summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>1999-05-03 07:29:11 +0000
committerRichard Henderson <rth@redhat.com>1999-05-03 07:29:11 +0000
commit252b5132c753830d5fd56823373aed85f2a0db63 (patch)
tree1af963bfd8d3e55167b81def4207f175eaff3a56
downloadbinutils-gdb-binu_ss_19990502.tar.gz
19990502 sourceware importbinu_ss_19990502
-rw-r--r--.cvsignore30
-rw-r--r--COPYING340
-rw-r--r--COPYING.LIB482
-rw-r--r--ChangeLog6537
-rw-r--r--Makefile.in1821
-rw-r--r--README47
-rw-r--r--bfd/COPYING340
-rw-r--r--bfd/ChangeLog3066
-rw-r--r--bfd/ChangeLog-91937851
-rw-r--r--bfd/ChangeLog-949510043
-rw-r--r--bfd/ChangeLog-96976711
-rw-r--r--bfd/Makefile.am1065
-rw-r--r--bfd/Makefile.in1599
-rw-r--r--bfd/PORTING83
-rw-r--r--bfd/README49
-rw-r--r--bfd/TODO25
-rw-r--r--bfd/acinclude.m4104
-rw-r--r--bfd/aclocal.m4861
-rw-r--r--bfd/aix386-core.c283
-rw-r--r--bfd/aout-adobe.c527
-rw-r--r--bfd/aout-arm.c546
-rw-r--r--bfd/aout-encap.c236
-rw-r--r--bfd/aout-ns32k.c370
-rw-r--r--bfd/aout-sparcle.c32
-rw-r--r--bfd/aout-target.h650
-rw-r--r--bfd/aout-tic30.c1065
-rw-r--r--bfd/aout0.c32
-rw-r--r--bfd/aout32.c23
-rw-r--r--bfd/aout64.c31
-rw-r--r--bfd/aoutf1.h859
-rw-r--r--bfd/aoutx.h5706
-rw-r--r--bfd/archive.c2127
-rw-r--r--bfd/archures.c896
-rw-r--r--bfd/bfd-in.h727
-rw-r--r--bfd/bfd-in2.h3003
-rw-r--r--bfd/bfd.c1159
-rw-r--r--bfd/binary.c386
-rw-r--r--bfd/bout.c1534
-rw-r--r--bfd/cache.c350
-rw-r--r--bfd/cf-i386lynx.c31
-rw-r--r--bfd/cf-m68klynx.c28
-rw-r--r--bfd/cf-sparclynx.c28
-rw-r--r--bfd/cisco-core.c327
-rw-r--r--bfd/coff-a29k.c640
-rw-r--r--bfd/coff-alpha.c2402
-rw-r--r--bfd/coff-apollo.c161
-rw-r--r--bfd/coff-arm.c2557
-rw-r--r--bfd/coff-aux.c135
-rw-r--r--bfd/coff-go32.c25
-rw-r--r--bfd/coff-h8300.c1388
-rw-r--r--bfd/coff-h8500.c354
-rw-r--r--bfd/coff-i386.c637
-rw-r--r--bfd/coff-i860.c422
-rw-r--r--bfd/coff-i960.c703
-rw-r--r--bfd/coff-m68k.c480
-rw-r--r--bfd/coff-m88k.c330
-rw-r--r--bfd/coff-mcore.c703
-rw-r--r--bfd/coff-mips.c2726
-rw-r--r--bfd/coff-pmac.c27
-rw-r--r--bfd/coff-ppc.c2934
-rw-r--r--bfd/coff-rs6000.c1418
-rw-r--r--bfd/coff-sh.c2959
-rw-r--r--bfd/coff-sparc.c256
-rw-r--r--bfd/coff-stgo32.c464
-rw-r--r--bfd/coff-svm68k.c26
-rw-r--r--bfd/coff-tic30.c206
-rw-r--r--bfd/coff-tic80.c759
-rw-r--r--bfd/coff-u68k.c35
-rw-r--r--bfd/coff-w65.c445
-rw-r--r--bfd/coff-we32k.c109
-rw-r--r--bfd/coff-z8k.c280
-rw-r--r--bfd/coffcode.h4318
-rw-r--r--bfd/coffgen.c2378
-rw-r--r--bfd/cofflink.c2752
-rw-r--r--bfd/coffswap.h908
-rw-r--r--bfd/config.bfd719
-rw-r--r--bfd/config.in234
-rwxr-xr-xbfd/configure5987
-rw-r--r--bfd/configure.bat18
-rw-r--r--bfd/configure.com215
-rw-r--r--bfd/configure.host70
-rw-r--r--bfd/configure.in648
-rw-r--r--bfd/corefile.c106
-rw-r--r--bfd/cpu-a29k.c39
-rw-r--r--bfd/cpu-alpha.c51
-rw-r--r--bfd/cpu-arc.c70
-rw-r--r--bfd/cpu-arm.c134
-rw-r--r--bfd/cpu-d10v.c40
-rw-r--r--bfd/cpu-d30v.c39
-rw-r--r--bfd/cpu-fr30.c38
-rw-r--r--bfd/cpu-h8300.c134
-rw-r--r--bfd/cpu-h8500.c199
-rw-r--r--bfd/cpu-hppa.c71
-rw-r--r--bfd/cpu-i386.c70
-rw-r--r--bfd/cpu-i860.c40
-rw-r--r--bfd/cpu-i960.c166
-rw-r--r--bfd/cpu-m10200.c38
-rw-r--r--bfd/cpu-m10300.c41
-rw-r--r--bfd/cpu-m32r.c32
-rw-r--r--bfd/cpu-m68k.c42
-rw-r--r--bfd/cpu-m88k.c42
-rw-r--r--bfd/cpu-mcore.c38
-rw-r--r--bfd/cpu-mips.c88
-rw-r--r--bfd/cpu-ns32k.c846
-rw-r--r--bfd/cpu-powerpc.c124
-rw-r--r--bfd/cpu-rs6000.c70
-rw-r--r--bfd/cpu-sh.c102
-rw-r--r--bfd/cpu-sparc.c156
-rw-r--r--bfd/cpu-tic30.c39
-rw-r--r--bfd/cpu-tic80.c39
-rw-r--r--bfd/cpu-v850.c103
-rw-r--r--bfd/cpu-vax.c39
-rw-r--r--bfd/cpu-w65.c54
-rw-r--r--bfd/cpu-we32k.c39
-rw-r--r--bfd/cpu-z8k.c198
-rw-r--r--bfd/demo64.c24
-rw-r--r--bfd/dep-in.sed26
-rw-r--r--bfd/doc/ChangeLog390
-rw-r--r--bfd/doc/Makefile.am250
-rw-r--r--bfd/doc/Makefile.in600
-rw-r--r--bfd/doc/bfd.texinfo348
-rw-r--r--bfd/doc/bfdint.texi1885
-rw-r--r--bfd/doc/bfdsumm.texi148
-rw-r--r--bfd/doc/chew.c1579
-rw-r--r--bfd/doc/doc.str158
-rw-r--r--bfd/doc/makefile.vms5
-rw-r--r--bfd/doc/proto.str135
-rw-r--r--bfd/dwarf1.c576
-rw-r--r--bfd/dwarf2.c1466
-rw-r--r--bfd/ecoff.c4825
-rw-r--r--bfd/ecofflink.c2499
-rw-r--r--bfd/ecoffswap.h853
-rw-r--r--bfd/elf-bfd.h1114
-rw-r--r--bfd/elf-m10200.c1525
-rw-r--r--bfd/elf-m10300.c2821
-rw-r--r--bfd/elf.c5250
-rw-r--r--bfd/elf32-arc.c213
-rw-r--r--bfd/elf32-arm.h3010
-rw-r--r--bfd/elf32-d10v.c534
-rw-r--r--bfd/elf32-d30v.c601
-rw-r--r--bfd/elf32-fr30.c811
-rw-r--r--bfd/elf32-gen.c71
-rw-r--r--bfd/elf32-hppa.c2988
-rw-r--r--bfd/elf32-hppa.h66
-rw-r--r--bfd/elf32-i386.c1943
-rw-r--r--bfd/elf32-i860.c33
-rw-r--r--bfd/elf32-m32r.c2082
-rw-r--r--bfd/elf32-m68k.c2128
-rw-r--r--bfd/elf32-m88k.c35
-rw-r--r--bfd/elf32-mcore.c747
-rw-r--r--bfd/elf32-mips.c7800
-rw-r--r--bfd/elf32-ppc.c3848
-rw-r--r--bfd/elf32-sh.c2059
-rw-r--r--bfd/elf32-sparc.c2059
-rw-r--r--bfd/elf32-v850.c2230
-rw-r--r--bfd/elf32.c23
-rw-r--r--bfd/elf64-alpha.c4768
-rw-r--r--bfd/elf64-gen.c71
-rw-r--r--bfd/elf64-mips.c2127
-rw-r--r--bfd/elf64-sparc.c2275
-rw-r--r--bfd/elf64.c22
-rw-r--r--bfd/elfarm-nabi.c670
-rw-r--r--bfd/elfarm-oabi.c381
-rw-r--r--bfd/elfcode.h1452
-rw-r--r--bfd/elfcore.h226
-rw-r--r--bfd/elflink.c433
-rw-r--r--bfd/elflink.h6150
-rw-r--r--bfd/elfxx-target.h536
-rw-r--r--bfd/epoc-pe-arm.c30
-rw-r--r--bfd/epoc-pei-arm.c29
-rw-r--r--bfd/format.c342
-rw-r--r--bfd/freebsd.h110
-rw-r--r--bfd/gen-aout.c101
-rw-r--r--bfd/genlink.h111
-rw-r--r--bfd/go32stub.h128
-rw-r--r--bfd/hash.c734
-rw-r--r--bfd/host-aout.c83
-rw-r--r--bfd/hosts/alphalinux.h6
-rw-r--r--bfd/hosts/alphavms.h69
-rw-r--r--bfd/hosts/decstation.h17
-rw-r--r--bfd/hosts/delta68.h18
-rw-r--r--bfd/hosts/dpx2.h8
-rw-r--r--bfd/hosts/hp300bsd.h13
-rw-r--r--bfd/hosts/i386bsd.h32
-rw-r--r--bfd/hosts/i386linux.h8
-rw-r--r--bfd/hosts/i386mach3.h25
-rw-r--r--bfd/hosts/i386sco.h19
-rw-r--r--bfd/hosts/i860mach3.h27
-rw-r--r--bfd/hosts/m68kaux.h16
-rw-r--r--bfd/hosts/m68klinux.h6
-rw-r--r--bfd/hosts/m88kmach3.h11
-rw-r--r--bfd/hosts/mipsbsd.h12
-rw-r--r--bfd/hosts/mipsmach3.h10
-rw-r--r--bfd/hosts/news-mips.h12
-rw-r--r--bfd/hosts/news.h9
-rw-r--r--bfd/hosts/pc532mach.h24
-rw-r--r--bfd/hosts/riscos.h10
-rw-r--r--bfd/hosts/symmetry.h20
-rw-r--r--bfd/hosts/tahoe.h12
-rw-r--r--bfd/hosts/vaxbsd.h19
-rw-r--r--bfd/hosts/vaxult.h8
-rw-r--r--bfd/hosts/vaxult2.h8
-rw-r--r--bfd/hp300bsd.c38
-rw-r--r--bfd/hp300hpux.c870
-rw-r--r--bfd/hppa_stubs.h23
-rw-r--r--bfd/hppabsd-core.c303
-rw-r--r--bfd/hpux-core.c404
-rw-r--r--bfd/i386aout.c91
-rw-r--r--bfd/i386bsd.c46
-rw-r--r--bfd/i386dynix.c80
-rw-r--r--bfd/i386freebsd.c33
-rw-r--r--bfd/i386linux.c767
-rw-r--r--bfd/i386lynx.c562
-rw-r--r--bfd/i386mach3.c66
-rw-r--r--bfd/i386msdos.c244
-rw-r--r--bfd/i386netbsd.c33
-rw-r--r--bfd/i386os9k.c371
-rw-r--r--bfd/ieee.c3970
-rw-r--r--bfd/ihex.c1041
-rw-r--r--bfd/init.c50
-rw-r--r--bfd/irix-core.c276
-rw-r--r--bfd/libaout.h624
-rw-r--r--bfd/libbfd-in.h538
-rw-r--r--bfd/libbfd.c1263
-rw-r--r--bfd/libbfd.h885
-rw-r--r--bfd/libcoff-in.h529
-rw-r--r--bfd/libcoff.h888
-rw-r--r--bfd/libecoff.h357
-rw-r--r--bfd/libhppa.h700
-rw-r--r--bfd/libieee.h133
-rw-r--r--bfd/libnlm.h264
-rw-r--r--bfd/liboasys.h82
-rw-r--r--bfd/linker.c2804
-rw-r--r--bfd/lynx-core.c233
-rw-r--r--bfd/m68k4knetbsd.c32
-rw-r--r--bfd/m68klinux.c772
-rw-r--r--bfd/m68klynx.c54
-rw-r--r--bfd/m68knetbsd.c34
-rw-r--r--bfd/m88kmach3.c38
-rw-r--r--bfd/makefile.dos49
-rw-r--r--bfd/makefile.vms75
-rw-r--r--bfd/mipsbsd.c468
-rw-r--r--bfd/mpw-config.in86
-rw-r--r--bfd/mpw-make.sed81
-rw-r--r--bfd/netbsd-core.c251
-rw-r--r--bfd/netbsd.h122
-rw-r--r--bfd/newsos3.c40
-rw-r--r--bfd/nlm-target.h229
-rw-r--r--bfd/nlm.c55
-rw-r--r--bfd/nlm32-alpha.c892
-rw-r--r--bfd/nlm32-i386.c451
-rw-r--r--bfd/nlm32-ppc.c1045
-rw-r--r--bfd/nlm32-sparc.c440
-rw-r--r--bfd/nlm32.c21
-rw-r--r--bfd/nlm64.c21
-rw-r--r--bfd/nlmcode.h2056
-rw-r--r--bfd/nlmswap.h157
-rw-r--r--bfd/ns32k.h41
-rw-r--r--bfd/ns32knetbsd.c53
-rw-r--r--bfd/oasys.c1535
-rw-r--r--bfd/opncls.c683
-rw-r--r--bfd/osf-core.c254
-rw-r--r--bfd/pc532-mach.c121
-rw-r--r--bfd/pe-arm.c34
-rw-r--r--bfd/pe-i386.c31
-rw-r--r--bfd/pe-mcore.c36
-rw-r--r--bfd/pe-ppc.c41
-rw-r--r--bfd/pei-arm.c36
-rw-r--r--bfd/pei-i386.c35
-rw-r--r--bfd/pei-mcore.c38
-rw-r--r--bfd/pei-ppc.c47
-rw-r--r--bfd/peicode.h2144
-rw-r--r--bfd/po/Make-in251
-rw-r--r--bfd/po/POTFILES.in264
-rw-r--r--bfd/po/bfd.pot632
-rw-r--r--bfd/ppcboot.c535
-rw-r--r--bfd/ptrace-core.c230
-rw-r--r--bfd/reloc.c2842
-rw-r--r--bfd/reloc16.c334
-rw-r--r--bfd/riscix.c644
-rw-r--r--bfd/rs6000-core.c507
-rw-r--r--bfd/sco5-core.c429
-rw-r--r--bfd/section.c1075
-rw-r--r--bfd/som.c6264
-rw-r--r--bfd/som.h237
-rw-r--r--bfd/sparclinux.c770
-rw-r--r--bfd/sparclynx.c266
-rw-r--r--bfd/sparcnetbsd.c34
-rw-r--r--bfd/srec.c1377
-rw-r--r--bfd/stab-syms.c57
-rw-r--r--bfd/stabs.c651
-rw-r--r--bfd/stamp-h.in1
-rw-r--r--bfd/sunos.c2948
-rw-r--r--bfd/syms.c1253
-rw-r--r--bfd/sysdep.h144
-rw-r--r--bfd/targets.c1079
-rw-r--r--bfd/targmatch.sed32
-rw-r--r--bfd/tekhex.c1065
-rw-r--r--bfd/trad-core.c316
-rw-r--r--bfd/vaxnetbsd.c33
-rw-r--r--bfd/versados.c923
-rw-r--r--bfd/vms-gsd.c920
-rw-r--r--bfd/vms-hdr.c461
-rw-r--r--bfd/vms-misc.c1145
-rw-r--r--bfd/vms-tir.c2489
-rw-r--r--bfd/vms.c1947
-rw-r--r--bfd/vms.h675
-rw-r--r--bfd/xcofflink.c6635
-rw-r--r--binutils/ChangeLog6404
-rw-r--r--binutils/Makefile.am495
-rw-r--r--binutils/Makefile.in1358
-rw-r--r--binutils/NEWS163
-rw-r--r--binutils/README189
-rw-r--r--binutils/acinclude.m41
-rw-r--r--binutils/aclocal.m41120
-rw-r--r--binutils/addr2line.1127
-rw-r--r--binutils/addr2line.c335
-rw-r--r--binutils/ar.1509
-rw-r--r--binutils/ar.c1338
-rw-r--r--binutils/arlex.l83
-rw-r--r--binutils/arparse.y202
-rw-r--r--binutils/arsup.c456
-rw-r--r--binutils/arsup.h75
-rw-r--r--binutils/binutils.texi2904
-rw-r--r--binutils/bucomm.c266
-rw-r--r--binutils/bucomm.h183
-rw-r--r--binutils/budbg.h58
-rw-r--r--binutils/coffdump.c541
-rw-r--r--binutils/coffgrok.c737
-rw-r--r--binutils/coffgrok.h206
-rw-r--r--binutils/config.in183
-rwxr-xr-xbinutils/configure5567
-rwxr-xr-xbinutils/configure.bat63
-rw-r--r--binutils/configure.com76
-rw-r--r--binutils/configure.in221
-rw-r--r--binutils/cxxfilt.man114
-rw-r--r--binutils/debug.c3568
-rw-r--r--binutils/debug.h798
-rw-r--r--binutils/deflex.l86
-rw-r--r--binutils/defparse.y157
-rw-r--r--binutils/dep-in.sed17
-rw-r--r--binutils/dlltool.c3199
-rw-r--r--binutils/dlltool.h42
-rw-r--r--binutils/dllwrap.c1050
-rw-r--r--binutils/dyn-string.c107
-rw-r--r--binutils/dyn-string.h34
-rw-r--r--binutils/filemode.c266
-rw-r--r--binutils/ieee.c7609
-rw-r--r--binutils/is-ranlib.c3
-rw-r--r--binutils/is-strip.c4
-rw-r--r--binutils/mac-binutils.r42
-rw-r--r--binutils/makefile.vms-in98
-rw-r--r--binutils/maybe-ranlib.c4
-rw-r--r--binutils/maybe-strip.c4
-rw-r--r--binutils/mpw-config.in27
-rw-r--r--binutils/mpw-make.sed115
-rw-r--r--binutils/nlmconv.1110
-rw-r--r--binutils/nlmconv.c2212
-rw-r--r--binutils/nlmconv.h84
-rw-r--r--binutils/nlmheader.y978
-rw-r--r--binutils/nm.1230
-rw-r--r--binutils/nm.c1558
-rw-r--r--binutils/not-ranlib.c3
-rw-r--r--binutils/not-strip.c4
-rw-r--r--binutils/objcopy.1319
-rw-r--r--binutils/objcopy.c2029
-rw-r--r--binutils/objdump.1412
-rw-r--r--binutils/objdump.c2829
-rw-r--r--binutils/po/Make-in251
-rw-r--r--binutils/po/POTFILES.in52
-rw-r--r--binutils/po/binutils.pot3443
-rw-r--r--binutils/prdbg.c1862
-rw-r--r--binutils/ranlib.183
-rwxr-xr-xbinutils/ranlib.sh3
-rw-r--r--binutils/rclex.l465
-rw-r--r--binutils/rcparse.y1617
-rw-r--r--binutils/rdcoff.c889
-rw-r--r--binutils/rddbg.c448
-rw-r--r--binutils/readelf.c5682
-rw-r--r--binutils/rename.c210
-rw-r--r--binutils/resbin.c2387
-rw-r--r--binutils/rescoff.c776
-rw-r--r--binutils/resrc.c2265
-rw-r--r--binutils/resres.c656
-rwxr-xr-xbinutils/sanity.sh50
-rw-r--r--binutils/size.1161
-rw-r--r--binutils/size.c515
-rw-r--r--binutils/srconv.c2036
-rw-r--r--binutils/stabs.c5188
-rw-r--r--binutils/stamp-h.in1
-rw-r--r--binutils/strings.1151
-rw-r--r--binutils/strings.c514
-rw-r--r--binutils/strip.1185
-rw-r--r--binutils/sysdump.c790
-rw-r--r--binutils/sysinfo.y415
-rw-r--r--binutils/syslex.l51
-rw-r--r--binutils/sysroff.info504
-rw-r--r--binutils/testsuite/ChangeLog585
-rw-r--r--binutils/testsuite/binutils-all/ar.exp219
-rw-r--r--binutils/testsuite/binutils-all/bintest.s12
-rw-r--r--binutils/testsuite/binutils-all/hppa/addendbug.s23
-rw-r--r--binutils/testsuite/binutils-all/hppa/objdump.exp59
-rw-r--r--binutils/testsuite/binutils-all/nm.exp123
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp591
-rw-r--r--binutils/testsuite/binutils-all/objdump.exp140
-rw-r--r--binutils/testsuite/binutils-all/readelf.exp217
-rw-r--r--binutils/testsuite/binutils-all/readelf.h16
-rw-r--r--binutils/testsuite/binutils-all/readelf.r4
-rw-r--r--binutils/testsuite/binutils-all/readelf.s13
-rw-r--r--binutils/testsuite/binutils-all/readelf.ss13
-rw-r--r--binutils/testsuite/binutils-all/readelf.wi78
-rw-r--r--binutils/testsuite/binutils-all/size.exp78
-rw-r--r--binutils/testsuite/binutils-all/testprog.c28
-rw-r--r--binutils/testsuite/config/default.exp88
-rw-r--r--binutils/testsuite/config/hppa.sed4
-rw-r--r--binutils/testsuite/lib/utils-lib.exp161
-rw-r--r--binutils/version.c44
-rw-r--r--binutils/windres.c947
-rw-r--r--binutils/windres.h847
-rw-r--r--binutils/winduni.c147
-rw-r--r--binutils/winduni.h60
-rw-r--r--binutils/wrstabs.c2416
-rw-r--r--config-ml.in687
-rwxr-xr-xconfig.guess1008
-rw-r--r--config.if87
-rwxr-xr-xconfig.sub1292
-rw-r--r--config/ChangeLog392
-rwxr-xr-xconfig/acinclude.m41994
-rw-r--r--config/mh-a68bsd12
-rw-r--r--config/mh-aix3861
-rw-r--r--config/mh-aix434
-rw-r--r--config/mh-apollo683
-rw-r--r--config/mh-armpic1
-rw-r--r--config/mh-cxux14
-rw-r--r--config/mh-cygwin6
-rw-r--r--config/mh-decstation5
-rw-r--r--config/mh-delta884
-rw-r--r--config/mh-dgux4
-rw-r--r--config/mh-dgux38622
-rw-r--r--config/mh-djgpp4
-rw-r--r--config/mh-elfalphapic1
-rw-r--r--config/mh-hp30013
-rw-r--r--config/mh-hpux4
-rw-r--r--config/mh-hpux84
-rw-r--r--config/mh-interix14
-rw-r--r--config/mh-irix47
-rw-r--r--config/mh-irix53
-rw-r--r--config/mh-irix67
-rw-r--r--config/mh-lynxos2
-rw-r--r--config/mh-lynxrs6k8
-rw-r--r--config/mh-m68kpic1
-rw-r--r--config/mh-mingw3212
-rw-r--r--config/mh-ncr300017
-rw-r--r--config/mh-ncrsvr439
-rw-r--r--config/mh-necv411
-rw-r--r--config/mh-papic1
-rw-r--r--config/mh-ppcpic1
-rw-r--r--config/mh-riscos15
-rw-r--r--config/mh-sco10
-rw-r--r--config/mh-solaris6
-rw-r--r--config/mh-sparcpic1
-rw-r--r--config/mh-sun33
-rw-r--r--config/mh-sysv3
-rw-r--r--config/mh-sysv411
-rw-r--r--config/mh-sysv58
-rw-r--r--config/mh-vaxult22
-rw-r--r--config/mh-x86pic1
-rw-r--r--config/mpw-mh-mpw157
-rw-r--r--config/mpw/ChangeLog53
-rw-r--r--config/mpw/MoveIfChange19
-rw-r--r--config/mpw/README23
-rw-r--r--config/mpw/forward-include3
-rw-r--r--config/mpw/g-mpw-make.sed293
-rw-r--r--config/mpw/mpw-touch7
-rw-r--r--config/mpw/mpw-true1
-rw-r--r--config/mpw/null-command1
-rw-r--r--config/mpw/open-brace4
-rw-r--r--config/mpw/tr-7to8-src9
-rw-r--r--config/mpw/true1
-rw-r--r--config/mt-armpic1
-rw-r--r--config/mt-d30v4
-rw-r--r--config/mt-elfalphapic1
-rw-r--r--config/mt-linux2
-rw-r--r--config/mt-m68kpic1
-rw-r--r--config/mt-netware1
-rw-r--r--config/mt-ospace3
-rw-r--r--config/mt-papic1
-rw-r--r--config/mt-ppcpic1
-rw-r--r--config/mt-sparcpic1
-rw-r--r--config/mt-v8104
-rw-r--r--config/mt-x86pic1
-rwxr-xr-xconfigure1595
-rw-r--r--configure.bat17
-rw-r--r--configure.in1184
-rw-r--r--etc/ChangeLog507
-rw-r--r--etc/Makefile.in156
-rw-r--r--etc/add-log.el573
-rw-r--r--etc/add-log.vi11
-rw-r--r--etc/configbuild.ein149
-rw-r--r--etc/configbuild.fig50
-rw-r--r--etc/configbuild.jinbin0 -> 11123 bytes
-rw-r--r--etc/configbuild.tin9
-rw-r--r--etc/configdev.ein185
-rw-r--r--etc/configdev.fig80
-rw-r--r--etc/configdev.jinbin0 -> 17967 bytes
-rw-r--r--etc/configdev.tin17
-rwxr-xr-xetc/configure862
-rw-r--r--etc/configure.in7
-rw-r--r--etc/configure.texi2644
-rw-r--r--etc/make-stds.texi914
-rw-r--r--etc/standards.texi3093
-rw-r--r--gas/CONTRIBUTORS111
-rw-r--r--gas/COPYING340
-rw-r--r--gas/ChangeLog3170
-rw-r--r--gas/ChangeLog-929513110
-rw-r--r--gas/ChangeLog-96975960
-rw-r--r--gas/Makefile.am1695
-rw-r--r--gas/Makefile.in2488
-rw-r--r--gas/NEWS287
-rw-r--r--gas/README274
-rw-r--r--gas/README-vms248
-rw-r--r--gas/acinclude.m456
-rw-r--r--gas/aclocal.m4822
-rw-r--r--gas/app.c1255
-rw-r--r--gas/as.c1010
-rw-r--r--gas/as.h645
-rw-r--r--gas/asintl.h44
-rw-r--r--gas/atof-generic.c636
-rw-r--r--gas/bignum-copy.c80
-rw-r--r--gas/bignum.h52
-rw-r--r--gas/bit_fix.h51
-rw-r--r--gas/cgen.c663
-rw-r--r--gas/cgen.h94
-rw-r--r--gas/cond.c461
-rw-r--r--gas/config-gas.com186
-rw-r--r--gas/config.in273
-rw-r--r--gas/config/aout_gnu.h455
-rw-r--r--gas/config/atof-ieee.c696
-rw-r--r--gas/config/atof-tahoe.c431
-rw-r--r--gas/config/atof-vax.c517
-rw-r--r--gas/config/e-i386coff.c17
-rw-r--r--gas/config/e-i386elf.c17
-rw-r--r--gas/config/e-mipsecoff.c37
-rw-r--r--gas/config/e-mipself.c37
-rw-r--r--gas/config/go32.cfg93
-rw-r--r--gas/config/itbl-mips.h47
-rw-r--r--gas/config/m68k-parse.h283
-rw-r--r--gas/config/m68k-parse.y1061
-rw-r--r--gas/config/m88k-opcode.h559
-rw-r--r--gas/config/obj-aout.c629
-rw-r--r--gas/config/obj-aout.h239
-rw-r--r--gas/config/obj-bout.c348
-rw-r--r--gas/config/obj-bout.h316
-rw-r--r--gas/config/obj-coff.c4482
-rw-r--r--gas/config/obj-coff.h841
-rw-r--r--gas/config/obj-ecoff.c309
-rw-r--r--gas/config/obj-ecoff.h67
-rw-r--r--gas/config/obj-elf.c1764
-rw-r--r--gas/config/obj-elf.h194
-rw-r--r--gas/config/obj-evax.c83
-rw-r--r--gas/config/obj-evax.h95
-rw-r--r--gas/config/obj-generic.c41
-rw-r--r--gas/config/obj-generic.h80
-rw-r--r--gas/config/obj-hp300.c52
-rw-r--r--gas/config/obj-hp300.h71
-rw-r--r--gas/config/obj-ieee.c627
-rw-r--r--gas/config/obj-ieee.h50
-rw-r--r--gas/config/obj-multi.c4
-rw-r--r--gas/config/obj-multi.h50
-rw-r--r--gas/config/obj-som.c307
-rw-r--r--gas/config/obj-som.h73
-rw-r--r--gas/config/obj-vms.c5549
-rw-r--r--gas/config/obj-vms.h552
-rw-r--r--gas/config/tc-a29k.c1296
-rw-r--r--gas/config/tc-a29k.h54
-rw-r--r--gas/config/tc-alpha.c4762
-rw-r--r--gas/config/tc-alpha.h104
-rw-r--r--gas/config/tc-arc.c1481
-rw-r--r--gas/config/tc-arc.h71
-rw-r--r--gas/config/tc-arm.c6857
-rw-r--r--gas/config/tc-arm.h204
-rw-r--r--gas/config/tc-d10v.c1636
-rw-r--r--gas/config/tc-d10v.h62
-rw-r--r--gas/config/tc-d30v.c2218
-rw-r--r--gas/config/tc-d30v.h59
-rw-r--r--gas/config/tc-fr30.c664
-rw-r--r--gas/config/tc-fr30.h81
-rw-r--r--gas/config/tc-generic.c0
-rw-r--r--gas/config/tc-generic.h39
-rw-r--r--gas/config/tc-h8300.c1595
-rw-r--r--gas/config/tc-h8300.h58
-rw-r--r--gas/config/tc-h8500.c1633
-rw-r--r--gas/config/tc-h8500.h57
-rw-r--r--gas/config/tc-hppa.c6716
-rw-r--r--gas/config/tc-hppa.h162
-rw-r--r--gas/config/tc-i386.c4475
-rw-r--r--gas/config/tc-i386.h471
-rw-r--r--gas/config/tc-i860.c1263
-rw-r--r--gas/config/tc-i860.h39
-rw-r--r--gas/config/tc-i960.c3231
-rw-r--r--gas/config/tc-i960.h171
-rw-r--r--gas/config/tc-m32r.c1300
-rw-r--r--gas/config/tc-m32r.h102
-rw-r--r--gas/config/tc-m68851.h304
-rw-r--r--gas/config/tc-m68k.c7009
-rw-r--r--gas/config/tc-m68k.h216
-rw-r--r--gas/config/tc-m88k.c1452
-rw-r--r--gas/config/tc-m88k.h108
-rw-r--r--gas/config/tc-mcore.c2183
-rw-r--r--gas/config/tc-mcore.h119
-rw-r--r--gas/config/tc-mips.c11783
-rw-r--r--gas/config/tc-mips.h153
-rw-r--r--gas/config/tc-mn10200.c1414
-rw-r--r--gas/config/tc-mn10200.h51
-rw-r--r--gas/config/tc-mn10300.c1649
-rw-r--r--gas/config/tc-mn10300.h50
-rw-r--r--gas/config/tc-ns32k.c2328
-rw-r--r--gas/config/tc-ns32k.h155
-rw-r--r--gas/config/tc-ppc.c5003
-rw-r--r--gas/config/tc-ppc.h276
-rw-r--r--gas/config/tc-sh.c2425
-rw-r--r--gas/config/tc-sh.h152
-rw-r--r--gas/config/tc-sparc.c3551
-rw-r--r--gas/config/tc-sparc.h164
-rw-r--r--gas/config/tc-tahoe.c2027
-rw-r--r--gas/config/tc-tahoe.h43
-rw-r--r--gas/config/tc-tic30.c1887
-rw-r--r--gas/config/tc-tic30.h55
-rw-r--r--gas/config/tc-tic80.c1061
-rw-r--r--gas/config/tc-tic80.h63
-rw-r--r--gas/config/tc-v850.c2478
-rw-r--r--gas/config/tc-v850.h85
-rw-r--r--gas/config/tc-vax.c3242
-rw-r--r--gas/config/tc-vax.h45
-rw-r--r--gas/config/tc-w65.c1219
-rw-r--r--gas/config/tc-w65.h61
-rw-r--r--gas/config/tc-z8k.c1589
-rw-r--r--gas/config/tc-z8k.h54
-rw-r--r--gas/config/te-386bsd.h31
-rw-r--r--gas/config/te-aux.h17
-rw-r--r--gas/config/te-delt88.h13
-rw-r--r--gas/config/te-delta.h14
-rw-r--r--gas/config/te-dpx2.h12
-rw-r--r--gas/config/te-dynix.h7
-rw-r--r--gas/config/te-epoc-pe.h8
-rw-r--r--gas/config/te-generic.h22
-rw-r--r--gas/config/te-go32.h16
-rw-r--r--gas/config/te-hp300.h25
-rw-r--r--gas/config/te-hppa.h26
-rw-r--r--gas/config/te-i386aix.h29
-rw-r--r--gas/config/te-ic960.h38
-rw-r--r--gas/config/te-linux.h4
-rw-r--r--gas/config/te-lnews.h5
-rw-r--r--gas/config/te-lynx.h7
-rw-r--r--gas/config/te-mach.h2
-rw-r--r--gas/config/te-macos.h11
-rw-r--r--gas/config/te-multi.h22
-rw-r--r--gas/config/te-nbsd.h23
-rw-r--r--gas/config/te-nbsd532.h19
-rw-r--r--gas/config/te-pc532mach.h19
-rw-r--r--gas/config/te-pe.h7
-rw-r--r--gas/config/te-ppcnw.h31
-rw-r--r--gas/config/te-psos.h22
-rw-r--r--gas/config/te-riscix.h6
-rw-r--r--gas/config/te-sparcaout.h21
-rw-r--r--gas/config/te-sun3.h48
-rw-r--r--gas/config/te-svr4.h4
-rw-r--r--gas/config/te-sysv32.h6
-rw-r--r--gas/config/vax-inst.h77
-rw-r--r--gas/config/vms-a-conf.h129
-rw-r--r--gas/config/vms-conf.h179
-rwxr-xr-xgas/configure5750
-rw-r--r--gas/configure.bat57
-rw-r--r--gas/configure.in766
-rw-r--r--gas/debug.c104
-rw-r--r--gas/dep-in.sed45
-rw-r--r--gas/depend.c208
-rw-r--r--gas/doc/Makefile.am49
-rw-r--r--gas/doc/Makefile.in438
-rw-r--r--gas/doc/all.texi72
-rw-r--r--gas/doc/as.1302
-rw-r--r--gas/doc/as.texinfo5322
-rw-r--r--gas/doc/c-a29k.texi182
-rw-r--r--gas/doc/c-arm.texi207
-rw-r--r--gas/doc/c-d10v.texi250
-rw-r--r--gas/doc/c-d30v.texi292
-rw-r--r--gas/doc/c-h8300.texi342
-rw-r--r--gas/doc/c-h8500.texi272
-rw-r--r--gas/doc/c-hppa.texi263
-rw-r--r--gas/doc/c-i386.texi518
-rw-r--r--gas/doc/c-i960.texi298
-rw-r--r--gas/doc/c-m32r.texi13
-rw-r--r--gas/doc/c-m68k.texi503
-rw-r--r--gas/doc/c-mips.texi257
-rw-r--r--gas/doc/c-ns32k.texi30
-rw-r--r--gas/doc/c-sh.texi272
-rw-r--r--gas/doc/c-sparc.texi179
-rw-r--r--gas/doc/c-v850.texi363
-rw-r--r--gas/doc/c-vax.texi357
-rw-r--r--gas/doc/c-z8k.texi380
-rw-r--r--gas/doc/gasp.texi1086
-rw-r--r--gas/doc/h8.texi26
-rw-r--r--gas/doc/internals.texi1557
-rw-r--r--gas/ecoff.c5308
-rw-r--r--gas/ecoff.h110
-rw-r--r--gas/ehopt.c469
-rw-r--r--gas/emul-target.h43
-rw-r--r--gas/emul.h23
-rw-r--r--gas/expr.c1859
-rw-r--r--gas/expr.h162
-rw-r--r--gas/flonum-copy.c73
-rw-r--r--gas/flonum-konst.c209
-rw-r--r--gas/flonum-mult.c200
-rw-r--r--gas/flonum.h110
-rw-r--r--gas/frags.c359
-rw-r--r--gas/frags.h158
-rw-r--r--gas/gasp.c3745
-rw-r--r--gas/gdbinit.in39
-rw-r--r--gas/hash.c1028
-rw-r--r--gas/hash.h45
-rw-r--r--gas/input-file.c248
-rw-r--r--gas/input-file.h68
-rw-r--r--gas/input-scrub.c521
-rw-r--r--gas/itbl-lex.l114
-rw-r--r--gas/itbl-ops.c921
-rw-r--r--gas/itbl-ops.h109
-rw-r--r--gas/itbl-parse.y459
-rw-r--r--gas/link.cmd10
-rw-r--r--gas/listing.c1420
-rw-r--r--gas/listing.h67
-rw-r--r--gas/literal.c95
-rw-r--r--gas/mac-as.r42
-rw-r--r--gas/macro.c1259
-rw-r--r--gas/macro.h53
-rw-r--r--gas/makefile.vms124
-rw-r--r--gas/messages.c541
-rw-r--r--gas/mpw-config.in115
-rw-r--r--gas/mpw-make.sed100
-rw-r--r--gas/obj.h81
-rw-r--r--gas/output-file.c156
-rw-r--r--gas/output-file.h25
-rw-r--r--gas/po/Make-in251
-rw-r--r--gas/po/POTFILES.in193
-rw-r--r--gas/po/gas.pot3853
-rw-r--r--gas/read.c5054
-rw-r--r--gas/read.h166
-rw-r--r--gas/sb.c289
-rw-r--r--gas/sb.h99
-rw-r--r--gas/stabs.c632
-rw-r--r--gas/stamp-h.in1
-rw-r--r--gas/struc-symbol.h166
-rw-r--r--gas/subsegs.c618
-rw-r--r--gas/subsegs.h159
-rw-r--r--gas/symbols.c1785
-rw-r--r--gas/symbols.h90
-rw-r--r--gas/tc.h112
-rw-r--r--gas/testsuite/ChangeLog2333
-rw-r--r--gas/testsuite/config/default.exp46
-rw-r--r--gas/testsuite/gas/all/align.d12
-rw-r--r--gas/testsuite/gas/all/align.s61
-rw-r--r--gas/testsuite/gas/all/cofftag.d25
-rw-r--r--gas/testsuite/gas/all/cofftag.s57
-rw-r--r--gas/testsuite/gas/all/comment.s3
-rw-r--r--gas/testsuite/gas/all/cond.d20
-rw-r--r--gas/testsuite/gas/all/cond.s18
-rw-r--r--gas/testsuite/gas/all/diff1.s5
-rw-r--r--gas/testsuite/gas/all/float.s4
-rw-r--r--gas/testsuite/gas/all/gas.exp145
-rw-r--r--gas/testsuite/gas/all/itbl20
-rw-r--r--gas/testsuite/gas/all/itbl-test.c129
-rw-r--r--gas/testsuite/gas/all/itbl.s13
-rw-r--r--gas/testsuite/gas/all/p1480.s3
-rw-r--r--gas/testsuite/gas/all/p2425.s6
-rw-r--r--gas/testsuite/gas/all/struct.d8
-rw-r--r--gas/testsuite/gas/all/struct.s10
-rw-r--r--gas/testsuite/gas/all/x930509.s3
-rw-r--r--gas/testsuite/gas/alpha/fp.d7
-rw-r--r--gas/testsuite/gas/alpha/fp.exp15
-rw-r--r--gas/testsuite/gas/alpha/fp.s14
-rw-r--r--gas/testsuite/gas/arc/alias.d68
-rw-r--r--gas/testsuite/gas/arc/alias.s76
-rw-r--r--gas/testsuite/gas/arc/arc.exp114
-rw-r--r--gas/testsuite/gas/arc/branch.d45
-rw-r--r--gas/testsuite/gas/arc/branch.s47
-rw-r--r--gas/testsuite/gas/arc/flag.d29
-rw-r--r--gas/testsuite/gas/arc/flag.s27
-rw-r--r--gas/testsuite/gas/arc/insn3.d44
-rw-r--r--gas/testsuite/gas/arc/insn3.s52
-rw-r--r--gas/testsuite/gas/arc/j.d75
-rw-r--r--gas/testsuite/gas/arc/j.s45
-rw-r--r--gas/testsuite/gas/arc/ld.d30
-rw-r--r--gas/testsuite/gas/arc/ld.s24
-rw-r--r--gas/testsuite/gas/arc/math.d78
-rw-r--r--gas/testsuite/gas/arc/math.s89
-rw-r--r--gas/testsuite/gas/arc/sshift.d44
-rw-r--r--gas/testsuite/gas/arc/sshift.s52
-rw-r--r--gas/testsuite/gas/arc/st.d25
-rw-r--r--gas/testsuite/gas/arc/st.s19
-rw-r--r--gas/testsuite/gas/arc/warn.exp13
-rw-r--r--gas/testsuite/gas/arc/warn.s14
-rw-r--r--gas/testsuite/gas/arm/arch4t.s21
-rw-r--r--gas/testsuite/gas/arm/arm.exp34
-rw-r--r--gas/testsuite/gas/arm/arm3.s6
-rw-r--r--gas/testsuite/gas/arm/arm6.s12
-rw-r--r--gas/testsuite/gas/arm/arm7dm.s12
-rw-r--r--gas/testsuite/gas/arm/arm7t.d68
-rw-r--r--gas/testsuite/gas/arm/arm7t.s79
-rw-r--r--gas/testsuite/gas/arm/copro.s24
-rw-r--r--gas/testsuite/gas/arm/float.s162
-rw-r--r--gas/testsuite/gas/arm/immed.s11
-rw-r--r--gas/testsuite/gas/arm/inst.d168
-rw-r--r--gas/testsuite/gas/arm/inst.s189
-rw-r--r--gas/testsuite/gas/arm/le-fpconst.d8
-rw-r--r--gas/testsuite/gas/arm/le-fpconst.s8
-rw-r--r--gas/testsuite/gas/arm/thumb.s193
-rw-r--r--gas/testsuite/gas/d30v/align.d17
-rw-r--r--gas/testsuite/gas/d30v/align.s28
-rw-r--r--gas/testsuite/gas/d30v/array.d31
-rw-r--r--gas/testsuite/gas/d30v/array.s15
-rw-r--r--gas/testsuite/gas/d30v/bittest.d20
-rw-r--r--gas/testsuite/gas/d30v/bittest.l56
-rw-r--r--gas/testsuite/gas/d30v/bittest.s28
-rw-r--r--gas/testsuite/gas/d30v/d30.exp35
-rw-r--r--gas/testsuite/gas/d30v/guard-debug.d25
-rw-r--r--gas/testsuite/gas/d30v/guard-debug.s17
-rw-r--r--gas/testsuite/gas/d30v/guard.d17
-rw-r--r--gas/testsuite/gas/d30v/guard.s24
-rw-r--r--gas/testsuite/gas/d30v/inst.d256
-rw-r--r--gas/testsuite/gas/d30v/inst.s504
-rw-r--r--gas/testsuite/gas/d30v/label-debug.d24
-rw-r--r--gas/testsuite/gas/d30v/label-debug.s11
-rw-r--r--gas/testsuite/gas/d30v/label.d16
-rw-r--r--gas/testsuite/gas/d30v/label.s11
-rw-r--r--gas/testsuite/gas/d30v/mul.d20
-rw-r--r--gas/testsuite/gas/d30v/mul.s19
-rw-r--r--gas/testsuite/gas/d30v/opt.d89
-rw-r--r--gas/testsuite/gas/d30v/opt.s216
-rw-r--r--gas/testsuite/gas/d30v/reloc.d93
-rw-r--r--gas/testsuite/gas/d30v/reloc.s68
-rw-r--r--gas/testsuite/gas/d30v/serial.l46
-rw-r--r--gas/testsuite/gas/d30v/serial.s14
-rw-r--r--gas/testsuite/gas/d30v/serial2.l138
-rw-r--r--gas/testsuite/gas/d30v/serial2.s29
-rw-r--r--gas/testsuite/gas/d30v/serial2O.l99
-rw-r--r--gas/testsuite/gas/d30v/serial2O.s29
-rw-r--r--gas/testsuite/gas/d30v/warn_oddreg.l40
-rw-r--r--gas/testsuite/gas/d30v/warn_oddreg.s12
-rw-r--r--gas/testsuite/gas/fr30/allinsn.d440
-rw-r--r--gas/testsuite/gas/fr30/allinsn.exp5
-rw-r--r--gas/testsuite/gas/fr30/allinsn.s434
-rw-r--r--gas/testsuite/gas/fr30/fr30.exp5
-rw-r--r--gas/testsuite/gas/h8300/addsub.s16
-rw-r--r--gas/testsuite/gas/h8300/addsubh.s25
-rw-r--r--gas/testsuite/gas/h8300/addsubs.s25
-rw-r--r--gas/testsuite/gas/h8300/bitops1.s18
-rw-r--r--gas/testsuite/gas/h8300/bitops1h.s19
-rw-r--r--gas/testsuite/gas/h8300/bitops1s.s29
-rw-r--r--gas/testsuite/gas/h8300/bitops2.s15
-rw-r--r--gas/testsuite/gas/h8300/bitops2h.s16
-rw-r--r--gas/testsuite/gas/h8300/bitops2s.s23
-rw-r--r--gas/testsuite/gas/h8300/bitops3.s15
-rw-r--r--gas/testsuite/gas/h8300/bitops3h.s16
-rw-r--r--gas/testsuite/gas/h8300/bitops3s.s24
-rw-r--r--gas/testsuite/gas/h8300/bitops4.s18
-rw-r--r--gas/testsuite/gas/h8300/bitops4h.s19
-rw-r--r--gas/testsuite/gas/h8300/bitops4s.s29
-rw-r--r--gas/testsuite/gas/h8300/branch.s10
-rw-r--r--gas/testsuite/gas/h8300/branchh.s12
-rw-r--r--gas/testsuite/gas/h8300/branchs.s12
-rw-r--r--gas/testsuite/gas/h8300/cbranch.s23
-rw-r--r--gas/testsuite/gas/h8300/cbranchh.s44
-rw-r--r--gas/testsuite/gas/h8300/cbranchs.s44
-rw-r--r--gas/testsuite/gas/h8300/cmpsi2.s28
-rw-r--r--gas/testsuite/gas/h8300/compare.s6
-rw-r--r--gas/testsuite/gas/h8300/compareh.s10
-rw-r--r--gas/testsuite/gas/h8300/compares.s10
-rw-r--r--gas/testsuite/gas/h8300/decimal.s5
-rw-r--r--gas/testsuite/gas/h8300/decimalh.s6
-rw-r--r--gas/testsuite/gas/h8300/decimals.s6
-rw-r--r--gas/testsuite/gas/h8300/divmul.s5
-rw-r--r--gas/testsuite/gas/h8300/divmulh.s12
-rw-r--r--gas/testsuite/gas/h8300/divmuls.s12
-rw-r--r--gas/testsuite/gas/h8300/extendh.s8
-rw-r--r--gas/testsuite/gas/h8300/extends.s8
-rw-r--r--gas/testsuite/gas/h8300/ffxx1.d23
-rw-r--r--gas/testsuite/gas/h8300/ffxx1.s20
-rw-r--r--gas/testsuite/gas/h8300/h8300.exp2183
-rw-r--r--gas/testsuite/gas/h8300/incdec.s5
-rw-r--r--gas/testsuite/gas/h8300/incdech.s14
-rw-r--r--gas/testsuite/gas/h8300/incdecs.s14
-rw-r--r--gas/testsuite/gas/h8300/logical.s14
-rw-r--r--gas/testsuite/gas/h8300/logicalh.s31
-rw-r--r--gas/testsuite/gas/h8300/logicals.s34
-rw-r--r--gas/testsuite/gas/h8300/macs.s11
-rw-r--r--gas/testsuite/gas/h8300/misc.s13
-rw-r--r--gas/testsuite/gas/h8300/misch.s27
-rw-r--r--gas/testsuite/gas/h8300/miscs.s41
-rw-r--r--gas/testsuite/gas/h8300/mov32bug.s4
-rw-r--r--gas/testsuite/gas/h8300/movb.s15
-rw-r--r--gas/testsuite/gas/h8300/movbh.s20
-rw-r--r--gas/testsuite/gas/h8300/movbs.s20
-rw-r--r--gas/testsuite/gas/h8300/movlh.s18
-rw-r--r--gas/testsuite/gas/h8300/movls.s18
-rw-r--r--gas/testsuite/gas/h8300/movw.s13
-rw-r--r--gas/testsuite/gas/h8300/movwh.s18
-rw-r--r--gas/testsuite/gas/h8300/movws.s18
-rw-r--r--gas/testsuite/gas/h8300/multiples.s10
-rw-r--r--gas/testsuite/gas/h8300/pushpop.s5
-rw-r--r--gas/testsuite/gas/h8300/pushpoph.s8
-rw-r--r--gas/testsuite/gas/h8300/pushpops.s8
-rw-r--r--gas/testsuite/gas/h8300/rotsh.s11
-rw-r--r--gas/testsuite/gas/h8300/rotshh.s27
-rw-r--r--gas/testsuite/gas/h8300/rotshs.s51
-rw-r--r--gas/testsuite/gas/hppa/README34
-rw-r--r--gas/testsuite/gas/hppa/basic/add.s100
-rw-r--r--gas/testsuite/gas/hppa/basic/addi.s83
-rw-r--r--gas/testsuite/gas/hppa/basic/basic.exp2262
-rw-r--r--gas/testsuite/gas/hppa/basic/branch.s227
-rw-r--r--gas/testsuite/gas/hppa/basic/comclr.s50
-rw-r--r--gas/testsuite/gas/hppa/basic/copr.s19
-rw-r--r--gas/testsuite/gas/hppa/basic/coprmem.s55
-rw-r--r--gas/testsuite/gas/hppa/basic/dcor.s41
-rw-r--r--gas/testsuite/gas/hppa/basic/deposit.s88
-rw-r--r--gas/testsuite/gas/hppa/basic/ds.s32
-rw-r--r--gas/testsuite/gas/hppa/basic/extract.s51
-rw-r--r--gas/testsuite/gas/hppa/basic/fmem.s52
-rw-r--r--gas/testsuite/gas/hppa/basic/fmemLRbug.s76
-rw-r--r--gas/testsuite/gas/hppa/basic/fp_comp.s81
-rw-r--r--gas/testsuite/gas/hppa/basic/fp_conv.s92
-rw-r--r--gas/testsuite/gas/hppa/basic/fp_fcmp.s114
-rw-r--r--gas/testsuite/gas/hppa/basic/fp_misc.s18
-rw-r--r--gas/testsuite/gas/hppa/basic/imem.s93
-rw-r--r--gas/testsuite/gas/hppa/basic/immed.s21
-rw-r--r--gas/testsuite/gas/hppa/basic/logical.s60
-rw-r--r--gas/testsuite/gas/hppa/basic/purge.s35
-rw-r--r--gas/testsuite/gas/hppa/basic/sh1add.s67
-rw-r--r--gas/testsuite/gas/hppa/basic/sh2add.s67
-rw-r--r--gas/testsuite/gas/hppa/basic/sh3add.s67
-rw-r--r--gas/testsuite/gas/hppa/basic/shift.s34
-rw-r--r--gas/testsuite/gas/hppa/basic/special.s15
-rw-r--r--gas/testsuite/gas/hppa/basic/spop.s34
-rw-r--r--gas/testsuite/gas/hppa/basic/sub.s117
-rw-r--r--gas/testsuite/gas/hppa/basic/subi.s49
-rw-r--r--gas/testsuite/gas/hppa/basic/system.s46
-rw-r--r--gas/testsuite/gas/hppa/basic/unit.s55
-rw-r--r--gas/testsuite/gas/hppa/basic/weird.s870
-rw-r--r--gas/testsuite/gas/hppa/parse/align1.s41
-rw-r--r--gas/testsuite/gas/hppa/parse/align2.s15
-rw-r--r--gas/testsuite/gas/hppa/parse/appbug.s1
-rw-r--r--gas/testsuite/gas/hppa/parse/badfmpyadd.s33
-rw-r--r--gas/testsuite/gas/hppa/parse/block1.s18
-rw-r--r--gas/testsuite/gas/hppa/parse/block2.s15
-rw-r--r--gas/testsuite/gas/hppa/parse/calldatabug.s189
-rw-r--r--gas/testsuite/gas/hppa/parse/callinfobug.s8
-rw-r--r--gas/testsuite/gas/hppa/parse/defbug.s18
-rw-r--r--gas/testsuite/gas/hppa/parse/entrybug.s24
-rw-r--r--gas/testsuite/gas/hppa/parse/exportbug.s14
-rw-r--r--gas/testsuite/gas/hppa/parse/exprbug.s39
-rw-r--r--gas/testsuite/gas/hppa/parse/fixup7bug.s6192
-rw-r--r--gas/testsuite/gas/hppa/parse/global.s15
-rw-r--r--gas/testsuite/gas/hppa/parse/labelbug.s35
-rw-r--r--gas/testsuite/gas/hppa/parse/linesepbug.s20
-rw-r--r--gas/testsuite/gas/hppa/parse/lselbug.s18
-rw-r--r--gas/testsuite/gas/hppa/parse/nosubspace.s21
-rw-r--r--gas/testsuite/gas/hppa/parse/parse.exp222
-rw-r--r--gas/testsuite/gas/hppa/parse/procbug.s16
-rw-r--r--gas/testsuite/gas/hppa/parse/regpopbug.s17
-rw-r--r--gas/testsuite/gas/hppa/parse/spacebug.s3
-rw-r--r--gas/testsuite/gas/hppa/parse/ssbug.s10
-rw-r--r--gas/testsuite/gas/hppa/parse/stdreg.s27
-rw-r--r--gas/testsuite/gas/hppa/parse/stringer.s19
-rw-r--r--gas/testsuite/gas/hppa/parse/undefbug.s14
-rw-r--r--gas/testsuite/gas/hppa/parse/versionbug.s9
-rw-r--r--gas/testsuite/gas/hppa/parse/xmpyubug.s17
-rw-r--r--gas/testsuite/gas/hppa/reloc/applybug.s130
-rw-r--r--gas/testsuite/gas/hppa/reloc/blebug.s16
-rw-r--r--gas/testsuite/gas/hppa/reloc/blebug2.s14
-rw-r--r--gas/testsuite/gas/hppa/reloc/blebug3.s14
-rw-r--r--gas/testsuite/gas/hppa/reloc/exitbug.s19
-rw-r--r--gas/testsuite/gas/hppa/reloc/fixupbug.s19
-rw-r--r--gas/testsuite/gas/hppa/reloc/funcrelocbug.s186
-rw-r--r--gas/testsuite/gas/hppa/reloc/labelopbug.s37
-rw-r--r--gas/testsuite/gas/hppa/reloc/longcall.s40
-rw-r--r--gas/testsuite/gas/hppa/reloc/picreloc.s13
-rw-r--r--gas/testsuite/gas/hppa/reloc/plabelbug.s47
-rw-r--r--gas/testsuite/gas/hppa/reloc/r_no_reloc.s45
-rw-r--r--gas/testsuite/gas/hppa/reloc/reduce.s48
-rw-r--r--gas/testsuite/gas/hppa/reloc/reduce2.s80
-rw-r--r--gas/testsuite/gas/hppa/reloc/reduce3.s51
-rw-r--r--gas/testsuite/gas/hppa/reloc/reloc.exp679
-rw-r--r--gas/testsuite/gas/hppa/reloc/roundmode.s23
-rw-r--r--gas/testsuite/gas/hppa/reloc/selectorbug.s28
-rw-r--r--gas/testsuite/gas/hppa/unsorted/align3.s20
-rw-r--r--gas/testsuite/gas/hppa/unsorted/align4.s4
-rw-r--r--gas/testsuite/gas/hppa/unsorted/brlenbug.s3502
-rw-r--r--gas/testsuite/gas/hppa/unsorted/common.s8
-rw-r--r--gas/testsuite/gas/hppa/unsorted/fragbug.s3
-rw-r--r--gas/testsuite/gas/hppa/unsorted/globalbug.s16
-rw-r--r--gas/testsuite/gas/hppa/unsorted/importbug.s42
-rw-r--r--gas/testsuite/gas/hppa/unsorted/labeldiffs.s40
-rw-r--r--gas/testsuite/gas/hppa/unsorted/locallabel.s15
-rw-r--r--gas/testsuite/gas/hppa/unsorted/ss_align.s12
-rw-r--r--gas/testsuite/gas/hppa/unsorted/unsorted.exp258
-rw-r--r--gas/testsuite/gas/i386/amd.d37
-rw-r--r--gas/testsuite/gas/i386/amd.s33
-rw-r--r--gas/testsuite/gas/i386/float.l81
-rw-r--r--gas/testsuite/gas/i386/float.s68
-rw-r--r--gas/testsuite/gas/i386/general.l205
-rw-r--r--gas/testsuite/gas/i386/general.s152
-rw-r--r--gas/testsuite/gas/i386/i386.exp34
-rw-r--r--gas/testsuite/gas/i386/inval.l98
-rw-r--r--gas/testsuite/gas/i386/inval.s48
-rw-r--r--gas/testsuite/gas/i386/modrm.l1984
-rw-r--r--gas/testsuite/gas/i386/modrm.s1671
-rw-r--r--gas/testsuite/gas/i386/opcode.d574
-rw-r--r--gas/testsuite/gas/i386/opcode.s567
-rw-r--r--gas/testsuite/gas/i386/prefix.d15
-rw-r--r--gas/testsuite/gas/i386/prefix.s11
-rw-r--r--gas/testsuite/gas/i386/reloc.d15
-rw-r--r--gas/testsuite/gas/i386/reloc.s8
-rw-r--r--gas/testsuite/gas/i386/white.l21
-rw-r--r--gas/testsuite/gas/i386/white.s18
-rw-r--r--gas/testsuite/gas/ieee-fp/x930509a.exp25
-rw-r--r--gas/testsuite/gas/ieee-fp/x930509a.s5
-rw-r--r--gas/testsuite/gas/m32r/allinsn.d374
-rw-r--r--gas/testsuite/gas/m32r/allinsn.exp5
-rw-r--r--gas/testsuite/gas/m32r/allinsn.s501
-rw-r--r--gas/testsuite/gas/m32r/fslot.d31
-rw-r--r--gas/testsuite/gas/m32r/fslot.s27
-rw-r--r--gas/testsuite/gas/m32r/high-1.d19
-rw-r--r--gas/testsuite/gas/m32r/high-1.s14
-rw-r--r--gas/testsuite/gas/m32r/m32r.exp8
-rw-r--r--gas/testsuite/gas/m32r/outofrange.s145
-rw-r--r--gas/testsuite/gas/m32r/relax-1.d18
-rw-r--r--gas/testsuite/gas/m32r/relax-1.s17
-rw-r--r--gas/testsuite/gas/m32r/uppercase.d26
-rw-r--r--gas/testsuite/gas/m32r/uppercase.s14
-rw-r--r--gas/testsuite/gas/m68k-coff/gas.exp15
-rw-r--r--gas/testsuite/gas/m68k-coff/p2389.s19
-rw-r--r--gas/testsuite/gas/m68k-coff/p2389a.s3
-rw-r--r--gas/testsuite/gas/m68k-coff/p2430.s6
-rw-r--r--gas/testsuite/gas/m68k-coff/p2430a.s4
-rw-r--r--gas/testsuite/gas/m68k-coff/t1.s36
-rw-r--r--gas/testsuite/gas/m68k/all.exp39
-rw-r--r--gas/testsuite/gas/m68k/bitfield.d28
-rw-r--r--gas/testsuite/gas/m68k/bitfield.s24
-rw-r--r--gas/testsuite/gas/m68k/cas.d20
-rw-r--r--gas/testsuite/gas/m68k/cas.s16
-rw-r--r--gas/testsuite/gas/m68k/disperr.s16
-rw-r--r--gas/testsuite/gas/m68k/fmoveml.d60
-rw-r--r--gas/testsuite/gas/m68k/fmoveml.s58
-rw-r--r--gas/testsuite/gas/m68k/link.d17
-rw-r--r--gas/testsuite/gas/m68k/link.s13
-rw-r--r--gas/testsuite/gas/m68k/op68000.d195
-rw-r--r--gas/testsuite/gas/m68k/operands.d242
-rw-r--r--gas/testsuite/gas/m68k/operands.s272
-rw-r--r--gas/testsuite/gas/m68k/p2410.s15
-rw-r--r--gas/testsuite/gas/m68k/p2663.s16
-rw-r--r--gas/testsuite/gas/m68k/pcrel.d88
-rw-r--r--gas/testsuite/gas/m68k/pcrel.s59
-rw-r--r--gas/testsuite/gas/m68k/pic1.s5
-rw-r--r--gas/testsuite/gas/m68k/t2.d8
-rw-r--r--gas/testsuite/gas/m68k/t2.s6
-rw-r--r--gas/testsuite/gas/m88k/init.d11
-rw-r--r--gas/testsuite/gas/m88k/init.s5
-rw-r--r--gas/testsuite/gas/m88k/m88k.exp10
-rw-r--r--gas/testsuite/gas/macros/err.s5
-rw-r--r--gas/testsuite/gas/macros/irp.d13
-rw-r--r--gas/testsuite/gas/macros/irp.s8
-rw-r--r--gas/testsuite/gas/macros/macros.exp22
-rw-r--r--gas/testsuite/gas/macros/rept.d10
-rw-r--r--gas/testsuite/gas/macros/rept.s3
-rw-r--r--gas/testsuite/gas/macros/semi.d8
-rw-r--r--gas/testsuite/gas/macros/semi.s14
-rw-r--r--gas/testsuite/gas/macros/test1.d5
-rw-r--r--gas/testsuite/gas/macros/test1.s7
-rw-r--r--gas/testsuite/gas/macros/test2.d10
-rw-r--r--gas/testsuite/gas/macros/test2.s9
-rw-r--r--gas/testsuite/gas/macros/test3.d8
-rw-r--r--gas/testsuite/gas/macros/test3.s7
-rw-r--r--gas/testsuite/gas/mcore/allinsn.d400
-rw-r--r--gas/testsuite/gas/mcore/allinsn.exp5
-rw-r--r--gas/testsuite/gas/mcore/allinsn.s146
-rw-r--r--gas/testsuite/gas/mips/abs.d15
-rw-r--r--gas/testsuite/gas/mips/abs.s5
-rw-r--r--gas/testsuite/gas/mips/add.d20
-rw-r--r--gas/testsuite/gas/mips/add.s16
-rw-r--r--gas/testsuite/gas/mips/and.d34
-rw-r--r--gas/testsuite/gas/mips/and.s28
-rw-r--r--gas/testsuite/gas/mips/beq.d40
-rw-r--r--gas/testsuite/gas/mips/beq.s28
-rw-r--r--gas/testsuite/gas/mips/bge.d53
-rw-r--r--gas/testsuite/gas/mips/bge.s31
-rw-r--r--gas/testsuite/gas/mips/bgeu.d47
-rw-r--r--gas/testsuite/gas/mips/bgeu.s27
-rw-r--r--gas/testsuite/gas/mips/blt.d53
-rw-r--r--gas/testsuite/gas/mips/blt.s31
-rw-r--r--gas/testsuite/gas/mips/bltu.d47
-rw-r--r--gas/testsuite/gas/mips/bltu.s27
-rw-r--r--gas/testsuite/gas/mips/break20.d18
-rw-r--r--gas/testsuite/gas/mips/break20.s17
-rw-r--r--gas/testsuite/gas/mips/delay.d20
-rw-r--r--gas/testsuite/gas/mips/delay.s8
-rw-r--r--gas/testsuite/gas/mips/div-ilocks.d110
-rw-r--r--gas/testsuite/gas/mips/div.d125
-rw-r--r--gas/testsuite/gas/mips/div.s41
-rw-r--r--gas/testsuite/gas/mips/dli.d115
-rw-r--r--gas/testsuite/gas/mips/dli.s67
-rw-r--r--gas/testsuite/gas/mips/elf_e_flags.c24
-rw-r--r--gas/testsuite/gas/mips/elf_e_flags.s43
-rw-r--r--gas/testsuite/gas/mips/elf_e_flags1.d26
-rw-r--r--gas/testsuite/gas/mips/elf_e_flags2.d26
-rw-r--r--gas/testsuite/gas/mips/elf_e_flags3.d26
-rw-r--r--gas/testsuite/gas/mips/elf_e_flags4.d26
-rw-r--r--gas/testsuite/gas/mips/itbl19
-rw-r--r--gas/testsuite/gas/mips/itbl.s18
-rw-r--r--gas/testsuite/gas/mips/jal-empic.d26
-rw-r--r--gas/testsuite/gas/mips/jal-svr4pic.d39
-rw-r--r--gas/testsuite/gas/mips/jal-svr4pic.s20
-rw-r--r--gas/testsuite/gas/mips/jal-xgot.d42
-rw-r--r--gas/testsuite/gas/mips/jal.d24
-rw-r--r--gas/testsuite/gas/mips/jal.s11
-rw-r--r--gas/testsuite/gas/mips/la-empic.d105
-rw-r--r--gas/testsuite/gas/mips/la-empic.s57
-rw-r--r--gas/testsuite/gas/mips/la-svr4pic.d474
-rw-r--r--gas/testsuite/gas/mips/la-xgot.d618
-rw-r--r--gas/testsuite/gas/mips/la.d384
-rw-r--r--gas/testsuite/gas/mips/la.s114
-rw-r--r--gas/testsuite/gas/mips/lb-empic.d102
-rw-r--r--gas/testsuite/gas/mips/lb-pic.s55
-rw-r--r--gas/testsuite/gas/mips/lb-svr4pic.d182
-rw-r--r--gas/testsuite/gas/mips/lb-xgot-ilocks.d214
-rw-r--r--gas/testsuite/gas/mips/lb-xgot.d242
-rw-r--r--gas/testsuite/gas/mips/lb.d395
-rw-r--r--gas/testsuite/gas/mips/lb.s125
-rw-r--r--gas/testsuite/gas/mips/ld-empic.d186
-rw-r--r--gas/testsuite/gas/mips/ld-ilocks-addr32.d632
-rw-r--r--gas/testsuite/gas/mips/ld-ilocks.d631
-rw-r--r--gas/testsuite/gas/mips/ld-pic.s60
-rw-r--r--gas/testsuite/gas/mips/ld-svr4pic.d225
-rw-r--r--gas/testsuite/gas/mips/ld-xgot.d273
-rw-r--r--gas/testsuite/gas/mips/ld.d639
-rw-r--r--gas/testsuite/gas/mips/ld.s144
-rw-r--r--gas/testsuite/gas/mips/li.d16
-rw-r--r--gas/testsuite/gas/mips/li.s12
-rw-r--r--gas/testsuite/gas/mips/lif-empic.d24
-rw-r--r--gas/testsuite/gas/mips/lif-svr4pic.d30
-rw-r--r--gas/testsuite/gas/mips/lif-xgot.d30
-rw-r--r--gas/testsuite/gas/mips/lifloat.d23
-rw-r--r--gas/testsuite/gas/mips/lifloat.s24
-rw-r--r--gas/testsuite/gas/mips/lineno.d97
-rw-r--r--gas/testsuite/gas/mips/lineno.s60
-rw-r--r--gas/testsuite/gas/mips/mips.exp102
-rw-r--r--gas/testsuite/gas/mips/mips16.d683
-rw-r--r--gas/testsuite/gas/mips/mips16.s258
-rw-r--r--gas/testsuite/gas/mips/mips4.d51
-rw-r--r--gas/testsuite/gas/mips/mips4.s52
-rw-r--r--gas/testsuite/gas/mips/mips4010.d23
-rw-r--r--gas/testsuite/gas/mips/mips4010.s20
-rw-r--r--gas/testsuite/gas/mips/mips4100.d15
-rw-r--r--gas/testsuite/gas/mips/mips4100.s10
-rw-r--r--gas/testsuite/gas/mips/mips4650.d14
-rw-r--r--gas/testsuite/gas/mips/mips4650.s8
-rw-r--r--gas/testsuite/gas/mips/mul-ilocks.d81
-rw-r--r--gas/testsuite/gas/mips/mul.d92
-rw-r--r--gas/testsuite/gas/mips/mul.s27
-rw-r--r--gas/testsuite/gas/mips/nodelay.d19
-rw-r--r--gas/testsuite/gas/mips/rol.d37
-rw-r--r--gas/testsuite/gas/mips/rol.s12
-rw-r--r--gas/testsuite/gas/mips/sb.d396
-rw-r--r--gas/testsuite/gas/mips/sb.s124
-rw-r--r--gas/testsuite/gas/mips/sync.d10
-rw-r--r--gas/testsuite/gas/mips/sync.s5
-rw-r--r--gas/testsuite/gas/mips/trap20.d20
-rw-r--r--gas/testsuite/gas/mips/trap20.s18
-rw-r--r--gas/testsuite/gas/mips/trunc.d29
-rw-r--r--gas/testsuite/gas/mips/trunc.s6
-rw-r--r--gas/testsuite/gas/mips/uld.d270
-rw-r--r--gas/testsuite/gas/mips/uld.s66
-rw-r--r--gas/testsuite/gas/mips/ulh-empic.d91
-rw-r--r--gas/testsuite/gas/mips/ulh-pic.s36
-rw-r--r--gas/testsuite/gas/mips/ulh-svr4pic.d124
-rw-r--r--gas/testsuite/gas/mips/ulh-xgot.d154
-rw-r--r--gas/testsuite/gas/mips/ulh.d374
-rw-r--r--gas/testsuite/gas/mips/ulh.s69
-rw-r--r--gas/testsuite/gas/mips/ulw.d270
-rw-r--r--gas/testsuite/gas/mips/ulw.s66
-rw-r--r--gas/testsuite/gas/mips/usd.d270
-rw-r--r--gas/testsuite/gas/mips/usd.s66
-rw-r--r--gas/testsuite/gas/mips/ush.d455
-rw-r--r--gas/testsuite/gas/mips/ush.s65
-rw-r--r--gas/testsuite/gas/mips/usw.d270
-rw-r--r--gas/testsuite/gas/mips/usw.s66
-rw-r--r--gas/testsuite/gas/mn10200/add.s13
-rw-r--r--gas/testsuite/gas/mn10200/basic.exp836
-rw-r--r--gas/testsuite/gas/mn10200/bcc.s17
-rw-r--r--gas/testsuite/gas/mn10200/bccx.s16
-rw-r--r--gas/testsuite/gas/mn10200/bit.s5
-rw-r--r--gas/testsuite/gas/mn10200/cmp.s10
-rw-r--r--gas/testsuite/gas/mn10200/ext.s7
-rw-r--r--gas/testsuite/gas/mn10200/logical.s12
-rw-r--r--gas/testsuite/gas/mn10200/mov1.s13
-rw-r--r--gas/testsuite/gas/mn10200/mov2.s10
-rw-r--r--gas/testsuite/gas/mn10200/mov3.s11
-rw-r--r--gas/testsuite/gas/mn10200/mov4.s9
-rw-r--r--gas/testsuite/gas/mn10200/movb.s13
-rw-r--r--gas/testsuite/gas/mn10200/movbu.s8
-rw-r--r--gas/testsuite/gas/mn10200/movx.s7
-rw-r--r--gas/testsuite/gas/mn10200/muldiv.s4
-rw-r--r--gas/testsuite/gas/mn10200/other.s10
-rw-r--r--gas/testsuite/gas/mn10200/shift.s5
-rw-r--r--gas/testsuite/gas/mn10200/sub.s10
-rw-r--r--gas/testsuite/gas/mn10300/add.s15
-rw-r--r--gas/testsuite/gas/mn10300/basic.exp986
-rw-r--r--gas/testsuite/gas/mn10300/bcc.s17
-rw-r--r--gas/testsuite/gas/mn10300/bit.s12
-rw-r--r--gas/testsuite/gas/mn10300/cmp.s11
-rw-r--r--gas/testsuite/gas/mn10300/ext.s7
-rw-r--r--gas/testsuite/gas/mn10300/extend.s15
-rw-r--r--gas/testsuite/gas/mn10300/logical.s15
-rw-r--r--gas/testsuite/gas/mn10300/loop.s15
-rw-r--r--gas/testsuite/gas/mn10300/mov1.s17
-rw-r--r--gas/testsuite/gas/mn10300/mov2.s16
-rw-r--r--gas/testsuite/gas/mn10300/mov3.s16
-rw-r--r--gas/testsuite/gas/mn10300/mov4.s13
-rw-r--r--gas/testsuite/gas/mn10300/movbu.s21
-rw-r--r--gas/testsuite/gas/mn10300/movhu.s21
-rw-r--r--gas/testsuite/gas/mn10300/movm.s5
-rw-r--r--gas/testsuite/gas/mn10300/muldiv.s5
-rw-r--r--gas/testsuite/gas/mn10300/other.s20
-rw-r--r--gas/testsuite/gas/mn10300/shift.s10
-rw-r--r--gas/testsuite/gas/mn10300/sub.s8
-rw-r--r--gas/testsuite/gas/mn10300/udf.s129
-rw-r--r--gas/testsuite/gas/mri/char.d9
-rw-r--r--gas/testsuite/gas/mri/char.s6
-rw-r--r--gas/testsuite/gas/mri/comment.d9
-rw-r--r--gas/testsuite/gas/mri/comment.s13
-rw-r--r--gas/testsuite/gas/mri/common.d8
-rw-r--r--gas/testsuite/gas/mri/common.s11
-rw-r--r--gas/testsuite/gas/mri/constants.d20
-rw-r--r--gas/testsuite/gas/mri/constants.s31
-rw-r--r--gas/testsuite/gas/mri/empty.s9
-rw-r--r--gas/testsuite/gas/mri/equ.d7
-rw-r--r--gas/testsuite/gas/mri/equ.s3
-rw-r--r--gas/testsuite/gas/mri/expr.d11
-rw-r--r--gas/testsuite/gas/mri/expr.s7
-rw-r--r--gas/testsuite/gas/mri/float.d10
-rw-r--r--gas/testsuite/gas/mri/float.s7
-rw-r--r--gas/testsuite/gas/mri/for.d30
-rw-r--r--gas/testsuite/gas/mri/for.s22
-rw-r--r--gas/testsuite/gas/mri/if.d25
-rw-r--r--gas/testsuite/gas/mri/if.s17
-rw-r--r--gas/testsuite/gas/mri/immconst.d22
-rw-r--r--gas/testsuite/gas/mri/label.d8
-rw-r--r--gas/testsuite/gas/mri/label.s5
-rw-r--r--gas/testsuite/gas/mri/moveml.d27
-rw-r--r--gas/testsuite/gas/mri/moveml.s17
-rw-r--r--gas/testsuite/gas/mri/mri.exp28
-rw-r--r--gas/testsuite/gas/mri/repeat.d16
-rw-r--r--gas/testsuite/gas/mri/repeat.s14
-rw-r--r--gas/testsuite/gas/mri/semi.d9
-rw-r--r--gas/testsuite/gas/mri/semi.s14
-rw-r--r--gas/testsuite/gas/mri/while.d18
-rw-r--r--gas/testsuite/gas/mri/while.s14
-rw-r--r--gas/testsuite/gas/ppc/astest.d74
-rw-r--r--gas/testsuite/gas/ppc/astest.s52
-rw-r--r--gas/testsuite/gas/ppc/astest2.d75
-rw-r--r--gas/testsuite/gas/ppc/astest2.s52
-rw-r--r--gas/testsuite/gas/ppc/ppc.exp21
-rw-r--r--gas/testsuite/gas/ppc/simpshft.d27
-rw-r--r--gas/testsuite/gas/ppc/simpshft.s110
-rw-r--r--gas/testsuite/gas/sh/basic.exp86
-rw-r--r--gas/testsuite/gas/sh/fp.s44
-rw-r--r--gas/testsuite/gas/sparc-solaris/addend.exp36
-rw-r--r--gas/testsuite/gas/sparc-solaris/addend.s11
-rw-r--r--gas/testsuite/gas/sparc-solaris/gas.exp10
-rw-r--r--gas/testsuite/gas/sparc-solaris/sol-cc.s81
-rw-r--r--gas/testsuite/gas/sparc-solaris/sol-gcc.s66
-rw-r--r--gas/testsuite/gas/sparc/asi.d35
-rw-r--r--gas/testsuite/gas/sparc/asi.s28
-rw-r--r--gas/testsuite/gas/sparc/membar.d19
-rw-r--r--gas/testsuite/gas/sparc/membar.s12
-rw-r--r--gas/testsuite/gas/sparc/mism-1.s22
-rw-r--r--gas/testsuite/gas/sparc/mismatch.exp20
-rw-r--r--gas/testsuite/gas/sparc/prefetch.d19
-rw-r--r--gas/testsuite/gas/sparc/prefetch.s11
-rw-r--r--gas/testsuite/gas/sparc/rdpr.d26
-rw-r--r--gas/testsuite/gas/sparc/rdpr.s19
-rw-r--r--gas/testsuite/gas/sparc/reloc64.d76
-rw-r--r--gas/testsuite/gas/sparc/reloc64.s48
-rw-r--r--gas/testsuite/gas/sparc/set64.d88
-rw-r--r--gas/testsuite/gas/sparc/set64.s43
-rw-r--r--gas/testsuite/gas/sparc/sparc.exp27
-rw-r--r--gas/testsuite/gas/sparc/splet-2.d23
-rw-r--r--gas/testsuite/gas/sparc/splet-2.s21
-rw-r--r--gas/testsuite/gas/sparc/splet.d195
-rw-r--r--gas/testsuite/gas/sparc/splet.s211
-rw-r--r--gas/testsuite/gas/sparc/synth.d11
-rw-r--r--gas/testsuite/gas/sparc/synth.s7
-rw-r--r--gas/testsuite/gas/sparc/synth64.d19
-rw-r--r--gas/testsuite/gas/sparc/synth64.s16
-rw-r--r--gas/testsuite/gas/sparc/wrpr.d24
-rw-r--r--gas/testsuite/gas/sparc/wrpr.s17
-rw-r--r--gas/testsuite/gas/sun4/addend.d13
-rw-r--r--gas/testsuite/gas/sun4/addend.exp7
-rw-r--r--gas/testsuite/gas/sun4/addend.s11
-rw-r--r--gas/testsuite/gas/template96
-rw-r--r--gas/testsuite/gas/tic80/add.d22
-rw-r--r--gas/testsuite/gas/tic80/add.lst34
-rw-r--r--gas/testsuite/gas/tic80/add.s19
-rw-r--r--gas/testsuite/gas/tic80/align.d19
-rw-r--r--gas/testsuite/gas/tic80/align.lst47
-rw-r--r--gas/testsuite/gas/tic80/align.s37
-rw-r--r--gas/testsuite/gas/tic80/bitnum.d82
-rw-r--r--gas/testsuite/gas/tic80/bitnum.lst97
-rw-r--r--gas/testsuite/gas/tic80/bitnum.s85
-rw-r--r--gas/testsuite/gas/tic80/ccode.d32
-rw-r--r--gas/testsuite/gas/tic80/ccode.lst37
-rw-r--r--gas/testsuite/gas/tic80/ccode.s30
-rw-r--r--gas/testsuite/gas/tic80/cregops.d68
-rw-r--r--gas/testsuite/gas/tic80/cregops.lst76
-rw-r--r--gas/testsuite/gas/tic80/cregops.s64
-rw-r--r--gas/testsuite/gas/tic80/endmask.d41
-rw-r--r--gas/testsuite/gas/tic80/endmask.lst45
-rw-r--r--gas/testsuite/gas/tic80/endmask.s38
-rw-r--r--gas/testsuite/gas/tic80/float.d40
-rw-r--r--gas/testsuite/gas/tic80/float.lst76
-rw-r--r--gas/testsuite/gas/tic80/float.s32
-rw-r--r--gas/testsuite/gas/tic80/regops.d188
-rw-r--r--gas/testsuite/gas/tic80/regops.lst264
-rw-r--r--gas/testsuite/gas/tic80/regops.s237
-rw-r--r--gas/testsuite/gas/tic80/regops2.d68
-rw-r--r--gas/testsuite/gas/tic80/regops2.lst96
-rw-r--r--gas/testsuite/gas/tic80/regops2.s60
-rw-r--r--gas/testsuite/gas/tic80/regops3.d28
-rw-r--r--gas/testsuite/gas/tic80/regops3.lst27
-rw-r--r--gas/testsuite/gas/tic80/regops3.s20
-rw-r--r--gas/testsuite/gas/tic80/regops4.d28
-rw-r--r--gas/testsuite/gas/tic80/regops4.lst27
-rw-r--r--gas/testsuite/gas/tic80/regops4.s20
-rw-r--r--gas/testsuite/gas/tic80/relocs1.c28
-rw-r--r--gas/testsuite/gas/tic80/relocs1.d56
-rw-r--r--gas/testsuite/gas/tic80/relocs1.lst80
-rw-r--r--gas/testsuite/gas/tic80/relocs1.s66
-rw-r--r--gas/testsuite/gas/tic80/relocs1b.d12
-rw-r--r--gas/testsuite/gas/tic80/relocs2.c41
-rw-r--r--gas/testsuite/gas/tic80/relocs2.d37
-rw-r--r--gas/testsuite/gas/tic80/relocs2.lst112
-rw-r--r--gas/testsuite/gas/tic80/relocs2.s72
-rw-r--r--gas/testsuite/gas/tic80/relocs2b.d38
-rw-r--r--gas/testsuite/gas/tic80/tic80.exp21
-rw-r--r--gas/testsuite/gas/v850/arith.s24
-rw-r--r--gas/testsuite/gas/v850/basic.exp438
-rw-r--r--gas/testsuite/gas/v850/bit.s8
-rw-r--r--gas/testsuite/gas/v850/branch.s24
-rw-r--r--gas/testsuite/gas/v850/compare.s28
-rw-r--r--gas/testsuite/gas/v850/fepsw.s2
-rw-r--r--gas/testsuite/gas/v850/hilo.s5
-rw-r--r--gas/testsuite/gas/v850/hilo2.s4
-rw-r--r--gas/testsuite/gas/v850/jumps.s8
-rw-r--r--gas/testsuite/gas/v850/logical.s11
-rw-r--r--gas/testsuite/gas/v850/mem.s16
-rw-r--r--gas/testsuite/gas/v850/misc.s13
-rw-r--r--gas/testsuite/gas/v850/move.s8
-rw-r--r--gas/testsuite/gas/v850/range.s2
-rw-r--r--gas/testsuite/gas/v850/reloc.s7
-rw-r--r--gas/testsuite/gas/vax/quad.exp23
-rw-r--r--gas/testsuite/gas/vax/quad.s2
-rw-r--r--gas/testsuite/gas/vtable/entry0.d10
-rw-r--r--gas/testsuite/gas/vtable/entry0.s2
-rw-r--r--gas/testsuite/gas/vtable/entry1.d10
-rw-r--r--gas/testsuite/gas/vtable/entry1.s2
-rw-r--r--gas/testsuite/gas/vtable/inherit0.d10
-rw-r--r--gas/testsuite/gas/vtable/inherit0.s13
-rw-r--r--gas/testsuite/gas/vtable/inherit1.l6
-rw-r--r--gas/testsuite/gas/vtable/inherit1.s1
-rw-r--r--gas/testsuite/gas/vtable/vtable.exp39
-rw-r--r--gas/testsuite/gasp/INC1.H3
-rw-r--r--gas/testsuite/gasp/INC2.H2
-rw-r--r--gas/testsuite/gasp/assign.asm13
-rw-r--r--gas/testsuite/gasp/assign.err1
-rw-r--r--gas/testsuite/gasp/assign.out22
-rw-r--r--gas/testsuite/gasp/condass.asm129
-rw-r--r--gas/testsuite/gasp/condass.err0
-rw-r--r--gas/testsuite/gasp/condass.out155
-rw-r--r--gas/testsuite/gasp/crash.asm22
-rw-r--r--gas/testsuite/gasp/crash.err1
-rw-r--r--gas/testsuite/gasp/crash.out3059
-rw-r--r--gas/testsuite/gasp/crash1.asm13
-rw-r--r--gas/testsuite/gasp/crash1.err0
-rw-r--r--gas/testsuite/gasp/crash1.out24
-rw-r--r--gas/testsuite/gasp/crash2.asm41
-rw-r--r--gas/testsuite/gasp/crash2.err0
-rw-r--r--gas/testsuite/gasp/crash2.out69
-rw-r--r--gas/testsuite/gasp/data.asm23
-rw-r--r--gas/testsuite/gasp/data.err0
-rw-r--r--gas/testsuite/gasp/data.out45
-rw-r--r--gas/testsuite/gasp/exp.asm80
-rw-r--r--gas/testsuite/gasp/exp.err7
-rw-r--r--gas/testsuite/gasp/exp.out124
-rw-r--r--gas/testsuite/gasp/gasp.exp40
-rw-r--r--gas/testsuite/gasp/include.asm4
-rw-r--r--gas/testsuite/gasp/include.err0
-rw-r--r--gas/testsuite/gasp/include.out15
-rw-r--r--gas/testsuite/gasp/listing.asm15
-rw-r--r--gas/testsuite/gasp/listing.err0
-rw-r--r--gas/testsuite/gasp/listing.out28
-rw-r--r--gas/testsuite/gasp/macro.asm102
-rw-r--r--gas/testsuite/gasp/macro.err0
-rw-r--r--gas/testsuite/gasp/macro.out382
-rw-r--r--gas/testsuite/gasp/mdouble.asm47
-rw-r--r--gas/testsuite/gasp/mdouble.err0
-rw-r--r--gas/testsuite/gasp/mdouble.out68
-rw-r--r--gas/testsuite/gasp/mri/embed.asm5
-rw-r--r--gas/testsuite/gasp/mri/embed.out9
-rw-r--r--gas/testsuite/gasp/mri/exists.asm10
-rw-r--r--gas/testsuite/gasp/mri/exists.out24
-rw-r--r--gas/testsuite/gasp/mri/irp.asm4
-rw-r--r--gas/testsuite/gasp/mri/irp.out8
-rw-r--r--gas/testsuite/gasp/mri/irpc.asm3
-rw-r--r--gas/testsuite/gasp/mri/irpc.out8
-rw-r--r--gas/testsuite/gasp/mri/macro.asm8
-rw-r--r--gas/testsuite/gasp/mri/macro.out18
-rw-r--r--gas/testsuite/gasp/mri/narg.asm9
-rw-r--r--gas/testsuite/gasp/mri/narg.out38
-rw-r--r--gas/testsuite/gasp/mri/rept.asm3
-rw-r--r--gas/testsuite/gasp/mri/rept.out16
-rw-r--r--gas/testsuite/gasp/pl1.asm20
-rw-r--r--gas/testsuite/gasp/pl1.err1
-rw-r--r--gas/testsuite/gasp/pl1.out49
-rw-r--r--gas/testsuite/gasp/pl2.asm28
-rw-r--r--gas/testsuite/gasp/pl2.err0
-rw-r--r--gas/testsuite/gasp/pl2.out51
-rw-r--r--gas/testsuite/gasp/pl3.asm30
-rw-r--r--gas/testsuite/gasp/pl3.err0
-rw-r--r--gas/testsuite/gasp/pl3.out86
-rw-r--r--gas/testsuite/gasp/pl4.asm10
-rw-r--r--gas/testsuite/gasp/pl4.err0
-rw-r--r--gas/testsuite/gasp/pl4.out16
-rw-r--r--gas/testsuite/gasp/pl5.asm15
-rw-r--r--gas/testsuite/gasp/pl5.err0
-rw-r--r--gas/testsuite/gasp/pl5.out32
-rw-r--r--gas/testsuite/gasp/pl6.asm21
-rw-r--r--gas/testsuite/gasp/pl6.err0
-rw-r--r--gas/testsuite/gasp/pl6.out54
-rw-r--r--gas/testsuite/gasp/pl7.asm12
-rw-r--r--gas/testsuite/gasp/pl7.err1
-rw-r--r--gas/testsuite/gasp/pl7.out26
-rw-r--r--gas/testsuite/gasp/pl8.asm18
-rw-r--r--gas/testsuite/gasp/pl8.err0
-rw-r--r--gas/testsuite/gasp/pl8.out33
-rw-r--r--gas/testsuite/gasp/pr7583.asm3
-rw-r--r--gas/testsuite/gasp/pr7583.err0
-rw-r--r--gas/testsuite/gasp/pr7583.out5
-rw-r--r--gas/testsuite/gasp/reg.asm9
-rw-r--r--gas/testsuite/gasp/reg.err0
-rw-r--r--gas/testsuite/gasp/reg.out15
-rw-r--r--gas/testsuite/gasp/rep.asm13
-rw-r--r--gas/testsuite/gasp/rep.err0
-rw-r--r--gas/testsuite/gasp/rep.out391
-rw-r--r--gas/testsuite/gasp/repeat.asm14
-rw-r--r--gas/testsuite/gasp/repeat.err0
-rw-r--r--gas/testsuite/gasp/repeat.out211
-rw-r--r--gas/testsuite/gasp/reperr.asm2
-rw-r--r--gas/testsuite/gasp/reperr.err1
-rw-r--r--gas/testsuite/gasp/reperr.out5
-rw-r--r--gas/testsuite/gasp/reperr1.asm3
-rw-r--r--gas/testsuite/gasp/reperr1.err1
-rw-r--r--gas/testsuite/gasp/reperr1.out5
-rw-r--r--gas/testsuite/gasp/reperr2.asm6
-rw-r--r--gas/testsuite/gasp/reperr2.err1
-rw-r--r--gas/testsuite/gasp/reperr2.out14
-rw-r--r--gas/testsuite/gasp/reperr3.asm21
-rw-r--r--gas/testsuite/gasp/reperr3.err6
-rw-r--r--gas/testsuite/gasp/reperr3.out2035
-rw-r--r--gas/testsuite/gasp/sdata.asm24
-rw-r--r--gas/testsuite/gasp/sdata.err3
-rw-r--r--gas/testsuite/gasp/sdata.out59
-rw-r--r--gas/testsuite/gasp/sfunc.asm26
-rw-r--r--gas/testsuite/gasp/sfunc.err0
-rw-r--r--gas/testsuite/gasp/sfunc.out49
-rw-r--r--gas/testsuite/gasp/t1.asm3
-rw-r--r--gas/testsuite/gasp/t1.err0
-rw-r--r--gas/testsuite/gasp/t1.out5
-rw-r--r--gas/testsuite/gasp/t2.asm8
-rw-r--r--gas/testsuite/gasp/t2.err0
-rw-r--r--gas/testsuite/gasp/t2.out13
-rw-r--r--gas/testsuite/gasp/t3.asm12
-rw-r--r--gas/testsuite/gasp/t3.err1
-rw-r--r--gas/testsuite/gasp/t3.out25
-rw-r--r--gas/testsuite/gasp/while.asm18
-rw-r--r--gas/testsuite/gasp/while.err0
-rw-r--r--gas/testsuite/gasp/while.out388
-rwxr-xr-xgas/testsuite/lib/doboth19
-rwxr-xr-xgas/testsuite/lib/doobjcmp88
-rwxr-xr-xgas/testsuite/lib/dostriptest14
-rwxr-xr-xgas/testsuite/lib/dotest43
-rwxr-xr-xgas/testsuite/lib/dounsreloc8
-rwxr-xr-xgas/testsuite/lib/dounssym8
-rw-r--r--gas/testsuite/lib/gas-defs.exp574
-rw-r--r--gas/testsuite/lib/gas-dg.exp53
-rwxr-xr-xgas/testsuite/lib/run2
-rw-r--r--gas/vmsconf.sh128
-rw-r--r--gas/write.c2884
-rw-r--r--gas/write.h208
-rw-r--r--gprof/.gdbinit1
-rw-r--r--gprof/ChangeLog1319
-rw-r--r--gprof/Makefile.am74
-rw-r--r--gprof/Makefile.in726
-rw-r--r--gprof/NOTES438
-rw-r--r--gprof/TEST7
-rw-r--r--gprof/TODO72
-rw-r--r--gprof/aclocal.m41109
-rw-r--r--gprof/alpha.c168
-rw-r--r--gprof/basic_blocks.c635
-rw-r--r--gprof/basic_blocks.h23
-rw-r--r--gprof/bb_exit_func.c78
-rwxr-xr-xgprof/bbconv.pl36
-rw-r--r--gprof/bsd_callg_bl.m108
-rw-r--r--gprof/call_graph.c116
-rw-r--r--gprof/call_graph.h13
-rw-r--r--gprof/cg_arcs.c685
-rw-r--r--gprof/cg_arcs.h36
-rw-r--r--gprof/cg_dfn.c281
-rw-r--r--gprof/cg_dfn.h17
-rw-r--r--gprof/cg_print.c1276
-rw-r--r--gprof/cg_print.h14
-rwxr-xr-xgprof/configure4403
-rw-r--r--gprof/configure.bat18
-rw-r--r--gprof/configure.in29
-rw-r--r--gprof/corefile.c762
-rw-r--r--gprof/corefile.h21
-rw-r--r--gprof/flat_bl.m27
-rw-r--r--gprof/fsf_callg_bl.m83
-rw-r--r--gprof/gconfig.in129
-rw-r--r--gprof/gen-c-prog.awk26
-rw-r--r--gprof/gmon.h156
-rw-r--r--gprof/gmon_io.c454
-rw-r--r--gprof/gmon_io.h20
-rw-r--r--gprof/gmon_out.h51
-rw-r--r--gprof/gprof.1252
-rw-r--r--gprof/gprof.c659
-rw-r--r--gprof/gprof.h157
-rw-r--r--gprof/gprof.texi2028
-rw-r--r--gprof/hertz.c54
-rw-r--r--gprof/hertz.h22
-rw-r--r--gprof/hist.c596
-rw-r--r--gprof/hist.h23
-rw-r--r--gprof/i386.c104
-rw-r--r--gprof/po/Make-in251
-rw-r--r--gprof/po/POTFILES.in38
-rw-r--r--gprof/po/gprof.pot470
-rw-r--r--gprof/search_list.c44
-rw-r--r--gprof/search_list.h20
-rw-r--r--gprof/source.c223
-rw-r--r--gprof/source.h55
-rw-r--r--gprof/sparc.c88
-rw-r--r--gprof/stamp-h.in1
-rw-r--r--gprof/sym_ids.c372
-rw-r--r--gprof/sym_ids.h25
-rw-r--r--gprof/symtab.c269
-rw-r--r--gprof/symtab.h111
-rw-r--r--gprof/tahoe.c345
-rw-r--r--gprof/utils.c106
-rw-r--r--gprof/utils.h7
-rw-r--r--gprof/vax.c350
-rw-r--r--include/COPYING340
-rw-r--r--include/ChangeLog1527
-rw-r--r--include/ansidecl.h163
-rw-r--r--include/aout/ChangeLog178
-rw-r--r--include/aout/adobe.h297
-rw-r--r--include/aout/aout64.h475
-rw-r--r--include/aout/ar.h36
-rw-r--r--include/aout/dynix3.h71
-rw-r--r--include/aout/encap.h135
-rw-r--r--include/aout/host.h22
-rw-r--r--include/aout/hp.h82
-rw-r--r--include/aout/hp300hpux.h119
-rw-r--r--include/aout/hppa.h7
-rw-r--r--include/aout/ranlib.h62
-rw-r--r--include/aout/reloc.h66
-rw-r--r--include/aout/stab.def268
-rw-r--r--include/aout/stab_gnu.h37
-rw-r--r--include/aout/sun4.h219
-rw-r--r--include/bfdlink.h520
-rw-r--r--include/bout.h182
-rw-r--r--include/callback.h270
-rw-r--r--include/coff/ChangeLog793
-rw-r--r--include/coff/a29k.h305
-rw-r--r--include/coff/alpha.h362
-rw-r--r--include/coff/apollo.h252
-rw-r--r--include/coff/arm.h258
-rw-r--r--include/coff/aux-coff.h31
-rw-r--r--include/coff/ecoff.h421
-rw-r--r--include/coff/go32exe.h20
-rw-r--r--include/coff/h8300.h204
-rw-r--r--include/coff/h8500.h201
-rw-r--r--include/coff/i386.h228
-rw-r--r--include/coff/i860.h205
-rw-r--r--include/coff/i960.h275
-rw-r--r--include/coff/internal.h728
-rw-r--r--include/coff/m68k.h225
-rw-r--r--include/coff/m88k.h219
-rw-r--r--include/coff/mcore.h245
-rw-r--r--include/coff/mips.h369
-rw-r--r--include/coff/pe.h169
-rw-r--r--include/coff/powerpc.h199
-rw-r--r--include/coff/rs6000.h243
-rw-r--r--include/coff/sh.h269
-rw-r--r--include/coff/sparc.h210
-rw-r--r--include/coff/sym.h484
-rw-r--r--include/coff/symconst.h177
-rw-r--r--include/coff/tic30.h203
-rw-r--r--include/coff/tic80.h228
-rw-r--r--include/coff/w65.h201
-rw-r--r--include/coff/we32k.h206
-rw-r--r--include/coff/z8k.h201
-rw-r--r--include/demangle.h95
-rw-r--r--include/dis-asm.h243
-rw-r--r--include/elf/ChangeLog719
-rw-r--r--include/elf/alpha.h108
-rw-r--r--include/elf/arc.h54
-rw-r--r--include/elf/arm-oabi.h87
-rw-r--r--include/elf/arm.h96
-rw-r--r--include/elf/common.h454
-rw-r--r--include/elf/d10v.h38
-rw-r--r--include/elf/d30v.h42
-rw-r--r--include/elf/dwarf.h319
-rw-r--r--include/elf/dwarf2.h637
-rw-r--r--include/elf/external.h256
-rw-r--r--include/elf/fr30.h43
-rw-r--r--include/elf/hppa.h187
-rw-r--r--include/elf/i386.h49
-rw-r--r--include/elf/internal.h312
-rw-r--r--include/elf/m32r.h66
-rw-r--r--include/elf/m68k.h56
-rw-r--r--include/elf/mcore.h43
-rw-r--r--include/elf/mips.h860
-rw-r--r--include/elf/mn10200.h39
-rw-r--r--include/elf/mn10300.h53
-rw-r--r--include/elf/ppc.h127
-rw-r--r--include/elf/reloc-macros.h116
-rw-r--r--include/elf/sh.h55
-rw-r--r--include/elf/sparc.h156
-rw-r--r--include/elf/v850.h111
-rw-r--r--include/floatformat.h111
-rw-r--r--include/fnmatch.h70
-rw-r--r--include/fopen-bin.h27
-rw-r--r--include/fopen-same.h27
-rw-r--r--include/fopen-vms.h24
-rw-r--r--include/gdbm.h91
-rw-r--r--include/getopt.h133
-rw-r--r--include/hp-symtab.h1871
-rw-r--r--include/ieee.h139
-rw-r--r--include/libiberty.h180
-rw-r--r--include/mpw/ChangeLog61
-rw-r--r--include/mpw/README1
-rw-r--r--include/mpw/dir.h23
-rw-r--r--include/mpw/dirent.h31
-rw-r--r--include/mpw/fcntl.h124
-rw-r--r--include/mpw/grp.h10
-rw-r--r--include/mpw/mpw.h130
-rw-r--r--include/mpw/pwd.h15
-rw-r--r--include/mpw/spin.h64
-rw-r--r--include/mpw/stat.h75
-rw-r--r--include/mpw/sys/file.h1
-rw-r--r--include/mpw/sys/param.h1
-rw-r--r--include/mpw/sys/resource.h9
-rw-r--r--include/mpw/sys/stat.h44
-rw-r--r--include/mpw/sys/time.h13
-rw-r--r--include/mpw/sys/types.h15
-rw-r--r--include/mpw/utime.h7
-rw-r--r--include/mpw/varargs.h9
-rw-r--r--include/nlm/ChangeLog83
-rw-r--r--include/nlm/alpha-ext.h166
-rw-r--r--include/nlm/common.h124
-rw-r--r--include/nlm/external.h174
-rw-r--r--include/nlm/i386-ext.h116
-rw-r--r--include/nlm/internal.h309
-rw-r--r--include/nlm/ppc-ext.h163
-rw-r--r--include/nlm/sparc32-ext.h120
-rw-r--r--include/oasys.h152
-rw-r--r--include/objalloc.h116
-rw-r--r--include/obstack.h593
-rw-r--r--include/opcode/ChangeLog1873
-rw-r--r--include/opcode/a29k.h285
-rw-r--r--include/opcode/alpha.h238
-rw-r--r--include/opcode/arc.h274
-rw-r--r--include/opcode/arm.h294
-rw-r--r--include/opcode/cgen.h1380
-rw-r--r--include/opcode/convex.h1711
-rw-r--r--include/opcode/d10v.h194
-rw-r--r--include/opcode/d30v.h273
-rw-r--r--include/opcode/h8300.h604
-rw-r--r--include/opcode/hppa.h486
-rw-r--r--include/opcode/i386.h1063
-rw-r--r--include/opcode/i860.h491
-rw-r--r--include/opcode/i960.h509
-rw-r--r--include/opcode/m68k.h315
-rw-r--r--include/opcode/m88k.h923
-rw-r--r--include/opcode/mips.h723
-rw-r--r--include/opcode/mn10200.h110
-rw-r--r--include/opcode/mn10300.h138
-rw-r--r--include/opcode/np1.h422
-rw-r--r--include/opcode/ns32k.h491
-rw-r--r--include/opcode/pn.h282
-rw-r--r--include/opcode/ppc.h248
-rw-r--r--include/opcode/pyr.h287
-rw-r--r--include/opcode/sparc.h240
-rw-r--r--include/opcode/tahoe.h213
-rw-r--r--include/opcode/tic30.h691
-rw-r--r--include/opcode/tic80.h277
-rw-r--r--include/opcode/v850.h166
-rw-r--r--include/opcode/vax.h382
-rw-r--r--include/os9k.h169
-rw-r--r--include/progress.h37
-rw-r--r--include/regs/ChangeLog0
-rw-r--r--include/remote-sim.h321
-rw-r--r--include/splay-tree.h116
-rw-r--r--include/symcat.h40
-rw-r--r--include/wait.h63
-rwxr-xr-xinstall-sh251
-rw-r--r--intl/ChangeLog1022
-rw-r--r--intl/ChangeLog.Cygnus30
-rw-r--r--intl/Makefile.in214
-rw-r--r--intl/acconfig.h14
-rw-r--r--intl/aclocal.m4387
-rw-r--r--intl/bindtextdom.c199
-rw-r--r--intl/cat-compat.c262
-rw-r--r--intl/config.in128
-rwxr-xr-xintl/configure2950
-rw-r--r--intl/configure.in10
-rw-r--r--intl/dcgettext.c593
-rw-r--r--intl/dgettext.c59
-rw-r--r--intl/explodename.c181
-rw-r--r--intl/finddomain.c189
-rw-r--r--intl/gettext.c70
-rw-r--r--intl/gettext.h105
-rw-r--r--intl/gettextP.h73
-rw-r--r--intl/hash-string.h63
-rw-r--r--intl/intl-compat.c76
-rw-r--r--intl/intlh.inst.in111
-rw-r--r--intl/l10nflist.c409
-rw-r--r--intl/libgettext.h182
-rw-r--r--intl/libintl.glibc111
-rw-r--r--intl/linux-msg.sed100
-rw-r--r--intl/loadinfo.h58
-rw-r--r--intl/loadmsgcat.c199
-rw-r--r--intl/localealias.c378
-rw-r--r--intl/po2tbl.sed.in102
-rw-r--r--intl/textdomain.c106
-rw-r--r--intl/xopen-msg.sed104
-rw-r--r--ld/ChangeLog8933
-rw-r--r--ld/Makefile.am863
-rw-r--r--ld/Makefile.in1546
-rw-r--r--ld/NEWS190
-rw-r--r--ld/README64
-rw-r--r--ld/TODO9
-rw-r--r--ld/acinclude.m41
-rw-r--r--ld/aclocal.m41120
-rw-r--r--ld/config.in171
-rwxr-xr-xld/configure5214
-rw-r--r--ld/configure.bat72
-rw-r--r--ld/configure.host171
-rw-r--r--ld/configure.in156
-rw-r--r--ld/configure.tgt249
-rw-r--r--ld/deffile.h123
-rw-r--r--ld/deffilep.y1004
-rw-r--r--ld/dep-in.sed16
-rw-r--r--ld/emulparams/README2
-rw-r--r--ld/emulparams/a29k.sh5
-rw-r--r--ld/emulparams/aixppc.sh4
-rw-r--r--ld/emulparams/aixrs6.sh4
-rw-r--r--ld/emulparams/alpha.sh3
-rw-r--r--ld/emulparams/arcelf.sh11
-rw-r--r--ld/emulparams/arm_epoc_pe.sh6
-rw-r--r--ld/emulparams/armaoutb.sh7
-rw-r--r--ld/emulparams/armaoutl.sh7
-rw-r--r--ld/emulparams/armcoff.sh6
-rw-r--r--ld/emulparams/armelf.sh21
-rw-r--r--ld/emulparams/armelf_linux.sh17
-rw-r--r--ld/emulparams/armelf_linux26.sh16
-rw-r--r--ld/emulparams/armelf_oabi.sh21
-rw-r--r--ld/emulparams/armpe.sh6
-rw-r--r--ld/emulparams/coff_sparc.sh7
-rw-r--r--ld/emulparams/d10velf.sh9
-rw-r--r--ld/emulparams/d30v_e.sh20
-rw-r--r--ld/emulparams/d30v_o.sh20
-rw-r--r--ld/emulparams/d30velf.sh20
-rw-r--r--ld/emulparams/delta68.sh5
-rw-r--r--ld/emulparams/ebmon29k.sh5
-rw-r--r--ld/emulparams/elf32_sparc.sh11
-rw-r--r--ld/emulparams/elf32b4300.sh29
-rw-r--r--ld/emulparams/elf32bmip.sh30
-rw-r--r--ld/emulparams/elf32bsmip.sh31
-rw-r--r--ld/emulparams/elf32ebmip.sh28
-rw-r--r--ld/emulparams/elf32elmip.sh28
-rwxr-xr-xld/emulparams/elf32fr30.sh10
-rw-r--r--ld/emulparams/elf32l4300.sh29
-rw-r--r--ld/emulparams/elf32lmip.sh30
-rw-r--r--ld/emulparams/elf32lppc.sh8
-rw-r--r--ld/emulparams/elf32lsmip.sh31
-rw-r--r--ld/emulparams/elf32mcore.sh20
-rw-r--r--ld/emulparams/elf32ppc.sh8
-rw-r--r--ld/emulparams/elf64_sparc.sh12
-rw-r--r--ld/emulparams/elf64alpha.sh15
-rw-r--r--ld/emulparams/elf_i386.sh10
-rw-r--r--ld/emulparams/elf_i386_be.sh11
-rw-r--r--ld/emulparams/gld960.sh7
-rw-r--r--ld/emulparams/gld960coff.sh19
-rw-r--r--ld/emulparams/go32.sh7
-rw-r--r--ld/emulparams/h8300.sh5
-rw-r--r--ld/emulparams/h8300h.sh5
-rw-r--r--ld/emulparams/h8300s.sh5
-rw-r--r--ld/emulparams/h8500.sh5
-rw-r--r--ld/emulparams/h8500b.sh5
-rw-r--r--ld/emulparams/h8500c.sh5
-rw-r--r--ld/emulparams/h8500m.sh5
-rw-r--r--ld/emulparams/h8500s.sh5
-rw-r--r--ld/emulparams/hp300bsd.sh5
-rw-r--r--ld/emulparams/hp3hpux.sh8
-rw-r--r--ld/emulparams/hppaelf.sh7
-rw-r--r--ld/emulparams/i386aout.sh6
-rwxr-xr-xld/emulparams/i386beos.sh5
-rw-r--r--ld/emulparams/i386bsd.sh6
-rw-r--r--ld/emulparams/i386coff.sh5
-rw-r--r--ld/emulparams/i386go32.sh8
-rw-r--r--ld/emulparams/i386linux.sh7
-rw-r--r--ld/emulparams/i386lynx.sh9
-rw-r--r--ld/emulparams/i386mach.sh7
-rw-r--r--ld/emulparams/i386moss.sh10
-rw-r--r--ld/emulparams/i386msdos.sh7
-rw-r--r--ld/emulparams/i386nbsd.sh6
-rw-r--r--ld/emulparams/i386nw.sh9
-rw-r--r--ld/emulparams/i386pe.sh5
-rw-r--r--ld/emulparams/lnk960.sh6
-rw-r--r--ld/emulparams/m32relf.sh13
-rw-r--r--ld/emulparams/m68k4knbsd.sh7
-rw-r--r--ld/emulparams/m68kaout.sh7
-rw-r--r--ld/emulparams/m68kaux.sh8
-rw-r--r--ld/emulparams/m68kcoff.sh5
-rw-r--r--ld/emulparams/m68kelf.sh10
-rw-r--r--ld/emulparams/m68klinux.sh7
-rw-r--r--ld/emulparams/m68klynx.sh8
-rw-r--r--ld/emulparams/m68knbsd.sh7
-rw-r--r--ld/emulparams/m68kpsos.sh6
-rw-r--r--ld/emulparams/m88kbcs.sh5
-rw-r--r--ld/emulparams/mcorepe.sh6
-rw-r--r--ld/emulparams/mipsbig.sh6
-rw-r--r--ld/emulparams/mipsbsd.sh7
-rw-r--r--ld/emulparams/mipsidt.sh11
-rw-r--r--ld/emulparams/mipsidtl.sh11
-rw-r--r--ld/emulparams/mipslit.sh6
-rw-r--r--ld/emulparams/mipslnews.sh9
-rw-r--r--ld/emulparams/mn10200.sh20
-rw-r--r--ld/emulparams/mn10300.sh20
-rw-r--r--ld/emulparams/news.sh5
-rw-r--r--ld/emulparams/ns32knbsd.sh5
-rw-r--r--ld/emulparams/pc532macha.sh6
-rw-r--r--ld/emulparams/ppcmacos.sh4
-rw-r--r--ld/emulparams/ppcnw.sh7
-rw-r--r--ld/emulparams/ppcpe.sh4
-rw-r--r--ld/emulparams/riscix.sh5
-rw-r--r--ld/emulparams/sa29200.sh5
-rw-r--r--ld/emulparams/sh.sh5
-rw-r--r--ld/emulparams/shelf.sh17
-rw-r--r--ld/emulparams/shl.sh5
-rw-r--r--ld/emulparams/shlelf.sh17
-rw-r--r--ld/emulparams/sparcaout.sh8
-rw-r--r--ld/emulparams/sparclinux.sh7
-rw-r--r--ld/emulparams/sparclynx.sh9
-rw-r--r--ld/emulparams/sparcnbsd.sh5
-rw-r--r--ld/emulparams/st2000.sh5
-rw-r--r--ld/emulparams/sun3.sh8
-rw-r--r--ld/emulparams/sun4.sh8
-rw-r--r--ld/emulparams/tic30aout.sh7
-rw-r--r--ld/emulparams/tic30coff.sh7
-rw-r--r--ld/emulparams/tic80coff.sh56
-rw-r--r--ld/emulparams/v850.sh14
-rw-r--r--ld/emulparams/vanilla.sh5
-rw-r--r--ld/emulparams/vax.sh5
-rw-r--r--ld/emulparams/vsta.sh8
-rw-r--r--ld/emulparams/w65.sh5
-rw-r--r--ld/emulparams/z8001.sh7
-rw-r--r--ld/emulparams/z8002.sh6
-rw-r--r--ld/emultempl/README3
-rw-r--r--ld/emultempl/aix.em1054
-rw-r--r--ld/emultempl/armcoff.em226
-rw-r--r--ld/emultempl/armelf.em168
-rw-r--r--ld/emultempl/armelf_oabi.em175
-rw-r--r--ld/emultempl/beos.em837
-rw-r--r--ld/emultempl/elf32.em1143
-rw-r--r--ld/emultempl/generic.em118
-rw-r--r--ld/emultempl/gld960.em176
-rw-r--r--ld/emultempl/gld960c.em192
-rw-r--r--ld/emultempl/hppaelf.em283
-rw-r--r--ld/emultempl/linux.em208
-rw-r--r--ld/emultempl/lnk960.em327
-rw-r--r--ld/emultempl/mipsecoff.em229
-rw-r--r--ld/emultempl/pe.em1104
-rw-r--r--ld/emultempl/stringify.sed4
-rw-r--r--ld/emultempl/sunos.em1037
-rw-r--r--ld/emultempl/vanilla.em69
-rw-r--r--ld/gen-doc.texi13
-rwxr-xr-xld/genscripts.sh133
-rw-r--r--ld/h8-doc.texi14
-rw-r--r--ld/ld.11115
-rw-r--r--ld/ld.h226
-rw-r--r--ld/ld.texinfo4305
-rw-r--r--ld/ldcref.c549
-rw-r--r--ld/ldctor.c383
-rw-r--r--ld/ldctor.h60
-rw-r--r--ld/ldemul.c298
-rw-r--r--ld/ldemul.h149
-rw-r--r--ld/ldexp.c985
-rw-r--r--ld/ldexp.h116
-rw-r--r--ld/ldfile.c416
-rw-r--r--ld/ldfile.h53
-rw-r--r--ld/ldgram.y1094
-rw-r--r--ld/ldint.texinfo564
-rw-r--r--ld/ldlang.c4703
-rw-r--r--ld/ldlang.h490
-rw-r--r--ld/ldlex.h62
-rw-r--r--ld/ldlex.l662
-rw-r--r--ld/ldmain.c1300
-rw-r--r--ld/ldmain.h40
-rw-r--r--ld/ldmisc.c538
-rw-r--r--ld/ldmisc.h56
-rw-r--r--ld/ldver.c49
-rw-r--r--ld/ldver.h22
-rw-r--r--ld/ldwrite.c530
-rw-r--r--ld/ldwrite.h20
-rw-r--r--ld/lexsup.c1140
-rw-r--r--ld/mac-ld.r42
-rw-r--r--ld/mpw-config.in52
-rw-r--r--ld/mpw-elfmips.c1439
-rw-r--r--ld/mpw-eppcmac.c1224
-rw-r--r--ld/mpw-esh.c315
-rw-r--r--ld/mpw-idtmips.c430
-rw-r--r--ld/mpw-make.sed95
-rw-r--r--ld/mri.c377
-rw-r--r--ld/mri.h39
-rw-r--r--ld/pe-dll.c1651
-rw-r--r--ld/po/Make-in251
-rw-r--r--ld/po/POTFILES.in64
-rw-r--r--ld/po/ld.pot1372
-rw-r--r--ld/scripttempl/README4
-rw-r--r--ld/scripttempl/a29k.sc37
-rw-r--r--ld/scripttempl/aix.sc55
-rw-r--r--ld/scripttempl/alpha.sc74
-rw-r--r--ld/scripttempl/aout.sc57
-rw-r--r--ld/scripttempl/armaout.sc35
-rw-r--r--ld/scripttempl/armcoff.sc62
-rw-r--r--ld/scripttempl/delta68.sc49
-rw-r--r--ld/scripttempl/ebmon29k.sc27
-rw-r--r--ld/scripttempl/elf.sc286
-rw-r--r--ld/scripttempl/elfd10v.sc226
-rw-r--r--ld/scripttempl/elfd30v.sc219
-rw-r--r--ld/scripttempl/elfppc.sc288
-rw-r--r--ld/scripttempl/go32coff.sc33
-rw-r--r--ld/scripttempl/h8300.sc69
-rw-r--r--ld/scripttempl/h8300h.sc76
-rw-r--r--ld/scripttempl/h8300s.sc76
-rw-r--r--ld/scripttempl/h8500.sc62
-rw-r--r--ld/scripttempl/h8500b.sc62
-rw-r--r--ld/scripttempl/h8500c.sc59
-rw-r--r--ld/scripttempl/h8500m.sc61
-rw-r--r--ld/scripttempl/h8500s.sc60
-rw-r--r--ld/scripttempl/hppaelf.sc38
-rw-r--r--ld/scripttempl/i386beos.sc194
-rw-r--r--ld/scripttempl/i386coff.sc43
-rw-r--r--ld/scripttempl/i386go32.sc46
-rw-r--r--ld/scripttempl/i386lynx.sc46
-rw-r--r--ld/scripttempl/i386msdos.sc38
-rw-r--r--ld/scripttempl/i960.sc25
-rw-r--r--ld/scripttempl/m68kaux.sc46
-rw-r--r--ld/scripttempl/m68kcoff.sc42
-rw-r--r--ld/scripttempl/m68klynx.sc46
-rw-r--r--ld/scripttempl/m88kbcs.sc49
-rw-r--r--ld/scripttempl/mcorepe.sc156
-rw-r--r--ld/scripttempl/mips.sc72
-rw-r--r--ld/scripttempl/mipsbsd.sc30
-rw-r--r--ld/scripttempl/nw.sc131
-rw-r--r--ld/scripttempl/pe.sc151
-rw-r--r--ld/scripttempl/ppcpe.sc198
-rw-r--r--ld/scripttempl/psos.sc61
-rw-r--r--ld/scripttempl/riscix.sc35
-rw-r--r--ld/scripttempl/sa29200.sc44
-rw-r--r--ld/scripttempl/sh.sc59
-rw-r--r--ld/scripttempl/sparccoff.sc48
-rw-r--r--ld/scripttempl/sparclynx.sc47
-rw-r--r--ld/scripttempl/st2000.sc26
-rw-r--r--ld/scripttempl/tic30aout.sc34
-rw-r--r--ld/scripttempl/tic30coff.sc58
-rw-r--r--ld/scripttempl/tic80coff.sc74
-rw-r--r--ld/scripttempl/v850.sc204
-rw-r--r--ld/scripttempl/vanilla.sc1
-rw-r--r--ld/scripttempl/w65.sc58
-rw-r--r--ld/scripttempl/z8000.sc54
-rw-r--r--ld/stamp-h.in1
-rw-r--r--ld/sysdep.h73
-rw-r--r--ld/testsuite/ChangeLog731
-rw-r--r--ld/testsuite/config/default.exp171
-rw-r--r--ld/testsuite/ld-bootstrap/bootstrap.exp103
-rw-r--r--ld/testsuite/ld-cdtest/cdtest-bar.cc17
-rw-r--r--ld/testsuite/ld-cdtest/cdtest-foo.cc89
-rw-r--r--ld/testsuite/ld-cdtest/cdtest-foo.h24
-rw-r--r--ld/testsuite/ld-cdtest/cdtest-main.cc40
-rw-r--r--ld/testsuite/ld-cdtest/cdtest.dat15
-rw-r--r--ld/testsuite/ld-cdtest/cdtest.exp100
-rw-r--r--ld/testsuite/ld-checks/asm.s14
-rw-r--r--ld/testsuite/ld-checks/checks.exp72
-rw-r--r--ld/testsuite/ld-checks/script6
-rw-r--r--ld/testsuite/ld-elfvers/vers.exp808
-rw-r--r--ld/testsuite/ld-elfvers/vers1.c98
-rw-r--r--ld/testsuite/ld-elfvers/vers1.dsym9
-rw-r--r--ld/testsuite/ld-elfvers/vers1.map16
-rw-r--r--ld/testsuite/ld-elfvers/vers1.sym4
-rw-r--r--ld/testsuite/ld-elfvers/vers1.ver8
-rw-r--r--ld/testsuite/ld-elfvers/vers13.asym10
-rw-r--r--ld/testsuite/ld-elfvers/vers15.c35
-rw-r--r--ld/testsuite/ld-elfvers/vers15.dsym5
-rw-r--r--ld/testsuite/ld-elfvers/vers15.sym3
-rw-r--r--ld/testsuite/ld-elfvers/vers15.ver5
-rw-r--r--ld/testsuite/ld-elfvers/vers16.c10
-rw-r--r--ld/testsuite/ld-elfvers/vers16.dsym2
-rw-r--r--ld/testsuite/ld-elfvers/vers16.map3
-rw-r--r--ld/testsuite/ld-elfvers/vers16a.c8
-rw-r--r--ld/testsuite/ld-elfvers/vers16a.dsym3
-rw-r--r--ld/testsuite/ld-elfvers/vers16a.ver3
-rw-r--r--ld/testsuite/ld-elfvers/vers2.c10
-rw-r--r--ld/testsuite/ld-elfvers/vers2.dsym3
-rw-r--r--ld/testsuite/ld-elfvers/vers2.map4
-rw-r--r--ld/testsuite/ld-elfvers/vers2.ver8
-rw-r--r--ld/testsuite/ld-elfvers/vers3.c10
-rw-r--r--ld/testsuite/ld-elfvers/vers3.dsym1
-rw-r--r--ld/testsuite/ld-elfvers/vers3.ver4
-rw-r--r--ld/testsuite/ld-elfvers/vers4.c27
-rw-r--r--ld/testsuite/ld-elfvers/vers4.sym1
-rw-r--r--ld/testsuite/ld-elfvers/vers4a.dsym2
-rw-r--r--ld/testsuite/ld-elfvers/vers4a.sym1
-rw-r--r--ld/testsuite/ld-elfvers/vers4a.ver4
-rw-r--r--ld/testsuite/ld-elfvers/vers5.c51
-rw-r--r--ld/testsuite/ld-elfvers/vers6.c19
-rw-r--r--ld/testsuite/ld-elfvers/vers6.dsym4
-rw-r--r--ld/testsuite/ld-elfvers/vers6.sym4
-rw-r--r--ld/testsuite/ld-elfvers/vers6.ver6
-rw-r--r--ld/testsuite/ld-elfvers/vers7.c11
-rw-r--r--ld/testsuite/ld-elfvers/vers7.map6
-rw-r--r--ld/testsuite/ld-elfvers/vers7a.c18
-rw-r--r--ld/testsuite/ld-elfvers/vers7a.dsym2
-rw-r--r--ld/testsuite/ld-elfvers/vers7a.sym2
-rw-r--r--ld/testsuite/ld-elfvers/vers7a.ver4
-rw-r--r--ld/testsuite/ld-elfvers/vers8.c5
-rw-r--r--ld/testsuite/ld-elfvers/vers8.map18
-rw-r--r--ld/testsuite/ld-elfvers/vers8.ver8
-rw-r--r--ld/testsuite/ld-elfvers/vers9.c45
-rw-r--r--ld/testsuite/ld-elfvers/vers9.dsym4
-rw-r--r--ld/testsuite/ld-elfvers/vers9.sym4
-rw-r--r--ld/testsuite/ld-elfvers/vers9.ver5
-rw-r--r--ld/testsuite/ld-empic/empic.exp263
-rw-r--r--ld/testsuite/ld-empic/relax.t49
-rw-r--r--ld/testsuite/ld-empic/relax1.c22
-rw-r--r--ld/testsuite/ld-empic/relax2.c19
-rw-r--r--ld/testsuite/ld-empic/relax3.c3
-rw-r--r--ld/testsuite/ld-empic/relax4.c3
-rw-r--r--ld/testsuite/ld-empic/run.c160
-rw-r--r--ld/testsuite/ld-empic/runtest1.c117
-rw-r--r--ld/testsuite/ld-empic/runtest2.c26
-rw-r--r--ld/testsuite/ld-empic/runtesti.s94
-rw-r--r--ld/testsuite/ld-scripts/cross1.c6
-rw-r--r--ld/testsuite/ld-scripts/cross1.t6
-rw-r--r--ld/testsuite/ld-scripts/cross2.c5
-rw-r--r--ld/testsuite/ld-scripts/cross2.t6
-rw-r--r--ld/testsuite/ld-scripts/cross3.c7
-rw-r--r--ld/testsuite/ld-scripts/crossref.exp77
-rw-r--r--ld/testsuite/ld-scripts/defined.exp39
-rw-r--r--ld/testsuite/ld-scripts/defined.s2
-rw-r--r--ld/testsuite/ld-scripts/defined.t7
-rw-r--r--ld/testsuite/ld-scripts/phdrs.exp57
-rw-r--r--ld/testsuite/ld-scripts/phdrs.s8
-rw-r--r--ld/testsuite/ld-scripts/phdrs.t14
-rw-r--r--ld/testsuite/ld-scripts/script.exp64
-rw-r--r--ld/testsuite/ld-scripts/script.s8
-rw-r--r--ld/testsuite/ld-scripts/script.t16
-rw-r--r--ld/testsuite/ld-scripts/scriptm.t10
-rw-r--r--ld/testsuite/ld-scripts/sizeof.exp55
-rw-r--r--ld/testsuite/ld-scripts/sizeof.s1
-rw-r--r--ld/testsuite/ld-scripts/sizeof.t17
-rw-r--r--ld/testsuite/ld-scripts/weak.exp57
-rw-r--r--ld/testsuite/ld-scripts/weak.t12
-rw-r--r--ld/testsuite/ld-scripts/weak1.s11
-rw-r--r--ld/testsuite/ld-scripts/weak2.s11
-rw-r--r--ld/testsuite/ld-selective/1.c12
-rw-r--r--ld/testsuite/ld-selective/2.c19
-rw-r--r--ld/testsuite/ld-selective/3.cc33
-rw-r--r--ld/testsuite/ld-selective/4.cc28
-rw-r--r--ld/testsuite/ld-selective/5.cc32
-rw-r--r--ld/testsuite/ld-selective/selective.exp208
-rw-r--r--ld/testsuite/ld-sh/sh.exp143
-rw-r--r--ld/testsuite/ld-sh/sh1.s13
-rw-r--r--ld/testsuite/ld-sh/sh2.c120
-rw-r--r--ld/testsuite/ld-sh/start.s27
-rw-r--r--ld/testsuite/ld-shared/elf-offset.ld168
-rw-r--r--ld/testsuite/ld-shared/main.c81
-rw-r--r--ld/testsuite/ld-shared/sh1.c166
-rw-r--r--ld/testsuite/ld-shared/sh2.c14
-rw-r--r--ld/testsuite/ld-shared/shared.dat16
-rw-r--r--ld/testsuite/ld-shared/shared.exp264
-rw-r--r--ld/testsuite/ld-shared/sun4.dat16
-rw-r--r--ld/testsuite/ld-shared/xcoff.dat10
-rw-r--r--ld/testsuite/ld-srec/sr1.c25
-rw-r--r--ld/testsuite/ld-srec/sr2.c18
-rw-r--r--ld/testsuite/ld-srec/sr3.cc113
-rw-r--r--ld/testsuite/ld-srec/srec.exp374
-rw-r--r--ld/testsuite/ld-undefined/undefined.c10
-rw-r--r--ld/testsuite/ld-undefined/undefined.exp126
-rw-r--r--ld/testsuite/ld-versados/t1-1.robin0 -> 3840 bytes
-rw-r--r--ld/testsuite/ld-versados/t1-2.robin0 -> 256 bytes
-rw-r--r--ld/testsuite/ld-versados/t1.ld281
-rw-r--r--ld/testsuite/ld-versados/t1.ook133
-rw-r--r--ld/testsuite/ld-versados/t2-1.robin0 -> 256 bytes
-rw-r--r--ld/testsuite/ld-versados/t2-2.robin0 -> 2304 bytes
-rw-r--r--ld/testsuite/ld-versados/t2-3.robin0 -> 1024 bytes
-rw-r--r--ld/testsuite/ld-versados/t2.ld281
-rw-r--r--ld/testsuite/ld-versados/t2.ook99
-rw-r--r--ld/testsuite/ld-versados/versados.exp99
-rw-r--r--ld/testsuite/lib/ld-lib.exp327
-rw-r--r--libiberty/COPYING.LIB482
-rw-r--r--libiberty/ChangeLog3232
-rw-r--r--libiberty/Makefile.in247
-rw-r--r--libiberty/README65
-rw-r--r--libiberty/acconfig.h11
-rw-r--r--libiberty/alloca-conf.h24
-rw-r--r--libiberty/alloca.c505
-rw-r--r--libiberty/argv.c390
-rw-r--r--libiberty/asprintf.c57
-rw-r--r--libiberty/atexit.c18
-rw-r--r--libiberty/basename.c37
-rw-r--r--libiberty/bcmp.c49
-rw-r--r--libiberty/bcopy.c35
-rw-r--r--libiberty/bzero.c31
-rw-r--r--libiberty/calloc.c26
-rw-r--r--libiberty/choose-temp.c203
-rw-r--r--libiberty/clock.c91
-rw-r--r--libiberty/concat.c167
-rw-r--r--libiberty/config.h-vms13
-rw-r--r--libiberty/config.in203
-rw-r--r--libiberty/config.table60
-rw-r--r--libiberty/config/mh-aix9
-rw-r--r--libiberty/config/mh-beos7
-rw-r--r--libiberty/config/mh-cxux71
-rw-r--r--libiberty/config/mh-fbsd211
-rw-r--r--libiberty/config/mh-windows1
-rwxr-xr-xlibiberty/configure2850
-rw-r--r--libiberty/configure.bat14
-rw-r--r--libiberty/configure.in341
-rw-r--r--libiberty/copysign.c140
-rw-r--r--libiberty/cplus-dem.c4535
-rw-r--r--libiberty/fdmatch.c73
-rw-r--r--libiberty/floatformat.c403
-rw-r--r--libiberty/fnmatch.c225
-rw-r--r--libiberty/getcwd.c54
-rw-r--r--libiberty/getopt.c1056
-rw-r--r--libiberty/getopt1.c190
-rw-r--r--libiberty/getpagesize.c96
-rw-r--r--libiberty/getruntime.c90
-rw-r--r--libiberty/hex.c33
-rw-r--r--libiberty/index.c11
-rw-r--r--libiberty/insque.c50
-rw-r--r--libiberty/makefile.dos29
-rw-r--r--libiberty/makefile.vms33
-rw-r--r--libiberty/memchr.c60
-rw-r--r--libiberty/memcmp.c38
-rw-r--r--libiberty/memcpy.c28
-rw-r--r--libiberty/memmove.c18
-rw-r--r--libiberty/memset.c19
-rw-r--r--libiberty/mkstemps.c128
-rw-r--r--libiberty/mpw-config.in7
-rw-r--r--libiberty/mpw-make.sed51
-rw-r--r--libiberty/mpw.c1010
-rw-r--r--libiberty/msdos.c15
-rw-r--r--libiberty/objalloc.c291
-rw-r--r--libiberty/obstack.c593
-rw-r--r--libiberty/pexecute.c738
-rw-r--r--libiberty/random.c377
-rw-r--r--libiberty/rename.c22
-rw-r--r--libiberty/rindex.c11
-rw-r--r--libiberty/sigsetmask.c30
-rw-r--r--libiberty/spaces.c78
-rw-r--r--libiberty/splay-tree.c368
-rw-r--r--libiberty/strcasecmp.c82
-rw-r--r--libiberty/strchr.c34
-rw-r--r--libiberty/strdup.c10
-rw-r--r--libiberty/strerror.c831
-rw-r--r--libiberty/strncasecmp.c82
-rw-r--r--libiberty/strrchr.c34
-rw-r--r--libiberty/strsignal.c644
-rw-r--r--libiberty/strstr.c51
-rw-r--r--libiberty/strtod.c122
-rw-r--r--libiberty/strtol.c143
-rw-r--r--libiberty/strtoul.c110
-rw-r--r--libiberty/tmpnam.c39
-rw-r--r--libiberty/vasprintf.c172
-rw-r--r--libiberty/vfork.c8
-rw-r--r--libiberty/vfprintf.c21
-rw-r--r--libiberty/vmsbuild.com165
-rw-r--r--libiberty/vprintf.c15
-rw-r--r--libiberty/vsprintf.c55
-rw-r--r--libiberty/waitpid.c11
-rw-r--r--libiberty/xatexit.c82
-rw-r--r--libiberty/xexit.c36
-rw-r--r--libiberty/xmalloc.c173
-rw-r--r--libiberty/xstrdup.c22
-rw-r--r--libiberty/xstrerror.c56
-rwxr-xr-xltconfig2822
-rw-r--r--ltmain.sh3782
-rw-r--r--makeall.bat16
-rw-r--r--makefile.vms71
-rwxr-xr-xmissing190
-rwxr-xr-xmkinstalldirs36
-rwxr-xr-xmove-if-change32
-rw-r--r--mpw-README376
-rw-r--r--mpw-build.in204
-rw-r--r--mpw-config.in113
-rw-r--r--mpw-configure448
-rw-r--r--mpw-install122
-rw-r--r--opcodes/ChangeLog5033
-rw-r--r--opcodes/Makefile.am348
-rw-r--r--opcodes/Makefile.in858
-rw-r--r--opcodes/a29k-dis.c353
-rw-r--r--opcodes/acinclude.m41
-rw-r--r--opcodes/aclocal.m41111
-rw-r--r--opcodes/alpha-dis.c213
-rw-r--r--opcodes/alpha-opc.c1546
-rw-r--r--opcodes/arc-dis.c267
-rw-r--r--opcodes/arc-opc.c1131
-rw-r--r--opcodes/arm-dis.c887
-rw-r--r--opcodes/arm-opc.h281
-rw-r--r--opcodes/cgen-asm.c359
-rw-r--r--opcodes/cgen-dis.c226
-rw-r--r--opcodes/cgen-opc.c597
-rw-r--r--opcodes/config.in135
-rwxr-xr-xopcodes/configure4754
-rw-r--r--opcodes/configure.bat24
-rw-r--r--opcodes/configure.in211
-rw-r--r--opcodes/d10v-dis.c301
-rw-r--r--opcodes/d10v-opc.c334
-rw-r--r--opcodes/d30v-dis.c399
-rw-r--r--opcodes/d30v-opc.c500
-rw-r--r--opcodes/dep-in.sed20
-rw-r--r--opcodes/dis-buf.c104
-rw-r--r--opcodes/disassemble.c248
-rw-r--r--opcodes/fr30-asm.c560
-rw-r--r--opcodes/fr30-desc.c1643
-rw-r--r--opcodes/fr30-desc.h266
-rw-r--r--opcodes/fr30-dis.c630
-rw-r--r--opcodes/fr30-ibld.c1506
-rw-r--r--opcodes/fr30-opc.c1368
-rw-r--r--opcodes/fr30-opc.h150
-rw-r--r--opcodes/h8300-dis.c457
-rw-r--r--opcodes/h8500-dis.c347
-rw-r--r--opcodes/h8500-opc.h3836
-rw-r--r--opcodes/hppa-dis.c631
-rw-r--r--opcodes/i386-dis.c3268
-rw-r--r--opcodes/i960-dis.c914
-rw-r--r--opcodes/m10200-dis.c341
-rw-r--r--opcodes/m10200-opc.c360
-rw-r--r--opcodes/m10300-dis.c548
-rw-r--r--opcodes/m10300-opc.c683
-rw-r--r--opcodes/m32r-asm.c556
-rw-r--r--opcodes/m32r-desc.c1150
-rw-r--r--opcodes/m32r-desc.h219
-rw-r--r--opcodes/m32r-dis.c557
-rw-r--r--opcodes/m32r-ibld.c1120
-rw-r--r--opcodes/m32r-opc.c1331
-rw-r--r--opcodes/m32r-opc.h126
-rw-r--r--opcodes/m32r-opinst.c562
-rw-r--r--opcodes/m68k-dis.c1243
-rw-r--r--opcodes/m68k-opc.c2090
-rw-r--r--opcodes/m88k-dis.c330
-rw-r--r--opcodes/makefile.vms42
-rw-r--r--opcodes/mcore-dis.c250
-rw-r--r--opcodes/mcore-opc.h202
-rw-r--r--opcodes/mips-dis.c1068
-rw-r--r--opcodes/mips-opc.c772
-rw-r--r--opcodes/mips16-opc.c226
-rw-r--r--opcodes/mpw-config.in27
-rw-r--r--opcodes/mpw-make.sed25
-rw-r--r--opcodes/ns32k-dis.c894
-rw-r--r--opcodes/opintl.h30
-rw-r--r--opcodes/po/Make-in251
-rw-r--r--opcodes/po/POTFILES.in69
-rw-r--r--opcodes/po/opcodes.pot242
-rw-r--r--opcodes/ppc-dis.c238
-rw-r--r--opcodes/ppc-opc.c3124
-rw-r--r--opcodes/sh-dis.c387
-rw-r--r--opcodes/sh-opc.h573
-rw-r--r--opcodes/sparc-dis.c969
-rw-r--r--opcodes/sparc-opc.c1920
-rw-r--r--opcodes/stamp-h.in1
-rw-r--r--opcodes/sysdep.h42
-rw-r--r--opcodes/tic30-dis.c711
-rw-r--r--opcodes/tic80-dis.c397
-rw-r--r--opcodes/tic80-opc.c1216
-rw-r--r--opcodes/v850-dis.c381
-rw-r--r--opcodes/v850-opc.c786
-rw-r--r--opcodes/vax-dis.c299
-rw-r--r--opcodes/w65-dis.c118
-rw-r--r--opcodes/w65-opc.h548
-rw-r--r--opcodes/z8k-dis.c574
-rw-r--r--opcodes/z8k-opc.h4438
-rw-r--r--opcodes/z8kgen.c1313
-rw-r--r--setup.com8
-rwxr-xr-xsymlink-tree48
-rwxr-xr-xylwrap123
2316 files changed, 881473 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 00000000000..dab6c3245ba
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,30 @@
+*-all
+*-co
+*-dirs
+*-done
+*-install-info
+*-src
+*-stamp-*
+*-tagged
+blockit
+cfg-paper.info
+config.status
+configure.aux
+configure.cp
+configure.cps
+configure.dvi
+configure.fn
+configure.fns
+configure.ky
+configure.kys
+configure.log
+configure.pg
+configure.pgs
+configure.toc
+configure.tp
+configure.tps
+configure.vr
+configure.vrs
+dir.info
+Makefile
+lost+found
diff --git a/COPYING b/COPYING
new file mode 100644
index 00000000000..60549be514a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644
index 00000000000..161a3d1d47b
--- /dev/null
+++ b/COPYING.LIB
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 00000000000..2604b21d5c6
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,6537 @@
+1999-04-30 Tom Tromey <tromey@cygnus.com>
+
+ * ltmain.sh: [mode link] Always use CC given by ltconfig.
+
+1999-04-23 Tom Tromey <tromey@cygnus.com>
+
+ * ltconfig, ltmain.sh: Update to libtool 1.2f.
+
+1999-04-20 Drew Moseley <dmoseley@cygnus.com>
+
+ * configure.in (noconfigdirs): Don't build libstub for arm-elf targets.
+ (noconfigdirs): Don't build any bsp stuff for for arm-oabi targets.
+ Bad merge removed these two changes.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * configure.in (i?86-*-beos*): Do config gperf; don't config
+ gdb, newlib, or libgloss.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * config.sub: Add support for mcore targets.
+
+1999-04-07 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (d30v-*): Use config/mt-d30v as makefile fragment,
+ not mt-ospace, in order to shut up assembler warning about using
+ symbols that are named the same as registers.
+
+1999-04-07 Drew Moseley <dmoseley@cygnus.com>
+
+ * Makefile.in (all-target-cygmon): Added all-target-bsp to the
+ dependency list for all-target-cygmon.
+
+1999-04-05 Doug Evans <devans@casey.cygnus.com>
+
+ * config-ml.in: Check $host, not $target, for selective multilibs.
+ (arm-*-*): Allow disabling of biendian, h/w fp, 26 bit apcs,
+ thumb interworking, and underscore prefix multilibs.
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * missing: Update to version from current automake.
+
+Fri Apr 2 15:11:32 1999 H.J. Lu (hjl@gnu.org)
+
+ * configure (gxx_include_dir): Removed.
+
+ * configure.in (gxx_include_dir): Handle it.
+ * Makefile.in: Likewise.
+
+1999-03-29 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config.sub (mips64vr4111,mips64vr4111el) Add.
+
+1999-03-21 Ben Elliston <bje@cygnus.com>
+
+ * config.guess: Correct typo for detecting ELF on FreeBSD.
+
+Thu Mar 18 00:17:50 1999 Mark Elbrecht <snowball3@usa.net>
+
+ * config/mh-go32: Delete.
+ * config/mh-djgpp: New. Renamed from mh-go32.
+ * configure.in (pc-msdosdjgpp): Set host_makefile_frag to
+ config/mh-djgpp.
+
+Thu Mar 11 18:37:23 1999 Drew Moseley <dmoseley@cygnus.com>
+
+ * Makefile.in (all-target-bsp): Added all-gcc all-binutils and
+ all-target-newlib to dependency list for all-target-bsp.
+
+Thu Mar 11 01:19:31 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * config.sub: Add i386-uwin support.
+ * config.guess: Likewise.
+
+Thu Mar 11 01:07:55 1999 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * configure.in: cleanup, add mh-*pic handling for arm, special
+ case powerpc*-*-aix*
+
+Wed Mar 10 18:35:07 1999 Jeff Johnston <jjohnstn@cygnus.com>
+
+ * configure.in (noconfigdirs): Removed target-libgloss so libnosys.a
+ can be built.
+
+Wed Mar 10 17:39:09 1999 Drew Moseley <dmoseley@cygnus.com>
+
+ * configure.in: Added bsp support to arm-*-coff and arm-*-elf
+ targets.
+
+1999-03-02 Nick Clifton <nickc@cygnus.com>
+
+ * config.sub: Rename CYGNUS LOCAL to EGCS LOCAL
+
+Sun Feb 28 02:20:00 1999 Geoffrey Noer <noer@cygnus.com>
+
+ * config.sub: Check for "cygwin*" rather than "cygwin32*"
+
+1999-02-24 Nick Clifton <nickc@cygnus.com>
+
+ * config.sub: Fix typo in arm recognition.
+
+Wed Feb 24 13:51:40 1999 Drew Moseley <dmoseley@cygnus.com>
+
+ * configure.in (noconfigdirs): Changed target_configdirs to
+ include target-bsp only for m68k-*-elf* and m68k-*-coff*
+ rather than m68k-*-* since it is not known to work on
+ m68k-aout. Ditto for arm-*-*oabi.
+
+Wed Feb 24 12:52:17 1999 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (*-*-windows*): Remove, no longer used.
+ * config/mh-windows: Ditto.
+
+1999-02-19 Ben Elliston <bje@cygnus.com>
+
+ * config.guess: Automatically recognise ELF on FreeBSD. From Niall
+ Smart and improved by Andrew Cagney.
+
+Thu Feb 18 19:55:09 1999 Marc Espie <espie@cvs.openbsd.org>
+
+ * config.guess: Recognize openbsd-*-hppa.
+
+Wed Feb 17 01:38:59 1999 H.J. Lu (hjl@gnu.org)
+
+ * Makefile.in (REALLY_SET_LIB_PATH): Append $$$(RPATH_ENVVAR)
+ only if it is not empty.
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ Patch from: Scott Bambrough <scottb@corelcomputer.com>
+
+ * config.guess: Modified to recognize uname's armv* syntax.
+
+ * config.sub: Modified to recognize uname's armv* syntax.
+
+1999-02-17 Mark Salter <msalter@cygnus.com>
+
+ * configure.in: Added target-bsp for sparclite.
+
+Mon Feb 8 14:17:24 1999 Richard Henderson <rth@cygnus.com>
+
+ * config.sub: Recognize alphapca5[67] and up to alphaev8.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in: Add support for strongarm port.
+ * config.sub: Add support for strongarm target.
+
+Sun Feb 7 18:01:54 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * configure.in (*-*-cygwin32*): Use config/mh-cygwin instead of
+ the old name config/mh-cygwin32.
+ Enable texinfo.
+
+Thu Feb 4 20:43:25 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Do build ld for ix86 Solaris.
+
+Tue Feb 2 19:46:40 1999 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): Set AR to $AR instead of
+ $AR_FOR_TARGET. Likewise for RANLIB.
+
+Tue Feb 2 20:05:05 1999 Catherine Moore <clm@cygnus.com>
+
+ * config.sub (oabi): Recognize.
+ * configure.in (arm-*-oabi): Handle.
+
+Sat Jan 30 06:09:00 1999 Robert Lipe (robertlipe@usa.net)
+
+ * config.guess: Improve detection of i686 on UnixWare 7.
+
+Sat Jan 30 08:04:00 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * config.guess: Add support for i386-pc-interix.
+ * config.sub: Likewise.
+ * configure.in: Likewise.
+ * config/mh-interix: New file.
+
+Mon Jan 18 13:59:20 1999 Christopher Faylor <cgf@cygnus.com>
+
+ * Makefile.in: Remove unneeded all-target-libio from
+ from all-target-winsup target since it is now unneeded.
+ Add all-target-libtermcap in its place since it is now
+ needed.
+
+Wed Dec 30 20:34:52 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: makefile stub for cygwin target is probably
+ unnecessary. Remove it for now.
+ * config/mt-cygwin: Remove.
+
+Wed Dec 30 01:13:03 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: libtermcap.a should be built when cygwin is the
+ target as well as the host.
+ * config.guess: Allow mixed case in cygwin uname output.
+ * Makefile.in: Add libtermcap target.
+ * config/mt-cygwin: New file. libtermcap target info.
+
+Tue Dec 15 17:02:58 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in: Add cygmon for x86-coff and x86-elf. Configure
+ cygmon for all sparclite targets, regardless of object format.
+
+1998-12-15 Mark Salter <msalter@cygnus.com>
+
+ * configure.in: Added target-bsp for several target architectures.
+
+ * Makefile.in: Added rules for bsp.
+
+Wed Dec 23 00:20:50 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub: Clean up handling of hppa2.0.
+
+Tue Dec 22 23:56:31 1998 Rodney Brown (rodneybrown@pmsc.com)
+
+ * config.guess: Use C code to identify more HP machines.
+
+Thu Dec 17 01:22:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub: Handle hppa2.0.
+
+Fri Dec 4 01:34:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess: Improve detection of hppa2.0 processors.
+
+Fri Dec 4 01:33:05 1998 Niall Smart <nialls@euristix.ie>
+
+ * config.guess: Recognize FreeBSD using ELF automatically.
+
+1998-11-26 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure (skip-this-dir): Add handling for new shell script, which
+ might be created by a sub-directory's configure to indicate, this particular
+ directory is "unwanted".
+ * Makefile.in ($(CONFIGURE_TARGET_MODULES)): Likewise.
+
+
+Wed Nov 18 18:28:45 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * ltconfig: import from libtool, after changing libtool to
+ account for the cygwin name change.
+
+Wed Nov 18 18:09:14 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: CC_FOR_TARGET and CXX_FOR_TARGET should also
+ include newlib/libc/sys/cygwin and newlib/libc/sys/cygwin32.
+
+Wed Nov 18 20:13:29 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Add libtermcap to list of cygwin dependencies.
+
+Tue Nov 17 16:57:51 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: modify CC_FOR_TARGET and CXX_FOR_TARGET so that
+ they include winsup/include when it's a cygwin target.
+
+1998-11-12 Tom Tromey <tromey@cygnus.com>
+
+ * configure.in (host_tools): Added zip.
+ * Makefile.in (all-target-libjava): Depend on all-zip.
+ (all-zip): New target.
+ (ALL_MODULES): Added all-zip.
+ (NATIVE_CHECK_MODULES): Added check-zip.
+ (INSTALL_MODULES): Added install-zip.
+ (CLEAN_MODULES): Added clean-zip.
+
+Thu Nov 12 17:27:21 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: lose "32" from comment about cygwin.
+
+Thu Nov 5 15:00:31 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in: Use -Os to build target libraries for the fr30.
+
+Wed Nov 4 18:49:43 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config.sub: Add fr30.
+
+Mon Nov 2 15:19:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: drop "32" from config/mh-cygwin32. Check
+ cygwin* instead of cygwin32*.
+ * config.sub: Check cygwin* instead of cygwin32*.
+
+1998-10-20 Syd Polk <spolk@cygnus.com>
+
+ * Makefile.in configure.in: Add the ability to use tcl8.1 and tk8.1
+ if desired.
+
+Sun Oct 18 18:34:50 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.if (cxx_interface, libstdcxx_interface): Do not try to set
+ these if the appropriate directories and files to not exist.
+
+Wed Oct 14 10:29:06 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (DEVO_SUPPORT): Add config.if.
+
+Tue Oct 13 09:17:06 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub: Bring back lost sparcv9.
+
+Wed Sep 30 22:20:50 1998 Robert Lipe <robertl@dgii.com>
+
+ * config.sub: Add support for i[34567]86-pc-udk.
+ * configure.in: Likewise.
+
+Wed Sep 30 19:23:48 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: add bzip2 package building bits for user
+ tools module
+ * configure.in: ditto
+
+1998-09-30 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure.in (target_subdir): Remove duplicate line.
+
+Tue Sep 29 22:45:41 1998 Felix Lee <flee@cygnus.com>
+
+ * Makefile.in (all-automake): fix dependencies.
+
+Mon Sep 28 04:04:27 1998 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Minor cleanups for building in the $(target_alias)
+ subdir.
+
+1998-09-22 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (bootstrap): Set r and s before make all. Use
+ BASE_FLAGS_TO_PASS in make all.
+ (cross): Likewise.
+
+1998-09-20 Mark Mitchell <mark@markmitchell.com>
+
+ * Makefile.in (bootstrap): Pass TARGET_FLAGS_TO_PASS to `make all'.
+
+
+Sun Sep 20 00:13:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * config.sub: Fix typo in last change.
+
+1998-09-19 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config.sub: Add support for C4x target.
+ * configure.in: Likewise.
+
+1998-09-13 David S. Miller <davem@pierdol.cobaltmicro.com>
+
+ * config.sub: Recognize sparcv9 just like sparc64.
+
+Wed Sep 9 15:44:52 1998 Robert Lipe <robertl@dgii.com>
+
+ * config.guess: Match "Pent II" or "PentII" for OpenServer.
+
+Tue Sep 8 01:18:39 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess: Correctly identify Pentium II sco boxes.
+
+ * config.guess: Fix "tr" code. From Weiwen Liu.
+
+Sat Sep 5 13:56:52 1998 John Hughes <john@Calva.COM>
+
+ * configure.in: Do not assume x86-svr4 or x86-unixware can handle
+ stabs.
+
+Sat Sep 5 02:12:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (TARGET_CONFIGDIRS): Add libchill.
+ (ALL_TARGET_MODULES): Add all-target-libchill.
+ (CONFIGURE_TARGET_MODULES, CHECK_TARGET_MODULES): Similarly.
+ (INSTALL_TARGET_MODULES, CLEAN_TARGET_MODULES): Similarly.
+ (all-target-libchill): Add dependencies.
+ * configure.in (target_libs): Add libchill.
+
+Sun Aug 30 22:27:02 1998 Lutz Wohlrab <lutz.wohlrab@informatik.tu-chemnitz.de>
+
+ * config.guess: Avoid assumptions about "tr" behaves when
+ LANG is set to something other than English.
+
+Sun Aug 30 22:14:44 1998 H.J. Lu (hjl@gnu.org)
+
+ * configure (gxx_include_dir): Changed to
+ '${prefix}/include/g++'-${libstdcxx_interface}.
+
+ * config.if: New to determine the interfaces.
+
+Sun Aug 30 21:15:19 1998 Mark Klein (mklein@dis.com)
+
+ * config.guess: Detect and handle MPE/IX.
+ * config.sub: Deal with MPE/IX.
+
+Sat Aug 29 14:32:55 1998 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * configure.in: Use mh-aix43.
+
+1998-07-29 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure: Fix --without/--disable cases for gxx-include-dir.
+
+Fri Aug 28 12:28:26 1998 Per Bothner <bothner@cygnus.com>
+
+ * mdata-sh: Imported. Needed for automake support.
+
+Thu Aug 13 12:49:29 1998 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.in (taz): Try "chmod -R og=u ." before
+ "chmod og=u `find . -print`".
+
+Fri Jul 31 09:38:33 1998 Catherine Moore <clm@cygnus.com>
+
+ * configure.in: Add arm-elf and thumb-elf support.
+
+Mon Jul 27 16:23:58 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.in: Undo previous patch.
+
+Fri Jul 24 19:55:24 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.in (INSTALL_TARGET): Move EXTRA_TARGET_HOST_INSTALL_MODULES
+ to here ...
+ (install-no-fixedincludes): and here
+ (INSTALL_MODULES): ... from here.
+
+Fri Jul 24 17:01:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Merge with FSF.
+
+ * config.guess: Merge with FSF.
+
+Fri Jul 24 08:43:36 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * configure (extraconfigdirs): New variable.
+ (SUBDIRS): Add extraconfigdirs and recurse on them too.
+ * Makefile.in (all): Move higher in file.
+ (EXTRA_TARGET_HOST_ALL_MODULES): New variable.
+ (EXTRA_TARGET_HOST_{INSTALL,CHECK}_MODULES): New variables.
+ (ALL_MODULES): Add EXTRA_TARGET_HOST_ALL_MODULES.
+ (CROSS_CHECK_MODULES): Add EXTRA_TARGET_HOST_CHECK_MODULES.
+ (INSTALL_MODULES): Add EXTRA_TARGET_HOST_INSTALL_MODULES.
+
+1998-07-23 Brendan Kehoe <brendan@cygnus.com>
+
+ * Makefile.in (all-target-libjava): Depend on all-gcc and
+ all-target-newlib.
+ (configure-target-libjava): Depend on $(ALL_GCC).
+
+Sat Jul 18 14:32:43 CDT 1998 Robert Lipe <robertl@dgii.com>
+
+ * config.guess: (*-pc-sco3.2v5) Add detection for Pentium II.
+ (*-pc-unixware7) Add detection for Pentium II, Pentium Pro.
+
+Fri Jul 17 13:30:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ylwrap: Change absolute path checks to check for DOS style path
+ names.
+
+ * ylwrap: Don't use a full path name if the source file is in the
+ same directory. From hjl@lucon.org (H.J. Lu).
+
+ * config-ml.in: Default to being verbose, to match Feb 18 change to
+ configure.
+
+Thu Jul 16 12:29:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Brought over from egcs:
+
+ Sat Jun 27 22:46:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (target_subdir): Set to ${target_alias} instead
+ of "libraries".
+
+ Mon Sep 1 16:45:44 1997 Jim Wilson <wilson@cygnus.com>
+
+ * configure.in (target_subdir): Set to libraries if enable_multilib.
+
+Wed Jul 15 01:00:54 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(CONFIGURE_TARGET_MODULES)): If there are any
+ multilibs, force reconfiguration the first time we create
+ multilib.out in a subdirectory, in case TARGET_SUBDIR is `.'.
+
+Tue Jul 14 23:41:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Strip any --no option from CONFIG_ARGUMENTS, to
+ avoid confusion with --no-recursion.
+
+Tue Jul 14 15:37:41 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: Win32 hosts shouldn't use install -x
+ * install-sh: remove -x option, and special .exe-handling
+ hack.
+
+Tue Jul 14 15:28:41 1998 Richard Henderson <rth@cygnus.com>
+
+ * config.guess: Recognize i586-pc-beos.
+ * configure.in: Don't build some bits for beos.
+
+Tue Jul 14 13:22:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: If CC is set but CFLAGS is not, and CC is gcc, make
+ CFLAGS default to -O2.
+
+ * ltmain.sh: Add some hacks to make SunOS --enable-shared work
+ when using GNU ld.
+
+Fri Jul 10 13:18:23 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltmain.sh: Correct install when using a different shell.
+
+Tue Jul 7 15:24:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Update to libtool 1.2b.
+
+Thu Jul 2 13:57:36 1998 Klaus Kaempf <kkaempf@rmi.de>
+
+ * makefile.vms: Update to build binutils/makefile.vms. Add install
+ target.
+
+Wed Jul 1 16:45:21 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig: Update to correct AIX handling.
+
+Sat Jun 27 22:46:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Add TARGET_SUBDIR.
+
+ * configure.in (target_subdir): Set to ${target_alias} instead
+ of "libraries".
+
+1998-06-26 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Add gcc_version_trigger.
+ (Makefile): Depend on $(gcc_version_trigger).
+
+ * configure (gcc_version): Change default initializer to empty
+ string.
+ (gcc_version_trigger): New variable; pass this variable down
+ to subdir configures to enable them checking gcc's version
+ themselves. Emit make macros for both gcc_version vars.
+ (topsrcdir): Initialize reliably.
+ (recursion line): Remove --with-gcc-version=${gcc_version}.
+
+1998-06-24 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure (enable_version_specific_runtime_libs): Implement new flag
+ --enable-version-specific-runtime-libs which installs C++ runtime stuff
+ in $(libsubdir); emit definition in each generated Makefile.
+ (gxx_include_dir): Initialize depending on
+ $enable_version_specific_runtime_libs.
+
+1998-06-24 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure (gcc_version): Initialize properly depending on
+ how and where configure is started.
+ (recursion line): Pass a --with-gcc-version=${gcc_version}
+ to configures in subdirs.
+
+Wed Jun 24 16:01:59 1998 John Metzler <jmetzler@cygnus.com>
+
+ * configure.in (noconfigdirs): Add configure pattern for mips tx39
+ cygmon
+
+Tue Jun 23 22:42:32 1998 Mark Alexander <marka@cygnus.com>
+
+ * configure.in: Add cygmon and libstub support for mn10200.
+
+1998-06-19 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure (gcc_version): Add new variable describing the
+ particular gcc version we're building.
+ * Makefile.in (libsubdir): Add new macro for the directory
+ in which the compiler finds executables, libraries, etc.
+ (BASE_FLAGS_TO_PASS): Pass down gcc_version, target_alias
+ and libsubdir.
+
+Fri Jun 19 02:36:59 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * Makefile.in (local-clean): remove *.log
+ (warning.log): built with warn_summary from build.log
+ (mail-report.log): run test_summary
+ (mail-report-with-warnings.log): run test_summary including
+ warning.log in the report
+
+Thu Jun 18 11:26:03 1998 Robert Lipe <robertl@dgii.com>
+
+ * config.guess: Detection of Pentium II for *-sco-3.2v5*.
+
+Mon Jun 15 14:53:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (grep): Grep no longer depends on libiberty.
+
+Fri Jun 12 14:03:34 1998 Syd Polk <spolk@cygnus.com>
+
+ * Makefile.in: all-snavigator needs all-libgui.
+
+Thu Jun 11 19:43:47 1998 Mark Alexander <marka@cygnus.com>
+
+ * configure.in: Add cygmon and libstub support for mn10300.
+
+Wed Jun 10 11:19:47 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * missing: Update to version from automake 1.3.
+
+ * ltmain.sh: On installation, don't get confused if the same name
+ appears more than once in the list of library names.
+
+Wed Jun 3 14:51:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Accept m68060 and m5200 as CPU names.
+
+Mon Jun 1 17:25:16 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Use && rather than using -a in test, because odd
+ strings can confuse test.
+ * configure.in: Likewise.
+
+Thu May 28 19:31:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Bring in Visual C++ support.
+
+Sat May 23 23:44:13 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * Makefile.in (boostrap2-lean, bootstrap3-lean,
+ bootstrap4-lean): new targets
+
+Mon May 11 23:11:34 1998 Jeffrey A Law (law@cygnus.com)
+
+ * COPYING.LIB: Update FSF address.
+
+Fri May 8 01:30:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Update to libtool 1.2a.
+
+ * Makefile.in (GASB_SUPPORT_DIRS): Remove intl; already included via
+ GAS_SUPPORT_DIRS.
+
+Thu May 7 17:27:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Avoid producing a version number if
+ -version-info was not used.
+
+Tue May 5 18:02:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add --with-newlib to CONFIG_ARGUMENTS if we are
+ building with newlib.
+
+1998-04-30 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): Remove backslash at end;
+ Solaris `make' causes it to continue to next definition.
+
+Tue Apr 28 18:11:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change alpha to alpha* in several places.
+
+Tue Apr 28 07:42:00 1998 Mark Alexander <marka@cygnus.com>
+
+ * config.sub: Recognize sparc86x.
+
+Tue Apr 28 07:35:02 1998 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (--enable-target-optspace): Remove debug echo.
+
+Thu Apr 23 21:31:16 1998 Jim Wilson <wilson@cygnus.com>
+
+ * configure: Set CXXFLAGS from CXXFLAGS, not CFLAGS.
+
+Thu Apr 23 12:26:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig: Update cygwin32 support.
+
+ * Makefile.in (GAS_SUPPORT_DIRS): Add intl.
+ (BINUTILS_SUPPORT_DIRS, GASB_SUPPORT_DIRS): Likewise.
+ (GDB_SUPPORT_DIRS): Likewise.
+
+Wed Apr 22 12:30:10 1998 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (target_makefile_frag): If --enable-target-optspace,
+ use -Os to compile target libraries rather than -O2. Default to
+ using -Os for d10v and m32r if --{enable,disable}-target-optspace is
+ not used.
+ * configure.in (target_cflags): Ditto for d30v.
+
+Tue Apr 21 23:06:54 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (all-bfd): Depend on all-intl.
+ (all-binutils): Likewise.
+ (all-gas): Likewise.
+ (all-gprof): Likewise.
+ (all-ld): Likewise.
+
+
+1998-04-19 Brendan Kehoe <brendan@cygnus.com>
+
+ * configure.in (host_tools): Fix typo, lbtool -> libtool.
+
+Fri Apr 17 16:20:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (all-bfd): Depend upon all-libiberty.
+
+ * ltconfig, ltmain.sh: Bring in newer cygwin32 support.
+
+Fri Apr 17 12:22:22 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * Makefile.in: Add libstub.
+
+ * configure.in: Ditto. Build libstub for targets that have cygmon
+ support.
+
+Tue Apr 14 18:01:55 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't set PICFLAG on ix86-cygwin32.
+
+Tue Apr 14 12:24:45 1998 J. Kean Johnston <jkj@sco.com>
+
+ * configure.in: Recognise i[3456]96-*-sysv5* as a valid host, and
+ use mh-sysv5 if specified. Support gprof on SCO Open Server.
+
+Tue Apr 14 11:33:51 1998 Krister Walfridsson <cato@df.lth.se>
+
+ * configure: Define DEFAULT_M4 by searching PATH.
+ * Makfile.in: Use DEFAULT_M4.
+
+Mon Apr 13 15:37:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig: Add cygwin32 support.
+
+ * Makefile.in, configure.in: Add libtool as a native only directory
+ to configure and build.
+
+Wed Apr 8 13:18:56 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): XFOO lines shortened.
+
+Thu Apr 2 14:48:44 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: add ash make rules
+ * configure.in: add ash to native_only and host_tools lists
+
+Thu Mar 26 12:53:20 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (all-gettext, all-intl): New targets.
+ (ALL_MODULES): Added all-gettext, all-intl.
+ (CROSS_CHECK_MODULES): Added check-gettext, check-intl.
+ (INSTALL_MODULES): Added install-gettext, install-intl.
+ (CLEAN_MODULES): Added clean-gettext, clean-intl.
+
+ * configure.in (host_tools): Added gettext.
+ (native_only): Likewise.
+ (noconfigdirs) [various cases]: Likewise.
+ (host_libs): Added intl.
+
+Wed Mar 25 11:49:12 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in: Revert yesterday's change.
+ (all-target-winsup): all-target-librx stays out of here.
+
+Tue Mar 24 16:58:29 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Makefile.in (TARGET_CONFIGDIRS, ALL_TARGET_MODULES,
+ CONFIGURE_TARGET_MODULES, CHECK_TARGET_MODULES,
+ INSTALL_TARGET_MODULES, CLEAN_TARGET_MODULES, all-target-winsup):
+ Remove references to librx and libg++.
+
+Tue Mar 24 18:28:12 1998 Eric Mumpower <nocturne@cygnus.com>
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Pass $(lispdir) down to
+ recursive makes
+
+Tue Mar 24 11:37:45 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): Use $(TARGET_SUBDIR) when passing -B
+ for newlib directory.
+ (CXX_FOR_TARGET): Likewise.
+
+Mon Mar 23 11:30:21 1998 Jeffrey A Law (law@cygnus.com)
+
+ * ltconfig: Update after libtool/ltconfig.in change for
+ hpux11.
+
+Fri Mar 20 18:51:43 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Update to libtool 1.2.
+
+Fri Mar 20 09:32:14 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (install-gcc): Don't specify LANGUAGES here.
+ (install-gcc-cross): Instead, override LANGUAGES here.
+
+1998-03-18 Dave Love <d.love@dl.ac.uk>
+
+ * Makefile.in ($(CONFIGURE_TARGET_MODULES)): Set CONFIG_SITE to a
+ non-existent file since /dev/null loses with bash 2.0/autoconf 2.12.
+
+Wed Mar 18 09:24:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in: Add Thumb-pe target.
+
+Tue Mar 17 16:59:00 1998 Syd Polk <spolk@cygnus.com>
+ * Makefile.in - changed sn targets to snavigator
+ * configure.in - changed sn targets to snavigator
+
+Tue Mar 17 10:33:28 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * config-ml.in: After building symlink tree call make distclean
+ if a Makefile got linked into ${ml_dir}/${ml_libdir}; this happens
+ to be the case for libiberty.
+
+Tue Mar 17 10:22:37 1998 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * configure: When making link, also check the current
+ directory. The configure scripts may create one.
+
+Fri Mar 6 01:02:03 1998 Richard Henderson <rth@cygnus.com>
+
+ * config.sub: Accept alphapca56 and alphaev6 properly.
+
+Fri Mar 6 00:14:55 1998 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * configure.in: Revert 3 Jan change for powerpc-linux-gnulibc1.
+
+
+Mon Feb 23 15:09:18 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de
+
+ * config.sub (sco5): Fix typo.
+
+Mon Feb 23 14:46:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL_MODULES): Move install-tcl before
+ install-itcl.
+ (install-itcl): Remove dependency on install-tcl.
+
+Mon Feb 23 09:53:28 1998 Mark Alexander <marka@cygnus.com>
+
+ * configure.in: Remove libgloss from noconfigdirs for MN10300.
+
+Fri Feb 20 16:47:24 1998 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Don't let builds be done in source tree.
+
+Thu Feb 19 13:40:41 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't build libgui for a cygwin32 target when not on
+ a cygwin32 host.
+
+Wed Feb 18 12:29:00 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure (redirect): Set to null, so default behavior of
+ configure is now --verbose.
+
+1998-02-16 Dave Love <d.love@dl.ac.uk>
+
+ * Makefile.in ($(CONFIGURE_TARGET_MODULES)): Run configure with
+ CONFIG_SITE=/dev/null to forestall lossage with site configuration.
+
+Mon Feb 16 12:23:53 1998 Manfred Hollstein <Manfred.Hollstein@ks.sel.alcatel.de>
+
+ * Makefile.in (BASE_FLAGS_TO_PASS, EXTRA_TARGET_FLAGS): Really add
+ this change to sync Makefile.in with its ChangeLog entries.
+
+Thu Feb 12 15:03:08 1998 H.J. Lu <hjl@gnu.org>
+
+ * ltmain.sh (mkdir): Check that the directory doesn't exist
+ before we exit with error, so that we don't get races during
+ parallel builds.
+
+Sat Feb 7 15:19:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Update from libtool 1.0i.
+
+Fri Feb 6 01:33:52 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Don't pass PICFLAG and
+ PICFLAG_FOR_TARGET.
+ (EXTRA_TARGET_FLAGS): Don't pass PICFLAG_FOR_TARGET.
+
+ * configure: Emit a definition for the new macro enable_shared
+ into each Makefile.
+
+ * config/mh-sparcpic (PICFLAG): Define to properly according
+ to current multilib configuration.
+ * config/mt-sparcpic (PICFLAG_FOR_TARGET): Define to properly
+ according to current multilib configuration.
+
+Thu Feb 5 17:01:12 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in (host_tools, native_only): Add libtool.
+
+Wed Feb 4 16:53:58 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: add target-gperf to noconfigdirs for Cygwin32.
+ Fix typo in ming config comment.
+
+Wed Feb 4 18:56:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltconfig, ltmain.sh: Update from libtool 1.0h.
+
+Mon Feb 2 19:38:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Add tic30 cases, and map c30 to tic30.
+
+Fri Jan 30 17:18:32 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: Remove expect from noconfigdirs when target
+ is cygwin32. OK to build expect and dejagnu with Canadian
+ Cross.
+
+Wed Jan 28 12:58:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Do build expect, dejagnu, and cvssrc for a cygwin32
+ host.
+
+ * config.guess: Use ${UNAME_MACHINE} rather than i386 for cygwin32
+ and mingw32.
+
+Wed Jan 28 10:26:37 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Remove passing $(local_prefix)
+ here as it is not defined in the toplevel Makefile.
+
+Tue Jan 27 23:25:06 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure (package_makefile_rules_frag): New variable, which names
+ a file with generic rules, ...
+ Change comment to mention we now have FIVE parts.
+ * configure: Undo last change.
+
+Tue Jan 27 23:15:55 1998 Lassi A. Tuura <lat@iki.fi>
+
+ * config.guess: More accurate determination of HP processor types.
+ * config.sub: More accurate determination of HP processor types.
+
+Sat Jan 24 01:59:45 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure (package_makefile_frag): Move inserting the
+ ${package_makefile_frag} to where it should be according
+ to the comment.
+
+Fri Jan 23 00:30:21 1998 Philip Blundell <pb@nexus.co.uk>
+
+ * config.guess: Add support for Linux/ARM.
+
+Thu Jan 22 15:14:01 1998 Fred Fish <fnf@cygnus.com>
+
+ * .cvsignore: Remove *-info and *-install since they match
+ release-info and mpw-install, which we don't want to just ignore.
+
+Thu Jan 22 01:38:33 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Revert 3 Jan change for alpha-linux-gnulibc1.
+
+Sat Jan 17 21:28:08 1998 Pieter Nagel <pnagel@epiuse.co.za>
+
+ * Makefile.in (FLAGS_TO_PASS): Pass down gcc_include_dir and
+ local_prefix to sub-make invocations.
+
+Sat Jan 17 21:04:59 1998 H.J. Lu (hjl@gnu.org)
+
+ * configure.in: Check makefile fragments in the source
+ directory.
+
+Fri Jan 16 00:41:37 1998 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * configure.in: check whether host and target makefile
+ fragments exist before adding them to *_makefile_frag
+
+Wed Jan 14 23:39:10 1998 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in (target_configdirs): Add cygmon for sparc64-elf.
+
+Wed Jan 14 12:48:07 1998 Keith Seitz <keiths@pizza.cygnus.com>
+
+ * configure.in: Make sure we only replace RPATH_ENVVAR on
+ lines which begin with RPATH_ENVVAR, i.e. add "^" to the
+ regexp to sed.
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Pass RRPATH_ENVVAR down
+ to sub-makes.
+
+1998-01-13 Lee Iverson (leei@ai.sri.com)
+
+ * config-ml.in (multi-do): LDFLAGS must include multilib
+ designator.
+
+Tue Jan 13 01:13:24 1998 Robert Lipe (robertl@dgii.com)
+
+ * config.guess: Recognize i[3456]-i586-UnixWare7-sysv5.
+
+Sun Jan 4 01:06:55 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * config.sub: Add mingw32 support.
+ * configure.in: Likewise.
+ * mh-mingw32: New file.
+
+Sat Jan 3 12:11:05 1998 Franz Sirl <franz.sirl-kernel@lauterbach.com>
+
+ * configure.in: Finalize support for {alpha|powerpc}*-*-linux-gnulibc1
+
+Sun Dec 28 11:28:58 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (INSTALL_TARGET): Do install-gcc first.
+ * configure (gxx_include_dir): Provide a definition for subdirs
+ which do not use autoconf.
+
+Wed Dec 24 22:46:55 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess: Sync with egcs. Picks up new alpha support,
+ BeOS & some additional linux support.
+
+Tue Dec 23 12:45:50 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess: HP 9000/803 is a PA1.1 machine.
+
+
+Sun Dec 21 16:53:12 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * configure.in (host_makefile_frag, target_makefile_frag):
+ Handle multiple config files.
+ (alpha-*-linux*): Treat alpha-*-linux* as alpha-*-linux* and
+ alpha-*-*.
+
+Thu Dec 18 13:13:03 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * mkdep: New file.
+
+Wed Dec 17 09:53:02 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (d30v-*-*): Allow configuring of libide, vmake, etc.
+
+Tue Dec 16 17:36:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Add libgui directory.
+ (GDB_TK): Add all-libgui.
+ * configure.in: Add libgui directory.
+ * configure: Add all-libgui to GDB_TK.
+
+Mon Dec 15 16:12:28 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config-ml.in (multidirs): Add m32r to multilib list.
+
+Fri Dec 12 10:43:31 1997 Brendan Kehoe <brendan@canuck.cygnus.com>
+
+ * Makefile.in (all-target-gperf): Change dependency to
+ all-target-libstdc++.
+
+Thu Dec 11 23:30:51 1997 Fred Fish <fnf@ninemoons.com>
+
+ * config.guess: Add BeOS support.
+
+Wed Dec 10 15:10:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Source directory cvs renamed to cvssrc:
+ * configure.in (host_tools): Change cvs to cvssrc.
+ (native_only): Likewise.
+ (noconfigdirs) [various cases]: Likewise.
+ * Makefile.in (ALL_MODULES): Change all-cvs to all-cvssrc.
+ (CROSS_CHECK_MODULES): Change check-cvs to check-cvssrc.
+ (INSTALL_MODULES): Change install-cvs to install-cvssrc.
+ (CLEAN_MODULES): Change clean-cvs to clean-cvssrc.
+ (all-cvssrc): Rename target from all-cvs.
+
+Wed Dec 3 07:55:59 1997 Jeffrey A Law (law@cygnus.com)
+
+ * configure (gxx_include_dir): Fix thinko.
+
+Tue Dec 2 10:55:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (INSTALL_TARGET_CROSS): Define.
+ (install-cross, install-gcc-cross): New targets.
+
+Tue Dec 2 10:08:31 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (noconfigdirs): Add support for Thumb target.
+
+ * config.sub (maybe_os): Add support for Thumb target.
+
+Sun Nov 30 16:12:27 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * Makefile.in: Add rules for cygmon.
+
+ * configure.in: Build cygmon for sparc-elf and sparclite-aout.
+
+Thu Nov 27 01:31:30 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (INSTALL_TARGET): Do install-gcc first.
+ * configure (gxx_include_dir): Provide a definition for subdirs
+ which do not use autoconf.
+
+Wed Nov 26 11:53:33 1997 Keith Seitz <keiths@onions.cygnus.com>
+
+ * Makefile.in, configure, configure.in, ChangeLog: merge with foundry's
+ 11/18/97 build
+
+Wed Nov 26 16:08:50 1997 Jeffrey A Law (law@cygnus.com)
+
+ * From Franz Sirl.
+ * config.guess (powerpc*-*-linux): Handle glibc2 beta release
+ found on RedHat Linux systems.
+
+Fri Nov 21 09:51:01 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess (alpha stuff): Merge with FSF to avoid incorrect
+ guesses.
+
+Thu Nov 13 11:38:37 1997 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (i[3456]86-ncr-sysv4.3*): Tweak.
+
+Mon Nov 10 15:23:21 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * ltmain.sh: If mkdir fails, check whether the directory was created
+ anyhow by some other process.
+
+Mon Nov 10 14:38:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (d30v-*-*): Configure all directories.
+
+Sun Nov 9 17:36:20 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (d30v-*-*): Configure newlib, libiberty directories
+ for the D30V.
+
+Sat Nov 8 14:42:59 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (d30v-*-*): Configure target-libgloss on the D30V.
+
+Fri Nov 7 10:34:09 1997 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * include/libiberty.h: Add extern "C" { so it can be used with C++
+ progrms.
+ * include/remote-sim.h: Add extern "C" { so it can be used with C++
+ programs.
+
+Thu Oct 30 11:09:29 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (d30v-*-*): Configure GCC now.
+
+Mon Oct 27 13:17:24 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in: Remove a "second pass" of tweaking noconfigdirs,
+ is no longer needed.
+
+Mon Oct 27 12:03:53 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in: check-target-libio depends on all-target-libstdc++.
+
+Sun Oct 26 11:48:27 1997 Manfred Hollstein (manfred@s-direktnet.de)
+
+ * Makefile.in (bootstrap-lean): Combined with `normal' bootstrap
+ targets using "$@" to provide support for similar but not identical
+ targets without having to duplicate code.
+
+Mon Oct 20 15:28:49 1997 Klaus K"ampf <kkaempf@progis.de>
+
+ * makefile.vms: Fix to work with DEC C.
+
+Tue Oct 7 23:58:57 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config.sub: Add mips-tx39-elf to marketing names.
+
+Tue Oct 7 14:24:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltmain.sh: Handle symlinks in generated script.
+
+Wed Oct 1 13:11:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Handle autoconf style directory options: --bindir,
+ --datadir, --includedir, --infodir, --libdir, --libexecdir,
+ --mandir, --oldincludedir, --sbindir, --sharedstatedir,
+ --sysconfdir.
+ * Makefile.in (sbindir, libexecdir, sysconfdir): New variables.
+ (sharedstatedir, localstatedir, oldincludedir): New variables.
+ (BASE_FLAGS_TO_PASS): Pass down bindir, datadir, includedir,
+ infodir, libdir, libexecdir, localstatedir, mandir, oldincludedir,
+ sbindir, sharedstatedir, and sysconfdir.
+
+Mon Sep 29 00:38:08 1997 Aaron Jackson <jackson@negril.msrce.howard.edu>
+
+ * Makefile.in (bootstrap-lean): New target.
+
+Wed Sep 24 18:06:27 1997 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * configure.in (d30v): Remove tcl, tk, expect, gdb, itcl, tix, db,
+ sn, and gnuserv from noconfigdirs.
+
+Wed Sep 24 15:18:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ltmain.sh: Tweak shell pattern to avoid bug in NetBSD /bin/sh.
+
+Thu Sep 18 23:58:27 1997 Jeffrey A Law (law@cygnus.com)
+
+* Makefile.in (cross): New target.
+
+Thu Sep 18 21:43:23 1997 Alexandre Oliva <oliva@dcc.unicamp.br>
+ Jeff Law <law@cygnus.com>
+
+ * Makefile.in (bootstrap2, bootstrap3): New targets.
+ (all-bootstrap): Remove outdated and confusing target.
+ (bootstrap, bootstrap2, bootstrap3): Don't pass BOOT_CFLAGS down.
+
+
+1997-09-15 02:37 Ulrich Drepper <drepper@cygnus.com>
+
+ * config/mt-linux: Define CXXFLAGS to make sure -fvtable-thunks is
+ used.
+ * configure.in: Name Linux target fragment.
+
+ * configure: Rewrite so that project Makefile fragment is inserted
+ first and appears last in the resulting Makefile.
+
+Tue Sep 16 09:55:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (install-itcl): Install tcl first.
+
+Sun Sep 14 20:53:42 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mh-cygwin32: ok to build split texinfo files
+
+Fri Sep 12 16:19:20 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: remove bison from noconfigdirs for Cygwin32 host
+
+Thu Sep 11 16:40:46 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * Makefile.in (local-distclean): Also remove mh-frag mt-frag.
+
+ * configure.in (skipdirs): Add target-librx for Linux.
+ (alpha-*-linux*): Use config/mh-elfalphapic and config/mt-elfalphapic.
+
+Wed Sep 10 21:29:54 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (bootstrap): New target.
+
+Wed Sep 10 15:19:22 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub: Accept 'amigados' for backward compatability.
+
+Mon Sep 8 20:46:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.guess: Merge with FSF.
+
+Sun Sep 7 15:55:28 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config.sub: Add "marketing-names" patch.
+
+Fri Sep 5 16:11:28 1997 Joel Sherrill (joel@OARcorp.com)
+
+ * configure.in (*-*-rtems*): Do not build libgloss for rtems.
+
+Fri Sep 5 12:27:17 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub: Handle v850-elf.
+
+Wed Sep 3 12:15:24 1997 Chris Provenzano <proven@cygnus.com>
+
+ * ltconfig: Set CONFIG_SHELL in libtool.
+ * ltmain.sh: Use CONFIG_SHELL instead of /bin/sh
+
+Mon Sep 1 16:45:44 1997 Jim Wilson <wilson@cygnus.com>
+
+ * configure.in (target_subdir): Set to libraries if enable_multilib.
+
+Wed Aug 27 16:15:11 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config.guess: Update from gcc directory.
+
+Tue Aug 26 16:46:46 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (all-sim): Depends on all-readline.
+
+Wed Aug 20 19:57:37 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (BISON, YACC): Use $$s.
+ (all-bison): Depend on all-texinfo.
+
+Tue Aug 19 01:41:32 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (BISON): Add -L flag.
+ (YACC): Likewise.
+
+Mon Aug 18 11:30:50 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (noconfigdirs): Add support for v850e target.
+
+ * config.sub (maybe_os): Add support for v850e target.
+
+Mon Aug 18 11:30:50 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (noconfigdirs): Add support for v850ea target.
+
+ * config.sub (maybe_os): Add support for v850ea target.
+
+Mon Aug 18 09:24:06 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config.sub: Add mipstx39. Delete r3900.
+
+Mon Aug 18 17:20:10 1997 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (all-autoconf): Depends on all-texinfo.
+
+Fri Aug 15 23:09:26 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config-ml.in ({powerpc,rs6000}*-*-*): Update to current AIX and
+ eabi targets.
+
+Thu Aug 14 14:42:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Get CFLAGS and CXXFLAGS from Makefile, if possible.
+
+ * configure: When handling a Canadian Cross, handle YACC as well as
+ BISON. Just set BISON to bison. When setting YACC, prefer bison.
+ * Makefile.in (all-bison): Depend upon all-texinfo.
+
+Tue Aug 12 20:09:48 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (BISON): bison, not byacc or bison -y.
+ (YACC): bison -y or byacc or yacc.
+ (various): Add *-bison as appropriate.
+ (taz): No need to mess with BISON anymore.
+
+Tue Aug 12 22:33:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: If OSTYPE matches *win32*, try to find a good value for
+ CONFIG_SHELL.
+
+Sun Aug 10 14:41:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (taz): Get the version number from AM_INIT_AUTOMAKE in
+ configure.in if it is present.
+
+Sat Aug 9 00:58:01 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (LD_FOR_TARGET): Change ld.new to ld-new.
+
+Fri Aug 8 16:30:13 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.sub: Recognize `arc' cpu.
+ * configure.in: Likewise.
+ * config-ml.in: Likewise.
+
+Thu Aug 7 11:02:34 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(INSTALL_X11_MODULES)): Depend upon installdirs.
+
+Wed Aug 6 16:27:29 1997 Chris Provenzano <proven@cygnus.com>
+
+ * configure: Changed sed delimiter from ':' to '|' when
+ attempting to substitute ${config_shell} for SHELL. On
+ NT ${config_shell} may contain a ':' in it.
+
+Wed Aug 6 12:29:05 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): Fix for non-bash shells.
+
+Wed Aug 6 00:42:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (AS_FOR_TARGET): Change as.new to as-new.
+
+Tue Aug 5 14:08:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (NM_FOR_TARGET): Change nm.new to nm-new.
+
+ * ylwrap: If the program is a relative path, force it to be
+ absolute.
+
+Tue Aug 5 12:12:44 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure (tooldir): Set BISON to `bison -y' and not just bison.
+
+Mon Aug 4 22:59:02 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): When winsup/Makefile present,
+ correctly specify the target build directory $(TARGET_SUBDIR)/winsup
+ for libraries.
+
+Mon Aug 4 12:40:24 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): Fix handling of macros with values
+ separated by spaces.
+
+Thu Jul 31 19:49:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ylwrap: New file.
+ * Makefile.in (DEVO_SUPPORT): Add ylwrap.
+
+ * ltmain.sh: Handle /bin/sh at start of install program.
+
+ * Makefile.in (DEVO_SUPPORT): Add ltconfig, ltmain.sh, and missing.
+
+ * ltconfig, ltmain.sh: New files, from libtool 1.0.
+ * missing: New file, from automake 1.2.
+
+Thu Jul 24 12:57:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Treat tix like tk, putting it in X11_MODULES. Add
+ check-tk to CHECK_X11_MODULES.
+
+Wed Jul 23 17:03:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Merge with FSF.
+
+Tue Jul 22 19:08:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.guess: Merge with FSF.
+
+Tue Jul 22 14:50:42 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * configure: Treat msdosdjgpp like go32.
+ * configure.in: Likewise. Don't remove gprof for go32.
+
+ * configure: Change Makefile.tem2 to Makefile.tm2.
+
+Mon Jul 21 10:31:26 1997 Stephen Peters <speters@cygnus.com>
+
+ * configure.in (noconfigdirs): For alpha-dec-osf*, don't ignore grep.
+
+Tue Jul 15 14:33:03 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * install-sh (chmodcmd): Set to null if the DST directory already
+ exists. Same as Nov 11th change.
+
+Mon Jul 14 11:01:15 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * configure (GDB_TK): Needs itcl and tix.
+
+Mon Jul 14 00:32:10 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * config.guess: Update from FSF.
+
+Fri Jul 11 11:57:11 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * Makefile.in (GDB_TK): Depend on itcl and tix.
+
+Fri Jul 4 13:25:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL_PROGRAM_ARGS): New variable.
+ (INSTALL_PROGRAM): Use $(INSTALL_PROGRAM_ARGS).
+ (INSTALL_SCRIPT): New variable.
+ (BASE_FLAGS_TO_PASS): Pass down INSTALL_SCRIPT.
+ * configure.in: If host is *-*-cygwin32*, set INSTALL_PROGRAM_ARGS
+ to -x.
+ * install-sh: Add support for -x option.
+
+Mon Jun 30 15:51:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in, Makefile.in: Treat tix like itcl.
+
+Thu Jun 26 13:59:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (WINDRES): New variable.
+ (WINDRES_FOR_TARGET): New variable.
+ (BASE_FLAGS_TO_PASS): Add WINDRES_FOR_TARGET.
+ (EXTRA_HOST_FLAGS): Add WINDRES.
+ (EXTRA_TARGET_FLAGS): Add WINDRES.
+ (EXTRA_GCC_FLAGS): Add WINDRES.
+ ($(DO_X)): Pass down WINDRES.
+ ($(CONFIGURE_TARGET_MODULES)): Set WINDRES when configuring.
+ * configure: Treat WINDRES like DLLTOOL, and WINDRES_FOR_TARGET like
+ DLLTOOL_FOR_TARGET.
+
+Wed Jun 25 15:01:26 1997 Felix Lee <flee@cygnus.com>
+
+ * configure.in: configure sim before gdb for win32-x-ppc
+
+Wed Jun 25 12:18:54 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ Move gperf into the toplevel, from libg++.
+ * configure.in (target_tools): Add target-gperf.
+ (native_only): Add target-gperf.
+ * Makefile.in (all-target-gperf): New target, depend on
+ all-target-libg++.
+ (configure-target-gperf): Empty rule.
+ (ALL_TARGET_MODULES): Add all-target-gperf.
+ (CONFIGURE_TARGET_MODULES): Add configure-target-gperf.
+ (CHECK_TARGET_MODULES): Add check-target-gperf.
+ (INSTALL_TARGET_MODULES): Add install-target-gperf.
+ (CLEAN_TARGET_MODULES): Add clean-target-gperf.
+
+Mon Jun 23 10:51:53 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub (mn10200): Recognize new basic machine.
+
+Thu Jun 19 14:16:42 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in: Don't set ENABLE_MULTILIB, so we'll be passing
+ --enable-multilib down to subdirs; setting TARGET_SUBDIR was enough.
+
+Tue Jun 17 15:31:20 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in: If we're building mips-sgi-irix6* native, turn on
+ ENABLE_MULTILIB and set TARGET_SUBDIR.
+
+Tue Jun 17 12:20:59 1997 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (all-sn): Depend on all-grep.
+
+Mon Jun 16 11:11:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use mh-ppcpic and mt-ppcpic for powerpc*-* targets.
+
+ * configure: Set CFLAGS and CXXFLAGS, and substitute them into
+ Makefile. From Jeff Makey <jeff@cts.com>.
+ * Makefile.in: Add comment for CFLAGS and CXXFLAGS.
+
+ * Makefile.in (DISTBISONFILES): Remove.
+ (taz): Don't futz with DISTBISONFILES. Change BISON to use
+ $(DEFAULT_YACC).
+
+ * configure.in: Build itl, db, sn, etc., when building for native
+ cygwin32.
+
+ * Makefile.in (LD): New variable.
+ (EXTRA_HOST_FLAGS): Pass down LD.
+ ($(DO_X)): Likewise.
+
+Mon Jun 16 11:10:35 1997 Philip Blundell <Philip.Blundell@pobox.com>
+
+ * Makefile.in (INSTALL): Use $(SHELL) when executing install-sh.
+
+Fri Jun 13 10:22:56 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in (targargs): Strip out any supplied --build argument
+ before adding our own. Always add --build.
+
+Thu Jun 12 21:12:28 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure.in (targargs): Pass --build if we're doing
+ a cross-compile.
+
+Fri Jun 6 21:38:40 1997 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure: Use '|' instead of ":" as the seperator in
+ sed. Otherwise sed chokes on NT path names with drive
+ designators. Also look for "?:*" as the leading characters in an
+ absolute pathname.
+
+Mon Jun 2 13:05:20 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config.sub: Support for r3900.
+
+Wed May 21 17:33:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use install-sh, not install.sh.
+
+Wed May 14 16:06:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (taz): Improve check for BISON so it doesn't try to
+ apply it twice.
+
+Fri May 9 17:22:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL_MODULES): Put install-opcodes before
+ install-binutils.
+
+Thu May 8 17:29:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Add automake targets.
+ * configure.in (host_tools): Add automake.
+
+Tue May 6 15:49:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Default CXX to c++, not gcc.
+ * Makefile.in (CXX): Set to c++, not gcc.
+ (CXX_FOR_TARGET): When cross, transform c++, not gcc.
+
+Thu May 1 10:11:43 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * install-sh: try appending a .exe if source file doesn't
+ exist
+
+Wed Apr 30 12:05:36 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in: Turn on multilib by default.
+ (cross_only): Remove target-libiberty.
+
+ * Makefile.in (all-gcc): Don't depend on libiberty.
+
+Mon Apr 28 18:39:45 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * config.guess: improve algorithm for recognizing Gnu Hurd x86.
+
+Thu Apr 24 19:30:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DEVO_SUPPORT): Add mpw-install.
+ (DISTBISONFILES): Add ld/Makefile.in
+
+Tue Apr 22 17:17:28 1997 Geoffrey Noer <noer@pizza.cygnus.com>
+
+ * configure.in: if target is cygwin32 but host isn't cygwin32,
+ don't configure gdb tcl tk expect, not just gdb.
+
+Mon Apr 21 13:33:39 1997 Tom Tromey <tromey@cygnus.com>
+
+ * configure.in: Added gnuserv everywhere sn appears.
+
+ * Makefile.in (ALL_MODULES): Added all-gnuserv.
+ (CROSS_CHECK_MODULES): Added check-gnuserv.
+ (INSTALL_MODULES): Added install-gnuserv.
+ (CLEAN_MODULES): Added clean-gnuserv.
+ (all-gnuserv): New target.
+
+Thu Apr 17 13:57:06 1997 Per Fogelstrom <pefo@openbsd.org>
+
+ * config.guess: Fixes for MIPS OpenBSD systems.
+
+Tue Apr 15 12:21:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL_XFORM): Remove.
+ (BASE_FLAGS_TO_PASS): Remove INSTALL_XFORM.
+
+ * mkinstalldirs: New file, copied from automake.
+ * Makefile.in (installdirs): Rename from install-dirs. Use
+ mkinstalldirs. Change all users.
+ (DEVO_SUPPORT): Add mkinstalldirs.
+
+Mon Apr 14 11:21:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * install-sh: Rename from install.sh.
+ * Makefile.in (INSTALL): Change install.sh to install-sh.
+ (DEVO_SUPPORT): Likewise.
+
+ * configure: Use ${config_shell} with ${moveifchange}. From Thomas
+ Graichen <graichen@rzpd.de>.
+
+Fri Apr 11 16:37:10 1997 Niklas Hallqvist <niklas@appli.se>
+
+ * config.guess: Recognize OpenBSD systems correctly.
+
+Fri Apr 11 17:07:04 1997 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * README, Makefile.in (ETC_SUPPORT): Remove references to
+ cfg-paper*, configure.{texi,man,info*}._
+
+Sun Apr 6 18:47:57 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * Makefile.in (all.normal): Ensure that gcc is built after all
+ the x11 - ie gdb - targets.
+
+Tue Apr 1 16:28:50 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Don't run conf-a-gas.
+
+Mon Mar 31 16:26:55 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (hppa1.1-*-rtems*): New target, like hppa-*-*elf*.
+
+Sun Mar 30 12:38:27 1997 Fred Fish <fnf@cygnus.com>
+
+ * configure.in: Remove noconfigdirs case since gdb also
+ configures and builds for tic80-coff.
+
+Fri Mar 28 18:28:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Set cache_file to config.cache.
+ * Makefile.in (local-distclean): Remove config.cache.
+
+Wed Mar 26 18:49:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * COPYING: Update FSF address.
+
+Wed Mar 26 10:38:25 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (tic80-*-*): Remove G++ libraries and libgloss from
+ noconfigdirs.
+
+Mon Mar 24 15:02:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install-dirs): Don't crash if prefix, and hence
+ MAKEDIRS, is empty.
+
+Mon Mar 24 12:40:55 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.sub: Tweak mn10300 entry.
+
+Fri Mar 21 15:35:27 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (host_tools): Put sim before gdb, so gdb's
+ configure.tgt can determine if the simulator was configured.
+
+Sun Mar 16 16:07:08 1997 Fred Fish <fnf@cygnus.com>
+
+ * config.sub: Move BeOS $os case to be with other Cygnus
+ local cases.
+
+Sun Mar 16 01:34:55 1997 Martin Hunt <hunt@cygnus.com>
+
+ * config.sub: Remove misplaced comment that broke Linux.
+
+Sat Mar 15 22:50:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * config.sub: Add BeOS support.
+
+Mon Mar 10 13:30:11 1997 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (CHECK_X11_MODULES): Don't run check-tk.
+
+Wed Mar 5 12:09:29 1997 Martin <hunt@cygnus.com>
+
+ * configure.in (noconfigdirs): Remove tcl and tk from
+ noconfigdirs for cygwin32 builds.
+
+Fri Feb 28 18:20:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (tic80-*-*): Remove ld from noconfigdirs.
+
+Thu Feb 27 14:57:26 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (GAS_SUPPORT_DIRS, BINUTILS_SUPPORT_DIRS): Remove
+ make-all.com, use makefile.vms instead.
+
+Tue Feb 25 18:46:14 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config.sub: Accept -lnews*.
+
+Tue Feb 25 13:19:14 1997 Andrew Cagney <cagney@kremvax.tpgi.com.au>
+
+ * configure.in (noconfigdirs): Disable target-newlib,
+ target-examples and target-libiberty for d30v.
+
+Fri Feb 21 17:56:25 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * configure.in (noconfigdirs): Enable ld for d30v.
+
+Fri Feb 21 20:58:51 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (tic80-*-*): Build compiler.
+
+Sun Feb 16 15:41:09 1997 Andrew Cagney <cagney@critters.cygnus.com>
+
+ * configure.in (d30v-*): Remove sim directory from list of
+ unsupported d30v directories
+
+Tue Feb 18 17:32:42 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config.sub, configure.in: Add d30v target cpu.
+
+Thu Feb 13 22:04:44 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: New file.
+ * make-all.com: Remove.
+
+Wed Feb 12 12:54:18 1997 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): Add LIBGCC2_DEBUG_CFLAGS.
+
+Sat Feb 8 20:36:49 1997 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.in (all-itcl): The rule is all-itcl, not all-tcl.
+
+Tue Feb 4 11:39:29 1997 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (ALL_MODULES): Added all-db.
+ (CROSS_CHECK_MODULES): Addec check-db.
+ (INSTALL_MODULES): Added install-db.
+ (CLEAN_MODULES): Added clean-db.
+
+Mon Feb 3 13:29:36 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.guess: Merge with latest FSF sources.
+
+Tue Jan 28 09:20:37 1997 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (ALL_MODULES): Added all-itcl.
+ (CROSS_CHECK_MODULES): Added check-itcl.
+ (INSTALL_MODULES): Added install-itcl.
+ (CLEAN_MODULES): Added clean-itcl.
+
+Thu Jan 23 01:44:27 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: build gdb for mn10200
+
+Fri Jan 17 15:32:15 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (all-target-winsup): Depend on all-target-libio.
+
+Mon Jan 13 22:46:54 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (tic80-*-*): Turn off most targets right now.
+
+Fri Jan 3 16:04:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (MAKEINFO): Check for the existence of the Makefile,
+ rather than the makeinfo program.
+ (do-info): Depend upon all-texinfo.
+
+Tue Dec 31 16:00:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Remove uses of config/mh-linux.
+
+ * config.sub, config.guess: Merge with latest FSF sources.
+
+Fri Dec 27 23:04:33 1996 Fred Fish <fnf@cygnus.com>
+
+ * config.sub (case $basic_machine): Add tic80 entries.
+
+Fri Dec 27 12:07:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub, config.guess: Merge with latest FSF sources.
+
+Wed Dec 18 22:46:39 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-build.in: Build ld before gcc, use NewFolderRecursive.
+ * mpw-config.in: Test for NewFolderRecursive.
+ * mpw-install: Use symbolic name for startup filename.
+ * mpw-README: Add various additional details.
+
+Wed Dec 18 13:11:46 1996 Jim Wilson <wilson@cygnus.com>
+
+ * configure.in (mips*-sgi-irix6*): Remove binutils from noconfigdirs.
+
+Wed Dec 18 10:29:31 1996 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Do build gcc and the target libraries for
+ the mn10200.
+
+Wed Dec 4 16:53:05 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: don't avoid building gdb for mn10300 any more
+ * Makefile.in: double-quote GCC_FOR_TARGET line in EXTRA_GCC_FLAGS
+ instead of single-quoting it.
+
+Tue Dec 3 23:26:50 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in: Don't use --with-stabs on IRIX 6.
+
+Tue Dec 3 09:05:25 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (m32r): Build gdb, libg++ now.
+
+Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in (mips*-sgi-irix6*): Remove gdb and related
+ directories from noconfigdirs.
+
+Tue Nov 26 11:45:33 1996 Kim Knuttila <krk@cygnus.com>
+
+ * config.sub (basic_machine): added mips16 configuration
+
+Sat Nov 23 19:26:22 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.sub: Handle d10v-unknown.
+
+Sat Nov 23 10:23:01 1996 Gavin Koch <gavin@cygnus.com>
+
+ * config.sub: Handle v850-unknown.
+
+Thu Nov 21 16:19:44 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.in: add findutils
+ * configure.in: add findutils to list of host_tools
+
+Wed Nov 20 10:09:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config.sub: Handle mn10200 and mn10300.
+
+Tue Nov 19 16:35:14 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (d10v-*): Do not build librx.
+
+Mon Nov 18 13:28:41 1996 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in (mn10300): Build everything except gdb & libgloss.
+
+Wed Nov 13 14:59:46 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * config.guess: Patch for Dansk Data Elektronik servers,
+ from Niels Skou Olsen <nso@dde.dk>.
+
+ For ncr, use /bin/uname rather than uname, since GNU uname does not
+ support -p. Suggested by Mark Mitchell <mmitchell@usa.net>.
+
+ Patch for MIPS R4000 running System V,
+ from Eric S. Raymond <esr@snark.thyrsus.com>.
+
+ Fix thinko for nextstep.
+
+ Patch for OSF1 in i?86, from Dan Murphy <dlm@osf.org> via Harlan Stenn.
+
+ Sat Jun 24 18:58:17 1995 Morten Welinder <terra+@cs.cmu.edu>
+ * config.guess: Guess mips-dec-mach_bsd4.3.
+
+ Thu Oct 10 04:07:04 1996 Harlan Stenn <harlan@pfcs.com>
+ * config.guess (i?86-ncr-sysv*): Emit just enough of the minor
+ release numbers.
+ * config.guess (mips-mips-riscos*): Emit just enough of the
+ release number.
+
+ Tue Oct 8 10:37:22 1996 Frank Vance <fvance@waii.com>
+ * config.guess (sparc-auspex-sunos*): Added.
+ (f300-fujitsu-*): Added.
+
+ Wed Sep 25 22:00:35 1996 Jeff Woolsey <woolsey@jlw.com>
+ * config.guess: Recognize a Tadpole as a sparc.
+
+Wed Nov 13 00:53:09 1996 David J. MacKenzie <djm@churchy.gnu.ai.mit.edu>
+
+ * config.guess: Don't assume that NextStep version is either 2 or
+ 3. NextStep 4 (aka OpenStep 4) has come out now.
+
+Mon Nov 11 23:52:03 1996 David J. MacKenzie <djm@churchy.gnu.ai.mit.edu>
+
+ * config.guess: Support Cray T90 that reports itself as "CRAY TS".
+ From Rik Faith <faith@cs.unc.edu>.
+
+Fri Nov 8 11:34:58 1996 David J. MacKenzie <djm@geech.gnu.ai.mit.edu>
+
+ * config.sub: Contributions from bug-gnu-utils to:
+ Support plain "hppa" (no version given) architecture, reported by
+ OpenStep.
+ OpenBSD like NetBSD.
+ LynxOs is not a hardware supplier.
+
+ * config.guess: Contributions from bug-gnu-utils to add support for:
+ OpenBSD like NetBSD.
+ Stratus systems.
+ More Pyramid systems.
+ i[n>4]86 Intel chips.
+ M680[n>4]0 Motorola chips.
+ Use unknown instead of lynx for hardware manufacturer.
+
+Mon Nov 11 10:09:08 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * install.sh (chmodcmd): Set to null if the DST directory already
+ exists.
+
+Mon Nov 11 10:43:41 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (powerpc*-{eabi,elf,linux,rtem,sysv,solaris}*): Do
+ not use mt-ppc target Makefile fragment any more.
+
+Sun Nov 3 19:17:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in (*-*-windows): Exclude everything but those dirs
+ needed to build windows.
+
+Tue Oct 29 16:41:31 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (all-target-winsup): Depend on all-target-librx.
+
+Mon Oct 28 17:32:46 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in: Exclude mmalloc from i386-windows.
+ * config/mh-windows: Add rules for building MSVC makefiles.
+
+Thu Oct 24 09:22:46 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Undo my previous change.
+
+Thu Oct 24 12:12:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): Pass down GCC_FOR_TARGET
+ unconditionally.
+ (MAKEOVERRIDES): Define (revert this part of October 18 change).
+
+Thu Oct 24 09:02:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Add $(HOST_FLAGS) to allow the
+ host to add it's own flags.
+ * config/mh-windows (HOST_FLAGS): Set srcroot, which is needed
+ for MSVC build procedure.
+
+Tue Oct 22 15:20:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Handle GCC_FOR_TARGET like CC_FOR_TARGET.
+
+Fri Oct 18 13:37:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): Check for xgcc, not Makefile.
+ (CXX_FOR_TARGET): Likewise.
+ (GCC_FOR_TARGET): Define.
+ (BASE_FLAGS_TO_PASS): Remove GCC_FOR_TARGET.
+ (EXTRA_GCC_FLAGS): Define GCC_FOR_TARGET based on whether
+ CC_FOR_TARGET was specified on the command line.
+ (MAKEOVERRIDES): Don't define.
+
+Thu Oct 17 10:27:56 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (m32r): Fix spelling of libg++ libs.
+
+Thu Oct 10 10:37:17 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config.sub (-apple*): Remove, now redundant.
+
+Thu Oct 10 12:30:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Don't get confused by CPU-VENDOR-linux-gnu.
+
+ * configure: Rework yesterday's sed script patch.
+
+ * config.sub: Merge with FSF.
+
+Wed Oct 9 17:24:59 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * config.guess: Merge from FSF.
+
+ 1996-09-12 Richard Stallman <rms@ethanol.gnu.ai.mit.edu>
+ * config.guess: Use pc instead of unknown, for pc clone systems.
+ Change linux to linux-gnu.
+
+ Mon Jul 15 23:51:11 1996 Karl Heuer <kwzh@gnu.ai.mit.edu>
+ * config.guess: Avoid non-portable tr syntax.
+
+Wed Oct 9 06:06:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * test-build.mk (HOLES): Add "xargs" for gdb.
+
+ * configure: Avoid hpux10.20 sed bug.
+
+Tue Oct 8 08:32:48 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in config/mh-windows: Add support for windows host
+ (that is a build done under the Microsoft build environment).
+
+Tue Oct 8 10:39:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Replace all uses of srcroot with s, to shrink
+ command line lengths.
+
+ Patches from Geoffrey Noer <noer@cygnus.com>:
+ * configure.in: If configuring for newlib, pass --with-newlib to
+ subdirectories.
+ * Makefile.in (CC_FOR_TARGET): If winsup/Makefile exists, pass a
+ -Bnewlib/ and -Lwinsup to gcc.
+ (CXX_FOR_TARGET): Likewise.
+
+Mon Oct 7 10:59:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ETC_SUPPORT): Add configure.
+
+Fri Oct 4 12:22:58 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * configure.in: Use config/mh-dgux386 for i[345]86-dg-dgux
+ host configuration file.
+
+Thu Oct 3 09:28:25 1996 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Break mn10x00 support into separate
+ mn10200 and mn10300 configurations.
+ * config.sub: Likewise.
+
+Wed Oct 2 22:27:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Add lots of stuff to noconfigdirs for
+ the mn10x00 targets.
+
+ * config.sub, configure.in: Add mn10x00 support.
+
+Wed Oct 2 15:52:36 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * make-all.com: Call conf-a-gas, not config-a-gas.
+
+Tue Oct 1 01:28:41 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * configure.in (noconfigdirs): Don't build libgloss for arm-coff
+ targets.
+
+Mon Sep 30 14:24:01 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-README: Add much more detail for native PowerMac.
+ * mpw-install: New file.
+ * mpw-configure: Add --norecursion and --help options.
+ * mpw-config.in: Translate readme and install files when
+ copying to objdir.
+ * mpw-build.in: Don't always depend on byacc and flex.
+ (install-only-top): New action.
+
+Fri Sep 27 17:39:44 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in: You can now configure GDB for the v850.
+
+Tue Sep 24 19:05:12 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (noconfigdirs): Don't configure any C++ dirs
+ if targeting D10V.
+
+Tue Sep 17 12:15:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Recognize mips64vr5000.
+
+Mon Sep 16 17:00:52 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use a single line for host_tools and native_only.
+
+Mon Sep 9 12:21:30 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.sub, configure.in: Add entries for m32r.
+
+Thu Sep 5 13:52:47 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (inet-install): Don't run install-gzip.
+
+Wed Sep 4 17:26:13 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.in: Don't config lots of things for *-*-windows*.
+
+Sat Aug 31 11:45:57 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Test for mpw-true, true, and null-command scripts.
+ (host_libs, host_tools): Copy from configure.in.
+ * mpw-configure: Don't complain about directories not found.
+
+Thu Aug 29 16:44:58 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (i[345]86): Recognize i686 for pentium pro.
+ (i[3456]86-*-dgux*): Use config/mh-sysv for the host configuration
+ file.
+
+ * config.guess (i[345]86): Ditto.
+
+Mon Aug 26 18:34:42 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * configure.in (noconfigdirs): Removed gdb for D10V.
+
+Thu Aug 22 17:13:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * configure.in: Remove ld, target-libio, target-libg++, and
+ target-libstdc++ from noconfigdirs.
+
+Wed Aug 21 18:56:38 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure: Fix three locations where shell scripts were
+ being run directly rather than with config_shell.
+
+Tue Aug 20 13:08:47 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * configure.in (v850-*-*): Set up initial $noconfigdirs.
+ * config.sub (basic_machine): Recognize v850.
+
+Thu Aug 15 12:19:33 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Handle multiple enable/disable options and
+ pass them down recursively, handle -c and -s flags appropriately
+ depending on choice of compiler, add escape mechanism for
+ quoted arguments to gC.
+
+Mon Aug 12 13:15:13 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (powerpc*-*-*): For eabi, system V.4, Linux, and
+ solaris targets, use config/mt-ppc to set C{,XX}FLAGS_FOR_TARGETS
+ so that -mrelocatable-lib and -mno-eabi are used.
+
+ * Makefile.in (CONFIGURE_TARGET_MODULES): If target compiler does
+ not support --print-multi-lib, don't abort.
+
+Sun Aug 11 20:51:50 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/mh-cygwin32 (CFLAGS): Define _WIN32 to be compatible
+ with normal Windows compilation environment.
+
+Thu Aug 8 12:18:59 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * make-all.com: Run config-a-gas.
+ * setup.com: Don't copy subdirectory files around.
+
+Tue Jul 30 17:49:31 1996 Brendan Kehoe <brendan@cygnus.com>
+
+ * configure.in (*-*-ose): Remove exclusion of libgloss for this
+ target, it now compiles correctly.
+
+Sat Jul 27 15:10:43 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Generate Mac include for elf/dwarf2.h.
+
+Tue Jul 23 10:47:04 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * configure.in (d10v-*-*): Remove ld from $noconfigdirs.
+
+Mon Jul 22 13:28:51 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in (native_only): Add prms.
+
+Mon Jul 22 12:27:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (GAS_SUPPORT_DIRS): Add make-all.com and setup.com.
+ (BINUTILS_SUPPORT_DIRS): Likewise.
+
+Thu Jul 18 12:55:40 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (d10v-*-*): Don't configure ld or gdb until the
+ d10v support is added.
+
+Wed Jul 17 14:33:09 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * configure.in (d10v-*-*): New target.
+
+Mon Jul 15 11:53:00 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess (HP 9000/811): Recognize this as a PA1.1
+ machine.
+
+Fri Jul 12 23:21:17 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (do-tar-gz): New target, split out from tail end of
+ taz target. Run each command separately, don't use pipes.
+ (taz): Use it.
+
+Fri Jul 12 12:08:04 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Look for g-mpw-make.sed in config/mpw.
+ * mpw-build.in: No builds should depend on building byacc or flex,
+ they are assumed to be installed already.
+
+Fri Jul 12 09:52:52 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (CONFIGURE_TARGET_MODULES): Set r environment
+ variable that CC_FOR_TARGET needs.
+
+Thu Jul 11 10:09:45 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (CONFIGURE_TARGET_MODULES): Determine if the multlib
+ options have changed since the last time the subdirectory was
+ configured, and if it has, reconfigure.
+ (CLEAN_TARGET_MODULES): Delete multilib.out and tmpmulti.out, which
+ CONFIGURE_TARGET_MODULES uses to remember the old multilib options.
+
+Wed Jul 10 18:56:59 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (ALL_MODULES,CROSS_CHECK_MODULES,INSTALL_MODULES,
+ CLEAN_MODULES): Add bash.
+ (all-bash): New target.
+
+Mon Jul 8 17:33:14 1996 Jim Wilson <wilson@cygnus.com>
+
+ * configure.in (mips-sgi-irix6*): Use mh-irix6 instead of mh-irix5.
+
+Mon Jul 1 13:31:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.sub (basic_machine): Recognize d10v as a valid processor.
+
+Fri Jun 28 12:14:35 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Add support for --bindir.
+ * mpw-build.in: Use a GCC-specific build script for GCC actions.
+
+Wed Jun 26 17:20:12 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: add bash, time, gawk to list of hosttools and things
+ to only build for native toolchains
+
+Tue Jun 25 23:09:03 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (docdir): Remove.
+
+Tue Jun 25 19:00:08 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (datadir): Set to $(prefix)/share.
+
+Mon Jun 24 23:26:07 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: build diff and patch for cygwin32-hosted
+ toolchains.
+
+Mon Jun 24 15:01:12 1996 Joel Sherrill <joel@merlin.gcs.redstone.army.mil>
+
+ * config.sub: Accept -rtems*.
+
+Sun Jun 23 22:41:54 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: enable dosrel for cygwin32-hosted builds,
+ remove diff from the list of things not buildable
+ via Canadian Cross
+
+Sat Jun 22 11:39:01 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (TARGET_SUBDIR): Move comment to previous line so we
+ don't get ". ".
+
+Fri Jun 21 17:24:48 1996 Jim Wilson <wilson@cygnus.com>
+
+ * configure.in (mips*-sgi-irix6*): Set noconfigdirs appropriately.
+
+Thu Jun 20 16:57:40 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (taz): Handle case where tex3patch didn't even get
+ checked out. Also, if it was found, put the symlink in a new util
+ subdirectory.
+
+Thu Jun 20 12:20:33 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.guess (*:Linux:*:*): Add support for PowerPC Linux.
+
+Tue Jun 18 14:24:12 1996 Klaus Kaempf (kkaempf@progis.de)
+
+ * config.sub: Recognize -openvms.
+ * configure.in (alpha*-*-*vms*): Set noconfigdirs.
+ * make-all.com, setup.com: New files.
+
+Mon Jun 17 16:34:46 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (taz): tex3patch moved to texinfo/util.
+
+Sat Jun 15 17:13:25 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: remove make from disable-if-Can-Cross list
+ enable gdb if ${host} and ${target} are cygwin32
+
+Fri Jun 7 18:16:52 1996 Harlan Stenn <harlan@pfcs.com>
+
+ * config.guess (i?86-ncr-sysv*): Emit minor release numbers.
+ Recognize the NCR 4850 machine and NCR Pentium-based platforms.
+
+Wed Jun 5 00:09:17 1996 Per Bothner <bothner@wombat.gnu.ai.mit.edu>
+
+ * config.guess: Combine mips-mips-riscos cases, and use cpp to
+ distinguish sysv/svr4/bsd variants.
+ Based on a patch from Harlan Stenn <harlan@pfcs.com>.
+
+Fri Jun 7 14:24:49 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * configure.in: Added copyright notice.
+ * move-if-change: Added copyright notice.
+
+Thu Jun 6 16:27:05 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (powerpcle-*-solaris*): Until we get shared
+ libraries working, don't build gdb, sim, make, tcl, tk, or
+ expect.
+
+Tue Jun 4 20:41:45 1996 Per Bothner <bothner@deneb.cygnus.com>
+
+ * config.guess: Merge with FSF:
+
+ Mon Jun 3 08:49:14 1996 Karl Heuer <kwzh@gnu.ai.mit.edu>
+ * config.guess (*:Linux:*:*): Add guess for sparc-unknown-linux.
+
+ Fri May 24 18:34:53 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+ * config.guess (AViiON:dgux:*:*): Fix typo in recognizing mc88110.
+
+ Fri Apr 12 20:03:59 1996 Per Bothner <bothner@spiff.gnu.ai.mit.edu>
+ * config.guess: Combine two OSF1 rules.
+ Also recognize field test versions. From mjr@zk3.dec.com.
+ * config.guess (dgux): Use /usr/bin/uname rather than uname,
+ because GNU uname does not support -p. From pmr@pajato.com.
+
+Tue Jun 4 11:07:25 1996 Tom Tromey <tromey@csk3.cygnus.com>
+
+ * Makefile.in (MAKEDIRS): Removed $(tooldir).
+
+Tue May 28 12:30:50 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-README: Document GCCIncludes.
+
+Sun May 26 15:16:27 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (alpha-*-linux*): Set enable_shared to yes.
+
+Tue May 21 15:41:39 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Handle --enable-FOO and --disable-FOO.
+
+Mon May 20 10:12:29 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in (*-*-cygwin32): Configure make.
+
+Tue May 7 14:19:42 1996 Tom Tromey <tromey@snuffle.cygnus.com>
+
+ * Makefile.in (inet-install): Quote value of INSTALL_MODULES.
+
+Fri May 3 08:57:17 1996 Tom Tromey <tromey@lisa.cygnus.com>
+
+ * Makefile.in (all-inet): Depend on all-perl.
+
+ * Makefile.in (inet-install): New target.
+
+ * Makefile.in (all-inet): Depend on all-tcl.
+ (all-inet): Depend on all-send-pr.
+
+Tue Apr 30 13:55:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (powerpcle-*-solaris*): Turn off tk and tcl
+ temporarily.
+
+Thu Apr 25 11:48:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't configure --with-gnu-ld on AIX.
+
+Thu Apr 25 06:33:36 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * configure.in (powerpcle-*-solaris*): Turn off gdb temporarily.
+
+Tue Apr 23 09:07:39 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (ALL_MODULES): Added all-inet.
+ (CROSS_CHECK_MODULES): Added check-inet.
+ (INSTALL_MODULES): Added install-inet.
+ (CLEAN_MODULES): Added clean-inet.
+ (all-indent): New target.
+
+ * configure.in (host_tools): Added inet.
+ (native_only): Added inet.
+ (noconfigdirs): Added inet.
+
+Fri Apr 19 15:35:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't configure libgloss if we are not configuring
+ newlib.
+
+Wed Apr 17 19:30:01 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Don't configure libgloss for unsupported
+ architectures.
+
+Tue Apr 16 11:17:05 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (CLEAN_MODULES): Add clean-apache.
+
+Mon Apr 15 15:09:05 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (ALL_MODULES): Include all-apache.
+ (CROSS_CHECK_MODULES): Include check-apache.
+ (INSTALL_MODULES): Include install-apache.
+ (all-apache): New target.
+
+ * configure.in: Added apache everywhere perl is seen.
+
+Mon Apr 15 14:59:13 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in: Add support for clean-{module} and
+ clean-target-{module} rules.
+
+Wed Apr 10 21:37:41 PDT 1996 Marilyn E. Sander <msander@cygnus.com>
+
+ * configure.in (*-*-ose) do not build libgloss.
+
+Mon Apr 8 16:16:20 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.guess (prep*:SunOS:5.*:*): Turn into
+ powerpele-unknown-solaris2.
+
+Mon Apr 8 14:45:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+
+Fri Apr 5 08:17:57 1996 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (host==solaris): Pass only the first word of $CC
+ to /usr/bin/which when checking if we're using /usr/ccs/bin/cc.
+
+Fri Apr 5 03:16:13 1996 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): pass down $(MAKE).
+
+Thu Mar 28 14:11:11 1996 Tom Tromey <tromey@creche.cygnus.com>
+
+ * Makefile.in (ALL_MODULES): Include all-perl.
+ (CROSS_CHECK_MODULES): Include check-perl.
+ (INSTALL_MODULES): Include install-perl.
+ (ALL_X11_MODULES): Include all-guile.
+ (CHECK_X11_MODULES): Include check-guile.
+ (INSTALL_X11_MODULES): Include install-guile.
+ (all-perl): New target.
+ (all-guile): New target.
+
+ * configure.in (host_tools): Include perl and guile.
+ (native_only): Include perl and guile.
+ (noconfigdirs): Don't build guile and perl; no ports have been
+ done.
+
+Tue Mar 26 21:18:50 1996 Andrew Cagney <cagney@kremvax.highland.com.au>
+
+ * configure (--enable-*): Handle quoted option lists such as
+ --enable-sim-cflags='-g0 -O' better.
+
+Thu Mar 21 11:53:08 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in ({,inst}all-target): New rule so we can make and
+ install all of the target directories easily.
+
+Wed Mar 20 18:10:57 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in: Add missing global flag in sed substitution when
+ deleting `target-' from ${configdirs}.
+
+Thu Mar 14 19:15:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DO_X): Don't get confused if CC contains `=' in an
+ option.
+
+ * configure.in (mips*-nec-sysvr4*): Use a host_makefile_frag of
+ config/mh-necv4.
+
+ * install.sh: Correct misspelling of transformbasename.
+
+ * config.guess: Recognize mips-*-sysv*.
+
+Mon Mar 11 15:36:42 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * config.sub: Recognize mon960.
+
+Sun Mar 10 13:18:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Restore Canadian Cross handling of BISON and LEX,
+ removed in Feb 20 change.
+
+Fri Mar 8 20:07:09 1996 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * README: Suggestions from Torbjorn Granlund <tege@matematik.su.se>:
+ Mention make install. Remove the old copyright date as well the
+ clumsy and rather pointless copyright on the README file.
+
+Fri Mar 8 17:51:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(CONFIGURE_TARGET_MODULES)): If there is a
+ Makefile after running symlink-tree, then run `make distclean' to
+ avoid clobbering any generated files in srcdir.
+
+Tue Mar 5 08:21:44 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (m68k-*-netbsd*): Build everything now.
+
+Wed Feb 28 12:25:46 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (taz): Fix quoting.
+
+Tue Feb 27 11:33:57 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in (sparclet-*-*): Build everything now.
+
+Tue Feb 27 14:31:51 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in (m68k-*-linux*): New host.
+
+Mon Feb 26 14:32:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Check for bison before byacc.
+
+Tue Feb 20 23:12:35 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * Makefile.in configure: Change the way LEX and BISON/YACC are
+ set. configure now defines DEFAULT_LEX and DEFAULT_YACC by
+ searching PATH. These are used as fallbacks by Makefile.in if
+ flex/bison/byacc aren't in objdir.
+
+Mon Feb 19 11:45:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Make everything which depends upon all-bfd also
+ depend upon all-opcodes, in case --with-commonbfdlib is used.
+
+Thu Feb 15 19:50:50 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (host *-*-cygwin32): Don't build gdb if we are
+ building NT native compilers on Unix.
+
+Thu Feb 15 17:42:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't get CC from the host Makefile fragment if we
+ can find gcc in PATH, or if this is a Canadian Cross. Move the
+ Solaris test for /usr/ucb/cc to the post target script, just after
+ the compiler sanity test.
+
+Wed Feb 14 16:57:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Merge with FSF.
+
+Tue Feb 13 14:27:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (RPATH_ENVVAR): New variable.
+ (REALLY_SET_LIB_PATH): Use it.
+ * configure.in: On HP/UX, set RPATH_ENVVAR to SHLIB_PATH.
+
+Mon Feb 12 15:28:49 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config.sub, configure.in: Recognize sparclet cpu.
+
+Mon Feb 12 15:33:59 1996 Christian Bauernfeind <chrisbfd@theorie3.physik.uni-erlangen.de>
+
+ * config.guess: Support m68k-cbm-sysv4.
+
+Sat Feb 10 12:06:42 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config.guess (*:Linux:*:*): Guess m68k-unknown-linux and
+ m68k-unknown-linuxaout from linker help string. Put quotes around
+ $ld_help_string.
+
+Thu Dec 7 09:03:24 1995 Tom Horsley <Tom.Horsley@mail.hcsc.com>
+
+ * config.guess (powerpc-harris-powerunix): Add guess for port
+ to new target.
+
+Thu Feb 8 15:37:52 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config.guess (UNAME_VERSION): Recognize X4.x as an OSF version.
+
+Mon Feb 5 16:36:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: If --enable-shared was used, set SET_LIB_PATH to
+ $(REALLY_SET_LIB_PATH) in Makefile.
+ * Makefile.in (SET_LIB_PATH): New variable.
+ (REALLY_SET_LIB_PATH): New variable.
+ ($(DO_X)): Use $(SET_LIB_PATH).
+ (install.all, gcc-no-fixedincludes, $(ALL_MODULES)): Likewise.
+ ($(NATIVE_CHECK_MODULES), $(CROSS_CHECK_MODULES)): Likewise.
+ ($(INSTALL_MODULES), $(CONFIGURE_TARGET_MODULES)): Likewise.
+ ($(ALL_TARGET_MODULES), $(CHECK_TARGET_MODULES)): Likewise.
+ ($(INSTALL_TARGET_MODULES), $(ALL_X11_MODULES)): Likewise.
+ ($(CHECK_X11_MODULES), $(INSTALL_X11_MODULES)): Likewise.
+ (all-gcc, all-bootstrap, check-gcc, install-gcc): Likewise.
+ (install-dosrel): Likewise.
+ (all-opcodes): Depend upon all-libiberty.
+
+Sun Feb 4 16:51:11 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config.guess (*:CYGWIN*): New
+
+Sat Feb 3 10:42:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (all-target-winsup): All all-target-libiberty.
+
+Fri Feb 2 17:58:56 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (noconfigdirs): Add missing # in front of comment.
+
+Thu Feb 1 14:38:13 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: add second pass to things added to noconfigdirs
+ so *-gm-magic can exclude libgloss properly.
+
+Thu Feb 1 11:10:16 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure (extralibs_name, rez_name): Set correctly
+ for MWC68K compiler.
+
+ * mpw-README: Add more info on the necessary build tools.
+
+Thu Feb 1 10:22:38 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in, config.sub: Recognize cygwin32.
+
+Wed Jan 31 14:17:10 1996 Richard Henderson <rth@tamu.edu>
+
+ * config.guess, config.sub: Recognize A/UX.
+
+Wed Jan 31 13:52:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Merge with gcc/config.sub.
+
+Thu Jan 25 11:01:10 1996 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw-build.in (do-binutils): Add build of stamps.
+
+Thu Jan 25 17:05:26 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config.sub: Add recognition for mips64vr4100*-* targets.
+
+Wed Jan 24 12:47:55 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * test-build.mk: Add checking of `hpux9' rather than just `hpux'.
+ Add creation of gconfigargs with `--enable-shared' turned on.
+ ($(host)-stamp-stage2-configured): Pass $(gconfigargs).
+ ($(host)-stamp-stage3-configured): Likewise.
+ (HOLES): Add chatr and ldd.
+ (i386-ncr-sysv4.3*): Add use of /usr/ccs/bin in the PATH and HOLE_DIRS.
+
+Wed Jan 24 20:32:30 1996 Torbjorn Granlund <tege@noisy.matematik.su.se>
+
+ * configure: Pass --nfp to recursive configures.
+
+Mon Jan 22 10:41:56 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in (DLLTOOL): New.
+ (DLLTOOL_FOR_TARGET): New.
+ (EXTRA_HOST_FLAGS): Pass down DLLTOOL.
+ (EXTRA_TARGET_FLAGS): Ditto.
+ (EXTRA_GCC_FLAGS): Ditto.
+ (CONFIGURE_TARGET_MODULES): Ditto.
+ (DO_X): Ditto.
+ * configure: Add DLLTOOL.
+
+Fri Jan 19 13:30:15 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ SCO OpenServer 5 changes from Robert Lipe <robertl@dgii.com>:
+ * configure.in (i[345]86-*-sco3.2v5*): Use mh-sysv instead of
+ mh-sco, since old workarounds no longer needed, and don't
+ build ld, since libraries have weak symbols in COFF.
+
+Sun Jan 14 23:01:31 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (CONFIGURE_TARGET_MODULES): Add missing ';'.
+
+Fri Jan 12 15:25:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Make sure that ${CC} can be used to compile an
+ executable.
+
+Wed Jan 3 17:54:41 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (newlib.tar.gz): Delete building of newlib's info files.
+
+Mon Jan 1 19:09:14 1996 Brendan Kehoe <brendan@rtl.cygnus.com>
+
+ * configure.in (noconfigdirs): Put ld or gas in this early, if the
+ user specifically used --with-gnu-ld=no or --with-gnu-as=no.
+
+Sat Dec 30 16:08:57 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config-ml.in: Add support for
+ --disable-{softfloat,m68881,m68000,m68020} on m68*-*-*.
+ Simplify setting of multidirs from --disable-foo.
+
+Fri Dec 29 07:56:11 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (EXTRA_GCC_FLAGS): If any of the make variables
+ LANGUAGES, BOOT_CFLAGS, STMP_FIXPROTO, LIMITS_H_TEST,
+ LIBGCC1_TEST, LIBGCC2_CFLAGS, LIBGCC2_INCLUDES, and ENQUIRE are
+ non-empty, pass them on to the GCC make.
+ (all-bootstrap): New rule that is like all-gcc, except it executes
+ the GCC bootstrap rule instead of the GCC all rule.
+
+Wed Dec 27 15:51:48 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config-ml.in (ml_realsrcdir): New, to account for ${subdir}.
+
+Tue Dec 26 11:45:31 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.guess (AViiON:dgux:*:*): Update from FSF to add pentium
+ DG/UX support.
+
+Fri Dec 15 10:01:27 1995 Stan Cox <coxs@dg-rtp.dg.com>
+
+ * config.sub (i*86*) Change [345] to [3456]
+
+Wed Dec 20 17:41:40 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in (noconfigdirs): Add gas or ld if --with-gnu-as=no or
+ --with-gnu-ld=no.
+
+Wed Dec 20 15:15:35 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config-ml.in (rs6000*, powerpc*): Add switches to control which
+ AIX multilibs get built.
+
+Mon Dec 18 17:55:46 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (i386-win32): Don't build expect if we're not
+ building the tcl subdir.
+
+Mon Dec 18 11:47:19 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in: (configure-target-examples, all-target-examples):
+ New targets, configure and build example programs.
+
+Fri Dec 15 16:13:03 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: If an mpw-config.in generated a file mk.sed,
+ use it as input to sedit the generated MPW makefile.
+ * mpw-README: Add a suggestion about Gestalt.h.
+
+Wed Dec 13 16:43:51 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Accept *-*-ieee*.
+
+Tue Dec 12 11:52:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (local-distclean): Remove $(TARGET_SUBDIR). From
+ Ronald F. Guilmette <rfg@monkeys.com>.
+
+Mon Dec 11 15:31:58 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (host==powerpc-pe): Add many directories to noconfigdirs
+ for powerpc-pe native.
+ (target==i386-win32): add tcl, make to noconfigdirs if canadian cross.
+ (target==powerpc-pe): duplicate i386-win32 entry.
+
+Sat Dec 9 14:58:28 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * configure.in (noconfigdirs): Exclude target-newlib for all versions
+ of vxworks, not just vxworks5.1.
+
+Mon Dec 4 12:05:40 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Add support for exec-prefix.
+
+Mon Dec 4 10:22:50 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config.guess: Recognize HP model 816 machines as having
+ a PA1.1 processor.
+
+Mon Dec 4 12:38:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Ignore new autoconf configure options.
+
+Thu Nov 30 14:45:25 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/mt-v810 (CC_FOR_TARGET): Add -ansi flag. NEC compiler
+ defaults to K&R mode, but doesn't have varargs.h, so we have to
+ compile in ANSI mode.
+
+Thu Nov 30 16:57:33 1995 Per Bothner <bothner@wombat.gnu.ai.mit.edu>
+
+ * config.guess: Recognize Pentium under SCO.
+ From Robert Lipe <robertl@arnet.com>.
+
+Wed Nov 29 13:49:08 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (noconfigdirs): Disable target-libio on v810-*-*.
+ * config/mt-v810 (CC_FOR_TARGET, AS_FOR_TARGET, AR_FOR_TARGET,
+ RANLIB_FOR_TARGET): Set as appropriate for NEC v810 toolchain.
+
+Wed Nov 29 12:12:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't configure gas for alpha-dec-osf*.
+
+Tue Nov 28 17:16:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Default to --with-stabs for some targets for which
+ it makes sense: mips*-*-*, alpha*-*-osf*, i[345]86*-*-sysv4* and
+ i[345]86*-*-unixware*.
+
+Mon Nov 27 13:44:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config-ml.in: Get list of multidirs using gcc --print-multi-lib
+ rather than basing it on the target. Simplify handling of options
+ controlling which directories to configure. Remove extraneous
+ slash in multi-clean target.
+
+Fri Nov 24 17:29:29 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * config-ml.in: Prefix more variables with ml_ so they don't collide
+ with configure's.
+
+Wed Nov 22 11:27:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Don't turn -v into --v.
+
+Tue Nov 21 16:48:02 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * configure.in (targargs): Fix typo.
+
+ * Makefile.in (DEVO_SUPPORT): Add symlink-tree.
+
+Tue Nov 21 14:08:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Strip --host and --target options from
+ CONFIG_ARGUMENTS, and always configure for --host only. Add
+ --with-cross-host option when building with a cross-compiler.
+ * configure: Canonicalize the arguments put into config.status by
+ always using `=' for an option with an argument. Pass a presumed
+ --host or --target explicitly.
+
+Fri Nov 17 17:50:30 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config.sub: Merge -macos*, -magic*, -pe*, and -win32 cases
+ into general OS recognition case.
+
+Fri Nov 17 17:42:25 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (target_configdirs): add target-winsup only
+ for win32 target systems.
+
+Thu Nov 16 14:04:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (all-target-libgloss): Depend upon
+ configure-target-newlib, since when libgloss is built it looks to
+ see if the newlib directory exists.
+
+Wed Nov 15 14:47:52 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (DEVO_SUPPORT): Use config-ml.in instead of
+ cfg-ml-*.in.
+
+Wed Nov 15 11:45:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Handle LD and LD_FOR_TARGET when configuring a
+ Canadian Cross.
+
+Tue Nov 14 15:03:12 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * config/mh-i386win32: add LD_FOR_TARGET.
+
+Tue Nov 14 14:56:11 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (target_libs): add target-winsup.
+ (target==i386-win32): add patch diff flex make to $noconfigdirs.
+ (target==ppcle-pe): remove ld from $noconfigdirs.
+
+Tue Nov 14 01:25:50 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (CONFIGURE_TARGET_MODULES): Pass --with-target-subdir.
+ Preserve relative path names in $srcdir. Build symlink tree if
+ configuring cross target dir and srcdir=. (= no VPATH support).
+ (configure-target-libg++): Depend on configure-target-librx.
+ * cfg-ml-com.in, cfg-ml-pos.in: Deleted.
+ * config-ml.in: New file.
+ * symlink-tree: New file.
+ * configure: Ensure srcdir="." if that's what it is.
+
+Mon Nov 13 12:34:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-README: Clarify some phrasing, add notes about CodeWarrior
+ includes and FLEX_SKELETON setting.
+ * mpw-configure (--with-gnu-ld): New option, controls whether
+ to use PPCLink or ld with PowerMac GCC.
+ * mpw-build.in (all-grez, do-grez, install-grez): New targets.
+ * mpw-config.in: Configure grez if targeting Mac.
+
+ * config.sub: Accept pmac and pmac-mpw as names for PowerMacs,
+ accept mpw and mac-mpw as names for m68k Macs, change macos7 to
+ just macos.
+ * configure.in: Configure grez resource compiler if targeting Mac.
+ * Makefile.in (all-grez, install-grez): New targets.
+
+Wed Nov 8 17:33:51 1995 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure: CXX defaults to gcc, not g++. If we find
+ gcc in the path, set CC to gcc -O2.
+
+Tue Nov 7 15:45:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Default ${build} correctly. Avoid picking up extra
+ spaces when reading CC and CXX from Makefile. When doing a
+ Canadian Cross, use plausible default values for numerous
+ variables.
+ * configure.in: When doing a Canadian Cross, don't try to
+ configure tools whose configure script can't handle it.
+
+Mon Nov 6 19:32:17 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * cfg-ml-com.in (sh-*-*): Add m2 and ml/m2 to multidirs.
+
+Sun Nov 5 00:15:41 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure: Remove dubious bug reporting address.
+
+Fri Nov 3 08:17:54 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in ($(CONFIGURE_TARGET_MODULES)): If subdir has
+ configure script, run that instead of this directory's configure.
+ In either case, print a message that we're configuring the sub-dir.
+
+Thu Nov 2 23:23:36 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in: Before checking for the existence of various files,
+ use sed to filter out "target-".
+
+Thu Nov 2 13:24:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DO_X): Split rule to decrease command line length
+ for systems with small ARG_MAX values. From phdm@info.ucl.ac.be
+ (Philippe De Muyter).
+
+Wed Nov 1 15:18:35 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in (all-patch): depend on all-libiberty.
+
+Wed Nov 1 12:23:20 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: If the only directory in target_configdirs which
+ actually exists is libiberty, then set target_configdirs to empty,
+ to avoid trying to build a target libiberty in a gas or gdb
+ distribution.
+
+Tue Oct 31 17:52:39 1995 J.T. Conklin <jtc@slave.cygnus.com>
+
+ * configure.in (host_makefile_frag): Use m68k-sun-sunos* instead
+ of m68k-sun-* when selecting mh-sun3 to avoid matching NetBSD/sun3
+ systems.
+
+Tue Oct 31 16:57:32 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * configure.in (copy_dirs): Use sys-include instead of include
+ for --with-headers option.
+
+Tue Oct 31 10:29:36 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in, configure.in: Make winsup builds work with
+ new scheme.
+
+Mon Oct 30 18:57:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Build the linker on AIX.
+
+Mon Oct 30 12:27:16 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Add $(TARGET_SUBDIR)
+ where needed.
+
+Mon Oct 30 12:45:25 1995 Doug Evans <dje@cygnus.com>
+
+ * Makefile.in (all-gcc): Fix typo.
+
+Sat Oct 28 10:27:59 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in ($(CHECK_TARGET_MODULES)): Fix typo.
+
+Fri Oct 27 23:14:12 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in: Rename libFOO to target-libFOO, and xiberty
+ to target-xiberty, to provide more flexibility.
+ (target_subdir): Define. Create if cross.
+ Set TARGET_SUBDIR in Makefile to ${target_subdir}.
+ * Makefile.in: Rename all-libFOO -> all-target-libFOO, all-xiberty
+ -> all-target-libiberty, configure-libFOO -> configure-target-libFOO,
+ check-libFOO -> check-target-libFOO, etc.
+ ($(DO_X)): Iterate over TARGET_CONFIGDIRS after SUBDIRS.
+ ($(CONFIGURE_TARGET_MODULES), $(CHECK_TARGET_MODULES),
+ $(ALL_TARGET_MODULES), $(INSTALL_TARGET_MODULES)): Update accordingly.
+ (configure-target-XXX): Depend on $(ALL_GCC), not all-gcc, to
+ allow ALL_GCC="" to only configure.
+ (DEVO_SUPPORT): Add cfg-ml-com.in and cfg-ml-pos.in.
+ (ETC_SUPPORT, ETC_SUPPORT_PFX): Merge; update 'taz' accordingly.
+ (LIBGXX_SUPPORT_DIRS): Remove xiberty.
+
+Sat Oct 28 01:53:49 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (taz): Build "info" in etc explicitly.
+
+Fri Oct 27 09:32:30 1995 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Make sure that CC is undefined (as opposed to
+ null) if toplevel/config/mh-{host} doesn't define it. Fixes a
+ problem with autoconf trying to configure on a host without GCC.
+
+Thu Oct 26 22:35:01 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Set host alias from choice of host compiler,
+ only use generic MPW Makefile sed if present, edit a file
+ named "hacked_Makefile.in" instead of "Makefile.in" if present.
+ * mpw-README: Add problem notes about CW6 and CW7.
+
+Thu Oct 26 05:45:10 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * Makefile.in (taz): Use ";" instead of ";;".
+
+Wed Oct 25 15:18:24 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (taz): Grep for '^diststuff:' or '^info:' in
+ sub-directory Makefiles, instead of using DISTSTUFFDIRS and
+ DISTDOCDIRS.
+ (DISTSTUFFDIRS, DISTDOCDIRS): Removed - no longer used.
+ (newlib.tar.gz): Don't pass DISTDOCDIRS to recursive make.
+
+Wed Oct 25 14:43:55 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (DISTDOCDIRS): Remove ld gprof bnutils gas libg++ gdb
+ and gnats, because they are now subsumed by DISTSTUFFDIRS.
+ Move bfd to DISTSTUFFDIRS.
+
+Tue Oct 24 18:19:09 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in (X11_LIB): Removed.
+ (X11_FLAGS_TO_PASS): pass only X11_EXTRA_CFLAGS and X11_EXTRA_LIBS.
+
+ * configure.in (host_makefile_frag): mh-aix & mh-sun removed.
+
+Sun Oct 22 13:04:42 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cfg-ml-com.in (powerpc*): Shorten some of the multilib directory
+ names.
+
+Fri Oct 20 18:02:10 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cfg-ml-com.in (powerpc*-eabi*): Add mcall-aixdesc varients.
+
+Thu Oct 19 10:40:57 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i[345]86-*-win32): Always build newlib.
+ Don't configure cvs, autoconf or texinfo.
+ * Makefile.in (LD_FOR_TARGET): New.
+ (BASE_FLAGS_TO_PASS, EXTRA_TARGET_FLAGS, CONFIGURE_TARGET_MODULES):
+ Pass down LD_FOR_TARGET.
+
+Wed Oct 18 15:53:56 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * winsup: New directory.
+ * Makefile.in: Build winsup.
+ * configure.in: Winsup is configured when target is win32.
+ Can only build win32 target GDB when native.
+
+Mon Oct 16 09:42:31 1995 Jeffrey A Law (law@cygnus.com)
+
+ * config.guess: Recognize HP model 819 machines as having
+ a PA 1.1 processor.
+
+Mon Oct 16 10:49:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Fix sed loop which substitutes for CC and CXX to
+ avoid bug found in various sed implementations.
+
+Wed Oct 11 16:16:20 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cfg-ml-com.in (powerpc-*-eabisim): Delete separate rule for
+ simulator. Use standard powerpc-*-eabi*.
+
+Mon Oct 9 17:21:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Stop putting gas and binutils in noconfigdirs for
+ powerpc-*-aix* and rs6000-*-*.
+
+Mon Oct 9 12:38:40 1995 Michael Meissner <meissner@cygnus.com>
+
+ * cfg-ml-com.in (powerpc*-*-eabisim*): Add support for building
+ -mcall-aixdesc libraries.
+
+Fri Oct 6 16:17:57 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config.sub (arm | armel | armeb): Fix shell syntax.
+
+Fri Oct 6 14:40:28 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cfg-ml-com.in ({powerpc,rs6000}-ibm-aix*): Add multilibs for
+ -msoft-float and -mcpu=common support.
+ (powerpc*-*-eabisim*): Add support for building -mcall-aix
+ libraries.
+
+Thu Oct 5 13:26:37 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in: Allow configuration and build of emacs19 for the alpha.
+
+Wed Oct 4 22:05:36 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (CC): Get ^CC, not just any old CC, from
+ ${host_makefile_frag}.
+
+Wed Oct 4 21:55:00 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (CC): Try to get CC from
+ ${srcdir}/${host_makefile_frag}, not ${host_makefile_frag}.
+
+Wed Oct 4 21:44:12 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in (TARGET_CONFIGDIRS): configure targetdirs
+ only if it exists in $(srcdir).
+
+Wed Oct 4 11:52:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: If CC and CXX are not set in the environment, set
+ them, based on either an existing Makefile or on searching for gcc
+ in PATH. Substitute for CC and CXX in Makefile.
+ * configure.in: Remove libm from target_libs. Separate
+ target_configdirs from configdirs. If CC is not set in
+ environment, try to get it from a host Makefile fragment. Rewrite
+ changes of configdirs to use skipdirs instead. A few minor
+ tweaks. Take directories out of target_configdirs as they are
+ taken out of configdirs. Remove existing Makefile files from
+ subdirectories. Substitute for TARGET_CONFIGDIRS and
+ CONFIG_ARGUMENTS in Makefile.
+ * Makefile.in (TARGET_CONFIGDIRS): New variable, automatically set
+ by configure.in.
+ (CONFIG_ARGUMENTS): Likewise.
+ (CONFIGURE_TARGET_MODULES): New variable.
+ ($(DO_X)): Loop over TARGET_CONFIGDIRS as well as SUBDIRS.
+ ($(CONFIGURE_TARGET_MODULES)): New target.
+ (configure-libg++, configure-libio): New targets.
+ (all-libg++): Depend upon configure-libg++.
+ (all-libio): Depend upon configure-libio.
+ (configure-libgloss, all-libgloss): New targets.
+ (configure-libstdc++): New target.
+ (all-libstdc++): Depend upon configure-libstdc++.
+ (configure-librx, all-librx): New targets.
+ (configure-newlib): New target.
+ (all-newlib): Depend upon configure-newlib
+ (configure-xiberty): New target.
+ (all-xiberty): Depend upon configure-xiberty.
+
+Sat Sep 30 04:32:59 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in (host i[345]86-*-win32): Expand the
+ noconfigdirs again.
+
+Thu Sep 28 21:18:49 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-configure: Fix sed command file name.
+
+Thu Sep 28 17:39:56 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (host i[345]86-*-win32): Reduce the
+ noconfigdirs again.
+
+Wed Sep 27 12:24:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't configure ld and gdb for powerpc*-*-winnt*
+ or powerpc*-*-pe*, since they are not yet supported.
+
+Tue Sep 26 14:30:01 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Add PowerMac support and many other enhancements.
+ * mpw-configure: New option --cc to select compiler to use,
+ paste options set according to --cc into the generated
+ Makefile, generate the Makefile by sed'ing the Unix Makefile.in
+ if mpw-make.sed is present.
+ * mpw-config.in: Don't test for gC1, test for mpw-touch,
+ add forward includes for PowerPC include files.
+ * mpw-build.in: Build using Makefile.PPC if present.
+ (do-byacc, etc): Remove separate version resource builds.
+ (do-gas): Build "stamps" before "all".
+ (do-gcc): Build "stamps-h" and "stamps-c" before "all".
+ * mpw-README: Update to reflect --cc option, PowerMac support,
+ and recently-reported compatibility problems.
+
+Fri Sep 22 12:15:42 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * cfg-ml-com.in (m68*-*-*): Only build multilibs for
+ embedded m68k systems (-aout, -coff, -elf, -vxworks).
+ (--with-multilib-top): Pass to recursive invocations.
+
+Tue Sep 19 13:51:05 1995 J.T. Conklin <jtc@blues.cygnus.com>
+
+ * configure.in (noconfigdirs): Disable libg++ and libstdc++ on
+ v810-*-*.
+
+Mon Sep 18 23:08:26 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (noconfigdirs): Disable bfd, binutils, gas, gcc,
+ gdb, ld and opcodes on v810-*-*.
+
+Sat Sep 16 18:31:08 PDT 1995 Angela Marie Thomas <angela@cygnus.com>
+
+ * config/mh-ncrsvr43: Removed AR_FLAGS
+
+Tue Sep 12 18:03:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DO_X): Change do-realclean to do-maintainer-clean.
+ (local-maintainer-clean): New target.
+ (maintainer-clean): New target.
+ (realclean): Just depend upon maintainer-clean.
+
+Fri Sep 8 17:11:14 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (noconfigdirs): Disable gdb on m68k-*-netbsd*.
+
+Fri Sep 8 16:46:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Build ld in mips*-*-bsd* case.
+
+Thu Sep 7 20:03:41 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config.sub: Accept -lites* OS. From Ian Dall.
+
+Fri Sep 1 08:06:58 1995 James G. Smith <jsmith@beauty.cygnus.com>
+
+ * config.sub: recognise mips64vr4300 and mips64vr4300el as valid
+ targets.
+
+Wed Aug 30 21:06:50 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in: treat i386-win32 canadian cross the same as
+ i386-go32 canadian cross.
+
+Thu Aug 24 14:53:20 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cfg-ml-com.in (powerpc*-*-eabisim): Add support for PowerPC
+ running under the simulator to build a reduced set of libraries.
+ (powerpc-*-eabiaix): Add fine grained multilib support added to
+ other powerpc targets yesterday.
+
+Wed Aug 23 09:41:56 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cfg-ml-com.in (powerpc*): Add support for -disable-biendian,
+ -disable-softfloat, -disable-relocatable, -disable-aix, and
+ -disable-sysv to control which multilib libraries get built.
+
+Thu Aug 17 16:03:41 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * configure: Add Makefile.tem to list of files to remove in trap
+ handler.
+
+Mon Aug 14 19:27:56 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.guess (*Linux*): Add missing "exit"s.
+ Also, need specific check for alpha-unknown-linux (uses COFF).
+
+Fri Aug 11 15:38:20 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.guess: Merge with FSF:
+
+ Wed Jun 28 17:57:27 1995 David Edelsohn <edelsohn@mhpcc.edu>
+ * config.guess (AIX4): More robust release numbering discovery.
+
+ Thu Jun 22 19:01:24 1995 Kenneth Stailey (kstailey@eagle.dol-esa.gov)
+ * config.guess (i386-sequent-ptx): Properly get version number.
+
+ Thu Jun 22 18:36:42 1995 Uwe Seimet (seimet@iris1.chemie.uni-kl.de)
+ * config.guess (mips:*:4*:UMIPS): New case.
+
+Mon Aug 7 09:21:35 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (i386-go32 host): Fix typo (deja-gnu -> dejagnu).
+ (i386-win32 host): Likewise. Don't build readline.
+
+Fri Aug 4 13:04:36 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (GDB_SUPPORT_DIRS): Add utils.
+ (DEVO_SUPPORT): Add mpw-README, mpw-build.in, mpw-config.h and
+ mpw-configure.
+
+Wed Aug 2 16:32:40 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in (appdirs): Use =, not ==, in test expression when
+ trying to build the text to print in the warning message for
+ Solaris users.
+
+Mon Jul 31 09:56:18 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * cfg-ml-com.in (z8k-*-coff): Add 'std' multilib build.
+
+Fri Jul 28 00:16:31 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config.guess: Recognize lynx-2.3.
+
+Thu Jul 27 15:47:59 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * config.sub (z8ksim): Deleted
+ (z8k-*-coff): New, this is the one true name of the target.
+
+Thu Jul 27 14:33:33 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * cfg-ml-pos.in (dotdot): Work around SunOS sed bug.
+
+Thu Jul 27 13:31:05 1995 Fred Fish (fnf@cygnus.com)
+
+ * config.guess (*:Linux:*:*): First try asking the linker what the
+ default object file format is (elf, aout, or coff). Then if this
+ fails, try previous methods.
+
+Thu Jul 27 11:28:17 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in: Don't build newlib for *-*-vxworks5.1.
+
+Thu Jul 27 11:18:47 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure.in: Don't build newlib for a29k-*-vxworks5.1.
+ * test-build.mk: Add setting of --with-headers for a29k-vxworks5.1.
+
+Tue Jul 25 21:25:39 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * cfg-ml-pos.in (MULTITOP): Trim excess trailing "/.".
+
+Fri Jul 21 10:41:12 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * cfg-ml-com.in: New file.
+ * cfg-ml-pos.in: New file.
+
+Wed Jul 19 00:37:27 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * COPYING.NEWLIB: Add HP free copyright to list.
+
+Tue Jul 18 10:58:51 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.sub: Recognize -eabi* for the system, not just -eabi.
+
+Mon Jul 3 13:44:51 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * Makfile.in (DLLTOOL_FOR_TARGET): New name, pass it down.
+ * config.sub, configure.in (win32): New target and host.
+
+Wed Jun 28 23:57:08 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in: Add i386-pe configuration.
+
+Fri Jun 23 14:28:44 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-build.in (install): Install GDB after LD.
+
+Thu Jun 22 17:10:53 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in (elf/mips.h): Always forward-include, needed
+ for GDB to build.
+
+Wed Jun 21 15:17:30 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * testsuite: New directory for customer acceptance and whole tool
+ chain tests.
+
+Wed Jun 21 16:50:29 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure: If per-host line isn't found, but AC_OUTPUT is found
+ and a configure script exists, run it instead.
+
+Thu Jun 15 21:09:24 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.guess: Update from FSF, for alpha-dec-winnt3.5 and Crays.
+
+Tue Jun 13 21:43:27 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure: Set build_{cpu,vendor,os,alias} to host values when
+ --build isn't specified.
+
+Mon Jun 5 18:26:36 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (PICFLAG, PICFLAG_FOR_TARGET): New macros.
+ (FLAGS_TO_PASS): Pass them.
+ (EXTRA_TARGET_FLAGS): Ditto.
+
+ * config/m?-*pic: Define PICFLAG* instead of LIB*FLAGS*.
+
+Wed May 31 22:27:42 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * Makefile.in (all-libg++): Depend on all-libstdc++.
+
+Thu May 25 22:40:59 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (noconfigdirs): Enable all packages for
+ i386-unknown-netbsd.
+
+Sat May 20 13:22:31 1995 Angela Marie Thomas <angela@cirdan.cygnus.com>
+
+ * configure.in (noconfigdirs): Don't configure tk for i386-go32
+ hosted builds (DOS builds)
+
+Thu May 18 18:08:49 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Changes for ARM based on patches from Richard Earnshaw:
+ * config.sub: Handle armeb and armel.
+ * configure.in: Omit arm linker only for riscix.
+
+Thu May 11 17:23:26 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.guess: Update from FSF.
+
+Tue May 9 15:52:05 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config.sub: Recognize powerpcle as the little endian varient of
+ the PowerPC. Recgonize ppc as a PowerPC variant, and ppcle as a
+ powerpcle variant. Convert pentium into i586, not i486. Add p5
+ alias for i586. Map new x86 variants p6, k5, nexgen into i586
+ temporarily.
+
+Tue May 2 16:29:41 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-lites*): Treat like hppa*-*-*elf*.
+
+Sun Apr 30 21:38:09 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config.sub: Accept -lites* as a basic system type.
+
+Thu Apr 27 11:33:29 1995 Michael Meissner (meissner@cygnus.com)
+
+ * config.guess (*:Linux:*:*): Check for whether the pre-BFD linker is
+ installed, and if so return linuxoldld as the system name.
+
+Wed Apr 26 10:59:02 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config.guess: Add hppa1.1-hp-lites support.
+
+Tue Apr 25 11:08:11 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure.in: Don't build newlib for m68k-vxworks5.1.
+
+Wed Apr 19 17:02:43 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * configure.in (mips-sgi-irix6): Use mh-irix5.
+
+Fri Apr 14 15:21:17 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * Makefile.in (all-gcc): Depend on all-ld (for libgcc1-test).
+
+Wed Apr 12 16:06:01 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * test-build.mk: Enable building of shared libraries on IRIX 5 and
+ OSF/1. Fix compiler flags.
+ * build-all.mk: Support Linux and OSF/1 3.0. Fix compiler flags.
+
+Tue Apr 11 18:55:40 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in: Recognize --with-newlib.
+ (sparc-*-sunos4*): Build sim, dejagnu, expect, tcl if cross target.
+
+Mon Apr 10 11:42:22 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Merge in support for Mac MPW as a host.
+ (Old change descriptions retained for informational value.)
+
+ * mpw-config.in: Add generic include forwards for cpu-specific
+ include files in aout and elf directories.
+
+ * mpw-configure: Added copyright.
+ * mpw-config.in: Check for presence of required build tools.
+ (target_libs): Add newlib.
+ (target_tools): Add examples.
+ (Read Me): Generate as "Read Me for MPW" instead.
+ * mpw-build.in: Base sub-builds on all-foo instead of do-foo.
+ (all-byacc, do-byacc, all-flex, do-flex, do-newlib): New actions.
+ (do-gas, do-gcc, do-gdb, do-ld): Build Version.r first.
+
+ * mpw-configure: Remove subdir-specific makefile hackery,
+ delete mk.tmp after using it.
+
+ * mpw-build.in (all): Display start and end times.
+
+ * mpw-configure (host_canonical): Set.
+ (target_cpu): Always add to makefiles.
+ (ARCHDEFS, EMUL): Add to makefile only if nonempty.
+ (TM_FILE, XM_FILE, NM_FILE): No longer add to makefile.
+ (mpw-mh-mpw): Look for in srcdir and srcroot.
+ Use sed instead of mpw-edit-prefix to edit prefix definitions.
+
+ * mpw-build.in: (install-only): New target.
+
+ * mpw-configure (host_alias, target_alias): Rename from hostalias
+ and targetalias, add into generated Makefile.
+ (mk.tmp): If present, add into generated Makefile.
+ * mpw-build.in (all-gas): Build config.h first before gas proper.
+
+ * mpw-configure (config.status): Write only if changed.
+ * mpw-config.in (readline): Configure it (not built, just used for
+ definitions).
+
+ * mpw-config.in (elf/mips.h): Add a forward include.
+
+ * mpw-config.in: Forward-include most .h files in include into
+ extra-include.
+ (readline): Don't build.
+ mpw-build.in (install): Install GDB.
+
+ * mpw-configure (prefix, mpw_prefix): Handle it.
+ * mpw-config.in (mmalloc, readline): Don't configure.
+ * mpw-build.in (thisscript): Rename to ThisScript.
+ Use mpw-build instead of BuildProgram everywhere.
+ (mmalloc, readline): Don't build.
+ * mpw-README: New file, basic documentation about the MPW port.
+
+ * mpw-config.in: Use forward-include to create include files.
+
+ * mpw-configure: Add more things to the top of each configured
+ Makefile, including contents of config/mpw-mh-mpw.
+ * mpw-config.in (extra-include): Create this directory and fill it
+ with Posix-like include files when configuring.
+
+ * config.sub (apple, mac, mpw): Add various aliases.
+
+ * mpw-build.in: New file, top-level build script fragment for MPW.
+ * mpw-configure: New file, configure script for MPW.
+ * mpw-config.in: New file, config fragment for MPW.
+
+Fri Apr 7 19:33:16 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in (host_libs): Remove glob, since it is gone from the
+ sources.
+
+Fri Mar 31 11:36:17 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Makefile.in: define empty GDB_NLM_DEPS var.
+
+ * configure.in(target_makefile_frag): use config/mt-netware
+ for netware targets.
+
+Thu Mar 30 13:51:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.sub: Merge in recent FSF changes. Remove linux special
+ cases.
+
+Tue Mar 28 14:47:34 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ build-all.mk,config/mh-solaris: revert these two changes:
+
+ Tue Mar 30 10:03:09 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * build-all.mk: Use CC=cc -Xs on Solaris.
+
+ Mon Mar 29 19:59:26 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/mh-solaris: SunPRO C needs -Xs to be able to get a
+ working xmakefile for Emacs.
+
+Tue Mar 21 10:43:32 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * glob/*: Removed. Schauer's 24 Feb 1994 readline change made us
+ stop using it.
+ * Makefile.in: Nuke all references to glob subdirectory.
+
+Thu Mar 16 13:35:30 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * configure.in: Fix --enable-shared logic in per-host.
+
+Mon Mar 13 12:33:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (*-hp-hpux[78]*): Use mh-hpux8.
+
+Mon Mar 6 10:21:58 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in (noconfigdirs): Don't build gas on AIX, for
+ powerpc*-*-aix* as well as for rs6000*-*-aix*.
+
+Wed Mar 1 12:51:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Fix --cache-file to work if the file argument is a
+ relative path.
+
+Tue Feb 28 17:36:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: If the --cache-file is used, pass it down to
+ configure in subdirectories.
+
+Mon Feb 27 12:52:46 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config.sub: add vxworks29k configuration.
+
+Fri Feb 10 16:12:26 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (taz): Do "diststuff" part quietly.
+
+Sun Feb 5 14:16:35 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.sub: Mini-merge with gcc/config.sub.
+
+Sat Feb 4 12:11:35 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config.guess (IRIX): Sed - to _.
+
+Fri Feb 3 11:54:42 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (source-vault, binary-vault): New targets.
+
+Thu Jan 26 13:00:11 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config.sub: Recognize -eabi as a basic system type.
+
+Thu Jan 12 13:13:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * configure.in (enable_shared stuff): Fix typo.
+
+Thu Jan 12 01:36:51 1995 deanm@medulla.LABS.TEK.COM (Dean Messing)
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): Fix typo in passing LIBCXXFLAGS*.
+
+Wed Jan 11 16:29:53 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (LIBCXXFLAGS_FOR_TARGET): Add -fno-implicit-templates.
+
+Mon Jan 9 12:48:01 1995 Jim Kingdon <kingdon@lioth.cygnus.com>
+
+ * configure.in (rs6000-*-*): Don't build gas.
+
+Wed Jan 4 23:53:49 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * Makefile.in: Use /x/x/ instead of /brokensed/brokensed/, to
+ reduce command line length.
+ (AS_FOR_TARGET): Check for as.new, not Makefile.
+ (NM_FOR_TARGET): Check for nm.new, not Makefile.
+
+Wed Jan 4 13:02:39 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.guess: Merge from FSF.
+
+Thu Dec 15 17:11:37 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * configure: Don't use $ when handling program_suffix.
+
+Mon Dec 12 12:09:37 1994 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Configure tk for hppa/hpux.
+
+Fri Dec 2 15:55:38 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (LIBGXX_SUPPORT_DIRS): Add libstdc++.
+
+Tue Nov 29 19:37:56 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in: Move -fno-implicit-template from CXXFLAGS
+ to LIBCXXFLAGS. Tests are better run without it.
+
+Wed Nov 23 10:29:25 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * Makefile.in (all-ispell): Depend on all-emacs19 instead of all-emacs.
+
+Mon Nov 21 11:14:01 1994 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (*-*-netware*): Don't configure xiberty.
+
+Mon Nov 14 08:49:15 1994 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Remove tk from native_only list.
+
+Fri Nov 11 15:31:26 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * build-all.mk: Add mips-ncd-elf target to sun4 targets
+ for special NCD build.
+
+Mon Nov 7 20:58:17 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (DEVO_SUPPORT): Remove configure.bat and
+ makeall.bat, they're only useful for binutils snapshots.
+ (binutils.tar.gz, gas+binutils.tar.gz): Add configure.bat and
+ makeall.bat to specified SUPPORT_FILES.
+
+Mon Nov 7 17:25:18 1994 Bill Cox (bill@cirdan.cygnus.com)
+
+ * build-all.mk: Add Ericsson targets to sun4 and solaris
+ hosts. Add BNR's sun4 target to solaris host, so their
+ build-from-source will be tested in-house first.
+
+Sat Nov 5 18:43:30 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * Makefile.in (LIBCFLAGS): New variable.
+ (CFLAGS_FOR_TARGET): Ditto.
+ (LIBCFLAGS_FOR_TARGET): Ditto.
+ (LIBCXXFLAGS): Ditto.
+ (CXXFLAGS_FOR_TARGET): Ditto.
+ (LIBCXXFLAGS_FOR_TARGET): Ditto.
+ (BASE_FLAGS_TO_PASS): Pass them.
+ (EXTRA_TARGET_FLAGS): Ditto.
+
+ * configure.in, config/m[th]-*pic: Support --enable-shared.
+
+Sat Nov 5 15:44:00 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in (target_libs): Include libstdc++ again.
+ * config.guess: Update from FSF (for FreeBSD).
+
+Thu Nov 3 16:32:30 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (DEVO_SUPPORT): Include configure.bat and
+ makeall.bat.
+ (DISTDOCDIRS): Add `etc'.
+ (ETC_SUPPORT_PFX): New variable.
+ (taz): Include anything from etc starting with a word in
+ ETC_SUPPORT_PFX.
+
+Wed Oct 26 16:19:35 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config.sub: Update for recent FSF changes. Remove obsolete
+ h8300hds entry. Add -windows* and -osx as basic os. Minor
+ spacing changes.
+
+Thu Oct 20 18:41:56 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in (target_libs): Remove libstdc++ for libg++-2.6.1.
+
+ * config.guess: Merge with FSF.
+ * configure.in: Match on i?86-ncr-sysv4.3, not i?86-ncr-sysv43.
+
+Thu Oct 20 19:26:56 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure: Since the "trap 0" handler will override the exit
+ status on many systems, only use it for "exit 1", and make it set
+ a non-zero exit status; reset it before "exit 0". Also, check
+ exit status of config.sub, and error out if it failed.
+
+Wed Oct 19 18:49:55 1994 Rob Savoye (rob@cygnus.com)
+
+ * Makefile.in: (ALL_TARGET_MODULES,INSTALL_TARGET_MODULES) Build
+ and install libgloss.
+
+Tue Oct 18 15:25:24 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (all-binutils): Depend upon all-byacc.
+
+ * configure.in: Don't build emacs on Irix 5.
+
+Mon Oct 17 16:22:12 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * configure.in (*-*-netware*): Add libio.
+
+Thu Oct 13 15:51:20 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * Makefile.in (ALL_TARGET_MODULES): Add libstdc++.
+ (CHECK_TARGET_MODULES): Ditto.
+ (INSTALL_TARGET_MODULES): Ditto.
+ (TARGET_LIBS): Ditto.
+ (all-libstdc++): Note dependencies.
+
+Thu Oct 13 01:43:08 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (BINUTILS_SUPPORT_DIRS): Add gas.
+
+Tue Oct 11 12:12:29 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * Makefile.in (CXXFLAGS): Use -fno-implicit-templates instead of
+ -fexternal-templates.
+
+ * configure.in (target_libs): Add libstdc++.
+ (noconfigdirs): Add libstdc++ as appropriate.
+
+Thu Oct 6 18:00:54 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Update from FSF.
+
+Tue Oct 4 12:05:42 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * configure: Use ${config_shell} when running ${configsub}.
+
+Mon Oct 3 14:28:34 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.sub: No longer recognize h8300h.
+
+Mon Oct 3 12:40:54 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config.sub: Remove extraneous differences between config.sub and
+ gcc/config.sub.
+
+Sat Oct 1 00:23:12 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (DISTSTUFFDIRS): Add gas.
+
+Thu Sep 22 19:04:55 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * COPYING.NEWLIB: New file.
+
+Mon Sep 19 18:25:40 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess (HP-UX): Patch from Harlan Stenn
+ <harlan@landmark.com> to also emit release level.
+
+Wed Sep 7 13:15:25 1994 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config.guess (sun4*:SunOS:*:*): Change '-JL' to '_JL'.
+
+Tue Sep 6 23:23:18 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.sub: Merge nextstep cleanup from FSF.
+
+Mon Sep 5 05:01:30 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * configure.in (arm-*-*): Don't configure ld for this target.
+
+Thu Sep 1 09:35:00 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * configure.in (*-*-netware): don't configure libg++, libio,
+ librx, or newlib.
+
+Wed Aug 31 13:52:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in (alpha-dec-osf*): Use osf*, not osf1*. Don't
+ configure ld--it works, but it doesn't support shared libraries.
+
+Sun Aug 28 18:13:45 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess (*-unknown-freebsd*): Get rid of possible
+ trailing "(Release)" in version string.
+ Patch from Paul Richards <paul@isl.cf.ac.uk>.
+
+Sat Aug 27 15:00:49 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Fix i486-ncr-sysv43 -> i486-ncr-sysv4.3.
+ Fix type: *-next-neststep -> *-next-nextstep.
+
+ * config.guess: Merge from FSF:
+
+ Fri Aug 26 18:45:25 1994 Philippe De Muyter (phdm@info.ucl.ac.be)
+
+ * config.guess: Recognize powerpc-ibm-aix3.2.5.
+
+ Wed Apr 20 06:36:32 1994 Philippe De Muyter (phdm@info.ucl.ac.be)
+
+ * config.guess: Recognize UnixWare 1.1 (UNAME_SYSTEM is SYSTEM_V
+ instead of UNIX_SV for UnixWare 1.0).
+
+Sat Aug 27 01:56:30 1994 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (all-gdb): Add dependencies on all-gcc and all-ld
+ to make gdb/nlm/* build after the compiler and linker.
+
+Fri Aug 26 14:30:05 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess (netbsd, freebsd, linux): Accept any machine,
+ not just i[34]86.
+ (m68k-atari-sysv4): Relocate to match FSF version.
+
+ * config.guess: More merges from the FSF:
+
+ Add a space before function call or macro invocation.
+
+ Tue May 10 16:53:55 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * config.guess: Add trap cmd to remove dummy.c and dummy when
+ interrupted.
+
+ Wed Apr 20 18:07:13 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * config.guess (dummy.c): Redirect stderr for `hostinfo' command.
+ (dummy): Redirect stderr from compilation of dummy.c.
+
+ Sat Apr 9 14:59:28 1994 Christian Kranz (kranz@sent5.uni-duisburg.de)
+
+ * config.guess: Distinguish between NeXTStep 2.1 and 3.x.
+
+Fri Aug 26 13:42:20 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ * configure: Accept and ignore --cache*, for compatibility with
+ new autoconf.
+
+Fri Aug 26 13:05:27 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Merge from FSF:
+
+ Thu Aug 25 20:28:51 1994 Richard Stallman <rms@mole.gnu.ai.mit.edu>
+
+ * config.guess (Pyramid*:OSx*:*:*): New case.
+ (PATH): Add /.attbin at end for finding uname.
+ (dummy.c): Handle i860-alliant-bsd. Follow whitespace conventions.
+
+ Wed Aug 17 18:21:02 1994 Tor Egge (tegge@pvv.unit.no)
+
+ * config.guess (M88*:DolphinOS:*:*): New case.
+
+ Thu Aug 11 17:00:13 1994 Stan Cox (coxs@dg-rtp.dg.com)
+
+ * config.guess (AViiON:dgux:*:*): Use TARGET_BINARY_INTERFACE
+ to select whether to use ELF or COFF.
+
+ Sun Jul 24 16:20:53 1994 Richard Stallman <rms@mole.gnu.ai.mit.edu>
+
+ * config.guess: Recognize i860-stardent-sysv and i860-unknown-sysv.
+
+ Sun May 1 10:23:10 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * config.guess: Guess the OS version for HPUX.
+
+ Tue Mar 1 21:53:03 1994 Karl Heuer (kwzh@hal.gnu.ai.mit.edu)
+
+ * config.guess (UNAME_VERSION): Recognize aix3.2.4 and aix3.2.5.
+
+Fri Aug 26 11:19:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Recognize --with-headers, --with-libs, and
+ --without-newlib.
+ * Makefile.in (all-xiberty): Depend upon all-ld.
+
+Wed Aug 24 12:36:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Change i[34]86 to i[345]86.
+
+Mon Aug 22 10:58:33 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure (version): A few more tweaks to help message.
+
+Fri Aug 19 12:40:25 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Remove (for now) librx as a host library,
+ now that we're building it for target.
+
+Fri Aug 19 10:49:17 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure: Fix up help message; from karl@owl.hq.ileaf.com
+ (Karl Berry).
+
+Tue Aug 16 16:11:08 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * configure.in: Also configure librx.
+
+Mon Aug 15 16:51:45 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Update various rules to reflect that librx
+ is now needed for libg++.
+
+Fri Aug 12 18:07:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config.sub: Accept mips64orion and mips64orionel as a CPU name.
+
+Mon Aug 8 11:36:17 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * configure.in: Configure the examples directory.
+
+Thu Aug 4 16:12:36 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure: Simplify Jun 2 1994 change.
+
+Wed Aug 3 04:58:16 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * change CC to /usr/latest/bin/gcc for lynx host builds, since
+ /bin/gcc isn't good enough to build gcc.
+
+Wed Jul 27 09:07:14 1994 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (GDB_SUPPORT_FILES): Remove
+ (setup-dirs-gdb, gdb.tar.gz, make-gdb.tar.gz): Remove old rules.
+ (gdb.tar.gz): Add new rule to use standard distribution building
+ mechanism.
+
+Mon Jul 25 11:10:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Warn about use of /usr/ucb/cc on Solaris. From
+ Bill Cox <bill@cygnus.com>.
+
+Sat Jul 23 12:19:46 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Recognize ISC. Patch from kwzh@gnu.ai.mit.edu.
+
+Fri Jul 22 17:53:59 1994 Stu Grossman (grossman@cygnus.com)
+
+ * configure: Search current dir first in .gdbinit.
+
+Fri Jul 22 11:28:30 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.sub: Recognize freebsd (merged from gcc config.sub).
+
+Thu Jul 21 14:10:52 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.sub: Refer to NeXT's operating system as nextstep.
+
+ * config.sub (case $basic_machine): Re-order the cases, to match
+ the order in the FSF version (which is mostly alphabethical).
+ Merge in some additions and changes from the FSF.
+
+Sat Jul 16 12:03:08 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config.guess: Recognize m68k-atari-sysv4 and m88k-harris-csux7.
+ * config.sub: Recognize cxux7.
+ * configure.in: Use mh-cxux for m88k-harris-cxux*.
+
+Mon Jul 11 14:37:39 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.sub: Fix typo powerpc -> powerpc-*.
+
+Sat Jul 9 13:03:43 1994 Michael Tiemann (tiemann@blues.cygnus.com)
+
+ * Makefile.in: `all-emacs19' depends on `all-byacc'.
+
+ * Makefile.in: Add all-emacs19 and install-emacs19 rules (in
+ parallel with all-emacs and install-emacs). Top-level command
+ `make all-emacs19 CC=gcc' now behaves as `make all-emacs CC=gcc'.
+
+Thu Jun 30 16:53:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * test-build.mk ($(host)-stamp-stage2-installed): Remove
+ $(relbindir)/make before doing ``make install'', and use
+ $(GNU_MAKE) while doing it. Avoids problem on SunOS with
+ installing over running make binary.
+ ($(host)-stamp-stage3-installed): Likewise.
+
+Tue Jun 28 13:43:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Recognize Mach.
+
+Mon Jun 27 16:41:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure: Check ${exec_prefixoption}, not ${exec_prefix}, to
+ see whether --exec-prefix was used.
+
+Sun Jun 26 21:15:54 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * README: Explicitly mention libg++/README. (Zoo's idea.)
+
+Tue Jun 21 12:45:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Add all-librx target similar to all-libproc.
+
+Wed Jun 8 23:11:55 1994 Stu Grossman (grossman@cygnus.com)
+
+ * config.guess: Rearrange tests for Alpha-OSF1 to properly deal
+ with post 1.2 uname bogosity.
+
+Thu Jun 9 00:27:59 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure: Remove temporary files on receipt of a signal.
+
+Tue Jun 7 12:06:24 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: If there is a package_makefile_frag, remove
+ ${subdir}/Makefile.tem after copying it in.
+
+Mon Jun 6 21:35:02 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * build_all.mk: support rs6000 lynx identifies itself as
+ rs6000-lynx-lynxos2.2.2. Also, use /usr/cygnus/progressive/bin/gcc
+ since /bin/gcc is too feeble to compile a modern gcc.
+
+Mon Jun 6 16:06:34 1994 Karen Christiansen (karen@cirdan.cygnus.com)
+
+ * brought devo/test-build.mk update-to-date with progressive/
+ test-build.mk. Add lynx targets and hppa flag info.
+
+Sat Jun 4 17:23:54 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * configure.in: Use mh-ncrsvr43. Patch from
+ Tom McConnell <tmcconne@sedona.intel.com>.
+
+Fri Jun 3 17:47:24 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess (i386-unknown-bsdi): No longer need to
+ check #if defined(__bsdi__) && defined(__i386__).
+
+Thu Jun 2 18:56:46 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure: Set program_transform_nameoption correctly.
+
+Thu Jun 2 10:57:06 1994 Karen Christiansen (karen@cirdan.cygnus.com)
+
+ * brought build-all.mk update-to-date with progressive build-all.mk,
+ added new targets and hppa info.
+
+Thu Jun 2 00:12:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure: If config.guess result is a prefix of the user
+ specified target, assume a native build and use the user specified
+ target as the host alias. Remove SunOS patch suffix removal hack.
+ * configure.in: Remove SunOS patch suffix removal hack.
+
+ * Makefile.in (CROSS_CHECK_MODULES): Remove check-flex, since it's
+ in NATIVE_CHECK_MODULES.
+
+Wed Jun 1 10:49:41 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in: Rename HOST_ONLY to NATIVE.
+ * configure: Delete SunOs patch suffix from host_canonical
+ and build_canonical variables that are prepended to Makefiles.
+ * configure.in: Add comments for easier maintenance.
+
+Tue May 31 19:39:47 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Add all-libproc target similar to all-gui.
+
+Tue May 31 17:16:33 1994 Tom Lord (lord@cygnus.com)
+
+ * Makefile.in (CHECK_MODULES): split into
+ HOST_ONLY_CHECK_MODULES and CROSS_CHECK_MODULES.
+
+Tue May 31 16:36:36 1994 Paul Eggert (eggert@twinsun.com)
+
+ * config.guess (i386-unknown-bsdi): New system to guess.
+
+Wed May 25 16:47:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Add all-gui target (but not yet build by "all").
+
+Thu May 26 08:53:19 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * config.sub: Move deletion of patch suffix from here...
+ * configure.in: To here, at Ian's suggestion. The top-
+ level scripts might need to know of a patch level.
+
+Wed May 25 09:15:54 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * config.sub: Strip off patch suffix so rtl is recognized
+ as a sunos4.1.3 machine, even though it's been patched.
+
+Fri May 20 08:25:49 1994 Steve Chamberlain (sac@deneb.cygnus.com)
+
+ * Makefile.in (INSTALL_LAST): Delete.
+ (INSTALL_DOSREL): New.
+
+Thu May 19 17:12:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Use ld for i[34]86-*-sysv4* and sparc-*-solaris2*.
+ Don't set use_gnu_ld to no for *-*-sysv4; that only controls
+ whether we pass down --with-gnu-ld anyhow.
+
+Thu May 19 09:29:12 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in (INSTALL_LAST): Change operation so it works
+ on more flavors of make.
+ * configure.in (go32): Don't build libg++ or libio.
+
+Fri May 13 13:28:34 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in (Move HOST_PREFIX_1 and friends up so
+ they can be overriden by templates.
+
+Sat May 7 16:46:44 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * configure.in (target==go32): Don't build gdb.
+ * dosrel: New directory.
+
+Fri May 6 14:19:25 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * configure.in (host==go32): Configure dosrel too.
+ * Makefile.in (INTALL_TARGET): Call INSTALL_LAST last.
+ (HOST_CC, HOST_PREFIX, HOST_PREFIX_1): Undefine, they should
+ be set by incoming names or templates.
+ (INSTALL_LAST): New rule.
+ * config/mh-go32: New fragment.
+
+Thu May 5 17:35:05 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config.sub (sparclitefrw, sparclitefrwcompat): Don't set the os.
+
+Thu May 5 20:06:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/mh-lynxrs6k: Renamed from mh-lynxosrs6k, to make it
+ unique in 8.3 naming schemes.
+ * configure.in (appdirs): New variable. Currently empty, but will
+ be used in gas distribution. If nonempty, lists a set of
+ directories at least one of which must get configured, or top
+ level configuration is considered to have failed.
+ (rs6000-*-lynxos*): Use new file name.
+
+Thu May 5 13:38:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Eliminate XTRAFLAGS.
+ * Makefile.in (CC_FOR_TARGET): If newlib exists, refer to the
+ newlib include files using -idirafter, and also use -nostdinc.
+ (CXX_FOR_TARGET): Likewise.
+ (XTRAFLAGS): Removed.
+ (BASE_FLAGS_TO_PASS): Remove XTRAFLAGS_FOR_TARGET.
+ (EXTRA_HOST_FLAGS): Remove XTRAFLAGS.
+ (EXTRA_TARGET_FLAGS, EXTRA_GCC_FLAGS): Likewise.
+ ($(DO_X)): Don't pass down XTRAFLAGS.
+
+Thu May 5 00:16:36 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * configure.in (mips*-dec-bsd*): New target; do build linker.
+ (mips*-*-bsd*): New target; don't build linker.
+
+Wed May 4 20:10:10 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * configure.in: support rs6000-*-lynxos* configuration.
+ support sunos4 as a cross target.
+
+ * config.sub: look for lynx*, not lynx since the OS version may
+ legitimately be part of the name.
+
+Tue May 3 21:48:11 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in (i[34]86-*-sco*): Move to be with other i386
+ targets.
+ (romp-*-*): New target. Skip various binary utilities.
+ (vax-*-*): New target. Don't build newlib.
+ (vax-*-vms): Renamed from *-*-vms. Don't build opcodes or newlib.
+
+Thu Apr 28 15:03:05 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.in: Only set host_makefile_frag if config
+ directory exists.
+
+Wed Apr 27 12:14:30 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * install.sh: If $dstdir exists, don't check whether each
+ component does.
+
+Tue Apr 26 18:11:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * test-build.mk (HOLES): Add sleep; used by rcs/src/conf.sh.
+
+Mon Apr 25 15:06:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * configure.in (*-*-lynxos*): Don't configure newlib for either
+ native or cross Lynx.
+
+Sat Apr 16 11:58:16 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config.sub (sparc64-elf): Fix os.
+ (z8k): Remove duplicate.
+
+Thu Apr 14 23:33:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (gcc-no-fixedincludes): Touch gcc/include/fixed, not
+ gcc/stmp-fixproto, to try to prevent fixproto from being run.
+
+Wed Apr 13 15:14:52 1994 Bill Cox (bill@cygnus.com)
+
+ * configure: Make file links cleanly even if Lynx fails on
+ an NFS symlink (at least fail cleanly).
+
+Mon Apr 11 10:58:56 1994 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * test-build.mk (CC): For mips-sgi-irix4, change -XNh1500 to
+ -XNh2000.
+
+Sat Apr 9 15:10:45 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure: Unknown options are fatal again.
+
+Fri Apr 8 12:01:41 1994 David J. Mackenzie (djm@cygnus.com)
+
+ * configure: Ignore --x-includes and --x-libraries, for Autoconf
+ compatibility.
+
+Thu Apr 7 17:31:43 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * build-all.mk: Add `clean' target.
+
+Wed Apr 6 20:44:56 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config.guess: Add SINIX support.
+ * configure.in: Add mips-*-sysv4* support.
+
+Mon Apr 4 17:41:44 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * build-all.mk: Document all useful targets.
+ If canonhost is sparc-sun-solaris2.3, change it to sparc-sun-solaris2.
+ If canonhost is mips-sgi-irix4.0.5H, change it to mips-sgi-irix4.
+
+Thu Mar 31 04:55:57 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure: Support --silent, --quiet.
+
+Wed Mar 30 21:37:38 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure: Support --disable-FEATURE.
+
+Tue Mar 29 19:15:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Recognize NCR running SVR4.3.
+
+Mon Mar 28 14:55:15 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Make BSDI generate i386-unknown-bsd386.
+ Patch from Paul Eggert <eggert@twinsun.com>.
+
+Mon Mar 28 12:54:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (powerpc-*-aix*): Treat like rs6000-*-*.
+
+Sat Mar 26 11:25:48 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure: Make unrecognized options give nonfatal warnings
+ instead of fatal errors, and pass them to any subdirectory
+ configures in case they recognize them.
+ Make --x equivalent to --with-x.
+
+Fri Mar 25 21:52:10 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure: Add --enable-* options. Clean up usage message and
+ some comments.
+
+Thu Mar 24 09:12:53 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * Makefile.in (NM_FOR_TARGET): Build tree version is now nm.new.
+
+Sun Mar 20 11:28:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-*): Enable binutils.
+
+Sat Mar 19 11:50:16 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.sub: Recognize cisco.
+
+Fri Mar 18 16:42:32 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * Makefile.in (CXXFLAGS): Add -fexternal-templates.
+
+Tue Mar 15 11:25:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: about target *-hitachi-hiuxwe2, don't print more
+ than one configuration name. Add comment.
+
+Sun Mar 6 23:13:38 1994 Hisashi MINAMINO (minamino@sra.co.jp)
+
+ * config.guess: about target *-hitachi-hiuxwe2, fixed
+ machine guessing order. [Hitachi's CPU_IS_HP_MC68K
+ macro is incorrect.]
+
+Sun Mar 13 09:10:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (TAGS): Just build TAGS in each subdirectory, rather
+ than the "make ls" stuff which used to be here.
+
+Fri Mar 11 12:52:39 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Recognize i[34]86-unknown-freebsd.
+ From Shawn M Carey <smcarey@rodan.syr.edu>.
+
+Thu Mar 3 14:24:21 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * configure.in (noconfigdirs for alpha): Remove libg++ and libio.
+
+Wed Mar 2 13:28:48 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * config.guess: Check for ptx.
+
+Mon Feb 28 16:46:50 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config.sub: Add os9k checking.
+
+Thu Feb 24 07:09:04 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config.guess: Handle OSF1 running on HPPA processors
+
+Fri Feb 18 14:14:00 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * configure: If subdir configure fails, print out a message with
+ subdirectory name, in case subdir's configure code didn't identify
+ itself.
+
+Fri Feb 18 12:50:15 1994 Doug Evans (dje@cygnus.com)
+
+ * configure.in: Remove embedded newlines from configdirs.
+ Avoid mismatches of substrings. Fix matching strings at end
+ of configdirs.
+
+Fri Feb 11 15:33:33 1994 Stu Grossman (grossman at cygnus.com)
+
+ * config.guess: Add Lynx/rs6000 config support.
+
+Tue Feb 8 13:41:09 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * configure.in (alpha-dec-osf1*, alpha*-*-*): Build gas.
+
+Mon Feb 7 15:42:36 1994 Jeffrey A. Law (law@cygnus.com)
+
+ * configure.in (hppa*-*-osf*): Treat this just like most other
+ PA configurations (eg no binutils or ld).
+ (hppa*-*-*elf*): These configurations have binutils and ld.
+
+Sun Feb 6 16:35:07 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config.sub (hiux): Fix typo. From m-kasahr@sramhc.sra.co.JP.
+
+Sat Feb 5 01:00:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (rs6000-*-*): Build gas.
+
+Wed Feb 2 13:57:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in: Avoid bug in losing hpux sed.
+
+Wed Feb 2 14:53:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in, test-build.mk: Remove MUNCH_NM; it was only needed
+ for GDB and GDB has been fixed to not need it.
+
+Mon Jan 31 18:40:55 1994 Stu Grossman (grossman at cygnus.com)
+
+ * config/mh-lynxosrs6k: Account for lack of ranlib!
+
+Sun Jan 30 17:58:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config.guess: Recognize vax hosts.
+
+Fri Jan 28 15:29:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure (while loop): Don't use "break 2" inside case
+ statement -- the case statement isn't an enclosing loop.
+
+Mon Jan 24 18:40:06 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Clean up NeXT support, to allow nextstep
+ on Intel machines. Make OS be nextstep.
+
+Sun Jan 23 18:47:22 1994 Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
+
+ * config.guess: Add alternate forms for Convex.
+
+Thu Jan 20 16:13:41 1994 Stu Grossman (grossman at cygnus.com)
+
+ * configure: Completely rewrite option processing. Take
+ advantage of pattern-matching to avoid invoking test frequently.
+ Also clean up host and target defaulting logic.
+
+Mon Jan 17 15:06:56 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in: Replace all occurrances of "rootme" with "r" and
+ "$${rootme}" with "$$r", to increase the likelihood that the do-*
+ commands (plus user environment) will fit SCO limits.
+
+Thu Jan 6 11:20:57 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Don't issue warnings about directories which are
+ not being configured if -norecursion is set. Correct test for
+ --with-gnu-as and --with-gnu-ld to not get confused by substring
+ matches.
+
+ * configure.in: Don't build gas for alpha-dec-osf1*.
+
+Tue Jan 4 17:10:19 1994 Stu Grossman (grossman at cygnus.com)
+
+ * configure: Back out Per's change of 12/19/1993. It changes the
+ behavior of configure in unexpected and confusing ways.
+
+ Also, use different delim char when calculating
+ program_transform_name so that the name can contain slashes.
+
+Sat Jan 1 13:45:31 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * configure.in, config.sub: Add support for VSTa micro-kernel.
+
+Sat Dec 25 20:00:47 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in: Nuke hacks which were used to get a special
+ version of GAS for HPPA configurations.
+
+Sun Dec 19 20:40:44 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * configure: If only ${target_alias} is given, use that
+ as the default for ${host_alias}.
+ * configure: Add missing back-slashes before nested quotes.
+
+Wed Dec 15 18:07:18 1993 david d `zoo' zuhn (zoo@andros.cygnus.com)
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): add YACC=$(BISON)
+
+Tue Dec 14 21:25:33 1993 Per Bothner (bothner@cygnus.com)
+
+ * config.guess: Recognize some Tektronix configurations.
+ From Kaveh R. Ghazi <ghazi@noc.rutgers.edu>.
+
+Sat Dec 11 11:18:00 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config.sub: Match any flavor of SH.
+
+Thu Dec 2 17:16:58 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in: Don't try to configure newlib for Alpha.
+
+Thu Dec 2 14:35:54 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Don't build ld for Irix 5. Don't build gas,
+ libg++ or libio for any Alpha target.
+
+ * configure.in (mips*-sgi-irix5*): New target; use mh-irix5.
+ * config/mh-irix5. New file for Irix 5.
+
+Wed Dec 1 17:00:33 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * Makefile.in (GZIPPROG): Renamed from GZIP, which gzip uses for
+ default arguments -- so it tried to compress itself.
+
+Tue Nov 30 13:45:15 1993 david d `zoo' zuhn (zoo@andros.cygnus.com)
+
+ * configure.in (notsupp): ensure that a space is always at the end
+ of the configdirs list, since the grep checks for an explicit space
+
+Tue Nov 16 15:04:27 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in (target i386-sysv4.2): don't build ld, since static
+ versions of many libraries are not available.
+
+Tue Nov 16 14:28:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Recognize Apollos (using environment variables).
+ * configure.in: Don't configure ld, binutils, or gprof for Apollo.
+
+Thu Nov 11 12:03:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Recognize Sony news mips running newsos.
+
+Wed Nov 10 16:57:00 1993 Mark Eichin (eichin@cygnus.com)
+
+ * Makefile.in (all-cygnus, build-cygnus): "fi else" needs to be
+ "fi ; else" for bash.
+
+Tue Nov 9 15:54:01 1993 Mark Eichin (eichin@cygnus.com)
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): pass SHELL.
+
+Fri Nov 5 08:07:27 1993 D. V. Henkel-Wallace (gumby@blues.cygnus.com)
+
+ * config.sub: accept unixware as an alias for svr4.2.
+ Fix some inconsistancies with the gcc version.
+
+Fri Nov 5 15:14:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (DISTDOCDIRS): Add gdb.
+
+Fri Nov 5 11:59:42 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (DISTDOCDIRS): Add libg++ and libio.
+
+Fri Nov 5 10:35:05 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * Makefile.in (taz): Only build "info" in DISTDOCDIRS.
+ (DISTDOCDIRS): Don't assume libg++ and gdb folks necessarily want
+ this now.
+
+Thu Nov 4 18:58:23 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.sub: Accept hiux* as an OS name.
+
+ * Makefile.in: Change RUNTEST_FLAGS back to RUNTESTFLAGS per
+ etc/make-stds.texi. The underscore came from gcc, and dje now
+ agrees that RUNTESTFLAGS is the correct name.
+
+Thu Nov 4 10:49:01 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * install.sh: Remove 'set -e'. It makes any conditionals
+ in the script useless.
+
+ * config.guess: Automatically recognize arm-acorn-riscix
+ Patch from Richard Earnshaw (rwe11@cl.cam.ac.uk).
+
+Thu Nov 04 08:08:04 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Change RUNTESTFLAGS to RUNTEST_FLAGS
+
+Wed Nov 3 22:09:46 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * Makefile.in (DISTDOCDIRS): New variable.
+ (taz): Edit local Makefile.in sooner, instead of proto-toplev
+ Makefile.in later. Build "info" and "dvi" in DISTDOCDIRS.
+
+Wed Nov 3 21:31:52 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in (hppa target): check the source directory for the
+ pagas sub-directory
+
+Wed Nov 3 11:12:22 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config.sub: Allow -aout* and -elf*.
+
+Wed Nov 3 11:08:33 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * configure.in: Don't build ld on i386-solaris2, same as for
+ sparc-solaris2.
+
+Tue Nov 2 14:21:25 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in (taz): Add texinfo/lgpl.texinfo (for libg++).
+
+Tue Nov 2 13:38:30 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in: Configure gdb for alpha.
+
+Mon Nov 1 10:42:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (CXXFLAGS): Add -O.
+
+Wed Oct 27 10:45:06 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config.guess: added support for DG Aviion
+
+Tue Oct 26 14:37:37 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * configure.in: Produce warning message for subdirectories not
+ configurable for this host/target combination. Don't try to
+ configure gdb for vms.
+
+Mon Oct 25 11:22:15 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * Makefile.in (taz): Replace "byacc" with "bison -y" in the
+ appropriate files before making "diststuff".
+ (DISTBISONFILES): New var: list of files to be edited.
+ (DISTSTUFFDIRS): Add binutils.
+
+Fri Oct 22 20:32:15 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config.sub: also handle mipsel and mips64el (for little endian mips)
+
+Fri Oct 22 07:59:20 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Add * to end of all OS names.
+
+Thu Oct 21 11:38:28 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: Build newlib for LynxOS native.
+
+Wed Oct 20 09:56:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Add support for delta 88k running SVR3.
+
+ * configure.in: Add comment about HP compiler vs. emacs.
+
+Tue Oct 19 16:02:22 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: don't build ld on solaris2 (not a viable option
+ due to bugs in getpwnam & getpwuid)
+
+Tue Oct 19 15:13:56 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * configure.in: Accept alpha-dec-osf1*, not just -osf1, since
+ config.guess will produce a full version number.
+
+Tue Oct 19 15:58:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Build linker and binutils for alpha-dec-osf1.
+
+Tue Oct 19 11:41:55 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Remove -O from CXXFLAGS for consistency with CFLAGS,
+ and gdb/testsuite/Makefile.in.
+
+Sat Oct 9 18:39:07 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: recognize mips*- instead of mips-
+
+Fri Oct 8 14:15:39 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config.sub: Accept linux*coff and linux*elf as operating
+ systems.
+
+Thu Oct 7 12:57:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config.sub: Recognize mips64, and mips3 as an alias for it.
+
+Wed Oct 6 13:54:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in: Remove alpha-dec-osf*, no longer necessary now that
+ gdb knows how to handle OSF/1 shared libraries.
+
+Tue Oct 5 11:55:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Recognize hppa*-*-hiux* (currently synonym for hpux).
+ * config.guess: Recognize Hitachi's HIUX.
+ * config.sub: Recognize h3050r* and hppahitachi.
+ Remove redundant cases for hp9k[23]*.
+
+Mon Oct 4 16:15:09 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: default to '--with-gnu-as' and '--with-gnu-ld'
+ if gas and ld are in the source tree and are in ${configdirs}.
+ If ${use_gnu_as} or ${use_gnu_ld} are 'no', then don't set the
+ the --with options (but still pass them down on the command line,
+ if they were explicitly specified).
+
+Fri Sep 24 19:11:13 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure: substitute SHELL value in Makefile.in with
+ ${CONFIG_SHELL}
+
+Thu Sep 23 18:05:13 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Build gas, ld, and binutils for *-*-sysv4* and
+ *-*-solaris2* targets.
+
+Sun Sep 19 17:01:41 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in: define M4, and pass it down to sub-makes;
+ all-autoconf now depends on all-m4
+
+Sat Sep 18 00:38:23 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in ({AR,RANLIB}_FOR_TARGET): make contingent on
+ presence of {ar,ranlib} instead of a configured directory
+
+Wed Sep 15 08:41:44 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * config.guess: Accept 34?? as well as 33?? for NCR.
+
+Mon Sep 13 12:28:43 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: grab mt-hppa for HPPA targets; use 'gas ' instead
+ of 'gas' in sed commands, since 'gash' is now in the tree as well.
+
+Fri Sep 10 11:23:52 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure: grab values for $(CC) and $(CXX) from the
+ environment, so that someone can do "CC=gcc configure; make" and
+ have it work right (matching the way that autoconf works now)
+
+ * configure.in, Makefile.in: add support for gash, the tcl
+ interface to Galaxy
+
+ * config.guess: add NetBSD variants (hp300, x86)
+
+Thu Sep 9 16:48:52 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * install.sh: Support -d option (in the manner of SunOS 4 install,
+ as it is more deterministic than that of GNU install)
+ (chmodcmd): Set file to mode 755 by default (should also do default
+ chgrp and chown, but I don't feel like dealing with that now)
+
+Tue Sep 7 11:59:39 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config.sub: Remove h8300hhms alias.
+
+Tue Aug 31 11:00:09 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Match *-*-solaris2* not *-sun-solaris2*.
+
+Mon Aug 30 18:29:10 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in (gcc-no-fixedincludes): touch stmp-fixproto as well
+ as stmp-fixinc
+
+Wed Aug 25 16:35:59 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config.sub: recognize m88110-bug-coff.
+
+Tue Aug 24 10:23:24 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in (all-libio): all dependencies on the toolchain used
+ to build this (gcc, gas, ld, etc)
+
+Fri Aug 20 17:24:24 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Deal with OSF/1 1.3 on alpha.
+
+Thu Aug 19 11:43:04 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * install.sh: add some 'else true' clauses for portability
+
+ * configure.in: don't build libio for h8[35]00-*-* targets
+
+Tue Aug 17 19:02:31 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * Makefile.in: Add support for new libio.
+
+Sun Aug 15 20:48:55 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * install.sh: If one command fails, don't try the rest. Don't try
+ to remove $dsttmp (via trap) unless we have already created it.
+ If $src doesn't exist, detect it and exit with an error.
+
+ * config.guess: Recognize BSD on hp300.
+
+Wed Aug 11 18:35:13 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * config.guess: Map (9000/[34]??:HP-UX:*:*) to m68k-hp-hpux.
+ Bug report from "Hamish (H.I.) Macdonald" <hamish@bnr.ca>.
+
+Wed Aug 11 15:37:51 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * Makefile.in (all-send-pr): depends on all-prms
+
+Wed Aug 11 16:56:03 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Fix typo (9000/8??:4.3bsd -> 9000/7??:4.3bsd).
+
+Fri Aug 6 14:45:02 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config.guess: From michael@mercury.cs.mun.ca (Michael Rendell):
+ Added test for mips-mips-riscos5.
+
+Thu Aug 5 15:45:08 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: use mh-hp300 for 68k HP hosts
+
+Mon Aug 2 11:56:53 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure: add support for CONFIG_SHELL, so that you can use
+ some alternate shell for evaluating configure scripts
+
+Sun Aug 1 11:36:27 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * Makefile.in (make-gdb.tar.gz): Sed bug reporting address
+ in configure script to bug-gdb@prep.ai.mit.edu when building
+ distribution archive.
+ * Makefile.in (COMPRESS): Remove def.
+ * Makefile.in (gdb.tar.gz, make-gdb.tar.gz): Renamed from
+ gdb.tar.Z and make-gdb.tar.Z respectively.
+ * Makefile.in (make-gdb.tar.gz): Now only build gzip'd archive.
+ * Makefile.in (make-gdb.tar.gz): Minor changes to move closer
+ to convergence with 'taz' target in Makefile.in.
+
+Fri Jul 30 12:34:57 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * install.sh (dsttmp): use trap to ensure that tmp files go
+ away on error conditions
+
+Wed Jul 28 11:57:36 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in (BASE_FLAGS_TO_PASS): remove LOADLIBES
+
+Tue Jul 27 12:43:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (install-dirs): Deal with a prefix like /gnu;
+ its parent is '/' not ''.
+
+ * Makefile.in (DEVO_SUPPORT): Add comments about ChangeLog.
+
+Fri Jul 23 09:53:37 1993 Jason Merrill (jason@wahini.cygnus.com)
+
+ * configure: if ${newsrcdir}/configure doesn't exist, don't assume
+ that ${newsrcdir}/configure.in does.
+
+Tue Jul 20 11:28:50 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * test-build.mk: support for CONFIG_SHELL
+
+Mon Jul 19 21:54:46 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * config.sub (netware): Add as a basic system type.
+
+Wed Jul 14 12:03:11 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (Makefile): depend on configure.in. Also drop the
+ $(srcdir)/ from the dependency on Makefile.in.
+
+Tue Jul 13 20:10:58 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config.sub: Recognize h8300hhms as h8300h-hitachi-hms.
+ (h8300hhms is temporary until multi-libraries are implemented).
+ * configure.in: Handle h8300h too.
+
+Sun Jul 11 17:35:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Recognize dpx/2 as m68k-bull-sysv3.
+
+Thu Jul 8 18:26:12 1993 John Gilmore (gnu@cygnus.com)
+
+ * configure: Remove extraneous output when guessing host type.
+ * config.guess: Remove extraneous output when guessing using C
+ compiler rather than uname, or when guessing fails.
+
+Wed Jul 7 17:58:14 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in: remove all.cross and install.cross targets
+
+ * configure: remove CROSS=-DCROSS_COMPILE and ALL=all.cross
+ definitions
+
+Tue Jul 6 10:39:44 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * configure.in (target sh): Build gprof.
+
+Thu Jul 1 16:52:56 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config.sub: change -solaris to -solaris2
+
+Thu Jul 1 15:46:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Use config/mh-riscos for mips-*-sysv*.
+
+Wed Jun 30 09:31:58 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: Correct error message for missing Makefile.in to
+ print correct directory.
+
+Tue Jun 29 13:52:16 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * install.sh: kludge around 386BSD shell bug
+
+Tue Jun 29 13:06:49 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config.guess: Recognize NeXT.
+ * config.guess: Recognize i486-ncr-sysv4.
+ * Makefile.in (taz): rm $(TOOL)-$$VER before linking.
+
+Tue Jun 29 12:50:57 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (MAKEINFOFLAGS): New variable.
+ (FLAGS_TO_PASS): Pass MAKEINFO as MAKEINFO MAKEINFOFLAGS.
+ * build-all.mk, test-build.mk: Pass down --no-split as
+ MAKEINFOFLAGS when hosted on DOS. Compile DOS hosted without -g.
+
+Thu Jun 24 13:39:11 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (DEVO_SUPPORT): Add COPYING COPYING.LIB install.sh.
+
+Wed Jun 23 12:59:21 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (libg++.tar.z): New rule.
+ * Makefile.in (taz): Replace 'configure -rm' by 'make distclean'.
+ * Makefile.in (taz): Only do a single chmod.
+
+Fri Jun 18 12:03:10 1993 david d `zoo' zuhn (zoo at majipoor.cygnus.com)
+
+ * install.sh: don't use dirname anymore (replaced with sed usage)
+
+Thu Jun 17 18:43:42 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in: Change extension for gzip'd files from '.z' to
+ '.gz' per new FSF standard usage.
+
+Thu Jun 17 16:58:50 1993 david d `zoo' zuhn (zoo at majipoor.cygnus.com)
+
+ * configure: put quotes around the final value of program_transform_name
+
+Tue Jun 15 16:48:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: new install.sh support; update install-info rules
+
+Wed Jun 9 12:31:34 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Build diff for crosses, but not for go32 host.
+
+ * configure.in: Build gprof only for native, and don't build it
+ for mips-*-*, rs6000-*-*, or i[34]86-*-sco*.
+
+Mon Jun 7 13:12:11 1993 david d `zoo' zuhn (zoo at deneb.cygnus.com)
+
+ * configure.in: don't build gas,ld,binutils on for *-*-sysv4
+
+Mon Jun 7 11:40:11 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * configure.in (host_tools): Add prms.
+
+Fri Jun 4 13:30:42 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: install gcc, do installation of $(INSTALL_MODULES)
+ with $(FLAGS_TO_PASS) on the command line
+
+ * config.sub: Recognize lynx and lynxos
+
+Fri Jun 4 10:59:56 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config.sub: Accept -ecoff*, not just -ecoff.
+
+Thu Jun 3 17:38:54 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (taz): Use .gz suffix instead of .z.
+ (binutils.tar.gz, gas+binutils.tar.gz, gas.tar.gz): Fixed target
+ names.
+
+Thu Jun 3 00:27:06 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in (vault-install): add an 'else true' (for Ultrix)
+
+Wed Jun 2 18:19:16 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in (install-no-fixedincludes): install gcc last, so
+ that rebuilds that might happen during 'make install' don't get
+ bogus gcc include files
+
+Wed Jun 2 16:14:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Change from Utah for HPPA support:
+ * config.guess: Recognize hppa1.x-hp-bsd.
+
+Wed Jun 2 11:53:33 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config.guess: Add support for Motorola Delta 68k, up to r3v7.
+ Patch from pot@fly.cnuce.cnr.it (Francesco Potorti`).
+
+Tue Jun 1 17:48:42 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * config.sub: Add support for rom68k and bug boot monitors.
+
+Mon May 31 09:36:37 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in: Make all-opcodes depend on all-bfd.
+
+Thu May 27 08:05:31 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config.guess: Added special check for i[34]86-univel-sysv4*.
+
+Wed May 26 16:33:40 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config.guess: For i[34]86-unknown-sysv4 use UNAME_MACHINE for
+ the processor rather than assuming i486.
+
+Wed May 26 09:40:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.guess: Recognize SunOS6 as Solaris3.
+
+Tue May 25 23:03:11 1993 Per Bothner (bothner@cygnus.com)
+
+ * config.guess: Fix typo. Avoid #elif (not in K&R 1).
+ Recognize SunOS 5.* only (and not [6-9].*) as being Solaris2.
+
+Tue May 25 12:44:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * build-all.mk (all-cross): New target for Canadian Cross.
+ Added Q2 go32 targets.
+ * test-build.mk: Configure go32 cross sparclite-aout and
+ mips-idt-ecoff -with-gnu-ld. Moved build binary directory from
+ PARTIAL_HOLE_DIRS to BUILD_HOLES_DIRS.
+
+Mon May 24 15:30:06 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: fix Alpha GDB typo; also, don't build DejaGnu for
+ GO32 hosted toolchains
+
+Mon May 24 14:18:41 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * configure: change so "-exec-prefix" gets passed down rather
+ than "-exec_prefix" so autoconf generated Makefiles get the
+ exec_prefix set right.
+
+Fri May 21 10:42:25 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config.guess: get the Solaris2 minor version number
+
+ * Makefile.in: add standards.texi and make-stds.texi to ETC_SUPPORT
+
+Fri May 21 06:20:52 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * config.guess: Recognize some Sequent platforms.
+
+Thu May 20 14:33:48 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added the vault-install target
+
+ * configure.in: actually use the Sun3 makefile fragment that's in
+ config, also added the release dir to configdirs
+
+Thu May 20 14:19:18 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (taz): Fix modes on stuff in $(TOOL) dir also.
+
+Tue May 18 20:26:41 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: remove some program from Alpha targetted toolchains
+
+Tue May 18 15:23:19 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (DISTSTUFFDIRS): Renamed from PROTODIRS. Add ld and
+ gprof.
+ (taz): Run "make diststuff" in those directories instead of "make
+ proto-dir". Look for "VERSION=" only at start of line in subdir
+ Makefile. Use "gzip -9" for compression.
+ (TEXINFO_SUPPORT, DIST_SUPPORT, BINUTILS_SUPPORT_DIRS): New vars.
+ (binutils.tar.z): New target.
+
+Mon May 17 17:01:15 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in (taz): Include gpl.texinfo.
+
+Fri May 14 06:48:38 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in (setup-dirs): Merged into "taz" target.
+ (taz): Only do `proto-dir' stuff if a directory is actually needed
+ for this target.
+
+Wed May 12 13:09:44 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (MUNCH_NM): New variable, defined to be $(NM).
+ (FLAGS_TO_PASS): Pass down MUNCH_NM.
+ (HOST_CC, HOST_PREFIX, HOST_PREFIX_1): New variables.
+ (EXTRA_GCC_FLAGS): Pass down HOST_* variables.
+ (gcc-no-fixedincludes): Correct for current gcc Makefile.
+
+Tue May 11 10:14:25 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (make-gdb.tar.Z): Add configure, config.guess,
+ config.sub, and move-if-change to gdb testsuite distribution
+ archive, so the testsuite can be extracted, configured, and
+ run separately from the gdb distribution. Blow away the Chill
+ tests that require a Chill compiled executable, since GNU Chill
+ is not yet publically available.
+
+Mon May 10 17:22:26 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * test-build.mk: set environment variables in a single command,
+ instead of a list of assignments and exports
+
+ * config.guess: recognize Alpha/OSF1 systems
+
+Mon May 10 14:55:51 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * configure: Change help message to prefer --options rather than
+ -options.
+
+Mon May 10 05:58:35 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config.sub: Convergent Tech. "miniframe" uses m68010, sez
+ zippy@ecst.csuchico.edu.
+ * config.guess: Recognize miniframe.
+
+Sun May 9 17:47:57 1993 Rob Savoye (rob at darkstar.cygnus.com)
+
+ * Makefile.in: Use srcroot to find runtest rather than rootme.
+ Pass RUNTESTFLAGS and EXPECT down in BASE_FLAGS_TO_PASS.
+
+Fri May 7 14:55:59 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * test-build.mk: Extensive additions to support building on a
+ machine other than the host.
+
+Wed May 5 08:35:04 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * configure (tooldir): Fix for i386-aix again.
+
+Mon May 3 19:00:27 1993 Per Bothner (bothner@cygnus.com)
+
+ * configure, Makefile.in: Change definition of $(tooldir)
+ to match the FSF.
+
+Fri Apr 30 15:55:21 1993 Fred Fish (fnf@cygnus.com)
+
+ * config.guess: Recognize i[34]86/SVR4.
+
+Fri Apr 30 15:52:46 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * Makefile.in (all-gdb): gdb depends on sim.
+
+Thu Apr 29 23:30:48 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (gdb.tar.Z): Make prototype gdb testsuite directory
+ at the same time we make the prototype gdb directory.
+ * Makefile.in (make-gdb.tar.Z): Make the testsuite distribution
+ files at the same time as the gdb base release distribution.
+
+Thu Apr 29 12:50:37 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (check): Use individual check targets rather than
+ DO_X rule.
+ (check-gcc): Added.
+
+Thu Apr 29 09:50:07 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * config.sub: Use sysv3.2 not sysv32 for canonical OS
+ for System V release 3.2.
+
+Thu Apr 29 10:33:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config.sub: Recognize hppaosf.
+ * configure.in: Do configure ld/binutils/gas for it.
+
+Tue Apr 27 06:25:34 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * configure (tooldir): Alter syntax used to set this, for systems
+ where "\$" isn't handled right, like i386-aix.
+
+Thu Apr 22 08:17:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: Pass program-transform-name, not
+ program_transform_name, to recursive configures.
+
+Thu Apr 22 02:58:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (gas+binutils.tar.z): New rule for building snapshots
+ of gas+ld+binutils.
+
+Mon Apr 19 17:41:30 1993 Per Bothner (bothner@cygnus.com)
+
+ * config.guess: Recognize AIX3.2 as distinct from 3.1.
+
+Sat Apr 17 17:19:50 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: rename m88k-motorola-m88kbcs to m88k-motorola-sysv
+
+ * config/mh-delta88: remove extraneous GCC references
+
+Tue Apr 13 16:52:16 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * Makefile.in (PRMS): Set back to all-prms.
+
+Sat Apr 10 12:04:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * test-build.mk: Pass -with-gnu-as for known MIPS native and MIPS
+ targets, rather than for MIPS hosts.
+
+Fri Apr 9 13:51:06 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: add comment for --with-x default values
+
+ * config.guess: handle Motorola Delta88 box for SVR3 and SVR4.
+
+ * Makefile.in: add check-* targets for each of the directories in
+ the tree. Add a definition of RUNTEST that will use the one we
+ just built, if it exists. Pass this down via FLAGS_TO_PASS.
+
+Thu Apr 8 09:21:30 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Removed obsolete references to bfd_target and
+ target_makefile_frag.
+
+ * build-all.mk: Set assorted targets for Q2.
+ * config.sub: Recognize z8k-sim and h8300-hms.
+ * test-build.mk: Really don't pass host to configure.
+ (HOLES): Added uname.
+
+Wed Apr 7 15:48:19 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: Handle an empty program-prefix, program-suffix or
+ program-transform-name correctly.
+
+Tue Apr 6 13:48:41 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * build-all.mk: -G 8 no longer required for MIPS targets.
+ * test-build.mk: Don't pass host argument to configure; make it
+ guess.
+
+Tue Apr 6 10:36:53 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (gdb.tar.Z): Fix for building gzip'd distribution.
+ * Makefile.in (COMPRESS): New macro, like GZIP.
+
+Fri Apr 2 09:02:31 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * test-build.mk: Use -with-gnu-as for mips-sgi-irix4 as well.
+
+ * build-all.mk: Set GCC to gcc -O -G 8 for MIPS targets, since gcc
+ with gas currently defaults to -G 0.
+
+Thu Apr 1 08:25:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (all-flex): flex depends on byacc.
+
+ * build-all.mk: If host not specified, use config.guess. Pass TAG
+ to test-build.mk as RELEASE_TAG.
+ * test-build.mk (configargs): New variable containing arguments to
+ pass to configure. Set to -with-gnu-as on mips-dec-ultrix.
+ (FLAGS_TO_PASS): Pass down RELEASE_TAG.
+
+ * config.guess: Use /bin/uname when checking -X argument on SCO,
+ to avoid invoking GNU uname which doesn't understand -X.
+
+ * test-build.mk: Don't use /usr/unsupported/bin/as on AIX.
+
+ * configure.in: Build gas for mips-*-*.
+
+Wed Mar 31 21:20:58 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in (all.normal): insert missing backslash.
+
+Wed Mar 31 12:31:56 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * build-all.mk, config/mh-irix4: Bump -XNh value to 1500 to match
+ gcc requirements.
+
+ * Makefile.in: Complete overhaul to merge many almost identical
+ targets.
+
+Tue Mar 30 20:17:01 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (setup-dirs-gdb): Renamed from setup-dirs.
+ (gdb.tar.Z): Adjusted.
+
+ * Makefile.in (setup-dirs, taz): New targets; should be general
+ enough to adapt for gdb sometime. Build only .z file.
+ (gas.tar.z): New target.
+
+Tue Mar 30 10:03:09 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * build-all.mk: Use CC=cc -Xs on Solaris.
+
+Mon Mar 29 19:59:26 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/mh-sun3: cc needs -J to compile cp-parse.c correctly
+
+ * config/mh-solaris: SunPRO C needs -Xs to be able to get a
+ working xmakefile for Emacs.
+
+Thu Mar 25 15:14:30 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in: Incorporate changes suggested by wilson@cygnus.com
+ for handling BISON for FSF releases.
+
+Thu Mar 25 06:19:48 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * configure: Actually implement the change zoo just documented.
+
+Wed Mar 24 13:02:44 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * configure: when using config.guess, only set target_alias when
+ it's not already been set (ie, on the command line)
+
+Mon Mar 22 23:07:39 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add installcheck target, set PRMS to install-prms
+
+Sun Mar 21 16:46:12 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure: add support for package_makefile_fragment, handle the
+ case where a directory has a configure.in file but no Makefile.in
+ more gracefully (with an actual understandable error message, even);
+ add support for --without (and add this to the usage message); also
+ explicitly add a --host=${host_alias} to the command line when
+ config.guess is used
+
+Sun Mar 21 12:11:58 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * configure: Must use both --host and --target in recursive calls.
+
+Thu Mar 18 12:31:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: Change deja-gnu to dejagnu.
+
+Mon Mar 15 15:44:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (h8300-*-*, h8500-*-*): Don't build libg++.
+
+Fri Mar 12 18:30:14 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: canonicalize all instances to *-*-solaris2*,
+ also strip out a number of tools to not build for go32 host
+
+Wed Mar 10 12:08:27 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * config.guess: add GPL.
+
+ * Makefile.in, config.guess, config.sub, configure: bump
+ copyrights to 93.
+
+Wed Mar 10 07:12:48 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (do-info): Removed obsolete check for existence of
+ localenv file.
+
+ * Makefile.in (MAKEOVERRIDES): Define to be empty.
+
+Wed Mar 10 03:11:56 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: a couple of 'else true' for decstation,
+ support for TclX
+
+ * configure.in: configure tclX too; don't remove Tk on RS/6000 anymore
+
+Tue Mar 9 16:06:12 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in (setup-dirs): change invocation of make to $(MAKE).
+
+Mon Mar 8 14:52:11 1993 Ken Raeburn (raeburn@cambridge)
+
+ * config.guess: Recognize i386-ibm-aix (PS/2).
+ * configure.in: Use config/mh-aix386 file for it.
+
+Mon Mar 8 11:12:43 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (GCC_FOR_TARGET): Eliminated definition; use
+ CC_FOR_TARGET instead.
+ (BASE_FLAGS_TO_PASS): Pass GCC_FOR_TARGET=$(CC_FOR_TARGET).
+
+Wed Mar 3 16:00:28 1993 Steve Chamberlain (sac@ok.cygnus.com)
+
+ * Makefile.in: Add sim to list of directories sent with gdb
+
+Wed Mar 3 11:42:39 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in: Put back mips-dec-bsd* case.
+
+Tue Mar 2 21:15:58 1993 Fred Fish (fnf@cygnus.com)
+
+ (Ultrix 2.2 support from Michael Rendell <michael@mercury.cs.mun.ca>)
+ * configure.in (vax-*-ultrix2*): Add Ultrix 2.2 triplet.
+ * config.guess: Change 'VAX*:ULTRIX:*:*' to 'VAX*:ULTRIX*:*:*'.
+ * config/mh-vaxult2: New file.
+
+Tue Mar 2 18:11:03 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: remove no-op mips-dec-bsd* in "case $target"
+
+ * Makefile.in (dir.info): only run gen-info-dir if it exists,
+ (install-info): install dir.info only if it exists,
+ (all-expect, install-expect): pass along X11_FLAGS_TO_PASS
+
+Tue Mar 2 09:01:30 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in: For vms target, skip bfd, ld, binutils. Do build
+ gas for mips-dec-bsd.
+
+Tue Mar 2 08:35:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure (makesrcdir): If ${srcdir} is relative and not ".",
+ and ${subdir} is not ".", set makesrcdir based on ${invsubdir}.
+
+Tue Feb 23 14:18:28 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * configure.in: Added "dejagnu" to hosttools list.
+
+Mon Feb 22 23:28:38 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config.sub, configure.in, config.guess: Add support
+ for Bosx, an AIX variant from Bull.
+ Patches from F.Pierresteguy@frcl.bull.fr.
+
+Sun Feb 21 11:15:22 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * devo/dejagnu: Initial creation of devo/dejagnu.
+ Migrated dejagnu testcases and support files for testing software
+ tools to reside as subdirectories, currently called "testsuite",
+ within the directory of the software tool. Migrated all programs,
+ support libraries, etc. beloging to dejagnu proper from
+ devo/deja-gnu to devo/dejagnu. These files were moved "as is"
+ with no modifications. The changes to these files which will
+ allow them to configure, build, and execute properly will be made
+ in a future update.
+
+Fri Feb 19 20:19:39 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * Makefile.in: Change send_pr to send-pr.
+ * configure.in: Likewise.
+ * send_pr: Renamed directory to send-pr.
+
+Fri Feb 19 19:00:13 1993 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Add some extra semi-colons (needed if SHELL=bash).
+
+Fri Feb 19 00:59:33 1993 John Gilmore (gnu@cygnus.com)
+
+ * README: Update for gdb-4.8 release.
+ * Makefile.in (gdb.tar.Z): Add texinfo/tex3patch. Build
+ gdb-xxx.tar.z (gzip'd) file also.
+
+Thu Feb 18 09:16:17 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: make all-diff depend on all-libiberty
+
+Tue Feb 16 16:06:31 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * config.guess: add vax-ultrix in the spirit of mips-ultrix.
+
+Tue Feb 16 05:57:15 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in, Makefile.in: add hello, tar, gzip, recode, indent
+
+Tue Feb 16 00:58:20 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (DEVO_SUPPORT): Remove etc directory
+ (ETC_SUPPORT): Only add the files GDB wants from etc/.
+ (gdb.tar.Z): Use ETC_SUPPORT. Use byacc when building the file.
+
+Thu Feb 11 20:14:28 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: makeinfo binary is in a new location
+
+Tue Feb 9 12:42:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config.sub: Accept -ecoff as an OS.
+
+ * Makefile.in: Various changes to eliminate a level of make
+ recursion and reduce the required command line length.
+ (BASE_FLAGS_TO_PASS): New variable holding flags passed to all
+ sub-makes.
+ (EXTRA_HOST_FLAGS, EXTRA_TARGET_FLAGS, EXTRA_GCC_FLAGS): New
+ variables holding settings for specific sub-makes.
+ (FLAGS_TO_PASS, TARGET_FLAGS_TO_PASS, GCC_FLAGS_TO_PASS): Rewrote
+ in terms of BASE_FLAGS_TO_PASS.
+ (TARGET_LIBS): New variable listing directories which use
+ TARGET_FLAGS_TO_PASS.
+ (subdir_do): Eliminated.
+ (do-*): New set of targets to replace subdir_do.
+ (various): All targets which used subdir_do now depend on do-*.
+ (local-clean): Renamed from do_clean.
+ (local-distclean): New target, dependency of distclean and
+ realclean.
+ (install-info): Don't create directories. Depend on dir.info
+ rather than calling make recursively.
+ (install-dir.info): Eliminated.
+ (install-info-dirs): Create all info directories here.
+ (dir.info): Depend upon do-install-info.
+
+ * test-build.mk (HOLES): Added false.
+
+Sat Feb 6 14:05:09 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config.guess: Recognize BSDI and BSDJ (Jolitz 386bsd).
+
+Thu Feb 4 20:49:18 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in (info): remove dependency on all-texinfo. The
+ problem was really in texinfo/C, not at this level.
+
+Thu Feb 4 13:38:41 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (info): Added dependency on all-texinfo (PR 2112).
+
+Thu Feb 4 01:50:53 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (make-gdb.tar.Z): Change BISON to 'bison -y' for
+ GDB releases.
+
+Wed Feb 3 17:22:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure: Include srcdir in message about target of link not
+ being found. Don't convert `-' to `_' in `with' options being
+ passed to subdirs.
+
+Tue Feb 2 18:57:59 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: add uudecode to host_tools
+
+ * Makefile.in: added {all,install}-uudecode targets, added them to
+ the appropriate lists
+
+Tue Feb 2 11:45:53 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (all-gcc): Added dependency on all-gas.
+
+ * configure.in (mips-*-*): Build ld and binutils.
+
+Mon Feb 1 12:35:41 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * configure: check return code from mkdir, print error message and
+ exit on failure.
+
+Sat Jan 30 16:40:28 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (make-gdb.tar.Z): New location for texinfo.tex.
+
+Thu Jan 28 15:09:59 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * test-build.mk (HOLES): Added tar, cpio and uudecode.
+
+Wed Jan 27 16:50:32 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config.sub (h8500): Recognize this as a cpu type.
+
+Sat Jan 23 20:32:01 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure: source directory missing is no longer a warning
+
+ * configure.in: recognize irix[34]* instead of irix[34]
+
+ * Makefile.in: define and pass down X11_LIB
+
+ * config/mh-sco: define X11_LIB to the mess that SCO ODT requires
+
+Sat Jan 23 13:49:40 1993 Per Bothner (bothner@cygnus.com)
+
+ * guess-systype: Renamed to ...
+ * config.guess: ... by popular request.
+ * configure.in, Makefile.in: Update accordingly.
+
+Thu Jan 21 12:20:55 1993 Per Bothner (bothner@cygnus.com)
+
+ * guess-systype: Patches from John Eaton <jwe@che.utexas.edu>:
+ + Add Convex, Cray/Unicos, and Encore/Multimax support.
+ + Execute ./dummy instead of assuming . is in PATH.
+
+Tue Jan 19 17:18:06 1993 Per Bothner (bothner@cygnus.com)
+
+ * guess-systype: New shell script. Attempts to guess the
+ canonical host name of the executing host.
+ Only a few hosts are supported so far.
+ * configure: Call guess-systype if no host is specified.
+
+Tue Jan 19 08:26:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (gcc-no-fixedincludes): Made to work with current
+ gcc Makefile.
+
+
+Fri Jan 15 10:27:02 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (GCC_FLAGS_TO_PASS): New variable.
+ (all-gcc, install-gcc, subdir_do): Use it.
+
+Wed Jan 13 17:06:45 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in: Rename uninstalled gcc driver from gcc to xgcc.
+
+Wed Jan 6 20:29:16 1993 Mike Werner (mtw@rtl.cygnus.com)
+
+ * Makefile.in: Removed explicit setting of SUBDIRS. SUBDIRS is now
+ set exclusively by configure, using configure.in .
+
+Wed Jan 6 13:44:11 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * test-build.mk: set $PATH for all builds
+
+ * Makefile.in: pass TARGET_FLAGS_TO_PASS for xiberty and libm
+
+Wed Jan 6 11:02:10 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (GCC_FOR_TARGET): Supply a default that matches
+ the one used in gcc/Makefile.in, so that a null expansion doesn't
+ override the one needed to build gcc with a native cc.
+
+
+Tue Jan 5 07:55:12 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure: Accept -with arguments.
+
+Sun Jan 3 15:15:09 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * Makefile.in: added h8300sim
+
+Tue Dec 29 15:06:00 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mh-sco: Don't override BISON definition.
+
+ * build-all.mk: If canonhost is i386-unknown-sco3.2v4, change it
+ to i386-sco3.2v4. Set TARGETS and CFLAGS for i386-sco3.2v4.
+ (all-cygnus, native, build-cygnus): Make
+ $(canonhost)-stamp-3stage-done, not $(host)....
+ * test-build.mk (stamp-3stage-compared): Use tail +10c for
+ i386-sco3.2v4. Added else true to if command.
+
+Mon Dec 28 12:08:56 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config.sub: (from FSF) Sequent uses a BSD-like OS.
+
+Mon Dec 28 08:32:06 1992 Minh Tran-Le (mtranle@paris.intellicorp.com)
+
+ * configure.in (i[34]86-*-isc*): added; uses mh-sysv.
+
+Thu Dec 24 17:26:24 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: don't remove binutils from Solaris builds
+
+Thu Dec 24 14:08:38 1992 david d`zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: get rid of earlier definitions for *clean,
+ also handle the recursive info rule better
+
+Thu Dec 24 12:40:21 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (mostlyclean, distclean, realclean): Fix to
+ do more-or-less the right thing.
+
+Wed Dec 16 10:25:31 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: Add lines defining CC and CXX, and use CXX rather
+ than gcc in definitions of CXX_FOR_BUILD and CXX_FOR_TARGET.
+
+Tue Dec 15 00:34:32 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: change all $(host_cpu)-$(host_vendor)-$(host_os) to
+ $(host_canonical).
+
+ * configure.in: split the configdirs list into 4 categories (native
+ v. cross, library v. tool) and handle the cross-only and native-
+ only in more reasonable (and correct!) way.
+
+Mon Dec 14 17:04:22 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in (hppa*-*-*): Don't remove bfd and gdb from
+ configdirs anymore.
+
+Sun Dec 13 00:37:26 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: extensive cleanup:: removed all of the explicit
+ clean-* targets, collapsed many wrappers around subdir_do into
+ one, added additional targets to satisfy standards.texi, deleted
+ some old targets, some changes for consistency
+
+Fri Dec 11 20:18:02 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: handle some programs as cross-only, and others as
+ native only
+
+ * test-build.mk: handle partial holes in a more generic manner
+
+ * Makefile.in: m4 depends on libiberty
+
+Mon Dec 7 06:43:27 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/mh-sco: don't default $(CC) to gcc
+
+Thu Dec 3 21:52:11 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: add m4, textutils, fileutils, sed, shellutils,
+ time, wdiff, and find to configdirs
+
+ * Makefile.in: all, clean, and install rules for the new programs
+ added to configure.in
+
+Mon Nov 30 14:54:34 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: use mh-sun for all *-sun-* hosts
+
+ * config/mh-solaris: rework standard X location to use
+ $OPENWINHOME, if defined.
+
+ * config/mh-sun: handle X11 include locations
+
+ * config/mh-decstation: define NeedFunctionPrototypes to 0, to
+ work around dain-bramaged DECwindows include files
+
+Fri Nov 27 18:35:54 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: define flags for X11 include files and library file
+ locations, pass them down to the programs that need this info
+
+ * build-all.mk: added a 'native' target, to 3stage the native toolchain
+
+ * config/{mh-hpux,mh-solaris}: define the "standard" locations for
+ the vendor supplied X11 headers and libraries
+
+Sun Nov 22 18:59:13 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: start building libg++ for HP-UX targets
+
+Wed Nov 18 19:33:11 1992 John Gilmore (gnu@cygnus.com)
+
+ * README: Update references to files moved into etc/.
+
+Sun Nov 15 09:36:08 1992 Fred Fish (fnf@cygnus.com)
+
+ * config.sub (i386sol2, i486sol2): i[34]86-unknown-solaris2.
+ * configure.in (i[34]86-*-solaris2*): Use config/mh-sysv4.
+
+Thu Nov 12 08:50:42 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: accept dash as well as underscore in long option
+ names for FSF compatibility.
+
+Wed Nov 11 08:04:37 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config.sub: added -sco3.2v4 support from FSF.
+
+Sun Nov 8 21:14:30 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: expand the section that adds or removes
+ directories from the list of programs to build, to handle native
+ vs. cross in addition to host v. native
+
+Sat Nov 7 18:52:27 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Replace C++ in macro names with CXX.
+ This is less likely to break ...
+
+Sat Nov 7 15:16:58 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * test-build.mk: add -w to GNU_MAKE
+
+Fri Nov 6 23:10:37 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config.sub: remove 'sparc'-->'sparc-sun' default transformation,
+ add 'sparc' to list of recognized cpus. This needed to make
+ 'sparc-aout' expand to 'sparc-unknown-aout' instead of 'sparc-sun-aout'.
+ Delete some redundant ose68 variants. Recognize -wrs as an os,
+ then changes that into $CPU-wrs-vxworks.
+
+ * configure.in: remove most references to gdbtest, regularize
+ target based program removal
+
+ * test-build.mk: import from p3 tree (many fixes and changes)
+
+Fri Nov 6 20:59:00 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: added rules to handle tcl, tk, and expect
+
+ * configure.in: handle those directories if they exist
+
+Thu Nov 5 14:35:41 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config.sub: removed bogus hppabsd and hppahpux names, since
+ "hppa" is not a valid cpu (hppa1.1 or hppa1.0 are, though)
+
+Thu Oct 29 00:12:41 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: all-gcc now depends on all-binutils. all-libg++
+ depends upon all-xiberty
+
+ * Makefile.in: changes from p3, including:
+
+ Thu Oct 8 15:00:17 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (XTRAFLAGS): include newlib directories if
+ newlib/Makefile exists, rather than if host != target.
+
+ Fri Sep 25 13:41:52 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added -nostdinc to XTRAFLAGS if we are using gcc
+ from the same source tree and not building a cross-compiler. This
+ matters for the libg++ configuration if reconfiguring a tree that
+ has already been installed.
+
+ Thu Sep 10 10:35:51 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added -I for newlib/targ-include to XTRAFLAGS, to
+ pick up the machine and system specific header files.
+
+ * Makefile.in: added AS_FOR_TARGET, passed down in
+ TARGET_FLAGS_TO_PASS. Added CC_FOR_BUILD, which is intended to be
+ the C compiler to use to create programs which are run in the
+ build environment, set it to default to $(CC), and passed it down
+ in FLAGS_TO_PASS and TARGET_FLAGS_TO_PASS.
+
+ Mon Sep 7 22:34:42 1992 Ian Lance Taylor (ian@cirdan.cygnus.com)
+
+ * Makefile.in: add $(host) = $(target) tests back to *_FOR_TARGET.
+ We need them for unusual native builds, like systems without
+ ranlib.
+
+ * configure: also define $(host_canonical) and
+ $(target_canonical), which are the full, canonical names for the
+ given host and target
+
+Sun Nov 1 16:38:17 1992 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Added separate definitions for C++.
+
+Fri Oct 30 11:37:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (configdirs): Add deja-gnu.
+
+Fri Oct 23 00:39:18 1992 John Gilmore (gnu@cygnus.com)
+
+ * README: Update for configure.texi and gdb-4.7 release.
+
+Wed Oct 21 21:54:27 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in: Move "all" target to top of file.
+ Previously, first target was ".PHONY" which caused BSD4.4 make
+ to build .PHONY when make was run without arguments.
+
+Mon Oct 19 01:17:54 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in: Add COPYING.LIB to GDB releases, now that there's
+ Library-copylefted code in libiberty.
+
+Tue Oct 13 01:22:32 1992 John Gilmore (gnu@cygnus.com)
+
+ * config.sub: Replace m68kmote with plain old m68k.
+
+Fri Oct 9 03:14:24 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in: Remove space from blank line, avoid Make complaints.
+
+Thu Oct 8 18:41:45 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config.sub: Complain if no argument is given. Added support for
+ 386bsd as OS and target alias.
+
+Thu Oct 8 15:07:22 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (XTRAFLAGS): include newlib directories if
+ newlib/Makefile exists, rather than if host != target.
+
+Mon Oct 5 03:00:09 1992 Mark Eichin (eichin at tweedledumber.cygnus.com)
+
+ * config.sub: recognize sparclite-wrs-vxworks.
+
+ * Makefile.in (install-xiberty): added *-xiberty make rules (from
+ p3.) Added clean-xiberty to clean.
+
+Thu Oct 1 17:59:19 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: use *-*-* instead of nested cases for host and target
+
+Tue Sep 29 14:11:18 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added -nostdinc to XTRAFLAGS if we are using gcc
+ from the same source tree and not building a cross-compiler. This
+ matters for the libg++ configuration if reconfiguring a tree that
+ has already been installed.
+
+Sep 20 08:53:10 1992 Fred Fish (fnf@cygnus.com)
+
+ * config.sub (i486v/i486v4): Merge in from FSF version.
+
+Fri Sep 18 00:32:00 1992 Mark Eichin (eichin@cygnus.com)
+
+ * configure: only set PWD if it is already set.
+
+Thu Sep 17 23:05:53 1992 Mark Eichin (eichin@cygnus.com)
+
+ * configure: just set PWD=`pwd` at the top, since Ultrix sh
+ doesn't have unset and all success paths (and most error paths)
+ out set it anyway. (Note: should change all uses of ${PWD=`pwd`}
+ to just ${PWD} to avoid confusion.)
+
+Tue Sep 15 16:00:54 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: always set $(tooldir) to $(libdir)/$(target_alias),
+ even for a native compilation.
+
+Tue Sep 15 02:22:56 1992 John Gilmore (gnu@cygnus.com)
+
+ Changes to make the gdb.tar.Z rule work better.
+
+ * Makefile.in (GDB_SUPPORT_DIRS): Add opcodes.
+ (DEVO_SUPPORT): Add configure.texi.
+ (bfd-ilrt.tar.Z): Remove ancient rule.
+
+Thu Sep 10 10:43:19 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added -I for newlib/targ-include to XTRAFLAGS, to
+ pick up the machine and system specific header files.
+
+ * configure.in, config.sub: added new target m68010-adobe-scout,
+ with alias of adobe68k. Changed configure.in to check for
+ -scout before -sco* to avoid a false match.
+
+ * Makefile.in: added AS_FOR_TARGET, passed down in
+ TARGET_FLAGS_TO_PASS. Added CC_FOR_BUILD, which is intended to be
+ the C compiler to use to create programs which are run in the
+ build environment, set it to default to $(CC), and passed it down
+ in FLAGS_TO_PASS and TARGET_FLAGS_TO_PASS.
+
+Wed Sep 9 12:21:42 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added TARGET_FLAGS_TO_PASS, CC_FOR_TARGET,
+ AR_FOR_TARGET, RANLIB_FOR_TARGET, NM_FOR_TARGET. Pass
+ TARGET_FLAGS_TO_PASS, which defines CC, AR, RANLIB and NM as the
+ FOR_TARGET variants, to newlib and libg++.
+
+Tue Sep 8 17:28:30 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (all-gas, all-gdb): Require all-opcodes to be built
+ first.
+
+Wed Sep 2 02:50:05 1992 John Gilmore (gnu@cygnus.com)
+
+ * config.sub: Accept `elf' as an environment.
+
+Tue Sep 1 15:48:30 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * Makefile.in (all-opcodes): cd into the right directory
+
+Sun Aug 30 21:12:11 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure: added -program_transform_name option, used as
+ argument to sed when installing programs.
+ configure.texi: added documentation for -program_prefix,
+ -program_suffix and -program_transform_name.
+
+Thu Aug 27 21:59:44 1992 John Gilmore (gnu@cygnus.com)
+
+ * config.sub: Accept i486 where i386 ok.
+
+Thu Aug 27 13:04:42 1992 Brendan Kehoe (brendan@rtl.cygnus.com)
+
+ * config.sub: accept we32k
+
+Mon Aug 24 14:05:14 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config.sub, configure.in: accept OSE68000 and OSE68k.
+
+ * Makefile.in: don't create all directories for ``make install'';
+ let the subdirectories create the ones they need.
+
+Tue Aug 11 23:13:17 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * COPYING: new file, GPL v2
+
+Tue Aug 4 01:12:43 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: use the new gen-info-dir, which needs a template
+ argument (which also lives in texinfo)
+
+ * configure.texi, standards.texi: fix INFO-DIR-ENTRY
+
+Mon Aug 3 15:41:28 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/mh-solaris: removed the -xs from CFLAGS (let the people
+ with Sun's C compiler deal with it themselved)
+
+Mon Aug 3 00:34:17 1992 Fred Fish (fnf@cygnus.com)
+
+ * config.sub (ncr3000): Change i386 to i486.
+
+Thu Jul 23 00:12:17 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add install-rcs, install-grep to
+ install-no-fixedincludes, removed install-bison and install-libgcc
+
+Tue Jul 21 01:01:50 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * configure.in: grab the HPUX makefile fragment if on HPUX
+
+Mon Jul 20 11:02:09 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * Makefile.in: eradicate bison spoor (ditto libgcc).
+ configure.in: recognise m68{k,000}-ericsson-OSE.
+ es1800 is alias for m68k-ericsson-OSE
+
+Sun Jul 19 17:49:02 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: rearrange the parts that remove programs from
+ configdirs, based now on HOST==TARGET or by canonical triple.
+
+Fri Jul 17 22:52:49 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * test-build.mk: recurse explicitly with -f test-build.mk when
+ appropriate. predicate stage3 and comparison on the existence
+ of gcc. That is, if gcc isn't around, we aren't three-staging.
+ On very clean, also remove ...stamp-co. Build in-place before
+ doing other builds.
+
+Thu Jul 16 18:33:09 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * Makefile.in, configure.in: add tgas
+
+Thu Jul 16 16:05:28 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: a number of changes merged in from progressive.
+
+ * configure.in: add libm.
+
+ * .cvsignore: ignore some stuff that comes from test-build.mk.
+
+Wed Jul 8 00:01:30 1992 Stu Grossman (grossman at cygnus.com)
+
+ * config/mh-solaris: Use -xs when compiling so that Sun-C puts
+ a symbol-table into the executable.
+
+Tue Jul 7 00:24:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * config.sub: Add es1800 (m68k-ericsson-es1800).
+
+Tue Jun 30 20:24:41 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * configure: Add program_suffix (parallel to program_prefix)
+ * Makefile.in: adjust directory-creating script for losing decstation
+
+Mon Jun 22 23:43:48 1992 Per Bothner (bothner@cygnus.com)
+
+ * configure: Minor $subdir-related fixes.
+
+Mon Jun 22 18:30:26 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * configure: fix various problems with propogating
+ makefile_target_frag in subdirs.
+ * configure.in: config libgcc if its there
+
+Fri Jun 19 15:19:40 1992 Stu Grossman (grossman at cygnus.com)
+
+ * config.sub: HPPA merge.
+
+Mon Jun 15 12:31:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/mh-ncr3000 (INSTALL): Don't use /usr/ucb/install,
+ it is broken on ncr 3000's.
+
+Sun Jun 14 10:29:19 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Replace all-bison with all-byacc in all
+ dependency lines for other tools (which now use byacc).
+
+Fri Jun 12 22:21:57 1992 John Gilmore (gnu at cygnus.com)
+
+ * config.sub: Add sun4sol2 => sparc-sun-solaris2.
+
+Tue Jun 9 17:18:11 1992 Fred Fish (fnf at cygnus.com)
+
+ * config/{mh-ncr3000, mh-sysv4}: Add INSTALL.
+
+Thu Jun 4 12:07:32 1992 Mark Eichin (eichin@cygnus.com)
+
+ * Makefile.in: make gprof rules similar to byacc rules (instead of
+ vestigal $(unsubdir) that didn't work...)
+
+Thu Jun 4 00:37:05 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config.sub: Add support for Linux.
+ * Makefile.in: Use $(FLAGS_TO_PASS) more consistently
+ (at least for libg++).
+
+Tue Jun 02 20:03:00 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * configure.texi: fix doc for the -nfp option to configure
+
+Tue Jun 2 17:20:52 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * Makefile.in (all-binutils): ar needs flex, so depend on all-flex.
+
+Sun May 31 15:04:08 1992 Mark Eichin (eichin at cygnus.com)
+
+ * config.sub: changed [^-]+ to [^-][^-]* so that it works under
+ Sun sed. (BSD 4.3 sed doesn't handle [^-]+ either.)
+ * configure.in: added solaris* host_makefile_frag hook.
+
+Sun May 31 01:10:34 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config.sub: changed recognition of m68000 so that various
+ m68k types can be specified via m680[01234]0
+
+Sat May 30 21:01:06 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config.sub (basic_machine): fix sed so that '-foo' isn't
+ completely substituted out while .+'-foo' loses the '-foo'
+
+Wed May 27 23:18:52 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * config.sub ($os): Add -aout.
+
+Fri May 22 14:00:02 1992 Per Bothner (bothner@cygnus.com)
+
+ * configure: If host_makefile_frag is absolute, don't
+ prefix ${invsubdir} (relevant to libg++ auto-configure).
+
+Thu May 21 18:00:09 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * Makefile.in (tooldir): Define it.
+ (all-ld): Depend on all-flex.
+
+Sun May 10 21:45:59 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (check): Fix libg++ special case.
+
+Fri May 8 08:31:41 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure: do not bury `pwd` into config.status, thus do fewer
+ pwd's.
+
+ * configure: print the "Building in" message only when building in
+ other than "." AND verbose.
+
+ * configure: remove -s, rework -v to better accomodate guested
+ configures.
+
+ * standards.texi: updated to 3 may, fixed librid <-> libdir typo.
+
+Fri May 1 18:00:50 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: macroize flags passed on recursion. remove
+ fileutils.
+
+Thu Apr 30 08:56:20 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure: get makesrcdir right for subdirs deeper than 1.
+
+ * Makefile.in: pass INSTALL, INSTALL_DATA, INSTALL_PROGRAM on
+ install.
+
+Fri Apr 24 15:51:51 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: don't print subdir_do or recursion lines.
+
+Fri Apr 24 15:22:04 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * standards.texi: added menu item.
+
+ * Makefile.in: build and install standards.info.
+
+ * standards.texi: new file.
+
+Wed Apr 22 18:06:55 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * configure: test for and move config.status pieces from
+ ${subdir}/.
+
+Wed Apr 22 14:38:34 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/mh-delta88, config/mh-ncr3000: Replace MINUS_G with
+ CFLAGS per new configuration strategy.
+ * configure: Test for existance of files before trying to mv
+ them, to avoid numerous non-existance messages.
+
+Tue Apr 21 12:31:33 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure: correct final line of config.status.
+
+ * configure: patch from eggert. Avoids a protection problem if
+ the original Makefile.in is read only.
+
+ * configure: use move-if-change from gcc to create config.status.
+ Some makefiles depend on config.status to tell if a directory
+ has been reconfigured for a different host. This change
+ prevents those directories from remaking everything in the case
+ where the reconfig was only intended to rebuild a Makefile.
+
+ * configure: test for config.sub with "config.sub sun4" rather
+ than "config.sub ${host_alias}". Otherwise we can't tell a bad
+ host alias from a missing config.sub.
+
+Mon Apr 20 18:16:36 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: explicitly pass CFLAGS on recursion. no longer pass
+ MINUS_G (this can be done with CFLAGS). Default CFLAGS to -g.
+
+Fri Apr 17 18:27:51 1992 Per Bothner (bothner@cygnus.com)
+
+ * configure: mkdir ${subdir} as needed.
+
+Wed Apr 15 17:37:22 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in,configure.in: added autoconf.
+
+Wed Apr 15 17:27:34 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: no longer pass against on recursion.
+
+ * Makefile.in: added .NOEXPORT: so that stray makefile_frag
+ definitions are not inherited.
+
+ * configure: correct makesrcdir when subdir is .
+
+Tue Apr 14 11:56:09 1992 Per Bothner (bothner@cygnus.com)
+
+ * configure: Add support for 'subdirs' variable, which is
+ like 'configdirs', except that configure doesn't re-invoke
+ itself for subdirs, it just creates a Makefile for each subdir.
+ * configure.texi: Document subdirs.
+
+Mon Apr 13 18:50:16 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: added flex to configdirs
+
+Mon Apr 13 18:43:55 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: remove clean-stamps from clean.
+
+Sat Apr 11 03:52:03 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Add gdbtest to configdirs.
+
+Fri Apr 10 23:11:49 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (MINUS_G): Add macro, default to -g, pass on
+ to recursive makes.
+ * configure.in: Recognize new ncr3000 config.
+
+Wed Apr 8 23:08:12 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed references to gdbm.
+
+Tue Apr 7 16:48:20 1992 Per Bothner (bothner@cygnus.com)
+
+ * config.sub: Don't canonicalize os value
+ newsos* to bsd (readline needs to check for newsos).
+ (This fix was earlier made Jan 31, but got re-broken.)
+
+Mon Apr 6 14:34:08 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: sco is an os, not a vendor!
+
+ * configure: Quote $( better. Keep various shells happy.
+
+Tue Mar 31 16:32:57 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: eliminate stamp-files.
+
+Mon Mar 30 22:20:23 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: add send_pr. remove "force" from .stmp-gprof rule.
+ Supress echoing of all the "if [ -d ... $(MAKE)" lines.
+
+Wed Mar 25 15:20:04 1992 Stu Grossman (grossman@cygnus.com)
+
+ * config.sub: fix iris/iris3.
+
+Wed Mar 25 10:34:19 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure: re-add -rm.
+
+Tue Mar 24 23:50:16 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Maskefile.in: add .stmp-rcs to all.
+
+ * configure.in: remove gas from rs6000 build, use aix host fragment.
+
+Mon Mar 23 19:43:35 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure: pass down site_option during recursion.
+
+Thu Mar 19 16:49:36 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (all.cross): Add .stmp-bfd .stmp-readline.
+
+Wed Mar 18 15:29:33 1992 Mike Stump (mrs@cygnus.com)
+
+ * configure: Change exec_prefix so that it really defaults to prefix.
+
+Sat Mar 14 17:20:38 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in, configure.in: Add support for mmalloc library.
+
+Fri Mar 13 18:44:18 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: add stmp dependencies for a few more things.
+
+Thu Mar 12 04:56:24 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure: adjusted error message on objdir/srcdir configure
+ collision, per john's suggestion.
+
+ * Makefile.in: add libiberty stmp to all and all.cross.
+
+Wed Mar 11 02:07:52 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: remove force dependencies, add grep to all.
+
+Tue Mar 10 21:49:18 1992 K. Richard Pixley (rich@mars.cygnus.com)
+
+ * Makefile.in: drop flex. make stamp files work.
+
+ * configure: added test for conflicting configuration in srcdir,
+ remove trailing slashes from srcdir. Otherwise emacs gdb mode
+ gets cranky. use relative paths for configure and srcdir
+ whenever possible. Send some error messages to stderr that were
+ going to stdout.
+
+Tue Mar 10 18:01:55 1992 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Fix libg++ rule to check for gcc directory
+ before using gcc/gcc. Also pass XTRAFLAGS.
+
+Thu Mar 5 21:45:07 1992 K. Richard Pixley (rich@sendai)
+
+ * Makefile.in: added stmp-files so that directories aren't polled
+ when they are already built.
+
+ * configure.texi: fixed a node pointer problem.
+
+Thu Mar 5 12:05:58 1992 Stu Grossman (grossman at cygnus.com)
+
+ * config.sub configure.in config/mh-irix4 gdb/configure.in
+ gdb/mips-tdep.c gdb/mipsread.c gdb/procfs.c gdb/signame.h
+ gdb/tm-irix3.h gdb/tm-mips.h gdb/xm-irix4.h gdb/config/mt-irix3
+ gdb/config/mh-irix4 texinfo/configure.in: Port to SGI Irix-4.x.
+
+Wed Mar 4 02:57:46 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * configure: -recurring becomes -silent. corrected help message
+ for -site= option.
+
+ * Makefile.in: mkdir $(exec_prefix) and $(tooldir).
+
+Tue Mar 3 14:51:21 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * configure: when building Makefile for crosses, replace
+ tooldir and program_prefix. default srcdir from location of
+ config.sub. remove "for host in hosts" and "for target in
+ targets" loops.
+
+Wed Feb 26 19:48:25 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: Do not pass bindir or mandir to cvs.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+ * configure.texi: remove most references to multiple hosts,
+ multiple targets, subdirs, etc.
+
+ * configure.man: removed rcsid. reference config.sub not
+ config.subr.
+
+ * Makefile.in: mkdir $(infodir) on install-info.
+
+Wed Feb 19 15:41:13 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.texi: Explain better about .gdbinit and about
+ the environment that configure.in sections run in.
+
+Fri Feb 7 07:55:00 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Ultrix is only a decstation if it's a MIPS.
+
+Fri Jan 31 21:54:51 1992 John Gilmore (gnu at cygnus.com)
+
+ * README: DOC.configure => cfg-paper.texi.
+
+Fri Jan 31 21:48:18 1992 Stu Grossman (grossman at cygnus.com)
+
+ * config.sub (near case $os): Don't convert newsos* to bsd!
+
+Fri Jan 31 02:27:32 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Reinstall change from gdb-4.3 that reduces
+ the number of copies of COPYING that go into the GDB tar file.
+
+Thu Jan 30 16:17:30 1992 Stu Grossman (grossman at cygnus.com)
+
+ * bfd/configure.in, config/mh-sco, gdb/config/mh-i386sco,
+ gdb/config/mt-i386v32, gdb/configure.in, readline/configure.in:
+ Fix SCO configuration stuff.
+
+Tue Jan 28 23:51:07 1992 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: For libg++, make sure the -I pointing
+ to the gcc directory goes *after* all the libg++-local -I flags.
+ Also, move just-gcc dependency from just-libg++ to all-libg++.
+
+Tue Jan 28 12:56:24 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure: Change -x to -f to keep Ultrix /bin/test happy.
+
+Sat Jan 18 17:45:11 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (make-gdb.tar.Z): Remove texinfo targets.
+
+Sat Jan 18 17:03:21 1992 Fred Fish (fnf at cygnus.com)
+
+ * config.sub: Add stratus configuration frags. Also
+ submitted to FSF.
+
+Sat Jan 18 15:35:29 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (DEV_SUPPORT): add configure.man.
+
+ * config.sub(Decode manufacturer-specific): add -none*.
+
+Fri Jan 17 17:58:05 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in: remove form feeds to make Sun's make happy.
+ (DEVO_SUPPORT): DOC.configure => cfg-paper.texi.
+
+Sat Jan 4 16:11:44 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (AR_FLAGS): Make quieter.
+
+Thu Jan 2 22:57:12 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Add libg++.
+ * configure: When verbose, don't output the command line at each
+ level; it will be unremarkably the same as the previous version,
+ which will be the same as what the user typed.
+
+Fri Dec 27 16:26:47 1991 K. Richard Pixley (rich at cygnus.com)
+
+ * configure.in, Makefile.in: fix clean-info, add flex. add
+ fileutils.
+
+ * configure: be less sensitive to spaces in Makefile.in. Do not
+ look for sources in "..". Doing so breaks subdirectories that
+ might have their own configure. If a subdir has it's own
+ configure script, use it.
+
+Thu Dec 26 16:30:26 1991 K. Richard Pixley (rich at cygnus.com)
+
+ * cfg-paper.texi: some changes suggested by rms.
+
+Thu Dec 26 10:13:36 1991 Fred Fish (fnf at cygnus.com)
+
+ * config.sub: Merge in some small additions from the FSF version,
+ taken from the gcc distribution, to bring the Cygnus and FSF
+ versions into closer sync.
+
+Fri Dec 20 11:34:18 1991 Fred Fish (fnf at cygnus.com)
+
+ * configure.in: Changed svr4 references to sysv4.
+
+Thu Dec 19 15:54:29 1991 K. Richard Pixley (rich at cygnus.com)
+
+ * configure: added -V for version number option.
+
+Wed Dec 18 15:39:34 1991 K. Richard Pixley (rich at cygnus.com)
+
+ * DOC.configure, cfg-paper.texi: revised, updated, and texinfo'd.
+ renamed from DOC.configure to cfg-paper.texi.
+
+Mon Dec 16 23:05:19 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * configure, config.subr, config.sub: config.subr is now
+ config.sub again.
+
+Fri Dec 13 01:17:06 1991 K. Richard Pixley (rich at cygnus.com)
+
+ * configure.texi: new file, in progress.
+
+ * Makefile.in: build info file and install the man page for
+ configure.
+
+ * configure.man: new file, first cut.
+
+ * configure: find config.subr again now that configuration "none"
+ has gone. removed all traces of the -ansi option. removed all
+ traces of the -languages option.
+
+ * config.subr: resync from rms.
+
+Wed Dec 11 22:25:20 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * configure, config.sub, config.subr: merge config.sub into
+ config.subr, call the result config.subr, remove config.sub, use
+ config.subr.
+
+ * Makefile.in: revised install for dir.info.
+
+Tue Dec 10 00:04:35 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * configure.in: add decstation host makefile frag.
+
+ * Makefile.in: BISON now bison -y again. also install-gcc on
+ install. clean-gdbm on clean. infodir belongs in datadir.
+ Make directories for info install. Build dir.info here then
+ install it.
+
+Mon Dec 9 16:48:33 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: fix for bad directory tests.
+
+Sat Dec 7 00:17:01 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * configure: \{1,2\} appears to be a sysv'ism. Use a different
+ regexp. -srcdir relative was being handled incorrectly.
+
+ * Makefile.in: unwrapped some for loops so that parallel makes
+ work again and so one can focus one's attention on a particular
+ package.
+
+Fri Dec 6 00:22:08 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * configure: added PWD as a stand in for `pwd` (for speed). use
+ elif wherever possible. make -srcdir work without -objdir.
+ -objdir= commented out.
+
+Thu Dec 5 22:46:52 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * configure: +options become --options. -subdirs commented out.
+ added -host, -datadir. Renamed -destdir to -prefix. Comment in
+ Makefile now at top of generated Makefile. Removed cvs log
+ entries. added -srcdir. create .gdbinit only if there is one
+ in ${srcdir}.
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+Fri Nov 22 07:38:11 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Freshly created ChangeLog.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 76
+version-control: never
+End:
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 00000000000..7f1bb8c2b29
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,1821 @@
+#
+# Makefile for directory with subdirs to build.
+# Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+# Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+srcdir = .
+
+prefix = /usr/local
+exec_prefix = $(prefix)
+
+bindir=${exec_prefix}/bin
+sbindir=${exec_prefix}/sbin
+libexecdir=${exec_prefix}/libexec
+datadir=${prefix}/share
+sysconfdir=${prefix}/etc
+sharedstatedir=${prefix}/com
+localstatedir=${prefix}/var
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+oldincludedir=/usr/include
+infodir=${prefix}/info
+mandir=${prefix}/man
+gxx_include_dir=${includedir}/g++
+
+tooldir = $(exec_prefix)/$(target)
+
+program_transform_name =
+
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = $(prefix)/info
+includedir = $(prefix)/include
+# Directory in which the compiler finds executables, libraries, etc.
+libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(gcc_version)
+GDB_NLM_DEPS =
+
+SHELL = /bin/sh
+
+# INSTALL_PROGRAM_ARGS is changed by configure.in to use -x for a
+# cygwin host.
+INSTALL_PROGRAM_ARGS =
+
+INSTALL = $(SHELL) $$s/install-sh -c
+INSTALL_PROGRAM = $(INSTALL) $(INSTALL_PROGRAM_ARGS)
+INSTALL_SCRIPT = $(INSTALL)
+INSTALL_DATA = $(INSTALL) -m 644
+
+INSTALL_DOSREL = install-dosrel-fake
+
+AS = as
+AR = ar
+AR_FLAGS = rc
+CC = cc
+
+# Special variables passed down in EXTRA_GCC_FLAGS. They are defined
+# here so that they can be overridden by Makefile fragments.
+HOST_CC = $(CC_FOR_BUILD)
+HOST_PREFIX =
+HOST_PREFIX_1 = loser-
+
+# These flag values are normally overridden by the configure script.
+CFLAGS = -g
+CXXFLAGS = -g -O2
+
+LIBCFLAGS = $(CFLAGS)
+CFLAGS_FOR_TARGET = $(CFLAGS)
+LDFLAGS_FOR_TARGET =
+LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARGET)
+PICFLAG =
+PICFLAG_FOR_TARGET =
+
+CHILLFLAGS = $(CFLAGS)
+CHILL_LIB = -lchill
+CXX = c++
+
+# Use -O2 to stress test the compiler.
+LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates -fexceptions
+CXXFLAGS_FOR_TARGET = $(CXXFLAGS)
+LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates -fexceptions
+
+RANLIB = ranlib
+
+DLLTOOL = dlltool
+WINDRES = windres
+
+NM = nm
+
+LD = ld
+
+# Not plain GZIP, since gzip looks there for extra command-line options.
+GZIPPROG = gzip
+
+# These values are substituted by configure.
+DEFAULT_YACC = yacc
+DEFAULT_LEX = lex
+DEFAULT_M4 = m4
+
+BISON = `if [ -f $$r/bison/bison ] ; then \
+ echo $$r/bison/bison -L $$s/bison/ ; \
+ else \
+ echo bison ; \
+ fi`
+
+YACC = `if [ -f $$r/bison/bison ] ; then \
+ echo $$r/bison/bison -y -L $$s/bison/ ; \
+ elif [ -f $$r/byacc/byacc ] ; then \
+ echo $$r/byacc/byacc ; \
+ else \
+ echo ${DEFAULT_YACC} ; \
+ fi`
+
+LEX = `if [ -f $$r/flex/flex ] ; \
+ then echo $$r/flex/flex ; \
+ else echo ${DEFAULT_LEX} ; fi`
+
+M4 = `if [ -f $$r/m4/m4 ] ; \
+ then echo $$r/m4/m4 ; \
+ else echo ${DEFAULT_M4} ; fi`
+
+MAKEINFO = `if [ -f $$r/texinfo/makeinfo/Makefile ] ; \
+ then echo $$r/texinfo/makeinfo/makeinfo ; \
+ else echo makeinfo ; fi`
+
+# This just becomes part of the MAKEINFO definition passed down to
+# sub-makes. It lets flags be given on the command line while still
+# using the makeinfo from the object tree.
+MAKEINFOFLAGS =
+
+EXPECT = `if [ -f $$r/expect/expect ] ; \
+ then echo $$r/expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $$s/dejagnu/runtest ] ; \
+ then echo $$s/dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+
+# compilers to use to create programs which must be run in the build
+# environment.
+CC_FOR_BUILD = $(CC)
+CXX_FOR_BUILD = $(CXX)
+
+SUBDIRS = "this is set via configure, don't edit this"
+OTHERS =
+
+# This is set by the configure script to the list of directories which
+# should be built using the target tools.
+
+
+TARGET_CONFIGDIRS = libiberty libgloss $(SPECIAL_LIBS) newlib libio librx libstdc++ libg++ winsup opcodes bsp libstub cygmon
+
+# Target libraries are put under this directory:
+# Changed by configure to $(target_alias) if cross.
+TARGET_SUBDIR = .
+
+# This is set by the configure script to the arguments passed to configure.
+CONFIG_ARGUMENTS =
+
+# This is set by configure to REALLY_SET_LIB_PATH if --enable-shared
+# was used.
+SET_LIB_PATH =
+
+# This is the name of the environment variable used for the path to
+# the libraries. This may be changed by configure.in.
+RPATH_ENVVAR = LD_LIBRARY_PATH
+
+# configure.in sets SET_LIB_PATH to this if --enable-shared was used.
+REALLY_SET_LIB_PATH = \
+ if [ x"$$$(RPATH_ENVVAR)" != x ]; then \
+ $(RPATH_ENVVAR)=$$r/bfd:$$r/opcodes:$$$(RPATH_ENVVAR); \
+ else \
+ $(RPATH_ENVVAR)=$$r/bfd:$$r/opcodes; \
+ fi; \
+ export $(RPATH_ENVVAR);
+
+ALL = all.normal
+INSTALL_TARGET = installdirs \
+ install-gcc \
+ $(INSTALL_MODULES) \
+ $(INSTALL_TARGET_MODULES) \
+ $(INSTALL_X11_MODULES) \
+ $(INSTALL_DOSREL)
+
+INSTALL_TARGET_CROSS = installdirs \
+ install-gcc-cross \
+ $(INSTALL_MODULES) \
+ $(INSTALL_TARGET_MODULES) \
+ $(INSTALL_X11_MODULES) \
+ $(INSTALL_DOSREL)
+
+CC_FOR_TARGET = ` \
+ if [ -f $$r/gcc/xgcc ] ; then \
+ if [ -f $$r/$(TARGET_SUBDIR)/newlib/Makefile ] ; then \
+ case "$(target_canonical)" in \
+ i[3456]86-*-cygwin*) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -B$$r/$(TARGET_SUBDIR)/newlib/ -L$$r/$(TARGET_SUBDIR)/winsup -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/winsup/include -idirafter $$s/newlib/libc/include -idirafter $$s/newlib/libc/sys/cygwin -idirafter $$s/newlib/libc/sys/cygwin32 -nostdinc; \
+ ;; \
+ *) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/newlib/libc/include -nostdinc; \
+ ;; \
+ esac \
+ else \
+ echo $$r/gcc/xgcc -B$$r/gcc/; \
+ fi; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(CC); \
+ else \
+ t='$(program_transform_name)'; echo gcc | sed -e 's/x/x/' $$t; \
+ fi; \
+ fi`
+
+# If CC_FOR_TARGET is not overriden on the command line, then this
+# variable is passed down to the gcc Makefile, where it is used to
+# build libgcc2.a. We define it here so that it can itself be
+# overridden on the command line.
+GCC_FOR_TARGET = $$r/gcc/xgcc -B$$r/gcc/
+
+CHILL_FOR_TARGET = ` \
+ if [ -f $$r/gcc/xgcc ] ; then \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -L$$r/gcc/ch/runtime/; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(CC); \
+ else \
+ t='$(program_transform_name)'; echo gcc | sed -e 's/x/x/' $$t; \
+ fi; \
+ fi`
+
+CXX_FOR_TARGET = ` \
+ if [ -f $$r/gcc/xgcc ] ; then \
+ if [ -f $$r/$(TARGET_SUBDIR)/newlib/Makefile ] ; then \
+ case "$(target_canonical)" in \
+ i[3456]86-*-cygwin*) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -B$$r/$(TARGET_SUBDIR)/newlib/ -L$$r/$(TARGET_SUBDIR)/winsup -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/winsup/include -idirafter $$s/newlib/libc/include -idirafter $$s/newlib/libc/sys/cygwin -idirafter $$s/newlib/libc/sys/cygwin32 -nostdinc; \
+ ;; \
+ *) \
+ echo $$r/gcc/xgcc -B$$r/gcc/ -idirafter $$r/$(TARGET_SUBDIR)/newlib/targ-include -idirafter $$s/newlib/libc/include -nostdinc; \
+ ;; \
+ esac \
+ else \
+ echo $$r/gcc/xgcc -B$$r/gcc/; \
+ fi; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(CXX); \
+ else \
+ t='$(program_transform_name)'; echo c++ | sed -e 's/x/x/' $$t; \
+ fi; \
+ fi`
+
+AS_FOR_TARGET = ` \
+ if [ -f $$r/gas/as-new ] ; then \
+ echo $$r/gas/as-new ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(AS); \
+ else \
+ t='$(program_transform_name)'; echo as | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+LD_FOR_TARGET = ` \
+ if [ -f $$r/ld/ld-new ] ; then \
+ echo $$r/ld/ld-new ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(LD); \
+ else \
+ t='$(program_transform_name)'; echo ld | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+DLLTOOL_FOR_TARGET = ` \
+ if [ -f $$r/binutils/dlltool ] ; then \
+ echo $$r/binutils/dlltool ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(DLLTOOL); \
+ else \
+ t='$(program_transform_name)'; echo dlltool | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+WINDRES_FOR_TARGET = ` \
+ if [ -f $$r/binutils/windres ] ; then \
+ echo $$r/binutils/windres ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(WINDRES); \
+ else \
+ t='$(program_transform_name)'; echo windres | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+AR_FOR_TARGET = ` \
+ if [ -f $$r/binutils/ar ] ; then \
+ echo $$r/binutils/ar ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(AR); \
+ else \
+ t='$(program_transform_name)'; echo ar | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+RANLIB_FOR_TARGET = ` \
+ if [ -f $$r/binutils/ranlib ] ; then \
+ echo $$r/binutils/ranlib ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(RANLIB); \
+ else \
+ t='$(program_transform_name)'; echo ranlib | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+NM_FOR_TARGET = ` \
+ if [ -f $$r/binutils/nm-new ] ; then \
+ echo $$r/binutils/nm-new ; \
+ else \
+ if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ echo $(NM); \
+ else \
+ t='$(program_transform_name)'; echo nm | sed -e 's/x/x/' $$t ; \
+ fi; \
+ fi`
+
+# The first rule in the file had better be this one. Don't put any above it.
+# This lives here to allow makefile fragments to contain dependencies.
+all: all.normal
+.PHONY: all
+
+# These can be overridden by config/mt-*.
+# The _TARGET_ is because they're specified in mt-foo.
+# The _HOST_ is because they're programs that run on the host.
+EXTRA_TARGET_HOST_ALL_MODULES =
+EXTRA_TARGET_HOST_INSTALL_MODULES =
+EXTRA_TARGET_HOST_CHECK_MODULES =
+
+#### host and target specific makefile fragments come in here.
+###
+
+# Flags to pass down to all sub-makes.
+# Please keep these in alphabetical order.
+BASE_FLAGS_TO_PASS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "AR_FOR_TARGET=$(AR_FOR_TARGET)" \
+ "AS_FOR_TARGET=$(AS_FOR_TARGET)" \
+ "BISON=$(BISON)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CC_FOR_TARGET=$(CC_FOR_TARGET)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "CHILLFLAGS=$(CHILLFLAGS)" \
+ "CHILL_FOR_TARGET=$(CHILL_FOR_TARGET)" \
+ "CHILL_LIB=$(CHILL_LIB)" \
+ "CXX_FOR_BUILD=$(CXX_FOR_BUILD)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CXXFLAGS_FOR_TARGET=$(CXXFLAGS_FOR_TARGET)" \
+ "CXX_FOR_TARGET=$(CXX_FOR_TARGET)" \
+ "DLLTOOL_FOR_TARGET=$(DLLTOOL_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LEX=$(LEX)" \
+ "LD_FOR_TARGET=$(LD_FOR_TARGET)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "LIBCXXFLAGS=$(LIBCXXFLAGS)" \
+ "LIBCXXFLAGS_FOR_TARGET=$(LIBCXXFLAGS_FOR_TARGET)" \
+ "M4=$(M4)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "NM_FOR_TARGET=$(NM_FOR_TARGET)" \
+ "RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET)" \
+ "RPATH_ENVVAR=$(RPATH_ENVVAR)" \
+ "SHELL=$(SHELL)" \
+ "EXPECT=$(EXPECT)" \
+ "RUNTEST=$(RUNTEST)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "TARGET_SUBDIR=$(TARGET_SUBDIR)" \
+ "WINDRES_FOR_TARGET=$(WINDRES_FOR_TARGET)" \
+ "YACC=$(YACC)" \
+ "bindir=$(bindir)" \
+ "datadir=$(datadir)" \
+ "exec_prefix=$(exec_prefix)" \
+ "includedir=$(includedir)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "libexecdir=$(libexecdir)" \
+ "lispdir=$(lispdir)" \
+ "localstatedir=$(localstatedir)" \
+ "mandir=$(mandir)" \
+ "oldincludedir=$(oldincludedir)" \
+ "prefix=$(prefix)" \
+ "sbindir=$(sbindir)" \
+ "sharedstatedir=$(sharedstatedir)" \
+ "sysconfdir=$(sysconfdir)" \
+ "tooldir=$(tooldir)" \
+ "gxx_include_dir=$(gxx_include_dir)" \
+ "gcc_version=$(gcc_version)" \
+ "gcc_version_trigger=$(gcc_version_trigger)" \
+ "target_alias=$(target_alias)" \
+ "libsubdir=$(libsubdir)"
+
+# Flags to pass down to most sub-makes, in which we're building with
+# the host environment.
+# If any variables are added here, they must be added to do-*, below.
+EXTRA_HOST_FLAGS = \
+ 'AR=$(AR)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'CXX=$(CXX)' \
+ 'DLLTOOL=$(DLLTOOL)' \
+ 'LD=$(LD)' \
+ 'NM=$(NM)' \
+ 'RANLIB=$(RANLIB)' \
+ 'WINDRES=$(WINDRES)'
+
+FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS)
+
+# Flags that are concerned with the location of the X11 include files
+# and library files
+#
+# NOTE: until the top-level is getting the values via autoconf, it only
+# causes problems to have this top-level Makefile overriding the autoconf-set
+# values in child directories. Only variables that don't conflict with
+# autoconf'ed ones should be passed by X11_FLAGS_TO_PASS for now.
+#
+X11_FLAGS_TO_PASS = \
+ 'X11_EXTRA_CFLAGS=$(X11_EXTRA_CFLAGS)' \
+ 'X11_EXTRA_LIBS=$(X11_EXTRA_LIBS)'
+
+# Flags to pass down to makes which are built with the target environment.
+# The double $ decreases the length of the command line; the variables
+# are set in BASE_FLAGS_TO_PASS, and the sub-make will expand them.
+# If any variables are added here, they must be added to do-*, below.
+EXTRA_TARGET_FLAGS = \
+ 'AR=$$(AR_FOR_TARGET)' \
+ 'AS=$$(AS_FOR_TARGET)' \
+ 'CC=$$(CC_FOR_TARGET)' \
+ 'CFLAGS=$$(CFLAGS_FOR_TARGET)' \
+ 'CXX=$$(CXX_FOR_TARGET)' \
+ 'CXXFLAGS=$$(CXXFLAGS_FOR_TARGET)' \
+ 'DLLTOOL=$$(DLLTOOL_FOR_TARGET)' \
+ 'LD=$$(LD_FOR_TARGET)' \
+ 'LIBCFLAGS=$$(LIBCFLAGS_FOR_TARGET)' \
+ 'LIBCXXFLAGS=$$(LIBCXXFLAGS_FOR_TARGET)' \
+ 'NM=$$(NM_FOR_TARGET)' \
+ 'RANLIB=$$(RANLIB_FOR_TARGET)' \
+ 'WINDRES=$$(WINDRES_FOR_TARGET)'
+
+TARGET_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS)
+
+# Flags to pass down to gcc. gcc builds a library, libgcc.a, so it
+# unfortunately needs the native compiler and the target ar and
+# ranlib.
+# If any variables are added here, they must be added to do-*, below.
+# The HOST_* variables are a special case, which are used for the gcc
+# cross-building scheme.
+EXTRA_GCC_FLAGS = \
+ 'AR=$(AR)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'CXX=$(CXX)' \
+ 'DLLTOOL=$$(DLLTOOL_FOR_TARGET)' \
+ 'HOST_CC=$(CC_FOR_BUILD)' \
+ 'HOST_PREFIX=$(HOST_PREFIX)' \
+ 'HOST_PREFIX_1=$(HOST_PREFIX_1)' \
+ 'NM=$(NM)' \
+ 'RANLIB=$(RANLIB)' \
+ 'WINDRES=$$(WINDRES_FOR_TARGET)' \
+ "GCC_FOR_TARGET=$(GCC_FOR_TARGET)" \
+ "`echo 'LANGUAGES=$(LANGUAGES)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'STMP_FIXPROTO=$(STMP_FIXPROTO)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIMITS_H_TEST=$(LIMITS_H_TEST)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC1_TEST=$(LIBGCC1_TEST)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC2_CFLAGS=$(LIBGCC2_CFLAGS)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC2_DEBUG_CFLAGS=$(LIBGCC2_DEBUG_CFLAGS)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'LIBGCC2_INCLUDES=$(LIBGCC2_INCLUDES)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'ENQUIRE=$(ENQUIRE)' | sed -e s/.*=$$/XFOO=/`" \
+ "`echo 'BOOT_CFLAGS=$(BOOT_CFLAGS)' | sed -e s/.*=$$/XFOO=/`"
+
+GCC_FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_GCC_FLAGS)
+
+# This is a list of the targets for all of the modules which are compiled
+# using $(FLAGS_TO_PASS).
+ALL_MODULES = \
+ all-apache \
+ all-ash \
+ all-autoconf \
+ all-automake \
+ all-bash \
+ all-bfd \
+ all-binutils \
+ all-bison \
+ all-byacc \
+ all-bzip2 \
+ all-cvssrc \
+ all-db \
+ all-dejagnu \
+ all-diff \
+ all-dosutils \
+ all-etc \
+ all-fileutils \
+ all-findutils \
+ all-find \
+ all-flex \
+ all-gas \
+ all-gawk \
+ all-gettext \
+ all-gnuserv \
+ all-gprof \
+ all-grep \
+ all-grez \
+ all-gzip \
+ all-hello \
+ all-indent \
+ all-inet \
+ all-intl \
+ all-ispell \
+ all-itcl \
+ all-ld \
+ all-libgui \
+ all-libiberty \
+ all-libtool \
+ all-m4 \
+ all-make \
+ all-mmalloc \
+ all-opcodes \
+ all-patch \
+ all-perl \
+ all-prms \
+ all-rcs \
+ all-readline \
+ all-release \
+ all-recode \
+ all-sed \
+ all-send-pr \
+ all-shellutils \
+ all-sim \
+ all-tar \
+ all-tcl \
+ all-tcl8.1 \
+ all-texinfo \
+ all-textutils \
+ all-tgas \
+ all-time \
+ all-uudecode \
+ all-wdiff \
+ all-zip \
+ $(EXTRA_TARGET_HOST_ALL_MODULES)
+
+# This is a list of the check targets for all of the modules which are
+# compiled using $(FLAGS_TO_PASS).
+#
+# The list is in two parts. The first lists those tools which
+# are tested as part of the host's native tool-chain, and not
+# tested in a cross configuration.
+NATIVE_CHECK_MODULES = \
+ check-bison \
+ check-byacc \
+ check-flex \
+ check-zip
+
+CROSS_CHECK_MODULES = \
+ check-apache \
+ check-ash \
+ check-autoconf \
+ check-automake \
+ check-bash \
+ check-bfd \
+ check-binutils \
+ check-bzip2 \
+ check-cvssrc \
+ check-db \
+ check-dejagnu \
+ check-diff \
+ check-etc \
+ check-fileutils \
+ check-findutils \
+ check-find \
+ check-gas \
+ check-gawk \
+ check-gettext \
+ check-gnuserv \
+ check-gprof \
+ check-grep \
+ check-gzip \
+ check-hello \
+ check-indent \
+ check-inet \
+ check-intl \
+ check-ispell \
+ check-itcl \
+ check-ld \
+ check-libgui \
+ check-libiberty \
+ check-libtool \
+ check-m4 \
+ check-make \
+ check-mmcheckoc \
+ check-opcodes \
+ check-patch \
+ check-perl \
+ check-prms \
+ check-rcs \
+ check-readline \
+ check-recode \
+ check-sed \
+ check-send-pr \
+ check-shellutils \
+ check-sim \
+ check-tar \
+ check-tcl \
+ check-texinfo \
+ check-textutils \
+ check-tgas \
+ check-time \
+ check-uudecode \
+ check-wdiff \
+ $(EXTRA_TARGET_HOST_CHECK_MODULES)
+
+CHECK_MODULES=$(NATIVE_CHECK_MODULES) $(CROSS_CHECK_MODULES)
+
+# This is a list of the install targets for all of the modules which are
+# compiled using $(FLAGS_TO_PASS).
+# We put install-opcodes before install-binutils because the installed
+# binutils might be on PATH, and they might need the shared opcodes
+# library.
+# We put install-tcl before install-itcl because itcl wants to run a
+# program on installation which uses the Tcl libraries.
+INSTALL_MODULES = \
+ install-apache \
+ install-ash \
+ install-autoconf \
+ install-automake \
+ install-bash \
+ install-bfd \
+ install-bzip2 \
+ install-opcodes \
+ install-binutils \
+ install-bison \
+ install-byacc \
+ install-cvssrc \
+ install-db \
+ install-dejagnu \
+ install-diff \
+ install-dosutils \
+ install-etc \
+ install-fileutils \
+ install-findutils \
+ install-find \
+ install-flex \
+ install-gas \
+ install-gawk \
+ install-gettext \
+ install-gnuserv \
+ install-gprof \
+ install-grep \
+ install-grez \
+ install-gzip \
+ install-hello \
+ install-indent \
+ install-inet \
+ install-intl \
+ install-ispell \
+ install-tcl \
+ install-tcl8.1 \
+ install-itcl \
+ install-ld \
+ install-libgui \
+ install-libiberty \
+ install-libtool \
+ install-m4 \
+ install-make \
+ install-mmalloc \
+ install-patch \
+ install-perl \
+ install-prms \
+ install-rcs \
+ install-readline \
+ install-recode \
+ install-sed \
+ install-send-pr \
+ install-shellutils \
+ install-sim \
+ install-tar \
+ install-texinfo \
+ install-textutils \
+ install-tgas \
+ install-time \
+ install-uudecode \
+ install-wdiff \
+ install-zip \
+ $(EXTRA_TARGET_HOST_INSTALL_MODULES)
+
+# This is a list of the targets for all of the modules which are compiled
+# using $(X11_FLAGS_TO_PASS).
+ALL_X11_MODULES = \
+ all-emacs \
+ all-emacs19 \
+ all-gdb \
+ all-expect \
+ all-gash \
+ all-guile \
+ all-tclX \
+ all-tk \
+ all-tk8.1 \
+ all-tix
+
+# This is a list of the check targets for all of the modules which are
+# compiled using $(X11_FLAGS_TO_PASS).
+CHECK_X11_MODULES = \
+ check-emacs \
+ check-gdb \
+ check-guile \
+ check-expect \
+ check-gash \
+ check-tclX \
+ check-tk \
+ check-tix
+
+# This is a list of the install targets for all the modules which are
+# compiled using $(X11_FLAGS_TO_PASS).
+INSTALL_X11_MODULES = \
+ install-emacs \
+ install-emacs19 \
+ install-gdb \
+ install-guile \
+ install-expect \
+ install-gash \
+ install-tclX \
+ install-tk \
+ install-tk8.1 \
+ install-tix
+
+# This is a list of the targets for all of the modules which are compiled
+# using $(TARGET_FLAGS_TO_PASS).
+ALL_TARGET_MODULES = \
+ all-target-libio \
+ all-target-libstdc++ \
+ all-target-librx \
+ all-target-libg++ \
+ all-target-newlib \
+ all-target-libtermcap \
+ all-target-winsup \
+ all-target-libgloss \
+ all-target-libiberty \
+ all-target-gperf \
+ all-target-examples \
+ all-target-libstub \
+ all-target-bsp \
+ all-target-cygmon
+
+# This is a list of the configure targets for all of the modules which
+# are compiled using the target tools.
+CONFIGURE_TARGET_MODULES = \
+ configure-target-libio \
+ configure-target-libstdc++ \
+ configure-target-librx \
+ configure-target-libg++ \
+ configure-target-newlib \
+ configure-target-libtermcap \
+ configure-target-winsup \
+ configure-target-libgloss \
+ configure-target-libiberty \
+ configure-target-gperf \
+ configure-target-examples \
+ configure-target-libstub \
+ configure-target-bsp \
+ configure-target-cygmon
+
+# This is a list of the check targets for all of the modules which are
+# compiled using $(TARGET_FLAGS_TO_PASS).
+CHECK_TARGET_MODULES = \
+ check-target-libio \
+ check-target-libstdc++ \
+ check-target-libg++ \
+ check-target-newlib \
+ check-target-winsup \
+ check-target-libiberty \
+ check-target-gperf
+
+# This is a list of the install targets for all of the modules which are
+# compiled using $(TARGET_FLAGS_TO_PASS).
+INSTALL_TARGET_MODULES = \
+ install-target-libio \
+ install-target-libstdc++ \
+ install-target-libg++ \
+ install-target-newlib \
+ install-target-libtermcap \
+ install-target-winsup \
+ install-target-libgloss \
+ install-target-libiberty \
+ install-target-bsp \
+ install-target-gperf
+
+# This is a list of the targets for which we can do a clean-{target}.
+CLEAN_MODULES = \
+ clean-apache \
+ clean-ash \
+ clean-autoconf \
+ clean-automake \
+ clean-bash \
+ clean-bfd \
+ clean-binutils \
+ clean-bison \
+ clean-byacc \
+ clean-bzip2 \
+ clean-cvssrc \
+ clean-db \
+ clean-dejagnu \
+ clean-diff \
+ clean-dosutils \
+ clean-etc \
+ clean-fileutils \
+ clean-findutils \
+ clean-find \
+ clean-flex \
+ clean-gas \
+ clean-gawk \
+ clean-gettext \
+ clean-gnuserv \
+ clean-gprof \
+ clean-grep \
+ clean-grez \
+ clean-gzip \
+ clean-hello \
+ clean-indent \
+ clean-inet \
+ clean-intl \
+ clean-ispell \
+ clean-itcl \
+ clean-ld \
+ clean-libgui \
+ clean-libiberty \
+ clean-libtool \
+ clean-m4 \
+ clean-make \
+ clean-mmalloc \
+ clean-opcodes \
+ clean-patch \
+ clean-perl \
+ clean-prms \
+ clean-rcs \
+ clean-readline \
+ clean-release \
+ clean-recode \
+ clean-sed \
+ clean-send-pr \
+ clean-shellutils \
+ clean-sim \
+ clean-tar \
+ clean-tcl \
+ clean-texinfo \
+ clean-textutils \
+ clean-tgas \
+ clean-time \
+ clean-uudecode \
+ clean-wdiff \
+ clean-zip
+
+# All of the target modules that can be cleaned
+CLEAN_TARGET_MODULES = \
+ clean-target-libio \
+ clean-target-libstdc++ \
+ clean-target-librx \
+ clean-target-libg++ \
+ clean-target-newlib \
+ clean-target-winsup \
+ clean-target-libgloss \
+ clean-target-libiberty \
+ clean-target-gperf \
+ clean-target-examples \
+ clean-target-libstub \
+ clean-target-bsp \
+ clean-target-cygmon
+
+# All of the x11 modules that can be cleaned
+CLEAN_X11_MODULES = \
+ clean-emacs \
+ clean-emacs19 \
+ clean-gdb \
+ clean-expect \
+ clean-gash \
+ clean-guile \
+ clean-tclX \
+ clean-tk \
+ clean-tix
+
+# The target built for a native build.
+.PHONY: all.normal
+all.normal: \
+ $(ALL_MODULES) \
+ $(ALL_X11_MODULES) \
+ $(ALL_TARGET_MODULES) \
+ all-gcc
+
+# Do a target for all the subdirectories. A ``make do-X'' will do a
+# ``make X'' in all subdirectories (because, in general, there is a
+# dependency (below) of X upon do-X, a ``make X'' will also do this,
+# but it may do additional work as well).
+# This target ensures that $(BASE_FLAGS_TO_PASS) appears only once,
+# because it is so large that it can easily overflow the command line
+# length limit on some systems.
+DO_X = \
+ do-clean \
+ do-distclean \
+ do-dvi \
+ do-info \
+ do-install-info \
+ do-installcheck \
+ do-mostlyclean \
+ do-maintainer-clean \
+ do-TAGS
+.PHONY: $(DO_X)
+$(DO_X):
+ @target=`echo $@ | sed -e 's/^do-//'`; \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ for i in $(SUBDIRS) -dummy-; do \
+ if [ -f ./$$i/Makefile ]; then \
+ case $$i in \
+ gcc) \
+ for flag in $(EXTRA_GCC_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'|"`; \
+ done; \
+ ;; \
+ *) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'|"`; \
+ done; \
+ ;; \
+ esac ; \
+ export AR AS CC CXX LD NM RANLIB DLLTOOL WINDRES; \
+ if (cd ./$$i; \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ $${target}); \
+ then true; else exit 1; fi; \
+ else true; fi; \
+ done
+ @target=`echo $@ | sed -e 's/^do-//'`; \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ for i in $(TARGET_CONFIGDIRS) -dummy-; do \
+ if [ -f $(TARGET_SUBDIR)/$$i/Makefile ]; then \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'|"`; \
+ done; \
+ export AR AS CC CXX LD NM RANLIB DLLTOOL WINDRES; \
+ if (cd $(TARGET_SUBDIR)/$$i; \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ $${target}); \
+ then true; else exit 1; fi; \
+ else true; fi; \
+ done
+
+# Here are the targets which correspond to the do-X targets.
+
+.PHONY: info installcheck dvi install-info
+.PHONY: clean distclean mostlyclean maintainer-clean realclean
+.PHONY: local-clean local-distclean local-maintainer-clean
+info: do-info
+installcheck: do-installcheck
+dvi: do-dvi
+
+# Make sure makeinfo is built before we do a `make info'.
+do-info: all-texinfo
+
+install-info: do-install-info dir.info
+ s=`cd $(srcdir); pwd`; export s; \
+ if [ -f dir.info ] ; then \
+ $(INSTALL_DATA) dir.info $(infodir)/dir.info ; \
+ else true ; fi
+
+local-clean:
+ -rm -f *.a TEMP errs core *.o *~ \#* TAGS *.E *.log
+
+local-distclean:
+ -rm -f Makefile config.status config.cache mh-frag mt-frag
+ -if [ "$(TARGET_SUBDIR)" != "." ]; then \
+ rm -rf $(TARGET_SUBDIR); \
+ else true; fi
+
+local-maintainer-clean:
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+clean: do-clean local-clean
+mostlyclean: do-mostlyclean local-clean
+distclean: do-distclean local-clean local-distclean
+maintainer-clean: local-maintainer-clean do-maintainer-clean local-clean
+maintainer-clean: local-distclean
+realclean: maintainer-clean
+
+# This rule is used to clean specific modules.
+.PHONY: $(CLEAN_MODULES) $(CLEAN_X11_MODULES) clean-gcc
+$(CLEAN_MODULES) $(CLEAN_X11_MODULES) clean-gcc:
+ @dir=`echo $@ | sed -e 's/clean-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) clean); \
+ else \
+ true; \
+ fi
+
+.PHONY: $(CLEAN_TARGET_MODULES)
+$(CLEAN_TARGET_MODULES):
+ @dir=`echo $@ | sed -e 's/clean-target-//'`; \
+ rm -f $(TARGET_SUBDIR)/$${dir}/multilib.out $(TARGET_SUBDIR)/$${dir}/tmpmulti.out; \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/$${dir}; $(MAKE) $(TARGET_FLAGS_TO_PASS) clean); \
+ else \
+ true; \
+ fi
+
+clean-target: $(CLEAN_TARGET_MODULES)
+
+# Check target.
+
+.PHONY: check
+check: $(CHECK_MODULES) \
+ $(CHECK_TARGET_MODULES) \
+ $(CHECK_X11_MODULES) \
+ check-gcc
+
+# Automated reporting of test results.
+
+warning.log: build.log
+ $(srcdir)/contrib/warn_summary build.log > $@
+
+mail-report.log:
+ if test x'$(BOOT_CFLAGS)' != x''; then \
+ BOOT_CFLAGS='$(BOOT_CFLAGS)'; export BOOT_CFLAGS; \
+ fi; \
+ $(srcdir)/contrib/test_summary -t >$@
+ chmod +x $@
+ echo If you really want to send e-mail, run ./$@ now
+
+mail-report-with-warnings.log: warning.log
+ if test x'$(BOOT_CFLAGS)' != x''; then \
+ BOOT_CFLAGS='$(BOOT_CFLAGS)'; export BOOT_CFLAGS; \
+ fi; \
+ $(srcdir)/contrib/test_summary -t -i warning.log >$@
+ chmod +x $@
+ echo If you really want to send e-mail, run ./$@ now
+
+# Installation targets.
+
+.PHONY: install install-cross uninstall source-vault binary-vault vault-install
+install: $(INSTALL_TARGET)
+install-cross: $(INSTALL_TARGET_CROSS)
+
+uninstall:
+ @echo "the uninstall target is not supported in this tree"
+
+source-vault:
+ $(MAKE) -f ./release/Build-A-Release \
+ host=$(host_alias) source-vault
+
+binary-vault:
+ $(MAKE) -f ./release/Build-A-Release \
+ host=$(host_alias) target=$(target_alias)
+
+vault-install:
+ @if [ -f ./release/vault-install ] ; then \
+ ./release/vault-install $(host_alias) $(target_alias) ; \
+ else \
+ true ; \
+ fi
+
+.PHONY: install.all
+install.all: install-no-fixedincludes
+ @if [ -f ./gcc/Makefile ] ; then \
+ r=`pwd` ; export r ; \
+ $(SET_LIB_PATH) \
+ (cd ./gcc; \
+ $(MAKE) $(FLAGS_TO_PASS) install-headers) ; \
+ else \
+ true ; \
+ fi
+
+# inet-install is used because the I*Net wants DejaGNU installed but
+# not built. Similarly, gzip is built but not installed.
+inet-install:
+ $(MAKE) INSTALL_MODULES="`echo $(INSTALL_MODULES) | sed -e 's/install-dejagnu//' -e 's/install-gzip//'`" install
+
+# install-no-fixedincludes is used because Cygnus can not distribute
+# the fixed header files.
+.PHONY: install-no-fixedincludes
+install-no-fixedincludes: \
+ installdirs \
+ $(INSTALL_MODULES) \
+ $(INSTALL_TARGET_MODULES) \
+ $(INSTALL_X11_MODULES) \
+ gcc-no-fixedincludes
+
+# Install the gcc headers files, but not the fixed include files,
+# which Cygnus is not allowed to distribute. This rule is very
+# dependent on the workings of the gcc Makefile.in.
+.PHONY: gcc-no-fixedincludes
+gcc-no-fixedincludes:
+ @if [ -f ./gcc/Makefile ]; then \
+ rm -rf gcc/tmp-include; \
+ mv gcc/include gcc/tmp-include 2>/dev/null; \
+ mkdir gcc/include; \
+ cp $(srcdir)/gcc/gsyslimits.h gcc/include/syslimits.h; \
+ touch gcc/stmp-fixinc gcc/include/fixed; \
+ rm -f gcc/stmp-headers gcc/stmp-int-hdrs; \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd` ; export s; \
+ $(SET_LIB_PATH) \
+ (cd ./gcc; \
+ $(MAKE) $(GCC_FLAGS_TO_PASS) install); \
+ rm -rf gcc/include; \
+ mv gcc/tmp-include gcc/include 2>/dev/null; \
+ else true; fi
+
+
+# This rule is used to build the modules which use FLAGS_TO_PASS. To
+# build a target all-X means to cd to X and make all.
+#
+# all-gui, and all-libproc are handled specially because
+# they are still experimental, and if they fail to build, that
+# shouldn't stop "make all".
+.PHONY: $(ALL_MODULES) all-gui all-libproc
+$(ALL_MODULES) all-gui all-libproc:
+ @dir=`echo $@ | sed -e 's/all-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) all); \
+ else \
+ true; \
+ fi
+
+# These rules are used to check the modules which use FLAGS_TO_PASS.
+# To build a target check-X means to cd to X and make check. Some
+# modules are only tested in a native toolchain.
+
+.PHONY: $(CHECK_MODULES) $(NATIVE_CHECK_MODULES) $(CROSS_CHECK_MODULES)
+$(NATIVE_CHECK_MODULES):
+ @if [ "$(host_canonical)" = "$(target_canonical)" ] ; then \
+ dir=`echo $@ | sed -e 's/check-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) check); \
+ else \
+ true; \
+ fi; \
+ fi
+
+$(CROSS_CHECK_MODULES):
+ @dir=`echo $@ | sed -e 's/check-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) check); \
+ else \
+ true; \
+ fi
+
+# This rule is used to install the modules which use FLAGS_TO_PASS.
+# To build a target install-X means to cd to X and make install.
+.PHONY: $(INSTALL_MODULES)
+$(INSTALL_MODULES): installdirs
+ @dir=`echo $@ | sed -e 's/install-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) install); \
+ else \
+ true; \
+ fi
+
+# This rule is used to configure the modules which are built with the
+# target tools.
+.PHONY: $(CONFIGURE_TARGET_MODULES)
+$(CONFIGURE_TARGET_MODULES):
+ @dir=`echo $@ | sed -e 's/configure-target-//'`; \
+ if [ -d $(TARGET_SUBDIR)/$${dir} ]; then \
+ r=`pwd`; export r; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/$${dir}/tmpmulti.out 2> /dev/null; \
+ if [ -s $(TARGET_SUBDIR)/$${dir}/tmpmulti.out ]; then \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/multilib.out ]; then \
+ if cmp $(TARGET_SUBDIR)/$${dir}/multilib.out $(TARGET_SUBDIR)/$${dir}/tmpmulti.out > /dev/null; then \
+ rm -f $(TARGET_SUBDIR)/$${dir}/tmpmulti.out; \
+ else \
+ echo "Multilibs changed for $${dir}, reconfiguring"; \
+ rm -f $(TARGET_SUBDIR)/$${dir}/multilib.out $(TARGET_SUBDIR)/$${dir}/Makefile; \
+ mv $(TARGET_SUBDIR)/$${dir}/tmpmulti.out $(TARGET_SUBDIR)/$${dir}/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/$${dir}/tmpmulti.out $(TARGET_SUBDIR)/$${dir}/multilib.out; \
+ fi; \
+ fi; \
+ fi; exit 0 # break command into two pieces
+ @dir=`echo $@ | sed -e 's/configure-target-//'`; \
+ if [ ! -d $(TARGET_SUBDIR) ]; then \
+ true; \
+ elif [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ true; \
+ elif echo " $(TARGET_CONFIGDIRS) " | grep " $${dir} " >/dev/null 2>&1; then \
+ if [ -d $(srcdir)/$${dir} ]; then \
+ [ -d $(TARGET_SUBDIR)/$${dir} ] || mkdir $(TARGET_SUBDIR)/$${dir};\
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ AR="$(AR_FOR_TARGET)"; export AR; \
+ AS="$(AS_FOR_TARGET)"; export AS; \
+ CC="$(CC_FOR_TARGET)"; export CC; \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXX="$(CXX_FOR_TARGET)"; export CXX; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
+ LD="$(LD_FOR_TARGET)"; export LD; \
+ LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
+ NM="$(NM_FOR_TARGET)"; export NM; \
+ RANLIB="$(RANLIB_FOR_TARGET)"; export RANLIB; \
+ WINDRES="$(WINDRES_FOR_TARGET)"; export WINDRES; \
+ echo Configuring in $(TARGET_SUBDIR)/$${dir}; \
+ cd $(TARGET_SUBDIR)/$${dir}; \
+ case $(srcdir) in \
+ /*) \
+ topdir=$(srcdir) ;; \
+ *) \
+ case "$(TARGET_SUBDIR)" in \
+ .) topdir="../$(srcdir)" ;; \
+ *) topdir="../../$(srcdir)" ;; \
+ esac ;; \
+ esac; \
+ if [ "$(srcdir)" = "." ] ; then \
+ if [ "$(TARGET_SUBDIR)" != "." ] ; then \
+ if $(SHELL) $$s/symlink-tree $${topdir}/$${dir} "no-such-file" ; then \
+ if [ -f Makefile ]; then \
+ if $(MAKE) distclean; then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ else \
+ true; \
+ fi; \
+ else \
+ exit 1; \
+ fi; \
+ else \
+ true; \
+ fi; \
+ srcdiroption="--srcdir=."; \
+ libsrcdir="."; \
+ else \
+ srcdiroption="--srcdir=$${topdir}/$${dir}"; \
+ libsrcdir="$$s/$${dir}"; \
+ fi; \
+ if [ -f $${libsrcdir}/configure ] ; then \
+ rm -f no-such-file skip-this-dir; \
+ CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+ $(CONFIG_ARGUMENTS) $${srcdiroption} \
+ --with-target-subdir="$(TARGET_SUBDIR)"; \
+ else \
+ rm -f no-such-file skip-this-dir; \
+ CONFIG_SITE=no-such-file $(SHELL) $$s/configure \
+ $(CONFIG_ARGUMENTS) $${srcdiroption} \
+ --with-target-subdir="$(TARGET_SUBDIR)"; \
+ fi; \
+ if [ -f skip-this-dir ] ; then \
+ sh skip-this-dir; \
+ rm -f skip-this-dir; \
+ cd ..; rmdir $${dir} || true; \
+ else \
+ true; \
+ fi; \
+ else \
+ true; \
+ fi; \
+ else \
+ true; \
+ fi
+
+# This rule is used to build the modules which use TARGET_FLAGS_TO_PASS.
+# To build a target all-X means to cd to X and make all.
+.PHONY: $(ALL_TARGET_MODULES)
+$(ALL_TARGET_MODULES):
+ @dir=`echo $@ | sed -e 's/all-target-//'`; \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/$${dir}; $(MAKE) $(TARGET_FLAGS_TO_PASS) all); \
+ else \
+ true; \
+ fi
+
+# This rule is used to check the modules which use TARGET_FLAGS_TO_PASS.
+# To build a target install-X means to cd to X and make install.
+.PHONY: $(CHECK_TARGET_MODULES)
+$(CHECK_TARGET_MODULES):
+ @dir=`echo $@ | sed -e 's/check-target-//'`; \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/$${dir};$(MAKE) $(TARGET_FLAGS_TO_PASS) check);\
+ else \
+ true; \
+ fi
+
+# This rule is used to install the modules which use
+# TARGET_FLAGS_TO_PASS. To build a target install-X means to cd to X
+# and make install.
+.PHONY: $(INSTALL_TARGET_MODULES)
+$(INSTALL_TARGET_MODULES): installdirs
+ @dir=`echo $@ | sed -e 's/install-target-//'`; \
+ if [ -f $(TARGET_SUBDIR)/$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/$${dir}; \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) install); \
+ else \
+ true; \
+ fi
+
+# This rule is used to build the modules which use X11_FLAGS_TO_PASS.
+# To build a target all-X means to cd to X and make all.
+.PHONY: $(ALL_X11_MODULES)
+$(ALL_X11_MODULES):
+ @dir=`echo $@ | sed -e 's/all-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; \
+ $(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) all); \
+ else \
+ true; \
+ fi
+
+# This rule is used to check the modules which use X11_FLAGS_TO_PASS.
+# To build a target check-X means to cd to X and make all.
+.PHONY: $(CHECK_X11_MODULES)
+$(CHECK_X11_MODULES):
+ @dir=`echo $@ | sed -e 's/check-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; \
+ $(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) check); \
+ else \
+ true; \
+ fi
+
+# This rule is used to install the modules which use X11_FLAGS_TO_PASS.
+# To build a target install-X means to cd to X and make install.
+.PHONY: $(INSTALL_X11_MODULES)
+$(INSTALL_X11_MODULES): installdirs
+ @dir=`echo $@ | sed -e 's/install-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; \
+ $(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) install); \
+ else \
+ true; \
+ fi
+
+# gcc is the only module which uses GCC_FLAGS_TO_PASS.
+.PHONY: all-gcc
+all-gcc:
+ @if [ -f ./gcc/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) all); \
+ else \
+ true; \
+ fi
+
+# Building GCC uses some tools for rebuilding "source" files
+# like texinfo, bison/byacc, etc. So we must depend on those.
+#
+# While building GCC, it may be necessary to run various target
+# programs like the assembler, linker, etc. So we depend on
+# those too.
+#
+# In theory, on an SMP all those dependencies can be resolved
+# in parallel.
+#
+.PHONY: bootstrap bootstrap-lean bootstrap2 bootstrap2-lean bootstrap3 bootstrap3-lean bootstrap4 bootstrap4-lean
+bootstrap bootstrap-lean bootstrap2 bootstrap2-lean bootstrap3 bootstrap3-lean bootstrap4 bootstrap4-lean: all-texinfo all-bison all-byacc all-binutils all-gas all-ld
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Bootstrapping the compiler"; \
+ cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) $@
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ case "$@" in \
+ *bootstrap4-lean ) \
+ msg="Comparing stage3 and stage4 of the compiler"; \
+ compare=compare3-lean ;; \
+ *bootstrap4 ) msg="Comparing stage3 and stage4 of the compiler"; \
+ compare=compare3 ;; \
+ *-lean ) msg="Comparing stage2 and stage3 of the compiler"; \
+ compare=compare-lean ;; \
+ * ) msg="Comparing stage2 and stage3 of the compiler"; \
+ compare=compare ;; \
+ esac; \
+ $(SET_LIB_PATH) \
+ echo "$$msg"; \
+ cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) $$compare
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd` ; export s; \
+ $(SET_LIB_PATH) \
+ echo "Building runtime libraries"; \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) all
+
+.PHONY: cross
+cross: all-texinfo all-bison all-byacc all-binutils all-gas all-ld
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Building the C and C++ compiler"; \
+ cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) LANGUAGES="c c++"
+ @r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd` ; export s; \
+ $(SET_LIB_PATH) \
+ echo "Building runtime libraries"; \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) all LANGUAGES="c c++"
+
+.PHONY: check-gcc
+check-gcc:
+ @if [ -f ./gcc/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) check); \
+ else \
+ true; \
+ fi
+
+.PHONY: install-gcc
+install-gcc:
+ @if [ -f ./gcc/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) install); \
+ else \
+ true; \
+ fi
+
+.PHONY: install-gcc-cross
+install-gcc-cross:
+ @if [ -f ./gcc/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) LANGUAGES="c c++" install); \
+ else \
+ true; \
+ fi
+# EXPERIMENTAL STUFF
+# This rule is used to install the modules which use FLAGS_TO_PASS.
+# To build a target install-X means to cd to X and make install.
+.PHONY: install-dosrel
+install-dosrel: installdirs info
+ @dir=`echo $@ | sed -e 's/install-//'`; \
+ if [ -f ./$${dir}/Makefile ] ; then \
+ r=`pwd`; export r; \
+ s=`cd $(srcdir); pwd`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $${dir}; $(MAKE) $(FLAGS_TO_PASS) install); \
+ else \
+ true; \
+ fi
+
+install-dosrel-fake:
+
+
+# This is a list of inter-dependencies among modules.
+all-apache:
+all-ash:
+all-autoconf: all-m4 all-texinfo
+all-automake: all-m4 all-texinfo
+all-bash:
+all-bfd: all-libiberty all-intl
+all-binutils: all-libiberty all-opcodes all-bfd all-flex all-bison all-byacc all-intl
+all-bison: all-texinfo
+configure-target-bsp: $(ALL_GCC)
+all-target-bsp: configure-target-bsp all-gcc all-binutils all-target-newlib
+all-byacc:
+all-bzip2:
+all-cvssrc:
+configure-target-cygmon: $(ALL_GCC)
+all-target-cygmon: configure-target-cygmon all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio all-target-libstub all-target-bsp
+all-db:
+all-dejagnu: all-tcl all-expect all-tk
+all-diff: all-libiberty
+all-emacs:
+all-emacs19: all-bison all-byacc
+all-etc:
+configure-target-examples: $(ALL_GCC)
+all-target-examples: configure-target-examples
+all-expect: all-tcl all-tk
+all-fileutils: all-libiberty
+all-findutils:
+all-find:
+all-flex: all-libiberty all-bison all-byacc
+all-gas: all-libiberty all-opcodes all-bfd all-intl
+all-gash: all-tcl
+all-gawk:
+ALL_GCC = all-gcc
+all-gcc: all-bison all-byacc all-binutils all-gas all-ld
+all-bootstrap: all-libiberty all-bison all-byacc all-binutils all-gas all-ld
+GDB_TK = all-tk all-tcl all-itcl all-tix all-libgui
+all-gdb: all-libiberty all-opcodes all-bfd all-mmalloc all-readline all-bison all-byacc all-sim $(gdbnlmrequirements) $(GDB_TK)
+all-gettext:
+all-gnuserv:
+configure-target-gperf: $(ALL_GCC)
+all-target-gperf: configure-target-gperf all-target-libiberty all-target-libstdc++
+all-gprof: all-libiberty all-bfd all-opcodes all-intl
+all-grez: all-libiberty all-bfd all-opcodes
+all-gui: all-gdb all-libproc all-target-librx
+all-guile:
+all-gzip: all-libiberty
+all-hello: all-libiberty
+all-indent:
+all-inet: all-tcl all-send-pr all-perl
+all-intl:
+all-ispell: all-emacs19
+all-itcl: all-tcl all-tk all-tcl8.1 all-tk8.1
+all-ld: all-libiberty all-bfd all-opcodes all-bison all-byacc all-flex all-intl
+configure-target-libg++: $(ALL_GCC) configure-target-librx
+all-target-libg++: configure-target-libg++ all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio all-target-librx all-target-libstdc++
+configure-target-libgloss: $(ALL_GCC)
+all-target-libgloss: configure-target-libgloss configure-target-newlib
+configure-target-libio: $(ALL_GCC)
+all-target-libio: configure-target-libio all-gas all-ld all-gcc all-target-libiberty all-target-newlib
+check-target-libio: all-target-libstdc++
+all-libgui: all-tcl all-tk all-tcl8.1 all-tk8.1 all-itcl
+all-libiberty:
+configure-target-librx: $(ALL_GCC) configure-target-newlib
+all-target-librx: configure-target-librx
+configure-target-libstdc++: $(ALL_GCC)
+all-target-libstdc++: configure-target-libstdc++ all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio
+configure-target-libstub: $(ALL_GCC)
+all-target-libstub: configure-target-libstub
+all-libtool:
+all-m4: all-libiberty
+all-make: all-libiberty
+all-mmalloc:
+configure-target-newlib: $(ALL_GCC)
+configure-target-libtermcap: $(ALL_GCC)
+all-target-newlib: configure-target-newlib all-binutils all-gas all-gcc
+all-target-libtermcap: configure-target-libtermcap all-binutils all-gas all-gcc
+all-opcodes: all-bfd all-libiberty
+all-patch: all-libiberty
+all-perl:
+all-prms: all-libiberty
+all-rcs:
+all-readline:
+all-recode: all-libiberty
+all-sed: all-libiberty
+all-send-pr: all-prms
+all-shellutils:
+all-sim: all-libiberty all-bfd all-opcodes all-readline
+all-tar: all-libiberty
+all-tcl:
+all-tcl8.1:
+all-tclX: all-tcl all-tk
+all-tk: all-tcl
+all-tk8.1: all-tcl8.1
+all-texinfo: all-libiberty
+all-textutils:
+all-tgas: all-libiberty all-bfd all-opcodes
+all-time:
+all-tix: all-tcl all-tk all-tcl8.1 all-tk8.1
+all-wdiff:
+all-target-winsup: all-target-newlib all-target-libiberty all-target-libtermcap configure-target-winsup
+configure-target-winsup: configure-target-newlib
+all-uudecode: all-libiberty
+all-zip:
+configure-target-libiberty: $(ALL_GCC)
+all-target-libiberty: configure-target-libiberty all-gcc all-ld all-target-newlib
+all-target: $(ALL_TARGET_MODULES)
+install-target: $(INSTALL_TARGET_MODULES)
+### other supporting targets
+
+MAKEDIRS= \
+ $(prefix) \
+ $(exec_prefix)
+.PHONY: installdirs
+installdirs: mkinstalldirs
+ $(SHELL) $(srcdir)/mkinstalldirs $(MAKEDIRS)
+
+dir.info: do-install-info
+ if [ -f $(srcdir)/texinfo/gen-info-dir ] ; then \
+ $(srcdir)/texinfo/gen-info-dir $(infodir) $(srcdir)/texinfo/dir.info-template > dir.info.new ; \
+ mv -f dir.info.new dir.info ; \
+ else true ; \
+ fi
+
+dist:
+ @echo "Building a full distribution of this tree isn't done"
+ @echo "via 'make dist'. Check out the etc/ subdirectory"
+
+etags tags: TAGS
+
+# Right now this just builds TAGS in each subdirectory. emacs19 has the
+# ability to use several tags files at once, so there is probably no need
+# to combine them into one big TAGS file (like CVS 1.3 does). We could
+# (if we felt like it) have this Makefile write a piece of elisp which
+# the user could load to tell emacs19 where all the TAGS files we just
+# built are.
+TAGS: do-TAGS
+
+# with the gnu make, this is done automatically.
+
+Makefile: Makefile.in configure.in $(host_makefile_frag) $(target_makefile_frag) $(gcc_version_trigger)
+ $(SHELL) ./config.status
+
+#
+# Support for building net releases
+
+# Files in devo used in any net release.
+# ChangeLog omitted because it may refer to files which are not in this
+# distribution (perhaps it would be better to include it anyway).
+DEVO_SUPPORT= README Makefile.in configure configure.in \
+ config.guess config.if config.sub config move-if-change \
+ mpw-README mpw-build.in mpw-config.in mpw-configure mpw-install \
+ COPYING COPYING.LIB install-sh config-ml.in symlink-tree \
+ mkinstalldirs ltconfig ltmain.sh missing ylwrap
+
+# Files in devo/etc used in any net release.
+# ChangeLog omitted because it may refer to files which are not in this
+# distribution (perhaps it would be better to include it anyway).
+ETC_SUPPORT= Makefile.in configure configure.in standards.texi \
+ make-stds.texi standards.info*
+
+# When you use `make setup-dirs' or `make taz' you should always redefine
+# this macro.
+SUPPORT_FILES = list-of-support-files-for-tool-in-question
+
+.PHONY: taz
+
+taz: $(DEVO_SUPPORT) $(SUPPORT_FILES) \
+ texinfo/texinfo.tex texinfo/gpl.texinfo texinfo/lgpl.texinfo
+ # Take out texinfo from a few places.
+ sed -e '/^all\.normal: /s/\all-texinfo //' \
+ -e '/^ install-texinfo /d' \
+ <Makefile.in >tmp
+ mv -f tmp Makefile.in
+ #
+ ./configure sun4
+ [ -z "$(CONFIGURE_TARGET_MODULES)" ] \
+ || $(MAKE) $(CONFIGURE_TARGET_MODULES) ALL_GCC="" \
+ CC_FOR_TARGET="$(CC)" CXX_FOR_TARGET="$(CXX)"
+ # Make links, and run "make diststuff" or "make info" when needed.
+ rm -rf proto-toplev ; mkdir proto-toplev
+ set -e ; dirs="$(TOOL) $(DEVO_SUPPORT) $(SUPPORT_FILES)" ; \
+ for d in $$dirs ; do \
+ if [ -d $$d ]; then \
+ if [ ! -f $$d/Makefile ] ; then true ; \
+ elif grep '^diststuff:' $$d/Makefile >/dev/null ; then \
+ (cd $$d ; $(MAKE) diststuff ) || exit 1 ; \
+ elif grep '^info:' $$d/Makefile >/dev/null ; then \
+ (cd $$d ; $(MAKE) info ) || exit 1 ; \
+ fi ; \
+ if [ -d $$d/proto-$$d.dir ]; then \
+ ln -s ../$$d/proto-$$d.dir proto-toplev/$$d ; \
+ else \
+ ln -s ../$$d proto-toplev/$$d ; \
+ fi ; \
+ else ln -s ../$$d proto-toplev/$$d ; fi ; \
+ done
+ cd etc ; $(MAKE) info
+ $(MAKE) distclean
+ #
+ mkdir proto-toplev/etc
+ (cd proto-toplev/etc; \
+ for i in $(ETC_SUPPORT); do \
+ ln -s ../../etc/$$i . ; \
+ done)
+ #
+ # Take out texinfo from configurable dirs
+ rm proto-toplev/configure.in
+ sed -e '/^host_tools=/s/texinfo //' \
+ <configure.in >proto-toplev/configure.in
+ #
+ mkdir proto-toplev/texinfo
+ ln -s ../../texinfo/texinfo.tex proto-toplev/texinfo/
+ ln -s ../../texinfo/gpl.texinfo proto-toplev/texinfo/
+ ln -s ../../texinfo/lgpl.texinfo proto-toplev/texinfo/
+ if test -r texinfo/util/tex3patch ; then \
+ mkdir proto-toplev/texinfo/util && \
+ ln -s ../../../texinfo/util/tex3patch proto-toplev/texinfo/util ; \
+ else true; fi
+ chmod -R og=u . || chmod og=u `find . -print`
+ if grep AM_INIT_AUTOMAKE $(TOOL)/configure.in >/dev/null 2>&1; then \
+ ver=`sed < $(TOOL)/configure.in -n 's/AM_INIT_AUTOMAKE[^,]*, *\([^)]*\))/\1/p'`; \
+ else \
+ ver=`sed <$(TOOL)/Makefile.in -n 's/^VERSION *= *//p'`; \
+ fi; \
+ $(MAKE) -f Makefile.in do-tar-gz TOOL=$(TOOL) VER=$$ver
+
+do-tar-gz:
+ echo "==> Making $(TOOL)-$(VER).tar.gz"
+ -rm -f $(TOOL)-$(VER)
+ ln -s proto-toplev $(TOOL)-$(VER)
+ tar cfh $(TOOL)-$(VER).tar $(TOOL)-$(VER)
+ $(GZIPPROG) -v -9 $(TOOL)-$(VER).tar
+
+TEXINFO_SUPPORT= texinfo/texinfo.tex texinfo/gpl.texinfo texinfo/lgpl.texinfo
+DIST_SUPPORT= $(DEVO_SUPPORT) $(TEXINFO_SUPPORT)
+
+.PHONY: gas.tar.gz
+GAS_SUPPORT_DIRS= bfd include libiberty opcodes intl setup.com makefile.vms
+gas.tar.gz: $(DIST_SUPPORT) $(GAS_SUPPORT_DIRS) gas
+ $(MAKE) -f Makefile.in taz TOOL=gas \
+ SUPPORT_FILES="$(GAS_SUPPORT_DIRS)"
+
+# The FSF "binutils" release includes gprof and ld.
+.PHONY: binutils.tar.gz
+BINUTILS_SUPPORT_DIRS= bfd gas include libiberty opcodes ld gprof intl setup.com makefile.vms
+binutils.tar.gz: $(DIST_SUPPORT) $(BINUTILS_SUPPORT_DIRS) binutils
+ $(MAKE) -f Makefile.in taz TOOL=binutils \
+ SUPPORT_FILES="$(BINUTILS_SUPPORT_DIRS) makeall.bat configure.bat"
+
+.PHONY: gas+binutils.tar.gz
+GASB_SUPPORT_DIRS= $(GAS_SUPPORT_DIRS) binutils ld gprof
+gas+binutils.tar.gz: $(DIST_SUPPORT) $(GASB_SUPPORT_DIRS) gas
+ $(MAKE) -f Makefile.in taz TOOL=gas \
+ SUPPORT_FILES="$(GASB_SUPPORT_DIRS) makeall.bat configure.bat"
+
+.PHONY: libg++.tar.gz
+LIBGXX_SUPPORT_DIRS=include libstdc++ libio librx libiberty
+libg++.tar.gz: $(DIST_SUPPORT) libg++
+ $(MAKE) -f Makefile.in taz TOOL=libg++ \
+ SUPPORT_FILES="$(LIBGXX_SUPPORT_DIRS)"
+
+GNATS_SUPPORT_DIRS=include libiberty send-pr
+gnats.tar.gz: $(DIST_SUPPORT) $(GNATS_SUPPORT_DIRS) gnats
+ $(MAKE) -f Makefile.in taz TOOL=gnats \
+ SUPPORT_FILES="$(GNATS_SUPPORT_DIRS)"
+
+.PHONY: gdb.tar.gz
+GDB_SUPPORT_DIRS= bfd include libiberty mmalloc opcodes readline sim utils intl
+gdb.tar.gz: $(DIST_SUPPORT) $(GDB_SUPPORT_DIRS) gdb
+ $(MAKE) -f Makefile.in taz TOOL=gdb \
+ SUPPORT_FILES="$(GDB_SUPPORT_DIRS)"
+
+.PHONY: newlib.tar.gz
+NEWLIB_SUPPORT_DIRS=libgloss
+# taz configures for the sun4 target which won't configure newlib.
+# We need newlib configured so that the .info files are made.
+# Unfortunately, it is not enough to just configure newlib separately:
+# taz will build the .info files but since SUBDIRS won't contain newlib,
+# distclean won't be run (leaving Makefile, config.status, and the tmp files
+# used in building the .info files, eg: *.def, *.ref).
+# The problem isn't solvable however without a lot of extra work because
+# target libraries are built in subdir $(target_alias) which gets nuked during
+# the make distclean. For now punt on the issue of shipping newlib info files
+# with newlib net releases and wait for a day when some native target (sun4?)
+# supports newlib (if only minimally).
+newlib.tar.gz: $(DIST_SUPPORT) $(NEWLIB_SUPPORT_DIRS) newlib
+ $(MAKE) -f Makefile.in taz TOOL=newlib \
+ SUPPORT_FILES="$(NEWLIB_SUPPORT_DIRS)" \
+ DEVO_SUPPORT="$(DEVO_SUPPORT) COPYING.NEWLIB" newlib
+
+.NOEXPORT:
+MAKEOVERRIDES=
+
+# end of Makefile.in
diff --git a/README b/README
new file mode 100644
index 00000000000..eb0e436d860
--- /dev/null
+++ b/README
@@ -0,0 +1,47 @@
+ README for GNU development tools
+
+This directory contains various GNU compilers, assemblers, linkers,
+debuggers, etc., plus their support routines, definitions, and documentation.
+
+If you are receiving this as part of a GDB release, see the file gdb/README.
+If with a binutils release, see binutils/README; if with a libg++ release,
+see libg++/README, etc. That'll give you info about this
+package -- supported targets, how to use it, how to report bugs, etc.
+
+It is now possible to automatically configure and build a variety of
+tools with one command. To build all of the tools contained herein,
+run the ``configure'' script here, e.g.:
+
+ ./configure
+ make
+
+To install them (by default in /usr/local/bin, /usr/local/lib, etc),
+then do:
+ make install
+
+(If the configure script can't determine your type of computer, give it
+the name as an argument, for instance ``./configure sun4''. You can
+use the script ``config.sub'' to test whether a name is recognized; if
+it is, config.sub translates it to a triplet specifying CPU, vendor,
+and OS.)
+
+If you have more than one compiler on your system, it is often best to
+explicitly set CC in the environment before running configure, and to
+also set CC when running make. For example (assuming sh/bash/ksh):
+
+ CC=gcc ./configure
+ make
+
+A similar example using csh:
+
+ setenv CC gcc
+ ./configure
+ make
+
+Much of the code and documentation enclosed is copyright by
+the Free Software Foundation, Inc. See the file COPYING or
+COPYING.LIB in the various directories, for a description of the
+GNU General Public License terms under which you can copy the files.
+
+REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info
+on where and how to report problems.
diff --git a/bfd/COPYING b/bfd/COPYING
new file mode 100644
index 00000000000..60549be514a
--- /dev/null
+++ b/bfd/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
new file mode 100644
index 00000000000..66a5b243f36
--- /dev/null
+++ b/bfd/ChangeLog
@@ -0,0 +1,3066 @@
+1999-04-29 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (coff_mcore_relocate_section): Fix typos.
+
+Fri Apr 28 16:36:19 1999 Stan Cox <scox@cygnus.com>
+
+ * elf32-sh.c (sh_elf_relocate_section): Include relocation addend
+ in relocation calculation.
+
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-21 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c: Add support for mcore relocs.
+
+1999-04-20 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_print_private_bfd_data): Scrap the
+ incorrect use EF_MIPS_xxBITPTRS.
+
+1999-04-18 Ian Lance Taylor <ian@zembu.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Remove unused local
+ variable insn.
+
+ * bfd-in2.h: Rebuild.
+ * libbfd.h: Rebuild.
+
+Sat Apr 17 20:55:15 1999 Catherine Moore <clm@cygnus.com>
+
+ * coff-arm.c (coff_arm_rtype_to_howto): Remove ARM26D transform.
+ (coff_arm_relocate_section): Add ARM26D transform. Only
+ change to ARM26D for relocateable links.
+
+1999-04-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_print_private_bfd_data): New.
+ (bfd_elf32_bfd_print_private_bfd_data): New.
+
+1999-04-15 Doug Evans <devans@casey.cygnus.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): For R_ARM_THM_ABS5,
+ refetch addend if USE_REL, add many comments regarding current state.
+ For R_ARM_THM_PC22, refetch addend if USE_REL, simplify.
+ * elfarm-nabi.c (elf32_arm_howto_table): For R_ARM_THM_ABS5, fix
+ size and rightshift. For R_ARM_THM_PC22, fix bitsize.
+ * elfarm-oabi.c (elf32_arm_howto_table): Ditto.
+
+Wed Apr 14 14:33:08 1999 Richard Henderson <rth@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_read_ecoff_info): Zero `debug'.
+ * elf64-alpha.c (elf64_alpha_read_ecoff_info): Likewise.
+
+1999-04-13 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2.c (decode_line_info): Don't truncate address to least
+ significant 32 bits (breaks 64 bit targets).
+ (lookup_address_in_function_table): Ditto.
+ (comp_unit_contains_address): Ditto.
+
+Tue Apr 13 21:27:19 1999 Catherine Moore <clm@cygnus.com>
+
+ * coff-arm.c (arm_emit_base_file_entry): New routine.
+ (A2T3_OFFSET): Define.
+ (T2A3_OFFSET): Define.
+ (coff_arm_relocate_section): Emit base file entries for interworking
+ stubs.
+
+1999-04-13 Philip Blundell <philb@gnu.org>
+
+ * elfarm-nabi.c (elf32_arm_howto_table): Add dummy entries for
+ relocs 17 through 19.
+
+Sun Apr 11 01:25:17 1999 Richard Henderson <rth@cygnus.com>
+
+ * elfcode.h: Remove fnmatch.h.
+ * elflink.h (elf_link_assign_sym_version): Call back to ld
+ instead of calling fnmatch.
+
+ * config.bfd (i?86-*-beoself): Include pe vecs.
+
+Sun Apr 11 01:14:06 1999 Richard Henderson <rth@cygnus.com>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_sections): Allow .plt
+ to go missing.
+
+1999-04-10 Richard Henderson <rth@cygnus.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Mind no_undefined
+ when trying to resolve dynamic symbol references.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elflink.h (elf_link_output_extsym): Likewise.
+
+Sat Apr 10 15:12:09 1999 Richard Henderson <rth@cygnus.com>
+
+ * section.c (_bfd_strip_section_from_output): New function moved from
+ * elf64-alpha.c (elf64_alpha_strip_section_from_output): ... here.
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Use it.
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise.
+ * elf32-mips.c (mips_elf_size_dynamic_sections): Likewise.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise.
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Likewise.
+ * elf64-sparc.c (sparc64_elf_size_dynamic_sections): Likewise.
+ * bfd-in2.h: Update.
+
+1999-04-09 Ian Lance Taylor <ian@zembu.com>
+
+ * elf64-sparc.c: Fix incorrect calls to bfd_check_overflow.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c: New File: Support for mcore-pe targets.
+ * cpu-mcore.c: New File: Support for mcore targets.
+ * elf32-mcore.c: New File: Support for mcore-elf target.
+ * pe-mcore.c: New File: Definitions for mcore-pe target.
+ * pei-mcore.c: New File: Definitions for mcore-pei target.
+ * Makefile.am: Add support for MCore targets.
+ * Makefile.in: Regenerate.
+ * config.bfd: Add support for MCore targets.
+ * configure.in: Add support for MCore targets.
+ * configure: Regenerate.
+ * archures.c: Add support for MCore architecture.
+ * bfd-in2.h: Regenerate.
+ * coffcode.h: Add support for mcore-pe targets.
+ * elf.c: Add support for mcore-elf target.
+ * reloc.c: Add support for MCore relocs.
+ * targets.c: Add support for MCore targets.
+
+1999-04-07 Nick Clifton <nickc@cygnus.com>
+
+ * elfarm-nabi.c (elf32_arm_howto_table): Add entries for
+ R_ARM_XPC25 and R_ARM_THM_XPC22.
+ (elf32_arm_reloc_map): Remove redundant entries.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * sysdep.h (LC_MESSAGES): Never define.
+
+1999-04-06 Chris Torek <torek@bsdi.com>
+
+ * reloc.c (bfd_check_overflow): Add addrsize parameter. Change
+ all callers. Rewrite completely.
+ (_bfd_relocate_contents): Rewrite overflow checking.
+ * bfd-in2.h: Rebuild.
+
+1999-04-05 Ian Lance Taylor <ian@zembu.com>
+
+ From Gabriel Paubert <paubert@iram.es>:
+ * elf32-ppc.c (ppc_elf_howto_raw): Set R_PPC_GOT16_LO,
+ R_PPC_PLT16_LO and R_PPC_SECTOFF_LO to be complain_overflow_dont.
+ Set R_PPC_PLT16_HA, R_PPC_SECTOFF_HA and R_PPC_EMB_NADDR16_HA to
+ have a rightshift of 16 and use ppc_elf_addr16_ha_reloc.
+ * ppcboot.c (ppcboot_vec): Use little endian routines for
+ headers.
+
+ * elf.c (elfcore_strndup): Only define if it will be used.
+ * elf32-ppc.c (ppc_elf_relax_section): Remove unused locals irel
+ and irelend.
+ (ppc_elf_check_relocs): Remove unused local i.
+ (ppc_elf_gc_mark_hook): Add default case to switch.
+
+ From Bernd Nitzler <nitzler@kagcpd01.ag01.kodak.COM>:
+ * srec.c (srec_scan): Accept \r in symbol definitions.
+ (srec_object_p): Set HAS_SYMS if we saw any symbols.
+ (symbolsrec_object_p): Likewise.
+
+1999-04-04 Don Bowman <don@pixsci.com>
+
+ * config.bfd: Add mips*el-*-vxworks* and mips*-*-vxworks*.
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * dwarf1.c (parse_line_table): Remove unused locals last_pc and
+ last_line.
+ * elf-bfd.h (_bfd_elfcore_section_from_phdr): Declare.
+ * elf32-i386.c (elf_i386_gc_mark_hook): Add default case to
+ switch.
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Remove unused
+ local i.
+ * syms.c (_bfd_stab_section_find_nearest_line): Remove unused
+ local val.
+
+1999-03-31 Nick Clifton <nickc@cygnus.com>
+
+ * config.bfd: Add support for arm-epoc-pe target.
+ * configure.in: Add support for arm-epoc-pe target.
+ * configure: Regenerate.
+ * targets.c: Add support for arm-epoc-pe target.
+ * coff-arm.c: Allow header files to override definition of
+ TARGET_UNDERSCORE and USER_LABEL_PREFIX.
+ * pe-arm.h: Allow previous header files to override definition of
+ TARGET_LITTLE_SYM and TARGET_BIG_SYM.
+ * pei-arm.h: Allow previous header files to override definition of
+ TARGET_LITTLE_SYM and TARGET_BIG_SYM.
+ * epoc-pe-arm.c: New file. Support arm-epoc-pe target.
+ * epoc-pei-arm.c: New file. Support arm-epoc-pei target.
+
+1999-03-30 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (elf_map_symbols): Handle the case where section
+ symbols are generated for content-less sections which are
+ not mapped to the output file.
+
+ * linker.c: Replace direct references to fields in BFD structure
+ with accessor macros.
+
+ * elflink.h: Replace direct references to fields in BFD structure
+ with accessor macros.
+
+1999-03-25 Philip Blundell <pb@nexus.co.uk>
+
+ * config.bfd: Eliminate redundancy in checks for Linux/ARM.
+
+ * elf32-arm.h (elf32_arm_relocate_section): Take the rightshift into
+ account when adjusting section symbols during a partial link.
+
+1999-03-24 Nick Clifton <nickc@cygnus.com>
+
+ * coff-sparc.c (struct coff_reloc_map): Change type of field
+ 'bfd_reloc_val' to bfd_reloc_code_real_type.
+ * elf-m10200.c (struct mn10200_reloc_map): Ditto.
+ * elf-m10300.c (struct mn10300_reloc_map): Ditto.
+ * elf32-arc.c (struct arc_reloc_map): Ditto.
+ * elf32-d10v.c (struct d10v_reloc_map): Ditto.
+ * elf32-d30v.c (struct d30v_reloc_map): Ditto.
+ * elf32-fr30.c (struct fr30_reloc_map): Ditto.
+ * elf32-m32r.c (struct m32r_reloc_map): Ditto.
+ * elf32-sh.c (struct elf_reloc_map): Ditto.
+ * elf32-sparc.c (struct elf_reloc_map): Ditto.
+ * elf32-v850.c (struct v850_reloc_map): Ditto.
+ * elf64-sparc.c (struct elf_reloc_map): Ditto.
+ * elfarm-nabi.c (struct elf32_arm_reloc_map): Ditto.
+ * elfarm-oabi.c (struct elf32_arm_reloc_map): Ditto.
+
+1999-03-17 Martin Hunt <hunt@cygnus.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Changed this
+ function so source-level assembly works. If multiple N_SOs
+ are seen without and N_FUNs, create an indextable entry with
+ a NULL function name.
+
+1999-03-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_merge_private_bfd_data) Allow merging
+ of certian similar cpus.
+
+1999-03-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing):
+ Add the 5000. Change the architecture for the 5400 to mips4.
+ (elf_mips_mach): Add r5000.
+
+1999-03-11 Doug Evans <devans@casey.cygnus.com>
+
+ * cpu-i960.c (scan_i960_mach): Recognize i960:ka_sa and i960:kb_sb.
+
+1999-03-11 Nick Clifton <nickc@cygnus.com>
+
+ * binary.c (binary_set_section_contents): Generate warning about
+ huge file offsets for any section that will occupy file space, not
+ just those that are loadable.
+
+1999-02-24 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * libbfd.h: Regenerate after Nick Clifton's Feb 17 changes.
+
+1999-02-22 Jim Lemke <jlemke@cygnus.com>
+
+ * elf32-ppc.c: Add ppc_elf_relax_section() for the ld option mpc860c0.
+
+Mon Feb 22 18:26:51 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf-bfd.h (ELF_LINK_HASH_REF_REGULAR_NONWEAK): Define.
+ * elflink.h: Revert all changes since Feb 16. Instead:
+ (elf_link_add_object_symbols): Set REF_REGULAR_NONWEAK flag if
+ appropriate. Copy it to version symbols.
+ (elf_fix_symbol_flags): Set REF_REGULAR_NONWEAK for non ELF
+ symbols if appropriate.
+ (elf_adjust_dynamic_symbol): Set REF_REGULAR_NONWEAK for weakdef
+ symbol if appropriate.
+ (elf_link_output_extsym): If symbol is marked as undefined, and
+ has no nonweak references, mark it as weak undefined.
+
+Fri Feb 19 16:01:12 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_merge_symbol): When overriding a dynamic
+ definition with a weak undefined symbol, set NEEDS_PLT if it is a
+ function.
+ (elf_link_add_object_symbols): Don't copy the other field if we
+ are overridding.
+
+Thu Feb 18 18:07:43 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_merge_symbol): Do not merge any symbol from a
+ shared object with a weak undefined symbol.
+
+1999-02-18 Nick Clifton <nickc@cygnus.com>
+
+ * elfarm-nabi.c: Set partial_inplace back to false.
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (TARGET_UNDERSCORE): Re-enable.
+ (USER_LABEL_PREFIX): Set to "_".
+
+ The following patches are from: Scott Bambrough
+ <scottb@corelcomputer.com>
+
+ * libaout.h (M_ARM6_NETBSD): Set to 143.
+
+ * reloc.c: Add ARM PIC relocs: BFD_RELOC_ARM_GOT12,
+ BFD_RELOC_ARM_GOT32, BFD_RELOC_ARM_JUMP_SLOT, BFD_RELOC_ARM_COPY,
+ BFD_RELOC_ARM_GLOB_DAT, BFD_RELOC_ARM_PLT32,
+ BFD_RELOC_ARM_RELATIVE, BFD_RELOC_ARM_GOTOFF, BFD_RELOC_ARM_GOTPC.
+ * bfd-in2.h: Regenerate.
+
+ * elfarm-nabi.c (elf32_arm_howto_table): Set partial_inplace to
+ 'true' as REL relocs are now being used. Add new PIC relocs:
+ R_ARM_COPY, R_ARM_GLOB_DAT, R_ARM_JUMP_SLOT, R_ARM_RELATIVE,
+ R_ARM_GOTOFF, R_ARM_GOTPC, R_ARM_GOT32, R_ARM_PLT32.
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Check byte order
+ of targets.
+ (elf32_arm_final_link_relocate): Change parameters so that entire
+ reloc is passed. Add support for PIC relocs.
+ (elf32_arm_relocate_section): Pass entire reloc to
+ elf32_arm_final_link_relocate.
+ (elf32_arm_check_relocs): Handle new PIC relocs.
+ (elf32_arm_adjust_dynamic_symbol): New function.
+ (elf32_arm_size_dynamic_sections): New function.
+ (elf32_arm_discard_copies): New function.
+ (elf32_arm_finish_dynamic_symbol): New function.
+ (elf32_arm_finish_dynamic_sections): New function.
+ (ELF_MAXPAGE_SIZE): Define.
+ (bfd_elf32_bfd_reloc_type_lookup): Define.
+ (elf_backend_relocate_section): Define.
+ (elf_backend_adjust_dynamic_symbol): Define.
+ (elf_backend_create_dynamic_sections): Define.
+ (elf_backend_finish_dynamic_symbol): Define.
+ (elf_backend_finish_dynamic_sections): Define.
+ (elf_backend_size_dynamic_sections): Define.
+ (elf_backend_plt_readonly): Define.
+ (elf_backend_want_got_plt): Define.
+ (elf_backend_want_plt_sym): Define.
+
+Wed Feb 17 12:02:26 1999 Stan Cox <scox@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_section_from_shdr): Make reginfo
+ sections SEC_LINK_ONCE and SEC_LINK_DUPLICATES_SAME_SIZE.
+ (_bfd_mips_elf_fake_sections): Likewise.
+
+Wed Feb 17 12:07:23 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * elfarm-oabi.c (bfd_elf32_arm_allocate_interworking_sections,
+ bfd_elf32_arm_get_bfd_for_interworking,
+ bfd_elf32_arm_process_before_allocation): Define to avoid clash
+ with elfarm-nabi.c.
+
+ * elf32-arm.h: Don't declare elf32_arm_info_to_howto.
+ (elf32_thumb_to_arm_stub, elf32_arm_to_thumb_stub,
+ elf32_arm_find_nearest_line): Make them static.
+
+Tue Feb 16 22:44:37 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_merge_symbol): Add pflags parameter. Change all
+ callers. Do not merge a definition from a shared object with a
+ weak undefined symbol.
+ (elf_link_add_object_symbols): Do not change the symbol type or
+ size if the old symbol overrides the new one.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * config.bfd: Add support for strongarm target.
+
+Mon Feb 8 11:18:14 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * elf32-m68k.c (reloc_map): Use the correct types for the struct
+ fields instead of unsigned char.
+
+Fri Feb 5 00:22:36 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+Thu Feb 4 22:30:13 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change AC_PREREQ to 2.13. Remove AM_CYGWIN32.
+ Change AM_EXEEXT to AC_EXEEXT and AM_PROG_INSTALL to
+ AC_PROG_INSTALL. Add comments to uses of AC_DEFINE.
+ * acinclude.m4: Add comments to uses of AC_DEFINE.
+ * acconfig.h: Remove.
+ * configure: Rebuild with current autoconf/automake.
+ * aclocal.m4: Likewise.
+ * config.in: Likewise.
+ * Makefile.in: Likewise.
+
+1999-02-04 DJ Delorie <dj@cygnus.com>
+
+ * libbfd.c (real_read): don't call fread for zero bytes. This
+ covers up a bug (or misuse of bfd) that's exposed by Solaris.
+
+Thu Feb 4 12:38:10 1999 Stan Cox <scox@cygnus.com>
+
+ * elf32-mips.c (mips_elf_relocate_section): Insure that the target
+ of a jump is in the current 256 MB region.
+
+Thu Feb 4 12:15:38 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * format.c (bfd_check_format_matches): Change last patch to only
+ take effect for the binary target.
+
+Wed Feb 3 19:40:12 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_reloc_type_lookup): Add BFD_RELOC_CTOR.
+
+Wed Feb 3 15:02:44 1999 Catherine Moore <clm@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_check_relocs): New routine.
+
+Tue Feb 2 21:38:28 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * format.c (bfd_check_format_matches): If the target was
+ previously specified, don't check other targets when checking for
+ an archive file.
+
+Tue Feb 2 18:16:43 1999 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.h (elf32_arm_reloc_map): Removed.
+ (elf32_arm_reloc_type_lookup): Removed
+ * elfarm-nabi.c (elf32_arm_reloc_map): New.
+ (elf32_arm_reloc_type_lookup): New.
+ * elfarm-oabi.c (elf32_arm_reloc_map): New.
+ (elf32_arm_reloc_type_lookup): New.
+
+Mon Feb 1 19:49:21 1999 Catherine Moore <clm@cygnus.com>
+
+ * elfarm-nabi.c: Renamed from elf32-arm-newabi.c.
+ * elfarm-oabi.c: Renamed from elf32-arm-oldabi.c
+ * Makefile.am: Use new files.
+ * Makefile.in: Regenerate.
+ * configure.in: Use new files.
+ * configure: Regenerate.
+
+1999-02-01 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_gc_mark_hook): New function.
+ (fr30_elf_gc_sweep_hook): New function.
+ (elf_backend_can_gc_sections): Define.
+
+Mon Feb 1 12:21:47 1999 Catherine Moore <clm@cygnus.com>
+
+ * targets.c (bfd_target_vector): Add bfd_elf32_littlearm_oabi_vec
+ and bfd_elf32_bigarm_oabi_vec.
+
+Mon Feb 1 11:46:31 1999 Catherine Moore <clm@cygnus.com>
+
+ * Makefile.am (elf32-arm-oldabi.lo): New.
+ (elf32-arm-newabi.lo): New.
+ * Makefile.in: Regenerate.
+ * config.bfd (thumb-*-elf): Remove definition of targ_underscore.
+ (arm-*-elf): Likewise.
+ (arm-*-oabi): New.
+ (thumb-*-oabi): New.
+ * configure: Regenerate.
+ * configure.in (bfd_elf32_littlearm_oabi_vec): New.
+ (bfd_elf32_bigarm_oabi_vec): New.
+ * elf32-arm-newabi.c: New.
+ * elf32-arm-oldabi.c: New.
+ * elf32-arm.c: Removed.
+ * elf32-arm.h: New.
+
+Mon Feb 1 11:52:12 1999 Frank Ch. Eigler <fche@cygnus.com>
+
+ * binary.c (binary_set_section_contents): Omit warnings for
+ unloadable sections.
+
+1999-01-31 Michael Meissner <meissner@cygnus.com>
+
+ * config.bfd (powerpc{,le}-*-vxworks*): Add aliases to
+ powerpc{,le}-*-eabi.
+
+1999-01-29 Nick Clifton <nickc@cygnus.com>
+
+ * dwarf2.c (read_unsigned_leb128): Remove unused variables.
+ * dwarf2.c (read_signed_leb128): Remove unused variables.
+
+Fri Jan 29 00:47:21 1999 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (assign_file_positions_for_segments): Only adjust
+ p_align when needed.
+
+Thu Jan 28 20:05:22 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * binary.c (binary_set_section_contents): Don't return early for a
+ non-loadable section, in case the first section is non-loadable.
+ Don't set the low lma for a SEC_NEVER_LOAD section. From Maciej
+ W. Rozycki <macro@ds2.pg.gda.pl>.
+
+1999-01-28 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_reloc_map): Add R_FR30_GNU_VTINHERIT and
+ R_FR30_GNU_VTENTRY relocs.
+
+Thu Jan 28 11:08:16 1999 Catherine Moore <clm@cygnus.com>
+
+ * elflink.h (elf_link_output_sym): Zero syms which are
+ part of sections which have been excluded.
+
+Wed Jan 27 13:35:35 1999 Stan Cox <scox@cygnus.com>
+
+ * coff-arm.c (_bfd_coff_arm_set_private_flags): Changed F_PIC
+ to F_PIC_INT.
+ * coffcode.h (coff_set_arch_mach_hook): Removed F_ARM_2a and
+ F_ARM_3M labels. Changed F_PIC to F_PIC_INT.
+
+1999-01-27 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_howto_table): Fix name of R_FR30_48
+ relocation.
+ (fr30_final_link_relocate): Use computed value as result of
+ relocation.
+
+1999-01-26 Frank Ch. Eigler <fche@cygnus.com>
+
+ * binary.c (binary_set_section_contents): Emit warning for
+ huge file offsets due to widely-dispersed section LMAs.
+
+Mon Jan 18 03:35:35 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): If not D_PAGED,
+ align first section to largest section alignment, not first
+ section alignment.
+
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Require autoconf 2.12.1 or higher.
+
+Tue Dec 22 15:21:41 1998 Catherine Moore <clm@cygnus.com>
+
+ * archures.c (bfd_mach_i386_i386_intel_syntax): Define.
+ * bfd-in2.h: Likewise.
+ * cpu-i386.c (bfd_i386_arch_intel_syntax): New.
+
+1998-12-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * archures.c,bfd-in2.h (bfd_mach_mips4111): New.
+ * cpu-mips.c: Add support for and independent 4111.
+ * elf32-mips.c (elf_mips_mach): E_MIPS_MACH_4111 -> bfd_mach_mips4111.
+ (_bfd_mips_elf_final_write_processing):
+ bfd_mach_mips4111 -> E_MIPS_ARCH_3 | E_MIPS_MACH_4111.
+
+1998-12-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (elf_mips_abi_name): New.
+ (_bfd_mips_elf_merge_private_bfd_data): Compare EF_MIPS_ABI flags.
+
+1998-12-12 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing):
+ Handle bfd_mach_mips4300.
+
+1998-12-11 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf32-i386.c: Remove leaked development code from patch
+ 1998-12-10 by Richard Henderson.
+
+1998-12-10 Richard Henderson <rth@cygnus.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Don't fail relocations
+ in debug sections for symbol defined externally.
+
+Thu Dec 10 10:58:38 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * targets.c (bfd_target_vector): Remove duplicate entry for
+ tekhex_vec.
+
+1998-12-09 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_howto_table): Set src_mask fields to 0
+ since we are using RELAs.
+
+Tue Dec 8 22:15:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ SCO Open Server Release 5 core file support, from Jouke Numan
+ <jnuman@hiscom.nl>:
+ * sco5-core.c: New file.
+ * configure.in (i[3456]86-*-sco3.2v5*): Use sco5-core.lo.
+ (sco5-core.lo): Define SCO5_CORE in COREFLAG.
+ * Makefile.am: Rebuild dependencies.
+ (OPTIONAL_BACKENDS): Add sco5-core.lo.
+ (OPTIONAL_BACKENDS_CFILES): Add sco5-core.c.
+ * bfd.c (struct _bfd): Add sco5_core_data field to tdata.
+ * targets.c (sco5_core_vec): Add to target list if SCO5_CORE.
+ * bfd-in2.h, configure, Makefile.in: Rebuild.
+
+Tue Dec 8 19:38:42 1998 Mark Klein <mklein@dis.com>
+
+ * config.bfd (hppa*-*-mpeix*): New target.
+ * configure.in: Add AC_HEADER_DIRENT.
+ (hppa*-*-mpeix*): New target.
+ * configure.host (hppa*-*-mpeix*): New host.
+ * hpux-core.c: Check HOST_HPPAMPEIX. Use HAVE_DIRENT_H and
+ friends rather than just including <sys/dir.h>.
+ * som.h (struct som_symbol): Add hppa_priv_level and apto
+ tc_data. Change all users.
+ (struct somdata): Add comp_unit field.
+ (obj_som_compilation_unit): Define.
+ (bfd_som_attach_compilation_unix): Declare.
+ * som.c: Check HOST_HPPAMPEIX.
+ (struct som_misc_symbol_info): Add new field priv_level.
+ (som_object_setup): Add current_offset parameter. Change all
+ callers.
+ (setup_sections): Likewise.
+ (som_object_p): For EXECLIBMAGIC, read the lst header.
+ (som_write_symbol_strings): Add compilation_unit parameter.
+ Change all callers.
+ (som_finish_writing): Write out compilation_unit.
+ (som_bfd_derive_misc_symbol_info): Set priv_level.
+ (som_build_and_write_symbol_table): Set xleast field to 3.
+ (som_slurp_symbol_table): Set symbol priv_level.
+ (bfd_som_attach_compilation_unit): New function.
+ (som_bfd_ar_write_symbol_stuff): Set xleast field to 3. Set
+ priv_level into symbol_value.
+ * configure, config.in: Rebuild.
+
+Tue Dec 8 16:21:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * hpux-core.c (hpux_core_core_file_p): Change call to nonexistent
+ warning function to call _bfd_error_handler instead.
+
+ * libbfd.c (COERCE32): Cast through unsigned long and long to
+ avoid bug in old version of gcc.
+
+ * elf64-alpha.c (elf64_alpha_additional_program_headers): Remove.
+ (elf_backend_additional_program_headers): Don't define.
+
+1998-12-08 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_final_link_relocate): Fix PC relative
+ relocations to include offset of 2 included in the insns, and the
+ offset of the relocs within the section.
+
+Wed Dec 2 15:03:59 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by David Taylor
+ <taylor@texas.cygnus.com>, Edith Epstein
+ <eepstein@sophia.cygnus.com>, Jim Blandy
+ <jimb@zwingli.cygnus.com>, and Elena Zannoni
+ <ezannoni@kwikemart.cygnus.com> as part of the project to merge in
+ changes originally made by HP; HP did not create ChangeLog
+ entries.
+
+ * aclocal.m4, configure, Makefile.in: Rebuilt using latest
+ automake macro library.
+
+ * hpux-core.c (hpux_core_core_file_p): this function now
+ understands HPUX 10.30 thread info. Yes, the thread stacks can be
+ found in the corefile! Also, in hpux_core_core_file_p, if we
+ encounter a section with an unknown type, don't punt. Instead,
+ just skip it. Also, count the number of sections of known type
+ that we encounter. If we encounter at least one good one, then
+ we'll declare that the file is a core file. If we encounter any
+ unknown ones but some known ones, then we'll issue a warning (but
+ still declare it to be a core file). Also, correctly decide when a
+ file is not a core.
+ (PROC_INFO_HAS_THREAD_ID): define if CORE_ANON_SHMEM defined.
+ (CORE_ANON_SHMEM): define if not defined.
+ (hpux_core_struct): add members lwpid and user_tid.
+ (core_kernel_thread_id, core_user_thread_id): new macros.
+ (make_bfd_asection): use bfd_alloc to allocate room for a copy of
+ the name before storing it in the bfd.
+ (hpux_core_core_file_p): handle threads.
+
+ * libhppa.h (GET_FIELD): protect against redefinition.
+ (HPPA_WIDE): define.
+ (GET_FIELD): define.
+ (GET_BIT): define.
+ (MASK): define.
+ (CATENATE): define.
+ (ELEVEN): define.
+ (sign_extend): redefine.
+ (assemble_6): define.
+ (assemble_12): rewrite.
+ (assemble_16): define.
+ (assemble_16a): define.
+ (assemble_17): rewrite.
+ (assemble_22): define.
+
+1998-12-07 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_final_link_relocate): Using signed
+ relocations for signed values.
+
+Sun Dec 6 16:30:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * mipsbsd.c (MY(set_arch_mach)): Make static.
+ * aoutx.h (NAME(aout,machine_type)): For bfd_arch_mips, use
+ bfd_mach_mips* macros rather than simple numbers.
+
+ COFF weak symbol support, based on patches from Mark Elbrecht
+ <snowball3@usa.net>:
+ * coffcode.h (coff_slurp_symbol_table): Handle C_WEAKEXT.
+ * coffgen.c (coff_renumber_symbols): Handle weak symbols.
+ (coff_write_alien_symbol): Likewise.
+ * cofflink.c (coff_link_check_ar_symbols): Likewise.
+ (coff_link_add_symbols): Likewise.
+ (_bfd_coff_link_input_bfd): Likewise.
+ (_bfd_coff_write_global_sym): Likewise.
+
+ * elf.c (copy_private_bfd_data): Always initialize the
+ includes_phdrs field.
+
+ * elflink.h (elf_fix_symbol_flags): Check for case where a non-ELF
+ file defines a symbol first mentioned in an ELF file.
+
+ * bfd-in.h: Always define BFD_HOST_64_BIT and BFD_HOST_U_64_BIT if
+ possible, rather than only if BFD64.
+ * elflink.h (compute_bucket_count): Just check BFD_HOST_U_64_BIT,
+ not __GNUC__.
+ * bfd-in2.h: Rebuild.
+
+ * srec.c (srec_set_section_contents): Correct test to avoid
+ switching to 4 byte addresses after seeing a second section which
+ requires 3 byte addresses. From Joel Schantz
+ <joel.schantz@argosys.boeing.com>.
+
+ * config.bfd (m68*-*-gnu*): New target. From Aymeric Vincent
+ <aymeric.vincent@emi.u-bordeaux.fr>.
+
+1998-12-04 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data): Fix logic to
+ decide whether the output file is -mrelocatable-lib,
+ -mrelocatable, or neither. (gdb.base/nodebug.exp)
+
+1998-12-03 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c: Add support for R_FR30_48 reloc.
+ * reloc.c: Add BFD_RELOC_FR30_48 relocation.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate
+
+Wed Dec 2 00:58:37 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_adjust_dynamic_symbol): Warn on an attempt to
+ link against a dynamic symbol with no type or size.
+
+1998-12-01 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf32-i386.c (i386_check_relocs) [R_386_32]: Don't emit
+ relocation for section which does not get loaded.
+ (elf_i386_relocate_section) [R_386_32]: Likewise.
+
+Tue Dec 1 11:33:33 1998 Jim Wilson <wilson@cygnus.com>
+
+ * coff-h8300.c (h8300_bfd_link_add_symbols): Make reloc_size,
+ reloc_count and i long instead of unsigned long. Handle error
+ return from bfd_canonicalize_reloc.
+
+1998-12-01 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_relocate_section): Detect the absence of
+ a hash table.
+
+Mon Nov 30 15:28:09 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * elf32-sh.c (elf/sh.h): Include.
+ sh_reloc_type: Delete. Changed all references to elf_sh_reloc_type.
+ (sh_elf_howto_tab): Add HOWTO for R_SH_SWITCH8.
+ (sh_reloc_map): Map BFD_RELOC_8_PCREL to R_SH_SWITCH8.
+ (sh_elf_relax_delete_bytes): Handle R_SH_SWITCH8.
+ * Makefile.in: Add dependency of elf32-sh.lo on $(INCDIR)/elf/sh.h.
+
+Fri Nov 27 17:51:38 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elflink.h (compute_bucket_count): Don't allow minsize==0, it
+ causes division by zero later on.
+
+Thu Nov 26 11:19:35 1998 Dave Brolley <brolley@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_pc9_reloc,fr30_elf_pc12_reloc): Not
+ needed.
+
+1998-11-25 DJ Delorie <dj@cygnus.com>
+
+ * coff-i386.c (i3coff_object_p): Remove hack. Use new emulation
+ hook now.
+
+Tue Nov 24 10:25:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_relocate_section): Call
+ fr30_final_link_relocate.
+ (fr30_final_link_relocate): New function: Handle I20 and I32
+ relocs.
+ (fr30_elf_i32_reloc): New function: Handle I32 relocs.
+ (fr30_elf_pc9_reloc): New function: Handle 9_PCREL relocs.
+ (fr30_elf_pc12_reloc): New function: Handle 12_PCREL relocs.
+
+ * elf32-v850.c (v850_elf_relocate_section): Reset hi16s reloc
+ chain to empty.
+
+ The following changes are based on a patch submitted by Gianluca
+ Moro <glctr@abc.it>:
+
+ (v850_elf_perform_relocation): Only update a hi16s reloc if it has
+ not already been updated.
+ (find_remembered_hi16s_reloc): New parameter 'already_found'
+ returns state of remembered hi16s reloc.
+ (remember_hi16s_reloc): Set 'found' field to false.
+ (hi16s_location): Add 'found' field.
+
+1998-11-23 DJ Delorie <dj@cygnus.com>
+
+ * coff-i386.c (bfd_pe_dll_not_recognized_hack): the linker wants
+ to see .DLL files as unrecognized.
+ (i3coff_object_p): Sorry, had to hack it to not recognize these
+ files (pei-i386) on request.
+
+1998-11-23 DJ Delorie <dj@cygnus.com>
+
+ * opncls.c (bfd_make_readable): need more cleanup for symbols and
+ relents. Call bfd_check_format to reinitialize.
+
+Fri Nov 20 14:21:36 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_elf_relocate_section): Remove spurious
+ warnings.
+
+Thu Nov 19 14:42:15 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * aclocal.m4: regenerate
+ * configure: regenerate
+
+Tue Nov 17 20:23:35 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Add vtable_entries_size.
+ * elf.c (_bfd_elf_link_hash_newfunc): Clear it.
+ * elflink.h (elf_gc_propagate_vtable_entries_used): Copy it, and
+ respect it as an upper bound on what memory to reference.
+ (elf_gc_smash_unused_vtentry_relocs): Likewise.
+ (elf_gc_record_vtentry): Handle as-yet undefined vtables. Set and
+ update vtable_entries_size appropriately.
+
+Tue Nov 17 15:28:31 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-fr30.c (fr30_reloc_type_lookup): Used integers to hold
+ reloc number.
+
+Mon Nov 16 22:19:21 1998 DJ Delorie <dj@cygnus.com>
+
+ * archive.c (bfd_ar_hdr_from_filesystem): support BFD_IN_MEMORY
+ bfds; they have no "file" so we fake it.
+ * bfd-in2.h: add bfd_make_writable and bfd_make_readable (regen)
+ * libbfd.c (bfd_write): Allow writing to BFD_IN_MEMORY bfds by
+ resizing the memory buffer.
+ * opncls.c (bfd_make_writable): New function; lets you write a
+ bfd_create'd bfd to an in-memory buffer.
+ (bfd_make_readable): New function; lets you read back that buffer
+ as if it were from bfd_openr. Used to build generated archive
+ members (winsup's ld's dlltool)
+
+Mon Nov 16 19:15:19 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/bfd.pot: Regenerated.
+
+Mon Nov 16 10:57:06 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (hi16s_location): Replaced fixed size array with
+ linked list.
+
+Sun Nov 15 20:28:25 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Search for the proper
+ element of the gotentry list for local symbols too.
+ (elf64_alpha_relocate_section): Unify local and global handling.
+ Assert that gotent->use_count > 0.
+
+Sat Nov 14 15:16:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (vms_alpha_vec): Rename from evax_alpha_vec, and
+ update for file name changes of July 2, 1998.
+ (vms_vax_vec): New.
+ * configure: Rebuild.
+
+Thu Nov 12 19:19:54 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/bfd.pot: Regenerated.
+
+Tue Nov 10 16:17:06 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * acinclude.m4, config.bfd: detect cygwin* instead of cygwin32*.
+ * aclocal.m4, configure: regenerate
+
+Tue Nov 10 15:13:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (prep_headers): Add support for bfd_arch_fr30.
+
+Tue Nov 10 13:37:36 1998 Felix Lee <flee@cygnus.com>
+
+ * acinclude.m4 (BFD_HAVE_SYS_PROCFS_TYPE,
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER): didn't define macro when value
+ was cached.
+ * aclocal.m4, configure: regenerated.
+
+Tue Nov 10 14:31:01 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-d10v.c (reloc_type): Add R_D10V_GNU_VTINHERIT and
+ R_D10V_GNU_VTENTRY relocs.
+ (elf_d10v_howto_table): Likewise.
+ (d10v_reloc_map d10v_reloc_map): Likewise.
+ (elf32_d10v_gc_mark_hook): New.
+ (elf32_d10v_gc_sweep_hook): New.
+ (elf32_d10v_check_relocs): New.
+ (elf32_d10v_relocate_section): New.
+ (elf_backend_relocate_section): Define.
+ (elf_backend_can_gc_sections): Define.
+
+Sat Nov 7 18:07:51 1998 Peter Schauer <peter.schauer@regent.e-technik.tu-muenchen.de>
+
+ * Makefile.am (BFD32_BACKENDS): Move vms files here...
+ (BFD64_BACKENDS): ...from here.
+ (BFD32_BACKENDS_CFILES): Move vms files here...
+ (BFD64_BACKENDS_CFILES): ...from here.
+ * Makefile.in: Rebuild.
+
+Wed Nov 4 15:58:48 1998 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Add FR30 target.
+ * Makefile.in: Add FR30 target.
+ * archures.c: Add support for FR30.
+ * config.bfd: Add support for FR30.
+ * configure.in: Add support for FR30.
+ * reloc.c: Add support for FR30 relocations.
+ * targets.c: Add support for FR30 relocations.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * cpu-fr30.c: New file.
+ * elf32-fr30.c: New file.
+
+Mon Nov 2 14:59:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Sun Nov 1 19:32:28 1998 Jeffrey A Law (law@cygnus.com)
+
+ * elf-m10300.c (mn10300_elf_relax_section): Do not use alloca,
+ use bfd_malloc and free instead and check return value from bfd_malloc.
+
+Sun Nov 1 16:20:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd-in.h (_bfd_dwarf1_find_nearest_line): Declare.
+ * libbfd.h: Rebuild.
+
+ * elf32-mips.c (mips_elf_dynsym_sec_names): Comment out.
+ (SIZEOF_MIPS_DYNSYM_SECNAMES): Likewise.
+ (MIPS_TEXT_DYNSYM_SECN): Likewise.
+ (_bfd_mips_elf_fake_sections): Don't set sh_info field of a .hash
+ section.
+ (struct mips_elf_link_hash_table): Remove dynsym_sec_strindex
+ field.
+ (mips_elf_link_hash_table_create): Don't initialize
+ dynsym_sec_strindex.
+ (mips_elf_gc_mark_hook): Add default case to avoid warning.
+ (mips_elf_size_dynamic_sections): Generate a section symbol for
+ every output section.
+ (mips_elf_finish_dynamic_sections): Count all sections for
+ DT_MIPS_UNREFEXTNO.
+ (mips_elf_finish_dynamic_sections): Use dynamic symbols for all
+ output sections.
+
+Sun Nov 1 12:46:53 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Allocate two slots
+ for later PLT entries in large PLTs.
+ (ppc_elf_finish_dynamic_symbol): Allow for the extra slots.
+
+Sat Oct 31 20:10:09 1998 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-ppc.c (ppc_elf_reload_section): Fix typo.
+
+1998-10-26 15:58 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Add new field elf_hash_value.
+ * elflink.h (elf_collect_hash_codes): New function. This function is
+ called for each exported symbol and we compute the ELF hash value for
+ it.
+ (compute_bucket_value): New function. It is called from
+ size_dynamic_sections to determine the hash table size. When we are
+ optimizing a better, but slower, algorithm is used.
+ (size_dynamic_sections): Call compute_bucket_value.
+
+ * elf.c (bfd_elf_hash): Optimize the hash function a bit.
+
+Mon Oct 19 20:03:21 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-sh.c: Add HOWTO entries for R_SH_GNU_VTINHERIT and
+ R_SH_GNU_VTENTRY.
+ (sh_elf_gc_mark_hook): New.
+ (sh_elf_gc_sweep_hook): New.
+ (sh_elf_check_relocs): New.
+ (elf_backend_can_gc_sections): Define.
+
+Mon Oct 19 16:57:05 1998 Felix Lee <flee@cygnus.com>
+
+ * acinclude.m4: undo previous gettext change
+ * aclocal.m4: rebuild with right version of aclocal.
+
+Mon Oct 19 01:47:21 1998 Felix Lee <flee@cygnus.com>
+
+ * acinclude.m4, aclocal.m4: move gettext-related fragments from
+ aclocal.m4 to acinclude.m4, so they don't get lost.
+
+ * elfcore.h: rewrite for better corefile support.
+ * elf.c (elfcore_*): new functions.
+ * elf-bfd.h (elf_obj_tdata): new structure members.
+ * acconfig.h, acinclude.m4, configure.in: add feature-tests for
+ flavor of procfs.
+ * aclocal.m4, config.in, configure, Makefile.in: regenerated.
+
+Fri Oct 16 14:07:45 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-m32r.c: Add HOWTO entries for R_M32R_GNU_VTINHERIT
+ and R_M32R_GNU_VTENTRY.
+ (elf_backend_can_gc_sections): Define.
+ (m32r_elf_check_relocs): New.
+ (m32r_elf_gc_mark_hook): New.
+ (m32r_elf_gc_sweep_hook): New.
+ (m32r_elf_relocate_section): Handle VT relocs.
+
+Mon Oct 12 14:18:40 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (arm_relocate_section): Remove redundant test.
+
+ * bfd-in2.h (struct reloc_howto_struct): Improve comment to make
+ cleat that the 'bitsize' field is the size of the bitfield AFTER
+ relocation not before.
+
+ * elf32-m32r.c (R_M32R_18_PCREL): Fix size of bitfield.
+
+ * coff-mips.c (mips_relocate_hi): Cope with missing refhi or reflo
+ relocs.
+
+Tue Oct 6 09:20:44 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-sparc.c: Add HOWTO entries for R_SPARC_GNU_VTINHERIT and
+ R_SPARC_GNU_VTENTRY.
+ (elf32_sparc_check_relocs): Handle them.
+ (elf32_sparc_reloc_type_lookup): Likewise.
+ (elf32_sparc_relocate_section): Likewise.
+ (elf32_sparc_gc_mark_hook): New.
+ (elf32_sparc_gc_sweep_hook): New.
+
+Mon Oct 5 14:55:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_finish_writing): Perform some sanity checks when
+ writing an executable or shared library.
+
+Mon Oct 5 12:02:31 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * dwarf1.c : New file. Adds _bfd_dwarf1_find_nearest_line.
+ * configure.in (elf): Add dwarf1.lo.
+ * elf_bfd.h (elf_ob_tdata): Add dwarf1_find_line_info.
+ * elf.c (_bfd_elf_find_nearest_line): Add call to
+ _bfd_dwarf1_find_nearest_line.
+ * elf32-mips.c (_bfd_mips_elf_find_nearest_line):
+ Add call to _bfd_dwarf1_find_nearest_line.
+ * configure: Rebuilt.
+
+Mon Oct 5 10:06:22 1998 Catherine Moore <clm@cygnus.com>
+
+ * elflink.h (elf_gc_sections): Do not allow garbage
+ collection if dynamic sections have been created.
+
+Mon Oct 5 09:07:37 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-v850.c: Add HOWTO entries for R_V850_GNU_VTINHERIT and
+ R_V850_GNU_VTENTRY.
+ (v850_elf_check_relocs): Handle VTINHERIT and VTENTRY relocs.
+ (v850_elf_perform_relocation): Likewise.
+ (v850_elf_final_link_relocate): Likewise.
+ (v850_elf_relocate_section): Likewise.
+ (v850_elf_gc_sweep_hook): New routine.
+ (v850_elf_gc_mark_hook): New routine.
+ (elf_backend_can_gc_sections): Define.
+
+Mon Oct 5 09:04:25 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Don't assume
+ that dynobj exists.
+
+Sun Oct 4 23:29:34 1998 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * rs6000-core.c (rs6000coff_core_file_matches_executable_p):
+ Declare size as bfd_size_type.
+ (rs6000coff_get_section_contents): Declare count as bfd_size_type.
+
+Sun Oct 4 20:38:29 1998 Jeffrey A Law (law@cygnus.com)
+
+ * cpu-hppa.c (bfd_hppa20_arch): Define. Link it into the bfd_hppa_arch
+ structure.
+ * som.c (CPU_PA_RISC2_0): Define.
+ (_PA_RISC2_0_ID): Likewise.
+ (som_finish_writing): Use CPU_PA_RISC2_0 for the system_id as needed.
+
+Sun Oct 4 21:19:09 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): When a versioned symbol
+ has a base which is already defined, only add the referenced
+ symbol to the dynamic symbol table if it is defined or referenced
+ by a regular file.
+
+ * elf32-i386.c (elf_i386_info_to_howto_rel): Handle vtable relocs
+ correctly.
+
+1998-09-27 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elflink.h (elf_link_add_object_symbols): Undo last change.
+
+Wed Sep 23 16:09:31 1998 Richard Henderson <rth@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't record a dynamic
+ symbol for the indirect alias to a versioned symbol.
+
+Mon Sep 21 12:15:22 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-i386.c (elf32_i386_vtinherit_howto): New.
+ (elf32_i386_vtentry_howto): New.
+ (elf_i386_reloc_type_lookup): Return elf32_i386_vtentry_howto
+ or elf32_i386_vtinherit_howto on lookup.
+
+Sun Sep 20 00:48:07 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c: Include "elf/m68k.h". Remove definition of enum
+ reloc_type. Rename R_68K__max to R_68K_max.
+ (howto_table): Use _bfd_elf_rel_vtable_reloc_fn for a VTENTRY
+ reloc.
+
+Sun Sep 20 00:09:25 1998 Chris Torek <torek@bsdi.com>
+
+ * libbfd.c (bfd_getb32): Rewrite expression to get better code.
+ (bfd_getl32, bfd_getb_signed_32, bfd_getl_signed_32): Likewise.
+
+ * libbfd.c (bfd_log2): Cast to bfd_vma before shifting, not
+ after.
+
+Sat Sep 19 22:42:23 1998 Doug Rabson <dfr@nlsystems.com>
+
+ * elflink.h (elf_link_add_object_symbols): Ensure that the warning
+ message has a null byte terminator.
+
+Fri Sep 18 14:35:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_perform_relocation): Ignore contents of
+ word subject to R_V850_32 relocation.
+
+Thu Sep 17 17:20:36 1998 Nick Clifton <nickc@cygnus.com>
+
+ * dwarf2.c: Add comment describing problem computing line numbers
+ for undefined symbols at link time.
+
+Thu Sep 17 16:03:28 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_adjust_dynamic_symbol): Don't
+ transform a defweak into a plt entry.
+ (elf64_alpha_calc_dynrel_sizes): Allow room for secondary
+ plt entry references to receive a RELATIVE reloc.
+ (elf64_alpha_finish_dynamic_symbol): Fill them in.
+ (elf64_alpha_relocate_section): Assert we don't overrun
+ the allocated relocation space.
+
+Wed Sep 16 18:03:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (swap_out_syms): Always treat section symbols as
+ special, even if they are attached to a common section.
+
+Wed Sep 16 10:34:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_symbol_processing): Move symbols in
+ sections with v850 common section attributes into named v850
+ common sections.
+ (v850_elf_add_symbol_hook): Move symbols in sections with v850
+ common section attributes into named v850 common sections.
+
+Wed Sep 16 11:26:49 CDT 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.c (elf32_arm_gc_mark_hook): Remove print
+ statement.
+
+1998-09-15 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Reverse output_offset
+ part of Vladimir's change of 1998-08-19. Make a R_PPC_SDAREL16
+ reloc to the wrong section a warning, not an error. .dynsbss
+ is not an output section, so there is no need to check for it.
+
+Tue Sep 15 12:40:05 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf-bfd.h: Add argument to elf_backend_get_symbol_type.
+
+Tue Sep 15 08:34:40 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf.c (swap_out_syms): Pass type to elf_backend_get_symbol_type.
+ * elf32-arm.c: Add HOWTO entries for R_ARM_GNU_VTINHERIT and
+ R_ARM_GNU_VTENTRY.
+ (elf32_arm_gc_mark_hook): New.
+ (elf32_arm_gc_sweep_hook): New.
+ (elf32_arm_check_relocs): New.
+ (elf32_arm_final_link_relocate): Handle VTINHERIT and VTENTRY
+ relocations.
+ (elf32_arm_relocate_section): Handle VTINHERIT and VTENTRY
+ relocations.
+
+1998-09-10 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): If dynobj is NULL,
+ assume there is no PLT or GOT.
+
+Wed Sep 9 14:24:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.c (elf32_arm_find_nearest_line): New function: just
+ like _elf_bfd_find_nearest_line() except that STT_ARM_TFUNC is
+ also accepted as a function symbol type.
+
+Mon Sep 7 13:24:03 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * rs6000-core.c (_LONG_LONG): Define for AIX 4.x only.
+
+Sat Sep 5 20:40:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd-in.h (_bfd_nolink_bfd_gc_sections): Correct definition to
+ match definition of _bfd_gc_sections field.
+ * libbfd.h: Rebuild.
+
+Fri Sep 4 13:54:23 1998 David Miller <davem@dm.cobaltmicro.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Properly adjust
+ the addend of a dynamic relocation referencing a section.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ (sparc64_elf_finish_dynamic_symbol): Fix the PLT relocation offset.
+
+Thu Sep 3 17:28:50 1998 Richard Henderson <rth@cygnus.com>
+
+ * elflink.h (bfd_elfNN_size_dynamic_sections): Verify that the
+ bed has a size_dynamic_sections routine before trying to use it.
+
+Mon Aug 31 14:49:22 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf32-mips.c (elf_mips_gnu_vtentry_howto): Use
+ _bfd_elf_rel_vtable_reloc_fn.
+
+Mon Aug 31 10:23:40 1998 Catherine Moore <clm@cygnus.com>
+
+ * Makefile.am: Add elf32-arm.c.
+ * Makefile.in: Rebuild.
+ * elf-bfd.h: Add elf_backend_get_symbol_type.
+ * elf.c (swap_out_syms): If defined, call
+ elf_backend_get_symbol_type.
+ * elf32-arm.c: Define elf_backend_get_symbol_type.
+ (elf32_arm_get_symbol-type): New routine.
+ (record_thumb_to_arm_glue): Change to use STT_ARM_TFUNC.
+ (bfd_elf32_arm_process_before_allocation): Change to
+ check for STT_ARM_TFUNC.
+ (elf32_arm_final_link_relocate): Likewise.
+ * elfxx-target.h: Add elf_backend_get_symbol_type.
+
+Fri Aug 28 19:44:07 1998 Richard Henderson <rth@cygnus.com>
+
+ * archures.c (bfd_mach_alpha_ev[456]): New.
+ * cpu-alpha.c: Rework to match these types.
+ * bfd-in2.h: Rebuild.
+
+Fri Aug 28 19:38:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (_bfd_elf_rel_vtable_reloc_fn): Declare.
+ * elf.c (_bfd_elf_rel_vtable_reloc_fn): New.
+
+ * elf32-i386.c (elf_howto_table): Add vtable relocs.
+ (elf_i386_reloc_type_lookup): Recognize them.
+ (elf_i386_check_relocs): Pass them off to generic code.
+ (elf_i386_relocate_section): Ignore them.
+ (elf_i386_gc_mark_hook, elf_i386_gc_sweep_hook): New.
+ (elf_backend_can_gc_sections): True.
+
+Thu Aug 20 15:03:45 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.c (elf32_thumb_to_arm_stub): Check sym_sec is not NULL
+ before looking at owner field.
+ (elf32_arm_to_thumb_stub): Ditto.
+ (elf32_arm_relocate_section): Compute name before calling
+ elf32_arm_final_link_relocate().
+
+Thu Aug 20 11:30:17 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * elf.c: comment and formatting cleanups.
+ * elfcore.h: ditto.
+
+Wed Aug 19 15:43:26 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * elfcode.h (elf_object_p): Reject files of header type ET_CORE
+ (core files are treated differently than object files).
+ * elf-bfd.h (_bfd_elf_write_corefile_contents,
+ bfd_elf_mkcorefile): declare.
+ * elfxx-target.h (_bfd_elf_write_corefile_contents,
+ bfd_elf_mkcorefile): add to bfd_target vector.
+ * elfcore.h (elf_core_file_p): save the program header table,
+ and set the bfd architecture from the elf file header.
+ * elf.c (bfd_elf_mkcorefile): new function.
+ (_bfd_elf_write_corefile_contents): new function.
+ (assign_file_positions_for_segments): add cases for handling
+ PT_NOTE segments. (assign_file_positions_except_relocs):
+ core files should be handled the same as exec files.
+ (prep_headers): identify core files as type ET_CORE.
+ (copy_private_bfd_data): identify the sections belonging to
+ the PT_NOTE segment.
+
+ * elf32-sparc.c (elf32_sparc_final_write_processing):
+ add break statement to default case.
+
+1998-08-19 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Check that output
+ section (not input) will be in sections ".sbss", ".sbss2",
+ ".sdata", and ".sdata" for R_PPC_SDAREL16, R_PPC_EMB_SDA2REL,
+ R_PPC_EMB_SDA21, R_PPC_EMB_RELSDA. In all these cases also ignore
+ output_offset for correct evaluation of addend.
+
+Tue Aug 18 11:48:12 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.c: Add prefix bfd_ to elf32_arm_get_bfd_for_interworking,
+ elf32_arm_allocate_interworking_sections and
+ elf32_arm_process_before_allocation.
+
+Tue Aug 18 11:46:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * bfd-in.h: Ammend prototype for
+ elf32_arm_process_before_allocation to remove surplus third
+ argument.
+
+ * bfd-in2.h: Regenerate.
+
+Sat Aug 15 20:55:08 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Handle indirect symbols.
+
+Fri Aug 14 09:12:28 1998 Stan Cox <scox@cygnus.com>
+
+ * aoutx.h (aout_link_input_section_ext): Use the relocation already
+ calculated for RELOC_SPARC_REV32 case.
+
+Thu Aug 13 14:02:02 1998 Catherine Moore <clm@cygnus.com>
+
+ * bfd-in.h: Add prototypes for elf32_arm_get_bfd_for_interworking,
+ elf32_arm_allocate_interworking_sections and
+ elf32_arm_process_before_allocation.
+ * bfd-in2.h: Regenerated.
+ * elf32-arm.c Define elf32_arm_link_hash_table.
+ (insert_thumb_branch): New routine.
+ (find_thumb_glue): New routine.
+ (find_arm_glue): New routine.
+ (record_arm_to_thumb_glue): New routine.
+ (record_thumb_to_arm_glue): New routine.
+ (elf32_arm_link_hash_table_create): New routine.
+ (elf32_arm_get_bfd_for_interworking): New routine.
+ (elf32_arm_allocate_interworking_sections) New routine.
+ (elf32_arm_process_before_allocation) New routine.
+ (elf32_thumb_to_arm_stub): New routine.
+ (elf32_arm_to_thumb_stub): New routine.
+ (elf32_print_private_bfd_data): Fix typo.
+ (elf32_arm_final_link_relocate): Add argument sym_sec.
+ Check for branches to thumb symbols in case R_ARM_PC24.
+ Check for branches to arm symbols in case R_ARM_THM_PC22.
+ (elf32_arm_relocate_section): Pass symbol section to
+ elf32_arm_final_link_relocate.
+
+Wed Aug 12 19:00:39 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Generate PLT
+ entries unless the symbol is defined in the executable; in
+ particular, undefined weak symbols get a PLT entry.
+
+Wed Aug 12 14:48:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * libaout.h: Remove nested comment to avoid warning.
+
+Wed Aug 12 08:10:11 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Rework
+ R_ARM_PC24 relocation.
+
+Tue Aug 11 14:42:26 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Remove unused
+ argument is_local. Add argument sym_flags. Check sym_flags
+ in R_ARM_ABS32 case. Include addend for R_ARM_THM_PC22 case.
+ (elf32_arm_relocate_section): Don't pass local sym and pass
+ sym_flags to elf32_arm_final_link_relocate.
+
+Mon Aug 10 20:38:39 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_calc_dynrel_sizes): Correct last change
+ to not count too few relocs for dynamicly linked executables.
+
+Mon Aug 10 15:35:34 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Never consider
+ symbols without a dynamic index dynamic. Consider all weak
+ symbols dynamic.
+ (elf64_alpha_strip_section_from_output): Don't assume 1-1
+ correspondance between input and output sections.
+
+Mon Aug 10 15:31:39 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elflink.h (elf_gc_common_finalize_got_offsets): For backends
+ that use a .got.plt section start the got offset at zero.
+
+Mon Aug 10 17:31:21 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_write_processor): Correct the processor ID written
+ out for bfd_arch_m68k, accommodating change of March 25.
+
+Sun Aug 9 20:55:44 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Rework
+ R_ARM_THM_RPC22 relocations.
+
+Sat Aug 8 15:15:30 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Undef weak symbols
+ are always dynamic.
+ (elf64_alpha_calc_dynrel_sizes): Allow enough room for RELATIVE
+ .got relocs in -Bsymbolic shared objects.
+
+Wed Aug 5 15:48:08 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.c: Add private flags to ELF header.
+ (elf32_arm_print_private_bfd_data): New Function.
+ (elf32_arm_set_private_flags): New Function.
+ (elf32_arm_copy_private_flags): New Function.
+ (elf32_arm_merge_private_bfd_data): New Function.
+
+Mon Aug 3 17:10:15 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_check_relocs): Permit WPLT30 against
+ a local symbol.
+ (elf32_sparc_relocate_section): Likewise.
+
+Sun Aug 2 03:19:23 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Init sgot to NULL. Create the
+ .got if any relocation referrs to _GLOBAL_OFFSET_TABLE_.
+ (ppc_elf_relocate_section): Pull sgot and splt search to the start
+ of the function. Recognize no .plt as static linking.
+
+1998-08-01 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_section_from_shdr): Don't pass
+ ".liblist" string through gettext.
+
+Fri Jul 31 16:38:14 1998 Catherine Moore <clm@cygnus.com>
+
+ * Makefile.am: Add support for elf32-arm.lo.
+ * Makefile.in: Rebuild.
+ * config.bfd (arm-*-elf): Define targ_defvec and targ_selvecs.
+ (thumb-*-elf): Define targ_defvec and targ_selvecs.
+ * configure.in: Handle bfd_elf32_littlearm_vec and bfd_elf32_bigarm_vec.
+ * configure: Regenerate.
+ * elf.c: (prep_headers): Support arch_type of EM_ARM.
+ * targets.c: Support new targets bfd_elf32_bigarm_vec and
+ bfd_target bfd_elf32_littlearm_vec.
+ * elf32-arm.c: New file.
+
+Tue Jun 28 19:05:28 1998 Stan Cox <scox@cygnus.com>
+
+ * libaout.h (M_SPARCLITE_LE): New machine.
+ * sunos.c (MACHTYPE_OK): Add machine M_SPARCLITE_LE.
+ * aoutf1.h (sunos_set_arch_mach): Add machine M_SPARCLITE_LE.
+ (sunos_write_object_contents): Add machine bfd_mach_sparc_sparclite_le
+ * aoutx.h (howto_table_ext): Add relocation R_SPARC_REV32.
+ (NAME(aout,machine_type)) Add machine bfd_mach_sparc_sparclite_le
+ (aout_link_input_section_ext): Add RELOC_SPARC_REV32 support.
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table, sparc_reloc_map,
+ elf32_sparc_relocate_section): Rename R_SPARC_32LE to be R_SPARC_REV32
+ * libbfd.h (bfd_reloc_code_real_names): Rename BFD_RELOC_SPARC_32LE to
+ be BFD_RELOC_SPARC_REV32.
+ * reloc.c: Ditto.
+ * config.bfd (sparc86x-*-aout): New
+
+Fri Jul 24 13:54:19 1998 Nick Clifton <nickc@cygnus.com>
+
+ * linker.c (_bfd_generic_final_link): Allocate NULL symbol before
+ actually mapping the output sections.
+
+Fri Jul 24 11:24:29 1998 Jeffrey A Law (law@cygnus.com)
+
+
+ * elf-m10300.c (mn10300_elf_howto): Add R_MN10300_24 entry.
+ (mn10300_elf_reloc_map): Similarly.
+ (mn10300_elf_final_link_relocate): Handle R_MN10300_24.
+
+Fri Jul 24 12:36:04 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (elf_mips_howto_table): Add reloc types used on
+ Irix 6.
+ (bfd_elf32_bfd_reloc_type_lookup): Add default case.
+ * elf64-mips.c: Replace all uses of mips_elf64_reloc_type with
+ elf_mips_reloc_type defined in elf/mips.h.
+
+1998-07-24 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf64-mips.c: Remove reloc_type definition completely. It's now
+ in elf/mips.h.
+
+Thu Jul 23 13:33:19 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * elf64-mips.c (mips_elf64_reloc_type): #if 0 out more relocations
+ as they are defined in elf/mips.h now.
+
+Thu Jul 23 11:29:43 1998 Jeffrey A Law (law@cygnus.com)
+
+
+ * Re-add lost change:
+ * elf-m10300.c (elf32_mn10300_link_hash_entry): Add new field
+ "movm_stack_size".
+ (mn10300_elf_relax_section): Include stack space for register saves
+ in the imm8 field of a "call" instruction.
+ (compute_function_info): Determine how much stack is allocated by
+ the movm instruction. Fix typo.
+ (elf32_mn10300_link_hash_newfunc): Initialize movm_stack_size.
+
+Thu Jul 23 11:38:05 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf_backend_got_header_size): Define as 4.
+ * elf64-sparc.c (elf_backend_got_header_size): Define as 8.
+
+1998-07-22 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf32-ppc.c: Change use of pp_reloc_type to elf_ppc_reloc_type.
+
+Wed Jul 22 16:27:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-hppa.h: Let ELF header define the enum containing the
+ external reloc numbers.
+ * elf32-i386.h: Likewise.
+
+1998-07-22 14:57 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf-m10300.c: Let ELF header now define the macros to get the enum.
+ * elf32-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+
+Wed Jul 22 13:53:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * bfd-in2.h: Change type of 'class' parameter to 'unsigned int' in
+ bfd_coff_set_symbol_class(), in order to avoid K&R compatability
+ prblems.
+ * bfd-in.h: Regenerate.
+ * coffgen.c (bfd_coff_set_symbol_class): Change type of 'class'
+ parameter to 'unsigned int' to avoid K&R compatability problems.
+
+Wed Jul 22 16:43:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_find_nearest_line): Change filename_ptr and
+ functionname_ptr to be const. Change line_ptr to be unsigned.
+
+ * coffcode.h (coff_link_output_has_begun): Simplify handling when
+ macro is not defined. Change second parameter from bfd_link_info
+ to coff_final_link_info. Add prototype.
+ (coff_final_link_postscript): Simplify handling when macro is not
+ defined. Add prototype.
+
+1998-07-22 13:08 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf-mn10300.c: Before include system specific ELF header define
+ START_RELOC_NUMBERS, RELOC_NUMBER, and END_RELOC_NUMBERS.
+ * elf32-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+
+Wed Jul 22 13:46:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf64-mips.c (mips_elf64_reloc_type): Copy Ulrich's elf32-mips.c
+ temporary patch over to elf64-mips.c as well.
+
+1998-07-21 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf32-mips.c (reloc_type): Temporarily disable definition of
+ standard relocation since they are now defined in elf/mips.h.
+
+Tue Jul 21 09:47:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf-m10200.c (mn10200_elf_final_link_relocate):
+ Modify range test for case R_MN10200_8.
+
+ * elf-m10300.c (mn10300_elf_final_link_relocate):
+ Modify range test for case R_MN10300_8.
+
+Mon Jul 20 18:50:54 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add got_ & plt_header_size.
+ * elf32-i386.c (elf_backend_got_header_size): Define.
+ (elf_backend_plt_header_size): Define.
+ * elf32-m68k.c, elf32-mips.c, elf32-ppc.c: Likewise.
+ * elf32-sparc.c, elf64-alpha.c, elf64-sparc.c: Likewise.
+ * elfxx-target.h: Provide a default of zero.
+ * elflink.c (_bfd_elf_create_got_section): Use got_header_size.
+ * elflink.h (elf_gc_common_finalize_got_offsets): Likewise.
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Don't remove a PLT
+ entry from an executable, even if the plt refcount goes to 0.
+
+Mon Jul 20 12:47:26 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Also remember the
+ directory name at the line number.
+
+ * elf.c (_bfd_elf_find_nearest_line): Also consider symbols
+ with an unspecified type.
+
+Wed Jul 15 11:20:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c: Add undef of valid to avoid problem on SunOS.
+
+Tue Jul 14 15:30:59 1998 Richard Henderson <rth@cygnus.com>
+
+ * config.bfd (i?86-pc-beos{pe,elf,}*): Recognize.
+
+Tue Jul 14 11:22:21 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Also reference count
+ R_68K_PCxx and R_68K_xx relocations. Make sure that
+ ELF_LINK_HASH_NEEDS_PLT is always set for a PLT reloc reference.
+ (elf_m68k_gc_sweep_hook): Also reference count R_68K_PCxx and
+ R_68K_xx relocations.
+ (elf_m68k_adjust_dynamic_symbol): Reset the plt offset of a symbol
+ that has no plt entry.
+ (elf_m68k_relocate_section): Ignore the plt offset in a static
+ link.
+ * elflink.h (elf_adjust_dynamic_symbol): Reset the plt offset for
+ an ignored symbol.
+ (elf_gc_common_finalize_got_offsets): Set the got offsets also in
+ a static link.
+
+ * elf32-m68k.c (R_68K_GNU_VTINHERIT, R_68K_GNU_VTENTRY): New reloc
+ types.
+ (howto_table, reloc_map): Add entries for them.
+ (elf_m68k_check_relocs): Handle them. Implement reference
+ counting for got and plt entries.
+ (elf_m68k_gc_mark_hook, elf_m68k_gc_sweep_hook): New functions.
+ (elf_m68k_adjust_dynamic_symbol): Handle unreferenced plt
+ symbols.
+ (rtype_to_howto_rel, elf_info_to_howto_rel): Delete.
+ (elf_m68k_relocate_section): Handle the new reloc types.
+ (bfd_elf32_bfd_final_link, elf_backend_gc_mark_hook,
+ elf_backend_gc_sweep_hook, elf_backend_can_gc_sections): Define.
+ * elflink.h (elf_link_add_object_symbols): When creating an
+ indirect reference for symbol versioning also copy the plt
+ offset.
+ (elf_fix_symbol_flags): When clearing the ELF_LINK_HASH_NEEDS_PLT
+ flag also reset the plt offset.
+ (elf_link_assign_sym_version): Likewise.
+ (elf_gc_common_finalize_got_offsets): Increment the got offset by
+ the size of the entry in bytes.
+ (elf_gc_allocate_got_offsets): Likewise.
+
+Tue Jul 14 11:18:14 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_gc_sections): Return true rather than falling off
+ the bottom.
+
+ * coffgen.c (bfd_coff_set_symbol_class): Call bfd_alloc, not
+ xmalloc.
+
+Mon Jul 13 11:06:31 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c: Supress definition of TARGET_UNDERSCORE and add a
+ comment describing when it should be enabled.
+ Changed definition of USER_LABEL_PREFIX to "", to fall into line
+ with GCC sources.
+
+Mon Jul 13 13:06:54 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_slurp_external_symbols): Handle call optimization
+ information ATN records.
+
+Fri Jul 10 16:31:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_slurp_external_symbols): Select an appropriate
+ section for an absolute symbol in a fully linked file. Based on
+ patch from Christian Holland <CHolland@de.lucent.com>.
+
+Wed Jul 8 11:29:56 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * coff-m88k.c (m88k_special_reloc): Don't lose the information
+ that a symbol is undefined.
+
+Tue Jul 7 21:47:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_bfd_gc_sections): Define.
+
+Mon Jul 6 11:35:50 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (aoutarm_std_reloc_howto): Do not complain about
+ overflows in ARM_26D patches, since they have already been
+ implmented. Patch submitted by Dr. R.J. Black <rjb@dcs.gla.ac.uk>
+
+Sat Jul 4 12:25:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): If we have any long
+ section names, call coff_write_symbols even if there are no
+ symbols.
+
+Fri Jul 3 13:11:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (copy_private_bfd_data): Only set phdr_included once for a
+ PT_LOAD segment, rather than only setting it once for the entire
+ file.
+
+ * elf.c (_bfd_elf_make_section_from_shdr): When setting the LMA,
+ rather than ignoring every phdr with a p_paddr of 0, ignore all
+ the phdrs if they all have a p_paddr of 0.
+
+ * stabs.c (_bfd_write_stab_strings): Check whether the .stabstr
+ section was discarded from the link.
+
+Fri Jul 3 14:39:05 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * coff-sh.c (sh_insn_uses_freg): Ignore lowest bit of register number.
+
+Fri Jul 3 14:35:48 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * coff-sh.c (sh_insns_conflict): Load of fpscr conflicts with
+ floating point operations.
+
+Thu Jul 2 18:37:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Skip undefined global
+ function symbols.
+
+Thu Jul 2 14:59:42 1998 Klaus Kaempf <kkaempf@rmi.de>
+
+ Merge of vax/vms (read-only) support
+ * configure.com: Support Vax target.
+ * makefile.vms: Support Vax target.
+ * vms.h: Renamed from evax.h, merged vax/vms (read-only) support.
+ * vms.c: Renamed from evax-alpha.c, merged vax/vms (read-only)
+ support.
+ * vms-hdr.c: Renamed from evax-emh.c, merged vax/vms (read-only)
+ support.
+ * vms-gsd.c: Renamed from evax-egsd.c, merged vax/vms (read-only)
+ support.
+ * vms-tir.c: Renamed from evax-etir.c, merged vax/vms (read-only)
+ support.
+ * vms-misc.c: Renamed from evax-misc.c, merged vax/vms (read-only)
+ support.
+ * libbfd.c (real_read): Use unbuffered read on VMS/Vax.
+ * targets.c (bfd_target_ovax_flavour): New flavour.
+ (vms_alpha_vec): Renamed from evax_alpha_vec.
+ (vms_vax_vec): New.
+ (target_vector): Update accordingly.
+ * config.bfd (alpha*-*-*vms*): Use vms_alpha_vec, not
+ evax_alpha_vec.
+ (vax*-*-*vms*): New target.
+ * Makefile.am: Update for renamed files. Rebuild dependencies.
+ * bfd-in2.h: Rebuild.
+ * configure.in, Makefile.in, aclocal.m4: Rebuild.
+
+Thu Jul 2 13:31:55 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from Matt Semersky <matts@scd.hp.com>:
+ * linker.c (_bfd_generic_final_link): Force a trailing NULL
+ pointer on abfd->outsymbols.
+ (generic_add_output_symbol): Handle NULL sym parameter.
+
+Wed Jul 1 17:05:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (copy_private_bfd_data): Add support for changing VMA or
+ LMA of sections.
+
+Wed Jul 1 16:58:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (sh_relax_delete_bytes): Correct address comparisons
+ when handling 32 bit immediate relocs.
+ * elf32-sh.c (sh_elf_relax_delete_bytes): Likewise.
+
+Tue Jun 30 09:55:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * section.c (STD_SECTION): Account for recently added gc_mark
+ field in struct asection.
+
+ * elf-m10300.c (bfd_mn10300_elf_merge_private_bfd_data): New function.
+ (bfd_elf32_bfd_merge_private_bfd_data): Define.
+
+Thu Jun 25 18:31:41 1998 Richard Henderson <rth@cygnus.com>
+
+ ELF Section-level Garbage Collection:
+ * bfd.c (bfd_gc_sections): New.
+ * aout-adobe.c: Hook to default implementation.
+ * aout-target.h, aout-tic30.c, binary.c, bout.c: Likewise.
+ * coff-alpha.c, coff-mips.c, coff-rs6000.c, coffcode.h: Likewise.
+ * evax-alpha.c, i386msdos.c, i386os9k.c, ieee.c: Likewise.
+ * ihex.c, nlm-target.h, oasys.c, ppcboot.c, srec.c: Likewise.
+ * tekhex.c, versados.c: Likewise.
+ * libbfd-in.h (_bfd_nolink_bfd_gc_sections): New.
+ * targets.c (BFD_JUMP_TABLE_LINK): Add _bfd_gc_sections.
+
+ * reloc.c (BFD_RELOC_VTABLE_INHERIT, BFD_RELOC_VTABLE_ENTRY): New.
+ (bfd_generic_gc_sections): New.
+ * section.c (SEC_KEEP): New.
+ (asection): Add gc_mark member.
+
+ * elfcode.h (elf_gc*): New name remappings.
+ * elflink.h (elf_link_input_bfd): Don't set contents on stabs
+ sections to be excluded.
+ (elf_gc_mark, elf_gc_sweep, elf_gc_sweep_symbol): New.
+ (elf_gc_propogate_vtable_entries_used): New.
+ (elf_gc_smash_unused_vtentry_relocs): New.
+ (elf_gc_sections, elf_gc_record_vtinherit, elf_gc_record_vtentry): New.
+ (elf_gc_common_finalize_got_offsets): New.
+ (elf_gc_allocate_got_offsets, elf_gc_common_final_link): New.
+ * elfxx-target.h: Add and default gc hooks.
+
+ * elf-bfd.h (struct elf_link_hash_entry): Swap got_offset/plt_offset
+ for unions.
+ (struct elf_obj_tdata): Likewise for local_got_offsets.
+ * elf.c, elf-i386.c, elf32-m68k.c, elf32-mips.c: Update all uses.
+ * elf32-ppc.c, elf32-sparc.c, elf64-alpha.c: Likewise.
+ * elf64-sparc.c, elflink.h: Likewise.
+
+ * elf-bfd.h (struct elf_link_hash_entry): Add vtable members.
+ (ELF_LINK_HASH_MARK): Define.
+ (struct elf_backend_data): Add GC hooks.
+ * elf.c (_bfd_elf_link_hash_newfunc): Zero vtable members.
+
+ * elf-m10300.c (mn10300_elf_check_relocs): New.
+ (mn10300_elf_gc_mark_hook): New.
+ (R_MN10300_GNU_VTINHERIT, R_MN10300_GNU_VTENTRY): New.
+ (elf_mn10300_howto, mn10300_reloc_map): Handle them.
+ (mn10300_elf_final_link_relocate): Likewise.
+ (mn10300_elf_relocate_section): Likewise.
+ (elf_backend_can_gc_sections): Define.
+ * elf32-mips.c (R_MIPS_GNU_VTINHERIT, R_MIPS_GNU_VTENTRY): New.
+ (elf_mips_gnu_vtinherit_howto, elf_mips_gnu_vtentry_howto): New.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle them.
+ (mips_info_to_howto_rel): Likewise.
+ (mips_elf_relocate_section): Likewise.
+ (mips_elf_check_relocs): Likewise.
+ (mips_elf_gc_mark_hook, mips_elf_gc_sweep_hook): New.
+ (elf_backend_can_gc_sections): Define.
+ * elf32-ppc.c (R_PPC_GNU_VTINHERIT, R_PPC_GNU_VTENTRY): New.
+ (ppc_elf_howto_raw): Handle them.
+ (ppc_elf_reloc_type_lookup): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ (ppc_elf_check_relocs): Reference count .got and .plt entires.
+ Handle new vtable relocs.
+ (ppc_elf_adjust_dynamic_symbol): Recognize unused .plt entries.
+ (ppc_elf_gc_mark_hook, ppc_elf_gc_sweep_hook): New.
+ (elf_backend_can_gc_sections): Define.
+
+Fri Jun 26 10:48:23 1998 Jeffrey A Law (law@cygnus.com)
+
+ * archures.c (bfd_mach_mn10300): Define.
+ * elf-m10300.c: Include elf/mn10300.h
+ (elf_mn10300_mach): New function.
+ (_bfd_mn10300_elf_final_write_processing): Likewise.
+ (_bfd_mn10300_elf_object_p): Likewise.
+ (elf_backendfinal_write_processing): Define.
+ (elf_backend_object_p): Likewise.
+
+Thu Jun 25 18:31:08 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_perform_relocation): Fix HI16_S
+ relocation.
+
+Wed Jun 24 17:17:57 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_bfd_final_link): Loop over input_bfds using the
+ link_next field, not the next field.
+
+Sun Jun 21 19:38:39 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (map_sections_to_segments): Check the section address
+ against the phdr size both with and without a modulo of
+ maxpagesize.
+
+Fri Jun 19 17:08:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_size_dynamic_sections): Only strip a
+ linker created empty input section if the output section has the
+ same name.
+
+ * elflink.h (elf_link_output_extsym): Print an error message if
+ _bfd_elf_section_from_bfd_section fails.
+
+ * elf.c (_bfd_elf_section_from_bfd_section): Call bfd_set_error on
+ failure.
+
+Tue Jun 16 11:55:55 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (copy_private_bfd_data): Improve handling of Solaris
+ native linker output. Avoid putting an empty section in more than
+ one segment.
+
+Fri Jun 12 13:30:17 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): If maintainer mode, depend on .pot file.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+Fri Jun 12 13:34:02 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * elf.c (swap_out_syms): New arg relocatable_p.
+ Don't add section VMA to symbols for relocatable output.
+ (_bfd_elf_compute_section_file_positions): Update call to
+ swap_out_syms.
+
+Mon Jun 8 15:20:57 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_perform_relocation): Make comparisons
+ against 'addend' be signed rather than unsigned.
+
+Sat Jun 6 00:31:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-m32r.c: Add prototyps for static functions.
+
+ * coff-arm.c: Add prototypes for static functions.
+
+Fri Jun 5 17:21:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (elf_sort_sections): Sort by LMA first then VMA, since the
+ LMA is used to order sections in a segment.
+
+ * elf32-v850.c: Add prototypes for static functions.
+ Change type of addend parameter to bfd_vma in various functions.
+
+Fri Jun 5 18:09:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (howto_table_ext): Change RELOC_BASE13 to use
+ complain_overflow_signed instead of complain_overflow_bitfield.
+
+Fri Jun 5 15:11:11 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf.c (elf_map_symbols): Don't add section VMA to symbol value
+ when comparing against 0.
+
+Wed Jun 3 17:52:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (config.status): New target.
+ * Makefile.in: Rebuild.
+
+Wed Jun 3 12:18:24 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Give an
+ error if previous object endianness doesn't match current object.
+
+Tue Jun 2 17:50:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_print_private_bfd_data): Call
+ _bfd_elf_print_private)bfd_data ().
+
+Tue Jun 2 15:29:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_merge_symbol): Don't always set type_change_ok
+ and size_change_ok.
+ (elf_link_add_object_symbols): Set type_change_ok and
+ size_change_ok before calling elf_merge_symbol.
+
+ * elf32-mips.c (mips_elf_relocate_section): If we issue an
+ undefined symbol error, don't also issue an overflow error.
+
+Tue Jun 2 13:51:00 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): The target of an
+ R_PPC_LOCAL24PC relocation should be local; if not, print an error
+ message instead of crashing.
+
+Mon Jun 1 18:23:12 1998 Yuli Barcohen <yuli.barcohen@telrad.co.il>
+
+ * archures.c (bfd_mach_cpu32): Define.
+ (bfd_default_scan): Add case for 68060. Fix 68332 case to use
+ bfd_mach_cpu32.
+ * cpu-m68k.c (arch_info_struct): Add m68k:cpu32.
+ * ieee.c: Include <ctype.h>.
+ (ieee_object_p): Parse out process ID string to make it more
+ likely to be acceptable for bfd_scan_arch.
+ * bfd-in2.h: Rebuild.
+
+Mon Jun 1 11:12:02 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_print_private_bfd_data): Also call
+ _bfd_elf_print_private_bfd_data() so that the program header will
+ be displayed.
+
+Mon Jun 1 12:14:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (coff_swap_sym_in): Check for C_SECTION rather than
+ 0x68. Reindent. Add some comments.
+
+Fri May 29 09:58:08 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (copy_private_bfd_data): Adjust physical address of
+ segment in output BFD to contain LMAs of its sections.
+
+Tue May 26 19:37:47 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table, sparc_reloc_map,
+ elf32_sparc_relocate_section): Added R_SPARC_32LE for little
+ endian data 32 bit relocations.
+ (elf32_sparc_merge_private_bfd_data): Check if linking little
+ endian objects with big endian objects.
+ (elf32_sparc_object_p): Set bfd_mach_sparc_sparclite_le.
+ (elf32_sparc_final_write_processing): Set EF_SPARC_LEDATA in e_flags.
+ * libbfd.h (bfd_reloc_code_real_names): Added BFD_RELOC_SPARC_32LE.
+ * reloc.c: Same.
+ * cpu-sparc.c (arch_info_struct): Added sparc:sparclite_le
+ * archures.c (bfd_mach_sparc_sparclite_le): New.
+ * bfd-in2.h (BFD_RELOC_SPARC_32LE, bfd_mach_sparc_sparclite_le): New.
+
+Thu May 21 16:59:28 1998 Nick Clifton <nickc@cygnus.com>
+
+ * peicode.h (add_data_entry): Fix precedence of operators in if ()
+ statement.
+
+Tue May 19 18:41:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd-in.h: Move over patch to bfd-in2.h.
+
+ * reloc.c (bfd_check_overflow): Add casts before shifts which may
+ not fit in 32 bits.
+ (_bfd_relocate_contents): Likewise.
+
+Mon May 18 14:44:15 1998 Nick Clifton <nickc@cygnus.com>
+
+ * peicode.h (add_data_entry): If the section has no private data
+ then do not create a Data Dictionary entry for it.
+
+Mon May 18 00:09:28 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Set again on changes.
+ (elf64_alpha_can_merge_gots, elf64_alpha_merge_gots,
+ elf64_alpha_size_got_sections): Rewrite, handling multiple got
+ subsections during relaxation more correctly.
+
+Thu May 14 14:22:58 1998 Nick Clifton <nickc@cygnus.com>
+
+ * bfd-in2.h: Add new prototype: bfd_coff_set_symbol_class ().
+ Add extra argument to bfd_arm_process_before_allocation ().
+ * bfd-in.h: Reflect changes made in bfd-in2.h.
+ * coffgen.c (bfd_coff_set_symbol_class): New function. Set the
+ coff class of a BFD symbol.
+ * coff-arm.c: Add support for interworking between Thumb code and
+ non-interworking aware ARM code.
+
+Sun May 10 22:33:59 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Thu May 7 17:40:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * filemode.c: Remove; not used.
+
+ If sysdep.h includes a header file, don't include it again:
+ * aix386-core.c: Don't include <stdio.h>, <stddef.h>, or
+ <errno.h>.
+ * aoutx.h: Don't include <string.h>. Use "sysdep.h" rather than
+ <sysdep.h>.
+ * archive.c: Don't include <string.h> or <errno.h>.
+ * evax-alpha.c; Don't include <stdio.h>.
+ * evax-egsd.c: Likewise.
+ * evax-etir.c: Likewise.
+ * evax-misc.c: Likewise.
+ * evax-emh.c: Likewise. Also, don't include <sys/types.h>.
+ * hppabsd-core.c: Don't include <stdio.h>, <sys/types.h>, or
+ <errno.h>.
+ * hpux-core.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * som.c: Likewise.
+ * libbfd.c: Don't include <sys/types.h>.
+ * nlmcode.h: Don't include <string.h>.
+ * osf-core.c: Don't include <string.h> or <stdio.h>.
+ * ptrace-core.c: Don't include <stdio.h>, <sys/types.h>,
+ <errno.h>, or <unistd.h>.
+ * trad-core.c: Don't include <stdio.h> or <sys/types.h>.
+
+Thu May 7 13:12:50 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * configure.com: If the version number can not be found in
+ configure.in, set it to "unknown" rather than "2.8.1".
+
+Wed May 6 09:46:05 1998 Gavin Koch <gavin@cygnus.com>
+
+ * elf32-mips.c (elf_mips_mach): New.
+ (_bfd_mips_elf_object_p): Use elf_mips_mach.
+ (_bfd_mips_elf_final_write_processing): Use the names
+ of machines, rather than the numbers. Set both the ARCH
+ and MACH in e_flags. Handle a few more specific machines.
+ (_bfd_mips_elf_merge_private_bfd_data): Merge both
+ EF_MIPS_ARCH and EF_MIPS_MACH.
+
+Tue May 5 21:01:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * syms.c (bfd_is_local_label): Revert last change.
+ * srec.c (srec_write_symbols): Discard debugging symbols.
+
+Tue May 5 23:36:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * som.c: Include <ctype.h>.
+ * som.h: Don't include sysdep.h.
+
+Tue May 5 18:29:24 1998 Tom Tromey <tromey@cygnus.com>
+
+ * libbfd.h: Rebuilt.
+ * libbfd-in.h: Removed gettext includes and defines.
+ * sysdep.h: Moved gettext-related includes and defines here.
+
+Tue May 5 16:47:54 1998 Richard Henderson <rth@cygnus.com>
+
+ * srec.c (srec_write_symbols): Use bfd_is_local_label rather than
+ an ad-hoc test. Kill bogus #if 0 code.
+ * syms.c (bfd_is_local_label): Consider BSF_DEBUGGING symbols local.
+
+Mon May 4 16:10:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_check_dynamic_reloc): Don't use the PLT address
+ when generating a normal executable for a symbol defined in a
+ regular file. When copying a reloc into the output file, adjust
+ the addend for a PC relative reloc against a global symbol.
+
+Mon May 4 10:08:18 1998 Tom Tromey <tromey@cygnus.com>
+
+ * libbfd.h: Rebuilt.
+ * libbfd-in.h (_): Define as dgettext.
+
+Mon May 4 11:02:23 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Cast to bfd_signed_vma,
+ not signed.
+ * peicode.h (pe_saved_coff_bfd_print_private_bfd_data): Use PARAMS
+ when declaring parameter types.
+ (pe_saved_coff_bfd_copy_private_bfd_data): Likewise.
+
+Wed Apr 29 15:35:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.bfd: If we include any ELF targets in targ_defvec and/or
+ targ_selvecs, then add the generic ELF targets to targ_selvecs.
+ * elf32-gen.c (dummy): New static const variable.
+ (elf_generic_info_to_howto): New static function.
+ (elf_generic_info_to_howto_rel): New static function.
+ (elf_info_to_howto): Define as elf_generic_info_to_howto.
+ (elf_info_to_howto_rel): Define as elf_generic_info_to_howto_rel.
+ * elf64-gen.c: Same changes as elf32-gen.c.
+ * elfcode.h (elf_object_p): For the generic target, ignore a
+ failure of bfd_default_set_arch_mach. Fix indentation a bit.
+
+Tue Apr 28 20:05:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (WIN32LIBADD): Add -lintl on cygwin32.
+ * configure: Rebuild.
+
+Tue Apr 28 12:16:57 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * config.bfd: Update OSR5/Unixware patterns.
+
+Mon Apr 27 18:02:24 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Allow for holes
+ between sections added by a link script.
+
+Mon Apr 27 11:49:55 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.9.4
+ * configure: Rebuild.
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * elf.c (bfd_elf_get_bfd_needed_list): New function.
+ * bfd-in.h (bfd_elf_get_bfd_needed_list): Declare.
+ * bfd-in2.h: Rebuild.
+
+Sat Apr 25 20:07:53 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (struct alpha_relax_info): Replace elfsym with other.
+ Change all users.
+
+Sat Apr 25 18:29:07 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (struct alpha_relax_info): Add tsec & elfsym members.
+ (elf64_alpha_relax_section): Fill them in.
+ (elf64_alpha_relax_opt_call): Implement more than a stub.
+ (elf64_alpha_add_symbol_hook): Don't set SEC_LOAD or default
+ alignment on .scommon.
+ (elf64_alpha_merge_gots): Merge use counts as well.
+
+Sat Apr 25 14:07:29 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Use the proper section
+ for calculating a local symbol's address.
+ (elf64_alpha_calc_got_offsets): Skip entries with 0 use count.
+ Set the .got's cooked size as well as the raw size.
+
+Fri Apr 24 09:16:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_print_private_bfd_data): Add
+ internationalisation of printed information.
+
+ * coff-arm.c (coff_arm_print_private_bfd_data): Add
+ internationalisation of printed information.
+
+Fri Apr 24 12:09:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * syms.c (struct indexentry): Change directory_name, file_name,
+ and function_name fields to char *.
+ (struct stab_find_info): Change cached_file_name field to char *.
+
+Thu Apr 23 08:13:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * peicode.h (dir_names): Add missing N_() macros to dir_names array.
+
+Wed Apr 22 13:06:15 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir).
+
+Wed Apr 22 17:48:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (install-data-local): Make $(includedir).
+ * Makefile.in: Rebuild.
+
+Wed Apr 22 13:06:15 1998 Tom Tromey <tromey@cygnus.com>
+
+ * libbfd-in.h: Use `gettext' and not `dgettext' for now.
+
+Wed Apr 22 12:53:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (INCLUDES): Add -I$(srcdir)/../intl -I../intl.
+ * Makefile.in: Rebuild.
+
+ * bfd-in2.h: Rebuild for Nick's changes.
+
+Tue Apr 21 23:11:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Fix lossage in last
+ change wrt length == max_namelen.
+
+Tue Apr 21 21:19:36 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * Many files: Added gettext invocations around user-visible
+ strings.
+ * libbfd-in.h: Added gettext includes and defines.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY,
+ HAVE_LC_MESSAGES): Define.
+ * configure.in: Call CY_GNU_GETTEXT. Create po/Makefile.in and
+ po/Makefile.
+ * Makefile.am (SUBDIRS): Added po.
+ (POTFILES): New macro.
+ (po/POTFILES.in): New target.
+ (SOURCE_HFILES): New macro.
+ (HFILES): Use it.
+ * po/Make-in, po/POTFILES.in, po/bfd.pot: New files.
+
+Tue Apr 21 13:38:18 1998 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfcore.h (bfd_prstatus): Copy core_prstatus from the first
+ NT_PRSTATUS note section encountered, it contains the status of
+ the currently executing thread when the core file was written.
+
+Tue Apr 21 10:00:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * libcoff.h: Add extra parameter to
+ bfd_coff_link_output_has_begun overrideable function.
+ * cofflink.c: Pass extra parameter to
+ bfd_coff_link_output_has_begun function.
+ * bfd-in.h: Add prototypes for exported ARM interworking
+ functions.
+ * peicode.h: ARM specific code reorganised to conform to BFD
+ coding conventions.
+ * coffcode.h: ARM specific code reorganised to conform to BFD
+ coding conventions.
+ * coff-arm.c: Code reorganised to conform to the BFD coding
+ conventions. Global variables have been moved into an ARM
+ specific hash table structure and a new function:
+ bfd_arm_get_bfd_for_interworking() has been created which is
+ called from the linker scripts.
+
+Tue Apr 21 00:11:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Simplify end-of-name test.
+
+ * elf64-alpha.c (elf64_alpha_find_reloc_at_ofs): Renamed from
+ elf64_alpha_relax_find_reloc_ofs. Changed all callers.
+ (elf64_alpha_add_symbol_hook): Put small commons in .scommon not .sbss.
+ (elf64_alpha_size_got_sections): Don't merge .got sections twice.
+
+Sat Apr 18 01:21:04 1998 Stan Cox <scox@cygnus.com>
+
+ * config.bfd: Added sparc86x support.
+
+Fri Apr 17 22:29:04 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_relocate_section): Do not complain about
+ an out of range pc-relative jump/call to an undefined weak symbol.
+
+Thu Apr 16 13:49:00 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_do_reloc_gpdisp): Do all gpdisp
+ comparisons signed.
+
+Thu Apr 16 11:43:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * archive.c (bfd_generic_archive_p): If a slurp subroutine returns
+ an error other than bfd_error_system_call, set the error to
+ bfd_error_wrong_format.
+
+ * targets.c (bfd_target_vector) [SELECT_VECS not defined]: Add
+ bfd_elf32_powerpcle_vec.
+
+ * elf.c (copy_private_bfd_data): If all the p_paddr fields in the
+ program segments are zero, don't set p_paddr_valid.
+
+Wed Apr 15 22:15:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c: Initial implementation of relaxation --
+ (struct alpha_elf_link_hash_entry): Add use_count member.
+ (elf64_alpha_check_relocs): Initialize and increment it.
+ (elf64_alpha_can_merge_gots): Check it when considering merging.
+ (elf64_alpha_merge_gots): Drop entries with zero use.
+ (elf64_alpha_calc_got_offsets_for_symbol): Likewise.
+ (elf64_alpha_always_size_sections): Split out got sizing ...
+ (elf64_alpha_size_got_sections): ... here. New function.
+ (elf64_alpha_relax_find_reloc_ofs): New function.
+ (elf64_alpha_relax_with_lituse): Likewise.
+ (elf64_alpha_relax_without_lituse): Likewise.
+ (elf64_alpha_relax_opt_call): Likewise.
+ (elf64_alpha_relax_section): Likewise.
+ (elf64_alpha_add_symbol_hook): Likewise.
+ (elf64_alpha_howto_table): Implement GPRELHIGH/LOW & IMMED_GP_16.
+ (elf64_alpha_relocate_section): Likewise.
+ (bfd_elf64_bfd_relax_section): Define.
+ (elf_backend_add_symbol_hook): Likewise.
+
+Wed Apr 15 16:08:46 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf.c (prep_headers): Use new EM_SPARCV9 symbol.
+ * elf64-sparc.c (ELF_MACHINE_CODE): Likewise.
+ (ELF_MACHINE_ALT1): New. Set to EM_OLD_SPARC64.
+
+Wed Apr 15 11:34:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add -lkernel32 to WIN32LIBADD on cygwin32.
+ * configure: Rebuild.
+
+Mon Apr 13 16:46:27 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (libbfd_la_LIBADD): Add @WIN32LIBADD@.
+ (libbfd_la_LDFLAGS): Add @WIN32LDFLAGS@.
+ * configure.in: Define and substitute WIN32LDFLAGS and
+ WIN32LIBADD.
+ * aclocal.m4: Rebuild with new libtool.
+ * configure, Makefile.in: Rebuild.
+
+Fri Apr 10 13:44:27 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): Move a PE COMDAT symbol
+ before any other symbols in the same section.
+
+Wed Apr 8 14:50:23 1998 Michael Meissner <meissner@cygnus.com>
+
+ * config.bfd (powerpc*-*-*): Remove PowerPC NT support from ELF
+ systems.
+
+Tue Apr 7 16:25:31 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * dwarf2.c (comp_unit): Move it earlier in the source. Add
+ addr_size.
+ (read_address): Replace 'bdf*' argument with 'comp_unit*' argument.
+ Use addr_size for address size, rather than sizeof(bfd_vma).
+ (read_attribute): Replace bdf* argument with 'comp_unit*' argument.
+ Fix call to read_address.
+ (decode_line_info): Replace bdf* argument with 'comp_unit*' argument.
+ Scrap other unneeded arguments. Fix call to read_address.
+ (scan_unit_for_functions): Fix call to read_attribute.
+ (parse_comp_unit): We now handle more values for addr_size.
+ Set addr_size in unit. Fix call to read_attribute and
+ decode_line_info.
+
+Tue Apr 7 15:44:47 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * dwarf2.c (parse_comp_unit): Drop use of unit->name when it is null.
+
+Tue Apr 7 12:35:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * archures.c (bfd_default_scan): Add m68k cases back to default
+ switch, reverting patch of March 25, since IEEE support depends
+ upon them.
+
+Mon Apr 6 14:06:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (diststuff): New target.
+ * Makefile.in: Rebuild.
+
+Sun Apr 5 16:21:44 1998 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_bfd_ar_write_symbol_stuff): Fix computation of
+ som_offset when we have an extended name table.
+
+Sun Apr 5 16:04:39 1998 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (stamp-lib): Check that .libs/libbfd.a exists before
+ trying to copy it.
+ * Makefile.in: Rebuild.
+
+Fri Apr 3 11:09:42 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Generate section
+ symbols when creating a shared library.
+ (elf_m68k_adjust_dynindx): New function, used by above code.
+ (elf_m68k_finish_dynamic_sections): Initialize the section
+ symbols.
+ (elf_m68k_relocate_section): Change abort to BFD_ASSERT.
+
+Wed Apr 1 16:04:02 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (in_reloc_p): Use ARM_RVA32 in place of constant
+ value 11.
+
+Wed Apr 1 13:36:58 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c (elf_m68k_relocate_section, case R_68K_PLT*O): Fix
+ assertion.
+
+Tue Mar 31 00:12:12 1998 Jeffrey A Law (law@cygnus.com)
+
+ * elf-m10300.c (mn10300_elf_relax_section): Correctly handle
+ absolute symbols.
+
+Mon Mar 30 12:46:15 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set version to 2.9.1.
+ * configure: Rebuild.
+
+ * Branched binutils 2.9.
+
+Mon Mar 30 12:20:50 1998 Brent Baccala <baccala@freesoft.org>
+
+ * syms.c (ENABLE_CACHING): Define.
+ (struct indexentry): Define.
+ (struct stab_cache): Remove.
+ (cmpindexentry): New static function.
+ (struct stab_find_info): Add new fields: indextable,
+ indextablesize, cached_indexentry, cached_offset, cached_stab, and
+ cached_file_name. Remove fields: file_cache, function_cache, and
+ line_cache.
+ (_bfd_stab_section_find_nearest_line): Rewrite to build a sorted
+ index table and search it.
+
+Mon Mar 30 10:39:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (_bfd_elf_copy_private_section_data): Call
+ copy_private_bfd_data once we've seen the last SEC_ALLOC section.
+
+ * cpu-mips.c: Remove trailing comma at end of enumeration list.
+
+Sat Mar 28 16:33:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-arm.c: Define all globally visible variables and functions
+ only when COFF_WITH_PE is not defined.
+ * configure.in (armpe_little_vec, armpe_big_vec): Add
+ coff-arm.lo.
+ * configure: Rebuild.
+
+Fri Mar 27 16:06:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Fix some gcc -Wall warnings:
+ * aout-arm.c (MY(fix_pcrel_26)): Add casts to avoid warnings.
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Likewise.
+ * archures.c (bfd_default_scan): Likewise.
+ * bfd.c (bfd_scan_vma): Likewise.
+ * binary.c (mangle_name): Likewise
+ * coff-arm.c (aoutarm_fix_pcrel_26): Likewise.
+ * coff-sh.c (sh_relocate_section): Likewise.
+ * coff-stgo32.c (create_go32_stub): Likewise.
+ * coffcode.h (coff_slurp_line_table): Likewise.
+ * ecoff.c (_bfd_ecoff_write_armap): Likewise.
+ * elf.c (_bfd_elf_make_section_from_shdr): Likewise.
+ (assign_file_positions_for_segments): Likewise.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
+ * oasys.c (oasys_write_sections): Likewise.
+ * ppcboot.c (ppcboot_object_p): Likewise.
+ (mangle_name): Likewise.
+ * riscix.c (riscix_fix_pcrel_26): Likewise.
+ * srec.c (srec_scan): Likewise.
+ * stabs.c (_bfd_write_section_stabs): Likewise.
+ * sunos.c (sunos_add_dynamic_symbols): Likewise.
+ * aout-ns32k.c (_bfd_ns32k_relocate_contents): Add default case to
+ switch. Declare parameters for function pointers.
+ * archures.c (bfd_default_scan): Add braces to avoid ambiguous if
+ warning.
+ * elf.c (elf_sort_sections): Likewise.
+ * coff-arm.c (coff_thumb_pcrel_common): Initialize relocation.
+ Add default cases to switches.
+ (coff_arm_relocate_section): Remove unused local variables.
+ Always set rstat.
+ (coff_arm_bfd_set_private_flags): Change flag variable to type
+ flagword.
+ * coff-mips.c (mips_relocate_section): Initialize use_lo.
+ * coff-ppc.c (ppc_record_toc_entry): Change i to unsigned int.
+ (dump_toc): Change cat to const, and initialize it.
+ * coff-sh.c (sh_relax_delete_bytes): Initialize start and voff.
+ * elf32-sh.c (sh_elf_relax_delete_bytes): Likewise.
+ (sh_elf_relocate_section): Initialize r_symndx.
+ * coffcode.h (coff_compute_section_file_positions): Only declare
+ old_sofar if ALIGN_SECTIONS_IN_FILE.
+ (coff_write_object_contents): Initialize csym.
+ * coffgen.c (coff_pointerize_aux): Make type and class unsigned.
+ * cpu-ns32k.c (_bfd_ns32k_get_displacement): Add default case to
+ switch.
+ * dwarf2.c: Include libiberty.h.
+ (read_2_signed_bytes, read_4_signed_bytes): Comment out.
+ (decode_line_info): Remove unused local variables.
+ * elf32-m32r.c (m32r_elf_sda16_reloc): Likewise.
+ (m32r_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_store_addend_in_insn): Likewise.
+ (v850_elf_reloc): Likewise.
+ * elf-bfd.h (elf_linker_section_t): Make alignment unsigned.
+ (struct elf_obj_tdata): Make cverdefs and cverrefs unsigned.
+ * elf.c (assign_file_positions_for_segments): Always set adjust.
+ * elf32-d30v.c (bfd_elf_d30v_reloc): Initialize tmp_addr. Fully
+ parenthesize expression.
+ * elf32-m32r.c (m32r_elf_relocate_section): Always initialize h.
+ (m32r_elf_object_p): Return a value.
+ (m32r_elf_print_private_bfd_data): Change fprintf format string.
+ * elf32-mips.c (mips_elf_final_link): Initialize last.
+ (mips_elf_finish_dynamic_sections): Initialize last and dindx.
+ * elf32-v850.c (v850_elf_object_p): Return a value.
+ (v850_elf_print_private_bfd_data): Change fprintf format string.
+ * elfcode.h (elf_slurp_symbol_table): Change symcount and i to
+ unsigned long.
+ * elflink.h (elf_link_add_object_symbols): Change vernum to
+ unsigned int, and initialize it. Change fprintf format string.
+ (NAME(bfd_elf,size_dynamic_sections)): Cast -1 to bfd_size_type
+ when setting or comparing to soname_indx.
+ (elf_create_pointer_linker_section): Change num_symbols to
+ unsigned int.
+ * libcoff-in.h (coff_data_type): Change flags to flagword.
+ * peicode.h (pe_print_idata): Initialize idx. Change j to
+ bfd_size_type. Initialize hint_member. Remove useless test to
+ time_stamp.
+ (pe_print_edata): Change num_functions and num_names in struct
+ EDT_type to unsigned long. Remove cast. Change fprintf format
+ string.
+ * ppcboot.c (ppcboot_object_p): Change i to size_t.
+ * reloc.c (bfd_get_reloc_size): Change return type to unsigned
+ int.
+ * reloc16.c (bfd_coff_reloc16_relax_section): Change shrinks to
+ int *. Update uses. Change j to long.
+ * bfd-in2.h, libcoff.h: Rebuild.
+
+Fri Mar 27 10:10:46 1998 Catherine Moore <clm@cygnus.com>
+
+ * elf32-v850.c Remove definition of USE_REL.
+ (v850_elf_info_to_howto_rela): New function.
+ (v850_elf_perform_relocation): Renamed from
+ v850_elf_store_addend_in_insn. Removed replace argument.
+ (v850_elf_reloc): store the relocation in the addend field instead
+ of the insn.
+ (v850_elf_final_link_relocate): Now calls
+ v850_elf_perform_relocation.
+ (v850_elf_relocate_section): Remove code to generate REL
+ relocations.
+
+Thu Mar 26 13:32:17 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_new_section_hook): Set the type and storage
+ class in the native symbol information allocated for a new section
+ symbol.
+
+Thu Mar 26 10:13:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * peicode.h: Chain together calls to
+ coff_bfd_copy_private_bfd_data and
+ coff_bfd_print_private_bfd_data.
+
+ * coff-arm.c: Add prototypes for
+ coff_arm_bfd_print_private_bfd_data and
+ coff_arm_bfd_copy_private_bfd_data.
+
+Wed Mar 25 15:45:55 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coffcode.h (coff_mkobject_hook): Set private falgs even for a PE
+ build.
+
+ * peicode.h: Call arm-coff private data functions after handling
+ pe private data.
+
+ * coff-arm.c: Turn statics into globals so that they can be shared
+ both pe and pei backends.
+
+Wed Mar 25 15:19:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutf1.h (sunos_set_arch_mach): Use bfd_mach_m68* rather than
+ plain numbers.
+ (sunos_write_object_contents): Likewise.
+ * aoutx.h (NAME(aout,machine_type)): Likewise.
+ * coffcode.h (coff_set_arch_mach_hook): Likewise.
+
+Wed Mar 25 13:59:24 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * archures.c (bfd_mach_m68*): Add definitions for various m68k
+ variants.
+ (bfd_default_scan): Remove m68k special cases.
+ * bfd-in2.h: Rebuild.
+ * mipsbsd.c (MY(write_object_contents)): Use bfd_mach_m68* rather
+ than plain numbers.
+ * sparclynx.c (NAME(lynx,set_arch_mach)): Likewise.
+ * cpu-m68k.c (arch_info_struct): Likewise. Add entry for
+ m68k:68000.
+ (bfd_m68k_arch): Set mach field to zero to signal no explicit
+ selection, change printable_name to just "m68k" and make that the
+ default instead of m68k:68020.
+
+ * aout-tic30.c (NAME): Define this to avoid multiple definitions
+ from aoutx.h.
+ (MY_get_section_contents): Define as aout_32_get_section_contents
+ rather than NAME(aout,get_section_contents).
+
+ * elf-m10300.c (elf32_mn10300_link_hash_table_create): Fix cast.
+
+ * evax-alpha.c (evax_set_arch_mach): Only accept bfd_arch_alpha
+ and call bfd_default_set_arch_mach to do the real work.
+
+Wed Mar 25 10:41:35 1998 Richard Henderson <rth@cygnus.com>
+
+ * bout.c (BALX): Include return register g14 as part of the insn.
+ (BALX_MASK): New.
+ (calljx_callback): Use it.
+
+Wed Mar 25 11:19:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd-in.h (BFD_ALIGN): Cast this parameter to bfd_vma.
+ * libbfd.h: Rebuild.
+
+ * elf-m10300.c (elf32_mn10300_finish_hash_table_entry): Change
+ byte_count to unsigned int.
+ (mn10300_elf_relax_section): Initialize internal_relocs. Remove
+ unused local variables.
+
+ * evax-alpha.c (evax_close_and_cleanup): Remove unused local
+ variables er and er1.
+
+ * cpu-v850.c: Include <ctype.h>.
+ (scan): Case isdigit argument to unsigned char.
+
+ From Yan Meroth <YAN.MEROTH@st.com>:
+ * ihex.c (ihex_scan): Add extbase variable so that getting an
+ extended linear address record does not ignore any previous
+ extended address.
+ (ihex_write_object_contents): When writing out an extended linear
+ address record, zero out any previous extended address.
+
+Tue Mar 24 16:09:43 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * ieee.c (do_one): Check section before dereferencing it.
+ (ieee_canonicalize_reloc): Likewise with src->relent.sym_ptr_ptr.
+ (ieee_generic_stat_arch_elt): Likewise with abfd->my_archive.
+
+Mon Mar 23 18:51:47 1998 Joel Sherrill <joel@OARcorp.com>
+
+ * config.bfd: (sh*-*-rtems*): Switched from ELF to COFF.
+
+Mon Mar 23 14:23:36 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c: Add interworking functions to pe backends.
+
+Fri Mar 20 18:47:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use AM_DISABLE_SHARED.
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Fri Mar 20 11:25:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Better error messages
+ when interowrking conflucts occur. Courtesy of Jonathan Walton
+ and Tony Thompson.
+ (aoutarm_std_reloc_howto): Fixed bitsize fields of rightshifted
+ relocations. Patch courtesy of Jonathan Walton and Tony
+ Thompson.
+
+Fri Mar 20 02:26:43 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Revert
+ part of Feb 22 change controling when to override the existing
+ symbol with the .plt entry.
+
+Wed Mar 18 09:26:25 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config.bfd (targ_cpu): Add thumb-pe target.
+
+ * coffcode.h (OTHER_GLOBAL_CLASS): Support thumb external
+ functions in PE build.
+
+Sun Mar 8 23:37:26 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * config.bfd (sparclite-*-elf*): Added.
+
+Mon Feb 23 19:31:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add elf.lo to elf shell variable.
+ * Makefile.am (BFD_LIBS): Remove elf.lo.
+ (BFD_LIBS_CFILES): Remove elf.c.
+ (BFD32_BACKENDS): Add elf.lo.
+ (BFD32_BACKENDS_CFILES): Add elf.c.
+ * configure, Makefile.in: Rebuild.
+
+1998-02-23 15:53 Richard Henderson <rth@cygnus.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): A pc-relative
+ relocation against a now-local symbol should not have a dynamic
+ relocation.
+
+Mon Feb 23 16:17:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (coff_swap_filehdr_in): Don't set BFD flag HAS_SYMS in
+ COFF filehdr flags.
+ (pe_print_private_bfd_data): Print PE flags. From Mikey
+ <jeffdb@netzone.com>.
+
+Sun Feb 22 20:39:00 1998 Richard Henderson <rth@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Don't create
+ a plt entry when we can determine that we authoritatively define
+ the symbol.
+
+Sun Feb 22 20:33:05 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in (COREFILE selection): Remove sparc-*-linux*. They
+ don't actually use trad-core, but a SunOS-style core file handled
+ by gdb directly.
+ * hosts/sparclinux.h: Remove.
+
+Wed Feb 18 15:31:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (pe_print_idata): If there is no .idata section, look
+ for the import tables in some other section. Make the initial
+ label line up better with the data. Print the import address
+ table even if there is no import name table. If the import
+ address table holds actual addresses, print them.
+
+Tue Feb 17 12:58:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd.c (bfd_seek): If fseek fails, save errno around call to
+ bfd_tell. If errno is EINVAL, set bfd_error_file_truncated, not
+ bfd_error_system_call.
+
+Fri Feb 13 13:11:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e.
+
+ From H.J. Lu <hjl@gnu.org>:
+ * Makefile.am (libbfd_la_LDFLAGS): Define.
+ * Makefile.in: Rebuild.
+
+Thu Feb 12 17:31:11 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ NetBSD patches from Gordon W. Ross <gwr@mc.com>:
+ * netbsd.h (MACHTYPE_OK): Define.
+ (MY(write_object_contents)): Use DEFAULT_ARCH and DEFAULT_MID when
+ calling N_SET_MACHTYPE, rather than having a switch.
+ * libaout.h (enum machine_type): Add M_PMAX_NETBSD, M_VAX_NETBSD,
+ and M_ALPHA_NETBSD.
+ * i386netbsd.c (MACHTYPE_OK): Don't define.
+ (DEFAULT_MID): Define.
+ * m68k4knetbsd.c (SEGMENT_SIZE): Don't define.
+ (MACHTYPE_OK): Don't define.
+ (DEFAULT_MID): Define.
+ * m68knetbsd.c: (MACHTYPE_OK): Don't define.
+ (DEFAULT_MID): Define.
+ * ns32knetbsd.c (MACHTYPE_OK): Don't define.
+ (DEFAULT_MID): Define.
+ * sparcnetbsd.c (MACHTYPE_OK): Don't define.
+ (DEFAULT_MID): Define.
+
+ NetBSD patches from Gordon W. Ross <gwr@mc.com>:
+ * vaxnetbsd.c: New file.
+ * netbsd-core.c: Clean up. Remove unused macros. Use netbsd
+ rather than netbsd_core.
+ * targets.c (vaxnetbsd_vec): Declare.
+ (bfd_target_vector): Add vaxnetbsd_vec. If NETBSD_CORE is
+ defined, add netbsd_core_vec.
+ * configure.in: Set COREFILE for alpha*-*-netbsd* and
+ powerpc-*-netbsd* to netbsd-core.lo. If COREFILE is
+ netbsd-core.lo, set COREFLAG to -DNETBSD_CORE.
+ * config.bfd (alpha*-*-netbsd*): New target.
+ * Makefile.am: Rebuild dependencies.
+ (BFD32_BACKENDS): Add vaxnetbsd.lo.
+ (BFD32_BACKENDS_CFILES): Add vaxnetbsd.c.
+ * configure, Makefile.in: Rebuild.
+
+ * configure.host: Remove the old shared library build stuff. We
+ now use libtool instead.
+
+Wed Feb 11 17:13:09 1998 Richard Henderson <rth@cygnus.com>
+
+ * tekhex.c (tekhex_write_object_contents): Call tekhex_init.
+
+Tue Feb 10 19:23:28 1998 H.J. Lu <hjl@gnu.org>
+
+ * configure.in: Take stab-syms.lo out of sparclinux_vec list.
+ * configure: Rebuild.
+
+Tue Feb 10 15:16:38 1998 Nick Clifton <nickc@cygnus.com>
+ * elf32-v850.c (remember_hi16s_reloc): New function.
+ (find_remembered_hi16s_reloc): New function.
+ (v850_elf_store_addend_in_insn): Use the above new functions to
+ match up HI6S relocs with LO16 relocs.
+
+Tue Feb 10 15:01:39 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change -linux* to -linux-gnu*.
+ * config.bfd, configure.host: Likewise.
+ * configure: Rebuild.
+
+Mon Feb 9 19:40:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_store_addend_in_insn): Fix another
+ LO16/HI16S bug and improve comments about what is going on.
+
+Sat Feb 7 15:27:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Fri Feb 6 14:48:20 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_merge_private_bfd_data): Do not complain
+ when merging v850 code into v850e/v850ea code. Do not initialise
+ output flags if the input is the default architecture.
+
+Fri Feb 6 11:50:22 1998 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mips.c (bfd_elf32_bfd_reloc_type_lookup): For BFD_RELOC_CTOR
+ get the size from bfd_arch_bits_per_address instead of directly
+ from the isa.
+
+Thu Feb 5 14:21:34 1998 Michael Meissner <meissner@cygnus.com>
+
+ * libbfd-in.h (BFD_ALIGN): If rounding up would cause the address
+ to wrap, just return all 1's bits instead.
+ * libbfd.h: Regenerate.
+
+Thu Feb 5 11:51:05 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i386.c (coff_pe_i386_relocate_section): New static function
+ if COFF_WITH_PE.
+ (coff_relocate_section): If COFF_WITH_PE, define as
+ coff_pe_i386_relocate_section.
+ * coffcode.h (coff_write_object_contents): If COFF_IMAGE_WITH_PE,
+ skip empty sections, to match coff_write_object_contents.
+
+ * elf64-mips.c (mips_elf64_swap_reloca_out): Swap out r_addend,
+ rather than swapping out r_offset twice. From Luke Deller
+ <luked@cse.unsw.edu.au>.
+
+Wed Feb 4 19:11:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set libtool_enable_shared rather than
+ libtool_shared. Remove diversion hack.
+ * configure, Makefile.in, doc/Makefile.in, aclocal.m4: Rebuild
+ with new libtool.
+
+Wed Feb 4 16:10:21 1998 Brent Baccala <baccala@freesoft.org>
+
+ * syms.c (struct stab_cache): Define.
+ (struct stab_find_info): Remove cached_offset, cached_stab,
+ cached_str, and cached_stroff fields. Add file_cache,
+ function_cache, and line_cache fields.
+ (_bfd_stab_section_find_nearest_line): Use extensive caching to
+ speed up searches.
+
+Wed Feb 4 13:34:22 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (pe_print_idata): Check for import of ordinal rather
+ than name.
+ (pe_print_edata): If there is no .edata section, look for the
+ export data in some other section.
+
+Mon Feb 2 20:05:42 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * configure.in: Change version to 2.8.4.
+ * configure: Regenerated.
+
+Mon Feb 2 17:39:39 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ Add tms320c30 support:
+ * cpu-tic30.c: New file.
+ * aout-tic30.c: New file.
+ * coff-tic30.c: New file.
+ * archures.c (bfd_arch_tic30): Define.
+ (bfd_tic30_arch): Declare.
+ (bfd_archures_list): Add bfd_tic30_arch.
+ * targets.c (bfd_target_vector): Add tic30_aout_vec and
+ tic30_coff_vec.
+ * reloc.c (BFD_RELOC_TIC30_LDP): Define.
+ * coffcode.h (coff_set_arch_mach_hook): Add tic30 case.
+ (coff_set_flags): Likewise.
+ * config.bfd (tic30-*-*aout*, tic30-*-*coff*): New targets.
+ * configure.in (tic30_aout_vec, tic30_coff_vec): New vectors.
+ * Makefile.am: Rebuild dependencies.
+ (ALL_MACHINES): Add cpu-tic30.lo.
+ (ALL_MACHINES_CFILES): Add cpu-tic30.c.
+ (BFD32_BACKENDS): Add aout-tic30.lo and coff-tic30.lo.
+ (BFD32_BACKENDS_CFILES): Add aout-tic30.c and coff-tic30.c.
+ * configure, Makefile.in, bfd-in2.h, libbfd.h: Rebuild.
+
+Mon Feb 2 12:25:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_store_addend_in_insn): Allow HI16_S reloc
+ to lag behind LO16 reloc by a couple of instructions.
+
+Mon Feb 2 14:09:46 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am ($(srcdir)/bfd-in2.h): Add dummy command to force
+ make to reexamine the file timestamp.
+ ($(srcdir)/libbfd.h, $(srcddir)/libcoff.h): Likewise.
+
+ * elf64-alpha.c (ELF_MAXPAGESIZE): Change to 0x10000 from
+ 0x100000.
+
+Fri Jan 30 19:07:07 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_create_dynamic_sections): New procedure
+ to create .dynsbss and .rela.sbss sections.
+ (ppc_elf_adjust_dynamic_symbol): Put space for small data to be
+ copied from dynamic objects into .sbss.
+ (ppc_elf_size_dynamic_sections): Strip .rela.sbss if we don't
+ use it. Correct typo of .rela.sdata2.
+ (ppc_elf_finish_dynamic_symbol): Generate reloc to where we
+ put the data, which may now be in .sbss.
+ (ppc_elf_relocate_section): A SDAREL16 reloc can be in dynsbss.
+ (elf_backend_create_dynamic_sections): Define as
+ ppc_elf_create_dynamic_sections.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't emit R_PPC_REL* relocs
+ against _GLOBAL_OFFSET_TABLE_.
+ (ppc_elf_relocate_section): Don't emit R_PPC_REL32 relocs in
+ shared libraries which refer to local symbols. Make sure that the
+ test for allocating space for a reloc in a shared object is the
+ same as the test for emitting a reloc.
+
+Thu Jan 29 15:55:35 1998 J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl>
+
+ * config.bfd (i[3456]-*-mingw32*): New target.
+ * acinclude.m4 (BFD_BINARY_OPEN): Check for mingw32.
+ * aclocal.m4, configure: Rebuild.
+
+Wed Jan 28 13:41:26 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (_bfd_elf_close_and_cleanup): Only check the strtab if we
+ have a bfd_object.
+
+Tue Jan 27 21:43:55 1998 Richard Henderson <rth@cygnus.com>
+
+ Sparc v9 ABI compliant PLT:
+ * elf64-sparc.c (PLT_HEADER_SIZE): V9 ABI uses 4 entries.
+ (plt_templates, sparc64_elf_build_plt_entry): Delete.
+ (LARGE_PLT_THRESHOLD): New define.
+ (GOT_RESERVED_ENTRIES): V9 ABI only uses 1.
+ (sparc64_elf_build_plt): New function.
+ (sparc64_elf_plt_entry_offset): Likewise.
+ (sparc64_elf_plt_ptr_offset): Likewise.
+ (sparc64_elf_adjust_dynamic_symbol): Change h->plt_offset to
+ contain the index for convenience. Skip the initial entries
+ in .rela.plt.
+ (sparc64_elf_size_dynamic_sections): Zero the allocated contents
+ memory for the benefit of .rela.plt.
+ (sparc64_elf_relocate_section): Call sparc64_elf_plt_entry_offset.
+ (sparc64_elf_finish_dynamic_symbol): Kill template stuff. Use
+ sparc64_elf_plt_entry_offset & sparc64_elf_plt_ptr_offset for reloc.
+ (sparc64_elf_finish_dynamic_sections): DT_PLTGOT points to .plt.
+ Call sparc64_elf_build_plt.
+ (elf_backend_want_got_plt): No.
+ (elf_backend_plt_readonly): No.
+ (elf_backend_plt_alignment): 8.
+
+ * elf.c (_bfd_elf_close_and_cleanup): New function; free the shstrtab.
+ * elf-bfd.h (_bfd_elf_close_and_cleanup): Declare it.
+ * elfxx-target.h (bfd_elfNN_close_and_cleanup): Arrange for it
+ to be called.
+
+Tue Jan 27 21:45:15 1998 Jeffrey A Law (law@cygnus.com)
+
+ * archures.c (bfd_mach_mips*): Add definitions for various MIPS
+ processors.
+ * cpu-mips.c (arch_info_struct): Add mips variants.
+ * bfd-in2.h: Rebuilt.
+
+Tue Jan 27 15:06:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Preserve the contents of
+ t2a3_b_insn.
+
+Tue Jan 27 12:47:27 1998 Robert Lipe <robertl@dgii.com>
+
+ * config.bfd (i[3456]86-sco3.2v5*): ELF now the default.
+ (i[3456]86sco3.2v5*coff): New target.
+
+Mon Jan 26 15:41:30 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd-in2.h: Rebuild with changes to chew--tab expansion.
+
+Thu Jan 22 21:26:48 1998 Richard Henderson <rth@cygnus.com>
+
+ * bfd.c (bfd_get_error_handler): Add orthogonal function.
+ * bfd-in2.h: Regenerate.
+
+Thu Jan 22 21:13:39 1998 Richard Henderson <rth@cygnus.com>
+
+ * tekhex.c (tekhex_write_object_contents): Check for no symbols.
+
+Wed Jan 21 21:19:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i386.c (coff_i386_rtype_to_howto): If COFF_WITH_PE, don't
+ adjust addend for an output common symbol (from Jimmy Blair
+ <jimmyb@wrs.com>). If COFF_WITH_PE, adjust addend for PC relative
+ defined symbol to counteract adjustment made in generic relocation
+ code.
+
+ * dwarf2.c: Include sysdep.h, not stdio.h and stdlib.h.
+
+Wed Jan 21 21:16:06 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * coff-m88k.c (GET_SCNDHR_NRELOC): Fix typo in macro name.
+ (GET_SCNDHR_NLNNO): Likewise.
+
+Mon Jan 19 12:49:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * cpu-sh.c (arch_info_struct): Correct next field of sh3e.
+
+Wed Jan 14 17:23:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-m32r.c: Add macros to handle NOP insertion.
+
+Wed Jan 14 16:15:22 1998 Richard Henderson <rth@cygnus.com>
+
+ * xcofflink.c (xcoff_mark_symbol): Don't mark the absolute section.
+ (xcoff_mark): Likewise.
+ (xcoff_build_ldsyms): Mark absolute symbols.
+
+Wed Jan 14 16:03:11 1998 Richard Henderson <rth@cygnus.com>
+
+ * bout.c (b_out_write_object_contents): Sort symbols before output
+ to keep {CALL,BAL}NAME symbols adjacent.
+ (b_out_symbol_cmp): New function.
+
+For older changes see ChangeLog-9697
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-9193 b/bfd/ChangeLog-9193
new file mode 100644
index 00000000000..15af9319596
--- /dev/null
+++ b/bfd/ChangeLog-9193
@@ -0,0 +1,7851 @@
+Fri Dec 31 16:23:43 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Minor cleanups suggested by CodeCenter.
+ * aoutx.h, coffgen.c, ecoff.c, ecofflink.c, elf.c, libbfd.c,
+ linker.c, reloc.c, section.c, srec.c: Added /*ARGSUSED*/ as
+ appropriate.
+ * aoutx.h (struct external_exec): Removed unnecessary declaration.
+ (NAME(aout,some_aout_object_p)): Set some tdata pointers to NULL.
+ (adjust_z_magic): Removed useless variable data_vma.
+ (stringtab_init): Initialize hash_zero.
+ (add_to_stringtab): Removed unused fourth argument.
+ (NAME(aout,swap_std_reloc_out)): Removed useless variable
+ r_addend.
+ (aout_link_input_section): Added some casts.
+ * archive.c (get_extended_arelt_filename, do_slurp_coff_armap,
+ bfd_ar_hdr_from_filesystem, bsd_write_armap, coff_write_armap):
+ Minor code rewriting to make it more C like.
+ (do_slurp_bsd_armap): Added some casts.
+ * ecoff.c (ecoff_write_object_contents): Removed useless variable
+ scn_base.
+ (ecoff_write_armap): Added some casts. Use "" rather than "\0".
+ * ecofflink.c (bfd_ecoff_write_debug): Added a cast.
+ * libaout.h (struct internal_exec): Removed unnecessary
+ declaration.
+ * linker.c (_bfd_generic_indirect_link_order): Added a cast.
+ * opncls.c (new_bfd): Removed a cast.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Added
+ some casts.
+ * srec.c (internal_srec_write_object_contents): Removed useless
+ variable bytes_written.
+
+Fri Dec 31 11:46:13 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * i386mach3.c (N_TXTADDR): Don't define after all.
+ (TEXT_START_ADDR): Don't include exec header size in value.
+
+Thu Dec 30 15:47:54 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * i386mach3.c (N_TXTADDR): Define.
+
+Thu Dec 30 13:37:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Extensive changes to move the bulk of the linker into BFD so that
+ more efficient backend code can be written for specific object
+ files. Only existing efficient backend is a.out.
+ * seclet.c, seclet.h: Removed.
+ * hash.c, linker.c, genlink.h: New files.
+ * bfd-in.h: Removed bfd_error_vector. Declared hash table
+ structures and functions.
+ (JUMP_TABLE): Removed bfd_seclet_link, added
+ bfd_link_hash_table_create, bfd_link_add_symbols and
+ bfd_final_link.
+ * All backends: Changed accordingly.
+ * bfd-in2.h: Rebuilt.
+ * bfd.c (struct _bfd): Added link_next and archive_pass fields.
+ Removed ld_symbols field.
+ (bfd_nonrepresentable_section, bfd_undefined_symbol,
+ bfd_reloc_value_truncated, bfd_reloc_is_dangerous,
+ bfd_error_vector): Removed.
+ (bfd_default_error_trap, bfd_error_trap,
+ bfd_error_nonrepresentabltrap): Removed.
+ (bfd_get_relocated_section_contents): Pass link_info. Pass
+ link_order instead of seclet. Pass symbols.
+ (bfd_relax_section): Pass link_info.
+ (bfd_seclet_link): Removed.
+ (bfd_link_hash_table_create, bfd_link_add_symbols,
+ bfd_final_link): New macros.
+ * libbfd-in.h: If __GNUC__ is defined and alloca is not, define
+ alloca as __builtin_alloca. Declare internal linking functions.
+ * libbfd.h: Rebuilt.
+ * libbfd.c (bfd_seek): Comment out fseek assertion. It's worked
+ for months.
+ * reloc.c (reloc_howto_type): Added error_message argument to
+ special_function field. Changed all callers and all definitions.
+ (bfd_get_reloc_size): Make argument a const pointer.
+ (bfd_perform_relocation): Add error_message argument to hold
+ string set if return value if bfd_reloc_dangerous. Changed all
+ callers.
+ (_bfd_final_link_relocate, _bfd_relocate_contents): New functions.
+ * section.c (asection): Renamed seclets_head and seclets_tail to
+ link_order_head and link_order_tail.
+ * targets.c (bfd_target): Replaced seclet argument with link_info
+ and link_order and symbols arguments in
+ bfd_get_relocated_section_contents. Added symbols argument to
+ bfd_relax_section. Removed bfd_seclet_link. Added
+ bfd_link_hash_table_create, bfd_link_add_symbols and
+ bfd_final_link.
+ * libaout.h (struct aoutdata): Added external_syms,
+ external_sym_count, external_strings, sym_hashes fields.
+ (obj_aout_external_syms, obj_aout_external_sym_count,
+ obj_aout_external_strings, obj_aout_sym_hashes): New accessor
+ macros.
+ (WRITE_HEADERS): Only output symbols if outsymbols is not NULL.
+ * aoutx.h: Wrote new back end linker routines.
+ (translate_to_native_sym_flags): Return boolean value. Don't use
+ bfd_error_vector.
+ (NAME(aout,write_syms)): Return boolean value. Check return value
+ of translate_to_native_sym_flags and bfd_write.
+ * aout-target.h (final_link_callback): New function.
+ (MY_bfd_final_link): New function.
+ * aout-adobe.c (aout_adobe_write_object_contents): Check return
+ value of aout_32_write_syms.
+ * hp300hpux.c (MY(write_object_contents)): Likewise.
+ * i386lynx.c (WRITE_HEADERS): Likewise.
+ * libaout.h (WRITE_HEADERS): Likewise.
+ * bout.c: Changed functions to use link_info->callbacks rather
+ than bfd_error_vector, and link_orders rather than seclets.
+ * coff-alpha.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-h8500.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-z8k.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * reloc16.c: Likewise.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Look
+ up _gp in the hash table rather than in outsymbols.
+ * coff-a29k.c (a29k_reloc): Pass errors back in new error_message
+ argument rather than printing them.
+ * coffcode.h (bfd_coff_reloc16_extra_cases): Take link_info and
+ link_order arguments rather than seclet. Changed all uses and
+ definitions.
+ (bfd_coff_reloc16_estimate): Pass link_info arguments. Changed
+ all uses and definitions.
+ * libcoff.h: Rebuilt.
+ * ecoff.c (ecoff_get_extr): If symbol is defined by linker, but
+ not by ECOFF, make it scAbs.
+ (ecoff_bfd_final_link): Renamed from ecoff_bfd_seclet_link and
+ rewritten.
+ * elf32-mips.c (mips_elf_final_link): Renamed from
+ mips_elf_seclet_link and rewritten.
+ * elf32-hppa.c (elf32_hppa_stub_description): Added link_info
+ field.
+ (new_stub, add_stub_by_name, hppa_elf_build_arg_reloc_stub,
+ hppa_elf_build_long_branch_stub, hppa_look_for_stubs_in_section):
+ Added link_info arguments. Changed all callers.
+ * elfcode.h (elf_slurp_symbol_table): Don't quit if outsymbols is
+ not NULL.
+ * oasys.c (oasys_write_sections): Return boolean value rather than
+ using bfd_error_vector.
+ (oasys_write_object_contents): Check return value of
+ oasys_write_sections.
+ * hosts/std-host.h: Don't declare qsort or strtol.
+ * Makefile.in: Rebuild dependencies.
+ (BFD_LIBS): Removed seclet.o. Added hash.o and linker.o.
+ (CFILES): Removed seclet.c. Added hash.c and linker.c.
+ (HFILES): Removed seclet.h. Added genlink.h.
+
+Thu Dec 30 07:41:36 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * section.c (bfd_get_section_contents): Return zero filled buffer
+ if section has no contents.
+
+Tue Dec 28 12:43:54 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf.c (bfd_elf_generic_reloc): If this is not an inplace reloc,
+ then skip bfd_perform_relocation even if the addend is non-zero.
+
+Tue Dec 21 09:22:19 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * coffcode.h (coff_write_relocs) [SWAP_OUT_RELOC_OFFSET]: Copy
+ addend to r_offset field.
+
+ * Makefile.in (CFILES): Added coff-sparc.c. Rebuild dependencies.
+
+ * coff-sparc.c (SWAP_IN_RELOC_OFFSET, SWAP_OUT_RELOC_OFFSET,
+ CALC_ADDEND): Define.
+
+ * aix386-core.c (aix386_core_file_p): Use cd_regs[0] for computing
+ the offsetof because AIX /bin/cc does not like to take the address
+ of an array. (From Minh Tran-Le.)
+
+Thu Dec 16 13:06:32 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Thu Dec 16 15:41:06 1993 Peter Hoogenboom (hoogen@cs.utah.edu)
+
+ * elf32-hppa.c (hppa_elf_build_arg_reloc_stub): Make sure to copy
+ the return pointer into %r2 if no jump-in-call-delay-slot
+ optimization was done.
+
+ * hosts/hp300bsd.h: Correctly identify 4.3BSD vs 4.4BSD.
+
+Wed Dec 15 08:04:16 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * hosts/std-host.h: (time): Don't declare; conflicts on Mach3.
+
+ * hosts/i386mach3.h (HOST_PAGE_SIZE): Set to 1 to avoid padding.
+ (HOST_SEGMENT_SIZE): Set to 0 for same reason.
+
+ * i386mach3.c (PAGE_SIZE, SEGMENT_SIZE): Same changes as above.
+ (TEXT_START_ADDR): Correct.
+ (MY_backend_data): Define.
+
+ * aoutx.h (adjust_o_magic, adjust_z_magic, adjust_n_magic):
+ New functions; code moved from aout_<size>_adjust_sizes_and_vmas.
+
+Tue Dec 14 21:48:33 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_begin_writing): Fix thinkos in auxiliary header
+ support.
+ (bfd_som_attach_aux_hdr): Likewise.
+
+Mon Dec 13 23:34:48 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (hppa_elf_gen_reloc_type): Handle 'T' field
+ selectors for PIC code.
+
+ * som.c (hppa_som_gen_reloc_type): Handle 'T' field selectors.
+ (som_write_fixups): Handle R_DLT_REL, R_FSEL, R_RSEL, R_LSEL
+ relocations needed by PIC.
+
+Tue Dec 7 15:47:51 1993 Stu Grossman (grossman at cygnus.com)
+
+ * nlmcode.h: Fixes to avoid compiler warnings...
+
+Tue Dec 7 15:10:54 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * libnlm.h (nlm_backend_data): Removed macro definition.
+ (nlm_alpha_backend_data): Adjusted accordingly.
+
+Sun Dec 5 19:32:08 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_begin_writing): Flesh out code for handling simple
+ auxiliary headers.
+ (bfd_som_attach_aux_hdr): New function.
+
+ * som.h (struct somdata): Add fields for attaching version and
+ copyright headers. Add accessor macros.
+
+ * som.c (R_DLT_REL, R_AUX_UNWIND, R_SEC_STMT): Add protected
+ definitions for old versions of HPUX which fail to define them.
+ (som_hppa_howto_talbe): Add R_DLT_REL, R_AUX_UNWIND, and R_SEC_STMT
+ now that they're safe. Delete bogus R_STATEMENT relocations.
+
+ * som.c (som_hppa_howto_table): Add missing R_END_TRY. Delete
+ extra R_DATA_OVERRIDE.
+ (hppa_som_gen_reloc_type): Generate a relocation for the rounding
+ mode selector if needed.
+ (som_write_fixups): Handle requests for a change in the default
+ rounding mode. Rounding modes do not consume input bytes, but
+ are just markers much like R_ENTRY and R_EXIT.
+
+Sat Dec 4 19:40:32 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ Fri Dec 3 09:55:17 1993 Pete Hoogenboom (hoogen@cs.utah.edu)
+
+ * elf32-hppa.c: (hppa_elf_reloc): Do not do code reordering when
+ the branch instruction as originally been nullified.
+ hppa_elf_reloc): Avoid useless call to bfd_put_32 () in the
+ case of no code reordering due to an LDO instruction in the
+ delay slot of the branch. Make sure to relocate the correct
+ instruction. Do not perform instruction reordering for millicode
+ calls.
+ (hppa_elf_build_arg_reloc_stub): Change the relocation type
+ to R_HPPA_STUB_CALL_17 when special processing might be needed.
+ (hppa_elf_build_long_branch_stub): Prevent code reordering on
+ a call from a linker stub to another linker stub and for millicode
+ calls. Do not trash the return register for calls from one linker
+ stub to a second linker stub.
+
+ * elf32-hppa.c: (elf_hppa_howto_table): PLABEL and DLT
+ relocations are not pc-relative.
+
+ * hppa_stubs.h: (BLE_N_XXX_0_31): New instruction used in
+ linker stub code.
+ (COPY_2_31): Likewise.
+
+Fri Dec 3 18:40:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/solaris2.mh (HDEFINES): Remove -Dconst=
+ * hosts/solaris.h: If not __GNUC__, define const as empty.
+
+Thu Dec 2 15:43:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c: Added various casts for 32/64 bit cross targeting.
+ (ecoff_mkobject_hook): Set SEC_SHARED_LIBRARY for the .reginfo
+ section so that the linker ignores it.
+ * ecofflink.c: Added various casts for 32/64 bit cross targeting.
+ (ecoff_add_bytes): Changed need argument to size_t.
+ (bfd_ecoff_debug_link_other): Check return value of
+ ecoff_add_string.
+
+ * libbfd-in.h (new_bfd): Use void rather than an empty parameter
+ list.
+ * libbfd.h: Rebuilt.
+
+ * libnlm.h (struct nlm_obj_tdata): New field backend_data.
+ (nlm_backend_data, nlm_alpha_backend_data): New accessor macros.
+ (struct nlm_backend_data): New field no_uninitialized_data.
+ (nlm_no_uninitialized_data): New accessor macro.
+ * nlmcode.h (nlm_compute_section_file_positions): Handle
+ no_uninitialized_data.
+ (nlm_external_reloc_compare): Sort relocs by address for a
+ particular symbol, to make the sort more stable.
+ (nlm_write_object_contents): Cast the arguments to qsort. Get the
+ value of a debugging symbol the same way we get the value of a
+ normal symbol.
+ * nlm32-alpha.c: Various changes. Write out GP and .lita relocs.
+ Set no_uninitialized_data to true.
+ * nlm32-i386.c (nlm32_i386_backend), nlm32-sparc.c
+ (nlm32_sparc_backend): Set no_uninitialized_data field false.
+ * nlmswap.h (nlm_swap_fixed_header_out): Zero out destination
+ before filling it in.
+
+Wed Dec 1 21:47:58 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_section_type, som_decode_symcalss): New functions.
+ (som_get_symbol_info): Use them.
+ (som_slurp_symbol_table): Set the section of common and undefined
+ symbols correctly.
+
+Wed Dec 1 14:15:10 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * elfcode.h (write_relocs): Initialize local var LAST_SYM_IDX, to
+ make gcc happy.
+
+ * mipsbsd.c: Changes from Ralph Campbell:
+ (mips_howto_table_ext): MIPS_RELOC_LO16 should use
+ complain_overflow_dont.
+ (aout_mips_*_vec): Make name use "a.out" instead of "aout", to
+ make gdb happy.
+
+ * bfd.c (bfd_errmsgs): Reword invalid-target message.
+
+ * config.bfd: For sparc*-*-coff, use sparc-coff.
+ * configure.in: Handle sparccoff_vec.
+ * targets.c (sparccoff_vec): Declare.
+
+ * reloc.c (bfd_get_reloc_size): New function.
+ (struct reloc_howto_type): Update documentation of size field.
+
+Wed Dec 1 14:39:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlm32-alpha.c: New file; preliminary Alpha NetWare support.
+ * config.bfd (alpha-*-netware*): New target; use alpha-nlm.
+ * config/alpha-nlm.mt: New file.
+ * configure.in (nlm32_alpha_vec): New vector; use nlm32-alpha.o,
+ nlm32.o, and nlm.o.
+ * Makefile.in (BFD32_BACKENDS): Added nlm32-alpha.o.
+ (CFILES): Added nlm32-alpha.c.
+ Rebuilt dependencies.
+ * targets.c (nlm32_alpha_vec): Declare.
+
+ * libnlm.h (struct nlm_backend_data): New fields
+ optional_prefix_size, nlm_backend_object_p, nlm_write_prefix,
+ nlm_set_public_section, nlm_get_public_offset. Removed unused
+ nlm_write_reloc field. Changed nlm_write_import to remove
+ unnecessary symbol argument. Renamed nlm_write_externals to
+ nlm_write_external, and changed cound argument from bfd_vma to
+ bfd_size_type.
+ (nlm_optional_prefix_size, nlm_backend_object_p_func,
+ nlm_write_prefix_func, nlm_set_public_section_func,
+ nlm_get_public_offset_func): New accessor macros.
+ (nlm_write_reloc_func): Removed.
+ (nlm_write_external_func): Adjusted for field renaming.
+ * nlm32-i386.c (nlm_i386_write_import): Renamed from
+ nlm_i386_write_reloc. Removed old nlm_i386_write_import which
+ just called old nlm_i386_write_reloc.
+ (nlm_i386_write_external): Renamed from nlm_i386_write_externals.
+ Declared. Changed second argument from bfd_vma to bfd_size_type.
+ (nlm32_i386_backend): Adjusted for changes to fields and names.
+ * nlm32-sparc.c (nlm_sparc_mangle_relocs): Removed unused,
+ ifdeffed out code.
+ (nlm_sparc_write_import): Removed second argument.
+ (nlm_sparc_write_external): Renamed from
+ nlm_sparc_write_externals. Changed second argument from bfd_vma
+ to bfd_size_type.
+ (nlm32_sparc_backend): Adjusted for changes to fields and names.
+ * nlmcode.h: Removed some unused code.
+ (nlm_object_p): Don't destroy tdata pointer. Call
+ backend_object_p function if it exists.
+ (nlm_slurp_symbol_table): Removed unused variable rcount. Call
+ set_public_section_func if it exists instead of checking
+ NLM_HIBIT.
+ (nlm_compute_section_file_positions): Account for
+ optional_prefix_size.
+ (nlm_write_object_contents): Account for optional_prefix_size.
+ Removed useless variable write_reloc_func. Changed declaration
+ and call of write_import_func. Call write_prefix_func if it
+ exists. Removed unused variables len and temp. Call
+ get_public_offset_func if it exists rather than setting NLM_HIBIT.
+ * nlmswap.h: Declare functions.
+
+ * bfd-in.h (uint64_typeLOW, uint64_typeHIGH): Fully parenthesize
+ for clarity.
+ (fprintf_vma, sprintf_vma): Use %lx, not %x.
+ * bfd-in2.h: Rebuilt.
+ * hosts/alphaosf.h (uint64_typeLOW, uint64_typeHIGH): Cast results
+ to unsigned long.
+
+ * config.bfd: Don't set target64 here, as the setting is ignored.
+ * configure.in (ecoffalpha_little_vec): Set target64.
+
+ * config/alphaosf.mt (TDEFINES): Removed; setting host parameters
+ in TDEFINES is wrong.
+
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents):
+ Remove unused variable output_section.
+
+Tue Nov 30 16:45:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * irix-core.c: New file for Irix 4 and Irix 5 core support.
+ Functions taken out of coff-mips.c. Handle vmap type VMAPFILE.
+ * coff-mips.c: Irix 4 core file support moved to irix-core.c.
+ * targets.c: If IRIX_CORE defined, include irix_core_vec in
+ target_vector.
+ * config/irix4.mh (HDEFINES): Add -DIRIX_CORE.
+ (HDEPFILES): Define to be irix-core.o.
+ * config/irix5.mh (HDEFINES): Define to be -DIRIX_CORE.
+ (HDEPFILES): Define to be irix-core.o.
+ * Makefile.in (OPTIONAL_BACKENDS): Added irix-core.o. Removed
+ sco-core.o, which no longer exists.
+ (CFILES): Added all *-core.c files.
+ Rebuilt dependencies.
+
+Wed Nov 24 02:02:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (map_program_segments): Restore check of file_size !=
+ mem_size, but only if SHT_PROGBITS.
+
+ * ecofflink.c: New file to hold ECOFF debug information linking
+ routines.
+ * ecoff.c (ecoff_clear_output_flags, ecoff_rel, ecoff_dump_seclet,
+ ecoff_add_string, ecoff_get_debug): Removed. Functionality now in
+ ecofflink.c.
+ (ecoff_get_extr, ecoff_set_index): New functions.
+ (ecoff_slurp_symbolic_info): Don't save raw_size.
+ (ecoff_bfd_seclet_link): Rewrote to use ecofflink.c functions.
+ (ecoff_compute_section_file_positions): Don't set EXEC_P just
+ because there is a start address.
+ (ecoff_write_object_contents): Handle external symbols here. Use
+ ecofflink.c functions to write out debugging information.
+ * elf32-mips.c (mips_elf_read_ecoff_info, mips_elf_get_extr,
+ mips_elf_set_index): New functions.
+ (mips_elf_seclet_link): Discard empty sections, the .options
+ section and .gptab sections. Handle linking .mdebug section.
+ * libecoff.h (ecoff_data_type): Removed raw_size and ifdbase.
+ * libelf.h (elf_symbol_type): Added mips_extr to tc_data union.
+ * bfd-in.h: Added prototypes for routines in ecofflink.c (some are
+ called by gas, so they are public).
+ * bfd-in2.h: Rebuilt.
+ * Makefile.in (BFD_LIBS): Added ecofflink.o.
+ (CFILES): Added ecofflink.c.
+ (ecofflink.o): New target. Rebuilt dependencies.
+
+Mon Nov 22 22:26:42 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (hppa_object_p): Also recognize SHARED_MAGIC_CNX as
+ a valid magic number if it's been defined.
+
+Mon Nov 22 14:17:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_mkobject): Don't create .scommon section; linker
+ no longer requires it.
+ (ecoff_bfd_seclet_link, ecoff_sizeof_headers,
+ ecoff_write_object_contents): Don't treat .scommon section
+ specially.
+
+Mon Nov 22 10:54:27 1993 Fred Fish (fnf@cygnus.com)
+
+ Merged changes from kev@spuds.geg.mot.com (Kevin A. Buettner):
+ * bfd/config/delta88.mh (HDEFINES): Define this to be -DPTRACE_CORE.
+ * bfd/config/delta88.mh (HDEPFILES): Defined to be ptrace-core.o.
+ * bfd/ptrace-core.c: New file for dealing with core files with
+ start with the ptrace_user structure found on BCS compliant systems.
+ * bfd/targets.c (ptrace_core_vec): New vector.
+
+Mon Nov 22 02:33:12 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Minimal support for reading SOM fixup streams. Allows
+ objdump -r to do something reasonable.
+ * som.c (som_get_reloc_upper_bound): Implement.
+ (som_canonicalize_reloc): Implement.
+ (som_set_reloc_info, som_slurp_reloc_table): New functions.
+
+Sun Nov 21 13:46:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hosts/lynx.h (FPRINTF_ALREADY_DECLARED): Define.
+ * hosts/sparclynx.h: Include lynx.h instead of duplicating it.
+
+Fri Nov 19 14:34:04 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-a29k.c (a29k_reloc): For R_IREL, don't left shift
+ signed_value before sign extending it. Don't subtract out
+ reloc_entry->address. This makes it compatible with what gas is
+ generating.
+
+ * elfcode.h (elf_fake_sections): Accept .sbss as the name for a
+ SHT_NOBITS sections.
+ (map_program_segments): Don't leave the loop after the first
+ SHT_NOBITS section.
+ (assign_file_positions_except_relocs): Only force sh_offset and
+ sh_addr to match modulo maxpagesize for a section which is not
+ SHT_NOBITS. Changed the method used to force page alignment after
+ a SHT_NOBITS section to only do it for the last such consecutive
+ section, and to really force page alignment.
+
+Fri Nov 19 04:02:01 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * coffcode.h (coff_slurp_symbol_table): Print more verbose message
+ in the case of an unknown (or unhandled) storage class.
+
+ * config/i386-lynx.mt (TDEFINES): FPRINTF_ALREADY_DECLARED should
+ not be defined here, since it is a host attribute, not a target
+ one.
+ * config/m68k-lynx.mt, config/sparc-lynx.mt: Ditto.
+
+ * coffcode.h (coff_bfd_reloc_type_lookup): Don't define if already
+ defined.
+
+ * coff-sparc.c: Define some relocations, based on ELF relocations.
+ (enum reloc_type, bfd_coff_generic_reloc, coff_sparc_howto_table,
+ struct coff_reloc_map, sparc_reloc_map,
+ coff_sparc_reloc_type_lookup): Borrowed from elf32-sparc.c and
+ elf.c, renamed.
+ (coff_bfd_reloc_type_lookup): Define to be coff_sparc_reloc_....
+ (rtype2howto): Index into coff_sparc_howto_table using
+ dst->r_type.
+
+Thu Nov 18 11:45:39 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config.bfd (mips*-*-irix5*): New target; use mipsbelf.
+ * configure.host (mips-sgi-irix5*) New host; use irix5 (no
+ hosts/irix5.h created; just use std-host.h).
+ * config/irix5.mh: New file; like irix4.mh, but don't use -G or
+ -lmalloc.
+ * Makefile.in: Rebuilt dependencies.
+
+ * ecoffswap.h: Changed type of internal pointers for swap out
+ functions to const *.
+
+ * elf32-mips.c (mips_elf_got16_reloc): New function. Handle GOT16
+ correctly for assembler, but linker support not implemented.
+ (elf_mips_howto_table): Use mips_elf_got16_reloc for GOT16.
+ (mips_elf_sym_is_global): New function; at least on Irix 5, all
+ non section symbols are considered global.
+ (elf_backend_sym_is_global): Define.
+ (mips_elf_final_write_processing): New function. Set the MIPS
+ architecture level correctly.
+ (elf_backend_final_write_processing): Define.
+ (mips_elf_section_from_shdr): Handle SHT_MIPS_OPTIONS.
+ (mips_elf_fake_sections): Set entsize of .mdebug or .reginfo
+ section to 1. Handle .options section.
+ (mips_elf_acom_section, mips_elf_acom_symbol,
+ mips_elf_acom_symbol_ptr): New static variables, used to build a
+ generic .acommon section to hold SHN_MIPS_ACOMMON symbols.
+ (mips_elf_symbol_processing): Handle SHN_MIPS_ACOMMON symbols by
+ putting them all in a global .acommon section.
+
+ * elfcode.h (bfd_section_from_shdr): Don't dump core if target
+ section has no ELF section data.
+ (elf_make_sections): Set addralign of reloc section to 4.
+ (elf_fake_sections): Likewise.
+ (map_program_segments): Don't consider section 0.
+ (assign_file_positions_except_relocs): Don't consider section 0.
+ In the main loop, skip the symtab and strtab sections, since their
+ positions are set elsewhere.
+ (swap_out_syms): Set addralign of symtab section to 4. Set
+ addralign of strtab sections to 1.
+ (assign_file_positions_for_relocs): Don't consider section 0.
+ (write_object_contents): Don't write out section 0.
+
+ * libelf.h (struct elf_backend_data): Added fields
+ elf_backend_sym_is_global and elf_backend_final_write_processing.
+ * elf32-target.h (elf32_bed): Added corresponding initializers.
+ * elf64-target.h (elf64_bed): Likewise.
+ * elfcode.h (sym_is_global): Take abfd argument. Call
+ elf_backend_sym_is_global if it is not NULL.
+ (elf_map_symbols): Pass abfd to sym_is_global.
+ (write_object_contents): Call elf_backend_final_write_processing
+ if it is defined.
+
+Wed Nov 17 18:43:28 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libecoff.h: Include coff/ecoff.h.
+ (struct ecoff_backend_data): Move external debugging information
+ fields into a single field pointing to an ecoff_debug_swap
+ structure.
+ (ecoff_data_type): Move debugging information fields into a single
+ field pointing to an ecoff_debug_info structure.
+ * coff-alpha.c, coff-mips.c, ecoff.c: Corresponding changes.
+
+Wed Nov 17 17:38:58 1993 Sean Eric Fagan (sef@cygnus.com)
+
+ * nlmswap.h: New file to swap fixed header. Included by NLM
+ backends.
+ * libnlm.h (struct reloc_and_sec): Define.
+ (struct nlm_backend_data): Add fields fixed_header_size,
+ nlm_read_import, nlm_write_import, nlm_swap_fhdr_in,
+ nlm_swap_fhdr_out.
+ (nlm_fixed_header_size, nlm_read_import_func,
+ nlm_write_import_func, nlm_swap_fixed_header_in_func,
+ nlm_swap_fixed_header_out_func, nlm_write_external_func): New
+ accessor macros.
+ * nlmcode.h: Use new functions.
+ * nlm32-i386.c: Provide new functions.
+ * nlm32-sparc.c: New file; SPARC NLM backend.
+
+Wed Nov 17 13:56:10 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * i386lynx.c (swap_std_reloc_in, swap_ext_reloc_in): Ignore
+ garbage bits appearing in the upper end of symbolnums.
+
+ * config/sparc-lynx.mt (TDEFINES): Add -DFPRINTF_ALREADY_DECLARED.
+
+Tue Nov 16 17:03:41 1993 Stu Grossman (grossman at cygnus.com)
+
+ * lynx-core.c (lynx_core_file_p): Change bfd_zalloc to bfd_alloc.
+ * m68klynx.c: Define core file macros.
+ * hosts/i386lynx.h, hosts/m68klynx.h, hosts/lynx.h: Move all
+ non-architecture specific stuff into lynx.h.
+
+Tue Nov 16 15:45:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i386linux.c: Define new macro ZMAGIC_DISK_BLOCK_SIZE to 1024, and
+ change PAGE_SIZE to 4096.
+
+Mon Nov 15 11:48:08 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * Makefile.in (diststuff): New target.
+
+ * VERSION: Updated.
+
+Sun Nov 14 23:33:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_object_setup): Do not create dummy ".text", ".data",
+ and ".bss" sections.
+ (setup_sections): Do not set SEC_HAS_CONTENTS if a section's size
+ is zero. Recognize BSS type sections and turn off SEC_LOAD and
+ SEC_DATA (so binutils/size works). Set the correct value for
+ a section's _raw_size.
+ (som_slurp_symbol_table): Program entry points, and millicode are
+ also functions. Mark them as such. Also mark L$* symbols as
+ debugging symbols.
+
+ * bfd-in2.h: Rebuilt.
+
+Sat Nov 13 15:27:15 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_reloc_type_lookup): Add missing prototype. Returns
+ a pointer to constant data. Delete bogus #define which made the
+ function useless.
+
+ * som.c (som_prep_for_fixups): New function.
+ (som_write_fixups): New function.
+ (som_write_space_strings): New function.
+ (som_write_symbol_strings): New function.
+ (som_begin_writing): New function.
+
+Fri Nov 12 15:29:36 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_write_object_contents): Do not abort. Flesh out.
+ (som_set_section_contents): Do not abort. Flesh out.
+
+ * som.c (som_write_headers): New function.
+ (som_prep_headers): New function.
+ (som_build_and_write_symbol_table): New function.
+
+ * som.c (som_sizeof_headers): Add missing prototype.
+ (som_set_arch_mach): Do not abort.
+
+ * som.c (som_count_spaces): New function.
+ (som_count_subspaces): New function.
+ (compare_syms): New function.
+ (som_compute_checksum): New function.
+
+ * som.c (hppa_som_gen_reloc_type): New function.
+ (som_bfd_reloc_type_lookup): New function.
+
+ * som.c (try_prev_fixup): New function.
+ (som_reloc_skip): New function.
+ (som_reloc_addend): New function.
+ (som_reloc_call): New function.
+
+ * som.c (som_initialize_reloc_queue): New function.
+ (som_reloc_queue_insert): Likewise.
+ (som_reloc_queue_fix): Likewise.
+ (som_reloc_queue_find): Likewise.
+
+ * som.c (som_hppa_howto_table): SOM howto relocation table.
+ (hppa_som_reloc): New function.
+
+ * som.c (struct reloc_queue): New structure to keep track of
+ the last four multibyte relocations emitted.
+ (enum pa_symbol_type): Type to fully describe the symbol types
+ associated with .import/.export assembler directives.
+
+ * som.c: Include libhppa.h
+
+ * som.c (bfd_som_set_section_attributes): New function.
+ (bfd_som_set_subsection_attributes): Likewise.
+ (bfd_som_set_symboL_type): Likewise.
+ (bfd_som_attach_unwind_info): Likewise.
+ * som.h: Declare new exported functions.
+
+ * som.h (struct som_symbol): Add new fields to hold additional
+ information needed to build/write symbol tables and fixup streams.
+ (struct som_section_data_struct): Add new fields to hold additional
+ information needed to build/write space and subspace headers.
+ (som_symbol_data): New accessor macro for SOM symbol information.
+ (R_HPPA_*): Basic relocation types to be used by the assembler.
+
+Fri Nov 12 11:00:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * trad-core.c (trad_unix_core_file_p): If new hook
+ TRAD_CORE_ALLOW_ANY_EXTRA_SIZE defined, then skip the check for the
+ corefile being too big.
+ * hosts/i386sco.h: Define it.
+
+Thu Nov 11 15:16:28 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * bfd.c (struct _bfd): Add hppabsd_core_data.
+ * targets.c (target_vector): Add hppabsd_core_vec.
+ * hpux-core.c (hpux_core_core_file_p): Fail if an unknown core
+ section is encountered during core section scanning.
+ * hppabsd-core.c: New file.
+ * config/hppabsd.mh: Enable HPPA BSD core files.
+
+ * elf32-hppa.c (hppa_elf_reloc): Remove DEFUN crud. Remove code
+ which is either commented out or ifdef'd out. Add, update and
+ clean comments. Fix various indention and spacing problems. Handle
+ problems related to using "ble" to jump to a stub rather than "bl"
+ (%r31 is trashed by "ble", but not by "bl").
+ (NEW_INSTRUCTION): Put inside curly braces.
+ (CURRENT_STUB_OFFSET): Fix indention problems.
+ (hppa_elf_build_arg_reloc_stub): Fix indention and spacing problems.
+ Add, update and clean comments. Handle "ble" %r31 lossage problems.
+ (hppa_elf_build_long_branch_stub): Likewise.
+ (hppa_look_for_stubs_in_section): Likewise.
+ (hppa_elf_stub_check): Remove obsolete function.
+
+ * hppa_stubs.h: Add new instructions to deal with %r31 lossage
+ problems. Delete unused instructions.
+
+Tue Nov 9 11:40:27 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * m68klynx.c (TARGET_IS_BIG_ENDIAN_P): Define.
+
+Tue Nov 9 11:26:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (elf_object_p): Rather than looking through an array
+ of architectures, get the ELF EM_xxx code from the backend
+ information. Let the generic ELF target match any EM_xxx code not
+ matched by another ELF target. Call elf_backend_object_p to let
+ the backend do more checks and set global information.
+ * libelf.h (struct elf_backend_data): Added elf_machine_code and
+ elf_backend_object_p fields.
+ (struct bfd_elf_arch_map): Removed.
+ (bfd_elf_arch_map, bfd_elf_arch_map_size): Don't declare.
+ * elf32-target.h, elf64-target.h: Initialize elf_machine_code
+ field with ELF_MACHINE_CODE. Initialize elf_backend_object_p
+ field with elf_backend_object_p (if it is defined).
+ * elf32-gen.c, elf32-hppa.c, elf32-i386.c, elf32-i860.c,
+ elf32-m68k.c, elf32-m88k.c, elf32-mips.c, elf32-sparc.c,
+ elf64-gen.c (ELF_MACHINE_CODE): Defined.
+ * elf32-mips.c: Include ecoffswap.h to get ECOFF swapping
+ routines.
+ (mips_elf_object_p): Set the right machine number.
+ (mips_elf_ecoff_debug_swap): Defined.
+ (elf_backend_object_p): Defined to be mips_elf_object_p.
+ (elf_backend_ecoff_debug_swap): Defined to be
+ mips_elf_ecoff_debug_swap.
+ * elf.c (bfd_elf_arch_map, bfd_elf_arch_map_size): Removed.
+
+ * libbfd-in.h (target_vector, default_vector): Declare.
+ * libbfd.h: Rebuilt.
+ * format.c (target_vector, default_vector): Don't declare.
+
+ * elf32-mips.c (elf_mips_howto_table): Don't complain on overflow
+ for R_MIPS_26. Correct overflow detection requires matching the
+ upper four bits of the destination against the PC. From Ted Lemon
+ <mellon@pepper.ncd.com>.
+
+ * bout.c (b_out_reloc_type_lookup): Return type should point to
+ const data.
+ * coff-i960.c (coff_i960_reloc_type_lookup): Likewise.
+ * elf32-hppa.c (elf_hppa_reloc_type_lookup): Likewise.
+ * mipsbsd.c (MY(reloc_howto_type_lookup)): Likewise.
+ * coff-i386.c (coff_i386_reloc): Made howto const.
+ * oasys.c (oasys_write_data): Made how const.
+
+ * libelf.h: Added some comments.
+ (struct elf_backend_data): Added elf_backend_ecoff_debug_swap
+ field. Removed unused write_relocs field.
+ * elf32-target.h: Adjusted elf_backend_data initialization
+ accordingly.
+ * elf64-target.h: Corrected elf_backend_data initialization to
+ fill in all fields and to set elf_64_p to 1.
+
+Mon Nov 8 18:13:14 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (bfd_section_from_shdr): Remove duplicate assignment
+ to filepos in SHT_STRTAB case.
+ (assign_file_position_for_section): Set BFD section filepos as
+ well as ELF section sh_offset.
+
+ * reloc.c: Use const instead of CONST.
+ (bfd_perform_relocation): Make variable howto a const pointer.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+Mon Nov 8 12:19:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (realclean): Don't remove generated headers. Reverts
+ change of 2 Jul 1993.
+
+Mon Nov 8 06:08:31 1993 D. V. Henkel-Wallace (gumby@cirdan.cygnus.com)
+
+ * configure.bfd: make unixware equivalent to sysv4.
+
+ * config/i386-nlm.mt: bring in elf config; make it the default.
+
+Sun Nov 7 20:21:38 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * libbfd.c (bfd_put_8): Add parens around reference to "val"
+ argument.
+
+Fri Nov 5 21:45:09 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * hosts/i386mach3.h (HOST_SEGMENT_SIZE),
+ i386mach3.c (SEGMENT_SIZE, TEXT_START_ADDR): Correct values (?).
+
+Fri Nov 5 15:17:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffcode.h (coff_write_object_contents): Zero out internal_a.
+
+Fri Nov 5 10:41:07 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h, archive.c, archures.c, bfd.c, cache.c, coffcode.h,
+ core.c, ctor.c, format.c, init.c, libbfd.c, opncls.c, reloc.c,
+ section.c, syms.c, targets.c:
+ Doc cleanup (spelling, punctuation, grammar, formatting).
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+Thu Nov 4 14:46:14 1993 John Gilmore (gnu@rtl.cygnus.com)
+
+ * bfd-in.h (bfd_get_cacheable, bfd_set_cacheable): New accessors.
+ * bfd.c, opncls.c: Improve comments on file descriptor cacheing.
+
+Thu Nov 4 08:54:30 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * From Pete Hoogenboom (hoogen@cs.utah.edu)
+ * elf32-hppa.c (hppa_elf_get_section_contents): Fix logic error
+ in last change. Always rebuild symbol extension section the first
+ time though if output sections exist (fixes ld -r problems).
+
+Thu Nov 04 08:08:46 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Add .PHONY for check and installcheck rules.
+
+Tue Nov 2 14:42:27 1993 Bill Cox (bill@tarkas.cygnus.com)
+
+ * libbfd-in.h (artdata): Use long, not time_t for portability, at
+ least to HPUX. File below is a derived file.
+
+Tue Nov 2 14:42:27 1993 Bill Cox (bill@tarkas.cygnus.com)
+
+ * libbfd.h (artdata): Use long, not time_t for portability, at
+ least to HPUX.
+
+Tue Nov 2 09:32:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.bfd: Use bigmips for mips*-*-bsd*.
+
+Mon Nov 1 14:30:09 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (elf_slurp_reloca_table, elf_slurp_reloc_table):
+ Handle symbol number of zero.
+
+ * reloc.c (enum bfd_reloc_code_real): Added
+ BFD_RELOC_MIPS_LITERAL, BFD_RELOC_MIPS_GOT16,
+ BFD_RELOC_MIPS_CALL16, BFD_RELOC_MIPS_GPREL32.
+ * bfd-in2.h: Rebuilt.
+ * coff-mips.c (mips_bfd_reloc_type_lookup): Handle
+ BFD_RELOC_MIPS_LITERAL.
+ * elf32-mips.c (mips_reloc_map): Handle new relocs.
+ (mips_elf_hi16_reloc, mips_elf_lo16_reloc): Rearrange _gp_disp
+ checks slightly.
+
+ * aout-target.h (MY_bfd_debug_info_start, MY_bfd_debug_info_end,
+ MY_bfd_debug_info_accumulat [sic]): Remove unused definitions.
+ (MY_bfd_get_relocated_section_contents, MY_bfd_relax_section,
+ MY_bfd_seclet_link): Define.
+ (MY_bfd_reloc_type_lookup): Rename from
+ MY_reloc_howto_type_lookup.
+ (MY_bfd_make_debug_symbol): Rename from MY_make_debug_symbol.
+ (MY(vec)): Use JUMP_TABLE rather than listing functions.
+ * hp300hpux.c (MY_get_symtab, MY_get_symtab_upper_bound,
+ MY_canonicalize_reloc, MY_write_object_contents): Don't define in
+ terms of MY, because that causes a recusive invocation of CAT when
+ expanded within JUMP_TABLE, and ANSI compilers don't expand
+ recursive macros.
+ * mipsbsd.c (MY_bfd_reloc_type_lookup): Rename from
+ MY_reloc_howto_type_lookup, and don't define in terms of MY.
+ (MY_canonicalize_reloc): Don't define in terms of MY.
+ (aout_mips_little_vec, aout_mips_big_vec): Use JUMP_TABLE rather
+ than listing functions.
+
+Mon Nov 1 09:12:25 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.bfd: Use m68k-elf for m68*-*-sysv4*.
+
+Sun Oct 31 09:35:49 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * targets.c: Move enum target_flavour outside of struct and change
+ the name to enum bfd_flavour. This means bfd clients can use it.
+ * bfd-in.h: Add macro bfd_get_flavour.
+ * bfd-in2.h: Rebuilt.
+
+ * som.c: Add comment about how abort() on corrupt executable is evil.
+
+Sat Oct 30 12:27:09 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (aout,slurp_reloc_table): Avoid a goto.
+
+Fri Oct 29 16:04:33 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * gen-aout.c, libbfd.c: exit(1) instead of exit(-1).
+
+Fri Oct 29 13:17:21 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd-in.h: Added commands for object file flag values.
+ * bfd-in2.h: Rebuilt.
+ * elfcode.h (elf_object_p): If type is ET_DYN, set DYNAMIC flag,
+ not EXEC_P.
+ * bout.c, coff-h8300.c, coff-sh.c: Add BFD_IS_RELAXABLE to
+ object_flags field for target vector.
+ * aix386-core.c, aout-adobe.c, aout-target.h, bout.c, coff-a29k.c,
+ coff-alpha.c, coff-apollo.c, coff-h8300.c, coff-h8500.c,
+ coff-i386.c, coff-i960.c, coff-m68k.c, coff-m88k.c, coff-mips.c,
+ coff-rs6000.c, coff-sh.c, coff-we32k.c, coff-z8k.c, hpux-core.c,
+ ieee.c, mipsbsd.c, nlm-target.h, oasys.c, osf-core.c, som.c,
+ srec.c, tekhex.c, trad-core.c: Remove DYNAMIC from object_flags
+ field for target vector.
+
+Thu Oct 28 20:02:31 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * hosts/std-host.h: Don't declare time; causes error on mach3.
+ * configure.in (i386mach3_vec): Require aout32.o stab-syms.o.
+
+Thu Oct 28 16:33:26 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ LynxOS and Sparc LynxOS changes:
+ * config.bfd: Recognize sparc-*-lynxos*.
+ * configure.host: Recognize sparc-*-lynxos*.
+ * configure.in: Recognize Sparc Lynx vectors.
+ * targets.c (sparclynx_aout_vec): Declare.
+ (sparclynx_coff_vec): Declare.
+ (target_vector): Add them.
+ * cf-i386lynx.c: New file, renamed from i386lynx-cf.c.
+ * cf-m68klynx.c: New file, renamed from m68klynx-cf.c.
+ * cf-sparclynx.c: New file, support for coff in Sparc LynxOS.
+ * coff-sparc.c: New file, basic Sparc coff support.
+ * sparclynx.c: New file, support for a.out in Sparc LynxOS.
+ * Makefile.in: Change filenames appropriately, add Sparc rules.
+ * coffcode.h (coff_set_arch_mach_hook): Recognize Sparc magic
+ number.
+ (coff_set_flags): Use LynxOS magic number for i386, m68k, and
+ Sparc LynxOS, set Sparc magic number for Sparcs.
+ * config/m68k-lynx.mt (SELECT_VECS): Remove redundant vector.
+ * config/sparc-lynx.mt: New file.
+ * hosts/i386lynx.h: Cosmetic improvements.
+ * hosts/m68klynx.h: Add ifdefs, #define of cfree.
+ * hosts/sparclynx.h: New file.
+
+Thu Oct 28 16:23:40 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ gcc -Wall lint:
+ * coff-h8300.c (h8300_reloc16_estimate): Declare return type.
+ Remove useless statement probably left by code copy.
+ * cpu-i960.c (compatible): Fully bracket matrix initializer.
+ * elf32-hppa.c (hppa_elf_build_arg_reloc_stub): Use bfd_xmalloc
+ rather than xmalloc. Use realloc and check the return value
+ rather than xrealloc.
+ (hppa_elf_get_section_contents): Add some casts.
+ * elf32-i386.c (elf_i386_reloc_type_lookup): Remove unused
+ variable. Add default case to switch.
+ * hp300hpux.c: Declare aout_32_write_syms.
+ * i386bsd.c, i386linux.c, netbsd386.c (N_SHARED_LIB): Define as 0
+ (definition from aout/aout64.h is always 0 anyhow).
+ * i386lynx.c (swap_std_reloc_in): Remove unused variable.
+ * ieee.c (ieee_write_id): length can never be negative.
+ (read_id): Likewise.
+ (ieee_archive_p): Remove unused variable.
+ * libcoff-in.h (bfd_perform_slip): Declare.
+ * libcoff.h: Rebuilt.
+ * oasys.c (oasys_write_sections): Remove zero initialization of
+ static structure.
+ * reloc16.c: Indentation change.
+
+Wed Oct 27 16:51:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in, config/i386-mach3.mt: Update for new configuration
+ (--with-targets and so on).
+ * hosts/i386mach3.h: Declare errno.
+ * targets.c: Declare i386mach3_vec.
+
+Wed Oct 27 12:18:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmcode.h (nlm_swap_auxiliary_headers_in,
+ nlm_swap_auxiliary_headers_out): Handle sharedDebugRecordOffset
+ and sharedDebugRecordCount fields.
+
+Tue Oct 26 16:21:12 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * targets.c (target_vector): Remove SCO_CORE. On Sep 11 1993,
+ we started using trad-core.c for SCO instead.
+
+ * targets.c (target_vector): Re-enable generic ELF and NLM targets.
+
+Tue Oct 26 16:53:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (assign_file_position_for_section): Align sh_offset to
+ sh_addralign (this is what UnixWare does, and it shouldn't hurt).
+
+Tue Oct 26 10:16:54 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ From Jeff Law and Pete Hoogenboom at Utah:
+
+ * elf32-hppa.h (hppa_elf_stub_finish): Add prototype.
+ (ELF32_HPPA_R_ARG_RELOC): Renamed without the ELF32 prefix
+ and moved into libhppa.h. All references changed.
+ (ELF32_HPPA_R_CONSTANT, ELF32_HPPA_R_ADDEND): Likewise.
+ (get_opcode and opcode defines): Move into libhppa.h
+ * elf32-hppa.c (hppa_elf_insn2fmt): Rename and move info
+ libhppa.h.
+ * libhppa.h (HPPA_R_*): Moved here. Reformatted slightly to make
+ for easier reading.
+ (get_opcode): Moved here. FIXME! this really should be a C function
+ inside the opcode library!
+ (bfd_hppa_insn2fmt): Likewise.
+
+ * targets.c (target_vector): Enable elf32-hppa vector.
+
+ * elf32-hppa.c (hppa_elf_get_section_contents): Add new comments
+ and clarify existing comments. Do not use DEFUN to declare this
+ function. Fix numerous indention problems. Correctly handle cases
+ where symbol extension section may need to be read from disk,
+ read from memory, or built then read from memory.
+
+ * elf32-hppa.h: Reformat with gnu-indent and hand fix numerous
+ formatting and indention problems gnu-indent can not handle.
+ Clarify some comments about relocation types. Comment basic
+ relocation "classes". Group PARAM declarations together.
+ (HPPA_SXT_{NULL, SYMNDX, RG_RELOC}): Make members of a new
+ enumerated type rather than #defines.
+
+Tue Oct 26 02:40:46 1993 Stu Grossman (grossman at cygnus.com)
+
+ * som.c (hppa_object_setup): Set SEC_CODE for .text section so
+ that GDB can figure out text_start and text_end.
+
+Mon Oct 25 16:05:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Fix up warnings from gcc -Wall:
+ * coffgen.c (coff_print_symbol): Use %lx and cast n_value to
+ unsigned long. Use %ld for tagndx. Use %lx for offset + vma and
+ cast it to unsigned long.
+ * ecoff.c (ecoff_emit_aggregate): Use %ld.
+ (ecoff_print_symbol): Use %ld, and cast indx and sym_base to long.
+ * coffcode.h (dummy_reloc16_estimate): Specify return type.
+
+ * libbfd.c (bfd_write): If not everything is written out, set
+ bfd_error to system_call_error. If the return value is
+ non-negative, set errno to ENOSPC (if ENOSPC is defined).
+ (bfd_seek): If the seek fails, set bfd_error to system_call_error.
+ (bfd_generic_set_section_contents): For a bad offset + count, set
+ bfd_error to bad_value.
+ * seclet.c (rel): Don't abort. Instead, return false.
+
+Mon Oct 25 09:59:37 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * aoutx.h (reloc_type_lookup): Handle BFD_RELOC_SPARC_WDISP22.
+
+Fri Oct 22 20:35:54 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config.bfd: handle mips*-* instead of mips-*, use mips*el
+ instead of mips-*-*l
+
+Fri Oct 22 14:03:33 1993 Mark Eichin (eichin@cygnus.com)
+
+ * m68k-lynx.mt, i386-lynx.mt (TDEFINES): set
+ FPRINTF_ALREADY_DECLARED because the objdump.c declaration of
+ fprintf collides with the native one.
+
+Fri Oct 22 11:50:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * targets.c (target_vector): Enable MIPS ELF vectors.
+
+Fri Oct 22 07:51:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.bfd: Use bigmips for mips-sony-bsd*.
+
+ * configure.host, config.bfd: Add * to end of all OS names.
+
+Thu Oct 21 12:16:26 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * elfcode.h (FILE_ALIGN): Renamed from EALIGN, to avoid conflict
+ with Ultrix header files.
+
+ * som.h (struct som_section_data_struct): Renamed from
+ som_section_data to avoid conflict with macro by that name.
+
+ Changes from Jeff Law and Peter Hoogenboom at Utah:
+
+ * elf32-hppa.c (hppa_elf_reloc): Target register for a 'jump
+ in delay slot' optimization in combination with a long call
+ stub should always be r31.
+
+ * elf32-hppa.c: (hppa_elf_relocate_insn): To be consistent
+ across all relocation types, retrieve instruction addends from
+ the relocation entry rather than from the instruction itself.
+
+ * elf32-hppa.c: (hppa_elf_relocate_insn): Fix a relocation
+ error that only occurred when the addend of an 'addil' or
+ 'ldil' was larger than 21 bits and very close to a 2K byte
+ boundary.
+
+ * elf32-hppa.c: (hppa_elf_reloc): Handle the optimization in
+ which a jump is placed in the delay slot of a function call.
+ The jump was being accomplished via an adjustment to the
+ return pointer. This optimization would break the long call
+ stub code, if there was any.
+
+ * elf32-hppa.c: (hppa_elf_build_long_branch_stub): Corrections
+ to long branch stubs to avoid use of general register 2.
+
+ * hppa_stubs.h: New stub instructions.
+
+ * elfcode.h: Declare bfd_elf_find_section.
+
+ * som.h (som_section_data): Add new "subspace_index" field.
+
+ * som.c (setup_sections): Save the original SOM subspace index
+ in the BFD section associated with that subspace.
+ (som_get_symtab_upper_bound): Implement.
+ (som_get_symtab): Implement.
+ (som_print_symbol): Implement.
+ (som_slurp_string_table): New function to read a string table
+ from a SOM object file.
+ (som_section_from_subspace_index): New function to return the
+ section which corresponds to a SOM subspace index.
+ (som_slurp_symbol_table): New function to read the symbol
+ table from a SOM object file.
+ (som_make_empty_symbol): Check for errors from bfd_zalloc.
+ (som_new_section_hook): Initialize subspace_index field to
+ -1 instead of 0.
+
+ * som.c (som_object_setup): Fix polarity of test to set HAS_RELOC.
+ Set EXEC_P for executables.
+ (setup_sections): Correctly identify when a section has
+ relocations.
+ (log2): New function.
+ (setup_sections): Correctly convert between SOM alignments and BFD
+ alignments.
+
+ * som.c (setup_sections): Do not set SEC_ALLOC or SEC_LOAD
+ for sections which correspond to SOM spaces, doing so confuses
+ many utilities. Set assorted SEC_* flags for SOM subspaces
+ which correspond to BFD sections.
+
+ * elf32-hppa.c: (elf32_hppa_backend_fake_sections): The stab
+ string table should have sh_type == SHT_STRTAB. Add
+ processing to make it so.
+
+ * elfcode.h: (bfd_section_from_shdr): String tables (other
+ than .strtab) were not getting the file offsets recorded, so
+ they could not be read from disk.
+
+ * elfcode.h: (elf_make_sections): Leave the sh_addr field of
+ the section header and the vma field of a section at 0 if the
+ section is not part of the program execution image. (e.g.,
+ .stab)
+
+ * som.[hc]: Change target vector prefix from "hppa" to "som".
+ Consistently use obj_som prefix to access fields in backend data
+ structures. Fix all callers/references.
+
+ * som.h: Do not include files only needed for core file reading here.
+ Include a.out for both HOST_HPPAHPUX and HOST_HPPABSD. Delete
+ forward structure declarations, they are unnecessary.
+ (struct somdata): Delete aux_hdr, and hp_symbol_entry_size fields.
+ Change "symbols" to "symtab". Add "stringtab" and "reloc_filepos"
+ fields for future use. Change obj_som_* macros as appropriate.
+ (som_section_data): New structure to keep SOM specific information
+ about BFD sections (for future use).
+
+ * som.c: Provide PARAMS declarations for all functions currently
+ in this file.
+ (struct container): Delete unwanted structure definition.
+ (som_object_setup): Add comments. Use som_mkobject to allocate
+ SOM specific information in the BFD; use information from the
+ file and (possibly empty) auxiliary headers to initialize this
+ information. Delete redundant bfd_get_symcount (abfd) "calls".
+ (setup_sections): Return type is now boolean, fix return statements.
+ "Fix" handling of BSS like subspaces in the computation of the
+ containing space's size. If the subspace has relocations, set the
+ appropriate BFD section flags and record the index into and the
+ size of the fixup stream. Always return a value.
+ (som_object_p): Set bfd_error appropriately if errors are detected
+ from bfd_{read,seek} functions. Handle EXECLIBMAGIC type files.
+ Do not try to read a non-existant auxiliary header.
+ (som_mkobject): Flesh out.
+ (som_section_hook): Allocate space to hold SOM specific information
+ about sections.
+
+Thu Oct 21 12:41:34 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ gcc -Wall lint:
+ * coff-h8300.c, coffcode.h: Change shrink parameter
+ in *_reloc16_estimate to unsigned to match prototype.
+ * archive.c: Avoid "/*" in comment.
+
+Thu Oct 21 13:05:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * dep-in.sed: Create our own line breaks for a more aesthetic
+ Makefile.
+ * Makefile.in: Rebuilt dependencies.
+
+ * elf32-mips.c: Include "seclet.h".
+ (mips_elf_fake_sections): Force size of .reginfo section to sizeof
+ Elf32_External_RegInfo.
+ (mips_elf_seclet_link): New function. Link the .reginfo section
+ specially, and pass everything else to the generic routine.
+ (bfd_elf32_bfd_seclet_link): Define macro.
+ * elf32-target.h: If bfd_elf32_bfd_seclet_link is already defined,
+ don't override it.
+
+Wed Oct 20 12:22:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libnlm.h (nlm_backend_data): Added signature field.
+ (nlm_signature): New macro.
+ * nlmcode.h (nlm_object_p, nlm_write_object_contents): Use the NLM
+ signature from the backend rather than the constant NLM_SIGNATURE.
+ * nlm32-i386.c (nlm32_i386_backend): Initialize signature field.
+
+ * aoutf1.h (MACHTYPE_OK): Accept M_UNKNOWN.
+ (NAME(sunos,set_arch_mach)): Treat M_UNKNOWN as 68000, not 68020.
+
+Wed Oct 20 10:28:27 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/i386bsd.h [__bsdi__]: Define HOST_DATA_START_ADDR.
+
+Wed Oct 20 10:10:07 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (HFILES): New variable, for use in "make dep".
+ (.dep): Depend on $(CFILES) and $(HFILES). Delete .dep1 and
+ remake it, so that "$?" is complete.
+ (.dep1): Don't need to remove .dep1 first.
+ (dep.sed): Depend on config.status, not Makefile.
+ (CFILES): Add nlm.c.
+
+Tue Oct 19 15:26:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-alpha.c: Implemented reloc handling for the linker, made
+ various other related changes.
+ * libecoff.h (ecoff_backend_data): Added rdata_in_text field.
+ Renamed finish_reloc to adjust_reloc_in. Added adjust_reloc_out
+ field.
+ (ecoff_bfd_get_relocated_section_contents): Don't define.
+ * ecoff.c (ecoff_sec_to_styp_flags, ecoff_styp_to_sec_flags):
+ Handle .lita section.
+ (ecoff_slurp_reloc_table): Handle RELOC_SECTION_FINI.
+ finish_reloc backend field renamed to adjust_reloc_in.
+ (ecoff_bfd_seclet_link): Adjust number of aux entries to
+ debug_align boundary.
+ (ecoff_compute_section_file_positions): If rdata_in_text put
+ .rdata section in text segment, not data segment. Put .pdata
+ section in text segment.
+ (ecoff_write_object_contents): Likewise. Also, call
+ adjust_reloc_out, and handle .lita, .xdata, .pdata, .fini and
+ absolute sections when writing out relocs.
+ * coffswap.h (coff_swap_aouthdr_out): For ALPHAECOFF, output 2 for
+ bldrev field, as on Alpha OSF/1. Padding field is now 2 bytes.
+ * coff-mips.c (mips_ecoff_swap_reloc_out): Added assertion.
+ (mips_adjust_reloc_in): Renamed from mips_finish_reloc.
+ (mips_adjust_reloc_out): New function (does nothing).
+ (mips_ecoff_backend_data): Initialize new fields.
+ (ecoff_bfd_get_relocation_section_contents): Define to be
+ bfd_generic_get_relocated_section_contents.
+
+ * reloc.c (bfd_perform_relocation): Added casts to avoid Alpha
+ OSF/1 cc bug.
+
+Thu Oct 14 01:10:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Add comments attempting to
+ explain PC relative relocations.
+
+ * coffcode.h (styp_to_sec_flags): Don't set SEC_DEBUGGING until it
+ is made to work.
+ (coff_compute_section_file_positions): Remove check for
+ USE_DISCARDED_SECTIONS_COUNT.
+ * coff-i386.c: Don't define USE_DISCARDED_SECTIONS_COUNT. Basing
+ it on host defines is wrong.
+
+ * ecoff.c (ecoff_bfd_seclet_link): Don't link a .reginfo section.
+ (ecoff_write_object_contents): Don't require the .reginfo section
+ to be a particular size.
+
+Wed Oct 13 18:39:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (dep-in): New rule, for editing dependencies into
+ Makefile.in in $(srcdir). Use move-if-change.
+ (.dep1, dep): Use move-if-change.
+ (CFILES): Add coff-apollo.c.
+
+ Sun Oct 10 18:02:56 1993 Troy Rollo (troy@cbme.unsw.EDU.AU)
+
+ * Makefile.in: Recognise new file, coff-apollo.o
+
+ * coff-apollo.c: New file
+
+ * coffcode.h: Recognise apollo magic numbers and writable text
+
+ * coffswap.h: Swap Apollo optional header entries
+
+ * config.bfd: Add line for Apollo
+
+ * configure.host: Replace apollo68b and apollo68v with Apollo
+
+ * configure.in: Recognise apollocoff_vec
+
+ * targets.c: Likewise
+
+ * config/apollo.mh, config/apollo.mt: New files
+
+ * hosts/apollo68.h: Remove inclusion of strings.h
+
+Wed Oct 13 14:28:17 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * coff-i386.c (i3coff_object_p): Now static.
+
+ * Makefile.in: Updated dependencies.
+ (.dep, .dep1, dep.sed): New targets, to make "make dep" work
+ better.
+ * dep-in.sed: New file.
+
+ * m68klynx-cf.c (ONLY_DECLARE_RELOCS): Define, to avoid name
+ conflicts when "--with-targets=all".
+ * coff-m68k.c (m68kcoff_howto_table, m68k_rtype2howto,
+ m68k_howto2rtype): Rename via macros to keep namespace clean.
+ * configure.in: For m68klynx_coff_vec, include coff-m68k.o for
+ now.
+
+Tue Oct 12 17:03:27 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-mips.c: Extensive additions to do relocations and to
+ handle MIPS specific sections.
+ * libelf.h (elf_backend_data): Pass fourth argument to
+ elf_backend_section_from_bfd_section to permit it to control the
+ section index to use.
+ (elf_obj_tdata): Add gp and gp_size fields.
+ (elf_gp, elf_gp_size): New accessor macros.
+ * elfcode.h: Removed a number of unused local variables.
+ (elf_fake_sections): Clear section header before calling
+ elf_backend_fake_sections, not after.
+ (prep_headers): Return true at end.
+ (elf_section_from_bfd_section): Pass retval argument to
+ elf_backend_section_from_bfd_section.
+ * elf32-hppa.c (elf32_hppa_backend_section_from_bfd_section):
+ Accept and ignore new retval argument.
+ * bfd.c: Include libelf.h.
+ (bfd_set_gp_size): Handle ELF targets.
+ * Makefile.in (bfd.o): Depends upon libelf.h.
+ (elf32-mips.o): Depends upon $(INCDIR)/elf/mips.h.
+
+Mon Oct 11 17:25:18 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_mkobject): Check bfd_make_section return value.
+ (ecoff_mkobject_hook): New function.
+ (ecoff_new_section_hook, ecoff_sizeof_headers,
+ ecoff_compute_section_file_positions, ecoff_set_section_contents,
+ ecoff_write_object_contents): Handle dummy REGINFO section.
+ (ecoff_get_section_contents): New function to handle reading
+ REGINFO section.
+ * libecoff.h (ecoff_get_section_contents): Change from macro
+ definition to function prototype.
+ (ecoff_mkobject_hook): New prototype.
+ * coff-alpha.c (alpha_ecoff_mkobject_hook): Removed.
+ (alpha_ecoff_backend_data): Use ecoff_mkobject_hook.
+ * coff-mips.c (mips_ecoff_mkobject_hook): Removed.
+ (mips_ecoff_backend_data): Use ecoff_mkobject_hook.
+
+Fri Oct 8 15:25:33 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * libbfd.c (bfd_get*32, bfd_get*64): Prevent ANSI sign extension
+ by casting the most significant byte to bfd_vma.
+
+Fri Oct 8 02:34:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in: Do not define SELECT_VECS, SELECT_ARCHITECTURES
+ if configuring --with-targets=all.
+
+Thu Oct 7 17:34:07 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * aoutx.h (howto_table_std): Correct the "size" field in some
+ entries.
+
+ * reloc.c (reloc_howto_type): Change documentation to dispel any
+ notion that the "size" field is a power-of-two indicator.
+
+Thu Oct 7 10:50:38 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * coffswap.h: (bfd_swap_reloc_in): a symndx is signed.
+
+ Make support for relaxing more generic.
+ * reloc16.c: Add new target entry - bfd_coff_reloc16_estimate,
+ fix bit rot.
+ * libcoff.h, libcoff-in.h: declarations. Prototypes
+ * coffcode.h (bfd_coff_std_swap_table): Add calls to
+ coff_reloc_16_extra_cases and coff_reloc16_estimate.
+ (dummy_reloc16_estimate): New function.
+ * coff-h8300.c (h8300_reloc16_estimate): New function
+
+Thu Oct 7 14:24:13 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elfcode.h (EALIGN): Define, dependent on ARCH_SIZE.
+ (align_file_position): New function.
+ (elf_locate_sh): Disabled function deleted.
+ (assign_file_positions_for_symtab_and_strtabs): Align position,
+ then place symtab, then do other sections.
+ (map_program_segments): Align program header.
+ (assign_file_positions_except_relocs): Align section headers.
+ (assign_file_positions_for_relocs): Align relocation sections.
+
+Tue Oct 5 10:44:32 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.host: Recognize hppa*-*-hiux* (currently synonym for hpux).
+ Change other hppa entries to use -*- not -hp-.
+ * config.bfd: Recognize hppa*-*-hiux* (currently synonym for hpux).
+
+ * coff-rs6000.c, cpu-rs6000.c, rs6000-core.c: Change non-ASCII
+ characters in comment to octal escapes.
+
+Sun Oct 3 12:35:15 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * coff-i386lynx.c: Removed, name too long.
+ * i386lynx-cf.c: New file, was coff-i386lynx.c.
+ * configure.in: Reflect file name changes.
+ * Makefile.in: Mention Lynx-related files.
+
+ * i386lynx.c (lynx_32_swap_ext_reloc_in): get reloc bits in i386
+ Lynx-specific way.
+
+ * m68klynx-cf.c: New file, defines coff format for M68K LynxOS.
+ * m68klynx.c: Remove coff vector definition, now in m68klynx-cf.c.
+
+ * coffcode.h (sec_to_styp_flags): Set section flag to STYP_INFO
+ for .stab, .stabstr and .debug sections, and set SEC_DEBUGGING for
+ sections of type STYP_INFO. (from Minh Tran-Le)
+ (coff_compute_section_file_positions): Add discarded_sections_count
+ to abfd->section_count, which helps `strip' keep the size
+ of the executable header constant.
+ * coff-i386.c (discarded_sections_count): New variable, initialized
+ to zero. For use by `strip'. Currently being used only in aix386
+ coff, but may be useful for other coff systems. (from Minh Tran-Le)
+
+ * coffswap.h (coff_swap_filehdr_out): Added a missing cast.
+
+ * archive.c: Cosmetic improvements.
+ * opncls.c: Cosmetic improvements.
+ (new_bfd): Removed redundant structure slot init.
+
+Sat Oct 2 18:48:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/news-mips.mh, hosts/news-mips.h: New files.
+ * configure.host: Use news-mips for mips-sony-bsd*.
+
+Fri Oct 1 13:14:17 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: i386lynx_coff_vec requires coff-i386lynx.o.
+ * coff-i386lynx.c: New file, defines Lynx target vector and name,
+ includes coff-i386.c.
+ * coff-i386.c (i386coff_vec): Allow redefinition of target vector
+ symbol and name, if TARGET_SYM and/or TARGET_NAME are defined.
+ * i386lynx.c: Remove coff vector definition entirely.
+ (lynx_32_swap_ext_reloc_in): Define.
+ (lynx_32_swap_std_reloc_in): Define, get reloc bits in i386
+ Lynx-specific way.
+ (lynx_32_swap_ext_reloc_out): Define.
+ (lynx_32_swap_std_reloc_out): Define.
+ (lynx_32_slurp_reloc_table): Define, call Lynx swapping fns.
+ (lynx_32_squirt_out_relocs): Define, call Lynx swapping fns.
+ (lynx_32_canonicalize_reloc): Define, call Lynx swapping fns.
+ (WRITE_HEADERS): Define, call Lynx swapping fns.
+
+ * config/i386-lynx.mt (SELECT_VECS): Remove redundant vector.
+
+Thu Sep 30 17:50:52 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * reloc.c (bfd_reloc_code_type): Add linkage-table relative
+ relocations of size 8, 16, 32. Sort generic relocs by type rather
+ than size. Added a little documentation too.
+
+ * aoutx.h (howto_table_std): Add BASE16 and BASE32 relocs.
+ (TABLE_SIZE): New macro.
+ (reloc_type_lookup): Handle BFD_RELOC_{16,32}_BASEREL for std
+ relocs.
+ (swap_std_reloc_out): Write baserel relocs correctly.
+ (swap_std_reloc_in): Handle r_baserel field. Assert that
+ r_jmptable and r_relative fields are clear, and that the computed
+ index does refer to a defined entry of the howto table.
+
+Tue Sep 28 14:47:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * section.c (bfd_make_section_anyway): New function.
+ * section.c: Change comments to say several sections can have
+ the same name.
+ * bfd-in2.h: Re-generate to reflect above change.
+ * coffgen.c (make_a_section_from_file): Call bfd_make_section_anyway
+ if still no section after the bfd_coff_make_section_hook.
+ * coffcode.h: Add comment about TWO_DATA_SECS.
+
+Tue Sep 28 03:22:24 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * ecoff.c (ecoff_slurp_symbolic_info): Always determine raw_size
+ explicitly.
+ * ecoff.c (ecoff_sec_to_styp_flags, ecoff_styp_to_sec_flags): Handle
+ .fini section.
+
+Mon Sep 27 18:29:18 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * config.bfd configure.host: Match on *-lynxos* for LynxOS,
+ add m68*-*-lynxos*.
+ * configure.in : Replaced i386lynx_vec with i386lynx_aout_vec
+ and i386lynx_coff_vec.
+ Added m68klynx_aout_vec and m68klynx_coff_vec.
+ * targets.c (target_vector): Removed i386lynx_vec, added
+ {i386,m68k}lynx_{aout,coff}_vec.
+ * i386lynx.c: Added copy of i386coff.c, renamed bfd target to
+ i386lynx_coff_vec.
+ * m68klynx.c: New file.
+ * config/i386-lynx.mt: Replaced i386lynx_vec with i386lynx_aout_vec
+ and i386lynx_coff_vec.
+ * config/m68k-lynx.mt: New file.
+ * hosts/i386lynx.h: Added definition of cfree as free (from Eichin).
+ * hosts/m68klynx.h: New file.
+
+Mon Sep 27 18:00:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * archive.c: Define offsetof here.
+ * hosts/*.h: Don't define it here.
+
+Mon Sep 27 19:09:27 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (bfd_section_from_shdr): Set filepos for SHT_STRTAB
+ section.
+
+Fri Sep 24 15:47:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hpux-core.c: Add comment about hpux version 7.
+
+Fri Sep 24 16:50:26 1993 Stu Grossman (grossman at cygnus.com)
+
+ * lynx-core.c (lynx_core_file_p): Change per-thread register
+ section names from .regXXX to .reg/XXX to avoid parsing ambiguity
+ in gdb/corelow.c. Create alias .reg section for the currently
+ running thread.
+
+Fri Sep 24 13:22:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libecoff.h (ecoff_backend_data): Removed big_magic and
+ little_magic fields.
+ * coff-alpha.c (alpha_ecoff_backend_data): Removed initialization
+ of big_magic and little_magic.
+ * coff-mips.c (mips_ecoff_bad_format_hook): Make sure magic number
+ matches endianess of bfd.
+ (mips_ecoff_backend_data): Removed initialization of big_magic and
+ little_magic.
+ * ecoff.c (ecoff_set_arch_mach_hook): Set MIPS machine number
+ based on magic number. Support r4000 magic numbers.
+ (ecoff_get_magic): New function.
+ (ecoff_write_object_contents): Use ecoff_get_magic, not fields in
+ the backend structure.
+ * cpu-mips.c (arch_info_struct): Added case for r6000.
+
+ For MIPS configurations put both big and little endian versions in
+ the list of targets; the code is getting compiled in anyhow.
+ * bigmips.mt (SELECT_VECS): Define to be ecoff_little_vec.
+ * decstation.mt (SELECT_VECS): Define to be ecoff_big_vec.
+ * mipsbelf.mt (SELECT_VECS): Define to be bfd_elf32_littlemips_vec.
+ * mipslelf.mt (SELECT_VECS): Define to be bfd_elf32_bitmips_vec.
+ * riscos.mt (SELECT_VECS): Define to be ecoff_little_vec.
+
+Fri Sep 24 00:42:23 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * osf-core.c: New file for OSF/1 core file support.
+ * config/alphaosf.mh (HDEFINES): Add -DOSF_CORE.
+ (HDEPFILES): Set to osf-core.o.
+ * bfd-in2.h (union tdata): Add osf_core_data member.
+ * targets.c: If OSF_CORE is defined, add osf_core_vec to target list.
+ * Makefile.in (OPTIONAL_BACKENDS): Add osf-core.o.
+ (osf-core.o): New dependency.
+
+Thu Sep 23 21:04:53 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * TODO: Remove note about making --with-bfd-targets use canonical
+ target configuration name (already done); reword item about
+ separating reading and writing stuff to not refer to a
+ non-existent item.
+
+ * ecoff.h (ecoff_set_arch_mach_hook): Accept MIPS_MAGIC_LITTLE2
+ and MIPS_MAGIC_BIG2.
+
+Thu Sep 23 11:06:34 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * gen-aout.c (main): Output newline after end of comment, not
+ before. (Reported by Jonathan Stone,
+ jonathan@oscar.stanford.edu).
+
+Thu Sep 23 10:48:27 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * archive.c (compute_and_write_armap): Put weak symbols in the
+ armap.
+
+ * elfcode.h (fix_up_strtabs): Set sh_entsize for the .stab
+ section, not the .stabstr section. Set the type of the .stabstr
+ section to SHT_STRTAB.
+ (elf_section_from_bfd_section): Handle SHT_STRTAB sections.
+
+ * section.c (SEC_DEBUGGING): New section flag.
+ * elfcode.h (bfd_section_from_shdr): If section is SHT_PROGBITS,
+ and the name starts with .debug, .line or .stab, set
+ SEC_DEBUGGING. If SHT_STRTAB, check for .debug and .stab.
+ * elf32-target.h (TARGET_BIG_SYM, TARGET_LITTLE_SYM): Added
+ SEC_DEBUGGING to section_flags.
+ * elf64-target.h (TARGET_BIG_SYM, TARGET_LITTLE_SYM): Added
+ SEC_DEBUGGING and SEC_CODE to section_flags.
+ * bfd-in2.h: Updated.
+
+Wed Sep 22 16:34:14 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.c (tdata): Add lynx_core_data.
+
+ * ecoff.c (ecoff_compute_section_file_positions): Set filepos for
+ sections with SEC_LOAD set, even if SEC_HAS_CONTENTS is clear.
+ (ecoff_write_object_contents): Don't set scnptr to zero just
+ because size of section is zero. Needed for Irix 4.0.5F.
+
+Wed Sep 22 09:49:32 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.bfd: Use i960-bout, not i960-coff for i960-*-nindy*.
+
+Wed Sep 22 07:34:09 1993 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in (OPTIONAL_BACKENDS): Add lynx-core.o.
+ * bfd-in2.h (tdata): Add lynx_core_data;
+ * config.bfd configure.host: Get rid of superfluous netbsd and
+ lynxos entries.
+ * configure.in: Add lynx-core.o to Lynx config.
+ * i386lynx.c: Add defs for core file support.
+ * lynx-core.c: New file with Lynx core file support.
+ * hosts/i386lynx.h: Move lots of host specific includes to here.
+ Add def of HOST_LYNX. Remove unnecessary defs.
+
+Mon Sep 20 19:18:10 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (bfd_section_from_shdr): Only set SEC_DATA for a
+ SHF_PROGBITS or SHT_STRTAB section if SEC_ALLOC is set. Never set
+ SEC_DATA for a SHF_NOBITS section.
+
+ * nlm32-i386.c (nlm_i386_mangle_relocs): Check SEC_LOAD rather
+ than SEC_CODE | SEC_DATA. Add some casts to avoid warnings.
+ * nlmcode.h: Add some casts to avoid warnings.
+ (nlm_write_object_contents): Ignore relocs for sections that are
+ neither code nor data. Just use the symbol value for debugging
+ symbols; don't offset by the section vma.
+
+Fri Sep 17 18:08:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Don't return an error when
+ performing a reloc against an undefined weak symbol.
+ * syms.c (bfd_print_symbol_vandf): Show value of BSF_WEAK rather
+ than obsolete BSF_EXPORT.
+
+Fri Sep 17 02:04:31 1993 John Gilmore (gnu@cygnus.com)
+
+ * hosts/{alphaosf.h, amix.h, apollo68.h, apollov68.h,
+ decstation.h, delta88.h, dgux.h, dose.h, go32.h, harris.h,
+ hp300.h, hp300bsd.h, hppabsd.h, hppahpux.h, i386aix.h, i386bsd.h,
+ i386linux.h, i386lynx.h, i386v.h, i386v4.h, irix3.h, irix4.h,
+ mipsbsd.h, ncr3000.h, rs6000.h, rtbsd.h, solaris2.h, sparc-ll.h,
+ std-host.h, stratus.h, sun3.h, sysv4.h, tahoe.h, ultra3.h,
+ vaxult.h, vaxult2.h, we32k.h}: Make sure that "offsetof" is
+ defined on all hosts, now that archive.c uses it.
+
+Thu Sep 16 18:20:30 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (elf_map_symbols): Create section symbols for all
+ sections, not just allocated sections; debugging sections can have
+ relocs.
+ (elf_symbol_from_bfd_symbol): If there is an output section, use
+ the section index from that rather than the input section.
+
+Thu Sep 16 12:20:50 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * libbfd-in.h (bfd_flush, bfd_stat): Reflect John's changes to
+ libbfd.h, which is regenerated from this file.
+
+ * bfd-in.h (symtype): Deleted typedef.
+
+Wed Sep 15 11:48:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libbfd.c (COERCExx): Cast x to bfd_signed_vma before doing the
+ xor and subtract. Otherwise it will not sign extend if the type
+ of bfd_vma is larger than int.
+
+ * ecoffswap.h (ecoff_swap_pdr_in): Get regoffset, iopt, fregoffset
+ and frameoffset as signed numbers. From Peter Schauer.
+
+Tue Sep 14 18:20:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-i386.c (elf_howto_table): Add bfd_elf_generic_reloc
+ special function for all reloc entries.
+ * elf32-target.h (TARGET_LITTLE_SYM): Add SEC_CODE to
+ section_flags.
+ * libelf.h (elf_symbol_type): Remove desc, type and other fields.
+ * Makefile.in (elf32-*.o): These depend upon elf32-target.h.
+
+Tue Sep 14 14:34:45 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * libbfd-in.h (struct artdata): Add armap_timestamp and
+ armap_datepos here too.
+
+Mon Sep 13 21:03:18 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ Improve timestamp support in BSD archive files to avoid linker
+ warnings.
+
+ * libbfd.h (struct artdata): Add armap_timestamp and armap_datepos.
+ (bfd_flush, bfd_stat): Add prototypes.
+ * libbfd.c (bfd_flush): Add, does fflush on a BFD.
+ (bfd_stat): Add, does fstat on a BFD.
+
+ * archive.c (_bfd_write_archive_contents): At end of file writing,
+ verify and possibly update the timestamp in the armap, if a BSD
+ archive. FIXME! Kludge recognizes BSD archive, rather than
+ vectoring properly. Should add to xvec.
+ (compute_and_write_armap): Move prototype to top, avoid PROTO.
+ (bsd_write_armap): Save timestamp and file location thereof, when
+ writing the armap in a BSD file.
+ (bsd_update_armap_timestamp): New function to check and
+ rewrite the timestamp.
+
+ * hosts/std-host.h (offsetof): Define, if not already, for archive.c.
+
+Sat Sep 11 18:13:42 1993 Jim Kingdon (kingdon@poseidon.cygnus.com)
+
+ * hosts/i386sco.h: Define a bunch of stuff for core files.
+ * sco-core.c: Remove, replace by trad-core.c.
+ * trad-core.c: If HOST_STACK_START_ADDR is defined, use it.
+ * config/i386sco.mh: Use trad-core not sco-core.
+ * hosts/i386isc.h, config/i386isc.mh: Remove.
+ * configure.host: Use i386sco for isc.
+ * config/i386-sco.mt: Remove, identical to i386-coff.mt.
+ * config.bfd: Use i386-coff not i386-sco.
+
+ * config.bfd: Recognize i[34]86-*-solaris2* specifically rather
+ than using *-*-solaris2* (i486-unknown-solaris2 is i386-elf, not
+ i486-elf which doesn't exist).
+
+Fri Sep 10 12:56:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffswap.h (coff_swap_aouthdr_out): For ALPHAECOFF, force
+ padding field to zero.
+
+ * config.bfd (i[34]86-*-netbsd*): New target; use i386-netbsd.
+ * configure.in: Remove bogus netbsd386 handling.
+
+ * coff-mips.c: Don't warn about overflow for MIPS_R_JMPADDR reloc.
+ Correct overflow detection requires matching the upper four bits
+ of the destination against the PC.
+
+Thu Sep 9 16:57:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: Make 64-bit stuff work with "--with-targets=all".
+
+Tue Sep 7 14:17:02 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libbfd-in.h: Removed swapping routines declarations.
+ * bfd-in.h: Added swapping routine declarations, and renamed them
+ from _do_* to bfd_*.
+ * libbfd.c: Renamed swapping routines from _do_* to _bfd_*.
+ * Changed all callers.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+
+Mon Sep 6 15:28:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-i386.c (elf_howto_table): Set pcrel_offset to true for
+ R_386_PC32.
+
+Fri Sep 3 13:06:12 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: Reorganized setting of makefile variables so
+ 64-bit stuff works again.
+
+ * libbfd-in.h (_do_get*, _do_put*): Renamed via macros to clean up
+ namespace.
+
+ * libelf.h (elf32_symbol_type, elf64_symbol_type): Deleted
+ "native_elf_sym" field, merged to make new type "elf_symbol_type".
+ (struct elf_obj_tdata): Field symbols is now elf_symbol_type*.
+ Deleted field raw_syms.
+ (obj_symbols): Remove cast.
+ (obj_raw_syms): Deleted.
+ * elfcode.h (elf_slurp_symbol_table): Don't set raw_syms or
+ native_elf_sym fields.
+ * elf32-hppa.c: Changed uses of elf32_symbol_type to
+ elf_symbol_type.
+
+ From Pete Hoogenboom and Jeff Law:
+
+ * elf32-hppa.c (ELF_MAXPAGESIZE): Define.
+
+ * elf32-hppa.c (elf_hppa_tc_symbol): If the argument relocation
+ bits are zero (e.g., they specify no relocations), then do not
+ even bother adding their entries to the symextn section.
+
+ * elf32-hppa.c (elf_hppa_tc_symbol): Any function, regardless
+ of scope can have an argument relocation stub.
+
+ * elf32-hppa.c: (Elf32_hppa_Stub_description): Rename this
+ structure and type to elf32_hppa_stub_description. This makes
+ it consistent with the GNU coding conventions.
+ (elf32_hppa_stub_description): Added a 'next' field to allow
+ linking of stub description structures.
+ (elf32_hppa_stub_description): Added a 'stub_listP' field to
+ keep track of individual stubs.
+ (Elf32_hppa_Stub_list, Elf32_hppa_Stub_list_struct): Removed.
+ Combined with the elf32_hppa_stub_description structure.
+ (elf32_hppa_stub_name_list): New type to keep track of
+ individual stubs.
+ (add_stub): Removed.
+ (add_stub_by_name): New function.
+ (find_stub_by_name): New function.
+ (hppa_elf_build_arg_reloc_stub): Allow reusing stubs that
+ already exist.
+ (hppa_elf_build_long_branch_stub): Allow reusing stubs that
+ already exist.
+
+ * elf32-hppa.c: (retval_mismatches): The direction of argument
+ relocation was reversed.
+ (hppa_elf_build_arg_reloc_stub): Return address was not being
+ restored.
+ (hppa_elf_arg_reloc_needed_p): Add argument containing caller
+ argument relocation bits so this function can be used in the check
+ for plabel stubs.
+ (hppa_elf_stub_check): Pass caller argument relocation bits into
+ hppa_elf_arg_reloc_needed_p().
+ (hppa_look_for_stubs_in_section): Add check for plabel stubs and
+ pass caller argument relocation bits into
+ hppa_elf_arg_reloc_needed_p().
+
+Thu Sep 2 00:59:55 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * libhppa.h (hppa_field_adjust): Remove unused `init_value' variable.
+
+ * hosts/delta88v4.h: New for SVR4.
+ * configure.hosts: Use it.
+
+Wed Sep 1 14:23:32 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * libaout.h, netbsd386.c: Change M_I386 to M_386_NETBSD. M_I386
+ is an SCO pre-define.
+
+Tue Aug 31 12:50:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmcode.h (nlm_object_p): Set HAS_SYMS if there are external
+ references.
+ (nlm_swap_auxiliary_headers_{in,out}): The copyright length is
+ only one byte.
+ (nlm_get_symtab_upper_bound): Include debugging symbols in symbol
+ count.
+ (nlm_slurp_symbol_table): Make symlength unsigned. Read debugging
+ symbols as BFD local symbols.
+ (nlm_write_object_contents): Don't bother writing out exported
+ symbols more than once; they now appear in the symbol table more
+ than once (with and without a prefix) if necessary. Set offset
+ values to be non-zero as NLMLINK does.
+
+Tue Aug 31 12:07:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * libhppa.h: Restore #undefs of e_fsel and other e_* symbols.
+
+Fri Aug 27 16:43:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * section.c (struct sec): Move position of user_set_vma, and
+ document it.
+ (SEC_BALIGN): Disable for now. I don't think it's currently used.
+
+ * elf32-hppa.c (elf_hppa_howto_table): Now static.
+ (symext_rootP, symext_lastP, global_value, GOT_value,
+ global_symbol, global_sym_defined, symextn_contents,
+ symextn_contents_real_size, elf_hppa_stub_rootP,
+ elf32_hppa_symextn_map, elf32_hppa_symextn_map_size): Rely on
+ default initialization.
+ (hppa_elf_gen_reloc_type): Macro "UNDEFINED" doesn't need a
+ trailing semicolon.
+ (hppa_look_for_stubs_in_section): Introduce temporaries to make
+ code more readable in 80 columns.
+
+ * libhppa.h (all functions): Now inline under GNU C.
+
+ More patches from Jeff Law:
+
+ * elf32-hppa.c (AR_WARN): Give argument which caused the
+ invalid argument relocation.
+ (AR_UNIMP): Delete unused macro.
+ (hppa_elf_set_section_contents): Always return a value.
+ (elf32_hppa_backend_table_processing): Likewise.
+ (elf32_hppa_backend_section_processing: Likewise.
+
+ * som.c: New file containing SOM specific code extracted
+ from hppa.c
+
+ * som.h: New file containing SOM specific code extracted
+ from libhppa.h
+
+ * hppa.c: Deleted.
+
+ * libhppa.h: Delete SOM specific code. Add generic PA
+ code which can be shared by both SOM and ELF backends.
+
+ * Makefile.in: Replace hppa.c with som.c. elf32-hppa.o
+ depends on libhppa.h now.
+
+ * configure.in (hppa_vec): Needs som.o module instead of
+ hppa.o.
+
+ * elf32-hppa.c: Include libhppa.h. Do not define
+ BYTES_IN_WORD.
+
+ * elf32-hppa.h (hppa_reloc_field_selector_type): Delete
+ now lives in libhppa.h.
+ (hppa_reloc_field_selector_type_alt): Likewise.
+
+ * hosts/hppabsd.h: Include <stdlib.h> and <unistd.h>. Do not
+ define malloc or free.
+
+ * config/hppa-elf.mt (SELECT_ARCHITECTURES): Don't define
+ SELECT_VECS.
+
+ * elf32-hppa.c (hppa_elf_relocate_unwind_table): Delete unused
+ variables.
+ (elf_hppa_reloc_type_lookup): Likewise.
+ (elf_hppa_tc_make_sections): Likewise.
+ (hppa_elf_arg_reloc_needed_p): Likewise.
+ (hppa_elf_build_long_branch_stub): Likewise.
+ (elf_reloc_map): Delete, no longer used.
+ (elf_hppa_reloc_map): Likewise.
+ (elf32_hppa_symextn_map_max_size): Likewise.
+ (elf32_hppa_get_sym_extn): Abort if type is bogus.
+
+ * elf32-hppa.c (elf32_hppa_backend_fake_sections): Add processing
+ of the .hppa_unwind section.
+
+Wed Aug 25 16:13:49 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config.bfd: recognize m88110.
+
+Tue Aug 24 16:32:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Merged changes from Jeff Law and Pete Hoogenboom at Utah:
+
+ * elfcode.h (elf_section_from_bfd_section): Add detection of
+ SHT_NOTE sections.
+
+ * elf32-hppa.c:
+ (hppa_elf_build_long_branch_stub,hppa_elf_long_branch_needed_p):
+ New functions for support of long branch stubs.
+ (hppa_elf_stub_check,hppa_look_for_stubs_in_section): Add
+ check for long branch stubs.
+ (hppa_look_for_stubs): Unused function. Removed.
+ (hppa_elf_set_section_contents): Implement a PA/ELF-specific
+ version of bfd_set_section_contents.
+ (hppa_elf_long_branch_needed_p): Only output debugging diagnostics
+ when BFD is configured for debugging.
+
+ * elf32-hppa.c: (elf32_hppa_get_symextn_chain): New function
+ to return a list of symbols that have non-zero argument
+ relocation bits.
+ (hppa_elf_stub_finish): Make sure stub generation is done only
+ once.
+
+ * elf32-hppa.c: (hppa_elf_stub_reloc): New function for
+ generation relocation entries within a stub.
+ (hppa_elf_build_arg_reloc_stub): Corrections to argument
+ relocation stubs.
+
+ * elf32-hppa.c: New #define's for argument relocation types.
+ (mismatches, retval_mismatches): Updated to reflect new
+ argument relocation types.
+ (CURRENT_STUB_OFFSET): New macro.
+
+ * elfcode.h (map_program_segments): Set the PF_X bit for data
+ segments.
+
+ * elf32-hppa.c: (elf_hppa_howto_table): Add
+ R_HPPA_STUB_CALL_17 for support of linker stub generation.
+ (hppa_elf_reloc): Add support of R_HPPA_STUB_CALL_17
+ relocation type.
+
+ * elf32-hppa.h: (elf32_hppa_reloc_type): Add
+ R_HPPA_STUB_CALL_17 for support of linker stub generation.
+
+ * hppa_stubs.h: Add new instructions that are used in linker
+ stub generation.
+
+ * elf32-hppa.c (hppa_elf_relocate_unwind_table): The offsets in an
+ unwind descriptor were incorrect.
+
+ * libelf.h (bfd_elf_find_section): Declare.
+
+ * elf32-hppa.c: (elf32_hppa_backend_symbol_processing): New
+ function in place of global_sym field in elf_backend_data
+ structure.
+ (elf32_hppa_backend_symbol_table_processing,
+ elf32_hppa_backend_section_processing,
+ elf32_hppa_backend_fake_sections,
+ elf32_hppa_backend_section_from_shdr,
+ elf32_hppa_backend_section_from_bfd_section): New functions to
+ provide support of symbol extension sections and argument
+ relocation stubs.
+ (elf_info_to_howto): Remove call to abort().
+
+ * elf32-target.h: Support for special processing by the backend.
+ (struct elf_backend_data): Added elf_backend_symbol_processing,
+ elf_backend_symbol_table_processing,
+ elf_backend_section_processing, elf_backend_section_from_shdr,
+ elf_backend_fake_sections, and
+ elf_backend_section_from_bfd_section fields.
+ * elfcode.h: (bfd_section_from_shdr): Add a check for
+ processor-specific section types.
+ (elf_fake_sections): Add a check for processor-specific
+ section types.
+ (bfd_elf32_write_object_contents): Add a check to see if
+ there is any final section processing to be done by the
+ backend.
+ (elf_section_from_bfd_section): Add a check for
+ processor-specific section types.
+ (elf_slurp_symbol_table): Remove reference to global_sym in the
+ elf_backend_data structure. Replace it with a call to
+ elf_backend_symbol_processing.
+ * libelf.h: Remove global_sym field in the elf_backend_data
+ structure. Replace it with a series of backend-specific
+ functions.
+
+ * elf32-hppa.c (hppa_elf_stub_branch_reloc): The formal argument
+ stub_sym should be called target_sym.
+ (hppa_elf_build_arg_reloc_stub): Refer to the stub bfd (abfd)
+ rather than the output bfd (output_bfd).
+ (hppa_elf_reloc): Get rid of references to the global_sym field in
+ the elf_backend_data structure.
+
+ * elfcode.h (elf_fake_sections): Check the correct condition for
+ .bss. Also, detect the existence of a .note section.
+
+ * elf32-hppa.c (hppa_elf_relocate_insn): r_format argument should
+ have been r_field.
+
+ * hosts/hppabsd.h (HOST_MACHINE_ARCH): Reference to bfd_arch_m68k
+ should be a reference to bfd_arch_hppa.
+
+ * hppa.c (hppa_vec): Replace bfd_false with _bfd_dummy_target in
+ the bfd_check_format structure to avoid a type mismatch.
+
+Mon Aug 23 1993 Sean Fagan (sef@cygnus.com)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ Add NetBSD support:
+ * netbsd386.c: New file.
+ * aoutx.h: Make sym_is_debugger_info true for N_FN.
+ * Makefile.in, aout-target.h, config.bfd, configure.host, configure.in,
+ libaout.h, targets.c: Other changes.
+
+Fri Aug 20 17:04:59 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/m88k-elf.mt: New file.
+ * config.bfd: Use it for m88*-*-sysv4*.
+
+Fri Aug 20 15:16:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elfcode.h (elf_build_phdrs): Unused function deleted.
+ (bfd_shdr_from_section): Ditto.
+ (write_relocs): Don't change section contents for addend.
+ (elf_locate_sh): Return type is now always elf_internal_shdr,
+ since the other types were really aliases for this type anyways.
+ Don't compile this function, since it is static and doesn't appear
+ to be used in this file.
+ (sym_is_global): Return non-zero for weak symbols. Abort if
+ section pointer is null.
+ (swap_out_syms): Reorder tests so function symbols can be weak.
+ (elf_slurp_symbol_table): Don't use BSF_EXPORT.
+ (elf_slurp_reloca_table): Make RELOC_PROCESSING section smaller by
+ extracting out some common code. Abort if BFD section symbol has
+ null name.
+ (elf_slurp_reloc_table): Translate ELF section symbols into BFD
+ section symbols. Don't read section contents to fill in addend
+ field.
+
+ * elf32-i386.c (elf_howto_table): All partial_inplace fields
+ should be "true".
+
+ * Merged from OSF:
+
+ Tue Jun 15 14:38:32 1993 Michael Meissner (meissner@osf.org)
+
+ * libelf.h (struct Elf_Sym_Extra): New structure to contain ELF
+ specific information for a symbol. Put in elf_sym_num, which
+ gives the external symbol number in the elf object file, since
+ local symbols must come before global symbols.
+ (elf_sym_extra): New macro.
+ (elf_symtab_map): Delete, in favor of using Elf_Sym_Extra.
+ * elfcode.h (elf_map_symbols): Use Elf_Sym_Extra to map internal
+ symbol number to external number. Store the address of the
+ Elf_Sym_Extra field for the symbol in the udata field.
+ (elf_write_object_contents): Use Elf_Sym_Extra to map out symbols.
+
+ Sun Jun 20 16:30:11 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_obj_tdata): Add field to count the size of the
+ array of pointers to section symbols.
+ (elf_map_symbols): Bump the max index of the section symbols so
+ that we don't overwrite memory. Store the max index into the
+ elf_obj_tdata field.
+
+ Sat Jun 19 10:12:27 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_obj_tdata): Add pointer to an array of pointers
+ to the section symbols we created. Remove unused field
+ internal_syms.
+ (elf_map_symbols): Fill in array of pointers to section symbols.
+ Only create section symbols for sections that have SEC_ALLOC set,
+ and have non-zero size.
+ (elf_symbol_from_bfd_symbol): If udata is NULL, and this is a
+ section symbol, look up the section in the list of section
+ symbols, and set the udata pointer appropriately. Otherwise, if
+ udata is still NULL, fail an assertion, and use 0, instead of
+ dropping core.
+
+Fri Aug 20 12:18:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config.bfd (mips-*-elfl*, mips-*-elf*): New targets, using
+ mipslelf and mipsbelf respectively.
+ * config/mipslelf.mt, config/mipsbelf.mt: New files.
+ * elf32-mips.c: Added some reloc information.
+ * configure.in: Fixed error message.
+
+ * ecoff.c (ECOFF_LONG_SIZE): Removed. Just use constants.
+
+Thu Aug 19 09:45:51 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (BFD_LIBS, ALL_MACHINES, BFD32_BACKENDS, BFD64_BACKENDS,
+ OPTIONAL_BACKENDS): Alphabetize entries and add a few missing ones.
+ * archures.c: Alphabetize decls.
+
+ * configure.in, targets.c: Add missing vectors to the tables.
+ * targets.c (target_vector) [!SELECT_VECS]: Add DEFAULT_VECTOR.
+ Remove hp300bsd_vec due to clash with sunos_big_vec.
+
+Tue Aug 17 18:12:32 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/i386{mach3,osf1mk}.h: New files, for Mach hosting.
+ * hosts/i386mach.h: removed, replaced by i386osf1mk.h.
+ * config/i386mach3.mt, i386mach3.c: New files, for Mach a.out format.
+ * Makefile.in, configure.host, config.bfd: Corresponding changes.
+ * hosts/decstation.h: Include <sys/param.h> not <machine/param.h>.
+
+Tue Aug 17 15:19:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffgen.c (coff_section_symbol): If section's output_section is
+ not yet set, point to itself. This is needed because this is
+ called on the output file, not the input file.
+
+ * coff-rs6000.c (dummy_reloc, RTYPE2HOWTO): Set howto field to a
+ dummy value, rather than leaving it NULL.
+
+ * archures.c (bfd_default_set_arch_mach): Set bfd_error on
+ failure.
+ * aoutx.h (NAME(aout,set_arch_mach)): Check return value of
+ bfd_default_set_arch_mach.
+
+Tue Aug 17 09:42:16 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * config.bfd (cpu): Extract from canonical name with sed.
+ * configure.in: Don't pass it.
+
+Sun Aug 15 20:45:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * bfd-in.h: Remove {BYTE,WORD,LONG}_SIZE; they are pointless and
+ BYTE_SIZE conflicts with a Mach header.
+ * ecoff.c: Change LONG_SIZE to ECOFF_LONG_SIZE and define it.
+
+ * configure.host: Make sure all OS fields end in *.
+
+Fri Aug 13 16:33:33 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_slurp_reloc_table): Use bfd_abs_section for
+ RELOC_SECTION_NONE and RELOC_SECTION_ABS. If a reloc section
+ doesn't exist, don't try to create it.
+
+ * nlmcode.h (nlm_write_object_contents): procedure offsets are
+ from start of code segment, not start of file.
+ * config/i386-nlm.mt (DEFAULT_VECTOR): It's nlm32_i386_vec, not
+ bfd_nlm32_i386_vec.
+ * configure.in (SELECT_VECS switch): Likewise.
+
+Thu Aug 12 10:32:47 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * format.c (bfd_check_format): If the target matches the default
+ target, set match_count to 1, to ignore any previous matches.
+
+ * Makefile.in (BFD32_BACKENDS): Remove srec.o, add reloc16.o.
+
+ * configure.in: Add reloc16.o when we add
+ coff-h8300.o, coff-h8500.o, coff-sh.o, coff-z8k.o.
+ Makefile.in (BFD_LIBS): Remove reloc16.o.
+
+ * config/u68k-coff.mt: Fix typo, DEFAULT_TARGET for
+ DEFAULT_VECTOR.
+
+ * config/h8300-coff.mt, h8500-coff.mt, sh-coff.mt, st2000.mt,
+ z8k-coff.mt (DEFAULT_VECTOR): Define. Don't explicitly add
+ S-records via SELECT_VECS.
+
+ * targets.c (target_vector), Makefile.in (BFD_LIBS): Always
+ support S-records, for convenience.
+
+Thu Aug 12 08:30:05 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-alpha.c (alpha_howto_table, alpha_finish_reloc,
+ alpha_ecoff_swap_reloc_{in,out}, alpha_bfd_reloc_type_lookup):
+ Read and write Alpha relocs. Can't process them yet.
+ * ecoff.c (ecoff_slurp_reloc_table): Recognize new reloc sections.
+ If the section does not already exist, create it.
+
+ * ecoffswap.h (ecoff_swap_pdr_{in,out}): Handle new fields defined
+ on the Alpha.
+
+ * libecoff.h (ecoff_backend_data): Added constructor_reloc and
+ finish_reloc fields.
+ * ecoff.c: Move MIPS reloc support from here...
+ * coff-mips.c: to here.
+ * ecoff.c (ecoff_set_symbol_info): Get constructor reloc howto
+ from backend.
+ (ecoff_slurp_reloc_table): Removed MIPS specific stuff. Call
+ finish_reloc backend function.
+ (ecoff_write_object_contents): Removed MIPS specific assertions.
+ * coff-mips.c (mips_finish_reloc): New function.
+ (mips_ecoff_backend_data): Fill in new fields.
+ * coff-alpha.c (alpha_ecoff_backend_data): Use NULL for new
+ fields.
+ * targets.c: Added extern for ecoffalpha_little_vec.
+
+ * bfd.c (_bfd_host_big_endian): Removed.
+ * bfd-in.h (HOST_BYTE_ORDER_BIG_P, bfd_header_twiddle_required):
+ Removed.
+ * bfd-in2.h: Regenerated.
+
+Wed Aug 11 12:11:23 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * config.bfd: New file, broken out of configure.in.
+ * configure.in: Use it, and use standard target names for
+ --with-targets, replacing --with-bfd-targets.
+
+ * archures.c (archures_init_table): Add bfd_sh_arch.
+
+ * configure.in: Include coff-m68k.o for m68kcoffun_vec.
+ Include nlm32.o and nlm.o for bfd_nlm32_i386_vec.
+ Fix error in error message.
+
+ * oasys.c: Make bfd_error_vector extern.
+
+ * configure.in: Include stab-syms.o for a.out/b.out targets
+ and hp300{bsd,hpux}.
+
+Wed Aug 11 06:40:51 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * nlmcode.h (nlm_compute_section_file_positions): Add the .bss
+ section before setting output_has_begun.
+ (nlm_set_section_contents): Remove argument names from
+ mangle_relocs_func prototype.
+ (nlm_write_object_contents): Remove shadowing local variable.
+ Don't write out debugging symbols if debugInfoOffset is -1. Add
+ the codeImageOffset to the start, exit, and check procedure
+ offsets.
+ * nlm32-i386.c (nlm_i386_write_reloc, nlm_i386_mangle_relocs):
+ Don't check partial_inplace field; its value is irrelevant.
+
+ * Base use of sco-core on host, not target.
+ * configure.host (i[34]86-*-sco*): Use i386sco rather than i386v.
+ * config/i386-sco.mt (TDEFINES): Removed.
+ * config/i386sco.mh: New file to use sco-core.
+ * hosts/i386sco.h: New file; just includes hosts/i386v.h.
+
+ * ecoffswap.h (ecoff_swap_{hdr,ext}_{in,out}): Use signed
+ conversions for some fields.
+
+Tue Aug 10 13:32:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_gprel_reloc): If _gp is not defined, give an
+ error rather than aborting.
+
+ * libnlm.h (struct nlm_backend_data): Added mach field.
+ (nlm_machine): New accessor macro.
+ * nlm.c (nlm_mkobject): Set architecture and machine from backend
+ information.
+ * nlm32-i386.c (nlm32_i386_backend): Initialize new mach field.
+
+Tue Aug 10 09:31:18 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * configure.in: Replace calls to sort with shell code
+ to uniq the lists.
+
+Tue Aug 10 06:23:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: Include aout32.o for any a.out/b.out formats.
+
+Mon Aug 9 09:37:18 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * config/i386-linux.mt (SELECT_VECS): Support bfd_elf32_i386_vec.
+ * config/m68k-elf.mt (SELECT_VECS): Support m68kcoff_vec.
+ * config/i386-elf.mt (SELECT_VECS): Support i386coff_vec.
+ * config/hppa-elf.mt (SELECT_VECS): Support hppa_vec.
+ * config/sparc-elf.mt (SELECT_VECS): Support sunos_big_vec.
+ * config/i386-sco.mt (SELECT_VECS): Don't define; Ian says it was
+ just a hack.
+
+Mon Aug 9 13:15:00 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/m88k-coff.mt (DEFAULT_VEC -> DEFAULT_VECTOR): renamed.
+
+Mon Aug 9 14:26:45 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * syms.c (BSF_EXPORT): Now same as BSF_GLOBAL.
+
+ * bfd.c (bfd_scan_vma): New function.
+
+Mon Aug 9 11:29:53 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd-in.h (bfd_get_architecture, bfd_get_machine): Removed
+ obsolete macros.
+ * bfd-in2.h: Updated.
+
+ * ecoff.c (ecoff_slurp_armap): Correct bug in initialization of
+ stringbase.
+
+Sun Aug 8 12:21:13 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * configure.in: Remove unneeded test.
+
+Sun Aug 8 12:41:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in ({dist,real}clean): Use $(MAKE), not make.
+
+Sat Aug 7 09:14:21 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * config/st2000.mt (TDEFINES): Don't define MRI; not used.
+
+ * PORTING, TODO, config/README: Update to reflect below changes.
+
+ * configure.in: Replace MINIMIZE and --with-minimal-bfd with
+ --with-bfd-targets="target1,target2,..." and the special target
+ "all" to get the previous default behavior.
+ Figure out which architecture and backend .o files are needed from
+ DEFAULT_VECTOR, SELECT_VECS, and SELECT_ARCHITECTURES as set in
+ the .mt files. Define TDEFAULTS based on them, also.
+
+ * Makefile.in: Remove references to MINIMIZE.
+ * archures.c, targets.c: Ditto.
+
+ * config/*.mt: Define DEFAULT_VECTOR, SELECT_VECS, and
+ SELECT_ARCHITECTURES as variables rather than as -D arguments to
+ TDEFAULTS.
+
+ * config/a29k-coff.mt,alphaosf.mt, i386-sco.mt, i960-bout.mt,
+ i960-coff.mt (TDEFAULTS): Don't put the default vector in
+ SELECT_VECS manually; it's automatic now.
+
+ * config/i386-sco.mt (TDEFAULTS): Don't put &sco_core_vec in
+ SELECT_VECS manually; -DSCO_CORE does it automatically now.
+
+ * config/h8300-coff.mt,h8500-coff.mt,sh-coff.mt,st2000.mt,z8k-coff.mt
+ (TDEFAULTS): Don't define BFD; not used.
+
+ * config/hppaosf.mh (HDEFINES): Don't define SELECT_ARCHITECTURES;
+ this is a host, not a target.
+
+Sat Aug 7 05:28:03 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * elfcode.h (elf_object_p): Add comment about what this function
+ does and to watch out for side effects. Add FIXME for memory leaks.
+ Fix comment about checking for matching byte order. Preserve
+ pointer to old tdata (if any), and restore it if we don't match
+ file with target vector. If we are going to use goto's, use them
+ consistently and maintainably.
+ * nlmcode.h (nlm_object_p): Expand comments about leaked memory
+ to note that the problem is even more serious than just leaked
+ memory. Replace goto with more traditional return.
+
+Fri Aug 6 12:00:03 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ Fix incorrect or useless makefile variable definitions:
+ * config/news.mt, config/u68k-coff.mt (TDEFAULTS): Use this to
+ define DEFAULT_VECTOR, instead of TDEFINES.
+ * config/i386aix.mh (MINIMIZE): Don't define.
+ * config/hppaosf.mh (MINIMIZE): Don't conditionalize.
+ * config/rs6000.mh (ALLOCA),
+ * config/i386v.mh (ALLOCA),
+ * config/i386linux.mh (ALLOCA),
+ * config/i386isc.mh (ALLOCA),
+ * config/go32.mh (EXTRALIBS): Don't define; not used.
+ * config/solaris2.mh (HDEFINES): Renamed from H_DEFINES.
+ * config/alphaosf.mt (TDEFINES): Set it, not HDEFINES.
+ * config/z8k-coff.mt (CC): Don't define. It's a target, not a host.
+
+ * config/README: New file, explaining the variables.
+
+ * targets.c (target_vector): Add hp300_bsd_vec.
+ * Makefile.in (BFD32_BACKENDS, CFILES): Add hp300bsd.
+ (hp300bsd.o): New rule.
+
+Fri Aug 6 15:13:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * libelf.h (NAME): Provide a default definition, that's neither
+ for 32 bits nor for 64.
+
+ Tue Jun 15 14:38:32 1993 Michael Meissner (meissner@osf.org)
+
+ * libelf.h (elf_hash): Change declaration to bfd_elf_hash, since
+ that is what is in elf.c.
+
+Fri Aug 6 12:28:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_set_symbol_info): Removed special handling for
+ scBss and scSBss symbols, since it was wrong.
+
+ * Makefile.in (coff-mips.o, coff-alpha.o): Don't depend on
+ coffcode.h.
+
+ * coffcode.h (sec_to_styp_flags): Inspired by mb@tti.COM (Michael
+ Bloom): Only set STYP_BSS for SEC_ALLOC sections.
+
+ * ecoff.c (ecoff_slurp_armap): From Arne Henrik Juul
+ <arnej@kari.fm.unit.no>: Handle a COFF style armap.
+
+Fri Aug 6 09:59:45 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hpux-core.c: Cast return value from bfd_zalloc.
+
+Thu Aug 5 13:22:44 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * aoutx.h (log2): Delete i387-specific code.
+
+ * Makefile.in (BFD_LIBS): Always include elf.o.
+ (BFD32_BACKENDS): Don't include elf.o here.
+ (ofiles): Delete references to ofiles2 and ofiles3.
+ (do_clean): Delete ofiles.
+ (BFDIN_H): Changed references to $(srcdir)/bfd-in2.h.
+ (stmp-bfd.h): Use bfd.h-new as temporary name, not bfd.h2.
+ (headers): Use bfd-in2.h-new as temporary name, not bfd.h-new.
+
+ * bfd-in.h: Reworded comment to make it clear that bfd-in2.h is a
+ generated file.
+
+ * reloc.c (enum bfd_reloc_code_real): Added i386-elf reloc types
+ (from Meissner's additions to bfd-in2.h).
+
+ * elf32-i386.c (ELF_MAXPAGESIZE): Define.
+
+ Merged:
+
+ Wed Jun 23 06:05:58 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_write_object_contents): Don't drop core if
+ elf_symbol_from returns a NULL pointer when processing a non-elf
+ symbol, use a 0 size instead.
+
+ Tue Jun 15 14:38:32 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_hash): Delete macro mapping elf_hash to
+ bfd_elf32_hash, since the hash table is independent of the 32/64
+ bit system.
+
+ * libelf.h (elf_hash): Change declaration to bfd_elf_hash, since
+ that is what is in elf.c.
+
+ Sat Jun 19 10:12:27 1993 Michael Meissner (meissner@osf.org)
+
+ * elf32-i386.h (reloc_type): Reformat spacing.
+ (elf_howto_table): Add the rest of the 386/ELF relocations.
+ (elf_i386_reloc_type_lookup): Ditto.
+ (elf_i386_info_to_howto): Ditto.
+ (elf_i386_info_to_howto_rel): Ditto.
+
+Thu Aug 5 10:07:43 1993 Fred Fish (fnf@cygnus.com)
+
+ * nlmcode.h (nlm_get_reloc_upper_bound): Test return value
+ of nlm_slurp_symbol_table as boolean, not pointer.
+ * nlmcode.h (nlm_canonicalize_reloc): Test return value
+ of nlm_slurp_reloc_fixups as boolean, not pointer.
+
+Wed Aug 4 16:22:55 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/go32.mh: remove HDEFINES; since __MSDOS__ and __GO32__
+ are now predefined by GCC
+
+Wed Aug 4 16:06:29 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * coffgen.c (coff_print_symbol): Add the section offset to the
+ line number address, so it's printed the same way as the function
+ address. Only showed up for line numbers that aren't in the first
+ section (.text).
+
+Wed Aug 4 08:33:55 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * libnlm.h (nlm_backend_data): Added nlm_mangle_relocs.
+ (nlm_mangle_relocs_func): New macro.
+ * nlm32-i386.c (nlm_i386_write_reloc): Rewrote correctly.
+ (nlm_i386_mangle_relocs): New function.
+ * nlmcode.h (nlm_compute_section_file_positions): Move all common
+ symbols into the .bss section.
+ (nlm_set_section_contents): Call the mangle_relocs function.
+ (nlm_write_object_contents): Treat a reloc against any defined
+ symbol as an internal reloc. Fix bug in external reloc counting.
+ Get the offset and debugging type right for .bss symbols. Only
+ output debugging symbols for defined symbols.
+
+ * coff-h8500.c (rtype2howto): Do an fprintf to stderr rather than
+ using printf.
+ * coff-z8k.c (rtype2howto): Likewise.
+ * coffcode.h (dummy_reloc16_extra_cases): Likewise.
+ * elf32-i386.c (TRACE): Likewise.
+ * hp300hpux.c (convert_sym_type, swap_std_reloc_in): Likewise.
+ * rs6000-core.c (rs6000coff_get_section_contents): Likewise.
+ * coffgen.c (coff_print_symbol): Do an fprintf to the file
+ argument rather than using printf.
+
+Tue Aug 3 18:17:25 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffswap.h: Added macros used when accessing several fields;
+ default is the same as before.
+ (coff_swap_aouthdr_{in,out}): Handle the Alpha ECOFF fields.
+ * coff-alpha.c: Defined macros to use the right sizes in
+ coffswap.h.
+ * libecoff.h: Backend information is now in target vector, not
+ BFD. Start of backend information is COFF backend information.
+ * coff-alpha.c, coff-mips.c: Changed accordingly.
+ * ecoff.c (ecoff_mkobject): New function.
+ (ARMAP_START): Changed into backend information, since Alpha uses
+ a different name.
+ (ecoff_slurp_armap): Don't overlay archive header.
+ * bfd.c: Include libcoff.h.
+
+Tue Aug 3 16:33:11 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (install): Fix sh syntax error.
+
+ * aoutf1.h: Make bfd_error_trap extern; it's defined in bfd.c.
+
+Tue Aug 3 15:19:09 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * nlm_slurp_symbol_table: Don't use '&' on arrays.
+
+Tue Aug 3 11:06:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.c: New file for generic ECOFF functions.
+ * ecoffswap.h: New file for ECOFF swapping functions which differ
+ only slightly for different targets.
+ * libecoff.h: Added prototypes for ecoff.c functions.
+ (ecoff_backend_data): New structure.
+ (ecoff_tdata): Added backend_data field. Changed external data
+ pointers to be PTR rather than to a particular struct.
+ (ecoff_symbol_struct): Moved in from coff-mips.c.
+ * coff-alpha.c, coff-mips.c: Moved common functions into ecoff.c.
+ Added ECOFF backend structures. Include ecoffswap.h.
+ * coff-msym.c: Removed; superseded by ecoffswap.h.
+ * bfd.c: Include coff/internal.h.
+ * Makefile.in (BFD_LIBS): Removed coff-mips.o and coff-msym.o.
+ Added ecoff.o.
+ (BFD64_BACKENDS): Added coff-alpha.o.
+ (CFILES): Removed coff-msym.c. Added ecoff.c.
+ (bfd.o): Added dependency on $(INCDIR)/coff/sym.h.
+ (coff-mips.o): Added dependency on ecoffswap.h and coff/ecoff.h.
+ (ecoff.o, coff-alpha.o): New targets.
+ (coff-msym.o): Removed target.
+
+Mon Aug 2 23:33:38 1993 John Gilmore (gnu@cygnus.com)
+
+ * elf32-hppa.h, hosts/*: Remove (one more time) all occurrances
+ of EXFUN in the BFD sources. Heave ho!
+
+Mon Aug 2 16:45:57 1993 Stu Grossman (grossman at cygnus.com)
+
+ * coffcode.h (coff_set_arch_mach_hook): Add check for I386LYNXMAGIC.
+
+Mon Aug 2 12:18:03 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * hosts/sun3.h: remove some more conflicting decls
+
+Mon Aug 2 11:48:23 1993 Stu Grossman (grossman at cygnus.com)
+
+ * i386lynx.c: Remove unnecessary def of N_HEADER_IN_TEXT,
+ redefine TEXT_START_ADDR to be 0.
+
+Sun Aug 1 22:54:08 1993 Stu Grossman (grossman at cygnus.com)
+
+ * configure.host, configure.in, hosts/i386lynx.h: Lynx/386
+ host and target info.
+
+Fri Jul 30 18:08:27 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlm32-i386.c: New file. First cut at i386 NLM code.
+ * libnlm.h: Added some more prototypes.
+ (struct nlm_relent): New structure.
+ (nlmNAME(symbol_type)): Added rcnt and relocs fields.
+ (struct nlm_obj_tdata): Added new fields: nlm_symbols,
+ nlm_text_low, nlm_data_low, nlm_reloc_fixups,
+ nlm_reloc_fixup_secs.
+ (struct nlm_backend_data): New structure, with accessor macros.
+ * nlmcode.h: Use NLM_HIBIT rather than MSB.
+ (nlm_object_p): Set SEC_RELOC for .text and .data. Don't set
+ SEC_DATA for .bss. Set HAS_RELOC and HAS_SYMS for abfd. Set the
+ architecture.
+ (nlm_swap_fixed_header_out, nlm_swap_variable_header_out,
+ find_nonzero, nlm_swap_auxiliary_headers_out): New outbound
+ swapping functions.
+ (nlm_get_symtab_upper_bound, nlm_slurp_symbol_table): Include
+ external references in symbol table as undefined symbols.
+ (nlm_get_symtab, nlm_slurp_symbol_table): Fill in alocation
+ argument in get_symtab rather than in slurp_symbol_table.
+ (nlm_slurp_symbol_table): Save symbol information in tdata.
+ (nlm_print_symbol): New function.
+ (nlm_slurp_reloc_fixups, nlm_get_reloc_upper_bound,
+ nlm_canonicalize_reloc): New functions to read relocs.
+ (nlm_compute_section_file_positions, nlm_set_section_contents,
+ nlm_external_reloc_compare, nlm_write_object_contents): New
+ functions to create NLM files.
+ * nlm-target.h: Define all the nlm functions here either as
+ default values or in terms of nlmNAME. Use JUMP_TABLE(nlm). Set
+ the backend_data field to TARGET_BACKEND_DATA.
+ * nlm32-gen.c, nlm64-gen.c: Don't define function macros here;
+ they are now in nlm-target.h.
+ (TARGET_BACKEND_DATA): Define as NULL.
+ * nlm.c (nlm_mkobject): Do allocate the tdata field.
+ (nlm_set_arch_mach): New function.
+ * targets.c: Added nlm32_i386_vec.
+ * Makefile.in (BFD32_BACKENDS): Added nlm32-i386.o.
+ (CFILES): Added nlm32-i386.c.
+ (nlm32-gen.o, nlm64-gen.o): Depend on nlm-target.h.
+ (nlm32-i386.o): New target.
+
+Thu Jul 29 20:20:39 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * hosts/sun3.h: remove some function decls that conflict w/ ANSI
+ C, and aren't needed anyway (return int)
+
+Wed Jul 28 15:46:38 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elfcode.h: Use casts with bfd_alloc and alloca.
+
+Tue Jul 27 12:51:43 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * nlm{32,64}-gen.c (JUMP_TABLE_PREFIX): Delete.
+ * nlm{32,64}-gen.c (JUMP_TABLE_INIT): New macro that works with
+ older cpp's, that don't do additional replacement on the JUMP_TABLE
+ macro's argument.
+ * nlm-target.h (JUMP_TABLE_INIT): Use new macro in place of
+ JUMP_TABLE macro.
+
+Mon Jul 26 17:39:01 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ Yet another trad-core variant:
+ * config/esix.mh, hosts/esix.h: New files.
+ * configure.hosts: Use them.
+
+Mon Jul 26 13:22:15 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Handle the case of
+ complain_overflow_bitfield, rightshift > bitpos, and a negative
+ number.
+
+Mon Jul 26 14:40:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elfcode.h: Reimplement segment writing.
+ (elf_write_phdrs): Use precomputed e_phoff rather than making
+ assumptions.
+ (elf_build_phdrs): Disabled, for now.
+ (assign_file_position_for_section): Don't change file offset for
+ SHT_NOBITS.
+ (assign_file_positions_for_symtab_and_strtabs): New function.
+ (struct seg_info): New type.
+ (map_program_segments): New function.
+ (assign_file_positions_except_relocs): For executables, leave
+ section headers &c for last, and properly align all sections with
+ flag SHF_ALLOC set.
+ (prep_headers): No longer abort when EXEC_P is set.
+ (write_shdrs_and_ehdr): Deleted all code relating to program
+ segments.
+
+ * elfcode.h (various): Deleted some unused code, and debugging
+ "malloc(0)" calls.
+ (write_relocs): Cache value of last symbol looked up, to save
+ time if the symbol is referred to repeatedly.
+ (elf_fake_sections): Check only SEC_RELOC flag, not number of
+ relocs.
+ (assign_section_numbers): Likewise.
+
+ * Makefile.in (ofiles): Stars in wildcards belong outside quotes.
+
+ * libelf.h (struct elf_backend_data): New field, maxpagesize.
+ (struct elf_obj_tdata): New field, phdr.
+ * elf32-target.h (elf32_bed): Initialize maxpagesize from
+ ELF_MAXPAGESIZE.
+ (ELF_MAXPAGESIZE): Default to 1.
+ * elf64-target.h (elf64_bed, ELF_MAXPAGESIZE): Likewise.
+ * elf32-sparc.c (ELF_MAXPAGESIZE): Define.
+ (elf_sparc_howto_table): All relocs should have pcrel_offset=true.
+ Most should have length field of `2'.
+
+ * reloc.c (bfd_perform_relocation): Handle 64-bit relocs.
+
+ * config/sparc-aout.mt (TARGET_BACKENDS): Define.
+
+Mon Jul 26 08:56:16 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Don't look in ${srcdir} for ${target_makefile_frag};
+ the top level script has already adjusted for it.
+
+Mon Jul 26 08:09:19 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * srec.c (srec_write_symbols): Get CR LF in the right order.
+
+Mon Jul 26 02:08:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/vaxbsd.h: Include std-host.h. Don't include <machine/param.h>.
+
+Sat Jul 24 16:13:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Handle case of rightshift !=
+ bitpos when overflow checking.
+
+Fri Jul 23 10:20:27 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * bfd.c (bfd_nonrepresentable_section, bfd_undefined_symbol,
+ bfd_reloc_value_truncated, bfd_reloc_is_dangerous, bfd_assert):
+ Send error messages to stderr.
+
+Thu Jul 22 15:57:29 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * nlm{32,64}-target.h: Remove.
+ * nlm-target.h: New file, merged from nlm{32,64}-target.h
+ * libnlm.h (NLM_ARCH_SIZE): Define to ARCH_SIZE.
+ * nlm.c (ARCH_SIZE): Remove define to zero.
+ * nlm32-gen.c (ARCH_SIZE): Define to 32.
+ * nlm32-gen.c (JUMP_TABLE_PREFIX): Define to nlm32.
+ * nlm{32,64}-gen.c (nlm-target.h): Include.
+ * targets.c, libnlm.h, nlm.c, nlm{32,64}-gen.c, nlm{32,64}.c,
+ nlmcode.h: Convert prefixes from bfd_nlm<size> to just
+ nlm<size>, and use macros select size.
+
+Thu Jul 22 15:40:14 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (Makefile): add configure.in, drop redundant
+ $(srcdir), drop redundant ./
+
+Thu Jul 22 13:34:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * hpux-core.c: New file; backend for HP/UX style core files.
+ * bfd.c (struct _bfd): Renamed hppa_core_data field to
+ hpux_core_data.
+ * bfd-in2.h: Updated.
+ * hppa.c (make_bfd_asection, hppa_core_file_p,
+ hppa_core_file_failing_command, hppa_core_file_failing_signal,
+ hppa_core_file_matches_executable_p): Moved into hpux-core.c.
+ Removed from target vector.
+ * libhppa.h (struct hppa_core_struct and accessor macros): Moved
+ into hpux-core.c.
+ * targets.c: If HPUX_CORE is defined, add hpux_core_vec to
+ target list.
+ * config/hp300.mh (HDEFINES): Set to -DHPUX_CORE.
+ (HDEPFILES): Set to hpux-core.o.
+ * config/hppabsd.mh, config/hppahpux.mh: Likewise.
+ * hosts/hp300.h (HOST_HP300HPUX): Define.
+ * Makefile.in (OPTIONAL_BACKENDS): Added sco-core.o,
+ aix386-core.o, hpux-core.o.
+ (sco-core.o, aix386-core.o, hpux-core.o): New dependencies.
+
+ * reloc.c (enum complain_overflow): New enumeration with the
+ various flavours of overflow checking.
+ (srtuct reloc_howto_struct): Changed complain_on_overflow field
+ from boolean to emum complain_overflow. Removed obsolete absolute
+ field.
+ (HOWTO): Removed absolute argument.
+ (bfd_perform_relocation): Do overflow checking on all types of
+ fields.
+ * bfd-in2.h: Updated accordingly.
+ * all targets: Updated initialization of reloc howto tables.
+
+Wed Jul 21 20:34:34 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * opncls.c (bfd_create): Don't use C++ keyword "template" as a C
+ variable name.
+
+Tue Jul 20 15:02:23 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * coff-m68k.c (m68k_howto2rtype): Make arg CONST to match callers.
+
+ * elfcode.h: Fix several illegal pointer combination warnings for
+ usages of bfd_alloc and alloca.
+
+ * libnlm.h (nlm_obj_tdata): Rename hidden struct members to avoid
+ apparent Sun C preprocessor recursion. Fix access macros.
+ * nlmcode.h: Remove spurious '&' before several array references.
+
+Tue Jul 20 14:36:27 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * Rename for DOS uniqueness: coff-m68k-un.c -> coff-u68k.c
+ config/m68k-coffun.mt -> u68k-coff.mt.
+ * Makefile.in, configure.in: Corresponding changes.
+
+Tue Jul 20 16:21:52 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf32-sparc.c (elf_sparc_howto_table): Don't use "&" before
+ function name; it's valid without, and some compilers give
+ warnings with it there.
+
+Tue Jul 20 08:21:15 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * bfd-in.h: Apply some of the changes that were made to bfd-in2.h.
+ * bfd.c (union tdata): Add nlm_obj_data;
+ * targets.c (enum target_flavour): Add bfd_target_nlm_flavour.
+
+Mon Jul 19 20:46:18 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * configure.in (*-*-netware, i[34]86-*-netware): New configs.
+ * Makefile.in (BFD32_BACKENDS): Add nlm.o, nlm32.o, nlm32-gen.o.
+ * Makefile.in (BFD64_BACKENDS): Add nlm64.o, nlm64-gen.o.
+ * Makefile.in (CFILES): Add nlm{32,64}.c, nlm{32,64}-gen.c.
+ * Makefile.in (nlm.o, nlm{32,64}.o, nlm{32,64}-gen.o: New targets.
+ * bfd-in2.h (INLINE): Defines moved here.
+ * {aoutx.h, elf.c, elfcode.h}: Move INLINE defines to bfd-in2.h.
+ * libelf.h (CAT4): Move define to bfd-in2.h.
+ * bfd-in2.h (CAT4): Merge CAT4 macro with other CAT macros.
+ * bfd-in2.h (union tdata): Add nlm_obj_data.
+ * bfd-in2.h (enum target_flavour): Add bfd_target_nlm_flavour.
+ * targets.c (bfd_nlm{32,64}_{big,little}_vec): Add prototypes.
+ * targets.c (target_vector): Add bfd_nlm{32,64}_{big,little}_vec.
+ * (libnlm.h, nlm.c, nlmcode.h, nlm{32,64}-gen.c,
+ nlm{32,64}-target.h, nlm{32,64}.c, config/i386-nlm.mt): New files
+ for NLM support.
+
+Mon Jul 19 15:09:01 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.{hosts,in}: add i[34]86-*-lynxos* support
+
+Mon Jul 19 14:53:30 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * elf.c, elfcode.h, libelf.h: Serious reorganization.
+ Deleted `thunk' structure, merged into tdata, duplicate data
+ eliminated.
+ Rearranged functions, grouping by functionality.
+ Broke up many functions in elfcode.h, re-ordered many parts of
+ file writing to handle unpredictable state of section relocation
+ table as provided by various applications.
+ Still needs cleanup: Merge functions back together, split out
+ data structure with only data that is used only when writing out
+ object file.
+
+ * elf.c (bfd_elf_generic_reloc): New function, taken from
+ coff-mips.c.
+ * elf32-sparc.c (elf_sparc_howto_table): Use it, to work around
+ bfd_perform_relocation lossage.
+
+ * Makefile.in (BFD_LIBS): Include coff-mips.o and coff-msym.o, so
+ that gdb will link.
+ (ofiles): Don't use sort or uniq; do it with sh constructs.
+
+Sun Jul 18 19:42:14 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * coffcode.h: Recognize I386PTXMAGIC.
+ * aoutf1.h, libaout.h: Add M_386_DYNIX.
+ * trad-core.c (TRAD_CORE_USER_OFFSET, TRAD_CORE_STACK_FILEPOS):
+ New macros; use it if defined.
+ * config/symmetry.mh, hosts/symmetry.h: New files.
+
+Fri Jul 16 14:56:31 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * Rename elf{32,64}-generic.c to *-gen.c for 14 char filenames.
+ * Makefile.in: Change accordingly.
+ (CFILES): Add elf64-gen.c.
+
+Fri Jul 16 09:53:23 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c: Use MIPS_AOUT_{OZ}MAGIC rather than {OZ}MAGIC.
+
+Thu Jul 15 16:02:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-m88k.c (howto_table): Corrected bitsize for R_PCR26L from
+ 16 to 26.
+
+Wed Jul 14 15:29:56 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hppa.c [HOST_HPPABSD]: Use hpux-style core files.
+ * libhppa.h [HOST_HPPABSD]: Include hpux version of core.h
+
+Wed Jul 14 09:30:48 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Recognize h8300h-*-*.
+
+Tue Jul 13 12:03:00 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * coff-h8500.c (reloc_processing, rtype2howto): New relocation
+ type R_H8500_HIGH_16.
+ * coff-sh.c (r_imm32): Get the width of the reloc right.
+
+Tue Jul 13 16:48:56 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr)
+
+ * configure.in: Add new target m68k-coffun to the dpx/2.
+ * config/m68k-coffun.mt: New file, renamed from config/dpx2.mt.
+
+Mon Jul 12 10:42:49 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * reloc.c (enum bfd_reloc_code_real): Move SPARC_BASE13 reloc into
+ sparc-aout-specific list.
+
+ * libelf.h (struct elf_obj_tdata): Add field `thunk'.
+
+ * config/sparc-elf.mt (TARGET_BACKENDS): New make variable.
+
+Thu Jul 1 14:52:47 1993 Frederic Pierresteguy (F.Pierresteguy@frcl.bull.fr)
+ and Jim Kingdon (kingdon@cygnus.com)
+
+ * elfcode.h: Use memset not bzero.
+ * trad-core.c: Don't include <sys/file.h>.
+ * i386linux.h: Include <sys/file.h>.
+ * coff-m68k-un.c: new file to handle names with underscores on
+ svr3 machines.
+ * coff-m68k.c (m68k_rtype2howto): added #ifdef ONLY_DECLARE_RELOCS
+ to not duplicate the function in the executable.
+ (TARGET_SYM, TARGET_NAME, NAMES_HAVE_UNDERSCORE): new macros needed
+ by coff-m68k-un.c.
+ * coffcode.h (MC68KBCSMAGIC): case added.
+ * targets.c: Add m68kcoffun_vec.
+ * configure.host: added support for Bull dpx/2.
+ * config/dpx2.mh, hosts/dpx2.h: new files.
+ * Makefile.in: added target coff-m68k-un.
+
+Fri Jul 9 00:43:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aoutf1.h: Add definition of MACHTYPE_OK.
+
+Thu Jul 8 14:37:44 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Don't subtract the addend
+ again for coff.
+
+ * syms.c, bfd-in2.h: Doc fix.
+
+ * coffcode.h (CALC_ADDEND): Check for common section using the
+ section flag as well as the symbol flag.
+
+Thu Jul 8 13:43:52 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/i386bsd.h: Conditionalize HOST_STACK_END_ADDR on __bsdi__.
+ i386bsd.c: Remove defines of N_TXT*; the versions in aout64.h should
+ be sufficient. Define TEXT_START_ADDR.
+
+Wed Jul 7 10:56:21 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * aoutx.h (translate_from_native_sym_flags): Removed statep
+ argument. Just let an indirect symbol point to the next symbol
+ without forcing the next symbol to be undefined. Changed all
+ callers.
+ * hp300hpux.c (slurp_symbol_table): Changed call to
+ translate_from_native_sym_flags.
+ * targets.c: Added hp300hpux_vec.
+ * Makefile.in (hp300hpux.o): Added dependencies.
+
+Tue Jul 6 13:24:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * reloc.c (enum bfd_reloc_code_real): Put simple power-of-two
+ relocs together, and add 64-bit versions.
+ (bfd_generic_get_relocated_section_contents): Argument to alloca
+ is size_t.
+
+ * libbfd.c (bfd_xmalloc_by_size_t): New function.
+ * opncls.c (bfd_cache_init, bfd_open_file): Add prototypes to
+ declarations.
+ (obstack_chunk_alloc): Use bfd_xmalloc_by_size_t.
+ (new_bfd): Prototype-style definition, using DEFUN.
+ (bfd_alloc_grow, bfd_alloc, bfd_zalloc, bfd_realloc): Size
+ argument is type size_t, not bfd_size_type.
+ * ieee.c (obstack_chunk_alloc): Use bfd_xmalloc_by_size_t.
+ * bfd.c (bfd_default_error_trap, bfd_error_trap,
+ bfd_error_nonrepresentabltrap): Prototypes.
+ * libbfd-in.h (bfd_alloc, bfd_zalloc, bfd_realloc,
+ bfd_alloc_grow): Adjusted prototypes for arg type change.
+ * archive.c (get_elt_at_filepos, do_slurp_bsd_armap, normalize,
+ do_slurp_coff_armap, bfd_construct_extended_name_table):
+ Prototypes.
+ * elfcode.h (elf_string_from_elf_strtab): Prototypes.
+ * libelf.h (elf_string_from_elf_section, elf_get_str_section):
+ Prototypes.
+
+ * Makefile.in (ALL_MACHINES): Renamed from BFD_MACHINES.
+ (ofiles): New target. Build a list of unique file names, in case
+ any got duplicated.
+ (TARGETLIB): Use list of files from ofiles.
+ * configure.in: Set BFD_MACHINES and BFD_BACKENDS depending on
+ minimal-bfd flag and target makefile frag contents.
+
+ * elfcode.h (elf_read): Delete static declaration, since function
+ has moved.
+ (elf_map_symbols): Write out section symbols for all sections, for
+ now.
+ (elf_symbol_from_bfd_symbol): Allow match if both symbols are
+ section symbols for the same section.
+ (elf_find_nearest_line): Don't print message, just return false.
+
+ * libelf.h (bfd_elf_locate_sh): Declaration deleted.
+
+Mon Jul 5 16:48:11 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * cpu-h8300.c (h8300_scan): Fix parsing of architecture string.
+
+Fri Jul 2 18:27:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (clean): Remove bfd.h and stmp-bfd.h.
+ (realclean): Remove generated headers.
+
+Fri Jul 2 14:51:51 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * section.c (bfd_set_section_content): Deny if file is not opened with
+ the proper mode, set output_has_begun if file is openened for update.
+ * aoutx.h (aout_*_set_section_content): Remove checks that are now
+ done in bfd_set_section_content.
+
+Fri Jul 2 09:25:20 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * hosts/std-host.h: Removed declarations of printf, fprintf,
+ fcntl, fread and fwrite. They are all error prone for one reason
+ or another. Changed declaration of memchr from char * to PTR.
+
+ * configure.in (mips-*-riscos*): New target; use riscos.
+ * configure.host (mips-*-riscos*): New host; use riscos.
+ * config/riscos.mh (HDEFINES): Add -G 4.
+
+ * libaout.h (GET_SWORD): Use the bfd_h_get_signed entry points
+ rather than casting the result of bfd_h_get.
+
+Fri Jul 2 10:13:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in, hosts/delta68.h, config/delta68.mh: Add stuff for
+ Motorola Delta 68.
+
+Wed Jun 30 06:02:43 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * targets.c (bfd_elf64_{big,little}_generic_vec): Declare, and
+ include in search list if BFD64 is defined.
+
+ * libelf.h (CAT4): Added a version for Saber-C, ANSI mode.
+ (bfd_elf64_*): Declarations for 64-bit versions of many routines.
+
+Tue Jun 29 22:50:59 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf64-target.h, elf64-generic.c: New files.
+ * Makefile.in (BFD64_BACKENDS): Include elf64-generic.o.
+ (elf64-generic.o): List dependencies.
+
+ * Makefile.in: List target `all' explicitly before host/target
+ makefile fragments are included, in case they define any new
+ targets.
+
+ * elfcode.h (ELF_R_INFO, ELF_R_SYM): Define as 32- or 64-bit
+ versions as appropriate. Uses updated.
+ (elf_debug_section): Declare before use.
+ (elf_debug_file): New function.
+ (bfd_section_from_shdr, bfd_shdr_from_section, elf_fake_sections):
+ Alignment value in section header is n_bytes, not log2.
+ (new_section_hook): Do nothing for now.
+ (bfd_section_from_shdr): Use Elf_External_Rel[a], not 32-bit
+ version explicitly.
+ (elf_core_file_p): Simplify check for correct class (word size).
+ (elf_make_sections, elf_fake_sections, elf_write_object_contents):
+ Initialize all fields when creating data structures.
+ (elf_locate_sh): Renamed from bfd_elfXX_locate_sh, made static.
+ (elf_compute_section_file_positions): Set correct class in output
+ file.
+ (elf_write_object_contents): Section symbols have empty names in
+ output file.
+
+ * libbfd.c (bfd_xmalloc, zalloc): Be sure to cast malloc, memset
+ args to size_t before call.
+ (bfd_add_to_string_table): Cast zalloc arg to bfd_size_type.
+
+Tue Jun 29 10:49:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_find_nearest_line): If procedure has no line
+ number information, return 0 for line number.
+
+Mon Jun 28 10:45:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aoutx.h (some_aout_object_p): If *oldrawptr is non-NULL, copy it
+ into *rawptr.
+
+Sun Jun 27 09:05:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/riscos.h: Define NBPG and UPAGES.
+
+Sun Jun 27 16:28:26 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * elfcode.h (elf_slurp_symbol_table): Don't use obj_raw_syms as
+ lvalue; it contains a cast.
+
+Fri Jun 25 17:09:55 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (hash, compare, struct stringtab_entry, add_to_stringtab):
+ Use unsigned hash values for better hashing.
+ (hash): Hash in the string length for long strings.
+
+Thu Jun 24 15:47:51 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (compare): Replace 3 if's with a subtraction.
+ (translate_to_native_sym_flags, add_to_stringtab): Reorder tests
+ in decreasing order of success, as an optimization.
+ (hash): Take a length arg; ignore chars after #25, for speed.
+ (add_to_stringtab): Pass length to hash.
+
+Thu Jun 24 17:25:51 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * elf32-sparc.c (sparc_reloc_map): Add SPARC_WDISP22 reloc.
+
+ * elfcode.h (elf_new_section_hook): Do nothing for now.
+ (elf_write_object_contents): Output common symbols the way ELF
+ wants them.
+
+Wed Jun 23 16:20:07 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * libelf.h (struct elf_obj_tdata and associated macros): Moved
+ here from elfcode.h. A couple of size-specific structure pointers
+ were changed to PTR; uses fixed appropriately.
+ (elf32_symbol_type, elf64_symbol_type): Separated definitions.
+ (bfd_elf_mkobject): Renamed from bfd_elf32_mkobject.
+ (bfd_elf32_mkobject, bfd_elf64_mkobject, elf_mkobject): New
+ temporary macros to ease name change.
+ * elf.c (elf_read, elf_mkobject, elf_get_str_section,
+ elf_string_from_elf_section, bfd_elf_find_section): Moved here
+ from elfcode.h.
+ * doc/Makefile.in (libbfd.h): Process elf.c too.
+ * Makefile.in (elf.o): Note new dependencies.
+
+ * elfcode.h: Lots of stuff moved elsewhere. Deleted some unused
+ code, tweaked some debug hooks.
+ (elf_slurp_reloca_table): Translate ELF section symbols into BFD
+ section symbols.
+
+Wed Jun 23 11:34:21 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * hosts/riscos.h: New file.
+
+Tue Jun 22 14:35:20 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * elfcode.h (bfd_section_from_shdr, case SHT_PROGBITS): Even if
+ section already exists, use its pointer to fill in rawdata slot.
+
+Tue Jun 22 16:36:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/std-host.h: Return value of puts and fputs is int not void.
+
+Tue Jun 22 14:25:58 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (howto_table_ext): Comment the field names.
+ * reloc.c (bfd_perform_relocation): Fix max and min values.
+
+Mon Jun 21 18:19:14 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * elf32-target.h, elf32-hppa.c, elfcode.h: Use new
+ size-independent elf internal data structures.
+ * elfcode.h (put_word, get_word): Define as appropriate for
+ architecture word size. Structure swapping functions changed to
+ use them as appropriate.
+
+ * configure.in: If compiling 64-bit back ends, do them before
+ 32-bit ones.
+
+ * libelf.h: Use new size-independent versions of elf internal data
+ structures.
+ (symbol_type): Reordered to put any fields dependent on target
+ size at the end.
+ (elf_backend_data): Renamed from elf##_backend_data and made
+ size-independent.
+ (elf_sect_thunk): Now size-independent.
+
+ * libbfd.c (bfd_log2): Now returns unsigned int.
+
+Mon Jun 21 12:30:47 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Rename config/m88k-aout.mt to config/noop.mt.
+ configure.in: Use it for mips-*-bsd*.
+
+Sun Jun 20 20:32:19 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * cpu-m68k.c (arch_info_struct): Eliminate "partially bracketed
+ initializer" warning from gcc.
+ * cpu-h8500.c (arch_info_struct): Likewise.
+ * cpu-sh.c (arch_info_struct): Likewise.
+
+ * cpu-h8300.c (local_bfd_reloc_type_lookup, howto*_callback,
+ howto_*): Unused functions and variables commented out.
+ * cpu-z8k.c (local_bfd_reloc_type_lookup, howto*_callback,
+ howto_*): Likewise.
+ * cpu-h8500.c (compatible): Likewise.
+ * cpu-sh.c (compatible): Likewise.
+
+ * hp300hpux.c (swap_std_reloc_in): Delete unused variables.
+ Always set a valid length value, even for invalid input.
+
+ * srec.c (srec_write_symbols): Use sprintf_vma.
+
+ * bfd-in.h (uint64_typeLOW, uint64_typeHIGH, int64_type,
+ uint64_type): Provide default definitions.
+ * hosts/std-host.h (int64 stuff): Remove them from here.
+
+ * bfd-in.h (sprintf_vma): Define parallel to fprintf_vma.
+
+ * elf32-i386.c (elf_i386_reloc_type_lookup): Delete unused
+ variable. Added default case to switch.
+
+ * aoutx.h (translate_from_native_sym_flags): Before casting
+ pointers to integers, make sure the integer type is wide enough.
+ * coff-mips.c (ecoff_set_symbol_info): Ditto.
+
+ * section.c (bfd_get_section_contents): Since `count' is unsigned,
+ don't bother comparing for less-than-zero.
+ (bfd_set_section_contents): Ditto.
+
+ * elfcode.h (bfd_add_to_strtab): Now static.
+ (sym_is_global): New function.
+ (elf_map_symbols): Call it. Now returns void. Removed unused
+ local variable.
+ (bfd_section_from_shdr): Mark string tables other than for section
+ and symbol names as normal sections having contents.
+ (fix_up_strtabs): New function; fixes up ELF header fields for
+ stab sections with string tables associated.
+ (elf_write_object_contents): Map fix_up_strtabs over all BFD
+ sections. Reordered condition tests for symbol flags; default to
+ local-object value instead of global-object.
+ (elf_symbol_from_bfd_symbol): Hid conditionally-used variable
+ inside condition test.
+ (elf_print_symbol): Use fprintf_vma.
+ (elf_idx_of_sym, bfd_shdr_from_section): Unused functions
+ commented out.
+
+ * bfd-in.h (int64_type, uint64_type): Define these if we fall
+ back to "long long" for HOST_64_BIT.
+
+ * libelf.h (elfNAME, ElfNAME): New versions to get desired results
+ without using invalid ANSI C preprocessing tokens.
+
+ * elf32-target.h (bfd_elf32_new_section_hook): Delete macro.
+ * libelf.h (bfd_elf32_new_section_hook): Declare.
+ * elfcode.h (new_section_hook): Define here.
+
+ * hosts/sparc.h, hosts/std-host.h, hosts/i386bsd.h: Protect
+ against multiple inclusions.
+
+ * hosts/news.h: Include hosts/std-host.h, not plain std-host.h.
+
+ * Makefile.in (bfd.h): Generate into current directory by grabbing
+ 64-bit definition (if any) from sysdep.h.
+ * bfd-in.h: Put in marker for sysdep.h inclusion.
+
+Fri Jun 18 19:57:23 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Check for overflow on
+ pc-relative relocations if the howto asked for it.
+
+Fri Jun 18 16:00:20 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (stmp-bfd.h): Ignore nonzero exit status from grep.
+
+Fri Jun 18 16:54:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/riscos.m{h,t}: New files.
+ * configure.{host,in}: Use them.
+
+Fri Jun 18 12:55:10 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * elf32-mips.c: comment change. This is a mips file, not 88k.
+
+Mon Jun 14 14:02:41 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * cache.c (bfd_cache_init): Increment open_files and call close_one
+ if necessary.
+ (bfd_open_file): Don't increment open_files here.
+
+Fri Jun 18 10:00:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config/delta88.mh: Don't set CC.
+
+ * Makefile.in: Add elf32-{mips,m88k,generic}.
+ elf32-{mips,m88k,generic}.c: New files.
+ targets.c (target_vector): Include bfd_elf32_{mips,m88k,generic}_vec.
+ elfcode.h (elf_object_p): Match elf32-generic for all machines which
+ don't match a different target.
+
+Fri Jun 18 03:12:12 1993 John Gilmore (gnu@cygnus.com)
+
+ Eliminate "int8_type", "int16_type", "int32_type", and their
+ variants from the BFD universe. Leave the 64-bit types for now,
+ since they are in flux.
+
+ * aoutx.h, hp300hpux.c: Eliminate needless (int32_type) casts.
+ * libaout.h (GET_SWORD): Convert (int32_type) to (int).
+ * ieee.c: Convert uint8e_type => unsigned char.
+ * oasys.c: Extensive changes to eliminate obsolete types.
+ These depend on changes in ../include/oasys.h as well.
+ * hosts/*.h: Remove declarations of all these types.
+
+Mon Jun 14 14:02:41 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * hosts/delta88.h: #if 0 out some declarations which conflict with
+ system headers.
+
+Mon Jun 14 17:08:18 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in (install): remove parentdir cruft
+
+Mon Jun 14 19:04:09 1993 Stu Grossman (grossman@cygnus.com)
+
+ * hppa.c (hppa_get_symbol_info): Remove redundant copy.
+ * Expurgate random DEFUNs that have crept in.
+
+Mon Jun 14 10:23:53 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_set_symbol_info): Constructor sections should
+ only be aligned to a 4 byte boundary.
+
+Sat Jun 12 16:13:17 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * hosts/std-host.h (struct int64e_struct): Remove needless typedef
+ keyword.
+
+Fri Jun 11 14:25:34 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * aoutf1.h (sunos4_write_object_contents): set flags to 1, breaking
+ 1927 but fixing some other important things.
+
+Thu Jun 10 20:36:22 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * hosts/std-host.h (int64e_type): Fix definition.
+
+Thu Jun 10 11:48:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_sec_to_styp_flags): Use STYP_MIPS_INIT for
+ section named _INIT. Don't set STYP_TEXT unless SEC_CODE is set.
+ (ecoff_styp_to_sec_flags): Treat a STYP_MIPS_INIT section like
+ a STYP_TEXT section.
+
+Wed Jun 9 16:48:13 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in (install, headers): don't put comments after a tab
+ in the actions section of a rule
+
+Wed Jun 9 15:00:01 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_mkobject_hook): Mark ZMAGIC files as D_PAGED.
+ (ecoff_write_object_contents): If not D_PAGED, don't add the
+ section headers to text_size. If not D_PAGED, set the magic
+ number to OMAGIC rather than ZMAGIC. If creating a D_PAGED
+ executable, the executable must fully occupy an even number of
+ pages.
+ (ecoff_set_symbol_info, make_bfd_asection, ecoff_little_vec,
+ ecoff_big_vec): Consistently set section alignment power to 4,
+ since ECOFF sections should be multiples of 16 bytes.
+ (ecoff_little_vec, ecoff_big_vec): Added D_PAGED to object_flags.
+ Made ar_pad_char and ar_max_namelen agree for both.
+
+Tue Jun 8 20:28:02 1993 Mark Eichin (eichin at tweedledumber)
+
+ * elfcode.h (elf_slurp_symbol_table): subtract section vma from
+ symbol value, since bfd symbols are section relative, but ELF
+ symbols aren't.
+
+Tue Jun 8 12:08:27 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * cpu-i960.c, cpu-h8300.c (compatible): Make static.
+
+Tue Jun 8 14:27:56 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * hosts/news.h, config/news.mh: New files.
+
+Tue Jun 8 12:08:27 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * bfd-in2.h, archures.c (bfd_mach_h8300[h]): new defines.
+ * coff-h8300.c: More addressing modes.
+ * coffcode.h (coff_set_arch_mach_hook): Cope with H8300 magic
+ number.
+ * cpu-h8300.c: Removed disassemble stuff. (h8300_scan): Recognise
+ H8/300H name. (compatible): New function.
+ * reloc16.c (bfd_coff_reloc16_get_relocated_sec): Cope with more
+ addressing modes.
+
+Tue Jun 8 10:30:13 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_compute_section_file_positions,
+ ecoff_write_object_contents): Only round to page boundaries if
+ D_PAGED flag is set for the output BFD.
+
+Fri Jun 4 15:47:52 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * coffcode.h (get_index, coff_slurp_symbol_table): Fix pointer
+ casts to work on machine where sizeof(long) != sizeof(int) !=
+ sizeof(char *).
+ * coffgen.c (coff_get_normalized_symtab): Ditto.
+ * cpu-h8300.c coff-h8300.c: Support for H8/300-H.
+
+Fri Jun 4 15:24:27 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * coffgen.c (coff_write_symbols): For empty string table, write
+ out 4 in correct byte order. (from minyard@bnr.ca)
+
+ * elf32-hppa.c: Don't include libhppa.h for now; define
+ BYTES_IN_WORD instead, until Utah sends a better fix.
+ (hppa_elf_build_arg_reloc_stub): Use xmalloc and xrealloc instead
+ of malloc and realloc.
+
+Fri Jun 4 07:49:01 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-*-ecoffl*): New target; use decstation.
+ (mips-*-ecoff*): Added trailing '*'.
+
+ * coff-mips.c (ecoff_get_debug): Get the offset from the first PDR
+ for the FDR, not from the first PDR in the file.
+
+Thu Jun 3 16:41:10 1993 Stu Grossman (grossman@cygnus.com)
+
+ * hppa.c (hppa_get_symbol_info): New func needed for JUMP_TABLE.
+
+Thu Jun 3 15:33:57 1993 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * hppa.c (hppa_get_symbol_info): New function.
+
+Thu Jun 3 13:07:42 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elfcode.h (elf_map_symbols): Don't crash if no symbols have been
+ allocated yet.
+
+ From Peter Hoogenboom (hoogen@schafer.cs.utah.edu):
+ * libhppa.h (MAXCOMLEN): Define unconditionally.
+ (_PA_RISC_ID): Only define if not already defined.
+ * elf32-hppa.c: Include libhppa.h.
+
+ From Ralph Campbell:
+ * hosts/mipsbsd.h (HOST_DATA_START_ADDR): Delete definition.
+
+ * elf32-hppa.h (symext_rootP, symext_lastP): Delete decls.
+
+Thu Jun 3 00:23:53 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/go32.mh: define EXTRALIBES to -lm (for binutils), also
+ remove defines of __MSDOS__ and __GO32__ (these are in the
+ compiler now).
+
+Wed Jun 2 17:57:13 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ From Utah:
+ * hosts/hppabsd.h: Eliminate use of obsolete EXFUN.
+ * config/hppabsd.mh: Don't use ranlib.
+
+Tue Jun 1 04:15:57 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * elf.c: New file, for word-size independent code.
+ * elfcode.h (elf_hash): Moved to there, renamed bfd_elf_hash.
+ * Makefile.in: Include elf.o in standard objects.
+
+ * bfd-in.h (CAT3): Define here.
+ * libaout.h, libelf.h: Not here.
+
+ * libelf.h (struct strtab): Define here.
+ (bfd_elf_locate_sh): Declare here.
+ * elfcode.h (struct strtab): Definition deleted.
+
+ * reloc.c (enum bfd_reloc_code_real): Added HPPA_PCREL_CALL_12.
+
+ * Makefile.in: Make "all", not "bfd.h", be the default target.
+ (stmp-bfd.h): New target; prevents rebuilding world if bfd.h
+ hasn't really changed.
+
+ Tue May 25 12:15:15 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_hash): Provide elf standard hash function.
+ (various): Key off of the machines use_rela_p field to determine
+ whether to use REL or RELA relocations.
+ (elf_swap_reloc_out, elf_swap_reloc_in): New functions.
+ (elf_make_sections): Allocate a pointer to hold all data for a
+ given section, and copy each fragment into the data region.
+ Update the section's pointer with the REL implicit addends if the
+ machine uses REL relocation.
+
+ * elf32-i386.c (elf_bfd_reloc_type_lookup): Rename to
+ elf_i386_bfd_reloc_type_lookup, and use cpp to map the name back
+ into was elf32-target.h expects.
+ (elf_info_to_howto): Rename to elf_i386_info_to_howto.
+ (elf_i386_bfd_reloc_type_lookup): Add relocation support.
+ (elf_i386_info_to_howto): Add minimal relocation support.
+
+ * libelf.h (elf_backend_data): Add use_rela_p, elf_64_p,
+ elf_info_to_howto_rel fields.
+
+ * elf32-target.h (elf_bed): Add support for new fields in
+ elf_backend_data.
+
+ Sun May 30 16:38:24 1993 Peter Hoogenboom (hoogen@fast.cs.utah.edu)
+
+ * elf32-hppa.c: Add symbol extension section support, fix
+ relocation howto table, add stub generation support.
+
+ * elf32-hppa.h: Add symbol extension section support, fix
+ relocation howto table, add stub generation support.
+
+ * elfcode.h (bfd_elf_locate_sh): New function to locate ELF
+ section header.
+
+ * elfcode.h (bfd_add_to_strtab): Made non-static due to a call
+ from elf32-hppa.c.
+
+ * elfcode.h (elf_idx_of_sym): Return STN_UNDEF instead of 0 when
+ the symbol is not found.
+
+ * elfcode.h (elf_compute_section_file_positions): Not all section
+ file positions were computed.
+
+ * elfcode.h (elf_get_sect_thunk): New function.
+
+ * hppa.c (sign_ext): Reimplement.
+
+ * hppa.c (round_down,round,round_up,L,R,LS,RS,LD,RD,LR,RR): Make
+ these functions static.
+
+Tue Jun 1 14:40:41 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (bfd.h): Move closer to headers - and after 'all'!
+
+ * aoutx.h (translate_from_native_sym_flags): Don't set
+ BSF_DEBUGGING for constructor symbols, only BSF_CONSTRUCTOR.
+ * aoutx.h (translate_to_native_sym_flags): Translate
+ constructor symbols properly.
+
+Thu May 27 16:09:04 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * archures.c (bfd_default_arch_struct): use 4 byte alignment as a
+ minimum.
+ * aout-target.h (minimum_alignment): 8 byte alignment is right.
+ (fix ld/2680)
+
+Thu May 27 13:38:47 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in, Makefile.in: Build bfd-in2.h in source directory,
+ from bfd-in.h and .c files. Build bfd.h in build directory,
+ substituting in requested target word size. Insert word size into
+ makefile, and maybe enable 64-bit targets.
+
+ * bfd-in.h, libbfd.c, demo64.c, targets.c: Define BFD64 if 64 bits
+ are available. Conditionalize on this. Assume HOST_64_BIT
+ will be defined if needed, so 64-bit targets are conditionalized
+ only in the Makefile.
+
+Tue May 25 14:03:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * libbfd.c (COERCE64): Rewrite to avoid out-of-range values.
+
+ * coff-sh.c (rtype2howto): Put error message on stderr.
+ (extra_case): Delete unused variable.
+
+ * coff-mips.c (ecoff_print_symbol): Cast bfd_vma values to long
+ before calling printf.
+
+ * elfcode.h: New file, almost completely derived from old elf32.c.
+ * elf32.c: Now just define ARCH_SIZE and include elfcode.h.
+ * Makefile.in (elf64.o): List dependencies, don't build by
+ default.
+ (elf64.c): Add to list of sources.
+ (elf32.o): Update dependencies.
+ * elf32-*.c: Updated type/macro/structure names. Cleaned up
+ namespace pollution; rename vectors.
+ * targets.c, config/*-elf.mt: Updated.
+ * All uses of 32-bit versions of structures, routines, and macros
+ renamed.
+
+ * Makefile.in (archures.o, targets.o): Depend on Makefile.
+
+Mon May 24 15:53:13 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * elf32-i386.c (enum reloc_type): No comma after last enumerator.
+
+ * elf32.c (elf_string_from_elf_section): Handle index of zero
+ specially.
+ (bfd_section_from_shdr, elf_slurp_symbol_table): Don't need to do
+ so here.
+ (elf_write_object_contents): Deleted one unused variable and
+ initialized another to avoid gcc warnings.
+ (elf_set_section_contents): Delete unused variable.
+
+Fri May 21 19:04:21 1993 Stu Grossman (grossman@cygnus.com)
+
+ * i386lynx.c: New module for Lynx variant of a.out.
+ * Makefile.in (BFD_BACKENDS CFILES depends): Add i386lynx.c.
+ * gen-aout.c: Get rid of defunct endian stuff, print out true
+ pagesize.
+ * targets.c (target_vector): Add i386lynx_vec.
+
+Fri May 21 17:02:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * configure.in: Use i386-sco.mt for i[36]86-*-isc*.
+
+Fri May 21 13:44:18 1993 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * aix386-core.c, aout-target.h, aoutx.h, coff-alpha.c,
+ coff-mips.c, coffgen.c, elf32.c, ieee.c, libaout.h, libcoff-in.h,
+ libelf.h, mipsbsd.c, oasys.c, sco-core.c, srec.c, tekhex.c,
+ trad-core.c: Define a TARGET_get_symbol_info function or macro.
+ Remove the bfd_print_symbol_nm case from TARGET_print_symbol.
+
+ * bfd-in.h: Don't define bfd_print_symbol_nm.
+ Define symbol_info type.
+ (JUMP_TABLE): Set _get_symbol_info element.
+
+ * syms.c (coff_section_type, bfd_symbol_info): New functions.
+ (bfd_decode_symclass): Use coff_section_type.
+
+ * targets.c: Add bfd_get_symbol_info call.
+
+Wed May 19 15:30:52 1993 Stu Grossman (grossman@cygnus.com)
+
+ * coff-i386.c (coff_i386_reloc): Use unsigned char to avoid
+ complaints from ancient gcc's.
+
+Wed May 19 15:51:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * trad-core.c: Check macro TRAD_CORE_EXTRA_SIZE_ALLOWED.
+ hosts/i386linux.h: Define it.
+
+Mon May 17 15:00:33 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * VERSION, bfd-in.h: Bump version number to 2.2.
+
+ * hppa.c (assemble_3, dis_assemble_3, assemble_12,
+ dis_assemble_12, assemble_17, dis_assemble_17, assemble_21,
+ dis_assemble_21, sign_ext, ones, sign_unext, low_sign_ext,
+ low_sign_unext, round_down, round, round_up, L, R, LS, RS, LD, RD,
+ LR, RR, hppa_field_adjust): New functions.
+
+Mon May 17 10:04:16 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_set_symbol_info): Added support for indirect
+ stabs symbols, including new indirect_ptr_ptr argument.
+ (ecoff_slurp_symbol_table): Pass new argument in calls to
+ ecoff_set_symbol_info.
+
+Fri May 14 00:05:06 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: For m68k sysv systems, use m68k-coff.
+
+ * config/hppa-elf.mt (TDEFINES): Don't define DEFAULT_VECTOR here.
+ (TDEFAULTS): Define it here. Use the new name.
+
+ * elf32-hppa.c (elf_hppa_backend_data): Delete; rely on default
+ values instead.
+
+ * reloc.c (bfd_reloc_code_real_type): Add some HPPA reloc types.
+
+ * aix386-core.c (NO_GETS): Fix PROTO invocation to have correct
+ number of arguments.
+ (aix386_core_file_p): Initialize core_size to correct value.
+
+Wed May 12 14:39:59 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (CC_FOR_BUILD): New variable, set to $(CC).
+ (FLAGS_TO_PASS): Pass down CC_FOR_BUILD.
+
+ * bout.c (aout32_slurp_extended_name_table): Define to be
+ _bfd_slurp_extended_name_table rather than bfd_true.
+
+ * coff-mips.c: Include libaout.h and aout/aout64.h to get
+ definitions for N_SET[ATDB].
+ (ecoff_howto_table): Moved near top of file.
+ (ecoff_set_symbol_info): If a STABS symbol of type N_SET[ATDB] is
+ seen, cook up a constructor section of the same name and put in a
+ reloc pointing to the symbol. This lets the GNU linker build
+ global constructors and destructors without using collect.
+
+Tue May 11 00:33:31 1993 John Gilmore (gnu@cygnus.com)
+
+ * coff-m88k.c (m88kbcs_vec): Symbols have underbars.
+
+Mon May 10 05:55:45 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * hosts/miniframe.h: New file.
+ * configure.host: Use it.
+
+Sun May 9 16:36:59 1993 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (hppa*-*-bsd): Change to hppa*-*-bsd*
+ * configure.in (hppa*-*-hpux): Change to hppa*-*-hpux*
+ * configure.in (m68*-hp-bsd): Change to m68*-hp-bsd*
+ * configure.in (m68*-*-hpux): Change to m68*-*-hpux*
+ * configure.in (*-*-bsd): Change to *-*-bsd*
+
+Wed May 5 16:08:32 1993 Per Bothner (bothner@cygnus.com)
+
+ * elf32-hppa.c (elf_hppa_reloc_type_lookup): Cast enums to
+ int, for the sake of the old Portable C Compiler.
+
+Mon May 3 14:37:01 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Makefile.in (CFILES): Add cpu-sh.c and coff-sh.c.
+
+Mon May 3 14:03:21 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * configure.in: Get target name right for m68*-*-hpux.
+
+Sun May 2 11:39:44 1993 Fred Fish (fnf@cygnus.com)
+
+ * trad-core.c (NO_SIGNED_GET): New macro.
+ * trad-core.c (trad_core_vec): Use new NO_SIGNED_GET instead of
+ signed NO_GET, where appropriate.
+
+ * configure.in (i[34]86-*-linux*): Add; bfd_target = i386-linux.
+ * configure.in (*-*-linux*): Remove until linux port for a
+ non-i386/i486 system is actually available.
+
+Fri Apr 30 20:04:10 1993 Stu Grossman (grossman@cygnus.com)
+
+ * libhppa.h: #undef e_* symbols which come from <machine/som.h>
+ when compiling under HPUX.
+
+Fri Apr 30 17:25:23 1993 Stu Grossman (grossman@cygnus.com)
+
+ * The following patches are from Jeffrey Law <law@cs.utah.edu>.
+ * hppa.c (hppa_core_file_p): Provide a temporary dummy routine
+ for HOST_HPPABSD.
+ * bfd/hosts/hppabsd.h: Fix declarations of malloc and free.
+ * bfd/libhppa.h: Include sysdep here. Conditionalize
+ includes based on HOST_HPPAHPUX or HOST_HPPABSD.
+ Provide definitions for MAXCOMLEN and _PA_RISC_ID suitable
+ for BSD.
+
+Fri Apr 30 17:34:11 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf32-hppa.c: Don't include a.out.h. Apparently not even the
+ GNU version is needed.
+
+Fri Apr 30 09:38:59 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * coffcode.h: use dummy_reloc16_extra_cases rather than casting abort.
+
+Thu Apr 29 11:30:32 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in: Build elf32-hppa.o.
+
+ * syms.c (BSF_FUNCTION): New symbol flag.
+
+ * elf32-hppa.c: Fixed to work with elf32-target.h.
+
+ * hp300hpux.c (NAME, NAME_swap_exec_header_in): Fix for
+ traditional C.
+ * libaout.h (NAME): Don't define if already defined.
+
+ * libelf.h: Protect against multiple inclusions.
+ (elf_symbol_type): Moved here, added new fields.
+ (struct elf_backend_data): New field `global_sym'; I suspect this
+ may be misplaced.
+ * elf32.c (elf_symbol_type): Deleted from here.
+ (struct elf_obj_tdata): New fields raw_syms and internal_syms, to
+ point to backend versions of symbols.
+ (obj_symbols, obj_raw_syms, obj_internal_syms): New macros.
+ (elf_swap_phdr_out, elf_build_phdrs, elf_write_phdrs): New
+ functions.
+ (elf_write_object_contents): Write program headers if appropriate.
+ (bfd_section_from_shdr): Unnamed sections get empty string for
+ name, not "unnamed". Handle SHT_NOBITS separately from
+ SHT_PROGBITS, and set some different flags.
+ (elf_file_p): New routine.
+ (elf_object_p, elf_core_file_p): Call it.
+ (elf_object_p): Handle EM_HPPA.
+ (elf_symbol_from, elf_idx_of_sym): New functions.
+ (elf_make_sections): Get symbol number right for relocations. Set
+ SHF_ALLOC, SHF_WRITE, SHF_EXECINSTR when appropriate.
+ (elf_fake_sections): BSS section should be SHT_NOBITS, not
+ SHT_PROGBITS. Always generate symtab and strtab, not only if
+ relocations are needed. Set SHF_* flags as appropriate.
+ (elf_compute_section_file_positions): Handle bfd_arch_hppa.
+ (elf_write_object_contents): Fix off-by-one error in symbol count.
+ Store a correct value for the symbol; write the size field
+ properly; make some guesses about the type field. Set section
+ type correctly for string tables.
+ (section_from_elf_index): Check for absolute and common sections
+ first.
+ (elf_section_from_bfd_section): Ditto.
+ (elf_slurp_symbol_table): Use elf_symbol_type instead of asymbol.
+ Use empty string instead of "unnamed" for nameless symbols.
+ Handle STTY_FUNC type, and weirdness with "$global$" symbol for
+ HPPA (only?). Don't free raw symbols; keep the pointer around for
+ later.
+ (elf_set_arch_mach): Handle bfd_arch_hppa.
+ (elf_find_nearest_line): Just return false.
+ (elf_write_object_contents, elf_set_section_contents): Set
+ output_has_begun field after computing file positions.
+ (elf_set_section_contents): Write section contents immediately,
+ rather than caching the whole file and writing it at close time.
+
+ * libhppa.h (enum hppa_reloc_field_selector_type, enum
+ hppa_reloc_field_selector_typ_alt, enum hppa_reloc_expr_type, enum
+ hppa_reloc_expr_type_alt): New enumerator types.
+
+ * config/hppa-elf.mt,. config/hppaosf.mh: HP PA/OSF support.
+ * configure.in, configure.host: Use them.
+
+Wed Apr 28 23:21:01 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf32-target.h: Allow overrides of armap defaults.
+
+ * elf32-hppa.c, elf32-hppa.h: New files.
+
+ * config/hp300hpux.mt: New file.
+
+Tue Apr 27 05:39:40 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * aix386-core.c (NO_GETS): New macro; NO_GET for signed values.
+ (aix386_core_vec): Update for new fields.
+
+ * archive.c (bfd_generic_archive_p): Call target-specific
+ slurp_armap code, instead of bfd_slurp_armap.
+ (bfd_slurp_bsd_armap_f2): New function.
+ * libbfd-in.h (bfd_slurp_bsd_armap_f2): Declare it.
+ * aout-target.h (AR_PAD_CHAR): Define it if not already defined.
+ (vec): Use it.
+ * libaout.h (struct aoutdata): New field for subformat, for
+ differentiating between highly similar a.out formats.
+ * aoutx.h (NAME_swap_exec_header_in): New macro, defaults to local
+ version of function.
+ (swap_exec_header_in): Don't define if NAME_swap_exec_header_in is
+ already defined.
+ * hp300hpux.c: New file.
+ * Makefile.in: Include it.
+
+Mon Apr 26 13:24:43 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * Makefile.in, archures.c, coffcode.h, targets.c: Support for
+ Hitachi SH.
+
+Mon Apr 26 13:55:42 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * trad-core.c (trad_unix_core_file_p): Check the file size.
+
+Mon Apr 26 13:24:43 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-alpha.c: Remove duplicate function and add warnings.
+
+Mon Apr 26 11:25:58 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * sco-core.c (sco_core_vec): Add initializers for new target
+ fields.
+
+Sat Apr 24 21:33:45 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * coffcode.h [_LIT]: Recognize .lit section.
+
+Fri Apr 23 19:00:36 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-alpha.c, cpu-alpha.c, config/alphaosf.mt,
+ config/alphaosf.mt, hosts/alphaosf.h: New files.
+
+Fri Apr 23 16:48:46 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Merge in HPPA/BSD changes from Utah.
+ * hppa.c: Use this for both HPUX & BSD.
+ * targets.c: Enable hppa_vec for both HPUX & BSD.
+ * config/hppabsd.mt: TDEFINES => TDEFAULTS.
+ * hosts/hppabsd.h: #define HOST_HPPABSD.
+
+Wed Apr 21 01:50:10 1993 John Gilmore (gnu@cygnus.com)
+
+ * libbfd.c: Whitespace changes around byteswap macros.
+ * libbfd-in.h: Whitespace changes around byteswap declarations.
+
+Tue Apr 20 15:59:07 1993 Stu Grossman (grossman@cygnus.com)
+
+ * aoutf1.h (sunos4_core_file_p): Don't default bfd_error to
+ system_error anymore. It confuses bfd_check_format().
+
+Mon Apr 19 23:03:08 1993 Stu Grossman (grossman@cygnus.com)
+
+ * bfd.c: Add sgi_core_data to tdata union.
+ * coff-mips.c: Add Irix 4.x core file support.
+ * hosts/irix4.h: #define HOST_IRIX4.
+
+Mon Apr 19 18:52:52 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * aoutx.h (translate_from_native_sym_flags): Check that the
+ symbol's section does get set.
+ (slurp_symbol_table): Zero index means null-string name.
+
+ * aoutx.h (struct stringtab_entry, struct stringtab_data): New
+ data structures.
+ (hash, stringtab_init, add_to_stringtab, emit_strtab, compare):
+ New functions.
+ (write_syms): Use them, to reduce string table size.
+
+Mon Apr 19 16:45:12 1993 Fred Fish (fnf@cygnus.com)
+
+ * trad-core.c (trad_core_vec): Add 6 new initializers to match
+ new signed get/put fields. Minor reformatting to label
+ some fields.
+
+Mon Apr 19 06:09:41 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * bfd-in.h: Insert comment about SVR3 compiler warnings.
+
+ * hosts/{hp300,i386isc,i386v}.h: Remove unused #defines of {r,}index
+ (bfd uses strchr and the broken SVR3.2 cpp loses with the defines).
+
+ * libbfd.c: bfd_put*: Remove casts to bfd_vma.
+
+Fri Apr 16 17:49:27 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * aoutf1.h (internal_sunos_core): Make c_stacktop a bfd_vma.
+ (swapcore_sparc): Make sp a bfd_vma.
+
+Thu Apr 15 09:09:18 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * libbfd.c: Add signed versions of bfd_{h_,}{get,put}_signed_<size>.
+ libbfd.c, libbfd-in.h: Add _do*signed*.
+ targets.c, all targets: Add bfd*signed*.
+ bfd-in.h: Add bfd_signed_vma. Add comments.
+
+ * bfd-in.h (bfd_error), bfd.c (bfd_errmsgs): Add file_truncated.
+
+ * format.c (bfd_check_error): Check error return from
+ _bfd_check_format routines.
+
+Wed Apr 14 23:48:25 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * rs6000-core.c (rs6000coff_core_p): Improve error checking and
+ recognize .data section if present.
+
+Thu Apr 15 01:00:29 1993 John Gilmore (gnu@cygnus.com)
+
+ * aoutx.h (aout_*_adjust_sizes_and_vmas): Avoid `sanity'
+ check for the case where the user sets the address of the BSS
+ section (and the file header can't specify this). Let the user
+ set it wherever they want, regardless of what goes in the header.
+
+ * ieee.c (ieee_slurp_sections): Pass all ieee section names
+ straight through into BFD sections. Add comments.
+
+Wed Apr 14 20:34:54 1993 John Gilmore (gnu@cygnus.com)
+
+ Cleanup in preparation for better 64-bit host support.
+
+ * bfd-in.h (bfd_64_type): Remove.
+ * libbfd.c (_do_getb64, _do_putb64): Use bfd_vma, not bfd_64_type.
+
+ * bfd-in.h (bfd_size): Remove.
+
+ * bfd-in.h (bfd_offset): Remove, after fixing ld/ldlang.[ch].
+
+ * bfd-in.h (bfd_word): Remove.
+ * reloc.c (reloc_howto_type): Replace bfd_word with bfd_vma.
+
+ * bfd-in.h (rawdata_offset): Remove.
+ * reloc.c (arelent): Replace rawdata_offset with bfd_size_type.
+ (bfd_perform_relocation): Lint.
+ (enum bfd_reloc_status): Comment cleanup.
+
+ * aout-adobe.c, cpu-h8300.c, mipsbsd.c, srec.c: lint -Wall.
+
+Tue Apr 13 11:19:52 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * aoutf1.h (swapcore_sparc): Guess the right value of USRSTACK.
+
+Mon Apr 12 14:18:00 1993 John Gilmore (gnu@cygnus.com)
+
+ * elf32.c: Clean up old comments.
+
+Fri Apr 9 10:43:20 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/sun3.h: String argument to fprintf is const.
+
+ * coff-mips.c: Renamed PAGE_SIZE to ROUND_SIZE, to avoid confusion
+ on systems which define PAGE_SIZE in <limits.h>.
+
+Thu Apr 8 10:28:00 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * trad-core.c (trad_unix_core_file_failing_signal): Use new macro
+ TRAD_UNIX_CORE_FILE_FAILING_SIGNAL to allow host files to specify
+ the core file failing signal.
+ * hosts/decstation.h (TRAD_UNIX_CORE_FILE_FAILING_SIGNAL): Define
+ to supply the core file failing signal.
+
+Thu Apr 8 09:17:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h (styp_to_sec_flags): Only set SEC_SHARED_LIBRARY for
+ a STYP_NOLOAD | STYP_BSS section if BSS_NOLOAD_IS_SHARED_LIBRARY
+ is defined. On many COFF targets STYP_BSS is always STYP_NOLOAD.
+ * coff-i386.h (BSS_NOLOAD_IS_SHARED_LIBRARY): Define.
+
+Wed Apr 7 11:33:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (PAGESIZE): Correct value.
+
+Tue Apr 6 12:05:44 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_find_nearest_line): Address of first PDR is
+ an offset (patch from Jean-Daniel Fekete <jdf@lri.lri.fr>).
+
+Mon Apr 5 12:07:12 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h (styp_to_sec_flags): Set SEC_SHARED_LIBRARY for a
+ STYP_NOLOAD | STYP_BSS section. Don't set SEC_NEVER_LOAD for a
+ STYP_INFO section.
+ (coff_compute_section_file_positions): Force vma and lma of _LIB
+ section to be zero.
+ (coff_set_section_contents): Count number of entries in new lma
+ field, not in vma.
+ * coffgen.c (make_a_section_from_file): Force lineno_count of
+ SEC_SHARED_LIBRARY section to be zero, since it is non-zero on the
+ SCO 3.2v4 shared library.
+ * seclet.c (rel): Copy over any section with contents, not just
+ loadable sections.
+
+ * coff-mips.c (ecoff_make_empty_symbol): Zero out newly allocated
+ symbol.
+
+ * coff-i386.c (coff_i386_reloc): New function, to generate
+ relocateable output correctly.
+ (howto_table): Use coff_i386_reloc for all reloc types.
+ (CALC_ADDEND): Use a more efficient hack to get the correct addend
+ for a common symbol.
+ (i386comm_value): Removed; no longer needed.
+
+Sun Apr 4 15:08:48 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coffcode.h (coff_set_section_contents): Don't write out
+ sections without a filepos.
+
+Fri Apr 2 14:35:05 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * seclet.c (seclet_dump_seclet): Correct SEC_HAS_CONTENTS test.
+
+Wed Mar 31 17:41:05 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * reloc.c (bfd_reloc_code_real_type): Added BFD_RELOC_MIPS_GPREL.
+ * libecoff.h (ecoff_data_type): Added gp_size field.
+ * coff-mips.c (ecoff_mkobject_hook): Initialize gp_size to 8.
+ (ecoff_set_symbol_info): Compare against gp_size, not hardcoded 8.
+ Set flags to 0 for large common symbols.
+ (ecoff_gprel_reloc): Handle non-zero addend for external symbols,
+ which can occur for gas-generated relocs.
+ (ecoff_bfd_reloc_type_lookup): Added BFD_RELOC_MIPS_GPREL case.
+ * bfd.c (bfd_get_gp_size, bfd_set_gp_size): New functions.
+ * Makefile.in (bfd.o): Now depends on coff/sym.h and libecoff.h.
+
+Tue Mar 30 09:33:16 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * srec.c (srec_set_section_contents): Use lma field for load
+ address.
+ * section.c: Add declaration of lma field to section structure.
+ * coffcode.h (coff_write_object_contents): Use lma field for load
+ address.
+ * bfd-in.h (bfd_set_section_vma): Set lma along with vma.
+
+ * aoutx.h (translate_from_native_sym_flags): Now handles indirect
+ symbols in a better way. (translate_to_native_sym_flag): Set the
+ N_INDR bit when necessary. (aout<>slurp_symbol_table): Maintain
+ indirect state.
+ * section.c: Added BFD_IND_SECTION_NAME and bfd_ind_section.
+ (bfd_make_section): Cope with new builtin section.
+ * syms.c (bfd_decode_symclass): Can now print indirect section
+ info.
+
+Wed Mar 24 13:36:33 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * aout-target.h (MY(object_p)): Fail if MACHTYPE_OK is
+ defined, and yields false.
+ * aout-mipsbsd.c, i386bsd.c: Define MACHTYPE_OK appropriately.
+
+ * archive.c (snarf_ar_hdr): Add support for reading (only,
+ so far) BSD-4.4-style extended headers.
+ * archive.c: Some more comments.
+
+Wed Mar 24 02:05:10 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: fix rule for dvi and info, so that the recursive
+ makes does the right thing, instead of always info
+
+Wed Mar 24 02:56:44 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * libbfd.c (bfd_seek): Disable optimized handling for archives and
+ archive members; they need more special reatment. For now, verify
+ that computed and actual file positions correspond.
+
+Tue Mar 23 08:45:33 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * mipsbsd.c: Renamed from aout-mipsbsd.c.
+ (set_arch_mach): Delete non-MIPS code.
+ (reloc_howto_type_lookup): Ditto.
+ * Makefile.in: Adjusted.
+
+ * libbfd.c (bfd_tell): Update `where' field.
+ (bfd_seek): Don't do anything if we're not changing the file
+ position. If FILE_OFFSET_IS_CHAR_INDEX is defined, check `where'
+ field against a SEEK_SET request. Call bfd_tell to re-update
+ `where' field when done.
+ (bfd_read, bfd_write) [FILE_OFFSET_IS_CHAR_INDEX]: Maintain
+ `where' field.
+ * hosts/sparc.h: Define FILE_OFFSET_IS_CHAR_INDEX.
+
+Mon Mar 22 23:18:10 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added installcheck target
+
+Mon Mar 22 14:57:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_set_symbol_info): Relocate encapsulated stabs
+ if the type is not stNil.
+
+Tue Mar 16 10:35:27 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * elf32.c (elf_little_vec, elf_big_vec): Delete now-invalid
+ forward declarations.
+
+ * elf32-sparc.c (elf_sparc_howto_table): Don't use CONST here,
+ it's implied by the type.
+
+Fri Mar 12 18:58:08 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.host: recognize sparc-sun-solaris2* instead of sparc-sun-solaris*
+
+Tue Mar 9 09:23:12 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * rs6000-core.c: Add .ldinfo section.
+
+Fri Mar 12 11:57:52 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (MAKEOVERRIDES): Define to be empty.
+
+Fri Mar 12 08:32:11 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * section.c (bfd_set_section_contents): whitespace
+ * seclet.c (seclet_dump_seclet): Don't try and fill sections with
+ no contents.
+
+Thu Mar 11 19:26:15 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * hosts/go32.h: don't define POSIX_UTIME
+
+Tue Mar 9 10:52:01 1993 Fred Fish (fnf@cygnus.com)
+
+ * elf32.c (elf_object_p): Use ELF_ARCH stored in xvec to match
+ against machine architecture stored in the ELF header, to resolve
+ ambiguities.
+ * elf32.c (bfd_section_from_shdr): Bfd_make_section can return
+ NULL, so only use results when non-NULL.
+ * targets.c (elf32_m68k_vec, elf32_i860_vec): Add extern decls
+ and add to vector of targets.
+
+Mon Mar 8 15:13:44 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_set_symbol_info): Encapsulated STABS symbols
+ are always just debugging symbols.
+
+ * coff-mips.c (ecoff_[gs]et_sym_index): Moved macros from here...
+ libecoff.h (ecoff_[gs]et_sym_index): ...to here.
+
+Mon Mar 8 14:55:13 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hppa.c (_PA_RISC_ID): Defined if not already defined (e.g., for
+ hpux 7). Patch from friedman@gnu.ai.mit.edu.
+ (hppa_object_p): Only check for DL_MAGIC and SHL_MAGIC if they're
+ defined, which they aren't in hpux 7.0.
+
+ * aix386-core.c: Include uinfo.h and coredump.h. Patch from Minh
+ Tran-Le, tranle@intellicorp.com.
+
+Fri Mar 5 14:54:21 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_generic_reloc): If the addend is non-zero, go
+ ahead and do the relocation.
+ (ecoff_refhi_reloc): Don't to the relocation here, just remember
+ what needs to be done.
+ (ecoff_reflo_reloc): Do the REFHI relocation here.
+
+Thu Mar 4 14:44:01 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_bfd_reloc_type_lookup): New function.
+ (ecoff_write_object_contents): Added BFD_ASSERT calls to ensure
+ relocs are reasonable.
+ * coff-msym.c: Eliminated uses of DEFUN.
+ (ecoff_swap_tir_out): New function.
+
+Tue Mar 2 17:52:58 1993 Fred Fish (fnf@cygnus.com)
+
+ (Ultrix 2.2 support from Michael Rendell <michael@mercury.cs.mun.ca>)
+ * configure.host (vax-*-ultrix2*): Add triplet.
+ * hosts/vaxult2.h: New file.
+ * config/vaxult2.mh: New file.
+
+ * aoutx.h (string.h): Include for strchr and friends.
+ * archive.c (string.h): Include for memchr and friends.
+ * elf32.c (string.h): Include for strrchr and friends.
+
+Sat Feb 27 00:44:24 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * aoutf1.c (sunos4_reloc_type_lookup): Unused; deleted.
+ (MY_set_sizes): Use sunos4_set_sizes.
+
+ * elf32.c: Renamed from elf.c. Several CPU-specific functions
+ deleted, as well as elf-big and elf-little targets.
+ * libelf.h: New file.
+ * elf32-sparc.c, elf32-i386.c, elf32-i860.c, elf32-m68k.c: New
+ files, new targets.
+ * Makefile.in, config/*-elf.mt, targets.c: Adjusted.
+
+ * i386linux.c (TARGETNAME): Use hyphens instead of parentheses.
+
+ * coffcode.h (coff_compute_section_file_positions): Don't need
+ variable "old_sofar" if compiling for i960.
+
+ * reloc.c (bfd_default_reloc_type_lookup): First argument is now a
+ bfd pointer.
+ * libbfd.h: Updated.
+
+ * ieee.c (exten, envi): "static" belongs first in declaration.
+
+Fri Feb 26 17:37:34 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * srec.c: add support for symbolsrec, srecords with symbols in
+ them.
+
+Thu Feb 25 11:43:30 1993 John Gilmore (gnu@cacophony.cygnus.com)
+
+ * ieee.c: cast all arguments of ieee_write_byte to bfd_byte
+ to avoid lint complaints.
+
+Thu Feb 25 02:15:52 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf.c (elf_write_object_contents): Section ".shstrtab" should be
+ type SHT_STRTAB. Don't alter file offset for section 0.
+ (reloc_type_names): Now an array instead of a macro. Still inside
+ "#if 0", since it's used only in debugging code also in "#if 0".
+ (struct elf_reloc_map_elt, struct elf_reloc_map): New types.
+ (sort_reloc_map): New function.
+ (sparc_reloc_map): New variable.
+ (elf_bfd_reloc_type_lookup): New function.
+
+Tue Feb 23 12:17:16 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd-in.h (JUMP_TABLE): Added bfd_reloc_type_lookup and
+ bfd_make_debug_symbol; they were already in the target structure.
+ * Adjusted all uses of JUMP_TABLE.
+ * coffgen.c, libcoff-in.h (coff_bfd_make_debug_symbol): Renamed
+ from coff_make_debug_symbol.
+ * libcoff.h: Updated accordingly.
+
+ * Minor cleanups provoked by gcc warnings:
+ * aoutx.h (NAME(aout, reloc_type_lookup)),
+ cpu-h8300.c (local_bfd_reloc_type_lookup),
+ cpu-z8k.c (local_bfd_reloc_type_lookup): Added default case to
+ switches.
+ * archive.c (do_slurp_bsd_armap, do_slurp_coff_armap),
+ ieee.c (ieee_slurp_section_data),
+ elf.c (elf_make_sections, elf_fake_sections,
+ elf_compute_section_file_positions, elf_write_object_contents):
+ Removed unused variables.
+ * archures.c: Removed /* from within comment.
+ * bout.c (b_out_squirt_out_relocs): Initialize r_extern.
+ * oasys.c (oasys_write_data): Initialize i.
+
+Mon Feb 22 18:40:06 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * libcoff.h (obj_raw_syment_coun): New macro.
+ * coffgen.c (coff_get_normalized_symtab): Initialize
+ raw_syment_count.
+ * coffgen.c (coff_find_nearest_line): Numerous little fixes.
+
+Mon Feb 22 15:03:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (ecoff_set_symbol_info): stBlock symbols are always
+ debugging symbols.
+ (ecoff_get_debug): Offset the fdr adr by the adr of the first pdr,
+ for compatibility with tools from MIPS.
+
+ * config/bigmips.mt: New file; default vector is ecoff_big_vec.
+ * config/irix3.mt, config/irix4.mt: Removed.
+ * configure.in (mips-*-ecoff): New target; uses bigmips.mt.
+ (mips-sgi-*, mips-big-*): Use bigmips rather than irix3.
+
+Wed Feb 17 23:40:41 1993 John Gilmore (gnu@cygnus.com)
+
+ * hosts/hp300bsd.h: Add gross hack to determine whether we
+ are running on BSD 4.3 or BSD 4.4, and use appropriate include
+ files (and set other parameters) to match.
+
+Wed Feb 17 12:28:13 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * trad-core.c (trad_unix_make_empty_symbol): wrap PARAMS around an
+ ansi definition which otherwise confuses non-ansi compilers.
+
+ * aout-adobe.c (aout_adobe_object_p): eliminate a warning from vax
+ ultrix cc by forward declaring getenv as is done in
+ bfd_find_target.
+
+Tue Feb 16 17:56:58 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * elf.c (elf_info_to_howto): cast an enum into unsigned char
+ avoiding a fatal error in vax ultrix 4.2 cc.
+
+Tue Feb 16 00:44:54 1993 John Gilmore (gnu@cygnus.com)
+
+ * bfd-in.h, VERSION: Roll to version 2.1.
+
+Mon Feb 15 20:43:51 1993 John Gilmore (gnu@cygnus.com)
+
+ * oasys.c (oasys_write_object_contents): Lint.
+ * srec.c: Whitespace cleanup.
+
+Fri Feb 12 14:23:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffgen.c (coff_print_symbol): Print correct tagndx value;
+ cleaned up output formatting a bit.
+
+Fri Feb 12 08:28:56 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coffcode.h (coff_set_arch_mach_hook): *FIXME* the H8/300 is always
+ relaxable. Should be moved somewhere else.
+
+Thu Feb 11 14:09:42 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * aout-mipsbsd.c: Eliminated uses of DEFUN.
+ (aout_mips_*_vec): Added seclet_link element.
+
+ * Makefile.in (BFD_BACKENDS, CFILES, aout-mipsbsd.o): Added
+ support for aout-mipsbsd target.
+
+ * bout.c (get_value): Don't truncate 32-bit addend to 16 bits.
+
+Fri Feb 5 08:08:43 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * cpu-h8500.c (scan_mach): return false if it's not an H8/500
+
+Thu Feb 4 12:52:40 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Add support for the H8/500
+
+ * coff-h8500.c, cpu-h8500.c, archures.c, coffcode.h, targets.c
+
+Thu Feb 4 12:35:02 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * libecoff.h: New file. Defines ECOFF backend data for gdb.
+ * coff-mips.c: Now includes libecoff.h.
+ (ecoff_data_type): Moved to libecoff.h.
+ (ecoff_slurp_symbolic_info): Made globally visible so that gdb can
+ call it. If there is ever another ECOFF target, this and the
+ swapping functions should be accessed via an ECOFF specific target
+ vector.
+ * Makefile.in (coff-mips.o): Depends on libecoff.h.
+
+Wed Feb 3 09:14:36 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h: Removed MIPS specific information, since coff-mips.c
+ no longer includes this file.
+
+ * coff-msym.c (ecoff_swap_fdr_in, ecoff_swap_ext_in): Set reserved
+ bits to 0 to make comparison test useful.
+
+ * config/irix3.mh, config/irix4.mh (HDEFINES): Set to -G 4 to
+ avoid overflowing GP accessible sections in binutils/objdump.
+
+Tue Feb 2 15:36:55 1993 Per Bothner (bothner@cygnus.com)
+
+ * aoutx.h (NAME(aout,slurp_symbol_table)): Made symbol
+ reading more robust: Fail if string index is out of string
+ table range.
+
+Tue Feb 2 11:43:25 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * bout.c (b_out_get_relocated_section_contents, cases PCREL24 and
+ PCREL13): Don't take dst_address into account; the input file has
+ already taken care of that.
+
+Tue Feb 2 11:41:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c: Completed support for linker and binutils.
+
+Mon Feb 1 14:45:38 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * bout.c (b_out_get_relocated_section_contents, case ABS32): Keep
+ original addend from section contents.
+
+Thu Jan 28 21:01:37 1993 John Gilmore (gnu@cygnus.com)
+
+ Fix minor bugs reported by Carl Greco, <cgreco@parrot.creighton.edu>:
+ * hosts/delta88.h (strtol): Fix prototype.
+ * config/m88k-coff.mt (SELECT_ARCHITECTURES): Fix name.
+
+Wed Jan 27 17:16:51 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf.c: Get rid of "#ifdef sparc".
+ (RELOC_TYPE_NAMES): Never used (currently), so don't include it.
+ (elf_sparc_howto_table): Renamed from elf_howto_table, and always
+ used.
+ (elf_info_to_howto): Use runtime conditionals on CPU type, not
+ compile type conditionals on host CPU.
+ (elf_little_vec, elf_big_vec): Use bfd_default_reloc_type_lookup,
+ not null pointer.
+ (reloc_type, RELOC_TYPE_NAMES): Include i386 values.
+
+Tue Jan 26 11:43:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * section.c (SEC_IS_COMMON): New section flag, needed for MIPS
+ ECOFF which has two common sections.
+ (bfd_com_section): Set SEC_IS_COMMON flag.
+ * bfd-in.h (bfd_is_com_section): New macro to test SEC_IS_COMMON.
+ * aoutx.h, archive.c, bout.c, coff-a29k.c, coff-m88k.c,
+ coff-mips.c, coffgen.c, ieee.c, oasys.c, reloc.c, syms.: Use
+ bfd_is_com_section macro rather than checking for equality to
+ bfd_com_section.
+
+Mon Jan 25 15:27:36 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h (_bfd_coff_mkobject_hook): Pass aouthdr argument.
+ (coff_mkobject_hook): Accept aouthdr argument.
+ * coffgen.c (coff_real_object_p): Pass aouthdr to mkobject_hook.
+ Handle NULL aouthdr argument.
+ (coff_object_p): If there is no aouthdr, pass it as NULL to
+ coff_real_object_p.
+ * libcoff.h: Rebuilt for mkobject_hook changes.
+
+ * coffswap.h (coff_swap_aouthdr_in, coff_swap_aouthdr_in): Swap
+ additional MIPS ECOFF fields.
+
+Sat Jan 23 18:36:20 PST 1993 Ralph Campbell (ralphc@pyramid.com)
+
+ * configure.host: added mips-dec-bsd*
+ * configure.in: added mips-dec-bsd*
+ * aout-mipsbsd.c: new file for mips-dec-bsd*
+ * aout-target.h: don't define '' if 'MY_BFD_TARGET' is defined.
+ * aoutx.h: added mips support.
+ * archures.c: added mips support to bfd_default_scan().
+ * cpu-mips.c: added support for R4000 (untested).
+ * libaout.h: added MIPS1 & MIPS2 magic numbers.
+ * reloc.c: fix typo's in comments. Added BFD_RELOC entries which I
+ hope will make it into include/bfd.h.
+ * targets.c: added aout_mips_*_vec.
+
+Wed Jan 20 17:15:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/decstation.mt: Set DEFAULT_VECTOR to ecoff_little_vec.
+
+Tue Jan 19 09:06:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd-in.h (bfd_asymbol_value): Add needed parentheses.
+
+ * libcoff-in.h: Update prototype for coff_count_linenumbers.
+
+Fri Jan 15 18:13:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-msym.c (ecoff_swap_hdr_out, ecoff_swap_fdr_out,
+ ecoff_swap_pdr_out, ecoff_swap_sym_out, ecoff_swap_ext_out,
+ ecoff_swap_rndx_out, ecoff_swap_rfd_out, ecoff_swap_opt_in,
+ ecoff_swap_opt_out, ecoff_swap_dnr_in, ecoff_swap_dnr_out): New
+ functions.
+ * coffswap.h: If NO_COFF_RELOCS is defined, don't define
+ bfd_swap_reloc_in or coff_swap_reloc_out.
+ * coff-mips.c: Added code to link and write out symbolic debugging
+ information, and to swap relocs in and out.
+
+Thu Jan 14 15:51:58 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * libcoff.h, coffgen.c (coff_count_linenumbers), coffcode.h
+ (coff_write_object_contents): coff_count_linenumbers returns the
+ number of line number records it found.
+
+ * coffgen.c (coff_write_linenumbers): only write out line numbers
+ in the section they belong to.
+
+Mon Jan 11 18:32:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * targets.c (bfd_target): Added relocateable argument to
+ _bfd_get_relocated_section_contents. Added _bfd_seclet_link
+ target vector for linker use.
+ * bfd.c (bfd_seclet_link): New macro.
+ * bfd-in.h (JUMP_TABLE): Added _bfd_seclet_link.
+ * seclet.c (rel, seclet_dump_seclet): Added relocateable argument
+ and boolean return value. Made static.
+ (bfd_generic_seclet_link): Renamed from seclet_dump. Added
+ relocateable argument.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Added
+ relocateable argument (if relocateable, saves relocs).
+ * bout.c (b_out_get_relocated_section_contents),
+ reloc16.c (bfd_coff_reloc16_get_relocated_section_contents): Added
+ relocateable argument (if relocateable, just calls
+ bfd_generic_get_relocated_section_contents).
+ * libcoff-in.h (bfd_coff_reloc16_get_value): Added relocateable
+ argument to prototype.
+ * All targets: Set new _bfd_seclet_link vector to
+ bfd_generic_seclet_link.
+
+Sat Jan 9 21:29:32 1993 Stu Grossman (grossman at cygnus.com)
+
+ * coffgen.c: #include seclet.h.
+
+Sat Jan 9 19:48:14 1993 Stu Grossman (grossman at cygnus.com)
+
+ * hppa.c (hppa_object_setup): Get rid of all knowledge of stabs
+ debug info. Setup info about linker symbols only, and use
+ standard bfd fields to hold the info.
+ * (hppa_object_p): Remove unneeded decls.
+ * (hppa_new_section_hook): Get rid of most of this.
+ * libhppa.h (struct hppadata): Remove ten pounds of useless ugly
+ fat. Remove all knowledge of stabs, remove redundant knowledge of
+ linker symbols.
+ * Remove macros for accessing fields which are now gone.
+
+Fri Jan 8 15:20:00 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coffcode.h (sec_to_styp_flags): allow SEC_NEVER_LOAD to turn on
+ STYP_NOLOAD bit.
+ * coff-z8k.c: delete unused reloc functions
+
+Fri Jan 8 15:47:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.c (struct _bfd): Added ecoff_tdata to tdata union.
+ * targets.c (enum target_flavour): Added bfd_target_ecoff_flavour.
+ * coff-msym.c: Use DEFUN for function definitons.
+ * coff-mips.c: Added code to read and print symbols, and to find
+ line numbers.
+
+ * coffcode.h: Moved many generic functions into coffgen.c. Moved
+ swapping functions into coffswap.h for ECOFF use. Moved
+ relocation functions, only used by h8300 and z8k, into reloc16.c.
+ Added hooks for coffgen.c functions to backend data structure, and
+ added hook functions. Still more could be done.
+ * coffswap.h: New file to hold COFF swapping routines.
+ * coffgen.c: New file to hold generic COFF functions.
+ * reloc16.c: New file to hold h8300 and z8k specific relocation
+ functions.
+ * libcoff-in.h: Added declarations for functions in coffgen.c.
+ * libcoff.h: Rebuilt to incorporate changes.
+ * coff-h8300.c: Function name changes.
+ * coff-z8k.c: Function name changes. Use coff_reloc16_extra_cases
+ hook rather than defining EXTRA_CASES.
+ * Makefile.in: Build new files coffgen and reloc16. Added
+ dependencies of coff-*.o on coffswap.h and seclet.h.
+
+Thu Jan 7 16:16:26 1993 Per Bothner (bothner@cygnus.com)
+
+ * ieee.c (ieee_slurp_sections): Add cast to avoid warning
+ about discarding const.
+
+Wed Jan 6 00:16:49 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * archive.c, seclet.c, elf.c use bfd_xmalloc instead of malloc
+
+Tue Jan 5 09:35:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in (post-target): If --with-minimal-bfd is specified,
+ set MINIMIZE=1.
+
+Mon Jan 4 07:20:01 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * srec.c (srec_write_records): one of my boards wants a CR between
+ records.
+
+Wed Dec 30 12:46:30 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * archive.c (do_slurp_coff_armap): set symdef_count correctly
+ (it broke a couple of weeks ago).
+
+Tue Dec 29 21:41:05 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * elf.c (bfd_elf_find_section): Switch back to "struct ..." for
+ return type, so libbfd.h doesn't reference undefined typedefnames.
+
+Tue Dec 29 13:54:35 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h (coff_real_object_p): use name I386AIXMAGIC rather
+ than I386SVMAGIC.
+ (coff_pointerize_aux): don't pointerize a negative tagndx
+ (sometimes generated by SCO 3.2v4 cc).
+
+ * bout.c (calljx_callback, callj_callback,
+ b_out_get_relocated_section_contents): warn if relocating against
+ an undefined symbol.
+
+Mon Dec 28 14:30:55 1992 Stu Grossman (grossman at cygnus.com)
+
+ * hppa.c: Get rid of DEFUN, use more conventional prolog stuff.
+ Make a bunch more routines be static.
+ * hppa.c (fill_spaces): Get rid of this, replace with much better
+ written setup_sections().
+ * (setup_sections): New routine to create BFD sections for each
+ space and subspace in SOM files.
+ * (hppa_object_setup): Use BFD sections created by
+ setup_sections() to locate GDB symbol table info.
+ * (make_unique_section): New routine to create a BFD section. It
+ ensures that the given name is unique, and will generate a unique
+ one if necessary.
+ * (hppa_object_p): Become much more paranoid about file header.
+ * (make_bfd_asection): Call bfd_make_section to do the dirty
+ work. Simplify code somewhat.
+ * (hppa_core_file_p): Use proper name for stack section.
+ * libhppa.h: Remove millicode_start, millicode_end decls.
+
+Mon Dec 28 11:03:22 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (coff-we32k.o, coff-z8k.o): Note dependencies.
+
+ * reloc.c (bfd_perform_relocation): For normal 2- or 4-byte
+ relocs, don't bother doing the adjustment if the value to add is
+ zero.
+
+Sun Dec 27 17:45:05 1992 Fred Fish (fnf@cygnus.com)
+
+ * bfd.c (bfd_get_size): New function that gets an upper bound
+ on the possible size of any object in a bfd.
+ * elf.c (bfd_elf_find_section, elf_get_str_section,
+ elf_get_symtab_upper_bound): Rewrite to avoid NULL pointer
+ dereferences.
+ * elf.c (elf_big_vec, elf_little_vec): Document last three
+ members initialized to NULL.
+
+Thu Dec 24 17:49:09 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * hppa.c: change a 'const' to 'CONST', or else HP C compiler dies
+
+Mon Dec 21 16:33:34 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * hosts/std-host.h: New file. Attempt at a generic/default
+ set of definitions, to discourage porting to new hosts by copying.
+ * hosts/news.h: Removed.
+ * hosts/sparc.h: Use std-host.h.
+ * bfd-in.h: New macros bfd_asymbol_bfd and bfd_asymbol_flavour;
+ perhaps we can later remove the the_bfd field from each symbol.
+ * syms.c (struct symbol_cache_entry): Remove unused field
+ app_data. Add comment noting that the_bfd is almost redundant,
+ but not quite.
+ * aoutx.h, coff-a29k.c, coff-i386.c, coff-i960.c, coffcode.h:
+ Use new macros bfd_asymbol_bfd and bfd_asymbol_flavour.
+ * hppa.c (fill_spaces): Make slightly more rebust.
+ * configure.in: Allow std-host as the "default" host.
+
+Mon Dec 21 17:24:13 1992 Stu Grossman (grossman at cygnus.com)
+
+ * bfd.c: Add struct hppa_core_data to tdata union.
+ * hppa.c: Conditionalize on HOST_HPPAHPUX instead of hp9000s800.
+ Get rid of HPPA/BSD specific code. That will go somewhere else
+ someday.
+ * (fill_spaces): Don't spin forever and die if you don't find
+ $MILLICODE$ subspace.
+ * (hppa_object_p): Make sure that we have a real honest-to-cthulu
+ exec file!
+ * (hppa_core_file_failing_signal, hppa_core_file_failing_command):
+ Make these work for HPUX.
+ * (make_bfd_asection): New routine to make section creation a
+ little easier.
+ * (hppa_core_file_p): Completely rewrite, leave out bugs.
+ * libhppa.h: #include the right system files. Redefine all of
+ the structs/macros for hacking core files to use more sensible
+ HPUX core file structures.
+ * targets.c (target_vector): Conditionalize hppa_vec on
+ HOST_HPPAHPUX, not hp9000s800.
+ * hosts/hppahpux.h: #include stdlib.h to get correct decls for
+ malloc and realloc. #define HOST_HPPAHPUX.
+
+Mon Dec 21 12:40:10 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Patches from Minh Tran-le <mtranle@paris.intellicorp.com>.
+ * configure.in (i386-*-isc*, i386-*-aix*): New targets.
+ * configure.host (i386-*-isc*, i386-*-aix*): New hosts.
+ * hosts/i386isc.h, config/i386isc.mh: New files for Interactive
+ Unix.
+ * hosts/i386aix.h, config/i386aix.mh: New files for AIX on PS/2.
+ * aix386-core.c: New file for handling core files on AIX on PS/2.
+ * targets.c: if AIX386_CORE, use aix386_core_vec.
+ * coffcode.h (coff_real_object_p): check for I386SVMAGIC as well
+ as I386MAGIC.
+
+Fri Dec 18 10:20:27 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * aoutf1.h (sunos4_write_object_contents): set flags to 0, fixing
+ 1927.
+
+Thu Dec 17 19:35:32 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added dvi target
+
+Thu Dec 17 00:36:24 1992 John Gilmore (gnu@cygnus.com)
+
+ * bfd.c: Use right name for tekhex tdata struct.
+ * tekhex.c: Insert leading_char (0) into bfd_target struct. Style.
+ * libcoff.h: Updated to get spacing change from coffcode.h.
+ * trad-core.c: leading_char is 0 (no symbols!), not '_'.
+
+Tue Dec 15 15:40:30 1992 Per Bothner (bothner@cygnus.com)
+
+ * archive.c (do_slurp_bsd_armap, do_slurp_coff_armap): New
+ functions, with the "guts" of the old bfd_slurp_bsd_armap
+ and bfd_slurp_coff_armap, but assuming we've already checked
+ if the armap is present or not.
+ Also, rewrite a bit to avoid keeping around obstack data
+ that we don't need.
+ * archive.c (snarf_ar_header, _bfd_slurp_extended_name_table):
+ Various fixes to correctly handle COFF_style archives names.
+ (Note that because these have a trailing '/', the names can
+ have embedded spaces.)
+ * archive.c (bfd_slurp_armap): New function, replaces old
+ bfd_slurp_bsd_armap and bfd_slurp_coff_armap. Recognizes
+ _either_ format, and calls do_slurp_bsd_armap or
+ do_slurp_coff_armap if either form of map is seen.
+ * libbfd-in.h: Changed bfd_slurp_bsd_armap and
+ bfd_slurp_coff_armap into macro synonyms for bfd_slurp_armap.
+ * elf.c (elf_slurp_armap, elf_write_armap): Fix.
+ * Makefile.in (AR_FLAGS): Use rc instead of non-standard qc.
+
+Mon Dec 14 17:08:08 1992 Stu Grossman (grossman at cygnus.com)
+
+ * hppa.c: #include "sysdep.h", not <sysdep.h>.
+ * libhppa.h: Make millicode_start and millicode_end be unsigned
+ int to be same type as CORE_ADDR in GDB. Why are these here?
+
+Sat Dec 12 15:54:36 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-i386.c (CALC_ADDEND): if reloc is PC relative, add the
+ vaddr of the section to the addend.
+ * targets.c: if MINIMIZE is 1, and SCO_CORE is defined, add
+ SCO_CORE to SELECT_VECS.
+ (target_vector): add sco_core_vec.
+ * sco-core.c (sco_core_vec): add leading underscore initializer.
+ * configure.in (i[34]86-*-sco*): use target i386-sco.
+ * config/i386-sco.mt: new file; define SCO_CORE.
+
+Thu Dec 10 02:13:15 1992 John Gilmore (gnu@cygnus.com)
+
+ * aout-adobe.c (aout_adobe_object_p): Fix !strcmp thinko.
+
+Fri Dec 4 14:02:49 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * coffcode.h (bfd_coff_std_swap_table): Now static and const.
+
+Thu Dec 3 16:54:58 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hosts/i386linux.h: Include unistd.h.
+
+ * aoutx.h (print_symbol): aout_stab_name returns a constant
+ string.
+ * libaout.h (aout_stab_name): Fix prototype.
+ * stab-syms.c (aout_stab_names): Array is now const.
+ (aout_stab_name): Return value is now pointer to const.
+
+ * aoutx.h, archive.c, archures.c, coffcode.h, ctor.c, reloc.c,
+ syms.c: Doc fixes.
+
+ * syms.c (asymbol): Added new field "app_data", for data
+ particular to the application. Some of the linker flags ought to
+ get moved to this field someday.
+
+ * archures.c (bfd_default_scan): Recognize a few more numbers:
+ 80486, 80960, and 960.
+
+ * bfd-in.h (COFF_SWAP_TABLE): New is just address of
+ bfd_coff_std_swap_table, cast to PTR.
+ * bfd.c (bfd_coff_swap_*): Deleted macros.
+ * targets.c (struct bfd_target): Deleted COFF-specific swapping
+ routine pointers.
+ * coffcode.h (type bfd_coff_backend_data): New structure type,
+ contains pointers to the COFF-specific swapping routines.
+ (bfd_coff_std_swap_table): New data structure, to be used when
+ NO_COFF_SYMBOLS and NO_COFF_LINENOS are not defined.
+ (bfd_coff_swap_*): New macros.
+ * coff-mips.c (mips_coff_swap_table): New data structure.
+ (ecoff_big_vec): Use it.
+ * All COFF targets: Moved COFF_SWAP_TABLE to target-specific data.
+ * All other targets: Deleted coff-specific vector entries.
+
+ * trad-core.c: Fixed some `PARAMS' uses that were missing
+ parentheses.
+
+Sun Nov 29 08:37:13 1992 Fred Fish (fnf@cygnus.com)
+
+ * aoutx.h (some_aout_object_p): Protect arg prototype in
+ callback_to_real_object_p with PARAMS macro for non-ANSI compilers.
+
+Sat Nov 28 04:01:21 1992 John Gilmore (gnu@cygnus.com)
+
+ * aout-target.h, aoutf1.h, trad-core.c, coffcode.h, libaout.h,
+ libbfd-in.h, bfd-in.h: Eliminate all PROTO calls, replace with
+ PARAMS for readability.
+
+ * aoutx.h: Add type to callback parameter.
+ * coff-mips.c: Don't call trad-core.h, not needed.
+ * trad-core.c: Incorporate trad-core.h declarations. Fix comments.
+ * trad-core.h: Eliminate, unused.
+
+Wed Nov 18 13:16:17 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * format.c (bfd_check_format): if default target isn't found
+ then look through the entire list rather than return early.
+
+Mon Nov 16 14:33:03 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/i960-coff.mt: reorder vec to match bfd_check_format (from Per)
+
+Thu Nov 12 17:01:41 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: pass down prefix and exec_prefix in FLAGS_TO_PASS
+
+Thu Nov 12 09:46:47 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-z8k.c: checkpoint, more addressing modes handled
+ * coffcode.h (get_value): don't truncate reloc->addend field, it's
+ a long now.
+
+Wed Nov 11 23:57:55 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ * we32k.mt (TDEFAULTS): Use we32kcoff_vec, not i386coff_vec.
+
+Tue Nov 10 14:04:38 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: minor tweaks to make $(CC) command lines more consistent
+
+Mon Nov 9 23:58:17 1992 John Gilmore (gnu@cygnus.com)
+
+ * opncls.c (bfd_fdopenr, bfd_close): Add doc about cacheing
+ and about when file descriptors are closed.
+
+Sat Nov 7 00:42:20 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * bout.c (b_out_squirt_out_relocs): Make sure alignment relocs get
+ written out correctly.
+
+Thu Nov 5 15:34:19 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * section.c: New section bit SEC_SHARED_LIBRARY.
+ coffcode.h (styp_to_sec_flags): if STYP_NOLOAD && (STYP_TEXT ||
+ STYP_DATA), set SEC_SHARED_LIBRARY. This seems to be correct for
+ i386-sysv.
+
+Thu Nov 5 04:43:09 1992 John Gilmore (gnu@cygnus.com)
+
+ * target.c (struct bfd_target): Eliminate the SDEF and SDEF_FMT
+ macros; use PARAMS to declare the function pointers involved.
+
+ * bfd-in.h, bfd.c, libbfd.h, reloc.c, seclet.h, section.c,
+ targets.c: Rename struct bfd_seclet_struct to struct bfd_seclet.
+
+Thu Nov 5 02:59:09 1992 John Gilmore (gnu@cygnus.com)
+
+ Cleanup: Replace all uses of EXFUN in the BFD sources, with PARAMS.
+
+ * archures.c, reloc.c, section.c, tekhex.c: Use PARAMS in
+ declaring pointers to functions.
+ * cache.c, elf.c: Move static function decls to top, use PARAMS.
+ * seclet.h: Declare external function with PARAMS.
+
+ * doc/chew.c (exfunstuff): Eliminate.
+ (paramstuff): Replace exfunstuff with function to generate PARAMS.
+ * doc/proto.str: Use paramstuff rather than exfunstuff.
+
+ * libbfd.h: Update, based on changes in source code and chew.
+
+Wed Nov 4 22:47:29 1992 John Gilmore (gnu@cygnus.com)
+
+ * libieee.h: Add FIXME about removing limit on number of sections.
+ * bfd-in.h: Improve comments to make it clear that bfd.h is
+ the wrong place to edit this file.
+ * Makefile.in (install): Install ansidecl.h and obstack.h in the
+ same places where we install bfd.h.
+
+Wed Nov 4 13:40:23 1992 Sean Eric Fagan (sef@cygnus.com)
+
+ * coffcode.h (coff_swap_aux_out, coff_swap_aux_in): check for
+ symbol type before blindly modifying the auxent. Specifically,
+ only modify the endndx fields for types that need it, and don't
+ set the array information for non-arrays.
+
+Wed Nov 4 09:30:50 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * aoutx.h (some_aout_object_p): Section list should be set up
+ correctly anyways; don't have to set up "next" pointers manually.
+
+Mon Nov 2 12:36:14 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/delta88.mh, config/hp300.mh, config/hppahpux.mh,
+ config/i386v.mh: removed -DUSG from HDEFINES.
+ hosts/delta88.h, hosts/hp300.h, hosts/hppahpux.h, hosts/i386v.h:
+ defined USE_UTIME.
+ hosts/i386v.h: don't define POSIX_UTIME.
+
+Fri Oct 30 16:13:52 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ieee.c (ieee_slurp_sections): make a private copy of the
+ section's name before truncating it.
+
+Thu Oct 29 08:30:50 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * hppa.c: add symbol_leading_char entry in transfer vec
+
+,Wed Oct 28 16:11:57 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ieee.c (get_symbol): can now cope when two symbols of a
+ different class, but the same index number occur consecutively.
+ (get_section_entry): nicer name for sections being forward
+ referenced. (ieee_archive_p): don't free the filename string,
+ since it was never malloced.
+
+Wed Oct 28 13:42:09 1992 John Gilmore (gnu@cygnus.com)
+
+ * coffcode.h (coff_write_object_contents): Zero timestamp field.
+
+Tue Oct 27 12:24:34 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h (coff_swap_aux_out): set the fcnary info before
+ optionally setting the dimen info, since they are in the same
+ memory locations. Also zero out external auxent.
+ (coff_write_symbol): don't zero external auxent; now done in
+ coff_swap_aux_out.
+
+Fri Oct 23 13:55:35 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Check fclose return value for errors.
+ libbfd.h: bfd_cache_close now returns a boolean.
+ cache.c (bfd_cache_delete): return fclose success value.
+ (bfd_cache_close): return bfd_cache_delete return value.
+ opncls.c (bfd_close, bfd_close_all_done): return result of
+ bfd_cache_close.
+
+Fri Oct 23 10:32:36 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * seclet.c (rel): don't load sections without the SEC_LOAD bit.
+
+Thu Oct 15 10:16:35 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-m68k.c (m68k_howto2type, SELECT_RELOC): new function to
+ work out a coff relocation type from a howto's attributes rather
+ than using the input r_type field. This fixes PR1677 and allows
+ conversion of a.out relocs to coff relocs.
+
+ * coffcode.h (coff_write_relocs): if supplied a relocation
+ relative to an absolute symbol, use the right symbol index.
+
+ * reloc.c (bfd_perform_relocation): do a partial link for coff
+ relocs right.
+
+Fri Oct 23 08:15:56 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * changes to support i386-sysv with shared libraries:
+ * coffcode.h (sec_to_styp_flags): if TWO_DATA_SECS is defined,
+ check for .data2; if _LIB is defined, check for it; map
+ SEC_NEVER_LOAD to STYP_NOLOAD.
+ (styp_to_sec_flags): map STYP_NOLOAD to SEC_NEVER_LOAD.
+ (make_a_section_from_file): if TWO_DATA_SECS, accept .data2.
+ (coff_write_object_contents): force vaddr of .lib to 0; set scnptr
+ if section has contents, not just if it is loadable; if
+ TWO_DATA_SECS, check for .data2
+ (coff_set_section_contents): set vma of .lib section to number of
+ .lib sections.
+ * coff-i386.c: define TWO_DATA_SECS; use a special CALC_ADDEND;
+ don't define coff_write_armap to bsd_write_armap.
+ * hosts/i386v.h: don't include <utime.h>, since it is not provided
+ by SVR3.2.
+
+Thu Oct 22 22:40:20 1992 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * solaris2.h: Get the definition of alloca from alloca.h if we
+ aren't using gcc.
+
+Thu Oct 22 03:07:28 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in (i960-*-{aout,bout}): Support these.
+
+Wed Oct 21 03:46:34 1992 John Gilmore (gnu@cygnus.com)
+
+ * config/a29k-aout.mt (DEFAULT_TARGET): Set to one that exists.
+
+Thu Oct 15 15:05:39 1992 Per Bothner (bothner@cygnus.com)
+
+ * apollo68.h, apollov68.h, hp300.h, i386v.h, irix3.h: Remove
+ no-longer-used definitions of L_SET and L_INCR.
+ * i386linux.h: Tweaks to smooth Linux build.
+
+Thu Oct 15 01:32:22 1992 John Gilmore (gnu@cygnus.com)
+
+ * seclet.h: Add enum tag to bfd_seclet_enum_type.
+
+ * bfd-in.h (file_ptr): Update comments, make FIXME re off_t.
+
+ * aout-adobe.c, aoutf1.h, archive.c, bout.c, coff-rs6000.c,
+ coffcode.h, elf.c, ieee.c, libaout.h, libbfd.c, oasys.c,
+ sco-core.c: Lint: Second argument of bfd_seek is always file_ptr.
+ Third argument is SEEK_SET or SEEK_CUR. Result is always 0 or -1.
+
+ * aout-adobe.c, aoutf1.h, aoutx.h, bout.c coff-m68k.c, coff-z8k.c,
+ coffcode.h, elf.c, libaout.h, libbfd-in.h, srec.c: Lint.
+
+Fri Oct 9 03:46:37 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.host: New file, contains mapping of host configs
+ to host support file names for bfd, binutils, opcodes.
+ * configure.in: Use it.
+ * i386aout.c: Cleanup, dump TARGET_IS_LITTLE_ENDIAN_P.
+ * i386bsd.c: Cleanup, reformat.
+ * config/i386-bsd.mt: Comment changes.
+ * config/i386bsd.mh: New file for core file support.
+ * hosts/i386bsd.h: Merge changes from Peter Schauer.
+ * bout.c (ALIGN): Rename to ALIGNER, since system header files
+ on BSD 4.4 define ALIGN (sigh!).
+
+Thu Oct 8 22:18:10 1992 Mark Eichin (eichin at tweedledumber.cygnus.com)
+
+ * libaout.h (aout_backend_data): added exec_header_not_counted
+ field. For ZMAGIC files only, when text_includes_header is set, by
+ default the length of the exec header is counted in the text
+ section size. For go32, exec header is mapped in but does *not*
+ contribute to the size of section.
+ * aoutx.h (aout_adjust_sizes_and_vmas): if exec_header_not_counted
+ is not set, but ztih is, add the size of the exec header to the
+ recorded size of the text section.
+ * aoutf1.h (sunos4_aout_backend): clear exec_header_not_counted.
+ * i386aout.c (i386aout_backend_data): set exec_header_not_counted.
+ Also set text_includes_header.
+ * aout-target.h (*_backend_data): cleare exec_header_not_counted
+ by default in MY(backend_data).
+
+Thu Oct 8 18:12:49 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * aout-target.h (callback): Don't define this function if it won't be
+ used.
+
+ * aoutx.h (some_aout_object_p): Restore old aout_data value if this
+ type doesn't match. Don't lose if file sections have already been
+ created.
+ (set_arch_mach): Set reloc_entry_size.
+ (slurp_symbol_table): Use bfd_h_get_{16,8} for reaeding symbol data.
+
+ * hosts/i386bsd.h: New file.
+ * configure.in: Recognize i[34]86-*-bsd host.
+
+ * aout-target.h (callback, write_object_contents): Delete unused
+ variables.
+
+ * aoutx.h (reloc_type_lookup): New function.
+ * aout-target.h (MY_reloc_howto_type_lookup): Use it as default.
+ * aoutf1.h (sunos4_reloc_type_lookup): Deleted.
+ (MY_reloc_howto_type_lookup): Don't define it.
+
+ * aoutx.h (adjust_sizes_and_vmas): Don't bother with padding for
+ OMAGIC files.
+ (slurp_symbol_table): Use header byte order, not target byte
+ order, for reading symbol data.
+
+Thu Oct 8 17:33:39 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in: Undo some brain damage in the host section.
+ * configure.in: Reformat the target section, test many configs.
+ * Makefile.in (make): Remove obsolete `make make'.
+ * aoutx.h (some_aout_object_p): Make defines line up.
+
+Thu Oct 8 08:52:48 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Now a bfd knows whether underscores are normally prepended
+ to symbols in its file format.
+
+ * aout-adobe.c, aout-target.h, bout.c, coff-a29k.c, coff-h8300.c,
+ coff-z8k.c: targets set so they have leading underscore
+ * coff-i386.c, coff-i960.c, coff-m68k.c, coff-mips.c, coff-m88k.c,
+ coff-rs6000.c, coff-we32k.c, elf.c, ieee.c, srec.c: targets set
+ without leading underscore flag
+ * targets.c: add symbol leading char to xvec description
+ * bfd-in.h (bfd_get_symbol_leading_char): new macro.
+
+Mon Oct 5 14:32:55 1992 Per Bothner (bothner@cygnus.com)
+
+ * archive.c: Make errno global.
+ * archive.c (_bfd_write_archive_contents): If read fails (and
+ errno!=0) set bfd_error to malformed_archive (since this probably
+ indicates a truncated archive), rather than system_call_error.
+
+Mon Oct 5 03:33:39 1992 Mark Eichin (eichin at tweedledumber.cygnus.com)
+
+ * Makefile.in: added rules for i386bsd.c
+ * i386bsd.c: new file, supporting 386bsd.
+ * configure.in: recognize i386-*-bsd target.
+ * config/i386-bsd.mt: new file - 386bsd target configuration.
+
+Thu Oct 1 17:51:07 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: re-arrange host section to use *-*-* notation,
+ clean up some of the target section as well
+
+ * seclet.c: cast result of bfd_get_relocated_section_contents to
+ avoid compiler warnings
+
+Tue Sep 29 13:24:09 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * coffcode.h (coff_section_symbol): Create section if it doesn't
+ already exist.
+
+ * bout.c: Removed some unused variables.
+
+Tue Sep 29 08:30:21 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Portability fixes from p3:
+ coffcode.h (coff_write_relocs): removed sanity check until it
+ works on all targets (per advice from sac).
+ config/hp9000.mh: new file to define USG.
+ hppa.c: #undef hppa before the JUMP_TABLE.
+ hosts/hppahpux.h: #define NATIVE_HPPAHPUX_COMPILER if not
+ __STDC__.
+ targets.c (bfd_target_list): if NATIVE_HPPAHPUX_COMPILER, make
+ local variable target volatile to avoid mysterious bug in
+ HP9000/700 cc.
+
+Sat Sep 26 03:58:49 1992 John Gilmore (gnu@cygnus.com)
+
+ * config/hppabsd.mh, config.hppahpux.mh: Remove various bogosity.
+ * hosts/hppahpux.h: Remove bcopy and index circumventions.
+
+Fri Sep 25 22:36:52 1992 John Gilmore (gnu@cygnus.com)
+
+ * coff-z8k.c (func_da, func_jr): Lint.
+ * coffcode.h: Use memset rather than bzero.
+ * elf.c: Use memcpy rather than bcopy.
+ * tekhex.c: Use memset rather than bzero.
+
+Fri Sep 25 19:14:48 1992 John Gilmore (gnu@cygnus.com)
+
+ Add Adobe a.out support.
+
+ * aout-adobe.c: New file. So far, only reads a.out.adobe. FIXME.
+ * config/adobe.mt: Add.
+ * configure.in (*-adobe-* target): Add.
+ * targets.c (a_out_adobe_vec): Add.
+ * Makefile.in: add aout-adobe.c.
+
+ * configure.in: Put two dashes in all entries to be matched.
+ Add comments to remind people to do this.
+ Reorder all entries that match manufacturer names, to occur
+ last, so they will only be matched if no more specific match
+ occurs. Remove manufacturers `aout', `bout', `coff', and `elf'.
+
+Fri Sep 25 15:03:22 1992 Brendan Kehoe (brendan@rtl.cygnus.com)
+
+ * elf.c (section_from_elf_index): Return bfd_abs_section, not 0,
+ since we should never have a NULL section.
+ (elf_slurp_symbol_table): If st_shndx doesn't match any of our
+ tests, set the section to bfd_abs_section.
+
+Fri Sep 25 11:11:57 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-z8k.c: getting closer
+ * coffcode.h (coff_get_relocated_section_contents): allow
+ EXTRA_CASES hooks for different arches to provide different reloc
+ types.
+ * seclet.h: #ifndef around it to allow multiple inclusion
+ * srec.c: minor doc fix
+
+Mon Sep 21 14:33:58 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * hosts/hp9000.h, hosts/irix3.h: changes from WRS.
+
+Sun Sep 20 08:48:25 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Use i386-elf for all i386/i486 sysv4 hosts, not
+ just ncr.
+
+Thu Sep 17 06:40:46 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * bout.c (b_out_slurp_reloc_table): Clear howto field before
+ filling in reloc, in case immediately following code doesn't set
+ it.
+
+Fri Sep 11 15:37:06 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * coffcode.h (coff_renumber_symbols): set the last renumbered
+ symbol pointer to NULL, as expected by coff_write_linenumbers.
+ (coff_write_relocs): apparently a non-zero addend is OK for reloc
+ type R_IHCONST used on the 29k.
+
+Thu Sep 10 13:28:24 1992 John Gilmore (gnu@cygnus.com)
+
+ * opncls.c (bfd_fdopenr): Determine whether to fdopen for
+ update, based on how the underlying file was opened. Obsoletes
+ FASCIST_FDOPEN.
+ * hosts/rs6000.h, hosts/tahoe.h, hosts/vaxbsd.h: Remove
+ all FASCIST_FDOPEN config defines.
+
+Tue Sep 8 21:37:58 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * sparc-opc.c: Moved to opcodes library, now that we have one.
+ * Makefile: Don't compile it.
+
+Tue Sep 8 10:10:34 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * aoutx.h: adjust_sizes_and_vmas did not return anything.
+
+Thu Sep 3 19:29:04 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * section.c (bfd_set_section_flags): Remove a sanity check.
+ It is unfortunately broken, and prevents strip from working.
+
+Thu Sep 3 16:14:40 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * sparc-opc.c (condr): Remove extraneous, but harmless, backlash
+ created by last change.
+
+Thu Sep 3 13:52:38 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * reloc.c (reloc_howto_struct): Make size field be unsigned.
+ * bfd-in.h: Bump to version 2.0.
+
+Thu Sep 3 09:05:37 1992 Stu Grossman (grossman at cygnus.com)
+
+ * bout.c, cpu-z8k.c: Use enums when initializing structs to keep
+ braindamaged HP/Apollo compiler happy.
+
+Wed Sep 2 02:53:29 1992 John Gilmore (gnu@cygnus.com)
+
+ * format.c: Fix description of search for matching target.
+ * aoutx.h (some_aout_object_p): Set SEC_CODE and SEC_DATA.
+ * targets.c: Update description of search for matching target.
+ * Makefile.in (do_clean, clean): Fix infant mortality typo.
+ (docdir): Set to ./doc, not ${srcdir}/doc, which has no makefile.
+ (z8k and we32k files): `*.o: *.c': avoid Sun Make bug.
+
+Wed Sep 2 00:26:32 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Added mostlyclean/clean/distclean rules.
+
+Tue Sep 1 13:38:40 1992 Per Bothner (bothner@cygnus.com)
+
+ * targets.c (target_vector): Take out oasys (unless that is
+ the default): Because there is no magic number in archives,
+ there can be annoying target mis-matches.
+
+Mon Aug 31 10:11:37 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * sparc-opc.c: Rigorously updated to match architecture manual.
+
+Mon Aug 31 08:07:58 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * aoutx.h (aout<n>swap_ext_reloc_out), bout.c
+ (b_out_squirt_out_relocs): fix bug 1506 where abs symbols attached
+ to the built-in abs_section were not written out correctly.
+
+Fri Aug 28 16:29:15 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * archive.c (bfd_slurp_bsd_armap): if the symdef_count is too
+ large, assume we're using a swapped byte order and fail with
+ wrong_format rather than dumping core.
+
+Fri Aug 28 15:38:03 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * Renamed opc-sparc.c to sparc-opc.c for systems with short
+ filename constraints.
+ * Makefile.in: Updated to reflect change.
+
+Thu Aug 27 13:05:28 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ Add preliminary support for the we32k:
+
+ * Makefile.in, archures.c, coffocode.h, configure.in, targets.c:
+ Minor edits.
+ * coff-we32k.c, cpu-we32k.c, config/we32k.mt, hosts/we32k.h: New files.
+
+Wed Aug 26 14:20:16 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bout.c: added support for relaxable alignment relocs.
+
+ * seclet.c (rel, seclet_dump_seclet, seclet_dump): get the app to
+ pass down pointer to play area rather than use alloca
+
+ * cpu-z8k.c (compatible): made static to reduce name space
+ polution.
+
+Tue Aug 25 08:39:10 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Add basic support for the z8k:
+
+ * Makefile.in, archures.c, coffcode.h, configure.in, reloc.c,
+ section.c, targets.c,
+
+ * syms.c: move mis-inserted patch.
+
+Fri Aug 14 15:39:29 PDT 1992 Howard Chu (hyc@hanauma.jpl.nasa.gov)
+
+ Documentation fixes:
+ * ctors.c, format.c, section.c, reloc.c: append " -" to item tags.
+ * reloc.c, section.c, syms.c, targets.c: add DOCDD before @node
+ comments.
+ * reloc.c: break out addend item from surrounding text.
+
+ * doc.str (DOCDD): Defined. Adds text to output.
+ (bodytext): Put bulletize before kill_bogus_lines.
+ * chew.c (bulletize): End itemization after a blank line, to
+ prevent following text from being swallowed up in an item.
+
+Mon Aug 24 20:50:22 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: Add sparclite as a target.
+
+Mon Aug 24 12:06:31 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ieee.c (ieee_get_symtab): always null terminate the symbol list,
+ lint.
+
+ * coffcode.h (coff_add_missing_symbols): if symbols don't come
+ from a coff file (csym is null), dont deref them
+
+ * ieee.c (parse_expression): get the answer right when adding an
+ abs+(sec+off), (ieee_generic_stat_arch_elt): call ieee_object_p
+ on elts so that filename is filled in.
+
+Thu Aug 20 19:05:48 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * bout.c (howto_align_table): New set of relocs, with enough
+ data for "objdump -r" to work.
+ (b_out_reloc_type_lookup): Recognize alignment relocs.
+
+Tue Aug 18 12:57:45 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: added FLAGS_TO_PASS, and used it for all recursive
+ invocations of make. Also, always create installation
+ directories.
+
+ * config/apollov68.mh: removed -g from CC definition.
+
+Mon Aug 17 13:40:08 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/decstation.mh (HDEFINES): Specify "-G 4" to avoid
+ overflowing gp-offset range.
+
+Mon Aug 17 11:44:28 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * srec.c (srec_set_section_contents): don't write out sections
+ without the LOAD and ALLOC attributes
+
+Mon Aug 17 11:55:07 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * archures.c, cpu-m68k.c, cpu-sparc.c: Undo 16 June changes.
+ * libaout.h (struct aout_backend_data): New callback "set_sizes".
+ * aout-target.h (callback): Don't set page/seg sizes.
+ (mkobject): Ditto.
+ (set_sizes): New routine.
+ (backend_data): Point to it.
+ * aoutf1.h (sunos4_set_sizes): Heed architecture when setting sizes.
+ (sunos4_aout_backend): Point to it.
+ * aoutx.h (set_arch_mach): Call set_sizes callback.
+
+Fri Aug 14 19:22:18 1992 Per Bothner (bothner@cygnus.com)
+
+ * aout-target.h: Make _bfd_slurp_extended_name_table be
+ the default. Given that we *write* the suckers (for long
+ archive member names), we really ought to be able to read them!
+ * trad-core.c: Don't include <machine/reg.h>. It doesn't
+ seem to be needed, and many machines don't have it.
+
+Thu Aug 13 09:53:39 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-m68k.c (vector): read and write archives in coff format.
+
+Tue Aug 11 12:19:42 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * opc-sparc.c: New file.
+
+Sat Aug 8 23:15:35 1992 Fred Fish (fnf@cygnus.com)
+
+ * bout.c (bfd_reloc_status_type, callj_callback): Cast void*
+ pointers to bfd_byte* before performing arithmetic on them. Such
+ use with bare void* pointers is a gcc extension.
+ * cache.c (bfd_cache_delete): Forward decl with prototype form.
+ * archive (normalize): Add to CONST to match actual usages with
+ CONST.
+
+Mon Aug 3 00:35:29 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Recognize i486 host cpu, and use i386-elf
+ for i486-ncr-sysv4.
+
+Sat Aug 1 13:49:59 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/stratus.mt (CC): Remove definition.
+ * elf.c (bfd_section_from_shdr): Test for the possibility that
+ section_from_elf_index returns NULL and don't dereference it.
+
+Mon Jul 20 02:46:09 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * add hppa_data to bfd tdata (indirectly via sef).
+
+ * config/hppahpux.mh: hpux is -DUSG (patch by sef)
+
+Sat Jul 18 15:50:11 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: error messages to stderr, not stdout
+
+Fri Jul 17 18:32:46 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * bfd.c, cache.c, coff-a29k.c, coff-i386.c, coff-i960.c,
+ coff-m68k.c, coff-m88k.c, demo64.c, libaout.h, libbfd.c,
+ oasys.c, opncls.c, sunos.c, targets.c: removed rcsid's.
+
+Fri Jul 17 17:06:56 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognize hppa* instead of hppa
+
+Thu Jul 16 16:39:25 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-m68k.c: added R_RELLONG_NEG reloc type, and changed
+ RTYPE2HOWTO to cope with same.
+ * reloc.c (bfd_perform_relocation): added support for size of -2
+ (subtract a word reloc type). Updated doc.
+
+Thu Jul 16 16:28:09 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: merged changes from progressive, removed rcsid.
+
+ * archures.c, archive.c, Makefile.dos: removed rcsid.
+
+Thu Jul 16 08:08:25 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd-in.h : add BFD_IS_RELAXABLE flag
+ * bout.c (bout_swap_exec_header_[in_out]): new field in exec
+ header e_relaxable, major hackery in callbacks
+ * libaout.h : add space for a_relaxable.
+ * seclet.c (rel): don't relax empty sections
+
+
+Wed Jul 15 07:57:46 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * section.c (STD_SECTION): add some casts to the initializers for
+ dumb compilers
+
+Tue Jul 14 14:06:28 1992 Stu Grossman (grossman at cygnus.com)
+
+ * rs6000-core.c (rs6000coff_core_p): Greatly simplify expression,
+ and add appropriate casts to keep (picayune) aix-cc happy.
+
+Mon Jul 13 05:06:51 1992 John Gilmore (gnu at cygnus.com)
+
+ * elf.c (elf_slurp_symbol_table): Now 2nd arg is where to write
+ symbol pointers. Punt expensive & useless bfd_realloc. Use
+ malloc for raw symbols, and free it before returning.
+ (bfd_section_from_shdr): Do not slurp symbol table until politely
+ asked. Do not even slurp string tables.
+ (elf_get_symtab_upper_bound): Count 'em without reading them.
+ (elf_get_symtab): This is how to politely ask. Schlurp!
+ This should probably just *become* elf_slurp_symbol_table, FIXME.
+
+Wed Jul 8 16:24:33 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * archive.c (bsd_write_armap): write the timestamp of the
+ archive header to be just a little bit later than the timestamp of
+ the file, otherwise the linker will complain that the index is
+ out of date.
+
+Tue Jul 7 00:23:23 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Add m68k-ericsson-*.
+
+Sat Jul 4 03:29:41 1992 John Gilmore (gnu at cygnus.com)
+
+ * syms.h: Define BSF_FILE, update BSF_SECTION_SYM desc.
+ * elf.c: Remove unconditional debug printf's.
+ (elf_write_object_contents, elf_slurp_symbol_table): Handle
+ BSF_SECTION_SYM <=> STT_SECTION, BSF_FILE <=> STT_FILE.
+ (elf_slurp_symbol_table): Hand out symbols in forward, not
+ reverse order. Simplify duplicate code.
+
+Fri Jul 3 20:23:34 1992 Fred Fish (fnf@cygnus.com)
+
+ * elf.c: Remove "(void)" casts from function calls where the
+ return value is ignored, in accordance with GNU coding standards.
+
+Tue Jun 30 16:49:12 1992 Fred Fish (fnf@cygnus.com)
+
+ * hppa.c: Apply John's standard fix to avoid "empty translation
+ unit" warnings from some ANSI-C compilers.
+
+Thu Jun 25 04:39:25 1992 John Gilmore (gnu at cygnus.com)
+
+ * hosts/solaris2.h: Configure same as sysv4.
+
+Tue Jun 23 21:54:44 1992 Fred Fish (fnf@cygnus.com)
+
+ * libbfd.h, libbfd-in.h (bfd_seek): Make prototype match definition.
+ * reloc.c (bfd_default_reloc_type_lookup): Make cast on return
+ type match actual return type.
+ * elf_print_symbol (section_name): Make CONST.
+
+Mon Jun 22 17:35:24 1992 Per Bothner (bothner@cygnus.com)
+
+ * i386linux.c, hosts/i386linux.h, config/i386-linux.mt:
+ New files, for Linux (a free Unix clone for 386 machines).
+ * Makefile.in, configure.in, targets.c: Update accordingly.
+
+Fri Jun 19 20:23:21 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+ Lints for bfd_reloc_code_type->bfd_reloc_code_real_type, and
+ correct calling of howto special functions and fixes from Raeburn
+ for gas<>bfdness
+ * archures.c: nuke bfd_reloc_code_type
+ * bout.c, cpu-h8300.c, coff-i960.c, coff-m88k.c: special function lint
+ * coffcode.h (styp_to_sec_flags): STYP_INFO is marked as
+ SEC_NEVER_LOAD, various other bfdgas newness
+ * reloc.c->libbfd.h: change protype of bfd_default_reloc_type_lookup
+ * targets.c: change jump table vector to above
+
+
+Fri Jun 19 19:00:45 1992 John Gilmore (gnu at cygnus.com)
+
+ * elf.c (bfd_elf_find_section): Mark as INTERNAL_FUNCTION so
+ its prototype will be included in libbfd.h. Change result type
+ to struct * (rather than equivalent typedef) so it can be used in
+ the prototype, where they typedef won't be known.
+ * libbfd.h: Updated version.
+
+Fri Jun 19 15:21:56 1992 Stu Grossman (grossman at cygnus.com)
+
+ * Makefile.in, archures.c, configure.in, cpu-hppa.c, hppa.c, libhppa.h,
+ targets.c: HPPA merge.
+
+Fri Jun 19 12:21:38 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Separate Solaris2 from SYSV4 on SPARC.
+ * config/solaris2.mh: Kludge around Sun compiler bug.
+
+Wed Jun 17 14:02:46 1992 Stu Grossman (grossman at cygnus.com)
+
+ * libaout.h (aout_backend_data): Change defs of two bitfields to
+ be unsigned chars instead to get around rs6000 compiler problem.
+
+Wed Jun 17 13:55:31 1992 Fred Fish (fnf@cygnus.com)
+
+ * elf.c (bfd_section_from_shdr, elf_slurp_symbol_table):
+ Correct misconception that there can be only one symbol table.
+ Only call elf_slurp_symbol_table on the full symbol table, not
+ the dynamic one which is only a subset of the full one.
+
+Wed Jun 17 15:54:57 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * coffcode.h (coff_compute_section_file_positions): For I960,
+ don't align sections in file.
+
+Tue Jun 16 06:28:21 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * targets.c (struct bfd_target): Added field for target-specific
+ (but not file-specific) data, for distinguishing minor
+ characteristics between (e.g.) a.out formats.
+
+ * section.c (struct sec): New field user_set_vma indicates vma
+ field should be heeded, not assumed to be unset.
+ (STD_SECTION): Initialize that field of standard sections to zero.
+ * bfd-in.h (bfd_set_section_vma): Set user_set_vma to true.
+
+ * coffcode.h (coff_write_relocs): Write out swapped reloc, not
+ pre-swapped version.
+
+ * archures.c (struct bfd_arch_info): Fixed order of comment and
+ field decl. New fields indicate size of page and segment for
+ architecture.
+ * cpu-m68k.c (N): Fill in values.
+ * cpu-sparc.c (arch_info_struct): Ditto.
+
+ * libaout.h (struct aout_backend_data): Various bits of data (not
+ all used currently) with characteristics of a.out implementation.
+ Important field for now is text_includes_header, indicating that
+ the text section starts immediately after the file header, which
+ gets mapped in with it.
+ (struct aout_data): New fields indicate whether vma has been
+ adjusted yet (not yet used), and what magic number will be used in
+ the output file (should go away in favor of vma_adjusted).
+ (WRITE_HEADERS): Code for dealing with section sizes and related
+ header fields replaced with call to adjust_sizes_and_vmas.
+ * aoutx.h (some_aout_object_p): Fill in magic number field.
+ Set WP_TEXT flag for ZMAGIC as well as NMAGIC files.
+ (set_arch_mach): Set page size and segment size once CPU
+ type is known.
+ (adjust_sizes_and_vmas): New function; has much code moved
+ from set_section_contents and WRITE_HEADERS. Sets or adjusts vma
+ and size parameters, as well as many header fields, after deciding
+ on magic number for output file. Checks to ensure that this
+ adjustment has only been done once.
+ (set_section_contents): Call adjust_sizes_and_vmas instead of
+ doing much of the work here.
+
+ * aout-target.h (MY_make_debug_symbol, MY_backend_data): Provide
+ default (null) values of these fields.
+ * aoutf1.h (sunos4_write_object_contents): Don't override a_text
+ value in exec header.
+ (sunos4_aout_backend, MY_backend_data): Define backend data
+ indicating file header is included in text section.
+
+ * aoutf1.h (MY_reloc_howto_type_lookup): Fix typo.
+
+ * hosts/sparc.h (abort, exit): Hide these names if compiling with
+ gcc version 2, to avoid warnings.
+
+Mon Jun 15 12:26:56 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/ncr3000.mh (INSTALL, RANLIB): Don't use /usr/ucb/install,
+ it's broken on ncr 3000's. Use simple "true" for RANLIB.
+
+Sat Jun 13 09:16:43 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * configure.in (m680[01234]0-wrs-*): Fix typo in match pattern.
+
+Fri Jun 12 19:48:34 1992 John Gilmore (gnu at cygnus.com)
+
+ * section.c (STD_SECTION): Remove extra semicolon in declarations.
+ * configure.in: Rewrite target parsing to use simple format.
+ Handle sparc-sun-solaris2 configuration.
+ * aout64.h: Avoid ANSI C brain death warning.
+ * elf.c: Avoid trigraph (???) or /* in comments.
+
+Fri Jun 12 14:51:14 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/sysv4.mh: new file, RANLIB=echo
+
+ * configure.in: handle Solaris2 as -sysv4 or -solaris2
+
+Thu Jun 11 00:52:03 1992 John Gilmore (gnu at cygnus.com)
+
+ * elf.c (elf_obj_tdata): Merge elf_obj_tdata_struct and
+ elf_core_tdata_struct into a single common struct. Core files
+ wouldn't have worked at all without this.
+ (bfd_elf_find_section): New function for GDB's undercover use
+ to find string sections that BFD hides from it.
+ (elf_get_str_section): Avoid multiple alloc&reads for same data;
+ lint.
+ (elf_object_p, elf_core_file_p): Allocate internal file header
+ storage dynamically.
+ * bfd.c (union {...} tdata): Remove elf_core_tdata_struct.
+ * demo64.c: Prevent "empty translation unit" warnings from idiots.
+
+Tue Jun 9 17:15:26 1992 Fred Fish (fnf at cygnus.com)
+
+ * config/{i386v4.mh, ncr3000.mh}: Update RANLIB, add INSTALL.
+
+Sat Jun 6 17:02:51 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Handle Solaris2 as *-sun-sysv4 or as *-sun-sunos5.
+
+Sun May 31 05:45:00 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * configure.in: handle m680[01234]0 as aliases for m68k
+
+Tue May 26 16:50:59 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-a29k.c: do byte relocs correctly
+ * coffcode.h (styp_to_sec_flags): never load INFO sections
+ * seclet.c (rel): don't relocate INFO sections
+
+Wed May 20 08:18:18 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * section.c (bfd_*_symbol, bfd_*_section): Initialize statically.
+ Make the symbols unmodifiable.
+ (bfd_section_init): Deleted.
+ * init.c (bfd_init): Don't call bfd_section_init.
+
+ * section.c (bfd_set_section_contents): Ensure that range to be
+ written is within section boundaries.
+ (bfd_get_section_contents): Likewise. Don't bother dispatching if
+ size is zero.
+
+ * libbfd.c (bfd_xmalloc): Text of error message should be const.
+
+ * coff-i960.c (howto_table): Deleted.
+ (howto_rellong, howto_iprmed, howto_optcall): New vars;
+ interesting entries from old howto_table.
+ (RTYPE2HOWTO): Adjusted to use switch.
+ (coff_i960_reloc_type_lookup): New function.
+
+ * coffcode.h (coff_new_section_hook): Allocate storage for aux
+ records for section symbol.
+ (make_abs_section): Unused; deleted.
+ (renumber_symbols): Re-order symbols so undefined symbols come
+ last, as COFF format desires.
+ (coff_write_symbol): Put C_FILE symbols in debug section always.
+ (coff_section_symbol): New function; creates a symbol with the
+ same name as a section, and sets up aux records for it.
+ (coff_add_missing_symbols): New function; adds section symbols to
+ symbol table if they aren't there already. Should someday also
+ add a dummy C_FILE symbol if none is present.
+ (coff_write_object_contents): Add missing symbols before preparing
+ symbol table to be written.
+ (coff_slurp_reloc_table): Verify that symbol indices read in are
+ in a reasonable range.
+ * libcoff-in.h (struct coff_tdata): New field conv_table_size.
+ (obj_conv_table_size): Accessor macro.
+
+ * bout.c (b_out_reloc_type_lookup): New function. Handles three
+ reloc types on i960.
+
+ * bfd-in.h (bfd_get_section_name): New macro. Like
+ bfd_section_name, but returns rvalue, not lvalue.
+ (bfd_get_section_vma, bfd_get_section_alignment): Similar.
+ (bfd_get_section_flags): Now returns rvalue.
+
+ * reloc.c (enum bfd_reloc_code_real): Add several new values, some
+ general, some specific to sparc or i960.
+
+ * aoutx.h (set_section_contents): Set VMA for each section based
+ on previous section. If text section VMA doesn't appear to have
+ been set, make a best guess from the type of file.
+
+ * aout-target.h (MY_reloc_howto_type_lookup): Define as zero if
+ not defined.
+ (MY(vec)): Initialize reloc_type_lookup field.
+
+ * aoutx.h (howto_table_*): Export as aout_#_*_howto_table.
+ (bfd_error_trap, bfd_error_vector): Extern, not common.
+
+ * aoutf1.h (sunos4_reloc_type_lookup): New function. Handles a
+ few types of relocs for sparc; will need enhancement.
+
+ * bout.c (callj_callback): Use DEFUN macro in definition.
+ * coff-i960.c (optcall_callback): Likewise.
+
+ * targets.c (bfd_target): Added fields reloc_type_lookup and
+ _bfd_make_debug_symbol. Also minor comment changes.
+ * syms.c (bfd_make_debug_symbol): New dispatching macro.
+ * reloc.c (bfd_reloc_type_lookup): Take a BFD ptr as arg rather
+ than arch info, and dispatch with BFD_SEND. Callers changed.
+ * archures.c (struct bfd_arch_info): Deleted field
+ reloc_type_lookup.
+ * cpu-*.c: Don't initialize that field.
+
+ * bfd-in.h (enum bfd_error): Add new value "bad_value".
+ * bfd.c (bfd_errmsgs): Now const; added entry for bad_value.
+ (bfd_errmsg): Now returns ptr to const.
+ * bfd-in.h (bfd_errmsg): Fix prototype.
+
+ * cache.c (BFD_CACHE_MAX_OPEN): Fix typo in doc.
+ * reloc.c (bfd_generic_relax_section): Ditto.
+
+ * section.c (Section Output doc): Improve description of use of
+ output_section and output_offset.
+
+Tue May 19 23:42:10 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * sco-core.c: new file from net.
+ * aoutx.h (translate_to_native_sym_flags): bugfix from net:
+ Now we have the hairy linker, it's possible to move symbols from
+ one section into another. Actually make that work!
+
+Sat May 16 17:57:59 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * hosts/sun3.h: fix declaration of free.
+
+Tue May 12 14:08:59 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-a29k.c (perform_reloc): fix bug in jmp/call evaluation
+ * coff-h8300.c (reloc_processing): all relocs are relative to
+ section start.
+ * opncls.c: don't use fdopen on DOS systems
+
+ short patches from Glenn Kasten (glenn@ready.com)
+ * target.c: enabled oasys support
+ * oasys.c: Insert . when UNDERSCORE_HACK is enabled,
+ fix problem where a relocation which crossed a modification byte
+ boundary did not work. Fix problem where a relocation near the end
+ of a data record did not work.
+
+
+Tue May 5 18:11:25 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * archive.c (bfd_slurp_coff_armap): old versions of BFD wrote
+ archvie header string counts the endian way, this heuristic sees
+ how big an archive string to read by trying it one way and if the
+ string table is unreasonably big, trying it the other. *FIXME*.
+ * opncls.c (bfd_fdopenr): can't do fdopens on VMS
+
+Tue May 5 14:18:24 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * bfd-in.h: Increase version number to 1.97, for consistency
+ with ../binutils.
+ * Makefile.in: docdir is ./doc, not ${srcdir}/doc.
+
+Mon May 4 11:49:15 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd-in.h: bump version to 1.96
+ Major change; changed calling convention for
+ bfd_get_relocated_section_contents so that caller allocates
+ memory for section data.
+ * coffcode.h (bfd_coff_get_relocated_section_contents), reloc.c,
+ seclet.c, targets.c, bfd.c: reflect new convention.
+ * coffcode.h (styp_to_sec_flags): if styp_flags is not a special
+ case, then use reasonable default values for SEC_* flags.
+
+Fri May 1 12:58:34 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coffcode.h (coff_write_object_contents): use RELSZ to work out
+ size of output reloc struct.
+ * targets.c, Makefile.in: comment out tekhex for the moment.
+ * ieee.c: if some places where null pointers were used instead of &bfd_abs_section.
+ * configure.in: tandem target is st2000
+ * coff-m68k.c: rename static howto_table to global
+ m68kcoff_howto_table.
+ * bout.c: remove unnecessary abort
+ * coff-a29k.c: various changes to the way relocations work to cope
+ with the "new order" and latent bugs.
+ * coffcode.h: lint
+
+Wed Apr 29 12:37:07 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * aoutx.h (aout_swap_ext_reloc_out, aout_swap_std_reloc_out)
+ bout.c (b_out_squirt_out_relocs): treat abs sumbols the right way.
+ * reloc.c (bfd_perform-relocation): don't relocate refs to
+ absolute symbols if doing a partial link.
+
+Fri Apr 24 07:35:26 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: Add a29k-amd-udi.
+
+Thu Apr 23 18:37:55 1992 Fred Fish (fnf@cygnus.com)
+
+ * aoutx.h (aout_<bits>_swap_exec_header_in): Zero out the
+ internal_exec structure before initializing the fields that
+ are used, so that the unused fields are in a known state.
+
+Wed Apr 22 09:36:08 1992 Fred Fish (fnf@cygnus.com)
+
+ * tekhex.c (struct data_struct): Convert from typedef that
+ typedefs nothing to a normal structure declaration.
+ * tekhex.c (pass_over): Prototype args for function that
+ second arg points to.
+
+Mon Apr 20 22:22:51 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: remove old style staging. Do not print recursion
+ lines.
+
+ * Makefile.in: rework CFLAGS so that CFLAGS can be passed from the
+ Makefile command line. Remove MINUS_G. Default CFLAGS to -g.
+ Pass CFLAGS.
+
+Fri Apr 17 09:15:31 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.c, Makefile.in: added tekhex
+ * aoutx.h (set_section_contents): pages should be padded to the
+ size of a page, not the size of a segment.
+ * configure.in: added go32 host and i386-aout target.
+ * i386aout.c, libaout.h: now works for go32 target
+ * ieee.c: fix bit rot.
+ * seclet.c: support for padding seclet type.
+
+Wed Apr 15 18:11:58 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: added .NOEXPORT:
+
+Tue Apr 14 14:34:42 1992 Fred Fish (fnf@cygnus.com)
+
+ * elf.c (bfd_add_strtab, bfd_add_2_to_strtab): CONST spreads
+ like ooze.
+ * elf.c (elf_compute_section_file_positions,
+ elf_write_object_contents): Return boolean, not NULL (which
+ can be void *).
+ * elf.c (bfd_section_from_shdr): Ifdef-out debugging code.
+ Also ifdef-out code that aborts on unhandled section types.
+
+Fri Apr 10 22:29:18 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Recognize ncr3000 config
+ * Makefile.in (MINUS_G): Pass on to recursive makes.
+ * hosts/ncr3000.h, config/ncr3000.mh: Add host config files.
+
+Thu Apr 2 17:42:45 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Now that we have sym.h and symconst.h, compile
+ coff-msym.c on all systems.
+ * config/{decstation.mh, irix3.mh, irix4.mh}: Remove coff-msym.o dep.
+ * coff-msym.c: Update include files and comments; add weakext bit.
+
+Wed Apr 1 23:16:38 1992 John Gilmore (gnu at cygnus.com)
+
+ * archive.c, bfd.c, bout.c, coffcode.h, init.c, reloc.c,
+ section.c, srec.c, syms.c, coff-h8300.c: Lint.
+
+Sun Mar 29 09:37:59 1992 John Gilmore (gnu at cygnus.com)
+
+ * bout.c, coff-a29k.c, coff-i960.c: Lint.
+ * configure.in: Add new host and target configs.
+ * elf.c (bfd_prstatus, bfd_fpregset): Avoid typename of register
+ structs, which vary; just use member name.
+ (elf_object_p, elf_core_file_p): Lint, fix comments.
+ * config/sparc-elf.mt, hosts/sysv4.h: New config files.
+
+Sat Mar 28 13:07:02 1992 Fred Fish (fnf@cygnus.com)
+
+ * elf.c (elf_object_p, elf_core_file_p): Fix to use only a single
+ local, disposable, copy of the external form of section header
+ table and program header table entries.
+
+Thu Mar 26 16:59:58 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Set MINIMIZE back to 0 for a real release.
+
+Tue Mar 24 15:57:03 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure.in: config/irix4.m[ht], hosts/irix4.h: add support for
+ irix4.
+
+Mon Mar 23 22:37:34 1992 Stu Grossman (grossman at cygnus.com)
+
+ * coff-msym.c (ecoff_swap_rfd_in): remove & for array ref.
+
+Tue Mar 17 14:12:25 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * bout.c (b_out_slurp_reloc_table): Use BFD_ASSERT macro,
+ not internal bfd_assert function (twice).
+
+Tue Mar 17 10:45:12 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * aout-target.h: change ar_max_namelen to 15 (the right value)
+ * coff-a29k, coffcode.h: more hangovers from the bfd_abs_section
+ change
+
+Mon Mar 16 14:57:22 1992 Steve Chamberlain (sac@rtl.cygnus.com)
+
+ * archive.c (bfd_generic_archive_p): check for bout archives too.
+ * bout.c: make it work again.
+
+Sat Mar 14 17:30:40 1992 Fred Fish (fnf@cygnus.com)
+
+ * elf.c (elf_corefile_note): Call bfd_xmalloc() instead of bare
+ malloc().
+ * reloc.c (bfd_generic_get_relocated_section_contents): Call
+ bfd_xmalloc() instead of bare malloc().
+
+Fri Mar 13 15:44:37 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: pass down MAKEINFO on info.
+
+Fri Mar 13 07:41:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/mt-<foo> now <foo>.mt, config/mh-<foo> now <foo>.mh.
+ host/h-<foo> now just <foo>.
+ * configure.in: reflect changes
+
+Thu Mar 12 11:15:02 1992 Per Bothner (bothner@cygnus.com)
+
+ * libbfd-in.h (set_tdata): Make change of Feb 27 in the
+ actual source file, not just the generated libbfd.h.
+
+Sat Mar 7 10:33:41 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * coff-i960.c (icoff_little_vec): add COFF_SWAP_TABLE so we can run
+ gdb on little-endian 960 code.
+ * archive.c (compute_and_write_armap): indirect symbols should go
+ into the archive header too.
+
+Fri Mar 6 21:55:16 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added check target.
+
+Thu Mar 5 23:51:42 1992 John Gilmore (gnu at cygnus.com)
+
+ * coff-msym.c: Move this file from gdb/ecoff.c. It
+ handles byte-swapping for ECOFF (MIPS symbol) files.
+ * config/mh-decstation, config/mh-irix3: Add coff-msym.o
+ to the files built on MIPS-based hosts.
+ * Makefile.in: Add rule for coff-msym.
+
+Thu Mar 5 21:36:05 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added clean-info target. MINIMIZE=1.
+
+Sun Mar 1 22:32:58 1992 Per Bothner (bothner@cygnus.com)
+
+ * coff-rs6000.c: Move core file functions into separate
+ new file rs6000-core.c. This is needed because reading
+ core files depends on native include files that conflict
+ with ../include/coff/rs6000.h.
+ * config/mh-rs6000: Add rs6000-core.o to HDEPFILES.
+
+Thu Feb 27 22:19:55 1992 Per Bothner (bothner@cygnus.com)
+
+ * aoutx.h (NAME(aout,print_symbol)): Don't print
+ symbol addresss for undefined symbols.
+ * coff-rs6000.c: Various updates (due to target-
+ independent changes).
+ * libbfd.h: Ditto (tdata field is now a union).
+ * hosts/h-sparc.h: Removed prototype for bogus function
+ 'emset' (presumably should have been 'memset' - which is there).
+
+Thu Feb 27 11:46:33 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in (mips-big-* target): Same is Iris.
+
+Thu Feb 27 09:24:56 1992 Steve Chamberlain (sac at thepub.cygnus.com)
+
+ * aoutx.h (translate_from_native_sym_flags): when creating an
+ alias symbol, fill in the section as undefined, rather than
+ leaving it blank. If an output section can't be found for a
+ symbol, then don't core dump.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Wed Feb 26 19:40:59 1992 Steve Chamberlain (sac at thepub.cygnus.com)
+
+ * bfd.c: lint
+ * coff-h8300.c: fix stupid reloc subtraction bug
+ * coffcode.h (coff_swap_aux_out): only swap a tvndx by 2 bytes,
+ since that's how wide it is. (coff_slurp_symbol_table): always zero out
+ the symbol.flags and done_lineno fields.
+
+Tue Feb 25 14:29:24 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffcode.h (coff_write_symbol): write out the correct number of
+ auxents.
+ * cpu-h8300.c: fix disassembly bug
+
+Fri Feb 21 21:39:56 1992 John Gilmore (gnu at cygnus.com)
+
+ * bfd-in.h (bfd_errmsg), coffcode.h (coff_swap_aux_in,
+ section_from_bfd_index), cpu-h8300.c (howto*_callback),
+ reloc.c, section.c (bfd_map_over_sections), targets.c
+ (bfd_target_list): Protolint.
+ * libbfd.h: Update to match a libbfd-in.h from a month ago.
+
+Fri Feb 21 10:57:54 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffcode.h (coff_swap_aux_in): lint, (coff_print_symbol): prints
+ out tagndx too.
+ * aoutx.h (swap_std_reloc_out, swap_ext_reloc_out): use the output
+ section of a symbol rather than the section of a reffed symbol to
+ determine the r_index of an emmitted reloc.
+
+Thu Feb 20 18:10:34 1992 Per Bothner (bothner at cygnus.com)
+
+ * PORTING: New (preliminary) porting guide.
+
+Wed Feb 19 21:39:37 1992 John Gilmore (gnu at cygnus.com)
+
+ * bout.c (callj_callback), coff-a29k.c (a29k_reloc), coff-m88k.c
+ (howto_hvrt16): lint.
+
+Mon Feb 17 12:02:17 1992 Per Bothner (bothner at cygnus.com)
+
+ * hp300bsd.c (new), config/mt-hp300bsd: Make hp300bsd
+ a full configuration (with possible cross-development),
+ instead of using host-aout.c.
+
+Sun Feb 16 13:01:49 1992 Per Bothner (bothner at cygnus.com)
+
+ * aout-target.h (MY(write_object_contents):
+ Set obj_reloc_entry_size (abfd).
+ * gen-aout.c: Change to emit a .c files, not a .h file.
+
+Thu Feb 13 20:11:47 1992 Fred Fish (fnf at cygnus.com)
+
+ * elf.c (elf_slurp_symbol_table): Remove obsolete use of
+ BSF_ABSOLUTE and replace with bfd_abs_section reference.
+
+Thu Feb 13 17:22:44 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffcode.h (get_normalized_symtab): fixed bug where symbols
+ with more than one auxent can cause nasty core dumps.
+
+ * coffcode.h, libcoff.c: added new fielded to coff_symbol_struct
+ "done_lineno" so that a symbol which appears twice in the symbol
+ table only gets it's linenumbers relocated once. Modifed
+ (coff_write_native_symbol) and (coff_make_empty_symbol) to make
+ use of it.
+
+Tue Feb 4 15:39:55 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * aoutx.h: (translate_from_native_sym_flags): fix constructor
+ stuff to use the New Order.
+
+Fri Jan 31 01:34:45 1992 Stu Grossman (grossman at cygnus.com)
+
+ * ieee.c: Change type of envi[] to unsigned char.
+
+ * configure.in: fix vax ultrix configuration.
+
+ * elf.c (bfd_section_from_shdr): Deal with null return from
+ bfd_make_section(). (elf_object_p): Select endianess properly.
+
+Fri Jan 31 01:19:55 1992 John Gilmore (gnu at cygnus.com)
+
+ * hosts/h-tahoe.h, h-vaxbsd.h: Fix stack in core files.
+
+Thu Jan 30 23:51:07 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: host-aout.c doesn't depend on aout-params.h.
+ * aout-target.h: Use TARGET_BIG_ENDIAN_P to set up vector.
+ * host-aout.c: Don't use aout-params.h; configure these systems
+ in their xm files, not in a randomly generated file.
+ * hosts/h-hp300bsd.h, h-tahoe.h, h-vaxbsd.h, h-vaxult.h:
+ Specify byte order.
+ * hosts/h-vaxbsd.h: Define the form of exec and core files.
+
+Thu Jan 30 13:02:41 1992 Per Bothner (bothner at cygnus.com)
+
+ * config/mt-tahoe, config/mt-vax: Change DEFAULT_VECTOR to
+ host_aout_vec here as well.
+
+Thu Jan 30 11:41:45 1992 Stu Grossman (grossman at cygnus.com)
+
+ * host-aout.c: Change TARGETNAME to "a.out" to be compatible with
+ gdb. config/mt-hp300bsd: Change DEFAULT_VECTOR to host_aout_vec
+ to prevent undefined symbol.
+
+Thu Jan 30 07:26:53 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ Various lints found on PersSony
+ * aoutx.h: cast an enum
+ * coff-a29k.c: many ints in reloc structure turned to enum
+ * coffcode.h: more enums
+ * cpu-h8300.c: more enums
+ * opncls.c: more enums
+
+Thu Jan 30 01:19:56 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Make Tahoe configuration work again.
+ * bfd-in.h: Remove trailing comma from enum declaration.
+ * ieee.c: Can't put byte values >0x7F into a signed char.
+
+Tue Jan 28 21:10:51 1992 Fred Fish (fnf at cygnus.com)
+
+ * Makefile.in: Add dependencies for various coff-*.o files.
+
+ * elf.c: Remove extraneous paren from core_prpsinfo and
+ core_prpstatus macros, rename core_prpstatus to core_prstatus.
+ Replace references to old section "size" member with new
+ "_raw_size" member. Implement elf_make_empty_symbol, which
+ is now used.
+
+Tue Jan 28 14:51:40 1992 Stu Grossman (grossman at cygnus.com)
+
+ * trad-core.c, bfd.c, ../include/bfd.h: Various fixes for PMAX
+ core reading.
+
+Tue Jan 28 10:46:32 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffcode.h (bfd_coff_relax_section): now static.
+ (bfd_coff_get_relocated_section_contents): various type lints.
+
+Mon Jan 27 19:44:08 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ New entry point in the transfer vector - bfd_relax_section.
+
+ * aout-target.h: add to vector, call generic_relax
+ * bfd-in.h: add to vector
+ * bfd.c: add #define for vector
+ * bout.c: add to vector, call generic_relax
+ * coffcode.h: add to vector, also now has coff specific relax code
+ for the relaxable H8/300 relocs. Also clean up abs section cruft.
+ * elf.c: call generic_relax
+ * ieee.c: call new vector, clean up some bugs due to the creation
+ of bfd_abs_section
+ * libbfd.h: add bfd_generic_relax_section EXFUN
+ * oasys.c: call generic_relax
+ * reloc.c: implement generic_relax
+ * seclet.c: moved much of this into coffcode.h
+ * srec.c: call generic_relax
+ * targets.c: define new transfer vector
+
+Fri Jan 24 14:40:17 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * everything: now modified to use smaller reloc type. Self hosts
+ on sun3 & sun4.
+
+Sat Jan 18 17:00:16 1992 Fred Fish (fnf at cygnus.com)
+
+ * config/mh-stratus, config/mt-i860-elf, hosts/h-stratus:
+ New files for stratus.
+
+ * configure.in: Add configuration fragments for stratus.
+
+Wed Jan 15 10:02:43 1992 Fred Fish (fnf at cygnus.com)
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Declare various filename
+ variables as CONST since they are set to point to a const char
+ string. Fixes compiler complaints.
+
+Fri Jan 10 17:44:53 1992 Fred Fish (fnf at cygnus.com)
+
+ * hosts/h-amix.h hosts/h-i386v4.h: Change abort() to a function
+ returning void.
+
+Fri Jan 10 14:33:32 1992 Per Bothner (bothner at cygnus.com)
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Recognize N_SOL
+ symbols, so that we can emit the correct file name even
+ if it's an include file.
+
+Thu Jan 2 16:43:34 1992 John Gilmore (gnu at cygnus.com)
+
+ * coff-i960.c: Add COFF_SWAP_TABLE to little_vec as well as big_vec.
+ (Reported by john@labtam.labtam.oz.au (John Carey)).
+
+Wed Jan 1 04:23:06 1992 Fred Fish (fnf at cygnus.com)
+
+ * elf.c: Change all '#if HAVE_PROCFS' to '#ifdef HAVE_PROCFS'.
+
+ * config/mh-amix, config/mh-i386v4: Remove HDEFINES that was
+ being used to -DHAVE_PROCFS.
+
+ * hosts/h-amix, hosts/h-i386v4: Add '#define HAVE_PROCFS'. Move
+ '#include "fopen-same.h"' to end of file to match other h-* files.
+
+Fri Dec 20 12:06:17 1991 Fred Fish (fnf at cygnus.com)
+
+ * configure.in: Change svr4 references to sysv4. Add case
+ "unknown" for target vendor and infer some targets based
+ on the specified operating system.
+
+Wed Dec 18 17:17:59 1991 Stu Grossman (grossman at cygnus.com)
+
+ * bfd-in.h, libaout.h: ANSIfy enums.
+
+Wed Dec 18 16:12:25 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * archive.c (normalize): created version for VMS which removes the
+ VMS directory crap from the front and end of a filename, eg turn
+ [-.foo]bar.obj;123 into bar.obj
+ (bfd_construct_extended_name_table): now writes index into an
+ extended name table in decimal - the same base used to read an
+ extended name table.
+
+Wed Dec 18 14:40:39 1991 Per Bothner (bothner at cygnus.com)
+
+ * aout-encap.c: Fix to use aout-target.h.
+ * aoutf1.h: Use standard MY_object_p and MY_callback
+ in aout-target.h. Remove target-specific versions.
+ * host-aout.c: Re-write to use aout-target.h.
+ * gen-aout.c: New files use with host-aout.c to generate
+ host-specific a.out-related parameters.
+ * Makefile.in: host-aout.o depends on aout-params.h, which is
+ generated by gen-aout.
+ * aout-target.h: Make a little more flexible.
+ * libaout.h, aout-target.h: Removed WORK_OUT_FILE_POSTIONS
+ macro. Instead, inline it in aout-target.h.
+ * newsos3.c: Define N_SHARED_LIB(x) as 0 to avoid
+ a gcc -Wall warning.
+ * archive.c: Add missing commas in DEFUN macro (2 places).
+ * elf.c, coffcode.h, aoutf1.h: Use ANSI functions instead of
+ Berkeley ones, now that libiberty has them:
+ bcopy->memcpy, bzero->memset, bcmp->memcmp.
+ * aoutx.h: Various touch-ups: Re-formatting, fix a cast,
+ remove unused variable.
+
+Tue Dec 17 19:48:59 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf.c (elf_core_file_matches_executable_p): Enclose corename
+ and execname inside HAVE_PROCFS ifdef since they are unused
+ when it is not defined.
+
+Mon Dec 16 12:00:10 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf.c: Flag all sections as either code or data. We can't
+ be sure what they are anyway, since ELF doesn't fit the
+ traditional model of text+data+bss very well. Add new local
+ function elf_read() to simplify code. Record entry point in
+ the bfd structure.
+
+Thu Dec 12 21:01:22 1991 John Gilmore (gnu at cygnus.com)
+
+ * hosts/h-*.h: Configure fopen using ../include/fopen-*.h
+ rather than N copies of the same lines.
+
+Wed Dec 11 16:39:45 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * cpu-h8300.c: disassemble branch displacements correctly
+ * coff-h8300.c: put reloc offsets out in 32bits
+
+ * makefile.dos, configdj.bat: New files from DJ
+ * cache.c: fopen with new macros is needed for DOS.
+ * ieee.c: environ renamed to envi to stop an include file
+ conflict.
+ * opncls.c, coff-rs6000.c: more fopens with macros.
+
+Tue Dec 10 04:07:24 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Sat Dec 7 16:39:23 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * Makefile.in: fix where docdir lives
+
+ * aoutx.h, archive.c, archures.c, bfd.c, cache.c, coff-m88k.c,
+ coffcode.h, core.c, ctor.c, elf.c, format.c, ieee.c, init.c,
+ libbfd.c, libbfd.h, libcoff.h, opncls.c, reloc.c, section.c,
+ srec.c, syms.c, targets.c : all new documentation and lint
+ removal.
+
+
+Sat Dec 7 07:22:09 1991 John Gilmore (gnu at cygnus.com)
+
+ * coffcode.h, srec.c: Lint.
+
+Fri Dec 6 22:58:48 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: install using INSTALL_DATA, added standards.text
+ support.
+
+ * configure.in: mark directory as target dependent. configure
+ nows works in objdir always so make file existence checks
+ against ${srcdir}.
+
+Thu Dec 5 22:46:19 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+Wed Dec 4 10:14:17 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * aoutf1.h (sunos_<size>_object_p, sunos4_callback): moved the
+ computation of arch and machine type so it's worked out before
+ some_aout_object_p is called.
+ * aoutx.h: (some_aout_object_p): don't set arch and mach to
+ unknown.
+ * archures.c: add extra field 'section_align_power' to hold
+ default section alignment in object files.
+ * cpu-a29k.c, cpu-h8300.c, cpu-i386.c, cpu-i960.c, cpu-m68k.c,
+ cpu-m88k.c, cpu-mips.c, cpu-rs6000.c, cpu-sparc.c, cpu-vax.c:
+ initialize the new field.
+ * bout.c (b_out_callback): replace the text size, since aout
+ fries them.
+ * aoutx.h: Documentation in the new style
+
+Wed Dec 4 02:00:30 1991 John Gilmore (gnu at cygnus.com)
+
+ * bfd.c (bfd_get_mtime): Don't cache mtime any more; only
+ use the saved value if mtime_set is already set (intended
+ for archive files, though apparently not used yet).
+
+Tue Dec 3 22:54:50 1991 John Gilmore (gnu at cygnus.com)
+
+ * targets.c: Revise comments about how to configure the target
+ vector, to match reality. Remove mention of obsolete methods.
+ Remove long lists of capitalized macros that turn into the same
+ thing in lowercase. Normal vector simply lists all known
+ lowercase xvec names; all other cases are handled by SELECT_VECS.
+
+ * config/mt-i386-coff: Set DEFAULT_VECTOR to real identifier,
+ not macro name.
+
+ * config/mt-i960-{coff,bout}: Use SELECT_VECS to make a short
+ list of supported targets.
+
+Tue Dec 3 14:06:15 1991 Per Bothner (bothner at cygnus.com)
+
+ * archive.c (bsd_write_armap): The pad byte sometimes added to
+ the string table in a __.SYMDEF member is now
+ counted as part of the size of the string table.
+ This is compatible with the old ranlib, as well as Sun's.
+
+Tue Dec 3 10:53:30 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * srec.c: Rewrote to fix many bugs; now gets the record type
+ right, doesn't choke on input, sets the start address in an S9 and
+ fills in the filename on an S0.
+
+Sat Nov 30 21:19:15 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * cpu-h8300.c: Add support for MEMIND addressing mode
+
+ * coff-a29k.c: defined RELOC_PROCESSING to take the #ifdef out of
+ coffcode.h
+ * coffcode.h: use the new macro if available
+
+ * elf.c (elf_corefile_note): cast malloc to avoid warning.
+ * Makefile.in: Fixed dependencies due to file rename
+
+ * aout-encap.c, aoutf1.h, aoutx.h, archive.c, bout.c, coff-a29k.c,
+ coff-h8300.c, coff-i386.c, coff-i960.c, coff-m68k.c, coff-m88k.c,
+ coff-mips.c, coff-rs6000.c, cpu-h300.c, elf.c, i386aout.c,
+ newos3.c, stab-syms.c, syms.c: All these files have had their
+ #includes altered to point to the new places.
+
+Fri Nov 29 20:04:49 1991 Fred Fish (fnf at cygnus.com)
+
+ * config/mh-i386v4, config/mh-i386-elf, hosts/h-i386v4.h: New files.
+
+ * configure.in: Add vendor "ncr" as supported per-target vendor.
+ Add svr4 case for i386 per-host case.
+
+ * elf.c (elf_object_p, elf_core_file_p): Add missing "break" to
+ ELFDATA2LSB cases.
+
+Fri Nov 29 12:16:51 1991 Per Bothner (bothner at cygnus.com)
+
+ * syms.c (bfd_decode_symclass): Return 'A'
+ for symbols that are both absolute and global.
+ * archive.c (bfd_special_undocumented_glue): Return NULL
+ if bfd_ar_hdr_from_filesystem returns NULL.
+
+Tue Nov 26 09:10:55 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * Makefile.in: added coff-h8300
+ * configure.in: now h8 is a coff target
+ * cpu-h8300.c: fix various disassembly problems
+ * libcoff.h: took out some code which has been #0ed for a long
+ time.
+ * targets.c: added h8 coff
+ * coff-a29k.c, coff-i386.c, coff-i960.c, coff-m68k.c, coff-m88k.c
+ added new macro RTYPE2HOWTO to take a load of #ifdefs out of
+ coffcode.h
+ * coffcode.h: Started to change the way machine dependencies are
+ handled, from the nest of #ifdefs to macros defined in the
+ including coff-<foo>.c
+
+Fri Nov 22 08:11:42 1991 John Gilmore (gnu at cygnus.com)
+
+ * aoutx.h (some_aout_object_p): Set the `executable' bit
+ if the entry point is contained in the text segment, even if the
+ text segment is at location 0.
+
+ * coff-mips.c, coffcode.h: Peter Schauer's patch to kludge in
+ nonstandard MIPS sections (.rdata, .sdata, etc).
+
+ * aoutx.h, bfd.c, coffcode.h, ieee.c, oasys.c, targets.c: CONST lint.
+ * libbfd-in.h, libbfd.h, aoutx.h, coffcode.h, elf.c, libaout.h:
+ Rename ALIGN to BFD_ALIGN to avoid conflict with BSD <sys/param.h>.
+ * libbfd.c: Lint.
+ * host-aout.c, trad-core.c: Fix write_armap prototypes. Lint.
+
+Thu Nov 21 19:56:40 1991 Per Bothner (bothner at cygnus.com)
+
+ * stab-syms.c, syms.c: Moved bfd_stab_name() and bfd_stab_names[]
+ from syms.c to new file stab-syms.c. Also, since GNU extended
+ type codes such as N_SETT are no longer in ../include/stab.def,
+ include them manually.
+ * stab-syms.c, aoutx.h: Renamed bfd_stab_name() and
+ bfd_stab_names[] to aout_stab_name() and aout_stab_names[].
+ * libaout.h: Added prototype for aout_stab_name().
+ * Makefile.in: Update Makefile for new stab-syms.[co].
+
+Thu Nov 21 11:50:49 1991 John Gilmore (gnu at cygnus.com)
+
+ * libaout.h (WORK_OUT_FILE_POSITIONS): One more try at this
+ rather complicated seeming problem. Eliminate LOGICAL_ versions,
+ just make N_XXX work by excluding the header from the text segment.
+ * aoutx.h: Fix comments to match.
+
+Tue Nov 19 18:49:01 1991 Per Bothner (bothner at cygnus.com)
+
+ * libaout.h (WORK_OUT_FILE_POSITIONS): Use new LOGICAL_TXTADDR,
+ LOGICAL_TXTOFF, LOGICAL_TXTSIZE macros to figure out numbers
+ for the "logical" text segment (i.e. never consider the exec
+ header to be part of the text segment). This change is
+ needed for consistency with various other parts of bfd and ld.
+ * aoutx.h (NAME(aout,soe_aout_object_p)): Fix comment,
+ and move calculation of obj_textsec(abfd)->size to libaout.h.
+ * bfd-in.h: Removed bogus ';'.
+
+ * Makefile.in: Add MINIMIZE flag to select lean
+ or bloated target_vector.
+ * targets.c: Use new MINIMIZE macro, and add trad_core if needed.
+ * newsos3.c: Fixes to ../include/aout64.h remove need
+ for special N_TXTOFF macro, but require N_HEADER_IN_TEXT.
+
+Mon Nov 18 12:00:59 1991 Per Bothner (bothner at cygnus.com)
+
+ * aout-target.h, aoutf1.h, newsos3.c: Make aout-target.h
+ handle both little and big-endian targets, with little
+ the default unless TARGET_IS_BIG_ENDIAN_P is defined.
+ * host-aout.c: Add FIXME note.
+
+Sun Nov 17 13:29:39 1991 Per Bothner (bothner at cygnus.com)
+
+ * targets.c: Make the default target_vector contain
+ just &DEFAULT_VECTOR. This makes executables a lot smaller.
+ Old behavior can be gotten by defining ALL_TARGETS.
+ * aoutf1.h, demo64.c, i386aout.c, newsos3.c, sunos.c:
+ Factored out common code into new file aout-target.h.
+ Saves a lot of duplicate code for a.out variants.
+
+Fri Nov 15 13:00:43 1991 Per Bothner (bothner at cygnus.com)
+
+ Get 'make headers' to work when configured with +subdirs.
+ * Makefile.in: Add $(subdir) to docdir path.
+ * doc/Makefile.in (protos): Add $(srcdir) prefix
+ to name of sed scripts.
+
+Thu Nov 14 19:49:10 1991 Per Bothner (bothner at cygnus.com)
+
+ * aoutx.h (NAME(aout,print_symbol)): Fix thinko.
+ * syms.c (bfd_stab_names): Turn on new GNU_EXTRA_STABS macro
+ to include names of N_SETT etc.
+
+Thu Nov 14 19:11:13 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf.c: Add minimal support for ELF symbol tables. Generates
+ canonical bfd symbol tables from ELF symbol tables. Change the
+ name of some functions from bfd_<name> to elf_<name>.
+
+ * syms.c: Trivial fix to comment to remove a redundant "to".
+
+Wed Nov 13 17:02:01 1991 John Gilmore (gnu at cygnus.com)
+
+ * coff-{i386,m68k,m88k}.c: Change name of file format to standard
+ form that GDB recognizes as COFF.
+
+Wed Nov 13 09:09:41 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * ieee.c (ieee_object_p): cast NULL correctly.
+ * configure.in: added harris host
+
+ * coff-a29k.c: Lots of changes, most from David Wood.
+
+Tue Nov 12 07:21:41 1991 John Gilmore (gnu at cygnus.com)
+
+ * coff-m88k.c (coff_write_armap): Just #undef it.
+
+Mon Nov 11 20:30:18 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * Makefile.in: standardize on MINUS_G to disable debugging
+ * coff-m88k.c: create coff armaps instead of bsd ones.
+ * opncls.c (bfd_close_all_done), (bfd_close): Mask out random bits
+ when calling chmod.
+
+Mon Nov 11 19:07:32 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf.c: Additions to support ELF format core files.
+ * config/mh-amix: Add -DHAVE_PROCFS to HDEFINES, since host
+ has support for /proc (all the include files in particular).
+
+Mon Nov 11 18:36:47 1991 Per Bothner (bothner at cygnus.com)
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Handle the case
+ of two N_SO stabs, one for directory, and one for filename.
+
+ * bfd-in.h (print_vma): Factor out duplicate definition.
+
+ Exit a little more gracefully when malloc returns NULL.
+ * libbfd.c: New function bfd_xmalloc (malloc wrapper).
+ * opncls.c, syms.c, bout.c, aoutx.h: Replace malloc by bfd_xmalloc.
+ * libbfd.h: Rre-generated due to libbfd.c update.
+
+Sat Nov 9 13:45:01 1991 Fred Fish (fnf at cygnus.com)
+
+ * config/mt-m68k-elf: Define DEFAULT_VECTOR as elf_big_vec.
+
+ * elf.c (elf_object_p): Don't try to create a bfd section for
+ the first ELF section header. It is just a placeholder.
+
+Sat Nov 9 03:04:26 1991 John Gilmore (gnu at cygnus.com)
+
+ * coff-rs6000.c, config/mh-rs6000: Make it work on archive and
+ core files, when compiling native.
+ * hosts/h-rs6000.h: Define FASCIST_FDOPEN for bfd_fdopenr.
+
+ FIXME: The aoutf1.h change below needs to be reversed back
+ to the way it was.
+
+Thu Nov 7 11:03:55 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * coffcode.h: Defined new macros [PUT|GET]LINENO_LNNO for
+ manipulation of lnno fields in lineno structs in a coff-<f>.h
+ independent way. Override it in coff-<f>.h to your favourite
+ number if you don't have a 16bit lnno field. (coff_swap_lineno_in)
+ (coff_swap_lineno_out): modified to use the new macros.
+
+Mon Nov 4 11:38:33 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * aoutf1.h (sunos4_callback): Now defaults to 68020 rather than
+ unknown arch when the magic number doesn't specify the
+ architecture, since some OSs (eg old sun3s) don't set the number, and
+ 020 is probably the right answer anyway.
+
+Sun Nov 3 12:07:08 1991 Per Bothner (bothner at cygnus.com)
+
+ * hosts/h-news.h, hosts/h-rtbsd.h:
+ Get rid of MISSING_VFPRINTF, since libiberty provides one.
+ * bfd-in.h (bfd_print_symbol_type_hopw enum): Add new option
+ bfd_print_symbol_nm, for use by nm.
+ * aoutx.h (NAME(aout,print_symbol)): Add code for new
+ bfd_print_symbol_nm option, to print in nm format.
+ * coffcode.h (coff_print_symbol), ieee.c (ieee_print_symbol)
+ oasys.c (oasys_print_symbol): Provide stub implementations
+ for bfd_print_symbol_nm.
+ * syms.c: New function bfd_decode_symclass, used by nm printer.
+ New function bfd_stab_name to look up string name of stab code.
+
+Sat Nov 2 14:26:03 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * Makefile.in: Added ctor.c
+ * archures.c (bfd_default_arch_struct) added
+ bfd_default_reloc_type_lookup.
+ * coffcode.h: removed a load of #if 0ed code.
+ (coff_compute_file_section_positions): now works out the section
+ alignment and size correctly in all cases.
+ (coff_get_symtab): looks for constructor symbols and calls the
+ right function when they're found. (coff_canonicalize_reloc):
+ knows when a section is full of constructors and does the right
+ thing.
+ * cpu-m88k.c: Added default_reloc_type lookup to the architecture
+ description.
+ * libbfd-in.h: (bfd_default_reloc_type_lookup) defun added.
+ * libcoff.h: removed #if 0ed code
+ * reloc.c: (bfd_reloc_code_real_type) added BFD_RELOC_CTOR for
+ arch independent constructor relocation type.
+ (bfd_reloc_type_lookup): removed the comment "this will go away"
+ since it won't. (bfd_howto_32): stolen from 88k, this is a 32bit
+ reloc which is used when BFD_RELOC_CTOR falls through to give a
+ default 32bit reloc for constructors.
+ (bfd_default_reloc_type_lookup): added.
+ * aoutf1.h: fixed SEGMENT_SIZE typo.
+
+Thu Oct 31 18:23:06 1991 John Gilmore (gnu at cygnus.com)
+
+ * coff-rs6000.c: Change name to "aixcoff-rs6000", to avoid
+ matching prefix "coff".
+ * coffcode.h (coff_swap_aux_in, coff_swap_aux_out): Handle
+ rs/6000 csect records.
+
+Sun Oct 27 16:56:58 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * coff-m88k.c, targets.c: change name of m88k_bcs to m88kbcs
+ * configure.in: add motorola delta88 cases
+ * libbfd.h, libbfd-in.h, archive.c, ieee.c, elf.c, srec.c: fix
+ write_armap prototype
+ * libbfd.c: add doc on bfd_write_bigendian_4byte_int
+
+Fri Oct 25 02:48:19 1991 John Gilmore (gnu at cygnus.com)
+
+ * Rename COFF-related files in `coff-ARCH.c' form.
+ coff-a29k.c, coff-i386.c, coff-i960.c, coff-m68k.c, coff-m88k.c,
+ coff-mips.c, coff-rs6000.c to be exact.
+
+ * Makefile.in: Only supply TARGET_DEFAULTS to targets.c, reducing
+ make output clutter.
+ * config/mt-*: Ditto.
+
+Thu Oct 24 22:40:07 1991 John Gilmore (gnu at cygnus.com)
+
+ RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and
+ John Gilmore. Archive support from Damon A. Permezel.
+
+ * Makefile.in: Add cpu-rs6000.c and rs6000coff.c.
+ * configure.in: Add rs6000 case.
+ * targets.c: Add rs6000 vector.
+ * archures.c: Add rs6000, fix comment on romp.
+ * bfd-in.h (enum bfd_error): Add no_debug_section error.
+ * libcoff-in.h (struct coff_tdata): Remove unused string_table.
+ * bfd.c (bfd_errmsgs): Add no_debug_section error message.
+ * section.c (bfd_make_section): Return NULL on attempt to create
+ a section twice.
+ * coffcode.h (bfd_swap_reloc_in): Handle r_type and r_size.
+ (bfd_swap_aouthdr_in): Handle lots more members.
+ (make_a_section_from_file): If section has already been seen,
+ just return false rather than overwriting it.
+ (coff_real_object_p): Understand incoming magic numbers.
+ (coff_set_flags): Understand outgoing magic numbers.
+ (coff_compute_section_file_positions): outgoing aouthdr magic #.
+ (build_debug_section): Add fn for reading debug string section.
+ (get_normalized_symtab): Handle symbol names in debug string section.
+ Remove unused obj_string_table.
+ (coff_slurp_symbol_table): Handle rs6000-specific storage classes.
+ * aoutx.h (translate_from_native_sym_flags, N_SET*): Check for
+ existing section before making one.
+ * cpu-rs6000.c: New file.
+ * rs6000coff.c: New file.
+
+Thu Oct 24 02:03:24 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf.c: Add partial support for ELF format corefiles. Still needs
+ support for extracting registers from corefiles.
+
+ * config/t-m68k-elf: Set DEFAULT_VECTOR to elf_big_vec.
+
+ * config/{h-amix,h-dgux,h-irix3,h-ultra3}: For systems where
+ RANLIB is defined as echo, send the output to /dev/null to help
+ reduce clutter in the output from doing a make.
+
+Mon Oct 21 17:48:48 1991 John Gilmore (gnu at cygnus.com)
+
+ * hosts/h-vaxult.h: Remove malloc/free decls covered in stdlib.h.
+ Fix HOST_PAGE_SIZE and HOST_SEGMENT_SIZE. From David Taylor.
+
+Mon Oct 21 09:34:11 1991 Steve Chamberlain (steve at rtl.cygnus.com)
+
+ * coffcode.h (coff_compute_section_file_positions): make it pad
+ section size out if there are alignment restrictions so that the
+ image will be ok on a system where section positions are worked
+ out by accumulating sizes rather than from the section headers.
+ * targets.c (proto write_armap). Changed orl_count to unsigned.
+ * opncls.c (bfd_close_all_done). Added so that generative
+ programs like gas can close a bfd without causing bfd confusion.
+ * libbfd.h (changed becuase of protos)
+ * amdcoff.c: messed with the way that jmp displacements are
+ calcualated. This may not yet be totally correct.
+ * archive.c (coff_write_armap): rewrote the way that ranlibs are
+ written out.
+ * coffcode.h (fixup_symbol_value): now doesn't core dump if a non
+ abs symbol has no section (like a register symbol).
+ (coff_write_symbol) now zeros auxent before filling it up to help
+ with sensitive applications.
+ * libbfd.c (bfd_write_bigendian_4byte_int): added.
+
+Wed Oct 16 22:58:45 1991 John Gilmore (gnu at cygnus.com)
+
+ * bfd.c: Make sure we don't get a macro strerror().
+ * opncls.c (bfd_fdopenr): If FASCIST_FDOPEN, use "r", not "r+".
+ * trad-core.c (trad_unix_core_file_failing_command): Suppress
+ attempt to recover command, ifdef NO_CORE_COMMAND.
+ * hosts/h-tahoe.h: Add FASCIST_FDOPEN and NO_CORE_COMMAND;
+ revamp HOST_*, etc.
+ * hosts/h-i386v.h: Use <utime.h>, not <sys/utime.h>, unlike POSIX.
+
+Wed Oct 16 12:43:49 1991 Per Bothner (bothner at cygnus.com)
+
+ * archive.c (bsd_write_argmap): The size of the ranlib structures
+ should not include the size field itself.
+ * aoutx.h, libaout.h (NAME(aout, sizeof_headers)): Use
+ adata(abfd)->exec_bytes_size field instead of constant macro,
+ because aoutx.h compiles to a simple .o file shared by
+ all 32-bits a.out targets.
+
+Wed Oct 16 11:11:05 1991 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Allow i386-sco-sysv.
+ * bout.c: Remove unused i960_align; lint dummy core file handlers.
+ * cpu-h8300.c: lint.
+
+ * host-aout.c: New strategy. We use common code, include files,
+ and data structures to handle the file, but set a few parameters
+ from the host's config file (page size, text start addr, etc).
+ * libaout.h: Define HP BSD machine types.
+ * aoutf1.h: Handle reading a.outs with these types.
+
+ * trad-core.c: Pass the u.u_ar0 value as the negative of the
+ virtual-memory-address of the .reg section. We can't just make a
+ section for "all the regs and nothing else" because only GDB knows
+ exactly where the regs are (scattered around the upage and stack).
+ Clean up memory allocation. Remove big- and little-endian
+ vectors, replace with single vector; this only runs on the host,
+ in host byte order. Replace byteswap routines with aborts in case
+ anyone calls them.
+ * targets.c: There's only one trad_core_vec now.
+ * aoutf1.h (sunos_core_file_p): VMA of .reg* now needs to be 0.
+
+Tue Oct 15 08:29:03 1991 John Gilmore (gnu at cygnus.com)
+
+ * hosts/h-amix.h (free): Fix prototype.
+
+ * aoutx.h: Don't use NULL as an integer, for braindead systems
+ that declare it as (void *)0. (From Peter Schauer.)
+
+Mon Oct 14 17:20:47 1991 Per Bothner (bothner at cygnus.com)
+
+ * opncls.c (bfd_fdopenr): Add parentheses to avoid reported
+ problem with bad Ultrix system headers.
+ * aoutx.h (NAME(aout,set_section_contents)): Try to handle the
+ various kinds of alignments for the various kinds of
+ magic numbers.
+
+Mon Oct 14 14:23:10 1991 John Gilmore (gnu at cygnus.com)
+
+ * doc/Makefile: Don't assume . is on the path (from James Clark).
+
+Fri Oct 11 22:45:14 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Avoid Sun Make VPATH bugs.
+ * targets.c: Declare trad_core vectors extern.
+
+Fri Oct 11 13:03:02 1991 Per Bothner (bothner at cygnus.com)
+
+ * coffcode.h: Moved ALIGN macro to libbfd.h. Removed i960_align.
+ * libbfd.h: Moved ALIGN macro here.
+ * bout.c (b_out_callback): Replace i960_align by align_power.
+
+ * libaout.h (struct aoutdata): Added fields page_size,
+ segment_size and exec_bytes_size. These help generic code
+ (in aoutx.h and libaout.h) to figure out where to align
+ the various segments in a demand paged file.
+ * libaout.h (WRITE_HEADER): Use new (struct aoutdata) fields
+ to decide if the exec header counts in a_text (text segment size).
+ Also, assume D_PAGED flag is set; don't set it here.
+ * bout.c (b_out_callback): Add initialization of
+ adata fields page_size, segment_size, and exec_bytes_size.
+ * host-aout.c (NAME(host_aout, callback) and
+ NAME(host_aout,mkobject): Ditto.
+ * i386aout.c (aout386_callback) and new aout386_mkobject): Ditto.
+ * newos3.c (newsos3_callback) and new newsos_mkobject): Ditto.
+ * aoutf1.c (sunos4_callback) and new sunos_mkobject): Ditto.
+ * aoutx.h (NAME(aout,some_aout_object_p)): Don't subtract
+ EXEC_BYTES_SIZE from the a_test size; this is only appropriate
+ for some systems (mainly sunos), so do it in the callback instead.
+ Same routine: Add stuff to the THIS_IS_ONLY_DOCUMENTATION comment.
+ * aoutx.h (NAME(aout,set_section_contents): Change the way
+ filepos and size of sections are carried out to support
+ older styles of demand paged executables.
+
+
+Fri Oct 11 12:33:36 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * bfd-in.h: Added more macros to COFF_SWAP_TABLE.
+ * bfd.c: Added macros to enable gas to swap coff records.
+ * coffcode.h: Make the coff_swap_*_out routines return the number
+ of bytes swapped, and cleaned up their prototypes.
+ * configure.in: Added ebmon/coff support
+ * ecoff.c: Changed null definitions of coff_swap_*_out to conform
+ to new prototypes
+ * targets.c: Added new entry points for coff swapping
+
+Fri Oct 11 03:01:52 1991 John Gilmore (gnu at cygnus.com)
+
+ Restructure configuration scheme for bfd, binutils, ld.
+
+ * include/sys/h-*.h: Move to bfd/hosts/h-*.h.
+ * configure.in: Revise to symlink sysdep.h to hosts/h-xxx.h.
+ Change some config names to match other dirs.
+ * *.c: Include bfd.h before sysdep.h, so ansidecl and PROTO()
+ get defined first.
+ * Makefile.in: Use -I. to get sysdep.h. Remove refs to
+ ../include/sysdep.h.
+ * cpu-i960.c: Strncmp needed a length arg.
+ * ecoff.c: Don't ever call trad_unix_core_file_p from here.
+ * i386aout.c: Remove dead N_TXTOFF override.
+ * trad-core.c: Don't disable the whole file if SUN4_SYS.
+ * config/: Rename some config files to match up h-*.h names.
+ Remove all the HOST_SYS definitions from the config files.
+ * hosts/h-amix.h, h-i386v.h: Define POSIX_UTIME, not USG.
+ * hosts/h-hp9000.h: Remove USG comment.
+ * hosts/h-rs6000.h: Include <stdlib.h> for malloc.
+ * hosts/h-news.h, h-sparc-64.h: New config files that had
+ previously been kludged in the <sysdep.h> file.
+
+Thu Oct 10 17:54:08 1991 John Gilmore (gnu at cygnus.com)
+
+ * config/*: trad-core support is HOST dependent, not target
+ dependent. Target config files only set DEFAULT_VECTOR and/or
+ other vector elements. Exception: when host-aout.c is in use,
+ in which case we're forced to assume we're native (hp, vax,
+ tahoe). Rename XDEPFILES to HDEPFILES.
+ * Makefile.in: Rename XDEPFILES.
+ * config/h-sun*: Don't force static linking.
+ * trad-core.c: Document how to use it nowadays.
+ * i386aout.c, newsos3.c: Clean up.
+ * i386coff.c: Allow 386 coff files to be used as core files too
+ (for reading core files from embedded systems).
+
+Tue Oct 8 15:30:39 1991 John Gilmore (gnu at cygnus.com)
+
+ * Add i386aout.c for a.out support on the i386.
+
+Tue Oct 8 12:18:54 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * reloc.c, section.c, syms.c, targets.c: correct info-node
+ structure in *doc* comments.
+ doc/Makefile: stop hiding complaints from makeinfo.
+
+Sun Oct 6 19:10:06 1991 John Gilmore (gnu at cygnus.com)
+
+ * aoutx.h (...some_aout_object_p): Take a third parameter,
+ the internal_exec struct, and avoid ever looking at an
+ external_exec. All callers changed to read the entire
+ external_exec struct, swap and check its magic number,
+ swap in the whole structure, and pass the swapped-in version to
+ some_aout_object_p.
+ * bout.c: Bring into modern era. Use single _object_p routine
+ for big- aand little-endian. Provide internal and external
+ exec header structs. Use separate swap-in and swap-out routines.
+
+ * libaout.h: Move struct internal_exec from ../include/aout64.h
+ to here. Add obj_symbol_entry_size to struct aoutdata.
+ * aoutx.h (...some_aout_object_p): Set obj_symbol_entry_size.
+
+ * ../include/aout64.h: Change EXTERNAL_LIST_SIZE to
+ EXTERNAL_NLIST_SIZE. Callers changed.
+
+Fri Oct 4 18:18:46 1991 John Gilmore (gnu at cygnus.com)
+
+ * bfd.c: Remove strerror() to libiberty.
+
+ * elf.c: Remove elf_set_section_contents, use generic one. Lint.
+ * libbfd-in.h, libbfd.c: Add bfd_generic_set_section_contents.
+ * libbfd.c (bfd_generic_{get,set}_section_contents): Check that
+ last byte of transfer, not first byte, is within the section.
+
+ * host-aout.c: Remove `BSD' archive support. Lint.
+
+ * archures.c: Rename `struct bfd_arch_info_struct' to `struct
+ bfd_arch_info'. Rename `typedef bfd_arch_info_struct_type' to
+ `bfd_arch_info_type'. All uses changed.
+ * reloc.c: Rename `bfd_reloc_status_enum_type' to
+ `bfd_reloc_status_type'. Rename `bfd_reloc_code_enum_real_type'
+ to `bfd_reloc_code_real_type'. (This seems to be a misnomer,
+ it needs a better name.) All uses changed.
+ * targets.c: Rename `enum target_flavour_enum' to `enum
+ target_flavour', and remove the `_enum' from all of the enum
+ values themselves. All uses changed.
+
+ * configure.in, config/h-i386mach: i386 mach host.
+ * config/t-i386-aout: Use host-aout.c.
+
+ * trad-core.c: Give it its own xvec's to make it independent
+ of other file formats.
+ * ecoff.c, host-aout.c: Remove refs to trad-core.
+ * config/t-dec3100, t-hp300bsd, t-tahoe, t-vax: Define TRAD_CORE.
+ * targets.c: #ifdef TRAD_CORE, include it in the vector.
+
+Fri Oct 4 17:38:03 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * reloc.c: Extended NEWHOWTO macro
+ * ieee.c: Changed the way 8bit pcrel is done
+ * cpu-h8300.c: got the registers in the right order
+
+Thu Oct 3 19:39:55 1991 John Gilmore (gnu at cygnus.com)
+
+ * bfd-in.h: enum boolean => enum bfd_boolean for SVR4. Gumby's
+ prediction is vindicated!
+
+ * bfd-in.h, libbfd-in.h, doc/Makefile, doc/tolibbfd, doc/intobfd:
+ Remove refs to howto.c, since Steve forgot.
+
+Thu Oct 3 07:49:21 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * elf.c: took the abort out of set_arch_mach so that objdump -i will
+ still work. Now allows any architecture/machine to be set.
+
+Wed Oct 2 13:50:35 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * howto.c deleted and moved code to reloc.c
+
+ * libbfd.h, libbfd-in.h removed $id stuff for real
+
+ * cpu-h8300.c Made it match various different spellings of h8300.
+
+ * archures.c: Took out the first char filter which made it only
+ look for a cpu/arch match when the first chars of supplied and
+ tested names were the same.
+
+ * targets.c removed oasys stuff, pending someone to fix the bugs
+ in it.
+
+
+Tue Oct 1 12:29:44 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in, configure.in, targets.c, elf.c: Add preliminary
+ ELF support good enough for GDB.
+ * configure.in, config/h-amix, config/t-m68k-elf: Handle
+ m68k-cbm-svr4 host and target.
+ * config/t-m68k-coff, t-m88k-coff, t-m88k-aout: Make files nonempty
+ so `diff' and `patch' can cope.
+
+Tue Oct 1 11:24:31 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * archures.c: removed texinfo error
+
+ * init.c: added texinfo hooks, and removed initialization error
+ message.
+
+ * libcoff-in.h, libbfd-in.h removed $id field so cvs can merge
+ without complaints.
+
+Tue Oct 1 05:02:53 1991 John Gilmore (gnu at cygnus.com)
+
+ * cpu-i960.c: Avoid numerical count of initializers.
+
+ Vax Ultrix changes from David Taylor <taylor@think.com>:
+ * host-aout.c: Make little-endian vector really little-endian.
+ * configure.in: Separate vax and tahoe cases, handle ultrix.
+ * config/t-vax: Add trad-core.o.
+ * config/h-vaxult: New host system.
+
+Mon Sep 30 15:13:46 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * bfd-in.h VERSION, change version number to 0.18, this makes a
+ gap, but now is the same as the linker version number.
+
+ * cpu-a29k.c, cpu-i386.c, cpu-m68k.c, cpu-mips.c, cpu-vax.c,
+ cpu-h8300.c, cpu-i960.c, cpu-m88k.c, cpu-sparc.c: added. These
+ files will eventually contain processor specific bits for bfd,
+ like strange relocation information and dis/assembly. So far only
+ the H8 has been even partially done. This work also ties in with
+ the change in handling architectures.
+
+ * amdcoff.c: (a29k_reloc) fix error message.
+
+ * aout-f1.h: (choose_reloc_size) now calls bfd_get_arch to
+ discover the architecture of the bfd. (sunos4_callback) calls the
+ function bfd_set_arch_mach rather than stuffing stuff directly
+ into the bfd. (sunos4_write_object_contents), changed names of
+ accessor functions.
+
+ * aoutx.h: (set_arch_mach) now calls bfd_default_set_arch_mach to
+ setup the environment.
+
+ * archive.c: (bfd_slurp_coff_armap) coff archives always have the
+ headers in big endian format, regardless of the endianess of the
+ host or target.
+
+ * archures.c: totally changed. Now an architecture is represented
+ with a pointer to an info structure rather than an enumerated type
+ and a long. The old info is available as two elements in the
+ structure. Future enhancements to architecure support will
+ involve pointers to methods being placed into the info structure.
+
+ * bfd.c: changed the definition of the bfd structure for the new
+ architecture stuff.
+
+ * bout.c: (b_out_set_arch_mach) changed to use the new
+ architecture mechanism.
+
+ * coffcode.h: (coff_set_arch_mach, coff_set_flags) changed to use
+ the new architecture mechanism.
+
+ * configure.in: added h8 stuff.
+
+ * ieee.c: too many changes to note. Now ieee files written with
+ bfd gas and ld can be read by gld and ieee only linkers and
+ simulators.
+
+ * libbfd.c, libbfd.h: changed prototype of bfd_write.
+
+ * newsos3.c: (newos3_callback) now calls bfd_set_arch_mach rather
+ than fixing the structure directly.
+
+ * oasys.c: (oasys_object_p) now calls bfd_default_set_arch_mach rather
+ than fixing the structure directly.
+
+ * opncls.c: (new_bfd) makes sure that bfd_init has been called
+ before opening a bfd.
+
+ * srec.c: (srec_set_arch_mach) now calls bfd_default_set_arch_mach
+ rather than fixing the structure directly.
+
+ * targets.c: (target_vector) now by defining SELECT_VECS (perhaps
+ in the t/hmake file) a user can select which backends they want
+ linked with bfd without changing the source.
+
+ * init.c: new, looks after initializing modules.
+
+ * howto.c: for future use, will allow an application to work out
+ what cookie to use as a handle on a relcoatio howto.
+
+Mon Sep 30 13:31:15 1991 John Gilmore (gnu at cygnus.com)
+
+ * srec.c: Better error checking, partly from Peter Schauer.
+ (srec_object_p): Avoid assuming any file that starts with 'S' is
+ an S-record file! (Check for 3 uppercase-hex digits after it.)
+ (ISHEX): Define new macro for checking supposedly hex characters.
+ (pass_over): Treat as EOF any S-record line that:
+ * doesn't have hex in either size character
+ * produces a size larger than 0x7F
+ * has an unrecognized type number
+
+Thu Sep 26 15:27:29 1991 John Gilmore (gnu at cygnus.com)
+
+ * aoutf1.h, aoutx.h, bout.c, coffcode.h, host-aout.c, oasys.c,
+ opncls.c: Lint (saber actually).
+
+Thu Sep 26 11:24:24 1991 Per Bothner (bothner at cygnus.com)
+
+ * libaout.h (WRITE_HEADERS): Set header's a_text field always.
+ * newsos3.c: Fixed two types: newos3 -> newsos3.
+ * reloc.c (bfd_perform_relocation): Fix pc-relative relocation
+ to use correct segment.
+
+Mon Sep 23 18:24:34 1991 Per Bothner (bothner at cygnus.com)
+
+ * aoutx.h (print_symbol): Handle missing symbol->name.
+
+Fri Sep 20 12:26:01 1991 Stu Grossman (grossman at cygnus.com)
+
+ * aoutf1.h (swapcore_sparc): Change name of USRSTACK, fix comment
+ at top of routine.
+
+Tue Sep 17 17:23:49 1991 Stu Grossman (grossman at cygnus.com)
+
+ * oasys.c, configure.in, config/h-irix3, config/t-irix3:
+ add sgi/irix support.
+
+Thu Sep 12 14:29:09 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Changes for the AMD 29000 Ultracomputer port from David Wood.
+ (wood@nyu.edu).
+
+ * opncls.c (bfd_fdopenr): Handle NO_FCNTL.
+
+ * Makefile.in: Make subdirs work by using $(INCDIR) in the
+ crude dependencies.
+
+ * coffcode.h (coff_real_object_p): Pass information about the
+ current file's coff symbol format to BFD via the coff_data struct.
+ (coff_find_nearest_line): obj_icof => coff_data.
+ (coff_swap_sym_{in,out}): Check that SYMNMLEN == E_SYMNMLEN.
+ (coff_swap_aux_{in,out}): Check that FILNMLEN == E_FILNMLEN
+ and DIMNUM == E_DIMNUM.
+ * configure.in: Handle a29k-*-* hosts, and targets
+ a29k-*-coff, a29k-*-aout, and a29k-*-sym1.
+ * libcoff-in.h: Add local_n_btmask, local_n_btshft,
+ local_n_tmask, local_n_tshift, local_symesz, local_auxesz,
+ local_linesz to `coff_data' (tdata) struct.
+ (coff_data, coff_data_type, coff_tdata): Rename struct icofdata.
+ * config/h-ultra3: Handle a29k-*-* hosts as Ultracomputers.
+
+Thu Sep 12 14:07:22 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * Makefile.in: $(MAKE) for make, $(docdir) for doc
+ * doc/Makefile: redundant dependencies for Sun-make VPATH bug
+
+Tue Sep 10 20:34:12 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * aoutf1.h (sunos4_core_file_p): Release the right storage in
+ error case.
+ (sunos4_core_file_matches_executable_p): Fix header comparison.
+ * aoutx.h: Avoid shifts of 32 bits, undefined in C. Lint.
+ * bout.c, icoff.c, ieee.c, libbfd.c, oasys.c: gcc -O -W lint.
+
+Wed Sep 4 00:44:52 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Allow GDB to patch object files.
+
+ * aoutf1.h (sunos_core_file_p): Set SEC_HAS_CONTENTS on all sections.
+ * trad-core.h (trad_unix_core_file_p): Ditto.
+ * aoutx.h (aout_set_section_contents): On first output, check
+ abfd->direction and complain if erroneous.
+
+ * Makefile.in: Add crude dependencies.
+
+Tue Sep 3 13:46:19 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * config/* aoutx.h configure* shortened all the h/tmake-xxxx
+ to h/t-xxxx files so that everything will work on System V.
+
+Fri Aug 23 13:51:06 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * aoutx.h: Add information on host-aout.c and how to configure
+ to use it, to the manual.
+ * configure.in: Tix typo.
+ * ecoff.c: If compiling for DEC3100, use trad_unix core files,
+ else dummy out the core file support.
+ * trad-core.c (trad_unix_core_file_p): If HOST_DATA_START_ADDR is
+ specified, use it to locate the data section.
+ * coffcode.h (coff_write_symbols): Declare buffer as bfd_bytes
+ rather than as chars (lint).
+
+Thu Aug 22 22:20:19 1991 Stu Grossman (grossman at cygint.cygnus.com)
+
+ * aoutx.h, coffcode.h: saberized.
+
+Thu Aug 22 11:27:06 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * bfd.texinfo: some cleanup, reincorporated more intro matter from
+ bfd.doc
+ bfd.c, targets.c: minor rewording of doc segments
+
+
+Wed Aug 21 19:13:22 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * trad-core.c (trad_unix_core_file_p): Use HOST_TEXT_START_ADDR,
+ etc, rather than TEXT_START_ADDR.
+ * host-aout.c: Remove #if 0 around whole thing.
+ Update to modern (32/64-bit) a.out naming conventions.
+ Include a large chunk of ../include/a.out.gnu.h to get macros that
+ are not defined by the system include files.
+ (host_aout_{32,64}_write_object_contents): Use the WRITE_HEADERS
+ macro used by the other a.out implementations.
+ * Makefile.in: Give dependencies to OPTIONAL_BACKENDS.
+
+Wed Aug 21 14:33:06 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * Makefile.in: use targets "bfd.dvi" and "bfd.ps" instead of
+ texdoc and psdoc; make these depend on generated .texi's
+
+ * scanit, (new) unPROTO: turn PROTO macros into ANSI declarations in
+ doc
+
+ * bfd.c, reloc.c, syms.c: minor spelling/wording fixes in doc
+ portions
+
+ * Makefile.in, awkscan-ip, awkscan-p, intobfd,
+ libbfd.h, libcoff.h, tolibcoff; new bfd-in.h, libbfd-in.h,
+ libcoff-in.h: (a) use separate files for invariant parts of bfd.h,
+ libbfd.h, and libcoff.h; (b) in generated parts of same, use less
+ obtrusive marks indicating .c origins.
+
+ * bfd.texinfo: generalize most references to linker
+
+Tue Aug 20 15:18:02 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * Makefile.in: include core.p in PROTOS (building better bfd.h)
+ * archures.c: remove empty foo() definition (crept in at vn1.9)
+
+Mon Aug 19 13:48:22 1991 Roland H. Pesch (pesch at cygint.cygnus.com)
+
+ * bfd.texinfo: use @setchapternewpage on instead of lots of
+ @page's; minor rephrasing in Introduction.
+
+ * aoutx.h, archive.c, archures.c, bfd.c, bfd.texinfo, cache.c,
+ coffcode.h, core.c, format.c, ieee.c, libbfd.c, libbfd.h, libcoff.h,
+ oasys.c, opncls.c, reloc.c, section.c, syms.c, targets.c (documentation
+ segments): used BFD (caps) more consistently as a name in
+ discourse, fixed a few other minor typos and uses of fonts
+
+
+Thu Aug 8 16:47:43 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * coffcode.h: fixed bug where string table size wasn't being swapped.
+
+Thu Aug 1 16:35:28 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * section.c: added SEC_CONSTRUCTOR_TEXT|DATA|BSS flags
+
+ * syms.c: added BSF_CONSTRUCTOR, BSF_WARNING and BSF_INDIRECT
+ flags. (bfd_print_symbol_vandf) now knows what to do with the
+ above flags.
+
+ * aoutx.h: made translate_from_native_sym_flags and
+ translate_to_native_sym_flags produce the above flags.
+
+
+Wed Jul 31 09:53:52 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * all files: update copyright notices for GPL version 2.
+ Install header comments and attribute most modules to their
+ authors. BFD's name is now officially "Binary File Descriptor",
+ so remove any conflicting pejoratives.
+ archures.h: Consists solely of comments; remove it.
+
+Fri Jul 26 18:11:34 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * Makefile.in, bfd.c: Made it compile again.
+
+Fri Jul 19 08:17:09 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * newsos3.c, targets.c, coffcode.h: new patches from David Wood
+
+
+Mon Jul 15 16:27:42 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * aoutf1.h archive.c bfd.c coffcode.h core.c ecoff.c ieee.c
+ bfd.texinfo oasys.c opncls.c reloc.c srec.c: More documentation on
+ lint fixes.
+
+ * amdcoff.c bfd.texinfo Makefile.in : Folded in changes for amd
+ 29k coff by David Wood (wood@lab.ultra.nyu.edu).
+
+Thu Jul 4 09:53:16 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * Everything: created some new files, core.c format.c, reloc.c,
+ section.c and syms.c to split the functionality a bit better.
+ Cleaned up the rest of the files a bit, and added some
+ documentation.
+
+
+Mon Jul 1 13:29:47 1991 David Wood (wood at david.ultra.nya.edu)
+
+ * opncls.c, ../include/sys/h-sun3.h ../include/sys/h-sun4.h: fcntl
+ really takes 3 arguments, patched code and ammended prototypes.
+
+Fri Jun 14 13:19:40 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * ../include/bfd.h (struct bfd_target): Added new field
+ "align_power_min" which contains the minimum alignment for a
+ section. This is used in coff_new_section_hook. The field
+ insertion necessitates an update of all backends..
+
+ * aoutf1.h jump table field inserted
+
+ * archive.c(snarf_ar_hdr)(bfd_slurp_coff_armap) can now parse dgux style extended
+ filenames too.
+
+ * bout.c(b_out_squirt_out_relocs) fix to assertion tests. Jump
+ table field inserted.
+
+ * coffcode.h(just about everything) Now patches up symbol tables
+ using a different mechanism. The Intel major bug has been fixed,
+ and the linker can self host on the Aviion and be debugged with
+ gdb.
+
+ * ecoff.c: new include and jump table patch, i386coff.c: new
+ include and jump table patch, icoff.c: new include and jump table
+ patch, ieee.c: can now read archives containing ieee modules.,
+ libcoff.h: added (combined_entry_type), libieee.h: uped max
+ sections to 20, m68kcoff.c: new include and jump table patch,
+ m88kbcs.c: new include and jump table patch, oasys.c: various bugs
+ fixed. opncls.c: added bfd_alloc_grow and bfd_alloc_finish.
+ srec.c: jump table patch. trad-code.c fixed #IF typeo
+
+Fri Jun 7 12:35:46 1991 Sean Fagan (sef at cygint.cygnus.com)
+
+ * coffcode.h (coff_swap_aux_in): added else case to deal with
+ filenames less than 9 characters.
+
+
+Thu Jun 6 18:27:38 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * ../include/oasys.h oasys.c (oasys_archive_p): fixed so it works
+
+ * srec.c: now allows any number of sections to be created in a
+ file. Outputs addresses of the right length.
+
+Thu May 30 15:30:10 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * bfd.c (bfd_check_format): Fixed problem where when a defaulted
+ target didn't match, the format got set to the attempted match,
+ breaking a future test.
+
+ *../include/i386coff.h : fixed typo in type field with size
+
+ * i386coff.c icoff.c m88k-bcs.c ecoff.c ../include/bfd.h : Added
+ support in the jump table for the swapping routines exported to
+ gdb. Now gdb works with the 386.
+
+Tue May 28 17:21:43 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Merge in changes from gdb-3.95 release.
+ Makefile.in: Allow hmake and tmake files to add OFILES.
+ aoutf1.h:
+ bfd.c: support specific targets as well as searching. When
+ searching, take default target in preference to others.
+ bfd.doc: typos
+ ieee.c, oasys.c: Avoid using the "tdata" macros left of assignment.
+ liba.out.h: Don't hard-code file offsets; use N_ macros for them.
+ libbfd.h: Support specific targets as well as searching.
+ opncls.c: Support specific targets as well as searching.
+ targets.c: Search is short-circuited if default target matches.
+ liboasys.c, libieee.c: Undo bothner changes that make macros
+ work to the left of assignment, but which depend on the
+ representations of different pointer types being the same.
+
+Fri May 24 18:56:52 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * i386coff.c: created.
+ * coffcode.h: added support for 386.
+ * Makefile.in: added support for 386.
+ * ../include/i386coff.h: created
+
+Wed May 22 07:26:38 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * coffcode.h: removed all put_x_<sizes>
+ * libbfd.c: Changed #ifdef __GNUC__ to #ifdef HOST_64_BIT, Added
+ DEFUNS
+
+
+Tue May 21 08:58:58 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+ (bothner)
+ * opncls.c: Changed obstack_chunk_alloc use xmalloc
+
+Mon May 20 17:12:17 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * everything: Removed sysdep.h from bfd.h and put back into files
+ from which it was split out. Now 64 bit version is built with a
+ -DHOST_64_BIT="long long" on the compile line.
+
+Fri May 17 19:35:26 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ Changed all the [get|put][name] routines to use [get|put]_[size
+ in bytes].
+
+ Put in support for 64 bit work. Now two versions of bfd may be
+ generated, according to the state of TARGET_64_BIT, one which is
+ 32 bit only, and one which is 64/32 bits.
+ Created new back end 'demo64' to test 64 bit functionality.
+
+ Renamed some files to work on DOS.
+
+ * archive.c: lint * bfd.c: prototypes and lint. * ecoff.c: added
+ 64bit transfer * icoff.c: added 64bit transfer * ieee.c: name
+ chage, 64 bit transfer. * liba.out.h: Split out common code from
+ sunos and newsos into liba.out. Name changes and prototype mods. *
+ libbfd.c: lint and prototypes, extra 64bit swaps. * libbfd.h:
+ prototypes for new functions. * libcoff.h: lint * libieee.h: make
+ work on DOS * liboasys.h: make work on DOS * m88k-bcs.c: Name
+ change and 64bit stuff.* newsos3.c: common code removed, new jump
+ table. * oasys.c: Name change * opncls.c: Portability fixes *
+ srec.c: Name changes * sunos.c: Removed comon code. * targets.c:
+ Added demo * aout32, aout64.c include aoutx.h * bout.c: used to
+ be called b.out.c * coffcode.h: used to be called coff-code.h, now
+ 64bit ized. * demo64.c: 64 bit a.out back end
+
+Thu May 16 16:02:07 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+ from bothner
+ * libieee.h: Make ieee_data and ieee_ar_data macros usable
+ on LHS of assignment, even when using old compilers.
+ * liboasys.h: Ditto for oasys_data and oasys_ar_data.
+ * m68kcoff.c: Add enum-to-int casts to accomodate old compilers.
+ * newsos3.c: Fix definitions of SEGMENT_SIZE and TEXT_START_ADDR.
+ * opncls.c: Define S_IXUSR, S_IXGRP, S_IXOTH if undefined.
+ * targets.c: Add declaration of newsos3_vec.
+
+Mon May 13 10:03:29 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * aout.c: fixxed some of the problems with filepos calculation.
+ (swap_ext_reloc): fixed problem with creation of relocs.
+ (aout_set_section_contents): fixed filepos problem
+
+ * coff-code.h: (swap_filehdr_in, swap_filehdr_out) add.
+ (swap_filehdr) delete. Changed all the usage of bfd_h_put_x.
+ (swap_aouthdr_in, swap_aouthdr_out) add. (swap_aouthdr) delete.
+ (coff_real_object_p) cleaned up, added MIPS. (coff_object_p)
+ cleaned up. (coff_write_object_contents) cleaned up.
+
+ * ecoff.c: Totally different. Now supports ecoff fully.
+
+ * icoff.c: fixed problems in relocation callout.
+
+ * libcoff.h: (struct icofdata) removed hdr structure from tdata.
+
+ * m68kcoff.c: updated target vector.
+
+ * sunos.c: (choose_reloc_size) added: (sunos4_callback) calls
+ choose_reloc_size. (sunos4_write_object_contents) now calls
+ choose_reloc_size so outputs relocs correctly, also calculates the
+ size of the sections correctly.
+
+
+
+Fri May 10 16:58:53 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Merge Per Bothner's changes to modularize BFD a.out a bit.
+
+ * libbfd.h, libbfd.c (bfd_generic_get_section_contents): Add.
+ * ieee.c: Cast enums to int before comparing them, for brain-
+ dead compilers.
+ * coff-code.h: Remove coff_get_section_contents, and use the
+ generic one instead.
+
+ * aout.c: Derive new module from sunos.c, containing generic
+ support code for all kinds of a.out files.
+
+ * sunos.c: Remove all code that goes in aout.c. Split out
+ machine dependent followup in sunos4_object_p into
+ sunos4_callback. Use JUMP_TABLE(aout) for the transver vector,
+ and redefine only the names we CHANGE, not all the names. Drop
+ the little-endian vector, and rename the vector as sunos4 rather
+ than generic.
+
+ * b.out.c: Use aout.c routines for most of the work. Slight
+ changes for the new regime. Remove close_and_cleanup and
+ get_section_contents in favor of generics. New transfer vector
+ regime.
+
+ * newsos.c: New support for Sony NEWS, another a.out format.
+
+ * ecoff.c: Remove close_and_cleanup. New tvec regime.
+ * icoff.c, m88k-bcs.c: Add write_contents to tvec.
+ * ieee.c, oasys.c: Remove close_and_cleanup, add write_contents
+ to tvec.
+ * opncls.c (bfd_close): Call format-dependent write_contents
+ routine, if writing, before calling target-dependent
+ close_and_cleanup routine (which is now always generic, I think).
+ * srec.c: Use bfd_alloc instead of malloc. Remove
+ close_and_cleanup and move code from it to
+ srec_write_object_contents. Add write_contents to tvec.
+ * targets.c: Remove a.out little vector, replace a.out big
+ vector with SunOS vector. FIXME: Need Vax support again now.
+
+ * libbfd.h: Add write_contents format-dependent-vector to the
+ bfd_target vector. Supply a generic close_and_cleanup routine.
+ * liba.out.h: Handle the new aout.c split. Add prototypes for
+ all routines defined in aout.c. Rename "sunos" things to "aout"
+ things. Add a few fields where needed for various formats.
+ * Makefile.in: Add aout.c and newsos.c.
+
+ * archive.c, ieee.c, oasys.c: Lint.
+
+Fri May 10 12:34:48 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * ../include/bfd.h
+ changed forward declaration struct stat; to reduce warnings. Changed
+ comment on bfd_h_<x>_x.
+
+ * ../include/m68kcoff.h, ../include/intel-coff.h,
+ ../include/m88k-bcs.h
+ Now there are two incarnations of relocs, linenos and syments. One for
+ internal digestion, and one full of char arrays for I/O. The original
+ names have gone to detect errors.
+
+ * Makefile.in, m68kcoff.c, targets.c
+ Test new structure code with a 68k coff implementaion
+
+ * coff-code.h, icoff.c, coffswap.c, libcoff.h
+ Fixed all the places where there were problems with the size and
+ alignments of structures on disk and structures in memory. #ifed out
+ all the code in coffswap.c, since it should be done using the target
+ swap routines now.
+
+Thu May 9 11:00:45 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * ieee.c (do_one, ieee_slurp_section_data): now supports the load
+ multiple reloc command.
+
+ * sunos.c (sunos4_set_section_contents): Made it so that sections
+ are always padded to their alignment size.
+
+Sat May 4 15:49:43 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * archive.c, bfd.c, coff-code.h, opncls.c, sunos.c, trad-core.c:
+ Clean up types and such (saber C problems).
+ * ecoff.c: Clean up types and such. Remove routines that are
+ not used. Fix up reading and swapping of shorts from files.
+
+ Notes on bfd-0.5.2-patch1a, from Per Bothner:
+
+ * a.out.vax.c: Remove two bogus "static" from prototypes.
+
+ * ecoff.c: Got rid of lots of non-working junk (that had
+ been copied directly from coff-code.h).
+ Updated to be consistent with updates to icoff.c and coff-code.h.
+
+ * libbfd.h: Added definitions for S_IXUSR, S_IXGRP, and S_IXOTH
+ if they're missing (as they are in (BDS-4.3-based) NewsOS-3).
+
+ * sunos.c (n_txtoff): (Re-)Add support for sony. This is a kludge,
+ but until the target_vector is automatically generated,
+ it's as good as any. Note that the text offset is the only
+ difference between NewsOS and SunOs (including magic numbers).
+ (Most of the sunos_* routines should to renamed bsd_*
+ and move to a bsd.c file. Then (and when the target_vector
+ is automatically generated) it might make sense to create
+ a separate Sony target.)
+
+ * sysdep.h: Don't declare fread and fwrite. Causes trouble
+ on some systems, and doesn't help on others.
+ Similarly, only define X_OK if not already defined.
+
+ * trad-core.c: Don't include sys/stat.h - at least
+ on NewsOS 3, it has already been included.
+
+Tue Mar 5 01:47:57 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * coff-code.h (bfd_coff_swap_sym, bfd_coff_swap_aux,
+ bfd_coff_swap_lineno): Export the routines that byte-swap COFF
+ symbol tables if necessary when reading them in, so gdb can use
+ them. Add "bfd_coff_" to the names so they won't conflict with
+ names in calling programs. FIXME-soon: if coff-code.h is
+ included in two BFD modules, this will cause duplicate
+ definitions; the routines should be exported to a separate,
+ common, module (probably along with a mess of other ones).
+
+Sat Mar 2 12:11:26 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Improve modtime support.
+
+ * bfd.h: Add boolean mtime_set, and declare bfd_get_mtime.
+ Remove #define for bfd_get_mtime. Remove gratuitous comment.
+ * bfd.c (bfd_get_mtime): New fn, caches mtime, gets if not cached.
+ BUG: archive members still do not get correct mod times.
+
+ Improve floating point support for core files.
+
+ * sunos.c (struct core): Change void *fpa_dummy to double fp_stuff.
+ (sunos4_core_file_p): Create a second registers section in the
+ core file, called ".reg2", for the float registers.
+
+Thu Feb 14 15:49:06 1991 Gumby Vinayak Wallace (gumby at cygint.cygnus.com)
+
+ * many changes to improve archive handling; found a logic flaw in
+ bfd_check_format which only just happened to work by cooncidence.
+
+Thu Feb 14 07:53:16 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * bfd.c (bfd_perform_relocation): fixed to use output_offsets
+ correctly.
+
+ * bfd.h: changed type of udata in asymbol to void *, like it
+ should be. Added bfd_reloc_dangerous enum member.
+
+ * coff-code.h: Fixed it so that internally generated symbols get
+ their values relocated correctly in all cases. Removed calls to
+ xmalloc.
+
+ * icoff.c: Not understanding the destination symbol of a reloc is
+ not a failure any more, just 'dangerous'. This allows linking of
+ b.out and coff images.
+
+ * sunos.c: Cleaned up the way that ZMAGIC section sizes are
+ calculated.
+
+
+Tue Feb 12 13:25:46 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * sunos.c (translate_to_native_sym_flags): fixed
+ sym_pointer->n_value so that symbols on the way out get their
+ section relative values calculated correctly.
+
+ * coff-code.h (mangle_symbols): fixed problem where tags were not
+ being relocated for structs, enums, unions. Also various lints.
+
+Mon Feb 11 19:52:26 1991 Gumby Vinayak Wallace (gumby at cygint.cygnus.com)
+
+ * archive.c (get_elt_at_filepos): system_call_error returned
+ incorrectly.
+
+Sun Feb 10 23:18:40 1991 Gumby Vinayak Wallace (gumby at cygint.cygnus.com)
+
+ * Resolve the use of no_error and system_call_error.
+ The bfd library itself now will never set bfd_error to
+ no_error.
+
+ The code still needs to be combed to make sure all the error
+ codes are correct. I suspect they are not always set correctly.
+
+ * The names of all the messages have _ prepended because the sun
+ bundled compiler can't distinguish from a macro which takes an
+ argument and the same identifier in a non-macro context.
+
+ * The reason for the above being that entry points which used to
+ be trampoline functions are now just macros which expand to a
+ direct call through the bfd's xfer vector.
+
+ * (../include/intel-coff.h) F_AR32WR: fix this constant. Why
+ must gas have its own version of everything (the gas version
+ had the correct value)
+
+Tue Feb 5 11:46:53 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ * b.out.c: Added patches supplied by chrisb@mipon2.intel.com to
+ properly support i960 architecture and output correct reloc stuff.
+
+ * bfd.h: added prototype for bfd_printable_arch_mach, added
+ BFD_FAIL
+
+ * coff-code.h: Applied patches from chrisb to support i960
+ architecture, zero relocs and swap them correcly and conditionally
+ compiled the timestamp.
+
+ * sunos.c: Made the default section alignment 2^3 so that doubles
+ are done properly. Fixed the same reloc bug that was in b.out.c
+
+ * sysdep.h: Now compiles on a Posix box
+
+Wed Jan 30 21:36:26 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * icoff.c: Fix comment on big-endian version.
+ * coff-code.h: Make HAS_RELOC really work (it's backwards from
+ F_RELFLG). Set F_AR32WR in output files if little endian
+ architecture.
+
+Tue Jan 29 20:56:10 PST 1991 steve@cygnus.com
+
+ * archures.c fixed =/== typo
+
+ * sunos.c added architecture stuff for output. Fixed
+ bug where files where vma(data) != size(text)
+ were processed wrong.
+
+ * coff-code.h added a lint cast
+
+ * (../include/a.out.sun4.h) fixed it so zmagic
+ worked
+
+Mon Jan 28 19:15:29 PST 1991 steve@cygnus.com
+
+ * archive.c removed loads of includes, and fixed bug where string
+ table didn't have a null at the end.
+
+ * bfd.c fixed includes, added symbols argument to
+ canonicalize_reloc entry point.
+
+ * libbfd.c fixed includes and added some lint patches.
+
+ * targets.c added both sorts of intel coff.
+
+ * b.out.c fixed included, changed was the canonical
+ relocs were done.
+
+ * icoff.c added support for callj and big and little
+ enidian tables.
+
+ * opncls.c added chmod+xing for files with EXEC_P set.
+
+ * sunos.c fixed includes. Changed default section
+ alignement to words. Fixed relocation stuff to work with
+ new scheme
+
+ * bfd.h various new types added, prototype for new
+ reloc calls, changed bfd->iostream to a void *
+ to including files don't need stdio.h.
+
+ * libcoff.h added conversion table to tie relocs to
+ canonical symbols
+
+ * sysdep.h created
+
+ * coff-code.h fixed includes. Added code to support
+ big and little endian formats. Various lints. Better
+ processing of symbols. Changed reloc stuff to new
+ order
+
+ * libbfd.h fixed includes
+
+
+Mon Jan 21 11:53:51 PST 1991 steve@cygnus.com
+
+ * bfd.h changed name of alignment entry in sec_struct to
+ alignment_power, because of conflicting uses within bfd.
+ Now it should be obvious that it's a 2**n alignment
+ specifier. Removed start_pad, end_alignment, block, minsize,
+ output_file_alignment, subsection_alignment and original_vma fields.
+ Added align_power() macro. Fixed bfd_section_alignment
+ acessor macros. Added bfd_symbol_same_target macro.
+
+ * b.out.c (b_out_write_object_contents) fixed to use
+ new alignment member. Fixed (callj_callback) to use section
+ relative symbols properly.
+
+ * sunos.c (sunos4_object_p) fixed to use new alignment_power.
+ Fixed (translate_from_native_sym_flags) to correctly make
+ symbols section relative.
+
+ * bfd.c (bfd_errmsg) fixed various enum cast problems.
+ (bfd_make_section) took out initialization of obsolete members.
+ (bfd_print_symbol_vandf) added
+
+ * opncls.c (bfd_create) created.
+
+ * coff-code.h (coff_new_section_hook) took away refs
+ to obsolete members. (make_a_section_from_file) added
+ conversion between alignment types. (coff_symbol_from)
+ added. (coff_count_linenumbers) only counts linenumbers
+ if symbol is of coff-type. (coff_mangle_symbols) only
+ heavily mangles symbols if symbol is coff-type.
+ (coff_write_symbols) various lints. (coff_write_object_contents)
+ various lints and modification for alignment conversion.
+ (coff_slurp_relocs) fixed for use with new asection shape.
+
+Sat Jan 19 16:10:42 PST 1991 steve@cygnus.com
+
+ * archive.c lots of lint
+
+ * b.out.c added callj relocation support, upgrated reloc howto.
+ Fixed so that asymbol and reloc records are output
+ correctly.
+
+ * bfd.c lots of lint, support for new bfd entry point
+ bfd_print_symbol.
+
+ * bfd.h changed definition of asymbol to contain pointer to
+ owning bfd, removed target dependencies.
+
+ * cache.c took out print statements, put in BFD_ASSERT calls.
+
+ * coff-code.h various lints, corrected linenumber output
+ functionality. Added support for new style asymbols and
+ bfd_print_symbol. Fixed so that asymbol and
+ reloc records are handled correctly. Added timestamp.
+
+ * icoff.c Added support for new howto shape.
+
+ * liba.out.h Added support for new asymbol shape
+
+ * libbfd.c various lints
+
+ * libbfd.h various lints
+
+ * libcoff.h added support for new asymbol shape.
+
+ * sunos.c various lints. Added support for new asymbol shape
+ and bfd_print_symbol.
+
+Wed Jan 16 21:38:09 PST 1991 steve@cygnus.com
+
+ * b.out.c removed prototype of sunos4_ennativate_symtab, lots of
+ pointer lint. Added support for callj relocation. Fixed bug where
+ the last 32 bytes of the text section were overwritten by data. Fixed bug
+ where archives of b.out didn't work due bfd_slurp_extended_name_table
+ returning false.
+
+ * sunos.c added support for n_other field. Braced the howto table so
+ that it won't be affected by any lengthing of the howto struct typedef.
+ Various lints
+
+ * bfd.h added support for n_other field, added special_function
+ reloc type, modified bfd_perform_relocation prototype. Added bfd_h_get_x
+ macros.
+
+ * bfd.c upgraded bfd_perform_relocation, various lints.
+
+Wed Jan 16 01:55:53 1991 John Gilmore (gnu at rtl)
+
+ * ChangeLog: Started ChangeLog for BFD.
+ * ToDo: Create file for suggestions.
+
+ * Makefile: Support easy loading into Saber C.
+ Add dependencies for icoff.o and bcs88kcoff.o.
+ Rename coff.c to coff-code.h. Change callers.
+
+ * bfd.c (bfd_check_format): Allow the check_format routines
+ to return the desired target vector, rather than just a Boolean.
+ bfd.h (bfd_check_format): Change function pointer return type.
+ archive.c (bfd_generic_archive_p): change callee.
+ b.out.c (b_out_little_object_p, b_out_big_object_p,
+ b_out_real_object_p): change callee.
+ libbfd.c (_bfd_dummy_target): Dummy routine replacing bfd_false
+ in check_format transfer vectors that need a filler.
+ libbfd.h (bfd_generic_archive_p, _bfd_dummy_target): Fix decls.
+ bcs88kcoff.c: change callee.
+ coff-code.h (coff_real_object_p, coff_big_object_p): change callee.
+ icoff.c: change callee.
+ sunos.c (sunos4_object_p, sunos4_core_file_p): change callee.
+
+ * libbfd.c (zalloc): It should actually zero the storage!
+ This was commented out for some reason.
+
+ * libbfd.h: Add malloc, xmalloc, memcpy, and fatal decls.
+ This is so callers can avoid <stdlib.h> which doesn't exist
+ on older systems.
+
+ * bfd.c (map_over_sections): Add debugging code, since I
+ noticed the section count for sunos core files was bad, but only
+ GDB had detected the problem.
+ (bfd_set_section_lineno_size, bfd_set_section_linenos,
+ bfd_get_section_linenos): Remove obsolete functions.
+ (bfd_apply_relocations): Use longs, not ints, for the math.
+
+ * bfd.h: Declare enum boolean and struct bfd_target as well
+ as typedefs for them. Remove obsolete
+ bfd_get_section_lineno_size.
+
+ * cache.c: Make the "fdopen" support work. Keep better track
+ of how many files are open. Centralize the opening of files
+ and be sure bfd_open[rw] actually try to open the file. Evade
+ linked list initialization problems.
+
+ * b.out.c, coff-code.h, opncls.c, sunos.c: lint.
+
+ * coff-code.h (coff_slurp_symbol_table): Null-terminate symtab names.
+
+ * cplus-dem.c: Delete file, since it is not part of BFD.
+
+ * opncls.c (bfd_openr): Eliminate misplaced #if 0 code.
+ (bfd_openr, bfd_openw): Actually open the file, give error now.
+
+ * sunos.c (sunos4_core_file_p): Set section count.
+ (sunos4_set_section_linenos, stab_names, fprint_name): Eliminiate
+ obsolete definitions.
+ (_write_symbol_table): Initialize <idx> counter.
+ (foop): Eliminate debugging code.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-9495 b/bfd/ChangeLog-9495
new file mode 100644
index 00000000000..9868583cb4b
--- /dev/null
+++ b/bfd/ChangeLog-9495
@@ -0,0 +1,10043 @@
+Thu Dec 21 12:43:49 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Add a phony reloc to handle the
+ old style TOC16 references without using R_PPC_GOT.
+ (ppc_reloc_type): Ditto.
+ (ppc_elf_reloc_type_lookup): Add support for TOC16.
+ (ppc_elf_toc16_inner): Renamed from ppc_elf_got16_inner.
+ (ppc_elf_toc16_reloc): Renamed from ppc_elf_toc16_reloc.
+ (ppc_elf_got16_{inner,reloc}): Stubs for real GOT support.
+ (ppc_elf_check_relocs): New function for GOT/PLT support that is
+ work in progress.
+ (ppc_elf_adjust_dynamic_symbol): Ditto.
+ (ppc_elf_adjust_dynindx): Ditto.
+ (ppc_elf_size_dynamic_sections): Ditto.
+ (ppc_elf_finish_dynamic_symbol): Ditto.
+ (ppc_elf_finish_dynamic_sections): Ditto.
+ (ELF_DYNAMIC_INTERPRETER): Define.
+
+Wed Dec 20 19:14:18 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * elf.c (copy_private_bfd_data): When attaching sections to
+ segments ignore sections that won't be allocated. Patch from
+ Andreas Schwab.
+
+Tue Dec 19 20:01:43 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config.bfd: Match on m68k-cbm-* only if OS doesn't match
+ anything else.
+
+Tue Dec 19 16:38:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i960.c (CALC_ADDEND): Define.
+ (coff_i960_relocate_section): Add the input section VMA to the
+ addend for PC relative relocs.
+
+Sun Dec 17 20:11:55 1995 Kim Knuttila <krk@cygnus.com>
+
+ * peicode.h (pe_print_pdata): Must test the entire entry for zero
+ to correctly terminate.
+
+Fri Dec 15 12:05:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * targets.c (enum bfd_endian): Define.
+ (bfd_target): Rename byteorder_big_p to byteorder, and change it
+ from boolean to enum bfd_endian. Change header_byteorder_big_p
+ correspondingly.
+ * bfd-in.h (bfd_big_endian, bfd_little_endian): New macros.
+ (bfd_header_big_endian, bfd_header_little_endian): New macros.
+ * bfd-in2.h: Rebuild.
+ * All targets: Change initialization of byteorder and
+ header_byteorder to use enum bfd_endian values rather than
+ booleans.
+ * All files: Change all references to byteorder_big_p and
+ header_byteorder_big_p to use new bfd_*_endian macros.
+
+ * coffgen.c (make_a_section_from_file): Set lma to s_paddr, not
+ s_vaddr.
+ * coffcode.h (coff_write_object_contents): Set s_paddr to lma, not
+ vma.
+ * ecoff.c (_bfd_ecoff_write_object_contents): Likewise.
+
+Fri Dec 15 07:32:09 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * pe[i]-i386.c (TARGET_UNDERSCORE): Define to '_'.
+
+Thu Dec 14 13:45:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: Lots of minor cleanups. Make many functions return
+ errors rather than calling abort. Also:
+ (ieee_write_twobyte): Remove; change callers to call existing
+ ieee_write_2bytes function.
+ (ieee_write_expression): Don't output the section twice when
+ outputting a local symbol. Don't emit an extraneous zero if there
+ is only one term.
+ (ieee_slurp_sections): Set the lma as well as the vma.
+ (ieee_archive_p): Use bfd_alloc_grow rather than an obstack.
+
+ * ihex.c (ihex_set_arch_mach): Don't accept any architecture, just
+ a recognized one or bfd_arch_unknown.
+ (ihex_get_symtab_upper_bound): Define as bfd_0l, to permit objcopy
+ to succeed.
+ (ihex_get_symtab): Likewise.
+
+Wed Dec 13 15:44:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h: Include <ctype.h>.
+ (struct aout_link_includes_table): Define.
+ (struct aout_link_includes_totals): Define.
+ (struct aout_link_includes_entry): Define.
+ (aout_link_includes_lookup): Define macro.
+ (struct aout_final_link_info): Add includes field.
+ (aout_link_includes_newfunc): New static function.
+ (NAME(aout,final_link)): Initialize includes hash table.
+ (aout_link_write_symbols): Eliminate duplicate N_BINCL entries.
+
+Wed Dec 13 10:52:14 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Match on mips-*-* instead of mips-idt-ecoff.
+
+Wed Dec 13 11:07:45 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (coff_ppc_relocate_section): removed debugging code.
+
+Tue Dec 12 17:42:06 1995 Kim Knuttila <krk@cygnus.com>
+
+ * peicode.h (pe_print_reloc): New function to dump the .reloc section.
+ (pe_print_private_bfd_data): call pe_print_reloc.
+ * coffcode.h (coff_set_alignment_hook): .reloc section alignment.
+ * coff-ppc.c (in_reloc_p): Added missing non-eligible relocs. Spiffed
+ up some debugging as well.
+
+Tue Dec 12 11:34:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.bfd: Handle sparc-*-elf*. From Ronald F. Guilmette
+ <rfg@monkeys.com>.
+
+Fri Dec 8 17:47:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Set section_count to 0
+ when setting sections to NULL.
+
+Wed Dec 6 17:05:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (struct xcoff_loader_info): Add export_defineds
+ field.
+ (bfd_xcoff_size_dynamic_sections): Add export_defineds parameter.
+ (xcoff_build_ldsyms): If export_defineds is set, set XCOFF_EXPORT
+ for all symbols.
+ * bfd-in.h (bfd_xcoff_size_dynamic_sections): Update declaration.
+ * bfd-in2.h: Rebuild.
+
+Mon Dec 4 16:40:47 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coffcode.h (coff_set_alignment_hook): Removed some debugging printf's
+
+Mon Dec 4 11:25:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ihex.c (ihex_scan): Handle record types 4 and 5.
+ (ihex_object_p): Permit types 4 and 5.
+ (ihex_set_section_contents): Remove check for out of range
+ addresses.
+ (ihex_write_object_contents): Generate types 4 and 5.
+
+ * elflink.h (elf_link_output_extsym): Just ignore warning and
+ indirect references to symbols which don't really exist.
+
+Sun Dec 3 19:00:27 1995 Kim Knuttila <krk@cygnus.com>
+
+ * peicode.h (pe_print_idata): Minor format fixes
+ (pe_print_edata): New function. Under private printing, this formats
+ the edata section of a PE file.
+ (pe_print_private_bfd_data): Added call to pe_print_edata.
+
+Sun Dec 3 16:46:54 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * aout-arm.c (MY_swap_std_reloc_out): Use KEEPIT to get the symbol
+ index, don't call stoi.
+
+Fri Dec 1 14:46:51 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * srec.c (srec_scan): Set lma as well as vma.
+
+ * ihex.c: New file; support for Intel Hex format.
+ * targets.c (enum bfd_flavour): Add bfd_target_ihex_flavour.
+ (ihex_vec): Declare.
+ (bfd_target_vector): Always include ihex_vec.
+ * bfd.c (struct _bfd): Add ihex_data field to tdata union.
+ * Makefile.in: Rebuild dependencies.
+ (BFD_LIBS): Add ihex.o
+ (BFD_LIBS_CFILES): Add ihex.c.
+ * bfd-in2.h: Rebuild.
+
+ * elf.c (assign_file_positions_for_segments): Sort the sections in
+ each segment.
+ (get_program_header_size): Return the right size if segment_map is
+ not NULL.
+ (copy_private_bfd_data): Don't bother to sort the sections.
+
+ * bfd.c (bfd_record_phdr): New function.
+ * bfd-in.h (bfd_record_phdr): Declare.
+ * bfd_in2.h: Rebuild.
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Remove bogus
+ BFD_ASSERT.
+
+ * libbfd.c (bfd_malloc, bfd_realloc): New functions.
+ (bfd_zmalloc): Return PTR, not char *. Take size_t, not
+ bfd_size_type.
+ * libbfd-in.h (bfd_malloc, bfd_realloc): Declare.
+ (bfd_zmalloc): Change declaration.
+ * libbfd.h: Rebuild.
+ * Many files: Use bfd_malloc and bfd_realloc rather than malloc
+ and realloc. Don't set bfd_error_no_memory if they fail.
+
+Thu Nov 30 19:32:26 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c: Added macros to tidy up toc cell treatment. Numerous
+ uses as well. Added a new howto to deal with TOCREL16 relocs that
+ are TOCDEFN as well.
+ (coff_ppc_relocate_section): Expanded treatment of ADDR32NB relocs
+ to handle RVA relocs from dlltool.
+ (ppc_coff_rtype2howto): TOCDEFN reloc addition.
+ (coff_ppc_rtype_to_howto): TOCDEFN reloc addition.
+ (ppc_coff_reloc_type_lookup): TOCDEFN reloc addition.
+
+ * coffcode.h (coff_set_alignment_hook): check idata$X sections
+ to get the right section alignment.
+
+Thu Nov 30 16:48:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Don't set lma based on
+ p_paddr if p_paddr is zero.
+ (make_mapping): Set includes_filehdr and includes_phdrs for first
+ PT_LOAD segment.
+ (map_sections_to_segments): Set includes_phdrs for PT_PHDR
+ segment.
+ (assign_file_positions_for_segments): Handle includes_filehdr and
+ includes_phdrs. Remove special handling of PT_PHDR and first
+ PT_LOAD segments.
+ (copy_private_bfd_data): Set includes_filehdr and includes_phdr
+ when appropriate. Remove special handling of PT_PHDR segment.
+ Use a more complex condition for when a section is included in a
+ segment to handle Solaris linker oddities.
+
+Thu Nov 30 11:17:33 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * coff-m88k.c (howto_table): Reformatted for easier reading;
+ special_function now points to new function m88k_special_reloc.
+ (howto_hvrt16): Function previously used for handling HVRT16 relocs
+ removed.
+ (rtype2howto): Do not add reloc's r_offset to the addend, this will
+ be done correctly by m88k_special_reloc.
+ (reloc_processing): New function to be used by RELOC_PROCESSING.
+ (RELOC_PROCESSING): Define to call reloc_processing.
+
+Wed Nov 29 12:42:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (pe_print_idata): Call malloc rather than xmalloc.
+ (pe_print_pdata): Likewise.
+
+ * opncls.c (bfd_alloc_by_size_t): Set bfd_error_no_memory if
+ obstack_alloc fails.
+ (bfd_alloc_finish): Set bfd_error_no_memory if obstack_finish
+ fails.
+ * libbfd.c (bfd_zmalloc): Set bfd_error_no_memory if malloc fails.
+ * Many files: don't set bfd_error_no_memory if one of the above
+ routines fails.
+
+ * elf.c (assign_file_positions_for_segments): Don't adjust p_paddr
+ if p_paddr_valid is set.
+ (copy_private_bfd_data): New static function.
+ (_bfd_elf_copy_private_section_data): Call copy_private_bfd_data.
+
+ * elf.c (assign_file_positions_for_segments): Fix case where extra
+ program headers were allocated.
+
+ * elf.c (_bfd_elf_print_private_bfd_data): New function.
+ * elf-bfd.h (_bfd_elf_print_private_bfd_data): Declare.
+ * elfxx-target.h (bfd_elfNN_bfd_print_private_bfd_data): Define to
+ _bfd_elf_print_private_bfd_data.
+
+ * coff-alpha.c (alpha_ecoff_swap_reloc_in): Don't abort if
+ r_symndx is RELOC_SECTION_NONE for an ALPHA_R_IGNORE reloc.
+ Change a RELOC_SECTION_LITA symndx to RELOC_SECTION_ABS.
+ (alpha_ecoff_swap_reloc_out): Change RELOC_SECTION_ABS to
+ RELOC_SECTION_LITA for ALPHA_R_IGNORE.
+ (alpha_adjust_reloc_out): For ALPHA_R_IGNORE, don't change
+ RELOC_SECTION_ABS to RELOC_SECTION_NONE.
+
+Tue Nov 28 16:59:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Add segment_map field.
+ * elf.c (make_mapping): New static function.
+ (map_sections_to_segments): New static function.
+ (elf_sort_sections): New static function.
+ (assign_file_positions_for_segments): New static function.
+ (map_program_segments): Remove.
+ (get_program_header_size): Remove sorted_hdrs, count, and
+ maxpagesize parameters. Simplify.
+ (assign_file_positions_except_relocs): When generating an
+ executable, use assign_file_positions_for_segments.
+ (elf_sort_hdrs): Remove.
+ (_bfd_elf_sizeof_headers): Remove eliminated parameters from call
+ to get_program_header_size.
+
+Mon Nov 27 12:27:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * hp300hpux.c (MY(callback)): Set lma as well as vma.
+
+ * configure, config.in: Regenerate with autoconf 2.7.
+
+ * elf32-i386.c (elf_backend_plt_readonly): Set correctly, to 1.
+ * elf32-sparc.c (elf_backend_plt_readonly): Set correctly, to 0.
+
+Wed Nov 22 12:02:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_new_section_hook): Handle .rconst section.
+ (ecoff_sec_to_styp_flags): Likewise.
+ (_bfd_ecoff_styp_to_sec_flags): Handle STYP_RCONST.
+ (ecoff_set_symbol_info): Handle scRConst.
+ (ecoff_slurp_reloc_table): Handle RELOC_SECTION_RCONST.
+ (ecoff_compute_section_file_positions): Handle .rconst section.
+ (_bfd_ecoff_write_object_contents): Likewise.
+ (ecoff_link_check_archive_element): Handle scRConst.
+ (ecoff_link_add_externals): Likewise.
+ (ecoff_link_write_external): Handle .rconst section.
+ (ecoff_reloc_link_order): Likewise.
+ * ecofflink.c (bfd_ecoff_debug_accumulate): Handle scRConst.
+ * coff-alpha.c (alpha_convert_external_reloc): Handle .rconst
+ section.
+ (alpha_relocate_section): Handle RELOC_SECTION_RCONST.
+
+ * sunos.c (sunos_scan_dynamic_symbol): Only set written if the
+ DEF_DYNAMIC flag is set.
+
+Tue Nov 21 13:25:29 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * host-aout.c: If TRAD_HEADER is defined, include it.
+
+Tue Nov 21 13:03:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4 (AC_PROG_CC): Remove local definition.
+ (BFD_BINARY_FOPEN): Require AC_CANONICAL_SYSTEM.
+ (BFD_NEED_DECLARATION): New function.
+ * configure.in: Use BFD_NEED_DECLARATION.
+ * acconfig.h: Put NEED_DECLARATION_* in @TOP@ section.
+ * configure, config.in: Rebuild with autoconf 2.6.
+
+ * xcofflink.c (bfd_xcoff_size_dynamic_sections): Clear
+ special_sections before returning when called with a non XCOFF
+ BFD.
+
+ * coffgen.c (coff_renumber_symbols): Sort common symbols with
+ global symbols.
+
+ * coffcode.h (coff_compute_section_file_positions): Only pad the
+ previous section to force file alignment when creating an
+ executable.
+
+Mon Nov 20 14:54:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_compute_section_file_positions): If
+ RS6000COFF_C, set up the .debug section.
+
+ * xcofflink.c (xcoff_link_input_bfd): Adjust the TOC anchor value
+ if it is not large enough to accomodate the entire TOC area with
+ signed 16 bit offsets.
+ (xcoff_write_global_symbol): Handle negative TOC offsets in global
+ linkage code.
+ (_bfd_ppc_xcoff_relocate_section): Adjust relocations against a
+ TOC anchor to use the TOC value used in the output file.
+
+Sat Nov 18 18:01:41 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgen.c (_bfd_coff_get_external_symbols): Cast malloc return.
+ (_bfd_coff_read_string_table): Likewise.
+
+Sat Nov 18 19:43:04 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * pe-arm.c: Fix typos.
+ * coff-arm.c: Likewise.
+
+Fri Nov 17 16:22:04 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (list_ele): Added "cat"egory member.
+ (record_toc): New category parameter (priv or pub).
+ (ppc_record_toc_entry): Check to see if toc bounds exceeded.
+ (ppc_process_before_allocation): Removed embrionic data-in-toc from
+ the mainline. It addes extra toc cells in error.
+ (ppc_coff_swap_sym_in_hook): Added some documentation.
+ (dump_toc): Can now diagnose "virtual toc" chicanery.
+
+Fri Nov 17 10:41:25 1995 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * elf-bfd.h (struct elf_link_hash_table): Change type of
+ dynsymcount and bucketcount fields from size_t to bfd_size_type.
+
+Fri Nov 17 10:02:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_pointerize_aux_hook): I960 version: don't
+ pointerize C_LEAFSTAT or C_LEAFEXT entries.
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Only create
+ DT_INIT and DT_FINI entries if the _init or _fini symbol is
+ defined or mentioned in a regular file.
+
+Thu Nov 16 15:16:42 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (ppc_record_data_in_toc_entry): new function
+ (coff_ppc_relocate_section): Handle TOCDEFN attribute
+ (coff_ppc_relocate_section): Correct REL24 handling
+ (ppc_process_before_allocation): Correct TOCDEFN handling
+
+ * peicode.h (dir_names): Added name descriptions
+
+Thu Nov 16 03:38:03 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * VERSION: Updated to cygnus-2.6.
+
+Wed Nov 15 19:30:07 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * targets.c (m68k4knetbsd_vec): Declare.
+
+Wed Nov 15 18:05:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * targets.c (bfd_target): Change type of second argument to
+ _bfd_print_private_bfd_data from void * to PTR.
+ * libbfd-in.h (_bfd_generic_bfd_print_private_bfd_data): Cast
+ using PTR rather than void *.
+ * bfd-in2, libbfd.h: Rebuild.
+ * peicode.h (pe_print_private_bfd_data): Change vfile from void *
+ to PTR.
+ * elfxx-target.h (bfd_elfNN_bfd_print_private_bfd_data): Define as
+ _bfd_generic_bfd_print_private_bfd_data rather than casting
+ bfd_true.
+
+Wed Nov 15 04:09:14 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (.dep1): Fix stupid typo in last change. Remove any
+ "DO NOT DELETE" lines or blank lines that mkdep writes on some
+ systems.
+ (BFD_LIBS_CFILES, ALL_MACHINES_CFILES, BFD32_BACKENDS_CFILES,
+ BFD64_BACKENDS_CFILES): New variables.
+ (CFILES): Use them.
+
+Tue Nov 14 11:52:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (coff_swap_aouthdr_out): For PPC PE, start isize at 0,
+ not at the file position of the first section.
+ * coffcode.h (coff_compute_section_file_positions): Avoid using
+ unportable #elif.
+ (coff_write_object_contents): When generating a PPC PE executable
+ with no symbols, round up the file size to a COFF_PAGE_SIZE
+ boundary.
+ * cofflink.c (_bfd_coff_final_link): If there are no symbols,
+ don't write out a string table.
+
+ * elf.c (bfd_section_from_shdr): When using a different section
+ header, pass the new one to _bfd_elf_make_section_from_shdr.
+ (elf_fake_sections): Don't set sh_info and sh_entsize fields.
+ (elf_map_symbols): Add section VMA to symbol value when comparing
+ against 0.
+ (_bfd_elf_compute_section_file_positions): Only build symbol table
+ if there are some symbols. Set file offset of symtab and strtab
+ sections.
+ (assign_file_positions_except_relocs): Remove dosyms parameter.
+ Change all callers. Never set file offset of symtab and strtab
+ sections.
+ (_bfd_elf_copy_private_section_data): New function.
+ (MAP_ONESYMTAB, MAP_DYNSYMTAB, MAP_STRTAB, MAP_SHSTRTAB): Define.
+ (_bfd_elf_copy_private_symbol_data): New function.
+ (swap_out_syms): Check for special mapping of st_shndx created by
+ copy_private_symbol_data.
+ * elfxx-target.h: Use new copy routines.
+ * elf-bfd.h (_bfd_elf_copy_private_symbol_data): Declare.
+ (_bfd_elf_copy_private_section_data): Declare.
+
+ * config.bfd (sh-*-*): Set targ_defvec to shcoff_vec.
+
+ * coffcode.h (coff_slurp_symbol_table): If COFF_WITH_PE, handle
+ C_NT_WEAK.
+
+ * coff-sh.c (shlcoff_vec): Use _bfd_generic_archive_p, not
+ _bfd_dummy_target, matching the recent change to archive
+ recognition.
+
+Mon Nov 13 13:24:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd.c (bfd_get_file_window): Use casts to avoid doing
+ arithmetic on PTR types.
+
+ * aout-target.h (MY(callback)): Set the lma of the sections.
+
+ * ecoff.c (ecoff_reloc_link_order): Turn a reloc against a defined
+ symbol into a reloc against the section.
+
+Mon Nov 13 07:31:35 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (ppc_coff_link_hash_entry): added support for inline
+ glue for the relocs: IMGLUE and IFGLUE.
+ (record_toc): new function - tracks toc contents
+ (ppc_mark_symbol_as_glue): new function - supports the IMGLUE reloc
+ (coff_ppc_relocate_section): Added support and fixes for IMGLUE/IFGLUE
+ (ppc_coff_rtype2howto): removed invalid IMGLUE hack
+ (coff_ppc_rtype_to_howto): removed invalid IMGLUE hack
+ (ppc_record_toc_entry): Removed a debug define (duh)
+
+ * peicode.h (coff_swap_scnhdr_out): Fixed invalid strcmp for ".reldata"
+ (pe_print_idata): New function - formats the idata section data
+ (pe_print_pdata): New function - formats the pdata section data
+ (pe_print_private_bfd_data): calls to above
+
+Sun Nov 12 12:23:24 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (bfd_libs_here, etc): Provide empty definitions.
+ * coff-rs6000.c (rs6000coff_vec): Add conditional defines
+ TARGET_SYM and TARGET_NAME for vector and BFD name.
+ * coff-pmac.c (pmac_xcoff_vec): Remove.
+ (TARGET_SYM, TARGET_NAME): Define.
+ * coffcode.h (coff_set_arch_mach_hook) [POWERMAC]: Set the
+ machine to 0, not all PowerMacs are 601s.
+
+Fri Nov 10 12:10:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_object_p): Read in any program headers.
+ * elf.c (_bfd_elf_make_section_from_shdr): Adjust section lma
+ based on the program headers, if any.
+ (elf_fake_sections): Set sh_addr from the vma, not the lma.
+ (map_program_segments): Set p_paddr of program headers based on
+ the lma.
+
+Thu Nov 9 13:01:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * archive.c (bfd_generic_archive_p): Preserve tdata in case of
+ failure.
+
+ * aoutx.h (NAME(aout,final_link)): Report a reasonable error when
+ trying to do a relocateable link with a non-a.out object file.
+
+ * archive.c (bfd_generic_archive_p): Check the first object file
+ in an archive even if target_defaulted is set. If the object file
+ has the wrong xvec, reject it.
+
+ * aoutx.h (NAME(aout,set_section_contents)): If a section can not
+ be represented, report the name via _bfd_error_handler.
+ (translate_to_native_sym_flags): Likewise.
+ * elf32-mips.c (mips_elf_final_link): Likewise.
+ * oasys.c (oasys_write_sections): Likewise.
+
+ * coffcode.h (coff_set_alignment_hook): Write RS6000COFF_C version
+ which checks for STYP_OVRFLO sections.
+ (coff_compute_section_file_positions): If RS6000COFF_C, handle
+ reloc and lineno count overflows.
+ (coff_write_object_contents): Call coff_count_linenumbers before
+ coff_compute_section_file_positions. If RS6000COFF_C, handle
+ reloc and lineno count overflows.
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Count line numbers and
+ relocs before dealing with .pad sections. Count overflow section
+ headers when handling .pad sections.
+
+ * coffcode.h (coff_write_object_contents): Set a.out vstamp to 1
+ if RS6000COFF_C.
+
+ * xcofflink.c (XCOFF_DESCRIPTOR): Define.
+ (struct xcoff_link_hash_table): Add descriptor_section and
+ special_sections fields.
+ (_bfd_xcoff_bfd_link_hash_table_create): Initialize new fields.
+ (xcoff_link_add_symbols): Set linkage section alignment. Create
+ descriptor section. Check for magic symbol names (_text, etc.),
+ and record them in special_sections if found. Set
+ XCOFF_DESCRIPTOR flag for a function descriptor, and set its
+ descriptor field to point back to the function code symbol.
+ (xcoff_sweep): Always mark the special descriptor_section.
+ (bfd_xcoff_export_symbol): Check whether the symbol might be a
+ function descriptor, and mark it if it is.
+ (bfd_xcoff_size_dynamic_sections): Add new special_sections
+ parameter, and fill it in. Allocate space for the descriptor
+ section.
+ (xcoff_build_ldsyms): Set XCOFF_DEF_REGULAR flag when defining
+ global linkage code. If an undefined function descriptor is
+ exported, arrange to define it. Warn about any other undefined
+ exported symbol.
+ (_bfd_xcoff_bfd_final_link): Write out the descriptor section.
+ (xcoff_write_global_symbol): Create a function descriptor when
+ necessary.
+ * bfd-in.h (bfd_xcoff_size_dynamic_sections): Update declaration.
+ * bfd-in2.h: Rebuild.
+
+Thu Nov 9 08:40:23 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (ppc_coff_link_hash_entry): new types for hashing
+ (ppc_coff_link_hash_table): new types for hashing
+ (ppc_coff_link_hash_newfunc): hash entry constructor
+ (ppc_coff_link_hash_table_init): hash table initializer
+ (ppc_coff_link_hash_table_create): hash table constructor
+ (ppc_record_toc_entry): changed references to hash table
+ (coff_ppc_relocate_section): changed references to hash table
+
+ * libcoff-in.h (coff_link_hash_entry): removed toc_offset
+ * libcoff.h: Rebuild
+
+ * cofflink.c (_bfd_coff_link_hash_newfunc): removed toc_offset init
+ (coff_link_add_symbols): removed toc_offset init
+
+Thu Nov 9 04:00:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (.dep1): Make sure the file mkdep is to write exists
+ first.
+
+ * configure.in: Added new option --with[out]-mmap. Set USE_MMAP
+ if it is given and mmep is available.
+ * acconfig.h: Undef USE_MMAP.
+ * configure, config.in: Regenerated.
+ * aoutx.h: If USE_MMAP is not defined, do all symbol and string
+ table handling the old way.
+ (aout_get_external_symbols): Don't complain if last byte of string
+ table is nonzero.
+ * libbfd.c [HAVE_MADVISE]: Include sys/types.h and sys/mman.h.
+ (bfd_free_window) [! USE_MMAP]: Don't define.
+ (bfd_get_file_window,
+ _bfd_generic_get_section_contents_in_window) [! USE_MMAP]: Abort.
+
+Wed Nov 8 20:03:44 1995 Eric Freudenthal <freudenthal@nyu.edu>
+
+ * coff-a29k.c (SIGN_EXTEND_HWORD): Use ~0xffff rather than
+ 0xffff0000.
+
+Wed Nov 8 11:31:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-a29k.c (a29k_reloc): Change handling of R_IREL reloc to be
+ compatible with AMD generated COFF files. Try to support both AMD
+ and GNU formats simultaneously.
+ (coff_a29k_relocate_section): Likewise.
+
+ * libbfd.c (bfd_get_file_window): Change writable parameter from
+ int to boolean; update all callers. Pass MAP_SHARED if not
+ writable--it's required on Solaris. Cast fprintf argument to
+ avoid warning.
+ * bfd-in.h (bfd_get_file_window): Update declaration.
+ * bfd-in2.h: Rebuild.
+ * aoutx.h: Update calls to bfd_get_file_window.
+
+ * xcofflink.c (XCOFF_DEF_DYNAMIC): Rename from XCOFF_REF_DYNAMIC.
+ Change all uses.
+ (xcoff_swap_ldhdr_in): New static function.
+ (xcoff_swap_ldsym_in): New static function.
+ (xcoff_find_reloc): Handle the case of a single reloc correctly.
+ (xcoff_link_add_symbols): If we just created a descriptor, pass it
+ to _bfd_generic_link_add_one_symbol, to save a hash lookup.
+ Handle XTY_ER/XMC_XO symbols correctly.
+ (xcoff_link_add_dynamic_symbols): Rewrite to read .loader symbols
+ rather than normal symbol table.
+ (bfd_xcoff_import_symbol): It's not an error if the symbol is
+ already defined with the same absolute value.
+ (xcoff_mark): When considering called symbols, check whether the
+ descriptor is from a dynamic object, rather than the symbol
+ itself.
+ (xcoff_build_ldsyms): Likewise.
+
+ * libbfd.c (bfd_get_file_window): Change return type to boolean.
+ Cast realloc and malloc return values. If malloc or realloc fail,
+ set bfd_error_no_memory.
+ * bfd-in.h (bfd_get_file_window): Change type to boolean.
+ * bfd-in2.h: Rebuild.
+
+Tue Nov 7 11:53:48 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (ppc_record_toc_entry): new function.
+ (in_reloc_p): changed return value.
+ (coff_ppc_relocate_section): much rework.
+ (ppc_allocate_toc_section): new function.
+ (ppc_process_before_allocation): new function.
+ (ppc_coff_swap_sym_in_hook): new function.
+
+ * cofflink.c (_bfd_coff_link_hash_newfunc): initialize toc_offset.
+ (coff_link_add_symbols): initialize toc_offset.
+
+ * peicode.h (coff_swap_sym_in): Added coff_swap_sym_in_hook
+ (coff_swap_aouthdr_out): Added more sections to the data
+ dictionary for the pe file header. Also changed linker version
+ number on the ppc side.
+ (dir_names): small improvements to the dictionary printing.
+ (pe_mkobject_hook): save the file level flags.
+
+ * libcoff-in.h (coff_link_hash_entry): added toc_offset field
+ (pe_tdata): added real_flags field
+ (coff_tdata): added local_toc_sym_map and access macro
+
+ * libcoff.h (coff_link_hash_entry): added toc_offset field
+ (pe_tdata): added real_flags field
+ (coff_tdata): added local_toc_sym_map and access macro
+
+ * coffcode.h (coff_set_alignment_hook): added hook for PE.
+ (coff_mkobject): init for local_toc_sym_map
+ (coff_write_object_contents): set the internal_a.magic to
+ IMAGE_NT_OPTIONAL_HDR_MAGIC which appears to be what other
+ ppc compilers use.
+
+Tue Nov 7 13:48:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecofflink.c (_bfd_ecoff_locate_line): Keep looking through stabs
+ entries until both the line number address and the function name
+ address are too large.
+
+ * configure.in: Call AC_CHECK_PROG to find and cache AR.
+ * configure: Rebuilt.
+
+ * aclocal.m4 (BFD_CC_FOR_BUILD): Don't define CC_FOR_BUILD if it
+ is defined in the environment.
+
+Tue Nov 7 10:57:24 1995 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_get_section_contents_in_window): Define to use
+ generic version.
+
+Mon Nov 6 17:13:15 1995 Harry Dolan <dolan@ssd.intel.com>
+
+ * coff-i860.c: New file, based on coff-i386.c.
+ * cpu-i860.c: New file, based on cpu-i386.c.
+ * hosts/i860mach3.h: New file, based on hosts/i386mach3.h.
+ * config.bfd (i860-*-mach3*, i860-*-osf1*, i860-*-coff*): New
+ targets, using i860coff_vec.
+ * configure.in (i860-*-mach3*, i860-*-osf1*): New hosts, using
+ trad-core.o and hosts/i860mach3.h.
+ (i860coff_vec): Use coff-i860.o and cofflink.o.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (ALL_MACHINES): Add cpu-i860.o.
+ (BFD32_BACKENDS): Add coff-i860.o.
+ (CFILES): Add cpu-i860.c and coff-i860.c.
+ * targets.c (i860coff_vec): Declare.
+ (bfd_target_vector): Add &i860coff_vec.
+ * archures.c (bfd_i860_arch): Declare.
+ (bfd_archures_list): Add &bfd_i860_arch.
+ * coffcode.h (coff_set_arch_mach_hook): Handle I860 magic number.
+ (coff_set_flags): Handle bfd_arch_i860.
+ (coff_write_object_contents): Handle I860 a.out magic number.
+
+Mon Nov 6 14:34:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Set the alignment power of
+ the created .tc section to 2.
+ (xcoff_mark): Don't keep a .loader reloc for a call to an
+ undefined symbol when creating a shared library.
+ (xcoff_build_ldsyms): When creating a shared library, generate
+ global linkage code for a call to an undefined symbol.
+
+Sun Nov 5 21:44:13 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (CFILES): Rebuild list from BFD_LIBS, ALL_MACHINES,
+ BFD32_BACKENDS, BFD64_BACKENDS.
+ (.dep1): Put mkdep output in a separate file.
+ Rebuilt dependencies.
+
+ * ecoff.c (_bfd_ecoff_slurp_armap): Cast _bfd_read_ar_hdr return
+ value.
+
+ Permit use of mmap when available:
+
+ * configure.in: Check for mmap, madvise, mprotect.
+ * config.in, configure: Regenerated.
+
+ * libbfd.c (struct _bfd_window_internal): Define type.
+ (bfd_init_window, bfd_free_window, bfd_get_file_window): New
+ functions.
+ (ok_to_map): New static variable for debugging.
+ (_bfd_generic_get_section_contents_in_window): New function.
+ * bfd-in.h (bfd_window_internal): Declare type.
+ (bfd_window): Define type.
+ (bfd_init_window, bfd_free_window, bfd_get_file_window): Declare.
+ * libbfd-in.h (_bfd_generic_get_section_contents_in_window):
+ Declare.
+
+ * libaout.h (struct aoutdata): Add two window fields.
+ (obj_aout_sym_window, obj_aout_string_window): New macros.
+ * aoutx.h (some_aout_object_p): Initialize windows.
+ (aout_get_external_symbols): Get symbol data and strings in
+ windows instead of explicitly allocated buffers.
+ (slurp_symbol_table): Free window instead of memory.
+ (bfd_free_cached_info): Release windows instead of freeing storage
+ directly.
+ (aout_link_free_symbols): Ditto.
+
+ * targets.c (bfd_target): Add new field for
+ get_section_contents_in_window.
+ (BFD_JUMP_TABLE_GENERIC): Updated.
+ * aout-adobe.c, aout-target.h, binary.c, bout.c, coff-alpha.c,
+ coff-mips.c, elfxx-target.h, i386msdos.c, i386os9k.c, ieee.c,
+ libcoff-in.h, oasys.c, srec.c, tekhex.c, versados.c: Added new
+ macros for get_section_contents_in_window field.
+
+Sat Nov 4 12:23:26 1995 Fred Fish <fnf@cygnus.com>
+
+ * core.c: Renamed to corefile.c
+ * makefile.dos (OBJS): Change core.o to corefile.o
+ * Makefile.in (CFILES, BFD_LIBS): Use corefile.c instead of core.c
+
+Fri Nov 3 15:54:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Rename local variable sub
+ to o. Clobber and restore the list of new csects around the call
+ to _bfd_generic_link_add_one_symbol, in case it wants to report a
+ linker error and the linker wants to read the symbol table. Reset
+ the line number count of a real section even if it has no relocs.
+ (_bfd_xcoff_bfd_final_link): If shared, set the DYNAMIC flag.
+
+ * coffgen.c (_bfd_coff_read_string_table): Warn if the string size
+ is too small.
+
+Thu Nov 2 23:16:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (_bfd_ppc_xcoff_relocate_section): Don't warn about
+ an undefined symbol in a shared link.
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Correct type of
+ oldtype from bfd_link_order_type to bfd_link_hash_type. From
+ phdm@info.ucl.ac.be (Philippe De Muyter).
+
+Wed Nov 1 14:26:02 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * coff-m88k.c (rtype2howto): New static function.
+ (RTYPE2HOWTO): Use it rather than a macro definition.
+
+ * coffcode.h (coff_write_object_contents): set internal_a.magic
+ to PAGEMAGICPEXECPAGED #if defined (M68) && !defined (LYNXOS).
+
+ * configure.in: m68*-motorola-sysv* does not use ptrace-core.o;
+ define TRAD_HEADER to new file hosts/delta68.h.
+ m88*-motorola-sysv*, however, does use ptrace-core.o.
+ * hosts/delta68.h: New file.
+
+ * ptrace-core.c (ptrace_unix_core_file_p): change bfd_zmalloc to
+ bfd_zalloc; provide proper parm abfd to calls to bfd_zalloc.
+
+Wed Nov 1 13:51:54 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * i386linux.c (MY(vec)): Declare before use.
+
+Wed Nov 1 11:45:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * reloc16.c (bfd_coff_reloc16_get_relocated_section_contents):
+ Pass input_bfd, not in_bfd, to bfd_coff_reloc16_extra_cases.
+
+ * elf.c (bfd_elf_set_dt_needed_name): Don't do anything if the
+ BFD is not of the right type.
+ (bfd_elf_get_needed_list): Likewise.
+ * i386linux.c (bfd_linux_size_dynamic_sections): Likewise.
+ * sunos.c (bfd_sunos_get_needed_list): Likewise.
+ * xcofflink.c (XCOFF_XVECP): Define.
+ (bfd_xcoff_link_record_set): Don't do anything if the BFD is not
+ of the right type.
+ (bfd_xcoff_import_symbol): Likewise.
+ (bfd_xcoff_export_symbol): Likewise.
+ (bfd_xcoff_link_count_reloc): Likewise.
+ (bfd_xcoff_record_link_assignment): Likewise.
+ (bfd_xcoff_size_dynamic_sections): Likewise.
+
+ * sunos.c (sunos_scan_ext_relocs): Only check the reloc symbol
+ table index against the number of symbols for a base relative
+ reloc.
+
+ * coff-rs6000.c (_bfd_xcoff_sizeof_headers): Change from macro to
+ static function.
+ * xcofflink.c (_bfd_xcoff_bfd_link_hash_table_create): Set
+ full_aouthdr flag here...
+ (_bfd_xcoff_bfd_final_link): ...not here.
+
+Tue Oct 31 12:52:02 1995 Fred Fish <fnf@cygnus.com>
+
+ * libelf.h: Rename to elf-bfd.h to avoid conflict with
+ systems that have a system <libelf.h>.
+ * Makefile.in: Globally replace libelf.h with elf-bfd.h.
+ * bfd.c, elf.c, elf32-arc.c, elf32-gen.c, elf32-hppa.c,
+ elf32-hppa.h, elf32-i386.c, elf32-i860.c, elf32-m68k.c,
+ elf32-m88k.c, elf32-mips.c, elf32-ppc.c, elf32-sparc.c,
+ elf64-gen.c, elf64-sparc.c, elfcode.h, elflink.c,
+ elfxx-target.h: Include elf-bfd.h rather than libelf.h.
+ * elfxx-target.h: Change libelf.h reference to elf-bfd.h.
+
+Tue Oct 31 15:30:07 1995 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * ecoff.c (ecoff_set_symbol_info): Add new parameter weak. If
+ set, set BSF_WEAK in symbol. Change all callers.
+ (ecoff_get_extr): Set weakext based on BSF_WEAK.
+ (ecoff_link_add_externals): If weakext is set, pass BSF_WEAK to
+ _bfd_generic_link_add_one_symbol.
+ (ecoff_indirect_link_order): Check that the section tdata relocs
+ are not NULL before using them.
+
+ * configure.in (alpha*-*-linux*): Set COREFILE to trad-core.o and
+ define TRAD_HEADER as hosts/alphalinux.h.
+ * configure: Rebuild.
+ * hosts/alphalinux.h: New file.
+ * trad-core.c (trad_unix_core_file_p): Cast u.u_ar0 to bfd_vma,
+ not int.
+
+Tue Oct 31 12:34:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_slurp_symbol_table): Accept C_BCOMM and
+ C_ECOMM storage classes.
+
+ * xcofflink.c (xcoff_mark_symbol): New static function, broken out
+ of xcoff_mark.
+ (xcoff_mark): Call xcoff_mark_symbol.
+ (bfd_xcoff_export_symbol): Call xcoff_mark_symbol.
+ (bfd_xcoff_link_count_reloc): Call xcoff_mark_symbol rather than
+ doing it by hand.
+ (xcoff_build_ldsyms): Build a .loader symbol for an export symbol.
+
+Mon Oct 30 14:53:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (struct xcoff_final_link_info): Add new line_filepos
+ field.
+ (xcoff_find_reloc): New static function.
+ (xcoff_link_add_symbols): Use it.
+ (_bfd_xcoff_bfd_final_link): Set finfo.line_filepos.
+ (xcoff_link_input_bfd): Handle C_BINCL and C_EINCL. Don't
+ relocate the value of C_DECL.
+
+ * elf.c (elf_fake_sections): Remove bogus BFD_ASSERT.
+
+Sat Oct 28 01:25:34 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Make
+ callback decide what goes in .relocs.
+ * pe[i]-i386.c (TARGET_UNDERSCORE): Define.
+ * peicode.h (pe_mkobject_hook): Only copy aouthdr if
+ there is one.
+
+Sat Oct 28 01:51:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Handle csects in the
+ absolute section.
+
+Fri Oct 27 18:14:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c: More improvements, mostly to fix handling of
+ constructors and a few other special cases.
+ * coff-rs6000.c (rs6000coff_vec): Set symbol_leading_char back to
+ zero, reverting yesterday's change.
+ * bfd-in.h (bfd_xcoff_link_record_set): Declare.
+ (bfd_xcoff_link_count_reloc): Declare.
+ (bfd_xcoff_record_link_assignment): Declare.
+ * bfd-in2.h: Rebuild.
+
+Fri Oct 27 14:42:15 1995 Niklas Hallqvist <niklas@appli.se>
+
+ * PORTING, aout-arm.c, aout-encap.c, aout-target.h,
+ aoutx.h, gen-aout.c, host-aout.c, hp300bsd.c, i386aout.c
+ i386bsd.c, i386dynix.c, i386linux.c, i386lynx.c, i386mach3.c,
+ i386netbsd.c, m68klynx.c, m88kmach3.c, mipsbsd.c, newsos3.c,
+ ns32knetbsd.c, pc532-mach.c, riscix.c, sparclynx.c, sparcnetbsd.c:
+ Change PAGE_SIZE to TARGET_PAGE_SIZE.
+
+ * m68knetbsd.c: Ditto as well as add support for the m68k4k object
+ format.
+
+ * netbsd.h: Double ditto (incl. m68k4k support). NetBSD's text
+ segments includes the a.out header. See to that the magic number
+ *always* is big-endian.
+
+ * config.bfd: Add m68*-hp*-netbsd* case. Cross-pollinate m68k and
+ m68k4k NetBSD configurations.
+
+ * configure.in, configure: Separate i386 & mips NetBSD
+ configurations from other BSD ones. Don't assume DEC is the only
+ thing NetBSD/mips run on. Add {m68k,ns32k,sparc}-*-netbsd*
+ configurations. Add support for m68k4k NetBSD object format.
+
+ * libaout.h: Added M_68K4K_NETBSD magic.
+
+ * m68k4knetbsd.c: New file.
+
+ * hosts/{m68k,sparc}nbsd.h: Don't define HOST_BIG_ENDIAN_P.
+
+ * hosts/nbsd.h: Define HOST_BIG_ENDIAN_P according to
+ <machine/endian.h>.
+
+ * hosts/mipsnbsd.h: New file.
+
+Thu Oct 26 14:16:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c: Numerous changes to get closer to a working XCOFF
+ linker.
+ * libcoff-in.h (struct xcoff_tdata): Add full_aouthdr,
+ toc_section, and entry_section fields.
+ (struct xcoff_section_tdata): Remove ldrel_count field.
+ * libcoff.h: Rebuild.
+ * coffcode.h (coff_mkobject_hook): Initialize new xcoff_data
+ fields.
+ (coff_compute_section_file_positions): If RS6000COFF_C, generate
+ full a.out header if full_aouthdr is set in xcoff_data.
+ (coff_write_object_contents): Likewise. Set o_snentry and o_sntoc
+ based on sections stored in xcoff_data.
+ * coff-rs6000.c (xcoff_copy_private_bfd_data): Copy new xcoff_data
+ fields.
+ (xcoff_reloc_type_lookup): Handle BFD_RELOC_CTOR.
+ (rs6000coff_vec): Set symbol_leading_char to '.'.
+ * coffgen.c (coff_get_symbol_info): If fix_value is set, fix the
+ value stored in ret rather than returning a pointer value.
+
+Wed Oct 25 23:10:39 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.bfd (powerpc{,le}-{elf,sysv4,eabi,solaris2}): Remove MAC
+ format for now.
+
+Wed Oct 25 16:19:27 1995 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_slurp_string_table): Allocate the strings with malloc
+ since they're free'd by free_cached_info.
+ (som_slurp_symbol_table): Similarly for the symbol table.
+
+Wed Oct 25 14:59:22 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (diststuff): Don't make headers.
+
+Wed Oct 25 11:32:54 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild dependencies.
+
+ * sunos.c (bfd_sunos_record_link_assignment): Don't do anything if
+ output_bfd is not SunOS.
+ (bfd_sunos_size_dynamic_sections): Likewise. Don't scan relocs of
+ non-SunOS input files.
+
+ * xcofflink.c: Extensive changes to support linking shared objects
+ and generating a .loader section.
+ * libcoff-in.h (struct xcoff_tdata): Add import_file_id field.
+ (struct xcoff_section_tdata): Add lineno_count, first_symndx,
+ last_symndx, and ldrel_count fields.
+ * libcoff.h: Rebuild.
+ * coff-rs6000.c (xcoff_howto_table): Correct reloc names.
+ * coffcode.h (styp_to_sec_flags): Don't set any flags if STYP_PAD
+ is set.
+ * bfd-in.h (bfd_xcoff_import_symbol): Declare.
+ (bfd_xcoff_export_symbol): Declare.
+ (bfd_xcoff_size_dynamic_sections): Declare.
+ * bfd-in2.h: Rebuild.
+
+Tue Oct 24 17:44:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in: Add xcofflink.o to pmac_xcoff_vec.
+ * configure: Rebuild.
+ * mpw-config.in: Add xcofflink.c.o to powerpc-apple-macos.
+ * coff-pmac.c: Include coff-rs6000.c instead of duplicating its
+ contents.
+ (pmac_xcoff_vec): Update to use new xcoff support.
+ * coff-rs6000.c (xcoff_generic_stat_arch_elt): Make static.
+ (xcoff_write_armap): Declare buf as unsigned char.
+ * xcofflink.c (xcoff_link_add_symbols): Declare a local as PTR.
+
+ * mpw-make.sed: Generalize subdir_do edit.
+
+Tue Oct 24 10:25:01 1995 Jeffrey A Law (law@cygnus.com)
+
+ * hppabsd-core.c (make_bfd_asection): Initialize asect->filepos
+ correctly. Don't initialize asect->vma.
+
+Fri Oct 20 13:23:48 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * opncls.c (_bfd_new_bfd): If _bfd_chunksize wasn't preset, use
+ something a little less than the page size.
+
+Thu Oct 19 13:06:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i960.c (coff_i960_adjust_symndx): Clear *adjustedp.
+
+Wed Oct 18 16:20:08 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coff-i386.c (coff_i386_reloc_type_lookup): New.
+ * coffcode.h (coff_write_object_contents): If .bss is before
+ .data us that as data_start.
+ * cofflink.c (_bfd_coff_generic_relocate_section): Get reloc
+ calc correct.
+ * peicode.h (add_data_entry): Use _cooked_size of data directory.
+ (coff_swap_outhdr_out): Hardwire in version number.
+
+Wed Oct 18 16:50:54 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * sunos.c (sunos_add_dynamic_symbols): Rename local variables
+ major and minor to *_vno, since the former are also macros in
+ SunOS header files. Cast result of bfd_alloc to appropriate
+ type.
+
+ * coffgen.c (coff_find_nearest_line): Cast used_by_bfd value
+ before assigning to sec_data.
+
+Wed Oct 18 13:25:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): The offset argument is
+ now relative to the section, not absolute.
+ * ecofflink.c (_bfd_ecoff_locate_line): Use the right symbol to
+ get the file name when there is a N_SO directory name. When
+ handling stabs, remember that section->vma was added to the
+ offset.
+
+Tue Oct 17 18:24:54 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (struct sunos_link_hash_table): Add needed field.
+ (sunos_link_hash_table_create): Call bfd_release, not free.
+ (sunos_link_hash_table_create): Initialize needed field.
+ (sunos_add_dynamic_symbols): Record needed objects.
+ (bfd_sunos_get_needed_list): New function.
+ * bfd-in.h (bfd_sunos_get_needed_list): Declare.
+ * bfd-in2.h: Rebuild.
+
+Mon Oct 16 14:43:59 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * libcoff-in.h (pe_data_type.in_reloc_p): New.
+
+Mon Oct 16 10:52:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd-in.h (struct bfd_link_needed_list): Rename from
+ bfd_elf_link_needed_list.
+ * bfd-in2.h: Rebuild.
+ * elf.c, elflink.h, libelf.h: Corresponding changes.
+
+ Add start at AIX linker support; no shared libraries yet.
+ * xcofflink.c: New file.
+ * configure.in (rs600coff_vec): Use xcofflink.o.
+ * configure: Rebuild.
+ * libcoff-in.h (struct xcoff_tdata): Add csects and debug_indices
+ fields.
+ (struct xcoff_section_tdata): Define.
+ (xcoff_section_data): Define macro.
+ (_bfd_xcoff_bfd_link_hash_table_create): Declare.
+ (_bfd_xcoff_bfd_link_add_symbols): Declare.
+ (_bfd_xcoff_bfd_final_link): Declare.
+ (_bfd_ppc_xcoff_relocate_section): Declare.
+ * libcoff.h: Rebuild.
+ * coff-rs6000.c: Clean up a bit.
+ (xcoff_mkobject): Default modtype to 1L, not RE. Initialize
+ cputype, csects, and debug_indices.
+ (xcoff_copy_private_bfd_data): Copy cputype.
+ (xcoff_howto_table): Rename from rs6000coff_howto_table.
+ (xcoff_rtype2howto): Rename from rs6000coff_rtype2howto.
+ (xcoff_reloc_type_lookup): Rename from
+ rs6000coff_reloc_type_lookup.
+ (coff_relocate_section): Define.
+ (_bfd_xcoff_sizeof_headers): Define.
+ (_bfd_xcoff_bfd_get_relocated_section_contents): Define.
+ (_bfd_xcoff_bfd_relax_section): Define.
+ (_bfd_xcoff_bfd_link_split_section): Define.
+ (rs6000coff_vec): For BFD_JUMP_TABLE_LINK, use _bfd_xcoff, not
+ coff.
+ * coffcode.h (coff_compute_section_file_positions): If AIX,
+ increment sofar by SMALL_AOUTSZ if not executable.
+ (coff_write_object_contents): If AIX, always output an a.out
+ header; if not executable, header size of SMALL_AOUTSZ.
+ * hash.c (struct bfd_strtab_hash): Add xcoff field.
+ (_bfd_stringtab_init): Initialize xcoff field.
+ (_bfd_xcoff_stringtab_init): New function.
+ (_bfd_stringtab_add): In XCOFF mode, leave two bytes for length.
+ (_bfd_stringtab_emit): In XCOFF mode, write out length.
+ * libbfd-in.h (_bfd_xcoff_stringtab_init): Declare.
+ * libbfd.h: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add xcofflink.o.
+ (CFILES): Add xcofflink.c.
+
+ * elf32-mips.c (mips_elf_symbol_processing): Set SEC_ALLOC, not
+ SEC_NO_FLAGS, for .acommon section. From Peter Schauer
+ <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>.
+
+Sat Oct 14 21:36:02 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * coff-ppc.c (in_reloc_p): Add, clone from coff-i386.c.
+
+Fri Oct 13 17:48:43 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * acconfig.h (HAVE_SYS_PROCFS_H): Undef, with comment.
+ * config.in: Regenerated.
+
+ * opncls.c (getpagesize) [!HAVE_GETPAGESIZE]: Define as 2048.
+ (_bfd_chunksize): New variable.
+ (_bfd_new_bfd): Set it to getpagesize() if negative, and use it
+ for obstack chunk size.
+ * configure.in: Check for getpagesize.
+ * configure: Regenerated.
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * trad-core.c (rawptr): Make it a local variable of
+ ptrace_unix_core_file_p.
+
+Fri Oct 13 11:22:01 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coff-arm.c (in_reloc_p): New.
+ * coff-i386.c (in_reloc_p): New.
+ * coffcode.h: Allways include peicode.h if COFF_WITH_PE.
+ (coff_write_object_contents): Only set has_reloc_section
+ if PE_IMAGE.
+ * cofflink.c (_bfd_coff_generic_relocate_section): Call
+ in_reloc_p to decide if reloc should be emitted.
+ * libcoff.h (pe_data_type.in_reloc_p): New.
+ * peicode.h (pe_mkobject): Initialize in_reloc_p.
+
+Wed Oct 11 00:49:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_internal_syment_name): Move to coffgen.c.
+ (_bfd_coff_read_internal_relocs): Likewise.
+ * coffgen.c (_bfd_coff_internal_syment_name): Copy from coffgen.c.
+ (_bfd_coff_read_internal_relocs): Likewise.
+
+ * elflink.h (elf_link_add_object_symbols): Correct conditions
+ under which type and size change warnings are issued.
+
+Tue Oct 10 18:32:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgen.c (coff_count_linenumbers): Don't count line numbers for
+ a symbol which is not in a real section.
+ (coff_write_native_symbol): Corresponding change.
+
+ * cofflink.c (_bfd_coff_link_hash_newfunc): Rename from
+ coff_link_hash_newfunc and make non-static.
+ (_bfd_coff_link_hash_table_init): New function, broken out of
+ _bfd_coff_link_hash_table_create.
+ (_bfd_coff_link_hash_table_create): Use it.
+ (process_embedded_commands): Make static.
+ * libcoff-in.h ((_bfd_coff_link_hash_newfunc): Declare.
+ (_bfd_coff_link_hash_table_init): Declare.
+ * libcoff.h: Rebuild.
+
+ * coffcode.h (coff_mkobject_hook): If RS6000COFF_C, set cputype
+ field in XCOFF tdata.
+ (coff_set_arch_mach_hook): Check ifdef RS6000COFF_C, not ifdef
+ U802ROMAGIC, for clarity. Try to set arch and machine correctly
+ based on cputype stored in a.out header, or in n_type of initial
+ .file symbol.
+ (coff_write_object_contents): Set cputype correctly in a.out
+ header.
+ (coff_slurp_symbol_table): Add casts to file_ptr to avoid
+ warnings.
+ * coffswap.h (coff_swap_aouthdr_in): Swap in cputype field.
+ (coff_swap_aouthdr_out): Swap out cputype field. Don't clear
+ old resv1 field.
+ * libcoff-in.h (struct xcoff_tdata): Add cputype field.
+ * libcoff.h: Rebuild.
+
+ * cpu-rs6000.c (rs6000_compatible): New static function.
+ (bfd_rs6000_arch): Use it.
+ * cpu-powerpc.c (powerpc_compatible): New static function.
+ (arch_info_struct): Define various flavours of PowerPC.
+ (bfd_powerpc_arch): Use powerpc_compatible. Point at
+ arch_info_struct.
+
+Tue Oct 10 10:50:46 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (FLAGS_TO_PASS): Remove BISON.
+
+Tue Oct 10 01:28:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't warn about
+ changing the size or type if the old definition was weak.
+
+Mon Oct 9 11:24:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (combined_entry_type): Add fix_line field.
+ (coff_slurp_line_table): Warn if we try to set the lineno field of
+ a symbol twice.
+ (coff_slurp_symbol_table): If RS6000COFF_C, handle C_BINCL and
+ C_EINCL by setting fix_line. Fix C_BSTAT symbol value.
+ * coffgen.c (coff_mangle_symbols): Handle fix_line.
+ (coff_write_symbol): Only use N_DEBUG if the symbol is in the
+ absolute section.
+ (coff_print_symbol): Print fix_value symbols in a useful fashion.
+ * libcoff.h: Rebuild.
+
+ * libcoff-in.h (struct xcoff_tdata): Define.
+ (xcoff_data): Define.
+ * bfd.c (struct _bfd): Add xcoff_obj_data field to tdata union.
+ * bfd-in2.h, libcoff.h: Rebuild.
+ * coff-rs6000.c (xcoff_mkobject): New static function.
+ (coff_mkobject): Define.
+ (xcoff_copy_private_bfd_data): New static function.
+ (coff_bfd_copy_private_bfd_data): Define.
+ (rs6000coff_howto_table): Change R_TOC complain_on_overflow from
+ signed to bitfield.
+ (rs6000coff_vec): Add DYNAMIC to object_flags.
+ * coffcode.h (sec_to_styp_flags): If RS6000COFF_C, handle .pad and
+ .loader sections specially.
+ (coff_new_section_hook): If RS6000COFF_C, get the .text and .data
+ section alignment from the XCOFF tdata information.
+ (coff_mkobject_hook): If RS6000COFF_C, set DYNAMIC based on
+ F_SHROBJ, and copy the extra a.out header information into the
+ XCOFF tdata structure.
+ (coff_write_object_contents): If RS6000COFF_C, set F_SHROBJ,
+ F_DYNLOAD and the extra a.out header information.
+ (coff_slurp_symbol_table): Set BSF_NOT_AT_END for a C_EXT or
+ C_HIDEXT symbol with attached csect information.
+ * coffswap.h (coff_swap_aouthdr_in): If RS6000COFF_C, swap
+ in the o_maxdata field.
+ (coff_swap_aouthdr_out): If RS6000COFF_C, swap extra XCOFF fields.
+ * coffgen.c (coff_renumber_symbols): Don't move any symbol to the
+ end if BSF_NOT_AT_END is set.
+
+ * targets.c (bfd_target): Rename _bfd_read_ar_hdr field to
+ _bfd_read_ar_hdr_fn.
+ * libbfd-in.h (_bfd_read_ar_hdr): Update accordingly.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * archive.c (_bfd_get_elt_at_filepos): Cast _bfd_read_ar_hdr
+ return value.
+ (do_slurp_bsd_armap, do_slurp_coff_armap): Likewise.
+ (bfd_slurp_bsd_armap_f2): Likewise.
+ (_bfd_slurp_extended_name_table): Likewise.
+
+Fri Oct 6 16:18:35 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * archive.c (bfd_get_next_mapent): Return BFD_NO_MORE_SYMBOLS
+ when the symbol table is empty.
+
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Don't reserve
+ space for section symbols, since we don't output them either.
+ (elf_m68k_adjust_dynindx): Removed.
+
+ * ptrace-core.c (rawptr): Make it a local variable of
+ ptrace_unix_core_file_p.
+
+Fri Oct 6 12:24:47 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * coff-rs6000.c (xcoff_write_archive_contents): Return false, not
+ NULL.
+
+ * config.bfd (powerpc{,le}-{elf,sysv4,eabi,solaris2}): Add NT, and
+ Mac object file formats.
+
+Fri Oct 6 12:04:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgen.c (coff_fix_symbol_name): Don't try to set up file
+ auxent if there isn't one.
+ (coff_write_symbols): If there is no file auxent, use SYMNMLEN
+ rather than FILNMLEN as the maximum name length.
+
+ * coffcode.h (bfd_coff_backend_data): Add new field
+ _bfd_coff_print_aux.
+ (bfd_coff_print_aux): New static function.
+ (coff_pointerize_aux_hook (RS6000COFF_C version)): Pointerize the
+ scnlen field of an XTY_LD csect aux entry.
+ (coff_print_aux): New static function.
+ (coff_slurp_symbol_table): Don't pointerize scnlen field; now done
+ in coff_pointerize_aux_hook.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * coffgen.c (coff_print_symbol): Call bfd_coff_print_aux.
+ * libcoff.h: Rebuild.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize new field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+
+ * coffcode.h (coff_write_object_contents): On AIX, clear F_RELFLG
+ if there are symbols, for native AIX ld compatibility.
+
+ * coffcode.h (bfd_coff_backend_data): Add new field
+ _bfd_coff_pointerize_aux_hook.
+ (coff_pointerize_aux_hook): Define as a function if RS6000COFF_C
+ or I960, and as 0 otherwise.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * libcoff.h: Rebuild.
+ * coffgen.c (coff_pointerize_aux): Change parameters to take
+ symbol pointer instead of type and class, and to take aux index.
+ Call _bfd_coff_pointerize_aux_hook if it is defined.
+ (coff_get_normalized_symtab): Always call coff_pointerize_aux.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize all fields.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+
+ * coff-rs6000.c: Add full support for AIX archives. Rewrite old
+ read-only/host-only support.
+
+ * coffcode.h (coff_slurp_symbol_table): Set C_HIDEXT symbols to be
+ BSF_LOCAL.
+ (OTHER_GLOBAL_CLASS): Do not define to be C_HIDEXT if
+ RS6000COFF_C.
+
+ * targets.c (bfd_target): Add _bfd_read_ar_hdr field. Modify
+ BFD_JUMP_TABLE_ARCHIVE accordingly.
+ * libbfd-in.h (_bfd_snarf_ar_hdr): Don't declare.
+ (_bfd_compute_and_write_armap): Declare.
+ (_bfd_generic_read_ar_hdr): Declare.
+ (_bfd_read_ar_hdr): Define.
+ (_bfd_noarchive_read_ar_hdr): Define.
+ (_bfd_archive_bsd_read_ar_hdr): Define.
+ (_bfd_archive_coff_read_ar_hdr): Define.
+ * archive.c: Change all callers of _bfd_snarf_ar_hdr to call
+ _bfd_read_ar_hdr instead.
+ (_bfd_generic_read_ar_hdr): Rename from _bfd_snarf_ar_hdr.
+ (_bfd_compute_and_write_armap): Rename from
+ compute_and_write_armap. Make non-static. Change all callers.
+ * ecoff.c (_bfd_ecoff_slurp_armap): Call _bfd_read_ar_hdr rather
+ than _bfd_snarf_ar_hdr.
+ * aout-target.h (MY_read_ar_hdr): Define if not defined.
+ * ieee.c (ieee_read_ar_hdr): Define.
+ * libecoff.h (_bfd_ecoff_read_ar_hdr): Define.
+ * oasys.c (oasys_read_ar_hdr): Define.
+ * som.c (som_read_ar_hdr): Define.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+Thu Oct 5 14:04:07 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * peicode.c (coff_swap_filehdr_in): If symptr is
+ zero, there aren't any symbols, even if nsyms is set.
+
+Thu Oct 5 11:45:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libecoff.h (struct ecoff_backend_data): Add adjust_headers
+ field.
+ * ecoff.c (ecoff_sec_to_styp_flags): Check for various Alpha
+ sections, and set styp correctly for them: .got, .hash, .dynamic,
+ .liblist, .rel.dyn, .conflic, .dynstr, .dynsym, .comment.
+ (_bfd_ecoff_styp_to_sec_flags): Check for various Alpha section
+ types.
+ (ecoff_sort_hdrs): New static function.
+ (ecoff_compute_section_file_positions): Return boolean, not void.
+ Sort the sections by VMA before looking through them. Put the
+ first non SEC_ALLOC section on a new page. Put every SEC_ALLOC
+ section on an appropriate boundary within the page.
+ (ecoff_compute_reloc_file_positions): Check return value of
+ ecoff_compute_section_file_positions.
+ (_bfd_ecoff_set_section_contents): Likewise.
+ (_bfd_ecoff_write_object_contents): Check for various Alpha
+ section types when incrementing text_size and data_size. Call
+ adjust_headers backend function if it exists.
+ * coff-alpha.c (alpha_adjust_headers): New static function.
+ (alpha_ecoff_backend_data): Initialize adjust_headers field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+
+ * hosts/i386bsd.h: Restore file incorrectly deleted on Sep 6.
+
+Wed Oct 4 18:15:02 1995 Jeff Law (law@hurl.cygnus.com)
+
+ * rs6000-core.c (CORE_VERSION_1): Use CORE_VERSION_1 instead
+ of ALTERNATE_AIX_CORE_FORMAT.
+ * configure.in (aix4): No longer need CORE_FLAGS.
+ * configure: Updated.
+
+Wed Oct 4 15:36:36 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ NS32k changes from Ian Dall:
+ * aoutx.h (MY_final_link_relocate, MY_relocate_contents): New
+ macros.
+ (aout_link_input_section_std, aout_link_input_section_ext,
+ aout_link_reloc_link_order): Call them instead of _bfd_*
+ versions.
+ * aout-target.h (MY_exec_header_not_counted): New macro, defaults
+ to zero.
+ (backend_data): Use it instead of hardcoded zero.
+
+ * aout-ns32k.c (CTOR_TABLE_RELOC_HOWTO): New macro.
+ (MY_swap_std_reloc_out): Use udata.i for KEEPIT, don't call stoi.
+
+ * ns32knetbsd.c: Include bfd.h.
+ (MY_text_includes_header, MY_bfd_reloc_type_lookup): New macros.
+ (MY_bfd_reloc_type_lookup): Declare function too.
+ * pc532-mach.c (set_sizes): Don't declare.
+ (MY_text_includes_header, MY_exec_header_not_counted): Define.
+ (backend_data, MY_backend_data): Don't define.
+
+ * config.bfd: Treat ns32k-pc532-ux* like ns32k-pc532-mach*, and
+ ns32k-*-lites* like ns32k-*-netbsd*.
+
+ * hosts/nbsd.h: Swap order of sys/vmparam.h and sys/param.h, to
+ compile on lites.
+
+Wed Oct 4 14:15:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): Restore setting
+ f_timdat to 0, deleted on August 22.
+
+Tue Oct 3 16:28:32 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coffcode.h (coff_bfd_copy_private_symbol_data,
+ coff_bfd_copy_private_section_data,
+ coff_bfd_copy_private_bfd_data): ifdef to allow overrides.
+ * peicode.h (coff_bfd_copy_private_bfd_data): New
+ (pe_bfd_copy_private_bfd_data): New.
+ (coff_swap_scnhdr_in): Swap bss size into the right place.
+ (pe_print_private_bfd_data): Add some newlines.
+
+Tue Oct 3 11:53:04 1995 Jeff Law (law@hurl.cygnus.com)
+
+ * som.c (setup_sections): Don't die if a space has no subspaces.
+
+Mon Oct 2 14:08:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't let a weak
+ dynamic symbol override a common symbol. Don't change the size or
+ type if they have been set and the new symbol is not a definition.
+ Warn if the size or type changes.
+
+Sun Oct 1 01:34:41 1995 Jeff Law (law@hurl.cygnus.com)
+
+ * som.c (som_begin_writing): Don't write the symbol table or
+ symbol strings.
+ (som_finish_writing): Write them here. Place them after the
+ subspace data, but before the relocs.
+
+Fri Sep 29 11:01:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_add_one_symbol): Just pass false, not
+ info->shared_library, to sunos_create_dynamic_sections.
+ (sunos_scan_ext_relocs): Don't warn about a reloc in the .text
+ section.
+ (sunos_check_dynamic_reloc): Remove .text section assertion.
+
+Thu Sep 28 18:48:47 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config.bfd: Add powerpc-*-macos*, powerpc-*-mpw*.
+ * configure, configure.in: Add pmac_xcoff_vec case.
+ * Makefile.in (BFD32_BACKENDS): Add coff-pmac.o.
+ * coff-pmac.c: New file, PowerMac XCOFF support.
+ * coffcode.h (coff_set_arch_mach_hook): Add PowerMac case.
+ * targets.c (pmac_xcoff_vec): Declare.
+
+ * mpw-config.in: Various changes to be compatible with the
+ autoconf-based configury.
+ * mpw-make.sed: New file, sed commands to translate Unix
+ makefile into MPW syntax.
+ * mpw-make.in: Remove.
+ * hosts/mpw.h: Remove.
+ * bfd-in.h, bfd-in2.h: If MPW, include the file that defines
+ true and false as enums, then define TRUE_FALSE_ALREADY_DEFINED.
+
+Thu Sep 28 17:06:23 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * binary.c (binary_get_symtab): Return an empty string on error.
+ * opncls.c (bfd_fdpenr): Change WIN32 restriction to WINGDB.
+
+Thu Sep 28 15:30:44 1995 Kim Knuttila <krk@nellie>
+
+ * coff-ppc.c: Reformatted according to gnu conventions
+ Removed irrelevant "if 0" code
+
+Thu Sep 28 11:19:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * hp300hpux.c (convert_sym_type): Treat secondary symbols as weak
+ symbols rather than as indirect symbols.
+ (MY(slurp_symbol_table)): Don't do anything special about
+ secondary symbols.
+
+ * coffcode.h (coff_new_section_hook): Make sure that the alignment
+ of .ctors and .dtors sections is no larger than 2.
+
+ * sunos.c (sunos_add_one_symbol): Don't change
+ bfd_link_hash_common to bfd_link_hash_new, since it may be on the
+ undef list.
+ (bfd_sunos_record_link_assignment): Don't put __DYNAMIC in the
+ dynamic symbols when creating a shared library.
+ (sunos_scan_ext_relocs): Handle relocs correctly when creating a
+ shared library.
+ (sunos_scan_dynamic_symbol): Don't mark the __DYNAMIC symbol as
+ written even if it is not defined in a regular object.
+ (sunos_write_dynamic_symbol): Use plt_offset for the address of
+ the jump table reloc. Add an assertion. Use RELOC_JMP_SLOT
+ rather than the constant 22.
+ (sunos_check_dynamic_reloc): Handle creating a shared library.
+ (sunos_finish_dynamic_link): Set the first entry in the GOT to
+ zero when creating a shared library.
+ * aoutx.h (NAME(aout,final_link)): If there is a symbol __DYNAMIC,
+ write it out at the start of the symbol table.
+
+ * Makefile.in (BFD32_BACKENDS): Add coff-arm.o.
+
+Thu Sep 28 00:58:05 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * config.bfd: Add arm-*-coff.
+ * configure.in, configure: Add armcoff_{little,big}_vec.
+ * targets.c (armcoff_{little,big}_vec): Declare.
+ (bfd_target_vector): Add armcoff_{little,big}_vec.
+ * coff-arm.c (armcoff_{little,big}_vec): Always define.
+
+Wed Sep 27 10:37:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * targets.c (bfd_find_target): Remove debugging code.
+
+Wed Sep 27 07:23:39 1995 Kim Knuttila <krk@nellie>
+
+ * coff-ppc.c, pe-ppc.c, pei-ppc.c: Initial bfd for coff/PE
+ support on powerpc.
+ * Makefile.in: added *-ppc files
+ * coffcode.h: ppc MAGIC, and use peicode.h rather than coffswap.h to
+ allow pe based .o's to be shared with other tools on ppc/NT
+ * config.bfd: added powerpc[le]-[pe|winnt] config support
+ * configure, configure.in: added bfd_powerpc[le]_pe[i]_vec
+ * peicode.h: Added more section flags for PE on ppc
+ Added coff_swap_filehdr_out to allow peicode.h to be
+ used for non-image PE files on ppc.
+ Check for image, or not, before copying pe_opthdr
+ * targets.c: Added new bfd's
+ * targets.c: Removed two inactive bfds that shouldn't have made it this
+ far.
+
+Tue Sep 26 14:06:41 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_reloc_type): Rename from reloc_type, and use
+ explicit values to initialize all relocs. Change all users.
+ (ppc_elf_brtaken_inner): New function to handle branch predicition
+ relocs.
+ (ppc_elf_brtaken_reloc): Ditto.
+ (ppc_elf_howto_raw): Use new functions. Make sure all unsupported
+ relocs use ppc_elf_unsupported_reloc.
+ (ppc_elf_merge_private_bfd_data): Keep track of whether an error
+ needs to be reported.
+ (ppc_elf_relocate_section): Support branch prediction relocs.
+
+Tue Sep 26 12:48:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd.c (bfd_assert): Remove \n from string passed to
+ _bfd_error_handler.
+
+ * coff-i386.c: (TWO_DATA_SECS): Don't define.
+ * coffcode.h (bfd_coff_backend_data): Remove _bfd_make_section_hook.
+ (bfd_coff_make_section_hook): Don't define.
+ (coff_make_section_hook): Remove.
+ (sec_to_styp_flags): Remove TWO_DATA_SECS case.
+ (styp_to_sec_flags): Likewise.
+ (coff_write_object_contents): Likewise.
+ (bfd_coff_std_swap_table): Don't initialize make_section_hook
+ field.
+ * libcoff.h: Rebuild.
+ * coffgen.c (make_a_section_from_file): Just call
+ bfd_make_section_anyway, not bfd_make_section or
+ bfd_coff_make_section_hook.
+ * ecoff.c (_bfd_ecoff_make_section_hook): Remove.
+ * libecoff.h (_bfd_ecoff_make_section_hook): Don't declare.
+ * coff-alpha.c (alpha_ecoff_backend_data): Don't initialize
+ make_section_hook field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+
+ * aoutx.h (translate_from_native_sym_flags): Don't try to stuff
+ pointers into value field for warning and indirect symbols; just
+ leave the value field alone.
+ * linker.c (generic_link_add_symbol_list): Use next symbol for
+ warning and indirect symbols, rather than looking in symbol value.
+ * ecoff.c (ecoff_set_symbol_info): Remove indirect_ptr_ptr
+ parameter. Change all callers. Remove support for indirect
+ symbols; it didn't work anyhow.
+ (_bfd_ecoff_slurp_symbol_table): Remove indirect_ptr variable.
+ * syms.c: Change comments about BSF_WARNING and BSF_INDIRECT.
+ * bfd-in2.h: Rebuild.
+
+Mon Sep 25 16:04:09 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): For all 14-bit branch relocs,
+ go back to telling the tools this reloc operates on 32 bits.
+
+Mon Sep 25 11:48:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aout-adobe.c (aout_adobe_callback): Use _bfd_error_handler
+ rather than a direct fprintf.
+ * archive.c (_bfd_write_archive_contents): Likewise.
+ * coffcode.h (coff_slurp_symbol_table): Likewise.
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data): Likewise.
+ (ppc_elf_unsupported_reloc): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ * i386linux.c (linux_tally_symbols): Likewise.
+ (linux_finish_dynamic_link): Likewise.
+ * osf-core.c (osf_core_core_file_p): Likewise.
+ * rs6000-core.c (rs6000coff_get_section_contents): Likewise.
+ * som.c (som_sizeof_headers): Likewise.
+ * srec.c (srec_bad_byte): Likewise.
+ * bfd.c (bfd_assert): Likewise. Also change file to be const.
+ * libbfd-in.h (bfd_assert): Declare first parameter const.
+ * libbfd.h: Rebuild.
+ * coff-a29k.c (a29k_reloc): Don't bother to fprintf; returning
+ bfd_reloc_overflow is enough.
+ * coff-h8300.c (rtype2howto): Don't bother to fprintf; just abort.
+ * coff-h8500.c (rtype2howto): Likewise.
+ * coff-z8k.c (rtype2howto): Likewise.
+ * coffcode.h (dummy_reloc16_extra_cases): Likewise.
+ * elf.c (_bfd_elf_get_lineno): Likewise.
+ (_bfd_elf_no_info_to_howto): Likewise.
+ (_bfd_elf_no_info_to_howto_rel): Likewise.
+ * hp300hpux.c (convert_sym_type): Likewise.
+ (MY(swap_std_reloc_in)): Likewise.
+ * elf.c (bfd_section_from_shdr): Remove #if 0 sections.
+
+ * libaout.h (struct aoutdata): Add line_buf field.
+ * aoutx.h (NAME(aout,find_nearest_line)): Remove statics buffer
+ and filename_buffer. Instead, use a malloc buffer stored in the
+ new line_buf field. Remove length restrictions.
+
+ * coffgen.c (string_size): Remove static variable.
+ (debug_string_size, debug_string_section): Likewise.
+ (coff_fix_symbol_name): Add string_size_p, debug_string_section_p,
+ and debug_string_size_p parameters. Use them instead of the
+ global variables. Change all callers.
+ (coff_write_symbol): Likewise.
+ (coff_write_alien_symbol, coff_write_native_symbol): Likewise.
+ (coff_write_symbols): Add local variables to replace removed
+ global variables.
+
+ * libcoff-in.h (struct coff_section_tdata): Add offset, i,
+ function, and line_base fields.
+ * libcoff.h: Rebuild.
+ * coffgen.c (coff_find_nearest_line): Use section tdata to cache
+ information, rather than using static variables.
+
+ * sunos.c (sunos_read_dynamic_info): Adjust offsets in an NMAGIC
+ file. From Peter DeWolf <pld@amt.tay1.dec.com>.
+
+ * init.c (initialized): Remove static variable.
+ (bfd_init): Don't bother setting initialized.
+ (bfd_check_init): Remove.
+ * opncls.c (_bfd_new_bfd): Don't call bfd_check_init.
+ * libbfd.h: Rebuild.
+
+Sat Sep 23 01:22:23 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-core.c (rs6000coff_core_p): Don't check the core file
+ size for full core dumps. Copy core file header to private data.
+ (rs6000coff_core_file_failing_command,
+ rs6000coff_core_file_failing_signal): New functions to extract
+ the file name and terminating signal from the core file.
+ * coff-rs6000.c: Use them.
+
+Fri Sep 22 17:44:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Change arch info to be const, initialized at compile time.
+ * archures.c: Reindent many functions. Change CONST to const.
+ (bfd_arch_info_type): Make arch_name const. Remove disassemble;
+ nothing set it anyhow. Make next const.
+ (bfd_arch_info_list): Remove.
+ (bfd_archures_list): Rename from archures_init_table. Change from
+ a table of function pointers to a table of bfd_arch_info_type
+ structure addresses.
+ (bfd_scan_arch): Rewrite accordingly. Return a const pointer.
+ (bfd_lookup_arch): Likewise.
+ (bfd_set_arch_info): Rewrite accordingly. Change argument to be a
+ const pointer.
+ (bfd_default_arch_struct): Make const.
+ (bfd_arch_init, bfd_arch_linkin): Remove.
+ (bfd_get_arch_info): Return a const pointer.
+ * init.c (bfd_init): Don't call bfd_arch_init.
+ * bfd.c (struct _bfd): Make arch_info const.
+ * bfd-in2.h: Rebuild.
+ * libbfd.h: Rebuild.
+ * configure.in: Put & before everything in $selarchs.
+ * configure: Rebuild.
+ * cpu-*.c: Change bfd_*_arch from a function which calls
+ bfd_arch_linkin to a const structure.
+ * ieee.c (ieee_object_p): Make arch const.
+
+Fri Sep 22 16:23:18 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * reloc.c (bfd_reloc_code_type): Add relocations to support all of
+ PowerPC V.4.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+ * elf32-ppc.c (reloc_type): Update names to match current draft.
+ (ppc_elf_howto_raw): Mark 14 bit relocs as short sized and PC
+ relative. Update names to current V.4 draft.
+ (ppc_elf_reloc_type_lookup): Add support for more relocations.
+ (ppc_elf_relocate_section): Rename relocations to match draft.
+
+Thu Sep 21 21:53:18 1995 Michael Meissner <meissner@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data): Allow modules
+ compiled with -mrelocatable-lib to be linked with either normal
+ modules or -mrelocatable modules.
+
+Wed Sep 20 12:03:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): Clear the vstamp field
+ in the a.out header.
+
+ * aoutx.h (NAME(aout,swap_ext_reloc_out)): Don't set r_extern for
+ a reloc against a local symbol, even if it's not a section.
+
+Tue Sep 19 17:02:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * targets.c (bfd_target): Remove unused align_power_min field.
+ * bfd-in2.h: Rebuild.
+ * All backends: Remove initialization of align_power_min.
+
+Tue Sep 19 14:02:21 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * peicode.h (coff_swap_scnhdr_out): Get sizes for BSS right.
+
+Mon Sep 18 14:35:01 1995 Arne H. Juul <arnej@pvv.unit.no>
+
+ * config.bfd (mips-dec-netbsd*): New target.
+ * configure.host (mips-dec-netbsd*): New host.
+ * configure.in (mips-dec-netbsd*): New native.
+ * configure: Rebuild.
+
+Fri Sep 15 10:24:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Make the COFF backend linker merge common types:
+ * cofflink.c (struct coff_debug_merge_element): Define.
+ (struct coff_debug_merge_type): Define.
+ (struct coff_debug_merge_hash_entry): Define.
+ (struct coff_debug_merge_hash_table): Define.
+ (coff_debug_merge_hash_table_init): Define.
+ (coff_debug_merge_hash_table_free): Define.
+ (coff_debug_merge_hash_lookup): Define.
+ (struct coff_final_link_info): Add debug_merge field.
+ (coff_debug_merge_hash_newfunc): New static function.
+ (_bfd_coff_final_link): Allocate and free debug_merge table.
+ (coff_link_input_bfd): Merge identical enum, struct and union
+ types.
+
+Thu Sep 14 14:53:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Convert i960 COFF to use COFF backend linker.
+ * coff-i960.c (coff_i960_relocate): Use a coff_section_data
+ structure to store the symbol being used.
+ (coff_i960_start_final_link): New static function.
+ (coff_i960_relocate_section): New static function.
+ (coff_i960_adjust_symndx): New static function.
+ (coff_start_final_link): Define.
+ (coff_relocate_section): Define.
+ (coff_adjust_symndx): Define.
+ * coffcode.h (bfd_coff_backend_data): Add new callback function
+ _bfd_coff_start_final_link.
+ (bfd_coff_start_final_link): Define.
+ (coff_start_final_link): Define if not defined.
+ (bfd_coff_std_swap_table): Add coff_start_final_link.
+ * cofflink.c (_bfd_coff_internal_syment_name): Make globally
+ visible.
+ (_bfd_coff_final_link): Call bfd_coff_start_final_link if the
+ function callback is not NULL.
+ * libcoff-in.h (struct coff_section_tdata): Add tdata field.
+ (_bfd_coff_internal_syment_name): Declare.
+ * libcoff.h: Rebuild.
+ * configure.in (icoff_big_vec): Add cofflink.o.
+ (icoff_little_vec): Likewise.
+ * configure: Rebuild.
+
+Wed Sep 13 17:38:23 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * Makefile.in (clean-info): Remove extraneous tab from line
+ following action.
+
+Wed Sep 13 13:27:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (coff_link_input_bfd): Fail if a section with no
+ contents has relocs.
+
+Thu Sep 12 12:45:34 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coffcode.h (coff_compute_section_file_positions): Keep the
+ raw size safe.
+ (coff_write_object_contents): Remember if it's a relocatable
+ file.
+ * libcoff-in.h (pe_data_type): New member 'has_reloc_section'
+ * peicode.h (coff_swap_filehdr_out): Clear not-reloc flag
+ if relocatable file. Swap out saved raw size.
+
+Tue Sep 12 12:14:33 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (do_maintainer_clean): Rename from do_realclean.
+ (maintainer-clean): Rename from realclean, passing
+ maintainer-clean down to subdirectories, but leave realclean as a
+ synonym.
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Pass symbol name to
+ warning callback.
+
+ * dep-in.sed: Remove config.h from generated dependencies.
+
+ * sunos.c (sunos_slurp_dynamic_symtab): New static function,
+ broken out of sunos_canonicalize_dynamic_symtab.
+ (sunos_canonicalize_dynamic_symtab): Call new function
+ sunos_slurp_dynamic_symtab.
+ (sunos_add_dynamic_symbols): Add three new parameters. Return the
+ dynamic symbol table to the caller.
+ * aoutx.h (aout_link_add_symbols): Permit add_dynamic_symbols
+ callback to override the symbols being read.
+ * libaout.h (struct aout_backend_data): Add three new parameters
+ to add_dynamic_symbols callback.
+
+ Extensive minor changes to avoid various gcc warnings. Also:
+ * Makefile.in (BFD32_BACKENDS): Remove coff-arm.o.
+ * archures.c (bfd_arch_info_type): Change mach field from long to
+ unsigned long.
+ (bfd_lookup_arch): Change machine parameter from long to unsigned
+ long.
+
+Mon Sep 11 10:55:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_scan_std_relocs): Fix BFD_ASSERT: it's OK to find
+ a symbol with a non-zero plt_offset.
+
+Fri Sep 8 11:47:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (align_file_position): Remove; not used.
+
+ * configure.in: Only check for <sys/procfs.h> on a native system,
+ and make sure it defines prstatus_t.
+ * configure: Rebuild.
+
+Thu Sep 7 12:48:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_write_dynamic_symbol): Correct m68k abort test.
+
+ * config.in: Rename from config.h.in.
+ * configure.in: Call AC_CONFIG_HEADER with config.h:config.in.
+ Check for config.h:config.in when creating stamp-h.
+ * configure: Rebuild.
+ * Makefile.in (stamp-h): Depend upon config.in rather than
+ config.h.in. Set CONFIG_HEADERS to config.h:config.in when
+ calling config.status.
+
+ * Makefile.in (do_distclean): Remove config.h and stamp-h.
+ (Makefile): Just rebuild Makefile.
+ (config.h, stamp-h): New targets.
+ * configure.in: Create stamp-h when rebuilding config.h.
+ * configure: Rebuild.
+
+Wed Sep 6 15:00:33 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_CONFIG_HEADER. Substitute
+ HOST_64BIT_LONG. Check that various header files exist. Check
+ that fcntl exists. Call BFD_BINARY_FOPEN. Check whether malloc
+ and/or free need to be declared. Don't make a link to sysdep.h.
+ Define TRAD_HEADER for various hosts.
+ * configure: Rebuild.
+ * configure.host: Don't set my_host. Add definitions taken from
+ host header files for various entries. Remove entries which now
+ do nothing.
+ * acconfig.h: New file.
+ * config.h.in: New file, built by autoheader.
+ * sysdep.h: New file.
+ * Makefile.in (do_distclean): Don't remove sysdep.h.
+ (RECONFIG): Remove.
+ (LOCAL_H_DEPS): New variable.
+ ($(BFD_LIBS)): Use $(LOCAL_H_DEPS) rather than libbfd.h and
+ $(RECONFIG).
+ ($(BFD_MACHINES), $(BFD_BACKENDS)): Likewise.
+ ($(OPTIONAL_BACKENDS)): Likewise.
+ (stmp-bfd.h): Just substitute for BFD_HOST_64BIT_LONG, rather than
+ looking through sysdep.h.
+ * bfd-in.h (BFD_HOST_64BIT_LONG): Define; set by Makefile.
+ (BFD_HOST_64_BIT): Define based on BFD_HOST_64BIT_LONG.
+ (fprintf_vma, sprintf_vma): Likewise.
+ (int64_type, uint64_type): Don't define.
+ * bfd-in2.h: Rebuild.
+ * archures.c, bfd.c, srec.c: Include <ctype.h>.
+ * elfcore.h: Check HAVE_SYS_PROCFS_H rather than HAVE_PROCFS.
+ * lynx-core.c: Include stuff from old hosts/lynx.h.
+ * opncls.c (bfd_fdopenr): Check HAVE_FNCTL and defined (F_GETFL),
+ rather than NO_FCNTL.
+ * targets.c (bfd_target_list): Check HOST_HPPAHPUX and ! __STDC__
+ rather than NATIVE_HPPAHPUX_COMPILER.
+ * trad-core.c: Don't include <errno.h>. Include TRAD_HEADER if it
+ is defined.
+ * hosts/*.h: Remove all header files which merely include,
+ declare, and define things. Leave header files which define
+ information needed by trad-core.c.
+
+ * aclocal.m4 (BFD_BINARY_FOPEN): Define.
+ (BFD_CC_FOR_BUILD): Define.
+ * configure.in: Use BFD_CC_FOR_BUILD.
+ * configure: Rebuild.
+
+Tue Sep 5 19:35:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4: Don't try to grep ../Makefile if it doesn't exist.
+ * configure: Rebuild.
+
+ * coff-sparc.c (CALC_ADDEND): Don't set the addend to the value of
+ a global symbol.
+
+Tue Sep 5 12:48:26 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * config.bfd: i386pe_ve -> i386pe_vec.
+
+Mon Sep 4 14:02:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Incorporate host Makefile fragments by setting
+ shell variables.
+ * configure.in: Call AC_PROG_CC. Substitute CFLAGS, HDEFINES and
+ AR. Call AC_PROG_INSTALL. Substitute CC_FOR_BUILD, choosing a
+ value based on whether the code is being compiled by a cross
+ compiler. Don't substitute host_makefile_frag or frags.
+ * aclocal.m4: New file to define local AC_PROG_CC.
+ * configure: Rebuild.
+ * Makefile.in (INSTALL): Set to @INSTALL@.
+ (INSTALL_PROGRAM): Set to @INSTALL_PROGRAM@.
+ (INSTALL_DATA): Set to @INSTALL_DATA@.
+ (AR): Set to @AR@.
+ (CC): Define as @CC@.
+ (CFLAGS): Set to @CFLAGS@.
+ (CC_FOR_BUILD): Set to @CC_FOR_BUILD@.
+ (@host_makefile_frag@): Remove.
+ (ALL_CFLAGS): Change $(HDEFINES) to @HDEFINES@. Move $(CFLAGS)
+ after other options.
+ (config.status): Remove dependency upon @frags@.
+ * config/*.mh, config/README: Remove.
+
+ * config.bfd: Rewrite to incorporate the contents of the Makefile
+ fragments by setting shell variables, rather than merely returning
+ the name of a Makefile fragment.
+ * configure.in: Use shell variables set by config.bfd rather than
+ looking at the target Makefile fragment files. Don't substitute
+ target_makefile_frag. Do substitute TDEFINES.
+ * configure: Rebuild.
+ * Makefile.in (@target_makefile_frag@): Remove.
+ (ALL_CFLAGS): Change $(TDEFINES) to @TDEFINES@.
+ * config/*.mt: Remove.
+
+Mon Sep 4 03:13:28 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: Put changequote lines around "i[345]86" patterns
+ section of core file support.
+
+Sun Sep 3 11:31:58 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_print_private_bfd_data): Define to use the
+ generic version.
+
+Fri Sep 1 17:08:40 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * peicode.h (coff_swap_aouthdr_in): Add ImageBase to
+ entry, text_start and data_start.
+
+Fri Sep 1 18:06:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (OFILES): Remove $(TDEPFILES).
+ * config/apollo.mt (TDEPFILES): Remove.
+ * config/README: Update.
+
+ * configure.in: For a native configuration, set COREFILE and
+ COREFLAG based on the canonical host name.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (ALL_CFLAGS): Add @COREFLAG@.
+ (OFILES): Replace $(HDEPFILES) with @COREFILE@.
+ * coff-rs6000.c: Check AIX_CORE rather than HOST_AIX for core file
+ support routines. Check LYNX_CORE rather than HOST_LYNX.
+ * lynx-core.c: Check LYNX_CORE rather than HOST_LYNX.
+ * i386lynx.c: Likewise.
+ * m68klynx.c: Likewise.
+ * sparclynx.c: Likewise.
+ * rs6000-core.c: Check AIX_CORE rather than HOST_AIX.
+ * *-core.c: Comment changes.
+ * config/decstation.mh (HDEPFILES): Remove.
+ (HDEFINES): Remove -DTRAD_CORE.
+ * config/irix3.mh (RANLIB): Remove.
+ * config/irix4.mh (HDEPFILES, RANLIB): Remove.
+ (HDEFINES): Remove -DIRIX_CORE.
+ * config/riscos.mh (RANLIB, HDEPFILES): Remove.
+ (HDEFINES): Remove -DTRAD_CORE.
+ * config/ncr3000.mh (AR_FLAGS, RANLIB): Remove.
+ * config/ultra3.mh (RANLIB): Remove.
+ * config/aix4.mh, config/alphaosf.mh, config/amix.mh: Remove.
+ * config/apollo.mh, config/delta68.mh, config/delta88.mh: Remove.
+ * config/dpx2.mh, config/esix.mh, config/harris.mh: Remove.
+ * config/hp300.mh, config/hp300bsd.mh, config/hppabsd.mh: Remove.
+ * config/hppahpux.mh, config/hppaosf.mh: Remove.
+ * config/i386aix.mh, config/i386bsd.mh: Remove.
+ * config/i386linux.mh, config/i386mach3.mh: Remove.
+ * config/i386sco.mh, config/i386v.mh, config/i386v4.mh: Remove.
+ * config/irix5.mh, config/m88kmach3.mh, config/mipsbsd.mh: Remove.
+ * config/mipsmach3.mh, config/news-mips.mh: Remove.
+ * config/news.mh, config/pc532mach.mh, config/riscix.mh: Remove.
+ * config/rs600.mh, config/rs6000lynx.mh: Remove.
+ * config/solaris2.mh, config/stratus.mh: Remove.
+ * config/symmetry.mh, config/sysv4.mh, config/tahoe.mh: Remove.
+ * config/vaxbsd.mh, config/vaxult.mh, config/vaxult2.mh: Remove.
+
+Fri Sep 1 15:18:50 1995 Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>
+
+ * elflink.h (elf_bfd_final_link): Don't change a DT_INIT or
+ DT_FINI entry if the appropriate symbol is not in the hash table.
+
+ * libelf.h (struct elf_backend_data): Add create_program_headers
+ and want_hdr_in_seg fields.
+ * elfxx-target.h (elf_backend_want_hdr_in_seg): Define if not
+ defined.
+ (elf_backend_create_program_headers): Likewise.
+ (elfNN_bed): Initialize create_program_headers and
+ want_hdr_in_seg.
+ * elf.c (get_program_header_size): Call create_program_headers
+ backend routine.
+ (map_program_segments): Check want_hdr_in_seg backend field. Call
+ create_program_headers backend routine.
+
+ * elf.c (assign_file_positions_except_relocs): Align non allocated
+ sections when creating an executable.
+
+ * elfcode.h (elf_swap_phdr_in): Make non static.
+ (elf_swap_phdr_out): Make non static.
+ * libelf.h (bfd_elf32_swap_phdr_in): Declare.
+ (bfd_elf32_swap_phdr_out): Declare.
+ (bfd_elf64_swap_phdr_in): Declare.
+ (bfd_elf64_swap_phdr_out): Declare.
+
+ * ecofflink.c (ecoff_collect_shuffle): New static function.
+ (_bfd_ecoff_get_accumulated_pdr): New function.
+ (_bfd_ecoff_get_accumulated_sym): New function.
+ (_bfd_ecoff_get_accumulated_ss): New function.
+ * libbfd-in.h (_bfd_ecoff_get_accumulated_pdr): Declare.
+ (_bfd_ecoff_get_accumulated_sym): Declare.
+ (_bfd_ecoff_get_accumulated_ss): Declare.
+ * libbfd.h: Rebuild.
+
+Fri Sep 1 13:20:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libecoff.h (_bfd_ecoff_bfd_print_private_bfd_data): Fix typo.
+
+ * elflink.h (elf_link_add_object_symbols): Handle indirect and
+ warning symbols. If any section is named .gnu.warning.XXX, treat
+ the contents as a warning to be issued if the symbol XXX is
+ referenced.
+ (elf_link_output_extsym): For an indirect or warning symbol, just
+ output the symbol it points to.
+
+ * linker.c (_bfd_link_hash_newfunc): Don't bother to set bfd_error
+ if bfd_hash_allocate fails, since it will already be set.
+ (generic_link_hash_newfunc): Likewise.
+ (archive_hash_newfunc): Likewise.
+ (hash_entry_bfd): New static function.
+ (_bfd_generic_link_add_one_symbol): Pass new arguments to warning
+ callback. Allocate a new warning using the hash table newfunc.
+ Use bfd_hash_replace to update the entry in the hash table, rather
+ than assuming we can copy the fields with structure assignment.
+
+ * hash.c (bfd_hash_replace): New function.
+ * bfd-in.h (bfd_hash_replace): Declare.
+ * bfd-in2.h: Rebuild.
+
+Fri Sep 1 08:12:50 1995 James G. Smith <jsmith@beauty.cygnus.com>
+
+ * config.bfd: Add mips*vr4300-*-elf* target.
+ * config/mipsbvr4300.mt: Added.
+
+Thu Aug 31 16:00:53 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in: Update dependencies.
+ * aout-target.h (MY_bfd_print_private_bfd_data): New.
+ * bfd-in.h (PE STUFF): Deleted.
+ * bfd.c (tdata->pe_obj_data): New.
+ (bfd_print_private_bfd_data): New.
+ * coff-i386.c, coff-arm.c (coff_*-rtype_to_howto): Get image base from
+ new place.
+ * libcoff.h, libbfd.h, bfd-in2.h: Rebuilt.
+ * coffcode.h (pe_value): Delete
+ (coff_mkobject, coff_mkobject_hook): Conditionally build.
+ (coff_compute_section_file_positions): Look in new place.
+ (add_data_entry, fill_pe_header_info): Deleted.
+ (coff_write_object_contents): Remove PE stuff.
+ (coff_bfd_print_private_bfd_data): New.
+ * coffswap.h: Remove PE stuff.
+ * elfxx-target.h (bfd_elfNN_bfd_print_private_bfd_data): New.
+ * libbfd-in.h (_bfd_generic_bfd_print_private_bfd_data): New.
+ * libcoff-in.h (pe_data_type): New.
+ * libecoff.h (_bfd_ecoff_bfd_print_private_bfd_data): New.
+ * targets.c (_bfd_print_private_bfd_data): New.
+ * peicode.h: New file.
+
+Thu Aug 31 11:49:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd-in.h: Add extern "C" if __cplusplus.
+ * bfd-in2.h: Rebuild.
+
+ * coff-mips.c (mips_relocate_section): Don't convert a reloc
+ against an absolute symbol into a reloc against a section.
+
+Thu Aug 31 08:00:14 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coff-arm.c (coff_arm_reloc): Fix common size problem.
+ (i3coff_object_p): Delete.
+
+Wed Aug 30 20:41:27 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coff-arm.c (deletemeacoff_arm_reloc): Deleted.
+ (arm26): Not partial inplace.
+ * coffcode.h (coff_compute_section_file_positions): Don't
+ do page aligning if COFF_PAGE_SIZE isn't defined.
+ * coffswap.h (coff_swap_scnhdr_in): Update image base correctly.
+
+Tue Aug 29 13:50:21 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * coffcode.h (coff_compute_section_file_positions):
+ Compile even if COFF_PAGE_SIZE isn't defined.
+ * cofflink.c (_bfd_coff_generate_reloc_section): Write
+ base file info as rvas.
+ * coff-arm.c (coff_rtype_to_howto): Deal with reloc 11.
+ * coffcode.h (coff_write_object_contents): Remove #if0ed code
+ Only remove empty sections in PE inmage files.
+ * libbfd.h, bfd-in2.h: regenerated.
+ * coff-arm.c (aoutarm_std_relo): New entry at 11.
+ (arm_reloc_type_lookup) : Understand type 11.
+ * coff-i386.c (howto_table): fix name of rva type.
+ (coff-i386_rtype_to_howto): Understand R_IMAGEBASE type.
+ * coffcode.h (sec_to_styp_flags): .edata is data.
+ (coff_compute_section_file_positions): Get page size right for PE.
+ Pagesize info is only valid in PE image files.
+ (fill_pe_header_info): Fix fields.
+ (coff_write_object_contents): Remove end_of_image calc.
+ (_bfd_coff_generate_reloc_section): Remove orphaned comment.
+ * coffswap.h (coff_swap_scnhdr_in): Don't always add IMAGE_BASE.
+ Swap in PE header.
+ (coff_swap_scnhdr_out): Setup PE flags correctly.
+ * reloc.c (BFD_RELOC_RVA): New field.
+
+Thu Aug 24 17:49:59 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * cofflink.c (coff_link_input_bfd): Don't include line numbers for
+ a section if its output section has no contents.
+
+Wed Aug 23 16:48:52 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.c (_bfd_ecoff_slurp_symbolic_info): Add parentheses to FIX
+ expression to avoid compiler bug on HP-UX 9.01.
+
+Wed Aug 23 09:49:39 1995 Steve Chamberlain <sac@rtl.cygnus.com>
+
+ * coffcode.h (pe_value): Unansify.
+
+Mon Aug 21 17:49:28 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * bfd-in.h (bfd_link_subsystem): Turn enum into #defines.
+ (bfd_link_pe_info_dval): New
+ (bfd_link_stack_heap): Renamed and massaged into bfd_link_pe_info.
+ * bfd-in2.h: rebuilt.
+ * bfd.c (NT_subsystem, NT_stack_heap): Deleted.
+ * coffcode.h (pe_value): New function.
+ (fill_pe_header_info): New function.
+ (coff_write_object_contents): Use new function.
+ (coff_write_object_contents): Initialze link_data if not set.
+ * cofflink.c (coff_final_link_info): Remove pe randomness.
+ (dores_com): Update info in bfd_link_pe_info_dval.
+ (process_embedded_commands): Use the bfd_link_pe_info_dval.
+ (_bfd_coff_final_link): Remove PE stuff, initialize
+ coff_data->link_info.
+ * coffswap.h (coff_swap_[aout|filehdr]_out): Use indirect PE pointer.
+ (coff_swap_scnhdr_out): Use real imagebase.
+ * libcoff-in.h (coff_data_type.link_info): New field.
+
+Mon Aug 21 11:10:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * linker.c (link_action): If an undefined reference follows an
+ undefined weak reference, change the type to undefined.
+ * elflink.h (elf_link_add_archive_symbols): Don't record an
+ undefined weak reference as defined, in case it turns into a real
+ undefined reference later in the same archive.
+
+Thu Aug 17 16:29:09 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * coff-sh.c (sh_relax_section): Cast value for used_by_bfd field
+ to PTR, not coff_section_tdata pointer, since PTR is the real type
+ of the field.
+ * cofflink.c (_bfd_coff_read_internal_relocs): Ditto.
+
+Thu Aug 17 14:44:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Add support for linking SPARC SunOS PIC compiled code.
+ * sunos.c (SPARC_PLT_PIC_WORD0): Define.
+ (SPARC_PLT_PIC_WORD1, SPARC_PLT_PIC_WORD2): Define.
+ (struct sunos_link_hash_entry): Add got_offset and plt_offset
+ fields.
+ (struct sunos_link_hash_table): Add dynamic_sections_created and
+ dynamic_sections_needed fields.
+ (sunos_link_hash_newfunc): Initialize new fields.
+ (sunos_link_hash_table_create): Initialize new fields.
+ (sunos_create_dynamic_sections): New static function, broken out
+ of sunos_add_dynamic_symbols.
+ (sunos_add_dynamic_symbols): Call sunos_create_dynamic_sections.
+ (sunos_add_one_symbol): Call sunos_create_dynamic_sections.
+ (bfd_sunos_size_dynamic_sections): Call sunos_scan_relocs before
+ checking whether we need to set up the dynamic link information.
+ Define __GLOBAL_OFFSET_TABLE if anything referred to it.
+ (sunos_scan_std_relocs): Call sunos_create_dynamic_sections. Use
+ plt_offset field; only put symbol in .plt if it is not defined by
+ a regular object.
+ (sunos_scan_ext_relocs): Likewise. Handle base relative relocs.
+ (sunos_scan_dynamic_symbol): Store dynobj in local variable.
+ (sunos_write_dynamic_symbol): Check plt_offset rather than
+ checking whether symbol is in .plt section. If symbol is defined
+ in a regular object file, use SPARC_PLT_PIC_WORD[012], and don't
+ add a JMP_TBL reloc.
+ (sunos_check_dynamic_reloc): Add contents and relocationp fields.
+ If plt_offset is set, redirect relocation to PLT. If this is a
+ base relative reloc, redirect relocation to GOT. Check
+ dynamic_sections_needed field rather than whether dynobj is set.
+ (sunos_finish_dynamic_link): Check dynamic_sections_needed field
+ rather than whether dynobj is set. Don't die if .need and .rules
+ sections were not created.
+ * aoutx.h (howto_table_ext): Mark PC10, PC22, and JMP_TBL entries
+ PC relative. Mark PC10 complain_overflow_dont. Mark PC22 and
+ JMP_TBL complain_overflow_signed.
+ (NAME(aout,final_link)): If info->shared is set, set DYNAMIC.
+ (aout_link_input_section_std): Call check_dynamic_reloc for all
+ relocs. Pass contents and &relocation. Don't warn about an
+ undefined symbol until check_dynamic_reloc has been called. Don't
+ warn about an undefined symbol for a base relative reloc.
+ (aout_link_input_section_ext): Likewise. For a base relative
+ reloc, always treat r_index as an index into the symbol table.
+ * libaout.h (struct aout_backend_data): Add contents and
+ relocation argument to check_dynamic_reloc entry point.
+ (struct aoutdata): Add local_got_offsets field.
+
+Wed Aug 16 01:03:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Fix bug in last change.
+
+Mon Aug 14 11:39:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,machine_type)): Handle a machine of
+ bfd_mach_sparc or bfd_mach_sparc64.
+
+ * elflink.h (elf_link_add_object_symbols): If a symbol is a weak
+ definition, add it to the dynamic symbol table if any dynamic
+ object mentions it. If we do add it, make sure we add the
+ corresponding real symbol.
+ (elf_adjust_dynamic_symbol): Adjust a weak defined symbol which we
+ put in the dynamic symbol table, even if no regular object refers
+ to it.
+ * elf32-i386.c (elf_i386_check_relocs): When creating a shared
+ library, don't allocate space for a PC relative reloc against a
+ local symbol.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Change assertion
+ to accept symbol with weakdef set.
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): When creating a shared
+ libary, don't copy over a PC relative reloc against a local
+ symbol.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+Sun Aug 13 00:40:58 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.h (R_HPPA_BEGIN_BRTAB): Define.
+ (R_HPPA_END_BRTAB): Likewise.
+ * som.c (som_write_fixups): Handle R_BEGIN_BRTAB and R_END_BRTAB.
+
+Thu Aug 10 15:53:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffswap.h (coff_swap_aux_in): Swap the array dimensions
+ whenever x_fcnary is not being used for something else, rather
+ than only for an array.
+ (coff_swap_aux_out): Likewise.
+
+Tue Aug 8 16:34:57 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Remove most
+ of special case stuff for PE. Now handled by relocs.
+ * coff-i386.c (coff_i386_reloc): Special case of PE type 7s.
+ (howto_table): Type 7 is dir32-rva.
+
+Tue Aug 8 10:15:43 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * configure.host: Recognize aix4 explicitly.
+ * rs6000-core.c (CORE_DATA_SIZE_FIELD): New macro to get a the size
+ of a core dump's data section. Provide alternate definition for aix4.
+ (SAVE_FIELD): Similarly for save state field (register info).
+ (STACK_END_ADDR): Provide definition suitable for aix4.
+ * config/{aix4.mh,aix4.mt}: New configuration files.
+ * hosts/aix4.h: Likewise.
+
+Mon Aug 7 23:03:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * som.c (som_bfd_copy_private_symbol_data): Cast initializations
+ to avoid warnings.
+
+Mon Aug 7 14:51:08 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_decode_symclass): Handle absolute symbols by checking
+ the SOM type (since they will rarely if ever be in the absolute
+ section).
+
+Wed Aug 6 09:12:50 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * archures.c (bfd_mach_sparc, bfd_mach_sparc64): Define.
+ * bfd-in2.h: Regenerated.
+ * cpu-sparc.c (sparc_arch_info): Renamed from arch_info_struct.
+ (sparc64_arch_info): New static variable.
+ (bfd_sparc_arch): Link in sparc64_arch_info.
+ * elf64-sparc.c (sparc64_elf_xxx): Renamed from elf64_xxx.
+ (sparc64_elf_object_p): New static function.
+ (elf_backend_object_p): Define.
+ * config/sparc64-elf.mt (SELECT_VECS): Add bfd_elf32_sparc_vec.
+
+Sat Aug 5 00:04:08 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som (som_get_reloc_upper_bound): Return -1 on error. Compute
+ return value with sizeof (arelent *), not sizeof (arelent).
+
+Wed Aug 2 12:32:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (bfd_section_from_shdr): If the section pointed to by the
+ sh_link field of a reloc section is not a symbol table, and the
+ file contains a single symbol table, clobber the sh_link field of
+ the reloc section to point to the symbol table.
+
+Tue Aug 1 10:09:01 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * coff-arm.c (howto reloc ARM26): Change size from 3 to 2.
+ (howto reloc ARM26D): Likewise.
+
+Mon Jul 24 14:17:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Use the line just before
+ the offset, not the one just after. Break out of the loop after
+ finding a function past the offset, not merely when finding a
+ function with a line defined.
+
+ * ecofflink.c (_bfd_ecoff_locate_line): When handling stabs:
+ correct setting of sym_ptr_end to consider symbols skipped when
+ setting sym_ptr; don't leave loop early unless an N_FUN is found
+ with a larger value.
+
+ * coff-sh.c (sh_coff_howtos): Mark R_SH_PCDISP8BY2 and R_SH_PCDISP
+ as PC relative. Describe R_SH_IMM16. Add entries for
+ R_SH_SWITCH16, R_SH_SWITCH32, R_SH_USES, R_SH_COUNT, and
+ R_SH_ALIGN.
+ (SWAP_IN_RELOC_OFFSET): Define.
+ (SWAP_OUT_RELOC_OFFSET): Define.
+ (CALC_ADDEND): Define.
+ (sh_reloc): Change sym_value and addr to type bfd_vma. Skip reloc
+ types other than R_SH_IMM32 and R_SH_PCDISP on an external symbol.
+ (coff_bfd_relax_section): Define.
+ (coff_bfd_get_relocated_section_contents): Define.
+ (sh_relax_section): New static function.
+ (sh_relax_delete_bytes): New static function.
+ (sh_relocate_section): Handle R_SH_PCDISP on an external symbol.
+ (sh_coff_get_relocated_section_contents): New static function.
+
+ * cofflink.c (coff_link_add_object_symbols): Call
+ _bfd_coff_get_external_symbols, not coff_link_get_symbols. Call
+ _bfd_coff_free_symbols, not coff_link_free_symbols. Call
+ _bfd_coff_read_string_table, not coff_read_string_table.
+ (coff_link_check_archive_element): Likewise.
+ (coff_link_input_bfd): Likewise.
+ (coff_link_get_symbols): Move to coffgen.c.
+ (coff_read_string_table): Likewise.
+ (coff_link_free_symbols): Likewise.
+ (_bfd_coff_internal_syment_name): New static function.
+ (coff_link_check_ar_symbols): Use _bfd_coff_internal_syment_name.
+ (coff_link_add_symbols): Likewise.
+ (coff_link_input_bfd): Likewise.
+ (_bfd_coff_generic_relocate_section): Likewise.
+ (_bfd_coff_read_internal_relocs): New function.
+ (coff_link_input_bfd): Use cached section contents if available.
+ Use _bfd_coff_read_internal_relocs.
+ * coffcode.h (coff_slurp_symbol_table): Don't call bfd_seek.
+ (coff_bfd_get_relocated_section_contents): Only define if not
+ already defined.
+ (coff_bfd_relax_section): Likewise.
+ * coffgen.c (build_string_table): Remove.
+ (_bfd_coff_get_external_symbols): New function, moved in from old
+ coff_link_get_symbols in cofflink.c.
+ (_bfd_coff_read_string_table): New function, moved in from old
+ coff_read_string_table in cofflink.c.
+ (_bfd_coff_free_symbols): New function, moved in frmo old
+ coff_link_free_symbols in cofflink.c.
+ (coff_get_normalized_symtab): Use _bfd_coff_get_external_symbols
+ rather than reading the symbols directly. To free them, call
+ _bfd_coff_free_symbols. Use _bfd_coff_read_string_table rather
+ than build_string_table.
+ * libcoff-in.h (obj_coff_keep_syms): Define.
+ (obj_coff_keep_strings): Define.
+ (coff_data_type): Add fields keep_syms and keep_strings.
+ (coff_section_tdata): Define new structure.
+ (coff_section_data): Define.
+ (_bfd_coff_get_external_symbols): Declare.
+ (_bfd_coff_read_string_table): Declare.
+ (_bfd_coff_free_symbols): Declare.
+ (_bfd_coff_read_internal_relocs): Declare.
+ * libcoff.h: Rebuild.
+
+Fri Jul 21 22:32:54 1995 Michael Meissner <meissner@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Add support for R_PPC_SDAREL
+ relocation.
+ (ppc_elf_reloc_type_lookup): Ditto.
+ (ppc_elf_got16_inner): Ditto.
+ (ppc_elf_relocate_section): Ditto.
+
+Thu Jul 20 19:19:06 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (hppa_elf_gen_reloc_type): Add new (ignored)
+ argument.
+ * elf32-hppa.h: Corresponding change.
+
+Thu Jul 20 19:01:07 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * libaout.h (set_aout_section_data): New macro.
+ * sunos.c (sunos_scan_relocs): Use it.
+
+ * aout-ns32k.c (MY_swap_std_reloc_out): Undef KEEPIT before
+ defining it.
+
+Thu Jul 20 13:48:00 1995 Fred Fish <fnf@cygnus.com>
+
+ * hosts/i386v4.h (getgid, getuid): Change prototypes to be
+ compatible with Unixware 1.x and Unixware 2.x, and probably other
+ i386 svr4 versions as well.
+
+Thu Jul 20 13:41:21 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * targets.c (bfd_target_vector): Since armpe and armpei have been
+ split into big- and little-endian variants, list all of them,
+ instead of the now-nonexistant armpe[i]_vec.
+
+Thu Jul 20 00:06:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (bfd_section_from_phdr): Set lma based on p_paddr.
+ (elf_fake_sections): Set sh_addr based on lma, not vma.
+
+Wed Jul 19 15:52:01 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * coff-arm.c (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Replaces TARGET_SYM.
+ * configure.in (armpe_vec, armpei_vec): Add bi-endian support.
+ * configure: "regenerated".
+ * pe-arm.c (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Replaces TARGET_SYM.
+ (TARGET_LITTLE_NAME, TARGET_BIG_NAME): Replaces TARGET_NAME.
+ * pei-arm.c (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Replaces TARGET_SYM.
+ (TARGET_LITTLE_NAME, TARGET_BIG_NAME): Replaces TARGET_NAME.
+ * targets.c (armpe_vec, armpei_vec): Deleted.
+ (armpe_little_vec, armpe_big_vec, armpei_little_vec, armpei_big_vec):
+ Added.
+ * config/arm-pe.mt (DEFAULT_VECTOR): Default is armpe_little_vec.
+ (SELECT_VECS): Add bi-endian support.
+
+Wed Jul 19 10:47:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c: Clean up and comment.
+ (r_imm32): Remove.
+ (sh_coff_howtos): New static array.
+ (SH_COFF_HOWTO_COUNT): Define.
+ (get_symbol_value): Make relocation bfd_vma rather than long.
+ (RTYPE2HOWTO): Rewrite to use sh_coff_howtos.
+ (coff_relocate_section): Define to sh_relocate_section.
+ (sh_relocate_section): New static function.
+
+Sat Jul 15 01:02:53 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.host: Add support for generic m68k SVR4 host.
+
+Fri Jul 14 13:13:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (KEEPIT): Change definition to udata.i.
+ (KEEPITTYPE): Remove.
+ (NAME(aout,reloc_type_lookup)): Add cases to the
+ extended reloc type switch: SPARC_GOT10, SPARC_GOT13, SPARC_GOT22,
+ SPARC_PC10, SPARC_PC22, SPARC_WPLT30.
+ (NAME(aout,swap_std_reloc_out)): Don't bother to use stoi when
+ retrieving KEEPIT value.
+ (NAME(aout,swap_ext_reloc_out)): Likewise. Also, only add in
+ output section VMA for section symbols, and check BSF_SECTION_SYM
+ to control whether to set r_extern to 1.
+
+ * syms.c: Fix comments so that `make info' works.
+
+ * elf32-mips.c (mips_elf_find_nearest_line): Set SEC_HAS_CONTENTS
+ in .mdebug section, in case backend linker has cleared it.
+
+Fri Jul 14 11:58:34 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_addr16_ha_inner): Rewrite to take just one
+ argument, the final relocated address.
+ (ppc_elf_addr16_ha_inner): Adjust ppc_elf_addr16_ha_inner caller.
+ (ppc_elf_relocate_section): Ditto.
+
+Thu Jul 13 17:22:03 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (hppa_som_gen_reloc_type): Choose a reasonable field
+ selector relocation for the difference of two symbols.
+
+Thu Jul 13 10:33:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,slurp_reloc_table)): Cast argument to size_t
+ for malloc.
+ * coff-mips.c (mips_relocate_section): Likewise, for memmove.
+ (mips_relax_section): Likewise, for malloc.
+ * cofflink.c (process_embedded_commands): Likewise.
+ (_bfd_coff_final_link): Likewise.
+ * ecoff.c (_bfd_ecoff_write_object_contents): Likewise.
+ (ecoff_final_link_debug_accumulate): Likewise.
+ (ecoff_indirect_link_order): Likewise, for memcpy and malloc.
+ (ecoff_reloc_link_order): Likewise, for malloc.
+ * ecofflink.c (ecoff_align_debug): Likewise, for memset.
+ (ecoff_write_symhdr): Likewise, for malloc.
+ * elf32-hppa.c (elf32_hppa_read_symext_info): Likewise.
+ * elf.c (assign_file_positions_except_relocs): Likewise, for
+ qsort.
+ * elf32-mips.c (mips_elf_read_ecoff_info): Likewise, for malloc.
+ * elfcode.h (elf_slurp_reloc_table): Likewise.
+ * elfcore.h (elf_corefile_note): Likewise.
+ * elflink.h (elf_link_add_object_symbols): Likewise.
+ (elf_link_read_relocs): Likewise.
+ (NAME(bfd_elf,size_dynamic_sections)): Likewise, for memset.
+ * i386linux.c (bfd_linux_size_dynamic_sections): Likewise.
+ * ieee.c (do_with_relocs): Likewise.
+ * linker.c (default_indirect_link_order): Likewise, for malloc.
+ * nlmcode.h (nlm_object_p): Likewise.
+ (nlm_write_object_contents): Likewise.
+ * oasys.c (oasys_set_section_contents): Likewise, for memcpy.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Likewise,
+ for malloc.
+ * section.c (bfd_get_section_contents): Likewise, for memcpy.
+ * srec.c (srec_get_section_contents): Likewise.
+ (srec_set_section_contents): Likewise.
+ * sunos.c (bfd_sunos_size_dynamic_sections): Likewise, for
+ realloc and memset.
+ (sunos_scan_relocs): Likewise, for malloc.
+ (sunos_scan_dynamic_symbol): Likewise, for realloc.
+ * syms.c (_bfd_generic_read_minisymbols): Likewise, for malloc.
+ * versados.c (versados_get_section_contents): Likewise, for
+ memcpy.
+
+ * libbfd.c (real_read): Add prototype. Change argument types from
+ int to size_t.
+ (bfd_read): Cast real_read argument to size_t, not int.
+ (bfd_write): Cast fwrite argument to size_t, not int.
+
+ * elf64-gen.c (elf_info_to_howto): Fix definition for recent elf.c
+ changes.
+
+ * configure.in: Fix typo: change {$enableval} to ${enableval}.
+ * configure: Rebuild.
+
+ * Makefile.in (BFD32_BACKENDS): Add elflink.o.
+
+ * targets.c (bfd_target): Add fields _read_minisymbols and
+ _minisymbol_to_symbol.
+ (BFD_JUMP_TABLE_SYMBOLS): Add _read_minisymbols and
+ _minisymbol_to_symbol.
+ (bfd_read_minisymbols): Define.
+ (bfd_minisymbol_to_symbol): Define.
+ * syms.c (_bfd_generic_read_minisymbols): Define.
+ (_bfd_generic_minisymbol_to_symbol): Define.
+ * libbfd-in.h (_bfd_nosymbols_read_minisymbols): Define.
+ (_bfd_nosymbols_minisymbol_to_symbol): Define.
+ (_bfd_generic_read_minisymbols): Declare.
+ (_bfd_generic_minisymbol_to_symbol): Declare.
+ * bfd-in2.h: Rebuild.
+ * libbfd.h: Rebuild.
+ * aoutx.h (MINISYM_THRESHOLD): Define.
+ (NAME(aout,read_minisymbols)): New function.
+ (NAME(aout,minisymbol_to_symbol)): New function.
+ * libaout.h (NAME(aout,read_minisymbols)): Declare.
+ (NAME(aout,minisymbol_to_symbol)): Declare.
+ * aout-target.h (MY_read_minisymbols): Define.
+ (MY_minisymbol_to_symbol): Define.
+ * All targets: Define read_minisymbols and minisymbol_to_symbol.
+
+Wed Jul 12 17:55:55 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Cast return value from
+ bfd_alloc.
+
+ * elfcode.h (size_info): Don't use "&" before function names.
+
+Wed Jul 12 00:16:48 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * libelf.h (elf_backend_data): Use unsigned, not unsigned char,
+ for bitfields.
+
+Tue Jul 11 15:19:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (bfd_section_from_shdr): In case SHT_REL[A], only get the
+ BFD section for the sh_link section if it is a SYMTAB section.
+
+ * aoutx.h (NAME(aout,link_add_symbols)): Don't bother to check
+ that archives hold a.out objects.
+ * cf-i386lynx.c (coff_bfd_link_add_symbols): Don't define.
+ (lynx_link_add_symbols): Remove.
+ * cf-m68klynx.c (coff_bfd_link_add_symbols): Don't define.
+ (lynx_link_add_symbols): Remove.
+ * elflink.h (elf_bfd_link_add_symbols): Don't bother to check that
+ archives hold ELF objects.
+
+ * archive.c (bfd_generic_archive_p): If the archive has a map, and
+ the target was defaulted, but the first object in the archive can
+ not be matched with that target, then return a bad format error.
+
+ * elf64-sparc.c (elf_sparc_howto_table): Set howto for WDISP16 to
+ elf64_wdisp16_reloc.
+ (elf64_wdisp16_reloc): New static function.
+ (elf64_sparc_relocate_section): New static function.
+ (elf_backend_relocate_section): Define.
+
+ * libelf.h (struct elf_size_info): Change type of last argument to
+ swap_symbol_out from char * to PTR.
+ (bfd_elf32_swap_symbol_out): Update declaration.
+ (bfd_elf64_swap_symbol_out): Likewise.
+ * elfcode.h (elf_swap_symbol_out): Change type of cdst from char *
+ to PTR.
+ * elf.c (swap_out_syms): Cast to PTR, not char *, when calling
+ swap_symbol_out routine.
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Likewise.
+ (elf_link_output_sym): Likewise.
+ (elf_link_output_extsym): Likewise.
+ * elf32-sparc.c (elf32_sparc_finish_dynamic_sections): Likewise.
+
+Tue Jul 11 12:29:49 1995 Rick Sladkey <jrs@world.std.com>
+
+ * elf.c (_bfd_elf_find_nearest_line): Handle the simple case where
+ there is no debugging information.
+
+Mon Jul 10 11:45:55 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * makefile.dos (OBJS): Add binary.o and tekhex.o. From DJ
+ Delorie.
+
+Mon Jul 10 11:09:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * linker.c (set_symbol_from_hash): bfd_link_hash_new case: Don't
+ abort; it can happen for constructor symbols when not building
+ constructors.
+
+ * coff-i960.c (coff_i960_relocate): Correct typo: use ! on strcmp,
+ not on string.
+ * cofflink.c (_bfd_coff_generic_relocate_section): Remove unused
+ local i.
+ * coff-arm.c (coff_arm_rtype_to_howto): Don't declare.
+ (PCRELOFFSET): Define if not already defined.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add coff-arm.o
+ (CFILES): Add coff-arm.c, pe-arm.c, pei-arm.c.
+
+ * aoutx.h (NAME(aout,link_hash_table_create)): Allocate hash table
+ using bfd_alloc, not malloc.
+ * cofflink.c (_bfd_coff_link_hash_table_create): Likewise.
+ * ecoff.c (_bfd_ecoff_bfd_link_hash_table_create): Likewise.
+ * i386linux.c (linux_link_hash_table_create): Likewise.
+ * linker.c (_bfd_generic_link_hash_table_create): Likewise.
+ * sunos.c (sunos_link_hash_table_create): Likewise.
+
+ Based on patches from Eric Youngdale <eric@aib.com>:
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): If -Bsymbolic,
+ output a DT_SYMBOLIC dynamic entry.
+ (elf_adjust_dynamic_symbol): If -Bsymbolic, don't require a PLT
+ entry for a locally defined symbol.
+ * elf32-i386.c (elf_i386_relocate_section): If -Bsymbolic, do warn
+ about undefined symbols, and fill in the GOT entry for a symbol
+ defined in a regular object file.
+ (elf_i386_finish_dynamic_symbol): If -Bsymbolic, output a RELATIVE
+ reloc rather than a GLOB_DAT reloc for a symbol defined in a
+ regular object file.
+ * elf32-m68k.c (elf_m68k_relocate_section): If -Bsymbolic, do warn
+ about undefined symbols, and fill in the GOT entry for a symbol
+ defined in a regular object file.
+ (elf_m68k_finish_dynamic_symbol): If -Bsymbolic, output a RELATIVE
+ reloc rather than a GLOB_DAT reloc for a symbol defined in a
+ regular object file.
+ * elf32-sparc.c (elf32_sparc_relocate_section): If -Bsymbolic, do
+ warn about undefined symbols, and fill in the GOT entry for a
+ symbol defined in a regular object file.
+ (elf32_sparc_finish_dynamic_symbol): If -Bsymbolic, output a
+ RELATIVE reloc rather than a GLOB_DAT reloc for a symbol defined
+ in a regular object file.
+
+ * config/m68k-coff.mt (SELECT_VECS): Rename from SELECT_VECTORS.
+ Correct elements to be actual BFD vector names.
+
+ * Makefile.in (Makefile): Don't depend upon @frags@.
+ (config.status): Depend upon @frags@.
+
+Fri Jul 7 17:36:44 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgen.c (coff_renumber_symbols): Sort defined symbols that are
+ neither BSF_FUNCTION not BSF_NOT_AT_END just before undefined
+ symbols.
+ * coffcode.h (coff_slurp_symbol_table): Set BSF_FUNCTION as well
+ as BSF_NOT_AT_END.
+
+Fri Jul 7 17:16:15 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (do_mostlyclean): Remove config.log.
+ (do_distclean): Remove config.cache.
+
+Thu Jul 6 14:37:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Revert May 24 patch.
+ Don't copy PC32 reloc against section into shared object.
+
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Added elflink.c.
+ (Makefile): Depend upon config.status, not configure.in.
+ (config.status): New target; depend upon configure configure.host
+ and config.bfd.
+
+Wed Jul 5 20:17:14 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * elfcore.h, elflink.h, elfcode.h, elf.c, elflink.c: Moved some
+ primarily size-independent code from elfcode.h to elf.c and new
+ file elflink.c; moved out other core- or linker-related routines
+ into other new .h files for clarity. Renamed many routines to
+ start with bfd_elf or _bfd_elf. Added a structure of
+ size-dependent but target-independent info to elfcode.h.
+ * Makefile.in: Build elflink.o. Update dependencies.
+ * libelf.h: Updated some declarations. Added a definition for the
+ new structure in elfcode.h. Added more fields to elf backend data
+ structure.
+ * elfxx-target.h: Refer to the appropriate size-dependent info.
+ * elf32-*.c: Changed some function names. Moved common
+ create_dynamic_sections code from m68k, sparc, and i386 support
+ into elflink.c. Define some new macros to fill in new fields of
+ back end data. Also clean up some "gcc -Wall" warnings regarding
+ unused or uninitialized variables.
+
+ * Makefile.in (BFD_LIBS): No, don't put elflink.o here.
+ * configure.in: Include it here whenever elf.o is specified.
+
+Wed Jul 5 10:31:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_object_p): Unconditionally set
+ elf_bad_symtab, since sometimes the symbol table is messed up and
+ the last symbol is global.
+
+ * ecoff.c (_bfd_ecoff_bfd_is_local_label): New function.
+ * libecoff.h (_bfd_ecoff_bfd_is_local_label): Declare.
+ * elf32-mips.c (mips_elf_is_local_label): New static function.
+ (bfd_elf32_bfd_is_local_label): Define.
+
+ * configure.in: Use $ac_config_sub, not $configsub.
+ * configure: Likewise.
+
+ Permit --enable-targets=ieee:
+ * config.bfd (*-*-ieee*): New target.
+ * config/ieee.mt: New file.
+
+Wed Jul 5 04:16:35 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * config/i386aix.mh (HDEFINES): Remove -DFASCIST_FDOPEN.
+
+ Autoconfiscation:
+ * configure.in, Makefile.in, doc/Makefile.in: Switch from Cygnus
+ configure to autoconf ways of processing --enable arguments,
+ setting up symlinks, incorporating makefile fragments, printing
+ messages at configuration time, setting variables in Makefile.
+ Deleted some unused variables. Check for ranlib via autoconf.
+ For now, configure script removes doc/config.status.
+ * configure: New file.
+ * dep-in.sed: Use @SRCDIR@ instead of @srcdir@, so Makefile.in
+ line doesn't get broken by configure.
+ * doc/configure.in: Removed.
+
+Tue Jul 4 12:22:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * archive.c (_bfd_construct_extended_name_table): If
+ BFD_TRADITIONAL_FORMAT is set, limit the length of all file names
+ to ar_max_namelen.
+ (bfd_dont_truncate_arname): If BFD_TRADITIONAL_FORMAT is set, call
+ bfd_bsd_truncate_arname.
+ (_bfd_write_archive_contents): Revert June 1 change.
+
+ * elfcode.h (NAME(bfd_elf,record_link_assignment)): Add provide
+ argument.
+ * bfd-in.h (bfd_elf32_record_link_assignment): Update prototype.
+ (bfd_elf64_record_link_assignment): Likewise.
+ * bfd-in2.h: Rebuild.
+
+ * libelf.h (struct elf_link_hash_table): Add needed field. Remove
+ saw_needed field.
+ * elfcode.h (elf_link_add_object_symbols): If elf_dt_needed_name
+ is an empty string, don't make a DT_NEEDED entry in the output
+ file. Record all DT_NEEDED entries found in input dynamic
+ objects.
+ (elf_link_output_extsym): Don't check saw_needed when issuing
+ warnings.
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize needed, not
+ saw_needed.
+ (bfd_elf_get_needed_list): New function.
+ * bfd-in.h (struct bfd_elf_link_needed_list): Define.
+ (bfd_elf_get_needed_list): Define.
+ * bfd-in2.h: Rebuild.
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): Also initialize
+ find_buffer and fdrtab_len fields of newly allocated
+ find_line_info structure.
+
+Mon Jul 3 17:03:52 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (hppa_som_gen_reloc_type): New argument "sym_diff",
+ nonzero when we're generating relocations for an expression
+ using the difference of two symbols. All callers changed.
+ Handle difference of symbols for both R_HPPA and R_COMPLEX
+ cases.
+ (som_write_fixups): Handle R_COMP1, R_COMP2 and R_CODE_EXPR
+ fixups.
+
+Mon Jul 3 13:55:18 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config.bfd (win32): New configuration.
+ * configure.host (pe): Changed to i386win32.
+ * config/i386pe.mh: Deleted.
+ * config/i386win32.mh: New file.
+
+Mon Jul 3 11:30:45 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): If we allocate
+ find_line_info, clear the fdrtab field.
+
+ * targets.c (enum bfd_flavour): Add bfd_target_msdos_flavour here,
+ rather than in bfd-in2.h.
+
+ * bfd.c (enum bfd_error): Define bfd_error_no_armap.
+ (bfd_errmsgs): Add string for bfd_error_no_armap.
+ * bfd-in2.h: Rebuild.
+ * ecoff.c (ecoff_link_add_archive_symbols): If an archive has no
+ armap, set bfd_error_no_armap rather than bfd_error_no_symbols.
+ * elfcode.h (elf_link_add_archive_symbols): Likewise.
+ * linker.c (_bfd_generic_link_add_archive_symbols): Likewise.
+
+ * elfcode.h (elf_link_add_object_symbols): Permit common and
+ indirect symbols in weakdefs BFD_ASSERT.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Simplify
+ BFD_ASSERT to permit some legal, but odd, cases.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
+
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add versados.o.
+ (CFILES): Add pe-i386.c, pei-i386.c, and versados.c.
+
+Sun Jul 2 17:49:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Cast base_file
+ to FILE * before using it.
+ * stab-syms.c: Revert yesterday's patch.
+
+Sat Jul 1 12:10:42 1995 Fred Fish <fnf@cygnus.com>
+
+ * stab-syms.c (stdio.h): Include prior to libaout.h, which
+ includes bfdlink.h, which now uses FILE.
+
+Sat Jul 1 00:11:08 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * elfxx-target.h: New file.
+
+ * libelf.h (struct elf_backend_data): Remove elf_64_p field.
+ * elfxx-target.h (elfNN_bed): Don't set it.
+
+ * elf32-target.h, elf64-target.h: Deleted.
+ * Makefile.in (elf32-target.h, elf64-target.h): Build them from
+ elfxx-target.h.
+
+Fri Jun 30 16:07:18 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Compare
+ the full text of .reloc or .edata section names.
+
+Fri Jun 30 15:47:37 1995 Fred Fish <fnf@cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section):
+ Remove extra '+'.
+
+Thu Jun 29 17:24:52 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * coff-h8300.c (COFF_LONG_FILENAMES): Define.
+
+Wed Jun 28 18:04:42 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in: versados.o is now conditionally built.
+ * coffcode.h (add_data_entry): New function.
+ (coff_write_object_contents): Clean up. Calculate
+ data entries.
+ * cofflink.c (_bfd_coff_generic_relocate_section):
+ .reloc and .edata sections are IMAGE_BASED too.
+ If there's a base_file then write out base information.
+ * configure.host (i386-*-pe): New.
+ * syms.c (coff_section_type): Only scan prefixes.
+ * targets.c (bfd_target_vector): Versados is now conditionally
+ built.
+ * config/m68k-coff.mt: Build versados.o
+ * hosts/i386pe.h: New file.
+
+Mon Jun 26 13:53:49 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hpa.c (elf32_hppa_relocate_section): Close comment before
+ R_PARISC_DPREL21L handling.
+
+Thu Jun 22 19:28:36 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sun May 7 11:53:41 MDT 1995 Bryan Ford <baford@cs.utah.edu>
+
+ * config/i386-moss.mt: created.
+
+Thu Jun 22 08:56:10 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * reloc.c (bfd_perform_relocation): Add case for -ve words.
+
+Wed Jun 21 13:13:49 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Don't try to apply a
+ relocation against an undefined symbols.
+
+Wed Jun 21 10:16:10 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * versados.c: Second pass/rewrite.
+
+Mon Jun 19 08:40:45 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * syms.c (coff_section_type): Compare only the front part
+ of a section name.
+
+Sat Jun 17 09:40:44 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Set the size of the stub
+ section if we get an error.
+
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Don't mess
+ with the operands of an R_PARISC_DPREL21L relocation if the insn
+ is not "addil <symbol>,%r27".
+
+Fri Jun 16 15:04:47 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * bfd-in.h (NT_subsystem, NT_stack_heap): Declare but don't
+ define.
+ * bfd-in2.h: Rebuilt.
+ * bfd.c (NT_subsystem, NT_stack_heap): Define.
+
+Fri Jun 16 00:07:25 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_bfd_link_link_relocate): Use the right
+ type field (there are two!) when checking to see if $global$ is
+ defined.
+
+Thu Jun 15 14:03:47 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * bfd-in.h, bfd-in2.h (bfd_boolean): Rename bfd_true, bfd_false
+ to bfd_tttrue, bfd_fffalse so as not to conflict with functions.
+ * coffswap.h (coff_swap_scnhdr_out): Remove version that was
+ hacked for MPW C.
+ * mpw-config.in: Set shell vars instead of pasting to makefile
+ for each configuration, edit coffswap.h to make MPW C not choke.
+ (i386-unknown-coff, sh-hitachi-hms): Recognize.
+ * mpw-make.in (BFD_LIBS): Add versados.c.o.
+
+ * versados.c (versados_scan): Properly cast results from bfd_alloc.
+
+Wed Jun 14 15:27:32 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * cofflink.c (process_embedded_commands): New function
+ reads and handles .drectve sections for PE.
+ (coff_link_input_bfd): Call new function if PE.
+
+Mon Jun 12 12:09:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * bfd-in.h (bfd_set_section_vma): Case true to a boolean.
+ (bfd_set_cacheable): Likewise.
+ * bfd-in2.h: Rebuilt.
+
+Fri Jun 9 12:20:28 1995 Steve Chamberlain <sac@rtl.cygnus.com>
+
+ * elfcode.h (elf_sort_hdrs): Rewrite to be symmetrical.
+
+Fri Jun 9 12:49:00 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * targets.c: Add copy_private_symbol_data and link_split_section
+ to the target vector.
+ * libbfd-in.h (_bfd_generic_bfd_copy_private_symbol_data): Define.
+ (_bfd_nolink_bfd_link_split_section): Likewise.
+ (bfd_generic_link_split_section): Declare.
+ * syms.c (bfd_copy_private_symbol_data): Define.
+ * linker.c (bf_link_split_section): Likewise.
+ * som.c (som_bfd_copy_private_symbol_data): New function
+ (som_bfd_link_split_section): Likewise.
+ * All other targets updated with default versions of new routines.
+
+ * Take out my braindamaged bfd_true/bfd_false changes from earlier
+ today. Replace with just:
+ * bfd-in.h: (TRUE_FALSE_ALREADY_DEFINED): Define this if
+ compiling with g++-2.6 or later.
+ * bfd-in2.h: Rebuilt.
+
+Fri Jun 9 07:54:29 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * versados.c (struct esd, get_4): Lint; use unsigned chars.
+
+ * coff-i960.c (coff_i960_relocate): Compare output section names
+ when converting for vxworks.
+
+Wed Jun 7 19:01:30 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * elfcode.h (elf_fake_sections): Permit .scommon or COMMON
+ sections as random SHT_NOBITS sections, in case a linker script is
+ strange.
+
+Tue Jun 6 17:29:32 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * bfd-in.h (NT_subsystem, NT_stack_heap): Moved from pe.h
+ * coff-i386.c (coff_i386_rtype_to_howto): Get PE relocs right.
+ * coffcode.h (coff_mkobject): Set pe tdata bit when using PE.
+ * cofflink.c (COFF_WITH_PE code): Test on obj_pe bit rather
+ than conditional compile.
+ * configure.in: Fix PE dependencies.
+ * libcoff-in.h (obj_pe): New.
+ (coff_tdata): Added pe entry.
+ * libcoff.h: Regenerated.
+
+Mon Jun 5 09:07:13 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * coff-a29k.c (coff_a29k_adjust_symndx): Completely parenthesize
+ macro.
+
+Mon Jun 5 02:15:20 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Linker support for m68k-elf from Andreas Schwab
+ <schwab@issan.informatik.uni-dortmund.de>:
+ * elfcode.h (elf_link_add_object_symbols): Check for NULL when
+ looping through the symbol hashes.
+ (elf_bfd_final_link): When looking for _init and _fini don't use
+ the symbol if it is imported from another object.
+ * elf32-m68k.c: Relocation type changed from REL to RELA. Regular
+ and dynamic linking support functions added, similar to other elf
+ targets.
+
+ * config.bfd (i[345]86-*-gnu*): Use ELF configuration.
+
+Fri Jun 2 18:54:59 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * versados.c: New file.
+ * bfd-in2.h (struct _bfd): New field.
+ * bfd.c (struct _bfd): New field.
+ * configure.in (versados_vec): New field.
+ * targets.c (bfd_flavor): Added versados.
+
+Thu Jun 1 13:51:49 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * coffcode.h (sec_to_styp_flags, styp_to_sec_flags,
+ coff_new_section_hook): Any section that starts ".stab"
+ is now marked as debugging.
+
+Thu Jun 1 16:15:16 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * archive.c (_bfd_write_archive_contents): Disable extended name
+ table until it can be made optional, so that native AR has half a
+ chance on SunOS and HP/UX.
+
+ * linker.c (_bfd_generic_link_output_symbols, case
+ bfd_link_hash_indirect): Add cast to correct pointer types.
+
+Sat May 27 21:37:31 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config.bfd (m68k-bull-sysv*): Added strip_underscore=yes.
+ (m68k-est-coff): Removed. target does not effect object format.
+
+Wed May 24 10:52:01 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * linker.c (_bfd_generic_link_output_symbols): Cope with
+ indirect symbols.
+
+ * elf32-i386.c (elf_i386_relocate_section): Give error
+ message when linking to a shared reloc which isn't there.
+
+Wed May 24 10:40:00 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Support for ARM-PE.
+
+ * Makefile.in, coffcode.h, config.bfd, configure.in, pe-arm.c,
+ pei-arm.c, coff-arm.c, reloc.c, targets.c, config/arm-pe.mt:
+ Support for ARM COFF/PE.
+
+Tue May 23 19:24:58 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * bfd.c (bfd_get_relocated_section_contents): Now a function,
+ tries calling routine from input bfd target vector for
+ bfd_indirect_link_order. Put a declaration into the header file.
+ * bfd-in2.h: Regenerated.
+ * elf32-mips.c (gprel16_with_gp): New function, split out from
+ mips_elf_gprel16_reloc.
+ (mips_elf_gprel16_reloc): Call it. If output bfd target vector
+ isn't elf flavoured, abort, since it's assumed to be elf in some
+ of this code, including the code that looks up the gp value.
+ (elf32_mips_get_relocated_section_contents): New function,
+ modified from bfd_generic_get_relocated_section_contents to deal
+ with passing gp to gprel16_with_gp.
+ (bfd_elf32_bfd_get_relocated_section_contents): New macro.
+ * elf32-target.h (bfd_elf32_bfd_get_relocated_section_contents):
+ Don't define if already defined.
+
+Tue May 23 15:58:15 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * Makefile.in: Install bfdlink.h too.
+
+Sun May 21 22:25:09 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Handle undefined and
+ notsupported return codes from final_link_relocate (used when
+ $global$ is undefined or nonexistant).
+ (elf32_hppa_bfd_link_link_relocate): If $global$ exists, but is
+ not defined,then return bfd_reloc_undefined.
+
+Fri May 19 10:00:14 1995 Steve Chamberlain <sac@rtl.cygnus.com>
+
+ * coffswap.h: (IMAGE_BASE): Define to 0 if not.
+
+Thu May 18 04:24:01 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * aoutx.h (aout_link_input_section_standard): If defined, call
+ MY_relocatable_reloc before doing a partial relocation.
+
+ * aout-arm.c: (WRITE_HEADERS): Delete.
+ (NAME): Define version to override default in aoutx.h
+ (MY(howto_table)): Reformat. Alter some entries slightly.
+ (RELOC_ARM_BITS_NEG_{BIG,LITTLE}): Define.
+ (MY(reloc_howto), MY(put_reloc), MY(relocatable_reloc)): New functions.
+ (MY_reloc_howto, MY_put_reloc, MY_relocatable_reloc): Define.
+ (MY(fix_pcrel_26)): Renamed from aoutarm_fix_pcrel_26, return
+ bfd_reloc_ok not bfd_reloc_continue.
+ (MY(fix_pcrel_26_done)): Likewise.
+ (MY(bfd_reloc_type_lookup)): Renamed from aoutarm_reloc_type_lookup.
+ (MY_bfd_link_hash_table_create, MY_bfd_link_add_symbols,
+ MY_bfd_final_link): Delete.
+ (MY_swap_std_reloc_in, MY_swap_std_reloc_out, MY_get_section_contents):
+ Define.
+ (aoutx.h): Include it.
+ (MY(swap_std_reloc_{in,out})): New functions.
+ Use RELOC_ARM_BITS_NEG_{BIG,LITTLE} to extract negative reloc bit.
+ (aoutarm_squirt_out_relocs): Delete.
+
+ From: David Taylor (dtaylor@armltd.co.uk)
+ * config/arm[lb]-aout.mt: New files.
+ * aout-arm.c: New file.
+ * config.bfd: Handle arm{,e[lb]}-*-aout
+ * configure.in: Add vetor for aout_arm_{big,little}_vec.
+ * reloc.c: New relocation types for the ARM.
+ * targets.c (aout_arm_{big,little}_vec): declare.
+
+Tue May 16 10:29:51 1995 Jim Kingdon <kingdon@deneb.cygnus.com>
+
+ * libbfd.c (bfd_stat): If bfd_cache_lookup returns an error,
+ return an error to the caller. Call bfd_set_error on errors.
+
+Tue May 16 14:44:45 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * libcoff-in.h (coff_renumber_symbols): Modified prototypes in
+ accordance with 11 May libcoff.h change.
+
+Thu May 11 16:43:14 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ tekhex.c (first_phase): Understand type 0 symbols.
+ (tekhex_write_object_contents): Fix typo in final record.
+
+Thu May 11 16:43:14 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * coff-i960.c (optcall_callback): don't try and optimize
+ undefined refs.
+ (coff_write_relocs): Search for broken relocs on the way
+ out and fix them up.
+ (coff_renumber_symbols): Calculate and return index of
+ first undefined symbol.
+ (coff_write_object_contents): Call coff_renumber_symbols
+ and coff_write_relocs with the new args.
+ * libcoff.h: (coff_renumber_symbols, coff_renumber_symbols):
+ Modified prototypes.
+
+Thu May 11 16:43:14 1995 Steve Chamberlain <sac@slash.cygnus.com>
+ Tom Griest <griest@cs.yale.edu>
+
+ Initial support for PE format.
+
+ * Makefile.in, targets.c, configure.in, config.bfd:
+ Add support for i386-*-winnt and i386-*-pe.
+ * archive.c (do_slurp_coff_armap): Understand NTPE format
+ archives.
+ (_bfd_slurp_extended_name_table): Turn \ in a filename
+ into /.
+ * bfd-in.h (bfd_link_subsystem, _bfd_link_stack_heap): New.
+ * coff-i386.c (howto_table): Conditionalize PCRELOFFSET.
+ * coffcode.h (IMAGE_BASE): New.
+ (coff_compute_section_file_positions): Throw away .junk
+ sections for PE, align symbols.
+ (coff_write_object_contents): Throw away .junk sections
+ for PE. Remember info on .idata and .rsrc sections.
+ Fill in the PE header.
+ (coff_slurp_symbol_table): PE uses C_SECTION class.
+ * cofflink.c (_bfd_coff_final_link): Keep PE info up to date.
+ (_bfd_coff_generic_relocate_section): Cope with PE relocs.
+ * coffswap.h (coff_swap_{aout/file/scn/sym}hdr_{in/out}):
+ New code for PE headers.
+
+Tue May 9 17:01:38 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.bfd: Add little endian PowerPC support.
+ * configure.in: Ditto.
+ * targets.c: Ditto.
+ * config/ppcle-elf.mt: New file, for little endian PowerPC
+ support.
+ * config/ppc-elf.mt: Add little endian powerpc to the BFD
+ selection vectors.
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data): Complain if
+ linking a different endian object than we expect.
+ (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME): Define, to provide little
+ endian support.
+
+Tue May 2 16:32:24 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config.bfd (hppa*-*-lites*): Treat just like hppa*-*-*elf*.
+
+Tue Apr 25 19:38:43 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * coffgen.c (make_a_section_from_file): Initialize lma same as
+ vma.
+
+Tue Apr 25 11:03:21 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * hosts/std-host.h: #include ansidecl.h 'cause PTR is used in
+ std-host.h.
+
+Mon Apr 24 23:56:44 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * hosts/i386linux.h (HAVE_PROCFS): Don't define it. Added lengthy
+ comment explaining why.
+
+Mon Apr 24 10:34:02 1995 Michael Meissner <meissner@cygnus.com>
+
+ * hosts/i386linux.h (HAVE_PROCFS): If NO_PROCFS is defined, don't
+ define HAVE_PROCFS.
+
+Mon Apr 24 08:33:12 1995 Michael Meissner <meissner@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Do not continue
+ processing unknown symbols to prevent a cascade of errors.
+
+Fri Apr 21 12:48:48 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Patches from H.J. Lu for Linux ELF core file support.
+ * elfcode.h (elf_core_file_matches_executable_p) [HAVE_PROCFS]:
+ Use prpsinfo_t instead of struct prpsinfo, for consistency.
+ * hosts/i386linux.h (HAVE_PROCFS): Define.
+
+Thu Apr 20 09:07:39 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * linker.c (link_action): Do the right thing when a undefined
+ strong symbol appears after an undefined weak symbol.
+
+Fri Apr 14 16:51:17 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): New function to relocate
+ a whole section for the linker, bypassing bfd_perform_relocation.
+ (ppc_elf_reloc_type_lookup): New function to map the BFD
+ enumeration code into a howto structure.
+ (ppc_elf_howto_raw): Rename from ppc_elf_howto_table.
+ (ppc_elf_howto_table): New array that maps PowerPC relocation
+ numbers to howto structures without a linear search. Change from
+ using bfd_elf_generic_reloc to use ppc_elf_std_reloc.
+ (ppc_elf_howto_init): Initialize ppc_elf_howto_table from
+ ppc_elf_howto_raw.
+ (ppc_elf_reloc_type_lookup): Use a case statement instead of a
+ loop.
+ (ppc_elf_std_reloc): Replacement for bfd_elf_generic_reloc.
+ (ppc_elf_unsupported_reloc): Print a real error message, instead
+ of calling abort.
+ (ppc_elf_addr16_ha_inner): Abstract getting adjustment from
+ ppc_elf_addr16_ha_reloc, so ppc_elf_relocate_section can use it
+ too.
+ (ppc_elf_addr16_ha_reloc): Call it.
+ (ppc_elf_got16_inner): Abstract getting adjustment from
+ ppc_elf_got16_reloc, so ppc_elf_relocate_section can use it too.
+ (ppc_elf_got16_reloc): Call it.
+ (ppc_elf_info_to_howto): Rename from powerpc_info_to_howto.
+
+ * elfcode.h (elf_symbol_from_bfd_symbol): Omit space in debugging
+ output.
+ (elf_symbol_flags): Add debug function to decode flags so that
+ defining DEBUG to be 4 will compile again.
+ (elf_debug_section): Fix typo in debug output.
+
+Fri Apr 14 16:03:04 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config.bfd: Add m68*-*-elf*.
+ * elf32-m68k.c: Filled out implementation, except for dynamic
+ linking support.
+ * reloc.c (enum bfd_reloc_code_real): Added *_GOT_PCREL, *_GOTOFF,
+ *_PLT_PCREL, *_PLTOFF, *_68K_* relocations for ELF.
+ * libbfd.h, bfd-in2.h: Regenerated.
+
+Thu Apr 13 14:28:04 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * coff-m68k.c (COFF_DEFAULT_SECTION_ALIGNMENT_POWER): Change from
+ 1 to 2.
+ (bfd_target): Change minimum section alignment from 1 to 2.
+
+Wed Apr 12 12:40:04 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * aoutx.h (machine_type, case bfd_arch_mips): Treat R8000 like
+ R6000 and R4000 for now.
+
+Tue Apr 4 12:28:25 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: New file, MPW version of configure.in.
+ * mpw-make.in: New file, MPW version of Makefile.in.
+ * hosts/mpw.h: New file, MPW host definitions.
+ * ecoffswap.h (ecoff_swap_pdr_in, ecoff_swap_pdr_in) [MPW_C]:
+ Alternate versions without ECOFF_64 that chokes MPW C.
+ * coffswap.h (coff_swap_scnhdr_out): Add alternative version with
+ partly-expanded macros.
+
+Thu Mar 30 14:56:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * reloc.c (bfd_perform_relocation): Don't bother to check for
+ overflow if the symbol is undefined.
+
+Thu Mar 30 14:32:26 1995 H.J. Lu (hjl@nynexst.com)
+
+ * config.bfd: Change linux to default to elf. Using
+ i[345]86-*-linuxaout will build a library which defaults to a.out.
+ * config/i386-laout.mt: Rename from old config/i386-linux.mt.
+ * config/i386-linux.mt: Rename from old config/i386-lelf.mt.
+ Comment out EXTRALIBS.
+ * config/i386-lelf.mt: Remove.
+
+Wed Mar 29 12:01:30 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i960.c (coff_i960_relocate): Cache the section symbol in
+ the used_by_bfd field of the section, to avoid looping for each
+ reloc.
+
+ * cpu-h8500.c (arch_info_struct): Change name from "H8/300" to
+ "h8300" for consistency with other cpu-* files.
+
+Tue Mar 28 15:14:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bout.c (b_out_canonicalize_reloc): Handle SEC_CONSTRUCTOR
+ sections.
+ (b_out_get_reloc_upper_bound): Likewise.
+
+ * linker.c (generic_link_add_symbol_list): Skip constructor
+ symbols which the main linker code did not do anything with.
+ (_bfd_generic_link_output_symbols): Use udata.p if it is set,
+ rather than looking the symbol up in the hash table. Just pass
+ through constructor symbols for which udata.p is not set. If the
+ linker defined the symbol, clear the constructor flag.
+
+Tue Mar 21 10:50:32 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_set_reloc_info): Sign extend constants from
+ R_DATA_OVERRIDE fixups.
+ * libhppa.h (sign_extend): Renamed from sign_ext. Fix.
+ (low_sign_extend): Likewise.
+
+Mon Mar 20 22:39:10 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_slurp_symbol_table): Tighten test to determine
+ what symbols are section symbols.
+
+Sat Mar 18 01:54:45 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_bfd_link_add_symbols): An empty archive is OK.
+
+Fri Mar 17 16:29:02 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_copy_private_section_data): Just return true when
+ either the input or output section isn't attached to a SOM BFD.
+ (som_bfd_copy_private_bfd_data): Similarly for BFD private data.
+
+Fri Mar 17 11:50:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_link_add_object_symbols): Check whether a dynamic
+ object has already been included, and ignore it the second time.
+
+Wed Mar 15 11:56:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf_sparc_howto_table): Change R_SPARC_GOT13 from
+ complain_overflow_bitfield to complain_overflow_signed.
+
+ * libelf.h (bfd_elf32__write_relocs): Don't declare.
+ (bfd_elf64__write_relocs): Don't declare.
+
+Tue Mar 14 05:54:33 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * stab-syms.c (aout_stab_name): Moved aout_stab_names to be local
+ to this function. Recoded function to stop using table, to
+ improve performance (on i486-netbsd host). Left old version
+ intact under "#if 0" for further performance testing.
+
+Mon Mar 13 13:48:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (write_relocs): Make static. Use PTR argument as a
+ pointer to a boolean variable set to true if something fails.
+ Cast to PTR rather than void *.
+ (sym_is_global): Rewrite for clarity.
+ (map_program_segments): If the program header size is too small,
+ call _bfd_error_handler and return failure rather than aborting.
+ (NAME(bfd_elf,write_object_contents)): Pass boolean variable when
+ calling write_relocs.
+ (elf_symbol_from_bfd_symbol): Use BFD_ASSERT rather than abort.
+ (struct elf_info_failed): Define.
+ (NAME(bfd_elf,size_dynamic_sections)): Declare variables in inner
+ blocks. Pass elf_info_failed structure when calling
+ elf_export_symbol and elf_adjust_dynamic_symbol.
+ (elf_export_symbol): Treat data argument as elf_info_failed rather
+ than bfd_link_info. Set failed field on error.
+ (elf_adjust_dynamic_symbol): Likewise.
+ (struct elf_finfo_failed): Define.
+ (elf_bfd_final_link): Pass elf_finfo_failed structure when calling
+ elf_link_output_extsym. Use BFD_ASSERT rather than abort.
+ (elf_link_output_extsym): Treat data argument as elf_finfo_failed
+ rather than elf_final_link_info. Set failed field on error.
+ (elf_link_input_bfd): Use BFD_ASSERT rather than abort.
+ (elf_reloc_link_order): Likewise.
+
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Only write
+ out PLTRELSZ, PLTREL and JMPREL relocs if there is a .rela.plt
+ section. Solaris 2.4 apparently does not handle empty reloc
+ information correctly.
+
+ * archive.c (bsd_write_armap): Cast getuid and getgid results to
+ long, and print with %ld.
+
+Fri Mar 10 16:41:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (translate_to_native_sym_flags): Always use the output
+ section if it is not NULL.
+
+Thu Mar 9 15:06:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffswap.h (coff_swap_scnhdr_out): If the line number count or
+ the reloc count does not fit, print an error and return 0.
+ * coffcode.h (coff_write_object_contents): Check return value of
+ coff_swap_scnhdr_out.
+ * ecoff.c (_bfd_ecoff_write_object_contents): Check return value
+ of bfd_coff_swap_scnhdr_out.
+
+ * bfd.c: Include <stdarg.h> or <varargs.h>, depending upon
+ ANSI_PROTOTYPES.
+ (bfd_error_handler_type): New global type.
+ (_bfd_error_program_name): New static variable.
+ (_bfd_default_error_handler): New static function.
+ (_bfd_error_handler): New BFD private global variable.
+ (bfd_set_error_handler): New globally visible function.
+ (bfd_set_error_program_name): New globally visible function.
+ * libbfd-in.h (_bfd_error_handler): Declare.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+ * aoutx.h (NAME(aout,swap_ext_reloc_in)): Add symcount parameter,
+ and use it instead of bfd_get_symcount. Check r_index after
+ setting r_extern based on whether this is a base relative reloc.
+ (NAME(aout,swap_std_reloc_IN)): Add symcount parameter, and use it
+ instead of bfd_get_symcount.
+ (NAME(aout,slurp_reloc_table)): Pass bfd_get_symcount to reloc
+ swap routines.
+ * libaout.h (NAME(aout,swap_ext_reloc_in)): Add symcount parameter
+ to declaration.
+ (NAME(aout,swap_std_reloc_in)): Likewise.
+ * sunos.c (sunos_canonicalize_dynamic_reloc): Pass
+ info->dynsym_count to reloc swap routines.
+ * aout-ns32k.c (MY_swap_std_reloc_in): Add symcount parameter.
+ * hp300hpux.c (MY(swap_std_reloc_in)): Likewise.
+ (MY(slurp_reloc_table)): Pass bfd_get_symcount to reloc swap
+ routine.
+ * i386lynx.c (NAME(lynx,swap_ext_reloc_in)): Add symcount
+ parameter.
+ (NAME(lynx,swap_std_reloc_in)): Likewise.
+ (NAME(lynx,slurp_reloc_table)): Pass bfd_get_symcount to reloc
+ swap routines.
+
+Thu Mar 9 12:04:05 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * bfd.c (bfd_merge_private_bfd_data): New function vector to be
+ called by the linker to merge any private bfd data of the input
+ files and the output file. Used by the PowerPC ELF support to
+ check whether -mrelocatable is used for all modules.
+ (bfd_set_private_flags): New function vector to be called by the
+ assembler to set private flags. Used by the PowerPC ELF support
+ to set that a particular object file was assembled with the
+ -mrelocatable option.
+
+ * targets.c (BFD_JUMP_TABLE_COPY): Add intiialization of the
+ bfd_merge_private_bfd_data and bfd_set_private_flags function
+ vectors.
+
+ * bfd-in2.h, libbfd-in.h: Rebuild with bfd.c and targets.c
+ changes.
+
+ * elf32-ppc.c (ppc_elf_set_private_flags): New function to set the
+ ELF e_flags field.
+ (ppc_elf_copy_private_bfd_data): Copy the e_flags field from the
+ input file to the output file.
+ (ppc_elf_merge_private_bfd_data): Check for a mismatch between the
+ e_flags field of all of the linker input files.
+
+ * libelf.h (elf_obj_tdata): Add ppc_flags_init field so that the
+ PowerPC support can check if compataible e_flags are present.
+
+ * aout-target.h: Add NOP for the bfd_merge_private_bfd_data
+ and bfd_set_private_flags function vectors.
+ * coffcode.h: Ditto.
+ * elf32-target.h: Ditto.
+ * elf64-target.h: Ditto.
+ * libbfd.h: Ditto.
+ * libecoff.h: Ditto.
+ * som.c: Ditto.
+
+Wed Mar 8 00:53:54 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * cpu-mips.c (arch_info_struct): Add mips:8000 entry.
+
+ * elfcode.h (swap_out_syms): Mark an undefined BSF_WEAK symbol as
+ STB_WEAK rather than STB_GLOBAL.
+
+Tue Mar 7 12:23:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (bfd_coff_backend_data): Add new field
+ _bfd_coff_adjust_symndx.
+ (bfd_coff_adjust_symndx): Define.
+ (coff_adjust_symndx): Define as NULL if not already defined.
+ (bfd_coff_std_swap_table): Initialize new field to
+ coff_adjust_symndx.
+ * cofflink.c (coff_link_input_bfd): Call coff_adjust_symndx if it
+ is defined.
+ * coff-a29k.c (coff_a29k_adjust_symndx): New static function.
+ (coff_adjust_symndx): Define before including coffcode.h.
+ * libcoff.h: Rebuild.
+
+ * format.c (bfd_check_format_matches): Skip binary_vec when
+ searching through bfd_target_vector.
+
+ * elfcode.h (elf_sort_hdrs): Check SHT_NOBITS before checking
+ sh_size.
+
+Mon Mar 6 23:31:36 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * elfcode.h (elf_sort_hdrs): Keep SHT_NOBITS sections after
+ !SHT_NOBITS ones.
+
+Mon Mar 6 09:53:08 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * cpu-hppa.c (arch_info_struct): Support both PA1.0 and PA1.1
+ machine types.
+ (bfd_hppa_arch): Link in both PA1.0 and PA1.1 architecture info
+ structures.
+ * libhppa.h (enum pa_arch): New enumeration to describe the
+ different variants of the PA architecture.
+ * som.c (som_object_setup): Use new enumeration to set machine
+ type.
+ (som_finish_writing): If the machine type is PA1.1, then use the
+ PA1.1 machine identifier in the output file.
+
+Thu Mar 2 15:58:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,swap_ext_reloc_in)): Treat the index of a
+ base relative reloc as an index into the symbol table, regardless
+ of the setting of r_extern.
+ (NAME(aout,swap_std_reloc_in)): Likewise.
+
+ * aoutx.h (NAME(aout,set_section_contents)): Double check that the
+ caller is writing to a valid section.
+
+Thu Mar 2 14:37:57 1995 Bryan Ford <baford@cs.utah.edu>
+
+ * binary.c: Add support for reading binary files. Loads the raw
+ contents of the file into a data section and wraps some symbols
+ around it. The symbols `_binary_<filename>_start' and
+ `_binary_<filename>_end' indicate the start and end of the data,
+ while `_binary_<filename>_size' is an absolute symbol whose value
+ is the size of the data. <filename> is the name of the binary
+ input file, with all non-alphanumeric characters converted to
+ underscores.
+
+ * archures.c (bfd_arch_get_compatible): Assume users knows what
+ they're doing if one of the architectures is bfd_arch_unknown.
+
+Wed Mar 1 17:30:46 1995 Michael Meissner <meissner@cygnus.com>
+
+ * elf32-ppc.c (elf_powerpc_howto_table): For relocation
+ R_PPC_GOT16, change complain_on_overflow to be
+ complain_overflow_signed.
+
+Wed Mar 1 11:52:55 1995 Jason Molenda <crash@phydeaux.cygnus.com>
+
+ * configure.host: Recognize powerpc-*-aix*.
+
+Wed Mar 1 11:57:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i960.c (COFF_PAGE_SIZE): Define.
+
+ * configure.in: Rewrite output of TDEFAULTS to avoid relying on
+ semantics of single quotes in parameter substitution.
+
+Tue Feb 28 12:53:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_sort_hdrs): Sort empty sections before non-empty
+ sections, if they have the same VMA.
+
+ * config.bfd (i[345]86-*-linuxelf*): New target. Use i386-lelf.
+ (i[345]86-*-gnuelf*): New target. Use i386-gelf.
+ * config/i386-lelf.mt: New file.
+ * config/i386-gelf.mt: New file.
+
+Mon Feb 27 12:58:25 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * config.bfd: add a29k-*-vxworks configuration.
+
+Wed Feb 22 14:40:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libaout.h (NAME(aout,slurp_reloc_table)): Change declaration to
+ use reloc_howto_type rather than const struct reloc_howto_struct.
+
+Tue Feb 21 18:19:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bout.c (b_out_slurp_reloc_table): Don't return an error if asked
+ for relocations for the .bss section.
+
+Tue Feb 21 15:13:05 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_ar_write_symbol_stuff): Handle objects with odd
+ lengths.
+
+Fri Feb 17 12:34:36 1995 Michael Meissner <meissner@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_got16_reloc): Make GOT style relocs add
+ 32768, so the GOT pointer can point to 16384 pointers, instead of
+ 8192.
+
+Fri Feb 17 11:45:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * hosts/sysv4.h: Include <unistd.h>, <stdlib.h>, and <time.h>.
+ Only define SEEK_SET and SEEK_CUR if they are not already defined.
+ Remove all external function declarations.
+
+ * syms.c (bfd_decode_symclass): Return 'W' for a weak symbol.
+
+ * coffgen.c (coff_real_object_p): Set start address and flags
+ before calling coff_mkobject_hook. Restore them on failure.
+ * ecoff.c (_bfd_ecoff_mkobject_hook): If not ECOFF_AOUT_ZMAGIC,
+ clear D_PAGED.
+
+ * coffgen.c: Reindented.
+
+Thu Feb 16 14:37:23 1995 Doug Evans <dje@cygnus.com>
+
+ * reloc.c (bfd_perform_relocation): Don't use bitpos in overflow
+ calculations.
+ (bfd_install_relocation): Likewise.
+
+Thu Feb 16 13:22:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * hosts/std-host.h: Remove all function declarations which return
+ int or void, except the one for free.
+
+Wed Feb 15 14:54:18 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (elf_powerpc_howto_table): Use a destination mask of
+ 0xffffffff for R_PPC_REL32, not 0.
+ (powerpc_reloc_map): Add low 16 bit, high 16 bit, and high 16 bit
+ adjusted relocations.
+
+Tue Feb 14 17:47:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (struct mips_elf_find_line): Define.
+ (mips_elf_find_nearest_line): New static function.
+ (bfd_elf32_find_nearest_line): Define.
+ * libelf.h (struct elf_obj_tdata): Add find_line_info field.
+
+ * ecoff.c (_bfd_ecoff_swap_tir_in): Move to ecofflink.c.
+ (_bfd_ecoff_swap_tir_out): Likewise.
+ (_bfd_ecoff_swap_rndx_in): Likewise.
+ (_bfd_ecoff_swap_rndx_out): Likewise.
+ (cmp_fdrtab_entry): Likewise.
+ (mk_fdrtab): Likewise.
+ (lookup): Likewise.
+ (_bfd_ecoff_find_nearest_line): Just call _bfd_ecoff_locate_line
+ to do most of the work. Allocate find_line_info if necessary.
+ * ecofflink.c: Include "aout/stab_gnu.h".
+ (_bfd_ecoff_swap_tir_in): Move in from ecoff.c.
+ (_bfd_ecoff_swap_tir_out): Likewise.
+ (_bfd_ecoff_swap_rndx_in): Likewise.
+ (_bfd_ecoff_swap_rndx_out): Likewise.
+ (cmp_fdrtab_entry): Likewise. Use PTR instead of void *.
+ (mk_fdrtab): Move in from ecoff.c. Add debug_info, debug_swap,
+ and line_info arguments, and use them instead of ecoff_data.
+ (fdrtab_lookup): Move in from lookup in ecoff.c. Remove abfd
+ argument, add line_info argument. Use it instead of ecoff_data.
+ (_bfd_ecoff_locate_line): New function, mostly from the old
+ _bfd_ecoff_find_nearest_line in ecoff.c.
+ * libecoff.h (ecoff_data_type): Remove find_buffer, fdrtab_len and
+ fdrtab fields, replacing them find_line_info field.
+ (_bfd_ecoff_swap_tir_in): Declare.
+ (_bfd_ecoff_swap_tir_out): Declare.
+ (_bfd_ecoff_swap_rndx_in): Declare.
+ (_bfd_ecoff_swap_rndx_out): Declare.
+ * libbfd-in.h (_bfd_ecoff_locate_line): Declare.
+ * libbfd.h: Rebuild.
+ * configure.in: Don't use ecoff.o for bfd_elf32_bigmips_vec or
+ bfd_elf32_littlemips_vec.
+ * Makefile.in: Rebuild dependencies.
+
+Tue Feb 14 14:04:22 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * libelf.h (elf_backend_data): Add fields elf_machine_alt1 and
+ elf_machine_alt2 which provide alternate versions of the machine
+ code.
+
+ * elf32-ppc.c (ELF_MACHINE_ALT1, ELF_MACHINE_ALT2): Define to
+ recognize old versions of the PowerPC machine code.
+
+ * elf32-target.h (elf32_bed): Initialize alternate machine code
+ fields defined by ELF_MACHINE_ALT1 and ELF_MACHINE_ALT2.
+
+ * elf64-target.h (elf64_bed): Initialize alternate machine code
+ fields defined by ELF_MACHINE_ALT1 and ELF_MACHINE_ALT2.
+
+ * elfcode.h (elf_object_p, elf_core_file_p): In addition to the
+ main machine code field, check the two alternate machine code
+ fields.
+
+Tue Feb 14 12:46:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutf1.h (MACHTYPE_OK): Don't define if already defined. Don't
+ accept M_SPARC if bfd_arch_sparc is not in the list of supported
+ architectures, and don't accept a 680x0 machine type if
+ bfd_arch_m68k is not in the list of supported architectures.
+ * aout0.c (MACHTYPE_OK): Define.
+
+Mon Feb 13 23:25:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,swap_ext_reloc_in)): Don't return a pointer
+ to garbage if the symbol index is out of range.
+ (NAME(aout,swap_std_reloc_in)): Likewise.
+
+Thu Feb 9 18:36:52 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (BFD32_BACKENDS): Add i386msdos.o.
+
+Thu Feb 9 12:02:35 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386linux.c (NEEDS_SHRLIB): Define.
+ (linux_tally_symbols): Crash if a NEEDS_SHRLIB symbol is
+ undefined. From hjl@nynexst.com (H.J. Lu).
+
+Wed Feb 8 17:26:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * linker.c (generic_link_check_archive_element): Allocate common
+ symbol information structure. Don't bother to check for common
+ symbol size overflow.
+ (_bfd_generic_link_add_one_symbol): Likewise.
+ * aoutx.h (aout_link_check_ar_symbols): Likewise.
+ * linker.c (generic_link_check_archive_element): Adjust references
+ to common symbol information for new structure.
+ (_bfd_generic_link_add_one_symbol): Likewise.
+ * aoutx.h (aout_link_check_ar_symbols): Likewise.
+ (aout_link_add_symbols): Likewise.
+ * ecoff.c (ecoff_link_add_externals): Likewise.
+ * elfcode.h (elf_link_add_object_symbols): Likewise.
+ (elf_link_output_extsym): Likewise.
+ * sunos.c (sunos_add_one_symbol): Likewise.
+
+Wed Feb 8 09:53:42 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * elfcode.h (elf_sort_hdrs): Put SHT_NOBITS sections after !SHT_NOBITS.
+
+Tue Feb 7 16:27:33 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_find_nearest_line): Just return false, don't
+ abort.
+
+Tue Feb 7 14:43:33 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * ecoff.c: Reformatted some comments and brace constructs in
+ recent changes to GNU style.
+ (cmp_fdrtab_entry, mk_fdrtab, lookup): Use old-style function
+ definitions.
+
+Tue Feb 7 14:21:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoffswap.h (ecoff_swap_pdr_in): Zero out intern before setting
+ any of the fields.
+
+Mon Feb 6 20:01:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sat Feb 4 14:20:24 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
+
+ * ecoffswap.h (ecoff_swap_pdr_in, ecoff_swap_pdr_out): added
+ internalizing/externalizing new "prof" field.
+
+ * libecoff.h (ecoff_tdata): added fdrtab.
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): Fixed.
+
+Mon Feb 6 14:25:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libelf.h (struct elf_link_hash_table): Add saw_needed field.
+ * elfcode.h (elf_link_add_object_symbols): Set saw_needed if
+ DT_NEEDED seen in .dynamic section.
+ (elf_link_output_extsym): Warn if an undefined symbol is
+ only referenced from a dynamic object, and not making a shared
+ object, and saw_needed is false.
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize saw_needed.
+
+ * libelf.h (ELF_LINK_HASH_DEFINED_WEAK): Don't define.
+ * elfcode.h (elf_link_add_object_symbols): Don't clear or set
+ ELF_LINK_HASH_DEFINED_WEAK.
+ (elf_link_output_extsym): Don't check ELF_LINK_HASH_DEFINED_WEAK.
+
+ Distinguish a weak defined symbol from a regular defined symbol.
+ * linker.c (enum link_action): Add DEFW.
+ (link_action): Add bfd_link_hash_defweak column.
+ (_bfd_generic_link_add_one_symbol): Add DEFW case. Handle
+ bfd_link_hash_defweak in a few other cases.
+ * Many files (bfd_link_hash_undefweak): Renamed from
+ bfd_link_hash_weak.
+ * aoutx.h (aout_link_write_symbols): Handle bfd_link_hash_defweak.
+ (aout_link_write_other_symbol): Likewise.
+ (aout_link_input_section_std): Likewise.
+ (aout_link_input_section_ext): Likewise.
+ * bout.c (get_value): Likewise.
+ * coff-a29k.c (coff_a29k_relocate_section): Likewise.
+ * coff-alpha.c (alpha_convert_external_reloc): Likewise.
+ (alpha_relocate_section): Likewise.
+ * coff-mips.c (mips_relocate_section): Likewise.
+ (mips_relax_section): Likewise.
+ (bfd_mips_ecoff_create_embedded_relocs): Likewise.
+ * cofflink.c (coff_write_global_sym): Likewise.
+ (_bfd_coff_generic_relocate_section): Likewise.
+ * ecoff.c (ecoff_link_add_externals): Likewise.
+ (ecoff_link_write_external): LIkewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ (elf32_hppa_size_stubs): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ * elf32-mips.c (mips_elf_output_extsym): Likewise.
+ (mips_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+ (elf32_sparc_relocate_section): Likewise.
+ * elfcode.h (elf_link_add_object_symbols): Likewise.
+ (elf_adjust_dynamic_symbol): Likewise.
+ (elf_bfd_final_link): Likewise.
+ (elf_link_output_extsym): Likewise.
+ * i386linux.c (linux_add_one_symbol): Likewise.
+ (linux_tally_symbols): Likewise.
+ (linux_finish_dynamic_link): Likewise.
+ * linker.c (_bfd_generic_link_output_symbols): Likewise.
+ (set_symbol_from_hash): Likewise.
+ * reloc16.c (bfd_coff_reloc16_get_value): Likewise.
+ (bfd_perform_slip): Likewise.
+ * sunos.c (sunos_add_one_symbol): Likewise.
+ (sunos_scan_std_relocs): Likewise.
+ (sunos_scan_ext_relocs): Likewise.
+ (sunos_scan_dynamic_symbol): Likewise.
+ (sunos_write_dynamic_symbol): Likewise.
+
+Mon Feb 6 03:20:17 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from Bryan Ford, baford@schirf.cs.utah.edu:
+ * config.bfd (i[345]86-*-msdos*): New target.
+ * configure.in (i386msdos_vec): Handle it.
+ * i386msdos.c: New file.
+ * config/i386-msdos.mt: New file.
+ * bfd.c (enum bfd_error): Added new value bfd_error_file_too_big.
+ (bfd_errmsgs): Added string to table.
+ * libaout.h (reloc_type-lookup): Declare it.
+ * targets.c (enum bfd_flavour): Added bfd_target_msdos_flavour.
+ (i386msdos_vec): Declare.
+ (bfd_target_vector): Add it to the list.
+ * bfd-in2.h: Regenerated.
+
+Wed Feb 1 01:32:14 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_set_reloc_info, case R_DATA_ONE_SYMBOL): If there's
+ nothing in R_DATA_OVERRIDE, then try to find the addend in the
+ section's contents.
+ (som_write_fixups): Ignore the addend in a R_DATA_ONE_SYMBOL fixup.
+
+ * som.c (som_object_setup): More heruistics to detect the
+ braindamaged HP OSF1 linker.
+ (setup_sections): Don't forget to free subspace_sections if we get
+ an error.
+ (som_slurp_string_table): Allocate strings on this bfd's obstack
+ rather than directly out of the heap.
+ (som_slurp_symbol_table): Likewise for the saved copy of the
+ canonical symbols.
+ (som_slurp_reloc_table): Likewise for the saved copy of the
+ canonical relocations. Free the native relocations when we're
+ done with them.
+
+Tue Jan 31 21:53:28 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * libelf.h (struct elf_obj_tdata): New member program_header_size.
+ * elfcode.h (get_program_header_size): New parameters sorted_hdrs,
+ count, and maxpagesize. All callers updated.
+ If sorted_hdrs is non-NULL, use it to compute the number of segments.
+ Save result in case called again.
+ (assign_file_positions_except_relocs): Sort headers before calling
+ get_program_header_size.
+
+Tue Jan 31 15:27:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (map_program_segments): Add sorted_hdrs parameter.
+ Search through it rather than through unsorted section headers.
+ (assign_file_positions_except_relocs): Pass sorted_hdrs to
+ map_program_segments.
+
+Mon Jan 30 22:04:53 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): Fix problems in range
+ checking. Expect argument OFFSET to be section-relative. From
+ David Mosberger-Tang, davidm@piston.cs.arizona.edu.
+
+Mon Jan 30 11:22:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (NAME(bfd_elf,record_link_assignment)): Don't do
+ anything if we are not linking an ELF file.
+ (NAME(bfd_elf,size_dynamic_sections)): Likewise.
+
+Sat Jan 28 12:48:57 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (compare_subspaces): New function to sort subspaces by
+ their location in the object file.
+ (setup_sections): When computing the index for each subspace,
+ handle case where setup_sections reads the subspaces in a
+ different order that they appear in the object file.
+ (som_is_space): Also examine the output section for the containing
+ section.
+ (som_is_subspace, som_is_container): Likewise.
+ (som_begin_writing): Don't prepare or write fixups here. When
+ writing the symbol strings, use the unsorted symbol table.
+ (som_write_object_contents): Don't write the symbol table here.
+ (som_finish_writing): Prepare and write the fixups here. Likewise
+ for the symbol table.
+ (som_bfd_derive_misc_symbol_info): Undefined symbols always have
+ type SS_UNSAT regardless of BSF_EXPORT.
+ (som_set_reloc_info): Unpack and attach argument location
+ information for R_PCREL_CALL and R_ABS_CALL relocations.
+
+ * som.c (som_object_setup): New heuristic to determine if the
+ entry and flags fields are switched in the exec header.
+
+Sat Jan 28 00:16:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_link_add_object_symbols): Use *sym_hash instead
+ of h if we might not be doing an ELF link.
+
+Fri Jan 27 16:13:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_final_link): If the size of an input
+ .reginfo section is zero, force it to the correct size, since the
+ linker emulation code may have clobbered it.
+
+ * elfcode.h (elf_sort_hdrs): Correct SHF_ALLOC test.
+ (assign_file_positions_except_relocs): Free sorted_hdrs.
+
+Thu Jan 26 09:00:12 1995 Steve Chamberlain <sac@splat>
+
+ * srec.c (srec_set_section_contents): Fix off by
+ one end address calculation.
+
+ * config.bfd: (m68*-est-coff): New configuration.
+
+Thu Jan 26 11:39:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_link_add_object_symbols): Only examine weakdef if
+ we are using an ELF hash table.
+
+ * aoutx.h (NAME(aout,some_aout_object_p)): Always set EXEC_P if
+ the start address is in the .text section, even if STAT_FOR_EXEC
+ is set. Just use STAT_FOR_EXEC as an additional test.
+
+Thu Jan 26 11:12:54 1995 Michael Meissner <meissner@cygnus.com>
+
+ * elfcode.h (prep_headers): Use EM_PPC instead of
+ EM_CYGNUS_POWERPC.
+
+ * elf32-ppc.c (reloc_type): Add all System V.4 and eABI
+ relocations currently defined.
+ (powerpc_reloc_map): Adjust to new relocation names.
+ (elf_powerpc_howto_table): Add most of the new relocations.
+ (ELF_MACHINE_CODE): Use EM_PPC instead of EM_CYGNUS_POWERPC.
+
+ * config.bfd: Add support for powerpc-*-eabi.
+
+ * config/ppc-elf.mt: Add rs6000 architecture support to the
+ PowerPC. Also add XCOFF support.
+
+Wed Jan 25 23:26:13 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (CALC_ADDEND): Don't define.
+ (coff_sh_relocate_section): Remove.
+ (coff_relocate_section): Use _bfd_coff_generic_relocate_section.
+
+Tue Jan 24 14:22:47 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elf32-mips.c (mips_elf_output_extsym): Set the value of the
+ ECOFF symbol from the hash table entry.
+
+Mon Jan 23 14:53:35 1995 Steve Chamberlain <sac@splat>
+
+ * coff-sh.c (coff_sh_relocate_section): Don't subtract
+ vma twice.
+
+Mon Jan 23 13:33:18 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * coff-sh.c (sh_reloc): Don't ignore the previous contents of an
+ R_SH_IMM32 reloc.
+
+ * config.bfd (i[345]86-*-gnu*): Set bfd_name to i386-gnu.
+ * config/i386-gnu.mt: New file. Include ELF support.
+
+ * opncls.c (bfd_openstreamr): Call bfd_cache_init.
+
+Fri Jan 20 11:44:45 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * sunos.c (sunos_add_one_symbol): Only set the sunos specific
+ fields if we are doing a sunos link.
+
+Wed Jan 18 12:28:17 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * cpu-h8300.c (h8300_info_struct): Change name from "H8/300" to
+ "h8300" for consistency with other cpu-* files.
+ (h8300h_info_struct): Change name from "H8/300H" to "h8300h".
+ * coff-h8300.c (special): Remove unused variable diff.
+
+Tue Jan 17 10:52:32 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * bfd-in.h (bfd_byte, reloc_howto_type): Define here, not...
+ * reloc.c (bfd_byte, reloc_howto_type): here.
+ * Changed all occurrences of ``const struct reloc_howto_struct''
+ to be ``reloc_howto_type'' instead.
+ * bfd-in2.h, libbfd.h, libcoff.h: Rebuilt.
+
+ * opncls.c (bfd_openstreamr): New function.
+ * bfd-in2.h: Rebuilt.
+
+ * elf32-mips.c (enum reloc_type): Define new relocs used on Irix.
+ (elf_mips_howto_table): Add entries for new relocs.
+ (mips_elf_section_from_shdr): Handle SHT_MIPS_MSYM,
+ SHT_MIPS_DWARF, and SHT_MIPS_EVENTS.
+ (mips_elf_fake_sections): Handle sections named .msym, .debug_*
+ and .MIPS.events.*.
+
+ * srec.c (srec_init): Remove unused local variable i.
+
+Sat Jan 14 19:09:48 1995 Steve Chamberlain <sac@jonny>
+
+ * archures.c, Makefile.in, targets.c, bfd-in2.h, coffcode.h,
+ config.bfd, configure.in, config/w65.mt: Initial support for the W65.
+
+Sun Jan 15 13:57:45 1995 Steve Chamberlain <sac@splat>
+
+ * opncls.c (bfd_fdopenr): Configure for WIN32.
+
+Thu Jan 12 16:30:47 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (diststuff): Include `headers'.
+
+ * sunos.c (m68k_plt_first_entry, sparc_plt_first_entry): Now
+ const.
+ * tekhex.c (digs): Ditto.
+ * elf32-i386.c (elf_i386_plt0_entry, elf_i386_plt_entry): Ditto.
+
+ * srec.c, tekhex.c: Include libiberty.h. Delete static array
+ hex_value and replace references to it with references to
+ hex_init, hex_p, and hex_value.
+ * Makefile.in: Updated dependencies.
+
+ * archures.c (archures_init_table): Now const.
+ (bfd_arch_init): Adjusted type of local var `ptable'.
+
+Thu Jan 12 09:33:24 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * hosts/symmetry.h: Redefine `shared' to enable compilation
+ with the native Dynix cc compiler.
+ * i386dynix.c: Include aoutx.h instead of using routines
+ from aout32.c.
+
+Wed Jan 11 21:31:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * reloc.c (reloc_howto_type): Make typedef include `const'.
+ * aout-ns32k.c, aoutx.h, bout.c, cf-m68klynx.c, coff-i386.c,
+ coff-i960.c, coff-m68k.c, cofflink.c, cpu-ns32k.c, ecoff.c,
+ elf32-hppa.c, elf32-i386.c, elf32-mips.c, elf32-sparc.c,
+ elfcode.h, libbfd-in.h, linker.c, mipsbsd.c, nlm32-ppc.c, oasys.c,
+ reloc.c, som.c: Don't use `const' in combination with
+ `reloc_howto_type'.
+ * bfd-in2.h, libbfd.h: Regenerated.
+
+ * ecoff.c (ecoff_type_to_string): Local variable `buffer1' doesn't
+ need to be static.
+
+Wed Jan 11 14:36:41 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * sunos.c (sunos_add_one_symbol): Don't core dump if a multiple
+ definition of an absolute symbol is encountered.
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Ignore
+ redefinitions of an absolute symbol to the same value.
+
+Mon Jan 9 15:51:32 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_link_add_object_symbols): It's reasonable for no
+ flags to be set, so don't insist otherwise.
+
+Fri Jan 6 16:39:40 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_slurp_symbol_table): Don't set BSF_GLOBAL for an
+ undefined or common symbol.
+ (elf_link_add_object_symbols): Likewise.
+
+Wed Jan 4 14:14:05 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (bfd_section_from_som_symbol): Only return sections which
+ correspond to subspaces.
+
+ * som.c (som_begin_writing): Don't forget to bump the
+ total_subspaces when writing the unloadable subspaces.
+
+Wed Dec 28 20:54:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_write_fixups): Use SEC_HAS_CONTENTS to identify
+ bss-like sections.
+ (som_get_section_contents): Likewise.
+ (som_set_section_contents): Likewise.
+
+Tue Dec 27 14:03:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (setup_sections): Turn off SEC_HAS_CONTENTS for bss-like
+ sections.
+
+Tue Dec 20 15:30:12 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * coffgen.c (bfd_debug_section): Deleted.
+ (coff_section_from_bfd_index): Return absolute section for debug
+ symbol.
+ (coff_write_symbol): Set BSF_DEBUGGING for C_FILE symbols. If
+ BSF_DEBUGGING is set, set section to N_DEBUG.
+ (coff_bfd_make_debug_symbol): Use absolute section.
+
+ * elfcode.h (assign_file_positions_except_relocs): In assertion,
+ force all values to the same type.
+
+Tue Dec 20 11:11:58 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coff-h8300.c (howto_table): All relocs get a special function.
+ (special): Never do anything when linking -r.
+
+Tue Dec 20 13:58:01 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * i386linux.c (linux_add_one_symbol): Don't do anything Linux
+ specific if this is not a Linux hash table. From Eric Youngdale
+ <eric@aib.com>.
+
+ Patches from kkojima@mix.or.jp (Kazumoto Kojima):
+ * mipsbsd.c (mips_howto_table_ext): Change sizes of memory relocs
+ apply to from two bytes to four bytes.
+ * MY(reloc_howto_type_lookup): Handle BFD_RELOC_CTOR.
+
+ * elf32-i386.c (elf_i386_relocate_section): Correct and expand the
+ list of cases for which relocation need not be computed.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+Mon Dec 19 23:09:16 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_read_symext_info): Delete do_locals and
+ do_globals arguments, always read symbol extension information for
+ globals and locals. All callers changed.
+ (elf32_hppa_size_stubs): Rework to only read symbol extension
+ information once for each input bfd. 10% improvement in linker
+ performance.
+
+Fri Dec 16 12:28:46 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_section_from_bfd_section): Check
+ bfd_is_abs_section, etc., only after checking for the section in
+ the BFD and after calling the backend routine.
+
+Wed Dec 14 20:21:58 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_map_symbols): Only use section symbols whose
+ value is the start of the section, checking output_offset when
+ using output_section. When creating a new symbol, set the value
+ to 0, since BFD symbol values are section relative.
+
+Tue Dec 13 13:31:06 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * cpu-z8k.c (arch_info_struct): Make z8002 the default
+ architecture.
+
+Fri Dec 9 12:43:05 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_bfd_link_add_symbols): If the first object in the
+ archive is not an ELF object, pass the archive to the add_symbols
+ entry point appropriate for the first object. From Eric Youngdale
+ <eric@aib.com>.
+ * aoutx.h (NAME(aout,link_add_symbols)): Similar change if the
+ first object is not an a.out object.
+
+ * elf32-i386.c (elf_i386_relocate_section): Don't compute
+ relocation in cases where we won't use it.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+Thu Dec 8 14:19:41 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * pc532-mach.c (NAME): Define to use ns32kaout prefix.
+ * ns32knetbsd.c (NAME): Ditto.
+ (ns32kaout_32_get_section_contents): Define to standard aout-32
+ version.
+
+Fri Dec 2 13:56:49 1994 Ian Lance Taylor <ian@rtl.cygnus.com>
+
+ * coff-mips.c (mips_read_relocs): New static function, broken out
+ of mips_relax_section.
+ (mips_relax_section): Call mips_read_relocs.
+ (bfd_mips_ecoff_create_embedded_relocs): New function.
+ * bfd-in.h (bfd_mnips_ecoff_create_embedded_relocs): Declare.
+ * bfd-in2.h: Rebuild.
+
+Wed Nov 30 14:12:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-sh.c: Use _bfd_dummy_target instead of no_archive.
+
+Tue Nov 29 14:00:19 1994 J.T. Conklin <jtc@.rtl.cygnus.com>
+
+ * config.bfd (i[345]86-*-freebsd*): Use i386-bsd as bfd_name.
+ * configure.host (i[345]86-*-freebsd*): Use i386bsd as my_host.
+
+Mon Nov 28 15:36:04 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/m68k-nbsd.mt (DEFAULT_VECTOR): set to m68knetbsd_vec.
+ * Makefile.in: Rebuilt dependancies.
+ (CFILES): Added m68knetbsd.c.
+ (HFILES): Added netbsd.h.
+
+Wed Nov 23 19:21:41 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coff-sh.c (shlcoff_vec): New target vector.
+ (no_archive): New function.
+ * coffcode.h (coff_set_arch_mach_hook, coff_set_flags): Handle
+ little endian SH.
+ * configure.in: Handle shl.
+ * targets.c (bfd_target_vector): Add shlcoff_vec.
+ * config/sh-coff.mt (SELECT_VECS): Handle shl_coff_vec.
+
+Wed Nov 23 10:50:13 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elfcode.h (write_relocs): Do not subtract the section's vma from
+ the reloc's offset when writing .o's. Instead add the section's
+ vma to the reloc's offset when writing an executable or shared
+ library.
+
+Tue Nov 22 23:34:37 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Do not add
+ input_section->vma to the relocation's offset.
+
+Mon Nov 21 12:37:25 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * srec.c (srec_get_reloc_upper_bound): Define.
+ (srec_canonicalize_reloc): Define.
+ (srec_bfd_reloc_type_lookup): Define.
+ (srec_vec, symbolsrec_vec): Use BFD_JUMP_TABLE_RELOCS (srec).
+
+Sat Nov 19 03:10:51 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.host (i[345]86-*-solaris*): Use solaris2 to
+ enable extraction of procfs info from core file for GDB.
+
+Thu Nov 17 17:37:39 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * reloc.c (bfd_reloc_code_type): Add new value BFD_RELOC_12_PCREL.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+Thu Nov 17 13:12:08 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * bfd/elf32-hppa.c (elf32_hppa_bfd_final_link_relocated): Use the
+ vma from the output_section containing $global$ when computing
+ global_vlaue.
+
+Thu Nov 17 14:29:13 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * archive.c (_bfd_write_archive_contents): Round up the archive
+ header size of the extended name table to an even number.
+
+Wed Nov 16 16:08:06 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * coff-sh.c: Deleted some code that was commented out or inside
+ "#if 0".
+ (COFF_LONG_FILENAMES): Define.
+
+ * cpu-sh.c (arch_info_struct): Convert name to lowercase, for
+ consistency with other architectures.
+
+Sat Nov 12 23:50:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (elf_export_symbol): Also export symbols which are
+ referenced by a regular file.
+
+Fri Nov 11 14:29:31 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Add
+ export_dynamic argument, and handle it.
+ (elf_export_symbol): New function.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update declaration.
+ (bfd_elf64_size_dynamic_sections): Update declaration.
+ * bfd-in2.h: Rebuild.
+
+Fri Nov 11 10:35:33 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hpux-core.c (hpux_core_struct): Delete handles for the
+ data, reg and stack sections. They're never used. Delete
+ accessor macros.
+ (make_bfd_asection): Use bfd_make_section_anyway since debugging
+ cores from dynamic executables may have several sections with the
+ same logical name.
+ (hpux_core_core_file_p): Don't save handles to data, reg and
+ stack sections. Handle CORE_TEXT, CORE_MMF and CORE_SHM.
+
+Tue Nov 8 13:03:30 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * bout.c (callj_callback): Add new argument shrinking. Change all
+ callers. Handle relocs against section symbols correctly. If not
+ shrinking, don't subtract out dstidx; the subtraction is already
+ in the object file.
+
+Sun Nov 6 12:52:00 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.h: Conditionally include <shl.h> and <dl.h>.
+
+Thu Nov 3 18:19:13 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (ALL_MACHINES): Include m68knetbsd.o.
+
+ * config/i386linux.mh (EXTRALIBS): Include -lm.
+
+ Patches from DJ Delorie:
+ * coff-go32.c: Replacement file, uses coff-i386.c with minor
+ changes.
+ * coff-i386.c (TARGET_UNDERSCORE): allow other files to override
+ underscore also
+ * makefile.dos: del ctor.o, add cofflink.o and elf32.o
+
+ * aoutx.h (adjust_o_magic): If user set data section vma, use it
+ to determine the default bss vma. Patch from Takada Hiroaki,
+ hiro@is.s.u-tokyo.ac.jp.
+ (machine_type, case bfd_arch_vax): Set *unknown to false. Patch
+ from John David Anglin <dave@hiauly1.hia.nrc.ca>.
+
+ * configure.in (tb): Rename ns32knetbsd_vec to pc532netbsd_vec,
+ since that's what it's called.
+
+Wed Nov 2 15:24:51 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * archive.c (normalize): Change to take a BFD as an argument.
+ Change VMS version to use bfd_alloc rather than malloc, so that we
+ don't lose the memory forever.
+ (_bfd_construct_extended_name_table): Check the name of an archive
+ entry which is not being extended, and correct it if it is wrong.
+ This is necessary in case the archive was constructed by another
+ program which put an entry in the extended name table which we
+ don't plan to put in ourselves. From jjc@jclark.com (James
+ Clark).
+ (bfd_dont_truncate_arname): Check return value of normalize.
+
+Mon Oct 31 14:19:08 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elf32-hppa.c (ELF32_PARISC_SX_SIZE): Define.
+ (ELF32_PARISC_SX_GET, ELF32_PARISC_SX_PUT): Define.
+ (symextn_entry): Don't define.
+ (symext_chain_size): Change type to bfd_size_type.
+ (symextn_contents): Change type to bfd_byte *.
+ (elf32_hppa_backend_begin_write_processing): Use
+ ELF32_PARISC_SX_SIZE instead of sizeof (symext_entryS).
+ (elf32_hppa_size_symext): Likewise. Also, change type of sizep to
+ bfd_size_type *.
+ (elf_hppa_tc_make_sections): Cast symextn_contents assignment to
+ bfd_byte *. Use ELF32_PARISC_SX_PUT instead of direct assignment.
+ (elf32_hppa_backend_symbol_table_processing): Use
+ ELF32_PARISC_SX_SIZE instead of sizeof (symext_entryS). Use
+ ELF32_PARISC_SX_GET insetad of direct assignment.
+ (elf32_hppa_read_symext_info): Change type of contents, and its
+ assignment cast, to bfd_byte *. Use ELF32_PARISC_SX_SIZE instead
+ of sizeof (symextn_entry). Use symext_entryS instead of
+ symextn_entry. Use ELF32_PARISC_SX_GET instead of direct
+ assignment.
+
+ * archive.c (bfd_dont_truncate_arname): Add the ar padding
+ character, if there is room for it, even if the name is the
+ maximum length.
+
+ * elfcode.h (assign_file_positions_except_relocs): Sort the ELF
+ headers by section address when assigning file positions.
+ (elf_sort_hdrs): New static function.
+
+Sun Oct 30 18:56:58 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Create DT_INIT
+ and DT_FINI dynamic entries based on the existence of _init and
+ _fini symbols, not on the .init and .fini sections. This is
+ compatible with some SVR4 linkers.
+ (elf_bfd_final_link): Corresponding change.
+
+Sat Oct 29 12:18:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Don't move a
+ symbol with a PLT entry into the .plt section if it is defined in
+ a regular file.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+
+ * linker.c (_bfd_generic_link_add_archive_symbols): It's not an
+ error if an empty archive has no symbol table.
+ * ecoff.c (ecoff_link_add_archive_symbols): Likewise.
+ * elfcode.h (elf_link_add_archive_symbols): Likewise.
+
+Fri Oct 28 10:08:41 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ NetBSD/m68k support, based on work by mikeb@snow.datametrics.com:
+ * config.bfd (m68*-*-netbsd*): Use m68k-nbsd as bfd_name.
+ * configure.in (m68knetbsd_vec): Added.
+ * targets.c (bfd_m68knetbsd_vec): Added.
+ * hosts/m68knbsd.h, config/m68k-nbsd.mt, m68knetbsd.c: New files.
+ * Makefile.in (BFD32_BACKENDS, CFILES): Add m68knetbsd.c.
+
+ miscellaneous cleanup required by all netbsd targets, based on work
+ by Andrew Cagney <cagney@highland.com.au>:
+ * netbsd.h (N_MAGIC, N_SET_MAGIC, N_GETMAGIC, N_GETMAGIC2, N_TXTADDR,
+ N_TXTOFF, N_ALIGN, N_DATADDR, N_DATOFF): Removed. Generic a.out
+ definitions work.
+ * i386nbsd.c, ns32knbsd.c, sparcnbsd.c (__LDPGSZ): Removed.
+ (MY(write_object_contents)): Use NetBSD's magic numbers
+
+Thu Oct 27 16:59:52 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * libelf.h (struct bfd_elf_section_data): Add field dynindx.
+ * elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Don't finalize
+ the .dynsym, .dynstr or .hash sections until after the backend
+ size_dynamic_sections routine, so that it can add dynamic symbols
+ if it wants to.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Don't define the
+ symbol to be in the .plt section when generating a shared library
+ if it is a defined symbol.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+ (elf32_sparc_size_dynamic_sections): When generating a shared
+ library, allocate space for a dynamic symbol for each output
+ section, storing the index in the dynindx field of the ELF section
+ data. Adjust the other dynindx fields to account for this.
+ (elf32_sparc_adjust_dynindx): New static function.
+ (elf32_sparc_relocate_section): When copying a reloc into a shared
+ library, use the original addend as appropriate. Convert an
+ R_SPARC_32 reloc into an R_SPARC_RELATIVE reloc. Use the dynamic
+ symbol index of the output section, not the normal symbol index.
+ (elf32_sparc_finish_dynamic_sections): Don't die if a section does
+ not exist when setting the value of the dynamic tags. Write out
+ a dynamic symbol for each output section.
+
+Wed Oct 26 01:15:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_link_input_section): Don't bother to read or write
+ the relocs if there aren't any.
+
+Tue Oct 25 11:44:38 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (ALL_MACHINES): Add tekhex.o.
+ * targets.c (bfd_target_vector): If SELECT_VECS is not defined,
+ include tekhex_vec.
+ * tekhex.c (NIBBLE, ISHEX): Cast array arguments to unsigned char.
+ (getvalue, getsym, out): Likewise.
+ (find_chunk): Remove unused variable s.
+ (first_phase): Remove unused variable s.
+ (pass_over): Remove unused variable address.
+ (tekhex_object_p): Remove unused variable section.
+ (move_section_contents): Change return type from boolean to void.
+ (tekhex_write_object_contents): Remove unused variables tdata and
+ list.
+
+ * linker.c (enum link_action): Add CIND.
+ (link_action): Change COMMON_ROW\indr from MDEF to CREF. Change
+ INDR_ROW\common from MDEF to CIND.
+ (_bfd_generic_link_add_one_symbol): In CREF case, handle an
+ existing symbol which is indirect rather than defined. Add new
+ CIND case.
+
+Mon Oct 24 15:33:16 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ Change S-record backend to use multiple sections to handle gaps in
+ file.
+ * srec.c (srec_data_list_struct): Move field next from last place
+ to first. Change type of data to bfd_byte *.
+ (struct srec_symbol): Define.
+ (tdata_type): Remove done_symbol_read, count, strings, symbol_idx,
+ string_size, string_idx. Change type of symbols to struct
+ srec_symbol *. Add symtail and csymbols.
+ (low, high): Remove.
+ (size_symbols, fillup_symbols, size_srec, fillup): Remove.
+ (white, skipwhite, pass_over, object_p): Remove.
+ (srec_mkobject): Call srec_init. Adjust tdata initialization for
+ field changes.
+ (srec_get_byte, srec_bad_byte): New static functions.
+ (srec_new_symbol, srec_scan): New static functions.
+ (srec_object_p): Change type of b to bfd_byte. Explicitly set
+ wrong_format error. Call srec_mkobject and srec_scan instead of
+ object_p.
+ (symbolsrec_object_p): Likewise. Also, change b to be only two
+ bytes.
+ (srec_read_section): New static function.
+ (srec_get_section_contents): Call srec_read_section rather than
+ pass_over. Handle zero length section correctly.
+ (set_set_arch_mach): Change from function to macro.
+ (srec_set_section_contents): Change data to bfd_byte *.
+ (srec_write_record): Change data, end and src to bfd_byte *.
+ (srec_write_header): Change buffer and dst to bfd_byte *.
+ (srec_write_section): Change location to bfd_byte *.
+ (srec_write_terminator): Change buffer to bfd_byte *.
+ (srec_get_symtab_upper_bound): Don't call
+ srec_get_section_contents.
+ (srec_get_symtab): Rewrite.
+
+ * ecoff.c (ecoff_set_symbol_info): Set udata.i to 0, not NULL.
+
+Fri Oct 21 16:43:13 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * libaout.h (machine_type): added M_68K_NETBSD and M_SPARC_NETBSD.
+ * i386netbsd.c, ns32knetbsd.c, sparcnetbsd.c: removed RCS Id's.
+ changed how PAGE_SIZE and SEGMENT_SIZE are defined so they are
+ consistant with each other.
+ * netbsd.h (N_HEADER_IN_TEXT, TEXT_START_ADDR): NetBSD fits its
+ header into the start of its text segment.
+
+Fri Oct 21 17:13:07 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * targets.c (BFD_JUMP_TABLE_ARCHIVE): Add case for
+ _construct_extended_name_table.
+ (bfd_target): Add _bfd_construct_extended_name_table.
+ * archive.c (_bfd_archive_bsd_construct_extended_name_table): New
+ function.
+ (_bfd_archive_coff_construct_extended_name_table): New function.
+ (_bfd_construct_extended_name_table): Renamed by adding a leading
+ underscore, and made externally visible. Added trailing_slash
+ argument, and used it instead of elf_style. Changed type of
+ tablen to bfd_size_type *.
+ (_bfd_write_archive_contents): Use BFD_SEND to call
+ construct_extended_name_table. Use the returned name.
+ * libbfd-in.h (_bfd_construct_extended_name_table): Declare.
+ (_bfd_noarchive_construct_extended_name_table): Define.
+ (_bfd_archive_bsd_construct_extended_name_table): Declare.
+ (_bfd_archive_coff_construct_extended_name_table): Declare.
+ * bfd-in2.h: Rebuild.
+ * libbfd.h: Rebuild.
+ * som.c (som_construct_extended_name_table): New static function.
+ * aout-target.h (MY_construct_extended_name_table): Define.
+ * coff-rs6000.c (rs6000coff_construct_extended_name_table):
+ Define.
+ * ieee.c (ieee_construct_extended_name_table): Define.
+ * libecoff.h (_bfd_ecoff_construct_extended_name_table): Define.
+ * oasys.c (oasys_construct_extended_name_table): Define.
+
+ Fix the ELF linker to not require an interpreter if no dynamic
+ objects were seen, even when linking PIC code.
+ * libelf.h (ELF_LINK_HASH_NEEDS_PLT): Define.
+ (struct elf_link_hash_table): Add field dynamic_sections_created.
+ * elfcode.h (elf_link_record_dynamic_symbol): Create dynstr if it
+ doesn't already exist.
+ (elf_link_add_object_symbols): Create dynamic sections based on
+ dynamic_sections_created field, not dynobj field. Don't bother to
+ set dynobj.
+ (elf_link_create_dynamic_sections): If dynamic sections were
+ already created, don't do anything. If dynobj is already set, use
+ it; otherwise, set it to the bfd argument. Don't initialize
+ dynsymcount. Only create dynstr if it does not exist. Set
+ dynamic_sections_created to true.
+ (NAME(bfd_elf,size_dynamic_sections)): Skip most of this function
+ if no dynamic objects were seen.
+ (elf_adjust_dynamic_symbol): If a symbol has the
+ ELF_LINK_HASH_NEEDS_PLT flag set, let the backend adjust it.
+ (elf_bfd_final_link): Change most decisions based on dynobj to
+ check dynamic_sections_created instead.
+ (elf_link_output_extsym): Only handle dynamic symbols if a dynamic
+ object was seen.
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize new field
+ dynamic_sections_created. Set dynsymcount to 1, not 0.
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Call
+ elf_i386_create_got_section rather than creating the .got and
+ .got.plt sections.
+ (elf_i386_create_got_section): New static function.
+ (elf_i386_check_relocs): Just call elf_i386_create_got_section if
+ a GOT table is needed, not bfd_elf32_link_create_dynamic_sections.
+ Only create the .rel.got section, and only make space for a reloc,
+ for a global symbol or when generating a shared object. For a
+ R_386_PLT32 reloc, just set the ELF_LINK_HASH_NEEDS_PLT flag.
+ (elf_i386_adjust_dynamic_symbol): Rework initial assertion to
+ permit ELF_LINK_HASH_NEEDS_PLT non dynamic symbols. Create a
+ procedure linkage table entry for such symbols. But, if no
+ dynamic objects were seen, never create a PLT entry.
+ (elf_i386_size_dynamic_sections): If no dynamic objects were seen,
+ skip most of this function, and force the size of the .rel.got
+ section to zero.
+ (elf_i386_relocate_section): For a R_386_GOT32 reloc against a global
+ symbol when no dynamic object was seen, initialize the contents of
+ the .got section. For a R_386_GOT32 against a local symbol, only
+ create a R_386_RELATIVE reloc when generating a shared object.
+ Treat a R_386_PLT32 reloc against a symbol for which we did not
+ create a PLT entry as a R_386_PC32 reloc.
+ (elf_i386_finish_dynamic_sections): Only fiddle with the dynamic
+ entries and the PLT if we saw a dynamic object.
+ * elf32-sparc.c (elf_sparc_howto_table): Fix R_SPARC_PC22 by
+ setting rightshift to 10. Fix R_SPARC_WPLT20 by setting
+ rightshift to 2, size to 2, bitsize to 30, and dst_mask to
+ 0x3fffffff.
+ (elf32_sparc_create_dynamic_sections): Don't set the size of the
+ .plt section. Call elf32_sparc_create_got_section rather than
+ creating the .got section.
+ (elf32_sparc_check_relocs): Call elf32_sparc_create_got_section if
+ a GOT table is needed, not bfd_elf32_link_create_dynamic_sections.
+ Only create the .rela.got section, and only make space for a
+ reloc, for a global symbol or when generating a shared object.
+ Set the alignment of the .rela.got section to 2. For a
+ R_SPARC_WPLT30 reloc, just set the ELF_LINK_HASH_NEEDS_PLT flag.
+ (elf32_sparc_adjust_dynamic_symbol): Rework initial assertion to
+ permit ELF_LINK_HASH_NEDS_PLT non dynamic symbols. Create a
+ procedure linkage table for such symbols. But, if no dynamic
+ objects were seen, never create a PLT entry. Initialize the size
+ of the .plt section.
+ (elf32_sparc_size_dynamic_sections): If no dynamic objects were
+ seen, skip most of this function, and force the size of the
+ .rela.got section to zero. Strip empty reloc sections, and strip
+ an empty .plt section.
+ (elf32_sparc_relocate_section): For a GOT reloc against a global
+ symbol when no dynamic object was seen, initialize the contents of
+ the .got section. For a GOT reloc against a local symbol, only
+ create a R_SPARC_RELATIVE reloc when generating a shared object.
+ Treat a R_SPARC_WPLT30 reloc against a symbol for which we did not
+ create a PLT entry as a R_SPARC_WDISP30 reloc.
+ (elf32_sparc_finish_dynamic_sections): Only fiddle with the
+ dynamic entries and the PLT if we saw a dynamic object.
+
+Thu Oct 20 13:28:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (elf_map_symbols): Don't worry about section symbols
+ in a section not owned by any BFD.
+ (elf_section_from_bfd_section): Separate out loop which calls
+ backend routine. Check bfd_section and call the backend routine
+ even for a section not owned by any BFD.
+ * elf32-mips.c (mips_elf_section_from_bfd_section): Handle
+ .acommon section.
+
+Wed Oct 19 13:28:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * coffgen.c (coff_print_symbol): Make names for section number and
+ storage class slightly more verbose. It's not clear how many
+ characters I can justify using up, but before this change they
+ both were abbreviated "sc" which is (IMHO) clearly unacceptable.
+
+Wed Oct 19 01:26:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * binary.c (binary_set_section_contents): Set the base file
+ position from the lowest section VMA, not the start address.
+
+ * aoutx.h (NAME(aout,slurp_symbol_table)): Don't return an error
+ if there are no symbols.
+ * coffgen.c (coff_get_normalized_symtab): Likewise.
+ * hp300hpux.c (MY(slurp_symbol_table)): Likewise.
+
+Tue Oct 18 12:56:43 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * aout-target.h (MY_bfd_copy_private_section_data): Only copy
+ subformat to another bfd_target_aout_flavour file.
+
+ * binary.c: New file for raw binary output format.
+ * Makefile.in (BFD_LIBS): Add binary.o.
+ (CFILES): Add binary.c.
+ * targets.c (binary_vec): Declare.
+ (bfd_target_vector): Include binary_vec.
+
+ * srec.c (tdata_type): Add field tail.
+ (srec_mkobject): Initialize tail.
+ (srec_set_section_contents): Sort S record list by address.
+
+Mon Oct 17 11:38:16 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_map_symbols): Sort the symbols into a new array,
+ rather than messing with Elf_Sym_Extra. Store the symbol index in
+ the udata.i field.
+ (swap_out_syms): Use outbound_syms as a pointer rather than as an
+ array. Don't worry about elf_sym_num.
+ * libelf.h (struct elf_sym_extra): Don't define.
+ (Elf_Sym_Extra): Don't define.
+ (struct elf_obj_tdata): Remove sym_extra field.
+ (elf_sym_extra): Don't define.
+ * elf32-hppa.c (elf32_hppa_backend_final_write_processing): Use
+ udata.i rather than elf_sym_extra array.
+
+ * syms.c (asymbol): Change udata field into a union.
+ * bfd-in2.h: Rebuild.
+ * aoutx.h (NAME(aout,translate_symbol_table)): Use udata.p rather
+ than just udata.
+ * bout.c (perform_slip): Likewise.
+ * hp300hpux.c (MY(slurp_symbol_table)): Likewise.
+ * ieee.c (ieee_slurp_external_symbols): Likewise.
+ * linker.c (generic_link_add_symbol_list): Likewise.
+ (default_indirect_link_order): Likewise.
+ * oasys.c (oasys_slurp_symbol_table): Likewise.
+ * reloc16.c (bfd_perform_slip): Likewise.
+ * srec.c (fillup_symbols): Likewise.
+ * coffcode.h (get_index): Use udata.i rather than just udata.
+ (coff_slurp_symbol_table): Likewise.
+ * coffgen.c (set_index): Likewise.
+ * ecoff.c (ecoff_set_symbol_info): Likewise.
+ * elfcode.h (elf_symbol_from_bfd_symbol): Likewise.
+ * libecoff.h (ecoff_get_sym_index, ecoff_set_sym_index): Likewise.
+ * som.c (compare_syms): Likewise.
+ (som_prep_for_fixups): Likewise.
+ (som_write_fixups): Likewise.
+
+ Use a hash table when writing out ELF symbol names.
+ * elfcode.h (elf_stringtab_init): New static function.
+ (bfd_new_strtab, bfd_add_to_strtab, bfd_add_2_to_strtab): Remove.
+ Change all callers to use elf_stringtab_init or
+ _bfd_stringtab_add, and get stringtab lengths using
+ _bfd_stringtab_size.
+ (elf_fake_sections): Change ignored argument to pointer to
+ boolean, and set the boolean to true if an error occurs. If an
+ error has already occurred, don't do anything.
+ (assign_section_numbers): Just set sh_size, not contents.
+ (elf_compute_section_file_positions): Pass the address of a
+ boolean to elf_fake_sections. Pass the address of a
+ bfd_strtab_hash to swap_out_syms. Write out the .strtab section.
+ (prep_headers): Change shstrtab to bfd_strtab_hash.
+ (swap_out_syms): Take a pointer to a bfd_strtab_hash as an
+ argument. Set it to the symbol names.
+ (NAME(bfd_elf,write_object_contents)): Write out the section
+ header names using _bfd_stringtab_emit.
+ (elf_debug_section): Remove first argument; get the section name
+ via the bfd_section pointer. Change caller.
+ (elf_bfd_final_link): Write out the symbol names using
+ _bfd_stringtab_emit. Likewise for the .dynstr section contents.
+ Free the symbol names at the end of the function.
+ (elf_link_input_bfd): Remove the last argument, output_names,
+ from relocate_section. Save the old symbol contents before
+ calling elf_link_output_sym, and restore them afterward.
+ * libelf.h (struct elf_link_hash_table): Change dynstr field to
+ struct bfd_strtab_hash.
+ (struct elf_backend_data): Remove last argument, output_names,
+ from elf_backend_relocate_section field.
+ (struct strtab): Don't define.
+ (struct elf_obj_tdata): Change strtab_ptr field to struct
+ bfd_strtab_hash.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Remove last
+ argument, output_names.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+ * libbfd-in.h (DEFAULT_STRING_SPACE_SIZE): Don't define.
+ (bfd_add_to_string_table): Don't declare.
+ * libbfd.h: Rebuild.
+ * libbfd.c (bfd_add_to_string_table): Remove.
+
+ * elfcode.h (elf_swap_shdr_in): Use bfd_section, not rawdata.
+ Clear contents field.
+ (bfd_section_from_shdr): In SHT_STRTAB case, check bfd_section,
+ not rawdata. Don't set rawdata if e_shstrndx. Use bfd_section
+ rather than rawdata in commented out code. In SHT_REL[A] case,
+ don't bother to check elf_section_data of section returned by
+ section_from_elf_index.
+ (elf_fake_sections): Set bfd_section, not rawdata. Don't set
+ size.
+ (elf_map_symbols): Don't set elf_num_section_syms. Don't create
+ section symbols that already exist.
+ (assign_file_position_for_section): Use bfd_section, not rawdata.
+ (section_from_elf_index): Just check bfd_section field.
+ (elf_section_from_bfd_section): Likewise.
+ (elf_debug_section): Don't print rawdata, contents, or size.
+ (elf_link_add_object_symbols): Don't error out if
+ section_from_elf_index returns NULL.
+ (elf_bfd_final_link): Check return value from
+ section_from_elf_index against NULL, not bfd_is_abs_section.
+ (elf_link_input_bfd): Don't check section_from_elf_index return
+ value.
+ * libelf.h (struct elf_obj_tdata): Remove num_section_syms field.
+ (elf_num_section_syms): Don't define.
+ * elf.c (elf_get_str_section): Store section contents in contents
+ field rather than rawdata field.
+ (elf_string_from_elf_section): Likewise.
+ (_bfd_elf_make_section_from_shdr): Store BFD section pointer in
+ bfd_section field rather than rawdata field.
+ * elf32-hppa.c (elf32_hppa_read_symext_info): Use bfd_section
+ rather than rawdata.
+ (elf32_hppa_size_stubs): Likewise.
+ (elf32_hppa_backend_symbol_table_processing): Don't set
+ symextn_hdr->size; just use sh_size.
+ * elf32-mips.c (mips_elf_final_write_processing): Use bfd_section
+ rathern than rawdata.
+ (mips_elf_section_from_shdr): Likewise.
+ (mips_elf_section_processing): Likewise.
+ (mips_elf_section_from_bfd_section): Remove rawdata check.
+
+ * srec.c (pass_over): Set the start address for S7, S8 or S9.
+
+Fri Oct 14 19:15:46 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * VERSION: Updated to 2.5.
+
+Fri Oct 14 11:07:50 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * bfd.c (bfd_scan_vma): Cast end to be non const before passing it
+ to strtoul.
+
+Thu Oct 13 14:40:41 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * bfd.c (bfd_scan_vma): Pass end argument on to strtoul.
+
+Wed Oct 12 16:46:43 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * opncls.c (bfd_realloc): Deleted, since it's broken and fixing it
+ would make it slow. Besides, it isn't used much.
+ * elfcode.h (elf_map_symbols): Always allocate new storage for the
+ symbol table.
+
+Wed Oct 12 11:54:37 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ecoff.c (ecoff_set_symbol_info): Mark local stProc, stLabel or
+ stabs symbols as BSF_DEBUGGING.
+
+ * rs6000-core.c (rs6000coff_core_file_matches_executable_p): Make
+ str1 and str2 const pointers.
+
+ * Makefile.in (INSTALL): Use top level install.sh script.
+ * config/README (INSTALL): Remove.
+ * config/delta88.mh (INSTALL): Remove.
+ * config/i386v4.mh (INSTALL): Remove.
+ * config/irix4.mh (INSTALL): Remove.
+ * config/irix5.mh (INSTALL): Remove.
+ * config/ncrt3000.mh (INSTALL): Remove.
+
+Tue Oct 11 13:57:56 1994 Eric Youngdale (eric@andante.aib.com)
+
+ * elf32-i386.c (elf_i386_check_relocs): Make sure that a symbol
+ with a global offset table entry or a procedure linkage table
+ entry is added to the dynamic symbol table.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): If a symbol has
+ already gotten a procedure linkage table entry, change the
+ definition to the PLT entry.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+
+Tue Oct 11 17:12:00 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * lynx-core.c (lynx_core_file_p): SPARC Lynx appears to start
+ dumping the .data section in a core file at a page boundary.
+
+Mon Oct 10 16:24:44 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * cofflink.c (_bfd_coff_final_link): Cast argument to bfd_h_put_32
+ to correct type.
+ (coff_read_string_table): Cast argument to bfd_h_get_32 to correct
+ type.
+ * elfcode.h (elf_link_output_extsym): Cast argument to
+ bfd_elf_hash to correct type.
+
+ * elf32-sparc.c (elf_sparc_howto_table): The PC10, PC22, and
+ WPLT30 relocations are PC-relative.
+
+Thu Oct 6 12:57:26 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * aoutx.h (adjust_o_magic): Correctly initialize vma if the vma of
+ the text section was user-defined.
+
+Wed Oct 5 14:42:12 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * archive.c (bfd_construct_extended_name_table): SVR4 uses slash
+ newline at the end of the file name, not just newline.
+
+Tue Oct 4 11:23:12 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_new_section_hook): Default section alignment
+ power to 4, rather than using align_power_min.
+
+ * coffcode.h (coff_new_section_hook): Don't use align_power_min;
+ use COFF_DEFAULT_SECTION_ALIGNMENT_POWER instead. Force the .stab
+ and .stabstr sections to be aligned to no more than 2. Remove
+ COFF_SPARC special cases.
+ * coff-a29k.c: Define COFF_DEFAULT_SECTION_ALIGNMENT_POWER.
+ * coff-apollo.c, coff-go32.c, coff-h8300.c: Likewise.
+ * coff-h8500.c, coff-i386.c, coff-i960.c, coff-m68k.c: Likewise.
+ * coff-m88k.c, coff-rs6000.c, coff-sh.c, coff-sparc.c: Likewise.
+ * coff-we32k.c, coff-z8k.c: Likewise.
+
+ * configure.in: Use ${config_shell} when running config.bfd.
+
+ * cofflink.c (coff_link_input_bfd): Don't try to convert a long
+ filename if the offset field is zero.
+
+ * elfcode.h (swap_out_syms): If the alignment of a common symbol
+ was not set, use a sensible default rather than zero.
+
+Mon Oct 3 16:04:29 1994 H.J. Lu (hjl@nynexst.com)
+
+ * opncls.c (bfd_close): Honor umask when setting execution bits.
+ (bfd_close_all_done): Likewise.
+
+Mon Oct 3 04:41:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-core.c (rs6000coff_core_p): Set SEC_HAS_CONTENTS flag
+ for .stack and .ldinfo sections. Cast coredata.c_tab to a
+ file_ptr to avoid warnings from gcc.
+
+Fri Sep 30 13:11:38 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * elfcode.h (elf_bfd_final_link): Remove assertion when a non
+ SEC_IN_MEMORY section is found in dynobj. This can happen when
+ linking PIC compiled code.
+
+Thu Sep 29 15:21:44 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * reloc.c (bfd_install_relocation): Change type of "data" to
+ bfd_byte *, to go along with yesterday's change.
+
+ * elf.c (bfd_elf_print_symbol): Moved here from elf_print_symbol
+ in elfcode.h. (case bfd_print_symbol_all): Print symbol's size
+ field, except for common symbols; print their alignment.
+ * elfcode.h (elf_print_symbol): Deleted.
+ * libelf.h (bfd_elf_print_symbol): Declare.
+ (bfd_elf{32,64}_print_symbol): Replace declarations with macros.
+
+ * syms.c (bfd_print_symbol_vandf): Show BSF_LOCAL and BSF_GLOBAL
+ in one column. Use the column freed up to show BSF_FUNCTION and
+ BSF_FILE.
+
+Thu Sep 29 12:29:01 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * syms.c (stt): Add .rdata and .rodata.
+
+Wed Sep 28 13:35:05 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * reloc.c (bfd_install_relocation): Cast data_start to bfd_byte *
+ before trying to add values to it.
+
+Tue Sep 27 16:47:58 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * elf32-hppa.c (elf32_hppa_backend_final_write_processing): Cast
+ return value from elf_sym_extra.
+ (elf32_hppa_build_stubs): Cast return value from bfd_zalloc.
+ (elf32_hppa_size_stubs): Cast return value from malloc.
+
+ * gen-aout.c (main): Declare and initialize "arch".
+
+ * cofflink.c (coff_link_add_symbols): Cast return value of
+ bfd_hash_allocate.
+
+ * riscix.c (riscix_callback): Use PARAMS macro in prototype.
+
+ * reloc.c (bfd_install_relocation): New function, mostly copied
+ from bfd_perform_relocation, adjusted for the assembler's needs.
+ * bfd-in2.h: Regenerated.
+
+Mon Sep 26 11:00:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (assign_file_positions_except_relocs): Align the
+ section VMA and the file position even if D_PAGED is not set.
+
+ * bfd-in.h (bfd_seek): Change declaration to not mark fp const.
+ * bfd-in2.h: Rebuild.
+ * libbfd.c (bfd_seek): Don't mark parameters const, to avoid
+ conflicts with declaration.
+
+Fri Sep 23 15:15:31 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (map_program_segments): Don't abort if we allocated
+ too much space for the program header, only if we allocated too
+ little.
+ (assign_file_positions_except_relocs): Similar change.
+
+Tue Sep 20 13:17:07 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * libaout.h: Fix comment.
+ * ns32knbsd.h: Changed M_NS32K_NETBSD to M_532_NETBSD to match
+ libaout.h.
+
+Tue Sep 20 15:23:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in: Rebuilt dependencies.
+ (BFD32_BACKENDS): Add sparcnetbsd.o.
+ (CFILES): Add ns32knetbsd.c and sparcnetbsd.c.
+ * targets.c: ns32knetbsd_vec was renamed to pc532netbsd_vec.
+
+ * coff-sh.c (rtype2howto): Remove; unused.
+ (coff_sh_relocate_section): Remove unused local variable rstat.
+ (reloc_processing): Comment out; unused.
+
+Fri Sep 16 12:12:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * aoutx.h (aout_link_write_other_symbol): If h->indx is -2, then
+ always write it out even if it would normally be stripped.
+ (aout_link_input_section_std): If we find a reloc against a
+ stripped global symbol, force it to be written out rather than
+ merely calling unattached_reloc.
+ (aout_link_input_section_ext): Likewise.
+ (aout_link_reloc_link_order): Likewise.
+
+Wed Sep 14 15:37:19 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.h (struct somdata): New field sorted_syms.
+ (obj_som_sorted_syms): Accessor macro.
+ * som.c (som_object_setup): Initialize sorted_syms to NULL.
+ (som_prep_for_fixups): Sort a copy of the BFD's symbol table;
+ store the sorted symbol table in sorted_syms.
+ (som_write_fixups): Initalize tmp_reloc to NULL to make GCC happy.
+ (som_begin_writing): Similarly for exec_header. Pass the sorted
+ symbol table to som_write_symbol_strings.
+ (som_build_and_write_symbol_table): Use the sorted symbols rather
+ than the canonical symbol table.
+
+ * som.h (som_symbol_type): Add "stringtab_offset" field.
+ * som.c (som_write_symbol_strings): Use "stringtab_offset"
+ rather than destroying the "name" field in the BFD symbol.
+ (som_build_and_write_symbol_table): Likewise.
+
+Wed Sep 14 15:06:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * aoutx.h (aout_link_write_symbols): Rename skip_indirect to
+ skip_next. If we find an N_WARNING symbol which has already been
+ written out, set skip_next.
+
+ * libecoff.h (struct ecoff_tdata): Add field find_buffer.
+ * ecoff.c: Include aout/stab_gnu.h.
+ (ecoff_find_nearest_line): Handle stabs debugging information.
+
+ * elfcode.h (elf_link_output_extsym): Keep a symbol marked as weak
+ even if it is referenced by another object.
+
+Tue Sep 13 17:57:00 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_fixup_formats): Case R_ENTRY (0xb3), set both
+ 'T' and 'U' to grab all the unwind information.
+ (som_set_reloc_info): Make 'U' unwind bits persist across
+ multiple SOM relocations. Set the addend field of an R_ENTRY
+ relocation to the value in 'T'; set the addend field on an
+ R_EXIT relocation to the value in 'U'.
+
+ * som.h (som_symbol_type): Delete unwind field.
+
+ * som.c (som_write_fixups): For R_ENTRY fixups, get 32bits of
+ unwind information from the addend field of the R_ENTRY, get the
+ other 32bits from the addend field of the R_EXIT.
+ (bfd_som_attach_unwind_info): Delete function and all references.
+
+ * som.h (som_symbol_type): Delete unused a.out-related fields.
+
+ * som.c (bfd_section_from_som_symbol): Use bfd_abs_section_ptr
+ instead of &bfd_abs_section.
+
+ * som.c (som_object_setup): Handle exec_entry and exec_flags being
+ switched in executables created by the OSF1 linker.
+ (som_write_fixups): Handle R_EXIT just like the R_{F,L,R}SEL
+ fixups. Support R_ALT_ENTRY (handle just like R_EXIT).
+
+Tue Sep 13 16:04:07 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * cofflink.c (coff_link_input_bfd): syment_base is unsigned
+ so can't compare -ve numbers with it.
+
+Mon Sep 12 20:31:17 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * configure.in (shcoff_vec): Use cofflink.o now.
+ * coff-sh.c: Rewritten to use new fast coff backend.
+
+Tue Sep 13 16:23:57 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * aoutx.h (NAME(aout,final_link)): Don't assume that all the input
+ files are a.out.
+
+Tue Sep 13 11:09:39 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * configure.host (sparc-*-netbsd): use sparcnbsd.
+ (ns32k-*-netbsd): use ns32knbsd.
+
+ * hosts/{nbsd,i386nbsd,ns32knbsd,sparcnbsd}.h: New files, NetBSD
+ host support.
+
+ * sparcnetbsd.c: New file, adds support for NetBSD/sparc.
+ * config/sparc-nbsd.mt: Likewise.
+
+ * netbsd.h: New file, definitions common to all netbsd ports.
+ * i386netbsd.c: Use it.
+ * ns32knetbsd.c: Use it.
+
+ * Makefile.in, configure.in, targets.c, config/i386-nbsd.mt,
+ config/ns32k-nbsd.mt: canonicalize netbsd targets to conform to
+ file/variable naming conventions.
+ * i386netbsd.c: New file, renamed from netbsd386.c.
+ * ns32knetbsd.c: New file, renamed from netbsd532.c.
+
+Mon Sep 12 21:56:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_reloc_skip): Correct off-by-one error for 4-byte
+ R_NO_RELOCATION fixups.
+ (bfd_section_from_som_symbol): Return the absolute section if the
+ symbol isn't contained in any section in the output file.
+ (som_slurp_symbol_table): ST_PRI_PROG and ST_SEC_PROG symbols are
+ not function symbols (they are magic code labels which *can* be the
+ targets of cross space branches). $START$ is not a section symbol.
+
+Mon Sep 12 11:43:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coff-alpha.c (ecoffalpha_little_vec): Add SEC_CODE and SEC_DATA
+ to section_flags.
+ * coff-mips.c (ecoff_little_vec, ecoff_big_vec): Likewise.
+
+ * elfcode.h (swap_out_syms): Set the type of an undefined symbol
+ to STT_FUNC if the BSF_FUNCTION flag is set.
+
+ * cofflink.c (coff_link_input_bfd): If r_symndx is -1, don't
+ change it.
+ (_bfd_coff_generic_relocate_section): If r_symndx is -1, it is an
+ absolute reloc. Don't dump core using r_symndx as an array index.
+ * cf-m68klynx.c (coff_bfd_link_add_symbols): Define.
+ (lynx_link_add_symbols): New static function (copy of function in
+ coff-i386.c).
+ (coff_m68k_lynxrtype_to_howto): sym argument may be NULL.
+ * coff-i386.c (coff_i386_rtype_to_howto): Likewise.
+ * coff-a29k.c (coff_a29k_relocate_section): Handle an r_symndx
+ value of -1, meaning an absolute reloc.
+
+ * ctor.c: Remove; obsolete.
+ * Makefile.in: Rebuild dependencies.
+ (BFD_LIBS): Remove ctor.o.
+ (CFILES): Remove ctor.c.
+ * libbfd.h: Rebuild.
+
+Mon Sep 12 01:58:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): If there was a link
+ error of some sort (for example, undefined symbols), then do not
+ apply any relocs, just notify the user of the errors.
+ (elf32_hppa_backend_begin_write_processing): Do not build a symbol
+ extension section for an executable (it's useless).
+ (elf32_hppa_link_output_symbol_hook): Do nothing if there was a
+ link error of some sort (for example, undefined symbols).
+ (elf32_hppa_read_symext_info): Kludge. Turn off SEC_HAS_CONTENTS
+ for all the input symbol extension sections to keep the generic
+ BFD code happy. Temporarily turn it on to read the contents of
+ the symbol extension section.
+
+Sun Sep 11 21:58:59 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/hppaosf.mh (RANLIB): Do not set.
+ * config/hppabsd.mh (RANLIB): Likewise.
+
+Sun Sep 11 22:50:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * cf-i386lynx.c: Remove #if 0 code.
+ (i386_lynxos_coff_object_p): Remove unused function.
+ (coff_bfd_link_add_symbols): Define.
+ (lynx_link_add_symbols): New static function.
+ * coffcode.h (coff_bfd_link_hash_table_create): If
+ coff_relocate_section is defined, only define this if not already
+ defined.
+ (coff_bfd_link_add_symbols, coff_bfd_final_link): Likewise.
+
+ * linker.c (_bfd_generic_final_link): Handle
+ bfd_indirect_link_order explicitly, rather than via
+ _bfd_default_link_order.
+ (set_symbol_from_hash): New static function, broken out of
+ _bfd_generic_link_write_global_symbol.
+ (_bfd_generic_link_write_global_symbol): Symbol setting code moved
+ to set_symbol_from_hash; call it.
+ (default_indirect_link_order): Add generic_linker argument.
+ Change all callers. If false, set the generic symbols based on
+ the hash table entries.
+
+Fri Sep 9 11:51:49 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coffgen.c (coff_get_symtab): Reindented. Removed commented out
+ call to bfd_constructor_entry.
+
+ Convert m68k COFF to use new COFF backend linker.
+ * coff-m68k.c (coff_relocate_section): Define.
+ * cf-m68klynx.c (coff_rtype_to_howto): Define.
+ (coff_m68k_lynx_rtype_to_howto): New static function.
+ * configure.in (m68kcoff_vec): Build cofflink.o.
+ (m68kcoffun_vec, m68klynx_coff_vec): Likewise.
+
+Thu Sep 8 16:20:38 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coff-h8300.c (h8300_reloc16_extra_cases, case RELBYTE): Flag
+ overflows correctly.
+
+Wed Sep 7 19:01:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * libelf.h (struct elf_backend_data): Change second argument of
+ elf_backend_final_write_processing hook to boolean.
+ (struct elf_obj_tdata): Add linker field.
+ * elfcode.h (NAME(bfd_elf,write_object_contents)): Pass value of
+ tdata linker field to final_write_processing, rather than NULL.
+ (elf_bfd_final_link): Don't call final_write_processing hook. Set
+ tdata linker field to true.
+ * elf32-mips.c (mips_elf_final_write_processing): Change type of
+ second argument to boolean.
+ * elf32-hppa.c (elf32_hppa_backend_final_write_processing):
+ Likewise.
+
+ * coff-go32.c (RTYPE2HOWTO): Fully parenthesize arguments.
+ * coff-i960.c (RTYPE2HOWTO): Likewise.
+ * coff-m88k.c (RTYPE2HOWTO): Likewise.
+ * coff-we32k.c (RTYPE2HOWTO): Likewise.
+
+ Make i386 COFF use new COFF backend linker.
+ * coff-i386.c (RTYPE2HOWTO): Fully parenthesize arguments.
+ (coff_relocate_section): Define.
+ (coff_i386_rtype_to_howto): New function.
+ * configure.in (i386coff_vec): Use cofflink.o.
+ (i386lynx_coff_vec): Likewise.
+
+ * coffcode.h (bfd_coff_backend_data): Add new field
+ _bfd_coff_rtype_to_howto.
+ (bfd_coff_rtype_to_howto): Define.
+ (coff_rtype_to_howto): Define to use RTYPE2HOWTO, if not already
+ defined.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * cofflink.c (_bfd_coff_final_link): Allocate section_count + 1
+ section_info structures, since the target_index is 1 based.
+ (coff_link_input_bfd): Set *secpp to bfd_com_section_ptr for a
+ common symbol. Adjust rel_hash by the output reloc count.
+ (_bfd_coff_generic_relocate_section): New function.
+ * libcoff-in.h (_bfd_coff_generic_relocate_section): Declare.
+ * libcoff.h: Rebuild.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize new field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+
+Tue Sep 6 23:28:52 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_derive_misc_symbol_info): Treat undefined code
+ symbols and undefined symbols which no type in the same manner
+ if the associated BFD symbol has BSF_FUNCTION set. For a defined
+ symbol which no type, select a SOM type based on the flags of the
+ section containing the symbol.
+ (som_slurp_symbol_type): Set BSF_FUNCTION for undefined ST_STUB
+ or ST_CODE symbols (importing a non-function code symbol is
+ meaningless in SOM).
+ (som_set_reloc_info): Don't set "offset" to the section's vma; it
+ should always start at zero.
+
+Tue Sep 6 14:51:11 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ Add new style linker support to COFF backend. a29k only for now.
+ * cofflink.c: New file.
+ * libcoff-in.h: Include bfdlink.h.
+ (obj_coff_external_syms, obj_coff_strings): Define accessor macro.
+ (obj_coff_sym_hashes): Define accessor macro.
+ (struct coff_tdata): Add fields external_syms, strings, and
+ sym_hashes.
+ (struct coff_link_hash_entry): Define.
+ (struct coff_link_hash_table): Define.
+ (coff_link_hash_lookup, coff_link_hash_traverse): Define.
+ (coff_hash_table): Define.
+ (_bfd_coff_link_hash_table_create): Declare.
+ (_bfd_coff_link_add_symbols, _bfd_coff_final_link): Declare.
+ * coffcode.h (bfd_coff_backend_data): Add fields _bfd_relsz,
+ _bfd_coff_swap_reloc_in, _bfd_coff_sym_is_global,
+ _bfd_coff_compute_section_file_positions,
+ _bfd_coff_relocate_section.
+ (bfd_coff_relsz, bfd_coff_swap_reloc_in): Define.
+ (bfd_coff_sym_is_global): Define.
+ (bfd_coff_compute_section_file_positions): Define.
+ (bfd_coff_relocate_section): Define.
+ (coff_mkobject_hook): Initialize obj_raw_syment_count and
+ obj_conv_table_size.
+ (coff_compute_section_file_positions): Set target_index of all
+ sections. Set output_has_begun field.
+ (coff_write_object_contents): Don't set target_index; now done by
+ coff_compute_section_file_positions. Remove obsolete handling of
+ scn_base and data_base. Don't bother to check that target_index
+ is positive, since it always is. Remove use of pad, which is
+ always zero. Check obj_raw_syment_count, not bfd_get_symcount,
+ for the number of symbols, but only write them out if
+ bfd_get_symcount is non-zero. Don't check obj_raw_syment_count
+ until after coff_write_symbols is called.
+ (coff_slurp_symbol_table): Use obj_raw_syment_count, not
+ bfd_get_symcount for the number of symbols. Don't set
+ obj_conv_table_size.
+ (coff_sym_is_global): New static function or macro.
+ (coff_slurp_reloc_table): Call coff_swap_reloc_in, not
+ bfd_swap_reloc_in.
+ (coff_bfd_link_hash_table_create): If coff_relocate_section is
+ defined, define as _bfd_coff_link_hash_table_create.
+ (coff_bfd_link_add_symbols): Similar change.
+ (coff_bfd_final_link): Similar change.
+ (coff_relocate_section): Define as NULL if not defined.
+ (bfd_coff_std_swap_table): Initialize new fields.
+ * coffgen.c (coff_real_object_p): Don't set obj_raw_syment_count
+ and obj_conv_table_size here.
+ (coff_count_linenumbers): Reindent. If bfd_get_symcount is zero,
+ add up the line numbers from the sections.
+ (coff_write_symbols): Set obj_raw_syment_count, not
+ bfd_get_symcount.
+ (coff_pointerize_aux): Don't pointerize a nonpositive x_endndx
+ field.
+ (coff_get_normalized_symtab): Use obj_raw_syment_count, not
+ bfd_get_symcount.
+ (coff_print_symbol): If auxp->fix_end, print x_endndx value.
+ * coffswap.h (coff_swap_reloc_in): Rename from bfd_swap_reloc_in.
+ Reindent. Change argument type to PTR.
+ * coff-a29k.c (coff_a29k_relocate_section): New static function.
+ (coff_relocate_section): Define.
+ * configure.in (a29kcoff_big_vec): Compile cofflink.o.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize new fields.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+ * libcoff.h: Rebuilt.
+ * Makefile.in: Rebuilt dependencies.
+ (BFD32_BACKENDS): Add cofflink.o.
+ (CFILES): Add cofflink.c.
+
+Tue Sep 6 14:00:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * coffgen.c (coff_print_symbol, case bfd_symbol_print_all): Check
+ for section symbol, and print its aux fields with appropriate
+ labels.
+
+ * Makefile.in (ALL_MACHINES): Added cpu-arm.o.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * aoutx.h (NAME(aout,machine_type)): Recognize the ARM processor.
+ * archures.c, config.bfd, configure.host, libaout.h, reloc.c,
+ targets.c: Add support for the ARM.
+ * cpu-arm.c, riscix.c, config/riscix.mh, config/riscix.mt: New files.
+
+ * aoutx.h (add_to_stringtable): Check that str isn't a NULL pointer.
+
+Fri Sep 2 14:10:30 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * reloc.c (enum bfd_reloc_code_real): Rewrote definition to use
+ new "chew" commands for simultaneous definition of enumerator and
+ enumerator name table.
+ (bfd_get_reloc_code_name): New function, for retrieving a symbolic
+ name associated with an enumerator.
+ * libbfd.h, bfd-in2.h: Regenerated.
+
+Tue Aug 30 21:24:54 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_write_fixups, case R_ENTRY): Handle case where no
+ unwind descriptor information is available.
+
+Tue Aug 30 11:43:30 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Add soname
+ argument, and use it to set DT_SONAME dynamic entry.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update prototype.
+ (bfd_elf64_size_dynamic_sections): Update prototype.
+ * bfd-in2.h: Rebuilt.
+
+Fri Aug 26 15:47:57 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coffgen.c (coff_real_object_p): Set obj_raw_syment_count.
+ (coff_get_normalized_symtab): Verify obj_raw_syment_count, rather
+ than setting it.
+
+Thu Aug 25 10:44:53 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * archive.c (bsd_write_armap): Remove host dependencies.
+
+ * aoutx.h (add_to_stringtab): Check for _bfd_stringtab_add error
+ before adding BYTES_IN_WORD.
+
+ * coffgen.c (coff_find_nearest_line): Look for the best C_FILE,
+ not merely the first.
+
+ * coffgen.c (coff_write_alien_symbol): If we are not using the
+ symbol, clear the name so that it is not put in the string table.
+ From Antti.Miettinen@ntc.nokia.com.
+
+Wed Aug 24 11:49:19 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coffgen.c (coff_print_symbol): Cast pointer different to long
+ and use %ld to print it.
+ * osf-core.c (osf_core_core_file_p): Remove unused variable
+ dseccnt.
+ * ecoffswap.h (ecoff_swap_ext_out): If ECOFF_64, clear remaining
+ bytes in bits2.
+
+ * configure.host, config.bfd: Change i[34]86 to i[345]86.
+ * coffgen.c (coff_real_object_p): Set obj_conv_table_size here,
+ rather than waiting until coff_slurp_symbol_table.
+ (coff_write_alien_symbol): Just ignore BSF_DEBUGGING symbols.
+ From Antti.Miettinen@ntc.nokia.com.
+
+ * section.c (bfd_make_section_anyway): Fix failure check of
+ bfd_make_empty_symbol. From Antti.Miettinen@ntc.nokia.com.
+
+ * aoutx.h (translate_to_native_sym_flags): Use the output_section
+ (and output_offset) if there is one.
+
+ * aoutx.h (aout_link_check_archive_element): Discard the symbols
+ if the archive element was not needed.
+
+ * aoutx.h (aout_get_external_symbols): Ensure that a zero string
+ index yields an empty string.
+ (aout_link_write_symbols): If info->keep_memory is false, use name
+ from original hash table entry, not from entry in *sym_hash.
+
+ * aoutx.h (struct aout_final_link_info): Add fields contents,
+ relocs, symbol_map and output_syms.
+ (NAME(aout,final_link)): Work out the largest section size, reloc
+ size, and number of symbols. Use them to preallocate buffers that
+ are large enough for all cases.
+ (aout_link_input_bfd): Use preallocated symbol_map.
+ (aout_link_write_symbols): Remove symbol_map argument; use
+ preallocated symbol_map instead. Change all callers. Use
+ preallocated output_syms.
+ (aout_link_input_section): Remove symbol_map argument. Change all
+ callers. Use preallocated contents and relocs.
+ (aout_link_input_section_std): Remove symbol_map argument; use
+ preallocated symbol_map instead. Change all callers.
+ (aout_link_input_section_ext): Likewise.
+
+Tue Aug 23 10:51:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * archive.c (_bfd_write_archive_contents): Don't update the
+ symbol map timestamp if there is no symbol map. From
+ schwab@issan.informatik.uni-dortmund.de (Andreas Schwab).
+
+Mon Aug 22 12:26:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * targets.c (BFD_JUMP_TABLE_ARCHIVE): Add _update_armap_timestamp.
+ (bfd_target): Add field _bfd_update_armap_timestamp.
+ * bfd.c (bfd_update_armap_timestamp): Define.
+ * bfd-in2.h: Rebuilt.
+ * libbfd-in.h (_bfd_noarchive_update_armap_timestamp): Define.
+ (_bfd_archive_bsd_update_armap_timestamp): Declare.
+ (_bfd_archive_coff_update_armap_timestamp): Define.
+ * libbfd.h: Rebuilt.
+ * archive.c (_bfd_write_archive_contents): Call
+ bfd_update_armap_timestamp instead of checking for a BSD archive
+ and calling bsd_update_armap_timestamp.
+ (_bfd_archive_bsd_update_armap_timestamp): Rename from
+ _bsd_update_armap_timestamp. Don't assume that armap_datepos is
+ already set.
+ * aout-target.h (MY_update_armap_timestamp): Define if not already
+ defined.
+ * coff-rs6000.c (rs6000coff_update_armap_timestamp): Define.
+ * ieee.c (ieee_update_armap_timestamp): Define.
+ * libecoff.h (_bfd_ecoff_update_armap_timestamp): Define.
+ * oasys.c (oasys_update_armap_timestamp): Define.
+ * som.c (som_update_armap_timestamp): Define.
+
+ * hash.c: Copy string hash functions from aoutx.h.
+ * aoutx.h: String hash functions moved to hash.c. Retain
+ simplified versions of add_to_stringtab and emit_stringtab.
+ Change all callers to use new function and structure names.
+ * libbfd-in.h (_bfd_stringtab_init, _bfd_stringtab_free): Declare.
+ (_bfd_stringtab_size, _bfd_stringtab_add): Declare.
+ (_bfd_stringtab_emit): Declare.
+ * libbfd.h: Rebuilt.
+
+Mon Aug 22 10:49:37 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * i386linux.c (linux_add_one_symbol): Create a fixup for any
+ defined absolute symbol, not just GOT or PLT symbols.
+ (linux_tally_symbols): Correct handling of references to defined
+ symbols.
+
+Thu Aug 18 16:29:57 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ Get ld -x -r to handle a.out set symbols correctly.
+ * aoutx.h (adjust_o_magic): If the .bss VMA was set outside of
+ BFD, pad the .data section up to the VMA of the .bss section.
+ (aout_link_add_symbols): If a set symbol does not get modified,
+ treat it as a local symbol.
+ (aout_link_write_symbols): Set the value of set symbols
+ correctly. Don't discard set symbols even if discarding local
+ symbols.
+ (aout_link_write_other_symbol): Don't abort on bfd_link_hash_new,
+ since it can now happen for set symbols.
+
+ * elfcode.h (elf_fake_sections): Just check for ".rela" and
+ ".rel", not ".rela." and ".rel."; make this work by checking
+ use_rela_p.
+ * elf32-i386.c (elf_i386_check_relocs): Just check for ".rel", not
+ ".rel."
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Just check for
+ ".rela", not ".rela."
+ (elf32_sparc_size_dynamic_sections): Likewise.
+ (elf32_sparc_relocate_section): Likewise.
+
+Wed Aug 17 16:54:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * linker.c (_bfd_generic_link_add_archive_symbols): Initialize
+ PASS to the old value + 1.
+
+ * coffgen.c (coff_get_normalized_symtab): If a C_FILE symbol has
+ no aux entries, use the symbol name as the file name.
+ (coff_find_nearest_line): Look for the right C_FILE symbol, rather
+ than always using the first one. If there is a debugging symbol
+ after a function symbol, skip it. Add the section VMA to the line
+ offset, since it was subtracted out in coff_slurp_line_table.
+
+Tue Aug 16 16:53:00 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_prep_headers): If writing some form of an executable,
+ allocate and attach an exec header to the BFD private data.
+ (som_begin_writing): Don't fill fields of the exec header based
+ on BFD private data here (like the exec flags). Do not write
+ the exec header here.
+ (som_write_headers): Instead do it here.
+ * som.h (struct somdata): New field "exec_hdr" for the executable
+ file header.
+ (obj_som_exec_hdr): New accessor macro.
+
+Tue Aug 16 00:12:31 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * i386linux.c (linux_link_create_dynamic_sections): Create section
+ named .linux-dynamic, not .dynamic.
+ (linux_add_one_symbol): Use .linux-dynamic, not .dynamic.
+ (bfd_linux_size_dynamic_sections): Likewise.
+ (linux_finish_dynamic_link): Likewise.
+
+Mon Aug 15 12:16:56 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coffgen.c (STRING_SIZE_SIZE): Define.
+ (coff_fix_symbol_name): Use STRING_SIZE_SIZE, not 4.
+ (coff_write_symbols, build_string_table): Likewise.
+ (coff_get_normalized_symtab): Likewise.
+
+ * libcoff-in.h (obj_symbol_slew): Don't define.
+ (struct coff_tdata): Remove unused fields index_slew, raw_linenos,
+ and flags.
+ * libcoff.h: Rebuilt.
+ * coffcode.h (coff_mkobject): Don't initialize raw_linenos.
+ (coff_mkobject_hook): Don't initialize flags.
+
+ * aout-target.h (MY_zmagic_contiguous): Define as 0 if not already
+ defined.
+ (MY(backend_data)): Use MY_zmagic_contiguous, not hardcoded 0.
+ * i386linux.c (MY_zmagic_contiguous): Define.
+
+ * elfcode.h (bfd_section_from_shdr): If a SHT_SYMTAB section in a
+ shared object has SHF_ALLOC set, create a BFD section for it.
+ (elf_section_from_bfd_section): There may be a BFD section for a
+ SHT_SYMTAB section.
+
+ * coffcode.h (styp_to_sec_flags): Add name argument. If no flags
+ are recognized, chose section flags based on the name.
+ (bfd_coff_backend_data): _bfd_styp_to_sec_flags_hook field: Add
+ name argument.
+ (bfd_coff_styp_to_sec_flags_hook): Add name argument.
+ (coff_compute_section_file_positions): Don't adjust the section
+ position by COFF_PAGE_SIZE unless SEC_ALLOC is set.
+ * libcoff.h: Rebuilt.
+ * coffgen.c (make_a_section_from_file): Pass section name to
+ bfd_coff_styp_to_sec_flags_hook.
+ * ecoff.c (_bfd_ecoff_styp_to_sec_flags): Add unused name
+ argument.
+ * libecoff.h (_bfd_ecoff_styp_to_sec_flags): Add name argument to
+ prototype.
+
+Fri Aug 12 11:22:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (section_from_elf_index): Correct check for invalid
+ section index.
+
+ * elfcode.h (elf_link_add_object_symbols): If there is no symbol
+ table, try using the dynamic symbol table. From Eric Youngdale
+ <ericy@cais.cais.com>.
+
+ * configure.host (sparc-*-solaris2*): Use solaris2, not sysv4.
+ The linker depends upon configuring for solaris2.
+ * hosts/solaris2.h: New file; include hosts/sysv4.h.
+ * config/solaris2.mh: New file; copy of config/sysv4.mh.
+
+Wed Aug 10 13:09:38 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * aoutx.h (adjust_z_magic): Make sure data section is padded to
+ page boundary when the VMA is set by the calling program. From
+ Eric Youngdale <ericy@cais.cais.com>.
+
+Mon Aug 8 17:18:49 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Update to ns32k support, from Ian Dall (dall@hfrd.dsto.gov.au).
+ * aout-ns32k.c: Add declarations that were in aout-ns32k.h, change
+ declarations to traditional form.
+ (MY_reloc_howto, MY_put_reloc): Change from macro to function.
+ (ns32k_relocate_contents): New function.
+ * aout-ns32k.h: Remove.
+ * cpu-ns32k.c: Add declarations that were in aout-ns32k.h, change
+ declarations to traditional form.
+ (ns32k_final_link_relocate): Call ns32k_relocate_contents.
+ * netbsd532.c: Reformat to standards, add copyright notice.
+ (ARCH): Don't define.
+ (aout-ns32k.h): Don't include.
+ * pc532-mach.c: Ditto.
+
+Mon Aug 8 17:55:52 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coff-i960.c (coff_i960_relocate): Don't try to convert relocs
+ against common symbols.
+
+Sat Aug 6 22:27:30 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * irix-core.c (irix_core_core_file_p): Ignore sections that
+ are not contained in the core file.
+
+Thu Aug 4 11:32:23 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coff-m68k.c (m68k_reloc_type_lookup): New function.
+ (coff_bfd_reloc_type_lookup): Define.
+ * cf-m68klynx.c (_bfd_m68kcoff_reloc_type_lookup): Define.
+
+ * elfcode.h (elf_bfd_final_link): Force the vma of sections which
+ do not have SEC_ALLOC set to be 0. This is needed to handle
+ relocs against debugging sections.
+
+Wed Aug 3 16:45:41 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coff-i960.c (coff_i960_relocate): Rewrote to change relocs
+ against locally defined symbols into relocs against section
+ symbols, for VxWorks 5.1.
+
+Wed Aug 3 10:34:37 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * i386linux.c (linux_add_one_symbol): Only handle
+ SHARABLE_CONFLICTS specially if BSF_CONSTRUCTOR is set. Set hashp
+ for a GOT or PLT symbol. Set jump field of fixup for a PLT symbol.
+ (linux_tally_symbols): Check section of real symbol. When looking
+ for a builtin fixup, check builtin and jump flags. Create no more
+ than one fixup, and always create one if the real symbol is in the
+ absolute section. Only strip absolute symbols.
+
+Wed Aug 3 05:08:24 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * coffcode.h (coff_write_object_contents): set internal_a.magic to
+ LYNXCOFFMAGIC whenever 68k, SPARC or i386 LynxOS
+ (yes, they have the same magic number!)
+
+Tue Aug 2 10:43:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * hp300hpux.c (BMAGIC): Define as HPUX_DOT_O_MAGIC, to make test
+ in aoutx.h work correctly.
+
+ * coff-i960.c (coff_i960_relocate): New function.
+ (howto_rellong, howto_iprmed): Use it as special_function.
+
+ * libbfd-in.h: Move declarations of bfd_read, bfd_write, bfd_seek,
+ bfd_tell, bfd_flush, and bfd_stat from here...
+ * bfd-in.h: ...to here, to make them visible to programs which
+ know more about the object file format than BFD does.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+
+Mon Aug 1 17:55:53 1994 Fred Fish (fnf@cygnus.com)
+
+ * ptrace-core.c (ptrace_unix_core_file_p): Convert zalloc usage
+ to bfd_zalloc.
+
+Mon Aug 1 12:04:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elf64-sparc.c (ELF_MAXPAGESIZE): Define.
+
+ ELF linker patches from Eric Youngdale <ericy@cais.cais.com>.
+ * elfcode.h (elf_link_create_dynamic_sections): Set type of
+ _DYNAMIC to STT_OBJECT.
+ (NAME(bfd_elf,record_link_assignment)): Always create hash table
+ entry. Set type to STT_OBJECT.
+ (elf_link_output_extsym): Don't set type of weak defined symbol to
+ STB_WEAK if symbol was referenced.
+ (map_program_segments): Check DYNAMIC as well as EXEC_P.
+ (assign_file_positions_except_relocs): Likewise.
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Set type of
+ _GLOBAL_OFFSET_TABLE to STT_OBJECT.
+ (elf_i386_check_relocs): Ignore local PLT32 relocs.
+ (elf_i386_relocate_section): Treat local PLT32 relocs as PC32.
+
+ * elfcode.h (elf_adjust_dynamic_symbol): Correct weak symbol
+ handling again.
+
+ * elfcode.h (elf_slurp_reloc_table): Don't try to read the relocs
+ if there aren't any.
+
+ * configure.host (sparc-*-solaris2*): Use sysv4, not solaris2.
+ * hosts/solaris2.h: Remove.
+ * config/solaris2.mh: Remove.
+
+Sun Jul 31 14:27:04 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c, elf32-hppa.h: Update comment reflecting which
+ HPPA ELF spec the code implements.
+
+Tue Jul 26 17:38:01 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * cpu-i960.c (MAX_ARCH): New macro.
+ (compatible): Use it in computing array bounds. Put comma after
+ last entry in array, for regularity.
+ (arch_info_struct): Adjust spacing for easier reading.
+
+ * coff-i960.c (howto_rellong, howto_iprmed, howto_optcall): Use
+ HOWTO macro.
+
+ * cpu-i960.c (JX): Define as bfd_mach_i960_jx.
+ (scan_960_mach): Recognize jx machine.
+ (MAX_ARCH): Define to be JX.
+ (compatible): Add JX row to array.
+ (arch_info_struct): Add JX entry.
+
+ * archures.c (bfd_mach_i960_jx): New macro.
+ * bfd-in2.h: Regenerated.
+
+ * coffcode.h (coff_set_arch_mach_hook): For F_I960JX, set machine
+ to bfd_mach_i960_jx.
+ (coff_set_flags): For bfd_mach_i960_jx, set F_I960JX.
+
+Tue Jul 26 11:04:00 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (elf_adjust_dynamic_symbol): When handling a weak
+ symbol, correct check to see whether the equivalent normal symbol
+ was referenced.
+
+ Add support for creating shared libraries under i386 ELF and SPARC
+ ELF. Based on patches by Eric Youngdale <ericy@cais.cais.com>.
+ * libelf.h (struct elf_link_hash_entry): Remove copy_offset field.
+ Add got_offset and plt_offset fields.
+ (ELF_LINK_HASH_REF_DYNAMIC_MULTIPLE): Don't define.
+ (ELF_LINK_HASH_DEF_DYNAMIC_MULTIPLE): Don't define.
+ (ELF_LINK_HASH_NEEDS_COPY): Define.
+ (struct elf_backend_data): Add check_relocs field.
+ (struct bfd_elf_section_data): Change relocs from PTR to
+ Elf_Internal_Rela *.
+ (struct elf_obj_tdata): Add local_got_offsets field.
+ (elf_local_got_offsets): Define accessor macro.
+ (bfd_elf32_link_create_dynamic_sections): Declare.
+ (bfd_elf32_link_record_dynamic_symbol): Declare.
+ (bfd_elf64_link_create_dynamic_sections): Declare.
+ (bfd_elf64_link_record_dynamic_symbol): Declare.
+ * elfcode.h (elf_slurp_reloc_table): Don't use the section data
+ relocs field.
+ (elf_link_record_dynamic_symbol): Make globally visible. Use
+ macro to rename to NAME(bfd_elf,link_record_dynamic_symbol).
+ (elf_link_add_object_symbols): If creating a shared library, put
+ make all local symbols dynamic. Don't bother with the
+ DYNAMIC_MULTIPLE flags. Call the check_relocs backend function if
+ it is defined.
+ (elf_link_create_dynamic_sections): Make globally visible. Use
+ macro to rename to NAME(bfd_elf,link_create_dynamic_sections). If
+ creating a shared library, make sure that _DYNAMIC is added as a
+ dynamic symbol.
+ (elf_link_read_relocs): New function.
+ (NAME(bfd_elf,record_link_assignment)): If creating a shared
+ library, always create symbols, and always make them dynamic.
+ (elf_bfd_final_link): Permit creation of shared libraries.
+ (elf_link_input_bfd): Use elf_link_read_relocs to get the relocs.
+ * elf.c (_bfd_elf_link_hash_newfunc): Don't initialize
+ copy_offset. Initialize got_offset and plt_offset.
+ * elf32-target.h (elf_backend_check_relocs): Define as 0 if not
+ defined.
+ (elf32_bed): Initialize check_relocs field.
+ * elf64-target.h (elf_backend_check_relocs): Define as 0 if not
+ defined.
+ (elf64_bed): Initialize check_relocs field.
+ * elf32-i386.c (elf_howto_table): Change R_386_PLT32 and
+ R_386_GOTPC to be pc_relative and pcrel_offset.
+ (elf_i386_pic_plt0_entry): Define.
+ (elf_i386_pic_plt_entry): Define.
+ (elf_i386_create_dynamic_sections): Create a .got.plt section, and
+ define _GLOBAL_OFFSET_TABLE_ at the start of it. If creating a
+ shared library, make sure that _GLOBAL_OFFSET_TABLE_ is added as a
+ dynamic symbol. Don't create .rel.bss if creating a shared
+ library.
+ (elf_i386_check_relocs): New function.
+ (elf_i386_adjust_dynamic_symbol): Don't make a PLT entry if the
+ symbol already has one. When making a PLT entry, set plt_offset.
+ Don't create a copy reloc when creating a shared library. Don't
+ set copy_offset, just set ELF_LINK_HASH_NEEDS_COPY.
+ (elf_i386_allocate_dynamic_section): Remove.
+ (elf_i386_size_dynamic_sections): Look through all the sections
+ rather than assuming we know their names. Remove any empty reloc
+ or plt sections. Only add a DT_DEBUG entry if not creating a
+ shared library. Only add a DT_PLTGOT entry if there is a PLT.
+ Add a DT_TEXTREL entry if required.
+ (elf_i386_relocate_section): Permit undefined symbols when
+ creating a shared library. Handle the special relocation types
+ specially.
+ (elf_i386_finish_dynamic_symbol): Create a PLT entry if plt_offset
+ is set. If creating a shared library, produce a PIC PLT entry.
+ Only mark a PLT symbol as undefined if it was not defined by a
+ regular object file. Create a GOT entry if got_offset is set.
+ Create a copy reloc if ELF_LINK_HASH_NEEDS_COPY is set.
+ (elf_i386_finish_dynamic_sections): Change the handling of
+ DT_RELSZ to simply subtract out the size of .rel.plt. If creating
+ a shared library, produce PIC PLT code.
+ (elf_backend_check_relocs): Define.
+ * elf32-sparc.c (elf_sparc_howto_table): Change R_SPARC_GOT10,
+ R_SPARC_GOT22, and R_SPARC_PC10 to not warn about reloc overflow.
+ (elf32_sparc_create_dynamic_sections): If creating a shared
+ library, make sure that _GLOBAL_OFFSET_TABLE_ is added as a
+ dynamic symbol, and set the type to STT_OBJECT. Likewise for
+ _PROCEDURE_LINKAGE_TABLE_. Don't create .rel.bss if creating a
+ shared library.
+ (elf32_sparc_check_relocs): New function.
+ (elf32_sparc_adjust_dynamic_symbol): Don't make a PLT entry if the
+ symbol already has one. When making a PLT entry, set plt_offset.
+ Don't create a copy reloc when creating a shared library. Don't
+ set copy_offset, just set ELF_LINK_HASH_NEEDS_COPY.
+ (elf32_sparc_allocate_dynamic_section): Remove.
+ (elf32_sparc_size_dynamic_sections): Look through all the sections
+ rather than assuming we know their names. Only add a DT_DEBUG
+ entry if not creating a shared library. Add a DT_TEXTREL entry if
+ required.
+ (elf32_sparc_relocate_section): Permit undefined symbols when
+ creating a shared library. Handle the special relocation types
+ specially.
+ (elf32_sparc_finish_dynamic_symbol): Create a PLT entry if plt_offset
+ is set. Only mark a PLT symbol as undefined if it was not defined
+ by a regular object file. Create a GOT entry if got_offset is
+ set. Create a copy reloc if ELF_LINK_HASH_NEEDS_COPY is set.
+ (elf32_sparc_finish_dynamic_sections): Store dynobj in a local
+ variable.
+ (elf_backend_check_relocs): Define.
+
+Mon Jul 25 12:21:07 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * configure.in (pc532mach_vec): Change to pc532machaout_vec.
+ * config.bfd (ns32k-*-netbsd*): Use ns32k-nbsd as bfd_name.
+ * Makefile.in (ALL_MACHINES): Add cpu-ns32k.o.
+ (BFD32_BACKENDS): Add aout-ns32k.o, netbsd532.o, m88kmach3.o,
+ pc532-mach.o.
+ * targets.c (pc532machaout_vec): Use instead of pc532mach_vec.
+ * config/pc532-mach.mt (DEFAULT_VECTOR): Ditto.
+ (SELECT_VECS): Remove.
+ * config/ns32k-nbsd.mt: New file, was ns32k-netbsd.mt.
+ * config/ns32k-netbsd.mt: Remove, name too long.
+
+Fri Jul 22 11:07:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * linker.c (generic_link_check_archive_element): When changing a
+ symbol to common, set the alignment.
+ (_bfd_generic_link_add_one_symbol): When creating a common symbol,
+ set the alignment.
+ * aoutx.h (aout_link_check_ar_symbols): When changing a symbol to
+ common, set the alignment.
+ (aout_link_add_symbols): Restrict the alignment of a common symbol
+ to the alignment power given by the architecture.
+ * libelf.h (struct elf_link_hash_entry): Remove align field. Add
+ copy_offset field.
+ * elfcode.h (elf_link_add_object_symbols): Store alignment in
+ new bfd_link_hash_entry field, not in elf_link_hash_entry field.
+ (elf_link_output_extsym): Similar change when getting alignment.
+ * elf.c (_bfd_elf_link_hash_newfunc): Don't initialize align. Do
+ initialize copy_offset.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Use copy_offset
+ field rather than align field. Get alignment using bfd_log2
+ rather than switch.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Use copy_offset,
+ not align.
+ * elf32-sparc.c (elf32_sparc_finish_dynamic_symbol): Likewise.
+
+ * aoutx.h (NAME(aout,some_aout_object_p)): Just check
+ STAT_FOR_EXEC, don't check MACH.
+ * m88kmach3.c (MACH): Don't define.
+ * config/i386-mach3.mt (TDEFINES): Define STAT_FOR_EXEC.
+ * config/m88k-mach3.mt (TDEFINES): Likewise.
+ * config/mips-mach3.mt (TDEFINES): Likewise.
+
+Thu Jul 21 17:24:31 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * i386mach3.c: Reverted to version from before Jul 5 1994 changes.
+
+Thu Jul 21 12:26:01 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * reloc.c (struct reloc_howto_struct): Remove special_function1.
+ It's the wrong way to do things.
+ (HOWTO): Change accordingly.
+ (HOWTO2): Remove.
+ (_bfd_final_link_relocate): Remove references to
+ special_function1.
+ * bfd-in2.h: Rebuilt.
+ * aoutx.h (aout_link_input_section_std): Remove references to
+ special_function1.
+ (aout_link_reloc_link_order): Likewise.
+
+Wed Jul 20 15:46:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Add rpath
+ argument. If it is not NULL, use it to set DT_RPATH.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update prototype.
+ (bfd_elf64_size_dynamic_sections): Likewise.
+ * bfd-in2.h: Rebuilt.
+
+Sat Jul 16 21:10:39 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (elf_get_dynamic_symtab_upper_bound): If there is no
+ dynamic symtab, return error.
+
+ * libelf.h (ELF_LINK_HASH_DEFINED_WEAK): Define.
+ * elfcode.h (elf_link_add_object_symbols): If symbol is defined as
+ weak, set ELF_LINK_HASH_DEFINED_WEAK.
+ (elf_link_output_extsym): If symbol is defined as weak, mark it
+ STB_WEAK.
+
+ * libelf.h (struct bfd_elf_section_data): Add relocs field.
+ (shdr_name): Remove; unused.
+ * elfcode.h (elf_slurp_reloc_table): Rewrote to handle both REL
+ and RELA relocs. Free up the unswapped relocs. Permit the relocs
+ to be cached in the section_data. Correct the reloc address.
+ (elf_slurp_reloca_table): Remove.
+ (elf_canonicalize_reloc): Rewrote.
+ (elf_link_input_bfd): Permit the relocs to be cached in the
+ section data.
+
+Sat Jul 16 13:55:38 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config.bfd (m88*-harris-cxux*): Recognize.
+ * hosts/harris.h (POSIX_UTIME, HAVE_PROCFS): Define.
+
+ * configure.host (m68*-atari-sysv4*): New host.
+ (m68*-cbm-sysv4*): Use m68kv4 instead of amix.
+ * hosts/amix.h: Remove.
+ * hosts/m68kv4.h: New file, was amix.h.
+
+Thu Jul 14 15:12:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * reloc.c (enum bfd_reloc_code_real, bfd_type, struct
+ reloc_howto_struct, reloc_howto_type, HOWTO, HOWTO2): Copied
+ changes over from bfd-in2.h so they get generated properly next
+ time someone runs "make headers".
+ * bfd-in2.h: Rebuilt.
+
+ * targets.c (netbsd532_vec, pc532mach_vec): Declare const.
+ (m88kmach3_vec): Restore deleted declaration.
+
+ * configure.in: Alphabetize target vector names.
+
+ * config/pc532mach.mh: New file.
+ (HDEPFILES, HDEFINES): Define here.
+ * config/pc532-mach.mt (HDEPFILES, HDEFINES): Deleted.
+ * config/ns32k-netbsd.mt (HDEPFILES, HDEFINES): Deleted.
+
+ Sun Jul 10 00:04:20 1994 Ian Dall (dall@hfrd.dsto.gov.au)
+
+ * pc532-mach.c: New File. pc532-mach a.out format.
+
+ * netbsd532.c: New file. pc532-netbsd532 a.out format.
+
+ * hosts/pc532mach.h: New file. pc532-mach host support.
+
+ * cpu-ns32k.c: New file. ns32k support cpu specific code rather
+ than format specific code.
+
+ * config/pc532-mach.mt: New file. Support for pc532-mach target.
+
+ * config/ns32k-netbsd.mt: New file. Support for netbsd532 target.
+
+ * aout-ns32k.c, aout-ns32k.h: New files supporting aout format for
+ ns32k series.
+
+ * targets.c: Add netbsd532_vec and pc532machaout_vec into
+ bfd_target_vector array. Move netbsd386_vec to alphabetic order
+ location.
+
+ * reloc.c (_bfd_final_link_relocate) Add support for
+ special_function1 in howto.
+
+ * libaout.h: add M_NS32032, M_NS32532, M_532_NETBSD entries in
+ machine_type enum.
+
+ * configure.in: add pc532mach_vec and netbsd532_vec entries.
+
+ * config.bfd: add pc532mach host entries. Use for both
+ ns32k-pc532-mach and ns32k-pc532-netbsd.
+
+ * config.bfd: it doesn't work to use i386-mach3 for ns32k*-*-mach.
+ add ns32k-pc532-mach* and ns32k-*-netbsd* entries.
+
+ * bfd-in2.h: Add ns32k specific relocations to bfd_reloc_code_real
+ enum.
+
+ * bfd-in2.h: Add special_function1 to struct howto. Change HOWTO
+ and NEWHOWTO macros to make special_function1 NULL. Neww HOWTO2
+ macro.
+
+ * bfd-in2.h: Split definition of struct reloc_howto_struct
+ and corresponding typedef into two statements.
+
+ * bfd-in2.h: Add entry bfd_arch_ns32k to bfd_architecture enum.
+
+ * archures.c: Add bfd_ns32k_arch prototype, and entry in
+ archures_init_table.
+
+ * aoutx.h (aout_link_reloc_link_order): Allow for target dependent
+ MY_put_reloc macro. Allow for target dependent special_function1
+ to apply the relocation.
+
+ * aoutx.h (aout_link_input_section_std): Allow for target
+ dependent determination of reloc howto. Allow for target dependent
+ special_function1 to apply the relocation.
+
+ * aoutx.h (get_reloc_upper_bound): Detect bss and return 0.
+
+ * aoutx.h (slurp_reloc_table): Detect bss and succesfully read
+ zero reloc entries.
+
+ * aoutx.h (machine_type): Add bfd_arch_ns32k case.
+
+ * aoutx.h: Stat to determine executable status if STAT_FOR_EXEC
+ is defined (not just MACH). Use fstat instead of stat and check
+ for fstat error.
+
+ * aoutx.h: Allow target dependent swap_std_reloc_{in,out}.
+
+ * aoutx.h: Allow CTORS reloc info to be in target dependent reloc
+ table.
+
+ * aout-target.h: Apply SWAP_MAGIC (if defined) after
+ swap_exec_header_in, otherwise we have magic in the wrong order.
+
+Thu Jul 14 11:47:27 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * coff-sparc.c (sparccoff_vec): Have leading underscores.
+
+Tue Jul 12 12:08:10 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * aix386-core.c, aoutf1.h, cisco-core.c, elfcode.h, hppabsd-core.c,
+ hpux-core.c, irix-core.c, lynx-core.c, osf-core.c, ptrace-core.c,
+ rs6000-core.c, trad-core.c: Remove SEC_ALLOC flag from .reg
+ sections, .reg sections are not allocated and contain debug
+ information only.
+ * osf-core.c (make_bfd_asection, osf_core_core_file_p): Use
+ bfd_make_section_anyway instead of building unique section names.
+
+Tue Jul 12 11:41:22 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * libelf.h (bfd_elf32_swap_symbol_in): Declare.
+ (bfd_elf32_swap_symbol_out): Declare.
+ (bfd_elf64_swap_symbol_in, bfd_elf64_swap_symbol_out): Declare.
+ * elf32-hppa.c (elf32_hppa_args_hash_table_init): Correct cast.
+
+ * aout-encap.c (ARCH): Don't define. Obsolete.
+ * aout0.c, aoutx.h, gen-aout.c, hp300bsd.c, hp300hpux.c: Likewise.
+ * i386aout.c, i386bsd.c, i386dynix.c, i386linux.c: Likewise.
+ * i386lynx.c, m68klynx.c, mipsbsd.c, netbsd386.c: Likewise.
+ * newsos3.c, sparclynx.c, sunos.c: Likewise.
+
+Mon Jul 11 20:08:23 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * section.c (STD_SECTION): Make the sixth argument boolean, not
+ the seventh. From gary@tuva.pacsemi.oz.au (gary kopff).
+
+Sun Jul 10 09:12:02 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * aoutx.h (bfd_free_cached_info): Change name of FREE to BFCI_FREE
+ in order not to collide with LynxOS's definition of FREE in
+ /usr/include/sys/proc.h
+
+Thu Jul 7 14:18:06 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * reloc.c (bfd_perform_relocation): Don't clobber the relocation
+ value for coff-Intel-little or coff-Intel-big. Hack upon hack.
+
+Thu Jul 7 10:10:34 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * aoutx.h (howto_table_std): Add entry for GOT relocations
+ which are present in sun3 shared libraries, to avoid assertions
+ when reading the dynamic relocations.
+
+Thu Jul 7 10:19:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.h (R_HPPA_COMPLEX): Fix dumb typo.
+
+Wed Jul 6 19:21:57 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * hosts/sysv4.h (qsort, strtol): Don't declare.
+
+ * elfcode.h (elf_link_output_sym): Don't call output_symbol_hook
+ if it is NULL.
+
+ * elf32-mips.c (mips_elf_final_write_processing): Add ignored info
+ argument to correspond to recent libelf.h change.
+
+Wed Jul 6 00:48:57 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * coff-alpha.c (alpha_ecoff_mkobject_hook): New hook to
+ additionally copy object type information from the alpha file
+ header to the BFD flags.
+ (alpha_ecoff_backend_data): Use it.
+ (ecoffalpha_little_vec): Add DYNAMIC to object_flags.
+ * aout64.c: Fix typo in conditional QMAGIC definition.
+
+Wed Jul 6 00:13:17 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppabsd-core.c (hppabsd_core_core_file_p): Sanity check the
+ value of clicksz to help weed out non HPPA BSD core files.
+
+Tue Jul 5 13:26:02 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ Mach 3 support.
+ * config.bfd (m88*-*-mach3*, mips*-dec-mach3*, mips*-*-mach3*):
+ New targets.
+ * configure.host (i[34]86-*-mach3*, ns32k-*-mach3*): Recognize
+ "mach3" instead of "mach".
+ (m88*-*-mach3*, mips*-dec-mach3*, mips*-*-mach3*): New hosts.
+ * targets.c (m88kmach3_vec): New target vector.
+ (bfd_target_vector): Add i386mach3_vec and m88kmach3_vec, but
+ inside #if 0.
+ * aoutx.h (some_aout_object_p) [MACH]: Recognize executables by
+ checking for execute permission, instead of looking at entry
+ point.
+ * i386mach3.c: Update, define MACH, N_TXTOFF, N_TXTADDR,
+ N_SHARED_LIB, don't include aout/*.h files, etc.
+ * m88kmach3.c: New file, m88k Mach 3 target.
+ * config/m88k-mach3.mt, config/mips-mach3.mt: New files, target
+ makefile fragments.
+ * config/i386mach3.mh, config/m88kmach3.mh, config/mipsmach3.mh:
+ New files, host makefile fragments.
+ * hosts/m88kmach3.h, hosts/mipsmach3.h: New files, host definitions.
+
+Tue Jul 5 13:56:52 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * elfcode.h (swap_out_syms): Get alignment of common symbol from
+ st_value field of saved ELF symbol information, if there is any.
+
+Mon Jul 4 19:13:32 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.h (R_HPPA_COMPLEX): Define.
+ * elf32-hppa.h (R_HPPA_COMPLEX): Define.
+ (elf32_hppa_reloc_type): Delete R_PARISC_STUB_CALL_17.
+
+Fri Jul 1 12:07:41 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * Support code for enabling the new style linker for PA ELF.
+ * elfcode.h (swap_symbol_in, swap_symbol_out): Externalize.
+ (elf_compute_section_file_positions): Pass link_info to
+ the begin_write_processing hook.
+ (bfd_elf_write_object_contents): Pass NULL for new link_info
+ argument to final_write_processing hook.
+ (elf_link_output_sym): Accept new "input_section" argument for
+ the symbols's input section. All callers changed. Call the
+ link_output_symbol_hook if it's defined.
+ (elf_bfd_final_link): Call the final_write_processing hook if
+ it's defined.
+ * libelf.h (elf_backend_link_output_symbol_hook): Declare.
+ (elf_backend_begin_write_processing): Add new "info" argument.
+ (elf_backend_final_write_processing): Likewise.
+ * elf32-target.h (elf_backend_link_output_symbol_hook): Provide
+ a default definition.
+ (elf32_bed): Add elf_backend_link_output_symbol_hook.
+ * elf64-target.h: Likewise.
+
+ * Major rework of the PA ELF code. Uses the new style BFD
+ linker, major cleanups.
+ * hppa_stubs.h: Rewrite from scratch. Much smaller and simpler.
+ * elf32-hppa.h: Delete all symbol extension related code.
+ (hppa_look_for_stubs_in_section): Delete decl.
+ (elf32_hppa_size_stubs, elf32_hppa_build_stubs): New decls.
+ * elf32-hppa.c: Symbol extension stuff moved form elf32-hppa.h
+ into elf32-hppa.c. Do not include aout64.h.
+ (typdef hppa_stub_type): Delete.
+ (elf32_hppa_stub_name_list_struct): Delete.
+ (elf32_hppa_stub_description_struct): Delete.
+ (arg_reloc_type): Use simpler enumerations. All references changed.
+ (arg_location, arg_reloc_relocation): Likewise.
+ (elf32_hppa_symextn_map_struct): Delete.
+ (get_symbol_value): Delete.
+ (elf32_hppa_get_sym_extn): Delete.
+ (find_stubs, new_stubs, type_of_mismatch): Delete.
+ (find_stub_by_name, add_stub_by_name): Delete.
+ (hppa_elf_stub_finish, hppa_elf_stub_reloc): Delete.
+ (hppa_elf_arg_reloc_needed): Renamed. Simplify.
+ (hppa_elf_build_linker_stub, hppa_elf_create_stub_sec): Delete.
+ (hppa_elf_long_branch_needed_p): Delete.
+ (hppa_look_for_stubs_in_section): Delete.
+ (hppa_elf_get_section_contents): Delete.
+ (elf32_hppa_backend_symbol_processing): Delete.
+ (elf32_hppa_backend_section_processing): Delete.
+ (elf32_hppa_backend_section_from_shdr): Delete.
+ (elf32_hppa_backend_fake_sections): Delete.
+ (elf32_hppa_backend_section_from_bfd_section): Delete.
+ (NEW_INSTRUCTION): Delete.
+ (CURRENT_STUB_OFFSET): Delete.
+ (elf32_hppa_relocate_section): New function.
+ (elf32_hppa_bfd_final_link_relocate): New function.
+ (elf32_hppa_size_symext): New function.
+ (elf32_hppa_link_output_symbol_hook): New function.
+ (elf32_hppa_read_symext_info): New function.
+ (elf32_hppa_add_symbol_hook): New function.
+ (elf32_hppa_name_of_stub): New function.
+ (elf32_hppa_size_of_stub): New function.
+ (elf32_hppa_build_one_sub): New function.
+ (elf32_hppa_build_stubs): New function.
+ (elf32_hppa_size_stubs): New function.
+ (linker, stub and argument hash tables): Add appropriate
+ structures, definitions and functions to implement all three
+ hash tables.
+ (hppa_elf_relocate_insn): Don't need argument location information
+ in this function.
+ (add_entry_to_symext_chain): Accept a symbol's argument location
+ information rather than the symbol itself. All callers changed.
+ (hppa_elf_gen_reloc_type): Simplify.
+ (hppa_elf_set_section_contents): Stub section is no longer special.
+ (hppa_elf_reloc): Greatly simplify.
+ (elf32_hppa_begin_write_processing): Accept link_info argument.
+ Handle being called from the BFD backend linker.
+ (elf32_hppa_final_write_processing): Likewise.
+ (elf_hppa_tc_make_sections): No longer call stub_finish.
+
+Mon Jun 27 18:07:06 1994 Steve Chamberlain (sac@cirdan.cygnus.com)
+
+ * section.c (bfd_get_section_contents): Put in parens to get
+ precedence right.
+
+Sun Jun 26 18:08:29 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * libelf.h (relocate_section): New argument "output_names" added
+ to prototype.
+ * elfcode.h (elf_link_input_bfd): New argument "output_names"
+ added to prototype of relocate_section. Pass the output symbol
+ names to relocate_section.
+ * elf32-i386.c (elf_i386_relocate_section): Use "output_names" to
+ determine the name of a local symbol.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+Fri Jun 24 08:15:42 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Add Solaris BCP (the part of Solaris which allows it to run
+ SunOS4 a.out files) core file handling.
+ * aoutf1.h (external_solaris_bcp_core, swapcore_solaris_bcp):
+ New structure and its swap in function.
+ (internal_sunos_core): New member c_data_addr, to receive the
+ start address of the data section in the core file.
+ (swapcore_sun3, swapcore_sparc, sunos4_core_file_p): Use it.
+ (sunos4_core_file_p): Recognize Solaris BCP core file.
+ (sunos4_core_file_matches_executable_p): Always indicate match
+ for Solaris BCP core files.
+
+Thu Jun 23 15:31:28 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ Preliminary support for generating shared libraries, from Eric
+ Youngdale <ericy@cais.cais.com>.
+ * elfcode.h (prep_headers): If DYNAMIC, set e_type to ET_DYN.
+ (elf_link_add_object_symbols): If generating a shared library,
+ create dynamic sections for first input BFD with the right format.
+ (elf_link_create_dynamic_sections): Don't create .interp section
+ if creating a shared library.
+ (elf_link_input_bfd): Skip dynamic sections in input file.
+ (elf_bfd_final_link): If creating a shared library, it's OK for
+ dynobj to have sections which are not SEC_IN_MEMORY.
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Only set .interp
+ section if not creating a shared library.
+ * elf32-sparc.c (elf_sparc_size_dynamic_sections): Likewise.
+
+ * elfcode.h (elf_object_p): Don't set DYNAMIC just because there
+ is an SHT_DYNAMIC section.
+
+ * cf-i386lynx.c (i386coff_vec): Don't include DYNAMIC in
+ object_flags.
+ * coff-sparc.c (sparccoff_vec): Likewise.
+ * hppabsd-core.c (hppabsd_core_vec): Likewise.
+
+ * aoutx.h (NAME(aout,some_aout_object_p)): Don't set SEC_RELOC
+ just because DYNAMIC is set.
+
+Thu Jun 23 12:53:41 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.in: Change --with-targets to --enable-targets and
+ --with-64-bit-bfd to --enable-64-bit-bfd.
+ * Makefile.in, mpw-make.in, targets.c: Change comments.
+
+Wed Jun 22 17:59:59 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config.bfd (powerpc-*-elf*): New target, just like
+ powerpc-*-sysv4*.
+
+ * linker.c (FAIL): Undefine macro before defining as enum.
+
+Wed Jun 22 10:52:47 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * linker.c (_bfd_generic_link_add_archive_symbols): Initialize
+ pass from abfd->archive_pass, and save it there as well.
+
+ * hash.c (bfd_hash_allocate): Don't call bfd_set_error if
+ obstack_alloc returns NULL unless the size is non-zero.
+
+ * linker.c (archive_hash_allocate): Define.
+ (_bfd_generic_link_add_archive_symbols): Use archive_hash_allocate
+ rather than obstack_alloc, for clarity.
+
+ * elfcode.h (elf_get_reloc_upper_bound): Correct.
+
+ * aout64.c (BMAGIC, QMAGIC): Define if not already defined. From
+ Peter Schauer <pes@regent.e-technik.tu-muenchen.de>.
+
+ Linux ZMAGIC support from Eric Youngdale <ericy@cais.cais.com>.
+ * libaout.h (struct aoutdata): Add field zmagic_disk_block_size.
+ * aout-target.h (MY(callback)): Only set alignment according to
+ architecture if the section sizes are aligned to that alignment,
+ for backward compatibility.
+ (MY(set_sizes)): Initialize zmagic_disk_block_size field.
+ * aoutx.h (adjust_z_magic): Set ztih if using q_magic_format. Set
+ text section filepos to zmagic_disk_block_size if not ztih. Use a
+ different padding algorithm if not ztih.
+ * i386linux.c (MY_text_includes_header): Don't define.
+
+ * aoutx.h (aout_link_check_ar_symbols): Just skip N_STAB and N_FN
+ symbols; don't look them up in the hash table. From
+ ralphc@pyramid.com (Ralph Campbell).
+
+Tue Jun 21 11:47:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * coff-go32.c (go32coff_archive_p): Remove unused function.
+
+ * section.c (bfd_abs_section): Make const.
+ (bfd_abs_section_ptr, bfd_is_abs_section): Define.
+ (bfd_und_section): Make const.
+ (bfd_und_section_ptr, bfd_is_und_section): Define.
+ (bfd_com_section): Make const.
+ (bfd_com_section_ptr): Define.
+ (bfd_ind_section): Make const.
+ (bfd_ind_section_ptr, bfd_is_ind_section): Define.
+ (bfd_abs_symbol, bfd_com_symbol): Make const.
+ (bfd_und_symbol, bfd_ind_symbol): Likewise.
+ (global_syms): Cast initialization of section field.
+ (STD_SECTION): Define as const, and cast initializations.
+ * bfd-in2.h: Rebuilt.
+ * Many files: Change uses of bfd_abs_section, etc., to use
+ bfd_abs_section_ptr or bfd_is_abs_section, etc.
+
+Mon Jun 20 11:06:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Many files: change all bfd_target vectors to be const. Change
+ all uses of bfd_target * to be const bfd_target *. Change
+ bfd_target_vector and bfd_default_vector arrays to be const
+ bfd_target * const *.
+
+ * ecoff.c, libecoff.h, ecoffswap.h, coff-alpha.c, coff-mips.c,
+ elf32-mips.c: Renamed all externally visible ECOFF routines which
+ are local to BFD to start with _bfd_ecoff instead of just ecoff.
+
+ * ecoff.c (ecoff_swap_tir_in): Change input argument to const.
+ (ecoff_swap_tir_out): Likewise.
+ (ecoff_swap_rndx_in, ecoff_swap_rndx_out): Likewise.
+ (ecoff_slurp_symbolic_info): Add new arguments to correspond to
+ read_debug_info entry point in ecoff_debug_swap structure.
+ Change all calls.
+ * libecoff.h (ecoff_slurp_symbolic_info): Change declaration.
+ * ecoffswap.h (ecoff_swap_tir_in, ecoff_swap_tir_out): Declare.
+ (ecoff_swap_rndx_in, ecoff_swap_rndx_out): Declare.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize new
+ ecoff_debug_swap fields.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+ * elf32-mips.c (mips_elf_read_ecoff_info): Undefine READ.
+ (mips_elf_ecoff_debug_swap): Initialize new ecoff_debug_swap
+ fields.
+ * configure.in (bfd_elf32_bigmips_vec): Use ecoff.o and
+ ecofflink.o.
+ (bfd_elf32_littlemips_vec): Likewise.
+ (ecoff_big_vec, ecoff_little_vec): Likewise.
+ (ecoffalpha_little_vec): Likewise.
+ * Makefile.in (BFD_LIBS): Remove ecoff.o and ecofflink.o.
+ (BFD32_BACKENDS): Add ecoff.o and ecofflink.o.
+
+ * aoutx.h (NAME(aout,final_link)): Check flavour of sub, not abfd,
+ when computing reloc sizes. From Eric Youngdale
+ <ericy@cais.cais.com>.
+ * elfcode.h (elf_bfd_final_link): Don't try to compute maximum
+ reloc count or size for a non-ELF file.
+
+ * mipsbsd.c (MY_final_link_callback): Define to avoid warning.
+
+ * hp300hpux.c (MY_final_link_callback): Define to avoid warning.
+ (BMAGIC, QMAGIC): Define; used by aoutx.h.
+ (MY(slurp_symbol_table)): Change translate_from_native_sym_flags
+ calls to use new parameters.
+
+Fri Jun 17 14:45:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aout-target.h (MY(callback)): Set the alignments of the text,
+ data and bss sections after determining the architecture.
+
+ * sunos.c (sunos_add_one_symbol): Treat a common symbol from a
+ dynamic object as being in the .bss section of the object, rather
+ than as being undefined.
+
+Fri Jun 17 11:16:50 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * libhppa.h (bfd_hppa_insn2fmt, hppa_rebuild_insn): Make INLINE.
+
+ * elf32-hppa.h (elf_hppa_final_processing): Delete decl.
+
+Thu Jun 16 23:36:23 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elfcode.h (elf_link_input_bfd): Don't try to read local symbols
+ if there aren't any in the input file.
+
+Thu Jun 16 14:25:22 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * i386linux.c: Many new functions and definitions for linker
+ support for Linux shared libraries.
+ * bfd-in.h (bfd_linux_size_dynamic_sections): Declare.
+ * bfd-in2.h: Rebuild.
+
+Thu Jun 16 14:23:46 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config.bfd: If second argument is ``_'', then, instead of
+ echoing config file name, echo whether target uses leading
+ underscores on symbol names. Add appropriate settings to
+ different cases. Used by binutils/configure.in to set default for
+ c++filt.
+
+ * elfcode.h (elf_bfd_final_link): If trying to generate a shared
+ object, warn and return false.
+
+ * aoutx.h (NAME(aout,some_aout_object_p)): Accept BMAGIC objects
+ and treat them as OMAGIC.
+
+Wed Jun 15 18:02:21 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ Enable sparc v9 support for release. Note that this is still a
+ work in progress, pending release of an ABI specification.
+ * config.bfd, configure.in: Include sparc v9 elf config.
+ * elfcode.h (prep_headers): Handle sparc v9 (64 bit).
+ * reloc.c (bfd_reloc_code_real): New reloc types.
+ * elf64-sparc.c: Implement elf64-sparc target.
+ * Makefile.in, targets.c: Updated.
+
+Wed Jun 15 01:34:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libelf.h (struct elf_obj_tdata): New field dt_needed_name.
+ (elf_dt_needed_name): New accessor macro.
+ * elfcode.h (elf_link_add_object_symbols): If elf_dt_needed_name
+ is set, use that instead of the filename for the DT_NEEDED dynamic
+ entry.
+ * elf.c (bfd_elf_set_dt_needed_name): New function.
+ * bfd-in.h (bfd_elf_set_dt_needed_name): Declare.
+ * bfd-in2.h: Rebuilt.
+
+ * elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Add sinterpptr
+ argument, and set it to the .interp section.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update prototype.
+ (bfd_elf64_size_dynamic_sections): Likewise.
+ * bfd-in2.h: Rebuilt.
+
+ * coff-sparc.c (SWAP_OUT_RELOC_EXTRA): Define to clear the r_spare
+ field of the reloc rather than letting it be garbage.
+
+ * archive.c (bfd_slurp_armap): Recognize __.SYMDEF/ as well as
+ __.SYMDEF; the former was used in old Linux archives. From
+ jrs@world.std.com (Rick Sladkey).
+
+ * i386linux.c (i386linux_write_object_contents): Define; like
+ MY(write_object_contents) in aout-target.h, but set MACHTYPE to
+ M_386. From jrs@world.std.com (Rick Sladkey).
+ (MY_write_object_contents): Define.
+
+ * aoutx.h (translate_from_native_sym_flags): Treat N_SETV symbols
+ as N_DATA symbols.
+ (aout_link_add_symbols): Likewise.
+
+ * aoutx.h: Rewrite symbol duplicate elimination to use BFD hash
+ tables.
+ (struct stringtab_entry, struct stringtab_data): Remove.
+ (HASHMAXLEN, HASH_CHAR, hash, compare, log2, emit_strtab): Remove.
+ (struct strtab_hash_entry, struct strtab_hash): Define.
+ (strtab_hash_newfunc, strtab_hash_lookup): Define.
+ (stringtab_free, emit_stringtab): Define.
+ (stringtab_init, add_to_stringtab): Rewrite.
+ (NAME(aout,write_syms)): Use new stringtab code.
+ (struct aout_final_link_info, NAME(aout,final_link)): Likewise.
+ (aout_link_write_symbols, aout_link_write_other_symbol): Likewise.
+
+ * bfd-in.h (BFD_TRADITIONAL_FORMAT): Define new BFD flag to
+ request BFD to write object in the traditional format, whatever
+ that means for the particular backend.
+ * bfd-in2.h: Rebuilt.
+
+ * hash.c (bfd_hash_allocate): If obstack_alloc fails, set
+ bfd_error_no_memory.
+
+Tue Jun 14 13:00:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libaout.h (struct aoutdata): Add q_magic_format to subformat
+ enum.
+ * aout-target.h (MY_bfd_copy_private_bfd_data): Define as function
+ if not already defined. Copy subformat information.
+ (MY_text_includes_header): Define as 0 if not already defined.
+ (MY(backend_data)): Use MY_text_includes_header rather than 0.
+ (MY_final_link_callback): Rename from final_link_callback, and
+ define only if MY_final_link_callback is not already defined.
+ (MY_bfd_final_link): Rename use of final_link_callback to
+ MY_final_link_callback.
+ * aoutx.h (NAME(aout,some_aout_object_p)): Handle QMAGIC like
+ ZMAGIC, but set the subformat to q_magic_format. Abort if the
+ magic number if not recognized.
+ (adjust_z_magic): Use QMAGIC if q_magic_format.
+ * i386linux.c (MY_text_includes_header): Define as 1.
+ (i386linux_bfd_final_link): New static function.
+ (MY_bfd_final_link): Define as i386linux_bfd_final_link.
+
+ * aoutx.h (translate_to_native_sym_flags): Check both section and
+ output_section against sections of abfd.
+
+ * libecoff.h (struct ecoff_link_hash_entry): Change type of
+ written from boolean to char. Add new field small.
+ * ecoff.c (ecoff_link_hash_newfunc): Initialize written to 0
+ rather than false. Initialize small to 0.
+ (ecoff_link_add_externals): If ECOFF type is scSUndefined, set
+ small. If small is set, and hash table type is common, force the
+ symbol into a section named SCOMMON and change the ECOFF type from
+ scCommon to scSCommon.
+ (ecoff_link_write_external): Set written to 1 rather than true.
+ * coff-mips.c (mips_relocate_section): Correct JMPADDR reloc
+ overflow check to consider section VMA of input file.
+
+Mon Jun 13 14:20:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutf1.h (aout_32_sunos4_write_object_contents): Handle a
+ machine type of 68000.
+ * aoutx.h (NAME(aout,machine_type)): Add new argument unknown.
+ Set *unknown to true if machine type is really unknown, as opposed
+ to M_UNKNOWN for the 68000.
+ (NAME(aout,set_arch_mach)): Change NAME(aout,machine_type) call
+ accordingly.
+ * libaout.h (NAME(aout,machine_type)): Add new argument to
+ prototype.
+
+Sun Jun 12 20:21:03 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (EXEC_AUX_ID): Define based on availablity of HPUX_AUX_ID
+ or HIUX_AUX_ID.
+ (som_begin_writing): Use EXEC_AUX_ID instead of HPUX_AUX_ID.
+ (som_write_armap): Use CPU_PA_RISC1_0 as the magic number. Note
+ som.c is careful to always define CPU_PA_RISC1_0.
+
+Sat Jun 11 16:32:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add weak symbols as an extension to a.out.
+ * aoutx.h (sym_in_text_section): Don't define.
+ (sym_in_data_section, sym_in_bss_section): Likewise.
+ (sym_is_undefined, sym_is_global_defn): Likewise.
+ (sym_is_debugger_info, sym_is_fortrancommon): Likewise.
+ (sym_is_absolute, sym_is_indirect): Likewise.
+ (translate_from_native_sym_flags): Rewrite for clarity. Rearrange
+ arguments and change caller. Handle weak symbols.
+ (translate_to_native_sym_flags): Likewise.
+ (aout_link_check_ar_symbols): Don't ignore weak symbols. Pull
+ object in from archive if a weak defintion is found for an
+ existing undefined symbol.
+ (aout_link_add_symbols): Put all cases in switch. Set flags of an
+ undefined symbol to 0. Handle weak symbols.
+ (aout_link_write_symbols): Handle weak symbols.
+ (aout_link_write_other_symbol): Likewise.
+ (aout_link_input_section_std): Likewise.
+ (aout_link_input_section_ext): Likewise.
+ * sunos.c (sunos_write_dynamic_symbol): Likewise.
+
+Fri Jun 10 13:25:13 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (NAME(aout,canonicalize_reloc)): Handle .bss section.
+ (NAME(aout,get_reloc_upper_bound)): Likewise.
+
+ * coff-i960.c (coff_i960_reloc_type_lookup): Add BFD_RELOC_CTOR.
+ * linker.c (_bfd_generic_link_write_global_symbol): Don't assume
+ the section of a common symbol is not NULL.
+
+Wed Jun 8 23:15:53 1994 Stu Grossman (grossman@cygnus.com)
+
+ * nlmcode.h (nlm_object_p): Set EXEC_P and start address for GDB.
+
+Wed Jun 8 23:57:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_get_external_symbols): Don't try to read the
+ strings if there are no symbols.
+ (aout_link_write_other_symbol): Use the output section when
+ working out the type.
+
+Tue Jun 7 13:25:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (assign_section_numbers): Put shstrtab, symtab and
+ strtab sections at end of file. Avoids bug in some versions of
+ SVR4 strip. From Eric Youngdale <eric@tantalus.nrl.navy.mil>.
+
+ * coffcode.h (styp_to_sec_flags): If COFF_PAGE_SIZE is defined,
+ set SEC_DEBUGGING for STYP_INFO sections.
+ (coff_compute_section_file_positions): If COFF_PAGE_SIZE is
+ defined, and D_PAGED is set, set the file position equal to the
+ section VMA modulo COFF_PAGE_SIZE.
+ * coffgen.c (coff_real_object_p): If F_EXEC is set, set D_PAGED.
+ * coff-i386.c: Set D_PAGED in BFD target.
+ (COFF_PAGE_SIZE): Define.
+ * coff-m68k.c, coff-sparc.c: Likewise.
+
+Mon Jun 6 10:57:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (bfd_section_from_shdr): Don't turn a reloc section
+ into a BFD section just because SHF_ALLOC is set; require that it
+ not use the normal symbol table.
+ (elf_section_from_bfd_section): Corresponding change.
+
+ Better indirect and warning symbol handling inspired by Stuart
+ Quick <stuck@cs.man.ac.uk>.
+ * linker.c (enum link_action): Add REF, MIND, CWARN, REFC.
+ (link_action): Change UNDEF_ROW/def and UNDEFW_ROW/def from NOACT
+ to REF. Change UNDEF_ROW/indr and UNDEFW_ROW/indr from CYCLE to
+ REFC. Change DEF_ROW/indr and COMMON_ROW/indr from CYCLE to MDEF.
+ Change DEFW_ROW/indr from CYCLE to NOACT. Change INDR_ROW/indr
+ from MDEF to MIND. Change INDR_ROW/warn from WARNC to CYCLE.
+ Change WARN_ROW/def and WARN_ROW/indr from MWARN to CWARN. Change
+ WARN_ROW/com from MWARN to WARN. Change WARN_ROW/warn from NOACT
+ to CYCLE. Change SET_ROW/warn from WARNC to CYCLE>
+ (_bfd_generic_link_add_one_symbol): Handle REF, MIND, CWARN and
+ REFC. If a new indirect symbol has been referenced, push the
+ reference down to the symbol it points to. FIx handling of WARN.
+ * aoutx.h (translate_from_native_sym_flags): If N_WARNING, don't
+ clobber e_type of next symbol.
+ (translate_to_native_sym_flags): Likewise.
+ (aout_link_write_symbols): Loop on bfd_link_hash_warning as well
+ as bfd_link_hash_indirect.
+
+ * libaout.h (struct aout_link_hash_entry): New field written.
+ * aoutx.h (NAME(aout,link_hash_newfunc)): Initialize written.
+ (aout_link_write_symbols): Use written, not root.written.
+ (aout_link_write_other_symbol): Likewise.
+ * sunos.c (sunos_scan_dynamic_symbol): Likewise.
+ * libecoff.h (struct ecoff_link_hash_entry): New field written.
+ * ecoff.c (ecoff_link_hash_newfunc): Initialize written.
+ (ecoff_link_write_external): use written, not root.written.
+ * genlink.h (struct generic_link_hash_entry): New field written.
+ * linker.c (_bfd_link_hash_newfunc): Don't initialize written.
+ (generic_link_hash_newfunc): Initialize written.
+ (_bfd_generic_link_output_symbols): Use written, not root.written.
+ (_bfd_generic_link_write_global_symbol): Likewise.
+ (_bfd_generic_reloc_link_order): Likewise.
+
+ * libecoff.h (ecoff_data_type): Add linker field.
+ * ecoff.c (ecoff_write_object_contents): Check new tdata linker
+ field, rather than outsymbols being non-NULL, to decide whether to
+ output the symbols and relocs.
+ (ecoff_bfd_final_link): Set new tdata linker field to true.
+
+ * ecoff.c (ecoff_bfd_copy_private_bfd_data): Don't try to copy
+ data to a non-ECOFF file.
+
+ * libbfd-in.h: Add warning that libbfd.h is a generated file.
+ * libbfd.h: Rebuilt.
+
+Sun Jun 5 15:02:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Changes to support ELF strip and objcopy on dynamically linked
+ files.
+ * elfcode.h (elf_fake_sections): Add prototype.
+ (bfd_section_from_shdr): Make a BFD section from an SHT_HASH
+ section, and from an SHT_DYNSYM section, and from the dynamic
+ string table section.
+ (elf_object_p): Set D_PAGED if there is a program header.
+ (elf_make_sections): Remove.
+ (fix_up_strtabs): Remove.
+ (elf_fake_sections): Rewrite. Now sets sh_entsize.
+ (assign_section_numbers): Rewrite. Now sets sh_link and sh_info
+ for all sections.
+ (elf_compute_section_file_positions): Don't call obsolete
+ functions elf_make_sections or fix_up_strtabs.
+ (swap_out_syms): Set sh_addralign to FILE_ALIGN rather than 4.
+ (NAME(bfd_elf,write_object_contents)): Permit writing DYNAMIC
+ objects.
+ (elf_section_from_bfd_section): Treat SHT_DYNSYM like other normal
+ sections. If an SHT_REL or SHT_RELA section is allocated or uses
+ an unusual symbol table, permit a BFD section to map to it.
+ Permit most SHT_STRTAB sections to have a BFD section mapped to
+ them.
+ (elf_bfd_final_link): Don't set sh_link, sh_info or sh_entsize
+ fields of dynamic sections here; do it in assign_section_numbers.
+ * elf32-target.h, elf64-target.h: Add D_PAGED to permitted object
+ flags.
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Only set SEC_DATA if
+ SEC_LOAD is set, rather than checking SEC_ALLOC.
+
+ * libbfd-in.h (bfd_realloc): Change last arg to "size_t size".
+
+Fri Jun 3 10:58:02 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_write_object_contents): Don't compute the file header's
+ checksum here.
+ (som_write_headers): Instead do it here.
+
+ * libbfd.h (bfd_realloc): Change last arg to "size_t size".
+
+Thu Jun 2 17:39:22 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * hosts/sun3.h: Include <stdlib.h>. Don't declare free, exit or
+ getenv.
+
+ Add linker support for SunOS shared libraries.
+ * sunos.c: Include bfdlink.h. Add many new functions and
+ definitions for SunOS shared library support.
+ * bfd-in.h (bfd_sunos_record_link_assignment): Declare.
+ (bfd_sunos_size_dynamic_sections): Declare.
+ * bfd-in2.h: Rebuilt.
+ * aoutx.h (struct aout_link_hash_entry): Move to libaout.h.
+ (struct aout_link_hash_table): Likewise.
+ (aout_link_hash_lookup, aout_link_hash_traverse): Likewise.
+ (aout_hash_table): Likewise.
+ (NAME(aout,link_hash_newfunc)): Rename from aout_link_hash_newfunc
+ and make externally visible.
+ (NAME(aout,link_hash_table_init)): New function.
+ (NAME(aout,link_hash_table_create)): Call
+ NAME(aout,link_hash_table_init), not _bfd_link_hash_table_init.
+ (aout_link_add_symbols): Don't fail if no symbols. If it exists,
+ call add_dynamic_symbols backend entry point for dynamic objects.
+ Use add_one_symbol backend entry point if it exists.
+ (NAME(aout,final_link)): Call finish_dynamic_link backend entry
+ point, if it exists.
+ (aout_link_input_bfd): For a dynamic object, call
+ link_dynamic_object backend entry point, if it exists.
+ (aout_link_write_other_symbol): Call write_dynamic_symbol backend
+ entry point, if it exists.
+ (aout_link_input_section): Don't read the relocs if they have
+ already been read.
+ (aout_link_input_section_std): When doing a final link, for a
+ reloc against an external symbol, call check_dynamic_reloc backend
+ entry point, if it exists.
+ (aout_link_input_section_ext): Likewise.
+ * libaout.h: Protect against multiple inclusion. Include
+ bfdlink.h.
+ (struct aout_link_hash_entry): Move in from aoutx.h.
+ (struct aout_link_hash_table): Likewise.
+ (aout_link_hash_lookup, aout_link_hash_traverse): Likewise.
+ (aout_hash_table): Likewise.
+ (struct aout_backend_data): Add fields add_dynamic_symbols,
+ add_one_symbol, link_dynamic_object, write_dynamic_symbol,
+ check_dynamic_reloc, and finish_dynamic_link.
+ (struct aout_section_data_struct): Define new structure.
+ (aout_section_data): Define new accessor macro.
+ (NAME(aout,link_hash_newfunc)): Declare.
+ (NAME(aout,link_hash_table_init)): Declare.
+ * aoutf1.h (sunos4_aout_backend): Initialize new aout_backend_data
+ fields.
+ * aout-target.h (MY(backend_data)): Likewise.
+ * i386aout.c (MY(backend_data)): Likewise.
+ * i386mach3.c (MY(backend_data)): Likewise.
+ * mipsbsd.c (MY(backend_data)): Likewise.
+ * sparclynx.c (sparclynx_aout_backend): Likewise.
+
+ * aoutx.h (NAME(aout,slurp_symbol_table)): Don't zero out cached
+ until we know it is non-NULL.
+ (aout_link_write_symbols): Don't skip a warning symbol even if it
+ has already been written out. If skipping an indirect symbol,
+ skip the next symbol as well.
+
+Wed Jun 1 14:37:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * hosts/sun3.h: Don't declare qsort, malloc or realloc.
+
+Thu May 26 13:56:03 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * nlmcode.h (nlm_swap_auxiliary_headers_in): Cast bfd_byte pointer
+ to char pointer to avoid compiler warnings.
+
+ * dep-in.sed: Remove spaces before colons.
+
+ Merged changes back in from FSF gas release 2.3:
+
+ * Makefile.in (stmp-bfd.h): Wrap `if' block around grep
+ invocation, to avoid a bug in BSD 4.4 make.
+
+ From Ralph Campbell:
+ * mipsbsd.c (mips_fix_jmp_addr): If symbol is undefined, return an
+ error.
+ (mips_fix_hi16_s): Ditto.
+
+ Fri May 13 21:21:00 1994 DJ Delorie (dj@ctron.com)
+
+ * makefile.dos: define a default target, or archives won't work
+ due to multiple matches.
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: update for latest files
+ * makefile.dos: update for correct targets and sources
+ * coff-go32.c: [new] go32's COFF format (i386coff with underscores)
+ * targets.c: add go32coff target
+ * makefile.in: add coff-go32.c support
+
+Thu May 26 10:10:21 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_prep_headers): Do not set the system_id here, private
+ bfd data has not been copied yet.
+ (som_write_headers): Instead do it here.
+
+Tue May 24 16:17:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Make MIPS ELF use new ELF backend linker. No shared library
+ support yet.
+ * elf32-mips.c (bfd_mips_elf32_swap_gptab_in): New function.
+ (bfd_mips_elf32_swap_gptab_out): New function.
+ (mips_elf_object_p): If last symbol is LOCAL, set elf_bad_symtab.
+ (mips_elf_final_write_processing): Set sh_info field for .gptab.*
+ sections.
+ (mips_elf_fake_sections): Set sh_entsize for .gptab.* sections.
+ (mips_elf_read_ecoff_info): Read and free external symbols last,
+ not first, for clarity.
+ (struct mips_elf_link_hash_entry): Define new structure.
+ (struct mips_elf_link_hash_table): Define new structure.
+ (mips_elf_link_hash_lookup): Define new macro.
+ (mips_elf_link_hash_traverse): Define new macro.
+ (mips_elf_hash_table): Define new macro.
+ (mips_elf_link_hash_newfunc): New static function.
+ (mips_elf_link_hash_table_create): New static function.
+ (mips_elf_add_symbol_hook): New static function.
+ (struct extsym_info): Define new structure.
+ (mips_elf_get_extr, mips_elf_set_index): Remove.
+ (mips_elf_output_extsym): New static function.
+ (gptab_compare): New static function.
+ (mips_elf_final_link): Rewrite to use ELF backend linker, and to
+ merge gptab information in input files.
+ (mips_elf_relocate_hi16): New static function.
+ (mips_elf_relocate_section): New static function.
+ (bfd_elf32_bfd_link_hash_table_create): Define as macro before
+ including elf32-target.h.
+ (elf_backend_relocate_section): Likewise.
+ (elf_backend_add_symbol_hook): Likewise.
+ * elf.c (_bfd_elf_link_hash_newfunc): Rename from
+ elf_link_hash_newfunc and make globally visible. Change caller.
+ (_bfd_elf_link_hash_table_init): New function, broken out of
+ _bfd_elf_link_hash_table_create.
+ (_bfd_elf_link_hash_table_create): Use
+ _bfd_elf_link_hash_table_init.
+ * libelf.h (struct elf_obj_tdata): Add new field bad_symtab.
+ (elf_bad_symtab): Define new accessor macro.
+ (_bfd_elf_link_hash_newfunc): Declare.
+ (_bew_elf_link_hash_table_init): Declare.
+ * elfcode.h (elf_object_p): Call backend object_p hook after
+ swapping in all the section headers.
+ (map_program_segments): Correct typo: Internal for External.
+ (elf_link_add_object_symbols): If elf_bad_symtab is set, read all
+ the symbols. Skip STB_LOCAL symbols rather than giving an error.
+ (elf_bfd_final_link): If elf_bad_symtab is set, allocate space for
+ all symbols, not just locals.
+ (elf_link_output_extsym): Only skip a symbol not mentioned by a
+ regular file if it is mentioned by a dynamic object.
+ (elf_link_input_bfd): If elf_bad_symtab is set, read all the
+ symbols.
+
+Fri May 20 13:38:23 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * som.c (som_set_reloc_info): Do not set any relocation info
+ for SOM fixups which are never passed to BFD.
+
+Fri May 20 11:57:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-mips.c (mips_relocate_section): Add MIPS_R_JMPADDR overflow
+ checking.
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Add DT_DEBUG to
+ the dynamic linking information for the benefit of the debugger.
+ From Peter Schauer.
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Likewise.
+
+ * elf.c (_bfd_elf_make_section_from_shdr): New function, based on
+ code repeated three times in bfd_section_from_shdr in elfcode.h.
+ * libelf.h (_bfd_elf_make_section_from_shdr): Declare.
+ * elfcode.h (bfd_section_from_shdr): Use new function
+ _bfd_elf_make_section_from_shdr to create BFD sections. If a
+ reloc section does not use the main symbol table, or it is part of
+ the process image, treat it as a normal section, not relocs.
+ * elf32-mips.c (mips_elf_section_from_shdr): Use new function
+ _bfd_elf_make_section_from_shdr.
+
+Thu May 19 11:37:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-target.h, elf64-target.h: Change ar_max_namelen value from
+ 15 to 14 to match SVR4 ar.
+
+ Add support for ELF shared libraries. Loosely based on work by
+ Eric Youngdale <ericy@cais.com>.
+ * libelf.h (struct elf_backend_data): Add new fields for dynamic
+ linking: elf_backend_create_dynamic_sections,
+ elf_backend_adjust_dynamic_symbol,
+ elf_backend_size_dynamic_sections,
+ elf_backend_finish_dynamic_symbol,
+ elf_backend_finish_dynamic_sections.
+ (struct elf_link_hash_entry): Change type of align field to
+ bfd_size_type. Add fields dynindx, dynstr_index, weakdef,
+ elf_link_hash_flags.
+ (struct elf_link_hash_table): Add fields dynobj, dynsymcount,
+ dynstr, bucketcount.
+ (bfd_elf32_swap_reloc_in, bfd_elf32_swap_reloc_out): Declare.
+ (bfd_elf32_swap_reloca_in, bfd_elf32_swap_reloca_out): Declare.
+ (bfd_elf32_swap_dyn_in, bfd_elf32_swap_dyn_out): Declare.
+ (bfd_elf32_add_dynamic_entry): Declare.
+ (bfd_elf64_swap_reloc_in, bfd_elf64_swap_reloc_out): Declare.
+ (bfd_elf64_swap_reloca_in, bfd_elf64_swap_reloca_out): Declare.
+ (bfd_elf64_swap_dyn_in, bfd_elf64_swap_dyn_out): Declare.
+ (bfd_elf64_add_dynamic_entry): Declare.
+ * elfcode.h (Elf_External_Dyn): Define.
+ (elf_swap_reloc_in): Define as macro using NAME. Make externally
+ visible.
+ (elf_swap_reloc_out): Likewise.
+ (elf_swap_reloca_in, elf_swap_reloca_out): Likewise.
+ (elf_swap_dyn_in, elf_swap_dyn_out): Define as macro using NAME
+ and as new externally visible function.
+ (elf_fake_sections): Set section type of dynamic sections based on
+ section names.
+ (elf_write_phdrs): Remove.
+ (assign_file_position_for_section): Add new align argument.
+ Change all callers.
+ (get_program_header_size): New static function.
+ (struct seg_info): Remove.
+ (map_program_segments): Completely rewrite.
+ (assign_file_positions_except_relocs): Completely rewrite.
+ (assign_file_positions_for_relocs): Don't set a file position for
+ sections which already have one. Don't bother to align the file
+ position here.
+ (section_from_elf_index): Handle SHT_HASH and SHT_DYNAMIC
+ section types.
+ (elf_section_from_bfd_section): Likewise.
+ (elf_slurp_symbol_table): If section_from_elf_index fails, just
+ use bfd_abs_section rather than returning an error.
+ (elf_sizeof_headers): Make useful.
+ (elf_link_record_dynamic_symbol): New static function.
+ (elf_link_add_object_symbols): Handle dynamic objects.
+ (elf_link_create_dynamic_sections): New static function.
+ (elf_add_dynamic_entry): Define as macro using NAME and as new
+ externally visible function.
+ (NAME(bfd_elf,record_link_assignment)): New function.
+ (elf_buckets): New static variable.
+ (NAME(bfd_elf,size_dynamic_sections)): New function.
+ (struct elf_final_link_info): Add dynsym_sec and hash_sec fields.
+ (elf_bfd_final_link): Handle dynamic linking. Create a section
+ symbol for all ELF sections, not all BFD sections. Store section
+ symbol index in target_index field, not index field. Traverse
+ over global symbols even if stripping.
+ (elf_link_output_extsym): Output dynamic symbols. Mark symbols
+ defined by dynamic objects as undefined.
+ (elf_link_input_bfd): Ignore dynamic objects. Use target_index
+ field for section relocs, and make sure it is set.
+ (elf_reloc_link_order): Use target_index field for section relocs,
+ and make sure it is set.
+ * elf.c (elf_link_hash_newfunc): Initialize dynindx, dynstr_index,
+ weakdef and elf_link_hash_flags fields.
+ (_bfd_elf_link_hash_table_create): Initialize dynobj, dynsymcount,
+ dynstr and bucketcount fields.
+ * elf32-target.h: Initialize new dynamic linking fields.
+ * elf64-target.h: Likewise.
+ * elf32-i386.c: New functions for dynamic linking support.
+ * elf32-sparc.c: Likewise.
+ * bfd-in.h (bfd_elf32_record_link_assignment): Declare.
+ (bfd_elf64_record_link_assignment): Declare.
+ (bfd_elf32_size_dynamic_sections): Declare.
+ (bfd_elf64_size_dynamic_sections): Declare.
+ * bfd-in2.h: Rebuilt.
+
+Wed May 18 08:29:04 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * som.c: Don't include <sys/dir.h> or <sys/user.h>.
+ (som_reloc_queue_find): Call memcmp instead of bcmp.
+ (som_bfd_reloc_type_lookup): Change first argument to bfd *.
+ (compare_syms): Change types of arguments to const void *.
+ (bfd_section_from_som_symbol): Removed unused local found.
+ (som_write_armap): Add elength, map, orl_count and int arguments.
+ (som_write_armap): Use %ld and cast to long for getuid result.
+
+Wed May 18 09:09:32 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.h (R_HPPA_ABS_CALL): Define.
+ * elf32-hppa.c (hppa_elf_gen_reloc_type): Handle absolute calls.
+
+ * som.h (R_HPPA_ABS_CALL): Define.
+ * som.c (hppa_som_gen_reloc_type): Delete complex relocation types.
+
+Tue May 17 19:33:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * coff-i960.c (icoff_little_vec, icoff_big_vec): Indicate leading
+ underscore, for compatibility with Intel tool chain (gnu960v2).
+
+Mon May 16 10:09:22 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * bfd-in2.h: Rebuilt.
+
+ * elf32-hppa.c: Change .hppa_linker_stubs to .PARISC.stubs,
+ likewise for other PA specific sections.
+ (hppa_elf_relocate_unwind_table): Delete unused
+ function.
+ (elf_hppa_howto_table): Completely new table based on 94-02-02
+ draft PA ELF spec. Change relocation tags appropriately
+ throughout elf32-hppa.c
+ (hppa_elf_gen_reloc_type): Rewrite and simplify based on 94-02-02
+ spec.
+ (hppa_elf_reloc): Likewise.
+ (hppa_look_for_stubs_in_section): Likewise
+ (ELF_MACHINE_CODE): Change to EM_PARISC.
+ * elf32-hppa.h: Include "elf/hppa.h". Change relocation tags
+ appropriately throughout elf32-hppa.h.
+ (elf32_hppa_reloc_type): New table based on 94-02-02 draft PA ELF
+ spec.
+ (R_HPPA_ABS_CALL, R_HPPA_COMPLEX*, R_HPPA_UNWIND): Delete definitions.
+ * elfcode.h (prep_headers): Use EM_PARISC instead of EM_HPPA.
+ * reloc.c (bfd_reloc_code_real): Delete unused HPPA relocations.
+ * som.h (R_HPPA_ABS_CALL, R_HPPA_COMPLEX): Delete definitions.
+
+ * libhppa.h (hppa_field_adjust): Avoid adding constant_value into
+ the final value twice for LR and RR field selectors.
+
+Sat May 14 09:09:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aoutx.h (add_to_stringtab): Use BFD_ASSERT not assert. This
+ avoids __eprintf troubles.
+
+Fri May 13 10:51:21 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bout.c (b_out_bfd_reloc_type_lookup): Handle BFD_RELOC_CTOR.
+
+ * config/mipsbelf.mt (SELECT_VECS): Add ecoff_big_vec and
+ ecoff_little_vec since Irix 5 supports ECOFF executables.
+
+Wed May 11 00:31:57 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_find_nearest_line): Handle fdr.adr != pdr.adr
+ correctly.
+
+ * Makefile.in (stmp-bfd.h): Use || instead of ; to force SunOS
+ make to invoke the shell.
+
+Tue May 10 14:23:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * section.c (SEC_COFF_SHARED_LIBRARY): Renamed from
+ SEC_SHARED_LIBRARY for clarity. Changed all uses.
+ * bfd-in2.h: Rebuilt.
+ * coffcode.h (sec_to_styp_flags): If SEC_COFF_SHARED_LIBRARY is
+ set, set STYP_NOLOAD.
+ * coffgen.c (coff_section_from_bfd_index): Don't get an assertion
+ failure because of a bad shared library.
+
+Mon May 9 18:53:40 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * linker.c: Add missing comment terminator.
+
+Mon May 9 11:53:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * linker.c (_bfd_generic_link_add_one_symbol): If hashp and *hashp
+ are not NULL, assume the caller has already looked up the symbol
+ in the hash table and has stored the entry in *hashp.
+ (generic_link_add_symbol_list): Set h to NULL before calling
+ _bfd_generic_link_add_one_symbol.
+ * ecoff.c (ecoff_link_add_externals): Likewise.
+
+ * elfcode.h (assign_file_positions_except_relocs): Don't require
+ page shared between .data and .bss segments to contain zeroes.
+
+ * elfcode.h: Include bfdlink.h. Added several new functions to do
+ linking.
+ (ELF_R_TYPE): Define.
+ (bfd_add_to_strtab): Return unsigned long. Change check for
+ realloc failure.
+ (elf_fake_sections): Check return value of bfd_add_to_strtab.
+ (elf_compute_section_file_positions): Add link_info argument.
+ Call elf_backend_begin_write_processing hook and prep_headers
+ here. Only call swap_out_syms if link_info is NULL. Set up
+ .shstrtab section here. Pass dosyms argument to
+ assign_file_positions_except_relocs. Set output_has_begun flag.
+ (assign_file_positions_for_symtab_and_strtabs): Add dosyms
+ argument, and use it to control setting .symtab and .strtab file
+ positions.
+ (assign_file_positions_except_relocs): Add dosyms argument, and
+ pass it on.
+ (prep_headers): Check return value of bfd_add_to_strtab.
+ (swap_out_syms): Likewise. Also, don't set up .shstrtab here.
+ (NAME(bfd_elf,write_object_contents)): Some calls moved into
+ elf_compute_section_file_positions.
+ (elf_set_section_contents): Likewise.
+ (elf_slurp_symbol_table): SHN_LORESERV corrected to SHN_LORESERVE.
+ * libelf.h: Include bfdlink.h.
+ (struct elf_backend_data): Add fields collect,
+ elf_add_symbol_hook, elf_backend_relocate_section.
+ (struct bfd_elf_section_data): Add field rel_hashes.
+ (struct elf_obj_tdata): Remove fields internal_syms and symbols.
+ Add field sym_hashes.
+ (obj_symbols, obj_internal_syms): Remove definitions.
+ (elf_sym_hashes): Define.
+ (struct elf_link_hash_entry): Define.
+ (struct elf_link_hash_table): Define.
+ (elf_link_hash_lookup): Define.
+ (elf_link_hash_traverse): Define.
+ (elf_hash_table): Define.
+ (_bfd_elf_link_hash_table_create): Declare.
+ (bfd_elf32_bfd_link_add_symbols): Declare.
+ (bfd_elf32_bfd_final_link): Declare.
+ (bfd_elf64_bfd_link_add_symbols): Declare.
+ (bfd_elf64_bfd_final_link): Declare.
+ * elf.c: Include bfdlink.h.
+ (elf_link_hash_newfunc): New function.
+ (_bfd_elf_link_hash_table_create): New function.
+ * elf32-target.h (elf_backend_relocate_section): If not defined,
+ define as 0 and use generic linker. Otherwise, use ELF backend
+ linker.
+ (elf_backend_collect): If not defined, define as false.
+ (elf_backend_add_symbol_hook): If not defined, define as 0.
+ (elf32_bed): Initialize new fields.
+ * elf64-target.h: Same changes as elf32-target.h.
+ * elf32-i386.c: Include bfdlink.h.
+ (elf_i386_relocate_section): New function.
+ (elf_backend_relocate_section): Define.
+ * elf32-sparc.c: Include bfdlink.h.
+ (elf_info_to_howto): Change type of dst from Elf32_Internal_Rela
+ to Elf_Internal_Rela (they're the same type anyhow).
+ (elf_sparc_relocate_section): New function.
+ (elf_backend_relocate_section): Define.
+ * elf32-mips.c (elf_backend_collect): Define.
+
+ * Makefile.in (stmp-bfd.h): Avoid useless make error message in a
+ different way; touch takes a numeric argument on some systems.
+
+Fri May 6 13:34:14 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmcode.h (nlm_swap_auxiliary_headers_in): Rework custom header
+ handling for latest suggested format.
+ (nlm_swap_auxiliary_headers_out): Likewise.
+ (nlm_compute_section_file_positions): Likewise.
+
+Fri May 6 11:11:50 1994 D. V. Henkel-Wallace (gumby@rtl.cygnus.com)
+
+ * config.bfd: handle erricsson config (for OSE).
+
+Thu May 5 15:40:47 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ Patches from Ralph Campbell:
+ * mipsbsd.c (mips_fix_jmp_addr): New function.
+ (mips_fix_hi16_s): Use bfd_is_com_section.
+ (mips_howto_table_ext): Call mips_fix_jmp_addr for MIPS_RELOC_JMP.
+
+Fri May 6 11:48:55 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/go32.mh: XX support.
+
+ From bill
+ * Makefile.in: Build sysdep.h without causing worrying but
+ harmless error message.
+
+Wed May 4 11:09:53 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ Changed m68k-aout to set flags to 0; m68k-sunos still uses 1.
+ * aout0.c: New file.
+ * targets.c (aout0_big_vec): Declare.
+ (bfd_target_vector): Add aout0_big_vec.
+ * config.bfd (m68*-*-aout*): Use m68k-0aout, not m68k-aout.
+ * config/m68k-aout.mt (SELECT_VECS): Removed.
+ * config/m68k-0aout.mt: New file.
+ * configure.in (aout0_big_vec): New target vector: use aout0.o,
+ aout32.o and stab-syms.o.
+ * Makefile.in: Rebuilt dependencies.
+ (BFD32_BACKENDS): Add aout0.o.
+ (CFILES): Add aout0.c.
+
+ * libaout.h (struct aout_backend_data): Add field exec_hdr_flags.
+ * aout-target.h (MY_exec_hdr_flags): If not defined, define as 0.
+ MY(backend_data): Initialize exec_hdr_flags field.
+ * aoutf1.h (sunos_32_set_arch_mach): Make static.
+ (aout32_sunos4_write_object_contents): Set flags from backend
+ info.
+ (MY_exec_hdr_flags): If not defined, define as 1.
+ (sunos4_aout_backend): Initialize exec_hdr_flags field.
+ * aout-encap.c (encap_write_object_contents): Set flags from
+ backend info.
+ (MY_exec_hdr_flags): Define as N_FLAGS_COFF_ENCAPSULATE.
+ * hp300hpux.c (MY_exec_hdr_flags): Define as 0x2.
+ (MY(write_object_contents)): Set flags from backend info.
+ * i386aout.c (MY(backend_data)): Initialize exec_hdr_flags field.
+ * i386mach3.c (MY(backend_data)): Likewise.
+ * mipsbsd.c (MY(backend_data)): Likewise.
+ * sparclynx.c (NAME(aout,sparclynx_write_object_contents)): Set
+ flags from backend info.
+ (sparclynx_aout_backend): Initialize exec_hdr_flags field.
+
+Wed May 4 02:56:00 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config.bfd (i386-*-gnu*): Treat like i386-*-mach*.
+ (m68*-apollo-*): Treat all Apollo configs the same, don't handle
+ BSD specially.
+
+Tue May 3 19:43:21 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * cache.c: Rewrote to work correctly.
+ * libbfd.h: Rebuilt.
+ * opncls.c (bfd_cache_init, bfd_open_file): Don't declare.
+ (bfd_fdopenr): Check return value of bfd_cache_init.
+
+Fri Apr 29 15:08:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * cf-m68klynx.c (CALC_ADDEND): Check for PC relative relocs by
+ enumerating them, since the reloc type can not serve as an index
+ into the m68k COFF howto_table.
+
+Fri Apr 29 09:42:39 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config.bfd (*-go32): Changed to coff.
+ * coff-h8300.c (JMPL1): Get HOWTO right for 24bit branches.
+ * srec.c (srec_write_symbols): Write out the correct number of
+ symbols and don't stick in extra nulls.
+
+Tue Apr 26 15:07:24 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * cf-sparclynx.c (LYNXOS, COFF_LONG_FILENAMES): Define.
+ * coff-sparc.c (BADMAG): Recognize LYNXCOFFMAGIC.
+ (COFF_SPARC): Define.
+ * coffcode.h (coff_new_section_hook): If COFF_SPARC, set alignment
+ power of data and bss sections to 3.
+ * hosts/lynx.h (__LYNXOS): Define.
+
+Tue Apr 26 15:04:26 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (hppa_elf_reloc): Adjust the addend of relocations
+ against section symbols to avoid losing during ld -r.
+
+Tue Apr 26 12:16:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (shstrtab_length_fixed): Remove useless static
+ variable.
+ (struct elf_sect_data): Remove unused structure.
+ (elf_object_p): Free memory if error occurs. Check return value
+ of bfd_default_set_arch_mach. If elf_get_str_section fails,
+ preserve error code rather than setting wrong_format.
+ (null_shdr): Remove static variable.
+ (assign_section_numbers): Remove shstrtab_length_fixed assignment.
+ Allocate first section header on BFD obstack rather than using
+ null_shdr.
+ (bfd_prpsinfo): Remove unused local variable newsect.
+
+Mon Apr 25 15:31:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (write_relocs): Undo patch of Apr 10; breaks Solaris.
+
+ * elfcode.h (bfd_section_from_shdr): Use bfd_make_section_anyway
+ to create sections. Check return value of recursive calls.
+ (bfd_section_from_phdr): Check return value of bfd_make_section.
+ (elf_symbol_from_bfd_symbol): Likewise.
+ (elf_object_p): Check return value of bfd_section_from_shdr.
+ (section_from_elf_index): Likewise.
+ (elf_slurp_symbol_table): Check return value of
+ section_from_elf_index.
+ (bfd_prstatus): Return boolean value. Check return value of
+ bfd_make_section.
+ (bfd_fpregset): Likewise.
+ (bfd_prpsinfo): Return boolean value.
+ (elf_corefile_note): Check return values of bfd_prstatus,
+ bfd_fpregset, and bfd_prpsinfo.
+ (elf_core_file_p): Check return value of elf_corefile_note.
+
+Fri Apr 22 11:08:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Get rid of the ECOFF .reginfo section hack.
+ * ecoff.c (ecoff_mkobject_hook): Don't create a .reginfo section.
+ (ecoff_new_section_hook): Don't handle the .reginfo section.
+ (ecoff_sizeof_headers): Likewise.
+ (ecoff_get_section_contents): Likewise.
+ (ecoff_compute_section_file_positions): Likewise.
+ (ecoff_compute_reloc_file_positions): Likewise.
+ (ecoff_set_section_contents): Likewise.
+ (ecoff_write_object_contents): Likewise.
+ (ecoff_bfd_final_link): Likewise.
+ (ecoff_bfd_copy_private_bfd_data): Copy the GP value and the
+ register masks.
+ (bfd_ecoff_get_gp_value): New function.
+ (bfd_ecoff_set_gp_value): New function.
+ (bfd_ecoff_set_regmasks): New function.
+ * bfd-in.h (bfd_ecoff_get_gp_value): Declare.
+ (bfd_ecoff_set_gp_value): Declare.
+ (bfd_ecoff_set_regmasks): Declare.
+ * bfd-in2.h: Rebuilt.
+
+ Fix ECOFF objcopy to actually copy debugging information.
+ * ecoff.c (ecoff_bfd_copy_private_bfd_data): New function.
+ (ecoff_get_extr): Assume that any ECOFF symbol with local clear is
+ an external symbol, rather than checking the symbol flags. Only
+ check the flags for non-ECOFF symbols.
+ * ecofflink.c (bfd_ecoff_debug_externals): Don't crash if the
+ output_section field of the symbol section is NULL.
+ * libecoff.h (ecoff_bfd_copy_private_bfd_data): Declare as
+ function rather than defining as macro.
+
+ * ieee.c (ieee_object_p): Set bfd_error_got_wrong_format if
+ appropriate.
+
+ * targets.c (bfd_target_vector): Add bfd_elf32_powerpc_vec.
+
+ * aout-adobe.c (aout_adobe_set_arch_mach): Check return value of
+ bfd_default_set_arch_mach. Accept bfd_arch_m68k as well as
+ bfd_arch_unknown.
+ * coffcode.h (coff_set_arch_mach): Check return value of
+ bfd_default_set_arch_mach.
+ * elfcode.h (elf_set_arch_mach): Don't check a list of ELF
+ architectures, just see if the desired architecture matches what
+ the ELF backend permits.
+
+ * coffcode.h (coff_set_arch_mach_hook): Rename SHMAGIC to
+ SH_ARCH_MAGIC to match change in coff/sh.h.
+ (coff_set_flags): Likewise.
+
+ Follow convention in which each NLM header has an 8 byte stamp
+ followed by a four byte length.
+ * libnlm.h (struct nlm_obj_tdata): Rename nlm_cygnus_section_hdr
+ to nlm_cygnus_ext_header, and change type to
+ Nlm_Internal_Cygnus_Ext_Header.
+ (nlm_cygnus_ext_header): Rename from nlm_cygnus_section_header.
+ * nlmcode.h (nlm_swap_auxiliary_headers_in): Use CyGnUsEx instead
+ of CyGnUsSeCs. Rename from cygnus_section to cygnus_ext. Require
+ length word to be 8.
+ (nlm_swap_auxiliary_headers_out): Rename from cygnus_section to
+ cygnus_ext. Set length word to 8.
+ (nlm_compute_section_file_positions): Rename from cygnus_section
+ to cygnus_ext.
+
+Thu Apr 21 22:54:22 1994 Stu Grossman (grossman at cygnus.com)
+
+ * nlmcode.h (nlm_swap_auxiliary_headers_in): Keep section table
+ (from CyGnUsSeCs) in more permanent memory to keep section names
+ from getting trashed.
+
+Thu Apr 21 09:29:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * libelf.h (elf_obj_tdata): Add members for dynamic symbol table
+ handling.
+ * elfcode.h (bfd_section_from_shdr): Handle dynamic symbol table.
+ * elfcode.h (elf_slurp_symbol_table): Take additional parameter
+ to select static or dynamic symbol table and return number of
+ symbols slurped or -1 on error.
+ * elfcode.h (elf_get_symtab): Set bfd symcount from
+ elf_slurp_symbol_table result.
+ * elfcode.h (elf_get_dynamic_symtab_upper_bound,
+ elf_canonicalize_dynamic_symtab): New functions to handle dynamic
+ symbol table.
+ * elf32-target.h, elf64-target.h (BFD_JUMP_TABLE_DYNAMIC):
+ Change to handle dynamic symbol table, provide default definitions
+ for dynamic relocs.
+ * aoutx.h (howto_table_std, NAME(aout,swap_std_reloc_out),
+ NAME(aout,swap_std_reloc_in), aout_link_input_section_std,
+ aout_link_reloc_link_order): Handle r_jmptable and r_relative
+ relocations.
+
+Thu Apr 21 11:58:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Clean up uses of _bfd_dummy_target (from Peter Schauer).
+ * libbfd.c (_bfd_dummy_target): Set bfd_error_wrong_format.
+ * nlm-target.h (nlm_core_file_p): Define as _bfd_dummy_target, not
+ NULL.
+ * srec.c (srec_vec): Use _bfd_dummy_target, not NULL, in
+ _bfd_check_format.
+ (symbolsrec_vec): Likewise.
+ * tekhex.c (tekhex_vec): Likewise.
+
+ * libnlm.h (struct nlm_obj_tdata): Add nlm_cygnus_section_hdr
+ field.
+ (nlm_cygnus_section_header): New accessor macro.
+ * nlmcode.h (nlm_object_p): Free new tdata structure if failure.
+ Add fixed sections before swapping in auxiliary headers. After
+ adding sections, treat errors as real, not as wrong format.
+ (nlm_swap_auxiliary_headers_in): Swap in the sections header; add
+ sections to the BFD for each section it describes.
+ (nlm_swap_auxiliary_headers_out): Swap out the sections header.
+ (nlm_compute_section_file_positions): Account for the size of the
+ sections header.
+
+Wed Apr 20 16:45:51 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * coff-sparc.c (sparccoff_vec): Change minimum alignment power to
+ 2, so that stab sections can be multiples of 4 bytes only.
+
+ * hosts/i386aix.h: Changes to avoid prototypes conflicts with the
+ ones defined in stdlib.h. (From Minh Tran-Le.)
+
+Wed Apr 20 14:15:21 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlm32-ppc.c: Complete rewrite for new version of PowerPC
+ NetWare. Old code still present, but ifdeffed out.
+
+ * nlmcode.h (nlm_swap_auxiliary_headers_in): Don't assume a
+ particular format for the customer header. Allocate a block of
+ memory and read it into that.
+ (nlm_swap_auxiliary_headers_out): Write out the block of memory.
+ (nlm_compute_section_file_positions): Include length of customer
+ header when computing its size.
+
+Mon Apr 18 14:27:17 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_prep_headers): Get the space's number from the
+ backend private section data rather than target_index.
+ (bfd_som_set_section_attributes): Store the space's number
+ in the backend private section data rather than target_index.
+
+ * som.h (som_copyable_section_data_struct): Add space_number.
+
+Fri Apr 15 12:22:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-a29k.c (reloc_processing): Always set the address of a
+ R_IHCONST reloc to that of the immediately preceding R_IHIHALF.
+ gas does this anyhow, but some other assemblers seem to leave
+ garbage in the R_IHCONST address field.
+
+ * bfd/archive.c: Consistently use ARFMAG; from
+ schwab@issan.informatik.uni-dortmund.de (Andreas Schwab).
+ (_bfd_write_archive_contents): Use ARFMAG rather than '`' and
+ '\012'.
+ (bsd_write_armap): Likewise.
+ (coff_write_armap): Likewise.
+
+ * coff-mips.c (mips_relocate_section): When relaxing, adjust local
+ relocs against the .text section as required.
+ * ecofflink.c (bfd_ecoff_debug_accumulate): When relaxing, adjust
+ PDR addresses as required.
+
+ * ecoff.c (ecoff_emit_aggregate): Take fdr argument. Map fdr
+ index through rfd map if it exists. Check for a couple of cases
+ which gdb handles specially. Change all callers.
+ (ecoff_type_to_string): Take fdr argument rather than aux_ptr and
+ bigendian argument. Change all callers.
+ (ecoff_print_symbol): Handle stStruct, stUnion and stEnum.
+
+Thu Apr 14 13:05:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-mips.c (mips_howto_table): Add dummy entries to account for
+ numbering changes in include/coff/mips.h. Add entries for
+ MIPS_R_RELHI and MIPS_R_RELLO.
+ (mips_ecoff_swap_reloc_in): Handle an extra bit for the reloc type
+ when little endian. Treat internal MIPS_R_RELLO or MIPS_R_RELHI
+ relocs like MIPS_R_SWITCH, and convert r_offset from 24 to 32
+ bits.
+ (mips_ecoff_swap_reloc_out): Likewise.
+ (mips_adjust_reloc_in): Handle internal MIPS_R_RELLO or
+ MIPS_R_RELHI relocs like MIPS_R_SWITCH.
+ (mips_adjust_reloc_out): Likewise.
+ (mips_relhi_addr, mips_relhi_addend): New static variables.
+ (mips_relhi_reloc, mips_rello_reloc): New functions.
+ (mips_bfd_reloc_type_lookup): Turn BFD_RELOC_PCREL_HI16_S into
+ MIPS_R_RELHI and turn BFD_RELOC_PCREL_LO16 into MIPS_R_RELLO.
+ (mips_relocate_hi): Rename from mips_relocate_refhi, and add pcrel
+ argument. Changed all callers.
+ (mips_relocate_section): Rename got_reflo to got_lo and
+ reflo_int_rel to lo_int_rel. Handle MIPS_R_RELLO and MIPS_R_RELHI
+ relocs.
+ (mips_relax_section): Adjust MIPS_R_RELHI/MIPS_R_RELLO pairs when
+ expanding a PC relative call.
+
+ * reloc.c (bfd_reloc_code_real_type): Add BFD_RELOC_PCREL_HI16_S
+ and BFD_RELOC_PCREL_LO16.
+ * bfd-in2.h: Rebuilt.
+
+Wed Apr 13 11:50:07 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * coff-sparc.c (sparccoff_vec): Set minimum alignment power to 3.
+
+Tue Apr 12 13:36:20 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_write_fixups): Always emit at least
+ one relocation for any non-bss section.
+
+Mon Apr 11 14:41:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (assign_file_positions_except_relocs): Don't require
+ the file alignment to correspond to the page size when linking
+ with -N.
+
+Sun Apr 10 01:02:24 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elfcode.h (write_relocs): For rela relocations, adjust the
+ addend for relocations involving section symbols to account
+ for the lossage of 1:1 mapping from input section symbols to
+ output section symbols.
+
+Fri Apr 8 12:22:02 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (NAME(aout,make_sections)): New function.
+ (NAME(aout,some_aout_object_p)): Call NAME(aout,make_sections)
+ rather than making sections inline.
+ (NAME(aout,mkobject)): Don't make any sections.
+ (NAME(aout,adjust_sizes_and_vmas)): Call NAME(aout,make_sections).
+ (NAME(aout,final_link)): Don't dereference obj_textsec (abfd) or
+ obj_datasec (abfd) if they are NULL.
+ * libaout.h (NAME(aout,make_sections)): Declare.
+ * bout.c (b_out_mkobject): Don't make any sections.
+ (b_out_write_object_contents): Call aout_32_make_sections.
+ (b_out_set_section_contents): Likewise.
+ * i386os9k.c (os9k_mkobject): Don't make any sections.
+ (os9k_write_object_contents): Call aout_32_make_sections.
+ (os9k_set_section_contents): Likewise.
+
+ * aoutx.h (NAME(aout,new_section_hook)): Don't set N_EXT in target
+ index.
+
+Wed Apr 6 20:44:56 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config.bfd, configure.host: Add mips-*-sysv4* support.
+
+Thu Apr 7 14:23:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-mips.c (mips_howto_table): Add entry for MIPS_R_SWITCH.
+ (mips_ecoff_swap_reloc_in): For MIPS_R_SWTICH, copy r_symndx into
+ r_offset and set r_symndx to RELOC_SECTION_TEXT.
+ (mips_ecoff_swap_reloc_out): For MIPS_R_SWITCH, get the r_symndx
+ value from the r_offset field.
+ (mips_adjust_reloc_in): Maximum r_type value is now MIPS_R_SWITCH.
+ For MIPS_R_SWITCH, copy the r_offset field into the addend field.
+ (mips_adjust_reloc_out): For MIPS_R_SWITCH, copy the addend field
+ into the r_offset field.
+ (mips_switch_reloc): New function.
+ (mips_bfd_reloc_type_lookup): Translate BFD_RELOC_GPREL32 into
+ MIPS_R_SWITCH.
+ (mips_relocate_section): Handle MIPS_R_SWITCH.
+ (mips_relax_section): Adjust MIPS_R_SWITCH offset if necessary.
+
+Thu Apr 7 11:10:51 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elfcode.h (elf_set_section_contents): Support calling the backend
+ function elf_backend_begin_write_processing when just beginning to
+ write an object file.
+
+ * libelf.h (elf_backend_begin_write_processing): Declare.
+
+ * elf{32,64}-target.h (elf_backend_begin_write_processing): Provide
+ a default definition.
+ (elf{32,64}_bed): Add elf_backend_begin_write_processing.
+
+ * elf32-hppa.h (elf_hppa_tc_symbol): Delete extern declaration.
+ (elf_hppa_tc_make_sections): Likewise.
+
+ * elf32-hppa.c (symext_chain_built): Delete.
+ (symext_chain_size): Renamed from symextn_contents_real_size.
+ (elf32_hppa_backend_{begin,final}_write_processing): New functions.
+ (add_entry_to_symext_chain): New function.
+ (hppa_elf_set_section_contents): Ignore writes to the symbol extension
+ section until it's been rebuilt internally.
+ (hppa_elf_get_section_contents): Symbol extension section is no
+ longer special.
+ (elf_backend_{begin,final}_write_processing): Define.
+ (elf_hppa_tc_make_sections): Simplify now that much code has
+ migrated into elf32_hppa_backend_{being,final}_write_processing.
+
+Wed Apr 6 17:24:14 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add new target vectors to read the dynamic symbols and dynamic
+ relocs. Change a.out to use these rather than reading the dynamic
+ symbols and relocs along with the normal symbols and relocs.
+ * targets.c (bfd_target): Add fields
+ _bfd_get_dynamic_symtab_upper_bound,
+ _bfd_canonicalize_dynamic_symtab,
+ _bfd_get_dynamic_reloc_upper_bound,
+ _bfd_canonicalize_dynamic_reloc.
+ (BFD_JUMP_TABLE_DYNAMIC): Define.
+ * libbfd-in.h (_bfd_nodynamic_get_dynamic_symtab_upper_bound):
+ Define.
+ (_bfd_nodynamic_canonicalize_dynamic_symtab): Define.
+ (_bfd_nodynamic_get_dynamic_reloc_upper_bound): Define.
+ (_bfd_nodynamic_canonicalize_dynamic_reloc): Define.
+ * bfd.c (bfd_get_dynamic_symtab_upper_bound): Define.
+ (bfd_canonicalize_dynamic_symtab): Define.
+ (bfd_get_dynamic_reloc_upper_bound): Define.
+ (bfd_canonicalize_dynamic_reloc): Define.
+ * sunos.c (MY_read_dynamic_symbols): Don't define.
+ (MY_read_dynamic_relocs): Don't define.
+ (MY_get_dynamic_symtab_upper_bound): Define.
+ (MY_canonicalize_dynamic_symtab): Define.
+ (MY_get_dynamic_reloc_upper_bound): Define.
+ (MY_canonicalize_dynamic_reloc): Define.
+ (struct sunos_dynamic_info): Change type of dynsym_count and
+ dynrel_count to long. Add fields canonical_dynsym and
+ canonical_dynrel.
+ (sunos_read_dynamic_info): Check that BFD had DYNAMIC flag set.
+ Clear info->canonical_dynsym and info->canonical_dynrel.
+ (MY(read_dynamic_symbols)): Removed.
+ (MY(read_dynamic_relocs)): Removed.
+ (sunos_get_dynamic_symtab_upper_bound): New function.
+ (sunos_canonicalize_dynamic_symtab): New function.
+ (sunos_get_dynamic_reloc_upper_bound): New function.
+ (sunos_canonicalize_dynamic_reloc): New function.
+ * libaout.h: Declare struct reloc_ext_external and
+ reloc_std_external to avoid prototype problems.
+ (struct aout_backend_data): Remove fields read_dynamic_symbols and
+ read_dynamic_relocs.
+ (NAME(aout,translate_symbol_table)): Declare.
+ (NAME(aout,swap_ext_reloc_in)): Declare.
+ (NAME(aout,swap_std_reloc_in)): Declare.
+ * aoutx.h (NAME(aout,translate_symbol_table)): Renamed from
+ translate_symbol_table and made non-static. Changed all callers.
+ (NAME(aout,slurp_symbol_table)): Don't read dynamic symbols.
+ (NAME(aout,slurp_reloc_table)): Don't read dynamic relocs.
+ (NAME(aout,get_reloc_upper_bound)): Don't count dynamic relocs.
+ * aoutf1.h (aout_32_sunos4_write_object_contents): Don't bother to
+ remove dynamic symbols and relocs. They will no longer be
+ present.
+ (MY_read_dynamic_symbols): Don't define.
+ (MY_read_dynamic_relocs): Don't define.
+ (sunos4_aout_backend): Don't initialize dynamic entry points.
+ * aout-target.h (MY_read_dynamic_symbols): Don't define.
+ (MY_read_dynamic_relocs): Don't define.
+ (MY(backend_data)): Don't initialize dynamic entry points.
+ (MY_get_dynamic_symtab_upper_bound): If not defined, define to
+ _bfd_nodynamic version.
+ (MY_canonicalize_dynamic_symtab): Likewise.
+ (MY_get_dynamic_reloc_upper_bound): Likewise.
+ (MY_canonicalize_dynamic_reloc): Likewise.
+ * All backends: Added BFD_JUMP_TABLE_DYNAMIC to target vector.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+
+ * cf-m68klynx.c: Include sysdep.h.
+
+ * hp300hpux.c: Removed some spaces in uses of NAME to avoid
+ problems with traditional C compilers.
+
+ * targets.c (bfd_target): Rearranged fields in target vector.
+ Removed _bfd_debug_info_start, _bfd_debug_info_end and
+ _bfd_debug_info_accumulate, which were never used.
+ (BFD_JUMP_TABLE_GENERIC, BFD_JUMP_TABLE_COPY): Defined.
+ (BFD_JUMP_TABLE_CORE, BFD_JUMP_TABLE_ARCHIVE): Defined.
+ (BFD_JUMP_TABLE_SYMBOLS, BFD_JUMP_TABLE_RELOCS): Defined.
+ (BFD_JUMP_TABLE_WRITE, BFD_JUMP_TABLE_LINK): Defined.
+ * All backends: Changed to use the new BFD_JUMP_TABLE_* macros
+ rather than the single JUMP_TABLE macro. Removed many of the
+ weird macro definitions needed to support the monolithic
+ JUMP_TABLE.
+ * bfd-in.h (JUMP_TABLE): Removed.
+ * libbfd-in.h: Define a bunch of macros, and declare a few
+ functions, for use with the new BFD_JUMP_TABLE_* macros.
+ * libbfd.c (_bfd_dummy_new_section_hook): Removed.
+ (bfd_false): Set bfd_error_invalid_operation.
+ (bfd_nullvoidptr): Likewise.
+ (bfd_n1): New function.
+ (_bfd_nocore_core_file_matches_executable_p): Renamed from
+ _bfd_dummy_core_file_matches_executable_p.
+ (_bfd_nocore_core_file_failing_command): Similar rename. Set
+ bfd_error_invalid_operation.
+ (_bfd_nocore_core_file_failing_signal): Likewise.
+ (_bfd_generic_get_section_contents): Renamed from
+ bfd_generic_get_section_contents. Changed all callers.
+ (_bfd_generic_set_section_contents): Similar rename.
+ * ieee.c: #if 0 out ieee_bfd_debug_info_start,
+ ieee_bfd_debug_info_end, ieee_bfd_debug_info_accumulate. They
+ were never called.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+
+Tue Apr 5 22:10:04 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Crude support for examining dynamic libraries.
+ * som.c (som_object_setup): Set DYNAMIC flag for SHL_MAGIC and
+ DL_MAGIC objects.
+ (som_prep_headers): Preserve the system_id for DYNAMIC objects.
+ Use SHL_MAGIC as the magic number of the DYNAMIC flag is set.
+ Write exec headers for DYNAMIC objects.
+ (som_begin_writing): DYNAMIC objects have the same alignment
+ restrictions as D_PAGED objects.
+ (bfd_section_from_som_symbol): Treat DYNAMIC objects like EXEC_P
+ objects.
+ (object_flags): Add DYNAMIC.
+
+Tue Apr 5 17:48:52 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * i386lynx.c, sparclynx.c (NAME): Remove embedded whitespace in
+ macro uses, confuses some non-ANSI compilers.
+
+Tue Apr 5 15:50:01 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_free_cached_info): Add missing PARAMS decl.
+ Don't free anything if we don't have a bfd_object.
+ (som_close_and_cleanup): Call som_bfd_free_cached_info.
+
+Tue Apr 5 11:22:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-mips.c (mips_elf_final_link): Don't remove empty sections.
+ It turns out not to be required on Irix 5, and it causes problems
+ if the sections happen to contain symbols.
+
+ * elfcode.h (write_shdrs_and_ehdr): Correct bfd_write check.
+
+ * aoutx.h (NAME(aout,canonicalize_reloc)): Don't error out if
+ section->relocation is NULL; malloc might have returned NULL when
+ given a zero size if there were no relocations.
+ * bout.c (b_out_canonicalize_reloc): Likewise.
+ * coffcode.h (coff_canonicalize_reloc): Likewise.
+ * ecoff.c (ecoff_canonicalize_reloc): Likewise.
+ * elfcode.h (elf_canonicalize_reloc): Likewise.
+ * mipsbsd.c (MY(canonicalize_reloc)): Likewise.
+ * i386lynx.c (NAME(lynx,canonicalize_reloc)): Likewise.
+ * nlmcode.h (nlm_canonicalize_reloc): Likewise.
+ * som.c (som_canonicalize_reloc): Likewise.
+ * hp300hpux.c (MY(slurp_reloc_table)): Likewise. Also, if malloc
+ returns NULL, don't report an error if we asked for zero bytes.
+ * i386lynx.c (NAME(lynx,slurp_reloc_table)): If malloc returns
+ NULL, don't report an error if we asked for zero bytes.
+ * nlmcode.h (nlm_slurp_reloc_fixups): Likewise.
+
+Mon Apr 4 15:30:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (NAME(aout,bfd_free_cached_info)): Don't free anything
+ if we don't have a bfd_object.
+
+ Made sure that every call to bfd_read, bfd_write, and bfd_seek
+ checks the return value and handled bfd_error correctly. These
+ changes are not itemised. Also:
+ * aoutx.h (emit_strtab): Change return type to boolean, and return
+ errors.
+ (NAME(aout,write_syms)): Check emit_strtab return value.
+ (NAME(aout,final_link)): Likewise.
+ * coffcode.h (coff_write_relocs): Change return type to boolean,
+ and return errors.
+ (coff_write_object_contents): Check coff_write_relocs return
+ value.
+ * i386os9k.c (os9k_swap_exec_header_in): Change return type to
+ boolean.
+ (os9k_object_p): Check os9k_swap_exec_header_in return value.
+ * oasys.c (oasys_read_record): Change return type to boolean.
+ (oasys_slurp_symbol_table: Check oasys_read_record return value.
+ (oasys_object_p, oasys_slurp_section_data): Likewise.
+ (oasys_write_record): Change return type to boolean.
+ (oasys_write_syms): Likewise. Also, check oasys_write_record
+ return value.
+ (oasys_write_sections): Check oasys_write_record return value.
+ (oasys_write_header): Change return type to boolean. Check
+ oasys_write_record return value.
+ (oasys_write_end, oasys_write_data): Likewise.
+ (oasys_write_object_contents): Check return values of
+ oasys_write_header, oasys_write_syms, oasys_write_data, and
+ oasys_write_end.
+ * srec.c (srec_write_record): Change return type to boolean.
+ (srec_write_header): Likewise. Also, check srec_write_record
+ return value.
+ (srec_write_section, srec_write_terminator): Likewise.
+ (srec_write_symbols): Change return type to boolean.
+ (internal_srec_write_object_contents): Check return value of
+ srec_write_symbols, srec_write_header, srec_write_section, and
+ srec_write_terminator.
+
+ * Makefile.in: Rebuilt dependencies.
+
+Mon Apr 4 10:56:45 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * aix386-core.c (aix386_bfd_is_local_label): Correct cast from
+ asection to asymbol.
+ * ptrace-core.c (ptrace_unix_bfd_is_local_label): Correct cast from
+ bfd to asymbol.
+ * trad-core.c (trad_unix_bfd_is_local_label): Correct cast from
+ asection to asymbol.
+
+Sun Apr 3 18:27:29 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_slurp_string_table): Use malloc to allocate space
+ for the cached copy of the native string table.
+ (som_slurp_symbol_table): Likewise for the native symbol table.
+ (som_slurp_reloc_table): Likewise for the native and generic
+ relocation tables.
+ (som_bfd_free_cached_info): Free the cached native strings,
+ symbols, and relocations. Also free the canonical cached
+ relocations.
+
+Fri Apr 1 12:40:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_link_write_symbols): If keep_memory is false, make
+ sure the symbol name is stored in permanent memory before adding
+ it to the string table.
+
+ * archive.c (_bfd_write_archive_contents): Once we've found an
+ object, don't bother to look for more when deciding whether to
+ build a map.
+ (compute_and_write_armap): After adding the symbols for a BFD,
+ call bfd_free_cached_info on it.
+
+ Add bfd_free_cached_info support to a.out backends.
+ * aoutx.h (aout_get_external_symbols): Renamed from
+ aout_link_get_symbols. Read strings even if symbols have been
+ read. Store string size in obj_aout_string_size.
+ (NAME(aout,slurp_symbol_table)): Call aout_get_external_symbols to
+ read the symbols. Allocate the cached symbols with malloc, not
+ bfd_alloc.
+ (NAME(aout,slurp_reloc_table)): Allocate the cached relocs with
+ malloc, not bfd_alloc.
+ (NAME(aout,bfd_free_cached_info)): New function; free cached
+ symbols and relocs.
+ * libaout.h (struct aoutdata): Add external_string_size field.
+ (obj_aout_external_string_size): New accessor macro.
+ (NAME(aout,close_and_cleanup)): Don't declare.
+ (NAME(aout,bfd_free_cached_info)): Declare.
+ (aout_32_close_and_cleanup): Don't define.
+ (aout_64_close_and_cleanup): Don't define.
+ * aout-target.h (MY_bfd_free_cached_info): If not already defined,
+ define as NAME(aout,free_cached_info).
+ (MY_close_and_cleanup): If not already defined, define as
+ MY_bfd_free_cached_info.
+ * aout-adobe.c (aout_32_close_and_cleanup): Define.
+ (aout_32_bfd_free_cached_info): Don't define.
+ * bout.c (aout_32_close_and_cleanup): Define.
+ (aout_32_bfd_free_cached_info): Don't define.
+ * hp300hpux.c (MY_bfd_free_cached_info): Define as bfd_true.
+ (MY_close_and_cleanup): Don't define.
+ * i386lynx.c (NAME(lynx,slurp_reloc_table)): Allocate the cached
+ relocs with malloc, not bfd_alloc.
+ * i386os9k.c (aout_32_close_and_cleanup): Define.
+ (aout_32_bfd_free_cached_info): Don't define.
+
+ Add a new entry point to free memory cached by a BFD.
+ * targets.c (bfd_target): Add _bfd_free_cached_info field.
+ * bfd.c (bfd_free_cached_info): Define.
+ * bfd-in.h (JUMP_TABLE): Add _bfd_free_cached_info.
+ * bfd-in2.h: Rebuilt.
+ * All backends: Initialize bfd_free_cached_info entry point to
+ bfd_true.
+
+ * elf32-hppa.c (elf_hppa_reloc_type_lookup): Correct type of
+ first, unused, argument.
+ (hppa_elf_is_local_label): Declare instead of
+ som_bfd_is_local_label.
+
+ * coff-a29k.c (a29k_reloc): Add reloc_entry->address to value of
+ absolute R_IREL reloc.
+
+Thu Mar 31 11:52:15 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Added some support for Irix 4 shared libraries.
+ * ecoff.c (ecoff_new_section_hook): Set SEC_SHARED_LIBRARY for a
+ .lib section.
+ (ecoff_sec_to_styp_flags): Set SEC_SHARED_LIBRARY if
+ STYP_ECOFF_LIB bit is set.
+ (ecoff_compute_section_file_positions): Round the contents of a
+ .lib section up to the next page boundary.
+ (ecoff_set_section_contents): If we see a .lib section, increment
+ the vma by one to count the number of shared libraries we have.
+ (ecoff_write_object_contents): Don't crash if we see a
+ STYP_ECOFF_LIB section, and don't adjust text_start or data_start
+ or bss_size either.
+
+ * coffcode.h (CALC_ADDEND): Change to fetch original symbol value
+ from original BFD, rather than using value of current BFD symbol.
+ Needed for new linker.
+ * coff-sparc.c (CALC_ADDEND): Likewise.
+
+ * ecoff.c (ecoff_write_object_contents): Set the text_start and
+ data_start entries in the optional header correctly even if a text
+ or data section starts at location zero.
+
+ * reloc.c (bfd_reloc_code_real_type): Added BFD_RELOC_26 (from sef
+ and raeburn).
+ * bfd-in2.h: Rebuilt.
+
+ * nlm32-i386.c (nlm_i386_read_import): Null terminate the symbol
+ name.
+ * nlm32-alpha.c (nlm_alpha_read_import): Likewise.
+ * nlm32-sparc.c (nlm_sparc_read_import): Likewise.
+
+ * coffgen.c (coff_write_symbol): Reindented. Changed to return
+ boolean, and changed written to unsigned int *. Check error
+ returns from called functions.
+ (coff_write_alien_symbol): Likewise.
+ (coff_write_native_symbol): Likewise.
+ (coff_write_symbols): Likewise. Reworked checks on whether to
+ write symbol name to string table for clarity and to avoid core
+ dumping when given a non COFF symbol.
+ * libcoff-in.h (coff_write_symbols): Declare as returning boolean.
+ * libcoff.h: Rebuilt.
+ * coffcode.h (coff_write_object_contents): Check return value of
+ coff_write_symbols.
+
+Wed Mar 30 16:25:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Changes to let BFD return an error indication from
+ get_symtab_upper_bound, bfd_canonicalize_symtab,
+ bfd_get_reloc_upper_bound, and bfd_canonicalize_reloc. They now
+ return long instead of unsigned int, and use -1 to indicate an
+ error. Along the way, rename get_symtab_upper_bound to
+ bfd_get_symtab_upper_bound.
+ * bfd.c (bfd_get_reloc_upper_bound): Return long, and -1 on
+ errors.
+ (bfd_canonicalize_reloc): Likewise.
+ * syms.c (bfd_get_symtab_upper_bound): Renamed from
+ get_symtab_upper_bound.
+ * targets.c (bfd_target): Renamed _get_symtab_upper_bound to
+ _bfd_get_symtab_upper_bound, and changed it and
+ _bfd_canonicalize_symtab and _get_reloc_upper_bound and
+ _bfd_canonicalize_reloc to all return long.
+ * aoutx.h (NAME(aout,get_symtab)): Return long, and -1 on errors.
+ (NAME(aout,canonicalize_reloc)): Likewise.
+ (NAME(aout,get_reloc_upper_bound)): Likewise.
+ (NAME(aout,get_symtab_upper_bound)): Likewise.
+ * bout.c (b_out_canonicalize_reloc): Likewise.
+ (b_out_get_reloc_upper_bound): Likewise.
+ * coffcode.h (coff_canonicalize_reloc): Likewise.
+ * coffgen.c (coff_get_symtab_upper_bound): Likewise.
+ (coff_get_symtab): Likewise.
+ (coff_get_reloc_upper_bound): Likewise.
+ * ecoff.c (ecoff_get_symtab_upper_bound): Likewise.
+ (ecoff_get_symtab): Likewise.
+ (ecoff_canonicalize_reloc): Likewise.
+ * elfcode.h (elf_get_symtab_upper_bound): Likewise.
+ (elf_get_reloc_upper_bound): Likewise.
+ (elf_canonicalize_reloc): Likewise.
+ (elf_get_symtab): Likewise.
+ * hp300hpux.c (MY(get_symtab)): Likewise.
+ (MY(get_symtab_upper_bound)): Likewise.
+ (MY(canonicalize_reloc)): Likewise.
+ * i386lynx.c (NAME(lynx,canonicalize_reloc)): Likewise.
+ * ieee.c (ieee_slurp_external_symbols): Change return type to
+ boolean. Check for errors from get_symbol.
+ (ieee_slurp_symbol_table): Change return type to boolean. Check
+ for errors from ieee_slurp_external_symbols.
+ (ieee_get_symtab_upper_bound): Return long, and -1 on errors.
+ (ieee_get_symtab): Likewise.
+ (ieee_get_reloc_upper_bound): Likewise.
+ (ieee_canonicalize_reloc): Likewise.
+ * mipsbsd.c (MY(canonicalize_reloc)): Likewise.
+ * nlmcode.h (nlm_get_symtab_upper_bound): Likewise.
+ (nlm_get_symtab): Likewise.
+ (nlm_get_reloc_upper_bound): Likewise.
+ (nlm_canonicalize_reloc): Likewise.
+ * oasys.c (oasys_get_symtab_upper_bound): Likewise.
+ (oasys_get_symtab): Likewise.
+ (oasys_get_reloc_upper_bound): Likewise.
+ (oasys_canonicalize_reloc): Likewise.
+ * som.c (som_get_symtab_upper_bound): Likewise.
+ (som_get_symtab): Likewise.
+ (som_get_reloc_upper_bound): Likewise.
+ (som_canonicalize_reloc): Likewise.
+ * srec.c (srec_get_symtab_upper_bound): Likewise.
+ (srec_get_symtab): Likewise.
+ (srec_get_reloc_upper_bound): Define as bfd_0l.
+ (srec_canonicalize_reloc): Likewise.
+ * tekhex.c (tekhex_get_symtab): Return long, and -1 on errors.
+ (tekhex_get_symtab_upper_bound): Likewise.
+ (tekhex_get_reloc_upper_bound): Define as bfd_0l.
+ (tekhex_canonicalize_reloc): Likewise.
+ * libaout.h (NAME(aout,get_symtab_upper_bound)): Change
+ declaration to return long.
+ (NAME(aout,get_symtab)): Likewise.
+ (NAME(aout,canonicalize_reloc)): Likewise.
+ (NAME(aout,get_reloc_upper_bound)): Likewise.
+ * libcoff-in.h (coff_get_symtab_upper_bound): Likewise.
+ (coff_get_symtab): Likewise.
+ (coff_get_reloc_upper_bound): Likewise.
+ * libecoff.h (ecoff_get_symtab_upper_bound): Likewise.
+ (ecoff_get_symtab): Likewise.
+ (ecoff_canonicalize_reloc): Likewise.
+ * libelf.h (bfd_elf32_get_symtab_upper_bound): Likewise.
+ (bfd_elf32_get_symtab): Likewise.
+ (bfd_elf32_get_reloc_upper_bound): Likewise.
+ (bfd_elf32_canonicalize_reloc): Likewise.
+ (bfd_elf64_get_symtab_upper_bound): Likewise.
+ (bfd_elf64_get_symtab): Likewise.
+ (bfd_elf64_get_reloc_upper_bound): Likewise.
+ (bfd_elf64_canonicalize_reloc): Likewise.
+ * libnlm.h (nlmNAME(get_symtab_upper_bound)): Likewise.
+ (nlmNAME(get_symtab)): Likewise.
+ (nlmNAME(get_reloc_upper_bound)): Likewise.
+ (nlmNAME(canonicalize_reloc)): Likewise.
+ * archive.c (compute_and_write_armap): Use error_return and
+ no_memory_return labels rather than freeing information in various
+ places. Change storage, symcount and src_count to long. Check
+ errors from bfd_get_symtab_upper_bound and
+ bfd_canonicalize_symtab.
+ * bout.c (b_out_relax_section): Change reloc_size to long. Check
+ for errors from bfd_get_reloc_upper_bound and
+ bfd_canonicalize_reloc.
+ (b_out_get_relocated_section_contents): Likewise.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents):
+ Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-hppa.c (hppa_elf_stub_finish): Likewise.
+ (hppa_look_for_stubs_in_section): Check for errors from
+ bfd_get_symtab_upper_bound, bfd_canonicalize_symtab, and
+ bfd_canonicalize_reloc.
+ * ecofflink.c (bfd_ecoff_debug_accumulate_other): Check for errors
+ from bfd_get_symtab_upper_bound and bfd_canonicalize_symtab.
+ * linker.c (generic_link_read_symbols): Likewise.
+ (_bfd_generic_final_link): Check for errors from
+ bfd_get_reloc_upper_bound and bfd_canonicalize_reloc.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
+ * reloc16.c (bfd_coff_reloc16_relax_section): Likewise.
+ (bfd_coff_reloc16_get_relocated_section_contents): Likewise.
+ * libbfd.c (bfd_0l): New function.
+ * libbfd-in.h (bfd_0l): Declare.
+ * aix386-core.c: Change get_symtab_upper_bound, get_symtab,
+ get_reloc_upper_bound, and canonicalize_reloc to use bfd_0l rather
+ than bfd_0u.
+ * cisco-core.c, hppabsd-core.c, hpux-core.c: Likewise.
+ * irix-core.c, osf-core.c, ptrace-core.c, trad-core.c: Likewise.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * libcoff.h: Rebuilt.
+
+ * nlm32-sparc.c (nlm_sparc_read_reloc): Remove unused variables
+ temp and name.
+
+Wed Mar 30 08:33:04 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/dpx2.h: Define POSIX_UTIME.
+
+Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * i386dynix.c, config/i386-dynix.mt: New files, handling Dynix
+ variant of a.out.
+ * configure.in, config.bfd: Use them for Dynix.
+ * Makefile.in: Add dependencies for i386dynix.o.
+ * targets.c: Add definition for i386dynix_vec.
+ * hosts/symmetry.h: Do not define TRAD_CORE_USER_OFFSET for Dynix.
+ Define HOST_DATA_START_ADDR and TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
+ for Dynix. Remove inclusion of dynix3.h, Dynix bfd is now handled by
+ i386dynix.c
+
+Mon Mar 28 12:53:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (BFD32_BACKENDS): Add coff-sparc.o.
+
+ * coffcode.h (coff_set_flags): Handle bfd_arch_powerpc like
+ bfd_arch_rs6000.
+
+ * config.bfd (powerpc-*-aix*): New target; use rs6000.mt.
+ * config/rs6000.mt (SELECT_ARCHITECTURES): Add bfd_powerpc_arch.
+
+ * aoutx.h (translate_from_native_sym_flags): Set SEC_RELOC flag
+ for generated constructor section.
+
+Sun Mar 27 16:25:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_begin_writing): New approach at dealing with holes
+ in executables left by the HP linker. Does not rely on subspace
+ alignments as subspaces are *NOT* guaranteed to be properly
+ aligned in an executable (can you believe that!).
+
+Sat Mar 26 10:25:43 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_get_section_contents): New function. Do not try
+ to actually read data from a section that doesn't have either
+ SEC_LOAD or SEC_DEBUGGING set (eg $BSS$) just return true.
+
+ * libbfd.c (bfd_read): Set bfd_error as appropriate for a short
+ read. (bfd_error_system_call or bfd_error_file_truncated).
+
+ * som.c: Do not blindly set bfd_error_system_call after a
+ failing bfd_read, bfd_write, or bfd_seek. In a few places
+ (like som_object_p) override the error status set by bfd_read.
+
+ * aix386-core.c, aout-encap,c archive.c, bout.c: Likewise.
+ * coff-rs6000.c, coffgen.c ecoff.c, elf.c: Likewise.
+ * elf32-hppa.c, elfcode.h, hp300hpux.c, i386lynx.c: Likewise.
+ * nlm32-alpha.c, nlm32-i386.c, nlm32-sparc.c: Likewise.
+
+ * som.c: Check return values from several bfd_{seek,read,write}
+ calls that we just assumed were not failing.
+
+Fri Mar 25 11:44:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hosts/sysv4.h (HAVE_PROCFS): Add comments about ptx4.
+ * config/sysv4.mh: Add comment.
+ * config/symmetry.mh: Change comment.
+ * configure.host: Use sysv4, not symmetry, for i[34]86-sequent-sysv4*.
+
+Fri Mar 25 17:10:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Changes to support linker relaxing of embedded MIPS PIC code to
+ use a five instruction sequence for function calls which are out of
+ range of the bal instruction.
+ * libecoff.h (struct ecoff_section_tdata): Define.
+ (ecoff_section_data): Define.
+ (ecoff_bfd_relax_section): Don't define.
+ * ecoff.c (ecoff_final_link_debug_accumulate): Don't read or free
+ the debugging information if it has already been read.
+ (ecoff_indirect_link_order): Handle _cooked_size being different
+ from _raw_size. Don't reread the contents or the relocs if they
+ have already been read in.
+ * coff-mips.c (mips_howto_table): Change bitsize of PCREL16 from
+ 18 to 16.
+ (PCREL16_EXPANSION_ADJUSTMENT): Define.
+ (mips_relocate_refhi): Take adjust argument.
+ (mips_relocate_section): Handle reloc offsets stored in section
+ used_by_bfd field. Call mips_relax_pcrel16 to handle details of
+ expanding an out of range PCREL16. Keep trace of adjustments
+ required by expansions. Set s and unset h when converting a reloc
+ from undefined to section. Change handling of PC relative relocs:
+ if against a section, they are correct in the object file, if
+ against an external symbol they are pcrel_offset.
+ (mips_relax_section): New function.
+ (mips_relax_pcrel16): New function.
+ (ecoff_bfd_relax_section): Define.
+ * coff-alpha.c (ecoff_bfd_relax_section): Define.
+ * ecofflink.c (bfd_ecoff_debug_accumulate): Handle adjustments
+ built by mips_relax_section when writing out addresses.
+ * elf32-mips.c (mips_elf_read_ecoff_info): Clear adjust field.
+
+ * aoutx.h (NAME(aout,find_nearest_line)): The caller expects
+ functionname_ptr to be set to a symbol name, so prepend
+ symbol_leading_char.
+
+Thu Mar 24 11:33:46 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Add relaxing info
+ for 16bit relative branches.
+ * coff-h8500.c (r_high8, r_low16, r_high16): Don't complain on
+ overflow.
+
+Thu Mar 24 09:21:13 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_prep_for_ar_write): Ignore non-SOM objects.
+ (som_bfd_ar_write_symbol_stuff, som_write_armap): Likewise.
+
+Wed Mar 23 14:29:31 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * netbsd386.c (N_SET_FLAGS): Delete the old definition.
+
+Wed Mar 23 14:58:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Clean up the relaxing code for the new linker.
+ * targets.c (_bfd_relax_section): Take boolean *again argument
+ rather than asymbol list.
+ * bfd.c (bfd_relax_section): Change name of fourth argument from
+ symbols to again.
+ * reloc.c (bfd_generic_relax_section): Take boolean *again
+ argument rather than asymbol list. Always return true.
+ * bout.c: Include genlink.h.
+ (aligncode, perform_slip): Declare.
+ (perform_slip): Take BFD argument rather than asymbol list.
+ Changed all callers. Get the symbols from the BFD. Change the
+ hash table entry value as well as the symbol value.
+ (abs32code): Take BFD argument rather than asymbol list. Changed
+ all callers.
+ (aligncode): Likewise.
+ (b_out_relax_section): Take boolean *again argument rather than
+ asymbol list. Only return false if an error occurred. Set *again
+ to false. Get symbols from BFD.
+ * reloc16.c: Include genlink.h.
+ (bfd_perform_slip): Take BFD argument rather than asymbol list.
+ Get the symbols from the BFD. Change the hash table entry value
+ as well as the symbol value.
+ (bfd_coff_reloc16_relax_section): Take boolean *again argument
+ rather than asymbol list. Only return false if an error occurred.
+ Set *again to false. Get symbols from BFD.
+ * coffcode.h (bfd_coff_backend_data): Change
+ _bfd_coff_reloc16_estimate to take BFD argument rather than
+ asymbol list.
+ (bfd_coff_reloc16_estimate): Corresponding change.
+ (dummy_reloc16_estimate): Corresponding change.
+ * libcoff-in.h (bfd_coff_reloc16_relax_section): Change
+ declaration to take boolean * rather than asymbol list.
+ (bfd_perform_slip): Change declaration to take BFD rather than
+ asymbol list.
+ * coff-h8300.c (h300_reloc16_estimate): Take BFD argument rather
+ than asymbol list. Changed calls to bfd_perform_slip.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * libcoff.h: Rebuilt.
+ * Makefile.in: Rebuilt dependencies.
+
+ * genlink.h (_bfd_generic_link_get_symbols): Define.
+ (_bfd_generic_link_get_symcount): Define.
+ * linker.c (generic_link_read_symbols): New function.
+ (generic_link_add_object_symbols): Use it. Use
+ _bfd_generic_link_get_symbols and _bfd_generic_link_get_symcount
+ to get the symbols from the BFD.
+ (generic_link_check_archive_element): Likewise.
+ (_bfd_generic_final_link): Likewise.
+ (_bfd_generic_link_output_symbols): Likewise.
+ (default_indirect_link_order): Likewise.
+ (generic_link_add_symbol_list): Store pointer to hash table entry
+ in asymbol udata field.
+
+Tue Mar 22 13:09:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-mips.c (mips_howto_table): Add entry for new MIPS_R_PCREL16
+ reloc, used in embedded PIC code.
+ (mips_adjust_reloc_in): Change sanity check to permit new reloc.
+ (mips_bfd_reloc_type_lookup): Turn BFD_RELOC_16_PCREL_S2 into
+ MIPS_R_PCREL16.
+
+ * elf32-mips.c (mips_elf_final_link): Account for link_order
+ relocs when allocating space for relocations. Set SEC_RELOC flag
+ for any section which has relocs. Handle link_order relocs in
+ link_order loop. Use _bfd_generic_link_add_symbols_collect for
+ add_symbls entry point.
+
+ * linker.c (_bfd_generic_final_link): Set reloc_count to 0 before
+ counting relocs. Set SEC_RELOC flag for any section which has
+ relocs.
+
+ * linker.c (_bfd_default_link_order): Handle bfd_data_link_order.
+
+ * linker.c (_bfd_generic_link_add_symbols): Just call
+ generic_link_add_symbols.
+ (_bfd_generic_link_add_symbols_collect): New function, like
+ _bfd_generic_link_add_symbols but also collect constructors and
+ destructors by name as collect2 does.
+ (generic_link_add_symbols): New function, like old
+ _bfd_generic_link_add_symbols but with collect argument.
+ (generic_link_add_object_symbols): Take collect argument.
+ (generic_link_check_archive_element_no_collect): New function.
+ (generic_link_check_archive_element_collect): New function.
+ (generic_link_check_archive_element): Take collect argument.
+ (generic_link_add_symbol_list): Take collect argument.
+ (_bfd_generic_link_add_one_symbol): Rename constructor argument to
+ collect.
+ * libbfd-in.h (_bfd_generic_link_add_symbols_collect): Declare.
+ * libbfd.h: Rebuilt.
+
+Tue Mar 22 10:04:00 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * archive.c (bfd_construct_extended_name_table): Use ar_padchar
+ for first character in an extended name.
+ (_bfd_write_archive_contents): If ar_padchar == '/', then use
+ "//" as the name of the special archive member holding the
+ extended name table.
+
+Mon Mar 21 12:28:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Support for link_order types which generate relocs in order to
+ support -Ur in the linker.
+ * linker.c (generic_link_add_symbol_list): Remove bitsize argument
+ from call to _bfd_generic_link_add_one_symbol.
+ (_bfd_generic_link_add_one_symbol): Remove bitsize argument.
+ Don't pass bitsize to constructor call back. Pass BFD_RELOC_CTOR
+ instead of bitsize to add_to_set call back.
+ (_bfd_generic_final_link): Account for link_order relocs when
+ allocating space for relocations. Handle them in link_order loop.
+ (_bfd_generic_reloc_link_order): New function.
+ (_bfd_default_link_order): If a reloc_link_order is seen here,
+ abort.
+ (_bfd_count_link_order_relocs): New function.
+ * libbfd-in.h (_bfd_generic_link_add_one_symbol): Remove bitsize
+ argument from declaration.
+ (_bfd_generic_reloc_link_order): Declare.
+ (_bfd_count_link_order_relocs): Declare.
+ * libbfd.h: Rebuilt.
+ * aoutx.h (aout_link_add_symbols): Remove bitsize argument from
+ call to _bfd_generic_link_add_one_symbol.
+ (NAME(aout,final_link)): Account for link_order relocs when
+ allocating space for relocations. Handle them after handling all
+ input BFDs.
+ (aout_link_reloc_link_order): New function.
+ * ecoff.c (ecoff_link_add_externals): Remove bitsize argument from
+ call to _bfd_generic_link_add_one_symbol.
+ (ecoff_bfd_final_link): Account for link_order relocs when
+ allocating space for relocations. Handle them in link_order loop.
+ (ecoff_link_write_external): Set the storage class of a defined
+ linker created symbol based on the section it is in. Correct
+ bfd_link_hash_weak case to use .sc rather than .st.
+ (ecoff_reloc_link_order): New function.
+ * coff-alpha.c (alpha_bfd_reloc_type_lookup): Handle
+ BFD_RELOC_CTOR.
+ * coff-mips.c (mips_bfd_reloc_type_lookup): Likewise.
+
+ * sunos.c (sunos_read_dynamic_info): Remove unused locals dynsym
+ and buf.
+
+ * cisco-core.c (cisco_core_file_p): Only pass one argument to
+ bfd_zmalloc. Free a pointer, not a union.
+ (cisco_bfd_is_local_label): Correct cast from asection to asymbol.
+
+Sun Mar 20 09:24:36 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * bfd/som.c (som_begin_writing): Fix thinko (off by one error).
+
+ * som.c (bfd_section_from_som_symbol): Only to do the value
+ comparison for function symbols within executables.
+
+ * som.c (bfd_section_from_som_symbol): Renamed from
+ som_section_from_subspace_index. Pass in a native SOM symbol.
+ For executables, iterate through the sections to find out
+ which contains the symbol's address rather than using the
+ symbol_info field. (symbol_info has a different meaning for
+ dynamicly linked executables.)
+
+ * trad-core.c (trad_unix_core_file_p): Don't pass abfd to
+ bfd_zmalloc.
+
+ * som.c (som_begin_writing): Fix braino (one call to align
+ space/subspace data was done unconditionally rather than
+ just for executables.)
+
+ * som.c (som_begin_writing): Align text in all executables to
+ make HPUX kernel happy. Fixes strip/objcopy for shared
+ executables.
+
+Sat Mar 19 07:06:59 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_begin_writing): Account for alignment needs of
+ subspaces too when writing executables. Never request a negative
+ bss size. Fixes some problems with demand paged executables,
+ still having problems with pure executables and shared executables.
+
+Fri Mar 18 19:12:47 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * trad-core.c (trad_unix_core_file_p): Call bfd_zmalloc not
+ bfd_zalloc for rawptr, because later on we may call free, not
+ bfd_release, on it.
+
+ * bfd.c (struct _bfd): Add cisco_core_struct to tdata union.
+ * libbfd.c (bfd_read, bfd_seek): Add comments regarding errors.
+ * cisco-core.c: New file.
+ * Makefile.in: Change accordingly.
+ * configure.in: Recognize cisco_core_vec.
+ * config/m68k-aout.mt (SELECT_VECS): Add cisco_core_vec.
+ * targets.c: Add cisco_core_vec.
+ * bfd-in2.h: Rebuilt.
+
+Fri Mar 18 18:13:49 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.h (som_copyable_section_data_struct): New structure
+ containing all the private section information which needs
+ to be copied from input section to output section during
+ objcopy or strip.
+ (som_section_data_struct): Remove several fields now in
+ som_copyable_section_data_struct. Make the space and
+ subspace dictionaries be pointers (to save space when
+ only reading objects).
+
+ * som.c (bfd_som_set_section_attributes): Now returns a boolean;
+ some references changed. Allocate a copyable data stucture if
+ none exists. Store info into the copyable data structure.
+ (bfd_som_set_subsection_attributes): Likewise.
+ (som_is_space, som_is_subspace, som_is_container): New functions.
+ Use these instead of directly accessing private data.
+ (som_prep_headers): Allocate space and subspace headers here.
+ Fill in some fields in the space/subspace headers from the
+ copyable data.
+ (som_bfd_copy_private_section_data): Only copy the stuff
+ that we really need to make objcopy and strip work. Allocate
+ the copy_data structure for the output bfd before copying.
+
+ * som.h (struct som_exec_data): New structure to hold exec
+ info that must be preserved when running objcopy/strip.
+ (struct somdata): Add new "exec_data" field and accessor
+ macro. Add some comments on how the various fields are used.
+ (som_section_data_struct): Make is_space and is_subspace bitfields.
+ Delete unused subspace_index. All references now use the
+ target_index field within the section structure itself.
+
+ * som.c (make_unique_section): Delete unused declaration.
+ (som_bfd_copy_private_bfd_data): New function.
+ (som_object_setup): Allocate space for and save exec information
+ that needs to be copied during objcopy/strip.
+ (som_mkobject): Do not allocate space for a file header here.
+ It is not used when only reading SOM objects.
+ (som_prep_headers): Allocate space for and attach a file header
+ to the output bfd. For executables, use the saved system_id
+ value rather than trying to guess the right value. Do not abort
+ wwhen setting file_hdr->entry* for executables.
+ (som_begin_writing): For executables, set the exec_entry and
+ exec_flags fields.
+ (som_copy_private_backend_section_data): Always return a value.
+
+ * libhppa.h (PA_PAGESIZE): Define.
+
+ * som.c (SOM_ALIGN): Define.
+ (som_begin_writing): If writing an executable, initialize all
+ fields in the exec header to zero. Update fields in the exec
+ header as sizes of loadable subspaces are computed. Carefully
+ preserve alignments when building executables. Actually write the
+ exec after all the fields are filled in.
+
+ * Better long-filename handling. Reads SOM ABI compliant extended
+ names, but doesn't quite write compliant extended names yet.
+ * som.c (som_slurp_extended_name_table): Delete function. The
+ generic code will handle things correctly.
+ (som_slurp_armap): Seek to the beginning of the next member.
+ (normalize): New function.
+ (som_bfd_ar_write_symbol_stuff): Take the size of the extended
+ name table into account when computing the file offsets in the
+ SOM dictionary. Make sure to align to an even boundary.
+ (som_write_armap): Initialize the checksum to zero.
+ (ar_maxchars): Fix. Opps.
+
+Fri Mar 18 20:35:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * aoutx.h (reloc_type_lookup): Handle BFD_RELOC_CTOR on a 64-bit
+ machine. Handle BFD_RELOC_SPARC13 and BFD_RELOC_SPARC_BASE13.
+
+Thu Mar 17 18:26:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * bfd-in.h (BFD_VERSION): Use @VERSION@.
+ * Makefile.in (bfd.h): Replace it with contents of VERSION file.
+ * bfd-in2.h: Regenerated.
+
+ * trad-core.c (trad_unix_bfd_is_local_label): Fixed typo where
+ this was also named trad_unix_bfd_copy_private_bfd_data.
+
+Thu Mar 17 10:37:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aoutx.h, elfcode.h, coff-alpha.c, bout.c, ecoff.c, ecofflink.c,
+ elf32-hppa.c, elf32-mips.c, linker.c, som.c, sunos.c: If malloc(0)
+ returns NULL, it is not an error. It's possible that some of
+ these checks are not necessary (because the size can never be
+ zero), but putting in the checks is the conservative thing to do
+ in light of the fact that some of these malloc calls replaced
+ unchecked alloca calls, in which a zero argument would work fine.
+
+Thu Mar 17 11:44:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * osf-core.c (osf_core_bfd_copy_private_bfd_data): Remove
+ duplicate definition.
+ (osf_core_bfd_is_local_label): Define.
+
+ * reloc.c (bfd_generic_get_relocated_section_contents): Don't fail
+ if malloc (0) fails. bfd_canonicalize_reloc returning 0 is not a
+ failure indication, it merely means there are no relocs.
+
+ * elfcode.h (NAME(bfd_elf,write_object_contents)): Don't use space
+ after NAME, since SunOS /bin/cc can't handle it.
+
+Wed Mar 16 16:43:33 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * netbsd386.c (N_SET_FLAGS): Don't nuke the machine id field.
+ From sukes@glue.umd.edu (Tasuki Hirata).
+
+Wed Mar 16 07:55:54 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aoutf1.h (4 places): Use a simple #if on ARCH_SIZE, rather than
+ all that convoluted stuff with NAME, CAT3, etc. The convoluted
+ stuff broke for SunOS4 /bin/cc (due to DEFUN elimination, I guess).
+
+Wed Mar 16 00:02:05 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_prep_for_fixups): Detect section symbols based
+ on either the lack of private data or the symbol flags. Do not
+ munge section symbol names anymore -- they no longer confuse GDB.
+ (som_begin_writing): Leave space for an exec header if writing
+ an executable.
+ (som_slurp_symbol_table): Recognize both forms of section symbol
+ names "L$0\002" and "$<FOO>$". Change the name of "L$0\002"
+ section symbols to be the name of the section they represent.
+ Debugging symbols begin with "L$0\001", not just "L$".
+
+Tue Mar 15 22:58:28 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * bfd-in2.h, libbfd.h, libcoff.h: Rebuilt.
+
+ * bfd-in.h (JUMP_TABLE): Add new entries to the jump table
+ for bfd_copy_private_section_data, bfd_copy_private_bfd_data,
+ and bfd_is_local_label.
+
+ * targets.c: Add new entries to the bfd_target structure.
+
+ * bfd.c (bfd_copy_private_bfd_data): New definition.
+
+ * section.c (bfd_copy_private_section_data): New definition.
+
+ * syms.c (bfd_is_local_label): New definition.
+
+ * libbfd-in.h (bfd_generic_is_local_label): Declare.
+
+ * libbfd.c (bfd_generic_is_local_label): New function.
+
+ * *-core.c: Provide default definitions for new functions in
+ the target vector which all point to bfd_false.
+
+ * aout-target.h, coffcode.h, elf32-target.h elf64-target.h, ieee.c
+ libaout.h, libecoff.h, nlm-target.h, oasys.c, srec.c, tekhex.c
+ Default new vectors for copying private backend data to bfd_true.
+ Default new vector for determining if a symbol is a local label
+ to bfd_generic_is_local_label.
+
+ * som.c (som_bfd_copy_private_section_data): New function.
+ (som_bfd_is_local_label): New function.
+ (som_bfd_copy_private_bfd_data): For now default to bfd_true.
+
+ * elf32-hppa.c (hppa_elf_is_local_label): New function.
+
+Tue Mar 15 23:55:47 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * cf-m68klynx.c (CALC_ADDEND): Use _bfd_m68klynx_howto_table.
+
+Tue Mar 15 04:41:13 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * Most files:
+ Replace DEFUN and DEFUN_VOID with K&R-style function definition.
+ Indent some of them to GNU standards.
+
+ * aout32.c, archures.c, core.c, cpu-h8300.c, cpu-i960.c,
+ cpu-m68k.c, cpu-m88k.c, cpu-mips.c, cpu-vax.c, ctor.c, demo64.c,
+ elf32-hppa.h, gen-aout.c, host-aout.c, init.c, libhppa.h,
+ libieee.h, liboasys.h, newsos3.c, som.h, stab-syms.c, sunos.c:
+ Update copyright years.
+
+Mon Mar 14 11:41:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_prep_for_fixups): A relocation involving the section
+ symbol for the *ABS* section is really a relocation involving
+ no symbol.
+ (som_slurp_symbol_table): Do not set BSF_GLOBAL or BSF_EXPORT for
+ undefined symbols. Correctly distinguish between debugger symbols
+ and section symbols.
+
+ * som (setup_sections): Set SEC_DEBUGGING and the section attributes
+ for spaces and subspaces.
+
+ * som.c (som_bfd_count_ar_symbols): Fix typo.
+
+ * som.c (som_object_setup): Set EXEC_P, D_PAGED, WP_TEXT, and
+ HAS_RELOC based on the object's magic number.
+ (make_unique_section): Delete function. BFD and its users are
+ prepared to handle multiple sections with the same name.
+ (setup_sections): Allocate space on the BFD's obstack to hold
+ section names. Use bfd_make_setion_anyway rather than the
+ obsolete make_unique_section.
+ (som_prep_headers): Choose the correct SOM magic number based
+ on the BFD's flags.
+ (som_bfd_fill_in_ar_symbols): Return false, not NULL on error.
+
+Sat Mar 12 09:46:09 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * elf32-ppc.c: Renamed from elf32-powerpc.c.
+ * nlm32-ppc.c: Renamed from nlm32-powerpc.c.
+ * Makefile.in, configure.in: Corresponding changes.
+
+Fri Mar 11 22:27:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf32-powerpc.c: Extensive changes to update to preliminary ABI.
+
+Fri Mar 11 00:34:59 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sunos.c (sunos_read_dynamic_info): Assume that dynamic info
+ is always located at the start of the data section to allow
+ recovery of the dynamic info from a stripped executable.
+ * ecoff.c (ecoff_styp_to_sec_flags): Handle STYP_PDATA, STYP_XDATA
+ and STYP_COMMENT.
+
+Wed Mar 9 17:17:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * libbfd-in.h: Remove alloca cruft. It was missing some necessary
+ cruft (like the #pragma alloca for AIX).
+ In addition to that problem, the C alloca calls xmalloc, which
+ means checking for being out of memory can't work right. The
+ following changes remove all uses of alloca from BFD.
+ * hosts/solaris2.h: Remove alloca cruft.
+ * som.c: Replace alloca with a fixed size auto array.
+ * aoutx.h, elfcode.h, nlmcode.h, bout.c, coff-alpha.c, ecoff.c,
+ ecofflink.c, elf32-hppa.c, elf32-mips.c, linker.c, reloc.c, som.c,
+ sunos.c: Replace alloca with malloc and appropriate error checking and
+ freeing.
+ * linker.c: Replace alloca with obstack_alloc.
+ * libbfd.h: Rebuilt.
+
+Tue Mar 8 12:10:38 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * coff-mips.c (mips_relocate_section): Handle MIPS_R_LITERAL like
+ MIPS_R_GPREL.
+
+Sat Mar 5 14:08:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elf32-hppa.h, elfcode.h: Replace uses of Elf*_Half, Elf*_Word,
+ Elf*_Off typedefs by their expansion, the typedefs have been
+ removed from include/elf/internal.h.
+ * elfcode.h (bfd_section_from_shdr): Handle SHT_DYNAMIC section like
+ SHT_PROGBITS section.
+
+Thu Mar 3 20:03:39 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.h (_PA_RISC_ID): Treat HOST_HPPAOSF just like HOST_HPPABSD.
+
+Wed Mar 2 13:28:06 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * configure.host: Recognize i[34]86-sequent-*.
+
+ * trad-core.c (trad_unix_core_file_p): A non-zero, not zero,
+ return from bfd_seek indicates an error.
+ New macro TRAD_CORE_DSIZE_INCLUDES_TSIZE to replace
+ TRAD_CORE_STACK_OFFSET.
+ * hosts/symmetry.h: Define TRAD_CORE_DSIZE_INCLUDES_TSIZE and
+ TRAD_CORE_USER_OFFSET but not HOST_STACK_OFFSET.
+
+Wed Mar 2 11:57:03 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.[ch]: Do not include libhppa.h in som.c, instead include
+ it in som.h.
+
+ * elf32-hppa.[ch]: Do not include libhppa.h in elf32-hppa.c, instead
+ include it in elf32-hppa.h.
+
+ * som.c (log2): Return -1 on error rather than aborting.
+ (setup_sections): Bubble up an error from log2.
+
+ * Changes to make HP C compiler happy in both traditional
+ and ANSI mode.
+ * som.c (hppa_som_gen_reloc_type): Use correct enum type for
+ field parameter.
+ (bfd_som_set_section_attributes): Use unsigned int rather than
+ unsigned char to avoid GNU-C extensions.
+ (bfd_som_attach_aux_hdr): Return a boolean to indicate success
+ or failure rather than aborting on failure.
+
+ * som.h (bfd_som_set_section_attributes): Fix prototype to match
+ som.c changes.
+ (bfd_som_attach_aux_hdr): Add prototype.
+ (hppa_som-gen_reloc_type): Likewise.
+
+ * elf32-hppa.c: Add a couple casts to make HP compiler happy.
+ (hppa_look_for_stubs_in_section): Do not return false on failure
+ until rest of code is ready to handle it. Abort for now.
+
+Tue Mar 1 18:33:59 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * bfd-in2.h: Rebuilt.
+
+Tue Mar 1 13:06:53 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * i386os9k.c: use new functions bfd_set_error and bfd_get_error.
+ * Makefile.in: delete an extra blank.
+ * configure.in : Add i396os9k_vec.
+
+Mon Feb 28 15:41:01 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config.bfd : Add i386-os9k.
+ * config/i386-os9k.mt : Newly add os9k target makefile.
+
+ * i386os9k.c : new file to handle os9k format bfd.
+ * Makefile.in : Handle new file i386os9k.c
+ * targets.c : Add bfd_target_os9k_flavour and i386os9k_vec.
+ * cache.c : Initialize cache_sentinel to 0.
+
+Sun Feb 27 16:30:55 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (mismatches, retval_mismatches): Fix mismatch
+ action in case where caller specified no argument relocation.
+ (hppa_elf_build_linker_stub): Try again to get the sym_ptr_ptr
+ right in the original relocation and the stub's relocation.
+
+ * elf32-hppa.h (hppa_look_for_stub_in_section): Fix typo. Delete
+ unused symbols argument.
+
+ * elf32-hppa.c (hppa_elf_stub_reloc): Accept asymbol ** rather
+ than asymbol * for original target symbol. All callers changed.
+ Set reloc->sym_ptr_ptr appropriately.
+ (hppa_elf_build_linker_stub): Set reloc->sym_ptr_ptr correctly.
+ (hppa_elf_look_for_stubs_in_section): No longer need symbols
+ argument. Use the output symbols when canonicalizing the relocs,
+ creating them if necessary.
+
+ * linker.c (_bfd_generic_link_output_symbols): Do not
+ rebuild/clobber the output symbols if they already exist.
+
+Sun Feb 27 15:22:36 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * targets.c (BFD_SEND, BFD_SEND_FMT): Add debugging versions that
+ check all the pointer dereferences. Enabled via DEBUG_BFD_SEND.
+ * bfd-in2.h: Rebuilt.
+
+ * srec.c (hex_value): Always set to a size of 256 bytes.
+ (srec_init): Cosmetic changes.
+
+Sun Feb 27 11:18:47 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c: Second half of major cleanup. More comments,
+ PARAMize and staticize rest of functions. Delete unused
+ functions. Delete unused/unnecessary arguments to some functions.
+ Group static vars together. Abort for bad errors until we have
+ error code propogation working. Work on spacing and indention.
+ Add FIXMEs for unresolved problems. Use enums rather than
+ #defines for lots of things. Merge two functions which build
+ linker stubs into a single function (so they can easily share a
+ ton of common code).
+
+Sat Feb 26 10:00:45 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * reloc.c (_bfd_relocate_contents): Adjust handling of overflow to
+ avoid depending upon right shifts of signed numbers, and to
+ correct handling of src_mask with lower bits zero.
+
+ * aoutx.h, archive.c: Add casts to avoid warnings from SVR4 cc.
+ * ecoff.c, ecofflink.c, ecoffswap.h, srec.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elfcode.h (bfd_section_from_shdr): Make i unsigned; remove old
+ #if 0 code.
+ (elf_write_phdrs): Make i unsigned.
+ (map_program_segments): Make i and n_left unsigned.
+ (assign_file_positions_except_relocs): Make i unsigned.
+ (write_shdrs_and_ehdr): Make count unsigned.
+ (assign_file_positions_for_relocs): Make i unsigned.
+ (NAME(bfd,elf_write_object_contents)): Make count unsigned.
+ (section_from_elf_index): Make index argument unsigned.
+
+Fri Feb 25 21:34:58 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * elfcode.h: Don't include assert.h.
+ (swap_out_syms): Use BFD_ASSERT rather than assert.
+
+ * linker.c (_bfd_generic_link_write_global_symbol): Add missing
+ break in switch.
+
+ * hosts/i386v4.h (qsort, strtol): Remove incorrect and useless
+ declarations.
+
+Fri Feb 25 16:35:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * libhppa.h (hppa_rebuild_insn): Moved here from elf32-hppa.c.
+
+ * elf32-hppa.h (elf_hppa_tc_symbol): Add new arguments.
+ (elf_hppa_tc_make_sections): Likewise.
+ (elf_hppa_final_processing): Add extern decl.
+
+ * elf32-hppa.c: First half of major cleanup. Add/cleanup lots of
+ comments. PARAMize some static functions. Delete unused functions.
+ Delete unused/unnecessary arguments to many functions. Group
+ static vars together. Collapse common case statements together
+ in many places. Use default case when possible instead of listing
+ each case separately. Abort for bad errors until we get error
+ code propogation working. Work on spacing and indention problems.
+ Add FIXMEs for some unresolved problems. Delete hopelessly broken
+ COMPLEX relocation support (it's never used anyway).
+ (hppa_elf_rebuild_insn): Delete. Moved into libhppa.h.
+ (elf_hppa_tc_symbol): Accept and use new arguments (symext chains).
+ (elf_hppa_tc_make_sections): Likewise.
+
+ * format.c (bfd_check_format_matches): Initialize matching_vector
+ to keep gcc -Wall quiet.
+
+ * elfcode.h (elf_slurp_reloca_table): Fix typo.
+
+ * som.c (som_get_symtab_upper_bound): Use "sizeof (asymbol *)"
+ not "sizeof (som_symbol_type *)".
+
+ * elfcode.h (elf_get_symtab_upper_bound): Use "sizeof (asymbol *)"
+ not "sizeof (asymbol"). Opps.
+
+Fri Feb 25 13:19:04 1994 Ted Lemon (mellon@pepper.ncd.com)
+
+ * bfd.c (bfd_get_gp_size): Can't return gp value on an archive.
+ (bfd_set_gp_size): Can't set gp value on an archive.
+
+Fri Feb 25 12:57:00 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * srec.c (pass_over): Don't skip too many characters when
+ end of line seen.
+
+Fri Feb 25 11:41:57 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.c (ecoff_sizeof_headers): Align result to 16 byte
+ boundary.
+
+Thu Feb 24 07:13:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_derive_misc_symbol_info): Derive symbol_info
+ field for absolute symbols in the same manner as undefined
+ and common symbols.
+
+Thu Feb 24 04:29:19 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfcode.h (elf_core_file_p): Check for core file e_machine match
+ like in elf_object_p.
+
+Wed Feb 23 18:28:37 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elfcode.h (alloca): Delete declaration.
+
+ * som.c (som_prep_headers): Use CPU_PA_RISC1_0 for magic
+ number rather than HP9000S800_ID. Note som.c is careful
+ to make sure CPU_PA_RISC1_0 is always defined.
+
+Mon Feb 21 10:12:02 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (targets.o, archures.o): Use ALL_CFLAGS to supply
+ flags to explicit compile actions.
+
+Mon Feb 21 09:50:06 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * ecofflink.c (ecoff_write_symhdr): Set symhdr->magic here.
+ * ecoff.c (ecoff_write_object_contents): Make sure .bss section
+ ends on a page boundary if there is no symbol table.
+ (ecoff_bfd_final_link): Don't set symhdr->magic here.
+
+ * hosts/hp300.h: Include <stdlib.h>; don't declare free.
+
+ * som.c (som_bfd_count_ar_symbols): Use a pointer and alloca
+ rather than an array of variable size.
+ (som_bfd_fill_in_ar_symbols): Likewise.
+ (som_bfd_ar_write_symbol_stuff): Likewise.
+
+ * coff-alpha.c (alpha_relocate_section): Rewrite mask and shift
+ operation to avoid OSF 1.3 cc bug.
+ * ecoff.c (ecoff_write_object_contents): Make text_size, data_size
+ and bss_size bfd_size_type instead of unsigned long. Make
+ text_start and data_start bfd_vma instead of unsigned long.
+ * ecofflink.c (ecoff_add_string): Remove incorrect cast of return
+ value.
+
+Sun Feb 20 16:06:54 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * linker.c (_bfd_generic_link_add_archive_symbols): Consider
+ symbols in the order they appear in the archive map.
+
+Sat Feb 19 03:17:32 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * coff-alpha.c (reloc_nil): Add forward declaration, add missing
+ error_message argument.
+ * coff-sparc.c (bfd_coff_generic_reloc): Add forward declaration,
+ add missing error_message argument.
+ * mipsbsd.c (mips_fix_hi16_s): Add forward declaration, add missing
+ error_message argument.
+
+Fri Feb 18 11:41:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Support for PowerPC NetWare.
+ * nlm32-powerpc.c: New file.
+ * config.bfd (powerpc-*-netware*): New target; use ppc-nlm.
+ * config/ppc-nlm.mt: New file.
+ * configure.in (nlm32_powerpc_vec): New target vector; use
+ nlm32-powerpc.o, nlm32.o, nlm.o.
+ * targets.c (nlm32_powerpc_vec): Declare.
+ * Makefile.in (BFD32_BACKENDS): Add nlm32-powerpc.o.
+ (CFILES): Add nlm32-powerpc.c.
+
+ Initial support for PowerPC ELF. Done without an ABI, and
+ probably to be changed when I get an ABI.
+ * config.bfd (powerpc-*-sysv4*): New target; use ppc-elf.
+ * config/ppc-elf.mt: New file.
+ * configure.in (bfd_elf32_powerpc_vec): New target vector; use
+ elf32-powerpc.o, elf32.o, elf.o.
+ * elf32-powerpc.c: New file.
+ * elfcode.h (prep_headers): Add bfd_arch_powerpc case.
+ (elf_set_arch_mach): Likewise.
+ * targets.c (bfd_elf32_powerpc_vec): Declare.
+ * Makefile.in (BFD32_BACKENDS): Add elf32-powerpc.o.
+ (CFILES): Add elf32-powerpc.c.
+ Rebuilt dependencies.
+
+Thu Feb 17 15:29:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffgen.c (coff_write_linenumbers): Always return a value.
+
+ * elfcode.h (elf_slurp_symbol_table): Handle zero symbols
+ reasonably. Allocate x_symp using alloca.
+
+ * elfcode.h (map_program_segments): ELF program header entries
+ must be sorted by load address. This used to generate the entries
+ in reverse order.
+
+ * section.c (SEC_IN_MEMORY): Define.
+ (asection): Rename unused field otheruserdata to contents, and
+ make it char *.
+ (bfd_make_section_anyway): Initialize contents field to NULL.
+ (bfd_get_section_contents): If SEC_IN_MEMORY is set, get section
+ contents from contents field rather than from file.
+ * bfd-in2.h: Rebuilt.
+
+Thu Feb 17 08:30:53 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * bfd.c (bfd_get_error, bfd_set_error): New functions.
+ (bfd_error): Make static.
+ (bfd_error_type): Renamed from bfd_ec. Prepend "bfd_error_" to
+ all values.
+ * bfd-in2.h: Regenerated.
+ * aix386-core.c, aout-adobe.c, aout-encap.c, aout-target.h,
+ aoutf1.h, aoutx.h, archive.c, archures.c,
+ bfd.c, bout.c, cache.c, coff-alpha.c, coff-mips.c,
+ coff-rs6000.c, coffcode.h, coffgen.c, core.c, ctor.c,
+ ecoff.c, ecofflink.c, elf.c, elf32-hppa.c, elf32-mips.c,
+ elfcode.h, format.c, hash.c, hp300hpux.c, hppabsd-core.c,
+ i386lynx.c, ieee.c, libbfd.c, libelf.h, linker.c,
+ lynx-core.c, nlm.c, nlm32-alpha.c, nlm32-i386.c,
+ nlm32-sparc.c, nlmcode.h, oasys.c, opncls.c, osf-core.c,
+ ptrace-core.c, reloc16.c, rs6000-core.c, section.c, som.c,
+ srec.c, sunos.c, syms.c, targets.c, tekhex.c,
+ trad-core.c: Change callers.
+
+Tue Feb 15 22:27:27 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c: Remove FIXMEs for things which have been dealt with.
+
+Tue Feb 15 19:39:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * section.c (bfd_get_section_contents): Since this function reads
+ unrelocated contents, the section's raw size is always the one to
+ use for bounds checking.
+
+ * linker.c (default_indirect_link_order): In assertion, compare
+ link_order size field against cooked size, not raw size, of input
+ section.
+
+ * bout.c (b_out_get_reloc_upper_bound): For BSS section, just
+ return 0.
+ (aligncode): When shrinking, the addend should be set to the
+ current offset in the section plus the number of bytes of padding
+ that will actually be retained.
+ (b_out_relax_section): If a section contains no relocations, don't
+ bother processing them.
+ (b_out_get_relocated_section_contents): Set reloc_done. Assert
+ that bfd_get_section_contents returns true. Check that relocs are
+ properly ordered.
+ (b_out_get_relocated_section_contents, case ALIGNDONE): Assert
+ that reloc->addend falls between the current source offset and the
+ raw size of the input section.
+
+ * config.bfd: Support i960 vxworks versions > 5.0 with coff, not
+ bout. Default with no version number is still bout. Support
+ explicit i960-coff target too.
+
+ * bout.c: Changed some indentation, deleted trailing whitespace,
+ fixed some comments, removed some "#if 1" lines.
+ (output_addr): New macro.
+ (calljx_callback, callj_callback, get_value, abs32code, aligncode,
+ b_out_get_relocated_section_contents): Use it for readability.
+
+Tue Feb 15 09:00:16 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_bfd_prep_for_ar_write): Iterate through the SOM
+ symbols, not the BFD symbols.
+ (som_bfd_ar_write_symbol_stuff): Likewise.
+
+Mon Feb 14 22:55:20 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_slurp_symbol_table): Do not die if a BFD doesn't
+ have any symbols.
+
+ * Finish basic read-write support for SOM archive libraries. Bugs
+ surely remain as this hasn't been tested all that much.
+ * som.c (SOM_LST_HASH_SIZE, SOM_LST_MODULE_LIMIT): Define.
+ (struct som_misc_symbol_info): New structure to hold info necessary
+ to build both normal and library symbol tables.
+ (som_derive_misc_symbol_info): New function to derive info necessary
+ to build both normal and library symbol tables.
+ (som_build_and_write_symbol_table): Use new function to derive misc
+ symbol information.
+ (som_slurp_symbol_table): Update backend private data for symbols
+ appropriately.
+ (som_bfd_prep_for_ar_write): New function.
+ (som_bfd_ar_symbol_hash): New function.
+ (som_bfd_ar_write_symbol_stuff): New function.
+ (som_write_armap): Flesh out.
+ (som_vec): Fix ar padding character.
+
+ * som.c: Consistently use memset rather than bzero.
+
+Mon Feb 14 17:02:28 1994 Stu Grossman (grossman at cygnus.com)
+
+ * coff-rs6000.c: Add Lynx core file support, use HOST_AIX, where
+ appropriate.
+ * rs6000-core.c: Use HOST_AIX instead of COREFILES_PLEASE.
+ * config/rs6000.mh: Remove defs of ARCHIVES_PLEASE and
+ COREFILES_PLEASE.
+ * config/rs6000lynx.mh: Turn on Lynx core file support.
+ * hosts/rs6000.h: #define HOST_AIX.
+ * hosts/rs6000lynx.h: Create this to enable Lynx host support.
+
+Sun Feb 13 14:30:00 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.h (som_symbol_data): Safely access backend private data
+ for BFD symbols. All callers changed.
+
+ * Read-only SOM archive support.
+ * som.c (som_bfd_count_ar_symbols): New helper function.
+ (som_bfd_fill_in_ar_symbols): New helper function.
+ (som_slurp_armap): New function to read a SOM LST.
+
+ * som.h: Include <lst.h> and <ar.h>.
+
+Sat Feb 12 22:34:14 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elfcode.h (elf_map_symbols): Fix typo.
+ (write_object_contents): Check return values from prep_headers and
+ elf_compute_section_file_positions.
+ (set_section_contents): Likewise.
+
+Fri Feb 11 16:56:50 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * archive.c (normalize) [VMS]: Call malloc, not bfd_xmalloc.
+ (bfd_construct_extended_name_table): Check result of normalize.
+
+Tue Feb 8 08:57:31 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ Make all callers of malloc or realloc (including via obstacks)
+ check the result for NULL. Most set bfd_error to no_memory and
+ return in that case; a few are harder to fix, and are marked
+ with "FIXME <return type>".
+
+ * elf32-hppa.c (hppa_elf_build_arg_reloc_stub
+ hppa_elf_build_long_branch_stub): Check bfd_make_empty_symbol return.
+ * linker.c (_bfd_generic_link_output_symbols
+ _bfd_generic_link_write_global_symbol): Ditto
+ * section.c (bfd_make_section_anyway): Ditto.
+
+ * tekhex.c (find_chunk tekhex_mkobject): Check bfd_alloc.
+ (first_phase): Ditto. FIXME void
+ (tekhex_make_empty_symbol): Check bfd_zalloc.
+
+ * sunos.c (sunos_read_dynamic_info): Check bfd_zalloc.
+ (MY(read_dynamic_symbols) MY(read_dynamic_relocs)): Check bfd_alloc.
+
+ * stringhash.c (_bfd_stringtab_hash_newfunc): Check bfd_hash_allocate.
+
+ * srec.c: Indent.
+ (fillup_symbols): Check bfd_alloc. FIXME void
+ (srec_mkobject srec_get_section_contents
+ srec_set_section_contents): Check bfd_alloc.
+ (srec_make_empty_symbol): Check bfd_zalloc.
+
+ * som.c (hppa_som_gen_reloc_type): Check bfd_alloc_by_size_t.
+ (make_unique_section): Check bfd_alloc.
+ (som_new_section_hook): Check bfd_zalloc.
+ (bfd_som_attach_aux_hdr): Ditto. FIXME void
+
+ * rs6000-core.c (rs6000coff_core_p): Check bfd_zalloc.
+
+ * osf-core.c (osf_core_make_empty_symbol): Check bfd_zalloc.
+ (osf_core_core_file_p): Check bfd_alloc.
+
+ * oasys.c (oasys_slurp_symbol_table oasys_archive_p
+ oasys_mkobject oasys_object_p oasys_new_section_hook
+ oasys_set_section_contents): Check bfd_alloc.
+ (oasys_slurp_section_data): Check bfd_zalloc and bfd_alloc.
+ (oasys_make_empty_symbol): Check bfd_zalloc.
+
+ * nlmcode.h (nlm_make_empty_symbol): Check bfd_zalloc.
+ (nlm_slurp_symbol_table): Check bfd_zalloc and bfd_alloc.
+
+ * nlm32-sparc.c (nlm_sparc_read_import): Check bfd_alloc.
+
+ * nlm32-i386.c (nlm_i386_read_import): Check bfd_alloc.
+
+ * nlm32-alpha.c (nlm_alpha_read_import): Check bfd_alloc.
+
+ * linker.c (_bfd_link_hash_newfunc
+ (generic_link_hash_newfunc
+ (archive_hash_newfunc
+ (_bfd_generic_link_add_one_symbol): Check bfd_hash_allocate.
+ (_bfd_generic_final_link
+ (_bfd_generic_link_output_symbols
+ (default_indirect_link_order): Check bfd_alloc.
+ (bfd_new_link_order): Check bfd_alloc_by_size_t.
+
+ * irix-core.c (irix_core_make_empty_symbol): Check bfd_zalloc.
+
+ * ieee.c: Indent.
+ (read_id get_symbol get_section_entry ieee_archive_p ieee_object_p
+ ieee_slurp_section_data ieee_new_section_hook): Check bfd_alloc.
+ (do_one): Check bfd_alloc. Return a boolean.
+ (ieee_slurp_section_data): Check it.
+ (init_for_output): Check bfd_alloc. Return a boolean.
+ (ieee_set_section_contents): Check it.
+ (do_with_relocs): Check bfd_alloc. Return a boolean.
+ (ieee_bfd_debug_info_accumulate): Ditto. FIXME void.
+ (ieee_mkobject): Check bfd_zalloc.
+ (ieee_make_empty_symbol): Check bfd_zmalloc.
+
+ * hpux-core.c (hpux_core_make_empty_symbol): Check
+ bfd_zalloc.
+
+ * hppabsd-core.c (hppabsd_core_make_empty_symbol): Check
+ bfd_zalloc.
+ (hppabsd_core_core_file_p): Check bfd_zalloc.
+
+ * hp300hpux.c (MY(slurp_symbol_table)): Check bfd_alloc.
+
+ * elfcode.h (elf_new_section_hook): Check bfd_alloc.
+ (bfd_section_from_phdr): Ditto.
+ (write_relocs): Ditto. FIXME void
+ (elf_map_symbols assign_section_numbers map_program_segments):
+ Ditto. Return a boolean.
+ (swap_out_syms): Ditto. Check elf_map_symbols.
+ (elf_slurp_symbol_table): Check bfd_zalloc.
+ (elf_slurp_reloca_table): Check bfd_alloc.
+ (elf_slurp_reloc_table): Ditto.
+ (elf_compute_section_file_positions): Check assign_section_numbers.
+ (assign_file_positions_except_relocs): Return a boolean.
+ Check map_program_segments.
+ (elf_compute_section_file_positions): Check it.
+
+ * elf32-mips.c (mips_elf_final_link): Check bfd_alloc.
+
+ * elf32-hppa.c (hppa_elf_stub_branch_reloc): Check bfd_zmalloc and
+ realloc.
+ (hppa_elf_stub_reloc): Ditto.
+ (hppa_elf_build_arg_reloc_stub): Check bfd_zalloc.
+ (hppa_elf_build_long_branch_stub): Ditto.
+ (elf32_hppa_backend_symbol_table_processing): Ditto.
+
+ * ecoff.c (ecoff_set_symbol_info): Check bfd_alloc. Return a boolean.
+ (ecoff_slurp_symbol_table): Check it.
+ (ecoff_slurp_armap): Check bfd_alloc.
+ (ecoff_write_armap): Check bfd_zalloc.
+ (ecoff_link_hash_newfunc): Check bfd_hash_allocate and
+ _bfd_link_hash_newfunc.
+ (ecoff_link_add_externals): Check bfd_alloc.
+
+ * ctor.c (bfd_constructor_entry): Check bfd_alloc.
+
+ * coffgen.c (coff_real_object_p): Check bfd_alloc.
+ (coff_renumber_symbols): Check bfd_alloc_by_size_t. Return a boolean.
+ (coff_write_symbol): Check bfd_alloc. FIXME int
+ (coff_write_linenumbers): Check bfd_alloc. Return a boolean.
+ (coff_section_symbol): Check bfd_alloc_by_size_t.
+ (coff_get_normalized_symtab): Check bfd_alloc.
+ (coff_bfd_make_debug_symbol): Check bfd_zalloc.
+ * libcoff-in.h: Change decls of coff_renumber_symbols,
+ coff_write_linenumbers.
+ * libcoff.h: Rebuilt.
+ * coffcode.h (coff_write_object_contents): Check
+ coff_renumber_symbols, coff_write_linenumbers.
+
+ * coffcode.h: Indent.
+ (coff_add_missing_symbols): Check bfd_alloc_by_size_t. Return a
+ boolean.
+ (coff_write_object_contents): Check it.
+
+ * coff-alpha.c (alpha_relocate_section): Check bfd_alloc.
+ * coff-mips.c (mips_relocate_section): Ditto.
+
+ * archive.c (bfd_slurp_bsd_armap_f2): Check bfd_alloc value.
+ (do_slurp_bsd_armap): Ditto.
+ (compute_and_write_armap): Check bfd_realloc value.
+
+ * aoutx.h (translate_from_native_sym_flags): Check bfd_alloc
+ return value. Return boolean value.
+ (NAME(aout,make_empty_symbol)): Check bfd_zalloc return value.
+ (NAME(aout,slurp_symbol_table)): Check bf_alloc and bfd_zalloc
+ return value.
+ (add_to_stringtab): Ditto. FIXME void
+ (aout_link_hash_newfunc): Check bfd_hash_allocate return value.
+ (aout_link_add_symbols): Check bfd_alloc value.
+ (translate_symbol_table): Check translate_from_native_sym_flags.
+ * hp300hpux.c (MY(slurp_symbol_table)): Ditto.
+ * aoutx.h (aout_link_hash_newfunc): Check _bfd_link_hash_newfunc.
+
+ * opncls.c (bfd_zalloc bfd_realloc): Check result of bfd_alloc.
+
+ * opncls.c (obstack_chunk_alloc): Define as malloc, not
+ bfd_xmalloc_by_size_t.
+ (_bfd_new_bfd): Check obstack_begin for 0 return.
+
+ * ieee.c (obstack_chunk_alloc): Define as malloc, not
+ bfd_xmalloc_by_size_t.
+ (ieee_archive_p): Check obstack_begin for 0 return and
+ obstack_finish for NULL return.
+
+ * hash.c (obstack_chunk_alloc): Define as malloc, not
+ bfd_xmalloc_by_size_t.
+ (bfd_hash_table_init_n): Check obstack_begin for 0 return and
+ obstack_finish for NULL return.
+ (bfd_hash_lookup): Check obstack_alloc for NULL return.
+
+ * ecofflink.c (obstack_chunk_alloc): Define as malloc, not
+ bfd_xmalloc_by_size_t.
+ bfd_ecoff_debug_accumulate
+ bfd_ecoff_debug_accumulate_other): Check obstack_alloc.
+ (add_file_shuffle add_memory_shuffle): Check obstack_alloc for
+ NULL return. Return boolean, not void.
+ (bfd_ecoff_debug_init): Check obstack_begin for 0 return.
+ (bfd_ecoff_debug_accumulate): Check add_file_shuffle
+ and add_memory_shuffle return.
+ (string_hash_newfunc): Check bfd_hash_allocate and bfd_hash_newfunc.
+ (bfd_ecoff_debug_accumulate): Check bfd_alloc.
+ (ecoff_add_string): Check add_memory_shuffle return.
+
+ * libbfd-in.h (xmalloc, bfd_xmalloc, bfd_xmalloc_by_size_t):
+ Remove decls.
+ * libbfd.h: Rebuilt.
+
+Fri Feb 11 15:35:32 1994 Stu Grossman (grossman at cygnus.com)
+
+ * configure.host: Add Lynx/rs6000 support.
+ * config/i386-nlm.mt: Enable a.out file support.
+ * config/rs6000lynx.mh: Lynx/rs6000 host support.
+
+Fri Feb 11 17:25:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * archive.c (compute_and_write_armap): Rewrite somewhat to improve
+ memory usage.
+
+Fri Feb 11 13:10:42 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * archive.c: Change all references to '\n' in archive magic
+ to '\012', for greater portability.
+ * ecoff.c (ecoff_write_armap): Ditto.
+
+Thu Feb 10 12:58:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_link_write_other_symbol): Check strip settings to
+ see whether symbol should be output.
+ * genlink.h (struct generic_write_global_symbol_info): Added info
+ field.
+ * linker.c (_bfd_generic_final_link): Initialize wginfo.info.
+ (_bfd_generic_link_write_global_symbol): Check strip settings to
+ see whether symbol should be output.
+ * elf32-mips.c (mips_elf_final_link): Initialize wginfo.info.
+
+Wed Feb 9 21:34:58 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_reloc_queue_find): Do not examine a NULL queue entry.
+
+ * som.c: Cast return values from BFD memory allocation routines to
+ avoid warnings from the HP compiler.
+
+Wed Feb 9 12:55:02 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-alpha.c (alpha_relocate_section): Accept a LITERAL
+ reloc on an "ldl" instruction too.
+
+ * archive.c (bfd_ar_hdr_from_filesystem): Cast status elements
+ when passing them to sprintf. Use %ld instead of %d.
+
+ * coff-rs6000.c (rs6000coff_mkarchive): Return false.
+ (rs6000_coff_snarf_ar_hdr): Don't declare errno; it's not used.
+ Also removed unused variable namelen.
+ (rs6000coff_write_armap): Declare orl_count and stridx parameters.
+
+Tue Feb 8 18:00:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libbfd-in.h (xmalloc): Don't declare parameter type, to avoid
+ conflicts.
+ * libbfd.h: Rebuilt.
+
+Tue Feb 8 15:55:50 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * coff-alpha.c (reloc_nil): New function.
+ (alpha_howto_table): Use it as special_function to prevent certain
+ relocs from being adjusted by bfd_perform_relocation. IGNORE
+ reloc should be partial_inplace.
+ (alpha_ecoff_get_relocated_section_contents): Accept a LITERAL
+ reloc on an "ldl" instruction too.
+
+Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elf32-hppa.c (CURRENT_STUB_OFFSET, hppa_elf_build_arg_reloc_stub,
+ hppa_elf_build_long_branch_stub): Cast to char * instead of int
+ before performing pointer arithmetic.
+
+Mon Feb 7 20:56:27 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config.bfd (hppa*-*-osf*): Use bfd_name hppaosf for this
+ configuration.
+ (hppa*-*-*elf*): This configuration used hppa-elf now.
+
+ * som.c: This file is also used for HOST_HPPAOSF.
+
+ * targets.c (bfd_target_vector): Enable som_vec for HOST_HPPAOSF.
+
+ * hosts/hppaosf.h: New host configuration file.
+
+ * config/hppabsd.mt (SELECT_VECS): Add bfd_elf32_hppa_vec as
+ BSD handles both SOM and ELF object files.
+
+ * config/hppaosf.mh (HDEFINES): Delete. No longer needed.
+ (RANLIB): Doesn't do anything, define it to be "echo".
+
+ * config/hppaosf.mt: New target makefile fragment for a PA running
+ OSF1.
+
+Mon Feb 7 15:02:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * archures.c (enum bfd_architecture): Added bfd_arch_powerpc.
+ (archures_init_table): If SELECT_ARCHITECTURES is not defined,
+ added bfd_powerpc_arch.
+ * bfd-in2.h: Rebuilt.
+ * cpu-powerpc.c: New file.
+ * Makefile.in (ALL_MACHINES, CFILES): Added cpu-powerpc.c.
+ Rebuilt dependencies.
+
+ * elfcode.h (bfd_section_from_shdr): Get vma and alignment_power
+ of an SHT_STRTAB section from sh_addr and sh_addralign, rather
+ than just setting them to zero.
+
+Sun Feb 6 20:04:10 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * elfcode.h (prep_headers, swap_out_syms): Check for NULL return
+ from bfd_new_strtab.
+ (elf_compute_section_file_positions): Check for false return from
+ swap_out_syms.
+
+ * linker.c (default_indirect_link_order): Check for NULL return
+ from bfd_get_relocated_section_contents.
+
+ * syms.c: Make example application in doc call xmalloc, not
+ bfd_xmalloc.
+
+ * aoutx.h (NAME(aout,slurp_symbol_table),
+ aout_link_get_symbols, NAME(aout,link_hash_table_create)):
+ * bout.c (b_out_slurp_reloc_table, b_out_squirt_out_relocs):
+ * ecoff.c (ecoff_bfd_link_hash_table_create):
+ * ecofflink.c (bfd_ecoff_debug_init):
+ * format.c (bfd_check_format_matches):
+ * linker.c (_bfd_generic_link_hash_table_create):
+ (_bfd_generic_final_link):
+ * reloc16.c (bfd_coff_reloc16_relax_section):
+ (bfd_coff_reloc16_get_relocated_section_contents):
+ * elf32-hppa.c (hppa_elf_build_arg_reloc_stub):
+ * elf32-mips.c (mips_elf_final_link):
+ * elfcode.h (bfd_new_strtab):
+ (bfd_add_2_to_strtab):
+ (elf_slurp_symbol_table):
+ (elf_corefile_note):
+ * libbfd.c (bfd_zmalloc):
+ Use malloc and check the result, instead of bfd_xmalloc.
+
+Sat Feb 5 12:39:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.bfd: Put m68*-*-sysv* line after m68*-*-sysv4*.
+
+Sat Feb 5 05:32:44 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * srec.c (srec_write_record): Put CONST keyword for "src" before
+ "unsigned", some compilers don't like it after "unsigned".
+ * libcoff.h, libcoff-in.h (bfd_perform_slip): Rename "value" to
+ "val" in prototype declaration because some compilers don't like
+ arguments whose names are the same as types.
+
+Sat Feb 5 01:14:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_link_check_ar_symbols): Correct test for whether
+ object file defines symbol. Also, if skipping a symbol, skip the
+ second symbol of a N_WARNING or N_INDR symbol as well.
+
+Fri Feb 4 23:55:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add basic support for writing RS/6000 XCOFF files.
+ * coff-rs6000.c (dummy_reloc): Removed.
+ (rs6000coff_howto_table): Defined XCOFF relocs.
+ (RTYPE2HOWTO): Defined to use rs6000coff_rtype2howto.
+ (rs6000coff_rtype2howto): New function.
+ (coff_bfd_reloc_type_lookup): Defined to use
+ rs6000coff_reloc_type_lookup.
+ (rs6000coff_reloc_type_lookup): New function.
+ (SELECT_RELOC): Defined to set r_type and r_size fields.
+ (COFF_LONG_FILENAMES): Defined.
+ * coffcode.h (combined_entry_type): Changed fix_tag and fix_end
+ fields to bitfields. Added fields fix_value and fix_scnlen.
+ (sec_to_styp_flags): If STYP_DEBUG is defined, use it rather than
+ STYP_INFO for the type of a section named .debug.
+ (coff_add_missing_symbols): Don't define if RS6000COFF_C.
+ (coff_write_object_contents): If RS6000COFF_C, don't call
+ coff_add_missing_symbols.
+ (coff_slurp_symbol_table): If RS6000COFF_C, then if the last aux
+ entry has type STY_LD change the x_scnlen into a pointer to a
+ symbol and set fix_scnlen. Also, for a C_BSTAT symbol, change the
+ value into a pointer to a symbol and set fix_value.
+ * libcoff.h: Rebuilt.
+ * coffgen.c (coff_mangle_symbols): Reindent. If fix_value is set,
+ get the symbol offset. Likewise for fix_scnlen.
+ (string_size): Change type to bfd_size_type.
+ (debug_string_size, debug_string_section): New static variables.
+ (coff_fix_symbol_name): If bfd_coff_symname_in_debug returns true,
+ write the symbol name into the .debug section; assume that the
+ section has already been created with the right size.
+ (coff_write_symbols): Initialize debug_string_size to 0. If
+ bfd_coff_symname_in_debug returns true, don't put symbol name in
+ usual string table. After writing out all symbols, if
+ debug_string_size is not 0, check that it matches the size of the
+ .debug section.
+ (coff_get_normalized_symtab): Clear new fix_value and fix_scnlen
+ fields. If the string offset is 0, always use an empty string as
+ the name.
+ (coff_make_empty_symbol): Zero out the symbol structure.
+ * reloc.c (bfd_perform_relocation): Work around one gross hack
+ with another: actually look at the target name to avoid the broken
+ COFF check.
+ (bfd_reloc_code_real_type): Add BFD_RELOC_PPC_B26,
+ BFD_RELOC_PPC_BA26 and BFD_RELOC_PPC_TOC16.
+ * bfd-in2.h: Rebuilt.
+
+Fri Feb 4 17:28:32 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * libbfd.c (bfd_zmalloc): Call bfd_xmalloc instead of malloc.
+ (bfd_xmalloc, bfd_xmalloc_by_size_t): Functions deleted.
+ * libbfd-in.h: Define them as macros calling xmalloc and declare
+ xmalloc.
+ * libbfd.h: Rebuilt.
+
+Thu Feb 3 16:49:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecofflink.c (bfd_ecoff_debug_externals): If a small undefined
+ symbol has a value in the ECOFF symbol but not in the BFD symbol,
+ keep the value in the ECOFF symbol. This helps gas.
+
+ * linker.c (_bfd_generic_link_output_symbols,
+ _bfd_generic_link_write_global_symbol): Don't require that all
+ references to a common symbol be themselves common symbols.
+
+ * aoutx.h (aout_reloc_index_to_section): Handle N_UNDF.
+
+Wed Feb 2 20:37:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * libbfd.c, bfd-in.h, hosts/alphaosf.h, hosts/sparc-ll.h, aoutf1.h,
+ sparclynx.c, Makefile.in: Change HOST_64_BIT to BFD_HOST_64_BIT.
+ * bfd-in2.h: Rebuilt.
+
+Wed Feb 2 12:30:13 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffswap.h (coff_swap_reloc_out): If RS6000COFF_C, handle type
+ and size correctly.
+ (coff_swap_aux_in): If RS6000COFF_C, change x_csect.x_scnlen to
+ x_csect.x_scnlen.l to match change in coff/internal.h.
+ (coff_swap_aux_out): Likewise.
+
+ * coff-mips.c (mips_ecoff_backend_data), coff-alpha.c
+ (alpha_ecoff_backend_data): Change casts of aux_in and aux_out
+ fields to match yesterday's changes.
+
+ * coffcode.h (coff_write_relocs): If SELECT_RELOC is defined, pass
+ in the internal_reloc itself, not the type.
+ * coff-apollo.c, coff-h8300.c, coff-h8500.c, coff-i386.c,
+ coff-m68k.c, coff-sh.c, coff-we32k.c, coff-z8k.c: Changed
+ definition of SELECT_RELOC accordingly.
+
+Tue Feb 1 12:05:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coffcode.h (bfd_coff_backend_data): Added new arguments to
+ _bfd_coff_swap_aux_in and _bfd_coff_swap_aux_out: aux index number
+ and number of aux entries.
+ (bfd_coff_swap_aux_in, bfd_coff_swap_aux_out): Changed
+ accordingly.
+ * libcoff.h: Rebuilt.
+ * coffswap.h (coff_swap_aux_in, coff_swap_aux_out): Accept new
+ arguments. If RS6000COFF_C, only treat C_EXT and C_HIDEXT
+ specially if this is the last aux entry.
+ * coffgen.c (coff_write_symbol, coff_get_normalized_symtab): Pass
+ new arguments to swap_aux functions.
+
+Sun Jan 30 15:14:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gen-aout.c (main): Set DEFAULT_ARCH based on preprocessor macros
+ (only testing for m68k and vax at the moment); do verify that the
+ preprocessor didn't trash the arch name inside the string version.
+ Don't print out "pagesize =" line that prevents output from
+ compiling. Derive BYTES_IN_WORD and ARCH values from sizeof
+ results.
+ * Makefile.in (aout-params.h): Pass gen-aout a dummy target name.
+ (check, installcheck): Identify directory in "no testsuites"
+ message.
+
+Sun Jan 30 13:25:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_link_write_symbols): Write out correct value for
+ object file symbol.
+
+Fri Jan 28 18:34:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * hosts/vaxbsd.h (HOST_STACK_END_ADDR): Vax BSD doesn't define
+ KERNBASE, so hard-code 0x80000000 instead.
+
+Thu Jan 27 13:54:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * linker.c (generic_link_add_symbol_list): If symbol is common,
+ set the BSF_OLD_COMMON flag.
+
+Wed Jan 26 13:47:15 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * format.c (bfd_check_format_matches): Put the new entry in the
+ correct element of matching_vector.
+
+Tue Jan 25 11:43:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * som.c, som.h (bfd_som_set_section_attributes,
+ bfd_som_set_subsection_attributes): Change parameters from char
+ to int. Following a prototype with an old-style function definition
+ in the presence of widened parameters is a GCC-ism not supported
+ by the HP compiler in ANSI mode.
+
+Tue Jan 25 11:46:46 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * reloc.c (bfd_get_reloc_size): Size of type -2 is 4 bytes, not 2.
+
+ * hp300hpux.c (MY(write_object_contents)): Write out the symbols
+ before writing out the relocs, so that the right symbol indices
+ are used.
+
+ * archive.c (do_slurp_bsd_armap, bfd_slurp_bsd_armap_f2): Do not
+ try to overlay the internal carsyms on the external symdefs. That
+ can not work if the size of a host pointer is larger than 4 bytes.
+
+ * format.c (bfd_check_format_matches): Cast result of
+ bfd_xmalloc_by_size_t.
+ * opncls.c (_bfd_new_bfd): Avoid ANSI C prototype.
+
+ * archive.c: Reindented to GNU standards.
+
+Mon Jan 24 14:41:23 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * opncls.c (_bfd_new_bfd, _bfd_new_bfd_contained_in): Add
+ "_bfd_" to function names.
+ * archive.c (_bfd_create_empty_archive_element_shell),
+ libbfd-in.h: Change callers.
+
+ * libbfd.c (bfd_zmalloc): Renamed from zalloc.
+ * libbfd.c (bfd_add_to_string_table),
+ trad-core.c (trad_unix_core_file_p),
+ targets.c (bfd_target_list),
+ ptrace-core.c (ptrace_unix_core_file_p),
+ opncls.c (new_bfd), libbfd-in.h,
+ ieee.c (ieee_make_empty_symbol),
+ elf32-hppa.c (hppa_elf_stub_branch_reloc),
+ (hppa_elf_stub_reloc): Change callers.
+ * libbfd.h: Regenerated.
+
+ * archive.c (_bfd_look_for_bfd_in_cache): Add "_bfd_" to name.
+ (_bfd_get_elt_at_filepos),
+ coff-rs6000.c (rs6000coff_get_elt_at_filepos), libbfd-in.h:
+ Change callers.
+
+ * format.c (bfd_check_format_matches), libbfd-in.h, targets.c,
+ elfcode.h (elf_object_p): Rename target_vector to bfd_target_vector
+ and default_vector to bfd_default_vector.
+ * libbfd.h: Regenerated.
+
+ * format.c (bfd_check_format_matches): New function.
+ (bfd_check_format): Call it.
+ (bfd_matching_formats): Function removed.
+ * targets.c: Replace the vector added on Jan 21 with a count of
+ entries in default_vector.
+ * bfd-in2.h: Regenerated.
+
+Mon Jan 24 12:38:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * coff-alpha.c (alpha_ecoff_object_p): New function. Set size of
+ .pdata section based on lnnoptr field, not section header.
+ (alpha_relocate_section): Don't bother to check if r_symndx >= 0,
+ since it is unsigned.
+ (ecoffalpha_little_vec): Use alpha_ecoff_object_p rather than
+ coff_object_p.
+ * ecoff.c (ecoff_new_section_hook): Set alignment_power field of
+ .pdata section to 3.
+ (ecoff_compute_section_file_positions): Save the size of the
+ .pdata section in the line_filepos field, and actually align the
+ .pdata section to an alignment power of 4.
+ (ecoff_compute_reloc_file_positions): Set output_has_begun after
+ calling ecoff_compute_section_file_positions.
+ (ecoff_write_object_contents): Set s_lnnoptr for the .pdata
+ section from the line_filepos field. Set vstamp for the optional
+ header from the vstamp of the symbolic header.
+ (ecoff_bfd_final_link): Set vstamp of the symbolic header to the
+ vstamp used by the first object file in the link.
+
+ * ecofflink.c (ecoff_align_debug): Align RFDs to debug_align.
+
+ * linker.c (generic_link_check_achive_element): Set SEC_ALLOC flag
+ for a created common section.
+ (_bfd_generic_link_add_one_symbol): Likewise.
+
+ * elfcode.h (swap_out_syms): Use elf_section_from_bfd_section to
+ get the index of a common section, rather than always using
+ SHN_COMMON (MIPS has multiple common sections).
+
+ * elf32-hppa.c (hppa_elf_gen_reloc_type): Typo (== for =).
+
+ * bfd/aoutx.h (aout_link_input_section_std,
+ aout_link_input_section_ext): Pass additional arguments to
+ reloc_overflow callback.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents,
+ alpha_relocat_section): Likewise.
+ * coff-h8300.c (h8300_reloc16_extra_cases): Likewise.
+ * coff-h8500.c (extra_case): Likewise.
+ * coff-mips.c (mips_relocate_section): Likewise.
+ * coff-z8k.c (extra_case): Likewise.
+ * elf32-hppa.c (hppa_elf_stub_finish): Likewise.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
+
+ * bout.c (calljx_callback, callj_callback): Use get_value to get
+ the symbol value and check for undefined symbols.
+ (get_value): If the symbol is undefined, look it up in the linker
+ hash table.
+ (b_out_get_relocated_section_contents): For PCREL24 and PCREL13
+ use get_value to get the symbol value and check for undefined
+ symbols.
+ * reloc16.c (bfd_coff_reloc16_get_value): If the symbol is
+ undefined, look it up in the linker hash table.
+
+ * aoutx.h (translate_symbol_table): The string index 0 has a
+ special meaning for normal symbols, but not for dynamic symbols.
+
+Sat Jan 22 12:26:01 1994 Stu Grossman (grossman at cygnus.com)
+
+ * sparclynx.c: Setup appropriate macros to enable core file
+ support.
+
+Fri Jan 21 16:25:35 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * targets.c: Add a vector of matching format names.
+ * format.c (bfd_matching_formats): New function to return it.
+ (bfd_check_format): Set it.
+ * bfd-in2.h: Regenerated.
+
+ * bfd-in.h: Remove decls of bfd_ec type and error printing functions.
+ Remove decl of type symclass; wasn't used.
+ * bfd.c: Document error handling, including code fragments
+ containing the error decls that were in bfd-in.h.
+ Remove DEFUNs.
+ * bfd-in2.h: Regenerated.
+
+Fri Jan 21 14:11:16 1994 Sean Fagan (sef@cygnus.com)
+
+ * nlmcode.h, liblnm.h, nlm32-alpha.c nlm32-i386.c nlm32-sparc.c:
+ The sparc (and possibly other?) NLM format requires a different
+ way to write exports, so add a write_export field to the backend
+ data (and set it to NULL for everything but the sparc).
+
+Fri Jan 21 14:11:16 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sunos.c (MY(read_dynamic_relocs)): Compare info->dynrel with NULL,
+ not (struct external_nlist *) NULL. info->dynrel is a PTR, not
+ a struct external_nlist *.
+
+Fri Jan 21 09:29:01 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * bfd.c: Remove error strings for errors removed below.
+ * aoutx.h (translate_to_native_sym_flags), bfd-in.h (bfd_ec),
+ oasys.c (oasys_write_sections): Rename
+ bfd_error_nonrepresentable_section to nonrepresentable_section.
+ None of the other bfd error names start with "bfd_error".
+ Remove errors symbol_not_found and no_relocation_info, which seem
+ to be unused.
+ * bfd-in2.h: Regenerated.
+
+Fri Jan 21 01:11:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.c (bfd_get_gp_size): Added support for ELF.
+
+ * syms.c (BSF_DYNAMIC): New symbol flag.
+ (bfd_print_symbol_vandf): Print it.
+ * bfd-in2.h: Rebuilt.
+ * libaout.h (struct aout_backend_data): New read_dynamic_symbols
+ and read_dynamic_relocs fields.
+ (struct aoutdata): New dynamic_info field.
+ (obj_aout_dynamic_info): New accessor macro.
+ * sunos.c (struct sunos_dynamic_info): New structure.
+ (sunos_read_dynamic_info, MY(read_dynamic_symbols),
+ MY(read_dynamic_relocs)): New functions to read dynamic symbols
+ and relocs.
+ * aoutx.h (NAME(aout,some_aout_object_p)): If the object is
+ dynamically linked, set SEC_RELOC for both the .text and .data
+ sections.
+ (translate_from_native_sym_flags): Don't set BSF_LOCAL for an
+ undefined symbol.
+ (translate_symbol_table): New function, split out of
+ slurp_symbol_table; set the BSF_DYNAMIC flag appropriately.
+ (NAME(aout,slurp_symbol_table)): Read dynamic symbols, if any.
+ (NAME(aout,slurp_reloc_table)): Read dynamic relocs, if any.
+ (NAME(aout,get_reloc_upper_bound)): Include dynamic reloc count in
+ return value.
+ * aoutf1.h (NAME(aout,sunos4_write_object_contents)): Don't write
+ out dynamic symbols or relocs against reloc symbols, since they
+ are already in the .text section and we wouldn't know where to
+ write them anyhow.
+ (sunos4_aout_backend): Initialize read_dynamic_symbols and
+ read_dynamic_relocs fields.
+ * aout-target.h (MY(backend_data)): Initialize
+ read_dynamic_symbols and read_dynamic_relocs fields.
+
+Thu Jan 20 20:57:27 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * hosts/alphaosf.h (uint64e_type, uint64_type, int64_type): Delete
+ typedefs, since HOST_64_BIT will take care of defining them in
+ bfd.h.
+
+Wed Jan 19 17:28:59 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/alphaosf.mh (HDEFINES): Don't define HOST_64_BIT here;
+ that's dealt with elsewhere.
+ * hosts/alphaosf.h (sprintf_vma, fprintf_vma): New macros.
+ (uint64_typeHIGH, uint64_typeLOW): Comment with HOST_64_BIT so
+ they get copied to bfd.h.
+
+ * reloc.c (enum bfd_reloc_code_real): Add some Alpha relocation
+ types. Reorganized some of the existing ones.
+ * coff-alpha.c (alpha_howto_table): Construct 64-bit negative one
+ values in case of compilation on a 32-bit machine. Fix pcrel
+ fields of some reloc types.
+ (alpha_bfd_reloc_type_lookup): Handle more relocation types.
+
+ * bfd-in.h (uint64_typeHIGH, uint64_typeLOW): Supply default
+ definitions when not defined, regardless of whether uint64_type is
+ a defined macro or not.
+ (fprintf_vma, sprintf_vma): Define only if fprintf_vma is not
+ already defined.
+
+Wed Jan 19 00:02:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (translate_to_native_sym_flags): Set the type of a
+ BSF_WARNING symbol to N_WARNING.
+
+Tue Jan 18 16:43:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (aout_link_add_symbols): Increment sym_hash as well as p
+ for an indirect or warning symbol.
+ (aout_link_write_symbols): Update sym_hash with the target of an
+ indirect or warning symbol. If an indirect symbol is defined,
+ output the calculated value and don't output the target symbol.
+
+Tue Jan 18 03:54:59 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (translate_from_native_sym_flags): Give warning symbols
+ an (unused) nonzero section value, needed for check below.
+
+Mon Jan 17 15:12:07 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (translate_from_native_sym_flags,
+ aout_link_add_symbols): Treat N_SET[ABDT] | N_EXT like
+ N_SET[ABDT].
+
+Fri Jan 14 16:45:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elfcode.h (elf_object_p): If there is a SHT_DYNAMIC section, set
+ the DYNAMIC flag for the BFD.
+ (NAME(bfd_elf,write_object_contents)): Don't try to write out a
+ BFD with the DYNAMIC flag set, since we don't generate the program
+ header table correctly.
+
+Fri Jan 14 01:04:36 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfcode.h (elf_slurp_symbol_table): Free x_symp at the end
+ of the function to avoid storage leak.
+
+Thu Jan 13 23:07:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_link_write_external): An ifd can be -1.
+
+Thu Jan 13 12:33:27 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (som_set_reloc_info): Provide a default symbol for
+ relocations which don't actually have an associated symbol.
+
+ * som.c (hppa_som_reloc): Add new "error message" argument.
+
+Wed Jan 12 13:36:43 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ Enable gdb to write to core files on more core file readers.
+ * libbfd.c (bfd_generic_set_section_contents): Remove range check
+ for section size, it is already done in bfd_set_section_contents
+ with bfd_get_section_size_now.
+ * aix386-core.c, hppabsd-core.c, hpux-core.c, irix-core.c,
+ osf-core.c, ptrace-core.c, trad-core.c (*_set_section_contents):
+ Use bfd_generic_set_section_contents instead of bfd_false.
+
+Wed Jan 12 15:31:57 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * linker.c: Added initial documentation.
+
+ * linker.c (default_indirect_link_order): Don't expect space for
+ output relocations if there aren't any input relocations.
+
+Tue Jan 11 14:37:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aoutx.h (NAME(aout,final_link)): Set a_entry before computing
+ file offsets.
+
+ * elfcode.h (swap_out_syms): A common symbol is STT_OBJECT, not
+ STT_NOTYPE.
+
+Tue Jan 11 09:10:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.bfd: Use ELF, not COFF for m88*-*-dgux*.
+ Combine m88k-*-* and m88110-*-* cases into m88*-*-*.
+
+Tue Jan 11 00:07:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecofflink.c: Extensive changes to compress and merge debugging
+ information, and to write some of out directly rather than saving
+ it in memory. Several new functions and structures, and new
+ arguments to existing functions.
+ * ecoff.c (ecoff_compute_reloc_file_positions): Compute
+ sym_filepos as well.
+ (ecoff_get_extr): Use ifdmap instead of ifdbase.
+ (ecoff_write_object_contents): Don't compute sym_filepos here.
+ Only output symbols if outsymbols is not NULL.
+ (ecoff_bfd_final_link): Adjust for changes in ecoff_debug_info and
+ bfd_ecoff_debug functions. Write out debugging information here.
+ (ecoff_final_link_debug_accumulate): Adjust for changes in
+ bfd_ecoff_debug functions.
+ (ecoff_link_write_external): Use ifdmap rather than ifdbase.
+ * elf32-mips.c (mips_elf_read_ecoff_info): Read external symbols
+ first, to put them in the first memory buffer. Clear fdr field.
+ (mips_elf_get_extr): Use pointer to unswapped external symbol.
+ (mips_elf_final_link): Adjust for changes in bfd_ecoff functions.
+ Preserve .text, .data and .bss even if they are empty. Save
+ pointer to unswapped external symbol rather than copying it.
+ Don't free up the external symbols.
+ * libelf.h (elf_symbol_type): Change mips_extr to PTR.
+ * bfd-in.h (bfd_ecoff_debug_init, bfd_ecoff_debug_free): Declare.
+ (bfd_ecoff_debug_accumulate): Update declaration.
+ (bfd_ecoff_debug_accumulate_other): Rename declaration from
+ bfd_ecoff_debug_link_other and update.
+ (bfd_ecoff_write_accumulated_debug): Declare.
+ * bfd-in2.h: Rebuilt.
+ * Makefile.in: Rebuilt dependencies.
+
+Mon Jan 10 20:46:53 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in (install): Remove "@" which follows a backslash. In
+ this position it just causes errors, not suppresses echoes.
+
+Mon Jan 10 09:06:21 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * som.c (hppa_som_gen_reloc_type): Fix handling of LT and RT
+ field selectors.
+
+Sun Jan 9 04:32:25 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/i386-netbsd.mt (SELECT_VECS): Include i386bsd_vec.
+
+Fri Jan 7 10:27:27 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * aoutx.h (adjust_z_magic): Don't merge the start of bss with the
+ end of data if they are not contiguous.
+
+ * aoutf1.h (sunos4_aout_backend): Comment the fields' meanings.
+
+Fri Jan 7 15:40:16 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_mkobject_hook): Don't set SEC_SHARED_LIBRARY flag
+ for .reginfo section here.
+ (ecoff_new_section_hook): Set it here instead.
+
+Fri Jan 7 10:29:27 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * bfd-in.h: (bfd_boolean): Add workaround for systems that also
+ define true and false as enums.
+ (ALMOST_STDC): Add as alternative to __STDC__.
+ * bfd-in2.h: Rebuilt.
+ * syms.c (bfd_print_symbol_vandf): Convert a PTR to FILE*.
+
+Thu Jan 6 14:24:44 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aoutx.h (translate_to_native_sym_flags): Catch the case where
+ there is no output section.
+
+Thu Jan 6 14:37:42 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmcode.h (nlm_object_p): If we can't read the fixed header,
+ count it as a wrong format error, not a system call error, since
+ the object file might simply be too small.
+
+ * targets.c (target_vector): Added nlm32_alpha_vec inside #ifdef
+ BFD64.
+ * Makefile.in (BFD32_BACKENDS): Remove nlm32-alpha.o.
+ (BFD64_BACKENDS): Add nlm32-alpha.o. It depends on 64 bit
+ support, even though it is for an Alpha in 32 bit mode.
+ * configure.in (nlm32_alpha_vec): Set target64 to true.
+
+ * nlm32-gen.c, nlm64-gen.c: Removed. All nlm targets are
+ different, so there is no point to providing a generic one.
+ * libnlm.h: Don't bother to check for nlm_backend(bfd) being NULL
+ in the backend accessor macros; that should no longer be possible.
+ * targets.c (target_vector): Removed nlm32_big_generic_vec,
+ nlm64_big_generic_vec, nlm64_little_generic_vec.
+ * configure.in (nlm32_big_generic_vec, nlm32_little_generic_vec,
+ nlm64_big_generic_vec, nlm64_little_generic_vec): Removed.
+ * Makefile.in: Rebuilt dependencies, and
+ (BFD32_BACKENDS): Removed nlm32-gen.o.
+ (BFD64_BACKENDS): Removed nlm64-gen.o.
+ (CFILES): Removed nlm32-gen.c and nlm64-gen.c.
+
+ * hp300hpux.c (ARCH_SIZE): Define before including aoutx.h.
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Add constructor and
+ bitsize arguments. Changed all callers (aoutx.h).
+ * libbfd-in.h (_bfd_generic_link_add_one_symbol): Add constructor
+ and bitsize arguments to declaration.
+ * libbfd.h: Rebuilt.
+
+ * ecoff.c: First cut at new style of linker backend for
+ ECOFF--added a bunch of functions. Also:
+ (ecoff_sec_to_styp_flags): Set flags for .pdata and .xdata.
+ (ecoff_slurp_symbolic_header): New function.
+ (ecoff_slurp_symbolic_info): Call ecoff_slurp_symbolic_header.
+ (ecoff_compute_reloc_file_positions): New function.
+ (ecoff_set_section_contents): Get out quickly if count is zero.
+ Check errors better.
+ (ecoff_write_object_contents): Put .xdata section in data segment.
+ Call ecoff_compute_reloc_file_positions. Don't output relocs or
+ external symbols if outsymbols is NULL.
+ (ecoff_bfd_final_link): Completely rewritten.
+ * libecoff.h: Include bfdlink.h.
+ (struct ecoff_backend_data): Add relocate_section field.
+ (ecoff_data_type): Add sym_hashes and symndx_to_section fields.
+ (struct ecoff_link_hash_entry): Define.
+ (struct ecoff_link_hash_table): Define.
+ (ecoff_bfd_link_add_symbols): Declare as function, not macro.
+ (ecoff_bfd_link_hash_table_create): Likewise.
+ * ecofflink.c (bfd_ecoff_debug_one_external): New function.
+ (bfd_ecoff_debug_externals): Call bfd_ecoff_debug_one_external.
+ * bfd-in.h (bfd_ecoff_debug_one_external): Declare.
+ * bfd-in2.h: Rebuilt.
+ * coff-alpha.c (alpha_howto_table): Mark BRADDR as
+ partial_inplace, and set the src_mask to 0x1fffff.
+ (alpha_ecoff_get_relocated_section_contents): Remove unused
+ variable gp_warned.
+ (alpha_convert_external_reloc): New static function.
+ (alpha_relocate_section): New static function.
+ (alpha_ecoff_backend_data): Initialize relocate_section field.
+ * coff-mips.c (mips_relocate_refhi): New static function.
+ (mips_relocate_section): New static function.
+ (mips_ecoff_backend_data): Initialize relocate_section field.
+
+ * reloc.c (_bfd_relocate_contents): Corrected signed overflow
+ checking when there is an addend.
+
+ * aoutx.h (NAME(aout,final_link)): Don't abort when trying to link
+ a non a.out file, just pass it to _bfd_default_link_order.
+ (aout_link_input_section_std): When doing a final PC relative link
+ against a section symbol, subtract the VMA of the input section.
+ (aout_link_input_section_ext): Likewise.
+
+ * linker.c (default_indirect_link_order): Renamed from
+ _bfd_generic_indirect_link_order and made static.
+ (_bfd_generic_final_link): Don't switch on link_order type, just
+ call _bfd_default_link_order.
+ (_bfd_default_link_order): Handle bfd_indirect_link_order type.
+ * genlink.h: Removed declaration of
+ _bfd_generic_indirect_link_order.
+ * elf32-mips.c (mips_elf_final_link): Don't switch on link_order
+ type, just call _bfd_default_link_order.
+
+Tue Jan 4 21:23:37 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * linker.c (generic_link_check_archive_element): Base the name of
+ the created common section on the name of the section the symbol
+ came from.
+ (_bfd_generic_link_add_one_symbol): (case BIG): A common symbol
+ must have a section, so don't bother to create one.
+
+Mon Jan 3 15:32:16 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aout-target.h (MY(vec)): Add DYNAMIC to mask of object flags.
+ * aoutf1.h (NAME(aout,sunos4_write_object_contents)):
+ If the DYNAMIC flag is set, set it in the exec header.
+ * aoutx.h (NAME(aout,some_aout_object_p)): If the object is
+ dynamically linked, set the DYNAMIC flag in the BFD.
+ * libaout.h (N_SET_DYNAMIC): New macro.
+ (N_DYNAMIC): Add missing 0 in mask.
+
+Mon Jan 3 11:41:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_get_extr): Don't output section symbols as
+ external symbols.
+
+ * bfd-in.h, hash.c: Change bfd_hash_allocate argument from size_t
+ to unsigned int, because size_t may not be defined in bfd.h.
+ * bfd-in2.h: Rebuilt.
+
+ * bfd-in.h (bfd_get{b,l}[_signed_]{16,32,64}): Declare argument to
+ be a const pointer.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.c (bfd_get{b,l}[_signed_]{16,32,64}): Declare argument to
+ be a const pointer.
+ * targets.c (bfd_target): Change swap function pointers
+ accordingly.
+ * archive.c (do_slurp_coff_armap): Change swap accordingly.
+ * aix386-core.c: Change NO_GET and NO_GETS accordingly.
+ * hppabsd-core.c, hpux-core.c, irix-core.c, osf-core.c,
+ ptrace-core.c, trad-core.c: Change NO_GET and NO_SIGNED_GET
+ accordingly.
+
+ * libbfd-in.h (struct artdata): Added tdata field.
+ (_bfd_add_bfd_to_archive_cache): Declare.
+ (_bfd_get_elt_at_filepos): Declare.
+ (_bfd_snarf_ar_hdr): Renamed from snarf_ar_hdr.
+ * libbfd.h: Rebuilt.
+ * archive.c: Cleaned up some more.
+ (_bfd_generic_mkarchive, bfd_generic_archive_p): Initialize
+ pointer elements of artdata.
+ (_bfd_add_bfd_to_archive_cache): Renamed from add_bfd_to_cache.
+ (_bfd_snarf_ar_hdr): Renamed from snarf_ar_hdr.
+ (_bfd_get_elt_at_filepos): Renamed from get_elt_at_filepos.
+ (get_extended_arelt_filename, bfd_construct_extended_name_table,
+ bfd_ar_hdr_from_filesystem, compute_and_write_armap): Made static.
+ * ecoff.c: Some comment changes.
+ (ecoff_slurp_armap): Handle rename of snarf_ar_hdr. Set
+ ardata->tdata to raw_armap.
+ (ecoff_archive_p): Initialize pointer elements of artdata.
+ * coff-rs6000.c (rs6000coff_get_elt_at_filepos): Handle rename of
+ add_bfd_to_cache.
+
+ * hash.c: Added some documentation.
+
+Mon Jan 3 11:09:28 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aout-target.h, netbsd386.c: Replace NO_SWAP_MAGIC with SWAP_MAGIC,
+ and do the swapping here rather than calling ntohl from the N_*
+ macros. This cleans up assumptions about the size of a host long,
+ the existence to ntohl, etc.
+
+Sat Jan 1 13:50:05 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config.bfd: Add support for VSTa micro-kernel. It currently uses
+ i386-aout.
+
+Sat Jan 1 10:18:54 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * hosts/i386mach3.h (HOST_SEGMENT_SIZE): Fix value.
+ * i386mach3.c (SEGMENT_SIZE): Fix value.
+
+For older changes see ChangeLog-9193
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-9697 b/bfd/ChangeLog-9697
new file mode 100644
index 00000000000..dc22c8c7c8b
--- /dev/null
+++ b/bfd/ChangeLog-9697
@@ -0,0 +1,6711 @@
+Tue Dec 30 12:45:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_check_relocs): If -Bsymbolic, don't
+ allocate space for a PC relative reloc against a symbol which is
+ defined in a regular file.
+ (elf32_sparc_relocate_section): If -Bsymbolic, don't copy a PC
+ relative reloc against a symbol which is defined in a regular
+ file.
+
+Mon Dec 29 18:02:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Jonathan Stone <jonathan@DSG.Stanford.EDU>:
+ * config.bfd (mips-dec-netbsd*): Add ECOFF vectors to
+ targ_selvecs.
+ (mips*el-*-netbsd*): Like mips-dec-netbsd*.
+ (mips*-*-netbsd*): New target.
+
+Mon Dec 29 17:13:28 1997 H.J. Lu (hjl@gnu.org)
+
+ * elflink.h (elf_link_assign_sym_version): Change error message
+ from "undefined version name" to "undefined versioned symbol
+ name".
+
+Mon Dec 29 11:41:16 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Fix typo from previous
+ delta.
+
+Tue Dec 23 17:01:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd-in.h (_bfd_dwarf2_find_nearest_line): Declare.
+ * libbfd.h: Rebuild.
+
+ * peicode.h (coff_swap_scnhdr_out): Set .reloc section to be
+ shared. Set stab* sections to be shared and read. Set .rsrc
+ section to be read and shared.
+
+Mon Dec 22 13:20:57 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (ALL_MACHINES_CFILES): Add dwarf2.lo.
+ (ALL_MACHINES_CFILES): Add dwarf2.c.
+ * Makefile.in: Rebuild.
+
+ * coff-arm.c: Don't include obstack.h.
+
+Mon Dec 22 13:04:33 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * config.bfd (i[3456]86*-go32-rtems*): Fix to be the same as
+ i[3456]86-go32.
+
+Thu Dec 18 16:01:25 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * configure: Regenerate to get @SHELL@ substituted.
+
+Wed Dec 17 09:45:09 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Only look at section
+ owner if there is one.
+
+ * elf.c (assign_file_positions_for_segments): Fail if there is not
+ enough room for the program headers.
+
+Tue Dec 16 08:09:56 1997 Gavin Koch <gavin@cygnus.com>
+
+ * elf.c (_bfd_elf_find_nearest_line): Call
+ _bfd_dwarf2_find_nearest_line first.
+ * elf32-mips.c (_bfd_mips_elf_find_nearest_line): Same.
+ * dwarf2.c: New file; implement _bfd_dwarf2_find_nearest_line.
+
+Mon Dec 15 16:08:52 1997 Nick Clifton <nickc@cygnus.com>
+
+ * archures.c: Add bfd_mach_m32r.
+
+Mon Dec 15 16:11:22 1997 Fred Fish <fnf@cygnus.com>
+
+ * coffcode.h (ALIGN_SECTIONS_IN_FILE): Define if I960 not defined.
+ (coff_compute_section_file_positions): Use ALIGN_SECTIONS_IN_FILE
+ to decide when to align the file sections for paging.
+ * coffcode.h (ALIGN_SECTIONS_IN_FILE): Undefine for TIC80COFF.
+
+Mon Dec 15 15:01:15 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_object_p): New Function.
+ (m32r_elf_final_write_processing): New Function.
+ (m32r_elf_set_private_flags): New Function.
+ (m32r_elf_copy_private_bfd_data): New Function.
+ (m32r_elf_merge_private_bfd_data): New Function.
+ (m32r_elf_print_private_bfd_data): New Function.
+ (elf_backend_object_p): Point to m32r_object_p.
+ (elf_backend_final_write_processing): Point to
+ m32r_elf_final_write_processing.
+ (bfd_elf32_bfd_copy_private_bfd_data): Point to
+ m32r_elf_copy_private_bfd_data.
+ (bfd_elf32_bfd_merge_private_bfd_data): Point to
+ m32r_elf_merge_private_bfd_data.
+ (bfd_elf32_bfd_set_private_flags): Point to
+ m32r_elf_set_private_bfd_data.
+ (bfd_elf32_bfd_print_private_bfd_data): Point to
+ m32r_elf_print_private_bfd_data.
+
+
+ * bfd-in2.h (bfd_mach_m32r): Add identifier for M32R architecture
+ machines.
+
+Fri Dec 12 11:30:28 1997 Brendan Kehoe <brendan@canuck.cygnus.com>
+
+ * configure: Only build libbfd shared if --enable-shared's value
+ was `yes', or was set to `*bfd*'.
+ * aclocal.m4: Likewise.
+ * NOTE: this really needs to be fixed in libtool/libtool.m4, the
+ original source of this bit of code. It's not clear what the best fix
+ would be, though.
+
+Thu Dec 11 17:48:11 1997 Richard Henderson <rth@cygnus.com>
+
+ * linker.c (generic_link_add_symbol_list): Always init udata.p so
+ that the generic relaxation code can function when input and output
+ file formats are mismatched.
+
+Thu Dec 11 01:02:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (bfd_coff_small_swap_table): Initialize new fields.
+
+ * elf.c (assign_file_positions_for_segments): For a loadable
+ section, make sure that the load address is correct relative to
+ the load address of the segment plus the size of the segment so
+ far.
+
+ * coffcode.h (_coff_link_output_has_begun): Make static.
+ (_coff_final_link_postscript): Likewise.
+
+Wed Dec 10 23:37:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_input_bfd): Handle a relocateable link in
+ which a relocation refers to an indirect or warning symbol.
+
+Wed Dec 10 11:15:55 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (bfd_arm_coff_final_link): Function deleted.
+ (coff_arm_final_link_postscript): New function.
+ (coff_arm_link_output_has_begun): New function.
+
+ * libcoff.h (struct bfd_coff_backend_data): Add new fields:
+ _bfd_coff_link_output_has_begun and
+ _bfd_coff_final_link_postscript. Add new macros:
+ bfd_coff_link_output_has_begun() and
+ bfd_coff_final_link_postscript().
+
+ * cofflink.c (_bfd_coff_final_link): Insert calls to
+ bfd_coff_link_output_has_begun() and
+ bfd_coff_final_link_postscript().
+
+ * coffcode.h: Add two new fields to bfd_coff_backend_data
+ structure: _bfd_coff_link_output_has_begun and
+ _bfd_coff_final_link_postscript. Add default initialisers for
+ these fields. Add overridable aliases for the coff swap functions
+ in the backend data structure.
+
+ * elf32-v850.c: Update with patches from the branch to fix
+ HI16_S/LO16 reloc pairs.
+
+Wed Dec 10 14:06:48 1997 Michael Meissner <meissner@cygnus.com>
+
+ * elf32-d30v.c (d30v_info_to_howto_rela): New function to support
+ RELA relocations.
+ (USE_REL): Don't define any more, switch to using RELA
+ relocations.
+ (elf_info_to_howto): Define as d30v_info_to_howto_rela.
+
+Tue Dec 9 11:37:53 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * archures.c (bfd_mach_mips*): Define.
+ (bfd_default_scan): For 3000 and 4000 replace magic constant with
+ macro.
+
+ * cpu-mips.c (N): Define.
+ (bfd_mips_arch, arch_info_struct): Re-write using macro N, replace
+ numbers with bfd_mach_mips* macros.
+
+Fri Dec 5 11:13:46 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_reloc, v850_elf_store_addend_in_insn,
+ v850_elf_relocate_section): Fix reloc addend handling.
+ (v850_elf_section_from_bfd_section, v850_elf_symbol_processing,
+ v850_elf_add_symbol_hook, v850_elf_link_output_symbol_hook,
+ v850_elf_section_from_shdr, v850_elf_fake_sections): New functions
+ to create and handle special common sections.
+ (v850_elf_final_link_relocate): Fix HI16 and HI16_S relocations
+ which have data stored in the instructions.
+
+Tue Dec 2 10:26:16 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (TARGET_UNDERSCORE): Revert back to '_'
+ (USER_LABEL_PREFIX): Revert back to '_'
+
+ * config.bfd (targ_cpu): Add support for Thumb target.
+
+Mon Dec 1 20:24:18 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * coff-sh.c (sh_coff_howtos): Add R_SH_SWITCH8 entry.
+ (get_symbol_value): Handle R_SH_SWITCH8.
+ (sh_relax_delete_bytes): Likewise.
+
+Wed Nov 26 14:13:34 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (TARGET_UNDERSCORE): Changed to match definition in
+ gcc/config/arm/semi.h
+
+ * coffcode.h (coff_slurp_symbol_table): Add ARM and Thumb symbol
+ classes.
+
+Sun Nov 23 16:02:58 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * freebsd.h (SWAP_MAGIC): Read magic number little and not big
+ endian.
+
+Wed Nov 26 09:30:37 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coffcode.h (coff_mkobject_hook): Only set private flags for non
+ PE ARM ports.
+
+Tue Nov 25 15:33:23 1997 Richard Henderson <rth@cygnus.com>
+
+ * binary.c (binary_set_section_contents): Also ignore NEVER_LOAD
+ sections.
+
+Tue Nov 25 10:55:36 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (coff_arm_bfd_merge_private_bfd_data): Do not
+ complain if inout and output formats differ.
+
+Tue Nov 25 11:26:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (BFD32_BACKENDS): Remove tekhex.lo.
+ (BFD32_BACKENDS_CFILES): Remove tekhex.c.
+ * Makefile.in: Rebuild.
+ * aclocal.m4, configure, src/Makefile.in: Rebuild with current
+ automake and autoconf.
+
+ * coff-arm.c (arm_allocate_interworking_sections): Fix typo
+ (COFF_WITH_PR to COFF_WITH_PE).
+
+Mon Nov 24 15:47:49 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c: Make variables and some functions static, so that
+ this file can be included in multiple object files.
+ (coff_arm_bfd_final_link): Fix minor bug.
+
+Sat Nov 22 15:16:00 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c: Add support for PIC and APCS-FLOAT type binaries.
+
+ * coffcode.h: Add support for PIC and APCS-FLOAT type binaries.
+
+Sat Nov 22 16:06:56 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * evax-emh.c (_bfd_evax_write_emh): Use alloca instead of strdup.
+
+Sat Nov 22 12:29:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_add_one_symbol): When overriding a defined
+ symbol, set it to undefined, not new.
+
+ * elf32-sh.c (sh_elf_relax_delete_bytes): Don't kill LABEL
+ relocs.
+
+Fri Nov 21 14:14:22 1997 Richard Henderson <rth@cygnus.com>
+
+ * coff-sh.c (sh_relax_section): Force sign extention of USES r_offset.
+ (sh_relax_delete_bytes): Don't kill LABEL relocs.
+
+Mon Nov 17 15:08:38 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf-m10300.c (elf32_mn10300_finish_hash_table_entry): Fix typo.
+ (mn10300_elf_relax_section): Likewise.
+
+Sat Nov 15 15:36:07 1997 Fred Fish <fnf@cygnus.com>
+
+ * peicode.h (coff_swap_aouthdr_in): Cast second arg of
+ bfd_h_get_* calls to "bfd_byte *".
+
+Tue Nov 11 10:37:23 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf-m10300.c (elf32_mn10300_link_hash_entry): Add new field
+ "movm_stack_size".
+ (mn10300_elf_relax_section): Include stack space for register saves
+ in the imm8 field of a "call" instruction.
+ (compute_function_info): Determine how much stack is allocated by
+ the movm instruction. Fix typo.
+ (elf32_mn10300_link_hash_newfunc): Initialize movm_stack_size.
+
+Mon Nov 10 14:32:40 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Don't crash if
+ a version dependency could not be found.
+
+Tue Nov 4 12:05:56 1997 Klaus K"ampf <kkaempf@progis.de>
+
+ * configure.com: Get version info from configure.in
+
+Fri Oct 24 11:15:58 1997 Jakub Jelinek <jj@sunsite.mff.cuni.cz>
+
+ * elf64-sparc.c (sparc64_elf_merge_private_bfd_data):
+ New function. Avoid mixing US1 and HAL R1 code.
+ Set resulting memory ordering to the strongest one used.
+ (sparc64_elf_object_p): Set bfd_mach correctly.
+
+Thu Oct 23 14:09:33 1997 Richard Henderson <rth@cygnus.com>
+
+ * elf64-sparc.c (sparc64_elf_howto_table): Add UA64 & UA16.
+ (sparc64_elf_check_relocs): Handle them.
+ (sparc64_elf_relocate_section): Likewise. Before emitting a dyn reloc,
+ check alignment and transmute R_SPARC_x<->R_SPARC_UAx.
+
+Thu Oct 23 00:53:14 1997 Richard Henderson <rth@dot.cygnus.com>
+
+ * configure.in (sparc*-*-linux*): Use trad-core and ...
+ * hosts/sparclinux.h: New file.
+
+Thu Oct 23 00:25:29 1997 Richard Henderson <rth@dot.cygnus.com>
+
+ * config.bfd (sparc64-*-linux*): New target.
+
+ * elf-bfd.h (struct elf_backend_data): Add plt_alignment member.
+ * elflink.c (_bfd_elf_create_got_section): Set .got alignment based
+ on arch_size.
+ (_bfd_elf_create_dynamic_sections): Likewise for .rel* sections.
+ Set .plt alignment from new plt_alignment.
+ * elflink.h (elf_link_create_dynamic_sections): Set version section
+ alignment to LOG_FILE_ALIGN.
+ * elfxx-target.h (elf_backend_plt_alignment): Provide default.
+ (elfXX_bed): Init plt_alignment.
+
+ * elf64-sparc.c (sparc64_elf_check_relocs,
+ sparc64_elf_adjust_dynamic_symbol, sparc64_elf_size_dynamic_sections,
+ sparc64_elf_adjust_dynindx, sparc64_elf_finish_dynamic_symbol,
+ sparc64_elf_finish_dynamic_sections): New functions.
+ (sparc64_elf_howto_table): Fix a few name strings.
+ (ELF_DYNAMIC_INTERPRETER): New definition.
+ (sparc64_elf_relocate_section): Handle shared libraries.
+
+ * elf64-sparc.c (struct plt_template, plt_*_header, plt_*_entry,
+ sparc64_elf_build_plt_entry, sparc64_elf_finish_dynamic_symbol):
+ PLT definitions sparc64-linux originally choose. These will go
+ away soon in favour of the official abi definitions.
+
+Wed Oct 22 16:08:45 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (coff_small_object_p): New static function.
+ (coff_small_new_section_hook): New static function.
+ (bfd_coff_small_swap_table): New static const structure.
+ (coff_small_close_and_cleanup): Define.
+ (coff_small_bfd_free_cached_info): Define.
+ (coff_small_get_section_contents): Define.
+ (coff_small_get_section_contents_in_window): Define.
+ (shcoff_small_vec): New static structure.
+ (shlcoff_small_vec): New static structure.
+ * targets.c (bfd_target_vector): Add shcoff_small_vec and
+ shlcoff_small_vec.
+ * config.bfd (sh-*-elf*): Add shcoff_small_vec and
+ shlcoff_small_vec to targ_selvecs.
+ (sh-*-*): Likewise.
+ * configure.in: Add shcoff_small_vec and shlcoff_small_vec cases.
+ * configure: Rebuild.
+
+Mon Oct 20 15:01:27 1997 Klaus K"ampf <kkaempf@progis.de>
+
+ * evax-egsd.c: Weak symbols are global.
+
+ * evax-emh.c: Use proper casts.
+
+ * evax-egsd.c (_bfd_evax_write_egsd): Remove unneeded uname.
+
+ * evax-egsd.c: Section names and symbols have different
+ length restrictions. Add length parameter to
+ _bfd_evax_length_hash_symbol.
+ * evax-etir.c: Likewise.
+ * evax-misc.c (_bfd_evax_length_hash_symbol): Add length
+ parameter.
+ * evax.h (EOBJ_S_C_SECSIZ): Define.
+
+ * evax-alpha.c: Remove duplicate test.
+
+ * evax-emh.c: SYS$ functions are upper-case.
+
+ * evax-egsd.c: Create separate sections for common symbols.
+ * evax-etir.c: Don't output common section.
+ * evax.h: Bump up section count.
+
+ * configure.com: Use 64bit integers with DEC C.
+
+ * evax-egsd.c: Make section flags dec c compatible.
+
+Mon Oct 20 09:38:31 1997 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (normalize): Delete function.
+ (som_bfd_ar_write_symbol_stuff): New parameter elength. All callers
+ changed. Use passed in elength to determine size of the extended
+ name table instead of computing it again.
+
+Sun Oct 19 23:36:21 1997 Jim Wilson <wilson@cygnus.com>
+
+ * peicode.h (coff_swap_scnhdr_out): Use |= not = to set
+ IMAGE_SCN_MEM_READ for an unrecognized section.
+
+Sun Oct 19 21:04:56 1997 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_bfd_ar_write_symbol_stuff): Account for trailing
+ '/' in the extended name table.
+
+Fri Oct 17 00:04:13 1997 Richard Henderson <rth@cygnus.com>
+
+ * elflink.h (elf_link_assign_sym_version): For explicitly versioned
+ symbols, check globals list before matching on locals.
+
+Thu Oct 16 08:17:06 1997 Michael Meissner <meissner@cygnus.com>
+
+ * peicode.h (coff_swap_scnhdr_out,pe_print_idata): Fix mangled
+ patch.
+
+Wed Oct 15 13:45:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (pe_mkobject_hook): Set DLL flag.
+ (pe_bfd_copy_private_bfd_data): Copy DLL flag.
+
+ * peicode.h (coff_swap_scnhdr_out): Set IMAGE_SCN_MEM_DISCARDABLE
+ for .stab* sections. Replace strlen of constant strings with
+ number.
+
+Tue Oct 14 15:42:45 1997 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_merge_ind_symbols): New function to
+ merge got and reloc entries from ind syms to their target.
+ (elf64_alpha_always_size_sections): Call it.
+ (elf64_alpha_check_relocs): Operate on the target of indirect symbols.
+ (elf64_alpha_can_merge_gots): Likewise.
+ (elf64_alpha_merge_gots): Likewise.
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Back out HJ's change,
+ as it is insufficient to handle the relocation changes as well.
+
+Mon Oct 13 23:10:08 1997 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_calc_dynrel_sizes): Allow for RELATIVE
+ relocs for symbols in shlibs that have been forced local.
+ (elf64_alpha_relocate_section): Output RELATIVEs in .got for same.
+
+Mon Oct 13 21:24:04 1997 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Use the
+ got_enties of the default symbol for the default versioned
+ symbol. Patch from hjl@gnu.ai.mit.edu, modified not to use
+ alloca in the loop.
+
+Mon Oct 13 17:37:37 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_final_link_relocate): Only use the bottom
+ 24 bits of the PC when computing a PC relative relocation.
+
+Fri Oct 10 16:01:30 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_reloc, v850_elf_final_link_relocate):
+ Correct value for maximum positive 22 bit PC relative relocation.
+ (v850_elf_final_link_relocate): Prevent overflow from HI16_S and
+ HI_16 relocations. Correct bit adjustment in TDA offsets.
+
+Thu Oct 9 16:43:39 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf64-sparc.c (sparc_elf_{hix22,lox10}_reloc): New functions.
+ (sparc64_elf_howto_table): Use them for HIX22,LOX10 relocs.
+
+Wed Oct 8 11:38:45 1997 Richard Henderson <rth@cygnus.com>
+
+ * elfcore.h (bfd_prstatus): Pedanticly, alignment_power should
+ be LOG_FILE_ALIGN.
+
+Wed Oct 8 11:36:00 1997 Richard Henderson <rth@cygnus.com>
+
+ * config.bfd: Missed one alpha* change.
+
+Tue Oct 7 13:00:17 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): Remove BFD64 support.
+ * elf64-sparc.c (SPARC64_OLD_RELOCS): Undef.
+ (MINUS_ONE): New macro.
+ (sparc_elf_notsup_reloc): New function.
+ (sparc64_elf_howto_table): Add entries for DISP64,PLT64,HIX22,LOX10,
+ H44,M44,L44,REGISTER.
+ (sparc_reloc_map): Likewise. Map BFD_RELOC_CTOR to R_SPARC_64.
+ (init_insn_reloc): New function.
+ (sparc_elf_wdisp16_reloc): Use it.
+ (sparc64_elf_relocate_section): Add entries for OLO10,HIX22,LOX10.
+
+Tue Oct 7 11:40:37 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * som.c (som_construct_extended_name_table): Remove static
+ function, and define as macro instead.
+
+Fri Oct 3 14:02:17 1997 Richard Henderson <rth@cygnus.com>
+
+ * config.bfd: Change alpha-*-* to alpha*-*-*; config.guess now
+ recognizes alphaev5 etc.
+ * configure.host: Likewise.
+
+Fri Oct 3 11:23:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Make ld -s work on AIX:
+ * xcofflink.c (xcoff_link_add_symbols): Don't create the .debug
+ section if we are stripping.
+ (bfd_xcoff_size_dynamic_sections): Don't set the .debug section
+ size if we are stripping.
+ (_bfd_xcoff_bfd_final_link): Don't set SEC_RELOC or rel_filepos,
+ and don't write out relocs, if we are stripping.
+ (xcoff_link_input_bfd): Don't set up reloc if we are stripping.
+ (xcoff_write_global_symbol): Don't write out symbol or reloc if we
+ are stripping.
+
+ * configure.in: Don't include elf.lo again for ELF targets; it's
+ always in the library anyhow.
+ * configure: Rebuild.
+
+ * bfd-in2.h: Rebuild.
+
+ * elf32-sparc.c (sparc_elf_wdisp16_reloc): Cast to bfd_byte *, not
+ char *, when calling bfd_get_32 and bfd_put_32.
+ * sunos.c (sunos_scan_dynamic_symbol): Cast contents to char *
+ when calling strcpy.
+
+Thu Oct 2 16:15:50 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * reloc.c (bfd_check_overflow): New function.
+ (bfd_perform_relocation, bfd_install_relocation): Use it.
+ (BFD_RELOC_SPARC_{DISP64,PLT64}): New relocs.
+ (BFD_RELOC_SPARC_{HIX22,LOX10,H44,M44,L44,REGISTER}): New relocs.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+Thu Oct 2 13:17:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (coff_swap_scnhdr_out): Set IMAGE_SCN_MEM_READ for an
+ unrecognized section. From Jon Thackray <jont@harlequin.co.uk>.
+
+Wed Oct 1 14:03:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am ($(BFD_H)): Change stmp-bfd.h to stmp-bfd-h.
+ (stmp-bfd-h): Rename from stmp-bfd.h.
+ (BFD_H_FILES, LIBBFD_H_FILES, LIBCOFF_H_FILES): New variables.
+ ($(srcdir)/bfd-in2.h): Just depend upon stmp-bin2-h.
+ (stmp-bin2-h): New target.
+ ($(srcdir)/libbfd.h): Just depend upon stmp-lbfd-h.
+ (stmp-lbfd-h): New target.
+ ($(srcdir)/libcoff.h): Just depend upon stmp-lcoff-h.
+ (stmp-lcoff-h): New target.
+ (CLEANFILES): Change stmp-bfd.h to stmp-bfd-h. Add stmp-bin2.h,
+ stmp-lbfd-h, and stmp-lcoff-h.
+ * Makefile.in: Rebuild.
+
+ * configure.in: Use a diversion to set enable_shared before the
+ arguments are parsed.
+ * configure: Rebuild.
+
+Tue Sep 30 14:18:32 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): R_SPARC_GLOB_JMP
+ renamed to R_SPARC_UNUSED_42.
+ (sparc_reloc_map): Delete R_SPARC_GLOB_JMP entry.
+ * elf64-sparc.c (_bfd_sparc_elf_howto_table): R_SPARC_GLOB_JMP
+ renamed to R_SPARC_UNUSED_42.
+ (sparc_reloc_map): Delete R_SPARC_GLOB_JMP entry.
+ * reloc.c (BFD_RELOC_SPARC_GLOB_JMP): Delete.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+
+Thu Sep 25 12:15:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_merge_symbol): Don't check the hash creator until
+ after we have set *sym_hash.
+
+Wed Sep 24 16:52:28 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * config.bfd (sh*-*-rtems*): New target, like sh-*-*elf*.
+
+Wed Sep 24 11:27:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (libbfd_a_SOURCES): Define.
+ * Makefile.in: Rebuild.
+
+ * configure.in: Call AC_CHECK_TOOL before AM_PROG_LIBTOOL.
+ * aclocal.m4: Rebuild with new libtool.
+ * configure: Rebuild.
+
+Tue Sep 23 19:03:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (map_sections_to_segments): Even if we are not demand
+ paged, don't put a loadable section after a nonloadable section.
+ (assign_file_positions_for_segments): Increment the file offset
+ for a section with contents, even if it is not loadable.
+
+Sun Sep 21 11:03:24 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_final_link_relocate): Add return code
+ indicating that __ctbp could not be found.
+
+Thu Sep 18 15:04:57 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_check_relocs): Improve error message.
+
+Wed Sep 17 09:54:51 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_final_link_relocate, v850_elf_reloc,
+ v850_elf_check_relocs, v850_elf_reloc_map, v850_elf_howto_table):
+ Add support for the CALLT relocs.
+
+ * reloc.c (COMMENT): Add BFD_RELOC_V850_CALLT_6_7_OFFSET and
+ BFD_RELOC_V850_CALLT_16_16_OFFSET.
+
+ * elf32-v850.c (v850_elf_final_link_relocate): Add checks to catch
+ relocations against non-existant symbols.
+
+Tue Sep 16 14:20:27 1997 Nick Clifton <nickc@cygnus.com>
+
+ * reloc.c: Add BFR_RELOC_V850_TDA_16_16_OFFSET.
+
+ * elf32-v850.c (v850_elf_reloc, v850_elf_final_link_relocate,
+ v850_elf_howto_table, v850_elf_reloc_map): Add support for a 16
+ bit reloc in the tiny data area.
+
+Mon Sep 15 11:27:36 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merged changes from Martin Hunt:
+
+ * elf32-d30v.c (bfd_elf_d30v_reloc): Change pc-relative relocs
+ over 2^32 bytes to be absolute. Needed because D30V PC doesn't
+ necessarily wrap.
+
+ * reloc.c, elf32-d30v.c (BFD_RELOC_D30V_9_PCREL,
+ BFD_RELOC_D30V_9_PCREL_R): New relocs.
+
+ * elf32-d30v.c (bfd_elf_d30v_reloc_21): New function.
+ Do 15 and 21 bit pc-relative relocations.
+ * reloc.c (BFD_RELOC_D30V_15_PCREL_R, BFD_RELOC_D30V_21_PCREL_R):
+ New relocations.
+
+ * elf32-d30v.c (bfd_elf_d30v_reloc): Addend needs to be
+ added to the relocation, not or'd.
+
+Wed Sep 10 15:17:25 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_reloc): Remove spurious error message.
+
+Wed Sep 10 11:17:50 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * archures.c (bfd_default_scan): Use strcasecmp.
+ (bfd_default_scan): Test for match with arch_name + ":" +
+ printable_name.
+ (bfd_default_scan): Test for match with printable_name - ":".
+ (bfd_default_scan): Delete w65, h8300, h8500, z8k, i960 special
+ cases. Each implements their own scan function.
+ (bfd_default_scan): Delete 386, 2900, 860, mips 2000, mips 4400
+ special cases. Since info->mach == 0. The test mach == number
+ fails.
+ (bfd_arch_list): New function, return name of all the supported
+ architectures.
+
+Tue Sep 9 10:21:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_print_private_bfd_data): Break after
+ decoding architecture.
+ (v850_elf_reloc): Do not complain if a R_V850_LO16 reloc has bit
+ 15 set.
+
+Sun Sep 7 12:25:22 1997 H.J. Lu (hjl@gnu.ai.mit.edu)
+
+ * bfd/elf64-alpha.c (reloc_howto_type): Fix the howto table.
+
+Thu Sep 4 09:44:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (ALL_MACHINES_CFILES): Add cpu-v850.c.
+ (ALL_MACHINES_CFILES): Add elf32-v850.c.
+ * Makefile.in: Rebuild.
+
+ * reloc.c: Remove extraneous commas from relocation entries.
+ Remove BFD_RELOC_V850_16_PCREL.
+ * bfd-in2.h: Rebuild.
+
+ * xcofflink.c (xcoff_link_add_symbols): Put XTY_CM/XMC_TD symbols
+ in sections named .tocbss rather than .bss.
+
+Wed Sep 3 11:23:23 1997 Nick Clifton <nickc@cygnus.com>
+
+ * libbfd.h, bfd-in2.h, elf32-v850.c: Removed
+ BFD_RELOC_V850_16_PCREL.
+
+Tue Sep 2 20:44:10 1997 Fred Fish <fnf@cygnus.com>
+
+ * cofflink.c (coff_link_check_ar_symbols): Handle C_SYSTEM syms
+ the same as C_EXT syms.
+ (coff_link_add_symbols): Ditto.
+ (_bfd_coff_link_input_bfd): Ditto.
+ (_bfd_coff_write_task_globals): Add save_global_to_static. Use
+ it to preserve and restore state of global_to_static flag.
+
+Tue Sep 2 17:45:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_object_p): Set machine number based on
+ bits in e_flags field rather than magic numbers.
+ (v850_elf_final_write_processing, v850_elf_set_private_flags,
+ v850_elf_copy_private_bfd_data, v850_elf_merge_private_bfd_data,
+ v850_elf_print_private_bfd_data): New functions.
+
+Tue Sep 2 17:43:49 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (prep_headers): Remove V850E magic number.
+ * elf.c (prep_headers): Remove V850EA magic number.
+
+Tue Sep 2 17:35:05 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cpu-arc.c (arc_get_mach): Properly scan defined mach entries.
+
+Tue Sep 2 18:29:37 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf-m10200.c (mn10200_elf_final_link_relocate): PC relative
+ instructions are relative to the next instruction, not the
+ current instruction.
+ (mn10200_elf_relax_section): Similarly.
+
+Tue Sep 2 15:45:45 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-v850.c: Use a macro to construct bfd_arch_info_type
+ entries.
+
+ * reloc.c, libbfd.h, bfd-in2.h, elf32-v850.c: Replace
+ BFD_RELOC_V850_{SDA/TDA/ZDA}_OFFSET relocs with new bit pattern
+ specific versions: BFD_RELOC_V850_{area}_{bits}_OFFSET.
+
+Thu Aug 28 17:01:09 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * cpu-v850.c: Remove "plain" from v850 printable name.
+ (scan): Use strcasecmp.
+
+ * archures.c (bfd_mach_v850): Define.
+
+ * cpu-sh.c (scan_mach): Compare with table instead of hardwired to
+ just sh/SH, use strcasecmp.
+ (arch_info_struct): Add entries for sh3 et.al.
+
+ * archures.c (bfd_mach_sh, ...): Define.
+
+Wed Aug 27 17:33:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * archures.c (bfd_archures_list): Always NULL terminate the list.
+
+Tue Aug 26 17:26:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (ALL_MACHINES_CFILES): Add cpu-arc.c.
+ (ALL_MACHINES_CFILES): Add elf32-arc.c.
+ (elf32-arc.lo): Remove explicit dependency.
+ * Makefile.in: Rebuild.
+
+ * acinclude.m4 (BFD_CC_FOR_BUILD): Set EXEEXT_FOR_BUILD.
+ * doc/Makefile.am (MKDOC): Use EXEEXT_FOR_BUILD, not EXEEXT.
+ * aclocal.m4, configure, Makefile.in, doc/Makefile.in: Rebuild.
+
+Mon Aug 25 16:14:34 1997 Christopher Provenzano <proven@cygnus.com>
+
+ * configure: Rebuild with latest devo autoconf for NT support
+
+Mon Aug 25 16:11:04 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-arm.c (compatible): If B is a default type, return A.
+
+Mon Aug 25 15:35:46 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-v850.c (scan): New function.
+ (arch_info_struct): New structure.
+ (bfd_v850_arch): Add link into arch_info_structure.
+
+ * config.bfd (targ_cpu): All v850 variants use the bfd_arch_v850
+ architecture.
+
+ * elf32-v850.c (v850_elf_object_p): New function.
+
+ * archures.c (bfd_mach_v850e): Machine value for v850e.
+
+ * bfd-in2.h (bfd_mach_v850e): Machine value for v850e.
+
+ * elf32-v850.c (ELF_MACHINE_CODE): Default to v850e machine
+ number.
+
+ * elf.c (prep_headers): Add support for v850e machine number.
+
+ * archures.c (bfd_mach_v850ea): Machine value for v850ea.
+
+ * bfd-in2.h (bfd_mach_v850ea): Machine value for v850ea.
+
+ * elf32-v850.c (ELF_MACHINE_CODE): Default to v850ea machine
+ number.
+
+ * elf.c (prep_headers): Add support for v850ea machine number.
+
+Mon Aug 25 14:07:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Clear the
+ cached_stab field if the offset prevents us from using the cache.
+
+Mon Aug 25 12:08:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aout-target.h (MY(vec)): Add SEC_CODE and SEC_DATA to section
+ flags.
+ * aout-arm.c (aout_arm_little_vec): Likewise.
+ (aout_arm_big_vec): Likewise.
+ * bout.c (b_out_vec_big_host): Likewise.
+ (b_out_vec_little_host): Likewise.
+ * mipsbsd.c (aout_mips_little_vec): Likewise.
+ (aout_mips_big_vec): Likewise.
+
+Tue Aug 19 10:09:10 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (COFF_ALIGN_IN_SFLAGS): Define to 1.
+ * coffcode.h (styp_to_sec_flags): Ignore incoming STYP_INFO
+ bit in s_flags if COFF_ALIGN_IN_S_FLAGS is defined.
+
+Tue Aug 19 08:47:17 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-i960.c (COFF_ALIGN_IN_SECTION_HEADER): Define to 1.
+ (GET_SCNHDR_ALIGN, PUT_SCNHDR_ALIGN): Define.
+ * coff-m88k.c (GET_SCNHDR_NRELOC, GET_SCNHDR_NLNNO): Define.
+ * coffcode.h (coff_set_alignment_hook): Conditionally compile in if
+ COFF_ALIGN_IN_SECTION_HEADER is defined. Convert alignment to power
+ of two for I960 only.
+ * coffswap.h (GET_SCNHDR_NRELOC, PUT_SCNHDR_NRELOC, GET_SCNDHR_NLNNO,
+ PUT_SCNHDR_NLNNO, GET_SCNHDR_FLAGS, PUT_SCNHDR_FLAGS): Provide
+ default definitions.
+ (coff_swap_scnhdr_in): Use GET_SCNHDR_FLAGS, GET_SCNHDR_NRELOC,
+ GET_SCNHDR_NLNNO, and GET_SCNHDR_ALIGN.
+ (coff_swap_scnhdr_out): Use PUT_SCNHDR_FLAGS, PUT_SCNHDR_ALIGN.
+ * Makefile.in (coff-tic80.o): Depends upon coffswap.h.
+ * coff-tic80.c (COFF_ALIGN_IN_SECTION_HEADER): Define to 1.
+ (GET_SCNHDR_FLAGS, PUT_SCNHDR_FLAGS): Define
+ * coffcode.h (coff_write_object_contents): Set alignment field in
+ section header for TIC80COFF files.
+
+Mon Aug 18 11:36:19 1997 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_howto_table, v850_elf_reloc_map,
+ v850_elf_check_relocs, v850_elf_reloc,
+ v850_elf_final_link_relocate): Add support for
+ BFD_RELOC_V850_16_PCREL relocation.
+
+ * reloc.c (COMMENT): Add suuport for BFD_RELOC_V850_16_PCREL
+ relocation.
+
+ * libbfd.h: Add support for BFD_RELOC_V850_16_PCREL relocation.
+
+ * bfd-in2.h: Add support for BFD_RELOC_V850_16_PCREL relocation.
+
+Mon Aug 18 11:33:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-v850e: New file.
+
+ * elf.c (prep_headers): Add support for v850e target.
+
+ * bfd-in2.h (bfd_architecture): Add support for v850e target.
+
+ * config.bfd: Add support for v850e target.
+
+ * archures.c: Add support for v850e target.
+
+Mon Aug 18 11:33:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-v850ea: New file.
+
+ * elf.c (prep_headers): Add support for v850ea target.
+
+ * bfd-in2.h (bfd_architecture): Add support for v850ea target.
+
+ * config.bfd: Add support for v850ea target.
+
+ * archures.c: Add support for v850ea target.
+
+Fri Aug 15 12:01:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgen.c (coff_find_nearest_line): Correctly handle the offset
+ argument as section relative, rather than an absolute address.
+ From Jan Hoogenraad <hoogenrd@natlab.research.philips.com>.
+
+Fri Aug 15 04:58:02 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.bfd (arc-*-elf*): Add.
+ * configure.in (bfd_elf32_{little,big}arc_vec): Add.
+ * configure: Rebuild.
+ * Makefile.am (ALL_MACHINES): Add cpu-arc.lo.
+ (BFD32_BACKENDS): Add elf32-arc.lo.
+ (cpu-arc.lo,elf32-arc.lo): Add rules for.
+ * Makefile.in: Rebuild.
+ * archures.c (architecture list): Add bfd_arch_arc.
+ (bfd_archures_list): Add bfd_arc_arch.
+ (bfd_mach_arc_base): Define.
+ * reloc.c (BFD_RELOC_ARC_B22_PCREL,BFD_RELOC_ARC_B26): Add.
+ * targets.c (bfd_elf32_{little,big}arc_vec): Declare.
+ (bfd_target_vect): Add them.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * cpu-arc.c, elf32-arc.c: New files.
+ * elf.c (pre_headers): Recognize bfd_arch_arc.
+
+Tue Aug 12 11:45:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,final_link)): If no symbols, make sure the
+ data section is correctly rounded to a page in the file.
+
+Mon Aug 11 12:45:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,final_link)): Don't emit the string table if
+ there are no symbols.
+
+Sun Aug 10 14:45:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-stgo32.c: Rename from coff-stubgo32.c to avoid old System V
+ file system 14 character limit.
+ * Makefile.am, configure.in: Corresponding changes.
+ * Makefile.in, configure: Rebuild.
+
+Fri Aug 8 18:34:36 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: (ALL_MACHINES_CFILES): Add elf32-d10v.c.
+ Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+Wed Aug 6 18:56:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (docdir): Define.
+ * Makefile.in: Rebuild.
+
+Tue Aug 5 23:05:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.1.
+
+Mon Aug 4 12:00:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure: Rebuild with new automake patches.
+
+Sun Aug 3 08:15:12 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-core.c (make_bfd_asection): New function to add a section
+ to the core file bfd.
+ (rs6000coff_core_p): Use make_bfd_asection to add the core file
+ sections.
+ Use BFD routines to seek, read and stat the core file.
+ Handle .data sections from loaded objects and anonymously mmapped
+ regions, these are available in AIX 4 core files.
+
+Fri Aug 1 12:58:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set enable_shared before AM_PROG_LIBTOOL.
+ * acinclude.m4: Move acmacros.m4 in here. Remove AM_PROG_LIBTOOL
+ copy; use a patches libtool instead.
+ * acmacros.m4: Remove.
+ * Makefile.in, aclocal.m4, configure: Rebuild.
+
+Thu Jul 31 19:55:36 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * acmacros.m4: New file, copied from old aclocal.m4.
+ * acinclude.m4: New file.
+ * configure.in: Call AM_PROG_LIBTOOL. Remove shared library
+ handling; now handled by libtool. Replace AC_CONFIG_HEADER with
+ AM_CONFIG_HEADER. Replace AC_PROG_INSTALL with AM_PROG_INSTALL.
+ Call AM_MAINTAINER_MODE, AM_CYGWIN32, and AM_EXEEXT. Change all
+ .o files to .lo. Remove stamp-h handling in AC_OUTPUT.
+ * acconfig.h: Mention PACKAGE and VERSION.
+ * stamp-h.in: New file.
+ * dep-in.sed: Change .o to .lo.
+ * Makefile.in: Now built with automake.
+ * aclocal.m4: Now built with aclocal.
+ * config.in, configure: Rebuild.
+ * VERSION: Remove.
+
+Thu Jul 31 12:09:20 1997 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Don't set TEXTREL
+ if there is only a relocation to a read-only but not allocatable
+ section (like .stab).
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Likewise.
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Likewise.
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise.
+ * elf32-mips.c (mips_elf_size_dynamic_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Likewise.
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Correct various comments.
+ (ppc_elf_create_linker_section): These sections are not
+ created by the linker (that is, they are created by the user
+ putting data in them). In particular, they can be the source
+ and target of relocations.
+ (ppc_elf_adjust_dynamic_symbol): Check postcondition of
+ bfd_elf32_link_record_dynamic_symbol. Align 16-byte common
+ objects (for instance, 'long double') to 16-byte boundaries.
+ (ppc_elf_size_dynamic_sections): Make the code that generates
+ section symbols exactly the same as for sparc, reducing the
+ number of section symbols output.
+ (ppc_elf_check_relocs): Check postcondition of
+ bfd_elf32_link_record_dynamic_symbol. Make default case the
+ same as corresponding code for sparc, fixing bug involving
+ .rela.stabs.
+ (ppc_elf_finish_dynamic_symbol): Fix case involving GOT symbols
+ forced to be local because of versioning (by replicating
+ corresponding change in sparc). Treat R_PPC_RELATIVE RELA relocs
+ as usual in ELF, not as pseudo-REL relocs (as the sparc linker
+ does).
+ (ppc_elf_relocate_section): Add handy debugging code for when
+ assertion fails. Add some more 'symbol made local because of
+ versioning' cases.
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Cope with addend when
+ processing a GOT relocation as required by ABI.
+
+Wed Jul 30 21:30:35 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elflink.h (NAME(bfd_elf,record_link_assignment)): Remove any
+ version info if this symbol came from a dynamic object.
+ (elf_link_add_object_symbols): Set the version info of a symbol
+ only if the object actually contains version definitions and
+ defines this symbol.
+
+Mon Jul 28 18:07:43 1997 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * aclocal.m4: Add CYGWIN and EXEEXT autoconf macros.
+ * configure.in: Use CYGWIN and EXEEXT autoconf macro to look for
+ win32 dependencies.
+ * configure: Regenerated with autoconf 2.12.
+ * doc/Makefile.in: Add $(EXEEXT) to chew executable.
+
+Mon Jul 28 02:50:29 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * rs6000-core.c (rs6000coff_core_p): If CORE_TRUNC is set, print
+ a warning rather than returning an error.
+
+Sun Jul 27 19:54:14 1997 Felix Lee <flee@cygnus.com>
+
+ * coffswap.h (coff_swap_aux_in): add semicolon to make MSVC happy.
+
+Fri Jul 25 14:50:08 1997 Felix Lee <flee@cygnus.com>
+
+ * cisco-core.c: define signals for wingdb.
+
+Fri Jul 25 16:27:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecofflink.c (bfd_ecoff_debug_accumulate): Only merge files with
+ the same number of aux entries.
+
+Fri Jul 25 08:22:15 1997 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (hppa_som_gen_reloc_type): Use R_DATA_EXPR for the
+ difference of two symbols if the relocation size is 32 bits.
+ (som_write_fixups): Handle R_DATA_EXPR.
+
+Wed Jul 23 16:08:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i386.c (coff_i386_reloc): Don't offset a common symbol by
+ its value if COFF_WITH_PE is defined.
+
+Tue Jul 22 17:19:45 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * coff-stubgo32.c: New file.
+ * go32stub.h: New file.
+ * coff-i386.c: If COFF_GO32_EXE, include coff/go32exe.h.
+ * coffswap.h (coff_swap_filehdr_in): Invoke
+ COFF_ADJUST_FILEHDR_IN_PRE and COFF_ADJUST_FILEHDR_IN_POST if they
+ are defined.
+ (coff_swap_filehdr_out): Invoke COFF_ADJUST_FILEHDR_OUT_PRE and
+ COFF_ADJUST_FILEHDR_OUT_POST if they are defined.
+ (coff_swap_aux_in): Invoke COFF_ADJUST_AUX_IN_PRE and
+ COFF_ADJUST_AUX_IN_POST if they are defined.
+ (coff_swap_aux_out): Invoke COFF_ADJUST_AUX_OUT_PRE and
+ COFF_ADJUST_AUX_OUT_POST if they are defined.
+ (coff_swap_scnhdr_in): Invoke COFF_ADJUST_SCNHDR_IN_PRE and
+ COFF_ADJUST_SCNHDR_IN_POST if they are defined.
+ (coff_swap_scnhdr_out): Invoke COFF_ADJUST_SCNHDR_OUT_PRE and
+ COFF_ADJUST_SCNHDR_OUT_POST if they are defined.
+ * targets.c (go32stubbedcoff_vec): Declare.
+ (bfd_target_vector): Add go32stubbedcoff_vec.
+ * configure.in (go32coff_vec): New target vector.
+ (go32stubbedcoff_vec): Likewise.
+ * config.bfd (i[3456]86-*-msdosdjgpp*): New target.
+ (i[3456]86-*-go32*): Change to be like new msdosdjgpp*.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add coff-stubgo32.o.
+ (BFD32_BACKENDS_CFILES): Add coff-stubgo32.c.
+ (HFILES): Add go32stub.h.
+
+Tue Jul 22 15:09:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check for fdopen.
+ * configure, config.in: Rebuild.
+ * opncls.c (bfd_fdopenr): Check HAVE_FDOPEN rather than VMS or
+ __GO32__. Reindent a bit.
+
+Sun Jul 20 20:05:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_create_dynamic_sections): Set SEC_LINKER_CREATED
+ flag for newly created sections.
+ (sunos_add_dynamic_symbols): Don't discard newly created sections
+ if shared library is dynobj.
+
+Mon Jul 14 15:33:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (map_sections_to_segments): When checking whether
+ including a section in a segment would force us to skip a page,
+ align the address of the next segment to avoid wraparound
+ problems.
+
+Tue Jul 8 12:11:29 1997 Fred Fish <fnf@cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): Initialize
+ target id field to TIC80_TARGET_ID.
+ * coffswap.h (coff_swap_filehdr_out): Swap out target id field
+ if used.
+ (coff_swap_filehdr_in): Swap in target id field if used.
+
+Mon Jul 7 16:41:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i386.c (coff_i386_is_local_label_name): New static function
+ if TARGET_UNDERSCORE.
+ (coff_bfd_is_local_label_name): Define if TARGET_UNDERSCORE.
+ (i386coff_vec): Add SEC_CODE and SEC_DATA to section_flags.
+
+Mon Jun 30 14:29:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-m68k.c (howto_table): Use complain_overflow_bitfield, not
+ complain_overflow_signed, for 32 bit PC relative relocations.
+
+Thu Jun 26 01:26:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): When a version
+ indirection symbol is overridden, make the original symbol point
+ at the real overriding symbol.
+
+ * elf.c (bfd_elf_string_from_elf_section): Check for an invalid
+ string index.
+
+ * elflink.h (elf_link_output_extsym): Use the right section for a
+ common symbol.
+ * elf32-mips.c (mips_elf_link_output_symbol_hook): If a common
+ symbol was in .scommon, mark it as SHN_MIPS_SCOMMON.
+
+Wed Jun 25 12:43:10 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * elflink.h (elf_merge_symbols): Resolve indirect and warning
+ symbols before checking for new symbols.
+
+ * elfcore.h (elf_corefile_note): Move out of HAVE_SYS_PROCFS_H.
+
+Tue Jun 24 11:20:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgen.c (coff_object_p): Read the f_opthdr bytes from the
+ file, not aoutsz bytes (they are different in XCOFF .o files).
+
+ * xcofflink.c (xcoff_link_add_symbols): Permit symbols to be
+ redefined by objects included from archives.
+
+Mon Jun 23 18:03:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_merge_symbol): In the case of a new defined
+ symbol overriding an old defined symbol, return the hash table
+ entry which we modify, even if it is the target of an
+ indirection.
+ (elf_link_add_object_symbols): If the real name of the symbol gets
+ overridden, convert the versioned symbol into an indirect symbol
+ to the real symbol.
+
+ * elflink.h (elf_merge_symbol): New static function, broken out of
+ elf_link_add_object_symbols.
+ (elf_link_add_object_symbols): Call it.
+
+Sun Jun 22 19:40:57 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i386.c (i3coff_object_p): If COFF_IMAGE_WITH_PE, hack to
+ handle case where COFF filehdr does not immediately follow PE
+ header.
+ * coffgen.c (coff_object_p): Remove useless seek to current
+ location.
+
+Wed Jun 18 19:03:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * linker.c (link_action): Change COMMON_ROW/indr to from CREF to
+ REFC.
+
+Tue Jun 17 11:55:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_link_input_bfd): If stripping debugging
+ symbols, skip N_ABS symbols with debugging storage classes.
+
+Mon Jun 16 18:56:27 1997 Geoff Keating <geoffk@ozemail.com.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't emit R_PPC_REL*
+ relocs in shared libraries which refer to local symbols. Cope
+ with addend when processing a GOT relocation.
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Only create symbols
+ for sections that the linker didn't create.
+ (ppc_elf_finish_dynamic_sections): Only try to write out a section
+ symbol if it was created in ppc_elf_size_dynamic_sections.
+ (ppc_elf_relocate_section): Complain if we have to generate a reloc
+ relative to a section for which we didn't output a symbol.
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Clean up. PLT
+ relocs are 'rela' relocs, like everything else. .rela.plt is not
+ a read-only section, so we don't have to special-case it.
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Entries in the
+ .rela.bss section are (of course) 'rela' relocs not 'rel' relocs.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Initialise srelgot.
+ (ppc_elf_relocate_section): @got offsets are 4 from start of the
+ actual .got section.
+ * elflink.c (_bfd_elf_create_got_section): The three reserved
+ words start from the symbol '_GLOBAL_OFFSET_TABLE_'.
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): '.rela' is 5
+ characters, not 4.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Use
+ _bfd_elf_create_got_section to create the GOT rather than
+ ppc_elf_create_linker_section. Create the '.rela.got' section
+ ourselves.
+ (ppc_elf_finish_dynamic_symbol): Set up GOT relocations when a
+ symbol has a GOT entry.
+ (ppc_elf_relocate_section): Record when a symbol is used through
+ the GOT, and allocate space in the GOT for each such symbol.
+ (ppc_elf_adjust_dynamic_symbol): Delete unused .got.plt stuff.
+ (ppc_elf_create_linker_section): Delete unused LINKER_SECTION_GOT
+ stuff.
+
+ * elf32-ppc.c (ppc_elf_howto_raw): GOT16_HA relocs should be
+ treated in a similar way to ADDR16_HA relocs.
+ (ppc_elf_relocate_section): PLTREL24 relocs do not get copied into
+ shared objects; the linker must deal with them.
+ (ppc_elf_create_linker_section): Stop setting
+ _GLOBAL_OFFSET_TABLE_ to the wrong value; delete unused
+ LINKER_SECTION_PLT stuff.
+ (ppc_elf_check_relocs): Delete unused LINKER_SECTION_PLT stuff.
+ (ppc_elf_finish_dynamic_sections): Use BFD calls to get GOT
+ section, not ELF-specific calls.
+ (elf_backend_plt_not_loaded): Set to 1.
+ (elf_backend_got_symbol_offset): Set to 4.
+ * elf-bfd.h (elf_backend_data): Add 'plt_not_loaded' member
+ for when ld.so fills in the PLT; and 'got_symbol_offset' member.
+ * elflink.c (_bfd_elf_create_dynamic_sections): Apply
+ plt_not_loaded member.
+ (_bfd_elf_create_got_section): Apply got_symbol_offset.
+ * elfxx-target.h (elf_backend_plt_not_loaded): Set default to
+ 'loaded'.
+ (elf_backend_G_O_T_offset): Set default to 0.
+ (elfNN_bed): Set added fields.
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Was setting
+ DT_RELENT in shared objects; should be DT_RELAENT.
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Propagate
+ R_PPC_ADDR16_HA relocs to shared objects. Cope with case where
+ such a reloc (in a non-shared object) refers to a symbol that's
+ not defined.
+
+Mon Jun 16 14:42:14 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * elfcode.h (put_signed_word): Define.
+ (get_signed_word): Define.
+ (elf_swap_reloca_in): Use get_signed_word for the r_addend field.
+ (elf_swap_reloca_out): Use put_signed_word for the r_addend
+ field.
+ * elf32-m68k.c (elf_m68k_finish_dynamic_symbol): Use
+ bfd_get_signed_32 to set the r_addend field.
+ * elf64-mips.c (mips_elf64_swap_reloca_in): Use
+ bfd_h_get_signed_64 to set the r_addend field.
+
+Mon Jun 16 12:31:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): When generating a
+ shared library, do the relocation if the input section is not
+ allocated in memory.
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Call
+ elf_link_assign_sym_version before elf_adjust_dynamic_symbol.
+ (elf_fix_symbol_flags): New static function, broken out of
+ elf_adjust_dynamic_symbol.
+ (elf_adjust_dynamic_symbol): Call elf_fix_symbol_flags.
+ (elf_link_assign_sym_version): Likewise. Permit a symbol to be
+ forced local even if NEEDS_PLT is set. When forcing a symbol to
+ be local, clear NEEDS_PLT.
+ (elf_link_output_extsym): Remove unused local bed.
+
+Wed Jun 11 22:44:20 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (elf32_mn10300_link_hash_entry): New structure
+ for derived elf linker hash table entries. References to
+ elf_link_hash_entry changed appropriately.
+ (elf32_mn10300_link_hash_table): New structure for derived elf
+ linker hash table.
+ (elf32_mn10300_hash_table): Define.
+ (elf32_mn10300_link_hash_traverse): Likewise.
+ (elf32_mn10300_link_hash_newfunc): New function.
+ (elf32_mn10300_link_hash_table_create): Likewise.
+ (elf32_mn10300_finish_hash_table_entry): Likewise.
+ (mn10300_elf_relax_section): Handle "call" -> "calls", removal
+ of prologue code, and call:32->call:16 relaxing.
+ (compute_function_info: New function.
+ (bfd_elf32_bfd_ilink_hash_table_create): Define.
+
+Wed Jun 11 00:00:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_output_extsym): Call finish_dynamic_symbol
+ for a symbol which is being forced to be local.
+ * elf32-i386.c (elf_i386_relocate_section): Write out the
+ relocation value for a GOT reloc for a symbol which is turning
+ into a local symbol.
+ (elf_i386_finish_dynamic_symbol): If a symbol is turning into a
+ local symbol, write out a RELATIVE reloc rather than a GLOB_DAT
+ reloc.
+ * elf32-m68k.c, elf32-sparc.c: Corresponding changes.
+
+ * elf32-i386.c (elf_i386_relocate_section): Get the relocation
+ value if the symbol is turning into a local symbol.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+1997-06-10 22:58 Ulrich Drepper <drepper@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Also read verneed
+ information by calling `_bfd_elf_slurp_version_tables'.
+ (elf_link_add_object_symbols): For undefined symbols look for
+ version information in the verneed records.
+ (elf_link_add_object_symbols): Use soname of shared object
+ for verneed record if it is available.
+
+Tue Jun 10 11:13:03 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * cpu-arm.c: Add prototypes for compatible and scan.
+ * cofflink.c: Add prototype for mark_relocs.
+
+ * archive.c (bfd_special_undocumented_glue): Change filename to
+ const pointer. Add prototype.
+
+Mon Jun 9 12:34:21 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elflink.h (elf_link_add_object_symbols): Ignore relocations of
+ sections that will be discarded.
+
+1997-06-06 22:58 Ulrich Drepper <drepper@cygnus.com>
+
+ * elflink.h (elf_link_find_version_dependencies): When searching
+ for known version symbol skip non-matching verdef records, not
+ matching records.
+
+Thu Jun 5 15:52:45 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Write a long,
+ not a bfd_vma, to the base file, to match how dlltool reads it.
+
+Tue Jun 3 16:57:45 1997 Nick Clifton <nickc@cygnus.com>
+
+ * reloc.c: Add thumb relocations.
+
+ * bfd-in2.h: Add Thumb relocations.
+
+ * libbfd.h: Add Thumb relocations.
+
+Mon Jun 2 10:41:52 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * cpu-m68k.c (arch_info_struct): Fix 68060 cpu name.
+
+Fri May 30 12:46:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Set dynindx
+ for a section even if it is not loaded.
+
+ * cofflink.c (coff_link_add_symbols): If PE file, don't subtract
+ section VMA.
+ (_bfd_coff_link_input_bfd): Separate section VMA handling for
+ input and output files.
+ (_bfd_coff_generic_relocate_section): Check whether input file,
+ not output file, is a PE file.
+
+Wed May 28 15:48:43 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c: (coff_arm_bfd_set_private_flags): Make static.
+
+Wed May 28 16:16:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-i386.c (coff_i386_reloc): Don't just exit if we see an
+ R_IMAGEBASE reloc.
+
+Wed May 28 09:48:43 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-arm.c (compatible): Add test for supersets of ARM
+ architectures.
+
+Tue May 27 19:42:03 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * cofflink.c (_bfd_coff_final_link): Initialize global_to_static
+ member.
+
+Tue May 27 14:34:08 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (coff_arm_bfd_set_private_flags): Make global. It is
+ called directly by gas/config/tc-arm.c.
+
+Tue May 27 15:58:53 1997 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (PLT_ENTRY_*): Use a new thread-safe format.
+ (elf64_alpha_finish_dynamic_symbol): Fill it in properly.
+
+Mon May 26 14:05:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-ppc.c (coff_ppc_relocate_section): If PE file, don't add
+ section VMA.
+
+Mon May 26 10:57:48 1997 Fred Fish <fnf@cygnus.com>
+
+ * peicode.h (coff_bfd_print_private_bfd_data): #undef before #define.
+ (coff_bfd_copy_private_bfd_data): Ditto.
+ * coff-arm.c (coff_arm_bfd_merge_private_bfd_data): Make static.
+ (coff_arm_bfd_print_private_bfd_data): Ditto.
+ (coff_arm_bfd_set_private_flags): Ditto.
+ (coff_arm_bfd_copy_private_bfd_data): Ditto.
+
+Fri May 23 15:14:58 1997 Fred Fish <fnf@cygnus.com>
+
+ * libcoff-in.h (struct coff_final_link_info): Add boolean
+ global_to_static member for support of task linking.
+ (_bfd_coff_write_task_globals): Add prototype.
+ * libcoff.h: Regenerate.
+ * coffcode.h (coff_write_object_contents): Use #ifdef to
+ check RS6000COFF_C, to be consistent with all other uses
+ in this file.
+ * cofflink.c (_bfd_coff_final_link): If doing task linking,
+ call _bfd_coff_write_task_globals.
+ (_bfd_coff_link_input_bfd): If doing task linking, convert
+ global functions to static.
+ (_bfd_coff_write_global_sym): If doing task linking, convert
+ global variables to static.
+ (_bfd_coff_write_task_globals): New function.
+ * coff-tic80.c (TIC80COFF): Define this instead of just TIC80.
+ (C_AUTOARG): #undef since it clashes with C_UEXT.
+ (C_LASTENT): #undef since it clashes with C_STATLAB.
+ * coffcode.h (coff_write_object_contents): Use TIC80COFF
+ rather than TIC80.
+ (coff_slurp_symbol_table): Use C_SYSTEM. Hide C_AUTOARG use
+ when TIC80COFF defined (clashes with C_UEXT). Explicitly
+ recognize C_UEXT, C_STATLAB, and C_EXTLAB as unsupported.
+
+Fri May 23 12:38:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-tic80.c (tic80_howto_table): Change overflow check for most
+ PP relocations to complain_overflow_dont.
+
+Thu May 22 20:22:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-tic80.c (tic80_howto_table): Add PP relocations. Change
+ name of R_RELLONG to "RELLONG". Set rightshift and complain for
+ M_PPCR.
+ (ppbase_reloc, glob15_reloc): New static functions.
+ (glob16_reloc, local16_reloc): New static functions.
+ (rtype2howto): Handle all relocation types.
+ (coff_tic80_relocate_section): New static function.
+ (coff_relocate_section): Define to coff_tic80_relocate_section.
+ * Makefile.in (coff-tic80.o): Depends upon include/coff/tic80.h.
+
+Wed May 21 17:15:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_slurp_symbol_table): If COFF_WITH_PE or
+ COFF_IMAGE_WITH_PE, don't subtract the section VMA from the symbol
+ value.
+ * coffgen.c (fixup_symbol_value): Add abfd parameter. Change all
+ callers. If PE file, don't add section VMA.
+ (coff_write_alien_symbol): If PE file, don't add section VMA.
+ * cofflink.c (_bfd_coff_link_input_bfd): Likewise.
+ (_bfd_coff_write_global_sym): Likewise.
+ (_bfd_coff_generic_relocate_section): Likewise.
+
+ * peicode.h: Add & 0xffffffff when using ImageBase in case bfd_vma
+ is 64 bits.
+
+Wed May 21 09:58:10 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cofflink.c (mark_relocs): Add new function to mark symbols which
+ are used by relocations.
+ (_bfd_coff_link_input_bfd): Add call to mark_relocs() and code to
+ suppress the skipping of symbols that have thus been marked.
+
+Tue May 20 18:45:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (sh_merge_private_data): New static function.
+ (coff_bfd_merge_private_bfd_data): Define.
+
+Mon May 19 14:46:00 1997 Mark Alexander <marka@cygnus.com>
+
+ * coff-tic80.c: Remove unnecessary #ifdefs.
+ * config.bfd: Set targ_underscore to yes for tic80.
+
+Mon May 19 14:26:36 1997 Mark Alexander <marka@cygnus.com>
+
+ * coff-tic80.c (NAMES_HAVE_UNDERSCORE): Define (fixes problem
+ with unresolved external symbols in GDB).
+
+Fri May 16 10:23:03 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf-m10300.c (elf32_mn10300_relax_section): Read in all
+ the symbols associated with each BFD.
+ (mn10300_elf_relax_delete_bytes): Don't adjust the same symbol
+ more than once.
+ * elf-m10200.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-sh.c: Likewise.
+
+Fri May 16 12:10:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't decrease the
+ alignment of a common symbol. If two symbols that look like
+ common symbols are found in two shared libraries, and the size is
+ different, use the larger size, and warn if --warn-common. If a
+ common symbol overrides a definition in a shared library, set the
+ size to the larger size, and warn if --warn-common.
+
+Thu May 15 14:31:28 1997 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-arm.c (compatible): Allow default machine to be polymorphed
+ into any other machine type.
+
+ * coffcode.h (coff_set_flags): Initialise flags variable to 0.
+
+ * coff-arm.c (coff_arm_bfd_merge_private_bfd_data): When merging
+ data into an unitialised destination set its machine type as well.
+
+Thu May 15 16:40:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Force ELF symbol size
+ to common symbol size. Consistently treat uninitialized symbols
+ in shared objects as common symbols.
+
+Fri May 9 10:15:27 1997 Nick Clifton <nickc@cygnus.com>
+
+ * archures.c (constants): Added new constants to identify the
+ type of the ARM architecture: bfd_mach_arm_2, bfd_mach_arm_2a,
+ bfd_mach_arm_3, bfd_mach_arm_3M, bfd_mach_arm_4 and bfd_mach_arm_4T.
+
+ * bfd-in2.h (constants): Added new constants to identify
+ the type of the ARM architecture: bfd_mach_arm_2, bfd_mach_arm_2a,
+ bfd_mach_arm_3, bfd_mach_arm_3M, bfd_mach_arm_4 and
+ bfd_mach_arm_4T. This file is auto-magically generated from the
+ archures.c file. This update is just to save work.
+
+ * coff-arm.c (coff_arm_bfd_merge_private_bfd_data,
+ coff_arm_bfd_print_private_bfd_data,
+ coff_arm_bfd_set_private_flags,
+ coff_arm_bfd_copy_private_bfd_data): Added these new functions.
+ (global): Macro redefinitions set up to use these new functions.
+
+ * coffcode.h (coff_mkobject_hook): Added call to
+ coff_arm_bfd_set_private_flags().
+ (coff_set_arch_mach_hook): Added code to set machine type based on
+ bits stored in internal flags.
+ (coff_set_flags): Added code to set the new bits in the flags
+ field based on the machine number.
+ (function definition macros): Made all function definition macros
+ conditional so that they can be overridden by target specific
+ files.
+
+ * cpu-arm.c (compatible): Added this function. (arch_info_struct):
+ Structure extended to include new types, one each for ARMv2,
+ ARMv2a, ARMv3, ARMv3M, ARMv4 and ARMv4T.
+
+ * libcoff-in.h (struct coff_tdata): Added flags field.
+
+Fri May 9 17:40:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.bfd (i[3456]86-*-gnu*): Don't include Mach support.
+
+ * config.bfd: Change #if 0 around uses of host_aout_vec to #if
+ HAVE_host_aout_vec.
+
+Mon May 5 13:57:32 1997 Mike Meissner <meissner@cygnus.com>
+
+ * coffgen.c (coff_find_nearest_line): If there are no syments,
+ just return false.
+
+Mon May 5 18:18:45 1997 Philip Blundell <pjb27@cam.ac.uk>
+
+ * config.bfd: cope with '*-*-linux-gnuaout' targets.
+
+Thu May 1 11:31:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * targmatch.sed: Add explicit \n characters to work around bug in
+ HP/UX 10.20 sed program.
+
+Wed Apr 30 12:27:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (copy_private_bfd_data): Cast csecs to avoid sign
+ extension problems.
+
+Tue Apr 22 12:06:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (do_maintainer_clean): Don't remove bfd-in2.h.
+
+Mon Apr 21 11:21:31 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c: Follow the last changes in elf32-i386.c:
+ (struct elf_m68k_pcrel_relocs_copied, struct
+ elf_m68k_link_hash_entry, struct elf_m68k_link_hash_table,
+ elf_m68k_link_hash_traverse, elf_m68k_hash_table,
+ elf_m68k_link_hash_newfunc, elf_m68k_link_hash_table_create,
+ elf_m68k_discard_copies, bfd_elf32_bfd_link_hash_table_create):
+ New definitions.
+ (elf_m68k_check_relocs): If linking with -Bsymbolic, don't copy
+ PC relative relocs for a global symbol defined in a regular
+ object, and count the number of PC relative relocs copied for any
+ global symbol.
+ (elf_m68k_size_dynamic_sections): If linking with -Bsymbolic,
+ traverse with elf_m68k_discard_copies.
+
+Sat Apr 19 22:50:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Only count PC relative
+ relocs. From Jamie Lokier <jamie@rebellion.co.uk>.
+
+ * coffcode.h (coff_compute_section_file_positions): Force the
+ potential last byte in the file to be written out when
+ COFF_IMAGE_WITH_PE.
+
+Thu Apr 17 13:46:56 1997 Per Fogelstrom <pefo@openbsd.org>
+
+ * configure.host (mips*-*-openbsd*): New host.
+
+Thu Apr 17 11:10:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Only subtract the
+ section VMA from the symbol value if this is a fully linked file.
+
+ * elf32-i386.c (struct elf_i386_pcrel_relocs_copied): Define.
+ (struct elf_i386_link_hash_entry): Define.
+ (struct elf_i386_link_hash_table): Define.
+ (elf_i386_link_hash_traverse): Define.
+ (elf_i386_hash_table): Define.
+ (elf_i386_link_hash_newfunc): New static function.
+ (elf_i386_link_hash_table_create): New static function.
+ (elf_i386_check_relocs): If linking with -Bsymbolic, don't copy
+ PC relative relocs for a global symbol defined in a regular
+ object, and count the number of PC relative relocs copied for any
+ global symbol.
+ (elf_i386_size_dynamic_sections): If linking with -Bsymbolic,
+ traverse with elf_i386_discard_copies.
+ (elf_i386_discard_copies): New static function.
+ (bfd_elf32_bfd_link_hash_table_create): Define.
+
+ From Gordon W. Ross <gwr@mc.com>:
+ * aoutf1.h (MY_entry_is_text_address): Define if not defined.
+ (sunos4_aout_backend): Use MY_entry_is_text_address.
+
+Wed Apr 16 12:43:32 1997 Martin Hunt <hunt@cygnus.com>
+
+ * elf32-d30v.c (elf_d30v_howto_table): Changed size of
+ R_D30V_32_NORMAL to 2 (4 bytes).
+
+Wed Apr 16 14:02:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Gordon W. Ross <gwr@mc.com>:
+ * netbsd.h (N_SHARED_LIB): Define.
+ (SEGMENT_SIZE): Don't define.
+ * m68knetbsd.c (SEGMENT_SIZE): Don't define (revert change of
+ April 11).
+ * sparcnetbsd.c (TARGET_PAGE_SIZE): Define as 0x2000.
+ (SEGMENT_SIZE): Don't define.
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Set .rela.bss size
+ to sizeof Rela structure, not sizeof Rel structure. From Gary
+ Thomas <g.thomas@opengroup.org>.
+
+Tue Apr 15 11:50:37 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aout-target.h (MY(callback)): If entry_is_text_address, adjust
+ whenever entry is larger than text address, but only by whole
+ pages. From Gordon W. Ross <gwr@mc.com>.
+
+ * Makefile.in (install): Depend upon installdirs. Use
+ mkinstalldirs to build $(oldincludedir).
+ (installdirs): New target.
+
+ * elflink.h (elf_link_add_object_symbols): Don't call check_relocs
+ if this is a debugging section which we are stripping.
+
+Mon Apr 14 12:39:30 1997 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (elf64_alpha_object_p): Allocate the
+ alpha-specific target data struct.
+
+Mon Apr 14 11:45:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Thomas Graichen <graichen@rzpd.de>:
+ * Makefile.in: Always use $(SHELL) when running move-if-change.
+ * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub.
+ * configure: Rebuild.
+
+Fri Apr 11 15:43:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_slurp_symbol_table): Only subtract the section
+ VMA if this is an executable file or a shared object.
+
+ * targets.c (netbsd_core_vec): Declare. From Gordon W. Ross
+ <gwr@mc.com>.
+
+ * libaout.h (struct aout_backend_data): Add entry_is_text_address
+ field.
+ * aout-target.h (SEGMENT_SIZE): Define to TARGET_PAGE_SIZE at the
+ start of the file. Remove uses later on which switch using
+ ifdef.
+ (MY(callback)): Handle entry_is_text_address.
+ (MY_entry_is_text_address): Define if not defined.
+ (MY(backend_data)): Initialize new field.
+ * aoutf1.h (sunos4_aout_backend): Likewise.
+ * i386aout.c (MY(backend_data)): Likewise.
+ * i386mach3.c (MY(backend_data)): Likewise.
+ * mipsbsd.c (MY(backend_data)): Likewise.
+ * sparclynx.c (sparclynx_aout_backend): Likewise.
+ * netbsd.h (SEGMENT_SIZE): Define if not defined.
+ (MY_entry_is_text_address): Define.
+ * m68knetbsd.c (SEGMENT_SIZE): Define as 0x20000.
+
+ * xcofflink.c (bfd_xcoff_import_symbol): Handle importing a symbol
+ whose name starts with `.'.
+
+Fri Apr 11 11:57:15 1997 Niklas Hallqvist <niklas@appli.se>
+
+ * config.bfd: (i[3456]86-*-openbsd*, m68*-*-openbsd*,
+ mips*el*-*-openbsd*, mips*-*-openbsd*, ns32k-*-openbsd*,
+ powerpc-*-*bsd*, sparc-*-openbsd*): New targets.
+ * configure.in (i[3456]86-*-openbsd*, mips*-*-openbsd*,
+ m68*-*-openbsd*, ns32k-*-openbsd*, powerpc-*-*bsd*,
+ sparc-*-openbsd*): New targets.
+ * configure: Rebuild.
+
+Tue Apr 8 18:09:29 1997 Jamie Lokier <jamie@rebellion.co.uk>
+
+ * stabs.c (struct stab_section_info): New field
+ `cumulative_skips'.
+ (_bfd_link_section_stabs): Fill the above array.
+ (_bfd_stab_section_offset): Use `cumulative_skips' to
+ speed up offset calculation.
+
+Tue Apr 8 00:01:31 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf-mn10300.c (mn10300_elf_relax_section): Don't forget the
+ addend for non pc-relative relocations.
+
+ * elf-m10300.c (bfd_elf32_mn10300_reloc): Remove prototype
+ for non-existent function.
+
+ * elf-m10300.c (mn10300_elf_relax_section): New function.
+ (mn10300_elf_relax_delete_bytes): Likewise.
+ (mn10300_elf_symbol_address_p): Likewise.
+ (mn10300_elf_get_relocated_section_contents): Likewise.
+ (bfd_elf32_bfd_relax_section): Define.
+ (bfd_elf32_bfd_get_relocated_section_contents): Likewise.
+
+Mon Apr 7 16:47:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Set SHLIB_LIBS.
+ * configure.in: Substitute SHLIB_LIBS.
+ * configure: Rebuild.
+ * Makefile.in (SHLIB_LIBS): New variable.
+ ($(SHLIB)): Use $(SHLIB_LIBS).
+
+Mon Apr 7 10:53:52 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * bfd-in.h bfd-in2.h: add bfd_section_lma macro to correspond
+ with bfd_section_vma.
+
+Fri Apr 4 11:37:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Update file names for bfd_elf32_mn10[23]00_vec.
+ Correct CPU file names for mn10[23]00.
+ * configure: Rebuild.
+
+ * bfd.c (bfd_record_phdr): Cast count to size_t before
+ subtraction.
+
+ * coff-ppc.c (dump_toc): Add cast to avoid warning from SunOS cc.
+ * coff-rs6000.c (xcoff_read_ar_hdr): Likewise.
+ (xcoff_write_archive_contents): LIkewise.
+ * elf32-mips.c (_bfd_mips_elf_set_section_contents): Likewise.
+ (mips_elf_create_procedure_table): Likewise.
+ * peicode.h (pe_print_idata): Likewise.
+ (pe_print_edata, pe_print_pdata, pe_print_reloc): Likewise.
+ * xcofflink.c (xcoff_get_section_contents): Likewise.
+ (_bfd_xcoff_canonicalize_dynamic_symtab): Likewise.
+ (xcoff_link_add_symbols): Likewise.
+ (xcoff_link_add_symbols): Likewise.
+
+ * ppcboot.c (ppcboot_set_arch_mach): Make static.
+ (ppcboot_bfd_print_private_bfd_data): Likewise.
+
+ * elf32-mips.c (elf_mips_ctor64_howto): Set complain_on_overflow
+ to complain_overflow_signed.
+
+Thu Apr 3 11:51:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * VERSION: Set to 2.8.1.
+
+ * Branched binutils 2.8.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't check SEC_ALLOC when
+ deciding whether to copy a reloc into a shared object.
+ (ppc_elf_relocate_section): Likewise. Relocate R_PPC_RELATIVE
+ relocs in unallocated sections.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Relocate
+ R_SPARC_RELATIVE relocs in unallocated sections.
+
+Wed Apr 2 16:19:41 1997 Mike Meissner <meissner@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Undo March 26 change and
+ always create got section so that the _GLOBAL_OFFSET_TABLE_ label
+ is always created.
+
+Wed Apr 2 10:49:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Let a common symbol
+ override an uninitialized symbol from a shared library with a
+ smaller size.
+
+ * elf-m10200.c: Rename from elf32-mn10200.c.
+ * elf-m10300.c: Rename from elf32-mn10300.c.
+ * cpu-m10200.c: Rename from cpu-mn10200.c
+ * cpu-m10300.c: Rename from cpu-mn10300.c
+ * Makefile.in: Update accordingly.
+
+ * elf32-mips.c (elf_mips_ctor64_howto): New static variable.
+ (elf_mips_isa): Move to earlier in file.
+ (mips_reloc_map): Remove BFD_RELOC_CTOR entry.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle BFD_RELOC_CTOR
+ specially.
+
+ * elf32-mips.c (mips16_jump_reloc): Print a warning rather than
+ calling abort.
+
+Tue Apr 1 16:18:05 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * configure.com: New file.
+ * config.h-vms: Remove file.
+ * makefile.vms: Update for new configure scheme.
+
+Mon Mar 31 23:28:39 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * libcoff-in.h (ppc_allocate_toc_section): Declare.
+ (ppc_process_before_allocation): Declare.
+ * libcoff.h: Rebuild.
+
+ * coffcode.h (coff_mkobject_hook): Declare if not a macro.
+
+Mon Mar 31 16:29:50 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * config.bfd (hppa*-*-rtems*): New target, like hppa-*-*elf*.
+
+Mon Mar 31 16:11:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-a29k.c (coff_a29k_relocate_section): Don't use symndx as a
+ symbol index for a R_IHCONST reloc.
+
+Mon Mar 31 15:40:59 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * targmatch.sed: Do not use \(\) recursively.
+
+Fri Mar 28 14:44:08 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * m68klinux.c (MACHTYPE_OK): Define.
+ * i386linux.c (MACHTYPE_OK): Define.
+
+Fri Mar 28 11:56:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From David S. Miller <davem@caip.rutgers.edu> and H.J. Lu
+ <hjl@gnu.ai.mit.edu>:
+ * sparclinux.c: New file.
+ * bfd-in.h (bfd_sparclinux_size_dynamic_sections): Declare.
+ * bfd-in2.h: Rebuild.
+ * config.bfd (sparc-*-linuxaout*, sparc-*-linux*): New targets.
+ * configure.in (sparclinux_vec): Add to list of vectors.
+ * configure: Rebuild.
+ * targets.c (sparclinux_vec): Declare.
+ (bfd_target_vector): Add sparclinux_vec.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add sparclinux.o.
+ (BFD32_BACKENDS_CFILES): Add sparclinux.c.
+
+ * coff-mips.c (mips_ecoff_backend_data): Initialize new
+ bfd_coff_backend_data field.
+ * coff-alpha.c (alpha_ecoff_backend_data): Likewise.
+
+ * config.bfd: Add bfd_elf64_{big,little}mips_vec to targ_selvecs
+ for mips*el*-*-linux* and mips*-*-linux*. From H.J. Lu
+ <hjl@lucon.org> and Ralf Baechle <ralf@gnu.ai.mit.edu>.
+
+ * bfd.c: Include "libiberty.h".
+ (strerror): Don't declare.
+ (bfd_errmsg): Call xstrerror rather than strerror.
+
+Thu Mar 27 12:55:42 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Generate a COPY
+ reloc even if the symbol is in the .bss section.
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
+
+ * coffcode.h (bfd_coff_backend_data): Add new field
+ _bfd_coff_default_section_alignment_power.
+ (bfd_coff_default_section_alignment_power): Define.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * libcoff.h: Rebuild.
+ * cofflink.c (coff_link_add_symbols): Limit alignment of a common
+ symbol to the default section alignment.
+
+ * COPYING: Update FSF address.
+
+Thu Mar 27 00:45:57 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * elf32-d30v.c (elf_d30v_howto_table): Fix a typo in the
+ 21-bit absolute that made it act as a relative.
+
+Wed Mar 26 14:50:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.c (_bfd_elf_create_linker_section): Don't set
+ bss_section and rel_section from existing sections.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Only create the got section
+ if it is needed.
+
+Tue Mar 25 22:26:56 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * aoutx.h (some_aout_object_p): Change executable test to fix
+ problems with embedded a.out systems.
+
+Tue Mar 25 14:35:37 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (_bfd_stab_section_offset): New function.
+ * libbfd-in.h (_bfd_stab_section_offset): Declare.
+ * libbfd.h: Rebuild.
+ * elf32-i386.c (elf_i386_relocate_section): Adjust the offset of a
+ stab reloc.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+
+ * stabs.c (_bfd_link_section_stabs): Copy over the first header
+ symbol. Check for memory allocation failure of *psinfo.
+ (_bfd_write_section_stabs): Add psinfo parameter. Change all
+ callers. Set the value of the header symbol.
+ * libbfd-in.h (_bfd_write_section_stabs): Update declaration.
+ * libbfd.h: Rebuild.
+
+Mon Mar 24 20:07:29 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (tic80_howto_table): Add R_ABS entry.
+ (rtype2howto): Handle R_ABS reloc type. Also abort on unhandled
+ reloc types, rather than silently failing to generate an output file.
+
+Mon Mar 24 13:41:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * targmatch.sed: Use the hold space to put the #ifdef around the
+ the string constant.
+ * targets.c (UNSUPPORTED_TARGET): Don't define.
+ (find_target): Don't check for UNSUPPORTED_TARGET.
+ (bfd_set_default_target): Don't try to optimize by checking for
+ default.
+
+ * Makefile.in: Rebuild dependencies.
+ (ALL_MACHINES_CFILES): Add cpu-m32r.c.
+ (BFD32_BACKENDS_CFILES): Add elf32-m32r.c.
+ (elf32-m32r.o): Remove explicit target.
+
+ * config.bfd: Don't set targ_underscore for i[3456]86-*-gnu* or
+ i[3456]86-*-linux*.
+
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Don't
+ count section symbols for sections that were created by the
+ linker, or are not allocatable or not loadable.
+ (elf32_sparc_finish_dynamic_sections): Output output section
+ symbols for section for which we made space for them.
+
+Fri Mar 21 13:08:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): If there is
+ no .rela.plt section, don't output a DT_PLTGOT dynamic entry.
+
+Fri Mar 21 12:36:46 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_howto_table): Use special function for LO16.
+ (m32r_hi16_list): New static local.
+ (m32r_elf_hi16_reloc): Don't perform reloc, just queue it up.
+ (m32r_elf_do_hi16_reloc): Delete.
+ (m32r_elf_relocate_hi16): New function.
+ (m32r_elf_lo16_reloc): New function.
+ (m32r_elf_relocate_section): For HI16 relocs, scan for corresponding
+ LO16 reloc.
+
+ Mon Mar 10 16:03:31 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_create_linker_section): Delete.
+ (m32r_elf_add_symbol_hook): Rewrite _SDA_BASE_ support.
+ (m32r_elf_final_sda_base): New function.
+ (m32r_elf_relocate_section): Rewrite sdata support.
+ (m32r_elf_finish_dynamic_sections): Delete.
+
+Thu Mar 20 12:39:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Philippe De Muyter <phdm@info.ucl.ac.be>.
+ * coff-svm68k.c: New file. Just defines some macros and includes
+ coff-m68k.c.
+ * coff-m68k.c: Add functions to handle common addends, moved in
+ from cf-m68klynx.c. Control them using COFF_COMMON_ADDEND macro.
+ Control whether relocs are visible using STATIC_RELOCS.
+ * cf-m68klynx.c: Simplify greatly: just define macros to control
+ coff-m68k.c.
+ * coff-aux.c: Likewise. Just leave add_one_symbol routine.
+ * targets. (m68ksysvcoff_vec): Declare.
+ (bfd_target_vector): Add m68ksysvcoff_vec.
+ * config.bfd (m68*-motorola-sysv*): New target.
+ * configure.in (m68ksysvcoff_vec): New vector.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add coff-svm68k.o.
+ (BFD32_BACKENDS_CFILES): Add coff-svm68k.c.
+
+ * binary.c (binary_set_section_contents): Don't get misled if the
+ first section is not loadable. From Matthew L. Martin
+ <mlm@xedia.com>.
+
+ * elflink.h (elf_bfd_final_link): Set the value of a section
+ symbol to the section address unless doing a relocateable link.
+
+Tue Mar 18 23:03:17 1997 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (elf64_alpha_adjust_dynamic_symbol): Don't create
+ .plt entry if we've taken the function's address.
+ (elf64_alpha_merge_gots): Merge collected flags info as well.
+
+Tue Mar 18 22:40:09 1997 H.J. Lu <hjl@lucon.org>
+
+ * Many files: Add function prototypes.
+ * cpu-m68k.c (bfd_default_scan_num_mach): Don't declare.
+ * ecofflink.c: Include "libcoff.h" and "libecoff.h".
+ * elf32-ppc.c (ppc_elf_fake_sections): Make static.
+ * opncls.c (bfd_openstreamr): Change stream parameter to PTR.
+ * peicode.h: Change several void * parameters to PTR.
+ * srec.c (srec_get_symbol_info): Make static.
+ * syms.c (bfd_symbol_is_absolute): Remove.
+ * Makefile.in: Rebuild dependencies.
+
+Tue Mar 18 12:58:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_is_local_label_name): Remove.
+ (bfd_elf32_bfd_is_local_label): Don't define.
+
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Call bfd_malloc rather
+ than malloc.
+
+Mon Mar 17 11:32:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd-in.h: Don't include obstack.h.
+ (struct bfd_hash_table): Change memory field to PTR.
+ * bfd.c (struct _bfd): Change memory field to PTR.
+ * bfd-in2.h: Rebuild.
+ * libbfd-in.h (bfd_release): Declare as function, don't define as
+ macro.
+ * libbfd.h: Rebuild.
+ * opncls.c: Include "objalloc.h" rather than "obstack.h". Use
+ objalloc routines rather than obstack routines.
+ (obstack_chunk_alloc, obstack_chunk_free): Don't define.
+ (getpagesize): Don't define.
+ (_bfd_new_bfd): Don't set _bfd_chunksize.
+ (bfd_openr): Free new bfd and objalloc on failure.
+ (bfd_fdopenr, bfd_openstreamr, bfd_openw): Likewise.
+ (bfd_alloc_size): Remove.
+ (bfd_release): New function.
+ * hash.c: Include "objalloc.h" rather than "obstack.h". Use
+ objalloc routines rather than obstack routines.
+ (obstack_chunk_alloc, obstack_chunk_free): Don't define.
+ * ecofflink.c: Include "objalloc.h" rather than "obstack.h". Use
+ objalloc routines rather than obstack routines.
+ (obstack_chunk_alloc, obstack_chunk_free): Don't define.
+ (struct accumulate): Change memory to struct objalloc *.
+ * liboasys.h (oasys_data_type): Remove oasys_obstack field.
+ * dep-in.sed: Don't remove obstack.h from dependency list.
+ * Makefile.in: Rebuild dependencies.
+ (BFD_H_DEPS): Remove obstack.h.
+ (install): Don't install obstack.h.
+ * Many files: Don't include "obstack.h".
+ * VERSION: Bump.
+
+ * opncls.c (bfd_alloc_grow, bfd_alloc_finish): Remove.
+ * libbfd-in.h (bfd_alloc_grow, bfd_alloc_finish): Don't declare.
+ * libbfd.h: Rebuild.
+ * ieee.c (ieee_archive_p): Rewrite to not use bfd_alloc_grow.
+ * sunos.c (sunos_add_dynamic_symbols): Likewise.
+ * srec.c (srec_scan): Rewrite to not use obstack_1grow.
+
+ * opncls.c (bfd_alloc): Rename from bfd_alloc_by_size_t. Remove
+ old version of bfd_alloc.
+ * libbfd-in.h (bfd_alloc_by_size_t): Don't declare.
+ * libbfd.h: Rebuild.
+ * Several files: Call bfd_alloc rather than bfd_alloc_by_size_t.
+
+Sat Mar 15 15:24:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_is_local_label_name): Accept the generic
+ ELF local label syntax as well.
+
+Sat Mar 15 10:16:42 1997 Fred Fish <fnf@cygnus.com>
+
+ * config.bfd (powerpc-*-beos*): New target.
+ * configure.in (powerpc-*-beos*): Add case that explicitly
+ does not set COREFILE for now. A future BeOS version is
+ expected to support core files.
+ * configure: Regenerate with autoconf.
+
+Fri Mar 14 16:43:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_check_relocs): Give an error if CALL16 is
+ seen with a local symbol, rather than crashing.
+
+ * elfcode.h (elf_slurp_symbol_table): Don't try to read the
+ version symbols if there aren't any.
+
+Thu Mar 13 16:38:30 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (coff_rtype_to_howto): Define
+ (coff_tic80_rtype_to_howto): Clone generic coff version and
+ add code to handle the funky TI "internal relocations".
+
+Thu Mar 13 14:08:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't warn about type
+ or size changes because of a weak symbol.
+
+ * cisco-core.c (SIGEMT): Define if not defined.
+
+Wed Mar 12 21:36:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Use extsymoff when
+ setting ever. Sanity check the version number. Sort out copying
+ flags and other information when adding an indirect symbol.
+ (NAME(bfd_elf,size_dynamic_sections)): Preserve any dynamic
+ symbols added by the backend. Clear the entire contents of the
+ versym section.
+ (elf_export_symbol): Ignore indirect symbols.
+ (elf_link_output_extsym): Accept a section without an owner in an
+ assert.
+ * elfcode.h (elf_slurp_symbol_table): Add a sanity check on the
+ version count. Correct the allocation of x_versymp.
+
+ * elf32-mips.c (mips_elf_add_symbol_hook): Don't set the owner of
+ the magic sections used for SHN_MIPS_TEXT and SHN_MIPS_DATA.
+ Don't return bfd_und_section_ptr when info->shared.
+ (mips_elf_final_link): Set the alignment of .rtproc to 4, not 12.
+ (mips_elf_create_dynamic_sections): Correct type: ^= for &=.
+ (mips_elf_check_relocs): Resolve an indirect symbol in
+ sym_hashes.
+ (mips_elf_finish_dynamic_symbol): Don't change SHN_ABS into
+ SHN_MIPS_TEXT or SHN_MIPS_DATA.
+
+ * elf.c (bfd_elf_print_symbol): Tweak version output slightly.
+
+Tue Mar 11 01:38:36 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * elf-bfd.h (ELF_LINK_FORCED_LOCAL): Define.
+ * elf.c (bfd_elf_print_symbol): Correct errors in last change.
+ * elflink.h (elf_link_add_object_symbols): Handle cases in which a
+ versioned symbol appears in both a regular and a shared object.
+ (elf_link_assign_sym_version): Set ELF_LINK_FORCED_LOCAL when
+ appropriate. Improve error message.
+ (struct elf_outext_info): Rename from elf_finfo_failed. Change
+ all uses. Add localsyms field.
+ (elf_bfd_final_link): When generating a shared library, call
+ elf_link_output_extsym to output all local symbols.
+ (elf_link_output_extsym): Handle symbols which were forced to
+ become local.
+
+Sun Mar 9 23:08:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * elf-bfd.h (elf_symbol_type): Add version field.
+ * elfcode.h (elf_slurp_symbol_table): Set version field.
+ * elflink.h (elf_link_add_object_symbols): When creating an
+ indirect symbol for a default version symbol, set DEF_DYNAMIC if
+ appropriate. Set up an indirection from the nondefault version of
+ the symbol as well.
+ (NAME(bfd_elf,size_dynamic_sections)): Call
+ elf_link_assign_sym_version before checking whether there are any
+ versions. Always record the version name as a dynamic symbol.
+ Initialize counters.
+ (elf_link_assign_sym_version): After finding a version, see if a
+ symbol should be forced to local scope. Create a new version
+ definition if appropriate.
+ (elf_link_output_extsym): Correct indirect symbol handling.
+ * elf.c (bfd_elf_print_symbol): Print version information.
+ (bfd_section_from_shdr): Turn version sections into BFD sections.
+ (elf_fake_sections): Only copy cverdefs and cverrefs into sh_info
+ if sh_info is not already set.
+ (_bfd_elf_copy_private_section_data): Copy sh_info for version
+ sections.
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Tell
+ _bfd_stringtab_add to copy the name into permanent memory if
+ appropriate.
+
+Fri Mar 7 11:55:31 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Fully parenthesize.
+
+Fri Mar 7 10:37:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (bfd_coff_backend_data): Change
+ _bfd_coff_compute_section_file_positions to return a boolean
+ value. Change all callers.
+ (coff_compute_section_file_positions): Change return type to
+ boolean. If the size of the last section changed, then output a
+ zero byte at the end of the file.
+ * libcoff.h: Rebuild.
+
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Always allocate space
+ for at least 6 output symbols.
+ (xcoff_write_global_symbol): When emitting TOC entry relocs, also
+ emit a TC csect to represent the space they take up. For an XO
+ symbol, just emit a reference, not a csect.
+
+ * Makefile.in ($(SHLINK)): Just use ln -s, not ln -sf, since
+ Solaris doesn't like the combined options, and the -f is
+ unnecessary.
+ (stamp-tshlink, install): Likewise.
+
+ * elf32-mips.c (mips_elf_relocate_section): Correct R_MIPS16_26
+ handling when little endian.
+
+Thu Mar 6 13:51:51 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (mn10300_elf_final_link_relocate): New function.
+ (mn10300_elf_relocate_section): Likewise.
+ (elf_backend_relocate_section): Define.
+
+ * elf32-mn10300.c (reloc_type): Remove PCREL{8,16,32}_{1,2}BYTE
+ relocs. Replace them with generic PCREL_{8,16,32} relocs.
+ (elf32_mn10300_howto_table): Likewise.
+ (elf32_mn10300_reloc_map): Likewise.
+ (bfd_elf32_mn10300_reloc): Delete unused function.
+
+Thu Mar 6 12:19:59 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (rtype2howto): If passed a relocation type we don't
+ understand, just set the howto field to NULL, and the caller will
+ print an appropriate error message.
+ * coffcode.h (coff_slurp_reloc_table): Pull duplicate declarations and
+ code fragment out of both legs of #ifdef RELOC_PROCESSING ... #endif
+ block. Use NULL for initializations of "ptr" rather than bare 0.
+ * coff-h8300.c: Fix typo in comment.
+ * coff-h8500.c: Ditto.
+ * coff-w65.c: Ditto
+ * coff-z8k.c: Ditto.
+
+Wed Mar 5 13:59:09 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_do_10_pcrel_reloc): Fix overflow calc.
+ (m32r_elf_relax_section, m32r_elf_relax_delete_bytes,
+ m32r_elf_get_relocated_section_contents): First pass at relax support.
+
+Mon Mar 3 13:27:09 1997 Ulrich Drepper <drepper@rtl.cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Use correct sh_size
+ entry for reading verdef records.
+ Use correct braces for computing increments of extverdaux and
+ exteverdef record pointers.
+
+Sun Mar 2 22:47:54 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (COFF_DEFAULT_SECTION_ALIGNMENT_POWER): Set this to 2
+ instead of 4.
+
+Sun Mar 2 16:25:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_find_version_dependencies): Check that
+ DEF_REGULAR is not set as well as checking that DEF_DYNAMIC is
+ set.
+
+Fri Feb 28 16:52:40 1997 Fred Fish <fnf@cygnus.com>
+
+ * coffcode.h (coff_set_flags): Add case for TIC80_ARCH_MAGIC.
+
+Fri Feb 28 15:06:45 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * targets.c (bfd_default_vector): Make non-const.
+ (find_target): New static function, broken out of
+ bfd_find_target.
+ (bfd_set_default_target): New function.
+ (bfd_find_target): Call find_target. When defaulting, use
+ bfd_default_vector[0] if it is not NULL.
+ * libbfd-in.h (bfd_default_vector): Adjust declaration.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+ * syms.c (bfd_is_local_label): Return false if the symbol has no
+ name.
+ * coff-i960.c (coff_i960_is_local_label_name): New function.
+ (coff_bfd_is_local_label_name): Define.
+ * coff-m68k.c (m68k_coff_is_local_label_name): New function.
+ (coff_bfd_is_local_label_name): Define.
+ * coff-rs6000.c (xcoff_is_local_label_name): New function.
+ (coff_bfd_is_local_label_name): Define.
+ * elf.c (_bfd_elf_is_local_label_name): Treat symbols beginning
+ with .. or _.L_ as local.
+ * elf32-i386.c (elf_i386_is_local_label_name): New function.
+ (bfd_elf32_bfd_is_local_label_name): Define.
+ * evax-alpha.c (evax_bfd_is_local_label_name): Treat symbols
+ beginning with $ as local.
+
+Thu Feb 27 18:36:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (aout_link_write_symbols): Use bfd_is_local_label_name
+ rather than comparing against info->lprefix.
+ * cofflink.c (_bfd_coff_link_input_bfd): Likewise.
+ * elflink.h (elf_link_input_bfd): Likewise.
+ * linker.c (_bfd_generic_link_output_symbols): Likewise.
+ * xcofflink.c (xcoff_link_input_bfd): Likewise.
+
+ * elfxx-target.h (bfd_elfNN_bfd_is_local_label_name): Define as
+ _bfd_elf_is_local_label_name if not already defined.
+ * elf.c (_bfd_elf_is_local_label_name): New function.
+ * elf-bfd.h (_bfd_elf_is_local_label_name): Declare.
+
+ * coff-m88k.c (coff_bfd_is_local_label_name): Define.
+ (m88k_is_local_label_name): New static function.
+
+ * coffcode.h (coff_bfd_is_local_label_name): Define as
+ _bfd_coff_is_local_label_name if not already defined.
+ * coffgen.c (_bfd_coff_is_local_label_name): New function.
+ * libcoff-in.h (_bfd_coff_is_local_label_name): Declare.
+ * libcoff.h: Rebuild.
+
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Change _bfd_is_local_label
+ to _bfd_is_local_label_name.
+ (bfd_target): Likewise.
+ * syms.c (bfd_is_local_label): Define as function, not macro.
+ (bfd_is_local_name): Define.
+ * libbfd.c (bfd_generic_is_local_label_name): Rename from
+ bfd_generic_is_local_label, and take a string rather than a
+ symbol.
+ * libbfd-in.h (_bfd_nosymbols_bfd_is_local_label): Don't define.
+ (_bfd_nosymbols_bfd_is_local_label_name): Define.
+ (bfd_generic_is_local_label): Don't declare.
+ (bfd_generic_is_local_label_name): Declare.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * All backends: Change local_label to local_label_name.
+
+ * elf32-mips.c (struct mips_got_info): Add assigned_gotno field.
+ (mips_elf_relocate_got_local): Change return type to boolean.
+ Don't assume that the first zero entry is unassigned; instead, use
+ assigned_gotno.
+ (mips_elf_relocate_section): Check return value of
+ mips_elf_relocate_got_local.
+ (mips_elf_create_got_section): Initialize assigned_gotno field.
+
+Wed Feb 26 15:19:51 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * elf32-d30v.c (bfd_elf_d30v_reloc): Add code to do 32-bit
+ relocations.
+
+Wed Feb 26 13:33:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_input_bfd): Don't skip symbols from sections
+ that have no contents merely because linker_mark is not set.
+
+Tue Feb 25 18:51:35 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config.bfd (mips*-*-lnews*): New target.
+ * coff-mips.c (mips_relocate_section): Make assert compare
+ content byteorder instead of header byteorder.
+ (ecoff_biglittle_vec): New BFD, big-endian headers, little-endian
+ data.
+ * targets.c (bfd_target_vector): Add ecoff_biglittle_vec.
+ * configure.in (ecoff_biglittle_vec): Add case.
+ * configure: Update.
+
+Tue Feb 25 00:32:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (elf_fake_sections): Use SHT_NOTE for any section whose
+ name begins with ".note".
+ (map_sections_to_segments): Add a PT_NOTE segment for any loadable
+ section whose name begins with ".note".
+ (get_program_header_size): Corresponding change.
+
+ * elf32-mips.c (mips_elf_relocate_section): Check for misaligned
+ jal and for jal overflow.
+
+Mon Feb 24 17:53:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * elflink.h (elf_link_add_archive_symbols): If a default symbol is
+ not found, try looking it up again without the version name.
+ (elf_link_add_object_symbols): Always link against the dynamic
+ symbol table of a dynamic object. When linking against a dynamic
+ object, include version strings in symbol names, and set up
+ version information. Add indirect symbols for default versions.
+ (elf_link_create_dynamic_sections): Add special version sections.
+ (struct elf_assign_sym_version_info): Define.
+ (struct elf_find_verdep_info): Define.
+ (NAME(bfd_elf,size_dynamic_sections)): Add verdefs parameter. Set
+ up version sections.
+ (elf_adjust_dynamic_symbol): Ignore indirect symbols.
+ (elf_link_find_version_dependencies): New static function.
+ (elf_link_assign_sym_version): New static function.
+ (elf_link_renumber_dynsyms): New static function.
+ (struct elf_final_link_info): Add symver_sec field.
+ (elf_bfd_final_link): Initialize finfo.symver_sec. Don't count
+ local symbols of a dynamic object. Handle DT_VER* constants.
+ (elf_link_output_extsym): Simplify BFD_ASSERT checking for a
+ dynamic object. Skip indirect symbols from ELF objects. Remove
+ the version name before choosing a hash bucket. Write out the
+ version information if appropriate.
+ (elf_link_input_bfd): Check for DYNAMIC, not ET_DYN.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update declaration.
+ (bfd_elf64_size_dynamic_sections): Likewise.
+ * bfd-in2.h: Rebuild.
+ * elf-bfd.h (struct elf_link_hash_entry): Add verinfo field.
+ Change elf_link_hash_flags to unsigned short.
+ (ELF_LINK_HIDDEN): Define.
+ (struct elf_obj_tdata): Add fields dynversym_hdr, dynverref_hdr,
+ dynverdef_hdr, dynversym_section, dynverdef_section,
+ dynverref_section, cverdefs, cverrefs, verdef, verref.
+ (elf_dynversym, elf_dynverdef, elf_dynverref): Define.
+ (_bfd_elf_swap_verdef_in, _bfd_elf_swap_verdef_out): Declare.
+ (_bfd_elf_swap_verdaux_in, _bfd_elf_swap_verdaux_out): Declare.
+ (_bfd_elf_swap_verneed_in, _bfd_elf_swap_verneed_out): Declare.
+ (_bfd_elf_swap_vernaux_in, _bfd_elf_swap_vernaux_out): Declare.
+ (_bfd_elf_swap_versym_in, _bfd_elf_swap_versym_out): Declare.
+ (_bfd_elf_slurp_version_tables): Declare.
+ * elf.c (_bfd_elf_swap_verdef_in): New function.
+ (_bfd_elf_swap_verdef_out): Likewise.
+ (_bfd_elf_swap_verdaux_in, _bfd_elf_swap_verdaux_out): Likewise.
+ (_bfd_elf_swap_verneed_in, _bfd_elf_swap_verneed_out): Likewise.
+ (_bfd_elf_swap_vernaux_in, _bfd_elf_swap_vernaux_out): Likewise.
+ (_bfd_elf_swap_versym_in, _bfd_elf_swap_versym_out): Likewise.
+ (_bfd_elf_print_private_bfd_data): Add DT_VER* constants. Print
+ version information if there is any.
+ (_bfd_elf_link_hash_newfunc): Initialize verinfo field.
+ (bfd_section_from_shdr): Handle SHT_GNU_ver* section types.
+ (elf_fake_sections): Handle .gnu.version* section names.
+ (assign_section_numbers): Handle SHT_GNU_ver* section types.
+ (_bfd_elf_slurp_version_tables): New function.
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Don't include
+ version name in string entered in dynamic hash table.
+ * elfcode.h: Include fnmatch.h.
+ * elf32-i386.c (elf_i386_relocate_section): Handle a dynamic
+ symbol which was forced to become local.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise.
+
+Fri Feb 21 16:15:18 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10200.c (mn10200_elf_final_link_relocate): Simplify
+ somewhat.
+ (mn10200_elf_relax_section): Correctly compute a symbol's value
+ when the symbol is local, but not in the same section as we are
+ relaxing. Implement abs24 -> abs16, imm24 -> imm16 and d24 -> d16
+ relaxing.
+
+Fri Feb 21 13:55:14 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * elf32-m32r.c: Rewrite to use ELF backend linker.
+ Store lower 16 bits of addend in R_M32R_HI16_[SU]LO insns.
+ Add small data area support (R_M32R_SDA16).
+ * reloc.c: Document BFD_RELOC_M32R_SDA16.
+ * bfd-in2.h,libbfd.h: Regenerated.
+
+Thu Feb 20 23:50:31 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10200.c (mn10200_elf_relax_section): New function.
+ (mn10200_elf_relax_delete_bytes): Likewise.
+ (mn10200_elf_symbol_address_p): Likewise.
+ (mn10200_elf_get_relocated_section_contents): Likewise.
+ (bfd_elf32_bfd_relax_section): Define.
+ (bfd_elf32_bfd_get_relocated_section_contents): Likewise.
+
+ * elf32-mn10200.c (mn10200_elf_final_link_relocate): New function.
+ (mn10200_elf_relocate_section): Likewise.
+ (elf_backend_relocate_section): Define.
+
+Tue Feb 18 17:22:59 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * Makefile.in, archures.c, config.bfd, configure.in, elf.c,
+ reloc.c, targets.c: New target, elf-*-D30V.
+
+ * bfd-in2.h, configure, libbfd.h: Rebuilt.
+
+ * cpu-d30v.c, elf32-d30v.c: New files.
+
+Tue Feb 18 15:31:48 1997 Fred Fish <fnf@cygnus.com>
+
+ * reloc.c (struct reloc_howto_struct): Fix typo in comment.
+ * bfd-in2.h: Regenerated.
+ * coff-tic80.c (RTYPE2HOWTO): Replace abort with real function.
+ (rtype2howto): Add function.
+ (tic80_howto_table): Add.
+
+Tue Feb 18 11:41:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * sysdep.h: Don't define errno in MSVC if error.h is included.
+
+Tue Feb 18 10:04:13 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (v850_elf_relocate_section): Make sure r_symndx
+ is initialized before it is used.
+
+Mon Feb 17 11:28:40 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * hp300hpux.c (convert_sym_type): Don't convert a secondary common
+ symbol into a weak undefined symbol; leave it as a common symbol.
+
+Fri Feb 14 19:08:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't issue a warning
+ about a symbol defined in a dynamic object if it has already been
+ defined in a regular object.
+
+Thu Feb 13 20:53:22 1997 Klaus Kaempf (kkaempf@progis.de)
+
+ * makefile.vms: Add gcc flags to allow compiling with current gcc
+ snapshot
+ (targmatch.h): New dependency.
+
+ * reloc.c (BFD_RELOC_ALPHA_CODEADDR): New relocation for
+ openVMS/Alpha.
+ * evax.h (ALPHA_R_CODEADDR): New relocation.
+ * evax-alpha.c (ALPHA_R_CODEADDR): 64 bit procedure relocation for
+ openVMS/Alpha.
+ * evax-etir.c (ALPHA_R_CODEADDR): Output object code for this
+ relocation.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+ Restrict symbol length to 64 bytes, case preserving:
+ * evax-emh.c (_bfd_evax_write_emh): Remove case hacking.
+ * evax-misc.c (_bfd_evax_case_hack_symbol): Remove.
+ (_bfd_evax_length_hash_symbol): Added.
+ * evax-etir.c (_bfd_evax_write_etir): Call
+ _bfd_evax_length_hash_symbol before output of symbol.
+ * evax-egsd.c (_bfd_evax_write_egsd): Likewise.
+ * evax.h (flag_hash_long_names, flag_show_after_trunc): Remove.
+
+ * evax-emh.c: Output filename to object file without path.
+
+ * evax-egsd.c: New sections for local and global commons.
+
+ * evax-alpha.c, evax-emh.c, evax-egsd.c, evax-etir.c,
+ evax-misc.c, evax.h: Remove 8 bit characters from copyright
+ notices. Replace AXP with Alpha.
+
+Wed Feb 12 18:10:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_create_dynamic_sections): We need the dynamic
+ sections if we are creating a shared library.
+
+Tue Feb 11 15:45:43 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.host (i386-windows): Don't set host64=true.
+
+Tue Feb 11 15:27:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (reloc_type): Add R_MIPS16_GPREL.
+ (elf_mips16_gprel_howto): New static variable.
+ (mips16_gprel_reloc): New static function.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle BFD_RELOC_MIPS16_GPREL.
+ (mips_info_to_howto_rel): Handle R_MIPS16_GPREL.
+ (mips_elf_relocate_section): Handle R_MIPS16_GPREL.
+ * reloc.c (BFD_RELOC_MIPS16_GPREL): Define.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+Mon Feb 10 23:25:00 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * elf32-m32r.c (elf_m32r_howto_table): Change partial_inplace to true
+ for R_M32R_{16,32,24,HI16_ULO,HI16_SLO,LO16}.
+
+Fri Feb 7 12:39:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_input_bfd): If we've discarded a section,
+ the output section will be the absolute section; don't print an
+ assertion message for that case when doing a relocateable link.
+
+Thu Feb 6 16:55:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (FN_STUB, CALL_STUB, CALL_FP_STUB): Define.
+ (struct mips_elf_link_hash_entry): Add new fields fn_stub,
+ need_fn_sub, call_stub, and call_fp_stub.
+ (struct mips_elf_link_hash_table): Add field mips16_stubs_seen.
+ (mips_elf_link_hash_newfunc): Initialize new fields.
+ (mips_elf_link_hash_table_create): Likewise.
+ (mips_elf_relocate_section): Redirect relocations to use mips16
+ stubs when appropriate.
+ (mips_elf_check_relocs): Attach stub sections to the appropriate
+ symbol. Set need_fn_stub when appropriate.
+ (mips_elf_always_size_sections): New static function.
+ (mips_elf_check_mips16_stubs): New static function.
+ (elf_backend_always_size_sections): Define.
+ * elf-bfd.h (struct elf_obj_tdata): Add local_stubs field.
+
+ * elflink.h (elf_link_input_bfd): Discard local symbols that are
+ attached to sections which are not being included in the link.
+
+Wed Feb 5 13:20:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Ignore the
+ symbol value when computing the addend for a pc_relative
+ pcrel_offset reloc.
+
+Mon Feb 3 11:54:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): If doing a
+ relocateable link, just skip pc_relative pcrel_offset relocs.
+ * coff-arm.c (coff_arm_rtype_to_howto): Return a different howto
+ structure for an ARM26 reloc which can be resolved.
+ (coff_arm_adjust_symndx): Only convert ARM26 to ARM26D if the
+ reloc can be resolved.
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Correct off by one
+ error in overflow check for R_RELBYTE.
+
+Fri Jan 31 14:07:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_slurp_section_data): Pick up the start address.
+ From Mark Rasin <mark.rasin@telrad.co.il>.
+
+ * aoutx.h (aout_link_write_symbols): Don't apply discard_l to
+ debugging symbols.
+
+Wed Jan 29 00:00:49 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10200.c (reloc_type): Add 16bit pc-relative reloc.
+ (elf_mn10200_howto_table): Likewise.
+ (mn10200_reloc_map): Likewise.
+
+Mon Jan 27 12:07:35 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * reloc.c: Add relocs BFD_RELOC_M32R_{HI16_[US]LO,LO16}.
+ * bfd-in2.h, libbfd.h: Regenerated.
+ * elf32-m32r.c: Add support for them.
+
+Mon Jan 27 12:25:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aout-arm.c (MY_swap_std_reloc_in): Remove unused r_length.
+ * elf32-ppc.c (ppc_elf_check_relocs): Remove unused plt.
+ * elf32-v850.c (v850_elf_final_link_relocate): Remove used
+ r_format and r_pcrel. Always return a value.
+ * riscix.c (MY_final_link_callback): Define to dummy value.
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): When checking for
+ relocations against the text segment, look up the output name of
+ the reloc section.
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise.
+ * elf32-mips.c (mips_elf_size_dynamic_sections): Likewise.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise.
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Likewise.
+
+Wed Jan 22 15:40:28 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (tic80coff_vec): Use correct data put/get
+ routines for little endian data.
+ * coffcode.h (coff_write_object_contents): Set magic to
+ TIC80_ARCH_MAGIC for TIc80.
+
+Tue Jan 21 12:32:43 1997 Fred Fish <fnf@cygnus.com>
+
+ * coff-tic80.c (tic80coff_vec): Change to little endian data
+ as the default.
+
+Thu Jan 16 17:45:57 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Change type of
+ auxiliary_filters parameter to be const char * const *. Accept a
+ NULL terminated array.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update declaration.
+ (bfd_elf32_size_dynamic_sections): Update declaration.
+ * bfd-in2.h: Rebuild.
+
+Wed Jan 15 11:21:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Treat a
+ NOTYPE symbol in a text section as a FUNC symbol.
+
+ * coffcode.h (coff_compute_section_file_positions): Force
+ relocbase to be aligned to COFF_DEFAULT_SECTION_ALIGNMENT_POWER.
+
+Tue Jan 14 08:46:33 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * libaout.h (machine_type): Reserve several values for sparclet.
+
+Mon Jan 13 22:39:08 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.bfd (tic80-*-*): Don't require 'coff'.
+
+Mon Jan 13 19:36:25 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-v850.c (v850_elf_howto_table): Set the special_function
+ table to v850_elf_reloc for all non-standard relocations.
+ (v850_elf_check_relocs): Add check for h being non-null.
+ (v850_elf_reloc): Add R_V850_ZDA_OFFSET support. Use switch
+ statement instead of multiple ifs.
+ (v850_elf_relocate_section): Fix up error message, don't just call
+ abort.
+
+Mon Jan 6 13:28:35 1997 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10200.c (elf_mn10200_howto): Don't ever set partial-inplace.
+ Use bfd_elf_generic_reloc as special function for all relocs.
+ (bfd_elf32_mn10200_reloc): Remove unnecessary function.
+
+ * elf32-mn10200.c (elf_mn10200_howto): Set pcrel_offset for
+ 24bit pc-relative reloc.
+
+Fri Jan 3 16:33:00 1997 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (coff-tic80.o): Add coffcode.h to dependency list.
+ * coff-tic80.c (tic80coff_vec): Data byte order is big endian and
+ header byte order is little endian. Use correct bfd_get and
+ bfd_put routines for little endian headers.
+ * coffcode.h (coff_set_arch_mach_hook): Set arch to
+ bfd_arch_tic80 for TIC80_ARCH_MAGIC number.
+
+Fri Jan 3 16:54:08 1997 Jeffrey A Law (law@cygnus.com)
+
+ * reloc.c: Add BFD_RELOC_24.
+ * elf32-mn10200.c (enum reloc_type): Add 24bit and pcrel relocs.
+ (elf_mn10200_howto, mn10200_reloc_map): Corresponding changes.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+Fri Jan 3 16:58:31 1997 Richard Henderson <rth@tamu.edu>
+
+ elf64-alpha multiple .got rewrite:
+
+ * elf-bfd.h (struct elf_backend_data): Add always_size_sections entry.
+ (bfd_elf*_mkobject): Don't define here ...
+ * elfxx-target.h: ... but rather here. Default always_size_sections
+ hook to NULL.
+ * elf.c (elf_mkobject): Rename to bfd_elf_mkobject, since that was
+ what the #defines in elf-bfd.h transmuted it to anyway.
+
+ * section.c: Add SEC_LINKER_CREATED flag.
+ * bfd-in2.h: Rebuild.
+ * elf32-i386.c (elf_i386_check_relocs): Add SEC_LINKER_CREATED to
+ relocation section flags.
+ (elf_i386_size_dynamic_sections): Use SEC_LINKER_CREATED instead of
+ SEC_IN_MEMORY to recognize generated bits.
+ * elf32-m68k.c (elf_m68k_check_relocs, elf_m68k_size_dynamic_sections):
+ Likewise.
+ * elf32-mips.c (mips_elf_final_link, mips_elf_create_dynamic_sections,
+ mips_elf_create_compact_rel_section, mips_elf_create_got_section,
+ mips_elf_check_relocs, mips_elf_size_dynamic_sections): Likewise.
+ * elf32-ppc.c (ppc_elf_create_linker_section,
+ ppc_elf_size_dynamic_sections): Likewise.
+ * elf32-sparc.c (elf32_sparc_check_relocs,
+ elf32_sparc_size_dynamic_sections): Likewise.
+ * elflink.c (_bfd_elf_create_got_section): Add SEC_LINKER_CREATED to
+ section flags.
+ (_bfd_elf_create_dynamic_sections): Likewise.
+ (_bfd_elf_make_linker_section_rela): Likewise.
+ * elflink.h (elf_link_create_dynamic_sections): Likewise.
+ (bfd_elf,size_dynamic_sections): Call the always_size_sections hook.
+ (elf_bfd_final_link): Use SEC_LINKER_CREATED instead of SEC_IN_MEMORY
+ to identify generated bits.
+ (elf_link_input_bfd): Likewise.
+
+ * elf64-alpha.c: Rewrite everything touching relocations.
+
+Fri Jan 3 11:42:53 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-v850.c (all functions and static variables): Go through
+ and regularize names to be of the form v850_elf_<xxx>.
+ (toplevel): Include <elf/v850.h>.
+ (enum reloc_type): Move to include/elf/v850.h.
+ (v850_elf_check_relocs): For common variables, if the variable is
+ referenced by a R_V850_{SDA,ZDA,TDA} relocation, put the variable
+ into the appropriate section.
+ (elf_backend_check_relocs): Define.
+
+Tue Dec 31 15:15:28 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-v850.c (elf_v850_howto_table): Fix some spacing.
+
+Tue Dec 31 14:44:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.bfd (mips*el-*-linux*): New target.
+ (mips*-*-linux*): New target.
+
+ * elf32-mips.c (_bfd_mips_elf_merge_private_bfd_data): Clean up.
+ Return a useful value.
+
+ * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE.
+
+ * configure.in: Check ac_cv_func_mmap_fixed_mapped, not
+ ac_cv_func_mmap.
+ * configure: Rebuild.
+ * configure.host: Use ac_cv_func_mmap_fixed_mapped instead of
+ ac_cv_func_mmap in bfd/configure.host.
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Add
+ filter_shlib and auxiliary_filter_shlib parameters.
+ * elf.c (_bfd_elf_print_private_bfd_data): Handle DT_AUXILIARY and
+ DT_FILTER.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections): Update declaration.
+ (bfd_elf64_size_dynamic_sections): Likewise.
+ * bfd-in2.h: Rebuild.
+
+Mon Dec 30 18:48:52 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_build_ldsyms): When exporting all defined
+ symbols, don't export a symbol which is defined by an object in an
+ archive which contains shared objects.
+
+Mon Dec 30 16:12:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * archures.c (enum bfd_architecture): Add bfd_arch_tic80
+ for TI TMS320c80 (MVP).
+ (bfd_archures_list): Add bfd_tic80_arch.
+ * bfd-in2.h: Regenerate by running "make headers".
+
+Sun Dec 29 16:18:52 1996 Fred Fish <fnf@cygnus.com>
+
+ * cpu-tic80.c (bfd_tic80_arch): Add struct.
+ * configure.in (case $vec): Correct typo, "tb" not "tp".
+ Also add cofflink.o for tic80coff_vec.
+ * configure: Regenerate with autoconf.
+
+Mon Dec 30 11:54:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd.c: Patch up the mmap code so that it is only built if BFD
+ is configured with --with-mmap.
+
+Sun Dec 29 10:48:57 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (BFD32_BACKENDS): Add coff-tic80.o
+ (ALL_MACHINES): Add cpu-tic80.o
+ (cpu-tic80.o, coff-tic80.o): Add dependencies.
+ * coff-tic80.c: Add skeleton, cloned from another coff config.
+ * coffcode.h (coff_write_object_contents): Set magic to TIC80MAGIC
+ for TIc80.
+
+Fri Dec 27 20:56:41 1996 Fred Fish <fnf@cygnus.com>
+
+ * TODO: Correct a misspelling.
+ * coff-tic80.c: New file for TI TMS320C80 (MVP).
+ * cpu-tic80.c: New file for TI TMS320C80 (MVP).
+ * configure.in (case $vec): Add tic80coff_vec entry.
+ * configure: Regenerate with autoconf.
+ * archures.c (bfd_tic80_arch): Declare.
+ * bfd-in2.h (enum bfd_architecture): Add bfd_arch_tic80.
+ * config.bfd (case ${targ}): Add tic80*-*-coff* target.
+ * targets.c (tic80coff_vec): Add decl as extern bfd_target.
+ (bfd_target_vector): Add tic80coff_vec entry.
+
+Fri Dec 27 11:48:12 1996 H.J. Lu <hjl@lucon.org>
+
+ * elflink.h (elf_buckets): Add some more values for larger
+ binaries.
+
+Thu Dec 26 18:36:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install): Move subdir_do out of conditional. From
+ Fred Fish <fnf@cygnus.com>.
+
+Wed Dec 18 10:04:30 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10200.c (enum reloc_type): Enable basic 8, 16, and
+ 32 bit relocs.
+ (elf_mn10200_howto_table): Likewise.
+ (mn10200_reloc_map): Likewise.
+
+Tue Dec 17 11:09:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_add_symbol_hook): Add 1 to the value of a
+ mips16 symbol during the link.
+ (mips_elf_finish_dynamic_symbol): Subtract 1 from the value of a
+ mips16 symbol.
+ (mips_elf_link_output_symbol_hook): New static function.
+ (elf_backend_link_output_symbol_hook): Define.
+
+ * elf.c (bfd_elf_print_symbol): Print the st_other field if it is
+ not zero.
+
+Mon Dec 16 14:38:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (bfd_section_from_shdr): Don't check for reloc sections
+ against SEC_DEBUGGING sections here (revert patch of December 5).
+ * elfcode.h (elf_object_p): Check for them here, instead.
+
+Sun Dec 15 14:46:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcode.h (elf_slurp_reloc_table): Add dynamic parameter.
+ * elf.c (_bfd_elf_canonicalize_reloc): Pass new argument to
+ slurp_reloc_table.
+ (_bfd_elf_get_dynamic_reloc_upper_bound): New function.
+ (_bfd_elf_canonicalize_dynamic_reloc): New function.
+ * elf-bfd.h (struct elf_size_info): Update declaration of
+ slurp_reloc_table.
+ (_bfd_elf_get_dynamic_reloc_upper_bound): Declare.
+ (_bfd_elf_canonicalize_dynamic_reloc): Declare.
+ * elfxx-target.h: Use new dynamic reloc routines by default.
+ * elf64-mips.c (mips_elf64_slurp_reloc_table): Add dynamic
+ parameter.
+
+Fri Dec 13 13:18:49 1996 Dan Wilder <dan@gasboy.com>
+
+ * coffcode.h (coff_set_flags): Use MC68KBCSMAGIC for bfd_arch_m68k
+ if NAMES_HAVE_UNDERSCORE is defined.
+
+Fri Dec 13 11:13:23 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * libaout.h (enum machine_type): Change M_SPARCLET from 142 to 131.
+
+Thu Dec 12 15:07:20 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Move R_PPC_PLTREL24 into the
+ supported relocs.
+
+Thu Dec 12 14:55:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Only add a weak
+ symbol if the real definition is in the dynamic symbol table.
+ After finding the real definition, then, if it is dynamic, add the
+ weak symbol to the dynamic symbol table.
+
+ * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Make static.
+
+ * ppcboot.c (ppcboot_set_arch_mach): Don't define; it's a
+ function.
+ (ppcboot_bfd_print_private_bfd_data): Don't take the address of an
+ array.
+
+Tue Dec 10 23:23:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (reloc_type): Remove big endian mn10300 reloc
+ variants.
+ (elf32_mn10300_howto_table, mn10300_reloc_map): Likewise.
+ (bfd_elf32_mn10300_reloc): Write data in little endian format.
+ * reloc.c: Remove mn10300 big endian relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+ * elf32-mn10200.c: Update from elf32-mn10300.c.
+
+Fri Dec 6 15:18:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (elf_symbol_leading_char): Define.
+
+ * elf32-mn10300.c: Add some comments.
+
+Fri Dec 6 17:16:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ihex.c (ihex_scan): Always initialize buf before jumping to
+ error_return.
+ (ihex_read_section): Likewise.
+
+Thu Dec 5 22:29:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (elf_mn10300_howto_table): Don't set partial-
+ inplace for most relocs.
+
+Thu Dec 5 13:24:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Calling check_relocs
+ even if SEC_ALLOC is not set.
+ * elf32-i386.c (elf_i386_check_relocs): Don't check SEC_ALLOC
+ when deciding whether to copy a reloc into a shared object.
+ (elf_i386_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Likewise.
+ (elf32_sparc_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_check_relocs): Don't set SEC_ALLOC in a
+ reloc section if it is not set in the source section.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Likewise.
+ * elf.c (bfd_section_from_shdr): Mark a reloc section associated
+ with a SEC_DEBUGGING section as SEC_DEBUGGING.
+
+Wed Dec 4 14:18:13 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): #if 0 code that
+ expects a .got.plt until we actually create it.
+
+Mon Dec 2 12:13:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Print an error
+ message for bfd_reloc_outofrange, rather than aborting. From
+ Philippe De Muyter <phdm@info.ucl.ac.be>.
+
+ * cofflink.c (_bfd_coff_final_link): If there aren't any relocs in
+ a relocateable link, don't try to process them. From Heinz Wrobel
+ <wrobel@lpr.e-technik.tu-muenchen.de>.
+
+Mon Dec 2 00:39:24 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (mn10300_info_howto): Renamed from
+ mn10300_info_howto_rel. Tweak reloc argument to be an
+ Elf32_Internal_Rela.
+ (USE_RELA): Define instead of USE_REL.
+ (elf_info_to_howto, elf_info_howto_rel): Corresponding changes.
+
+Sun Dec 1 00:18:59 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * configure.in, configure: Handle mips*-sgi-irix6*.
+ * irix-core.c (irix_core_core_file_p): Accept CORE_MAGICN32
+ core files.
+
+Wed Nov 27 12:10:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Warn about a
+ relocation against a symbol defined in a section with no output
+ section.
+
+Tue Nov 26 11:07:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4 (BFD_CC_FOR_BUILD): Don't require AC_C_CROSS.
+ * configure, config.in: Rebuild with autoconf 2.12.
+
+ * elf-bfd.h (struct elf_link_hash_entry): Add other field.
+ * elf.c (_bfd_elf_link_hash_newfunc): Initialize other field.
+ (swap_out_syms): Set st_other from existing st_other field.
+ * elflink.h (elf_link_add_object_symbols): Store st_other in hash
+ table other field.
+ (elf_link_output_extsym): Set the other field from the global hash
+ table entry.
+ * elf32-mips.c (enum reloc_type): Add R_MIPS16_26.
+ (elf_mips16_jump_howto): New static variable.
+ (mips16_jump_reloc): New static function.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle BFD_RELOC_MIPS16_JMP.
+ (mips_info_to_howto_rel): Handle R_MIPS16_26.
+ (mips_elf_relocate_section): Handle R_MIPS16_26. Handle R_MIPS_26
+ to a mips16 symbol.
+ * reloc.c (BFD_RELOC_MIPS16_JMP): Add to list of relocs.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * cpu-mips.c (arch_info_struct): Add mips:16 entry.
+
+Mon Nov 25 11:23:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Use long long for mips-sgi-irix6*.
+
+ * coffswap.h (coff_swap_scnhdr_out): Make line number overflow
+ only a warning. From Philippe De Muyter <phdemuyt@ulb.ac.be>.
+
+Mon Nov 25 08:52:29 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c (bfd_elf32_mn10300_reloc): New function.
+ (enum reloc_type): Add more reloc types.
+ (elf32_mn10300_howto_table): Update for new reloc types.
+ (elf32_mn10300_reloc_map): Update for new reloc types.
+ * reloc.c: Add some new relocs for the mn10300 series.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+Sat Nov 23 13:26:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (setup_sections): Don't lose for a space which has
+ no data, but some symbols.
+
+Fri Nov 22 11:32:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (struct sunos_link_hash_table): Add got_needed field.
+ (sunos_link_hash_table_create): Initialize got_needed.
+ (sunos_create_dynamic_sections): Only set .got section size if it
+ is not already set. Set got_needed.
+ (bfd_sunos_size_dynamic_sections): Check got_needed. Only set
+ sdynptr, and only handle dynamic sections, if dynamic sections are
+ needed.
+ (sunos_scan_std_relocs): Pass false to create_dynamic_sections.
+ Initialize .got section.
+ (sunos_scan_ext_relocs): Likewise.
+ (sunos_write_dynamic_symbol): Set up PLT entry even if this is not
+ a dynamic symbol.
+ (sunos_finish_dynamic_link): Check got_needed. Only set up
+ dynamic linking information if needed.
+
+Thu Nov 21 10:31:31 1996 Rob Savoye (rob@cygnus.com)
+
+ * config.bfd: Added VersaDOS format to the Ericsson configuration.
+
+Wed Nov 20 16:31:31 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-mn10300.c: Rough cut at relocs for the mn10300.
+
+Wed Nov 13 08:12:38 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (elf32-d10v.o): Don't depend on elf/d10v.h
+ anymore.
+
+Tue Nov 12 13:30:00 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * filemode.c: Include sysdep.h.
+ * ihex.c: Add casts to eliminate compiler warnings.
+ * sunos.c: Add casts to eliminate compiler warnings.
+
+Mon Nov 11 10:37:02 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Create .got.plt
+ section.
+ (ppc_elf_check_relocs): Add support for R_PPC_LOCAL24PC. Make
+ appropriate relocations in the .so file if shared.
+ (ppc_elf_relocate_section): Ditto.
+
+Tue Oct 29 15:03:02 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf32-m32r.c (elf_m32r_howto_table, R_M32R_24): Use
+ complain_overflow_unsigned.
+
+Tue Oct 29 12:53:46 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * elf32-d10v.c (elf_d10v_howto_table): Don't complain on
+ overflows for R_D10V_16 and R_D10V_18.
+
+Tue Oct 29 13:23:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_write_section_part): Use LMA rather than VMA.
+ (do_with_relocs): Likewise.
+ (do_as_repeat): Likewise.
+ (copy_expression): Likewise.
+
+Fri Oct 25 16:56:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_write_external_part): Correctly record whether
+ there is an external part.
+
+Thu Oct 24 14:32:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (elf32_v850_bfd_final_link_relocate): Correctly
+ handle tda offsets for sld.w and sst.w instructions.
+ Fix alignment check in sld.w and sst.w tda reloc handling.
+
+Thu Oct 24 09:08:47 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * aclocal.m4, configure: Set USE_BINARY_FOPEN for *-*-windows.
+
+Wed Oct 23 00:53:16 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c: Add comments about assumptions about
+ char, short & long sizes.
+ (elf32_v850_bfd_final_link_relocate): Fix sign extension
+ problems for several relocs.
+
+ * elf32-v850.c (elf32_v850_howto_table): Fix typo in
+ R_V850_SDA_OFFSET entry.
+
+Wed Oct 23 00:20:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (bfd_xcoff_import_symbol): Don't allocate ldsym.
+ Store import file index in ldindx.
+ (xcoff_build_ldsyms): Assume that ldsym was not previously
+ allocated. For an imported symbol, copy ldindx into l_ifile.
+
+Tue Oct 22 19:20:38 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (elf_v850_howto_table): Fix ordering of
+ R_V850_ZDA_OFFSET and R_V850_TDA_OFFSET. Fix various
+ fields in R_V850_TDA_OFFSET.
+ (elf32_v850_bfd_final_link_relocate): Tweak pc-relative
+ relocs to work more like other relocs. Handle R_V850_TDA_OFFSET
+ relocations.
+
+ * elf32-v850.c: Include bfdlink.h.
+ (bfd_elf32_v850_reloc): Return an error if we get a reloc
+ we can't handle.
+ (elf32_v850_bfd_final_link_relocate): New function.
+ (v850_elf_relocation_section): Likewise.
+ (elf_backend_relocate_section): Define.
+
+Tue Oct 22 17:22:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binary.c (binary_set_section_contents): Ignore sections which
+ don't have SEC_LOAD and SEC_ALLOC set.
+
+Mon Oct 21 12:13:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * linker.c (_bfd_generic_final_link): Avoid losing static
+ symbols in the .bss section.
+
+Mon Oct 21 10:54:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (elf_mips_howto_table): Describe R_MIPS_64.
+ (mips32_64bit_reloc): New static function.
+ (mips_reloc_map): Add entry for BFD_RELOC_64.
+ (mips_elf_relocate_section): Handle R_MIPS_64.
+
+ * linker.c (default_indirect_link_order): Print an error message
+ when attempting to do a relocateable link with different object
+ file formats, rather than calling abort.
+
+Thu Oct 17 10:43:29 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * reloc.c (m32r relocs): Rename them.
+ * bfd-in2.h, libbfd.h: Regenerated.
+ * elf32-m32r.c: Update.
+ (m32r_elf_10_pcrel_reloc): New function.
+ (elf_m32r_howto_table, R_M32R_10_PCREL entry): Use it.
+ (elf_m32r_howto_table, R_M32R_24 entry): Fix {src,dst}_masks.
+
+Wed Oct 16 11:24:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * linker.c (_bfd_generic_final_link): Set "linker_mark" for
+ all sections that will be included in the output file.
+ (_bfd_generic_link_output_symbols): Discard symbols in sections
+ which are being discarded.
+ * elf32-v850.c (enum reloc_type): Add R_V850_SDA_OFFSET,
+ R_V850_TDA_OFFSET and R_V850_ZDA_OFFSET.
+ (elf_v850_howto_table): Corresponding changes.
+ (elf_v850_reloc_map): Corresponding changes.
+ * reloc.c: Add additional V850 relocations.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+ * elf32-v850.c (bfd_elf32_v850_reloc): Mask out bits we
+ no longer want in pc-relative relocs.
+
+Tue Oct 15 22:17:37 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (bfd_elf32_v850_reloc): Don't silently
+ accept a reloc against an undefined sybmol!
+
+Tue Oct 15 16:17:28 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * elf32-v850.c: Define elf_symbol_leading_char to be '_'.
+
+Tue Oct 15 12:40:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * VERSION: Bump for new relocation.
+
+ * hosts/i386bsd.h: If NBPG is not defined, define it as
+ PAGE_SIZE, for recent versions of FreeBSD.
+
+Mon Oct 14 12:37:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Use `long long' as the 64 bit type on a Solaris
+ host, since both gcc and the SunPRO compilers support it.
+
+Mon Oct 14 11:17:24 1996 Richard Henderson <rth@tamu.edu>
+
+ * reloc.c: Create a new BFD_RELOC_ALPHA_ELF_LITERAL. It was a
+ mistake to have reused the ECOFF LITERAL for ELF since they have
+ different semantics.
+ * elf64-alpha.c (elf_reloc_map): Map from ELF_LITERAL.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Trap .got
+ section overflow.
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Do not emit a
+ dynamic relocation for an undefweak symbol when we are building
+ a static executable.
+
+Thu Oct 10 11:15:06 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed (config.bfd, targmatch.sed): Edit references to
+ point explicitly to srcdir.
+ (targmatch.h): Edit references to point explicitly to objdir.
+
+Thu Oct 10 14:14:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.bfd: When setting targ_cpu, don't get confused by
+ linux-gnu.
+
+Tue Oct 8 08:51:19 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * configure.host: Add support for windows host (a build done
+ under the Microsoft build environment).
+
+Tue Oct 8 11:40:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): If a symbol is a weak
+ definition in a dynamic object, add it to the dynamic symbol table
+ if any dynamic object mentions it. Reverts part of last patch.
+
+ * sunos.c (struct sunos_link_hash_table): Add got_base field.
+ (sunos_link_hash_table_create): Initialize got_base.
+ (bfd_sunos_size_dynamic_sections): If the .got section is more
+ than 0x1000 bytes, set __GLOBAL_OFFSET_TABLE_ and got_base to
+ 0x1000.
+ (sunos_check_dynamic_reloc): Subtract got_base from a base
+ relative relocation.
+
+ * elf32-mips.c (elf_mips_isa): New static function.
+ (_bfd_mips_elf_merge_private_bfd_data): Don't warn about linking
+ -mips1 and -mips2 code together, or -mips3 and -mips4 code.
+
+Mon Oct 7 11:44:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * archive.c (do_slurp_coff_armap): Only treat archive as little
+ endian for i960 COFF.
+
+Fri Oct 4 13:49:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_compute_section_file_positions): Adjust sofar
+ by the change in size of the section when EXEC_P is not set.
+
+ * coff-m68k.c (coff_rtype_to_howto): Define if not defined.
+ (m68kcoff_rtype_to_howto): New static function.
+ * cf-m68klynx.c (coff_m68k_lynx_rtype_to_howto): Add the section
+ VMA to the addend for a PC relative reloc.
+
+ * dep-in.sed: Rework backslash loop a bit to avoid bug in sed on
+ HP/UX 10.20.
+ * Makefile.in: Rebuild dependencies.
+
+ * dep-in.sed: Remove ../bfd/sysdep.h, since it will appear when
+ som.h is included.
+
+Fri Oct 4 11:41:39 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in: Remove explicit dependencies for mn10200 and
+ mn10300 files.
+ (ALL_MACHINE_CFILES): Add cpu-mn10200.c and cpu-mn10300.c.
+ (BFD32_BACKENDS_CFILES): Add elf32-mn10200.c and elf32-mn10300.c
+ (dependencies): Rebuilt.
+
+Thu Oct 3 16:57:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (coff_link_add_symbols): Set obj_coff_keep_syms
+ during this function.
+
+ * elflink.c (_bfd_elf_create_linker_section): Only use an existing
+ section if the flags are compatible.
+
+ * configure.in: Add havevecs, and put it in tdefaults.
+ * mpw-config.in: Likewise.
+ * configure: Rebuild.
+ * targmatch.sed: New file; a sed script to build targmatch.h from
+ config.bfd.
+ * config.bfd: Add #if, #endif, and comments for targmatch.h.
+ * targets.c: Include "fnmatch.h".
+ (struct targmatch): Define.
+ (bfd_target_match): Define by including targmatch.h.
+ (bfd_find_target): If the target is not found by name, search for
+ it as a configuration triplet.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add aout-arm.o, aout-sparcle.o, hp300bsd.o,
+ i386dynix.o, m68k4knetbsd.o, and riscix.o.
+ (BFD32_BACKENDS_CFILES): Add aout-arm.c, aout-sparcle.c,
+ hp300bsd.c, i386dynix.c, m68k4knetbsd.c, and riscix.c.
+ (HFILES): Add targmatch.h. Also, alphabetize and reindent.
+ (CFILES): Remove i386dynix.c and hp300bsd.c.
+ (targmatch.h): New target.
+ (do_clean): Remove targmatch.h.
+
+ * configure.in: Add BFD_NEED_DECLARATION(getenv).
+ * acconfig.h: Add NEED_DECLARATION_GETENV.
+ * configure, config.in: Rebuild.
+ * sysdep.h: If NEED_DECLARATION_GETENV, declare getenv.
+ * aout-adobe.c (aout_adobe_object_p): Don't declare getenv.
+
+Thu Oct 3 09:29:09 1996 Jeffrey A Law (law@cygnus.com)
+
+ * cpu-mn10x00.c, elf32-mn10x00: Removed.
+ * cpu-mn10200.c, cpu-mn10300.c: New files.
+ * elf32-mn10200.c, elf32-mn10300.c: New files.
+ * Makefile.in: Break mn10x00 support into two separate
+ configurations, mn10200 and mn10300.
+ * archures.c, config.bfd, configure.in, elf.c, targets.c: Likewise.
+ * bfd-in2.h, configure: Rebuilt.
+
+Thu Oct 3 15:38:19 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (do_clean): Move config.log to do_distclean.
+
+Wed Oct 2 21:40:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * cpu-mn10x00.c, elf32-mn10x00.c: New files.
+ * Makefile.in (ALL_MACHINES): Add cpu-mn10x00.o.
+ (BFD32_BACKENDS): Similarly for elf32-mn10x00.o.
+ (elf32-mn10x00.o): Add dependencies.
+ * archures.c (enum bfd_architecture): Add bfd_arch_mn10x00.
+ (bfd_mn10x00_arch): Declare.
+ (bfd_archures_list): Add bfd_mn10x00_arch.
+ * config.bfd: Add mn10x00-*-*.
+ * configure.in: Add bfd_elf32_mn10x00_vec.
+ * elf.c (prep_headers): Handle bfd_arch_mn10x00.
+ * targets.c (bfd_elf32_mn10x00_vec): Declare.
+ (bfd_target_vector): Add bfd_elf32_mn10x00_vec.
+ * bfd-in2.h, configure: Rebuilt.
+
+Wed Oct 2 15:46:45 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ openVMS/Alpha: Provide filename and case_hack flags via
+ symbol table from gas.
+ Add case_hack code for symbol output from vax/vms.
+ * evax-alpha.c (evax_initialize): Remove filename handling,
+ filename is provided via symbol table.
+ (evax_get_symtab): Use local symbol count when setting up table.
+ * evax-egsd.c (_bfd_evax_slurp_egsd): Print correct name when
+ debugging.
+ (_bfd_evax_write_egsd): Skip file name symbol.
+ * evax-emh.c (get_vms_time_string): Local function now.
+ (_bfd_evax_write_emh): Extract source filename and case_hack flags
+ from symbol table.
+ * evax_write_etir (_bfd_evax_write_etir): Pass all symbol names
+ through _bfd_evax_case_hack_symbol.
+ * evax-misc.c (hash_string, _bfd_evax_case_hack_symbol): New
+ functions.
+ (_bfd_evax_basename): Removed.
+ (_bfd_get_vms_time_string): Moved to evax-emh.c.
+ * evax.h (evax_private_data_struct): Remove filename.
+ (flag_hash_long_names, flag_show_after_trunc,
+ flag_no_hash_mixed_case, vms_name_mapping): New flags for
+ vms_case_hack.
+
+Wed Oct 2 12:02:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * freebsd.h (N_GET_MAGIC_NET): Don't use ntohl.
+ (N_GETMID_NET, N_GETFLAG_NET): Likewise.
+ (NO_SWAP_MAGIC): Don't define.
+ (SWAP_MAGIC): Define.
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Don't crash if there is
+ no hash table entry for a global symbol.
+
+Tue Oct 1 16:14:22 1996 Joel Sherrill <joel@oarcorp.com>
+
+ * config.bfd (mips*-*-rtems*): New target, like mips*-*-elf*.
+
+Tue Oct 1 12:31:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (coff_link_add_symbols): Don't override a meaningful
+ symbol type with T_NULL. Warn if symbol type changes. Based on
+ patch from Philippe De Muyter <phdm@info.ucl.ac.be>.
+
+ * elflink.h (elf_link_add_object_symbols): Only put a symbol from
+ a dynamic object in the dynamic symbol table if it is referenced
+ or defined by a regular object.
+
+Fri Sep 27 18:41:07 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * elf32-v850.c (bfd_elf32_v850_is_local_label): New function to
+ remove dwarf local labels. Shrinks binaries by a factor of 3!
+
+Mon Sep 23 13:33:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Create the .sbss section
+ by hand, rather than by calling bfd_make_section.
+
+Mon Sep 23 09:23:41 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * reloc.c: Rename m32r relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+ * elf32-m32r.c: Update.
+
+Fri Sep 20 11:43:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (aout_link_input_section_ext): When doing a relocateable
+ link, adjust the symbol index of a base relative reloc. Don't
+ change the addend of a PC relative reloc if pcrel_offset is set.
+ * sunos.c (bfd_sunos_size_dynamic_sections): Don't do anything for
+ a relocateable link.
+
+ * reloc.c (bfd_perform_relocation): Apply the relocation even if
+ it is zero, in case src_mask matters.
+ (bfd_install_relocation): Likewise.
+
+Thu Sep 19 11:03:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Always initialize
+ keep_syms.
+ (_bfd_xcoff_bfd_final_link): Don't set target_index
+ to an uninitialized value.
+
+Tue Sep 17 14:18:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_slurp_line_table): Warn about illegal symbol
+ indices, rather than crashing.
+ (coff_slurp_reloc_table): Likewise. Check whether the howto field
+ is NULL.
+ * coff-sh.c (sh_relocate_section): Check for an illegal symbol
+ index.
+
+Mon Sep 16 12:39:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-arm.c (aoutarm_std_reloc_howto): Change dst_mask for ARM26D
+ reloc to 0.
+ (coff_arm_adjust_symndx): New static function.
+ (coff_adjust_symndx): Define.
+
+ * srec.c (srec_scan): Accept multiple symbols on a single line.
+ From Pascal Martin <pmartin@alsys.com>.
+
+ * README: New file.
+
+Fri Sep 13 14:32:42 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * aoutf1.h (MY_bfd_merge_private_bfd_data): Define.
+ (sunos_merge_private_bfd_data): New function.
+
+Fri Sep 13 15:50:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd.c (bfd_copy_private_bfd_data): Switch on output BFD rather
+ than input BFD.
+ (bfd_merge_private_bfd_data): Likewise.
+ * section.c (bfd_copy_private_section_data): Likewise.
+ * syms.c (bfd_copy_private_symbol_data): Likewise.
+ * bfd-in2.h: Rebuild.
+ * aout-target.h (MY_bfd_copy_private_section_data): Check that
+ both BFD's are the right flavour.
+ * ecoff.c (_bfd_ecoff_bfd_copy_private_bfd_data): Likewise.
+ * elf.c (_bfd_elf_copy_private_symbol_data): Likewise.
+ * elf32-mips.c (_bfd_mips_elf_copy_private_bfd_data): Likewise.
+ (_bfd_mips_elf_merge_private_bfd_data): Likewise.
+ * elf32-ppc.c (ppc_elf_copy_private_bfd_data): Likewise.
+ (ppc_elf_merge_private_bfd_data): Likewise.
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Likewise.
+ * peicode.h (pe_bfd_copy_private_section_data): Likewise.
+
+ * elf32-hppa.c (elf_hppa_howto_table): Fill in some fields for
+ R_PARISC_DIR32, so that _bfd_stab_section_find_nearest_line passes
+ its sanity check.
+
+Thu Sep 12 11:45:57 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * reloc.c: Add m32r relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+ * cpu-m32r.c,elf32-m32r.c: New files.
+
+Thu Sep 12 11:10:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_vec): Set symbol_leading_char field to '_'.
+
+Wed Sep 11 11:57:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * tekhex.c (first_phase): Change type parameter from char to int.
+ (out): Likewise.
+ (pass_over): Change func to expect int, not char.
+
+ * elf.c (assign_file_positions_for_segments): Test SEC_ALLOC
+ rather than SEC_LOAD when aligning the file offset for the first
+ section in a segment.
+
+Tue Sep 10 16:18:30 1996 Fred Fish <fnf@cygnus.com>
+
+ * syms.c (coff_section_type): Make arg const.
+ * irix-core.c (irix_core_core_file_p): Remove extraneous extra arg
+ to make_bfd_asection().
+ * elf-bfd.h (bfd_section_from_phdr): Add prototype.
+ * elfcode.h (bfd_section_from_phdr): Remove prototype.
+ (_bfd_elf_stringtab_init): Remove prototype.
+
+ * netbsd-core.c (swap_abort): Add prototype.
+ * aix386-core.c (swap_abort): Ditto & make static
+ * hpux-core.c (swap_abort): Ditto & make static.
+ * irix-core.c (swap_abort): Ditto & make static.
+ * ptrace-core.c (swap_abort): Ditto & make static.
+ * trad-core.c (swap_abort): Ditto & make static.
+ * coffswap.h (coff_swap_reloc_in): Ditto.
+ (coff_swap_reloc_out): Ditto.
+ (coff_swap_filehdr_in): Ditto.
+ (coff_swap_filehdr_out): Ditto.
+ (coff_swap_sym_in): Ditto.
+ (coff_swap_sym_out): Ditto.
+ (coff_swap_aux_in): Ditto.
+ (coff_swap_aux_out): Ditto.
+ (coff_swap_lineno_in): Ditto.
+ (coff_swap_lineno_out): Ditto.
+ (coff_swap_aouthdr_in): Ditto.
+ (coff_swap_aouthdr_out): Ditto.
+ (coff_swap_scnhdr_in): Ditto.
+ (coff_swap_scnhdr_out): Ditto.
+ * ihex.c (ihex_sizeof_headers): Ditto.
+ * tekhex.c (getsym): Ditto.
+ (find_chunk): Ditto & make static.
+ (insert_byte): Ditto.
+ (first_phase): Ditto.
+ (pass_over): Ditto.
+ (tekhex_get_symtab): Ditto & make static.
+ (tekhex_get_symtab_upper_bound): Ditto & make static.
+ (tekhex_mkobject): Ditto.
+ (tekhex_object_p): Ditto.
+ (move_section_contents): Ditto.
+ (tekhex_get_section_contents): Ditto.
+ (tekhex_set_arch_mach): Ditto & make static.
+ (tekhex_set_section_contents): Ditto.
+ (writevalue): Ditto.
+ (writesym): Ditto.
+ (out): Ditto.
+ (tekhex_write_object_contents): Ditto.
+ (tekhex_sizeof_headers): Ditto.
+ (tekhex_make_empty_symbol): Ditto.
+ (tekhex_get_symbol_info): Ditto.
+ (tekhex_print_symbol): Ditto.
+ * irix-core.c (make_bfd_asection): Ditto.
+ (irix_core_core_file_p): Ditto.
+ (irix_core_core_file_failing_command): Ditto.
+ (irix_core_core_file_failing_signal): Ditto.
+ (irix_core_core_file_matches_executable_p): Ditto.
+ (irix_core_make_empty_symbol): Ditto.
+ * coff-mips.c (mips_bfd_reloc_type_lookup): Ditto.
+ * srec.c (srec_new_symbol): Ditto.
+ (srec_get_section_contents): Ditto.
+ (srec_set_arch_mach): Ditto.
+ (srec_set_section_contents): Ditto.
+ (internal_srec_write_object_contents): Ditto.
+ (srec_write_object_contents): Ditto.
+ (symbolsrec_write_object_contents): Ditto.
+ (srec_sizeof_headers): Ditto.
+ (srec_make_empty_symbol): Ditto.
+ (srec_get_symtab_upper_bound): Ditto.
+ (srec_get_symtab): Ditto.
+ (srec_print_symbol): Ditto and make static.
+ * elf.c (elf_read): Ditto
+ (assign_section_numbers): Ditto.
+ (elf_fake_sections): Ditto.
+ (sym_is_global): Ditto.
+ (elf_map_symbols): Ditto.
+ (get_program_header_size): Ditto.
+ * coffgen.c (make_a_section_from_file): Ditto.
+ (coff_real_object_p): Ditto.
+ (fixup_symbol_value): Ditto.
+ (build_debug_section): Ditto.
+ (copy_name): Ditto.
+ * syms.c (coff_section_type): Ditto.
+
+Mon Sep 9 22:36:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * bfd-in2.h: Rebuilt after m32r changes.
+
+Mon Sep 9 12:31:22 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.bfd,configure.in,configure: Add m32r support.
+ * Makefile.in,archures.c,elf.c,targets.c: Likewise.
+ * config.bfd: Keep target list alphabetically sorted.
+
+Mon Sep 9 11:48:41 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (bfd_elf32_v850_reloc, case R_V850_HI16): Don't forget
+ to add in the constant part found in the instruction itself.
+ (case R_V850_HI16_S): Likewise.
+
+Fri Sep 6 17:04:39 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * elf32-d10v.c (elf_d10v_howto_table): Modify the size of R_D10V_16
+ and R_D10V_18 to be 1 (word).
+
+Thu Sep 5 15:23:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (_bfd_link_section_stabs): If the output_section field
+ of either section is bfd_abs_section, then the linker is
+ discarding the section and we should not optimize it.
+
+Tue Sep 3 12:16:20 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (aout-sparcle.o): New target.
+ * aoutf1.h (TARGET_IS_BIG_ENDIAN_P): Don't define if little endian.
+ * config.bfd (sparclet-*-aout*): Add case.
+ * configure.in (sparcle_aout_vec): Add case.
+ * configure: Regenerated.
+ * targets.c (sparcle_aout_vec): Declare.
+ (bfd_target_vector): Add sparcle_aout_vec.
+ * aout-sparcle.c: New file.
+
+Tue Sep 3 00:57:02 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (bfd_elf32_v850_reloc): Fix handling of
+ low order sign bit propogation for R_V850_HI16_S.
+
+ * elf32-v850.c (bfd_elf32_v850_reloc): New function for
+ handling V850 specific relocs.
+ (elf_v850_howto_table): Use the new function for some
+ relocations. Twiddle masks & shifts for some relocs.
+ Set partial_inplace where needed.
+
+Mon Sep 2 12:12:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cpu-mips.c: Add an explicit mips:3000 entry, and change the
+ default architecture to a machine number of 0.
+ * elf32-mips.c (_bfd_mips_elf_object_p): Set the machine number
+ for E_MIPS_ARCH_1.
+ (_bfd_mips_elf_merge_private_bfd_data): If the machine number of
+ the output BFD is the default, set it from the first input BFD.
+
+Sun Sep 1 18:38:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (elf_v850_howto_table): All the 16bit relocs
+ insert at bitpos zero. The HI16 relocs are shifted right
+ by 16 bits. Fix src_mask for all relocs.
+ (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME): Define. The V850 is
+ little endian!
+ (TARGET_BIG_SYM, TARGET_BIG_NAME): Remove. The V850 is little
+ endian!
+
+Sun Sep 1 15:41:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * rs6000-core.c (rs6000coff_core_file_matches_executable_p):
+ Rewrite to use BFD file read routines and to avoid using a fixed
+ length for the file name.
+
+Sat Aug 31 10:22:25 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (enum reloc_type): Add R_V850_{32,16,8}.
+ (elf_v850_howto_table): Add support for R_V850_{32,16,8}.
+ (v850_reloc_map): Add translation from BFD_RELOC_{32,16,8}
+ to R_V850_{32,16,8}.
+
+Fri Aug 30 18:06:04 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * elf32-v850.c (reloc_type): Add R_V850_HI16_S.
+ (elf_v850_howto_table): Add info for HI16_S reloc.
+ (v850_reloc_map): Add HI_16_S reloc.
+ * reloc.c: Define BFD_RELOC_V850_* relocs.
+
+Fri Aug 30 11:49:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Add SH ELF support.
+ * elf32-sh.c: New file.
+ * elf.c (prep_headers): Handle bfd_arch_sh.
+ * elfcode.h (write_relocs): Handle absolute symbol.
+ * elf-bfd.h (_bfd_elf32_link_read_relocs): Declare.
+ (_bfd_elf64_link_read_relocs): Declare.
+ * elflink.h (NAME(_bfd_elf,link_read_relocs)): Rename from
+ elf_link_read_relocs. Make globally visible. Change all
+ callers.
+ (elf_link_input_bfd): Get external symbols from cache in
+ symtab_hdr->contents. Get contents from cache in
+ elf_section_data.
+ * elfxx-target.h (bfD_elfNN_bfd_relax_section): Only define if not
+ already defined.
+ * reloc.c: Define BFD_RELOC_SH_* relocs.
+ * libbfd-in.h (_bfd_sh_align_load_span): Declare.
+ * coff-sh.c (sh_insns_conflict): Fix a return value.
+ (_bfd_sh_align_load_span): New globally visible function, broken
+ out of sh_align_load.
+ (sh_align_load): Call _bfd_sh_align_load_span.
+ (sh_swap_insns): Change relocs parameter to PTR.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * targets.c (bfd_elf32_sh_vec): Declare.
+ (bfd_elf32_shl_vec): Declare.
+ * config.bfd (sh-*-elf*): New target.
+ * configure.in (bfd_elf32_sh_vec): New target vector.
+ (bfd_elf32_shl_vec): New target vector.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add elf32-sh.o.
+ (BFD32_BACKENDS_CFILES): Add elf32-sh.c.
+
+ * elf.c (map_sections_to_segments): Check that LMA does not skip a
+ page before checking D_PAGED.
+
+ * ihex.c (ihex_scan): Removed unnecessary extbase variable.
+ (ihex_write_object_contents): Remove extbase; always use segbase
+ instead.
+
+Thu Aug 29 16:52:17 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+ * configure.host (i[345]86-*-*): Ditto.
+ * config.bfd (i[345]86-*-*): Ditto.
+ * configure: Regenerate.
+
+ * config.bfd (i[3456]86-*-dgux*): Recognize as a synonym for x86
+ elf.
+
+Tue Aug 27 09:18:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-hppa.c (hppa_elf_gen_reloc_type): Add new argument.
+ * elf32-hppa.h (hppa_elf_gen_reloc_type): Update prototype.
+ * som.c (hppa_som_gen_reloc_type): Add new argument. If
+ we encounter an R_DATA_ONE_SYMBOL reloc against a symbol that
+ will have an ST_CODE type, change the symbol's type to ST_DATA.
+ * som.c (hppa_som_gen_reloc_type): Update prototype.
+
+Tue Aug 27 00:12:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_check_relocs): Set dynobj if needed for
+ R_MIPS_32 and R_MIPS_REL32. Set sgot and g as soon as possible.
+ (mips_elf_size_dynamic_sections): Don't require .got to exist.
+ (mips_elf_finish_dynamic_sections): Likewise.
+
+Thu Aug 22 10:54:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host (HLDENV): New variable to set. Set it for
+ *-*-sysv4*, since those linkers may not support -R but they always
+ support LD_RUN_PATH.
+
+ * libieee.h (NSECTIONS): Don't define.
+ (ieee_data_struct): Change section_table to asection **. Add
+ section_table_size.
+ * ieee.c (get_section_entry): If the table isn't big enough, make
+ it bigger.
+ (ieee_slurp_sections): Remove assertion about number of sections.
+ (ieee_object_p): Adjust initialization of ieee to match changes to
+ the structure.
+
+ * xcofflink.c (xcoff_mark): Don't copy relocs for undefined
+ symbols merely because we are generating a shared library.
+ (xcoff_build_ldsyms): Don't set up global linkage code for an
+ undefined symbol merely because we are generating a shared
+ library.
+
+Tue Aug 20 15:06:05 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * Makefile.in (ALL_MACHINES): Add cpu-v850.o.
+ (BFD32_BACKENDS) Add elf32-v850.o.
+ * archures.c: Add bfd_v850_arch.
+ * bfd-in2.h: Add bfd_v850_arch.
+ * config.bfd (v850-*-*): New target.
+ * configure: (bfd_elf32_v850_vec) New vector.
+ * configure.in: (bfd_elf32_v850_vec) New vector.
+ * cpu-v850.c: New file.
+ * elf.c (prep_headers): Added case bfd_arch_v850.
+ * elf32-v850.c: New file.
+ * targets.c (bfd_elf32_v850_vec): New vector.
+
+Fri Aug 16 16:25:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_dynamic_symbols): Create and define
+ a function code symbol for an XMC_XO symbol.
+
+Thu Aug 15 12:33:29 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Update editing of autoconf vars to reflect
+ Jul 18 configure.in change.
+ * mpw-make.sed: Update editing of include pathnames to be
+ more general, add @DASH_C_FLAG@ to explicit compile rule edit.
+
+Thu Aug 15 10:35:13 1996 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (elf64_alpha_output_extsym): The section from
+ which to offset to get the .plt entry address is ".plt".
+
+Thu Aug 15 16:40:30 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * reloc.c: (BFD_RELOC_ARM_THUMB_ADD, BFD_RELOC_ARM_THUMB_IMM,
+ BFD_RELOC_ARM_THUMB_SHIFT, BFD_RELOC_ARM_THUMB_OFFSET):
+ Added, for internal use by the ARM gas.
+ * libbfd.h: Rebuilt
+ * bfd-in2.h: Rebuilt
+
+Wed Aug 14 17:02:09 1996 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Correct typo
+ in section dynidx start.
+
+Tue Aug 13 14:35:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Treat sections whose
+ name begins with .gnu.linkonce as SEC_LINK_ONCE. This is an
+ optimization for g++.
+
+Tue Aug 13 17:04:40 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data): If one module has
+ the -mrelocatable-lib bit set and the other doesn't, clear the
+ -mrelocatable-lib bit in the header.
+
+Sat Aug 10 22:59:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_link_add_object_symbols): Do not resolve a common
+ symbol against a STT_FUNC symbol in a shared library.
+
+Fri Aug 9 12:44:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_dynamic_symbols): If a descriptor
+ symbol is found, automatically define the corresponding function
+ code.
+
+ * cofflink.c (coff_link_add_symbols): Only set (*sym_hash)->numaux
+ if sym.n_numaux is not zero.
+ (_bfd_coff_link_input_bfd): Permit the symbol and the hash table
+ entry to disagree about the number of aux entries if the symbol
+ has zero.
+
+ * elf32-mips.c (mips_elf_check_relocs): Create the .rel.dyn
+ section if it might be needed, not just if info->shared.
+ (mips_elf_adjust_dynamic_symbol): Make room for a null element at
+ the start of .rel.dyn if we are going to use it.
+ (mips_elf_finish_dynamic_sections): Only clear the first element
+ of .rel.dyn if the size is greater than zero.
+
+Thu Aug 8 16:24:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_input_bfd): If we already called the
+ undefined_symbol callback for a symbol, then don't issue any more
+ warnings about loader relocs.
+ (_bfd_ppc_xcoff_relocate_section): Don't do any further processing
+ after calling the undefined_symbol callback.
+
+ * xcofflink.c (XCOFF_MULTIPLY_DEFINED): Define.
+ (xcoff_link_add_symbols): Permit multiple definitions of a symbol
+ as the AIX linker seems to do.
+
+Thu Aug 8 12:21:56 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * evax-alpha.c (evax_alpha_vec): Corrected flags, cleanup.
+ (evax_initialize): Remove evax_reloc_table.
+ (evax_close_and_cleanup): Ditto.
+ (reloc_nil): Ditto.
+ (alpha_howto_table): Remove ALPHA_R_SWREL32 and ALPHA_R_SWREL64
+ entries.
+ (evax_bfd_reloc_type_lookup): Ditto.
+ * evax-egsd.c (_bfd_evax_slurp_egsd): Add a few casts; set
+ cooked_size == raw_size.
+ * evax-emh.c (_bfd_evax_register_filename): Remove.
+ * evax-etir.c (etir_stc): Allow ETIR_S_C_STC_xx commands.
+ * evax-misc.c (add_new_contents): Malloc section at full size.
+ (_bfd_save_evax_section): Memcpy section contents directly.
+ * evax.h (ALPHA_R_SWREL32, ALPHA_R_SWREL64): Remove.
+ (evax_reloc_table): Remove.
+
+ * hosts/alphavms.h (O_ACCMODE): Define if needed.
+
+ * makefile.vms: Add better support for DEC C compilation
+ Add evax.h dependencies
+
+ * reloc.c (bfd_get_reloc_size): Add case for 16 byte reloc.
+ (BFD_RELOC_SWREL32,BFD_RELOC_SWREL64): Remove.
+ (BFD_RELOC_ALPHA_BASEREG): Remove.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+Thu Aug 8 08:17:32 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * archive.c (bsd_write_armap): Ifdef around calls to getuid and
+ getgid if _WIN32 is defined.
+ * opncls.c (bfd_fdopenr): Remove unnecessary WINGDB ifdef.
+
+Wed Aug 7 23:19:00 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * aoutx.h bfd-in.h bfd-in2.h opncls.c riscix.c som.c targets.c:
+ Change NO_FLAGS to BFD_NO_FLAGS to avoid conflict with an HPUX
+ include file.
+ * libbfd.c: Create dummy getpagesize() macro if HAVE_GETPAGESIZE
+ isn't defined.
+
+Wed Aug 7 14:11:44 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * configure.in: Call BFD_NEEDED_DECLARATION on strstr and
+ realloc.
+ * acconfig.h (NEED_DECLARATION_STRSTR): New macro.
+ (NEED_DECLARATION_REALLOC): New macro.
+ * configure, config.in: Rebuild.
+ * sysdep.h (strstr): Declare if NEED_DECLARATION_STRSTR.
+ (realloc): Declare if NEED_DECLARATION_REALLOC.
+
+ * aclocal.m4 (BFD_NEED_DECLARATION): Include <string.h> or
+ <strings.h> if they exist.
+
+ * ieee.c (ieee_set_section_contents): Cast bfd_alloc return.
+
+Wed Aug 7 12:12:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cpu-i386.c (i8086_arch): Architecture info for the i8086.
+
+ Based on patches from Eric Valette <valette@crf.canon.fr>:
+ * elf32-i386.c (enum reloc_type): Add FIRST_INVALID_RELOC,
+ LAST_INVALID_RELOC, R_386_16, R_386_PC16, R_386_8, R_386_PC8.
+ (elf_howto_table): Add entries for new relocs.
+ (elf_i386_reloc_type_lookup): Handle new relocs.
+ (elf_i386_info_to_howto): Just call abort.
+ (elf_i386_info_to_howto_rel): Check that the reloc type is valid.
+ (elf_i386_relocate_section): Likewise.
+
+Tue Aug 6 12:54:56 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * elf32-d10v.c (elf_d10v_howto_table): Added R_D10V_32.
+
+Mon Aug 5 13:42:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): For a loadable section,
+ only get the LMA from the phdr if they are in the same part of the
+ file.
+
+ * elf.c (map_sections_to_segments): Rewrite tests for starting a
+ new segment to make them more comprehensible. If the relationship
+ between the LMA and the VMA changed, start a new segment. Don't
+ check dynsec when deciding whether to start a new segment for a
+ writeable section; -N will now handle this.
+
+Thu Aug 1 22:43:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h: Remove "esel" changes. Not the right approach.
+ * som.c: Corresponding changes.
+ (som_bfd_derive_misc_symbol_info): Use ST_DATA for symbols
+ which don't have a SOM symbol type associated with them.
+ Reverses a 1994 change.
+
+Wed Jul 31 15:50:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Make ld -N more reasonable for ELF:
+ * elf.c (map_sections_to_segments): If D_PAGED is not set, set
+ phdr_in_section to false, and always use a single load segment.
+ (elf_sort_sections): Sort sections by LMA after VMA.
+ (assign_file_positions_for_segments): If D_PAGED is not set, don't
+ align to maxpagesize.
+ (assign_file_positions_except_relocs): Likewise.
+ * elfcode.h (elf_object_p): If a section is loaded but not page
+ aligned, clear D_PAGED.
+
+Wed Jul 31 15:00:12 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * reloc.c: (BFD_RELOC_ARM_OFFSETIMM8, BFD_RELOC_ARM_HWLITERAL):
+ Added, for internal use by the ARM gas.
+ * libbfd.h: Rebuilt
+ * bfd-in2.h: Rebuilt
+
+Tue Jul 30 14:14:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h (R_HPPA_ESEL): New field selector.
+ (e_esel): Similarly.
+ * som.c (hppa_som_gen_reloc_type): If we encounter an e_esel,
+ then generate R_COMP2 (PUSH_SYM), R_DATA_EXPR fixup stream.
+ (som_write_fixups): Handle R_DATA_EXPR just like R_CODE_EXPR.
+
+Tue Jul 30 13:31:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): Do the regular
+ archive search before looking for stripped dynamic objects.
+
+Fri Jul 26 17:51:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_build_ldsyms): Make exporting an undefined
+ symbol a warning rather than an error.
+
+Wed Jul 24 12:02:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Track the virtual
+ memory position separately from the file position, and use it to
+ compute the alignment adjustment.
+
+Tue Jul 23 10:43:31 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * elf32-d10v.c (elf_d10v_howto_table): Changed all relocs to "long"
+ and fixed mask on R_D10V_10_PCREL_L.
+
+Mon Jul 22 15:30:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf64-mips.c: Include "aout/ar.h".
+ (mips_elf64_slurp_armap): New static function.
+ (mips_elf64_write_armap): New static function.
+ (bfd_elf64_archive_*): Define.
+ * elfxx-target.h (bfd_elfNN_archive_p): Define if not defined.
+ Use instead of bfd_generic_archive_p.
+ (bfd_elfNN_write_archive_contents): Define if not defined. Use
+ instead of _bfd_write_archive_contents.
+ (bfd_elfNN_mkdarchive): Define if not defined. Use instead of
+ _bfd_generic_mkarchive.
+ (TARGET_BIG_SYM): If bfd_elfNN_archive_functions is defined, use
+ bfd_elfNN_archive in BFD_JUMP_TABLE_ARCHIVE rather than
+ _bfd_archive_coff.
+ (TARGET_LITTLE_SYM): Likewise.
+ * archive.c (bfd_slurp_armap): Check for and reject an archive map
+ name of /SYM64/.
+ * Makefile.in: Rebuild dependencies.
+
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing): Handle
+ SHT_MIPS_LIBLIST, SHT_MIPS_CONTENT, SHT_MIPS_SYMBOL_LIB, and
+ SHT_MIPS_EVENTS sections.
+ (_bfd_mips_elf_section_from_shdr): Handle SHT_MIPS_IFACE,
+ SHT_MIPS_CONTENT, SHT_MIPS_SYMBOL_LIB, and SHT_MIPS_EVENTS
+ sections.
+ (_bfd_mips_elf_fake_sections): Likewise.
+
+ * libecoff.h (ecoff_data_type): Add rdata_in_text field.
+ * ecoff.c (ecoff_compute_section_file_positions): Copy
+ rdata_in_text from backend info to tdata. Clear it if any data
+ section comes before .rdata.
+ (_bfd_ecoff_write_object_contents): Use rdata_in_text field in
+ tdata rather than backend info.
+
+Fri Jul 19 18:15:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Fix test for whether a compiler has a 64 bit
+ type. From Jim Wilson <wilson@cygnus.com>.
+
+Thu Jul 18 15:39:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host (mips-sgi-irix6*): New host.
+
+ * configure.in: Set and substitute VERSION, BFD_HOST_64BIT_LONG
+ (replacing HOST_64BITLONG), BFD_HOST_64_BIT_DEFINED,
+ BFD_HOST_64_BIT, and BFD_HOST_U_64_BIT. Add bfd-in2.h:bfd-in2.h
+ to AC_OUTPUT call.
+ * configure: Rebuild.
+ * bfd-in.h (BFD_ARCH_SIZE): Define as @wordsize@, not @WORDSIZE@.
+ (BFD_HOST_64_BIT): Define conditionally.
+ (BFD_HOST_U_64_BIT): Define when BFD_HOST_64_BIT is defined.
+ (bfd_vma): Typedef as BFD_HOST_U_64_BIT.
+ (symvalue, bfd_size_type): Likewise.
+ * bfd-in2.h: Rebuild.
+ * Makefile.in (do_clean): Remove bfd-tmp.h.
+ (do_distclean): Remove bfd-in3.h.
+ (stmp-bfd.h): Just do copy-if-change bfd-in3.h bfd.h.
+ (bfd-in3.h): New target.
+
+ * config.bfd (sparc-*-sysv4*): Don't build sunos_big_vec. From
+ Andrew Gierth <ANDREWG@microlise.co.uk>.
+
+ * configure.host: Set INSTALL_SHLIB.
+ * configure.in: Call AC_SUBST (INSTALL_SHLIB).
+ * configure: Rebuild.
+ * Makefile.in (install): Use @INSTALL_SHLIB@.
+
+ * config.bfd (mips*-*-irix6*): New target.
+ * configure.host: Handle Irix 6 shared library like Irix 5.
+
+ * xcofflink.c (xcoff_link_add_symbols): Don't check an XMC_TD
+ symbol for a magic name.
+ (xcoff_link_input_bfd): Don't change the reloc symbol for an
+ XMC_TD symbol.
+ (_bfd_ppc_xcoff_relocate_section): Don't get the TOC offset for an
+ XMC_TD symbol.
+
+Thu Jul 18 11:36:31 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add ELF support to mips config, create the
+ elf32-target.h file in the object dir.
+ * mpw-make.sed: Edit elfXX-target.h refs at beginnings of lines.
+
+Wed Jul 17 18:02:32 1996 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c: Redid debug scheme - numerous fprintf's gone.
+ Also removed most abort calls, in favor of using bfd reporting.
+
+Wed Jul 17 14:51:52 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * Makefile.in (ALL_MACHINES): Add cpu-d10v.o.
+ (BFD32_BACKENDS) Add elf32-d10v.o.
+ * archures.c: Add bfd_d10v_arch.
+ * bfd-in2.h: Add bfd_d10v_arch.
+ * config.bfd (d10v-*-*): New target.
+ * configure: (bfd_elf32_d10v_vec) New vector.
+ * configure.in: (bfd_elf32_d10v_vec) New vector.
+ * cpu-d10v.c: New file.
+ * elf.c (prep_headers): Added case bfd_arch_d10v.
+ * elf32-d10v.c: New file.
+ * libbfd.h: Rebuild.
+ * reloc.c (BFD_RELOC_D10V_10_PCREL_R, BFD_RELOC_D10V_10_PCREL_L,
+ BFD_RELOC_D10V_18, BFD_RELOC_D10V_18_PCREL): Define.
+ * targets.c (bfd_elf32_d10v_vec): New vector.
+
+Wed Jul 17 10:58:55 1996 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (coff_ppc_relocate_section): Removed bogus fprintf
+
+Tue Jul 16 23:49:02 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * archures.c bfd-in2.h: Add bfd_mach_i386_i386 and
+ bfd_mach_i386_i8086 machine types.
+
+Wed Jul 10 12:42:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_new_section_hook): Set SEC_CODE for _INIT
+ and _FINI sections.
+
+Wed Jul 10 11:18:21 1996 Richard Henderson <rth@tamu.edu>
+
+ * coffcode.h (coff_set_section_contents): A/UX does not require
+ special handling of the _LIB section.
+
+Tue Jul 9 15:52:20 1996 Jeffrey A Law (law@cygnus.com)
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Use the correct
+ value for R_RELBYTE.
+
+ * reloc16.c (bfd_coff_reloc16_relax_section): Only "shrinks"
+ array if one was allocated.
+
+Tue Jul 9 12:21:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Kazumoto Kojima <kkojima@kk.info.kanagawa-u.ac.jp>:
+ * elf32-mips.c (struct mips_elf_link_hash_table): Add new fields
+ use_rld_obj_head and rld_value.
+ (mips_elf_link_hash_table_create): Initialize new fields.
+ (mips_elf_add_symbol_hook): Mark __rld_obj_head symbol as
+ dynamic.
+ (mips_elf_create_dynamic_sections): Create .rld_map section. If
+ __rld_obj_head symbol not seen, create an __rld_map symbol.
+ (mips_elf_size_dynamic_sections): Make space in .rld_map section.
+ Create a DT_MIPS_RLD_MAP entry rather than a DT_DEBUG entry.
+ (mips_elf_finish_dynamic_symbol): Save value of __rld_map or
+ __rld_obj_head symbol.
+ (mips_elf_finish_dynamic_sections): Handle DT_MIPS_RLD_MAP.
+
+Mon Jul 8 16:18:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_reloc_map): Remove BFD_RELOC_32_PCREL entry.
+
+ * elf32-ppc.c (ppc_elf_howto_raw): For R_PPC_ADDR16_HA, use
+ ppc_elf_addr16_ha_reloc.
+ (ppc_elf_addr16_ha_reloc): New static function.
+
+ * coff-mips.c (struct mips_hi): Define.
+ (mips_refhi_list): New static variable.
+ (mips_refhi_addr, mips_refhi_addend): Remove.
+ (mips_refhi_reloc): Maintain a list of unmatched REFHI relocs.
+ (mips_reflo_reloc): Process mips_refhi_list.
+ (mips_relhi_list): New static variable.
+ (mips_relhi_addr, mips_relhi_addend): Remove.
+ (mips_relhi_reloc): Maintain a list of unmatched RELHI relocs.
+ (mips_rello_reloc): Process mips_relhi_list.
+ (mips_relocate_section): Permit an arbitrary number of REFHI or
+ RELHI relocs before the associated REFLO or RELLO reloc.
+
+Fri Jul 5 19:27:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aout-target.h (MY(callback)): Set reloc_count fields.
+
+Thu Jul 4 12:00:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (sunos_add_dynamic_symbols): Don't create dynamic
+ sections unless this is a SunOS link.
+
+ * VERSION: Set to 2.7.1.
+
+ * Released binutils 2.7.
+
+Wed Jul 3 14:59:47 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386aout.c: Include "aout/aout64.h".
+ (i386aout_write_object_contents): New static function.
+ (MY_write_object_contents): Define.
+
+ * netbsd.h (MY(write_object_contents)): Make sure that
+ adjust_sizes_and_vmas is called before fiddling with the magic
+ number.
+
+Tue Jul 2 23:30:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (_bfd_link_section_stabs): Fix casts of psinfo.
+
+Sun Jun 30 13:34:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libbfd-in.h (itos, stoi): Don't define.
+ * libbfd.h: Rebuild.
+ * i386lynx.c (KEEPIT): Define as udata.i.
+ (NAME(lynx,swap_std_reloc_out)): Don't use stoi.
+ (NAME(lynx,swap_ext_reloc_out)): Likewise.
+ * riscix.c (riscix_swap_std_reloc_out): Use udata.i rather than
+ flags. Don't use stoi.
+
+ * elf32-mips.c (ELF_MAGPAGESIZE): Change definition to 0x1000.
+
+ * elf.c (map_sections_to_segments): Don't start a new segment for
+ a writable section if it's on the same page as the previous
+ segment. Reset the writable variable for a readonly section.
+
+Sat Jun 29 16:18:51 1996 Kim Knuttila <krk@cygnus.com>
+
+ * peicode.h (coff_swap_aouthdr_in): Missing initializations of
+ first_thunk_address, thunk_size, and import_table_size.
+ * peicode.h: Improved some diagnostics regarding edata sections.
+
+ * coff-ppc.c (coff_ppc_relocate_section): Earlier error check
+ on IMGLUE relocs.
+ (coff_ppc_relocate_section): Improved diagnostic for large TOCDEFN's.
+ (TARGET_LITTLE_SYM): Added missing D_PAGED.
+
+Fri Jun 28 13:48:45 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_check_ar_symbols): An undefined symbol
+ with XCOFF_DEF_DYNAMIC set is really defined.
+ (xcoff_link_check_dynamic_ar_symbols): Likewise.
+ (xcoff_link_add_symbols): Only create special sections if using an
+ XCOFF hash table.
+
+ * reloc.c (bfd_perform_relocation): Handle xcoff-powermac like
+ aixcoff-rs6000.
+ (bfd_install_relocation): Likewise.
+
+Fri Jun 28 11:17:00 1996 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (struct alpha_elf_link_hash_entry): Add flags
+ field.
+ (ALPHA_ELF_LINK_HASH_LU_ADDR): Define.
+ (ALPHA_ELF_LINK_HASH_LU_MEM): Define.
+ (ALPHA_ELF_LINK_HASH_LU_FUNC): Define.
+ (elf64_alpha_link_hash_newfunc): Initialize flags field.
+ (elf64_alpha_check_relocs): Record types of LITUSE entries that
+ are found for LITERAL relocs.
+ (elf64_alpha_adjust_dynamic_symbol): If a symbol has its address
+ taken, we cannot generate a .plt entry for the symbol.
+
+Thu Jun 27 11:24:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add AC_ISC_POSIX, and check for setitimer and
+ sysconf functions (for gprof).
+ * configure, config.in: Rebuild.
+
+Wed Jun 26 16:29:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_archive_p): Check the first object file in
+ an archive if it has a map. If the object file has the wrong
+ xvec, reject it.
+
+ * coff-alpha.c (alpha_adjust_reloc_in): Set the addend for a
+ BRADDR, SREL16, SREL32, or SREL64 reloc against an external
+ symbol.
+ (alpha_relocate_section): Likewise.
+
+ * coffswap.h (coff_swap_reloc_out): Use RELSZ, not sizeof.
+ (coff_swap_filehdr_out): Use FILHSZ, not sizeof.
+ (coff_swap_sym_out): Use SYMESZ, not sizeof.
+ (coff_swap_aux_out): Use AUXESZ, not sizeof.
+ (coff_swap_lineno_out): Use LINESZ, not sizeof.
+ (coff_swap_aouthdr_out): Use AOUTSZ, not sizeof.
+ (coff_swap_scnhdr_out): Use SCNHSZ, not sizeof.
+ * peicode.h: Corresponding changes.
+
+Tue Jun 25 15:28:34 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elflink.h (elf_create_pointer_linker_section): Comment out code
+ dealing with making GOT pointers negative of the GOT symbol for
+ now.
+
+Tue Jun 25 11:41:24 1996 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c (elf64_alpha_adjust_dynamic_symbol): Don't
+ increment the .rela.plt size until after we're done creating the
+ .plt entry.
+ (elf64_alpha_finish_dynamic_symbol): Change .plt entry to load the
+ .rela.plt offset directly rather than calculating it.
+
+Mon Jun 24 17:15:10 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in, (bindir, libdir, datadir, mandir, infodir, includedir):
+ Use autoconf-set values.
+ * doc/Makefile.in (bindir, libdir, datadir, mandir, infodir,
+ includedir, INSTALL, INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set
+ values.
+ (docdir): Deleted.
+ * configure.in (AC_PREREQ): autoconf v2.5 or higher.
+ * configure: Rebuilt.
+
+Mon Jun 24 22:50:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_write_fixups): Fix typo in R_END_TRY for exception
+ handling code > 1k away.
+
+Mon Jun 24 18:41:06 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elflink.h (elf_create_pointer_linker_section): If DEBUG is
+ defined, output whenever the symbol is updated.
+
+Mon Jun 24 17:58:12 1996 Jouke Numan <jnuman@bazis.nl>
+
+ * elf.c (elf_fake_sections): Don't set sh_addr of a non SEC_ALLOC
+ section to 0 if user_set_vma is set.
+ * elflink.h (elf_bfd_final_link): Likewise.
+
+Sun Jun 23 20:42:51 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ Partially undo patch of Jun 20.
+ * coffcode.h (coff_set_alignment_hook): Use COFF_IMAGE_WITH_PE.
+ (coff_compute_section_file_positions): Likewise.
+ (coff_write_object_contents): Likewise. Re-add deleted code, but
+ use #ifdef COFF_WITH_PE, not COFF_OBJ_WITH_PE.
+ * peicode.h (pe_bfd_copy_private_bfd_data): Re-add #ifdef.
+
+Fri Jun 21 17:38:15 1996 Joel Sherrill <joel@merlin.gcs.redstone.army.mil>
+
+ * config.bfd: Add support for *-*-rtems* configurations.
+
+Fri Jun 21 15:19:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (prep_headers): Add bfd_arch_alpha case.
+
+Fri Jun 21 12:35:27 1996 Richard Henderson <rth@tamu.edu>
+
+ * elf64-alpha.c: New file.
+ * config.bfd (alpha-*-linuxecoff*): New target.
+ (alpha-*-linux*, alpha-*-elf*): New targets.
+ * configure.in (bfd_elf64_alpha_vec): New vector.
+ * configure: Rebuild.
+ * targets.c (bfd_elf64_alpha_vec): Declare.
+ (bfd_target_vector): Add bfd_elf64_alpha_vec if BFD64.
+ * reloc.c (BFD_RELOC_ALPHA_GPDISP): Define.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD64_BACKENDS): Add elf64-alpha.o.
+ (BFD64_BACKENDS_CFILES): Add elf64-alpha.c.
+
+Thu Jun 20 18:14:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_armap_hash): If hlog is 0, just return 0, rather
+ than relying on a right shift of 32.
+
+Thu Jun 20 11:00:57 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * coffcode.h (coff_set_alignment_hook): Change COFF_IMAGE_WITH_PE
+ ifdef to COFF_WITH_PE.
+ (coff_compute_section_file_positions): Likewise.
+ (coff_write_object_contents): Likewise. Delete COFF_OBJ_WITH_PE.
+ * pe-{arm,i386,ppc}.c (COFF_OBJ_WITH_PE): Delete.
+ * peicode.h (pe_bfd_copy_private_bfd_data): Delete ifdef
+ COFF_IMAGE_WITH_PE, always include.
+
+ * peicode.h (coff_swap_scnhdr_out): ".drectve" doesn't have trailing 0.
+
+Wed Jun 19 11:37:52 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (map_sections_to_segments): Fix up the test for -Ttext to
+ approximate the correct answer if SIZEOF_HEADERS was not used.
+
+ * binary.c (binary_set_section_contents): Set section file
+ position based on LMA rather than VMA.
+
+Wed Jun 19 11:19:25 1996 Manfred Hollstein KS/EIC5 60/3/142 #40283 <manfred@lts.sel.alcatel.de>
+
+ * linker.c (_bfd_generic_link_output_symbols): Don't output any
+ symbols if info->strip == strip_all.
+
+Tue Jun 18 15:17:36 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * coff-h8300.c: Remove #if 0 code.
+ (compatable): Don't allow mixing/matching of different architectures.
+
+ * archures.c (bfd_mach_h8300s): Add.
+ * bfd-in2.h: Rebuilt.
+ * coff-h8300.c (funcvec_hash_newfunc): Handle H8/S too.
+ (BADMAG): Likewise.
+ (h8300_reloc16_estimate): Likewise.
+ (h8300_reloc16_extra_cases): Likewise.
+ (h8300_bfd_link_add_symbols): Likewise.
+ * coffcode.h (coff_set_arch_mach_hook): Likewise.
+ (coff_set_flags): Likewise.
+ * cpu-h8300.c (h8300_scan): Likewise.
+ Add H8/S to bfd_h8300_arch list.
+
+Tue Jun 18 14:42:58 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ Added support for Alpha OpenVMS:
+ * evax.h, evax-alpha.c, evax-egsd.c, evax-emh.c: New files.
+ * evax-etir.c, evax-misc.c, hosts/alphavms.h: New files.
+ * config.h-vms, makefile.vms: New files.
+ * config.bfd (alpha-*-*vms*): New target.
+ * configure.in (evax_alpha_vec): New target vector.
+ * configure: Rebuild.
+ * reloc.c (BFD_RELOC_SWREL32, BFD_RELOC_SWREL64): Define.
+ (BFD_RELOC_ALPHA_LINKAGE, BFD_RELOC_ALPHA_BASEREG): Define.
+ * targets.c (bfd_target_evax_flavour): Define.
+ (evax_alpha_vec): Declare.
+ (bfd_target_vector): Add ecoffalpha_little_vec and evax_alpha_vec
+ if BFD64 is defined.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD64_BACKENDS): Add evax-alpha.o, evax-egsd.o, evax-etir.o,
+ evax-emh.o, and evax-misc.o.
+ (BFD64_BACKENDS_CFILES): Add evax-alpha.c, evax-egsd.c,
+ evax-etir.c, evax-emh.c, and evax-misc.c.
+ (HFILES): Add evax.h.
+
+Tue Jun 18 13:54:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Make name a const
+ pointer.
+ (h8300_bfd_link_add_symbols): Likewise.
+
+Mon Jun 17 10:06:50 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * som.h (R_HPPA_BEGIN_TRY, R_HPPA_END_TRY): Define.
+ * som.c (som_write_fixups): Handle R_BEGIN_TRY and R_END_TRY.
+
+Mon Jun 17 12:49:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_relocate_section): Don't create a reloc
+ for R_MIPS_REL32 and R_MIPS_32 relocs if no dynamic sections were
+ created.
+ (mips_elf_check_relocs): Only create .rel.dyn for R_MIPS_REL32 and
+ R_MIPS_32 relocs if creating a shared library.
+
+Thu Jun 13 20:14:51 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * peicode.h (add_data_entry): Use pei_section_data rather than
+ _cooked_size. Corresponds to May 13 change in coffcode.h.
+
+Thu Jun 13 10:23:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_final_link): Handle long section names.
+ * coffcode.h (coff_write_object_contents): If there are long
+ section names, always set the f_symptr field, even if there are no
+ symbols.
+ * peicode.h (coff_swap_filehdr_in): Don't clear the f_symptr field
+ if there are no symbols.
+
+ * coffgen.c (make_a_section_from_file): Check return value of
+ _bfd_coff_read_string_table.
+ (coff_real_object_p): Check return value of
+ make_a_section_from_file.
+ (_bfd_coff_read_string_table): Check that there are some symbols
+ before trying to read the string table size.
+
+Wed Jun 12 11:16:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): When considering whether
+ to replace a symbol in a dynamic object with a symbol from another
+ dynamic object, do the replacement if the existing symbol is
+ global linkage code.
+
+ * xcofflink.c (_bfd_ppc_xcoff_relocate_section): Check explicitly
+ for _ptrgl, and treat it as global linkage code.
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Notice if we find a
+ filename or N_SO symbol past the offset, and use it to indicate
+ that there is no line number or function when appropriate.
+
+Tue Jun 11 15:24:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_build_ldsyms): Set XCOFF_DEF_REGULAR for a
+ common symbol defined by the linker. Don't export function code
+ even if export_defineds is set.
+
+Mon Jun 10 11:57:27 1996 Jeffrey A Law (law@cygnus.com)
+
+ * coff-h8300.c (howto_table): Add new entries for R_BCC_INV
+ and R_JMP_DEL.
+ (rtype2howto): Handle R_BCC_INV and R_JMP_DEL.
+ (h8300_symbol_address_p): New function.
+ (h8300_reloc16_estimate): Eliminate jumps made unnecessary by
+ relaxing.
+
+Sun Jun 9 16:30:20 1996 Jeffrey A Law (law@cygnus.com)
+
+ * coff-h8300.c (h8300_reloc16_estimate): Fix many minor spacing
+ problems.
+ (h8300_reloc16_estimate, cases R_JMP1, R_JMP2): Adjust "dot"
+ correctly for the two variants. Allow relaxing if the target
+ is 128 bytes away since after relaxation it'll be 126 bytes away.
+ (h8300_reloc16_estimate, case R_PCRWORD): Correctly adjust
+ "dot" and "value". Allow relaxing if the target is 128 bytes
+ away since after relaxation it'll be 126 bytes away.
+ * reloc16.c (bfd_coff_reloc16_relax_section): Keep relaxing
+ the given section until nothing changes.
+
+Thu Jun 6 15:24:45 1996 Richard Henderson <rth@tamu.edu>
+
+ * ecoff.c (_bfd_ecoff_new_section_hook): Remove the _PDATA
+ alignment hack--we can get the lnnoptr info another way without
+ suddenly increasing the alignment requirements. Set the flags for
+ the _PDATA section.
+ (ecoff_compute_section_file_positions): Do so.
+
+Thu Jun 6 11:24:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_write_object_contents): Put a timestamp in the file
+ to keep the HP emulator database happy.
+
+ * config.bfd: Recognize powerpc-*-linux* and powerpcle-*-linux*.
+ From Kevin Buettner <kev@primenet.com>.
+
+Wed Jun 5 15:16:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (translate_to_native_sym_flags): Don't try to print the
+ name of a NULL section.
+
+Tue Jun 4 18:53:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * linker.c (_bfd_generic_link_add_one_symbol): If notice_all is
+ set, always call the notice callback.
+
+ * VERSION: Increment for bfdlink.h change.
+
+Mon Jun 3 11:01:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (COFF_DEFAULT_SECTION_ALIGNMENT_POWER): Set to 4.
+ (sh_relax_delete_bytes): Correct handling of differently sized
+ trailing alignment reloc.
+
+ * bfd-in.h: Use #error if BFD_HOST_64_BIT can not be defined.
+ * bfd-in2.h: Rebuild.
+ * configure.in: Warn if there is no known 64 bit type.
+ * configure: Rebuild.
+
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add ppcboot.o.
+ (BFD32_BACKENDS_CFILES): Add ppcboot.c.
+
+ * elf32-mips.c (mips_elf_size_dynamic_sections): Initialize c.
+ From Per Fogelstrom <per.fogelstrom@mailbox200.swipnet.se>.
+
+Sat Jun 1 21:49:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf64-mips.c (bfd_mips_elf64_swap_reginfo_in)
+ (bfd_mips_elf64_swap_reginfo_out): Move from here...
+ * elf32-mips.c (bfd_mips_elf64_swap_reginfo_in)
+ (bfd_mips_elf64_swap_reginfo_out): ...to here.
+
+Fri May 31 13:51:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf64-mips.c: Improve reloc special_functions and handling of
+ SHT_MIPS_OPTIONS section.
+ * elf32-mips.c (_bfd_mips_elf_hi16_reloc): Rename from
+ mips_elf_hi16_reloc and make globally visible.
+ (_bfd_mips_elf_lo16_reloc): Rename from mips_elf_lo16_reloc and
+ make globally visible.
+ (_bfd_mips_elf_got16_reloc): Rename from mips_elf_got16_reloc and
+ make globally visible.
+ (_bfd_mips_elf_gprel16_reloc): Rename from mips_elf_gprel16_reloc
+ and make globally visible.
+ (gprel16_with_gp): Check howto->src_mask before using value in
+ insn.
+ (_bfd_mips_elf_gprel32_reloc): Rename from mips_elf_gprel32_reloc
+ and make globally visible.
+ (gprel32_with_gp): Check howto->src_mask before fetching value.
+ (bfd_mips_elf_swap_options_in): New function.
+ (bfd_mips_elf_swap_options_out): New function.
+ (_bfd_mips_elf_set_private_flags): Rename from
+ mips_elf_set_private_flags and make globally visible.
+ (_bfd_mips_elf_copy_private_bfd_data): Rename from
+ mips_elf_copy_private_bfd_data and make globally visible.
+ (_bfd_mips_elf_merge_private_bfd_data): Rename from
+ mips_elf_merge_private_bfd_data and make globally visible.
+ (_bfd_mips_elf_section_from_shdr): Accept .MIPS.options as a name
+ for a SHT_MIPS_OPTIONS section.
+ (mips_elf32_section_from_shdr): Handle SHT_MIPS_OPTIONS section.
+ (_bfd_mips_elf_fake_sections): Consider .MIPS.options to be the
+ name of a SHT_MIPS_OPTIONS section.
+ (_bfd_mips_elf_set_section_contents): New function.
+ (mips_elf32_section_processing): Set the GP value in a
+ SHT_MIPS_OPTIONS section.
+ (_bfd_mips_elf_find_nearest_line): Rename from
+ mips_elf_find_nearest_line and make globally visible.
+ (bfd_elf32_set_section_contents): Define.
+ * elf-bfd.h (_bfd_mips_elf_hi16_reloc): Declare.
+ (_bfd_mips_elf_lo16_reloc): Declare.
+ (_bfd_mips_elf_gprel16_reloc): Declare.
+ (_bfd_mips_elf_got16_reloc): Declare.
+ (_bfd_mips_elf_gprel32_reloc): Declare.
+ (_bfd_mips_elf_set_private_flags): Declare.
+ (_bfd_mips_elf_copy_private_bfd_data): Declare.
+ (_bfd_mips_elf_merge_private_bfd_data): Declare.
+ (_bfd_mips_elf_find_nearest_line): Declare.
+ (_bfd_mips_elf_set_section_contents): Declare.
+
+ * elf32-hppa.c (elf32_hppa_info_to_howto): Rename from
+ elf_info_to_howto.
+ (elf_info_to_howto): Define.
+ * elf32-sparc.c (elf32_sparc_info_to_howto): Rename from
+ elf_info_to_howto.
+ (elf_info_to_howto): Define.
+ * elf64-sparc.c (sparc64_elf_info_to_howto): Rename from
+ elf_info_to_howto.
+ (elf_info_to_howto): Define.
+
+ * coff-w65.c (h8300_reloc16_estimate): Rename R_MOVB[12] to
+ R_MOV16B[12], to match change in coff/internal.h.
+
+Thu May 30 12:38:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf64-mips.c: Extensive additions to provide better support for
+ writing files and for gas.
+ * elf32-mips.c (_bfd_mips_elf_object_p): New function, broken out
+ of mips_elf_object_p.
+ (mips_elf32_object_p): Rename from mips_elf_object_p; call
+ _bfd_mips_elf_object_p.
+ (_bfd_mips_elf_final_write_processing): Rename from
+ mips_elf_final_write_processing and make globally visible.
+ (_bfd_mips_elf_fake_sections): Rename from
+ mips_elf_fake_sections and make globally visible.
+ (_bfd_mips_elf_section_from_bfd_section): Rename from
+ mips_elf_section_from_bfd_section and make globally visible.
+ (_bfd_mips_elf_section_processing): New function, broken out of
+ mips_elf_section_processing.
+ (mips_elf32_section_processing): Rename from
+ mips_elf_section_processing; call
+ _bfd_mips_elf_section_processing.
+ (_bfd_mips_elf_symbol_processing): Rename from
+ mips_elf_symbol_processing and make globally visible.
+ (_bfd_mips_elf_read_ecoff_info): Rename from
+ mips_elf_read_ecoff_info and make globally visible.
+ (mips_elf32_ecoff_debug_swap): Rename from
+ mips_elf_ecoff_debug_swap.
+ * elf.c (_bfd_elf_symbol_from_bfd_symbol): Use asymbol rather than
+ struct symbol_cache_entry.
+ (_bfd_elf_validate_reloc): New function, moved in from
+ elfcode.h:validate_reloc.
+ * elfcode.h (validate_reloc): Remove; moved into elf.c and renamed
+ to _bfd_elf_validate_reloc. Change all callers.
+ * elf-bfd.h (bfd_section_from_shdr): Declare.
+ (_bfd_elf_symbol_from_bfd_symbol): Declare.
+ (_bfd_elf_validate_reloc): Declare.
+ (_bfd_mips_elf_object_p): Declare.
+ (_bfd_mips_elf_fake_sections): Declare.
+ (_bfd_mips_elf_section_from_bfd_section): Declare.
+ (_bfd_mips_elf_section_processing): Declare.
+ (_bfd_mips_elf_symbol_processing): Declare.
+ (_bfd_mips_elf_read_ecoff_info): Declare.
+ (_bfd_mips_elf_final_write_processing): Declare.
+ * elfxx-target.h (bfd_elfNN_get_reloc_upper_bound): Don't define
+ if already defined.
+
+ * elf32-mips.c (mips_elf_object_p): Handle E_MIPS_ARCH_4.
+ (mips_elf_final_write_processing): Likewise.
+
+Wed May 29 16:15:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ 64-bit MIPS ELF ABI objdump support:
+ * elf64-mips.c: New file.
+ * Makefile.in: Rebuild dependencies.
+ (BFD64_BACKENDS): Add elf64-mips.o.
+ (BFD64_BACKENDS_CFILES): Add elf64-mips.c.
+ * config.bfd (mips*el-*-elf*) Add bfd_elf64_bigmips_vec and
+ bfd_elf64_littlemips_vec to targ_selvecs.
+ (mips*-*-elf*): Likewise.
+ * confingure.in: Add bfd_elf64_bigmips_vec and
+ bfd_elf64_littlemips_vec to vector switch.
+ * configure: Rebuild.
+ * elf32-mips.c (_bfd_mips_elf_section_from_shdr): New function,
+ broken out of mips_elf_section_from_shdr.
+ (mips_elf32_section_from_shdr): Rename from
+ mips_elf_section_from_shdr. Call new function.
+ (elf_backend_section_from_shdr): Update name of renamed function.
+ * elf-bfd.h (struct elf_size_info): Change second parameter of
+ write_out_phdrs to be const. Likewise for second parameter of
+ swap_symbol_out.
+ (struct bfd_elf_section_data): Add rel_hdr2 field.
+ (bfd_elf32_swap_symbol_in): Change second parameter to be const.
+ (bfd_elf32_swap_symbol_out): Likewise.
+ (bfd_elf32_swap_reloc_in): Likewise.
+ (bfd_elf32_swap_reloc_out): Likewise.
+ (bfd_elf32_swap_reloca_in): Likewise.
+ (bfd_elf32_swap_reloca_out): Likewise.
+ (bfd_elf32_swap_phdr_in): Likewise.
+ (bfd_elf32_swap_phdr_out): Likewise.
+ (bfd_elf32_swap_dyn_in): Likewise.
+ (bfd_elf32_swap_dyn_out): Likewise.
+ (bfd_elf32_slurp_symbol_table): Declare.
+ (bfd_elf32_write_shdrs_and_ehdr): Declare.
+ (bfd_elf32_write_out_phdrs): Declare.
+ (bfd_elf64_swap_symbol_in): Change second parameter to be const.
+ (bfd_elf64_swap_symbol_out): Likewise.
+ (bfd_elf64_swap_reloc_in): Likewise.
+ (bfd_elf64_swap_reloc_out): Likewise.
+ (bfd_elf64_swap_reloca_in): Likewise.
+ (bfd_elf64_swap_reloca_out): Likewise.
+ (bfd_elf64_swap_phdr_in): Likewise.
+ (bfd_elf64_swap_phdr_out): Likewise.
+ (bfd_elf64_swap_dyn_in): Likewise.
+ (bfd_elf64_swap_dyn_out): Likewise.
+ (bfd_elf64_slurp_symbol_table): Declare.
+ (bfd_elf64_write_shdrs_and_ehdr): Declare.
+ (bfd_elf64_write_out_phdrs): Declare.
+ (_bfd_mips_elf_section_from_shdr): Declare.
+ * elf.c (bfd_section_from_shdr): Remove assertion requiring
+ SHT_REL/SHT_RELA to match use_rela_p. If there is already a reloc
+ section for the section, add the new one to rel_hdr2. Increment
+ reloc_count rather than setting it.
+ * elfcode.h (elf_slurp_symbol_table): Define name as macro.
+ Remove static declaration.
+ (elf_write_shdrs_and_ehdr): Define name as macro.
+ (elf_write_out_phdrs): Likewise.
+ (elf_swap_ehdr_in, elf_swap_ehdr_out): Declare.
+ (elf_swap_shdr_in, elf_swap_shdr_out): Declare.
+ (elf_swap_symbol_in): Change second parameter to be const.
+ (elf_swap_symbol_out): Likewise.
+ (elf_swap_ehdr_in, elf_swap_ehdr_out): Likewise.
+ (elf_swap_shdr_in, elf_swap_shdr_out): Likewise.
+ (elf_swap_phdr_in, elf_swap_phdr_out): Likewise.
+ (elf_swap_reloc_in, elf_swap_reloc_out): Likewise.
+ (elf_swap_reloca_in, elf_swap_reloca_out): Likewise.
+ (elf_write_out_phdrs): Rename from write_out_phdrs. Change second
+ parameter to be const. Make non-static.
+ (elf_write_shdrs_and_ehdr): Rename from write_shdrs_and_ehdr.
+ Make non-static.
+ (elf_slurp_symbol_table): Make non-static.
+ (NAME(_bfd_elf,size_info)): Update names of renamed functions.
+ * elfxx-target.h (elf_info_to_howto): Define if not defined.
+ (elf_backend_size_info): Likewise.
+ (elfNN_bed): Use elf_backend_size_info.
+ * targets.c (bfd_elf64_bigmips_vec): Declare.
+ (bfd_elf64_littlemips_vec): Declare.
+ (bfd_target_vector): Add bfd_elf64_bigmips_vec and
+ bfd_elf64_littlemips_vec if BFD64 is defined.
+
+ * libbfd.c (bfd_get_file_window): Add cast to fprintf argument.
+
+Tue May 28 11:42:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (sh_relax_delete_bytes): Insert nop instructions, not
+ zeroes, in alignment holes.
+
+ * configure: Rebuild with autoconf 2.10.
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Make room for the
+ potential leading underscore in the allocated buffer.
+
+Fri May 24 14:28:38 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Do not put small common
+ symbols into .sbss if this is a relocatable link.
+
+Thu May 23 12:26:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (_bfd_ppc_xcoff_relocate_section): Warn about
+ undefined symbols when creating a shared library.
+
+Fri May 17 13:54:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c: Add a bunch of new code and static const arrays to
+ support aligning loads and stores on four byte memory boundaries.
+ Also:
+ (sh_coff_howtos): Add entries for R_SH_CODE, R_SH_DATA and
+ R_SH_LABEL.
+ (sh_relax_section): Look for R_SH_CODE relocs. If we find one,
+ call sh_align_loads.
+ (sh_relax_delete_bytes): Don't mark R_SH_CODE or R_SH_DATA relocs
+ as unused.
+
+Thu May 16 16:34:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cache.c (bfd_open_file): Unlink the file before opening it for
+ write. From Marty Leisner <leisner@sdsp.mc.xerox.com>.
+
+ * opncls.c (bfd_fdopenr): Set opened_once.
+
+Tue May 14 12:35:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * som.c (som_slurp_reloc_table): Clear external_relocs cache after
+ freeing it.
+
+ * libbfd.c: Remove #ifdef FILE_OFFSET_IS_CHAR_INDEX, and compile
+ the code unconditionally.
+
+Mon May 13 19:51:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libcoff-in.h (struct pei_section_tdata): Define structure.
+ (pei_section_data): Define macro.
+ * libcoff.h: Rebuild.
+ * coffcode.h (coff_set_alignment_hook): If COFF_IMAGE_WITH_PE,
+ store s_paddr field in pei_section_data.
+ (coff_compute_section_file_positions): Use pei_section_data rather
+ than _cooked_size, and don't overwrite an existing value.
+ (coff_write_object_contents): If COFF_OBJ_WITH_PE, set s_paddr to
+ 0. If COFF_IMAGE_WITH_PE, set s_paddr to pei_section_data.
+ * peicode.h (coff_bfd_copy_private_section_data): Define if
+ COFF_IMAGE_WITH_PE.
+ (pe_bfd_copy_private_section_data): New static function if
+ COFF_IMAGE_WITH_PE.
+
+Wed May 8 16:10:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * srec.c (srec_set_arch_mach): Write as a function rather than a
+ macro definition.
+
+ * xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): If an archive has
+ no map, just check each member in turn to see whether it is
+ required.
+
+Wed May 8 09:17:34 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppcboot.c (ppcboot_object_p): Check for type 0x41 in partition
+ table. Call BFD_ASSERT to validate header size, instead of
+ calling fatal.
+ (ppcboot_bfd_print_private_bfd_data): Put quotes around partition
+ name.
+
+Tue May 7 16:10:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppcboot.c: New target for looking at PPCbug boot records.
+
+ * config{ure.in,.bfd}: Add support for ppcboot target.
+ * targets.c: Ditto.
+ * configure: Regenerate.
+
+Tue May 7 11:15:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * coff-h8300.c (howto_table): Update names to match recent
+ changes to include/coff/internal.h. Fix minor errors in the
+ existing relocs. Add R_MOVL1 and R_MOVL2.
+ (rtype2howto): Similarly.
+ (h8300_reloc16_estimate): Rewrite to simplify, fix bugs in the
+ existing relaxing code and peform more relaxing.
+ (h8300_reloc16_extra_cases): Likewise.
+
+Mon May 6 18:24:09 1996 Jeffrey A Law (law@cygnus.com)
+
+ * reloc16.c (bfd_coff_reloc16_get_value): Handle common
+ symbols correctly.
+
+Sat May 4 05:08:45 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * elfcode.h (elf_object_p): Reject generic ELF target if
+ e_machine matches an alternate machine code in a specific backend.
+
+ * netbsd-core.c (netbsd_core_vec): Remove initializer for
+ obsolete align_power_min field.
+
+Fri May 3 13:07:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * coff-h8300.c (reloc_howto_type): Add howto entry for
+ R_PCRWORD_B.
+ (rtype2howto): Handle R_PCRWORD_B.
+ (h8300_reloc16_extra_cases): Handle R_PCRWORD_B.
+ (h8300_reloc_16_estimate): Likewise. Try to turn a 16bit
+ pc-relative branch (R_PCRWORD) into an 8bit pc-relative
+ branch (R_PCWORD_B).
+
+Fri May 3 10:47:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (translate_from_native_sym_flags): Set the section for
+ BSF_CONSTRUCTOR symbols.
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Correct setting of
+ last_bf_index.
+
+Wed May 1 18:39:32 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): In comdat section lookup,
+ stop looking when section is found.
+
+Wed May 1 14:17:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (STRING_SIZE_SIZE): Define.
+ (styp_to_sec_flags): Handle long symbol names when looking for the
+ section symbol.
+ (bfd_coff_backend_data): Add _bfd_coff_long_section_names field.
+ (bfd_coff_long_section_names): Define.
+ (coff_write_object_contents): Handle long section names.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * libcoff.h: Rebuild.
+ * coffgen.c (make_a_section_from_file): Handle long section
+ names.
+ (coff_write_symbols): Handle long section names.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize new field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+ * pe-arm.c (COFF_LONG_SECTION_NAMES): Define.
+ * pei-arm.c (COFF_LONG_SECTION_NAMES): Define.
+ * pe-i386.c (COFF_LONG_SECTION_NAMES): Define.
+ * pei-i386.c (COFF_LONG_SECTION_NAMES): Define.
+ * pe-ppc.c (COFF_LONG_SECTION_NAMES): Define.
+ * pei-ppc.c (COFF_LONG_SECTION_NAMES): Define.
+
+ * bout.c (b_out_callback): Set lma of sections.
+ (b_out_bfd_get_relocated_section_contents): Rename in_abfd
+ parameter to output_bfd. Used input_bfd instead of output_bfd in
+ several places.
+
+Tue Apr 30 17:56:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (translate_from_native_sym_flags): Don't create
+ SEC_CONSTRUCTOR sections.
+ * ecoff.c (ecoff_set_symbol_info): Likewise.
+
+ * elf32-mips.c (mips_elf_copy_private_bfd_data): Copy elf_gp.
+ From Don Bowman <bowman@waterloo.hp.com>.
+
+Tue Apr 30 17:06:32 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * coff-arm.c (armcoff_little_vec): If COFF_WITH_PE is defined, add
+ SEC_LINK_ONCE and SEC_LINK_DUPLICATES to section_flags.
+
+Mon Apr 29 13:15:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (struct mips_elf_link_hash_entry): Add
+ mips_32_relocs field.
+ (mips_elf_link_hash_newfunc): Initialize mips_32_relocs field.
+ (mips_elf_relocate_section): Copy R_MIPS_REL32 and R_MIPS_32
+ relocs against a global symbol which is not defined in a regular
+ file.
+ (mips_elf_check_relocs): For a R_MIPS_REL32 or R_MIPS_32 reloc
+ against a global symbol, increment mips_32_relocs.
+ (mips_elf_adjust_dynamic_symbol): If mips_32_relocs is set, and
+ the symbol is not defined in a regular file, make room in the
+ .rel.dyn section.
+
+Fri Apr 26 18:00:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_compute_section_file_positions): Track the real
+ file position and the virtual file position separately. Set
+ filepos information bsaed on the real file position.
+ (_bfd_ecoff_set_section_contents): Handle .lib sections like the
+ Jan 23 change to coffcode.h.
+
+ * som.c (som_slurp_symbol_table): Set the symbol count to the
+ number of BFD symbols created.
+
+Fri Apr 26 12:34:29 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Forward relocations to the
+ output file if linking shared objects. Loop to check all relocs,
+ rather than returning false on first error.
+
+Thu Apr 25 13:25:12 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_create_linker_section): Add PLT case.
+ (ppc_elf_additional_program_headers): If .interp section, bump #
+ of program headers by 1.
+ (ppc_elf_adjust_dynamic_symbol): Flesh out support.
+ (ppc_elf_size_dynamic_sections): Add support for .plt section.
+ (ppc_elf_check_relocs): Print out filename in debug code. Enable
+ PLT support.
+ (ppc_elf_finish_dynamic_symbol): Add support for PLT's, beef up
+ debug output.
+ (ppc_elf_relocate_section): If the output section isn't defined,
+ don't abort, just give an error message.
+
+ * elflink.c (_bfd_elf_create_dynamic_sections): If the section
+ being created is .sdata or .sdata2, don't make the symbol dynamic.
+
+Wed Apr 24 14:04:07 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): Look through the
+ members of an archive for dynamic objects with no symbols, and
+ pass them directly to check_archive_element.
+ (xcoff_link_check_ar_symbols): Pass dynamic objects to
+ xcoff_link_check_dynamic_ar_symbols.
+ (xcoff_link_check_dynamic_ar_symbols): New static function.
+
+ * coff-rs6000.c (rs6000coff_vec): Change BFD_JUMP_TABLE_DYNAMIC
+ from _bfd_nodynamic to _bfd_xcoff.
+ * libcoff-in.h (_bfd_xcoff_get_dynamic_symtab_upper_bound):
+ Declare.
+ (_bfd_xcoff_canonicalize_dynamic_symtab): Declare.
+ (_bfd_xcoff_get_dynamic_reloc_upper_bound): Declare.
+ (_bfd_xcoff_canonicalize_dynamic_reloc): Declare.
+ * libcoff.h: Rebuild.
+ * xcofflink.c (xcoff_swap_ldrel_in): New static function.
+ (xcoff_get_section_contents): New static function.
+ (_bfd_xcoff_get_dynamic_symtab_upper_bound): New function.
+ (_bfd_xcoff_canonicalize_dynamic_symtab): New function.
+ (_bfd_xcoff_get_dynamic_reloc_upper_bound): New function.
+ (xcoff_dynamic_reloc): New static variable.
+ (_bfd_xcoff_canonicalize_dynamic_reloc): New function.
+ (xcoff_link_add_dynamic_symbols): Use xcoff_get_section_contents.
+
+Tue Apr 23 12:48:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sparc.c (bfd_coff_generic_reloc): Return bfd_reloc_ok even
+ if reloc_entry->addend is not 0.
+ (CALC_ADDEND): Just set the addend to reloc.r_offset.
+
+Mon Apr 22 18:29:01 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): Fix spelling of
+ R_SPARC_GLOB_JMP.
+ * elf64-sparc.c (sparc64_elf_howto_table): Likewise.
+ Add entries for R_SPARC_[56].
+ (sparc_reloc_map): Add entries for R_SPARC_[56].
+
+Mon Apr 22 15:07:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Optimize linking of stabs in sections as used in ELF and COFF.
+ * stabs.c: New file.
+ * libbfd-in.h (_bfd_link_section_stabs): Declare.
+ (_bfd_write_section_stabs): Declare.
+ (_bfd_write_stab_strings): Declare.
+ * libbfd.h: Rebuild.
+ * libcoff-in.h (struct coff_section_tdata): Add stab_info field.
+ (struct coff_link_hash_table): Add stab_info field.
+ * libcoff.h: Rebuild.
+ * cofflink.c (_bfd_coff_link_hash_table_init): Initialize
+ stab_info field.
+ (coff_link_add_symbols): Call _bfd_link_section_stabs if
+ appropriate.
+ (_bfd_coff_final_link): Write out stab strings hash table.
+ (_bfd_coff_link_input_bfd): Handle optimized stabs sections.
+ * coff-ppc.c (ppc_bfd_coff_final_link): Write out stab strings
+ hash table.
+ * elf-bfd.h (struct elf_link_hash_table): Add stab_info field.
+ (struct bfd_elf_section_data): Add stab_info field.
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize stab_info
+ field.
+ * elflink.h (elf_link_add_object_symbols): If appropriate, call
+ _bfd_link_section_stabs.
+ (elf_bfd_final_link): Write out stab strings hash table.
+ (elf_link_input_bfd): Handle optimized stabs sections.
+ * reloc.c (_bfd_final_link_relocate): Check address against
+ _raw_size rather than _cooked_size.
+ * Makefile.in: Rebuild dependencies.
+ (BFD_LIBS): Add stabs.o
+ (BFD_LIBS_CFILES): Add stabs.c.
+
+ * VERSION: Increment for bfdlink.h change.
+
+ * coffgen.c (coff_renumber_symbols): Correct handling of
+ BSF_NOT_AT_END common symbols.
+
+Fri Apr 19 19:21:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-ppc.c (record_toc): Add cast to avoid warning.
+ (ppc_allocate_toc_section): Likewise.
+ (coff_ppc_relocate_section): Remove ANSI C string concatenation.
+ (ppc_coff_reloc_type_lookup): Remove unreached code.
+ * coffcode.h (coff_write_object_contents): Don't take the address
+ of an array.
+ * peicode.h (pe_print_idata): Add casts to avoid warning.
+ (pe_print_edata): Likewise.
+ (pe_print_reloc): Remove ANSI C string concatenation.
+
+Thu Apr 18 18:51:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libcoff-in.h (struct coff_final_link_info): Add last_bf_index
+ and last_bf fields.
+ * libcoff.h: Rebuild.
+ * coffswap.h (coff_swap_aux_in): Swap endndx field for C_FCN
+ symbols.
+ (coff_swap_aux_out): Likewise.
+ * peicode.h (coff_swap_aux_in): Likewise.
+ (coff_swap_aux_out): Likewise.
+ * coffgen.c (coff_pointerize_aux): Check endndx field for C_FCN
+ symbols.
+ * cofflink.c (_bfd_coff_final_link): Initialize last_bf_index
+ field.
+ (_bfd_coff_link_input_bfd): Check endndx field for C_FCN symbols.
+ Fix up .bf endndx link fields.
+ * coff-ppc.c (ppc_bfd_coff_final_link): Initialize last_bf_index
+ field.
+ * xcofflink.c (xcoff_link_input_bfd): Check endndx field for C_FCN
+ symbols.
+
+Wed Apr 17 12:08:24 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * pe{,i}-ppc.c (PPC_PE): Define instead of PPC, so that compiling
+ on Solaris PowerPC systems doesn't get confused.
+
+ * ccffcode.h (coff_write_object_contents): Use #ifdef PPC_PE, not
+ #ifdef PPC.
+
+ * elfcore.h (bfd_prstatus, bfd_fpregset): Add thread argument.
+ (elf_corefile_note): If HAVE_SYS_PROCFS_H is not defined, don't
+ update did_reg and did_reg2.
+
+Wed Apr 17 13:07:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_input_bfd): Check for TOC overflow.
+
+ * linker.c (_bfd_generic_link_add_one_symbol): When calling the
+ callback routines, pass h->root.string rather than name, in case
+ copy is true and name is transient.
+
+Tue Apr 16 16:36:38 1996 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * elfcore.h: Add support for core files with multiple threads.
+ (Primarily for Solaris.)
+
+Tue Apr 16 13:44:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (NAME(aout,squirt_out_relocs)): Don't do anything if
+ section->orelocation is NULL.
+
+ * coffgen.c (bfd_coff_get_syment): New function.
+ (bfd_coff_get_auxent): New function.
+ * bfd-in.h (bfd_coff_get_syment): Declare.
+ (bfd_coff_get_auxent): Declare.
+ * bfd-in2.h: Rebuild.
+
+Mon Apr 15 19:06:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (struct mips_hi16): Define.
+ (mips_hi16_addr, mips_hi16_addend): Remove.
+ (mips_hi16_list): New static variable.
+ (mips_elf_hi16_reloc): Maintain a list of unmatched HI16 relocs.
+ (mips_elf_lo16_reloc): Process mips_hi16_list.
+ (mips_elf_relocate_section): Permit an arbitrary number of HI16
+ relocs before the associated LO16 reloc.
+
+Wed Apr 10 00:23:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * versados.c (versados_scan): Check bfd_alloc return value.
+ (versados_object_p): Check all bfd_read return values. Require
+ that lang field be less than 10, to avoid confusion with Intel Hex
+ files.
+
+ * libaout.h (WRITE_HEADERS): Write out the relocs even if there
+ aren't any symbols.
+ * aoutx.h (NAME(aout,swap_std_reloc_out)): Set r_index to N_ABS,
+ not 0, for an absolute symbol.
+ (NAME(aout,swap_ext_reloc_out)): Likewise.
+
+ * ihex.c (ihex_scan): Accept a length of 4 for record type 5.
+ (ihex_write_object_contents): For a large start address, output
+ the full 32 bit address in record type 5.
+
+ * ieee.c (ieee_write_byte): Change second parameter from bfd_byte
+ to int to avoid promotion problems in prototype.
+
+Tue Apr 9 11:44:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Use ${srcdir} when looking for picfrag.
+
+ * configure.host: Switch on ${libdir}, not $(libdir). From
+ alan@spri.levels.unisa.edu.au (Alan Modra).
+
+ * aoutx.h (aout_link_add_symbols): Always call add_dynamic_symbols
+ entry point, not just for DYNAMIC objects.
+ * sunos.c (sunos_add_dynamic_symbols): Always call
+ sunos_create_dynamic_sections. If called with a non DYNAMIC
+ object, don't do anything else.
+ (sunos_add_one_symbol): Don't call sunos_create_dynamic_sections.
+
+Mon Apr 8 12:09:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+ * configure: Rebuild.
+
+ * configure.host: Set HLDFLAGS and SHLIB_CFLAGS for *-dec-osf*
+ host when configuring with --enable-shard.
+
+Fri Apr 5 12:24:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.bfd: Add i[345]86-*-freebsdelf* target; from John Polstra
+ <jdp@polstra.com>.
+
+ * linker.c (link_action): For WARN_ROW/warn, use MWARN, not CYCLE,
+ to avoid crashing in bfd_hash_replace.
+
+ * sysdep.h: Use #ifdef, not #if.
+
+Thu Apr 4 23:32:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.in: Rebuild.
+
+Thu Apr 4 18:49:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (mips-sony-bsd*): Fix typo in AC_DEFINE.
+ (AC_CHECK_HEADERS): Check for sys/time.h
+ (AC_HEADER_TIME): Add macro.
+ * configure: Rebuild.
+ * sysdep.h: Use TIME_WITH_SYS_TIME and HAVE_SYS_TIME_H
+ to control what combination of <time> and <sys/time.h>
+ get included.
+
+Tue Apr 2 13:11:53 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * aoutf1.h (sunos_32_set_arch_mach): Handle M_SPARCLET.
+ (aout_32_sunos4_write_object_contents): Likewise.
+ * aoutx.h (NAME(aout,machine_type)): Handle
+ bfd_mach_sparc_{sparclet,sparclite}.
+ * archures.c (bfd_mach_sparc_{sparclet,sparclite}): Define.
+ (bfd_mach_sparc_v9_p): Update.
+ * cpu-sparc.c (arch_info_struct): Add entries for sparclet,sparclite.
+ * libaout.h (enum machine_type): Add M_SPARCLET.
+ * sunos.c (MACHTYPE_OK): Define.
+ * bfd-in2.h: Regenerated.
+
+Tue Apr 2 00:33:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf-bfd.h (struct elf_link_hash_table): Add hgot field.
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize hgot field.
+ * elflink.c (_bfd_elf_create_got_section): Store the
+ _GLOBAL_OFFSET_TABLE_ hash table entry in the hgot field.
+ * elf32-sparc.c (elf32_sparc_check_relocs): If the size of the
+ global offset table goes over 0x1000, set the value of
+ _GLOBAL_OFFSET_TABLE_ to 0x1000 into the section.
+ (elf32_sparc_relocate_section): Subtract the offset of
+ _GLOBAL_OFFSET_TABLE_ when handling GOT relocations.
+
+ * elfcode.h: Don't include <string.h>.
+
+Mon Apr 1 10:39:24 1996 Jeffrey A Law (law@cygnus.com)
+
+ * linker.c (_bfd_generic_link_hash_newfunc): Renamed from
+ generic_link_hash_newfunc. All references changed.
+ * genlink.h (_bfd_generic_link_hash_newfunc): Declaration
+ moved here from libbfd-in.h.
+ * libbfd-in.h: Corresponding changes.
+ * libbfd.h: Regenerated.
+
+Mon Apr 1 12:35:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (aout_link_input_section_std): When reporting an
+ overflow error, use the name of the symbol in the hash table if
+ available.
+ (aout_link_input_section_ext): Likewise.
+
+ * elflink.h (elf_adjust_dynamic_symbol): If a common symbol got
+ defined in a regular file, set ELF_LINK_HASH_DEF_REGULAR.
+
+Sun Mar 31 01:58:41 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * peicode.h (coff_swap_aouthdr_out): Delete test for .junk.
+ * coffcode.h (coff_compute_section_file_positions): Likewise.
+ (coff_write_object_contents): Likewise.
+
+Fri Mar 29 12:44:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * section.c (SEC_LINK_ONCE): Define.
+ (SEC_LINK_DUPLICATES): Define.
+ (SEC_LINK_DUPLICATES_DISCARD): Define.
+ (SEC_LINK_DUPLICATES_ONE_ONLY): Define.
+ (SEC_LINK_DUPLICATES_SAME_SIZE): Define.
+ (SEC_LINK_DUPLICATES_SAME_CONTENTS): Define.
+ * bfd-in2.h: Rebuild.
+ * coffcode.h (sec_to_styp_flags): If COFF_WITH_PE, turn
+ SEC_LINK_ONCE into IMAGE_SCN_LNK_COMDAT.
+ (styp_to_sec_flags): If COFF_WITH_PE, turn IMAGE_SCN_LNK_REMOVE
+ into SEC_EXCLUDE. If IMAGE_SCN_LNK_COMDAT is set, set
+ SEC_LINK_ONCE, and look through the symbol table for the setting
+ for SEC_LINK_DUPLICATES.
+ (coff_write_object_contents): If COFF_WITH_PE, if SEC_LINK_ONCE is
+ set for a section, find the section symbol in the symbol table,
+ and set the aux entry based on SEC_LINK_DUPLICATES.
+ * coffgen.c (coff_print_symbol): Add a space before "checksum".
+ * coff-arm.c (armcoff_big_vec): If COFF_WITH_PE is defined, add
+ SEC_LINK_ONCE and SEC_LINK_DUPLICATES to section_flags.
+ * coff-i386.c (i386coff_vec): Likewise.
+ * coff-ppc.c (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Likewise.
+
+ * VERSION: Bump to 2.6.1.
+ * Makefile.in (stamp-h): Depend upon VERSION.
+
+Thu Mar 28 23:48:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * libbfd-in.h (generic_link_hash_newfunc): Add declaration.
+ * libbfd.h: Rebuilt.
+ * linker.c (generic_link_hash_newfunc): No longer static.
+ * coffcode.h (coff_bfd_link_hash_create): Allow specific targets
+ to override.
+ * coff-h8300.c: Add two derived hash tables and their associated
+ funtions and #defines for use by the h8300 linker.
+ (h8300_reloc16_extra_cases, case R_MEM_INDIRECT): Create entries in
+ the function vector as needed. Place the address of the function
+ vector entry in the location specified by the R_MEM_INDIRECT reloc.
+ Rewrite the vectors section contents as necessary.
+ (h8300_bfd_link_add_symbols): New function for the h8300 linker.
+ (coff_bfd_link_add_symbols): Define to use h8300 specific version.
+ (coff_bfd_link_hash_table_create): Likewise.
+
+Thu Mar 28 17:44:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libhppa.h: If gcc 2.7 or higher, declare all the functions with
+ __attribute__ ((__unused__)) so that -Wall doesn't warn about
+ them.
+ (hppa_rebuild_insn): Pass pointer to correct type to
+ low_sign_unext and dis_assemble_21.
+
+Thu Mar 28 11:00:36 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config.bfd (sparc64-{sysv4*,solaris2*}): Delete.
+ Stick with sparc-*-{sysv4*,solaris2*}.
+
+Wed Mar 27 10:43:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * peicode.h (coff_swap_aux_in): Swap in extra PE x_scn fields.
+ (coff_swap_aux_out): Swap out extra PE x_scn fields.
+ * coffswap.h (coff_swap_aux_in): Zero out extra PE x_scn fields.
+ * coffgen.c (coff_print_symbol): If any of the extra PE x_scn
+ fields is non-zero, print them.
+
+ * coff-ppc.c (ppc_record_toc_entry): Put inside COFF_IMAGE_WITH_PE
+ ifdef. Remove unused variables.
+ (ppc_record_data_in_toc_entry): Ifdef out. Removed unused
+ variables.
+ (ppc_mark_symbol_as_glue): Put inside COFF_IMAGE_WITH_PE ifdef.
+ (get_symbol_value): Ifdef out.
+ (pe_ppc_reloc): Ifdef out. Remove unused variables.
+ (coff_ppc_relocate_section): Remove unused variables. Make
+ fprintf strings and argument types correspond. Put before_addr in
+ DEBUG_RELOC ifdef.
+ (dump_toc): Make fprintf strings and argument types correspond.
+ (ppc_process_before_allocation): Remove unused variables. Always
+ return a value.
+ (ppc_reflo_reloc): Ifdef out.
+ (ppc_addr32nb_reloc): Ifdef out.
+ (ppc_coff_rtype2howto): Make fprintf strings and argument types
+ correspond.
+ (coff_ppc_rtype_to_howto): Likewise.
+ (ppc_coff_swap_sym_in_hook): Remove unused variables.
+
+ * peicode.h (pe_print_idata): Move otherwise unused variables into
+ the #ifdef where they are used. Always return a value.
+ (pe_print_edata): Make fprintf strings and argument types
+ correspond. Always return a value.
+ (pe_print_pdata): Removed unused variable addr_value. Always
+ return a value.
+ (pe_print_reloc): Remove unused variable onaline. Make fprintf
+ strings and argument types correspond. Always return a value.
+
+ * elf32-ppc.c (ppc_elf_fake_sections): Return true.
+ (ppc_elf_finish_dynamic_symbol): Move definition of unused
+ variable rela inside #if 0 section where it is used.
+
+ * ns32k.h: New file.
+ * cpu-ns32k.h: Include ns32k.h. Rename externally visible
+ functions to start with _bfd_.
+ * aout-ns32k.c: Include ns32k.h. Change references to renamed
+ functions in cpu-ns32k.h.
+ * Makefile.in: Rebuild dependencies.
+ (HFILES): Add ns32k.h.
+
+ * section.c (struct sec): Add linker_mark field. Change
+ user_set_vma and reloc_done to be single bit fields.
+ (STD_SECTION): Update accordingly.
+ * bfd-in2.h: Rebuild.
+ * aoutx.h (NAME(aout,final_link)): Mark sections included in the
+ link.
+ (aout_link_input_bfd): Don't link unmarked sections.
+ * cofflink.c (_bfd_coff_final_link): Mark sections included in the
+ link.
+ (_bfd_coff_link_input_bfd): Don't link unmarked sections.
+ * coff-ppc.c (ppc_bfd_coff_final_link): Mark sections included in
+ the link.
+ * elflink.h (elf_bfd_final_link): Mark sections included in the
+ link.
+ (elf_link_input_bfd): Don't link unmarked sections.
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Mark sections included
+ in the link.
+ (xcoff_link_input_bfd): Don't link unmarked sections.
+
+ * coffswap.h (coff_swap_scnhdr_out): Include section name in
+ overflow error messages.
+
+Tue Mar 26 15:46:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd.c (_bfd_default_error_handler): If _bfd_error_program_name
+ is not set, print "BFD: " before the error message.
+
+ * configure.in: Use AC_CHECK_TOOL to find ar and ranlib. From
+ Miles Bader <miles@gnu.ai.mit.edu>.
+ * configure: Rebuild.
+
+Fri Mar 22 12:17:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_input_bfd): Fix scan for C_BINCL/C_EINCL
+ symbols.
+
+ * config.bfd: Add ieee_vec to targ_selvecs for i960 targets and
+ m68k-aout, m68k-coff, and m68k-elf targets.
+
+Fri Mar 22 11:33:44 1996 Martin Anantharaman <martin@goofy.imech.uni-duisburg.de>
+
+ * ieee.c: Changed #ifdef KEEPMINUSPCININST to #if KEEPMINUSPCININST.
+ (ieee_generic_stat_arch_elt): Restructured to prevent
+ ieee_object_p from being called repeatedly.
+
+Thu Mar 21 11:00:47 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): Allocate
+ buffers large enough for any FILEHDR or AOUTHDR.
+
+Thu Mar 21 16:28:17 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * ecofflink.c (lookup_line): New static function, renamed and
+ slighly changed from old _bfd_ecoff_locate_line.
+ (_bfd_ecoff_locate_line): Cache line number information. Use
+ lookup_line for actual lookup.
+
+Thu Mar 21 14:59:11 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * peicode.h (pe_print_pdata): Warn if the .pdata section is not a
+ multiple of 20 bytes.
+
+Thu Mar 21 13:54:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): Use bfd_zalloc to
+ allocate ecoff_find_line, and don't initialize by hand.
+ * elf32-mips.c (mips_elf_find_nearest_line): Use bfd_zalloc for
+ mips_elf_find_line, and don't call memset.
+
+ * coffcode.h (coff_compute_section_file_positions): If not
+ producing a final executable, don't consider sofar when aligning
+ the section to the correct size.
+
+Wed Mar 20 16:53:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_add_missing_symbols): Ifdef out.
+ (coff_write_object_contents): Don't call coff_add_missing_symbols.
+ * coffgen.c (coff_section_symbol): Ifdef out.
+
+Mon Mar 18 12:54:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf32-mips.c (mips_elf_gprel32_reloc): Initialize gp if
+ output_bfd is not NULL.
+
+Thu Mar 14 17:12:06 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * coffgen.c (coff_get_normalized_symtab): Call bfd_zalloc instead
+ of bfd_alloc (fixes fix_line not being initialized).
+ Delete zeroing of fix_{value,tag,end,scnlen} fields.
+
+Thu Mar 14 16:06:06 1996 Jeffrey A Law (law@cygnus.com)
+
+ * coffcode.h: Allow specific backends to override the
+ bfd_link_add_symbols routine.
+
+ * coff-h8300.c: Include genlink.h.
+ (howto_table): Add R_MEM_INDIRECT.
+ (rtype2howto): Support R_MEM_INDIRECT.
+ (h8300_reloc16_extra_cases): Handle R_MEM_INDIRECT like R_RELBYTE
+ for now.
+
+Tue Mar 12 12:41:17 1996 David Mosberger-Tang <davidm@koala.azstarnet.com>
+
+ * coff-alpha.c (alpha_relocate_section): Use
+ info->callbacks_warning, rather than _bfd_error_handler, for
+ "multiple gp" warning.
+
+Tue Mar 12 12:10:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * linker.c (bfd_wrapped_link_hash_lookup): New function.
+ (_bfd_generic_link_add_one_symbol): Remove BFD_ASSERT on hash
+ table string. Use bfd_wrapped_link_hash_lookup.
+ (_bfd_generic_link_write_global_symbol): Remove BFD_ASSERT on hash
+ table string.
+ * aoutx.h (aout_link_write_symbols): Use the name from the hash
+ table, if any, when writing out symbols.
+ (aout_link_input_section_std): Use the name from the hash table,
+ if any, when reporting undefined symbols.
+ (aout_link_input_section_ext): Likewise.
+ (aout_link_reloc_link_order): Use bfd_wrapped_link_hash_lookup.
+ * bout.c (get_value): Likewise.
+ * cofflink.c (_bfd_coff_reloc_link_order): Likewise.
+ * ecoff.c (ecoff_reloc_link_order): Likewise.
+ * elflink.h (elf_link_add_object_symbols): Likewise.
+ (elf_reloc_link_order): Likewise.
+ * linker.c (_bfd_generic_link_output_symbols): Likewise.
+ (_bfd_generic_reloc_link_order): Likewise.
+ (default_indirect_link_order): Likewise.
+ * reloc16.c (bfd_coff_reloc16_get_value): Likewise.
+ * sunos.c (sunos_add_one_symbol): Likewise.
+ * xcofflink.c (xcoff_link_add_symbols): Likewise.
+ (bfd_xcoff_link_count_reloc): Likewise.
+ (xcoff_reloc_link_order): Likewise.
+
+ * ecoffswap.h (ecoff_swap_fdr_in): If ECOFF_64, turn 0xffffffff
+ into -1 for intern->rss.
+
+ * configure: Rebuild with autoconf 2.8.
+
+Mon Mar 11 12:28:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stab-syms.c (__define_stab_duplicate): Define.
+ (bfd_get_stab_name): Rename from aout_stab_name. Rewrite to use a
+ switch.
+ * bfd-in.h (bfd_get_stab_name): Declare.
+ * bfd-in2.h: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD_LIBS): Add stab-syms.o.
+ (BFD_LIBS_CFILES): Add stab-syms.c.
+ (BFD32_BACKENDS): Remove stab-syms.o.
+ (BFD32_BACKENDS_CFILES): Remove stab-syms.c.
+ * configure.in: Don't list stab-syms.o in bfd_backends.
+ * configure: Rebuild.
+ * libaout.h (aout_stab_name): Don't declare.
+ * aoutx.h (NAME(aout,get_symbol_info)): Call bfd_get_stab_name,
+ not aout_stab_name.
+
+Fri Mar 8 11:26:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Adjust file offset
+ for section alignment even if SEC_LOAD is not set.
+
+Tue Mar 5 12:02:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't set SHLIB or SHLINK to an empty string,
+ since they appear as targets in Makefile.in.
+ * configure: Rebuild.
+
+ * sunos.c (sunos_scan_ext_relocs): If not making a shared library,
+ don't fiddle with a symbol which is not defined anywhere.
+
+Mon Mar 4 12:49:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_mark): Treat undefined imported symbols as
+ though they are defined in a shared library.
+ (xcoff_build_ldsyms): Likewise.
+
+ * coffgen.c (coff_find_nearest_line): Don't look at the line
+ numbers for the section if section->lineno is NULL.
+
+ * elf.c (_bfd_elf_symbol_from_bfd_symbol): Print a useful error
+ message rather than calling BFD_ASSERT.
+ * elfcode.h (write_relocs): Check return value of
+ _bfd_elf_symbol_from_bfd_symbol.
+
+Fri Mar 1 09:42:59 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Don't set SEC_LOAD flag
+ for .sbss section.
+
+Wed Feb 28 11:25:47 1996 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h (hppa_reloc_field_selector_type): Add R_HPPA_NLSEL
+ and R_HPPA_NLRSEL.
+ (e_nsel, e_nlsel, e_nlrsel): Undefine. Add to
+ hppa_reloc_field_selector_type_alt.
+ (hppa_field_adjust): Handle e_nlsel, e_nlrsel. Fix e_nsel handling.
+ * som.c (hppa_som_gen_reloc_type): Handle N', NL' NLR' field
+ selectors.
+ (som_write_fixups): Finish handling of R_N0SEL and R_N1SEL.
+
+Wed Feb 28 11:00:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Adjust the segment
+ memory size for the alignment of a SEC_ALLOC section, not just a
+ SEC_LOAD section.
+
+Tue Feb 27 14:17:31 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68klinux.c: New file.
+ * hosts/m68klinux.h: New file.
+ * config.bfd (m68*-*-linuxaout*, m68*-*-linux*): New targets.
+ * configure.in (m68*-*-linux*): New native host.
+ (m68klinux_vec): New vector.
+ * configure: Rebuild.
+ * targets.c (m68klinux_vec): Declare.
+ * i386linux.c (bfd_i386linux_size_dynamic_sections): Renamed from
+ bfd_linux_size_dynmic_sections to avoid clash with m68klinux.c.
+ * bfd-in.h (bfd_i386linux_size_dynamic_sections): Rename
+ declaration from bfd_linux_size_dynamic_sections.
+ (bfd_m68klinux_size_dynamic_sections): Declare.
+ * bfd-in2.h: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add m68klinux.o.
+ (BFD32_BACKENDS_CFILES): Add m68klinux.c.
+
+Tue Feb 27 11:31:34 1996 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h (pa_arch): Add pa20.
+ (hppa_reloc_field_selector_type): Add R_HPPA_NSEL.
+ (e_nsel): Undefine. Add to hppa_reloc_field_selector_type_alt.
+ (hppa_field_adjust): Handle e_nsel.
+ * som.c: Provide default definitions for many new relocs found only
+ in hpux10 include files.
+ (som_fixup_formats): Add several new relocs from hpux10.
+ (som_hppa_howto_table): Add hpux10 relocs.
+ (som_write_fixups): Handle R_N0SEL and R_N1SEL hpux10 relocs.
+
+Mon Feb 26 12:52:48 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit out recent shared library support, and
+ rules to rebuild .h files using doc/chew.
+
+Mon Feb 26 14:48:39 1996 David Mosberger-Tang <davidm@AZStarNet.com>
+
+ * ecoff.c (ecoff_compute_section_file_positions): Adjust the file
+ size even of sections with no contents.
+
+Mon Feb 26 14:01:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cofflink.c (_bfd_coff_link_input_bfd): When merging, skip names
+ starting with '$' the way we skip names starting with '.'. When
+ updating x_endndx, don't be fooled by an index which has been
+ merged.
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Don't try to optimize a
+ struct/union/enum type with no elements.
+
+Sat Feb 24 11:38:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd.c (bfd_errmsg): Handle a NULL return from strerror.
+
+ * archive.c (bfd_generic_archive_p): If the first file in the
+ archive can not be recognized as an object, don't assume that this
+ is the wrong format.
+
+ * elf.c (bfd_elf_set_dt_needed_name): Don't do anything if the
+ format is not bfd_object.
+ (bfd_elf_get_dt_soname): Likewise.
+
+Wed Feb 21 13:58:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-sh.c (sh_relax_delete_bytes): Correct range of R_SH_USES
+ reloc.
+
+Tue Feb 20 16:22:44 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * bfd.c (tdata): Add netbsd_core_data.
+ * bfd-in2.h: Regenerated.
+
+Tue Feb 20 16:50:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sunos.c (SUNOS_CONSTRUCTOR): Define.
+ (sunos_add_one_symbol): Don't let a symbol from a dynamic object
+ override a constructor symbol. Set SUNOS_CONSTRUCTOR when
+ appropriate.
+
+ * bout.c (b_out_squirt_out_relocs): Use udata.i rather than flags
+ to get the symbol index, matching 14 Jul 95 change.
+
+Tue Feb 20 08:26:27 1996 Fred Fish <fnf@phydeaux.cygnus.com>
+
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents):
+ Remove duplicate definition of gp.
+
+Mon Feb 19 12:37:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Don't
+ assume that we can set the GP value and then get the same value,
+ since it won't be true if the output file is neither ELF nor
+ ECOFF.
+ * coff-mips.c (mips_adjust_reloc_in): Don't bother to use
+ _bfd_get_gp_value here.
+ (mips_gprel_reloc): Don't assume we can set and get the GP value.
+ * elf32-mips.c (mips_elf_hi16_reloc): Get gp value from
+ mips_elf_final_gp.
+ (mips_elf_lo16_reloc): Likewise.
+ (mips_elf_final_gp): Add pgp parameter. Set it to the GP value.
+ Don't require that the BFD be ELF.
+ (mips_elf_gprel16_reloc): Get gp value from mips_elf_final_gp.
+ (mips_elf_gprel32_reloc): Likewise.
+ (mips_elf_relocate_section): Don't assume we can set and get the
+ GP value.
+ (mips_elf_finish_dynamic_symbol): Don't bother to use
+ _bfd_get_gp_value here.
+
+ * elf32-mips.c (mips_elf_create_procedure_table): Initialize sv.
+ Don't change epdr between malloc and free. Be careful not to free
+ NULL pointers. Zero out the first RPDR.
+
+ * configure.host: On Linux, only pass -rpath option if $(libdir)
+ is neither /lib nor /usr/lib. From Alan Modra
+ <alan@mullet.Levels.UniSA.Edu.Au>.
+
+ * elf-bfd.h (struct elf_obj_tdata): Rename dt_needed_name to
+ dt_name.
+ (elf_dt_name): Rename from elf_dt_needed_name.
+ * elf.c (bfd_elf_set_dt_needed_name): Use elf_dt_name, not
+ elf_dt_needed_name.
+ (bfd_elf_get_dt_soname): New function.
+ * elflink.h (elf_link_add_object_symbols): Use elf_dt_name, not
+ elf_dt_needed_name. Save the SONAME back in elf_dt_name.
+ * bfd-in.h (bfd_elf_get_dt_soname): Declare.
+ * bfd-in2.h: Rebuild.
+
+Mon Feb 19 02:50:23 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_reloc_type_lookup): Renamed from
+ _bfd_sparc_elf_reloc_type_lookup.
+ (bfd_elf32_bfd_reloc_type_lookup): Update.
+ * elf64-sparc.c (SPARC64_OLD_RELOCS): Define.
+ (sparc64_elf_howto_table): Define.
+ (sparc_reloc_map): Define.
+ (sparc64_elf_reloc_type_lookup): New function.
+ (sparc_elf_wdisp16_reloc): New function.
+ (elf_info_to_howto): Use sparc64_elf_howto_table.
+ (sparc64_elf_relocate_section): Likewise.
+ (bfd_elf64_bfd_reloc_type_lookup): Update.
+
+Sun Feb 18 15:02:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Check for 'do not mix' from native linker before
+ trying to use -rpath.
+
+Fri Feb 16 12:46:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd.c (_bfd_get_gp_value): New function.
+ (_bfd_set_gp_value): New function.
+ * libbfd-in.h (_bfd_get_gp_value): Declare.
+ (_bfd_set_gp_value): Declare.
+ * libbfd.h: Rebuild.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Use
+ _bfd_get_gp_value and _bfd_set_gp_value rather than referring
+ directly to the fields in the tdata information.
+ (alpha_relocate_section): Likewise.
+ * coff-mips.c (mips_adjust_reloc_in): Likewise.
+ (mips_gprel_reloc): Likewise.
+ (mips_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_hi16_reloc): Likewise.
+ (mips_elf_lo16_reloc): Likewise.
+ (mips_elf_final_gp): Likewise.
+ (mips_elf_gprel16_reloc): Likewise.
+ (mips_elf_gprel32_reloc): Likewise.
+ (mips_elf_relocate_section): Likewise.
+ (mips_elf_finish_dynamic_symbol): Likewise.
+
+ * bout.c (b_out_set_arch_mach): Recognize bfd_mach_i960_jx.
+
+Thu Feb 15 11:29:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_PROG_CC before configure.host.
+ * configure: Rebuild.
+ * configure.host: Don't set information which autoconf should
+ figure out, namely CC, CFLAGS, LDFLAGS, AR, and RANLIB.
+
+ * configure.host: Remove go32 and win32 host information, since it
+ should no longer be needed.
+
+ * elf.c (map_sections_to_segments): If we have a .dynamic section,
+ then start a new segment rather than put a writable section in a
+ readonly segment.
+
+ * configure.host: Set RPATH_ENVVAR.
+
+ * Makefile.in: Rebuild dependencies.
+
+ * elflink.c (_bfd_elf_create_linker_section): Remove unused
+ zero_section variable.
+
+Thu Feb 15 10:39:17 1996 H.J. Lu <hjl@zoom.com>
+
+ * Makefile.in ($(srcdir)/bfd-in2.h): Rename target from bfd-in2.h.
+ ($(srcdir)/libbfd.h): Rename from libbfd.h.
+ ($(srcdir)/libcoff.h): Rename from libcoff.h.
+
+Wed Feb 14 16:29:07 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de>
+
+ * ieee.c (ieee_write_expression): Only use an R variable for a
+ local symbol. Don't output a zero offset. Handle a zero address.
+ (SRC_MASK, PCREL_OFFSET): Define based on KEEPMINUSPCININST.
+ (rel32_howto, rel16_howto, rel8_howto): Use SRC_MASK and
+ PCREL_OFFSET.
+ (parse_expression): Don't try to handle multiple occurrences of a
+ P variable. Handle I variables differently from X variables. Fix
+ the order of minus expressions.
+ (ieee_slurp_external_symbols): Generate an I variable for an NN
+ record. Fix handling of ATI and ATX records.
+ (ieee_slurp_sections): Only set minimal section attributes.
+ Adjust them later, based on the section contents.
+ (ieee_object_p): Read in the file until just after the ME record.
+ Call ieee_slurp_section_data to set the section flags.
+ (do_one): Add iterations parameter. Only repeat the first load
+ item. Set the section and file reloc flags.
+ (ieee_slurp_section_data): Set section flags. Pass iterations to
+ do_one.
+ (ieee_canonicalize_reloc): Handle I variables.
+ (do_with_relocs): Only emit relocation size when necessary.
+ Increase MAXRUN to 127. Change ov to be assigned, and take
+ src_mask and pcrel_offset into account.
+ (ieee_write_data_part): Skip sections that are not loaded.
+ (ieee_write_external_part): Don't output optional last entry of WX
+ records.
+ (ieee_write_me_part): Make setting of me_record neater.
+ (ieee_generic_stat_arch_elt): Get the size of an archive element.
+
+ * syms.c (stt): Add entries for zerovars, vars, and code.
+
+ * elfcode.h (validate_reloc): New static function.
+ (write_relocs): Call validate_reloc for non ELF relocs.
+
+ * elfxx-target.h (elf_symbol_leading_char): Define if not defined.
+ (TARGET_BIG_SYM): Use elf_symbol_leading_char.
+ (TARGET_LITTLE_SYM): Likewise.
+
+ * config.bfd (m68*-*-psos*): New target.
+
+Tue Feb 13 15:56:22 1996 Bryan Ford <baford@snake.cs.utah.edu>
+
+ * i386msdos.c: Remove some #if 0 code.
+ (msdos_write_object_contents): Don't include empty sections in the
+ size computation, regardless of their address.
+
+Tue Feb 13 15:36:37 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't segfault if dynboj
+ is NULL, ie, the -r switch is used.
+
+Tue Feb 13 14:35:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * reloc.c (BFD_RELOC_MIPS_GOT_HI16): Define.
+ (BFD_RELOC_MIPS_GOT_LO16): Define.
+ (BFD_RELOC_MIPS_CALL_HI16, BFD_RELOC_MIPS_CALL_LO16): Define.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * elf32-mips.c (mips_reloc_map): Map new relocs.
+
+ * configure.host: Set HDLFLAGS for *-*-hpux with --enable-shared.
+
+ * Makefile.in ($(SHLINK)): Check ts against $(SHLIB), not
+ $(SHLINK).
+
+ * ieee.c (get_symbol): Set the section to bfd_abs_section.
+ (do_with_relocs): If EXEC_P is set and there are no relocs, use a
+ simple number for the section address, rather than an expression.
+ Limit the number of bytes between relocs to MAXRUN.
+ (ieee_write_me_part): Set me_record to the file offset after the
+ start address.
+ (ieee_write_processor): New static function.
+ (ieee_write_object_contents): Use ieee_write_processor.
+
+Fri Feb 9 10:53:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Use ${CC-gcc} when testing for -rpath on SunOS.
+
+ * coff-aux.c: Change include of aux.h to aux-coff.h.
+
+Thu Feb 8 14:01:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c (elf_m68k_relocate_section): For a R_68K_RELATIVE
+ relocation put the addend both in the reloc entry and the data.
+ (elf_m68k_finish_dynamic_symbol): Likewise. Mask out marker in
+ GOT offset value.
+
+ * elf32-m68k.c (elf_m68k_relocate_section): If -Bsymbolic, resolve
+ a R_68K_PCxx reloc against a defined global symbol directly.
+ (elf_m68k_check_relocs): Don't count such a reloc.
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Don't record a symbol with
+ a PLTxx reloc as dynamic. Disallow PLTxxO reloc against a local
+ symbol for now, otherwise always record the symbol as dynamic.
+ (elf_m68k_adjust_dynamic_symbol): If a symbol with a PLTxx reloc
+ is not referenced by a dynamic object, and we are not making a
+ shared object, then don't make a PLT entry. If we do make a PLT
+ entry, make sure the symbol has been recorded as dynamic.
+
+Wed Feb 7 13:56:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: When making a shared library, set HLDFLAGS to
+ pass an appropriate -rpath option. Use the make variable SONAME
+ as the shared library soname, rather than computing it here. On
+ SunOS, build stamp-tshlink in place of $(SHLINK).
+ * Makefile.in (SONAME): New variable.
+ ($(SHLINK)): Make a link to the transformed name, as well.
+ (stamp-tshlink): New target.
+ (install): Skip stamp-tshlink during install.
+
+Wed Feb 7 13:37:39 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Do not assume that the
+ linker sections have been set up yet.
+
+ * elf.c (make_mapping): Add an additional argument to suppress
+ making the first section include the program headers.
+ (map_sections_to_segments): If the user used -Ttext such that the
+ program headers are on a different page, do not set the flags
+ saying that this section includes the program headers.
+
+Tue Feb 6 14:04:49 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * configure.in (*-*-netbsd*): Set COREFILE to netbsd-core.c.
+ don't define TRAD_HEADER.
+ * configure: Rebuild.
+
+ * netbsd-core.c: New file, support for NetBSD core files.
+ * hosts/*nbsd.h: Removed.
+
+Tue Feb 6 11:47:49 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * reloc.c (BFD_RELOC_SPARC_[567]): New reloc types.
+ (BFD_RELOC_SPARC_LO7 reloc type): Deleted.
+ * libbfd.h, bfd-in2.h: Regenerated.
+ * elf32-sparc.c (_bfd_sparc_elf_reloc_type_lookup): Renamed from
+ bfd_elf32_bfd_reloc_type_lookup.
+ (reloc_type{,_names}): Deleted.
+ (_bfd_sparc_elf_howto_table): Renamed from elf_sparc_howto_table.
+ Add sparc64 relocs.
+ (sparc_reloc_map): Add sparc64 relocs.
+ (sparc_elf_notsupported_reloc): New static function.
+ (sparc_elf_wdisp16_reloc): New static function.
+ (elf32_sparc_check_relocs): Handle R_SPARC_WDISP{16,19}.
+ (elf32_sparc_relocate_section): Likewise.
+ (bfd_elf32_bfd_reloc_type_lookup): Define.
+ * elf64-sparc.c (sparc64_elf_wdisp16_reloc): Deleted.
+ (reloc_type{,_names}): Deleted.
+ (elf_sparc_howto_table): Deleted.
+ (sparc_reloc_map): Deleted.
+ (_bfd_sparc_elf_howto_table): Renamed from elf_sparc_howto_table.
+ (bfd_elf64_bfd_reloc_type_lookup): Change from function to #define.
+
+Tue Feb 6 12:12:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Make SHLIB_CFLAGS include $(PICFLAG) on a
+ *-*-hpux* host.
+
+ * Makefile.in (program_transform_name): New variable.
+ (install): Transform library name before installing it.
+
+Mon Feb 5 10:38:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * archures.c (bfd_mach_i960_hx): Define.
+ * bfd-in2.h: Rebuild.
+ * cpu-i960.c (scan_960_mach): Accept machine "hx".
+ (MATRIX): Expand entries for HX.
+ (arch_info_struct): Add i960:hx entry.
+ * bout.c (b_out_set_arch_mach): Handle bfd_mach_i960_hx.
+ * coffcode.h (coff_set_arch_mach_hook): Handle F_I960HX.
+ (coff_set_flags): Handle bfd_mach_i960_hx.
+
+ Support for building as a shared library, based on patches from
+ Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in: Add AC_ARG_ENABLE for shared and commonbfdlib.
+ New substitutions: ALLLIBS, PICFLAG, SHLIB, SHLIB_CC,
+ SHLIB_CFLAGS, COMMON_SHLIB, PICLIST, SHLINK.
+ * configure: Rebuild.
+ * configure.host: If --enable-shared, adjust shared library stuff
+ based on the host. If the host is SunOS, and the linker supports
+ -rpath, set HLDFLAGS to use it.
+ * Makefile.in (ALLLIBS): New variable.
+ (PICFLAG, SHLIB, SHLIB_CC, SHLIB_CFLAGS): New variables.
+ (COMMON_SHLIB, SHLINK): New variables.
+ (.c.o): If PICFLAG is set, compile twice, once PIC, once normal.
+ (STAGESTUFF): Remove variable.
+ (all): Depend upon $(ALLLIBS) and @PICLIST@ rather than
+ $(TARGETLIB).
+ (stamp-ofiles): New target, like old ofiles target, but build
+ using a temporary file and move-if-change, and touch stamp-ofiles
+ when done.
+ (ofiles): Just depend upon stamp-ofiles.
+ (stamp-piclist, piclist): New targets.
+ ($(SHLIB), $(SHLINK)): New targets.
+ (targets.o, archures.o): Build twice if PICFLAG is set.
+ (do_mostlyclean): Remove pic/*.o.
+ (do_clean): Remove stamp-ofiles, $(SHLIB), $(SHLINK), piclist, and
+ stamp-piclist.
+ (do_distclean): Remove pic and stamp-picdir.
+ (install): Install shared libraries.
+ ($(OFILES)): Depend upon stamp-picdir.
+ (stamp-picdir): New target.
+
+ * libcoff-in.h: Add comment reminding people that libcoff.h is a
+ generated file.
+ * libcoff.h: Rebuild.
+
+ * elflink.h (elf_adjust_dynamic_symbol): Don't try to get the
+ flavour of a section with no owner.
+
+ * elf32-mips.c (mips_elf_create_dynamic_sections): Clear
+ ELF_LINK_NON_ELF flag.
+ (mips_elf_create_got_section): Likewise.
+
+ * elf.c: Revert last change, since it breaks dynamic linking.
+ * elf-bfd.h (struct elf_backend_data): Remove want_hdr_in_seg
+ field.
+ * elf32-mips.c (elf_backend_want_hdr_in_seg): Don't define.
+ * elfxx-target.h (elf_backend_want_hdr_in_seg): Don't define.
+ (elfNN_bed): Don't initialize want_hdr_in_seg field.
+
+Sun Feb 4 20:45:13 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): If the backend does
+ not want the elf header or the program headers in the address
+ space, do not include them in the calculations.
+
+ * elf32-ppc.c (ppc_elf_additional_program_headers): New hook
+ function to determine if we need additional program headers.
+ (ppc_elf_modify_segment_map): Define as a NOP function for now.
+ (ppc_elf_create_linker_section): .sdata2 is a read-only section.
+
+Sat Feb 3 23:00:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h: Move today's libcoff.h change into coffcode.h.
+
+Sat Feb 3 15:43:44 1996 Fred Fish <fnf@cygnus.com>
+
+ * libcoff.h (bfd_coff_link_add_one_symbol): Combine macro args
+ back into one line. Some compilers (sunos 4.1.3 for example)
+ won't accept args split across more than one line.
+
+Fri Feb 2 11:42:15 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * aclocal.m4 (BFD_BINARY_FOPEN): Understand cygwin32.
+ * configure: Regenerate.
+
+Fri Feb 2 12:12:16 1996 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-hppa.c (elf32_hppa_backend_symbol_table_processing): Don't
+ try to do arithmetic on a void *, cast it to a unsigned char * first.
+
+Thu Feb 1 16:04:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf-bfd.h (ELF_LINK_NON_ELF): Define.
+ * elf.c (_bfd_elf_link_hash_newfunc): Set elf_link_hash_flags to
+ ELF_LINK_NON_ELF.
+ * elflink.h (elf_link_add_object_symbols): Reset ELF_LINK_NON_ELF
+ flag for a newly defined symbol.
+ (NAME(bfd_elf,record_link_assignment)): Likewise.
+ (elf_adjust_dynamic_symbol): If ELF_LINK_NON_ELF is set, try to
+ set the DEF or REF_REGULAR flags correctly.
+
+ * Makefile.in (bfd-in2.h): Make bfd.h, not protos, in docdir.
+ (libbfd.h, libcoff.h): Corresponding change.
+
+ * elf32-i386.c (elf_i386_check_relocs): Don't record a symbol with
+ a PLT32 reloc as dynamic.
+ (elf_i386_adjust_dynamic_symbol): If a symbol with a PLT32 reloc
+ is not referenced by a dynamic object, and we are not making a
+ shared object, then don't make a PLT entry. If we do make a PLT
+ entry, make sure the symbol has been recorded as dynamic.
+
+Wed Jan 31 17:23:32 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * coff-i386.c (coff_i386_reloc_type_lookup): Add BFD_RELOC_32_PCREL.
+ * config.bfd (i[345]86-*-win32): Becomes i[345]86-*-cygwin32.
+ (powerpcle-*-cygwin32): New.
+ * peicode.h (add_data_entry): Get address from vma.
+
+Wed Jan 31 16:23:57 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elflink.c (_bfd_elf_create_linker_section): If the symbol
+ attached to the section has already been created as an undefined
+ symbol, treat it as if it hasn't been created yet.
+
+Wed Jan 31 16:16:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elflink.h (elf_bfd_final_link): Don't output initial dummy
+ symbol or section symbols if stripping all symbols and this is not
+ a relocateable link. Don't output the symbol string table if
+ there are no symbols.
+ (elf_link_flush_output_syms): Don't do anything if there are no
+ symbols to flush.
+
+Wed Jan 31 12:55:49 1996 Richard Henderson <rth@tamu.edu>
+
+ * coff-aux.c: New file.
+ * hosts/m68kaux.h: New file.
+ * config.bfd (m68*-apple-aux*): New target.
+ * configure.in (m68*-apple-aux*): New native host.
+ (m68kaux_coff_vec): New vector.
+ * configure: Rebuild.
+ * targets.c (m68kaux_coff_vec): Declare.
+ * coffcode.h (bfd_coff_backend_data): Add field
+ _bfd_coff_link_add_one_symbol.
+ (bfd_coff_link_add_one_symbol): Define.
+ (compare_arelent_ptr): New static function if TARG_AUX.
+ (coff_write_relocs): If TARG_AUX, sort the relocs.
+ (coff_write_object_contents): Set A/UX aouthdr magic number.
+ (coff_link_add_one_symbol): Define if not defined.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * libcoff.h: Rebuild.
+ * cofflink.c (coff_link_add_symbols): Call
+ bfd_coff_link_add_one_symbol rather than
+ _bfd_generic_link_add_one_symbol.
+ * coff-m68k.c (COFF_PAGE_SIZE): Don't define if already defined.
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize new field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+ * Makefile.in: Rebuild dependencies.
+ (BFD32_BACKENDS): Add coff-aux.o.
+ (BFD32_BACKENDS_CFILES): Add coff-aux.c.
+
+Wed Jan 31 11:37:46 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * elf32-m68k.c (elf_m68k_relocate_section): Fix R_68K_GOT*
+ relocation; ignore addend with R_68K_{GOT,PLT}*O relocation.
+
+Tue Jan 30 12:09:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (do_maintainer_clean): Remove $(srcdir)/bfd-in2.h,
+ $(srcdir)/libbfd.h and $(srcdir)/libcoff.h.
+ (maintainer-clean): Warn about deleting special files.
+ (bfd-in2.h, libbfd.h, libcoff.h): New targets.
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Handle indirect and
+ warning symbols correctly.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Add casts to avoid
+ warnings.
+
+Mon Jan 29 14:27:24 1996 Kim Knuttila <krk@cygnus.com>
+
+ * libcoff-in.h: aligned newly exported names with bfd naming
+ conventions. Removed an erroneous define of POWERPC_LE_PE.
+ * libcoff.h: Rebuild.
+ * cofflink.c, coff-ppc.c: the above function name changes
+
+Mon Jan 29 13:06:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Basim Kadhim <kadhim@spock.cs.colorado.edu>:
+ * ecoff.c (struct extsym_info): Define.
+ (_bfd_ecoff_bfd_final_link): Pass a pointer to struct extsym_info
+ to ecoff_link_write_external.
+ (ecoff_link_write_external): Accept a struct extsym_info pointer.
+ Strip symbols when appropriate.
+
+ Based on patches from Ronald F. Guilmette <rfg@monkeys.com>:
+ * syms.c (BSF_OBJECT): Define.
+ (bfd_print_symbol_vandf): Print 'O' for BSF_OBJECT.
+ * bfd-in2.h: Rebuild.
+ * elfcode.h (elf_slurp_symbol_table): Set BSF_OBJECT for an
+ STT_OBJECT symbol.
+ * elf.c (swap_out_syms): Only set type to STT_OBJECT if BSF_OBJECT
+ is set.
+
+ * elf32-i386.c (elf_i386_relocate_section): If -Bsymbolic, when
+ copying relocs into a shared object, treat a defined global symbol
+ as a local symbol.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+ * elflink.h (elf_link_add_object_symbols): Only set weakdef to a
+ real defined symbol, not to a weak defined symbol.
+
+Mon Jan 29 11:34:36 1996 Kim Knuttila <krk@cygnus.com>
+
+ * cofflink.c: removed the POWERPC_LE_PE hack, promoted some types
+ and made a few static functions externs.
+
+ * coff-ppc.c (ppc_bfd_coff_final_link): new function, replaces the
+ POWERPC_LE_PE hack in cofflink.
+
+ * libcoff-in.h: promoted the following from cofflink.c to allow
+ _bfd_coff_final_link to be overridden - STRING_SIZE_SIZE,
+ coff_debug_merge_element, struct coff_debug_merge_type,
+ coff_debug_merge_hash_entry, coff_debug_merge_hash_table,
+ coff_debug_merge_hash_table_init, coff_debug_merge_hash_table_free,
+ coff_debug_merge_hash_lookup, coff_link_section_info,
+ coff_final_link_info, coff_debug_merge_hash_newfunc,
+ coff_write_global_sym, coff_link_input_bfd, coff_reloc_link_order.
+
+ * libcoff.h: re-gen'd
+
+Fri Jan 26 18:33:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * syms.c: Include "bfdlink.h".
+ (struct stab_find_info): Define.
+ (_bfd_stab_section_find_nearest_line): New function.
+ * libbfd-in.h (_bfd_stab_section_find_nearest_line): Declare.
+ * libbfd.h: Rebuild.
+ * elf-bfd.h (struct elf_obj_tdata): Add line_info field.
+ * elf.c (_bfd_elf_find_nearest_line): Try calling
+ _bfd_stab_section_find_nearest_line before searching the ELF
+ symbol table. Find the closest STT_FUNC symbol, not the last one.
+ * libcoff-in.h (coff_data_type): Add line_info field.
+ * libcoff.h: Rebuild.
+ * coffgen.c (coff_find_nearest_line): Try calling
+ _bfd_stab_section_find_nearest_line before searching the COFF
+ symbol table.
+ * Makefile.in: Rebuild dependencies.
+
+Fri Jan 26 16:11:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (R_PPC_EMB_SDA21 relocations): Make relocation size
+ 4 bytes, so we get the correct value when updating the register
+ field in little endian mode.
+
+Thu Jan 25 12:14:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libcoff-in.h (struct xcoff_tdata): Remove toc_section and
+ entry_section fields. Add sntoc and snentry fields.
+ * libcoff.h: Rebuild.
+ * coffcode.h (coff_mkobject_hook): Initialize sntoc and snentry,
+ not toc_section and entry_section (the COFF file does not have any
+ sections at this point).
+ (coff_write_object_contents): Set o_snentry and o_sntoc from
+ snentry and sntoc rather than entry_section and toc_section.
+ * coff-rs6000.c (xcoff_copy_private_bfd_data): Copy sntoc and
+ snentry, not toc_section and entry_section.
+ * xcofflink.c (bfd_xcoff_size_dynamic_sections): Don't set
+ entry_section from hentry.
+ (xcoff_link_input_bfd): If a defined symbol has XCOFF_ENTRY set,
+ set snenty.
+ (xcoff_link_input_bfd): Set sntoc, not toc_section.
+ (xcoff_write_global_symbol): Get toc_section from sntoc, rather
+ than using toc_section directly.
+
+ * archures.c: Add missing `.' in enum bfd_architecture.
+ * bfd-in2.h: Rebuild.
+
+ * config.bfd (i[345]86-*-sco*elf*): Use bfd_elf32_i386_vec. From
+ Robert Lipe <robertl@arnet.com>.
+
+Thu Jan 25 12:08:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Add .rela.sdata{,2}
+ to sections we allocate. Use bfd_zalloc to allocate initialial
+ sections, not bfd_alloc.
+ (ppc_elf_check_relocs): Remove BFD_ASSERTs for !shared from
+ SDA{,2}I16 relocations.
+ (ppc_elf_add_symbol_hook): Use the value of -G nn to determine
+ whether to put something in .sbss or not.
+ (ppc_elf_relocate_section): Add support for more relocations. Add
+ in sec->output_offset where appropriate. Make error messages
+ include the symbol name.
+
+ * elflink.c (_bfd_elf_create_linker_section): Lookup symbol before
+ trying to add it to the symbol table, so _GLOBAL_OFFSET_TABLE_
+ doesn't get redefined messages if -shared.
+
+ * elflink.h (elf_create_pointer_linker_section) Only bump RELA
+ section if the rel_section field has been set up.
+
+Wed Jan 24 20:40:26 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Fix typo in eabi
+ relocations.
+
+Wed Jan 24 10:38:34 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Delete checking
+ of flags, only flags used are controlled by mach number. Bump up
+ output file mach number to highest of input file mach numbers.
+ (elf32_sparc_object_p): Watch for EF_SPARC_SUN_US1.
+ (elf32_sparc_final_write_processing): Set EF_SPARC_SUN_US1 if v8plusa.
+
+ * config.bfd (sparc64-*-{sysv4*,solaris2*}): Comment out
+ bfd_elf64_sparc_vec support.
+
+Tue Jan 23 14:33:05 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_copy_private_bfd_data): Don't complain if
+ the embedded bit is set on some objects and not on others. Just
+ or it together.
+ (ppc_elf_relocate_section): Implement R_PPC_EMB_{SDA21,RELSDA}
+ relocations.
+
+Tue Jan 23 14:22:45 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_new_section_hook): Don't try to align the
+ .stabstr section.
+
+ * coffcode.h (coff_set_section_contents): Fix the handling of the
+ .lib section to work even if the entire section contents are
+ written at once. From Gvran Uddeborg <gvran@uddeborg.pp.se> and
+ Robert Lipe <robertl@arnet.com>.
+
+Mon Jan 22 18:45:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elflink.h (elf_finish_pointer_linker_section): Don't allocate
+ memory here for contents.
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Bump up _SDA_BASE_ and
+ _SDA2_BASE_ by 32768.
+ (ppc_elf_size_dynamic_sections): #if out PLT code which we haven't
+ started using. Allocate contents for .sdata and .sdata2 sections
+ also.
+ (ppc_elf_check_relocs): Use bfd_get_section_name in debug message,
+ rather than _name.
+ (ppc_elf_finish_dynamic_symbol): Remove code that attempted to
+ size _SDA{,2}_BASE_.
+ (ppc_elf_relocate_section): Change how sdata{,2} relocations are
+ done.
+
+Mon Jan 22 08:52:04 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * elflink.h (elf_finish_pointer_linker_section): Fix typo.
+
+ * archures.c (bfd_mach_sparc_v9): Renamed from bfd_mach_sparc64.
+ (bfd_mach_sparc_{v8plus,v8plusa}): Define.
+ (bfd_mach_sparc_v9a): Define.
+ (bfd_mach_sparc_v9_p): Define.
+ * bfd-in2.h: Regenerated.
+ * aoutx.h (aout,machine_type): bfd_mach_sparc64 renamed to
+ bfd_mach_sparc_v9.
+ * elf64-sparc.c (sparc64_elf_object_p): Likewise.
+ * config.bfd (sparc64-*-sysv4*,sparc64-*-solaris2*): Set targ_defvec
+ to bfd_elf32_sparc_vec.
+ * cpu-sparc.c (arch_info_struct): Renamed from sparc_arch_info.
+ Add v8plus{,a} support.
+ Add v9a support.
+ (sparc_compatible): New function.
+ * elf32-sparc.h: #include "elf/sparc.h".
+ (elf32_sparc_merge_private_bfd_data, elf32_sparc_object_p,
+ elf32_sparc_final_write_processing): New functions.
+ (bfd_elf32_bfd_merge_private_bfd_data, elf_backend_object_p,
+ elf_backend_final_write_processing): Define.
+
+Mon Jan 22 11:21:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Add
+ linker_section_pointer field.
+ (enum elf_linker_section_enum): Enumeration for new way of
+ creating linker dynamic sections and symbols.
+ (elf_linker_section{,_pointers}): New structures for creating
+ dynamic sections and symbols.
+ (elf_obj_tdata): Add linker_section_pointers and linker_section
+ fields.
+ (elf_local_ptr_offsets,elf_linker_section): New accessor macros.
+ (_bfd_elf_create_linker_section): New declarations.
+ (_bfd_elf_find_pointer_linker_section): Ditto.
+ (bfd_elf{32,64}_{create,finish}_pointer_linker_section): Ditto.
+ (_bfd_elf_make_linker_section_rela): Ditto.
+
+ * elf.c (_bfd_elf_link_hash_newfunc): Initialize new fields.
+
+ * elf32-ppc.c (ppc_elf_create_dynamic_sections): Delete.
+ (ppc_elf_create_linker_section): New function to create the
+ sections .got, .sdata, and .sdata2.
+ (ppc_elf_size_dynamic_sections): Zap .rela.{sdata,sdata2} if
+ needed.
+ (ppc_elf_check_relocs): Support more of the eabi relocations.
+ (ppc_elf_relocate_section): Ditto.
+ (ppc_elf_finish_dynamic_symbols): Adjust _SDA{,2}_BASE_ by 32768
+ if the .sdata{,2} + .sbss{,2} section size is > 32k.
+
+ * elflink.h (elf_create_pointer_linker_section): New function to
+ create initialized pointers in dynamic linker sections.
+ (elf_finish_pointer_linker_section): Actually intialize the
+ pointers created above.
+
+ * elfcode.h (bfd_elf{32,64}_create_pointer_linker_section): New
+ macros to provide both 32 and 64 bit versions of
+ elf_create_pointer_linker_section.
+ (bfd_elf{32,64}_finish_pointer_linker_section): New macros to
+ provide both 32 and 64 bit versions of
+ elf_finish_pointer_linker_section.
+
+ * elflink.c (_bfd_elf_create_linker_section): New function to
+ create a linker section.
+ (_bfd_elf_find_pointer_linker_section): Find a unique pointer to a
+ given address in the linker pointer offsets created for a given
+ symbol.
+ (_bfd_elf_make_linker_section_rela): Make a RELA section
+ corresponding to the generated linker section.
+
+Sat Jan 20 08:36:10 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * elf32-sparc.c (ELF_MACHINE_ALT1): Define.
+
+Thu Jan 18 18:25:34 1996 Kim Knuttila <krk@cygnus.com>
+
+ * coff-ppc.c (coff_ppc_relocate_section): changed TOCDEFN relocs.
+ (coff_ppc_relocate_section): Handle special values for gcc built dlls.
+ (dump_toc): fix diagnosing code to identify out-of-toc-bounds entries.
+ Also begin the toc at 4 as an eye catcher ('31313131' marks the first
+ toc entry in an objdump) for now.
+ (ppc_do_last, ppc_get_last): New function - needed to save processing
+ the toc owner to the end.
+ (ppc_coff_swap_sym_in_hook): Removed an incorrect hack for doing the
+ toc owner last.
+
+ * cofflink.c (_bfd_coff_final_link): Added a new hack to keep the
+ toc owner from being done till last. Must define POWERPC_LE_PC
+ to enable it.
+
+ * coffcode.h (coff_set_alignment_hook): alignment setting for .stab
+
+ * peicode.h (coff_swap_scnhdr_out): set section flags for stab/str
+ to INFO.
+ (coff_swap_aouthdr_out): Removed a non-working hack for computing the
+ SizeOfImage for PowerPC. Ignore the size of the .junk section.
+
+Thu Jan 18 17:42:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elfcore.h: Include <signal.h> before <sys/procfs.h>.
+
+Wed Jan 17 12:40:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cpu-powerpc.c (arch_info_struct): Change last entry to not point
+ back to first.
+ (bfd_powerpc_arch): Point at first entry in arch_info_struct.
+
+Tue Jan 16 15:10:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Don't increment file
+ offset for a segment which contains no loadable sections.
+
+Mon Jan 15 17:46:27 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * reloc.c: Add new PowerPC relocations.
+ * {bfd-in2,libbfd}.h: Regenerate.
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Add more PPC relocations.
+ (ppc_elf_reloc_type_lookup): Lookup new relocations.
+
+Mon Jan 15 14:29:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aoutx.h (howto_table_ext): Fix RELOC_BASE10 and RELOC_BASE22
+ entries.
+
+ * sunos.c (sunos_scan_ext_relocs): Don't fail assert if
+ info->shared.
+
+ * coffgen.c (coff_find_nearest_line): Don't try to cache
+ information in sections that are not owned by a BFD. From Richard
+ Henderson <richard@atheist.tamu.edu>.
+
+ * elf32-mips.c: Numerous changes to dynamic linking code, mostly
+ from Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
+ * elflink.h (elf_link_output_extsym): Remove special check for
+ _rld_new_interface.
+
+ * ecoffswap.h: Add prototypes for static functions.
+
+Sun Jan 14 21:36:08 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_{unsupported,std}_reloc): Remove functions.
+ (ppc_elf_howto_raw): Remove ppc_elf_{unsupported,std}_reloc
+ references.
+ (ppc_elf_relocate_section): No longer allow .sdata/.sbss sections
+ to satisfy a TOC16 relocation. Rewrite unsupported relocation
+ support. Begin support for R_PPC_SDA{2,}REL.
+
+Sat Jan 13 09:36:52 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_create_dynamic_sections): New function to
+ create the .got and .got.neg sections.
+ (ppc_elf_size_dynamic_sections): Call it.
+ (ppc_elf_check_relocs): Call it.
+ (ppc_elf_size_dynamic_sections): Support .got.neg, just like .got.
+ (ppc_elf_check_relocs): Add error messages for relocations we
+ don't yet support. Do not include R_PPC_SDAREL16 like a GOT
+ relocation.
+
+Fri Jan 12 15:27:59 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_fake_sections): Define, and handle the new
+ section flags for V.4 and eabi.
+
+Fri Jan 12 13:59:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): If a segment
+ contains no sections, don't mark it as readable.
+
+ * elf-bfd.h (_bfd_elf_section_from_bfd_section): Declare.
+ * elfcode.h (_bfd_elf_section_from_bfd_section): Don't declare.
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Dump contents of
+ dynamic section, if there is one.
+ * elf-bfd.h (struct elf_size_info): Add swap_dyn_in field.
+ (bfd_elf32_swap_dyn_in): Change type of second parameter to PTR.
+ (bfd_elf64_swap_dyn_in): Likewise.
+ * elfcode.h (elf_swap_dyn_in): Change type of second parameter to
+ PTR.
+ (NAME(_bfd_elf,size_info)): Initialize swap_dyn_in field.
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Don't create a
+ DT_TEXTREL entry because of .rel.plt. From Martin Pirker
+ <pirker@eiunix.tuwien.ac.at>.
+
+Thu Jan 11 17:06:14 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * section.c (SEC_{EXCLUDE,SORT_ENTRIES}): New section flags for
+ PowerPC V.4 and eabi.
+ * bfd-in2.h: Regenerate.
+ * libfd.h: Regenerate.
+
+ * elfxx-target.h (TARGET_{BIG,LITTLE}_SYM): Add new flags.
+
+ * elf32-ppc.c (ppc_elf_section_from_shdr): Support SHT_ORDERED
+ section type and SHF_EXCLUDE section flag, turning them into the
+ appropriate bfd section flag.
+
+Thu Jan 11 11:23:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Create the special
+ sections if we see a DYNAMIC object, in case that is the only
+ XCOFF input object we see.
+
+ * elf32-mips.c: Extensive changes for a start at dynamic linking
+ support, from Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
+
+ * elf-bfd.h (struct elf_backend_data): Add type_change_ok field.
+ (struct elf_backend_data): Remove
+ elf_backend_create_program_headers field. Add
+ elf_backend_additional_program_headers and
+ elf_backend_modify_segment_map fields.
+ * elfxx-target.h (elf_backend_type_change_ok): Define if not
+ defined.
+ (elf_backend_additional_program_headers): Likewise.
+ (elf_backend_modify_segment_map): Likewise.
+ (elf_backend_create_program_headers): Don't define.
+ (elfNN_bed): Change to account for field changes.
+ * elf.c (assign_file_positions_for_segments): Call new
+ modify_segment_map backend function. Don't call old
+ create_program_headers backend function.
+ (get_program_header_size): Call additional_program_headers rather
+ than create_program_headers.
+ * elflink.h (elf_link_add_object_symbols): Initialize
+ type_change_ok from new backend field.
+ (elf_link_output_extsym): Don't warn if _rld_new_interface is
+ defined.
+ (elf_reloc_link_order): Treat a reloc against a defined symbol as
+ a reloc against the appropriate section.
+
+ * elf-bfd.h (struct bfd_elf_section_data): Add tdata field.
+ (struct elf_obj_tdata): Rename ppc_flags_init field to flags_init.
+ (elf_flags_init): Rename from elf_ppc_flags_init.
+ * elf32-ppc.c (ppc_elf_set_private_flags): Use elf_flags_init, not
+ elf_ppc_flags_init.
+ (ppc_elf_copy_private_bfd_data): Likewise.
+ (ppc_elf_merge_private_bfd_data): Likewise.
+
+ * elf32-m68k.c (howto_table): Change src_mask to 0 for all
+ relocation entries.
+
+Tue Jan 9 15:22:53 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * coff-alpha.c (alpha_relocate_section): During final link, allow
+ output .lita section to be bigger than 64k by adjusting gp value
+ on a per-input section basis.
+ * libecoff.h (struct ecoff_tdata): Add issued_multiple_gp_warning
+ field.
+ (struct ecoff_section_tdata): Add gp field.
+
+Tue Jan 9 12:00:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Handle Alpha ECOFF changes in OSF/1 3.2.
+ * libecoff.h (struct ecoff_backend_data): Add get_elt_at_filepos
+ field.
+ * coff-alpha.c: Include "aout/ar.h".
+ (alpha_ecoff_get_relocated_section_contents): Don't require an
+ ALPHA_R_IGNORE reloc after an ALPHA_R_GPDISP reloc, since OSF/1
+ 3.2 doesn't generate one.
+ (alpha_relocate_section): Likewise.
+ (alpha_ecoff_slurp_armap): Define.
+ (alpha_ecoff_slurp_extended_name_table): Define.
+ (alpha_ecoff_construct_extended_name_table): Define.
+ (alpha_ecoff_truncate_arname): Define.
+ (alpha_ecoff_write_armap): Define.
+ (alpha_ecoff_generic_stat_arch_elt): Define.
+ (alpha_ecoff_update_armap_timestamp): Define.
+ (ARFZMAG): Define.
+ (alpha_ecoff_read_ar_hdr): New static function.
+ (alpha_ecoff_get_elt_at_filepos): New static function.
+ (alpha_ecoff_openr_next_archived_file): New static function.
+ (alpha_ecoff_get_elt_at_index): New static function.
+ (alpha_ecoff_backend_data): Initialize get_elt_at_filepos field.
+ (ecoffalpha_little_vec): Change BFD_JUMP_TABLE_ARCHIVE from
+ _bfd_ecoff to alpha_ecoff.
+ * ecoff.c (ecoff_link_add_archive_symbols): Use get_elt_at_filepos
+ field from backend structure, rather than always calling
+ _bfd_get_elt_at_filepos.
+ * coff-mips.c (mips_ecoff_backend_data): Initialize
+ get_elt_at_filepos field.
+ * archive.c (_bfd_generic_read_ar_hdr_mag): New function, copied
+ from _bfd_generic_read_ar_hdr with minor changes.
+ (_bfd_generic_read_ar_hdr): Use _bfd_generic_read_ar_hdr_mag.
+ * libbfd-in.h (_bfd_generic_read_ar_hdr_mag): Declare.
+ * libbfd.h: Rebuild.
+
+ * bfd-in.h (BFD_IN_MEMORY): Define.
+ * libbfd-in.h (struct bfd_in_memory): Define.
+ * libbfd.c (bfd_read): Handle BFD_IN_MEMORY flag.
+ (bfd_get_file_window): Don't try to map a BFD_IN_MEMORY file.
+ (bfd_write, bfd_stat): Abort if BFD_IN_MEMORY is set.
+ (bfd_tell, bfd_flush, bfd_seek): Handle BFD_IN_MEMORY flag.
+ * bfd.c (struct _bfd): Change iostream field from char * to PTR.
+ (bfd_get_size): Handle BFD_IN_MEMORY flag.
+ * cache.c (bfd_cache_close): Ignore BFD_IN_MEMORY files.
+ (bfd_open_file): Cast to PTR, not char *, when setting iostream.
+ (bfd_cache_lookup_worker): Abort if BFD_IN_MEMORY is set.
+ * opncls.c (bfd_fdopenr): Cast to PTR, not char *, when setting
+ iostream.
+ (bfd_openstreamr): Likewise.
+ * aoutx.h (NAME(aout,some_aout_object_p)): Only fstat iostream if
+ BFD_IN_MEMORY is not set.
+ * riscix.c (riscix_some_aout_object_p): Likewise.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+ * targets.c (bfd_target): Add _bfd_get_elt_at_index field.
+ (BFD_JUMP_TABLE_ARCHIVE): Add _get_elt_at_index.
+ (bfd_get_elt_at_index): Define.
+ * archive.c (_bfd_generic_get_elt_at_index): Rename from
+ bfd_get_elt_at_index. Change index parameter from int to
+ symindex.
+ * libbfd-in.h (_bfd_generic_get_elt_at_index): Declare.
+ (_bfd_noarchive_get_elt_at_index): Define.
+ (_bfd_archive_bsd_get_elt_at_index): Define.
+ (_bfd_archive_coff_get_elt_at_index): Define.
+ * bfd-in2.h, libbfd.h: Rebuild.
+ * aout-target.h (MY_get_elt_at_index): Define if not defined.
+ * coff-rs6000.c (xcoff_get_elt_at_index): Define.
+ * ieee.c (ieee_get_elt_at_index): Define.
+ * libecoff.h (_bfd_ecoff_get_elt_at_index): Define.
+ * oasys.c (oasys_get_elt_at_index): Define.
+ * som.c (som_get_elt_at_index): Define.
+
+ * ecoff.c (_bfd_ecoff_find_nearest_line): Don't restrict line
+ numbers to the .text section.
+
+Mon Jan 8 17:00:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_write_debug_part): Change return type to boolean.
+ If there is a SEC_DEBUGGING section, get the contents of the debug
+ information part from it.
+ (ieee_set_section_contents): Store the contents of a SEC_DEBUGGING
+ section in memory.
+ (ieee_write_object_contents): Check ieee_write_debug_part return.
+
+Thu Jan 4 17:12:37 1996 Fred Fish <fnf@cygnus.com>
+
+ * config.bfd (i[345]86-*-freebsd*): Add target.
+ * configure.in (i386freebsd_vec): Add vec.
+ * configure: Regenerate.
+ * Makefile.in (BFD32_BACKENDS): Add i386freebsd.o.
+ (BFD32_BACKENDS_CFILES): Add i386freebsd.c.
+ Rebuild dependencies..
+ * freebsd.h: New file.
+ * i386freebsd.c: New file.
+ * targets.c (i386freebsd_vec): Declare.
+ (bfd_target_vector): Add i386freebsd_vec.
+ * i386linux.c (SEGMENT_SIZE): Define as TARGET_PAGE_SIZE
+ * i386netbsd.c (SEGMENT_SIZE): Define as TARGET_PAGE_SIZE
+
+Thu Jan 4 16:27:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_slurp_debug): New static function.
+ (ieee_object_p): Call it.
+ (ieee_slurp_section_data): Skip debugging sections.
+ (ieee_get_reloc_upper_bound): Likewise.
+ (ieee_get_section_contents): Likewise.
+ (ieee_canonicalize_reloc): Likewise.
+ (ieee_write_section_part): Likewise.
+ (ieee_write_debug_part): Likewise.
+ (ieee_write_data_part): Likewise.
+ (init_for_output): Likewise.
+
+Wed Jan 3 19:42:47 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Make @GOT relocations
+ work.
+ (ppc_elf_howto_raw): Just use bfd_elf_generic_reloc for all howto
+ relocs, since ppc_elf_relocate_section handles the linker case.
+ (ppc_elf_{addr16_ha,got16,toc16,brtaken}_reloc): Delete, no longer
+ used.
+ (ppc_elf_{addr16_ha,got16,toc16,brtaken}_inner): Merge these into
+ ppc_elf_relocate_section since that is now the only caller.
+ (ppc_elf_relocate_section): Ditto.
+
+Wed Jan 3 15:11:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffcode.h (coff_write_object_contents): If we don't know the
+ section of the entry point for an XCOFF executable, always set the
+ entry address to -1.
+
+Tue Jan 2 14:17:15 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * elf.c (bfd_section_from_shdr): Add support for note sections.
+
+Tue Jan 2 13:10:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfd-in.h (struct _symbol_info): Add stab_type field.
+ * bfd-in2.h: Rebuild.
+ * aoutx.h (NAME(aout,get_symbol_info)): Set stab_type.
+
+ * elf32-ppc.c: Remove trailing newline from calls to
+ _bfd_error_handler.
+ (ppc_elf_merge_private_bfd_data): Only warn about endianness
+ difference if target endianness is known.
+
+For older changes see ChangeLog-9495
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
new file mode 100644
index 00000000000..a15531171d8
--- /dev/null
+++ b/bfd/Makefile.am
@@ -0,0 +1,1065 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCDIR = $(srcdir)/../include
+CSEARCH = -I. -I$(srcdir) -I$(INCDIR)
+DEP = mkdep
+
+SUBDIRS = doc po
+
+docdir = doc
+
+lib_LTLIBRARIES = libbfd.la
+
+# bfd.h goes here, for now
+BFD_H = bfd.h
+
+# Jim Kingdon notes:
+# Writing S-records should be included in all (or at least most)
+# *-*-coff, *-*-aout, etc., configurations, because people will want to
+# be able to use objcopy to create S-records. (S-records are not useful
+# for the debugger, so if you are downloading things as S-records you
+# need two copies of the executable, one to download and one for the
+# debugger).
+BFD_LIBS = \
+ archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
+ format.lo init.lo libbfd.lo opncls.lo reloc.lo \
+ section.lo syms.lo targets.lo hash.lo linker.lo \
+ srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo
+
+BFD_LIBS_CFILES = \
+ archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
+ format.c init.c libbfd.c opncls.c reloc.c \
+ section.c syms.c targets.c hash.c linker.c \
+ srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c
+
+# This list is alphabetized to make it easier to keep in sync
+# with the decls and initializer in archures.c.
+ALL_MACHINES = \
+ cpu-a29k.lo \
+ cpu-alpha.lo \
+ cpu-arc.lo \
+ cpu-arm.lo \
+ cpu-d10v.lo \
+ cpu-d30v.lo \
+ cpu-fr30.lo \
+ cpu-h8300.lo \
+ cpu-h8500.lo \
+ cpu-hppa.lo \
+ cpu-i386.lo \
+ cpu-i860.lo \
+ cpu-i960.lo \
+ cpu-m32r.lo \
+ cpu-m68k.lo \
+ cpu-m88k.lo \
+ cpu-m10200.lo \
+ cpu-m10300.lo \
+ cpu-mcore.lo \
+ cpu-mips.lo \
+ cpu-ns32k.lo \
+ cpu-powerpc.lo \
+ cpu-rs6000.lo \
+ cpu-sh.lo \
+ cpu-sparc.lo \
+ cpu-tic30.lo \
+ cpu-tic80.lo \
+ cpu-v850.lo \
+ cpu-vax.lo \
+ cpu-we32k.lo \
+ cpu-w65.lo \
+ cpu-z8k.lo
+
+ALL_MACHINES_CFILES = \
+ cpu-a29k.c \
+ cpu-alpha.c \
+ cpu-arc.c \
+ cpu-arm.c \
+ cpu-d10v.c \
+ cpu-d30v.c \
+ cpu-fr30.c \
+ cpu-h8300.c \
+ cpu-h8500.c \
+ cpu-hppa.c \
+ cpu-i386.c \
+ cpu-i860.c \
+ cpu-i960.c \
+ cpu-m32r.c \
+ cpu-m68k.c \
+ cpu-m88k.c \
+ cpu-m10200.c \
+ cpu-m10300.c \
+ cpu-mcore.c \
+ cpu-mips.c \
+ cpu-ns32k.c \
+ cpu-powerpc.c \
+ cpu-rs6000.c \
+ cpu-sh.c \
+ cpu-sparc.c \
+ cpu-tic30.c \
+ cpu-tic80.c \
+ cpu-v850.c \
+ cpu-vax.c \
+ cpu-we32k.c \
+ cpu-w65.c \
+ cpu-z8k.c
+
+# The .o files needed by all of the 32 bit vectors that are configured into
+# target_vector in targets.c if configured with --enable-targets=all.
+BFD32_BACKENDS = \
+ aout-adobe.lo \
+ aout-arm.lo \
+ aout-ns32k.lo \
+ aout-sparcle.lo \
+ aout-tic30.lo \
+ aout0.lo \
+ aout32.lo \
+ bout.lo \
+ cf-i386lynx.lo \
+ cf-m68klynx.lo \
+ cf-sparclynx.lo \
+ coff-a29k.lo \
+ coff-apollo.lo \
+ coff-arm.lo \
+ coff-aux.lo \
+ coff-h8300.lo \
+ coff-h8500.lo \
+ coff-i386.lo \
+ coff-go32.lo \
+ coff-i860.lo \
+ coff-i960.lo \
+ coff-m68k.lo \
+ coff-m88k.lo \
+ coff-mips.lo \
+ coff-pmac.lo \
+ coff-rs6000.lo \
+ coff-sh.lo \
+ coff-sparc.lo \
+ coff-stgo32.lo \
+ coff-svm68k.lo \
+ coff-tic30.lo \
+ coff-tic80.lo \
+ coff-u68k.lo \
+ coff-we32k.lo \
+ coff-w65.lo \
+ coff-z8k.lo \
+ cofflink.lo \
+ dwarf2.lo \
+ ecoff.lo \
+ ecofflink.lo \
+ elf.lo \
+ elf32-arc.lo \
+ elfarm-oabi.lo \
+ elfarm-nabi.lo \
+ elf32-d10v.lo \
+ elf32-d30v.lo \
+ elf32-fr30.lo \
+ elf32-gen.lo \
+ elf32-hppa.lo \
+ elf32-i386.lo \
+ elf32-i860.lo \
+ elf32-m32r.lo \
+ elf32-m68k.lo \
+ elf32-m88k.lo \
+ elf-m10200.lo \
+ elf-m10300.lo \
+ elf32-mcore.lo \
+ elf32-mips.lo \
+ elf32-ppc.lo \
+ elf32-sh.lo \
+ elf32-sparc.lo \
+ elf32-v850.lo \
+ elf32.lo \
+ elflink.lo \
+ hp300bsd.lo \
+ hp300hpux.lo \
+ som.lo \
+ i386aout.lo \
+ i386bsd.lo \
+ i386dynix.lo \
+ i386freebsd.lo \
+ i386linux.lo \
+ i386lynx.lo \
+ i386msdos.lo \
+ i386netbsd.lo \
+ i386mach3.lo \
+ i386os9k.lo \
+ ieee.lo \
+ m68k4knetbsd.lo \
+ m68klinux.lo \
+ m68klynx.lo \
+ m68knetbsd.lo \
+ m88kmach3.lo \
+ mipsbsd.lo \
+ newsos3.lo \
+ nlm.lo \
+ nlm32-i386.lo \
+ nlm32-sparc.lo \
+ nlm32-ppc.lo \
+ nlm32.lo \
+ ns32knetbsd.lo \
+ oasys.lo \
+ pc532-mach.lo \
+ pe-arm.lo \
+ pei-arm.lo \
+ pe-i386.lo \
+ pei-i386.lo \
+ pe-mcore.lo \
+ pei-mcore.lo \
+ pe-ppc.lo \
+ pei-ppc.lo \
+ ppcboot.lo \
+ reloc16.lo \
+ riscix.lo \
+ sparclinux.lo \
+ sparclynx.lo \
+ sparcnetbsd.lo \
+ sunos.lo \
+ vaxnetbsd.lo \
+ versados.lo \
+ vms.lo \
+ vms-gsd.lo \
+ vms-hdr.lo \
+ vms-misc.lo \
+ vms-tir.lo \
+ xcofflink.lo
+
+BFD32_BACKENDS_CFILES = \
+ aout-adobe.c \
+ aout-arm.c \
+ aout-ns32k.c \
+ aout-sparcle.c \
+ aout-tic30.c \
+ aout0.c \
+ aout32.c \
+ bout.c \
+ cf-i386lynx.c \
+ cf-m68klynx.c \
+ cf-sparclynx.c \
+ coff-a29k.c \
+ coff-apollo.c \
+ coff-arm.c \
+ coff-aux.c \
+ coff-h8300.c \
+ coff-h8500.c \
+ coff-i386.c \
+ coff-i860.c \
+ coff-go32.c \
+ coff-i960.c \
+ coff-m68k.c \
+ coff-m88k.c \
+ coff-mips.c \
+ coff-pmac.c \
+ coff-rs6000.c \
+ coff-sh.c \
+ coff-sparc.c \
+ coff-stgo32.c \
+ coff-svm68k.c \
+ coff-tic30.c \
+ coff-tic80.c \
+ coff-u68k.c \
+ coff-we32k.c \
+ coff-w65.c \
+ coff-z8k.c \
+ cofflink.c \
+ dwarf2.c \
+ ecoff.c \
+ ecofflink.c \
+ elf.c \
+ elf32-arc.c \
+ elfarm-oabi.c \
+ elfarm-nabi.c \
+ elf32-d10v.c \
+ elf32-d30v.c \
+ elf32-fr30.c \
+ elf32-gen.c \
+ elf32-hppa.c \
+ elf32-i386.c \
+ elf32-i860.c \
+ elf32-m32r.c \
+ elf32-m68k.c \
+ elf32-m88k.c \
+ elf-m10200.c \
+ elf-m10300.c \
+ elf32-mcore.c \
+ elf32-mips.c \
+ elf32-ppc.c \
+ elf32-sh.c \
+ elf32-sparc.c \
+ elf32-v850.c \
+ elf32.c \
+ elflink.c \
+ hp300bsd.c \
+ hp300hpux.c \
+ som.c \
+ i386aout.c \
+ i386bsd.c \
+ i386dynix.c \
+ i386freebsd.c \
+ i386linux.c \
+ i386lynx.c \
+ i386msdos.c \
+ i386netbsd.c \
+ i386mach3.c \
+ i386os9k.c \
+ ieee.c \
+ m68k4knetbsd.c \
+ m68klinux.c \
+ m68klynx.c \
+ m68knetbsd.c \
+ m88kmach3.c \
+ mipsbsd.c \
+ newsos3.c \
+ nlm.c \
+ nlm32-i386.c \
+ nlm32-sparc.c \
+ nlm32-ppc.c \
+ nlm32.c \
+ ns32knetbsd.c \
+ oasys.c \
+ pc532-mach.c \
+ pe-arm.c \
+ pei-arm.c \
+ pe-i386.c \
+ pei-i386.c \
+ pe-mcore.c \
+ pei-mcore.c \
+ pe-ppc.c \
+ pei-ppc.c \
+ ppcboot.c \
+ reloc16.c \
+ riscix.c \
+ sparclinux.c \
+ sparclynx.c \
+ sparcnetbsd.c \
+ sunos.c \
+ vaxnetbsd.c \
+ versados.c \
+ vms.c \
+ vms-gsd.c \
+ vms-hdr.c \
+ vms-misc.c \
+ vms-tir.c \
+ xcofflink.c
+
+# The .o files needed by all of the 64 bit vectors that are configured into
+# target_vector in targets.c if configured with --enable-targets=all
+# and --enable-64-bit-bfd.
+BFD64_BACKENDS = \
+ aout64.lo \
+ coff-alpha.lo \
+ demo64.lo \
+ elf64-alpha.lo \
+ elf64-gen.lo \
+ elf64-mips.lo \
+ elf64-sparc.lo \
+ elf64.lo \
+ nlm32-alpha.lo \
+ nlm64.lo
+
+BFD64_BACKENDS_CFILES = \
+ aout64.c \
+ coff-alpha.c \
+ demo64.c \
+ elf64-alpha.c \
+ elf64-gen.c \
+ elf64-mips.c \
+ elf64-sparc.c \
+ elf64.c \
+ nlm32-alpha.c \
+ nlm64.c
+
+OPTIONAL_BACKENDS = \
+ aix386-core.lo \
+ hpux-core.lo \
+ irix-core.lo \
+ lynx-core.lo \
+ osf-core.lo \
+ sco5-core.lo \
+ trad-core.lo \
+ cisco-core.lo
+
+OPTIONAL_BACKENDS_CFILES = \
+ aix386-core.c \
+ hpux-core.c \
+ irix-core.c \
+ lynx-core.c \
+ osf-core.c \
+ sco5-core.c \
+ trad-core.c \
+ cisco-core.c
+
+# These are defined by configure.in:
+WORDSIZE = @wordsize@
+ALL_BACKENDS = @all_backends@
+BFD_BACKENDS = @bfd_backends@
+BFD_MACHINES = @bfd_machines@
+TDEFAULTS = @tdefaults@
+
+INCLUDES = -D_GNU_SOURCE @HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES) -I$(srcdir)/../intl -I../intl
+
+# C source files that correspond to .o's.
+CFILES = \
+ $(BFD_LIBS_CFILES) \
+ $(ALL_MACHINES_CFILES) \
+ $(BFD32_BACKENDS_CFILES) \
+ $(BFD64_BACKENDS_CFILES) \
+ $(OPTIONAL_BACKENDS_CFILES)
+
+## This is a list of all .h files which are in the source tree.
+SOURCE_HFILES = \
+ aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h \
+ ecoffswap.h elf32-hppa.h \
+ elfcode.h genlink.h go32stub.h hppa_stubs.h libaout.h \
+ libbfd.h libcoff.h libecoff.h elf-bfd.h libhppa.h libieee.h \
+ libnlm.h liboasys.h netbsd.h nlm-target.h nlmcode.h ns32k.h \
+ som.h vms.h
+
+HFILES = \
+ elf32-target.h elf64-target.h targmatch.h \
+ $(SOURCE_HFILES)
+
+POTFILES = $(CFILES) $(SOURCE_HFILES)
+
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+diststuff: info
+
+# Various kinds of .o files to put in libbfd.a:
+# BFD_BACKENDS Routines the configured targets need.
+# BFD_MACHINES Architecture-specific routines the configured targets need.
+# COREFILE Core file routines for a native configuration
+OFILES = $(BFD_BACKENDS) $(BFD_MACHINES) @COREFILE@
+
+stamp-ofiles: Makefile
+ rm -f tofiles
+ f=""; \
+ for i in $(OFILES) ; do \
+ case " $$f " in \
+ *" $$i "*) ;; \
+ *) f="$$f $$i" ;; \
+ esac ; \
+ done ; \
+ echo $$f > tofiles
+ $(SHELL) $(srcdir)/../move-if-change tofiles ofiles
+ touch stamp-ofiles
+
+ofiles: stamp-ofiles ; @true
+
+libbfd_la_SOURCES = $(BFD_LIBS_CFILES)
+libbfd_la_DEPENDENCIES = $(OFILES) ofiles
+libbfd_la_LIBADD = `cat ofiles` @WIN32LIBADD@
+libbfd_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
+
+# libtool will build .libs/libbfd.a. We create libbfd.a in the build
+# directory so that we don't have to convert all the programs that use
+# libbfd.a simultaneously. This is a hack which should be removed if
+# everything else starts using libtool. FIXME.
+
+noinst_LIBRARIES = libbfd.a
+libbfd_a_SOURCES =
+
+stamp-lib: libbfd.la
+ if [ -f .libs/libbfd.a ]; then \
+ cp .libs/libbfd.a libbfd.tmp; \
+ $(SHELL) $(srcdir)/../move-if-change libbfd.tmp libbfd.a; \
+ else true; fi
+ touch stamp-lib
+
+libbfd.a: stamp-lib ; @true
+
+# This file holds an array associating configuration triplets and
+# vector names. It is built from config.bfd. It is not compiled by
+# itself, but is included by targets.c.
+targmatch.h: config.bfd targmatch.sed
+ rm -f targmatch.h
+ sed -f $(srcdir)/targmatch.sed < $(srcdir)/config.bfd > targmatch.new
+ mv -f targmatch.new targmatch.h
+
+# When compiling archures.c and targets.c, supply the default target
+# info from configure.
+
+targets.lo: targets.c config.status
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $(TDEFAULTS) $(srcdir)/targets.c
+
+archures.lo: archures.c config.status
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $(TDEFAULTS) $(srcdir)/archures.c
+
+elf32-target.h : elfxx-target.h
+ rm -f elf32-target.h
+ sed -e s/NN/32/g < $(srcdir)/elfxx-target.h > elf32-target.new
+ mv -f elf32-target.new elf32-target.h
+
+elf64-target.h : elfxx-target.h
+ rm -f elf64-target.h
+ sed -e s/NN/64/g < $(srcdir)/elfxx-target.h > elf64-target.new
+ mv -f elf64-target.new elf64-target.h
+
+BFD_H_DEPS= $(INCDIR)/ansidecl.h
+LOCAL_H_DEPS= libbfd.h sysdep.h config.h
+$(BFD_LIBS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+$(BFD_MACHINES): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+$(BFD_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+$(OPTIONAL_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+
+# Install BFD include file, and others that it needs.
+install-data-local: $(BFD_H)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(includedir)
+ $(INSTALL_DATA) $(BFD_H) $(includedir)/bfd.h
+ $(INSTALL_DATA) $(INCDIR)/ansidecl.h $(includedir)/ansidecl.h
+ $(INSTALL_DATA) $(INCDIR)/bfdlink.h $(includedir)/bfdlink.h
+
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) bfd.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+# The NetBSD mkdep overwrites any existing file contents, and doesn't insert
+# the "DO NOT DELETE" line.
+# Other mkdep versions require a file that already exists, and do insert it.
+# Hence the weirdness....
+.dep1: $(CFILES)
+ rm -f .dep2 .dep2a
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ echo > .dep2a
+ $(DEP) -f .dep2a $(INCLUDES) $(CFLAGS) $?
+ sed -e '/DO NOT DELETE/d' -e '/^$$/d' < .dep2a >> .dep2
+ rm -f .dep2a
+ $(SHELL) $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@BFD_H@!$(BFD_H)!' \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+host-aout.lo: Makefile
+
+# The following program can be used to generate a simple config file
+# which can be folded into an h-XXX file for a new host, with some editing.
+aout-params.h: gen-aout
+ ./gen-aout host > aout-params.h
+gen-aout: $(srcdir)/gen-aout.c Makefile
+ $(CC) -o gen-aout $(CFLAGS) $(LFLAGS) $(srcdir)/gen-aout.c
+
+$(BFD_H): stmp-bfd-h ; @true
+
+stmp-bfd-h: bfd-in3.h
+ rm -f bfd-tmp.h
+ cp bfd-in3.h bfd-tmp.h
+ $(SHELL) $(srcdir)/../move-if-change bfd-tmp.h $(BFD_H)
+ rm -f bfd-tmp.h
+ touch stmp-bfd-h
+
+BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \
+ reloc.c syms.c bfd.c archive.c corefile.c targets.c format.c
+LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c cache.c reloc.c archures.c elf.c
+LIBCOFF_H_FILES = libcoff-in.h coffcode.h
+
+# Could really use a "copy-if-change"...
+headers:
+ (cd $(docdir); $(MAKE) protos $(FLAGS_TO_PASS))
+ cp $(docdir)/bfd.h bfd-in2.h-new
+ $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
+ cp $(docdir)/libbfd.h libbfd.h-new
+ $(SHELL) $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h
+ cp $(docdir)/libcoff.h libcoff.h-new
+ $(SHELL) $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h
+
+# We only rebuild the header files automatically if we have been
+# configured with --enable-maintainer-mode.
+
+$(srcdir)/bfd-in2.h: @MAINT@ stmp-bin2-h ; @true
+stmp-bin2-h: $(BFD_H_FILES)
+ (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
+ cp $(docdir)/bfd.h bfd-in2.h-new
+ $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
+ touch stmp-bin2-h
+
+$(srcdir)/libbfd.h: @MAINT@ stmp-lbfd-h ; @true
+stmp-lbfd-h: $(LIBBFD_H_FILES)
+ (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) libbfd.h)
+ cp $(docdir)/libbfd.h libbfd.h-new
+ $(SHELL) $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h
+ touch stmp-lbfd-h
+
+$(srcdir)/libcoff.h: @MAINT@ stmp-lcoff-h ; @true
+stmp-lcoff-h: $(LIBCOFF_H_FILES)
+ (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) libcoff.h)
+ cp $(docdir)/libcoff.h libcoff.h-new
+ $(SHELL) $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h
+ touch stmp-lcoff-h
+
+MOSTLYCLEANFILES = elf32-target.h elf64-target.h ofiles stamp-ofiles \
+ targmatch.h
+
+CLEANFILES = bfd.h dep.sed stmp-bfd-h .dep .dep1 libbfd.a stamp-lib \
+ stmp-bin2-h stmp-lbfd-h stmp-lcoff-h
+
+# We want to rerun configure if config.bfd or configure.host change.
+config.status: $(srcdir)/configure $(srcdir)/config.bfd $(srcdir)/configure.host
+ $(SHELL) ./config.status --recheck
+
+
+elfarm-oabi.lo: elfarm-oabi.c elf32-arm.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+elfarm-nabi.lo: elfarm-nabi.c elf32-arm.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+archive.lo: archive.c $(INCDIR)/aout/ar.h $(INCDIR)/aout/ranlib.h
+archures.lo: archures.c
+bfd.lo: bfd.c $(INCDIR)/libiberty.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h libcoff.h \
+ libecoff.h $(INCDIR)/coff/ecoff.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
+cache.lo: cache.c
+coffgen.lo: coffgen.c $(INCDIR)/coff/internal.h libcoff.h \
+ $(INCDIR)/bfdlink.h
+corefile.lo: corefile.c
+format.lo: format.c
+init.lo: init.c
+libbfd.lo: libbfd.c
+opncls.lo: opncls.c $(INCDIR)/objalloc.h
+reloc.lo: reloc.c $(INCDIR)/bfdlink.h
+section.lo: section.c $(INCDIR)/bfdlink.h
+syms.lo: syms.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def
+targets.lo: targets.c $(INCDIR)/fnmatch.h targmatch.h
+hash.lo: hash.c $(INCDIR)/objalloc.h
+linker.lo: linker.c $(INCDIR)/bfdlink.h genlink.h
+srec.lo: srec.c $(INCDIR)/libiberty.h
+binary.lo: binary.c
+tekhex.lo: tekhex.c $(INCDIR)/libiberty.h
+ihex.lo: ihex.c $(INCDIR)/libiberty.h
+stabs.lo: stabs.c $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+stab-syms.lo: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def
+cpu-a29k.lo: cpu-a29k.c
+cpu-alpha.lo: cpu-alpha.c
+cpu-arc.lo: cpu-arc.c
+cpu-arm.lo: cpu-arm.c
+cpu-d10v.lo: cpu-d10v.c
+cpu-d30v.lo: cpu-d30v.c
+cpu-fr30.lo: cpu-fr30.c
+cpu-h8300.lo: cpu-h8300.c
+cpu-h8500.lo: cpu-h8500.c
+cpu-hppa.lo: cpu-hppa.c
+cpu-i386.lo: cpu-i386.c
+cpu-i860.lo: cpu-i860.c
+cpu-i960.lo: cpu-i960.c
+cpu-m32r.lo: cpu-m32r.c
+cpu-m68k.lo: cpu-m68k.c
+cpu-m88k.lo: cpu-m88k.c
+cpu-m10200.lo: cpu-m10200.c
+cpu-m10300.lo: cpu-m10300.c
+cpu-mcore.lo: cpu-mcore.c
+cpu-mips.lo: cpu-mips.c
+cpu-ns32k.lo: cpu-ns32k.c ns32k.h
+cpu-powerpc.lo: cpu-powerpc.c
+cpu-rs6000.lo: cpu-rs6000.c
+cpu-sh.lo: cpu-sh.c
+cpu-sparc.lo: cpu-sparc.c
+cpu-tic30.lo: cpu-tic30.c
+cpu-tic80.lo: cpu-tic80.c
+cpu-v850.lo: cpu-v850.c
+cpu-vax.lo: cpu-vax.c
+cpu-we32k.lo: cpu-we32k.c
+cpu-w65.lo: cpu-w65.c
+cpu-z8k.lo: cpu-z8k.c
+aout-adobe.lo: aout-adobe.c $(INCDIR)/aout/adobe.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h \
+ $(INCDIR)/bfdlink.h
+aout-arm.lo: aout-arm.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aoutx.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+aout-ns32k.lo: aout-ns32k.c $(INCDIR)/aout/aout64.h \
+ ns32k.h libaout.h $(INCDIR)/bfdlink.h
+aout-sparcle.lo: aout-sparcle.c $(INCDIR)/bfdlink.h \
+ libaout.h aoutf1.h $(INCDIR)/aout/sun4.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+aout-tic30.lo: aout-tic30.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h aoutx.h
+aout0.lo: aout0.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+aout32.lo: aout32.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h
+bout.lo: bout.c $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/bout.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h
+cf-i386lynx.lo: cf-i386lynx.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+cf-m68klynx.lo: cf-m68klynx.c coff-m68k.c $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+cf-sparclynx.lo: cf-sparclynx.c coff-sparc.c $(INCDIR)/coff/sparc.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-a29k.lo: coff-a29k.c $(INCDIR)/coff/a29k.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-apollo.lo: coff-apollo.c $(INCDIR)/coff/apollo.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-arm.lo: coff-arm.c $(INCDIR)/coff/arm.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-aux.lo: coff-aux.c $(INCDIR)/coff/aux-coff.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h coff-m68k.c libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-h8300.lo: coff-h8300.c $(INCDIR)/bfdlink.h genlink.h \
+ $(INCDIR)/coff/h8300.h $(INCDIR)/coff/internal.h libcoff.h \
+ coffcode.h coffswap.h
+coff-h8500.lo: coff-h8500.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/h8500.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-i386.lo: coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-i860.lo: coff-i860.c $(INCDIR)/coff/i860.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-go32.lo: coff-go32.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-i960.lo: coff-i960.c $(INCDIR)/coff/i960.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-m68k.lo: coff-m68k.c $(INCDIR)/coff/m68k.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-m88k.lo: coff-m88k.c $(INCDIR)/coff/m88k.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-mips.lo: coff-mips.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/mips.h libcoff.h libecoff.h coffswap.h \
+ ecoffswap.h
+coff-pmac.lo: coff-pmac.c coff-rs6000.c $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-rs6000.lo: coff-rs6000.c $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-sh.lo: coff-sh.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/sh.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-sparc.lo: coff-sparc.c $(INCDIR)/coff/sparc.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-stgo32.lo: coff-stgo32.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/go32exe.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h \
+ go32stub.h
+coff-svm68k.lo: coff-svm68k.c coff-m68k.c $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-tic30.lo: coff-tic30.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/tic30.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-tic80.lo: coff-tic80.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/tic80.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-u68k.lo: coff-u68k.c coff-m68k.c $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-we32k.lo: coff-we32k.c $(INCDIR)/coff/we32k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-w65.lo: coff-w65.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/w65.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-z8k.lo: coff-z8k.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/z8k.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+cofflink.lo: cofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ libcoff.h
+dwarf2.lo: dwarf2.c $(INCDIR)/libiberty.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/elf/dwarf2.h
+ecoff.lo: ecoff.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/ar.h \
+ $(INCDIR)/aout/ranlib.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ libaout.h $(INCDIR)/aout/aout64.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ libcoff.h libecoff.h
+ecofflink.lo: ecofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/objalloc.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ libcoff.h libecoff.h
+elf.lo: elf.c $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
+elf32-arc.lo: elf32-arc.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elfarm-oabi.lo: elfarm-oabi.c $(INCDIR)/elf/arm-oabi.h \
+ $(INCDIR)/elf/reloc-macros.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-arm.h elf32-target.h
+elfarm-nabi.lo: elfarm-nabi.c $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h \
+ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf32-arm.h \
+ elf32-target.h
+elf32-d10v.lo: elf32-d10v.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-d30v.lo: elf32-d30v.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-fr30.lo: elf32-fr30.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/fr30.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-gen.lo: elf32-gen.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-hppa.lo: elf32-hppa.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ elf32-hppa.h libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h \
+ hppa_stubs.h elf32-target.h
+elf32-i386.lo: elf32-i386.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/i386.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-i860.lo: elf32-i860.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-m32r.lo: elf32-m32r.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/m32r.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-m68k.lo: elf32-m68k.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/m68k.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-m88k.lo: elf32-m88k.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf-m10200.lo: elf-m10200.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf-m10300.lo: elf-m10300.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/mn10300.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-mcore.lo: elf32-mcore.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-mips.lo: elf32-mips.c $(INCDIR)/bfdlink.h genlink.h \
+ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/mips.h ecoffswap.h \
+ elf32-target.h
+elf32-ppc.lo: elf32-ppc.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-sh.lo: elf32-sh.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-sparc.lo: elf32-sparc.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-v850.lo: elf32-v850.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32.lo: elf32.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ elfcore.h elflink.h
+elflink.lo: elflink.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
+hp300bsd.lo: hp300bsd.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+hp300hpux.lo: hp300hpux.c $(INCDIR)/aout/hp300hpux.h \
+ aoutx.h $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+som.lo: som.c
+i386aout.lo: i386aout.c $(INCDIR)/aout/aout64.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386bsd.lo: i386bsd.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386dynix.lo: i386dynix.c $(INCDIR)/aout/dynix3.h aoutx.h \
+ $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+i386freebsd.lo: i386freebsd.c freebsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386linux.lo: i386linux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+i386lynx.lo: i386lynx.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386msdos.lo: i386msdos.c libaout.h $(INCDIR)/bfdlink.h
+i386netbsd.lo: i386netbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386mach3.lo: i386mach3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+i386os9k.lo: i386os9k.c $(INCDIR)/bfdlink.h libaout.h \
+ $(INCDIR)/os9k.h
+ieee.lo: ieee.c $(INCDIR)/ieee.h libieee.h
+m68k4knetbsd.lo: m68k4knetbsd.c netbsd.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+m68klinux.lo: m68klinux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+m68klynx.lo: m68klynx.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+m68knetbsd.lo: m68knetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+m88kmach3.lo: m88kmach3.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+mipsbsd.lo: mipsbsd.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+newsos3.lo: newsos3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+nlm.lo: nlm.c libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h
+nlm32-i386.lo: nlm32-i386.c $(INCDIR)/nlm/i386-ext.h \
+ libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h
+nlm32-sparc.lo: nlm32-sparc.c $(INCDIR)/nlm/sparc32-ext.h \
+ libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h
+nlm32-ppc.lo: nlm32-ppc.c $(INCDIR)/nlm/ppc-ext.h libnlm.h \
+ $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h \
+ nlmswap.h nlm-target.h
+nlm32.lo: nlm32.c nlmcode.h libnlm.h $(INCDIR)/nlm/common.h \
+ $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h
+ns32knetbsd.lo: ns32knetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+oasys.lo: oasys.c $(INCDIR)/oasys.h liboasys.h
+pc532-mach.lo: pc532-mach.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+pe-arm.lo: pe-arm.c coff-arm.c $(INCDIR)/coff/arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-arm.lo: pei-arm.c coff-arm.c $(INCDIR)/coff/arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pe-i386.lo: pe-i386.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-i386.lo: pei-i386.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pe-mcore.lo: pe-mcore.c coff-mcore.c $(INCDIR)/coff/mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-mcore.lo: pei-mcore.c coff-mcore.c $(INCDIR)/coff/mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pe-ppc.lo: pe-ppc.c coff-ppc.c $(INCDIR)/coff/powerpc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-ppc.lo: pei-ppc.c coff-ppc.c $(INCDIR)/coff/powerpc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+ppcboot.lo: ppcboot.c
+reloc16.lo: reloc16.c $(INCDIR)/bfdlink.h genlink.h \
+ $(INCDIR)/coff/internal.h libcoff.h
+riscix.lo: riscix.c libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ aout-target.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h
+sparclinux.lo: sparclinux.c $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ libaout.h $(INCDIR)/bfdlink.h aout-target.h
+sparclynx.lo: sparclynx.c $(INCDIR)/aout/sun4.h libaout.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+sparcnetbsd.lo: sparcnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+sunos.lo: sunos.c $(INCDIR)/bfdlink.h libaout.h aoutf1.h \
+ $(INCDIR)/aout/sun4.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+vaxnetbsd.lo: vaxnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+versados.lo: versados.c $(INCDIR)/libiberty.h
+vms.lo: vms.c $(INCDIR)/bfdlink.h vms.h
+vms-gsd.lo: vms-gsd.c $(INCDIR)/bfdlink.h vms.h
+vms-hdr.lo: vms-hdr.c $(INCDIR)/bfdlink.h vms.h
+vms-misc.lo: vms-misc.c $(INCDIR)/bfdlink.h vms.h
+vms-tir.lo: vms-tir.c $(INCDIR)/bfdlink.h vms.h
+xcofflink.lo: xcofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ libcoff.h
+aout64.lo: aout64.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h
+coff-alpha.lo: coff-alpha.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h libcoff.h \
+ libecoff.h coffswap.h ecoffswap.h
+demo64.lo: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h \
+ libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+elf64-alpha.lo: elf64-alpha.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h \
+ libcoff.h libecoff.h ecoffswap.h elf64-target.h
+elf64-gen.lo: elf64-gen.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf64-target.h
+elf64-mips.lo: elf64-mips.c $(INCDIR)/aout/ar.h $(INCDIR)/bfdlink.h \
+ genlink.h elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/alpha.h ecoffswap.h \
+ elf64-target.h
+elf64-sparc.lo: elf64-sparc.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h \
+ elf64-target.h
+elf64.lo: elf64.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ elfcore.h elflink.h
+nlm32-alpha.lo: nlm32-alpha.c $(INCDIR)/nlm/alpha-ext.h \
+ libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h
+nlm64.lo: nlm64.c nlmcode.h libnlm.h $(INCDIR)/nlm/common.h \
+ $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h
+aix386-core.lo: aix386-core.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h
+hpux-core.lo: hpux-core.c
+irix-core.lo: irix-core.c
+lynx-core.lo: lynx-core.c
+osf-core.lo: osf-core.c
+sco5-core.lo: sco5-core.c libaout.h $(INCDIR)/bfdlink.h
+trad-core.lo: trad-core.c libaout.h $(INCDIR)/bfdlink.h \
+ hosts/i386linux.h
+cisco-core.lo: cisco-core.c
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
new file mode 100644
index 00000000000..9258df13b2f
--- /dev/null
+++ b/bfd/Makefile.in
@@ -0,0 +1,1599 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AR = @AR@
+AS = @AS@
+BFD_HOST_64BIT_LONG = @BFD_HOST_64BIT_LONG@
+BFD_HOST_64_BIT = @BFD_HOST_64_BIT@
+BFD_HOST_64_BIT_DEFINED = @BFD_HOST_64_BIT_DEFINED@
+BFD_HOST_U_64_BIT = @BFD_HOST_U_64_BIT@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+COREFILE = @COREFILE@
+COREFLAG = @COREFLAG@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+HDEFINES = @HDEFINES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+TDEFINES = @TDEFINES@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WIN32LDFLAGS = @WIN32LDFLAGS@
+WIN32LIBADD = @WIN32LIBADD@
+all_backends = @all_backends@
+bfd_backends = @bfd_backends@
+bfd_machines = @bfd_machines@
+l = @l@
+tdefaults = @tdefaults@
+wordsize = @wordsize@
+
+AUTOMAKE_OPTIONS = cygnus
+
+INCDIR = $(srcdir)/../include
+CSEARCH = -I. -I$(srcdir) -I$(INCDIR)
+DEP = mkdep
+
+SUBDIRS = doc po
+
+docdir = doc
+
+lib_LTLIBRARIES = libbfd.la
+
+# bfd.h goes here, for now
+BFD_H = bfd.h
+
+# Jim Kingdon notes:
+# Writing S-records should be included in all (or at least most)
+# *-*-coff, *-*-aout, etc., configurations, because people will want to
+# be able to use objcopy to create S-records. (S-records are not useful
+# for the debugger, so if you are downloading things as S-records you
+# need two copies of the executable, one to download and one for the
+# debugger).
+BFD_LIBS = \
+ archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
+ format.lo init.lo libbfd.lo opncls.lo reloc.lo \
+ section.lo syms.lo targets.lo hash.lo linker.lo \
+ srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo
+
+
+BFD_LIBS_CFILES = \
+ archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
+ format.c init.c libbfd.c opncls.c reloc.c \
+ section.c syms.c targets.c hash.c linker.c \
+ srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c
+
+
+# This list is alphabetized to make it easier to keep in sync
+# with the decls and initializer in archures.c.
+ALL_MACHINES = \
+ cpu-a29k.lo \
+ cpu-alpha.lo \
+ cpu-arc.lo \
+ cpu-arm.lo \
+ cpu-d10v.lo \
+ cpu-d30v.lo \
+ cpu-fr30.lo \
+ cpu-h8300.lo \
+ cpu-h8500.lo \
+ cpu-hppa.lo \
+ cpu-i386.lo \
+ cpu-i860.lo \
+ cpu-i960.lo \
+ cpu-m32r.lo \
+ cpu-m68k.lo \
+ cpu-m88k.lo \
+ cpu-m10200.lo \
+ cpu-m10300.lo \
+ cpu-mcore.lo \
+ cpu-mips.lo \
+ cpu-ns32k.lo \
+ cpu-powerpc.lo \
+ cpu-rs6000.lo \
+ cpu-sh.lo \
+ cpu-sparc.lo \
+ cpu-tic30.lo \
+ cpu-tic80.lo \
+ cpu-v850.lo \
+ cpu-vax.lo \
+ cpu-we32k.lo \
+ cpu-w65.lo \
+ cpu-z8k.lo
+
+
+ALL_MACHINES_CFILES = \
+ cpu-a29k.c \
+ cpu-alpha.c \
+ cpu-arc.c \
+ cpu-arm.c \
+ cpu-d10v.c \
+ cpu-d30v.c \
+ cpu-fr30.c \
+ cpu-h8300.c \
+ cpu-h8500.c \
+ cpu-hppa.c \
+ cpu-i386.c \
+ cpu-i860.c \
+ cpu-i960.c \
+ cpu-m32r.c \
+ cpu-m68k.c \
+ cpu-m88k.c \
+ cpu-m10200.c \
+ cpu-m10300.c \
+ cpu-mcore.c \
+ cpu-mips.c \
+ cpu-ns32k.c \
+ cpu-powerpc.c \
+ cpu-rs6000.c \
+ cpu-sh.c \
+ cpu-sparc.c \
+ cpu-tic30.c \
+ cpu-tic80.c \
+ cpu-v850.c \
+ cpu-vax.c \
+ cpu-we32k.c \
+ cpu-w65.c \
+ cpu-z8k.c
+
+
+# The .o files needed by all of the 32 bit vectors that are configured into
+# target_vector in targets.c if configured with --enable-targets=all.
+BFD32_BACKENDS = \
+ aout-adobe.lo \
+ aout-arm.lo \
+ aout-ns32k.lo \
+ aout-sparcle.lo \
+ aout-tic30.lo \
+ aout0.lo \
+ aout32.lo \
+ bout.lo \
+ cf-i386lynx.lo \
+ cf-m68klynx.lo \
+ cf-sparclynx.lo \
+ coff-a29k.lo \
+ coff-apollo.lo \
+ coff-arm.lo \
+ coff-aux.lo \
+ coff-h8300.lo \
+ coff-h8500.lo \
+ coff-i386.lo \
+ coff-go32.lo \
+ coff-i860.lo \
+ coff-i960.lo \
+ coff-m68k.lo \
+ coff-m88k.lo \
+ coff-mips.lo \
+ coff-pmac.lo \
+ coff-rs6000.lo \
+ coff-sh.lo \
+ coff-sparc.lo \
+ coff-stgo32.lo \
+ coff-svm68k.lo \
+ coff-tic30.lo \
+ coff-tic80.lo \
+ coff-u68k.lo \
+ coff-we32k.lo \
+ coff-w65.lo \
+ coff-z8k.lo \
+ cofflink.lo \
+ dwarf2.lo \
+ ecoff.lo \
+ ecofflink.lo \
+ elf.lo \
+ elf32-arc.lo \
+ elfarm-oabi.lo \
+ elfarm-nabi.lo \
+ elf32-d10v.lo \
+ elf32-d30v.lo \
+ elf32-fr30.lo \
+ elf32-gen.lo \
+ elf32-hppa.lo \
+ elf32-i386.lo \
+ elf32-i860.lo \
+ elf32-m32r.lo \
+ elf32-m68k.lo \
+ elf32-m88k.lo \
+ elf-m10200.lo \
+ elf-m10300.lo \
+ elf32-mcore.lo \
+ elf32-mips.lo \
+ elf32-ppc.lo \
+ elf32-sh.lo \
+ elf32-sparc.lo \
+ elf32-v850.lo \
+ elf32.lo \
+ elflink.lo \
+ hp300bsd.lo \
+ hp300hpux.lo \
+ som.lo \
+ i386aout.lo \
+ i386bsd.lo \
+ i386dynix.lo \
+ i386freebsd.lo \
+ i386linux.lo \
+ i386lynx.lo \
+ i386msdos.lo \
+ i386netbsd.lo \
+ i386mach3.lo \
+ i386os9k.lo \
+ ieee.lo \
+ m68k4knetbsd.lo \
+ m68klinux.lo \
+ m68klynx.lo \
+ m68knetbsd.lo \
+ m88kmach3.lo \
+ mipsbsd.lo \
+ newsos3.lo \
+ nlm.lo \
+ nlm32-i386.lo \
+ nlm32-sparc.lo \
+ nlm32-ppc.lo \
+ nlm32.lo \
+ ns32knetbsd.lo \
+ oasys.lo \
+ pc532-mach.lo \
+ pe-arm.lo \
+ pei-arm.lo \
+ pe-i386.lo \
+ pei-i386.lo \
+ pe-mcore.lo \
+ pei-mcore.lo \
+ pe-ppc.lo \
+ pei-ppc.lo \
+ ppcboot.lo \
+ reloc16.lo \
+ riscix.lo \
+ sparclinux.lo \
+ sparclynx.lo \
+ sparcnetbsd.lo \
+ sunos.lo \
+ vaxnetbsd.lo \
+ versados.lo \
+ vms.lo \
+ vms-gsd.lo \
+ vms-hdr.lo \
+ vms-misc.lo \
+ vms-tir.lo \
+ xcofflink.lo
+
+
+BFD32_BACKENDS_CFILES = \
+ aout-adobe.c \
+ aout-arm.c \
+ aout-ns32k.c \
+ aout-sparcle.c \
+ aout-tic30.c \
+ aout0.c \
+ aout32.c \
+ bout.c \
+ cf-i386lynx.c \
+ cf-m68klynx.c \
+ cf-sparclynx.c \
+ coff-a29k.c \
+ coff-apollo.c \
+ coff-arm.c \
+ coff-aux.c \
+ coff-h8300.c \
+ coff-h8500.c \
+ coff-i386.c \
+ coff-i860.c \
+ coff-go32.c \
+ coff-i960.c \
+ coff-m68k.c \
+ coff-m88k.c \
+ coff-mips.c \
+ coff-pmac.c \
+ coff-rs6000.c \
+ coff-sh.c \
+ coff-sparc.c \
+ coff-stgo32.c \
+ coff-svm68k.c \
+ coff-tic30.c \
+ coff-tic80.c \
+ coff-u68k.c \
+ coff-we32k.c \
+ coff-w65.c \
+ coff-z8k.c \
+ cofflink.c \
+ dwarf2.c \
+ ecoff.c \
+ ecofflink.c \
+ elf.c \
+ elf32-arc.c \
+ elfarm-oabi.c \
+ elfarm-nabi.c \
+ elf32-d10v.c \
+ elf32-d30v.c \
+ elf32-fr30.c \
+ elf32-gen.c \
+ elf32-hppa.c \
+ elf32-i386.c \
+ elf32-i860.c \
+ elf32-m32r.c \
+ elf32-m68k.c \
+ elf32-m88k.c \
+ elf-m10200.c \
+ elf-m10300.c \
+ elf32-mcore.c \
+ elf32-mips.c \
+ elf32-ppc.c \
+ elf32-sh.c \
+ elf32-sparc.c \
+ elf32-v850.c \
+ elf32.c \
+ elflink.c \
+ hp300bsd.c \
+ hp300hpux.c \
+ som.c \
+ i386aout.c \
+ i386bsd.c \
+ i386dynix.c \
+ i386freebsd.c \
+ i386linux.c \
+ i386lynx.c \
+ i386msdos.c \
+ i386netbsd.c \
+ i386mach3.c \
+ i386os9k.c \
+ ieee.c \
+ m68k4knetbsd.c \
+ m68klinux.c \
+ m68klynx.c \
+ m68knetbsd.c \
+ m88kmach3.c \
+ mipsbsd.c \
+ newsos3.c \
+ nlm.c \
+ nlm32-i386.c \
+ nlm32-sparc.c \
+ nlm32-ppc.c \
+ nlm32.c \
+ ns32knetbsd.c \
+ oasys.c \
+ pc532-mach.c \
+ pe-arm.c \
+ pei-arm.c \
+ pe-i386.c \
+ pei-i386.c \
+ pe-mcore.c \
+ pei-mcore.c \
+ pe-ppc.c \
+ pei-ppc.c \
+ ppcboot.c \
+ reloc16.c \
+ riscix.c \
+ sparclinux.c \
+ sparclynx.c \
+ sparcnetbsd.c \
+ sunos.c \
+ vaxnetbsd.c \
+ versados.c \
+ vms.c \
+ vms-gsd.c \
+ vms-hdr.c \
+ vms-misc.c \
+ vms-tir.c \
+ xcofflink.c
+
+
+# The .o files needed by all of the 64 bit vectors that are configured into
+# target_vector in targets.c if configured with --enable-targets=all
+# and --enable-64-bit-bfd.
+BFD64_BACKENDS = \
+ aout64.lo \
+ coff-alpha.lo \
+ demo64.lo \
+ elf64-alpha.lo \
+ elf64-gen.lo \
+ elf64-mips.lo \
+ elf64-sparc.lo \
+ elf64.lo \
+ nlm32-alpha.lo \
+ nlm64.lo
+
+
+BFD64_BACKENDS_CFILES = \
+ aout64.c \
+ coff-alpha.c \
+ demo64.c \
+ elf64-alpha.c \
+ elf64-gen.c \
+ elf64-mips.c \
+ elf64-sparc.c \
+ elf64.c \
+ nlm32-alpha.c \
+ nlm64.c
+
+
+OPTIONAL_BACKENDS = \
+ aix386-core.lo \
+ hpux-core.lo \
+ irix-core.lo \
+ lynx-core.lo \
+ osf-core.lo \
+ sco5-core.lo \
+ trad-core.lo \
+ cisco-core.lo
+
+
+OPTIONAL_BACKENDS_CFILES = \
+ aix386-core.c \
+ hpux-core.c \
+ irix-core.c \
+ lynx-core.c \
+ osf-core.c \
+ sco5-core.c \
+ trad-core.c \
+ cisco-core.c
+
+
+# These are defined by configure.in:
+WORDSIZE = @wordsize@
+ALL_BACKENDS = @all_backends@
+BFD_BACKENDS = @bfd_backends@
+BFD_MACHINES = @bfd_machines@
+TDEFAULTS = @tdefaults@
+
+INCLUDES = -D_GNU_SOURCE @HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES) -I$(srcdir)/../intl -I../intl
+
+# C source files that correspond to .o's.
+CFILES = \
+ $(BFD_LIBS_CFILES) \
+ $(ALL_MACHINES_CFILES) \
+ $(BFD32_BACKENDS_CFILES) \
+ $(BFD64_BACKENDS_CFILES) \
+ $(OPTIONAL_BACKENDS_CFILES)
+
+
+SOURCE_HFILES = \
+ aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h \
+ ecoffswap.h elf32-hppa.h \
+ elfcode.h genlink.h go32stub.h hppa_stubs.h libaout.h \
+ libbfd.h libcoff.h libecoff.h elf-bfd.h libhppa.h libieee.h \
+ libnlm.h liboasys.h netbsd.h nlm-target.h nlmcode.h ns32k.h \
+ som.h vms.h
+
+
+HFILES = \
+ elf32-target.h elf64-target.h targmatch.h \
+ $(SOURCE_HFILES)
+
+
+POTFILES = $(CFILES) $(SOURCE_HFILES)
+
+# Various kinds of .o files to put in libbfd.a:
+# BFD_BACKENDS Routines the configured targets need.
+# BFD_MACHINES Architecture-specific routines the configured targets need.
+# COREFILE Core file routines for a native configuration
+OFILES = $(BFD_BACKENDS) $(BFD_MACHINES) @COREFILE@
+
+libbfd_la_SOURCES = $(BFD_LIBS_CFILES)
+libbfd_la_DEPENDENCIES = $(OFILES) ofiles
+libbfd_la_LIBADD = `cat ofiles` @WIN32LIBADD@
+libbfd_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
+
+# libtool will build .libs/libbfd.a. We create libbfd.a in the build
+# directory so that we don't have to convert all the programs that use
+# libbfd.a simultaneously. This is a hack which should be removed if
+# everything else starts using libtool. FIXME.
+
+noinst_LIBRARIES = libbfd.a
+libbfd_a_SOURCES =
+
+BFD_H_DEPS = $(INCDIR)/ansidecl.h
+LOCAL_H_DEPS = libbfd.h sysdep.h config.h
+
+BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \
+ reloc.c syms.c bfd.c archive.c corefile.c targets.c format.c
+
+LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c cache.c reloc.c archures.c elf.c
+LIBCOFF_H_FILES = libcoff-in.h coffcode.h
+
+MOSTLYCLEANFILES = elf32-target.h elf64-target.h ofiles stamp-ofiles \
+ targmatch.h
+
+
+CLEANFILES = bfd.h dep.sed stmp-bfd-h .dep .dep1 libbfd.a stamp-lib \
+ stmp-bin2-h stmp-lbfd-h stmp-lcoff-h
+
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = bfd-in3.h
+LIBRARIES = $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libbfd_a_LIBADD =
+libbfd_a_OBJECTS =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libbfd_la_OBJECTS = archive.lo archures.lo bfd.lo cache.lo coffgen.lo \
+corefile.lo format.lo init.lo libbfd.lo opncls.lo reloc.lo section.lo \
+syms.lo targets.lo hash.lo linker.lo srec.lo binary.lo tekhex.lo \
+ihex.lo stabs.lo stab-syms.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = README ./stamp-h.in COPYING ChangeLog Makefile.am \
+Makefile.in TODO acinclude.m4 aclocal.m4 bfd-in2.h config.in configure \
+configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES)
+OBJECTS = $(libbfd_a_OBJECTS) $(libbfd_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+bfd-in3.h: $(top_builddir)/config.status bfd-in2.h
+ cd $(top_builddir) && CONFIG_FILES=$@:bfd-in2.h CONFIG_HEADERS= $(SHELL) ./config.status
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+libbfd.la: $(libbfd_la_OBJECTS) $(libbfd_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libbfd_la_LDFLAGS) $(libbfd_la_OBJECTS) $(libbfd_la_LIBADD) $(LIBS)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am:
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-recursive
+
+install-data-am: install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-libLTLIBRARIES
+uninstall: uninstall-recursive
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-noinstLIBRARIES \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-libLTLIBRARIES mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-noinstLIBRARIES clean-compile clean-libtool \
+ clean-libLTLIBRARIES clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-noinstLIBRARIES distclean-compile \
+ distclean-libtool distclean-libLTLIBRARIES \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-libLTLIBRARIES maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool mostlyclean-libLTLIBRARIES \
+distclean-libLTLIBRARIES clean-libLTLIBRARIES \
+maintainer-clean-libLTLIBRARIES uninstall-libLTLIBRARIES \
+install-libLTLIBRARIES install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-info-am \
+install-info all-recursive-am install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+diststuff: info
+
+stamp-ofiles: Makefile
+ rm -f tofiles
+ f=""; \
+ for i in $(OFILES) ; do \
+ case " $$f " in \
+ *" $$i "*) ;; \
+ *) f="$$f $$i" ;; \
+ esac ; \
+ done ; \
+ echo $$f > tofiles
+ $(SHELL) $(srcdir)/../move-if-change tofiles ofiles
+ touch stamp-ofiles
+
+ofiles: stamp-ofiles ; @true
+
+stamp-lib: libbfd.la
+ if [ -f .libs/libbfd.a ]; then \
+ cp .libs/libbfd.a libbfd.tmp; \
+ $(SHELL) $(srcdir)/../move-if-change libbfd.tmp libbfd.a; \
+ else true; fi
+ touch stamp-lib
+
+libbfd.a: stamp-lib ; @true
+
+# This file holds an array associating configuration triplets and
+# vector names. It is built from config.bfd. It is not compiled by
+# itself, but is included by targets.c.
+targmatch.h: config.bfd targmatch.sed
+ rm -f targmatch.h
+ sed -f $(srcdir)/targmatch.sed < $(srcdir)/config.bfd > targmatch.new
+ mv -f targmatch.new targmatch.h
+
+# When compiling archures.c and targets.c, supply the default target
+# info from configure.
+
+targets.lo: targets.c config.status
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $(TDEFAULTS) $(srcdir)/targets.c
+
+archures.lo: archures.c config.status
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $(TDEFAULTS) $(srcdir)/archures.c
+
+elf32-target.h : elfxx-target.h
+ rm -f elf32-target.h
+ sed -e s/NN/32/g < $(srcdir)/elfxx-target.h > elf32-target.new
+ mv -f elf32-target.new elf32-target.h
+
+elf64-target.h : elfxx-target.h
+ rm -f elf64-target.h
+ sed -e s/NN/64/g < $(srcdir)/elfxx-target.h > elf64-target.new
+ mv -f elf64-target.new elf64-target.h
+$(BFD_LIBS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+$(BFD_MACHINES): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+$(BFD_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+$(OPTIONAL_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+
+# Install BFD include file, and others that it needs.
+install-data-local: $(BFD_H)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(includedir)
+ $(INSTALL_DATA) $(BFD_H) $(includedir)/bfd.h
+ $(INSTALL_DATA) $(INCDIR)/ansidecl.h $(includedir)/ansidecl.h
+ $(INSTALL_DATA) $(INCDIR)/bfdlink.h $(includedir)/bfdlink.h
+
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) bfd.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+# The NetBSD mkdep overwrites any existing file contents, and doesn't insert
+# the "DO NOT DELETE" line.
+# Other mkdep versions require a file that already exists, and do insert it.
+# Hence the weirdness....
+.dep1: $(CFILES)
+ rm -f .dep2 .dep2a
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ echo > .dep2a
+ $(DEP) -f .dep2a $(INCLUDES) $(CFLAGS) $?
+ sed -e '/DO NOT DELETE/d' -e '/^$$/d' < .dep2a >> .dep2
+ rm -f .dep2a
+ $(SHELL) $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@BFD_H@!$(BFD_H)!' \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+host-aout.lo: Makefile
+
+# The following program can be used to generate a simple config file
+# which can be folded into an h-XXX file for a new host, with some editing.
+aout-params.h: gen-aout
+ ./gen-aout host > aout-params.h
+gen-aout: $(srcdir)/gen-aout.c Makefile
+ $(CC) -o gen-aout $(CFLAGS) $(LFLAGS) $(srcdir)/gen-aout.c
+
+$(BFD_H): stmp-bfd-h ; @true
+
+stmp-bfd-h: bfd-in3.h
+ rm -f bfd-tmp.h
+ cp bfd-in3.h bfd-tmp.h
+ $(SHELL) $(srcdir)/../move-if-change bfd-tmp.h $(BFD_H)
+ rm -f bfd-tmp.h
+ touch stmp-bfd-h
+
+# Could really use a "copy-if-change"...
+headers:
+ (cd $(docdir); $(MAKE) protos $(FLAGS_TO_PASS))
+ cp $(docdir)/bfd.h bfd-in2.h-new
+ $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
+ cp $(docdir)/libbfd.h libbfd.h-new
+ $(SHELL) $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h
+ cp $(docdir)/libcoff.h libcoff.h-new
+ $(SHELL) $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h
+
+# We only rebuild the header files automatically if we have been
+# configured with --enable-maintainer-mode.
+
+$(srcdir)/bfd-in2.h: @MAINT@ stmp-bin2-h ; @true
+stmp-bin2-h: $(BFD_H_FILES)
+ (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
+ cp $(docdir)/bfd.h bfd-in2.h-new
+ $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
+ touch stmp-bin2-h
+
+$(srcdir)/libbfd.h: @MAINT@ stmp-lbfd-h ; @true
+stmp-lbfd-h: $(LIBBFD_H_FILES)
+ (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) libbfd.h)
+ cp $(docdir)/libbfd.h libbfd.h-new
+ $(SHELL) $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h
+ touch stmp-lbfd-h
+
+$(srcdir)/libcoff.h: @MAINT@ stmp-lcoff-h ; @true
+stmp-lcoff-h: $(LIBCOFF_H_FILES)
+ (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) libcoff.h)
+ cp $(docdir)/libcoff.h libcoff.h-new
+ $(SHELL) $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h
+ touch stmp-lcoff-h
+
+# We want to rerun configure if config.bfd or configure.host change.
+config.status: $(srcdir)/configure $(srcdir)/config.bfd $(srcdir)/configure.host
+ $(SHELL) ./config.status --recheck
+
+
+elfarm-oabi.lo: elfarm-oabi.c elf32-arm.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+elfarm-nabi.lo: elfarm-nabi.c elf32-arm.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+archive.lo: archive.c $(INCDIR)/aout/ar.h $(INCDIR)/aout/ranlib.h
+archures.lo: archures.c
+bfd.lo: bfd.c $(INCDIR)/libiberty.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h libcoff.h \
+ libecoff.h $(INCDIR)/coff/ecoff.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
+cache.lo: cache.c
+coffgen.lo: coffgen.c $(INCDIR)/coff/internal.h libcoff.h \
+ $(INCDIR)/bfdlink.h
+corefile.lo: corefile.c
+format.lo: format.c
+init.lo: init.c
+libbfd.lo: libbfd.c
+opncls.lo: opncls.c $(INCDIR)/objalloc.h
+reloc.lo: reloc.c $(INCDIR)/bfdlink.h
+section.lo: section.c $(INCDIR)/bfdlink.h
+syms.lo: syms.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def
+targets.lo: targets.c $(INCDIR)/fnmatch.h targmatch.h
+hash.lo: hash.c $(INCDIR)/objalloc.h
+linker.lo: linker.c $(INCDIR)/bfdlink.h genlink.h
+srec.lo: srec.c $(INCDIR)/libiberty.h
+binary.lo: binary.c
+tekhex.lo: tekhex.c $(INCDIR)/libiberty.h
+ihex.lo: ihex.c $(INCDIR)/libiberty.h
+stabs.lo: stabs.c $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+stab-syms.lo: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def
+cpu-a29k.lo: cpu-a29k.c
+cpu-alpha.lo: cpu-alpha.c
+cpu-arc.lo: cpu-arc.c
+cpu-arm.lo: cpu-arm.c
+cpu-d10v.lo: cpu-d10v.c
+cpu-d30v.lo: cpu-d30v.c
+cpu-fr30.lo: cpu-fr30.c
+cpu-h8300.lo: cpu-h8300.c
+cpu-h8500.lo: cpu-h8500.c
+cpu-hppa.lo: cpu-hppa.c
+cpu-i386.lo: cpu-i386.c
+cpu-i860.lo: cpu-i860.c
+cpu-i960.lo: cpu-i960.c
+cpu-m32r.lo: cpu-m32r.c
+cpu-m68k.lo: cpu-m68k.c
+cpu-m88k.lo: cpu-m88k.c
+cpu-m10200.lo: cpu-m10200.c
+cpu-m10300.lo: cpu-m10300.c
+cpu-mcore.lo: cpu-mcore.c
+cpu-mips.lo: cpu-mips.c
+cpu-ns32k.lo: cpu-ns32k.c ns32k.h
+cpu-powerpc.lo: cpu-powerpc.c
+cpu-rs6000.lo: cpu-rs6000.c
+cpu-sh.lo: cpu-sh.c
+cpu-sparc.lo: cpu-sparc.c
+cpu-tic30.lo: cpu-tic30.c
+cpu-tic80.lo: cpu-tic80.c
+cpu-v850.lo: cpu-v850.c
+cpu-vax.lo: cpu-vax.c
+cpu-we32k.lo: cpu-we32k.c
+cpu-w65.lo: cpu-w65.c
+cpu-z8k.lo: cpu-z8k.c
+aout-adobe.lo: aout-adobe.c $(INCDIR)/aout/adobe.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h \
+ $(INCDIR)/bfdlink.h
+aout-arm.lo: aout-arm.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aoutx.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+aout-ns32k.lo: aout-ns32k.c $(INCDIR)/aout/aout64.h \
+ ns32k.h libaout.h $(INCDIR)/bfdlink.h
+aout-sparcle.lo: aout-sparcle.c $(INCDIR)/bfdlink.h \
+ libaout.h aoutf1.h $(INCDIR)/aout/sun4.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+aout-tic30.lo: aout-tic30.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h aoutx.h
+aout0.lo: aout0.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+aout32.lo: aout32.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h
+bout.lo: bout.c $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/bout.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def libaout.h
+cf-i386lynx.lo: cf-i386lynx.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+cf-m68klynx.lo: cf-m68klynx.c coff-m68k.c $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+cf-sparclynx.lo: cf-sparclynx.c coff-sparc.c $(INCDIR)/coff/sparc.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-a29k.lo: coff-a29k.c $(INCDIR)/coff/a29k.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-apollo.lo: coff-apollo.c $(INCDIR)/coff/apollo.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-arm.lo: coff-arm.c $(INCDIR)/coff/arm.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-aux.lo: coff-aux.c $(INCDIR)/coff/aux-coff.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/m68k.h coff-m68k.c libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-h8300.lo: coff-h8300.c $(INCDIR)/bfdlink.h genlink.h \
+ $(INCDIR)/coff/h8300.h $(INCDIR)/coff/internal.h libcoff.h \
+ coffcode.h coffswap.h
+coff-h8500.lo: coff-h8500.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/h8500.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-i386.lo: coff-i386.c $(INCDIR)/coff/i386.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-i860.lo: coff-i860.c $(INCDIR)/coff/i860.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-go32.lo: coff-go32.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-i960.lo: coff-i960.c $(INCDIR)/coff/i960.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-m68k.lo: coff-m68k.c $(INCDIR)/coff/m68k.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-m88k.lo: coff-m88k.c $(INCDIR)/coff/m88k.h $(INCDIR)/coff/internal.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h
+coff-mips.lo: coff-mips.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/mips.h libcoff.h libecoff.h coffswap.h \
+ ecoffswap.h
+coff-pmac.lo: coff-pmac.c coff-rs6000.c $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-rs6000.lo: coff-rs6000.c $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/rs6000.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-sh.lo: coff-sh.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/sh.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-sparc.lo: coff-sparc.c $(INCDIR)/coff/sparc.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-stgo32.lo: coff-stgo32.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/go32exe.h \
+ libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h \
+ go32stub.h
+coff-svm68k.lo: coff-svm68k.c coff-m68k.c $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-tic30.lo: coff-tic30.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/tic30.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-tic80.lo: coff-tic80.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/tic80.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-u68k.lo: coff-u68k.c coff-m68k.c $(INCDIR)/coff/m68k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-we32k.lo: coff-we32k.c $(INCDIR)/coff/we32k.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \
+ coffcode.h coffswap.h
+coff-w65.lo: coff-w65.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/w65.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+coff-z8k.lo: coff-z8k.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/z8k.h \
+ $(INCDIR)/coff/internal.h libcoff.h coffcode.h coffswap.h
+cofflink.lo: cofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ libcoff.h
+dwarf2.lo: dwarf2.c $(INCDIR)/libiberty.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/elf/dwarf2.h
+ecoff.lo: ecoff.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/ar.h \
+ $(INCDIR)/aout/ranlib.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ libaout.h $(INCDIR)/aout/aout64.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ libcoff.h libecoff.h
+ecofflink.lo: ecofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/objalloc.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ libcoff.h libecoff.h
+elf.lo: elf.c $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
+elf32-arc.lo: elf32-arc.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elfarm-oabi.lo: elfarm-oabi.c $(INCDIR)/elf/arm-oabi.h \
+ $(INCDIR)/elf/reloc-macros.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-arm.h elf32-target.h
+elfarm-nabi.lo: elfarm-nabi.c $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h \
+ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf32-arm.h \
+ elf32-target.h
+elf32-d10v.lo: elf32-d10v.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-d30v.lo: elf32-d30v.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-fr30.lo: elf32-fr30.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/fr30.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-gen.lo: elf32-gen.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-hppa.lo: elf32-hppa.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ elf32-hppa.h libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h \
+ hppa_stubs.h elf32-target.h
+elf32-i386.lo: elf32-i386.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/i386.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-i860.lo: elf32-i860.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf32-m32r.lo: elf32-m32r.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/m32r.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-m68k.lo: elf32-m68k.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/m68k.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-m88k.lo: elf32-m88k.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf-m10200.lo: elf-m10200.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf32-target.h
+elf-m10300.lo: elf-m10300.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/mn10300.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-mcore.lo: elf32-mcore.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-mips.lo: elf32-mips.c $(INCDIR)/bfdlink.h genlink.h \
+ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/mips.h ecoffswap.h \
+ elf32-target.h
+elf32-ppc.lo: elf32-ppc.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-sh.lo: elf32-sh.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-sparc.lo: elf32-sparc.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h \
+ elf32-target.h
+elf32-v850.lo: elf32-v850.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32.lo: elf32.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ elfcore.h elflink.h
+elflink.lo: elflink.c $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h
+hp300bsd.lo: hp300bsd.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+hp300hpux.lo: hp300hpux.c $(INCDIR)/aout/hp300hpux.h \
+ aoutx.h $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+som.lo: som.c
+i386aout.lo: i386aout.c $(INCDIR)/aout/aout64.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386bsd.lo: i386bsd.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386dynix.lo: i386dynix.c $(INCDIR)/aout/dynix3.h aoutx.h \
+ $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+i386freebsd.lo: i386freebsd.c freebsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386linux.lo: i386linux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+i386lynx.lo: i386lynx.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386msdos.lo: i386msdos.c libaout.h $(INCDIR)/bfdlink.h
+i386netbsd.lo: i386netbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+i386mach3.lo: i386mach3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+i386os9k.lo: i386os9k.c $(INCDIR)/bfdlink.h libaout.h \
+ $(INCDIR)/os9k.h
+ieee.lo: ieee.c $(INCDIR)/ieee.h libieee.h
+m68k4knetbsd.lo: m68k4knetbsd.c netbsd.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+m68klinux.lo: m68klinux.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+m68klynx.lo: m68klynx.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+m68knetbsd.lo: m68knetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+m88kmach3.lo: m88kmach3.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+mipsbsd.lo: mipsbsd.c libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+newsos3.lo: newsos3.c $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h libaout.h \
+ $(INCDIR)/bfdlink.h aout-target.h
+nlm.lo: nlm.c libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h
+nlm32-i386.lo: nlm32-i386.c $(INCDIR)/nlm/i386-ext.h \
+ libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h
+nlm32-sparc.lo: nlm32-sparc.c $(INCDIR)/nlm/sparc32-ext.h \
+ libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h
+nlm32-ppc.lo: nlm32-ppc.c $(INCDIR)/nlm/ppc-ext.h libnlm.h \
+ $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h \
+ nlmswap.h nlm-target.h
+nlm32.lo: nlm32.c nlmcode.h libnlm.h $(INCDIR)/nlm/common.h \
+ $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h
+ns32knetbsd.lo: ns32knetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+oasys.lo: oasys.c $(INCDIR)/oasys.h liboasys.h
+pc532-mach.lo: pc532-mach.c libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h aout-target.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+pe-arm.lo: pe-arm.c coff-arm.c $(INCDIR)/coff/arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-arm.lo: pei-arm.c coff-arm.c $(INCDIR)/coff/arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pe-i386.lo: pe-i386.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-i386.lo: pei-i386.c coff-i386.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pe-mcore.lo: pe-mcore.c coff-mcore.c $(INCDIR)/coff/mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-mcore.lo: pei-mcore.c coff-mcore.c $(INCDIR)/coff/mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pe-ppc.lo: pe-ppc.c coff-ppc.c $(INCDIR)/coff/powerpc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+pei-ppc.lo: pei-ppc.c coff-ppc.c $(INCDIR)/coff/powerpc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \
+ $(INCDIR)/bfdlink.h coffcode.h peicode.h
+ppcboot.lo: ppcboot.c
+reloc16.lo: reloc16.c $(INCDIR)/bfdlink.h genlink.h \
+ $(INCDIR)/coff/internal.h libcoff.h
+riscix.lo: riscix.c libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ aout-target.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h
+sparclinux.lo: sparclinux.c $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ libaout.h $(INCDIR)/bfdlink.h aout-target.h
+sparclynx.lo: sparclynx.c $(INCDIR)/aout/sun4.h libaout.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+sparcnetbsd.lo: sparcnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+sunos.lo: sunos.c $(INCDIR)/bfdlink.h libaout.h aoutf1.h \
+ $(INCDIR)/aout/sun4.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
+vaxnetbsd.lo: vaxnetbsd.c netbsd.h libaout.h $(INCDIR)/bfdlink.h \
+ aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+versados.lo: versados.c $(INCDIR)/libiberty.h
+vms.lo: vms.c $(INCDIR)/bfdlink.h vms.h
+vms-gsd.lo: vms-gsd.c $(INCDIR)/bfdlink.h vms.h
+vms-hdr.lo: vms-hdr.c $(INCDIR)/bfdlink.h vms.h
+vms-misc.lo: vms-misc.c $(INCDIR)/bfdlink.h vms.h
+vms-tir.lo: vms-tir.c $(INCDIR)/bfdlink.h vms.h
+xcofflink.lo: xcofflink.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ libcoff.h
+aout64.lo: aout64.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def \
+ $(INCDIR)/aout/ar.h
+coff-alpha.lo: coff-alpha.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h libcoff.h \
+ libecoff.h coffswap.h ecoffswap.h
+demo64.lo: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h \
+ libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \
+ aout-target.h
+elf64-alpha.lo: elf64-alpha.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h \
+ libcoff.h libecoff.h ecoffswap.h elf64-target.h
+elf64-gen.lo: elf64-gen.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ elf64-target.h
+elf64-mips.lo: elf64-mips.c $(INCDIR)/aout/ar.h $(INCDIR)/bfdlink.h \
+ genlink.h elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/alpha.h ecoffswap.h \
+ elf64-target.h
+elf64-sparc.lo: elf64-sparc.c elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h \
+ elf64-target.h
+elf64.lo: elf64.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ elfcore.h elflink.h
+nlm32-alpha.lo: nlm32-alpha.c $(INCDIR)/nlm/alpha-ext.h \
+ libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmswap.h nlm-target.h
+nlm64.lo: nlm64.c nlmcode.h libnlm.h $(INCDIR)/nlm/common.h \
+ $(INCDIR)/nlm/internal.h $(INCDIR)/nlm/external.h
+aix386-core.lo: aix386-core.c $(INCDIR)/coff/i386.h \
+ $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h
+hpux-core.lo: hpux-core.c
+irix-core.lo: irix-core.c
+lynx-core.lo: lynx-core.c
+osf-core.lo: osf-core.c
+sco5-core.lo: sco5-core.c libaout.h $(INCDIR)/bfdlink.h
+trad-core.lo: trad-core.c libaout.h $(INCDIR)/bfdlink.h \
+ hosts/i386linux.h
+cisco-core.lo: cisco-core.c
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bfd/PORTING b/bfd/PORTING
new file mode 100644
index 00000000000..c8bfd77b96f
--- /dev/null
+++ b/bfd/PORTING
@@ -0,0 +1,83 @@
+ Preliminary Notes on Porting BFD
+ --------------------------------
+
+The 'host' is the system a tool runs *on*.
+The 'target' is the system a tool runs *for*, i.e.
+a tool can read/write the binaries of the target.
+
+Porting to a new host
+---------------------
+Pick a name for your host. Call that <host>.
+(<host> might be sun4, ...)
+Create a file hosts/<host>.mh.
+
+Porting to a new target
+-----------------------
+Pick a name for your target. Call that <target>.
+Call the name for your CPU architecture <cpu>.
+You need to create <target>.c and config/<target>.mt,
+and add a case for it to a case statements in bfd/configure.host and
+bfd/config.bfd, which associates each canonical host type with a BFD
+host type (used as the base of the makefile fragment names), and to the
+table in bfd/configure.in which associates each target vector with
+the .o files it uses.
+
+config/<target>.mt is a Makefile fragment.
+The following is usually enough:
+DEFAULT_VECTOR=<target>_vec
+SELECT_ARCHITECTURES=bfd_<cpu>_arch
+
+See the list of cpu types in archures.c, or "ls cpu-*.c".
+If your architecture is new, you need to add it to the tables
+in bfd/archures.c, opcodes/configure.in, and binutils/objdump.c.
+
+For more information about .mt and .mh files, see config/README.
+
+The file <target>.c is the hard part. It implements the
+bfd_target <target>_vec, which includes pointers to
+functions that do the actual <target>-specific methods.
+
+Porting to a <target> that uses the a.out binary format
+-------------------------------------------------------
+
+In this case, the include file aout-target.h probaby does most
+of what you need. The program gen-aout generates <target>.c for
+you automatically for many a.out systems. Do:
+ make gen-aout
+ ./gen-aout <target> > <target>.c
+(This only works if you are building on the target ("native").
+If you must make a cross-port from scratch, copy the most
+similar existing file that includes aout-target.h, and fix what is wrong.)
+
+Check the parameters in <target>.c, and fix anything that is wrong.
+(Also let us know about it; perhaps we can improve gen-aout.c.)
+
+TARGET_IS_BIG_ENDIAN_P
+ Should be defined if <target> is big-endian.
+
+N_HEADER_IN_TEXT(x)
+ See discussion in ../include/aout/aout64.h.
+
+BYTES_IN_WORD
+ Number of bytes per word. (Usually 4 but can be 8.)
+
+ARCH
+ Number of bits per word. (Usually 32, but can be 64.)
+
+ENTRY_CAN_BE_ZERO
+ Define if the extry point (start address of an
+ executable program) can be 0x0.
+
+TEXT_START_ADDR
+ The address of the start of the text segemnt in
+ virtual memory. Normally, the same as the entry point.
+
+TARGET_PAGE_SIZE
+
+SEGMENT_SIZE
+ Usually, the same as the TARGET_PAGE_SIZE.
+ Alignment needed for the data segment.
+
+TARGETNAME
+ The name of the target, for run-time lookups.
+ Usually "a.out-<target>"
diff --git a/bfd/README b/bfd/README
new file mode 100644
index 00000000000..51ce133355f
--- /dev/null
+++ b/bfd/README
@@ -0,0 +1,49 @@
+BFD is a an object file library. It permits applications to use the
+same routines to process object files regardless of their format.
+
+BFD is used by the GNU debugger, assembler, linker, and the binary
+utilities.
+
+The documentation on using BFD is scanty and may be occasionally
+incorrect. Pointers to documentation problems, or an entirely
+rewritten manual, would be appreciated.
+
+There is some BFD internals documentation in doc/bfdint.texi which may
+help programmers who want to modify BFD.
+
+BFD is normally built as part of another package. See the build
+instructions for that package, probably in a README file in the
+appropriate directory.
+
+BFD supports the following configure options:
+
+ --target=TARGET
+ The default target for which to build the library. TARGET is
+ a configuration target triplet, such as sparc-sun-solaris.
+ --enable-targets=TARGET,TARGET,TARGET...
+ Additional targets the library should support. To include
+ support for all known targets, use --enable-targets=all.
+ --enable-64-bit-bfd
+ Include support for 64 bit targets. This is automatically
+ turned on if you explicitly request a 64 bit target, but not
+ for --enable-targets=all. This requires a compiler with a 64
+ bit integer type, such as gcc.
+ --enable-shared
+ Build BFD as a shared library.
+ --with-mmap
+ Use mmap when accessing files. This is faster on some hosts,
+ but slower on others. It may not work on all hosts.
+
+Report bugs with BFD to bug-gnu-utils@gnu.org.
+
+Patches are encouraged. When sending patches, always send the output
+of diff -u or diff -c from the original file to the new file. Do not
+send default diff output. Do not make the diff from the new file to
+the original file. Remember that any patch must not break other
+systems. Remember that BFD must support cross compilation from any
+host to any target, so patches which use ``#ifdef HOST'' are not
+acceptable. Please also read the ``Reporting Bugs'' section of the
+gcc manual.
+
+Bug reports without patches will be remembered, but they may never get
+fixed until somebody volunteers to fix them.
diff --git a/bfd/TODO b/bfd/TODO
new file mode 100644
index 00000000000..7a127352521
--- /dev/null
+++ b/bfd/TODO
@@ -0,0 +1,25 @@
+Things that still need to be done: -*- Text -*-
+
+ o - A source of space lossage is that all the target-dependent code
+ is in a single bfd_target structure. Hence all the code for
+ *writing* object files is still pulled into all the applications
+ that only care about *reading* (gdb, nm, objdump), while gas has
+ to carry along all the unneeded baggage for reading objects. And
+ so on. This would be a substantial change, and the payoff would
+ not all that great (essentially none if bfd is used as a shared
+ library).
+
+ o - The storage needed by BFD data structures is also larger than strictly
+ needed. This may be difficult to do much about.
+
+ o - implement bfd_abort, which should close the bfd but not alter the
+ filesystem.
+
+ o - update the bfd doc; write a how-to-write-a-backend doc, take out
+ the stupid quips and fill in all the blanks.
+
+ o - upgrade the reloc handling as per Steve's suggestion.
+
+
+
+
diff --git a/bfd/acinclude.m4 b/bfd/acinclude.m4
new file mode 100644
index 00000000000..dbe1c30fc81
--- /dev/null
+++ b/bfd/acinclude.m4
@@ -0,0 +1,104 @@
+dnl See whether we need to use fopen-bin.h rather than fopen-same.h.
+AC_DEFUN(BFD_BINARY_FOPEN,
+[AC_REQUIRE([AC_CANONICAL_SYSTEM])
+case "${host}" in
+changequote(,)dnl
+*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows)
+changequote([,])dnl
+ AC_DEFINE(USE_BINARY_FOPEN, 1, [Use b modifier when opening binary files?]) ;;
+esac])dnl
+
+dnl Get a default for CC_FOR_BUILD to put into Makefile.
+AC_DEFUN(BFD_CC_FOR_BUILD,
+[# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ CC_FOR_BUILD=gcc
+ fi
+fi
+AC_SUBST(CC_FOR_BUILD)
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+else
+ AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext,
+ [cat > ac_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+ ${CC_FOR_BUILD} -o ac_c_test am_c_test.c 1>&5 2>&5
+ bfd_cv_build_exeext=`echo ac_c_test.* | grep -v ac_c_test.c | sed -e s/ac_c_test//`
+ rm -f ac_c_test*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no])
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+AC_SUBST(EXEEXT_FOR_BUILD)])dnl
+
+dnl See whether we need a declaration for a function.
+AC_DEFUN(BFD_NEED_DECLARATION,
+[AC_MSG_CHECKING([whether $1 must be declared])
+AC_CACHE_VAL(bfd_cv_decl_needed_$1,
+[AC_TRY_COMPILE([
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif],
+[char *(*pfn) = (char *(*)) $1],
+bfd_cv_decl_needed_$1=no, bfd_cv_decl_needed_$1=yes)])
+AC_MSG_RESULT($bfd_cv_decl_needed_$1)
+if test $bfd_cv_decl_needed_$1 = yes; then
+ AC_DEFINE([NEED_DECLARATION_]translit($1, [a-z], [A-Z]), 1,
+ [Define if $1 is not declared in system header files.])
+fi
+])dnl
+
+dnl Check for existence of a type $1 in sys/procfs.h
+
+AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE,
+[AC_MSG_CHECKING([for $1 in sys/procfs.h])
+ AC_CACHE_VAL(bfd_cv_have_sys_procfs_type_$1,
+ [AC_TRY_COMPILE([#include <sys/procfs.h>],
+ [$1 avar],
+ bfd_cv_have_sys_procfs_type_$1=yes,
+ bfd_cv_have_sys_procfs_type_$1=no
+ )])
+ if test $bfd_cv_have_sys_procfs_type_$1 = yes; then
+ AC_DEFINE([HAVE_]translit($1, [a-z], [A-Z]), 1,
+ [Define if <sys/procfs.h> has $1.])
+ fi
+ AC_MSG_RESULT($bfd_cv_have_sys_procfs_type_$1)
+])
+
+
+dnl Check for existence of member $2 in type $1 in sys/procfs.h
+
+AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE_MEMBER,
+[AC_MSG_CHECKING([for $1.$2 in sys/procfs.h])
+ AC_CACHE_VAL(bfd_cv_have_sys_procfs_type_member_$1_$2,
+ [AC_TRY_COMPILE([#include <sys/procfs.h>],
+ [$1 avar; void* aref = (void*) &avar.$2],
+ bfd_cv_have_sys_procfs_type_member_$1_$2=yes,
+ bfd_cv_have_sys_procfs_type_member_$1_$2=no
+ )])
+ if test $bfd_cv_have_sys_procfs_type_member_$1_$2 = yes; then
+ AC_DEFINE([HAVE_]translit($1, [a-z], [A-Z])[_]translit($2, [a-z], [A-Z]), 1,
+ [Define if <sys/procfs.h> has $1.$2.])
+ fi
+ AC_MSG_RESULT($bfd_cv_have_sys_procfs_type_member_$1_$2)
+])
+
+
diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4
new file mode 100644
index 00000000000..43580002449
--- /dev/null
+++ b/bfd/aclocal.m4
@@ -0,0 +1,861 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl See whether we need to use fopen-bin.h rather than fopen-same.h.
+AC_DEFUN(BFD_BINARY_FOPEN,
+[AC_REQUIRE([AC_CANONICAL_SYSTEM])
+case "${host}" in
+changequote(,)dnl
+*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows)
+changequote([,])dnl
+ AC_DEFINE(USE_BINARY_FOPEN, 1, [Use b modifier when opening binary files?]) ;;
+esac])dnl
+
+dnl Get a default for CC_FOR_BUILD to put into Makefile.
+AC_DEFUN(BFD_CC_FOR_BUILD,
+[# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ CC_FOR_BUILD=gcc
+ fi
+fi
+AC_SUBST(CC_FOR_BUILD)
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+else
+ AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext,
+ [cat > ac_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+ ${CC_FOR_BUILD} -o ac_c_test am_c_test.c 1>&5 2>&5
+ bfd_cv_build_exeext=`echo ac_c_test.* | grep -v ac_c_test.c | sed -e s/ac_c_test//`
+ rm -f ac_c_test*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no])
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+AC_SUBST(EXEEXT_FOR_BUILD)])dnl
+
+dnl See whether we need a declaration for a function.
+AC_DEFUN(BFD_NEED_DECLARATION,
+[AC_MSG_CHECKING([whether $1 must be declared])
+AC_CACHE_VAL(bfd_cv_decl_needed_$1,
+[AC_TRY_COMPILE([
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif],
+[char *(*pfn) = (char *(*)) $1],
+bfd_cv_decl_needed_$1=no, bfd_cv_decl_needed_$1=yes)])
+AC_MSG_RESULT($bfd_cv_decl_needed_$1)
+if test $bfd_cv_decl_needed_$1 = yes; then
+ AC_DEFINE([NEED_DECLARATION_]translit($1, [a-z], [A-Z]), 1,
+ [Define if $1 is not declared in system header files.])
+fi
+])dnl
+
+dnl Check for existence of a type $1 in sys/procfs.h
+
+AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE,
+[AC_MSG_CHECKING([for $1 in sys/procfs.h])
+ AC_CACHE_VAL(bfd_cv_have_sys_procfs_type_$1,
+ [AC_TRY_COMPILE([#include <sys/procfs.h>],
+ [$1 avar],
+ bfd_cv_have_sys_procfs_type_$1=yes,
+ bfd_cv_have_sys_procfs_type_$1=no
+ )])
+ if test $bfd_cv_have_sys_procfs_type_$1 = yes; then
+ AC_DEFINE([HAVE_]translit($1, [a-z], [A-Z]), 1,
+ [Define if <sys/procfs.h> has $1.])
+ fi
+ AC_MSG_RESULT($bfd_cv_have_sys_procfs_type_$1)
+])
+
+
+dnl Check for existence of member $2 in type $1 in sys/procfs.h
+
+AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE_MEMBER,
+[AC_MSG_CHECKING([for $1.$2 in sys/procfs.h])
+ AC_CACHE_VAL(bfd_cv_have_sys_procfs_type_member_$1_$2,
+ [AC_TRY_COMPILE([#include <sys/procfs.h>],
+ [$1 avar; void* aref = (void*) &avar.$2],
+ bfd_cv_have_sys_procfs_type_member_$1_$2=yes,
+ bfd_cv_have_sys_procfs_type_member_$1_$2=no
+ )])
+ if test $bfd_cv_have_sys_procfs_type_member_$1_$2 = yes; then
+ AC_DEFINE([HAVE_]translit($1, [a-z], [A-Z])[_]translit($2, [a-z], [A-Z]), 1,
+ [Define if <sys/procfs.h> has $1.$2.])
+ fi
+ AC_MSG_RESULT($bfd_cv_have_sys_procfs_type_member_$1_$2)
+])
+
+
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+# serial 25 AM_PROG_LIBTOOL
+AC_DEFUN(AM_PROG_LIBTOOL,
+[AC_REQUIRE([AM_ENABLE_SHARED])dnl
+AC_REQUIRE([AM_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AM_PROG_LD])dnl
+AC_REQUIRE([AM_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags=
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ CFLAGS="$CFLAGS -belf"
+ ;;
+
+*-*-cygwin*)
+ AM_SYS_LIBTOOL_CYGWIN
+ ;;
+
+esac
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+# AM_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AM_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AM_ENABLE_SHARED,
+[define([AM_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AM_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AM_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AM_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AM_DISABLE_SHARED,
+[AM_ENABLE_SHARED(no)])
+
+# AM_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AM_DISABLE_STATIC,
+[AM_ENABLE_STATIC(no)])
+
+# AM_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AM_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AM_ENABLE_STATIC,
+[define([AM_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AM_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AM_ENABLE_STATIC_DEFAULT)dnl
+])
+
+
+# AM_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AM_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:\\*)
+changequote([,])dnl
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AM_PROG_LD_GNU
+])
+
+AC_DEFUN(AM_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AM_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AM_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ else
+ ac_cv_path_NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AM_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin
+AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
diff --git a/bfd/aix386-core.c b/bfd/aix386-core.c
new file mode 100644
index 00000000000..a75fa94262a
--- /dev/null
+++ b/bfd/aix386-core.c
@@ -0,0 +1,283 @@
+/* BFD back-end for AIX on PS/2 core files.
+ This was based on trad-core.c, which was written by John Gilmore of
+ Cygnus Support.
+ Copyright 1988, 89, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>.
+ Converted to back end form by Ian Lance Taylor <ian@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/i386.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#include <signal.h>
+
+#if defined (_AIX) && defined (_I386)
+#define NOCHECKS /* this is for coredump.h */
+#define _h_USER /* avoid including user.h from coredump.h */
+#include <uinfo.h>
+#include <sys/i386/coredump.h>
+#endif /* _AIX && _I386 */
+
+/* maybe this could work on some other i386 but I have not tried it
+ * mtranle@paris - Tue Sep 24 12:49:35 1991
+ */
+
+#ifndef COR_MAGIC
+# define COR_MAGIC "core"
+#endif
+
+/* need this cast because ptr is really void * */
+#define core_hdr(bfd) \
+ (((bfd->tdata.trad_core_data))->hdr)
+#define core_section(bfd,n) \
+ (((bfd)->tdata.trad_core_data)->sections[n])
+#define core_regsec(bfd) \
+ (((bfd)->tdata.trad_core_data)->reg_section)
+#define core_reg2sec(bfd) \
+ (((bfd)->tdata.trad_core_data)->reg2_section)
+
+/* These are stored in the bfd's tdata */
+struct trad_core_struct {
+ struct corehdr *hdr; /* core file header */
+ asection *reg_section;
+ asection *reg2_section;
+ asection *sections[MAX_CORE_SEGS];
+};
+
+static void swap_abort PARAMS ((void));
+
+static const bfd_target *
+aix386_core_file_p (abfd)
+ bfd *abfd;
+{
+ int i,n;
+ unsigned char longbuf[4]; /* Raw bytes of various header fields */
+ int core_size = sizeof (struct corehdr);
+ struct corehdr *core;
+ struct mergem {
+ struct trad_core_struct coredata;
+ struct corehdr internal_core;
+ } *mergem;
+
+ if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != sizeof (longbuf))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (strncmp(longbuf,COR_MAGIC,4)) return 0;
+
+ if (bfd_seek (abfd, 0L, false) < 0) return 0;
+
+ mergem = (struct mergem *)bfd_zalloc (abfd, sizeof (struct mergem));
+ if (mergem == NULL)
+ return 0;
+
+ core = &mergem->internal_core;
+
+ if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ bfd_release (abfd, (char *)mergem);
+ return 0;
+ }
+
+ set_tdata (abfd, &mergem->coredata);
+ core_hdr (abfd) = core;
+
+ /* create the sections. This is raunchy, but bfd_close wants to reclaim
+ them */
+ core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_regsec (abfd) == NULL)
+ {
+ loser:
+ bfd_release (abfd, (char *)mergem);
+ return 0;
+ }
+ core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_reg2sec (abfd) == NULL)
+ {
+ loser1:
+ bfd_release (abfd, core_regsec (abfd));
+ goto loser;
+ }
+
+ for (i=0, n=0 ; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type) ; i++)
+ {
+ if (core->cd_segs[i].cs_offset == 0)
+ continue;
+ core_section (abfd,n) =
+ (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_section (abfd,n) == NULL)
+ {
+ int j;
+ if (n > 0)
+ {
+ for (j=0; j < n; j++)
+ bfd_release (abfd, core_section(abfd, j));
+ }
+ bfd_release (abfd, (char *)mergem);
+ goto loser1;
+ }
+
+ switch (core->cd_segs[i].cs_type)
+ {
+ case COR_TYPE_DATA:
+ core_section (abfd, n)->name = ".data";
+ core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD +
+ SEC_HAS_CONTENTS);
+ break;
+ case COR_TYPE_STACK:
+ core_section (abfd, n)->name = ".stack";
+ core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD +
+ SEC_HAS_CONTENTS);
+ break;
+ case COR_TYPE_LIBDATA:
+ core_section (abfd, n)->name = ".libdata";
+ core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+ break;
+ case COR_TYPE_WRITE:
+ core_section (abfd, n)->name = ".writeable";
+ core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+ break;
+ case COR_TYPE_MSC:
+ core_section (abfd, n)->name = ".misc";
+ core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+ break;
+ default:
+ core_section (abfd, n)->name = ".unknown";
+ core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+ break;
+ }
+ core_section (abfd, n)->_raw_size = core->cd_segs[i].cs_len;
+ core_section (abfd, n)->vma = core->cd_segs[i].cs_address;
+ core_section (abfd, n)->filepos = core->cd_segs[i].cs_offset;
+ core_section (abfd, n)->alignment_power = 2;
+ core_section (abfd, n)->next = NULL;
+ if (n > 0)
+ core_section (abfd, (n-1))->next = core_section (abfd, n);
+
+ abfd->section_count = ++n;
+ }
+
+ core_regsec (abfd)->name = ".reg";
+ core_reg2sec (abfd)->name = ".reg2";
+
+ core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
+ core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
+
+ core_regsec (abfd)->_raw_size = sizeof(core->cd_regs);
+ core_reg2sec (abfd)->_raw_size = sizeof(core->cd_fpregs);
+
+ core_regsec (abfd)->vma = -1;
+ core_reg2sec (abfd)->vma = -1;
+
+ /* We'll access the regs afresh in the core file, like any section: */
+ core_regsec (abfd)->filepos = (file_ptr)offsetof(struct corehdr,cd_regs[0]);
+ core_reg2sec (abfd)->filepos = (file_ptr)offsetof(struct corehdr,
+ cd_fpregs);
+
+ /* add the 2 reg fake sections to abfd */
+ abfd->section_count += 2;
+ abfd->sections = core_regsec (abfd);
+ core_regsec (abfd)->next = core_reg2sec (abfd);
+ core_reg2sec (abfd)->next = core_section (abfd, 0);
+
+ return abfd->xvec;
+}
+
+static char *
+aix386_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_hdr (abfd)->cd_comm;
+}
+
+static int
+aix386_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_hdr (abfd)->cd_cursig;
+}
+
+static boolean
+aix386_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd;
+ bfd *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this
+ point */
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((PROTO(bfd_vma, (*), ( const bfd_byte *))) swap_abort )
+#define NO_GETS ((PROTO(bfd_signed_vma, (*), (const bfd_byte *))) swap_abort )
+#define NO_PUT ((PROTO(void, (*), (bfd_vma, bfd_byte *))) swap_abort )
+
+const bfd_target aix386_core_vec =
+ {
+ "aix386-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIANG_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_GETS, NO_PUT,
+ NO_GET, NO_GETS, NO_PUT,
+ NO_GET, NO_GETS, NO_PUT, /* data */
+ NO_GET, NO_GETS, NO_PUT,
+ NO_GET, NO_GETS, NO_PUT,
+ NO_GET, NO_GETS, NO_PUT, /* hdrs */
+
+ {_bfd_dummy_target, _bfd_dummy_target,
+ _bfd_dummy_target, aix386_core_file_p},
+ {bfd_false, bfd_false, /* bfd_create_object */
+ bfd_false, bfd_false},
+ {bfd_false, bfd_false, /* bfd_write_contents */
+ bfd_false, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (aix386),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/aout-adobe.c b/bfd/aout-adobe.c
new file mode 100644
index 00000000000..2c11ffe9ff2
--- /dev/null
+++ b/bfd/aout-adobe.c
@@ -0,0 +1,527 @@
+/* BFD back-end for a.out.adobe binaries.
+ Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Written by Cygnus Support. Based on bout.c.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "aout/adobe.h"
+
+#include "aout/stab_gnu.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+extern const bfd_target a_out_adobe_vec; /* Forward decl */
+
+static const bfd_target *aout_adobe_callback PARAMS ((bfd *));
+
+extern boolean aout_32_slurp_symbol_table PARAMS ((bfd *abfd));
+extern boolean aout_32_write_syms PARAMS ((bfd *));
+static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect));
+
+/* Swaps the information in an executable header taken from a raw byte
+ stream memory image, into the internal exec_header structure. */
+
+void aout_adobe_swap_exec_header_in
+ PARAMS ((bfd *abfd, struct external_exec *raw_bytes,
+ struct internal_exec *execp));
+
+void
+aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
+ bfd *abfd;
+ struct external_exec *raw_bytes;
+ struct internal_exec *execp;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
+ execp->a_text = GET_WORD (abfd, bytes->e_text);
+ execp->a_data = GET_WORD (abfd, bytes->e_data);
+ execp->a_bss = GET_WORD (abfd, bytes->e_bss);
+ execp->a_syms = GET_WORD (abfd, bytes->e_syms);
+ execp->a_entry = GET_WORD (abfd, bytes->e_entry);
+ execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
+ execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
+}
+
+/* Swaps the information in an internal exec header structure into the
+ supplied buffer ready for writing to disk. */
+
+PROTO(void, aout_adobe_swap_exec_header_out,
+ (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *raw_bytes));
+void
+aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
+ bfd *abfd;
+ struct internal_exec *execp;
+ struct external_exec *raw_bytes;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
+ PUT_WORD (abfd, execp->a_text , bytes->e_text);
+ PUT_WORD (abfd, execp->a_data , bytes->e_data);
+ PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
+ PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
+ PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
+ PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
+ PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
+}
+
+
+static const bfd_target *
+aout_adobe_object_p (abfd)
+ bfd *abfd;
+{
+ struct internal_exec anexec;
+ struct external_exec exec_bytes;
+ char *targ;
+
+ if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE) {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
+
+ /* Normally we just compare for the magic number.
+ However, a bunch of Adobe tools aren't fixed up yet; they generate
+ files using ZMAGIC(!).
+ If the environment variable GNUTARGET is set to "a.out.adobe", we will
+ take just about any a.out file as an Adobe a.out file. FIXME! */
+
+ if (N_BADMAG (anexec)) {
+ targ = getenv ("GNUTARGET");
+ if (targ && !strcmp (targ, a_out_adobe_vec.name))
+ ; /* Just continue anyway, if specifically set to this format */
+ else
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ }
+
+ aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
+ return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
+}
+
+
+/* Finish up the opening of a b.out file for reading. Fill in all the
+ fields that are not handled by common code. */
+
+static const bfd_target *
+aout_adobe_callback (abfd)
+ 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, 0);
+
+ /* 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 (;;) {
+ if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext)) {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ 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)
+ (_("%s: Unknown section type in a.out.adobe file: %x\n"),
+ bfd_get_filename (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 (abfd, section_name);
+ trynum = 0;
+ while (!sect) {
+ if (bfd_get_error () != bfd_error_no_error)
+ return 0; /* Some other error -- slide into the sunset */
+ sprintf (try_again, "%s%d", section_name, ++trynum);
+ sect = bfd_make_section (abfd, try_again);
+ }
+
+ /* Fix the name, if it is a sprintf'd name. */
+ if (sect->name == try_again) {
+ newname = (char *) bfd_zalloc(abfd, strlen (sect->name));
+ if (newname == NULL)
+ return 0;
+ strcpy (newname, sect->name);
+ sect->name = newname;
+ }
+
+ /* Now set the section's attributes. */
+ bfd_set_section_flags (abfd, sect, flags);
+ sect->_raw_size = ((ext->e_size[0] << 8) /* Assumed big-endian */
+ | ext->e_size[1] << 8)
+ | ext->e_size[2];
+ sect->_cooked_size = sect->_raw_size;
+ sect->vma = bfd_h_get_32 (abfd, ext->e_virtbase);
+ sect->filepos = bfd_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;
+ }
+ }
+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;
+}
+
+struct bout_data_struct {
+ struct aoutdata a;
+ struct internal_exec e;
+};
+
+static boolean
+aout_adobe_mkobject (abfd)
+ bfd *abfd;
+{
+ struct bout_data_struct *rawptr;
+
+ rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
+ if (rawptr == NULL)
+ return false;
+
+ abfd->tdata.bout_data = rawptr;
+ exec_hdr (abfd) = &rawptr->e;
+
+ 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 true;
+}
+
+
+static boolean
+aout_adobe_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec swapped_hdr;
+ static struct external_segdesc sentinel[1]; /* Initialized to zero */
+ asection *sect;
+
+ 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->_raw_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->_raw_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->_raw_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);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE))
+ 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). */
+ if (bfd_write ((PTR) sentinel, 1, sizeof (*sentinel), abfd)
+ != sizeof (*sentinel))
+ 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;
+}
+
+static void
+aout_adobe_write_section (abfd, sect)
+ bfd *abfd;
+ sec_ptr sect;
+{
+ /* FIXME XXX */
+}
+
+static boolean
+aout_adobe_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ file_ptr section_start;
+ sec_ptr sect;
+
+ if (abfd->output_has_begun == false) { /* set by bfd.c handler */
+
+ /* Assign file offsets to sections. Text sections are first, and
+ are contiguous. Then data sections. Everything else at the end. */
+
+ section_start = N_TXTOFF (ignore<-->me);
+
+ for (sect = abfd->sections; sect; sect = sect->next) {
+ if (sect->flags & SEC_CODE) {
+ sect->filepos = section_start;
+ /* FIXME: Round to alignment */
+ section_start += sect->_raw_size;
+ }
+ }
+
+ for (sect = abfd->sections; sect; sect = sect->next) {
+ if (sect->flags & SEC_DATA) {
+ sect->filepos = section_start;
+ /* FIXME: Round to alignment */
+ section_start += sect->_raw_size;
+ }
+ }
+
+ for (sect = abfd->sections; sect; sect = sect->next) {
+ if (sect->flags & SEC_HAS_CONTENTS &&
+ !(sect->flags & (SEC_CODE|SEC_DATA))) {
+ sect->filepos = section_start;
+ /* FIXME: Round to alignment */
+ section_start += sect->_raw_size;
+ }
+ }
+ }
+
+ /* regardless, once we know what we're doing, we might as well get going */
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
+ return false;
+
+ if (count != 0) {
+ return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
+ }
+ return true;
+}
+
+static boolean
+aout_adobe_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ if (! bfd_default_set_arch_mach (abfd, arch, machine))
+ return false;
+
+ if (arch == bfd_arch_unknown
+ || arch == bfd_arch_m68k)
+ return true;
+
+ return false;
+}
+
+static int
+aout_adobe_sizeof_headers (ignore_abfd, ignore)
+ bfd *ignore_abfd;
+ boolean ignore;
+{
+ return sizeof(struct internal_exec);
+}
+
+
+
+
+/* Build the transfer vector for Adobe A.Out files. */
+
+#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
+
+#define aout_32_bfd_make_debug_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+
+#define aout_32_bfd_reloc_type_lookup \
+ ((reloc_howto_type *(*) \
+ PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+
+#define aout_32_set_arch_mach aout_adobe_set_arch_mach
+#define aout_32_set_section_contents aout_adobe_set_section_contents
+
+#define aout_32_sizeof_headers aout_adobe_sizeof_headers
+#define aout_32_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define aout_32_bfd_relax_section bfd_generic_relax_section
+#define aout_32_bfd_gc_sections bfd_generic_gc_sections
+#define aout_32_bfd_link_hash_table_create \
+ _bfd_generic_link_hash_table_create
+#define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define aout_32_bfd_final_link _bfd_generic_final_link
+#define aout_32_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target a_out_adobe_vec =
+{
+ "a.out.adobe", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is unknown (big assumed) */
+ BFD_ENDIAN_BIG, /* hdr byte order is big */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT ),
+ /* section flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
+ '_', /* symbol leading char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ {_bfd_dummy_target, aout_adobe_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, aout_adobe_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, aout_adobe_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (aout_32),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
+ BFD_JUMP_TABLE_SYMBOLS (aout_32),
+ BFD_JUMP_TABLE_RELOCS (aout_32),
+ BFD_JUMP_TABLE_WRITE (aout_32),
+ BFD_JUMP_TABLE_LINK (aout_32),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/aout-arm.c b/bfd/aout-arm.c
new file mode 100644
index 00000000000..beb900beaa1
--- /dev/null
+++ b/bfd/aout-arm.c
@@ -0,0 +1,546 @@
+/* BFD back-end for raw ARM a.out binaries.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#define N_TXTADDR(x) \
+ ((N_MAGIC(x) == NMAGIC) ? 0x8000 : \
+ (N_MAGIC(x) != ZMAGIC) ? 0 : \
+ (N_SHARED_LIB(x)) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) : \
+ TEXT_START_ADDR)
+
+#define TEXT_START_ADDR 0x8000
+#define TARGET_PAGE_SIZE 0x8000
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_arm
+
+#define MY(OP) CAT(aoutarm_,OP)
+#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \
+ (((x).a_info & ~006000) != OMAGIC) && \
+ ((x).a_info != NMAGIC))
+#define N_MAGIC(x) ((x).a_info & ~07200)
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define MYARM(OP) CAT(aoutarm_,OP)
+reloc_howto_type *MYARM(bfd_reloc_type_lookup)
+ PARAMS((bfd *, bfd_reloc_code_real_type));
+static boolean MYARM(write_object_contents) PARAMS((bfd *));
+
+/* Avoid multiple defininitions from aoutx if supporting standarad a.out
+ as well as our own. */
+#define NAME(x,y) CAT3(aoutarm,_32_,y)
+
+#define MY_bfd_reloc_type_lookup aoutarm_bfd_reloc_type_lookup
+
+#include "libaout.h"
+#include "aout/aout64.h"
+
+static bfd_reloc_status_type
+MY(fix_pcrel_26_done) PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+
+static bfd_reloc_status_type
+MY(fix_pcrel_26) PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+static void MY(swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *,
+ arelent *, asymbol **,
+ bfd_size_type));
+void MY(swap_std_reloc_out) PARAMS ((bfd *, arelent *,
+ struct reloc_std_external *));
+
+reloc_howto_type MY(howto_table)[] =
+{
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask
+ pcdone */
+ HOWTO (0, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true,
+ 0x000000ff, 0x000000ff, false),
+ HOWTO (1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true,
+ 0x0000ffff, 0x0000ffff, false),
+ HOWTO (2, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true,
+ 0xffffffff, 0xffffffff, false),
+ HOWTO (3, 2, 2, 26, true, 0, complain_overflow_signed, MY(fix_pcrel_26),
+ "ARM26", true, 0x00ffffff, 0x00ffffff, true),
+ HOWTO (4, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true,
+ 0x000000ff, 0x000000ff, true),
+ HOWTO (5, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true,
+ 0x0000ffff, 0x0000ffff, true),
+ HOWTO (6, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true,
+ 0xffffffff, 0xffffffff, true),
+ HOWTO (7, 2, 2, 26, false, 0, complain_overflow_signed,
+ MY(fix_pcrel_26_done), "ARM26D", true, 0x0, 0x0,
+ false),
+ {-1},
+ HOWTO (9, 0, -1, 16, false, 0, complain_overflow_bitfield, 0, "NEG16", true,
+ 0x0000ffff, 0x0000ffff, false),
+ HOWTO (10, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "NEG32", true,
+ 0xffffffff, 0xffffffff, false)
+};
+
+#define RELOC_ARM_BITS_NEG_BIG ((unsigned int) 0x08)
+#define RELOC_ARM_BITS_NEG_LITTLE ((unsigned int) 0x10)
+
+reloc_howto_type *
+MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel)
+ bfd *abfd;
+ struct reloc_std_external *rel;
+ int *r_index;
+ int *r_extern;
+ int *r_pcrel;
+{
+ unsigned int r_length;
+ unsigned int r_pcrel_done;
+ unsigned int r_neg;
+ int index;
+
+ *r_pcrel = 0;
+ if (bfd_header_big_endian (abfd))
+ {
+ *r_index = ((rel->r_index[0] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[2]);
+ *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
+ r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+ r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG));
+ r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
+ >> RELOC_STD_BITS_LENGTH_SH_BIG);
+ }
+ else
+ {
+ *r_index = ((rel->r_index[2] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[0]);
+ *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+ r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+ r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE));
+ r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+ >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
+ }
+ index = r_length + 4 * r_pcrel_done + 8 * r_neg;
+ if (index == 3)
+ *r_pcrel = 1;
+
+ return MY(howto_table) + index;
+}
+
+#define MY_reloc_howto(BFD, REL, IN, EX, PC) \
+ MY(reloc_howto) (BFD, REL, &IN, &EX, &PC)
+
+void
+MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc)
+ bfd *abfd;
+ int r_extern;
+ int r_index;
+ long value;
+ reloc_howto_type *howto;
+ struct reloc_std_external *reloc;
+{
+ unsigned int r_length;
+ int r_pcrel;
+ int r_neg;
+
+ PUT_WORD (abfd, value, reloc->r_address);
+ r_length = howto->size ; /* Size as a power of two */
+
+ /* Special case for branch relocations. */
+ if (howto->type == 3 || howto->type == 7)
+ r_length = 3;
+
+ r_pcrel = howto->type & 4; /* PC Relative done? */
+ r_neg = howto->type & 8; /* Negative relocation */
+ if (bfd_header_big_endian (abfd))
+ {
+ reloc->r_index[0] = r_index >> 16;
+ reloc->r_index[1] = r_index >> 8;
+ reloc->r_index[2] = r_index;
+ reloc->r_type[0] =
+ ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
+ | (r_neg ? RELOC_ARM_BITS_NEG_BIG : 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
+ }
+ else
+ {
+ reloc->r_index[2] = r_index >> 16;
+ reloc->r_index[1] = r_index >> 8;
+ reloc->r_index[0] = r_index;
+ reloc->r_type[0] =
+ ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
+ | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE : 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
+ }
+}
+
+#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
+ MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC)
+
+void
+MY(relocatable_reloc)(howto, abfd, reloc, amount, r_addr)
+ reloc_howto_type *howto;
+ bfd *abfd;
+ struct reloc_std_external *reloc;
+ bfd_vma *amount;
+ bfd_vma r_addr;
+{
+ if (howto->type == 3)
+ {
+ if (reloc->r_type[0]
+ & (bfd_header_big_endian (abfd)
+ ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE))
+ {
+ /* The reloc is still external, so don't modify anything. */
+ *amount = 0;
+ }
+ else
+ {
+ *amount -= r_addr;
+ /* Change the r_pcrel value -- on the ARM, this bit is set once the
+ relocation is done. */
+ if (bfd_header_big_endian (abfd))
+ reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG;
+ else
+ reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE;
+ }
+ }
+ else if (howto->type == 7)
+ *amount = 0;
+}
+
+#define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \
+ MY(relocatable_reloc)(HOW, BFD, REL, &(AMOUNT), ADDR)
+
+static bfd_reloc_status_type
+MY(fix_pcrel_26_done) (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* This is dead simple at present. */
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+MY(fix_pcrel_26) (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_size_type addr = reloc_entry->address;
+ long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+
+ /* If this is an undefined symbol, return error */
+ if (symbol->section == &bfd_und_section
+ && (symbol->flags & BSF_WEAK) == 0)
+ return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
+
+ /* If the sections are different, and we are doing a partial relocation,
+ just ignore it for now. */
+ if (symbol->section->name != input_section->name
+ && output_bfd != (bfd *)NULL)
+ return bfd_reloc_ok;
+
+ relocation = (target & 0x00ffffff) << 2;
+ relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
+ relocation += symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+ relocation -= input_section->output_section->vma;
+ relocation -= input_section->output_offset;
+ relocation -= addr;
+ if (relocation & 3)
+ return bfd_reloc_overflow;
+
+ /* Check for overflow */
+ if (relocation & 0x02000000)
+ {
+ if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
+ flag = bfd_reloc_overflow;
+ }
+ else if (relocation & ~0x03ffffff)
+ flag = bfd_reloc_overflow;
+
+ target &= ~0x00ffffff;
+ target |= (relocation >> 2) & 0x00ffffff;
+ bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
+
+ /* Now the ARM magic... Change the reloc type so that it is marked as done.
+ Strictly this is only necessary if we are doing a partial relocation. */
+ reloc_entry->howto = &MY(howto_table)[7];
+
+ return flag;
+}
+
+reloc_howto_type *
+MY(bfd_reloc_type_lookup)(abfd,code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+#define ASTD(i,j) case i: return &MY(howto_table)[j]
+ if (code == BFD_RELOC_CTOR)
+ switch (bfd_get_arch_info (abfd)->bits_per_address)
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default: return (CONST struct reloc_howto_struct *) 0;
+ }
+
+ switch (code)
+ {
+ ASTD (BFD_RELOC_16, 1);
+ ASTD (BFD_RELOC_32, 2);
+ ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
+ ASTD (BFD_RELOC_8_PCREL, 4);
+ ASTD (BFD_RELOC_16_PCREL, 5);
+ ASTD (BFD_RELOC_32_PCREL, 6);
+ default: return (CONST struct reloc_howto_struct *) 0;
+ }
+}
+
+#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
+#define MY_swap_std_reloc_out MY(swap_std_reloc_out)
+#define MY_get_section_contents _bfd_generic_get_section_contents
+/* #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create */
+/* #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols */
+/* #define MY_bfd_final_link _bfd_generic_final_link */
+
+#include "aoutx.h"
+
+static void
+MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct reloc_std_external *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ int r_index;
+ int r_extern;
+ int r_pcrel;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
+
+ cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel);
+
+ MOVE_ADDRESS (0);
+}
+
+void
+MY_swap_std_reloc_out (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ struct reloc_std_external *natptr;
+{
+ int r_index;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ int r_extern;
+ int r_length;
+ int r_pcrel;
+ int r_neg = 0; /* Negative relocs use the BASEREL bit. */
+ asection *output_section = sym->section->output_section;
+
+ PUT_WORD(abfd, g->address, natptr->r_address);
+
+ r_length = g->howto->size ; /* Size as a power of two */
+ if (r_length < 0)
+ {
+ r_length = -r_length;
+ r_neg = 1;
+ }
+
+ r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
+
+ /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
+ relocation has been done already (Only for the 26-bit one I think)???!!!
+ */
+
+ if (g->howto->type == 3)
+ {
+ r_length = 3;
+ r_pcrel = 0;
+ }
+ else if (g->howto->type == 7)
+ {
+ r_length = 3;
+ r_pcrel = 1;
+ }
+
+
+#if 0
+ /* For a standard reloc, the addend is in the object file. */
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+#endif
+
+ /* name was clobbered by aout_write_syms to be symbol index */
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ check for that here
+ */
+
+ if (bfd_is_com_section (output_section)
+ || output_section == &bfd_abs_section
+ || output_section == &bfd_und_section)
+ {
+ if (bfd_abs_section.symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_index = 0;
+ r_extern = 0;
+ }
+ else
+ {
+ /* Fill in symbol */
+ r_extern = 1;
+ r_index = (*(g->sym_ptr_ptr))->KEEPIT;
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd))
+ {
+ natptr->r_index[0] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[2] = r_index;
+ natptr->r_type[0] =
+ ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0)
+ | (r_neg ? RELOC_ARM_BITS_NEG_BIG: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
+ }
+ else
+ {
+ natptr->r_index[2] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[0] = r_index;
+ natptr->r_type[0] =
+ ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0)
+ | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
+ }
+}
+
+#define MY_BFD_TARGET
+
+#include "aout-target.h"
+
+const bfd_target aout_arm_little_vec =
+{
+ "a.out-arm-little", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_LITTLE, /* target byte order (little) */
+ BFD_ENDIAN_LITTLE, /* target headers byte order (little) */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ MY_symbol_leading_char,
+ AR_PAD_CHAR, /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+ {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, MY_core_file_p},
+ {bfd_false, MY_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, MY_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (MY),
+ BFD_JUMP_TABLE_COPY (MY),
+ BFD_JUMP_TABLE_CORE (MY),
+ BFD_JUMP_TABLE_ARCHIVE (MY),
+ BFD_JUMP_TABLE_SYMBOLS (MY),
+ BFD_JUMP_TABLE_RELOCS (MY),
+ BFD_JUMP_TABLE_WRITE (MY),
+ BFD_JUMP_TABLE_LINK (MY),
+ BFD_JUMP_TABLE_DYNAMIC (MY),
+
+ (PTR) MY_backend_data,
+};
+
+const bfd_target aout_arm_big_vec =
+{
+ "a.out-arm-big", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_BIG, /* target byte order (big) */
+ BFD_ENDIAN_BIG, /* target headers byte order (big) */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ MY_symbol_leading_char,
+ AR_PAD_CHAR, /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, MY_core_file_p},
+ {bfd_false, MY_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, MY_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (MY),
+ BFD_JUMP_TABLE_COPY (MY),
+ BFD_JUMP_TABLE_CORE (MY),
+ BFD_JUMP_TABLE_ARCHIVE (MY),
+ BFD_JUMP_TABLE_SYMBOLS (MY),
+ BFD_JUMP_TABLE_RELOCS (MY),
+ BFD_JUMP_TABLE_WRITE (MY),
+ BFD_JUMP_TABLE_LINK (MY),
+ BFD_JUMP_TABLE_DYNAMIC (MY),
+
+ (PTR) MY_backend_data,
+};
diff --git a/bfd/aout-encap.c b/bfd/aout-encap.c
new file mode 100644
index 00000000000..c25f9037dce
--- /dev/null
+++ b/bfd/aout-encap.c
@@ -0,0 +1,236 @@
+/* BFD back-end for a.out files encapsulated with COFF headers.
+ Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* THIS MODULE IS NOT FINISHED. IT PROBABLY DOESN'T EVEN COMPILE. */
+
+#if 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0
+#define BYTES_IN_WORD 4
+#endif
+
+#include "bfd.h"
+#include <sysdep.h>
+#include "libbfd.h"
+#include <aout/aout64.h>
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+const bfd_target *encap_real_callback ();
+
+const bfd_target *
+encap_object_p (abfd)
+ bfd *abfd;
+{
+ unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
+ unsigned long magic; /* Swapped magic number */
+ short coff_magic;
+ struct external_exec exec_bytes;
+ struct internal_exec exec;
+
+ if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
+ sizeof (magicbuf))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ coff_magic = bfd_h_get_16 (abfd, magicbuf);
+ if (coff_magic != COFF_MAGIC)
+ return 0; /* Not an encap coff file */
+
+ __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0)
+ (fseek ((f), HEADER_OFFSET((f)), 1))
+
+ magic = bfd_h_get_32 (abfd, magicbuf);
+
+ if (N_BADMAG (*((struct internal_exec *) &magic))) return 0;
+
+ struct external_exec exec_bytes;
+ if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE) {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
+
+ return aout_32_some_aout_object_p (abfd, &exec, encap_realcallback);
+}
+
+/* Finish up the reading of a encapsulated-coff a.out file header */
+const bfd_target *
+encap_real_callback (abfd)
+ bfd *abfd;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ MY(callback)(abfd, execp);
+
+ /* If we have a coff header, it can give us better values for
+ text_start and exec_data_start. This is particularly useful
+ for remote debugging of embedded systems. */
+ if (N_FLAGS(exec_aouthdr) & N_FLAGS_COFF_ENCAPSULATE)
+ {
+ struct coffheader ch;
+ int val;
+ val = lseek (execchan, -(sizeof (AOUTHDR) + sizeof (ch)), 1);
+ if (val == -1)
+ perror_with_name (filename);
+ val = myread (execchan, &ch, sizeof (ch));
+ if (val < 0)
+ perror_with_name (filename);
+ text_start = ch.text_start;
+ exec_data_start = ch.data_start;
+ } else
+ {
+ text_start =
+ IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr);
+ exec_data_start = IS_OBJECT_FILE (exec_aouthdr)
+ ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr);
+ }
+
+ /* Determine the architecture and machine type of the object file. */
+ bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0); /* FIXME */
+
+ return abfd->xvec;
+}
+
+/* Write an object file in Encapsulated COFF format.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+boolean
+encap_write_object_contents (abfd)
+ bfd *abfd;
+{
+ bfd_size_type data_pad = 0;
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+/****** FIXME: Fragments from the old GNU LD program for dealing with
+ encap coff. */
+struct coffheader coffheader;
+int need_coff_header;
+
+ /* Determine whether to count the header as part of
+ the text size, and initialize the text size accordingly.
+ This depends on the kind of system and on the output format selected. */
+
+ N_SET_MAGIC (outheader, magic);
+#ifdef INITIALIZE_HEADER
+ INITIALIZE_HEADER;
+#endif
+
+ text_size = sizeof (struct exec);
+#ifdef COFF_ENCAPSULATE
+ if (relocatable_output == 0 && file_table[0].just_syms_flag == 0)
+ {
+ need_coff_header = 1;
+ /* set this flag now, since it will change the values of N_TXTOFF, etc */
+ N_SET_FLAGS (outheader, aout_backend_info (abfd)->exec_hdr_flags);
+ text_size += sizeof (struct coffheader);
+ }
+#endif
+
+#ifdef COFF_ENCAPSULATE
+ if (need_coff_header)
+ {
+ /* We are encapsulating BSD format within COFF format. */
+ struct coffscn *tp, *dp, *bp;
+
+ tp = &coffheader.scns[0];
+ dp = &coffheader.scns[1];
+ bp = &coffheader.scns[2];
+
+ strcpy (tp->s_name, ".text");
+ tp->s_paddr = text_start;
+ tp->s_vaddr = text_start;
+ tp->s_size = text_size;
+ tp->s_scnptr = sizeof (struct coffheader) + sizeof (struct exec);
+ tp->s_relptr = 0;
+ tp->s_lnnoptr = 0;
+ tp->s_nreloc = 0;
+ tp->s_nlnno = 0;
+ tp->s_flags = 0x20;
+ strcpy (dp->s_name, ".data");
+ dp->s_paddr = data_start;
+ dp->s_vaddr = data_start;
+ dp->s_size = data_size;
+ dp->s_scnptr = tp->s_scnptr + tp->s_size;
+ dp->s_relptr = 0;
+ dp->s_lnnoptr = 0;
+ dp->s_nreloc = 0;
+ dp->s_nlnno = 0;
+ dp->s_flags = 0x40;
+ strcpy (bp->s_name, ".bss");
+ bp->s_paddr = dp->s_vaddr + dp->s_size;
+ bp->s_vaddr = bp->s_paddr;
+ bp->s_size = bss_size;
+ bp->s_scnptr = 0;
+ bp->s_relptr = 0;
+ bp->s_lnnoptr = 0;
+ bp->s_nreloc = 0;
+ bp->s_nlnno = 0;
+ bp->s_flags = 0x80;
+
+ coffheader.f_magic = COFF_MAGIC;
+ coffheader.f_nscns = 3;
+ /* store an unlikely time so programs can
+ * tell that there is a bsd header
+ */
+ coffheader.f_timdat = 1;
+ coffheader.f_symptr = 0;
+ coffheader.f_nsyms = 0;
+ coffheader.f_opthdr = 28;
+ coffheader.f_flags = 0x103;
+ /* aouthdr */
+ coffheader.magic = ZMAGIC;
+ coffheader.vstamp = 0;
+ coffheader.tsize = tp->s_size;
+ coffheader.dsize = dp->s_size;
+ coffheader.bsize = bp->s_size;
+ coffheader.entry = outheader.a_entry;
+ coffheader.text_start = tp->s_vaddr;
+ coffheader.data_start = dp->s_vaddr;
+ }
+#endif
+
+#ifdef COFF_ENCAPSULATE
+ if (need_coff_header)
+ mywrite (&coffheader, sizeof coffheader, 1, outdesc);
+#endif
+
+#ifndef COFF_ENCAPSULATE
+ padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc);
+#endif
+
+ text_size -= N_TXTOFF (outheader);
+ WRITE_HEADERS(abfd, execp);
+ return true;
+}
+
+#define MY_write_object_content encap_write_object_contents
+#define MY_object_p encap_object_p
+#define MY_exec_hdr_flags N_FLAGS_COFF_ENCAPSULATE
+
+#include "aout-target.h"
diff --git a/bfd/aout-ns32k.c b/bfd/aout-ns32k.c
new file mode 100644
index 00000000000..c1335aa84d7
--- /dev/null
+++ b/bfd/aout-ns32k.c
@@ -0,0 +1,370 @@
+/* BFD back-end for ns32k a.out-ish binaries.
+ Copyright (C) 1990, 91, 92, 94, 95, 96, 1998 Free Software Foundation, Inc.
+ Contributed by Ian Dall (idall@eleceng.adelaide.edu.au).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+
+#include "bfd.h"
+#include "aout/aout64.h"
+#include "ns32k.h"
+
+#define MYNS(OP) CAT(ns32kaout_,OP)
+reloc_howto_type *
+MYNS(bfd_reloc_type_lookup)
+ PARAMS((bfd *abfd AND
+ bfd_reloc_code_real_type code));
+
+boolean
+MYNS(write_object_contents)
+ PARAMS((bfd *abfd));
+
+/* Avoid multiple definitions from aoutx if supporting standard a.out format(s)
+ * as well as this one
+ */
+#define NAME(x,y) CAT3(ns32kaout,_32_,y)
+
+void bfd_ns32k_arch PARAMS ((void));
+
+#include "libaout.h"
+
+#define MY(OP) MYNS(OP)
+
+#define MY_swap_std_reloc_in MY(swap_std_reloc_in)
+#define MY_swap_std_reloc_out MY(swap_std_reloc_out)
+
+static void
+MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes,
+ arelent *cache_ptr, asymbol **symbols,
+ bfd_size_type symcount));
+
+static void
+MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g,
+ struct reloc_std_external *natptr));
+
+/* The ns32k series is ah, unusual, when it comes to relocation.
+ * There are three storage methods for relocateable objects. There
+ * are displacements, immediate operands and ordinary twos complement
+ * data. Of these, only the last fits into the standard relocation
+ * scheme. Immediate operands are stored huffman encoded and
+ * immediate operands are stored big endian (where as the natural byte
+ * order is little endian for this achitecture).
+
+ * Note that the ns32k displacement storage method is orthogonal to
+ * whether the relocation is pc relative or not. The "displacement"
+ * storage scheme is used for essentially all address constants. The
+ * displacement can be relative to zero (absolute displacement),
+ * relative to the pc (pc relative), the stack pointer, the frame
+ * pointer, the static base register and general purpose register etc.
+
+ * For example:
+ *
+ * sym1: .long . # pc relative 2's complement
+ * sym1: .long foo # 2's complement not pc relative
+ *
+ * self: movd @self, r0 # pc relative displacement
+ * movd foo, r0 # non pc relative displacement
+ *
+ * self: movd self, r0 # pc relative immediate
+ * movd foo, r0 # non pc relative immediate
+ *
+ * In addition, for historical reasons the encoding of the relocation types
+ * in the a.out format relocation entries is such that even the relocation
+ * methods which are standard are not encoded the standard way.
+ *
+ */
+
+reloc_howto_type MY(howto_table)[] =
+{
+ /* ns32k immediate operands */
+ HOWTO (BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true,
+ _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
+ true, 0x000000ff,0x000000ff, false),
+ HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true,
+ _bfd_ns32k_reloc_imm, "NS32K_IMM_16",
+ true, 0x0000ffff,0x0000ffff, false),
+ HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true,
+ _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
+ true, 0xffffffff,0xffffffff, false),
+ HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false,
+ _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
+ true, 0x000000ff, 0x000000ff, false),
+ HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false,
+ _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
+ true, 0x0000ffff,0x0000ffff, false),
+ HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false,
+ _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
+ true, 0xffffffff,0xffffffff, false),
+
+ /* ns32k displacements */
+ HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true,
+ _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
+ true, 0x000000ff,0x000000ff, false),
+ HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true,
+ _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
+ true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true,
+ _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false,
+ _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
+ true, 0x000000ff,0x000000ff, false),
+ HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false,
+ _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
+ true, 0x0000ffff,0x0000ffff, false),
+ HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false,
+ _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_32",
+ true, 0xffffffff,0xffffffff, false),
+
+ /* Normal 2's complement */
+ HOWTO (BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,
+ "8", true, 0x000000ff,0x000000ff, false),
+ HOWTO (BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,
+ "16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO (BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,
+ "32", true, 0xffffffff,0xffffffff, false),
+ HOWTO (BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0,
+ "PCREL_8", true, 0x000000ff,0x000000ff, false),
+ HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0,
+ "PCREL_16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0,
+ "PCREL_32", true, 0xffffffff,0xffffffff, false),
+};
+
+
+#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14)
+
+#define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06
+#define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60
+#define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1
+#define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5
+
+reloc_howto_type *
+MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel)
+ bfd *abfd;
+ struct reloc_std_external *rel;
+ int *r_index;
+ int *r_extern;
+ int *r_pcrel;
+{
+ unsigned int r_length;
+ int r_ns32k_type;
+/* BFD_ASSERT(bfd_header_little_endian (abfd)); */
+ *r_index = ((rel->r_index[2] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[0] );
+ *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+ *r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+ r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+ >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
+ r_ns32k_type = ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE)
+ >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
+ return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type);
+}
+
+#define MY_reloc_howto(BFD,REL,IN,EX,PC) MY(reloc_howto)(BFD, REL, &IN, &EX, &PC)
+
+void
+MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc)
+ bfd *abfd;
+ int r_extern;
+ int r_index;
+ long value;
+ reloc_howto_type *howto;
+ struct reloc_std_external *reloc;
+{
+ unsigned int r_length;
+ int r_pcrel;
+ int r_ns32k_type;
+ PUT_WORD (abfd, value, reloc->r_address);
+ r_length = howto->size ; /* Size as a power of two */
+ r_pcrel = (int) howto->pc_relative; /* Relative to PC? */
+ r_ns32k_type = (howto - MY(howto_table) )/6;
+/* BFD_ASSERT (bfd_header_little_endian (abfd)); */
+ reloc->r_index[2] = r_index >> 16;
+ reloc->r_index[1] = r_index >> 8;
+ reloc->r_index[0] = r_index;
+ reloc->r_type[0] =
+ (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
+ | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)
+ | (r_ns32k_type << RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE);
+}
+
+#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \
+ MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC)
+
+#define STAT_FOR_EXEC
+
+#define MY_final_link_relocate _bfd_ns32k_final_link_relocate
+#define MY_relocate_contents _bfd_ns32k_relocate_contents
+
+#include <aoutx.h>
+
+reloc_howto_type *
+MY(bfd_reloc_type_lookup)(abfd,code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+
+#define ENTRY(i,j) case i: return &MY(howto_table)[j]
+
+ int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
+
+ BFD_ASSERT(ext == 0);
+ if (code == BFD_RELOC_CTOR)
+ switch (bfd_get_arch_info (abfd)->bits_per_address)
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ }
+ switch (code)
+ {
+ ENTRY(BFD_RELOC_NS32K_IMM_8, 0);
+ ENTRY(BFD_RELOC_NS32K_IMM_16, 1);
+ ENTRY(BFD_RELOC_NS32K_IMM_32, 2);
+ ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3);
+ ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4);
+ ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5);
+ ENTRY(BFD_RELOC_NS32K_DISP_8, 6);
+ ENTRY(BFD_RELOC_NS32K_DISP_16, 7);
+ ENTRY(BFD_RELOC_NS32K_DISP_32, 8);
+ ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9);
+ ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10);
+ ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11);
+ ENTRY(BFD_RELOC_8, 12);
+ ENTRY(BFD_RELOC_16, 13);
+ ENTRY(BFD_RELOC_32, 14);
+ ENTRY(BFD_RELOC_8_PCREL, 15);
+ ENTRY(BFD_RELOC_16_PCREL, 16);
+ ENTRY(BFD_RELOC_32_PCREL, 17);
+ default: return (reloc_howto_type *) NULL;
+ }
+#undef ENTRY
+}
+
+
+static void
+MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct reloc_std_external *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ int r_index;
+ int r_extern;
+ int r_pcrel;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
+
+ /* now the fun stuff */
+
+ cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel);
+
+ MOVE_ADDRESS(0);
+}
+
+static void
+MY_swap_std_reloc_out (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ struct reloc_std_external *natptr;
+{
+ int r_index;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ int r_extern;
+ unsigned int r_addend;
+ asection *output_section = sym->section->output_section;
+
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+
+ /* name was clobbered by aout_write_syms to be symbol index */
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ Check for that here. */
+
+ if (bfd_is_com_section (output_section)
+ || output_section == &bfd_abs_section
+ || output_section == &bfd_und_section)
+ {
+ if (bfd_abs_section.symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_index = 0;
+ r_extern = 0;
+ }
+ else
+ {
+ /* Fill in symbol */
+ r_extern = 1;
+#undef KEEPIT
+#define KEEPIT udata.i
+ r_index = (*(g->sym_ptr_ptr))->KEEPIT;
+#undef KEEPIT
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+ MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr);
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_relocate_contents (howto, input_bfd, relocation, location)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd_vma relocation;
+ bfd_byte *location;
+{
+ int r_ns32k_type = (howto - MY(howto_table)) / 6;
+ long (*get_data) PARAMS ((bfd_byte *, long, long));
+ int (*put_data) PARAMS ((long, bfd_byte *, long, long));
+
+ switch (r_ns32k_type)
+ {
+ case 0:
+ get_data = _bfd_ns32k_get_immediate;
+ put_data = _bfd_ns32k_put_immediate;
+ break;
+ case 1:
+ get_data = _bfd_ns32k_get_displacement;
+ put_data = _bfd_ns32k_put_displacement;
+ break;
+ case 2:
+ return _bfd_relocate_contents (howto, input_bfd, relocation,
+ location);
+ /* NOT REACHED */
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+ return _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation,
+ location, get_data, put_data);
+}
diff --git a/bfd/aout-sparcle.c b/bfd/aout-sparcle.c
new file mode 100644
index 00000000000..903b1367cb3
--- /dev/null
+++ b/bfd/aout-sparcle.c
@@ -0,0 +1,32 @@
+/* BFD backend for sparc little-endian aout binaries.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGETNAME "a.out-sparc-little"
+#define MY(OP) CAT(sparcle_aout_,OP)
+
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libaout.h"
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_SPARCLET)
+
+/* Include the usual a.out support. */
+#define TARGET_IS_LITTLE_ENDIAN_P
+#include "aoutf1.h"
diff --git a/bfd/aout-target.h b/bfd/aout-target.h
new file mode 100644
index 00000000000..1aee07aada0
--- /dev/null
+++ b/bfd/aout-target.h
@@ -0,0 +1,650 @@
+/* Define a target vector and some small routines for a variant of a.out.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+/*#include "libaout.h"*/
+
+#ifndef SEGMENT_SIZE
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#endif
+
+extern reloc_howto_type * NAME(aout,reloc_type_lookup)
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+
+/* Set parameters about this a.out file that are machine-dependent.
+ This routine is called from some_aout_object_p just before it returns. */
+#ifndef MY_callback
+
+static const bfd_target *MY(callback) PARAMS ((bfd *));
+
+static const bfd_target *
+MY(callback) (abfd)
+ bfd *abfd;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+ unsigned int arch_align_power;
+ unsigned long arch_align;
+
+ /* Calculate the file positions of the parts of a newly read aout header */
+ obj_textsec (abfd)->_raw_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);
+
+ /* For some targets, if the entry point is not in the same page
+ as the start of the text, then adjust the VMA so that it is.
+ FIXME: Do this with a macro like SET_ARCH_MACH instead? */
+ if (aout_backend_info (abfd)->entry_is_text_address
+ && execp->a_entry > obj_textsec (abfd)->vma)
+ {
+ bfd_vma adjust;
+
+ adjust = execp->a_entry - obj_textsec (abfd)->vma;
+ /* Adjust only by whole pages. */
+ adjust &= ~(TARGET_PAGE_SIZE - 1);
+ obj_textsec (abfd)->vma += adjust;
+ obj_datasec (abfd)->vma += adjust;
+ obj_bsssec (abfd)->vma += adjust;
+ }
+
+ /* Set the load addresses to be the same as the virtual addresses. */
+ 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
+
+ /* The number of relocation records. This must be called after
+ SET_ARCH_MACH. It assumes that SET_ARCH_MACH will set
+ obj_reloc_entry_size correctly, if the reloc size is not
+ RELOC_STD_SIZE. */
+ obj_textsec (abfd)->reloc_count =
+ execp->a_trsize / obj_reloc_entry_size (abfd);
+ obj_datasec (abfd)->reloc_count =
+ execp->a_drsize / obj_reloc_entry_size (abfd);
+
+ /* Now that we know the architecture, set the alignments of the
+ sections. This is normally done by NAME(aout,new_section_hook),
+ but when the initial sections were created the architecture had
+ not yet been set. However, for backward compatibility, we don't
+ set the alignment power any higher than as required by the size
+ of the section. */
+ arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
+ arch_align = 1 << arch_align_power;
+ if ((BFD_ALIGN (obj_textsec (abfd)->_raw_size, arch_align)
+ == obj_textsec (abfd)->_raw_size)
+ && (BFD_ALIGN (obj_datasec (abfd)->_raw_size, arch_align)
+ == obj_datasec (abfd)->_raw_size)
+ && (BFD_ALIGN (obj_bsssec (abfd)->_raw_size, arch_align)
+ == obj_bsssec (abfd)->_raw_size))
+ {
+ obj_textsec (abfd)->alignment_power = arch_align_power;
+ obj_datasec (abfd)->alignment_power = arch_align_power;
+ obj_bsssec (abfd)->alignment_power = arch_align_power;
+ }
+
+ /* Don't set sizes now -- can't be sure until we know arch & mach.
+ Sizes get set in set_sizes callback, later. */
+#if 0
+ adata(abfd).page_size = TARGET_PAGE_SIZE;
+ adata(abfd).segment_size = SEGMENT_SIZE;
+ adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+#endif
+
+ return abfd->xvec;
+}
+#endif
+
+#ifndef MY_object_p
+/* Finish up the reading of an a.out file header */
+
+static const bfd_target *MY(object_p) PARAMS ((bfd *));
+
+static const bfd_target *
+MY(object_p) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes; /* Raw exec header from file */
+ struct internal_exec exec; /* Cleaned-up exec header */
+ const bfd_target *target;
+
+ if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE) {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+#ifdef SWAP_MAGIC
+ exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
+#else
+ exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
+#endif /* SWAP_MAGIC */
+
+ if (N_BADMAG (exec)) return 0;
+#ifdef MACHTYPE_OK
+ if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
+#endif
+
+ NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
+
+#ifdef SWAP_MAGIC
+ /* swap_exec_header_in read in a_info with the wrong byte order */
+ exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
+#endif /* SWAP_MAGIC */
+
+ target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
+
+#ifdef ENTRY_CAN_BE_ZERO
+ /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
+ * means that it isn't obvious if EXEC_P should be set.
+ * All of the following must be true for an executable:
+ * There must be no relocations, the bfd can be neither an
+ * archive nor an archive element, and the file must be executable. */
+
+ if (exec.a_trsize + exec.a_drsize == 0
+ && bfd_get_format(abfd) == bfd_object && abfd->my_archive == NULL)
+ {
+ struct stat buf;
+#ifndef S_IXUSR
+#define S_IXUSR 0100 /* Execute by owner. */
+#endif
+ if (stat(abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
+ abfd->flags |= EXEC_P;
+ }
+#endif /* ENTRY_CAN_BE_ZERO */
+
+ return target;
+}
+#define MY_object_p MY(object_p)
+#endif
+
+
+#ifndef MY_mkobject
+
+static boolean MY(mkobject) PARAMS ((bfd *));
+
+static boolean
+MY(mkobject) (abfd)
+ bfd *abfd;
+{
+ if (NAME(aout,mkobject)(abfd) == false)
+ return false;
+#if 0 /* Sizes get set in set_sizes callback, later, after we know
+ the architecture and machine. */
+ adata(abfd).page_size = TARGET_PAGE_SIZE;
+ adata(abfd).segment_size = SEGMENT_SIZE;
+ adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+#endif
+ return true;
+}
+#define MY_mkobject MY(mkobject)
+#endif
+
+#ifndef MY_bfd_copy_private_section_data
+
+/* Copy private section data. This actually does nothing with the
+ sections. It copies the subformat field. We copy it here, because
+ we need to know whether this is a QMAGIC file before we set the
+ section contents, and copy_private_bfd_data is not called until
+ after the section contents have been set. */
+
+static boolean MY_bfd_copy_private_section_data
+ PARAMS ((bfd *, asection *, bfd *, asection *));
+
+/*ARGSUSED*/
+static boolean
+MY_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
+ bfd *ibfd;
+ asection *isec;
+ bfd *obfd;
+ asection *osec;
+{
+ if (bfd_get_flavour (ibfd) == bfd_target_aout_flavour
+ && bfd_get_flavour (obfd) == bfd_target_aout_flavour)
+ obj_aout_subformat (obfd) = obj_aout_subformat (ibfd);
+ return true;
+}
+
+#endif
+
+/* Write an object file.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+#ifndef MY_write_object_contents
+static boolean
+MY(write_object_contents) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+#if CHOOSE_RELOC_SIZE
+ CHOOSE_RELOC_SIZE(abfd);
+#else
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+#endif
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
+#define MY_write_object_contents MY(write_object_contents)
+#endif
+
+#ifndef MY_set_sizes
+
+static boolean MY(set_sizes) PARAMS ((bfd *));
+
+static boolean
+MY(set_sizes) (abfd)
+ bfd *abfd;
+{
+ adata(abfd).page_size = TARGET_PAGE_SIZE;
+ adata(abfd).segment_size = SEGMENT_SIZE;
+
+#ifdef ZMAGIC_DISK_BLOCK_SIZE
+ adata(abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
+#else
+ adata(abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE;
+#endif
+
+ adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+ return true;
+}
+#define MY_set_sizes MY(set_sizes)
+#endif
+
+#ifndef MY_exec_hdr_flags
+#define MY_exec_hdr_flags 0
+#endif
+
+#ifndef MY_backend_data
+
+#ifndef MY_zmagic_contiguous
+#define MY_zmagic_contiguous 0
+#endif
+#ifndef MY_text_includes_header
+#define MY_text_includes_header 0
+#endif
+#ifndef MY_entry_is_text_address
+#define MY_entry_is_text_address 0
+#endif
+#ifndef MY_exec_header_not_counted
+#define MY_exec_header_not_counted 0
+#endif
+#ifndef MY_add_dynamic_symbols
+#define MY_add_dynamic_symbols 0
+#endif
+#ifndef MY_add_one_symbol
+#define MY_add_one_symbol 0
+#endif
+#ifndef MY_link_dynamic_object
+#define MY_link_dynamic_object 0
+#endif
+#ifndef MY_write_dynamic_symbol
+#define MY_write_dynamic_symbol 0
+#endif
+#ifndef MY_check_dynamic_reloc
+#define MY_check_dynamic_reloc 0
+#endif
+#ifndef MY_finish_dynamic_link
+#define MY_finish_dynamic_link 0
+#endif
+
+static CONST struct aout_backend_data MY(backend_data) = {
+ MY_zmagic_contiguous,
+ MY_text_includes_header,
+ MY_entry_is_text_address,
+ MY_exec_hdr_flags,
+ 0, /* text vma? */
+ MY_set_sizes,
+ MY_exec_header_not_counted,
+ MY_add_dynamic_symbols,
+ MY_add_one_symbol,
+ MY_link_dynamic_object,
+ MY_write_dynamic_symbol,
+ MY_check_dynamic_reloc,
+ MY_finish_dynamic_link
+};
+#define MY_backend_data &MY(backend_data)
+#endif
+
+#ifndef MY_final_link_callback
+
+/* Callback for the final_link routine to set the section offsets. */
+
+static void MY_final_link_callback
+ PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+
+static void
+MY_final_link_callback (abfd, ptreloff, pdreloff, psymoff)
+ bfd *abfd;
+ file_ptr *ptreloff;
+ file_ptr *pdreloff;
+ file_ptr *psymoff;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ *ptreloff = N_TRELOFF (*execp);
+ *pdreloff = N_DRELOFF (*execp);
+ *psymoff = N_SYMOFF (*execp);
+}
+
+#endif
+
+#ifndef MY_bfd_final_link
+
+/* Final link routine. We need to use a call back to get the correct
+ offsets in the output file. */
+
+static boolean MY_bfd_final_link PARAMS ((bfd *, struct bfd_link_info *));
+
+static boolean
+MY_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
+}
+
+#endif
+
+/* We assume BFD generic archive files. */
+#ifndef MY_openr_next_archived_file
+#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file
+#endif
+#ifndef MY_get_elt_at_index
+#define MY_get_elt_at_index _bfd_generic_get_elt_at_index
+#endif
+#ifndef MY_generic_stat_arch_elt
+#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#endif
+#ifndef MY_slurp_armap
+#define MY_slurp_armap bfd_slurp_bsd_armap
+#endif
+#ifndef MY_slurp_extended_name_table
+#define MY_slurp_extended_name_table _bfd_slurp_extended_name_table
+#endif
+#ifndef MY_construct_extended_name_table
+#define MY_construct_extended_name_table \
+ _bfd_archive_bsd_construct_extended_name_table
+#endif
+#ifndef MY_write_armap
+#define MY_write_armap bsd_write_armap
+#endif
+#ifndef MY_read_ar_hdr
+#define MY_read_ar_hdr _bfd_generic_read_ar_hdr
+#endif
+#ifndef MY_truncate_arname
+#define MY_truncate_arname bfd_bsd_truncate_arname
+#endif
+#ifndef MY_update_armap_timestamp
+#define MY_update_armap_timestamp _bfd_archive_bsd_update_armap_timestamp
+#endif
+
+/* No core file defined here -- configure in trad-core.c separately. */
+#ifndef MY_core_file_failing_command
+#define MY_core_file_failing_command _bfd_nocore_core_file_failing_command
+#endif
+#ifndef MY_core_file_failing_signal
+#define MY_core_file_failing_signal _bfd_nocore_core_file_failing_signal
+#endif
+#ifndef MY_core_file_matches_executable_p
+#define MY_core_file_matches_executable_p \
+ _bfd_nocore_core_file_matches_executable_p
+#endif
+#ifndef MY_core_file_p
+#define MY_core_file_p _bfd_dummy_target
+#endif
+
+#ifndef MY_bfd_debug_info_start
+#define MY_bfd_debug_info_start bfd_void
+#endif
+#ifndef MY_bfd_debug_info_end
+#define MY_bfd_debug_info_end bfd_void
+#endif
+#ifndef MY_bfd_debug_info_accumulate
+#define MY_bfd_debug_info_accumulate \
+ (void (*) PARAMS ((bfd*, struct sec *))) bfd_void
+#endif
+
+#ifndef MY_core_file_failing_command
+#define MY_core_file_failing_command NAME(aout,core_file_failing_command)
+#endif
+#ifndef MY_core_file_failing_signal
+#define MY_core_file_failing_signal NAME(aout,core_file_failing_signal)
+#endif
+#ifndef MY_core_file_matches_executable_p
+#define MY_core_file_matches_executable_p NAME(aout,core_file_matches_executable_p)
+#endif
+#ifndef MY_set_section_contents
+#define MY_set_section_contents NAME(aout,set_section_contents)
+#endif
+#ifndef MY_get_section_contents
+#define MY_get_section_contents NAME(aout,get_section_contents)
+#endif
+#ifndef MY_get_section_contents_in_window
+#define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#endif
+#ifndef MY_new_section_hook
+#define MY_new_section_hook NAME(aout,new_section_hook)
+#endif
+#ifndef MY_get_symtab_upper_bound
+#define MY_get_symtab_upper_bound NAME(aout,get_symtab_upper_bound)
+#endif
+#ifndef MY_get_symtab
+#define MY_get_symtab NAME(aout,get_symtab)
+#endif
+#ifndef MY_get_reloc_upper_bound
+#define MY_get_reloc_upper_bound NAME(aout,get_reloc_upper_bound)
+#endif
+#ifndef MY_canonicalize_reloc
+#define MY_canonicalize_reloc NAME(aout,canonicalize_reloc)
+#endif
+#ifndef MY_make_empty_symbol
+#define MY_make_empty_symbol NAME(aout,make_empty_symbol)
+#endif
+#ifndef MY_print_symbol
+#define MY_print_symbol NAME(aout,print_symbol)
+#endif
+#ifndef MY_get_symbol_info
+#define MY_get_symbol_info NAME(aout,get_symbol_info)
+#endif
+#ifndef MY_get_lineno
+#define MY_get_lineno NAME(aout,get_lineno)
+#endif
+#ifndef MY_set_arch_mach
+#define MY_set_arch_mach NAME(aout,set_arch_mach)
+#endif
+#ifndef MY_find_nearest_line
+#define MY_find_nearest_line NAME(aout,find_nearest_line)
+#endif
+#ifndef MY_sizeof_headers
+#define MY_sizeof_headers NAME(aout,sizeof_headers)
+#endif
+#ifndef MY_bfd_get_relocated_section_contents
+#define MY_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#endif
+#ifndef MY_bfd_relax_section
+#define MY_bfd_relax_section bfd_generic_relax_section
+#endif
+#ifndef MY_bfd_gc_sections
+#define MY_bfd_gc_sections bfd_generic_gc_sections
+#endif
+#ifndef MY_bfd_reloc_type_lookup
+#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup)
+#endif
+#ifndef MY_bfd_make_debug_symbol
+#define MY_bfd_make_debug_symbol 0
+#endif
+#ifndef MY_read_minisymbols
+#define MY_read_minisymbols NAME(aout,read_minisymbols)
+#endif
+#ifndef MY_minisymbol_to_symbol
+#define MY_minisymbol_to_symbol NAME(aout,minisymbol_to_symbol)
+#endif
+#ifndef MY_bfd_link_hash_table_create
+#define MY_bfd_link_hash_table_create NAME(aout,link_hash_table_create)
+#endif
+#ifndef MY_bfd_link_add_symbols
+#define MY_bfd_link_add_symbols NAME(aout,link_add_symbols)
+#endif
+#ifndef MY_bfd_link_split_section
+#define MY_bfd_link_split_section _bfd_generic_link_split_section
+#endif
+
+
+#ifndef MY_bfd_copy_private_bfd_data
+#define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#endif
+
+#ifndef MY_bfd_merge_private_bfd_data
+#define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#endif
+
+#ifndef MY_bfd_copy_private_symbol_data
+#define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#endif
+
+#ifndef MY_bfd_print_private_bfd_data
+#define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+#endif
+
+#ifndef MY_bfd_set_private_flags
+#define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#endif
+
+#ifndef MY_bfd_is_local_label_name
+#define MY_bfd_is_local_label_name bfd_generic_is_local_label_name
+#endif
+
+#ifndef MY_bfd_free_cached_info
+#define MY_bfd_free_cached_info NAME(aout,bfd_free_cached_info)
+#endif
+
+#ifndef MY_close_and_cleanup
+#define MY_close_and_cleanup MY_bfd_free_cached_info
+#endif
+
+#ifndef MY_get_dynamic_symtab_upper_bound
+#define MY_get_dynamic_symtab_upper_bound \
+ _bfd_nodynamic_get_dynamic_symtab_upper_bound
+#endif
+#ifndef MY_canonicalize_dynamic_symtab
+#define MY_canonicalize_dynamic_symtab \
+ _bfd_nodynamic_canonicalize_dynamic_symtab
+#endif
+#ifndef MY_get_dynamic_reloc_upper_bound
+#define MY_get_dynamic_reloc_upper_bound \
+ _bfd_nodynamic_get_dynamic_reloc_upper_bound
+#endif
+#ifndef MY_canonicalize_dynamic_reloc
+#define MY_canonicalize_dynamic_reloc \
+ _bfd_nodynamic_canonicalize_dynamic_reloc
+#endif
+
+/* Aout symbols normally have leading underscores */
+#ifndef MY_symbol_leading_char
+#define MY_symbol_leading_char '_'
+#endif
+
+/* Aout archives normally use spaces for padding */
+#ifndef AR_PAD_CHAR
+#define AR_PAD_CHAR ' '
+#endif
+
+#ifndef MY_BFD_TARGET
+const bfd_target MY(vec) =
+{
+ TARGETNAME, /* name */
+ bfd_target_aout_flavour,
+#ifdef TARGET_IS_BIG_ENDIAN_P
+ BFD_ENDIAN_BIG, /* target byte order (big) */
+ BFD_ENDIAN_BIG, /* target headers byte order (big) */
+#else
+ BFD_ENDIAN_LITTLE, /* target byte order (little) */
+ BFD_ENDIAN_LITTLE, /* target headers byte order (little) */
+#endif
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ MY_symbol_leading_char,
+ AR_PAD_CHAR, /* ar_pad_char */
+ 15, /* ar_max_namelen */
+#ifdef TARGET_IS_BIG_ENDIAN_P
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+#else
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+#endif
+ {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, MY_core_file_p},
+ {bfd_false, MY_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, MY_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (MY),
+ BFD_JUMP_TABLE_COPY (MY),
+ BFD_JUMP_TABLE_CORE (MY),
+ BFD_JUMP_TABLE_ARCHIVE (MY),
+ BFD_JUMP_TABLE_SYMBOLS (MY),
+ BFD_JUMP_TABLE_RELOCS (MY),
+ BFD_JUMP_TABLE_WRITE (MY),
+ BFD_JUMP_TABLE_LINK (MY),
+ BFD_JUMP_TABLE_DYNAMIC (MY),
+
+ (PTR) MY_backend_data,
+};
+#endif /* MY_BFD_TARGET */
diff --git a/bfd/aout-tic30.c b/bfd/aout-tic30.c
new file mode 100644
index 00000000000..eae6cb754cb
--- /dev/null
+++ b/bfd/aout-tic30.c
@@ -0,0 +1,1065 @@
+/* BFD back-end for TMS320C30 a.out binaries.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+#define N_HEADER_IN_TEXT(x) 1
+#define BYTES_IN_WORD 4
+#define TEXT_START_ADDR 1024
+#define TARGET_PAGE_SIZE 128
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_tic30
+#define ARCH_SIZE 32
+
+#define MY(OP) CAT(tic30_aout_,OP)
+#define TARGETNAME "a.out-tic30"
+#define NAME(x,y) CAT3(tic30_aout,_32_,y)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libaout.h"
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+static bfd_reloc_status_type tic30_aout_fix_16
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type tic30_aout_fix_32
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type tic30_aout_fix_pcrel_16
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *tic30_aout_reloc_howto
+ PARAMS ((bfd *, struct reloc_std_external *, int *, int *, int *));
+static bfd_reloc_status_type tic30_aout_relocate_contents
+ PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
+static bfd_reloc_status_type tic30_aout_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma,
+ bfd_vma, bfd_vma));
+static const bfd_target *tic30_aout_object_p PARAMS ((bfd *));
+static boolean tic30_aout_write_object_contents PARAMS ((bfd *));
+static boolean tic30_aout_set_sizes PARAMS ((bfd *));
+
+#define MY_reloc_howto(BFD,REL,IN,EX,PC) tic30_aout_reloc_howto(BFD,REL,&IN,&EX,&PC)
+#define MY_final_link_relocate tic30_aout_final_link_relocate
+#define MY_object_p tic30_aout_object_p
+#define MY_mkobject NAME(aout,mkobject)
+#define MY_write_object_contents tic30_aout_write_object_contents
+#define MY_set_sizes tic30_aout_set_sizes
+
+#ifndef MY_exec_hdr_flags
+#define MY_exec_hdr_flags 1
+#endif
+
+#ifndef MY_backend_data
+
+#ifndef MY_zmagic_contiguous
+#define MY_zmagic_contiguous 0
+#endif
+#ifndef MY_text_includes_header
+#define MY_text_includes_header 0
+#endif
+#ifndef MY_entry_is_text_address
+#define MY_entry_is_text_address 0
+#endif
+#ifndef MY_exec_header_not_counted
+#define MY_exec_header_not_counted 1
+#endif
+#ifndef MY_add_dynamic_symbols
+#define MY_add_dynamic_symbols 0
+#endif
+#ifndef MY_add_one_symbol
+#define MY_add_one_symbol 0
+#endif
+#ifndef MY_link_dynamic_object
+#define MY_link_dynamic_object 0
+#endif
+#ifndef MY_write_dynamic_symbol
+#define MY_write_dynamic_symbol 0
+#endif
+#ifndef MY_check_dynamic_reloc
+#define MY_check_dynamic_reloc 0
+#endif
+#ifndef MY_finish_dynamic_link
+#define MY_finish_dynamic_link 0
+#endif
+
+static CONST struct aout_backend_data tic30_aout_backend_data =
+{
+ MY_zmagic_contiguous,
+ MY_text_includes_header,
+ MY_entry_is_text_address,
+ MY_exec_hdr_flags,
+ 0, /* text vma? */
+ MY_set_sizes,
+ MY_exec_header_not_counted,
+ MY_add_dynamic_symbols,
+ MY_add_one_symbol,
+ MY_link_dynamic_object,
+ MY_write_dynamic_symbol,
+ MY_check_dynamic_reloc,
+ MY_finish_dynamic_link
+};
+#define MY_backend_data &tic30_aout_backend_data
+#endif
+
+/* FIXME: This is wrong. aoutx.h should really only be included by
+ aout32.c. */
+
+#include "aoutx.h"
+
+/* This table lists the relocation types for the TMS320C30. There are
+ only a few relocations required, and all must be divided by 4 (>>
+ 2) to get the 32-bit addresses in the format the TMS320C30 likes
+ it. */
+reloc_howto_type tic30_aout_howto_table[] =
+{
+ {-1},
+ HOWTO (1, 2, 1, 16, false, 0, 0, tic30_aout_fix_16,
+ "16", false, 0x0000FFFF, 0x0000FFFF, false),
+ HOWTO (2, 2, 2, 24, false, 0, complain_overflow_bitfield, NULL,
+ "24", false, 0x00FFFFFF, 0x00FFFFFF, false),
+ HOWTO (3, 18, 3, 24, false, 0, complain_overflow_bitfield, NULL,
+ "LDP", false, 0x00FF0000, 0x000000FF, false),
+ HOWTO (4, 2, 4, 32, false, 0, complain_overflow_bitfield, tic30_aout_fix_32,
+ "32", false, 0xFFFFFFFF, 0xFFFFFFFF, false),
+ HOWTO (5, 2, 1, 16, true, 0, complain_overflow_signed,
+ tic30_aout_fix_pcrel_16, "PCREL", true, 0x0000FFFF, 0x0000FFFF, true),
+ {-1},
+ {-1},
+ {-1},
+ {-1},
+ {-1}
+};
+
+extern reloc_howto_type *NAME (aout, reloc_type_lookup) ();
+
+reloc_howto_type *
+tic30_aout_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_8:
+ case BFD_RELOC_TIC30_LDP:
+ return &tic30_aout_howto_table[3];
+ case BFD_RELOC_16:
+ return &tic30_aout_howto_table[1];
+ case BFD_RELOC_24:
+ return &tic30_aout_howto_table[2];
+ case BFD_RELOC_16_PCREL:
+ return &tic30_aout_howto_table[5];
+ case BFD_RELOC_32:
+ return &tic30_aout_howto_table[4];
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+}
+
+static reloc_howto_type *
+tic30_aout_reloc_howto (abfd, relocs, r_index, r_extern, r_pcrel)
+ bfd *abfd;
+ struct reloc_std_external *relocs;
+ int *r_index;
+ int *r_extern;
+ int *r_pcrel;
+{
+ unsigned int r_length;
+ unsigned int r_pcrel_done;
+ int index;
+
+ *r_pcrel = 0;
+ if (bfd_header_big_endian (abfd))
+ {
+ *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]);
+ *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
+ r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+ r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG);
+ }
+ else
+ {
+ *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]);
+ *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+ r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+ r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
+ }
+ index = r_length + 4 * r_pcrel_done;
+ return tic30_aout_howto_table + index;
+}
+
+/* This function is used as a callback for 16-bit relocs. This is
+ required for relocations between segments. A line in aoutx.h
+ requires that any relocations for the data section should point to
+ the end of the aligned text section, plus an offset. By default,
+ this does not happen, therefore this function takes care of
+ that. */
+
+static bfd_reloc_status_type
+tic30_aout_fix_16 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+
+ /* Make sure that the symbol's section is defined. */
+ if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
+ return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
+ /* Get the size of the input section and turn it into the TMS320C30
+ 32-bit address format. */
+ relocation = (symbol->section->vma >> 2);
+ relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
+ bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+/* This function does the same thing as tic30_aout_fix_16 except for 32
+ bit relocations. */
+
+static bfd_reloc_status_type
+tic30_aout_fix_32 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+
+ /* Make sure that the symbol's section is defined. */
+ if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
+ return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
+ /* Get the size of the input section and turn it into the TMS320C30
+ 32-bit address format. */
+ relocation = (symbol->section->vma >> 2);
+ relocation += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ bfd_put_32 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+/* This function is used to work out pc-relative offsets for the
+ TMS320C30. The data already placed by md_pcrel_from within gas is
+ useless for a relocation, so we just get the offset value and place
+ a version of this within the object code.
+ tic30_aout_final_link_relocate will then calculate the required
+ relocation to add on to the value in the object code. */
+
+static bfd_reloc_status_type
+tic30_aout_fix_pcrel_16 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation = 1;
+ bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1);
+
+ /* The byte before the location of the fix contains bits 23-16 of
+ the pcrel instruction. Bit 21 is set for a delayed instruction
+ which requires on offset of 3 instead of 1. */
+ if (offset_data & 0x20)
+ relocation -= 3;
+ else
+ relocation -= 1;
+ bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+/* These macros will get 24-bit values from the bfd definition.
+ Big-endian only. */
+#define bfd_getb_24(BFD,ADDR) (bfd_get_8(BFD,ADDR) << 16) | \
+ (bfd_get_8(BFD,ADDR+1) << 8) | \
+ (bfd_get_8(BFD,ADDR+2))
+
+#define bfd_putb_24(BFD,DATA,ADDR) bfd_put_8(BFD,(bfd_byte)((DATA >> 16) & 0xFF),ADDR); \
+ bfd_put_8(BFD,(bfd_byte)((DATA >> 8) & 0xFF),ADDR+1); \
+ bfd_put_8(BFD,(bfd_byte)(DATA & 0xFF),ADDR+2)
+
+/* 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 *
+tic30_aout_callback (abfd)
+ bfd *abfd;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+ unsigned int arch_align_power;
+ unsigned long arch_align;
+
+ /* Calculate the file positions of the parts of a newly read aout header */
+ obj_textsec (abfd)->_raw_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
+
+ /* Now that we know the architecture, set the alignments of the
+ sections. This is normally done by NAME(aout,new_section_hook),
+ but when the initial sections were created the architecture had
+ not yet been set. However, for backward compatibility, we don't
+ set the alignment power any higher than as required by the size
+ of the section. */
+ arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
+ arch_align = 1 << arch_align_power;
+ if ((BFD_ALIGN (obj_textsec (abfd)->_raw_size, arch_align)
+ == obj_textsec (abfd)->_raw_size)
+ && (BFD_ALIGN (obj_datasec (abfd)->_raw_size, arch_align)
+ == obj_datasec (abfd)->_raw_size)
+ && (BFD_ALIGN (obj_bsssec (abfd)->_raw_size, arch_align)
+ == obj_bsssec (abfd)->_raw_size))
+ {
+ obj_textsec (abfd)->alignment_power = arch_align_power;
+ obj_datasec (abfd)->alignment_power = arch_align_power;
+ obj_bsssec (abfd)->alignment_power = arch_align_power;
+ }
+ return abfd->xvec;
+}
+
+static bfd_reloc_status_type
+tic30_aout_final_link_relocate (howto, input_bfd, input_section, contents,
+ address, value, addend)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma address;
+ bfd_vma value;
+ bfd_vma addend;
+{
+ bfd_vma relocation;
+
+ if (address > input_section->_raw_size)
+ return bfd_reloc_outofrange;
+
+ relocation = value + addend;
+ if (howto->pc_relative)
+ {
+ relocation -= (input_section->output_section->vma + input_section->output_offset);
+ if (howto->pcrel_offset)
+ relocation -= address;
+ }
+ return tic30_aout_relocate_contents (howto, input_bfd, relocation,
+ contents + address);
+}
+
+bfd_reloc_status_type
+tic30_aout_relocate_contents (howto, input_bfd, relocation, location)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd_vma relocation;
+ bfd_byte *location;
+{
+ bfd_vma x;
+ boolean overflow;
+
+ if (howto->size < 0)
+ relocation = -relocation;
+
+ switch (howto->size)
+ {
+ default:
+ case 0:
+ abort ();
+ break;
+ case 1:
+ x = bfd_get_16 (input_bfd, location);
+ break;
+ case 2:
+ x = bfd_getb_24 (input_bfd, location);
+ break;
+ case 3:
+ x = bfd_get_8 (input_bfd, location);
+ break;
+ case 4:
+ x = bfd_get_32 (input_bfd, location);
+ break;
+ }
+ overflow = false;
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+ bfd_vma add;
+ bfd_signed_vma signed_add;
+
+ if (howto->rightshift == 0)
+ {
+ check = relocation;
+ signed_check = (bfd_signed_vma) relocation;
+ }
+ else
+ {
+ check = relocation >> howto->rightshift;
+ if ((bfd_signed_vma) relocation >= 0)
+ signed_check = check;
+ else
+ signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
+ }
+ add = x & howto->src_mask;
+ signed_add = add;
+ if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
+ signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
+ if (howto->bitpos == 0)
+ {
+ check += add;
+ signed_check += signed_add;
+ }
+ else
+ {
+ check += add >> howto->bitpos;
+ if (signed_add >= 0)
+ signed_check += add >> howto->bitpos;
+ else
+ signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos)));
+ }
+ switch (howto->complain_on_overflow)
+ {
+ case complain_overflow_signed:
+ {
+ bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+ if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+ overflow = true;
+ }
+ break;
+ case complain_overflow_unsigned:
+ {
+ bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+ if (check > reloc_unsigned_max)
+ overflow = true;
+ }
+ break;
+ case complain_overflow_bitfield:
+ {
+ bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+ if ((check & ~reloc_bits) != 0 && (((bfd_vma) signed_check & ~reloc_bits) != (-1 & ~reloc_bits)))
+ overflow = true;
+ }
+ break;
+ default:
+ abort ();
+ }
+ }
+ relocation >>= (bfd_vma) howto->rightshift;
+ relocation <<= (bfd_vma) howto->bitpos;
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask));
+ switch (howto->size)
+ {
+ default:
+ case 0:
+ abort ();
+ break;
+ case 1:
+ bfd_put_16 (input_bfd, x, location);
+ break;
+ case 2:
+ bfd_putb_24 (input_bfd, x, location);
+ break;
+ case 3:
+ bfd_put_8 (input_bfd, x, location);
+ break;
+ case 4:
+ bfd_put_32 (input_bfd, x, location);
+ break;
+ }
+ return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+}
+
+/* Finish up the reading of an a.out file header */
+
+static const bfd_target *
+tic30_aout_object_p (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes; /* Raw exec header from file */
+ struct internal_exec exec; /* Cleaned-up exec header */
+ const bfd_target *target;
+
+ if (bfd_read ((PTR) & exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+#ifdef SWAP_MAGIC
+ exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
+#else
+ exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
+#endif /* SWAP_MAGIC */
+
+ if (N_BADMAG (exec))
+ return 0;
+#ifdef MACHTYPE_OK
+ if (!(MACHTYPE_OK (N_MACHTYPE (exec))))
+ return 0;
+#endif
+
+ NAME (aout, swap_exec_header_in) (abfd, &exec_bytes, &exec);
+
+#ifdef SWAP_MAGIC
+ /* swap_exec_header_in read in a_info with the wrong byte order */
+ exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
+#endif /* SWAP_MAGIC */
+
+ target = NAME (aout, some_aout_object_p) (abfd, &exec, tic30_aout_callback);
+
+#ifdef ENTRY_CAN_BE_ZERO
+ /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
+ * means that it isn't obvious if EXEC_P should be set.
+ * All of the following must be true for an executable:
+ * There must be no relocations, the bfd can be neither an
+ * archive nor an archive element, and the file must be executable. */
+
+ if (exec.a_trsize + exec.a_drsize == 0
+ && bfd_get_format (abfd) == bfd_object && abfd->my_archive == NULL)
+ {
+ struct stat buf;
+#ifndef S_IXUSR
+#define S_IXUSR 0100 /* Execute by owner. */
+#endif
+ if (stat (abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
+ abfd->flags |= EXEC_P;
+ }
+#endif /* ENTRY_CAN_BE_ZERO */
+
+ return target;
+}
+
+/* Copy private section data. This actually does nothing with the
+ sections. It copies the subformat field. We copy it here, because
+ we need to know whether this is a QMAGIC file before we set the
+ section contents, and copy_private_bfd_data is not called until
+ after the section contents have been set. */
+
+/*ARGSUSED */
+static boolean
+MY_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
+ bfd *ibfd;
+ asection *isec;
+ bfd *obfd;
+ asection *osec;
+{
+ if (bfd_get_flavour (obfd) == bfd_target_aout_flavour)
+ obj_aout_subformat (obfd) = obj_aout_subformat (ibfd);
+ return true;
+}
+
+/* Write an object file.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static boolean
+tic30_aout_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+#if CHOOSE_RELOC_SIZE
+ CHOOSE_RELOC_SIZE (abfd);
+#else
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+#endif
+ {
+ bfd_size_type text_size; /* dummy vars */
+ file_ptr text_end;
+ if (adata (abfd).magic == undecided_magic)
+ NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
+
+ execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
+ 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));
+ NAME (aout, swap_exec_header_out) (abfd, execp, &exec_bytes);
+
+ if (adata (abfd).exec_bytes_size > 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+ if (bfd_write ((PTR) & exec_bytes, 1, adata (abfd).exec_bytes_size, abfd) != adata (abfd).exec_bytes_size)
+ return false;
+ }
+ /* Now write out reloc info, followed by syms and strings */
+
+ if (bfd_get_outsymbols (abfd) != (asymbol **) NULL
+ && bfd_get_symcount (abfd) != 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*execp)), SEEK_SET) != 0)
+ return false;
+
+ if (!NAME (aout, write_syms) (abfd))
+ return false;
+ }
+
+ if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 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_SET) != 0)
+ return false;
+ if (!NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
+ return false;
+ }
+
+ return true;
+}
+
+static boolean
+tic30_aout_set_sizes (abfd)
+ bfd *abfd;
+{
+ adata (abfd).page_size = TARGET_PAGE_SIZE;
+
+#ifdef SEGMENT_SIZE
+ adata (abfd).segment_size = SEGMENT_SIZE;
+#else
+ adata (abfd).segment_size = TARGET_PAGE_SIZE;
+#endif
+
+#ifdef ZMAGIC_DISK_BLOCK_SIZE
+ adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
+#else
+ adata (abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE;
+#endif
+
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+
+ return true;
+}
+
+#ifndef MY_final_link_callback
+
+/* Callback for the final_link routine to set the section offsets. */
+
+static void MY_final_link_callback
+ PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+
+static void
+MY_final_link_callback (abfd, ptreloff, pdreloff, psymoff)
+ bfd *abfd;
+ file_ptr *ptreloff;
+ file_ptr *pdreloff;
+ file_ptr *psymoff;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ *ptreloff = obj_datasec (abfd)->filepos + execp->a_data;
+ *pdreloff = *ptreloff + execp->a_trsize;
+ *psymoff = *pdreloff + execp->a_drsize;;
+}
+
+#endif
+
+#ifndef MY_bfd_final_link
+
+/* Final link routine. We need to use a call back to get the correct
+ offsets in the output file. */
+
+static boolean
+MY_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+ file_ptr pos;
+ bfd_vma vma = 0;
+ int pad;
+
+ /* Set the executable header size to 0, as we don't want one for an
+ output. */
+ adata (abfd).exec_bytes_size = 0;
+ pos = adata (abfd).exec_bytes_size;
+ /* Text. */
+ vma = info->create_object_symbols_section->vma;
+ pos += vma;
+ obj_textsec (abfd)->filepos = pos;
+ obj_textsec (abfd)->vma = vma;
+ obj_textsec (abfd)->user_set_vma = 1;
+ pos += obj_textsec (abfd)->_raw_size;
+ vma += obj_textsec (abfd)->_raw_size;
+
+ /* Data. */
+ if (abfd->flags & D_PAGED)
+ {
+ if (info->create_object_symbols_section->next->vma > 0)
+ obj_datasec (abfd)->vma = info->create_object_symbols_section->next->vma;
+ else
+ obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
+ }
+ else
+ {
+ obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
+ }
+ if (obj_datasec (abfd)->vma < vma)
+ {
+ obj_datasec (abfd)->vma = BFD_ALIGN (vma, 4);
+ }
+ obj_datasec (abfd)->user_set_vma = 1;
+ vma = obj_datasec (abfd)->vma;
+ obj_datasec (abfd)->filepos = vma + adata (abfd).exec_bytes_size;
+ execp->a_text = vma - obj_textsec (abfd)->vma;
+ obj_textsec (abfd)->_raw_size = execp->a_text;
+
+ /* Since BSS follows data immediately, see if it needs alignment. */
+ vma += obj_datasec (abfd)->_raw_size;
+ pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
+ obj_datasec (abfd)->_raw_size += pad;
+ pos += obj_datasec (abfd)->_raw_size;
+ execp->a_data = obj_datasec (abfd)->_raw_size;
+
+ /* BSS. */
+ obj_bsssec (abfd)->vma = vma;
+ obj_bsssec (abfd)->user_set_vma = 1;
+
+ /* We are fully resized, so don't readjust in final_link. */
+ adata (abfd).magic = z_magic;
+
+ return NAME (aout, final_link) (abfd, info, MY_final_link_callback);
+}
+
+#endif
+
+enum machine_type
+tic30_aout_machine_type (arch, machine, unknown)
+ enum bfd_architecture arch;
+ unsigned long machine;
+ boolean *unknown;
+{
+ enum machine_type arch_flags;
+
+ arch_flags = M_UNKNOWN;
+ *unknown = true;
+
+ switch (arch)
+ {
+ case bfd_arch_tic30:
+ *unknown = false;
+ break;
+ default:
+ arch_flags = M_UNKNOWN;
+ }
+ if (arch_flags != M_UNKNOWN)
+ *unknown = false;
+ return arch_flags;
+}
+
+boolean
+tic30_aout_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ if (!bfd_default_set_arch_mach (abfd, arch, machine))
+ return false;
+ if (arch != bfd_arch_unknown)
+ {
+ boolean unknown;
+ tic30_aout_machine_type (arch, machine, &unknown);
+ if (unknown)
+ return false;
+ }
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+ return (*aout_backend_info (abfd)->set_sizes) (abfd);
+}
+
+/* We assume BFD generic archive files. */
+#ifndef MY_openr_next_archived_file
+#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file
+#endif
+#ifndef MY_get_elt_at_index
+#define MY_get_elt_at_index _bfd_generic_get_elt_at_index
+#endif
+#ifndef MY_generic_stat_arch_elt
+#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#endif
+#ifndef MY_slurp_armap
+#define MY_slurp_armap bfd_slurp_bsd_armap
+#endif
+#ifndef MY_slurp_extended_name_table
+#define MY_slurp_extended_name_table _bfd_slurp_extended_name_table
+#endif
+#ifndef MY_construct_extended_name_table
+#define MY_construct_extended_name_table \
+ _bfd_archive_bsd_construct_extended_name_table
+#endif
+#ifndef MY_write_armap
+#define MY_write_armap bsd_write_armap
+#endif
+#ifndef MY_read_ar_hdr
+#define MY_read_ar_hdr _bfd_generic_read_ar_hdr
+#endif
+#ifndef MY_truncate_arname
+#define MY_truncate_arname bfd_bsd_truncate_arname
+#endif
+#ifndef MY_update_armap_timestamp
+#define MY_update_armap_timestamp _bfd_archive_bsd_update_armap_timestamp
+#endif
+
+/* No core file defined here -- configure in trad-core.c separately. */
+#ifndef MY_core_file_failing_command
+#define MY_core_file_failing_command _bfd_nocore_core_file_failing_command
+#endif
+#ifndef MY_core_file_failing_signal
+#define MY_core_file_failing_signal _bfd_nocore_core_file_failing_signal
+#endif
+#ifndef MY_core_file_matches_executable_p
+#define MY_core_file_matches_executable_p \
+ _bfd_nocore_core_file_matches_executable_p
+#endif
+#ifndef MY_core_file_p
+#define MY_core_file_p _bfd_dummy_target
+#endif
+
+#ifndef MY_bfd_debug_info_start
+#define MY_bfd_debug_info_start bfd_void
+#endif
+#ifndef MY_bfd_debug_info_end
+#define MY_bfd_debug_info_end bfd_void
+#endif
+#ifndef MY_bfd_debug_info_accumulate
+#define MY_bfd_debug_info_accumulate \
+ (void (*) PARAMS ((bfd*, struct sec *))) bfd_void
+#endif
+
+#ifndef MY_core_file_failing_command
+#define MY_core_file_failing_command NAME(aout,core_file_failing_command)
+#endif
+#ifndef MY_core_file_failing_signal
+#define MY_core_file_failing_signal NAME(aout,core_file_failing_signal)
+#endif
+#ifndef MY_core_file_matches_executable_p
+#define MY_core_file_matches_executable_p NAME(aout,core_file_matches_executable_p)
+#endif
+#ifndef MY_set_section_contents
+#define MY_set_section_contents NAME(aout,set_section_contents)
+#endif
+#ifndef MY_get_section_contents
+#define MY_get_section_contents aout_32_get_section_contents
+#endif
+#ifndef MY_get_section_contents_in_window
+#define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#endif
+#ifndef MY_new_section_hook
+#define MY_new_section_hook NAME(aout,new_section_hook)
+#endif
+#ifndef MY_get_symtab_upper_bound
+#define MY_get_symtab_upper_bound NAME(aout,get_symtab_upper_bound)
+#endif
+#ifndef MY_get_symtab
+#define MY_get_symtab NAME(aout,get_symtab)
+#endif
+#ifndef MY_get_reloc_upper_bound
+#define MY_get_reloc_upper_bound NAME(aout,get_reloc_upper_bound)
+#endif
+#ifndef MY_canonicalize_reloc
+#define MY_canonicalize_reloc NAME(aout,canonicalize_reloc)
+#endif
+#ifndef MY_make_empty_symbol
+#define MY_make_empty_symbol NAME(aout,make_empty_symbol)
+#endif
+#ifndef MY_print_symbol
+#define MY_print_symbol NAME(aout,print_symbol)
+#endif
+#ifndef MY_get_symbol_info
+#define MY_get_symbol_info NAME(aout,get_symbol_info)
+#endif
+#ifndef MY_get_lineno
+#define MY_get_lineno NAME(aout,get_lineno)
+#endif
+#ifndef MY_set_arch_mach
+#define MY_set_arch_mach tic30_aout_set_arch_mach
+#endif
+#ifndef MY_find_nearest_line
+#define MY_find_nearest_line NAME(aout,find_nearest_line)
+#endif
+#ifndef MY_sizeof_headers
+#define MY_sizeof_headers NAME(aout,sizeof_headers)
+#endif
+#ifndef MY_bfd_get_relocated_section_contents
+#define MY_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#endif
+#ifndef MY_bfd_relax_section
+#define MY_bfd_relax_section bfd_generic_relax_section
+#endif
+#ifndef MY_bfd_gc_sections
+#define MY_bfd_gc_sections bfd_generic_gc_sections
+#endif
+#ifndef MY_bfd_reloc_type_lookup
+#define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup
+#endif
+#ifndef MY_bfd_make_debug_symbol
+#define MY_bfd_make_debug_symbol 0
+#endif
+#ifndef MY_read_minisymbols
+#define MY_read_minisymbols NAME(aout,read_minisymbols)
+#endif
+#ifndef MY_minisymbol_to_symbol
+#define MY_minisymbol_to_symbol NAME(aout,minisymbol_to_symbol)
+#endif
+#ifndef MY_bfd_link_hash_table_create
+#define MY_bfd_link_hash_table_create NAME(aout,link_hash_table_create)
+#endif
+#ifndef MY_bfd_link_add_symbols
+#define MY_bfd_link_add_symbols NAME(aout,link_add_symbols)
+#endif
+#ifndef MY_bfd_link_split_section
+#define MY_bfd_link_split_section _bfd_generic_link_split_section
+#endif
+
+
+#ifndef MY_bfd_copy_private_bfd_data
+#define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#endif
+
+#ifndef MY_bfd_merge_private_bfd_data
+#define MY_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#endif
+
+#ifndef MY_bfd_copy_private_symbol_data
+#define MY_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#endif
+
+#ifndef MY_bfd_print_private_bfd_data
+#define MY_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+#endif
+
+#ifndef MY_bfd_set_private_flags
+#define MY_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#endif
+
+#ifndef MY_bfd_is_local_label_name
+#define MY_bfd_is_local_label_name bfd_generic_is_local_label_name
+#endif
+
+#ifndef MY_bfd_free_cached_info
+#define MY_bfd_free_cached_info NAME(aout,bfd_free_cached_info)
+#endif
+
+#ifndef MY_close_and_cleanup
+#define MY_close_and_cleanup MY_bfd_free_cached_info
+#endif
+
+#ifndef MY_get_dynamic_symtab_upper_bound
+#define MY_get_dynamic_symtab_upper_bound \
+ _bfd_nodynamic_get_dynamic_symtab_upper_bound
+#endif
+#ifndef MY_canonicalize_dynamic_symtab
+#define MY_canonicalize_dynamic_symtab \
+ _bfd_nodynamic_canonicalize_dynamic_symtab
+#endif
+#ifndef MY_get_dynamic_reloc_upper_bound
+#define MY_get_dynamic_reloc_upper_bound \
+ _bfd_nodynamic_get_dynamic_reloc_upper_bound
+#endif
+#ifndef MY_canonicalize_dynamic_reloc
+#define MY_canonicalize_dynamic_reloc \
+ _bfd_nodynamic_canonicalize_dynamic_reloc
+#endif
+
+/* Aout symbols normally have leading underscores */
+#ifndef MY_symbol_leading_char
+#define MY_symbol_leading_char '_'
+#endif
+
+/* Aout archives normally use spaces for padding */
+#ifndef AR_PAD_CHAR
+#define AR_PAD_CHAR ' '
+#endif
+
+#ifndef MY_BFD_TARGET
+const bfd_target tic30_aout_vec =
+{
+ TARGETNAME, /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_BIG, /* target byte order (big) */
+ BFD_ENDIAN_BIG, /* target headers byte order (big) */
+ (HAS_RELOC | /* object flags */
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ MY_symbol_leading_char,
+ AR_PAD_CHAR, /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, MY_core_file_p},
+ {bfd_false, MY_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, MY_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (MY),
+ BFD_JUMP_TABLE_COPY (MY),
+ BFD_JUMP_TABLE_CORE (MY),
+ BFD_JUMP_TABLE_ARCHIVE (MY),
+ BFD_JUMP_TABLE_SYMBOLS (MY),
+ BFD_JUMP_TABLE_RELOCS (MY),
+ BFD_JUMP_TABLE_WRITE (MY),
+ BFD_JUMP_TABLE_LINK (MY),
+ BFD_JUMP_TABLE_DYNAMIC (MY),
+
+ (PTR) MY_backend_data,
+};
+#endif /* MY_BFD_TARGET */
diff --git a/bfd/aout0.c b/bfd/aout0.c
new file mode 100644
index 00000000000..5bc7ae0f67f
--- /dev/null
+++ b/bfd/aout0.c
@@ -0,0 +1,32 @@
+/* BFD backend for SunOS style a.out with flags set to 0
+ Copyright (C) 1990, 91, 92, 93, 1994 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGETNAME "a.out-zero-big"
+#define MY(OP) CAT(aout0_big_,OP)
+
+#include "bfd.h"
+
+#define MY_exec_hdr_flags 0
+
+#define MACHTYPE_OK(mtype) \
+ ((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020)
+
+/* Include the usual a.out support. */
+#include "aoutf1.h"
diff --git a/bfd/aout32.c b/bfd/aout32.c
new file mode 100644
index 00000000000..bfc40b46303
--- /dev/null
+++ b/bfd/aout32.c
@@ -0,0 +1,23 @@
+/* BFD back-end for 32-bit a.out files.
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 32
+
+#include "aoutx.h"
diff --git a/bfd/aout64.c b/bfd/aout64.c
new file mode 100644
index 00000000000..84036c885a2
--- /dev/null
+++ b/bfd/aout64.c
@@ -0,0 +1,31 @@
+/* BFD back-end for 64-bit a.out files.
+ Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 64
+
+/* aoutx.h requires definitions for BMAGIC and QMAGIC. */
+#ifndef BMAGIC
+#define BMAGIC 0
+#endif
+#ifndef QMAGIC
+#define QMAGIC 0
+#endif
+
+#include "aoutx.h"
diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h
new file mode 100644
index 00000000000..fdf95b5b117
--- /dev/null
+++ b/bfd/aoutf1.h
@@ -0,0 +1,859 @@
+/* A.out "format 1" file handling code for BFD.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "aout/sun4.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+/* This is needed to reject a NewsOS file, e.g. in
+ gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
+ I needed to add M_UNKNOWN to recognize a 68000 object, so this will
+ probably no longer reject a NewsOS object. <ian@cygnus.com>. */
+#ifndef MACHTYPE_OK
+#define MACHTYPE_OK(mtype) \
+ (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
+ || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
+ && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
+#endif
+
+/*
+The file @code{aoutf1.h} contains the code for BFD's
+a.out back end. Control over the generated back end is given by these
+two preprocessor names:
+@table @code
+@item ARCH_SIZE
+This value should be either 32 or 64, depending upon the size of an
+int in the target format. It changes the sizes of the structs which
+perform the memory/disk mapping of structures.
+
+The 64 bit backend may only be used if the host compiler supports 64
+ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}.
+With this name defined, @emph{all} bfd operations are performed with 64bit
+arithmetic, not just those to a 64bit target.
+
+@item TARGETNAME
+The name put into the target vector.
+@item
+@end table
+
+*/
+
+/*SUPPRESS558*/
+/*SUPPRESS529*/
+
+#if ARCH_SIZE == 64
+#define sunos_set_arch_mach sunos_64_set_arch_mach
+#define sunos_write_object_contents aout_64_sunos4_write_object_contents
+#else
+#define sunos_set_arch_mach sunos_32_set_arch_mach
+#define sunos_write_object_contents aout_32_sunos4_write_object_contents
+#endif
+
+static boolean sunos_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+static void sunos_set_arch_mach PARAMS ((bfd *, int));
+static void choose_reloc_size PARAMS ((bfd *));
+static boolean sunos_write_object_contents PARAMS ((bfd *));
+static const bfd_target *sunos4_core_file_p PARAMS ((bfd *));
+static char *sunos4_core_file_failing_command PARAMS ((bfd *));
+static int sunos4_core_file_failing_signal PARAMS ((bfd *));
+static boolean sunos4_core_file_matches_executable_p PARAMS ((bfd *, bfd *));
+static boolean sunos4_set_sizes PARAMS ((bfd *));
+
+/* Merge backend data into the output file.
+ This is necessary on sparclet-aout where we want the resultant machine
+ number to be M_SPARCLET if any input file is M_SPARCLET. */
+
+#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data
+
+static boolean
+sunos_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd, *obfd;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour
+ || bfd_get_flavour (obfd) != bfd_target_aout_flavour)
+ return true;
+
+ if (bfd_get_arch (obfd) == bfd_arch_sparc)
+ {
+ if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
+ bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd));
+ }
+
+ return true;
+}
+
+/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach,
+ depending upon ARCH_SIZE. */
+
+static void
+sunos_set_arch_mach (abfd, machtype)
+ bfd *abfd;
+ int machtype;
+{
+ /* Determine the architecture and machine type of the object file. */
+ enum bfd_architecture arch;
+ long machine;
+ switch (machtype)
+ {
+
+ case M_UNKNOWN:
+ /* Some Sun3s make magic numbers without cpu types in them, so
+ we'll default to the 68000. */
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68000;
+ break;
+
+ case M_68010:
+ case M_HP200:
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68010;
+ break;
+
+ case M_68020:
+ case M_HP300:
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68020;
+ break;
+
+ case M_SPARC:
+ arch = bfd_arch_sparc;
+ machine = 0;
+ break;
+
+ case M_SPARCLET:
+ arch = bfd_arch_sparc;
+ machine = bfd_mach_sparc_sparclet;
+ break;
+
+ case M_SPARCLITE_LE:
+ arch = bfd_arch_sparc;
+ machine = bfd_mach_sparc_sparclite_le;
+ break;
+
+ case M_386:
+ case M_386_DYNIX:
+ arch = bfd_arch_i386;
+ machine = 0;
+ break;
+
+ case M_29K:
+ arch = bfd_arch_a29k;
+ machine = 0;
+ break;
+
+ case M_HPUX:
+ arch = bfd_arch_m68k;
+ machine = 0;
+ break;
+
+ default:
+ arch = bfd_arch_obscure;
+ machine = 0;
+ break;
+ }
+ bfd_set_arch_mach (abfd, arch, machine);
+}
+
+#define SET_ARCH_MACH(ABFD, EXEC) \
+ NAME(sunos,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
+ choose_reloc_size(ABFD);
+
+/* Determine the size of a relocation entry, based on the architecture */
+static void
+choose_reloc_size (abfd)
+ bfd *abfd;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ case bfd_arch_a29k:
+ obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+ break;
+ default:
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+ break;
+ }
+}
+
+/* Write an object file in SunOS format. Section contents have
+ already been written. We write the file header, symbols, and
+ relocation. The real name of this function is either
+ aout_64_sunos4_write_object_contents or
+ aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE. */
+
+static boolean
+sunos_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ /* Magic number, maestro, please! */
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_m68000:
+ N_SET_MACHTYPE (*execp, M_UNKNOWN);
+ break;
+ case bfd_mach_m68010:
+ N_SET_MACHTYPE (*execp, M_68010);
+ break;
+ default:
+ case bfd_mach_m68020:
+ N_SET_MACHTYPE (*execp, M_68020);
+ break;
+ }
+ break;
+ case bfd_arch_sparc:
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_sparc_sparclet:
+ N_SET_MACHTYPE (*execp, M_SPARCLET);
+ break;
+ case bfd_mach_sparc_sparclite_le:
+ N_SET_MACHTYPE (*execp, M_SPARCLITE_LE);
+ break;
+ default:
+ N_SET_MACHTYPE (*execp, M_SPARC);
+ break;
+ }
+ break;
+ case bfd_arch_i386:
+ N_SET_MACHTYPE (*execp, M_386);
+ break;
+ case bfd_arch_a29k:
+ N_SET_MACHTYPE (*execp, M_29K);
+ break;
+ default:
+ N_SET_MACHTYPE (*execp, M_UNKNOWN);
+ }
+
+ choose_reloc_size (abfd);
+
+ N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
+
+ N_SET_DYNAMIC (*execp, bfd_get_file_flags (abfd) & DYNAMIC);
+
+ WRITE_HEADERS (abfd, execp);
+
+ return true;
+}
+
+/* core files */
+
+#define CORE_MAGIC 0x080456
+#define CORE_NAMELEN 16
+
+/* The core structure is taken from the Sun documentation.
+ Unfortunately, they don't document the FPA structure, or at least I
+ can't find it easily. Fortunately the core header contains its own
+ length. So this shouldn't cause problems, except for c_ucode, which
+ so far we don't use but is easy to find with a little arithmetic. */
+
+/* But the reg structure can be gotten from the SPARC processor handbook.
+ This really should be in a GNU include file though so that gdb can use
+ the same info. */
+struct regs
+{
+ int r_psr;
+ int r_pc;
+ int r_npc;
+ int r_y;
+ int r_g1;
+ int r_g2;
+ int r_g3;
+ int r_g4;
+ int r_g5;
+ int r_g6;
+ int r_g7;
+ int r_o0;
+ int r_o1;
+ int r_o2;
+ int r_o3;
+ int r_o4;
+ int r_o5;
+ int r_o6;
+ int r_o7;
+};
+
+/* Taken from Sun documentation: */
+
+/* FIXME: It's worse than we expect. This struct contains TWO substructs
+ neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
+ even portably access the stuff in between! */
+
+struct external_sparc_core
+ {
+ int c_magic; /* Corefile magic number */
+ int c_len; /* Sizeof (struct core) */
+#define SPARC_CORE_LEN 432
+ int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */
+ struct external_exec c_aouthdr; /* A.out header */
+ int c_signo; /* Killing signal, if any */
+ int c_tsize; /* Text size (bytes) */
+ int c_dsize; /* Data size (bytes) */
+ int c_ssize; /* Stack size (bytes) */
+ char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
+ double fp_stuff[1]; /* external FPU state (size unknown by us) */
+ /* The type "double" is critical here, for alignment.
+ SunOS declares a struct here, but the struct's alignment
+ is double since it contains doubles. */
+ int c_ucode; /* Exception no. from u_code */
+ /* (this member is not accessible by name since we don't
+ portably know the size of fp_stuff.) */
+ };
+
+/* Core files generated by the BCP (the part of Solaris which allows
+ it to run SunOS4 a.out files). */
+struct external_solaris_bcp_core
+ {
+ int c_magic; /* Corefile magic number */
+ int c_len; /* Sizeof (struct core) */
+#define SOLARIS_BCP_CORE_LEN 456
+ int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */
+ int c_exdata_vp; /* exdata structure */
+ int c_exdata_tsize;
+ int c_exdata_dsize;
+ int c_exdata_bsize;
+ int c_exdata_lsize;
+ int c_exdata_nshlibs;
+ short c_exdata_mach;
+ short c_exdata_mag;
+ int c_exdata_toffset;
+ int c_exdata_doffset;
+ int c_exdata_loffset;
+ int c_exdata_txtorg;
+ int c_exdata_datorg;
+ int c_exdata_entloc;
+ int c_signo; /* Killing signal, if any */
+ int c_tsize; /* Text size (bytes) */
+ int c_dsize; /* Data size (bytes) */
+ int c_ssize; /* Stack size (bytes) */
+ char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
+ double fp_stuff[1]; /* external FPU state (size unknown by us) */
+ /* The type "double" is critical here, for alignment.
+ SunOS declares a struct here, but the struct's alignment
+ is double since it contains doubles. */
+ int c_ucode; /* Exception no. from u_code */
+ /* (this member is not accessible by name since we don't
+ portably know the size of fp_stuff.) */
+ };
+
+struct external_sun3_core
+ {
+ int c_magic; /* Corefile magic number */
+ int c_len; /* Sizeof (struct core) */
+#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1 */
+ int c_regs[18]; /* General purpose registers -- MACHDEP SIZE */
+ struct external_exec c_aouthdr; /* A.out header */
+ int c_signo; /* Killing signal, if any */
+ int c_tsize; /* Text size (bytes) */
+ int c_dsize; /* Data size (bytes) */
+ int c_ssize; /* Stack size (bytes) */
+ char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
+ double fp_stuff[1]; /* external FPU state (size unknown by us) */
+ /* The type "double" is critical here, for alignment.
+ SunOS declares a struct here, but the struct's alignment
+ is double since it contains doubles. */
+ int c_ucode; /* Exception no. from u_code */
+ /* (this member is not accessible by name since we don't
+ portably know the size of fp_stuff.) */
+ };
+
+struct internal_sunos_core
+ {
+ int c_magic; /* Corefile magic number */
+ int c_len; /* Sizeof (struct core) */
+ long c_regs_pos; /* file offset of General purpose registers */
+ int c_regs_size; /* size of General purpose registers */
+ struct internal_exec c_aouthdr; /* A.out header */
+ int c_signo; /* Killing signal, if any */
+ int c_tsize; /* Text size (bytes) */
+ int c_dsize; /* Data size (bytes) */
+ bfd_vma c_data_addr; /* Data start (address) */
+ int c_ssize; /* Stack size (bytes) */
+ bfd_vma c_stacktop; /* Stack top (address) */
+ char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
+ long fp_stuff_pos; /* file offset of external FPU state (regs) */
+ int fp_stuff_size; /* Size of it */
+ int c_ucode; /* Exception no. from u_code */
+ };
+
+static void swapcore_sun3
+ PARAMS ((bfd *, char *, struct internal_sunos_core *));
+static void swapcore_sparc
+ PARAMS ((bfd *, char *, struct internal_sunos_core *));
+static void swapcore_solaris_bcp
+ PARAMS ((bfd *, char *, struct internal_sunos_core *));
+
+/* byte-swap in the Sun-3 core structure */
+static void
+swapcore_sun3 (abfd, ext, intcore)
+ bfd *abfd;
+ char *ext;
+ struct internal_sunos_core *intcore;
+{
+ struct external_sun3_core *extcore = (struct external_sun3_core *) ext;
+
+ intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic);
+ intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len);
+ intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs);
+ intcore->c_regs_size = sizeof (extcore->c_regs);
+#if ARCH_SIZE == 64
+ aout_64_swap_exec_header_in
+#else
+ aout_32_swap_exec_header_in
+#endif
+ (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
+ intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo);
+ intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize);
+ intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize);
+ intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
+ intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize);
+ memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
+ intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff);
+ /* FP stuff takes up whole rest of struct, except c_ucode. */
+ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+ (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff);
+ /* Ucode is the last thing in the struct -- just before the end */
+ intcore->c_ucode =
+ bfd_h_get_32 (abfd,
+ intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore);
+ intcore->c_stacktop = 0x0E000000; /* By experimentation */
+}
+
+
+/* byte-swap in the Sparc core structure */
+static void
+swapcore_sparc (abfd, ext, intcore)
+ bfd *abfd;
+ char *ext;
+ struct internal_sunos_core *intcore;
+{
+ struct external_sparc_core *extcore = (struct external_sparc_core *) ext;
+
+ intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic);
+ intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len);
+ intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs);
+ intcore->c_regs_size = sizeof (extcore->c_regs);
+#if ARCH_SIZE == 64
+ aout_64_swap_exec_header_in
+#else
+ aout_32_swap_exec_header_in
+#endif
+ (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
+ intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo);
+ intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize);
+ intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize);
+ intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
+ intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize);
+ memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
+ intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff);
+ /* FP stuff takes up whole rest of struct, except c_ucode. */
+ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+ (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff);
+ /* Ucode is the last thing in the struct -- just before the end */
+ intcore->c_ucode =
+ bfd_h_get_32 (abfd,
+ intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore);
+
+ /* Supposedly the user stack grows downward from the bottom of kernel memory.
+ Presuming that this remains true, this definition will work. */
+ /* Now sun has provided us with another challenge. The value is different
+ for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or
+ the other based on the current value of the stack pointer. This
+ loses (a) if the stack pointer has been clobbered, or (b) if the stack
+ is larger than 128 megabytes.
+
+ It's times like these you're glad they're switching to ELF.
+
+ Note that using include files or nlist on /vmunix would be wrong,
+ because we want the value for this core file, no matter what kind of
+ machine we were compiled on or are running on. */
+#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
+#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
+ {
+ bfd_vma sp = bfd_h_get_32
+ (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6);
+ if (sp < SPARC_USRSTACK_SPARC10)
+ intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
+ else
+ intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
+ }
+}
+
+/* byte-swap in the Solaris BCP core structure */
+static void
+swapcore_solaris_bcp (abfd, ext, intcore)
+ bfd *abfd;
+ char *ext;
+ struct internal_sunos_core *intcore;
+{
+ struct external_solaris_bcp_core *extcore =
+ (struct external_solaris_bcp_core *) ext;
+
+ intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic);
+ intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len);
+ intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs);
+ intcore->c_regs_size = sizeof (extcore->c_regs);
+
+ /* The Solaris BCP exdata structure does not contain an a_syms field,
+ so we are unable to synthesize an internal exec header.
+ Luckily we are able to figure out the start address of the data section,
+ which is the only thing needed from the internal exec header,
+ from the exdata structure.
+
+ As of Solaris 2.3, BCP core files for statically linked executables
+ are buggy. The exdata structure is not properly filled in, and
+ the data section is written from address zero instead of the data
+ start address. */
+ memset ((PTR) &intcore->c_aouthdr, 0, sizeof (struct internal_exec));
+ intcore->c_data_addr =
+ bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_exdata_datorg);
+ intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo);
+ intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize);
+ intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize);
+ intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize);
+ memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
+ intcore->fp_stuff_pos =
+ (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff);
+ /* FP stuff takes up whole rest of struct, except c_ucode. */
+ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+ (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff);
+ /* Ucode is the last thing in the struct -- just before the end */
+ intcore->c_ucode =
+ bfd_h_get_32 (abfd,
+ intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore);
+
+ /* Supposedly the user stack grows downward from the bottom of kernel memory.
+ Presuming that this remains true, this definition will work. */
+ /* Now sun has provided us with another challenge. The value is different
+ for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or
+ the other based on the current value of the stack pointer. This
+ loses (a) if the stack pointer has been clobbered, or (b) if the stack
+ is larger than 128 megabytes.
+
+ It's times like these you're glad they're switching to ELF.
+
+ Note that using include files or nlist on /vmunix would be wrong,
+ because we want the value for this core file, no matter what kind of
+ machine we were compiled on or are running on. */
+#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
+#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
+ {
+ bfd_vma sp = bfd_h_get_32
+ (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6);
+ if (sp < SPARC_USRSTACK_SPARC10)
+ intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
+ else
+ intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
+ }
+}
+
+/* need this cast because ptr is really void * */
+#define core_hdr(bfd) ((bfd)->tdata.sun_core_data)
+#define core_datasec(bfd) (core_hdr(bfd)->data_section)
+#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
+#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
+#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section)
+
+/* These are stored in the bfd's tdata */
+struct sun_core_struct
+{
+ struct internal_sunos_core *hdr; /* core file header */
+ asection *data_section;
+ asection *stack_section;
+ asection *reg_section;
+ asection *reg2_section;
+};
+
+static const bfd_target *
+sunos4_core_file_p (abfd)
+ bfd *abfd;
+{
+ unsigned char longbuf[4]; /* Raw bytes of various header fields */
+ bfd_size_type core_size;
+ unsigned long core_mag;
+ struct internal_sunos_core *core;
+ char *extcore;
+ struct mergem
+ {
+ struct sun_core_struct suncoredata;
+ struct internal_sunos_core internal_sunos_core;
+ char external_core[1];
+ }
+ *mergem;
+
+ if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) !=
+ sizeof (longbuf))
+ return 0;
+ core_mag = bfd_h_get_32 (abfd, longbuf);
+
+ if (core_mag != CORE_MAGIC)
+ return 0;
+
+ /* SunOS core headers can vary in length; second word is size; */
+ if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) !=
+ sizeof (longbuf))
+ return 0;
+ core_size = bfd_h_get_32 (abfd, longbuf);
+ /* Sanity check */
+ if (core_size > 20000)
+ return 0;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0)
+ return 0;
+
+ mergem = (struct mergem *) bfd_zalloc (abfd, core_size + sizeof (struct mergem));
+ if (mergem == NULL)
+ return 0;
+
+ extcore = mergem->external_core;
+
+ if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size)
+ {
+ bfd_release (abfd, (char *) mergem);
+ return 0;
+ }
+
+ /* Validate that it's a core file we know how to handle, due to sun
+ botching the positioning of registers and other fields in a machine
+ dependent way. */
+ core = &mergem->internal_sunos_core;
+ switch (core_size)
+ {
+ case SPARC_CORE_LEN:
+ swapcore_sparc (abfd, extcore, core);
+ break;
+ case SUN3_CORE_LEN:
+ swapcore_sun3 (abfd, extcore, core);
+ break;
+ case SOLARIS_BCP_CORE_LEN:
+ swapcore_solaris_bcp (abfd, extcore, core);
+ break;
+ default:
+ bfd_set_error (bfd_error_system_call); /* FIXME */
+ bfd_release (abfd, (char *) mergem);
+ return 0;
+ }
+
+ abfd->tdata.sun_core_data = &mergem->suncoredata;
+ abfd->tdata.sun_core_data->hdr = core;
+
+ /* create the sections. This is raunchy, but bfd_close wants to reclaim
+ them */
+ core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_stacksec (abfd) == NULL)
+ {
+ loser:
+ bfd_release (abfd, (char *) mergem);
+ return 0;
+ }
+ core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_datasec (abfd) == NULL)
+ {
+ loser1:
+ bfd_release (abfd, core_stacksec (abfd));
+ goto loser;
+ }
+ core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_regsec (abfd) == NULL)
+ {
+ loser2:
+ bfd_release (abfd, core_datasec (abfd));
+ goto loser1;
+ }
+ core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_reg2sec (abfd) == NULL)
+ {
+ bfd_release (abfd, core_regsec (abfd));
+ goto loser2;
+ }
+
+ core_stacksec (abfd)->name = ".stack";
+ core_datasec (abfd)->name = ".data";
+ core_regsec (abfd)->name = ".reg";
+ core_reg2sec (abfd)->name = ".reg2";
+
+ core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
+ core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
+
+ core_stacksec (abfd)->_raw_size = core->c_ssize;
+ core_datasec (abfd)->_raw_size = core->c_dsize;
+ core_regsec (abfd)->_raw_size = core->c_regs_size;
+ core_reg2sec (abfd)->_raw_size = core->fp_stuff_size;
+
+ core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize);
+ core_datasec (abfd)->vma = core->c_data_addr;
+ core_regsec (abfd)->vma = 0;
+ core_reg2sec (abfd)->vma = 0;
+
+ core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
+ core_datasec (abfd)->filepos = core->c_len;
+ /* We'll access the regs afresh in the core file, like any section: */
+ core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos;
+ core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos;
+
+ /* Align to word at least */
+ core_stacksec (abfd)->alignment_power = 2;
+ core_datasec (abfd)->alignment_power = 2;
+ core_regsec (abfd)->alignment_power = 2;
+ core_reg2sec (abfd)->alignment_power = 2;
+
+ abfd->sections = core_stacksec (abfd);
+ core_stacksec (abfd)->next = core_datasec (abfd);
+ core_datasec (abfd)->next = core_regsec (abfd);
+ core_regsec (abfd)->next = core_reg2sec (abfd);
+
+ abfd->section_count = 4;
+
+ return abfd->xvec;
+}
+
+static char *
+sunos4_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_hdr (abfd)->hdr->c_cmdname;
+}
+
+static int
+sunos4_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_hdr (abfd)->hdr->c_signo;
+}
+
+static boolean
+sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd;
+ bfd *exec_bfd;
+{
+ if (core_bfd->xvec != exec_bfd->xvec)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return false;
+ }
+
+ /* Solaris core files do not include an aouthdr. */
+ if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN)
+ return true;
+
+ return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr),
+ (char *) exec_hdr (exec_bfd),
+ sizeof (struct internal_exec)) == 0) ? true : false;
+}
+
+#define MY_set_sizes sunos4_set_sizes
+static boolean
+sunos4_set_sizes (abfd)
+ bfd *abfd;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ default:
+ return false;
+ case bfd_arch_sparc:
+ adata (abfd).page_size = 0x2000;
+ adata (abfd).segment_size = 0x2000;
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+ return true;
+ case bfd_arch_m68k:
+ adata (abfd).page_size = 0x2000;
+ adata (abfd).segment_size = 0x20000;
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+ return true;
+ }
+}
+
+/* We default to setting the toolversion field to 1, as is required by
+ SunOS. */
+#ifndef MY_exec_hdr_flags
+#define MY_exec_hdr_flags 1
+#endif
+
+#ifndef MY_entry_is_text_address
+#define MY_entry_is_text_address 0
+#endif
+#ifndef MY_add_dynamic_symbols
+#define MY_add_dynamic_symbols 0
+#endif
+#ifndef MY_add_one_symbol
+#define MY_add_one_symbol 0
+#endif
+#ifndef MY_link_dynamic_object
+#define MY_link_dynamic_object 0
+#endif
+#ifndef MY_write_dynamic_symbol
+#define MY_write_dynamic_symbol 0
+#endif
+#ifndef MY_check_dynamic_reloc
+#define MY_check_dynamic_reloc 0
+#endif
+#ifndef MY_finish_dynamic_link
+#define MY_finish_dynamic_link 0
+#endif
+
+static CONST struct aout_backend_data sunos4_aout_backend =
+{
+ 0, /* zmagic files are not contiguous */
+ 1, /* text includes header */
+ MY_entry_is_text_address,
+ MY_exec_hdr_flags,
+ 0, /* default text vma */
+ sunos4_set_sizes,
+ 0, /* header is counted in zmagic text */
+ MY_add_dynamic_symbols,
+ MY_add_one_symbol,
+ MY_link_dynamic_object,
+ MY_write_dynamic_symbol,
+ MY_check_dynamic_reloc,
+ MY_finish_dynamic_link
+};
+
+#define MY_core_file_failing_command sunos4_core_file_failing_command
+#define MY_core_file_failing_signal sunos4_core_file_failing_signal
+#define MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p
+
+#define MY_bfd_debug_info_start bfd_void
+#define MY_bfd_debug_info_end bfd_void
+#define MY_bfd_debug_info_accumulate \
+ (void (*) PARAMS ((bfd *, struct sec *))) bfd_void
+#define MY_core_file_p sunos4_core_file_p
+#define MY_write_object_contents NAME(aout,sunos4_write_object_contents)
+#define MY_backend_data &sunos4_aout_backend
+
+#ifndef TARGET_IS_LITTLE_ENDIAN_P
+#define TARGET_IS_BIG_ENDIAN_P
+#endif
+
+#include "aout-target.h"
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
new file mode 100644
index 00000000000..2704eecccfe
--- /dev/null
+++ b/bfd/aoutx.h
@@ -0,0 +1,5706 @@
+/* BFD semi-generic back-end for a.out binaries.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ a.out backends
+
+
+DESCRIPTION
+
+ BFD supports a number of different flavours of a.out format,
+ though the major differences are only the sizes of the
+ structures on disk, and the shape of the relocation
+ information.
+
+ The support is split into a basic support file @file{aoutx.h}
+ and other files which derive functions from the base. One
+ derivation file is @file{aoutf1.h} (for a.out flavour 1), and
+ adds to the basic a.out functions support for sun3, sun4, 386
+ and 29k a.out files, to create a target jump vector for a
+ specific target.
+
+ This information is further split out into more specific files
+ for each machine, including @file{sunos.c} for sun3 and sun4,
+ @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
+ demonstration of a 64 bit a.out format.
+
+ The base file @file{aoutx.h} defines general mechanisms for
+ reading and writing records to and from disk and various
+ other methods which BFD requires. It is included by
+ @file{aout32.c} and @file{aout64.c} to form the names
+ <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
+
+ As an example, this is what goes on to make the back end for a
+ sun4, from @file{aout32.c}:
+
+| #define ARCH_SIZE 32
+| #include "aoutx.h"
+
+ Which exports names:
+
+| ...
+| aout_32_canonicalize_reloc
+| aout_32_find_nearest_line
+| aout_32_get_lineno
+| aout_32_get_reloc_upper_bound
+| ...
+
+ from @file{sunos.c}:
+
+| #define TARGET_NAME "a.out-sunos-big"
+| #define VECNAME sunos_big_vec
+| #include "aoutf1.h"
+
+ requires all the names from @file{aout32.c}, and produces the jump vector
+
+| sunos_big_vec
+
+ The file @file{host-aout.c} is a special case. It is for a large set
+ of hosts that use ``more or less standard'' a.out files, and
+ for which cross-debugging is not interesting. It uses the
+ standard 32-bit a.out support routines, but determines the
+ file offsets and addresses of the text, data, and BSS
+ sections, the machine architecture and machine type, and the
+ entry point address, in a host-dependent manner. Once these
+ values have been determined, generic code is used to handle
+ the object file.
+
+ When porting it to run on a new system, you must supply:
+
+| HOST_PAGE_SIZE
+| HOST_SEGMENT_SIZE
+| HOST_MACHINE_ARCH (optional)
+| HOST_MACHINE_MACHINE (optional)
+| HOST_TEXT_START_ADDR
+| HOST_STACK_END_ADDR
+
+ in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These
+ values, plus the structures and macros defined in @file{a.out.h} on
+ your host system, will produce a BFD target that will access
+ ordinary a.out files on your host. To configure a new machine
+ to use @file{host-aout.c}, specify:
+
+| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
+| TDEPFILES= host-aout.o trad-core.o
+
+ in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
+ to use the
+ @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
+ configuration is selected.
+
+*/
+
+/* Some assumptions:
+ * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
+ Doesn't matter what the setting of WP_TEXT is on output, but it'll
+ get set on input.
+ * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
+ * Any BFD with both flags clear is OMAGIC.
+ (Just want to make these explicit, so the conditions tested in this
+ file make sense if you're more familiar with a.out than with BFD.) */
+
+#define KEEPIT udata.i
+
+#include <ctype.h>
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "libaout.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+static boolean aout_get_external_symbols PARAMS ((bfd *));
+static boolean translate_from_native_sym_flags
+ PARAMS ((bfd *, aout_symbol_type *));
+static boolean translate_to_native_sym_flags
+ PARAMS ((bfd *, asymbol *, struct external_nlist *));
+static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
+static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
+static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
+
+/*
+SUBSECTION
+ Relocations
+
+DESCRIPTION
+ The file @file{aoutx.h} provides for both the @emph{standard}
+ and @emph{extended} forms of a.out relocation records.
+
+ The standard records contain only an
+ address, a symbol index, and a type field. The extended records
+ (used on 29ks and sparcs) also have a full integer for an
+ addend.
+
+*/
+#ifndef CTOR_TABLE_RELOC_HOWTO
+#define CTOR_TABLE_RELOC_IDX 2
+#define CTOR_TABLE_RELOC_HOWTO(BFD) ((obj_reloc_entry_size(BFD) == RELOC_EXT_SIZE \
+ ? howto_table_ext : howto_table_std) \
+ + CTOR_TABLE_RELOC_IDX)
+#endif
+
+#ifndef MY_swap_std_reloc_in
+#define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
+#endif
+
+#ifndef MY_swap_std_reloc_out
+#define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
+#endif
+
+#ifndef MY_final_link_relocate
+#define MY_final_link_relocate _bfd_final_link_relocate
+#endif
+
+#ifndef MY_relocate_contents
+#define MY_relocate_contents _bfd_relocate_contents
+#endif
+
+#define howto_table_ext NAME(aout,ext_howto_table)
+#define howto_table_std NAME(aout,std_howto_table)
+
+reloc_howto_type howto_table_ext[] =
+{
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+ HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false),
+ HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false),
+ HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false),
+ HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false),
+ HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false),
+ HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false),
+ HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false),
+ HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false),
+ HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false),
+ HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false),
+ HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false),
+ HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false),
+ HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
+ HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
+ HOWTO(RELOC_BASE10, 0, 2, 10, false, 0, complain_overflow_dont,0,"BASE10", false, 0,0x000003ff, false),
+ HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_signed,0,"BASE13", false, 0,0x00001fff, false),
+ HOWTO(RELOC_BASE22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x003fffff, false),
+ HOWTO(RELOC_PC10, 0, 2, 10, true, 0, complain_overflow_dont,0,"PC10", false, 0,0x000003ff, true),
+ HOWTO(RELOC_PC22, 10, 2, 22, true, 0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true),
+ HOWTO(RELOC_JMP_TBL,2, 2, 30, true, 0, complain_overflow_signed,0,"JMP_TBL", false, 0,0x3fffffff, false),
+ HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false),
+ HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false),
+ HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false),
+ HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
+ HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(0, 0, 0, 0, false, 0, complain_overflow_dont, 0, "R_SPARC_NONE", false,0,0x00000000,true),
+#define RELOC_SPARC_REV32 RELOC_WDISP19
+ HOWTO(RELOC_SPARC_REV32, 0, 2, 32, false, 0, complain_overflow_dont,0,"R_SPARC_REV32", false, 0,0xffffffff, false),
+};
+
+/* Convert standard reloc records to "arelent" format (incl byte swap). */
+
+reloc_howto_type howto_table_std[] = {
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
+HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
+HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
+HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false),
+HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false),
+HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
+HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false),
+HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false),
+HOWTO( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false),
+HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false),
+HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false),
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+ HOWTO(16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false),
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
+ HOWTO(32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false),
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+{ -1 },
+ HOWTO(40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false),
+};
+
+#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
+
+reloc_howto_type *
+NAME(aout,reloc_type_lookup) (abfd,code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+#define EXT(i,j) case i: return &howto_table_ext[j]
+#define STD(i,j) case i: return &howto_table_std[j]
+ int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
+ if (code == BFD_RELOC_CTOR)
+ switch (bfd_get_arch_info (abfd)->bits_per_address)
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ case 64:
+ code = BFD_RELOC_64;
+ break;
+ }
+ if (ext)
+ switch (code)
+ {
+ EXT (BFD_RELOC_32, 2);
+ EXT (BFD_RELOC_HI22, 8);
+ EXT (BFD_RELOC_LO10, 11);
+ EXT (BFD_RELOC_32_PCREL_S2, 6);
+ EXT (BFD_RELOC_SPARC_WDISP22, 7);
+ EXT (BFD_RELOC_SPARC13, 10);
+ EXT (BFD_RELOC_SPARC_GOT10, 14);
+ EXT (BFD_RELOC_SPARC_BASE13, 15);
+ EXT (BFD_RELOC_SPARC_GOT13, 15);
+ EXT (BFD_RELOC_SPARC_GOT22, 16);
+ EXT (BFD_RELOC_SPARC_PC10, 17);
+ EXT (BFD_RELOC_SPARC_PC22, 18);
+ EXT (BFD_RELOC_SPARC_WPLT30, 19);
+ EXT (BFD_RELOC_SPARC_REV32, 26);
+ default: return (reloc_howto_type *) NULL;
+ }
+ else
+ /* std relocs */
+ switch (code)
+ {
+ STD (BFD_RELOC_16, 1);
+ STD (BFD_RELOC_32, 2);
+ STD (BFD_RELOC_8_PCREL, 4);
+ STD (BFD_RELOC_16_PCREL, 5);
+ STD (BFD_RELOC_32_PCREL, 6);
+ STD (BFD_RELOC_16_BASEREL, 9);
+ STD (BFD_RELOC_32_BASEREL, 10);
+ default: return (reloc_howto_type *) NULL;
+ }
+}
+
+/*
+SUBSECTION
+ Internal entry points
+
+DESCRIPTION
+ @file{aoutx.h} exports several routines for accessing the
+ contents of an a.out file, which are gathered and exported in
+ turn by various format specific files (eg sunos.c).
+
+*/
+
+/*
+FUNCTION
+ aout_@var{size}_swap_exec_header_in
+
+SYNOPSIS
+ void aout_@var{size}_swap_exec_header_in,
+ (bfd *abfd,
+ struct external_exec *raw_bytes,
+ struct internal_exec *execp);
+
+DESCRIPTION
+ Swap the information in an executable header @var{raw_bytes} taken
+ from a raw byte stream memory image into the internal exec header
+ structure @var{execp}.
+*/
+
+#ifndef NAME_swap_exec_header_in
+void
+NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
+ bfd *abfd;
+ struct external_exec *raw_bytes;
+ struct internal_exec *execp;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* The internal_exec structure has some fields that are unused in this
+ configuration (IE for i960), so ensure that all such uninitialized
+ fields are zero'd out. There are places where two of these structs
+ are memcmp'd, and thus the contents do matter. */
+ memset ((PTR) execp, 0, sizeof (struct internal_exec));
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
+ execp->a_text = GET_WORD (abfd, bytes->e_text);
+ execp->a_data = GET_WORD (abfd, bytes->e_data);
+ execp->a_bss = GET_WORD (abfd, bytes->e_bss);
+ execp->a_syms = GET_WORD (abfd, bytes->e_syms);
+ execp->a_entry = GET_WORD (abfd, bytes->e_entry);
+ execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
+ execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
+}
+#define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
+#endif
+
+/*
+FUNCTION
+ aout_@var{size}_swap_exec_header_out
+
+SYNOPSIS
+ void aout_@var{size}_swap_exec_header_out
+ (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *raw_bytes);
+
+DESCRIPTION
+ Swap the information in an internal exec header structure
+ @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
+*/
+void
+NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
+ bfd *abfd;
+ struct internal_exec *execp;
+ struct external_exec *raw_bytes;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
+ PUT_WORD (abfd, execp->a_text , bytes->e_text);
+ PUT_WORD (abfd, execp->a_data , bytes->e_data);
+ PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
+ PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
+ PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
+ PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
+ PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
+}
+
+/* Make all the section for an a.out file. */
+
+boolean
+NAME(aout,make_sections) (abfd)
+ bfd *abfd;
+{
+ if (obj_textsec (abfd) == (asection *) NULL
+ && bfd_make_section (abfd, ".text") == (asection *) NULL)
+ return false;
+ if (obj_datasec (abfd) == (asection *) NULL
+ && bfd_make_section (abfd, ".data") == (asection *) NULL)
+ return false;
+ if (obj_bsssec (abfd) == (asection *) NULL
+ && bfd_make_section (abfd, ".bss") == (asection *) NULL)
+ return false;
+ return true;
+}
+
+/*
+FUNCTION
+ aout_@var{size}_some_aout_object_p
+
+SYNOPSIS
+ const bfd_target *aout_@var{size}_some_aout_object_p
+ (bfd *abfd,
+ const bfd_target *(*callback_to_real_object_p)());
+
+DESCRIPTION
+ Some a.out variant thinks that the file open in @var{abfd}
+ checking is an a.out file. Do some more checking, and set up
+ for access if it really is. Call back to the calling
+ environment's "finish up" function just before returning, to
+ handle any last-minute setup.
+*/
+
+const bfd_target *
+NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
+ bfd *abfd;
+ struct internal_exec *execp;
+ const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
+{
+ struct aout_data_struct *rawptr, *oldrawptr;
+ const bfd_target *result;
+
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
+ if (rawptr == NULL)
+ return 0;
+
+ oldrawptr = abfd->tdata.aout_data;
+ abfd->tdata.aout_data = rawptr;
+
+ /* Copy the contents of the old tdata struct.
+ In particular, we want the subformat, since for hpux it was set in
+ hp300hpux.c:swap_exec_header_in and will be used in
+ hp300hpux.c:callback. */
+ if (oldrawptr != NULL)
+ *abfd->tdata.aout_data = *oldrawptr;
+
+ abfd->tdata.aout_data->a.hdr = &rawptr->e;
+ *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */
+ execp = abfd->tdata.aout_data->a.hdr;
+
+ /* Set the file flags */
+ abfd->flags = BFD_NO_FLAGS;
+ if (execp->a_drsize || execp->a_trsize)
+ abfd->flags |= HAS_RELOC;
+ /* Setting of EXEC_P has been deferred to the bottom of this function */
+ if (execp->a_syms)
+ abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
+ if (N_DYNAMIC(*execp))
+ abfd->flags |= DYNAMIC;
+
+ if (N_MAGIC (*execp) == ZMAGIC)
+ {
+ abfd->flags |= D_PAGED | WP_TEXT;
+ adata (abfd).magic = z_magic;
+ }
+ else if (N_MAGIC (*execp) == QMAGIC)
+ {
+ abfd->flags |= D_PAGED | WP_TEXT;
+ adata (abfd).magic = z_magic;
+ adata (abfd).subformat = q_magic_format;
+ }
+ else if (N_MAGIC (*execp) == NMAGIC)
+ {
+ abfd->flags |= WP_TEXT;
+ adata (abfd).magic = n_magic;
+ }
+ else if (N_MAGIC (*execp) == OMAGIC
+ || N_MAGIC (*execp) == BMAGIC)
+ adata (abfd).magic = o_magic;
+ else
+ {
+ /* Should have been checked with N_BADMAG before this routine
+ was called. */
+ abort ();
+ }
+
+ bfd_get_start_address (abfd) = execp->a_entry;
+
+ obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
+ bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
+
+ /* The default relocation entry size is that of traditional V7 Unix. */
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ /* The default symbol entry size is that of traditional Unix. */
+ obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
+
+#ifdef USE_MMAP
+ bfd_init_window (&obj_aout_sym_window (abfd));
+ bfd_init_window (&obj_aout_string_window (abfd));
+#endif
+ obj_aout_external_syms (abfd) = NULL;
+ obj_aout_external_strings (abfd) = NULL;
+ obj_aout_sym_hashes (abfd) = NULL;
+
+ if (! NAME(aout,make_sections) (abfd))
+ return NULL;
+
+ obj_datasec (abfd)->_raw_size = execp->a_data;
+ obj_bsssec (abfd)->_raw_size = execp->a_bss;
+
+ obj_textsec (abfd)->flags =
+ (execp->a_trsize != 0
+ ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
+ : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
+ obj_datasec (abfd)->flags =
+ (execp->a_drsize != 0
+ ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
+ : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
+ obj_bsssec (abfd)->flags = SEC_ALLOC;
+
+#ifdef THIS_IS_ONLY_DOCUMENTATION
+ /* The common code can't fill in these things because they depend
+ on either the start address of the text segment, the rounding
+ up of virtual addresses between segments, or the starting file
+ position of the text segment -- all of which varies among different
+ versions of a.out. */
+
+ /* Call back to the format-dependent code to fill in the rest of the
+ fields and do any further cleanup. Things that should be filled
+ in by the callback: */
+
+ struct exec *execp = exec_hdr (abfd);
+
+ obj_textsec (abfd)->size = N_TXTSIZE(*execp);
+ obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
+ /* data and bss are already filled in since they're so standard */
+
+ /* 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);
+
+ /* 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_str_filepos (abfd) = N_STROFF (*execp);
+ obj_sym_filepos (abfd) = N_SYMOFF (*execp);
+
+ /* Determine the architecture and machine type of the object file. */
+ switch (N_MACHTYPE (*exec_hdr (abfd))) {
+ default:
+ abfd->obj_arch = bfd_arch_obscure;
+ break;
+ }
+
+ adata(abfd)->page_size = TARGET_PAGE_SIZE;
+ adata(abfd)->segment_size = SEGMENT_SIZE;
+ adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
+
+ return abfd->xvec;
+
+ /* The architecture is encoded in various ways in various a.out variants,
+ or is not encoded at all in some of them. The relocation size depends
+ on the architecture and the a.out variant. Finally, the return value
+ is the bfd_target vector in use. If an error occurs, return zero and
+ set bfd_error to the appropriate error code.
+
+ Formats such as b.out, which have additional fields in the a.out
+ header, should cope with them in this callback as well. */
+#endif /* DOCUMENTATION */
+
+ result = (*callback_to_real_object_p)(abfd);
+
+ /* Now that the segment addresses have been worked out, take a better
+ guess at whether the file is executable. If the entry point
+ is within the text segment, assume it is. (This makes files
+ executable even if their entry point address is 0, as long as
+ their text starts at zero.).
+
+ This test had to be changed to deal with systems where the text segment
+ runs at a different location than the default. The problem is that the
+ entry address can appear to be outside the text segment, thus causing an
+ erroneous conclusion that the file isn't executable.
+
+ To fix this, we now accept any non-zero entry point as an indication of
+ executability. This will work most of the time, since only the linker
+ sets the entry point, and that is likely to be non-zero for most systems. */
+
+ if (execp->a_entry != 0
+ || (execp->a_entry >= obj_textsec(abfd)->vma
+ && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
+ abfd->flags |= EXEC_P;
+#ifdef STAT_FOR_EXEC
+ else
+ {
+ struct stat stat_buf;
+
+ /* The original heuristic doesn't work in some important cases.
+ The a.out file has no information about the text start
+ address. For files (like kernels) linked to non-standard
+ addresses (ld -Ttext nnn) the entry point may not be between
+ the default text start (obj_textsec(abfd)->vma) and
+ (obj_textsec(abfd)->vma) + text size. This is not just a mach
+ issue. Many kernels are loaded at non standard addresses. */
+ if (abfd->iostream != NULL
+ && (abfd->flags & BFD_IN_MEMORY) == 0
+ && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
+ && ((stat_buf.st_mode & 0111) != 0))
+ abfd->flags |= EXEC_P;
+ }
+#endif /* STAT_FOR_EXEC */
+
+ if (result)
+ {
+#if 0 /* These should be set correctly anyways. */
+ abfd->sections = obj_textsec (abfd);
+ obj_textsec (abfd)->next = obj_datasec (abfd);
+ obj_datasec (abfd)->next = obj_bsssec (abfd);
+#endif
+ }
+ else
+ {
+ free (rawptr);
+ abfd->tdata.aout_data = oldrawptr;
+ }
+ return result;
+}
+
+/*
+FUNCTION
+ aout_@var{size}_mkobject
+
+SYNOPSIS
+ boolean aout_@var{size}_mkobject, (bfd *abfd);
+
+DESCRIPTION
+ Initialize BFD @var{abfd} for use with a.out files.
+*/
+
+boolean
+NAME(aout,mkobject) (abfd)
+ bfd *abfd;
+{
+ struct aout_data_struct *rawptr;
+
+ bfd_set_error (bfd_error_system_call);
+
+ /* Use an intermediate variable for clarity */
+ rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
+
+ if (rawptr == NULL)
+ return false;
+
+ abfd->tdata.aout_data = rawptr;
+ exec_hdr (abfd) = &(rawptr->e);
+
+ obj_textsec (abfd) = (asection *)NULL;
+ obj_datasec (abfd) = (asection *)NULL;
+ obj_bsssec (abfd) = (asection *)NULL;
+
+ return true;
+}
+
+
+/*
+FUNCTION
+ aout_@var{size}_machine_type
+
+SYNOPSIS
+ enum machine_type aout_@var{size}_machine_type
+ (enum bfd_architecture arch,
+ unsigned long machine));
+
+DESCRIPTION
+ Keep track of machine architecture and machine type for
+ a.out's. Return the <<machine_type>> for a particular
+ architecture and machine, or <<M_UNKNOWN>> if that exact architecture
+ and machine can't be represented in a.out format.
+
+ If the architecture is understood, machine type 0 (default)
+ is always understood.
+*/
+
+enum machine_type
+NAME(aout,machine_type) (arch, machine, unknown)
+ enum bfd_architecture arch;
+ unsigned long machine;
+ boolean *unknown;
+{
+ enum machine_type arch_flags;
+
+ arch_flags = M_UNKNOWN;
+ *unknown = true;
+
+ switch (arch) {
+ case bfd_arch_sparc:
+ if (machine == 0
+ || machine == bfd_mach_sparc
+ || machine == bfd_mach_sparc_sparclite
+ || machine == bfd_mach_sparc_sparclite_le
+ || machine == bfd_mach_sparc_v9)
+ arch_flags = M_SPARC;
+ else if (machine == bfd_mach_sparc_sparclet)
+ arch_flags = M_SPARCLET;
+ break;
+
+ case bfd_arch_m68k:
+ switch (machine) {
+ case 0: arch_flags = M_68010; break;
+ case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = false; break;
+ case bfd_mach_m68010: arch_flags = M_68010; break;
+ case bfd_mach_m68020: arch_flags = M_68020; break;
+ default: arch_flags = M_UNKNOWN; break;
+ }
+ break;
+
+ case bfd_arch_i386:
+ if (machine == 0) arch_flags = M_386;
+ break;
+
+ case bfd_arch_a29k:
+ if (machine == 0) arch_flags = M_29K;
+ break;
+
+ case bfd_arch_arm:
+ if (machine == 0) arch_flags = M_ARM;
+ break;
+
+ case bfd_arch_mips:
+ switch (machine) {
+ case 0:
+ case bfd_mach_mips3000:
+ case bfd_mach_mips3900:
+ arch_flags = M_MIPS1;
+ break;
+ case bfd_mach_mips6000:
+ arch_flags = M_MIPS2;
+ break;
+ case bfd_mach_mips4000:
+ case bfd_mach_mips4010:
+ case bfd_mach_mips4100:
+ case bfd_mach_mips4300:
+ case bfd_mach_mips4400:
+ case bfd_mach_mips4600:
+ case bfd_mach_mips4650:
+ case bfd_mach_mips8000:
+ case bfd_mach_mips10000:
+ case bfd_mach_mips16:
+ /* FIXME: These should be MIPS3 or MIPS4. */
+ arch_flags = M_MIPS2;
+ break;
+ default:
+ arch_flags = M_UNKNOWN;
+ break;
+ }
+ break;
+
+ case bfd_arch_ns32k:
+ switch (machine) {
+ case 0: arch_flags = M_NS32532; break;
+ case 32032: arch_flags = M_NS32032; break;
+ case 32532: arch_flags = M_NS32532; break;
+ default: arch_flags = M_UNKNOWN; break;
+ }
+ break;
+
+ case bfd_arch_vax:
+ *unknown = false;
+ break;
+
+ default:
+ arch_flags = M_UNKNOWN;
+ }
+
+ if (arch_flags != M_UNKNOWN)
+ *unknown = false;
+
+ return arch_flags;
+}
+
+
+/*
+FUNCTION
+ aout_@var{size}_set_arch_mach
+
+SYNOPSIS
+ boolean aout_@var{size}_set_arch_mach,
+ (bfd *,
+ enum bfd_architecture arch,
+ unsigned long machine));
+
+DESCRIPTION
+ Set the architecture and the machine of the BFD @var{abfd} to the
+ values @var{arch} and @var{machine}. Verify that @var{abfd}'s format
+ can support the architecture required.
+*/
+
+boolean
+NAME(aout,set_arch_mach) (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ if (! bfd_default_set_arch_mach (abfd, arch, machine))
+ return false;
+
+ if (arch != bfd_arch_unknown)
+ {
+ boolean unknown;
+
+ NAME(aout,machine_type) (arch, machine, &unknown);
+ if (unknown)
+ return false;
+ }
+
+ /* Determine the size of a relocation entry */
+ switch (arch) {
+ case bfd_arch_sparc:
+ case bfd_arch_a29k:
+ case bfd_arch_mips:
+ obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+ break;
+ default:
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+ break;
+ }
+
+ return (*aout_backend_info(abfd)->set_sizes) (abfd);
+}
+
+static void
+adjust_o_magic (abfd, execp)
+ bfd *abfd;
+ struct internal_exec *execp;
+{
+ file_ptr pos = adata (abfd).exec_bytes_size;
+ bfd_vma vma = 0;
+ int pad = 0;
+
+ /* Text. */
+ obj_textsec(abfd)->filepos = pos;
+ if (!obj_textsec(abfd)->user_set_vma)
+ obj_textsec(abfd)->vma = vma;
+ else
+ vma = obj_textsec(abfd)->vma;
+
+ pos += obj_textsec(abfd)->_raw_size;
+ vma += obj_textsec(abfd)->_raw_size;
+
+ /* Data. */
+ if (!obj_datasec(abfd)->user_set_vma)
+ {
+#if 0 /* ?? Does alignment in the file image really matter? */
+ pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
+#endif
+ obj_textsec(abfd)->_raw_size += pad;
+ pos += pad;
+ vma += pad;
+ obj_datasec(abfd)->vma = vma;
+ }
+ else
+ vma = obj_datasec(abfd)->vma;
+ obj_datasec(abfd)->filepos = pos;
+ pos += obj_datasec(abfd)->_raw_size;
+ vma += obj_datasec(abfd)->_raw_size;
+
+ /* BSS. */
+ if (!obj_bsssec(abfd)->user_set_vma)
+ {
+#if 0
+ pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
+#endif
+ obj_datasec(abfd)->_raw_size += pad;
+ pos += pad;
+ vma += pad;
+ obj_bsssec(abfd)->vma = vma;
+ }
+ else
+ {
+ /* The VMA of the .bss section is set by the the VMA of the
+ .data section plus the size of the .data section. We may
+ need to add padding bytes to make this true. */
+ pad = obj_bsssec (abfd)->vma - vma;
+ if (pad > 0)
+ {
+ obj_datasec (abfd)->_raw_size += pad;
+ pos += pad;
+ }
+ }
+ obj_bsssec(abfd)->filepos = pos;
+
+ /* Fix up the exec header. */
+ execp->a_text = obj_textsec(abfd)->_raw_size;
+ execp->a_data = obj_datasec(abfd)->_raw_size;
+ execp->a_bss = obj_bsssec(abfd)->_raw_size;
+ N_SET_MAGIC (*execp, OMAGIC);
+}
+
+static void
+adjust_z_magic (abfd, execp)
+ bfd *abfd;
+ struct internal_exec *execp;
+{
+ bfd_size_type data_pad, text_pad;
+ file_ptr text_end;
+ CONST struct aout_backend_data *abdp;
+ int ztih; /* Nonzero if text includes exec header. */
+
+ abdp = aout_backend_info (abfd);
+
+ /* Text. */
+ ztih = (abdp != NULL
+ && (abdp->text_includes_header
+ || obj_aout_subformat (abfd) == q_magic_format));
+ obj_textsec(abfd)->filepos = (ztih
+ ? adata(abfd).exec_bytes_size
+ : adata(abfd).zmagic_disk_block_size);
+ if (! obj_textsec(abfd)->user_set_vma)
+ {
+ /* ?? Do we really need to check for relocs here? */
+ obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
+ ? 0
+ : (ztih
+ ? (abdp->default_text_vma
+ + adata(abfd).exec_bytes_size)
+ : abdp->default_text_vma));
+ text_pad = 0;
+ }
+ else
+ {
+ /* The .text section is being loaded at an unusual address. We
+ may need to pad it such that the .data section starts at a page
+ boundary. */
+ if (ztih)
+ text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
+ & (adata (abfd).page_size - 1));
+ else
+ text_pad = ((- obj_textsec (abfd)->vma)
+ & (adata (abfd).page_size - 1));
+ }
+
+ /* Find start of data. */
+ if (ztih)
+ {
+ text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size;
+ text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
+ }
+ else
+ {
+ /* Note that if page_size == zmagic_disk_block_size, then
+ filepos == page_size, and this case is the same as the ztih
+ case. */
+ text_end = obj_textsec (abfd)->_raw_size;
+ text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
+ text_end += obj_textsec (abfd)->filepos;
+ }
+ obj_textsec(abfd)->_raw_size += text_pad;
+ text_end += text_pad;
+
+ /* Data. */
+ if (!obj_datasec(abfd)->user_set_vma)
+ {
+ bfd_vma vma;
+ vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
+ obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
+ }
+ if (abdp && abdp->zmagic_mapped_contiguous)
+ {
+ text_pad = (obj_datasec(abfd)->vma
+ - obj_textsec(abfd)->vma
+ - obj_textsec(abfd)->_raw_size);
+ obj_textsec(abfd)->_raw_size += text_pad;
+ }
+ obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
+ + obj_textsec(abfd)->_raw_size);
+
+ /* Fix up exec header while we're at it. */
+ execp->a_text = obj_textsec(abfd)->_raw_size;
+ if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
+ execp->a_text += adata(abfd).exec_bytes_size;
+ if (obj_aout_subformat (abfd) == q_magic_format)
+ N_SET_MAGIC (*execp, QMAGIC);
+ else
+ N_SET_MAGIC (*execp, ZMAGIC);
+
+ /* Spec says data section should be rounded up to page boundary. */
+ obj_datasec(abfd)->_raw_size
+ = align_power (obj_datasec(abfd)->_raw_size,
+ obj_bsssec(abfd)->alignment_power);
+ execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
+ adata(abfd).page_size);
+ data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
+
+ /* BSS. */
+ if (!obj_bsssec(abfd)->user_set_vma)
+ obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
+ + obj_datasec(abfd)->_raw_size);
+ /* If the BSS immediately follows the data section and extra space
+ in the page is left after the data section, fudge data
+ in the header so that the bss section looks smaller by that
+ amount. We'll start the bss section there, and lie to the OS.
+ (Note that a linker script, as well as the above assignment,
+ could have explicitly set the BSS vma to immediately follow
+ the data section.) */
+ if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
+ == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size)
+ execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
+ obj_bsssec(abfd)->_raw_size - data_pad;
+ else
+ execp->a_bss = obj_bsssec(abfd)->_raw_size;
+}
+
+static void
+adjust_n_magic (abfd, execp)
+ bfd *abfd;
+ struct internal_exec *execp;
+{
+ file_ptr pos = adata(abfd).exec_bytes_size;
+ bfd_vma vma = 0;
+ int pad;
+
+ /* Text. */
+ obj_textsec(abfd)->filepos = pos;
+ if (!obj_textsec(abfd)->user_set_vma)
+ obj_textsec(abfd)->vma = vma;
+ else
+ vma = obj_textsec(abfd)->vma;
+ pos += obj_textsec(abfd)->_raw_size;
+ vma += obj_textsec(abfd)->_raw_size;
+
+ /* Data. */
+ obj_datasec(abfd)->filepos = pos;
+ if (!obj_datasec(abfd)->user_set_vma)
+ obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
+ vma = obj_datasec(abfd)->vma;
+
+ /* Since BSS follows data immediately, see if it needs alignment. */
+ vma += obj_datasec(abfd)->_raw_size;
+ pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
+ obj_datasec(abfd)->_raw_size += pad;
+ pos += obj_datasec(abfd)->_raw_size;
+
+ /* BSS. */
+ if (!obj_bsssec(abfd)->user_set_vma)
+ obj_bsssec(abfd)->vma = vma;
+ else
+ vma = obj_bsssec(abfd)->vma;
+
+ /* Fix up exec header. */
+ execp->a_text = obj_textsec(abfd)->_raw_size;
+ execp->a_data = obj_datasec(abfd)->_raw_size;
+ execp->a_bss = obj_bsssec(abfd)->_raw_size;
+ N_SET_MAGIC (*execp, NMAGIC);
+}
+
+boolean
+NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
+ bfd *abfd;
+ bfd_size_type *text_size;
+ file_ptr *text_end;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ if (! NAME(aout,make_sections) (abfd))
+ return false;
+
+ if (adata(abfd).magic != undecided_magic)
+ return true;
+
+ obj_textsec(abfd)->_raw_size =
+ align_power(obj_textsec(abfd)->_raw_size,
+ obj_textsec(abfd)->alignment_power);
+
+ *text_size = obj_textsec (abfd)->_raw_size;
+ /* Rule (heuristic) for when to pad to a new page. Note that there
+ are (at least) two ways demand-paged (ZMAGIC) files have been
+ handled. Most Berkeley-based systems start the text segment at
+ (TARGET_PAGE_SIZE). However, newer versions of SUNOS start the text
+ segment right after the exec header; the latter is counted in the
+ text segment size, and is paged in by the kernel with the rest of
+ the text. */
+
+ /* This perhaps isn't the right way to do this, but made it simpler for me
+ to understand enough to implement it. Better would probably be to go
+ right from BFD flags to alignment/positioning characteristics. But the
+ old code was sloppy enough about handling the flags, and had enough
+ other magic, that it was a little hard for me to understand. I think
+ I understand it better now, but I haven't time to do the cleanup this
+ minute. */
+
+ if (abfd->flags & D_PAGED)
+ /* Whether or not WP_TEXT is set -- let D_PAGED override. */
+ adata(abfd).magic = z_magic;
+ else if (abfd->flags & WP_TEXT)
+ adata(abfd).magic = n_magic;
+ else
+ adata(abfd).magic = o_magic;
+
+#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
+#if __GNUC__ >= 2
+ fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
+ ({ char *str;
+ switch (adata(abfd).magic) {
+ case n_magic: str = "NMAGIC"; break;
+ case o_magic: str = "OMAGIC"; break;
+ case z_magic: str = "ZMAGIC"; break;
+ default: abort ();
+ }
+ str;
+ }),
+ obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
+ obj_textsec(abfd)->alignment_power,
+ obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
+ obj_datasec(abfd)->alignment_power,
+ obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size,
+ obj_bsssec(abfd)->alignment_power);
+#endif
+#endif
+
+ switch (adata(abfd).magic)
+ {
+ case o_magic:
+ adjust_o_magic (abfd, execp);
+ break;
+ case z_magic:
+ adjust_z_magic (abfd, execp);
+ break;
+ case n_magic:
+ adjust_n_magic (abfd, execp);
+ break;
+ default:
+ abort ();
+ }
+
+#ifdef BFD_AOUT_DEBUG
+ fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
+ obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
+ obj_textsec(abfd)->filepos,
+ obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
+ obj_datasec(abfd)->filepos,
+ obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
+#endif
+
+ return true;
+}
+
+/*
+FUNCTION
+ aout_@var{size}_new_section_hook
+
+SYNOPSIS
+ boolean aout_@var{size}_new_section_hook,
+ (bfd *abfd,
+ asection *newsect));
+
+DESCRIPTION
+ Called by the BFD in response to a @code{bfd_make_section}
+ request.
+*/
+boolean
+NAME(aout,new_section_hook) (abfd, newsect)
+ bfd *abfd;
+ asection *newsect;
+{
+ /* align to double at least */
+ newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
+
+
+ if (bfd_get_format (abfd) == bfd_object)
+ {
+ if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
+ obj_textsec(abfd)= newsect;
+ newsect->target_index = N_TEXT;
+ return true;
+ }
+
+ if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
+ obj_datasec(abfd) = newsect;
+ newsect->target_index = N_DATA;
+ return true;
+ }
+
+ if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
+ obj_bsssec(abfd) = newsect;
+ newsect->target_index = N_BSS;
+ return true;
+ }
+
+ }
+
+ /* We allow more than three sections internally */
+ return true;
+}
+
+boolean
+NAME(aout,set_section_contents) (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ file_ptr text_end;
+ bfd_size_type text_size;
+
+ if (! abfd->output_has_begun)
+ {
+ if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
+ return false;
+ }
+
+ if (section == obj_bsssec (abfd))
+ {
+ bfd_set_error (bfd_error_no_contents);
+ return false;
+ }
+
+ if (section != obj_textsec (abfd)
+ && section != obj_datasec (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%s: can not represent section `%s' in a.out object file format"),
+ bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+
+ if (count != 0)
+ {
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+ || bfd_write (location, 1, count, abfd) != count)
+ return false;
+ }
+
+ return true;
+}
+
+/* Read the external symbols from an a.out file. */
+
+static boolean
+aout_get_external_symbols (abfd)
+ bfd *abfd;
+{
+ if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
+ {
+ bfd_size_type count;
+ struct external_nlist *syms;
+
+ count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
+
+#ifdef USE_MMAP
+ if (bfd_get_file_window (abfd,
+ obj_sym_filepos (abfd), exec_hdr (abfd)->a_syms,
+ &obj_aout_sym_window (abfd), true) == false)
+ return false;
+ syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
+#else
+ /* We allocate using malloc to make the values easy to free
+ later on. If we put them on the objalloc it might not be
+ possible to free them. */
+ syms = ((struct external_nlist *)
+ bfd_malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
+ if (syms == (struct external_nlist *) NULL && count != 0)
+ return false;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd)
+ != exec_hdr (abfd)->a_syms))
+ {
+ free (syms);
+ return false;
+ }
+#endif
+
+ obj_aout_external_syms (abfd) = syms;
+ obj_aout_external_sym_count (abfd) = count;
+ }
+
+ if (obj_aout_external_strings (abfd) == NULL
+ && exec_hdr (abfd)->a_syms != 0)
+ {
+ unsigned char string_chars[BYTES_IN_WORD];
+ bfd_size_type stringsize;
+ char *strings;
+
+ /* Get the size of the strings. */
+ if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
+ || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
+ != BYTES_IN_WORD))
+ return false;
+ stringsize = GET_WORD (abfd, string_chars);
+
+#ifdef USE_MMAP
+ if (bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
+ &obj_aout_string_window (abfd), true) == false)
+ return false;
+ strings = (char *) obj_aout_string_window (abfd).data;
+#else
+ strings = (char *) bfd_malloc ((size_t) stringsize + 1);
+ if (strings == NULL)
+ return false;
+
+ /* Skip space for the string count in the buffer for convenience
+ when using indexes. */
+ if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD,
+ abfd)
+ != stringsize - BYTES_IN_WORD)
+ {
+ free (strings);
+ return false;
+ }
+#endif
+
+ /* Ensure that a zero index yields an empty string. */
+ strings[0] = '\0';
+
+ strings[stringsize - 1] = 0;
+
+ obj_aout_external_strings (abfd) = strings;
+ obj_aout_external_string_size (abfd) = stringsize;
+ }
+
+ return true;
+}
+
+/* Translate an a.out symbol into a BFD symbol. The desc, other, type
+ and symbol->value fields of CACHE_PTR will be set from the a.out
+ nlist structure. This function is responsible for setting
+ symbol->flags and symbol->section, and adjusting symbol->value. */
+
+static boolean
+translate_from_native_sym_flags (abfd, cache_ptr)
+ bfd *abfd;
+ aout_symbol_type *cache_ptr;
+{
+ flagword visible;
+
+ if ((cache_ptr->type & N_STAB) != 0
+ || cache_ptr->type == N_FN)
+ {
+ asection *sec;
+
+ /* This is a debugging symbol. */
+
+ cache_ptr->symbol.flags = BSF_DEBUGGING;
+
+ /* Work out the symbol section. */
+ switch (cache_ptr->type & N_TYPE)
+ {
+ case N_TEXT:
+ case N_FN:
+ sec = obj_textsec (abfd);
+ break;
+ case N_DATA:
+ sec = obj_datasec (abfd);
+ break;
+ case N_BSS:
+ sec = obj_bsssec (abfd);
+ break;
+ default:
+ case N_ABS:
+ sec = bfd_abs_section_ptr;
+ break;
+ }
+
+ cache_ptr->symbol.section = sec;
+ cache_ptr->symbol.value -= sec->vma;
+
+ return true;
+ }
+
+ /* Get the default visibility. This does not apply to all types, so
+ we just hold it in a local variable to use if wanted. */
+ if ((cache_ptr->type & N_EXT) == 0)
+ visible = BSF_LOCAL;
+ else
+ visible = BSF_GLOBAL;
+
+ switch (cache_ptr->type)
+ {
+ default:
+ case N_ABS: case N_ABS | N_EXT:
+ cache_ptr->symbol.section = bfd_abs_section_ptr;
+ cache_ptr->symbol.flags = visible;
+ break;
+
+ case N_UNDF | N_EXT:
+ if (cache_ptr->symbol.value != 0)
+ {
+ /* This is a common symbol. */
+ cache_ptr->symbol.flags = BSF_GLOBAL;
+ cache_ptr->symbol.section = bfd_com_section_ptr;
+ }
+ else
+ {
+ cache_ptr->symbol.flags = 0;
+ cache_ptr->symbol.section = bfd_und_section_ptr;
+ }
+ break;
+
+ case N_TEXT: case N_TEXT | N_EXT:
+ cache_ptr->symbol.section = obj_textsec (abfd);
+ cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
+ cache_ptr->symbol.flags = visible;
+ break;
+
+ /* N_SETV symbols used to represent set vectors placed in the
+ data section. They are no longer generated. Theoretically,
+ it was possible to extract the entries and combine them with
+ new ones, although I don't know if that was ever actually
+ done. Unless that feature is restored, treat them as data
+ symbols. */
+ case N_SETV: case N_SETV | N_EXT:
+ case N_DATA: case N_DATA | N_EXT:
+ cache_ptr->symbol.section = obj_datasec (abfd);
+ cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
+ cache_ptr->symbol.flags = visible;
+ break;
+
+ case N_BSS: case N_BSS | N_EXT:
+ cache_ptr->symbol.section = obj_bsssec (abfd);
+ cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
+ cache_ptr->symbol.flags = visible;
+ break;
+
+ case N_SETA: case N_SETA | N_EXT:
+ case N_SETT: case N_SETT | N_EXT:
+ case N_SETD: case N_SETD | N_EXT:
+ case N_SETB: case N_SETB | N_EXT:
+ {
+ /* This code is no longer needed. It used to be used to make
+ the linker handle set symbols, but they are now handled in
+ the add_symbols routine instead. */
+#if 0
+ asection *section;
+ arelent_chain *reloc;
+ asection *into_section;
+
+ /* This is a set symbol. The name of the symbol is the name
+ of the set (e.g., __CTOR_LIST__). The value of the symbol
+ is the value to add to the set. We create a section with
+ the same name as the symbol, and add a reloc to insert the
+ appropriate value into the section.
+
+ This action is actually obsolete; it used to make the
+ linker do the right thing, but the linker no longer uses
+ this function. */
+
+ section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name);
+ if (section == NULL)
+ {
+ char *copy;
+
+ copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
+ if (copy == NULL)
+ return false;
+
+ strcpy (copy, cache_ptr->symbol.name);
+ section = bfd_make_section (abfd, copy);
+ if (section == NULL)
+ return false;
+ }
+
+ reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
+ if (reloc == NULL)
+ return false;
+
+ /* Build a relocation entry for the constructor. */
+ switch (cache_ptr->type & N_TYPE)
+ {
+ case N_SETA:
+ into_section = bfd_abs_section_ptr;
+ cache_ptr->type = N_ABS;
+ break;
+ case N_SETT:
+ into_section = obj_textsec (abfd);
+ cache_ptr->type = N_TEXT;
+ break;
+ case N_SETD:
+ into_section = obj_datasec (abfd);
+ cache_ptr->type = N_DATA;
+ break;
+ case N_SETB:
+ into_section = obj_bsssec (abfd);
+ cache_ptr->type = N_BSS;
+ break;
+ }
+
+ /* Build a relocation pointing into the constructor section
+ pointing at the symbol in the set vector specified. */
+ reloc->relent.addend = cache_ptr->symbol.value;
+ cache_ptr->symbol.section = into_section;
+ reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
+
+ /* We modify the symbol to belong to a section depending upon
+ the name of the symbol, and add to the size of the section
+ to contain a pointer to the symbol. Build a reloc entry to
+ relocate to this symbol attached to this section. */
+ section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
+
+ section->reloc_count++;
+ section->alignment_power = 2;
+
+ reloc->next = section->constructor_chain;
+ section->constructor_chain = reloc;
+ reloc->relent.address = section->_raw_size;
+ section->_raw_size += BYTES_IN_WORD;
+
+ reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd);
+
+#endif /* 0 */
+
+ switch (cache_ptr->type & N_TYPE)
+ {
+ case N_SETA:
+ cache_ptr->symbol.section = bfd_abs_section_ptr;
+ break;
+ case N_SETT:
+ cache_ptr->symbol.section = obj_textsec (abfd);
+ break;
+ case N_SETD:
+ cache_ptr->symbol.section = obj_datasec (abfd);
+ break;
+ case N_SETB:
+ cache_ptr->symbol.section = obj_bsssec (abfd);
+ break;
+ }
+
+ cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
+ }
+ break;
+
+ case N_WARNING:
+ /* This symbol is the text of a warning message. The next
+ symbol is the symbol to associate the warning with. If a
+ reference is made to that symbol, a warning is issued. */
+ cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
+ cache_ptr->symbol.section = bfd_abs_section_ptr;
+ break;
+
+ case N_INDR: case N_INDR | N_EXT:
+ /* An indirect symbol. This consists of two symbols in a row.
+ The first symbol is the name of the indirection. The second
+ symbol is the name of the target. A reference to the first
+ symbol becomes a reference to the second. */
+ cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
+ cache_ptr->symbol.section = bfd_ind_section_ptr;
+ break;
+
+ case N_WEAKU:
+ cache_ptr->symbol.section = bfd_und_section_ptr;
+ cache_ptr->symbol.flags = BSF_WEAK;
+ break;
+
+ case N_WEAKA:
+ cache_ptr->symbol.section = bfd_abs_section_ptr;
+ cache_ptr->symbol.flags = BSF_WEAK;
+ break;
+
+ case N_WEAKT:
+ cache_ptr->symbol.section = obj_textsec (abfd);
+ cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
+ cache_ptr->symbol.flags = BSF_WEAK;
+ break;
+
+ case N_WEAKD:
+ cache_ptr->symbol.section = obj_datasec (abfd);
+ cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
+ cache_ptr->symbol.flags = BSF_WEAK;
+ break;
+
+ case N_WEAKB:
+ cache_ptr->symbol.section = obj_bsssec (abfd);
+ cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
+ cache_ptr->symbol.flags = BSF_WEAK;
+ break;
+ }
+
+ return true;
+}
+
+/* Set the fields of SYM_POINTER according to CACHE_PTR. */
+
+static boolean
+translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
+ bfd *abfd;
+ asymbol *cache_ptr;
+ struct external_nlist *sym_pointer;
+{
+ bfd_vma value = cache_ptr->value;
+ asection *sec;
+ bfd_vma off;
+
+ /* Mask out any existing type bits in case copying from one section
+ to another. */
+ sym_pointer->e_type[0] &= ~N_TYPE;
+
+ sec = bfd_get_section (cache_ptr);
+ off = 0;
+
+ if (sec == NULL)
+ {
+ /* This case occurs, e.g., for the *DEBUG* section of a COFF
+ file. */
+ (*_bfd_error_handler)
+ (_("%s: can not represent section for symbol `%s' in a.out object file format"),
+ bfd_get_filename (abfd),
+ cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+
+ if (sec->output_section != NULL)
+ {
+ off = sec->output_offset;
+ sec = sec->output_section;
+ }
+
+ if (bfd_is_abs_section (sec))
+ sym_pointer->e_type[0] |= N_ABS;
+ else if (sec == obj_textsec (abfd))
+ sym_pointer->e_type[0] |= N_TEXT;
+ else if (sec == obj_datasec (abfd))
+ sym_pointer->e_type[0] |= N_DATA;
+ else if (sec == obj_bsssec (abfd))
+ sym_pointer->e_type[0] |= N_BSS;
+ else if (bfd_is_und_section (sec))
+ sym_pointer->e_type[0] = N_UNDF | N_EXT;
+ else if (bfd_is_ind_section (sec))
+ sym_pointer->e_type[0] = N_INDR;
+ else if (bfd_is_com_section (sec))
+ sym_pointer->e_type[0] = N_UNDF | N_EXT;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: can not represent section `%s' in a.out object file format"),
+ bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+
+ /* Turn the symbol from section relative to absolute again */
+ value += sec->vma + off;
+
+ if ((cache_ptr->flags & BSF_WARNING) != 0)
+ sym_pointer->e_type[0] = N_WARNING;
+
+ if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
+ sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
+ else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
+ sym_pointer->e_type[0] |= N_EXT;
+
+ if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
+ {
+ int type = ((aout_symbol_type *) cache_ptr)->type;
+ switch (type)
+ {
+ case N_ABS: type = N_SETA; break;
+ case N_TEXT: type = N_SETT; break;
+ case N_DATA: type = N_SETD; break;
+ case N_BSS: type = N_SETB; break;
+ }
+ sym_pointer->e_type[0] = type;
+ }
+
+ if ((cache_ptr->flags & BSF_WEAK) != 0)
+ {
+ int type;
+
+ switch (sym_pointer->e_type[0] & N_TYPE)
+ {
+ default:
+ case N_ABS: type = N_WEAKA; break;
+ case N_TEXT: type = N_WEAKT; break;
+ case N_DATA: type = N_WEAKD; break;
+ case N_BSS: type = N_WEAKB; break;
+ case N_UNDF: type = N_WEAKU; break;
+ }
+ sym_pointer->e_type[0] = type;
+ }
+
+ PUT_WORD(abfd, value, sym_pointer->e_value);
+
+ return true;
+}
+
+/* Native-level interface to symbols. */
+
+asymbol *
+NAME(aout,make_empty_symbol) (abfd)
+ bfd *abfd;
+{
+ aout_symbol_type *new =
+ (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
+ if (!new)
+ return NULL;
+ new->symbol.the_bfd = abfd;
+
+ return &new->symbol;
+}
+
+/* Translate a set of internal symbols into external symbols. */
+
+boolean
+NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
+ bfd *abfd;
+ aout_symbol_type *in;
+ struct external_nlist *ext;
+ bfd_size_type count;
+ char *str;
+ bfd_size_type strsize;
+ boolean dynamic;
+{
+ struct external_nlist *ext_end;
+
+ ext_end = ext + count;
+ for (; ext < ext_end; ext++, in++)
+ {
+ bfd_vma x;
+
+ x = GET_WORD (abfd, ext->e_strx);
+ in->symbol.the_bfd = abfd;
+
+ /* For the normal symbols, the zero index points at the number
+ of bytes in the string table but is to be interpreted as the
+ null string. For the dynamic symbols, the number of bytes in
+ the string table is stored in the __DYNAMIC structure and the
+ zero index points at an actual string. */
+ if (x == 0 && ! dynamic)
+ in->symbol.name = "";
+ else if (x < strsize)
+ in->symbol.name = str + x;
+ else
+ return false;
+
+ in->symbol.value = GET_SWORD (abfd, ext->e_value);
+ in->desc = bfd_h_get_16 (abfd, ext->e_desc);
+ in->other = bfd_h_get_8 (abfd, ext->e_other);
+ in->type = bfd_h_get_8 (abfd, ext->e_type);
+ in->symbol.udata.p = NULL;
+
+ if (! translate_from_native_sym_flags (abfd, in))
+ return false;
+
+ if (dynamic)
+ in->symbol.flags |= BSF_DYNAMIC;
+ }
+
+ return true;
+}
+
+/* We read the symbols into a buffer, which is discarded when this
+ function exits. We read the strings into a buffer large enough to
+ hold them all plus all the cached symbol entries. */
+
+boolean
+NAME(aout,slurp_symbol_table) (abfd)
+ bfd *abfd;
+{
+ struct external_nlist *old_external_syms;
+ aout_symbol_type *cached;
+ size_t cached_size;
+
+ /* If there's no work to be done, don't do any */
+ if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
+ return true;
+
+ old_external_syms = obj_aout_external_syms (abfd);
+
+ if (! aout_get_external_symbols (abfd))
+ return false;
+
+ cached_size = (obj_aout_external_sym_count (abfd)
+ * sizeof (aout_symbol_type));
+ cached = (aout_symbol_type *) bfd_malloc (cached_size);
+ if (cached == NULL && cached_size != 0)
+ return false;
+ if (cached_size != 0)
+ memset (cached, 0, cached_size);
+
+ /* Convert from external symbol information to internal. */
+ if (! (NAME(aout,translate_symbol_table)
+ (abfd, cached,
+ obj_aout_external_syms (abfd),
+ obj_aout_external_sym_count (abfd),
+ obj_aout_external_strings (abfd),
+ obj_aout_external_string_size (abfd),
+ false)))
+ {
+ free (cached);
+ return false;
+ }
+
+ bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
+
+ obj_aout_symbols (abfd) = cached;
+
+ /* It is very likely that anybody who calls this function will not
+ want the external symbol information, so if it was allocated
+ because of our call to aout_get_external_symbols, we free it up
+ right away to save space. */
+ if (old_external_syms == (struct external_nlist *) NULL
+ && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_sym_window (abfd));
+#else
+ free (obj_aout_external_syms (abfd));
+#endif
+ obj_aout_external_syms (abfd) = NULL;
+ }
+
+ return true;
+}
+
+/* We use a hash table when writing out symbols so that we only write
+ out a particular string once. This helps particularly when the
+ linker writes out stabs debugging entries, because each different
+ contributing object file tends to have many duplicate stabs
+ strings.
+
+ This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
+ if BFD_TRADITIONAL_FORMAT is set. */
+
+static bfd_size_type add_to_stringtab
+ PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
+static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
+
+/* Get the index of a string in a strtab, adding it if it is not
+ already present. */
+
+static INLINE bfd_size_type
+add_to_stringtab (abfd, tab, str, copy)
+ bfd *abfd;
+ struct bfd_strtab_hash *tab;
+ const char *str;
+ boolean copy;
+{
+ boolean hash;
+ bfd_size_type index;
+
+ /* An index of 0 always means the empty string. */
+ if (str == 0 || *str == '\0')
+ return 0;
+
+ /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
+ doesn't understand a hashed string table. */
+ hash = true;
+ if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = false;
+
+ index = _bfd_stringtab_add (tab, str, hash, copy);
+
+ if (index != (bfd_size_type) -1)
+ {
+ /* Add BYTES_IN_WORD to the return value to account for the
+ space taken up by the string table size. */
+ index += BYTES_IN_WORD;
+ }
+
+ return index;
+}
+
+/* Write out a strtab. ABFD is already at the right location in the
+ file. */
+
+static boolean
+emit_stringtab (abfd, tab)
+ register bfd *abfd;
+ struct bfd_strtab_hash *tab;
+{
+ bfd_byte buffer[BYTES_IN_WORD];
+
+ /* The string table starts with the size. */
+ PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
+ if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
+ return false;
+
+ return _bfd_stringtab_emit (abfd, tab);
+}
+
+boolean
+NAME(aout,write_syms) (abfd)
+ bfd *abfd;
+{
+ unsigned int count ;
+ asymbol **generic = bfd_get_outsymbols (abfd);
+ struct bfd_strtab_hash *strtab;
+
+ strtab = _bfd_stringtab_init ();
+ if (strtab == NULL)
+ return false;
+
+ for (count = 0; count < bfd_get_symcount (abfd); count++)
+ {
+ asymbol *g = generic[count];
+ bfd_size_type indx;
+ struct external_nlist nsp;
+
+ indx = add_to_stringtab (abfd, strtab, g->name, false);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
+
+ if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
+ {
+ bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc);
+ bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other);
+ bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type);
+ }
+ else
+ {
+ bfd_h_put_16(abfd,0, nsp.e_desc);
+ bfd_h_put_8(abfd, 0, nsp.e_other);
+ bfd_h_put_8(abfd, 0, nsp.e_type);
+ }
+
+ if (! translate_to_native_sym_flags (abfd, g, &nsp))
+ goto error_return;
+
+ if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
+ != EXTERNAL_NLIST_SIZE)
+ goto error_return;
+
+ /* NB: `KEEPIT' currently overlays `udata.p', so set this only
+ here, at the end. */
+ g->KEEPIT = count;
+ }
+
+ if (! emit_stringtab (abfd, strtab))
+ goto error_return;
+
+ _bfd_stringtab_free (strtab);
+
+ return true;
+
+error_return:
+ _bfd_stringtab_free (strtab);
+ return false;
+}
+
+
+long
+NAME(aout,get_symtab) (abfd, location)
+ bfd *abfd;
+ asymbol **location;
+{
+ unsigned int counter = 0;
+ aout_symbol_type *symbase;
+
+ if (!NAME(aout,slurp_symbol_table)(abfd))
+ return -1;
+
+ for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
+ *(location++) = (asymbol *)( symbase++);
+ *location++ =0;
+ return bfd_get_symcount (abfd);
+}
+
+
+/* Standard reloc stuff */
+/* Output standard relocation information to a file in target byte order. */
+
+extern void NAME(aout,swap_std_reloc_out)
+ PARAMS ((bfd *, arelent *, struct reloc_std_external *));
+
+void
+NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ struct reloc_std_external *natptr;
+{
+ int r_index;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ int r_extern;
+ unsigned int r_length;
+ int r_pcrel;
+ int r_baserel, r_jmptable, r_relative;
+ asection *output_section = sym->section->output_section;
+
+ PUT_WORD(abfd, g->address, natptr->r_address);
+
+ r_length = g->howto->size ; /* Size as a power of two */
+ r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
+ /* XXX This relies on relocs coming from a.out files. */
+ r_baserel = (g->howto->type & 8) != 0;
+ r_jmptable = (g->howto->type & 16) != 0;
+ r_relative = (g->howto->type & 32) != 0;
+
+#if 0
+ /* For a standard reloc, the addend is in the object file. */
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+#endif
+
+ /* name was clobbered by aout_write_syms to be symbol index */
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ check for that here
+ */
+
+
+ if (bfd_is_com_section (output_section)
+ || bfd_is_abs_section (output_section)
+ || bfd_is_und_section (output_section))
+ {
+ if (bfd_abs_section_ptr->symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_index = N_ABS;
+ r_extern = 0;
+ }
+ else
+ {
+ /* Fill in symbol */
+ r_extern = 1;
+ r_index = (*(g->sym_ptr_ptr))->KEEPIT;
+
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd)) {
+ natptr->r_index[0] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[2] = r_index;
+ natptr->r_type[0] =
+ (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
+ | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
+ | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
+ | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
+ | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
+ } else {
+ natptr->r_index[2] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[0] = r_index;
+ natptr->r_type[0] =
+ (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
+ | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
+ | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
+ | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
+ | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
+ }
+}
+
+
+/* Extended stuff */
+/* Output extended relocation information to a file in target byte order. */
+
+extern void NAME(aout,swap_ext_reloc_out)
+ PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
+
+void
+NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ register struct reloc_ext_external *natptr;
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_type;
+ unsigned int r_addend;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ asection *output_section = sym->section->output_section;
+
+ PUT_WORD (abfd, g->address, natptr->r_address);
+
+ r_type = (unsigned int) g->howto->type;
+
+ r_addend = g->addend;
+ if ((sym->flags & BSF_SECTION_SYM) != 0)
+ r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ check for that here. */
+
+ if (bfd_is_abs_section (bfd_get_section (sym)))
+ {
+ r_extern = 0;
+ r_index = N_ABS;
+ }
+ else if ((sym->flags & BSF_SECTION_SYM) == 0)
+ {
+ if (bfd_is_und_section (bfd_get_section (sym))
+ || (sym->flags & BSF_GLOBAL) != 0)
+ r_extern = 1;
+ else
+ r_extern = 0;
+ r_index = (*(g->sym_ptr_ptr))->KEEPIT;
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd)) {
+ natptr->r_index[0] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[2] = r_index;
+ natptr->r_type[0] =
+ ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
+ | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
+ } else {
+ natptr->r_index[2] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[0] = r_index;
+ natptr->r_type[0] =
+ (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
+ | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
+ }
+
+ PUT_WORD (abfd, r_addend, natptr->r_addend);
+}
+
+/* BFD deals internally with all things based from the section they're
+ in. so, something in 10 bytes into a text section with a base of
+ 50 would have a symbol (.text+10) and know .text vma was 50.
+
+ Aout keeps all it's symbols based from zero, so the symbol would
+ contain 60. This macro subs the base of each section from the value
+ to give the true offset from the section */
+
+
+#define MOVE_ADDRESS(ad) \
+ if (r_extern) { \
+ /* undefined symbol */ \
+ cache_ptr->sym_ptr_ptr = symbols + r_index; \
+ cache_ptr->addend = ad; \
+ } else { \
+ /* defined, section relative. replace symbol with pointer to \
+ symbol which points to section */ \
+ switch (r_index) { \
+ case N_TEXT: \
+ case N_TEXT | N_EXT: \
+ cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
+ cache_ptr->addend = ad - su->textsec->vma; \
+ break; \
+ case N_DATA: \
+ case N_DATA | N_EXT: \
+ cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
+ cache_ptr->addend = ad - su->datasec->vma; \
+ break; \
+ case N_BSS: \
+ case N_BSS | N_EXT: \
+ cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
+ cache_ptr->addend = ad - su->bsssec->vma; \
+ break; \
+ default: \
+ case N_ABS: \
+ case N_ABS | N_EXT: \
+ cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
+ cache_ptr->addend = ad; \
+ break; \
+ } \
+ } \
+
+void
+NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct reloc_ext_external *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ unsigned int r_index;
+ int r_extern;
+ unsigned int r_type;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd)) {
+ r_index = (bytes->r_index[0] << 16)
+ | (bytes->r_index[1] << 8)
+ | bytes->r_index[2];
+ r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
+ r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+ >> RELOC_EXT_BITS_TYPE_SH_BIG;
+ } else {
+ r_index = (bytes->r_index[2] << 16)
+ | (bytes->r_index[1] << 8)
+ | bytes->r_index[0];
+ r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
+ r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+ >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
+ }
+
+ cache_ptr->howto = howto_table_ext + r_type;
+
+ /* Base relative relocs are always against the symbol table,
+ regardless of the setting of r_extern. r_extern just reflects
+ whether the symbol the reloc is against is local or global. */
+ if (r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22)
+ r_extern = 1;
+
+ if (r_extern && r_index > symcount)
+ {
+ /* We could arrange to return an error, but it might be useful
+ to see the file even if it is bad. */
+ r_extern = 0;
+ r_index = N_ABS;
+ }
+
+ MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
+}
+
+void
+NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct reloc_std_external *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ unsigned int r_index;
+ int r_extern;
+ unsigned int r_length;
+ int r_pcrel;
+ int r_baserel, r_jmptable, r_relative;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+ unsigned int howto_idx;
+
+ cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd)) {
+ r_index = (bytes->r_index[0] << 16)
+ | (bytes->r_index[1] << 8)
+ | bytes->r_index[2];
+ r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
+ r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+ r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
+ r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+ r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
+ r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
+ >> RELOC_STD_BITS_LENGTH_SH_BIG;
+ } else {
+ r_index = (bytes->r_index[2] << 16)
+ | (bytes->r_index[1] << 8)
+ | bytes->r_index[0];
+ r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+ r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+ r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
+ r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
+ r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
+ r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+ >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
+ }
+
+ howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel
+ + 16 * r_jmptable + 32 * r_relative;
+ BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
+ cache_ptr->howto = howto_table_std + howto_idx;
+ BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
+
+ /* Base relative relocs are always against the symbol table,
+ regardless of the setting of r_extern. r_extern just reflects
+ whether the symbol the reloc is against is local or global. */
+ if (r_baserel)
+ r_extern = 1;
+
+ if (r_extern && r_index > symcount)
+ {
+ /* We could arrange to return an error, but it might be useful
+ to see the file even if it is bad. */
+ r_extern = 0;
+ r_index = N_ABS;
+ }
+
+ MOVE_ADDRESS(0);
+}
+
+/* Read and swap the relocs for a section. */
+
+boolean
+NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
+ bfd *abfd;
+ sec_ptr asect;
+ asymbol **symbols;
+{
+ unsigned int count;
+ bfd_size_type reloc_size;
+ PTR relocs;
+ arelent *reloc_cache;
+ size_t each_size;
+ unsigned int counter = 0;
+ arelent *cache_ptr;
+
+ if (asect->relocation)
+ return true;
+
+ if (asect->flags & SEC_CONSTRUCTOR)
+ return true;
+
+ if (asect == obj_datasec (abfd))
+ reloc_size = exec_hdr(abfd)->a_drsize;
+ else if (asect == obj_textsec (abfd))
+ reloc_size = exec_hdr(abfd)->a_trsize;
+ else if (asect == obj_bsssec (abfd))
+ reloc_size = 0;
+ else
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+ return false;
+
+ each_size = obj_reloc_entry_size (abfd);
+
+ count = reloc_size / each_size;
+
+ reloc_cache = (arelent *) bfd_malloc ((size_t) (count * sizeof (arelent)));
+ if (reloc_cache == NULL && count != 0)
+ return false;
+ memset (reloc_cache, 0, count * sizeof (arelent));
+
+ relocs = bfd_malloc ((size_t) reloc_size);
+ if (relocs == NULL && reloc_size != 0)
+ {
+ free (reloc_cache);
+ return false;
+ }
+
+ if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
+ {
+ free (relocs);
+ free (reloc_cache);
+ return false;
+ }
+
+ cache_ptr = reloc_cache;
+ if (each_size == RELOC_EXT_SIZE)
+ {
+ register struct reloc_ext_external *rptr =
+ (struct reloc_ext_external *) relocs;
+
+ for (; counter < count; counter++, rptr++, cache_ptr++)
+ NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
+ bfd_get_symcount (abfd));
+ }
+ else
+ {
+ register struct reloc_std_external *rptr =
+ (struct reloc_std_external *) relocs;
+
+ for (; counter < count; counter++, rptr++, cache_ptr++)
+ MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
+ bfd_get_symcount (abfd));
+ }
+
+ free (relocs);
+
+ asect->relocation = reloc_cache;
+ asect->reloc_count = cache_ptr - reloc_cache;
+
+ return true;
+}
+
+/* Write out a relocation section into an object file. */
+
+boolean
+NAME(aout,squirt_out_relocs) (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ arelent **generic;
+ unsigned char *native, *natptr;
+ size_t each_size;
+
+ unsigned int count = section->reloc_count;
+ size_t natsize;
+
+ if (count == 0 || section->orelocation == NULL)
+ return true;
+
+ each_size = obj_reloc_entry_size (abfd);
+ natsize = each_size * count;
+ native = (unsigned char *) bfd_zalloc (abfd, natsize);
+ if (!native)
+ return false;
+
+ generic = section->orelocation;
+
+ if (each_size == RELOC_EXT_SIZE)
+ {
+ for (natptr = native;
+ count != 0;
+ --count, natptr += each_size, ++generic)
+ NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
+ }
+ else
+ {
+ for (natptr = native;
+ count != 0;
+ --count, natptr += each_size, ++generic)
+ MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr);
+ }
+
+ if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
+ bfd_release(abfd, native);
+ return false;
+ }
+ bfd_release (abfd, native);
+
+ return true;
+}
+
+/* This is stupid. This function should be a boolean predicate */
+long
+NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr = section->relocation;
+ unsigned int count;
+
+ if (section == obj_bsssec (abfd))
+ {
+ *relptr = NULL;
+ return 0;
+ }
+
+ if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
+ return -1;
+
+ if (section->flags & SEC_CONSTRUCTOR) {
+ arelent_chain *chain = section->constructor_chain;
+ for (count = 0; count < section->reloc_count; count ++) {
+ *relptr ++ = &chain->relent;
+ chain = chain->next;
+ }
+ }
+ else {
+ tblptr = section->relocation;
+
+ for (count = 0; count++ < section->reloc_count;)
+ {
+ *relptr++ = tblptr++;
+ }
+ }
+ *relptr = 0;
+
+ return section->reloc_count;
+}
+
+long
+NAME(aout,get_reloc_upper_bound) (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ if (bfd_get_format (abfd) != bfd_object) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+ if (asect->flags & SEC_CONSTRUCTOR) {
+ return (sizeof (arelent *) * (asect->reloc_count+1));
+ }
+
+ if (asect == obj_datasec (abfd))
+ return (sizeof (arelent *)
+ * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
+ + 1));
+
+ if (asect == obj_textsec (abfd))
+ return (sizeof (arelent *)
+ * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
+ + 1));
+
+ if (asect == obj_bsssec (abfd))
+ return sizeof (arelent *);
+
+ if (asect == obj_bsssec (abfd))
+ return 0;
+
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+}
+
+
+long
+NAME(aout,get_symtab_upper_bound) (abfd)
+ bfd *abfd;
+{
+ if (!NAME(aout,slurp_symbol_table)(abfd))
+ return -1;
+
+ return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
+}
+
+/*ARGSUSED*/
+ alent *
+NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
+ bfd *ignore_abfd;
+ asymbol *ignore_symbol;
+{
+return (alent *)NULL;
+}
+
+/*ARGSUSED*/
+void
+NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+
+ if (ret->type == '?')
+ {
+ int type_code = aout_symbol(symbol)->type & 0xff;
+ const char *stab_name = bfd_get_stab_name (type_code);
+ static char buf[10];
+
+ if (stab_name == NULL)
+ {
+ sprintf(buf, "(%d)", type_code);
+ stab_name = buf;
+ }
+ ret->type = '-';
+ ret->stab_type = type_code;
+ ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
+ ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
+ ret->stab_name = stab_name;
+ }
+}
+
+/*ARGSUSED*/
+void
+NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *)afile;
+
+ switch (how) {
+ case bfd_print_symbol_name:
+ if (symbol->name)
+ fprintf(file,"%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
+ (unsigned)(aout_symbol(symbol)->other & 0xff),
+ (unsigned)(aout_symbol(symbol)->type));
+ break;
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name = symbol->section->name;
+
+
+ bfd_print_symbol_vandf((PTR)file,symbol);
+
+ fprintf(file," %-5s %04x %02x %02x",
+ section_name,
+ (unsigned)(aout_symbol(symbol)->desc & 0xffff),
+ (unsigned)(aout_symbol(symbol)->other & 0xff),
+ (unsigned)(aout_symbol(symbol)->type & 0xff));
+ if (symbol->name)
+ fprintf(file," %s", symbol->name);
+ }
+ break;
+ }
+}
+
+/* If we don't have to allocate more than 1MB to hold the generic
+ symbols, we use the generic minisymbol methord: it's faster, since
+ it only translates the symbols once, not multiple times. */
+#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
+
+/* Read minisymbols. For minisymbols, we use the unmodified a.out
+ symbols. The minisymbol_to_symbol function translates these into
+ BFD asymbol structures. */
+
+long
+NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
+ bfd *abfd;
+ boolean dynamic;
+ PTR *minisymsp;
+ unsigned int *sizep;
+{
+ if (dynamic)
+ {
+ /* We could handle the dynamic symbols here as well, but it's
+ easier to hand them off. */
+ return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
+ }
+
+ if (! aout_get_external_symbols (abfd))
+ return -1;
+
+ if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
+ return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
+
+ *minisymsp = (PTR) obj_aout_external_syms (abfd);
+
+ /* By passing the external symbols back from this routine, we are
+ giving up control over the memory block. Clear
+ obj_aout_external_syms, so that we do not try to free it
+ ourselves. */
+ obj_aout_external_syms (abfd) = NULL;
+
+ *sizep = EXTERNAL_NLIST_SIZE;
+ return obj_aout_external_sym_count (abfd);
+}
+
+/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
+ unmodified a.out symbol. The SYM argument is a structure returned
+ by bfd_make_empty_symbol, which we fill in here. */
+
+asymbol *
+NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
+ bfd *abfd;
+ boolean dynamic;
+ const PTR minisym;
+ asymbol *sym;
+{
+ if (dynamic
+ || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
+ return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
+
+ memset (sym, 0, sizeof (aout_symbol_type));
+
+ /* We call translate_symbol_table to translate a single symbol. */
+ if (! (NAME(aout,translate_symbol_table)
+ (abfd,
+ (aout_symbol_type *) sym,
+ (struct external_nlist *) minisym,
+ (bfd_size_type) 1,
+ obj_aout_external_strings (abfd),
+ obj_aout_external_string_size (abfd),
+ false)))
+ return NULL;
+
+ return sym;
+}
+
+/*
+ provided a BFD, a section and an offset into the section, calculate
+ and return the name of the source file and the line nearest to the
+ wanted location.
+*/
+
+boolean
+NAME(aout,find_nearest_line)
+ (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ /* Run down the file looking for the filename, function and linenumber */
+ asymbol **p;
+ CONST char *directory_name = NULL;
+ CONST char *main_file_name = NULL;
+ CONST char *current_file_name = NULL;
+ CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
+ CONST char *line_directory_name = NULL; /* Value of directory_name at line number. */
+ bfd_vma low_line_vma = 0;
+ bfd_vma low_func_vma = 0;
+ asymbol *func = 0;
+ size_t filelen, funclen;
+ char *buf;
+
+ *filename_ptr = abfd->filename;
+ *functionname_ptr = 0;
+ *line_ptr = 0;
+ if (symbols != (asymbol **)NULL) {
+ for (p = symbols; *p; p++) {
+ aout_symbol_type *q = (aout_symbol_type *)(*p);
+ next:
+ switch (q->type){
+ case N_TEXT:
+ /* If this looks like a file name symbol, and it comes after
+ the line number we have found so far, but before the
+ offset, then we have probably not found the right line
+ number. */
+ if (q->symbol.value <= offset
+ && ((q->symbol.value > low_line_vma
+ && (line_file_name != NULL
+ || *line_ptr != 0))
+ || (q->symbol.value > low_func_vma
+ && func != NULL)))
+ {
+ const char *symname;
+
+ symname = q->symbol.name;
+ if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
+ {
+ if (q->symbol.value > low_line_vma)
+ {
+ *line_ptr = 0;
+ line_file_name = NULL;
+ }
+ if (q->symbol.value > low_func_vma)
+ func = NULL;
+ }
+ }
+ break;
+
+ case N_SO:
+ /* If this symbol is less than the offset, but greater than
+ the line number we have found so far, then we have not
+ found the right line number. */
+ if (q->symbol.value <= offset)
+ {
+ if (q->symbol.value > low_line_vma)
+ {
+ *line_ptr = 0;
+ line_file_name = NULL;
+ }
+ if (q->symbol.value > low_func_vma)
+ func = NULL;
+ }
+
+ main_file_name = current_file_name = q->symbol.name;
+ /* Look ahead to next symbol to check if that too is an N_SO. */
+ p++;
+ if (*p == NULL)
+ break;
+ q = (aout_symbol_type *)(*p);
+ if (q->type != (int)N_SO)
+ goto next;
+
+ /* Found a second N_SO First is directory; second is filename. */
+ directory_name = current_file_name;
+ main_file_name = current_file_name = q->symbol.name;
+ if (obj_textsec(abfd) != section)
+ goto done;
+ break;
+ case N_SOL:
+ current_file_name = q->symbol.name;
+ break;
+
+ case N_SLINE:
+
+ case N_DSLINE:
+ case N_BSLINE:
+ /* We'll keep this if it resolves nearer than the one we have
+ already. */
+ if (q->symbol.value >= low_line_vma
+ && q->symbol.value <= offset)
+ {
+ *line_ptr = q->desc;
+ low_line_vma = q->symbol.value;
+ line_file_name = current_file_name;
+ line_directory_name = directory_name;
+ }
+ break;
+ case N_FUN:
+ {
+ /* We'll keep this if it is nearer than the one we have already */
+ if (q->symbol.value >= low_func_vma &&
+ q->symbol.value <= offset) {
+ low_func_vma = q->symbol.value;
+ func = (asymbol *)q;
+ }
+ else if (q->symbol.value > offset)
+ goto done;
+ }
+ break;
+ }
+ }
+ }
+
+ done:
+ if (*line_ptr != 0)
+ {
+ main_file_name = line_file_name;
+ directory_name = line_directory_name;
+ }
+
+ if (main_file_name == NULL
+ || main_file_name[0] == '/'
+ || directory_name == NULL)
+ filelen = 0;
+ else
+ filelen = strlen (directory_name) + strlen (main_file_name);
+ if (func == NULL)
+ funclen = 0;
+ else
+ funclen = strlen (bfd_asymbol_name (func));
+
+ if (adata (abfd).line_buf != NULL)
+ free (adata (abfd).line_buf);
+ if (filelen + funclen == 0)
+ adata (abfd).line_buf = buf = NULL;
+ else
+ {
+ buf = (char *) bfd_malloc (filelen + funclen + 3);
+ adata (abfd).line_buf = buf;
+ if (buf == NULL)
+ return false;
+ }
+
+ if (main_file_name != NULL)
+ {
+ if (main_file_name[0] == '/' || directory_name == NULL)
+ *filename_ptr = main_file_name;
+ else
+ {
+ sprintf (buf, "%s%s", directory_name, main_file_name);
+ *filename_ptr = buf;
+ buf += filelen + 1;
+ }
+ }
+
+ if (func)
+ {
+ const char *function = func->name;
+ char *p;
+
+ /* The caller expects a symbol name. We actually have a
+ function name, without the leading underscore. Put the
+ underscore back in, so that the caller gets a symbol name. */
+ if (bfd_get_symbol_leading_char (abfd) == '\0')
+ strcpy (buf, function);
+ else
+ {
+ buf[0] = bfd_get_symbol_leading_char (abfd);
+ strcpy (buf + 1, function);
+ }
+ /* Have to remove : stuff */
+ p = strchr (buf, ':');
+ if (p != NULL)
+ *p = '\0';
+ *functionname_ptr = buf;
+ }
+
+ return true;
+}
+
+/*ARGSUSED*/
+int
+NAME(aout,sizeof_headers) (abfd, execable)
+ bfd *abfd;
+ boolean execable;
+{
+ return adata(abfd).exec_bytes_size;
+}
+
+/* Free all information we have cached for this BFD. We can always
+ read it again later if we need it. */
+
+boolean
+NAME(aout,bfd_free_cached_info) (abfd)
+ bfd *abfd;
+{
+ asection *o;
+
+ if (bfd_get_format (abfd) != bfd_object)
+ return true;
+
+#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
+ BFCI_FREE (obj_aout_symbols (abfd));
+#ifdef USE_MMAP
+ obj_aout_external_syms (abfd) = 0;
+ bfd_free_window (&obj_aout_sym_window (abfd));
+ bfd_free_window (&obj_aout_string_window (abfd));
+ obj_aout_external_strings (abfd) = 0;
+#else
+ BFCI_FREE (obj_aout_external_syms (abfd));
+ BFCI_FREE (obj_aout_external_strings (abfd));
+#endif
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ BFCI_FREE (o->relocation);
+#undef BFCI_FREE
+
+ return true;
+}
+
+/* a.out link code. */
+
+static boolean aout_link_add_object_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean aout_link_check_archive_element
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *));
+static boolean aout_link_free_symbols PARAMS ((bfd *));
+static boolean aout_link_check_ar_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
+static boolean aout_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Routine to create an entry in an a.out link hash table. */
+
+struct bfd_hash_entry *
+NAME(aout,link_hash_newfunc) (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct aout_link_hash_entry *) NULL)
+ ret = ((struct aout_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
+ if (ret == (struct aout_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct aout_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->written = false;
+ ret->indx = -1;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize an a.out link hash table. */
+
+boolean
+NAME(aout,link_hash_table_init) (table, abfd, newfunc)
+ struct aout_link_hash_table *table;
+ bfd *abfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+}
+
+/* Create an a.out link hash table. */
+
+struct bfd_link_hash_table *
+NAME(aout,link_hash_table_create) (abfd)
+ bfd *abfd;
+{
+ struct aout_link_hash_table *ret;
+
+ ret = ((struct aout_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct aout_link_hash_table)));
+ if (ret == NULL)
+ return (struct bfd_link_hash_table *) NULL;
+ if (! NAME(aout,link_hash_table_init) (ret, abfd,
+ NAME(aout,link_hash_newfunc)))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+ return &ret->root;
+}
+
+/* Given an a.out BFD, add symbols to the global hash table as
+ appropriate. */
+
+boolean
+NAME(aout,link_add_symbols) (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return aout_link_add_object_symbols (abfd, info);
+ case bfd_archive:
+ return _bfd_generic_link_add_archive_symbols
+ (abfd, info, aout_link_check_archive_element);
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+}
+
+/* Add symbols from an a.out object file. */
+
+static boolean
+aout_link_add_object_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ if (! aout_get_external_symbols (abfd))
+ return false;
+ if (! aout_link_add_symbols (abfd, info))
+ return false;
+ if (! info->keep_memory)
+ {
+ if (! aout_link_free_symbols (abfd))
+ return false;
+ }
+ return true;
+}
+
+/* Check a single archive element to see if we need to include it in
+ the link. *PNEEDED is set according to whether this element is
+ needed in the link or not. This is called from
+ _bfd_generic_link_add_archive_symbols. */
+
+static boolean
+aout_link_check_archive_element (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ if (! aout_get_external_symbols (abfd))
+ return false;
+
+ if (! aout_link_check_ar_symbols (abfd, info, pneeded))
+ return false;
+
+ if (*pneeded)
+ {
+ if (! aout_link_add_symbols (abfd, info))
+ return false;
+ }
+
+ if (! info->keep_memory || ! *pneeded)
+ {
+ if (! aout_link_free_symbols (abfd))
+ return false;
+ }
+
+ return true;
+}
+
+/* Free up the internal symbols read from an a.out file. */
+
+static boolean
+aout_link_free_symbols (abfd)
+ bfd *abfd;
+{
+ if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_sym_window (abfd));
+#else
+ free ((PTR) obj_aout_external_syms (abfd));
+#endif
+ obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
+ }
+ if (obj_aout_external_strings (abfd) != (char *) NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_string_window (abfd));
+#else
+ free ((PTR) obj_aout_external_strings (abfd));
+#endif
+ obj_aout_external_strings (abfd) = (char *) NULL;
+ }
+ return true;
+}
+
+/* Look through the internal symbols to see if this object file should
+ be included in the link. We should include this object file if it
+ defines any symbols which are currently undefined. If this object
+ file defines a common symbol, then we may adjust the size of the
+ known symbol but we do not include the object file in the link
+ (unless there is some other reason to include it). */
+
+static boolean
+aout_link_check_ar_symbols (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ register struct external_nlist *p;
+ struct external_nlist *pend;
+ char *strings;
+
+ *pneeded = false;
+
+ /* Look through all the symbols. */
+ p = obj_aout_external_syms (abfd);
+ pend = p + obj_aout_external_sym_count (abfd);
+ strings = obj_aout_external_strings (abfd);
+ for (; p < pend; p++)
+ {
+ int type = bfd_h_get_8 (abfd, p->e_type);
+ const char *name;
+ struct bfd_link_hash_entry *h;
+
+ /* Ignore symbols that are not externally visible. This is an
+ optimization only, as we check the type more thoroughly
+ below. */
+ if (((type & N_EXT) == 0
+ || (type & N_STAB) != 0
+ || type == N_FN)
+ && type != N_WEAKA
+ && type != N_WEAKT
+ && type != N_WEAKD
+ && type != N_WEAKB)
+ {
+ if (type == N_WARNING
+ || type == N_INDR)
+ ++p;
+ continue;
+ }
+
+ name = strings + GET_WORD (abfd, p->e_strx);
+ h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+
+ /* We are only interested in symbols that are currently
+ undefined or common. */
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common))
+ {
+ if (type == (N_INDR | N_EXT))
+ ++p;
+ continue;
+ }
+
+ if (type == (N_TEXT | N_EXT)
+ || type == (N_DATA | N_EXT)
+ || type == (N_BSS | N_EXT)
+ || type == (N_ABS | N_EXT)
+ || type == (N_INDR | N_EXT))
+ {
+ /* This object file defines this symbol. We must link it
+ in. This is true regardless of whether the current
+ definition of the symbol is undefined or common. If the
+ current definition is common, we have a case in which we
+ have already seen an object file including
+ int a;
+ and this object file from the archive includes
+ int a = 5;
+ In such a case we must include this object file.
+
+ FIXME: The SunOS 4.1.3 linker will pull in the archive
+ element if the symbol is defined in the .data section,
+ but not if it is defined in the .text section. That
+ seems a bit crazy to me, and I haven't implemented it.
+ However, it might be correct. */
+ if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+
+ if (type == (N_UNDF | N_EXT))
+ {
+ bfd_vma value;
+
+ value = GET_WORD (abfd, p->e_value);
+ if (value != 0)
+ {
+ /* This symbol is common in the object from the archive
+ file. */
+ if (h->type == bfd_link_hash_undefined)
+ {
+ bfd *symbfd;
+ unsigned int power;
+
+ symbfd = h->u.undef.abfd;
+ if (symbfd == (bfd *) NULL)
+ {
+ /* This symbol was created as undefined from
+ outside BFD. We assume that we should link
+ in the object file. This is done for the -u
+ option in the linker. */
+ if (! (*info->callbacks->add_archive_element) (info,
+ abfd,
+ name))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+ /* Turn the current link symbol into a common
+ symbol. It is already on the undefs list. */
+ h->type = bfd_link_hash_common;
+ h->u.c.p = ((struct bfd_link_hash_common_entry *)
+ bfd_hash_allocate (&info->hash->table,
+ sizeof (struct bfd_link_hash_common_entry)));
+ if (h->u.c.p == NULL)
+ return false;
+
+ h->u.c.size = value;
+
+ /* FIXME: This isn't quite right. The maximum
+ alignment of a common symbol should be set by the
+ architecture of the output file, not of the input
+ file. */
+ power = bfd_log2 (value);
+ if (power > bfd_get_arch_info (abfd)->section_align_power)
+ power = bfd_get_arch_info (abfd)->section_align_power;
+ h->u.c.p->alignment_power = power;
+
+ h->u.c.p->section = bfd_make_section_old_way (symbfd,
+ "COMMON");
+ }
+ else
+ {
+ /* Adjust the size of the common symbol if
+ necessary. */
+ if (value > h->u.c.size)
+ h->u.c.size = value;
+ }
+ }
+ }
+
+ if (type == N_WEAKA
+ || type == N_WEAKT
+ || type == N_WEAKD
+ || type == N_WEAKB)
+ {
+ /* This symbol is weak but defined. We must pull it in if
+ the current link symbol is undefined, but we don't want
+ it if the current link symbol is common. */
+ if (h->type == bfd_link_hash_undefined)
+ {
+ if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+ }
+ }
+
+ /* We do not need this object file. */
+ return true;
+}
+
+/* Add all symbols from an object file to the hash table. */
+
+static boolean
+aout_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
+ const char *, flagword, asection *,
+ bfd_vma, const char *, boolean,
+ boolean,
+ struct bfd_link_hash_entry **));
+ struct external_nlist *syms;
+ bfd_size_type sym_count;
+ char *strings;
+ boolean copy;
+ struct aout_link_hash_entry **sym_hash;
+ register struct external_nlist *p;
+ struct external_nlist *pend;
+
+ syms = obj_aout_external_syms (abfd);
+ sym_count = obj_aout_external_sym_count (abfd);
+ strings = obj_aout_external_strings (abfd);
+ if (info->keep_memory)
+ copy = false;
+ else
+ copy = true;
+
+ if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
+ {
+ if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
+ (abfd, info, &syms, &sym_count, &strings)))
+ return false;
+ }
+
+ /* We keep a list of the linker hash table entries that correspond
+ to particular symbols. We could just look them up in the hash
+ table, but keeping the list is more efficient. Perhaps this
+ should be conditional on info->keep_memory. */
+ sym_hash = ((struct aout_link_hash_entry **)
+ bfd_alloc (abfd,
+ ((size_t) sym_count
+ * sizeof (struct aout_link_hash_entry *))));
+ if (sym_hash == NULL && sym_count != 0)
+ return false;
+ obj_aout_sym_hashes (abfd) = sym_hash;
+
+ add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
+ if (add_one_symbol == NULL)
+ add_one_symbol = _bfd_generic_link_add_one_symbol;
+
+ p = syms;
+ pend = p + sym_count;
+ for (; p < pend; p++, sym_hash++)
+ {
+ int type;
+ const char *name;
+ bfd_vma value;
+ asection *section;
+ flagword flags;
+ const char *string;
+
+ *sym_hash = NULL;
+
+ type = bfd_h_get_8 (abfd, p->e_type);
+
+ /* Ignore debugging symbols. */
+ if ((type & N_STAB) != 0)
+ continue;
+
+ name = strings + GET_WORD (abfd, p->e_strx);
+ value = GET_WORD (abfd, p->e_value);
+ flags = BSF_GLOBAL;
+ string = NULL;
+ switch (type)
+ {
+ default:
+ abort ();
+
+ case N_UNDF:
+ case N_ABS:
+ case N_TEXT:
+ case N_DATA:
+ case N_BSS:
+ case N_FN_SEQ:
+ case N_COMM:
+ case N_SETV:
+ case N_FN:
+ /* Ignore symbols that are not externally visible. */
+ continue;
+ case N_INDR:
+ /* Ignore local indirect symbol. */
+ ++p;
+ ++sym_hash;
+ continue;
+
+ case N_UNDF | N_EXT:
+ if (value == 0)
+ {
+ section = bfd_und_section_ptr;
+ flags = 0;
+ }
+ else
+ section = bfd_com_section_ptr;
+ break;
+ case N_ABS | N_EXT:
+ section = bfd_abs_section_ptr;
+ break;
+ case N_TEXT | N_EXT:
+ section = obj_textsec (abfd);
+ value -= bfd_get_section_vma (abfd, section);
+ break;
+ case N_DATA | N_EXT:
+ case N_SETV | N_EXT:
+ /* Treat N_SETV symbols as N_DATA symbol; see comment in
+ translate_from_native_sym_flags. */
+ section = obj_datasec (abfd);
+ value -= bfd_get_section_vma (abfd, section);
+ break;
+ case N_BSS | N_EXT:
+ section = obj_bsssec (abfd);
+ value -= bfd_get_section_vma (abfd, section);
+ break;
+ case N_INDR | N_EXT:
+ /* An indirect symbol. The next symbol is the symbol
+ which this one really is. */
+ BFD_ASSERT (p + 1 < pend);
+ ++p;
+ string = strings + GET_WORD (abfd, p->e_strx);
+ section = bfd_ind_section_ptr;
+ flags |= BSF_INDIRECT;
+ break;
+ case N_COMM | N_EXT:
+ section = bfd_com_section_ptr;
+ break;
+ case N_SETA: case N_SETA | N_EXT:
+ section = bfd_abs_section_ptr;
+ flags |= BSF_CONSTRUCTOR;
+ break;
+ case N_SETT: case N_SETT | N_EXT:
+ section = obj_textsec (abfd);
+ flags |= BSF_CONSTRUCTOR;
+ value -= bfd_get_section_vma (abfd, section);
+ break;
+ case N_SETD: case N_SETD | N_EXT:
+ section = obj_datasec (abfd);
+ flags |= BSF_CONSTRUCTOR;
+ value -= bfd_get_section_vma (abfd, section);
+ break;
+ case N_SETB: case N_SETB | N_EXT:
+ section = obj_bsssec (abfd);
+ flags |= BSF_CONSTRUCTOR;
+ value -= bfd_get_section_vma (abfd, section);
+ break;
+ case N_WARNING:
+ /* A warning symbol. The next symbol is the one to warn
+ about. */
+ BFD_ASSERT (p + 1 < pend);
+ ++p;
+ string = name;
+ name = strings + GET_WORD (abfd, p->e_strx);
+ section = bfd_und_section_ptr;
+ flags |= BSF_WARNING;
+ break;
+ case N_WEAKU:
+ section = bfd_und_section_ptr;
+ flags = BSF_WEAK;
+ break;
+ case N_WEAKA:
+ section = bfd_abs_section_ptr;
+ flags = BSF_WEAK;
+ break;
+ case N_WEAKT:
+ section = obj_textsec (abfd);
+ value -= bfd_get_section_vma (abfd, section);
+ flags = BSF_WEAK;
+ break;
+ case N_WEAKD:
+ section = obj_datasec (abfd);
+ value -= bfd_get_section_vma (abfd, section);
+ flags = BSF_WEAK;
+ break;
+ case N_WEAKB:
+ section = obj_bsssec (abfd);
+ value -= bfd_get_section_vma (abfd, section);
+ flags = BSF_WEAK;
+ break;
+ }
+
+ if (! ((*add_one_symbol)
+ (info, abfd, name, flags, section, value, string, copy, false,
+ (struct bfd_link_hash_entry **) sym_hash)))
+ return false;
+
+ /* Restrict the maximum alignment of a common symbol based on
+ the architecture, since a.out has no way to represent
+ alignment requirements of a section in a .o file. FIXME:
+ This isn't quite right: it should use the architecture of the
+ output file, not the input files. */
+ if ((*sym_hash)->root.type == bfd_link_hash_common
+ && ((*sym_hash)->root.u.c.p->alignment_power >
+ bfd_get_arch_info (abfd)->section_align_power))
+ (*sym_hash)->root.u.c.p->alignment_power =
+ bfd_get_arch_info (abfd)->section_align_power;
+
+ /* If this is a set symbol, and we are not building sets, then
+ it is possible for the hash entry to not have been set. In
+ such a case, treat the symbol as not globally defined. */
+ if ((*sym_hash)->root.type == bfd_link_hash_new)
+ {
+ BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
+ *sym_hash = NULL;
+ }
+
+ if (type == (N_INDR | N_EXT) || type == N_WARNING)
+ ++sym_hash;
+ }
+
+ return true;
+}
+
+/* A hash table used for header files with N_BINCL entries. */
+
+struct aout_link_includes_table
+{
+ struct bfd_hash_table root;
+};
+
+/* A linked list of totals that we have found for a particular header
+ file. */
+
+struct aout_link_includes_totals
+{
+ struct aout_link_includes_totals *next;
+ bfd_vma total;
+};
+
+/* An entry in the header file hash table. */
+
+struct aout_link_includes_entry
+{
+ struct bfd_hash_entry root;
+ /* List of totals we have found for this file. */
+ struct aout_link_includes_totals *totals;
+};
+
+/* Look up an entry in an the header file hash table. */
+
+#define aout_link_includes_lookup(table, string, create, copy) \
+ ((struct aout_link_includes_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* During the final link step we need to pass around a bunch of
+ information, so we do it in an instance of this structure. */
+
+struct aout_final_link_info
+{
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Output bfd. */
+ bfd *output_bfd;
+ /* Reloc file positions. */
+ file_ptr treloff, dreloff;
+ /* File position of symbols. */
+ file_ptr symoff;
+ /* String table. */
+ struct bfd_strtab_hash *strtab;
+ /* Header file hash table. */
+ struct aout_link_includes_table includes;
+ /* A buffer large enough to hold the contents of any section. */
+ bfd_byte *contents;
+ /* A buffer large enough to hold the relocs of any section. */
+ PTR relocs;
+ /* A buffer large enough to hold the symbol map of any input BFD. */
+ int *symbol_map;
+ /* A buffer large enough to hold output symbols of any input BFD. */
+ struct external_nlist *output_syms;
+};
+
+static struct bfd_hash_entry *aout_link_includes_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean aout_link_input_bfd
+ PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
+static boolean aout_link_write_symbols
+ PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
+static boolean aout_link_write_other_symbol
+ PARAMS ((struct aout_link_hash_entry *, PTR));
+static boolean aout_link_input_section
+ PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
+ asection *input_section, file_ptr *reloff_ptr,
+ bfd_size_type rel_size));
+static boolean aout_link_input_section_std
+ PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
+ asection *input_section, struct reloc_std_external *,
+ bfd_size_type rel_size, bfd_byte *contents));
+static boolean aout_link_input_section_ext
+ PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
+ asection *input_section, struct reloc_ext_external *,
+ bfd_size_type rel_size, bfd_byte *contents));
+static INLINE asection *aout_reloc_index_to_section
+ PARAMS ((bfd *, int));
+static boolean aout_link_reloc_link_order
+ PARAMS ((struct aout_final_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* The function to create a new entry in the header file hash table. */
+
+static struct bfd_hash_entry *
+aout_link_includes_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct aout_link_includes_entry *ret =
+ (struct aout_link_includes_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct aout_link_includes_entry *) NULL)
+ ret = ((struct aout_link_includes_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct aout_link_includes_entry)));
+ if (ret == (struct aout_link_includes_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct aout_link_includes_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->totals = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Do the final link step. This is called on the output BFD. The
+ INFO structure should point to a list of BFDs linked through the
+ link_next field which can be used to find each BFD which takes part
+ in the output. Also, each section in ABFD should point to a list
+ of bfd_link_order structures which list all the input sections for
+ the output section. */
+
+boolean
+NAME(aout,final_link) (abfd, info, callback)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+{
+ struct aout_final_link_info aout_info;
+ boolean includes_hash_initialized = false;
+ register bfd *sub;
+ bfd_size_type trsize, drsize;
+ size_t max_contents_size;
+ size_t max_relocs_size;
+ size_t max_sym_count;
+ bfd_size_type text_size;
+ file_ptr text_end;
+ register struct bfd_link_order *p;
+ asection *o;
+ boolean have_link_order_relocs;
+
+ if (info->shared)
+ abfd->flags |= DYNAMIC;
+
+ aout_info.info = info;
+ aout_info.output_bfd = abfd;
+ aout_info.contents = NULL;
+ aout_info.relocs = NULL;
+ aout_info.symbol_map = NULL;
+ aout_info.output_syms = NULL;
+
+ if (! bfd_hash_table_init_n (&aout_info.includes.root,
+ aout_link_includes_newfunc,
+ 251))
+ goto error_return;
+ includes_hash_initialized = true;
+
+ /* Figure out the largest section size. Also, if generating
+ relocateable output, count the relocs. */
+ trsize = 0;
+ drsize = 0;
+ max_contents_size = 0;
+ max_relocs_size = 0;
+ max_sym_count = 0;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ size_t sz;
+
+ if (info->relocateable)
+ {
+ if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
+ {
+ trsize += exec_hdr (sub)->a_trsize;
+ drsize += exec_hdr (sub)->a_drsize;
+ }
+ else
+ {
+ /* FIXME: We need to identify the .text and .data sections
+ and call get_reloc_upper_bound and canonicalize_reloc to
+ work out the number of relocs needed, and then multiply
+ by the reloc size. */
+ (*_bfd_error_handler)
+ (_("%s: relocateable link from %s to %s not supported"),
+ bfd_get_filename (abfd),
+ sub->xvec->name, abfd->xvec->name);
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+ }
+
+ if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
+ {
+ sz = bfd_section_size (sub, obj_textsec (sub));
+ if (sz > max_contents_size)
+ max_contents_size = sz;
+ sz = bfd_section_size (sub, obj_datasec (sub));
+ if (sz > max_contents_size)
+ max_contents_size = sz;
+
+ sz = exec_hdr (sub)->a_trsize;
+ if (sz > max_relocs_size)
+ max_relocs_size = sz;
+ sz = exec_hdr (sub)->a_drsize;
+ if (sz > max_relocs_size)
+ max_relocs_size = sz;
+
+ sz = obj_aout_external_sym_count (sub);
+ if (sz > max_sym_count)
+ max_sym_count = sz;
+ }
+ }
+
+ if (info->relocateable)
+ {
+ if (obj_textsec (abfd) != (asection *) NULL)
+ trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
+ ->link_order_head)
+ * obj_reloc_entry_size (abfd));
+ if (obj_datasec (abfd) != (asection *) NULL)
+ drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
+ ->link_order_head)
+ * obj_reloc_entry_size (abfd));
+ }
+
+ exec_hdr (abfd)->a_trsize = trsize;
+ exec_hdr (abfd)->a_drsize = drsize;
+
+ exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
+
+ /* Adjust the section sizes and vmas according to the magic number.
+ This sets a_text, a_data and a_bss in the exec_hdr and sets the
+ filepos for each section. */
+ if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
+ goto error_return;
+
+ /* The relocation and symbol file positions differ among a.out
+ targets. We are passed a callback routine from the backend
+ specific code to handle this.
+ FIXME: At this point we do not know how much space the symbol
+ table will require. This will not work for any (nonstandard)
+ a.out target that needs to know the symbol table size before it
+ can compute the relocation file positions. This may or may not
+ be the case for the hp300hpux target, for example. */
+ (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
+ &aout_info.symoff);
+ obj_textsec (abfd)->rel_filepos = aout_info.treloff;
+ obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
+ obj_sym_filepos (abfd) = aout_info.symoff;
+
+ /* We keep a count of the symbols as we output them. */
+ obj_aout_external_sym_count (abfd) = 0;
+
+ /* We accumulate the string table as we write out the symbols. */
+ aout_info.strtab = _bfd_stringtab_init ();
+ if (aout_info.strtab == NULL)
+ goto error_return;
+
+ /* Allocate buffers to hold section contents and relocs. */
+ aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
+ aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
+ aout_info.output_syms = ((struct external_nlist *)
+ bfd_malloc ((max_sym_count + 1)
+ * sizeof (struct external_nlist)));
+ if ((aout_info.contents == NULL && max_contents_size != 0)
+ || (aout_info.relocs == NULL && max_relocs_size != 0)
+ || (aout_info.symbol_map == NULL && max_sym_count != 0)
+ || aout_info.output_syms == NULL)
+ goto error_return;
+
+ /* If we have a symbol named __DYNAMIC, force it out now. This is
+ required by SunOS. Doing this here rather than in sunos.c is a
+ hack, but it's easier than exporting everything which would be
+ needed. */
+ {
+ struct aout_link_hash_entry *h;
+
+ h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
+ false, false, false);
+ if (h != NULL)
+ aout_link_write_other_symbol (h, &aout_info);
+ }
+
+ /* The most time efficient way to do the link would be to read all
+ the input object files into memory and then sort out the
+ information into the output file. Unfortunately, that will
+ probably use too much memory. Another method would be to step
+ through everything that composes the text section and write it
+ out, and then everything that composes the data section and write
+ it out, and then write out the relocs, and then write out the
+ symbols. Unfortunately, that requires reading stuff from each
+ input file several times, and we will not be able to keep all the
+ input files open simultaneously, and reopening them will be slow.
+
+ What we do is basically process one input file at a time. We do
+ everything we need to do with an input file once--copy over the
+ section contents, handle the relocation information, and write
+ out the symbols--and then we throw away the information we read
+ from it. This approach requires a lot of lseeks of the output
+ file, which is unfortunate but still faster than reopening a lot
+ of files.
+
+ We use the output_has_begun field of the input BFDs to see
+ whether we have already handled it. */
+ for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
+ sub->output_has_begun = false;
+
+ /* Mark all sections which are to be included in the link. This
+ will normally be every section. We need to do this so that we
+ can identify any sections which the linker has decided to not
+ include. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order)
+ p->u.indirect.section->linker_mark = true;
+ }
+ }
+
+ have_link_order_relocs = false;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour (p->u.indirect.section->owner)
+ == bfd_target_aout_flavour))
+ {
+ bfd *input_bfd;
+
+ input_bfd = p->u.indirect.section->owner;
+ if (! input_bfd->output_has_begun)
+ {
+ if (! aout_link_input_bfd (&aout_info, input_bfd))
+ goto error_return;
+ input_bfd->output_has_begun = true;
+ }
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ /* These are handled below. */
+ have_link_order_relocs = true;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ }
+ }
+
+ /* Write out any symbols that we have not already written out. */
+ aout_link_hash_traverse (aout_hash_table (info),
+ aout_link_write_other_symbol,
+ (PTR) &aout_info);
+
+ /* Now handle any relocs we were asked to create by the linker.
+ These did not come from any input file. We must do these after
+ we have written out all the symbols, so that we know the symbol
+ indices to use. */
+ if (have_link_order_relocs)
+ {
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ if (! aout_link_reloc_link_order (&aout_info, o, p))
+ goto error_return;
+ }
+ }
+ }
+ }
+
+ if (aout_info.contents != NULL)
+ {
+ free (aout_info.contents);
+ aout_info.contents = NULL;
+ }
+ if (aout_info.relocs != NULL)
+ {
+ free (aout_info.relocs);
+ aout_info.relocs = NULL;
+ }
+ if (aout_info.symbol_map != NULL)
+ {
+ free (aout_info.symbol_map);
+ aout_info.symbol_map = NULL;
+ }
+ if (aout_info.output_syms != NULL)
+ {
+ free (aout_info.output_syms);
+ aout_info.output_syms = NULL;
+ }
+ if (includes_hash_initialized)
+ {
+ bfd_hash_table_free (&aout_info.includes.root);
+ includes_hash_initialized = false;
+ }
+
+ /* Finish up any dynamic linking we may be doing. */
+ if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
+ {
+ if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
+ goto error_return;
+ }
+
+ /* Update the header information. */
+ abfd->symcount = obj_aout_external_sym_count (abfd);
+ exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
+ obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
+ obj_textsec (abfd)->reloc_count =
+ exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
+ obj_datasec (abfd)->reloc_count =
+ exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
+
+ /* Write out the string table, unless there are no symbols. */
+ if (abfd->symcount > 0)
+ {
+ if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
+ || ! emit_stringtab (abfd, aout_info.strtab))
+ goto error_return;
+ }
+ else if (obj_textsec (abfd)->reloc_count == 0
+ && obj_datasec (abfd)->reloc_count == 0)
+ {
+ bfd_byte b;
+
+ b = 0;
+ if (bfd_seek (abfd,
+ (obj_datasec (abfd)->filepos
+ + exec_hdr (abfd)->a_data
+ - 1),
+ SEEK_SET) != 0
+ || bfd_write (&b, 1, 1, abfd) != 1)
+ goto error_return;
+ }
+
+ return true;
+
+ error_return:
+ if (aout_info.contents != NULL)
+ free (aout_info.contents);
+ if (aout_info.relocs != NULL)
+ free (aout_info.relocs);
+ if (aout_info.symbol_map != NULL)
+ free (aout_info.symbol_map);
+ if (aout_info.output_syms != NULL)
+ free (aout_info.output_syms);
+ if (includes_hash_initialized)
+ bfd_hash_table_free (&aout_info.includes.root);
+ return false;
+}
+
+/* Link an a.out input BFD into the output file. */
+
+static boolean
+aout_link_input_bfd (finfo, input_bfd)
+ struct aout_final_link_info *finfo;
+ bfd *input_bfd;
+{
+ bfd_size_type sym_count;
+
+ BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
+
+ /* If this is a dynamic object, it may need special handling. */
+ if ((input_bfd->flags & DYNAMIC) != 0
+ && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
+ {
+ return ((*aout_backend_info (input_bfd)->link_dynamic_object)
+ (finfo->info, input_bfd));
+ }
+
+ /* Get the symbols. We probably have them already, unless
+ finfo->info->keep_memory is false. */
+ if (! aout_get_external_symbols (input_bfd))
+ return false;
+
+ sym_count = obj_aout_external_sym_count (input_bfd);
+
+ /* Write out the symbols and get a map of the new indices. The map
+ is placed into finfo->symbol_map. */
+ if (! aout_link_write_symbols (finfo, input_bfd))
+ return false;
+
+ /* Relocate and write out the sections. These functions use the
+ symbol map created by aout_link_write_symbols. The linker_mark
+ field will be set if these sections are to be included in the
+ link, which will normally be the case. */
+ if (obj_textsec (input_bfd)->linker_mark)
+ {
+ if (! aout_link_input_section (finfo, input_bfd,
+ obj_textsec (input_bfd),
+ &finfo->treloff,
+ exec_hdr (input_bfd)->a_trsize))
+ return false;
+ }
+ if (obj_datasec (input_bfd)->linker_mark)
+ {
+ if (! aout_link_input_section (finfo, input_bfd,
+ obj_datasec (input_bfd),
+ &finfo->dreloff,
+ exec_hdr (input_bfd)->a_drsize))
+ return false;
+ }
+
+ /* If we are not keeping memory, we don't need the symbols any
+ longer. We still need them if we are keeping memory, because the
+ strings in the hash table point into them. */
+ if (! finfo->info->keep_memory)
+ {
+ if (! aout_link_free_symbols (input_bfd))
+ return false;
+ }
+
+ return true;
+}
+
+/* Adjust and write out the symbols for an a.out file. Set the new
+ symbol indices into a symbol_map. */
+
+static boolean
+aout_link_write_symbols (finfo, input_bfd)
+ struct aout_final_link_info *finfo;
+ bfd *input_bfd;
+{
+ bfd *output_bfd;
+ bfd_size_type sym_count;
+ char *strings;
+ enum bfd_link_strip strip;
+ enum bfd_link_discard discard;
+ struct external_nlist *outsym;
+ bfd_size_type strtab_index;
+ register struct external_nlist *sym;
+ struct external_nlist *sym_end;
+ struct aout_link_hash_entry **sym_hash;
+ int *symbol_map;
+ boolean pass;
+ boolean skip_next;
+
+ output_bfd = finfo->output_bfd;
+ sym_count = obj_aout_external_sym_count (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ strip = finfo->info->strip;
+ discard = finfo->info->discard;
+ outsym = finfo->output_syms;
+
+ /* First write out a symbol for this object file, unless we are
+ discarding such symbols. */
+ if (strip != strip_all
+ && (strip != strip_some
+ || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
+ false, false) != NULL)
+ && discard != discard_all)
+ {
+ bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
+ bfd_h_put_8 (output_bfd, 0, outsym->e_other);
+ bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
+ strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ input_bfd->filename, false);
+ if (strtab_index == (bfd_size_type) -1)
+ return false;
+ PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
+ PUT_WORD (output_bfd,
+ (bfd_get_section_vma (output_bfd,
+ obj_textsec (input_bfd)->output_section)
+ + obj_textsec (input_bfd)->output_offset),
+ outsym->e_value);
+ ++obj_aout_external_sym_count (output_bfd);
+ ++outsym;
+ }
+
+ pass = false;
+ skip_next = false;
+ sym = obj_aout_external_syms (input_bfd);
+ sym_end = sym + sym_count;
+ sym_hash = obj_aout_sym_hashes (input_bfd);
+ symbol_map = finfo->symbol_map;
+ memset (symbol_map, 0, sym_count * sizeof *symbol_map);
+ for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
+ {
+ const char *name;
+ int type;
+ struct aout_link_hash_entry *h;
+ boolean skip;
+ asection *symsec;
+ bfd_vma val = 0;
+ boolean copy;
+
+ /* We set *symbol_map to 0 above for all symbols. If it has
+ already been set to -1 for this symbol, it means that we are
+ discarding it because it appears in a duplicate header file.
+ See the N_BINCL code below. */
+ if (*symbol_map == -1)
+ continue;
+
+ /* Initialize *symbol_map to -1, which means that the symbol was
+ not copied into the output file. We will change it later if
+ we do copy the symbol over. */
+ *symbol_map = -1;
+
+ type = bfd_h_get_8 (input_bfd, sym->e_type);
+ name = strings + GET_WORD (input_bfd, sym->e_strx);
+
+ h = NULL;
+
+ if (pass)
+ {
+ /* Pass this symbol through. It is the target of an
+ indirect or warning symbol. */
+ val = GET_WORD (input_bfd, sym->e_value);
+ pass = false;
+ }
+ else if (skip_next)
+ {
+ /* Skip this symbol, which is the target of an indirect
+ symbol that we have changed to no longer be an indirect
+ symbol. */
+ skip_next = false;
+ continue;
+ }
+ else
+ {
+ struct aout_link_hash_entry *hresolve;
+
+ /* We have saved the hash table entry for this symbol, if
+ there is one. Note that we could just look it up again
+ in the hash table, provided we first check that it is an
+ external symbol. */
+ h = *sym_hash;
+
+ /* Use the name from the hash table, in case the symbol was
+ wrapped. */
+ if (h != NULL)
+ name = h->root.root.string;
+
+ /* If this is an indirect or warning symbol, then change
+ hresolve to the base symbol. We also change *sym_hash so
+ that the relocation routines relocate against the real
+ symbol. */
+ hresolve = h;
+ if (h != (struct aout_link_hash_entry *) NULL
+ && (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning))
+ {
+ hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
+ while (hresolve->root.type == bfd_link_hash_indirect
+ || hresolve->root.type == bfd_link_hash_warning)
+ hresolve = ((struct aout_link_hash_entry *)
+ hresolve->root.u.i.link);
+ *sym_hash = hresolve;
+ }
+
+ /* If the symbol has already been written out, skip it. */
+ if (h != (struct aout_link_hash_entry *) NULL
+ && h->root.type != bfd_link_hash_warning
+ && h->written)
+ {
+ if ((type & N_TYPE) == N_INDR
+ || type == N_WARNING)
+ skip_next = true;
+ *symbol_map = h->indx;
+ continue;
+ }
+
+ /* See if we are stripping this symbol. */
+ skip = false;
+ switch (strip)
+ {
+ case strip_none:
+ break;
+ case strip_debugger:
+ if ((type & N_STAB) != 0)
+ skip = true;
+ break;
+ case strip_some:
+ if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
+ == NULL)
+ skip = true;
+ break;
+ case strip_all:
+ skip = true;
+ break;
+ }
+ if (skip)
+ {
+ if (h != (struct aout_link_hash_entry *) NULL)
+ h->written = true;
+ continue;
+ }
+
+ /* Get the value of the symbol. */
+ if ((type & N_TYPE) == N_TEXT
+ || type == N_WEAKT)
+ symsec = obj_textsec (input_bfd);
+ else if ((type & N_TYPE) == N_DATA
+ || type == N_WEAKD)
+ symsec = obj_datasec (input_bfd);
+ else if ((type & N_TYPE) == N_BSS
+ || type == N_WEAKB)
+ symsec = obj_bsssec (input_bfd);
+ else if ((type & N_TYPE) == N_ABS
+ || type == N_WEAKA)
+ symsec = bfd_abs_section_ptr;
+ else if (((type & N_TYPE) == N_INDR
+ && (hresolve == (struct aout_link_hash_entry *) NULL
+ || (hresolve->root.type != bfd_link_hash_defined
+ && hresolve->root.type != bfd_link_hash_defweak
+ && hresolve->root.type != bfd_link_hash_common)))
+ || type == N_WARNING)
+ {
+ /* Pass the next symbol through unchanged. The
+ condition above for indirect symbols is so that if
+ the indirect symbol was defined, we output it with
+ the correct definition so the debugger will
+ understand it. */
+ pass = true;
+ val = GET_WORD (input_bfd, sym->e_value);
+ symsec = NULL;
+ }
+ else if ((type & N_STAB) != 0)
+ {
+ val = GET_WORD (input_bfd, sym->e_value);
+ symsec = NULL;
+ }
+ else
+ {
+ /* If we get here with an indirect symbol, it means that
+ we are outputting it with a real definition. In such
+ a case we do not want to output the next symbol,
+ which is the target of the indirection. */
+ if ((type & N_TYPE) == N_INDR)
+ skip_next = true;
+
+ symsec = NULL;
+
+ /* We need to get the value from the hash table. We use
+ hresolve so that if we have defined an indirect
+ symbol we output the final definition. */
+ if (h == (struct aout_link_hash_entry *) NULL)
+ {
+ switch (type & N_TYPE)
+ {
+ case N_SETT:
+ symsec = obj_textsec (input_bfd);
+ break;
+ case N_SETD:
+ symsec = obj_datasec (input_bfd);
+ break;
+ case N_SETB:
+ symsec = obj_bsssec (input_bfd);
+ break;
+ case N_SETA:
+ symsec = bfd_abs_section_ptr;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+ }
+ else if (hresolve->root.type == bfd_link_hash_defined
+ || hresolve->root.type == bfd_link_hash_defweak)
+ {
+ asection *input_section;
+ asection *output_section;
+
+ /* This case usually means a common symbol which was
+ turned into a defined symbol. */
+ input_section = hresolve->root.u.def.section;
+ output_section = input_section->output_section;
+ BFD_ASSERT (bfd_is_abs_section (output_section)
+ || output_section->owner == output_bfd);
+ val = (hresolve->root.u.def.value
+ + bfd_get_section_vma (output_bfd, output_section)
+ + input_section->output_offset);
+
+ /* Get the correct type based on the section. If
+ this is a constructed set, force it to be
+ globally visible. */
+ if (type == N_SETT
+ || type == N_SETD
+ || type == N_SETB
+ || type == N_SETA)
+ type |= N_EXT;
+
+ type &=~ N_TYPE;
+
+ if (output_section == obj_textsec (output_bfd))
+ type |= (hresolve->root.type == bfd_link_hash_defined
+ ? N_TEXT
+ : N_WEAKT);
+ else if (output_section == obj_datasec (output_bfd))
+ type |= (hresolve->root.type == bfd_link_hash_defined
+ ? N_DATA
+ : N_WEAKD);
+ else if (output_section == obj_bsssec (output_bfd))
+ type |= (hresolve->root.type == bfd_link_hash_defined
+ ? N_BSS
+ : N_WEAKB);
+ else
+ type |= (hresolve->root.type == bfd_link_hash_defined
+ ? N_ABS
+ : N_WEAKA);
+ }
+ else if (hresolve->root.type == bfd_link_hash_common)
+ val = hresolve->root.u.c.size;
+ else if (hresolve->root.type == bfd_link_hash_undefweak)
+ {
+ val = 0;
+ type = N_WEAKU;
+ }
+ else
+ val = 0;
+ }
+ if (symsec != (asection *) NULL)
+ val = (symsec->output_section->vma
+ + symsec->output_offset
+ + (GET_WORD (input_bfd, sym->e_value)
+ - symsec->vma));
+
+ /* If this is a global symbol set the written flag, and if
+ it is a local symbol see if we should discard it. */
+ if (h != (struct aout_link_hash_entry *) NULL)
+ {
+ h->written = true;
+ h->indx = obj_aout_external_sym_count (output_bfd);
+ }
+ else if ((type & N_TYPE) != N_SETT
+ && (type & N_TYPE) != N_SETD
+ && (type & N_TYPE) != N_SETB
+ && (type & N_TYPE) != N_SETA)
+ {
+ switch (discard)
+ {
+ case discard_none:
+ break;
+ case discard_l:
+ if ((type & N_STAB) == 0
+ && bfd_is_local_label_name (input_bfd, name))
+ skip = true;
+ break;
+ case discard_all:
+ skip = true;
+ break;
+ }
+ if (skip)
+ {
+ pass = false;
+ continue;
+ }
+ }
+
+ /* An N_BINCL symbol indicates the start of the stabs
+ entries for a header file. We need to scan ahead to the
+ next N_EINCL symbol, ignoring nesting, adding up all the
+ characters in the symbol names, not including the file
+ numbers in types (the first number after an open
+ parenthesis). */
+ if (type == N_BINCL)
+ {
+ struct external_nlist *incl_sym;
+ int nest;
+ struct aout_link_includes_entry *incl_entry;
+ struct aout_link_includes_totals *t;
+
+ val = 0;
+ nest = 0;
+ for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
+ {
+ int incl_type;
+
+ incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
+ if (incl_type == N_EINCL)
+ {
+ if (nest == 0)
+ break;
+ --nest;
+ }
+ else if (incl_type == N_BINCL)
+ ++nest;
+ else if (nest == 0)
+ {
+ const char *s;
+
+ s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
+ for (; *s != '\0'; s++)
+ {
+ val += *s;
+ if (*s == '(')
+ {
+ /* Skip the file number. */
+ ++s;
+ while (isdigit ((unsigned char) *s))
+ ++s;
+ --s;
+ }
+ }
+ }
+ }
+
+ /* If we have already included a header file with the
+ same value, then replace this one with an N_EXCL
+ symbol. */
+ copy = ! finfo->info->keep_memory;
+ incl_entry = aout_link_includes_lookup (&finfo->includes,
+ name, true, copy);
+ if (incl_entry == NULL)
+ return false;
+ for (t = incl_entry->totals; t != NULL; t = t->next)
+ if (t->total == val)
+ break;
+ if (t == NULL)
+ {
+ /* This is the first time we have seen this header
+ file with this set of stabs strings. */
+ t = ((struct aout_link_includes_totals *)
+ bfd_hash_allocate (&finfo->includes.root,
+ sizeof *t));
+ if (t == NULL)
+ return false;
+ t->total = val;
+ t->next = incl_entry->totals;
+ incl_entry->totals = t;
+ }
+ else
+ {
+ int *incl_map;
+
+ /* This is a duplicate header file. We must change
+ it to be an N_EXCL entry, and mark all the
+ included symbols to prevent outputting them. */
+ type = N_EXCL;
+
+ nest = 0;
+ for (incl_sym = sym + 1, incl_map = symbol_map + 1;
+ incl_sym < sym_end;
+ incl_sym++, incl_map++)
+ {
+ int incl_type;
+
+ incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
+ if (incl_type == N_EINCL)
+ {
+ if (nest == 0)
+ {
+ *incl_map = -1;
+ break;
+ }
+ --nest;
+ }
+ else if (incl_type == N_BINCL)
+ ++nest;
+ else if (nest == 0)
+ *incl_map = -1;
+ }
+ }
+ }
+ }
+
+ /* Copy this symbol into the list of symbols we are going to
+ write out. */
+ bfd_h_put_8 (output_bfd, type, outsym->e_type);
+ bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
+ outsym->e_other);
+ bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
+ outsym->e_desc);
+ copy = false;
+ if (! finfo->info->keep_memory)
+ {
+ /* name points into a string table which we are going to
+ free. If there is a hash table entry, use that string.
+ Otherwise, copy name into memory. */
+ if (h != (struct aout_link_hash_entry *) NULL)
+ name = h->root.root.string;
+ else
+ copy = true;
+ }
+ strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ name, copy);
+ if (strtab_index == (bfd_size_type) -1)
+ return false;
+ PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
+ PUT_WORD (output_bfd, val, outsym->e_value);
+ *symbol_map = obj_aout_external_sym_count (output_bfd);
+ ++obj_aout_external_sym_count (output_bfd);
+ ++outsym;
+ }
+
+ /* Write out the output symbols we have just constructed. */
+ if (outsym > finfo->output_syms)
+ {
+ bfd_size_type outsym_count;
+
+ if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
+ return false;
+ outsym_count = outsym - finfo->output_syms;
+ if (bfd_write ((PTR) finfo->output_syms,
+ (bfd_size_type) EXTERNAL_NLIST_SIZE,
+ (bfd_size_type) outsym_count, output_bfd)
+ != outsym_count * EXTERNAL_NLIST_SIZE)
+ return false;
+ finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
+ }
+
+ return true;
+}
+
+/* Write out a symbol that was not associated with an a.out input
+ object. */
+
+static boolean
+aout_link_write_other_symbol (h, data)
+ struct aout_link_hash_entry *h;
+ PTR data;
+{
+ struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
+ bfd *output_bfd;
+ int type;
+ bfd_vma val;
+ struct external_nlist outsym;
+ bfd_size_type indx;
+
+ output_bfd = finfo->output_bfd;
+
+ if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
+ {
+ if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
+ (output_bfd, finfo->info, h)))
+ {
+ /* FIXME: No way to handle errors. */
+ abort ();
+ }
+ }
+
+ if (h->written)
+ return true;
+
+ h->written = true;
+
+ /* An indx of -2 means the symbol must be written. */
+ if (h->indx != -2
+ && (finfo->info->strip == strip_all
+ || (finfo->info->strip == strip_some
+ && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
+ false, false) == NULL)))
+ return true;
+
+ switch (h->root.type)
+ {
+ default:
+ abort ();
+ /* Avoid variable not initialized warnings. */
+ return true;
+ case bfd_link_hash_new:
+ /* This can happen for set symbols when sets are not being
+ built. */
+ return true;
+ case bfd_link_hash_undefined:
+ type = N_UNDF | N_EXT;
+ val = 0;
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section->output_section;
+ BFD_ASSERT (bfd_is_abs_section (sec)
+ || sec->owner == output_bfd);
+ if (sec == obj_textsec (output_bfd))
+ type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
+ else if (sec == obj_datasec (output_bfd))
+ type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
+ else if (sec == obj_bsssec (output_bfd))
+ type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
+ else
+ type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
+ type |= N_EXT;
+ val = (h->root.u.def.value
+ + sec->vma
+ + h->root.u.def.section->output_offset);
+ }
+ break;
+ case bfd_link_hash_common:
+ type = N_UNDF | N_EXT;
+ val = h->root.u.c.size;
+ break;
+ case bfd_link_hash_undefweak:
+ type = N_WEAKU;
+ val = 0;
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ /* FIXME: Ignore these for now. The circumstances under which
+ they should be written out are not clear to me. */
+ return true;
+ }
+
+ bfd_h_put_8 (output_bfd, type, outsym.e_type);
+ bfd_h_put_8 (output_bfd, 0, outsym.e_other);
+ bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
+ indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
+ false);
+ if (indx == (bfd_size_type) -1)
+ {
+ /* FIXME: No way to handle errors. */
+ abort ();
+ }
+ PUT_WORD (output_bfd, indx, outsym.e_strx);
+ PUT_WORD (output_bfd, val, outsym.e_value);
+
+ if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
+ || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
+ (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
+ {
+ /* FIXME: No way to handle errors. */
+ abort ();
+ }
+
+ finfo->symoff += EXTERNAL_NLIST_SIZE;
+ h->indx = obj_aout_external_sym_count (output_bfd);
+ ++obj_aout_external_sym_count (output_bfd);
+
+ return true;
+}
+
+/* Link an a.out section into the output file. */
+
+static boolean
+aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
+ rel_size)
+ struct aout_final_link_info *finfo;
+ bfd *input_bfd;
+ asection *input_section;
+ file_ptr *reloff_ptr;
+ bfd_size_type rel_size;
+{
+ bfd_size_type input_size;
+ PTR relocs;
+
+ /* Get the section contents. */
+ input_size = bfd_section_size (input_bfd, input_section);
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (PTR) finfo->contents,
+ (file_ptr) 0, input_size))
+ return false;
+
+ /* Read in the relocs if we haven't already done it. */
+ if (aout_section_data (input_section) != NULL
+ && aout_section_data (input_section)->relocs != NULL)
+ relocs = aout_section_data (input_section)->relocs;
+ else
+ {
+ relocs = finfo->relocs;
+ if (rel_size > 0)
+ {
+ if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+ || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
+ return false;
+ }
+ }
+
+ /* Relocate the section contents. */
+ if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
+ {
+ if (! aout_link_input_section_std (finfo, input_bfd, input_section,
+ (struct reloc_std_external *) relocs,
+ rel_size, finfo->contents))
+ return false;
+ }
+ else
+ {
+ if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
+ (struct reloc_ext_external *) relocs,
+ rel_size, finfo->contents))
+ return false;
+ }
+
+ /* Write out the section contents. */
+ if (! bfd_set_section_contents (finfo->output_bfd,
+ input_section->output_section,
+ (PTR) finfo->contents,
+ input_section->output_offset,
+ input_size))
+ return false;
+
+ /* If we are producing relocateable output, the relocs were
+ modified, and we now write them out. */
+ if (finfo->info->relocateable && rel_size > 0)
+ {
+ if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
+ return false;
+ if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
+ != rel_size)
+ return false;
+ *reloff_ptr += rel_size;
+
+ /* Assert that the relocs have not run into the symbols, and
+ that if these are the text relocs they have not run into the
+ data relocs. */
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
+ && (reloff_ptr != &finfo->treloff
+ || (*reloff_ptr
+ <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ }
+
+ return true;
+}
+
+/* Get the section corresponding to a reloc index. */
+
+static INLINE asection *
+aout_reloc_index_to_section (abfd, indx)
+ bfd *abfd;
+ int indx;
+{
+ switch (indx & N_TYPE)
+ {
+ case N_TEXT:
+ return obj_textsec (abfd);
+ case N_DATA:
+ return obj_datasec (abfd);
+ case N_BSS:
+ return obj_bsssec (abfd);
+ case N_ABS:
+ case N_UNDF:
+ return bfd_abs_section_ptr;
+ default:
+ abort ();
+ }
+}
+
+/* Relocate an a.out section using standard a.out relocs. */
+
+static boolean
+aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
+ rel_size, contents)
+ struct aout_final_link_info *finfo;
+ bfd *input_bfd;
+ asection *input_section;
+ struct reloc_std_external *relocs;
+ bfd_size_type rel_size;
+ bfd_byte *contents;
+{
+ boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
+ bfd *, asection *,
+ struct aout_link_hash_entry *,
+ PTR, bfd_byte *, boolean *,
+ bfd_vma *));
+ bfd *output_bfd;
+ boolean relocateable;
+ struct external_nlist *syms;
+ char *strings;
+ struct aout_link_hash_entry **sym_hashes;
+ int *symbol_map;
+ bfd_size_type reloc_count;
+ register struct reloc_std_external *rel;
+ struct reloc_std_external *rel_end;
+
+ output_bfd = finfo->output_bfd;
+ check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
+
+ BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
+ BFD_ASSERT (input_bfd->xvec->header_byteorder
+ == output_bfd->xvec->header_byteorder);
+
+ relocateable = finfo->info->relocateable;
+ syms = obj_aout_external_syms (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ sym_hashes = obj_aout_sym_hashes (input_bfd);
+ symbol_map = finfo->symbol_map;
+
+ reloc_count = rel_size / RELOC_STD_SIZE;
+ rel = relocs;
+ rel_end = rel + reloc_count;
+ for (; rel < rel_end; rel++)
+ {
+ bfd_vma r_addr;
+ int r_index;
+ int r_extern;
+ int r_pcrel;
+ int r_baserel = 0;
+ reloc_howto_type *howto;
+ struct aout_link_hash_entry *h = NULL;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_addr = GET_SWORD (input_bfd, rel->r_address);
+
+#ifdef MY_reloc_howto
+ howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
+#else
+ {
+ int r_jmptable;
+ int r_relative;
+ int r_length;
+ unsigned int howto_idx;
+
+ if (bfd_header_big_endian (input_bfd))
+ {
+ r_index = ((rel->r_index[0] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[2]);
+ r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
+ r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+ r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
+ r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+ r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
+ r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
+ >> RELOC_STD_BITS_LENGTH_SH_BIG);
+ }
+ else
+ {
+ r_index = ((rel->r_index[2] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[0]);
+ r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+ r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+ r_baserel = (0 != (rel->r_type[0]
+ & RELOC_STD_BITS_BASEREL_LITTLE));
+ r_jmptable= (0 != (rel->r_type[0]
+ & RELOC_STD_BITS_JMPTABLE_LITTLE));
+ r_relative= (0 != (rel->r_type[0]
+ & RELOC_STD_BITS_RELATIVE_LITTLE));
+ r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+ >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
+ }
+
+ howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
+ + 16 * r_jmptable + 32 * r_relative);
+ BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
+ howto = howto_table_std + howto_idx;
+ }
+#endif
+
+ if (relocateable)
+ {
+ /* We are generating a relocateable output file, and must
+ modify the reloc accordingly. */
+ if (r_extern)
+ {
+ /* If we know the symbol this relocation is against,
+ convert it into a relocation against a section. This
+ is what the native linker does. */
+ h = sym_hashes[r_index];
+ if (h != (struct aout_link_hash_entry *) NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection *output_section;
+
+ /* Change the r_extern value. */
+ if (bfd_header_big_endian (output_bfd))
+ rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
+ else
+ rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
+
+ /* Compute a new r_index. */
+ output_section = h->root.u.def.section->output_section;
+ if (output_section == obj_textsec (output_bfd))
+ r_index = N_TEXT;
+ else if (output_section == obj_datasec (output_bfd))
+ r_index = N_DATA;
+ else if (output_section == obj_bsssec (output_bfd))
+ r_index = N_BSS;
+ else
+ r_index = N_ABS;
+
+ /* Add the symbol value and the section VMA to the
+ addend stored in the contents. */
+ relocation = (h->root.u.def.value
+ + output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ /* We must change r_index according to the symbol
+ map. */
+ r_index = symbol_map[r_index];
+
+ if (r_index == -1)
+ {
+ if (h != NULL)
+ {
+ /* We decided to strip this symbol, but it
+ turns out that we can't. Note that we
+ lose the other and desc information here.
+ I don't think that will ever matter for a
+ global symbol. */
+ if (h->indx < 0)
+ {
+ h->indx = -2;
+ h->written = false;
+ if (! aout_link_write_other_symbol (h,
+ (PTR) finfo))
+ return false;
+ }
+ r_index = h->indx;
+ }
+ else
+ {
+ const char *name;
+
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, name, input_bfd, input_section,
+ r_addr)))
+ return false;
+ r_index = 0;
+ }
+ }
+
+ relocation = 0;
+ }
+
+ /* Write out the new r_index value. */
+ if (bfd_header_big_endian (output_bfd))
+ {
+ rel->r_index[0] = r_index >> 16;
+ rel->r_index[1] = r_index >> 8;
+ rel->r_index[2] = r_index;
+ }
+ else
+ {
+ rel->r_index[2] = r_index >> 16;
+ rel->r_index[1] = r_index >> 8;
+ rel->r_index[0] = r_index;
+ }
+ }
+ else
+ {
+ asection *section;
+
+ /* This is a relocation against a section. We must
+ adjust by the amount that the section moved. */
+ section = aout_reloc_index_to_section (input_bfd, r_index);
+ relocation = (section->output_section->vma
+ + section->output_offset
+ - section->vma);
+ }
+
+ /* Change the address of the relocation. */
+ PUT_WORD (output_bfd,
+ r_addr + input_section->output_offset,
+ rel->r_address);
+
+ /* Adjust a PC relative relocation by removing the reference
+ to the original address in the section and including the
+ reference to the new address. */
+ if (r_pcrel)
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma);
+
+#ifdef MY_relocatable_reloc
+ MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
+#endif
+
+ if (relocation == 0)
+ r = bfd_reloc_ok;
+ else
+ r = MY_relocate_contents (howto,
+ input_bfd, relocation,
+ contents + r_addr);
+ }
+ else
+ {
+ boolean hundef;
+
+ /* We are generating an executable, and must do a full
+ relocation. */
+ hundef = false;
+
+ if (r_extern)
+ {
+ h = sym_hashes[r_index];
+
+ if (h != (struct aout_link_hash_entry *) NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ relocation = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else if (h != (struct aout_link_hash_entry *) NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ hundef = true;
+ relocation = 0;
+ }
+ }
+ else
+ {
+ asection *section;
+
+ section = aout_reloc_index_to_section (input_bfd, r_index);
+ relocation = (section->output_section->vma
+ + section->output_offset
+ - section->vma);
+ if (r_pcrel)
+ relocation += input_section->vma;
+ }
+
+ if (check_dynamic_reloc != NULL)
+ {
+ boolean skip;
+
+ if (! ((*check_dynamic_reloc)
+ (finfo->info, input_bfd, input_section, h,
+ (PTR) rel, contents, &skip, &relocation)))
+ return false;
+ if (skip)
+ continue;
+ }
+
+ /* Now warn if a global symbol is undefined. We could not
+ do this earlier, because check_dynamic_reloc might want
+ to skip this reloc. */
+ if (hundef && ! finfo->info->shared && ! r_baserel)
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
+ if (! ((*finfo->info->callbacks->undefined_symbol)
+ (finfo->info, name, input_bfd, input_section, r_addr)))
+ return false;
+ }
+
+ r = MY_final_link_relocate (howto,
+ input_bfd, input_section,
+ contents, r_addr, relocation,
+ (bfd_vma) 0);
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else if (r_extern)
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ else
+ {
+ asection *s;
+
+ s = aout_reloc_index_to_section (input_bfd, r_index);
+ name = bfd_section_name (input_bfd, s);
+ }
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info, name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, r_addr)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Relocate an a.out section using extended a.out relocs. */
+
+static boolean
+aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
+ rel_size, contents)
+ struct aout_final_link_info *finfo;
+ bfd *input_bfd;
+ asection *input_section;
+ struct reloc_ext_external *relocs;
+ bfd_size_type rel_size;
+ bfd_byte *contents;
+{
+ boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
+ bfd *, asection *,
+ struct aout_link_hash_entry *,
+ PTR, bfd_byte *, boolean *,
+ bfd_vma *));
+ bfd *output_bfd;
+ boolean relocateable;
+ struct external_nlist *syms;
+ char *strings;
+ struct aout_link_hash_entry **sym_hashes;
+ int *symbol_map;
+ bfd_size_type reloc_count;
+ register struct reloc_ext_external *rel;
+ struct reloc_ext_external *rel_end;
+
+ output_bfd = finfo->output_bfd;
+ check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
+
+ BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
+ BFD_ASSERT (input_bfd->xvec->header_byteorder
+ == output_bfd->xvec->header_byteorder);
+
+ relocateable = finfo->info->relocateable;
+ syms = obj_aout_external_syms (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ sym_hashes = obj_aout_sym_hashes (input_bfd);
+ symbol_map = finfo->symbol_map;
+
+ reloc_count = rel_size / RELOC_EXT_SIZE;
+ rel = relocs;
+ rel_end = rel + reloc_count;
+ for (; rel < rel_end; rel++)
+ {
+ bfd_vma r_addr;
+ int r_index;
+ int r_extern;
+ unsigned int r_type;
+ bfd_vma r_addend;
+ struct aout_link_hash_entry *h = NULL;
+ asection *r_section = NULL;
+ bfd_vma relocation;
+
+ r_addr = GET_SWORD (input_bfd, rel->r_address);
+
+ if (bfd_header_big_endian (input_bfd))
+ {
+ r_index = ((rel->r_index[0] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[2]);
+ r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
+ r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+ >> RELOC_EXT_BITS_TYPE_SH_BIG);
+ }
+ else
+ {
+ r_index = ((rel->r_index[2] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[0]);
+ r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
+ r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+ >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
+ }
+
+ r_addend = GET_SWORD (input_bfd, rel->r_addend);
+
+ BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
+
+ if (relocateable)
+ {
+ /* We are generating a relocateable output file, and must
+ modify the reloc accordingly. */
+ if (r_extern
+ || r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22)
+ {
+ /* If we know the symbol this relocation is against,
+ convert it into a relocation against a section. This
+ is what the native linker does. */
+ if (r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22)
+ h = NULL;
+ else
+ h = sym_hashes[r_index];
+ if (h != (struct aout_link_hash_entry *) NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection *output_section;
+
+ /* Change the r_extern value. */
+ if (bfd_header_big_endian (output_bfd))
+ rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
+ else
+ rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
+
+ /* Compute a new r_index. */
+ output_section = h->root.u.def.section->output_section;
+ if (output_section == obj_textsec (output_bfd))
+ r_index = N_TEXT;
+ else if (output_section == obj_datasec (output_bfd))
+ r_index = N_DATA;
+ else if (output_section == obj_bsssec (output_bfd))
+ r_index = N_BSS;
+ else
+ r_index = N_ABS;
+
+ /* Add the symbol value and the section VMA to the
+ addend. */
+ relocation = (h->root.u.def.value
+ + output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ /* Now RELOCATION is the VMA of the final
+ destination. If this is a PC relative reloc,
+ then ADDEND is the negative of the source VMA.
+ We want to set ADDEND to the difference between
+ the destination VMA and the source VMA, which
+ means we must adjust RELOCATION by the change in
+ the source VMA. This is done below. */
+ }
+ else
+ {
+ /* We must change r_index according to the symbol
+ map. */
+ r_index = symbol_map[r_index];
+
+ if (r_index == -1)
+ {
+ if (h != NULL)
+ {
+ /* We decided to strip this symbol, but it
+ turns out that we can't. Note that we
+ lose the other and desc information here.
+ I don't think that will ever matter for a
+ global symbol. */
+ if (h->indx < 0)
+ {
+ h->indx = -2;
+ h->written = false;
+ if (! aout_link_write_other_symbol (h,
+ (PTR) finfo))
+ return false;
+ }
+ r_index = h->indx;
+ }
+ else
+ {
+ const char *name;
+
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, name, input_bfd, input_section,
+ r_addr)))
+ return false;
+ r_index = 0;
+ }
+ }
+
+ relocation = 0;
+
+ /* If this is a PC relative reloc, then the addend
+ is the negative of the source VMA. We must
+ adjust it by the change in the source VMA. This
+ is done below. */
+ }
+
+ /* Write out the new r_index value. */
+ if (bfd_header_big_endian (output_bfd))
+ {
+ rel->r_index[0] = r_index >> 16;
+ rel->r_index[1] = r_index >> 8;
+ rel->r_index[2] = r_index;
+ }
+ else
+ {
+ rel->r_index[2] = r_index >> 16;
+ rel->r_index[1] = r_index >> 8;
+ rel->r_index[0] = r_index;
+ }
+ }
+ else
+ {
+ /* This is a relocation against a section. We must
+ adjust by the amount that the section moved. */
+ r_section = aout_reloc_index_to_section (input_bfd, r_index);
+ relocation = (r_section->output_section->vma
+ + r_section->output_offset
+ - r_section->vma);
+
+ /* If this is a PC relative reloc, then the addend is
+ the difference in VMA between the destination and the
+ source. We have just adjusted for the change in VMA
+ of the destination, so we must also adjust by the
+ change in VMA of the source. This is done below. */
+ }
+
+ /* As described above, we must always adjust a PC relative
+ reloc by the change in VMA of the source. However, if
+ pcrel_offset is set, then the addend does not include the
+ location within the section, in which case we don't need
+ to adjust anything. */
+ if (howto_table_ext[r_type].pc_relative
+ && ! howto_table_ext[r_type].pcrel_offset)
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma);
+
+ /* Change the addend if necessary. */
+ if (relocation != 0)
+ PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
+
+ /* Change the address of the relocation. */
+ PUT_WORD (output_bfd,
+ r_addr + input_section->output_offset,
+ rel->r_address);
+ }
+ else
+ {
+ boolean hundef;
+ bfd_reloc_status_type r;
+
+ /* We are generating an executable, and must do a full
+ relocation. */
+ hundef = false;
+
+ if (r_extern)
+ {
+ h = sym_hashes[r_index];
+
+ if (h != (struct aout_link_hash_entry *) NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ relocation = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else if (h != (struct aout_link_hash_entry *) NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ hundef = true;
+ relocation = 0;
+ }
+ }
+ else if (r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22)
+ {
+ struct external_nlist *sym;
+ int type;
+
+ /* For base relative relocs, r_index is always an index
+ into the symbol table, even if r_extern is 0. */
+ sym = syms + r_index;
+ type = bfd_h_get_8 (input_bfd, sym->e_type);
+ if ((type & N_TYPE) == N_TEXT
+ || type == N_WEAKT)
+ r_section = obj_textsec (input_bfd);
+ else if ((type & N_TYPE) == N_DATA
+ || type == N_WEAKD)
+ r_section = obj_datasec (input_bfd);
+ else if ((type & N_TYPE) == N_BSS
+ || type == N_WEAKB)
+ r_section = obj_bsssec (input_bfd);
+ else if ((type & N_TYPE) == N_ABS
+ || type == N_WEAKA)
+ r_section = bfd_abs_section_ptr;
+ else
+ abort ();
+ relocation = (r_section->output_section->vma
+ + r_section->output_offset
+ + (GET_WORD (input_bfd, sym->e_value)
+ - r_section->vma));
+ }
+ else
+ {
+ r_section = aout_reloc_index_to_section (input_bfd, r_index);
+
+ /* If this is a PC relative reloc, then R_ADDEND is the
+ difference between the two vmas, or
+ old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
+ where
+ old_dest_sec == section->vma
+ and
+ old_src_sec == input_section->vma
+ and
+ old_src_off == r_addr
+
+ _bfd_final_link_relocate expects RELOCATION +
+ R_ADDEND to be the VMA of the destination minus
+ r_addr (the minus r_addr is because this relocation
+ is not pcrel_offset, which is a bit confusing and
+ should, perhaps, be changed), or
+ new_dest_sec
+ where
+ new_dest_sec == output_section->vma + output_offset
+ We arrange for this to happen by setting RELOCATION to
+ new_dest_sec + old_src_sec - old_dest_sec
+
+ If this is not a PC relative reloc, then R_ADDEND is
+ simply the VMA of the destination, so we set
+ RELOCATION to the change in the destination VMA, or
+ new_dest_sec - old_dest_sec
+ */
+ relocation = (r_section->output_section->vma
+ + r_section->output_offset
+ - r_section->vma);
+ if (howto_table_ext[r_type].pc_relative)
+ relocation += input_section->vma;
+ }
+
+ if (check_dynamic_reloc != NULL)
+ {
+ boolean skip;
+
+ if (! ((*check_dynamic_reloc)
+ (finfo->info, input_bfd, input_section, h,
+ (PTR) rel, contents, &skip, &relocation)))
+ return false;
+ if (skip)
+ continue;
+ }
+
+ /* Now warn if a global symbol is undefined. We could not
+ do this earlier, because check_dynamic_reloc might want
+ to skip this reloc. */
+ if (hundef
+ && ! finfo->info->shared
+ && r_type != RELOC_BASE10
+ && r_type != RELOC_BASE13
+ && r_type != RELOC_BASE22)
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
+ if (! ((*finfo->info->callbacks->undefined_symbol)
+ (finfo->info, name, input_bfd, input_section, r_addr)))
+ return false;
+ }
+
+ if (r_type != RELOC_SPARC_REV32)
+ r = MY_final_link_relocate (howto_table_ext + r_type,
+ input_bfd, input_section,
+ contents, r_addr, relocation,
+ r_addend);
+ else
+ {
+ bfd_vma x;
+
+ x = bfd_get_32 (input_bfd, contents + r_addr);
+ x = x + relocation + r_addend;
+ bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
+ r = bfd_reloc_ok;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else if (r_extern
+ || r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22)
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ else
+ {
+ asection *s;
+
+ s = aout_reloc_index_to_section (input_bfd, r_index);
+ name = bfd_section_name (input_bfd, s);
+ }
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info, name, howto_table_ext[r_type].name,
+ r_addend, input_bfd, input_section, r_addr)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+static boolean
+aout_link_reloc_link_order (finfo, o, p)
+ struct aout_final_link_info *finfo;
+ asection *o;
+ struct bfd_link_order *p;
+{
+ struct bfd_link_order_reloc *pr;
+ int r_index;
+ int r_extern;
+ reloc_howto_type *howto;
+ file_ptr *reloff_ptr;
+ struct reloc_std_external srel;
+ struct reloc_ext_external erel;
+ PTR rel_ptr;
+
+ pr = p->u.reloc.p;
+
+ if (p->type == bfd_section_reloc_link_order)
+ {
+ r_extern = 0;
+ if (bfd_is_abs_section (pr->u.section))
+ r_index = N_ABS | N_EXT;
+ else
+ {
+ BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
+ r_index = pr->u.section->target_index;
+ }
+ }
+ else
+ {
+ struct aout_link_hash_entry *h;
+
+ BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
+ r_extern = 1;
+ h = ((struct aout_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
+ pr->u.name, false, false, true));
+ if (h != (struct aout_link_hash_entry *) NULL
+ && h->indx >= 0)
+ r_index = h->indx;
+ else if (h != NULL)
+ {
+ /* We decided to strip this symbol, but it turns out that we
+ can't. Note that we lose the other and desc information
+ here. I don't think that will ever matter for a global
+ symbol. */
+ h->indx = -2;
+ h->written = false;
+ if (! aout_link_write_other_symbol (h, (PTR) finfo))
+ return false;
+ r_index = h->indx;
+ }
+ else
+ {
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, pr->u.name, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ r_index = 0;
+ }
+ }
+
+ howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
+ if (howto == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (o == obj_textsec (finfo->output_bfd))
+ reloff_ptr = &finfo->treloff;
+ else if (o == obj_datasec (finfo->output_bfd))
+ reloff_ptr = &finfo->dreloff;
+ else
+ abort ();
+
+ if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
+ {
+#ifdef MY_put_reloc
+ MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
+ &srel);
+#else
+ {
+ int r_pcrel;
+ int r_baserel;
+ int r_jmptable;
+ int r_relative;
+ int r_length;
+
+ r_pcrel = howto->pc_relative;
+ r_baserel = (howto->type & 8) != 0;
+ r_jmptable = (howto->type & 16) != 0;
+ r_relative = (howto->type & 32) != 0;
+ r_length = howto->size;
+
+ PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
+ if (bfd_header_big_endian (finfo->output_bfd))
+ {
+ srel.r_index[0] = r_index >> 16;
+ srel.r_index[1] = r_index >> 8;
+ srel.r_index[2] = r_index;
+ srel.r_type[0] =
+ ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
+ | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
+ | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
+ | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
+ }
+ else
+ {
+ srel.r_index[2] = r_index >> 16;
+ srel.r_index[1] = r_index >> 8;
+ srel.r_index[0] = r_index;
+ srel.r_type[0] =
+ ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
+ | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
+ | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
+ | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
+ }
+ }
+#endif
+ rel_ptr = (PTR) &srel;
+
+ /* We have to write the addend into the object file, since
+ standard a.out relocs are in place. It would be more
+ reliable if we had the current contents of the file here,
+ rather than assuming zeroes, but we can't read the file since
+ it was opened using bfd_openw. */
+ if (pr->addend != 0)
+ {
+ bfd_size_type size;
+ bfd_reloc_status_type r;
+ bfd_byte *buf;
+ boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == (bfd_byte *) NULL)
+ return false;
+ r = MY_relocate_contents (howto, finfo->output_bfd,
+ pr->addend, buf);
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info,
+ (p->type == bfd_section_reloc_link_order
+ ? bfd_section_name (finfo->output_bfd,
+ pr->u.section)
+ : pr->u.name),
+ howto->name, pr->addend, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return false;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (finfo->output_bfd, o,
+ (PTR) buf,
+ (file_ptr) p->offset,
+ size);
+ free (buf);
+ if (! ok)
+ return false;
+ }
+ }
+ else
+ {
+ PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
+
+ if (bfd_header_big_endian (finfo->output_bfd))
+ {
+ erel.r_index[0] = r_index >> 16;
+ erel.r_index[1] = r_index >> 8;
+ erel.r_index[2] = r_index;
+ erel.r_type[0] =
+ ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
+ | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
+ }
+ else
+ {
+ erel.r_index[2] = r_index >> 16;
+ erel.r_index[1] = r_index >> 8;
+ erel.r_index[0] = r_index;
+ erel.r_type[0] =
+ (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
+ | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
+ }
+
+ PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
+
+ rel_ptr = (PTR) &erel;
+ }
+
+ if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
+ || (bfd_write (rel_ptr, (bfd_size_type) 1,
+ obj_reloc_entry_size (finfo->output_bfd),
+ finfo->output_bfd)
+ != obj_reloc_entry_size (finfo->output_bfd)))
+ return false;
+
+ *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
+
+ /* Assert that the relocs have not run into the symbols, and that n
+ the text relocs have not run into the data relocs. */
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
+ && (reloff_ptr != &finfo->treloff
+ || (*reloff_ptr
+ <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+
+ return true;
+}
diff --git a/bfd/archive.c b/bfd/archive.c
new file mode 100644
index 00000000000..8ac5aa4e95d
--- /dev/null
+++ b/bfd/archive.c
@@ -0,0 +1,2127 @@
+/* BFD back-end for archive files (libraries).
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+@setfilename archive-info
+SECTION
+ Archives
+
+DESCRIPTION
+ An archive (or library) is just another BFD. It has a symbol
+ table, although there's not much a user program will do with it.
+
+ The big difference between an archive BFD and an ordinary BFD
+ is that the archive doesn't have sections. Instead it has a
+ chain of BFDs that are considered its contents. These BFDs can
+ be manipulated like any other. The BFDs contained in an
+ archive opened for reading will all be opened for reading. You
+ may put either input or output BFDs into an archive opened for
+ output; they will be handled correctly when the archive is closed.
+
+ Use <<bfd_openr_next_archived_file>> to step through
+ the contents of an archive opened for input. You don't
+ have to read the entire archive if you don't want
+ to! Read it until you find what you want.
+
+ Archive contents of output BFDs are chained through the
+ <<next>> pointer in a BFD. The first one is findable through
+ the <<archive_head>> slot of the archive. Set it with
+ <<bfd_set_archive_head>> (q.v.). A given BFD may be in only one
+ open output archive at a time.
+
+ As expected, the BFD archive code is more general than the
+ archive code of any given environment. BFD archives may
+ contain files of different formats (e.g., a.out and coff) and
+ even different architectures. You may even place archives
+ recursively into archives!
+
+ This can cause unexpected confusion, since some archive
+ formats are more expressive than others. For instance, Intel
+ COFF archives can preserve long filenames; SunOS a.out archives
+ cannot. If you move a file from the first to the second
+ format and back again, the filename may be truncated.
+ Likewise, different a.out environments have different
+ conventions as to how they truncate filenames, whether they
+ preserve directory names in filenames, etc. When
+ interoperating with native tools, be sure your files are
+ homogeneous.
+
+ Beware: most of these formats do not react well to the
+ presence of spaces in filenames. We do the best we can, but
+ can't always handle this case due to restrictions in the format of
+ archives. Many Unix utilities are braindead in regards to
+ spaces and such in filenames anyway, so this shouldn't be much
+ of a restriction.
+
+ Archives are supported in BFD in <<archive.c>>.
+
+*/
+
+/* Assumes:
+ o - all archive elements start on an even boundary, newline padded;
+ o - all arch headers are char *;
+ o - all arch headers are the same size (across architectures).
+*/
+
+/* Some formats provide a way to cram a long filename into the short
+ (16 chars) space provided by a BSD archive. The trick is: make a
+ special "file" in the front of the archive, sort of like the SYMDEF
+ entry. If the filename is too long to fit, put it in the extended
+ name table, and use its index as the filename. To prevent
+ confusion prepend the index with a space. This means you can't
+ have filenames that start with a space, but then again, many Unix
+ utilities can't handle that anyway.
+
+ This scheme unfortunately requires that you stand on your head in
+ order to write an archive since you need to put a magic file at the
+ front, and need to touch every entry to do so. C'est la vie.
+
+ We support two variants of this idea:
+ The SVR4 format (extended name table is named "//"),
+ and an extended pseudo-BSD variant (extended name table is named
+ "ARFILENAMES/"). The origin of the latter format is uncertain.
+
+ BSD 4.4 uses a third scheme: It writes a long filename
+ directly after the header. This allows 'ar q' to work.
+ We currently can read BSD 4.4 archives, but not write them.
+*/
+
+/* Summary of archive member names:
+
+ Symbol table (must be first):
+ "__.SYMDEF " - Symbol table, Berkeley style, produced by ranlib.
+ "/ " - Symbol table, system 5 style.
+
+ Long name table (must be before regular file members):
+ "// " - Long name table, System 5 R4 style.
+ "ARFILENAMES/ " - Long name table, non-standard extended BSD (not BSD 4.4).
+
+ Regular file members with short names:
+ "filename.o/ " - Regular file, System 5 style (embedded spaces ok).
+ "filename.o " - Regular file, Berkeley style (no embedded spaces).
+
+ Regular files with long names (or embedded spaces, for BSD variants):
+ "/18 " - SVR4 style, name at offset 18 in name table.
+ "#1/23 " - Long name (or embedded paces) 23 characters long,
+ BSD 4.4 style, full name follows header.
+ Implemented for reading, not writing.
+ " 18 " - Long name 18 characters long, extended pseudo-BSD.
+ */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+#include "aout/ranlib.h"
+#include <ctype.h>
+
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef GNU960
+#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB)
+#endif
+
+/* Define offsetof for those systems which lack it */
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+/* We keep a cache of archive filepointers to archive elements to
+ speed up searching the archive by filepos. We only add an entry to
+ the cache when we actually read one. We also don't sort the cache;
+ it's generally short enough to search linearly.
+ Note that the pointers here point to the front of the ar_hdr, not
+ to the front of the contents!
+*/
+struct ar_cache
+{
+ file_ptr ptr;
+ bfd *arelt;
+ struct ar_cache *next;
+};
+
+#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
+#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)
+
+#define arch_eltdata(bfd) ((struct areltdata *)((bfd)->arelt_data))
+#define arch_hdr(bfd) ((struct ar_hdr *)arch_eltdata(bfd)->arch_header)
+
+static char *get_extended_arelt_filename PARAMS ((bfd *arch,
+ const char *name));
+static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd));
+static boolean do_slurp_coff_armap PARAMS ((bfd *abfd));
+static const char *normalize PARAMS ((bfd *, const char *file));
+static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
+ const char *,
+ bfd *member));
+
+boolean
+_bfd_generic_mkarchive (abfd)
+ bfd *abfd;
+{
+ abfd->tdata.aout_ar_data = ((struct artdata *)
+ bfd_zalloc (abfd, sizeof (struct artdata)));
+
+ if (bfd_ardata (abfd) == NULL)
+ return false;
+
+ bfd_ardata (abfd)->cache = NULL;
+ bfd_ardata (abfd)->archive_head = NULL;
+ bfd_ardata (abfd)->symdefs = NULL;
+ bfd_ardata (abfd)->extended_names = NULL;
+ bfd_ardata (abfd)->tdata = NULL;
+
+ return true;
+}
+
+/*
+FUNCTION
+ bfd_get_next_mapent
+
+SYNOPSIS
+ symindex bfd_get_next_mapent(bfd *abfd, symindex previous, carsym **sym);
+
+DESCRIPTION
+ Step through archive @var{abfd}'s symbol table (if it
+ has one). Successively update @var{sym} with the next symbol's
+ information, returning that symbol's (internal) index into the
+ symbol table.
+
+ Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get
+ the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already
+ got the last one.
+
+ A <<carsym>> is a canonical archive symbol. The only
+ user-visible element is its name, a null-terminated string.
+*/
+
+symindex
+bfd_get_next_mapent (abfd, prev, entry)
+ bfd *abfd;
+ symindex prev;
+ carsym **entry;
+{
+ if (!bfd_has_map (abfd))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return BFD_NO_MORE_SYMBOLS;
+ }
+
+ if (prev == BFD_NO_MORE_SYMBOLS)
+ prev = 0;
+ else
+ ++prev;
+ if (prev >= bfd_ardata (abfd)->symdef_count)
+ return BFD_NO_MORE_SYMBOLS;
+
+ *entry = (bfd_ardata (abfd)->symdefs + prev);
+ return prev;
+}
+
+/* To be called by backends only */
+
+bfd *
+_bfd_create_empty_archive_element_shell (obfd)
+ bfd *obfd;
+{
+ return _bfd_new_bfd_contained_in (obfd);
+}
+
+/*
+FUNCTION
+ bfd_set_archive_head
+
+SYNOPSIS
+ boolean bfd_set_archive_head(bfd *output, bfd *new_head);
+
+DESCRIPTION
+ Set the head of the chain of
+ BFDs contained in the archive @var{output} to @var{new_head}.
+*/
+
+boolean
+bfd_set_archive_head (output_archive, new_head)
+ bfd *output_archive;
+ bfd *new_head;
+{
+
+ output_archive->archive_head = new_head;
+ return true;
+}
+
+bfd *
+_bfd_look_for_bfd_in_cache (arch_bfd, filepos)
+ bfd *arch_bfd;
+ file_ptr filepos;
+{
+ struct ar_cache *current;
+
+ for (current = bfd_ardata (arch_bfd)->cache; current != NULL;
+ current = current->next)
+ if (current->ptr == filepos)
+ return current->arelt;
+
+ return NULL;
+}
+
+/* Kind of stupid to call cons for each one, but we don't do too many */
+boolean
+_bfd_add_bfd_to_archive_cache (arch_bfd, filepos, new_elt)
+ bfd *arch_bfd, *new_elt;
+ file_ptr filepos;
+{
+ struct ar_cache *new_cache = ((struct ar_cache *)
+ bfd_zalloc (arch_bfd,
+ sizeof (struct ar_cache)));
+
+ if (new_cache == NULL)
+ return false;
+
+ new_cache->ptr = filepos;
+ new_cache->arelt = new_elt;
+ new_cache->next = (struct ar_cache *) NULL;
+ if (bfd_ardata (arch_bfd)->cache == NULL)
+ bfd_ardata (arch_bfd)->cache = new_cache;
+ else
+ {
+ struct ar_cache *current = bfd_ardata (arch_bfd)->cache;
+
+ while (current->next != NULL)
+ current = current->next;
+ current->next = new_cache;
+ }
+
+ return true;
+}
+
+/* The name begins with space. Hence the rest of the name is an index into
+ the string table. */
+
+static char *
+get_extended_arelt_filename (arch, name)
+ bfd *arch;
+ const char *name;
+{
+ unsigned long index = 0;
+
+ /* Should extract string so that I can guarantee not to overflow into
+ the next region, but I'm too lazy. */
+ errno = 0;
+ /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */
+ index = strtol (name + 1, NULL, 10);
+ if (errno != 0)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+
+ return bfd_ardata (arch)->extended_names + index;
+}
+
+/* This functions reads an arch header and returns an areltdata pointer, or
+ NULL on error.
+
+ Presumes the file pointer is already in the right place (ie pointing
+ to the ar_hdr in the file). Moves the file pointer; on success it
+ should be pointing to the front of the file contents; on failure it
+ could have been moved arbitrarily.
+*/
+
+PTR
+_bfd_generic_read_ar_hdr (abfd)
+ bfd *abfd;
+{
+ return _bfd_generic_read_ar_hdr_mag (abfd, (const char *) NULL);
+}
+
+/* Alpha ECOFF uses an optional different ARFMAG value, so we have a
+ variant of _bfd_generic_read_ar_hdr which accepts a magic string. */
+
+PTR
+_bfd_generic_read_ar_hdr_mag (abfd, mag)
+ bfd *abfd;
+ const char *mag;
+{
+ struct ar_hdr hdr;
+ char *hdrp = (char *) &hdr;
+ unsigned int parsed_size;
+ struct areltdata *ared;
+ char *filename = NULL;
+ unsigned int namelen = 0;
+ unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
+ char *allocptr = 0;
+
+ if (bfd_read ((PTR) hdrp, 1, sizeof (struct ar_hdr), abfd)
+ != sizeof (struct ar_hdr))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+ if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
+ && (mag == NULL
+ || strncmp (hdr.ar_fmag, mag, 2) != 0))
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+
+ errno = 0;
+ parsed_size = strtol (hdr.ar_size, NULL, 10);
+ if (errno != 0)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+
+ /* Extract the filename from the archive - there are two ways to
+ specify an extended name table, either the first char of the
+ name is a space, or it's a slash. */
+ if ((hdr.ar_name[0] == '/'
+ || (hdr.ar_name[0] == ' '
+ && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL))
+ && bfd_ardata (abfd)->extended_names != NULL)
+ {
+ filename = get_extended_arelt_filename (abfd, hdr.ar_name);
+ if (filename == NULL)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+ }
+ /* BSD4.4-style long filename.
+ Only implemented for reading, so far! */
+ else if (hdr.ar_name[0] == '#'
+ && hdr.ar_name[1] == '1'
+ && hdr.ar_name[2] == '/'
+ && isdigit ((unsigned char) hdr.ar_name[3]))
+ {
+ /* BSD-4.4 extended name */
+ namelen = atoi (&hdr.ar_name[3]);
+ allocsize += namelen + 1;
+ parsed_size -= namelen;
+
+ allocptr = bfd_zalloc (abfd, allocsize);
+ if (allocptr == NULL)
+ return NULL;
+ filename = (allocptr
+ + sizeof (struct areltdata)
+ + sizeof (struct ar_hdr));
+ if (bfd_read (filename, 1, namelen, abfd) != namelen)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+ filename[namelen] = '\0';
+ }
+ else
+ {
+ /* We judge the end of the name by looking for '/' or ' '.
+ Note: The SYSV format (terminated by '/') allows embedded
+ spaces, so only look for ' ' if we don't find '/'. */
+
+ char *e;
+ e = memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
+ if (e == NULL)
+ {
+ e = memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
+ if (e == NULL)
+ e = memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
+ }
+
+ if (e != NULL)
+ namelen = e - hdr.ar_name;
+ else
+ {
+ /* If we didn't find a termination character, then the name
+ must be the entire field. */
+ namelen = ar_maxnamelen (abfd);
+ }
+
+ allocsize += namelen + 1;
+ }
+
+ if (!allocptr)
+ {
+ allocptr = bfd_zalloc (abfd, allocsize);
+ if (allocptr == NULL)
+ return NULL;
+ }
+
+ ared = (struct areltdata *) allocptr;
+
+ ared->arch_header = allocptr + sizeof (struct areltdata);
+ memcpy ((char *) ared->arch_header, (char *) &hdr, sizeof (struct ar_hdr));
+ ared->parsed_size = parsed_size;
+
+ if (filename != NULL)
+ ared->filename = filename;
+ else
+ {
+ ared->filename = allocptr + (sizeof (struct areltdata) +
+ sizeof (struct ar_hdr));
+ if (namelen)
+ memcpy (ared->filename, hdr.ar_name, namelen);
+ ared->filename[namelen] = '\0';
+ }
+
+ return (PTR) ared;
+}
+
+/* This is an internal function; it's mainly used when indexing
+ through the archive symbol table, but also used to get the next
+ element, since it handles the bookkeeping so nicely for us. */
+
+bfd *
+_bfd_get_elt_at_filepos (archive, filepos)
+ bfd *archive;
+ file_ptr filepos;
+{
+ struct areltdata *new_areldata;
+ bfd *n_nfd;
+
+ n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos);
+ if (n_nfd)
+ return n_nfd;
+
+ if (0 > bfd_seek (archive, filepos, SEEK_SET))
+ return NULL;
+
+ if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL)
+ return NULL;
+
+ n_nfd = _bfd_create_empty_archive_element_shell (archive);
+ if (n_nfd == NULL)
+ {
+ bfd_release (archive, (PTR) new_areldata);
+ return NULL;
+ }
+
+ n_nfd->origin = bfd_tell (archive);
+ n_nfd->arelt_data = (PTR) new_areldata;
+ n_nfd->filename = new_areldata->filename;
+
+ if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
+ return n_nfd;
+
+ /* huh? */
+ bfd_release (archive, (PTR) n_nfd);
+ bfd_release (archive, (PTR) new_areldata);
+ return NULL;
+}
+
+/* Return the BFD which is referenced by the symbol in ABFD indexed by
+ INDEX. INDEX should have been returned by bfd_get_next_mapent. */
+
+bfd *
+_bfd_generic_get_elt_at_index (abfd, index)
+ bfd *abfd;
+ symindex index;
+{
+ carsym *entry;
+
+ entry = bfd_ardata (abfd)->symdefs + index;
+ return _bfd_get_elt_at_filepos (abfd, entry->file_offset);
+}
+
+/*
+FUNCTION
+ bfd_openr_next_archived_file
+
+SYNOPSIS
+ bfd *bfd_openr_next_archived_file(bfd *archive, bfd *previous);
+
+DESCRIPTION
+ Provided a BFD, @var{archive}, containing an archive and NULL, open
+ an input BFD on the first contained element and returns that.
+ Subsequent calls should pass
+ the archive and the previous return value to return a created
+ BFD to the next contained element. NULL is returned when there
+ are no more.
+
+*/
+
+bfd *
+bfd_openr_next_archived_file (archive, last_file)
+ bfd *archive;
+ bfd *last_file;
+{
+ if ((bfd_get_format (archive) != bfd_archive) ||
+ (archive->direction == write_direction))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ return BFD_SEND (archive,
+ openr_next_archived_file,
+ (archive,
+ last_file));
+}
+
+bfd *
+bfd_generic_openr_next_archived_file (archive, last_file)
+ bfd *archive;
+ bfd *last_file;
+{
+ file_ptr filestart;
+
+ if (!last_file)
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ else
+ {
+ unsigned int size = arelt_size (last_file);
+ /* Pad to an even boundary...
+ Note that last_file->origin can be odd in the case of
+ BSD-4.4-style element with a long odd size. */
+ filestart = last_file->origin + size;
+ filestart += filestart % 2;
+ }
+
+ return _bfd_get_elt_at_filepos (archive, filestart);
+}
+
+
+const bfd_target *
+bfd_generic_archive_p (abfd)
+ bfd *abfd;
+{
+ struct artdata *tdata_hold;
+ char armag[SARMAG + 1];
+
+ tdata_hold = abfd->tdata.aout_ar_data;
+
+ if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+#ifdef GNU960
+ if (strncmp (armag, BFD_GNU960_ARMAG (abfd), SARMAG) != 0)
+ return 0;
+#else
+ if (strncmp (armag, ARMAG, SARMAG) != 0 &&
+ strncmp (armag, ARMAGB, SARMAG) != 0)
+ return 0;
+#endif
+
+ /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
+ involves a cast, we can't do it as the left operand of assignment. */
+ abfd->tdata.aout_ar_data = ((struct artdata *)
+ bfd_zalloc (abfd, sizeof (struct artdata)));
+
+ if (bfd_ardata (abfd) == NULL)
+ return NULL;
+
+ bfd_ardata (abfd)->first_file_filepos = SARMAG;
+ bfd_ardata (abfd)->cache = NULL;
+ bfd_ardata (abfd)->archive_head = NULL;
+ bfd_ardata (abfd)->symdefs = NULL;
+ bfd_ardata (abfd)->extended_names = NULL;
+ bfd_ardata (abfd)->tdata = NULL;
+
+ if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd)))
+ {
+ bfd_release (abfd, bfd_ardata (abfd));
+ abfd->tdata.aout_ar_data = tdata_hold;
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
+ {
+ bfd_release (abfd, bfd_ardata (abfd));
+ abfd->tdata.aout_ar_data = tdata_hold;
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_has_map (abfd))
+ {
+ bfd *first;
+
+ /* This archive has a map, so we may presume that the contents
+ are object files. Make sure that if the first file in the
+ archive can be recognized as an object file, it is for this
+ target. If not, assume that this is the wrong format. If
+ the first file is not an object file, somebody is doing
+ something weird, and we permit it so that ar -t will work.
+
+ This is done because any normal format will recognize any
+ normal archive, regardless of the format of the object files.
+ We do accept an empty archive. */
+
+ first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
+ if (first != NULL)
+ {
+ boolean fail;
+
+ first->target_defaulted = false;
+ fail = false;
+ if (bfd_check_format (first, bfd_object)
+ && first->xvec != abfd->xvec)
+ {
+ (void) bfd_close (first);
+ bfd_release (abfd, bfd_ardata (abfd));
+ abfd->tdata.aout_ar_data = tdata_hold;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* We ought to close first here, but we can't, because we
+ have no way to remove it from the archive cache. FIXME. */
+ }
+ }
+
+ return abfd->xvec;
+}
+
+/* Some constants for a 32 bit BSD archive structure. We do not
+ support 64 bit archives presently; so far as I know, none actually
+ exist. Supporting them would require changing these constants, and
+ changing some bfd_h_get_32 to bfd_h_get_64. */
+
+/* The size of an external symdef structure. */
+#define BSD_SYMDEF_SIZE 8
+
+/* The offset from the start of a symdef structure to the file offset. */
+#define BSD_SYMDEF_OFFSET_SIZE 4
+
+/* The size of the symdef count. */
+#define BSD_SYMDEF_COUNT_SIZE 4
+
+/* The size of the string count. */
+#define BSD_STRING_COUNT_SIZE 4
+
+/* Returns false on error, true otherwise */
+
+static boolean
+do_slurp_bsd_armap (abfd)
+ bfd *abfd;
+{
+ struct areltdata *mapdata;
+ unsigned int counter;
+ bfd_byte *raw_armap, *rbase;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char *stringbase;
+ unsigned int parsed_size;
+ carsym *set;
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return false;
+ parsed_size = mapdata->parsed_size;
+ bfd_release (abfd, (PTR) mapdata); /* Don't need it any more. */
+
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
+ if (raw_armap == (bfd_byte *) NULL)
+ return false;
+
+ if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ byebye:
+ bfd_release (abfd, (PTR) raw_armap);
+ return false;
+ }
+
+ ardata->symdef_count = bfd_h_get_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE;
+
+ if (ardata->symdef_count * BSD_SYMDEF_SIZE >
+ parsed_size - BSD_SYMDEF_COUNT_SIZE)
+ {
+ /* Probably we're using the wrong byte ordering. */
+ bfd_set_error (bfd_error_wrong_format);
+ goto byebye;
+ }
+
+ ardata->cache = 0;
+ rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE;
+ stringbase = ((char *) rbase
+ + ardata->symdef_count * BSD_SYMDEF_SIZE
+ + BSD_STRING_COUNT_SIZE);
+ ardata->symdefs = (carsym *) bfd_alloc (abfd,
+ (ardata->symdef_count
+ * sizeof (carsym)));
+ if (!ardata->symdefs)
+ return false;
+
+ for (counter = 0, set = ardata->symdefs;
+ counter < ardata->symdef_count;
+ counter++, set++, rbase += BSD_SYMDEF_SIZE)
+ {
+ set->name = bfd_h_get_32 (abfd, rbase) + stringbase;
+ set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
+ }
+
+ ardata->first_file_filepos = bfd_tell (abfd);
+ /* Pad to an even boundary if you have to */
+ ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
+ /* FIXME, we should provide some way to free raw_ardata when
+ we are done using the strings from it. For now, it seems
+ to be allocated on an objalloc anyway... */
+ bfd_has_map (abfd) = true;
+ return true;
+}
+
+/* Returns false on error, true otherwise */
+static boolean
+do_slurp_coff_armap (abfd)
+ bfd *abfd;
+{
+ struct areltdata *mapdata;
+ int *raw_armap, *rawptr;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char *stringbase;
+ unsigned int stringsize;
+ unsigned int parsed_size;
+ carsym *carsyms;
+ unsigned int nsymz; /* Number of symbols in armap. */
+ bfd_vma (*swap) PARAMS ((const bfd_byte *));
+ char int_buf[sizeof (long)];
+ unsigned int carsym_size, ptrsize, i;
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return false;
+ parsed_size = mapdata->parsed_size;
+ bfd_release (abfd, (PTR) mapdata); /* Don't need it any more. */
+
+ if (bfd_read ((PTR) int_buf, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
+ }
+ /* It seems that all numeric information in a coff archive is always
+ in big endian format, nomatter the host or target. */
+ swap = bfd_getb32;
+ nsymz = bfd_getb32 ((PTR) int_buf);
+ stringsize = parsed_size - (4 * nsymz) - 4;
+
+#if 1
+ /* ... except that some archive formats are broken, and it may be our
+ fault - the i960 little endian coff sometimes has big and sometimes
+ little, because our tools changed. Here's a horrible hack to clean
+ up the crap. */
+
+ if (stringsize > 0xfffff
+ && bfd_get_arch (abfd) == bfd_arch_i960
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour)
+ {
+ /* This looks dangerous, let's do it the other way around */
+ nsymz = bfd_getl32 ((PTR) int_buf);
+ stringsize = parsed_size - (4 * nsymz) - 4;
+ swap = bfd_getl32;
+ }
+#endif
+
+ /* The coff armap must be read sequentially. So we construct a
+ bsd-style one in core all at once, for simplicity. */
+
+ carsym_size = (nsymz * sizeof (carsym));
+ ptrsize = (4 * nsymz);
+
+ ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
+ if (ardata->symdefs == NULL)
+ return false;
+ carsyms = ardata->symdefs;
+ stringbase = ((char *) ardata->symdefs) + carsym_size;
+
+ /* Allocate and read in the raw offsets. */
+ raw_armap = (int *) bfd_alloc (abfd, ptrsize);
+ if (raw_armap == NULL)
+ goto release_symdefs;
+ if (bfd_read ((PTR) raw_armap, 1, ptrsize, abfd) != ptrsize
+ || bfd_read ((PTR) stringbase, 1, stringsize, abfd) != stringsize)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ goto release_raw_armap;
+ }
+
+ /* OK, build the carsyms */
+ for (i = 0; i < nsymz; i++)
+ {
+ rawptr = raw_armap + i;
+ carsyms->file_offset = swap ((PTR) rawptr);
+ carsyms->name = stringbase;
+ stringbase += strlen (stringbase) + 1;
+ carsyms++;
+ }
+ *stringbase = 0;
+
+ ardata->symdef_count = nsymz;
+ ardata->first_file_filepos = bfd_tell (abfd);
+ /* Pad to an even boundary if you have to */
+ ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
+
+
+ bfd_has_map (abfd) = true;
+ bfd_release (abfd, (PTR) raw_armap);
+
+
+ /* Check for a second archive header (as used by PE) */
+ {
+ struct areltdata *tmp;
+
+ bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET);
+ tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (tmp != NULL)
+ {
+ if (tmp->arch_header[0] == '/'
+ && tmp->arch_header[1] == ' ')
+ {
+ ardata->first_file_filepos +=
+ (tmp->parsed_size + sizeof(struct ar_hdr) + 1) & ~1;
+ }
+ bfd_release (abfd, tmp);
+ }
+ }
+
+ return true;
+
+release_raw_armap:
+ bfd_release (abfd, (PTR) raw_armap);
+release_symdefs:
+ bfd_release (abfd, (PTR) (ardata)->symdefs);
+ return false;
+}
+
+/* This routine can handle either coff-style or bsd-style armaps.
+ Returns false on error, true otherwise */
+
+boolean
+bfd_slurp_armap (abfd)
+ bfd *abfd;
+{
+ char nextname[17];
+ int i = bfd_read ((PTR) nextname, 1, 16, abfd);
+
+ if (i == 0)
+ return true;
+ if (i != 16)
+ return false;
+
+ if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+ return false;
+
+ if (!strncmp (nextname, "__.SYMDEF ", 16)
+ || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */
+ return do_slurp_bsd_armap (abfd);
+ else if (!strncmp (nextname, "/ ", 16))
+ return do_slurp_coff_armap (abfd);
+ else if (!strncmp (nextname, "/SYM64/ ", 16))
+ {
+ /* Irix 6 archive--must be recognized by code in elf64-mips.c. */
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ bfd_has_map (abfd) = false;
+ return true;
+}
+
+/* Returns false on error, true otherwise */
+/* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the
+ header is in a slightly different order and the map name is '/'.
+ This flavour is used by hp300hpux. */
+
+#define HPUX_SYMDEF_COUNT_SIZE 2
+
+boolean
+bfd_slurp_bsd_armap_f2 (abfd)
+ bfd *abfd;
+{
+ struct areltdata *mapdata;
+ char nextname[17];
+ unsigned int counter;
+ bfd_byte *raw_armap, *rbase;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char *stringbase;
+ unsigned int stringsize;
+ carsym *set;
+ int i = bfd_read ((PTR) nextname, 1, 16, abfd);
+
+ if (i == 0)
+ return true;
+ if (i != 16)
+ return false;
+
+ /* The archive has at least 16 bytes in it */
+ if (bfd_seek (abfd, -16L, SEEK_CUR) != 0)
+ return false;
+
+ if (!strncmp (nextname, "__.SYMDEF ", 16)
+ || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */
+ return do_slurp_bsd_armap (abfd);
+
+ if (strncmp (nextname, "/ ", 16))
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return false;
+
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size);
+ if (raw_armap == NULL)
+ {
+ byebye:
+ bfd_release (abfd, (PTR) mapdata);
+ return false;
+ }
+
+ if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) !=
+ mapdata->parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ byebyebye:
+ bfd_release (abfd, (PTR) raw_armap);
+ goto byebye;
+ }
+
+ ardata->symdef_count = bfd_h_get_16 (abfd, (PTR) raw_armap);
+
+ if (ardata->symdef_count * BSD_SYMDEF_SIZE
+ > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE)
+ {
+ /* Probably we're using the wrong byte ordering. */
+ bfd_set_error (bfd_error_wrong_format);
+ goto byebyebye;
+ }
+
+ ardata->cache = 0;
+
+ stringsize = bfd_h_get_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
+ /* skip sym count and string sz */
+ stringbase = ((char *) raw_armap
+ + HPUX_SYMDEF_COUNT_SIZE
+ + BSD_STRING_COUNT_SIZE);
+ rbase = (bfd_byte *) stringbase + stringsize;
+ ardata->symdefs = (carsym *) bfd_alloc (abfd,
+ (ardata->symdef_count
+ * BSD_SYMDEF_SIZE));
+ if (!ardata->symdefs)
+ return false;
+
+ for (counter = 0, set = ardata->symdefs;
+ counter < ardata->symdef_count;
+ counter++, set++, rbase += BSD_SYMDEF_SIZE)
+ {
+ set->name = bfd_h_get_32 (abfd, rbase) + stringbase;
+ set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
+ }
+
+ ardata->first_file_filepos = bfd_tell (abfd);
+ /* Pad to an even boundary if you have to */
+ ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
+ /* FIXME, we should provide some way to free raw_ardata when
+ we are done using the strings from it. For now, it seems
+ to be allocated on an objalloc anyway... */
+ bfd_has_map (abfd) = true;
+ return true;
+}
+
+/** Extended name table.
+
+ Normally archives support only 14-character filenames.
+
+ Intel has extended the format: longer names are stored in a special
+ element (the first in the archive, or second if there is an armap);
+ the name in the ar_hdr is replaced by <space><index into filename
+ element>. Index is the P.R. of an int (decimal). Data General have
+ extended the format by using the prefix // for the special element */
+
+/* Returns false on error, true otherwise */
+boolean
+_bfd_slurp_extended_name_table (abfd)
+ bfd *abfd;
+{
+ char nextname[17];
+ struct areltdata *namedata;
+
+ /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
+ we probably don't want to return true. */
+ bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET);
+ if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16)
+ {
+ if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+ return false;
+
+ if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 &&
+ strncmp (nextname, "// ", 16) != 0)
+ {
+ bfd_ardata (abfd)->extended_names = NULL;
+ return true;
+ }
+
+ namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (namedata == NULL)
+ return false;
+
+ bfd_ardata (abfd)->extended_names =
+ bfd_zalloc (abfd, namedata->parsed_size);
+ if (bfd_ardata (abfd)->extended_names == NULL)
+ {
+ byebye:
+ bfd_release (abfd, (PTR) namedata);
+ return false;
+ }
+
+ if (bfd_read ((PTR) bfd_ardata (abfd)->extended_names, 1,
+ namedata->parsed_size, abfd) != namedata->parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names));
+ bfd_ardata (abfd)->extended_names = NULL;
+ goto byebye;
+ }
+
+ /* Since the archive is supposed to be printable if it contains
+ text, the entries in the list are newline-padded, not null
+ padded. In SVR4-style archives, the names also have a
+ trailing '/'. DOS/NT created archive often have \ in them
+ We'll fix all problems here.. */
+ {
+ char *temp = bfd_ardata (abfd)->extended_names;
+ char *limit = temp + namedata->parsed_size;
+ for (; temp < limit; ++temp) {
+ if (*temp == '\012')
+ temp[temp[-1] == '/' ? -1 : 0] = '\0';
+ if (*temp == '\\')
+ *temp = '/';
+ }
+ }
+
+ /* Pad to an even boundary if you have to */
+ bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd);
+ bfd_ardata (abfd)->first_file_filepos +=
+ (bfd_ardata (abfd)->first_file_filepos) % 2;
+
+ /* FIXME, we can't release namedata here because it was allocated
+ below extended_names on the objalloc... */
+ /* bfd_release (abfd, namedata); */
+ }
+ return true;
+}
+
+#ifdef VMS
+
+/* Return a copy of the stuff in the filename between any :]> and a
+ semicolon */
+static const char *
+normalize (abfd, file)
+ bfd *abfd;
+ const char *file;
+{
+ CONST char *first;
+ CONST char *last;
+ char *copy;
+
+ first = file + strlen (file) - 1;
+ last = first + 1;
+
+ while (first != file)
+ {
+ if (*first == ';')
+ last = first;
+ if (*first == ':' || *first == ']' || *first == '>')
+ {
+ first++;
+ break;
+ }
+ first--;
+ }
+
+ copy = (char *) bfd_alloc (abfd, last - first + 1);
+ if (copy == NULL)
+ return NULL;
+
+ memcpy (copy, first, last - first);
+ copy[last - first] = 0;
+
+ return copy;
+}
+
+#else
+static const char *
+normalize (abfd, file)
+ bfd *abfd;
+ const char *file;
+{
+ const char *filename = strrchr (file, '/');
+
+ if (filename != (char *) NULL)
+ filename++;
+ else
+ filename = file;
+ return filename;
+}
+#endif
+
+/* Build a BFD style extended name table. */
+
+boolean
+_bfd_archive_bsd_construct_extended_name_table (abfd, tabloc, tablen, name)
+ bfd *abfd;
+ char **tabloc;
+ bfd_size_type *tablen;
+ const char **name;
+{
+ *name = "ARFILENAMES/";
+ return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);
+}
+
+/* Build an SVR4 style extended name table. */
+
+boolean
+_bfd_archive_coff_construct_extended_name_table (abfd, tabloc, tablen, name)
+ bfd *abfd;
+ char **tabloc;
+ bfd_size_type *tablen;
+ const char **name;
+{
+ *name = "//";
+ return _bfd_construct_extended_name_table (abfd, true, tabloc, tablen);
+}
+
+/* Follows archive_head and produces an extended name table if
+ necessary. Returns (in tabloc) a pointer to an extended name
+ table, and in tablen the length of the table. If it makes an entry
+ it clobbers the filename so that the element may be written without
+ further massage. Returns true if it ran successfully, false if
+ something went wrong. A successful return may still involve a
+ zero-length tablen! */
+
+boolean
+_bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen)
+ bfd *abfd;
+ boolean trailing_slash;
+ char **tabloc;
+ bfd_size_type *tablen;
+{
+ unsigned int maxname = abfd->xvec->ar_max_namelen;
+ unsigned int total_namelen = 0;
+ bfd *current;
+ char *strptr;
+
+ *tablen = 0;
+
+ /* Figure out how long the table should be */
+ for (current = abfd->archive_head; current != NULL; current = current->next)
+ {
+ const char *normal;
+ unsigned int thislen;
+
+ normal = normalize (current, current->filename);
+ if (normal == NULL)
+ return false;
+
+ thislen = strlen (normal);
+
+ if (thislen > maxname
+ && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
+ thislen = maxname;
+
+ if (thislen > maxname)
+ {
+ /* Add one to leave room for \n. */
+ total_namelen += thislen + 1;
+ if (trailing_slash)
+ {
+ /* Leave room for trailing slash. */
+ ++total_namelen;
+ }
+ }
+ else
+ {
+ struct ar_hdr *hdr = arch_hdr (current);
+ if (strncmp (normal, hdr->ar_name, thislen) != 0
+ || (thislen < sizeof hdr->ar_name
+ && hdr->ar_name[thislen] != ar_padchar (current)))
+ {
+ /* Must have been using extended format even though it
+ didn't need to. Fix it to use normal format. */
+ memcpy (hdr->ar_name, normal, thislen);
+ if (thislen < maxname
+ || (thislen == maxname && thislen < sizeof hdr->ar_name))
+ hdr->ar_name[thislen] = ar_padchar (current);
+ }
+ }
+ }
+
+ if (total_namelen == 0)
+ return true;
+
+ *tabloc = bfd_zalloc (abfd, total_namelen);
+ if (*tabloc == NULL)
+ return false;
+
+ *tablen = total_namelen;
+ strptr = *tabloc;
+
+ for (current = abfd->archive_head; current != NULL; current =
+ current->next)
+ {
+ const char *normal;
+ unsigned int thislen;
+
+ normal = normalize (current, current->filename);
+ if (normal == NULL)
+ return false;
+
+ thislen = strlen (normal);
+ if (thislen > maxname)
+ {
+ /* Works for now; may need to be re-engineered if we
+ encounter an oddball archive format and want to
+ generalise this hack. */
+ struct ar_hdr *hdr = arch_hdr (current);
+ strcpy (strptr, normal);
+ if (! trailing_slash)
+ strptr[thislen] = '\012';
+ else
+ {
+ strptr[thislen] = '/';
+ strptr[thislen + 1] = '\012';
+ }
+ hdr->ar_name[0] = ar_padchar (current);
+ /* We know there will always be enough room (one of the few
+ cases where you may safely use sprintf). */
+ sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc));
+ /* Kinda Kludgy. We should just use the returned value of
+ sprintf but not all implementations get this right */
+ {
+ char *temp = hdr->ar_name + 2;
+ for (; temp < hdr->ar_name + maxname; temp++)
+ if (*temp == '\0')
+ *temp = ' ';
+ }
+ strptr += thislen + 1;
+ if (trailing_slash)
+ ++strptr;
+ }
+ }
+
+ return true;
+}
+
+/** A couple of functions for creating ar_hdrs */
+
+/* Takes a filename, returns an arelt_data for it, or NULL if it can't
+ make one. The filename must refer to a filename in the filesystem.
+ The filename field of the ar_hdr will NOT be initialized. If member
+ is set, and it's an in-memory bfd, we fake it. */
+
+static struct areltdata *
+bfd_ar_hdr_from_filesystem (abfd, filename, member)
+ bfd *abfd;
+ const char *filename;
+ bfd *member;
+{
+ struct stat status;
+ struct areltdata *ared;
+ struct ar_hdr *hdr;
+ char *temp, *temp1;
+
+ if (member && (member->flags & BFD_IN_MEMORY) != 0)
+ {
+ /* Assume we just "made" the member, and fake it */
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream;
+ time(&status.st_mtime);
+ status.st_uid = getuid();
+ status.st_gid = getgid();
+ status.st_mode = 0644;
+ status.st_size = bim->size;
+ }
+ else if (stat (filename, &status) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ ared = (struct areltdata *) bfd_zalloc (abfd, sizeof (struct ar_hdr) +
+ sizeof (struct areltdata));
+ if (ared == NULL)
+ return NULL;
+ hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
+
+ /* ar headers are space padded, not null padded! */
+ memset ((PTR) hdr, ' ', sizeof (struct ar_hdr));
+
+ strncpy (hdr->ar_fmag, ARFMAG, 2);
+
+ /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
+ sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime);
+ sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid);
+ sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid);
+ sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode);
+ sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size);
+ /* Correct for a lossage in sprintf whereby it null-terminates. I cannot
+ understand how these C losers could design such a ramshackle bunch of
+ IO operations */
+ temp = (char *) hdr;
+ temp1 = temp + sizeof (struct ar_hdr) - 2;
+ for (; temp < temp1; temp++)
+ {
+ if (*temp == '\0')
+ *temp = ' ';
+ }
+ strncpy (hdr->ar_fmag, ARFMAG, 2);
+ ared->parsed_size = status.st_size;
+ ared->arch_header = (char *) hdr;
+
+ return ared;
+}
+
+/* This is magic required by the "ar" program. Since it's
+ undocumented, it's undocumented. You may think that it would take
+ a strong stomach to write this, and it does, but it takes even a
+ stronger stomach to try to code around such a thing! */
+
+struct ar_hdr *bfd_special_undocumented_glue PARAMS ((bfd *, const char *));
+
+struct ar_hdr *
+bfd_special_undocumented_glue (abfd, filename)
+ bfd *abfd;
+ const char *filename;
+{
+ struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename, 0);
+ if (ar_elt == NULL)
+ return NULL;
+ return (struct ar_hdr *) ar_elt->arch_header;
+}
+
+
+/* Analogous to stat call */
+int
+bfd_generic_stat_arch_elt (abfd, buf)
+ bfd *abfd;
+ struct stat *buf;
+{
+ struct ar_hdr *hdr;
+ char *aloser;
+
+ if (abfd->arelt_data == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ hdr = arch_hdr (abfd);
+
+#define foo(arelt, stelt, size) \
+ buf->stelt = strtol (hdr->arelt, &aloser, size); \
+ if (aloser == hdr->arelt) return -1;
+
+ foo (ar_date, st_mtime, 10);
+ foo (ar_uid, st_uid, 10);
+ foo (ar_gid, st_gid, 10);
+ foo (ar_mode, st_mode, 8);
+
+ buf->st_size = arch_eltdata (abfd)->parsed_size;
+
+ return 0;
+}
+
+void
+bfd_dont_truncate_arname (abfd, pathname, arhdr)
+ bfd *abfd;
+ CONST char *pathname;
+ char *arhdr;
+{
+ /* FIXME: This interacts unpleasantly with ar's quick-append option.
+ Fortunately ic960 users will never use that option. Fixing this
+ is very hard; fortunately I know how to do it and will do so once
+ intel's release is out the door. */
+
+ struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
+ size_t length;
+ const char *filename;
+ size_t maxlen = ar_maxnamelen (abfd);
+
+ if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
+ {
+ bfd_bsd_truncate_arname (abfd, pathname, arhdr);
+ return;
+ }
+
+ filename = normalize (abfd, pathname);
+ if (filename == NULL)
+ {
+ /* FIXME */
+ abort ();
+ }
+
+ length = strlen (filename);
+
+ if (length <= maxlen)
+ memcpy (hdr->ar_name, filename, length);
+
+ /* Add the padding character if there is room for it. */
+ if (length < maxlen
+ || (length == maxlen && length < sizeof hdr->ar_name))
+ (hdr->ar_name)[length] = ar_padchar (abfd);
+}
+
+void
+bfd_bsd_truncate_arname (abfd, pathname, arhdr)
+ bfd *abfd;
+ CONST char *pathname;
+ char *arhdr;
+{
+ struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
+ int length;
+ CONST char *filename = strrchr (pathname, '/');
+ int maxlen = ar_maxnamelen (abfd);
+
+ if (filename == NULL)
+ filename = pathname;
+ else
+ ++filename;
+
+ length = strlen (filename);
+
+ if (length <= maxlen)
+ memcpy (hdr->ar_name, filename, length);
+ else
+ {
+ /* pathname: meet procrustes */
+ memcpy (hdr->ar_name, filename, maxlen);
+ length = maxlen;
+ }
+
+ if (length < maxlen)
+ (hdr->ar_name)[length] = ar_padchar (abfd);
+}
+
+/* Store name into ar header. Truncates the name to fit.
+ 1> strip pathname to be just the basename.
+ 2> if it's short enuf to fit, stuff it in.
+ 3> If it doesn't end with .o, truncate it to fit
+ 4> truncate it before the .o, append .o, stuff THAT in. */
+
+/* This is what gnu ar does. It's better but incompatible with the
+ bsd ar. */
+
+void
+bfd_gnu_truncate_arname (abfd, pathname, arhdr)
+ bfd *abfd;
+ CONST char *pathname;
+ char *arhdr;
+{
+ struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
+ int length;
+ CONST char *filename = strrchr (pathname, '/');
+ int maxlen = ar_maxnamelen (abfd);
+
+ if (filename == NULL)
+ filename = pathname;
+ else
+ ++filename;
+
+ length = strlen (filename);
+
+ if (length <= maxlen)
+ memcpy (hdr->ar_name, filename, length);
+ else
+ { /* pathname: meet procrustes */
+ memcpy (hdr->ar_name, filename, maxlen);
+ if ((filename[length - 2] == '.') && (filename[length - 1] == 'o'))
+ {
+ hdr->ar_name[maxlen - 2] = '.';
+ hdr->ar_name[maxlen - 1] = 'o';
+ }
+ length = maxlen;
+ }
+
+ if (length < 16)
+ (hdr->ar_name)[length] = ar_padchar (abfd);
+}
+
+/* The BFD is open for write and has its format set to bfd_archive */
+
+boolean
+_bfd_write_archive_contents (arch)
+ bfd *arch;
+{
+ bfd *current;
+ char *etable = NULL;
+ bfd_size_type elength = 0;
+ const char *ename = NULL;
+ boolean makemap = bfd_has_map (arch);
+ boolean hasobjects = false; /* if no .o's, don't bother to make a map */
+ bfd_size_type wrote;
+ unsigned int i;
+ int tries;
+
+ /* Verify the viability of all entries; if any of them live in the
+ filesystem (as opposed to living in an archive open for input)
+ then construct a fresh ar_hdr for them. */
+ for (current = arch->archive_head; current; current = current->next)
+ {
+ if (bfd_write_p (current))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+ if (!current->arelt_data)
+ {
+ current->arelt_data =
+ (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename, current);
+ if (!current->arelt_data)
+ return false;
+
+ /* Put in the file name */
+ BFD_SEND (arch, _bfd_truncate_arname, (arch,
+ current->filename,
+ (char *) arch_hdr (current)));
+ }
+
+ if (makemap && ! hasobjects)
+ { /* don't bother if we won't make a map! */
+ if ((bfd_check_format (current, bfd_object))
+#if 0 /* FIXME -- these are not set correctly */
+ && ((bfd_get_file_flags (current) & HAS_SYMS))
+#endif
+ )
+ hasobjects = true;
+ }
+ }
+
+ if (!BFD_SEND (arch, _bfd_construct_extended_name_table,
+ (arch, &etable, &elength, &ename)))
+ return false;
+
+ if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+#ifdef GNU960
+ wrote = bfd_write (BFD_GNU960_ARMAG (arch), 1, SARMAG, arch);
+#else
+ wrote = bfd_write (ARMAG, 1, SARMAG, arch);
+#endif
+ if (wrote != SARMAG)
+ return false;
+
+ if (makemap && hasobjects)
+ {
+ if (_bfd_compute_and_write_armap (arch, elength) != true)
+ return false;
+ }
+
+ if (elength != 0)
+ {
+ struct ar_hdr hdr;
+
+ memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
+ strcpy (hdr.ar_name, ename);
+ /* Round size up to even number in archive header. */
+ sprintf (&(hdr.ar_size[0]), "%-10d",
+ (int) ((elength + 1) & ~1));
+ strncpy (hdr.ar_fmag, ARFMAG, 2);
+ for (i = 0; i < sizeof (struct ar_hdr); i++)
+ if (((char *) (&hdr))[i] == '\0')
+ (((char *) (&hdr))[i]) = ' ';
+ if ((bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ || bfd_write (etable, 1, elength, arch) != elength)
+ return false;
+ if ((elength % 2) == 1)
+ {
+ if (bfd_write ("\012", 1, 1, arch) != 1)
+ return false;
+ }
+ }
+
+ for (current = arch->archive_head; current; current = current->next)
+ {
+ char buffer[DEFAULT_BUFFERSIZE];
+ unsigned int remaining = arelt_size (current);
+ struct ar_hdr *hdr = arch_hdr (current);
+
+ /* write ar header */
+ if (bfd_write ((char *) hdr, 1, sizeof (*hdr), arch) != sizeof (*hdr))
+ return false;
+ if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+ while (remaining)
+ {
+ unsigned int amt = DEFAULT_BUFFERSIZE;
+ if (amt > remaining)
+ amt = remaining;
+ errno = 0;
+ if (bfd_read (buffer, amt, 1, current) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
+ }
+ if (bfd_write (buffer, amt, 1, arch) != amt)
+ return false;
+ remaining -= amt;
+ }
+ if ((arelt_size (current) % 2) == 1)
+ {
+ if (bfd_write ("\012", 1, 1, arch) != 1)
+ return false;
+ }
+ }
+
+ if (makemap && hasobjects)
+ {
+ /* Verify the timestamp in the archive file. If it would not be
+ accepted by the linker, rewrite it until it would be. If
+ anything odd happens, break out and just return. (The
+ Berkeley linker checks the timestamp and refuses to read the
+ table-of-contents if it is >60 seconds less than the file's
+ modified-time. That painful hack requires this painful hack. */
+ tries = 1;
+ do
+ {
+ if (bfd_update_armap_timestamp (arch))
+ break;
+ (*_bfd_error_handler)
+ (_("Warning: writing archive was slow: rewriting timestamp\n"));
+ }
+ while (++tries < 6);
+ }
+
+ return true;
+}
+
+/* Note that the namidx for the first symbol is 0 */
+
+boolean
+_bfd_compute_and_write_armap (arch, elength)
+ bfd *arch;
+ unsigned int elength;
+{
+ char *first_name = NULL;
+ bfd *current;
+ file_ptr elt_no = 0;
+ struct orl *map = NULL;
+ int orl_max = 1024; /* fine initial default */
+ int orl_count = 0;
+ int stridx = 0; /* string index */
+ asymbol **syms = NULL;
+ long syms_max = 0;
+ boolean ret;
+
+ /* Dunno if this is the best place for this info... */
+ if (elength != 0)
+ elength += sizeof (struct ar_hdr);
+ elength += elength % 2;
+
+ map = (struct orl *) bfd_malloc (orl_max * sizeof (struct orl));
+ if (map == NULL)
+ goto error_return;
+
+ /* We put the symbol names on the arch objalloc, and then discard
+ them when done. */
+ first_name = bfd_alloc (arch, 1);
+ if (first_name == NULL)
+ goto error_return;
+
+ /* Drop all the files called __.SYMDEF, we're going to make our
+ own */
+ while (arch->archive_head &&
+ strcmp (arch->archive_head->filename, "__.SYMDEF") == 0)
+ arch->archive_head = arch->archive_head->next;
+
+ /* Map over each element */
+ for (current = arch->archive_head;
+ current != (bfd *) NULL;
+ current = current->next, elt_no++)
+ {
+ if ((bfd_check_format (current, bfd_object) == true)
+ && ((bfd_get_file_flags (current) & HAS_SYMS)))
+ {
+ long storage;
+ long symcount;
+ long src_count;
+
+ storage = bfd_get_symtab_upper_bound (current);
+ if (storage < 0)
+ goto error_return;
+
+ if (storage != 0)
+ {
+ if (storage > syms_max)
+ {
+ if (syms_max > 0)
+ free (syms);
+ syms_max = storage;
+ syms = (asymbol **) bfd_malloc ((size_t) syms_max);
+ if (syms == NULL)
+ goto error_return;
+ }
+ symcount = bfd_canonicalize_symtab (current, syms);
+ if (symcount < 0)
+ goto error_return;
+
+ /* Now map over all the symbols, picking out the ones we want */
+ for (src_count = 0; src_count < symcount; src_count++)
+ {
+ flagword flags = (syms[src_count])->flags;
+ asection *sec = syms[src_count]->section;
+
+ if ((flags & BSF_GLOBAL ||
+ flags & BSF_WEAK ||
+ flags & BSF_INDIRECT ||
+ bfd_is_com_section (sec))
+ && ! bfd_is_und_section (sec))
+ {
+ size_t namelen;
+ struct orl *new_map;
+
+ /* This symbol will go into the archive header */
+ if (orl_count == orl_max)
+ {
+ orl_max *= 2;
+ new_map =
+ ((struct orl *)
+ bfd_realloc (map, orl_max * sizeof (struct orl)));
+ if (new_map == (struct orl *) NULL)
+ goto error_return;
+
+ map = new_map;
+ }
+
+ namelen = strlen (syms[src_count]->name);
+ map[orl_count].name = ((char **)
+ bfd_alloc (arch,
+ sizeof (char *)));
+ if (map[orl_count].name == NULL)
+ goto error_return;
+ *(map[orl_count].name) = bfd_alloc (arch, namelen + 1);
+ if (*(map[orl_count].name) == NULL)
+ goto error_return;
+ strcpy (*(map[orl_count].name), syms[src_count]->name);
+ (map[orl_count]).pos = (file_ptr) current;
+ (map[orl_count]).namidx = stridx;
+
+ stridx += namelen + 1;
+ ++orl_count;
+ }
+ }
+ }
+
+ /* Now ask the BFD to free up any cached information, so we
+ don't fill all of memory with symbol tables. */
+ if (! bfd_free_cached_info (current))
+ goto error_return;
+ }
+ }
+
+ /* OK, now we have collected all the data, let's write them out */
+ ret = BFD_SEND (arch, write_armap,
+ (arch, elength, map, orl_count, stridx));
+
+ if (syms_max > 0)
+ free (syms);
+ if (map != NULL)
+ free (map);
+ if (first_name != NULL)
+ bfd_release (arch, first_name);
+
+ return ret;
+
+ error_return:
+ if (syms_max > 0)
+ free (syms);
+ if (map != NULL)
+ free (map);
+ if (first_name != NULL)
+ bfd_release (arch, first_name);
+
+ return false;
+}
+
+boolean
+bsd_write_armap (arch, elength, map, orl_count, stridx)
+ bfd *arch;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int orl_count;
+ int stridx;
+{
+ int padit = stridx & 1;
+ unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE;
+ unsigned int stringsize = stridx + padit;
+ /* Include 8 bytes to store ranlibsize and stringsize in output. */
+ unsigned int mapsize = ranlibsize + stringsize + 8;
+ file_ptr firstreal;
+ bfd *current = arch->archive_head;
+ bfd *last_elt = current; /* last element arch seen */
+ bfd_byte temp[4];
+ unsigned int count;
+ struct ar_hdr hdr;
+ struct stat statbuf;
+ unsigned int i;
+
+ firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
+
+ stat (arch->filename, &statbuf);
+ memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
+ sprintf (hdr.ar_name, RANLIBMAG);
+ /* Remember the timestamp, to keep it holy. But fudge it a little. */
+ bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET;
+ bfd_ardata (arch)->armap_datepos = (SARMAG
+ + offsetof (struct ar_hdr, ar_date[0]));
+ sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
+#ifndef _WIN32
+ sprintf (hdr.ar_uid, "%ld", (long) getuid ());
+ sprintf (hdr.ar_gid, "%ld", (long) getgid ());
+#else
+ sprintf (hdr.ar_uid, "%ld", (long) 666);
+ sprintf (hdr.ar_gid, "%ld", (long) 42);
+#endif
+ sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+ strncpy (hdr.ar_fmag, ARFMAG, 2);
+ for (i = 0; i < sizeof (struct ar_hdr); i++)
+ if (((char *) (&hdr))[i] == '\0')
+ (((char *) (&hdr))[i]) = ' ';
+ if (bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ return false;
+ bfd_h_put_32 (arch, (bfd_vma) ranlibsize, temp);
+ if (bfd_write (temp, 1, sizeof (temp), arch) != sizeof (temp))
+ return false;
+
+ for (count = 0; count < orl_count; count++)
+ {
+ bfd_byte buf[BSD_SYMDEF_SIZE];
+
+ if (((bfd *) (map[count]).pos) != last_elt)
+ {
+ do
+ {
+ firstreal += arelt_size (current) + sizeof (struct ar_hdr);
+ firstreal += firstreal % 2;
+ current = current->next;
+ }
+ while (current != (bfd *) (map[count]).pos);
+ } /* if new archive element */
+
+ last_elt = current;
+ bfd_h_put_32 (arch, map[count].namidx, buf);
+ bfd_h_put_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
+ if (bfd_write (buf, BSD_SYMDEF_SIZE, 1, arch) != BSD_SYMDEF_SIZE)
+ return false;
+ }
+
+ /* now write the strings themselves */
+ bfd_h_put_32 (arch, stringsize, temp);
+ if (bfd_write (temp, 1, sizeof (temp), arch) != sizeof (temp))
+ return false;
+ for (count = 0; count < orl_count; count++)
+ {
+ size_t len = strlen (*map[count].name) + 1;
+
+ if (bfd_write (*map[count].name, 1, len, arch) != len)
+ return false;
+ }
+
+ /* The spec sez this should be a newline. But in order to be
+ bug-compatible for sun's ar we use a null. */
+ if (padit)
+ {
+ if (bfd_write ("", 1, 1, arch) != 1)
+ return false;
+ }
+
+ return true;
+}
+
+/* At the end of archive file handling, update the timestamp in the
+ file, so the linker will accept it.
+
+ Return true if the timestamp was OK, or an unusual problem happened.
+ Return false if we updated the timestamp. */
+
+boolean
+_bfd_archive_bsd_update_armap_timestamp (arch)
+ bfd *arch;
+{
+ struct stat archstat;
+ struct ar_hdr hdr;
+ unsigned int i;
+
+ /* Flush writes, get last-write timestamp from file, and compare it
+ to the timestamp IN the file. */
+ bfd_flush (arch);
+ if (bfd_stat (arch, &archstat) == -1)
+ {
+ perror (_("Reading archive file mod timestamp"));
+ return true; /* Can't read mod time for some reason */
+ }
+ if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp)
+ return true; /* OK by the linker's rules */
+
+ /* Update the timestamp. */
+ bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;
+
+ /* Prepare an ASCII version suitable for writing. */
+ memset (hdr.ar_date, 0, sizeof (hdr.ar_date));
+ sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
+ for (i = 0; i < sizeof (hdr.ar_date); i++)
+ if (hdr.ar_date[i] == '\0')
+ (hdr.ar_date)[i] = ' ';
+
+ /* Write it into the file. */
+ bfd_ardata (arch)->armap_datepos = (SARMAG
+ + offsetof (struct ar_hdr, ar_date[0]));
+ if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0
+ || (bfd_write (hdr.ar_date, sizeof (hdr.ar_date), 1, arch)
+ != sizeof (hdr.ar_date)))
+ {
+ /* FIXME: bfd can't call perror. */
+ perror (_("Writing updated armap timestamp"));
+ return true; /* Some error while writing */
+ }
+
+ return false; /* We updated the timestamp successfully. */
+}
+
+/* A coff armap looks like :
+ lARMAG
+ struct ar_hdr with name = '/'
+ number of symbols
+ offset of file for symbol 0
+ offset of file for symbol 1
+
+ offset of file for symbol n-1
+ symbol name 0
+ symbol name 1
+
+ symbol name n-1
+*/
+
+boolean
+coff_write_armap (arch, elength, map, symbol_count, stridx)
+ bfd *arch;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int symbol_count;
+ int stridx;
+{
+ /* The size of the ranlib is the number of exported symbols in the
+ archive * the number of bytes in a int, + an int for the count */
+ unsigned int ranlibsize = (symbol_count * 4) + 4;
+ unsigned int stringsize = stridx;
+ unsigned int mapsize = stringsize + ranlibsize;
+ file_ptr archive_member_file_ptr;
+ bfd *current = arch->archive_head;
+ unsigned int count;
+ struct ar_hdr hdr;
+ unsigned int i;
+ int padit = mapsize & 1;
+
+ if (padit)
+ mapsize++;
+
+ /* work out where the first object file will go in the archive */
+ archive_member_file_ptr = (mapsize
+ + elength
+ + sizeof (struct ar_hdr)
+ + SARMAG);
+
+ memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
+ hdr.ar_name[0] = '/';
+ sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+ sprintf (hdr.ar_date, "%ld", (long) time (NULL));
+ /* This, at least, is what Intel coff sets the values to.: */
+ sprintf ((hdr.ar_uid), "%d", 0);
+ sprintf ((hdr.ar_gid), "%d", 0);
+ sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
+ strncpy (hdr.ar_fmag, ARFMAG, 2);
+
+ for (i = 0; i < sizeof (struct ar_hdr); i++)
+ if (((char *) (&hdr))[i] == '\0')
+ (((char *) (&hdr))[i]) = ' ';
+
+ /* Write the ar header for this item and the number of symbols */
+
+ if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ return false;
+
+ bfd_write_bigendian_4byte_int (arch, symbol_count);
+
+ /* Two passes, first write the file offsets for each symbol -
+ remembering that each offset is on a two byte boundary. */
+
+ /* Write out the file offset for the file associated with each
+ symbol, and remember to keep the offsets padded out. */
+
+ current = arch->archive_head;
+ count = 0;
+ while (current != (bfd *) NULL && count < symbol_count)
+ {
+ /* For each symbol which is used defined in this object, write out
+ the object file's address in the archive */
+
+ while (((bfd *) (map[count]).pos) == current)
+ {
+ bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr);
+ count++;
+ }
+ /* Add size of this archive entry */
+ archive_member_file_ptr += (arelt_size (current)
+ + sizeof (struct ar_hdr));
+ /* remember aboout the even alignment */
+ archive_member_file_ptr += archive_member_file_ptr % 2;
+ current = current->next;
+ }
+
+ /* now write the strings themselves */
+ for (count = 0; count < symbol_count; count++)
+ {
+ size_t len = strlen (*map[count].name) + 1;
+
+ if (bfd_write (*map[count].name, 1, len, arch) != len)
+ return false;
+ }
+
+ /* The spec sez this should be a newline. But in order to be
+ bug-compatible for arc960 we use a null. */
+ if (padit)
+ {
+ if (bfd_write ("", 1, 1, arch) != 1)
+ return false;
+ }
+
+ return true;
+}
diff --git a/bfd/archures.c b/bfd/archures.c
new file mode 100644
index 00000000000..f2438623364
--- /dev/null
+++ b/bfd/archures.c
@@ -0,0 +1,896 @@
+/* BFD library support routines for architectures.
+ Copyright (C) 1990, 91-98, 1999 Free Software Foundation, Inc.
+ Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include <ctype.h>
+
+/*
+
+SECTION
+ Architectures
+
+ BFD keeps one atom in a BFD describing the
+ architecture of the data attached to the BFD: a pointer to a
+ <<bfd_arch_info_type>>.
+
+ Pointers to structures can be requested independently of a BFD
+ so that an architecture's information can be interrogated
+ without access to an open BFD.
+
+ The architecture information is provided by each architecture package.
+ The set of default architectures is selected by the macro
+ <<SELECT_ARCHITECTURES>>. This is normally set up in the
+ @file{config/@var{target}.mt} file of your choice. If the name is not
+ defined, then all the architectures supported are included.
+
+ When BFD starts up, all the architectures are called with an
+ initialize method. It is up to the architecture back end to
+ insert as many items into the list of architectures as it wants to;
+ generally this would be one for each machine and one for the
+ default case (an item with a machine field of 0).
+
+ BFD's idea of an architecture is implemented in @file{archures.c}.
+*/
+
+/*
+
+SUBSECTION
+ bfd_architecture
+
+DESCRIPTION
+ This enum gives the object file's CPU architecture, in a
+ global sense---i.e., what processor family does it belong to?
+ Another field indicates which processor within
+ the family is in use. The machine gives a number which
+ distinguishes different versions of the architecture,
+ containing, for example, 2 and 3 for Intel i960 KA and i960 KB,
+ and 68020 and 68030 for Motorola 68020 and 68030.
+
+.enum bfd_architecture
+.{
+. bfd_arch_unknown, {* File arch not known *}
+. bfd_arch_obscure, {* Arch known, not one of these *}
+. bfd_arch_m68k, {* Motorola 68xxx *}
+.#define bfd_mach_m68000 1
+.#define bfd_mach_m68008 2
+.#define bfd_mach_m68010 3
+.#define bfd_mach_m68020 4
+.#define bfd_mach_m68030 5
+.#define bfd_mach_m68040 6
+.#define bfd_mach_m68060 7
+.#define bfd_mach_cpu32 8
+. bfd_arch_vax, {* DEC Vax *}
+. bfd_arch_i960, {* Intel 960 *}
+. {* The order of the following is important.
+. lower number indicates a machine type that
+. only accepts a subset of the instructions
+. available to machines with higher numbers.
+. The exception is the "ca", which is
+. incompatible with all other machines except
+. "core". *}
+.
+.#define bfd_mach_i960_core 1
+.#define bfd_mach_i960_ka_sa 2
+.#define bfd_mach_i960_kb_sb 3
+.#define bfd_mach_i960_mc 4
+.#define bfd_mach_i960_xa 5
+.#define bfd_mach_i960_ca 6
+.#define bfd_mach_i960_jx 7
+.#define bfd_mach_i960_hx 8
+.
+. bfd_arch_a29k, {* AMD 29000 *}
+. bfd_arch_sparc, {* SPARC *}
+.#define bfd_mach_sparc 1
+.{* The difference between v8plus and v9 is that v9 is a true 64 bit env. *}
+.#define bfd_mach_sparc_sparclet 2
+.#define bfd_mach_sparc_sparclite 3
+.#define bfd_mach_sparc_v8plus 4
+.#define bfd_mach_sparc_v8plusa 5 {* with ultrasparc add'ns *}
+.#define bfd_mach_sparc_sparclite_le 6
+.#define bfd_mach_sparc_v9 7
+.#define bfd_mach_sparc_v9a 8 {* with ultrasparc add'ns *}
+.{* Nonzero if MACH has the v9 instruction set. *}
+.#define bfd_mach_sparc_v9_p(mach) \
+. ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9a)
+. bfd_arch_mips, {* MIPS Rxxxx *}
+.#define bfd_mach_mips3000 3000
+.#define bfd_mach_mips3900 3900
+.#define bfd_mach_mips4000 4000
+.#define bfd_mach_mips4010 4010
+.#define bfd_mach_mips4100 4100
+.#define bfd_mach_mips4111 4111
+.#define bfd_mach_mips4300 4300
+.#define bfd_mach_mips4400 4400
+.#define bfd_mach_mips4600 4600
+.#define bfd_mach_mips4650 4650
+.#define bfd_mach_mips5000 5000
+.#define bfd_mach_mips6000 6000
+.#define bfd_mach_mips8000 8000
+.#define bfd_mach_mips10000 10000
+.#define bfd_mach_mips16 16
+. bfd_arch_i386, {* Intel 386 *}
+.#define bfd_mach_i386_i386 0
+.#define bfd_mach_i386_i8086 1
+.#define bfd_mach_i386_i386_intel_syntax 2
+. bfd_arch_we32k, {* AT&T WE32xxx *}
+. bfd_arch_tahoe, {* CCI/Harris Tahoe *}
+. bfd_arch_i860, {* Intel 860 *}
+. bfd_arch_romp, {* IBM ROMP PC/RT *}
+. bfd_arch_alliant, {* Alliant *}
+. bfd_arch_convex, {* Convex *}
+. bfd_arch_m88k, {* Motorola 88xxx *}
+. bfd_arch_pyramid, {* Pyramid Technology *}
+. bfd_arch_h8300, {* Hitachi H8/300 *}
+.#define bfd_mach_h8300 1
+.#define bfd_mach_h8300h 2
+.#define bfd_mach_h8300s 3
+. bfd_arch_powerpc, {* PowerPC *}
+. bfd_arch_rs6000, {* IBM RS/6000 *}
+. bfd_arch_hppa, {* HP PA RISC *}
+. bfd_arch_d10v, {* Mitsubishi D10V *}
+. bfd_arch_d30v, {* Mitsubishi D30V *}
+. bfd_arch_z8k, {* Zilog Z8000 *}
+.#define bfd_mach_z8001 1
+.#define bfd_mach_z8002 2
+. bfd_arch_h8500, {* Hitachi H8/500 *}
+. bfd_arch_sh, {* Hitachi SH *}
+.#define bfd_mach_sh 0
+.#define bfd_mach_sh3 0x30
+.#define bfd_mach_sh3e 0x3e
+. bfd_arch_alpha, {* Dec Alpha *}
+.#define bfd_mach_alpha_ev4 0x10
+.#define bfd_mach_alpha_ev5 0x20
+.#define bfd_mach_alpha_ev6 0x30
+. bfd_arch_arm, {* Advanced Risc Machines ARM *}
+.#define bfd_mach_arm_2 1
+.#define bfd_mach_arm_2a 2
+.#define bfd_mach_arm_3 3
+.#define bfd_mach_arm_3M 4
+.#define bfd_mach_arm_4 5
+.#define bfd_mach_arm_4T 6
+. bfd_arch_ns32k, {* National Semiconductors ns32000 *}
+. bfd_arch_w65, {* WDC 65816 *}
+. bfd_arch_tic30, {* Texas Instruments TMS320C30 *}
+. bfd_arch_tic80, {* TI TMS320c80 (MVP) *}
+. bfd_arch_v850, {* NEC V850 *}
+.#define bfd_mach_v850 0
+.#define bfd_mach_v850e 'E'
+.#define bfd_mach_v850ea 'A'
+. bfd_arch_arc, {* Argonaut RISC Core *}
+.#define bfd_mach_arc_base 0
+. bfd_arch_m32r, {* Mitsubishi M32R/D *}
+.#define bfd_mach_m32r 0 {* backwards compatibility *}
+. bfd_arch_mn10200, {* Matsushita MN10200 *}
+. bfd_arch_mn10300, {* Matsushita MN10300 *}
+.#define bfd_mach_mn10300 300
+. bfd_arch_fr30,
+.#define bfd_mach_fr30 0x46523330
+. bfd_arch_mcore,
+. bfd_arch_last
+. };
+
+
+*/
+
+/*
+
+SUBSECTION
+ bfd_arch_info
+
+DESCRIPTION
+ This structure contains information on architectures for use
+ within BFD.
+
+.
+.typedef struct bfd_arch_info
+.{
+. int bits_per_word;
+. int bits_per_address;
+. int bits_per_byte;
+. enum bfd_architecture arch;
+. unsigned long mach;
+. const char *arch_name;
+. const char *printable_name;
+. unsigned int section_align_power;
+. {* true if this is the default machine for the architecture *}
+. boolean the_default;
+. const struct bfd_arch_info * (*compatible)
+. PARAMS ((const struct bfd_arch_info *a,
+. const struct bfd_arch_info *b));
+.
+. boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *));
+.
+. const struct bfd_arch_info *next;
+.} bfd_arch_info_type;
+*/
+
+extern const bfd_arch_info_type bfd_a29k_arch;
+extern const bfd_arch_info_type bfd_alpha_arch;
+extern const bfd_arch_info_type bfd_arc_arch;
+extern const bfd_arch_info_type bfd_arm_arch;
+extern const bfd_arch_info_type bfd_d10v_arch;
+extern const bfd_arch_info_type bfd_d30v_arch;
+extern const bfd_arch_info_type bfd_h8300_arch;
+extern const bfd_arch_info_type bfd_h8500_arch;
+extern const bfd_arch_info_type bfd_hppa_arch;
+extern const bfd_arch_info_type bfd_i386_arch;
+extern const bfd_arch_info_type bfd_i860_arch;
+extern const bfd_arch_info_type bfd_i960_arch;
+extern const bfd_arch_info_type bfd_m32r_arch;
+extern const bfd_arch_info_type bfd_m68k_arch;
+extern const bfd_arch_info_type bfd_m88k_arch;
+extern const bfd_arch_info_type bfd_mips_arch;
+extern const bfd_arch_info_type bfd_mn10200_arch;
+extern const bfd_arch_info_type bfd_mn10300_arch;
+extern const bfd_arch_info_type bfd_powerpc_arch;
+extern const bfd_arch_info_type bfd_rs6000_arch;
+extern const bfd_arch_info_type bfd_sh_arch;
+extern const bfd_arch_info_type bfd_sparc_arch;
+extern const bfd_arch_info_type bfd_tic30_arch;
+extern const bfd_arch_info_type bfd_tic80_arch;
+extern const bfd_arch_info_type bfd_vax_arch;
+extern const bfd_arch_info_type bfd_we32k_arch;
+extern const bfd_arch_info_type bfd_z8k_arch;
+extern const bfd_arch_info_type bfd_ns32k_arch;
+extern const bfd_arch_info_type bfd_w65_arch;
+extern const bfd_arch_info_type bfd_v850_arch;
+extern const bfd_arch_info_type bfd_fr30_arch;
+extern const bfd_arch_info_type bfd_mcore_arch;
+
+static const bfd_arch_info_type * const bfd_archures_list[] =
+{
+#ifdef SELECT_ARCHITECTURES
+ SELECT_ARCHITECTURES,
+#else
+ &bfd_a29k_arch,
+ &bfd_alpha_arch,
+ &bfd_arc_arch,
+ &bfd_arm_arch,
+ &bfd_d10v_arch,
+ &bfd_d30v_arch,
+ &bfd_h8300_arch,
+ &bfd_h8500_arch,
+ &bfd_hppa_arch,
+ &bfd_i386_arch,
+ &bfd_i860_arch,
+ &bfd_i960_arch,
+ &bfd_m32r_arch,
+ &bfd_m68k_arch,
+ &bfd_m88k_arch,
+ &bfd_mips_arch,
+ &bfd_mn10200_arch,
+ &bfd_mn10300_arch,
+ &bfd_powerpc_arch,
+ &bfd_rs6000_arch,
+ &bfd_sh_arch,
+ &bfd_sparc_arch,
+ &bfd_tic30_arch,
+ &bfd_tic80_arch,
+ &bfd_vax_arch,
+ &bfd_we32k_arch,
+ &bfd_z8k_arch,
+ &bfd_ns32k_arch,
+ &bfd_w65_arch,
+ &bfd_v850_arch,
+ &bfd_fr30_arch,
+ & bfd_mcore_arch,
+#endif
+ 0
+};
+
+/*
+FUNCTION
+ bfd_printable_name
+
+SYNOPSIS
+ const char *bfd_printable_name(bfd *abfd);
+
+DESCRIPTION
+ Return a printable string representing the architecture and machine
+ from the pointer to the architecture info structure.
+
+*/
+
+const char *
+bfd_printable_name (abfd)
+ bfd *abfd;
+{
+ return abfd->arch_info->printable_name;
+}
+
+
+
+/*
+FUNCTION
+ bfd_scan_arch
+
+SYNOPSIS
+ const bfd_arch_info_type *bfd_scan_arch(const char *string);
+
+DESCRIPTION
+ Figure out if BFD supports any cpu which could be described with
+ the name @var{string}. Return a pointer to an <<arch_info>>
+ structure if a machine is found, otherwise NULL.
+
+*/
+
+const bfd_arch_info_type *
+bfd_scan_arch (string)
+ const char *string;
+{
+ const bfd_arch_info_type * const *app, *ap;
+
+ /* Look through all the installed architectures */
+ for (app = bfd_archures_list; *app != NULL; app++)
+ {
+ for (ap = *app; ap != NULL; ap = ap->next)
+ {
+ if (ap->scan (ap, string))
+ return ap;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+/*
+FUNCTION
+ bfd_arch_list
+
+SYNOPSIS
+ const char **bfd_arch_list(void);
+
+DESCRIPTION
+ Return a freshly malloced NULL-terminated vector of the names
+ of all the valid BFD architectures. Do not modify the names.
+
+*/
+
+const char **
+bfd_arch_list ()
+{
+ int vec_length = 0;
+ const char **name_ptr;
+ const char **name_list;
+ const bfd_arch_info_type * const *app;
+
+ /* Determine the number of architectures */
+ vec_length = 0;
+ for (app = bfd_archures_list; *app != NULL; app++)
+ {
+ const bfd_arch_info_type *ap;
+ for (ap = *app; ap != NULL; ap = ap->next)
+ {
+ vec_length++;
+ }
+ }
+
+ name_list = (CONST char **)
+ bfd_malloc ((vec_length + 1) * sizeof (char **));
+ if (name_list == NULL)
+ return NULL;
+
+ /* Point the list at each of the names */
+ name_ptr = name_list;
+ for (app = bfd_archures_list; *app != NULL; app++)
+ {
+ const bfd_arch_info_type *ap;
+ for (ap = *app; ap != NULL; ap = ap->next)
+ {
+ *name_ptr = ap->printable_name;
+ name_ptr++;
+ }
+ }
+ *name_ptr = NULL;
+
+ return name_list;
+}
+
+
+
+/*
+FUNCTION
+ bfd_arch_get_compatible
+
+SYNOPSIS
+ const bfd_arch_info_type *bfd_arch_get_compatible(
+ const bfd *abfd,
+ const bfd *bbfd);
+
+DESCRIPTION
+ Determine whether two BFDs'
+ architectures and machine types are compatible. Calculates
+ the lowest common denominator between the two architectures
+ and machine types implied by the BFDs and returns a pointer to
+ an <<arch_info>> structure describing the compatible machine.
+*/
+
+const bfd_arch_info_type *
+bfd_arch_get_compatible (abfd, bbfd)
+ const bfd *abfd;
+ const bfd *bbfd;
+{
+ /* If either architecture is unknown, then all we can do is assume
+ the user knows what he's doing. */
+ if (abfd->arch_info->arch == bfd_arch_unknown)
+ return bbfd->arch_info;
+ if (bbfd->arch_info->arch == bfd_arch_unknown)
+ return abfd->arch_info;
+
+ /* Otherwise architecture-specific code has to decide. */
+ return abfd->arch_info->compatible (abfd->arch_info, bbfd->arch_info);
+}
+
+
+/*
+INTERNAL_DEFINITION
+ bfd_default_arch_struct
+
+DESCRIPTION
+ The <<bfd_default_arch_struct>> is an item of
+ <<bfd_arch_info_type>> which has been initialized to a fairly
+ generic state. A BFD starts life by pointing to this
+ structure, until the correct back end has determined the real
+ architecture of the file.
+
+.extern const bfd_arch_info_type bfd_default_arch_struct;
+
+*/
+
+const bfd_arch_info_type bfd_default_arch_struct =
+{
+ 32,32,8,bfd_arch_unknown,0,"unknown","unknown",2,true,
+ bfd_default_compatible,
+ bfd_default_scan,
+ 0,
+};
+
+/*
+FUNCTION
+ bfd_set_arch_info
+
+SYNOPSIS
+ void bfd_set_arch_info(bfd *abfd, const bfd_arch_info_type *arg);
+
+DESCRIPTION
+ Set the architecture info of @var{abfd} to @var{arg}.
+*/
+
+void
+bfd_set_arch_info (abfd, arg)
+ bfd *abfd;
+ const bfd_arch_info_type *arg;
+{
+ abfd->arch_info = arg;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_default_set_arch_mach
+
+SYNOPSIS
+ boolean bfd_default_set_arch_mach(bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long mach);
+
+DESCRIPTION
+ Set the architecture and machine type in BFD @var{abfd}
+ to @var{arch} and @var{mach}. Find the correct
+ pointer to a structure and insert it into the <<arch_info>>
+ pointer.
+*/
+
+boolean
+bfd_default_set_arch_mach (abfd, arch, mach)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long mach;
+{
+ const bfd_arch_info_type * const *app, *ap;
+
+ for (app = bfd_archures_list; *app != NULL; app++)
+ {
+ for (ap = *app; ap != NULL; ap = ap->next)
+ {
+ if (ap->arch == arch
+ && (ap->mach == mach
+ || (mach == 0 && ap->the_default)))
+ {
+ abfd->arch_info = ap;
+ return true;
+ }
+ }
+ }
+
+ abfd->arch_info = &bfd_default_arch_struct;
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+}
+
+
+/*
+FUNCTION
+ bfd_get_arch
+
+SYNOPSIS
+ enum bfd_architecture bfd_get_arch(bfd *abfd);
+
+DESCRIPTION
+ Return the enumerated type which describes the BFD @var{abfd}'s
+ architecture.
+
+*/
+
+enum bfd_architecture
+bfd_get_arch (abfd)
+ bfd *abfd;
+{
+ return abfd->arch_info->arch;
+}
+
+/*
+FUNCTION
+ bfd_get_mach
+
+SYNOPSIS
+ unsigned long bfd_get_mach(bfd *abfd);
+
+DESCRIPTION
+ Return the long type which describes the BFD @var{abfd}'s
+ machine.
+*/
+
+unsigned long
+bfd_get_mach (abfd)
+ bfd *abfd;
+{
+ return abfd->arch_info->mach;
+}
+
+/*
+FUNCTION
+ bfd_arch_bits_per_byte
+
+SYNOPSIS
+ unsigned int bfd_arch_bits_per_byte(bfd *abfd);
+
+DESCRIPTION
+ Return the number of bits in one of the BFD @var{abfd}'s
+ architecture's bytes.
+
+*/
+
+unsigned int
+bfd_arch_bits_per_byte (abfd)
+ bfd *abfd;
+{
+ return abfd->arch_info->bits_per_byte;
+}
+
+/*
+FUNCTION
+ bfd_arch_bits_per_address
+
+SYNOPSIS
+ unsigned int bfd_arch_bits_per_address(bfd *abfd);
+
+DESCRIPTION
+ Return the number of bits in one of the BFD @var{abfd}'s
+ architecture's addresses.
+*/
+
+unsigned int
+bfd_arch_bits_per_address (abfd)
+ bfd *abfd;
+{
+ return abfd->arch_info->bits_per_address;
+}
+
+
+/*
+INTERNAL_FUNCTION
+ bfd_default_compatible
+
+SYNOPSIS
+ const bfd_arch_info_type *bfd_default_compatible
+ (const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b);
+
+DESCRIPTION
+ The default function for testing for compatibility.
+*/
+
+const bfd_arch_info_type *
+bfd_default_compatible (a,b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->mach > b->mach)
+ return a;
+
+ if (b->mach > a->mach)
+ return b;
+
+ return a;
+}
+
+
+/*
+INTERNAL_FUNCTION
+ bfd_default_scan
+
+SYNOPSIS
+ boolean bfd_default_scan(const struct bfd_arch_info *info, const char *string);
+
+DESCRIPTION
+ The default function for working out whether this is an
+ architecture hit and a machine hit.
+*/
+
+boolean
+bfd_default_scan (info, string)
+ const struct bfd_arch_info *info;
+ const char *string;
+{
+ const char *ptr_src;
+ const char *ptr_tst;
+ unsigned long number;
+ enum bfd_architecture arch;
+ const char *printable_name_colon;
+
+ /* Exact match of the architecture name (ARCH_NAME) and also the
+ default architecture? */
+ if (strcasecmp (string, info->arch_name) == 0
+ && info->the_default)
+ return true;
+
+ /* Exact match of the machine name (PRINTABLE_NAME)? */
+ if (strcasecmp (string, info->printable_name) == 0)
+ return true;
+
+ /* Given that printable_name contains no colon, attempt to match:
+ ARCH_NAME [ ":" ] PRINTABLE_NAME? */
+ printable_name_colon = strchr (info->printable_name, ':');
+ if (printable_name_colon == NULL)
+ {
+ int strlen_arch_name = strlen (info->arch_name);
+ if (strncasecmp (string, info->arch_name, strlen_arch_name) == 0)
+ {
+ if (string[strlen_arch_name] == ':')
+ {
+ if (strcasecmp (string + strlen_arch_name + 1,
+ info->printable_name) == 0)
+ return true;
+ }
+ else
+ {
+ if (strcasecmp (string + strlen_arch_name,
+ info->printable_name) == 0)
+ return true;
+ }
+ }
+ }
+
+ /* Given that PRINTABLE_NAME has the form: <arch> ":" <mach>;
+ Attempt to match: <arch> <mach>? */
+ if (printable_name_colon != NULL)
+ {
+ int colon_index = printable_name_colon - info->printable_name;
+ if (strncasecmp (string, info->printable_name, colon_index) == 0
+ && strcasecmp (string + colon_index,
+ info->printable_name + colon_index + 1) == 0)
+ return true;
+ }
+
+ /* Given that PRINTABLE_NAME has the form: <arch> ":" <mach>; Do not
+ attempt to match just <mach>, it could be ambigious. This test
+ is left until later. */
+
+ /* NOTE: The below is retained for compatibility only. Please do not
+ add to this code */
+
+ /* See how much of the supplied string matches with the
+ architecture, eg the string m68k:68020 would match the 68k entry
+ up to the :, then we get left with the machine number */
+
+ for (ptr_src = string, ptr_tst = info->arch_name;
+ *ptr_src && *ptr_tst;
+ ptr_src++, ptr_tst++)
+ {
+ if (*ptr_src != *ptr_tst) break;
+ }
+
+ /* Chewed up as much of the architecture as will match, skip any
+ colons */
+ if (*ptr_src == ':')
+ ptr_src++;
+
+ if (*ptr_src == 0)
+ {
+ /* nothing more, then only keep this one if it is the default
+ machine for this architecture */
+ return info->the_default;
+ }
+
+ number = 0;
+ while (isdigit ((unsigned char) *ptr_src))
+ {
+ number = number * 10 + *ptr_src - '0';
+ ptr_src++;
+ }
+
+ /* NOTE: The below is retained for compatibility only.
+ PLEASE DO NOT ADD TO THIS CODE. */
+
+ switch (number)
+ {
+ /* FIXME: These are needed to parse IEEE objects. */
+ case 68000:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_m68000;
+ break;
+ case 68010:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_m68010;
+ break;
+ case 68020:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_m68020;
+ break;
+ case 68030:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_m68030;
+ break;
+ case 68040:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_m68040;
+ break;
+ case 68060:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_m68060;
+ break;
+ case 68332:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_cpu32;
+ break;
+
+ case 32000:
+ arch = bfd_arch_we32k;
+ break;
+
+ case 3000:
+ arch = bfd_arch_mips;
+ number = bfd_mach_mips3000;
+ break;
+
+ case 4000:
+ arch = bfd_arch_mips;
+ number = bfd_mach_mips4000;
+ break;
+
+ case 6000:
+ arch = bfd_arch_rs6000;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (arch != info->arch)
+ return false;
+
+ if (number != info->mach)
+ return false;
+
+ return true;
+}
+
+
+/*
+FUNCTION
+ bfd_get_arch_info
+
+SYNOPSIS
+ const bfd_arch_info_type * bfd_get_arch_info(bfd *abfd);
+
+DESCRIPTION
+ Return the architecture info struct in @var{abfd}.
+*/
+
+const bfd_arch_info_type *
+bfd_get_arch_info (abfd)
+ bfd *abfd;
+{
+ return abfd->arch_info;
+}
+
+
+/*
+FUNCTION
+ bfd_lookup_arch
+
+SYNOPSIS
+ const bfd_arch_info_type *bfd_lookup_arch
+ (enum bfd_architecture
+ arch,
+ unsigned long machine);
+
+DESCRIPTION
+ Look for the architecure info structure which matches the
+ arguments @var{arch} and @var{machine}. A machine of 0 matches the
+ machine/architecture structure which marks itself as the
+ default.
+*/
+
+const bfd_arch_info_type *
+bfd_lookup_arch (arch, machine)
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ const bfd_arch_info_type * const *app, *ap;
+
+ for (app = bfd_archures_list; *app != NULL; app++)
+ {
+ for (ap = *app; ap != NULL; ap = ap->next)
+ {
+ if (ap->arch == arch
+ && (ap->mach == machine
+ || (machine == 0 && ap->the_default)))
+ return ap;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+FUNCTION
+ bfd_printable_arch_mach
+
+SYNOPSIS
+ const char *bfd_printable_arch_mach
+ (enum bfd_architecture arch, unsigned long machine);
+
+DESCRIPTION
+ Return a printable string representing the architecture and
+ machine type.
+
+ This routine is depreciated.
+*/
+
+const char *
+bfd_printable_arch_mach (arch, machine)
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ const bfd_arch_info_type *ap = bfd_lookup_arch (arch, machine);
+
+ if (ap)
+ return ap->printable_name;
+ return "UNKNOWN!";
+}
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
new file mode 100644
index 00000000000..8bdbf80f1b1
--- /dev/null
+++ b/bfd/bfd-in.h
@@ -0,0 +1,727 @@
+/* Main header file for the bfd library -- portable access to object files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+** NOTE: bfd.h and bfd-in2.h are GENERATED files. Don't change them;
+** instead, change bfd-in.h or the other BFD source files processed to
+** generate these files.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* bfd.h -- The only header file required by users of the bfd library
+
+The bfd.h file is generated from bfd-in.h and various .c files; if you
+change it, your changes will probably be lost.
+
+All the prototypes and definitions following the comment "THE FOLLOWING
+IS EXTRACTED FROM THE SOURCE" are extracted from the source files for
+BFD. If you change it, someone oneday will extract it from the source
+again, and your changes will be lost. To save yourself from this bind,
+change the definitions in the source in the bfd directory. Type "make
+docs" and then "make headers" in that directory, and magically this file
+will change to reflect your changes.
+
+If you don't have the tools to perform the extraction, then you are
+safe from someone on your system trampling over your header files.
+You should still maintain the equivalence between the source and this
+file though; every change you make to the .c file should be reflected
+here. */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+
+/* These two lines get substitutions done by commands in Makefile.in. */
+#define BFD_VERSION "@VERSION@"
+#define BFD_ARCH_SIZE @wordsize@
+#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@
+#if @BFD_HOST_64_BIT_DEFINED@
+#define BFD_HOST_64_BIT @BFD_HOST_64_BIT@
+#define BFD_HOST_U_64_BIT @BFD_HOST_U_64_BIT@
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* forward declaration */
+typedef struct _bfd bfd;
+
+/* To squelch erroneous compiler warnings ("illegal pointer
+ combination") from the SVR3 compiler, we would like to typedef
+ boolean to int (it doesn't like functions which return boolean.
+ Making sure they are never implicitly declared to return int
+ doesn't seem to help). But this file is not configured based on
+ the host. */
+/* General rules: functions which are boolean return true on success
+ and false on failure (unless they're a predicate). -- bfd.doc */
+/* I'm sure this is going to break something and someone is going to
+ force me to change it. */
+/* typedef enum boolean {false, true} boolean; */
+/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h> -fnf */
+/* It gets worse if the host also defines a true/false enum... -sts */
+/* And even worse if your compiler has built-in boolean types... -law */
+#if defined (__GNUG__) && (__GNUC_MINOR__ > 5)
+#define TRUE_FALSE_ALREADY_DEFINED
+#endif
+#ifdef MPW
+/* Pre-emptive strike - get the file with the enum. */
+#include <Types.h>
+#define TRUE_FALSE_ALREADY_DEFINED
+#endif /* MPW */
+#ifndef TRUE_FALSE_ALREADY_DEFINED
+typedef enum bfd_boolean {false, true} boolean;
+#define BFD_TRUE_FALSE
+#else
+/* Use enum names that will appear nowhere else. */
+typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean;
+#endif
+
+/* A pointer to a position in a file. */
+/* FIXME: This should be using off_t from <sys/types.h>.
+ For now, try to avoid breaking stuff by not including <sys/types.h> here.
+ This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
+ Probably the best long-term answer is to avoid using file_ptr AND off_t
+ in this header file, and to handle this in the BFD implementation
+ rather than in its interface. */
+/* typedef off_t file_ptr; */
+typedef long int file_ptr;
+
+/* Support for different sizes of target format ints and addresses.
+ If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be
+ set to 1 above. Otherwise, if gcc is being used, this code will
+ use gcc's "long long" type. Otherwise, BFD_HOST_64_BIT must be
+ defined above. */
+
+#ifndef BFD_HOST_64_BIT
+# if BFD_HOST_64BIT_LONG
+# define BFD_HOST_64_BIT long
+# define BFD_HOST_U_64_BIT unsigned long
+# else
+# ifdef __GNUC__
+# if __GNUC__ >= 2
+# define BFD_HOST_64_BIT long long
+# define BFD_HOST_U_64_BIT unsigned long long
+# endif /* __GNUC__ >= 2 */
+# endif /* ! defined (__GNUC__) */
+# endif /* ! BFD_HOST_64BIT_LONG */
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+ fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+ sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64 */
+
+/* Represent a target address. Also used as a generic unsigned type
+ which is guaranteed to be big enough to hold any arithmetic types
+ we need to deal with. */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+ arithmetic types we need to deal with. Can be assumed to be compatible
+ with bfd_vma in the same way that signed and unsigned ints are compatible
+ (as parameters, in assignment, etc). */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s. */
+#define fprintf_vma(s,x) fprintf(s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf(s, "%08lx", x)
+
+#endif /* not BFD64 */
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+
+/** File formats */
+
+typedef enum bfd_format {
+ bfd_unknown = 0, /* file format is unknown */
+ bfd_object, /* linker/assember/compiler output */
+ bfd_archive, /* object archive file */
+ bfd_core, /* core dump */
+ bfd_type_end} /* marks the end; don't use it! */
+ bfd_format;
+
+/* Values that may appear in the flags field of a BFD. These also
+ appear in the object_flags field of the bfd_target structure, where
+ they indicate the set of flags used by that backend (not all flags
+ are meaningful for all object file formats) (FIXME: at the moment,
+ the object_flags values have mostly just been copied from backend
+ to another, and are not necessarily correct). */
+
+/* No flags. */
+#define BFD_NO_FLAGS 0x00
+
+/* BFD contains relocation entries. */
+#define HAS_RELOC 0x01
+
+/* BFD is directly executable. */
+#define EXEC_P 0x02
+
+/* BFD has line number information (basically used for F_LNNO in a
+ COFF header). */
+#define HAS_LINENO 0x04
+
+/* BFD has debugging information. */
+#define HAS_DEBUG 0x08
+
+/* BFD has symbols. */
+#define HAS_SYMS 0x10
+
+/* BFD has local symbols (basically used for F_LSYMS in a COFF
+ header). */
+#define HAS_LOCALS 0x20
+
+/* BFD is a dynamic object. */
+#define DYNAMIC 0x40
+
+/* Text section is write protected (if D_PAGED is not set, this is
+ like an a.out NMAGIC file) (the linker sets this by default, but
+ clears it for -r or -N). */
+#define WP_TEXT 0x80
+
+/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
+ linker sets this by default, but clears it for -r or -n or -N). */
+#define D_PAGED 0x100
+
+/* BFD is relaxable (this means that bfd_relax_section may be able to
+ do something) (sometimes bfd_relax_section can do something even if
+ this is not set). */
+#define BFD_IS_RELAXABLE 0x200
+
+/* This may be set before writing out a BFD to request using a
+ traditional format. For example, this is used to request that when
+ writing out an a.out object the symbols not be hashed to eliminate
+ duplicates. */
+#define BFD_TRADITIONAL_FORMAT 0x400
+
+/* This flag indicates that the BFD contents are actually cached in
+ memory. If this is set, iostream points to a bfd_in_memory struct. */
+#define BFD_IN_MEMORY 0x800
+
+/* symbols and relocation */
+
+/* A count of carsyms (canonical archive symbols). */
+typedef unsigned long symindex;
+
+/* How to perform a relocation. */
+typedef const struct reloc_howto_struct reloc_howto_type;
+
+#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
+
+/* General purpose part of a symbol X;
+ target specific parts are in libcoff.h, libaout.h, etc. */
+
+#define bfd_get_section(x) ((x)->section)
+#define bfd_get_output_section(x) ((x)->section->output_section)
+#define bfd_set_section(x,y) ((x)->section) = (y)
+#define bfd_asymbol_base(x) ((x)->section->vma)
+#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value)
+#define bfd_asymbol_name(x) ((x)->name)
+/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/
+#define bfd_asymbol_bfd(x) ((x)->the_bfd)
+#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour)
+
+/* A canonical archive symbol. */
+/* This is a type pun with struct ranlib on purpose! */
+typedef struct carsym {
+ char *name;
+ file_ptr file_offset; /* look here to find the file */
+} carsym; /* to make these you call a carsymogen */
+
+
+/* Used in generating armaps (archive tables of contents).
+ Perhaps just a forward definition would do? */
+struct orl { /* output ranlib */
+ char **name; /* symbol name */
+ file_ptr pos; /* bfd* or file position */
+ int namidx; /* index into string table */
+};
+
+
+/* Linenumber stuff */
+typedef struct lineno_cache_entry {
+ unsigned int line_number; /* Linenumber from start of function*/
+ union {
+ struct symbol_cache_entry *sym; /* Function name */
+ unsigned long offset; /* Offset into section */
+ } u;
+} alent;
+
+/* object and core file sections */
+
+#define align_power(addr, align) \
+ ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
+
+typedef struct sec *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
+#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
+#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
+#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
+#define bfd_section_lma(bfd, ptr) ((ptr)->lma)
+#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
+#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
+#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = (boolean)true), true)
+#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true)
+#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true)
+
+typedef struct stat stat_type;
+
+typedef enum bfd_print_symbol
+{
+ bfd_print_symbol_name,
+ bfd_print_symbol_more,
+ bfd_print_symbol_all
+} bfd_print_symbol_type;
+
+/* Information about a symbol that nm needs. */
+
+typedef struct _symbol_info
+{
+ symvalue value;
+ char type;
+ CONST char *name; /* Symbol name. */
+ unsigned char stab_type; /* Stab type. */
+ char stab_other; /* Stab other. */
+ short stab_desc; /* Stab desc. */
+ CONST char *stab_name; /* String for stab type. */
+} symbol_info;
+
+/* Get the name of a stabs type code. */
+
+extern const char *bfd_get_stab_name PARAMS ((int));
+
+/* Hash table routines. There is no way to free up a hash table. */
+
+/* An element in the hash table. Most uses will actually use a larger
+ structure, and an instance of this will be the first field. */
+
+struct bfd_hash_entry
+{
+ /* Next entry for this hash code. */
+ struct bfd_hash_entry *next;
+ /* String being hashed. */
+ const char *string;
+ /* Hash code. This is the full hash code, not the index into the
+ table. */
+ unsigned long hash;
+};
+
+/* A hash table. */
+
+struct bfd_hash_table
+{
+ /* The hash array. */
+ struct bfd_hash_entry **table;
+ /* The number of slots in the hash table. */
+ unsigned int size;
+ /* A function used to create new elements in the hash table. The
+ first entry is itself a pointer to an element. When this
+ function is first invoked, this pointer will be NULL. However,
+ having the pointer permits a hierarchy of method functions to be
+ built each of which calls the function in the superclass. Thus
+ each function should be written to allocate a new block of memory
+ only if the argument is NULL. */
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+ /* An objalloc for this hash table. This is a struct objalloc *,
+ but we use PTR to avoid requiring the inclusion of objalloc.h. */
+ PTR memory;
+};
+
+/* Initialize a hash table. */
+extern boolean bfd_hash_table_init
+ PARAMS ((struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+
+/* Initialize a hash table specifying a size. */
+extern boolean bfd_hash_table_init_n
+ PARAMS ((struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int size));
+
+/* Free up a hash table. */
+extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *));
+
+/* Look up a string in a hash table. If CREATE is true, a new entry
+ will be created for this string if one does not already exist. The
+ COPY argument must be true if this routine should copy the string
+ into newly allocated memory when adding an entry. */
+extern struct bfd_hash_entry *bfd_hash_lookup
+ PARAMS ((struct bfd_hash_table *, const char *, boolean create,
+ boolean copy));
+
+/* Replace an entry in a hash table. */
+extern void bfd_hash_replace
+ PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old,
+ struct bfd_hash_entry *nw));
+
+/* Base method for creating a hash table entry. */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *));
+
+/* Grab some space for a hash table entry. */
+extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *,
+ unsigned int));
+
+/* Traverse a hash table in a random order, calling a function on each
+ element. If the function returns false, the traversal stops. The
+ INFO argument is passed to the function. */
+extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *,
+ boolean (*) (struct bfd_hash_entry *,
+ PTR),
+ PTR info));
+
+/* Semi-portable string concatenation in cpp.
+ The CAT4 hack is to avoid a problem with some strict ANSI C preprocessors.
+ The problem is, "32_" is not a valid preprocessing token, and we don't
+ want extra underscores (e.g., "nlm_32_"). The XCAT2 macro will cause the
+ inner CAT macros to be evaluated first, producing still-valid pp-tokens.
+ Then the final concatenation can be done. (Sigh.) */
+#ifndef CAT
+#ifdef SABER
+#define CAT(a,b) a##b
+#define CAT3(a,b,c) a##b##c
+#define CAT4(a,b,c,d) a##b##c##d
+#else
+#if defined(__STDC__) || defined(ALMOST_STDC)
+#define CAT(a,b) a##b
+#define CAT3(a,b,c) a##b##c
+#define XCAT2(a,b) CAT(a,b)
+#define CAT4(a,b,c,d) XCAT2(CAT(a,b),CAT(c,d))
+#else
+#define CAT(a,b) a/**/b
+#define CAT3(a,b,c) a/**/b/**/c
+#define CAT4(a,b,c,d) a/**/b/**/c/**/d
+#endif
+#endif
+#endif
+
+#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
+
+/* User program access to BFD facilities */
+
+/* Direct I/O routines, for programs which know more about the object
+ file than BFD does. Use higher level routines if possible. */
+
+extern bfd_size_type bfd_read
+ PARAMS ((PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
+extern bfd_size_type bfd_write
+ PARAMS ((const PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
+extern int bfd_seek PARAMS ((bfd *abfd, file_ptr fp, int direction));
+extern long bfd_tell PARAMS ((bfd *abfd));
+extern int bfd_flush PARAMS ((bfd *abfd));
+extern int bfd_stat PARAMS ((bfd *abfd, struct stat *));
+
+
+/* Cast from const char * to char * so that caller can assign to
+ a char * without a warning. */
+#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
+#define bfd_get_cacheable(abfd) ((abfd)->cacheable)
+#define bfd_get_format(abfd) ((abfd)->format)
+#define bfd_get_target(abfd) ((abfd)->xvec->name)
+#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
+#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
+#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_header_big_endian(abfd) \
+ ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG)
+#define bfd_header_little_endian(abfd) \
+ ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_get_file_flags(abfd) ((abfd)->flags)
+#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
+#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
+#define bfd_my_archive(abfd) ((abfd)->my_archive)
+#define bfd_has_map(abfd) ((abfd)->has_armap)
+
+#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
+#define bfd_usrdata(abfd) ((abfd)->usrdata)
+
+#define bfd_get_start_address(abfd) ((abfd)->start_address)
+#define bfd_get_symcount(abfd) ((abfd)->symcount)
+#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
+#define bfd_count_sections(abfd) ((abfd)->section_count)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (boolean)(bool)), true)
+
+extern boolean bfd_record_phdr
+ PARAMS ((bfd *, unsigned long, boolean, flagword, boolean, bfd_vma,
+ boolean, boolean, unsigned int, struct sec **));
+
+/* Byte swapping routines. */
+
+bfd_vma bfd_getb64 PARAMS ((const unsigned char *));
+bfd_vma bfd_getl64 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_64 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_64 PARAMS ((const unsigned char *));
+bfd_vma bfd_getb32 PARAMS ((const unsigned char *));
+bfd_vma bfd_getl32 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_32 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_32 PARAMS ((const unsigned char *));
+bfd_vma bfd_getb16 PARAMS ((const unsigned char *));
+bfd_vma bfd_getl16 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_16 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_16 PARAMS ((const unsigned char *));
+void bfd_putb64 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl64 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putb32 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl32 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putb16 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl16 PARAMS ((bfd_vma, unsigned char *));
+
+/* Externally visible ECOFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct symbol_cache_entry;
+struct bfd_link_info;
+struct bfd_link_hash_entry;
+struct bfd_elf_version_tree;
+#endif
+extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd));
+extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value));
+extern boolean bfd_ecoff_set_regmasks
+ PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+ unsigned long *cprmask));
+extern PTR bfd_ecoff_debug_init
+ PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap,
+ struct bfd_link_info *));
+extern void bfd_ecoff_debug_free
+ PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap,
+ struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_accumulate
+ PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap,
+ bfd *input_bfd, struct ecoff_debug_info *input_debug,
+ const struct ecoff_debug_swap *input_swap,
+ struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_accumulate_other
+ PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, bfd *input_bfd,
+ struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_externals
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ boolean relocateable,
+ boolean (*get_extr) (struct symbol_cache_entry *,
+ struct ecoff_extr *),
+ void (*set_index) (struct symbol_cache_entry *,
+ bfd_size_type)));
+extern boolean bfd_ecoff_debug_one_external
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ const char *name, struct ecoff_extr *esym));
+extern bfd_size_type bfd_ecoff_debug_size
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap));
+extern boolean bfd_ecoff_write_debug
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, file_ptr where));
+extern boolean bfd_ecoff_write_accumulated_debug
+ PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ struct bfd_link_info *info, file_ptr where));
+extern boolean bfd_mips_ecoff_create_embedded_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+ char **));
+
+/* Externally visible ELF routines. */
+
+struct bfd_link_needed_list
+{
+ struct bfd_link_needed_list *next;
+ bfd *by;
+ const char *name;
+};
+
+extern boolean bfd_elf32_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean));
+extern boolean bfd_elf64_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean));
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_elf_get_bfd_needed_list
+ PARAMS ((bfd *, struct bfd_link_needed_list **));
+extern boolean bfd_elf32_size_dynamic_sections
+ PARAMS ((bfd *, const char *, const char *, boolean, const char *,
+ const char * const *, struct bfd_link_info *, struct sec **,
+ struct bfd_elf_version_tree *));
+extern boolean bfd_elf64_size_dynamic_sections
+ PARAMS ((bfd *, const char *, const char *, boolean, const char *,
+ const char * const *, struct bfd_link_info *, struct sec **,
+ struct bfd_elf_version_tree *));
+extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
+extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
+
+/* SunOS shared library support routines for the linker. */
+
+extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_sunos_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern boolean bfd_sunos_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *, struct sec **, struct sec **,
+ struct sec **));
+
+/* Linux shared library support routines for the linker. */
+
+extern boolean bfd_i386linux_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_m68klinux_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_sparclinux_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* mmap hacks */
+
+struct _bfd_window_internal;
+typedef struct _bfd_window_internal bfd_window_internal;
+
+typedef struct _bfd_window {
+ /* What the user asked for. */
+ PTR data;
+ bfd_size_type size;
+ /* The actual window used by BFD. Small user-requested read-only
+ regions sharing a page may share a single window into the object
+ file. Read-write versions shouldn't until I've fixed things to
+ keep track of which portions have been claimed by the
+ application; don't want to give the same region back when the
+ application wants two writable copies! */
+ struct _bfd_window_internal *i;
+} bfd_window;
+
+extern void bfd_init_window PARAMS ((bfd_window *));
+extern void bfd_free_window PARAMS ((bfd_window *));
+extern boolean bfd_get_file_window
+ PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, boolean));
+
+/* XCOFF support routines for the linker. */
+
+extern boolean bfd_xcoff_link_record_set
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+ bfd_size_type));
+extern boolean bfd_xcoff_import_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+ bfd_vma, const char *, const char *, const char *));
+extern boolean bfd_xcoff_export_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+ boolean));
+extern boolean bfd_xcoff_link_count_reloc
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern boolean bfd_xcoff_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern boolean bfd_xcoff_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *,
+ unsigned long, unsigned long, unsigned long, boolean,
+ int, boolean, boolean, struct sec **));
+
+/* Externally visible COFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct internal_syment;
+union internal_auxent;
+#endif
+
+extern boolean bfd_coff_get_syment
+ PARAMS ((bfd *, struct symbol_cache_entry *, struct internal_syment *));
+
+extern boolean bfd_coff_get_auxent
+ PARAMS ((bfd *, struct symbol_cache_entry *, int, union internal_auxent *));
+
+extern boolean bfd_coff_set_symbol_class
+ PARAMS ((bfd *, struct symbol_cache_entry *, unsigned int));
+
+/* ARM Interworking support. Called from linker. */
+extern boolean bfd_arm_allocate_interworking_sections
+ PARAMS ((struct bfd_link_info *));
+
+extern boolean bfd_arm_process_before_allocation
+ PARAMS ((bfd *, struct bfd_link_info *, int));
+
+extern boolean bfd_arm_get_bfd_for_interworking
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* ELF ARM Interworking support. Called from linker. */
+ extern boolean bfd_elf32_arm_allocate_interworking_sections
+ PARAMS ((struct bfd_link_info *));
+
+ extern boolean bfd_elf32_arm_process_before_allocation
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+ extern boolean bfd_elf32_arm_get_bfd_for_interworking
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* And more from the source. */
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
new file mode 100644
index 00000000000..8e86304d953
--- /dev/null
+++ b/bfd/bfd-in2.h
@@ -0,0 +1,3003 @@
+/* Main header file for the bfd library -- portable access to object files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+** NOTE: bfd.h and bfd-in2.h are GENERATED files. Don't change them;
+** instead, change bfd-in.h or the other BFD source files processed to
+** generate these files.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* bfd.h -- The only header file required by users of the bfd library
+
+The bfd.h file is generated from bfd-in.h and various .c files; if you
+change it, your changes will probably be lost.
+
+All the prototypes and definitions following the comment "THE FOLLOWING
+IS EXTRACTED FROM THE SOURCE" are extracted from the source files for
+BFD. If you change it, someone oneday will extract it from the source
+again, and your changes will be lost. To save yourself from this bind,
+change the definitions in the source in the bfd directory. Type "make
+docs" and then "make headers" in that directory, and magically this file
+will change to reflect your changes.
+
+If you don't have the tools to perform the extraction, then you are
+safe from someone on your system trampling over your header files.
+You should still maintain the equivalence between the source and this
+file though; every change you make to the .c file should be reflected
+here. */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+
+/* These two lines get substitutions done by commands in Makefile.in. */
+#define BFD_VERSION "@VERSION@"
+#define BFD_ARCH_SIZE @wordsize@
+#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@
+#if @BFD_HOST_64_BIT_DEFINED@
+#define BFD_HOST_64_BIT @BFD_HOST_64_BIT@
+#define BFD_HOST_U_64_BIT @BFD_HOST_U_64_BIT@
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* forward declaration */
+typedef struct _bfd bfd;
+
+/* To squelch erroneous compiler warnings ("illegal pointer
+ combination") from the SVR3 compiler, we would like to typedef
+ boolean to int (it doesn't like functions which return boolean.
+ Making sure they are never implicitly declared to return int
+ doesn't seem to help). But this file is not configured based on
+ the host. */
+/* General rules: functions which are boolean return true on success
+ and false on failure (unless they're a predicate). -- bfd.doc */
+/* I'm sure this is going to break something and someone is going to
+ force me to change it. */
+/* typedef enum boolean {false, true} boolean; */
+/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h> -fnf */
+/* It gets worse if the host also defines a true/false enum... -sts */
+/* And even worse if your compiler has built-in boolean types... -law */
+#if defined (__GNUG__) && (__GNUC_MINOR__ > 5)
+#define TRUE_FALSE_ALREADY_DEFINED
+#endif
+#ifdef MPW
+/* Pre-emptive strike - get the file with the enum. */
+#include <Types.h>
+#define TRUE_FALSE_ALREADY_DEFINED
+#endif /* MPW */
+#ifndef TRUE_FALSE_ALREADY_DEFINED
+typedef enum bfd_boolean {false, true} boolean;
+#define BFD_TRUE_FALSE
+#else
+/* Use enum names that will appear nowhere else. */
+typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean;
+#endif
+
+/* A pointer to a position in a file. */
+/* FIXME: This should be using off_t from <sys/types.h>.
+ For now, try to avoid breaking stuff by not including <sys/types.h> here.
+ This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
+ Probably the best long-term answer is to avoid using file_ptr AND off_t
+ in this header file, and to handle this in the BFD implementation
+ rather than in its interface. */
+/* typedef off_t file_ptr; */
+typedef long int file_ptr;
+
+/* Support for different sizes of target format ints and addresses.
+ If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be
+ set to 1 above. Otherwise, if gcc is being used, this code will
+ use gcc's "long long" type. Otherwise, BFD_HOST_64_BIT must be
+ defined above. */
+
+#ifndef BFD_HOST_64_BIT
+# if BFD_HOST_64BIT_LONG
+# define BFD_HOST_64_BIT long
+# define BFD_HOST_U_64_BIT unsigned long
+# else
+# ifdef __GNUC__
+# if __GNUC__ >= 2
+# define BFD_HOST_64_BIT long long
+# define BFD_HOST_U_64_BIT unsigned long long
+# endif /* __GNUC__ >= 2 */
+# endif /* ! defined (__GNUC__) */
+# endif /* ! BFD_HOST_64BIT_LONG */
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+ fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+ sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64 */
+
+/* Represent a target address. Also used as a generic unsigned type
+ which is guaranteed to be big enough to hold any arithmetic types
+ we need to deal with. */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+ arithmetic types we need to deal with. Can be assumed to be compatible
+ with bfd_vma in the same way that signed and unsigned ints are compatible
+ (as parameters, in assignment, etc). */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s. */
+#define fprintf_vma(s,x) fprintf(s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf(s, "%08lx", x)
+
+#endif /* not BFD64 */
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+
+/** File formats */
+
+typedef enum bfd_format {
+ bfd_unknown = 0, /* file format is unknown */
+ bfd_object, /* linker/assember/compiler output */
+ bfd_archive, /* object archive file */
+ bfd_core, /* core dump */
+ bfd_type_end} /* marks the end; don't use it! */
+ bfd_format;
+
+/* Values that may appear in the flags field of a BFD. These also
+ appear in the object_flags field of the bfd_target structure, where
+ they indicate the set of flags used by that backend (not all flags
+ are meaningful for all object file formats) (FIXME: at the moment,
+ the object_flags values have mostly just been copied from backend
+ to another, and are not necessarily correct). */
+
+/* No flags. */
+#define BFD_NO_FLAGS 0x00
+
+/* BFD contains relocation entries. */
+#define HAS_RELOC 0x01
+
+/* BFD is directly executable. */
+#define EXEC_P 0x02
+
+/* BFD has line number information (basically used for F_LNNO in a
+ COFF header). */
+#define HAS_LINENO 0x04
+
+/* BFD has debugging information. */
+#define HAS_DEBUG 0x08
+
+/* BFD has symbols. */
+#define HAS_SYMS 0x10
+
+/* BFD has local symbols (basically used for F_LSYMS in a COFF
+ header). */
+#define HAS_LOCALS 0x20
+
+/* BFD is a dynamic object. */
+#define DYNAMIC 0x40
+
+/* Text section is write protected (if D_PAGED is not set, this is
+ like an a.out NMAGIC file) (the linker sets this by default, but
+ clears it for -r or -N). */
+#define WP_TEXT 0x80
+
+/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
+ linker sets this by default, but clears it for -r or -n or -N). */
+#define D_PAGED 0x100
+
+/* BFD is relaxable (this means that bfd_relax_section may be able to
+ do something) (sometimes bfd_relax_section can do something even if
+ this is not set). */
+#define BFD_IS_RELAXABLE 0x200
+
+/* This may be set before writing out a BFD to request using a
+ traditional format. For example, this is used to request that when
+ writing out an a.out object the symbols not be hashed to eliminate
+ duplicates. */
+#define BFD_TRADITIONAL_FORMAT 0x400
+
+/* This flag indicates that the BFD contents are actually cached in
+ memory. If this is set, iostream points to a bfd_in_memory struct. */
+#define BFD_IN_MEMORY 0x800
+
+/* symbols and relocation */
+
+/* A count of carsyms (canonical archive symbols). */
+typedef unsigned long symindex;
+
+/* How to perform a relocation. */
+typedef const struct reloc_howto_struct reloc_howto_type;
+
+#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
+
+/* General purpose part of a symbol X;
+ target specific parts are in libcoff.h, libaout.h, etc. */
+
+#define bfd_get_section(x) ((x)->section)
+#define bfd_get_output_section(x) ((x)->section->output_section)
+#define bfd_set_section(x,y) ((x)->section) = (y)
+#define bfd_asymbol_base(x) ((x)->section->vma)
+#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value)
+#define bfd_asymbol_name(x) ((x)->name)
+/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/
+#define bfd_asymbol_bfd(x) ((x)->the_bfd)
+#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour)
+
+/* A canonical archive symbol. */
+/* This is a type pun with struct ranlib on purpose! */
+typedef struct carsym {
+ char *name;
+ file_ptr file_offset; /* look here to find the file */
+} carsym; /* to make these you call a carsymogen */
+
+
+/* Used in generating armaps (archive tables of contents).
+ Perhaps just a forward definition would do? */
+struct orl { /* output ranlib */
+ char **name; /* symbol name */
+ file_ptr pos; /* bfd* or file position */
+ int namidx; /* index into string table */
+};
+
+
+/* Linenumber stuff */
+typedef struct lineno_cache_entry {
+ unsigned int line_number; /* Linenumber from start of function*/
+ union {
+ struct symbol_cache_entry *sym; /* Function name */
+ unsigned long offset; /* Offset into section */
+ } u;
+} alent;
+
+/* object and core file sections */
+
+#define align_power(addr, align) \
+ ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
+
+typedef struct sec *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
+#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
+#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
+#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
+#define bfd_section_lma(bfd, ptr) ((ptr)->lma)
+#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
+#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
+#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = (boolean)true), true)
+#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true)
+#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true)
+
+typedef struct stat stat_type;
+
+typedef enum bfd_print_symbol
+{
+ bfd_print_symbol_name,
+ bfd_print_symbol_more,
+ bfd_print_symbol_all
+} bfd_print_symbol_type;
+
+/* Information about a symbol that nm needs. */
+
+typedef struct _symbol_info
+{
+ symvalue value;
+ char type;
+ CONST char *name; /* Symbol name. */
+ unsigned char stab_type; /* Stab type. */
+ char stab_other; /* Stab other. */
+ short stab_desc; /* Stab desc. */
+ CONST char *stab_name; /* String for stab type. */
+} symbol_info;
+
+/* Get the name of a stabs type code. */
+
+extern const char *bfd_get_stab_name PARAMS ((int));
+
+/* Hash table routines. There is no way to free up a hash table. */
+
+/* An element in the hash table. Most uses will actually use a larger
+ structure, and an instance of this will be the first field. */
+
+struct bfd_hash_entry
+{
+ /* Next entry for this hash code. */
+ struct bfd_hash_entry *next;
+ /* String being hashed. */
+ const char *string;
+ /* Hash code. This is the full hash code, not the index into the
+ table. */
+ unsigned long hash;
+};
+
+/* A hash table. */
+
+struct bfd_hash_table
+{
+ /* The hash array. */
+ struct bfd_hash_entry **table;
+ /* The number of slots in the hash table. */
+ unsigned int size;
+ /* A function used to create new elements in the hash table. The
+ first entry is itself a pointer to an element. When this
+ function is first invoked, this pointer will be NULL. However,
+ having the pointer permits a hierarchy of method functions to be
+ built each of which calls the function in the superclass. Thus
+ each function should be written to allocate a new block of memory
+ only if the argument is NULL. */
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+ /* An objalloc for this hash table. This is a struct objalloc *,
+ but we use PTR to avoid requiring the inclusion of objalloc.h. */
+ PTR memory;
+};
+
+/* Initialize a hash table. */
+extern boolean bfd_hash_table_init
+ PARAMS ((struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+
+/* Initialize a hash table specifying a size. */
+extern boolean bfd_hash_table_init_n
+ PARAMS ((struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int size));
+
+/* Free up a hash table. */
+extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *));
+
+/* Look up a string in a hash table. If CREATE is true, a new entry
+ will be created for this string if one does not already exist. The
+ COPY argument must be true if this routine should copy the string
+ into newly allocated memory when adding an entry. */
+extern struct bfd_hash_entry *bfd_hash_lookup
+ PARAMS ((struct bfd_hash_table *, const char *, boolean create,
+ boolean copy));
+
+/* Replace an entry in a hash table. */
+extern void bfd_hash_replace
+ PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old,
+ struct bfd_hash_entry *nw));
+
+/* Base method for creating a hash table entry. */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *));
+
+/* Grab some space for a hash table entry. */
+extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *,
+ unsigned int));
+
+/* Traverse a hash table in a random order, calling a function on each
+ element. If the function returns false, the traversal stops. The
+ INFO argument is passed to the function. */
+extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *,
+ boolean (*) (struct bfd_hash_entry *,
+ PTR),
+ PTR info));
+
+/* Semi-portable string concatenation in cpp.
+ The CAT4 hack is to avoid a problem with some strict ANSI C preprocessors.
+ The problem is, "32_" is not a valid preprocessing token, and we don't
+ want extra underscores (e.g., "nlm_32_"). The XCAT2 macro will cause the
+ inner CAT macros to be evaluated first, producing still-valid pp-tokens.
+ Then the final concatenation can be done. (Sigh.) */
+#ifndef CAT
+#ifdef SABER
+#define CAT(a,b) a##b
+#define CAT3(a,b,c) a##b##c
+#define CAT4(a,b,c,d) a##b##c##d
+#else
+#if defined(__STDC__) || defined(ALMOST_STDC)
+#define CAT(a,b) a##b
+#define CAT3(a,b,c) a##b##c
+#define XCAT2(a,b) CAT(a,b)
+#define CAT4(a,b,c,d) XCAT2(CAT(a,b),CAT(c,d))
+#else
+#define CAT(a,b) a/**/b
+#define CAT3(a,b,c) a/**/b/**/c
+#define CAT4(a,b,c,d) a/**/b/**/c/**/d
+#endif
+#endif
+#endif
+
+#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
+
+/* User program access to BFD facilities */
+
+/* Direct I/O routines, for programs which know more about the object
+ file than BFD does. Use higher level routines if possible. */
+
+extern bfd_size_type bfd_read
+ PARAMS ((PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
+extern bfd_size_type bfd_write
+ PARAMS ((const PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd));
+extern int bfd_seek PARAMS ((bfd *abfd, file_ptr fp, int direction));
+extern long bfd_tell PARAMS ((bfd *abfd));
+extern int bfd_flush PARAMS ((bfd *abfd));
+extern int bfd_stat PARAMS ((bfd *abfd, struct stat *));
+
+
+/* Cast from const char * to char * so that caller can assign to
+ a char * without a warning. */
+#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
+#define bfd_get_cacheable(abfd) ((abfd)->cacheable)
+#define bfd_get_format(abfd) ((abfd)->format)
+#define bfd_get_target(abfd) ((abfd)->xvec->name)
+#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
+#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
+#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_header_big_endian(abfd) \
+ ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG)
+#define bfd_header_little_endian(abfd) \
+ ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_get_file_flags(abfd) ((abfd)->flags)
+#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
+#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
+#define bfd_my_archive(abfd) ((abfd)->my_archive)
+#define bfd_has_map(abfd) ((abfd)->has_armap)
+
+#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
+#define bfd_usrdata(abfd) ((abfd)->usrdata)
+
+#define bfd_get_start_address(abfd) ((abfd)->start_address)
+#define bfd_get_symcount(abfd) ((abfd)->symcount)
+#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
+#define bfd_count_sections(abfd) ((abfd)->section_count)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (boolean)(bool)), true)
+
+extern boolean bfd_record_phdr
+ PARAMS ((bfd *, unsigned long, boolean, flagword, boolean, bfd_vma,
+ boolean, boolean, unsigned int, struct sec **));
+
+/* Byte swapping routines. */
+
+bfd_vma bfd_getb64 PARAMS ((const unsigned char *));
+bfd_vma bfd_getl64 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_64 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_64 PARAMS ((const unsigned char *));
+bfd_vma bfd_getb32 PARAMS ((const unsigned char *));
+bfd_vma bfd_getl32 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_32 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_32 PARAMS ((const unsigned char *));
+bfd_vma bfd_getb16 PARAMS ((const unsigned char *));
+bfd_vma bfd_getl16 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getb_signed_16 PARAMS ((const unsigned char *));
+bfd_signed_vma bfd_getl_signed_16 PARAMS ((const unsigned char *));
+void bfd_putb64 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl64 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putb32 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl32 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putb16 PARAMS ((bfd_vma, unsigned char *));
+void bfd_putl16 PARAMS ((bfd_vma, unsigned char *));
+
+/* Externally visible ECOFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct symbol_cache_entry;
+struct bfd_link_info;
+struct bfd_link_hash_entry;
+struct bfd_elf_version_tree;
+#endif
+extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd));
+extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value));
+extern boolean bfd_ecoff_set_regmasks
+ PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+ unsigned long *cprmask));
+extern PTR bfd_ecoff_debug_init
+ PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap,
+ struct bfd_link_info *));
+extern void bfd_ecoff_debug_free
+ PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap,
+ struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_accumulate
+ PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap,
+ bfd *input_bfd, struct ecoff_debug_info *input_debug,
+ const struct ecoff_debug_swap *input_swap,
+ struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_accumulate_other
+ PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, bfd *input_bfd,
+ struct bfd_link_info *));
+extern boolean bfd_ecoff_debug_externals
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ boolean relocateable,
+ boolean (*get_extr) (struct symbol_cache_entry *,
+ struct ecoff_extr *),
+ void (*set_index) (struct symbol_cache_entry *,
+ bfd_size_type)));
+extern boolean bfd_ecoff_debug_one_external
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ const char *name, struct ecoff_extr *esym));
+extern bfd_size_type bfd_ecoff_debug_size
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap));
+extern boolean bfd_ecoff_write_debug
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, file_ptr where));
+extern boolean bfd_ecoff_write_accumulated_debug
+ PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ struct bfd_link_info *info, file_ptr where));
+extern boolean bfd_mips_ecoff_create_embedded_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+ char **));
+
+/* Externally visible ELF routines. */
+
+struct bfd_link_needed_list
+{
+ struct bfd_link_needed_list *next;
+ bfd *by;
+ const char *name;
+};
+
+extern boolean bfd_elf32_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean));
+extern boolean bfd_elf64_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean));
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_elf_get_bfd_needed_list
+ PARAMS ((bfd *, struct bfd_link_needed_list **));
+extern boolean bfd_elf32_size_dynamic_sections
+ PARAMS ((bfd *, const char *, const char *, boolean, const char *,
+ const char * const *, struct bfd_link_info *, struct sec **,
+ struct bfd_elf_version_tree *));
+extern boolean bfd_elf64_size_dynamic_sections
+ PARAMS ((bfd *, const char *, const char *, boolean, const char *,
+ const char * const *, struct bfd_link_info *, struct sec **,
+ struct bfd_elf_version_tree *));
+extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
+extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
+
+/* SunOS shared library support routines for the linker. */
+
+extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_sunos_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern boolean bfd_sunos_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *, struct sec **, struct sec **,
+ struct sec **));
+
+/* Linux shared library support routines for the linker. */
+
+extern boolean bfd_i386linux_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_m68klinux_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_sparclinux_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* mmap hacks */
+
+struct _bfd_window_internal;
+typedef struct _bfd_window_internal bfd_window_internal;
+
+typedef struct _bfd_window {
+ /* What the user asked for. */
+ PTR data;
+ bfd_size_type size;
+ /* The actual window used by BFD. Small user-requested read-only
+ regions sharing a page may share a single window into the object
+ file. Read-write versions shouldn't until I've fixed things to
+ keep track of which portions have been claimed by the
+ application; don't want to give the same region back when the
+ application wants two writable copies! */
+ struct _bfd_window_internal *i;
+} bfd_window;
+
+extern void bfd_init_window PARAMS ((bfd_window *));
+extern void bfd_free_window PARAMS ((bfd_window *));
+extern boolean bfd_get_file_window
+ PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, boolean));
+
+/* XCOFF support routines for the linker. */
+
+extern boolean bfd_xcoff_link_record_set
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+ bfd_size_type));
+extern boolean bfd_xcoff_import_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+ bfd_vma, const char *, const char *, const char *));
+extern boolean bfd_xcoff_export_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *,
+ boolean));
+extern boolean bfd_xcoff_link_count_reloc
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern boolean bfd_xcoff_record_link_assignment
+ PARAMS ((bfd *, struct bfd_link_info *, const char *));
+extern boolean bfd_xcoff_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *,
+ unsigned long, unsigned long, unsigned long, boolean,
+ int, boolean, boolean, struct sec **));
+
+/* Externally visible COFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct internal_syment;
+union internal_auxent;
+#endif
+
+extern boolean bfd_coff_get_syment
+ PARAMS ((bfd *, struct symbol_cache_entry *, struct internal_syment *));
+
+extern boolean bfd_coff_get_auxent
+ PARAMS ((bfd *, struct symbol_cache_entry *, int, union internal_auxent *));
+
+extern boolean bfd_coff_set_symbol_class
+ PARAMS ((bfd *, struct symbol_cache_entry *, unsigned int));
+
+/* ARM Interworking support. Called from linker. */
+extern boolean bfd_arm_allocate_interworking_sections
+ PARAMS ((struct bfd_link_info *));
+
+extern boolean bfd_arm_process_before_allocation
+ PARAMS ((bfd *, struct bfd_link_info *, int));
+
+extern boolean bfd_arm_get_bfd_for_interworking
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* ELF ARM Interworking support. Called from linker. */
+ extern boolean bfd_elf32_arm_allocate_interworking_sections
+ PARAMS ((struct bfd_link_info *));
+
+ extern boolean bfd_elf32_arm_process_before_allocation
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+ extern boolean bfd_elf32_arm_get_bfd_for_interworking
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* And more from the source. */
+void
+bfd_init PARAMS ((void));
+
+bfd *
+bfd_openr PARAMS ((CONST char *filename, CONST char *target));
+
+bfd *
+bfd_fdopenr PARAMS ((CONST char *filename, CONST char *target, int fd));
+
+bfd *
+bfd_openstreamr PARAMS ((const char *, const char *, PTR));
+
+bfd *
+bfd_openw PARAMS ((CONST char *filename, CONST char *target));
+
+boolean
+bfd_close PARAMS ((bfd *abfd));
+
+boolean
+bfd_close_all_done PARAMS ((bfd *));
+
+bfd *
+bfd_create PARAMS ((CONST char *filename, bfd *templ));
+
+boolean
+bfd_make_writable PARAMS ((bfd *abfd));
+
+boolean
+bfd_make_readable PARAMS ((bfd *abfd));
+
+
+ /* Byte swapping macros for user section data. */
+
+#define bfd_put_8(abfd, val, ptr) \
+ (*((unsigned char *)(ptr)) = (unsigned char)(val))
+#define bfd_put_signed_8 \
+ bfd_put_8
+#define bfd_get_8(abfd, ptr) \
+ (*(unsigned char *)(ptr))
+#define bfd_get_signed_8(abfd, ptr) \
+ ((*(unsigned char *)(ptr) ^ 0x80) - 0x80)
+
+#define bfd_put_16(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
+#define bfd_put_signed_16 \
+ bfd_put_16
+#define bfd_get_16(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx16, (ptr))
+#define bfd_get_signed_16(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
+
+#define bfd_put_32(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
+#define bfd_put_signed_32 \
+ bfd_put_32
+#define bfd_get_32(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx32, (ptr))
+#define bfd_get_signed_32(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
+
+#define bfd_put_64(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
+#define bfd_put_signed_64 \
+ bfd_put_64
+#define bfd_get_64(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx64, (ptr))
+#define bfd_get_signed_64(abfd, ptr) \
+ BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
+
+
+ /* Byte swapping macros for file header data. */
+
+#define bfd_h_put_8(abfd, val, ptr) \
+ bfd_put_8 (abfd, val, ptr)
+#define bfd_h_put_signed_8(abfd, val, ptr) \
+ bfd_put_8 (abfd, val, ptr)
+#define bfd_h_get_8(abfd, ptr) \
+ bfd_get_8 (abfd, ptr)
+#define bfd_h_get_signed_8(abfd, ptr) \
+ bfd_get_signed_8 (abfd, ptr)
+
+#define bfd_h_put_16(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
+#define bfd_h_put_signed_16 \
+ bfd_h_put_16
+#define bfd_h_get_16(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx16,(ptr))
+#define bfd_h_get_signed_16(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
+
+#define bfd_h_put_32(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
+#define bfd_h_put_signed_32 \
+ bfd_h_put_32
+#define bfd_h_get_32(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx32,(ptr))
+#define bfd_h_get_signed_32(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
+
+#define bfd_h_put_64(abfd, val, ptr) \
+ BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
+#define bfd_h_put_signed_64 \
+ bfd_h_put_64
+#define bfd_h_get_64(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx64,(ptr))
+#define bfd_h_get_signed_64(abfd, ptr) \
+ BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
+
+typedef struct sec
+{
+ /* The name of the section; the name isn't a copy, the pointer is
+ the same as that passed to bfd_make_section. */
+
+ CONST char *name;
+
+ /* Which section is it; 0..nth. */
+
+ int index;
+
+ /* The next section in the list belonging to the BFD, or NULL. */
+
+ struct sec *next;
+
+ /* The field flags contains attributes of the section. Some
+ flags are read in from the object file, and some are
+ synthesized from other information. */
+
+ flagword flags;
+
+#define SEC_NO_FLAGS 0x000
+
+ /* Tells the OS to allocate space for this section when loading.
+ This is clear for a section containing debug information
+ only. */
+#define SEC_ALLOC 0x001
+
+ /* Tells the OS to load the section from the file when loading.
+ This is clear for a .bss section. */
+#define SEC_LOAD 0x002
+
+ /* The section contains data still to be relocated, so there is
+ some relocation information too. */
+#define SEC_RELOC 0x004
+
+#if 0 /* Obsolete ? */
+#define SEC_BALIGN 0x008
+#endif
+
+ /* A signal to the OS that the section contains read only
+ data. */
+#define SEC_READONLY 0x010
+
+ /* The section contains code only. */
+#define SEC_CODE 0x020
+
+ /* The section contains data only. */
+#define SEC_DATA 0x040
+
+ /* The section will reside in ROM. */
+#define SEC_ROM 0x080
+
+ /* The section contains constructor information. This section
+ type is used by the linker to create lists of constructors and
+ destructors used by <<g++>>. When a back end sees a symbol
+ which should be used in a constructor list, it creates a new
+ section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+ the symbol to it, and builds a relocation. To build the lists
+ of constructors, all the linker has to do is catenate all the
+ sections called <<__CTOR_LIST__>> and relocate the data
+ contained within - exactly the operations it would peform on
+ standard data. */
+#define SEC_CONSTRUCTOR 0x100
+
+ /* The section is a constructor, and should be placed at the
+ end of the text, data, or bss section(?). */
+#define SEC_CONSTRUCTOR_TEXT 0x1100
+#define SEC_CONSTRUCTOR_DATA 0x2100
+#define SEC_CONSTRUCTOR_BSS 0x3100
+
+ /* The section has contents - a data section could be
+ <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
+ <<SEC_HAS_CONTENTS>> */
+#define SEC_HAS_CONTENTS 0x200
+
+ /* An instruction to the linker to not output the section
+ even if it has information which would normally be written. */
+#define SEC_NEVER_LOAD 0x400
+
+ /* The section is a COFF shared library section. This flag is
+ only for the linker. If this type of section appears in
+ the input file, the linker must copy it to the output file
+ without changing the vma or size. FIXME: Although this
+ was originally intended to be general, it really is COFF
+ specific (and the flag was renamed to indicate this). It
+ might be cleaner to have some more general mechanism to
+ allow the back end to control what the linker does with
+ sections. */
+#define SEC_COFF_SHARED_LIBRARY 0x800
+
+ /* The section contains common symbols (symbols may be defined
+ multiple times, the value of a symbol is the amount of
+ space it requires, and the largest symbol value is the one
+ used). Most targets have exactly one of these (which we
+ translate to bfd_com_section_ptr), but ECOFF has two. */
+#define SEC_IS_COMMON 0x8000
+
+ /* The section contains only debugging information. For
+ example, this is set for ELF .debug and .stab sections.
+ strip tests this flag to see if a section can be
+ discarded. */
+#define SEC_DEBUGGING 0x10000
+
+ /* The contents of this section are held in memory pointed to
+ by the contents field. This is checked by
+ bfd_get_section_contents, and the data is retrieved from
+ memory if appropriate. */
+#define SEC_IN_MEMORY 0x20000
+
+ /* The contents of this section are to be excluded by the
+ linker for executable and shared objects unless those
+ objects are to be further relocated. */
+#define SEC_EXCLUDE 0x40000
+
+ /* The contents of this section are to be sorted by the
+ based on the address specified in the associated symbol
+ table. */
+#define SEC_SORT_ENTRIES 0x80000
+
+ /* When linking, duplicate sections of the same name should be
+ discarded, rather than being combined into a single section as
+ is usually done. This is similar to how common symbols are
+ handled. See SEC_LINK_DUPLICATES below. */
+#define SEC_LINK_ONCE 0x100000
+
+ /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+ should handle duplicate sections. */
+#define SEC_LINK_DUPLICATES 0x600000
+
+ /* This value for SEC_LINK_DUPLICATES means that duplicate
+ sections with the same name should simply be discarded. */
+#define SEC_LINK_DUPLICATES_DISCARD 0x0
+
+ /* This value for SEC_LINK_DUPLICATES means that the linker
+ should warn if there are any duplicate sections, although
+ it should still only link one copy. */
+#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000
+
+ /* This value for SEC_LINK_DUPLICATES means that the linker
+ should warn if any duplicate sections are a different size. */
+#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000
+
+ /* This value for SEC_LINK_DUPLICATES means that the linker
+ should warn if any duplicate sections contain different
+ contents. */
+#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
+
+ /* This section was created by the linker as part of dynamic
+ relocation or other arcane processing. It is skipped when
+ going through the first-pass output, trusting that someone
+ else up the line will take care of it later. */
+#define SEC_LINKER_CREATED 0x800000
+
+ /* This section should not be subject to garbage collection. */
+#define SEC_KEEP 0x1000000
+
+ /* End of section flags. */
+
+ /* Some internal packed boolean fields. */
+
+ /* See the vma field. */
+ unsigned int user_set_vma : 1;
+
+ /* Whether relocations have been processed. */
+ unsigned int reloc_done : 1;
+
+ /* A mark flag used by some of the linker backends. */
+ unsigned int linker_mark : 1;
+
+ /* A mark flag used by some linker backends for garbage collection. */
+ unsigned int gc_mark : 1;
+
+ /* End of internal packed boolean fields. */
+
+ /* The virtual memory address of the section - where it will be
+ at run time. The symbols are relocated against this. The
+ user_set_vma flag is maintained by bfd; if it's not set, the
+ backend can assign addresses (for example, in <<a.out>>, where
+ the default address for <<.data>> is dependent on the specific
+ target and various flags). */
+
+ bfd_vma vma;
+
+ /* The load address of the section - where it would be in a
+ rom image; really only used for writing section header
+ information. */
+
+ bfd_vma lma;
+
+ /* The size of the section in bytes, as it will be output.
+ contains a value even if the section has no contents (e.g., the
+ size of <<.bss>>). This will be filled in after relocation */
+
+ bfd_size_type _cooked_size;
+
+ /* The original size on disk of the section, in bytes. Normally this
+ value is the same as the size, but if some relaxing has
+ been done, then this value will be bigger. */
+
+ bfd_size_type _raw_size;
+
+ /* If this section is going to be output, then this value is the
+ offset into the output section of the first byte in the input
+ section. E.g., if this was going to start at the 100th byte in
+ the output section, this value would be 100. */
+
+ bfd_vma output_offset;
+
+ /* The output section through which to map on output. */
+
+ struct sec *output_section;
+
+ /* The alignment requirement of the section, as an exponent of 2 -
+ e.g., 3 aligns to 2^3 (or 8). */
+
+ unsigned int alignment_power;
+
+ /* If an input section, a pointer to a vector of relocation
+ records for the data in this section. */
+
+ struct reloc_cache_entry *relocation;
+
+ /* If an output section, a pointer to a vector of pointers to
+ relocation records for the data in this section. */
+
+ struct reloc_cache_entry **orelocation;
+
+ /* The number of relocation records in one of the above */
+
+ unsigned reloc_count;
+
+ /* Information below is back end specific - and not always used
+ or updated. */
+
+ /* File position of section data */
+
+ file_ptr filepos;
+
+ /* File position of relocation info */
+
+ file_ptr rel_filepos;
+
+ /* File position of line data */
+
+ file_ptr line_filepos;
+
+ /* Pointer to data for applications */
+
+ PTR userdata;
+
+ /* If the SEC_IN_MEMORY flag is set, this points to the actual
+ contents. */
+ unsigned char *contents;
+
+ /* Attached line number information */
+
+ alent *lineno;
+
+ /* Number of line number records */
+
+ unsigned int lineno_count;
+
+ /* When a section is being output, this value changes as more
+ linenumbers are written out */
+
+ file_ptr moving_line_filepos;
+
+ /* What the section number is in the target world */
+
+ int target_index;
+
+ PTR used_by_bfd;
+
+ /* If this is a constructor section then here is a list of the
+ relocations created to relocate items within it. */
+
+ struct relent_chain *constructor_chain;
+
+ /* The BFD which owns the section. */
+
+ bfd *owner;
+
+ /* A symbol which points at this section only */
+ struct symbol_cache_entry *symbol;
+ struct symbol_cache_entry **symbol_ptr_ptr;
+
+ struct bfd_link_order *link_order_head;
+ struct bfd_link_order *link_order_tail;
+} asection ;
+
+ /* These sections are global, and are managed by BFD. The application
+ and target back end are not permitted to change the values in
+ these sections. New code should use the section_ptr macros rather
+ than referring directly to the const sections. The const sections
+ may eventually vanish. */
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+#define BFD_IND_SECTION_NAME "*IND*"
+
+ /* the absolute section */
+extern const asection bfd_abs_section;
+#define bfd_abs_section_ptr ((asection *) &bfd_abs_section)
+#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+ /* Pointer to the undefined section */
+extern const asection bfd_und_section;
+#define bfd_und_section_ptr ((asection *) &bfd_und_section)
+#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+ /* Pointer to the common section */
+extern const asection bfd_com_section;
+#define bfd_com_section_ptr ((asection *) &bfd_com_section)
+ /* Pointer to the indirect section */
+extern const asection bfd_ind_section;
+#define bfd_ind_section_ptr ((asection *) &bfd_ind_section)
+#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+
+extern const struct symbol_cache_entry * const bfd_abs_symbol;
+extern const struct symbol_cache_entry * const bfd_com_symbol;
+extern const struct symbol_cache_entry * const bfd_und_symbol;
+extern const struct symbol_cache_entry * const bfd_ind_symbol;
+#define bfd_get_section_size_before_reloc(section) \
+ (section->reloc_done ? (abort(),1): (section)->_raw_size)
+#define bfd_get_section_size_after_reloc(section) \
+ ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
+asection *
+bfd_get_section_by_name PARAMS ((bfd *abfd, CONST char *name));
+
+asection *
+bfd_make_section_old_way PARAMS ((bfd *abfd, CONST char *name));
+
+asection *
+bfd_make_section_anyway PARAMS ((bfd *abfd, CONST char *name));
+
+asection *
+bfd_make_section PARAMS ((bfd *, CONST char *name));
+
+boolean
+bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags));
+
+void
+bfd_map_over_sections PARAMS ((bfd *abfd,
+ void (*func)(bfd *abfd,
+ asection *sect,
+ PTR obj),
+ PTR obj));
+
+boolean
+bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val));
+
+boolean
+bfd_set_section_contents
+ PARAMS ((bfd *abfd,
+ asection *section,
+ PTR data,
+ file_ptr offset,
+ bfd_size_type count));
+
+boolean
+bfd_get_section_contents
+ PARAMS ((bfd *abfd, asection *section, PTR location,
+ file_ptr offset, bfd_size_type count));
+
+boolean
+bfd_copy_private_section_data PARAMS ((bfd *ibfd, asection *isec, bfd *obfd, asection *osec));
+
+#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+ BFD_SEND (obfd, _bfd_copy_private_section_data, \
+ (ibfd, isection, obfd, osection))
+void
+_bfd_strip_section_from_output
+ PARAMS ((asection *section));
+
+enum bfd_architecture
+{
+ bfd_arch_unknown, /* File arch not known */
+ bfd_arch_obscure, /* Arch known, not one of these */
+ bfd_arch_m68k, /* Motorola 68xxx */
+#define bfd_mach_m68000 1
+#define bfd_mach_m68008 2
+#define bfd_mach_m68010 3
+#define bfd_mach_m68020 4
+#define bfd_mach_m68030 5
+#define bfd_mach_m68040 6
+#define bfd_mach_m68060 7
+#define bfd_mach_cpu32 8
+ bfd_arch_vax, /* DEC Vax */
+ bfd_arch_i960, /* Intel 960 */
+ /* The order of the following is important.
+ lower number indicates a machine type that
+ only accepts a subset of the instructions
+ available to machines with higher numbers.
+ The exception is the "ca", which is
+ incompatible with all other machines except
+ "core". */
+
+#define bfd_mach_i960_core 1
+#define bfd_mach_i960_ka_sa 2
+#define bfd_mach_i960_kb_sb 3
+#define bfd_mach_i960_mc 4
+#define bfd_mach_i960_xa 5
+#define bfd_mach_i960_ca 6
+#define bfd_mach_i960_jx 7
+#define bfd_mach_i960_hx 8
+
+ bfd_arch_a29k, /* AMD 29000 */
+ bfd_arch_sparc, /* SPARC */
+#define bfd_mach_sparc 1
+ /* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
+#define bfd_mach_sparc_sparclet 2
+#define bfd_mach_sparc_sparclite 3
+#define bfd_mach_sparc_v8plus 4
+#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns */
+#define bfd_mach_sparc_sparclite_le 6
+#define bfd_mach_sparc_v9 7
+#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns */
+ /* Nonzero if MACH has the v9 instruction set. */
+#define bfd_mach_sparc_v9_p(mach) \
+ ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9a)
+ bfd_arch_mips, /* MIPS Rxxxx */
+#define bfd_mach_mips3000 3000
+#define bfd_mach_mips3900 3900
+#define bfd_mach_mips4000 4000
+#define bfd_mach_mips4010 4010
+#define bfd_mach_mips4100 4100
+#define bfd_mach_mips4111 4111
+#define bfd_mach_mips4300 4300
+#define bfd_mach_mips4400 4400
+#define bfd_mach_mips4600 4600
+#define bfd_mach_mips4650 4650
+#define bfd_mach_mips5000 5000
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips16 16
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_i386 0
+#define bfd_mach_i386_i8086 1
+#define bfd_mach_i386_i386_intel_syntax 2
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_alliant, /* Alliant */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Hitachi H8/300 */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+ bfd_arch_powerpc, /* PowerPC */
+ bfd_arch_rs6000, /* IBM RS/6000 */
+ bfd_arch_hppa, /* HP PA RISC */
+ bfd_arch_d10v, /* Mitsubishi D10V */
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Hitachi H8/500 */
+ bfd_arch_sh, /* Hitachi SH */
+#define bfd_mach_sh 0
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3e 0x3e
+ bfd_arch_alpha, /* Dec Alpha */
+#define bfd_mach_alpha_ev4 0x10
+#define bfd_mach_alpha_ev5 0x20
+#define bfd_mach_alpha_ev6 0x30
+ bfd_arch_arm, /* Advanced Risc Machines ARM */
+#define bfd_mach_arm_2 1
+#define bfd_mach_arm_2a 2
+#define bfd_mach_arm_3 3
+#define bfd_mach_arm_3M 4
+#define bfd_mach_arm_4 5
+#define bfd_mach_arm_4T 6
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+#define bfd_mach_v850 0
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850ea 'A'
+ bfd_arch_arc, /* Argonaut RISC Core */
+#define bfd_mach_arc_base 0
+ bfd_arch_m32r, /* Mitsubishi M32R/D */
+#define bfd_mach_m32r 0 /* backwards compatibility */
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_mcore,
+ bfd_arch_last
+ };
+
+typedef struct bfd_arch_info
+{
+ int bits_per_word;
+ int bits_per_address;
+ int bits_per_byte;
+ enum bfd_architecture arch;
+ unsigned long mach;
+ const char *arch_name;
+ const char *printable_name;
+ unsigned int section_align_power;
+ /* true if this is the default machine for the architecture */
+ boolean the_default;
+ const struct bfd_arch_info * (*compatible)
+ PARAMS ((const struct bfd_arch_info *a,
+ const struct bfd_arch_info *b));
+
+ boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *));
+
+ const struct bfd_arch_info *next;
+} bfd_arch_info_type;
+const char *
+bfd_printable_name PARAMS ((bfd *abfd));
+
+const bfd_arch_info_type *
+bfd_scan_arch PARAMS ((const char *string));
+
+const char **
+bfd_arch_list PARAMS ((void));
+
+const bfd_arch_info_type *
+bfd_arch_get_compatible PARAMS ((
+ const bfd *abfd,
+ const bfd *bbfd));
+
+void
+bfd_set_arch_info PARAMS ((bfd *abfd, const bfd_arch_info_type *arg));
+
+enum bfd_architecture
+bfd_get_arch PARAMS ((bfd *abfd));
+
+unsigned long
+bfd_get_mach PARAMS ((bfd *abfd));
+
+unsigned int
+bfd_arch_bits_per_byte PARAMS ((bfd *abfd));
+
+unsigned int
+bfd_arch_bits_per_address PARAMS ((bfd *abfd));
+
+const bfd_arch_info_type *
+bfd_get_arch_info PARAMS ((bfd *abfd));
+
+const bfd_arch_info_type *
+bfd_lookup_arch
+ PARAMS ((enum bfd_architecture
+ arch,
+ unsigned long machine));
+
+const char *
+bfd_printable_arch_mach
+ PARAMS ((enum bfd_architecture arch, unsigned long machine));
+
+typedef enum bfd_reloc_status
+{
+ /* No errors detected */
+ bfd_reloc_ok,
+
+ /* The relocation was performed, but there was an overflow. */
+ bfd_reloc_overflow,
+
+ /* The address to relocate was not within the section supplied. */
+ bfd_reloc_outofrange,
+
+ /* Used by special functions */
+ bfd_reloc_continue,
+
+ /* Unsupported relocation size requested. */
+ bfd_reloc_notsupported,
+
+ /* Unused */
+ bfd_reloc_other,
+
+ /* The symbol to relocate against was undefined. */
+ bfd_reloc_undefined,
+
+ /* The relocation was performed, but may not be ok - presently
+ generated only when linking i960 coff files with i960 b.out
+ symbols. If this type is returned, the error_message argument
+ to bfd_perform_relocation will be set. */
+ bfd_reloc_dangerous
+ }
+ bfd_reloc_status_type;
+
+
+typedef struct reloc_cache_entry
+{
+ /* A pointer into the canonical table of pointers */
+ struct symbol_cache_entry **sym_ptr_ptr;
+
+ /* offset in section */
+ bfd_size_type address;
+
+ /* addend for relocation value */
+ bfd_vma addend;
+
+ /* Pointer to how to perform the required relocation */
+ reloc_howto_type *howto;
+
+} arelent;
+enum complain_overflow
+{
+ /* Do not complain on overflow. */
+ complain_overflow_dont,
+
+ /* Complain if the bitfield overflows, whether it is considered
+ as signed or unsigned. */
+ complain_overflow_bitfield,
+
+ /* Complain if the value overflows when considered as signed
+ number. */
+ complain_overflow_signed,
+
+ /* Complain if the value overflows when considered as an
+ unsigned number. */
+ complain_overflow_unsigned
+};
+
+struct reloc_howto_struct
+{
+ /* The type field has mainly a documentary use - the back end can
+ do what it wants with it, though normally the back end's
+ external idea of what a reloc number is stored
+ in this field. For example, a PC relative word relocation
+ in a coff environment has the type 023 - because that's
+ what the outside world calls a R_PCRWORD reloc. */
+ unsigned int type;
+
+ /* The value the final relocation is shifted right by. This drops
+ unwanted data from the relocation. */
+ unsigned int rightshift;
+
+ /* The size of the item to be relocated. This is *not* a
+ power-of-two measure. To get the number of bytes operated
+ on by a type of relocation, use bfd_get_reloc_size. */
+ int size;
+
+ /* The number of bits in the item to be relocated. This is used
+ when doing overflow checking. */
+ unsigned int bitsize;
+
+ /* Notes that the relocation is relative to the location in the
+ data section of the addend. The relocation function will
+ subtract from the relocation value the address of the location
+ being relocated. */
+ boolean pc_relative;
+
+ /* The bit position of the reloc value in the destination.
+ The relocated value is left shifted by this amount. */
+ unsigned int bitpos;
+
+ /* What type of overflow error should be checked for when
+ relocating. */
+ enum complain_overflow complain_on_overflow;
+
+ /* If this field is non null, then the supplied function is
+ called rather than the normal function. This allows really
+ strange relocation methods to be accomodated (e.g., i960 callj
+ instructions). */
+ bfd_reloc_status_type (*special_function)
+ PARAMS ((bfd *abfd,
+ arelent *reloc_entry,
+ struct symbol_cache_entry *symbol,
+ PTR data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message));
+
+ /* The textual name of the relocation type. */
+ char *name;
+
+ /* When performing a partial link, some formats must modify the
+ relocations rather than the data - this flag signals this.*/
+ boolean partial_inplace;
+
+ /* The src_mask selects which parts of the read in data
+ are to be used in the relocation sum. E.g., if this was an 8 bit
+ bit of data which we read and relocated, this would be
+ 0x000000ff. When we have relocs which have an addend, such as
+ sun4 extended relocs, the value in the offset part of a
+ relocating field is garbage so we never use it. In this case
+ the mask would be 0x00000000. */
+ bfd_vma src_mask;
+
+ /* The dst_mask selects which parts of the instruction are replaced
+ into the instruction. In most cases src_mask == dst_mask,
+ except in the above special case, where dst_mask would be
+ 0x000000ff, and src_mask would be 0x00000000. */
+ bfd_vma dst_mask;
+
+ /* When some formats create PC relative instructions, they leave
+ the value of the pc of the place being relocated in the offset
+ slot of the instruction, so that a PC relative relocation can
+ be made just by adding in an ordinary offset (e.g., sun3 a.out).
+ Some formats leave the displacement part of an instruction
+ empty (e.g., m88k bcs); this flag signals the fact.*/
+ boolean pcrel_offset;
+
+};
+#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+ {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
+
+#define HOWTO_PREPARE(relocation, symbol) \
+ { \
+ if (symbol != (asymbol *)NULL) { \
+ if (bfd_is_com_section (symbol->section)) { \
+ relocation = 0; \
+ } \
+ else { \
+ relocation = symbol->value; \
+ } \
+ } \
+}
+unsigned int
+bfd_get_reloc_size PARAMS ((reloc_howto_type *));
+
+typedef struct relent_chain {
+ arelent relent;
+ struct relent_chain *next;
+} arelent_chain;
+bfd_reloc_status_type
+
+bfd_check_overflow
+ PARAMS ((enum complain_overflow how,
+ unsigned int bitsize,
+ unsigned int rightshift,
+ unsigned int addrsize,
+ bfd_vma relocation));
+
+bfd_reloc_status_type
+
+bfd_perform_relocation
+ PARAMS ((bfd *abfd,
+ arelent *reloc_entry,
+ PTR data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message));
+
+bfd_reloc_status_type
+
+bfd_install_relocation
+ PARAMS ((bfd *abfd,
+ arelent *reloc_entry,
+ PTR data, bfd_vma data_start,
+ asection *input_section,
+ char **error_message));
+
+enum bfd_reloc_code_real {
+ _dummy_first_bfd_reloc_code_real,
+
+
+/* Basic absolute relocations of N bits. */
+ BFD_RELOC_64,
+ BFD_RELOC_32,
+ BFD_RELOC_26,
+ BFD_RELOC_24,
+ BFD_RELOC_16,
+ BFD_RELOC_14,
+ BFD_RELOC_8,
+
+/* PC-relative relocations. Sometimes these are relative to the address
+of the relocation itself; sometimes they are relative to the start of
+the section containing the relocation. It depends on the specific target.
+
+The 24-bit relocation is used in some Intel 960 configurations. */
+ BFD_RELOC_64_PCREL,
+ BFD_RELOC_32_PCREL,
+ BFD_RELOC_24_PCREL,
+ BFD_RELOC_16_PCREL,
+ BFD_RELOC_12_PCREL,
+ BFD_RELOC_8_PCREL,
+
+/* For ELF. */
+ BFD_RELOC_32_GOT_PCREL,
+ BFD_RELOC_16_GOT_PCREL,
+ BFD_RELOC_8_GOT_PCREL,
+ BFD_RELOC_32_GOTOFF,
+ BFD_RELOC_16_GOTOFF,
+ BFD_RELOC_LO16_GOTOFF,
+ BFD_RELOC_HI16_GOTOFF,
+ BFD_RELOC_HI16_S_GOTOFF,
+ BFD_RELOC_8_GOTOFF,
+ BFD_RELOC_32_PLT_PCREL,
+ BFD_RELOC_24_PLT_PCREL,
+ BFD_RELOC_16_PLT_PCREL,
+ BFD_RELOC_8_PLT_PCREL,
+ BFD_RELOC_32_PLTOFF,
+ BFD_RELOC_16_PLTOFF,
+ BFD_RELOC_LO16_PLTOFF,
+ BFD_RELOC_HI16_PLTOFF,
+ BFD_RELOC_HI16_S_PLTOFF,
+ BFD_RELOC_8_PLTOFF,
+
+/* Relocations used by 68K ELF. */
+ BFD_RELOC_68K_GLOB_DAT,
+ BFD_RELOC_68K_JMP_SLOT,
+ BFD_RELOC_68K_RELATIVE,
+
+/* Linkage-table relative. */
+ BFD_RELOC_32_BASEREL,
+ BFD_RELOC_16_BASEREL,
+ BFD_RELOC_LO16_BASEREL,
+ BFD_RELOC_HI16_BASEREL,
+ BFD_RELOC_HI16_S_BASEREL,
+ BFD_RELOC_8_BASEREL,
+ BFD_RELOC_RVA,
+
+/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */
+ BFD_RELOC_8_FFnn,
+
+/* These PC-relative relocations are stored as word displacements --
+i.e., byte displacements shifted right two bits. The 30-bit word
+displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the
+SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The
+signed 16-bit displacement is used on the MIPS, and the 23-bit
+displacement is used on the Alpha. */
+ BFD_RELOC_32_PCREL_S2,
+ BFD_RELOC_16_PCREL_S2,
+ BFD_RELOC_23_PCREL_S2,
+
+/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of
+the target word. These are used on the SPARC. */
+ BFD_RELOC_HI22,
+ BFD_RELOC_LO10,
+
+/* For systems that allocate a Global Pointer register, these are
+displacements off that register. These relocation types are
+handled specially, because the value the register will have is
+decided relatively late. */
+ BFD_RELOC_GPREL16,
+ BFD_RELOC_GPREL32,
+
+/* Reloc types used for i960/b.out. */
+ BFD_RELOC_I960_CALLJ,
+
+/* SPARC ELF relocations. There is probably some overlap with other
+relocation types already defined. */
+ BFD_RELOC_NONE,
+ BFD_RELOC_SPARC_WDISP22,
+ BFD_RELOC_SPARC22,
+ BFD_RELOC_SPARC13,
+ BFD_RELOC_SPARC_GOT10,
+ BFD_RELOC_SPARC_GOT13,
+ BFD_RELOC_SPARC_GOT22,
+ BFD_RELOC_SPARC_PC10,
+ BFD_RELOC_SPARC_PC22,
+ BFD_RELOC_SPARC_WPLT30,
+ BFD_RELOC_SPARC_COPY,
+ BFD_RELOC_SPARC_GLOB_DAT,
+ BFD_RELOC_SPARC_JMP_SLOT,
+ BFD_RELOC_SPARC_RELATIVE,
+ BFD_RELOC_SPARC_UA32,
+
+/* I think these are specific to SPARC a.out (e.g., Sun 4). */
+ BFD_RELOC_SPARC_BASE13,
+ BFD_RELOC_SPARC_BASE22,
+
+/* SPARC64 relocations */
+#define BFD_RELOC_SPARC_64 BFD_RELOC_64
+ BFD_RELOC_SPARC_10,
+ BFD_RELOC_SPARC_11,
+ BFD_RELOC_SPARC_OLO10,
+ BFD_RELOC_SPARC_HH22,
+ BFD_RELOC_SPARC_HM10,
+ BFD_RELOC_SPARC_LM22,
+ BFD_RELOC_SPARC_PC_HH22,
+ BFD_RELOC_SPARC_PC_HM10,
+ BFD_RELOC_SPARC_PC_LM22,
+ BFD_RELOC_SPARC_WDISP16,
+ BFD_RELOC_SPARC_WDISP19,
+ BFD_RELOC_SPARC_7,
+ BFD_RELOC_SPARC_6,
+ BFD_RELOC_SPARC_5,
+#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL
+ BFD_RELOC_SPARC_PLT64,
+ BFD_RELOC_SPARC_HIX22,
+ BFD_RELOC_SPARC_LOX10,
+ BFD_RELOC_SPARC_H44,
+ BFD_RELOC_SPARC_M44,
+ BFD_RELOC_SPARC_L44,
+ BFD_RELOC_SPARC_REGISTER,
+
+/* SPARC little endian relocation */
+ BFD_RELOC_SPARC_REV32,
+
+/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or
+"addend" in some special way.
+For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+writing; when reading, it will be the absolute section symbol. The
+addend is the displacement in bytes of the "lda" instruction from
+the "ldah" instruction (which is at the address of this reloc). */
+ BFD_RELOC_ALPHA_GPDISP_HI16,
+
+/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+with GPDISP_HI16 relocs. The addend is ignored when writing the
+relocations out, and is filled in with the file's GP value on
+reading, for convenience. */
+ BFD_RELOC_ALPHA_GPDISP_LO16,
+
+/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+relocation except that there is no accompanying GPDISP_LO16
+relocation. */
+ BFD_RELOC_ALPHA_GPDISP,
+
+/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+the assembler turns it into a LDQ instruction to load the address of
+the symbol, and then fills in a register in the real instruction.
+
+The LITERAL reloc, at the LDQ instruction, refers to the .lita
+section symbol. The addend is ignored when writing, but is filled
+in with the file's GP value on reading, for convenience, as with the
+GPDISP_LO16 reloc.
+
+The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16.
+It should refer to the symbol to be referenced, as with 16_GOTOFF,
+but it generates output not based on the position within the .got
+section, but relative to the GP value chosen for the file during the
+final link stage.
+
+The LITUSE reloc, on the instruction using the loaded address, gives
+information to the linker that it might be able to use to optimize
+away some literal section references. The symbol is ignored (read
+as the absolute section symbol), and the "addend" indicates the type
+of instruction using the register:
+1 - "memory" fmt insn
+2 - byte-manipulation (byte offset reg)
+3 - jsr (target of branch)
+
+The GNU linker currently doesn't do any of this optimizing. */
+ BFD_RELOC_ALPHA_LITERAL,
+ BFD_RELOC_ALPHA_ELF_LITERAL,
+ BFD_RELOC_ALPHA_LITUSE,
+
+/* The HINT relocation indicates a value that should be filled into the
+"hint" field of a jmp/jsr/ret instruction, for possible branch-
+prediction logic which may be provided on some processors. */
+ BFD_RELOC_ALPHA_HINT,
+
+/* The LINKAGE relocation outputs a linkage pair in the object file,
+which is filled by the linker. */
+ BFD_RELOC_ALPHA_LINKAGE,
+
+/* The CODEADDR relocation outputs a STO_CA in the object file,
+which is filled by the linker. */
+ BFD_RELOC_ALPHA_CODEADDR,
+
+/* Bits 27..2 of the relocation address shifted right 2 bits;
+simple reloc otherwise. */
+ BFD_RELOC_MIPS_JMP,
+
+/* The MIPS16 jump instruction. */
+ BFD_RELOC_MIPS16_JMP,
+
+/* MIPS16 GP relative reloc. */
+ BFD_RELOC_MIPS16_GPREL,
+
+/* High 16 bits of 32-bit value; simple reloc. */
+ BFD_RELOC_HI16,
+
+/* High 16 bits of 32-bit value but the low 16 bits will be sign
+extended and added to form the final result. If the low 16
+bits form a negative number, we need to add one to the high value
+to compensate for the borrow when the low bits are added. */
+ BFD_RELOC_HI16_S,
+
+/* Low 16 bits. */
+ BFD_RELOC_LO16,
+
+/* Like BFD_RELOC_HI16_S, but PC relative. */
+ BFD_RELOC_PCREL_HI16_S,
+
+/* Like BFD_RELOC_LO16, but PC relative. */
+ BFD_RELOC_PCREL_LO16,
+
+/* Relocation relative to the global pointer. */
+#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16
+
+/* Relocation against a MIPS literal section. */
+ BFD_RELOC_MIPS_LITERAL,
+
+/* MIPS ELF relocations. */
+ BFD_RELOC_MIPS_GOT16,
+ BFD_RELOC_MIPS_CALL16,
+#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32
+ BFD_RELOC_MIPS_GOT_HI16,
+ BFD_RELOC_MIPS_GOT_LO16,
+ BFD_RELOC_MIPS_CALL_HI16,
+ BFD_RELOC_MIPS_CALL_LO16,
+
+
+/* i386/elf relocations */
+ BFD_RELOC_386_GOT32,
+ BFD_RELOC_386_PLT32,
+ BFD_RELOC_386_COPY,
+ BFD_RELOC_386_GLOB_DAT,
+ BFD_RELOC_386_JUMP_SLOT,
+ BFD_RELOC_386_RELATIVE,
+ BFD_RELOC_386_GOTOFF,
+ BFD_RELOC_386_GOTPC,
+
+/* ns32k relocations */
+ BFD_RELOC_NS32K_IMM_8,
+ BFD_RELOC_NS32K_IMM_16,
+ BFD_RELOC_NS32K_IMM_32,
+ BFD_RELOC_NS32K_IMM_8_PCREL,
+ BFD_RELOC_NS32K_IMM_16_PCREL,
+ BFD_RELOC_NS32K_IMM_32_PCREL,
+ BFD_RELOC_NS32K_DISP_8,
+ BFD_RELOC_NS32K_DISP_16,
+ BFD_RELOC_NS32K_DISP_32,
+ BFD_RELOC_NS32K_DISP_8_PCREL,
+ BFD_RELOC_NS32K_DISP_16_PCREL,
+ BFD_RELOC_NS32K_DISP_32_PCREL,
+
+/* Power(rs6000) and PowerPC relocations. */
+ BFD_RELOC_PPC_B26,
+ BFD_RELOC_PPC_BA26,
+ BFD_RELOC_PPC_TOC16,
+ BFD_RELOC_PPC_B16,
+ BFD_RELOC_PPC_B16_BRTAKEN,
+ BFD_RELOC_PPC_B16_BRNTAKEN,
+ BFD_RELOC_PPC_BA16,
+ BFD_RELOC_PPC_BA16_BRTAKEN,
+ BFD_RELOC_PPC_BA16_BRNTAKEN,
+ BFD_RELOC_PPC_COPY,
+ BFD_RELOC_PPC_GLOB_DAT,
+ BFD_RELOC_PPC_JMP_SLOT,
+ BFD_RELOC_PPC_RELATIVE,
+ BFD_RELOC_PPC_LOCAL24PC,
+ BFD_RELOC_PPC_EMB_NADDR32,
+ BFD_RELOC_PPC_EMB_NADDR16,
+ BFD_RELOC_PPC_EMB_NADDR16_LO,
+ BFD_RELOC_PPC_EMB_NADDR16_HI,
+ BFD_RELOC_PPC_EMB_NADDR16_HA,
+ BFD_RELOC_PPC_EMB_SDAI16,
+ BFD_RELOC_PPC_EMB_SDA2I16,
+ BFD_RELOC_PPC_EMB_SDA2REL,
+ BFD_RELOC_PPC_EMB_SDA21,
+ BFD_RELOC_PPC_EMB_MRKREF,
+ BFD_RELOC_PPC_EMB_RELSEC16,
+ BFD_RELOC_PPC_EMB_RELST_LO,
+ BFD_RELOC_PPC_EMB_RELST_HI,
+ BFD_RELOC_PPC_EMB_RELST_HA,
+ BFD_RELOC_PPC_EMB_BIT_FLD,
+ BFD_RELOC_PPC_EMB_RELSDA,
+
+/* The type of reloc used to build a contructor table - at the moment
+probably a 32 bit wide absolute relocation, but the target can choose.
+It generally does map to one of the other relocation types. */
+ BFD_RELOC_CTOR,
+
+/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
+not stored in the instruction. */
+ BFD_RELOC_ARM_PCREL_BRANCH,
+
+/* These relocs are only used within the ARM assembler. They are not
+(at present) written to any object files. */
+ BFD_RELOC_ARM_IMMEDIATE,
+ BFD_RELOC_ARM_OFFSET_IMM,
+ BFD_RELOC_ARM_SHIFT_IMM,
+ BFD_RELOC_ARM_SWI,
+ BFD_RELOC_ARM_MULTI,
+ BFD_RELOC_ARM_CP_OFF_IMM,
+ BFD_RELOC_ARM_ADR_IMM,
+ BFD_RELOC_ARM_LDR_IMM,
+ BFD_RELOC_ARM_LITERAL,
+ BFD_RELOC_ARM_IN_POOL,
+ BFD_RELOC_ARM_OFFSET_IMM8,
+ BFD_RELOC_ARM_HWLITERAL,
+ BFD_RELOC_ARM_THUMB_ADD,
+ BFD_RELOC_ARM_THUMB_IMM,
+ BFD_RELOC_ARM_THUMB_SHIFT,
+ BFD_RELOC_ARM_THUMB_OFFSET,
+ BFD_RELOC_ARM_GOT12,
+ BFD_RELOC_ARM_GOT32,
+ BFD_RELOC_ARM_JUMP_SLOT,
+ BFD_RELOC_ARM_COPY,
+ BFD_RELOC_ARM_GLOB_DAT,
+ BFD_RELOC_ARM_PLT32,
+ BFD_RELOC_ARM_RELATIVE,
+ BFD_RELOC_ARM_GOTOFF,
+ BFD_RELOC_ARM_GOTPC,
+
+/* Hitachi SH relocs. Not all of these appear in object files. */
+ BFD_RELOC_SH_PCDISP8BY2,
+ BFD_RELOC_SH_PCDISP12BY2,
+ BFD_RELOC_SH_IMM4,
+ BFD_RELOC_SH_IMM4BY2,
+ BFD_RELOC_SH_IMM4BY4,
+ BFD_RELOC_SH_IMM8,
+ BFD_RELOC_SH_IMM8BY2,
+ BFD_RELOC_SH_IMM8BY4,
+ BFD_RELOC_SH_PCRELIMM8BY2,
+ BFD_RELOC_SH_PCRELIMM8BY4,
+ BFD_RELOC_SH_SWITCH16,
+ BFD_RELOC_SH_SWITCH32,
+ BFD_RELOC_SH_USES,
+ BFD_RELOC_SH_COUNT,
+ BFD_RELOC_SH_ALIGN,
+ BFD_RELOC_SH_CODE,
+ BFD_RELOC_SH_DATA,
+ BFD_RELOC_SH_LABEL,
+
+/* Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must
+be zero and is not stored in the instruction. */
+ BFD_RELOC_THUMB_PCREL_BRANCH9,
+ BFD_RELOC_THUMB_PCREL_BRANCH12,
+ BFD_RELOC_THUMB_PCREL_BRANCH23,
+
+/* Argonaut RISC Core (ARC) relocs.
+ARC 22 bit pc-relative branch. The lowest two bits must be zero and are
+not stored in the instruction. The high 20 bits are installed in bits 26
+through 7 of the instruction. */
+ BFD_RELOC_ARC_B22_PCREL,
+
+/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not
+stored in the instruction. The high 24 bits are installed in bits 23
+through 0. */
+ BFD_RELOC_ARC_B26,
+
+/* Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0. */
+ BFD_RELOC_D10V_10_PCREL_R,
+
+/* Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0. This is the same as the previous reloc
+except it is in the left container, i.e.,
+shifted left 15 bits. */
+ BFD_RELOC_D10V_10_PCREL_L,
+
+/* This is an 18-bit reloc with the right 2 bits
+assumed to be 0. */
+ BFD_RELOC_D10V_18,
+
+/* This is an 18-bit reloc with the right 2 bits
+assumed to be 0. */
+ BFD_RELOC_D10V_18_PCREL,
+
+/* Mitsubishi D30V relocs.
+This is a 6-bit absolute reloc. */
+ BFD_RELOC_D30V_6,
+
+/* This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_9_PCREL,
+
+/* This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container. */
+ BFD_RELOC_D30V_9_PCREL_R,
+
+/* This is a 12-bit absolute reloc with the
+right 3 bitsassumed to be 0. */
+ BFD_RELOC_D30V_15,
+
+/* This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_15_PCREL,
+
+/* This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container. */
+ BFD_RELOC_D30V_15_PCREL_R,
+
+/* This is an 18-bit absolute reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_21,
+
+/* This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_21_PCREL,
+
+/* This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container. */
+ BFD_RELOC_D30V_21_PCREL_R,
+
+/* This is a 32-bit absolute reloc. */
+ BFD_RELOC_D30V_32,
+
+/* This is a 32-bit pc-relative reloc. */
+ BFD_RELOC_D30V_32_PCREL,
+
+/* Mitsubishi M32R relocs.
+This is a 24 bit absolute address. */
+ BFD_RELOC_M32R_24,
+
+/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */
+ BFD_RELOC_M32R_10_PCREL,
+
+/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */
+ BFD_RELOC_M32R_18_PCREL,
+
+/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */
+ BFD_RELOC_M32R_26_PCREL,
+
+/* This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as unsigned. */
+ BFD_RELOC_M32R_HI16_ULO,
+
+/* This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as signed. */
+ BFD_RELOC_M32R_HI16_SLO,
+
+/* This is a 16-bit reloc containing the lower 16 bits of an address. */
+ BFD_RELOC_M32R_LO16,
+
+/* This is a 16-bit reloc containing the small data area offset for use in
+add3, load, and store instructions. */
+ BFD_RELOC_M32R_SDA16,
+
+/* This is a 9-bit reloc */
+ BFD_RELOC_V850_9_PCREL,
+
+/* This is a 22-bit reloc */
+ BFD_RELOC_V850_22_PCREL,
+
+/* This is a 16 bit offset from the short data area pointer. */
+ BFD_RELOC_V850_SDA_16_16_OFFSET,
+
+/* This is a 16 bit offset (of which only 15 bits are used) from the
+short data area pointer. */
+ BFD_RELOC_V850_SDA_15_16_OFFSET,
+
+/* This is a 16 bit offset from the zero data area pointer. */
+ BFD_RELOC_V850_ZDA_16_16_OFFSET,
+
+/* This is a 16 bit offset (of which only 15 bits are used) from the
+zero data area pointer. */
+ BFD_RELOC_V850_ZDA_15_16_OFFSET,
+
+/* This is an 8 bit offset (of which only 6 bits are used) from the
+tiny data area pointer. */
+ BFD_RELOC_V850_TDA_6_8_OFFSET,
+
+/* This is an 8bit offset (of which only 7 bits are used) from the tiny
+data area pointer. */
+ BFD_RELOC_V850_TDA_7_8_OFFSET,
+
+/* This is a 7 bit offset from the tiny data area pointer. */
+ BFD_RELOC_V850_TDA_7_7_OFFSET,
+
+/* This is a 16 bit offset from the tiny data area pointer. */
+ BFD_RELOC_V850_TDA_16_16_OFFSET,
+
+/* This is a 5 bit offset (of which only 4 bits are used) from the tiny
+data area pointer. */
+ BFD_RELOC_V850_TDA_4_5_OFFSET,
+
+/* This is a 4 bit offset from the tiny data area pointer. */
+ BFD_RELOC_V850_TDA_4_4_OFFSET,
+
+/* This is a 16 bit offset from the short data area pointer, with the
+bits placed non-contigously in the instruction. */
+ BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET,
+
+/* This is a 16 bit offset from the zero data area pointer, with the
+bits placed non-contigously in the instruction. */
+ BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET,
+
+/* This is a 6 bit offset from the call table base pointer. */
+ BFD_RELOC_V850_CALLT_6_7_OFFSET,
+
+/* This is a 16 bit offset from the call table base pointer. */
+ BFD_RELOC_V850_CALLT_16_16_OFFSET,
+
+
+/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction. */
+ BFD_RELOC_MN10300_32_PCREL,
+
+/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction. */
+ BFD_RELOC_MN10300_16_PCREL,
+
+/* This is a 8bit DP reloc for the tms320c30, where the most
+significant 8 bits of a 24 bit word are placed into the least
+significant 8 bits of the opcode. */
+ BFD_RELOC_TIC30_LDP,
+
+/* This is a 48 bit reloc for the FR30 that stores 32 bits. */
+ BFD_RELOC_FR30_48,
+
+/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into
+two sections. */
+ BFD_RELOC_FR30_20,
+
+/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in
+4 bits. */
+ BFD_RELOC_FR30_6_IN_4,
+
+/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset
+into 8 bits. */
+ BFD_RELOC_FR30_8_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset
+into 8 bits. */
+ BFD_RELOC_FR30_9_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset
+into 8 bits. */
+ BFD_RELOC_FR30_10_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+short offset into 8 bits. */
+ BFD_RELOC_FR30_9_PCREL,
+
+/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative
+short offset into 11 bits. */
+ BFD_RELOC_FR30_12_PCREL,
+
+/* Motorola Mcore relocations. */
+ BFD_RELOC_MCORE_PCREL_IMM8BY4,
+ BFD_RELOC_MCORE_PCREL_IMM11BY2,
+ BFD_RELOC_MCORE_PCREL_IMM4BY2,
+ BFD_RELOC_MCORE_PCREL_32,
+ BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2,
+
+/* These two relocations are used by the linker to determine which of
+the entries in a C++ virtual function table are actually used. When
+the --gc-sections option is given, the linker will zero out the entries
+that are not used, so that the code for those functions need not be
+included in the output.
+
+VTABLE_INHERIT is a zero-space relocation used to describe to the
+linker the inheritence tree of a C++ virtual function table. The
+relocation's symbol should be the parent class' vtable, and the
+relocation should be located at the child vtable.
+
+VTABLE_ENTRY is a zero-space relocation that describes the use of a
+virtual function table entry. The reloc's symbol should refer to the
+table of the class mentioned in the code. Off of that base, an offset
+describes the entry that is being used. For Rela hosts, this offset
+is stored in the reloc's addend. For Rel hosts, we are forced to put
+this offset in the reloc's section offset. */
+ BFD_RELOC_VTABLE_INHERIT,
+ BFD_RELOC_VTABLE_ENTRY,
+ BFD_RELOC_UNUSED };
+typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+reloc_howto_type *
+
+bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+
+const char *
+bfd_get_reloc_code_name PARAMS ((bfd_reloc_code_real_type code));
+
+
+typedef struct symbol_cache_entry
+{
+ /* A pointer to the BFD which owns the symbol. This information
+ is necessary so that a back end can work out what additional
+ information (invisible to the application writer) is carried
+ with the symbol.
+
+ This field is *almost* redundant, since you can use section->owner
+ instead, except that some symbols point to the global sections
+ bfd_{abs,com,und}_section. This could be fixed by making
+ these globals be per-bfd (or per-target-flavor). FIXME. */
+
+ struct _bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */
+
+ /* The text of the symbol. The name is left alone, and not copied; the
+ application may not alter it. */
+ CONST char *name;
+
+ /* The value of the symbol. This really should be a union of a
+ numeric value with a pointer, since some flags indicate that
+ a pointer to another symbol is stored here. */
+ symvalue value;
+
+ /* Attributes of a symbol: */
+
+#define BSF_NO_FLAGS 0x00
+
+ /* The symbol has local scope; <<static>> in <<C>>. The value
+ is the offset into the section of the data. */
+#define BSF_LOCAL 0x01
+
+ /* The symbol has global scope; initialized data in <<C>>. The
+ value is the offset into the section of the data. */
+#define BSF_GLOBAL 0x02
+
+ /* The symbol has global scope and is exported. The value is
+ the offset into the section of the data. */
+#define BSF_EXPORT BSF_GLOBAL /* no real difference */
+
+ /* A normal C symbol would be one of:
+ <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or
+ <<BSF_GLOBAL>> */
+
+ /* The symbol is a debugging record. The value has an arbitary
+ meaning. */
+#define BSF_DEBUGGING 0x08
+
+ /* The symbol denotes a function entry point. Used in ELF,
+ perhaps others someday. */
+#define BSF_FUNCTION 0x10
+
+ /* Used by the linker. */
+#define BSF_KEEP 0x20
+#define BSF_KEEP_G 0x40
+
+ /* A weak global symbol, overridable without warnings by
+ a regular global symbol of the same name. */
+#define BSF_WEAK 0x80
+
+ /* This symbol was created to point to a section, e.g. ELF's
+ STT_SECTION symbols. */
+#define BSF_SECTION_SYM 0x100
+
+ /* The symbol used to be a common symbol, but now it is
+ allocated. */
+#define BSF_OLD_COMMON 0x200
+
+ /* The default value for common data. */
+#define BFD_FORT_COMM_DEFAULT_VALUE 0
+
+ /* In some files the type of a symbol sometimes alters its
+ location in an output file - ie in coff a <<ISFCN>> symbol
+ which is also <<C_EXT>> symbol appears where it was
+ declared and not at the end of a section. This bit is set
+ by the target BFD part to convey this information. */
+
+#define BSF_NOT_AT_END 0x400
+
+ /* Signal that the symbol is the label of constructor section. */
+#define BSF_CONSTRUCTOR 0x800
+
+ /* Signal that the symbol is a warning symbol. The name is a
+ warning. The name of the next symbol is the one to warn about;
+ if a reference is made to a symbol with the same name as the next
+ symbol, a warning is issued by the linker. */
+#define BSF_WARNING 0x1000
+
+ /* Signal that the symbol is indirect. This symbol is an indirect
+ pointer to the symbol with the same name as the next symbol. */
+#define BSF_INDIRECT 0x2000
+
+ /* BSF_FILE marks symbols that contain a file name. This is used
+ for ELF STT_FILE symbols. */
+#define BSF_FILE 0x4000
+
+ /* Symbol is from dynamic linking information. */
+#define BSF_DYNAMIC 0x8000
+
+ /* The symbol denotes a data object. Used in ELF, and perhaps
+ others someday. */
+#define BSF_OBJECT 0x10000
+
+ flagword flags;
+
+ /* A pointer to the section to which this symbol is
+ relative. This will always be non NULL, there are special
+ sections for undefined and absolute symbols. */
+ struct sec *section;
+
+ /* Back end special data. */
+ union
+ {
+ PTR p;
+ bfd_vma i;
+ } udata;
+
+} asymbol;
+#define bfd_get_symtab_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+boolean
+bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym));
+
+boolean
+bfd_is_local_label_name PARAMS ((bfd *abfd, const char *name));
+
+#define bfd_is_local_label_name(abfd, name) \
+ BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
+#define bfd_canonicalize_symtab(abfd, location) \
+ BFD_SEND (abfd, _bfd_canonicalize_symtab,\
+ (abfd, location))
+boolean
+bfd_set_symtab PARAMS ((bfd *abfd, asymbol **location, unsigned int count));
+
+void
+bfd_print_symbol_vandf PARAMS ((PTR file, asymbol *symbol));
+
+#define bfd_make_empty_symbol(abfd) \
+ BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+ BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+int
+bfd_decode_symclass PARAMS ((asymbol *symbol));
+
+void
+bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret));
+
+boolean
+bfd_copy_private_symbol_data PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym));
+
+#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+ BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
+ (ibfd, isymbol, obfd, osymbol))
+struct _bfd
+{
+ /* The filename the application opened the BFD with. */
+ CONST char *filename;
+
+ /* A pointer to the target jump table. */
+ const struct bfd_target *xvec;
+
+ /* To avoid dragging too many header files into every file that
+ includes `<<bfd.h>>', IOSTREAM has been declared as a "char
+ *", and MTIME as a "long". Their correct types, to which they
+ are cast when used, are "FILE *" and "time_t". The iostream
+ is the result of an fopen on the filename. However, if the
+ BFD_IN_MEMORY flag is set, then iostream is actually a pointer
+ to a bfd_in_memory struct. */
+ PTR iostream;
+
+ /* Is the file descriptor being cached? That is, can it be closed as
+ needed, and re-opened when accessed later? */
+
+ boolean cacheable;
+
+ /* Marks whether there was a default target specified when the
+ BFD was opened. This is used to select which matching algorithm
+ to use to choose the back end. */
+
+ boolean target_defaulted;
+
+ /* The caching routines use these to maintain a
+ least-recently-used list of BFDs */
+
+ struct _bfd *lru_prev, *lru_next;
+
+ /* When a file is closed by the caching routines, BFD retains
+ state information on the file here: */
+
+ file_ptr where;
+
+ /* and here: (``once'' means at least once) */
+
+ boolean opened_once;
+
+ /* Set if we have a locally maintained mtime value, rather than
+ getting it from the file each time: */
+
+ boolean mtime_set;
+
+ /* File modified time, if mtime_set is true: */
+
+ long mtime;
+
+ /* Reserved for an unimplemented file locking extension.*/
+
+ int ifd;
+
+ /* The format which belongs to the BFD. (object, core, etc.) */
+
+ bfd_format format;
+
+ /* The direction the BFD was opened with*/
+
+ enum bfd_direction {no_direction = 0,
+ read_direction = 1,
+ write_direction = 2,
+ both_direction = 3} direction;
+
+ /* Format_specific flags*/
+
+ flagword flags;
+
+ /* Currently my_archive is tested before adding origin to
+ anything. I believe that this can become always an add of
+ origin, with origin set to 0 for non archive files. */
+
+ file_ptr origin;
+
+ /* Remember when output has begun, to stop strange things
+ from happening. */
+ boolean output_has_begun;
+
+ /* Pointer to linked list of sections*/
+ struct sec *sections;
+
+ /* The number of sections */
+ unsigned int section_count;
+
+ /* Stuff only useful for object files:
+ The start address. */
+ bfd_vma start_address;
+
+ /* Used for input and output*/
+ unsigned int symcount;
+
+ /* Symbol table for output BFD (with symcount entries) */
+ struct symbol_cache_entry **outsymbols;
+
+ /* Pointer to structure which contains architecture information*/
+ const struct bfd_arch_info *arch_info;
+
+ /* Stuff only useful for archives:*/
+ PTR arelt_data;
+ struct _bfd *my_archive; /* The containing archive BFD. */
+ struct _bfd *next; /* The next BFD in the archive. */
+ struct _bfd *archive_head; /* The first BFD in the archive. */
+ boolean has_armap;
+
+ /* A chain of BFD structures involved in a link. */
+ struct _bfd *link_next;
+
+ /* A field used by _bfd_generic_link_add_archive_symbols. This will
+ be used only for archive elements. */
+ int archive_pass;
+
+ /* Used by the back end to hold private data. */
+
+ union
+ {
+ struct aout_data_struct *aout_data;
+ struct artdata *aout_ar_data;
+ struct _oasys_data *oasys_obj_data;
+ struct _oasys_ar_data *oasys_ar_data;
+ struct coff_tdata *coff_obj_data;
+ struct pe_tdata *pe_obj_data;
+ struct xcoff_tdata *xcoff_obj_data;
+ struct ecoff_tdata *ecoff_obj_data;
+ struct ieee_data_struct *ieee_data;
+ struct ieee_ar_data_struct *ieee_ar_data;
+ struct srec_data_struct *srec_data;
+ struct ihex_data_struct *ihex_data;
+ struct tekhex_data_struct *tekhex_data;
+ struct elf_obj_tdata *elf_obj_data;
+ struct nlm_obj_tdata *nlm_obj_data;
+ struct bout_data_struct *bout_data;
+ struct sun_core_struct *sun_core_data;
+ struct sco5_core_struct *sco5_core_data;
+ struct trad_core_struct *trad_core_data;
+ struct som_data_struct *som_data;
+ struct hpux_core_struct *hpux_core_data;
+ struct hppabsd_core_struct *hppabsd_core_data;
+ struct sgi_core_struct *sgi_core_data;
+ struct lynx_core_struct *lynx_core_data;
+ struct osf_core_struct *osf_core_data;
+ struct cisco_core_struct *cisco_core_data;
+ struct versados_data_struct *versados_data;
+ struct netbsd_core_struct *netbsd_core_data;
+ PTR any;
+ } tdata;
+
+ /* Used by the application to hold private data*/
+ PTR usrdata;
+
+ /* Where all the allocated stuff under this BFD goes. This is a
+ struct objalloc *, but we use PTR to avoid requiring the inclusion of
+ objalloc.h. */
+ PTR memory;
+};
+
+typedef enum bfd_error
+{
+ bfd_error_no_error = 0,
+ bfd_error_system_call,
+ bfd_error_invalid_target,
+ bfd_error_wrong_format,
+ bfd_error_invalid_operation,
+ bfd_error_no_memory,
+ bfd_error_no_symbols,
+ bfd_error_no_armap,
+ bfd_error_no_more_archived_files,
+ bfd_error_malformed_archive,
+ bfd_error_file_not_recognized,
+ bfd_error_file_ambiguously_recognized,
+ bfd_error_no_contents,
+ bfd_error_nonrepresentable_section,
+ bfd_error_no_debug_section,
+ bfd_error_bad_value,
+ bfd_error_file_truncated,
+ bfd_error_file_too_big,
+ bfd_error_invalid_error_code
+} bfd_error_type;
+
+bfd_error_type
+bfd_get_error PARAMS ((void));
+
+void
+bfd_set_error PARAMS ((bfd_error_type error_tag));
+
+CONST char *
+bfd_errmsg PARAMS ((bfd_error_type error_tag));
+
+void
+bfd_perror PARAMS ((CONST char *message));
+
+typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...));
+
+bfd_error_handler_type
+bfd_set_error_handler PARAMS ((bfd_error_handler_type));
+
+void
+bfd_set_error_program_name PARAMS ((const char *));
+
+bfd_error_handler_type
+bfd_get_error_handler PARAMS ((void));
+
+long
+bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
+
+long
+bfd_canonicalize_reloc
+ PARAMS ((bfd *abfd,
+ asection *sec,
+ arelent **loc,
+ asymbol **syms));
+
+void
+bfd_set_reloc
+ PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count)
+
+ );
+
+boolean
+bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags));
+
+boolean
+bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma));
+
+long
+bfd_get_mtime PARAMS ((bfd *abfd));
+
+long
+bfd_get_size PARAMS ((bfd *abfd));
+
+int
+bfd_get_gp_size PARAMS ((bfd *abfd));
+
+void
+bfd_set_gp_size PARAMS ((bfd *abfd, int i));
+
+bfd_vma
+bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base));
+
+boolean
+bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
+
+#define bfd_copy_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+ (ibfd, obfd))
+boolean
+bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
+
+#define bfd_merge_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+ (ibfd, obfd))
+boolean
+bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags));
+
+#define bfd_set_private_flags(abfd, flags) \
+ BFD_SEND (abfd, _bfd_set_private_flags, \
+ (abfd, flags))
+#define bfd_sizeof_headers(abfd, reloc) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line))
+
+ /* Do these three do anything useful at all, for any back end? */
+#define bfd_debug_info_start(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+ BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+
+#define bfd_stat_arch_elt(abfd, stat) \
+ BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+
+#define bfd_update_armap_timestamp(abfd) \
+ BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))
+
+#define bfd_set_arch_mach(abfd, arch, mach)\
+ BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
+
+#define bfd_relax_section(abfd, section, link_info, again) \
+ BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
+
+#define bfd_gc_sections(abfd, link_info) \
+ BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))
+
+#define bfd_link_hash_table_create(abfd) \
+ BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
+
+#define bfd_link_add_symbols(abfd, info) \
+ BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
+
+#define bfd_final_link(abfd, info) \
+ BFD_SEND (abfd, _bfd_final_link, (abfd, info))
+
+#define bfd_free_cached_info(abfd) \
+ BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
+
+#define bfd_get_dynamic_symtab_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
+
+#define bfd_print_private_bfd_data(abfd, file)\
+ BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))
+
+#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
+ BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
+
+#define bfd_get_dynamic_reloc_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
+
+#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
+ BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
+
+extern bfd_byte *bfd_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *,
+ struct bfd_link_order *, bfd_byte *,
+ boolean, asymbol **));
+
+symindex
+bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));
+
+boolean
+bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head));
+
+bfd *
+bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous));
+
+CONST char *
+bfd_core_file_failing_command PARAMS ((bfd *abfd));
+
+int
+bfd_core_file_failing_signal PARAMS ((bfd *abfd));
+
+boolean
+core_file_matches_executable_p
+ PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+
+#define BFD_SEND(bfd, message, arglist) \
+ ((*((bfd)->xvec->message)) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND
+#define BFD_SEND(bfd, message, arglist) \
+ (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+ ((*((bfd)->xvec->message)) arglist) : \
+ (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+#define BFD_SEND_FMT(bfd, message, arglist) \
+ (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND_FMT
+#define BFD_SEND_FMT(bfd, message, arglist) \
+ (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+ (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \
+ (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+enum bfd_flavour {
+ bfd_target_unknown_flavour,
+ bfd_target_aout_flavour,
+ bfd_target_coff_flavour,
+ bfd_target_ecoff_flavour,
+ bfd_target_elf_flavour,
+ bfd_target_ieee_flavour,
+ bfd_target_nlm_flavour,
+ bfd_target_oasys_flavour,
+ bfd_target_tekhex_flavour,
+ bfd_target_srec_flavour,
+ bfd_target_ihex_flavour,
+ bfd_target_som_flavour,
+ bfd_target_os9k_flavour,
+ bfd_target_versados_flavour,
+ bfd_target_msdos_flavour,
+ bfd_target_ovax_flavour,
+ bfd_target_evax_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+ /* Forward declaration. */
+typedef struct bfd_link_info _bfd_link_info;
+
+typedef struct bfd_target
+{
+ char *name;
+ enum bfd_flavour flavour;
+ enum bfd_endian byteorder;
+ enum bfd_endian header_byteorder;
+ flagword object_flags;
+ flagword section_flags;
+ char symbol_leading_char;
+ char ar_pad_char;
+ unsigned short ar_max_namelen;
+ bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *));
+ bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *));
+ void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
+ bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *));
+ bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *));
+ void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
+ bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *));
+ bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *));
+ void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
+ bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *));
+ bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *));
+ void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
+ bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *));
+ bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *));
+ void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
+ bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *));
+ bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *));
+ void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
+ const struct bfd_target *(*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
+ boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
+ boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
+
+ /* Generic entry points. */
+#define BFD_JUMP_TABLE_GENERIC(NAME)\
+CAT(NAME,_close_and_cleanup),\
+CAT(NAME,_bfd_free_cached_info),\
+CAT(NAME,_new_section_hook),\
+CAT(NAME,_get_section_contents),\
+CAT(NAME,_get_section_contents_in_window)
+
+ /* Called when the BFD is being closed to do any necessary cleanup. */
+ boolean (*_close_and_cleanup) PARAMS ((bfd *));
+ /* Ask the BFD to free all cached information. */
+ boolean (*_bfd_free_cached_info) PARAMS ((bfd *));
+ /* Called when a new section is created. */
+ boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
+ /* Read the contents of a section. */
+ boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
+ file_ptr, bfd_size_type));
+ boolean (*_bfd_get_section_contents_in_window)
+ PARAMS ((bfd *, sec_ptr, bfd_window *,
+ file_ptr, bfd_size_type));
+
+ /* Entry points to copy private data. */
+#define BFD_JUMP_TABLE_COPY(NAME)\
+CAT(NAME,_bfd_copy_private_bfd_data),\
+CAT(NAME,_bfd_merge_private_bfd_data),\
+CAT(NAME,_bfd_copy_private_section_data),\
+CAT(NAME,_bfd_copy_private_symbol_data),\
+CAT(NAME,_bfd_set_private_flags),\
+CAT(NAME,_bfd_print_private_bfd_data)\
+ /* Called to copy BFD general private data from one object file
+ to another. */
+ boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *));
+ /* Called to merge BFD general private data from one object file
+ to a common output file when linking. */
+ boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *));
+ /* Called to copy BFD private section data from one object file
+ to another. */
+ boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr,
+ bfd *, sec_ptr));
+ /* Called to copy BFD private symbol data from one symbol
+ to another. */
+ boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *,
+ bfd *, asymbol *));
+ /* Called to set private backend flags */
+ boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword));
+
+ /* Called to print private BFD data */
+ boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR));
+
+ /* Core file entry points. */
+#define BFD_JUMP_TABLE_CORE(NAME)\
+CAT(NAME,_core_file_failing_command),\
+CAT(NAME,_core_file_failing_signal),\
+CAT(NAME,_core_file_matches_executable_p)
+ char * (*_core_file_failing_command) PARAMS ((bfd *));
+ int (*_core_file_failing_signal) PARAMS ((bfd *));
+ boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
+
+ /* Archive entry points. */
+#define BFD_JUMP_TABLE_ARCHIVE(NAME)\
+CAT(NAME,_slurp_armap),\
+CAT(NAME,_slurp_extended_name_table),\
+CAT(NAME,_construct_extended_name_table),\
+CAT(NAME,_truncate_arname),\
+CAT(NAME,_write_armap),\
+CAT(NAME,_read_ar_hdr),\
+CAT(NAME,_openr_next_archived_file),\
+CAT(NAME,_get_elt_at_index),\
+CAT(NAME,_generic_stat_arch_elt),\
+CAT(NAME,_update_armap_timestamp)
+ boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
+ boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
+ boolean (*_bfd_construct_extended_name_table)
+ PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+ void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *));
+ boolean (*write_armap) PARAMS ((bfd *arch,
+ unsigned int elength,
+ struct orl *map,
+ unsigned int orl_count,
+ int stridx));
+ PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *));
+ bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
+#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i))
+ bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex));
+ int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
+ boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *));
+
+ /* Entry points used for symbols. */
+#define BFD_JUMP_TABLE_SYMBOLS(NAME)\
+CAT(NAME,_get_symtab_upper_bound),\
+CAT(NAME,_get_symtab),\
+CAT(NAME,_make_empty_symbol),\
+CAT(NAME,_print_symbol),\
+CAT(NAME,_get_symbol_info),\
+CAT(NAME,_bfd_is_local_label_name),\
+CAT(NAME,_get_lineno),\
+CAT(NAME,_find_nearest_line),\
+CAT(NAME,_bfd_make_debug_symbol),\
+CAT(NAME,_read_minisymbols),\
+CAT(NAME,_minisymbol_to_symbol)
+ long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *));
+ long (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
+ struct symbol_cache_entry **));
+ struct symbol_cache_entry *
+ (*_bfd_make_empty_symbol) PARAMS ((bfd *));
+ void (*_bfd_print_symbol) PARAMS ((bfd *, PTR,
+ struct symbol_cache_entry *,
+ bfd_print_symbol_type));
+#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+ void (*_bfd_get_symbol_info) PARAMS ((bfd *,
+ struct symbol_cache_entry *,
+ symbol_info *));
+#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e))
+ boolean (*_bfd_is_local_label_name) PARAMS ((bfd *, const char *));
+
+ alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
+ boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd,
+ struct sec *section, struct symbol_cache_entry **symbols,
+ bfd_vma offset, CONST char **file, CONST char **func,
+ unsigned int *line));
+ /* Back-door to allow format-aware applications to create debug symbols
+ while using BFD for everything else. Currently used by the assembler
+ when creating COFF files. */
+ asymbol * (*_bfd_make_debug_symbol) PARAMS ((
+ bfd *abfd,
+ void *ptr,
+ unsigned long size));
+#define bfd_read_minisymbols(b, d, m, s) \
+ BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+ long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *,
+ unsigned int *));
+#define bfd_minisymbol_to_symbol(b, d, m, f) \
+ BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f))
+ asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR,
+ asymbol *));
+
+ /* Routines for relocs. */
+#define BFD_JUMP_TABLE_RELOCS(NAME)\
+CAT(NAME,_get_reloc_upper_bound),\
+CAT(NAME,_canonicalize_reloc),\
+CAT(NAME,_bfd_reloc_type_lookup)
+ long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
+ long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **,
+ struct symbol_cache_entry **));
+ /* See documentation on reloc types. */
+ reloc_howto_type *
+ (*reloc_type_lookup) PARAMS ((bfd *abfd,
+ bfd_reloc_code_real_type code));
+
+ /* Routines used when writing an object file. */
+#define BFD_JUMP_TABLE_WRITE(NAME)\
+CAT(NAME,_set_arch_mach),\
+CAT(NAME,_set_section_contents)
+ boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture,
+ unsigned long));
+ boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
+ file_ptr, bfd_size_type));
+
+ /* Routines used by the linker. */
+#define BFD_JUMP_TABLE_LINK(NAME)\
+CAT(NAME,_sizeof_headers),\
+CAT(NAME,_bfd_get_relocated_section_contents),\
+CAT(NAME,_bfd_relax_section),\
+CAT(NAME,_bfd_link_hash_table_create),\
+CAT(NAME,_bfd_link_add_symbols),\
+CAT(NAME,_bfd_final_link),\
+CAT(NAME,_bfd_link_split_section),\
+CAT(NAME,_bfd_gc_sections)
+ int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
+ bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
+ struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *data, boolean relocateable,
+ struct symbol_cache_entry **));
+
+ boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
+ struct bfd_link_info *, boolean *again));
+
+ /* Create a hash table for the linker. Different backends store
+ different information in this table. */
+ struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *));
+
+ /* Add symbols from this object file into the hash table. */
+ boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+
+ /* Do a link based on the link_order structures attached to each
+ section of the BFD. */
+ boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
+
+ /* Should this section be split up into smaller pieces during linking. */
+ boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *));
+
+ /* Remove sections that are not referenced from the output. */
+ boolean (*_bfd_gc_sections) PARAMS ((bfd *, struct bfd_link_info *));
+
+ /* Routines to handle dynamic symbols and relocs. */
+#define BFD_JUMP_TABLE_DYNAMIC(NAME)\
+CAT(NAME,_get_dynamic_symtab_upper_bound),\
+CAT(NAME,_canonicalize_dynamic_symtab),\
+CAT(NAME,_get_dynamic_reloc_upper_bound),\
+CAT(NAME,_canonicalize_dynamic_reloc)
+ /* Get the amount of memory required to hold the dynamic symbols. */
+ long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *));
+ /* Read in the dynamic symbols. */
+ long (*_bfd_canonicalize_dynamic_symtab)
+ PARAMS ((bfd *, struct symbol_cache_entry **));
+ /* Get the amount of memory required to hold the dynamic relocs. */
+ long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *));
+ /* Read in the dynamic relocs. */
+ long (*_bfd_canonicalize_dynamic_reloc)
+ PARAMS ((bfd *, arelent **, struct symbol_cache_entry **));
+
+ PTR backend_data;
+} bfd_target;
+boolean
+bfd_set_default_target PARAMS ((const char *name));
+
+const bfd_target *
+bfd_find_target PARAMS ((CONST char *target_name, bfd *abfd));
+
+const char **
+bfd_target_list PARAMS ((void));
+
+boolean
+bfd_check_format PARAMS ((bfd *abfd, bfd_format format));
+
+boolean
+bfd_check_format_matches PARAMS ((bfd *abfd, bfd_format format, char ***matching));
+
+boolean
+bfd_set_format PARAMS ((bfd *abfd, bfd_format format));
+
+CONST char *
+bfd_format_string PARAMS ((bfd_format format));
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bfd/bfd.c b/bfd/bfd.c
new file mode 100644
index 00000000000..597e8f0bc68
--- /dev/null
+++ b/bfd/bfd.c
@@ -0,0 +1,1159 @@
+/* Generic BFD library interface and support routines.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ <<typedef bfd>>
+
+ A BFD has type <<bfd>>; objects of this type are the
+ cornerstone of any application using BFD. Using BFD
+ consists of making references though the BFD and to data in the BFD.
+
+ Here is the structure that defines the type <<bfd>>. It
+ contains the major data about the file and pointers
+ to the rest of the data.
+
+CODE_FRAGMENT
+.
+.struct _bfd
+.{
+. {* The filename the application opened the BFD with. *}
+. CONST char *filename;
+.
+. {* A pointer to the target jump table. *}
+. const struct bfd_target *xvec;
+.
+. {* To avoid dragging too many header files into every file that
+. includes `<<bfd.h>>', IOSTREAM has been declared as a "char
+. *", and MTIME as a "long". Their correct types, to which they
+. are cast when used, are "FILE *" and "time_t". The iostream
+. is the result of an fopen on the filename. However, if the
+. BFD_IN_MEMORY flag is set, then iostream is actually a pointer
+. to a bfd_in_memory struct. *}
+. PTR iostream;
+.
+. {* Is the file descriptor being cached? That is, can it be closed as
+. needed, and re-opened when accessed later? *}
+.
+. boolean cacheable;
+.
+. {* Marks whether there was a default target specified when the
+. BFD was opened. This is used to select which matching algorithm
+. to use to choose the back end. *}
+.
+. boolean target_defaulted;
+.
+. {* The caching routines use these to maintain a
+. least-recently-used list of BFDs *}
+.
+. struct _bfd *lru_prev, *lru_next;
+.
+. {* When a file is closed by the caching routines, BFD retains
+. state information on the file here: *}
+.
+. file_ptr where;
+.
+. {* and here: (``once'' means at least once) *}
+.
+. boolean opened_once;
+.
+. {* Set if we have a locally maintained mtime value, rather than
+. getting it from the file each time: *}
+.
+. boolean mtime_set;
+.
+. {* File modified time, if mtime_set is true: *}
+.
+. long mtime;
+.
+. {* Reserved for an unimplemented file locking extension.*}
+.
+. int ifd;
+.
+. {* The format which belongs to the BFD. (object, core, etc.) *}
+.
+. bfd_format format;
+.
+. {* The direction the BFD was opened with*}
+.
+. enum bfd_direction {no_direction = 0,
+. read_direction = 1,
+. write_direction = 2,
+. both_direction = 3} direction;
+.
+. {* Format_specific flags*}
+.
+. flagword flags;
+.
+. {* Currently my_archive is tested before adding origin to
+. anything. I believe that this can become always an add of
+. origin, with origin set to 0 for non archive files. *}
+.
+. file_ptr origin;
+.
+. {* Remember when output has begun, to stop strange things
+. from happening. *}
+. boolean output_has_begun;
+.
+. {* Pointer to linked list of sections*}
+. struct sec *sections;
+.
+. {* The number of sections *}
+. unsigned int section_count;
+.
+. {* Stuff only useful for object files:
+. The start address. *}
+. bfd_vma start_address;
+.
+. {* Used for input and output*}
+. unsigned int symcount;
+.
+. {* Symbol table for output BFD (with symcount entries) *}
+. struct symbol_cache_entry **outsymbols;
+.
+. {* Pointer to structure which contains architecture information*}
+. const struct bfd_arch_info *arch_info;
+.
+. {* Stuff only useful for archives:*}
+. PTR arelt_data;
+. struct _bfd *my_archive; {* The containing archive BFD. *}
+. struct _bfd *next; {* The next BFD in the archive. *}
+. struct _bfd *archive_head; {* The first BFD in the archive. *}
+. boolean has_armap;
+.
+. {* A chain of BFD structures involved in a link. *}
+. struct _bfd *link_next;
+.
+. {* A field used by _bfd_generic_link_add_archive_symbols. This will
+. be used only for archive elements. *}
+. int archive_pass;
+.
+. {* Used by the back end to hold private data. *}
+.
+. union
+. {
+. struct aout_data_struct *aout_data;
+. struct artdata *aout_ar_data;
+. struct _oasys_data *oasys_obj_data;
+. struct _oasys_ar_data *oasys_ar_data;
+. struct coff_tdata *coff_obj_data;
+. struct pe_tdata *pe_obj_data;
+. struct xcoff_tdata *xcoff_obj_data;
+. struct ecoff_tdata *ecoff_obj_data;
+. struct ieee_data_struct *ieee_data;
+. struct ieee_ar_data_struct *ieee_ar_data;
+. struct srec_data_struct *srec_data;
+. struct ihex_data_struct *ihex_data;
+. struct tekhex_data_struct *tekhex_data;
+. struct elf_obj_tdata *elf_obj_data;
+. struct nlm_obj_tdata *nlm_obj_data;
+. struct bout_data_struct *bout_data;
+. struct sun_core_struct *sun_core_data;
+. struct sco5_core_struct *sco5_core_data;
+. struct trad_core_struct *trad_core_data;
+. struct som_data_struct *som_data;
+. struct hpux_core_struct *hpux_core_data;
+. struct hppabsd_core_struct *hppabsd_core_data;
+. struct sgi_core_struct *sgi_core_data;
+. struct lynx_core_struct *lynx_core_data;
+. struct osf_core_struct *osf_core_data;
+. struct cisco_core_struct *cisco_core_data;
+. struct versados_data_struct *versados_data;
+. struct netbsd_core_struct *netbsd_core_data;
+. PTR any;
+. } tdata;
+.
+. {* Used by the application to hold private data*}
+. PTR usrdata;
+.
+. {* Where all the allocated stuff under this BFD goes. This is a
+. struct objalloc *, but we use PTR to avoid requiring the inclusion of
+. objalloc.h. *}
+. PTR memory;
+.};
+.
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include "libiberty.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "libcoff.h"
+#include "libecoff.h"
+#undef obj_symbols
+#include "elf-bfd.h"
+
+#include <ctype.h>
+
+/* provide storage for subsystem, stack and heap data which may have been
+ passed in on the command line. Ld puts this data into a bfd_link_info
+ struct which ultimately gets passed in to the bfd. When it arrives, copy
+ it to the following struct so that the data will be available in coffcode.h
+ where it is needed. The typedef's used are defined in bfd.h */
+
+
+
+/*
+SECTION
+ Error reporting
+
+ Most BFD functions return nonzero on success (check their
+ individual documentation for precise semantics). On an error,
+ they call <<bfd_set_error>> to set an error condition that callers
+ can check by calling <<bfd_get_error>>.
+ If that returns <<bfd_error_system_call>>, then check
+ <<errno>>.
+
+ The easiest way to report a BFD error to the user is to
+ use <<bfd_perror>>.
+
+SUBSECTION
+ Type <<bfd_error_type>>
+
+ The values returned by <<bfd_get_error>> are defined by the
+ enumerated type <<bfd_error_type>>.
+
+CODE_FRAGMENT
+.
+.typedef enum bfd_error
+.{
+. bfd_error_no_error = 0,
+. bfd_error_system_call,
+. bfd_error_invalid_target,
+. bfd_error_wrong_format,
+. bfd_error_invalid_operation,
+. bfd_error_no_memory,
+. bfd_error_no_symbols,
+. bfd_error_no_armap,
+. bfd_error_no_more_archived_files,
+. bfd_error_malformed_archive,
+. bfd_error_file_not_recognized,
+. bfd_error_file_ambiguously_recognized,
+. bfd_error_no_contents,
+. bfd_error_nonrepresentable_section,
+. bfd_error_no_debug_section,
+. bfd_error_bad_value,
+. bfd_error_file_truncated,
+. bfd_error_file_too_big,
+. bfd_error_invalid_error_code
+.} bfd_error_type;
+.
+*/
+
+static bfd_error_type bfd_error = bfd_error_no_error;
+
+CONST char *CONST bfd_errmsgs[] = {
+ N_("No error"),
+ N_("System call error"),
+ N_("Invalid bfd target"),
+ N_("File in wrong format"),
+ N_("Invalid operation"),
+ N_("Memory exhausted"),
+ N_("No symbols"),
+ N_("Archive has no index; run ranlib to add one"),
+ N_("No more archived files"),
+ N_("Malformed archive"),
+ N_("File format not recognized"),
+ N_("File format is ambiguous"),
+ N_("Section has no contents"),
+ N_("Nonrepresentable section on output"),
+ N_("Symbol needs debug section which does not exist"),
+ N_("Bad value"),
+ N_("File truncated"),
+ N_("File too big"),
+ N_("#<Invalid error code>")
+ };
+
+/*
+FUNCTION
+ bfd_get_error
+
+SYNOPSIS
+ bfd_error_type bfd_get_error (void);
+
+DESCRIPTION
+ Return the current BFD error condition.
+*/
+
+bfd_error_type
+bfd_get_error ()
+{
+ return bfd_error;
+}
+
+/*
+FUNCTION
+ bfd_set_error
+
+SYNOPSIS
+ void bfd_set_error (bfd_error_type error_tag);
+
+DESCRIPTION
+ Set the BFD error condition to be @var{error_tag}.
+*/
+
+void
+bfd_set_error (error_tag)
+ bfd_error_type error_tag;
+{
+ bfd_error = error_tag;
+}
+
+/*
+FUNCTION
+ bfd_errmsg
+
+SYNOPSIS
+ CONST char *bfd_errmsg (bfd_error_type error_tag);
+
+DESCRIPTION
+ Return a string describing the error @var{error_tag}, or
+ the system error if @var{error_tag} is <<bfd_error_system_call>>.
+*/
+
+CONST char *
+bfd_errmsg (error_tag)
+ bfd_error_type error_tag;
+{
+#ifndef errno
+ extern int errno;
+#endif
+ if (error_tag == bfd_error_system_call)
+ return xstrerror (errno);
+
+ if ((((int)error_tag <(int) bfd_error_no_error) ||
+ ((int)error_tag > (int)bfd_error_invalid_error_code)))
+ error_tag = bfd_error_invalid_error_code;/* sanity check */
+
+ return _(bfd_errmsgs [(int)error_tag]);
+}
+
+/*
+FUNCTION
+ bfd_perror
+
+SYNOPSIS
+ void bfd_perror (CONST char *message);
+
+DESCRIPTION
+ Print to the standard error stream a string describing the
+ last BFD error that occurred, or the last system error if
+ the last BFD error was a system call failure. If @var{message}
+ is non-NULL and non-empty, the error string printed is preceded
+ by @var{message}, a colon, and a space. It is followed by a newline.
+*/
+
+void
+bfd_perror (message)
+ CONST char *message;
+{
+ if (bfd_get_error () == bfd_error_system_call)
+ perror((char *)message); /* must be system error then... */
+ else {
+ if (message == NULL || *message == '\0')
+ fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ()));
+ else
+ fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ()));
+ }
+}
+
+/*
+SUBSECTION
+ BFD error handler
+
+ Some BFD functions want to print messages describing the
+ problem. They call a BFD error handler function. This
+ function may be overriden by the program.
+
+ The BFD error handler acts like printf.
+
+CODE_FRAGMENT
+.
+.typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...));
+.
+*/
+
+/* The program name used when printing BFD error messages. */
+
+static const char *_bfd_error_program_name;
+
+/* This is the default routine to handle BFD error messages. */
+
+#ifdef ANSI_PROTOTYPES
+
+static void _bfd_default_error_handler PARAMS ((const char *s, ...));
+
+static void
+_bfd_default_error_handler (const char *s, ...)
+{
+ va_list p;
+
+ if (_bfd_error_program_name != NULL)
+ fprintf (stderr, "%s: ", _bfd_error_program_name);
+ else
+ fprintf (stderr, "BFD: ");
+
+ va_start (p, s);
+
+ vfprintf (stderr, s, p);
+
+ va_end (p);
+
+ fprintf (stderr, "\n");
+}
+
+#else /* ! defined (ANSI_PROTOTYPES) */
+
+static void _bfd_default_error_handler ();
+
+static void
+_bfd_default_error_handler (va_alist)
+ va_dcl
+{
+ va_list p;
+ const char *s;
+
+ if (_bfd_error_program_name != NULL)
+ fprintf (stderr, "%s: ", _bfd_error_program_name);
+ else
+ fprintf (stderr, "BFD: ");
+
+ va_start (p);
+
+ s = va_arg (p, const char *);
+ vfprintf (stderr, s, p);
+
+ va_end (p);
+
+ fprintf (stderr, "\n");
+}
+
+#endif /* ! defined (ANSI_PROTOTYPES) */
+
+/* This is a function pointer to the routine which should handle BFD
+ error messages. It is called when a BFD routine encounters an
+ error for which it wants to print a message. Going through a
+ function pointer permits a program linked against BFD to intercept
+ the messages and deal with them itself. */
+
+bfd_error_handler_type _bfd_error_handler = _bfd_default_error_handler;
+
+/*
+FUNCTION
+ bfd_set_error_handler
+
+SYNOPSIS
+ bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);
+
+DESCRIPTION
+ Set the BFD error handler function. Returns the previous
+ function.
+*/
+
+bfd_error_handler_type
+bfd_set_error_handler (pnew)
+ bfd_error_handler_type pnew;
+{
+ bfd_error_handler_type pold;
+
+ pold = _bfd_error_handler;
+ _bfd_error_handler = pnew;
+ return pold;
+}
+
+/*
+FUNCTION
+ bfd_set_error_program_name
+
+SYNOPSIS
+ void bfd_set_error_program_name (const char *);
+
+DESCRIPTION
+ Set the program name to use when printing a BFD error. This
+ is printed before the error message followed by a colon and
+ space. The string must not be changed after it is passed to
+ this function.
+*/
+
+void
+bfd_set_error_program_name (name)
+ const char *name;
+{
+ _bfd_error_program_name = name;
+}
+
+
+/*
+FUNCTION
+ bfd_get_error_handler
+
+SYNOPSIS
+ bfd_error_handler_type bfd_get_error_handler (void);
+
+DESCRIPTION
+ Return the BFD error handler function.
+*/
+
+bfd_error_handler_type
+bfd_get_error_handler ()
+{
+ return _bfd_error_handler;
+}
+
+/*
+SECTION
+ Symbols
+*/
+
+/*
+FUNCTION
+ bfd_get_reloc_upper_bound
+
+SYNOPSIS
+ long bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
+
+DESCRIPTION
+ Return the number of bytes required to store the
+ relocation information associated with section @var{sect}
+ attached to bfd @var{abfd}. If an error occurs, return -1.
+
+*/
+
+
+long
+bfd_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ if (abfd->format != bfd_object) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
+}
+
+/*
+FUNCTION
+ bfd_canonicalize_reloc
+
+SYNOPSIS
+ long bfd_canonicalize_reloc
+ (bfd *abfd,
+ asection *sec,
+ arelent **loc,
+ asymbol **syms);
+
+DESCRIPTION
+ Call the back end associated with the open BFD
+ @var{abfd} and translate the external form of the relocation
+ information attached to @var{sec} into the internal canonical
+ form. Place the table into memory at @var{loc}, which has
+ been preallocated, usually by a call to
+ <<bfd_get_reloc_upper_bound>>. Returns the number of relocs, or
+ -1 on error.
+
+ The @var{syms} table is also needed for horrible internal magic
+ reasons.
+
+
+*/
+long
+bfd_canonicalize_reloc (abfd, asect, location, symbols)
+ bfd *abfd;
+ sec_ptr asect;
+ arelent **location;
+ asymbol **symbols;
+{
+ if (abfd->format != bfd_object) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+ return BFD_SEND (abfd, _bfd_canonicalize_reloc,
+ (abfd, asect, location, symbols));
+}
+
+/*
+FUNCTION
+ bfd_set_reloc
+
+SYNOPSIS
+ void bfd_set_reloc
+ (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
+
+DESCRIPTION
+ Set the relocation pointer and count within
+ section @var{sec} to the values @var{rel} and @var{count}.
+ The argument @var{abfd} is ignored.
+
+*/
+/*ARGSUSED*/
+void
+bfd_set_reloc (ignore_abfd, asect, location, count)
+ bfd *ignore_abfd;
+ sec_ptr asect;
+ arelent **location;
+ unsigned int count;
+{
+ asect->orelocation = location;
+ asect->reloc_count = count;
+}
+
+/*
+FUNCTION
+ bfd_set_file_flags
+
+SYNOPSIS
+ boolean bfd_set_file_flags(bfd *abfd, flagword flags);
+
+DESCRIPTION
+ Set the flag word in the BFD @var{abfd} to the value @var{flags}.
+
+ Possible errors are:
+ o <<bfd_error_wrong_format>> - The target bfd was not of object format.
+ o <<bfd_error_invalid_operation>> - The target bfd was open for reading.
+ o <<bfd_error_invalid_operation>> -
+ The flag word contained a bit which was not applicable to the
+ type of file. E.g., an attempt was made to set the <<D_PAGED>> bit
+ on a BFD format which does not support demand paging.
+
+*/
+
+boolean
+bfd_set_file_flags (abfd, flags)
+ bfd *abfd;
+ flagword flags;
+{
+ if (abfd->format != bfd_object) {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if (bfd_read_p (abfd)) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ bfd_get_file_flags (abfd) = flags;
+ if ((flags & bfd_applicable_file_flags (abfd)) != flags) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+return true;
+}
+
+void
+bfd_assert (file, line)
+ const char *file;
+ int line;
+{
+ (*_bfd_error_handler) (_("bfd assertion fail %s:%d"), file, line);
+}
+
+
+/*
+FUNCTION
+ bfd_set_start_address
+
+SYNOPSIS
+ boolean bfd_set_start_address(bfd *abfd, bfd_vma vma);
+
+DESCRIPTION
+ Make @var{vma} the entry point of output BFD @var{abfd}.
+
+RETURNS
+ Returns <<true>> on success, <<false>> otherwise.
+*/
+
+boolean
+bfd_set_start_address(abfd, vma)
+bfd *abfd;
+bfd_vma vma;
+{
+ abfd->start_address = vma;
+ return true;
+}
+
+
+/*
+FUNCTION
+ bfd_get_mtime
+
+SYNOPSIS
+ long bfd_get_mtime(bfd *abfd);
+
+DESCRIPTION
+ Return the file modification time (as read from the file system, or
+ from the archive header for archive members).
+
+*/
+
+long
+bfd_get_mtime (abfd)
+ bfd *abfd;
+{
+ FILE *fp;
+ struct stat buf;
+
+ if (abfd->mtime_set)
+ return abfd->mtime;
+
+ fp = bfd_cache_lookup (abfd);
+ if (0 != fstat (fileno (fp), &buf))
+ return 0;
+
+ abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
+ return buf.st_mtime;
+}
+
+/*
+FUNCTION
+ bfd_get_size
+
+SYNOPSIS
+ long bfd_get_size(bfd *abfd);
+
+DESCRIPTION
+ Return the file size (as read from file system) for the file
+ associated with BFD @var{abfd}.
+
+ The initial motivation for, and use of, this routine is not
+ so we can get the exact size of the object the BFD applies to, since
+ that might not be generally possible (archive members for example).
+ It would be ideal if someone could eventually modify
+ it so that such results were guaranteed.
+
+ Instead, we want to ask questions like "is this NNN byte sized
+ object I'm about to try read from file offset YYY reasonable?"
+ As as example of where we might do this, some object formats
+ use string tables for which the first <<sizeof(long)>> bytes of the
+ table contain the size of the table itself, including the size bytes.
+ If an application tries to read what it thinks is one of these
+ string tables, without some way to validate the size, and for
+ some reason the size is wrong (byte swapping error, wrong location
+ for the string table, etc.), the only clue is likely to be a read
+ error when it tries to read the table, or a "virtual memory
+ exhausted" error when it tries to allocate 15 bazillon bytes
+ of space for the 15 bazillon byte table it is about to read.
+ This function at least allows us to answer the quesion, "is the
+ size reasonable?".
+*/
+
+long
+bfd_get_size (abfd)
+ bfd *abfd;
+{
+ FILE *fp;
+ struct stat buf;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ return ((struct bfd_in_memory *) abfd->iostream)->size;
+
+ fp = bfd_cache_lookup (abfd);
+ if (0 != fstat (fileno (fp), &buf))
+ return 0;
+
+ return buf.st_size;
+}
+
+/*
+FUNCTION
+ bfd_get_gp_size
+
+SYNOPSIS
+ int bfd_get_gp_size(bfd *abfd);
+
+DESCRIPTION
+ Return the maximum size of objects to be optimized using the GP
+ register under MIPS ECOFF. This is typically set by the <<-G>>
+ argument to the compiler, assembler or linker.
+*/
+
+int
+bfd_get_gp_size (abfd)
+ bfd *abfd;
+{
+ if (abfd->format == bfd_object)
+ {
+ if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+ return ecoff_data (abfd)->gp_size;
+ else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ return elf_gp_size (abfd);
+ }
+ return 0;
+}
+
+/*
+FUNCTION
+ bfd_set_gp_size
+
+SYNOPSIS
+ void bfd_set_gp_size(bfd *abfd, int i);
+
+DESCRIPTION
+ Set the maximum size of objects to be optimized using the GP
+ register under ECOFF or MIPS ELF. This is typically set by
+ the <<-G>> argument to the compiler, assembler or linker.
+*/
+
+void
+bfd_set_gp_size (abfd, i)
+ bfd *abfd;
+ int i;
+{
+ /* Don't try to set GP size on an archive or core file! */
+ if (abfd->format != bfd_object)
+ return;
+ if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+ ecoff_data (abfd)->gp_size = i;
+ else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ elf_gp_size (abfd) = i;
+}
+
+/* Get the GP value. This is an internal function used by some of the
+ relocation special_function routines on targets which support a GP
+ register. */
+
+bfd_vma
+_bfd_get_gp_value (abfd)
+ bfd *abfd;
+{
+ if (abfd->format == bfd_object)
+ {
+ if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+ return ecoff_data (abfd)->gp;
+ else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ return elf_gp (abfd);
+ }
+ return 0;
+}
+
+/* Set the GP value. */
+
+void
+_bfd_set_gp_value (abfd, v)
+ bfd *abfd;
+ bfd_vma v;
+{
+ if (abfd->format != bfd_object)
+ return;
+ if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
+ ecoff_data (abfd)->gp = v;
+ else if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ elf_gp (abfd) = v;
+}
+
+/*
+FUNCTION
+ bfd_scan_vma
+
+SYNOPSIS
+ bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
+
+DESCRIPTION
+ Convert, like <<strtoul>>, a numerical expression
+ @var{string} into a <<bfd_vma>> integer, and return that integer.
+ (Though without as many bells and whistles as <<strtoul>>.)
+ The expression is assumed to be unsigned (i.e., positive).
+ If given a @var{base}, it is used as the base for conversion.
+ A base of 0 causes the function to interpret the string
+ in hex if a leading "0x" or "0X" is found, otherwise
+ in octal if a leading zero is found, otherwise in decimal.
+
+ Overflow is not detected.
+*/
+
+bfd_vma
+bfd_scan_vma (string, end, base)
+ CONST char *string;
+ CONST char **end;
+ int base;
+{
+ bfd_vma value;
+ int digit;
+
+ /* Let the host do it if possible. */
+ if (sizeof(bfd_vma) <= sizeof(unsigned long))
+ return (bfd_vma) strtoul (string, (char **) end, base);
+
+ /* A negative base makes no sense, and we only need to go as high as hex. */
+ if ((base < 0) || (base > 16))
+ return (bfd_vma) 0;
+
+ if (base == 0)
+ {
+ if (string[0] == '0')
+ {
+ if ((string[1] == 'x') || (string[1] == 'X'))
+ base = 16;
+ /* XXX should we also allow "0b" or "0B" to set base to 2? */
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+ if ((base == 16) &&
+ (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
+ string += 2;
+ /* XXX should we also skip over "0b" or "0B" if base is 2? */
+
+/* Speed could be improved with a table like hex_value[] in gas. */
+#define HEX_VALUE(c) \
+ (isxdigit ((unsigned char) c) \
+ ? (isdigit ((unsigned char) c) \
+ ? (c - '0') \
+ : (10 + c - (islower ((unsigned char) c) ? 'a' : 'A'))) \
+ : 42)
+
+ for (value = 0; (digit = HEX_VALUE(*string)) < base; string++)
+ {
+ value = value * base + digit;
+ }
+
+ if (end)
+ *end = string;
+
+ return value;
+}
+
+/*
+FUNCTION
+ bfd_copy_private_bfd_data
+
+SYNOPSIS
+ boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd);
+
+DESCRIPTION
+ Copy private BFD information from the BFD @var{ibfd} to the
+ the BFD @var{obfd}. Return <<true>> on success, <<false>> on error.
+ Possible error returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}.
+
+.#define bfd_copy_private_bfd_data(ibfd, obfd) \
+. BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+. (ibfd, obfd))
+
+*/
+
+/*
+FUNCTION
+ bfd_merge_private_bfd_data
+
+SYNOPSIS
+ boolean bfd_merge_private_bfd_data(bfd *ibfd, bfd *obfd);
+
+DESCRIPTION
+ Merge private BFD information from the BFD @var{ibfd} to the
+ the output file BFD @var{obfd} when linking. Return <<true>>
+ on success, <<false>> on error. Possible error returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}.
+
+.#define bfd_merge_private_bfd_data(ibfd, obfd) \
+. BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+. (ibfd, obfd))
+
+*/
+
+/*
+FUNCTION
+ bfd_set_private_flags
+
+SYNOPSIS
+ boolean bfd_set_private_flags(bfd *abfd, flagword flags);
+
+DESCRIPTION
+ Set private BFD flag information in the BFD @var{abfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}.
+
+.#define bfd_set_private_flags(abfd, flags) \
+. BFD_SEND (abfd, _bfd_set_private_flags, \
+. (abfd, flags))
+
+*/
+
+/*
+FUNCTION
+ stuff
+
+DESCRIPTION
+ Stuff which should be documented:
+
+.#define bfd_sizeof_headers(abfd, reloc) \
+. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+.
+.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+. BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line))
+.
+. {* Do these three do anything useful at all, for any back end? *}
+.#define bfd_debug_info_start(abfd) \
+. BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+.
+.#define bfd_debug_info_end(abfd) \
+. BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+.
+.#define bfd_debug_info_accumulate(abfd, section) \
+. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+.
+.
+.#define bfd_stat_arch_elt(abfd, stat) \
+. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+.
+.#define bfd_update_armap_timestamp(abfd) \
+. BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))
+.
+.#define bfd_set_arch_mach(abfd, arch, mach)\
+. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
+.
+.#define bfd_relax_section(abfd, section, link_info, again) \
+. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
+.
+.#define bfd_gc_sections(abfd, link_info) \
+. BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))
+.
+.#define bfd_link_hash_table_create(abfd) \
+. BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
+.
+.#define bfd_link_add_symbols(abfd, info) \
+. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
+.
+.#define bfd_final_link(abfd, info) \
+. BFD_SEND (abfd, _bfd_final_link, (abfd, info))
+.
+.#define bfd_free_cached_info(abfd) \
+. BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
+.
+.#define bfd_get_dynamic_symtab_upper_bound(abfd) \
+. BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
+.
+.#define bfd_print_private_bfd_data(abfd, file)\
+. BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))
+.
+.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
+. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
+.
+.#define bfd_get_dynamic_reloc_upper_bound(abfd) \
+. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
+.
+.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
+. BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
+.
+.extern bfd_byte *bfd_get_relocated_section_contents
+. PARAMS ((bfd *, struct bfd_link_info *,
+. struct bfd_link_order *, bfd_byte *,
+. boolean, asymbol **));
+.
+
+*/
+
+bfd_byte *
+bfd_get_relocated_section_contents (abfd, link_info, link_order, data,
+ relocateable, symbols)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ bfd *abfd2;
+ bfd_byte *(*fn) PARAMS ((bfd *, struct bfd_link_info *,
+ struct bfd_link_order *, bfd_byte *, boolean,
+ asymbol **));
+
+ if (link_order->type == bfd_indirect_link_order)
+ {
+ abfd2 = link_order->u.indirect.section->owner;
+ if (abfd2 == 0)
+ abfd2 = abfd;
+ }
+ else
+ abfd2 = abfd;
+ fn = abfd2->xvec->_bfd_get_relocated_section_contents;
+
+ return (*fn) (abfd, link_info, link_order, data, relocateable, symbols);
+}
+
+/* Record information about an ELF program header. */
+
+boolean
+bfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at,
+ includes_filehdr, includes_phdrs, count, secs)
+ bfd *abfd;
+ unsigned long type;
+ boolean flags_valid;
+ flagword flags;
+ boolean at_valid;
+ bfd_vma at;
+ boolean includes_filehdr;
+ boolean includes_phdrs;
+ unsigned int count;
+ asection **secs;
+{
+ struct elf_segment_map *m, **pm;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return true;
+
+ m = ((struct elf_segment_map *)
+ bfd_alloc (abfd,
+ (sizeof (struct elf_segment_map)
+ + ((size_t) count - 1) * sizeof (asection *))));
+ if (m == NULL)
+ return false;
+
+ m->next = NULL;
+ m->p_type = type;
+ m->p_flags = flags;
+ m->p_paddr = at;
+ m->p_flags_valid = flags_valid;
+ m->p_paddr_valid = at_valid;
+ m->includes_filehdr = includes_filehdr;
+ m->includes_phdrs = includes_phdrs;
+ m->count = count;
+ if (count > 0)
+ memcpy (m->sections, secs, count * sizeof (asection *));
+
+ for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
+ ;
+ *pm = m;
+
+ return true;
+}
diff --git a/bfd/binary.c b/bfd/binary.c
new file mode 100644
index 00000000000..6c63fff4adf
--- /dev/null
+++ b/bfd/binary.c
@@ -0,0 +1,386 @@
+/* BFD back-end for binary objects.
+ Copyright 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This is a BFD backend which may be used to write binary objects.
+ It may only be used for output, not input. The intention is that
+ this may be used as an output format for objcopy in order to
+ generate raw binary data.
+
+ This is very simple. The only complication is that the real data
+ will start at some address X, and in some cases we will not want to
+ include X zeroes just to get to that point. Since the start
+ address is not meaningful for this object file format, we use it
+ instead to indicate the number of zeroes to skip at the start of
+ the file. objcopy cooperates by specially setting the start
+ address to zero by default. */
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* Any bfd we create by reading a binary file has three symbols:
+ a start symbol, an end symbol, and an absolute length symbol. */
+#define BIN_SYMS 3
+
+static boolean binary_mkobject PARAMS ((bfd *));
+static const bfd_target *binary_object_p PARAMS ((bfd *));
+static boolean binary_get_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static long binary_get_symtab_upper_bound PARAMS ((bfd *));
+static char *mangle_name PARAMS ((bfd *, char *));
+static long binary_get_symtab PARAMS ((bfd *, asymbol **));
+static asymbol *binary_make_empty_symbol PARAMS ((bfd *));
+static void binary_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static boolean binary_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static int binary_sizeof_headers PARAMS ((bfd *, boolean));
+
+/* Create a binary object. Invoked via bfd_set_format. */
+
+static boolean
+binary_mkobject (abfd)
+ bfd *abfd;
+{
+ return true;
+}
+
+/* Any file may be considered to be a binary file, provided the target
+ was not defaulted. That is, it must be explicitly specified as
+ being binary. */
+
+static const bfd_target *
+binary_object_p (abfd)
+ bfd *abfd;
+{
+ struct stat statbuf;
+ asection *sec;
+
+ if (abfd->target_defaulted)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ abfd->symcount = BIN_SYMS;
+
+ /* Find the file size. */
+ if (bfd_stat (abfd, &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ /* One data section. */
+ sec = bfd_make_section (abfd, ".data");
+ if (sec == NULL)
+ return NULL;
+ sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS;
+ sec->vma = 0;
+ sec->_raw_size = statbuf.st_size;
+ sec->filepos = 0;
+
+ abfd->tdata.any = (PTR) sec;
+
+ return abfd->xvec;
+}
+
+#define binary_close_and_cleanup _bfd_generic_close_and_cleanup
+#define binary_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define binary_new_section_hook _bfd_generic_new_section_hook
+
+/* Get contents of the only section. */
+
+static boolean
+binary_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || bfd_read (location, 1, count, abfd) != count)
+ return false;
+ return true;
+}
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+binary_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ return (BIN_SYMS + 1) * sizeof (asymbol *);
+}
+
+/* Create a symbol name based on the bfd's filename. */
+
+static char *
+mangle_name (abfd, suffix)
+ bfd *abfd;
+ char *suffix;
+{
+ int size;
+ char *buf;
+ char *p;
+
+ size = (strlen (bfd_get_filename (abfd))
+ + strlen (suffix)
+ + sizeof "_binary__");
+
+ buf = (char *) bfd_alloc (abfd, size);
+ if (buf == NULL)
+ return "";
+
+ sprintf (buf, "_binary_%s_%s", bfd_get_filename (abfd), suffix);
+
+ /* Change any non-alphanumeric characters to underscores. */
+ for (p = buf; *p; p++)
+ if (! isalnum ((unsigned char) *p))
+ *p = '_';
+
+ return buf;
+}
+
+/* Return the symbol table. */
+
+static long
+binary_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ asection *sec = (asection *) abfd->tdata.any;
+ asymbol *syms;
+ unsigned int i;
+
+ syms = (asymbol *) bfd_alloc (abfd, BIN_SYMS * sizeof (asymbol));
+ if (syms == NULL)
+ return false;
+
+ /* Start symbol. */
+ syms[0].the_bfd = abfd;
+ syms[0].name = mangle_name (abfd, "start");
+ syms[0].value = 0;
+ syms[0].flags = BSF_GLOBAL;
+ syms[0].section = sec;
+ syms[0].udata.p = NULL;
+
+ /* End symbol. */
+ syms[1].the_bfd = abfd;
+ syms[1].name = mangle_name (abfd, "end");
+ syms[1].value = sec->_raw_size;
+ syms[1].flags = BSF_GLOBAL;
+ syms[1].section = sec;
+ syms[1].udata.p = NULL;
+
+ /* Size symbol. */
+ syms[2].the_bfd = abfd;
+ syms[2].name = mangle_name (abfd, "size");
+ syms[2].value = sec->_raw_size;
+ syms[2].flags = BSF_GLOBAL;
+ syms[2].section = bfd_abs_section_ptr;
+ syms[2].udata.p = NULL;
+
+ for (i = 0; i < BIN_SYMS; i++)
+ *alocation++ = syms++;
+ *alocation = NULL;
+
+ return BIN_SYMS;
+}
+
+/* Make an empty symbol. */
+
+static asymbol *
+binary_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ return (asymbol *) bfd_alloc (abfd, sizeof (asymbol));
+}
+
+#define binary_print_symbol _bfd_nosymbols_print_symbol
+
+/* Get information about a symbol. */
+
+static void
+binary_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+#define binary_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define binary_get_lineno _bfd_nosymbols_get_lineno
+#define binary_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define binary_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define binary_read_minisymbols _bfd_generic_read_minisymbols
+#define binary_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define binary_get_reloc_upper_bound \
+ ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
+#define binary_canonicalize_reloc \
+ ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
+#define binary_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+/* Set the architecture of a binary file. */
+#define binary_set_arch_mach _bfd_generic_set_arch_mach
+
+/* Write section contents of a binary file. */
+
+static boolean
+binary_set_section_contents (abfd, sec, data, offset, size)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ file_ptr offset;
+ bfd_size_type size;
+{
+ if (! abfd->output_has_begun)
+ {
+ boolean found_low;
+ bfd_vma low;
+ asection *s;
+
+ /* The lowest section LMA sets the virtual address of the start
+ of the file. We use this to set the file position of all the
+ sections. */
+ found_low = false;
+ low = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if (((s->flags
+ & (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_NEVER_LOAD))
+ == (SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC))
+ && (! found_low || s->lma < low))
+ {
+ low = s->lma;
+ found_low = true;
+ }
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ s->filepos = s->lma - low;
+
+ /* Skip following warning check for sections that will not
+ occupy file space. */
+ if ((s->flags
+ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_NEVER_LOAD))
+ != (SEC_HAS_CONTENTS | SEC_ALLOC))
+ continue;
+
+ /* If attempting to generate a binary file from a bfd with
+ LMA's all over the place, huge (sparse?) binary files may
+ result. This condition attempts to detect this situation
+ and print a warning. Better heuristics would be nice to
+ have. */
+
+ if (s->filepos < 0)
+ (*_bfd_error_handler)
+ (_("Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."),
+ bfd_get_section_name (abfd, s),
+ (unsigned long) s->filepos);
+ }
+
+ abfd->output_has_begun = true;
+ }
+
+ /* We don't want to output anything for a section that is neither
+ loaded nor allocated. The contents of such a section are not
+ meaningful in the binary format. */
+ if ((sec->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
+ return true;
+ if ((sec->flags & SEC_NEVER_LOAD) != 0)
+ return true;
+
+ return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
+}
+
+/* No space is required for header information. */
+
+static int
+binary_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return 0;
+}
+
+#define binary_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define binary_bfd_relax_section bfd_generic_relax_section
+#define binary_bfd_gc_sections bfd_generic_gc_sections
+#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define binary_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define binary_bfd_final_link _bfd_generic_final_link
+#define binary_bfd_link_split_section _bfd_generic_link_split_section
+#define binary_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+const bfd_target binary_vec =
+{
+ "binary", /* name */
+ bfd_target_unknown_flavour, /* flavour */
+ BFD_ENDIAN_UNKNOWN, /* byteorder */
+ BFD_ENDIAN_UNKNOWN, /* header_byteorder */
+ EXEC_P, /* object_flags */
+ (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ { /* bfd_check_format */
+ _bfd_dummy_target,
+ binary_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format */
+ bfd_false,
+ binary_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (binary),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (binary),
+ BFD_JUMP_TABLE_RELOCS (binary),
+ BFD_JUMP_TABLE_WRITE (binary),
+ BFD_JUMP_TABLE_LINK (binary),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL
+};
diff --git a/bfd/bout.c b/bfd/bout.c
new file mode 100644
index 00000000000..4ef10f52057
--- /dev/null
+++ b/bfd/bout.c
@@ -0,0 +1,1534 @@
+/* BFD back-end for Intel 960 b.out binaries.
+ Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "bout.h"
+
+#include "aout/stab_gnu.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+
+static int aligncode PARAMS ((bfd *abfd, asection *input_section,
+ arelent *r, unsigned int shrink));
+static void perform_slip PARAMS ((bfd *abfd, unsigned int slip,
+ asection *input_section, bfd_vma value));
+static boolean b_out_squirt_out_relocs PARAMS ((bfd *abfd, asection *section));
+static const bfd_target *b_out_callback PARAMS ((bfd *));
+static bfd_reloc_status_type calljx_callback
+ PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR src, PTR dst,
+ asection *));
+static bfd_reloc_status_type callj_callback
+ PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR data,
+ unsigned int srcidx, unsigned int dstidx, asection *, boolean));
+static bfd_vma get_value PARAMS ((arelent *, struct bfd_link_info *,
+ asection *));
+static int abs32code PARAMS ((bfd *, asection *, arelent *,
+ unsigned int, struct bfd_link_info *));
+static boolean b_out_bfd_relax_section PARAMS ((bfd *, asection *,
+ struct bfd_link_info *,
+ boolean *));
+static bfd_byte *b_out_bfd_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, boolean, asymbol **));
+
+/* Swaps the information in an executable header taken from a raw byte
+ stream memory image, into the internal exec_header structure. */
+
+void
+bout_swap_exec_header_in (abfd, raw_bytes, execp)
+ bfd *abfd;
+ struct external_exec *raw_bytes;
+ struct internal_exec *execp;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
+ execp->a_text = GET_WORD (abfd, bytes->e_text);
+ execp->a_data = GET_WORD (abfd, bytes->e_data);
+ execp->a_bss = GET_WORD (abfd, bytes->e_bss);
+ execp->a_syms = GET_WORD (abfd, bytes->e_syms);
+ execp->a_entry = GET_WORD (abfd, bytes->e_entry);
+ execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
+ execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
+ execp->a_tload = GET_WORD (abfd, bytes->e_tload);
+ execp->a_dload = GET_WORD (abfd, bytes->e_dload);
+ execp->a_talign = bytes->e_talign[0];
+ execp->a_dalign = bytes->e_dalign[0];
+ execp->a_balign = bytes->e_balign[0];
+ execp->a_relaxable = bytes->e_relaxable[0];
+}
+
+/* Swaps the information in an internal exec header structure into the
+ supplied buffer ready for writing to disk. */
+
+PROTO(void, bout_swap_exec_header_out,
+ (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *raw_bytes));
+void
+bout_swap_exec_header_out (abfd, execp, raw_bytes)
+ bfd *abfd;
+ struct internal_exec *execp;
+ struct external_exec *raw_bytes;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
+ PUT_WORD (abfd, execp->a_text , bytes->e_text);
+ PUT_WORD (abfd, execp->a_data , bytes->e_data);
+ PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
+ PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
+ PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
+ PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
+ PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
+ PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
+ PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
+ bytes->e_talign[0] = execp->a_talign;
+ bytes->e_dalign[0] = execp->a_dalign;
+ bytes->e_balign[0] = execp->a_balign;
+ bytes->e_relaxable[0] = execp->a_relaxable;
+}
+
+
+static const bfd_target *
+b_out_object_p (abfd)
+ bfd *abfd;
+{
+ struct internal_exec anexec;
+ struct external_exec exec_bytes;
+
+ if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE) {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
+
+ if (N_BADMAG (anexec)) {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
+ return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
+}
+
+
+/* Finish up the opening of a b.out file for reading. Fill in all the
+ fields that are not handled by common code. */
+
+static const bfd_target *
+b_out_callback (abfd)
+ bfd *abfd;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+ unsigned long bss_start;
+
+ /* Architecture and machine type */
+ bfd_set_arch_mach(abfd,
+ bfd_arch_i960, /* B.out only used on i960 */
+ bfd_mach_i960_core /* Default */
+ );
+
+ /* The positions of the string table and symbol table. */
+ obj_str_filepos (abfd) = N_STROFF (*execp);
+ obj_sym_filepos (abfd) = N_SYMOFF (*execp);
+
+ /* The alignments of the sections */
+ obj_textsec (abfd)->alignment_power = execp->a_talign;
+ obj_datasec (abfd)->alignment_power = execp->a_dalign;
+ obj_bsssec (abfd)->alignment_power = execp->a_balign;
+
+ /* The starting addresses of the sections. */
+ obj_textsec (abfd)->vma = execp->a_tload;
+ obj_datasec (abfd)->vma = execp->a_dload;
+
+ obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
+ obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
+
+ /* And reload the sizes, since the aout module zaps them */
+ obj_textsec (abfd)->_raw_size = execp->a_text;
+
+ bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
+ obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
+
+ obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
+
+ /* The file positions of the sections */
+ obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
+ obj_datasec (abfd)->filepos = N_DATOFF(*execp);
+
+ /* The file positions of the relocation info */
+ obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
+ obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
+
+ adata(abfd).page_size = 1; /* Not applicable. */
+ adata(abfd).segment_size = 1; /* Not applicable. */
+ adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+
+ if (execp->a_relaxable)
+ abfd->flags |= BFD_IS_RELAXABLE;
+ return abfd->xvec;
+}
+
+struct bout_data_struct {
+ struct aoutdata a;
+ struct internal_exec e;
+};
+
+static boolean
+b_out_mkobject (abfd)
+ bfd *abfd;
+{
+ struct bout_data_struct *rawptr;
+
+ rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
+ if (rawptr == NULL)
+ return false;
+
+ abfd->tdata.bout_data = rawptr;
+ exec_hdr (abfd) = &rawptr->e;
+
+ obj_textsec (abfd) = (asection *)NULL;
+ obj_datasec (abfd) = (asection *)NULL;
+ obj_bsssec (abfd) = (asection *)NULL;
+
+ return true;
+}
+
+static int
+b_out_symbol_cmp (a, b)
+ struct aout_symbol **a, **b;
+{
+ asection *sec;
+ bfd_vma av, bv;
+
+ /* Primary key is address */
+ sec = bfd_get_section (&(*a)->symbol);
+ av = sec->output_section->vma + sec->output_offset + (*a)->symbol.value;
+ sec = bfd_get_section (&(*b)->symbol);
+ bv = sec->output_section->vma + sec->output_offset + (*b)->symbol.value;
+
+ if (av < bv)
+ return -1;
+ if (av > bv)
+ return 1;
+
+ /* Secondary key puts CALLNAME syms last and BALNAME syms first, so
+ that they have the best chance of being contiguous. */
+ if (IS_BALNAME ((*a)->other) || IS_CALLNAME ((*b)->other))
+ return -1;
+ if (IS_CALLNAME ((*a)->other) || IS_BALNAME ((*b)->other))
+ return 1;
+
+ return 0;
+}
+
+static boolean
+b_out_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec swapped_hdr;
+
+ if (! aout_32_make_sections (abfd))
+ return false;
+
+ exec_hdr (abfd)->a_info = BMAGIC;
+
+ exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size;
+ exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size;
+ exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size;
+ exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
+ exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
+ exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
+ sizeof (struct relocation_info));
+ exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
+ sizeof (struct relocation_info));
+
+ exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
+ exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
+ exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
+
+ exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
+ exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
+
+ bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE))
+ return false;
+
+ /* Now write out reloc info, followed by syms and strings */
+ if (bfd_get_symcount (abfd) != 0)
+ {
+ /* Make sure {CALL,BAL}NAME symbols remain adjacent on output
+ by sorting. This is complicated by the fact that stabs are
+ also ordered. Solve this by shifting all stabs to the end
+ in order, then sorting the rest. */
+
+ asymbol **outsyms, **p, **q;
+
+ outsyms = bfd_get_outsymbols (abfd);
+ p = outsyms + bfd_get_symcount (abfd);
+
+ for (q = p--; p >= outsyms; p--)
+ {
+ if ((*p)->flags & BSF_DEBUGGING)
+ {
+ asymbol *t = *--q;
+ *q = *p;
+ *p = t;
+ }
+ }
+
+ if (q > outsyms)
+ qsort (outsyms, q - outsyms, sizeof(asymbol*), b_out_symbol_cmp);
+
+ /* Back to your regularly scheduled program. */
+
+ 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_TROFF(*exec_hdr(abfd))), SEEK_SET) != 0)
+ return false;
+
+ if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
+ if (bfd_seek (abfd, (file_ptr)(N_DROFF(*exec_hdr(abfd))), SEEK_SET)
+ != 0)
+ return false;
+
+ if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
+ }
+ return true;
+}
+
+/** Some reloc hackery */
+
+#define CALLS 0x66003800 /* Template for 'calls' instruction */
+#define BAL 0x0b000000 /* Template for 'bal' instruction */
+#define BAL_MASK 0x00ffffff
+#define BALX 0x85f00000 /* Template for 'balx' instruction */
+#define BALX_MASK 0x0007ffff
+#define CALL 0x09000000
+#define PCREL13_MASK 0x1fff
+
+
+#define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma)
+
+/* Magic to turn callx into calljx */
+static bfd_reloc_status_type
+calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ arelent *reloc_entry;
+ PTR src;
+ PTR dst;
+ asection *input_section;
+{
+ int word = bfd_get_32 (abfd, src);
+ asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
+ aout_symbol_type *symbol = aout_symbol (symbol_in);
+ bfd_vma value;
+
+ value = get_value (reloc_entry, link_info, input_section);
+
+ if (IS_CALLNAME (symbol->other))
+ {
+ aout_symbol_type *balsym = symbol+1;
+ int inst = bfd_get_32 (abfd, (bfd_byte *) src-4);
+ /* The next symbol should be an N_BALNAME */
+ BFD_ASSERT (IS_BALNAME (balsym->other));
+ inst &= BALX_MASK;
+ inst |= BALX;
+ bfd_put_32 (abfd, inst, (bfd_byte *) dst-4);
+ symbol = balsym;
+ value = (symbol->symbol.value
+ + output_addr (symbol->symbol.section));
+ }
+
+ word += value + reloc_entry->addend;
+
+ bfd_put_32(abfd, word, dst);
+ return bfd_reloc_ok;
+}
+
+
+/* Magic to turn call into callj */
+static bfd_reloc_status_type
+callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx,
+ input_section, shrinking)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ arelent *reloc_entry;
+ PTR data;
+ unsigned int srcidx;
+ unsigned int dstidx;
+ asection *input_section;
+ boolean shrinking;
+{
+ int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx);
+ asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
+ aout_symbol_type *symbol = aout_symbol (symbol_in);
+ bfd_vma value;
+
+ value = get_value (reloc_entry, link_info, input_section);
+
+ if (IS_OTHER(symbol->other))
+ {
+ /* Call to a system procedure - replace code with system
+ procedure number. */
+ word = CALLS | (symbol->other - 1);
+ }
+ else if (IS_CALLNAME(symbol->other))
+ {
+ aout_symbol_type *balsym = symbol+1;
+
+ /* The next symbol should be an N_BALNAME. */
+ BFD_ASSERT(IS_BALNAME(balsym->other));
+
+ /* We are calling a leaf, so replace the call instruction with a
+ bal. */
+ word = BAL | ((word
+ + output_addr (balsym->symbol.section)
+ + balsym->symbol.value + reloc_entry->addend
+ - dstidx
+ - output_addr (input_section))
+ & BAL_MASK);
+ }
+ else if ((symbol->symbol.flags & BSF_SECTION_SYM) != 0)
+ {
+ /* A callj against a symbol in the same section is a fully
+ resolved relative call. We don't need to do anything here.
+ If the symbol is not in the same section, I'm not sure what
+ to do; fortunately, this case will probably never arise. */
+ BFD_ASSERT (! shrinking);
+ BFD_ASSERT (symbol->symbol.section == input_section);
+ }
+ else
+ {
+ word = CALL | (((word & BAL_MASK)
+ + value
+ + reloc_entry->addend
+ - (shrinking ? dstidx : 0)
+ - output_addr (input_section))
+ & BAL_MASK);
+ }
+ bfd_put_32(abfd, word, (bfd_byte *) data + dstidx);
+ return bfd_reloc_ok;
+}
+
+/* type rshift size bitsize pcrel bitpos absolute overflow check*/
+
+#define ABS32CODE 0
+#define ABS32CODE_SHRUNK 1
+#define PCREL24 2
+#define CALLJ 3
+#define ABS32 4
+#define PCREL13 5
+#define ABS32_MAYBE_RELAXABLE 1
+#define ABS32_WAS_RELAXABLE 2
+
+#define ALIGNER 10
+#define ALIGNDONE 11
+static reloc_howto_type howto_reloc_callj =
+HOWTO(CALLJ, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
+static reloc_howto_type howto_reloc_abs32 =
+HOWTO(ABS32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"abs32", true, 0xffffffff,0xffffffff,false);
+static reloc_howto_type howto_reloc_pcrel24 =
+HOWTO(PCREL24, 0, 2, 24, true, 0, complain_overflow_signed,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
+
+static reloc_howto_type howto_reloc_pcrel13 =
+HOWTO(PCREL13, 0, 2, 13, true, 0, complain_overflow_signed,0,"pcrel13", true, 0x00001fff,0x00001fff,false);
+
+
+static reloc_howto_type howto_reloc_abs32codeshrunk =
+HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false);
+
+static reloc_howto_type howto_reloc_abs32code =
+HOWTO(ABS32CODE, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"callx", true, 0xffffffff,0xffffffff,false);
+
+static reloc_howto_type howto_align_table[] = {
+ HOWTO (ALIGNER, 0, 0x1, 0, false, 0, complain_overflow_dont, 0, "align16", false, 0, 0, false),
+ HOWTO (ALIGNER, 0, 0x3, 0, false, 0, complain_overflow_dont, 0, "align32", false, 0, 0, false),
+ HOWTO (ALIGNER, 0, 0x7, 0, false, 0, complain_overflow_dont, 0, "align64", false, 0, 0, false),
+ HOWTO (ALIGNER, 0, 0xf, 0, false, 0, complain_overflow_dont, 0, "align128", false, 0, 0, false),
+};
+
+static reloc_howto_type howto_done_align_table[] = {
+ HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, complain_overflow_dont, 0, "donealign16", false, 0, 0, false),
+ HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, complain_overflow_dont, 0, "donealign32", false, 0, 0, false),
+ HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, complain_overflow_dont, 0, "donealign64", false, 0, 0, false),
+ HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, complain_overflow_dont, 0, "donealign128", false, 0, 0, false),
+};
+
+static reloc_howto_type *
+b_out_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ default:
+ return 0;
+ case BFD_RELOC_I960_CALLJ:
+ return &howto_reloc_callj;
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return &howto_reloc_abs32;
+ case BFD_RELOC_24_PCREL:
+ return &howto_reloc_pcrel24;
+ }
+}
+
+/* Allocate enough room for all the reloc entries, plus pointers to them all */
+
+static boolean
+b_out_slurp_reloc_table (abfd, asect, symbols)
+ bfd *abfd;
+ sec_ptr asect;
+ asymbol **symbols;
+{
+ register struct relocation_info *rptr;
+ unsigned int counter ;
+ arelent *cache_ptr ;
+ int extern_mask, pcrel_mask, callj_mask, length_shift;
+ int incode_mask;
+ int size_mask;
+ bfd_vma prev_addr = 0;
+ unsigned int count;
+ size_t reloc_size;
+ struct relocation_info *relocs;
+ arelent *reloc_cache;
+
+ if (asect->relocation)
+ return true;
+ if (!aout_32_slurp_symbol_table (abfd))
+ return false;
+
+ if (asect == obj_datasec (abfd)) {
+ reloc_size = exec_hdr(abfd)->a_drsize;
+ goto doit;
+ }
+
+ if (asect == obj_textsec (abfd)) {
+ reloc_size = exec_hdr(abfd)->a_trsize;
+ goto doit;
+ }
+
+ if (asect == obj_bsssec (abfd)) {
+ reloc_size = 0;
+ goto doit;
+ }
+
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+
+ doit:
+ if (bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET) != 0)
+ return false;
+ count = reloc_size / sizeof (struct relocation_info);
+
+ relocs = (struct relocation_info *) bfd_malloc (reloc_size);
+ if (!relocs && reloc_size != 0)
+ return false;
+ reloc_cache = (arelent *) bfd_malloc ((count+1) * sizeof (arelent));
+ if (!reloc_cache) {
+ if (relocs != NULL)
+ free ((char*)relocs);
+ return false;
+ }
+
+ if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
+ free (reloc_cache);
+ if (relocs != NULL)
+ free (relocs);
+ return false;
+ }
+
+
+
+ if (bfd_header_big_endian (abfd)) {
+ /* big-endian bit field allocation order */
+ pcrel_mask = 0x80;
+ extern_mask = 0x10;
+ incode_mask = 0x08;
+ callj_mask = 0x02;
+ size_mask = 0x20;
+ length_shift = 5;
+ } else {
+ /* little-endian bit field allocation order */
+ pcrel_mask = 0x01;
+ extern_mask = 0x08;
+ incode_mask = 0x10;
+ callj_mask = 0x40;
+ size_mask = 0x02;
+ length_shift = 1;
+ }
+
+ for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
+ counter < count;
+ counter++, rptr++, cache_ptr++)
+ {
+ unsigned char *raw = (unsigned char *)rptr;
+ unsigned int symnum;
+ cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
+ cache_ptr->howto = 0;
+ if (bfd_header_big_endian (abfd))
+ {
+ symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
+ }
+ else
+ {
+ symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
+ }
+
+ if (raw[7] & extern_mask)
+ {
+ /* if this is set then the r_index is a index into the symbol table;
+ * if the bit is not set then r_index contains a section map.
+ * we either fill in the sym entry with a pointer to the symbol,
+ * or point to the correct section
+ */
+ cache_ptr->sym_ptr_ptr = symbols + symnum;
+ cache_ptr->addend = 0;
+ } else
+ {
+ /* in a.out symbols are relative to the beginning of the
+ * file rather than sections ?
+ * (look in translate_from_native_sym_flags)
+ * the reloc entry addend has added to it the offset into the
+ * file of the data, so subtract the base to make the reloc
+ * section relative */
+ int s;
+ {
+ /* sign-extend symnum from 24 bits to whatever host uses */
+ s = symnum;
+ if (s & (1 << 23))
+ s |= (~0) << 24;
+ }
+ cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
+ switch (s)
+ {
+ case N_TEXT:
+ case N_TEXT | N_EXT:
+ cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
+ cache_ptr->addend = - obj_textsec(abfd)->vma;
+ break;
+ case N_DATA:
+ case N_DATA | N_EXT:
+ cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
+ cache_ptr->addend = - obj_datasec(abfd)->vma;
+ break;
+ case N_BSS:
+ case N_BSS | N_EXT:
+ cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
+ cache_ptr->addend = - obj_bsssec(abfd)->vma;
+ break;
+ case N_ABS:
+ case N_ABS | N_EXT:
+ cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
+ cache_ptr->addend = 0;
+ break;
+ case -2: /* .align */
+ if (raw[7] & pcrel_mask)
+ {
+ cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
+ cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
+ {
+ /* .org? */
+ abort ();
+ }
+ cache_ptr->addend = 0;
+ break;
+ default:
+ BFD_ASSERT(0);
+ break;
+ }
+
+ }
+
+ /* the i960 only has a few relocation types:
+ abs 32-bit and pcrel 24bit. except for callj's! */
+ if (cache_ptr->howto != 0)
+ ;
+ else if (raw[7] & callj_mask)
+ {
+ cache_ptr->howto = &howto_reloc_callj;
+ }
+ else if ( raw[7] & pcrel_mask)
+ {
+ if (raw[7] & size_mask)
+ cache_ptr->howto = &howto_reloc_pcrel13;
+ else
+ cache_ptr->howto = &howto_reloc_pcrel24;
+ }
+ else
+ {
+ if (raw[7] & incode_mask)
+ {
+ cache_ptr->howto = &howto_reloc_abs32code;
+ }
+ else
+ {
+ cache_ptr->howto = &howto_reloc_abs32;
+ }
+ }
+ if (cache_ptr->address < prev_addr)
+ {
+ /* Ouch! this reloc is out of order, insert into the right place
+ */
+ arelent tmp;
+ arelent *cursor = cache_ptr-1;
+ bfd_vma stop = cache_ptr->address;
+ tmp = *cache_ptr;
+ while (cursor->address > stop && cursor >= reloc_cache)
+ {
+ cursor[1] = cursor[0];
+ cursor--;
+ }
+ cursor[1] = tmp;
+ }
+ else
+ {
+ prev_addr = cache_ptr->address;
+ }
+ }
+
+
+ if (relocs != NULL)
+ free (relocs);
+ asect->relocation = reloc_cache;
+ asect->reloc_count = count;
+
+
+ return true;
+}
+
+
+static boolean
+b_out_squirt_out_relocs (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ arelent **generic;
+ int r_extern = 0;
+ int r_idx;
+ int incode_mask;
+ int len_1;
+ unsigned int count = section->reloc_count;
+ struct relocation_info *native, *natptr;
+ size_t natsize = count * sizeof (struct relocation_info);
+ int extern_mask, pcrel_mask, len_2, callj_mask;
+ if (count == 0) return true;
+ generic = section->orelocation;
+ native = ((struct relocation_info *) bfd_malloc (natsize));
+ if (!native && natsize != 0)
+ return false;
+
+ if (bfd_header_big_endian (abfd))
+ {
+ /* Big-endian bit field allocation order */
+ pcrel_mask = 0x80;
+ extern_mask = 0x10;
+ len_2 = 0x40;
+ len_1 = 0x20;
+ callj_mask = 0x02;
+ incode_mask = 0x08;
+ }
+ else
+ {
+ /* Little-endian bit field allocation order */
+ pcrel_mask = 0x01;
+ extern_mask = 0x08;
+ len_2 = 0x04;
+ len_1 = 0x02;
+ callj_mask = 0x40;
+ incode_mask = 0x10;
+ }
+
+ for (natptr = native; count > 0; --count, ++natptr, ++generic)
+ {
+ arelent *g = *generic;
+ unsigned char *raw = (unsigned char *)natptr;
+ asymbol *sym = *(g->sym_ptr_ptr);
+
+ asection *output_section = sym->section->output_section;
+
+ bfd_h_put_32(abfd, g->address, raw);
+ /* Find a type in the output format which matches the input howto -
+ * at the moment we assume input format == output format FIXME!!
+ */
+ r_idx = 0;
+ /* FIXME: Need callj stuff here, and to check the howto entries to
+ be sure they are real for this architecture. */
+ if (g->howto== &howto_reloc_callj)
+ {
+ raw[7] = callj_mask + pcrel_mask + len_2;
+ }
+ else if (g->howto == &howto_reloc_pcrel24)
+ {
+ raw[7] = pcrel_mask + len_2;
+ }
+ else if (g->howto == &howto_reloc_pcrel13)
+ {
+ raw[7] = pcrel_mask + len_1;
+ }
+ else if (g->howto == &howto_reloc_abs32code)
+ {
+ raw[7] = len_2 + incode_mask;
+ }
+ else if (g->howto >= howto_align_table
+ && g->howto <= (howto_align_table
+ + sizeof (howto_align_table) / sizeof (howto_align_table[0])
+ - 1))
+ {
+ /* symnum == -2; extern_mask not set, pcrel_mask set */
+ r_idx = -2;
+ r_extern = 0;
+ raw[7] = (pcrel_mask
+ | ((g->howto - howto_align_table) << 1));
+ }
+ else {
+ raw[7] = len_2;
+ }
+
+ if (r_idx != 0)
+ /* already mucked with r_extern, r_idx */;
+ else if (bfd_is_com_section (output_section)
+ || bfd_is_abs_section (output_section)
+ || bfd_is_und_section (output_section))
+ {
+
+ if (bfd_abs_section_ptr->symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_idx = 0;
+ r_extern = 0;
+ }
+ else
+ {
+ /* Fill in symbol */
+
+ r_extern = 1;
+ r_idx = (*g->sym_ptr_ptr)->udata.i;
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_idx = output_section->target_index;
+ }
+
+ if (bfd_header_big_endian (abfd)) {
+ raw[4] = (unsigned char) (r_idx >> 16);
+ raw[5] = (unsigned char) (r_idx >> 8);
+ raw[6] = (unsigned char) (r_idx );
+ } else {
+ raw[6] = (unsigned char) (r_idx >> 16);
+ raw[5] = (unsigned char) (r_idx>> 8);
+ raw[4] = (unsigned char) (r_idx );
+ }
+ if (r_extern)
+ raw[7] |= extern_mask;
+ }
+
+ if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
+ free((PTR)native);
+ return false;
+ }
+ free ((PTR)native);
+
+ return true;
+}
+
+/* This is stupid. This function should be a boolean predicate */
+static long
+b_out_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr;
+ unsigned int count;
+
+ if ((section->flags & SEC_CONSTRUCTOR) != 0)
+ {
+ arelent_chain *chain = section->constructor_chain;
+ for (count = 0; count < section->reloc_count; count++)
+ {
+ *relptr++ = &chain->relent;
+ chain = chain->next;
+ }
+ }
+ else
+ {
+ if (section->relocation == NULL
+ && ! b_out_slurp_reloc_table (abfd, section, symbols))
+ return -1;
+
+ tblptr = section->relocation;
+ for (count = 0; count++ < section->reloc_count;)
+ *relptr++ = tblptr++;
+ }
+
+ *relptr = NULL;
+
+ return section->reloc_count;
+}
+
+static long
+b_out_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ if (bfd_get_format (abfd) != bfd_object) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ if (asect->flags & SEC_CONSTRUCTOR)
+ return sizeof (arelent *) * (asect->reloc_count + 1);
+
+ if (asect == obj_datasec (abfd))
+ return (sizeof (arelent *) *
+ ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
+ +1));
+
+ if (asect == obj_textsec (abfd))
+ return (sizeof (arelent *) *
+ ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
+ +1));
+
+ if (asect == obj_bsssec (abfd))
+ return 0;
+
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+}
+
+static boolean
+b_out_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+
+ if (abfd->output_has_begun == false) { /* set by bfd.c handler */
+ if (! aout_32_make_sections (abfd))
+ return false;
+
+ obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
+ obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos
+ + obj_textsec (abfd)->_raw_size;
+
+ }
+ /* regardless, once we know what we're doing, we might as well get going */
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
+ return false;
+
+ if (count != 0) {
+ return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
+ }
+ return true;
+}
+
+static boolean
+b_out_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ bfd_default_set_arch_mach(abfd, arch, machine);
+
+ if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
+ return true;
+ if (arch == bfd_arch_i960) /* i960 default is OK */
+ switch (machine) {
+ case bfd_mach_i960_core:
+ case bfd_mach_i960_kb_sb:
+ case bfd_mach_i960_mc:
+ case bfd_mach_i960_xa:
+ case bfd_mach_i960_ca:
+ case bfd_mach_i960_ka_sa:
+ case bfd_mach_i960_jx:
+ case bfd_mach_i960_hx:
+ case 0:
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+static int
+b_out_sizeof_headers (ignore_abfd, ignore)
+ bfd *ignore_abfd;
+ boolean ignore;
+{
+ return sizeof(struct internal_exec);
+}
+
+
+
+/************************************************************************/
+static bfd_vma
+get_value (reloc, link_info, input_section)
+ arelent *reloc;
+ struct bfd_link_info *link_info;
+ asection *input_section;
+{
+ bfd_vma value;
+ asymbol *symbol = *(reloc->sym_ptr_ptr);
+
+ /* A symbol holds a pointer to a section, and an offset from the
+ base of the section. To relocate, we find where the section will
+ live in the output and add that in */
+
+ if (bfd_is_und_section (symbol->section))
+ {
+ struct bfd_link_hash_entry *h;
+
+ /* The symbol is undefined in this BFD. Look it up in the
+ global linker hash table. FIXME: This should be changed when
+ we convert b.out to use a specific final_link function and
+ change the interface to bfd_relax_section to not require the
+ generic symbols. */
+ h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
+ bfd_asymbol_name (symbol),
+ false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ value = h->u.def.value + output_addr (h->u.def.section);
+ else if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_common)
+ value = h->u.c.size;
+ else
+ {
+ if (! ((*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (symbol),
+ input_section->owner, input_section, reloc->address)))
+ abort ();
+ value = 0;
+ }
+ }
+ else
+ {
+ value = symbol->value + output_addr (symbol->section);
+ }
+
+ /* Add the value contained in the relocation */
+ value += reloc->addend;
+
+ return value;
+}
+
+static void
+perform_slip (abfd, slip, input_section, value)
+ bfd *abfd;
+ unsigned int slip;
+ asection *input_section;
+ bfd_vma value;
+{
+ asymbol **s;
+
+ s = _bfd_generic_link_get_symbols (abfd);
+ BFD_ASSERT (s != (asymbol **) NULL);
+
+ /* Find all symbols past this point, and make them know
+ what's happened */
+ while (*s)
+ {
+ asymbol *p = *s;
+ if (p->section == input_section)
+ {
+ /* This was pointing into this section, so mangle it */
+ if (p->value > value)
+ {
+ p->value -=slip;
+ if (p->udata.p != NULL)
+ {
+ struct generic_link_hash_entry *h;
+
+ h = (struct generic_link_hash_entry *) p->udata.p;
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined);
+ h->root.u.def.value -= slip;
+ BFD_ASSERT (h->root.u.def.value == p->value);
+ }
+ }
+ }
+ s++;
+
+ }
+}
+
+/* This routine works out if the thing we want to get to can be
+ reached with a 24bit offset instead of a 32 bit one.
+ If it can, then it changes the amode */
+
+static int
+abs32code (abfd, input_section, r, shrink, link_info)
+ bfd *abfd;
+ asection *input_section;
+ arelent *r;
+ unsigned int shrink;
+ struct bfd_link_info *link_info;
+{
+ bfd_vma value = get_value (r, link_info, input_section);
+ bfd_vma dot = output_addr (input_section) + r->address;
+ bfd_vma gap;
+
+ /* See if the address we're looking at within 2^23 bytes of where
+ we are, if so then we can use a small branch rather than the
+ jump we were going to */
+
+ gap = value - (dot - shrink);
+
+
+ if (-1<<23 < (long)gap && (long)gap < 1<<23 )
+ {
+ /* Change the reloc type from 32bitcode possible 24, to 24bit
+ possible 32 */
+
+ r->howto = &howto_reloc_abs32codeshrunk;
+ /* The place to relc moves back by four bytes */
+ r->address -=4;
+
+ /* This will be four bytes smaller in the long run */
+ shrink += 4 ;
+ perform_slip (abfd, 4, input_section, r->address-shrink + 4);
+ }
+ return shrink;
+}
+
+static int
+aligncode (abfd, input_section, r, shrink)
+ bfd *abfd;
+ asection *input_section;
+ arelent *r;
+ unsigned int shrink;
+{
+ bfd_vma dot = output_addr (input_section) + r->address;
+ bfd_vma gap;
+ bfd_vma old_end;
+ bfd_vma new_end;
+ int shrink_delta;
+ int size = r->howto->size;
+
+ /* Reduce the size of the alignment so that it's still aligned but
+ smaller - the current size is already the same size as or bigger
+ than the alignment required. */
+
+ /* calculate the first byte following the padding before we optimize */
+ old_end = ((dot + size ) & ~size) + size+1;
+ /* work out where the new end will be - remember that we're smaller
+ than we used to be */
+ new_end = ((dot - shrink + size) & ~size);
+
+ /* This is the new end */
+ gap = old_end - ((dot + size) & ~size);
+
+ shrink_delta = (old_end - new_end) - shrink;
+
+ if (shrink_delta)
+ {
+ /* Change the reloc so that it knows how far to align to */
+ r->howto = howto_done_align_table + (r->howto - howto_align_table);
+
+ /* Encode the stuff into the addend - for future use we need to
+ know how big the reloc used to be */
+ r->addend = old_end - dot + r->address;
+
+ /* This will be N bytes smaller in the long run, adjust all the symbols */
+ perform_slip (abfd, shrink_delta, input_section, r->address - shrink);
+ shrink += shrink_delta;
+ }
+ return shrink;
+}
+
+static boolean
+b_out_bfd_relax_section (abfd, i, link_info, again)
+ bfd *abfd;
+ asection *i;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ /* Get enough memory to hold the stuff */
+ bfd *input_bfd = i->owner;
+ asection *input_section = i;
+ int shrink = 0 ;
+ arelent **reloc_vector = NULL;
+ long reloc_size = bfd_get_reloc_upper_bound(input_bfd,
+ input_section);
+
+ if (reloc_size < 0)
+ return false;
+
+ /* We only run this relaxation once. It might work to run it
+ multiple times, but it hasn't been tested. */
+ *again = false;
+
+ if (reloc_size)
+ {
+ long reloc_count;
+
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ /* Get the relocs and think about them */
+ reloc_count =
+ bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector,
+ _bfd_generic_link_get_symbols (input_bfd));
+ if (reloc_count < 0)
+ goto error_return;
+ if (reloc_count > 0)
+ {
+ arelent **parent;
+ for (parent = reloc_vector; *parent; parent++)
+ {
+ arelent *r = *parent;
+ switch (r->howto->type)
+ {
+ case ALIGNER:
+ /* An alignment reloc */
+ shrink = aligncode (abfd, input_section, r, shrink);
+ break;
+ case ABS32CODE:
+ /* A 32bit reloc in an addressing mode */
+ shrink = abs32code (input_bfd, input_section, r, shrink,
+ link_info);
+ break;
+ case ABS32CODE_SHRUNK:
+ shrink+=4;
+ break;
+ }
+ }
+ }
+ }
+ input_section->_cooked_size = input_section->_raw_size - shrink;
+
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return true;
+ error_return:
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return false;
+}
+
+static bfd_byte *
+b_out_bfd_get_relocated_section_contents (output_bfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ /* Get enough memory to hold the stuff */
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd,
+ input_section);
+ arelent **reloc_vector = NULL;
+ long reloc_count;
+
+ if (reloc_size < 0)
+ goto error_return;
+
+ /* If producing relocateable output, don't bother to relax. */
+ if (relocateable)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order,
+ data, relocateable,
+ symbols);
+
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ input_section->reloc_done = 1;
+
+ /* read in the section */
+ BFD_ASSERT (true == bfd_get_section_contents (input_bfd,
+ input_section,
+ data,
+ 0,
+ input_section->_raw_size));
+
+ reloc_count = bfd_canonicalize_reloc (input_bfd,
+ input_section,
+ reloc_vector,
+ symbols);
+ if (reloc_count < 0)
+ goto error_return;
+ if (reloc_count > 0)
+ {
+ arelent **parent = reloc_vector;
+ arelent *reloc ;
+
+ unsigned int dst_address = 0;
+ unsigned int src_address = 0;
+ unsigned int run;
+ unsigned int idx;
+
+ /* Find how long a run we can do */
+ while (dst_address < link_order->size)
+ {
+ reloc = *parent;
+ if (reloc)
+ {
+ /* Note that the relaxing didn't tie up the addresses in the
+ relocation, so we use the original address to work out the
+ run of non-relocated data */
+ BFD_ASSERT (reloc->address >= src_address);
+ run = reloc->address - src_address;
+ parent++;
+ }
+ else
+ {
+ run = link_order->size - dst_address;
+ }
+ /* Copy the bytes */
+ for (idx = 0; idx < run; idx++)
+ {
+ data[dst_address++] = data[src_address++];
+ }
+
+ /* Now do the relocation */
+
+ if (reloc)
+ {
+ switch (reloc->howto->type)
+ {
+ case ABS32CODE:
+ calljx_callback (input_bfd, link_info, reloc,
+ src_address + data, dst_address + data,
+ input_section);
+ src_address+=4;
+ dst_address+=4;
+ break;
+ case ABS32:
+ bfd_put_32 (input_bfd,
+ (bfd_get_32 (input_bfd, data + src_address)
+ + get_value (reloc, link_info, input_section)),
+ data + dst_address);
+ src_address+=4;
+ dst_address+=4;
+ break;
+ case CALLJ:
+ callj_callback (input_bfd, link_info, reloc, data,
+ src_address, dst_address, input_section,
+ false);
+ src_address+=4;
+ dst_address+=4;
+ break;
+ case ALIGNDONE:
+ BFD_ASSERT (reloc->addend >= src_address);
+ BFD_ASSERT (reloc->addend <= input_section->_raw_size);
+ src_address = reloc->addend;
+ dst_address = ((dst_address + reloc->howto->size)
+ & ~reloc->howto->size);
+ break;
+ case ABS32CODE_SHRUNK:
+ /* This used to be a callx, but we've found out that a
+ callj will reach, so do the right thing. */
+ callj_callback (input_bfd, link_info, reloc, data,
+ src_address + 4, dst_address, input_section,
+ true);
+ dst_address+=4;
+ src_address+=8;
+ break;
+ case PCREL24:
+ {
+ long int word = bfd_get_32 (input_bfd,
+ data + src_address);
+ bfd_vma value;
+
+ value = get_value (reloc, link_info, input_section);
+ word = ((word & ~BAL_MASK)
+ | (((word & BAL_MASK)
+ + value
+ - output_addr (input_section)
+ + reloc->addend)
+ & BAL_MASK));
+
+ bfd_put_32 (input_bfd, word, data + dst_address);
+ dst_address+=4;
+ src_address+=4;
+
+ }
+ break;
+
+ case PCREL13:
+ {
+ long int word = bfd_get_32 (input_bfd,
+ data + src_address);
+ bfd_vma value;
+
+ value = get_value (reloc, link_info, input_section);
+ word = ((word & ~PCREL13_MASK)
+ | (((word & PCREL13_MASK)
+ + value
+ + reloc->addend
+ - output_addr (input_section))
+ & PCREL13_MASK));
+
+ bfd_put_32 (input_bfd, word, data + dst_address);
+ dst_address+=4;
+ src_address+=4;
+
+ }
+ break;
+
+ default:
+ abort();
+ }
+ }
+ }
+ }
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return data;
+ error_return:
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return NULL;
+}
+/***********************************************************************/
+
+/* Build the transfer vectors for Big and Little-Endian B.OUT files. */
+
+#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
+
+#define b_out_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define b_out_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define b_out_bfd_final_link _bfd_generic_final_link
+#define b_out_bfd_link_split_section _bfd_generic_link_split_section
+#define b_out_bfd_gc_sections bfd_generic_gc_sections
+
+#define aout_32_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+const bfd_target b_out_vec_big_host =
+{
+ "b.out.big", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_BIG, /* hdr byte order is big */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ '_', /* symbol leading char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, b_out_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (aout_32),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
+ BFD_JUMP_TABLE_SYMBOLS (aout_32),
+ BFD_JUMP_TABLE_RELOCS (b_out),
+ BFD_JUMP_TABLE_WRITE (b_out),
+ BFD_JUMP_TABLE_LINK (b_out),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0,
+};
+
+
+const bfd_target b_out_vec_little_host =
+{
+ "b.out.little", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ '_', /* symbol leading char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, b_out_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (aout_32),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
+ BFD_JUMP_TABLE_SYMBOLS (aout_32),
+ BFD_JUMP_TABLE_RELOCS (b_out),
+ BFD_JUMP_TABLE_WRITE (b_out),
+ BFD_JUMP_TABLE_LINK (b_out),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/cache.c b/bfd/cache.c
new file mode 100644
index 00000000000..b28de4bc4b9
--- /dev/null
+++ b/bfd/cache.c
@@ -0,0 +1,350 @@
+/* BFD library -- caching of file descriptors.
+ Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ File caching
+
+ The file caching mechanism is embedded within BFD and allows
+ the application to open as many BFDs as it wants without
+ regard to the underlying operating system's file descriptor
+ limit (often as low as 20 open files). The module in
+ <<cache.c>> maintains a least recently used list of
+ <<BFD_CACHE_MAX_OPEN>> files, and exports the name
+ <<bfd_cache_lookup>>, which runs around and makes sure that
+ the required BFD is open. If not, then it chooses a file to
+ close, closes it and opens the one wanted, returning its file
+ handle.
+
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+static void insert PARAMS ((bfd *));
+static void snip PARAMS ((bfd *));
+static boolean close_one PARAMS ((void));
+static boolean bfd_cache_delete PARAMS ((bfd *));
+
+/*
+INTERNAL_FUNCTION
+ BFD_CACHE_MAX_OPEN macro
+
+DESCRIPTION
+ The maximum number of files which the cache will keep open at
+ one time.
+
+.#define BFD_CACHE_MAX_OPEN 10
+
+*/
+
+/* The number of BFD files we have open. */
+
+static int open_files;
+
+/*
+INTERNAL_FUNCTION
+ bfd_last_cache
+
+SYNOPSIS
+ extern bfd *bfd_last_cache;
+
+DESCRIPTION
+ Zero, or a pointer to the topmost BFD on the chain. This is
+ used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
+ determine when it can avoid a function call.
+*/
+
+bfd *bfd_last_cache;
+
+/*
+ INTERNAL_FUNCTION
+ bfd_cache_lookup
+
+ DESCRIPTION
+ Check to see if the required BFD is the same as the last one
+ looked up. If so, then it can use the stream in the BFD with
+ impunity, since it can't have changed since the last lookup;
+ otherwise, it has to perform the complicated lookup function.
+
+ .#define bfd_cache_lookup(x) \
+ . ((x)==bfd_last_cache? \
+ . (FILE*)(bfd_last_cache->iostream): \
+ . bfd_cache_lookup_worker(x))
+
+
+ */
+
+/* Insert a BFD into the cache. */
+
+static INLINE void
+insert (abfd)
+ bfd *abfd;
+{
+ if (bfd_last_cache == NULL)
+ {
+ abfd->lru_next = abfd;
+ abfd->lru_prev = abfd;
+ }
+ else
+ {
+ abfd->lru_next = bfd_last_cache;
+ abfd->lru_prev = bfd_last_cache->lru_prev;
+ abfd->lru_prev->lru_next = abfd;
+ abfd->lru_next->lru_prev = abfd;
+ }
+ bfd_last_cache = abfd;
+}
+
+/* Remove a BFD from the cache. */
+
+static INLINE void
+snip (abfd)
+ bfd *abfd;
+{
+ abfd->lru_prev->lru_next = abfd->lru_next;
+ abfd->lru_next->lru_prev = abfd->lru_prev;
+ if (abfd == bfd_last_cache)
+ {
+ bfd_last_cache = abfd->lru_next;
+ if (abfd == bfd_last_cache)
+ bfd_last_cache = NULL;
+ }
+}
+
+/* We need to open a new file, and the cache is full. Find the least
+ recently used cacheable BFD and close it. */
+
+static boolean
+close_one ()
+{
+ register bfd *kill;
+
+ if (bfd_last_cache == NULL)
+ kill = NULL;
+ else
+ {
+ for (kill = bfd_last_cache->lru_prev;
+ ! kill->cacheable;
+ kill = kill->lru_prev)
+ {
+ if (kill == bfd_last_cache)
+ {
+ kill = NULL;
+ break;
+ }
+ }
+ }
+
+ if (kill == NULL)
+ {
+ /* There are no open cacheable BFD's. */
+ return true;
+ }
+
+ kill->where = ftell ((FILE *) kill->iostream);
+
+ return bfd_cache_delete (kill);
+}
+
+/* Close a BFD and remove it from the cache. */
+
+static boolean
+bfd_cache_delete (abfd)
+ bfd *abfd;
+{
+ boolean ret;
+
+ if (fclose ((FILE *) abfd->iostream) == 0)
+ ret = true;
+ else
+ {
+ ret = false;
+ bfd_set_error (bfd_error_system_call);
+ }
+
+ snip (abfd);
+
+ abfd->iostream = NULL;
+ --open_files;
+
+ return ret;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_cache_init
+
+SYNOPSIS
+ boolean bfd_cache_init (bfd *abfd);
+
+DESCRIPTION
+ Add a newly opened BFD to the cache.
+*/
+
+boolean
+bfd_cache_init (abfd)
+ bfd *abfd;
+{
+ BFD_ASSERT (abfd->iostream != NULL);
+ if (open_files >= BFD_CACHE_MAX_OPEN)
+ {
+ if (! close_one ())
+ return false;
+ }
+ insert (abfd);
+ ++open_files;
+ return true;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_cache_close
+
+SYNOPSIS
+ boolean bfd_cache_close (bfd *abfd);
+
+DESCRIPTION
+ Remove the BFD @var{abfd} from the cache. If the attached file is open,
+ then close it too.
+
+RETURNS
+ <<false>> is returned if closing the file fails, <<true>> is
+ returned if all is well.
+*/
+
+boolean
+bfd_cache_close (abfd)
+ bfd *abfd;
+{
+ if (abfd->iostream == NULL
+ || (abfd->flags & BFD_IN_MEMORY) != 0)
+ return true;
+
+ return bfd_cache_delete (abfd);
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_open_file
+
+SYNOPSIS
+ FILE* bfd_open_file(bfd *abfd);
+
+DESCRIPTION
+ Call the OS to open a file for @var{abfd}. Return the <<FILE *>>
+ (possibly <<NULL>>) that results from this operation. Set up the
+ BFD so that future accesses know the file is open. If the <<FILE *>>
+ returned is <<NULL>>, then it won't have been put in the
+ cache, so it won't have to be removed from it.
+*/
+
+FILE *
+bfd_open_file (abfd)
+ bfd *abfd;
+{
+ abfd->cacheable = true; /* Allow it to be closed later. */
+
+ if (open_files >= BFD_CACHE_MAX_OPEN)
+ {
+ if (! close_one ())
+ return NULL;
+ }
+
+ switch (abfd->direction)
+ {
+ case read_direction:
+ case no_direction:
+ abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
+ break;
+ case both_direction:
+ case write_direction:
+ if (abfd->opened_once == true)
+ {
+ abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
+ if (abfd->iostream == NULL)
+ abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
+ }
+ else
+ {
+ /* Create the file. Unlink it first, for the convenience of
+ operating systems which worry about overwriting running
+ binaries. */
+ unlink (abfd->filename);
+ abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WB);
+ abfd->opened_once = true;
+ }
+ break;
+ }
+
+ if (abfd->iostream != NULL)
+ {
+ if (! bfd_cache_init (abfd))
+ return NULL;
+ }
+
+ return (FILE *) abfd->iostream;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_cache_lookup_worker
+
+SYNOPSIS
+ FILE *bfd_cache_lookup_worker(bfd *abfd);
+
+DESCRIPTION
+ Called when the macro <<bfd_cache_lookup>> fails to find a
+ quick answer. Find a file descriptor for @var{abfd}. If
+ necessary, it open it. If there are already more than
+ <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
+ avoid running out of file descriptors.
+*/
+
+FILE *
+bfd_cache_lookup_worker (abfd)
+ bfd *abfd;
+{
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ abort ();
+
+ if (abfd->my_archive)
+ abfd = abfd->my_archive;
+
+ if (abfd->iostream != NULL)
+ {
+ /* Move the file to the start of the cache. */
+ if (abfd != bfd_last_cache)
+ {
+ snip (abfd);
+ insert (abfd);
+ }
+ }
+ else
+ {
+ if (bfd_open_file (abfd) == NULL)
+ return NULL;
+ if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
+ return NULL;
+ }
+
+ return (FILE *) abfd->iostream;
+}
diff --git a/bfd/cf-i386lynx.c b/bfd/cf-i386lynx.c
new file mode 100644
index 00000000000..2a14bde8f12
--- /dev/null
+++ b/bfd/cf-i386lynx.c
@@ -0,0 +1,31 @@
+/* BFD back-end for Intel 386 COFF LynxOS files.
+ Copyright 1993, 1994 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define TARGET_SYM i386lynx_coff_vec
+#define TARGET_NAME "coff-i386-lynx"
+
+#define LYNXOS
+
+#define COFF_LONG_FILENAMES
+
+#include "coff-i386.c"
diff --git a/bfd/cf-m68klynx.c b/bfd/cf-m68klynx.c
new file mode 100644
index 00000000000..7674f1b248b
--- /dev/null
+++ b/bfd/cf-m68klynx.c
@@ -0,0 +1,28 @@
+/* BFD back-end for Motorola M68K COFF LynxOS files.
+ Copyright 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM m68klynx_coff_vec
+#define TARGET_NAME "coff-m68k-lynx"
+#define LYNXOS
+#define COFF_LONG_FILENAMES
+#define STATIC_RELOCS
+#define COFF_COMMON_ADDEND
+
+#include "coff-m68k.c"
diff --git a/bfd/cf-sparclynx.c b/bfd/cf-sparclynx.c
new file mode 100644
index 00000000000..774a099fefb
--- /dev/null
+++ b/bfd/cf-sparclynx.c
@@ -0,0 +1,28 @@
+/* BFD back-end for Sparc COFF LynxOS files.
+ Copyright 1993 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM sparclynx_coff_vec
+#define TARGET_NAME "coff-sparc-lynx"
+
+#define LYNXOS
+
+#define COFF_LONG_FILENAMES
+
+#include "coff-sparc.c"
diff --git a/bfd/cisco-core.c b/bfd/cisco-core.c
new file mode 100644
index 00000000000..11c9bbd4945
--- /dev/null
+++ b/bfd/cisco-core.c
@@ -0,0 +1,327 @@
+/* BFD back-end for CISCO crash dumps.
+
+Copyright 1994 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+/* core_file_failing_signal returns a host signal (this probably should
+ be fixed). */
+#include <signal.h>
+
+/* for MSVC builds */
+#ifndef SIGTRAP
+# define SIGTRAP 5
+#endif
+#ifndef SIGEMT
+# define SIGEMT 6
+#endif
+#ifndef SIGBUS
+# define SIGBUS 10
+#endif
+
+#define CRASH_INFO (0xffc)
+#define CRASH_MAGIC 0xdead1234
+
+typedef enum {
+ CRASH_REASON_NOTCRASHED = 0,
+ CRASH_REASON_EXCEPTION = 1,
+ CRASH_REASON_CORRUPT = 2,
+ } crashreason;
+
+struct crashinfo_external
+{
+ char magic[4]; /* Magic number */
+ char version[4]; /* Version number */
+ char reason[4]; /* Crash reason */
+ char cpu_vector[4]; /* CPU vector for exceptions */
+ char registers[4]; /* Pointer to saved registers */
+ char rambase[4]; /* Base of RAM (not in V1 crash info) */
+};
+
+struct cisco_core_struct
+{
+ int sig;
+};
+
+static const bfd_target *
+cisco_core_file_p (abfd)
+ bfd *abfd;
+{
+ char buf[4];
+ unsigned int crashinfo_offset;
+ struct crashinfo_external crashinfo;
+ int nread;
+ unsigned int rambase;
+ sec_ptr asect;
+ struct stat statbuf;
+
+ if (bfd_seek (abfd, CRASH_INFO, SEEK_SET) != 0)
+ return NULL;
+
+ nread = bfd_read (buf, 1, 4, abfd);
+ if (nread != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ crashinfo_offset = bfd_get_32 (abfd, buf);
+
+ if (bfd_seek (abfd, crashinfo_offset, SEEK_SET) != 0)
+ return NULL;
+
+ nread = bfd_read (&crashinfo, 1, sizeof (crashinfo), abfd);
+ if (nread != sizeof (crashinfo))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ if (bfd_get_32 (abfd, crashinfo.magic) != CRASH_MAGIC)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ switch (bfd_get_32 (abfd, crashinfo.version))
+ {
+ case 0:
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ case 1:
+ rambase = 0;
+ break;
+ default:
+ case 2:
+ rambase = bfd_get_32 (abfd, crashinfo.rambase);
+ break;
+ }
+
+ /* OK, we believe you. You're a core file. */
+
+ abfd->tdata.cisco_core_data =
+ ((struct cisco_core_struct *)
+ bfd_zmalloc (sizeof (struct cisco_core_struct)));
+ if (abfd->tdata.cisco_core_data == NULL)
+ return NULL;
+
+ switch ((crashreason) bfd_get_32 (abfd, crashinfo.reason))
+ {
+ case CRASH_REASON_NOTCRASHED:
+ /* Crash file probably came from write core. */
+ abfd->tdata.cisco_core_data->sig = 0;
+ break;
+ case CRASH_REASON_CORRUPT:
+ /* The crash context area was corrupt -- proceed with caution.
+ We have no way of passing this information back to the caller. */
+ abfd->tdata.cisco_core_data->sig = 0;
+ break;
+ case CRASH_REASON_EXCEPTION:
+ /* Crash occured due to CPU exception. */
+
+ /* This is 68k-specific; for MIPS we'll need to interpret
+ cpu_vector differently based on the target configuration
+ (since CISCO core files don't seem to have the processor
+ encoded in them). */
+
+ switch (bfd_get_32 (abfd, crashinfo.cpu_vector))
+ {
+ /* bus error */
+ case 2 : abfd->tdata.cisco_core_data->sig = SIGBUS; break;
+ /* address error */
+ case 3 : abfd->tdata.cisco_core_data->sig = SIGBUS; break;
+ /* illegal instruction */
+ case 4 : abfd->tdata.cisco_core_data->sig = SIGILL; break;
+ /* zero divide */
+ case 5 : abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* chk instruction */
+ case 6 : abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* trapv instruction */
+ case 7 : abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* privilege violation */
+ case 8 : abfd->tdata.cisco_core_data->sig = SIGSEGV; break;
+ /* trace trap */
+ case 9 : abfd->tdata.cisco_core_data->sig = SIGTRAP; break;
+ /* line 1010 emulator */
+ case 10: abfd->tdata.cisco_core_data->sig = SIGILL; break;
+ /* line 1111 emulator */
+ case 11: abfd->tdata.cisco_core_data->sig = SIGILL; break;
+
+ /* Coprocessor protocol violation. Using a standard MMU or FPU
+ this cannot be triggered by software. Call it a SIGBUS. */
+ case 13: abfd->tdata.cisco_core_data->sig = SIGBUS; break;
+
+ /* interrupt */
+ case 31: abfd->tdata.cisco_core_data->sig = SIGINT; break;
+ /* breakpoint */
+ case 33: abfd->tdata.cisco_core_data->sig = SIGTRAP; break;
+
+ /* floating point err */
+ case 48: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* floating point err */
+ case 49: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* zero divide */
+ case 50: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* underflow */
+ case 51: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* operand error */
+ case 52: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* overflow */
+ case 53: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ /* NAN */
+ case 54: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
+ default:
+#ifndef SIGEMT
+#define SIGEMT SIGTRAP
+#endif
+ /* "software generated"*/
+ abfd->tdata.cisco_core_data->sig = SIGEMT;
+ }
+ break;
+ default:
+ /* Unknown crash reason. */
+ abfd->tdata.cisco_core_data->sig = 0;
+ break;
+ }
+
+ abfd->sections = NULL;
+ abfd->section_count = 0;
+
+ asect = (asection *) bfd_zmalloc (sizeof (asection));
+ if (asect == NULL)
+ goto error_return;
+ asect->name = ".reg";
+ asect->flags = SEC_HAS_CONTENTS;
+ /* This can be bigger than the real size. Set it to the size of the whole
+ core file. */
+ asect->_raw_size = statbuf.st_size;
+ asect->vma = 0;
+ asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase;
+ asect->next = abfd->sections;
+ abfd->sections = asect;
+ ++abfd->section_count;
+
+ /* There is only one section containing data from the target system's RAM.
+ We call it .data. */
+ asect = (asection *) bfd_zmalloc (sizeof (asection));
+ if (asect == NULL)
+ goto error_return;
+ asect->name = ".data";
+ asect->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ /* The size of memory is the size of the core file itself. */
+ asect->_raw_size = statbuf.st_size;
+ asect->vma = rambase;
+ asect->filepos = 0;
+ asect->next = abfd->sections;
+ abfd->sections = asect;
+ ++abfd->section_count;
+
+ return abfd->xvec;
+
+ error_return:
+ {
+ sec_ptr nextsect;
+ for (asect = abfd->sections; asect != NULL;)
+ {
+ nextsect = asect->next;
+ free (asect);
+ asect = nextsect;
+ }
+ free (abfd->tdata.cisco_core_data);
+ return NULL;
+ }
+}
+
+char *
+cisco_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return NULL;
+}
+
+int
+cisco_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return abfd->tdata.cisco_core_data->sig;
+}
+
+boolean
+cisco_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd;
+ bfd *exec_bfd;
+{
+ return true;
+}
+
+const bfd_target cisco_core_vec =
+ {
+ "trad-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ cisco_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (cisco),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
diff --git a/bfd/coff-a29k.c b/bfd/coff-a29k.c
new file mode 100644
index 00000000000..bbf23eed981
--- /dev/null
+++ b/bfd/coff-a29k.c
@@ -0,0 +1,640 @@
+/* BFD back-end for AMD 29000 COFF binaries.
+ Copyright 1990, 91, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Contributed by David Wood at New York University 7/8/91.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define A29K 1
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/a29k.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+static long get_symbol_value PARAMS ((asymbol *));
+static bfd_reloc_status_type a29k_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean coff_a29k_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+static boolean coff_a29k_adjust_symndx
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, boolean *));
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+
+#define INSERT_HWORD(WORD,HWORD) \
+ (((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff))
+#define EXTRACT_HWORD(WORD) \
+ ((((WORD) & 0x00ff0000) >> 8) | ((WORD)& 0xff))
+#define SIGN_EXTEND_HWORD(HWORD) \
+ ((HWORD) & 0x8000 ? (HWORD)|(~0xffffL) : (HWORD))
+
+/* Provided the symbol, returns the value reffed */
+static long
+get_symbol_value (symbol)
+ asymbol *symbol;
+{
+ long relocation = 0;
+
+ if (bfd_is_com_section (symbol->section))
+ {
+ relocation = 0;
+ }
+ else
+ {
+ relocation = symbol->value +
+ symbol->section->output_section->vma +
+ symbol->section->output_offset;
+ }
+
+ return(relocation);
+}
+
+/* this function is in charge of performing all the 29k relocations */
+
+static bfd_reloc_status_type
+a29k_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* the consth relocation comes in two parts, we have to remember
+ the state between calls, in these variables */
+ static boolean part1_consth_active = false;
+ static unsigned long part1_consth_value;
+
+ unsigned long insn;
+ unsigned long sym_value;
+ unsigned long unsigned_value;
+ unsigned short r_type;
+ long signed_value;
+
+ unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
+ bfd_byte *hit_data =addr + (bfd_byte *)(data);
+
+ r_type = reloc_entry->howto->type;
+
+ if (output_bfd) {
+ /* Partial linking - do nothing */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+
+ }
+
+ if (symbol_in != NULL
+ && bfd_is_und_section (symbol_in->section))
+ {
+ /* Keep the state machine happy in case we're called again */
+ if (r_type == R_IHIHALF)
+ {
+ part1_consth_active = true;
+ part1_consth_value = 0;
+ }
+ return(bfd_reloc_undefined);
+ }
+
+ if ((part1_consth_active) && (r_type != R_IHCONST))
+ {
+ part1_consth_active = false;
+ *error_message = (char *) _("Missing IHCONST");
+ return(bfd_reloc_dangerous);
+ }
+
+
+ sym_value = get_symbol_value(symbol_in);
+
+ switch (r_type)
+ {
+ case R_IREL:
+ insn = bfd_get_32(abfd, hit_data);
+ /* Take the value in the field and sign extend it */
+ signed_value = EXTRACT_HWORD(insn);
+ signed_value = SIGN_EXTEND_HWORD(signed_value);
+ signed_value <<= 2;
+
+ /* See the note on the R_IREL reloc in coff_a29k_relocate_section. */
+ if (signed_value == - (long) reloc_entry->address)
+ signed_value = 0;
+
+ signed_value += sym_value + reloc_entry->addend;
+ if ((signed_value & ~0x3ffff) == 0)
+ { /* Absolute jmp/call */
+ insn |= (1<<24); /* Make it absolute */
+ /* FIXME: Should we change r_type to R_IABS */
+ }
+ else
+ {
+ /* Relative jmp/call, so subtract from the value the
+ address of the place we're coming from */
+ signed_value -= (reloc_entry->address
+ + input_section->output_section->vma
+ + input_section->output_offset);
+ if (signed_value>0x1ffff || signed_value<-0x20000)
+ return(bfd_reloc_overflow);
+ }
+ signed_value >>= 2;
+ insn = INSERT_HWORD(insn, signed_value);
+ bfd_put_32(abfd, insn ,hit_data);
+ break;
+ case R_ILOHALF:
+ insn = bfd_get_32(abfd, hit_data);
+ unsigned_value = EXTRACT_HWORD(insn);
+ unsigned_value += sym_value + reloc_entry->addend;
+ insn = INSERT_HWORD(insn, unsigned_value);
+ bfd_put_32(abfd, insn, hit_data);
+ break;
+ case R_IHIHALF:
+ insn = bfd_get_32(abfd, hit_data);
+ /* consth, part 1
+ Just get the symbol value that is referenced */
+ part1_consth_active = true;
+ part1_consth_value = sym_value + reloc_entry->addend;
+ /* Don't modify insn until R_IHCONST */
+ break;
+ case R_IHCONST:
+ insn = bfd_get_32(abfd, hit_data);
+ /* consth, part 2
+ Now relocate the reference */
+ if (part1_consth_active == false) {
+ *error_message = (char *) _("Missing IHIHALF");
+ return(bfd_reloc_dangerous);
+ }
+ /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
+ unsigned_value = 0; /*EXTRACT_HWORD(insn) << 16;*/
+ unsigned_value += reloc_entry->addend; /* r_symndx */
+ unsigned_value += part1_consth_value;
+ unsigned_value = unsigned_value >> 16;
+ insn = INSERT_HWORD(insn, unsigned_value);
+ part1_consth_active = false;
+ bfd_put_32(abfd, insn, hit_data);
+ break;
+ case R_BYTE:
+ insn = bfd_get_8(abfd, hit_data);
+ unsigned_value = insn + sym_value + reloc_entry->addend;
+ if (unsigned_value & 0xffffff00)
+ return(bfd_reloc_overflow);
+ bfd_put_8(abfd, unsigned_value, hit_data);
+ break;
+ case R_HWORD:
+ insn = bfd_get_16(abfd, hit_data);
+ unsigned_value = insn + sym_value + reloc_entry->addend;
+ if (unsigned_value & 0xffff0000)
+ return(bfd_reloc_overflow);
+ bfd_put_16(abfd, insn, hit_data);
+ break;
+ case R_WORD:
+ insn = bfd_get_32(abfd, hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_put_32(abfd, insn, hit_data);
+ break;
+ default:
+ *error_message = _("Unrecognized reloc");
+ return (bfd_reloc_dangerous);
+ }
+
+
+ return(bfd_reloc_ok);
+}
+
+/* type rightshift
+ size
+ bitsize
+ pc-relative
+ bitpos
+ absolute
+ complain_on_overflow
+ special_function
+ relocation name
+ partial_inplace
+ src_mask
+*/
+
+/*FIXME: I'm not real sure about this table */
+static reloc_howto_type howto_table[] =
+{
+ {R_ABS, 0, 3, 32, false, 0, complain_overflow_bitfield,a29k_reloc,"ABS", true, 0xffffffff,0xffffffff, false},
+ {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10},
+ {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20},
+ {21}, {22}, {23},
+ {R_IREL, 0, 3, 32, true, 0, complain_overflow_signed,a29k_reloc,"IREL", true, 0xffffffff,0xffffffff, false},
+ {R_IABS, 0, 3, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"IABS", true, 0xffffffff,0xffffffff, false},
+ {R_ILOHALF, 0, 3, 16, true, 0, complain_overflow_signed, a29k_reloc,"ILOHALF", true, 0x0000ffff,0x0000ffff, false},
+ {R_IHIHALF, 0, 3, 16, true, 16, complain_overflow_signed, a29k_reloc,"IHIHALF", true, 0xffff0000,0xffff0000, false},
+ {R_IHCONST, 0, 3, 16, true, 0, complain_overflow_signed, a29k_reloc,"IHCONST", true, 0xffff0000,0xffff0000, false},
+ {R_BYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, a29k_reloc,"BYTE", true, 0x000000ff,0x000000ff, false},
+ {R_HWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, a29k_reloc,"HWORD", true, 0x0000ffff,0x0000ffff, false},
+ {R_WORD, 0, 2, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"WORD", true, 0xffffffff,0xffffffff, false},
+};
+
+#define BADMAG(x) A29KBADMAG(x)
+
+#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (relent,reloc, symbols, abfd, section)
+ arelent *relent;
+ struct internal_reloc *reloc;
+ asymbol **symbols;
+ bfd *abfd;
+ asection *section;
+{
+ static bfd_vma ihihalf_vaddr = (bfd_vma) -1;
+
+ relent->address = reloc->r_vaddr;
+ relent->howto = howto_table + reloc->r_type;
+ if (reloc->r_type == R_IHCONST)
+ {
+ /* The address of an R_IHCONST should always be the address of
+ the immediately preceding R_IHIHALF. relocs generated by gas
+ are correct, but relocs generated by High C are different (I
+ can't figure out what the address means for High C). We can
+ handle both gas and High C by ignoring the address here, and
+ simply reusing the address saved for R_IHIHALF. */
+ if (ihihalf_vaddr == (bfd_vma) -1)
+ abort ();
+ relent->address = ihihalf_vaddr;
+ ihihalf_vaddr = (bfd_vma) -1;
+ relent->addend = reloc->r_symndx;
+ relent->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
+ {
+ asymbol *ptr;
+ relent->sym_ptr_ptr = symbols + obj_convert(abfd)[reloc->r_symndx];
+
+ ptr = *(relent->sym_ptr_ptr);
+
+ if (ptr
+ && bfd_asymbol_bfd(ptr) == abfd
+
+ && ((ptr->flags & BSF_OLD_COMMON)== 0))
+ {
+ relent->addend = 0;
+ }
+ else
+ {
+ relent->addend = 0;
+ }
+ relent->address-= section->vma;
+ if (reloc->r_type == R_IHIHALF)
+ ihihalf_vaddr = relent->address;
+ else if (ihihalf_vaddr != (bfd_vma) -1)
+ abort ();
+ }
+}
+
+/* The reloc processing routine for the optimized COFF linker. */
+
+static boolean
+coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, syms, sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+ boolean hihalf;
+ bfd_vma hihalf_val;
+
+ /* If we are performing a relocateable link, we don't need to do a
+ thing. The caller will take care of adjusting the reloc
+ addresses and symbol indices. */
+ if (info->relocateable)
+ return true;
+
+ hihalf = false;
+ hihalf_val = 0;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ bfd_byte *loc;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ asection *sec;
+ bfd_vma val;
+ boolean overflow;
+ unsigned long insn;
+ long signed_value;
+ unsigned long unsigned_value;
+ bfd_reloc_status_type rstat;
+
+ symndx = rel->r_symndx;
+ loc = contents + rel->r_vaddr - input_section->vma;
+
+ if (symndx == -1 || rel->r_type == R_IHCONST)
+ h = NULL;
+ else
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+
+ sym = NULL;
+ sec = NULL;
+ val = 0;
+
+ /* An R_IHCONST reloc does not have a symbol. Instead, the
+ symbol index is an addend. R_IHCONST is always used in
+ conjunction with R_IHHALF. */
+ if (rel->r_type != R_IHCONST)
+ {
+ if (h == NULL)
+ {
+ if (symndx == -1)
+ sec = bfd_abs_section_ptr;
+ else
+ {
+ sym = syms + symndx;
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value
+ - sec->vma);
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ if (hihalf)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info, _("missing IHCONST reloc"), input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ hihalf = false;
+ }
+ }
+
+ overflow = false;
+
+ switch (rel->r_type)
+ {
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+
+ case R_IREL:
+ insn = bfd_get_32 (input_bfd, loc);
+
+ /* Extract the addend. */
+ signed_value = EXTRACT_HWORD (insn);
+ signed_value = SIGN_EXTEND_HWORD (signed_value);
+ signed_value <<= 2;
+
+ /* Unfortunately, there are two different versions of COFF
+ a29k. In the original AMD version, the value stored in
+ the field for the R_IREL reloc is a simple addend. In
+ the GNU version, the value is the negative of the address
+ of the reloc within section. We try to cope here by
+ assuming the AMD version, unless the addend is exactly
+ the negative of the address; in the latter case we assume
+ the GNU version. This means that something like
+ .text
+ nop
+ jmp i-4
+ will fail, because the addend of -4 will happen to equal
+ the negative of the address within the section. The
+ compiler will never generate code like this.
+
+ At some point in the future we may want to take out this
+ check. */
+
+ if (signed_value == - (long) (rel->r_vaddr - input_section->vma))
+ signed_value = 0;
+
+ /* Determine the destination of the jump. */
+ signed_value += val;
+
+ if ((signed_value & ~0x3ffff) == 0)
+ {
+ /* We can use an absolute jump. */
+ insn |= (1 << 24);
+ }
+ else
+ {
+ /* Make the destination PC relative. */
+ signed_value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + (rel->r_vaddr - input_section->vma));
+ if (signed_value > 0x1ffff || signed_value < - 0x20000)
+ {
+ overflow = true;
+ signed_value = 0;
+ }
+ }
+
+ /* Put the adjusted value back into the instruction. */
+ signed_value >>= 2;
+ insn = INSERT_HWORD (insn, signed_value);
+
+ bfd_put_32 (input_bfd, (bfd_vma) insn, loc);
+
+ break;
+
+ case R_ILOHALF:
+ insn = bfd_get_32 (input_bfd, loc);
+ unsigned_value = EXTRACT_HWORD (insn);
+ unsigned_value += val;
+ insn = INSERT_HWORD (insn, unsigned_value);
+ bfd_put_32 (input_bfd, insn, loc);
+ break;
+
+ case R_IHIHALF:
+ /* Save the value for the R_IHCONST reloc. */
+ hihalf = true;
+ hihalf_val = val;
+ break;
+
+ case R_IHCONST:
+ if (! hihalf)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info, _("missing IHIHALF reloc"), input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ hihalf_val = 0;
+ }
+
+ insn = bfd_get_32 (input_bfd, loc);
+ unsigned_value = rel->r_symndx + hihalf_val;
+ unsigned_value >>= 16;
+ insn = INSERT_HWORD (insn, unsigned_value);
+ bfd_put_32 (input_bfd, (bfd_vma) insn, loc);
+
+ hihalf = false;
+
+ break;
+
+ case R_BYTE:
+ case R_HWORD:
+ case R_WORD:
+ rstat = _bfd_relocate_contents (howto_table + rel->r_type,
+ input_bfd, val, loc);
+ if (rstat == bfd_reloc_overflow)
+ overflow = true;
+ else if (rstat != bfd_reloc_ok)
+ abort ();
+ break;
+ }
+
+ if (overflow)
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else if (sym == NULL)
+ name = "*unknown*";
+ else if (sym->_n._n_n._n_zeroes == 0
+ && sym->_n._n_n._n_offset != 0)
+ name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
+ else
+ {
+ strncpy (buf, sym->_n._n_name, SYMNMLEN);
+ buf[SYMNMLEN] = '\0';
+ name = buf;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto_table[rel->r_type].name, (bfd_vma) 0,
+ input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#define coff_relocate_section coff_a29k_relocate_section
+
+/* We don't want to change the symndx of a R_IHCONST reloc, since it
+ is actually an addend, not a symbol index at all. */
+
+/*ARGSUSED*/
+static boolean
+coff_a29k_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
+ bfd *obfd;
+ struct bfd_link_info *info;
+ bfd *ibfd;
+ asection *sec;
+ struct internal_reloc *irel;
+ boolean *adjustedp;
+{
+ if (irel->r_type == R_IHCONST)
+ *adjustedp = true;
+ else
+ *adjustedp = false;
+ return true;
+}
+
+#define coff_adjust_symndx coff_a29k_adjust_symndx
+
+#include "coffcode.h"
+
+const bfd_target a29kcoff_big_vec =
+{
+ "coff-a29k-big", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC /* section flags */
+ | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY ),
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+ /* hdrs */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+ {
+
+ _bfd_dummy_target,
+ coff_object_p,
+ bfd_generic_archive_p,
+ _bfd_dummy_target
+ },
+ {
+ bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+ {
+ bfd_false,
+ coff_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE
+ };
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
new file mode 100644
index 00000000000..d841663edd5
--- /dev/null
+++ b/bfd/coff-alpha.c
@@ -0,0 +1,2402 @@
+/* BFD back-end for ALPHA Extended-Coff files.
+ Copyright 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
+ Ian Lance Taylor <ian@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff.h"
+#include "coff/alpha.h"
+#include "aout/ar.h"
+#include "libcoff.h"
+#include "libecoff.h"
+
+/* Prototypes for static functions. */
+
+static const bfd_target *alpha_ecoff_object_p PARAMS ((bfd *));
+static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
+static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
+static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
+ struct internal_reloc *));
+static void alpha_ecoff_swap_reloc_out PARAMS ((bfd *,
+ const struct internal_reloc *,
+ PTR));
+static void alpha_adjust_reloc_in PARAMS ((bfd *,
+ const struct internal_reloc *,
+ arelent *));
+static void alpha_adjust_reloc_out PARAMS ((bfd *, const arelent *,
+ struct internal_reloc *));
+static reloc_howto_type *alpha_bfd_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static bfd_byte *alpha_ecoff_get_relocated_section_contents
+ PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *data, boolean relocateable, asymbol **symbols));
+static bfd_vma alpha_convert_external_reloc
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *,
+ struct ecoff_link_hash_entry *));
+static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
+ bfd *, asection *,
+ bfd_byte *, PTR));
+static boolean alpha_adjust_headers
+ PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
+static PTR alpha_ecoff_read_ar_hdr PARAMS ((bfd *));
+static bfd *alpha_ecoff_get_elt_at_filepos PARAMS ((bfd *, file_ptr));
+static bfd *alpha_ecoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
+static bfd *alpha_ecoff_get_elt_at_index PARAMS ((bfd *, symindex));
+
+/* ECOFF has COFF sections, but the debugging information is stored in
+ a completely different format. ECOFF targets use some of the
+ swapping routines from coffswap.h, and some of the generic COFF
+ routines in coffgen.c, but, unlike the real COFF targets, do not
+ use coffcode.h itself.
+
+ Get the generic COFF swapping routines, except for the reloc,
+ symbol, and lineno ones. Give them ecoff names. Define some
+ accessor macros for the large sizes used for Alpha ECOFF. */
+
+#define GET_FILEHDR_SYMPTR bfd_h_get_64
+#define PUT_FILEHDR_SYMPTR bfd_h_put_64
+#define GET_AOUTHDR_TSIZE bfd_h_get_64
+#define PUT_AOUTHDR_TSIZE bfd_h_put_64
+#define GET_AOUTHDR_DSIZE bfd_h_get_64
+#define PUT_AOUTHDR_DSIZE bfd_h_put_64
+#define GET_AOUTHDR_BSIZE bfd_h_get_64
+#define PUT_AOUTHDR_BSIZE bfd_h_put_64
+#define GET_AOUTHDR_ENTRY bfd_h_get_64
+#define PUT_AOUTHDR_ENTRY bfd_h_put_64
+#define GET_AOUTHDR_TEXT_START bfd_h_get_64
+#define PUT_AOUTHDR_TEXT_START bfd_h_put_64
+#define GET_AOUTHDR_DATA_START bfd_h_get_64
+#define PUT_AOUTHDR_DATA_START bfd_h_put_64
+#define GET_SCNHDR_PADDR bfd_h_get_64
+#define PUT_SCNHDR_PADDR bfd_h_put_64
+#define GET_SCNHDR_VADDR bfd_h_get_64
+#define PUT_SCNHDR_VADDR bfd_h_put_64
+#define GET_SCNHDR_SIZE bfd_h_get_64
+#define PUT_SCNHDR_SIZE bfd_h_put_64
+#define GET_SCNHDR_SCNPTR bfd_h_get_64
+#define PUT_SCNHDR_SCNPTR bfd_h_put_64
+#define GET_SCNHDR_RELPTR bfd_h_get_64
+#define PUT_SCNHDR_RELPTR bfd_h_put_64
+#define GET_SCNHDR_LNNOPTR bfd_h_get_64
+#define PUT_SCNHDR_LNNOPTR bfd_h_put_64
+
+#define ALPHAECOFF
+
+#define NO_COFF_RELOCS
+#define NO_COFF_SYMBOLS
+#define NO_COFF_LINENOS
+#define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
+#define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
+#define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
+#define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
+#define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
+#define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
+#include "coffswap.h"
+
+/* Get the ECOFF swapping routines. */
+#define ECOFF_64
+#include "ecoffswap.h"
+
+/* How to process the various reloc types. */
+
+static bfd_reloc_status_type
+reloc_nil PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+
+static bfd_reloc_status_type
+reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc;
+ asymbol *sym;
+ PTR data;
+ asection *sec;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return bfd_reloc_ok;
+}
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+ from smaller values. Start with zero, widen, *then* decrement. */
+#define MINUS_ONE (((bfd_vma)0) - 1)
+
+static reloc_howto_type alpha_howto_table[] =
+{
+ /* Reloc type 0 is ignored by itself. However, it appears after a
+ GPDISP reloc to identify the location where the low order 16 bits
+ of the gp register are loaded. */
+ HOWTO (ALPHA_R_IGNORE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "IGNORE", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 32 bit reference to a symbol. */
+ HOWTO (ALPHA_R_REFLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "REFLONG", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit reference to a symbol. */
+ HOWTO (ALPHA_R_REFQUAD, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "REFQUAD", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit GP relative offset. This is just like REFLONG except
+ that when the value is used the value of the gp register will be
+ added in. */
+ HOWTO (ALPHA_R_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "GPREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Used for an instruction that refers to memory off the GP
+ register. The offset is 16 bits of the 32 bit instruction. This
+ reloc always seems to be against the .lita section. */
+ HOWTO (ALPHA_R_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "LITERAL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* This reloc only appears immediately following a LITERAL reloc.
+ It identifies a use of the literal. It seems that the linker can
+ use this to eliminate a portion of the .lita section. The symbol
+ index is special: 1 means the literal address is in the base
+ register of a memory format instruction; 2 means the literal
+ address is in the byte offset register of a byte-manipulation
+ instruction; 3 means the literal address is in the target
+ register of a jsr instruction. This does not actually do any
+ relocation. */
+ HOWTO (ALPHA_R_LITUSE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "LITUSE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Load the gp register. This is always used for a ldah instruction
+ which loads the upper 16 bits of the gp register. The next reloc
+ will be an IGNORE reloc which identifies the location of the lda
+ instruction which loads the lower 16 bits. The symbol index of
+ the GPDISP instruction appears to actually be the number of bytes
+ between the ldah and lda instructions. This gives two different
+ ways to determine where the lda instruction is; I don't know why
+ both are used. The value to use for the relocation is the
+ difference between the GP value and the current location; the
+ load will always be done against a register holding the current
+ address. */
+ HOWTO (ALPHA_R_GPDISP, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "GPDISP", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 21 bit branch. The native assembler generates these for
+ branches within the text segment, and also fills in the PC
+ relative offset in the instruction. */
+ HOWTO (ALPHA_R_BRADDR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "BRADDR", /* name */
+ true, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A hint for a jump to a register. */
+ HOWTO (ALPHA_R_HINT, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "HINT", /* name */
+ true, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL64", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Push a value on the reloc evaluation stack. */
+ HOWTO (ALPHA_R_OP_PUSH, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_PUSH", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Store the value from the stack at the given address. Store it in
+ a bitfield of size r_size starting at bit position r_offset. */
+ HOWTO (ALPHA_R_OP_STORE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_STORE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Subtract the reloc address from the value on the top of the
+ relocation stack. */
+ HOWTO (ALPHA_R_OP_PSUB, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_PSUB", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Shift the value on the top of the relocation stack right by the
+ given value. */
+ HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_PRSHIFT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Adjust the GP value for a new range in the object file. */
+ HOWTO (ALPHA_R_GPVALUE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "GPVALUE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+/* Recognize an Alpha ECOFF file. */
+
+static const bfd_target *
+alpha_ecoff_object_p (abfd)
+ bfd *abfd;
+{
+ static const bfd_target *ret;
+
+ ret = coff_object_p (abfd);
+
+ if (ret != NULL)
+ {
+ asection *sec;
+
+ /* Alpha ECOFF has a .pdata section. The lnnoptr field of the
+ .pdata section is the number of entries it contains. Each
+ entry takes up 8 bytes. The number of entries is required
+ since the section is aligned to a 16 byte boundary. When we
+ link .pdata sections together, we do not want to include the
+ alignment bytes. We handle this on input by faking the size
+ of the .pdata section to remove the unwanted alignment bytes.
+ On output we will set the lnnoptr field and force the
+ alignment. */
+ sec = bfd_get_section_by_name (abfd, _PDATA);
+ if (sec != (asection *) NULL)
+ {
+ bfd_size_type size;
+
+ size = sec->line_filepos * 8;
+ BFD_ASSERT (size == bfd_section_size (abfd, sec)
+ || size + 8 == bfd_section_size (abfd, sec));
+ if (! bfd_set_section_size (abfd, sec, size))
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+/* See whether the magic number matches. */
+
+static boolean
+alpha_ecoff_bad_format_hook (abfd, filehdr)
+ bfd *abfd;
+ PTR filehdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ if (ALPHA_ECOFF_BADMAG (*internal_f))
+ return false;
+
+ return true;
+}
+
+/* This is a hook called by coff_real_object_p to create any backend
+ specific information. */
+
+static PTR
+alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
+ bfd *abfd;
+ PTR filehdr;
+ PTR aouthdr;
+{
+ PTR ecoff;
+
+ ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
+
+ if (ecoff != NULL)
+ {
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ /* Set additional BFD flags according to the object type from the
+ machine specific file header flags. */
+ switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK)
+ {
+ case F_ALPHA_SHARABLE:
+ abfd->flags |= DYNAMIC;
+ break;
+ case F_ALPHA_CALL_SHARED:
+ /* Always executable if using shared libraries as the run time
+ loader might resolve undefined references. */
+ abfd->flags |= (DYNAMIC | EXEC_P);
+ break;
+ }
+ }
+ return ecoff;
+}
+
+/* Reloc handling. */
+
+/* Swap a reloc in. */
+
+static void
+alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
+ bfd *abfd;
+ PTR ext_ptr;
+ struct internal_reloc *intern;
+{
+ const RELOC *ext = (RELOC *) ext_ptr;
+
+ intern->r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext->r_vaddr);
+ intern->r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_symndx);
+
+ BFD_ASSERT (bfd_header_little_endian (abfd));
+
+ intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
+ >> RELOC_BITS0_TYPE_SH_LITTLE);
+ intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
+ intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
+ >> RELOC_BITS1_OFFSET_SH_LITTLE);
+ /* Ignored the reserved bits. */
+ intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
+ >> RELOC_BITS3_SIZE_SH_LITTLE);
+
+ if (intern->r_type == ALPHA_R_LITUSE
+ || intern->r_type == ALPHA_R_GPDISP)
+ {
+ /* Handle the LITUSE and GPDISP relocs specially. Its symndx
+ value is not actually a symbol index, but is instead a
+ special code. We put the code in the r_size field, and
+ clobber the symndx. */
+ if (intern->r_size != 0)
+ abort ();
+ intern->r_size = intern->r_symndx;
+ intern->r_symndx = RELOC_SECTION_NONE;
+ }
+ else if (intern->r_type == ALPHA_R_IGNORE)
+ {
+ /* The IGNORE reloc generally follows a GPDISP reloc, and is
+ against the .lita section. The section is irrelevant. */
+ if (! intern->r_extern &&
+ intern->r_symndx == RELOC_SECTION_ABS)
+ abort ();
+ if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA)
+ intern->r_symndx = RELOC_SECTION_ABS;
+ }
+}
+
+/* Swap a reloc out. */
+
+static void
+alpha_ecoff_swap_reloc_out (abfd, intern, dst)
+ bfd *abfd;
+ const struct internal_reloc *intern;
+ PTR dst;
+{
+ RELOC *ext = (RELOC *) dst;
+ long symndx;
+ unsigned char size;
+
+ /* Undo the hackery done in swap_reloc_in. */
+ if (intern->r_type == ALPHA_R_LITUSE
+ || intern->r_type == ALPHA_R_GPDISP)
+ {
+ symndx = intern->r_size;
+ size = 0;
+ }
+ else if (intern->r_type == ALPHA_R_IGNORE
+ && ! intern->r_extern
+ && intern->r_symndx == RELOC_SECTION_ABS)
+ {
+ symndx = RELOC_SECTION_LITA;
+ size = intern->r_size;
+ }
+ else
+ {
+ symndx = intern->r_symndx;
+ size = intern->r_size;
+ }
+
+ BFD_ASSERT (intern->r_extern
+ || (intern->r_symndx >= 0 && intern->r_symndx <= 14));
+
+ bfd_h_put_64 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
+ bfd_h_put_32 (abfd, symndx, (bfd_byte *) ext->r_symndx);
+
+ BFD_ASSERT (bfd_header_little_endian (abfd));
+
+ ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
+ & RELOC_BITS0_TYPE_LITTLE);
+ ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
+ | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
+ & RELOC_BITS1_OFFSET_LITTLE));
+ ext->r_bits[2] = 0;
+ ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE)
+ & RELOC_BITS3_SIZE_LITTLE);
+}
+
+/* Finish canonicalizing a reloc. Part of this is generic to all
+ ECOFF targets, and that part is in ecoff.c. The rest is done in
+ this backend routine. It must fill in the howto field. */
+
+static void
+alpha_adjust_reloc_in (abfd, intern, rptr)
+ bfd *abfd;
+ const struct internal_reloc *intern;
+ arelent *rptr;
+{
+ if (intern->r_type > ALPHA_R_GPVALUE)
+ abort ();
+
+ switch (intern->r_type)
+ {
+ case ALPHA_R_BRADDR:
+ case ALPHA_R_SREL16:
+ case ALPHA_R_SREL32:
+ case ALPHA_R_SREL64:
+ /* This relocs appear to be fully resolved when they are against
+ internal symbols. Against external symbols, BRADDR at least
+ appears to be resolved against the next instruction. */
+ if (! intern->r_extern)
+ rptr->addend = 0;
+ else
+ rptr->addend = - (intern->r_vaddr + 4);
+ break;
+
+ case ALPHA_R_GPREL32:
+ case ALPHA_R_LITERAL:
+ /* Copy the gp value for this object file into the addend, to
+ ensure that we are not confused by the linker. */
+ if (! intern->r_extern)
+ rptr->addend += ecoff_data (abfd)->gp;
+ break;
+
+ case ALPHA_R_LITUSE:
+ case ALPHA_R_GPDISP:
+ /* The LITUSE and GPDISP relocs do not use a symbol, or an
+ addend, but they do use a special code. Put this code in the
+ addend field. */
+ rptr->addend = intern->r_size;
+ break;
+
+ case ALPHA_R_OP_STORE:
+ /* The STORE reloc needs the size and offset fields. We store
+ them in the addend. */
+ BFD_ASSERT (intern->r_offset <= 256 && intern->r_size <= 256);
+ rptr->addend = (intern->r_offset << 8) + intern->r_size;
+ break;
+
+ case ALPHA_R_OP_PUSH:
+ case ALPHA_R_OP_PSUB:
+ case ALPHA_R_OP_PRSHIFT:
+ /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
+ address. I believe that the address supplied is really an
+ addend. */
+ rptr->addend = intern->r_vaddr;
+ break;
+
+ case ALPHA_R_GPVALUE:
+ /* Set the addend field to the new GP value. */
+ rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp;
+ break;
+
+ case ALPHA_R_IGNORE:
+ /* If the type is ALPHA_R_IGNORE, make sure this is a reference
+ to the absolute section so that the reloc is ignored. For
+ some reason the address of this reloc type is not adjusted by
+ the section vma. We record the gp value for this object file
+ here, for convenience when doing the GPDISP relocation. */
+ rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ rptr->address = intern->r_vaddr;
+ rptr->addend = ecoff_data (abfd)->gp;
+ break;
+
+ default:
+ break;
+ }
+
+ rptr->howto = &alpha_howto_table[intern->r_type];
+}
+
+/* When writing out a reloc we need to pull some values back out of
+ the addend field into the reloc. This is roughly the reverse of
+ alpha_adjust_reloc_in, except that there are several changes we do
+ not need to undo. */
+
+static void
+alpha_adjust_reloc_out (abfd, rel, intern)
+ bfd *abfd;
+ const arelent *rel;
+ struct internal_reloc *intern;
+{
+ switch (intern->r_type)
+ {
+ case ALPHA_R_LITUSE:
+ case ALPHA_R_GPDISP:
+ intern->r_size = rel->addend;
+ break;
+
+ case ALPHA_R_OP_STORE:
+ intern->r_size = rel->addend & 0xff;
+ intern->r_offset = (rel->addend >> 8) & 0xff;
+ break;
+
+ case ALPHA_R_OP_PUSH:
+ case ALPHA_R_OP_PSUB:
+ case ALPHA_R_OP_PRSHIFT:
+ intern->r_vaddr = rel->addend;
+ break;
+
+ case ALPHA_R_IGNORE:
+ intern->r_vaddr = rel->address;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* The size of the stack for the relocation evaluator. */
+#define RELOC_STACKSIZE (10)
+
+/* Alpha ECOFF relocs have a built in expression evaluator as well as
+ other interdependencies. Rather than use a bunch of special
+ functions and global variables, we use a single routine to do all
+ the relocation for a section. I haven't yet worked out how the
+ assembler is going to handle this. */
+
+static bfd_byte *
+alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ arelent **reloc_vector = NULL;
+ long reloc_count;
+ bfd *output_bfd = relocateable ? abfd : (bfd *) NULL;
+ bfd_vma gp;
+ boolean gp_undefined;
+ bfd_vma stack[RELOC_STACKSIZE];
+ int tos = 0;
+
+ if (reloc_size < 0)
+ goto error_return;
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ if (! bfd_get_section_contents (input_bfd, input_section, data,
+ (file_ptr) 0, input_section->_raw_size))
+ goto error_return;
+
+ /* The section size is not going to change. */
+ input_section->_cooked_size = input_section->_raw_size;
+ input_section->reloc_done = true;
+
+ reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
+ reloc_vector, symbols);
+ if (reloc_count < 0)
+ goto error_return;
+ if (reloc_count == 0)
+ goto successful_return;
+
+ /* Get the GP value for the output BFD. */
+ gp_undefined = false;
+ gp = _bfd_get_gp_value (abfd);
+ if (gp == 0)
+ {
+ if (relocateable != false)
+ {
+ asection *sec;
+ bfd_vma lo;
+
+ /* Make up a value. */
+ lo = (bfd_vma) -1;
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (sec->vma < lo
+ && (strcmp (sec->name, ".sbss") == 0
+ || strcmp (sec->name, ".sdata") == 0
+ || strcmp (sec->name, ".lit4") == 0
+ || strcmp (sec->name, ".lit8") == 0
+ || strcmp (sec->name, ".lita") == 0))
+ lo = sec->vma;
+ }
+ gp = lo + 0x8000;
+ _bfd_set_gp_value (abfd, gp);
+ }
+ else
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false,
+ true);
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || h->type != bfd_link_hash_defined)
+ gp_undefined = true;
+ else
+ {
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ _bfd_set_gp_value (abfd, gp);
+ }
+ }
+ }
+
+ for (; *reloc_vector != (arelent *) NULL; reloc_vector++)
+ {
+ arelent *rel;
+ bfd_reloc_status_type r;
+ char *err;
+
+ rel = *reloc_vector;
+ r = bfd_reloc_ok;
+ switch (rel->howto->type)
+ {
+ case ALPHA_R_IGNORE:
+ rel->address += input_section->output_offset;
+ break;
+
+ case ALPHA_R_REFLONG:
+ case ALPHA_R_REFQUAD:
+ case ALPHA_R_BRADDR:
+ case ALPHA_R_HINT:
+ case ALPHA_R_SREL16:
+ case ALPHA_R_SREL32:
+ case ALPHA_R_SREL64:
+ if (relocateable
+ && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
+ {
+ rel->address += input_section->output_offset;
+ break;
+ }
+ r = bfd_perform_relocation (input_bfd, rel, data, input_section,
+ output_bfd, &err);
+ break;
+
+ case ALPHA_R_GPREL32:
+ /* This relocation is used in a switch table. It is a 32
+ bit offset from the current GP value. We must adjust it
+ by the different between the original GP value and the
+ current GP value. The original GP value is stored in the
+ addend. We adjust the addend and let
+ bfd_perform_relocation finish the job. */
+ rel->addend -= gp;
+ r = bfd_perform_relocation (input_bfd, rel, data, input_section,
+ output_bfd, &err);
+ if (r == bfd_reloc_ok && gp_undefined)
+ {
+ r = bfd_reloc_dangerous;
+ err = (char *) _("GP relative relocation used when GP not defined");
+ }
+ break;
+
+ case ALPHA_R_LITERAL:
+ /* This is a reference to a literal value, generally
+ (always?) in the .lita section. This is a 16 bit GP
+ relative relocation. Sometimes the subsequent reloc is a
+ LITUSE reloc, which indicates how this reloc is used.
+ This sometimes permits rewriting the two instructions
+ referred to by the LITERAL and the LITUSE into different
+ instructions which do not refer to .lita. This can save
+ a memory reference, and permits removing a value from
+ .lita thus saving GP relative space.
+
+ We do not these optimizations. To do them we would need
+ to arrange to link the .lita section first, so that by
+ the time we got here we would know the final values to
+ use. This would not be particularly difficult, but it is
+ not currently implemented. */
+
+ {
+ unsigned long insn;
+
+ /* I believe that the LITERAL reloc will only apply to a
+ ldq or ldl instruction, so check my assumption. */
+ insn = bfd_get_32 (input_bfd, data + rel->address);
+ BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
+ || ((insn >> 26) & 0x3f) == 0x28);
+
+ rel->addend -= gp;
+ r = bfd_perform_relocation (input_bfd, rel, data, input_section,
+ output_bfd, &err);
+ if (r == bfd_reloc_ok && gp_undefined)
+ {
+ r = bfd_reloc_dangerous;
+ err =
+ (char *) _("GP relative relocation used when GP not defined");
+ }
+ }
+ break;
+
+ case ALPHA_R_LITUSE:
+ /* See ALPHA_R_LITERAL above for the uses of this reloc. It
+ does not cause anything to happen, itself. */
+ rel->address += input_section->output_offset;
+ break;
+
+ case ALPHA_R_GPDISP:
+ /* This marks the ldah of an ldah/lda pair which loads the
+ gp register with the difference of the gp value and the
+ current location. The second of the pair is r_size bytes
+ ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
+ but that no longer happens in OSF/1 3.2. */
+ {
+ unsigned long insn1, insn2;
+ bfd_vma addend;
+
+ /* Get the two instructions. */
+ insn1 = bfd_get_32 (input_bfd, data + rel->address);
+ insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend);
+
+ BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
+ BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
+
+ /* Get the existing addend. We must account for the sign
+ extension done by lda and ldah. */
+ addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
+ if (insn1 & 0x8000)
+ {
+ addend -= 0x80000000;
+ addend -= 0x80000000;
+ }
+ if (insn2 & 0x8000)
+ addend -= 0x10000;
+
+ /* The existing addend includes the different between the
+ gp of the input BFD and the address in the input BFD.
+ Subtract this out. */
+ addend -= (ecoff_data (input_bfd)->gp
+ - (input_section->vma + rel->address));
+
+ /* Now add in the final gp value, and subtract out the
+ final address. */
+ addend += (gp
+ - (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->address));
+
+ /* Change the instructions, accounting for the sign
+ extension, and write them out. */
+ if (addend & 0x8000)
+ addend += 0x10000;
+ insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
+ insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
+
+ bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address);
+ bfd_put_32 (input_bfd, (bfd_vma) insn2,
+ data + rel->address + rel->addend);
+
+ rel->address += input_section->output_offset;
+ }
+ break;
+
+ case ALPHA_R_OP_PUSH:
+ /* Push a value on the reloc evaluation stack. */
+ {
+ asymbol *symbol;
+ bfd_vma relocation;
+
+ if (relocateable)
+ {
+ rel->address += input_section->output_offset;
+ break;
+ }
+
+ /* Figure out the relocation of this symbol. */
+ symbol = *rel->sym_ptr_ptr;
+
+ if (bfd_is_und_section (symbol->section))
+ r = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += rel->addend;
+
+ if (tos >= RELOC_STACKSIZE)
+ abort ();
+
+ stack[tos++] = relocation;
+ }
+ break;
+
+ case ALPHA_R_OP_STORE:
+ /* Store a value from the reloc stack into a bitfield. */
+ {
+ bfd_vma val;
+ int offset, size;
+
+ if (relocateable)
+ {
+ rel->address += input_section->output_offset;
+ break;
+ }
+
+ if (tos == 0)
+ abort ();
+
+ /* The offset and size for this reloc are encoded into the
+ addend field by alpha_adjust_reloc_in. */
+ offset = (rel->addend >> 8) & 0xff;
+ size = rel->addend & 0xff;
+
+ val = bfd_get_64 (abfd, data + rel->address);
+ val &=~ (((1 << size) - 1) << offset);
+ val |= (stack[--tos] & ((1 << size) - 1)) << offset;
+ bfd_put_64 (abfd, val, data + rel->address);
+ }
+ break;
+
+ case ALPHA_R_OP_PSUB:
+ /* Subtract a value from the top of the stack. */
+ {
+ asymbol *symbol;
+ bfd_vma relocation;
+
+ if (relocateable)
+ {
+ rel->address += input_section->output_offset;
+ break;
+ }
+
+ /* Figure out the relocation of this symbol. */
+ symbol = *rel->sym_ptr_ptr;
+
+ if (bfd_is_und_section (symbol->section))
+ r = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += rel->addend;
+
+ if (tos == 0)
+ abort ();
+
+ stack[tos - 1] -= relocation;
+ }
+ break;
+
+ case ALPHA_R_OP_PRSHIFT:
+ /* Shift the value on the top of the stack. */
+ {
+ asymbol *symbol;
+ bfd_vma relocation;
+
+ if (relocateable)
+ {
+ rel->address += input_section->output_offset;
+ break;
+ }
+
+ /* Figure out the relocation of this symbol. */
+ symbol = *rel->sym_ptr_ptr;
+
+ if (bfd_is_und_section (symbol->section))
+ r = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += rel->addend;
+
+ if (tos == 0)
+ abort ();
+
+ stack[tos - 1] >>= relocation;
+ }
+ break;
+
+ case ALPHA_R_GPVALUE:
+ /* I really don't know if this does the right thing. */
+ gp = rel->addend;
+ gp_undefined = false;
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (relocateable)
+ {
+ asection *os = input_section->output_section;
+
+ /* A partial link, so keep the relocs. */
+ os->orelocation[os->reloc_count] = rel;
+ os->reloc_count++;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ case bfd_reloc_undefined:
+ if (! ((*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
+ input_bfd, input_section, rel->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_dangerous:
+ if (! ((*link_info->callbacks->reloc_dangerous)
+ (link_info, err, input_bfd, input_section,
+ rel->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_overflow:
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
+ rel->howto->name, rel->addend, input_bfd,
+ input_section, rel->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_outofrange:
+ default:
+ abort ();
+ break;
+ }
+ }
+ }
+
+ if (tos != 0)
+ abort ();
+
+ successful_return:
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return data;
+
+ error_return:
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return NULL;
+}
+
+/* Get the howto structure for a generic reloc type. */
+
+static reloc_howto_type *
+alpha_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ int alpha_type;
+
+ switch (code)
+ {
+ case BFD_RELOC_32:
+ alpha_type = ALPHA_R_REFLONG;
+ break;
+ case BFD_RELOC_64:
+ case BFD_RELOC_CTOR:
+ alpha_type = ALPHA_R_REFQUAD;
+ break;
+ case BFD_RELOC_GPREL32:
+ alpha_type = ALPHA_R_GPREL32;
+ break;
+ case BFD_RELOC_ALPHA_LITERAL:
+ alpha_type = ALPHA_R_LITERAL;
+ break;
+ case BFD_RELOC_ALPHA_LITUSE:
+ alpha_type = ALPHA_R_LITUSE;
+ break;
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ alpha_type = ALPHA_R_GPDISP;
+ break;
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ alpha_type = ALPHA_R_IGNORE;
+ break;
+ case BFD_RELOC_23_PCREL_S2:
+ alpha_type = ALPHA_R_BRADDR;
+ break;
+ case BFD_RELOC_ALPHA_HINT:
+ alpha_type = ALPHA_R_HINT;
+ break;
+ case BFD_RELOC_16_PCREL:
+ alpha_type = ALPHA_R_SREL16;
+ break;
+ case BFD_RELOC_32_PCREL:
+ alpha_type = ALPHA_R_SREL32;
+ break;
+ case BFD_RELOC_64_PCREL:
+ alpha_type = ALPHA_R_SREL64;
+ break;
+#if 0
+ case ???:
+ alpha_type = ALPHA_R_OP_PUSH;
+ break;
+ case ???:
+ alpha_type = ALPHA_R_OP_STORE;
+ break;
+ case ???:
+ alpha_type = ALPHA_R_OP_PSUB;
+ break;
+ case ???:
+ alpha_type = ALPHA_R_OP_PRSHIFT;
+ break;
+ case ???:
+ alpha_type = ALPHA_R_GPVALUE;
+ break;
+#endif
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+
+ return &alpha_howto_table[alpha_type];
+}
+
+/* A helper routine for alpha_relocate_section which converts an
+ external reloc when generating relocateable output. Returns the
+ relocation amount. */
+
+static bfd_vma
+alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ struct external_reloc *ext_rel;
+ struct ecoff_link_hash_entry *h;
+{
+ unsigned long r_symndx;
+ bfd_vma relocation;
+
+ BFD_ASSERT (info->relocateable);
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *hsec;
+ const char *name;
+
+ /* This symbol is defined in the output. Convert the reloc from
+ being against the symbol to being against the section. */
+
+ /* Clear the r_extern bit. */
+ ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
+
+ /* Compute a new r_symndx value. */
+ hsec = h->root.u.def.section;
+ name = bfd_get_section_name (output_bfd, hsec->output_section);
+
+ r_symndx = -1;
+ switch (name[1])
+ {
+ case 'A':
+ if (strcmp (name, "*ABS*") == 0)
+ r_symndx = RELOC_SECTION_ABS;
+ break;
+ case 'b':
+ if (strcmp (name, ".bss") == 0)
+ r_symndx = RELOC_SECTION_BSS;
+ break;
+ case 'd':
+ if (strcmp (name, ".data") == 0)
+ r_symndx = RELOC_SECTION_DATA;
+ break;
+ case 'f':
+ if (strcmp (name, ".fini") == 0)
+ r_symndx = RELOC_SECTION_FINI;
+ break;
+ case 'i':
+ if (strcmp (name, ".init") == 0)
+ r_symndx = RELOC_SECTION_INIT;
+ break;
+ case 'l':
+ if (strcmp (name, ".lita") == 0)
+ r_symndx = RELOC_SECTION_LITA;
+ else if (strcmp (name, ".lit8") == 0)
+ r_symndx = RELOC_SECTION_LIT8;
+ else if (strcmp (name, ".lit4") == 0)
+ r_symndx = RELOC_SECTION_LIT4;
+ break;
+ case 'p':
+ if (strcmp (name, ".pdata") == 0)
+ r_symndx = RELOC_SECTION_PDATA;
+ break;
+ case 'r':
+ if (strcmp (name, ".rdata") == 0)
+ r_symndx = RELOC_SECTION_RDATA;
+ else if (strcmp (name, ".rconst") == 0)
+ r_symndx = RELOC_SECTION_RCONST;
+ break;
+ case 's':
+ if (strcmp (name, ".sdata") == 0)
+ r_symndx = RELOC_SECTION_SDATA;
+ else if (strcmp (name, ".sbss") == 0)
+ r_symndx = RELOC_SECTION_SBSS;
+ break;
+ case 't':
+ if (strcmp (name, ".text") == 0)
+ r_symndx = RELOC_SECTION_TEXT;
+ break;
+ case 'x':
+ if (strcmp (name, ".xdata") == 0)
+ r_symndx = RELOC_SECTION_XDATA;
+ break;
+ }
+
+ if (r_symndx == -1)
+ abort ();
+
+ /* Add the section VMA and the symbol value. */
+ relocation = (h->root.u.def.value
+ + hsec->output_section->vma
+ + hsec->output_offset);
+ }
+ else
+ {
+ /* Change the symndx value to the right one for
+ the output BFD. */
+ r_symndx = h->indx;
+ if (r_symndx == -1)
+ {
+ /* Caller must give an error. */
+ r_symndx = 0;
+ }
+ relocation = 0;
+ }
+
+ /* Write out the new r_symndx value. */
+ bfd_h_put_32 (input_bfd, (bfd_vma) r_symndx,
+ (bfd_byte *) ext_rel->r_symndx);
+
+ return relocation;
+}
+
+/* Relocate a section while linking an Alpha ECOFF file. This is
+ quite similar to get_relocated_section_contents. Perhaps they
+ could be combined somehow. */
+
+static boolean
+alpha_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, external_relocs)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ PTR external_relocs;
+{
+ asection **symndx_to_section, *lita_sec;
+ struct ecoff_link_hash_entry **sym_hashes;
+ bfd_vma gp;
+ boolean gp_undefined;
+ bfd_vma stack[RELOC_STACKSIZE];
+ int tos = 0;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+
+ /* We keep a table mapping the symndx found in an internal reloc to
+ the appropriate section. This is faster than looking up the
+ section by name each time. */
+ symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
+ if (symndx_to_section == (asection **) NULL)
+ {
+ symndx_to_section = ((asection **)
+ bfd_alloc (input_bfd,
+ (NUM_RELOC_SECTIONS
+ * sizeof (asection *))));
+ if (!symndx_to_section)
+ return false;
+
+ symndx_to_section[RELOC_SECTION_NONE] = NULL;
+ symndx_to_section[RELOC_SECTION_TEXT] =
+ bfd_get_section_by_name (input_bfd, ".text");
+ symndx_to_section[RELOC_SECTION_RDATA] =
+ bfd_get_section_by_name (input_bfd, ".rdata");
+ symndx_to_section[RELOC_SECTION_DATA] =
+ bfd_get_section_by_name (input_bfd, ".data");
+ symndx_to_section[RELOC_SECTION_SDATA] =
+ bfd_get_section_by_name (input_bfd, ".sdata");
+ symndx_to_section[RELOC_SECTION_SBSS] =
+ bfd_get_section_by_name (input_bfd, ".sbss");
+ symndx_to_section[RELOC_SECTION_BSS] =
+ bfd_get_section_by_name (input_bfd, ".bss");
+ symndx_to_section[RELOC_SECTION_INIT] =
+ bfd_get_section_by_name (input_bfd, ".init");
+ symndx_to_section[RELOC_SECTION_LIT8] =
+ bfd_get_section_by_name (input_bfd, ".lit8");
+ symndx_to_section[RELOC_SECTION_LIT4] =
+ bfd_get_section_by_name (input_bfd, ".lit4");
+ symndx_to_section[RELOC_SECTION_XDATA] =
+ bfd_get_section_by_name (input_bfd, ".xdata");
+ symndx_to_section[RELOC_SECTION_PDATA] =
+ bfd_get_section_by_name (input_bfd, ".pdata");
+ symndx_to_section[RELOC_SECTION_FINI] =
+ bfd_get_section_by_name (input_bfd, ".fini");
+ symndx_to_section[RELOC_SECTION_LITA] =
+ bfd_get_section_by_name (input_bfd, ".lita");
+ symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
+ symndx_to_section[RELOC_SECTION_RCONST] =
+ bfd_get_section_by_name (input_bfd, ".rconst");
+
+ ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
+ }
+
+ sym_hashes = ecoff_data (input_bfd)->sym_hashes;
+
+ /* On the Alpha, the .lita section must be addressable by the global
+ pointer. To support large programs, we need to allow multiple
+ global pointers. This works as long as each input .lita section
+ is <64KB big. This implies that when producing relocatable
+ output, the .lita section is limited to 64KB. . */
+
+ lita_sec = symndx_to_section[RELOC_SECTION_LITA];
+ gp = _bfd_get_gp_value (output_bfd);
+ if (! info->relocateable && lita_sec != NULL)
+ {
+ struct ecoff_section_tdata *lita_sec_data;
+
+ /* Make sure we have a section data structure to which we can
+ hang on to the gp value we pick for the section. */
+ lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
+ if (lita_sec_data == NULL)
+ {
+ lita_sec_data = ((struct ecoff_section_tdata *)
+ bfd_zalloc (input_bfd,
+ sizeof (struct ecoff_section_tdata)));
+ ecoff_section_data (input_bfd, lita_sec) = lita_sec_data;
+ }
+
+ if (lita_sec_data->gp != 0)
+ {
+ /* If we already assigned a gp to this section, we better
+ stick with that value. */
+ gp = lita_sec_data->gp;
+ }
+ else
+ {
+ bfd_vma lita_vma;
+ bfd_size_type lita_size;
+
+ lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
+ lita_size = lita_sec->_cooked_size;
+ if (lita_size == 0)
+ lita_size = lita_sec->_raw_size;
+
+ if (gp == 0
+ || lita_vma < gp - 0x8000
+ || lita_vma + lita_size >= gp + 0x8000)
+ {
+ /* Either gp hasn't been set at all or the current gp
+ cannot address this .lita section. In both cases we
+ reset the gp to point into the "middle" of the
+ current input .lita section. */
+ if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
+ {
+ (*info->callbacks->warning) (info,
+ _("using multiple gp values"),
+ (char *) NULL, output_bfd,
+ (asection *) NULL, (bfd_vma) 0);
+ ecoff_data (output_bfd)->issued_multiple_gp_warning = true;
+ }
+ if (lita_vma < gp - 0x8000)
+ gp = lita_vma + lita_size - 0x8000;
+ else
+ gp = lita_vma + 0x8000;
+
+ }
+
+ lita_sec_data->gp = gp;
+ }
+
+ _bfd_set_gp_value (output_bfd, gp);
+ }
+
+ gp_undefined = (gp == 0);
+
+ BFD_ASSERT (bfd_header_little_endian (output_bfd));
+ BFD_ASSERT (bfd_header_little_endian (input_bfd));
+
+ ext_rel = (struct external_reloc *) external_relocs;
+ ext_rel_end = ext_rel + input_section->reloc_count;
+ for (; ext_rel < ext_rel_end; ext_rel++)
+ {
+ bfd_vma r_vaddr;
+ unsigned long r_symndx;
+ int r_type;
+ int r_extern;
+ int r_offset;
+ int r_size;
+ boolean relocatep;
+ boolean adjust_addrp;
+ boolean gp_usedp;
+ bfd_vma addend;
+
+ r_vaddr = bfd_h_get_64 (input_bfd, (bfd_byte *) ext_rel->r_vaddr);
+ r_symndx = bfd_h_get_32 (input_bfd, (bfd_byte *) ext_rel->r_symndx);
+
+ r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
+ >> RELOC_BITS0_TYPE_SH_LITTLE);
+ r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
+ r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
+ >> RELOC_BITS1_OFFSET_SH_LITTLE);
+ /* Ignored the reserved bits. */
+ r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
+ >> RELOC_BITS3_SIZE_SH_LITTLE);
+
+ relocatep = false;
+ adjust_addrp = true;
+ gp_usedp = false;
+ addend = 0;
+
+ switch (r_type)
+ {
+ default:
+ abort ();
+
+ case ALPHA_R_IGNORE:
+ /* This reloc appears after a GPDISP reloc. On earlier
+ versions of OSF/1, It marked the position of the second
+ instruction to be altered by the GPDISP reloc, but it is
+ not otherwise used for anything. For some reason, the
+ address of the relocation does not appear to include the
+ section VMA, unlike the other relocation types. */
+ if (info->relocateable)
+ bfd_h_put_64 (input_bfd,
+ input_section->output_offset + r_vaddr,
+ (bfd_byte *) ext_rel->r_vaddr);
+ adjust_addrp = false;
+ break;
+
+ case ALPHA_R_REFLONG:
+ case ALPHA_R_REFQUAD:
+ case ALPHA_R_HINT:
+ relocatep = true;
+ break;
+
+ case ALPHA_R_BRADDR:
+ case ALPHA_R_SREL16:
+ case ALPHA_R_SREL32:
+ case ALPHA_R_SREL64:
+ if (r_extern)
+ addend += - (r_vaddr + 4);
+ relocatep = true;
+ break;
+
+ case ALPHA_R_GPREL32:
+ /* This relocation is used in a switch table. It is a 32
+ bit offset from the current GP value. We must adjust it
+ by the different between the original GP value and the
+ current GP value. */
+ relocatep = true;
+ addend = ecoff_data (input_bfd)->gp - gp;
+ gp_usedp = true;
+ break;
+
+ case ALPHA_R_LITERAL:
+ /* This is a reference to a literal value, generally
+ (always?) in the .lita section. This is a 16 bit GP
+ relative relocation. Sometimes the subsequent reloc is a
+ LITUSE reloc, which indicates how this reloc is used.
+ This sometimes permits rewriting the two instructions
+ referred to by the LITERAL and the LITUSE into different
+ instructions which do not refer to .lita. This can save
+ a memory reference, and permits removing a value from
+ .lita thus saving GP relative space.
+
+ We do not these optimizations. To do them we would need
+ to arrange to link the .lita section first, so that by
+ the time we got here we would know the final values to
+ use. This would not be particularly difficult, but it is
+ not currently implemented. */
+
+ /* I believe that the LITERAL reloc will only apply to a ldq
+ or ldl instruction, so check my assumption. */
+ {
+ unsigned long insn;
+
+ insn = bfd_get_32 (input_bfd,
+ contents + r_vaddr - input_section->vma);
+ BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
+ || ((insn >> 26) & 0x3f) == 0x28);
+ }
+
+ relocatep = true;
+ addend = ecoff_data (input_bfd)->gp - gp;
+ gp_usedp = true;
+ break;
+
+ case ALPHA_R_LITUSE:
+ /* See ALPHA_R_LITERAL above for the uses of this reloc. It
+ does not cause anything to happen, itself. */
+ break;
+
+ case ALPHA_R_GPDISP:
+ /* This marks the ldah of an ldah/lda pair which loads the
+ gp register with the difference of the gp value and the
+ current location. The second of the pair is r_symndx
+ bytes ahead. It used to be marked with an ALPHA_R_IGNORE
+ reloc, but OSF/1 3.2 no longer does that. */
+ {
+ unsigned long insn1, insn2;
+
+ /* Get the two instructions. */
+ insn1 = bfd_get_32 (input_bfd,
+ contents + r_vaddr - input_section->vma);
+ insn2 = bfd_get_32 (input_bfd,
+ (contents
+ + r_vaddr
+ - input_section->vma
+ + r_symndx));
+
+ BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
+ BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
+
+ /* Get the existing addend. We must account for the sign
+ extension done by lda and ldah. */
+ addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
+ if (insn1 & 0x8000)
+ {
+ /* This is addend -= 0x100000000 without causing an
+ integer overflow on a 32 bit host. */
+ addend -= 0x80000000;
+ addend -= 0x80000000;
+ }
+ if (insn2 & 0x8000)
+ addend -= 0x10000;
+
+ /* The existing addend includes the difference between the
+ gp of the input BFD and the address in the input BFD.
+ We want to change this to the difference between the
+ final GP and the final address. */
+ addend += (gp
+ - ecoff_data (input_bfd)->gp
+ + input_section->vma
+ - (input_section->output_section->vma
+ + input_section->output_offset));
+
+ /* Change the instructions, accounting for the sign
+ extension, and write them out. */
+ if (addend & 0x8000)
+ addend += 0x10000;
+ insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
+ insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
+
+ bfd_put_32 (input_bfd, (bfd_vma) insn1,
+ contents + r_vaddr - input_section->vma);
+ bfd_put_32 (input_bfd, (bfd_vma) insn2,
+ contents + r_vaddr - input_section->vma + r_symndx);
+
+ gp_usedp = true;
+ }
+ break;
+
+ case ALPHA_R_OP_PUSH:
+ case ALPHA_R_OP_PSUB:
+ case ALPHA_R_OP_PRSHIFT:
+ /* Manipulate values on the reloc evaluation stack. The
+ r_vaddr field is not an address in input_section, it is
+ the current value (including any addend) of the object
+ being used. */
+ if (! r_extern)
+ {
+ asection *s;
+
+ s = symndx_to_section[r_symndx];
+ if (s == (asection *) NULL)
+ abort ();
+ addend = s->output_section->vma + s->output_offset - s->vma;
+ }
+ else
+ {
+ struct ecoff_link_hash_entry *h;
+
+ h = sym_hashes[r_symndx];
+ if (h == (struct ecoff_link_hash_entry *) NULL)
+ abort ();
+
+ if (! info->relocateable)
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ else
+ {
+ /* Note that we pass the address as 0, since we
+ do not have a meaningful number for the
+ location within the section that is being
+ relocated. */
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, (bfd_vma) 0)))
+ return false;
+ addend = 0;
+ }
+ }
+ else
+ {
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak
+ && h->indx == -1)
+ {
+ /* This symbol is not being written out. Pass
+ the address as 0, as with undefined_symbol,
+ above. */
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, h->root.root.string, input_bfd,
+ input_section, (bfd_vma) 0)))
+ return false;
+ }
+
+ addend = alpha_convert_external_reloc (output_bfd, info,
+ input_bfd,
+ ext_rel, h);
+ }
+ }
+
+ addend += r_vaddr;
+
+ if (info->relocateable)
+ {
+ /* Adjust r_vaddr by the addend. */
+ bfd_h_put_64 (input_bfd, addend,
+ (bfd_byte *) ext_rel->r_vaddr);
+ }
+ else
+ {
+ switch (r_type)
+ {
+ case ALPHA_R_OP_PUSH:
+ if (tos >= RELOC_STACKSIZE)
+ abort ();
+ stack[tos++] = addend;
+ break;
+
+ case ALPHA_R_OP_PSUB:
+ if (tos == 0)
+ abort ();
+ stack[tos - 1] -= addend;
+ break;
+
+ case ALPHA_R_OP_PRSHIFT:
+ if (tos == 0)
+ abort ();
+ stack[tos - 1] >>= addend;
+ break;
+ }
+ }
+
+ adjust_addrp = false;
+ break;
+
+ case ALPHA_R_OP_STORE:
+ /* Store a value from the reloc stack into a bitfield. If
+ we are generating relocateable output, all we do is
+ adjust the address of the reloc. */
+ if (! info->relocateable)
+ {
+ bfd_vma mask;
+ bfd_vma val;
+
+ if (tos == 0)
+ abort ();
+
+ /* Get the relocation mask. The separate steps and the
+ casts to bfd_vma are attempts to avoid a bug in the
+ Alpha OSF 1.3 C compiler. See reloc.c for more
+ details. */
+ mask = 1;
+ mask <<= (bfd_vma) r_size;
+ mask -= 1;
+
+ /* FIXME: I don't know what kind of overflow checking,
+ if any, should be done here. */
+ val = bfd_get_64 (input_bfd,
+ contents + r_vaddr - input_section->vma);
+ val &=~ mask << (bfd_vma) r_offset;
+ val |= (stack[--tos] & mask) << (bfd_vma) r_offset;
+ bfd_put_64 (input_bfd, val,
+ contents + r_vaddr - input_section->vma);
+ }
+ break;
+
+ case ALPHA_R_GPVALUE:
+ /* I really don't know if this does the right thing. */
+ gp = ecoff_data (input_bfd)->gp + r_symndx;
+ gp_undefined = false;
+ break;
+ }
+
+ if (relocatep)
+ {
+ reloc_howto_type *howto;
+ struct ecoff_link_hash_entry *h = NULL;
+ asection *s = NULL;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ /* Perform a relocation. */
+
+ howto = &alpha_howto_table[r_type];
+
+ if (r_extern)
+ {
+ h = sym_hashes[r_symndx];
+ /* If h is NULL, that means that there is a reloc
+ against an external symbol which we thought was just
+ a debugging symbol. This should not happen. */
+ if (h == (struct ecoff_link_hash_entry *) NULL)
+ abort ();
+ }
+ else
+ {
+ if (r_symndx >= NUM_RELOC_SECTIONS)
+ s = NULL;
+ else
+ s = symndx_to_section[r_symndx];
+
+ if (s == (asection *) NULL)
+ abort ();
+ }
+
+ if (info->relocateable)
+ {
+ /* We are generating relocateable output, and must
+ convert the existing reloc. */
+ if (r_extern)
+ {
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak
+ && h->indx == -1)
+ {
+ /* This symbol is not being written out. */
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, h->root.root.string, input_bfd,
+ input_section, r_vaddr - input_section->vma)))
+ return false;
+ }
+
+ relocation = alpha_convert_external_reloc (output_bfd,
+ info,
+ input_bfd,
+ ext_rel,
+ h);
+ }
+ else
+ {
+ /* This is a relocation against a section. Adjust
+ the value by the amount the section moved. */
+ relocation = (s->output_section->vma
+ + s->output_offset
+ - s->vma);
+ }
+
+ /* If this is PC relative, the existing object file
+ appears to already have the reloc worked out. We
+ must subtract out the old value and add in the new
+ one. */
+ if (howto->pc_relative)
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma);
+
+ /* Put in any addend. */
+ relocation += addend;
+
+ /* Adjust the contents. */
+ r = _bfd_relocate_contents (howto, input_bfd, relocation,
+ (contents
+ + r_vaddr
+ - input_section->vma));
+ }
+ else
+ {
+ /* We are producing a final executable. */
+ if (r_extern)
+ {
+ /* This is a reloc against a symbol. */
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *hsec;
+
+ hsec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + hsec->output_section->vma
+ + hsec->output_offset);
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section,
+ r_vaddr - input_section->vma)))
+ return false;
+ relocation = 0;
+ }
+ }
+ else
+ {
+ /* This is a reloc against a section. */
+ relocation = (s->output_section->vma
+ + s->output_offset
+ - s->vma);
+
+ /* Adjust a PC relative relocation by removing the
+ reference to the original source section. */
+ if (howto->pc_relative)
+ relocation += input_section->vma;
+ }
+
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ r_vaddr - input_section->vma,
+ relocation,
+ addend);
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (r_extern)
+ name = sym_hashes[r_symndx]->root.root.string;
+ else
+ name = bfd_section_name (input_bfd,
+ symndx_to_section[r_symndx]);
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, alpha_howto_table[r_type].name,
+ (bfd_vma) 0, input_bfd, input_section,
+ r_vaddr - input_section->vma)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (info->relocateable && adjust_addrp)
+ {
+ /* Change the address of the relocation. */
+ bfd_h_put_64 (input_bfd,
+ (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma
+ + r_vaddr),
+ (bfd_byte *) ext_rel->r_vaddr);
+ }
+
+ if (gp_usedp && gp_undefined)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info, _("GP relative relocation when GP not defined"),
+ input_bfd, input_section, r_vaddr - input_section->vma)))
+ return false;
+ /* Only give the error once per link. */
+ gp = 4;
+ _bfd_set_gp_value (output_bfd, gp);
+ gp_undefined = false;
+ }
+ }
+
+ if (tos != 0)
+ abort ();
+
+ return true;
+}
+
+/* Do final adjustments to the filehdr and the aouthdr. This routine
+ sets the dynamic bits in the file header. */
+
+/*ARGSUSED*/
+static boolean
+alpha_adjust_headers (abfd, fhdr, ahdr)
+ bfd *abfd;
+ struct internal_filehdr *fhdr;
+ struct internal_aouthdr *ahdr;
+{
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
+ fhdr->f_flags |= F_ALPHA_CALL_SHARED;
+ else if ((abfd->flags & DYNAMIC) != 0)
+ fhdr->f_flags |= F_ALPHA_SHARABLE;
+ return true;
+}
+
+/* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital
+ introduced archive packing, in which the elements in an archive are
+ optionally compressed using a simple dictionary scheme. We know
+ how to read such archives, but we don't write them. */
+
+#define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
+#define alpha_ecoff_slurp_extended_name_table \
+ _bfd_ecoff_slurp_extended_name_table
+#define alpha_ecoff_construct_extended_name_table \
+ _bfd_ecoff_construct_extended_name_table
+#define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
+#define alpha_ecoff_write_armap _bfd_ecoff_write_armap
+#define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
+#define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
+
+/* A compressed file uses this instead of ARFMAG. */
+
+#define ARFZMAG "Z\012"
+
+/* Read an archive header. This is like the standard routine, but it
+ also accepts ARFZMAG. */
+
+static PTR
+alpha_ecoff_read_ar_hdr (abfd)
+ bfd *abfd;
+{
+ struct areltdata *ret;
+ struct ar_hdr *h;
+
+ ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
+ if (ret == NULL)
+ return NULL;
+
+ h = (struct ar_hdr *) ret->arch_header;
+ if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
+ {
+ bfd_byte ab[8];
+
+ /* This is a compressed file. We must set the size correctly.
+ The size is the eight bytes after the dummy file header. */
+ if (bfd_seek (abfd, FILHSZ, SEEK_CUR) != 0
+ || bfd_read (ab, 1, 8, abfd) != 8
+ || bfd_seek (abfd, - (FILHSZ + 8), SEEK_CUR) != 0)
+ return NULL;
+
+ ret->parsed_size = bfd_h_get_64 (abfd, ab);
+ }
+
+ return (PTR) ret;
+}
+
+/* Get an archive element at a specified file position. This is where
+ we uncompress the archive element if necessary. */
+
+static bfd *
+alpha_ecoff_get_elt_at_filepos (archive, filepos)
+ bfd *archive;
+ file_ptr filepos;
+{
+ bfd *nbfd = NULL;
+ struct areltdata *tdata;
+ struct ar_hdr *hdr;
+ bfd_byte ab[8];
+ bfd_size_type size;
+ bfd_byte *buf, *p;
+ struct bfd_in_memory *bim;
+
+ nbfd = _bfd_get_elt_at_filepos (archive, filepos);
+ if (nbfd == NULL)
+ goto error_return;
+
+ if ((nbfd->flags & BFD_IN_MEMORY) != 0)
+ {
+ /* We have already expanded this BFD. */
+ return nbfd;
+ }
+
+ tdata = (struct areltdata *) nbfd->arelt_data;
+ hdr = (struct ar_hdr *) tdata->arch_header;
+ if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
+ return nbfd;
+
+ /* We must uncompress this element. We do this by copying it into a
+ memory buffer, and making bfd_read and bfd_seek use that buffer.
+ This can use a lot of memory, but it's simpler than getting a
+ temporary file, making that work with the file descriptor caching
+ code, and making sure that it is deleted at all appropriate
+ times. It can be changed if it ever becomes important. */
+
+ /* The compressed file starts with a dummy ECOFF file header. */
+ if (bfd_seek (nbfd, FILHSZ, SEEK_SET) != 0)
+ goto error_return;
+
+ /* The next eight bytes are the real file size. */
+ if (bfd_read (ab, 1, 8, nbfd) != 8)
+ goto error_return;
+ size = bfd_h_get_64 (nbfd, ab);
+
+ if (size == 0)
+ buf = NULL;
+ else
+ {
+ bfd_size_type left;
+ bfd_byte dict[4096];
+ unsigned int h;
+ bfd_byte b;
+
+ buf = (bfd_byte *) bfd_alloc (nbfd, size);
+ if (buf == NULL)
+ goto error_return;
+ p = buf;
+
+ left = size;
+
+ /* I don't know what the next eight bytes are for. */
+ if (bfd_read (ab, 1, 8, nbfd) != 8)
+ goto error_return;
+
+ /* This is the uncompression algorithm. It's a simple
+ dictionary based scheme in which each character is predicted
+ by a hash of the previous three characters. A control byte
+ indicates whether the character is predicted or whether it
+ appears in the input stream; each control byte manages the
+ next eight bytes in the output stream. */
+ memset (dict, 0, sizeof dict);
+ h = 0;
+ while (bfd_read (&b, 1, 1, nbfd) == 1)
+ {
+ unsigned int i;
+
+ for (i = 0; i < 8; i++, b >>= 1)
+ {
+ bfd_byte n;
+
+ if ((b & 1) == 0)
+ n = dict[h];
+ else
+ {
+ if (! bfd_read (&n, 1, 1, nbfd))
+ goto error_return;
+ dict[h] = n;
+ }
+
+ *p++ = n;
+
+ --left;
+ if (left == 0)
+ break;
+
+ h <<= 4;
+ h ^= n;
+ h &= sizeof dict - 1;
+ }
+
+ if (left == 0)
+ break;
+ }
+ }
+
+ /* Now the uncompressed file contents are in buf. */
+ bim = ((struct bfd_in_memory *)
+ bfd_alloc (nbfd, sizeof (struct bfd_in_memory)));
+ if (bim == NULL)
+ goto error_return;
+ bim->size = size;
+ bim->buffer = buf;
+
+ nbfd->mtime_set = true;
+ nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
+
+ nbfd->flags |= BFD_IN_MEMORY;
+ nbfd->iostream = (PTR) bim;
+ BFD_ASSERT (! nbfd->cacheable);
+
+ return nbfd;
+
+ error_return:
+ if (nbfd != NULL)
+ bfd_close (nbfd);
+ return NULL;
+}
+
+/* Open the next archived file. */
+
+static bfd *
+alpha_ecoff_openr_next_archived_file (archive, last_file)
+ bfd *archive;
+ bfd *last_file;
+{
+ file_ptr filestart;
+
+ if (last_file == NULL)
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ else
+ {
+ struct areltdata *t;
+ struct ar_hdr *h;
+ bfd_size_type size;
+
+ /* We can't use arelt_size here, because that uses parsed_size,
+ which is the uncompressed size. We need the compressed size. */
+ t = (struct areltdata *) last_file->arelt_data;
+ h = (struct ar_hdr *) t->arch_header;
+ size = strtol (h->ar_size, (char **) NULL, 10);
+
+ /* Pad to an even boundary...
+ Note that last_file->origin can be odd in the case of
+ BSD-4.4-style element with a long odd size. */
+ filestart = last_file->origin + size;
+ filestart += filestart % 2;
+ }
+
+ return alpha_ecoff_get_elt_at_filepos (archive, filestart);
+}
+
+/* Open the archive file given an index into the armap. */
+
+static bfd *
+alpha_ecoff_get_elt_at_index (abfd, index)
+ bfd *abfd;
+ symindex index;
+{
+ carsym *entry;
+
+ entry = bfd_ardata (abfd)->symdefs + index;
+ return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset);
+}
+
+/* This is the ECOFF backend structure. The backend field of the
+ target vector points to this. */
+
+static const struct ecoff_backend_data alpha_ecoff_backend_data =
+{
+ /* COFF backend structure. */
+ {
+ (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
+ (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
+ (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
+ (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
+ (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
+ (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
+ (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
+ alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
+ alpha_ecoff_swap_scnhdr_out,
+ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, false, 4,
+ alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
+ alpha_ecoff_swap_scnhdr_in, NULL,
+ alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
+ alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
+ _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ },
+ /* Supported architecture. */
+ bfd_arch_alpha,
+ /* Initial portion of armap string. */
+ "________64",
+ /* The page boundary used to align sections in a demand-paged
+ executable file. E.g., 0x1000. */
+ 0x2000,
+ /* True if the .rdata section is part of the text segment, as on the
+ Alpha. False if .rdata is part of the data segment, as on the
+ MIPS. */
+ true,
+ /* Bitsize of constructor entries. */
+ 64,
+ /* Reloc to use for constructor entries. */
+ &alpha_howto_table[ALPHA_R_REFQUAD],
+ {
+ /* Symbol table magic number. */
+ magicSym2,
+ /* Alignment of debugging information. E.g., 4. */
+ 8,
+ /* Sizes of external symbolic information. */
+ sizeof (struct hdr_ext),
+ sizeof (struct dnr_ext),
+ sizeof (struct pdr_ext),
+ sizeof (struct sym_ext),
+ sizeof (struct opt_ext),
+ sizeof (struct fdr_ext),
+ sizeof (struct rfd_ext),
+ sizeof (struct ext_ext),
+ /* Functions to swap in external symbolic data. */
+ ecoff_swap_hdr_in,
+ ecoff_swap_dnr_in,
+ ecoff_swap_pdr_in,
+ ecoff_swap_sym_in,
+ ecoff_swap_opt_in,
+ ecoff_swap_fdr_in,
+ ecoff_swap_rfd_in,
+ ecoff_swap_ext_in,
+ _bfd_ecoff_swap_tir_in,
+ _bfd_ecoff_swap_rndx_in,
+ /* Functions to swap out external symbolic data. */
+ ecoff_swap_hdr_out,
+ ecoff_swap_dnr_out,
+ ecoff_swap_pdr_out,
+ ecoff_swap_sym_out,
+ ecoff_swap_opt_out,
+ ecoff_swap_fdr_out,
+ ecoff_swap_rfd_out,
+ ecoff_swap_ext_out,
+ _bfd_ecoff_swap_tir_out,
+ _bfd_ecoff_swap_rndx_out,
+ /* Function to read in symbolic data. */
+ _bfd_ecoff_slurp_symbolic_info
+ },
+ /* External reloc size. */
+ RELSZ,
+ /* Reloc swapping functions. */
+ alpha_ecoff_swap_reloc_in,
+ alpha_ecoff_swap_reloc_out,
+ /* Backend reloc tweaking. */
+ alpha_adjust_reloc_in,
+ alpha_adjust_reloc_out,
+ /* Relocate section contents while linking. */
+ alpha_relocate_section,
+ /* Do final adjustments to filehdr and aouthdr. */
+ alpha_adjust_headers,
+ /* Read an element from an archive at a given file position. */
+ alpha_ecoff_get_elt_at_filepos
+};
+
+/* Looking up a reloc type is Alpha specific. */
+#define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
+
+/* So is getting relocated section contents. */
+#define _bfd_ecoff_bfd_get_relocated_section_contents \
+ alpha_ecoff_get_relocated_section_contents
+
+/* Handling file windows is generic. */
+#define _bfd_ecoff_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+/* Relaxing sections is generic. */
+#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
+#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
+
+const bfd_target ecoffalpha_little_vec =
+{
+ "ecoff-littlealpha", /* name */
+ bfd_target_ecoff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
+ _bfd_ecoff_archive_p, _bfd_dummy_target},
+ {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
+ BFD_JUMP_TABLE_COPY (_bfd_ecoff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
+ BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
+ BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
+ BFD_JUMP_TABLE_LINK (_bfd_ecoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) &alpha_ecoff_backend_data
+};
diff --git a/bfd/coff-apollo.c b/bfd/coff-apollo.c
new file mode 100644
index 00000000000..253ec8944b8
--- /dev/null
+++ b/bfd/coff-apollo.c
@@ -0,0 +1,161 @@
+/* BFD back-end for Apollo 68000 COFF binaries.
+ Copyright 1990, 91, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ By Troy Rollo (troy@cbme.unsw.edu.au)
+ Based on m68k standard COFF version Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/apollo.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+#ifdef ONLY_DECLARE_RELOCS
+extern reloc_howto_type apollocoff_howto_table[];
+#else
+reloc_howto_type apollocoff_howto_table[] =
+{
+ HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff,0x000000ff, false),
+ HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff,0xffffffff, false),
+ HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff,0x000000ff, false),
+ HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff,0xffffffff, false),
+ HOWTO(R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "-32", true, 0xffffffff,0xffffffff, false),
+};
+#endif /* not ONLY_DECLARE_RELOCS */
+
+#ifndef BADMAG
+#define BADMAG(x) M68KBADMAG(x)
+#endif
+#define APOLLO_M68 1 /* Customize coffcode.h */
+
+/* Turn a howto into a reloc number */
+
+#ifdef ONLY_DECLARE_RELOCS
+extern void apollo_rtype2howto PARAMS ((arelent *internal, int relocentry));
+extern int apollo_howto2rtype PARAMS ((reloc_howto_type *));
+#else
+void
+apollo_rtype2howto(internal, relocentry)
+ arelent *internal;
+ int relocentry;
+{
+ switch (relocentry)
+ {
+ case R_RELBYTE: internal->howto = apollocoff_howto_table + 0; break;
+ case R_RELWORD: internal->howto = apollocoff_howto_table + 1; break;
+ case R_RELLONG: internal->howto = apollocoff_howto_table + 2; break;
+ case R_PCRBYTE: internal->howto = apollocoff_howto_table + 3; break;
+ case R_PCRWORD: internal->howto = apollocoff_howto_table + 4; break;
+ case R_PCRLONG: internal->howto = apollocoff_howto_table + 5; break;
+ case R_RELLONG_NEG: internal->howto = apollocoff_howto_table + 6; break;
+ }
+}
+
+int
+apollo_howto2rtype (internal)
+ reloc_howto_type *internal;
+{
+ if (internal->pc_relative)
+ {
+ switch (internal->bitsize)
+ {
+ case 32: return R_PCRLONG;
+ case 16: return R_PCRWORD;
+ case 8: return R_PCRBYTE;
+ }
+ }
+ else
+ {
+ switch (internal->bitsize)
+ {
+ case 32: return R_RELLONG;
+ case 16: return R_RELWORD;
+ case 8: return R_RELBYTE;
+ }
+ }
+ return R_RELLONG;
+}
+#endif /* not ONLY_DECLARE_RELOCS */
+
+#define RTYPE2HOWTO(internal, relocentry) \
+ apollo_rtype2howto(internal, (relocentry)->r_type)
+
+#define SELECT_RELOC(external, internal) \
+ external.r_type = apollo_howto2rtype(internal);
+
+#include "coffcode.h"
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ apollocoff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "apollo-m68k", /* name */
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#ifdef NAMES_HAVE_UNDERSCORE
+ '_',
+#else
+ 0, /* leading underscore */
+#endif
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE
+ };
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
new file mode 100644
index 00000000000..d478ce5f98c
--- /dev/null
+++ b/bfd/coff-arm.c
@@ -0,0 +1,2557 @@
+/* BFD back-end for ARM COFF files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "coff/arm.h"
+
+#include "coff/internal.h"
+
+#ifdef COFF_WITH_PE
+#include "coff/pe.h"
+#endif
+
+#include "libcoff.h"
+
+/* Macros for manipulation the bits in the flags field of the coff data
+ structure. */
+#define APCS_26_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_26)
+#define APCS_FLOAT_FLAG( abfd ) (coff_data (abfd)->flags & F_APCS_FLOAT)
+#define PIC_FLAG( abfd ) (coff_data (abfd)->flags & F_PIC)
+#define APCS_SET( abfd ) (coff_data (abfd)->flags & F_APCS_SET)
+#define SET_APCS_FLAGS( abfd, flgs) (coff_data (abfd)->flags = \
+ (coff_data (abfd)->flags & ~ (F_APCS_26 | F_APCS_FLOAT | F_PIC)) \
+ | (flgs | F_APCS_SET))
+#define INTERWORK_FLAG( abfd ) (coff_data (abfd)->flags & F_INTERWORK)
+#define INTERWORK_SET( abfd ) (coff_data (abfd)->flags & F_INTERWORK_SET)
+#define SET_INTERWORK_FLAG( abfd, flg ) (coff_data (abfd)->flags = \
+ (coff_data (abfd)->flags & ~ F_INTERWORK) \
+ | (flg | F_INTERWORK_SET))
+
+typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
+/* some typedefs for holding instructions */
+typedef unsigned long int insn32;
+typedef unsigned short int insn16;
+
+
+ /* Forward declarations for stupid compilers. */
+static boolean coff_arm_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type aoutarm_fix_pcrel_26
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type coff_thumb_pcrel_23
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type coff_thumb_pcrel_12
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type coff_thumb_pcrel_9
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type coff_arm_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean coff_arm_adjust_symndx
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *,
+ asection *, struct internal_reloc *, boolean *));
+static reloc_howto_type * coff_arm_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
+static bfd_reloc_status_type coff_thumb_pcrel_common
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **,
+ thumb_pcrel_branchtype));
+static CONST struct reloc_howto_struct * coff_arm_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static struct bfd_link_hash_table * coff_arm_link_hash_table_create
+ PARAMS ((bfd *));
+static insn32 insert_thumb_branch
+ PARAMS ((insn32, int));
+static struct coff_link_hash_entry * find_thumb_glue
+ PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
+static struct coff_link_hash_entry * find_arm_glue
+ PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
+static void record_arm_to_thumb_glue
+ PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *));
+static void record_thumb_to_arm_glue
+ PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *));
+static boolean coff_arm_merge_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean coff_arm_print_private_bfd_data
+ PARAMS ((bfd *, PTR));
+static boolean _bfd_coff_arm_set_private_flags
+ PARAMS ((bfd *, flagword));
+static boolean coff_arm_copy_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean coff_arm_is_local_label_name
+ PARAMS ((bfd *, const char *));
+static boolean coff_arm_link_output_has_begun
+ PARAMS ((bfd *, struct coff_final_link_info *));
+static boolean coff_arm_final_link_postscript
+ PARAMS ((bfd *, struct coff_final_link_info *));
+
+/* The linker script knows the section names for placement.
+ The entry_names are used to do simple name mangling on the stubs.
+ Given a function name, and its type, the stub can be found. The
+ name can be changed. The only requirement is the %s be present.
+ */
+
+#define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
+#define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
+
+#define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
+#define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
+
+/* Used by the assembler. */
+static bfd_reloc_status_type
+coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ symvalue diff;
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ diff = reloc_entry->addend;
+
+#define DOIT(x) \
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+ if (diff != 0)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, addr);
+ DOIT (x);
+ bfd_put_16 (abfd, x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+/* If USER_LABEL_PREFIX is defined as "_" (see coff_arm_is_local_label_name()
+ in this file), then TARGET_UNDERSCORE should be defined, otherwise it
+ should not. */
+#ifndef TARGET_UNDERSCORE
+#define TARGET_UNDERSCORE '_'
+#endif
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET true
+#endif
+
+/* These most certainly belong somewhere else. Just had to get rid of
+ the manifest constants in the code. */
+
+#define ARM_8 0
+#define ARM_16 1
+#define ARM_32 2
+#define ARM_26 3
+#define ARM_DISP8 4
+#define ARM_DISP16 5
+#define ARM_DISP32 6
+#define ARM_26D 7
+/* 8 is unused */
+#define ARM_NEG16 9
+#define ARM_NEG32 10
+#define ARM_RVA32 11
+#define ARM_THUMB9 12
+#define ARM_THUMB12 13
+#define ARM_THUMB23 14
+
+static reloc_howto_type aoutarm_std_reloc_howto[] =
+{
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+ HOWTO(ARM_8, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_arm_reloc, /* special_function */
+ "ARM_8", /* name */
+ true, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET /* pcrel_offset */),
+ HOWTO(ARM_16,
+ 0,
+ 1,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_16",
+ true,
+ 0x0000ffff,
+ 0x0000ffff,
+ PCRELOFFSET),
+ HOWTO(ARM_32,
+ 0,
+ 2,
+ 32,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_32",
+ true,
+ 0xffffffff,
+ 0xffffffff,
+ PCRELOFFSET),
+ HOWTO(ARM_26,
+ 2,
+ 2,
+ 24,
+ true,
+ 0,
+ complain_overflow_signed,
+ aoutarm_fix_pcrel_26 ,
+ "ARM_26",
+ false,
+ 0x00ffffff,
+ 0x00ffffff,
+ PCRELOFFSET),
+ HOWTO(ARM_DISP8,
+ 0,
+ 0,
+ 8,
+ true,
+ 0,
+ complain_overflow_signed,
+ coff_arm_reloc,
+ "ARM_DISP8",
+ true,
+ 0x000000ff,
+ 0x000000ff,
+ true),
+ HOWTO( ARM_DISP16,
+ 0,
+ 1,
+ 16,
+ true,
+ 0,
+ complain_overflow_signed,
+ coff_arm_reloc,
+ "ARM_DISP16",
+ true,
+ 0x0000ffff,
+ 0x0000ffff,
+ true),
+ HOWTO( ARM_DISP32,
+ 0,
+ 2,
+ 32,
+ true,
+ 0,
+ complain_overflow_signed,
+ coff_arm_reloc,
+ "ARM_DISP32",
+ true,
+ 0xffffffff,
+ 0xffffffff,
+ true),
+ HOWTO( ARM_26D,
+ 2,
+ 2,
+ 24,
+ false,
+ 0,
+ complain_overflow_dont,
+ aoutarm_fix_pcrel_26_done,
+ "ARM_26D",
+ true,
+ 0x00ffffff,
+ 0x0,
+ false),
+ /* 8 is unused */
+ {-1},
+ HOWTO( ARM_NEG16,
+ 0,
+ -1,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_NEG16",
+ true,
+ 0x0000ffff,
+ 0x0000ffff,
+ false),
+ HOWTO( ARM_NEG32,
+ 0,
+ -2,
+ 32,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_NEG32",
+ true,
+ 0xffffffff,
+ 0xffffffff,
+ false),
+ HOWTO( ARM_RVA32,
+ 0,
+ 2,
+ 32,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_RVA32",
+ true,
+ 0xffffffff,
+ 0xffffffff,
+ PCRELOFFSET),
+ HOWTO( ARM_THUMB9,
+ 1,
+ 1,
+ 8,
+ true,
+ 0,
+ complain_overflow_signed,
+ coff_thumb_pcrel_9 ,
+ "ARM_THUMB9",
+ false,
+ 0x000000ff,
+ 0x000000ff,
+ PCRELOFFSET),
+ HOWTO( ARM_THUMB12,
+ 1,
+ 1,
+ 11,
+ true,
+ 0,
+ complain_overflow_signed,
+ coff_thumb_pcrel_12 ,
+ "ARM_THUMB12",
+ false,
+ 0x000007ff,
+ 0x000007ff,
+ PCRELOFFSET),
+ HOWTO( ARM_THUMB23,
+ 1,
+ 2,
+ 22,
+ true,
+ 0,
+ complain_overflow_signed,
+ coff_thumb_pcrel_23 ,
+ "ARM_THUMB23",
+ false,
+ 0x07ff07ff,
+ 0x07ff07ff,
+ PCRELOFFSET),
+};
+
+#ifdef COFF_WITH_PE
+/* Return true if this relocation should
+ appear in the output .reloc section. */
+
+static boolean
+in_reloc_p (abfd, howto)
+ bfd * abfd;
+ reloc_howto_type * howto;
+{
+ return !howto->pc_relative && howto->type != ARM_RVA32;
+}
+#endif
+
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type;
+
+#define coff_rtype_to_howto coff_arm_rtype_to_howto
+
+static reloc_howto_type *
+coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+ reloc_howto_type *howto;
+
+ howto = aoutarm_std_reloc_howto + rel->r_type;
+
+ if (rel->r_type == ARM_RVA32)
+ {
+ *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
+ }
+
+ return howto;
+
+}
+/* Used by the assembler. */
+
+static bfd_reloc_status_type
+aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* This is dead simple at present. */
+ return bfd_reloc_ok;
+}
+
+/* Used by the assembler. */
+
+static bfd_reloc_status_type
+aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_size_type addr = reloc_entry->address;
+ long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+
+ /* If this is an undefined symbol, return error */
+ if (symbol->section == &bfd_und_section
+ && (symbol->flags & BSF_WEAK) == 0)
+ return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
+
+ /* If the sections are different, and we are doing a partial relocation,
+ just ignore it for now. */
+ if (symbol->section->name != input_section->name
+ && output_bfd != (bfd *)NULL)
+ return bfd_reloc_continue;
+
+ relocation = (target & 0x00ffffff) << 2;
+ relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
+ relocation += symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+ relocation -= input_section->output_section->vma;
+ relocation -= input_section->output_offset;
+ relocation -= addr;
+
+ if (relocation & 3)
+ return bfd_reloc_overflow;
+
+ /* Check for overflow */
+ if (relocation & 0x02000000)
+ {
+ if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
+ flag = bfd_reloc_overflow;
+ }
+ else if (relocation & ~0x03ffffff)
+ flag = bfd_reloc_overflow;
+
+ target &= ~0x00ffffff;
+ target |= (relocation >> 2) & 0x00ffffff;
+ bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
+
+ /* Now the ARM magic... Change the reloc type so that it is marked as done.
+ Strictly this is only necessary if we are doing a partial relocation. */
+ reloc_entry->howto = &aoutarm_std_reloc_howto[ARM_26D];
+
+ return flag;
+}
+
+static bfd_reloc_status_type
+coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message, btype)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+ thumb_pcrel_branchtype btype;
+{
+ bfd_vma relocation = 0;
+ bfd_size_type addr = reloc_entry->address;
+ long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_vma dstmsk;
+ bfd_vma offmsk;
+ bfd_vma signbit;
+
+ /* NOTE: This routine is currently used by GAS, but not by the link
+ phase. */
+
+ switch (btype)
+ {
+ case b9:
+ dstmsk = 0x000000ff;
+ offmsk = 0x000001fe;
+ signbit = 0x00000100;
+ break;
+
+ case b12:
+ dstmsk = 0x000007ff;
+ offmsk = 0x00000ffe;
+ signbit = 0x00000800;
+ break;
+
+ case b23:
+ dstmsk = 0x07ff07ff;
+ offmsk = 0x007fffff;
+ signbit = 0x00400000;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If this is an undefined symbol, return error */
+ if (symbol->section == &bfd_und_section
+ && (symbol->flags & BSF_WEAK) == 0)
+ return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
+
+ /* If the sections are different, and we are doing a partial relocation,
+ just ignore it for now. */
+ if (symbol->section->name != input_section->name
+ && output_bfd != (bfd *)NULL)
+ return bfd_reloc_continue;
+
+ switch (btype)
+ {
+ case b9:
+ case b12:
+ relocation = ((target & dstmsk) << 1);
+ break;
+
+ case b23:
+ if (bfd_big_endian (abfd))
+ relocation = ((target & 0x7ff) << 1) | ((target & 0x07ff0000) >> 4);
+ else
+ relocation = ((target & 0x7ff) << 12) | ((target & 0x07ff0000) >> 15);
+ break;
+
+ default:
+ abort ();
+ }
+
+ relocation = (relocation ^ signbit) - signbit; /* Sign extend */
+ relocation += symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+ relocation -= input_section->output_section->vma;
+ relocation -= input_section->output_offset;
+ relocation -= addr;
+
+ if (relocation & 1)
+ return bfd_reloc_overflow;
+
+ /* Check for overflow */
+ if (relocation & signbit)
+ {
+ if ((relocation & ~offmsk) != ~offmsk)
+ flag = bfd_reloc_overflow;
+ }
+ else if (relocation & ~offmsk)
+ flag = bfd_reloc_overflow;
+
+ target &= ~dstmsk;
+ switch (btype)
+ {
+ case b9:
+ case b12:
+ target |= (relocation >> 1);
+ break;
+
+ case b23:
+ if (bfd_big_endian (abfd))
+ target |= ((relocation & 0xfff) >> 1) | ((relocation << 4) & 0x07ff0000);
+ else
+ target |= ((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff);
+ break;
+
+ default:
+ abort ();
+ }
+
+ bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
+
+ /* Now the ARM magic... Change the reloc type so that it is marked as done.
+ Strictly this is only necessary if we are doing a partial relocation. */
+ reloc_entry->howto = & aoutarm_std_reloc_howto [ARM_26D];
+
+ /* TODO: We should possibly have DONE entries for the THUMB PCREL relocations */
+ return flag;
+}
+
+static bfd_reloc_status_type
+coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message, b23);
+}
+
+static bfd_reloc_status_type
+coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message, b12);
+}
+
+static bfd_reloc_status_type
+coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message, b9);
+}
+
+
+static CONST struct reloc_howto_struct *
+coff_arm_reloc_type_lookup (abfd, code)
+ bfd * abfd;
+ bfd_reloc_code_real_type code;
+{
+#define ASTD(i,j) case i: return &aoutarm_std_reloc_howto[j]
+ if (code == BFD_RELOC_CTOR)
+ switch (bfd_get_arch_info (abfd)->bits_per_address)
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default: return (CONST struct reloc_howto_struct *) 0;
+ }
+
+ switch (code)
+ {
+ ASTD (BFD_RELOC_8, ARM_8);
+ ASTD (BFD_RELOC_16, ARM_16);
+ ASTD (BFD_RELOC_32, ARM_32);
+ ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
+ ASTD (BFD_RELOC_8_PCREL, ARM_DISP8);
+ ASTD (BFD_RELOC_16_PCREL, ARM_DISP16);
+ ASTD (BFD_RELOC_32_PCREL, ARM_DISP32);
+ ASTD (BFD_RELOC_RVA, ARM_RVA32);
+ ASTD (BFD_RELOC_THUMB_PCREL_BRANCH9, ARM_THUMB9);
+ ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
+ ASTD (BFD_RELOC_THUMB_PCREL_BRANCH23, ARM_THUMB23);
+ default: return (CONST struct reloc_howto_struct *) 0;
+ }
+}
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+#define COFF_PAGE_SIZE 0x1000
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define BADMAG(x) ARMBADMAG(x)
+#define ARM 1 /* Customize coffcode.h */
+
+/* Extend the coff_link_hash_table structure with a few ARM specific fields.
+ This allows us to store global data here without actually creating any
+ global variables, which is a no-no in the BFD world. */
+struct coff_arm_link_hash_table
+{
+ /* The original coff_link_hash_table structure. MUST be first field. */
+ struct coff_link_hash_table root;
+
+ /* The size in bytes of the section containg the Thumb-to-ARM glue. */
+ long int thumb_glue_size;
+
+ /* The size in bytes of the section containg the ARM-to-Thumb glue. */
+ long int arm_glue_size;
+
+ /* An arbitary input BFD chosen to hold the glue sections. */
+ bfd * bfd_of_glue_owner;
+
+ /* Support interworking with old, non-interworking aware ARM code. */
+ int support_old_code;
+};
+
+/* Get the ARM coff linker hash table from a link_info structure. */
+#define coff_arm_hash_table(info) \
+ ((struct coff_arm_link_hash_table *) ((info)->hash))
+
+/* Create an ARM coff linker hash table. */
+
+static struct bfd_link_hash_table *
+coff_arm_link_hash_table_create (abfd)
+ bfd * abfd;
+{
+ struct coff_arm_link_hash_table * ret;
+
+ ret = ((struct coff_arm_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct coff_arm_link_hash_table)));
+ if (ret == (struct coff_arm_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_coff_link_hash_table_init
+ (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->thumb_glue_size = 0;
+ ret->arm_glue_size = 0;
+ ret->bfd_of_glue_owner = NULL;
+
+ return & ret->root.root;
+}
+
+static
+arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
+ struct bfd_link_info *info;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_vma reloc_offset;
+{
+ bfd_vma addr = reloc_offset
+ - input_section->vma
+ + input_section->output_offset
+ + input_section->output_section->vma;
+
+ if (coff_data(output_bfd)->pe)
+ addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
+ fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file);
+
+}
+
+/* The thumb form of a long branch is a bit finicky, because the offset
+ encoding is split over two fields, each in it's own instruction. They
+ can occur in any order. So given a thumb form of long branch, and an
+ offset, insert the offset into the thumb branch and return finished
+ instruction.
+
+ It takes two thumb instructions to encode the target address. Each has
+ 11 bits to invest. The upper 11 bits are stored in one (identifed by
+ H-0.. see below), the lower 11 bits are stored in the other (identified
+ by H-1).
+
+ Combine together and shifted left by 1 (it's a half word address) and
+ there you have it.
+
+ Op: 1111 = F,
+ H-0, upper address-0 = 000
+ Op: 1111 = F,
+ H-1, lower address-0 = 800
+
+ They can be ordered either way, but the arm tools I've seen always put
+ the lower one first. It probably doesn't matter. krk@cygnus.com
+
+ XXX: Actually the order does matter. The second instruction (H-1)
+ moves the computed address into the PC, so it must be the second one
+ in the sequence. The problem, however is that whilst little endian code
+ stores the instructions in HI then LOW order, big endian code does the
+ reverse. nickc@cygnus.com */
+
+#define LOW_HI_ORDER 0xF800F000
+#define HI_LOW_ORDER 0xF000F800
+
+static insn32
+insert_thumb_branch (br_insn, rel_off)
+ insn32 br_insn;
+ int rel_off;
+{
+ unsigned int low_bits;
+ unsigned int high_bits;
+
+
+ BFD_ASSERT((rel_off & 1) != 1);
+
+ rel_off >>= 1; /* half word aligned address */
+ low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
+ high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
+
+ if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
+ br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
+ else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
+ br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
+ else
+ abort(); /* error - not a valid branch instruction form */
+
+ /* FIXME: abort is probably not the right call. krk@cygnus.com */
+
+ return br_insn;
+}
+
+
+static struct coff_link_hash_entry *
+find_thumb_glue (info, name, input_bfd)
+ struct bfd_link_info * info;
+ CONST char * name;
+ bfd * input_bfd;
+{
+ char * tmp_name;
+ struct coff_link_hash_entry * myh;
+
+ tmp_name = ((char *)
+ bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1));
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
+
+ myh = coff_link_hash_lookup
+ (coff_hash_table (info), tmp_name, false, false, true);
+
+ if (myh == NULL)
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"),
+ bfd_get_filename (input_bfd), tmp_name, name);
+
+ free (tmp_name);
+
+ return myh;
+}
+
+static struct coff_link_hash_entry *
+find_arm_glue (info, name, input_bfd)
+ struct bfd_link_info * info;
+ CONST char * name;
+ bfd * input_bfd;
+{
+ char * tmp_name;
+ struct coff_link_hash_entry * myh;
+
+ tmp_name = ((char *)
+ bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
+
+ myh = coff_link_hash_lookup
+ (coff_hash_table (info), tmp_name, false, false, true);
+
+ if (myh == NULL)
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"),
+ bfd_get_filename (input_bfd), tmp_name, name);
+
+ free (tmp_name);
+
+ return myh;
+}
+
+/*
+ ARM->Thumb glue:
+
+ .arm
+ __func_from_arm:
+ ldr r12, __func_addr
+ bx r12
+ __func_addr:
+ .word func @ behave as if you saw a ARM_32 reloc
+*/
+
+#define ARM2THUMB_GLUE_SIZE 12
+static const insn32 a2t1_ldr_insn = 0xe59fc000;
+static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
+static const insn32 a2t3_func_addr_insn = 0x00000001;
+
+#define A2T3_OFFSET 8
+
+/*
+ Thumb->ARM: Thumb->(non-interworking aware) ARM
+
+ .thumb .thumb
+ .align 2 .align 2
+ __func_from_thumb: __func_from_thumb:
+ bx pc push {r6, lr}
+ nop ldr r6, __func_addr
+ .arm mov lr, pc
+ __func_change_to_arm: bx r6
+ b func .arm
+ __func_back_to_thumb:
+ ldmia r13! {r6, lr}
+ bx lr
+ __func_addr:
+ .word func
+*/
+
+#define THUMB2ARM_GLUE_SIZE (globals->support_old_code ? 20 : 8)
+static const insn16 t2a1_bx_pc_insn = 0x4778;
+static const insn16 t2a2_noop_insn = 0x46c0;
+static const insn32 t2a3_b_insn = 0xea000000;
+
+#define T2A3_OFFSET 8
+
+static const insn16 t2a1_push_insn = 0xb540;
+static const insn16 t2a2_ldr_insn = 0x4e03;
+static const insn16 t2a3_mov_insn = 0x46fe;
+static const insn16 t2a4_bx_insn = 0x4730;
+static const insn32 t2a5_pop_insn = 0xe8bd4040;
+static const insn32 t2a6_bx_insn = 0xe12fff1e;
+
+/* TODO:
+ We should really create new local (static) symbols in destination
+ object for each stub we create. We should also create local
+ (static) symbols within the stubs when switching between ARM and
+ Thumb code. This will ensure that the debugger and disassembler
+ can present a better view of stubs.
+
+ We can treat stubs like literal sections, and for the THUMB9 ones
+ (short addressing range) we should be able to insert the stubs
+ between sections. i.e. the simplest approach (since relocations
+ are done on a section basis) is to dump the stubs at the end of
+ processing a section. That way we can always try and minimise the
+ offset to and from a stub. However, this does not map well onto
+ the way that the linker/BFD does its work: mapping all input
+ sections to output sections via the linker script before doing
+ all the processing.
+
+ Unfortunately it may be easier to just to disallow short range
+ Thumb->ARM stubs (i.e. no conditional inter-working branches,
+ only branch-and-link (BL) calls. This will simplify the processing
+ since we can then put all of the stubs into their own section.
+
+ TODO:
+ On a different subject, rather than complaining when a
+ branch cannot fit in the number of bits available for the
+ instruction we should generate a trampoline stub (needed to
+ address the complete 32bit address space). */
+
+/* The standard COFF backend linker does not cope with the special
+ Thumb BRANCH23 relocation. The alternative would be to split the
+ BRANCH23 into seperate HI23 and LO23 relocations. However, it is a
+ bit simpler simply providing our own relocation driver. */
+
+/* The reloc processing routine for the ARM/Thumb COFF linker. NOTE:
+ This code is a very slightly modified copy of
+ _bfd_coff_generic_relocate_section. It would be a much more
+ maintainable solution to have a MACRO that could be expanded within
+ _bfd_coff_generic_relocate_section that would only be provided for
+ ARM/Thumb builds. It is only the code marked THUMBEXTENSION that
+ is different from the original. */
+
+static boolean
+coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, syms, sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc * rel;
+ struct internal_reloc * relend;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+
+ for (; rel < relend; rel++)
+ {
+ int done = 0;
+ long symndx;
+ struct coff_link_hash_entry * h;
+ struct internal_syment * sym;
+ bfd_vma addend;
+ bfd_vma val;
+ reloc_howto_type * howto;
+ bfd_reloc_status_type rstat;
+ bfd_vma h_val;
+
+ symndx = rel->r_symndx;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ }
+
+ /* COFF treats common symbols in one of two ways. Either the
+ size of the symbol is included in the section contents, or it
+ is not. We assume that the size is not included, and force
+ the rtype_to_howto function to adjust the addend as needed. */
+
+ if (sym != NULL && sym->n_scnum != 0)
+ addend = - sym->n_value;
+ else
+ addend = 0;
+
+
+ howto = coff_rtype_to_howto (input_bfd, input_section, rel, h,
+ sym, &addend);
+ if (howto == NULL)
+ return false;
+
+ /* The relocation_section function will skip pcrel_offset relocs
+ when doing a relocateable link. However, we want to convert
+ ARM26 to ARM26D relocs if possible. We return a fake howto in
+ this case without pcrel_offset set, and adjust the addend to
+ compensate. */
+ if (rel->r_type == ARM_26
+ && h != NULL
+ && info->relocateable
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section == input_section->output_section)
+ {
+ static reloc_howto_type fake_arm26_reloc =
+ HOWTO (ARM_26,
+ 2,
+ 2,
+ 24,
+ true,
+ 0,
+ complain_overflow_signed,
+ aoutarm_fix_pcrel_26 ,
+ "ARM_26",
+ false,
+ 0x00ffffff,
+ 0x00ffffff,
+ false);
+
+ addend -= rel->r_vaddr - input_section->vma;
+ howto = &fake_arm26_reloc;
+ }
+
+ /* If we are doing a relocateable link, then we can just ignore
+ a PC relative reloc that is pcrel_offset. It will already
+ have the correct value. If this is not a relocateable link,
+ then we should ignore the symbol value. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ {
+ if (info->relocateable)
+ continue;
+ if (sym != NULL && sym->n_scnum != 0)
+ addend += sym->n_value;
+ }
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ asection *sec;
+
+ if (symndx == -1)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value
+ - sec->vma);
+ }
+ }
+ else
+ {
+#if 1 /* THUMBEXTENSION */
+ /* We don't output the stubs if we are generating a
+ relocatable output file, since we may as well leave the
+ stub generation to the final linker pass. If we fail to
+ verify that the name is defined, we'll try to build stubs
+ for an undefined name... */
+ if (! info->relocateable
+ && ( h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection * h_sec = h->root.u.def.section;
+ const char * name = h->root.root.string;
+
+ /* h locates the symbol referenced in the reloc. */
+ h_val = (h->root.u.def.value
+ + h_sec->output_section->vma
+ + h_sec->output_offset);
+
+ if (howto->type == ARM_26)
+ {
+ if ( h->class == C_THUMBSTATFUNC
+ || h->class == C_THUMBEXTFUNC)
+ {
+ /* Arm code calling a Thumb function */
+ unsigned long int tmp;
+ long int my_offset;
+ asection * s;
+ long int ret_offset;
+ struct coff_link_hash_entry * myh;
+ struct coff_arm_link_hash_table * globals;
+
+ myh = find_arm_glue (info, name, input_bfd);
+ if (myh == NULL)
+ return false;
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ my_offset = myh->root.u.def.value;
+
+ s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ if ((my_offset & 0x01) == 0x01)
+ {
+ if (h_sec->owner != NULL
+ && INTERWORK_SET (h_sec->owner)
+ && ! INTERWORK_FLAG (h_sec->owner))
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%s(%s): warning: interworking not enabled."),
+ bfd_get_filename (h_sec->owner), name);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_(" first occurrence: %s: arm call to thumb"),
+ bfd_get_filename (input_bfd));
+ }
+
+ --my_offset;
+ myh->root.u.def.value = my_offset;
+
+ bfd_put_32 (output_bfd, a2t1_ldr_insn,
+ s->contents + my_offset);
+
+ bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
+ s->contents + my_offset + 4);
+
+ /* It's a thumb address. Add the low order bit. */
+ bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
+ s->contents + my_offset + 8);
+
+ if (info->base_file)
+ arm_emit_base_file_entry (info, output_bfd, s, A2T3_OFFSET);
+
+ }
+
+ BFD_ASSERT (my_offset <= globals->arm_glue_size);
+
+ tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
+ - input_section->vma);
+
+ tmp = tmp & 0xFF000000;
+
+ /* Somehow these are both 4 too far, so subtract 8. */
+ ret_offset =
+ s->output_offset
+ + my_offset
+ + s->output_section->vma
+ - (input_section->output_offset
+ + input_section->output_section->vma
+ + rel->r_vaddr)
+ - 8;
+
+ tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
+
+ bfd_put_32 (output_bfd, tmp, contents + rel->r_vaddr
+ - input_section->vma);
+
+ done = 1;
+ }
+ }
+
+ /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12 */
+ else if (howto->type == ARM_THUMB23)
+ {
+ if ( h->class == C_EXT
+ || h->class == C_STAT
+ || h->class == C_LABEL)
+ {
+ /* Thumb code calling an ARM function */
+ asection * s = 0;
+ long int my_offset;
+ unsigned long int tmp;
+ long int ret_offset;
+ struct coff_link_hash_entry * myh;
+ struct coff_arm_link_hash_table * globals;
+
+ myh = find_thumb_glue (info, name, input_bfd);
+ if (myh == NULL)
+ return false;
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ my_offset = myh->root.u.def.value;
+
+ s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
+ THUMB2ARM_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ if ((my_offset & 0x01) == 0x01)
+ {
+ if (h_sec->owner != NULL
+ && INTERWORK_SET (h_sec->owner)
+ && ! INTERWORK_FLAG (h_sec->owner)
+ && ! globals->support_old_code)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%s(%s): warning: interworking not enabled."),
+ bfd_get_filename (h_sec->owner), name);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_(" first occurrence: %s: thumb call to arm"),
+ bfd_get_filename (input_bfd));
+ _bfd_error_handler
+ (_(" consider relinking with --support-old-code enabled"));
+ }
+
+ -- my_offset;
+ myh->root.u.def.value = my_offset;
+
+ if (globals->support_old_code)
+ {
+ bfd_put_16 (output_bfd, t2a1_push_insn,
+ s->contents + my_offset);
+
+ bfd_put_16 (output_bfd, t2a2_ldr_insn,
+ s->contents + my_offset + 2);
+
+ bfd_put_16 (output_bfd, t2a3_mov_insn,
+ s->contents + my_offset + 4);
+
+ bfd_put_16 (output_bfd, t2a4_bx_insn,
+ s->contents + my_offset + 6);
+
+ bfd_put_32 (output_bfd, t2a5_pop_insn,
+ s->contents + my_offset + 8);
+
+ bfd_put_32 (output_bfd, t2a6_bx_insn,
+ s->contents + my_offset + 12);
+
+ /* Store the address of the function in the last word of the stub. */
+ bfd_put_32 (output_bfd, h_val,
+ s->contents + my_offset + 16);
+ }
+ else
+ {
+ bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
+ s->contents + my_offset);
+
+ bfd_put_16 (output_bfd, t2a2_noop_insn,
+ s->contents + my_offset + 2);
+
+ ret_offset =
+ ((bfd_signed_vma) h_val) /* Address of destination of the stub */
+ - ((bfd_signed_vma)
+ (s->output_offset /* Offset from the start of the current section to the start of the stubs. */
+ + my_offset /* Offset of the start of this stub from the start of the stubs. */
+ + s->output_section->vma) /* Address of the start of the current section. */
+ + 4 /* The branch instruction is 4 bytes into the stub. */
+ + 8); /* ARM branches work from the pc of the instruction + 8. */
+
+ bfd_put_32 (output_bfd,
+ t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
+ s->contents + my_offset + 4);
+
+ if (info->base_file)
+ arm_emit_base_file_entry (info, output_bfd, s, T2A3_OFFSET);
+ }
+ }
+
+ BFD_ASSERT (my_offset <= globals->thumb_glue_size);
+
+ /* Now go back and fix up the original BL insn to point
+ to here. */
+ ret_offset =
+ s->output_offset
+ + my_offset
+ - (input_section->output_offset
+ + rel->r_vaddr)
+ -4;
+
+ tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
+ - input_section->vma);
+
+ bfd_put_32 (output_bfd,
+ insert_thumb_branch (tmp, ret_offset),
+ contents + rel->r_vaddr
+ - input_section->vma);
+
+ if (info->base_file)
+ arm_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
+
+ done = 1;
+ }
+ }
+ }
+
+ /* If the relocation type and destination symbol does not
+ fall into one of the above categories, then we can just
+ perform a direct link. */
+
+ if (done)
+ rstat = bfd_reloc_ok;
+ else
+#endif /* THUMBEXTENSION */
+ if ( h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+
+ else if (! info->relocateable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ if (info->base_file)
+ {
+ /* Emit a reloc if the backend thinks it needs it. */
+ if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
+ arm_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
+ }
+
+#if 1 /* THUMBEXTENSION */
+ if (done)
+ rstat = bfd_reloc_ok;
+ /* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
+ else if (! info->relocateable
+ && howto->type == ARM_THUMB23)
+ {
+ /* This is pretty much a copy of what the default
+ _bfd_final_link_relocate and _bfd_relocate_contents
+ routines do to perform a relocation, with special
+ processing for the split addressing of the Thumb BL
+ instruction. Again, it would probably be simpler adding a
+ ThumbBRANCH23 specific macro expansion into the default
+ code. */
+
+ bfd_vma address = rel->r_vaddr - input_section->vma;
+
+ if (address > input_section->_raw_size)
+ rstat = bfd_reloc_outofrange;
+ else
+ {
+ bfd_vma relocation = val + addend;
+ int size = bfd_get_reloc_size (howto);
+ boolean overflow = false;
+ bfd_byte * location = contents + address;
+ bfd_vma x = bfd_get_32 (input_bfd, location);
+ bfd_vma src_mask = 0x007FFFFE;
+ bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+ bfd_vma add;
+ bfd_signed_vma signed_add;
+
+ BFD_ASSERT (size == 4);
+
+ /* howto->pc_relative should be TRUE for type 14 BRANCH23 */
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* howto->pcrel_offset should be TRUE for type 14 BRANCH23 */
+ relocation -= address;
+
+ /* No need to negate the relocation with BRANCH23. */
+ /* howto->complain_on_overflow == complain_overflow_signed for BRANCH23. */
+ /* howto->rightshift == 1 */
+ /* Drop unwanted bits from the value we are relocating to. */
+
+ check = relocation >> howto->rightshift;
+
+ /* If this is a signed value, the rightshift just dropped
+ leading 1 bits (assuming twos complement). */
+ if ((bfd_signed_vma) relocation >= 0)
+ signed_check = check;
+ else
+ signed_check = (check
+ | ((bfd_vma) - 1
+ & ~((bfd_vma) - 1 >> howto->rightshift)));
+
+ /* Get the value from the object file. */
+ if (bfd_big_endian (input_bfd))
+ {
+ add = (((x) & 0x07ff0000) >> 4) | (((x) & 0x7ff) << 1);
+ }
+ else
+ {
+ add = ((((x) & 0x7ff) << 12) | (((x) & 0x07ff0000) >> 15));
+ }
+
+ /* Get the value from the object file with an appropriate sign.
+ The expression involving howto->src_mask isolates the upper
+ bit of src_mask. If that bit is set in the value we are
+ adding, it is negative, and we subtract out that number times
+ two. If src_mask includes the highest possible bit, then we
+ can not get the upper bit, but that does not matter since
+ signed_add needs no adjustment to become negative in that
+ case. */
+
+ signed_add = add;
+
+ if ((add & (((~ src_mask) >> 1) & src_mask)) != 0)
+ signed_add -= (((~ src_mask) >> 1) & src_mask) << 1;
+
+ /* Add the value from the object file, shifted so that it is a
+ straight number. */
+ /* howto->bitpos == 0 */
+
+ signed_check += signed_add;
+ relocation += signed_add;
+
+ BFD_ASSERT (howto->complain_on_overflow == complain_overflow_signed);
+
+ /* Assumes two's complement. */
+ if ( signed_check > reloc_signed_max
+ || signed_check < reloc_signed_min)
+ overflow = true;
+
+ /* Put RELOCATION into the correct bits: */
+
+ if (bfd_big_endian (input_bfd))
+ {
+ relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
+ }
+ else
+ {
+ relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
+ }
+
+ /* Add RELOCATION to the correct bits of X: */
+ x = ((x & ~howto->dst_mask) | relocation);
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_32 (input_bfd, x, location);
+
+ rstat = overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+ }
+ }
+ else
+#endif /* THUMBEXTENSION */
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents,
+ rel->r_vaddr - input_section->vma,
+ val, addend);
+#if 1 /* THUMBEXTENSION */
+ /* FIXME:
+ Is this the best way to fix up thumb addresses? krk@cygnus.com
+ Probably not, but it works, and if it works it don't need fixing! nickc@cygnus.com */
+ /* Only perform this fix during the final link, not a relocatable link. nickc@cygnus.com */
+ if (! info->relocateable
+ && rel->r_type == ARM_32)
+ {
+ /* Determine if we need to set the bottom bit of a relocated address
+ because the address is the address of a Thumb code symbol. */
+
+ int patchit = false;
+
+ if (h != NULL
+ && ( h->class == C_THUMBSTATFUNC
+ || h->class == C_THUMBEXTFUNC))
+ {
+ patchit = true;
+ }
+ else if (sym != NULL
+ && sym->n_scnum > N_UNDEF)
+ {
+ /* No hash entry - use the symbol instead. */
+
+ if ( sym->n_sclass == C_THUMBSTATFUNC
+ || sym->n_sclass == C_THUMBEXTFUNC)
+ patchit = true;
+ }
+
+ if (patchit)
+ {
+ bfd_byte * location = contents + rel->r_vaddr - input_section->vma;
+ bfd_vma x = bfd_get_32 (input_bfd, location);
+
+ bfd_put_32 (input_bfd, x | 1, location);
+ }
+ }
+#endif /* THUMBEXTENSION */
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_outofrange:
+ (*_bfd_error_handler)
+ (_("%s: bad reloc address 0x%lx in section `%s'"),
+ bfd_get_filename (input_bfd),
+ (unsigned long) rel->r_vaddr,
+ bfd_get_section_name (input_bfd, input_section));
+ return false;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return false;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#ifndef COFF_WITH_PE
+boolean
+bfd_arm_allocate_interworking_sections (info)
+ struct bfd_link_info * info;
+{
+ asection * s;
+ bfd_byte * foo;
+ struct coff_arm_link_hash_table * globals;
+#if 0
+ static char test_char = '1';
+#endif
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+
+ if (globals->arm_glue_size != 0)
+ {
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ foo = (bfd_byte *) bfd_alloc
+ (globals->bfd_of_glue_owner, globals->arm_glue_size);
+#if 0
+ memset (foo, test_char, globals->arm_glue_size);
+#endif
+
+ s->_raw_size = s->_cooked_size = globals->arm_glue_size;
+ s->contents = foo;
+ }
+
+ if (globals->thumb_glue_size != 0)
+ {
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ foo = (bfd_byte *) bfd_alloc
+ (globals->bfd_of_glue_owner, globals->thumb_glue_size);
+#if 0
+ memset (foo, test_char, globals->thumb_glue_size);
+#endif
+
+ s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
+ s->contents = foo;
+ }
+
+ return true;
+}
+
+static void
+record_arm_to_thumb_glue (info, h)
+ struct bfd_link_info * info;
+ struct coff_link_hash_entry * h;
+{
+ const char * name = h->root.root.string;
+ register asection * s;
+ char * tmp_name;
+ struct coff_link_hash_entry * myh;
+ struct coff_arm_link_hash_table * globals;
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ tmp_name = ((char *)
+ bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
+
+ myh = coff_link_hash_lookup
+ (coff_hash_table (info), tmp_name, false, false, true);
+
+ if (myh != NULL)
+ {
+ free (tmp_name);
+ return; /* we've already seen this guy */
+ }
+
+ /* The only trick here is using globals->arm_glue_size as the value. Even
+ though the section isn't allocated yet, this is where we will be putting
+ it. */
+
+ bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL,
+ s, globals->arm_glue_size + 1,
+ NULL, true, false,
+ (struct bfd_link_hash_entry **) & myh);
+
+ free (tmp_name);
+
+ globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
+
+ return;
+}
+
+static void
+record_thumb_to_arm_glue (info, h)
+ struct bfd_link_info * info;
+ struct coff_link_hash_entry * h;
+{
+ const char * name = h->root.root.string;
+ register asection * s;
+ char * tmp_name;
+ struct coff_link_hash_entry * myh;
+ struct coff_arm_link_hash_table * globals;
+
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ tmp_name = (char *) bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
+
+ myh = coff_link_hash_lookup
+ (coff_hash_table (info), tmp_name, false, false, true);
+
+ if (myh != NULL)
+ {
+ free (tmp_name);
+ return; /* we've already seen this guy */
+ }
+
+ bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, globals->thumb_glue_size + 1,
+ NULL, true, false,
+ (struct bfd_link_hash_entry **) & myh);
+
+ /* If we mark it 'thumb', the disassembler will do a better job. */
+ myh->class = C_THUMBEXTFUNC;
+
+ free (tmp_name);
+
+ /* Allocate another symbol to mark where we switch to arm mode. */
+
+#define CHANGE_TO_ARM "__%s_change_to_arm"
+#define BACK_FROM_ARM "__%s_back_from_arm"
+
+ tmp_name = (char *) bfd_malloc (strlen (name) + strlen (CHANGE_TO_ARM) + 1);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
+
+ myh = NULL;
+
+ bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_LOCAL, s, globals->thumb_glue_size
+ + (globals->support_old_code ? 8 : 4),
+ NULL, true, false,
+ (struct bfd_link_hash_entry **) & myh);
+
+ free (tmp_name);
+
+ globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
+
+ return;
+}
+
+/* Select a BFD to be used to hold the sections used by the glue code.
+ This function is called from the linker scripts in ld/emultempl/
+ {armcoff/pe}.em */
+boolean
+bfd_arm_get_bfd_for_interworking (abfd, info)
+ bfd * abfd;
+ struct bfd_link_info * info;
+{
+ struct coff_arm_link_hash_table * globals;
+ flagword flags;
+ asection * sec;
+
+ /* If we are only performing a partial link do not bother
+ getting a bfd to hold the glue. */
+ if (info->relocateable)
+ return true;
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+
+ if (globals->bfd_of_glue_owner != NULL)
+ return true;
+
+ sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
+
+ if (sec == NULL)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
+
+ if (sec == NULL
+ || ! bfd_set_section_flags (abfd, sec, flags)
+ || ! bfd_set_section_alignment (abfd, sec, 2))
+ return false;
+ }
+
+ sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
+
+ if (sec == NULL)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
+
+ if (sec == NULL
+ || ! bfd_set_section_flags (abfd, sec, flags)
+ || ! bfd_set_section_alignment (abfd, sec, 2))
+ return false;
+ }
+
+ /* Save the bfd for later use. */
+ globals->bfd_of_glue_owner = abfd;
+
+ return true;
+}
+
+boolean
+bfd_arm_process_before_allocation (abfd, info, support_old_code)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ int support_old_code;
+{
+ asection * sec;
+ struct coff_arm_link_hash_table * globals;
+
+ /* If we are only performing a partial link do not bother
+ to construct any glue. */
+ if (info->relocateable)
+ return true;
+
+ /* Here we have a bfd that is to be included on the link. We have a hook
+ to do reloc rummaging, before section sizes are nailed down. */
+
+ _bfd_coff_get_external_symbols (abfd);
+
+ globals = coff_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ globals->support_old_code = support_old_code;
+
+ /* Rummage around all the relocs and map the glue vectors. */
+ sec = abfd->sections;
+
+ if (sec == NULL)
+ return true;
+
+ for (; sec != NULL; sec = sec->next)
+ {
+ struct internal_reloc * i;
+ struct internal_reloc * rel;
+
+ if (sec->reloc_count == 0)
+ continue;
+
+ /* Load the relocs. */
+ /* FIXME: there may be a storage leak here. */
+
+ i = _bfd_coff_read_internal_relocs (abfd, sec, 1, 0, 0, 0);
+
+ BFD_ASSERT (i != 0);
+
+ for (rel = i; rel < i + sec->reloc_count; ++rel)
+ {
+ unsigned short r_type = rel->r_type;
+ long symndx;
+ struct coff_link_hash_entry * h;
+
+ symndx = rel->r_symndx;
+
+ /* If the relocation is not against a symbol it cannot concern us. */
+ if (symndx == -1)
+ continue;
+
+ h = obj_coff_sym_hashes (abfd)[symndx];
+
+ /* If the relocation is against a static symbol it must be within
+ the current section and so cannot be a cross ARM/Thumb relocation. */
+ if (h == NULL)
+ continue;
+
+ switch (r_type)
+ {
+ case ARM_26:
+ /* This one is a call from arm code. We need to look up
+ the target of the call. If it is a thumb target, we
+ insert glue. */
+
+ if (h->class == C_THUMBEXTFUNC)
+ record_arm_to_thumb_glue (info, h);
+ break;
+
+ case ARM_THUMB23:
+ /* This one is a call from thumb code. We used to look
+ for ARM_THUMB9 and ARM_THUMB12 as well. We need to look
+ up the target of the call. If it is an arm target, we
+ insert glue. If the symbol does not exist it will be
+ given a class of C_EXT and so we will generate a stub
+ for it. This is not really a problem, since the link
+ is doomed anyway. */
+
+ switch (h->class)
+ {
+ case C_EXT:
+ case C_STAT:
+ case C_LABEL:
+ record_thumb_to_arm_glue (info, h);
+ break;
+ default:
+ ;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+#endif /* ! COFF_WITH_PE */
+
+#define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
+#define coff_relocate_section coff_arm_relocate_section
+#define coff_bfd_is_local_label_name coff_arm_is_local_label_name
+#define coff_adjust_symndx coff_arm_adjust_symndx
+#define coff_link_output_has_begun coff_arm_link_output_has_begun
+#define coff_final_link_postscript coff_arm_final_link_postscript
+#define coff_bfd_merge_private_bfd_data coff_arm_merge_private_bfd_data
+#define coff_bfd_print_private_bfd_data coff_arm_print_private_bfd_data
+#define coff_bfd_set_private_flags _bfd_coff_arm_set_private_flags
+#define coff_bfd_copy_private_bfd_data coff_arm_copy_private_bfd_data
+#define coff_bfd_link_hash_table_create coff_arm_link_hash_table_create
+
+
+/* When doing a relocateable link, we want to convert ARM26 relocs
+ into ARM26D relocs. */
+
+static boolean
+coff_arm_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
+ bfd *obfd;
+ struct bfd_link_info *info;
+ bfd *ibfd;
+ asection *sec;
+ struct internal_reloc *irel;
+ boolean *adjustedp;
+{
+ if (irel->r_type == 3)
+ {
+ struct coff_link_hash_entry *h;
+
+ h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section == sec->output_section)
+ irel->r_type = 7;
+ }
+ *adjustedp = false;
+ return true;
+}
+
+/* Called when merging the private data areas of two BFDs.
+ This is important as it allows us to detect if we are
+ attempting to merge binaries compiled for different ARM
+ targets, eg different CPUs or differents APCS's. */
+
+static boolean
+coff_arm_merge_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ BFD_ASSERT (ibfd != NULL && obfd != NULL);
+
+ if (ibfd == obfd)
+ return true;
+
+ /* If the two formats are different we cannot merge anything.
+ This is not an error, since it is permissable to change the
+ input and output formats. */
+ if ( ibfd->xvec->flavour != bfd_target_coff_flavour
+ || obfd->xvec->flavour != bfd_target_coff_flavour)
+ return true;
+
+ /* Verify that the APCS is the same for the two BFDs */
+ if (APCS_SET (ibfd))
+ {
+ if (APCS_SET (obfd))
+ {
+ /* If the src and dest have different APCS flag bits set, fail. */
+ if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
+ {
+ _bfd_error_handler
+ /* xgettext: c-format */
+ (_("%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"),
+ bfd_get_filename (ibfd), APCS_26_FLAG (ibfd) ? 26 : 32,
+ bfd_get_filename (obfd), APCS_26_FLAG (obfd) ? 26 : 32
+ );
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
+ {
+ const char *msg;
+
+ if (APCS_FLOAT_FLAG (ibfd))
+ /* xgettext: c-format */
+ msg = _("%s: ERROR: passes floats in float registers whereas target %s uses integer registers");
+ else
+ /* xgettext: c-format */
+ msg = _("%s: ERROR: passes floats in integer registers whereas target %s uses float registers");
+
+ _bfd_error_handler (msg, bfd_get_filename (ibfd),
+ bfd_get_filename (obfd));
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
+ {
+ const char * msg;
+
+ if (PIC_FLAG (ibfd))
+ /* xgettext: c-format */
+ msg = _("%s: ERROR: compiled as position independent code, whereas target %s is absolute position");
+ else
+ /* xgettext: c-format */
+ msg = _("%s: ERROR: compiled as absolute position code, whereas target %s is position independent");
+ _bfd_error_handler (msg, bfd_get_filename (ibfd),
+ bfd_get_filename (obfd));
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+ }
+ else
+ {
+ SET_APCS_FLAGS (obfd, APCS_26_FLAG (ibfd) | APCS_FLOAT_FLAG (ibfd) | PIC_FLAG (ibfd));
+
+ /* Set up the arch and fields as well as these are probably wrong. */
+ bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
+ }
+ }
+
+ /* Check the interworking support. */
+ if (INTERWORK_SET (ibfd))
+ {
+ if (INTERWORK_SET (obfd))
+ {
+ /* If the src and dest differ in their interworking issue a warning. */
+ if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
+ {
+ const char * msg;
+
+ if (INTERWORK_FLAG (ibfd))
+ /* xgettext: c-format */
+ msg = _("Warning: input file %s supports interworking, whereas %s does not.");
+ else
+ /* xgettext: c-format */
+ msg = _("Warning: input file %s does not support interworking, whereas %s does.");
+
+ _bfd_error_handler (msg, bfd_get_filename (ibfd),
+ bfd_get_filename (obfd));
+ }
+ }
+ else
+ {
+ SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
+ }
+ }
+
+ return true;
+}
+
+
+/* Display the flags field. */
+
+static boolean
+coff_arm_print_private_bfd_data (abfd, ptr)
+ bfd * abfd;
+ PTR ptr;
+{
+ FILE * file = (FILE *) ptr;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* xgettext:c-format */
+ fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
+
+ if (APCS_SET (abfd))
+ {
+ /* xgettext: APCS is ARM Prodecure Call Standard, it should not be translated. */
+ fprintf (file, " [APCS-%d]", APCS_26_FLAG (abfd) ? 26 : 32);
+
+ if (APCS_FLOAT_FLAG (abfd))
+ fprintf (file, _(" [floats passed in float registers]"));
+ else
+ fprintf (file, _(" [floats passed in integer registers]"));
+
+ if (PIC_FLAG (abfd))
+ fprintf (file, _(" [position independent]"));
+ else
+ fprintf (file, _(" [absolute position]"));
+ }
+
+ if (! INTERWORK_SET (abfd))
+ fprintf (file, _(" [interworking flag not initialised]"));
+ else if (INTERWORK_FLAG (abfd))
+ fprintf (file, _(" [interworking supported]"));
+ else
+ fprintf (file, _(" [interworking not supported]"));
+
+ fputc ('\n', file);
+
+ return true;
+}
+
+
+/* Copies the given flags into the coff_tdata.flags field.
+ Typically these flags come from the f_flags[] field of
+ the COFF filehdr structure, which contains important,
+ target specific information.
+ Note: Although this function is static, it is explicitly
+ called from both coffcode.h and peicode.h. */
+
+static boolean
+_bfd_coff_arm_set_private_flags (abfd, flags)
+ bfd * abfd;
+ flagword flags;
+{
+ flagword flag;
+
+ BFD_ASSERT (abfd != NULL);
+
+ flag = (flags & F_APCS26) ? F_APCS_26 : 0;
+
+ /* Make sure that the APCS field has not been initialised to the opposite
+ value. */
+ if (APCS_SET (abfd)
+ && ( (APCS_26_FLAG (abfd) != flag)
+ || (APCS_FLOAT_FLAG (abfd) != (flags & F_APCS_FLOAT))
+ || (PIC_FLAG (abfd) != (flags & F_PIC_INT ? F_PIC : 0))
+ ))
+ return false;
+
+ flag |= (flags & (F_APCS_FLOAT | F_PIC));
+
+ SET_APCS_FLAGS (abfd, flag);
+
+ flag = (flags & F_INTERWORK);
+
+ /* If the BFD has already had its interworking flag set, but it
+ is different from the value that we have been asked to set,
+ then assume that that merged code will not support interworking
+ and set the flag accordingly. */
+ if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
+ {
+ if (flag)
+ /* xgettext: c-format */
+ _bfd_error_handler (_("Warning: Not setting interworking flag of %s, since it has already been specified as non-interworking"),
+ bfd_get_filename (abfd));
+ else
+ /* xgettext: c-format */
+ _bfd_error_handler (_("Warning: Clearing the interworking flag of %s due to outside request"),
+ bfd_get_filename (abfd));
+ flag = 0;
+ }
+
+ SET_INTERWORK_FLAG (abfd, flag);
+
+ return true;
+}
+
+
+/* Copy the important parts of the target specific data
+ from one instance of a BFD to another. */
+
+static boolean
+coff_arm_copy_private_bfd_data (src, dest)
+ bfd * src;
+ bfd * dest;
+{
+ BFD_ASSERT (src != NULL && dest != NULL);
+
+ if (src == dest)
+ return true;
+
+ /* If the destination is not in the same format as the source, do not do
+ the copy. */
+ if (src->xvec != dest->xvec)
+ return true;
+
+ /* copy the flags field */
+ if (APCS_SET (src))
+ {
+ if (APCS_SET (dest))
+ {
+ /* If the src and dest have different APCS flag bits set, fail. */
+ if (APCS_26_FLAG (dest) != APCS_26_FLAG (src))
+ return false;
+
+ if (APCS_FLOAT_FLAG (dest) != APCS_FLOAT_FLAG (src))
+ return false;
+
+ if (PIC_FLAG (dest) != PIC_FLAG (src))
+ return false;
+ }
+ else
+ SET_APCS_FLAGS (dest, APCS_26_FLAG (src) | APCS_FLOAT_FLAG (src)
+ | PIC_FLAG (src));
+ }
+
+ if (INTERWORK_SET (src))
+ {
+ if (INTERWORK_SET (dest))
+ {
+ /* If the src and dest have different interworking flags then turn
+ off the interworking bit. */
+ if (INTERWORK_FLAG (dest) != INTERWORK_FLAG (src))
+ {
+ if (INTERWORK_FLAG (dest))
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (("Warning: Clearing the interworking bit of %s, because the non-interworking code in %s has been copied into it"),
+ bfd_get_filename (dest),
+ bfd_get_filename (src));
+ }
+
+ SET_INTERWORK_FLAG (dest, 0);
+ }
+ }
+ else
+ {
+ SET_INTERWORK_FLAG (dest, INTERWORK_FLAG (src));
+ }
+ }
+
+ return true;
+}
+
+/* Note: the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
+ *must* match the definitions in gcc/config/arm/coff.h and semi.h */
+#define LOCAL_LABEL_PREFIX "."
+#ifndef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX "_"
+#endif
+
+static boolean
+coff_arm_is_local_label_name (abfd, name)
+ bfd * abfd;
+ const char * name;
+{
+#ifdef LOCAL_LABEL_PREFIX
+ /* If there is a prefix for local labels then look for this.
+ If the prefix exists, but it is empty, then ignore the test. */
+
+ if (LOCAL_LABEL_PREFIX[0] != 0)
+ {
+ if (strncmp (name, LOCAL_LABEL_PREFIX, strlen (LOCAL_LABEL_PREFIX)) == 0)
+ return true;
+ }
+#endif
+#ifdef USER_LABEL_PREFIX
+ if (USER_LABEL_PREFIX[0] != 0)
+ {
+ if (strncmp (name, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)) == 0)
+ return false;
+ }
+#endif
+
+ /* devo/gcc/config/dbxcoff.h defines ASM_OUTPUT_SOURCE_LINE to generate
+ local line numbers as .LM<number>, so treat these as local. */
+
+ switch (name[0])
+ {
+ case 'L': return true;
+ case '.': return (name[1] == 'L' && name[2] == 'M') ? true : false;
+ default: return false; /* Cannot make our minds up - default to
+ false so that it will not be stripped
+ by accident. */
+ }
+}
+
+/* This piece of machinery exists only to guarantee that the bfd that holds
+ the glue section is written last.
+
+ This does depend on bfd_make_section attaching a new section to the
+ end of the section list for the bfd.
+
+ krk@cygnus.com */
+
+static boolean
+coff_arm_link_output_has_begun (sub, info)
+ bfd * sub;
+ struct coff_final_link_info * info;
+{
+ return (sub->output_has_begun
+ || sub == coff_arm_hash_table (info->info)->bfd_of_glue_owner);
+}
+
+static boolean
+coff_arm_final_link_postscript (abfd, pfinfo)
+ bfd * abfd;
+ struct coff_final_link_info * pfinfo;
+{
+ struct coff_arm_link_hash_table * globals;
+
+ globals = coff_arm_hash_table (pfinfo->info);
+
+ BFD_ASSERT (globals != NULL);
+
+ if (globals->bfd_of_glue_owner != NULL)
+ {
+ if (! _bfd_coff_link_input_bfd (pfinfo, globals->bfd_of_glue_owner))
+ return false;
+
+ globals->bfd_of_glue_owner->output_has_begun = true;
+ }
+
+ return true;
+}
+
+#if 0
+#define coff_SWAP_sym_in arm_bfd_coff_swap_sym_in
+
+static void coff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
+
+/* Sepcial version of symbol swapper, used to grab a bfd
+ onto which the glue sections can be attached. */
+static void
+arm_bfd_coff_swap_sym_in (abfd, ext1, in1)
+ bfd * abfd;
+ PTR ext1;
+ PTR in1;
+{
+ flagword flags;
+ register asection * s;
+
+ /* Do the normal swap in. */
+ coff_swap_sym_in (abfd, ext1, in1);
+
+ if (bfd_of_glue_owner != NULL) /* we already have a toc, so go home */
+ return;
+
+ /* Save the bfd for later allocation. */
+ bfd_of_glue_owner = abfd;
+
+ s = bfd_get_section_by_name (bfd_of_glue_owner ,
+ ARM2THUMB_GLUE_SECTION_NAME);
+
+ if (s == NULL)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
+
+ s = bfd_make_section (bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+
+ if (s == NULL
+ || !bfd_set_section_flags (bfd_of_glue_owner, s, flags)
+ || !bfd_set_section_alignment (bfd_of_glue_owner, s, 2))
+ {
+ /* FIXME: set appropriate bfd error */
+ abort();
+ }
+ }
+
+ s = bfd_get_section_by_name (bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
+
+ if (s == NULL)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
+
+ s = bfd_make_section (bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
+
+ if (s == NULL
+ || !bfd_set_section_flags (bfd_of_glue_owner, s, flags)
+ || !bfd_set_section_alignment (bfd_of_glue_owner, s, 2))
+ {
+ /* FIXME: set appropriate bfd error krk@cygnus.com */
+ abort();
+ }
+ }
+
+ return;
+}
+#endif
+
+#include "coffcode.h"
+
+const bfd_target
+#ifdef TARGET_LITTLE_SYM
+TARGET_LITTLE_SYM =
+#else
+armcoff_little_vec =
+#endif
+{
+#ifdef TARGET_LITTLE_NAME
+ TARGET_LITTLE_NAME,
+#else
+ "coff-arm-little",
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+#ifndef COFF_WITH_PE
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+#ifdef TARGET_UNDERSCORE
+ TARGET_UNDERSCORE, /* leading underscore */
+#else
+ 0, /* leading underscore */
+#endif
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, coff_object_p},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) & bfd_coff_std_swap_table,
+};
+
+const bfd_target
+#ifdef TARGET_BIG_SYM
+TARGET_BIG_SYM =
+#else
+armcoff_big_vec =
+#endif
+{
+#ifdef TARGET_BIG_NAME
+ TARGET_BIG_NAME,
+#else
+ "coff-arm-big",
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+#ifndef COFF_WITH_PE
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+#ifdef TARGET_UNDERSCORE
+ TARGET_UNDERSCORE, /* leading underscore */
+#else
+ 0, /* leading underscore */
+#endif
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, coff_object_p},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) & bfd_coff_std_swap_table,
+};
diff --git a/bfd/coff-aux.c b/bfd/coff-aux.c
new file mode 100644
index 00000000000..6966392a33b
--- /dev/null
+++ b/bfd/coff-aux.c
@@ -0,0 +1,135 @@
+/* BFD back-end for Apple M68K COFF A/UX 3.x files.
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+ Written by Richard Henderson <rth@tamu.edu>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM m68kaux_coff_vec
+#define TARGET_NAME "coff-m68k-aux"
+
+#ifndef TARG_AUX
+#define TARG_AUX
+#endif
+
+#define COFF_LONG_FILENAMES
+
+/* 4k pages */
+#define COFF_PAGE_SIZE 0x1000
+
+/* On AUX, a STYP_NOLOAD|STYP_BSS section is part of a shared library. */
+#define BSS_NOLOAD_IS_SHARED_LIBRARY
+
+#define STATIC_RELOCS
+
+#define COFF_COMMON_ADDEND
+
+#include "bfd.h"
+#include "sysdep.h"
+
+static boolean coff_m68k_aux_link_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword,
+ asection *, bfd_vma, const char *, boolean, boolean,
+ struct bfd_link_hash_entry **));
+
+#define coff_link_add_one_symbol coff_m68k_aux_link_add_one_symbol
+
+#include "coff/aux-coff.h" /* override coff/internal.h and coff/m68k.h */
+#include "coff-m68k.c"
+
+/* We need non-absolute symbols to override absolute symbols. This
+ mirrors Apple's "solution" to let a static library symbol override
+ a shared library symbol. On the whole not a good thing, given how
+ shared libraries work here, but can work if you are careful with
+ what you include in the shared object. */
+
+static boolean
+coff_m68k_aux_link_add_one_symbol (info, abfd, name, flags, section, value,
+ string, copy, collect, hashp)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ const char *string;
+ boolean copy;
+ boolean collect;
+ struct bfd_link_hash_entry **hashp;
+{
+ struct bfd_link_hash_entry *h;
+
+ if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0 &&
+ !bfd_is_und_section (section) &&
+ !bfd_is_com_section (section))
+ {
+ /* The new symbol is a definition or an indirect definition */
+
+ /* This bit copied from linker.c */
+ if (hashp != NULL && *hashp != NULL)
+ {
+ h = *hashp;
+ BFD_ASSERT (strcmp (h->root.string, name) == 0);
+ }
+ else
+ {
+ h = bfd_link_hash_lookup (info->hash, name, true, copy, false);
+ if (h == NULL)
+ {
+ if (hashp != NULL)
+ *hashp = NULL;
+ return false;
+ }
+ }
+
+ if (info->notice_hash != (struct bfd_hash_table *) NULL
+ && (bfd_hash_lookup (info->notice_hash, name, false, false)
+ != (struct bfd_hash_entry *) NULL))
+ {
+ if (! (*info->callbacks->notice) (info, name, abfd, section, value))
+ return false;
+ }
+
+ if (hashp != (struct bfd_link_hash_entry **) NULL)
+ *hashp = h;
+ /* end duplication from linker.c */
+
+ if (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_indirect)
+ {
+ asection *msec;
+
+ if (h->type == bfd_link_hash_defined)
+ msec = h->u.def.section;
+ else
+ msec = bfd_ind_section_ptr;
+
+ if (bfd_is_abs_section (msec) && !bfd_is_abs_section (section))
+ {
+ h->u.def.section = section;
+ h->u.def.value = value;
+ return true;
+ }
+ else if (bfd_is_abs_section (section) && !bfd_is_abs_section (msec))
+ return true;
+ }
+ }
+
+ /* If we didn't exit early, finish processing in the generic routine */
+ return _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
+ value, string, copy, collect,
+ hashp);
+}
diff --git a/bfd/coff-go32.c b/bfd/coff-go32.c
new file mode 100644
index 00000000000..be4adb24f52
--- /dev/null
+++ b/bfd/coff-go32.c
@@ -0,0 +1,25 @@
+/* BFD back-end for Intel 386 COFF files (go32 variant).
+ Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Written by DJ Delorie.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM go32coff_vec
+#define TARGET_NAME "coff-go32"
+#define TARGET_UNDERSCORE '_'
+
+#include "coff-i386.c"
diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c
new file mode 100644
index 00000000000..74a4ec3962a
--- /dev/null
+++ b/bfd/coff-h8300.c
@@ -0,0 +1,1388 @@
+/* BFD back-end for Hitachi H8/300 COFF binaries.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Steve Chamberlain, <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "coff/h8300.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
+
+/* We derive a hash table from the basic BFD hash table to
+ hold entries in the function vector. Aside from the
+ info stored by the basic hash table, we need the offset
+ of a particular entry within the hash table as well as
+ the offset where we'll add the next entry. */
+
+struct funcvec_hash_entry
+{
+ /* The basic hash table entry. */
+ struct bfd_hash_entry root;
+
+ /* The offset within the vectors section where
+ this entry lives. */
+ bfd_vma offset;
+};
+
+struct funcvec_hash_table
+{
+ /* The basic hash table. */
+ struct bfd_hash_table root;
+
+ bfd *abfd;
+
+ /* Offset at which we'll add the next entry. */
+ unsigned int offset;
+};
+
+static struct bfd_hash_entry *
+funcvec_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+static boolean
+funcvec_hash_table_init
+ PARAMS ((struct funcvec_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *))));
+
+/* To lookup a value in the function vector hash table. */
+#define funcvec_hash_lookup(table, string, create, copy) \
+ ((struct funcvec_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* The derived h8300 COFF linker table. Note it's derived from
+ the generic linker hash table, not the COFF backend linker hash
+ table! We use this to attach additional data structures we
+ need while linking on the h8300. */
+struct h8300_coff_link_hash_table
+{
+ /* The main hash table. */
+ struct generic_link_hash_table root;
+
+ /* Section for the vectors table. This gets attached to a
+ random input bfd, we keep it here for easy access. */
+ asection *vectors_sec;
+
+ /* Hash table of the functions we need to enter into the function
+ vector. */
+ struct funcvec_hash_table *funcvec_hash_table;
+};
+
+static struct bfd_link_hash_table *h8300_coff_link_hash_table_create
+ PARAMS ((bfd *));
+
+/* Get the H8/300 COFF linker hash table from a link_info structure. */
+
+#define h8300_coff_hash_table(p) \
+ ((struct h8300_coff_link_hash_table *) ((coff_hash_table (p))))
+
+/* Initialize fields within a funcvec hash table entry. Called whenever
+ a new entry is added to the funcvec hash table. */
+
+static struct bfd_hash_entry *
+funcvec_hash_newfunc (entry, gen_table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *gen_table;
+ const char *string;
+{
+ struct funcvec_hash_entry *ret;
+ struct funcvec_hash_table *table;
+
+ ret = (struct funcvec_hash_entry *) entry;
+ table = (struct funcvec_hash_table *) gen_table;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct funcvec_hash_entry *)
+ bfd_hash_allocate (gen_table,
+ sizeof (struct funcvec_hash_entry)));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct funcvec_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, gen_table, string));
+
+ if (ret == NULL)
+ return NULL;
+
+ /* Note where this entry will reside in the function vector table. */
+ ret->offset = table->offset;
+
+ /* Bump the offset at which we store entries in the function
+ vector. We'd like to bump up the size of the vectors section,
+ but it's not easily available here. */
+ if (bfd_get_mach (table->abfd) == bfd_mach_h8300)
+ table->offset += 2;
+ else if (bfd_get_mach (table->abfd) == bfd_mach_h8300h
+ || bfd_get_mach (table->abfd) == bfd_mach_h8300s)
+ table->offset += 4;
+ else
+ return NULL;
+
+ /* Everything went OK. */
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize the function vector hash table. */
+
+static boolean
+funcvec_hash_table_init (table, abfd, newfunc)
+ struct funcvec_hash_table *table;
+ bfd *abfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ /* Initialize our local fields, then call the generic initialization
+ routine. */
+ table->offset = 0;
+ table->abfd = abfd;
+ return (bfd_hash_table_init (&table->root, newfunc));
+}
+
+/* Create the derived linker hash table. We use a derived hash table
+ basically to hold "static" information during an h8/300 coff link
+ without using static variables. */
+
+static struct bfd_link_hash_table *
+h8300_coff_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct h8300_coff_link_hash_table *ret;
+ ret = ((struct h8300_coff_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct h8300_coff_link_hash_table)));
+ if (ret == NULL)
+ return NULL;
+ if (!_bfd_link_hash_table_init (&ret->root.root, abfd, _bfd_generic_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ /* Initialize our data. */
+ ret->vectors_sec = NULL;
+ ret->funcvec_hash_table = NULL;
+
+ /* OK. Everything's intialized, return the base pointer. */
+ return &ret->root.root;
+}
+
+/* special handling for H8/300 relocs.
+ We only come here for pcrel stuff and return normally if not an -r link.
+ When doing -r, we can't do any arithmetic for the pcrel stuff, because
+ the code in reloc.c assumes that we can manipulate the targets of
+ the pcrel branches. This isn't so, since the H8/300 can do relaxing,
+ which means that the gap after the instruction may not be enough to
+ contain the offset required for the branch, so we have to use the only
+ the addend until the final link */
+
+static bfd_reloc_status_type
+special (abfd, reloc_entry, symbol, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type howto_table[] =
+{
+ HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8", false, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16", false, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "32", false, 0xffffffff, 0xffffffff, false),
+ HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8", false, 0x000000ff, 0x000000ff, true),
+ HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, special, "DISP16", false, 0x0000ffff, 0x0000ffff, true),
+ HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, special, "DISP32", false, 0xffffffff, 0xffffffff, true),
+ HOWTO (R_MOV16B1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:16", false, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_MOV16B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:16", false, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/pcrel", false, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_JMPL1, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "24/pcrell", false, 0x00ffffff, 0x00ffffff, false),
+ HOWTO (R_JMPL2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pc8/24", false, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_MOV24B1, 0, 1, 32, false, 0, complain_overflow_bitfield, special, "relaxable mov.b:24", false, 0xffffffff, 0xffffffff, false),
+ HOWTO (R_MOV24B2, 0, 1, 8, false, 0, complain_overflow_bitfield, special, "relaxed mov.b:24", false, 0x0000ffff, 0x0000ffff, false),
+
+ /* An indirect reference to a function. This causes the function's address
+ to be added to the function vector in lo-mem and puts the address of
+ the function vector's entry in the jsr instruction. */
+ HOWTO (R_MEM_INDIRECT, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8/indirect", false, 0x000000ff, 0x000000ff, false),
+
+ /* Internal reloc for relaxing. This is created when a 16bit pc-relative
+ branch is turned into an 8bit pc-relative branch. */
+ HOWTO (R_PCRWORD_B, 0, 0, 8, true, 0, complain_overflow_bitfield, special, "relaxed bCC:16", false, 0x000000ff, 0x000000ff, false),
+
+ HOWTO (R_MOVL1, 0, 2, 32, false, 0, complain_overflow_bitfield,special, "32/24 relaxable move", false, 0xffffffff, 0xffffffff, false),
+
+ HOWTO (R_MOVL2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "32/24 relaxed move", false, 0x0000ffff, 0x0000ffff, false),
+
+ HOWTO (R_BCC_INV, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8 inverted", false, 0x000000ff, 0x000000ff, true),
+
+ HOWTO (R_JMP_DEL, 0, 0, 8, true, 0, complain_overflow_signed, special, "Deleted jump", false, 0x000000ff, 0x000000ff, true),
+};
+
+
+/* Turn a howto into a reloc number */
+
+#define SELECT_RELOC(x,howto) \
+ { x.r_type = select_reloc(howto); }
+
+#define BADMAG(x) (H8300BADMAG(x) && H8300HBADMAG(x) && H8300SBADMAG(x))
+#define H8300 1 /* Customize coffcode.h */
+#define __A_MAGIC_SET__
+
+
+
+/* Code to swap in the reloc */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
+ dst->r_stuff[0] = 'S'; \
+ dst->r_stuff[1] = 'C';
+
+
+static int
+select_reloc (howto)
+ reloc_howto_type *howto;
+{
+ return howto->type;
+}
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table
+ */
+
+static void
+rtype2howto (internal, dst)
+ arelent *internal;
+ struct internal_reloc *dst;
+{
+ switch (dst->r_type)
+ {
+ case R_RELBYTE:
+ internal->howto = howto_table + 0;
+ break;
+ case R_RELWORD:
+ internal->howto = howto_table + 1;
+ break;
+ case R_RELLONG:
+ internal->howto = howto_table + 2;
+ break;
+ case R_PCRBYTE:
+ internal->howto = howto_table + 3;
+ break;
+ case R_PCRWORD:
+ internal->howto = howto_table + 4;
+ break;
+ case R_PCRLONG:
+ internal->howto = howto_table + 5;
+ break;
+ case R_MOV16B1:
+ internal->howto = howto_table + 6;
+ break;
+ case R_MOV16B2:
+ internal->howto = howto_table + 7;
+ break;
+ case R_JMP1:
+ internal->howto = howto_table + 8;
+ break;
+ case R_JMP2:
+ internal->howto = howto_table + 9;
+ break;
+ case R_JMPL1:
+ internal->howto = howto_table + 10;
+ break;
+ case R_JMPL2:
+ internal->howto = howto_table + 11;
+ break;
+ case R_MOV24B1:
+ internal->howto = howto_table + 12;
+ break;
+ case R_MOV24B2:
+ internal->howto = howto_table + 13;
+ break;
+ case R_MEM_INDIRECT:
+ internal->howto = howto_table + 14;
+ break;
+ case R_PCRWORD_B:
+ internal->howto = howto_table + 15;
+ break;
+ case R_MOVL1:
+ internal->howto = howto_table + 16;
+ break;
+ case R_MOVL2:
+ internal->howto = howto_table + 17;
+ break;
+ case R_BCC_INV:
+ internal->howto = howto_table + 18;
+ break;
+ case R_JMP_DEL:
+ internal->howto = howto_table + 19;
+ break;
+ default:
+ abort ();
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+
+
+/* Perform any necessary magic to the addend in a reloc entry */
+
+
+#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
+ cache_ptr->addend = ext_reloc.r_offset;
+
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (relent, reloc, symbols, abfd, section)
+ arelent * relent;
+ struct internal_reloc *reloc;
+ asymbol ** symbols;
+ bfd * abfd;
+ asection * section;
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (((int) reloc->r_symndx) > 0)
+ {
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ }
+ else
+ {
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+
+
+
+ relent->addend = reloc->r_offset;
+
+ relent->address -= section->vma;
+ /* relent->section = 0;*/
+}
+
+static boolean
+h8300_symbol_address_p (abfd, input_section, address)
+ bfd *abfd;
+ asection *input_section;
+ bfd_vma address;
+{
+ asymbol **s;
+
+ s = _bfd_generic_link_get_symbols (abfd);
+ BFD_ASSERT (s != (asymbol **) NULL);
+
+ /* Search all the symbols for one in INPUT_SECTION with
+ address ADDRESS. */
+ while (*s)
+ {
+ asymbol *p = *s;
+ if (p->section == input_section
+ && (input_section->output_section->vma
+ + input_section->output_offset
+ + p->value) == address)
+ return true;
+ s++;
+ }
+ return false;
+}
+
+
+/* If RELOC represents a relaxable instruction/reloc, change it into
+ the relaxed reloc, notify the linker that symbol addresses
+ have changed (bfd_perform_slip) and return how much the current
+ section has shrunk by.
+
+ FIXME: Much of this code has knowledge of the ordering of entries
+ in the howto table. This needs to be fixed. */
+
+static int
+h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info)
+ bfd *abfd;
+ asection *input_section;
+ arelent *reloc;
+ unsigned int shrink;
+ struct bfd_link_info *link_info;
+{
+ bfd_vma value;
+ bfd_vma dot;
+ bfd_vma gap;
+ static asection *last_input_section = NULL;
+ static arelent *last_reloc = NULL;
+
+ /* The address of the thing to be relocated will have moved back by
+ the size of the shrink - but we don't change reloc->address here,
+ since we need it to know where the relocation lives in the source
+ uncooked section. */
+ bfd_vma address = reloc->address - shrink;
+
+ if (input_section != last_input_section)
+ last_reloc = NULL;
+
+ /* Only examine the relocs which might be relaxable. */
+ switch (reloc->howto->type)
+ {
+
+ /* This is the 16/24 bit absolute branch which could become an 8 bit
+ pc-relative branch. */
+ case R_JMP1:
+ case R_JMPL1:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ /* Get the address of the next instruction (not the reloc). */
+ dot = (input_section->output_section->vma
+ + input_section->output_offset + address);
+
+ /* Adjust for R_JMP1 vs R_JMPL1. */
+ dot += (reloc->howto->type == R_JMP1 ? 1 : 2);
+
+ /* Compute the distance from this insn to the branch target. */
+ gap = value - dot;
+
+ /* If the distance is within -128..+128 inclusive, then we can relax
+ this jump. +128 is valid since the target will move two bytes
+ closer if we do relax this branch. */
+ if ((int)gap >= -128 && (int)gap <= 128 )
+ {
+
+ /* It's possible we may be able to eliminate this branch entirely;
+ if the previous instruction is a branch around this instruction,
+ and there's no label at this instruction, then we can reverse
+ the condition on the previous branch and eliminate this jump.
+
+ original: new:
+ bCC lab1 bCC' lab2
+ jmp lab2
+ lab1: lab1:
+
+ This saves 4 bytes instead of two, and should be relatively
+ common. */
+
+ if (gap <= 126
+ && last_reloc
+ && last_reloc->howto->type == R_PCRBYTE)
+ {
+ bfd_vma last_value;
+ last_value = bfd_coff_reloc16_get_value (last_reloc, link_info,
+ input_section) + 1;
+
+ if (last_value == dot + 2
+ && last_reloc->address + 1 == reloc->address
+ && ! h8300_symbol_address_p (abfd, input_section, dot - 2))
+ {
+ reloc->howto = howto_table + 19;
+ last_reloc->howto = howto_table + 18;
+ last_reloc->sym_ptr_ptr = reloc->sym_ptr_ptr;
+ last_reloc->addend = reloc->addend;
+ shrink += 4;
+ bfd_perform_slip (abfd, 4, input_section, address);
+ break;
+ }
+ }
+
+ /* Change the reloc type. */
+ reloc->howto = reloc->howto + 1;
+
+ /* This shrinks this section by two bytes. */
+ shrink += 2;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+ break;
+
+ /* This is the 16 bit pc-relative branch which could become an 8 bit
+ pc-relative branch. */
+ case R_PCRWORD:
+ /* Get the address of the target of this branch, add one to the value
+ because the addend field in PCrel jumps is off by -1. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section) + 1;
+
+ /* Get the address of the next instruction if we were to relax. */
+ dot = input_section->output_section->vma +
+ input_section->output_offset + address;
+
+ /* Compute the distance from this insn to the branch target. */
+ gap = value - dot;
+
+ /* If the distance is within -128..+128 inclusive, then we can relax
+ this jump. +128 is valid since the target will move two bytes
+ closer if we do relax this branch. */
+ if ((int)gap >= -128 && (int)gap <= 128 )
+ {
+ /* Change the reloc type. */
+ reloc->howto = howto_table + 15;
+
+ /* This shrinks this section by two bytes. */
+ shrink += 2;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+ break;
+
+ /* This is a 16 bit absolute address in a mov.b insn, which can
+ become an 8 bit absolute address if it's in the right range. */
+ case R_MOV16B1:
+ /* Get the address of the data referenced by this mov.b insn. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ /* The address is in 0xff00..0xffff inclusive on the h8300 or
+ 0xffff00..0xffffff inclusive on the h8300h, then we can
+ relax this mov.b */
+ if ((bfd_get_mach (abfd) == bfd_mach_h8300
+ && value >= 0xff00
+ && value <= 0xffff)
+ || ((bfd_get_mach (abfd) == bfd_mach_h8300h
+ || bfd_get_mach (abfd) == bfd_mach_h8300s)
+ && value >= 0xffff00
+ && value <= 0xffffff))
+ {
+ /* Change the reloc type. */
+ reloc->howto = reloc->howto + 1;
+
+ /* This shrinks this section by two bytes. */
+ shrink += 2;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+ break;
+
+ /* Similarly for a 24 bit absolute address in a mov.b. Note that
+ if we can't relax this into an 8 bit absolute, we'll fall through
+ and try to relax it into a 16bit absolute. */
+ case R_MOV24B1:
+ /* Get the address of the data referenced by this mov.b insn. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ /* The address is in 0xffff00..0xffffff inclusive on the h8300h,
+ then we can relax this mov.b */
+ if ((bfd_get_mach (abfd) == bfd_mach_h8300h
+ || bfd_get_mach (abfd) == bfd_mach_h8300s)
+ && value >= 0xffff00
+ && value <= 0xffffff)
+ {
+ /* Change the reloc type. */
+ reloc->howto = reloc->howto + 1;
+
+ /* This shrinks this section by four bytes. */
+ shrink += 4;
+ bfd_perform_slip(abfd, 4, input_section, address);
+
+ /* Done with this reloc. */
+ break;
+ }
+
+ /* FALLTHROUGH and try to turn the 32/24 bit reloc into a 16 bit
+ reloc. */
+
+ /* This is a 24/32 bit absolute address in a mov insn, which can
+ become an 16 bit absolute address if it's in the right range. */
+ case R_MOVL1:
+ /* Get the address of the data referenced by this mov insn. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ /* If this address is in 0x0000..0x7fff inclusive or
+ 0xff8000..0xffffff inclusive, then it can be relaxed. */
+ if (value <= 0x7fff || value >= 0xff8000)
+ {
+ /* Change the reloc type. */
+ reloc->howto = howto_table + 17;
+
+ /* This shrinks this section by two bytes. */
+ shrink += 2;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+ break;
+
+ /* No other reloc types represent relaxing opportunities. */
+ default:
+ break;
+ }
+
+ last_reloc = reloc;
+ last_input_section = input_section;
+ return shrink;
+}
+
+
+/* Handle relocations for the H8/300, including relocs for relaxed
+ instructions.
+
+ FIXME: Not all relocations check for overflow! */
+
+static void
+h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
+ dst_ptr)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ arelent *reloc;
+ bfd_byte *data;
+ unsigned int *src_ptr;
+ unsigned int *dst_ptr;
+{
+ unsigned int src_address = *src_ptr;
+ unsigned int dst_address = *dst_ptr;
+ asection *input_section = link_order->u.indirect.section;
+ bfd_vma value;
+ bfd_vma dot;
+ int gap,tmp;
+
+ switch (reloc->howto->type)
+ {
+
+ /* Generic 8bit pc-relative relocation. */
+ case R_PCRBYTE:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ dot = (link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma);
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap < -128 || gap > 126)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Everything looks OK. Apply the relocation and update the
+ src/dst address appropriately. */
+
+ bfd_put_8 (abfd, gap, data + dst_address);
+ dst_address++;
+ src_address++;
+
+ /* All done. */
+ break;
+
+ /* Generic 16bit pc-relative relocation. */
+ case R_PCRWORD:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ /* Get the address of the instruction (not the reloc). */
+ dot = (link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma + 1);
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap > 32766 || gap < -32768)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Everything looks OK. Apply the relocation and update the
+ src/dst address appropriately. */
+
+ bfd_put_16 (abfd, gap, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+
+ /* All done. */
+ break;
+
+ /* Generic 8bit absolute relocation. */
+ case R_RELBYTE:
+ /* Get the address of the object referenced by this insn. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Sanity check. */
+ if (value <= 0xff
+ || (value >= 0x0000ff00 && value <= 0x0000ffff)
+ || (value >= 0x00ffff00 && value <= 0x00ffffff)
+ || (value >= 0xffffff00 && value <= 0xffffffff))
+ {
+ /* Everything looks OK. Apply the relocation and update the
+ src/dst address appropriately. */
+
+ bfd_put_8 (abfd, value & 0xff, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ else
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* All done. */
+ break;
+
+ /* Various simple 16bit absolute relocations. */
+ case R_MOV16B1:
+ case R_JMP1:
+ case R_RELWORD:
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+ bfd_put_16 (abfd, value, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+ break;
+
+ /* Various simple 24/32bit absolute relocations. */
+ case R_MOV24B1:
+ case R_MOVL1:
+ case R_RELLONG:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ bfd_put_32 (abfd, value, data + dst_address);
+ dst_address += 4;
+ src_address += 4;
+ break;
+
+ /* Another 24/32bit absolute relocation. */
+ case R_JMPL1:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ value = ((value & 0x00ffffff)
+ | (bfd_get_32 (abfd, data + src_address) & 0xff000000));
+ bfd_put_32 (abfd, value, data + dst_address);
+ dst_address += 4;
+ src_address += 4;
+ break;
+
+ /* A 16bit abolute relocation that was formerlly a 24/32bit
+ absolute relocation. */
+ case R_MOVL2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Sanity check. */
+ if (value < 0x8000 || value > 0xff8000)
+ {
+ /* Insert the 16bit value into the proper location. */
+ bfd_put_16 (abfd, value, data + dst_address);
+
+ /* Fix the opcode. For all the move insns, we simply
+ need to turn off bit 0x20 in the previous byte. */
+ data[dst_address - 1] &= ~0x20;
+ dst_address += 2;
+ src_address += 4;
+ }
+ else
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ break;
+
+ /* A 16bit absolute branch that is now an 8-bit pc-relative branch. */
+ case R_JMP2:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Get the address of the next instruction. */
+ dot = (link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma + 1);
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap < -128 || gap > 126)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Now fix the instruction itself. */
+ switch (data[dst_address - 1])
+ {
+ case 0x5e:
+ /* jsr -> bsr */
+ bfd_put_8 (abfd, 0x55, data + dst_address - 1);
+ break;
+ case 0x5a:
+ /* jmp ->bra */
+ bfd_put_8 (abfd, 0x40, data + dst_address - 1);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Write out the 8bit value. */
+ bfd_put_8 (abfd, gap, data + dst_address);
+
+ dst_address += 1;
+ src_address += 3;
+
+ break;
+
+ /* A 16bit pc-relative branch that is now an 8-bit pc-relative branch. */
+ case R_PCRWORD_B:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Get the address of the instruction (not the reloc). */
+ dot = (link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma - 1);
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap < -128 || gap > 126)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Now fix the instruction. */
+ switch (data[dst_address - 2])
+ {
+ case 0x58:
+ /* bCC:16 -> bCC:8 */
+ /* Get the condition code from the original insn. */
+ tmp = data[dst_address - 1];
+ tmp &= 0xf0;
+ tmp >>= 4;
+
+ /* Now or in the high nibble of the opcode. */
+ tmp |= 0x40;
+
+ /* Write it. */
+ bfd_put_8 (abfd, tmp, data + dst_address - 2);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Output the target. */
+ bfd_put_8 (abfd, gap, data + dst_address - 1);
+
+ /* We don't advance dst_address -- the 8bit reloc is applied at
+ dst_address - 1, so the next insn should begin at dst_address. */
+ src_address += 2;
+
+ break;
+
+ /* Similarly for a 24bit absolute that is now 8 bits. */
+ case R_JMPL2:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Get the address of the instruction (not the reloc). */
+ dot = (link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma + 2);
+
+ gap = value - dot;
+
+ /* Fix the instruction. */
+ switch (data[src_address])
+ {
+ case 0x5e:
+ /* jsr -> bsr */
+ bfd_put_8 (abfd, 0x55, data + dst_address);
+ break;
+ case 0x5a:
+ /* jmp ->bra */
+ bfd_put_8 (abfd, 0x40, data + dst_address);
+ break;
+ default:
+ abort ();
+ }
+
+ bfd_put_8 (abfd, gap, data + dst_address + 1);
+ dst_address += 2;
+ src_address += 4;
+
+ break;
+
+ /* A 16bit absolute mov.b that is now an 8bit absolute mov.b. */
+ case R_MOV16B2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Sanity check. */
+ if (data[dst_address - 2] != 0x6a)
+ abort ();
+
+ /* Fix up the opcode. */
+ switch (data[src_address-1] & 0xf0)
+ {
+ case 0x00:
+ data[dst_address - 2] = (data[src_address-1] & 0xf) | 0x20;
+ break;
+ case 0x80:
+ data[dst_address - 2] = (data[src_address-1] & 0xf) | 0x30;
+ break;
+ default:
+ abort ();
+ }
+
+ bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
+ src_address += 2;
+ break;
+
+ /* Similarly for a 24bit mov.b */
+ case R_MOV24B2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* Sanity check. */
+ if (data[dst_address - 2] != 0x6a)
+ abort ();
+
+ /* Fix up the opcode. */
+ switch (data[src_address-1] & 0xf0)
+ {
+ case 0x20:
+ data[dst_address - 2] = (data[src_address-1] & 0xf) | 0x20;
+ break;
+ case 0xa0:
+ data[dst_address - 2] = (data[src_address-1] & 0xf) | 0x30;
+ break;
+ default:
+ abort ();
+ }
+
+ bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
+ src_address += 4;
+ break;
+
+ case R_BCC_INV:
+ /* Get the address of the target of this branch. */
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ dot = (link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma) + 1;
+
+ gap = value - dot;
+
+ /* Sanity check. */
+ if (gap < -128 || gap > 126)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+
+ /* Everything looks OK. Fix the condition in the instruction, apply
+ the relocation, and update the src/dst address appropriately. */
+
+ bfd_put_8 (abfd, bfd_get_8 (abfd, data + dst_address - 1) ^ 1,
+ data + dst_address - 1);
+ bfd_put_8 (abfd, gap, data + dst_address);
+ dst_address++;
+ src_address++;
+
+ /* All done. */
+ break;
+
+ case R_JMP_DEL:
+ src_address += 4;
+ break;
+
+ /* An 8bit memory indirect instruction (jmp/jsr).
+
+ There's several things that need to be done to handle
+ this relocation.
+
+ If this is a reloc against the absolute symbol, then
+ we should handle it just R_RELBYTE. Likewise if it's
+ for a symbol with a value ge 0 and le 0xff.
+
+ Otherwise it's a jump/call through the function vector,
+ and the linker is expected to set up the function vector
+ and put the right value into the jump/call instruction. */
+ case R_MEM_INDIRECT:
+ {
+ /* We need to find the symbol so we can determine it's
+ address in the function vector table. */
+ asymbol *symbol;
+ bfd_vma value;
+ const char *name;
+ struct funcvec_hash_entry *h;
+ asection *vectors_sec = h8300_coff_hash_table (link_info)->vectors_sec;
+
+ /* First see if this is a reloc against the absolute symbol
+ or against a symbol with a nonnegative value <= 0xff. */
+ symbol = *(reloc->sym_ptr_ptr);
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ if (symbol == bfd_abs_section_ptr->symbol
+ || (value >= 0 && value <= 0xff))
+ {
+ /* This should be handled in a manner very similar to
+ R_RELBYTES. If the value is in range, then just slam
+ the value into the right location. Else trigger a
+ reloc overflow callback. */
+ if (value >= 0 && value <= 0xff)
+ {
+ bfd_put_8 (abfd, value, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ else
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ break;
+ }
+
+ /* This is a jump/call through a function vector, and we're
+ expected to create the function vector ourselves.
+
+ First look up this symbol in the linker hash table -- we need
+ the derived linker symbol which holds this symbol's index
+ in the function vector. */
+ name = symbol->name;
+ if (symbol->flags & BSF_LOCAL)
+ {
+ char *new_name = bfd_malloc (strlen (name) + 9);
+ if (new_name == NULL)
+ abort ();
+
+ strcpy (new_name, name);
+ sprintf (new_name + strlen (name), "_%08x",
+ (int)symbol->section);
+ name = new_name;
+ }
+
+ h = funcvec_hash_lookup (h8300_coff_hash_table (link_info)->funcvec_hash_table,
+ name, false, false);
+
+ /* This shouldn't ever happen. If it does that means we've got
+ data corruption of some kind. Aborting seems like a reasonable
+ think to do here. */
+ if (h == NULL || vectors_sec == NULL)
+ abort ();
+
+ /* Place the address of the function vector entry into the
+ reloc's address. */
+ bfd_put_8 (abfd,
+ vectors_sec->output_offset + h->offset,
+ data + dst_address);
+
+ dst_address++;
+ src_address++;
+
+ /* Now create an entry in the function vector itself. */
+ if (bfd_get_mach (input_section->owner) == bfd_mach_h8300)
+ bfd_put_16 (abfd,
+ bfd_coff_reloc16_get_value (reloc,
+ link_info,
+ input_section),
+ vectors_sec->contents + h->offset);
+ else if (bfd_get_mach (input_section->owner) == bfd_mach_h8300h
+ || bfd_get_mach (input_section->owner) == bfd_mach_h8300s)
+ bfd_put_32 (abfd,
+ bfd_coff_reloc16_get_value (reloc,
+ link_info,
+ input_section),
+ vectors_sec->contents + h->offset);
+ else
+ abort ();
+
+ /* Gross. We've already written the contents of the vector section
+ before we get here... So we write it again with the new data. */
+ bfd_set_section_contents (vectors_sec->output_section->owner,
+ vectors_sec->output_section,
+ vectors_sec->contents,
+ vectors_sec->output_offset,
+ vectors_sec->_raw_size);
+ break;
+ }
+
+ default:
+ abort ();
+ break;
+
+ }
+
+ *src_ptr = src_address;
+ *dst_ptr = dst_address;
+}
+
+
+/* Routine for the h8300 linker.
+
+ This routine is necessary to handle the special R_MEM_INDIRECT
+ relocs on the h8300. It's responsible for generating a vectors
+ section and attaching it to an input bfd as well as sizing
+ the vectors section. It also creates our vectors hash table.
+
+ It uses the generic linker routines to actually add the symbols.
+ from this BFD to the bfd linker hash table. It may add a few
+ selected static symbols to the bfd linker hash table. */
+
+static boolean
+h8300_bfd_link_add_symbols(abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *sec;
+ struct funcvec_hash_table *funcvec_hash_table;
+
+ /* If we haven't created a vectors section, do so now. */
+ if (!h8300_coff_hash_table (info)->vectors_sec)
+ {
+ flagword flags;
+
+ /* Make sure the appropriate flags are set, including SEC_IN_MEMORY. */
+ flags = (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY);
+ h8300_coff_hash_table (info)->vectors_sec = bfd_make_section (abfd,
+ ".vectors");
+
+ /* If the section wasn't created, or we couldn't set the flags,
+ quit quickly now, rather than dieing a painful death later. */
+ if (! h8300_coff_hash_table (info)->vectors_sec
+ || ! bfd_set_section_flags (abfd,
+ h8300_coff_hash_table(info)->vectors_sec,
+ flags))
+ return false;
+
+ /* Also create the vector hash table. */
+ funcvec_hash_table = ((struct funcvec_hash_table *)
+ bfd_alloc (abfd, sizeof (struct funcvec_hash_table)));
+
+ if (!funcvec_hash_table)
+ return false;
+
+ /* And initialize the funcvec hash table. */
+ if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
+ funcvec_hash_newfunc))
+ {
+ bfd_release (abfd, funcvec_hash_table);
+ return false;
+ }
+
+ /* Store away a pointer to the funcvec hash table. */
+ h8300_coff_hash_table (info)->funcvec_hash_table = funcvec_hash_table;
+ }
+
+ /* Load up the function vector hash table. */
+ funcvec_hash_table = h8300_coff_hash_table (info)->funcvec_hash_table;
+
+ /* Add the symbols using the generic code. */
+ _bfd_generic_link_add_symbols (abfd, info);
+
+ /* Now scan the relocs for all the sections in this bfd; create
+ additional space in the .vectors section as needed. */
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ long reloc_size, reloc_count, i;
+ asymbol **symbols;
+ arelent **relocs;
+
+ /* Suck in the relocs, symbols & canonicalize them. */
+ reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
+ if (reloc_size <= 0)
+ continue;
+
+ relocs = (arelent **)bfd_malloc ((size_t)reloc_size);
+ if (!relocs)
+ return false;
+
+ /* The symbols should have been read in by _bfd_generic link_add_symbols
+ call abovec, so we can cheat and use the pointer to them that was
+ saved in the above call. */
+ symbols = _bfd_generic_link_get_symbols(abfd);
+ reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, symbols);
+ if (reloc_count <= 0)
+ {
+ free (relocs);
+ continue;
+ }
+
+ /* Now walk through all the relocations in this section. */
+ for (i = 0; i < reloc_count; i++)
+ {
+ arelent *reloc = relocs[i];
+ asymbol *symbol = *(reloc->sym_ptr_ptr);
+ const char *name;
+
+ /* We've got an indirect reloc. See if we need to add it
+ to the function vector table. At this point, we have
+ to add a new entry for each unique symbol referenced
+ by an R_MEM_INDIRECT relocation except for a reloc
+ against the absolute section symbol. */
+ if (reloc->howto->type == R_MEM_INDIRECT
+ && symbol != bfd_abs_section_ptr->symbol)
+
+ {
+ struct funcvec_hash_entry *h;
+
+ name = symbol->name;
+ if (symbol->flags & BSF_LOCAL)
+ {
+ char *new_name = bfd_malloc (strlen (name) + 9);
+
+ if (new_name == NULL)
+ abort ();
+
+ strcpy (new_name, name);
+ sprintf (new_name + strlen (name), "_%08x",
+ (int)symbol->section);
+ name = new_name;
+ }
+
+ /* Look this symbol up in the function vector hash table. */
+ h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
+ name, false, false);
+
+
+ /* If this symbol isn't already in the hash table, add
+ it and bump up the size of the hash table. */
+ if (h == NULL)
+ {
+ h = funcvec_hash_lookup (h8300_coff_hash_table (info)->funcvec_hash_table,
+ name, true, true);
+ if (h == NULL)
+ {
+ free (relocs);
+ return false;
+ }
+
+ /* Bump the size of the vectors section. Each vector
+ takes 2 bytes on the h8300 and 4 bytes on the h8300h. */
+ if (bfd_get_mach (abfd) == bfd_mach_h8300)
+ h8300_coff_hash_table (info)->vectors_sec->_raw_size += 2;
+ else if (bfd_get_mach (abfd) == bfd_mach_h8300h
+ || bfd_get_mach (abfd) == bfd_mach_h8300s)
+ h8300_coff_hash_table (info)->vectors_sec->_raw_size += 4;
+ }
+ }
+ }
+
+ /* We're done with the relocations, release them. */
+ free (relocs);
+ }
+
+ /* Now actually allocate some space for the function vector. It's
+ wasteful to do this more than once, but this is easier. */
+ if (h8300_coff_hash_table (info)->vectors_sec->_raw_size != 0)
+ {
+ /* Free the old contents. */
+ if (h8300_coff_hash_table (info)->vectors_sec->contents)
+ free (h8300_coff_hash_table (info)->vectors_sec->contents);
+
+ /* Allocate new contents. */
+ h8300_coff_hash_table (info)->vectors_sec->contents
+ = bfd_malloc (h8300_coff_hash_table (info)->vectors_sec->_raw_size);
+ }
+
+ return true;
+}
+
+#define coff_reloc16_extra_cases h8300_reloc16_extra_cases
+#define coff_reloc16_estimate h8300_reloc16_estimate
+#define coff_bfd_link_add_symbols h8300_bfd_link_add_symbols
+#define coff_bfd_link_hash_table_create h8300_coff_link_hash_table_create
+
+#define COFF_LONG_FILENAMES
+#include "coffcode.h"
+
+
+#undef coff_bfd_get_relocated_section_contents
+#undef coff_bfd_relax_section
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+
+
+const bfd_target h8300coff_vec =
+{
+ "coff-h8300", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-h8500.c b/bfd/coff-h8500.c
new file mode 100644
index 00000000000..91109eaa921
--- /dev/null
+++ b/bfd/coff-h8500.c
@@ -0,0 +1,354 @@
+/* BFD back-end for Hitachi H8/500 COFF binaries.
+ Copyright 1993, 94, 95, 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Written by Steve Chamberlain, <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/h8500.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
+
+static reloc_howto_type r_imm8 =
+HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0,
+ complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false);
+
+static reloc_howto_type r_imm16 =
+HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0,
+ complain_overflow_bitfield, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false);
+
+static reloc_howto_type r_imm24 =
+HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0,
+ complain_overflow_bitfield, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false);
+
+static reloc_howto_type r_imm32 =
+HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0,
+ complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false);
+
+
+static reloc_howto_type r_high8 =
+HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0,
+ complain_overflow_dont, 0, "r_high8", true, 0x000000ff, 0x000000ff, false);
+
+static reloc_howto_type r_low16 =
+HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0,
+ complain_overflow_dont, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false);
+
+static reloc_howto_type r_pcrel8 =
+HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, complain_overflow_signed, 0, "r_pcrel8", true, 0, 0, true);
+
+
+static reloc_howto_type r_pcrel16 =
+HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, complain_overflow_signed, 0, "r_pcrel16", true, 0, 0, true);
+
+static reloc_howto_type r_high16 =
+HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0,
+ complain_overflow_dont, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false);
+
+
+/* Turn a howto into a reloc number */
+
+static int
+coff_h8500_select_reloc (howto)
+ reloc_howto_type *howto;
+{
+ return howto->type;
+}
+
+#define SELECT_RELOC(x,howto) x.r_type = coff_h8500_select_reloc(howto)
+
+
+#define BADMAG(x) H8500BADMAG(x)
+#define H8500 1 /* Customize coffcode.h */
+
+#define __A_MAGIC_SET__
+
+/* Code to swap in the reloc */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
+ dst->r_stuff[0] = 'S'; \
+ dst->r_stuff[1] = 'C';
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table
+ */
+
+static void
+rtype2howto(internal, dst)
+ arelent * internal;
+ struct internal_reloc *dst;
+{
+ switch (dst->r_type)
+ {
+ default:
+ abort ();
+ break;
+ case R_H8500_IMM8:
+ internal->howto = &r_imm8;
+ break;
+ case R_H8500_IMM16:
+ internal->howto = &r_imm16;
+ break;
+ case R_H8500_IMM24:
+ internal->howto = &r_imm24;
+ break;
+ case R_H8500_IMM32:
+ internal->howto = &r_imm32;
+ break;
+ case R_H8500_PCREL8:
+ internal->howto = &r_pcrel8;
+ break;
+ case R_H8500_PCREL16:
+ internal->howto = &r_pcrel16;
+ break;
+ case R_H8500_HIGH8:
+ internal->howto = &r_high8;
+ break;
+ case R_H8500_HIGH16:
+ internal->howto = &r_high16;
+ break;
+ case R_H8500_LOW16:
+ internal->howto = &r_low16;
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+
+
+/* Perform any necessary magic to the addend in a reloc entry */
+
+
+#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
+ cache_ptr->addend = ext_reloc.r_offset;
+
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void reloc_processing (relent, reloc, symbols, abfd, section)
+ arelent * relent;
+ struct internal_reloc *reloc;
+ asymbol ** symbols;
+ bfd * abfd;
+ asection * section;
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (reloc->r_symndx > 0)
+ {
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ }
+ else
+ {
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+
+
+ relent->addend = reloc->r_offset;
+ relent->address -= section->vma;
+}
+
+static void
+extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
+ bfd *in_abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ arelent *reloc;
+ bfd_byte *data;
+ unsigned int *src_ptr;
+ unsigned int *dst_ptr;
+{
+ bfd_byte *d = data+*dst_ptr;
+ asection *input_section = link_order->u.indirect.section;
+ switch (reloc->howto->type)
+ {
+ case R_H8500_IMM8:
+ bfd_put_8 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ d);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_H8500_HIGH8:
+ bfd_put_8 (in_abfd,
+ (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ >> 16),
+ d );
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_H8500_IMM16:
+ bfd_put_16 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ d );
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+
+ case R_H8500_LOW16:
+ bfd_put_16 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ d);
+
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+
+ case R_H8500_HIGH16:
+ bfd_put_16 (in_abfd,
+ (bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ >>16),
+ d);
+
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+
+ case R_H8500_IMM24:
+ {
+ int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+ int o = bfd_get_32(in_abfd, data+ *dst_ptr -1);
+ v = (v & 0x00ffffff) | (o & 0xff00000);
+ bfd_put_32 (in_abfd, v, data + *dst_ptr -1);
+ (*dst_ptr) +=3;
+ (*src_ptr)+=3;;
+ }
+ break;
+ case R_H8500_IMM32:
+ {
+ int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+ bfd_put_32 (in_abfd, v, data + *dst_ptr);
+ (*dst_ptr) +=4;
+ (*src_ptr)+=4;;
+ }
+ break;
+
+
+ case R_H8500_PCREL8:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = link_order->offset
+ + *dst_ptr
+ + link_order->u.indirect.section->output_section->vma;
+ int gap = dst - dot - 1; /* -1 since were in the odd byte of the
+ word and the pc's been incremented */
+
+ if (gap > 128 || gap < -128)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ bfd_put_8 (in_abfd, gap, data + *dst_ptr);
+ (*dst_ptr)++;
+ (*src_ptr)++;
+ break;
+ }
+ case R_H8500_PCREL16:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = link_order->offset
+ + *dst_ptr
+ + link_order->u.indirect.section->output_section->vma;
+ int gap = dst - dot - 1; /* -1 since were in the odd byte of the
+ word and the pc's been incremented */
+
+ if (gap > 32767 || gap < -32768)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ bfd_put_16 (in_abfd, gap, data + *dst_ptr);
+ (*dst_ptr)+=2;
+ (*src_ptr)+=2;
+ break;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+#define coff_reloc16_extra_cases extra_case
+
+#include "coffcode.h"
+
+
+#undef coff_bfd_get_relocated_section_contents
+#undef coff_bfd_relax_section
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+const bfd_target h8500coff_vec =
+{
+ "coff-h8500", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
new file mode 100644
index 00000000000..7898cc159ca
--- /dev/null
+++ b/bfd/coff-i386.c
@@ -0,0 +1,637 @@
+/* BFD back-end for Intel 386 COFF files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "coff/i386.h"
+
+#include "coff/internal.h"
+
+#ifdef COFF_WITH_PE
+#include "coff/pe.h"
+#endif
+
+#ifdef COFF_GO32_EXE
+#include "coff/go32exe.h"
+#endif
+
+#include "libcoff.h"
+
+static bfd_reloc_status_type coff_i386_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *coff_i386_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+
+ bfd_vma *));
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+/* The page size is a guess based on ELF. */
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* For some reason when using i386 COFF the value stored in the .text
+ section for a reference to a common symbol is the value itself plus
+ any desired offset. Ian Taylor, Cygnus Support. */
+
+/* If we are producing relocateable output, we need to do some
+ adjustments to the object file that are not done by the
+ bfd_perform_relocation function. This function is called by every
+ reloc type to make any required adjustments. */
+
+static bfd_reloc_status_type
+coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ symvalue diff;
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ if (bfd_is_com_section (symbol->section))
+ {
+#ifndef COFF_WITH_PE
+ /* We are relocating a common symbol. The current value in the
+ object file is ORIG + OFFSET, where ORIG is the value of the
+ common symbol as seen by the object file when it was compiled
+ (this may be zero if the symbol was undefined) and OFFSET is
+ the offset into the common symbol (normally zero, but may be
+ non-zero when referring to a field in a common structure).
+ ORIG is the negative of reloc_entry->addend, which is set by
+ the CALC_ADDEND macro below. We want to replace the value in
+ the object file with NEW + OFFSET, where NEW is the value of
+ the common symbol which we are going to put in the final
+ object file. NEW is symbol->value. */
+ diff = symbol->value + reloc_entry->addend;
+#else
+ /* In PE mode, we do not offset the common symbol. */
+ diff = reloc_entry->addend;
+#endif
+ }
+ else
+ {
+ /* For some reason bfd_perform_relocation always effectively
+ ignores the addend for a COFF target when producing
+ relocateable output. This seems to be always wrong for 386
+ COFF, so we handle the addend here instead. */
+ diff = reloc_entry->addend;
+ }
+
+#ifdef COFF_WITH_PE
+ /* FIXME: How should this case be handled? */
+ if (reloc_entry->howto->type == R_IMAGEBASE && diff != 0)
+ abort ();
+#endif
+
+#define DOIT(x) \
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+ if (diff != 0)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, addr);
+ DOIT (x);
+ bfd_put_16 (abfd, x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+#ifdef COFF_WITH_PE
+/* Return true if this relocation should
+ appear in the output .reloc section. */
+
+static boolean in_reloc_p(abfd, howto)
+ bfd * abfd;
+ reloc_howto_type *howto;
+{
+ return ! howto->pc_relative && howto->type != R_IMAGEBASE;
+}
+#endif
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET false
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ {0},
+ {1},
+ {2},
+ {3},
+ {4},
+ {5},
+ HOWTO (R_DIR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "dir32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+ /* {7}, */
+ HOWTO (R_IMAGEBASE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "rva32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+ {010},
+ {011},
+ {012},
+ {013},
+ {014},
+ {015},
+ {016},
+ HOWTO (R_RELBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "8", /* name */
+ true, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_RELWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_RELLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_PCRBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "DISP8", /* name */
+ true, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_PCRWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "DISP16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_PCRLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "DISP32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET) /* pcrel_offset */
+};
+
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define BADMAG(x) I386BADMAG(x)
+#define I386 1 /* Customize coffcode.h */
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = howto_table + (dst)->r_type;
+
+/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
+ library. On some other COFF targets STYP_BSS is normally
+ STYP_NOLOAD. */
+#define BSS_NOLOAD_IS_SHARED_LIBRARY
+
+/* Compute the addend of a reloc. If the reloc is to a common symbol,
+ the object file contains the value of the common symbol. By the
+ time this is called, the linker may be using a different symbol
+ from a different object file with a different value. Therefore, we
+ hack wildly to locate the original symbol from this file so that we
+ can make the correct adjustment. This macro sets coffsym to the
+ symbol from the original file, and uses it to set the addend value
+ correctly. If this is not a common symbol, the usual addend
+ calculation is done, except that an additional tweak is needed for
+ PC relative relocs.
+ FIXME: This macro refers to symbols and asect; these are from the
+ calling function, not the macro arguments. */
+
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ if (coffsym != (coff_symbol_type *) NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != (asection *) NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && howto_table[reloc.r_type].pc_relative) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+/* We use the special COFF backend linker. For normal i386 COFF, we
+ can use the generic relocate_section routine. For PE, we need our
+ own routine. */
+
+#ifndef COFF_WITH_PE
+
+#define coff_relocate_section _bfd_coff_generic_relocate_section
+
+#else /* COFF_WITH_PE */
+
+/* The PE relocate section routine. The only difference between this
+ and the regular routine is that we don't want to do anything for a
+ relocateable link. */
+
+static boolean coff_pe_i386_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+static boolean
+coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents, relocs, syms,
+ sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ if (info->relocateable)
+ return true;
+
+ return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents,
+ relocs, syms, sections);
+}
+
+#define coff_relocate_section coff_pe_i386_relocate_section
+
+#endif /* COFF_WITH_PE */
+
+/* Convert an rtype to howto for the COFF backend linker. */
+
+static reloc_howto_type *
+coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+
+ reloc_howto_type *howto;
+
+ howto = howto_table + rel->r_type;
+
+#ifdef COFF_WITH_PE
+ *addendp = 0;
+#endif
+
+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
+ {
+ /* This is a common symbol. The section contents include the
+ size (sym->n_value) as an addend. The relocate_section
+ function will be adding in the final value of the symbol. We
+ need to subtract out the current size in order to get the
+ correct result. */
+
+ BFD_ASSERT (h != NULL);
+
+#ifndef COFF_WITH_PE
+ /* I think we *do* want to bypass this. If we don't, I have
+ seen some data parameters get the wrong relocation address.
+ If I link two versions with and without this section bypassed
+ and then do a binary comparison, the addresses which are
+ different can be looked up in the map. The case in which
+ this section has been bypassed has addresses which correspond
+ to values I can find in the map. */
+ *addendp -= sym->n_value;
+#endif
+ }
+
+#ifndef COFF_WITH_PE
+ /* If the output symbol is common (in which case this must be a
+ relocateable link), we need to add in the final size of the
+ common symbol. */
+ if (h != NULL && h->root.type == bfd_link_hash_common)
+ *addendp += h->root.u.c.size;
+#endif
+
+#ifdef COFF_WITH_PE
+ if (howto->pc_relative)
+ {
+ *addendp -= 4;
+
+ /* If the symbol is defined, then the generic code is going to
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
+ if (sym != NULL && sym->n_scnum != 0)
+ *addendp -= sym->n_value;
+ }
+
+ if (rel->r_type == R_IMAGEBASE)
+ {
+ *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
+ }
+#endif
+
+ return howto;
+}
+
+
+#define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
+
+
+static reloc_howto_type *
+coff_i386_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_RVA:
+ return howto_table +R_IMAGEBASE;
+ case BFD_RELOC_32:
+ return howto_table + R_DIR32;
+ case BFD_RELOC_32_PCREL:
+ return howto_table + R_PCRLONG;
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+#define coff_rtype_to_howto coff_i386_rtype_to_howto
+
+#ifdef TARGET_UNDERSCORE
+
+/* If i386 gcc uses underscores for symbol names, then it does not use
+ a leading dot for local labels, so if TARGET_UNDERSCORE is defined
+ we treat all symbols starting with L as local. */
+
+static boolean coff_i386_is_local_label_name PARAMS ((bfd *, const char *));
+
+static boolean
+coff_i386_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ if (name[0] == 'L')
+ return true;
+
+ return _bfd_coff_is_local_label_name (abfd, name);
+}
+
+#define coff_bfd_is_local_label_name coff_i386_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
+
+#include "coffcode.h"
+
+static const bfd_target *
+i3coff_object_p (abfd)
+ bfd *abfd;
+{
+#ifdef COFF_IMAGE_WITH_PE
+ /* We need to hack badly to handle a PE image correctly. In PE
+ images created by the GNU linker, the offset to the COFF header
+ is always the size. However, this is not the case in images
+ generated by other PE linkers. The PE format stores a four byte
+ offset to the PE signature just before the COFF header at
+ location 0x3c of the file. We pick up that offset, verify that
+ the PE signature is there, and then set ourselves up to read in
+ the COFF header. */
+ {
+ bfd_byte ext_offset[4];
+ file_ptr offset;
+ bfd_byte ext_signature[4];
+ unsigned long signature;
+
+ if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
+ || bfd_read (ext_offset, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ offset = bfd_h_get_32 (abfd, ext_offset);
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || bfd_read (ext_signature, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ signature = bfd_h_get_32 (abfd, ext_signature);
+
+ if (signature != 0x4550)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Here is the hack. coff_object_p wants to read filhsz bytes to
+ pick up the COFF header. We adjust so that that will work. 20
+ is the size of the i386 COFF filehdr. */
+
+ if (bfd_seek (abfd,
+ (bfd_tell (abfd)
+ - bfd_coff_filhsz (abfd)
+ + 20),
+ SEEK_SET)
+ != 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ }
+#endif
+
+ return coff_object_p (abfd);
+}
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ i386coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-i386", /* name */
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+#ifndef COFF_WITH_PE
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_CODE | SEC_DATA),
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_CODE | SEC_DATA
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+#ifdef TARGET_UNDERSCORE
+ TARGET_UNDERSCORE, /* leading underscore */
+#else
+ 0, /* leading underscore */
+#endif
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+ {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, i3coff_object_p},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-i860.c b/bfd/coff-i860.c
new file mode 100644
index 00000000000..929fa428cdb
--- /dev/null
+++ b/bfd/coff-i860.c
@@ -0,0 +1,422 @@
+/* BFD back-end for Intel 860 COFF files.
+ Copyright 1990, 91, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Created mostly by substituting "860" for "386" in coff-i386.c
+ Harry Dolan <dolan@ssd.intel.com>, October 1995
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "coff/i860.h"
+
+#include "coff/internal.h"
+
+#include "libcoff.h"
+
+static bfd_reloc_status_type coff_i860_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *coff_i860_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *));
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+/* The page size is a guess based on ELF. */
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* For some reason when using i860 COFF the value stored in the .text
+ section for a reference to a common symbol is the value itself plus
+ any desired offset. Ian Taylor, Cygnus Support. */
+
+/* If we are producing relocateable output, we need to do some
+ adjustments to the object file that are not done by the
+ bfd_perform_relocation function. This function is called by every
+ reloc type to make any required adjustments. */
+
+static bfd_reloc_status_type
+coff_i860_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ symvalue diff;
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+
+ if (bfd_is_com_section (symbol->section))
+ {
+ /* We are relocating a common symbol. The current value in the
+ object file is ORIG + OFFSET, where ORIG is the value of the
+ common symbol as seen by the object file when it was compiled
+ (this may be zero if the symbol was undefined) and OFFSET is
+ the offset into the common symbol (normally zero, but may be
+ non-zero when referring to a field in a common structure).
+ ORIG is the negative of reloc_entry->addend, which is set by
+ the CALC_ADDEND macro below. We want to replace the value in
+ the object file with NEW + OFFSET, where NEW is the value of
+ the common symbol which we are going to put in the final
+ object file. NEW is symbol->value. */
+ diff = symbol->value + reloc_entry->addend;
+ }
+ else
+ {
+ /* For some reason bfd_perform_relocation always effectively
+ ignores the addend for a COFF target when producing
+ relocateable output. This seems to be always wrong for 860
+ COFF, so we handle the addend here instead. */
+ diff = reloc_entry->addend;
+ }
+
+
+#define DOIT(x) \
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+ if (diff != 0)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, addr);
+ DOIT (x);
+ bfd_put_16 (abfd, x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET false
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ {0},
+ {1},
+ {2},
+ {3},
+ {4},
+ {5},
+ HOWTO (R_DIR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "dir32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+ /* {7}, */
+ HOWTO (R_IMAGEBASE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "rva32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+ {010},
+ {011},
+ {012},
+ {013},
+ {014},
+ {015},
+ {016},
+ HOWTO (R_RELBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "8", /* name */
+ true, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_RELWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_RELLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_PCRBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "DISP8", /* name */
+ true, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_PCRWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "DISP16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_PCRLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "DISP32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET) /* pcrel_offset */
+};
+
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define BADMAG(x) I860BADMAG(x)
+#define I860 1 /* Customize coffcode.h */
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = howto_table + (dst)->r_type;
+
+/* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
+ library. On some other COFF targets STYP_BSS is normally
+ STYP_NOLOAD. */
+#define BSS_NOLOAD_IS_SHARED_LIBRARY
+
+/* Compute the addend of a reloc. If the reloc is to a common symbol,
+ the object file contains the value of the common symbol. By the
+ time this is called, the linker may be using a different symbol
+ from a different object file with a different value. Therefore, we
+ hack wildly to locate the original symbol from this file so that we
+ can make the correct adjustment. This macro sets coffsym to the
+ symbol from the original file, and uses it to set the addend value
+ correctly. If this is not a common symbol, the usual addend
+ calculation is done, except that an additional tweak is needed for
+ PC relative relocs.
+ FIXME: This macro refers to symbols and asect; these are from the
+ calling function, not the macro arguments. */
+
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ if (coffsym != (coff_symbol_type *) NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != (asection *) NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && howto_table[reloc.r_type].pc_relative) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+/* We use the special COFF backend linker. */
+#define coff_relocate_section _bfd_coff_generic_relocate_section
+
+static reloc_howto_type *
+coff_i860_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+
+ reloc_howto_type *howto;
+
+ howto = howto_table + rel->r_type;
+
+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
+ {
+ /* This is a common symbol. The section contents include the
+ size (sym->n_value) as an addend. The relocate_section
+ function will be adding in the final value of the symbol. We
+ need to subtract out the current size in order to get the
+ correct result. */
+
+ BFD_ASSERT (h != NULL);
+
+
+ /* I think we *do* want to bypass this. If we don't, I have seen some data
+ parameters get the wrong relcation address. If I link two versions
+ with and without this section bypassed and then do a binary comparison,
+ the addresses which are different can be looked up in the map. The
+ case in which this section has been bypassed has addresses which correspond
+ to values I can find in the map */
+ *addendp -= sym->n_value;
+ }
+
+ /* If the output symbol is common (in which case this must be a
+ relocateable link), we need to add in the final size of the
+ common symbol. */
+ if (h != NULL && h->root.type == bfd_link_hash_common)
+ *addendp += h->root.u.c.size;
+
+ return howto;
+}
+
+#define coff_rtype_to_howto coff_i860_rtype_to_howto
+
+#include "coffcode.h"
+
+static const bfd_target *
+i3coff_object_p(a)
+ bfd *a;
+{
+ return coff_object_p(a);
+}
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ i860coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-i860", /* name */
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+ {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, i3coff_object_p},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-i960.c b/bfd/coff-i960.c
new file mode 100644
index 00000000000..25455d9ead8
--- /dev/null
+++ b/bfd/coff-i960.c
@@ -0,0 +1,703 @@
+/* BFD back-end for Intel 960 COFF files.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define I960 1
+#define BADMAG(x) I960BADMAG(x)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/i960.h"
+#include "coff/internal.h"
+#include "libcoff.h" /* to allow easier abstraction-breaking */
+
+static boolean coff_i960_is_local_label_name PARAMS ((bfd *, const char *));
+static bfd_reloc_status_type optcall_callback
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type coff_i960_relocate
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *coff_i960_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static boolean coff_i960_start_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean coff_i960_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+static boolean coff_i960_adjust_symndx
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, boolean *));
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+#define COFF_ALIGN_IN_SECTION_HEADER 1
+
+#define GET_SCNHDR_ALIGN bfd_h_get_32
+#define PUT_SCNHDR_ALIGN bfd_h_put_32
+
+/* The i960 does not support an MMU, so COFF_PAGE_SIZE can be
+ arbitrarily small. */
+#define COFF_PAGE_SIZE 1
+
+#define COFF_LONG_FILENAMES
+
+/* This set of local label names is taken from gas. */
+
+static boolean
+coff_i960_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return (name[0] == 'L'
+ || (name[0] == '.'
+ && (name[1] == 'C'
+ || name[1] == 'I'
+ || name[1] == '.')));
+}
+
+/* This is just like the usual CALC_ADDEND, but it includes the
+ section VMA for PC relative relocs. */
+#ifndef CALC_ADDEND
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ if (coffsym != (coff_symbol_type *) NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = 0; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != (asection *) NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && (reloc.r_type == 25 || reloc.r_type == 27)) \
+ cache_ptr->addend += asect->vma; \
+ }
+#endif
+
+#define CALLS 0x66003800 /* Template for 'calls' instruction */
+#define BAL 0x0b000000 /* Template for 'bal' instruction */
+#define BAL_MASK 0x00ffffff
+
+static bfd_reloc_status_type
+optcall_callback (abfd, reloc_entry, symbol_in, data,
+ input_section, ignore_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *ignore_bfd;
+ char **error_message;
+{
+ /* This item has already been relocated correctly, but we may be
+ * able to patch in yet better code - done by digging out the
+ * correct info on this symbol */
+ bfd_reloc_status_type result;
+ coff_symbol_type *cs = coffsymbol(symbol_in);
+
+ /* Don't do anything with symbols which aren't tied up yet,
+ except move the reloc. */
+ if (bfd_is_und_section (cs->symbol.section)) {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* So the target symbol has to be of coff type, and the symbol
+ has to have the correct native information within it */
+ if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour)
+ || (cs->native == (combined_entry_type *)NULL))
+ {
+ /* This is interesting, consider the case where we're outputting coff
+ from a mix n match input, linking from coff to a symbol defined in a
+ bout file will cause this match to be true. Should I complain? This
+ will only work if the bout symbol is non leaf. */
+ *error_message =
+ (char *) _("uncertain calling convention for non-COFF symbol");
+ result = bfd_reloc_dangerous;
+ }
+ else
+ {
+ switch (cs->native->u.syment.n_sclass)
+ {
+ case C_LEAFSTAT:
+ case C_LEAFEXT:
+ /* This is a call to a leaf procedure, replace instruction with a bal
+ to the correct location. */
+ {
+ union internal_auxent *aux = &((cs->native+2)->u.auxent);
+ int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
+ int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
+ BFD_ASSERT(cs->native->u.syment.n_numaux==2);
+
+ /* We replace the original call instruction with a bal to
+ the bal entry point - the offset of which is described in
+ the 2nd auxent of the original symbol. We keep the native
+ sym and auxents untouched, so the delta between the two
+ is the offset of the bal entry point. */
+ word = ((word + olf) & BAL_MASK) | BAL;
+ bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address);
+ }
+ result = bfd_reloc_ok;
+ break;
+ case C_SCALL:
+ /* This is a call to a system call, replace with a calls to # */
+ BFD_ASSERT(0);
+ result = bfd_reloc_ok;
+ break;
+ default:
+ result = bfd_reloc_ok;
+ break;
+ }
+ }
+ return result;
+}
+
+/* i960 COFF is used by VxWorks 5.1. However, VxWorks 5.1 does not
+ appear to correctly handle a reloc against a symbol defined in the
+ same object file. It appears to simply discard such relocs, rather
+ than adding their values into the object file. We handle this here
+ by converting all relocs against defined symbols into relocs
+ against the section symbol, when generating a relocateable output
+ file.
+
+ Note that this function is only called if we are not using the COFF
+ specific backend linker. It only does something when doing a
+ relocateable link, which will almost certainly fail when not
+ generating COFF i960 output, so this function is actually no longer
+ useful. It was used before this target was converted to use the
+ COFF specific backend linker. */
+
+static bfd_reloc_status_type
+coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ asection *osec;
+
+ if (output_bfd == NULL)
+ {
+ /* Not generating relocateable output file. */
+ return bfd_reloc_continue;
+ }
+
+ if (bfd_is_und_section (bfd_get_section (symbol)))
+ {
+ /* Symbol is not defined, so no need to worry about it. */
+ return bfd_reloc_continue;
+ }
+
+ if (bfd_is_com_section (bfd_get_section (symbol)))
+ {
+ /* I don't really know what the right action is for a common
+ symbol. */
+ return bfd_reloc_continue;
+ }
+
+ /* Convert the reloc to use the section symbol. FIXME: This method
+ is ridiculous. */
+ osec = bfd_get_section (symbol)->output_section;
+ if (coff_section_data (output_bfd, osec) != NULL
+ && coff_section_data (output_bfd, osec)->tdata != NULL)
+ reloc_entry->sym_ptr_ptr =
+ (asymbol **) coff_section_data (output_bfd, osec)->tdata;
+ else
+ {
+ const char *sec_name;
+ asymbol **syms, **sym_end;
+
+ sec_name = bfd_get_section_name (output_bfd, osec);
+ syms = bfd_get_outsymbols (output_bfd);
+ sym_end = syms + bfd_get_symcount (output_bfd);
+ for (; syms < sym_end; syms++)
+ {
+ if (bfd_asymbol_name (*syms) != NULL
+ && (*syms)->value == 0
+ && strcmp ((*syms)->section->output_section->name,
+ sec_name) == 0)
+ break;
+ }
+
+ if (syms >= sym_end)
+ abort ();
+
+ reloc_entry->sym_ptr_ptr = syms;
+
+ if (coff_section_data (output_bfd, osec) == NULL)
+ {
+ osec->used_by_bfd =
+ ((PTR) bfd_zalloc (abfd,
+ sizeof (struct coff_section_tdata)));
+ if (osec->used_by_bfd == NULL)
+ return bfd_reloc_overflow;
+ }
+ coff_section_data (output_bfd, osec)->tdata = (PTR) syms;
+ }
+
+ /* Let bfd_perform_relocation do its thing, which will include
+ stuffing the symbol addend into the object file. */
+ return bfd_reloc_continue;
+}
+
+static reloc_howto_type howto_rellong =
+ HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,false, 0,
+ complain_overflow_bitfield, coff_i960_relocate,"rellong", true,
+ 0xffffffff, 0xffffffff, 0);
+static reloc_howto_type howto_iprmed =
+ HOWTO (R_IPRMED, 0, 2, 24,true,0, complain_overflow_signed,
+ coff_i960_relocate, "iprmed ", true, 0x00ffffff, 0x00ffffff, 0);
+static reloc_howto_type howto_optcall =
+ HOWTO (R_OPTCALL, 0,2,24,true,0, complain_overflow_signed,
+ optcall_callback, "optcall", true, 0x00ffffff, 0x00ffffff, 0);
+
+static reloc_howto_type *
+coff_i960_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ default:
+ return 0;
+ case BFD_RELOC_I960_CALLJ:
+ return &howto_optcall;
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return &howto_rellong;
+ case BFD_RELOC_24_PCREL:
+ return &howto_iprmed;
+ }
+}
+
+/* The real code is in coffcode.h */
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+{ \
+ reloc_howto_type *howto_ptr; \
+ switch ((dst)->r_type) { \
+ case 17: howto_ptr = &howto_rellong; break; \
+ case 25: howto_ptr = &howto_iprmed; break; \
+ case 27: howto_ptr = &howto_optcall; break; \
+ default: howto_ptr = 0; break; \
+ } \
+ (cache_ptr)->howto = howto_ptr; \
+ }
+
+/* i960 COFF is used by VxWorks 5.1. However, VxWorks 5.1 does not
+ appear to correctly handle a reloc against a symbol defined in the
+ same object file. It appears to simply discard such relocs, rather
+ than adding their values into the object file. We handle this by
+ converting all relocs against global symbols into relocs against
+ internal symbols at the start of the section. This routine is
+ called at the start of the linking process, and it creates the
+ necessary symbols. */
+
+static boolean
+coff_i960_start_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd_size_type symesz = bfd_coff_symesz (abfd);
+ asection *o;
+ bfd_byte *esym;
+
+ if (! info->relocateable)
+ return true;
+
+ esym = (bfd_byte *) bfd_malloc (symesz);
+ if (esym == NULL)
+ return false;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
+ return false;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct internal_syment isym;
+
+ strncpy (isym._n._n_name, o->name, SYMNMLEN);
+ isym.n_value = 0;
+ isym.n_scnum = o->target_index;
+ isym.n_type = T_NULL;
+ isym.n_sclass = C_STAT;
+ isym.n_numaux = 0;
+
+ bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym);
+
+ if (bfd_write (esym, symesz, 1, abfd) != symesz)
+ {
+ free (esym);
+ return false;
+ }
+
+ obj_raw_syment_count (abfd) += 1;
+ }
+
+ free (esym);
+
+ return true;
+}
+
+/* The reloc processing routine for the optimized COFF linker. */
+
+static boolean
+coff_i960_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, syms, sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma addend;
+ bfd_vma val;
+ reloc_howto_type *howto;
+ bfd_reloc_status_type rstat = bfd_reloc_ok;
+ boolean done;
+
+ symndx = rel->r_symndx;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ }
+
+ if (sym != NULL && sym->n_scnum != 0)
+ addend = - sym->n_value;
+ else
+ addend = 0;
+
+ switch (rel->r_type)
+ {
+ case 17: howto = &howto_rellong; break;
+ case 25: howto = &howto_iprmed; break;
+ case 27: howto = &howto_optcall; break;
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ asection *sec;
+
+ if (symndx == -1)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value
+ - sec->vma);
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (! info->relocateable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ done = false;
+
+ if (howto->type == R_OPTCALL && ! info->relocateable && symndx != -1)
+ {
+ int class;
+
+ if (h != NULL)
+ class = h->class;
+ else
+ class = sym->n_sclass;
+
+ switch (class)
+ {
+ case C_NULL:
+ /* This symbol is apparently not from a COFF input file.
+ We warn, and then assume that it is not a leaf
+ function. */
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info,
+ _("uncertain calling convention for non-COFF symbol"),
+ input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ break;
+ case C_LEAFSTAT:
+ case C_LEAFEXT:
+ /* This is a call to a leaf procedure; use the bal
+ instruction. */
+ {
+ long olf;
+ unsigned long word;
+
+ if (h != NULL)
+ {
+ BFD_ASSERT (h->numaux == 2);
+ olf = h->aux[1].x_bal.x_balntry;
+ }
+ else
+ {
+ bfd_byte *esyms;
+ union internal_auxent aux;
+
+ BFD_ASSERT (sym->n_numaux == 2);
+ esyms = (bfd_byte *) obj_coff_external_syms (input_bfd);
+ esyms += (symndx + 2) * bfd_coff_symesz (input_bfd);
+ bfd_coff_swap_aux_in (input_bfd, (PTR) esyms, sym->n_type,
+ sym->n_sclass, 1, sym->n_numaux,
+ (PTR) &aux);
+ olf = aux.x_bal.x_balntry;
+ }
+
+ word = bfd_get_32 (input_bfd,
+ (contents
+ + (rel->r_vaddr - input_section->vma)));
+ word = ((word + olf - val) & BAL_MASK) | BAL;
+ bfd_put_32 (input_bfd,
+ word,
+ (contents
+ + (rel->r_vaddr - input_section->vma)));
+ done = true;
+ }
+ break;
+ case C_SCALL:
+ BFD_ASSERT (0);
+ break;
+ }
+ }
+
+ if (! done)
+ {
+ if (howto->pc_relative)
+ addend += input_section->vma;
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents,
+ rel->r_vaddr - input_section->vma,
+ val, addend);
+ }
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return false;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Adjust the symbol index of any reloc against a global symbol to
+ instead be a reloc against the internal symbol we created specially
+ for the section. */
+
+/*ARGSUSED*/
+static boolean
+coff_i960_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp)
+ bfd *obfd;
+ struct bfd_link_info *info;
+ bfd *ibfd;
+ asection *sec;
+ struct internal_reloc *irel;
+ boolean *adjustedp;
+{
+ struct coff_link_hash_entry *h;
+
+ *adjustedp = false;
+
+ h = obj_coff_sym_hashes (ibfd)[irel->r_symndx];
+ if (h == NULL
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak))
+ return true;
+
+ irel->r_symndx = h->root.u.def.section->output_section->target_index - 1;
+ *adjustedp = true;
+
+ return true;
+}
+
+#define coff_bfd_is_local_label_name coff_i960_is_local_label_name
+
+#define coff_start_final_link coff_i960_start_final_link
+
+#define coff_relocate_section coff_i960_relocate_section
+
+#define coff_adjust_symndx coff_i960_adjust_symndx
+
+#define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup
+
+#include "coffcode.h"
+
+const bfd_target icoff_little_vec =
+{
+ "coff-Intel-little", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+
+
+const bfd_target icoff_big_vec =
+{
+ "coff-Intel-big", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-m68k.c b/bfd/coff-m68k.c
new file mode 100644
index 00000000000..5a06b17d50b
--- /dev/null
+++ b/bfd/coff-m68k.c
@@ -0,0 +1,480 @@
+/* BFD back-end for Motorola 68000 COFF binaries.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/m68k.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+/* This source file is compiled multiple times for various m68k COFF
+ variants. The following macros control its behaviour:
+
+ TARGET_SYM
+ The C name of the BFD target vector. The default is m68kcoff_vec.
+ TARGET_NAME
+ The user visible target name. The default is "coff-m68k".
+ NAMES_HAVE_UNDERSCORE
+ Whether symbol names have an underscore.
+ ONLY_DECLARE_RELOCS
+ Only declare the relocation howto array. Don't actually compile
+ it. The actual array will be picked up in another version of the
+ file.
+ STATIC_RELOCS
+ Make the relocation howto array, and associated functions, static.
+ COFF_COMMON_ADDEND
+ If this is defined, then, for a relocation against a common
+ symbol, the object file holds the value (the size) of the common
+ symbol. If this is not defined, then, for a relocation against a
+ common symbol, the object file holds zero. */
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+
+#ifndef COFF_PAGE_SIZE
+/* The page size is a guess based on ELF. */
+#define COFF_PAGE_SIZE 0x2000
+#endif
+
+#ifndef COFF_COMMON_ADDEND
+#define RELOC_SPECIAL_FN 0
+#else
+static bfd_reloc_status_type m68kcoff_common_addend_special_fn
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *m68kcoff_common_addend_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *));
+#define RELOC_SPECIAL_FN m68kcoff_common_addend_special_fn
+#endif
+
+static boolean m68k_coff_is_local_label_name PARAMS ((bfd *, const char *));
+
+/* On the delta, a symbol starting with L% is local. We won't see
+ such a symbol on other platforms, so it should be safe to always
+ consider it local here. */
+
+static boolean
+m68k_coff_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ if (name[0] == 'L' && name[1] == '%')
+ return true;
+
+ return _bfd_coff_is_local_label_name (abfd, name);
+}
+
+#ifndef STATIC_RELOCS
+/* Clean up namespace. */
+#define m68kcoff_howto_table _bfd_m68kcoff_howto_table
+#define m68k_rtype2howto _bfd_m68kcoff_rtype2howto
+#define m68k_howto2rtype _bfd_m68kcoff_howto2rtype
+#define m68k_reloc_type_lookup _bfd_m68kcoff_reloc_type_lookup
+#endif
+
+#ifdef ONLY_DECLARE_RELOCS
+extern reloc_howto_type m68kcoff_howto_table[];
+#else
+#ifdef STATIC_RELOCS
+static
+#endif
+reloc_howto_type m68kcoff_howto_table[] =
+{
+ HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "8", true, 0x000000ff,0x000000ff, false),
+ HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "32", true, 0xffffffff,0xffffffff, false),
+ HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP8", true, 0x000000ff,0x000000ff, false),
+ HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, RELOC_SPECIAL_FN, "DISP32", true, 0xffffffff,0xffffffff, false),
+ HOWTO(R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, RELOC_SPECIAL_FN, "-32", true, 0xffffffff,0xffffffff, false),
+};
+#endif /* not ONLY_DECLARE_RELOCS */
+
+#ifndef BADMAG
+#define BADMAG(x) M68KBADMAG(x)
+#endif
+#define M68 1 /* Customize coffcode.h */
+
+/* Turn a howto into a reloc number */
+
+#ifdef ONLY_DECLARE_RELOCS
+extern void m68k_rtype2howto PARAMS ((arelent *internal, int relocentry));
+extern int m68k_howto2rtype PARAMS ((reloc_howto_type *));
+extern reloc_howto_type *m68k_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+#else
+#ifdef STATIC_RELOCS
+static
+#endif
+void
+m68k_rtype2howto(internal, relocentry)
+ arelent *internal;
+ int relocentry;
+{
+ switch (relocentry)
+ {
+ case R_RELBYTE: internal->howto = m68kcoff_howto_table + 0; break;
+ case R_RELWORD: internal->howto = m68kcoff_howto_table + 1; break;
+ case R_RELLONG: internal->howto = m68kcoff_howto_table + 2; break;
+ case R_PCRBYTE: internal->howto = m68kcoff_howto_table + 3; break;
+ case R_PCRWORD: internal->howto = m68kcoff_howto_table + 4; break;
+ case R_PCRLONG: internal->howto = m68kcoff_howto_table + 5; break;
+ case R_RELLONG_NEG: internal->howto = m68kcoff_howto_table + 6; break;
+ }
+}
+
+#ifdef STATIC_RELOCS
+static
+#endif
+int
+m68k_howto2rtype (internal)
+ reloc_howto_type *internal;
+{
+ if (internal->pc_relative)
+ {
+ switch (internal->bitsize)
+ {
+ case 32: return R_PCRLONG;
+ case 16: return R_PCRWORD;
+ case 8: return R_PCRBYTE;
+ }
+ }
+ else
+ {
+ switch (internal->bitsize)
+ {
+ case 32: return R_RELLONG;
+ case 16: return R_RELWORD;
+ case 8: return R_RELBYTE;
+ }
+ }
+ return R_RELLONG;
+}
+
+#ifdef STATIC_RELOCS
+static
+#endif
+reloc_howto_type *
+m68k_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ default: return NULL;
+ case BFD_RELOC_8: return m68kcoff_howto_table + 0;
+ case BFD_RELOC_16: return m68kcoff_howto_table + 1;
+ case BFD_RELOC_CTOR:
+ case BFD_RELOC_32: return m68kcoff_howto_table + 2;
+ case BFD_RELOC_8_PCREL: return m68kcoff_howto_table + 3;
+ case BFD_RELOC_16_PCREL: return m68kcoff_howto_table + 4;
+ case BFD_RELOC_32_PCREL: return m68kcoff_howto_table + 5;
+ /* FIXME: There doesn't seem to be a code for R_RELLONG_NEG. */
+ }
+ /*NOTREACHED*/
+}
+
+#endif /* not ONLY_DECLARE_RELOCS */
+
+#define RTYPE2HOWTO(internal, relocentry) \
+ m68k_rtype2howto(internal, (relocentry)->r_type)
+
+#define SELECT_RELOC(external, internal) \
+ external.r_type = m68k_howto2rtype (internal)
+
+#define coff_bfd_reloc_type_lookup m68k_reloc_type_lookup
+
+#ifndef COFF_COMMON_ADDEND
+#ifndef coff_rtype_to_howto
+
+#define coff_rtype_to_howto m68kcoff_rtype_to_howto
+
+static reloc_howto_type *m68kcoff_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *));
+
+/*ARGSUSED*/
+static reloc_howto_type *
+m68kcoff_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+ arelent relent;
+ reloc_howto_type *howto;
+
+ RTYPE2HOWTO (&relent, rel);
+
+ howto = relent.howto;
+
+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ return howto;
+}
+
+#endif /* ! defined (coff_rtype_to_howto) */
+#endif /* ! defined (COFF_COMMON_ADDEND) */
+
+#ifdef COFF_COMMON_ADDEND
+
+/* If COFF_COMMON_ADDEND is defined, then when using m68k COFF the
+ value stored in the .text section for a reference to a common
+ symbol is the value itself plus any desired offset. (taken from
+ work done by Ian Taylor, Cygnus Support, for I386 COFF). */
+
+/* If we are producing relocateable output, we need to do some
+ adjustments to the object file that are not done by the
+ bfd_perform_relocation function. This function is called by every
+ reloc type to make any required adjustments. */
+
+static bfd_reloc_status_type
+m68kcoff_common_addend_special_fn (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ symvalue diff;
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ if (bfd_is_com_section (symbol->section))
+ {
+ /* We are relocating a common symbol. The current value in the
+ object file is ORIG + OFFSET, where ORIG is the value of the
+ common symbol as seen by the object file when it was compiled
+ (this may be zero if the symbol was undefined) and OFFSET is
+ the offset into the common symbol (normally zero, but may be
+ non-zero when referring to a field in a common structure).
+ ORIG is the negative of reloc_entry->addend, which is set by
+ the CALC_ADDEND macro below. We want to replace the value in
+ the object file with NEW + OFFSET, where NEW is the value of
+ the common symbol which we are going to put in the final
+ object file. NEW is symbol->value. */
+ diff = symbol->value + reloc_entry->addend;
+ }
+ else
+ {
+ /* For some reason bfd_perform_relocation always effectively
+ ignores the addend for a COFF target when producing
+ relocateable output. This seems to be always wrong for 386
+ COFF, so we handle the addend here instead. */
+ diff = reloc_entry->addend;
+ }
+
+#define DOIT(x) \
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+ if (diff != 0)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, addr);
+ DOIT (x);
+ bfd_put_16 (abfd, x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+/* Compute the addend of a reloc. If the reloc is to a common symbol,
+ the object file contains the value of the common symbol. By the
+ time this is called, the linker may be using a different symbol
+ from a different object file with a different value. Therefore, we
+ hack wildly to locate the original symbol from this file so that we
+ can make the correct adjustment. This macro sets coffsym to the
+ symbol from the original file, and uses it to set the addend value
+ correctly. If this is not a common symbol, the usual addend
+ calculation is done, except that an additional tweak is needed for
+ PC relative relocs.
+ FIXME: This macro refers to symbols and asect; these are from the
+ calling function, not the macro arguments. */
+
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ if (coffsym != (coff_symbol_type *) NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != (asection *) NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && (reloc.r_type == R_PCRBYTE \
+ || reloc.r_type == R_PCRWORD \
+ || reloc.r_type == R_PCRLONG)) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+#ifndef coff_rtype_to_howto
+
+/* coff-m68k.c uses the special COFF backend linker. We need to
+ adjust common symbols. */
+
+/*ARGSUSED*/
+static reloc_howto_type *
+m68kcoff_common_addend_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+ arelent relent;
+ reloc_howto_type *howto;
+
+ RTYPE2HOWTO (&relent, rel);
+
+ howto = relent.howto;
+
+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
+ {
+ /* This is a common symbol. The section contents include the
+ size (sym->n_value) as an addend. The relocate_section
+ function will be adding in the final value of the symbol. We
+ need to subtract out the current size in order to get the
+ correct result. */
+ BFD_ASSERT (h != NULL);
+ *addendp -= sym->n_value;
+ }
+
+ /* If the output symbol is common (in which case this must be a
+ relocateable link), we need to add in the final size of the
+ common symbol. */
+ if (h != NULL && h->root.type == bfd_link_hash_common)
+ *addendp += h->root.u.c.size;
+
+ return howto;
+}
+
+#define coff_rtype_to_howto m68kcoff_common_addend_rtype_to_howto
+
+#endif /* ! defined (coff_rtype_to_howto) */
+
+#endif /* COFF_COMMON_ADDEND */
+
+#define coff_bfd_is_local_label_name m68k_coff_is_local_label_name
+
+#define coff_relocate_section _bfd_coff_generic_relocate_section
+
+#include "coffcode.h"
+
+#ifndef TARGET_SYM
+#define TARGET_SYM m68kcoff_vec
+#endif
+
+#ifndef TARGET_NAME
+#define TARGET_NAME "coff-m68k"
+#endif
+
+const bfd_target TARGET_SYM =
+{
+ TARGET_NAME,
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#ifdef NAMES_HAVE_UNDERSCORE
+ '_',
+#else
+ 0, /* leading underscore */
+#endif
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-m88k.c b/bfd/coff-m88k.c
new file mode 100644
index 00000000000..8da0b052530
--- /dev/null
+++ b/bfd/coff-m88k.c
@@ -0,0 +1,330 @@
+/* BFD back-end for Motorola 88000 COFF "Binary Compatability Standard" files.
+ Copyright 1990, 91, 92, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define M88 1 /* Customize various include files */
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/m88k.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+static boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
+static bfd_reloc_status_type m88k_special_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
+static void reloc_processing
+ PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+#define GET_SCNHDR_NRELOC bfd_h_get_32
+#define GET_SCNHDR_NLNNO bfd_h_get_32
+
+/* On coff-m88k, local labels start with '@'. */
+
+#define coff_bfd_is_local_label_name m88k_is_local_label_name
+
+static boolean
+m88k_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return name[0] == '@';
+}
+
+static bfd_reloc_status_type
+m88k_special_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ switch (howto->type)
+ {
+ case R_HVRT16:
+ case R_LVRT16:
+ if (output_bfd != (bfd *) NULL)
+ {
+ /* This is a partial relocation, and we want to apply the
+ relocation to the reloc entry rather than the raw data.
+ Modify the reloc inplace to reflect what we now know. */
+
+ reloc_entry->address += input_section->output_offset;
+ }
+ else
+ {
+ bfd_vma output_base = 0;
+ bfd_vma addr = reloc_entry->address;
+ bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ asection *reloc_target_output_section;
+ long relocation = 0;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (output_bfd)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += ((reloc_entry->addend << howto->bitsize) + x);
+
+ reloc_entry->addend = 0;
+
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ if (relocation)
+ bfd_put_16 (abfd, relocation, (unsigned char *) data + addr);
+ }
+
+ /* If we are not producing relocateable output, return an error if
+ the symbol is not defined. */
+ if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
+ return bfd_reloc_undefined;
+
+ return bfd_reloc_ok;
+
+ default:
+ if (output_bfd != (bfd *) NULL)
+ {
+ /* This is a partial relocation, and we want to apply the
+ relocation to the reloc entry rather than the raw data.
+ Modify the reloc inplace to reflect what we now know. */
+
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+ break;
+ }
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type howto_table[] =
+{
+ HOWTO (R_PCR16L, /* type */
+ 02, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ m88k_special_reloc, /* special_function */
+ "PCR16L", /* name */
+ false, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_PCR26L, /* type */
+ 02, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ m88k_special_reloc, /* special_function */
+ "PCR26L", /* name */
+ false, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_VRT16, /* type */
+ 00, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ m88k_special_reloc, /* special_function */
+ "VRT16", /* name */
+ false, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_HVRT16, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m88k_special_reloc, /* special_function */
+ "HVRT16", /* name */
+ false, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_LVRT16, /* type */
+ 00, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m88k_special_reloc, /* special_function */
+ "LVRT16", /* name */
+ false, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_VRT32, /* type */
+ 00, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ m88k_special_reloc, /* special_function */
+ "VRT32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+};
+
+/* Code to turn an external r_type into a pointer to an entry in the
+ above howto table. */
+static void
+rtype2howto (cache_ptr, dst)
+ arelent *cache_ptr;
+ struct internal_reloc *dst;
+{
+ if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32)
+ {
+ cache_ptr->howto = howto_table + dst->r_type - R_PCR16L;
+ }
+ else
+ {
+ BFD_ASSERT (0);
+ }
+}
+
+#define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
+
+
+/* Code to swap in the reloc offset */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_16
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_16
+
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (relent, reloc, symbols, abfd, section)
+ arelent *relent;
+ struct internal_reloc *reloc;
+ asymbol **symbols;
+ bfd *abfd;
+ asection *section;
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (((int) reloc->r_symndx) > 0)
+ {
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ }
+ else
+ {
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+
+ relent->addend = reloc->r_offset;
+ relent->address -= section->vma;
+}
+
+#define BADMAG(x) MC88BADMAG(x)
+#include "coffcode.h"
+
+#undef coff_write_armap
+
+const bfd_target m88kbcs_vec =
+{
+ "coff-m88kbcs", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-mcore.c b/bfd/coff-mcore.c
new file mode 100644
index 00000000000..d787096e379
--- /dev/null
+++ b/bfd/coff-mcore.c
@@ -0,0 +1,703 @@
+/* BFD back-end for Motorolla MCore COFF/PE
+ Copyright 1999
+ Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/mcore.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+
+#ifdef BADMAG
+#undef BADMAG
+#endif
+#define BADMAG(x) MCOREBADMAG(x)
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
+#endif
+
+/* This file is compiled more than once, but we only compile the
+ final_link routine once. */
+extern boolean mcore_bfd_coff_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+static struct bfd_link_hash_table * coff_mcore_link_hash_table_create
+ PARAMS ((bfd *));
+static bfd_reloc_status_type mcore_coff_unsupported_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean in_reloc_p
+ PARAMS ((bfd *, reloc_howto_type *));
+static boolean coff_mcore_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+static reloc_howto_type * mcore_coff_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static reloc_howto_type * coff_mcore_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
+static const bfd_target * pe_object_p
+ PARAMS ((bfd *));
+
+
+
+/* The NT loader points the toc register to &toc + 32768, in order to
+ use the complete range of a 16-bit displacement. We have to adjust
+ for this when we fix up loads displaced off the toc reg. */
+#define TOC_LOAD_ADJUSTMENT (-32768)
+#define TOC_SECTION_NAME ".private.toc"
+
+/* The main body of code is in coffcode.h. */
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+ from smaller values. Start with zero, widen, *then* decrement. */
+#define MINUS_ONE (((bfd_vma)0) - 1)
+
+
+static reloc_howto_type mcore_coff_howto_table[] =
+{
+ /* Unused: */
+ HOWTO (IMAGE_REL_MCORE_ABSOLUTE,/* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* dont complain_on_overflow */
+ 0, /* special_function */
+ "ABSOLUTE", /* name */
+ false, /* partial_inplace */
+ 0x00, /* src_mask */
+ 0x00, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (IMAGE_REL_MCORE_ADDR32,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
+ Should not appear in object files. */
+ HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mcore_coff_unsupported_reloc, /* special_function */
+ "IMM8BY4", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
+ Span 2k instructions == 4k bytes.
+ Only useful pieces at the relocated address are the opcode (5 bits) */
+ HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ NULL, /* special_function */
+ "IMM11BY2", /* name */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x7ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
+ HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mcore_coff_unsupported_reloc,/* special_function */
+ "IMM4BY2", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 32-bit pc-relative. Eventually this will help support PIC code. */
+ HOWTO (IMAGE_REL_MCORE_PCREL_32,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PCREL_32", /* name */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Like PCREL_IMM11BY2, this relocation indicates that there is a
+ 'jsri' at the specified address. There is a separate relocation
+ entry for the literal pool entry that it references, but we
+ might be able to change the jsri to a bsr if the target turns out
+ to be close enough [even though we won't reclaim the literal pool
+ entry, we'll get some runtime efficiency back]. Note that this
+ is a relocation that we are allowed to safely ignore. */
+ HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ NULL, /* special_function */
+ "JSR_IMM11BY2", /* name */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x7ff, /* dst_mask */
+ true) /* pcrel_offset */
+};
+
+/* Extend the coff_link_hash_table structure with a few M*Core specific fields.
+ This allows us to store global data here without actually creating any
+ global variables, which is a no-no in the BFD world. */
+typedef struct coff_mcore_link_hash_table
+{
+ /* The original coff_link_hash_table structure. MUST be first field. */
+ struct coff_link_hash_table root;
+
+ bfd * bfd_of_toc_owner;
+ long int global_toc_size;
+ long int import_table_size;
+ long int first_thunk_address;
+ long int thunk_size;
+}
+mcore_hash_table;
+
+/* Get the MCore coff linker hash table from a link_info structure. */
+#define coff_mcore_hash_table(info) \
+ ((mcore_hash_table *) ((info)->hash))
+
+/* Create an MCore coff linker hash table. */
+static struct bfd_link_hash_table *
+coff_mcore_link_hash_table_create (abfd)
+ bfd * abfd;
+{
+ mcore_hash_table * ret;
+
+ ret = ((mcore_hash_table *) bfd_alloc (abfd, sizeof (* ret)));
+ if (ret == (mcore_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_coff_link_hash_table_init
+ (& ret->root, abfd, _bfd_coff_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->bfd_of_toc_owner = NULL;
+ ret->global_toc_size = 0;
+ ret->import_table_size = 0;
+ ret->first_thunk_address = 0;
+ ret->thunk_size = 0;
+
+ return & ret->root.root;
+}
+
+/*ARGSUSED*/
+static bfd_reloc_status_type
+mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd * abfd;
+ arelent * reloc_entry;
+ asymbol * symbol;
+ PTR data;
+ asection * input_section;
+ bfd * output_bfd;
+ char ** error_message;
+{
+ BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
+
+ _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
+ bfd_get_filename (abfd),
+ reloc_entry->howto->name,
+ reloc_entry->howto->type);
+
+ return bfd_reloc_notsupported;
+}
+
+
+/* A cheesy little macro to make the code a little more readable. */
+#define HOW2MAP(bfd_rtype, mcore_rtype) \
+ case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
+
+static reloc_howto_type *
+mcore_coff_reloc_type_lookup (abfd, code)
+ bfd * abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ HOW2MAP (BFD_RELOC_32, IMAGE_REL_MCORE_ADDR32);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4, IMAGE_REL_MCORE_PCREL_IMM8BY4);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2, IMAGE_REL_MCORE_PCREL_IMM11BY2);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2, IMAGE_REL_MCORE_PCREL_IMM4BY2);
+ HOW2MAP (BFD_RELOC_32_PCREL, IMAGE_REL_MCORE_PCREL_32);
+ HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2);
+ default:
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+
+#undef HOW2MAP
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
+
+static reloc_howto_type *
+coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd * abfd;
+ asection * sec;
+ struct internal_reloc * rel;
+ struct coff_link_hash_entry * h;
+ struct internal_syment * sym;
+ bfd_vma * addendp;
+{
+ reloc_howto_type * howto;
+
+
+ if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
+ return NULL;
+
+ howto = mcore_coff_howto_table + rel->r_type;
+
+ if (howto->pc_relative)
+ {
+ * addendp = sec->vma - 2; /* XXX guess - is this right ? */
+
+ /* If the symbol is defined, then the generic code is going to
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
+ if (sym != NULL && sym->n_scnum != 0)
+ * addendp -= sym->n_value;
+ }
+ else
+ * addendp = 0;
+
+ return howto;
+}
+
+/* Return true if this relocation should
+ appear in the output .reloc section. */
+static boolean in_reloc_p (abfd, howto)
+ bfd * abfd;
+ reloc_howto_type * howto;
+{
+ return ! howto->pc_relative;
+}
+
+/* The reloc processing routine for the optimized COFF linker. */
+static boolean
+coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, syms, sections)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ struct internal_reloc * relocs;
+ struct internal_syment * syms;
+ asection ** sections;
+{
+ struct internal_reloc * rel;
+ struct internal_reloc * relend;
+ boolean hihalf;
+ bfd_vma hihalf_val;
+
+ /* If we are performing a relocateable link, we don't need to do a
+ thing. The caller will take care of adjusting the reloc
+ addresses and symbol indices. */
+ if (info->relocateable)
+ return true;
+
+ BFD_ASSERT (input_bfd->xvec->byteorder
+ == output_bfd->xvec->byteorder);
+
+ hihalf = false;
+ hihalf_val = 0;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+
+ for (; rel < relend; rel++)
+ {
+ asection * toc_section = NULL;
+ bfd_vma relocation;
+ long symndx;
+ struct internal_syment * sym;
+ bfd_vma val;
+ bfd_vma addend;
+ bfd_reloc_status_type rstat;
+ bfd_byte * loc;
+ unsigned short r_type = rel->r_type;
+ reloc_howto_type * howto = NULL;
+ struct coff_link_hash_entry * h;
+ const char * my_name;
+
+ symndx = rel->r_symndx;
+ loc = contents + rel->r_vaddr - input_section->vma;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ }
+
+ /* Get the howto and initialise the addend. */
+ howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
+ sym, & addend);
+ if (howto == NULL)
+ return false;
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ if (symndx == -1)
+ my_name = "*ABS*";
+ else
+ {
+ asection * sec = sections[symndx];
+
+ val = (sym->n_value
+ + sec->output_section->vma
+ + sec->output_offset);
+
+ if (sym == NULL)
+ my_name = "*unknown*";
+ else if ( sym->_n._n_n._n_zeroes == 0
+ && sym->_n._n_n._n_offset != 0)
+ my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
+ else
+ {
+ static char buf [SYMNMLEN + 1];
+
+ strncpy (buf, sym->_n._n_name, SYMNMLEN);
+ buf[SYMNMLEN] = '\0';
+ my_name = buf;
+ }
+ }
+ }
+ else
+ {
+ if ( h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection * sec = h->root.u.def.section;
+
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+
+ my_name = h->root.root.string;
+ }
+
+ rstat = bfd_reloc_ok;
+
+ /* Each case must do its own relocation, setting rstat appropriately. */
+ switch (r_type)
+ {
+ default:
+ _bfd_error_handler (_("%s: unsupported relocation type 0x%02x"),
+ bfd_get_filename (input_bfd), r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+
+ case IMAGE_REL_MCORE_ABSOLUTE:
+ fprintf (stderr,
+ _("Warning: unsupported reloc %s <file %s, section %s>\n"),
+ howto->name,
+ bfd_get_filename (input_bfd),
+ input_section->name);
+
+ fprintf (stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
+ rel->r_symndx, my_name, (long) rel->r_vaddr,
+ (unsigned long) rel->r_vaddr);
+ break;
+
+ case IMAGE_REL_MCORE_PCREL_IMM8BY4:
+ case IMAGE_REL_MCORE_PCREL_IMM11BY2:
+ case IMAGE_REL_MCORE_PCREL_IMM4BY2:
+ case IMAGE_REL_MCORE_PCREL_32:
+ case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2:
+ case IMAGE_REL_MCORE_ADDR32:
+ rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
+ break;
+ }
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, my_name, howto->name,
+ (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+/* Tailor coffcode.h -- macro heaven. */
+
+/* We use the special COFF backend linker, with our own special touch. */
+
+#define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
+#define coff_relocate_section coff_mcore_relocate_section
+#define coff_rtype_to_howto coff_mcore_rtype_to_howto
+
+#define SELECT_RELOC(internal, howto) {internal.r_type = howto->type;}
+
+#define COFF_PAGE_SIZE 0x1000
+
+#include "coffcode.h"
+
+static const bfd_target *
+pe_object_p (abfd)
+ bfd * abfd;
+{
+#ifdef COFF_IMAGE_WITH_PE
+ /* We need to hack badly to handle a PE image correctly. In PE
+ images created by the GNU linker, the offset to the COFF header
+ is always the size. However, this is not the case in images
+ generated by other PE linkers. The PE format stores a four byte
+ offset to the PE signature just before the COFF header at
+ location 0x3c of the file. We pick up that offset, verify that
+ the PE signature is there, and then set ourselves up to read in
+ the COFF header. */
+ {
+ bfd_byte ext_offset[4];
+ file_ptr offset;
+ bfd_byte ext_signature[4];
+ unsigned long signature;
+
+ if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
+ || bfd_read (ext_offset, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ offset = bfd_h_get_32 (abfd, ext_offset);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || bfd_read (ext_signature, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+
+ return NULL;
+ }
+
+ signature = bfd_h_get_32 (abfd, ext_signature);
+
+ if (signature != 0x4550)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Here is the hack. coff_object_p wants to read filhsz bytes to
+ pick up the COFF header. We adjust so that that will work. 20
+ is the size of the mips COFF filehdr. */
+ if (bfd_seek (abfd, (bfd_tell (abfd) - bfd_coff_filhsz (abfd) + 20),
+ SEEK_SET) != 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+
+ return NULL;
+ }
+ }
+#endif
+
+ return coff_object_p (abfd);
+}
+
+/* The transfer vectors that lead the outside world to all of the above. */
+
+const bfd_target
+TARGET_BIG_SYM =
+{
+ TARGET_BIG_NAME,
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ { _bfd_dummy_target,
+ pe_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, /* _bfd_dummy_target */
+ pe_object_p
+ },
+ { bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false
+ },
+ { bfd_false,
+ coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents,
+ bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+
+const bfd_target
+TARGET_LITTLE_SYM =
+{
+ TARGET_LITTLE_NAME,
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+
+ 0, /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+ {
+ _bfd_dummy_target,
+ pe_object_p, /* bfd_check_format */
+ bfd_generic_archive_p,
+ pe_object_p
+ },
+ {
+ bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false
+ },
+ {
+ bfd_false,
+ coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents,
+ bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
new file mode 100644
index 00000000000..051eb86b166
--- /dev/null
+++ b/bfd/coff-mips.c
@@ -0,0 +1,2726 @@
+/* BFD back-end for MIPS Extended-Coff files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Original version by Per Bothner.
+ Full support added by Ian Lance Taylor, ian@cygnus.com.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff.h"
+#include "coff/mips.h"
+#include "libcoff.h"
+#include "libecoff.h"
+
+/* Prototypes for static functions. */
+
+static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
+static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
+ struct internal_reloc *));
+static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
+ const struct internal_reloc *,
+ PTR));
+static void mips_adjust_reloc_in PARAMS ((bfd *,
+ const struct internal_reloc *,
+ arelent *));
+static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *,
+ struct internal_reloc *));
+static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static bfd_reloc_status_type mips_relhi_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static bfd_reloc_status_type mips_rello_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static bfd_reloc_status_type mips_switch_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+static void mips_relocate_hi PARAMS ((struct internal_reloc *refhi,
+ struct internal_reloc *reflo,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ size_t adjust,
+ bfd_vma relocation,
+ boolean pcrel));
+static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
+ bfd *, asection *,
+ bfd_byte *, PTR));
+static boolean mips_read_relocs PARAMS ((bfd *, asection *));
+static boolean mips_relax_section PARAMS ((bfd *, asection *,
+ struct bfd_link_info *,
+ boolean *));
+static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *,
+ asection *,
+ struct ecoff_link_hash_entry *,
+ bfd_byte *, bfd_vma));
+static reloc_howto_type *mips_bfd_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+
+
+/* ECOFF has COFF sections, but the debugging information is stored in
+ a completely different format. ECOFF targets use some of the
+ swapping routines from coffswap.h, and some of the generic COFF
+ routines in coffgen.c, but, unlike the real COFF targets, do not
+ use coffcode.h itself.
+
+ Get the generic COFF swapping routines, except for the reloc,
+ symbol, and lineno ones. Give them ECOFF names. */
+#define MIPSECOFF
+#define NO_COFF_RELOCS
+#define NO_COFF_SYMBOLS
+#define NO_COFF_LINENOS
+#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
+#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
+#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
+#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
+#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
+#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
+#include "coffswap.h"
+
+/* Get the ECOFF swapping routines. */
+#define ECOFF_32
+#include "ecoffswap.h"
+
+/* How to process the various relocs types. */
+
+static reloc_howto_type mips_howto_table[] =
+{
+ /* Reloc type 0 is ignored. The reloc reading code ensures that
+ this is a reference to the .abs section, which will cause
+ bfd_perform_relocation to do nothing. */
+ HOWTO (MIPS_R_IGNORE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "IGNORE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 16 bit reference to a symbol, normally from a data section. */
+ HOWTO (MIPS_R_REFHALF, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mips_generic_reloc, /* special_function */
+ "REFHALF", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit reference to a symbol, normally from a data section. */
+ HOWTO (MIPS_R_REFWORD, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mips_generic_reloc, /* special_function */
+ "REFWORD", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 26 bit absolute jump address. */
+ HOWTO (MIPS_R_JMPADDR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ /* This needs complex overflow
+ detection, because the upper four
+ bits must match the PC. */
+ mips_generic_reloc, /* special_function */
+ "JMPADDR", /* name */
+ true, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high 16 bits of a symbol value. Handled by the function
+ mips_refhi_reloc. */
+ HOWTO (MIPS_R_REFHI, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mips_refhi_reloc, /* special_function */
+ "REFHI", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The low 16 bits of a symbol value. */
+ HOWTO (MIPS_R_REFLO, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ mips_reflo_reloc, /* special_function */
+ "REFLO", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A reference to an offset from the gp register. Handled by the
+ function mips_gprel_reloc. */
+ HOWTO (MIPS_R_GPREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mips_gprel_reloc, /* special_function */
+ "GPREL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A reference to a literal using an offset from the gp register.
+ Handled by the function mips_gprel_reloc. */
+ HOWTO (MIPS_R_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mips_gprel_reloc, /* special_function */
+ "LITERAL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 8 },
+ { 9 },
+ { 10 },
+ { 11 },
+
+ /* This reloc is a Cygnus extension used when generating position
+ independent code for embedded systems. It represents a 16 bit PC
+ relative reloc rightshifted twice as used in the MIPS branch
+ instructions. */
+ HOWTO (MIPS_R_PCREL16, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mips_generic_reloc, /* special_function */
+ "PCREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* This reloc is a Cygnus extension used when generating position
+ independent code for embedded systems. It represents the high 16
+ bits of a PC relative reloc. The next reloc must be
+ MIPS_R_RELLO, and the addend is formed from the addends of the
+ two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO. The
+ final value is actually PC relative to the location of the
+ MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc. */
+ HOWTO (MIPS_R_RELHI, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mips_relhi_reloc, /* special_function */
+ "RELHI", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* This reloc is a Cygnus extension used when generating position
+ independent code for embedded systems. It represents the low 16
+ bits of a PC relative reloc. */
+ HOWTO (MIPS_R_RELLO, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ mips_rello_reloc, /* special_function */
+ "RELLO", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ { 15 },
+ { 16 },
+ { 17 },
+ { 18 },
+ { 19 },
+ { 20 },
+ { 21 },
+
+ /* This reloc is a Cygnus extension used when generating position
+ independent code for embedded systems. It represents an entry in
+ a switch table, which is the difference between two symbols in
+ the .text section. The symndx is actually the offset from the
+ reloc address to the subtrahend. See include/coff/mips.h for
+ more details. */
+ HOWTO (MIPS_R_SWITCH, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ mips_switch_reloc, /* special_function */
+ "SWITCH", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true) /* pcrel_offset */
+};
+
+#define MIPS_HOWTO_COUNT \
+ (sizeof mips_howto_table / sizeof mips_howto_table[0])
+
+/* When the linker is doing relaxing, it may change a external PCREL16
+ reloc. This typically represents an instruction like
+ bal foo
+ We change it to
+ .set noreorder
+ bal $L1
+ lui $at,%hi(foo - $L1)
+ $L1:
+ addiu $at,%lo(foo - $L1)
+ addu $at,$at,$31
+ jalr $at
+ PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the
+ instruction by. */
+
+#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)
+
+/* See whether the magic number matches. */
+
+static boolean
+mips_ecoff_bad_format_hook (abfd, filehdr)
+ bfd *abfd;
+ PTR filehdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ switch (internal_f->f_magic)
+ {
+ case MIPS_MAGIC_1:
+ /* I don't know what endianness this implies. */
+ return true;
+
+ case MIPS_MAGIC_BIG:
+ case MIPS_MAGIC_BIG2:
+ case MIPS_MAGIC_BIG3:
+ return bfd_big_endian (abfd);
+
+ case MIPS_MAGIC_LITTLE:
+ case MIPS_MAGIC_LITTLE2:
+ case MIPS_MAGIC_LITTLE3:
+ return bfd_little_endian (abfd);
+
+ default:
+ return false;
+ }
+}
+
+/* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
+ external form. They use a bit which indicates whether the symbol
+ is external. */
+
+/* Swap a reloc in. */
+
+static void
+mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
+ bfd *abfd;
+ PTR ext_ptr;
+ struct internal_reloc *intern;
+{
+ const RELOC *ext = (RELOC *) ext_ptr;
+
+ intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
+ if (bfd_header_big_endian (abfd))
+ {
+ intern->r_symndx = (((int) ext->r_bits[0]
+ << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
+ | ((int) ext->r_bits[1]
+ << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
+ | ((int) ext->r_bits[2]
+ << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
+ intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
+ >> RELOC_BITS3_TYPE_SH_BIG);
+ intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
+ }
+ else
+ {
+ intern->r_symndx = (((int) ext->r_bits[0]
+ << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
+ | ((int) ext->r_bits[1]
+ << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
+ | ((int) ext->r_bits[2]
+ << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
+ intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
+ >> RELOC_BITS3_TYPE_SH_LITTLE)
+ | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
+ << RELOC_BITS3_TYPEHI_SH_LITTLE));
+ intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
+ }
+
+ /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
+ MIPS_R_RELLO reloc, r_symndx is actually the offset from the
+ reloc address to the base of the difference (see
+ include/coff/mips.h for more details). We copy symndx into the
+ r_offset field so as not to confuse ecoff_slurp_reloc_table in
+ ecoff.c. In adjust_reloc_in we then copy r_offset into the reloc
+ addend. */
+ if (intern->r_type == MIPS_R_SWITCH
+ || (! intern->r_extern
+ && (intern->r_type == MIPS_R_RELLO
+ || intern->r_type == MIPS_R_RELHI)))
+ {
+ BFD_ASSERT (! intern->r_extern);
+ intern->r_offset = intern->r_symndx;
+ if (intern->r_offset & 0x800000)
+ intern->r_offset -= 0x1000000;
+ intern->r_symndx = RELOC_SECTION_TEXT;
+ }
+}
+
+/* Swap a reloc out. */
+
+static void
+mips_ecoff_swap_reloc_out (abfd, intern, dst)
+ bfd *abfd;
+ const struct internal_reloc *intern;
+ PTR dst;
+{
+ RELOC *ext = (RELOC *) dst;
+ long r_symndx;
+
+ BFD_ASSERT (intern->r_extern
+ || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
+
+ /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or
+ MIPS_R_RELHI reloc, we actually want to write the contents of
+ r_offset out as the symbol index. This undoes the change made by
+ mips_ecoff_swap_reloc_in. */
+ if (intern->r_type != MIPS_R_SWITCH
+ && (intern->r_extern
+ || (intern->r_type != MIPS_R_RELHI
+ && intern->r_type != MIPS_R_RELLO)))
+ r_symndx = intern->r_symndx;
+ else
+ {
+ BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT);
+ r_symndx = intern->r_offset & 0xffffff;
+ }
+
+ bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
+ if (bfd_header_big_endian (abfd))
+ {
+ ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
+ ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
+ ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
+ ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
+ & RELOC_BITS3_TYPE_BIG)
+ | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
+ }
+ else
+ {
+ ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
+ ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
+ ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
+ ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
+ & RELOC_BITS3_TYPE_LITTLE)
+ | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
+ & RELOC_BITS3_TYPEHI_LITTLE))
+ | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
+ }
+}
+
+/* Finish canonicalizing a reloc. Part of this is generic to all
+ ECOFF targets, and that part is in ecoff.c. The rest is done in
+ this backend routine. It must fill in the howto field. */
+
+static void
+mips_adjust_reloc_in (abfd, intern, rptr)
+ bfd *abfd;
+ const struct internal_reloc *intern;
+ arelent *rptr;
+{
+ if (intern->r_type > MIPS_R_SWITCH)
+ abort ();
+
+ if (! intern->r_extern
+ && (intern->r_type == MIPS_R_GPREL
+ || intern->r_type == MIPS_R_LITERAL))
+ rptr->addend += ecoff_data (abfd)->gp;
+
+ /* If the type is MIPS_R_IGNORE, make sure this is a reference to
+ the absolute section so that the reloc is ignored. */
+ if (intern->r_type == MIPS_R_IGNORE)
+ rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+
+ /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
+ MIPS_R_RELLO reloc, we want the addend field of the BFD relocto
+ hold the value which was originally in the symndx field of the
+ internal MIPS ECOFF reloc. This value was copied into
+ intern->r_offset by mips_swap_reloc_in, and here we copy it into
+ the addend field. */
+ if (intern->r_type == MIPS_R_SWITCH
+ || (! intern->r_extern
+ && (intern->r_type == MIPS_R_RELHI
+ || intern->r_type == MIPS_R_RELLO)))
+ rptr->addend = intern->r_offset;
+
+ rptr->howto = &mips_howto_table[intern->r_type];
+}
+
+/* Make any adjustments needed to a reloc before writing it out. None
+ are needed for MIPS. */
+
+static void
+mips_adjust_reloc_out (abfd, rel, intern)
+ bfd *abfd;
+ const arelent *rel;
+ struct internal_reloc *intern;
+{
+ /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
+ MIPS_R_RELLO reloc, we must copy rel->addend into
+ intern->r_offset. This will then be written out as the symbol
+ index by mips_ecoff_swap_reloc_out. This operation parallels the
+ action of mips_adjust_reloc_in. */
+ if (intern->r_type == MIPS_R_SWITCH
+ || (! intern->r_extern
+ && (intern->r_type == MIPS_R_RELHI
+ || intern->r_type == MIPS_R_RELLO)))
+ intern->r_offset = rel->addend;
+}
+
+/* ECOFF relocs are either against external symbols, or against
+ sections. If we are producing relocateable output, and the reloc
+ is against an external symbol, and nothing has given us any
+ additional addend, the resulting reloc will also be against the
+ same symbol. In such a case, we don't want to change anything
+ about the way the reloc is handled, since it will all be done at
+ final link time. Rather than put special case code into
+ bfd_perform_relocation, all the reloc types use this howto
+ function. It just short circuits the reloc if producing
+ relocateable output against an external symbol. */
+
+static bfd_reloc_status_type
+mips_generic_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ return bfd_reloc_continue;
+}
+
+/* Do a REFHI relocation. This has to be done in combination with a
+ REFLO reloc, because there is a carry from the REFLO to the REFHI.
+ Here we just save the information we need; we do the actual
+ relocation when we see the REFLO. MIPS ECOFF requires that the
+ REFLO immediately follow the REFHI. As a GNU extension, we permit
+ an arbitrary number of HI relocs to be associated with a single LO
+ reloc. This extension permits gcc to output the HI and LO relocs
+ itself. */
+
+struct mips_hi
+{
+ struct mips_hi *next;
+ bfd_byte *addr;
+ bfd_vma addend;
+};
+
+/* FIXME: This should not be a static variable. */
+
+static struct mips_hi *mips_refhi_list;
+
+static bfd_reloc_status_type
+mips_refhi_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ struct mips_hi *n;
+
+ /* If we're relocating, and this an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ ret = bfd_reloc_ok;
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ ret = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Save the information, and let REFLO do the actual relocation. */
+ n = (struct mips_hi *) bfd_malloc (sizeof *n);
+ if (n == NULL)
+ return bfd_reloc_outofrange;
+ n->addr = (bfd_byte *) data + reloc_entry->address;
+ n->addend = relocation;
+ n->next = mips_refhi_list;
+ mips_refhi_list = n;
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Do a REFLO relocation. This is a straightforward 16 bit inplace
+ relocation; this function exists in order to do the REFHI
+ relocation described above. */
+
+static bfd_reloc_status_type
+mips_reflo_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (mips_refhi_list != NULL)
+ {
+ struct mips_hi *l;
+
+ l = mips_refhi_list;
+ while (l != NULL)
+ {
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+ struct mips_hi *next;
+
+ /* Do the REFHI relocation. Note that we actually don't
+ need to know anything about the REFLO itself, except
+ where to find the low 16 bits of the addend needed by the
+ REFHI. */
+ insn = bfd_get_32 (abfd, l->addr);
+ vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
+ & 0xffff);
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += l->addend;
+
+ /* The low order 16 bits are always treated as a signed
+ value. Therefore, a negative value in the low order bits
+ requires an adjustment in the high order bits. We need
+ to make this adjustment in two ways: once for the bits we
+ took from the data, and once for the bits we are putting
+ back in to the data. */
+ if ((vallo & 0x8000) != 0)
+ val -= 0x10000;
+ if ((val & 0x8000) != 0)
+ val += 0x10000;
+
+ insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (abfd, insn, l->addr);
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ mips_refhi_list = NULL;
+ }
+
+ /* Now do the REFLO reloc in the usual way. */
+ return mips_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* Do a GPREL relocation. This is a 16 bit value which must become
+ the offset from the gp register. */
+
+static bfd_reloc_status_type
+mips_gprel_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ boolean relocateable;
+ bfd_vma gp;
+ bfd_vma relocation;
+ unsigned long val;
+ unsigned long insn;
+
+ /* If we're relocating, and this is an external symbol with no
+ addend, we don't want to change anything. We will only have an
+ addend if this is a newly created reloc, not read from an ECOFF
+ file. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ relocateable = true;
+ else
+ {
+ relocateable = false;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ if (bfd_is_und_section (symbol->section)
+ && relocateable == false)
+ return bfd_reloc_undefined;
+
+ /* We have to figure out the gp value, so that we can adjust the
+ symbol value correctly. We look up the symbol _gp in the output
+ BFD. If we can't find it, we're stuck. We cache it in the ECOFF
+ target data. We don't need to adjust the symbol value for an
+ external symbol if we are producing relocateable output. */
+ gp = _bfd_get_gp_value (output_bfd);
+ if (gp == 0
+ && (relocateable == false
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocateable != false)
+ {
+ /* Make up a value. */
+ gp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, gp);
+ }
+ else
+ {
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ if (sym == (asymbol **) NULL)
+ i = count;
+ else
+ {
+ for (i = 0; i < count; i++, sym++)
+ {
+ register CONST char *name;
+
+ name = bfd_asymbol_name (*sym);
+ if (*name == '_' && strcmp (name, "_gp") == 0)
+ {
+ gp = bfd_asymbol_value (*sym);
+ _bfd_set_gp_value (output_bfd, gp);
+ break;
+ }
+ }
+ }
+
+ if (i >= count)
+ {
+ /* Only get the error once. */
+ gp = 4;
+ _bfd_set_gp_value (output_bfd, gp);
+ *error_message =
+ (char *) _("GP relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+ }
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Set val to the offset into the section or symbol. */
+ val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
+ if (val & 0x8000)
+ val -= 0x10000;
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocateable output, we don't want to do this for
+ an external symbol. */
+ if (relocateable == false
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ insn = (insn &~ 0xffff) | (val & 0xffff);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if (relocateable != false)
+ reloc_entry->address += input_section->output_offset;
+
+ /* Make sure it fit in 16 bits. */
+ if (val >= 0x8000 && val < 0xffff8000)
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_ok;
+}
+
+/* Do a RELHI relocation. We do this in conjunction with a RELLO
+ reloc, just as REFHI and REFLO are done together. RELHI and RELLO
+ are Cygnus extensions used when generating position independent
+ code for embedded systems. */
+
+/* FIXME: This should not be a static variable. */
+
+static struct mips_hi *mips_relhi_list;
+
+static bfd_reloc_status_type
+mips_relhi_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ struct mips_hi *n;
+
+ /* If this is a reloc against a section symbol, then it is correct
+ in the object file. The only time we want to change this case is
+ when we are relaxing, and that is handled entirely by
+ mips_relocate_section and never calls this function. */
+ if ((symbol->flags & BSF_SECTION_SYM) != 0)
+ {
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* This is an external symbol. If we're relocating, we don't want
+ to change anything. */
+ if (output_bfd != (bfd *) NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ ret = bfd_reloc_ok;
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ ret = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Save the information, and let RELLO do the actual relocation. */
+ n = (struct mips_hi *) bfd_malloc (sizeof *n);
+ if (n == NULL)
+ return bfd_reloc_outofrange;
+ n->addr = (bfd_byte *) data + reloc_entry->address;
+ n->addend = relocation;
+ n->next = mips_relhi_list;
+ mips_relhi_list = n;
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Do a RELLO relocation. This is a straightforward 16 bit PC
+ relative relocation; this function exists in order to do the RELHI
+ relocation described above. */
+
+static bfd_reloc_status_type
+mips_rello_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (mips_relhi_list != NULL)
+ {
+ struct mips_hi *l;
+
+ l = mips_relhi_list;
+ while (l != NULL)
+ {
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+ struct mips_hi *next;
+
+ /* Do the RELHI relocation. Note that we actually don't
+ need to know anything about the RELLO itself, except
+ where to find the low 16 bits of the addend needed by the
+ RELHI. */
+ insn = bfd_get_32 (abfd, l->addr);
+ vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
+ & 0xffff);
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += l->addend;
+
+ /* If the symbol is defined, make val PC relative. If the
+ symbol is not defined we don't want to do this, because
+ we don't want the value in the object file to incorporate
+ the address of the reloc. */
+ if (! bfd_is_und_section (bfd_get_section (symbol))
+ && ! bfd_is_com_section (bfd_get_section (symbol)))
+ val -= (input_section->output_section->vma
+ + input_section->output_offset
+ + reloc_entry->address);
+
+ /* The low order 16 bits are always treated as a signed
+ value. Therefore, a negative value in the low order bits
+ requires an adjustment in the high order bits. We need
+ to make this adjustment in two ways: once for the bits we
+ took from the data, and once for the bits we are putting
+ back in to the data. */
+ if ((vallo & 0x8000) != 0)
+ val -= 0x10000;
+ if ((val & 0x8000) != 0)
+ val += 0x10000;
+
+ insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (abfd, insn, l->addr);
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ mips_relhi_list = NULL;
+ }
+
+ /* If this is a reloc against a section symbol, then it is correct
+ in the object file. The only time we want to change this case is
+ when we are relaxing, and that is handled entirely by
+ mips_relocate_section and never calls this function. */
+ if ((symbol->flags & BSF_SECTION_SYM) != 0)
+ {
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* bfd_perform_relocation does not handle pcrel_offset relocations
+ correctly when generating a relocateable file, so handle them
+ directly here. */
+ if (output_bfd != (bfd *) NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Now do the RELLO reloc in the usual way. */
+ return mips_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* This is the special function for the MIPS_R_SWITCH reloc. This
+ special reloc is normally correct in the object file, and only
+ requires special handling when relaxing. We don't want
+ bfd_perform_relocation to tamper with it at all. */
+
+/*ARGSUSED*/
+static bfd_reloc_status_type
+mips_switch_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return bfd_reloc_ok;
+}
+
+/* Get the howto structure for a generic reloc type. */
+
+static reloc_howto_type *
+mips_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ int mips_type;
+
+ switch (code)
+ {
+ case BFD_RELOC_16:
+ mips_type = MIPS_R_REFHALF;
+ break;
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ mips_type = MIPS_R_REFWORD;
+ break;
+ case BFD_RELOC_MIPS_JMP:
+ mips_type = MIPS_R_JMPADDR;
+ break;
+ case BFD_RELOC_HI16_S:
+ mips_type = MIPS_R_REFHI;
+ break;
+ case BFD_RELOC_LO16:
+ mips_type = MIPS_R_REFLO;
+ break;
+ case BFD_RELOC_MIPS_GPREL:
+ mips_type = MIPS_R_GPREL;
+ break;
+ case BFD_RELOC_MIPS_LITERAL:
+ mips_type = MIPS_R_LITERAL;
+ break;
+ case BFD_RELOC_16_PCREL_S2:
+ mips_type = MIPS_R_PCREL16;
+ break;
+ case BFD_RELOC_PCREL_HI16_S:
+ mips_type = MIPS_R_RELHI;
+ break;
+ case BFD_RELOC_PCREL_LO16:
+ mips_type = MIPS_R_RELLO;
+ break;
+ case BFD_RELOC_GPREL32:
+ mips_type = MIPS_R_SWITCH;
+ break;
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+
+ return &mips_howto_table[mips_type];
+}
+
+/* A helper routine for mips_relocate_section which handles the REFHI
+ and RELHI relocations. The REFHI relocation must be followed by a
+ REFLO relocation (and RELHI by a RELLO), and the addend used is
+ formed from the addends of both instructions. */
+
+static void
+mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
+ relocation, pcrel)
+ struct internal_reloc *refhi;
+ struct internal_reloc *reflo;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ size_t adjust;
+ bfd_vma relocation;
+ boolean pcrel;
+{
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+
+ if (refhi == NULL)
+ return;
+
+ insn = bfd_get_32 (input_bfd,
+ contents + adjust + refhi->r_vaddr - input_section->vma);
+ if (reflo == NULL)
+ vallo = 0;
+ else
+ vallo = (bfd_get_32 (input_bfd,
+ contents + adjust + reflo->r_vaddr - input_section->vma)
+ & 0xffff);
+
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += relocation;
+
+ /* The low order 16 bits are always treated as a signed value.
+ Therefore, a negative value in the low order bits requires an
+ adjustment in the high order bits. We need to make this
+ adjustment in two ways: once for the bits we took from the data,
+ and once for the bits we are putting back in to the data. */
+ if ((vallo & 0x8000) != 0)
+ val -= 0x10000;
+
+ if (pcrel)
+ val -= (input_section->output_section->vma
+ + input_section->output_offset
+ + (reflo->r_vaddr - input_section->vma + adjust));
+
+ if ((val & 0x8000) != 0)
+ val += 0x10000;
+
+ insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (input_bfd, (bfd_vma) insn,
+ contents + adjust + refhi->r_vaddr - input_section->vma);
+}
+
+/* Relocate a section while linking a MIPS ECOFF file. */
+
+static boolean
+mips_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, external_relocs)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ PTR external_relocs;
+{
+ asection **symndx_to_section;
+ struct ecoff_link_hash_entry **sym_hashes;
+ bfd_vma gp;
+ boolean gp_undefined;
+ size_t adjust;
+ long *offsets;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+ unsigned int i;
+ boolean got_lo;
+ struct internal_reloc lo_int_rel;
+
+ BFD_ASSERT (input_bfd->xvec->byteorder
+ == output_bfd->xvec->byteorder);
+
+ /* We keep a table mapping the symndx found in an internal reloc to
+ the appropriate section. This is faster than looking up the
+ section by name each time. */
+ symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
+ if (symndx_to_section == (asection **) NULL)
+ {
+ symndx_to_section = ((asection **)
+ bfd_alloc (input_bfd,
+ (NUM_RELOC_SECTIONS
+ * sizeof (asection *))));
+ if (!symndx_to_section)
+ return false;
+
+ symndx_to_section[RELOC_SECTION_NONE] = NULL;
+ symndx_to_section[RELOC_SECTION_TEXT] =
+ bfd_get_section_by_name (input_bfd, ".text");
+ symndx_to_section[RELOC_SECTION_RDATA] =
+ bfd_get_section_by_name (input_bfd, ".rdata");
+ symndx_to_section[RELOC_SECTION_DATA] =
+ bfd_get_section_by_name (input_bfd, ".data");
+ symndx_to_section[RELOC_SECTION_SDATA] =
+ bfd_get_section_by_name (input_bfd, ".sdata");
+ symndx_to_section[RELOC_SECTION_SBSS] =
+ bfd_get_section_by_name (input_bfd, ".sbss");
+ symndx_to_section[RELOC_SECTION_BSS] =
+ bfd_get_section_by_name (input_bfd, ".bss");
+ symndx_to_section[RELOC_SECTION_INIT] =
+ bfd_get_section_by_name (input_bfd, ".init");
+ symndx_to_section[RELOC_SECTION_LIT8] =
+ bfd_get_section_by_name (input_bfd, ".lit8");
+ symndx_to_section[RELOC_SECTION_LIT4] =
+ bfd_get_section_by_name (input_bfd, ".lit4");
+ symndx_to_section[RELOC_SECTION_XDATA] = NULL;
+ symndx_to_section[RELOC_SECTION_PDATA] = NULL;
+ symndx_to_section[RELOC_SECTION_FINI] =
+ bfd_get_section_by_name (input_bfd, ".fini");
+ symndx_to_section[RELOC_SECTION_LITA] = NULL;
+ symndx_to_section[RELOC_SECTION_ABS] = NULL;
+
+ ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
+ }
+
+ sym_hashes = ecoff_data (input_bfd)->sym_hashes;
+
+ gp = _bfd_get_gp_value (output_bfd);
+ if (gp == 0)
+ gp_undefined = true;
+ else
+ gp_undefined = false;
+
+ got_lo = false;
+
+ adjust = 0;
+
+ if (ecoff_section_data (input_bfd, input_section) == NULL)
+ offsets = NULL;
+ else
+ offsets = ecoff_section_data (input_bfd, input_section)->offsets;
+
+ ext_rel = (struct external_reloc *) external_relocs;
+ ext_rel_end = ext_rel + input_section->reloc_count;
+ for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
+ {
+ struct internal_reloc int_rel;
+ boolean use_lo = false;
+ bfd_vma addend;
+ reloc_howto_type *howto;
+ struct ecoff_link_hash_entry *h = NULL;
+ asection *s = NULL;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ if (! got_lo)
+ mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
+ else
+ {
+ int_rel = lo_int_rel;
+ got_lo = false;
+ }
+
+ BFD_ASSERT (int_rel.r_type
+ < sizeof mips_howto_table / sizeof mips_howto_table[0]);
+
+ /* The REFHI and RELHI relocs requires special handling. they
+ must be followed by a REFLO or RELLO reloc, respectively, and
+ the addend is formed from both relocs. */
+ if (int_rel.r_type == MIPS_R_REFHI
+ || int_rel.r_type == MIPS_R_RELHI)
+ {
+ struct external_reloc *lo_ext_rel;
+
+ /* As a GNU extension, permit an arbitrary number of REFHI
+ or RELHI relocs before the REFLO or RELLO reloc. This
+ permits gcc to emit the HI and LO relocs itself. */
+ for (lo_ext_rel = ext_rel + 1;
+ lo_ext_rel < ext_rel_end;
+ lo_ext_rel++)
+ {
+ mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
+ &lo_int_rel);
+ if (lo_int_rel.r_type != int_rel.r_type)
+ break;
+ }
+
+ if (lo_ext_rel < ext_rel_end
+ && (lo_int_rel.r_type
+ == (int_rel.r_type == MIPS_R_REFHI
+ ? MIPS_R_REFLO
+ : MIPS_R_RELLO))
+ && int_rel.r_extern == lo_int_rel.r_extern
+ && int_rel.r_symndx == lo_int_rel.r_symndx)
+ {
+ use_lo = true;
+ if (lo_ext_rel == ext_rel + 1)
+ got_lo = true;
+ }
+ }
+
+ howto = &mips_howto_table[int_rel.r_type];
+
+ /* The SWITCH reloc must be handled specially. This reloc is
+ marks the location of a difference between two portions of an
+ object file. The symbol index does not reference a symbol,
+ but is actually the offset from the reloc to the subtrahend
+ of the difference. This reloc is correct in the object file,
+ and needs no further adjustment, unless we are relaxing. If
+ we are relaxing, we may have to add in an offset. Since no
+ symbols are involved in this reloc, we handle it completely
+ here. */
+ if (int_rel.r_type == MIPS_R_SWITCH)
+ {
+ if (offsets != NULL
+ && offsets[i] != 0)
+ {
+ r = _bfd_relocate_contents (howto, input_bfd,
+ (bfd_vma) offsets[i],
+ (contents
+ + adjust
+ + int_rel.r_vaddr
+ - input_section->vma));
+ BFD_ASSERT (r == bfd_reloc_ok);
+ }
+
+ continue;
+ }
+
+ if (int_rel.r_extern)
+ {
+ h = sym_hashes[int_rel.r_symndx];
+ /* If h is NULL, that means that there is a reloc against an
+ external symbol which we thought was just a debugging
+ symbol. This should not happen. */
+ if (h == (struct ecoff_link_hash_entry *) NULL)
+ abort ();
+ }
+ else
+ {
+ if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
+ s = NULL;
+ else
+ s = symndx_to_section[int_rel.r_symndx];
+
+ if (s == (asection *) NULL)
+ abort ();
+ }
+
+ /* The GPREL reloc uses an addend: the difference in the GP
+ values. */
+ if (int_rel.r_type != MIPS_R_GPREL
+ && int_rel.r_type != MIPS_R_LITERAL)
+ addend = 0;
+ else
+ {
+ if (gp_undefined)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info, _("GP relative relocation when GP not defined"),
+ input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ /* Only give the error once per link. */
+ gp = 4;
+ _bfd_set_gp_value (output_bfd, gp);
+ gp_undefined = false;
+ }
+ if (! int_rel.r_extern)
+ {
+ /* This is a relocation against a section. The current
+ addend in the instruction is the difference between
+ INPUT_SECTION->vma and the GP value of INPUT_BFD. We
+ must change this to be the difference between the
+ final definition (which will end up in RELOCATION)
+ and the GP value of OUTPUT_BFD (which is in GP). */
+ addend = ecoff_data (input_bfd)->gp - gp;
+ }
+ else if (! info->relocateable
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ /* This is a relocation against a defined symbol. The
+ current addend in the instruction is simply the
+ desired offset into the symbol (normally zero). We
+ are going to change this into a relocation against a
+ defined symbol, so we want the instruction to hold
+ the difference between the final definition of the
+ symbol (which will end up in RELOCATION) and the GP
+ value of OUTPUT_BFD (which is in GP). */
+ addend = - gp;
+ }
+ else
+ {
+ /* This is a relocation against an undefined or common
+ symbol. The current addend in the instruction is
+ simply the desired offset into the symbol (normally
+ zero). We are generating relocateable output, and we
+ aren't going to define this symbol, so we just leave
+ the instruction alone. */
+ addend = 0;
+ }
+ }
+
+ /* If we are relaxing, mips_relax_section may have set
+ offsets[i] to some value. A value of 1 means we must expand
+ a PC relative branch into a multi-instruction of sequence,
+ and any other value is an addend. */
+ if (offsets != NULL
+ && offsets[i] != 0)
+ {
+ BFD_ASSERT (! info->relocateable);
+ BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16
+ || int_rel.r_type == MIPS_R_RELHI
+ || int_rel.r_type == MIPS_R_RELLO);
+ if (offsets[i] != 1)
+ addend += offsets[i];
+ else
+ {
+ bfd_byte *here;
+
+ BFD_ASSERT (int_rel.r_extern
+ && int_rel.r_type == MIPS_R_PCREL16);
+
+ /* Move the rest of the instructions up. */
+ here = (contents
+ + adjust
+ + int_rel.r_vaddr
+ - input_section->vma);
+ memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
+ (size_t) (input_section->_raw_size
+ - (int_rel.r_vaddr - input_section->vma)));
+
+ /* Generate the new instructions. */
+ if (! mips_relax_pcrel16 (info, input_bfd, input_section,
+ h, here,
+ (input_section->output_section->vma
+ + input_section->output_offset
+ + (int_rel.r_vaddr
+ - input_section->vma)
+ + adjust)))
+ return false;
+
+ /* We must adjust everything else up a notch. */
+ adjust += PCREL16_EXPANSION_ADJUSTMENT;
+
+ /* mips_relax_pcrel16 handles all the details of this
+ relocation. */
+ continue;
+ }
+ }
+
+ /* If we are relaxing, and this is a reloc against the .text
+ segment, we may need to adjust it if some branches have been
+ expanded. The reloc types which are likely to occur in the
+ .text section are handled efficiently by mips_relax_section,
+ and thus do not need to be handled here. */
+ if (ecoff_data (input_bfd)->debug_info.adjust != NULL
+ && ! int_rel.r_extern
+ && int_rel.r_symndx == RELOC_SECTION_TEXT
+ && (strcmp (bfd_get_section_name (input_bfd, input_section),
+ ".text") != 0
+ || (int_rel.r_type != MIPS_R_PCREL16
+ && int_rel.r_type != MIPS_R_SWITCH
+ && int_rel.r_type != MIPS_R_RELHI
+ && int_rel.r_type != MIPS_R_RELLO)))
+ {
+ bfd_vma adr;
+ struct ecoff_value_adjust *a;
+
+ /* We need to get the addend so that we know whether we need
+ to adjust the address. */
+ BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
+
+ adr = bfd_get_32 (input_bfd,
+ (contents
+ + adjust
+ + int_rel.r_vaddr
+ - input_section->vma));
+
+ for (a = ecoff_data (input_bfd)->debug_info.adjust;
+ a != (struct ecoff_value_adjust *) NULL;
+ a = a->next)
+ {
+ if (adr >= a->start && adr < a->end)
+ addend += a->adjust;
+ }
+ }
+
+ if (info->relocateable)
+ {
+ /* We are generating relocateable output, and must convert
+ the existing reloc. */
+ if (int_rel.r_extern)
+ {
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && ! bfd_is_abs_section (h->root.u.def.section))
+ {
+ const char *name;
+
+ /* This symbol is defined in the output. Convert
+ the reloc from being against the symbol to being
+ against the section. */
+
+ /* Clear the r_extern bit. */
+ int_rel.r_extern = 0;
+
+ /* Compute a new r_symndx value. */
+ s = h->root.u.def.section;
+ name = bfd_get_section_name (output_bfd,
+ s->output_section);
+
+ int_rel.r_symndx = -1;
+ switch (name[1])
+ {
+ case 'b':
+ if (strcmp (name, ".bss") == 0)
+ int_rel.r_symndx = RELOC_SECTION_BSS;
+ break;
+ case 'd':
+ if (strcmp (name, ".data") == 0)
+ int_rel.r_symndx = RELOC_SECTION_DATA;
+ break;
+ case 'f':
+ if (strcmp (name, ".fini") == 0)
+ int_rel.r_symndx = RELOC_SECTION_FINI;
+ break;
+ case 'i':
+ if (strcmp (name, ".init") == 0)
+ int_rel.r_symndx = RELOC_SECTION_INIT;
+ break;
+ case 'l':
+ if (strcmp (name, ".lit8") == 0)
+ int_rel.r_symndx = RELOC_SECTION_LIT8;
+ else if (strcmp (name, ".lit4") == 0)
+ int_rel.r_symndx = RELOC_SECTION_LIT4;
+ break;
+ case 'r':
+ if (strcmp (name, ".rdata") == 0)
+ int_rel.r_symndx = RELOC_SECTION_RDATA;
+ break;
+ case 's':
+ if (strcmp (name, ".sdata") == 0)
+ int_rel.r_symndx = RELOC_SECTION_SDATA;
+ else if (strcmp (name, ".sbss") == 0)
+ int_rel.r_symndx = RELOC_SECTION_SBSS;
+ break;
+ case 't':
+ if (strcmp (name, ".text") == 0)
+ int_rel.r_symndx = RELOC_SECTION_TEXT;
+ break;
+ }
+
+ if (int_rel.r_symndx == -1)
+ abort ();
+
+ /* Add the section VMA and the symbol value. */
+ relocation = (h->root.u.def.value
+ + s->output_section->vma
+ + s->output_offset);
+
+ /* For a PC relative relocation, the object file
+ currently holds just the addend. We must adjust
+ by the address to get the right value. */
+ if (howto->pc_relative)
+ {
+ relocation -= int_rel.r_vaddr - input_section->vma;
+
+ /* If we are converting a RELHI or RELLO reloc
+ from being against an external symbol to
+ being against a section, we must put a
+ special value into the r_offset field. This
+ value is the old addend. The r_offset for
+ both the RELHI and RELLO relocs are the same,
+ and we set both when we see RELHI. */
+ if (int_rel.r_type == MIPS_R_RELHI)
+ {
+ long addhi, addlo;
+
+ addhi = bfd_get_32 (input_bfd,
+ (contents
+ + adjust
+ + int_rel.r_vaddr
+ - input_section->vma));
+ addhi &= 0xffff;
+ if (addhi & 0x8000)
+ addhi -= 0x10000;
+ addhi <<= 16;
+
+ if (! use_lo)
+ addlo = 0;
+ else
+ {
+ addlo = bfd_get_32 (input_bfd,
+ (contents
+ + adjust
+ + lo_int_rel.r_vaddr
+ - input_section->vma));
+ addlo &= 0xffff;
+ if (addlo & 0x8000)
+ addlo -= 0x10000;
+
+ lo_int_rel.r_offset = addhi + addlo;
+ }
+
+ int_rel.r_offset = addhi + addlo;
+ }
+ }
+
+ h = NULL;
+ }
+ else
+ {
+ /* Change the symndx value to the right one for the
+ output BFD. */
+ int_rel.r_symndx = h->indx;
+ if (int_rel.r_symndx == -1)
+ {
+ /* This symbol is not being written out. */
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, h->root.root.string, input_bfd,
+ input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ int_rel.r_symndx = 0;
+ }
+ relocation = 0;
+ }
+ }
+ else
+ {
+ /* This is a relocation against a section. Adjust the
+ value by the amount the section moved. */
+ relocation = (s->output_section->vma
+ + s->output_offset
+ - s->vma);
+ }
+
+ relocation += addend;
+ addend = 0;
+
+ /* Adjust a PC relative relocation by removing the reference
+ to the original address in the section and including the
+ reference to the new address. However, external RELHI
+ and RELLO relocs are PC relative, but don't include any
+ reference to the address. The addend is merely an
+ addend. */
+ if (howto->pc_relative
+ && (! int_rel.r_extern
+ || (int_rel.r_type != MIPS_R_RELHI
+ && int_rel.r_type != MIPS_R_RELLO)))
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma);
+
+ /* Adjust the contents. */
+ if (relocation == 0)
+ r = bfd_reloc_ok;
+ else
+ {
+ if (int_rel.r_type != MIPS_R_REFHI
+ && int_rel.r_type != MIPS_R_RELHI)
+ r = _bfd_relocate_contents (howto, input_bfd, relocation,
+ (contents
+ + adjust
+ + int_rel.r_vaddr
+ - input_section->vma));
+ else
+ {
+ mips_relocate_hi (&int_rel,
+ use_lo ? &lo_int_rel : NULL,
+ input_bfd, input_section, contents,
+ adjust, relocation,
+ int_rel.r_type == MIPS_R_RELHI);
+ r = bfd_reloc_ok;
+ }
+ }
+
+ /* Adjust the reloc address. */
+ int_rel.r_vaddr += (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma);
+
+ /* Save the changed reloc information. */
+ mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
+ }
+ else
+ {
+ /* We are producing a final executable. */
+ if (int_rel.r_extern)
+ {
+ /* This is a reloc against a symbol. */
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *hsec;
+
+ hsec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + hsec->output_section->vma
+ + hsec->output_offset);
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ relocation = 0;
+ }
+ }
+ else
+ {
+ /* This is a reloc against a section. */
+ relocation = (s->output_section->vma
+ + s->output_offset
+ - s->vma);
+
+ /* A PC relative reloc is already correct in the object
+ file. Make it look like a pcrel_offset relocation by
+ adding in the start address. */
+ if (howto->pc_relative)
+ {
+ if (int_rel.r_type != MIPS_R_RELHI || ! use_lo)
+ relocation += int_rel.r_vaddr + adjust;
+ else
+ relocation += lo_int_rel.r_vaddr + adjust;
+ }
+ }
+
+ if (int_rel.r_type != MIPS_R_REFHI
+ && int_rel.r_type != MIPS_R_RELHI)
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ (int_rel.r_vaddr
+ - input_section->vma
+ + adjust),
+ relocation,
+ addend);
+ else
+ {
+ mips_relocate_hi (&int_rel,
+ use_lo ? &lo_int_rel : NULL,
+ input_bfd, input_section, contents, adjust,
+ relocation,
+ int_rel.r_type == MIPS_R_RELHI);
+ r = bfd_reloc_ok;
+ }
+ }
+
+ /* MIPS_R_JMPADDR requires peculiar overflow detection. The
+ instruction provides a 28 bit address (the two lower bits are
+ implicit zeroes) which is combined with the upper four bits
+ of the instruction address. */
+ if (r == bfd_reloc_ok
+ && int_rel.r_type == MIPS_R_JMPADDR
+ && (((relocation
+ + addend
+ + (int_rel.r_extern ? 0 : s->vma))
+ & 0xf0000000)
+ != ((input_section->output_section->vma
+ + input_section->output_offset
+ + (int_rel.r_vaddr - input_section->vma)
+ + adjust)
+ & 0xf0000000)))
+ r = bfd_reloc_overflow;
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (int_rel.r_extern)
+ name = h->root.root.string;
+ else
+ name = bfd_section_name (input_bfd, s);
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Read in the relocs for a section. */
+
+static boolean
+mips_read_relocs (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ struct ecoff_section_tdata *section_tdata;
+
+ section_tdata = ecoff_section_data (abfd, sec);
+ if (section_tdata == (struct ecoff_section_tdata *) NULL)
+ {
+ sec->used_by_bfd =
+ (PTR) bfd_alloc (abfd, sizeof (struct ecoff_section_tdata));
+ if (sec->used_by_bfd == NULL)
+ return false;
+
+ section_tdata = ecoff_section_data (abfd, sec);
+ section_tdata->external_relocs = NULL;
+ section_tdata->contents = NULL;
+ section_tdata->offsets = NULL;
+ }
+
+ if (section_tdata->external_relocs == NULL)
+ {
+ bfd_size_type external_relocs_size;
+
+ external_relocs_size = (ecoff_backend (abfd)->external_reloc_size
+ * sec->reloc_count);
+
+ section_tdata->external_relocs =
+ (PTR) bfd_alloc (abfd, external_relocs_size);
+ if (section_tdata->external_relocs == NULL && external_relocs_size != 0)
+ return false;
+
+ if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
+ || (bfd_read (section_tdata->external_relocs, 1,
+ external_relocs_size, abfd)
+ != external_relocs_size))
+ return false;
+ }
+
+ return true;
+}
+
+/* Relax a section when linking a MIPS ECOFF file. This is used for
+ embedded PIC code, which always uses PC relative branches which
+ only have an 18 bit range on MIPS. If a branch is not in range, we
+ generate a long instruction sequence to compensate. Each time we
+ find a branch to expand, we have to check all the others again to
+ make sure they are still in range. This is slow, but it only has
+ to be done when -relax is passed to the linker.
+
+ This routine figures out which branches need to expand; the actual
+ expansion is done in mips_relocate_section when the section
+ contents are relocated. The information is stored in the offsets
+ field of the ecoff_section_tdata structure. An offset of 1 means
+ that the branch must be expanded into a multi-instruction PC
+ relative branch (such an offset will only occur for a PC relative
+ branch to an external symbol). Any other offset must be a multiple
+ of four, and is the amount to change the branch by (such an offset
+ will only occur for a PC relative branch within the same section).
+
+ We do not modify the section relocs or contents themselves so that
+ if memory usage becomes an issue we can discard them and read them
+ again. The only information we must save in memory between this
+ routine and the mips_relocate_section routine is the table of
+ offsets. */
+
+static boolean
+mips_relax_section (abfd, sec, info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *info;
+ boolean *again;
+{
+ struct ecoff_section_tdata *section_tdata;
+ bfd_byte *contents = NULL;
+ long *offsets;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+ unsigned int i;
+
+ /* Assume we are not going to need another pass. */
+ *again = false;
+
+ /* If we are not generating an ECOFF file, this is much too
+ confusing to deal with. */
+ if (info->hash->creator->flavour != bfd_get_flavour (abfd))
+ return true;
+
+ /* If there are no relocs, there is nothing to do. */
+ if (sec->reloc_count == 0)
+ return true;
+
+ /* We are only interested in PC relative relocs, and why would there
+ ever be one from anything but the .text section? */
+ if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
+ return true;
+
+ /* Read in the relocs, if we haven't already got them. */
+ section_tdata = ecoff_section_data (abfd, sec);
+ if (section_tdata == (struct ecoff_section_tdata *) NULL
+ || section_tdata->external_relocs == NULL)
+ {
+ if (! mips_read_relocs (abfd, sec))
+ goto error_return;
+ section_tdata = ecoff_section_data (abfd, sec);
+ }
+
+ if (sec->_cooked_size == 0)
+ {
+ /* We must initialize _cooked_size only the first time we are
+ called. */
+ sec->_cooked_size = sec->_raw_size;
+ }
+
+ contents = section_tdata->contents;
+ offsets = section_tdata->offsets;
+
+ /* Look for any external PC relative relocs. Internal PC relative
+ relocs are already correct in the object file, so they certainly
+ can not overflow. */
+ ext_rel = (struct external_reloc *) section_tdata->external_relocs;
+ ext_rel_end = ext_rel + sec->reloc_count;
+ for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
+ {
+ struct internal_reloc int_rel;
+ struct ecoff_link_hash_entry *h;
+ asection *hsec;
+ bfd_signed_vma relocation;
+ struct external_reloc *adj_ext_rel;
+ unsigned int adj_i;
+ unsigned long ext_count;
+ struct ecoff_link_hash_entry **adj_h_ptr;
+ struct ecoff_link_hash_entry **adj_h_ptr_end;
+ struct ecoff_value_adjust *adjust;
+
+ /* If we have already expanded this reloc, we certainly don't
+ need to do it again. */
+ if (offsets != (long *) NULL && offsets[i] == 1)
+ continue;
+
+ /* Quickly check that this reloc is external PCREL16. */
+ if (bfd_header_big_endian (abfd))
+ {
+ if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
+ || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
+ >> RELOC_BITS3_TYPE_SH_BIG)
+ != MIPS_R_PCREL16))
+ continue;
+ }
+ else
+ {
+ if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
+ || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
+ >> RELOC_BITS3_TYPE_SH_LITTLE)
+ != MIPS_R_PCREL16))
+ continue;
+ }
+
+ mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
+
+ h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
+ if (h == (struct ecoff_link_hash_entry *) NULL)
+ abort ();
+
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ /* Just ignore undefined symbols. These will presumably
+ generate an error later in the link. */
+ continue;
+ }
+
+ /* Get the value of the symbol. */
+ hsec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + hsec->output_section->vma
+ + hsec->output_offset);
+
+ /* Subtract out the current address. */
+ relocation -= (sec->output_section->vma
+ + sec->output_offset
+ + (int_rel.r_vaddr - sec->vma));
+
+ /* The addend is stored in the object file. In the normal case
+ of ``bal symbol'', the addend will be -4. It will only be
+ different in the case of ``bal symbol+constant''. To avoid
+ always reading in the section contents, we don't check the
+ addend in the object file (we could easily check the contents
+ if we happen to have already read them in, but I fear that
+ this could be confusing). This means we will screw up if
+ there is a branch to a symbol that is in range, but added to
+ a constant which puts it out of range; in such a case the
+ link will fail with a reloc overflow error. Since the
+ compiler will never generate such code, it should be easy
+ enough to work around it by changing the assembly code in the
+ source file. */
+ relocation -= 4;
+
+ /* Now RELOCATION is the number we want to put in the object
+ file. See whether it fits. */
+ if (relocation >= -0x20000 && relocation < 0x20000)
+ continue;
+
+ /* Now that we know this reloc needs work, which will rarely
+ happen, go ahead and grab the section contents. */
+ if (contents == (bfd_byte *) NULL)
+ {
+ if (info->keep_memory)
+ contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
+ else
+ contents = (bfd_byte *) bfd_malloc ((size_t) sec->_raw_size);
+ if (contents == (bfd_byte *) NULL)
+ goto error_return;
+ if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ if (info->keep_memory)
+ section_tdata->contents = contents;
+ }
+
+ /* We only support changing the bal instruction. It would be
+ possible to handle other PC relative branches, but some of
+ them (the conditional branches) would require a different
+ length instruction sequence which would complicate both this
+ routine and mips_relax_pcrel16. It could be written if
+ somebody felt it were important. Ignoring this reloc will
+ presumably cause a reloc overflow error later on. */
+ if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
+ != 0x0411ffff) /* bgezal $0,. == bal . */
+ continue;
+
+ /* Bother. We need to expand this reloc, and we will need to
+ make another relaxation pass since this change may put other
+ relocs out of range. We need to examine the local branches
+ and we need to allocate memory to hold the offsets we must
+ add to them. We also need to adjust the values of all
+ symbols in the object file following this location. */
+
+ sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
+ *again = true;
+
+ if (offsets == (long *) NULL)
+ {
+ size_t size;
+
+ size = sec->reloc_count * sizeof (long);
+ offsets = (long *) bfd_alloc (abfd, size);
+ if (offsets == (long *) NULL)
+ goto error_return;
+ memset (offsets, 0, size);
+ section_tdata->offsets = offsets;
+ }
+
+ offsets[i] = 1;
+
+ /* Now look for all PC relative references that cross this reloc
+ and adjust their offsets. */
+ adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
+ for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
+ {
+ struct internal_reloc adj_int_rel;
+ bfd_vma start, stop;
+ int change;
+
+ mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
+
+ if (adj_int_rel.r_type == MIPS_R_PCREL16)
+ {
+ unsigned long insn;
+
+ /* We only care about local references. External ones
+ will be relocated correctly anyhow. */
+ if (adj_int_rel.r_extern)
+ continue;
+
+ /* We are only interested in a PC relative reloc within
+ this section. FIXME: Cross section PC relative
+ relocs may not be handled correctly; does anybody
+ care? */
+ if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
+ continue;
+
+ start = adj_int_rel.r_vaddr;
+
+ insn = bfd_get_32 (abfd,
+ contents + adj_int_rel.r_vaddr - sec->vma);
+
+ stop = (insn & 0xffff) << 2;
+ if ((stop & 0x20000) != 0)
+ stop -= 0x40000;
+ stop += adj_int_rel.r_vaddr + 4;
+ }
+ else if (adj_int_rel.r_type == MIPS_R_RELHI)
+ {
+ struct internal_reloc rello;
+ long addhi, addlo;
+
+ /* The next reloc must be MIPS_R_RELLO, and we handle
+ them together. */
+ BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end);
+
+ mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello);
+
+ BFD_ASSERT (rello.r_type == MIPS_R_RELLO);
+
+ addhi = bfd_get_32 (abfd,
+ contents + adj_int_rel.r_vaddr - sec->vma);
+ addhi &= 0xffff;
+ if (addhi & 0x8000)
+ addhi -= 0x10000;
+ addhi <<= 16;
+
+ addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma);
+ addlo &= 0xffff;
+ if (addlo & 0x8000)
+ addlo -= 0x10000;
+
+ if (adj_int_rel.r_extern)
+ {
+ /* The value we want here is
+ sym - RELLOaddr + addend
+ which we can express as
+ sym - (RELLOaddr - addend)
+ Therefore if we are expanding the area between
+ RELLOaddr and RELLOaddr - addend we must adjust
+ the addend. This is admittedly ambiguous, since
+ we might mean (sym + addend) - RELLOaddr, but in
+ practice we don't, and there is no way to handle
+ that case correctly since at this point we have
+ no idea whether any reloc is being expanded
+ between sym and sym + addend. */
+ start = rello.r_vaddr - (addhi + addlo);
+ stop = rello.r_vaddr;
+ }
+ else
+ {
+ /* An internal RELHI/RELLO pair represents the
+ difference between two addresses, $LC0 - foo.
+ The symndx value is actually the difference
+ between the reloc address and $LC0. This lets us
+ compute $LC0, and, by considering the addend,
+ foo. If the reloc we are expanding falls between
+ those two relocs, we must adjust the addend. At
+ this point, the symndx value is actually in the
+ r_offset field, where it was put by
+ mips_ecoff_swap_reloc_in. */
+ start = rello.r_vaddr - adj_int_rel.r_offset;
+ stop = start + addhi + addlo;
+ }
+ }
+ else if (adj_int_rel.r_type == MIPS_R_SWITCH)
+ {
+ /* A MIPS_R_SWITCH reloc represents a word of the form
+ .word $L3-$LS12
+ The value in the object file is correct, assuming the
+ original value of $L3. The symndx value is actually
+ the difference between the reloc address and $LS12.
+ This lets us compute the original value of $LS12 as
+ vaddr - symndx
+ and the original value of $L3 as
+ vaddr - symndx + addend
+ where addend is the value from the object file. At
+ this point, the symndx value is actually found in the
+ r_offset field, since it was moved by
+ mips_ecoff_swap_reloc_in. */
+ start = adj_int_rel.r_vaddr - adj_int_rel.r_offset;
+ stop = start + bfd_get_32 (abfd,
+ (contents
+ + adj_int_rel.r_vaddr
+ - sec->vma));
+ }
+ else
+ continue;
+
+ /* If the range expressed by this reloc, which is the
+ distance between START and STOP crosses the reloc we are
+ expanding, we must adjust the offset. The sign of the
+ adjustment depends upon the direction in which the range
+ crosses the reloc being expanded. */
+ if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr)
+ change = PCREL16_EXPANSION_ADJUSTMENT;
+ else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr)
+ change = - PCREL16_EXPANSION_ADJUSTMENT;
+ else
+ change = 0;
+
+ offsets[adj_i] += change;
+
+ if (adj_int_rel.r_type == MIPS_R_RELHI)
+ {
+ adj_ext_rel++;
+ adj_i++;
+ offsets[adj_i] += change;
+ }
+ }
+
+ /* Find all symbols in this section defined by this object file
+ and adjust their values. Note that we decide whether to
+ adjust the value based on the value stored in the ECOFF EXTR
+ structure, because the value stored in the hash table may
+ have been changed by an earlier expanded reloc and thus may
+ no longer correctly indicate whether the symbol is before or
+ after the expanded reloc. */
+ ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
+ adj_h_ptr = ecoff_data (abfd)->sym_hashes;
+ adj_h_ptr_end = adj_h_ptr + ext_count;
+ for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
+ {
+ struct ecoff_link_hash_entry *adj_h;
+
+ adj_h = *adj_h_ptr;
+ if (adj_h != (struct ecoff_link_hash_entry *) NULL
+ && (adj_h->root.type == bfd_link_hash_defined
+ || adj_h->root.type == bfd_link_hash_defweak)
+ && adj_h->root.u.def.section == sec
+ && adj_h->esym.asym.value > int_rel.r_vaddr)
+ adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
+ }
+
+ /* Add an entry to the symbol value adjust list. This is used
+ by bfd_ecoff_debug_accumulate to adjust the values of
+ internal symbols and FDR's. */
+ adjust = ((struct ecoff_value_adjust *)
+ bfd_alloc (abfd, sizeof (struct ecoff_value_adjust)));
+ if (adjust == (struct ecoff_value_adjust *) NULL)
+ goto error_return;
+
+ adjust->start = int_rel.r_vaddr;
+ adjust->end = sec->vma + sec->_raw_size;
+ adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
+
+ adjust->next = ecoff_data (abfd)->debug_info.adjust;
+ ecoff_data (abfd)->debug_info.adjust = adjust;
+ }
+
+ if (contents != (bfd_byte *) NULL && ! info->keep_memory)
+ free (contents);
+
+ return true;
+
+ error_return:
+ if (contents != (bfd_byte *) NULL && ! info->keep_memory)
+ free (contents);
+ return false;
+}
+
+/* This routine is called from mips_relocate_section when a PC
+ relative reloc must be expanded into the five instruction sequence.
+ It handles all the details of the expansion, including resolving
+ the reloc. */
+
+static boolean
+mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ struct ecoff_link_hash_entry *h;
+ bfd_byte *location;
+ bfd_vma address;
+{
+ bfd_vma relocation;
+
+ /* 0x0411ffff is bgezal $0,. == bal . */
+ BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
+
+ /* We need to compute the distance between the symbol and the
+ current address plus eight. */
+ relocation = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ relocation -= address + 8;
+
+ /* If the lower half is negative, increment the upper 16 half. */
+ if ((relocation & 0x8000) != 0)
+ relocation += 0x10000;
+
+ bfd_put_32 (input_bfd, 0x04110001, location); /* bal .+8 */
+ bfd_put_32 (input_bfd,
+ 0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
+ location + 4);
+ bfd_put_32 (input_bfd,
+ 0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
+ location + 8);
+ bfd_put_32 (input_bfd, 0x003f0821, location + 12); /* addu $at,$at,$ra */
+ bfd_put_32 (input_bfd, 0x0020f809, location + 16); /* jalr $at */
+
+ return true;
+}
+
+/* Given a .sdata section and a .rel.sdata in-memory section, store
+ relocation information into the .rel.sdata section which can be
+ used at runtime to relocate the section. This is called by the
+ linker when the --embedded-relocs switch is used. This is called
+ after the add_symbols entry point has been called for all the
+ objects, and before the final_link entry point is called. This
+ function presumes that the object was compiled using
+ -membedded-pic. */
+
+boolean
+bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *datasec;
+ asection *relsec;
+ char **errmsg;
+{
+ struct ecoff_link_hash_entry **sym_hashes;
+ struct ecoff_section_tdata *section_tdata;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+ bfd_byte *p;
+
+ BFD_ASSERT (! info->relocateable);
+
+ *errmsg = NULL;
+
+ if (datasec->reloc_count == 0)
+ return true;
+
+ sym_hashes = ecoff_data (abfd)->sym_hashes;
+
+ if (! mips_read_relocs (abfd, datasec))
+ return false;
+
+ relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 4);
+ if (relsec->contents == NULL)
+ return false;
+
+ p = relsec->contents;
+
+ section_tdata = ecoff_section_data (abfd, datasec);
+ ext_rel = (struct external_reloc *) section_tdata->external_relocs;
+ ext_rel_end = ext_rel + datasec->reloc_count;
+ for (; ext_rel < ext_rel_end; ext_rel++, p += 4)
+ {
+ struct internal_reloc int_rel;
+ boolean text_relative;
+
+ mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
+
+ /* We are going to write a four byte word into the runtime reloc
+ section. The word will be the address in the data section
+ which must be relocated. This must be on a word boundary,
+ which means the lower two bits must be zero. We use the
+ least significant bit to indicate how the value in the data
+ section must be relocated. A 0 means that the value is
+ relative to the text section, while a 1 indicates that the
+ value is relative to the data section. Given that we are
+ assuming the code was compiled using -membedded-pic, there
+ should not be any other possibilities. */
+
+ /* We can only relocate REFWORD relocs at run time. */
+ if (int_rel.r_type != MIPS_R_REFWORD)
+ {
+ *errmsg = _("unsupported reloc type");
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (int_rel.r_extern)
+ {
+ struct ecoff_link_hash_entry *h;
+
+ h = sym_hashes[int_rel.r_symndx];
+ /* If h is NULL, that means that there is a reloc against an
+ external symbol which we thought was just a debugging
+ symbol. This should not happen. */
+ if (h == (struct ecoff_link_hash_entry *) NULL)
+ abort ();
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.section->flags & SEC_CODE) != 0)
+ text_relative = true;
+ else
+ text_relative = false;
+ }
+ else
+ {
+ switch (int_rel.r_symndx)
+ {
+ case RELOC_SECTION_TEXT:
+ text_relative = true;
+ break;
+ case RELOC_SECTION_SDATA:
+ case RELOC_SECTION_SBSS:
+ case RELOC_SECTION_LIT8:
+ text_relative = false;
+ break;
+ default:
+ /* No other sections should appear in -membedded-pic
+ code. */
+ *errmsg = _("reloc against unsupported section");
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ if ((int_rel.r_offset & 3) != 0)
+ {
+ *errmsg = _("reloc not properly aligned");
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ bfd_put_32 (abfd,
+ (int_rel.r_vaddr - datasec->vma + datasec->output_offset
+ + (text_relative ? 0 : 1)),
+ p);
+ }
+
+ return true;
+}
+
+/* This is the ECOFF backend structure. The backend field of the
+ target vector points to this. */
+
+static const struct ecoff_backend_data mips_ecoff_backend_data =
+{
+ /* COFF backend structure. */
+ {
+ (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
+ (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
+ (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
+ (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
+ (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
+ (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
+ (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
+ mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
+ mips_ecoff_swap_scnhdr_out,
+ FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, false, 4,
+ mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
+ mips_ecoff_swap_scnhdr_in, NULL,
+ mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
+ _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
+ _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ },
+ /* Supported architecture. */
+ bfd_arch_mips,
+ /* Initial portion of armap string. */
+ "__________",
+ /* The page boundary used to align sections in a demand-paged
+ executable file. E.g., 0x1000. */
+ 0x1000,
+ /* True if the .rdata section is part of the text segment, as on the
+ Alpha. False if .rdata is part of the data segment, as on the
+ MIPS. */
+ false,
+ /* Bitsize of constructor entries. */
+ 32,
+ /* Reloc to use for constructor entries. */
+ &mips_howto_table[MIPS_R_REFWORD],
+ {
+ /* Symbol table magic number. */
+ magicSym,
+ /* Alignment of debugging information. E.g., 4. */
+ 4,
+ /* Sizes of external symbolic information. */
+ sizeof (struct hdr_ext),
+ sizeof (struct dnr_ext),
+ sizeof (struct pdr_ext),
+ sizeof (struct sym_ext),
+ sizeof (struct opt_ext),
+ sizeof (struct fdr_ext),
+ sizeof (struct rfd_ext),
+ sizeof (struct ext_ext),
+ /* Functions to swap in external symbolic data. */
+ ecoff_swap_hdr_in,
+ ecoff_swap_dnr_in,
+ ecoff_swap_pdr_in,
+ ecoff_swap_sym_in,
+ ecoff_swap_opt_in,
+ ecoff_swap_fdr_in,
+ ecoff_swap_rfd_in,
+ ecoff_swap_ext_in,
+ _bfd_ecoff_swap_tir_in,
+ _bfd_ecoff_swap_rndx_in,
+ /* Functions to swap out external symbolic data. */
+ ecoff_swap_hdr_out,
+ ecoff_swap_dnr_out,
+ ecoff_swap_pdr_out,
+ ecoff_swap_sym_out,
+ ecoff_swap_opt_out,
+ ecoff_swap_fdr_out,
+ ecoff_swap_rfd_out,
+ ecoff_swap_ext_out,
+ _bfd_ecoff_swap_tir_out,
+ _bfd_ecoff_swap_rndx_out,
+ /* Function to read in symbolic data. */
+ _bfd_ecoff_slurp_symbolic_info
+ },
+ /* External reloc size. */
+ RELSZ,
+ /* Reloc swapping functions. */
+ mips_ecoff_swap_reloc_in,
+ mips_ecoff_swap_reloc_out,
+ /* Backend reloc tweaking. */
+ mips_adjust_reloc_in,
+ mips_adjust_reloc_out,
+ /* Relocate section contents while linking. */
+ mips_relocate_section,
+ /* Do final adjustments to filehdr and aouthdr. */
+ NULL,
+ /* Read an element from an archive at a given file position. */
+ _bfd_get_elt_at_filepos
+};
+
+/* Looking up a reloc type is MIPS specific. */
+#define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
+
+/* Getting relocated section contents is generic. */
+#define _bfd_ecoff_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+
+/* Handling file windows is generic. */
+#define _bfd_ecoff_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+/* Relaxing sections is MIPS specific. */
+#define _bfd_ecoff_bfd_relax_section mips_relax_section
+
+/* GC of sections is not done. */
+#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
+
+const bfd_target ecoff_little_vec =
+{
+ "ecoff-littlemips", /* name */
+ bfd_target_ecoff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ _bfd_ecoff_archive_p, _bfd_dummy_target},
+ {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
+ BFD_JUMP_TABLE_COPY (_bfd_ecoff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
+ BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
+ BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
+ BFD_JUMP_TABLE_LINK (_bfd_ecoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) &mips_ecoff_backend_data
+};
+
+const bfd_target ecoff_big_vec =
+{
+ "ecoff-bigmips", /* name */
+ bfd_target_ecoff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ _bfd_ecoff_archive_p, _bfd_dummy_target},
+ {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
+ BFD_JUMP_TABLE_COPY (_bfd_ecoff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
+ BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
+ BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
+ BFD_JUMP_TABLE_LINK (_bfd_ecoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) &mips_ecoff_backend_data
+};
+
+const bfd_target ecoff_biglittle_vec =
+{
+ "ecoff-biglittlemips", /* name */
+ bfd_target_ecoff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ _bfd_ecoff_archive_p, _bfd_dummy_target},
+ {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
+ BFD_JUMP_TABLE_COPY (_bfd_ecoff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
+ BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
+ BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
+ BFD_JUMP_TABLE_LINK (_bfd_ecoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) &mips_ecoff_backend_data
+};
diff --git a/bfd/coff-pmac.c b/bfd/coff-pmac.c
new file mode 100644
index 00000000000..f3332d98959
--- /dev/null
+++ b/bfd/coff-pmac.c
@@ -0,0 +1,27 @@
+/* BFD back-end for Apple et al PowerPC Mac "XCOFF" files.
+ Copyright 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM pmac_xcoff_vec
+#define TARGET_NAME "xcoff-powermac"
+
+/* Tweak coffcode.h based on this being a PowerMac instead of RS/6000. */
+
+#define POWERMAC
+
+#include "coff-rs6000.c"
diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c
new file mode 100644
index 00000000000..cf4504479b5
--- /dev/null
+++ b/bfd/coff-ppc.c
@@ -0,0 +1,2934 @@
+/* BFD back-end for PowerPC Microsoft Portable Executable files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ Original version pieced together by Kim Knuttila (krk@cygnus.com)
+
+ There is nothing new under the sun. This file draws a lot on other
+ coff files, in particular, those for the rs/6000, alpha, mips, and
+ intel backends, and the PE work for the arm.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Current State:
+ - objdump works
+ - relocs generated by gas
+ - ld will link files, but they do not run.
+ - dlltool will not produce correct output in some .reloc cases, and will
+ not produce the right glue code for dll function calls.
+*/
+
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#include "libbfd.h"
+
+#include "coff/powerpc.h"
+#include "coff/internal.h"
+
+#include "coff/pe.h"
+
+#ifdef BADMAG
+#undef BADMAG
+#endif
+
+#define BADMAG(x) PPCBADMAG(x)
+
+#include "libcoff.h"
+
+/* This file is compiled more than once, but we only compile the
+ final_link routine once. */
+extern boolean ppc_bfd_coff_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern void dump_toc PARAMS ((PTR));
+
+/* The toc is a set of bfd_vma fields. We use the fact that valid */
+/* addresses are even (i.e. the bit representing "1" is off) to allow */
+/* us to encode a little extra information in the field */
+/* - Unallocated addresses are intialized to 1. */
+/* - Allocated addresses are even numbers. */
+/* The first time we actually write a reference to the toc in the bfd, */
+/* we want to record that fact in a fixup file (if it is asked for), so */
+/* we keep track of whether or not an address has been written by marking */
+/* the low order bit with a "1" upon writing */
+
+#define SET_UNALLOCATED(x) ((x) = 1)
+#define IS_UNALLOCATED(x) ((x) == 1)
+
+#define IS_WRITTEN(x) ((x) & 1)
+#define MARK_AS_WRITTEN(x) ((x) |= 1)
+#define MAKE_ADDR_AGAIN(x) ((x) &= ~1)
+
+
+/* Turn on this check if you suspect something amiss in the hash tables */
+#ifdef DEBUG_HASH
+
+/* Need a 7 char string for an eye catcher */
+#define EYE "krkjunk"
+
+#define HASH_CHECK_DCL char eye_catcher[8];
+#define HASH_CHECK_INIT(ret) strcpy(ret->eye_catcher, EYE)
+#define HASH_CHECK(addr) \
+ if (strcmp(addr->eye_catcher, EYE) != 0) \
+ { \
+ fprintf(stderr,\
+ _("File %s, line %d, Hash check failure, bad eye %8s\n"), \
+ __FILE__, __LINE__, addr->eye_catcher); \
+ abort(); \
+ }
+
+
+#else
+
+#define HASH_CHECK_DCL
+#define HASH_CHECK_INIT(ret)
+#define HASH_CHECK(addr)
+
+#endif
+
+/* In order not to add an int to every hash table item for every coff
+ linker, we define our own hash table, derived from the coff one */
+
+/* PE linker hash table entries. */
+
+struct ppc_coff_link_hash_entry
+{
+ struct coff_link_hash_entry root; /* First entry, as required */
+
+ /* As we wonder around the relocs, we'll keep the assigned toc_offset
+ here */
+ bfd_vma toc_offset; /* Our addition, as required */
+ int symbol_is_glue;
+ unsigned long int glue_insn;
+
+ HASH_CHECK_DCL
+};
+
+
+/* PE linker hash table. */
+
+struct ppc_coff_link_hash_table
+{
+ struct coff_link_hash_table root; /* First entry, as required */
+};
+
+static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *));
+static boolean ppc_coff_link_hash_table_init
+ PARAMS ((struct ppc_coff_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+static struct bfd_link_hash_table *ppc_coff_link_hash_table_create
+ PARAMS ((bfd *));
+static boolean coff_ppc_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+static reloc_howto_type *coff_ppc_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *));
+
+/* Routine to create an entry in the link hash table. */
+
+static struct bfd_hash_entry *
+ppc_coff_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct ppc_coff_link_hash_entry *ret =
+ (struct ppc_coff_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct ppc_coff_link_hash_entry *) NULL)
+ ret = (struct ppc_coff_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct ppc_coff_link_hash_entry));
+
+ if (ret == (struct ppc_coff_link_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct ppc_coff_link_hash_entry *)
+ _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ SET_UNALLOCATED(ret->toc_offset);
+ ret->symbol_is_glue = 0;
+ ret->glue_insn = 0;
+
+ HASH_CHECK_INIT(ret);
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize a PE linker hash table. */
+
+static boolean
+ppc_coff_link_hash_table_init (table, abfd, newfunc)
+ struct ppc_coff_link_hash_table *table;
+ bfd *abfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc);
+}
+
+/* Create a PE linker hash table. */
+
+static struct bfd_link_hash_table *
+ppc_coff_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct ppc_coff_link_hash_table *ret;
+
+ ret = ((struct ppc_coff_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct ppc_coff_link_hash_table)));
+ if (ret == NULL)
+ return NULL;
+ if (! ppc_coff_link_hash_table_init (ret, abfd,
+ ppc_coff_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+ return &ret->root.root;
+}
+
+/* Now, tailor coffcode.h to use our hash stuff */
+
+#define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create
+
+
+/* The nt loader points the toc register to &toc + 32768, in order to */
+/* use the complete range of a 16-bit displacement. We have to adjust */
+/* for this when we fix up loads displaced off the toc reg. */
+#define TOC_LOAD_ADJUSTMENT (-32768)
+#define TOC_SECTION_NAME ".private.toc"
+
+/* The main body of code is in coffcode.h. */
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+ from smaller values. Start with zero, widen, *then* decrement. */
+#define MINUS_ONE (((bfd_vma)0) - 1)
+
+/* these should definitely go in a header file somewhere... */
+
+/* NOP */
+#define IMAGE_REL_PPC_ABSOLUTE 0x0000
+
+/* 64-bit address */
+#define IMAGE_REL_PPC_ADDR64 0x0001
+
+/* 32-bit address */
+#define IMAGE_REL_PPC_ADDR32 0x0002
+
+/* 26-bit address, shifted left 2 (branch absolute) */
+#define IMAGE_REL_PPC_ADDR24 0x0003
+
+/* 16-bit address */
+#define IMAGE_REL_PPC_ADDR16 0x0004
+
+/* 16-bit address, shifted left 2 (load doubleword) */
+#define IMAGE_REL_PPC_ADDR14 0x0005
+
+/* 26-bit PC-relative offset, shifted left 2 (branch relative) */
+#define IMAGE_REL_PPC_REL24 0x0006
+
+/* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
+#define IMAGE_REL_PPC_REL14 0x0007
+
+/* 16-bit offset from TOC base */
+#define IMAGE_REL_PPC_TOCREL16 0x0008
+
+/* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
+#define IMAGE_REL_PPC_TOCREL14 0x0009
+
+/* 32-bit addr w/o image base */
+#define IMAGE_REL_PPC_ADDR32NB 0x000A
+
+/* va of containing section (as in an image sectionhdr) */
+#define IMAGE_REL_PPC_SECREL 0x000B
+
+/* sectionheader number */
+#define IMAGE_REL_PPC_SECTION 0x000C
+
+/* substitute TOC restore instruction iff symbol is glue code */
+#define IMAGE_REL_PPC_IFGLUE 0x000D
+
+/* symbol is glue code; virtual address is TOC restore instruction */
+#define IMAGE_REL_PPC_IMGLUE 0x000E
+
+/* va of containing section (limited to 16 bits) */
+#define IMAGE_REL_PPC_SECREL16 0x000F
+
+/* stuff to handle immediate data when the number of bits in the */
+/* data is greater than the number of bits in the immediate field */
+/* We need to do (usually) 32 bit arithmetic on 16 bit chunks */
+#define IMAGE_REL_PPC_REFHI 0x0010
+#define IMAGE_REL_PPC_REFLO 0x0011
+#define IMAGE_REL_PPC_PAIR 0x0012
+
+/* This is essentially the same as tocrel16, with TOCDEFN assumed */
+#define IMAGE_REL_PPC_TOCREL16_DEFN 0x0013
+
+/* Flag bits in IMAGE_RELOCATION.TYPE */
+
+/* subtract reloc value rather than adding it */
+#define IMAGE_REL_PPC_NEG 0x0100
+
+/* fix branch prediction bit to predict branch taken */
+#define IMAGE_REL_PPC_BRTAKEN 0x0200
+
+/* fix branch prediction bit to predict branch not taken */
+#define IMAGE_REL_PPC_BRNTAKEN 0x0400
+
+/* toc slot defined in file (or, data in toc) */
+#define IMAGE_REL_PPC_TOCDEFN 0x0800
+
+/* masks to isolate above values in IMAGE_RELOCATION.Type */
+#define IMAGE_REL_PPC_TYPEMASK 0x00FF
+#define IMAGE_REL_PPC_FLAGMASK 0x0F00
+
+#define EXTRACT_TYPE(x) ((x) & IMAGE_REL_PPC_TYPEMASK)
+#define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK)
+#define EXTRACT_JUNK(x) \
+ ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK))
+
+
+/* static helper functions to make relocation work */
+/* (Work In Progress) */
+
+static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+#if 0
+static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+#endif
+static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+
+
+static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+
+#if 0
+static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+#endif
+static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+
+static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+
+static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd,
+ arelent *reloc,
+ asymbol *symbol,
+ PTR data,
+ asection *section,
+ bfd *output_bfd,
+ char **error));
+
+
+
+static boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto));
+
+
+/* FIXME: It'll take a while to get through all of these. I only need a few to
+ get us started, so those I'll make sure work. Those marked FIXME are either
+ completely unverified or have a specific unknown marked in the comment */
+
+/*---------------------------------------------------------------------------*/
+/* */
+/* Relocation entries for Windows/NT on PowerPC. */
+/* */
+/* From the document "" we find the following listed as used relocs: */
+/* */
+/* ABSOLUTE : The noop */
+/* ADDR[64|32|16] : fields that hold addresses in data fields or the */
+/* 16 bit displacement field on a load/store. */
+/* ADDR[24|14] : fields that hold addresses in branch and cond */
+/* branches. These represent [26|16] bit addresses. */
+/* The low order 2 bits are preserved. */
+/* REL[24|14] : branches relative to the Instruction Address */
+/* register. These represent [26|16] bit addresses, */
+/* as before. The instruction field will be zero, and */
+/* the address of the SYM will be inserted at link time. */
+/* TOCREL16 : 16 bit displacement field referring to a slot in */
+/* toc. */
+/* TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. */
+/* ADDR32NB : 32 bit address relative to the virtual origin. */
+/* (On the alpha, this is always a linker generated thunk)*/
+/* (i.e. 32bit addr relative to the image base) */
+/* SECREL : The value is relative to the start of the section */
+/* containing the symbol. */
+/* SECTION : access to the header containing the item. Supports the */
+/* codeview debugger. */
+/* */
+/* In particular, note that the document does not indicate that the */
+/* relocations listed in the header file are used. */
+/* */
+/* */
+/* */
+/*---------------------------------------------------------------------------*/
+
+static reloc_howto_type ppc_coff_howto_table[] =
+{
+ /* IMAGE_REL_PPC_ABSOLUTE 0x0000 NOP */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* dont complain_on_overflow */
+ 0, /* special_function */
+ "ABSOLUTE", /* name */
+ false, /* partial_inplace */
+ 0x00, /* src_mask */
+ 0x00, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_ADDR64 0x0001 64-bit address */
+ /* Unused: */
+ HOWTO(IMAGE_REL_PPC_ADDR64, /* type */
+ 0, /* rightshift */
+ 3, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR64", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_ADDR32 0x0002 32-bit address */
+ /* Used: */
+ HOWTO (IMAGE_REL_PPC_ADDR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_ADDR24 0x0003 26-bit address, shifted left 2 (branch absolute) */
+ /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */
+ /* Of course, That's the IBM approved bit numbering, which is not what */
+ /* anyone else uses.... The li field is in bit 2 thru 25 */
+ /* Used: */
+ HOWTO (IMAGE_REL_PPC_ADDR24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR24", /* name */
+ true, /* partial_inplace */
+ 0x07fffffc, /* src_mask */
+ 0x07fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_ADDR16 0x0004 16-bit address */
+ /* Used: */
+ HOWTO (IMAGE_REL_PPC_ADDR16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_ADDR14 0x0005 */
+ /* 16-bit address, shifted left 2 (load doubleword) */
+ /* FIXME: the mask is likely wrong, and the bit position may be as well */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_ADDR14, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_REL24 0x0006 */
+ /* 26-bit PC-relative offset, shifted left 2 (branch relative) */
+ /* Used: */
+ HOWTO (IMAGE_REL_PPC_REL24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "REL24", /* name */
+ true, /* partial_inplace */
+ 0x3fffffc, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_REL14 0x0007 */
+ /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */
+ /* FIXME: the mask is likely wrong, and the bit position may be as well */
+ /* FIXME: how does it know how far to shift? */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_ADDR14, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_TOCREL16 0x0008 */
+ /* 16-bit offset from TOC base */
+ /* Used: */
+ HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_toc16_reloc, /* special_function */
+ "TOCREL16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_TOCREL14 0x0009 */
+ /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "TOCREL14", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_ADDR32NB 0x000A */
+ /* 32-bit addr w/ image base */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "ADDR32NB", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_SECREL 0x000B */
+ /* va of containing section (as in an image sectionhdr) */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_SECREL,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_secrel_reloc, /* special_function */
+ "SECREL", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_SECTION 0x000C */
+ /* sectionheader number */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_SECTION,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_section_reloc, /* special_function */
+ "SECTION", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_IFGLUE 0x000D */
+ /* substitute TOC restore instruction iff symbol is glue code */
+ /* Used: */
+ HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "IFGLUE", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_IMGLUE 0x000E */
+ /* symbol is glue code; virtual address is TOC restore instruction */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_imglue_reloc, /* special_function */
+ "IMGLUE", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_SECREL16 0x000F */
+ /* va of containing section (limited to 16 bits) */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_SECREL16,/* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SECREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_REFHI 0x0010 */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_REFHI, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_refhi_reloc, /* special_function */
+ "REFHI", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_REFLO 0x0011 */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_REFLO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_refhi_reloc, /* special_function */
+ "REFLO", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_PAIR 0x0012 */
+ /* Unused: */
+ HOWTO (IMAGE_REL_PPC_PAIR, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_pair_reloc, /* special_function */
+ "PAIR", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 */
+ /* 16-bit offset from TOC base, without causing a definition */
+ /* Used: */
+ HOWTO ( (IMAGE_REL_PPC_TOCREL16 | IMAGE_REL_PPC_TOCDEFN), /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "TOCREL16, TOCDEFN", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+
+
+
+/* Some really cheezy macros that can be turned on to test stderr :-) */
+
+#ifdef DEBUG_RELOC
+#define UN_IMPL(x) \
+{ \
+ static int i; \
+ if (i == 0) \
+ { \
+ i = 1; \
+ fprintf(stderr,_("Unimplemented Relocation -- %s\n"),x); \
+ } \
+}
+
+#define DUMP_RELOC(n,r) \
+{ \
+ fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \
+ n, (*(r->sym_ptr_ptr))->name, \
+ r->address, r->addend); \
+}
+
+/* Given a reloc name, n, and a pointer to an internal_reloc,
+ dump out interesting information on the contents
+
+#define n_name _n._n_name
+#define n_zeroes _n._n_n._n_zeroes
+#define n_offset _n._n_n._n_offset
+
+*/
+
+#define DUMP_RELOC2(n,r) \
+{ \
+ fprintf(stderr,"%s sym %d, r_vaddr %d %s\n", \
+ n, r->r_symndx, r->r_vaddr,\
+ (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \
+ ?" ":" TOCDEFN" ); \
+}
+
+#else
+#define UN_IMPL(x)
+#define DUMP_RELOC(n,r)
+#define DUMP_RELOC2(n,r)
+#endif
+
+
+
+/* toc construction and management routines */
+
+/* This file is compiled twice, and these variables are defined in one
+ of the compilations. FIXME: This is confusing and weird. Also,
+ BFD should not use global variables. */
+extern bfd* bfd_of_toc_owner;
+extern long int global_toc_size;
+
+extern long int import_table_size;
+extern long int first_thunk_address;
+extern long int thunk_size;
+
+enum toc_type
+{
+ default_toc,
+ toc_32,
+ toc_64
+};
+
+enum ref_category
+{
+ priv,
+ pub,
+ data
+};
+
+struct list_ele
+{
+ struct list_ele *next;
+ bfd_vma addr;
+ enum ref_category cat;
+ int offset;
+ const char *name;
+};
+
+extern struct list_ele *head;
+extern struct list_ele *tail;
+
+static void record_toc
+ PARAMS ((asection *, int, enum ref_category, const char *));
+
+static void
+record_toc (toc_section, our_toc_offset, cat, name)
+ asection *toc_section;
+ int our_toc_offset;
+ enum ref_category cat;
+ const char *name;
+{
+ /* add this entry to our toc addr-offset-name list */
+ struct list_ele *t;
+ t = (struct list_ele *) bfd_malloc (sizeof (struct list_ele));
+ if (t == NULL)
+ abort ();
+ t->next = 0;
+ t->offset = our_toc_offset;
+ t->name = name;
+ t->cat = cat;
+ t->addr = toc_section->output_offset + our_toc_offset;
+
+ if (head == 0)
+ {
+ head = t;
+ tail = t;
+ }
+ else
+ {
+ tail->next = t;
+ tail = t;
+ }
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+
+static boolean ppc_record_toc_entry
+ PARAMS ((bfd *, struct bfd_link_info *, asection *, int, enum toc_type));
+static void ppc_mark_symbol_as_glue
+ PARAMS ((bfd *, int, struct internal_reloc *));
+
+/* record a toc offset against a symbol */
+static boolean
+ppc_record_toc_entry(abfd, info, sec, sym, toc_kind)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ int sym;
+ enum toc_type toc_kind;
+{
+ struct ppc_coff_link_hash_entry *h;
+ const char *name;
+
+ int *local_syms;
+
+ h = 0;
+
+ h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
+ if (h != 0)
+ {
+ HASH_CHECK(h);
+ }
+
+ if (h == 0)
+ {
+ local_syms = obj_coff_local_toc_table(abfd);
+ if (local_syms == 0)
+ {
+ unsigned int i;
+ /* allocate a table */
+ local_syms =
+ (int *) bfd_zalloc (abfd,
+ obj_raw_syment_count(abfd) * sizeof(int));
+ if (local_syms == 0)
+ return false;
+ obj_coff_local_toc_table(abfd) = local_syms;
+ for (i = 0; i < obj_raw_syment_count(abfd); ++i)
+ {
+ SET_UNALLOCATED(local_syms[i]);
+ }
+ }
+
+ if (IS_UNALLOCATED(local_syms[sym]))
+ {
+ local_syms[sym] = global_toc_size;
+ global_toc_size += 4;
+
+ /* The size must fit in a 16bit displacment */
+ if (global_toc_size > 65535)
+ {
+ (*_bfd_error_handler) (_("TOC overflow"));
+ bfd_set_error (bfd_error_file_too_big);
+ return false;
+ }
+ }
+ }
+ else
+ {
+ name = h->root.root.root.string;
+
+ /* check to see if there's a toc slot allocated. If not, do it
+ here. It will be used in relocate_section */
+ if (IS_UNALLOCATED(h->toc_offset))
+ {
+ h->toc_offset = global_toc_size;
+ global_toc_size += 4;
+
+ /* The size must fit in a 16bit displacment */
+ if (global_toc_size >= 65535)
+ {
+ (*_bfd_error_handler) (_("TOC overflow"));
+ bfd_set_error (bfd_error_file_too_big);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* record a toc offset against a symbol */
+static void
+ppc_mark_symbol_as_glue(abfd, sym, rel)
+ bfd *abfd;
+ int sym;
+ struct internal_reloc *rel;
+{
+ struct ppc_coff_link_hash_entry *h;
+
+ h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]);
+
+ HASH_CHECK(h);
+
+ h->symbol_is_glue = 1;
+ h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr);
+
+ return;
+}
+
+#endif /* COFF_IMAGE_WITH_PE */
+
+
+/* Return true if this relocation should
+ appear in the output .reloc section. */
+
+static boolean in_reloc_p(abfd, howto)
+ bfd * abfd;
+ reloc_howto_type *howto;
+{
+ return
+ (! howto->pc_relative)
+ && (howto->type != IMAGE_REL_PPC_ADDR32NB)
+ && (howto->type != IMAGE_REL_PPC_TOCREL16)
+ && (howto->type != IMAGE_REL_PPC_IMGLUE)
+ && (howto->type != IMAGE_REL_PPC_IFGLUE)
+ && (howto->type != IMAGE_REL_PPC_SECREL)
+ && (howto->type != IMAGE_REL_PPC_SECTION)
+ && (howto->type != IMAGE_REL_PPC_SECREL16)
+ && (howto->type != IMAGE_REL_PPC_REFHI)
+ && (howto->type != IMAGE_REL_PPC_REFLO)
+ && (howto->type != IMAGE_REL_PPC_PAIR)
+ && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
+}
+
+#if 0
+
+/* this function is in charge of performing all the ppc PE relocations */
+/* Don't yet know if we want to do this this particular way ... (krk) */
+/* FIXME: (it is not yet enabled) */
+
+static bfd_reloc_status_type
+pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* the consth relocation comes in two parts, we have to remember
+ the state between calls, in these variables */
+ static boolean part1_consth_active = false;
+ static unsigned long part1_consth_value;
+
+ unsigned long sym_value;
+ unsigned short r_type;
+ unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
+
+ r_type = reloc_entry->howto->type;
+
+ if (output_bfd)
+ {
+ /* Partial linking - do nothing */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (symbol_in != NULL
+ && bfd_is_und_section (symbol_in->section))
+ {
+ /* Keep the state machine happy in case we're called again */
+ if (r_type == IMAGE_REL_PPC_REFHI)
+ {
+ part1_consth_active = true;
+ part1_consth_value = 0;
+ }
+ return(bfd_reloc_undefined);
+ }
+
+ if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR))
+ {
+ part1_consth_active = false;
+ *error_message = (char *) _("Missing PAIR");
+ return(bfd_reloc_dangerous);
+ }
+
+
+ sym_value = get_symbol_value(symbol_in);
+
+ return(bfd_reloc_ok);
+}
+
+#endif /* 0 */
+
+/* The reloc processing routine for the optimized COFF linker. */
+
+static boolean
+coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, syms, sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+ boolean hihalf;
+ bfd_vma hihalf_val;
+ asection *toc_section = 0;
+ bfd_vma relocation;
+ reloc_howto_type *howto = 0;
+
+ /* If we are performing a relocateable link, we don't need to do a
+ thing. The caller will take care of adjusting the reloc
+ addresses and symbol indices. */
+ if (info->relocateable)
+ return true;
+
+ hihalf = false;
+ hihalf_val = 0;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct ppc_coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma val;
+
+ asection *sec;
+ bfd_reloc_status_type rstat;
+ bfd_byte *loc;
+
+ unsigned short r_type = EXTRACT_TYPE (rel->r_type);
+ unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
+
+ symndx = rel->r_symndx;
+ loc = contents + rel->r_vaddr - input_section->vma;
+
+ /* FIXME: check bounds on r_type */
+ howto = ppc_coff_howto_table + r_type;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ h = (struct ppc_coff_link_hash_entry *)
+ (obj_coff_sym_hashes (input_bfd)[symndx]);
+ if (h != 0)
+ {
+ HASH_CHECK(h);
+ }
+
+ sym = syms + symndx;
+ }
+
+ if (r_type == IMAGE_REL_PPC_IMGLUE && h == 0)
+ {
+ /* An IMGLUE reloc must have a name. Something is very wrong. */
+ abort();
+ }
+
+ sec = NULL;
+ val = 0;
+
+ /* FIXME: PAIR unsupported in the following code */
+ if (h == NULL)
+ {
+ if (symndx == -1)
+ sec = bfd_abs_section_ptr;
+ else
+ {
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value);
+ if (! obj_pe (output_bfd))
+ val -= sec->vma;
+ }
+ }
+ else
+ {
+ HASH_CHECK(h);
+
+ if (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.root.u.def.section;
+ val = (h->root.root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ rstat = bfd_reloc_ok;
+
+ /* Each case must do its own relocation, setting rstat appropriately */
+ switch (r_type)
+ {
+ default:
+ (*_bfd_error_handler)
+ (_("%s: unsupported relocation type 0x%02x"),
+ bfd_get_filename (input_bfd), r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ case IMAGE_REL_PPC_TOCREL16:
+ {
+ bfd_vma our_toc_offset;
+ int fixit;
+
+ DUMP_RELOC2(howto->name, rel);
+
+ if (toc_section == 0)
+ {
+ toc_section = bfd_get_section_by_name (bfd_of_toc_owner,
+ TOC_SECTION_NAME);
+
+ if ( toc_section == NULL )
+ {
+ /* There is no toc section. Something is very wrong. */
+ abort();
+ }
+ }
+
+ /*
+ * Amazing bit tricks present. As we may have seen earlier, we
+ * use the 1 bit to tell us whether or not a toc offset has been
+ * allocated. Now that they've all been allocated, we will use
+ * the 1 bit to tell us if we've written this particular toc
+ * entry out.
+ */
+ fixit = false;
+ if (h == 0)
+ { /* it is a file local symbol */
+ int *local_toc_table;
+ const char *name;
+
+ sym = syms + symndx;
+ name = sym->_n._n_name;
+
+ local_toc_table = obj_coff_local_toc_table(input_bfd);
+ our_toc_offset = local_toc_table[symndx];
+
+ if (IS_WRITTEN(our_toc_offset))
+ {
+ /* if it has been written out, it is marked with the
+ 1 bit. Fix up our offset, but do not write it out
+ again.
+ */
+ MAKE_ADDR_AGAIN(our_toc_offset);
+ }
+ else
+ {
+ /* write out the toc entry */
+ record_toc(toc_section,
+ our_toc_offset,
+ priv,
+ strdup(name));
+
+ bfd_put_32(output_bfd,
+ val,
+ toc_section->contents + our_toc_offset);
+
+ MARK_AS_WRITTEN(local_toc_table[symndx]);
+ fixit = true;
+ }
+ }
+ else
+ {
+ const char *name = h->root.root.root.string;
+ our_toc_offset = h->toc_offset;
+
+ if ((r_flags & IMAGE_REL_PPC_TOCDEFN)
+ == IMAGE_REL_PPC_TOCDEFN )
+ {
+ /* This is unbelievable cheese. Some knowledgable asm
+ hacker has decided to use r2 as a base for loading
+ a value. He/She does this by setting the tocdefn bit,
+ and not supplying a toc definition. The behaviour is
+ then to use the difference between the value of the
+ symbol and the actual location of the toc as the toc
+ index.
+
+ In fact, what is usually happening is, because the
+ Import Address Table is mapped immediately following
+ the toc, some trippy library code trying for speed on
+ dll linkage, takes advantage of that and considers
+ the IAT to be part of the toc, thus saving a load.
+ */
+
+ our_toc_offset = val -
+ (toc_section->output_section->vma +
+ toc_section->output_offset);
+
+ /* The size must still fit in a 16bit displacment */
+ if (our_toc_offset >= 65535)
+ {
+ (*_bfd_error_handler)
+ (_("%s: Relocation for %s of %x exceeds Toc size limit"),
+ bfd_get_filename (input_bfd), name, our_toc_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ record_toc(toc_section, our_toc_offset, pub, strdup(name));
+ }
+ else if (IS_WRITTEN(our_toc_offset))
+ {
+ /* if it has been written out, it is marked with the
+ 1 bit. Fix up our offset, but do not write it out
+ again.
+ */
+ MAKE_ADDR_AGAIN(our_toc_offset);
+ }
+ else
+ {
+ record_toc(toc_section, our_toc_offset, pub, strdup(name));
+
+ /* write out the toc entry */
+ bfd_put_32(output_bfd,
+ val,
+ toc_section->contents + our_toc_offset);
+
+ MARK_AS_WRITTEN(h->toc_offset);
+ /* The tricky part is that this is the address that */
+ /* needs a .reloc entry for it */
+ fixit = true;
+ }
+ }
+
+ if (fixit && info->base_file)
+ {
+ /* So if this is non pcrelative, and is referenced
+ to a section or a common symbol, then it needs a reloc */
+
+ /* relocation to a symbol in a section which
+ isn't absolute - we output the address here
+ to a file */
+
+ bfd_vma addr = toc_section->output_section->vma
+ + toc_section->output_offset + our_toc_offset;
+
+ if (coff_data(output_bfd)->pe)
+ addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
+
+ fwrite (&addr, 1,4, (FILE *) info->base_file);
+ }
+
+
+ /* FIXME: this test is conservative */
+ if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN &&
+ our_toc_offset > toc_section->_raw_size)
+ {
+ (*_bfd_error_handler)
+ (_("%s: Relocation exceeds allocated TOC (%x)"),
+ bfd_get_filename (input_bfd),
+ toc_section->_raw_size);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Now we know the relocation for this toc reference */
+ relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT;
+ rstat = _bfd_relocate_contents (howto,
+ input_bfd,
+ relocation,
+ loc);
+ }
+ break;
+ case IMAGE_REL_PPC_IFGLUE:
+ {
+ /* To solve this, we need to know whether or not the symbol */
+ /* appearing on the call instruction is a glue function or not. */
+ /* A glue function must announce itself via a IMGLUE reloc, and */
+ /* the reloc contains the required toc restore instruction */
+
+ bfd_vma x;
+ const char *my_name;
+ DUMP_RELOC2(howto->name, rel);
+
+ if (h != 0)
+ {
+ my_name = h->root.root.root.string;
+ if (h->symbol_is_glue == 1)
+ {
+ x = bfd_get_32(input_bfd, loc);
+ bfd_put_32(input_bfd, h->glue_insn, loc);
+ }
+ }
+ }
+ break;
+ case IMAGE_REL_PPC_SECREL:
+ /* Unimplemented: codeview debugging information */
+ /* For fast access to the header of the section
+ containing the item. */
+ break;
+ case IMAGE_REL_PPC_SECTION:
+ /* Unimplemented: codeview debugging information */
+ /* Is used to indicate that the value should be relative
+ to the beginning of the section that contains the
+ symbol */
+ break;
+ case IMAGE_REL_PPC_ABSOLUTE:
+ {
+ const char *my_name;
+ if (h == 0)
+ my_name = (syms+symndx)->_n._n_name;
+ else
+ {
+ my_name = h->root.root.root.string;
+ }
+
+ fprintf(stderr,
+ _("Warning: unsupported reloc %s <file %s, section %s>\n"),
+ howto->name,
+ bfd_get_filename(input_bfd),
+ input_section->name);
+
+ fprintf(stderr,"sym %ld (%s), r_vaddr %ld (%lx)\n",
+ rel->r_symndx, my_name, (long) rel->r_vaddr,
+ (unsigned long) rel->r_vaddr);
+ }
+ break;
+ case IMAGE_REL_PPC_IMGLUE:
+ {
+ /* There is nothing to do now. This reloc was noted in the first
+ pass over the relocs, and the glue instruction extracted */
+ const char *my_name;
+ if (h->symbol_is_glue == 1)
+ break;
+ my_name = h->root.root.root.string;
+
+ (*_bfd_error_handler)
+ (_("%s: Out of order IMGLUE reloc for %s"),
+ bfd_get_filename (input_bfd), my_name);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ case IMAGE_REL_PPC_ADDR32NB:
+ {
+ struct coff_link_hash_entry *myh = 0;
+ const char *name = 0;
+ DUMP_RELOC2(howto->name, rel);
+
+ if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)
+ {
+ /* set magic values */
+ int idata5offset;
+ struct coff_link_hash_entry *myh = 0;
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ "__idata5_magic__",
+ false, false, true);
+ first_thunk_address = myh->root.u.def.value +
+ sec->output_section->vma +
+ sec->output_offset -
+ pe_data(output_bfd)->pe_opthdr.ImageBase;
+
+ idata5offset = myh->root.u.def.value;
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ "__idata6_magic__",
+ false, false, true);
+
+ thunk_size = myh->root.u.def.value - idata5offset;
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ "__idata4_magic__",
+ false, false, true);
+ import_table_size = myh->root.u.def.value;
+ }
+
+ if (h == 0)
+ { /* it is a file local symbol */
+ sym = syms + symndx;
+ name = sym->_n._n_name;
+ }
+ else
+ {
+ char *target = 0;
+
+ name = h->root.root.root.string;
+ if (strcmp(".idata$2", name) == 0)
+ target = "__idata2_magic__";
+ else if (strcmp(".idata$4", name) == 0)
+ target = "__idata4_magic__";
+ else if (strcmp(".idata$5", name) == 0)
+ target = "__idata5_magic__";
+
+ if (target != 0)
+ {
+ myh = 0;
+
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ target,
+ false, false, true);
+ if (myh == 0)
+ {
+ /* Missing magic cookies. Something is very wrong. */
+ abort();
+ }
+
+ val = myh->root.u.def.value +
+ sec->output_section->vma + sec->output_offset;
+ if (first_thunk_address == 0)
+ {
+ int idata5offset;
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ "__idata5_magic__",
+ false, false, true);
+ first_thunk_address = myh->root.u.def.value +
+ sec->output_section->vma +
+ sec->output_offset -
+ pe_data(output_bfd)->pe_opthdr.ImageBase;
+
+ idata5offset = myh->root.u.def.value;
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ "__idata6_magic__",
+ false, false, true);
+
+ thunk_size = myh->root.u.def.value - idata5offset;
+ myh = coff_link_hash_lookup (coff_hash_table (info),
+ "__idata4_magic__",
+ false, false, true);
+ import_table_size = myh->root.u.def.value;
+ }
+ }
+ }
+
+ rstat = _bfd_relocate_contents (howto,
+ input_bfd,
+ val -
+ pe_data(output_bfd)->pe_opthdr.ImageBase,
+ loc);
+ }
+ break;
+
+ case IMAGE_REL_PPC_REL24:
+ DUMP_RELOC2(howto->name, rel);
+ val -= (input_section->output_section->vma
+ + input_section->output_offset);
+
+ rstat = _bfd_relocate_contents (howto,
+ input_bfd,
+ val,
+ loc);
+ break;
+ case IMAGE_REL_PPC_ADDR16:
+ case IMAGE_REL_PPC_ADDR24:
+ case IMAGE_REL_PPC_ADDR32:
+ DUMP_RELOC2(howto->name, rel);
+ rstat = _bfd_relocate_contents (howto,
+ input_bfd,
+ val,
+ loc);
+ break;
+ }
+
+ if ( info->base_file )
+ {
+ /* So if this is non pcrelative, and is referenced
+ to a section or a common symbol, then it needs a reloc */
+ if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
+ {
+ /* relocation to a symbol in a section which
+ isn't absolute - we output the address here
+ to a file */
+ bfd_vma addr = rel->r_vaddr
+ - input_section->vma
+ + input_section->output_offset
+ + input_section->output_section->vma;
+
+ if (coff_data(output_bfd)->pe)
+ {
+ addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
+ }
+ fwrite (&addr, 1,4, (FILE *) info->base_file);
+ }
+ }
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.root.string;
+ else if (sym == NULL)
+ name = "*unknown*";
+ else if (sym->_n._n_n._n_zeroes == 0
+ && sym->_n._n_n._n_offset != 0)
+ name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
+ else
+ {
+ strncpy (buf, sym->_n._n_name, SYMNMLEN);
+ buf[SYMNMLEN] = '\0';
+ name = buf;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name,
+ (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ {
+ return false;
+ }
+ }
+ }
+
+ }
+
+ return true;
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+
+/* FIXME: BFD should not use global variables. This file is compiled
+ twice, and these variables are shared. This is confusing and
+ weird. */
+
+long int global_toc_size = 4;
+
+bfd* bfd_of_toc_owner = 0;
+
+long int import_table_size;
+long int first_thunk_address;
+long int thunk_size;
+
+struct list_ele *head;
+struct list_ele *tail;
+
+static char *
+h1 = N_("\n\t\t\tTOC MAPPING\n\n");
+static char *
+h2 = N_(" TOC disassembly Comments Name\n");
+static char *
+h3 = N_(" Offset spelling (if present)\n");
+
+void
+dump_toc (vfile)
+ PTR vfile;
+{
+ FILE *file = (FILE *) vfile;
+ struct list_ele *t;
+
+ fprintf(file, _(h1));
+ fprintf(file, _(h2));
+ fprintf(file, _(h3));
+
+ for(t = head; t != 0; t=t->next)
+ {
+ const char *cat = "";
+
+ if (t->cat == priv)
+ cat = _("private ");
+ else if (t->cat == pub)
+ cat = _("public ");
+ else if (t->cat == data)
+ cat = _("data-in-toc ");
+
+ if (t->offset > global_toc_size)
+ {
+ if (t->offset <= global_toc_size + thunk_size)
+ cat = _("IAT reference ");
+ else
+ {
+ fprintf(file,
+ _("**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n"),
+ global_toc_size, global_toc_size, thunk_size, thunk_size);
+ cat = _("Out of bounds!");
+ }
+ }
+
+ fprintf(file,
+ " %04lx (%d)", (unsigned long) t->offset, t->offset - 32768);
+ fprintf(file,
+ " %s %s\n",
+ cat, t->name);
+
+ }
+
+ fprintf(file, "\n");
+}
+
+boolean
+ppc_allocate_toc_section (info)
+ struct bfd_link_info *info;
+{
+ asection *s;
+ bfd_byte *foo;
+ static char test_char = '1';
+
+ if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */
+ return true;
+
+ if (bfd_of_toc_owner == 0)
+ {
+ /* No toc owner? Something is very wrong. */
+ abort();
+ }
+
+ s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME);
+ if (s == NULL)
+ {
+ /* No toc section? Something is very wrong. */
+ abort();
+ }
+
+ foo = (bfd_byte *) bfd_alloc(bfd_of_toc_owner, global_toc_size);
+ memset(foo, test_char, global_toc_size);
+
+ s->_raw_size = s->_cooked_size = global_toc_size;
+ s->contents = foo;
+
+ return true;
+}
+
+boolean
+ppc_process_before_allocation (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *sec;
+ struct internal_reloc *i, *rel;
+
+ /* here we have a bfd that is to be included on the link. We have a hook
+ to do reloc rummaging, before section sizes are nailed down. */
+
+ _bfd_coff_get_external_symbols(abfd);
+
+ /* rummage around all the relocs and map the toc */
+ sec = abfd->sections;
+
+ if (sec == 0)
+ {
+ return true;
+ }
+
+ for (; sec != 0; sec = sec->next)
+ {
+ if (sec->reloc_count == 0)
+ continue;
+
+ /* load the relocs */
+ /* FIXME: there may be a storage leak here */
+ i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0);
+
+ if (i == 0)
+ abort();
+
+ for (rel=i;rel<i+sec->reloc_count;++rel)
+ {
+ unsigned short r_type = EXTRACT_TYPE (rel->r_type);
+ unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
+ boolean ok = true;
+
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
+
+ switch(r_type)
+ {
+ case IMAGE_REL_PPC_TOCREL16:
+ /* if TOCDEFN is on, ignore as someone else has allocated the
+ toc entry */
+ if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN )
+ ok = ppc_record_toc_entry(abfd, info, sec,
+ rel->r_symndx, default_toc);
+ if (!ok)
+ return false;
+ break;
+ case IMAGE_REL_PPC_IMGLUE:
+ ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+#endif
+
+
+static bfd_reloc_status_type
+ppc_refhi_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("REFHI");
+ DUMP_RELOC("REFHI",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_undefined;
+}
+
+#if 0
+
+static bfd_reloc_status_type
+ppc_reflo_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("REFLO");
+ DUMP_RELOC("REFLO",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_undefined;
+}
+
+#endif
+
+static bfd_reloc_status_type
+ppc_pair_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("PAIR");
+ DUMP_RELOC("PAIR",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_undefined;
+}
+
+
+static bfd_reloc_status_type
+ppc_toc16_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("TOCREL16");
+ DUMP_RELOC("TOCREL16",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ {
+ return bfd_reloc_continue;
+ }
+
+ return bfd_reloc_ok;
+}
+
+#if 0
+
+/* ADDR32NB : 32 bit address relative to the virtual origin. */
+/* (On the alpha, this is always a linker generated thunk)*/
+/* (i.e. 32bit addr relative to the image base) */
+/* */
+/* */
+
+static bfd_reloc_status_type
+ppc_addr32nb_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("ADDR32NB");
+ DUMP_RELOC("ADDR32NB",reloc_entry);
+
+ return bfd_reloc_ok;
+}
+
+#endif
+
+static bfd_reloc_status_type
+ppc_secrel_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("SECREL");
+ DUMP_RELOC("SECREL",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+ppc_section_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("SECTION");
+ DUMP_RELOC("SECTION",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+ppc_imglue_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ UN_IMPL("IMGLUE");
+ DUMP_RELOC("IMGLUE",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_ok;
+}
+
+
+
+#define MAX_RELOC_INDEX \
+ (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1)
+
+
+/* FIXME: There is a possiblity that when we read in a reloc from a file,
+ that there are some bits encoded in the upper portion of the
+ type field. Not yet implemented.
+*/
+static void ppc_coff_rtype2howto PARAMS ((arelent *relent,
+ struct internal_reloc *internal));
+
+static void
+ppc_coff_rtype2howto (relent, internal)
+ arelent *relent;
+ struct internal_reloc *internal;
+{
+
+ /* We can encode one of three things in the type field, aside from the
+ type:
+ 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
+ value, rather than an addition value
+ 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
+ the branch is expected to be taken or not.
+ 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
+ For now, we just strip this stuff to find the type, and ignore it other
+ than that.
+ */
+ reloc_howto_type *howto;
+ unsigned short r_type = EXTRACT_TYPE (internal->r_type);
+ unsigned short r_flags = EXTRACT_FLAGS(internal->r_type);
+ unsigned short junk = EXTRACT_JUNK (internal->r_type);
+
+ /* the masking process only slices off the bottom byte for r_type. */
+ if ( r_type > MAX_RELOC_INDEX )
+ abort();
+
+ /* check for absolute crap */
+ if ( junk != 0 )
+ abort();
+
+ switch(r_type)
+ {
+ case IMAGE_REL_PPC_ADDR16:
+ case IMAGE_REL_PPC_REL24:
+ case IMAGE_REL_PPC_ADDR24:
+ case IMAGE_REL_PPC_ADDR32:
+ case IMAGE_REL_PPC_IFGLUE:
+ case IMAGE_REL_PPC_ADDR32NB:
+ case IMAGE_REL_PPC_SECTION:
+ case IMAGE_REL_PPC_SECREL:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ case IMAGE_REL_PPC_IMGLUE:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ case IMAGE_REL_PPC_TOCREL16:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal);
+ if (r_flags & IMAGE_REL_PPC_TOCDEFN)
+ howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
+ else
+ howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
+ break;
+ default:
+ fprintf(stderr,
+ _("Warning: Unsupported reloc %s [%d] used -- it may not work.\n"),
+ ppc_coff_howto_table[r_type].name,
+ r_type);
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ }
+
+ relent->howto = howto;
+
+}
+
+static reloc_howto_type *
+coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+ reloc_howto_type *howto;
+
+ /* We can encode one of three things in the type field, aside from the
+ type:
+ 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction
+ value, rather than an addition value
+ 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that
+ the branch is expected to be taken or not.
+ 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file
+ For now, we just strip this stuff to find the type, and ignore it other
+ than that.
+ */
+
+ unsigned short r_type = EXTRACT_TYPE (rel->r_type);
+ unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);
+ unsigned short junk = EXTRACT_JUNK (rel->r_type);
+
+ /* the masking process only slices off the bottom byte for r_type. */
+ if ( r_type > MAX_RELOC_INDEX )
+ abort();
+
+ /* check for absolute crap */
+ if ( junk != 0 )
+ abort();
+
+ switch(r_type)
+ {
+ case IMAGE_REL_PPC_ADDR32NB:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
+ *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ case IMAGE_REL_PPC_TOCREL16:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
+ if (r_flags & IMAGE_REL_PPC_TOCDEFN)
+ howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN;
+ else
+ howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
+ break;
+ case IMAGE_REL_PPC_ADDR16:
+ case IMAGE_REL_PPC_REL24:
+ case IMAGE_REL_PPC_ADDR24:
+ case IMAGE_REL_PPC_ADDR32:
+ case IMAGE_REL_PPC_IFGLUE:
+ case IMAGE_REL_PPC_SECTION:
+ case IMAGE_REL_PPC_SECREL:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ case IMAGE_REL_PPC_IMGLUE:
+ DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel);
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ default:
+ fprintf(stderr,
+ _("Warning: Unsupported reloc %s [%d] used -- it may not work.\n"),
+ ppc_coff_howto_table[r_type].name,
+ r_type);
+ howto = ppc_coff_howto_table + r_type;
+ break;
+ }
+
+ return howto;
+}
+
+
+/* a cheesy little macro to make the code a little more readable */
+#define HOW2MAP(bfd_rtype,ppc_rtype) \
+ case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype]
+
+static reloc_howto_type *ppc_coff_reloc_type_lookup
+PARAMS ((bfd *, bfd_reloc_code_real_type));
+
+static reloc_howto_type *
+ppc_coff_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ HOW2MAP(BFD_RELOC_32_GOTOFF, IMAGE_REL_PPC_IMGLUE);
+ HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE);
+ HOW2MAP(BFD_RELOC_16, IMAGE_REL_PPC_ADDR16);
+ HOW2MAP(BFD_RELOC_PPC_B26, IMAGE_REL_PPC_REL24);
+ HOW2MAP(BFD_RELOC_PPC_BA26, IMAGE_REL_PPC_ADDR24);
+ HOW2MAP(BFD_RELOC_PPC_TOC16, IMAGE_REL_PPC_TOCREL16);
+ HOW2MAP(BFD_RELOC_16_GOTOFF, IMAGE_REL_PPC_TOCREL16_DEFN);
+ HOW2MAP(BFD_RELOC_32, IMAGE_REL_PPC_ADDR32);
+ HOW2MAP(BFD_RELOC_RVA, IMAGE_REL_PPC_ADDR32NB);
+ default:
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+
+#undef HOW2MAP
+
+
+/* Tailor coffcode.h -- macro heaven. */
+
+#define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst)
+
+#ifndef COFF_IMAGE_WITH_PE
+static void ppc_coff_swap_sym_in_hook PARAMS ((bfd *, PTR, PTR));
+#endif
+
+/* We use the special COFF backend linker, with our own special touch. */
+
+#define coff_bfd_reloc_type_lookup ppc_coff_reloc_type_lookup
+#define coff_rtype_to_howto coff_ppc_rtype_to_howto
+#define coff_relocate_section coff_ppc_relocate_section
+#define coff_bfd_final_link ppc_bfd_coff_final_link
+
+#ifndef COFF_IMAGE_WITH_PE
+#define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook
+#endif
+
+#define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
+
+#define COFF_PAGE_SIZE 0x1000
+
+#define POWERPC_LE_PE
+
+#include "coffcode.h"
+
+
+
+#ifndef COFF_IMAGE_WITH_PE
+/* FIXME:
+ What we're trying to do here is allocate a toc section (early), and attach
+ it to the last bfd to be processed. This avoids the problem of having a toc
+ written out before all files have been processed. This code allocates
+ a toc section for every file, and records the last one seen. There are
+ at least two problems with this approach:
+ 1. We allocate whole bunches of toc sections that are ignored, but at
+ at least we will not allocate a toc if no .toc is present.
+ 2. It's not clear to me that being the last bfd read necessarily means
+ that you are the last bfd closed.
+ 3. Doing it on a "swap in" hook depends on when the "swap in" is called,
+ and how often, etc. It's not clear to me that there isn't a hole here.
+*/
+
+static void
+ppc_coff_swap_sym_in_hook (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
+{
+ struct internal_syment *in = (struct internal_syment *)in1;
+
+ if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */
+ return;
+
+ if (strcmp(in->_n._n_name, ".toc") == 0)
+ {
+ flagword flags;
+ register asection *s;
+
+ s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME);
+ if (s != NULL)
+ {
+ return;
+ }
+
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ;
+
+ s = bfd_make_section (abfd, TOC_SECTION_NAME);
+
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, flags)
+ || !bfd_set_section_alignment (abfd, s, 2))
+ {
+ /* FIXME: set appropriate bfd error */
+ abort();
+ }
+
+ /* save the bfd for later allocation */
+ bfd_of_toc_owner = abfd;
+ }
+
+ return;
+}
+#endif
+
+#ifndef COFF_IMAGE_WITH_PE
+
+static boolean ppc_do_last PARAMS ((bfd *));
+static bfd *ppc_get_last PARAMS ((void));
+
+static boolean
+ppc_do_last (abfd)
+ bfd *abfd;
+{
+ if (abfd == bfd_of_toc_owner)
+ return true;
+ else
+ return false;
+}
+
+static bfd *
+ppc_get_last()
+{
+ return bfd_of_toc_owner;
+}
+
+/* this piece of machinery exists only to guarantee that the bfd that holds
+ the toc section is written last.
+
+ This does depend on bfd_make_section attaching a new section to the
+ end of the section list for the bfd.
+
+ This is otherwise intended to be functionally the same as
+ cofflink.c:_bfd_coff_final_link(). It is specifically different only
+ where the POWERPC_LE_PE macro modifies the code. It is left in as a
+ precise form of comment. krk@cygnus.com
+*/
+#define POWERPC_LE_PE
+
+
+/* Do the final link step. */
+
+boolean
+ppc_bfd_coff_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd_size_type symesz;
+ struct coff_final_link_info finfo;
+ boolean debug_merge_allocated;
+ asection *o;
+ struct bfd_link_order *p;
+ size_t max_sym_count;
+ size_t max_lineno_count;
+ size_t max_reloc_count;
+ size_t max_output_reloc_count;
+ size_t max_contents_size;
+ file_ptr rel_filepos;
+ unsigned int relsz;
+ file_ptr line_filepos;
+ unsigned int linesz;
+ bfd *sub;
+ bfd_byte *external_relocs = NULL;
+ char strbuf[STRING_SIZE_SIZE];
+
+ symesz = bfd_coff_symesz (abfd);
+
+ finfo.info = info;
+ finfo.output_bfd = abfd;
+ finfo.strtab = NULL;
+ finfo.section_info = NULL;
+ finfo.last_file_index = -1;
+ finfo.last_bf_index = -1;
+ finfo.internal_syms = NULL;
+ finfo.sec_ptrs = NULL;
+ finfo.sym_indices = NULL;
+ finfo.outsyms = NULL;
+ finfo.linenos = NULL;
+ finfo.contents = NULL;
+ finfo.external_relocs = NULL;
+ finfo.internal_relocs = NULL;
+ debug_merge_allocated = false;
+
+ coff_data (abfd)->link_info = info;
+
+ finfo.strtab = _bfd_stringtab_init ();
+ if (finfo.strtab == NULL)
+ goto error_return;
+
+ if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
+ goto error_return;
+ debug_merge_allocated = true;
+
+ /* Compute the file positions for all the sections. */
+ if (! abfd->output_has_begun)
+ {
+ if (! bfd_coff_compute_section_file_positions (abfd))
+ return false;
+ }
+
+ /* Count the line numbers and relocation entries required for the
+ output file. Set the file positions for the relocs. */
+ rel_filepos = obj_relocbase (abfd);
+ relsz = bfd_coff_relsz (abfd);
+ max_contents_size = 0;
+ max_lineno_count = 0;
+ max_reloc_count = 0;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+
+ if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+
+ /* Mark all sections which are to be included in the
+ link. This will normally be every section. We need
+ to do this so that we can identify any sections which
+ the linker has decided to not include. */
+ sec->linker_mark = true;
+
+ if (info->strip == strip_none
+ || info->strip == strip_some)
+ o->lineno_count += sec->lineno_count;
+
+ if (info->relocateable)
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->_raw_size > max_contents_size)
+ max_contents_size = sec->_raw_size;
+ if (sec->lineno_count > max_lineno_count)
+ max_lineno_count = sec->lineno_count;
+ if (sec->reloc_count > max_reloc_count)
+ max_reloc_count = sec->reloc_count;
+ }
+ else if (info->relocateable
+ && (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order))
+ ++o->reloc_count;
+ }
+ if (o->reloc_count == 0)
+ o->rel_filepos = 0;
+ else
+ {
+ o->flags |= SEC_RELOC;
+ o->rel_filepos = rel_filepos;
+ rel_filepos += o->reloc_count * relsz;
+ }
+ }
+
+ /* If doing a relocateable link, allocate space for the pointers we
+ need to keep. */
+ if (info->relocateable)
+ {
+ unsigned int i;
+
+ /* We use section_count + 1, rather than section_count, because
+ the target_index fields are 1 based. */
+ finfo.section_info =
+ ((struct coff_link_section_info *)
+ bfd_malloc ((abfd->section_count + 1)
+ * sizeof (struct coff_link_section_info)));
+ if (finfo.section_info == NULL)
+ goto error_return;
+ for (i = 0; i <= abfd->section_count; i++)
+ {
+ finfo.section_info[i].relocs = NULL;
+ finfo.section_info[i].rel_hashes = NULL;
+ }
+ }
+
+ /* We now know the size of the relocs, so we can determine the file
+ positions of the line numbers. */
+ line_filepos = rel_filepos;
+ linesz = bfd_coff_linesz (abfd);
+ max_output_reloc_count = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->lineno_count == 0)
+ o->line_filepos = 0;
+ else
+ {
+ o->line_filepos = line_filepos;
+ line_filepos += o->lineno_count * linesz;
+ }
+
+ if (o->reloc_count != 0)
+ {
+ /* We don't know the indices of global symbols until we have
+ written out all the local symbols. For each section in
+ the output file, we keep an array of pointers to hash
+ table entries. Each entry in the array corresponds to a
+ reloc. When we find a reloc against a global symbol, we
+ set the corresponding entry in this array so that we can
+ fix up the symbol index after we have written out all the
+ local symbols.
+
+ Because of this problem, we also keep the relocs in
+ memory until the end of the link. This wastes memory,
+ but only when doing a relocateable link, which is not the
+ common case. */
+ BFD_ASSERT (info->relocateable);
+ finfo.section_info[o->target_index].relocs =
+ ((struct internal_reloc *)
+ bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
+ finfo.section_info[o->target_index].rel_hashes =
+ ((struct coff_link_hash_entry **)
+ bfd_malloc (o->reloc_count
+ * sizeof (struct coff_link_hash_entry *)));
+ if (finfo.section_info[o->target_index].relocs == NULL
+ || finfo.section_info[o->target_index].rel_hashes == NULL)
+ goto error_return;
+
+ if (o->reloc_count > max_output_reloc_count)
+ max_output_reloc_count = o->reloc_count;
+ }
+
+ /* Reset the reloc and lineno counts, so that we can use them to
+ count the number of entries we have output so far. */
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ }
+
+ obj_sym_filepos (abfd) = line_filepos;
+
+ /* Figure out the largest number of symbols in an input BFD. Take
+ the opportunity to clear the output_has_begun fields of all the
+ input BFD's. */
+ max_sym_count = 0;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ size_t sz;
+
+ sub->output_has_begun = false;
+ sz = obj_raw_syment_count (sub);
+ if (sz > max_sym_count)
+ max_sym_count = sz;
+ }
+
+ /* Allocate some buffers used while linking. */
+ finfo.internal_syms = ((struct internal_syment *)
+ bfd_malloc (max_sym_count
+ * sizeof (struct internal_syment)));
+ finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count
+ * sizeof (asection *));
+ finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
+ finfo.outsyms = ((bfd_byte *)
+ bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
+ finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
+ * bfd_coff_linesz (abfd));
+ finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
+ if (! info->relocateable)
+ finfo.internal_relocs = ((struct internal_reloc *)
+ bfd_malloc (max_reloc_count
+ * sizeof (struct internal_reloc)));
+ if ((finfo.internal_syms == NULL && max_sym_count > 0)
+ || (finfo.sec_ptrs == NULL && max_sym_count > 0)
+ || (finfo.sym_indices == NULL && max_sym_count > 0)
+ || finfo.outsyms == NULL
+ || (finfo.linenos == NULL && max_lineno_count > 0)
+ || (finfo.contents == NULL && max_contents_size > 0)
+ || (finfo.external_relocs == NULL && max_reloc_count > 0)
+ || (! info->relocateable
+ && finfo.internal_relocs == NULL
+ && max_reloc_count > 0))
+ goto error_return;
+
+ /* We now know the position of everything in the file, except that
+ we don't know the size of the symbol table and therefore we don't
+ know where the string table starts. We just build the string
+ table in memory as we go along. We process all the relocations
+ for a single input file at once. */
+ obj_raw_syment_count (abfd) = 0;
+
+ if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
+ {
+ if (! bfd_coff_start_final_link (abfd, info))
+ goto error_return;
+ }
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour (p->u.indirect.section->owner)
+ == bfd_target_coff_flavour))
+ {
+ sub = p->u.indirect.section->owner;
+#ifdef POWERPC_LE_PE
+ if (! sub->output_has_begun && !ppc_do_last(sub))
+#else
+ if (! sub->output_has_begun)
+#endif
+ {
+ if (! _bfd_coff_link_input_bfd (&finfo, sub))
+ goto error_return;
+ sub->output_has_begun = true;
+ }
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
+ goto error_return;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ }
+ }
+
+#ifdef POWERPC_LE_PE
+ {
+ bfd* last_one = ppc_get_last();
+ if (last_one)
+ {
+ if (! _bfd_coff_link_input_bfd (&finfo, last_one))
+ goto error_return;
+ }
+ last_one->output_has_begun = true;
+ }
+#endif
+
+ /* Free up the buffers used by _bfd_coff_link_input_bfd. */
+
+ coff_debug_merge_hash_table_free (&finfo.debug_merge);
+ debug_merge_allocated = false;
+
+ if (finfo.internal_syms != NULL)
+ {
+ free (finfo.internal_syms);
+ finfo.internal_syms = NULL;
+ }
+ if (finfo.sec_ptrs != NULL)
+ {
+ free (finfo.sec_ptrs);
+ finfo.sec_ptrs = NULL;
+ }
+ if (finfo.sym_indices != NULL)
+ {
+ free (finfo.sym_indices);
+ finfo.sym_indices = NULL;
+ }
+ if (finfo.linenos != NULL)
+ {
+ free (finfo.linenos);
+ finfo.linenos = NULL;
+ }
+ if (finfo.contents != NULL)
+ {
+ free (finfo.contents);
+ finfo.contents = NULL;
+ }
+ if (finfo.external_relocs != NULL)
+ {
+ free (finfo.external_relocs);
+ finfo.external_relocs = NULL;
+ }
+ if (finfo.internal_relocs != NULL)
+ {
+ free (finfo.internal_relocs);
+ finfo.internal_relocs = NULL;
+ }
+
+ /* The value of the last C_FILE symbol is supposed to be the symbol
+ index of the first external symbol. Write it out again if
+ necessary. */
+ if (finfo.last_file_index != -1
+ && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
+ {
+ finfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
+ (PTR) finfo.outsyms);
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + finfo.last_file_index * symesz),
+ SEEK_SET) != 0
+ || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
+ return false;
+ }
+
+ /* Write out the global symbols. */
+ finfo.failed = false;
+ coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
+ (PTR) &finfo);
+ if (finfo.failed)
+ goto error_return;
+
+ /* The outsyms buffer is used by _bfd_coff_write_global_sym. */
+ if (finfo.outsyms != NULL)
+ {
+ free (finfo.outsyms);
+ finfo.outsyms = NULL;
+ }
+
+ if (info->relocateable)
+ {
+ /* Now that we have written out all the global symbols, we know
+ the symbol indices to use for relocs against them, and we can
+ finally write out the relocs. */
+ external_relocs = ((bfd_byte *)
+ bfd_malloc (max_output_reloc_count * relsz));
+ if (external_relocs == NULL)
+ goto error_return;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct internal_reloc *irel;
+ struct internal_reloc *irelend;
+ struct coff_link_hash_entry **rel_hash;
+ bfd_byte *erel;
+
+ if (o->reloc_count == 0)
+ continue;
+
+ irel = finfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = finfo.section_info[o->target_index].rel_hashes;
+ erel = external_relocs;
+ for (; irel < irelend; irel++, rel_hash++, erel += relsz)
+ {
+ if (*rel_hash != NULL)
+ {
+ BFD_ASSERT ((*rel_hash)->indx >= 0);
+ irel->r_symndx = (*rel_hash)->indx;
+ }
+ bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
+ }
+
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
+ || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
+ abfd) != relsz * o->reloc_count)
+ goto error_return;
+ }
+
+ free (external_relocs);
+ external_relocs = NULL;
+ }
+
+ /* Free up the section information. */
+ if (finfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (finfo.section_info[i].relocs != NULL)
+ free (finfo.section_info[i].relocs);
+ if (finfo.section_info[i].rel_hashes != NULL)
+ free (finfo.section_info[i].rel_hashes);
+ }
+ free (finfo.section_info);
+ finfo.section_info = NULL;
+ }
+
+ /* If we have optimized stabs strings, output them. */
+ if (coff_hash_table (info)->stab_info != NULL)
+ {
+ if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
+ return false;
+ }
+
+ /* Write out the string table. */
+ if (obj_raw_syment_count (abfd) != 0)
+ {
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + obj_raw_syment_count (abfd) * symesz),
+ SEEK_SET) != 0)
+ return false;
+
+#if STRING_SIZE_SIZE == 4
+ bfd_h_put_32 (abfd,
+ _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
+ (bfd_byte *) strbuf);
+#else
+ #error Change bfd_h_put_32
+#endif
+
+ if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
+ return false;
+
+ if (! _bfd_stringtab_emit (abfd, finfo.strtab))
+ return false;
+ }
+
+ _bfd_stringtab_free (finfo.strtab);
+
+ /* Setting bfd_get_symcount to 0 will cause write_object_contents to
+ not try to write out the symbols. */
+ bfd_get_symcount (abfd) = 0;
+
+ return true;
+
+ error_return:
+ if (debug_merge_allocated)
+ coff_debug_merge_hash_table_free (&finfo.debug_merge);
+ if (finfo.strtab != NULL)
+ _bfd_stringtab_free (finfo.strtab);
+ if (finfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (finfo.section_info[i].relocs != NULL)
+ free (finfo.section_info[i].relocs);
+ if (finfo.section_info[i].rel_hashes != NULL)
+ free (finfo.section_info[i].rel_hashes);
+ }
+ free (finfo.section_info);
+ }
+ if (finfo.internal_syms != NULL)
+ free (finfo.internal_syms);
+ if (finfo.sec_ptrs != NULL)
+ free (finfo.sec_ptrs);
+ if (finfo.sym_indices != NULL)
+ free (finfo.sym_indices);
+ if (finfo.outsyms != NULL)
+ free (finfo.outsyms);
+ if (finfo.linenos != NULL)
+ free (finfo.linenos);
+ if (finfo.contents != NULL)
+ free (finfo.contents);
+ if (finfo.external_relocs != NULL)
+ free (finfo.external_relocs);
+ if (finfo.internal_relocs != NULL)
+ free (finfo.internal_relocs);
+ if (external_relocs != NULL)
+ free (external_relocs);
+ return false;
+}
+#endif
+
+
+/* The transfer vectors that lead the outside world to all of the above. */
+
+#ifdef TARGET_LITTLE_SYM
+const bfd_target
+TARGET_LITTLE_SYM =
+{
+ TARGET_LITTLE_NAME, /* name or coff-arm-little */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* FIXME: object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+#ifndef COFF_WITH_PE
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen??? FIXMEmgo */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+#endif
+
+#ifdef TARGET_BIG_SYM
+const bfd_target
+TARGET_BIG_SYM =
+{
+ TARGET_BIG_NAME,
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* FIXME: object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+#ifndef COFF_WITH_PE
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen??? FIXMEmgo */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p },
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+
+#endif
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
new file mode 100644
index 00000000000..6b4cd4429c2
--- /dev/null
+++ b/bfd/coff-rs6000.c
@@ -0,0 +1,1418 @@
+/* BFD back-end for IBM RS/6000 "XCOFF" files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ FIXME: Can someone provide a transliteration of this name into ASCII?
+ Using the following chars caused a compiler warning on HIUX (so I replaced
+ them with octal escapes), and isn't useful without an understanding of what
+ character set it is.
+ Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
+ and John Gilmore.
+ Archive support from Damon A. Permezel.
+ Contributed by IBM Corporation and Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Internalcoff.h and coffcode.h modify themselves based on this flag. */
+#define RS6000COFF_C 1
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/rs6000.h"
+#include "libcoff.h"
+
+/* The main body of code is in coffcode.h. */
+
+static boolean xcoff_mkobject PARAMS ((bfd *));
+static boolean xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static boolean xcoff_is_local_label_name PARAMS ((bfd *, const char *));
+static void xcoff_rtype2howto
+ PARAMS ((arelent *, struct internal_reloc *));
+static reloc_howto_type *xcoff_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static boolean xcoff_slurp_armap PARAMS ((bfd *));
+static const bfd_target *xcoff_archive_p PARAMS ((bfd *));
+static PTR xcoff_read_ar_hdr PARAMS ((bfd *));
+static bfd *xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
+static int xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
+static const char *normalize_filename PARAMS ((bfd *));
+static boolean xcoff_write_armap
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
+static boolean xcoff_write_archive_contents PARAMS ((bfd *));
+static int _bfd_xcoff_sizeof_headers PARAMS ((bfd *, boolean));
+
+/* We use our own tdata type. Its first field is the COFF tdata type,
+ so the COFF routines are compatible. */
+
+static boolean
+xcoff_mkobject (abfd)
+ bfd *abfd;
+{
+ coff_data_type *coff;
+
+ abfd->tdata.xcoff_obj_data =
+ ((struct xcoff_tdata *)
+ bfd_zalloc (abfd, sizeof (struct xcoff_tdata)));
+ if (abfd->tdata.xcoff_obj_data == NULL)
+ return false;
+ coff = coff_data (abfd);
+ coff->symbols = (coff_symbol_type *) NULL;
+ coff->conversion_table = (unsigned int *) NULL;
+ coff->raw_syments = (struct coff_ptr_struct *) NULL;
+ coff->relocbase = 0;
+
+ xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
+
+ /* We set cputype to -1 to indicate that it has not been
+ initialized. */
+ xcoff_data (abfd)->cputype = -1;
+
+ xcoff_data (abfd)->csects = NULL;
+ xcoff_data (abfd)->debug_indices = NULL;
+
+ return true;
+}
+
+/* Copy XCOFF data from one BFD to another. */
+
+static boolean
+xcoff_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ struct xcoff_tdata *ix, *ox;
+ asection *sec;
+
+ if (ibfd->xvec != obfd->xvec)
+ return true;
+ ix = xcoff_data (ibfd);
+ ox = xcoff_data (obfd);
+ ox->full_aouthdr = ix->full_aouthdr;
+ ox->toc = ix->toc;
+ if (ix->sntoc == 0)
+ ox->sntoc = 0;
+ else
+ {
+ sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
+ if (sec == NULL)
+ ox->sntoc = 0;
+ else
+ ox->sntoc = sec->output_section->target_index;
+ }
+ if (ix->snentry == 0)
+ ox->snentry = 0;
+ else
+ {
+ sec = coff_section_from_bfd_index (ibfd, ix->snentry);
+ if (sec == NULL)
+ ox->snentry = 0;
+ else
+ ox->snentry = sec->output_section->target_index;
+ }
+ ox->text_align_power = ix->text_align_power;
+ ox->data_align_power = ix->data_align_power;
+ ox->modtype = ix->modtype;
+ ox->cputype = ix->cputype;
+ ox->maxdata = ix->maxdata;
+ ox->maxstack = ix->maxstack;
+ return true;
+}
+
+/* I don't think XCOFF really has a notion of local labels based on
+ name. This will mean that ld -X doesn't actually strip anything.
+ The AIX native linker does not have a -X option, and it ignores the
+ -x option. */
+
+static boolean
+xcoff_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return false;
+}
+
+/* The XCOFF reloc table. Actually, XCOFF relocations specify the
+ bitsize and whether they are signed or not, along with a
+ conventional type. This table is for the types, which are used for
+ different algorithms for putting in the reloc. Many of these
+ relocs need special_function entries, which I have not written. */
+
+static reloc_howto_type xcoff_howto_table[] =
+{
+ /* Standard 32 bit relocation. */
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_POS", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit relocation, but store negative value. */
+ HOWTO (1, /* type */
+ 0, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_NEG", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative relocation. */
+ HOWTO (2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REL", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit TOC relative relocation. */
+ HOWTO (3, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TOC", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* I don't really know what this is. */
+ HOWTO (4, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RTB", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* External TOC relative symbol. */
+ HOWTO (5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_GL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Local TOC relative symbol. */
+ HOWTO (6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TCL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 7 },
+
+ /* Non modifiable absolute branch. */
+ HOWTO (8, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_BA", /* name */
+ true, /* partial_inplace */
+ 0x3fffffc, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 9 },
+
+ /* Non modifiable relative branch. */
+ HOWTO (0xa, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_BR", /* name */
+ true, /* partial_inplace */
+ 0x3fffffc, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 0xb },
+
+ /* Indirect load. */
+ HOWTO (0xc, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Load address. */
+ HOWTO (0xd, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RLA", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 0xe },
+
+ /* Non-relocating reference. */
+ HOWTO (0xf, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REF", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 0x10 },
+ { 0x11 },
+
+ /* TOC relative indirect load. */
+ HOWTO (0x12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TRL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TOC relative load address. */
+ HOWTO (0x13, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TRLA", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable relative branch. */
+ HOWTO (0x14, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RRTBI", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable absolute branch. */
+ HOWTO (0x15, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RRTBA", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable call absolute indirect. */
+ HOWTO (0x16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_CAI", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable call relative. */
+ HOWTO (0x17, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_CREL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch absolute. */
+ HOWTO (0x18, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RBA", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch absolute. */
+ HOWTO (0x19, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RBAC", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch relative. */
+ HOWTO (0x1a, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RBR", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch absolute. */
+ HOWTO (0x1b, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RBRC", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+static void
+xcoff_rtype2howto (relent, internal)
+ arelent *relent;
+ struct internal_reloc *internal;
+{
+ relent->howto = xcoff_howto_table + internal->r_type;
+
+ /* The r_size field of an XCOFF reloc encodes the bitsize of the
+ relocation, as well as indicating whether it is signed or not.
+ Doublecheck that the relocation information gathered from the
+ type matches this information. */
+ if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1)
+ abort ();
+#if 0
+ if ((internal->r_size & 0x80) != 0
+ ? (relent->howto->complain_on_overflow != complain_overflow_signed)
+ : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
+ abort ();
+#endif
+}
+
+static reloc_howto_type *
+xcoff_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_PPC_B26:
+ return &xcoff_howto_table[0xa];
+ case BFD_RELOC_PPC_BA26:
+ return &xcoff_howto_table[8];
+ case BFD_RELOC_PPC_TOC16:
+ return &xcoff_howto_table[3];
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return &xcoff_howto_table[0];
+ default:
+ return NULL;
+ }
+}
+
+#define SELECT_RELOC(internal, howto) \
+ { \
+ internal.r_type = howto->type; \
+ internal.r_size = \
+ ((howto->complain_on_overflow == complain_overflow_signed \
+ ? 0x80 \
+ : 0) \
+ | (howto->bitsize - 1)); \
+ }
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+#define COFF_LONG_FILENAMES
+
+#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
+
+#define coff_mkobject xcoff_mkobject
+#define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data
+#define coff_bfd_is_local_label_name xcoff_is_local_label_name
+#define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup
+#define coff_relocate_section _bfd_ppc_xcoff_relocate_section
+
+#include "coffcode.h"
+
+/* XCOFF archive support. The original version of this code was by
+ Damon A. Permezel. It was enhanced to permit cross support, and
+ writing archive files, by Ian Lance Taylor, Cygnus Support.
+
+ XCOFF uses its own archive format. Everything is hooked together
+ with file offset links, so it is possible to rapidly update an
+ archive in place. Of course, we don't do that. An XCOFF archive
+ has a real file header, not just an ARMAG string. The structure of
+ the file header and of each archive header appear below.
+
+ An XCOFF archive also has a member table, which is a list of
+ elements in the archive (you can get that by looking through the
+ linked list, but you have to read a lot more of the file). The
+ member table has a normal archive header with an empty name. It is
+ normally (and perhaps must be) the second to last entry in the
+ archive. The member table data is almost printable ASCII. It
+ starts with a 12 character decimal string which is the number of
+ entries in the table. For each entry it has a 12 character decimal
+ string which is the offset in the archive of that member. These
+ entries are followed by a series of null terminated strings which
+ are the member names for each entry.
+
+ Finally, an XCOFF archive has a global symbol table, which is what
+ we call the armap. The global symbol table has a normal archive
+ header with an empty name. It is normally (and perhaps must be)
+ the last entry in the archive. The contents start with a four byte
+ binary number which is the number of entries. This is followed by
+ a that many four byte binary numbers; each is the file offset of an
+ entry in the archive. These numbers are followed by a series of
+ null terminated strings, which are symbol names. */
+
+/* XCOFF archives use this as a magic string. */
+
+#define XCOFFARMAG "<aiaff>\012"
+#define SXCOFFARMAG 8
+
+/* This terminates an XCOFF archive member name. */
+
+#define XCOFFARFMAG "`\012"
+#define SXCOFFARFMAG 2
+
+/* XCOFF archives start with this (printable) structure. */
+
+struct xcoff_ar_file_hdr
+{
+ /* Magic string. */
+ char magic[SXCOFFARMAG];
+
+ /* Offset of the member table (decimal ASCII string). */
+ char memoff[12];
+
+ /* Offset of the global symbol table (decimal ASCII string). */
+ char symoff[12];
+
+ /* Offset of the first member in the archive (decimal ASCII string). */
+ char firstmemoff[12];
+
+ /* Offset of the last member in the archive (decimal ASCII string). */
+ char lastmemoff[12];
+
+ /* Offset of the first member on the free list (decimal ASCII
+ string). */
+ char freeoff[12];
+};
+
+#define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG)
+
+/* Each XCOFF archive member starts with this (printable) structure. */
+
+struct xcoff_ar_hdr
+{
+ /* File size not including the header (decimal ASCII string). */
+ char size[12];
+
+ /* File offset of next archive member (decimal ASCII string). */
+ char nextoff[12];
+
+ /* File offset of previous archive member (decimal ASCII string). */
+ char prevoff[12];
+
+ /* File mtime (decimal ASCII string). */
+ char date[12];
+
+ /* File UID (decimal ASCII string). */
+ char uid[12];
+
+ /* File GID (decimal ASCII string). */
+ char gid[12];
+
+ /* File mode (octal ASCII string). */
+ char mode[12];
+
+ /* Length of file name (decimal ASCII string). */
+ char namlen[4];
+
+ /* This structure is followed by the file name. The length of the
+ name is given in the namlen field. If the length of the name is
+ odd, the name is followed by a null byte. The name and optional
+ null byte are followed by XCOFFARFMAG, which is not included in
+ namlen. The contents of the archive member follow; the number of
+ bytes is given in the size field. */
+};
+
+#define SIZEOF_AR_HDR (7 * 12 + 4)
+
+/* We store a copy of the xcoff_ar_file_hdr in the tdata field of the
+ artdata structure. */
+#define xcoff_ardata(abfd) \
+ ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata)
+
+/* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
+ archive element. */
+#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
+#define arch_xhdr(bfd) \
+ ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header)
+
+/* XCOFF archives do not have anything which corresponds to an
+ extended name table. */
+
+#define xcoff_slurp_extended_name_table bfd_false
+#define xcoff_construct_extended_name_table \
+ ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
+ bfd_false)
+#define xcoff_truncate_arname bfd_dont_truncate_arname
+
+/* We can use the standard get_elt_at_index routine. */
+
+#define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
+
+/* XCOFF archives do not have a timestamp. */
+
+#define xcoff_update_armap_timestamp bfd_true
+
+/* Read in the armap of an XCOFF archive. */
+
+static boolean
+xcoff_slurp_armap (abfd)
+ bfd *abfd;
+{
+ file_ptr off;
+ struct xcoff_ar_hdr hdr;
+ size_t namlen;
+ bfd_size_type sz;
+ bfd_byte *contents, *cend;
+ unsigned int c, i;
+ carsym *arsym;
+ bfd_byte *p;
+
+ if (xcoff_ardata (abfd) == NULL)
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
+ if (off == 0)
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ if (bfd_seek (abfd, off, SEEK_SET) != 0)
+ return false;
+
+ /* The symbol table starts with a normal archive header. */
+ if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
+ return false;
+
+ /* Skip the name (normally empty). */
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0)
+ return false;
+
+ /* Read in the entire symbol table. */
+ sz = strtol (hdr.size, (char **) NULL, 10);
+ contents = (bfd_byte *) bfd_alloc (abfd, sz);
+ if (contents == NULL)
+ return false;
+ if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
+ return false;
+
+ /* The symbol table starts with a four byte count. */
+ c = bfd_h_get_32 (abfd, contents);
+
+ if (c * 4 >= sz)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ bfd_ardata (abfd)->symdefs = ((carsym *)
+ bfd_alloc (abfd, c * sizeof (carsym)));
+ if (bfd_ardata (abfd)->symdefs == NULL)
+ return false;
+
+ /* After the count comes a list of four byte file offsets. */
+ for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
+ i < c;
+ ++i, ++arsym, p += 4)
+ arsym->file_offset = bfd_h_get_32 (abfd, p);
+
+ /* After the file offsets come null terminated symbol names. */
+ cend = contents + sz;
+ for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
+ i < c;
+ ++i, ++arsym, p += strlen ((char *) p) + 1)
+ {
+ if (p >= cend)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ arsym->name = (char *) p;
+ }
+
+ bfd_ardata (abfd)->symdef_count = c;
+ bfd_has_map (abfd) = true;
+
+ return true;
+}
+
+/* See if this is an XCOFF archive. */
+
+static const bfd_target *
+xcoff_archive_p (abfd)
+ bfd *abfd;
+{
+ struct xcoff_ar_file_hdr hdr;
+
+ if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd)
+ != SIZEOF_AR_FILE_HDR)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
+ involves a cast, we can't do it as the left operand of
+ assignment. */
+ abfd->tdata.aout_ar_data =
+ (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
+
+ if (bfd_ardata (abfd) == (struct artdata *) NULL)
+ return NULL;
+
+ bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
+ (char **) NULL, 10);
+ bfd_ardata (abfd)->cache = NULL;
+ bfd_ardata (abfd)->archive_head = NULL;
+ bfd_ardata (abfd)->symdefs = NULL;
+ bfd_ardata (abfd)->extended_names = NULL;
+
+ bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR);
+ if (bfd_ardata (abfd)->tdata == NULL)
+ return NULL;
+
+ memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
+
+ if (! xcoff_slurp_armap (abfd))
+ {
+ bfd_release (abfd, bfd_ardata (abfd));
+ abfd->tdata.aout_ar_data = (struct artdata *) NULL;
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+/* Read the archive header in an XCOFF archive. */
+
+static PTR
+xcoff_read_ar_hdr (abfd)
+ bfd *abfd;
+{
+ struct xcoff_ar_hdr hdr;
+ size_t namlen;
+ struct xcoff_ar_hdr *hdrp;
+ struct areltdata *ret;
+
+ if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
+ return NULL;
+
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1);
+ if (hdrp == NULL)
+ return NULL;
+ memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
+ if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen)
+ return NULL;
+ ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
+
+ ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata));
+ if (ret == NULL)
+ return NULL;
+ ret->arch_header = (char *) hdrp;
+ ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
+ ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
+
+ /* Skip over the XCOFFARFMAG at the end of the file name. */
+ if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0)
+ return NULL;
+
+ return (PTR) ret;
+}
+
+/* Open the next element in an XCOFF archive. */
+
+static bfd *
+xcoff_openr_next_archived_file (archive, last_file)
+ bfd *archive;
+ bfd *last_file;
+{
+ file_ptr filestart;
+
+ if (xcoff_ardata (archive) == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ if (last_file == NULL)
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ else
+ filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10);
+
+ if (filestart == 0
+ || filestart == strtol (xcoff_ardata (archive)->memoff,
+ (char **) NULL, 10)
+ || filestart == strtol (xcoff_ardata (archive)->symoff,
+ (char **) NULL, 10))
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+
+ return _bfd_get_elt_at_filepos (archive, filestart);
+}
+
+/* Stat an element in an XCOFF archive. */
+
+static int
+xcoff_generic_stat_arch_elt (abfd, s)
+ bfd *abfd;
+ struct stat *s;
+{
+ struct xcoff_ar_hdr *hdrp;
+
+ if (abfd->arelt_data == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ hdrp = arch_xhdr (abfd);
+
+ s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
+ s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
+ s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
+ s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
+ s->st_size = arch_eltdata (abfd)->parsed_size;
+
+ return 0;
+}
+
+/* Normalize a file name for inclusion in an archive. */
+
+static const char *
+normalize_filename (abfd)
+ bfd *abfd;
+{
+ const char *file;
+ const char *filename;
+
+ file = bfd_get_filename (abfd);
+ filename = strrchr (file, '/');
+ if (filename != NULL)
+ filename++;
+ else
+ filename = file;
+ return filename;
+}
+
+/* Write out an XCOFF armap. */
+
+/*ARGSUSED*/
+static boolean
+xcoff_write_armap (abfd, elength, map, orl_count, stridx)
+ bfd *abfd;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int orl_count;
+ int stridx;
+{
+ struct xcoff_ar_hdr hdr;
+ char *p;
+ unsigned char buf[4];
+ bfd *sub;
+ file_ptr fileoff;
+ unsigned int i;
+
+ memset (&hdr, 0, sizeof hdr);
+ sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
+ sprintf (hdr.nextoff, "%d", 0);
+ memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12);
+ sprintf (hdr.date, "%d", 0);
+ sprintf (hdr.uid, "%d", 0);
+ sprintf (hdr.gid, "%d", 0);
+ sprintf (hdr.mode, "%d", 0);
+ sprintf (hdr.namlen, "%d", 0);
+
+ /* We need spaces, not null bytes, in the header. */
+ for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
+ if (*p == '\0')
+ *p = ' ';
+
+ if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR
+ || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
+ return false;
+
+ bfd_h_put_32 (abfd, orl_count, buf);
+ if (bfd_write (buf, 1, 4, abfd) != 4)
+ return false;
+
+ sub = abfd->archive_head;
+ fileoff = SIZEOF_AR_FILE_HDR;
+ i = 0;
+ while (sub != NULL && i < orl_count)
+ {
+ size_t namlen;
+
+ while (((bfd *) (map[i]).pos) == sub)
+ {
+ bfd_h_put_32 (abfd, fileoff, buf);
+ if (bfd_write (buf, 1, 4, abfd) != 4)
+ return false;
+ ++i;
+ }
+ namlen = strlen (normalize_filename (sub));
+ namlen = (namlen + 1) &~ 1;
+ fileoff += (SIZEOF_AR_HDR
+ + namlen
+ + SXCOFFARFMAG
+ + arelt_size (sub));
+ fileoff = (fileoff + 1) &~ 1;
+ sub = sub->next;
+ }
+
+ for (i = 0; i < orl_count; i++)
+ {
+ const char *name;
+ size_t namlen;
+
+ name = *map[i].name;
+ namlen = strlen (name);
+ if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
+ return false;
+ }
+
+ if ((stridx & 1) != 0)
+ {
+ char b;
+
+ b = '\0';
+ if (bfd_write (&b, 1, 1, abfd) != 1)
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out an XCOFF archive. We always write an entire archive,
+ rather than fussing with the freelist and so forth. */
+
+static boolean
+xcoff_write_archive_contents (abfd)
+ bfd *abfd;
+{
+ struct xcoff_ar_file_hdr fhdr;
+ size_t count;
+ size_t total_namlen;
+ file_ptr *offsets;
+ boolean makemap;
+ boolean hasobjects;
+ file_ptr prevoff, nextoff;
+ bfd *sub;
+ unsigned int i;
+ struct xcoff_ar_hdr ahdr;
+ bfd_size_type size;
+ char *p;
+ char decbuf[13];
+
+ memset (&fhdr, 0, sizeof fhdr);
+ strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
+ sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
+ sprintf (fhdr.freeoff, "%d", 0);
+
+ count = 0;
+ total_namlen = 0;
+ for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
+ {
+ ++count;
+ total_namlen += strlen (normalize_filename (sub)) + 1;
+ }
+ offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
+ if (offsets == NULL)
+ return false;
+
+ if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
+ return false;
+
+ makemap = bfd_has_map (abfd);
+ hasobjects = false;
+ prevoff = 0;
+ nextoff = SIZEOF_AR_FILE_HDR;
+ for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
+ {
+ const char *name;
+ size_t namlen;
+ struct xcoff_ar_hdr *ahdrp;
+ bfd_size_type remaining;
+
+ if (makemap && ! hasobjects)
+ {
+ if (bfd_check_format (sub, bfd_object))
+ hasobjects = true;
+ }
+
+ name = normalize_filename (sub);
+ namlen = strlen (name);
+
+ if (sub->arelt_data != NULL)
+ ahdrp = arch_xhdr (sub);
+ else
+ ahdrp = NULL;
+
+ if (ahdrp == NULL)
+ {
+ struct stat s;
+
+ memset (&ahdr, 0, sizeof ahdr);
+ ahdrp = &ahdr;
+ if (stat (bfd_get_filename (sub), &s) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return false;
+ }
+
+ sprintf (ahdrp->size, "%ld", (long) s.st_size);
+ sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
+ sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
+ sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
+ sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
+
+ if (sub->arelt_data == NULL)
+ {
+ sub->arelt_data = bfd_alloc (sub, sizeof (struct areltdata));
+ if (sub->arelt_data == NULL)
+ return false;
+ }
+
+ arch_eltdata (sub)->parsed_size = s.st_size;
+ }
+
+ sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
+ sprintf (ahdrp->namlen, "%ld", (long) namlen);
+
+ /* If the length of the name is odd, we write out the null byte
+ after the name as well. */
+ namlen = (namlen + 1) &~ 1;
+
+ remaining = arelt_size (sub);
+ size = (SIZEOF_AR_HDR
+ + namlen
+ + SXCOFFARFMAG
+ + remaining);
+
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+
+ offsets[i] = nextoff;
+
+ prevoff = nextoff;
+ nextoff += size + (size & 1);
+
+ sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
+
+ /* We need spaces, not null bytes, in the header. */
+ for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
+ if (*p == '\0')
+ *p = ' ';
+
+ if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
+ || bfd_write ((PTR) name, 1, namlen, abfd) != namlen
+ || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
+ != SXCOFFARFMAG))
+ return false;
+
+ if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+ while (remaining != 0)
+ {
+ bfd_size_type amt;
+ bfd_byte buffer[DEFAULT_BUFFERSIZE];
+
+ amt = sizeof buffer;
+ if (amt > remaining)
+ amt = remaining;
+ if (bfd_read (buffer, 1, amt, sub) != amt
+ || bfd_write (buffer, 1, amt, abfd) != amt)
+ return false;
+ remaining -= amt;
+ }
+
+ if ((size & 1) != 0)
+ {
+ bfd_byte b;
+
+ b = '\0';
+ if (bfd_write (&b, 1, 1, abfd) != 1)
+ return false;
+ }
+ }
+
+ sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
+
+ /* Write out the member table. */
+
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+ sprintf (fhdr.memoff, "%ld", (long) nextoff);
+
+ memset (&ahdr, 0, sizeof ahdr);
+ sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen));
+ sprintf (ahdr.prevoff, "%ld", (long) prevoff);
+ sprintf (ahdr.date, "%d", 0);
+ sprintf (ahdr.uid, "%d", 0);
+ sprintf (ahdr.gid, "%d", 0);
+ sprintf (ahdr.mode, "%d", 0);
+ sprintf (ahdr.namlen, "%d", 0);
+
+ size = (SIZEOF_AR_HDR
+ + 12
+ + count * 12
+ + total_namlen
+ + SXCOFFARFMAG);
+
+ prevoff = nextoff;
+ nextoff += size + (size & 1);
+
+ if (makemap && hasobjects)
+ sprintf (ahdr.nextoff, "%ld", (long) nextoff);
+ else
+ sprintf (ahdr.nextoff, "%d", 0);
+
+ /* We need spaces, not null bytes, in the header. */
+ for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
+ if (*p == '\0')
+ *p = ' ';
+
+ if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
+ || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
+ != SXCOFFARFMAG))
+ return false;
+
+ sprintf (decbuf, "%-12ld", (long) count);
+ if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
+ return false;
+ for (i = 0; i < count; i++)
+ {
+ sprintf (decbuf, "%-12ld", (long) offsets[i]);
+ if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
+ return false;
+ }
+ for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
+ {
+ const char *name;
+ size_t namlen;
+
+ name = normalize_filename (sub);
+ namlen = strlen (name);
+ if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1)
+ return false;
+ }
+ if ((size & 1) != 0)
+ {
+ bfd_byte b;
+
+ b = '\0';
+ if (bfd_write ((PTR) &b, 1, 1, abfd) != 1)
+ return false;
+ }
+
+ /* Write out the armap, if appropriate. */
+
+ if (! makemap || ! hasobjects)
+ sprintf (fhdr.symoff, "%d", 0);
+ else
+ {
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+ sprintf (fhdr.symoff, "%ld", (long) nextoff);
+ bfd_ardata (abfd)->tdata = (PTR) &fhdr;
+ if (! _bfd_compute_and_write_armap (abfd, 0))
+ return false;
+ }
+
+ /* Write out the archive file header. */
+
+ /* We need spaces, not null bytes, in the header. */
+ for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
+ if (*p == '\0')
+ *p = ' ';
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR, 1, abfd) !=
+ SIZEOF_AR_FILE_HDR))
+ return false;
+
+ return true;
+}
+
+/* We can't use the usual coff_sizeof_headers routine, because AIX
+ always uses an a.out header. */
+
+/*ARGSUSED*/
+static int
+_bfd_xcoff_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+ int size;
+
+ size = FILHSZ;
+ if (xcoff_data (abfd)->full_aouthdr)
+ size += AOUTSZ;
+ else
+ size += SMALL_AOUTSZ;
+ size += abfd->section_count * SCNHSZ;
+ return size;
+}
+
+#define CORE_FILE_P _bfd_dummy_target
+
+#define coff_core_file_failing_command _bfd_nocore_core_file_failing_command
+#define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal
+#define coff_core_file_matches_executable_p \
+ _bfd_nocore_core_file_matches_executable_p
+
+#ifdef AIX_CORE
+#undef CORE_FILE_P
+#define CORE_FILE_P rs6000coff_core_p
+extern const bfd_target * rs6000coff_core_p ();
+extern boolean rs6000coff_get_section_contents ();
+extern boolean rs6000coff_core_file_matches_executable_p ();
+
+#undef coff_core_file_matches_executable_p
+#define coff_core_file_matches_executable_p \
+ rs6000coff_core_file_matches_executable_p
+
+extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd));
+#undef coff_core_file_failing_command
+#define coff_core_file_failing_command rs6000coff_core_file_failing_command
+
+extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd));
+#undef coff_core_file_failing_signal
+#define coff_core_file_failing_signal rs6000coff_core_file_failing_signal
+
+#undef coff_get_section_contents
+#define coff_get_section_contents rs6000coff_get_section_contents
+#endif /* AIX_CORE */
+
+#ifdef LYNX_CORE
+
+#undef CORE_FILE_P
+#define CORE_FILE_P lynx_core_file_p
+extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd));
+
+extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
+ bfd *exec_bfd));
+#undef coff_core_file_matches_executable_p
+#define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p
+
+extern char *lynx_core_file_failing_command PARAMS ((bfd *abfd));
+#undef coff_core_file_failing_command
+#define coff_core_file_failing_command lynx_core_file_failing_command
+
+extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd));
+#undef coff_core_file_failing_signal
+#define coff_core_file_failing_signal lynx_core_file_failing_signal
+
+#endif /* LYNX_CORE */
+
+#define _bfd_xcoff_bfd_get_relocated_section_contents \
+ coff_bfd_get_relocated_section_contents
+#define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section
+#define _bfd_xcoff_bfd_gc_sections coff_bfd_gc_sections
+#define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section
+
+/* The transfer vector that leads the outside world to all of the above. */
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ rs6000coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "aixcoff-rs6000", /* name */
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG | DYNAMIC |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen??? FIXMEmgo */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ xcoff_archive_p, CORE_FILE_P},
+ {bfd_false, coff_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ xcoff_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (coff),
+ BFD_JUMP_TABLE_ARCHIVE (xcoff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (_bfd_xcoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c
new file mode 100644
index 00000000000..e3d6eec00d9
--- /dev/null
+++ b/bfd/coff-sh.c
@@ -0,0 +1,2959 @@
+/* BFD back-end for Hitachi Super-H COFF binaries.
+ Copyright 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Written by Steve Chamberlain, <sac@cygnus.com>.
+ Relaxing code written by Ian Lance Taylor, <ian@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/sh.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+/* Internal functions. */
+static bfd_reloc_status_type sh_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static long get_symbol_value PARAMS ((asymbol *));
+static boolean sh_merge_private_data PARAMS ((bfd *, bfd *));
+static boolean sh_relax_section
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+static boolean sh_relax_delete_bytes
+ PARAMS ((bfd *, asection *, bfd_vma, int));
+static const struct sh_opcode *sh_insn_info PARAMS ((unsigned int));
+static boolean sh_align_loads
+ PARAMS ((bfd *, asection *, struct internal_reloc *, bfd_byte *, boolean *));
+static boolean sh_swap_insns
+ PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
+static boolean sh_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+static bfd_byte *sh_coff_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, boolean, asymbol **));
+
+/* Default section alignment to 2**4. */
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (4)
+
+/* Generate long file names. */
+#define COFF_LONG_FILENAMES
+
+/* The supported relocations. There are a lot of relocations defined
+ in coff/internal.h which we do not expect to ever see. */
+static reloc_howto_type sh_coff_howtos[] =
+{
+ { 0 },
+ { 1 },
+ { 2 },
+ { 3 }, /* R_SH_PCREL8 */
+ { 4 }, /* R_SH_PCREL16 */
+ { 5 }, /* R_SH_HIGH8 */
+ { 6 }, /* R_SH_IMM24 */
+ { 7 }, /* R_SH_LOW16 */
+ { 8 },
+ { 9 }, /* R_SH_PCDISP8BY4 */
+
+ HOWTO (R_SH_PCDISP8BY2, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_pcdisp8by2", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ { 11 }, /* R_SH_PCDISP8 */
+
+ HOWTO (R_SH_PCDISP, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_pcdisp12by2", /* name */
+ true, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ { 13 },
+
+ HOWTO (R_SH_IMM32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_imm32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 15 },
+ { 16 }, /* R_SH_IMM8 */
+ { 17 }, /* R_SH_IMM8BY2 */
+ { 18 }, /* R_SH_IMM8BY4 */
+ { 19 }, /* R_SH_IMM4 */
+ { 20 }, /* R_SH_IMM4BY2 */
+ { 21 }, /* R_SH_IMM4BY4 */
+
+ HOWTO (R_SH_PCRELIMM8BY2, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_pcrelimm8by2", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_SH_PCRELIMM8BY4, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_pcrelimm8by4", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_SH_IMM16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_imm16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_SWITCH16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_switch16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_SWITCH32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_switch32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_USES, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_uses", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_COUNT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_count", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_ALIGN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_align", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_CODE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_code", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_DATA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_data", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_LABEL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_label", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_SH_SWITCH8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_reloc, /* special_function */
+ "r_switch8", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+#define SH_COFF_HOWTO_COUNT (sizeof sh_coff_howtos / sizeof sh_coff_howtos[0])
+
+/* Check for a bad magic number. */
+#define BADMAG(x) SHBADMAG(x)
+
+/* Customize coffcode.h (this is not currently used). */
+#define SH 1
+
+/* FIXME: This should not be set here. */
+#define __A_MAGIC_SET__
+
+/* Swap the r_offset field in and out. */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+
+/* Swap out extra information in the reloc structure. */
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
+ do \
+ { \
+ dst->r_stuff[0] = 'S'; \
+ dst->r_stuff[1] = 'C'; \
+ } \
+ while (0)
+
+/* Get the value of a symbol, when performing a relocation. */
+
+static long
+get_symbol_value (symbol)
+ asymbol *symbol;
+{
+ bfd_vma relocation;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = (symbol->value +
+ symbol->section->output_section->vma +
+ symbol->section->output_offset);
+
+ return relocation;
+}
+
+/* This macro is used in coffcode.h to get the howto corresponding to
+ an internal reloc. */
+
+#define RTYPE2HOWTO(relent, internal) \
+ ((relent)->howto = \
+ ((internal)->r_type < SH_COFF_HOWTO_COUNT \
+ ? &sh_coff_howtos[(internal)->r_type] \
+ : (reloc_howto_type *) NULL))
+
+/* This is the same as the macro in coffcode.h, except that it copies
+ r_offset into reloc_entry->addend for some relocs. */
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ if (coffsym != (coff_symbol_type *) NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = 0; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != (asection *) NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if ((reloc).r_type == R_SH_SWITCH8 \
+ || (reloc).r_type == R_SH_SWITCH16 \
+ || (reloc).r_type == R_SH_SWITCH32 \
+ || (reloc).r_type == R_SH_USES \
+ || (reloc).r_type == R_SH_COUNT \
+ || (reloc).r_type == R_SH_ALIGN) \
+ cache_ptr->addend = (reloc).r_offset; \
+ }
+
+/* This is the howto function for the SH relocations. */
+
+static bfd_reloc_status_type
+sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ unsigned long insn;
+ bfd_vma sym_value;
+ unsigned short r_type;
+ bfd_vma addr = reloc_entry->address;
+ bfd_byte *hit_data = addr + (bfd_byte *) data;
+
+ r_type = reloc_entry->howto->type;
+
+ if (output_bfd != NULL)
+ {
+ /* Partial linking--do nothing. */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Almost all relocs have to do with relaxing. If any work must be
+ done for them, it has been done in sh_relax_section. */
+ if (r_type != R_SH_IMM32
+ && (r_type != R_SH_PCDISP
+ || (symbol_in->flags & BSF_LOCAL) != 0))
+ return bfd_reloc_ok;
+
+ if (symbol_in != NULL
+ && bfd_is_und_section (symbol_in->section))
+ return bfd_reloc_undefined;
+
+ sym_value = get_symbol_value (symbol_in);
+
+ switch (r_type)
+ {
+ case R_SH_IMM32:
+ insn = bfd_get_32 (abfd, hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_put_32 (abfd, insn, hit_data);
+ break;
+ case R_SH_PCDISP:
+ insn = bfd_get_16 (abfd, hit_data);
+ sym_value += reloc_entry->addend;
+ sym_value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + addr
+ + 4);
+ sym_value += (insn & 0xfff) << 1;
+ if (insn & 0x800)
+ sym_value -= 0x1000;
+ insn = (insn & 0xf000) | (sym_value & 0xfff);
+ bfd_put_16 (abfd, insn, hit_data);
+ if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000)
+ return bfd_reloc_overflow;
+ break;
+ default:
+ abort ();
+ break;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* This routine checks for linking big and little endian objects
+ together. */
+
+static boolean
+sh_merge_private_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ if (ibfd->xvec->byteorder != obfd->xvec->byteorder
+ && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ (*_bfd_error_handler)
+ ("%s: compiled for a %s endian system and target is %s endian",
+ bfd_get_filename (ibfd),
+ bfd_big_endian (ibfd) ? "big" : "little",
+ bfd_big_endian (obfd) ? "big" : "little");
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ return true;
+}
+
+#define coff_bfd_merge_private_bfd_data sh_merge_private_data
+
+/* We can do relaxing. */
+#define coff_bfd_relax_section sh_relax_section
+
+/* We use the special COFF backend linker. */
+#define coff_relocate_section sh_relocate_section
+
+/* When relaxing, we need to use special code to get the relocated
+ section contents. */
+#define coff_bfd_get_relocated_section_contents \
+ sh_coff_get_relocated_section_contents
+
+#include "coffcode.h"
+
+/* This function handles relaxing on the SH.
+
+ Function calls on the SH look like this:
+
+ movl L1,r0
+ ...
+ jsr @r0
+ ...
+ L1:
+ .long function
+
+ The compiler and assembler will cooperate to create R_SH_USES
+ relocs on the jsr instructions. The r_offset field of the
+ R_SH_USES reloc is the PC relative offset to the instruction which
+ loads the register (the r_offset field is computed as though it
+ were a jump instruction, so the offset value is actually from four
+ bytes past the instruction). The linker can use this reloc to
+ determine just which function is being called, and thus decide
+ whether it is possible to replace the jsr with a bsr.
+
+ If multiple function calls are all based on a single register load
+ (i.e., the same function is called multiple times), the compiler
+ guarantees that each function call will have an R_SH_USES reloc.
+ Therefore, if the linker is able to convert each R_SH_USES reloc
+ which refers to that address, it can safely eliminate the register
+ load.
+
+ When the assembler creates an R_SH_USES reloc, it examines it to
+ determine which address is being loaded (L1 in the above example).
+ It then counts the number of references to that address, and
+ creates an R_SH_COUNT reloc at that address. The r_offset field of
+ the R_SH_COUNT reloc will be the number of references. If the
+ linker is able to eliminate a register load, it can use the
+ R_SH_COUNT reloc to see whether it can also eliminate the function
+ address.
+
+ SH relaxing also handles another, unrelated, matter. On the SH, if
+ a load or store instruction is not aligned on a four byte boundary,
+ the memory cycle interferes with the 32 bit instruction fetch,
+ causing a one cycle bubble in the pipeline. Therefore, we try to
+ align load and store instructions on four byte boundaries if we
+ can, by swapping them with one of the adjacent instructions. */
+
+static boolean
+sh_relax_section (abfd, sec, link_info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ struct internal_reloc *internal_relocs;
+ struct internal_reloc *free_relocs = NULL;
+ boolean have_code;
+ struct internal_reloc *irel, *irelend;
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+
+ *again = false;
+
+ if (link_info->relocateable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return true;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
+ internal_relocs = (_bfd_coff_read_internal_relocs
+ (abfd, sec, link_info->keep_memory,
+ (bfd_byte *) NULL, false,
+ (struct internal_reloc *) NULL));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ have_code = false;
+
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma laddr, paddr, symval;
+ unsigned short insn;
+ struct internal_reloc *irelfn, *irelscan, *irelcount;
+ struct internal_syment sym;
+ bfd_signed_vma foff;
+
+ if (irel->r_type == R_SH_CODE)
+ have_code = true;
+
+ if (irel->r_type != R_SH_USES)
+ continue;
+
+ /* Get the section contents. */
+ if (contents == NULL)
+ {
+ if (coff_section_data (abfd, sec) != NULL
+ && coff_section_data (abfd, sec)->contents != NULL)
+ contents = coff_section_data (abfd, sec)->contents;
+ else
+ {
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* The r_offset field of the R_SH_USES reloc will point us to
+ the register load. The 4 is because the r_offset field is
+ computed as though it were a jump offset, which are based
+ from 4 bytes after the jump instruction. */
+ laddr = irel->r_vaddr - sec->vma + 4;
+ /* Careful to sign extend the 32-bit offset. */
+ laddr += ((irel->r_offset & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ if (laddr >= sec->_raw_size)
+ {
+ (*_bfd_error_handler) ("%s: 0x%lx: warning: bad R_SH_USES offset",
+ bfd_get_filename (abfd),
+ (unsigned long) irel->r_vaddr);
+ continue;
+ }
+ insn = bfd_get_16 (abfd, contents + laddr);
+
+ /* If the instruction is not mov.l NN,rN, we don't know what to do. */
+ if ((insn & 0xf000) != 0xd000)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x",
+ bfd_get_filename (abfd), (unsigned long) irel->r_vaddr, insn));
+ continue;
+ }
+
+ /* Get the address from which the register is being loaded. The
+ displacement in the mov.l instruction is quadrupled. It is a
+ displacement from four bytes after the movl instruction, but,
+ before adding in the PC address, two least significant bits
+ of the PC are cleared. We assume that the section is aligned
+ on a four byte boundary. */
+ paddr = insn & 0xff;
+ paddr *= 4;
+ paddr += (laddr + 4) &~ 3;
+ if (paddr >= sec->_raw_size)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: bad R_SH_USES load offset",
+ bfd_get_filename (abfd), (unsigned long) irel->r_vaddr));
+ continue;
+ }
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ paddr += sec->vma;
+ for (irelfn = internal_relocs; irelfn < irelend; irelfn++)
+ if (irelfn->r_vaddr == paddr
+ && irelfn->r_type == R_SH_IMM32)
+ break;
+ if (irelfn >= irelend)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: could not find expected reloc",
+ bfd_get_filename (abfd), (unsigned long) paddr));
+ continue;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (! _bfd_coff_get_external_symbols (abfd))
+ goto error_return;
+ bfd_coff_swap_sym_in (abfd,
+ ((bfd_byte *) obj_coff_external_syms (abfd)
+ + (irelfn->r_symndx
+ * bfd_coff_symesz (abfd))),
+ &sym);
+ if (sym.n_scnum != 0 && sym.n_scnum != sec->target_index)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: symbol in unexpected section",
+ bfd_get_filename (abfd), (unsigned long) paddr));
+ continue;
+ }
+
+ if (sym.n_sclass != C_EXT)
+ {
+ symval = (sym.n_value
+ - sec->vma
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ struct coff_link_hash_entry *h;
+
+ h = obj_coff_sym_hashes (abfd)[irelfn->r_symndx];
+ BFD_ASSERT (h != NULL);
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ symval += bfd_get_32 (abfd, contents + paddr - sec->vma);
+
+ /* See if this function call can be shortened. */
+ foff = (symval
+ - (irel->r_vaddr
+ - sec->vma
+ + sec->output_section->vma
+ + sec->output_offset
+ + 4));
+ if (foff < -0x1000 || foff >= 0x1000)
+ {
+ /* After all that work, we can't shorten this function call. */
+ continue;
+ }
+
+ /* Shorten the function call. */
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ sec->used_by_bfd =
+ ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata)));
+ if (sec->used_by_bfd == NULL)
+ goto error_return;
+ }
+
+ coff_section_data (abfd, sec)->relocs = internal_relocs;
+ coff_section_data (abfd, sec)->keep_relocs = true;
+ free_relocs = NULL;
+
+ coff_section_data (abfd, sec)->contents = contents;
+ coff_section_data (abfd, sec)->keep_contents = true;
+ free_contents = NULL;
+
+ obj_coff_keep_syms (abfd) = true;
+
+ /* Replace the jsr with a bsr. */
+
+ /* Change the R_SH_USES reloc into an R_SH_PCDISP reloc, and
+ replace the jsr with a bsr. */
+ irel->r_type = R_SH_PCDISP;
+ irel->r_symndx = irelfn->r_symndx;
+ if (sym.n_sclass != C_EXT)
+ {
+ /* If this needs to be changed because of future relaxing,
+ it will be handled here like other internal PCDISP
+ relocs. */
+ bfd_put_16 (abfd,
+ 0xb000 | ((foff >> 1) & 0xfff),
+ contents + irel->r_vaddr - sec->vma);
+ }
+ else
+ {
+ /* We can't fully resolve this yet, because the external
+ symbol value may be changed by future relaxing. We let
+ the final link phase handle it. */
+ bfd_put_16 (abfd, 0xb000, contents + irel->r_vaddr - sec->vma);
+ }
+
+ /* See if there is another R_SH_USES reloc referring to the same
+ register load. */
+ for (irelscan = internal_relocs; irelscan < irelend; irelscan++)
+ if (irelscan->r_type == R_SH_USES
+ && laddr == irelscan->r_vaddr - sec->vma + 4 + irelscan->r_offset)
+ break;
+ if (irelscan < irelend)
+ {
+ /* Some other function call depends upon this register load,
+ and we have not yet converted that function call.
+ Indeed, we may never be able to convert it. There is
+ nothing else we can do at this point. */
+ continue;
+ }
+
+ /* Look for a R_SH_COUNT reloc on the location where the
+ function address is stored. Do this before deleting any
+ bytes, to avoid confusion about the address. */
+ for (irelcount = internal_relocs; irelcount < irelend; irelcount++)
+ if (irelcount->r_vaddr == paddr
+ && irelcount->r_type == R_SH_COUNT)
+ break;
+
+ /* Delete the register load. */
+ if (! sh_relax_delete_bytes (abfd, sec, laddr, 2))
+ goto error_return;
+
+ /* That will change things, so, just in case it permits some
+ other function call to come within range, we should relax
+ again. Note that this is not required, and it may be slow. */
+ *again = true;
+
+ /* Now check whether we got a COUNT reloc. */
+ if (irelcount >= irelend)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: could not find expected COUNT reloc",
+ bfd_get_filename (abfd), (unsigned long) paddr));
+ continue;
+ }
+
+ /* The number of uses is stored in the r_offset field. We've
+ just deleted one. */
+ if (irelcount->r_offset == 0)
+ {
+ ((*_bfd_error_handler) ("%s: 0x%lx: warning: bad count",
+ bfd_get_filename (abfd),
+ (unsigned long) paddr));
+ continue;
+ }
+
+ --irelcount->r_offset;
+
+ /* If there are no more uses, we can delete the address. Reload
+ the address from irelfn, in case it was changed by the
+ previous call to sh_relax_delete_bytes. */
+ if (irelcount->r_offset == 0)
+ {
+ if (! sh_relax_delete_bytes (abfd, sec,
+ irelfn->r_vaddr - sec->vma, 4))
+ goto error_return;
+ }
+
+ /* We've done all we can with that function call. */
+ }
+
+ /* Look for load and store instructions that we can align on four
+ byte boundaries. */
+ if (have_code)
+ {
+ boolean swapped;
+
+ /* Get the section contents. */
+ if (contents == NULL)
+ {
+ if (coff_section_data (abfd, sec) != NULL
+ && coff_section_data (abfd, sec)->contents != NULL)
+ contents = coff_section_data (abfd, sec)->contents;
+ else
+ {
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ if (! sh_align_loads (abfd, sec, internal_relocs, contents, &swapped))
+ goto error_return;
+
+ if (swapped)
+ {
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ sec->used_by_bfd =
+ ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata)));
+ if (sec->used_by_bfd == NULL)
+ goto error_return;
+ }
+
+ coff_section_data (abfd, sec)->relocs = internal_relocs;
+ coff_section_data (abfd, sec)->keep_relocs = true;
+ free_relocs = NULL;
+
+ coff_section_data (abfd, sec)->contents = contents;
+ coff_section_data (abfd, sec)->keep_contents = true;
+ free_contents = NULL;
+
+ obj_coff_keep_syms (abfd) = true;
+ }
+ }
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for coff_link_input_bfd. */
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ sec->used_by_bfd =
+ ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata)));
+ if (sec->used_by_bfd == NULL)
+ goto error_return;
+ coff_section_data (abfd, sec)->relocs = NULL;
+ }
+ coff_section_data (abfd, sec)->contents = contents;
+ }
+ }
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ return false;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static boolean
+sh_relax_delete_bytes (abfd, sec, addr, count)
+ bfd *abfd;
+ asection *sec;
+ bfd_vma addr;
+ int count;
+{
+ bfd_byte *contents;
+ struct internal_reloc *irel, *irelend;
+ struct internal_reloc *irelalign;
+ bfd_vma toaddr;
+ bfd_byte *esym, *esymend;
+ bfd_size_type symesz;
+ struct coff_link_hash_entry **sym_hash;
+ asection *o;
+
+ contents = coff_section_data (abfd, sec)->contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ toaddr = sec->_cooked_size;
+
+ irel = coff_section_data (abfd, sec)->relocs;
+ irelend = irel + sec->reloc_count;
+ for (; irel < irelend; irel++)
+ {
+ if (irel->r_type == R_SH_ALIGN
+ && irel->r_vaddr - sec->vma > addr
+ && count < (1 << irel->r_offset))
+ {
+ irelalign = irel;
+ toaddr = irel->r_vaddr - sec->vma;
+ break;
+ }
+ }
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+ if (irelalign == NULL)
+ sec->_cooked_size -= count;
+ else
+ {
+ int i;
+
+#define NOP_OPCODE (0x0009)
+
+ BFD_ASSERT ((count & 1) == 0);
+ for (i = 0; i < count; i += 2)
+ bfd_put_16 (abfd, NOP_OPCODE, contents + toaddr - count + i);
+ }
+
+ /* Adjust all the relocs. */
+ for (irel = coff_section_data (abfd, sec)->relocs; irel < irelend; irel++)
+ {
+ bfd_vma nraddr, stop;
+ bfd_vma start = 0;
+ int insn = 0;
+ struct internal_syment sym;
+ int off, adjust, oinsn;
+ bfd_signed_vma voff = 0;
+ boolean overflow;
+
+ /* Get the new reloc address. */
+ nraddr = irel->r_vaddr - sec->vma;
+ if ((irel->r_vaddr - sec->vma > addr
+ && irel->r_vaddr - sec->vma < toaddr)
+ || (irel->r_type == R_SH_ALIGN
+ && irel->r_vaddr - sec->vma == toaddr))
+ nraddr -= count;
+
+ /* See if this reloc was for the bytes we have deleted, in which
+ case we no longer care about it. Don't delete relocs which
+ represent addresses, though. */
+ if (irel->r_vaddr - sec->vma >= addr
+ && irel->r_vaddr - sec->vma < addr + count
+ && irel->r_type != R_SH_ALIGN
+ && irel->r_type != R_SH_CODE
+ && irel->r_type != R_SH_DATA
+ && irel->r_type != R_SH_LABEL)
+ irel->r_type = R_SH_UNUSED;
+
+ /* If this is a PC relative reloc, see if the range it covers
+ includes the bytes we have deleted. */
+ switch (irel->r_type)
+ {
+ default:
+ break;
+
+ case R_SH_PCDISP8BY2:
+ case R_SH_PCDISP:
+ case R_SH_PCRELIMM8BY2:
+ case R_SH_PCRELIMM8BY4:
+ start = irel->r_vaddr - sec->vma;
+ insn = bfd_get_16 (abfd, contents + nraddr);
+ break;
+ }
+
+ switch (irel->r_type)
+ {
+ default:
+ start = stop = addr;
+ break;
+
+ case R_SH_IMM32:
+ /* If this reloc is against a symbol defined in this
+ section, and the symbol will not be adjusted below, we
+ must check the addend to see it will put the value in
+ range to be adjusted, and hence must be changed. */
+ bfd_coff_swap_sym_in (abfd,
+ ((bfd_byte *) obj_coff_external_syms (abfd)
+ + (irel->r_symndx
+ * bfd_coff_symesz (abfd))),
+ &sym);
+ if (sym.n_sclass != C_EXT
+ && sym.n_scnum == sec->target_index
+ && ((bfd_vma) sym.n_value <= addr
+ || (bfd_vma) sym.n_value >= toaddr))
+ {
+ bfd_vma val;
+
+ val = bfd_get_32 (abfd, contents + nraddr);
+ val += sym.n_value;
+ if (val > addr && val < toaddr)
+ bfd_put_32 (abfd, val - count, contents + nraddr);
+ }
+ start = stop = addr;
+ break;
+
+ case R_SH_PCDISP8BY2:
+ off = insn & 0xff;
+ if (off & 0x80)
+ off -= 0x100;
+ stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
+ break;
+
+ case R_SH_PCDISP:
+ bfd_coff_swap_sym_in (abfd,
+ ((bfd_byte *) obj_coff_external_syms (abfd)
+ + (irel->r_symndx
+ * bfd_coff_symesz (abfd))),
+ &sym);
+ if (sym.n_sclass == C_EXT)
+ start = stop = addr;
+ else
+ {
+ off = insn & 0xfff;
+ if (off & 0x800)
+ off -= 0x1000;
+ stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
+ }
+ break;
+
+ case R_SH_PCRELIMM8BY2:
+ off = insn & 0xff;
+ stop = start + 4 + off * 2;
+ break;
+
+ case R_SH_PCRELIMM8BY4:
+ off = insn & 0xff;
+ stop = (start &~ (bfd_vma) 3) + 4 + off * 4;
+ break;
+
+ case R_SH_SWITCH8:
+ case R_SH_SWITCH16:
+ case R_SH_SWITCH32:
+ /* These relocs types represent
+ .word L2-L1
+ The r_offset field holds the difference between the reloc
+ address and L1. That is the start of the reloc, and
+ adding in the contents gives us the top. We must adjust
+ both the r_offset field and the section contents. */
+
+ start = irel->r_vaddr - sec->vma;
+ stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_offset);
+
+ if (start > addr
+ && start < toaddr
+ && (stop <= addr || stop >= toaddr))
+ irel->r_offset += count;
+ else if (stop > addr
+ && stop < toaddr
+ && (start <= addr || start >= toaddr))
+ irel->r_offset -= count;
+
+ start = stop;
+
+ if (irel->r_type == R_SH_SWITCH16)
+ voff = bfd_get_signed_16 (abfd, contents + nraddr);
+ else if (irel->r_type == R_SH_SWITCH8)
+ voff = bfd_get_8 (abfd, contents + nraddr);
+ else
+ voff = bfd_get_signed_32 (abfd, contents + nraddr);
+ stop = (bfd_vma) ((bfd_signed_vma) start + voff);
+
+ break;
+
+ case R_SH_USES:
+ start = irel->r_vaddr - sec->vma;
+ stop = (bfd_vma) ((bfd_signed_vma) start
+ + (long) irel->r_offset
+ + 4);
+ break;
+ }
+
+ if (start > addr
+ && start < toaddr
+ && (stop <= addr || stop >= toaddr))
+ adjust = count;
+ else if (stop > addr
+ && stop < toaddr
+ && (start <= addr || start >= toaddr))
+ adjust = - count;
+ else
+ adjust = 0;
+
+ if (adjust != 0)
+ {
+ oinsn = insn;
+ overflow = false;
+ switch (irel->r_type)
+ {
+ default:
+ abort ();
+ break;
+
+ case R_SH_PCDISP8BY2:
+ case R_SH_PCRELIMM8BY2:
+ insn += adjust / 2;
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, contents + nraddr);
+ break;
+
+ case R_SH_PCDISP:
+ insn += adjust / 2;
+ if ((oinsn & 0xf000) != (insn & 0xf000))
+ overflow = true;
+ bfd_put_16 (abfd, insn, contents + nraddr);
+ break;
+
+ case R_SH_PCRELIMM8BY4:
+ BFD_ASSERT (adjust == count || count >= 4);
+ if (count >= 4)
+ insn += adjust / 4;
+ else
+ {
+ if ((irel->r_vaddr & 3) == 0)
+ ++insn;
+ }
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH8:
+ voff += adjust;
+ if (voff < 0 || voff >= 0xff)
+ overflow = true;
+ bfd_put_8 (abfd, voff, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH16:
+ voff += adjust;
+ if (voff < - 0x8000 || voff >= 0x8000)
+ overflow = true;
+ bfd_put_signed_16 (abfd, voff, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH32:
+ voff += adjust;
+ bfd_put_signed_32 (abfd, voff, contents + nraddr);
+ break;
+
+ case R_SH_USES:
+ irel->r_offset += adjust;
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: fatal: reloc overflow while relaxing",
+ bfd_get_filename (abfd), (unsigned long) irel->r_vaddr));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ irel->r_vaddr = nraddr + sec->vma;
+ }
+
+ /* Look through all the other sections. If there contain any IMM32
+ relocs against internal symbols which we are not going to adjust
+ below, we may need to adjust the addends. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct internal_reloc *internal_relocs;
+ struct internal_reloc *irelscan, *irelscanend;
+ bfd_byte *ocontents;
+
+ if (o == sec
+ || (o->flags & SEC_RELOC) == 0
+ || o->reloc_count == 0)
+ continue;
+
+ /* We always cache the relocs. Perhaps, if info->keep_memory is
+ false, we should free them, if we are permitted to, when we
+ leave sh_coff_relax_section. */
+ internal_relocs = (_bfd_coff_read_internal_relocs
+ (abfd, o, true, (bfd_byte *) NULL, false,
+ (struct internal_reloc *) NULL));
+ if (internal_relocs == NULL)
+ return false;
+
+ ocontents = NULL;
+ irelscanend = internal_relocs + o->reloc_count;
+ for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++)
+ {
+ struct internal_syment sym;
+
+ if (irelscan->r_type != R_SH_IMM32)
+ continue;
+
+ bfd_coff_swap_sym_in (abfd,
+ ((bfd_byte *) obj_coff_external_syms (abfd)
+ + (irelscan->r_symndx
+ * bfd_coff_symesz (abfd))),
+ &sym);
+ if (sym.n_sclass != C_EXT
+ && sym.n_scnum == sec->target_index
+ && ((bfd_vma) sym.n_value <= addr
+ || (bfd_vma) sym.n_value >= toaddr))
+ {
+ bfd_vma val;
+
+ if (ocontents == NULL)
+ {
+ if (coff_section_data (abfd, o)->contents != NULL)
+ ocontents = coff_section_data (abfd, o)->contents;
+ else
+ {
+ /* We always cache the section contents.
+ Perhaps, if info->keep_memory is false, we
+ should free them, if we are permitted to,
+ when we leave sh_coff_relax_section. */
+ ocontents = (bfd_byte *) bfd_malloc (o->_raw_size);
+ if (ocontents == NULL)
+ return false;
+ if (! bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->_raw_size))
+ return false;
+ coff_section_data (abfd, o)->contents = ocontents;
+ }
+ }
+
+ val = bfd_get_32 (abfd, ocontents + irelscan->r_vaddr - o->vma);
+ val += sym.n_value;
+ if (val > addr && val < toaddr)
+ bfd_put_32 (abfd, val - count,
+ ocontents + irelscan->r_vaddr - o->vma);
+
+ coff_section_data (abfd, o)->keep_contents = true;
+ }
+ }
+ }
+
+ /* Adjusting the internal symbols will not work if something has
+ already retrieved the generic symbols. It would be possible to
+ make this work by adjusting the generic symbols at the same time.
+ However, this case should not arise in normal usage. */
+ if (obj_symbols (abfd) != NULL
+ || obj_raw_syments (abfd) != NULL)
+ {
+ ((*_bfd_error_handler)
+ ("%s: fatal: generic symbols retrieved before relaxing",
+ bfd_get_filename (abfd)));
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ /* Adjust all the symbols. */
+ sym_hash = obj_coff_sym_hashes (abfd);
+ symesz = bfd_coff_symesz (abfd);
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esymend = esym + obj_raw_syment_count (abfd) * symesz;
+ while (esym < esymend)
+ {
+ struct internal_syment isym;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
+
+ if (isym.n_scnum == sec->target_index
+ && (bfd_vma) isym.n_value > addr
+ && (bfd_vma) isym.n_value < toaddr)
+ {
+ isym.n_value -= count;
+
+ bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym);
+
+ if (*sym_hash != NULL)
+ {
+ BFD_ASSERT ((*sym_hash)->root.type == bfd_link_hash_defined
+ || (*sym_hash)->root.type == bfd_link_hash_defweak);
+ BFD_ASSERT ((*sym_hash)->root.u.def.value >= addr
+ && (*sym_hash)->root.u.def.value < toaddr);
+ (*sym_hash)->root.u.def.value -= count;
+ }
+ }
+
+ esym += (isym.n_numaux + 1) * symesz;
+ sym_hash += isym.n_numaux + 1;
+ }
+
+ /* See if we can move the ALIGN reloc forward. We have adjusted
+ r_vaddr for it already. */
+ if (irelalign != NULL)
+ {
+ bfd_vma alignto, alignaddr;
+
+ alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_offset);
+ alignaddr = BFD_ALIGN (irelalign->r_vaddr - sec->vma,
+ 1 << irelalign->r_offset);
+ if (alignto != alignaddr)
+ {
+ /* Tail recursion. */
+ return sh_relax_delete_bytes (abfd, sec, alignaddr,
+ alignto - alignaddr);
+ }
+ }
+
+ return true;
+}
+
+/* This is yet another version of the SH opcode table, used to rapidly
+ get information about a particular instruction. */
+
+/* The opcode map is represented by an array of these structures. The
+ array is indexed by the high order four bits in the instruction. */
+
+struct sh_major_opcode
+{
+ /* A pointer to the instruction list. This is an array which
+ contains all the instructions with this major opcode. */
+ const struct sh_minor_opcode *minor_opcodes;
+ /* The number of elements in minor_opcodes. */
+ unsigned short count;
+};
+
+/* This structure holds information for a set of SH opcodes. The
+ instruction code is anded with the mask value, and the resulting
+ value is used to search the order opcode list. */
+
+struct sh_minor_opcode
+{
+ /* The sorted opcode list. */
+ const struct sh_opcode *opcodes;
+ /* The number of elements in opcodes. */
+ unsigned short count;
+ /* The mask value to use when searching the opcode list. */
+ unsigned short mask;
+};
+
+/* This structure holds information for an SH instruction. An array
+ of these structures is sorted in order by opcode. */
+
+struct sh_opcode
+{
+ /* The code for this instruction, after it has been anded with the
+ mask value in the sh_major_opcode structure. */
+ unsigned short opcode;
+ /* Flags for this instruction. */
+ unsigned short flags;
+};
+
+/* Flag which appear in the sh_opcode structure. */
+
+/* This instruction loads a value from memory. */
+#define LOAD (0x1)
+
+/* This instruction stores a value to memory. */
+#define STORE (0x2)
+
+/* This instruction is a branch. */
+#define BRANCH (0x4)
+
+/* This instruction has a delay slot. */
+#define DELAY (0x8)
+
+/* This instruction uses the value in the register in the field at
+ mask 0x0f00 of the instruction. */
+#define USES1 (0x10)
+
+/* This instruction uses the value in the register in the field at
+ mask 0x00f0 of the instruction. */
+#define USES2 (0x20)
+
+/* This instruction uses the value in register 0. */
+#define USESR0 (0x40)
+
+/* This instruction sets the value in the register in the field at
+ mask 0x0f00 of the instruction. */
+#define SETS1 (0x80)
+
+/* This instruction sets the value in the register in the field at
+ mask 0x00f0 of the instruction. */
+#define SETS2 (0x100)
+
+/* This instruction sets register 0. */
+#define SETSR0 (0x200)
+
+/* This instruction sets a special register. */
+#define SETSSP (0x400)
+
+/* This instruction uses a special register. */
+#define USESSP (0x800)
+
+/* This instruction uses the floating point register in the field at
+ mask 0x0f00 of the instruction. */
+#define USESF1 (0x1000)
+
+/* This instruction uses the floating point register in the field at
+ mask 0x00f0 of the instruction. */
+#define USESF2 (0x2000)
+
+/* This instruction uses floating point register 0. */
+#define USESF0 (0x4000)
+
+/* This instruction sets the floating point register in the field at
+ mask 0x0f00 of the instruction. */
+#define SETSF1 (0x8000)
+
+static boolean sh_insn_uses_reg
+ PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
+static boolean sh_insn_uses_freg
+ PARAMS ((unsigned int, const struct sh_opcode *, unsigned int));
+static boolean sh_insns_conflict
+ PARAMS ((unsigned int, const struct sh_opcode *, unsigned int,
+ const struct sh_opcode *));
+static boolean sh_load_use
+ PARAMS ((unsigned int, const struct sh_opcode *, unsigned int,
+ const struct sh_opcode *));
+
+/* The opcode maps. */
+
+#define MAP(a) a, sizeof a / sizeof a[0]
+
+static const struct sh_opcode sh_opcode00[] =
+{
+ { 0x0008, SETSSP }, /* clrt */
+ { 0x0009, 0 }, /* nop */
+ { 0x000b, BRANCH | DELAY | USESSP }, /* rts */
+ { 0x0018, SETSSP }, /* sett */
+ { 0x0019, SETSSP }, /* div0u */
+ { 0x001b, 0 }, /* sleep */
+ { 0x0028, SETSSP }, /* clrmac */
+ { 0x002b, BRANCH | DELAY | SETSSP }, /* rte */
+ { 0x0038, USESSP | SETSSP }, /* ldtlb */
+ { 0x0048, SETSSP }, /* clrs */
+ { 0x0058, SETSSP } /* sets */
+};
+
+static const struct sh_opcode sh_opcode01[] =
+{
+ { 0x0002, SETS1 | USESSP }, /* stc sr,rn */
+ { 0x0003, BRANCH | DELAY | USES1 | SETSSP }, /* bsrf rn */
+ { 0x000a, SETS1 | USESSP }, /* sts mach,rn */
+ { 0x0012, SETS1 | USESSP }, /* stc gbr,rn */
+ { 0x001a, SETS1 | USESSP }, /* sts macl,rn */
+ { 0x0022, SETS1 | USESSP }, /* stc vbr,rn */
+ { 0x0023, BRANCH | DELAY | USES1 }, /* braf rn */
+ { 0x0029, SETS1 | USESSP }, /* movt rn */
+ { 0x002a, SETS1 | USESSP }, /* sts pr,rn */
+ { 0x0032, SETS1 | USESSP }, /* stc ssr,rn */
+ { 0x0042, SETS1 | USESSP }, /* stc spc,rn */
+ { 0x005a, SETS1 | USESSP }, /* sts fpul,rn */
+ { 0x006a, SETS1 | USESSP }, /* sts fpscr,rn */
+ { 0x0082, SETS1 | USESSP }, /* stc r0_bank,rn */
+ { 0x0083, LOAD | USES1 }, /* pref @rn */
+ { 0x0092, SETS1 | USESSP }, /* stc r1_bank,rn */
+ { 0x00a2, SETS1 | USESSP }, /* stc r2_bank,rn */
+ { 0x00b2, SETS1 | USESSP }, /* stc r3_bank,rn */
+ { 0x00c2, SETS1 | USESSP }, /* stc r4_bank,rn */
+ { 0x00d2, SETS1 | USESSP }, /* stc r5_bank,rn */
+ { 0x00e2, SETS1 | USESSP }, /* stc r6_bank,rn */
+ { 0x00f2, SETS1 | USESSP } /* stc r7_bank,rn */
+};
+
+static const struct sh_opcode sh_opcode02[] =
+{
+ { 0x0004, STORE | USES1 | USES2 | USESR0 }, /* mov.b rm,@(r0,rn) */
+ { 0x0005, STORE | USES1 | USES2 | USESR0 }, /* mov.w rm,@(r0,rn) */
+ { 0x0006, STORE | USES1 | USES2 | USESR0 }, /* mov.l rm,@(r0,rn) */
+ { 0x0007, SETSSP | USES1 | USES2 }, /* mul.l rm,rn */
+ { 0x000c, LOAD | SETS1 | USES2 | USESR0 }, /* mov.b @(r0,rm),rn */
+ { 0x000d, LOAD | SETS1 | USES2 | USESR0 }, /* mov.w @(r0,rm),rn */
+ { 0x000e, LOAD | SETS1 | USES2 | USESR0 }, /* mov.l @(r0,rm),rn */
+ { 0x000f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.l @rm+,@rn+ */
+};
+
+static const struct sh_minor_opcode sh_opcode0[] =
+{
+ { MAP (sh_opcode00), 0xffff },
+ { MAP (sh_opcode01), 0xf0ff },
+ { MAP (sh_opcode02), 0xf00f }
+};
+
+static const struct sh_opcode sh_opcode10[] =
+{
+ { 0x1000, STORE | USES1 | USES2 } /* mov.l rm,@(disp,rn) */
+};
+
+static const struct sh_minor_opcode sh_opcode1[] =
+{
+ { MAP (sh_opcode10), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcode20[] =
+{
+ { 0x2000, STORE | USES1 | USES2 }, /* mov.b rm,@rn */
+ { 0x2001, STORE | USES1 | USES2 }, /* mov.w rm,@rn */
+ { 0x2002, STORE | USES1 | USES2 }, /* mov.l rm,@rn */
+ { 0x2004, STORE | SETS1 | USES1 | USES2 }, /* mov.b rm,@-rn */
+ { 0x2005, STORE | SETS1 | USES1 | USES2 }, /* mov.w rm,@-rn */
+ { 0x2006, STORE | SETS1 | USES1 | USES2 }, /* mov.l rm,@-rn */
+ { 0x2007, SETSSP | USES1 | USES2 | USESSP }, /* div0s */
+ { 0x2008, SETSSP | USES1 | USES2 }, /* tst rm,rn */
+ { 0x2009, SETS1 | USES1 | USES2 }, /* and rm,rn */
+ { 0x200a, SETS1 | USES1 | USES2 }, /* xor rm,rn */
+ { 0x200b, SETS1 | USES1 | USES2 }, /* or rm,rn */
+ { 0x200c, SETSSP | USES1 | USES2 }, /* cmp/str rm,rn */
+ { 0x200d, SETS1 | USES1 | USES2 }, /* xtrct rm,rn */
+ { 0x200e, SETSSP | USES1 | USES2 }, /* mulu.w rm,rn */
+ { 0x200f, SETSSP | USES1 | USES2 } /* muls.w rm,rn */
+};
+
+static const struct sh_minor_opcode sh_opcode2[] =
+{
+ { MAP (sh_opcode20), 0xf00f }
+};
+
+static const struct sh_opcode sh_opcode30[] =
+{
+ { 0x3000, SETSSP | USES1 | USES2 }, /* cmp/eq rm,rn */
+ { 0x3002, SETSSP | USES1 | USES2 }, /* cmp/hs rm,rn */
+ { 0x3003, SETSSP | USES1 | USES2 }, /* cmp/ge rm,rn */
+ { 0x3004, SETSSP | USESSP | USES1 | USES2 }, /* div1 rm,rn */
+ { 0x3005, SETSSP | USES1 | USES2 }, /* dmulu.l rm,rn */
+ { 0x3006, SETSSP | USES1 | USES2 }, /* cmp/hi rm,rn */
+ { 0x3007, SETSSP | USES1 | USES2 }, /* cmp/gt rm,rn */
+ { 0x3008, SETS1 | USES1 | USES2 }, /* sub rm,rn */
+ { 0x300a, SETS1 | SETSSP | USES1 | USES2 | USESSP }, /* subc rm,rn */
+ { 0x300b, SETS1 | SETSSP | USES1 | USES2 }, /* subv rm,rn */
+ { 0x300c, SETS1 | USES1 | USES2 }, /* add rm,rn */
+ { 0x300d, SETSSP | USES1 | USES2 }, /* dmuls.l rm,rn */
+ { 0x300e, SETS1 | SETSSP | USES1 | USES2 | USESSP }, /* addc rm,rn */
+ { 0x300f, SETS1 | SETSSP | USES1 | USES2 } /* addv rm,rn */
+};
+
+static const struct sh_minor_opcode sh_opcode3[] =
+{
+ { MAP (sh_opcode30), 0xf00f }
+};
+
+static const struct sh_opcode sh_opcode40[] =
+{
+ { 0x4000, SETS1 | SETSSP | USES1 }, /* shll rn */
+ { 0x4001, SETS1 | SETSSP | USES1 }, /* shlr rn */
+ { 0x4002, STORE | SETS1 | USES1 | USESSP }, /* sts.l mach,@-rn */
+ { 0x4003, STORE | SETS1 | USES1 | USESSP }, /* stc.l sr,@-rn */
+ { 0x4004, SETS1 | SETSSP | USES1 }, /* rotl rn */
+ { 0x4005, SETS1 | SETSSP | USES1 }, /* rotr rn */
+ { 0x4006, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,mach */
+ { 0x4007, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,sr */
+ { 0x4008, SETS1 | USES1 }, /* shll2 rn */
+ { 0x4009, SETS1 | USES1 }, /* shlr2 rn */
+ { 0x400a, SETSSP | USES1 }, /* lds rm,mach */
+ { 0x400b, BRANCH | DELAY | USES1 }, /* jsr @rn */
+ { 0x400e, SETSSP | USES1 }, /* ldc rm,sr */
+ { 0x4010, SETS1 | SETSSP | USES1 }, /* dt rn */
+ { 0x4011, SETSSP | USES1 }, /* cmp/pz rn */
+ { 0x4012, STORE | SETS1 | USES1 | USESSP }, /* sts.l macl,@-rn */
+ { 0x4013, STORE | SETS1 | USES1 | USESSP }, /* stc.l gbr,@-rn */
+ { 0x4015, SETSSP | USES1 }, /* cmp/pl rn */
+ { 0x4016, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,macl */
+ { 0x4017, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,gbr */
+ { 0x4018, SETS1 | USES1 }, /* shll8 rn */
+ { 0x4019, SETS1 | USES1 }, /* shlr8 rn */
+ { 0x401a, SETSSP | USES1 }, /* lds rm,macl */
+ { 0x401b, LOAD | SETSSP | USES1 }, /* tas.b @rn */
+ { 0x401e, SETSSP | USES1 }, /* ldc rm,gbr */
+ { 0x4020, SETS1 | SETSSP | USES1 }, /* shal rn */
+ { 0x4021, SETS1 | SETSSP | USES1 }, /* shar rn */
+ { 0x4022, STORE | SETS1 | USES1 | USESSP }, /* sts.l pr,@-rn */
+ { 0x4023, STORE | SETS1 | USES1 | USESSP }, /* stc.l vbr,@-rn */
+ { 0x4024, SETS1 | SETSSP | USES1 | USESSP }, /* rotcl rn */
+ { 0x4025, SETS1 | SETSSP | USES1 | USESSP }, /* rotcr rn */
+ { 0x4026, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,pr */
+ { 0x4027, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,vbr */
+ { 0x4028, SETS1 | USES1 }, /* shll16 rn */
+ { 0x4029, SETS1 | USES1 }, /* shlr16 rn */
+ { 0x402a, SETSSP | USES1 }, /* lds rm,pr */
+ { 0x402b, BRANCH | DELAY | USES1 }, /* jmp @rn */
+ { 0x402e, SETSSP | USES1 }, /* ldc rm,vbr */
+ { 0x4033, STORE | SETS1 | USES1 | USESSP }, /* stc.l ssr,@-rn */
+ { 0x4037, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,ssr */
+ { 0x403e, SETSSP | USES1 }, /* ldc rm,ssr */
+ { 0x4043, STORE | SETS1 | USES1 | USESSP }, /* stc.l spc,@-rn */
+ { 0x4047, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,spc */
+ { 0x404e, SETSSP | USES1 }, /* ldc rm,spc */
+ { 0x4052, STORE | SETS1 | USES1 | USESSP }, /* sts.l fpul,@-rn */
+ { 0x4056, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,fpul */
+ { 0x405a, SETSSP | USES1 }, /* lds.l rm,fpul */
+ { 0x4062, STORE | SETS1 | USES1 | USESSP }, /* sts.l fpscr,@-rn */
+ { 0x4066, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,fpscr */
+ { 0x406a, SETSSP | USES1 } /* lds rm,fpscr */
+};
+
+static const struct sh_opcode sh_opcode41[] =
+{
+ { 0x4083, STORE | SETS1 | USES1 | USESSP }, /* stc.l rx_bank,@-rn */
+ { 0x4087, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,rx_bank */
+ { 0x408e, SETSSP | USES1 } /* ldc rm,rx_bank */
+};
+
+static const struct sh_opcode sh_opcode42[] =
+{
+ { 0x400c, SETS1 | USES1 | USES2 }, /* shad rm,rn */
+ { 0x400d, SETS1 | USES1 | USES2 }, /* shld rm,rn */
+ { 0x400f, LOAD|SETS1|SETS2|SETSSP|USES1|USES2|USESSP }, /* mac.w @rm+,@rn+ */
+};
+
+static const struct sh_minor_opcode sh_opcode4[] =
+{
+ { MAP (sh_opcode40), 0xf0ff },
+ { MAP (sh_opcode41), 0xf08f },
+ { MAP (sh_opcode42), 0xf00f }
+};
+
+static const struct sh_opcode sh_opcode50[] =
+{
+ { 0x5000, LOAD | SETS1 | USES2 } /* mov.l @(disp,rm),rn */
+};
+
+static const struct sh_minor_opcode sh_opcode5[] =
+{
+ { MAP (sh_opcode50), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcode60[] =
+{
+ { 0x6000, LOAD | SETS1 | USES2 }, /* mov.b @rm,rn */
+ { 0x6001, LOAD | SETS1 | USES2 }, /* mov.w @rm,rn */
+ { 0x6002, LOAD | SETS1 | USES2 }, /* mov.l @rm,rn */
+ { 0x6003, SETS1 | USES2 }, /* mov rm,rn */
+ { 0x6004, LOAD | SETS1 | SETS2 | USES2 }, /* mov.b @rm+,rn */
+ { 0x6005, LOAD | SETS1 | SETS2 | USES2 }, /* mov.w @rm+,rn */
+ { 0x6006, LOAD | SETS1 | SETS2 | USES2 }, /* mov.l @rm+,rn */
+ { 0x6007, SETS1 | USES2 }, /* not rm,rn */
+ { 0x6008, SETS1 | USES2 }, /* swap.b rm,rn */
+ { 0x6009, SETS1 | USES2 }, /* swap.w rm,rn */
+ { 0x600a, SETS1 | SETSSP | USES2 | USESSP }, /* negc rm,rn */
+ { 0x600b, SETS1 | USES2 }, /* neg rm,rn */
+ { 0x600c, SETS1 | USES2 }, /* extu.b rm,rn */
+ { 0x600d, SETS1 | USES2 }, /* extu.w rm,rn */
+ { 0x600e, SETS1 | USES2 }, /* exts.b rm,rn */
+ { 0x600f, SETS1 | USES2 } /* exts.w rm,rn */
+};
+
+static const struct sh_minor_opcode sh_opcode6[] =
+{
+ { MAP (sh_opcode60), 0xf00f }
+};
+
+static const struct sh_opcode sh_opcode70[] =
+{
+ { 0x7000, SETS1 | USES1 } /* add #imm,rn */
+};
+
+static const struct sh_minor_opcode sh_opcode7[] =
+{
+ { MAP (sh_opcode70), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcode80[] =
+{
+ { 0x8000, STORE | USES2 | USESR0 }, /* mov.b r0,@(disp,rn) */
+ { 0x8100, STORE | USES2 | USESR0 }, /* mov.w r0,@(disp,rn) */
+ { 0x8400, LOAD | SETSR0 | USES2 }, /* mov.b @(disp,rm),r0 */
+ { 0x8500, LOAD | SETSR0 | USES2 }, /* mov.w @(disp,rn),r0 */
+ { 0x8800, SETSSP | USESR0 }, /* cmp/eq #imm,r0 */
+ { 0x8900, BRANCH | USESSP }, /* bt label */
+ { 0x8b00, BRANCH | USESSP }, /* bf label */
+ { 0x8d00, BRANCH | DELAY | USESSP }, /* bt/s label */
+ { 0x8f00, BRANCH | DELAY | USESSP } /* bf/s label */
+};
+
+static const struct sh_minor_opcode sh_opcode8[] =
+{
+ { MAP (sh_opcode80), 0xff00 }
+};
+
+static const struct sh_opcode sh_opcode90[] =
+{
+ { 0x9000, LOAD | SETS1 } /* mov.w @(disp,pc),rn */
+};
+
+static const struct sh_minor_opcode sh_opcode9[] =
+{
+ { MAP (sh_opcode90), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcodea0[] =
+{
+ { 0xa000, BRANCH | DELAY } /* bra label */
+};
+
+static const struct sh_minor_opcode sh_opcodea[] =
+{
+ { MAP (sh_opcodea0), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcodeb0[] =
+{
+ { 0xb000, BRANCH | DELAY } /* bsr label */
+};
+
+static const struct sh_minor_opcode sh_opcodeb[] =
+{
+ { MAP (sh_opcodeb0), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcodec0[] =
+{
+ { 0xc000, STORE | USESR0 | USESSP }, /* mov.b r0,@(disp,gbr) */
+ { 0xc100, STORE | USESR0 | USESSP }, /* mov.w r0,@(disp,gbr) */
+ { 0xc200, STORE | USESR0 | USESSP }, /* mov.l r0,@(disp,gbr) */
+ { 0xc300, BRANCH | USESSP }, /* trapa #imm */
+ { 0xc400, LOAD | SETSR0 | USESSP }, /* mov.b @(disp,gbr),r0 */
+ { 0xc500, LOAD | SETSR0 | USESSP }, /* mov.w @(disp,gbr),r0 */
+ { 0xc600, LOAD | SETSR0 | USESSP }, /* mov.l @(disp,gbr),r0 */
+ { 0xc700, SETSR0 }, /* mova @(disp,pc),r0 */
+ { 0xc800, SETSSP | USESR0 }, /* tst #imm,r0 */
+ { 0xc900, SETSR0 | USESR0 }, /* and #imm,r0 */
+ { 0xca00, SETSR0 | USESR0 }, /* xor #imm,r0 */
+ { 0xcb00, SETSR0 | USESR0 }, /* or #imm,r0 */
+ { 0xcc00, LOAD | SETSSP | USESR0 | USESSP }, /* tst.b #imm,@(r0,gbr) */
+ { 0xcd00, LOAD | STORE | USESR0 | USESSP }, /* and.b #imm,@(r0,gbr) */
+ { 0xce00, LOAD | STORE | USESR0 | USESSP }, /* xor.b #imm,@(r0,gbr) */
+ { 0xcf00, LOAD | STORE | USESR0 | USESSP } /* or.b #imm,@(r0,gbr) */
+};
+
+static const struct sh_minor_opcode sh_opcodec[] =
+{
+ { MAP (sh_opcodec0), 0xff00 }
+};
+
+static const struct sh_opcode sh_opcoded0[] =
+{
+ { 0xd000, LOAD | SETS1 } /* mov.l @(disp,pc),rn */
+};
+
+static const struct sh_minor_opcode sh_opcoded[] =
+{
+ { MAP (sh_opcoded0), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcodee0[] =
+{
+ { 0xe000, SETS1 } /* mov #imm,rn */
+};
+
+static const struct sh_minor_opcode sh_opcodee[] =
+{
+ { MAP (sh_opcodee0), 0xf000 }
+};
+
+static const struct sh_opcode sh_opcodef0[] =
+{
+ { 0xf000, SETSF1 | USESF1 | USESF2 }, /* fadd fm,fn */
+ { 0xf001, SETSF1 | USESF1 | USESF2 }, /* fsub fm,fn */
+ { 0xf002, SETSF1 | USESF1 | USESF2 }, /* fmul fm,fn */
+ { 0xf003, SETSF1 | USESF1 | USESF2 }, /* fdiv fm,fn */
+ { 0xf004, SETSSP | USESF1 | USESF2 }, /* fcmp/eq fm,fn */
+ { 0xf005, SETSSP | USESF1 | USESF2 }, /* fcmp/gt fm,fn */
+ { 0xf006, LOAD | SETSF1 | USES2 | USESR0 }, /* fmov.s @(r0,rm),fn */
+ { 0xf007, STORE | USES1 | USESF2 | USESR0 }, /* fmov.s fm,@(r0,rn) */
+ { 0xf008, LOAD | SETSF1 | USES2 }, /* fmov.s @rm,fn */
+ { 0xf009, LOAD | SETS2 | SETSF1 | USES2 }, /* fmov.s @rm+,fn */
+ { 0xf00a, STORE | USES1 | USESF2 }, /* fmov.s fm,@rn */
+ { 0xf00b, STORE | SETS1 | USES1 | USESF2 }, /* fmov.s fm,@-rn */
+ { 0xf00c, SETSF1 | USESF2 }, /* fmov fm,fn */
+ { 0xf00e, SETSF1 | USESF1 | USESF2 | USESF0 } /* fmac f0,fm,fn */
+};
+
+static const struct sh_opcode sh_opcodef1[] =
+{
+ { 0xf00d, SETSF1 | USESSP }, /* fsts fpul,fn */
+ { 0xf01d, SETSSP | USESF1 }, /* flds fn,fpul */
+ { 0xf02d, SETSF1 | USESSP }, /* float fpul,fn */
+ { 0xf03d, SETSSP | USESF1 }, /* ftrc fn,fpul */
+ { 0xf04d, SETSF1 | USESF1 }, /* fneg fn */
+ { 0xf05d, SETSF1 | USESF1 }, /* fabs fn */
+ { 0xf06d, SETSF1 | USESF1 }, /* fsqrt fn */
+ { 0xf07d, SETSSP | USESF1 }, /* ftst/nan fn */
+ { 0xf08d, SETSF1 }, /* fldi0 fn */
+ { 0xf09d, SETSF1 } /* fldi1 fn */
+};
+
+static const struct sh_minor_opcode sh_opcodef[] =
+{
+ { MAP (sh_opcodef0), 0xf00f },
+ { MAP (sh_opcodef1), 0xf0ff }
+};
+
+static const struct sh_major_opcode sh_opcodes[] =
+{
+ { MAP (sh_opcode0) },
+ { MAP (sh_opcode1) },
+ { MAP (sh_opcode2) },
+ { MAP (sh_opcode3) },
+ { MAP (sh_opcode4) },
+ { MAP (sh_opcode5) },
+ { MAP (sh_opcode6) },
+ { MAP (sh_opcode7) },
+ { MAP (sh_opcode8) },
+ { MAP (sh_opcode9) },
+ { MAP (sh_opcodea) },
+ { MAP (sh_opcodeb) },
+ { MAP (sh_opcodec) },
+ { MAP (sh_opcoded) },
+ { MAP (sh_opcodee) },
+ { MAP (sh_opcodef) }
+};
+
+/* Given an instruction, return a pointer to the corresponding
+ sh_opcode structure. Return NULL if the instruction is not
+ recognized. */
+
+static const struct sh_opcode *
+sh_insn_info (insn)
+ unsigned int insn;
+{
+ const struct sh_major_opcode *maj;
+ const struct sh_minor_opcode *min, *minend;
+
+ maj = &sh_opcodes[(insn & 0xf000) >> 12];
+ min = maj->minor_opcodes;
+ minend = min + maj->count;
+ for (; min < minend; min++)
+ {
+ unsigned int l;
+ const struct sh_opcode *op, *opend;
+
+ l = insn & min->mask;
+ op = min->opcodes;
+ opend = op + min->count;
+
+ /* Since the opcodes tables are sorted, we could use a binary
+ search here if the count were above some cutoff value. */
+ for (; op < opend; op++)
+ if (op->opcode == l)
+ return op;
+ }
+
+ return NULL;
+}
+
+/* See whether an instruction uses a general purpose register. */
+
+static boolean
+sh_insn_uses_reg (insn, op, reg)
+ unsigned int insn;
+ const struct sh_opcode *op;
+ unsigned int reg;
+{
+ unsigned int f;
+
+ f = op->flags;
+
+ if ((f & USES1) != 0
+ && ((insn & 0x0f00) >> 8) == reg)
+ return true;
+ if ((f & USES2) != 0
+ && ((insn & 0x00f0) >> 4) == reg)
+ return true;
+ if ((f & USESR0) != 0
+ && reg == 0)
+ return true;
+
+ return false;
+}
+
+/* See whether an instruction uses a floating point register. */
+
+static boolean
+sh_insn_uses_freg (insn, op, freg)
+ unsigned int insn;
+ const struct sh_opcode *op;
+ unsigned int freg;
+{
+ unsigned int f;
+
+ f = op->flags;
+
+ /* We can't tell if this is a double-precision insn, so just play safe
+ and assume that it might be. So not only have we test FREG against
+ itself, but also even FREG against FREG+1 - if the using insn uses
+ just the low part of a double precision value - but also an odd
+ FREG against FREG-1 - if the setting insn sets just the low part
+ of a double precision value.
+ So what this all boils down to is that we have to ignore the lowest
+ bit of the register number. */
+
+ if ((f & USESF1) != 0
+ && ((insn & 0x0e00) >> 8) == (freg & 0xe))
+ return true;
+ if ((f & USESF2) != 0
+ && ((insn & 0x00e0) >> 4) == (freg & 0xe))
+ return true;
+ if ((f & USESF0) != 0
+ && freg == 0)
+ return true;
+
+ return false;
+}
+
+/* See whether instructions I1 and I2 conflict, assuming I1 comes
+ before I2. OP1 and OP2 are the corresponding sh_opcode structures.
+ This should return true if there is a conflict, or false if the
+ instructions can be swapped safely. */
+
+static boolean
+sh_insns_conflict (i1, op1, i2, op2)
+ unsigned int i1;
+ const struct sh_opcode *op1;
+ unsigned int i2;
+ const struct sh_opcode *op2;
+{
+ unsigned int f1, f2;
+
+ f1 = op1->flags;
+ f2 = op2->flags;
+
+ /* Load of fpscr conflicts with floating point operations.
+ FIXME: shouldn't test raw opcodes here. */
+ if (((i1 & 0xf0ff) == 0x4066 && (i2 & 0xf000) == 0xf000)
+ || ((i2 & 0xf0ff) == 0x4066 && (i1 & 0xf000) == 0xf000))
+ return true;
+
+ if ((f1 & (BRANCH | DELAY)) != 0
+ || (f2 & (BRANCH | DELAY)) != 0)
+ return true;
+
+ if ((f1 & SETSSP) != 0 && (f2 & USESSP) != 0)
+ return true;
+ if ((f2 & SETSSP) != 0 && (f1 & USESSP) != 0)
+ return true;
+
+ if ((f1 & SETS1) != 0
+ && sh_insn_uses_reg (i2, op2, (i1 & 0x0f00) >> 8))
+ return true;
+ if ((f1 & SETS2) != 0
+ && sh_insn_uses_reg (i2, op2, (i1 & 0x00f0) >> 4))
+ return true;
+ if ((f1 & SETSR0) != 0
+ && sh_insn_uses_reg (i2, op2, 0))
+ return true;
+ if ((f1 & SETSF1) != 0
+ && sh_insn_uses_freg (i2, op2, (i1 & 0x0f00) >> 8))
+ return true;
+
+ if ((f2 & SETS1) != 0
+ && sh_insn_uses_reg (i1, op1, (i2 & 0x0f00) >> 8))
+ return true;
+ if ((f2 & SETS2) != 0
+ && sh_insn_uses_reg (i1, op1, (i2 & 0x00f0) >> 4))
+ return true;
+ if ((f2 & SETSR0) != 0
+ && sh_insn_uses_reg (i1, op1, 0))
+ return true;
+ if ((f2 & SETSF1) != 0
+ && sh_insn_uses_freg (i1, op1, (i2 & 0x0f00) >> 8))
+ return true;
+
+ /* The instructions do not conflict. */
+ return false;
+}
+
+/* I1 is a load instruction, and I2 is some other instruction. Return
+ true if I1 loads a register which I2 uses. */
+
+static boolean
+sh_load_use (i1, op1, i2, op2)
+ unsigned int i1;
+ const struct sh_opcode *op1;
+ unsigned int i2;
+ const struct sh_opcode *op2;
+{
+ unsigned int f1;
+
+ f1 = op1->flags;
+
+ if ((f1 & LOAD) == 0)
+ return false;
+
+ /* If both SETS1 and SETSSP are set, that means a load to a special
+ register using postincrement addressing mode, which we don't care
+ about here. */
+ if ((f1 & SETS1) != 0
+ && (f1 & SETSSP) == 0
+ && sh_insn_uses_reg (i2, op2, (i1 & 0x0f00) >> 8))
+ return true;
+
+ if ((f1 & SETSR0) != 0
+ && sh_insn_uses_reg (i2, op2, 0))
+ return true;
+
+ if ((f1 & SETSF1) != 0
+ && sh_insn_uses_freg (i2, op2, (i1 & 0x0f00) >> 8))
+ return true;
+
+ return false;
+}
+
+/* Try to align loads and stores within a span of memory. This is
+ called by both the ELF and the COFF sh targets. ABFD and SEC are
+ the BFD and section we are examining. CONTENTS is the contents of
+ the section. SWAP is the routine to call to swap two instructions.
+ RELOCS is a pointer to the internal relocation information, to be
+ passed to SWAP. PLABEL is a pointer to the current label in a
+ sorted list of labels; LABEL_END is the end of the list. START and
+ STOP are the range of memory to examine. If a swap is made,
+ *PSWAPPED is set to true. */
+
+boolean
+_bfd_sh_align_load_span (abfd, sec, contents, swap, relocs,
+ plabel, label_end, start, stop, pswapped)
+ bfd *abfd;
+ asection *sec;
+ bfd_byte *contents;
+ boolean (*swap) PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
+ PTR relocs;
+ bfd_vma **plabel;
+ bfd_vma *label_end;
+ bfd_vma start;
+ bfd_vma stop;
+ boolean *pswapped;
+{
+ bfd_vma i;
+
+ /* Instructions should be aligned on 2 byte boundaries. */
+ if ((start & 1) == 1)
+ ++start;
+
+ /* Now look through the unaligned addresses. */
+ i = start;
+ if ((i & 2) == 0)
+ i += 2;
+ for (; i < stop; i += 4)
+ {
+ unsigned int insn;
+ const struct sh_opcode *op;
+ unsigned int prev_insn = 0;
+ const struct sh_opcode *prev_op = NULL;
+
+ insn = bfd_get_16 (abfd, contents + i);
+ op = sh_insn_info (insn);
+ if (op == NULL
+ || (op->flags & (LOAD | STORE)) == 0)
+ continue;
+
+ /* This is a load or store which is not on a four byte boundary. */
+
+ while (*plabel < label_end && **plabel < i)
+ ++*plabel;
+
+ if (i > start)
+ {
+ prev_insn = bfd_get_16 (abfd, contents + i - 2);
+ prev_op = sh_insn_info (prev_insn);
+
+ /* If the load/store instruction is in a delay slot, we
+ can't swap. */
+ if (prev_op == NULL
+ || (prev_op->flags & DELAY) != 0)
+ continue;
+ }
+ if (i > start
+ && (*plabel >= label_end || **plabel != i)
+ && prev_op != NULL
+ && (prev_op->flags & (LOAD | STORE)) == 0
+ && ! sh_insns_conflict (prev_insn, prev_op, insn, op))
+ {
+ boolean ok;
+
+ /* The load/store instruction does not have a label, and
+ there is a previous instruction; PREV_INSN is not
+ itself a load/store instruction, and PREV_INSN and
+ INSN do not conflict. */
+
+ ok = true;
+
+ if (i >= start + 4)
+ {
+ unsigned int prev2_insn;
+ const struct sh_opcode *prev2_op;
+
+ prev2_insn = bfd_get_16 (abfd, contents + i - 4);
+ prev2_op = sh_insn_info (prev2_insn);
+
+ /* If the instruction before PREV_INSN has a delay
+ slot--that is, PREV_INSN is in a delay slot--we
+ can not swap. */
+ if (prev2_op == NULL
+ || (prev2_op->flags & DELAY) != 0)
+ ok = false;
+
+ /* If the instruction before PREV_INSN is a load,
+ and it sets a register which INSN uses, then
+ putting INSN immediately after PREV_INSN will
+ cause a pipeline bubble, so there is no point to
+ making the swap. */
+ if (ok
+ && (prev2_op->flags & LOAD) != 0
+ && sh_load_use (prev2_insn, prev2_op, insn, op))
+ ok = false;
+ }
+
+ if (ok)
+ {
+ if (! (*swap) (abfd, sec, relocs, contents, i - 2))
+ return false;
+ *pswapped = true;
+ continue;
+ }
+ }
+
+ while (*plabel < label_end && **plabel < i + 2)
+ ++*plabel;
+
+ if (i + 2 < stop
+ && (*plabel >= label_end || **plabel != i + 2))
+ {
+ unsigned int next_insn;
+ const struct sh_opcode *next_op;
+
+ /* There is an instruction after the load/store
+ instruction, and it does not have a label. */
+ next_insn = bfd_get_16 (abfd, contents + i + 2);
+ next_op = sh_insn_info (next_insn);
+ if (next_op != NULL
+ && (next_op->flags & (LOAD | STORE)) == 0
+ && ! sh_insns_conflict (insn, op, next_insn, next_op))
+ {
+ boolean ok;
+
+ /* NEXT_INSN is not itself a load/store instruction,
+ and it does not conflict with INSN. */
+
+ ok = true;
+
+ /* If PREV_INSN is a load, and it sets a register
+ which NEXT_INSN uses, then putting NEXT_INSN
+ immediately after PREV_INSN will cause a pipeline
+ bubble, so there is no reason to make this swap. */
+ if (prev_op != NULL
+ && (prev_op->flags & LOAD) != 0
+ && sh_load_use (prev_insn, prev_op, next_insn, next_op))
+ ok = false;
+
+ /* If INSN is a load, and it sets a register which
+ the insn after NEXT_INSN uses, then doing the
+ swap will cause a pipeline bubble, so there is no
+ reason to make the swap. However, if the insn
+ after NEXT_INSN is itself a load or store
+ instruction, then it is misaligned, so
+ optimistically hope that it will be swapped
+ itself, and just live with the pipeline bubble if
+ it isn't. */
+ if (ok
+ && i + 4 < stop
+ && (op->flags & LOAD) != 0)
+ {
+ unsigned int next2_insn;
+ const struct sh_opcode *next2_op;
+
+ next2_insn = bfd_get_16 (abfd, contents + i + 4);
+ next2_op = sh_insn_info (next2_insn);
+ if ((next2_op->flags & (LOAD | STORE)) == 0
+ && sh_load_use (insn, op, next2_insn, next2_op))
+ ok = false;
+ }
+
+ if (ok)
+ {
+ if (! (*swap) (abfd, sec, relocs, contents, i))
+ return false;
+ *pswapped = true;
+ continue;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Look for loads and stores which we can align to four byte
+ boundaries. See the longer comment above sh_relax_section for why
+ this is desirable. This sets *PSWAPPED if some instruction was
+ swapped. */
+
+static boolean
+sh_align_loads (abfd, sec, internal_relocs, contents, pswapped)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *internal_relocs;
+ bfd_byte *contents;
+ boolean *pswapped;
+{
+ struct internal_reloc *irel, *irelend;
+ bfd_vma *labels = NULL;
+ bfd_vma *label, *label_end;
+
+ *pswapped = false;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Get all the addresses with labels on them. */
+ labels = (bfd_vma *) bfd_malloc (sec->reloc_count * sizeof (bfd_vma));
+ if (labels == NULL)
+ goto error_return;
+ label_end = labels;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ if (irel->r_type == R_SH_LABEL)
+ {
+ *label_end = irel->r_vaddr - sec->vma;
+ ++label_end;
+ }
+ }
+
+ /* Note that the assembler currently always outputs relocs in
+ address order. If that ever changes, this code will need to sort
+ the label values and the relocs. */
+
+ label = labels;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma start, stop;
+
+ if (irel->r_type != R_SH_CODE)
+ continue;
+
+ start = irel->r_vaddr - sec->vma;
+
+ for (irel++; irel < irelend; irel++)
+ if (irel->r_type == R_SH_DATA)
+ break;
+ if (irel < irelend)
+ stop = irel->r_vaddr - sec->vma;
+ else
+ stop = sec->_cooked_size;
+
+ if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_swap_insns,
+ (PTR) internal_relocs, &label,
+ label_end, start, stop, pswapped))
+ goto error_return;
+ }
+
+ free (labels);
+
+ return true;
+
+ error_return:
+ if (labels != NULL)
+ free (labels);
+ return false;
+}
+
+/* Swap two SH instructions. */
+
+static boolean
+sh_swap_insns (abfd, sec, relocs, contents, addr)
+ bfd *abfd;
+ asection *sec;
+ PTR relocs;
+ bfd_byte *contents;
+ bfd_vma addr;
+{
+ struct internal_reloc *internal_relocs = (struct internal_reloc *) relocs;
+ unsigned short i1, i2;
+ struct internal_reloc *irel, *irelend;
+
+ /* Swap the instructions themselves. */
+ i1 = bfd_get_16 (abfd, contents + addr);
+ i2 = bfd_get_16 (abfd, contents + addr + 2);
+ bfd_put_16 (abfd, i2, contents + addr);
+ bfd_put_16 (abfd, i1, contents + addr + 2);
+
+ /* Adjust all reloc addresses. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ int type, add;
+
+ /* There are a few special types of relocs that we don't want to
+ adjust. These relocs do not apply to the instruction itself,
+ but are only associated with the address. */
+ type = irel->r_type;
+ if (type == R_SH_ALIGN
+ || type == R_SH_CODE
+ || type == R_SH_DATA
+ || type == R_SH_LABEL)
+ continue;
+
+ /* If an R_SH_USES reloc points to one of the addresses being
+ swapped, we must adjust it. It would be incorrect to do this
+ for a jump, though, since we want to execute both
+ instructions after the jump. (We have avoided swapping
+ around a label, so the jump will not wind up executing an
+ instruction it shouldn't). */
+ if (type == R_SH_USES)
+ {
+ bfd_vma off;
+
+ off = irel->r_vaddr - sec->vma + 4 + irel->r_offset;
+ if (off == addr)
+ irel->r_offset += 2;
+ else if (off == addr + 2)
+ irel->r_offset -= 2;
+ }
+
+ if (irel->r_vaddr - sec->vma == addr)
+ {
+ irel->r_vaddr += 2;
+ add = -2;
+ }
+ else if (irel->r_vaddr - sec->vma == addr + 2)
+ {
+ irel->r_vaddr -= 2;
+ add = 2;
+ }
+ else
+ add = 0;
+
+ if (add != 0)
+ {
+ bfd_byte *loc;
+ unsigned short insn, oinsn;
+ boolean overflow;
+
+ loc = contents + irel->r_vaddr - sec->vma;
+ overflow = false;
+ switch (type)
+ {
+ default:
+ break;
+
+ case R_SH_PCDISP8BY2:
+ case R_SH_PCRELIMM8BY2:
+ insn = bfd_get_16 (abfd, loc);
+ oinsn = insn;
+ insn += add / 2;
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, loc);
+ break;
+
+ case R_SH_PCDISP:
+ insn = bfd_get_16 (abfd, loc);
+ oinsn = insn;
+ insn += add / 2;
+ if ((oinsn & 0xf000) != (insn & 0xf000))
+ overflow = true;
+ bfd_put_16 (abfd, insn, loc);
+ break;
+
+ case R_SH_PCRELIMM8BY4:
+ /* This reloc ignores the least significant 3 bits of
+ the program counter before adding in the offset.
+ This means that if ADDR is at an even address, the
+ swap will not affect the offset. If ADDR is an at an
+ odd address, then the instruction will be crossing a
+ four byte boundary, and must be adjusted. */
+ if ((addr & 3) != 0)
+ {
+ insn = bfd_get_16 (abfd, loc);
+ oinsn = insn;
+ insn += add / 2;
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, loc);
+ }
+
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: fatal: reloc overflow while relaxing",
+ bfd_get_filename (abfd), (unsigned long) irel->r_vaddr));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* This is a modification of _bfd_coff_generic_relocate_section, which
+ will handle SH relaxing. */
+
+static boolean
+sh_relocate_section (output_bfd, info, input_bfd, input_section, contents,
+ relocs, syms, sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma addend;
+ bfd_vma val;
+ reloc_howto_type *howto;
+ bfd_reloc_status_type rstat;
+
+ /* Almost all relocs have to do with relaxing. If any work must
+ be done for them, it has been done in sh_relax_section. */
+ if (rel->r_type != R_SH_IMM32
+ && rel->r_type != R_SH_PCDISP)
+ continue;
+
+ symndx = rel->r_symndx;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ if (symndx < 0
+ || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
+ {
+ (*_bfd_error_handler)
+ ("%s: illegal symbol index %ld in relocs",
+ bfd_get_filename (input_bfd), symndx);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ }
+
+ if (sym != NULL && sym->n_scnum != 0)
+ addend = - sym->n_value;
+ else
+ addend = 0;
+
+ if (rel->r_type == R_SH_PCDISP)
+ addend -= 4;
+
+ if (rel->r_type >= SH_COFF_HOWTO_COUNT)
+ howto = NULL;
+ else
+ howto = &sh_coff_howtos[rel->r_type];
+
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ asection *sec;
+
+ /* There is nothing to do for an internal PCDISP reloc. */
+ if (rel->r_type == R_SH_PCDISP)
+ continue;
+
+ if (symndx == -1)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value
+ - sec->vma);
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (! info->relocateable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents,
+ rel->r_vaddr - input_section->vma,
+ val, addend);
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else if (sym->_n._n_n._n_zeroes == 0
+ && sym->_n._n_n._n_offset != 0)
+ name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
+ else
+ {
+ strncpy (buf, sym->_n._n_name, SYMNMLEN);
+ buf[SYMNMLEN] = '\0';
+ name = buf;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses sh_relocate_section. */
+
+static bfd_byte *
+sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ asection *input_section = link_order->u.indirect.section;
+ bfd *input_bfd = input_section->owner;
+ asection **sections = NULL;
+ struct internal_reloc *internal_relocs = NULL;
+ struct internal_syment *internal_syms = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocateable
+ || coff_section_data (input_bfd, input_section) == NULL
+ || coff_section_data (input_bfd, input_section)->contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocateable,
+ symbols);
+
+ memcpy (data, coff_section_data (input_bfd, input_section)->contents,
+ input_section->_raw_size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ bfd_size_type symesz = bfd_coff_symesz (input_bfd);
+ bfd_byte *esym, *esymend;
+ struct internal_syment *isymp;
+ asection **secpp;
+
+ if (! _bfd_coff_get_external_symbols (input_bfd))
+ goto error_return;
+
+ internal_relocs = (_bfd_coff_read_internal_relocs
+ (input_bfd, input_section, false, (bfd_byte *) NULL,
+ false, (struct internal_reloc *) NULL));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ internal_syms = ((struct internal_syment *)
+ bfd_malloc (obj_raw_syment_count (input_bfd)
+ * sizeof (struct internal_syment)));
+ if (internal_syms == NULL)
+ goto error_return;
+
+ sections = (asection **) bfd_malloc (obj_raw_syment_count (input_bfd)
+ * sizeof (asection *));
+ if (sections == NULL)
+ goto error_return;
+
+ isymp = internal_syms;
+ secpp = sections;
+ esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
+ esymend = esym + obj_raw_syment_count (input_bfd) * symesz;
+ while (esym < esymend)
+ {
+ bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
+
+ if (isymp->n_scnum != 0)
+ *secpp = coff_section_from_bfd_index (input_bfd, isymp->n_scnum);
+ else
+ {
+ if (isymp->n_value == 0)
+ *secpp = bfd_und_section_ptr;
+ else
+ *secpp = bfd_com_section_ptr;
+ }
+
+ esym += (isymp->n_numaux + 1) * symesz;
+ secpp += isymp->n_numaux + 1;
+ isymp += isymp->n_numaux + 1;
+ }
+
+ if (! sh_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ internal_syms, sections))
+ goto error_return;
+
+ free (sections);
+ sections = NULL;
+ free (internal_syms);
+ internal_syms = NULL;
+ free (internal_relocs);
+ internal_relocs = NULL;
+ }
+
+ return data;
+
+ error_return:
+ if (internal_relocs != NULL)
+ free (internal_relocs);
+ if (internal_syms != NULL)
+ free (internal_syms);
+ if (sections != NULL)
+ free (sections);
+ return NULL;
+}
+
+/* The target vectors. */
+
+const bfd_target shcoff_vec =
+{
+ "coff-sh", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+
+const bfd_target shlcoff_vec =
+{
+ "coff-shl", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little endian too*/
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
+
+/* Some people want versions of the SH COFF target which do not align
+ to 16 byte boundaries. We implement that by adding a couple of new
+ target vectors. These are just like the ones above, but they
+ change the default section alignment. To generate them in the
+ assembler, use -small. To use them in the linker, use -b
+ coff-sh{l}-small and -oformat coff-sh{l}-small.
+
+ Yes, this is a horrible hack. A general solution for setting
+ section alignment in COFF is rather complex. ELF handles this
+ correctly. */
+
+/* Only recognize the small versions if the target was not defaulted.
+ Otherwise we won't recognize the non default endianness. */
+
+static const bfd_target *
+coff_small_object_p (abfd)
+ bfd *abfd;
+{
+ if (abfd->target_defaulted)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ return coff_object_p (abfd);
+}
+
+/* Set the section alignment for the small versions. */
+
+static boolean
+coff_small_new_section_hook (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ if (! coff_new_section_hook (abfd, section))
+ return false;
+
+ /* We must align to at least a four byte boundary, because longword
+ accesses must be on a four byte boundary. */
+ if (section->alignment_power == COFF_DEFAULT_SECTION_ALIGNMENT_POWER)
+ section->alignment_power = 2;
+
+ return true;
+}
+
+/* This is copied from bfd_coff_std_swap_table so that we can change
+ the default section alignment power. */
+
+static const bfd_coff_backend_data bfd_coff_small_swap_table =
+{
+ coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in,
+ coff_swap_aux_out, coff_swap_sym_out,
+ coff_swap_lineno_out, coff_swap_reloc_out,
+ coff_swap_filehdr_out, coff_swap_aouthdr_out,
+ coff_swap_scnhdr_out,
+ FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ,
+#ifdef COFF_LONG_FILENAMES
+ true,
+#else
+ false,
+#endif
+#ifdef COFF_LONG_SECTION_NAMES
+ true,
+#else
+ false,
+#endif
+ 2,
+ coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in,
+ coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
+ coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
+ coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
+ coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
+ coff_sym_is_global, coff_compute_section_file_positions,
+ coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
+ coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_link_output_has_begun, coff_final_link_postscript
+};
+
+#define coff_small_close_and_cleanup \
+ coff_close_and_cleanup
+#define coff_small_bfd_free_cached_info \
+ coff_bfd_free_cached_info
+#define coff_small_get_section_contents \
+ coff_get_section_contents
+#define coff_small_get_section_contents_in_window \
+ coff_get_section_contents_in_window
+
+const bfd_target shcoff_small_vec =
+{
+ "coff-sh-small", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff_small),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) &bfd_coff_small_swap_table
+};
+
+const bfd_target shlcoff_small_vec =
+{
+ "coff-shl-small", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little endian too*/
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_small_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff_small),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) &bfd_coff_small_swap_table
+};
diff --git a/bfd/coff-sparc.c b/bfd/coff-sparc.c
new file mode 100644
index 00000000000..bc2cf153843
--- /dev/null
+++ b/bfd/coff-sparc.c
@@ -0,0 +1,256 @@
+/* BFD back-end for Sparc COFF files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/sparc.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+#define BADMAG(x) ((x).f_magic != SPARCMAGIC && (x).f_magic != LYNXCOFFMAGIC)
+
+/* The page size is a guess based on ELF. */
+#define COFF_PAGE_SIZE 0x10000
+
+enum reloc_type
+ {
+ R_SPARC_NONE = 0,
+ R_SPARC_8, R_SPARC_16, R_SPARC_32,
+ R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
+ R_SPARC_WDISP30, R_SPARC_WDISP22,
+ R_SPARC_HI22, R_SPARC_22,
+ R_SPARC_13, R_SPARC_LO10,
+ R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
+ R_SPARC_PC10, R_SPARC_PC22,
+ R_SPARC_WPLT30,
+ R_SPARC_COPY,
+ R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
+ R_SPARC_RELATIVE,
+ R_SPARC_UA32,
+ R_SPARC_max
+ };
+
+#if 0
+static CONST char *CONST reloc_type_names[] =
+{
+ "R_SPARC_NONE",
+ "R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
+ "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
+ "R_SPARC_WDISP30", "R_SPARC_WDISP22",
+ "R_SPARC_HI22", "R_SPARC_22",
+ "R_SPARC_13", "R_SPARC_LO10",
+ "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
+ "R_SPARC_PC10", "R_SPARC_PC22",
+ "R_SPARC_WPLT30",
+ "R_SPARC_COPY",
+ "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
+ "R_SPARC_RELATIVE",
+ "R_SPARC_UA32",
+};
+#endif
+
+/* This is stolen pretty directly from elf.c. */
+static bfd_reloc_status_type
+bfd_coff_generic_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+
+static bfd_reloc_status_type
+bfd_coff_generic_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ return bfd_reloc_continue;
+}
+
+static reloc_howto_type coff_sparc_howto_table[] =
+{
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_32", false,0,0xffffffff,true),
+ HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP32", false,0,0x00ffffff,true),
+ HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_HI22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_LO10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_WPLT30", false,0,0x00000000,true),
+ HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_COPY", false,0,0x00000000,true),
+ HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_RELATIVE",false,0,0x00000000,true),
+ HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_UA32", false,0,0x00000000,true),
+};
+
+struct coff_reloc_map {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char coff_reloc_val;
+};
+
+static CONST struct coff_reloc_map sparc_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_SPARC_NONE, },
+ { BFD_RELOC_16, R_SPARC_16, },
+ { BFD_RELOC_8, R_SPARC_8 },
+ { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
+ { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */
+ { BFD_RELOC_32, R_SPARC_32 },
+ { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
+ { BFD_RELOC_HI22, R_SPARC_HI22 },
+ { BFD_RELOC_LO10, R_SPARC_LO10, },
+ { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
+ { BFD_RELOC_SPARC22, R_SPARC_22 },
+ { BFD_RELOC_SPARC13, R_SPARC_13 },
+ { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
+ { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
+ { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
+ { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
+ { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
+ { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
+ { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
+ { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
+ { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
+ { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
+ { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
+ /* { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
+};
+
+static reloc_howto_type *
+coff_sparc_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+ for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct coff_reloc_map); i++)
+ {
+ if (sparc_reloc_map[i].bfd_reloc_val == code)
+ return &coff_sparc_howto_table[(int) sparc_reloc_map[i].coff_reloc_val];
+ }
+ return 0;
+}
+#define coff_bfd_reloc_type_lookup coff_sparc_reloc_type_lookup
+
+static void
+rtype2howto (cache_ptr, dst)
+ arelent *cache_ptr;
+ struct internal_reloc *dst;
+{
+ BFD_ASSERT (dst->r_type < (unsigned int) R_SPARC_max);
+ cache_ptr->howto = &coff_sparc_howto_table[dst->r_type];
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ cache_ptr->addend = reloc.r_offset;
+
+/* Clear the r_spare field in relocs. */
+#define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \
+ do { \
+ dst->r_spare[0] = 0; \
+ dst->r_spare[1] = 0; \
+ } while (0)
+
+#define __A_MAGIC_SET__
+
+/* Enable Sparc-specific hacks in coffcode.h. */
+
+#define COFF_SPARC
+
+#include "coffcode.h"
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ sparccoff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-sparc", /* name */
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+/* Note that we allow an object file to be treated as a core file as well. */
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, coff_object_p},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-stgo32.c b/bfd/coff-stgo32.c
new file mode 100644
index 00000000000..21724fec0dc
--- /dev/null
+++ b/bfd/coff-stgo32.c
@@ -0,0 +1,464 @@
+/* BFD back-end for Intel 386 COFF files (go32 variant with a stub).
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Robert Hoehne.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file handles now also stubbed coff images. The stub is a small
+ DOS executable program before the coff image to load it in memory
+ and execute it. This is needed, because DOS cannot run coff files.
+
+ All the functions below are called by the corresponding functions
+ from coffswap.h.
+ The only thing what they do is to adjust the information stored in
+ the COFF file which are offset into the file.
+ This is needed, because DJGPP uses a very special way to load and run
+ the coff image. It loads the image in memory and assumes then, that the
+ image had no stub by using the filepointers as pointers in the coff
+ image and NOT in the file.
+
+ To be compatible with any existing executables I have fixed this
+ here and NOT in the DJGPP startup code.
+ */
+
+#define TARGET_SYM go32stubbedcoff_vec
+#define TARGET_NAME "coff-go32-exe"
+#define TARGET_UNDERSCORE '_'
+#define COFF_GO32_EXE
+
+#include "bfd.h"
+
+/* At first the prototypes */
+
+static void
+adjust_filehdr_in_post PARAMS ((bfd * abfd, PTR src, PTR dst));
+static void
+adjust_filehdr_out_pre PARAMS ((bfd * abfd, PTR in, PTR out));
+static void
+adjust_filehdr_out_post PARAMS ((bfd * abfd, PTR in, PTR out));
+
+static void
+adjust_scnhdr_in_post PARAMS ((bfd * abfd, PTR ext, PTR in));
+static void
+adjust_scnhdr_out_pre PARAMS ((bfd * abfd, PTR in, PTR out));
+static void
+adjust_scnhdr_out_post PARAMS ((bfd * abfd, PTR in, PTR out));
+
+static void
+adjust_aux_in_post PARAMS ((bfd * abfd, PTR ext1, int type, int class, int indx,
+ int numaux, PTR in1));
+static void
+adjust_aux_out_pre PARAMS ((bfd * abfd, PTR inp, int type, int class, int indx,
+ int numaux, PTR extp));
+static void
+adjust_aux_out_post PARAMS ((bfd * abfd, PTR inp, int type, int class, int indx,
+ int numaux, PTR extp));
+
+static void
+create_go32_stub PARAMS ((bfd * abfd));
+
+/*
+ All that ..._PRE and ...POST functions are called from the corresponding
+ coff_swap... functions. The ...PRE functions are called at the beginning
+ of the function and the ...POST functions at the end of the swap routines.
+ */
+
+#define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post
+#define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre
+#define COFF_ADJUST_FILEHDR_OUT_POST adjust_filehdr_out_post
+
+#define COFF_ADJUST_SCNHDR_IN_POST adjust_scnhdr_in_post
+#define COFF_ADJUST_SCNHDR_OUT_PRE adjust_scnhdr_out_pre
+#define COFF_ADJUST_SCNHDR_OUT_POST adjust_scnhdr_out_post
+
+#define COFF_ADJUST_AUX_IN_POST adjust_aux_in_post
+#define COFF_ADJUST_AUX_OUT_PRE adjust_aux_out_pre
+#define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post
+
+static boolean
+ go32_stubbed_coff_bfd_copy_private_bfd_data PARAMS ((bfd * ibfd, bfd * obfd));
+
+#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
+
+#include "coff-i386.c"
+
+/* I hold in the usrdata the stub */
+#define bfd_coff_go32stub bfd_usrdata
+
+/* This macro is used, because I cannot assume the endianess of the
+ host system */
+#define _H(index) (bfd_h_get_16(abfd, (bfd_byte *)(header+index*2)))
+
+/* This function checks if the bfd is a stubbed coff image */
+static const bfd_target *
+go32_stubbed_coff_object_p (abfd)
+ bfd *abfd;
+{
+ unsigned char header[10];
+ char magic[8];
+ unsigned long coff_start, exe_start;
+
+ if (bfd_read (&header, 1, sizeof (header), abfd) != sizeof (header))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ if (_H (0) != 0x5a4d) /* it is not an exe file. maybe a coff-image */
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ coff_start = (long) _H (2) * 512L;
+ if (_H (1))
+ coff_start += (long) _H (1) - 512L;
+
+ /* We can handle only a stub with a length of STUBSIZE */
+ if (coff_start != STUBSIZE)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ exe_start = _H (4) * 16;
+ if (bfd_seek (abfd, exe_start, SEEK_SET) != 0)
+ return 0;
+ if (bfd_read (&magic, 1, 8, abfd) != 8)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ if (memcmp (magic, "go32stub", 8) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return 0;
+
+ /* Call the normal COFF detection routine */
+ return coff_object_p (abfd);
+}
+
+/* These bytes are a 2048-byte DOS executable, which loads the COFF
+ image into memory and then runs it. It is called 'stub' */
+
+static unsigned char stub_bytes[STUBSIZE] =
+{
+#include "go32stub.h"
+};
+
+/*
+ I have not commented each swap function below, because the
+ technique is in any function the same. For the ...in function,
+ all the pointers are adjusted by adding STUBSIZE and for the
+ ...out function, it is subtracted first and after calling the
+ standard swap function it is reset to the old value */
+
+/* This macro is used for adjusting the filepointers, which
+ is done only, if the pointer is nonzero */
+
+#define ADJUST_VAL(val,diff) \
+ if (val != 0) val += diff
+
+static void
+adjust_filehdr_in_post (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ FILHDR *filehdr_src = (FILHDR *) src;
+ struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
+
+ ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE);
+
+ /* Save now the stub to be used later */
+ bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, STUBSIZE);
+
+ /* Since this function returns no status, I do not set here
+ any bfd_error_...
+ That means, before the use of bfd_coff_go32stub (), this value
+ should be checked if it is != NULL */
+ if (bfd_coff_go32stub (abfd) == NULL)
+ return;
+ memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE);
+}
+
+static void
+adjust_filehdr_out_pre (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
+ FILHDR *filehdr_out = (FILHDR *) out;
+
+ /* Generate the stub */
+ create_go32_stub (abfd);
+
+ /* Copy the stub to the file header */
+ if (bfd_coff_go32stub (abfd) != NULL)
+ memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE);
+ else
+ /* use the default */
+ memcpy (filehdr_out->stub, stub_bytes, STUBSIZE);
+
+ ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE);
+}
+
+static void
+adjust_filehdr_out_post (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
+ /* undo the above change */
+ ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE);
+}
+
+static void
+adjust_scnhdr_in_post (abfd, ext, in)
+ bfd *abfd;
+ PTR ext;
+ PTR in;
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
+}
+
+static void
+adjust_scnhdr_out_pre (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ ADJUST_VAL (scnhdr_int->s_scnptr, -STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_relptr, -STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_lnnoptr, -STUBSIZE);
+}
+
+static void
+adjust_scnhdr_out_post (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
+}
+
+static void
+adjust_aux_in_post (abfd, ext1, type, class, indx, numaux, in1)
+ bfd *abfd;
+ PTR ext1;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR in1;
+{
+ union internal_auxent *in = (union internal_auxent *) in1;
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
+ }
+}
+
+static void
+adjust_aux_out_pre (abfd, inp, type, class, indx, numaux, extp)
+ bfd *abfd;
+ PTR inp;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR extp;
+{
+ union internal_auxent *in = (union internal_auxent *) inp;
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -STUBSIZE);
+ }
+}
+
+static void
+adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp)
+ bfd *abfd;
+ PTR inp;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR extp;
+{
+ union internal_auxent *in = (union internal_auxent *) inp;
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
+ }
+}
+
+/*
+ That's the function, which creates the stub. There are
+ different cases from where the stub is taken.
+ At first the environment variable $(GO32STUB) is checked and then
+ $(STUB) if it was not set.
+ If it exists and points to a valid stub the stub is taken from
+ that file. This file can be also a whole executable file, because
+ the stub is computed from the exe information at the start of that
+ file.
+
+ If there was any error, the standard stub (compiled in this file)
+ is taken.
+ */
+
+static void
+create_go32_stub (abfd)
+ bfd *abfd;
+{
+ /* Do it only once */
+ if (bfd_coff_go32stub (abfd) == NULL)
+ {
+ char *stub;
+ struct stat st;
+ int f;
+ unsigned char header[10];
+ char magic[8];
+ unsigned long coff_start, exe_start;
+
+ /* Check at first the environment variable $(GO32STUB) */
+ stub = getenv ("GO32STUB");
+ /* Now check the environment variable $(STUB) */
+ if (stub == NULL)
+ stub = getenv ("STUB");
+ if (stub == NULL)
+ goto stub_end;
+ if (stat (stub, &st) != 0)
+ goto stub_end;
+#ifdef O_BINARY
+ f = open (stub, O_RDONLY | O_BINARY);
+#else
+ f = open (stub, O_RDONLY);
+#endif
+ if (f < 0)
+ goto stub_end;
+ if (read (f, &header, sizeof (header)) < 0)
+ {
+ close (f);
+ goto stub_end;
+ }
+ if (_H (0) != 0x5a4d) /* it is not an exe file */
+ {
+ close (f);
+ goto stub_end;
+ }
+ /* Compute the size of the stub (it is every thing up
+ to the beginning of the coff image) */
+ coff_start = (long) _H (2) * 512L;
+ if (_H (1))
+ coff_start += (long) _H (1) - 512L;
+
+ /* Currently there is only a fixed stub size of 2048 bytes
+ supported */
+ if (coff_start != 2048)
+ {
+ close (f);
+ goto stub_end;
+ }
+ exe_start = _H (4) * 16;
+ if ((unsigned long) lseek (f, exe_start, SEEK_SET) != exe_start)
+ {
+ close (f);
+ goto stub_end;
+ }
+ if (read (f, &magic, 8) != 8)
+ {
+ close (f);
+ goto stub_end;
+ }
+ if (memcmp (magic, "go32stub", 8) != 0)
+ {
+ close (f);
+ goto stub_end;
+ }
+ /* Now we found a correct stub (hopefully) */
+ bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, coff_start);
+ if (bfd_coff_go32stub (abfd) == NULL)
+ {
+ close (f);
+ return;
+ }
+ lseek (f, 0L, SEEK_SET);
+ if ((unsigned long) read (f, bfd_coff_go32stub (abfd), coff_start)
+ != coff_start)
+ {
+ bfd_release (abfd, bfd_coff_go32stub (abfd));
+ bfd_coff_go32stub (abfd) = NULL;
+ }
+ close (f);
+ }
+stub_end:
+ /* There was something wrong above, so use now the standard builtin
+ stub */
+ if (bfd_coff_go32stub (abfd) == NULL)
+ {
+ bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, STUBSIZE);
+ if (bfd_coff_go32stub (abfd) == NULL)
+ {
+ return;
+ }
+
+ memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE);
+ }
+}
+
+/* If ibfd was a stubbed coff image, copy the stub from that bfd
+ to the new obfd.
+ */
+
+static boolean
+go32_stubbed_coff_bfd_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ /* check if both are the same targets */
+ if (ibfd->xvec != obfd->xvec)
+ return true;
+
+ /* check if both have a valid stub */
+ if (bfd_coff_go32stub (ibfd) == NULL
+ || bfd_coff_go32stub (obfd) == NULL)
+ return true;
+
+ /* Now copy the stub */
+ memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE);
+
+ return true;
+}
diff --git a/bfd/coff-svm68k.c b/bfd/coff-svm68k.c
new file mode 100644
index 00000000000..3d2a5a7d565
--- /dev/null
+++ b/bfd/coff-svm68k.c
@@ -0,0 +1,26 @@
+/* BFD back-end for Motorola sysv68
+ Copyright 1997 Free Software Foundation, Inc.
+ Written by Philippe De Muyter <phdm@info.ucl.ac.be>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM m68ksysvcoff_vec
+#define TARGET_NAME "coff-m68k-sysv"
+#define STATIC_RELOCS
+#define COFF_COMMON_ADDEND
+
+#include "coff-m68k.c"
diff --git a/bfd/coff-tic30.c b/bfd/coff-tic30.c
new file mode 100644
index 00000000000..3ff8c594036
--- /dev/null
+++ b/bfd/coff-tic30.c
@@ -0,0 +1,206 @@
+/* BFD back-end for TMS320C30 coff binaries.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/tic30.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
+
+reloc_howto_type tic30_coff_howto_table[] =
+{
+ HOWTO (R_TIC30_ABS16, 2, 1, 16, false, 0, 0, NULL,
+ "16", false, 0x0000FFFF, 0x0000FFFF, false),
+ HOWTO (R_TIC30_ABS24, 2, 2, 24, false, 8, complain_overflow_bitfield, NULL,
+ "24", false, 0xFFFFFF00, 0xFFFFFF00, false),
+ HOWTO (R_TIC30_LDP, 18, 0, 24, false, 0, complain_overflow_bitfield, NULL,
+ "LDP", false, 0x00FF0000, 0x000000FF, false),
+ HOWTO (R_TIC30_ABS32, 2, 2, 32, false, 0, complain_overflow_bitfield, NULL,
+ "32", false, 0xFFFFFFFF, 0xFFFFFFFF, false),
+ HOWTO (R_TIC30_PC16, 2, 1, 16, true, 0, complain_overflow_signed, NULL,
+ "PCREL", false, 0x0000FFFF, 0x0000FFFF, false),
+ {-1}
+};
+
+#ifndef coff_bfd_reloc_type_lookup
+#define coff_bfd_reloc_type_lookup tic30_coff_reloc_type_lookup
+
+/* For the case statement use the code values used in tc_gen_reloc to
+ map to the howto table entries that match those in both the aout
+ and coff implementations. */
+reloc_howto_type *
+tic30_coff_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_8:
+ case BFD_RELOC_TIC30_LDP:
+ return &tic30_coff_howto_table[2];
+ case BFD_RELOC_16:
+ return &tic30_coff_howto_table[0];
+ case BFD_RELOC_24:
+ return &tic30_coff_howto_table[1];
+ case BFD_RELOC_16_PCREL:
+ return &tic30_coff_howto_table[4];
+ case BFD_RELOC_32:
+ return &tic30_coff_howto_table[3];
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+}
+
+#endif
+
+/* Turn a howto into a reloc number */
+
+static int
+coff_tic30_select_reloc (howto)
+ reloc_howto_type *howto;
+{
+ return howto->type;
+}
+
+#define SELECT_RELOC(x,howto) x.r_type = coff_tic30_select_reloc(howto)
+
+
+#define BADMAG(x) TIC30BADMAG(x)
+#define TIC30 1 /* Customize coffcode.h */
+#define __A_MAGIC_SET__
+
+/* Code to swap in the reloc */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) dst->r_stuff[0] = 'S'; \
+dst->r_stuff[1] = 'C';
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table. */
+
+static void
+rtype2howto (internal, dst)
+ arelent *internal;
+ struct internal_reloc *dst;
+{
+ switch (dst->r_type)
+ {
+ case R_TIC30_ABS16:
+ internal->howto = &tic30_coff_howto_table[0];
+ break;
+ case R_TIC30_ABS24:
+ internal->howto = &tic30_coff_howto_table[1];
+ break;
+ case R_TIC30_ABS32:
+ internal->howto = &tic30_coff_howto_table[3];
+ break;
+ case R_TIC30_LDP:
+ internal->howto = &tic30_coff_howto_table[2];
+ break;
+ case R_TIC30_PC16:
+ internal->howto = &tic30_coff_howto_table[4];
+ break;
+ default:
+ abort ();
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+
+/* Perform any necessary magic to the addend in a reloc entry */
+
+#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
+ cache_ptr->addend = ext_reloc.r_offset;
+
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (relent, reloc, symbols, abfd, section)
+ arelent *relent;
+ struct internal_reloc *reloc;
+ asymbol **symbols;
+ bfd *abfd;
+ asection *section;
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (reloc->r_symndx > 0)
+ {
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ }
+ else
+ {
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ relent->addend = reloc->r_offset;
+ relent->address -= section->vma;
+}
+
+#include "coffcode.h"
+
+const bfd_target tic30_coff_vec =
+{
+ "coff-tic30", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-tic80.c b/bfd/coff-tic80.c
new file mode 100644
index 00000000000..043c8a01835
--- /dev/null
+++ b/bfd/coff-tic80.c
@@ -0,0 +1,759 @@
+/* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP).
+ Copyright 1996, 1997, 1999 Free Software Foundation, Inc.
+
+ Written by Fred Fish (fnf@cygnus.com)
+
+ There is nothing new under the sun. This file draws a lot on other
+ coff files.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bfdlink.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/tic80.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+#define COFF_ALIGN_IN_SECTION_HEADER 1
+#define COFF_ALIGN_IN_SFLAGS 1
+
+#define GET_SCNHDR_FLAGS bfd_h_get_16
+#define PUT_SCNHDR_FLAGS bfd_h_put_16
+
+static void rtype2howto
+ PARAMS ((arelent *cache_ptr, struct internal_reloc *dst));
+static bfd_reloc_status_type ppbase_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type glob15_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type glob16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type local16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean coff_tic80_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+static reloc_howto_type tic80_howto_table[] =
+{
+
+ HOWTO (R_RELLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ NULL, /* special_function */
+ "RELLONG", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MPPCR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ NULL, /* special_function */
+ "MPPCR", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_ABS, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ NULL, /* special_function */
+ "ABS", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPBASE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppbase_reloc, /* special_function */
+ "PPBASE", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPLBASE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppbase_reloc, /* special_function */
+ "PPLBASE", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PP15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob15_reloc, /* special_function */
+ "PP15", /* name */
+ true, /* partial_inplace */
+ 0x1ffc0, /* src_mask */
+ 0x1ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PP15W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob15_reloc, /* special_function */
+ "PP15W", /* name */
+ true, /* partial_inplace */
+ 0x1ffc0, /* src_mask */
+ 0x1ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PP15H, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob15_reloc, /* special_function */
+ "PP15H", /* name */
+ true, /* partial_inplace */
+ 0x1ffc0, /* src_mask */
+ 0x1ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PP16B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob16_reloc, /* special_function */
+ "PP16B", /* name */
+ true, /* partial_inplace */
+ 0x3ffc0, /* src_mask */
+ 0x3ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPL15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PPL15", /* name */
+ true, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPL15W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PPL15W", /* name */
+ true, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPL15H, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PPL15H", /* name */
+ true, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPL16B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ local16_reloc, /* special_function */
+ "PPL16B", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPN15, /* type */
+ 0, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob15_reloc, /* special_function */
+ "PPN15", /* name */
+ true, /* partial_inplace */
+ 0x1ffc0, /* src_mask */
+ 0x1ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPN15W, /* type */
+ 2, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob15_reloc, /* special_function */
+ "PPN15W", /* name */
+ true, /* partial_inplace */
+ 0x1ffc0, /* src_mask */
+ 0x1ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPN15H, /* type */
+ 1, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob15_reloc, /* special_function */
+ "PPN15H", /* name */
+ true, /* partial_inplace */
+ 0x1ffc0, /* src_mask */
+ 0x1ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPN16B, /* type */
+ 0, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ glob16_reloc, /* special_function */
+ "PPN16B", /* name */
+ true, /* partial_inplace */
+ 0x3ffc0, /* src_mask */
+ 0x3ffc0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPLN15, /* type */
+ 0, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PPLN15", /* name */
+ true, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPLN15W, /* type */
+ 2, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PPLN15W", /* name */
+ true, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPLN15H, /* type */
+ 1, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "PPLN15H", /* name */
+ true, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_PPLN16B, /* type */
+ 0, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ local16_reloc, /* special_function */
+ "PPLN16B", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+/* Special relocation functions, used when the output file is not
+ itself a COFF TIc80 file. */
+
+/* This special function is used for the base address type
+ relocations. */
+
+static bfd_reloc_status_type
+ppbase_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* This special function is used for the global 15 bit relocations. */
+
+static bfd_reloc_status_type
+glob15_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* This special function is used for the global 16 bit relocations. */
+
+static bfd_reloc_status_type
+glob16_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* This special function is used for the local 16 bit relocations. */
+
+static bfd_reloc_status_type
+local16_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* Code to turn an external r_type into a pointer to an entry in the howto_table.
+ If passed an r_type we don't recognize the abort rather than silently failing
+ to generate an output file. */
+
+static void
+rtype2howto (cache_ptr, dst)
+ arelent *cache_ptr;
+ struct internal_reloc *dst;
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof tic80_howto_table / sizeof tic80_howto_table[0]; i++)
+ {
+ if (tic80_howto_table[i].type == dst->r_type)
+ {
+ cache_ptr->howto = tic80_howto_table + i;
+ return;
+ }
+ }
+
+ (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
+ (unsigned int) dst->r_type);
+ cache_ptr->howto = tic80_howto_table + 0;
+}
+
+#define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
+#define coff_rtype_to_howto coff_tic80_rtype_to_howto
+
+static reloc_howto_type *
+coff_tic80_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+ arelent genrel;
+
+ if (rel -> r_symndx == -1 && addendp != NULL)
+ {
+ /* This is a TI "internal relocation", which means that the relocation
+ amount is the amount by which the current section is being relocated
+ in the output section. */
+ *addendp = (sec -> output_section -> vma + sec -> output_offset) - sec -> vma;
+ }
+ RTYPE2HOWTO (&genrel, rel);
+ return genrel.howto;
+}
+
+#ifndef BADMAG
+#define BADMAG(x) TIC80BADMAG(x)
+#endif
+
+#define coff_relocate_section coff_tic80_relocate_section
+
+/* We need a special relocation routine to handle the PP relocs. Most
+ of this is a copy of _bfd_coff_generic_relocate_section. */
+
+static boolean
+coff_tic80_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents, relocs, syms,
+ sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma addend;
+ bfd_vma val;
+ reloc_howto_type *howto;
+ bfd_reloc_status_type rstat;
+ bfd_vma addr;
+
+ symndx = rel->r_symndx;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ }
+
+ /* COFF treats common symbols in one of two ways. Either the
+ size of the symbol is included in the section contents, or it
+ is not. We assume that the size is not included, and force
+ the rtype_to_howto function to adjust the addend as needed. */
+
+ if (sym != NULL && sym->n_scnum != 0)
+ addend = - sym->n_value;
+ else
+ addend = 0;
+
+ howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
+ sym, &addend);
+ if (howto == NULL)
+ return false;
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ asection *sec;
+
+ if (symndx == -1)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value);
+ if (! obj_pe (output_bfd))
+ val -= sec->vma;
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+
+ else if (! info->relocateable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ addr = rel->r_vaddr - input_section->vma;
+
+ /* FIXME: This code assumes little endian, but the PP can
+ apparently be bi-endian. I don't know if the bi-endianness
+ applies to the instruction set or just to the data. */
+ switch (howto->type)
+ {
+ default:
+ case R_ABS:
+ case R_RELLONGX:
+ case R_PPL15:
+ case R_PPL15W:
+ case R_PPL15H:
+ case R_PPLN15:
+ case R_PPLN15W:
+ case R_PPLN15H:
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, addr, val, addend);
+ break;
+
+ case R_PP15:
+ case R_PP15W:
+ case R_PP15H:
+ case R_PPN15:
+ case R_PPN15W:
+ case R_PPN15H:
+ /* Offset the address so that we can use 4 byte relocations. */
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents + 2, addr, val, addend);
+ break;
+
+ case R_PP16B:
+ case R_PPN16B:
+ {
+ /* The most significant bit is stored in bit 6. */
+ bfd_byte hold;
+
+ hold = contents[addr + 4];
+ contents[addr + 4] &=~ 0x20;
+ contents[addr + 4] |= (contents[addr] >> 1) & 0x20;
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents + 2, addr,
+ val, addend);
+ contents[addr] &=~ 0x40;
+ contents[addr] |= (contents[addr + 4] << 1) & 0x40;
+ contents[addr + 4] &=~ 0x20;
+ contents[addr + 4] |= hold & 0x20;
+ break;
+ }
+
+ case R_PPL16B:
+ case R_PPLN16B:
+ {
+ /* The most significant bit is stored in bit 28. */
+ bfd_byte hold;
+
+ hold = contents[addr + 1];
+ contents[addr + 1] &=~ 0x80;
+ contents[addr + 1] |= (contents[addr + 3] << 3) & 0x80;
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, addr,
+ val, addend);
+ contents[addr + 3] &= ~0x10;
+ contents[addr + 3] |= (contents[addr + 1] >> 3) & 0x10;
+ contents[addr + 1] &=~ 0x80;
+ contents[addr + 1] |= hold & 0x80;
+ break;
+ }
+
+ case R_PPBASE:
+ /* Parameter RAM is from 0x1000000 to 0x1000800. */
+ contents[addr] &=~ 0x3;
+ if (val >= 0x1000000 && val < 0x1000800)
+ contents[addr] |= 0x3;
+ else
+ contents[addr] |= 0x2;
+ rstat = bfd_reloc_ok;
+ break;
+
+ case R_PPLBASE:
+ /* Parameter RAM is from 0x1000000 to 0x1000800. */
+ contents[addr + 2] &= ~0xc0;
+ if (val >= 0x1000000 && val < 0x1000800)
+ contents[addr + 2] |= 0xc0;
+ else
+ contents[addr + 2] |= 0x80;
+ rstat = bfd_reloc_ok;
+ break;
+ }
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_outofrange:
+ (*_bfd_error_handler)
+ (_("%s: bad reloc address 0x%lx in section `%s'"),
+ bfd_get_filename (input_bfd),
+ (unsigned long) rel->r_vaddr,
+ bfd_get_section_name (input_bfd, input_section));
+ return false;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return false;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+#define TIC80COFF 1 /* Customize coffcode.h */
+#undef C_AUTOARG /* Clashes with TIc80's C_UEXT */
+#undef C_LASTENT /* Clashes with TIc80's C_STATLAB */
+#include "coffcode.h"
+
+const bfd_target
+ tic80coff_vec =
+{
+ "coff-tic80", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little (arch supports both) */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE
+ };
diff --git a/bfd/coff-u68k.c b/bfd/coff-u68k.c
new file mode 100644
index 00000000000..97ea73fa9c6
--- /dev/null
+++ b/bfd/coff-u68k.c
@@ -0,0 +1,35 @@
+/* BFD back-end for Motorola 68000 COFF binaries having underscore with name.
+ Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_SYM m68kcoffun_vec
+#define TARGET_NAME "coff-m68k-un"
+
+#define NAMES_HAVE_UNDERSCORE
+
+/* define this to not have multiple copy of m68k_rtype2howto
+ in the executable file */
+#define ONLY_DECLARE_RELOCS
+
+/* This magic number indicates that the names have underscores.
+ Other 68k magic numbers indicate that the names do not have
+ underscores. */
+#define BADMAG(x) ((x).f_magic != MC68KBCSMAGIC)
+
+#include "coff-m68k.c"
diff --git a/bfd/coff-w65.c b/bfd/coff-w65.c
new file mode 100644
index 00000000000..28d68c37998
--- /dev/null
+++ b/bfd/coff-w65.c
@@ -0,0 +1,445 @@
+/* BFD back-end for WDC 65816 COFF binaries.
+ Copyright 1995, 96, 1997 Free Software Foundation, Inc.
+ Written by Steve Chamberlain, <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/w65.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
+static reloc_howto_type howto_table[] =
+{
+ HOWTO (R_W65_ABS8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "abs8", true, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_W65_ABS16, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_W65_ABS24, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs24", true, 0x00ffffff, 0x00ffffff, false),
+ HOWTO (R_W65_ABS8S8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, ">abs8", true, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_W65_ABS8S16, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "^abs8", true, 0x000000ff, 0x000000ff, false),
+ HOWTO (R_W65_ABS16S8, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, ">abs16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_W65_ABS16S16,1, 0, 16, false, 0, complain_overflow_bitfield, 0, "^abs16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_W65_PCR8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "pcrel8", true, 0x000000ff, 0x000000ff, true),
+ HOWTO (R_W65_PCR16, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, true),
+ HOWTO (R_W65_DP, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "dp", true, 0x000000ff, 0x000000ff, false),
+
+};
+
+
+/* Turn a howto into a reloc number */
+
+#define SELECT_RELOC(x,howto) \
+ { x.r_type = select_reloc(howto); }
+
+#define BADMAG(x) (W65BADMAG(x))
+#define W65 1 /* Customize coffcode.h */
+#define __A_MAGIC_SET__
+
+
+/* Code to swap in the reloc */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
+ dst->r_stuff[0] = 'S'; \
+ dst->r_stuff[1] = 'C';
+
+
+static int
+select_reloc (howto)
+ reloc_howto_type *howto;
+{
+ return howto->type ;
+}
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table
+ */
+
+static void
+rtype2howto (internal, dst)
+ arelent *internal;
+ struct internal_reloc *dst;
+{
+ internal->howto = howto_table + dst->r_type - 1;
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+
+
+/* Perform any necessary magic to the addend in a reloc entry */
+
+
+#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
+ cache_ptr->addend = ext_reloc.r_offset;
+
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (relent, reloc, symbols, abfd, section)
+ arelent * relent;
+ struct internal_reloc *reloc;
+ asymbol ** symbols;
+ bfd * abfd;
+ asection * section;
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (((int) reloc->r_symndx) > 0)
+ {
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ }
+ else
+ {
+ relent->sym_ptr_ptr = (asymbol **)&(bfd_abs_symbol);
+ }
+
+
+
+ relent->addend = reloc->r_offset;
+
+ relent->address -= section->vma;
+ /* relent->section = 0;*/
+}
+
+
+static int
+h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info)
+ bfd *abfd;
+ asection *input_section;
+ arelent *reloc;
+ unsigned int shrink;
+ struct bfd_link_info *link_info;
+{
+ bfd_vma value;
+ bfd_vma dot;
+ bfd_vma gap;
+
+ /* The address of the thing to be relocated will have moved back by
+ the size of the shrink - but we don't change reloc->address here,
+ since we need it to know where the relocation lives in the source
+ uncooked section */
+
+ /* reloc->address -= shrink; conceptual */
+
+ bfd_vma address = reloc->address - shrink;
+
+
+ switch (reloc->howto->type)
+ {
+ case R_MOV16B2:
+ case R_JMP2:
+ shrink+=2;
+ break;
+
+ /* Thing is a move one byte */
+ case R_MOV16B1:
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ if (value >= 0xff00)
+ {
+
+ /* Change the reloc type from 16bit, possible 8 to 8bit
+ possible 16 */
+ reloc->howto = reloc->howto + 1;
+ /* The place to relc moves back by one */
+ /* This will be two bytes smaller in the long run */
+ shrink +=2 ;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+
+ break;
+ /* This is the 24 bit branch which could become an 8 bitter,
+ the relocation points to the first byte of the insn, not the
+ actual data */
+
+ case R_JMPL1:
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ dot = input_section->output_section->vma +
+ input_section->output_offset + address;
+
+ /* See if the address we're looking at within 127 bytes of where
+ we are, if so then we can use a small branch rather than the
+ jump we were going to */
+
+ gap = value - dot ;
+
+ if (-120 < (long)gap && (long)gap < 120 )
+ {
+
+ /* Change the reloc type from 24bit, possible 8 to 8bit
+ possible 32 */
+ reloc->howto = reloc->howto + 1;
+ /* This will be two bytes smaller in the long run */
+ shrink +=2 ;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+ break;
+
+ case R_JMP1:
+
+ value = bfd_coff_reloc16_get_value(reloc, link_info, input_section);
+
+ dot = input_section->output_section->vma +
+ input_section->output_offset + address;
+
+ /* See if the address we're looking at within 127 bytes of where
+ we are, if so then we can use a small branch rather than the
+ jump we were going to */
+
+ gap = value - (dot - shrink);
+
+
+ if (-120 < (long)gap && (long)gap < 120 )
+ {
+
+ /* Change the reloc type from 16bit, possible 8 to 8bit
+ possible 16 */
+ reloc->howto = reloc->howto + 1;
+ /* The place to relc moves back by one */
+
+ /* This will be two bytes smaller in the long run */
+ shrink +=2 ;
+ bfd_perform_slip(abfd, 2, input_section, address);
+ }
+ break;
+ }
+
+
+ return shrink;
+}
+
+
+/* First phase of a relaxing link */
+
+/* Reloc types
+ large small
+ R_MOV16B1 R_MOV16B2 mov.b with 16bit or 8 bit address
+ R_JMP1 R_JMP2 jmp or pcrel branch
+ R_JMPL1 R_JMPL_B8 24jmp or pcrel branch
+ R_MOV24B1 R_MOV24B2 24 or 8 bit reloc for mov.b
+
+*/
+
+static void
+h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
+ dst_ptr)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ arelent *reloc;
+ bfd_byte *data;
+ unsigned int *src_ptr;
+ unsigned int *dst_ptr;
+{
+ unsigned int src_address = *src_ptr;
+ unsigned int dst_address = *dst_ptr;
+ asection *input_section = link_order->u.indirect.section;
+
+ switch (reloc->howto->type)
+ {
+ case R_W65_ABS8:
+ case R_W65_DP:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_put_8 (abfd, gap, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ break;
+
+ case R_W65_ABS8S8:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ gap >>= 8;
+ bfd_put_8 (abfd, gap, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ break;
+
+ case R_W65_ABS8S16:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ gap >>=16;
+ bfd_put_8 (abfd, gap, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ break;
+
+ case R_W65_ABS16:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+
+ bfd_put_16 (abfd, gap, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+ }
+ break;
+ case R_W65_ABS16S8:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ gap >>= 8;
+ bfd_put_16 (abfd, gap, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+ }
+ break;
+ case R_W65_ABS16S16:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ gap >>= 16;
+ bfd_put_16 (abfd, gap, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+ }
+ break;
+
+ case R_W65_ABS24:
+ {
+ unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_put_16 (abfd, gap, data + dst_address);
+ bfd_put_8 (abfd, gap>>16, data+dst_address+2);
+ dst_address += 3;
+ src_address += 3;
+ }
+ break;
+
+ case R_W65_PCR8:
+ {
+ int gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma;
+
+ gap -= dot + 1;
+ if (gap < -128 || gap > 127) {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort();
+ }
+ bfd_put_8 (abfd, gap, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ break;
+
+ case R_W65_PCR16:
+ {
+ bfd_vma gap = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = link_order->offset
+ + dst_address
+ + link_order->u.indirect.section->output_section->vma;
+
+
+ /* This wraps within the page, so ignore the relativeness, look at the
+ high part */
+ if ((gap & 0xf0000) != (dot & 0xf0000)) {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort();
+ }
+
+ gap -= dot + 2;
+ bfd_put_16 (abfd, gap, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+ }
+ break;
+ default:
+ printf(_("ignoring reloc %s\n"), reloc->howto->name);
+ break;
+
+ }
+ *src_ptr = src_address;
+ *dst_ptr = dst_address;
+
+}
+
+#define coff_reloc16_extra_cases h8300_reloc16_extra_cases
+#define coff_reloc16_estimate h8300_reloc16_estimate
+
+#include "coffcode.h"
+
+
+#undef coff_bfd_get_relocated_section_contents
+#undef coff_bfd_relax_section
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+
+
+bfd_target w65_vec =
+{
+ "coff-w65", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-we32k.c b/bfd/coff-we32k.c
new file mode 100644
index 00000000000..826bbe330db
--- /dev/null
+++ b/bfd/coff-we32k.c
@@ -0,0 +1,109 @@
+/* BFD back-end for we32k COFF files.
+ Copyright (C) 1992, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Contributed by Brendan Kehoe (brendan@cs.widener.edu).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/we32k.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+static reloc_howto_type howto_table[] =
+{
+ {0},
+ {1},
+ {2},
+ {3},
+ {4},
+ {5},
+ HOWTO(R_DIR32, 0, 2, 32, false, 0,complain_overflow_bitfield, 0, "dir32", true, 0xffffffff,0xffffffff, false),
+ {7},
+ {010},
+ {011},
+ {012},
+ {013},
+ {014},
+ {015},
+ {016},
+ HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff,0x000000ff, false),
+ HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff,0xffffffff, false),
+ HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff,0x000000ff, false),
+ HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff,0xffffffff, false),
+};
+
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define BADMAG(x) WE32KBADMAG(x)
+#define WE32K 1
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = howto_table + (dst)->r_type;
+
+#include "coffcode.h"
+
+#define coff_write_armap bsd_write_armap
+
+const bfd_target we32kcoff_vec =
+{
+ "coff-we32k", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coff-z8k.c b/bfd/coff-z8k.c
new file mode 100644
index 00000000000..04049e89c28
--- /dev/null
+++ b/bfd/coff-z8k.c
@@ -0,0 +1,280 @@
+/* BFD back-end for Zilog Z800n COFF binaries.
+ Copyright 1992, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Written by Steve Chamberlain, <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/z8k.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1)
+
+static reloc_howto_type r_imm32 =
+HOWTO (R_IMM32, 0, 1, 32, false, 0,
+ complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff,
+ 0xffffffff, false);
+
+static reloc_howto_type r_imm4l =
+HOWTO (R_IMM4L, 0, 1, 4, false, 0,
+ complain_overflow_bitfield, 0, "r_imm4l", true, 0xf, 0xf, false);
+
+static reloc_howto_type r_da =
+HOWTO (R_IMM16, 0, 1, 16, false, 0,
+ complain_overflow_bitfield, 0, "r_da", true, 0x0000ffff, 0x0000ffff,
+ false);
+
+static reloc_howto_type r_imm8 =
+HOWTO (R_IMM8, 0, 1, 8, false, 0,
+ complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff,
+ false);
+
+static reloc_howto_type r_jr =
+HOWTO (R_JR, 0, 1, 8, true, 0, complain_overflow_signed, 0,
+ "r_jr", true, 0, 0, true);
+
+/* Turn a howto into a reloc number */
+
+static int
+coff_z8k_select_reloc (howto)
+ reloc_howto_type *howto;
+{
+ return howto->type;
+}
+
+#define SELECT_RELOC(x,howto) x.r_type = coff_z8k_select_reloc(howto)
+
+
+#define BADMAG(x) Z8KBADMAG(x)
+#define Z8K 1 /* Customize coffcode.h */
+#define __A_MAGIC_SET__
+
+
+
+/* Code to swap in the reloc */
+#define SWAP_IN_RELOC_OFFSET bfd_h_get_32
+#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32
+#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
+ dst->r_stuff[0] = 'S'; \
+ dst->r_stuff[1] = 'C';
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table
+ */
+
+static void
+rtype2howto (internal, dst)
+ arelent * internal;
+ struct internal_reloc *dst;
+{
+ switch (dst->r_type)
+ {
+ default:
+ abort ();
+ break;
+ case R_IMM8:
+ internal->howto = &r_imm8;
+ break;
+ case R_IMM16:
+ internal->howto = &r_da;
+ break;
+ case R_JR:
+ internal->howto = &r_jr;
+ break;
+ case R_IMM32:
+ internal->howto = &r_imm32;
+ break;
+ case R_IMM4L:
+ internal->howto = &r_imm4l;
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
+
+
+/* Perform any necessary magic to the addend in a reloc entry */
+
+
+#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
+ cache_ptr->addend = ext_reloc.r_offset;
+
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (relent, reloc, symbols, abfd, section)
+ arelent * relent;
+ struct internal_reloc *reloc;
+ asymbol ** symbols;
+ bfd * abfd;
+ asection * section;
+{
+ relent->address = reloc->r_vaddr;
+ rtype2howto (relent, reloc);
+
+ if (reloc->r_symndx > 0)
+ {
+ relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
+ }
+ else
+ {
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+
+
+ relent->addend = reloc->r_offset;
+ relent->address -= section->vma;
+}
+
+static void
+extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)
+ bfd *in_abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ arelent *reloc;
+ bfd_byte *data;
+ unsigned int *src_ptr;
+ unsigned int *dst_ptr;
+{
+ asection *input_section = link_order->u.indirect.section;
+
+ switch (reloc->howto->type)
+ {
+ case R_IMM8:
+ bfd_put_8 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ data + *dst_ptr);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_IMM32:
+ bfd_put_32 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ data + *dst_ptr);
+ (*dst_ptr) += 4;
+ (*src_ptr) += 4;
+ break;
+
+ case R_IMM4L:
+ bfd_put_8 (in_abfd,
+ ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0)
+ | (0x0f
+ & bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section))),
+ data + *dst_ptr);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_IMM16:
+ bfd_put_16 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info, input_section),
+ data + *dst_ptr);
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+
+ case R_JR:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (link_order->offset
+ + *dst_ptr
+ + input_section->output_section->vma);
+ int gap = dst - dot - 1;/* -1 since were in the odd byte of the
+ word and the pc's been incremented */
+
+ if (gap & 1)
+ abort ();
+ gap /= 2;
+ if (gap > 128 || gap < -128)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ bfd_put_8 (in_abfd, gap, data + *dst_ptr);
+ (*dst_ptr)++;
+ (*src_ptr)++;
+ break;
+ }
+ default:
+ abort ();
+ }
+}
+
+#define coff_reloc16_extra_cases extra_case
+
+#include "coffcode.h"
+
+
+#undef coff_bfd_get_relocated_section_contents
+#undef coff_bfd_relax_section
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+const bfd_target z8kcoff_vec =
+{
+ "coff-z8k", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
+ bfd_false},
+ {bfd_false, coff_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ COFF_SWAP_TABLE,
+};
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
new file mode 100644
index 00000000000..383719c00c9
--- /dev/null
+++ b/bfd/coffcode.h
@@ -0,0 +1,4318 @@
+/* Support for the generic parts of most COFF variants, for BFD.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+Most of this hacked by Steve Chamberlain,
+ sac@cygnus.com
+*/
+/*
+
+SECTION
+ coff backends
+
+ BFD supports a number of different flavours of coff format.
+ The major differences between formats are the sizes and
+ alignments of fields in structures on disk, and the occasional
+ extra field.
+
+ Coff in all its varieties is implemented with a few common
+ files and a number of implementation specific files. For
+ example, The 88k bcs coff format is implemented in the file
+ @file{coff-m88k.c}. This file @code{#include}s
+ @file{coff/m88k.h} which defines the external structure of the
+ coff format for the 88k, and @file{coff/internal.h} which
+ defines the internal structure. @file{coff-m88k.c} also
+ defines the relocations used by the 88k format
+ @xref{Relocations}.
+
+ The Intel i960 processor version of coff is implemented in
+ @file{coff-i960.c}. This file has the same structure as
+ @file{coff-m88k.c}, except that it includes @file{coff/i960.h}
+ rather than @file{coff-m88k.h}.
+
+SUBSECTION
+ Porting to a new version of coff
+
+ The recommended method is to select from the existing
+ implementations the version of coff which is most like the one
+ you want to use. For example, we'll say that i386 coff is
+ the one you select, and that your coff flavour is called foo.
+ Copy @file{i386coff.c} to @file{foocoff.c}, copy
+ @file{../include/coff/i386.h} to @file{../include/coff/foo.h},
+ and add the lines to @file{targets.c} and @file{Makefile.in}
+ so that your new back end is used. Alter the shapes of the
+ structures in @file{../include/coff/foo.h} so that they match
+ what you need. You will probably also have to add
+ @code{#ifdef}s to the code in @file{coff/internal.h} and
+ @file{coffcode.h} if your version of coff is too wild.
+
+ You can verify that your new BFD backend works quite simply by
+ building @file{objdump} from the @file{binutils} directory,
+ and making sure that its version of what's going on and your
+ host system's idea (assuming it has the pretty standard coff
+ dump utility, usually called @code{att-dump} or just
+ @code{dump}) are the same. Then clean up your code, and send
+ what you've done to Cygnus. Then your stuff will be in the
+ next release, and you won't have to keep integrating it.
+
+SUBSECTION
+ How the coff backend works
+
+SUBSUBSECTION
+ File layout
+
+ The Coff backend is split into generic routines that are
+ applicable to any Coff target and routines that are specific
+ to a particular target. The target-specific routines are
+ further split into ones which are basically the same for all
+ Coff targets except that they use the external symbol format
+ or use different values for certain constants.
+
+ The generic routines are in @file{coffgen.c}. These routines
+ work for any Coff target. They use some hooks into the target
+ specific code; the hooks are in a @code{bfd_coff_backend_data}
+ structure, one of which exists for each target.
+
+ The essentially similar target-specific routines are in
+ @file{coffcode.h}. This header file includes executable C code.
+ The various Coff targets first include the appropriate Coff
+ header file, make any special defines that are needed, and
+ then include @file{coffcode.h}.
+
+ Some of the Coff targets then also have additional routines in
+ the target source file itself.
+
+ For example, @file{coff-i960.c} includes
+ @file{coff/internal.h} and @file{coff/i960.h}. It then
+ defines a few constants, such as @code{I960}, and includes
+ @file{coffcode.h}. Since the i960 has complex relocation
+ types, @file{coff-i960.c} also includes some code to
+ manipulate the i960 relocs. This code is not in
+ @file{coffcode.h} because it would not be used by any other
+ target.
+
+SUBSUBSECTION
+ Bit twiddling
+
+ Each flavour of coff supported in BFD has its own header file
+ describing the external layout of the structures. There is also
+ an internal description of the coff layout, in
+ @file{coff/internal.h}. A major function of the
+ coff backend is swapping the bytes and twiddling the bits to
+ translate the external form of the structures into the normal
+ internal form. This is all performed in the
+ @code{bfd_swap}_@i{thing}_@i{direction} routines. Some
+ elements are different sizes between different versions of
+ coff; it is the duty of the coff version specific include file
+ to override the definitions of various packing routines in
+ @file{coffcode.h}. E.g., the size of line number entry in coff is
+ sometimes 16 bits, and sometimes 32 bits. @code{#define}ing
+ @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the
+ correct one. No doubt, some day someone will find a version of
+ coff which has a varying field size not catered to at the
+ moment. To port BFD, that person will have to add more @code{#defines}.
+ Three of the bit twiddling routines are exported to
+ @code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in}
+ and @code{coff_swap_linno_in}. @code{GDB} reads the symbol
+ table on its own, but uses BFD to fix things up. More of the
+ bit twiddlers are exported for @code{gas};
+ @code{coff_swap_aux_out}, @code{coff_swap_sym_out},
+ @code{coff_swap_lineno_out}, @code{coff_swap_reloc_out},
+ @code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out},
+ @code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track
+ of all the symbol table and reloc drudgery itself, thereby
+ saving the internal BFD overhead, but uses BFD to swap things
+ on the way out, making cross ports much safer. Doing so also
+ allows BFD (and thus the linker) to use the same header files
+ as @code{gas}, which makes one avenue to disaster disappear.
+
+SUBSUBSECTION
+ Symbol reading
+
+ The simple canonical form for symbols used by BFD is not rich
+ enough to keep all the information available in a coff symbol
+ table. The back end gets around this problem by keeping the original
+ symbol table around, "behind the scenes".
+
+ When a symbol table is requested (through a call to
+ @code{bfd_canonicalize_symtab}), a request gets through to
+ @code{coff_get_normalized_symtab}. This reads the symbol table from
+ the coff file and swaps all the structures inside into the
+ internal form. It also fixes up all the pointers in the table
+ (represented in the file by offsets from the first symbol in
+ the table) into physical pointers to elements in the new
+ internal table. This involves some work since the meanings of
+ fields change depending upon context: a field that is a
+ pointer to another structure in the symbol table at one moment
+ may be the size in bytes of a structure at the next. Another
+ pass is made over the table. All symbols which mark file names
+ (<<C_FILE>> symbols) are modified so that the internal
+ string points to the value in the auxent (the real filename)
+ rather than the normal text associated with the symbol
+ (@code{".file"}).
+
+ At this time the symbol names are moved around. Coff stores
+ all symbols less than nine characters long physically
+ within the symbol table; longer strings are kept at the end of
+ the file in the string table. This pass moves all strings
+ into memory and replaces them with pointers to the strings.
+
+
+ The symbol table is massaged once again, this time to create
+ the canonical table used by the BFD application. Each symbol
+ is inspected in turn, and a decision made (using the
+ @code{sclass} field) about the various flags to set in the
+ @code{asymbol}. @xref{Symbols}. The generated canonical table
+ shares strings with the hidden internal symbol table.
+
+ Any linenumbers are read from the coff file too, and attached
+ to the symbols which own the functions the linenumbers belong to.
+
+SUBSUBSECTION
+ Symbol writing
+
+ Writing a symbol to a coff file which didn't come from a coff
+ file will lose any debugging information. The @code{asymbol}
+ structure remembers the BFD from which the symbol was taken, and on
+ output the back end makes sure that the same destination target as
+ source target is present.
+
+ When the symbols have come from a coff file then all the
+ debugging information is preserved.
+
+ Symbol tables are provided for writing to the back end in a
+ vector of pointers to pointers. This allows applications like
+ the linker to accumulate and output large symbol tables
+ without having to do too much byte copying.
+
+ This function runs through the provided symbol table and
+ patches each symbol marked as a file place holder
+ (@code{C_FILE}) to point to the next file place holder in the
+ list. It also marks each @code{offset} field in the list with
+ the offset from the first symbol of the current symbol.
+
+ Another function of this procedure is to turn the canonical
+ value form of BFD into the form used by coff. Internally, BFD
+ expects symbol values to be offsets from a section base; so a
+ symbol physically at 0x120, but in a section starting at
+ 0x100, would have the value 0x20. Coff expects symbols to
+ contain their final value, so symbols have their values
+ changed at this point to reflect their sum with their owning
+ section. This transformation uses the
+ <<output_section>> field of the @code{asymbol}'s
+ @code{asection} @xref{Sections}.
+
+ o <<coff_mangle_symbols>>
+
+ This routine runs though the provided symbol table and uses
+ the offsets generated by the previous pass and the pointers
+ generated when the symbol table was read in to create the
+ structured hierachy required by coff. It changes each pointer
+ to a symbol into the index into the symbol table of the asymbol.
+
+ o <<coff_write_symbols>>
+
+ This routine runs through the symbol table and patches up the
+ symbols from their internal form into the coff way, calls the
+ bit twiddlers, and writes out the table to the file.
+
+*/
+
+/*
+INTERNAL_DEFINITION
+ coff_symbol_type
+
+DESCRIPTION
+ The hidden information for an <<asymbol>> is described in a
+ <<combined_entry_type>>:
+
+CODE_FRAGMENT
+.
+.typedef struct coff_ptr_struct
+.{
+.
+. {* Remembers the offset from the first symbol in the file for
+. this symbol. Generated by coff_renumber_symbols. *}
+.unsigned int offset;
+.
+. {* Should the value of this symbol be renumbered. Used for
+. XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. *}
+.unsigned int fix_value : 1;
+.
+. {* Should the tag field of this symbol be renumbered.
+. Created by coff_pointerize_aux. *}
+.unsigned int fix_tag : 1;
+.
+. {* Should the endidx field of this symbol be renumbered.
+. Created by coff_pointerize_aux. *}
+.unsigned int fix_end : 1;
+.
+. {* Should the x_csect.x_scnlen field be renumbered.
+. Created by coff_pointerize_aux. *}
+.unsigned int fix_scnlen : 1;
+.
+. {* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the
+. index into the line number entries. Set by
+. coff_slurp_symbol_table. *}
+.unsigned int fix_line : 1;
+.
+. {* The container for the symbol structure as read and translated
+. from the file. *}
+.
+.union {
+. union internal_auxent auxent;
+. struct internal_syment syment;
+. } u;
+.} combined_entry_type;
+.
+.
+.{* Each canonical asymbol really looks like this: *}
+.
+.typedef struct coff_symbol_struct
+.{
+. {* The actual symbol which the rest of BFD works with *}
+.asymbol symbol;
+.
+. {* A pointer to the hidden information for this symbol *}
+.combined_entry_type *native;
+.
+. {* A pointer to the linenumber information for this symbol *}
+.struct lineno_cache_entry *lineno;
+.
+. {* Have the line numbers been relocated yet ? *}
+.boolean done_lineno;
+.} coff_symbol_type;
+
+
+*/
+
+#ifdef COFF_WITH_PE
+#include "peicode.h"
+#else
+#include "coffswap.h"
+#endif
+
+#define STRING_SIZE_SIZE (4)
+
+static long sec_to_styp_flags PARAMS ((const char *, flagword));
+static flagword styp_to_sec_flags PARAMS ((bfd *, PTR, const char *));
+static boolean coff_bad_format_hook PARAMS ((bfd *, PTR));
+static boolean coff_new_section_hook PARAMS ((bfd *, asection *));
+static boolean coff_set_arch_mach_hook PARAMS ((bfd *, PTR));
+static boolean coff_write_relocs PARAMS ((bfd *, int));
+static boolean coff_set_flags
+ PARAMS ((bfd *, unsigned int *, unsigned short *));
+static boolean coff_set_arch_mach
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+static boolean coff_compute_section_file_positions PARAMS ((bfd *));
+static boolean coff_write_object_contents PARAMS ((bfd *));
+static boolean coff_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static PTR buy_and_read PARAMS ((bfd *, file_ptr, int, size_t));
+static boolean coff_slurp_line_table PARAMS ((bfd *, asection *));
+static boolean coff_slurp_symbol_table PARAMS ((bfd *));
+static boolean coff_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **));
+static long coff_canonicalize_reloc
+ PARAMS ((bfd *, asection *, arelent **, asymbol **));
+#ifndef coff_mkobject_hook
+static PTR coff_mkobject_hook PARAMS ((bfd *, PTR, PTR));
+#endif
+
+/* void warning(); */
+
+/*
+ * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the
+ * incoming SEC_* flags. The inverse of this function is styp_to_sec_flags().
+ * NOTE: If you add to/change this routine, you should mirror the changes
+ * in styp_to_sec_flags().
+ */
+static long
+sec_to_styp_flags (sec_name, sec_flags)
+ CONST char *sec_name;
+ flagword sec_flags;
+{
+ long styp_flags = 0;
+
+ if (!strcmp (sec_name, _TEXT))
+ {
+ styp_flags = STYP_TEXT;
+ }
+ else if (!strcmp (sec_name, _DATA))
+ {
+ styp_flags = STYP_DATA;
+ }
+ else if (!strcmp (sec_name, _BSS))
+ {
+ styp_flags = STYP_BSS;
+#ifdef _COMMENT
+ }
+ else if (!strcmp (sec_name, _COMMENT))
+ {
+ styp_flags = STYP_INFO;
+#endif /* _COMMENT */
+#ifdef _LIB
+ }
+ else if (!strcmp (sec_name, _LIB))
+ {
+ styp_flags = STYP_LIB;
+#endif /* _LIB */
+#ifdef _LIT
+ }
+ else if (!strcmp (sec_name, _LIT))
+ {
+ styp_flags = STYP_LIT;
+#endif /* _LIT */
+ }
+ else if (!strcmp (sec_name, ".debug"))
+ {
+#ifdef STYP_DEBUG
+ styp_flags = STYP_DEBUG;
+#else
+ styp_flags = STYP_INFO;
+#endif
+ }
+ else if (!strncmp (sec_name, ".stab", 5))
+ {
+ styp_flags = STYP_INFO;
+ }
+#ifdef COFF_WITH_PE
+ else if (!strcmp (sec_name, ".edata"))
+ {
+ styp_flags = STYP_DATA;
+ }
+#endif
+#ifdef RS6000COFF_C
+ else if (!strcmp (sec_name, _PAD))
+ {
+ styp_flags = STYP_PAD;
+ }
+ else if (!strcmp (sec_name, _LOADER))
+ {
+ styp_flags = STYP_LOADER;
+ }
+#endif
+ /* Try and figure out what it should be */
+ else if (sec_flags & SEC_CODE)
+ {
+ styp_flags = STYP_TEXT;
+ }
+ else if (sec_flags & SEC_DATA)
+ {
+ styp_flags = STYP_DATA;
+ }
+ else if (sec_flags & SEC_READONLY)
+ {
+#ifdef STYP_LIT /* 29k readonly text/data section */
+ styp_flags = STYP_LIT;
+#else
+ styp_flags = STYP_TEXT;
+#endif /* STYP_LIT */
+ }
+ else if (sec_flags & SEC_LOAD)
+ {
+ styp_flags = STYP_TEXT;
+ }
+ else if (sec_flags & SEC_ALLOC)
+ {
+ styp_flags = STYP_BSS;
+ }
+
+#ifdef STYP_NOLOAD
+ if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0)
+ styp_flags |= STYP_NOLOAD;
+#endif
+
+#ifdef COFF_WITH_PE
+ if (sec_flags & SEC_LINK_ONCE)
+ styp_flags |= IMAGE_SCN_LNK_COMDAT;
+#endif
+
+ return (styp_flags);
+}
+/*
+ * Return a word with SEC_* flags set to represent the incoming
+ * STYP_* flags (from scnhdr.s_flags). The inverse of this
+ * function is sec_to_styp_flags().
+ * NOTE: If you add to/change this routine, you should mirror the changes
+ * in sec_to_styp_flags().
+ */
+static flagword
+styp_to_sec_flags (abfd, hdr, name)
+ bfd *abfd;
+ PTR hdr;
+ const char *name;
+{
+ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+ long styp_flags = internal_s->s_flags;
+ flagword sec_flags = 0;
+
+#ifdef STYP_NOLOAD
+ if (styp_flags & STYP_NOLOAD)
+ {
+ sec_flags |= SEC_NEVER_LOAD;
+ }
+#endif /* STYP_NOLOAD */
+
+ /* For 386 COFF, at least, an unloadable text or data section is
+ actually a shared library section. */
+ if (styp_flags & STYP_TEXT)
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
+ }
+ else if (styp_flags & STYP_DATA)
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
+ }
+ else if (styp_flags & STYP_BSS)
+ {
+#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY;
+ else
+#endif
+ sec_flags |= SEC_ALLOC;
+ }
+ else if (styp_flags & STYP_INFO)
+ {
+ /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is
+ defined. coff_compute_section_file_positions uses
+ COFF_PAGE_SIZE to ensure that the low order bits of the
+ section VMA and the file offset match. If we don't know
+ COFF_PAGE_SIZE, we can't ensure the correct correspondence,
+ and demand page loading of the file will fail. */
+#if defined (COFF_PAGE_SIZE) && !defined (COFF_ALIGN_IN_S_FLAGS)
+ sec_flags |= SEC_DEBUGGING;
+#endif
+ }
+ else if (styp_flags & STYP_PAD)
+ {
+ sec_flags = 0;
+ }
+ else if (strcmp (name, _TEXT) == 0)
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
+ }
+ else if (strcmp (name, _DATA) == 0)
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
+ }
+ else if (strcmp (name, _BSS) == 0)
+ {
+#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY;
+ else
+#endif
+ sec_flags |= SEC_ALLOC;
+ }
+ else if (strcmp (name, ".debug") == 0
+#ifdef _COMMENT
+ || strcmp (name, _COMMENT) == 0
+#endif
+ || strncmp (name, ".stab", 5) == 0)
+ {
+#ifdef COFF_PAGE_SIZE
+ sec_flags |= SEC_DEBUGGING;
+#endif
+ }
+#ifdef _LIB
+ else if (strcmp (name, _LIB) == 0)
+ ;
+#endif
+#ifdef _LIT
+ else if (strcmp (name, _LIT) == 0)
+ {
+ sec_flags = SEC_LOAD | SEC_ALLOC | SEC_READONLY;
+ }
+#endif
+ else
+ {
+ sec_flags |= SEC_ALLOC | SEC_LOAD;
+ }
+
+#ifdef STYP_LIT /* A29k readonly text/data section type */
+ if ((styp_flags & STYP_LIT) == STYP_LIT)
+ {
+ sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY);
+ }
+#endif /* STYP_LIT */
+#ifdef STYP_OTHER_LOAD /* Other loaded sections */
+ if (styp_flags & STYP_OTHER_LOAD)
+ {
+ sec_flags = (SEC_LOAD | SEC_ALLOC);
+ }
+#endif /* STYP_SDATA */
+
+#ifdef COFF_WITH_PE
+ if (styp_flags & IMAGE_SCN_LNK_REMOVE)
+ sec_flags |= SEC_EXCLUDE;
+
+ if (styp_flags & IMAGE_SCN_LNK_COMDAT)
+ {
+ sec_flags |= SEC_LINK_ONCE;
+
+ /* Unfortunately, the PE format stores essential information in
+ the symbol table, of all places. We need to extract that
+ information now, so that objdump and the linker will know how
+ to handle the section without worrying about the symbols. We
+ can't call slurp_symtab, because the linker doesn't want the
+ swapped symbols. */
+
+ if (_bfd_coff_get_external_symbols (abfd))
+ {
+ bfd_byte *esym, *esymend;
+
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esymend = esym + obj_raw_syment_count (abfd) * SYMESZ;
+
+ while (esym < esymend)
+ {
+ struct internal_syment isym;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
+
+ if (sizeof (internal_s->s_name) > SYMNMLEN)
+ {
+ /* This case implies that the matching symbol name
+ will be in the string table. */
+ abort ();
+ }
+
+ if (isym.n_sclass == C_STAT
+ && isym.n_type == T_NULL
+ && isym.n_numaux == 1)
+ {
+ char buf[SYMNMLEN + 1];
+ const char *symname;
+
+ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
+ if (symname == NULL)
+ abort ();
+
+ if (strcmp (name, symname) == 0)
+ {
+ union internal_auxent aux;
+
+ /* This is the section symbol. */
+
+ bfd_coff_swap_aux_in (abfd, (PTR) (esym + SYMESZ),
+ isym.n_type, isym.n_sclass,
+ 0, isym.n_numaux, (PTR) &aux);
+
+ switch (aux.x_scn.x_comdat)
+ {
+ case IMAGE_COMDAT_SELECT_NODUPLICATES:
+ sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+ break;
+
+ default:
+ case IMAGE_COMDAT_SELECT_ANY:
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+
+ case IMAGE_COMDAT_SELECT_SAME_SIZE:
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+ break;
+
+ case IMAGE_COMDAT_SELECT_EXACT_MATCH:
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+
+ case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+ /* FIXME: This is not currently implemented. */
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ }
+
+ break;
+ }
+ }
+
+ esym += (isym.n_numaux + 1) * SYMESZ;
+ }
+ }
+ }
+#endif
+
+ return (sec_flags);
+}
+
+#define get_index(symbol) ((symbol)->udata.i)
+
+/*
+INTERNAL_DEFINITION
+ bfd_coff_backend_data
+
+CODE_FRAGMENT
+
+Special entry points for gdb to swap in coff symbol table parts:
+.typedef struct
+.{
+. void (*_bfd_coff_swap_aux_in) PARAMS ((
+. bfd *abfd,
+. PTR ext,
+. int type,
+. int class,
+. int indaux,
+. int numaux,
+. PTR in));
+.
+. void (*_bfd_coff_swap_sym_in) PARAMS ((
+. bfd *abfd ,
+. PTR ext,
+. PTR in));
+.
+. void (*_bfd_coff_swap_lineno_in) PARAMS ((
+. bfd *abfd,
+. PTR ext,
+. PTR in));
+.
+
+Special entry points for gas to swap out coff parts:
+
+. unsigned int (*_bfd_coff_swap_aux_out) PARAMS ((
+. bfd *abfd,
+. PTR in,
+. int type,
+. int class,
+. int indaux,
+. int numaux,
+. PTR ext));
+.
+. unsigned int (*_bfd_coff_swap_sym_out) PARAMS ((
+. bfd *abfd,
+. PTR in,
+. PTR ext));
+.
+. unsigned int (*_bfd_coff_swap_lineno_out) PARAMS ((
+. bfd *abfd,
+. PTR in,
+. PTR ext));
+.
+. unsigned int (*_bfd_coff_swap_reloc_out) PARAMS ((
+. bfd *abfd,
+. PTR src,
+. PTR dst));
+.
+. unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS ((
+. bfd *abfd,
+. PTR in,
+. PTR out));
+.
+. unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS ((
+. bfd *abfd,
+. PTR in,
+. PTR out));
+.
+. unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS ((
+. bfd *abfd,
+. PTR in,
+. PTR out));
+.
+
+Special entry points for generic COFF routines to call target
+dependent COFF routines:
+
+. unsigned int _bfd_filhsz;
+. unsigned int _bfd_aoutsz;
+. unsigned int _bfd_scnhsz;
+. unsigned int _bfd_symesz;
+. unsigned int _bfd_auxesz;
+. unsigned int _bfd_relsz;
+. unsigned int _bfd_linesz;
+. boolean _bfd_coff_long_filenames;
+. boolean _bfd_coff_long_section_names;
+. unsigned int _bfd_coff_default_section_alignment_power;
+. void (*_bfd_coff_swap_filehdr_in) PARAMS ((
+. bfd *abfd,
+. PTR ext,
+. PTR in));
+. void (*_bfd_coff_swap_aouthdr_in) PARAMS ((
+. bfd *abfd,
+. PTR ext,
+. PTR in));
+. void (*_bfd_coff_swap_scnhdr_in) PARAMS ((
+. bfd *abfd,
+. PTR ext,
+. PTR in));
+. void (*_bfd_coff_swap_reloc_in) PARAMS ((
+. bfd *abfd,
+. PTR ext,
+. PTR in));
+. boolean (*_bfd_coff_bad_format_hook) PARAMS ((
+. bfd *abfd,
+. PTR internal_filehdr));
+. boolean (*_bfd_coff_set_arch_mach_hook) PARAMS ((
+. bfd *abfd,
+. PTR internal_filehdr));
+. PTR (*_bfd_coff_mkobject_hook) PARAMS ((
+. bfd *abfd,
+. PTR internal_filehdr,
+. PTR internal_aouthdr));
+. flagword (*_bfd_styp_to_sec_flags_hook) PARAMS ((
+. bfd *abfd,
+. PTR internal_scnhdr,
+. const char *name));
+. void (*_bfd_set_alignment_hook) PARAMS ((
+. bfd *abfd,
+. asection *sec,
+. PTR internal_scnhdr));
+. boolean (*_bfd_coff_slurp_symbol_table) PARAMS ((
+. bfd *abfd));
+. boolean (*_bfd_coff_symname_in_debug) PARAMS ((
+. bfd *abfd,
+. struct internal_syment *sym));
+. boolean (*_bfd_coff_pointerize_aux_hook) PARAMS ((
+. bfd *abfd,
+. combined_entry_type *table_base,
+. combined_entry_type *symbol,
+. unsigned int indaux,
+. combined_entry_type *aux));
+. boolean (*_bfd_coff_print_aux) PARAMS ((
+. bfd *abfd,
+. FILE *file,
+. combined_entry_type *table_base,
+. combined_entry_type *symbol,
+. combined_entry_type *aux,
+. unsigned int indaux));
+. void (*_bfd_coff_reloc16_extra_cases) PARAMS ((
+. bfd *abfd,
+. struct bfd_link_info *link_info,
+. struct bfd_link_order *link_order,
+. arelent *reloc,
+. bfd_byte *data,
+. unsigned int *src_ptr,
+. unsigned int *dst_ptr));
+. int (*_bfd_coff_reloc16_estimate) PARAMS ((
+. bfd *abfd,
+. asection *input_section,
+. arelent *r,
+. unsigned int shrink,
+. struct bfd_link_info *link_info));
+. boolean (*_bfd_coff_sym_is_global) PARAMS ((
+. bfd *abfd,
+. struct internal_syment *));
+. boolean (*_bfd_coff_compute_section_file_positions) PARAMS ((
+. bfd *abfd));
+. boolean (*_bfd_coff_start_final_link) PARAMS ((
+. bfd *output_bfd,
+. struct bfd_link_info *info));
+. boolean (*_bfd_coff_relocate_section) PARAMS ((
+. bfd *output_bfd,
+. struct bfd_link_info *info,
+. bfd *input_bfd,
+. asection *input_section,
+. bfd_byte *contents,
+. struct internal_reloc *relocs,
+. struct internal_syment *syms,
+. asection **sections));
+. reloc_howto_type *(*_bfd_coff_rtype_to_howto) PARAMS ((
+. bfd *abfd,
+. asection *sec,
+. struct internal_reloc *rel,
+. struct coff_link_hash_entry *h,
+. struct internal_syment *sym,
+. bfd_vma *addendp));
+. boolean (*_bfd_coff_adjust_symndx) PARAMS ((
+. bfd *obfd,
+. struct bfd_link_info *info,
+. bfd *ibfd,
+. asection *sec,
+. struct internal_reloc *reloc,
+. boolean *adjustedp));
+. boolean (*_bfd_coff_link_add_one_symbol) PARAMS ((
+. struct bfd_link_info *info,
+. bfd *abfd,
+. const char *name,
+. flagword flags,
+. asection *section,
+. bfd_vma value,
+. const char *string,
+. boolean copy,
+. boolean collect,
+. struct bfd_link_hash_entry **hashp));
+.
+. boolean (*_bfd_coff_link_output_has_begun) PARAMS ((
+. bfd * abfd,
+. struct coff_final_link_info * pfinfo));
+. boolean (*_bfd_coff_final_link_postscript) PARAMS ((
+. bfd * abfd,
+. struct coff_final_link_info * pfinfo));
+.
+.} bfd_coff_backend_data;
+.
+.#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data)
+.
+.#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \
+. ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i))
+.
+.#define bfd_coff_swap_sym_in(a,e,i) \
+. ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))
+.
+.#define bfd_coff_swap_lineno_in(a,e,i) \
+. ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i))
+.
+.#define bfd_coff_swap_reloc_out(abfd, i, o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o))
+.
+.#define bfd_coff_swap_lineno_out(abfd, i, o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o))
+.
+.#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \
+. ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o))
+.
+.#define bfd_coff_swap_sym_out(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))
+.
+.#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o))
+.
+.#define bfd_coff_swap_filehdr_out(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o))
+.
+.#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o))
+.
+.#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz)
+.#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz)
+.#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz)
+.#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz)
+.#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz)
+.#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz)
+.#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz)
+.#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames)
+.#define bfd_coff_long_section_names(abfd) \
+. (coff_backend_info (abfd)->_bfd_coff_long_section_names)
+.#define bfd_coff_default_section_alignment_power(abfd) \
+. (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
+.#define bfd_coff_swap_filehdr_in(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o))
+.
+.#define bfd_coff_swap_aouthdr_in(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o))
+.
+.#define bfd_coff_swap_scnhdr_in(abfd, i,o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o))
+.
+.#define bfd_coff_swap_reloc_in(abfd, i, o) \
+. ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o))
+.
+.#define bfd_coff_bad_format_hook(abfd, filehdr) \
+. ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr))
+.
+.#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\
+. ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr))
+.#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\
+. ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr))
+.
+.#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name)\
+. ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr, name))
+.
+.#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\
+. ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr))
+.
+.#define bfd_coff_slurp_symbol_table(abfd)\
+. ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd))
+.
+.#define bfd_coff_symname_in_debug(abfd, sym)\
+. ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym))
+.
+.#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\
+. ((coff_backend_info (abfd)->_bfd_coff_print_aux)\
+. (abfd, file, base, symbol, aux, indaux))
+.
+.#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)\
+. ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
+. (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr))
+.
+.#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\
+. ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
+. (abfd, section, reloc, shrink, link_info))
+.
+.#define bfd_coff_sym_is_global(abfd, sym)\
+. ((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\
+. (abfd, sym))
+.
+.#define bfd_coff_compute_section_file_positions(abfd)\
+. ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\
+. (abfd))
+.
+.#define bfd_coff_start_final_link(obfd, info)\
+. ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\
+. (obfd, info))
+.#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\
+. ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\
+. (obfd, info, ibfd, o, con, rel, isyms, secs))
+.#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\
+. ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\
+. (abfd, sec, rel, h, sym, addendp))
+.#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
+. ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
+. (obfd, info, ibfd, sec, rel, adjustedp))
+.#define bfd_coff_link_add_one_symbol(info,abfd,name,flags,section,value,string,cp,coll,hashp)\
+. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
+. (info, abfd, name, flags, section, value, string, cp, coll, hashp))
+.
+.#define bfd_coff_link_output_has_begun(a,p) \
+. ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a,p))
+.#define bfd_coff_final_link_postscript(a,p) \
+. ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a,p))
+.
+*/
+
+/* See whether the magic number matches. */
+
+static boolean
+coff_bad_format_hook (abfd, filehdr)
+ bfd * abfd;
+ PTR filehdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ if (BADMAG (*internal_f))
+ return false;
+
+ /* if the optional header is NULL or not the correct size then
+ quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
+ and Intel 960 readwrite headers (I960WRMAGIC) is that the
+ optional header is of a different size.
+
+ But the mips keeps extra stuff in it's opthdr, so dont check
+ when doing that
+ */
+
+#if defined(M88) || defined(I960)
+ if (internal_f->f_opthdr != 0 && AOUTSZ != internal_f->f_opthdr)
+ return false;
+#endif
+
+ return true;
+}
+
+/*
+ initialize a section structure with information peculiar to this
+ particular implementation of coff
+*/
+
+static boolean
+coff_new_section_hook (abfd, section)
+ bfd * abfd;
+ asection * section;
+{
+ combined_entry_type *native;
+
+ section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
+
+#ifdef RS6000COFF_C
+ if (xcoff_data (abfd)->text_align_power != 0
+ && strcmp (bfd_get_section_name (abfd, section), ".text") == 0)
+ section->alignment_power = xcoff_data (abfd)->text_align_power;
+ if (xcoff_data (abfd)->data_align_power != 0
+ && strcmp (bfd_get_section_name (abfd, section), ".data") == 0)
+ section->alignment_power = xcoff_data (abfd)->data_align_power;
+#endif
+
+ /* Allocate aux records for section symbols, to store size and
+ related info.
+
+ @@ The 10 is a guess at a plausible maximum number of aux entries
+ (but shouldn't be a constant). */
+ native = ((combined_entry_type *)
+ bfd_zalloc (abfd, sizeof (combined_entry_type) * 10));
+ if (native == NULL)
+ return false;
+
+ /* We don't need to set up n_name, n_value, or n_scnum in the native
+ symbol information, since they'll be overriden by the BFD symbol
+ anyhow. However, we do need to set the type and storage class,
+ in case this symbol winds up getting written out. The value 0
+ for n_numaux is already correct. */
+
+ native->u.syment.n_type = T_NULL;
+ native->u.syment.n_sclass = C_STAT;
+
+ coffsymbol (section->symbol)->native = native;
+
+ /* The .stab section must be aligned to 2**2 at most, because
+ otherwise there may be gaps in the section which gdb will not
+ know how to interpret. Examining the section name is a hack, but
+ that is also how gdb locates the section.
+ We need to handle the .ctors and .dtors sections similarly, to
+ avoid introducing null words in the tables. */
+ if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 2
+ && (strncmp (section->name, ".stab", 5) == 0
+ || strcmp (section->name, ".ctors") == 0
+ || strcmp (section->name, ".dtors") == 0))
+ section->alignment_power = 2;
+
+ /* Similarly, the .stabstr section must be aligned to 2**0 at most. */
+ if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 0
+ && strncmp (section->name, ".stabstr", 8) == 0)
+ section->alignment_power = 0;
+
+ return true;
+}
+
+#ifdef COFF_ALIGN_IN_SECTION_HEADER
+
+/* Set the alignment of a BFD section. */
+
+static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR));
+
+static void
+coff_set_alignment_hook (abfd, section, scnhdr)
+ bfd * abfd;
+ asection * section;
+ PTR scnhdr;
+{
+ struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
+ unsigned int i;
+
+#ifdef I960
+ /* Extract ALIGN from 2**ALIGN stored in section header */
+ for (i = 0; i < 32; i++)
+ if ((1 << i) >= hdr->s_align)
+ break;
+#endif
+#ifdef TIC80COFF
+ /* TI tools hijack bits 8-11 for the alignment */
+ i = (hdr->s_flags >> 8) & 0xF ;
+#endif
+ section->alignment_power = i;
+}
+
+#else /* ! COFF_ALIGN_IN_SECTION_HEADER */
+#ifdef COFF_WITH_PE
+
+/* a couple of macros to help setting the alignment power field */
+#define ALIGN_SET(field,x,y) \
+ if (((field) & IMAGE_SCN_ALIGN_64BYTES) == x )\
+ {\
+ section->alignment_power = y;\
+ }
+
+#define ELIFALIGN_SET(field,x,y) \
+ else if (( (field) & IMAGE_SCN_ALIGN_64BYTES) == x ) \
+ {\
+ section->alignment_power = y;\
+ }
+
+static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR));
+
+static void
+coff_set_alignment_hook (abfd, section, scnhdr)
+ bfd * abfd;
+ asection * section;
+ PTR scnhdr;
+{
+ struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
+
+ ALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_64BYTES, 6)
+ ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_32BYTES, 5)
+ ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_16BYTES, 4)
+ ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_8BYTES, 3)
+ ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_4BYTES, 2)
+ ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_2BYTES, 1)
+ ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_1BYTES, 0)
+
+#ifdef POWERPC_LE_PE
+ if (strcmp (section->name, ".idata$2") == 0)
+ {
+ section->alignment_power = 0;
+ }
+ else if (strcmp (section->name, ".idata$3") == 0)
+ {
+ section->alignment_power = 0;
+ }
+ else if (strcmp (section->name, ".idata$4") == 0)
+ {
+ section->alignment_power = 2;
+ }
+ else if (strcmp (section->name, ".idata$5") == 0)
+ {
+ section->alignment_power = 2;
+ }
+ else if (strcmp (section->name, ".idata$6") == 0)
+ {
+ section->alignment_power = 1;
+ }
+ else if (strcmp (section->name, ".reloc") == 0)
+ {
+ section->alignment_power = 1;
+ }
+ else if (strncmp (section->name, ".stab", 5) == 0)
+ {
+ section->alignment_power = 2;
+ }
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* In a PE image file, the s_paddr field holds the virtual size of a
+ section, while the s_size field holds the raw size. */
+ if (hdr->s_paddr != 0)
+ {
+ if (coff_section_data (abfd, section) == NULL)
+ {
+ section->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata));
+ if (section->used_by_bfd == NULL)
+ {
+ /* FIXME: Return error. */
+ abort ();
+ }
+ }
+ if (pei_section_data (abfd, section) == NULL)
+ {
+ coff_section_data (abfd, section)->tdata =
+ (PTR) bfd_zalloc (abfd, sizeof (struct pei_section_tdata));
+ if (coff_section_data (abfd, section)->tdata == NULL)
+ {
+ /* FIXME: Return error. */
+ abort ();
+ }
+ }
+ pei_section_data (abfd, section)->virt_size = hdr->s_paddr;
+ }
+#endif
+
+}
+#undef ALIGN_SET
+#undef ELIFALIGN_SET
+
+#else /* ! COFF_WITH_PE */
+#ifdef RS6000COFF_C
+
+/* We grossly abuse this function to handle XCOFF overflow headers.
+ When we see one, we correct the reloc and line number counts in the
+ real header, and remove the section we just created. */
+
+static void coff_set_alignment_hook PARAMS ((bfd *, asection *, PTR));
+
+static void
+coff_set_alignment_hook (abfd, section, scnhdr)
+ bfd *abfd;
+ asection *section;
+ PTR scnhdr;
+{
+ struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
+ asection *real_sec;
+ asection **ps;
+
+ if ((hdr->s_flags & STYP_OVRFLO) == 0)
+ return;
+
+ real_sec = coff_section_from_bfd_index (abfd, hdr->s_nreloc);
+ if (real_sec == NULL)
+ return;
+
+ real_sec->reloc_count = hdr->s_paddr;
+ real_sec->lineno_count = hdr->s_vaddr;
+
+ for (ps = &abfd->sections; *ps != NULL; ps = &(*ps)->next)
+ {
+ if (*ps == section)
+ {
+ *ps = (*ps)->next;
+ --abfd->section_count;
+ break;
+ }
+ }
+}
+
+#else /* ! RS6000COFF_C */
+
+#define coff_set_alignment_hook \
+ ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
+
+#endif /* ! RS6000COFF_C */
+#endif /* ! COFF_WITH_PE */
+#endif /* ! COFF_ALIGN_IN_SECTION_HEADER */
+
+#ifndef coff_mkobject
+
+static boolean coff_mkobject PARAMS ((bfd *));
+
+static boolean
+coff_mkobject (abfd)
+ bfd * abfd;
+{
+ coff_data_type *coff;
+
+ abfd->tdata.coff_obj_data = (struct coff_tdata *) bfd_zalloc (abfd, sizeof (coff_data_type));
+ if (abfd->tdata.coff_obj_data == 0)
+ return false;
+ coff = coff_data (abfd);
+ coff->symbols = (coff_symbol_type *) NULL;
+ coff->conversion_table = (unsigned int *) NULL;
+ coff->raw_syments = (struct coff_ptr_struct *) NULL;
+ coff->relocbase = 0;
+ coff->local_toc_sym_map = 0;
+
+/* make_abs_section(abfd);*/
+
+ return true;
+}
+#endif
+
+/* Create the COFF backend specific information. */
+#ifndef coff_mkobject_hook
+static PTR
+coff_mkobject_hook (abfd, filehdr, aouthdr)
+ bfd * abfd;
+ PTR filehdr;
+ PTR aouthdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ coff_data_type *coff;
+
+ if (coff_mkobject (abfd) == false)
+ return NULL;
+
+ coff = coff_data (abfd);
+
+ coff->sym_filepos = internal_f->f_symptr;
+
+ /* These members communicate important constants about the symbol
+ table to GDB's symbol-reading code. These `constants'
+ unfortunately vary among coff implementations... */
+ coff->local_n_btmask = N_BTMASK;
+ coff->local_n_btshft = N_BTSHFT;
+ coff->local_n_tmask = N_TMASK;
+ coff->local_n_tshift = N_TSHIFT;
+ coff->local_symesz = SYMESZ;
+ coff->local_auxesz = AUXESZ;
+ coff->local_linesz = LINESZ;
+
+ obj_raw_syment_count (abfd) =
+ obj_conv_table_size (abfd) =
+ internal_f->f_nsyms;
+
+#ifdef RS6000COFF_C
+ if ((internal_f->f_flags & F_SHROBJ) != 0)
+ abfd->flags |= DYNAMIC;
+ if (aouthdr != NULL && internal_f->f_opthdr >= AOUTSZ)
+ {
+ struct internal_aouthdr *internal_a =
+ (struct internal_aouthdr *) aouthdr;
+ struct xcoff_tdata *xcoff;
+
+ xcoff = xcoff_data (abfd);
+ xcoff->full_aouthdr = true;
+ xcoff->toc = internal_a->o_toc;
+ xcoff->sntoc = internal_a->o_sntoc;
+ xcoff->snentry = internal_a->o_snentry;
+ xcoff->text_align_power = internal_a->o_algntext;
+ xcoff->data_align_power = internal_a->o_algndata;
+ xcoff->modtype = internal_a->o_modtype;
+ xcoff->cputype = internal_a->o_cputype;
+ xcoff->maxdata = internal_a->o_maxdata;
+ xcoff->maxstack = internal_a->o_maxstack;
+ }
+#endif
+
+#ifdef ARM
+ /* Set the flags field from the COFF header read in */
+ if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
+ coff->flags = 0;
+#endif
+
+ return (PTR) coff;
+}
+#endif
+
+/* Determine the machine architecture and type. FIXME: This is target
+ dependent because the magic numbers are defined in the target
+ dependent header files. But there is no particular need for this.
+ If the magic numbers were moved to a separate file, this function
+ would be target independent and would also be much more successful
+ at linking together COFF files for different architectures. */
+
+static boolean
+coff_set_arch_mach_hook (abfd, filehdr)
+ bfd *abfd;
+ PTR filehdr;
+{
+ long machine;
+ enum bfd_architecture arch;
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ machine = 0;
+ switch (internal_f->f_magic)
+ {
+#ifdef PPCMAGIC
+ case PPCMAGIC:
+ arch = bfd_arch_powerpc;
+ machine = 0; /* what does this mean? (krk) */
+ break;
+#endif
+#ifdef I386MAGIC
+ case I386MAGIC:
+ case I386PTXMAGIC:
+ case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler */
+ case LYNXCOFFMAGIC: /* shadows the m68k Lynx number below, sigh */
+ arch = bfd_arch_i386;
+ machine = 0;
+ break;
+#endif
+#ifdef A29K_MAGIC_BIG
+ case A29K_MAGIC_BIG:
+ case A29K_MAGIC_LITTLE:
+ arch = bfd_arch_a29k;
+ machine = 0;
+ break;
+#endif
+#ifdef ARMMAGIC
+ case ARMMAGIC:
+ arch = bfd_arch_arm;
+ switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK)
+ {
+ case F_ARM_2: machine = bfd_mach_arm_2; break;
+ case F_ARM_3: machine = bfd_mach_arm_3; break;
+ default:
+ case F_ARM_4: machine = bfd_mach_arm_4; break;
+ case F_ARM_4T: machine = bfd_mach_arm_4T; break;
+ }
+ break;
+#endif
+#ifdef MC68MAGIC
+ case MC68MAGIC:
+ case M68MAGIC:
+#ifdef MC68KBCSMAGIC
+ case MC68KBCSMAGIC:
+#endif
+#ifdef APOLLOM68KMAGIC
+ case APOLLOM68KMAGIC:
+#endif
+#ifdef LYNXCOFFMAGIC
+ case LYNXCOFFMAGIC:
+#endif
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68020;
+ break;
+#endif
+#ifdef MC88MAGIC
+ case MC88MAGIC:
+ case MC88DMAGIC:
+ case MC88OMAGIC:
+ arch = bfd_arch_m88k;
+ machine = 88100;
+ break;
+#endif
+#ifdef Z8KMAGIC
+ case Z8KMAGIC:
+ arch = bfd_arch_z8k;
+ switch (internal_f->f_flags & F_MACHMASK)
+ {
+ case F_Z8001:
+ machine = bfd_mach_z8001;
+ break;
+ case F_Z8002:
+ machine = bfd_mach_z8002;
+ break;
+ default:
+ return false;
+ }
+ break;
+#endif
+#ifdef I860
+ case I860MAGIC:
+ arch = bfd_arch_i860;
+ break;
+#endif
+#ifdef I960
+#ifdef I960ROMAGIC
+ case I960ROMAGIC:
+ case I960RWMAGIC:
+ arch = bfd_arch_i960;
+ switch (F_I960TYPE & internal_f->f_flags)
+ {
+ default:
+ case F_I960CORE:
+ machine = bfd_mach_i960_core;
+ break;
+ case F_I960KB:
+ machine = bfd_mach_i960_kb_sb;
+ break;
+ case F_I960MC:
+ machine = bfd_mach_i960_mc;
+ break;
+ case F_I960XA:
+ machine = bfd_mach_i960_xa;
+ break;
+ case F_I960CA:
+ machine = bfd_mach_i960_ca;
+ break;
+ case F_I960KA:
+ machine = bfd_mach_i960_ka_sa;
+ break;
+ case F_I960JX:
+ machine = bfd_mach_i960_jx;
+ break;
+ case F_I960HX:
+ machine = bfd_mach_i960_hx;
+ break;
+ }
+ break;
+#endif
+#endif
+
+#ifdef RS6000COFF_C
+ case U802ROMAGIC:
+ case U802WRMAGIC:
+ case U802TOCMAGIC:
+ {
+ int cputype;
+
+ if (xcoff_data (abfd)->cputype != -1)
+ cputype = xcoff_data (abfd)->cputype & 0xff;
+ else
+ {
+ /* We did not get a value from the a.out header. If the
+ file has not been stripped, we may be able to get the
+ architecture information from the first symbol, if it
+ is a .file symbol. */
+ if (obj_raw_syment_count (abfd) == 0)
+ cputype = 0;
+ else
+ {
+ bfd_byte buf[SYMESZ];
+ struct internal_syment sym;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_read (buf, 1, SYMESZ, abfd) != SYMESZ)
+ return false;
+ coff_swap_sym_in (abfd, (PTR) buf, (PTR) &sym);
+ if (sym.n_sclass == C_FILE)
+ cputype = sym.n_type & 0xff;
+ else
+ cputype = 0;
+ }
+ }
+
+ /* FIXME: We don't handle all cases here. */
+ switch (cputype)
+ {
+ default:
+ case 0:
+#ifdef POWERMAC
+ /* PowerPC Macs use the same magic numbers as RS/6000
+ (because that's how they were bootstrapped originally),
+ but they are always PowerPC architecture. */
+ arch = bfd_arch_powerpc;
+ machine = 0;
+#else
+ arch = bfd_arch_rs6000;
+ machine = 6000;
+#endif /* POWERMAC */
+ break;
+
+ case 1:
+ arch = bfd_arch_powerpc;
+ machine = 601;
+ break;
+ case 2: /* 64 bit PowerPC */
+ arch = bfd_arch_powerpc;
+ machine = 620;
+ break;
+ case 3:
+ arch = bfd_arch_powerpc;
+ machine = 0;
+ break;
+ case 4:
+ arch = bfd_arch_rs6000;
+ machine = 6000;
+ break;
+ }
+ }
+ break;
+#endif
+
+#ifdef WE32KMAGIC
+ case WE32KMAGIC:
+ arch = bfd_arch_we32k;
+ machine = 0;
+ break;
+#endif
+
+#ifdef H8300MAGIC
+ case H8300MAGIC:
+ arch = bfd_arch_h8300;
+ machine = bfd_mach_h8300;
+ /* !! FIXME this probably isn't the right place for this */
+ abfd->flags |= BFD_IS_RELAXABLE;
+ break;
+#endif
+
+#ifdef H8300HMAGIC
+ case H8300HMAGIC:
+ arch = bfd_arch_h8300;
+ machine = bfd_mach_h8300h;
+ /* !! FIXME this probably isn't the right place for this */
+ abfd->flags |= BFD_IS_RELAXABLE;
+ break;
+#endif
+
+#ifdef H8300SMAGIC
+ case H8300SMAGIC:
+ arch = bfd_arch_h8300;
+ machine = bfd_mach_h8300s;
+ /* !! FIXME this probably isn't the right place for this */
+ abfd->flags |= BFD_IS_RELAXABLE;
+ break;
+#endif
+
+#ifdef SH_ARCH_MAGIC_BIG
+ case SH_ARCH_MAGIC_BIG:
+ case SH_ARCH_MAGIC_LITTLE:
+ arch = bfd_arch_sh;
+ machine = 0;
+ break;
+#endif
+
+#ifdef H8500MAGIC
+ case H8500MAGIC:
+ arch = bfd_arch_h8500;
+ machine = 0;
+ break;
+#endif
+
+#ifdef SPARCMAGIC
+ case SPARCMAGIC:
+#ifdef LYNXCOFFMAGIC
+ case LYNXCOFFMAGIC:
+#endif
+ arch = bfd_arch_sparc;
+ machine = 0;
+ break;
+#endif
+
+#ifdef TIC30MAGIC
+ case TIC30MAGIC:
+ arch = bfd_arch_tic30;
+ break;
+#endif
+
+#ifdef TIC80_ARCH_MAGIC
+ case TIC80_ARCH_MAGIC:
+ arch = bfd_arch_tic80;
+ break;
+#endif
+
+#ifdef MCOREMAGIC
+ case MCOREMAGIC:
+ arch = bfd_arch_mcore;
+ break;
+#endif
+ default: /* Unreadable input file type */
+ arch = bfd_arch_obscure;
+ break;
+ }
+
+ bfd_default_set_arch_mach (abfd, arch, machine);
+ return true;
+}
+
+#ifdef SYMNAME_IN_DEBUG
+
+static boolean symname_in_debug_hook
+ PARAMS ((bfd *, struct internal_syment *));
+
+static boolean
+symname_in_debug_hook (abfd, sym)
+ bfd * abfd;
+ struct internal_syment *sym;
+{
+ return SYMNAME_IN_DEBUG (sym) ? true : false;
+}
+
+#else
+
+#define symname_in_debug_hook \
+ (boolean (*) PARAMS ((bfd *, struct internal_syment *))) bfd_false
+
+#endif
+
+#ifdef RS6000COFF_C
+
+/* Handle the csect auxent of a C_EXT or C_HIDEXT symbol. */
+
+static boolean coff_pointerize_aux_hook
+ PARAMS ((bfd *, combined_entry_type *, combined_entry_type *,
+ unsigned int, combined_entry_type *));
+
+/*ARGSUSED*/
+static boolean
+coff_pointerize_aux_hook (abfd, table_base, symbol, indaux, aux)
+ bfd *abfd;
+ combined_entry_type *table_base;
+ combined_entry_type *symbol;
+ unsigned int indaux;
+ combined_entry_type *aux;
+{
+ int class = symbol->u.syment.n_sclass;
+
+ if ((class == C_EXT || class == C_HIDEXT)
+ && indaux + 1 == symbol->u.syment.n_numaux)
+ {
+ if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
+ {
+ aux->u.auxent.x_csect.x_scnlen.p =
+ table_base + aux->u.auxent.x_csect.x_scnlen.l;
+ aux->fix_scnlen = 1;
+ }
+
+ /* Return true to indicate that the caller should not do any
+ further work on this auxent. */
+ return true;
+ }
+
+ /* Return false to indicate that this auxent should be handled by
+ the caller. */
+ return false;
+}
+
+#else
+#ifdef I960
+
+/* We don't want to pointerize bal entries. */
+
+static boolean coff_pointerize_aux_hook
+ PARAMS ((bfd *, combined_entry_type *, combined_entry_type *,
+ unsigned int, combined_entry_type *));
+
+/*ARGSUSED*/
+static boolean
+coff_pointerize_aux_hook (abfd, table_base, symbol, indaux, aux)
+ bfd *abfd;
+ combined_entry_type *table_base;
+ combined_entry_type *symbol;
+ unsigned int indaux;
+ combined_entry_type *aux;
+{
+ /* Return true if we don't want to pointerize this aux entry, which
+ is the case for the lastfirst aux entry for a C_LEAFPROC symbol. */
+ return (indaux == 1
+ && (symbol->u.syment.n_sclass == C_LEAFPROC
+ || symbol->u.syment.n_sclass == C_LEAFSTAT
+ || symbol->u.syment.n_sclass == C_LEAFEXT));
+}
+
+#else /* ! I960 */
+
+#define coff_pointerize_aux_hook 0
+
+#endif /* ! I960 */
+#endif /* ! RS6000COFF_C */
+
+/* Print an aux entry. This returns true if it has printed it. */
+
+static boolean coff_print_aux
+ PARAMS ((bfd *, FILE *, combined_entry_type *, combined_entry_type *,
+ combined_entry_type *, unsigned int));
+
+static boolean
+coff_print_aux (abfd, file, table_base, symbol, aux, indaux)
+ bfd *abfd;
+ FILE *file;
+ combined_entry_type *table_base;
+ combined_entry_type *symbol;
+ combined_entry_type *aux;
+ unsigned int indaux;
+{
+#ifdef RS6000COFF_C
+ if ((symbol->u.syment.n_sclass == C_EXT
+ || symbol->u.syment.n_sclass == C_HIDEXT)
+ && indaux + 1 == symbol->u.syment.n_numaux)
+ {
+ /* This is a csect entry. */
+ fprintf (file, "AUX ");
+ if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) != XTY_LD)
+ {
+ BFD_ASSERT (! aux->fix_scnlen);
+ fprintf (file, "val %5ld", aux->u.auxent.x_csect.x_scnlen.l);
+ }
+ else
+ {
+ fprintf (file, "indx ");
+ if (! aux->fix_scnlen)
+ fprintf (file, "%4ld", aux->u.auxent.x_csect.x_scnlen.l);
+ else
+ fprintf (file, "%4ld",
+ (long) (aux->u.auxent.x_csect.x_scnlen.p - table_base));
+ }
+ fprintf (file,
+ " prmhsh %ld snhsh %u typ %d algn %d clss %u stb %ld snstb %u",
+ aux->u.auxent.x_csect.x_parmhash,
+ (unsigned int) aux->u.auxent.x_csect.x_snhash,
+ SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp),
+ SMTYP_ALIGN (aux->u.auxent.x_csect.x_smtyp),
+ (unsigned int) aux->u.auxent.x_csect.x_smclas,
+ aux->u.auxent.x_csect.x_stab,
+ (unsigned int) aux->u.auxent.x_csect.x_snstab);
+ return true;
+ }
+#endif
+
+ /* Return false to indicate that no special action was taken. */
+ return false;
+}
+
+/*
+SUBSUBSECTION
+ Writing relocations
+
+ To write relocations, the back end steps though the
+ canonical relocation table and create an
+ @code{internal_reloc}. The symbol index to use is removed from
+ the @code{offset} field in the symbol table supplied. The
+ address comes directly from the sum of the section base
+ address and the relocation offset; the type is dug directly
+ from the howto field. Then the @code{internal_reloc} is
+ swapped into the shape of an @code{external_reloc} and written
+ out to disk.
+
+*/
+
+#ifdef TARG_AUX
+
+static int compare_arelent_ptr PARAMS ((const PTR, const PTR));
+
+/* AUX's ld wants relocations to be sorted */
+static int
+compare_arelent_ptr (x, y)
+ const PTR x;
+ const PTR y;
+{
+ const arelent **a = (const arelent **) x;
+ const arelent **b = (const arelent **) y;
+ bfd_size_type aadr = (*a)->address;
+ bfd_size_type badr = (*b)->address;
+
+ return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
+}
+
+#endif /* TARG_AUX */
+
+static boolean
+coff_write_relocs (abfd, first_undef)
+ bfd * abfd;
+ int first_undef;
+{
+ asection *s;
+
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ unsigned int i;
+ struct external_reloc dst;
+ arelent **p;
+
+#ifndef TARG_AUX
+ p = s->orelocation;
+#else
+ /* sort relocations before we write them out */
+ p = (arelent **) bfd_malloc (s->reloc_count * sizeof (arelent *));
+ if (p == NULL && s->reloc_count > 0)
+ return false;
+ memcpy (p, s->orelocation, s->reloc_count * sizeof (arelent *));
+ qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+#endif
+
+ if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
+ return false;
+ for (i = 0; i < s->reloc_count; i++)
+ {
+ struct internal_reloc n;
+ arelent *q = p[i];
+ memset ((PTR) & n, 0, sizeof (n));
+
+ /* Now we've renumbered the symbols we know where the
+ undefined symbols live in the table. Check the reloc
+ entries for symbols who's output bfd isn't the right one.
+ This is because the symbol was undefined (which means
+ that all the pointers are never made to point to the same
+ place). This is a bad thing,'cause the symbols attached
+ to the output bfd are indexed, so that the relocation
+ entries know which symbol index they point to. So we
+ have to look up the output symbol here. */
+
+ if (q->sym_ptr_ptr[0]->the_bfd != abfd)
+ {
+ int i;
+ const char *sname = q->sym_ptr_ptr[0]->name;
+ asymbol **outsyms = abfd->outsymbols;
+ for (i = first_undef; outsyms[i]; i++)
+ {
+ const char *intable = outsyms[i]->name;
+ if (strcmp (intable, sname) == 0) {
+ /* got a hit, so repoint the reloc */
+ q->sym_ptr_ptr = outsyms + i;
+ break;
+ }
+ }
+ }
+
+ n.r_vaddr = q->address + s->vma;
+
+#ifdef R_IHCONST
+ /* The 29k const/consth reloc pair is a real kludge. The consth
+ part doesn't have a symbol; it has an offset. So rebuilt
+ that here. */
+ if (q->howto->type == R_IHCONST)
+ n.r_symndx = q->addend;
+ else
+#endif
+ if (q->sym_ptr_ptr)
+ {
+ if (q->sym_ptr_ptr == bfd_abs_section_ptr->symbol_ptr_ptr)
+ /* This is a relocation relative to the absolute symbol. */
+ n.r_symndx = -1;
+ else
+ {
+ n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
+ /* Take notice if the symbol reloc points to a symbol
+ we don't have in our symbol table. What should we
+ do for this?? */
+ if (n.r_symndx > obj_conv_table_size (abfd))
+ abort ();
+ }
+ }
+
+#ifdef SWAP_OUT_RELOC_OFFSET
+ n.r_offset = q->addend;
+#endif
+
+#ifdef SELECT_RELOC
+ /* Work out reloc type from what is required */
+ SELECT_RELOC (n, q->howto);
+#else
+ n.r_type = q->howto->type;
+#endif
+ coff_swap_reloc_out (abfd, &n, &dst);
+ if (bfd_write ((PTR) & dst, 1, RELSZ, abfd) != RELSZ)
+ return false;
+ }
+
+#ifdef TARG_AUX
+ if (p != NULL)
+ free (p);
+#endif
+ }
+
+ return true;
+}
+
+/* Set flags and magic number of a coff file from architecture and machine
+ type. Result is true if we can represent the arch&type, false if not. */
+
+static boolean
+coff_set_flags (abfd, magicp, flagsp)
+ bfd * abfd;
+ unsigned int *magicp;
+ unsigned short *flagsp;
+{
+ switch (bfd_get_arch (abfd))
+ {
+#ifdef Z8KMAGIC
+ case bfd_arch_z8k:
+ *magicp = Z8KMAGIC;
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_z8001:
+ *flagsp = F_Z8001;
+ break;
+ case bfd_mach_z8002:
+ *flagsp = F_Z8002;
+ break;
+ default:
+ return false;
+ }
+ return true;
+#endif
+#ifdef I960ROMAGIC
+
+ case bfd_arch_i960:
+
+ {
+ unsigned flags;
+ *magicp = I960ROMAGIC;
+ /*
+ ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
+ I960RWMAGIC); FIXME???
+ */
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_i960_core:
+ flags = F_I960CORE;
+ break;
+ case bfd_mach_i960_kb_sb:
+ flags = F_I960KB;
+ break;
+ case bfd_mach_i960_mc:
+ flags = F_I960MC;
+ break;
+ case bfd_mach_i960_xa:
+ flags = F_I960XA;
+ break;
+ case bfd_mach_i960_ca:
+ flags = F_I960CA;
+ break;
+ case bfd_mach_i960_ka_sa:
+ flags = F_I960KA;
+ break;
+ case bfd_mach_i960_jx:
+ flags = F_I960JX;
+ break;
+ case bfd_mach_i960_hx:
+ flags = F_I960HX;
+ break;
+ default:
+ return false;
+ }
+ *flagsp = flags;
+ return true;
+ }
+ break;
+#endif
+
+#ifdef TIC30MAGIC
+ case bfd_arch_tic30:
+ *magicp = TIC30MAGIC;
+ return true;
+#endif
+#ifdef TIC80_ARCH_MAGIC
+ case bfd_arch_tic80:
+ *magicp = TIC80_ARCH_MAGIC;
+ return true;
+#endif
+#ifdef ARMMAGIC
+ case bfd_arch_arm:
+ * magicp = ARMMAGIC;
+ * flagsp = 0;
+ if (APCS_SET (abfd))
+ {
+ if (APCS_26_FLAG (abfd))
+ * flagsp |= F_APCS26;
+
+ if (APCS_FLOAT_FLAG (abfd))
+ * flagsp |= F_APCS_FLOAT;
+
+ if (PIC_FLAG (abfd))
+ * flagsp |= F_PIC_INT;
+ }
+ if (INTERWORK_SET (abfd) && INTERWORK_FLAG (abfd))
+ * flagsp |= F_INTERWORK;
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_arm_2: * flagsp |= F_ARM_2; break;
+ case bfd_mach_arm_2a: * flagsp |= F_ARM_2a; break;
+ case bfd_mach_arm_3: * flagsp |= F_ARM_3; break;
+ case bfd_mach_arm_3M: * flagsp |= F_ARM_3M; break;
+ case bfd_mach_arm_4: * flagsp |= F_ARM_4; break;
+ case bfd_mach_arm_4T: * flagsp |= F_ARM_4T; break;
+ }
+ return true;
+#endif
+#ifdef PPCMAGIC
+ case bfd_arch_powerpc:
+ *magicp = PPCMAGIC;
+ return true;
+ break;
+#endif
+#ifdef I386MAGIC
+ case bfd_arch_i386:
+ *magicp = I386MAGIC;
+#ifdef LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
+#endif
+ return true;
+ break;
+#endif
+#ifdef I860MAGIC
+ case bfd_arch_i860:
+ *magicp = I860MAGIC;
+ return true;
+ break;
+#endif
+#ifdef MC68MAGIC
+ case bfd_arch_m68k:
+#ifdef APOLLOM68KMAGIC
+ *magicp = APOLLO_COFF_VERSION_NUMBER;
+#else
+ /* NAMES_HAVE_UNDERSCORE may be defined by coff-u68k.c. */
+#ifdef NAMES_HAVE_UNDERSCORE
+ *magicp = MC68KBCSMAGIC;
+#else
+ *magicp = MC68MAGIC;
+#endif
+#endif
+#ifdef LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
+#endif
+ return true;
+ break;
+#endif
+
+#ifdef MC88MAGIC
+ case bfd_arch_m88k:
+ *magicp = MC88OMAGIC;
+ return true;
+ break;
+#endif
+#ifdef H8300MAGIC
+ case bfd_arch_h8300:
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_h8300:
+ *magicp = H8300MAGIC;
+ return true;
+ case bfd_mach_h8300h:
+ *magicp = H8300HMAGIC;
+ return true;
+ case bfd_mach_h8300s:
+ *magicp = H8300SMAGIC;
+ return true;
+ }
+ break;
+#endif
+
+#ifdef SH_ARCH_MAGIC_BIG
+ case bfd_arch_sh:
+ if (bfd_big_endian (abfd))
+ *magicp = SH_ARCH_MAGIC_BIG;
+ else
+ *magicp = SH_ARCH_MAGIC_LITTLE;
+ return true;
+ break;
+#endif
+
+#ifdef SPARCMAGIC
+ case bfd_arch_sparc:
+ *magicp = SPARCMAGIC;
+#ifdef LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
+#endif
+ return true;
+ break;
+#endif
+
+#ifdef H8500MAGIC
+ case bfd_arch_h8500:
+ *magicp = H8500MAGIC;
+ return true;
+ break;
+#endif
+#ifdef A29K_MAGIC_BIG
+ case bfd_arch_a29k:
+ if (bfd_big_endian (abfd))
+ *magicp = A29K_MAGIC_BIG;
+ else
+ *magicp = A29K_MAGIC_LITTLE;
+ return true;
+ break;
+#endif
+
+#ifdef WE32KMAGIC
+ case bfd_arch_we32k:
+ *magicp = WE32KMAGIC;
+ return true;
+ break;
+#endif
+
+#ifdef U802TOCMAGIC
+ case bfd_arch_rs6000:
+#ifndef PPCMAGIC
+ case bfd_arch_powerpc:
+#endif
+ *magicp = U802TOCMAGIC;
+ return true;
+ break;
+#endif
+
+#ifdef MCOREMAGIC
+ case bfd_arch_mcore:
+ * magicp = MCOREMAGIC;
+ return true;
+#endif
+
+ default: /* Unknown architecture */
+ /* return false; -- fall through to "return false" below, to avoid
+ "statement never reached" errors on the one below. */
+ break;
+ }
+
+ return false;
+}
+
+
+static boolean
+coff_set_arch_mach (abfd, arch, machine)
+ bfd * abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ unsigned dummy1;
+ unsigned short dummy2;
+
+ if (! bfd_default_set_arch_mach (abfd, arch, machine))
+ return false;
+
+ if (arch != bfd_arch_unknown &&
+ coff_set_flags (abfd, &dummy1, &dummy2) != true)
+ return false; /* We can't represent this type */
+
+ return true; /* We're easy ... */
+}
+
+
+/* Calculate the file position for each section. */
+
+#ifndef I960
+#define ALIGN_SECTIONS_IN_FILE
+#endif
+#ifdef TIC80COFF
+#undef ALIGN_SECTIONS_IN_FILE
+#endif
+
+static boolean
+coff_compute_section_file_positions (abfd)
+ bfd * abfd;
+{
+ asection *current;
+ asection *previous = (asection *) NULL;
+ file_ptr sofar = FILHSZ;
+ boolean align_adjust;
+ unsigned int count;
+#ifdef ALIGN_SECTIONS_IN_FILE
+ file_ptr old_sofar;
+#endif
+
+#ifdef RS6000COFF_C
+ /* On XCOFF, if we have symbols, set up the .debug section. */
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ bfd_size_type sz;
+ bfd_size_type i, symcount;
+ asymbol **symp;
+
+ sz = 0;
+ symcount = bfd_get_symcount (abfd);
+ for (symp = abfd->outsymbols, i = 0; i < symcount; symp++, i++)
+ {
+ coff_symbol_type *cf;
+
+ cf = coff_symbol_from (abfd, *symp);
+ if (cf != NULL
+ && cf->native != NULL
+ && SYMNAME_IN_DEBUG (&cf->native->u.syment))
+ {
+ size_t len;
+
+ len = strlen (bfd_asymbol_name (*symp));
+ if (len > SYMNMLEN)
+ sz += len + 3;
+ }
+ }
+ if (sz > 0)
+ {
+ asection *dsec;
+
+ dsec = bfd_make_section_old_way (abfd, ".debug");
+ if (dsec == NULL)
+ abort ();
+ dsec->_raw_size = sz;
+ dsec->flags |= SEC_HAS_CONTENTS;
+ }
+ }
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ int page_size;
+ if (coff_data (abfd)->link_info)
+ {
+ page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
+ }
+ else
+ page_size = PE_DEF_FILE_ALIGNMENT;
+#else
+#ifdef COFF_PAGE_SIZE
+ int page_size = COFF_PAGE_SIZE;
+#endif
+#endif
+
+ if (bfd_get_start_address (abfd))
+ {
+ /* A start address may have been added to the original file. In this
+ case it will need an optional header to record it. */
+ abfd->flags |= EXEC_P;
+ }
+
+ if (abfd->flags & EXEC_P)
+ sofar += AOUTSZ;
+#ifdef RS6000COFF_C
+ else if (xcoff_data (abfd)->full_aouthdr)
+ sofar += AOUTSZ;
+ else
+ sofar += SMALL_AOUTSZ;
+#endif
+
+ sofar += abfd->section_count * SCNHSZ;
+
+#ifdef RS6000COFF_C
+ /* XCOFF handles overflows in the reloc and line number count fields
+ by allocating a new section header to hold the correct counts. */
+ for (current = abfd->sections; current != NULL; current = current->next)
+ if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
+ sofar += SCNHSZ;
+#endif
+
+ align_adjust = false;
+ for (current = abfd->sections, count = 1;
+ current != (asection *) NULL;
+ current = current->next, ++count)
+ {
+#ifdef COFF_IMAGE_WITH_PE
+ /* The NT loader does not want empty section headers, so we omit
+ them. We don't actually remove the section from the BFD,
+ although we probably should. This matches code in
+ coff_write_object_contents. */
+ if (current->_raw_size == 0)
+ {
+ current->target_index = -1;
+ --count;
+ continue;
+ }
+#endif
+
+ current->target_index = count;
+
+ /* Only deal with sections which have contents */
+ if (!(current->flags & SEC_HAS_CONTENTS))
+ continue;
+
+ /* Align the sections in the file to the same boundary on
+ which they are aligned in virtual memory. I960 doesn't
+ do this (FIXME) so we can stay in sync with Intel. 960
+ doesn't yet page from files... */
+#ifdef ALIGN_SECTIONS_IN_FILE
+ if ((abfd->flags & EXEC_P) != 0)
+ {
+ /* make sure this section is aligned on the right boundary - by
+ padding the previous section up if necessary */
+
+ old_sofar = sofar;
+ sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ if (previous != (asection *) NULL)
+ {
+ previous->_raw_size += sofar - old_sofar;
+ }
+ }
+
+#endif
+
+ /* In demand paged files the low order bits of the file offset
+ must match the low order bits of the virtual address. */
+#ifdef COFF_PAGE_SIZE
+ if ((abfd->flags & D_PAGED) != 0
+ && (current->flags & SEC_ALLOC) != 0)
+ sofar += (current->vma - sofar) % page_size;
+#endif
+ current->filepos = sofar;
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* With PE we have to pad each section to be a multiple of its
+ page size too, and remember both sizes. */
+
+ if (coff_section_data (abfd, current) == NULL)
+ {
+ current->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata));
+ if (current->used_by_bfd == NULL)
+ return false;
+ }
+ if (pei_section_data (abfd, current) == NULL)
+ {
+ coff_section_data (abfd, current)->tdata =
+ (PTR) bfd_zalloc (abfd, sizeof (struct pei_section_tdata));
+ if (coff_section_data (abfd, current)->tdata == NULL)
+ return false;
+ }
+ if (pei_section_data (abfd, current)->virt_size == 0)
+ pei_section_data (abfd, current)->virt_size = current->_raw_size;
+
+ current->_raw_size = (current->_raw_size + page_size -1) & -page_size;
+#endif
+
+ sofar += current->_raw_size;
+
+#ifdef ALIGN_SECTIONS_IN_FILE
+ /* make sure that this section is of the right size too */
+ if ((abfd->flags & EXEC_P) == 0)
+ {
+ bfd_size_type old_size;
+
+ old_size = current->_raw_size;
+ current->_raw_size = BFD_ALIGN (current->_raw_size,
+ 1 << current->alignment_power);
+ align_adjust = current->_raw_size != old_size;
+ sofar += current->_raw_size - old_size;
+ }
+ else
+ {
+ old_sofar = sofar;
+ sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ align_adjust = sofar != old_sofar;
+ current->_raw_size += sofar - old_sofar;
+ }
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* For PE we need to make sure we pad out to the aligned
+ _raw_size, in case the caller only writes out data to the
+ unaligned _raw_size. */
+ if (pei_section_data (abfd, current)->virt_size < current->_raw_size)
+ align_adjust = true;
+#endif
+
+#ifdef _LIB
+ /* Force .lib sections to start at zero. The vma is then
+ incremented in coff_set_section_contents. This is right for
+ SVR3.2. */
+ if (strcmp (current->name, _LIB) == 0)
+ bfd_set_section_vma (abfd, current, 0);
+#endif
+
+ previous = current;
+ }
+
+ /* It is now safe to write to the output file. If we needed an
+ alignment adjustment for the last section, then make sure that
+ there is a byte at offset sofar. If there are no symbols and no
+ relocs, then nothing follows the last section. If we don't force
+ the last byte out, then the file may appear to be truncated. */
+ if (align_adjust)
+ {
+ bfd_byte b;
+
+ b = 0;
+ if (bfd_seek (abfd, sofar - 1, SEEK_SET) != 0
+ || bfd_write (&b, 1, 1, abfd) != 1)
+ return false;
+ }
+
+ /* Make sure the relocations are aligned. We don't need to make
+ sure that this byte exists, because it will only matter if there
+ really are relocs. */
+ sofar = BFD_ALIGN (sofar, 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER);
+
+ obj_relocbase (abfd) = sofar;
+ abfd->output_has_begun = true;
+
+ return true;
+}
+
+#if 0
+
+/* This can never work, because it is called too late--after the
+ section positions have been set. I can't figure out what it is
+ for, so I am going to disable it--Ian Taylor 20 March 1996. */
+
+/* If .file, .text, .data, .bss symbols are missing, add them. */
+/* @@ Should we only be adding missing symbols, or overriding the aux
+ values for existing section symbols? */
+static boolean
+coff_add_missing_symbols (abfd)
+ bfd *abfd;
+{
+ unsigned int nsyms = bfd_get_symcount (abfd);
+ asymbol **sympp = abfd->outsymbols;
+ asymbol **sympp2;
+ unsigned int i;
+ int need_text = 1, need_data = 1, need_bss = 1, need_file = 1;
+
+ for (i = 0; i < nsyms; i++)
+ {
+ coff_symbol_type *csym = coff_symbol_from (abfd, sympp[i]);
+ CONST char *name;
+ if (csym)
+ {
+ /* only do this if there is a coff representation of the input
+ symbol */
+ if (csym->native && csym->native->u.syment.n_sclass == C_FILE)
+ {
+ need_file = 0;
+ continue;
+ }
+ name = csym->symbol.name;
+ if (!name)
+ continue;
+ if (!strcmp (name, _TEXT))
+ need_text = 0;
+#ifdef APOLLO_M68
+ else if (!strcmp (name, ".wtext"))
+ need_text = 0;
+#endif
+ else if (!strcmp (name, _DATA))
+ need_data = 0;
+ else if (!strcmp (name, _BSS))
+ need_bss = 0;
+ }
+ }
+ /* Now i == bfd_get_symcount (abfd). */
+ /* @@ For now, don't deal with .file symbol. */
+ need_file = 0;
+
+ if (!need_text && !need_data && !need_bss && !need_file)
+ return true;
+ nsyms += need_text + need_data + need_bss + need_file;
+ sympp2 = (asymbol **) bfd_alloc (abfd, nsyms * sizeof (asymbol *));
+ if (!sympp2)
+ return false;
+ memcpy (sympp2, sympp, i * sizeof (asymbol *));
+ if (need_file)
+ {
+ /* @@ Generate fake .file symbol, in sympp2[i], and increment i. */
+ abort ();
+ }
+ if (need_text)
+ sympp2[i++] = coff_section_symbol (abfd, _TEXT);
+ if (need_data)
+ sympp2[i++] = coff_section_symbol (abfd, _DATA);
+ if (need_bss)
+ sympp2[i++] = coff_section_symbol (abfd, _BSS);
+ BFD_ASSERT (i == nsyms);
+ bfd_set_symtab (abfd, sympp2, nsyms);
+ return true;
+}
+
+#endif /* 0 */
+
+/* SUPPRESS 558 */
+/* SUPPRESS 529 */
+static boolean
+coff_write_object_contents (abfd)
+ bfd * abfd;
+{
+ asection *current;
+ boolean hasrelocs = false;
+ boolean haslinno = false;
+ file_ptr scn_base;
+ file_ptr reloc_base;
+ file_ptr lineno_base;
+ file_ptr sym_base;
+ unsigned long reloc_size = 0;
+ unsigned long lnno_size = 0;
+ boolean long_section_names;
+ asection *text_sec = NULL;
+ asection *data_sec = NULL;
+ asection *bss_sec = NULL;
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
+#ifdef COFF_LONG_SECTION_NAMES
+ size_t string_size = STRING_SIZE_SIZE;
+#endif
+
+ bfd_set_error (bfd_error_system_call);
+
+ /* Make a pass through the symbol table to count line number entries and
+ put them into the correct asections */
+
+ lnno_size = coff_count_linenumbers (abfd) * LINESZ;
+
+ if (abfd->output_has_begun == false)
+ {
+ if (! coff_compute_section_file_positions (abfd))
+ return false;
+ }
+
+ reloc_base = obj_relocbase (abfd);
+
+ /* Work out the size of the reloc and linno areas */
+
+ for (current = abfd->sections; current != NULL; current =
+ current->next)
+ reloc_size += current->reloc_count * RELSZ;
+
+ lineno_base = reloc_base + reloc_size;
+ sym_base = lineno_base + lnno_size;
+
+ /* Indicate in each section->line_filepos its actual file address */
+ for (current = abfd->sections; current != NULL; current =
+ current->next)
+ {
+ if (current->lineno_count)
+ {
+ current->line_filepos = lineno_base;
+ current->moving_line_filepos = lineno_base;
+ lineno_base += current->lineno_count * LINESZ;
+ }
+ else
+ {
+ current->line_filepos = 0;
+ }
+ if (current->reloc_count)
+ {
+ current->rel_filepos = reloc_base;
+ reloc_base += current->reloc_count * RELSZ;
+ }
+ else
+ {
+ current->rel_filepos = 0;
+ }
+ }
+
+ /* Write section headers to the file. */
+ internal_f.f_nscns = 0;
+
+ if ((abfd->flags & EXEC_P) != 0)
+ scn_base = FILHSZ + AOUTSZ;
+ else
+ {
+ scn_base = FILHSZ;
+#ifdef RS6000COFF_C
+ if (xcoff_data (abfd)->full_aouthdr)
+ scn_base += AOUTSZ;
+ else
+ scn_base += SMALL_AOUTSZ;
+#endif
+ }
+
+ if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
+ return false;
+
+ long_section_names = false;
+ for (current = abfd->sections;
+ current != NULL;
+ current = current->next)
+ {
+ struct internal_scnhdr section;
+
+#ifdef COFF_WITH_PE
+ /* If we've got a .reloc section, remember. */
+
+#ifdef COFF_IMAGE_WITH_PE
+ if (strcmp (current->name, ".reloc") == 0)
+ {
+ pe_data (abfd)->has_reloc_section = 1;
+ }
+#endif
+
+#endif
+ internal_f.f_nscns++;
+
+ strncpy (section.s_name, current->name, SCNNMLEN);
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Handle long section names as in PE. This must be compatible
+ with the code in coff_write_symbols. */
+ {
+ size_t len;
+
+ len = strlen (current->name);
+ if (len > SCNNMLEN)
+ {
+ memset (section.s_name, 0, SCNNMLEN);
+ sprintf (section.s_name, "/%lu", (unsigned long) string_size);
+ string_size += len + 1;
+ long_section_names = true;
+ }
+ }
+#endif
+
+#ifdef _LIB
+ /* Always set s_vaddr of .lib to 0. This is right for SVR3.2
+ Ian Taylor <ian@cygnus.com>. */
+ if (strcmp (current->name, _LIB) == 0)
+ section.s_vaddr = 0;
+ else
+#endif
+ section.s_vaddr = current->vma;
+ section.s_paddr = current->lma;
+ section.s_size = current->_raw_size;
+
+#ifdef COFF_WITH_PE
+ section.s_paddr = 0;
+#endif
+#ifdef COFF_IMAGE_WITH_PE
+ /* Reminder: s_paddr holds the virtual size of the section. */
+ if (coff_section_data (abfd, current) != NULL
+ && pei_section_data (abfd, current) != NULL)
+ section.s_paddr = pei_section_data (abfd, current)->virt_size;
+ else
+ section.s_paddr = 0;
+#endif
+
+ /*
+ If this section has no size or is unloadable then the scnptr
+ will be 0 too
+ */
+ if (current->_raw_size == 0 ||
+ (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ {
+ section.s_scnptr = 0;
+ }
+ else
+ {
+ section.s_scnptr = current->filepos;
+ }
+ section.s_relptr = current->rel_filepos;
+ section.s_lnnoptr = current->line_filepos;
+ section.s_nreloc = current->reloc_count;
+ section.s_nlnno = current->lineno_count;
+ if (current->reloc_count != 0)
+ hasrelocs = true;
+ if (current->lineno_count != 0)
+ haslinno = true;
+
+#ifdef RS6000COFF_C
+ /* Indicate the use of an XCOFF overflow section header. */
+ if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
+ {
+ section.s_nreloc = 0xffff;
+ section.s_nlnno = 0xffff;
+ }
+#endif
+
+ section.s_flags = sec_to_styp_flags (current->name, current->flags);
+
+ if (!strcmp (current->name, _TEXT))
+ {
+ text_sec = current;
+ }
+ else if (!strcmp (current->name, _DATA))
+ {
+ data_sec = current;
+ }
+ else if (!strcmp (current->name, _BSS))
+ {
+ bss_sec = current;
+ }
+
+#ifdef I960
+ section.s_align = (current->alignment_power
+ ? 1 << current->alignment_power
+ : 0);
+#else
+#ifdef TIC80COFF
+ section.s_flags |= (current->alignment_power & 0xF) << 8;
+#endif
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* suppress output of the sections if they are null. ld includes
+ the bss and data sections even if there is no size assigned
+ to them. NT loader doesn't like it if these section headers are
+ included if the sections themselves are not needed */
+ if (section.s_size == 0)
+ internal_f.f_nscns--;
+ else
+#endif
+ {
+ SCNHDR buff;
+ if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
+ || bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
+ return false;
+ }
+
+#ifdef COFF_WITH_PE
+ /* PE stores COMDAT section information in the symbol table. If
+ this section is supposed to have some COMDAT info, track down
+ the symbol in the symbol table and modify it. */
+ if ((current->flags & SEC_LINK_ONCE) != 0)
+ {
+ unsigned int i, count;
+ asymbol **psym;
+ coff_symbol_type *csym = NULL;
+ asymbol **psymsec;
+
+ psymsec = NULL;
+ count = bfd_get_symcount (abfd);
+ for (i = 0, psym = abfd->outsymbols; i < count; i++, psym++)
+ {
+ if ((*psym)->section != current)
+ continue;
+
+ /* Remember the location of the first symbol in this
+ section. */
+ if (psymsec == NULL)
+ psymsec = psym;
+
+ /* See if this is the section symbol. */
+ if (strcmp ((*psym)->name, current->name) == 0)
+ {
+ csym = coff_symbol_from (abfd, *psym);
+ if (csym == NULL
+ || csym->native == NULL
+ || csym->native->u.syment.n_numaux < 1
+ || csym->native->u.syment.n_sclass != C_STAT
+ || csym->native->u.syment.n_type != T_NULL)
+ continue;
+
+ /* Here *PSYM is the section symbol for CURRENT. */
+
+ break;
+ }
+ }
+
+ /* Did we find it?
+ Note that we might not if we're converting the file from
+ some other object file format. */
+ if (i < count)
+ {
+ combined_entry_type *aux;
+
+ /* We don't touch the x_checksum field. The
+ x_associated field is not currently supported. */
+
+ aux = csym->native + 1;
+ switch (current->flags & SEC_LINK_DUPLICATES)
+ {
+ case SEC_LINK_DUPLICATES_DISCARD:
+ aux->u.auxent.x_scn.x_comdat = IMAGE_COMDAT_SELECT_ANY;
+ break;
+
+ case SEC_LINK_DUPLICATES_ONE_ONLY:
+ aux->u.auxent.x_scn.x_comdat =
+ IMAGE_COMDAT_SELECT_NODUPLICATES;
+ break;
+
+ case SEC_LINK_DUPLICATES_SAME_SIZE:
+ aux->u.auxent.x_scn.x_comdat =
+ IMAGE_COMDAT_SELECT_SAME_SIZE;
+ break;
+
+ case SEC_LINK_DUPLICATES_SAME_CONTENTS:
+ aux->u.auxent.x_scn.x_comdat =
+ IMAGE_COMDAT_SELECT_EXACT_MATCH;
+ break;
+ }
+
+ /* The COMDAT symbol must be the first symbol from this
+ section in the symbol table. In order to make this
+ work, we move the COMDAT symbol before the first
+ symbol we found in the search above. It's OK to
+ rearrange the symbol table at this point, because
+ coff_renumber_symbols is going to rearrange it
+ further and fix up all the aux entries. */
+ if (psym != psymsec)
+ {
+ asymbol *hold;
+ asymbol **pcopy;
+
+ hold = *psym;
+ for (pcopy = psym; pcopy > psymsec; pcopy--)
+ pcopy[0] = pcopy[-1];
+ *psymsec = hold;
+ }
+ }
+ }
+#endif /* COFF_WITH_PE */
+ }
+
+#ifdef RS6000COFF_C
+ /* XCOFF handles overflows in the reloc and line number count fields
+ by creating a new section header to hold the correct values. */
+ for (current = abfd->sections; current != NULL; current = current->next)
+ {
+ if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
+ {
+ struct internal_scnhdr scnhdr;
+ SCNHDR buff;
+
+ internal_f.f_nscns++;
+ strncpy (&(scnhdr.s_name[0]), current->name, 8);
+ scnhdr.s_paddr = current->reloc_count;
+ scnhdr.s_vaddr = current->lineno_count;
+ scnhdr.s_size = 0;
+ scnhdr.s_scnptr = 0;
+ scnhdr.s_relptr = current->rel_filepos;
+ scnhdr.s_lnnoptr = current->line_filepos;
+ scnhdr.s_nreloc = current->target_index;
+ scnhdr.s_nlnno = current->target_index;
+ scnhdr.s_flags = STYP_OVRFLO;
+ if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
+ || bfd_write ((PTR) &buff, 1, SCNHSZ, abfd) != SCNHSZ)
+ return false;
+ }
+ }
+#endif
+
+ /* OK, now set up the filehdr... */
+
+ /* Don't include the internal abs section in the section count */
+
+ /*
+ We will NOT put a fucking timestamp in the header here. Every time you
+ put it back, I will come in and take it out again. I'm sorry. This
+ field does not belong here. We fill it with a 0 so it compares the
+ same but is not a reasonable time. -- gnu@cygnus.com
+ */
+ internal_f.f_timdat = 0;
+
+ internal_f.f_flags = 0;
+
+ if (abfd->flags & EXEC_P)
+ internal_f.f_opthdr = AOUTSZ;
+ else
+ {
+ internal_f.f_opthdr = 0;
+#ifdef RS6000COFF_C
+ if (xcoff_data (abfd)->full_aouthdr)
+ internal_f.f_opthdr = AOUTSZ;
+ else
+ internal_f.f_opthdr = SMALL_AOUTSZ;
+#endif
+ }
+
+ if (!hasrelocs)
+ internal_f.f_flags |= F_RELFLG;
+ if (!haslinno)
+ internal_f.f_flags |= F_LNNO;
+ if (abfd->flags & EXEC_P)
+ internal_f.f_flags |= F_EXEC;
+
+ /* FIXME: this is wrong for PPC_PE! */
+ if (bfd_little_endian (abfd))
+ internal_f.f_flags |= F_AR32WR;
+ else
+ internal_f.f_flags |= F_AR32W;
+
+#ifdef TIC80_TARGET_ID
+ internal_f.f_target_id = TIC80_TARGET_ID;
+#endif
+
+ /*
+ FIXME, should do something about the other byte orders and
+ architectures.
+ */
+
+#ifdef RS6000COFF_C
+ if ((abfd->flags & DYNAMIC) != 0)
+ internal_f.f_flags |= F_SHROBJ;
+ if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
+ internal_f.f_flags |= F_DYNLOAD;
+#endif
+
+ memset (&internal_a, 0, sizeof internal_a);
+
+ /* Set up architecture-dependent stuff */
+
+ {
+ unsigned int magic = 0;
+ unsigned short flags = 0;
+ coff_set_flags (abfd, &magic, &flags);
+ internal_f.f_magic = magic;
+ internal_f.f_flags |= flags;
+ /* ...and the "opt"hdr... */
+
+#ifdef A29K
+#ifdef ULTRA3 /* NYU's machine */
+ /* FIXME: This is a bogus check. I really want to see if there
+ * is a .shbss or a .shdata section, if so then set the magic
+ * number to indicate a shared data executable.
+ */
+ if (internal_f.f_nscns >= 7)
+ internal_a.magic = SHMAGIC; /* Shared magic */
+ else
+#endif /* ULTRA3 */
+ internal_a.magic = NMAGIC; /* Assume separate i/d */
+#define __A_MAGIC_SET__
+#endif /* A29K */
+#ifdef TIC80COFF
+ internal_a.magic = TIC80_ARCH_MAGIC;
+#define __A_MAGIC_SET__
+#endif /* TIC80 */
+#ifdef I860
+ /* FIXME: What are the a.out magic numbers for the i860? */
+ internal_a.magic = 0;
+#define __A_MAGIC_SET__
+#endif /* I860 */
+#ifdef I960
+ internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
+#define __A_MAGIC_SET__
+#endif /* I960 */
+#if M88
+#define __A_MAGIC_SET__
+ internal_a.magic = PAGEMAGICBCS;
+#endif /* M88 */
+
+#if APOLLO_M68
+#define __A_MAGIC_SET__
+ internal_a.magic = APOLLO_COFF_VERSION_NUMBER;
+#endif
+
+#if defined(M68) || defined(WE32K) || defined(M68K)
+#define __A_MAGIC_SET__
+#if defined(LYNXOS)
+ internal_a.magic = LYNXCOFFMAGIC;
+#else
+#if defined(TARG_AUX)
+ internal_a.magic = (abfd->flags & D_PAGED ? PAGEMAGICPEXECPAGED :
+ abfd->flags & WP_TEXT ? PAGEMAGICPEXECSWAPPED :
+ PAGEMAGICEXECSWAPPED);
+#else
+#if defined (PAGEMAGICPEXECPAGED)
+ internal_a.magic = PAGEMAGICPEXECPAGED;
+#endif
+#endif /* TARG_AUX */
+#endif /* LYNXOS */
+#endif /* M68 || WE32K || M68K */
+
+#if defined(ARM)
+#define __A_MAGIC_SET__
+ internal_a.magic = ZMAGIC;
+#endif
+
+#if defined(PPC_PE)
+#define __A_MAGIC_SET__
+ internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
+#endif
+
+#if defined MCORE_PE
+#define __A_MAGIC_SET__
+ internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
+#endif
+
+#if defined(I386)
+#define __A_MAGIC_SET__
+#if defined(LYNXOS)
+ internal_a.magic = LYNXCOFFMAGIC;
+#else /* LYNXOS */
+ internal_a.magic = ZMAGIC;
+#endif /* LYNXOS */
+#endif /* I386 */
+
+#if defined(SPARC)
+#define __A_MAGIC_SET__
+#if defined(LYNXOS)
+ internal_a.magic = LYNXCOFFMAGIC;
+#endif /* LYNXOS */
+#endif /* SPARC */
+
+#ifdef RS6000COFF_C
+#define __A_MAGIC_SET__
+ internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC :
+ (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC :
+ RS6K_AOUTHDR_OMAGIC;
+#endif
+
+#ifndef __A_MAGIC_SET__
+#include "Your aouthdr magic number is not being set!"
+#else
+#undef __A_MAGIC_SET__
+#endif
+ }
+
+ /* FIXME: Does anybody ever set this to another value? */
+ internal_a.vstamp = 0;
+
+ /* Now should write relocs, strings, syms */
+ obj_sym_filepos (abfd) = sym_base;
+
+ if (bfd_get_symcount (abfd) != 0)
+ {
+ int firstundef;
+#if 0
+ if (!coff_add_missing_symbols (abfd))
+ return false;
+#endif
+ if (!coff_renumber_symbols (abfd, &firstundef))
+ return false;
+ coff_mangle_symbols (abfd);
+ if (! coff_write_symbols (abfd))
+ return false;
+ if (! coff_write_linenumbers (abfd))
+ return false;
+ if (! coff_write_relocs (abfd, firstundef))
+ return false;
+ }
+#ifdef COFF_LONG_SECTION_NAMES
+ else if (long_section_names)
+ {
+ /* If we have long section names we have to write out the string
+ table even if there are no symbols. */
+ if (! coff_write_symbols (abfd))
+ return false;
+ }
+#endif
+#ifdef COFF_IMAGE_WITH_PE
+#ifdef PPC_PE
+ else if ((abfd->flags & EXEC_P) != 0)
+ {
+ bfd_byte b;
+
+ /* PowerPC PE appears to require that all executable files be
+ rounded up to the page size. */
+ b = 0;
+ if (bfd_seek (abfd,
+ BFD_ALIGN (sym_base, COFF_PAGE_SIZE) - 1,
+ SEEK_SET) != 0
+ || bfd_write (&b, 1, 1, abfd) != 1)
+ return false;
+ }
+#endif
+#endif
+
+ /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
+ backend linker, and obj_raw_syment_count is not valid until after
+ coff_write_symbols is called. */
+ if (obj_raw_syment_count (abfd) != 0)
+ {
+ internal_f.f_symptr = sym_base;
+#ifdef RS6000COFF_C
+ /* AIX appears to require that F_RELFLG not be set if there are
+ local symbols but no relocations. */
+ internal_f.f_flags &=~ F_RELFLG;
+#endif
+ }
+ else
+ {
+ if (long_section_names)
+ internal_f.f_symptr = sym_base;
+ else
+ internal_f.f_symptr = 0;
+ internal_f.f_flags |= F_LSYMS;
+ }
+
+ if (text_sec)
+ {
+ internal_a.tsize = bfd_get_section_size_before_reloc (text_sec);
+ internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
+ }
+ if (data_sec)
+ {
+ internal_a.dsize = bfd_get_section_size_before_reloc (data_sec);
+ internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
+ }
+ if (bss_sec)
+ {
+ internal_a.bsize = bfd_get_section_size_before_reloc (bss_sec);
+ if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
+ internal_a.data_start = bss_sec->vma;
+ }
+
+ internal_a.entry = bfd_get_start_address (abfd);
+ internal_f.f_nsyms = obj_raw_syment_count (abfd);
+
+#ifdef RS6000COFF_C
+ if (xcoff_data (abfd)->full_aouthdr)
+ {
+ bfd_vma toc;
+ asection *loader_sec;
+
+ internal_a.vstamp = 1;
+
+ internal_a.o_snentry = xcoff_data (abfd)->snentry;
+ if (internal_a.o_snentry == 0)
+ internal_a.entry = (bfd_vma) -1;
+
+ if (text_sec != NULL)
+ {
+ internal_a.o_sntext = text_sec->target_index;
+ internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
+ }
+ else
+ {
+ internal_a.o_sntext = 0;
+ internal_a.o_algntext = 0;
+ }
+ if (data_sec != NULL)
+ {
+ internal_a.o_sndata = data_sec->target_index;
+ internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
+ }
+ else
+ {
+ internal_a.o_sndata = 0;
+ internal_a.o_algndata = 0;
+ }
+ loader_sec = bfd_get_section_by_name (abfd, ".loader");
+ if (loader_sec != NULL)
+ internal_a.o_snloader = loader_sec->target_index;
+ else
+ internal_a.o_snloader = 0;
+ if (bss_sec != NULL)
+ internal_a.o_snbss = bss_sec->target_index;
+ else
+ internal_a.o_snbss = 0;
+
+ toc = xcoff_data (abfd)->toc;
+ internal_a.o_toc = toc;
+ internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
+
+ internal_a.o_modtype = xcoff_data (abfd)->modtype;
+ if (xcoff_data (abfd)->cputype != -1)
+ internal_a.o_cputype = xcoff_data (abfd)->cputype;
+ else
+ {
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_rs6000:
+ internal_a.o_cputype = 4;
+ break;
+ case bfd_arch_powerpc:
+ if (bfd_get_mach (abfd) == 0)
+ internal_a.o_cputype = 3;
+ else
+ internal_a.o_cputype = 1;
+ break;
+ default:
+ abort ();
+ }
+ }
+ internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
+ internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
+ }
+#endif
+
+ /* now write them */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+ {
+ char buff[FILHSZ];
+ coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) buff);
+ if (bfd_write ((PTR) buff, 1, FILHSZ, abfd) != FILHSZ)
+ return false;
+ }
+ if (abfd->flags & EXEC_P)
+ {
+ /* Note that peicode.h fills in a PEAOUTHDR, not an AOUTHDR.
+ include/coff/pe.h sets AOUTSZ == sizeof(PEAOUTHDR)) */
+ char buff[AOUTSZ];
+ coff_swap_aouthdr_out (abfd, (PTR) & internal_a, (PTR) buff);
+ if (bfd_write ((PTR) buff, 1, AOUTSZ, abfd) != AOUTSZ)
+ return false;
+ }
+#ifdef RS6000COFF_C
+ else
+ {
+ AOUTHDR buff;
+ size_t size;
+
+ /* XCOFF seems to always write at least a small a.out header. */
+ coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) &buff);
+ if (xcoff_data (abfd)->full_aouthdr)
+ size = AOUTSZ;
+ else
+ size = SMALL_AOUTSZ;
+ if (bfd_write ((PTR) &buff, 1, size, abfd) != size)
+ return false;
+ }
+#endif
+
+ return true;
+}
+
+static boolean
+coff_set_section_contents (abfd, section, location, offset, count)
+ bfd * abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (abfd->output_has_begun == false) /* set by bfd.c handler */
+ {
+ if (! coff_compute_section_file_positions (abfd))
+ return false;
+ }
+
+#if defined(_LIB) && !defined(TARG_AUX)
+
+ /* The physical address field of a .lib section is used to hold the
+ number of shared libraries in the section. This code counts the
+ number of sections being written, and increments the lma field
+ with the number.
+
+ I have found no documentation on the contents of this section.
+ Experimentation indicates that the section contains zero or more
+ records, each of which has the following structure:
+
+ - a (four byte) word holding the length of this record, in words,
+ - a word that always seems to be set to "2",
+ - the path to a shared library, null-terminated and then padded
+ to a whole word boundary.
+
+ bfd_assert calls have been added to alert if an attempt is made
+ to write a section which doesn't follow these assumptions. The
+ code has been tested on ISC 4.1 by me, and on SCO by Robert Lipe
+ <robertl@arnet.com> (Thanks!).
+
+ Gvran Uddeborg <gvran@uddeborg.pp.se> */
+
+ if (strcmp (section->name, _LIB) == 0)
+ {
+ bfd_byte *rec, *recend;
+
+ rec = (bfd_byte *) location;
+ recend = rec + count;
+ while (rec < recend)
+ {
+ ++section->lma;
+ rec += bfd_get_32 (abfd, rec) * 4;
+ }
+
+ BFD_ASSERT (rec == recend);
+ }
+
+#endif
+
+ /* Don't write out bss sections - one way to do this is to
+ see if the filepos has not been set. */
+ if (section->filepos == 0)
+ return true;
+
+ if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0)
+ return false;
+
+ if (count != 0)
+ {
+ return (bfd_write (location, 1, count, abfd) == count) ? true : false;
+ }
+ return true;
+}
+#if 0
+static boolean
+coff_close_and_cleanup (abfd)
+ bfd *abfd;
+{
+ if (!bfd_read_p (abfd))
+ switch (abfd->format)
+ {
+ case bfd_archive:
+ if (!_bfd_write_archive_contents (abfd))
+ return false;
+ break;
+ case bfd_object:
+ if (!coff_write_object_contents (abfd))
+ return false;
+ break;
+ default:
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ /* We depend on bfd_close to free all the memory on the objalloc. */
+ return true;
+}
+
+#endif
+
+static PTR
+buy_and_read (abfd, where, seek_direction, size)
+ bfd *abfd;
+ file_ptr where;
+ int seek_direction;
+ size_t size;
+{
+ PTR area = (PTR) bfd_alloc (abfd, size);
+ if (!area)
+ return (NULL);
+ if (bfd_seek (abfd, where, seek_direction) != 0
+ || bfd_read (area, 1, size, abfd) != size)
+ return (NULL);
+ return (area);
+} /* buy_and_read() */
+
+/*
+SUBSUBSECTION
+ Reading linenumbers
+
+ Creating the linenumber table is done by reading in the entire
+ coff linenumber table, and creating another table for internal use.
+
+ A coff linenumber table is structured so that each function
+ is marked as having a line number of 0. Each line within the
+ function is an offset from the first line in the function. The
+ base of the line number information for the table is stored in
+ the symbol associated with the function.
+
+ The information is copied from the external to the internal
+ table, and each symbol which marks a function is marked by
+ pointing its...
+
+ How does this work ?
+
+*/
+
+static boolean
+coff_slurp_line_table (abfd, asect)
+ bfd *abfd;
+ asection *asect;
+{
+ LINENO *native_lineno;
+ alent *lineno_cache;
+
+ BFD_ASSERT (asect->lineno == (alent *) NULL);
+
+ native_lineno = (LINENO *) buy_and_read (abfd,
+ asect->line_filepos,
+ SEEK_SET,
+ (size_t) (LINESZ *
+ asect->lineno_count));
+ lineno_cache =
+ (alent *) bfd_alloc (abfd, (size_t) ((asect->lineno_count + 1) * sizeof (alent)));
+ if (lineno_cache == NULL)
+ return false;
+ else
+ {
+ unsigned int counter = 0;
+ alent *cache_ptr = lineno_cache;
+ LINENO *src = native_lineno;
+
+ while (counter < asect->lineno_count)
+ {
+ struct internal_lineno dst;
+ coff_swap_lineno_in (abfd, src, &dst);
+ cache_ptr->line_number = dst.l_lnno;
+
+ if (cache_ptr->line_number == 0)
+ {
+ boolean warned;
+ long symndx;
+ coff_symbol_type *sym;
+
+ warned = false;
+ symndx = dst.l_addr.l_symndx;
+ if (symndx < 0
+ || (unsigned long) symndx >= obj_raw_syment_count (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: illegal symbol index %ld in line numbers"),
+ bfd_get_filename (abfd), dst.l_addr.l_symndx);
+ symndx = 0;
+ warned = true;
+ }
+ /* FIXME: We should not be casting between ints and
+ pointers like this. */
+ sym = ((coff_symbol_type *)
+ ((symndx + obj_raw_syments (abfd))
+ ->u.syment._n._n_n._n_zeroes));
+ cache_ptr->u.sym = (asymbol *) sym;
+ if (sym->lineno != NULL && ! warned)
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: duplicate line number information for `%s'"),
+ bfd_get_filename (abfd),
+ bfd_asymbol_name (&sym->symbol));
+ }
+ sym->lineno = cache_ptr;
+ }
+ else
+ {
+ cache_ptr->u.offset = dst.l_addr.l_paddr
+ - bfd_section_vma (abfd, asect);
+ } /* If no linenumber expect a symbol index */
+
+ cache_ptr++;
+ src++;
+ counter++;
+ }
+ cache_ptr->line_number = 0;
+
+ }
+ asect->lineno = lineno_cache;
+ /* FIXME, free native_lineno here, or use alloca or something. */
+ return true;
+}
+
+static boolean
+coff_slurp_symbol_table (abfd)
+ bfd * abfd;
+{
+ combined_entry_type *native_symbols;
+ coff_symbol_type *cached_area;
+ unsigned int *table_ptr;
+
+ unsigned int number_of_symbols = 0;
+
+ if (obj_symbols (abfd))
+ return true;
+
+ /* Read in the symbol table */
+ if ((native_symbols = coff_get_normalized_symtab (abfd)) == NULL)
+ {
+ return (false);
+ } /* on error */
+
+ /* Allocate enough room for all the symbols in cached form */
+ cached_area = ((coff_symbol_type *)
+ bfd_alloc (abfd,
+ (obj_raw_syment_count (abfd)
+ * sizeof (coff_symbol_type))));
+
+ if (cached_area == NULL)
+ return false;
+ table_ptr = ((unsigned int *)
+ bfd_alloc (abfd,
+ (obj_raw_syment_count (abfd)
+ * sizeof (unsigned int))));
+
+ if (table_ptr == NULL)
+ return false;
+ else
+ {
+ coff_symbol_type *dst = cached_area;
+ unsigned int last_native_index = obj_raw_syment_count (abfd);
+ unsigned int this_index = 0;
+ while (this_index < last_native_index)
+ {
+ combined_entry_type *src = native_symbols + this_index;
+ table_ptr[this_index] = number_of_symbols;
+ dst->symbol.the_bfd = abfd;
+
+ dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset);
+ /* We use the native name field to point to the cached field. */
+ src->u.syment._n._n_n._n_zeroes = (long) dst;
+ dst->symbol.section = coff_section_from_bfd_index (abfd,
+ src->u.syment.n_scnum);
+ dst->symbol.flags = 0;
+ dst->done_lineno = false;
+
+ switch (src->u.syment.n_sclass)
+ {
+#ifdef I960
+ case C_LEAFEXT:
+#if 0
+ dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
+ dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
+ dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
+#endif
+ /* Fall through to next case */
+
+#endif
+
+ case C_EXT:
+ case C_WEAKEXT:
+#if defined ARM
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
+#endif
+#ifdef RS6000COFF_C
+ case C_HIDEXT:
+#endif
+#ifdef C_SYSTEM
+ case C_SYSTEM: /* System Wide variable */
+#endif
+#ifdef COFF_WITH_PE
+ /* PE uses storage class 0x68 to denote a section symbol */
+ case C_SECTION:
+ /* PE uses storage class 0x69 for a weak external symbol. */
+ case C_NT_WEAK:
+#endif
+ if ((src->u.syment.n_scnum) == 0)
+ {
+ if ((src->u.syment.n_value) == 0)
+ {
+ dst->symbol.section = bfd_und_section_ptr;
+ dst->symbol.value = 0;
+ }
+ else
+ {
+ dst->symbol.section = bfd_com_section_ptr;
+ dst->symbol.value = (src->u.syment.n_value);
+ }
+ }
+ else
+ {
+ /* Base the value as an index from the base of the
+ section */
+
+ dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
+
+#if defined COFF_WITH_PE
+ /* PE sets the symbol to a value relative to the
+ start of the section. */
+ dst->symbol.value = src->u.syment.n_value;
+#else
+ dst->symbol.value = (src->u.syment.n_value
+ - dst->symbol.section->vma);
+#endif
+
+ if (ISFCN ((src->u.syment.n_type)))
+ {
+ /* A function ext does not go at the end of a
+ file. */
+ dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
+ }
+ }
+
+#ifdef RS6000COFF_C
+ /* A C_HIDEXT symbol is not global. */
+ if (src->u.syment.n_sclass == C_HIDEXT)
+ dst->symbol.flags = BSF_LOCAL;
+ /* A symbol with a csect entry should not go at the end. */
+ if (src->u.syment.n_numaux > 0)
+ dst->symbol.flags |= BSF_NOT_AT_END;
+#endif
+
+#ifdef COFF_WITH_PE
+ if (src->u.syment.n_sclass == C_NT_WEAK)
+ dst->symbol.flags = BSF_WEAK;
+#endif
+
+ if (src->u.syment.n_sclass == C_WEAKEXT)
+ dst->symbol.flags = BSF_WEAK;
+
+ break;
+
+ case C_STAT: /* static */
+#ifdef I960
+ case C_LEAFSTAT: /* static leaf procedure */
+#endif
+#if defined ARM
+ case C_THUMBSTAT: /* Thumb static */
+ case C_THUMBLABEL: /* Thumb label */
+ case C_THUMBSTATFUNC:/* Thumb static function */
+#endif
+ case C_LABEL: /* label */
+ if (src->u.syment.n_scnum == -2)
+ dst->symbol.flags = BSF_DEBUGGING;
+ else
+ dst->symbol.flags = BSF_LOCAL;
+
+ /* Base the value as an index from the base of the
+ section, if there is one. */
+ if (dst->symbol.section)
+ {
+#if defined COFF_WITH_PE
+ /* PE sets the symbol to a value relative to the
+ start of the section. */
+ dst->symbol.value = src->u.syment.n_value;
+#else
+ dst->symbol.value = (src->u.syment.n_value
+ - dst->symbol.section->vma);
+#endif
+ }
+ else
+ dst->symbol.value = src->u.syment.n_value;
+ break;
+
+ case C_MOS: /* member of structure */
+ case C_EOS: /* end of structure */
+#ifdef NOTDEF /* C_AUTOARG has the same value */
+#ifdef C_GLBLREG
+ case C_GLBLREG: /* A29k-specific storage class */
+#endif
+#endif
+ case C_REGPARM: /* register parameter */
+ case C_REG: /* register variable */
+#ifndef TIC80COFF
+#ifdef C_AUTOARG
+ case C_AUTOARG: /* 960-specific storage class */
+#endif
+#endif
+ case C_TPDEF: /* type definition */
+ case C_ARG:
+ case C_AUTO: /* automatic variable */
+ case C_FIELD: /* bit field */
+ case C_ENTAG: /* enumeration tag */
+ case C_MOE: /* member of enumeration */
+ case C_MOU: /* member of union */
+ case C_UNTAG: /* union tag */
+ dst->symbol.flags = BSF_DEBUGGING;
+ dst->symbol.value = (src->u.syment.n_value);
+ break;
+
+ case C_FILE: /* file name */
+ case C_STRTAG: /* structure tag */
+#ifdef RS6000COFF_C
+ case C_GSYM:
+ case C_LSYM:
+ case C_PSYM:
+ case C_RSYM:
+ case C_RPSYM:
+ case C_STSYM:
+ case C_BCOMM:
+ case C_ECOMM:
+ case C_DECL:
+ case C_ENTRY:
+ case C_FUN:
+ case C_ESTAT:
+#endif
+ dst->symbol.flags = BSF_DEBUGGING;
+ dst->symbol.value = (src->u.syment.n_value);
+ break;
+
+#ifdef RS6000COFF_C
+ case C_BINCL: /* beginning of include file */
+ case C_EINCL: /* ending of include file */
+ /* The value is actually a pointer into the line numbers
+ of the file. We locate the line number entry, and
+ set the section to the section which contains it, and
+ the value to the index in that section. */
+ {
+ asection *sec;
+
+ dst->symbol.flags = BSF_DEBUGGING;
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ if (sec->line_filepos <= (file_ptr) src->u.syment.n_value
+ && ((file_ptr) (sec->line_filepos
+ + sec->lineno_count * LINESZ)
+ > (file_ptr) src->u.syment.n_value))
+ break;
+ if (sec == NULL)
+ dst->symbol.value = 0;
+ else
+ {
+ dst->symbol.section = sec;
+ dst->symbol.value = ((src->u.syment.n_value
+ - sec->line_filepos)
+ / LINESZ);
+ src->fix_line = 1;
+ }
+ }
+ break;
+
+ case C_BSTAT:
+ dst->symbol.flags = BSF_DEBUGGING;
+
+ /* The value is actually a symbol index. Save a pointer
+ to the symbol instead of the index. FIXME: This
+ should use a union. */
+ src->u.syment.n_value =
+ (long) (native_symbols + src->u.syment.n_value);
+ dst->symbol.value = src->u.syment.n_value;
+ src->fix_value = 1;
+ break;
+#endif
+
+ case C_BLOCK: /* ".bb" or ".eb" */
+ case C_FCN: /* ".bf" or ".ef" */
+ case C_EFCN: /* physical end of function */
+ dst->symbol.flags = BSF_LOCAL;
+#if defined COFF_WITH_PE
+ /* PE sets the symbol to a value relative to the start
+ of the section. */
+ dst->symbol.value = src->u.syment.n_value;
+#else
+ /* Base the value as an index from the base of the
+ section. */
+ dst->symbol.value = (src->u.syment.n_value
+ - dst->symbol.section->vma);
+#endif
+ break;
+
+ case C_NULL:
+ case C_EXTDEF: /* external definition */
+ case C_ULABEL: /* undefined label */
+ case C_USTATIC: /* undefined static */
+#ifndef COFF_WITH_PE
+ /* C_LINE in regular coff is 0x68. NT has taken over this storage
+ class to represent a section symbol */
+ case C_LINE: /* line # reformatted as symbol table entry */
+ /* NT uses 0x67 for a weak symbol, not C_ALIAS. */
+ case C_ALIAS: /* duplicate tag */
+#endif
+ /* New storage classes for TIc80 */
+#ifdef TIC80COFF
+ case C_UEXT: /* Tentative external definition */
+#endif
+ case C_STATLAB: /* Static load time label */
+ case C_EXTLAB: /* External load time label */
+ case C_HIDDEN: /* ext symbol in dmert public lib */
+ default:
+ (*_bfd_error_handler)
+ (_("%s: Unrecognized storage class %d for %s symbol `%s'"),
+ bfd_get_filename (abfd), src->u.syment.n_sclass,
+ dst->symbol.section->name, dst->symbol.name);
+ dst->symbol.flags = BSF_DEBUGGING;
+ dst->symbol.value = (src->u.syment.n_value);
+ break;
+ }
+
+/* BFD_ASSERT(dst->symbol.flags != 0);*/
+
+ dst->native = src;
+
+ dst->symbol.udata.i = 0;
+ dst->lineno = (alent *) NULL;
+ this_index += (src->u.syment.n_numaux) + 1;
+ dst++;
+ number_of_symbols++;
+ } /* walk the native symtab */
+ } /* bfdize the native symtab */
+
+ obj_symbols (abfd) = cached_area;
+ obj_raw_syments (abfd) = native_symbols;
+
+ bfd_get_symcount (abfd) = number_of_symbols;
+ obj_convert (abfd) = table_ptr;
+ /* Slurp the line tables for each section too */
+ {
+ asection *p;
+ p = abfd->sections;
+ while (p)
+ {
+ coff_slurp_line_table (abfd, p);
+ p = p->next;
+ }
+ }
+ return true;
+} /* coff_slurp_symbol_table() */
+
+/* Check whether a symbol is globally visible. This is used by the
+ COFF backend linker code in cofflink.c, since a couple of targets
+ have globally visible symbols which are not class C_EXT. This
+ function need not handle the case of n_class == C_EXT. */
+
+#undef OTHER_GLOBAL_CLASS
+
+#ifdef I960
+#define OTHER_GLOBAL_CLASS C_LEAFEXT
+#endif
+
+#ifdef COFFARM
+#define OTHER_GLOBAL_CLASS C_THUMBEXT || syment->n_sclass == C_THUMBEXTFUNC
+#else
+#ifdef COFF_WITH_PE
+#define OTHER_GLOBAL_CLASS C_SECTION
+#endif
+#endif
+
+#ifdef OTHER_GLOBAL_CLASS
+
+static boolean coff_sym_is_global PARAMS ((bfd *, struct internal_syment *));
+
+static boolean
+coff_sym_is_global (abfd, syment)
+ bfd * abfd;
+ struct internal_syment * syment;
+{
+ return (syment->n_sclass == OTHER_GLOBAL_CLASS);
+}
+
+#undef OTHER_GLOBAL_CLASS
+
+#else /* ! defined (OTHER_GLOBAL_CLASS) */
+
+/* sym_is_global should not be defined if it has nothing to do. */
+
+#define coff_sym_is_global 0
+
+#endif /* ! defined (OTHER_GLOBAL_CLASS) */
+
+/*
+SUBSUBSECTION
+ Reading relocations
+
+ Coff relocations are easily transformed into the internal BFD form
+ (@code{arelent}).
+
+ Reading a coff relocation table is done in the following stages:
+
+ o Read the entire coff relocation table into memory.
+
+ o Process each relocation in turn; first swap it from the
+ external to the internal form.
+
+ o Turn the symbol referenced in the relocation's symbol index
+ into a pointer into the canonical symbol table.
+ This table is the same as the one returned by a call to
+ @code{bfd_canonicalize_symtab}. The back end will call that
+ routine and save the result if a canonicalization hasn't been done.
+
+ o The reloc index is turned into a pointer to a howto
+ structure, in a back end specific way. For instance, the 386
+ and 960 use the @code{r_type} to directly produce an index
+ into a howto table vector; the 88k subtracts a number from the
+ @code{r_type} field and creates an addend field.
+
+
+*/
+
+#ifndef CALC_ADDEND
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ if (coffsym != (coff_symbol_type *) NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = 0; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != (asection *) NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ }
+#endif
+
+static boolean
+coff_slurp_reloc_table (abfd, asect, symbols)
+ bfd * abfd;
+ sec_ptr asect;
+ asymbol ** symbols;
+{
+ RELOC *native_relocs;
+ arelent *reloc_cache;
+ arelent *cache_ptr;
+
+ unsigned int idx;
+
+ if (asect->relocation)
+ return true;
+ if (asect->reloc_count == 0)
+ return true;
+ if (asect->flags & SEC_CONSTRUCTOR)
+ return true;
+ if (!coff_slurp_symbol_table (abfd))
+ return false;
+ native_relocs =
+ (RELOC *) buy_and_read (abfd,
+ asect->rel_filepos,
+ SEEK_SET,
+ (size_t) (RELSZ *
+ asect->reloc_count));
+ reloc_cache = (arelent *)
+ bfd_alloc (abfd, (size_t) (asect->reloc_count * sizeof (arelent)));
+
+ if (reloc_cache == NULL)
+ return false;
+
+
+ for (idx = 0; idx < asect->reloc_count; idx++)
+ {
+ struct internal_reloc dst;
+ struct external_reloc *src;
+#ifndef RELOC_PROCESSING
+ asymbol *ptr;
+#endif
+
+ cache_ptr = reloc_cache + idx;
+ src = native_relocs + idx;
+
+ coff_swap_reloc_in (abfd, src, &dst);
+
+#ifdef RELOC_PROCESSING
+ RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect);
+#else
+ cache_ptr->address = dst.r_vaddr;
+
+ if (dst.r_symndx != -1)
+ {
+ if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: illegal symbol index %ld in relocs"),
+ bfd_get_filename (abfd), dst.r_symndx);
+ cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ ptr = NULL;
+ }
+ else
+ {
+ cache_ptr->sym_ptr_ptr = (symbols
+ + obj_convert (abfd)[dst.r_symndx]);
+ ptr = *(cache_ptr->sym_ptr_ptr);
+ }
+ }
+ else
+ {
+ cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ ptr = NULL;
+ }
+
+ /* The symbols definitions that we have read in have been
+ relocated as if their sections started at 0. But the offsets
+ refering to the symbols in the raw data have not been
+ modified, so we have to have a negative addend to compensate.
+
+ Note that symbols which used to be common must be left alone */
+
+ /* Calculate any reloc addend by looking at the symbol */
+ CALC_ADDEND (abfd, ptr, dst, cache_ptr);
+
+ cache_ptr->address -= asect->vma;
+/* !! cache_ptr->section = (asection *) NULL;*/
+
+ /* Fill in the cache_ptr->howto field from dst.r_type */
+ RTYPE2HOWTO (cache_ptr, &dst);
+#endif /* RELOC_PROCESSING */
+
+ if (cache_ptr->howto == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: illegal relocation type %d at address 0x%lx"),
+ bfd_get_filename (abfd), dst.r_type, (long) dst.r_vaddr);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ asect->relocation = reloc_cache;
+ return true;
+}
+
+#ifndef coff_rtype_to_howto
+#ifdef RTYPE2HOWTO
+
+/* Get the howto structure for a reloc. This is only used if the file
+ including this one defines coff_relocate_section to be
+ _bfd_coff_generic_relocate_section, so it is OK if it does not
+ always work. It is the responsibility of the including file to
+ make sure it is reasonable if it is needed. */
+
+static reloc_howto_type *coff_rtype_to_howto
+ PARAMS ((bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *));
+
+/*ARGSUSED*/
+static reloc_howto_type *
+coff_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
+ bfd *abfd;
+ asection *sec;
+ struct internal_reloc *rel;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma *addendp;
+{
+ arelent genrel;
+
+ RTYPE2HOWTO (&genrel, rel);
+ return genrel.howto;
+}
+
+#else /* ! defined (RTYPE2HOWTO) */
+
+#define coff_rtype_to_howto NULL
+
+#endif /* ! defined (RTYPE2HOWTO) */
+#endif /* ! defined (coff_rtype_to_howto) */
+
+/* This is stupid. This function should be a boolean predicate. */
+static long
+coff_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd * abfd;
+ sec_ptr section;
+ arelent ** relptr;
+ asymbol ** symbols;
+{
+ arelent *tblptr = section->relocation;
+ unsigned int count = 0;
+
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ /* this section has relocs made up by us, they are not in the
+ file, so take them out of their chain and place them into
+ the data area provided */
+ arelent_chain *chain = section->constructor_chain;
+ for (count = 0; count < section->reloc_count; count++)
+ {
+ *relptr++ = &chain->relent;
+ chain = chain->next;
+ }
+
+ }
+ else
+ {
+ if (! coff_slurp_reloc_table (abfd, section, symbols))
+ return -1;
+
+ tblptr = section->relocation;
+
+ for (; count++ < section->reloc_count;)
+ *relptr++ = tblptr++;
+
+
+ }
+ *relptr = 0;
+ return section->reloc_count;
+}
+
+#ifdef GNU960
+file_ptr
+coff_sym_filepos (abfd)
+ bfd *abfd;
+{
+ return obj_sym_filepos (abfd);
+}
+#endif
+
+#ifndef coff_reloc16_estimate
+#define coff_reloc16_estimate dummy_reloc16_estimate
+
+static int dummy_reloc16_estimate
+ PARAMS ((bfd *, asection *, arelent *, unsigned int,
+ struct bfd_link_info *));
+
+static int
+dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info)
+ bfd *abfd;
+ asection *input_section;
+ arelent *reloc;
+ unsigned int shrink;
+ struct bfd_link_info *link_info;
+{
+ abort ();
+}
+
+#endif
+
+#ifndef coff_reloc16_extra_cases
+
+#define coff_reloc16_extra_cases dummy_reloc16_extra_cases
+
+/* This works even if abort is not declared in any header file. */
+
+static void dummy_reloc16_extra_cases
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+ bfd_byte *, unsigned int *, unsigned int *));
+
+static void
+dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr,
+ dst_ptr)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ arelent *reloc;
+ bfd_byte *data;
+ unsigned int *src_ptr;
+ unsigned int *dst_ptr;
+{
+ abort ();
+}
+#endif
+
+/* If coff_relocate_section is defined, we can use the optimized COFF
+ backend linker. Otherwise we must continue to use the old linker. */
+#ifdef coff_relocate_section
+#ifndef coff_bfd_link_hash_table_create
+#define coff_bfd_link_hash_table_create _bfd_coff_link_hash_table_create
+#endif
+#ifndef coff_bfd_link_add_symbols
+#define coff_bfd_link_add_symbols _bfd_coff_link_add_symbols
+#endif
+#ifndef coff_bfd_final_link
+#define coff_bfd_final_link _bfd_coff_final_link
+#endif
+#else /* ! defined (coff_relocate_section) */
+#define coff_relocate_section NULL
+#ifndef coff_bfd_link_hash_table_create
+#define coff_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#endif
+#ifndef coff_bfd_link_add_symbols
+#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#endif
+#define coff_bfd_final_link _bfd_generic_final_link
+#endif /* ! defined (coff_relocate_section) */
+
+#define coff_bfd_link_split_section _bfd_generic_link_split_section
+
+#ifndef coff_start_final_link
+#define coff_start_final_link NULL
+#endif
+
+#ifndef coff_adjust_symndx
+#define coff_adjust_symndx NULL
+#endif
+
+#ifndef coff_link_add_one_symbol
+#define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol
+#endif
+
+#ifndef coff_link_output_has_begun
+
+static boolean coff_link_output_has_begun
+ PARAMS ((bfd *, struct coff_final_link_info *));
+
+static boolean
+coff_link_output_has_begun (abfd, info)
+ bfd * abfd;
+ struct coff_final_link_info * info;
+{
+ return abfd->output_has_begun;
+}
+#endif
+
+#ifndef coff_final_link_postscript
+
+static boolean coff_final_link_postscript
+ PARAMS ((bfd *, struct coff_final_link_info *));
+
+static boolean
+coff_final_link_postscript (abfd, pfinfo)
+ bfd * abfd;
+ struct coff_final_link_info * pfinfo;
+{
+ return true;
+}
+#endif
+
+#ifndef coff_SWAP_aux_in
+#define coff_SWAP_aux_in coff_swap_aux_in
+#endif
+#ifndef coff_SWAP_sym_in
+#define coff_SWAP_sym_in coff_swap_sym_in
+#endif
+#ifndef coff_SWAP_lineno_in
+#define coff_SWAP_lineno_in coff_swap_lineno_in
+#endif
+#ifndef coff_SWAP_aux_out
+#define coff_SWAP_aux_out coff_swap_aux_out
+#endif
+#ifndef coff_SWAP_sym_out
+#define coff_SWAP_sym_out coff_swap_sym_out
+#endif
+#ifndef coff_SWAP_lineno_out
+#define coff_SWAP_lineno_out coff_swap_lineno_out
+#endif
+#ifndef coff_SWAP_reloc_out
+#define coff_SWAP_reloc_out coff_swap_reloc_out
+#endif
+#ifndef coff_SWAP_filehdr_out
+#define coff_SWAP_filehdr_out coff_swap_filehdr_out
+#endif
+#ifndef coff_SWAP_aouthdr_out
+#define coff_SWAP_aouthdr_out coff_swap_aouthdr_out
+#endif
+#ifndef coff_SWAP_scnhdr_out
+#define coff_SWAP_scnhdr_out coff_swap_scnhdr_out
+#endif
+#ifndef coff_SWAP_reloc_in
+#define coff_SWAP_reloc_in coff_swap_reloc_in
+#endif
+#ifndef coff_SWAP_filehdr_in
+#define coff_SWAP_filehdr_in coff_swap_filehdr_in
+#endif
+#ifndef coff_SWAP_aouthdr_in
+#define coff_SWAP_aouthdr_in coff_swap_aouthdr_in
+#endif
+#ifndef coff_SWAP_scnhdr_in
+#define coff_SWAP_scnhdr_in coff_swap_scnhdr_in
+#endif
+
+
+
+static CONST bfd_coff_backend_data bfd_coff_std_swap_table =
+{
+ coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
+ coff_SWAP_aux_out, coff_SWAP_sym_out,
+ coff_SWAP_lineno_out, coff_SWAP_reloc_out,
+ coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out,
+ coff_SWAP_scnhdr_out,
+ FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ,
+#ifdef COFF_LONG_FILENAMES
+ true,
+#else
+ false,
+#endif
+#ifdef COFF_LONG_SECTION_NAMES
+ true,
+#else
+ false,
+#endif
+ COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
+ coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
+ coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
+ coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
+ coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
+ coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
+ coff_sym_is_global, coff_compute_section_file_positions,
+ coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
+ coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_link_output_has_begun, coff_final_link_postscript
+};
+
+#ifndef coff_close_and_cleanup
+#define coff_close_and_cleanup _bfd_generic_close_and_cleanup
+#endif
+
+#ifndef coff_bfd_free_cached_info
+#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#endif
+
+#ifndef coff_get_section_contents
+#define coff_get_section_contents _bfd_generic_get_section_contents
+#endif
+
+#ifndef coff_bfd_copy_private_symbol_data
+#define coff_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#endif
+
+#ifndef coff_bfd_copy_private_section_data
+#define coff_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
+#endif
+
+#ifndef coff_bfd_copy_private_bfd_data
+#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#endif
+
+#ifndef coff_bfd_merge_private_bfd_data
+#define coff_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#endif
+
+#ifndef coff_bfd_set_private_flags
+#define coff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#endif
+
+#ifndef coff_bfd_print_private_bfd_data
+#define coff_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+#endif
+
+#ifndef coff_bfd_is_local_label_name
+#define coff_bfd_is_local_label_name _bfd_coff_is_local_label_name
+#endif
+
+#ifndef coff_read_minisymbols
+#define coff_read_minisymbols _bfd_generic_read_minisymbols
+#endif
+
+#ifndef coff_minisymbol_to_symbol
+#define coff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#endif
+
+/* The reloc lookup routine must be supplied by each individual COFF
+ backend. */
+#ifndef coff_bfd_reloc_type_lookup
+#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+#endif
+
+#ifndef coff_bfd_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#endif
+
+#ifndef coff_bfd_relax_section
+#define coff_bfd_relax_section bfd_generic_relax_section
+#endif
+
+#ifndef coff_bfd_gc_sections
+#define coff_bfd_gc_sections bfd_generic_gc_sections
+#endif
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
new file mode 100644
index 00000000000..df413833bd3
--- /dev/null
+++ b/bfd/coffgen.c
@@ -0,0 +1,2378 @@
+/* Support for the generic parts of COFF, for BFD.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Most of this hacked by Steve Chamberlain, sac@cygnus.com.
+ Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */
+
+/* This file contains COFF code that is not dependent on any
+ particular COFF target. There is only one version of this file in
+ libbfd.a, so no target specific code may be put in here. Or, to
+ put it another way,
+
+ ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE **********
+
+ If you need to add some target specific behaviour, add a new hook
+ function to bfd_coff_backend_data.
+
+ Some of these functions are also called by the ECOFF routines.
+ Those functions may not use any COFF specific information, such as
+ coff_data (abfd). */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+static void coff_fix_symbol_name
+ PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_size_type *,
+ asection **, bfd_size_type *));
+static boolean coff_write_symbol
+ PARAMS ((bfd *, asymbol *, combined_entry_type *, unsigned int *,
+ bfd_size_type *, asection **, bfd_size_type *));
+static boolean coff_write_alien_symbol
+ PARAMS ((bfd *, asymbol *, unsigned int *, bfd_size_type *,
+ asection **, bfd_size_type *));
+static boolean coff_write_native_symbol
+ PARAMS ((bfd *, coff_symbol_type *, unsigned int *, bfd_size_type *,
+ asection **, bfd_size_type *));
+static void coff_pointerize_aux
+ PARAMS ((bfd *, combined_entry_type *, combined_entry_type *,
+ unsigned int, combined_entry_type *));
+static boolean make_a_section_from_file
+ PARAMS ((bfd *, struct internal_scnhdr *, unsigned int));
+static const bfd_target *coff_real_object_p
+ PARAMS ((bfd *, unsigned, struct internal_filehdr *,
+ struct internal_aouthdr *));
+static void fixup_symbol_value
+ PARAMS ((bfd *, coff_symbol_type *, struct internal_syment *));
+static char *build_debug_section
+ PARAMS ((bfd *));
+static char *copy_name
+ PARAMS ((bfd *, char *, int));
+
+#define STRING_SIZE_SIZE (4)
+
+/* Take a section header read from a coff file (in HOST byte order),
+ and make a BFD "section" out of it. This is used by ECOFF. */
+static boolean
+make_a_section_from_file (abfd, hdr, target_index)
+ bfd *abfd;
+ struct internal_scnhdr *hdr;
+ unsigned int target_index;
+{
+ asection *return_section;
+ char *name;
+
+ name = NULL;
+
+ /* Handle long section names as in PE. */
+ if (bfd_coff_long_section_names (abfd)
+ && hdr->s_name[0] == '/')
+ {
+ char buf[SCNNMLEN];
+ long strindex;
+ char *p;
+ const char *strings;
+
+ memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
+ buf[SCNNMLEN - 1] = '\0';
+ strindex = strtol (buf, &p, 10);
+ if (*p == '\0' && strindex >= 0)
+ {
+ strings = _bfd_coff_read_string_table (abfd);
+ if (strings == NULL)
+ return false;
+ /* FIXME: For extra safety, we should make sure that
+ strindex does not run us past the end, but right now we
+ don't know the length of the string table. */
+ strings += strindex;
+ name = bfd_alloc (abfd, strlen (strings) + 1);
+ if (name == NULL)
+ return false;
+ strcpy (name, strings);
+ }
+ }
+
+ if (name == NULL)
+ {
+ /* Assorted wastage to null-terminate the name, thanks AT&T! */
+ name = bfd_alloc (abfd, sizeof (hdr->s_name) + 1);
+ if (name == NULL)
+ return false;
+ strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
+ name[sizeof (hdr->s_name)] = 0;
+ }
+
+ return_section = bfd_make_section_anyway (abfd, name);
+ if (return_section == NULL)
+ return false;
+
+ return_section->vma = hdr->s_vaddr;
+ return_section->lma = hdr->s_paddr;
+ return_section->_raw_size = hdr->s_size;
+ return_section->filepos = hdr->s_scnptr;
+ return_section->rel_filepos = hdr->s_relptr;
+ return_section->reloc_count = hdr->s_nreloc;
+
+ bfd_coff_set_alignment_hook (abfd, return_section, hdr);
+
+ return_section->line_filepos = hdr->s_lnnoptr;
+
+ return_section->lineno_count = hdr->s_nlnno;
+ return_section->userdata = NULL;
+ return_section->next = (asection *) NULL;
+ return_section->flags = bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name);
+
+ return_section->target_index = target_index;
+
+ /* At least on i386-coff, the line number count for a shared library
+ section must be ignored. */
+ if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
+ return_section->lineno_count = 0;
+
+ if (hdr->s_nreloc != 0)
+ return_section->flags |= SEC_RELOC;
+ /* FIXME: should this check 'hdr->s_size > 0' */
+ if (hdr->s_scnptr != 0)
+ return_section->flags |= SEC_HAS_CONTENTS;
+ return true;
+}
+
+/* Read in a COFF object and make it into a BFD. This is used by
+ ECOFF as well. */
+
+static const bfd_target *
+coff_real_object_p (abfd, nscns, internal_f, internal_a)
+ bfd *abfd;
+ unsigned nscns;
+ struct internal_filehdr *internal_f;
+ struct internal_aouthdr *internal_a;
+{
+ flagword oflags = abfd->flags;
+ bfd_vma ostart = bfd_get_start_address (abfd);
+ PTR tdata;
+ size_t readsize; /* length of file_info */
+ unsigned int scnhsz;
+ char *external_sections;
+
+ if (!(internal_f->f_flags & F_RELFLG))
+ abfd->flags |= HAS_RELOC;
+ if ((internal_f->f_flags & F_EXEC))
+ abfd->flags |= EXEC_P;
+ if (!(internal_f->f_flags & F_LNNO))
+ abfd->flags |= HAS_LINENO;
+ if (!(internal_f->f_flags & F_LSYMS))
+ abfd->flags |= HAS_LOCALS;
+
+ /* FIXME: How can we set D_PAGED correctly? */
+ if ((internal_f->f_flags & F_EXEC) != 0)
+ abfd->flags |= D_PAGED;
+
+ bfd_get_symcount (abfd) = internal_f->f_nsyms;
+ if (internal_f->f_nsyms)
+ abfd->flags |= HAS_SYMS;
+
+ if (internal_a != (struct internal_aouthdr *) NULL)
+ bfd_get_start_address (abfd) = internal_a->entry;
+ else
+ bfd_get_start_address (abfd) = 0;
+
+ /* Set up the tdata area. ECOFF uses its own routine, and overrides
+ abfd->flags. */
+ tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a);
+ if (tdata == NULL)
+ return 0;
+
+ scnhsz = bfd_coff_scnhsz (abfd);
+ readsize = nscns * scnhsz;
+ external_sections = (char *) bfd_alloc (abfd, readsize);
+ if (!external_sections)
+ goto fail;
+
+ if (bfd_read ((PTR) external_sections, 1, readsize, abfd) != readsize)
+ goto fail;
+
+ /* Now copy data as required; construct all asections etc */
+ if (nscns != 0)
+ {
+ unsigned int i;
+ for (i = 0; i < nscns; i++)
+ {
+ struct internal_scnhdr tmp;
+ bfd_coff_swap_scnhdr_in (abfd,
+ (PTR) (external_sections + i * scnhsz),
+ (PTR) & tmp);
+ if (! make_a_section_from_file (abfd, &tmp, i + 1))
+ goto fail;
+ }
+ }
+
+ /* make_abs_section (abfd); */
+
+ if (bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f) == false)
+ goto fail;
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, tdata);
+ abfd->flags = oflags;
+ bfd_get_start_address (abfd) = ostart;
+ return (const bfd_target *) NULL;
+}
+
+/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is
+ not a COFF file. This is also used by ECOFF. */
+
+const bfd_target *
+coff_object_p (abfd)
+ bfd *abfd;
+{
+ unsigned int filhsz;
+ unsigned int aoutsz;
+ int nscns;
+ PTR filehdr;
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
+
+ /* figure out how much to read */
+ filhsz = bfd_coff_filhsz (abfd);
+ aoutsz = bfd_coff_aoutsz (abfd);
+
+ filehdr = bfd_alloc (abfd, filhsz);
+ if (filehdr == NULL)
+ return 0;
+ if (bfd_read (filehdr, 1, filhsz, abfd) != filhsz)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
+ bfd_release (abfd, filehdr);
+
+ if (bfd_coff_bad_format_hook (abfd, &internal_f) == false)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ nscns = internal_f.f_nscns;
+
+ if (internal_f.f_opthdr)
+ {
+ PTR opthdr;
+
+ opthdr = bfd_alloc (abfd, aoutsz);
+ if (opthdr == NULL)
+ return 0;;
+ if (bfd_read (opthdr, 1, internal_f.f_opthdr, abfd)
+ != internal_f.f_opthdr)
+ {
+ return 0;
+ }
+ bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a);
+ }
+
+ return coff_real_object_p (abfd, nscns, &internal_f,
+ (internal_f.f_opthdr != 0
+ ? &internal_a
+ : (struct internal_aouthdr *) NULL));
+}
+
+/* Get the BFD section from a COFF symbol section number. */
+
+asection *
+coff_section_from_bfd_index (abfd, index)
+ bfd *abfd;
+ int index;
+{
+ struct sec *answer = abfd->sections;
+
+ if (index == N_ABS)
+ return bfd_abs_section_ptr;
+ if (index == N_UNDEF)
+ return bfd_und_section_ptr;
+ if (index == N_DEBUG)
+ return bfd_abs_section_ptr;
+
+ while (answer)
+ {
+ if (answer->target_index == index)
+ return answer;
+ answer = answer->next;
+ }
+
+ /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a
+ has a bad symbol table in biglitpow.o. */
+ return bfd_und_section_ptr;
+}
+
+/* Get the upper bound of a COFF symbol table. */
+
+long
+coff_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ if (!bfd_coff_slurp_symbol_table (abfd))
+ return -1;
+
+ return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *));
+}
+
+
+/* Canonicalize a COFF symbol table. */
+
+long
+coff_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ unsigned int counter;
+ coff_symbol_type *symbase;
+ coff_symbol_type **location = (coff_symbol_type **) alocation;
+
+ if (!bfd_coff_slurp_symbol_table (abfd))
+ return -1;
+
+ symbase = obj_symbols (abfd);
+ counter = bfd_get_symcount (abfd);
+ while (counter-- > 0)
+ *location++ = symbase++;
+
+ *location = NULL;
+
+ return bfd_get_symcount (abfd);
+}
+
+/* Get the name of a symbol. The caller must pass in a buffer of size
+ >= SYMNMLEN + 1. */
+
+const char *
+_bfd_coff_internal_syment_name (abfd, sym, buf)
+ bfd *abfd;
+ const struct internal_syment *sym;
+ char *buf;
+{
+ /* FIXME: It's not clear this will work correctly if sizeof
+ (_n_zeroes) != 4. */
+ if (sym->_n._n_n._n_zeroes != 0
+ || sym->_n._n_n._n_offset == 0)
+ {
+ memcpy (buf, sym->_n._n_name, SYMNMLEN);
+ buf[SYMNMLEN] = '\0';
+ return buf;
+ }
+ else
+ {
+ const char *strings;
+
+ BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE);
+ strings = obj_coff_strings (abfd);
+ if (strings == NULL)
+ {
+ strings = _bfd_coff_read_string_table (abfd);
+ if (strings == NULL)
+ return NULL;
+ }
+ return strings + sym->_n._n_n._n_offset;
+ }
+}
+
+/* Read in and swap the relocs. This returns a buffer holding the
+ relocs for section SEC in file ABFD. If CACHE is true and
+ INTERNAL_RELOCS is NULL, the relocs read in will be saved in case
+ the function is called again. If EXTERNAL_RELOCS is not NULL, it
+ is a buffer large enough to hold the unswapped relocs. If
+ INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold
+ the swapped relocs. If REQUIRE_INTERNAL is true, then the return
+ value must be INTERNAL_RELOCS. The function returns NULL on error. */
+
+struct internal_reloc *
+_bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs,
+ require_internal, internal_relocs)
+ bfd *abfd;
+ asection *sec;
+ boolean cache;
+ bfd_byte *external_relocs;
+ boolean require_internal;
+ struct internal_reloc *internal_relocs;
+{
+ bfd_size_type relsz;
+ bfd_byte *free_external = NULL;
+ struct internal_reloc *free_internal = NULL;
+ bfd_byte *erel;
+ bfd_byte *erel_end;
+ struct internal_reloc *irel;
+
+ if (coff_section_data (abfd, sec) != NULL
+ && coff_section_data (abfd, sec)->relocs != NULL)
+ {
+ if (! require_internal)
+ return coff_section_data (abfd, sec)->relocs;
+ memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs,
+ sec->reloc_count * sizeof (struct internal_reloc));
+ return internal_relocs;
+ }
+
+ relsz = bfd_coff_relsz (abfd);
+
+ if (external_relocs == NULL)
+ {
+ free_external = (bfd_byte *) bfd_malloc (sec->reloc_count * relsz);
+ if (free_external == NULL && sec->reloc_count > 0)
+ goto error_return;
+ external_relocs = free_external;
+ }
+
+ if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
+ || (bfd_read (external_relocs, relsz, sec->reloc_count, abfd)
+ != relsz * sec->reloc_count))
+ goto error_return;
+
+ if (internal_relocs == NULL)
+ {
+ free_internal = ((struct internal_reloc *)
+ bfd_malloc (sec->reloc_count
+ * sizeof (struct internal_reloc)));
+ if (free_internal == NULL && sec->reloc_count > 0)
+ goto error_return;
+ internal_relocs = free_internal;
+ }
+
+ /* Swap in the relocs. */
+ erel = external_relocs;
+ erel_end = erel + relsz * sec->reloc_count;
+ irel = internal_relocs;
+ for (; erel < erel_end; erel += relsz, irel++)
+ bfd_coff_swap_reloc_in (abfd, (PTR) erel, (PTR) irel);
+
+ if (free_external != NULL)
+ {
+ free (free_external);
+ free_external = NULL;
+ }
+
+ if (cache && free_internal != NULL)
+ {
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ sec->used_by_bfd =
+ (PTR) bfd_zalloc (abfd,
+ sizeof (struct coff_section_tdata));
+ if (sec->used_by_bfd == NULL)
+ goto error_return;
+ coff_section_data (abfd, sec)->contents = NULL;
+ }
+ coff_section_data (abfd, sec)->relocs = free_internal;
+ }
+
+ return internal_relocs;
+
+ error_return:
+ if (free_external != NULL)
+ free (free_external);
+ if (free_internal != NULL)
+ free (free_internal);
+ return NULL;
+}
+
+/* Set lineno_count for the output sections of a COFF file. */
+
+int
+coff_count_linenumbers (abfd)
+ bfd *abfd;
+{
+ unsigned int limit = bfd_get_symcount (abfd);
+ unsigned int i;
+ int total = 0;
+ asymbol **p;
+ asection *s;
+
+ if (limit == 0)
+ {
+ /* This may be from the backend linker, in which case the
+ lineno_count in the sections is correct. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ total += s->lineno_count;
+ return total;
+ }
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ BFD_ASSERT (s->lineno_count == 0);
+
+ for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
+ {
+ asymbol *q_maybe = *p;
+
+ if (bfd_asymbol_flavour (q_maybe) == bfd_target_coff_flavour)
+ {
+ coff_symbol_type *q = coffsymbol (q_maybe);
+
+ /* The AIX 4.1 compiler can sometimes generate line numbers
+ attached to debugging symbols. We try to simply ignore
+ those here. */
+ if (q->lineno != NULL
+ && q->symbol.section->owner != NULL)
+ {
+ /* This symbol has line numbers. Increment the owning
+ section's linenumber count. */
+ alent *l = q->lineno;
+
+ ++q->symbol.section->output_section->lineno_count;
+ ++total;
+ ++l;
+ while (l->line_number != 0)
+ {
+ ++total;
+ ++q->symbol.section->output_section->lineno_count;
+ ++l;
+ }
+ }
+ }
+ }
+
+ return total;
+}
+
+/* Takes a bfd and a symbol, returns a pointer to the coff specific
+ area of the symbol if there is one. */
+
+/*ARGSUSED*/
+coff_symbol_type *
+coff_symbol_from (ignore_abfd, symbol)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+{
+ if (bfd_asymbol_flavour (symbol) != bfd_target_coff_flavour)
+ return (coff_symbol_type *) NULL;
+
+ if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL)
+ return (coff_symbol_type *) NULL;
+
+ return (coff_symbol_type *) symbol;
+}
+
+static void
+fixup_symbol_value (abfd, coff_symbol_ptr, syment)
+ bfd *abfd;
+ coff_symbol_type *coff_symbol_ptr;
+ struct internal_syment *syment;
+{
+
+ /* Normalize the symbol flags */
+ if (bfd_is_com_section (coff_symbol_ptr->symbol.section))
+ {
+ /* a common symbol is undefined with a value */
+ syment->n_scnum = N_UNDEF;
+ syment->n_value = coff_symbol_ptr->symbol.value;
+ }
+ else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING)
+ {
+ syment->n_value = coff_symbol_ptr->symbol.value;
+ }
+ else if (bfd_is_und_section (coff_symbol_ptr->symbol.section))
+ {
+ syment->n_scnum = N_UNDEF;
+ syment->n_value = 0;
+ }
+ else
+ {
+ if (coff_symbol_ptr->symbol.section)
+ {
+ syment->n_scnum =
+ coff_symbol_ptr->symbol.section->output_section->target_index;
+
+ syment->n_value = (coff_symbol_ptr->symbol.value
+ + coff_symbol_ptr->symbol.section->output_offset);
+ if (! obj_pe (abfd))
+ syment->n_value +=
+ coff_symbol_ptr->symbol.section->output_section->vma;
+ }
+ else
+ {
+ BFD_ASSERT (0);
+ /* This can happen, but I don't know why yet (steve@cygnus.com) */
+ syment->n_scnum = N_ABS;
+ syment->n_value = coff_symbol_ptr->symbol.value;
+ }
+ }
+}
+
+/* Run through all the symbols in the symbol table and work out what
+ their indexes into the symbol table will be when output.
+
+ Coff requires that each C_FILE symbol points to the next one in the
+ chain, and that the last one points to the first external symbol. We
+ do that here too. */
+
+boolean
+coff_renumber_symbols (bfd_ptr, first_undef)
+ bfd *bfd_ptr;
+ int *first_undef;
+{
+ unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
+ asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
+ unsigned int native_index = 0;
+ struct internal_syment *last_file = (struct internal_syment *) NULL;
+ unsigned int symbol_index;
+
+ /* COFF demands that undefined symbols come after all other symbols.
+ Since we don't need to impose this extra knowledge on all our
+ client programs, deal with that here. Sort the symbol table;
+ just move the undefined symbols to the end, leaving the rest
+ alone. The O'Reilly book says that defined global symbols come
+ at the end before the undefined symbols, so we do that here as
+ well. */
+ /* @@ Do we have some condition we could test for, so we don't always
+ have to do this? I don't think relocatability is quite right, but
+ I'm not certain. [raeburn:19920508.1711EST] */
+ {
+ asymbol **newsyms;
+ unsigned int i;
+
+ newsyms = (asymbol **) bfd_alloc (bfd_ptr,
+ sizeof (asymbol *) * (symbol_count + 1));
+ if (!newsyms)
+ return false;
+ bfd_ptr->outsymbols = newsyms;
+ for (i = 0; i < symbol_count; i++)
+ if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
+ || (!bfd_is_und_section (symbol_ptr_ptr[i]->section)
+ && !bfd_is_com_section (symbol_ptr_ptr[i]->section)
+ && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0
+ || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
+ == 0))))
+ *newsyms++ = symbol_ptr_ptr[i];
+
+ for (i = 0; i < symbol_count; i++)
+ if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
+ && !bfd_is_und_section (symbol_ptr_ptr[i]->section)
+ && (bfd_is_com_section (symbol_ptr_ptr[i]->section)
+ || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0
+ && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
+ != 0))))
+ *newsyms++ = symbol_ptr_ptr[i];
+
+ *first_undef = newsyms - bfd_ptr->outsymbols;
+
+ for (i = 0; i < symbol_count; i++)
+ if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
+ && bfd_is_und_section (symbol_ptr_ptr[i]->section))
+ *newsyms++ = symbol_ptr_ptr[i];
+ *newsyms = (asymbol *) NULL;
+ symbol_ptr_ptr = bfd_ptr->outsymbols;
+ }
+
+ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
+ {
+ coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
+ symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
+ if (coff_symbol_ptr && coff_symbol_ptr->native)
+ {
+ combined_entry_type *s = coff_symbol_ptr->native;
+ int i;
+
+ if (s->u.syment.n_sclass == C_FILE)
+ {
+ if (last_file != (struct internal_syment *) NULL)
+ last_file->n_value = native_index;
+ last_file = &(s->u.syment);
+ }
+ else
+ {
+
+ /* Modify the symbol values according to their section and
+ type */
+
+ fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment));
+ }
+ for (i = 0; i < s->u.syment.n_numaux + 1; i++)
+ s[i].offset = native_index++;
+ }
+ else
+ {
+ native_index++;
+ }
+ }
+ obj_conv_table_size (bfd_ptr) = native_index;
+
+ return true;
+}
+
+/* Run thorough the symbol table again, and fix it so that all
+ pointers to entries are changed to the entries' index in the output
+ symbol table. */
+
+void
+coff_mangle_symbols (bfd_ptr)
+ bfd *bfd_ptr;
+{
+ unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
+ asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
+ unsigned int symbol_index;
+
+ for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
+ {
+ coff_symbol_type *coff_symbol_ptr =
+ coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
+
+ if (coff_symbol_ptr && coff_symbol_ptr->native)
+ {
+ int i;
+ combined_entry_type *s = coff_symbol_ptr->native;
+
+ if (s->fix_value)
+ {
+ /* FIXME: We should use a union here. */
+ s->u.syment.n_value =
+ ((combined_entry_type *) s->u.syment.n_value)->offset;
+ s->fix_value = 0;
+ }
+ if (s->fix_line)
+ {
+ /* The value is the offset into the line number entries
+ for the symbol's section. On output, the symbol's
+ section should be N_DEBUG. */
+ s->u.syment.n_value =
+ (coff_symbol_ptr->symbol.section->output_section->line_filepos
+ + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr));
+ coff_symbol_ptr->symbol.section =
+ coff_section_from_bfd_index (bfd_ptr, N_DEBUG);
+ BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING);
+ }
+ for (i = 0; i < s->u.syment.n_numaux; i++)
+ {
+ combined_entry_type *a = s + i + 1;
+ if (a->fix_tag)
+ {
+ a->u.auxent.x_sym.x_tagndx.l =
+ a->u.auxent.x_sym.x_tagndx.p->offset;
+ a->fix_tag = 0;
+ }
+ if (a->fix_end)
+ {
+ a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
+ a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
+ a->fix_end = 0;
+ }
+ if (a->fix_scnlen)
+ {
+ a->u.auxent.x_csect.x_scnlen.l =
+ a->u.auxent.x_csect.x_scnlen.p->offset;
+ a->fix_scnlen = 0;
+ }
+ }
+ }
+ }
+}
+
+static void
+coff_fix_symbol_name (abfd, symbol, native, string_size_p,
+ debug_string_section_p, debug_string_size_p)
+ bfd *abfd;
+ asymbol *symbol;
+ combined_entry_type *native;
+ bfd_size_type *string_size_p;
+ asection **debug_string_section_p;
+ bfd_size_type *debug_string_size_p;
+{
+ unsigned int name_length;
+ union internal_auxent *auxent;
+ char *name = (char *) (symbol->name);
+
+ if (name == (char *) NULL)
+ {
+ /* coff symbols always have names, so we'll make one up */
+ symbol->name = "strange";
+ name = (char *) symbol->name;
+ }
+ name_length = strlen (name);
+
+ if (native->u.syment.n_sclass == C_FILE
+ && native->u.syment.n_numaux > 0)
+ {
+ strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
+ auxent = &(native + 1)->u.auxent;
+
+ if (bfd_coff_long_filenames (abfd))
+ {
+ if (name_length <= FILNMLEN)
+ {
+ strncpy (auxent->x_file.x_fname, name, FILNMLEN);
+ }
+ else
+ {
+ auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
+ auxent->x_file.x_n.x_zeroes = 0;
+ *string_size_p += name_length + 1;
+ }
+ }
+ else
+ {
+ strncpy (auxent->x_file.x_fname, name, FILNMLEN);
+ if (name_length > FILNMLEN)
+ {
+ name[FILNMLEN] = '\0';
+ }
+ }
+ }
+ else
+ {
+ if (name_length <= SYMNMLEN)
+ {
+ /* This name will fit into the symbol neatly */
+ strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN);
+ }
+ else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment))
+ {
+ native->u.syment._n._n_n._n_offset = (*string_size_p
+ + STRING_SIZE_SIZE);
+ native->u.syment._n._n_n._n_zeroes = 0;
+ *string_size_p += name_length + 1;
+ }
+ else
+ {
+ long filepos;
+ bfd_byte buf[2];
+
+ /* This name should be written into the .debug section. For
+ some reason each name is preceded by a two byte length
+ and also followed by a null byte. FIXME: We assume that
+ the .debug section has already been created, and that it
+ is large enough. */
+ if (*debug_string_section_p == (asection *) NULL)
+ *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug");
+ filepos = bfd_tell (abfd);
+ bfd_put_16 (abfd, name_length + 1, buf);
+ if (!bfd_set_section_contents (abfd,
+ *debug_string_section_p,
+ (PTR) buf,
+ (file_ptr) *debug_string_size_p,
+ (bfd_size_type) 2)
+ || !bfd_set_section_contents (abfd,
+ *debug_string_section_p,
+ (PTR) symbol->name,
+ ((file_ptr) *debug_string_size_p
+ + 2),
+ (bfd_size_type) name_length + 1))
+ abort ();
+ if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ abort ();
+ native->u.syment._n._n_n._n_offset = *debug_string_size_p + 2;
+ native->u.syment._n._n_n._n_zeroes = 0;
+ *debug_string_size_p += name_length + 3;
+ }
+ }
+}
+
+/* We need to keep track of the symbol index so that when we write out
+ the relocs we can get the index for a symbol. This method is a
+ hack. FIXME. */
+
+#define set_index(symbol, idx) ((symbol)->udata.i = (idx))
+
+/* Write a symbol out to a COFF file. */
+
+static boolean
+coff_write_symbol (abfd, symbol, native, written, string_size_p,
+ debug_string_section_p, debug_string_size_p)
+ bfd *abfd;
+ asymbol *symbol;
+ combined_entry_type *native;
+ unsigned int *written;
+ bfd_size_type *string_size_p;
+ asection **debug_string_section_p;
+ bfd_size_type *debug_string_size_p;
+{
+ unsigned int numaux = native->u.syment.n_numaux;
+ int type = native->u.syment.n_type;
+ int class = native->u.syment.n_sclass;
+ PTR buf;
+ bfd_size_type symesz;
+
+ if (native->u.syment.n_sclass == C_FILE)
+ symbol->flags |= BSF_DEBUGGING;
+
+ if (symbol->flags & BSF_DEBUGGING
+ && bfd_is_abs_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_DEBUG;
+ }
+ else if (bfd_is_abs_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_ABS;
+ }
+ else if (bfd_is_und_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_UNDEF;
+ }
+ else
+ {
+ native->u.syment.n_scnum =
+ symbol->section->output_section->target_index;
+ }
+
+ coff_fix_symbol_name (abfd, symbol, native, string_size_p,
+ debug_string_section_p, debug_string_size_p);
+
+ symesz = bfd_coff_symesz (abfd);
+ buf = bfd_alloc (abfd, symesz);
+ if (!buf)
+ return false;
+ bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
+ if (bfd_write (buf, 1, symesz, abfd) != symesz)
+ return false;
+ bfd_release (abfd, buf);
+
+ if (native->u.syment.n_numaux > 0)
+ {
+ bfd_size_type auxesz;
+ unsigned int j;
+
+ auxesz = bfd_coff_auxesz (abfd);
+ buf = bfd_alloc (abfd, auxesz);
+ if (!buf)
+ return false;
+ for (j = 0; j < native->u.syment.n_numaux; j++)
+ {
+ bfd_coff_swap_aux_out (abfd,
+ &((native + j + 1)->u.auxent),
+ type,
+ class,
+ j,
+ native->u.syment.n_numaux,
+ buf);
+ if (bfd_write (buf, 1, auxesz, abfd) != auxesz)
+ return false;
+ }
+ bfd_release (abfd, buf);
+ }
+
+ /* Store the index for use when we write out the relocs. */
+ set_index (symbol, *written);
+
+ *written += numaux + 1;
+ return true;
+}
+
+/* Write out a symbol to a COFF file that does not come from a COFF
+ file originally. This symbol may have been created by the linker,
+ or we may be linking a non COFF file to a COFF file. */
+
+static boolean
+coff_write_alien_symbol (abfd, symbol, written, string_size_p,
+ debug_string_section_p, debug_string_size_p)
+ bfd *abfd;
+ asymbol *symbol;
+ unsigned int *written;
+ bfd_size_type *string_size_p;
+ asection **debug_string_section_p;
+ bfd_size_type *debug_string_size_p;
+{
+ combined_entry_type *native;
+ combined_entry_type dummy;
+
+ native = &dummy;
+ native->u.syment.n_type = T_NULL;
+ native->u.syment.n_flags = 0;
+ if (bfd_is_und_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_UNDEF;
+ native->u.syment.n_value = symbol->value;
+ }
+ else if (bfd_is_com_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_UNDEF;
+ native->u.syment.n_value = symbol->value;
+ }
+ else if (symbol->flags & BSF_DEBUGGING)
+ {
+ /* There isn't much point to writing out a debugging symbol
+ unless we are prepared to convert it into COFF debugging
+ format. So, we just ignore them. We must clobber the symbol
+ name to keep it from being put in the string table. */
+ symbol->name = "";
+ return true;
+ }
+ else
+ {
+ native->u.syment.n_scnum =
+ symbol->section->output_section->target_index;
+ native->u.syment.n_value = (symbol->value
+ + symbol->section->output_offset);
+ if (! obj_pe (abfd))
+ native->u.syment.n_value += symbol->section->output_section->vma;
+
+ /* Copy the any flags from the the file header into the symbol.
+ FIXME: Why? */
+ {
+ coff_symbol_type *c = coff_symbol_from (abfd, symbol);
+ if (c != (coff_symbol_type *) NULL)
+ native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
+ }
+ }
+
+ native->u.syment.n_type = 0;
+ if (symbol->flags & BSF_LOCAL)
+ native->u.syment.n_sclass = C_STAT;
+ else if (symbol->flags & BSF_WEAK)
+ native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
+ else
+ native->u.syment.n_sclass = C_EXT;
+ native->u.syment.n_numaux = 0;
+
+ return coff_write_symbol (abfd, symbol, native, written, string_size_p,
+ debug_string_section_p, debug_string_size_p);
+}
+
+/* Write a native symbol to a COFF file. */
+
+static boolean
+coff_write_native_symbol (abfd, symbol, written, string_size_p,
+ debug_string_section_p, debug_string_size_p)
+ bfd *abfd;
+ coff_symbol_type *symbol;
+ unsigned int *written;
+ bfd_size_type *string_size_p;
+ asection **debug_string_section_p;
+ bfd_size_type *debug_string_size_p;
+{
+ combined_entry_type *native = symbol->native;
+ alent *lineno = symbol->lineno;
+
+ /* If this symbol has an associated line number, we must store the
+ symbol index in the line number field. We also tag the auxent to
+ point to the right place in the lineno table. */
+ if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL)
+ {
+ unsigned int count = 0;
+ lineno[count].u.offset = *written;
+ if (native->u.syment.n_numaux)
+ {
+ union internal_auxent *a = &((native + 1)->u.auxent);
+
+ a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
+ symbol->symbol.section->output_section->moving_line_filepos;
+ }
+
+ /* Count and relocate all other linenumbers. */
+ count++;
+ while (lineno[count].line_number != 0)
+ {
+#if 0
+ /* 13 april 92. sac
+ I've been told this, but still need proof:
+ > The second bug is also in `bfd/coffcode.h'. This bug
+ > causes the linker to screw up the pc-relocations for
+ > all the line numbers in COFF code. This bug isn't only
+ > specific to A29K implementations, but affects all
+ > systems using COFF format binaries. Note that in COFF
+ > object files, the line number core offsets output by
+ > the assembler are relative to the start of each
+ > procedure, not to the start of the .text section. This
+ > patch relocates the line numbers relative to the
+ > `native->u.syment.n_value' instead of the section
+ > virtual address.
+ > modular!olson@cs.arizona.edu (Jon Olson)
+ */
+ lineno[count].u.offset += native->u.syment.n_value;
+#else
+ lineno[count].u.offset +=
+ (symbol->symbol.section->output_section->vma
+ + symbol->symbol.section->output_offset);
+#endif
+ count++;
+ }
+ symbol->done_lineno = true;
+
+ symbol->symbol.section->output_section->moving_line_filepos +=
+ count * bfd_coff_linesz (abfd);
+ }
+
+ return coff_write_symbol (abfd, &(symbol->symbol), native, written,
+ string_size_p, debug_string_section_p,
+ debug_string_size_p);
+}
+
+/* Write out the COFF symbols. */
+
+boolean
+coff_write_symbols (abfd)
+ bfd *abfd;
+{
+ bfd_size_type string_size;
+ asection *debug_string_section;
+ bfd_size_type debug_string_size;
+ unsigned int i;
+ unsigned int limit = bfd_get_symcount (abfd);
+ unsigned int written = 0;
+ asymbol **p;
+
+ string_size = 0;
+ debug_string_section = NULL;
+ debug_string_size = 0;
+
+ /* If this target supports long section names, they must be put into
+ the string table. This is supported by PE. This code must
+ handle section names just as they are handled in
+ coff_write_object_contents. */
+ if (bfd_coff_long_section_names (abfd))
+ {
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ size_t len;
+
+ len = strlen (o->name);
+ if (len > SCNNMLEN)
+ string_size += len + 1;
+ }
+ }
+
+ /* Seek to the right place */
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
+ return false;
+
+ /* Output all the symbols we have */
+
+ written = 0;
+ for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
+ {
+ asymbol *symbol = *p;
+ coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol);
+
+ if (c_symbol == (coff_symbol_type *) NULL
+ || c_symbol->native == (combined_entry_type *) NULL)
+ {
+ if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size,
+ &debug_string_section,
+ &debug_string_size))
+ return false;
+ }
+ else
+ {
+ if (!coff_write_native_symbol (abfd, c_symbol, &written,
+ &string_size, &debug_string_section,
+ &debug_string_size))
+ return false;
+ }
+ }
+
+ obj_raw_syment_count (abfd) = written;
+
+ /* Now write out strings */
+
+ if (string_size != 0)
+ {
+ unsigned int size = string_size + STRING_SIZE_SIZE;
+ bfd_byte buffer[STRING_SIZE_SIZE];
+
+#if STRING_SIZE_SIZE == 4
+ bfd_h_put_32 (abfd, size, buffer);
+#else
+ #error Change bfd_h_put_32
+#endif
+ if (bfd_write ((PTR) buffer, 1, sizeof (buffer), abfd) != sizeof (buffer))
+ return false;
+
+ /* Handle long section names. This code must handle section
+ names just as they are handled in coff_write_object_contents. */
+ if (bfd_coff_long_section_names (abfd))
+ {
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ size_t len;
+
+ len = strlen (o->name);
+ if (len > SCNNMLEN)
+ {
+ if (bfd_write (o->name, 1, len + 1, abfd) != len + 1)
+ return false;
+ }
+ }
+ }
+
+ for (p = abfd->outsymbols, i = 0;
+ i < limit;
+ i++, p++)
+ {
+ asymbol *q = *p;
+ size_t name_length = strlen (q->name);
+ coff_symbol_type *c_symbol = coff_symbol_from (abfd, q);
+ size_t maxlen;
+
+ /* Figure out whether the symbol name should go in the string
+ table. Symbol names that are short enough are stored
+ directly in the syment structure. File names permit a
+ different, longer, length in the syment structure. On
+ XCOFF, some symbol names are stored in the .debug section
+ rather than in the string table. */
+
+ if (c_symbol == NULL
+ || c_symbol->native == NULL)
+ {
+ /* This is not a COFF symbol, so it certainly is not a
+ file name, nor does it go in the .debug section. */
+ maxlen = SYMNMLEN;
+ }
+ else if (bfd_coff_symname_in_debug (abfd,
+ &c_symbol->native->u.syment))
+ {
+ /* This symbol name is in the XCOFF .debug section.
+ Don't write it into the string table. */
+ maxlen = name_length;
+ }
+ else if (c_symbol->native->u.syment.n_sclass == C_FILE
+ && c_symbol->native->u.syment.n_numaux > 0)
+ maxlen = FILNMLEN;
+ else
+ maxlen = SYMNMLEN;
+
+ if (name_length > maxlen)
+ {
+ if (bfd_write ((PTR) (q->name), 1, name_length + 1, abfd)
+ != name_length + 1)
+ return false;
+ }
+ }
+ }
+ else
+ {
+ /* We would normally not write anything here, but we'll write
+ out 4 so that any stupid coff reader which tries to read the
+ string table even when there isn't one won't croak. */
+ unsigned int size = STRING_SIZE_SIZE;
+ bfd_byte buffer[STRING_SIZE_SIZE];
+
+#if STRING_SIZE_SIZE == 4
+ bfd_h_put_32 (abfd, size, buffer);
+#else
+ #error Change bfd_h_put_32
+#endif
+ if (bfd_write ((PTR) buffer, 1, STRING_SIZE_SIZE, abfd)
+ != STRING_SIZE_SIZE)
+ return false;
+ }
+
+ /* Make sure the .debug section was created to be the correct size.
+ We should create it ourselves on the fly, but we don't because
+ BFD won't let us write to any section until we know how large all
+ the sections are. We could still do it by making another pass
+ over the symbols. FIXME. */
+ BFD_ASSERT (debug_string_size == 0
+ || (debug_string_section != (asection *) NULL
+ && (BFD_ALIGN (debug_string_size,
+ 1 << debug_string_section->alignment_power)
+ == bfd_section_size (abfd, debug_string_section))));
+
+ return true;
+}
+
+boolean
+coff_write_linenumbers (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ bfd_size_type linesz;
+ PTR buff;
+
+ linesz = bfd_coff_linesz (abfd);
+ buff = bfd_alloc (abfd, linesz);
+ if (!buff)
+ return false;
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ if (s->lineno_count)
+ {
+ asymbol **q = abfd->outsymbols;
+ if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0)
+ return false;
+ /* Find all the linenumbers in this section */
+ while (*q)
+ {
+ asymbol *p = *q;
+ if (p->section->output_section == s)
+ {
+ alent *l =
+ BFD_SEND (bfd_asymbol_bfd (p), _get_lineno,
+ (bfd_asymbol_bfd (p), p));
+ if (l)
+ {
+ /* Found a linenumber entry, output */
+ struct internal_lineno out;
+ memset ((PTR) & out, 0, sizeof (out));
+ out.l_lnno = 0;
+ out.l_addr.l_symndx = l->u.offset;
+ bfd_coff_swap_lineno_out (abfd, &out, buff);
+ if (bfd_write (buff, 1, linesz, abfd) != linesz)
+ return false;
+ l++;
+ while (l->line_number)
+ {
+ out.l_lnno = l->line_number;
+ out.l_addr.l_symndx = l->u.offset;
+ bfd_coff_swap_lineno_out (abfd, &out, buff);
+ if (bfd_write (buff, 1, linesz, abfd) != linesz)
+ return false;
+ l++;
+ }
+ }
+ }
+ q++;
+ }
+ }
+ }
+ bfd_release (abfd, buff);
+ return true;
+}
+
+/*ARGSUSED */
+alent *
+coff_get_lineno (ignore_abfd, symbol)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+{
+ return coffsymbol (symbol)->lineno;
+}
+
+#if 0
+
+/* This is only called from coff_add_missing_symbols, which has been
+ disabled. */
+
+asymbol *
+coff_section_symbol (abfd, name)
+ bfd *abfd;
+ char *name;
+{
+ asection *sec = bfd_make_section_old_way (abfd, name);
+ asymbol *sym;
+ combined_entry_type *csym;
+
+ sym = sec->symbol;
+ csym = coff_symbol_from (abfd, sym)->native;
+ /* Make sure back-end COFF stuff is there. */
+ if (csym == 0)
+ {
+ struct foo
+ {
+ coff_symbol_type sym;
+ /* @@FIXME This shouldn't use a fixed size!! */
+ combined_entry_type e[10];
+ };
+ struct foo *f;
+ f = (struct foo *) bfd_alloc (abfd, sizeof (*f));
+ if (!f)
+ {
+ bfd_set_error (bfd_error_no_error);
+ return NULL;
+ }
+ memset ((char *) f, 0, sizeof (*f));
+ coff_symbol_from (abfd, sym)->native = csym = f->e;
+ }
+ csym[0].u.syment.n_sclass = C_STAT;
+ csym[0].u.syment.n_numaux = 1;
+/* SF_SET_STATICS (sym); @@ ??? */
+ csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
+ csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
+ csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
+
+ if (sec->output_section == NULL)
+ {
+ sec->output_section = sec;
+ sec->output_offset = 0;
+ }
+
+ return sym;
+}
+
+#endif /* 0 */
+
+/* This function transforms the offsets into the symbol table into
+ pointers to syments. */
+
+static void
+coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent)
+ bfd *abfd;
+ combined_entry_type *table_base;
+ combined_entry_type *symbol;
+ unsigned int indaux;
+ combined_entry_type *auxent;
+{
+ unsigned int type = symbol->u.syment.n_type;
+ unsigned int class = symbol->u.syment.n_sclass;
+
+ if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
+ {
+ if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
+ (abfd, table_base, symbol, indaux, auxent))
+ return;
+ }
+
+ /* Don't bother if this is a file or a section */
+ if (class == C_STAT && type == T_NULL)
+ return;
+ if (class == C_FILE)
+ return;
+
+ /* Otherwise patch up */
+#define N_TMASK coff_data (abfd)->local_n_tmask
+#define N_BTSHFT coff_data (abfd)->local_n_btshft
+ if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN)
+ && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0)
+ {
+ auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
+ table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
+ auxent->fix_end = 1;
+ }
+ /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can
+ generate one, so we must be careful to ignore it. */
+ if (auxent->u.auxent.x_sym.x_tagndx.l > 0)
+ {
+ auxent->u.auxent.x_sym.x_tagndx.p =
+ table_base + auxent->u.auxent.x_sym.x_tagndx.l;
+ auxent->fix_tag = 1;
+ }
+}
+
+/* Allocate space for the ".debug" section, and read it.
+ We did not read the debug section until now, because
+ we didn't want to go to the trouble until someone needed it. */
+
+static char *
+build_debug_section (abfd)
+ bfd *abfd;
+{
+ char *debug_section;
+ long position;
+
+ asection *sect = bfd_get_section_by_name (abfd, ".debug");
+
+ if (!sect)
+ {
+ bfd_set_error (bfd_error_no_debug_section);
+ return NULL;
+ }
+
+ debug_section = (PTR) bfd_alloc (abfd,
+ bfd_get_section_size_before_reloc (sect));
+ if (debug_section == NULL)
+ return NULL;
+
+ /* Seek to the beginning of the `.debug' section and read it.
+ Save the current position first; it is needed by our caller.
+ Then read debug section and reset the file pointer. */
+
+ position = bfd_tell (abfd);
+ if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0
+ || (bfd_read (debug_section,
+ bfd_get_section_size_before_reloc (sect), 1, abfd)
+ != bfd_get_section_size_before_reloc (sect))
+ || bfd_seek (abfd, position, SEEK_SET) != 0)
+ return NULL;
+ return debug_section;
+}
+
+
+/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
+ \0-terminated, but will not exceed 'maxlen' characters. The copy *will*
+ be \0-terminated. */
+static char *
+copy_name (abfd, name, maxlen)
+ bfd *abfd;
+ char *name;
+ int maxlen;
+{
+ int len;
+ char *newname;
+
+ for (len = 0; len < maxlen; ++len)
+ {
+ if (name[len] == '\0')
+ {
+ break;
+ }
+ }
+
+ if ((newname = (PTR) bfd_alloc (abfd, len + 1)) == NULL)
+ return (NULL);
+ strncpy (newname, name, len);
+ newname[len] = '\0';
+ return newname;
+}
+
+/* Read in the external symbols. */
+
+boolean
+_bfd_coff_get_external_symbols (abfd)
+ bfd *abfd;
+{
+ bfd_size_type symesz;
+ size_t size;
+ PTR syms;
+
+ if (obj_coff_external_syms (abfd) != NULL)
+ return true;
+
+ symesz = bfd_coff_symesz (abfd);
+
+ size = obj_raw_syment_count (abfd) * symesz;
+
+ syms = (PTR) bfd_malloc (size);
+ if (syms == NULL && size != 0)
+ return false;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_read (syms, size, 1, abfd) != size)
+ {
+ if (syms != NULL)
+ free (syms);
+ return false;
+ }
+
+ obj_coff_external_syms (abfd) = syms;
+
+ return true;
+}
+
+/* Read in the external strings. The strings are not loaded until
+ they are needed. This is because we have no simple way of
+ detecting a missing string table in an archive. */
+
+const char *
+_bfd_coff_read_string_table (abfd)
+ bfd *abfd;
+{
+ char extstrsize[STRING_SIZE_SIZE];
+ size_t strsize;
+ char *strings;
+
+ if (obj_coff_strings (abfd) != NULL)
+ return obj_coff_strings (abfd);
+
+ if (obj_sym_filepos (abfd) == 0)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return NULL;
+ }
+
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd)),
+ SEEK_SET) != 0)
+ return NULL;
+
+ if (bfd_read (extstrsize, sizeof extstrsize, 1, abfd) != sizeof extstrsize)
+ {
+ if (bfd_get_error () != bfd_error_file_truncated)
+ return NULL;
+
+ /* There is no string table. */
+ strsize = STRING_SIZE_SIZE;
+ }
+ else
+ {
+#if STRING_SIZE_SIZE == 4
+ strsize = bfd_h_get_32 (abfd, (bfd_byte *) extstrsize);
+#else
+ #error Change bfd_h_get_32
+#endif
+ }
+
+ if (strsize < STRING_SIZE_SIZE)
+ {
+ (*_bfd_error_handler)
+ (_("%s: bad string table size %lu"), bfd_get_filename (abfd),
+ (unsigned long) strsize);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ strings = (char *) bfd_malloc (strsize);
+ if (strings == NULL)
+ return NULL;
+
+ if (bfd_read (strings + STRING_SIZE_SIZE,
+ strsize - STRING_SIZE_SIZE, 1, abfd)
+ != strsize - STRING_SIZE_SIZE)
+ {
+ free (strings);
+ return NULL;
+ }
+
+ obj_coff_strings (abfd) = strings;
+
+ return strings;
+}
+
+/* Free up the external symbols and strings read from a COFF file. */
+
+boolean
+_bfd_coff_free_symbols (abfd)
+ bfd *abfd;
+{
+ if (obj_coff_external_syms (abfd) != NULL
+ && ! obj_coff_keep_syms (abfd))
+ {
+ free (obj_coff_external_syms (abfd));
+ obj_coff_external_syms (abfd) = NULL;
+ }
+ if (obj_coff_strings (abfd) != NULL
+ && ! obj_coff_keep_strings (abfd))
+ {
+ free (obj_coff_strings (abfd));
+ obj_coff_strings (abfd) = NULL;
+ }
+ return true;
+}
+
+/* Read a symbol table into freshly bfd_allocated memory, swap it, and
+ knit the symbol names into a normalized form. By normalized here I
+ mean that all symbols have an n_offset pointer that points to a null-
+ terminated string. */
+
+combined_entry_type *
+coff_get_normalized_symtab (abfd)
+ bfd *abfd;
+{
+ combined_entry_type *internal;
+ combined_entry_type *internal_ptr;
+ combined_entry_type *symbol_ptr;
+ combined_entry_type *internal_end;
+ bfd_size_type symesz;
+ char *raw_src;
+ char *raw_end;
+ const char *string_table = NULL;
+ char *debug_section = NULL;
+ unsigned long size;
+
+ if (obj_raw_syments (abfd) != NULL)
+ return obj_raw_syments (abfd);
+
+ size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
+ internal = (combined_entry_type *) bfd_zalloc (abfd, size);
+ if (internal == NULL && size != 0)
+ return NULL;
+ internal_end = internal + obj_raw_syment_count (abfd);
+
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return NULL;
+
+ raw_src = (char *) obj_coff_external_syms (abfd);
+
+ /* mark the end of the symbols */
+ symesz = bfd_coff_symesz (abfd);
+ raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz;
+
+ /* FIXME SOMEDAY. A string table size of zero is very weird, but
+ probably possible. If one shows up, it will probably kill us. */
+
+ /* Swap all the raw entries */
+ for (internal_ptr = internal;
+ raw_src < raw_end;
+ raw_src += symesz, internal_ptr++)
+ {
+
+ unsigned int i;
+ bfd_coff_swap_sym_in (abfd, (PTR) raw_src,
+ (PTR) & internal_ptr->u.syment);
+ symbol_ptr = internal_ptr;
+
+ for (i = 0;
+ i < symbol_ptr->u.syment.n_numaux;
+ i++)
+ {
+ internal_ptr++;
+ raw_src += symesz;
+ bfd_coff_swap_aux_in (abfd, (PTR) raw_src,
+ symbol_ptr->u.syment.n_type,
+ symbol_ptr->u.syment.n_sclass,
+ i, symbol_ptr->u.syment.n_numaux,
+ &(internal_ptr->u.auxent));
+ coff_pointerize_aux (abfd, internal, symbol_ptr, i,
+ internal_ptr);
+ }
+ }
+
+ /* Free the raw symbols, but not the strings (if we have them). */
+ obj_coff_keep_strings (abfd) = true;
+ if (! _bfd_coff_free_symbols (abfd))
+ return NULL;
+
+ for (internal_ptr = internal; internal_ptr < internal_end;
+ internal_ptr++)
+ {
+ if (internal_ptr->u.syment.n_sclass == C_FILE
+ && internal_ptr->u.syment.n_numaux > 0)
+ {
+ /* make a file symbol point to the name in the auxent, since
+ the text ".file" is redundant */
+ if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0)
+ {
+ /* the filename is a long one, point into the string table */
+ if (string_table == NULL)
+ {
+ string_table = _bfd_coff_read_string_table (abfd);
+ if (string_table == NULL)
+ return NULL;
+ }
+
+ internal_ptr->u.syment._n._n_n._n_offset =
+ ((long)
+ (string_table
+ + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset));
+ }
+ else
+ {
+ /* ordinary short filename, put into memory anyway */
+ internal_ptr->u.syment._n._n_n._n_offset = (long)
+ copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
+ FILNMLEN);
+ }
+ }
+ else
+ {
+ if (internal_ptr->u.syment._n._n_n._n_zeroes != 0)
+ {
+ /* This is a "short" name. Make it long. */
+ unsigned long i = 0;
+ char *newstring = NULL;
+
+ /* find the length of this string without walking into memory
+ that isn't ours. */
+ for (i = 0; i < 8; ++i)
+ {
+ if (internal_ptr->u.syment._n._n_name[i] == '\0')
+ {
+ break;
+ } /* if end of string */
+ } /* possible lengths of this string. */
+
+ if ((newstring = (PTR) bfd_alloc (abfd, ++i)) == NULL)
+ return (NULL);
+ memset (newstring, 0, i);
+ strncpy (newstring, internal_ptr->u.syment._n._n_name, i - 1);
+ internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring;
+ internal_ptr->u.syment._n._n_n._n_zeroes = 0;
+ }
+ else if (internal_ptr->u.syment._n._n_n._n_offset == 0)
+ internal_ptr->u.syment._n._n_n._n_offset = (long int) "";
+ else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment))
+ {
+ /* Long name already. Point symbol at the string in the
+ table. */
+ if (string_table == NULL)
+ {
+ string_table = _bfd_coff_read_string_table (abfd);
+ if (string_table == NULL)
+ return NULL;
+ }
+ internal_ptr->u.syment._n._n_n._n_offset =
+ ((long int)
+ (string_table
+ + internal_ptr->u.syment._n._n_n._n_offset));
+ }
+ else
+ {
+ /* Long name in debug section. Very similar. */
+ if (debug_section == NULL)
+ debug_section = build_debug_section (abfd);
+ internal_ptr->u.syment._n._n_n._n_offset = (long int)
+ (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
+ }
+ }
+ internal_ptr += internal_ptr->u.syment.n_numaux;
+ }
+
+ obj_raw_syments (abfd) = internal;
+ BFD_ASSERT (obj_raw_syment_count (abfd)
+ == (unsigned int) (internal_ptr - internal));
+
+ return (internal);
+} /* coff_get_normalized_symtab() */
+
+long
+coff_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ if (bfd_get_format (abfd) != bfd_object)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+asymbol *
+coff_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type));
+ if (new == NULL)
+ return (NULL);
+ memset (new, 0, sizeof *new);
+ new->symbol.section = 0;
+ new->native = 0;
+ new->lineno = (alent *) NULL;
+ new->done_lineno = false;
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
+
+/* Make a debugging symbol. */
+
+asymbol *
+coff_bfd_make_debug_symbol (abfd, ptr, sz)
+ bfd *abfd;
+ PTR ptr;
+ unsigned long sz;
+{
+ coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type));
+ if (new == NULL)
+ return (NULL);
+ /* @@ The 10 is a guess at a plausible maximum number of aux entries
+ (but shouldn't be a constant). */
+ new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10);
+ if (!new->native)
+ return (NULL);
+ new->symbol.section = bfd_abs_section_ptr;
+ new->symbol.flags = BSF_DEBUGGING;
+ new->lineno = (alent *) NULL;
+ new->done_lineno = false;
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
+
+/*ARGSUSED */
+void
+coff_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+ if (coffsymbol (symbol)->native != NULL
+ && coffsymbol (symbol)->native->fix_value)
+ {
+ combined_entry_type *psym;
+
+ psym = ((combined_entry_type *)
+ coffsymbol (symbol)->native->u.syment.n_value);
+ ret->value = (bfd_vma) (psym - obj_raw_syments (abfd));
+ }
+}
+
+/* Return the COFF syment for a symbol. */
+
+boolean
+bfd_coff_get_syment (abfd, symbol, psyment)
+ bfd *abfd;
+ asymbol *symbol;
+ struct internal_syment *psyment;
+{
+ coff_symbol_type *csym;
+
+ csym = coff_symbol_from (abfd, symbol);
+ if (csym == NULL || csym->native == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ *psyment = csym->native->u.syment;
+
+ if (csym->native->fix_value)
+ psyment->n_value = ((combined_entry_type *) psyment->n_value
+ - obj_raw_syments (abfd));
+
+ /* FIXME: We should handle fix_line here. */
+
+ return true;
+}
+
+/* Return the COFF auxent for a symbol. */
+
+boolean
+bfd_coff_get_auxent (abfd, symbol, indx, pauxent)
+ bfd *abfd;
+ asymbol *symbol;
+ int indx;
+ union internal_auxent *pauxent;
+{
+ coff_symbol_type *csym;
+ combined_entry_type *ent;
+
+ csym = coff_symbol_from (abfd, symbol);
+
+ if (csym == NULL
+ || csym->native == NULL
+ || indx >= csym->native->u.syment.n_numaux)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ ent = csym->native + indx + 1;
+
+ *pauxent = ent->u.auxent;
+
+ if (ent->fix_tag)
+ pauxent->x_sym.x_tagndx.l =
+ ((combined_entry_type *) pauxent->x_sym.x_tagndx.p
+ - obj_raw_syments (abfd));
+
+ if (ent->fix_end)
+ pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l =
+ ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p
+ - obj_raw_syments (abfd));
+
+ if (ent->fix_scnlen)
+ pauxent->x_csect.x_scnlen.l =
+ ((combined_entry_type *) pauxent->x_csect.x_scnlen.p
+ - obj_raw_syments (abfd));
+
+ return true;
+}
+
+/* Print out information about COFF symbol. */
+
+void
+coff_print_symbol (abfd, filep, symbol, how)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) filep;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+
+ case bfd_print_symbol_more:
+ fprintf (file, "coff %s %s",
+ coffsymbol (symbol)->native ? "n" : "g",
+ coffsymbol (symbol)->lineno ? "l" : " ");
+ break;
+
+ case bfd_print_symbol_all:
+ if (coffsymbol (symbol)->native)
+ {
+ unsigned long val;
+ unsigned int aux;
+ combined_entry_type *combined = coffsymbol (symbol)->native;
+ combined_entry_type *root = obj_raw_syments (abfd);
+ struct lineno_cache_entry *l = coffsymbol (symbol)->lineno;
+
+ fprintf (file, "[%3ld]", (long) (combined - root));
+
+ if (! combined->fix_value)
+ val = (unsigned long) combined->u.syment.n_value;
+ else
+ val = ((unsigned long)
+ ((combined_entry_type *) combined->u.syment.n_value
+ - root));
+
+ fprintf (file,
+ "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x%08lx %s",
+ combined->u.syment.n_scnum,
+ combined->u.syment.n_flags,
+ combined->u.syment.n_type,
+ combined->u.syment.n_sclass,
+ combined->u.syment.n_numaux,
+ val,
+ symbol->name);
+
+ for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
+ {
+ combined_entry_type *auxp = combined + aux + 1;
+ long tagndx;
+
+ if (auxp->fix_tag)
+ tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
+ else
+ tagndx = auxp->u.auxent.x_sym.x_tagndx.l;
+
+ fprintf (file, "\n");
+
+ if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux))
+ continue;
+
+ switch (combined->u.syment.n_sclass)
+ {
+ case C_FILE:
+ fprintf (file, "File ");
+ break;
+
+ case C_STAT:
+ if (combined->u.syment.n_type == T_NULL)
+ /* probably a section symbol? */
+ {
+ fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d",
+ (long) auxp->u.auxent.x_scn.x_scnlen,
+ auxp->u.auxent.x_scn.x_nreloc,
+ auxp->u.auxent.x_scn.x_nlinno);
+ if (auxp->u.auxent.x_scn.x_checksum != 0
+ || auxp->u.auxent.x_scn.x_associated != 0
+ || auxp->u.auxent.x_scn.x_comdat != 0)
+ fprintf (file, " checksum 0x%lx assoc %d comdat %d",
+ auxp->u.auxent.x_scn.x_checksum,
+ auxp->u.auxent.x_scn.x_associated,
+ auxp->u.auxent.x_scn.x_comdat);
+ break;
+ }
+ /* else fall through */
+
+ default:
+ fprintf (file, "AUX lnno %d size 0x%x tagndx %ld",
+ auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
+ auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
+ tagndx);
+ if (auxp->fix_end)
+ fprintf (file, " endndx %ld",
+ ((long)
+ (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
+ - root)));
+ break;
+ }
+ }
+
+ if (l)
+ {
+ fprintf (file, "\n%s :", l->u.sym->name);
+ l++;
+ while (l->line_number)
+ {
+ fprintf (file, "\n%4d : 0x%lx",
+ l->line_number,
+ ((unsigned long)
+ (l->u.offset + symbol->section->vma)));
+ l++;
+ }
+ }
+ }
+ else
+ {
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %-5s %s %s %s",
+ symbol->section->name,
+ coffsymbol (symbol)->native ? "n" : "g",
+ coffsymbol (symbol)->lineno ? "l" : " ",
+ symbol->name);
+ }
+ }
+}
+
+/* Return whether a symbol name implies a local symbol. In COFF,
+ local symbols generally start with ``.L''. Most targets use this
+ function for the is_local_label_name entry point, but some may
+ override it. */
+
+boolean
+_bfd_coff_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return name[0] == '.' && name[1] == 'L';
+}
+
+/* Provided a BFD, a section and an offset into the section, calculate
+ and return the name of the source file and the line nearest to the
+ wanted location. */
+
+/*ARGSUSED*/
+boolean
+coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
+ functionname_ptr, line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ boolean found;
+ unsigned int i;
+ unsigned int line_base;
+ coff_data_type *cof = coff_data (abfd);
+ /* Run through the raw syments if available */
+ combined_entry_type *p;
+ combined_entry_type *pend;
+ alent *l;
+ struct coff_section_tdata *sec_data;
+
+ /* Before looking through the symbol table, try to use a .stab
+ section to find the information. */
+ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+ &found, filename_ptr,
+ functionname_ptr, line_ptr,
+ &coff_data (abfd)->line_info))
+ return false;
+ if (found)
+ return true;
+
+ *filename_ptr = 0;
+ *functionname_ptr = 0;
+ *line_ptr = 0;
+
+ /* Don't try and find line numbers in a non coff file */
+ if (abfd->xvec->flavour != bfd_target_coff_flavour)
+ return false;
+
+ if (cof == NULL)
+ return false;
+
+ /* Find the first C_FILE symbol. */
+ p = cof->raw_syments;
+ if (!p)
+ return false;
+
+ pend = p + cof->raw_syment_count;
+ while (p < pend)
+ {
+ if (p->u.syment.n_sclass == C_FILE)
+ break;
+ p += 1 + p->u.syment.n_numaux;
+ }
+
+ if (p < pend)
+ {
+ bfd_vma sec_vma;
+ bfd_vma maxdiff;
+
+ /* Look through the C_FILE symbols to find the best one. */
+ sec_vma = bfd_get_section_vma (abfd, section);
+ *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
+ maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
+ while (1)
+ {
+ combined_entry_type *p2;
+
+ for (p2 = p + 1 + p->u.syment.n_numaux;
+ p2 < pend;
+ p2 += 1 + p2->u.syment.n_numaux)
+ {
+ if (p2->u.syment.n_scnum > 0
+ && (section
+ == coff_section_from_bfd_index (abfd,
+ p2->u.syment.n_scnum)))
+ break;
+ if (p2->u.syment.n_sclass == C_FILE)
+ {
+ p2 = pend;
+ break;
+ }
+ }
+
+ if (p2 < pend
+ && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value
+ && offset + sec_vma - (bfd_vma) p2->u.syment.n_value < maxdiff)
+ {
+ *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
+ maxdiff = offset + sec_vma - p2->u.syment.n_value;
+ }
+
+ /* Avoid endless loops on erroneous files by ensuring that
+ we always move forward in the file. */
+ if (p - cof->raw_syments >= p->u.syment.n_value)
+ break;
+
+ p = cof->raw_syments + p->u.syment.n_value;
+ if (p > pend || p->u.syment.n_sclass != C_FILE)
+ break;
+ }
+ }
+
+ /* Now wander though the raw linenumbers of the section */
+ /* If we have been called on this section before, and the offset we
+ want is further down then we can prime the lookup loop. */
+ sec_data = coff_section_data (abfd, section);
+ if (sec_data != NULL
+ && sec_data->i > 0
+ && offset >= sec_data->offset)
+ {
+ i = sec_data->i;
+ *functionname_ptr = sec_data->function;
+ line_base = sec_data->line_base;
+ }
+ else
+ {
+ i = 0;
+ line_base = 0;
+ }
+
+ if (section->lineno != NULL)
+ {
+ l = &section->lineno[i];
+
+ for (; i < section->lineno_count; i++)
+ {
+ if (l->line_number == 0)
+ {
+ /* Get the symbol this line number points at */
+ coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
+ if (coff->symbol.value > offset)
+ break;
+ *functionname_ptr = coff->symbol.name;
+ if (coff->native)
+ {
+ combined_entry_type *s = coff->native;
+ s = s + 1 + s->u.syment.n_numaux;
+
+ /* In XCOFF a debugging symbol can follow the
+ function symbol. */
+ if (s->u.syment.n_scnum == N_DEBUG)
+ s = s + 1 + s->u.syment.n_numaux;
+
+ /* S should now point to the .bf of the function. */
+ if (s->u.syment.n_numaux)
+ {
+ /* The linenumber is stored in the auxent. */
+ union internal_auxent *a = &((s + 1)->u.auxent);
+ line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
+ *line_ptr = line_base;
+ }
+ }
+ }
+ else
+ {
+ if (l->u.offset > offset)
+ break;
+ *line_ptr = l->line_number + line_base - 1;
+ }
+ l++;
+ }
+ }
+
+ /* Cache the results for the next call. */
+ if (sec_data == NULL && section->owner == abfd)
+ {
+ section->used_by_bfd =
+ ((PTR) bfd_zalloc (abfd,
+ sizeof (struct coff_section_tdata)));
+ sec_data = (struct coff_section_tdata *) section->used_by_bfd;
+ }
+ if (sec_data != NULL)
+ {
+ sec_data->offset = offset;
+ sec_data->i = i;
+ sec_data->function = *functionname_ptr;
+ sec_data->line_base = line_base;
+ }
+
+ return true;
+}
+
+int
+coff_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+ size_t size;
+
+ if (reloc == false)
+ {
+ size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
+ }
+ else
+ {
+ size = bfd_coff_filhsz (abfd);
+ }
+
+ size += abfd->section_count * bfd_coff_scnhsz (abfd);
+ return size;
+}
+
+/* Change the class of a coff symbol held by BFD. */
+boolean
+bfd_coff_set_symbol_class (abfd, symbol, class)
+ bfd * abfd;
+ asymbol * symbol;
+ unsigned int class;
+{
+ coff_symbol_type * csym;
+
+ csym = coff_symbol_from (abfd, symbol);
+ if (csym == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+ else if (csym->native == NULL)
+ {
+ /* This is an alien symbol which no native coff backend data.
+ We cheat here by creating a fake native entry for it and
+ then filling in the class. This code is based on that in
+ coff_write_alien_symbol(). */
+
+ combined_entry_type * native;
+
+ native = (combined_entry_type *) bfd_alloc (abfd, sizeof (* native));
+ if (native == NULL)
+ return false;
+
+ memset (native, 0, sizeof (* native));
+
+ native->u.syment.n_type = T_NULL;
+ native->u.syment.n_sclass = class;
+
+ if (bfd_is_und_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_UNDEF;
+ native->u.syment.n_value = symbol->value;
+ }
+ else if (bfd_is_com_section (symbol->section))
+ {
+ native->u.syment.n_scnum = N_UNDEF;
+ native->u.syment.n_value = symbol->value;
+ }
+ else
+ {
+ native->u.syment.n_scnum =
+ symbol->section->output_section->target_index;
+ native->u.syment.n_value = (symbol->value
+ + symbol->section->output_offset);
+ if (! obj_pe (abfd))
+ native->u.syment.n_value += symbol->section->output_section->vma;
+
+ /* Copy the any flags from the the file header into the symbol.
+ FIXME: Why? */
+ native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags;
+ }
+
+ csym->native = native;
+ }
+ else
+ {
+ csym->native->u.syment.n_sclass = class;
+ }
+
+ return true;
+}
+
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
new file mode 100644
index 00000000000..cf56869fe65
--- /dev/null
+++ b/bfd/cofflink.c
@@ -0,0 +1,2752 @@
+/* COFF specific linker code.
+ Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file contains the COFF backend linker code. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+static boolean coff_link_add_object_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean coff_link_check_archive_element
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *));
+static boolean coff_link_check_ar_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *));
+static boolean coff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
+static char *dores_com PARAMS ((char *, bfd *, int));
+static char *get_name PARAMS ((char *, char **));
+static int process_embedded_commands
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *));
+static void mark_relocs PARAMS ((struct coff_final_link_info *, bfd *));
+
+/* Create an entry in a COFF linker hash table. */
+
+struct bfd_hash_entry *
+_bfd_coff_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct coff_link_hash_entry *) NULL)
+ ret = ((struct coff_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct coff_link_hash_entry)));
+ if (ret == (struct coff_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct coff_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct coff_link_hash_entry *) NULL)
+ {
+ /* Set local fields. */
+ ret->indx = -1;
+ ret->type = T_NULL;
+ ret->class = C_NULL;
+ ret->numaux = 0;
+ ret->auxbfd = NULL;
+ ret->aux = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize a COFF linker hash table. */
+
+boolean
+_bfd_coff_link_hash_table_init (table, abfd, newfunc)
+ struct coff_link_hash_table *table;
+ bfd *abfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ table->stab_info = NULL;
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+}
+
+/* Create a COFF linker hash table. */
+
+struct bfd_link_hash_table *
+_bfd_coff_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct coff_link_hash_table *ret;
+
+ ret = ((struct coff_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct coff_link_hash_table)));
+ if (ret == NULL)
+ return NULL;
+ if (! _bfd_coff_link_hash_table_init (ret, abfd,
+ _bfd_coff_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+ return &ret->root;
+}
+
+/* Create an entry in a COFF debug merge hash table. */
+
+struct bfd_hash_entry *
+_bfd_coff_debug_merge_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct coff_debug_merge_hash_entry *ret =
+ (struct coff_debug_merge_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct coff_debug_merge_hash_entry *) NULL)
+ ret = ((struct coff_debug_merge_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct coff_debug_merge_hash_entry)));
+ if (ret == (struct coff_debug_merge_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct coff_debug_merge_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret != (struct coff_debug_merge_hash_entry *) NULL)
+ {
+ /* Set local fields. */
+ ret->types = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Given a COFF BFD, add symbols to the global hash table as
+ appropriate. */
+
+boolean
+_bfd_coff_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return coff_link_add_object_symbols (abfd, info);
+ case bfd_archive:
+ return (_bfd_generic_link_add_archive_symbols
+ (abfd, info, coff_link_check_archive_element));
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+}
+
+/* Add symbols from a COFF object file. */
+
+static boolean
+coff_link_add_object_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return false;
+ if (! coff_link_add_symbols (abfd, info))
+ return false;
+
+ if (! info->keep_memory)
+ {
+ if (! _bfd_coff_free_symbols (abfd))
+ return false;
+ }
+ return true;
+}
+
+/* Check a single archive element to see if we need to include it in
+ the link. *PNEEDED is set according to whether this element is
+ needed in the link or not. This is called via
+ _bfd_generic_link_add_archive_symbols. */
+
+static boolean
+coff_link_check_archive_element (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return false;
+
+ if (! coff_link_check_ar_symbols (abfd, info, pneeded))
+ return false;
+
+ if (*pneeded)
+ {
+ if (! coff_link_add_symbols (abfd, info))
+ return false;
+ }
+
+ if (! info->keep_memory || ! *pneeded)
+ {
+ if (! _bfd_coff_free_symbols (abfd))
+ return false;
+ }
+
+ return true;
+}
+
+/* Look through the symbols to see if this object file should be
+ included in the link. */
+
+static boolean
+coff_link_check_ar_symbols (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *));
+ bfd_size_type symesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+
+ *pneeded = false;
+
+ sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global;
+
+ symesz = bfd_coff_symesz (abfd);
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esym_end = esym + obj_raw_syment_count (abfd) * symesz;
+ while (esym < esym_end)
+ {
+ struct internal_syment sym;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+
+ if ((sym.n_sclass == C_EXT
+ || sym.n_sclass == C_WEAKEXT
+ || (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK)
+#ifdef C_SYSTEM
+ || sym.n_sclass == C_SYSTEM
+#endif
+ || (sym_is_global && (*sym_is_global) (abfd, &sym)))
+ && (sym.n_scnum != 0 || sym.n_value != 0))
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ struct bfd_link_hash_entry *h;
+
+ /* This symbol is externally visible, and is defined by this
+ object file. */
+
+ name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
+ if (name == NULL)
+ return false;
+ h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+
+ /* We are only interested in symbols that are currently
+ undefined. If a symbol is currently known to be common,
+ COFF linkers do not bring in an object file which defines
+ it. */
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_undefined)
+ {
+ if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ }
+
+ /* We do not need this object file. */
+ return true;
+}
+
+/* Add all the symbols from an object file to the hash table. */
+
+static boolean
+coff_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *));
+ boolean keep_syms;
+ boolean default_copy;
+ bfd_size_type symcount;
+ struct coff_link_hash_entry **sym_hash;
+ bfd_size_type symesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+
+ /* Keep the symbols during this function, in case the linker needs
+ to read the generic symbols in order to report an error message. */
+ keep_syms = obj_coff_keep_syms (abfd);
+ obj_coff_keep_syms (abfd) = true;
+
+ sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global;
+
+ if (info->keep_memory)
+ default_copy = false;
+ else
+ default_copy = true;
+
+ symcount = obj_raw_syment_count (abfd);
+
+ /* We keep a list of the linker hash table entries that correspond
+ to particular symbols. */
+ sym_hash = ((struct coff_link_hash_entry **)
+ bfd_alloc (abfd,
+ ((size_t) symcount
+ * sizeof (struct coff_link_hash_entry *))));
+ if (sym_hash == NULL && symcount != 0)
+ goto error_return;
+ obj_coff_sym_hashes (abfd) = sym_hash;
+ memset (sym_hash, 0,
+ (size_t) symcount * sizeof (struct coff_link_hash_entry *));
+
+ symesz = bfd_coff_symesz (abfd);
+ BFD_ASSERT (symesz == bfd_coff_auxesz (abfd));
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esym_end = esym + symcount * symesz;
+ while (esym < esym_end)
+ {
+ struct internal_syment sym;
+ boolean copy;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+
+ if (sym.n_sclass == C_EXT
+ || sym.n_sclass == C_WEAKEXT
+ || (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK)
+#ifdef C_SYSTEM
+ || sym.n_sclass == C_SYSTEM
+#endif
+ || (sym_is_global && (*sym_is_global) (abfd, &sym)))
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+
+ /* This symbol is externally visible. */
+
+ name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
+ if (name == NULL)
+ goto error_return;
+
+ /* We must copy the name into memory if we got it from the
+ syment itself, rather than the string table. */
+ copy = default_copy;
+ if (sym._n._n_n._n_zeroes != 0
+ || sym._n._n_n._n_offset == 0)
+ copy = true;
+
+ value = sym.n_value;
+
+ if (sym.n_scnum == 0)
+ {
+ if (value == 0)
+ {
+ flags = 0;
+ section = bfd_und_section_ptr;
+ }
+ else
+ {
+ flags = BSF_GLOBAL;
+ section = bfd_com_section_ptr;
+ }
+ }
+ else
+ {
+ flags = BSF_EXPORT | BSF_GLOBAL;
+ section = coff_section_from_bfd_index (abfd, sym.n_scnum);
+ if (! obj_pe (abfd))
+ value -= section->vma;
+ }
+
+ if (sym.n_sclass == C_WEAKEXT
+ || (obj_pe (abfd) && sym.n_sclass == C_NT_WEAK))
+ flags = BSF_WEAK;
+
+ if (! (bfd_coff_link_add_one_symbol
+ (info, abfd, name, flags, section, value,
+ (const char *) NULL, copy, false,
+ (struct bfd_link_hash_entry **) sym_hash)))
+ goto error_return;
+
+ if (section == bfd_com_section_ptr
+ && (*sym_hash)->root.type == bfd_link_hash_common
+ && ((*sym_hash)->root.u.c.p->alignment_power
+ > bfd_coff_default_section_alignment_power (abfd)))
+ (*sym_hash)->root.u.c.p->alignment_power
+ = bfd_coff_default_section_alignment_power (abfd);
+
+ if (info->hash->creator->flavour == bfd_get_flavour (abfd))
+ {
+ if (((*sym_hash)->class == C_NULL
+ && (*sym_hash)->type == T_NULL)
+ || sym.n_scnum != 0
+ || (sym.n_value != 0
+ && (*sym_hash)->root.type != bfd_link_hash_defined
+ && (*sym_hash)->root.type != bfd_link_hash_defweak))
+ {
+ (*sym_hash)->class = sym.n_sclass;
+ if (sym.n_type != T_NULL)
+ {
+ if ((*sym_hash)->type != T_NULL
+ && (*sym_hash)->type != sym.n_type)
+ (*_bfd_error_handler)
+ (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
+ name, (*sym_hash)->type, sym.n_type,
+ bfd_get_filename (abfd));
+ (*sym_hash)->type = sym.n_type;
+ }
+ (*sym_hash)->auxbfd = abfd;
+ if (sym.n_numaux != 0)
+ {
+ union internal_auxent *alloc;
+ unsigned int i;
+ bfd_byte *eaux;
+ union internal_auxent *iaux;
+
+ (*sym_hash)->numaux = sym.n_numaux;
+ alloc = ((union internal_auxent *)
+ bfd_hash_allocate (&info->hash->table,
+ (sym.n_numaux
+ * sizeof (*alloc))));
+ if (alloc == NULL)
+ goto error_return;
+ for (i = 0, eaux = esym + symesz, iaux = alloc;
+ i < sym.n_numaux;
+ i++, eaux += symesz, iaux++)
+ bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type,
+ sym.n_sclass, i, sym.n_numaux,
+ (PTR) iaux);
+ (*sym_hash)->aux = alloc;
+ }
+ }
+ }
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ sym_hash += sym.n_numaux + 1;
+ }
+
+ /* If this is a non-traditional, non-relocateable link, try to
+ optimize the handling of any .stab/.stabstr sections. */
+ if (! info->relocateable
+ && ! info->traditional_format
+ && info->hash->creator->flavour == bfd_get_flavour (abfd)
+ && (info->strip != strip_all && info->strip != strip_debugger))
+ {
+ asection *stab, *stabstr;
+
+ stab = bfd_get_section_by_name (abfd, ".stab");
+ if (stab != NULL)
+ {
+ stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+
+ if (stabstr != NULL)
+ {
+ struct coff_link_hash_table *table;
+ struct coff_section_tdata *secdata;
+
+ secdata = coff_section_data (abfd, stab);
+ if (secdata == NULL)
+ {
+ stab->used_by_bfd =
+ (PTR) bfd_zalloc (abfd,
+ sizeof (struct coff_section_tdata));
+ if (stab->used_by_bfd == NULL)
+ goto error_return;
+ secdata = coff_section_data (abfd, stab);
+ }
+
+ table = coff_hash_table (info);
+
+ if (! _bfd_link_section_stabs (abfd, &table->stab_info,
+ stab, stabstr,
+ &secdata->stab_info))
+ goto error_return;
+ }
+ }
+ }
+
+ obj_coff_keep_syms (abfd) = keep_syms;
+
+ return true;
+
+ error_return:
+ obj_coff_keep_syms (abfd) = keep_syms;
+ return false;
+}
+
+/* Do the final link step. */
+
+boolean
+_bfd_coff_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd_size_type symesz;
+ struct coff_final_link_info finfo;
+ boolean debug_merge_allocated;
+ boolean long_section_names;
+ asection *o;
+ struct bfd_link_order *p;
+ size_t max_sym_count;
+ size_t max_lineno_count;
+ size_t max_reloc_count;
+ size_t max_output_reloc_count;
+ size_t max_contents_size;
+ file_ptr rel_filepos;
+ unsigned int relsz;
+ file_ptr line_filepos;
+ unsigned int linesz;
+ bfd *sub;
+ bfd_byte *external_relocs = NULL;
+ char strbuf[STRING_SIZE_SIZE];
+
+ symesz = bfd_coff_symesz (abfd);
+
+ finfo.info = info;
+ finfo.output_bfd = abfd;
+ finfo.strtab = NULL;
+ finfo.section_info = NULL;
+ finfo.last_file_index = -1;
+ finfo.last_bf_index = -1;
+ finfo.internal_syms = NULL;
+ finfo.sec_ptrs = NULL;
+ finfo.sym_indices = NULL;
+ finfo.outsyms = NULL;
+ finfo.linenos = NULL;
+ finfo.contents = NULL;
+ finfo.external_relocs = NULL;
+ finfo.internal_relocs = NULL;
+ finfo.global_to_static = false;
+ debug_merge_allocated = false;
+
+ coff_data (abfd)->link_info = info;
+
+ finfo.strtab = _bfd_stringtab_init ();
+ if (finfo.strtab == NULL)
+ goto error_return;
+
+ if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
+ goto error_return;
+ debug_merge_allocated = true;
+
+ /* Compute the file positions for all the sections. */
+ if (! abfd->output_has_begun)
+ {
+ if (! bfd_coff_compute_section_file_positions (abfd))
+ goto error_return;
+ }
+
+ /* Count the line numbers and relocation entries required for the
+ output file. Set the file positions for the relocs. */
+ rel_filepos = obj_relocbase (abfd);
+ relsz = bfd_coff_relsz (abfd);
+ max_contents_size = 0;
+ max_lineno_count = 0;
+ max_reloc_count = 0;
+
+ long_section_names = false;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+
+ /* Mark all sections which are to be included in the
+ link. This will normally be every section. We need
+ to do this so that we can identify any sections which
+ the linker has decided to not include. */
+ sec->linker_mark = true;
+
+ if (info->strip == strip_none
+ || info->strip == strip_some)
+ o->lineno_count += sec->lineno_count;
+
+ if (info->relocateable)
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->_raw_size > max_contents_size)
+ max_contents_size = sec->_raw_size;
+ if (sec->lineno_count > max_lineno_count)
+ max_lineno_count = sec->lineno_count;
+ if (sec->reloc_count > max_reloc_count)
+ max_reloc_count = sec->reloc_count;
+ }
+ else if (info->relocateable
+ && (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order))
+ ++o->reloc_count;
+ }
+ if (o->reloc_count == 0)
+ o->rel_filepos = 0;
+ else
+ {
+ o->flags |= SEC_RELOC;
+ o->rel_filepos = rel_filepos;
+ rel_filepos += o->reloc_count * relsz;
+ }
+
+ if (bfd_coff_long_section_names (abfd)
+ && strlen (o->name) > SCNNMLEN)
+ {
+ /* This section has a long name which must go in the string
+ table. This must correspond to the code in
+ coff_write_object_contents which puts the string index
+ into the s_name field of the section header. That is why
+ we pass hash as false. */
+ if (_bfd_stringtab_add (finfo.strtab, o->name, false, false)
+ == (bfd_size_type) -1)
+ goto error_return;
+ long_section_names = true;
+ }
+ }
+
+ /* If doing a relocateable link, allocate space for the pointers we
+ need to keep. */
+ if (info->relocateable)
+ {
+ unsigned int i;
+
+ /* We use section_count + 1, rather than section_count, because
+ the target_index fields are 1 based. */
+ finfo.section_info =
+ ((struct coff_link_section_info *)
+ bfd_malloc ((abfd->section_count + 1)
+ * sizeof (struct coff_link_section_info)));
+ if (finfo.section_info == NULL)
+ goto error_return;
+ for (i = 0; i <= abfd->section_count; i++)
+ {
+ finfo.section_info[i].relocs = NULL;
+ finfo.section_info[i].rel_hashes = NULL;
+ }
+ }
+
+ /* We now know the size of the relocs, so we can determine the file
+ positions of the line numbers. */
+ line_filepos = rel_filepos;
+ linesz = bfd_coff_linesz (abfd);
+ max_output_reloc_count = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->lineno_count == 0)
+ o->line_filepos = 0;
+ else
+ {
+ o->line_filepos = line_filepos;
+ line_filepos += o->lineno_count * linesz;
+ }
+
+ if (o->reloc_count != 0)
+ {
+ /* We don't know the indices of global symbols until we have
+ written out all the local symbols. For each section in
+ the output file, we keep an array of pointers to hash
+ table entries. Each entry in the array corresponds to a
+ reloc. When we find a reloc against a global symbol, we
+ set the corresponding entry in this array so that we can
+ fix up the symbol index after we have written out all the
+ local symbols.
+
+ Because of this problem, we also keep the relocs in
+ memory until the end of the link. This wastes memory,
+ but only when doing a relocateable link, which is not the
+ common case. */
+ BFD_ASSERT (info->relocateable);
+ finfo.section_info[o->target_index].relocs =
+ ((struct internal_reloc *)
+ bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
+ finfo.section_info[o->target_index].rel_hashes =
+ ((struct coff_link_hash_entry **)
+ bfd_malloc (o->reloc_count
+ * sizeof (struct coff_link_hash_entry *)));
+ if (finfo.section_info[o->target_index].relocs == NULL
+ || finfo.section_info[o->target_index].rel_hashes == NULL)
+ goto error_return;
+
+ if (o->reloc_count > max_output_reloc_count)
+ max_output_reloc_count = o->reloc_count;
+ }
+
+ /* Reset the reloc and lineno counts, so that we can use them to
+ count the number of entries we have output so far. */
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ }
+
+ obj_sym_filepos (abfd) = line_filepos;
+
+ /* Figure out the largest number of symbols in an input BFD. Take
+ the opportunity to clear the output_has_begun fields of all the
+ input BFD's. */
+ max_sym_count = 0;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ size_t sz;
+
+ sub->output_has_begun = false;
+ sz = obj_raw_syment_count (sub);
+ if (sz > max_sym_count)
+ max_sym_count = sz;
+ }
+
+ /* Allocate some buffers used while linking. */
+ finfo.internal_syms = ((struct internal_syment *)
+ bfd_malloc (max_sym_count
+ * sizeof (struct internal_syment)));
+ finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count
+ * sizeof (asection *));
+ finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
+ finfo.outsyms = ((bfd_byte *)
+ bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
+ finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
+ * bfd_coff_linesz (abfd));
+ finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
+ if (! info->relocateable)
+ finfo.internal_relocs = ((struct internal_reloc *)
+ bfd_malloc (max_reloc_count
+ * sizeof (struct internal_reloc)));
+ if ((finfo.internal_syms == NULL && max_sym_count > 0)
+ || (finfo.sec_ptrs == NULL && max_sym_count > 0)
+ || (finfo.sym_indices == NULL && max_sym_count > 0)
+ || finfo.outsyms == NULL
+ || (finfo.linenos == NULL && max_lineno_count > 0)
+ || (finfo.contents == NULL && max_contents_size > 0)
+ || (finfo.external_relocs == NULL && max_reloc_count > 0)
+ || (! info->relocateable
+ && finfo.internal_relocs == NULL
+ && max_reloc_count > 0))
+ goto error_return;
+
+ /* We now know the position of everything in the file, except that
+ we don't know the size of the symbol table and therefore we don't
+ know where the string table starts. We just build the string
+ table in memory as we go along. We process all the relocations
+ for a single input file at once. */
+ obj_raw_syment_count (abfd) = 0;
+
+ if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
+ {
+ if (! bfd_coff_start_final_link (abfd, info))
+ goto error_return;
+ }
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour (p->u.indirect.section->owner)
+ == bfd_target_coff_flavour))
+ {
+ sub = p->u.indirect.section->owner;
+ if (! bfd_coff_link_output_has_begun (sub, & finfo))
+ {
+ if (! _bfd_coff_link_input_bfd (&finfo, sub))
+ goto error_return;
+ sub->output_has_begun = true;
+ }
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
+ goto error_return;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ }
+ }
+
+ if (! bfd_coff_final_link_postscript (abfd, & finfo))
+ goto error_return;
+
+ /* Free up the buffers used by _bfd_coff_link_input_bfd. */
+
+ coff_debug_merge_hash_table_free (&finfo.debug_merge);
+ debug_merge_allocated = false;
+
+ if (finfo.internal_syms != NULL)
+ {
+ free (finfo.internal_syms);
+ finfo.internal_syms = NULL;
+ }
+ if (finfo.sec_ptrs != NULL)
+ {
+ free (finfo.sec_ptrs);
+ finfo.sec_ptrs = NULL;
+ }
+ if (finfo.sym_indices != NULL)
+ {
+ free (finfo.sym_indices);
+ finfo.sym_indices = NULL;
+ }
+ if (finfo.linenos != NULL)
+ {
+ free (finfo.linenos);
+ finfo.linenos = NULL;
+ }
+ if (finfo.contents != NULL)
+ {
+ free (finfo.contents);
+ finfo.contents = NULL;
+ }
+ if (finfo.external_relocs != NULL)
+ {
+ free (finfo.external_relocs);
+ finfo.external_relocs = NULL;
+ }
+ if (finfo.internal_relocs != NULL)
+ {
+ free (finfo.internal_relocs);
+ finfo.internal_relocs = NULL;
+ }
+
+ /* The value of the last C_FILE symbol is supposed to be the symbol
+ index of the first external symbol. Write it out again if
+ necessary. */
+ if (finfo.last_file_index != -1
+ && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
+ {
+ finfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
+ (PTR) finfo.outsyms);
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + finfo.last_file_index * symesz),
+ SEEK_SET) != 0
+ || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
+ return false;
+ }
+
+ /* If doing task linking (ld --task-link) then make a pass through the
+ global symbols, writing out any that are defined, and making them
+ static. */
+ if (info->task_link)
+ {
+ finfo.failed = false;
+ coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_task_globals,
+ (PTR) &finfo);
+ if (finfo.failed)
+ goto error_return;
+ }
+
+ /* Write out the global symbols. */
+ finfo.failed = false;
+ coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
+ (PTR) &finfo);
+ if (finfo.failed)
+ goto error_return;
+
+ /* The outsyms buffer is used by _bfd_coff_write_global_sym. */
+ if (finfo.outsyms != NULL)
+ {
+ free (finfo.outsyms);
+ finfo.outsyms = NULL;
+ }
+
+ if (info->relocateable && max_output_reloc_count > 0)
+ {
+ /* Now that we have written out all the global symbols, we know
+ the symbol indices to use for relocs against them, and we can
+ finally write out the relocs. */
+ external_relocs = ((bfd_byte *)
+ bfd_malloc (max_output_reloc_count * relsz));
+ if (external_relocs == NULL)
+ goto error_return;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct internal_reloc *irel;
+ struct internal_reloc *irelend;
+ struct coff_link_hash_entry **rel_hash;
+ bfd_byte *erel;
+
+ if (o->reloc_count == 0)
+ continue;
+
+ irel = finfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = finfo.section_info[o->target_index].rel_hashes;
+ erel = external_relocs;
+ for (; irel < irelend; irel++, rel_hash++, erel += relsz)
+ {
+ if (*rel_hash != NULL)
+ {
+ BFD_ASSERT ((*rel_hash)->indx >= 0);
+ irel->r_symndx = (*rel_hash)->indx;
+ }
+ bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
+ }
+
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
+ || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
+ abfd) != relsz * o->reloc_count)
+ goto error_return;
+ }
+
+ free (external_relocs);
+ external_relocs = NULL;
+ }
+
+ /* Free up the section information. */
+ if (finfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (finfo.section_info[i].relocs != NULL)
+ free (finfo.section_info[i].relocs);
+ if (finfo.section_info[i].rel_hashes != NULL)
+ free (finfo.section_info[i].rel_hashes);
+ }
+ free (finfo.section_info);
+ finfo.section_info = NULL;
+ }
+
+ /* If we have optimized stabs strings, output them. */
+ if (coff_hash_table (info)->stab_info != NULL)
+ {
+ if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
+ return false;
+ }
+
+ /* Write out the string table. */
+ if (obj_raw_syment_count (abfd) != 0 || long_section_names)
+ {
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + obj_raw_syment_count (abfd) * symesz),
+ SEEK_SET) != 0)
+ return false;
+
+#if STRING_SIZE_SIZE == 4
+ bfd_h_put_32 (abfd,
+ _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
+ (bfd_byte *) strbuf);
+#else
+ #error Change bfd_h_put_32
+#endif
+
+ if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
+ return false;
+
+ if (! _bfd_stringtab_emit (abfd, finfo.strtab))
+ return false;
+ }
+
+ _bfd_stringtab_free (finfo.strtab);
+
+ /* Setting bfd_get_symcount to 0 will cause write_object_contents to
+ not try to write out the symbols. */
+ bfd_get_symcount (abfd) = 0;
+
+ return true;
+
+ error_return:
+ if (debug_merge_allocated)
+ coff_debug_merge_hash_table_free (&finfo.debug_merge);
+ if (finfo.strtab != NULL)
+ _bfd_stringtab_free (finfo.strtab);
+ if (finfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (finfo.section_info[i].relocs != NULL)
+ free (finfo.section_info[i].relocs);
+ if (finfo.section_info[i].rel_hashes != NULL)
+ free (finfo.section_info[i].rel_hashes);
+ }
+ free (finfo.section_info);
+ }
+ if (finfo.internal_syms != NULL)
+ free (finfo.internal_syms);
+ if (finfo.sec_ptrs != NULL)
+ free (finfo.sec_ptrs);
+ if (finfo.sym_indices != NULL)
+ free (finfo.sym_indices);
+ if (finfo.outsyms != NULL)
+ free (finfo.outsyms);
+ if (finfo.linenos != NULL)
+ free (finfo.linenos);
+ if (finfo.contents != NULL)
+ free (finfo.contents);
+ if (finfo.external_relocs != NULL)
+ free (finfo.external_relocs);
+ if (finfo.internal_relocs != NULL)
+ free (finfo.internal_relocs);
+ if (external_relocs != NULL)
+ free (external_relocs);
+ return false;
+}
+
+/* parse out a -heap <reserved>,<commit> line */
+
+static char *
+dores_com (ptr, output_bfd, heap)
+ char *ptr;
+ bfd *output_bfd;
+ int heap;
+{
+ if (coff_data(output_bfd)->pe)
+ {
+ int val = strtoul (ptr, &ptr, 0);
+ if (heap)
+ pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve =val;
+ else
+ pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve =val;
+
+ if (ptr[0] == ',')
+ {
+ int val = strtoul (ptr+1, &ptr, 0);
+ if (heap)
+ pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit =val;
+ else
+ pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit =val;
+ }
+ }
+ return ptr;
+}
+
+static char *get_name(ptr, dst)
+char *ptr;
+char **dst;
+{
+ while (*ptr == ' ')
+ ptr++;
+ *dst = ptr;
+ while (*ptr && *ptr != ' ')
+ ptr++;
+ *ptr = 0;
+ return ptr+1;
+}
+
+/* Process any magic embedded commands in a section called .drectve */
+
+static int
+process_embedded_commands (output_bfd, info, abfd)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *abfd;
+{
+ asection *sec = bfd_get_section_by_name (abfd, ".drectve");
+ char *s;
+ char *e;
+ char *copy;
+ if (!sec)
+ return 1;
+
+ copy = bfd_malloc ((size_t) sec->_raw_size);
+ if (!copy)
+ return 0;
+ if (! bfd_get_section_contents(abfd, sec, copy, 0, sec->_raw_size))
+ {
+ free (copy);
+ return 0;
+ }
+ e = copy + sec->_raw_size;
+ for (s = copy; s < e ; )
+ {
+ if (s[0]!= '-') {
+ s++;
+ continue;
+ }
+ if (strncmp (s,"-attr", 5) == 0)
+ {
+ char *name;
+ char *attribs;
+ asection *asec;
+
+ int loop = 1;
+ int had_write = 0;
+ int had_read = 0;
+ int had_exec= 0;
+ int had_shared= 0;
+ s += 5;
+ s = get_name(s, &name);
+ s = get_name(s, &attribs);
+ while (loop) {
+ switch (*attribs++)
+ {
+ case 'W':
+ had_write = 1;
+ break;
+ case 'R':
+ had_read = 1;
+ break;
+ case 'S':
+ had_shared = 1;
+ break;
+ case 'X':
+ had_exec = 1;
+ break;
+ default:
+ loop = 0;
+ }
+ }
+ asec = bfd_get_section_by_name (abfd, name);
+ if (asec) {
+ if (had_exec)
+ asec->flags |= SEC_CODE;
+ if (!had_write)
+ asec->flags |= SEC_READONLY;
+ }
+ }
+ else if (strncmp (s,"-heap", 5) == 0)
+ {
+ s = dores_com (s+5, output_bfd, 1);
+ }
+ else if (strncmp (s,"-stack", 6) == 0)
+ {
+ s = dores_com (s+6, output_bfd, 0);
+ }
+ else
+ s++;
+ }
+ free (copy);
+ return 1;
+}
+
+/* Place a marker against all symbols which are used by relocations.
+ This marker can be picked up by the 'do we skip this symbol ?'
+ loop in _bfd_coff_link_input_bfd() and used to prevent skipping
+ that symbol.
+ */
+
+static void
+mark_relocs (finfo, input_bfd)
+ struct coff_final_link_info * finfo;
+ bfd * input_bfd;
+{
+ asection * a;
+
+ if ((bfd_get_file_flags (input_bfd) & HAS_SYMS) == 0)
+ return;
+
+ for (a = input_bfd->sections; a != (asection *) NULL; a = a->next)
+ {
+ struct internal_reloc * internal_relocs;
+ struct internal_reloc * irel;
+ struct internal_reloc * irelend;
+
+
+ if ((a->flags & SEC_RELOC) == 0 || a->reloc_count < 1)
+ continue;
+
+ /* Read in the relocs. */
+ internal_relocs = _bfd_coff_read_internal_relocs
+ (input_bfd, a, false,
+ finfo->external_relocs,
+ finfo->info->relocateable,
+ (finfo->info->relocateable
+ ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
+ : finfo->internal_relocs)
+ );
+
+ if (internal_relocs == NULL)
+ continue;
+
+ irel = internal_relocs;
+ irelend = irel + a->reloc_count;
+
+ /* Place a mark in the sym_indices array (whose entries have
+ been initialised to 0) for all of the symbols that are used
+ in the relocation table. This will then be picked up in the
+ skip/don't pass */
+
+ for (; irel < irelend; irel++)
+ {
+ finfo->sym_indices[ irel->r_symndx ] = -1;
+ }
+ }
+}
+
+/* Link an input file into the linker output file. This function
+ handles all the sections and relocations of the input file at once. */
+
+boolean
+_bfd_coff_link_input_bfd (finfo, input_bfd)
+ struct coff_final_link_info *finfo;
+ bfd *input_bfd;
+{
+ boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *));
+ boolean (*adjust_symndx) PARAMS ((bfd *, struct bfd_link_info *, bfd *,
+ asection *, struct internal_reloc *,
+ boolean *));
+ bfd *output_bfd;
+ const char *strings;
+ bfd_size_type syment_base;
+ unsigned int n_tmask;
+ unsigned int n_btshft;
+ boolean copy, hash;
+ bfd_size_type isymesz;
+ bfd_size_type osymesz;
+ bfd_size_type linesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+ struct internal_syment *isymp;
+ asection **secpp;
+ long *indexp;
+ unsigned long output_index;
+ bfd_byte *outsym;
+ struct coff_link_hash_entry **sym_hash;
+ asection *o;
+
+ /* Move all the symbols to the output file. */
+
+ output_bfd = finfo->output_bfd;
+ sym_is_global = coff_backend_info (input_bfd)->_bfd_coff_sym_is_global;
+ strings = NULL;
+ syment_base = obj_raw_syment_count (output_bfd);
+ isymesz = bfd_coff_symesz (input_bfd);
+ osymesz = bfd_coff_symesz (output_bfd);
+ linesz = bfd_coff_linesz (input_bfd);
+ BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd));
+
+ n_tmask = coff_data (input_bfd)->local_n_tmask;
+ n_btshft = coff_data (input_bfd)->local_n_btshft;
+
+ /* Define macros so that ISFCN, et. al., macros work correctly. */
+#define N_TMASK n_tmask
+#define N_BTSHFT n_btshft
+
+ copy = false;
+ if (! finfo->info->keep_memory)
+ copy = true;
+ hash = true;
+ if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = false;
+
+ if (! _bfd_coff_get_external_symbols (input_bfd))
+ return false;
+
+ esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
+ esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
+ isymp = finfo->internal_syms;
+ secpp = finfo->sec_ptrs;
+ indexp = finfo->sym_indices;
+ output_index = syment_base;
+ outsym = finfo->outsyms;
+
+ if (coff_data (output_bfd)->pe)
+ {
+ if (! process_embedded_commands (output_bfd, finfo->info, input_bfd))
+ return false;
+ }
+
+ /* If we are going to perform relocations and also strip/discard some symbols
+ then we must make sure that we do not strip/discard those symbols that are
+ going to be involved in the relocations */
+ if (( finfo->info->strip != strip_none
+ || finfo->info->discard != discard_none)
+ && finfo->info->relocateable)
+ {
+ /* mark the symbol array as 'not-used' */
+ memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
+
+ mark_relocs (finfo, input_bfd);
+ }
+
+ while (esym < esym_end)
+ {
+ struct internal_syment isym;
+ boolean skip;
+ boolean global;
+ boolean dont_skip_symbol;
+ int add;
+
+ bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
+
+ /* Make a copy of *isymp so that the relocate_section function
+ always sees the original values. This is more reliable than
+ always recomputing the symbol value even if we are stripping
+ the symbol. */
+ isym = *isymp;
+
+ if (isym.n_scnum != 0)
+ *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
+ else
+ {
+ if (isym.n_value == 0)
+ *secpp = bfd_und_section_ptr;
+ else
+ *secpp = bfd_com_section_ptr;
+ }
+
+ /* Extract the flag indicating if this symbol is used by a
+ relocation. */
+ if ((finfo->info->strip != strip_none
+ || finfo->info->discard != discard_none)
+ && finfo->info->relocateable)
+ dont_skip_symbol = *indexp;
+ else
+ dont_skip_symbol = false;
+
+ *indexp = -1;
+
+ skip = false;
+ global = false;
+ add = 1 + isym.n_numaux;
+
+ /* If we are stripping all symbols, we want to skip this one. */
+ if (finfo->info->strip == strip_all && ! dont_skip_symbol)
+ skip = true;
+
+ if (! skip)
+ {
+ if (isym.n_sclass == C_EXT
+ || isym.n_sclass == C_WEAKEXT
+ || (obj_pe (input_bfd) && isym.n_sclass == C_NT_WEAK)
+#ifdef C_SYSTEM
+ || isym.n_sclass == C_SYSTEM
+#endif
+ || (sym_is_global && (*sym_is_global) (input_bfd, &isym)))
+ {
+ /* This is a global symbol. Global symbols come at the
+ end of the symbol table, so skip them for now.
+ Locally defined function symbols, however, are an
+ exception, and are not moved to the end. */
+ global = true;
+ if (! ISFCN (isym.n_type) || isym.n_scnum == 0)
+ skip = true;
+ }
+ else
+ {
+ /* This is a local symbol. Skip it if we are discarding
+ local symbols. */
+ if (finfo->info->discard == discard_all && ! dont_skip_symbol)
+ skip = true;
+ }
+ }
+
+ /* If we stripping debugging symbols, and this is a debugging
+ symbol, then skip it. FIXME: gas sets the section to N_ABS
+ for some types of debugging symbols; I don't know if this is
+ a bug or not. In any case, we handle it here. */
+ if (! skip
+ && finfo->info->strip == strip_debugger
+ && ! dont_skip_symbol
+ && (isym.n_scnum == N_DEBUG
+ || (isym.n_scnum == N_ABS
+ && (isym.n_sclass == C_AUTO
+ || isym.n_sclass == C_REG
+ || isym.n_sclass == C_MOS
+ || isym.n_sclass == C_MOE
+ || isym.n_sclass == C_MOU
+ || isym.n_sclass == C_ARG
+ || isym.n_sclass == C_REGPARM
+ || isym.n_sclass == C_FIELD
+ || isym.n_sclass == C_EOS))))
+ skip = true;
+
+ /* If some symbols are stripped based on the name, work out the
+ name and decide whether to skip this symbol. */
+ if (! skip
+ && (finfo->info->strip == strip_some
+ || finfo->info->discard == discard_l))
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
+ if (name == NULL)
+ return false;
+
+ if (! dont_skip_symbol
+ && ((finfo->info->strip == strip_some
+ && (bfd_hash_lookup (finfo->info->keep_hash, name, false,
+ false) == NULL))
+ || (! global
+ && finfo->info->discard == discard_l
+ && bfd_is_local_label_name (input_bfd, name))))
+ skip = true;
+ }
+
+ /* If this is an enum, struct, or union tag, see if we have
+ already output an identical type. */
+ if (! skip
+ && (finfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0
+ && (isym.n_sclass == C_ENTAG
+ || isym.n_sclass == C_STRTAG
+ || isym.n_sclass == C_UNTAG)
+ && isym.n_numaux == 1)
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ struct coff_debug_merge_hash_entry *mh;
+ struct coff_debug_merge_type *mt;
+ union internal_auxent aux;
+ struct coff_debug_merge_element **epp;
+ bfd_byte *esl, *eslend;
+ struct internal_syment *islp;
+
+ name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
+ if (name == NULL)
+ return false;
+
+ /* Ignore fake names invented by compiler; treat them all as
+ the same name. */
+ if (*name == '~' || *name == '.' || *name == '$'
+ || (*name == bfd_get_symbol_leading_char (input_bfd)
+ && (name[1] == '~' || name[1] == '.' || name[1] == '$')))
+ name = "";
+
+ mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name,
+ true, true);
+ if (mh == NULL)
+ return false;
+
+ /* Allocate memory to hold type information. If this turns
+ out to be a duplicate, we pass this address to
+ bfd_release. */
+ mt = ((struct coff_debug_merge_type *)
+ bfd_alloc (input_bfd,
+ sizeof (struct coff_debug_merge_type)));
+ if (mt == NULL)
+ return false;
+ mt->class = isym.n_sclass;
+
+ /* Pick up the aux entry, which points to the end of the tag
+ entries. */
+ bfd_coff_swap_aux_in (input_bfd, (PTR) (esym + isymesz),
+ isym.n_type, isym.n_sclass, 0, isym.n_numaux,
+ (PTR) &aux);
+
+ /* Gather the elements. */
+ epp = &mt->elements;
+ mt->elements = NULL;
+ islp = isymp + 2;
+ esl = esym + 2 * isymesz;
+ eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd)
+ + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz);
+ while (esl < eslend)
+ {
+ const char *elename;
+ char elebuf[SYMNMLEN + 1];
+ char *copy;
+
+ bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp);
+
+ *epp = ((struct coff_debug_merge_element *)
+ bfd_alloc (input_bfd,
+ sizeof (struct coff_debug_merge_element)));
+ if (*epp == NULL)
+ return false;
+
+ elename = _bfd_coff_internal_syment_name (input_bfd, islp,
+ elebuf);
+ if (elename == NULL)
+ return false;
+
+ copy = (char *) bfd_alloc (input_bfd, strlen (elename) + 1);
+ if (copy == NULL)
+ return false;
+ strcpy (copy, elename);
+
+ (*epp)->name = copy;
+ (*epp)->type = islp->n_type;
+ (*epp)->tagndx = 0;
+ if (islp->n_numaux >= 1
+ && islp->n_type != T_NULL
+ && islp->n_sclass != C_EOS)
+ {
+ union internal_auxent eleaux;
+ long indx;
+
+ bfd_coff_swap_aux_in (input_bfd, (PTR) (esl + isymesz),
+ islp->n_type, islp->n_sclass, 0,
+ islp->n_numaux, (PTR) &eleaux);
+ indx = eleaux.x_sym.x_tagndx.l;
+
+ /* FIXME: If this tagndx entry refers to a symbol
+ defined later in this file, we just ignore it.
+ Handling this correctly would be tedious, and may
+ not be required. */
+
+ if (indx > 0
+ && (indx
+ < ((esym -
+ (bfd_byte *) obj_coff_external_syms (input_bfd))
+ / (long) isymesz)))
+ {
+ (*epp)->tagndx = finfo->sym_indices[indx];
+ if ((*epp)->tagndx < 0)
+ (*epp)->tagndx = 0;
+ }
+ }
+ epp = &(*epp)->next;
+ *epp = NULL;
+
+ esl += (islp->n_numaux + 1) * isymesz;
+ islp += islp->n_numaux + 1;
+ }
+
+ /* See if we already have a definition which matches this
+ type. We always output the type if it has no elements,
+ for simplicity. */
+ if (mt->elements == NULL)
+ bfd_release (input_bfd, (PTR) mt);
+ else
+ {
+ struct coff_debug_merge_type *mtl;
+
+ for (mtl = mh->types; mtl != NULL; mtl = mtl->next)
+ {
+ struct coff_debug_merge_element *me, *mel;
+
+ if (mtl->class != mt->class)
+ continue;
+
+ for (me = mt->elements, mel = mtl->elements;
+ me != NULL && mel != NULL;
+ me = me->next, mel = mel->next)
+ {
+ if (strcmp (me->name, mel->name) != 0
+ || me->type != mel->type
+ || me->tagndx != mel->tagndx)
+ break;
+ }
+
+ if (me == NULL && mel == NULL)
+ break;
+ }
+
+ if (mtl == NULL || (bfd_size_type) mtl->indx >= syment_base)
+ {
+ /* This is the first definition of this type. */
+ mt->indx = output_index;
+ mt->next = mh->types;
+ mh->types = mt;
+ }
+ else
+ {
+ /* This is a redefinition which can be merged. */
+ bfd_release (input_bfd, (PTR) mt);
+ *indexp = mtl->indx;
+ add = (eslend - esym) / isymesz;
+ skip = true;
+ }
+ }
+ }
+
+ /* We now know whether we are to skip this symbol or not. */
+ if (! skip)
+ {
+ /* Adjust the symbol in order to output it. */
+
+ if (isym._n._n_n._n_zeroes == 0
+ && isym._n._n_n._n_offset != 0)
+ {
+ const char *name;
+ bfd_size_type indx;
+
+ /* This symbol has a long name. Enter it in the string
+ table we are building. Note that we do not check
+ bfd_coff_symname_in_debug. That is only true for
+ XCOFF, and XCOFF requires different linking code
+ anyhow. */
+ name = _bfd_coff_internal_syment_name (input_bfd, &isym,
+ (char *) NULL);
+ if (name == NULL)
+ return false;
+ indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+
+ if (isym.n_scnum > 0)
+ {
+ isym.n_scnum = (*secpp)->output_section->target_index;
+ isym.n_value += (*secpp)->output_offset;
+ if (! obj_pe (input_bfd))
+ isym.n_value -= (*secpp)->vma;
+ if (! obj_pe (finfo->output_bfd))
+ isym.n_value += (*secpp)->output_section->vma;
+ }
+
+ /* The value of a C_FILE symbol is the symbol index of the
+ next C_FILE symbol. The value of the last C_FILE symbol
+ is the symbol index to the first external symbol
+ (actually, coff_renumber_symbols does not get this
+ right--it just sets the value of the last C_FILE symbol
+ to zero--and nobody has ever complained about it). We
+ try to get this right, below, just before we write the
+ symbols out, but in the general case we may have to write
+ the symbol out twice. */
+ if (isym.n_sclass == C_FILE)
+ {
+ if (finfo->last_file_index != -1
+ && finfo->last_file.n_value != (long) output_index)
+ {
+ /* We must correct the value of the last C_FILE entry. */
+ finfo->last_file.n_value = output_index;
+ if ((bfd_size_type) finfo->last_file_index >= syment_base)
+ {
+ /* The last C_FILE symbol is in this input file. */
+ bfd_coff_swap_sym_out (output_bfd,
+ (PTR) &finfo->last_file,
+ (PTR) (finfo->outsyms
+ + ((finfo->last_file_index
+ - syment_base)
+ * osymesz)));
+ }
+ else
+ {
+ /* We have already written out the last C_FILE
+ symbol. We need to write it out again. We
+ borrow *outsym temporarily. */
+ bfd_coff_swap_sym_out (output_bfd,
+ (PTR) &finfo->last_file,
+ (PTR) outsym);
+ if (bfd_seek (output_bfd,
+ (obj_sym_filepos (output_bfd)
+ + finfo->last_file_index * osymesz),
+ SEEK_SET) != 0
+ || (bfd_write (outsym, osymesz, 1, output_bfd)
+ != osymesz))
+ return false;
+ }
+ }
+
+ finfo->last_file_index = output_index;
+ finfo->last_file = isym;
+ }
+
+ /* If doing task linking, convert normal global function symbols to
+ static functions. */
+
+ if (finfo->info->task_link
+ && (isym.n_sclass == C_EXT
+ || isym.n_sclass == C_WEAKEXT
+ || (obj_pe (input_bfd) && isym.n_sclass == C_NT_WEAK)))
+ isym.n_sclass = C_STAT;
+
+ /* Output the symbol. */
+
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
+
+ *indexp = output_index;
+
+ if (global)
+ {
+ long indx;
+ struct coff_link_hash_entry *h;
+
+ indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd))
+ / isymesz);
+ h = obj_coff_sym_hashes (input_bfd)[indx];
+ if (h == NULL)
+ {
+ /* This can happen if there were errors earlier in
+ the link. */
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ h->indx = output_index;
+ }
+
+ output_index += add;
+ outsym += add * osymesz;
+ }
+
+ esym += add * isymesz;
+ isymp += add;
+ ++secpp;
+ ++indexp;
+ for (--add; add > 0; --add)
+ {
+ *secpp++ = NULL;
+ *indexp++ = -1;
+ }
+ }
+
+ /* Fix up the aux entries. This must be done in a separate pass,
+ because we don't know the correct symbol indices until we have
+ already decided which symbols we are going to keep. */
+
+ esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
+ esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
+ isymp = finfo->internal_syms;
+ indexp = finfo->sym_indices;
+ sym_hash = obj_coff_sym_hashes (input_bfd);
+ outsym = finfo->outsyms;
+ while (esym < esym_end)
+ {
+ int add;
+
+ add = 1 + isymp->n_numaux;
+
+ if ((*indexp < 0
+ || (bfd_size_type) *indexp < syment_base)
+ && (*sym_hash == NULL
+ || (*sym_hash)->auxbfd != input_bfd))
+ esym += add * isymesz;
+ else
+ {
+ struct coff_link_hash_entry *h;
+ int i;
+
+ h = NULL;
+ if (*indexp < 0)
+ {
+ h = *sym_hash;
+
+ /* The m68k-motorola-sysv assembler will sometimes
+ generate two symbols with the same name, but only one
+ will have aux entries. */
+ BFD_ASSERT (isymp->n_numaux == 0
+ || h->numaux == isymp->n_numaux);
+ }
+
+ esym += isymesz;
+
+ if (h == NULL)
+ outsym += osymesz;
+
+ /* Handle the aux entries. This handling is based on
+ coff_pointerize_aux. I don't know if it always correct. */
+ for (i = 0; i < isymp->n_numaux && esym < esym_end; i++)
+ {
+ union internal_auxent aux;
+ union internal_auxent *auxp;
+
+ if (h != NULL)
+ auxp = h->aux + i;
+ else
+ {
+ bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ (PTR) &aux);
+ auxp = &aux;
+ }
+
+ if (isymp->n_sclass == C_FILE)
+ {
+ /* If this is a long filename, we must put it in the
+ string table. */
+ if (auxp->x_file.x_n.x_zeroes == 0
+ && auxp->x_file.x_n.x_offset != 0)
+ {
+ const char *filename;
+ bfd_size_type indx;
+
+ BFD_ASSERT (auxp->x_file.x_n.x_offset
+ >= STRING_SIZE_SIZE);
+ if (strings == NULL)
+ {
+ strings = _bfd_coff_read_string_table (input_bfd);
+ if (strings == NULL)
+ return false;
+ }
+ filename = strings + auxp->x_file.x_n.x_offset;
+ indx = _bfd_stringtab_add (finfo->strtab, filename,
+ hash, copy);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
+ }
+ }
+ else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
+ {
+ unsigned long indx;
+
+ if (ISFCN (isymp->n_type)
+ || ISTAG (isymp->n_sclass)
+ || isymp->n_sclass == C_BLOCK
+ || isymp->n_sclass == C_FCN)
+ {
+ indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l;
+ if (indx > 0
+ && indx < obj_raw_syment_count (input_bfd))
+ {
+ /* We look forward through the symbol for
+ the index of the next symbol we are going
+ to include. I don't know if this is
+ entirely right. */
+ while ((finfo->sym_indices[indx] < 0
+ || ((bfd_size_type) finfo->sym_indices[indx]
+ < syment_base))
+ && indx < obj_raw_syment_count (input_bfd))
+ ++indx;
+ if (indx >= obj_raw_syment_count (input_bfd))
+ indx = output_index;
+ else
+ indx = finfo->sym_indices[indx];
+ auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx;
+ }
+ }
+
+ indx = auxp->x_sym.x_tagndx.l;
+ if (indx > 0 && indx < obj_raw_syment_count (input_bfd))
+ {
+ long symindx;
+
+ symindx = finfo->sym_indices[indx];
+ if (symindx < 0)
+ auxp->x_sym.x_tagndx.l = 0;
+ else
+ auxp->x_sym.x_tagndx.l = symindx;
+ }
+
+ /* The .bf symbols are supposed to be linked through
+ the endndx field. We need to carry this list
+ across object files. */
+ if (i == 0
+ && h == NULL
+ && isymp->n_sclass == C_FCN
+ && (isymp->_n._n_n._n_zeroes != 0
+ || isymp->_n._n_n._n_offset == 0)
+ && isymp->_n._n_name[0] == '.'
+ && isymp->_n._n_name[1] == 'b'
+ && isymp->_n._n_name[2] == 'f'
+ && isymp->_n._n_name[3] == '\0')
+ {
+ if (finfo->last_bf_index != -1)
+ {
+ finfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l =
+ *indexp;
+
+ if ((bfd_size_type) finfo->last_bf_index
+ >= syment_base)
+ {
+ PTR auxout;
+
+ /* The last .bf symbol is in this input
+ file. This will only happen if the
+ assembler did not set up the .bf
+ endndx symbols correctly. */
+ auxout = (PTR) (finfo->outsyms
+ + ((finfo->last_bf_index
+ - syment_base)
+ * osymesz));
+ bfd_coff_swap_aux_out (output_bfd,
+ (PTR) &finfo->last_bf,
+ isymp->n_type,
+ isymp->n_sclass,
+ 0, isymp->n_numaux,
+ auxout);
+ }
+ else
+ {
+ /* We have already written out the last
+ .bf aux entry. We need to write it
+ out again. We borrow *outsym
+ temporarily. FIXME: This case should
+ be made faster. */
+ bfd_coff_swap_aux_out (output_bfd,
+ (PTR) &finfo->last_bf,
+ isymp->n_type,
+ isymp->n_sclass,
+ 0, isymp->n_numaux,
+ (PTR) outsym);
+ if (bfd_seek (output_bfd,
+ (obj_sym_filepos (output_bfd)
+ + finfo->last_bf_index * osymesz),
+ SEEK_SET) != 0
+ || bfd_write (outsym, osymesz, 1,
+ output_bfd) != osymesz)
+ return false;
+ }
+ }
+
+ if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0)
+ finfo->last_bf_index = -1;
+ else
+ {
+ /* The endndx field of this aux entry must
+ be updated with the symbol number of the
+ next .bf symbol. */
+ finfo->last_bf = *auxp;
+ finfo->last_bf_index = (((outsym - finfo->outsyms)
+ / osymesz)
+ + syment_base);
+ }
+ }
+ }
+
+ if (h == NULL)
+ {
+ bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ (PTR) outsym);
+ outsym += osymesz;
+ }
+
+ esym += isymesz;
+ }
+ }
+
+ indexp += add;
+ isymp += add;
+ sym_hash += add;
+ }
+
+ /* Relocate the line numbers, unless we are stripping them. */
+ if (finfo->info->strip == strip_none
+ || finfo->info->strip == strip_some)
+ {
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ bfd_vma offset;
+ bfd_byte *eline;
+ bfd_byte *elineend;
+
+ /* FIXME: If SEC_HAS_CONTENTS is not for the section, then
+ build_link_order in ldwrite.c will not have created a
+ link order, which means that we will not have seen this
+ input section in _bfd_coff_final_link, which means that
+ we will not have allocated space for the line numbers of
+ this section. I don't think line numbers can be
+ meaningful for a section which does not have
+ SEC_HAS_CONTENTS set, but, if they do, this must be
+ changed. */
+ if (o->lineno_count == 0
+ || (o->output_section->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0
+ || bfd_read (finfo->linenos, linesz, o->lineno_count,
+ input_bfd) != linesz * o->lineno_count)
+ return false;
+
+ offset = o->output_section->vma + o->output_offset - o->vma;
+ eline = finfo->linenos;
+ elineend = eline + linesz * o->lineno_count;
+ for (; eline < elineend; eline += linesz)
+ {
+ struct internal_lineno iline;
+
+ bfd_coff_swap_lineno_in (input_bfd, (PTR) eline, (PTR) &iline);
+
+ if (iline.l_lnno != 0)
+ iline.l_addr.l_paddr += offset;
+ else if (iline.l_addr.l_symndx >= 0
+ && ((unsigned long) iline.l_addr.l_symndx
+ < obj_raw_syment_count (input_bfd)))
+ {
+ long indx;
+
+ indx = finfo->sym_indices[iline.l_addr.l_symndx];
+
+ if (indx < 0)
+ {
+ /* These line numbers are attached to a symbol
+ which we are stripping. We should really
+ just discard the line numbers, but that would
+ be a pain because we have already counted
+ them. */
+ indx = 0;
+ }
+ else
+ {
+ struct internal_syment is;
+ union internal_auxent ia;
+
+ /* Fix up the lnnoptr field in the aux entry of
+ the symbol. It turns out that we can't do
+ this when we modify the symbol aux entries,
+ because gas sometimes screws up the lnnoptr
+ field and makes it an offset from the start
+ of the line numbers rather than an absolute
+ file index. */
+ bfd_coff_swap_sym_in (output_bfd,
+ (PTR) (finfo->outsyms
+ + ((indx - syment_base)
+ * osymesz)),
+ (PTR) &is);
+ if ((ISFCN (is.n_type)
+ || is.n_sclass == C_BLOCK)
+ && is.n_numaux >= 1)
+ {
+ PTR auxptr;
+
+ auxptr = (PTR) (finfo->outsyms
+ + ((indx - syment_base + 1)
+ * osymesz));
+ bfd_coff_swap_aux_in (output_bfd, auxptr,
+ is.n_type, is.n_sclass,
+ 0, is.n_numaux, (PTR) &ia);
+ ia.x_sym.x_fcnary.x_fcn.x_lnnoptr =
+ (o->output_section->line_filepos
+ + o->output_section->lineno_count * linesz
+ + eline - finfo->linenos);
+ bfd_coff_swap_aux_out (output_bfd, (PTR) &ia,
+ is.n_type, is.n_sclass, 0,
+ is.n_numaux, auxptr);
+ }
+ }
+
+ iline.l_addr.l_symndx = indx;
+ }
+
+ bfd_coff_swap_lineno_out (output_bfd, (PTR) &iline, (PTR) eline);
+ }
+
+ if (bfd_seek (output_bfd,
+ (o->output_section->line_filepos
+ + o->output_section->lineno_count * linesz),
+ SEEK_SET) != 0
+ || bfd_write (finfo->linenos, linesz, o->lineno_count,
+ output_bfd) != linesz * o->lineno_count)
+ return false;
+
+ o->output_section->lineno_count += o->lineno_count;
+ }
+ }
+
+ /* If we swapped out a C_FILE symbol, guess that the next C_FILE
+ symbol will be the first symbol in the next input file. In the
+ normal case, this will save us from writing out the C_FILE symbol
+ again. */
+ if (finfo->last_file_index != -1
+ && (bfd_size_type) finfo->last_file_index >= syment_base)
+ {
+ finfo->last_file.n_value = output_index;
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file,
+ (PTR) (finfo->outsyms
+ + ((finfo->last_file_index - syment_base)
+ * osymesz)));
+ }
+
+ /* Write the modified symbols to the output file. */
+ if (outsym > finfo->outsyms)
+ {
+ if (bfd_seek (output_bfd,
+ obj_sym_filepos (output_bfd) + syment_base * osymesz,
+ SEEK_SET) != 0
+ || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1,
+ output_bfd)
+ != (bfd_size_type) (outsym - finfo->outsyms)))
+ return false;
+
+ BFD_ASSERT ((obj_raw_syment_count (output_bfd)
+ + (outsym - finfo->outsyms) / osymesz)
+ == output_index);
+
+ obj_raw_syment_count (output_bfd) = output_index;
+ }
+
+ /* Relocate the contents of each section. */
+ adjust_symndx = coff_backend_info (input_bfd)->_bfd_coff_adjust_symndx;
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ bfd_byte *contents;
+ struct coff_section_tdata *secdata;
+
+ if (! o->linker_mark)
+ {
+ /* This section was omitted from the link. */
+ continue;
+ }
+
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
+ {
+ if ((o->flags & SEC_RELOC) != 0
+ && o->reloc_count != 0)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: relocs in section `%s', but it has no contents"),
+ bfd_get_filename (input_bfd),
+ bfd_get_section_name (input_bfd, o)));
+ bfd_set_error (bfd_error_no_contents);
+ return false;
+ }
+
+ continue;
+ }
+
+ secdata = coff_section_data (input_bfd, o);
+ if (secdata != NULL && secdata->contents != NULL)
+ contents = secdata->contents;
+ else
+ {
+ if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
+ (file_ptr) 0, o->_raw_size))
+ return false;
+ contents = finfo->contents;
+ }
+
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ int target_index;
+ struct internal_reloc *internal_relocs;
+ struct internal_reloc *irel;
+
+ /* Read in the relocs. */
+ target_index = o->output_section->target_index;
+ internal_relocs = (_bfd_coff_read_internal_relocs
+ (input_bfd, o, false, finfo->external_relocs,
+ finfo->info->relocateable,
+ (finfo->info->relocateable
+ ? (finfo->section_info[target_index].relocs
+ + o->output_section->reloc_count)
+ : finfo->internal_relocs)));
+ if (internal_relocs == NULL)
+ return false;
+
+ /* Call processor specific code to relocate the section
+ contents. */
+ if (! bfd_coff_relocate_section (output_bfd, finfo->info,
+ input_bfd, o,
+ contents,
+ internal_relocs,
+ finfo->internal_syms,
+ finfo->sec_ptrs))
+ return false;
+
+ if (finfo->info->relocateable)
+ {
+ bfd_vma offset;
+ struct internal_reloc *irelend;
+ struct coff_link_hash_entry **rel_hash;
+
+ offset = o->output_section->vma + o->output_offset - o->vma;
+ irel = internal_relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = (finfo->section_info[target_index].rel_hashes
+ + o->output_section->reloc_count);
+ for (; irel < irelend; irel++, rel_hash++)
+ {
+ struct coff_link_hash_entry *h;
+ boolean adjusted;
+
+ *rel_hash = NULL;
+
+ /* Adjust the reloc address and symbol index. */
+
+ irel->r_vaddr += offset;
+
+ if (irel->r_symndx == -1)
+ continue;
+
+ if (adjust_symndx)
+ {
+ if (! (*adjust_symndx) (output_bfd, finfo->info,
+ input_bfd, o, irel,
+ &adjusted))
+ return false;
+ if (adjusted)
+ continue;
+ }
+
+ h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx];
+ if (h != NULL)
+ {
+ /* This is a global symbol. */
+ if (h->indx >= 0)
+ irel->r_symndx = h->indx;
+ else
+ {
+ /* This symbol is being written at the end
+ of the file, and we do not yet know the
+ symbol index. We save the pointer to the
+ hash table entry in the rel_hash list.
+ We set the indx field to -2 to indicate
+ that this symbol must not be stripped. */
+ *rel_hash = h;
+ h->indx = -2;
+ }
+ }
+ else
+ {
+ long indx;
+
+ indx = finfo->sym_indices[irel->r_symndx];
+ if (indx != -1)
+ irel->r_symndx = indx;
+ else
+ {
+ struct internal_syment *is;
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ /* This reloc is against a symbol we are
+ stripping. This should have been handled
+ by the 'dont_skip_symbol' code in the while
+ loop at the top of this function. */
+
+ is = finfo->internal_syms + irel->r_symndx;
+
+ name = (_bfd_coff_internal_syment_name
+ (input_bfd, is, buf));
+ if (name == NULL)
+ return false;
+
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, name, input_bfd, o,
+ irel->r_vaddr)))
+ return false;
+ }
+ }
+ }
+
+ o->output_section->reloc_count += o->reloc_count;
+ }
+ }
+
+ /* Write out the modified section contents. */
+ if (secdata == NULL || secdata->stab_info == NULL)
+ {
+ if (! bfd_set_section_contents (output_bfd, o->output_section,
+ contents, o->output_offset,
+ (o->_cooked_size != 0
+ ? o->_cooked_size
+ : o->_raw_size)))
+ return false;
+ }
+ else
+ {
+ if (! (_bfd_write_section_stabs
+ (output_bfd, &coff_hash_table (finfo->info)->stab_info,
+ o, &secdata->stab_info, contents)))
+ return false;
+ }
+ }
+
+ if (! finfo->info->keep_memory)
+ {
+ if (! _bfd_coff_free_symbols (input_bfd))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out a global symbol. Called via coff_link_hash_traverse. */
+
+boolean
+_bfd_coff_write_global_sym (h, data)
+ struct coff_link_hash_entry *h;
+ PTR data;
+{
+ struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
+ bfd *output_bfd;
+ struct internal_syment isym;
+ bfd_size_type symesz;
+ unsigned int i;
+
+ output_bfd = finfo->output_bfd;
+
+ if (h->indx >= 0)
+ return true;
+
+ if (h->indx != -2
+ && (finfo->info->strip == strip_all
+ || (finfo->info->strip == strip_some
+ && (bfd_hash_lookup (finfo->info->keep_hash,
+ h->root.root.string, false, false)
+ == NULL))))
+ return true;
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ abort ();
+ return false;
+
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ isym.n_scnum = N_UNDEF;
+ isym.n_value = 0;
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section->output_section;
+ if (bfd_is_abs_section (sec))
+ isym.n_scnum = N_ABS;
+ else
+ isym.n_scnum = sec->target_index;
+ isym.n_value = (h->root.u.def.value
+ + h->root.u.def.section->output_offset);
+ if (! obj_pe (finfo->output_bfd))
+ isym.n_value += sec->vma;
+ }
+ break;
+
+ case bfd_link_hash_common:
+ isym.n_scnum = N_UNDEF;
+ isym.n_value = h->root.u.c.size;
+ break;
+
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ /* Just ignore these. They can't be handled anyhow. */
+ return true;
+ }
+
+ if (strlen (h->root.root.string) <= SYMNMLEN)
+ strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN);
+ else
+ {
+ boolean hash;
+ bfd_size_type indx;
+
+ hash = true;
+ if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = false;
+ indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash,
+ false);
+ if (indx == (bfd_size_type) -1)
+ {
+ finfo->failed = true;
+ return false;
+ }
+ isym._n._n_n._n_zeroes = 0;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+
+ isym.n_sclass = h->class;
+ isym.n_type = h->type;
+
+ if (isym.n_sclass == C_NULL)
+ isym.n_sclass = C_EXT;
+
+ /* If doing task linking and this is the pass where we convert
+ defined globals to statics, then do that conversion now. If the
+ symbol is not being converted, just ignore it and it will be
+ output during a later pass. */
+ if (finfo->global_to_static)
+ {
+ if (isym.n_sclass != C_EXT
+ && isym.n_sclass != C_WEAKEXT
+ && (! obj_pe (output_bfd) || isym.n_sclass != C_NT_WEAK))
+ {
+ return true;
+ }
+ isym.n_sclass = C_STAT;
+ }
+
+ isym.n_numaux = h->numaux;
+
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms);
+
+ symesz = bfd_coff_symesz (output_bfd);
+
+ if (bfd_seek (output_bfd,
+ (obj_sym_filepos (output_bfd)
+ + obj_raw_syment_count (output_bfd) * symesz),
+ SEEK_SET) != 0
+ || bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz)
+ {
+ finfo->failed = true;
+ return false;
+ }
+
+ h->indx = obj_raw_syment_count (output_bfd);
+
+ ++obj_raw_syment_count (output_bfd);
+
+ /* Write out any associated aux entries. There normally will be
+ none. If there are any, I have no idea how to modify them. */
+ for (i = 0; i < isym.n_numaux; i++)
+ {
+ bfd_coff_swap_aux_out (output_bfd, (PTR) (h->aux + i), isym.n_type,
+ isym.n_sclass, i, isym.n_numaux,
+ (PTR) finfo->outsyms);
+ if (bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz)
+ {
+ finfo->failed = true;
+ return false;
+ }
+ ++obj_raw_syment_count (output_bfd);
+ }
+
+ return true;
+}
+
+/* Write out task global symbols, converting them to statics. Called
+ via coff_link_hash_traverse. Calls bfd_coff_write_global_sym to do
+ the dirty work, if the symbol we are processing needs conversion. */
+
+boolean
+_bfd_coff_write_task_globals (h, data)
+ struct coff_link_hash_entry *h;
+ PTR data;
+{
+ struct coff_final_link_info *finfo = (struct coff_final_link_info *) data;
+ boolean rtnval = true;
+ boolean save_global_to_static;
+
+ if (h->indx < 0)
+ {
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ save_global_to_static = finfo->global_to_static;
+ finfo->global_to_static = true;
+ rtnval = _bfd_coff_write_global_sym (h, data);
+ finfo->global_to_static = save_global_to_static;
+ break;
+ default:
+ break;
+ }
+ }
+ return (rtnval);
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+boolean
+_bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
+ bfd *output_bfd;
+ struct coff_final_link_info *finfo;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+{
+ reloc_howto_type *howto;
+ struct internal_reloc *irel;
+ struct coff_link_hash_entry **rel_hash_ptr;
+
+ howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (link_order->u.reloc.p->addend != 0)
+ {
+ bfd_size_type size;
+ bfd_byte *buf;
+ bfd_reloc_status_type rstat;
+ boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL)
+ return false;
+
+ rstat = _bfd_relocate_contents (howto, output_bfd,
+ link_order->u.reloc.p->addend, buf);
+ switch (rstat)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info,
+ (link_order->type == bfd_section_reloc_link_order
+ ? bfd_section_name (output_bfd,
+ link_order->u.reloc.p->u.section)
+ : link_order->u.reloc.p->u.name),
+ howto->name, link_order->u.reloc.p->addend,
+ (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return false;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
+ (file_ptr) link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return false;
+ }
+
+ /* Store the reloc information in the right place. It will get
+ swapped and written out at the end of the final_link routine. */
+
+ irel = (finfo->section_info[output_section->target_index].relocs
+ + output_section->reloc_count);
+ rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
+ + output_section->reloc_count);
+
+ memset (irel, 0, sizeof (struct internal_reloc));
+ *rel_hash_ptr = NULL;
+
+ irel->r_vaddr = output_section->vma + link_order->offset;
+
+ if (link_order->type == bfd_section_reloc_link_order)
+ {
+ /* We need to somehow locate a symbol in the right section. The
+ symbol must either have a value of zero, or we must adjust
+ the addend by the value of the symbol. FIXME: Write this
+ when we need it. The old linker couldn't handle this anyhow. */
+ abort ();
+ *rel_hash_ptr = NULL;
+ irel->r_symndx = 0;
+ }
+ else
+ {
+ struct coff_link_hash_entry *h;
+
+ h = ((struct coff_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (output_bfd, finfo->info,
+ link_order->u.reloc.p->u.name,
+ false, false, true));
+ if (h != NULL)
+ {
+ if (h->indx >= 0)
+ irel->r_symndx = h->indx;
+ else
+ {
+ /* Set the index to -2 to force this symbol to get
+ written out. */
+ h->indx = -2;
+ *rel_hash_ptr = h;
+ irel->r_symndx = 0;
+ }
+ }
+ else
+ {
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ irel->r_symndx = 0;
+ }
+ }
+
+ /* FIXME: Is this always right? */
+ irel->r_type = howto->type;
+
+ /* r_size is only used on the RS/6000, which needs its own linker
+ routines anyhow. r_extern is only used for ECOFF. */
+
+ /* FIXME: What is the right value for r_offset? Is zero OK? */
+
+ ++output_section->reloc_count;
+
+ return true;
+}
+
+/* A basic reloc handling routine which may be used by processors with
+ simple relocs. */
+
+boolean
+_bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents, relocs, syms,
+ sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma addend;
+ bfd_vma val;
+ reloc_howto_type *howto;
+ bfd_reloc_status_type rstat;
+
+ symndx = rel->r_symndx;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ }
+ else
+ {
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ }
+
+ /* COFF treats common symbols in one of two ways. Either the
+ size of the symbol is included in the section contents, or it
+ is not. We assume that the size is not included, and force
+ the rtype_to_howto function to adjust the addend as needed. */
+
+ if (sym != NULL && sym->n_scnum != 0)
+ addend = - sym->n_value;
+ else
+ addend = 0;
+
+
+ howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
+ sym, &addend);
+ if (howto == NULL)
+ return false;
+
+ /* If we are doing a relocateable link, then we can just ignore
+ a PC relative reloc that is pcrel_offset. It will already
+ have the correct value. If this is not a relocateable link,
+ then we should ignore the symbol value. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ {
+ if (info->relocateable)
+ continue;
+ if (sym != NULL && sym->n_scnum != 0)
+ addend += sym->n_value;
+ }
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ asection *sec;
+
+ if (symndx == -1)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = sections[symndx];
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value);
+ if (! obj_pe (input_bfd))
+ val -= sec->vma;
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+
+ else if (! info->relocateable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+
+ if (info->base_file)
+ {
+ /* Emit a reloc if the backend thinks it needs it. */
+ if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
+ {
+ /* Relocation to a symbol in a section which isn't
+ absolute. We output the address here to a file.
+ This file is then read by dlltool when generating the
+ reloc section. Note that the base file is not
+ portable between systems. We write out a long here,
+ and dlltool reads in a long. */
+ long addr = (rel->r_vaddr
+ - input_section->vma
+ + input_section->output_offset
+ + input_section->output_section->vma);
+ if (coff_data (output_bfd)->pe)
+ addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
+ if (fwrite (&addr, 1, sizeof (long), (FILE *) info->base_file)
+ != sizeof (long))
+ {
+ bfd_set_error (bfd_error_system_call);
+ return false;
+ }
+ }
+ }
+
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents,
+ rel->r_vaddr - input_section->vma,
+ val, addend);
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_outofrange:
+ (*_bfd_error_handler)
+ (_("%s: bad reloc address 0x%lx in section `%s'"),
+ bfd_get_filename (input_bfd),
+ (unsigned long) rel->r_vaddr,
+ bfd_get_section_name (input_bfd, input_section));
+ return false;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return false;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
diff --git a/bfd/coffswap.h b/bfd/coffswap.h
new file mode 100644
index 00000000000..ae30a5d966f
--- /dev/null
+++ b/bfd/coffswap.h
@@ -0,0 +1,908 @@
+/* Generic COFF swapping routines, for BFD.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file contains routines used to swap COFF data. It is a header
+ file because the details of swapping depend on the details of the
+ structures used by each COFF implementation. This is included by
+ coffcode.h, as well as by the ECOFF backend.
+
+ Any file which uses this must first include "coff/internal.h" and
+ "coff/CPU.h". The functions will then be correct for that CPU. */
+
+#ifndef IMAGE_BASE
+#define IMAGE_BASE 0
+#endif
+
+#define PUTWORD bfd_h_put_32
+#define PUTHALF bfd_h_put_16
+#define PUTBYTE bfd_h_put_8
+
+#ifndef GET_FCN_LNNOPTR
+#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+
+#ifndef GET_FCN_ENDNDX
+#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+
+#ifndef PUT_FCN_LNNOPTR
+#define PUT_FCN_LNNOPTR(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+#ifndef PUT_FCN_ENDNDX
+#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#ifndef GET_LNSZ_LNNO
+#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef GET_LNSZ_SIZE
+#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef PUT_LNSZ_LNNO
+#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef PUT_LNSZ_SIZE
+#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef GET_SCN_SCNLEN
+#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
+#endif
+#ifndef GET_SCN_NRELOC
+#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
+#endif
+#ifndef GET_SCN_NLINNO
+#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
+#endif
+#ifndef PUT_SCN_SCNLEN
+#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
+#endif
+#ifndef PUT_SCN_NRELOC
+#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
+#endif
+#ifndef PUT_SCN_NLINNO
+#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
+#endif
+#ifndef GET_LINENO_LNNO
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
+#endif
+#ifndef PUT_LINENO_LNNO
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
+#endif
+
+/* The f_symptr field in the filehdr is sometimes 64 bits. */
+#ifndef GET_FILEHDR_SYMPTR
+#define GET_FILEHDR_SYMPTR bfd_h_get_32
+#endif
+#ifndef PUT_FILEHDR_SYMPTR
+#define PUT_FILEHDR_SYMPTR bfd_h_put_32
+#endif
+
+/* Some fields in the aouthdr are sometimes 64 bits. */
+#ifndef GET_AOUTHDR_TSIZE
+#define GET_AOUTHDR_TSIZE bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_TSIZE
+#define PUT_AOUTHDR_TSIZE bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_DSIZE
+#define GET_AOUTHDR_DSIZE bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_DSIZE
+#define PUT_AOUTHDR_DSIZE bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_BSIZE
+#define GET_AOUTHDR_BSIZE bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_BSIZE
+#define PUT_AOUTHDR_BSIZE bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_ENTRY
+#define GET_AOUTHDR_ENTRY bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_ENTRY
+#define PUT_AOUTHDR_ENTRY bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_TEXT_START
+#define GET_AOUTHDR_TEXT_START bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_TEXT_START
+#define PUT_AOUTHDR_TEXT_START bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_DATA_START
+#define GET_AOUTHDR_DATA_START bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_DATA_START
+#define PUT_AOUTHDR_DATA_START bfd_h_put_32
+#endif
+
+/* Some fields in the scnhdr are sometimes 64 bits. */
+#ifndef GET_SCNHDR_PADDR
+#define GET_SCNHDR_PADDR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_PADDR
+#define PUT_SCNHDR_PADDR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_VADDR
+#define GET_SCNHDR_VADDR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_VADDR
+#define PUT_SCNHDR_VADDR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_SIZE
+#define GET_SCNHDR_SIZE bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_SIZE
+#define PUT_SCNHDR_SIZE bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_SCNPTR
+#define GET_SCNHDR_SCNPTR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_SCNPTR
+#define PUT_SCNHDR_SCNPTR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_RELPTR
+#define GET_SCNHDR_RELPTR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_RELPTR
+#define PUT_SCNHDR_RELPTR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_LNNOPTR
+#define GET_SCNHDR_LNNOPTR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_LNNOPTR
+#define PUT_SCNHDR_LNNOPTR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_NRELOC
+#define GET_SCNHDR_NRELOC bfd_h_get_16
+#endif
+#ifndef PUT_SCNHDR_NRELOC
+#define PUT_SCNHDR_NRELOC bfd_h_put_16
+#endif
+#ifndef GET_SCNHDR_NLNNO
+#define GET_SCNHDR_NLNNO bfd_h_get_16
+#endif
+#ifndef PUT_SCNHDR_NLNNO
+#define PUT_SCNHDR_NLNNO bfd_h_put_16
+#endif
+#ifndef GET_SCNHDR_FLAGS
+#define GET_SCNHDR_FLAGS bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_FLAGS
+#define PUT_SCNHDR_FLAGS bfd_h_put_32
+#endif
+
+
+static void coff_swap_aouthdr_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_aouthdr_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_scnhdr_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_filehdr_out PARAMS ((bfd *, PTR, PTR));
+#ifndef NO_COFF_RELOCS
+static void coff_swap_reloc_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_reloc_out PARAMS ((bfd *, PTR, PTR));
+#endif /* NO_COFF_RELOCS */
+#ifndef NO_COFF_SYMBOLS
+static void coff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_sym_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_aux_in PARAMS ((bfd *, PTR, int, int, int, int, PTR));
+static unsigned int coff_swap_aux_out PARAMS ((bfd *, PTR, int, int, int, int, PTR));
+#endif /* NO_COFF_SYMBOLS */
+#ifndef NO_COFF_LINENOS
+static void coff_swap_lineno_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_lineno_out PARAMS ((bfd *, PTR, PTR));
+#endif /* NO_COFF_LINENOS */
+
+#ifndef NO_COFF_RELOCS
+
+static void
+coff_swap_reloc_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
+ reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
+ reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
+
+#ifdef RS6000COFF_C
+ reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type);
+ reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size);
+#else
+ reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
+#endif
+
+#ifdef SWAP_IN_RELOC_OFFSET
+ reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
+ (bfd_byte *) reloc_src->r_offset);
+#endif
+}
+
+static unsigned int
+coff_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ struct internal_reloc *reloc_src = (struct internal_reloc *)src;
+ struct external_reloc *reloc_dst = (struct external_reloc *)dst;
+ bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
+ bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
+
+#ifdef RS6000COFF_C
+ bfd_h_put_8 (abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type);
+ bfd_h_put_8 (abfd, reloc_src->r_size, (bfd_byte *) reloc_dst->r_size);
+#else
+ bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
+ reloc_dst->r_type);
+#endif
+
+#ifdef SWAP_OUT_RELOC_OFFSET
+ SWAP_OUT_RELOC_OFFSET(abfd,
+ reloc_src->r_offset,
+ (bfd_byte *) reloc_dst->r_offset);
+#endif
+#ifdef SWAP_OUT_RELOC_EXTRA
+ SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
+#endif
+
+ return RELSZ;
+}
+
+#endif /* NO_COFF_RELOCS */
+
+static void
+coff_swap_filehdr_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ FILHDR *filehdr_src = (FILHDR *) src;
+ struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
+#ifdef COFF_ADJUST_FILEHDR_IN_PRE
+ COFF_ADJUST_FILEHDR_IN_PRE (abfd, src, dst);
+#endif
+ filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic);
+ filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns);
+ filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat);
+ filehdr_dst->f_symptr =
+ GET_FILEHDR_SYMPTR (abfd, (bfd_byte *) filehdr_src->f_symptr);
+ filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
+ filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr);
+ filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
+#ifdef TIC80_TARGET_ID
+ filehdr_dst->f_target_id = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_target_id);
+#endif
+
+#ifdef COFF_ADJUST_FILEHDR_IN_POST
+ COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
+#endif
+}
+
+static unsigned int
+coff_swap_filehdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
+ FILHDR *filehdr_out = (FILHDR *)out;
+
+#ifdef COFF_ADJUST_FILEHDR_OUT_PRE
+ COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
+#endif
+ bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
+ bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
+ bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
+ PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
+ (bfd_byte *) filehdr_out->f_symptr);
+ bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
+ bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
+ bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
+#ifdef TIC80_TARGET_ID
+ bfd_h_put_16(abfd, filehdr_in->f_target_id, (bfd_byte *) filehdr_out->f_target_id);
+#endif
+
+#ifdef COFF_ADJUST_FILEHDR_OUT_POST
+ COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
+#endif
+ return FILHSZ;
+}
+
+
+#ifndef NO_COFF_SYMBOLS
+
+static void
+coff_swap_sym_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
+{
+ SYMENT *ext = (SYMENT *)ext1;
+ struct internal_syment *in = (struct internal_syment *)in1;
+
+ if( ext->e.e_name[0] == 0) {
+ in->_n._n_n._n_zeroes = 0;
+ in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
+ }
+ else {
+#if SYMNMLEN != E_SYMNMLEN
+ -> Error, we need to cope with truncating or extending SYMNMLEN!;
+#else
+ memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
+#endif
+ }
+ in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
+ in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
+ if (sizeof(ext->e_type) == 2){
+ in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
+ }
+ else {
+ in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
+ }
+ in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
+ in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
+}
+
+static unsigned int
+coff_swap_sym_out (abfd, inp, extp)
+ bfd *abfd;
+ PTR inp;
+ PTR extp;
+{
+ struct internal_syment *in = (struct internal_syment *)inp;
+ SYMENT *ext =(SYMENT *)extp;
+ if(in->_n._n_name[0] == 0) {
+ bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
+ bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset);
+ }
+ else {
+#if SYMNMLEN != E_SYMNMLEN
+ -> Error, we need to cope with truncating or extending SYMNMLEN!;
+#else
+ memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
+#endif
+ }
+ bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value);
+ bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum);
+ if (sizeof(ext->e_type) == 2)
+ {
+ bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
+ }
+ else
+ {
+ bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type);
+ }
+ bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
+ bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
+ return SYMESZ;
+}
+
+static void
+coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
+ bfd *abfd;
+ PTR ext1;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR in1;
+{
+ AUXENT *ext = (AUXENT *)ext1;
+ union internal_auxent *in = (union internal_auxent *)in1;
+
+#ifdef COFF_ADJUST_AUX_IN_PRE
+ COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, class, indx, numaux, in1);
+#endif
+ switch (class) {
+ case C_FILE:
+ if (ext->x_file.x_fname[0] == 0) {
+ in->x_file.x_n.x_zeroes = 0;
+ in->x_file.x_n.x_offset =
+ bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
+ } else {
+#if FILNMLEN != E_FILNMLEN
+ -> Error, we need to cope with truncating or extending FILNMLEN!;
+#else
+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+#endif
+ }
+ goto end;
+
+ /* RS/6000 "csect" auxents */
+#ifdef RS6000COFF_C
+ case C_EXT:
+ case C_HIDEXT:
+ if (indx + 1 == numaux)
+ {
+ in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
+ in->x_csect.x_parmhash = bfd_h_get_32 (abfd,
+ ext->x_csect.x_parmhash);
+ in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash);
+ /* We don't have to hack bitfields in x_smtyp because it's
+ defined by shifts-and-ands, which are equivalent on all
+ byte orders. */
+ in->x_csect.x_smtyp = bfd_h_get_8 (abfd, ext->x_csect.x_smtyp);
+ in->x_csect.x_smclas = bfd_h_get_8 (abfd, ext->x_csect.x_smclas);
+ in->x_csect.x_stab = bfd_h_get_32 (abfd, ext->x_csect.x_stab);
+ in->x_csect.x_snstab = bfd_h_get_16 (abfd, ext->x_csect.x_snstab);
+ goto end;
+ }
+ break;
+#endif
+
+ case C_STAT:
+#ifdef C_LEAFSTAT
+ case C_LEAFSTAT:
+#endif
+ case C_HIDDEN:
+ if (type == T_NULL) {
+ in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
+ in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
+ in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
+
+ /* PE defines some extra fields; we zero them out for
+ safety. */
+ in->x_scn.x_checksum = 0;
+ in->x_scn.x_associated = 0;
+ in->x_scn.x_comdat = 0;
+
+ goto end;
+ }
+ break;
+ }
+
+ in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
+ in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
+#endif
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
+ }
+ else
+ {
+#if DIMNUM != E_DIMNUM
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN(type)) {
+ in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+ }
+ else {
+ in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
+ in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
+ }
+
+end: ;
+ /* the semicolon is because MSVC doesn't like labels at
+ end of block. */
+
+#ifdef COFF_ADJUST_AUX_IN_POST
+ COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, class, indx, numaux, in1);
+#endif
+}
+
+static unsigned int
+coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
+ bfd *abfd;
+ PTR inp;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR extp;
+{
+ union internal_auxent *in = (union internal_auxent *)inp;
+ AUXENT *ext = (AUXENT *)extp;
+
+#ifdef COFF_ADJUST_AUX_OUT_PRE
+ COFF_ADJUST_AUX_OUT_PRE (abfd, inp, type, class, indx, numaux, extp);
+#endif
+ memset((PTR)ext, 0, AUXESZ);
+ switch (class) {
+ case C_FILE:
+ if (in->x_file.x_fname[0] == 0) {
+ PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
+ PUTWORD(abfd,
+ in->x_file.x_n.x_offset,
+ (bfd_byte *) ext->x_file.x_n.x_offset);
+ }
+ else {
+#if FILNMLEN != E_FILNMLEN
+ -> Error, we need to cope with truncating or extending FILNMLEN!;
+#else
+ memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
+#endif
+ }
+ goto end;
+
+#ifdef RS6000COFF_C
+ /* RS/6000 "csect" auxents */
+ case C_EXT:
+ case C_HIDEXT:
+ if (indx + 1 == numaux)
+ {
+ PUTWORD (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
+ PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
+ PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
+ /* We don't have to hack bitfields in x_smtyp because it's
+ defined by shifts-and-ands, which are equivalent on all
+ byte orders. */
+ PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
+ PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
+ PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
+ PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
+ goto end;
+ }
+ break;
+#endif
+
+ case C_STAT:
+#ifdef C_LEAFSTAT
+ case C_LEAFSTAT:
+#endif
+ case C_HIDDEN:
+ if (type == T_NULL) {
+ PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
+ PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
+ PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
+ goto end;
+ }
+ break;
+ }
+
+ PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
+ bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
+#endif
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+ PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+ }
+ else
+ {
+#if DIMNUM != E_DIMNUM
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ PUTWORD (abfd, in->x_sym.x_misc.x_fsize,
+ (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+ else
+ {
+ PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+ PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+ }
+
+end:
+#ifdef COFF_ADJUST_AUX_OUT_POST
+ COFF_ADJUST_AUX_OUT_POST (abfd, inp, type, class, indx, numaux, extp);
+#endif
+ return AUXESZ;
+}
+
+#endif /* NO_COFF_SYMBOLS */
+
+#ifndef NO_COFF_LINENOS
+
+static void
+coff_swap_lineno_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
+{
+ LINENO *ext = (LINENO *)ext1;
+ struct internal_lineno *in = (struct internal_lineno *)in1;
+
+ in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
+ in->l_lnno = GET_LINENO_LNNO(abfd, ext);
+}
+
+static unsigned int
+coff_swap_lineno_out (abfd, inp, outp)
+ bfd *abfd;
+ PTR inp;
+ PTR outp;
+{
+ struct internal_lineno *in = (struct internal_lineno *)inp;
+ struct external_lineno *ext = (struct external_lineno *)outp;
+ PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *)
+ ext->l_addr.l_symndx);
+
+ PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
+ return LINESZ;
+}
+
+#endif /* NO_COFF_LINENOS */
+
+static void
+coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
+ bfd *abfd;
+ PTR aouthdr_ext1;
+ PTR aouthdr_int1;
+{
+ AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+ struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
+
+ aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
+ aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
+ aouthdr_int->tsize =
+ GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
+ aouthdr_int->dsize =
+ GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
+ aouthdr_int->bsize =
+ GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
+ aouthdr_int->entry =
+ GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
+ aouthdr_int->text_start =
+ GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
+ aouthdr_int->data_start =
+ GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
+
+#ifdef I960
+ aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries);
+#endif
+
+#ifdef APOLLO_M68
+ bfd_h_put_32(abfd, aouthdr_int->o_inlib, (bfd_byte *) aouthdr_ext->o_inlib);
+ bfd_h_put_32(abfd, aouthdr_int->o_sri, (bfd_byte *) aouthdr_ext->o_sri);
+ bfd_h_put_32(abfd, aouthdr_int->vid[0], (bfd_byte *) aouthdr_ext->vid);
+ bfd_h_put_32(abfd, aouthdr_int->vid[1], (bfd_byte *) aouthdr_ext->vid + 4);
+#endif
+
+
+#ifdef RS6000COFF_C
+ aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc);
+ aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry);
+ aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext);
+ aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata);
+ aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc);
+ aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader);
+ aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss);
+ aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext);
+ aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata);
+ aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype);
+ aouthdr_int->o_cputype = bfd_h_get_16(abfd, aouthdr_ext->o_cputype);
+ aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack);
+ aouthdr_int->o_maxdata = bfd_h_get_32(abfd, aouthdr_ext->o_maxdata);
+#endif
+
+#ifdef MIPSECOFF
+ aouthdr_int->bss_start = bfd_h_get_32(abfd, aouthdr_ext->bss_start);
+ aouthdr_int->gp_value = bfd_h_get_32(abfd, aouthdr_ext->gp_value);
+ aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask);
+ aouthdr_int->cprmask[0] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[0]);
+ aouthdr_int->cprmask[1] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[1]);
+ aouthdr_int->cprmask[2] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[2]);
+ aouthdr_int->cprmask[3] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[3]);
+#endif
+
+#ifdef ALPHAECOFF
+ aouthdr_int->bss_start = bfd_h_get_64(abfd, aouthdr_ext->bss_start);
+ aouthdr_int->gp_value = bfd_h_get_64(abfd, aouthdr_ext->gp_value);
+ aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask);
+ aouthdr_int->fprmask = bfd_h_get_32(abfd, aouthdr_ext->fprmask);
+#endif
+}
+
+static unsigned int
+coff_swap_aouthdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
+ AOUTHDR *aouthdr_out = (AOUTHDR *)out;
+
+ bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->magic);
+ bfd_h_put_16(abfd, aouthdr_in->vstamp, (bfd_byte *) aouthdr_out->vstamp);
+ PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->tsize);
+ PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->dsize);
+ PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->bsize);
+ PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->entry);
+ PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
+ (bfd_byte *) aouthdr_out->text_start);
+ PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
+ (bfd_byte *) aouthdr_out->data_start);
+
+#ifdef I960
+ bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries);
+#endif
+
+#ifdef RS6000COFF_C
+ bfd_h_put_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
+ bfd_h_put_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
+ bfd_h_put_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
+ bfd_h_put_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
+ bfd_h_put_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
+ bfd_h_put_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
+ bfd_h_put_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
+ bfd_h_put_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
+ bfd_h_put_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
+ bfd_h_put_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
+ bfd_h_put_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
+ bfd_h_put_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
+ bfd_h_put_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
+ memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
+#endif
+
+#ifdef MIPSECOFF
+ bfd_h_put_32(abfd, aouthdr_in->bss_start, (bfd_byte *) aouthdr_out->bss_start);
+ bfd_h_put_32(abfd, aouthdr_in->gp_value, (bfd_byte *) aouthdr_out->gp_value);
+ bfd_h_put_32(abfd, aouthdr_in->gprmask, (bfd_byte *) aouthdr_out->gprmask);
+ bfd_h_put_32(abfd, aouthdr_in->cprmask[0], (bfd_byte *) aouthdr_out->cprmask[0]);
+ bfd_h_put_32(abfd, aouthdr_in->cprmask[1], (bfd_byte *) aouthdr_out->cprmask[1]);
+ bfd_h_put_32(abfd, aouthdr_in->cprmask[2], (bfd_byte *) aouthdr_out->cprmask[2]);
+ bfd_h_put_32(abfd, aouthdr_in->cprmask[3], (bfd_byte *) aouthdr_out->cprmask[3]);
+#endif
+
+#ifdef ALPHAECOFF
+ /* FIXME: What does bldrev mean? */
+ bfd_h_put_16(abfd, (bfd_vma) 2, (bfd_byte *) aouthdr_out->bldrev);
+ bfd_h_put_16(abfd, (bfd_vma) 0, (bfd_byte *) aouthdr_out->padding);
+ bfd_h_put_64(abfd, aouthdr_in->bss_start, (bfd_byte *) aouthdr_out->bss_start);
+ bfd_h_put_64(abfd, aouthdr_in->gp_value, (bfd_byte *) aouthdr_out->gp_value);
+ bfd_h_put_32(abfd, aouthdr_in->gprmask, (bfd_byte *) aouthdr_out->gprmask);
+ bfd_h_put_32(abfd, aouthdr_in->fprmask, (bfd_byte *) aouthdr_out->fprmask);
+#endif
+
+ return AOUTSZ;
+}
+
+static void
+coff_swap_scnhdr_in (abfd, ext, in)
+ bfd *abfd;
+ PTR ext;
+ PTR in;
+{
+ SCNHDR *scnhdr_ext = (SCNHDR *) ext;
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+#ifdef COFF_ADJUST_SCNHDR_IN_PRE
+ COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
+#endif
+ memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
+ scnhdr_int->s_vaddr =
+ GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
+ scnhdr_int->s_paddr =
+ GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
+ scnhdr_int->s_size =
+ GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
+
+ scnhdr_int->s_scnptr =
+ GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
+ scnhdr_int->s_relptr =
+ GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
+ scnhdr_int->s_lnnoptr =
+ GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
+ scnhdr_int->s_flags =
+ GET_SCNHDR_FLAGS (abfd, (bfd_byte *) scnhdr_ext->s_flags);
+ scnhdr_int->s_nreloc =
+ GET_SCNHDR_NRELOC (abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
+ scnhdr_int->s_nlnno =
+ GET_SCNHDR_NLNNO (abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
+#ifdef I960
+ scnhdr_int->s_align =
+ GET_SCNHDR_ALIGN (abfd, (bfd_byte *) scnhdr_ext->s_align);
+#endif
+#ifdef COFF_ADJUST_SCNHDR_IN_POST
+ COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
+#endif
+}
+
+static unsigned int
+coff_swap_scnhdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
+ SCNHDR *scnhdr_ext = (SCNHDR *)out;
+ unsigned int ret = SCNHSZ;
+
+#ifdef COFF_ADJUST_SCNHDR_OUT_PRE
+ COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
+#endif
+ memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
+
+ PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr,
+ (bfd_byte *) scnhdr_ext->s_vaddr);
+
+
+ PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr,
+ (bfd_byte *) scnhdr_ext->s_paddr);
+ PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size,
+ (bfd_byte *) scnhdr_ext->s_size);
+
+ PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
+ (bfd_byte *) scnhdr_ext->s_scnptr);
+ PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
+ (bfd_byte *) scnhdr_ext->s_relptr);
+ PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
+ (bfd_byte *) scnhdr_ext->s_lnnoptr);
+ PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags,
+ (bfd_byte *) scnhdr_ext->s_flags);
+#if defined(M88)
+ PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
+ PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+#else
+ if (scnhdr_int->s_nlnno <= 0xffff)
+ PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
+ else
+ {
+ char buf[sizeof (scnhdr_int->s_name) + 1];
+
+ memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
+ buf[sizeof (scnhdr_int->s_name)] = '\0';
+ (*_bfd_error_handler)
+ (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (abfd),
+ buf, scnhdr_int->s_nlnno);
+ PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+ }
+ if (scnhdr_int->s_nreloc <= 0xffff)
+ PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+ else
+ {
+ char buf[sizeof (scnhdr_int->s_name) + 1];
+
+ memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
+ buf[sizeof (scnhdr_int->s_name)] = '\0';
+ (*_bfd_error_handler) (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (abfd),
+ buf, scnhdr_int->s_nreloc);
+ bfd_set_error (bfd_error_file_truncated);
+ PUTHALF (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+ ret = 0;
+ }
+#endif
+
+#ifdef I960
+ PUT_SCNHDR_ALIGN (abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
+#endif
+#ifdef COFF_ADJUST_SCNHDR_OUT_POST
+ COFF_ADJUST_SCNHDR_OUT_POST (abfd, in, out);
+#endif
+ return ret;
+}
diff --git a/bfd/config.bfd b/bfd/config.bfd
new file mode 100644
index 00000000000..449ae915b1d
--- /dev/null
+++ b/bfd/config.bfd
@@ -0,0 +1,719 @@
+# config.bfd
+# Convert a canonical host type into a BFD host type.
+# Set shell variable targ to canonical target name, and run
+# using ``. config.bfd''.
+# Sets the following shell variables:
+# targ_defvec Default vector for this target
+# targ_selvecs Vectors to build for this target
+# targ_archs Architectures for this target
+# targ_cflags $(CFLAGS) for this target (FIXME: pretty bogus)
+# targ_underscore Whether underscores are used: yes or no
+
+# Part of this file is processed by targmatch.sed to generate the
+# targmatch.h file. The #ifdef and #endif lines that appear below are
+# copied directly into targmatch.h.
+
+# The binutils c++filt program wants to know whether underscores are
+# stripped or not. That is why we set targ_underscore. c++filt uses
+# this information to choose a default. This information is
+# duplicated in the symbol_leading_char field of the BFD target
+# vector, but c++filt does not deal with object files and is not
+# linked against libbfd.a. It is not terribly important that c++filt
+# get this right; it is just convenient.
+
+targ_defvec=
+targ_selvecs=
+targ_cflags=
+targ_underscore=no
+
+targ_cpu=`echo $targ | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+case "${targ_cpu}" in
+alpha*) targ_archs=bfd_alpha_arch ;;
+arm*) targ_archs=bfd_arm_arch ;;
+strongarm*) targ_archs=bfd_arm_arch ;;
+thumb*) targ_archs=bfd_arm_arch ;;
+c30*) targ_archs=bfd_tic30_arch ;;
+hppa*) targ_archs=bfd_hppa_arch ;;
+i[3456]86) targ_archs=bfd_i386_arch ;;
+m68*) targ_archs=bfd_m68k_arch ;;
+m88*) targ_archs=bfd_m88k_arch ;;
+mips*) targ_archs=bfd_mips_arch ;;
+powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+sparc*) targ_archs=bfd_sparc_arch ;;
+v850*) targ_archs=bfd_v850_arch ;;
+z8k*) targ_archs=bfd_z8k_arch ;;
+*) targ_archs=bfd_${targ_cpu}_arch ;;
+esac
+
+
+# WHEN ADDING ENTRIES TO THIS MATRIX:
+# Make sure that the left side always has two dashes. Otherwise you
+# can get spurious matches. Even for unambiguous cases, do this as a
+# convention, else the table becomes a real mess to understand and maintain.
+
+case "${targ}" in
+# START OF targmatch.h
+#ifdef BFD64
+ alpha*-*-netbsd*)
+ targ_defvec=bfd_elf64_alpha_vec
+ targ_selvecs=ecoffalpha_little_vec
+ ;;
+ alpha*-*-netware*)
+ targ_defvec=ecoffalpha_little_vec
+ targ_selvecs=nlm32_alpha_vec
+ ;;
+ alpha*-*-linuxecoff*)
+ targ_defvec=ecoffalpha_little_vec
+ targ_selvecs=bfd_elf64_alpha_vec
+ ;;
+ alpha*-*-linux-gnu* | alpha*-*-elf*)
+ targ_defvec=bfd_elf64_alpha_vec
+ targ_selvecs=ecoffalpha_little_vec
+ ;;
+ alpha*-*-*vms*)
+ targ_defvec=vms_alpha_vec
+ ;;
+ alpha*-*-*)
+ targ_defvec=ecoffalpha_little_vec
+ ;;
+#endif /* BFD64 */
+
+ arc-*-elf*)
+ targ_defvec=bfd_elf32_littlearc_vec
+ targ_selvecs=bfd_elf32_bigarc_vec
+ ;;
+
+ arm-*-riscix*)
+ targ_defvec=riscix_vec
+ ;;
+ arm-epoc-pe*)
+ targ_defvec=arm_epoc_pe_little_vec
+ targ_selvecs="arm_epoc_pe_little_vec arm_epoc_pe_big_vec arm_epoc_pei_little_vec arm_epoc_pei_big_vec"
+ targ_underscore=no
+ ;;
+ arm-*-pe*)
+ targ_defvec=armpe_little_vec
+ targ_selvecs="armpe_little_vec armpe_big_vec armpei_little_vec armpei_big_vec"
+ targ_underscore=yes
+ ;;
+ arm-*-aout | armel-*-aout)
+ targ_defvec=aout_arm_little_vec
+ targ_selvecs=aout_arm_big_vec
+ ;;
+ armeb-*-aout)
+ targ_defvec=aout_arm_big_vec
+ targ_selvecs=aout_arm_little_vec
+ ;;
+ arm-*-coff)
+ targ_defvec=armcoff_little_vec
+ targ_selvecs=armcoff_big_vec
+ targ_underscore=yes
+ ;;
+ arm-*-elf | arm*-*-linux-gnu)
+ targ_defvec=bfd_elf32_littlearm_vec
+ targ_selvecs=bfd_elf32_bigarm_vec
+ ;;
+ arm-*-oabi)
+ targ_defvec=bfd_elf32_littlearm_oabi_vec
+ targ_selvecs=bfd_elf32_bigarm_oabi_vec
+ ;;
+
+ thumb-*-coff)
+ targ_defvec=armcoff_little_vec
+ targ_selvecs=armcoff_big_vec
+ targ_underscore=yes
+ ;;
+ thumb-*-oabi)
+ targ_defvec=bfd_elf32_littlearm_oabi_vec
+ targ_selvecs=bfd_elf32_bigarm_oabi_vec
+ ;;
+ thumb-*-elf)
+ targ_defvec=bfd_elf32_littlearm_vec
+ targ_selvecs=bfd_elf32_bigarm_vec
+ ;;
+ thumb-epoc-pe*)
+ targ_defvec=arm_epoc_pe_little_vec
+ targ_selvecs="arm_epoc_pe_little_vec arm_epoc_pe_big_vec arm_epoc_pei_little_vec arm_epoc_pei_big_vec"
+ targ_underscore=no
+ ;;
+ thumb-*-pe*)
+ targ_defvec=armpe_little_vec
+ targ_selvecs="armpe_little_vec armpe_big_vec armpei_little_vec armpei_big_vec"
+ targ_underscore=yes
+ ;;
+ strongarm-*-elf)
+ targ_defvec=bfd_elf32_littlearm_vec
+ targ_selvecs=bfd_elf32_bigarm_vec
+ ;;
+ strongarm-*-coff)
+ targ_defvec=armcoff_little_vec
+ targ_selvecs=armcoff_big_vec
+ targ_underscore=yes
+ ;;
+
+ a29k-*-ebmon* | a29k-*-udi* | a29k-*-coff* | a29k-*-sym1* | \
+ a29k-*-vxworks* | a29k-*-sysv*)
+ targ_defvec=a29kcoff_big_vec
+ targ_selvecs=sunos_big_vec
+ targ_underscore=yes
+ ;;
+ a29k-*-aout* | a29k-*-bsd* | a29k-*-vsta*)
+ targ_defvec=sunos_big_vec
+ targ_underscore=yes
+ ;;
+
+ c30-*-*aout* | tic30-*-*aout*)
+ targ_defvec=tic30_aout_vec
+ ;;
+ c30-*-*coff* | tic30-*-*coff*)
+ targ_defvec=tic30_coff_vec
+ ;;
+
+ d10v-*-*)
+ targ_defvec=bfd_elf32_d10v_vec
+ ;;
+
+ d30v-*-*)
+ targ_defvec=bfd_elf32_d30v_vec
+ ;;
+
+ fr30-*-elf)
+ targ_defvec=bfd_elf32_fr30_vec
+ ;;
+
+
+ h8300*-*-*)
+ targ_defvec=h8300coff_vec
+ targ_underscore=yes
+ ;;
+
+ h8500-*-*)
+ targ_defvec=h8500coff_vec
+ targ_underscore=yes
+ ;;
+
+ hppa*-*-*elf* | hppa*-*-lites* | hppa*-*-sysv4* | hppa*-*-rtems*)
+ targ_defvec=bfd_elf32_hppa_vec
+ ;;
+#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) || defined (HOST_HPPAMPEIX)
+ hppa*-*-bsd*)
+ targ_defvec=som_vec
+ targ_selvecs=bfd_elf32_hppa_vec
+ ;;
+ hppa*-*-hpux* | hppa*-*-hiux* | hppa*-*-mpeix*)
+ targ_defvec=som_vec
+ ;;
+ hppa*-*-osf*)
+ targ_defvec=som_vec
+ targ_selvecs=bfd_elf32_hppa_vec
+ ;;
+#endif /* defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) */
+
+ i[3456]86-*-sco3.2v5*coff)
+ targ_defvec=i386coff_vec
+ targ_selvecs=bfd_elf32_i386_vec
+ ;;
+ i[3456]86-*-sysv4* | i[3456]86-*-unixware | i[3456]86-*-solaris2* | \
+ i[3456]86-*-elf | i[3456]86-*-sco3.2v5* | i[3456]86-*-freebsdelf* | \
+ i[3456]86-*-dgux* | i[3456]86-*-sysv5*)
+ targ_defvec=bfd_elf32_i386_vec
+ targ_selvecs=i386coff_vec
+ ;;
+ i[3456]86-*-msdosdjgpp* | i[3456]*-*-go32* | i[3456]86-go32-rtems* )
+ targ_defvec=go32coff_vec
+ targ_selvecs="go32stubbedcoff_vec i386aout_vec"
+ ;;
+ i[3456]86-*-sysv* | i[3456]86-*-isc* | i[3456]86-*-sco* | i[3456]86-*-coff | \
+ i[3456]86-*-aix* | i[3456]86*-*-rtems*)
+ targ_defvec=i386coff_vec
+ ;;
+ i[3456]86-sequent-bsd*)
+ targ_defvec=i386dynix_vec
+ targ_underscore=yes
+ ;;
+ i[3456]86-*-bsd*)
+ targ_defvec=i386bsd_vec
+ targ_underscore=yes
+ ;;
+ i[3456]86-*-freebsd*)
+ targ_defvec=i386freebsd_vec
+ targ_selvecs=i386bsd_vec
+ targ_underscore=yes
+ ;;
+ i[3456]86-*-netbsd* | i[3456]86-*-openbsd*)
+ targ_defvec=i386netbsd_vec
+ targ_selvecs=i386bsd_vec
+ targ_underscore=yes
+ ;;
+ i[3456]86-*-netware*)
+ targ_defvec=bfd_elf32_i386_vec
+ targ_selvecs="nlm32_i386_vec i386coff_vec i386aout_vec"
+ ;;
+ i[3456]86-*-linux*aout*)
+ targ_defvec=i386linux_vec
+ targ_selvecs=bfd_elf32_i386_vec
+ targ_underscore=yes
+ ;;
+ i[3456]86-*-linux-gnu*)
+ targ_defvec=bfd_elf32_i386_vec
+ targ_selvecs=i386linux_vec
+ ;;
+ i[3456]86-*-lynxos*)
+ targ_defvec=i386lynx_coff_vec
+ targ_selvecs=i386lynx_aout_vec
+ ;;
+ i[3456]86-*-gnu*)
+ targ_defvec=bfd_elf32_i386_vec
+ ;;
+ i[3456]86-*-mach* | i[3456]86-*-osf1mk*)
+ targ_defvec=i386mach3_vec
+ targ_cflags=-DSTAT_FOR_EXEC
+ targ_underscore=yes
+ ;;
+ i[3456]86-*-os9k)
+ targ_defvec=i386os9k_vec
+ ;;
+ i[3456]86-*-msdos*)
+ targ_defvec=i386aout_vec
+ targ_selvecs=i386msdos_vec
+ ;;
+ i[3456]86-*-moss*)
+ targ_defvec=bfd_elf32_i386_vec
+ targ_selvecs="i386msdos_vec i386aout_vec"
+ ;;
+ i[3456]86-*-beospe*)
+ targ_defvec=i386pe_vec
+ targ_selvecs="i386pe_vec i386pei_vec"
+ ;;
+ i[3456]86-*-beoself* | i[3456]86-*-beos*)
+ targ_defvec=bfd_elf32_i386_vec
+ targ_selvecs="i386pe_vec i386pei_vec"
+ ;;
+ i[3456]86-*-mingw32* | i[3456]86-*-cygwin* | i[3456]86-*-winnt | i[3456]86-*-pe)
+ targ_defvec=i386pe_vec
+ targ_selvecs="i386pe_vec i386pei_vec"
+ ;;
+ i[3456]86-none-*)
+ targ_defvec=i386coff_vec
+ ;;
+ i[3456]86-*-aout* | i[3456]86*-*-vsta*)
+ targ_defvec=i386aout_vec
+ ;;
+
+ i860-*-mach3* | i860-*-osf1* | i860-*-coff*)
+ targ_defvec=i860coff_vec
+ ;;
+ i860-*-sysv4* | i860-*-elf*)
+ targ_defvec=bfd_elf32_i860_vec
+ ;;
+
+ i960-*-vxworks4* | i960-*-vxworks5.0)
+ targ_defvec=b_out_vec_little_host
+ targ_selvecs="b_out_vec_big_host icoff_little_vec icoff_big_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+ i960-*-vxworks5.* | i960-*-coff* | i960-*-sysv* | i960-*-rtems*)
+ targ_defvec=icoff_little_vec
+ targ_selvecs="icoff_big_vec b_out_vec_little_host b_out_vec_big_host ieee_vec"
+ targ_underscore=yes
+ ;;
+ i960-*-vxworks* | i960-*-aout* | i960-*-bout* | i960-*-nindy*)
+ targ_defvec=b_out_vec_little_host
+ targ_selvecs="b_out_vec_big_host icoff_little_vec icoff_big_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+
+ m32r-*-*)
+ targ_defvec=bfd_elf32_m32r_vec
+ ;;
+
+ m68*-apollo-*)
+ targ_defvec=apollocoff_vec
+ ;;
+ m68*-bull-sysv*)
+ targ_defvec=m68kcoffun_vec
+ targ_underscore=yes
+ ;;
+ m68*-motorola-sysv*)
+ targ_defvec=m68ksysvcoff_vec
+ ;;
+ m68*-hp-bsd*)
+ targ_defvec=hp300bsd_vec
+ targ_underscore=yes
+ ;;
+ m68*-*-aout*)
+ targ_defvec=aout0_big_vec
+ # We include cisco_core_vec here, rather than making a separate cisco
+ # configuration, so that cisco-core.c gets routinely tested at
+ # least for compilation.
+ targ_selvecs="cisco_core_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-elf* | m68*-*-sysv4*)
+ targ_defvec=bfd_elf32_m68k_vec
+ targ_selvecs="m68kcoff_vec ieee_vec"
+ ;;
+ m68*-*-coff* | m68*-*-sysv* | m68*-*-rtems*)
+ targ_defvec=m68kcoff_vec
+ targ_selvecs="m68kcoff_vec versados_vec ieee_vec"
+ ;;
+ m68*-*-hpux*)
+ targ_defvec=hp300hpux_vec
+ targ_underscore=yes
+ ;;
+ m68*-*-linux*aout*)
+ targ_defvec=m68klinux_vec
+ targ_selvecs=bfd_elf32_m68k_vec
+ targ_underscore=yes
+ ;;
+ m68*-*-linux-gnu*)
+ targ_defvec=bfd_elf32_m68k_vec
+ targ_selvecs=m68klinux_vec
+ ;;
+ m68*-*-gnu*)
+ targ_defvec=bfd_elf32_m68k_vec
+ # targ_selvecs=m68kmach3_vec
+ # targ_cflags=-DSTAT_FOR_EXEC
+ ;;
+ m68*-*-lynxos*)
+ targ_defvec=m68klynx_coff_vec
+ targ_selvecs=m68klynx_aout_vec
+ ;;
+ m68*-hp*-netbsd*)
+ targ_defvec=m68k4knetbsd_vec
+ targ_selvecs="m68knetbsd_vec hp300bsd_vec sunos_big_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-netbsd* | m68*-*-openbsd*)
+ targ_defvec=m68knetbsd_vec
+ targ_selvecs="m68k4knetbsd_vec hp300bsd_vec sunos_big_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-sunos* | m68*-*-os68k* | m68*-*-vxworks* | m68*-netx-* | \
+ m68*-*-bsd* | m68*-*-vsta*)
+ targ_defvec=sunos_big_vec
+ targ_underscore=yes
+ ;;
+ m68*-ericsson-*)
+ targ_defvec=sunos_big_vec
+ targ_selvecs="m68kcoff_vec versados_vec tekhex_vec"
+ targ_underscore=yes
+ ;;
+ m68*-cbm-*)
+ targ_defvec=bfd_elf32_m68k_vec
+ targ_selvecs=m68kcoff_vec
+ ;;
+ m68*-apple-aux*)
+ targ_defvec=m68kaux_coff_vec
+ ;;
+ m68*-*-psos*)
+ targ_defvec=bfd_elf32_m68k_vec
+ targ_selvecs=ieee_vec
+ targ_underscore=yes
+ ;;
+
+ m88*-harris-cxux* | m88*-*-dgux* | m88*-*-sysv4*)
+ targ_defvec=bfd_elf32_m88k_vec
+ targ_selvecs=m88kbcs_vec
+ ;;
+ m88*-*-mach3*)
+ targ_defvec=m88kmach3_vec
+ targ_cflags=-DSTAT_FOR_EXEC
+ ;;
+ m88*-*-*)
+ targ_defvec=m88kbcs_vec
+ targ_underscore=yes
+ ;;
+
+ mcore-*-elf)
+ targ_defvec=bfd_elf32_mcore_big_vec
+ targ_selvecs="bfd_elf32_mcore_big_vec bfd_elf32_mcore_little_vec"
+ ;;
+ mcore-*-pe)
+ targ_defvec=mcore_pe_big_vec
+ targ_selvecs="mcore_pe_big_vec mcore_pe_little_vec mcore_pei_big_vec mcore_pei_little_vec"
+ ;;
+
+ mips*-big-*)
+ targ_defvec=ecoff_big_vec
+ targ_selvecs=ecoff_little_vec
+ ;;
+ mips-dec-netbsd* | mips*el*-*-netbsd*)
+ targ_defvec=bfd_elf32_littlemips_vec
+ targ_selvecs="bfd_elf32_bigmips_vec ecoff_little_vec ecoff_big_vec"
+ ;;
+ mips*-*-netbsd*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec"
+ ;;
+ mips*-dec-bsd*)
+ targ_defvec=aout_mips_little_vec
+ targ_underscore=yes
+ ;;
+ mips*-dec-mach3*)
+ targ_defvec=aout_mips_little_vec
+ targ_cflags=-DSTAT_FOR_EXEC
+ ;;
+ mips*-dec-* | mips*el-*-ecoff*)
+ targ_defvec=ecoff_little_vec
+ targ_selvecs=ecoff_big_vec
+ ;;
+ mips*-*-ecoff*)
+ targ_defvec=ecoff_big_vec
+ targ_selvecs=ecoff_little_vec
+ ;;
+ mips*-*-irix6*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+ ;;
+ mips*-*-irix5*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec"
+ ;;
+ mips*-sgi-* | mips*-*-bsd*)
+ targ_defvec=ecoff_big_vec
+ targ_selvecs=ecoff_little_vec
+ ;;
+ mips*-*-lnews*)
+ targ_defvec=ecoff_biglittle_vec
+ targ_selvecs="ecoff_little_vec ecoff_big_vec"
+ ;;
+ mips*-*-mach3*)
+ targ_defvec=aout_mips_little_vec
+ targ_cflags=-DSTAT_FOR_EXEC
+ ;;
+ mips*-*-sysv4*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec"
+ ;;
+ mips*-*-sysv* | mips*-*-riscos*)
+ targ_defvec=ecoff_big_vec
+ targ_selvecs=ecoff_little_vec
+ ;;
+ mips*el-*-elf* | mips*el-*-vxworks*)
+ targ_defvec=bfd_elf32_littlemips_vec
+ targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+ ;;
+ mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+ ;;
+ mips*-*-none)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+ ;;
+ mips*el*-*-linux-gnu* | mips*el*-*-openbsd*)
+ targ_defvec=bfd_elf32_littlemips_vec
+ targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_little_vec ecoff_big_vec"
+ ;;
+ mips*-*-linux-gnu* | mips*-*-openbsd*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_big_vec ecoff_little_vec"
+ ;;
+
+ mn10200-*-*)
+ targ_defvec=bfd_elf32_mn10200_vec
+ ;;
+
+ mn10300-*-*)
+ targ_defvec=bfd_elf32_mn10300_vec
+ ;;
+
+ ns32k-pc532-mach* | ns32k-pc532-ux*)
+ targ_defvec=pc532machaout_vec
+ targ_underscore=yes
+ ;;
+ ns32k-*-netbsd* | ns32k-*-lites* | ns32k-*-openbsd*)
+ targ_defvec=pc532netbsd_vec
+ targ_underscore=yes
+ ;;
+
+ powerpc-*-aix* | powerpc-*-beos*)
+ targ_defvec=rs6000coff_vec
+ ;;
+ powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
+ powerpc-*-solaris2* | powerpc-*-linux-gnu* | powerpc-*-rtems* | \
+ powerpc-*-vxworks*)
+ targ_defvec=bfd_elf32_powerpc_vec
+ targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec ppcboot_vec"
+ ;;
+ powerpc-*-macos* | powerpc-*-mpw*)
+ targ_defvec=pmac_xcoff_vec
+ ;;
+ powerpc-*-netware*)
+ targ_defvec=bfd_elf32_powerpc_vec
+ targ_selvecs="nlm32_powerpc_vec rs6000coff_vec"
+ ;;
+ powerpcle-*-elf* | powerpcle-*-sysv4* | powerpcle-*-eabi* | \
+ powerpcle-*-solaris2* | powerpcle-*-linux-gnu* | powerpcle-*-vxworks*)
+ targ_defvec=bfd_elf32_powerpcle_vec
+ targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec ppcboot_vec"
+ ;;
+
+ powerpcle-*-pe | powerpcle-*-winnt* | powerpcle-*-cygwin*)
+ targ_defvec=bfd_powerpcle_pe_vec
+ targ_selvecs="bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec"
+ ;;
+
+ rs6000-*-*)
+ targ_defvec=rs6000coff_vec
+ ;;
+
+ sh-*-elf*)
+ targ_defvec=bfd_elf32_sh_vec
+ targ_selvecs="bfd_elf32_shl_vec shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec"
+ targ_underscore=yes
+ ;;
+ sh-*-* | sh-*-rtems*)
+ targ_defvec=shcoff_vec
+ targ_selvecs="shcoff_vec shlcoff_vec shcoff_small_vec shlcoff_small_vec"
+ targ_underscore=yes
+ ;;
+
+ sparclet-*-aout*)
+ targ_defvec=sunos_big_vec
+ targ_selvecs=sparcle_aout_vec
+ targ_underscore=yes
+ ;;
+ sparc86x-*-aout*)
+ targ_defvec=sunos_big_vec
+ targ_underscore=yes
+ ;;
+ sparclite-*-elf* | sparc86x-*-elf*)
+ targ_defvec=bfd_elf32_sparc_vec
+ ;;
+ sparc-*-linux*aout*)
+ targ_defvec=sparclinux_vec
+ targ_selvecs="bfd_elf32_sparc_vec sunos_big_vec"
+ targ_underscore=yes
+ ;;
+ sparc-*-linux-gnu*)
+ targ_defvec=bfd_elf32_sparc_vec
+ targ_selvecs="sparclinux_vec sunos_big_vec"
+ ;;
+ sparc-*-lynxos*)
+ targ_defvec=sparclynx_coff_vec
+ targ_selvecs=sparclynx_aout_vec
+ ;;
+ sparc-*-netbsd* | sparc-*-openbsd*)
+ targ_defvec=sparcnetbsd_vec
+ targ_underscore=yes
+ ;;
+ sparc-*-elf* | sparc-*-solaris2*)
+ targ_defvec=bfd_elf32_sparc_vec
+ targ_selvecs=sunos_big_vec
+ ;;
+ sparc-*-sysv4*)
+ targ_defvec=bfd_elf32_sparc_vec
+ ;;
+ sparc-*-netware*)
+ targ_defvec=bfd_elf32_sparc_vec
+ targ_selvecs="nlm32_sparc_vec sunos_big_vec"
+ ;;
+#ifdef BFD64
+ sparc64-*-aout*)
+ targ_defvec=sunos_big_vec
+ targ_underscore=yes
+ ;;
+ sparc64-*-linux-gnu*)
+ targ_defvec=bfd_elf64_sparc_vec
+ targ_selvecs="bfd_elf32_sparc_vec sparclinux_vec sunos_big_vec"
+ ;;
+ sparc64-*-elf*)
+ targ_defvec=bfd_elf64_sparc_vec
+ targ_selvecs=bfd_elf32_sparc_vec
+ ;;
+#endif /* BFD64 */
+ sparc*-*-coff*)
+ targ_defvec=sparccoff_vec
+ ;;
+ sparc*-*-* | sparc*-*-rtems*)
+ targ_defvec=sunos_big_vec
+ targ_underscore=yes
+ ;;
+
+#if HAVE_host_aout_vec
+ tahoe-*-*)
+ targ_defvec=host_aout_vec
+ targ_underscore=yes
+ ;;
+#endif
+
+ tic80*-*-*)
+ targ_defvec=tic80coff_vec
+ targ_underscore=yes
+ ;;
+
+
+ v850-*-*)
+ targ_defvec=bfd_elf32_v850_vec
+ ;;
+ v850e-*-*)
+ targ_defvec=bfd_elf32_v850_vec
+ ;;
+ v850ea-*-*)
+ targ_defvec=bfd_elf32_v850_vec
+ ;;
+#if HAVE_host_aout_vec
+ vax-*-bsd* | vax-*-ultrix*)
+ targ_defvec=host_aout_vec
+ targ_underscore=yes
+ ;;
+#endif
+
+ vax*-*-*vms*)
+ targ_defvec=vms_vax_vec
+ ;;
+
+ we32k-*-*)
+ targ_defvec=we32kcoff_vec
+ ;;
+
+ w65-*-*)
+ targ_defvec=w65_vec
+ ;;
+
+ z8k*-*-*)
+ targ_defvec=z8kcoff_vec
+ targ_underscore=yes
+ ;;
+
+ *-*-ieee*)
+ targ_defvec=ieee_vec
+ ;;
+
+ *-adobe-*)
+ targ_defvec=a_out_adobe_vec
+ targ_underscore=yes
+ ;;
+
+ *-sony-*)
+ targ_defvec=newsos3_vec
+ targ_underscore=yes
+ ;;
+
+ *-tandem-*)
+ targ_defvec=m68kcoff_vec
+ targ_selvecs=ieee_vec
+ ;;
+# END OF targmatch.h
+ *)
+ echo 1>&2 "*** BFD does not support target ${targ}."
+ echo 1>&2 "*** Look in bfd/config.bfd for supported targets."
+ exit 1
+ ;;
+esac
+
+# If we support any ELF target, then automatically add support for the
+# generic ELF targets. This permits an objdump with some ELF support
+# to be used on an arbitrary ELF file for anything other than
+# relocation information.
+case "${targ_defvec} ${targ_selvecs}" in
+ *bfd_elf64*)
+ targ_selvecs="${targ_selvecs} bfd_elf64_little_generic_vec bfd_elf64_big_generic_vec bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec"
+ ;;
+ *bfd_elf32*)
+ targ_selvecs="${targ_selvecs} bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec"
+ ;;
+esac
diff --git a/bfd/config.in b/bfd/config.in
new file mode 100644
index 00000000000..51fa45b6928
--- /dev/null
+++ b/bfd/config.in
@@ -0,0 +1,234 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the fcntl function. */
+#undef HAVE_FCNTL
+
+/* Define if you have the fdopen function. */
+#undef HAVE_FDOPEN
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the madvise function. */
+#undef HAVE_MADVISE
+
+/* Define if you have the mprotect function. */
+#undef HAVE_MPROTECT
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setitimer function. */
+#undef HAVE_SETITIMER
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the sysconf function. */
+#undef HAVE_SYSCONF
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/procfs.h> header file. */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Use b modifier when opening binary files? */
+#undef USE_BINARY_FOPEN
+
+/* Define if strstr is not declared in system header files. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Define if malloc is not declared in system header files. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Define if realloc is not declared in system header files. */
+#undef NEED_DECLARATION_REALLOC
+
+/* Define if free is not declared in system header files. */
+#undef NEED_DECLARATION_FREE
+
+/* Define if getenv is not declared in system header files. */
+#undef NEED_DECLARATION_GETENV
+
+/* Define if <sys/procfs.h> has prstatus_t. */
+#undef HAVE_PRSTATUS_T
+
+/* Define if <sys/procfs.h> has prstatus_t.pr_who. */
+#undef HAVE_PRSTATUS_T_PR_WHO
+
+/* Define if <sys/procfs.h> has pstatus_t. */
+#undef HAVE_PSTATUS_T
+
+/* Define if <sys/procfs.h> has prpsinfo_t. */
+#undef HAVE_PRPSINFO_T
+
+/* Define if <sys/procfs.h> has psinfo_t. */
+#undef HAVE_PSINFO_T
+
+/* Define if <sys/procfs.h> has lwpstatus_t. */
+#undef HAVE_LWPSTATUS_T
+
+/* Define if <sys/procfs.h> has lwpstatus_t.pr_context. */
+#undef HAVE_LWPSTATUS_T_PR_CONTEXT
+
+/* Define if <sys/procfs.h> has lwpstatus_t.pr_reg. */
+#undef HAVE_LWPSTATUS_T_PR_REG
+
+/* Name of host specific header file to include in trad-core.c. */
+#undef TRAD_HEADER
+
+/* Use mmap if it's available? */
+#undef USE_MMAP
+
diff --git a/bfd/configure b/bfd/configure
new file mode 100755
index 00000000000..f6ca66fae69
--- /dev/null
+++ b/bfd/configure
@@ -0,0 +1,5987 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=no]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)"
+ac_help="$ac_help
+ --enable-targets alternative target configurations"
+ac_help="$ac_help
+ --enable-commonbfdlib build shared BFD/opcodes/libiberty library"
+ac_help="$ac_help
+ --with-mmap try using mmap for BFD input files if available"
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=libbfd.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:594: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:615: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:633: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:658: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:688: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:739: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:771: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 782 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:813: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:818: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:846: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:878: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:911: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:964: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1021: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=bfd
+
+VERSION=2.9.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:1067: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:1080: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:1093: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:1106: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:1119: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1142: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1174: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1206: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=no
+fi
+
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1289: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1329: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:\\*)
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1347: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1350: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1386: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1402: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ else
+ ac_cv_path_NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1437: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags=
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1473 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1474: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ CFLAGS="$CFLAGS -belf"
+ ;;
+
+*-*-cygwin*)
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1499: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1531: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ DLLTOOL="false"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1566: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1598: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ AS="false"
+fi
+fi
+
+
+ ;;
+
+esac
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+# Check whether --enable-64-bit-bfd or --disable-64-bit-bfd was given.
+if test "${enable_64_bit_bfd+set}" = set; then
+ enableval="$enable_64_bit_bfd"
+ case "${enableval}" in
+ yes) want64=true ;;
+ no) want64=false ;;
+ *) { echo "configure: error: bad value ${enableval} for 64-bit-bfd option" 1>&2; exit 1; } ;;
+esac
+else
+ want64=false
+fi
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+ case "${enableval}" in
+ yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; }
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi
+# Check whether --enable-commonbfdlib or --disable-commonbfdlib was given.
+if test "${enable_commonbfdlib+set}" = set; then
+ enableval="$enable_commonbfdlib"
+ case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) { echo "configure: error: bad value ${enableval} for BFD commonbfdlib option" 1>&2; exit 1; } ;;
+esac
+fi
+# Check whether --with-mmap or --without-mmap was given.
+if test "${with_mmap+set}" = set; then
+ withval="$with_mmap"
+ case "${withval}" in
+ yes) want_mmap=true ;;
+ no) want_mmap=false ;;
+ *) { echo "configure: error: bad value ${withval} for BFD with-mmap option" 1>&2; exit 1; } ;;
+esac
+else
+ want_mmap=false
+fi
+
+
+
+
+
+if test -z "$target" ; then
+ { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; }
+fi
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:1718: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1741: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1746 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1757: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1774: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1779 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1805: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:1815: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+host64=false
+target64=false
+
+# host stuff:
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1844: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1874: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1925: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1957: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1968 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1999: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2004: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2013: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2032: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+ALL_LINGUAS=
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2066: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2081 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2087: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2098 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2104: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2115 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2121: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2146: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2151 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2159: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2176 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2194 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2215 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2250: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2255 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2325: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 2332 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2365: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2370 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2398: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2403 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:2433: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2438 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:2445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:2466: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2471 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:2499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2531: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2536 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2561: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2566 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2616: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2624 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2668: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2673 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2678: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2707: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2712 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2735: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:2760: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2768 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2936: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2941 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2976: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2981 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3033: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3038 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:3095: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3100 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:3107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:3128: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:3148: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:3167: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3172 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3177: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:3194: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3199 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:3222: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3230 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:3241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:3257: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3262 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3297: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3331: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3336 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3386: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3422: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 3454 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:3462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3494: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3528: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3564: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:3654: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:3682: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3687 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+# Permit host specific settings.
+. ${srcdir}/configure.host
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:3770: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+BFD_HOST_64BIT_LONG=0
+BFD_HOST_64_BIT_DEFINED=0
+BFD_HOST_64_BIT=
+BFD_HOST_U_64_BIT=
+if test "x${HOST_64BIT_TYPE}" = "xlong"; then
+ BFD_HOST_64BIT_LONG=1
+elif test "x${HOST_64BIT_TYPE}" != "x"; then
+ BFD_HOST_64_BIT_DEFINED=1
+ BFD_HOST_64_BIT=${HOST_64BIT_TYPE}
+ BFD_HOST_U_64_BIT=${HOST_U_64BIT_TYPE}
+fi
+
+
+
+
+
+# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ CC_FOR_BUILD=gcc
+ fi
+fi
+
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+else
+ echo $ac_n "checking for build system executable suffix""... $ac_c" 1>&6
+echo "configure:3853: checking for build system executable suffix" >&5
+if eval "test \"`echo '$''{'bfd_cv_build_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > ac_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+ ${CC_FOR_BUILD} -o ac_c_test am_c_test.c 1>&5 2>&5
+ bfd_cv_build_exeext=`echo ac_c_test.* | grep -v ac_c_test.c | sed -e s/ac_c_test//`
+ rm -f ac_c_test*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no
+fi
+
+echo "$ac_t""$bfd_cv_build_exeext" 1>&6
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+
+
+for ac_hdr in stddef.h string.h strings.h stdlib.h time.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3878: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3883 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3888: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in fcntl.h sys/file.h sys/time.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3918: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3923 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3928: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:3955: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3960 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:3969: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:3994: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3999 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:4007: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:4032: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4040 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:4051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:4073: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4081 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:4092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in fcntl getpagesize setitimer sysconf fdopen
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4117: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4122 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+case "${host}" in
+*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows)
+ cat >> confdefs.h <<\EOF
+#define USE_BINARY_FOPEN 1
+EOF
+ ;;
+esac
+
+echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6
+echo "configure:4180: checking whether strstr must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4185 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strstr
+; return 0; }
+EOF
+if { (eval echo configure:4206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strstr" 1>&6
+if test $bfd_cv_decl_needed_strstr = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRSTR 1
+EOF
+
+fi
+
+echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6
+echo "configure:4227: checking whether malloc must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4232 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) malloc
+; return 0; }
+EOF
+if { (eval echo configure:4253: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_malloc=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_malloc=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_malloc" 1>&6
+if test $bfd_cv_decl_needed_malloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_MALLOC 1
+EOF
+
+fi
+
+echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6
+echo "configure:4274: checking whether realloc must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4279 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) realloc
+; return 0; }
+EOF
+if { (eval echo configure:4300: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_realloc=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_realloc=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_realloc" 1>&6
+if test $bfd_cv_decl_needed_realloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_REALLOC 1
+EOF
+
+fi
+
+echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
+echo "configure:4321: checking whether free must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4326 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) free
+; return 0; }
+EOF
+if { (eval echo configure:4347: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6
+if test $bfd_cv_decl_needed_free = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_FREE 1
+EOF
+
+fi
+
+echo $ac_n "checking whether getenv must be declared""... $ac_c" 1>&6
+echo "configure:4368: checking whether getenv must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_getenv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4373 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) getenv
+; return 0; }
+EOF
+if { (eval echo configure:4394: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_getenv=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_getenv=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_getenv" 1>&6
+if test $bfd_cv_decl_needed_getenv = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_GETENV 1
+EOF
+
+fi
+
+
+# If we are configured native, pick a core file support file.
+COREFILE=
+COREFLAG=
+TRAD_HEADER=
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ alpha*-*-linux-gnu*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/alphalinux.h"'
+ ;;
+ alpha*-*-netbsd*) COREFILE=netbsd-core.lo ;;
+ alpha*-*-*) COREFILE=osf-core.lo ;;
+ arm-*-riscix) COREFILE=trad-core.lo ;;
+ hppa*-*-hpux*) COREFILE=hpux-core.lo ;;
+ hppa*-*-hiux*) COREFILE=hpux-core.lo ;;
+ hppa*-*-mpeix*) COREFILE=hpux-core.lo ;;
+ hppa*-*-bsd*) COREFILE="hpux-core.lo hppabsd-core.lo"
+ COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;;
+ i[3456]86-sequent-bsd*)
+ COREFILE=trad-core.lo;
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+ i[3456]86-sequent-sysv4*) ;;
+ i[3456]86-sequent-sysv*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+ i[3456]86-*-bsd* | i[3456]86-*-freebsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386bsd.h"'
+ ;;
+ i[3456]86-*-netbsd* | i[3456]86-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ i[3456]86-esix-sysv3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/esix.h"'
+ ;;
+ i[3456]86-*-sco3.2v5*)
+ COREFILE=sco5-core.lo
+ ;;
+ i[3456]86-*-sco* | i[3456]86-*-isc*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386sco.h"'
+ ;;
+ i[3456]86-*-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386mach3.h"'
+ ;;
+ i[3456]86-*-linux-gnu*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386linux.h"'
+ ;;
+ i[3456]86-*-isc*) COREFILE=trad-core.lo ;;
+ i[3456]86-*-aix*) COREFILE=aix386-core.lo ;;
+ i860-*-mach3* | i860-*-osf1*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i860mach3.h"'
+ ;;
+ mips-dec-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/mipsbsd.h"'
+ ;;
+ mips-dec-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/mipsmach3.h"'
+ ;;
+ mips-*-netbsd* | mips*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ mips-dec-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/decstation.h"'
+ ;;
+ mips-sgi-irix4*) COREFILE=irix-core.lo ;;
+ mips-sgi-irix5*) COREFILE=irix-core.lo ;;
+ mips-sgi-irix6*) COREFILE=irix-core.lo ;;
+ mips-*-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/mipsmach3.h"'
+ ;;
+ mips-*-sysv4*) ;;
+ mips-*-sysv* | mips-*-riscos*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/riscos.h"'
+ ;;
+ mips-sony-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/news-mips.h"'
+ ;;
+ m68*-bull*-sysv*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/dpx2.h"'
+ ;;
+ m68*-hp-hpux*) COREFILE=hpux-core.lo ;;
+ m68*-hp-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/hp300bsd.h"'
+ ;;
+ m68*-*-linux-gnu*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/m68klinux.h"'
+ ;;
+ m68*-motorola-sysv*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/delta68.h"'
+ ;;
+ m68*-sony-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/news.h"'
+ ;;
+ m68*-*-netbsd* | m68*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ m68*-apple-aux*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/m68kaux.h"'
+ ;;
+ m88*-*-sysv4*) ;;
+ m88*-motorola-sysv*) COREFILE=ptrace-core.lo ;;
+ m88*-*-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/m88kmach3.h"'
+ ;;
+ ns32k-pc532-mach)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/pc532mach.h"'
+ ;;
+ ns32k-*-netbsd* | ns32k-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ rs6000-*-lynx*) COREFILE=lynx-core.lo ;;
+ rs6000-*-aix4*) COREFILE=rs6000-core.lo ;;
+ rs6000-*-*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-*bsd*) COREFILE=netbsd-core.lo ;;
+ powerpc-*-aix4*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-aix*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-beos*) ;;
+ powerpc-*-netbsd*) COREFILE=netbsd-core.lo ;;
+ sparc-*-netbsd* | sparc-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ tahoe-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/tahoe.h"'
+ ;;
+ vax-*-ultrix2*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-ultrix*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxbsd.h"'
+ ;;
+ esac
+
+ case "$COREFILE" in
+ aix386-core.lo) COREFLAG=-DAIX386_CORE ;;
+ hppabsd-core.lo) COREFLAG=-DHPPABSD_CORE ;;
+ hpux-core.lo) COREFLAG=-DHPUX_CORE ;;
+ irix-core.lo) COREFLAG=-DIRIX_CORE ;;
+ lynx-core.lo) COREFLAG=-DLYNX_CORE ;;
+ netbsd-core.lo) COREFLAG=-DNETBSD_CORE ;;
+ osf-core.lo) COREFLAG=-DOSF_CORE ;;
+ ptrace-core.lo) COREFLAG=-DPTRACE_CORE ;;
+ rs6000-core.lo) COREFLAG="$COREFLAG -DAIX_CORE" ;;
+ sco5-core.lo) COREFLAG="$COREFLAG -DSCO5_CORE" ;;
+ trad-core.lo) COREFLAG="$COREFLAG -DTRAD_CORE" ;;
+ esac
+
+ # ELF corefile support has several flavors, but all of
+ # them use something called <sys/procfs.h>
+ for ac_hdr in sys/procfs.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4595: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4600 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4605: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ if test "$ac_cv_header_sys_procfs_h" = yes; then
+ echo $ac_n "checking for prstatus_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4633: checking for prstatus_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prstatus_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4638 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+prstatus_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4645: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prstatus_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prstatus_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prstatus_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRSTATUS_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prstatus_t" 1>&6
+
+ echo $ac_n "checking for prstatus_t.pr_who in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4667: checking for prstatus_t.pr_who in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4672 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+prstatus_t avar; void* aref = (void*) &avar.pr_who
+; return 0; }
+EOF
+if { (eval echo configure:4679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRSTATUS_T_PR_WHO 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who" 1>&6
+
+ echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4701: checking for pstatus_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4706 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+pstatus_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4713: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pstatus_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_pstatus_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pstatus_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PSTATUS_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6
+
+ echo $ac_n "checking for prpsinfo_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4735: checking for prpsinfo_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prpsinfo_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4740 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+prpsinfo_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4747: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prpsinfo_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_prpsinfo_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prpsinfo_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRPSINFO_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_prpsinfo_t" 1>&6
+
+ echo $ac_n "checking for psinfo_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4769: checking for psinfo_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psinfo_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4774 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+psinfo_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4781: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_psinfo_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_psinfo_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_psinfo_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PSINFO_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_psinfo_t" 1>&6
+
+ echo $ac_n "checking for lwpstatus_t in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4803: checking for lwpstatus_t in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpstatus_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4808 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+lwpstatus_t avar
+; return 0; }
+EOF
+if { (eval echo configure:4815: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_lwpstatus_t=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_lwpstatus_t=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_lwpstatus_t = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LWPSTATUS_T 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpstatus_t" 1>&6
+
+ echo $ac_n "checking for lwpstatus_t.pr_context in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4837: checking for lwpstatus_t.pr_context in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4842 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+lwpstatus_t avar; void* aref = (void*) &avar.pr_context
+; return 0; }
+EOF
+if { (eval echo configure:4849: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LWPSTATUS_T_PR_CONTEXT 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context" 1>&6
+
+ echo $ac_n "checking for lwpstatus_t.pr_reg in sys/procfs.h""... $ac_c" 1>&6
+echo "configure:4871: checking for lwpstatus_t.pr_reg in sys/procfs.h" >&5
+ if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4876 "configure"
+#include "confdefs.h"
+#include <sys/procfs.h>
+int main() {
+lwpstatus_t avar; void* aref = (void*) &avar.pr_reg
+; return 0; }
+EOF
+if { (eval echo configure:4883: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg=no
+
+fi
+rm -f conftest*
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LWPSTATUS_T_PR_REG 1
+EOF
+
+ fi
+ echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg" 1>&6
+
+ fi
+fi
+
+
+cat >> confdefs.h <<EOF
+#define TRAD_HEADER $TRAD_HEADER
+EOF
+
+
+# Horrible hacks to build DLLs on Windows.
+WIN32LDFLAGS=
+WIN32LIBADD=
+case "${host}" in
+*-*-cygwin*)
+ if test "$enable_shared" = "yes"; then
+ WIN32LDFLAGS="-no-undefined"
+ WIN32LIBADD="-L`pwd`/../libiberty -liberty -L`pwd`/../intl -lintl -lcygwin -lkernel32"
+ fi
+ ;;
+esac
+
+
+
+# target stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets" ; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+ else
+ # Allow targets that config.sub doesn't recognize, like "all".
+ canon_targets="$canon_targets $targ"
+ fi
+ done
+fi
+
+all_targets=false
+defvec=
+selvecs=
+selarchs=
+TDEFINES=
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall"; then
+ all_targets=true
+ else
+ . $srcdir/config.bfd
+ if test "x$targ" = "x$target"; then
+ defvec=$targ_defvec
+ fi
+ selvecs="$selvecs $targ_defvec $targ_selvecs"
+ selarchs="$selarchs $targ_archs"
+ TDEFINES="$TDEFINES $targ_cflags"
+ fi
+done
+
+
+# This processing still needs to be done if we're to decide properly whether
+# 64-bit support needs to be compiled in. Currently, it will be included if
+# the default or any other explicitly requested target requires it; it
+# will not be included on a 32-bit host if no 64-bit target is requested, and
+# no "--with-64-bit-bfd" option is given, even if "--with-targets=all" is
+# used.
+
+# uniq the default and selected vectors in all the configured targets.
+f=""
+for i in $selvecs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+selvecs="$f"
+
+
+# uniq the architectures in all the configured targets.
+f=""
+for i in $selarchs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+selarchs="$f"
+
+# Target backend .o files.
+tb=
+
+elf="elf.lo elflink.lo dwarf2.lo dwarf1.lo"
+
+for vec in $selvecs
+do
+ case "$vec" in
+ # This list is alphabetized to make it easy to compare
+ # with the two vector lists in targets.c.
+ a29kcoff_big_vec) tb="$tb coff-a29k.lo cofflink.lo" ;;
+ a_out_adobe_vec) tb="$tb aout-adobe.lo aout32.lo" ;;
+ armcoff_little_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ armcoff_big_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ armpe_little_vec) tb="$tb pe-arm.lo coff-arm.lo cofflink.lo " ;;
+ armpe_big_vec) tb="$tb pe-arm.lo coff-arm.lo cofflink.lo " ;;
+ armpei_little_vec) tb="$tb pei-arm.lo cofflink.lo " ;;
+ armpei_big_vec) tb="$tb pei-arm.lo cofflink.lo " ;;
+ arm_epoc_pe_little_vec) tb="$tb epoc-pe-arm.lo cofflink.lo " ;;
+ arm_epoc_pe_big_vec) tb="$tb epoc-pe-arm.lo cofflink.lo " ;;
+ arm_epoc_pei_little_vec) tb="$tb epoc-pei-arm.lo cofflink.lo " ;;
+ arm_epoc_pei_big_vec) tb="$tb epoc-pei-arm.lo cofflink.lo " ;;
+ aout0_big_vec) tb="$tb aout0.lo aout32.lo" ;;
+ aout_arm_big_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ aout_arm_little_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ aout_mips_big_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
+ aout_mips_little_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
+ apollocoff_vec) tb="$tb coff-apollo.lo" ;;
+ b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;;
+ b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
+ bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"
+ target64=true ;;
+ bfd_elf32_littlearc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ bfd_elf32_littlearm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;;
+ bfd_elf32_littlearm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;
+ bfd_elf32_bigarc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ bfd_elf32_bigarm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;;
+ bfd_elf32_bigarm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;
+ bfd_elf32_big_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ bfd_elf32_bigmips_vec) tb="$tb elf32-mips.lo elf32.lo $elf ecofflink.lo" ;;
+ bfd_elf64_bigmips_vec) tb="$tb elf64-mips.lo elf64.lo elf32-mips.lo elf32.lo $elf ecofflink.lo"
+ target64=true ;;
+ bfd_elf32_d10v_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;;
+ bfd_elf32_d30v_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;;
+ bfd_elf32_fr30_vec) tb="$tb elf32-fr30.lo elf32.lo $elf" ;;
+ bfd_elf32_hppa_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ bfd_elf32_i386_vec) tb="$tb elf32-i386.lo elf32.lo $elf" ;;
+ bfd_elf32_i860_vec) tb="$tb elf32-i860.lo elf32.lo $elf" ;;
+ bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ bfd_elf32_littlemips_vec) tb="$tb elf32-mips.lo elf32.lo $elf ecofflink.lo" ;;
+ bfd_elf64_littlemips_vec) tb="$tb elf64-mips.lo elf64.lo elf32-mips.lo elf32.lo $elf ecofflink.lo"
+ target64=true ;;
+ bfd_elf32_m32r_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ bfd_elf32_m68k_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
+ bfd_elf32_m88k_vec) tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
+ bfd_elf32_mcore_big_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ bfd_elf32_mcore_little_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ bfd_elf32_mn10200_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;;
+ bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
+ bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf32.lo $elf" ;;
+ bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.lo elf32.lo $elf" ;;
+ bfd_elf32_sh_vec) tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo" ;;
+ bfd_elf32_shl_vec) tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo" ;;
+ bfd_elf32_sparc_vec) tb="$tb elf32-sparc.lo elf32.lo $elf" ;;
+ bfd_elf32_v850_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
+ bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"
+ target64=true ;;
+ bfd_elf64_little_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"
+ target64=true ;;
+ bfd_elf64_sparc_vec) tb="$tb elf64-sparc.lo elf64.lo $elf"
+ target64=true ;;
+ cisco_core_vec) tb="$tb cisco-core.lo" ;;
+ demo_64_vec) tb="$tb demo64.lo aout64.lo"
+ target64=true ;;
+ ecoff_big_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ ecoff_little_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ ecoff_biglittle_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ ecoffalpha_little_vec) tb="$tb coff-alpha.lo ecoff.lo ecofflink.lo"
+ target64=true ;;
+ go32coff_vec) tb="$tb coff-go32.lo cofflink.lo" ;;
+ go32stubbedcoff_vec) tb="$tb coff-stgo32.lo cofflink.lo" ;;
+ h8300coff_vec) tb="$tb coff-h8300.lo reloc16.lo" ;;
+ h8500coff_vec) tb="$tb coff-h8500.lo reloc16.lo" ;;
+ host_aout_vec) tb="$tb host-aout.lo aout32.lo" ;;
+ hp300bsd_vec) tb="$tb hp300bsd.lo aout32.lo" ;;
+ hp300hpux_vec) tb="$tb hp300hpux.lo aout32.lo" ;;
+ i386aout_vec) tb="$tb i386aout.lo aout32.lo" ;;
+ i386bsd_vec) tb="$tb i386bsd.lo aout32.lo" ;;
+ i386coff_vec) tb="$tb coff-i386.lo cofflink.lo" ;;
+ i386dynix_vec) tb="$tb i386dynix.lo aout32.lo" ;;
+ i386freebsd_vec) tb="$tb i386freebsd.lo aout32.lo" ;;
+ i386msdos_vec) tb="$tb i386msdos.lo" ;;
+ i386pe_vec) tb="$tb pe-i386.lo cofflink.lo " ;;
+ i386pei_vec) tb="$tb pei-i386.lo cofflink.lo" ;;
+ i386linux_vec) tb="$tb i386linux.lo aout32.lo" ;;
+ i386lynx_aout_vec) tb="$tb i386lynx.lo lynx-core.lo aout32.lo" ;;
+ i386lynx_coff_vec) tb="$tb cf-i386lynx.lo cofflink.lo lynx-core.lo" ;;
+ i386mach3_vec) tb="$tb i386mach3.lo aout32.lo" ;;
+ i386netbsd_vec) tb="$tb i386netbsd.lo aout32.lo" ;;
+ i386os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
+ i860coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
+ icoff_big_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ icoff_little_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ ieee_vec) tb="$tb ieee.lo" ;;
+ m68kcoff_vec) tb="$tb coff-m68k.lo cofflink.lo" ;;
+ m68kcoffun_vec) tb="$tb coff-u68k.lo coff-m68k.lo cofflink.lo" ;;
+ m68klinux_vec) tb="$tb m68klinux.lo aout32.lo" ;;
+ m68klynx_aout_vec) tb="$tb m68klynx.lo lynx-core.lo aout32.lo" ;;
+ m68klynx_coff_vec) tb="$tb cf-m68klynx.lo coff-m68k.lo cofflink.lo lynx-core.lo" ;;
+ m68knetbsd_vec) tb="$tb m68knetbsd.lo aout32.lo" ;;
+ m68k4knetbsd_vec) tb="$tb m68k4knetbsd.lo aout32.lo" ;;
+ m68kaux_coff_vec) tb="$tb coff-aux.lo coff-m68k.lo cofflink.lo" ;;
+ m68ksysvcoff_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;;
+ m88kbcs_vec) tb="$tb coff-m88k.lo" ;;
+ mcore_pe_big_vec) tb="$tb pe-mcore.lo cofflink.lo" ;;
+ mcore_pe_little_vec) tb="$tb pe-mcore.lo cofflink.lo" ;;
+ mcore_pei_big_vec) tb="$tb pei-mcore.lo cofflink.lo" ;;
+ mcore_pei_little_vec) tb="$tb pei-mcore.lo cofflink.lo" ;;
+ newsos3_vec) tb="$tb newsos3.lo aout32.lo" ;;
+ nlm32_i386_vec) tb="$tb nlm32-i386.lo nlm32.lo nlm.lo" ;;
+ nlm32_sparc_vec) tb="$tb nlm32-sparc.lo nlm32.lo nlm.lo" ;;
+ nlm32_alpha_vec) tb="$tb nlm32-alpha.lo nlm32.lo nlm.lo"
+ target64=true ;;
+ riscix_vec) tb="$tb aout32.lo riscix.lo" ;;
+ nlm32_powerpc_vec) tb="$tb nlm32-ppc.lo nlm32.lo nlm.lo" ;;
+ pc532netbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
+ pc532machaout_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
+ pmac_xcoff_vec) tb="$tb coff-pmac.lo xcofflink.lo" ;;
+ rs6000coff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
+ bfd_powerpc_pe_vec) tb="$tb pe-ppc.lo cofflink.lo" ;;
+ bfd_powerpcle_pe_vec) tb="$tb pe-ppc.lo cofflink.lo" ;;
+ bfd_powerpc_pei_vec) tb="$tb pei-ppc.lo cofflink.lo" ;;
+ bfd_powerpcle_pei_vec) tb="$tb pei-ppc.lo cofflink.lo" ;;
+ ppcboot_vec) tb="$tb ppcboot.lo" ;;
+ shcoff_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ shlcoff_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ shcoff_small_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ shlcoff_small_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ som_vec) tb="$tb som.lo" ;;
+ sparcle_aout_vec) tb="$tb aout-sparcle.lo aout32.lo" ;;
+ sparclinux_vec) tb="$tb sparclinux.lo aout32.lo" ;;
+ sparclynx_aout_vec) tb="$tb sparclynx.lo lynx-core.lo aout32.lo" ;;
+ sparclynx_coff_vec) tb="$tb cf-sparclynx.lo lynx-core.lo" ;;
+ sparcnetbsd_vec) tb="$tb sparcnetbsd.lo aout32.lo" ;;
+ sparccoff_vec) tb="$tb coff-sparc.lo" ;;
+ srec_vec) tb="$tb srec.lo" ;;
+ sunos_big_vec) tb="$tb sunos.lo aout32.lo" ;;
+ symbolsrec_vec) tb="$tb srec.lo" ;;
+ tekhex_vec) tb="$tb tekhex.lo" ;;
+ tic30_aout_vec) tb="$tb aout-tic30.lo" ;;
+ tic30_coff_vec) tb="$tb coff-tic30.lo" ;;
+ tic80coff_vec) tb="$tb coff-tic80.lo cofflink.lo" ;;
+ versados_vec) tb="$tb versados.lo" ;;
+ vms_alpha_vec) tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo"
+ target64=true ;;
+ vms_vax_vec) tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo" ;;
+ w65_vec) tb="$tb coff-w65.lo reloc16.lo" ;;
+ we32kcoff_vec) tb="$tb coff-we32k.lo" ;;
+ z8kcoff_vec) tb="$tb coff-z8k.lo reloc16.lo" ;;
+
+ "") ;;
+ *) { echo "configure: error: *** unknown target vector $vec" 1>&2; exit 1; } ;;
+ esac
+done
+
+# Target architecture .o files.
+# A couple of CPUs use shorter file names to avoid problems on DOS
+# filesystems.
+ta=`echo $selarchs | sed -e s/bfd_/cpu-/g -e s/_arch/.lo/g -e s/mn10200/m10200/ -e s/mn10300/m10300/`
+
+# Weed out duplicate .o files.
+f=""
+for i in $tb ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+tb="$f"
+
+f=""
+for i in $ta ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+ta="$f"
+
+bfd_backends="$tb"
+bfd_machines="$ta"
+
+if test x${all_targets} = xtrue ; then
+ bfd_backends="${bfd_backends}"' $(ALL_BACKENDS)'
+ bfd_machines="${bfd_machines}"' $(ALL_MACHINES)'
+ selvecs=
+ havevecs=
+ selarchs=
+else # all_targets is true
+ # Only set these if they will be nonempty, for the clever echo.
+ havevecs=
+ test -n "$selvecs" &&
+ havevecs=`echo $selvecs | sed -e 's/^/-DHAVE_/' -e 's/ \(.\)/ -DHAVE_\1/g'`
+ test -n "$selvecs" &&
+ selvecs=`echo $selvecs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'`
+ test -n "$selarchs" &&
+ selarchs=`echo $selarchs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'`
+fi # all_targets is true
+
+case ${host64}-${target64}-${want64} in
+ *true*)
+ wordsize=64
+ all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
+ if test -z "$GCC" && test "$BFD_HOST_64BIT_LONG" = "0" && test "$BFD_HOST_64_BIT_DEFINED" = "0"; then
+ echo "configure: warning: You have requested a 64 bit BFD configuration, but" 1>&2
+ echo "configure: warning: your compiler may not have a 64 bit integral type" 1>&2
+ fi
+ ;;
+ false-false-false)
+ wordsize=32
+ all_backends='$(BFD32_BACKENDS)'
+ ;;
+esac
+
+
+
+
+
+
+tdefaults=""
+test -n "${defvec}" && tdefaults="${tdefaults} -DDEFAULT_VECTOR=${defvec}"
+test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'"
+test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'"
+test -n "${havevecs}" && tdefaults="${tdefaults} ${havevecs}"
+
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5239: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5244 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5249: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5278: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5283 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:5331: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5339 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:5479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+for ac_func in madvise mprotect
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5504: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5509 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+case ${want_mmap}+${ac_cv_func_mmap_fixed_mapped} in
+ true+yes ) cat >> confdefs.h <<\EOF
+#define USE_MMAP 1
+EOF
+ ;;
+esac
+
+rm -f doc/config.status
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@HDEFINES@%$HDEFINES%g
+s%@BFD_HOST_64BIT_LONG@%$BFD_HOST_64BIT_LONG%g
+s%@BFD_HOST_64_BIT_DEFINED@%$BFD_HOST_64_BIT_DEFINED%g
+s%@BFD_HOST_64_BIT@%$BFD_HOST_64_BIT%g
+s%@BFD_HOST_U_64_BIT@%$BFD_HOST_U_64_BIT%g
+s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g
+s%@EXEEXT_FOR_BUILD@%$EXEEXT_FOR_BUILD%g
+s%@COREFILE@%$COREFILE%g
+s%@COREFLAG@%$COREFLAG%g
+s%@WIN32LDFLAGS@%$WIN32LDFLAGS%g
+s%@WIN32LIBADD@%$WIN32LIBADD%g
+s%@TDEFINES@%$TDEFINES%g
+s%@wordsize@%$wordsize%g
+s%@all_backends@%$all_backends%g
+s%@bfd_backends@%$bfd_backends%g
+s%@bfd_machines@%$bfd_machines%g
+s%@tdefaults@%$tdefaults%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/bfd/configure.bat b/bfd/configure.bat
new file mode 100644
index 00000000000..78fe79e9112
--- /dev/null
+++ b/bfd/configure.bat
@@ -0,0 +1,18 @@
+@echo off
+if "%1" == "h8/300" goto h8300
+
+echo Configuring bfd for go32
+update hosts\go32.h sysdep.h
+update Makefile.dos Makefile
+echo s/@WORDSIZE@/32/g>config.sed
+sed -e s/^/s\/@VERSION@\// -e s/$/\/g/g version >>config.sed
+sed -f config.sed < bfd-in2.h > bfd.h2
+update bfd.h2 bfd.h
+goto exit
+
+:h8300
+echo Configuring bfd for H8/300
+update hosts\h-go32.h sysdep.h
+update Makefile.dos Makefile
+
+:exit
diff --git a/bfd/configure.com b/bfd/configure.com
new file mode 100644
index 00000000000..929977ce8f1
--- /dev/null
+++ b/bfd/configure.com
@@ -0,0 +1,215 @@
+$!
+$! This file configures the bfd library for use with openVMS (Alpha and Vax)
+$!
+$! We do not use the configure script, since we do not have /bin/sh
+$! to execute it.
+$!
+$! Written by Klaus K"ampf (kkaempf@rmi.de)
+$!
+$arch_indx = 1 + ((f$getsyi("CPU").ge.128).and.1) ! vax==1, alpha==2
+$arch = f$element(arch_indx,"|","|VAX|Alpha|")
+$!
+$if arch .eqs. "Alpha"
+$then
+$ write sys$output "Configuring for Alpha target"
+$ target = "alpha"
+$!
+$! copy bfd-in2.h to bfd.h, replacing @ macros
+$!
+$ edit/tpu/nojournal/nosection/nodisplay/command=sys$input -
+ []bfd-in2.h /output=[]bfd.h
+$DECK
+!
+! Copy file, changing lines with macros (@@)
+!
+!
+ vfile := CREATE_BUFFER("vfile", "CONFIGURE.IN");
+ rang := CREATE_RANGE(BEGINNING_OF(vfile), END_OF(vfile));
+ match_pos := SEARCH_QUIETLY('AM_INIT_AUTOMAKE(bfd, ', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ vers := CURRENT_LINE-")";
+ ELSE;
+ vers := "unknown";
+ ENDIF;
+
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
+
+ match_pos := SEARCH_QUIETLY('@VERSION@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT(vers);
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@wordsize@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('64');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64BIT_LONG@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('0');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64_BIT_DEFINED@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('__DECC');
+ SPLIT_LINE;
+ COPY_TEXT('#include <ints.h>');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64_BIT@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('int64');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_U_64_BIT@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('uint64');
+ ENDIF;
+ WRITE_FILE(file, GET_INFO(COMMAND_LINE, "output_file"));
+ QUIT
+$ EOD
+$
+$else
+$
+$ write sys$output "Configuring for Vax target"
+$ target = "vax"
+$!
+$! copy bfd-in2.h to bfd.h, replacing @ macros
+$!
+$ edit/tpu/nojournal/nosection/nodisplay/command=sys$input -
+ []bfd-in2.h /output=[]bfd.h
+$DECK
+!
+! Copy file, changing lines with macros (@@)
+!
+!
+ vfile := CREATE_BUFFER("vfile", "CONFIGURE.IN");
+ rang := CREATE_RANGE(BEGINNING_OF(vfile), END_OF(vfile));
+ match_pos := SEARCH_QUIETLY('AM_INIT_AUTOMAKE(bfd, ', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ vers := CURRENT_LINE-")";
+ ELSE;
+ vers := "unknown";
+ ENDIF;
+
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
+
+ match_pos := SEARCH_QUIETLY('@VERSION@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT(vers);
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@wordsize@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('32');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64BIT_LONG@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('0');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64_BIT_DEFINED@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('__DECC');
+ SPLIT_LINE;
+ COPY_TEXT('#include <ints.h>');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64_BIT@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('int64');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_U_64_BIT@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('uint64');
+ ENDIF;
+ WRITE_FILE(file, GET_INFO(COMMAND_LINE, "output_file"));
+ QUIT
+$ EOD
+$endif
+$
+$ write sys$output "Generated `bfd.h' from `bfd-in2.h'."
+$!
+$!
+$! create targmatch.h
+$!
+$ open/write tfile []targmatch.h
+$ write tfile "{ """ + target + "-*-*vms*""" + ","
+$ write tfile "#if defined (SELECT_VECS)"
+$ write tfile "SELECT_VECS"
+$ write tfile "#else"
+$ write tfile "UNSUPPORTED_TARGET"
+$ write tfile "#endif"
+$ write tfile "},"
+$ close tfile
+$ write sys$output "Generated `targmatch.h'"
+$!
+$!
+$! create config.h
+$!
+$ create []config.h
+/* config.h-vms. Generated by hand by Klaus Kämpf, kkaempf@didymus.rmi.de. */
+/* config.in. Generated automatically from configure.in by autoheader. */
+/* Whether malloc must be declared even if <stdlib.h> is included. */
+/* #undef NEED_DECLARATION_MALLOC */
+/* Whether free must be declared even if <stdlib.h> is included. */
+/* #undef NEED_DECLARATION_FREE */
+/* Define if you have a working `mmap' system call. */
+/* #define HAVE_MMAP 1 */
+/* Do we need to use the b modifier when opening binary files? */
+/* #undef USE_BINARY_FOPEN */
+/* Name of host specific header file to include in trad-core.c. */
+/* #undef TRAD_HEADER */
+/* Define only if <sys/procfs.h> is available *and* it defines prstatus_t. */
+/* #undef HAVE_SYS_PROCFS_H */
+/* Do we really want to use mmap if it's available? */
+/* #undef USE_MMAP */
+/* Define if you have the fcntl function. */
+#define HAVE_FCNTL 1
+/* Define if you have the getpagesize function. */
+#define HAVE_GETPAGESIZE 1
+/* Define if you have the madvise function. */
+#define HAVE_MADVISE 1
+/* Define if you have the mprotect function. */
+#define HAVE_MPROTECT 1
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+/* Define if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+/* Define if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+$!
+$ write sys$output "Generated `config.h'"
+
diff --git a/bfd/configure.host b/bfd/configure.host
new file mode 100644
index 00000000000..ef7048be13c
--- /dev/null
+++ b/bfd/configure.host
@@ -0,0 +1,70 @@
+# This file is a shell script that overrides some of the tools and
+# flags used on a host specific basis.
+
+# Since the "bfd/hosts" directory is shared by the bfd, opcodes, and
+# binutils directories (at least), the index to it is also shared.
+# This is that index. Each configure.in file should source this file
+# in its per-host part.
+
+# This sets the following shell variables:
+# HDEFINES host specific compiler options
+# host64 set to true if 64 bit types are as fast as 32 bit
+# HOST_64BIT_TYPE host 64 bit type
+# HOST_U_64BIT_TYPE unsigned 64 bit type (not needed if 64BIT_TYPE is long)
+
+HDEFINES=
+host64=false
+HOST_64BIT_TYPE=
+HOST_U_64BIT_TYPE=
+
+case "${host}" in
+
+alpha*-*-*) host64=true; HOST_64BIT_TYPE=long ;;
+
+hppa*-*-hpux*) HDEFINES=-DHOST_HPPAHPUX ;;
+hppa*-*-hiux*) HDEFINES=-DHOST_HPPAHPUX ;;
+hppa*-*-mpeix*) HDEFINES=-DHOST_HPPAMPEIX ;;
+hppa*-*-bsd*) HDEFINES=-DHOST_HPPABSD ;;
+hppa*-*-osf*) HDEFINES=-DHOST_HPPAOSF ;;
+
+i[3456]86-sequent-bsd*) HDEFINES=-Dshared=genshared ;;
+i[3456]86-sequent-sysv4*) ;;
+i[3456]86-sequent-sysv*) HDEFINES=-Dshared=genshared ;;
+
+mips*-dec-netbsd*) ;;
+mips*-*-openbsd*) ;;
+mips*-dec-*) HDEFINES="-G 4" ;;
+mips*-sgi-irix3*) HDEFINES="-G 4" ;;
+mips*-sgi-irix4*) HDEFINES="-G 4" ;;
+mips*-sgi-irix6*) host64=true
+ HOST_64BIT_TYPE="long long";
+ HOST_U_64BIT_TYPE="unsigned long long";
+ ;;
+mips*-*-sysv4*) ;;
+mips*-*-sysv*) HDEFINES="-G 4" ;;
+mips*-*-riscos*) HDEFINES="-G 4" ;;
+
+m68*-hp-hpux*) HDEFINES=-DHOST_HP300HPUX ;;
+
+*-*-solaris*) HOST_64BIT_TYPE="long long"
+ HOST_U_64BIT_TYPE="unsigned long long"
+ ;;
+
+*-*-windows*)
+ HOST_64BIT_TYPE=__int64
+ HOST_U_64BIT_TYPE="unsigned __int64"
+# The following krock is necessary because we can't run the build compiler
+# (MSVC) on the configure host, so we have to explicitly set the values here.
+# Note that this file is never run through autoconf, so we can't use any
+# autoconf macros here. Because of this, we have to muck with autoconf
+# variables explicitly.
+ ac_cv_func_mmap_fixed_mapped=no
+ ac_cv_header_time=no
+ ac_cv_func_getpagesize=no
+ ac_cv_func_madvise=no
+ ac_cv_func_mprotect=no
+ ac_cv_header_sys_file_h=no
+ ac_cv_header_sys_time_h=no
+ ac_cv_header_unistd_h=no
+ ;;
+esac
diff --git a/bfd/configure.in b/bfd/configure.in
new file mode 100644
index 00000000000..3a3e36f1b66
--- /dev/null
+++ b/bfd/configure.in
@@ -0,0 +1,648 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+
+AC_PREREQ(2.13)
+AC_INIT(libbfd.c)
+
+AC_CANONICAL_SYSTEM
+AC_ISC_POSIX
+
+AM_INIT_AUTOMAKE(bfd, 2.9.4)
+
+dnl These must be called before AM_PROG_LIBTOOL, because it may want
+dnl to call AC_CHECK_PROG.
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+dnl Default to a non shared library. This may be overridden by the
+dnl configure option --enable-shared.
+AM_DISABLE_SHARED
+
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(64-bit-bfd,
+[ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)],
+[case "${enableval}" in
+ yes) want64=true ;;
+ no) want64=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for 64-bit-bfd option) ;;
+esac],[want64=false])dnl
+AC_ARG_ENABLE(targets,
+[ --enable-targets alternative target configurations],
+[case "${enableval}" in
+ yes | "") AC_ERROR(enable-targets option must specify target names or 'all')
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac])dnl
+AC_ARG_ENABLE(commonbfdlib,
+[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library],
+[case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for BFD commonbfdlib option]) ;;
+esac])dnl
+AC_ARG_WITH(mmap,
+[ --with-mmap try using mmap for BFD input files if available],
+[case "${withval}" in
+ yes) want_mmap=true ;;
+ no) want_mmap=false ;;
+ *) AC_MSG_ERROR(bad value ${withval} for BFD with-mmap option) ;;
+esac],[want_mmap=false])dnl
+
+AM_CONFIG_HEADER(config.h:config.in)
+
+if test -z "$target" ; then
+ AC_MSG_ERROR(Unrecognized target system type; please check config.sub.)
+fi
+AC_ARG_PROGRAM
+
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+host64=false
+target64=false
+
+# host stuff:
+
+AC_PROG_CC
+
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+# Permit host specific settings.
+. ${srcdir}/configure.host
+
+AC_SUBST(HDEFINES)
+AC_PROG_INSTALL
+
+BFD_HOST_64BIT_LONG=0
+BFD_HOST_64_BIT_DEFINED=0
+BFD_HOST_64_BIT=
+BFD_HOST_U_64_BIT=
+if test "x${HOST_64BIT_TYPE}" = "xlong"; then
+ BFD_HOST_64BIT_LONG=1
+elif test "x${HOST_64BIT_TYPE}" != "x"; then
+ BFD_HOST_64_BIT_DEFINED=1
+ BFD_HOST_64_BIT=${HOST_64BIT_TYPE}
+ BFD_HOST_U_64_BIT=${HOST_U_64BIT_TYPE}
+fi
+AC_SUBST(BFD_HOST_64BIT_LONG)
+AC_SUBST(BFD_HOST_64_BIT_DEFINED)
+AC_SUBST(BFD_HOST_64_BIT)
+AC_SUBST(BFD_HOST_U_64_BIT)
+
+BFD_CC_FOR_BUILD
+
+AC_CHECK_HEADERS(stddef.h string.h strings.h stdlib.h time.h unistd.h)
+AC_CHECK_HEADERS(fcntl.h sys/file.h sys/time.h)
+AC_HEADER_TIME
+AC_HEADER_DIRENT
+AC_CHECK_FUNCS(fcntl getpagesize setitimer sysconf fdopen)
+
+BFD_BINARY_FOPEN
+
+BFD_NEED_DECLARATION(strstr)
+BFD_NEED_DECLARATION(malloc)
+BFD_NEED_DECLARATION(realloc)
+BFD_NEED_DECLARATION(free)
+BFD_NEED_DECLARATION(getenv)
+
+# If we are configured native, pick a core file support file.
+COREFILE=
+COREFLAG=
+TRAD_HEADER=
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ alpha*-*-linux-gnu*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/alphalinux.h"'
+ ;;
+ alpha*-*-netbsd*) COREFILE=netbsd-core.lo ;;
+ alpha*-*-*) COREFILE=osf-core.lo ;;
+ arm-*-riscix) COREFILE=trad-core.lo ;;
+ hppa*-*-hpux*) COREFILE=hpux-core.lo ;;
+ hppa*-*-hiux*) COREFILE=hpux-core.lo ;;
+ hppa*-*-mpeix*) COREFILE=hpux-core.lo ;;
+ hppa*-*-bsd*) COREFILE="hpux-core.lo hppabsd-core.lo"
+ COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;;
+changequote(,)dnl
+ i[3456]86-sequent-bsd*)
+changequote([,])dnl
+ COREFILE=trad-core.lo;
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-sequent-sysv4*) ;;
+ i[3456]86-sequent-sysv*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-*-bsd* | i[3456]86-*-freebsd*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386bsd.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-*-netbsd* | i[3456]86-*-openbsd*)
+changequote([,])dnl
+ COREFILE=netbsd-core.lo
+ ;;
+changequote(,)dnl
+ i[3456]86-esix-sysv3*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/esix.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-*-sco3.2v5*)
+changequote([,])dnl
+ COREFILE=sco5-core.lo
+ ;;
+changequote(,)dnl
+ i[3456]86-*-sco* | i[3456]86-*-isc*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386sco.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-*-mach3*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386mach3.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-*-linux-gnu*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386linux.h"'
+ ;;
+changequote(,)dnl
+ i[3456]86-*-isc*) COREFILE=trad-core.lo ;;
+ i[3456]86-*-aix*) COREFILE=aix386-core.lo ;;
+changequote([,])dnl
+ i860-*-mach3* | i860-*-osf1*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i860mach3.h"'
+ ;;
+ mips-dec-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/mipsbsd.h"'
+ ;;
+ mips-dec-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/mipsmach3.h"'
+ ;;
+ mips-*-netbsd* | mips*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ mips-dec-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/decstation.h"'
+ ;;
+ mips-sgi-irix4*) COREFILE=irix-core.lo ;;
+ mips-sgi-irix5*) COREFILE=irix-core.lo ;;
+ mips-sgi-irix6*) COREFILE=irix-core.lo ;;
+ mips-*-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/mipsmach3.h"'
+ ;;
+ mips-*-sysv4*) ;;
+ mips-*-sysv* | mips-*-riscos*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/riscos.h"'
+ ;;
+ mips-sony-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/news-mips.h"'
+ ;;
+ m68*-bull*-sysv*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/dpx2.h"'
+ ;;
+ m68*-hp-hpux*) COREFILE=hpux-core.lo ;;
+ m68*-hp-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/hp300bsd.h"'
+ ;;
+ m68*-*-linux-gnu*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/m68klinux.h"'
+ ;;
+ m68*-motorola-sysv*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/delta68.h"'
+ ;;
+ m68*-sony-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/news.h"'
+ ;;
+ m68*-*-netbsd* | m68*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ m68*-apple-aux*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/m68kaux.h"'
+ ;;
+ m88*-*-sysv4*) ;;
+ m88*-motorola-sysv*) COREFILE=ptrace-core.lo ;;
+ m88*-*-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/m88kmach3.h"'
+ ;;
+ ns32k-pc532-mach)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/pc532mach.h"'
+ ;;
+ ns32k-*-netbsd* | ns32k-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ rs6000-*-lynx*) COREFILE=lynx-core.lo ;;
+ rs6000-*-aix4*) COREFILE=rs6000-core.lo ;;
+ rs6000-*-*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-*bsd*) COREFILE=netbsd-core.lo ;;
+ powerpc-*-aix4*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-aix*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-beos*) ;;
+ powerpc-*-netbsd*) COREFILE=netbsd-core.lo ;;
+ sparc-*-netbsd* | sparc-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ tahoe-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/tahoe.h"'
+ ;;
+ vax-*-ultrix2*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-ultrix*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxbsd.h"'
+ ;;
+ esac
+
+ case "$COREFILE" in
+ aix386-core.lo) COREFLAG=-DAIX386_CORE ;;
+ hppabsd-core.lo) COREFLAG=-DHPPABSD_CORE ;;
+ hpux-core.lo) COREFLAG=-DHPUX_CORE ;;
+ irix-core.lo) COREFLAG=-DIRIX_CORE ;;
+ lynx-core.lo) COREFLAG=-DLYNX_CORE ;;
+ netbsd-core.lo) COREFLAG=-DNETBSD_CORE ;;
+ osf-core.lo) COREFLAG=-DOSF_CORE ;;
+ ptrace-core.lo) COREFLAG=-DPTRACE_CORE ;;
+ rs6000-core.lo) COREFLAG="$COREFLAG -DAIX_CORE" ;;
+ sco5-core.lo) COREFLAG="$COREFLAG -DSCO5_CORE" ;;
+ trad-core.lo) COREFLAG="$COREFLAG -DTRAD_CORE" ;;
+ esac
+
+ # ELF corefile support has several flavors, but all of
+ # them use something called <sys/procfs.h>
+ AC_CHECK_HEADERS(sys/procfs.h)
+ if test "$ac_cv_header_sys_procfs_h" = yes; then
+ BFD_HAVE_SYS_PROCFS_TYPE(prstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(prstatus_t, pr_who)
+ BFD_HAVE_SYS_PROCFS_TYPE(pstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prpsinfo_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(psinfo_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(lwpstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(lwpstatus_t, pr_context)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(lwpstatus_t, pr_reg)
+ fi
+fi
+AC_SUBST(COREFILE)
+AC_SUBST(COREFLAG)
+AC_DEFINE_UNQUOTED(TRAD_HEADER, $TRAD_HEADER,
+ [Name of host specific header file to include in trad-core.c.])
+
+# Horrible hacks to build DLLs on Windows.
+WIN32LDFLAGS=
+WIN32LIBADD=
+case "${host}" in
+*-*-cygwin*)
+ if test "$enable_shared" = "yes"; then
+ WIN32LDFLAGS="-no-undefined"
+ WIN32LIBADD="-L`pwd`/../libiberty -liberty -L`pwd`/../intl -lintl -lcygwin -lkernel32"
+ fi
+ ;;
+esac
+AC_SUBST(WIN32LDFLAGS)
+AC_SUBST(WIN32LIBADD)
+
+# target stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets" ; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+ else
+ # Allow targets that config.sub doesn't recognize, like "all".
+ canon_targets="$canon_targets $targ"
+ fi
+ done
+fi
+
+all_targets=false
+defvec=
+selvecs=
+selarchs=
+TDEFINES=
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall"; then
+ all_targets=true
+ else
+ . $srcdir/config.bfd
+ if test "x$targ" = "x$target"; then
+ defvec=$targ_defvec
+ fi
+ selvecs="$selvecs $targ_defvec $targ_selvecs"
+ selarchs="$selarchs $targ_archs"
+ TDEFINES="$TDEFINES $targ_cflags"
+ fi
+done
+AC_SUBST(TDEFINES)
+
+# This processing still needs to be done if we're to decide properly whether
+# 64-bit support needs to be compiled in. Currently, it will be included if
+# the default or any other explicitly requested target requires it; it
+# will not be included on a 32-bit host if no 64-bit target is requested, and
+# no "--with-64-bit-bfd" option is given, even if "--with-targets=all" is
+# used.
+
+# uniq the default and selected vectors in all the configured targets.
+f=""
+for i in $selvecs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+selvecs="$f"
+
+
+# uniq the architectures in all the configured targets.
+f=""
+for i in $selarchs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+selarchs="$f"
+
+# Target backend .o files.
+tb=
+
+elf="elf.lo elflink.lo dwarf2.lo dwarf1.lo"
+
+for vec in $selvecs
+do
+ case "$vec" in
+ # This list is alphabetized to make it easy to compare
+ # with the two vector lists in targets.c.
+ a29kcoff_big_vec) tb="$tb coff-a29k.lo cofflink.lo" ;;
+ a_out_adobe_vec) tb="$tb aout-adobe.lo aout32.lo" ;;
+ armcoff_little_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ armcoff_big_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ armpe_little_vec) tb="$tb pe-arm.lo coff-arm.lo cofflink.lo " ;;
+ armpe_big_vec) tb="$tb pe-arm.lo coff-arm.lo cofflink.lo " ;;
+ armpei_little_vec) tb="$tb pei-arm.lo cofflink.lo " ;;
+ armpei_big_vec) tb="$tb pei-arm.lo cofflink.lo " ;;
+ arm_epoc_pe_little_vec) tb="$tb epoc-pe-arm.lo cofflink.lo " ;;
+ arm_epoc_pe_big_vec) tb="$tb epoc-pe-arm.lo cofflink.lo " ;;
+ arm_epoc_pei_little_vec) tb="$tb epoc-pei-arm.lo cofflink.lo " ;;
+ arm_epoc_pei_big_vec) tb="$tb epoc-pei-arm.lo cofflink.lo " ;;
+ aout0_big_vec) tb="$tb aout0.lo aout32.lo" ;;
+ aout_arm_big_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ aout_arm_little_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ aout_mips_big_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
+ aout_mips_little_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
+ apollocoff_vec) tb="$tb coff-apollo.lo" ;;
+ b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;;
+ b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;;
+ bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"
+ target64=true ;;
+ bfd_elf32_littlearc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ bfd_elf32_littlearm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;;
+ bfd_elf32_littlearm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;
+ bfd_elf32_bigarc_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ bfd_elf32_bigarm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;;
+ bfd_elf32_bigarm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;
+ bfd_elf32_big_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ bfd_elf32_bigmips_vec) tb="$tb elf32-mips.lo elf32.lo $elf ecofflink.lo" ;;
+ bfd_elf64_bigmips_vec) tb="$tb elf64-mips.lo elf64.lo elf32-mips.lo elf32.lo $elf ecofflink.lo"
+ target64=true ;;
+ bfd_elf32_d10v_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;;
+ bfd_elf32_d30v_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;;
+ bfd_elf32_fr30_vec) tb="$tb elf32-fr30.lo elf32.lo $elf" ;;
+ bfd_elf32_hppa_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ bfd_elf32_i386_vec) tb="$tb elf32-i386.lo elf32.lo $elf" ;;
+ bfd_elf32_i860_vec) tb="$tb elf32-i860.lo elf32.lo $elf" ;;
+ bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ bfd_elf32_littlemips_vec) tb="$tb elf32-mips.lo elf32.lo $elf ecofflink.lo" ;;
+ bfd_elf64_littlemips_vec) tb="$tb elf64-mips.lo elf64.lo elf32-mips.lo elf32.lo $elf ecofflink.lo"
+ target64=true ;;
+ bfd_elf32_m32r_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ bfd_elf32_m68k_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
+ bfd_elf32_m88k_vec) tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
+ bfd_elf32_mcore_big_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ bfd_elf32_mcore_little_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ bfd_elf32_mn10200_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;;
+ bfd_elf32_mn10300_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
+ bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf32.lo $elf" ;;
+ bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.lo elf32.lo $elf" ;;
+ bfd_elf32_sh_vec) tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo" ;;
+ bfd_elf32_shl_vec) tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo" ;;
+ bfd_elf32_sparc_vec) tb="$tb elf32-sparc.lo elf32.lo $elf" ;;
+ bfd_elf32_v850_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
+ bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"
+ target64=true ;;
+ bfd_elf64_little_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"
+ target64=true ;;
+ bfd_elf64_sparc_vec) tb="$tb elf64-sparc.lo elf64.lo $elf"
+ target64=true ;;
+ cisco_core_vec) tb="$tb cisco-core.lo" ;;
+ demo_64_vec) tb="$tb demo64.lo aout64.lo"
+ target64=true ;;
+ ecoff_big_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ ecoff_little_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ ecoff_biglittle_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ ecoffalpha_little_vec) tb="$tb coff-alpha.lo ecoff.lo ecofflink.lo"
+ target64=true ;;
+ go32coff_vec) tb="$tb coff-go32.lo cofflink.lo" ;;
+ go32stubbedcoff_vec) tb="$tb coff-stgo32.lo cofflink.lo" ;;
+ h8300coff_vec) tb="$tb coff-h8300.lo reloc16.lo" ;;
+ h8500coff_vec) tb="$tb coff-h8500.lo reloc16.lo" ;;
+ host_aout_vec) tb="$tb host-aout.lo aout32.lo" ;;
+ hp300bsd_vec) tb="$tb hp300bsd.lo aout32.lo" ;;
+ hp300hpux_vec) tb="$tb hp300hpux.lo aout32.lo" ;;
+ i386aout_vec) tb="$tb i386aout.lo aout32.lo" ;;
+ i386bsd_vec) tb="$tb i386bsd.lo aout32.lo" ;;
+ i386coff_vec) tb="$tb coff-i386.lo cofflink.lo" ;;
+ i386dynix_vec) tb="$tb i386dynix.lo aout32.lo" ;;
+ i386freebsd_vec) tb="$tb i386freebsd.lo aout32.lo" ;;
+ i386msdos_vec) tb="$tb i386msdos.lo" ;;
+ i386pe_vec) tb="$tb pe-i386.lo cofflink.lo " ;;
+ i386pei_vec) tb="$tb pei-i386.lo cofflink.lo" ;;
+ i386linux_vec) tb="$tb i386linux.lo aout32.lo" ;;
+ i386lynx_aout_vec) tb="$tb i386lynx.lo lynx-core.lo aout32.lo" ;;
+ i386lynx_coff_vec) tb="$tb cf-i386lynx.lo cofflink.lo lynx-core.lo" ;;
+ i386mach3_vec) tb="$tb i386mach3.lo aout32.lo" ;;
+ i386netbsd_vec) tb="$tb i386netbsd.lo aout32.lo" ;;
+ i386os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
+ i860coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
+ icoff_big_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ icoff_little_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ ieee_vec) tb="$tb ieee.lo" ;;
+ m68kcoff_vec) tb="$tb coff-m68k.lo cofflink.lo" ;;
+ m68kcoffun_vec) tb="$tb coff-u68k.lo coff-m68k.lo cofflink.lo" ;;
+ m68klinux_vec) tb="$tb m68klinux.lo aout32.lo" ;;
+ m68klynx_aout_vec) tb="$tb m68klynx.lo lynx-core.lo aout32.lo" ;;
+ m68klynx_coff_vec) tb="$tb cf-m68klynx.lo coff-m68k.lo cofflink.lo lynx-core.lo" ;;
+ m68knetbsd_vec) tb="$tb m68knetbsd.lo aout32.lo" ;;
+ m68k4knetbsd_vec) tb="$tb m68k4knetbsd.lo aout32.lo" ;;
+ m68kaux_coff_vec) tb="$tb coff-aux.lo coff-m68k.lo cofflink.lo" ;;
+ m68ksysvcoff_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;;
+ m88kbcs_vec) tb="$tb coff-m88k.lo" ;;
+ mcore_pe_big_vec) tb="$tb pe-mcore.lo cofflink.lo" ;;
+ mcore_pe_little_vec) tb="$tb pe-mcore.lo cofflink.lo" ;;
+ mcore_pei_big_vec) tb="$tb pei-mcore.lo cofflink.lo" ;;
+ mcore_pei_little_vec) tb="$tb pei-mcore.lo cofflink.lo" ;;
+ newsos3_vec) tb="$tb newsos3.lo aout32.lo" ;;
+ nlm32_i386_vec) tb="$tb nlm32-i386.lo nlm32.lo nlm.lo" ;;
+ nlm32_sparc_vec) tb="$tb nlm32-sparc.lo nlm32.lo nlm.lo" ;;
+ nlm32_alpha_vec) tb="$tb nlm32-alpha.lo nlm32.lo nlm.lo"
+ target64=true ;;
+ riscix_vec) tb="$tb aout32.lo riscix.lo" ;;
+ nlm32_powerpc_vec) tb="$tb nlm32-ppc.lo nlm32.lo nlm.lo" ;;
+ pc532netbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
+ pc532machaout_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
+ pmac_xcoff_vec) tb="$tb coff-pmac.lo xcofflink.lo" ;;
+ rs6000coff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
+ bfd_powerpc_pe_vec) tb="$tb pe-ppc.lo cofflink.lo" ;;
+ bfd_powerpcle_pe_vec) tb="$tb pe-ppc.lo cofflink.lo" ;;
+ bfd_powerpc_pei_vec) tb="$tb pei-ppc.lo cofflink.lo" ;;
+ bfd_powerpcle_pei_vec) tb="$tb pei-ppc.lo cofflink.lo" ;;
+ ppcboot_vec) tb="$tb ppcboot.lo" ;;
+ shcoff_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ shlcoff_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ shcoff_small_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ shlcoff_small_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ som_vec) tb="$tb som.lo" ;;
+ sparcle_aout_vec) tb="$tb aout-sparcle.lo aout32.lo" ;;
+ sparclinux_vec) tb="$tb sparclinux.lo aout32.lo" ;;
+ sparclynx_aout_vec) tb="$tb sparclynx.lo lynx-core.lo aout32.lo" ;;
+ sparclynx_coff_vec) tb="$tb cf-sparclynx.lo lynx-core.lo" ;;
+ sparcnetbsd_vec) tb="$tb sparcnetbsd.lo aout32.lo" ;;
+ sparccoff_vec) tb="$tb coff-sparc.lo" ;;
+ srec_vec) tb="$tb srec.lo" ;;
+ sunos_big_vec) tb="$tb sunos.lo aout32.lo" ;;
+ symbolsrec_vec) tb="$tb srec.lo" ;;
+ tekhex_vec) tb="$tb tekhex.lo" ;;
+ tic30_aout_vec) tb="$tb aout-tic30.lo" ;;
+ tic30_coff_vec) tb="$tb coff-tic30.lo" ;;
+ tic80coff_vec) tb="$tb coff-tic80.lo cofflink.lo" ;;
+ versados_vec) tb="$tb versados.lo" ;;
+ vms_alpha_vec) tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo"
+ target64=true ;;
+ vms_vax_vec) tb="$tb vms.lo vms-hdr.lo vms-gsd.lo vms-tir.lo vms-misc.lo" ;;
+ w65_vec) tb="$tb coff-w65.lo reloc16.lo" ;;
+ we32kcoff_vec) tb="$tb coff-we32k.lo" ;;
+ z8kcoff_vec) tb="$tb coff-z8k.lo reloc16.lo" ;;
+
+ "") ;;
+ *) AC_MSG_ERROR(*** unknown target vector $vec) ;;
+ esac
+done
+
+# Target architecture .o files.
+# A couple of CPUs use shorter file names to avoid problems on DOS
+# filesystems.
+ta=`echo $selarchs | sed -e s/bfd_/cpu-/g -e s/_arch/.lo/g -e s/mn10200/m10200/ -e s/mn10300/m10300/`
+
+# Weed out duplicate .o files.
+f=""
+for i in $tb ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+tb="$f"
+
+f=""
+for i in $ta ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+ta="$f"
+
+bfd_backends="$tb"
+bfd_machines="$ta"
+
+if test x${all_targets} = xtrue ; then
+ bfd_backends="${bfd_backends}"' $(ALL_BACKENDS)'
+ bfd_machines="${bfd_machines}"' $(ALL_MACHINES)'
+ selvecs=
+ havevecs=
+ selarchs=
+else # all_targets is true
+ # Only set these if they will be nonempty, for the clever echo.
+ havevecs=
+ test -n "$selvecs" &&
+ havevecs=`echo $selvecs | sed -e 's/^/-DHAVE_/' -e 's/ \(.\)/ -DHAVE_\1/g'`
+ test -n "$selvecs" &&
+ selvecs=`echo $selvecs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'`
+ test -n "$selarchs" &&
+ selarchs=`echo $selarchs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'`
+fi # all_targets is true
+
+case ${host64}-${target64}-${want64} in
+ *true*)
+ wordsize=64
+ all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
+ if test -z "$GCC" && test "$BFD_HOST_64BIT_LONG" = "0" && test "$BFD_HOST_64_BIT_DEFINED" = "0"; then
+ AC_MSG_WARN([You have requested a 64 bit BFD configuration, but])
+ AC_MSG_WARN([your compiler may not have a 64 bit integral type])
+ fi
+ ;;
+ false-false-false)
+ wordsize=32
+ all_backends='$(BFD32_BACKENDS)'
+ ;;
+esac
+
+AC_SUBST(wordsize)
+AC_SUBST(all_backends)
+AC_SUBST(bfd_backends)
+AC_SUBST(bfd_machines)
+
+tdefaults=""
+test -n "${defvec}" && tdefaults="${tdefaults} -DDEFAULT_VECTOR=${defvec}"
+test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'"
+test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'"
+test -n "${havevecs}" && tdefaults="${tdefaults} ${havevecs}"
+AC_SUBST(tdefaults)
+
+dnl AC_CHECK_HEADERS(sys/mman.h)
+AC_FUNC_MMAP
+AC_CHECK_FUNCS(madvise mprotect)
+case ${want_mmap}+${ac_cv_func_mmap_fixed_mapped} in
+ true+yes ) AC_DEFINE(USE_MMAP, 1, [Use mmap if it's available?]) ;;
+esac
+
+rm -f doc/config.status
+AC_OUTPUT(Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in,
+[sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile])
diff --git a/bfd/corefile.c b/bfd/corefile.c
new file mode 100644
index 00000000000..212f519ce8a
--- /dev/null
+++ b/bfd/corefile.c
@@ -0,0 +1,106 @@
+/* Core file generic interface routines for BFD.
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ Core files
+
+DESCRIPTION
+ These are functions pertaining to core files.
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+/*
+FUNCTION
+ bfd_core_file_failing_command
+
+SYNOPSIS
+ CONST char *bfd_core_file_failing_command(bfd *abfd);
+
+DESCRIPTION
+ Return a read-only string explaining which program was running
+ when it failed and produced the core file @var{abfd}.
+
+*/
+
+CONST char *
+bfd_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ if (abfd->format != bfd_core) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+ return BFD_SEND (abfd, _core_file_failing_command, (abfd));
+}
+
+/*
+FUNCTION
+ bfd_core_file_failing_signal
+
+SYNOPSIS
+ int bfd_core_file_failing_signal(bfd *abfd);
+
+DESCRIPTION
+ Returns the signal number which caused the core dump which
+ generated the file the BFD @var{abfd} is attached to.
+*/
+
+int
+bfd_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ if (abfd->format != bfd_core) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
+}
+
+
+/*
+FUNCTION
+ core_file_matches_executable_p
+
+SYNOPSIS
+ boolean core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+
+DESCRIPTION
+ Return <<true>> if the core file attached to @var{core_bfd}
+ was generated by a run of the executable file attached to
+ @var{exec_bfd}, <<false>> otherwise.
+*/
+boolean
+core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ return BFD_SEND (core_bfd, _core_file_matches_executable_p,
+ (core_bfd, exec_bfd));
+}
diff --git a/bfd/cpu-a29k.c b/bfd/cpu-a29k.c
new file mode 100644
index 00000000000..5bd25a47720
--- /dev/null
+++ b/bfd/cpu-a29k.c
@@ -0,0 +1,39 @@
+/* BFD support for the AMD 29000 architecture.
+ Copyright 1992 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_a29k_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_a29k,
+ 0, /* only 1 machine */
+ "a29k",
+ "a29k",
+ 4,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
diff --git a/bfd/cpu-alpha.c b/bfd/cpu-alpha.c
new file mode 100644
index 00000000000..b89900be3b7
--- /dev/null
+++ b/bfd/cpu-alpha.c
@@ -0,0 +1,51 @@
+/* BFD support for the Alpha architecture.
+ Copyright 1992 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \
+ { \
+ BITS_WORD, /* bits in a word */ \
+ BITS_ADDR, /* bits in an address */ \
+ 8, /* 8 bits in a byte */ \
+ bfd_arch_alpha, \
+ NUMBER, \
+ "alpha", \
+ PRINT, \
+ 3, \
+ DEFAULT, \
+ bfd_default_compatible, \
+ bfd_default_scan, \
+ NEXT, \
+ }
+
+#define NN(index) (&arch_info_struct[index])
+
+/* These exist only so that we can resonably disassemble PALcode. */
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (64, 64, bfd_mach_alpha_ev4, "alpha:ev4", false, NN(1)),
+ N (64, 64, bfd_mach_alpha_ev5, "alpha:ev5", false, NN(2)),
+ N (64, 64, bfd_mach_alpha_ev6, "alpha:ev6", false, 0),
+};
+
+const bfd_arch_info_type bfd_alpha_arch =
+ N (64, 64, 0, "alpha", true, NN(0));
diff --git a/bfd/cpu-arc.c b/bfd/cpu-arc.c
new file mode 100644
index 00000000000..bce59d4c99f
--- /dev/null
+++ b/bfd/cpu-arc.c
@@ -0,0 +1,70 @@
+/* BFD support for the ARC processor
+ Copyright 1994, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define ARC(mach, print_name, default_p, next) \
+{ \
+ 32, /* 32 bits in a word */ \
+ 32, /* 32 bits in an address */ \
+ 8, /* 8 bits in a byte */ \
+ bfd_arch_arc, \
+ mach, \
+ "arc", \
+ print_name, \
+ 4, /* section alignment power */ \
+ default_p, \
+ bfd_default_compatible, \
+ bfd_default_scan, \
+ next, \
+ }
+
+#if 0 /* ??? Not currently needed, but keep in for future reference. */
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ ARC (bfd_mach_arc_foo, "arc-foo", false, &arch_info_struct[1]),
+ ARC (bfd_mach_arc_bar, "arc-bar", false, 0),
+};
+#endif
+
+const bfd_arch_info_type bfd_arc_arch =
+ ARC (bfd_mach_arc_base, "arc-base", true, 0 /*&arch_info_struct[0]*/);
+
+/* Utility routines. */
+
+/* Given cpu type NAME, return its bfd_mach_arc_xxx value.
+ Returns -1 if not found. */
+
+int
+arc_get_mach (name)
+ char *name;
+{
+ const bfd_arch_info_type *p;
+
+ for (p = &bfd_arc_arch; p != NULL; p = p->next)
+ {
+ /* +4: skip over "arc-" */
+ if (strcmp (name, p->printable_name + 4) == 0)
+ return p->mach;
+ }
+ return -1;
+}
diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c
new file mode 100644
index 00000000000..d999c0ff247
--- /dev/null
+++ b/bfd/cpu-arm.c
@@ -0,0 +1,134 @@
+/* BFD support for the ARM processor
+ Copyright 1994, 95, 1997 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type *compatible
+ PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
+static boolean scan PARAMS ((const struct bfd_arch_info *, const char *));
+
+/* This routine is provided two arch_infos and works out which ARM
+ machine which would be compatible with both and returns a pointer
+ to its info structure */
+
+static const bfd_arch_info_type *
+compatible (a,b)
+ const bfd_arch_info_type * a;
+ const bfd_arch_info_type * b;
+{
+ /* If a & b are for different architecture we can do nothing */
+ if (a->arch != b->arch)
+ return NULL;
+
+ /* If a & b are for the same machine then all is well */
+ if (a->mach == b->mach)
+ return a;
+
+ /* Otherwise if either a or b is the 'default' machine then
+ it can be polymorphed into the other */
+ if (a->the_default)
+ return b;
+
+ if (b->the_default)
+ return a;
+
+ /* So far all newer ARM architecture cores are supersets of previous cores */
+ if (a->mach < b->mach)
+ return b;
+ else if (a->mach > b->mach)
+ return a;
+
+ /* Never reached! */
+ return NULL;
+}
+
+static struct
+{
+ enum bfd_architecture arch;
+ char * name;
+}
+processors[] =
+{
+ { bfd_mach_arm_2, "arm2" },
+ { bfd_mach_arm_2a, "arm250" },
+ { bfd_mach_arm_2a, "arm3" },
+ { bfd_mach_arm_3, "arm6" },
+ { bfd_mach_arm_3, "arm60" },
+ { bfd_mach_arm_3, "arm600" },
+ { bfd_mach_arm_3, "arm610" },
+ { bfd_mach_arm_3, "arm7" },
+ { bfd_mach_arm_3, "arm710" },
+ { bfd_mach_arm_3, "arm7500" },
+ { bfd_mach_arm_3, "arm7d" },
+ { bfd_mach_arm_3, "arm7di" },
+ { bfd_mach_arm_3M, "arm7dm" },
+ { bfd_mach_arm_3M, "arm7dmi" },
+ { bfd_mach_arm_4, "arm8" },
+ { bfd_mach_arm_4, "arm810" },
+ { bfd_mach_arm_4, "sa1" },
+ { bfd_mach_arm_4T, "arm7tdmi" }
+};
+
+static boolean
+scan (info, string)
+ const struct bfd_arch_info * info;
+ const char * string;
+{
+ int i;
+
+ /* First test for an exact match */
+ if (strcasecmp (string, info->printable_name) == 0)
+ return true;
+
+ /* Next check for a processor name instead of an Architecture name */
+ for (i = sizeof (processors) / sizeof (processors[0]); i--;)
+ {
+ if (strcasecmp (string, processors[ i ].name) == 0)
+ break;
+ }
+
+ if (i != -1 && info->arch == processors[ i ].arch)
+ return true;
+
+ /* Finally check for the default architecture */
+ if (strcasecmp (string, "arm") == 0)
+ return info->the_default;
+
+ return false;
+}
+
+
+#define N(number, print, default, next) \
+{ 32, 32, 8, bfd_arch_arm, number, "arm", print, 4, default, compatible, scan, next }
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N( bfd_mach_arm_2, "armv2", false, & arch_info_struct[1] ),
+ N( bfd_mach_arm_2a, "armv2a", false, & arch_info_struct[2] ),
+ N( bfd_mach_arm_3, "armv3", false, & arch_info_struct[3] ),
+ N( bfd_mach_arm_3M, "armv3m", false, & arch_info_struct[4] ),
+ N( bfd_mach_arm_4, "armv4", false, & arch_info_struct[5] ),
+ N( bfd_mach_arm_4T, "armv4t", false, NULL )
+};
+
+const bfd_arch_info_type bfd_arm_arch =
+ N( 0, "arm", true, & arch_info_struct[0] );
diff --git a/bfd/cpu-d10v.c b/bfd/cpu-d10v.c
new file mode 100644
index 00000000000..a1ff088bdbc
--- /dev/null
+++ b/bfd/cpu-d10v.c
@@ -0,0 +1,40 @@
+/* BFD support for the D10V processor
+ Copyright 1996 Free Software Foundation, Inc.
+ Contributed by Martin Hunt (hunt@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_d10v_arch =
+{
+ 16, /* 16 bits in a word */
+ 16, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_d10v,
+ 0,
+ "d10v",
+ "d10v",
+ 4, /* section alignment power */
+ true,
+ bfd_default_compatible,
+ bfd_default_scan,
+ 0,
+};
+
diff --git a/bfd/cpu-d30v.c b/bfd/cpu-d30v.c
new file mode 100644
index 00000000000..6eadfee271a
--- /dev/null
+++ b/bfd/cpu-d30v.c
@@ -0,0 +1,39 @@
+/* BFD support for the Mitsubishi D30V processor
+ Copyright 1997 Free Software Foundation, Inc.
+ Contributed by Martin Hunt (hunt@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_d30v_arch =
+{
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_d30v,
+ 0,
+ "d30v",
+ "d30v",
+ 4, /* section alignment power */
+ true,
+ bfd_default_compatible,
+ bfd_default_scan,
+ 0,
+};
diff --git a/bfd/cpu-fr30.c b/bfd/cpu-fr30.c
new file mode 100644
index 00000000000..33208f89bbb
--- /dev/null
+++ b/bfd/cpu-fr30.c
@@ -0,0 +1,38 @@
+/* BFD support for the FR30 processor.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_fr30_arch =
+{
+ 32, /* bits per word */
+ 32, /* bits per address */
+ 8, /* bits per byte */
+ bfd_arch_fr30, /* architecture */
+ bfd_mach_fr30, /* machine */
+ "fr30", /* architecture name */
+ "fr30", /* printable name */
+ 4, /* section align power */
+ true, /* the default ? */
+ bfd_default_compatible, /* architecture comparison fn */
+ bfd_default_scan, /* string to architecture convert fn */
+ NULL /* next in list */
+};
diff --git a/bfd/cpu-h8300.c b/bfd/cpu-h8300.c
new file mode 100644
index 00000000000..567b7df9de2
--- /dev/null
+++ b/bfd/cpu-h8300.c
@@ -0,0 +1,134 @@
+/* BFD library support routines for the Hitachi H8/300 architecture.
+ Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+int bfd_default_scan_num_mach ();
+
+static boolean
+h8300_scan (info, string)
+ const struct bfd_arch_info *info;
+ const char *string;
+{
+ if (*string != 'h' && *string != 'H')
+ return false;
+
+ string++;
+ if (*string != '8')
+ return false;
+
+ string++;
+ if (*string == '/')
+ string++;
+
+ if (*string != '3')
+ return false;
+ string++;
+ if (*string != '0')
+ return false;
+ string++;
+ if (*string != '0')
+ return false;
+ string++;
+ if (*string == '-')
+ string++;
+ if (*string == 'h' || *string == 'H')
+ {
+ return (info->mach == bfd_mach_h8300h);
+ }
+ else if (*string == 's' || *string == 'S')
+ {
+ return (info->mach == bfd_mach_h8300s);
+ }
+ else
+ {
+ return info->mach == bfd_mach_h8300;
+ }
+}
+
+
+/* This routine is provided two arch_infos and works out the
+ machine which would be compatible with both and returns a pointer
+ to its info structure */
+
+static const bfd_arch_info_type *
+compatible (in, out)
+ const bfd_arch_info_type * in;
+ const bfd_arch_info_type * out;
+{
+ /* It's really not a good idea to mix and match modes. */
+ if (in->mach != out->mach)
+ return 0;
+ else
+ return in;
+}
+
+static const bfd_arch_info_type h8300_info_struct =
+{
+ 16, /* 16 bits in a word */
+ 16, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_h8300,
+ bfd_mach_h8300,
+ "h8300", /* arch_name */
+ "h8300", /* printable name */
+ 1,
+ true, /* the default machine */
+ compatible,
+ h8300_scan,
+/* local_bfd_reloc_type_lookup, */
+ 0,
+};
+
+static const bfd_arch_info_type h8300h_info_struct =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_h8300,
+ bfd_mach_h8300h,
+ "h8300h", /* arch_name */
+ "h8300h", /* printable name */
+ 1,
+ false, /* the default machine */
+ compatible,
+ h8300_scan,
+/* local_bfd_reloc_type_lookup, */
+ &h8300_info_struct,
+};
+
+const bfd_arch_info_type bfd_h8300_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_h8300,
+ bfd_mach_h8300s,
+ "h8300s", /* arch_name */
+ "h8300s", /* printable name */
+ 1,
+ false, /* the default machine */
+ compatible,
+ h8300_scan,
+/* local_bfd_reloc_type_lookup, */
+ &h8300h_info_struct,
+};
diff --git a/bfd/cpu-h8500.c b/bfd/cpu-h8500.c
new file mode 100644
index 00000000000..e4abfd17807
--- /dev/null
+++ b/bfd/cpu-h8500.c
@@ -0,0 +1,199 @@
+/* BFD library support routines for the H8/500 architecture.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#if 0
+
+/*
+Relocations for the Z8K
+
+*/
+static bfd_reloc_status_type
+howto16_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+ long x = bfd_get_16(abfd, (bfd_byte *)data + addr);
+
+ HOWTO_PREPARE(relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_16(abfd, x, (bfd_byte *)data + addr);
+ return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+howto8_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+ long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
+
+ HOWTO_PREPARE(relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_8(abfd, x, (bfd_byte *)data + addr);
+ return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+
+ long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
+ abort();
+ HOWTO_PREPARE(relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_8(abfd, x, (bfd_byte *)data + addr);
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+ long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
+ abort();
+ HOWTO_PREPARE(relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_8(abfd, x, (bfd_byte *)data + addr);
+ return bfd_reloc_ok;
+}
+
+
+
+static reloc_howto_type howto_16
+ = NEWHOWTO(howto16_callback,"abs16",1,false,false);
+static reloc_howto_type howto_8
+ = NEWHOWTO(howto8_callback,"abs8",0,false,false);
+
+static reloc_howto_type howto_8_FFnn
+ = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,false,false);
+
+static reloc_howto_type howto_8_pcrel
+ = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,false,true);
+
+
+static reloc_howto_type *
+local_bfd_reloc_type_lookup (arch, code)
+ const struct bfd_arch_info *arch;
+ bfd_reloc_code_real_type code;
+{
+ switch (code) {
+ case BFD_RELOC_16:
+ return &howto_16;
+ case BFD_RELOC_8_FFnn:
+ return &howto_8_FFnn;
+ case BFD_RELOC_8:
+ return &howto_8;
+ case BFD_RELOC_8_PCREL:
+ return &howto_8_pcrel;
+ }
+ return (reloc_howto_type *)NULL;
+}
+#endif
+
+int bfd_default_scan_num_mach();
+
+static boolean
+scan_mach (info, string)
+ const struct bfd_arch_info *info;
+ const char *string;
+{
+ if (strcmp(string,"h8/500") == 0) return true;
+ if (strcmp(string,"H8/500") == 0) return true;
+ if (strcmp(string,"h8500") == 0) return true;
+ if (strcmp(string,"H8500") == 0) return true;
+ return false;
+}
+
+
+#if 0 /* not used currently */
+/* This routine is provided two arch_infos and returns whether
+ they'd be compatible */
+
+static const bfd_arch_info_type *
+compatible (a,b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ if (a->arch != b->arch || a->mach != b->mach)
+ return NULL;
+ return a;
+}
+#endif
+
+const bfd_arch_info_type bfd_h8500_arch =
+{
+ 16, /* 16 bits in a word */
+ 24, /* 24 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_h8500,
+ 0, /* only 1 machine */
+ "h8500", /* arch_name */
+ "h8500", /* printable name */
+ 1,
+ true, /* the default machine */
+ bfd_default_compatible,
+ scan_mach,
+ 0,
+};
diff --git a/bfd/cpu-hppa.c b/bfd/cpu-hppa.c
new file mode 100644
index 00000000000..5d26a92ad99
--- /dev/null
+++ b/bfd/cpu-hppa.c
@@ -0,0 +1,71 @@
+/* BFD support for the HP Precision Architecture architecture.
+ Copyright 1992 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type bfd_hppa10_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_hppa,
+ 10, /* By convention PA1.0 = 10 */
+ "hppa",
+ "hppa1.0",
+ 3,
+ true, /* Unless we use 1.1 specific features */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+};
+
+/* PA2.0 in narrow mode */
+static const bfd_arch_info_type bfd_hppa20_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_hppa,
+ 20, /* By convention PA1.0 = 10 */
+ "hppa",
+ "hppa2.0",
+ 3,
+ false, /* Unless we use 1.1 specific features */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ &bfd_hppa10_arch,
+};
+
+const bfd_arch_info_type bfd_hppa_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_hppa,
+ 11, /* By convention PA1.1 = 11 */
+ "hppa",
+ "hppa1.1",
+ 3,
+ false, /* 1.1 specific features used */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ &bfd_hppa20_arch,
+};
diff --git a/bfd/cpu-i386.c b/bfd/cpu-i386.c
new file mode 100644
index 00000000000..f5b9b181d18
--- /dev/null
+++ b/bfd/cpu-i386.c
@@ -0,0 +1,70 @@
+/* BFD support for the Intel 386 architecture.
+ Copyright 1992, 94, 95, 1996 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_i386_arch_intel_syntax =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_i386_i386_intel_syntax,
+ "i386:intel",
+ "i386:intel",
+ 3,
+ true,
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+};
+static const bfd_arch_info_type i8086_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address (well, not really) */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_i386_i8086,
+ "i8086",
+ "i8086",
+ 3,
+ false,
+ bfd_default_compatible,
+ bfd_default_scan ,
+ &bfd_i386_arch_intel_syntax,
+};
+
+const bfd_arch_info_type bfd_i386_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_i386_i386,
+ "i386",
+ "i386",
+ 3,
+ true,
+ bfd_default_compatible,
+ bfd_default_scan ,
+ &i8086_arch,
+};
+
diff --git a/bfd/cpu-i860.c b/bfd/cpu-i860.c
new file mode 100644
index 00000000000..57c867cdb2c
--- /dev/null
+++ b/bfd/cpu-i860.c
@@ -0,0 +1,40 @@
+/* BFD support for the Intel 860 architecture.
+ Copyright 1992, 1995 Free Software Foundation, Inc.
+ Created mostly by substituting "860" for "386" in cpu-i386.c
+ Harry Dolan <dolan@ssd.intel.com>, October 1995
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_i860_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i860,
+ 0, /* only 1 machine */
+ "i860",
+ "i860",
+ 3,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
diff --git a/bfd/cpu-i960.c b/bfd/cpu-i960.c
new file mode 100644
index 00000000000..7fb2c7ebc5c
--- /dev/null
+++ b/bfd/cpu-i960.c
@@ -0,0 +1,166 @@
+/* BFD library support routines for the i960 architecture.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+/* This routine is provided a string, and tries to work out if it
+ could possibly refer to the i960 machine pointed at in the
+ info_struct pointer */
+
+static boolean
+scan_960_mach (ap, string)
+ const bfd_arch_info_type *ap;
+ const char *string;
+{
+ unsigned long machine;
+
+ /* Look for the string i960, or somesuch at the front of the string */
+
+ if (strncmp("i960",string,4) == 0) {
+ string+=4;
+ }
+ else {
+ /* no match, can be us */
+ return false;
+ }
+ if (string[0] == 0) {
+ /* i960 on it's own means core to us*/
+ if (ap->mach == bfd_mach_i960_core) return true;
+ return false;
+ }
+
+ if (string[0] != ':') {
+ return false;
+ }
+ string++;
+ if (string[0] == '\0')
+ return false;
+ if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' &&
+ string[3] == 'e' && string[4] == '\0')
+ machine = bfd_mach_i960_core;
+ else if (strcmp (string, "ka_sa") == 0)
+ machine = bfd_mach_i960_ka_sa;
+ else if (strcmp (string, "kb_sb") == 0)
+ machine = bfd_mach_i960_kb_sb;
+ else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */
+ return false;
+ else if (string[0] == 'k' && string[1] == 'b')
+ machine = bfd_mach_i960_kb_sb;
+ else if (string[0] == 's' && string[1] == 'b')
+ machine = bfd_mach_i960_kb_sb;
+ else if (string[0] == 'm' && string[1] == 'c')
+ machine = bfd_mach_i960_mc;
+ else if (string[0] == 'x' && string[1] == 'a')
+ machine = bfd_mach_i960_xa;
+ else if (string[0] == 'c' && string[1] == 'a')
+ machine = bfd_mach_i960_ca;
+ else if (string[0] == 'k' && string[1] == 'a')
+ machine = bfd_mach_i960_ka_sa;
+ else if (string[0] == 's' && string[1] == 'a')
+ machine = bfd_mach_i960_ka_sa;
+ else if (string[0] == 'j' && string[1] == 'x')
+ machine = bfd_mach_i960_jx;
+ else if (string[0] == 'h' && string[1] == 'x')
+ machine = bfd_mach_i960_hx;
+ else
+ return false;
+ if (machine == ap->mach) return true;
+ return false;
+}
+
+
+
+/* This routine is provided two arch_infos and works out the i960
+ machine which would be compatible with both and returns a pointer
+ to its info structure */
+
+static const bfd_arch_info_type *
+compatible (a,b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+
+ /* The i960 has distinct subspecies which may not interbreed:
+ CORE CA
+ CORE KA KB MC XA
+ CORE HX JX
+ Any architecture on the same line is compatible, the one on
+ the right is the least restrictive.
+
+ We represent this information in an array, each machine to a side */
+
+#define ERROR 0
+#define CORE bfd_mach_i960_core /*1*/
+#define KA bfd_mach_i960_ka_sa /*2*/
+#define KB bfd_mach_i960_kb_sb /*3*/
+#define MC bfd_mach_i960_mc /*4*/
+#define XA bfd_mach_i960_xa /*5*/
+#define CA bfd_mach_i960_ca /*6*/
+#define JX bfd_mach_i960_jx /*7*/
+#define HX bfd_mach_i960_hx /*8*/
+#define MAX_ARCH ((int)HX)
+
+ static CONST unsigned long matrix[MAX_ARCH+1][MAX_ARCH+1] =
+ {
+ { ERROR, CORE, KA, KB, MC, XA, CA, JX, HX },
+ { CORE, CORE, KA, KB, MC, XA, CA, JX, HX },
+ { KA, KA, KA, KB, MC, XA, ERROR, ERROR, ERROR},
+ { KB, KB, KB, KB, MC, XA, ERROR, ERROR, ERROR},
+ { MC, MC, MC, MC, MC, XA, ERROR, ERROR, ERROR},
+ { XA, XA, XA, XA, XA, XA, ERROR, ERROR, ERROR},
+ { CA, CA, ERROR, ERROR, ERROR, ERROR, CA, ERROR, ERROR},
+ { JX, JX, ERROR, ERROR, ERROR, ERROR, ERROR, JX, HX },
+ { HX, HX, ERROR, ERROR, ERROR, ERROR, ERROR, HX, HX },
+ };
+
+
+ if (a->arch != b->arch || matrix[a->mach][b->mach] == ERROR)
+ {
+ return NULL;
+ }
+ else
+ {
+ return (a->mach == matrix[a->mach][b->mach]) ? a : b;
+ }
+}
+
+
+
+int bfd_default_scan_num_mach();
+#define N(a,b,d,n) \
+{ 32, 32, 8,bfd_arch_i960,a,"i960",b,3,d,compatible,scan_960_mach,n,}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N(bfd_mach_i960_ka_sa,"i960:ka_sa",false, &arch_info_struct[1]),
+ N(bfd_mach_i960_kb_sb,"i960:kb_sb",false, &arch_info_struct[2]),
+ N(bfd_mach_i960_mc, "i960:mc", false, &arch_info_struct[3]),
+ N(bfd_mach_i960_xa, "i960:xa", false, &arch_info_struct[4]),
+ N(bfd_mach_i960_ca, "i960:ca", false, &arch_info_struct[5]),
+ N(bfd_mach_i960_jx, "i960:jx", false, &arch_info_struct[6]),
+ N(bfd_mach_i960_hx, "i960:hx", false, 0),
+};
+
+const bfd_arch_info_type bfd_i960_arch =
+ N(bfd_mach_i960_core, "i960:core", true, &arch_info_struct[0]);
diff --git a/bfd/cpu-m10200.c b/bfd/cpu-m10200.c
new file mode 100644
index 00000000000..3f8a678beec
--- /dev/null
+++ b/bfd/cpu-m10200.c
@@ -0,0 +1,38 @@
+/* BFD support for the Matsushita 10200 processor
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_mn10200_arch =
+ {
+ 16, /* 16 bits in a word */
+ 24, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_mn10200,
+ 200,
+ "mn10200",
+ "mn10200",
+ 2,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
diff --git a/bfd/cpu-m10300.c b/bfd/cpu-m10300.c
new file mode 100644
index 00000000000..5aa0bfe9c88
--- /dev/null
+++ b/bfd/cpu-m10300.c
@@ -0,0 +1,41 @@
+/* BFD support for the Matsushita 10300 processor
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define NEXT NULL
+
+const bfd_arch_info_type bfd_mn10300_arch =
+ {
+ 32, /* 16 bits in a word */
+ 32, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_mn10300,
+ 300,
+ "mn10300",
+ "mn10300",
+ 2,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ NEXT,
+ };
+
diff --git a/bfd/cpu-m32r.c b/bfd/cpu-m32r.c
new file mode 100644
index 00000000000..bd3cc31963d
--- /dev/null
+++ b/bfd/cpu-m32r.c
@@ -0,0 +1,32 @@
+/* BFD support for the M32R processor.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define N(number, print, default, next) \
+{ 32, 32, 8, bfd_arch_m32r, number, "m32r", print, 4, default, \
+ bfd_default_compatible, bfd_default_scan, next }
+
+#define NEXT NULL
+
+
+const bfd_arch_info_type bfd_m32r_arch =
+ N (bfd_mach_m32r, "m32r", true, NEXT);
diff --git a/bfd/cpu-m68k.c b/bfd/cpu-m68k.c
new file mode 100644
index 00000000000..184182d695e
--- /dev/null
+++ b/bfd/cpu-m68k.c
@@ -0,0 +1,42 @@
+/* BFD library support routines for architectures.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 97, 1998
+ Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define N(name, print,d,next) \
+{ 32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_default_compatible,bfd_default_scan, next, }
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N(bfd_mach_m68000, "m68k:68000", false, &arch_info_struct[1]),
+ N(bfd_mach_m68008, "m68k:68008", false, &arch_info_struct[2]),
+ N(bfd_mach_m68010, "m68k:68010", false, &arch_info_struct[3]),
+ N(bfd_mach_m68020, "m68k:68020", false, &arch_info_struct[4]),
+ N(bfd_mach_m68030, "m68k:68030", false, &arch_info_struct[5]),
+ N(bfd_mach_m68040, "m68k:68040", false, &arch_info_struct[6]),
+ N(bfd_mach_cpu32, "m68k:cpu32", false, &arch_info_struct[7]),
+ N(bfd_mach_m68060, "m68k:68060", false, 0),
+};
+
+const bfd_arch_info_type bfd_m68k_arch =
+ N(0, "m68k", true, &arch_info_struct[0]);
diff --git a/bfd/cpu-m88k.c b/bfd/cpu-m88k.c
new file mode 100644
index 00000000000..c3716c5a394
--- /dev/null
+++ b/bfd/cpu-m88k.c
@@ -0,0 +1,42 @@
+/* bfd back-end for m88k support
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+
+
+const bfd_arch_info_type bfd_m88k_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_m88k,
+ 88100, /* only 1 machine */
+ "m88k",
+ "m88k:88100",
+ 3,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
diff --git a/bfd/cpu-mcore.c b/bfd/cpu-mcore.c
new file mode 100644
index 00000000000..7dbfe1b5dac
--- /dev/null
+++ b/bfd/cpu-mcore.c
@@ -0,0 +1,38 @@
+/* BFD library support routines for Motorolla's MCore architecture
+ Copyright (C) 1993, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_mcore_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_mcore, /* Architecture */
+ 0, /* Machine number - 0 for now */
+ "MCore", /* Architecture name */
+ "MCore", /* Printable name */
+ 3, /* Section align power */
+ true, /* Is this the default architecture ? */
+ bfd_default_compatible, /* Architecture comparison function */
+ bfd_default_scan, /* String to architecture conversion */
+ NULL /* Next in list */
+};
diff --git a/bfd/cpu-mips.c b/bfd/cpu-mips.c
new file mode 100644
index 00000000000..a933b8cd10b
--- /dev/null
+++ b/bfd/cpu-mips.c
@@ -0,0 +1,88 @@
+/* bfd back-end for mips support
+ Copyright (C) 1990, 91-97, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \
+ { \
+ BITS_WORD, /* bits in a word */ \
+ BITS_ADDR, /* bits in an address */ \
+ 8, /* 8 bits in a byte */ \
+ bfd_arch_mips, \
+ NUMBER, \
+ "mips", \
+ PRINT, \
+ 3, \
+ DEFAULT, \
+ bfd_default_compatible, \
+ bfd_default_scan, \
+ NEXT, \
+ }
+
+enum {
+I_mips3000,
+I_mips3900,
+I_mips4000,
+I_mips4010,
+I_mips4100,
+I_mips4111,
+I_mips4300,
+I_mips4400,
+I_mips4600,
+I_mips4650,
+I_mips5000,
+I_mips6000,
+I_mips8000,
+I_mips10000,
+I_mips16
+};
+
+
+#define NN(index) (&arch_info_struct[(index)+1])
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (32, 32, bfd_mach_mips3000, "mips:3000", false, NN(I_mips3000)),
+ N (32, 32, bfd_mach_mips3900, "mips:3900", false, NN(I_mips3900)),
+ N (64, 64, bfd_mach_mips4000, "mips:4000", false, NN(I_mips4000)),
+ N (64, 64, bfd_mach_mips4010, "mips:4010", false, NN(I_mips4010)),
+ N (64, 64, bfd_mach_mips4100, "mips:4100", false, NN(I_mips4100)),
+ N (64, 64, bfd_mach_mips4111, "mips:4111", false, NN(I_mips4111)),
+ N (64, 64, bfd_mach_mips4300, "mips:4300", false, NN(I_mips4300)),
+ N (64, 64, bfd_mach_mips4400, "mips:4400", false, NN(I_mips4400)),
+ N (64, 64, bfd_mach_mips4600, "mips:4600", false, NN(I_mips4600)),
+ N (64, 64, bfd_mach_mips4650, "mips:4650", false, NN(I_mips4650)),
+ N (64, 64, bfd_mach_mips5000, "mips:5000", false, NN(I_mips5000)),
+ N (32, 32, bfd_mach_mips6000, "mips:6000", false, NN(I_mips6000)),
+ N (64, 64, bfd_mach_mips8000, "mips:8000", false, NN(I_mips8000)),
+ N (64, 64, bfd_mach_mips10000, "mips:10000", false, NN(I_mips10000)),
+
+
+ N (64, 64, bfd_mach_mips16, "mips:16", false, 0),
+};
+
+/* The default architecture is mips:3000, but with a machine number of
+ zero. This lets the linker distinguish between a default setting
+ of mips, and an explicit setting of mips:3000. */
+
+const bfd_arch_info_type bfd_mips_arch =
+N (32, 32, 0, "mips", true, &arch_info_struct[0]);
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c
new file mode 100644
index 00000000000..1b0a18d5c52
--- /dev/null
+++ b/bfd/cpu-ns32k.c
@@ -0,0 +1,846 @@
+/* BFD support for the ns32k architecture.
+ Copyright (C) 1990, 91, 94, 95, 96, 1998 Free Software Foundation, Inc.
+ Almost totally rewritten by Ian Dall from initial work
+ by Andrew Cagney.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "ns32k.h"
+
+#define N(machine, printable, d, next) \
+{ 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
+};
+
+const bfd_arch_info_type bfd_ns32k_arch =
+ N(32032,"ns32k:32032",false, &arch_info_struct[0]);
+
+static long
+ns32k_sign_extend(value, bits)
+ int value;
+ int bits;
+{
+ value = value & ((1 << bits) - 1);
+ return (value & (1 << (bits-1))
+ ? value | (~((1 << bits) - 1))
+ : value);
+}
+
+long
+_bfd_ns32k_get_displacement(buffer, offset, size)
+ bfd_byte *buffer;
+ long offset;
+ long size;
+{
+ long value;
+ buffer += offset;
+ switch (size)
+ {
+ case 1:
+ value = ns32k_sign_extend (*buffer, 7);
+ break;
+ case 2:
+ value = ns32k_sign_extend(*buffer++, 6);
+ value = (value << 8) | (0xff & *buffer);
+ break;
+ case 4:
+ value = ns32k_sign_extend(*buffer++, 6);
+ value = (value << 8) | (0xff & *buffer++);
+ value = (value << 8) | (0xff & *buffer++);
+ value = (value << 8) | (0xff & *buffer);
+ break;
+ default:
+ abort ();
+ return 0;
+ }
+ return value;
+}
+
+int
+_bfd_ns32k_put_displacement(value, buffer, offset, size)
+ long value;
+ bfd_byte *buffer;
+ long offset;
+ long size;
+{
+ buffer += offset;
+ switch (size)
+ {
+ case 1:
+ if (value < -64 || value > 63)
+ return -1;
+ value&=0x7f;
+ *buffer++=value;
+ break;
+ case 2:
+ if (value < -8192 || value > 8191)
+ return -1;
+ value&=0x3fff;
+ value|=0x8000;
+ *buffer++=(value>>8);
+ *buffer++=value;
+ break;
+ case 4:
+ if (value < -0x1f000000 || value >= 0x20000000)
+ return -1;
+ value|=0xc0000000;
+ *buffer++=(value>>24);
+ *buffer++=(value>>16);
+ *buffer++=(value>>8);
+ *buffer++=value;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+long
+_bfd_ns32k_get_immediate (buffer, offset, size)
+ bfd_byte *buffer;
+ long offset;
+ long size;
+{
+ long value = 0;
+ buffer += offset;
+ switch (size)
+ {
+ case 4:
+ value = (value << 8) | (*buffer++ & 0xff);
+ case 3:
+ value = (value << 8) | (*buffer++ & 0xff);
+ case 2:
+ value = (value << 8) | (*buffer++ & 0xff);
+ case 1:
+ value = (value << 8) | (*buffer++ & 0xff);
+ }
+ return value;
+}
+
+int
+_bfd_ns32k_put_immediate (value, buffer, offset, size)
+ long value;
+ bfd_byte *buffer;
+ long offset;
+ long size;
+{
+ buffer += offset + size - 1;
+ switch (size)
+ {
+ case 4:
+ *buffer-- = (value & 0xff); value >>= 8;
+ case 3:
+ *buffer-- = (value & 0xff); value >>= 8;
+ case 2:
+ *buffer-- = (value & 0xff); value >>= 8;
+ case 1:
+ *buffer-- = (value & 0xff); value >>= 8;
+ }
+ return 0;
+}
+
+/* This is just like the standard perform_relocation except we
+ * use get_data and put_data which know about the ns32k
+ * storage methods.
+ * This is probably a lot more complicated than it needs to be!
+ */
+static bfd_reloc_status_type
+do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
+ error_message, get_data, put_data)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+ long (*get_data)();
+ int (*put_data)();
+{
+ int overflow = 0;
+ bfd_vma relocation;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *reloc_target_output_section;
+
+ if ((symbol->section == &bfd_abs_section)
+ && output_bfd != (bfd *) NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* If we are not producing relocateable output, return an error if
+ the symbol is not defined. An undefined weak symbol is
+ considered to have a value of zero (SVR4 ABI, p. 4-27). */
+ if (symbol->section == &bfd_und_section
+ && (symbol->flags & BSF_WEAK) == 0
+ && output_bfd == (bfd *) NULL)
+ flag = bfd_reloc_undefined;
+
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (output_bfd && howto->partial_inplace == false)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ if (howto->pc_relative == true)
+ {
+ /* This is a PC relative relocation. We want to set RELOCATION
+ to the distance between the address of the symbol and the
+ location. RELOCATION is already the address of the symbol.
+
+ We start by subtracting the address of the section containing
+ the location.
+
+ If pcrel_offset is set, we must further subtract the position
+ of the location within the section. Some targets arrange for
+ the addend to be the negative of the position of the location
+ within the section; for example, i386-aout does this. For
+ i386-aout, pcrel_offset is false. Some other targets do not
+ include the position of the location; for example, m88kbcs,
+ or ELF. For those targets, pcrel_offset is true.
+
+ If we are producing relocateable output, then we must ensure
+ that this reloc will be correctly computed when the final
+ relocation is done. If pcrel_offset is false we want to wind
+ up with the negative of the location within the section,
+ which means we must adjust the existing addend by the change
+ in the location within the section. If pcrel_offset is true
+ we do not want to adjust the existing addend at all.
+
+ FIXME: This seems logical to me, but for the case of
+ producing relocateable output it is not what the code
+ actually does. I don't want to change it, because it seems
+ far too likely that something will break. */
+
+ relocation -=
+ input_section->output_section->vma + input_section->output_offset;
+
+ if (howto->pcrel_offset == true)
+ relocation -= reloc_entry->address;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ if (howto->partial_inplace == false)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Modify the reloc
+ inplace to reflect what we now know. */
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return flag;
+ }
+ else
+ {
+ /* This is a partial relocation, but inplace, so modify the
+ reloc record a bit.
+
+ If we've relocated with a symbol with a section, change
+ into a ref to the section belonging to the symbol. */
+
+ reloc_entry->address += input_section->output_offset;
+
+ /* WTF?? */
+ if (abfd->xvec->flavour == bfd_target_coff_flavour
+ && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
+ {
+#if 1
+ /* For m68k-coff, the addend was being subtracted twice during
+ relocation with -r. Removing the line below this comment
+ fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled: --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers. I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way. There may very well be a reason that the
+code works as it does.
+
+Hmmm. The first obvious point is that bfd_perform_relocation should
+not have any tests that depend upon the flavour. It's seem like
+entirely the wrong place for such a thing. The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF. That's peculiar. In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location). When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol. Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output. When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output. Therefore, your
+patch is correct. In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file. This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line. Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c. The function
+specifically adds the addend field into the object file, knowing that
+bfd_perform_relocation is not going to. If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice. It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code. With BFD it's hard to be sure of anything. The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets. It should be straightforward if time and disk
+space consuming. For each target:
+ 1) build the linker
+ 2) generate some executable, and link it using -r (I would
+ probably use paranoia.o and link against newlib/libc.a, which
+ for all the supported targets would be available in
+ /usr/cygnus/progressive/H-host/target/lib/libc.a).
+ 3) make the change to reloc.c
+ 4) rebuild the linker
+ 5) repeat step 2
+ 6) if the resulting object files are the same, you have at least
+ made it no worse
+ 7) if they are different you have to figure out which version is
+ right
+*/
+ relocation -= reloc_entry->addend;
+#endif
+ reloc_entry->addend = 0;
+ }
+ else
+ {
+ reloc_entry->addend = relocation;
+ }
+ }
+ }
+ else
+ {
+ reloc_entry->addend = 0;
+ }
+
+ /* FIXME: This overflow checking is incomplete, because the value
+ might have overflowed before we get here. For a correct check we
+ need to compute the value in a size larger than bitsize, but we
+ can't reasonably do that for a reloc the same size as a host
+ machine word.
+ FIXME: We should also do overflow checking on the result after
+ adding in the value contained in the object file. */
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_vma check;
+
+ /* Get the value that will be used for the relocation, but
+ starting at bit position zero. */
+ if (howto->rightshift > howto->bitpos)
+ check = relocation >> (howto->rightshift - howto->bitpos);
+ else
+ check = relocation << (howto->bitpos - howto->rightshift);
+ switch (howto->complain_on_overflow)
+ {
+ case complain_overflow_signed:
+ {
+ /* Assumes two's complement. */
+ bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+
+ /* The above right shift is incorrect for a signed value.
+ Fix it up by forcing on the upper bits. */
+ if (howto->rightshift > howto->bitpos
+ && (bfd_signed_vma) relocation < 0)
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> (howto->rightshift - howto->bitpos)));
+ if ((bfd_signed_vma) check > reloc_signed_max
+ || (bfd_signed_vma) check < reloc_signed_min)
+ flag = bfd_reloc_overflow;
+ }
+ break;
+ case complain_overflow_unsigned:
+ {
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ bfd_vma reloc_unsigned_max =
+ (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ if ((bfd_vma) check > reloc_unsigned_max)
+ flag = bfd_reloc_overflow;
+ }
+ break;
+ case complain_overflow_bitfield:
+ {
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ if (((bfd_vma) check & ~reloc_bits) != 0
+ && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ {
+ /* The above right shift is incorrect for a signed
+ value. See if turning on the upper bits fixes the
+ overflow. */
+ if (howto->rightshift > howto->bitpos
+ && (bfd_signed_vma) relocation < 0)
+ {
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> (howto->rightshift - howto->bitpos)));
+ if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
+ flag = bfd_reloc_overflow;
+ }
+ else
+ flag = bfd_reloc_overflow;
+ }
+ }
+ break;
+ default:
+ abort ();
+ }
+ }
+
+ /*
+ Either we are relocating all the way, or we don't want to apply
+ the relocation to the reloc entry (probably because there isn't
+ any room in the output format to describe addends to relocs)
+ */
+
+ /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+ (OSF version 1.3, compiler version 3.11). It miscompiles the
+ following program:
+
+ struct str
+ {
+ unsigned int i0;
+ } s = { 0 };
+
+ int
+ main ()
+ {
+ unsigned long x;
+
+ x = 0x100000000;
+ x <<= (unsigned long) s.i0;
+ if (x == 0)
+ printf ("failed\n");
+ else
+ printf ("succeeded (%lx)\n", x);
+ }
+ */
+
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ /* Wait for the day when all have the mask in them */
+
+ /* What we do:
+ i instruction to be left alone
+ o offset within instruction
+ r relocation offset to apply
+ S src mask
+ D dst mask
+ N ~dst mask
+ A part 1
+ B part 2
+ R result
+
+ Do this:
+ i i i i i o o o o o from bfd_get<size>
+ and S S S S S to get the size offset we want
+ + r r r r r r r r r r to get the final value to place
+ and D D D D D to chop to right size
+ -----------------------
+ A A A A A
+ And this:
+ ... i i i i i o o o o o from bfd_get<size>
+ and N N N N N get instruction
+ -----------------------
+ ... B B B B B
+
+ And then:
+ B B B B B
+ or A A A A A
+ -----------------------
+ R R R R R R R R R R put into bfd_put<size>
+ */
+
+#define DOIT(x) \
+ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = get_data (data, addr, 1);
+ DOIT (x);
+ overflow = put_data(x, data, addr, 1);
+ }
+ break;
+
+ case 1:
+ if (relocation)
+ {
+ short x = get_data (data, addr, 2);
+ DOIT (x);
+ overflow = put_data(x, (unsigned char *) data, addr, 2);
+ }
+ break;
+ case 2:
+ if (relocation)
+ {
+ long x = get_data (data, addr, 4);
+ DOIT (x);
+ overflow = put_data(x, data, addr, 4);
+ }
+ break;
+ case -2:
+ {
+ long x = get_data(data, addr, 4);
+ relocation = -relocation;
+ DOIT(x);
+ overflow = put_data(x, data , addr, 4);
+ }
+ break;
+
+ case 3:
+ /* Do nothing */
+ break;
+
+ case 4:
+#ifdef BFD64
+ if (relocation)
+ {
+ bfd_vma x = get_data (data, addr, 8);
+ DOIT (x);
+ overflow = put_data(x, data, addr, 8);
+ }
+#else
+ abort ();
+#endif
+ break;
+ default:
+ return bfd_reloc_other;
+ }
+ if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
+ return bfd_reloc_overflow;
+
+ return flag;
+}
+
+/* Relocate a given location using a given value and howto. */
+
+bfd_reloc_status_type
+_bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
+ get_data, put_data)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd_vma relocation;
+ bfd_byte *location;
+ long (*get_data)();
+ int (*put_data)();
+{
+ int size;
+ bfd_vma x;
+ boolean overflow;
+
+ /* If the size is negative, negate RELOCATION. This isn't very
+ general. */
+ if (howto->size < 0)
+ relocation = -relocation;
+
+ /* Get the value we are going to relocate. */
+ size = bfd_get_reloc_size (howto);
+ switch (size)
+ {
+ default:
+ case 0:
+ abort ();
+ case 1:
+ case 2:
+ case 4:
+#ifdef BFD64
+ case 8:
+#endif
+ x = get_data (location, 0, size);
+ break;
+ }
+
+ /* Check for overflow. FIXME: We may drop bits during the addition
+ which we don't check for. We must either check at every single
+ operation, which would be tedious, or we must do the computations
+ in a type larger than bfd_vma, which would be inefficient. */
+ overflow = false;
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+ bfd_vma add;
+ bfd_signed_vma signed_add;
+
+ if (howto->rightshift == 0)
+ {
+ check = relocation;
+ signed_check = (bfd_signed_vma) relocation;
+ }
+ else
+ {
+ /* Drop unwanted bits from the value we are relocating to. */
+ check = relocation >> howto->rightshift;
+
+ /* If this is a signed value, the rightshift just dropped
+ leading 1 bits (assuming twos complement). */
+ if ((bfd_signed_vma) relocation >= 0)
+ signed_check = check;
+ else
+ signed_check = (check
+ | ((bfd_vma) - 1
+ & ~((bfd_vma) - 1 >> howto->rightshift)));
+ }
+
+ /* Get the value from the object file. */
+ add = x & howto->src_mask;
+
+ /* Get the value from the object file with an appropriate sign.
+ The expression involving howto->src_mask isolates the upper
+ bit of src_mask. If that bit is set in the value we are
+ adding, it is negative, and we subtract out that number times
+ two. If src_mask includes the highest possible bit, then we
+ can not get the upper bit, but that does not matter since
+ signed_add needs no adjustment to become negative in that
+ case. */
+ signed_add = add;
+ if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
+ signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
+
+ /* Add the value from the object file, shifted so that it is a
+ straight number. */
+ if (howto->bitpos == 0)
+ {
+ check += add;
+ signed_check += signed_add;
+ }
+ else
+ {
+ check += add >> howto->bitpos;
+
+ /* For the signed case we use ADD, rather than SIGNED_ADD,
+ to avoid warnings from SVR4 cc. This is OK since we
+ explictly handle the sign bits. */
+ if (signed_add >= 0)
+ signed_check += add >> howto->bitpos;
+ else
+ signed_check += ((add >> howto->bitpos)
+ | ((bfd_vma) - 1
+ & ~((bfd_vma) - 1 >> howto->bitpos)));
+ }
+
+ switch (howto->complain_on_overflow)
+ {
+ case complain_overflow_signed:
+ {
+ /* Assumes two's complement. */
+ bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+
+ if (signed_check > reloc_signed_max
+ || signed_check < reloc_signed_min)
+ overflow = true;
+ }
+ break;
+ case complain_overflow_unsigned:
+ {
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ bfd_vma reloc_unsigned_max =
+ (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ if (check > reloc_unsigned_max)
+ overflow = true;
+ }
+ break;
+ case complain_overflow_bitfield:
+ {
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ if ((check & ~reloc_bits) != 0
+ && (((bfd_vma) signed_check & ~reloc_bits)
+ != (-1 & ~reloc_bits)))
+ overflow = true;
+ }
+ break;
+ default:
+ abort ();
+ }
+ }
+
+ /* Put RELOCATION in the right bits. */
+ relocation >>= (bfd_vma) howto->rightshift;
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ /* Add RELOCATION to the right bits of X. */
+ x = ((x & ~howto->dst_mask)
+ | (((x & howto->src_mask) + relocation) & howto->dst_mask));
+
+ /* Put the relocated value back in the object file. */
+ switch (size)
+ {
+ default:
+ case 0:
+ abort ();
+ case 1:
+ case 2:
+ case 4:
+#ifdef BFD64
+ case 8:
+#endif
+ put_data(x, location, 0, size);
+ break;
+ }
+
+ return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message,
+ _bfd_ns32k_get_displacement,
+ _bfd_ns32k_put_displacement);
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message, _bfd_ns32k_get_immediate,
+ _bfd_ns32k_put_immediate);
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
+ address, value, addend)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma address;
+ bfd_vma value;
+ bfd_vma addend;
+{
+ bfd_vma relocation;
+
+ /* Sanity check the address. */
+ if (address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* This function assumes that we are dealing with a basic relocation
+ against a symbol. We want to compute the value of the symbol to
+ relocate to. This is just VALUE, the value of the symbol, plus
+ ADDEND, any addend associated with the reloc. */
+ relocation = value + addend;
+
+ /* If the relocation is PC relative, we want to set RELOCATION to
+ the distance between the symbol (currently in RELOCATION) and the
+ location we are relocating. Some targets (e.g., i386-aout)
+ arrange for the contents of the section to be the negative of the
+ offset of the location within the section; for such targets
+ pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
+ simply leave the contents of the section as zero; for such
+ targets pcrel_offset is true. If pcrel_offset is false we do not
+ need to subtract out the offset of the location within the
+ section (which is just ADDRESS). */
+ if (howto->pc_relative)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ if (howto->pcrel_offset)
+ relocation -= address;
+ }
+
+ return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
+ contents + address);
+}
diff --git a/bfd/cpu-powerpc.c b/bfd/cpu-powerpc.c
new file mode 100644
index 00000000000..11f0f80af5a
--- /dev/null
+++ b/bfd/cpu-powerpc.c
@@ -0,0 +1,124 @@
+/* BFD PowerPC CPU definition
+ Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* The common PowerPC architecture is compatible with the RS/6000. */
+
+static const bfd_arch_info_type *powerpc_compatible
+ PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
+
+static const bfd_arch_info_type *
+powerpc_compatible (a,b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ BFD_ASSERT (a->arch == bfd_arch_powerpc);
+ switch (b->arch)
+ {
+ default:
+ return NULL;
+ case bfd_arch_powerpc:
+ return bfd_default_compatible (a, b);
+ case bfd_arch_rs6000:
+ if (a->mach == 0)
+ return a;
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ 603, /* for the mpc603 */
+ "powerpc",
+ "powerpc:603",
+ 3,
+ false, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[1]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ 604, /* for the mpc604 */
+ "powerpc",
+ "powerpc:604",
+ 3,
+ false, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[2]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ 403, /* for the 403 */
+ "powerpc",
+ "powerpc:403",
+ 3,
+ false, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[3]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ 601, /* for the mpc601 */
+ "powerpc",
+ "powerpc:601",
+ 3,
+ false, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ 0
+ }
+};
+
+const bfd_arch_info_type bfd_powerpc_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ 0, /* for the POWER/PowerPC common architecture */
+ "powerpc",
+ "powerpc:common",
+ 3,
+ true, /* the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[0]
+ };
diff --git a/bfd/cpu-rs6000.c b/bfd/cpu-rs6000.c
new file mode 100644
index 00000000000..9852ae9a053
--- /dev/null
+++ b/bfd/cpu-rs6000.c
@@ -0,0 +1,70 @@
+/* BFD back-end for rs6000 support
+ Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+ FIXME: Can someone provide a transliteration of this name into ASCII?
+ Using the following chars caused a compiler warning on HIUX (so I replaced
+ them with octal escapes), and isn't useful without an understanding of what
+ character set it is.
+ Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+ and John Gilmore of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* The RS/6000 architecture is compatible with the PowerPC common
+ architecture. */
+
+static const bfd_arch_info_type *rs6000_compatible
+ PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
+
+static const bfd_arch_info_type *
+rs6000_compatible (a,b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ BFD_ASSERT (a->arch == bfd_arch_rs6000);
+ switch (b->arch)
+ {
+ default:
+ return NULL;
+ case bfd_arch_rs6000:
+ return bfd_default_compatible (a, b);
+ case bfd_arch_powerpc:
+ if (b->mach == 0)
+ return b;
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+
+const bfd_arch_info_type bfd_rs6000_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_rs6000,
+ 6000, /* only 1 machine */
+ "rs6000",
+ "rs6000:6000",
+ 3,
+ true, /* the one and only */
+ rs6000_compatible,
+ bfd_default_scan,
+ 0,
+ };
diff --git a/bfd/cpu-sh.c b/bfd/cpu-sh.c
new file mode 100644
index 00000000000..44adf9217ff
--- /dev/null
+++ b/bfd/cpu-sh.c
@@ -0,0 +1,102 @@
+/* BFD library support routines for the Hitachi-SH architecture.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+static boolean
+scan_mach (info, string)
+ const struct bfd_arch_info *info;
+ const char *string;
+{
+ if (strcasecmp (info->printable_name, string) == 0)
+ return true;
+ return false;
+}
+
+
+#if 0
+/* This routine is provided two arch_infos and returns whether
+ they'd be compatible */
+
+static const bfd_arch_info_type *
+compatible (a,b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ if (a->arch != b->arch || a->mach != b->mach)
+ return NULL;
+ return a;
+}
+#endif
+
+#define SH_NEXT &arch_info_struct[0]
+#define SH3_NEXT &arch_info_struct[1]
+#define SH3E_NEXT NULL
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_sh,
+ bfd_mach_sh3,
+ "sh", /* arch_name */
+ "sh3", /* printable name */
+ 1,
+ false, /* not the default */
+ bfd_default_compatible,
+ scan_mach,
+ SH3_NEXT
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_sh,
+ bfd_mach_sh3e,
+ "sh", /* arch_name */
+ "sh3e", /* printable name */
+ 1,
+ false, /* not the default */
+ bfd_default_compatible,
+ scan_mach,
+ SH3E_NEXT
+ },
+};
+
+const bfd_arch_info_type bfd_sh_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_sh,
+ bfd_mach_sh,
+ "sh", /* arch_name */
+ "sh", /* printable name */
+ 1,
+ true, /* the default machine */
+ bfd_default_compatible,
+ scan_mach,
+ SH_NEXT
+};
diff --git a/bfd/cpu-sparc.c b/bfd/cpu-sparc.c
new file mode 100644
index 00000000000..234bd92bd29
--- /dev/null
+++ b/bfd/cpu-sparc.c
@@ -0,0 +1,156 @@
+/* BFD support for the SPARC architecture.
+ Copyright (C) 1992, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* Don't mix 32 bit and 64 bit files. */
+
+static const bfd_arch_info_type *sparc_compatible
+ PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
+
+static const bfd_arch_info_type *
+sparc_compatible (a, b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ if (a->bits_per_word != b->bits_per_word)
+ return NULL;
+
+ return bfd_default_compatible (a, b);
+}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_sparclet,
+ "sparc",
+ "sparc:sparclet",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[1],
+ },
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_sparclite,
+ "sparc",
+ "sparc:sparclite",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[2],
+ },
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_v8plus,
+ "sparc",
+ "sparc:v8plus",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[3],
+ },
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_v8plusa,
+ "sparc",
+ "sparc:v8plusa",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[4],
+ },
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_sparclite_le,
+ "sparc",
+ "sparc:sparclite_le",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[5],
+ },
+ {
+ 64, /* bits in a word */
+ 64, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_v9,
+ "sparc",
+ "sparc:v9",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[6],
+ },
+ {
+ 64, /* bits in a word */
+ 64, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_v9a,
+ "sparc",
+ "sparc:v9a",
+ 3,
+ false,
+ sparc_compatible,
+ bfd_default_scan,
+ 0,
+ }
+};
+
+const bfd_arch_info_type bfd_sparc_arch =
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc,
+ "sparc",
+ "sparc",
+ 3,
+ true, /* the default */
+ sparc_compatible,
+ bfd_default_scan,
+ &arch_info_struct[0],
+ };
diff --git a/bfd/cpu-tic30.c b/bfd/cpu-tic30.c
new file mode 100644
index 00000000000..dd723f7b4a5
--- /dev/null
+++ b/bfd/cpu-tic30.c
@@ -0,0 +1,39 @@
+/* BFD support for the Texas Instruments TMS320C30 architecture.
+ Copyright 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_tic30_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_tic30,
+ 0, /* only 1 machine */
+ "tic30",
+ "tms320c30",
+ 2,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan,
+ 0,
+};
diff --git a/bfd/cpu-tic80.c b/bfd/cpu-tic80.c
new file mode 100644
index 00000000000..302866ece9d
--- /dev/null
+++ b/bfd/cpu-tic80.c
@@ -0,0 +1,39 @@
+/* bfd back-end for TI TMS320C80 (MVP) support
+ Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus support (fnf@cygnus.com)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_tic80_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_tic80, /* bfd_architecture enum */
+ 0, /* only 1 machine */
+ "tic80", /* architecture name */
+ "tic80", /* printable name */
+ 2, /* section alignment power */
+ true, /* default machine for architecture */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ NULL, /* Pointer to next in chain */
+ };
diff --git a/bfd/cpu-v850.c b/bfd/cpu-v850.c
new file mode 100644
index 00000000000..539413de022
--- /dev/null
+++ b/bfd/cpu-v850.c
@@ -0,0 +1,103 @@
+/* BFD support for the NEC V850 processor
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include <ctype.h>
+
+static boolean
+scan (info, string)
+ const struct bfd_arch_info * info;
+ const char * string;
+{
+ const char *ptr_src;
+ const char *ptr_tst;
+ unsigned long number;
+ enum bfd_architecture arch;
+
+ /* First test for an exact match */
+ if (strcasecmp (string, info->printable_name) == 0)
+ return true;
+
+ /* See how much of the supplied string matches with the
+ architecture, eg the string m68k:68020 would match the m68k entry
+ up to the :, then we get left with the machine number */
+
+ for (ptr_src = string, ptr_tst = info->arch_name;
+ *ptr_src && *ptr_tst;
+ ptr_src++, ptr_tst++)
+ {
+ if (*ptr_src != *ptr_tst) break;
+ }
+
+ /* Chewed up as much of the architecture as will match, skip any
+ colons */
+ if (*ptr_src == ':')
+ ptr_src++;
+
+ if (*ptr_src == 0)
+ {
+ /* nothing more, then only keep this one if it is the default
+ machine for this architecture */
+ return info->the_default;
+ }
+
+ number = 0;
+ while (isdigit ((unsigned char) *ptr_src))
+ {
+ number = number * 10 + * ptr_src - '0';
+ ptr_src++;
+ }
+
+ switch (number)
+ {
+ case bfd_mach_v850e: arch = bfd_arch_v850; break;
+ case bfd_mach_v850ea: arch = bfd_arch_v850; break;
+ default:
+ return false;
+ }
+
+ if (arch != info->arch)
+ return false;
+
+ if (number != info->mach)
+ return false;
+
+ return true;
+}
+
+#define N(number, print, default, next) \
+{ 32, 32, 8, bfd_arch_v850, number, "v850", print, 2, default, \
+ bfd_default_compatible, scan, next }
+
+#define NEXT NULL
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (bfd_mach_v850e, "v850e", false, &arch_info_struct[1]),
+ N (bfd_mach_v850ea, "v850ea", false, NULL)
+};
+
+#undef NEXT
+#define NEXT &arch_info_struct[0]
+
+const bfd_arch_info_type bfd_v850_arch =
+ N (bfd_mach_v850, "v850", true, NEXT);
diff --git a/bfd/cpu-vax.c b/bfd/cpu-vax.c
new file mode 100644
index 00000000000..bdc6d39e451
--- /dev/null
+++ b/bfd/cpu-vax.c
@@ -0,0 +1,39 @@
+/* bfd back-end for vax support
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_vax_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_vax,
+ 0, /* only 1 machine */
+ "vax",
+ "vax",
+ 3,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
diff --git a/bfd/cpu-w65.c b/bfd/cpu-w65.c
new file mode 100644
index 00000000000..c0bbf045219
--- /dev/null
+++ b/bfd/cpu-w65.c
@@ -0,0 +1,54 @@
+/* BFD library support routines for the WDC 65816 architecture.
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as publiw65ed 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 w65ould have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+int bfd_default_scan_num_mach();
+
+static boolean
+scan_mach (info, string)
+ const struct bfd_arch_info *info;
+ const char *string;
+{
+ if (strcmp(string,"w65") == 0) return true;
+ if (strcmp(string,"w65816") == 0) return true;
+ return false;
+}
+
+
+
+const bfd_arch_info_type bfd_w65_arch =
+{
+ 16, /* 16 bits in a word */
+ 24, /* 24 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_w65,
+ 0, /* only 1 machine */
+ "w65", /* arch_name */
+ "w65", /* printable name */
+ 1,
+ true, /* the default machine */
+ bfd_default_compatible,
+ scan_mach,
+ 0,
+};
diff --git a/bfd/cpu-we32k.c b/bfd/cpu-we32k.c
new file mode 100644
index 00000000000..a38cbc1268b
--- /dev/null
+++ b/bfd/cpu-we32k.c
@@ -0,0 +1,39 @@
+/* bfd back-end for we32k support
+ Copyright (C) 1992 Free Software Foundation, Inc.
+ Contributed by Brendan Kehoe (brendan@cs.widener.edu).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_we32k_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_we32k,
+ 32000, /* only 1 machine */
+ "we32k",
+ "we32k:32000",
+ 3,
+ true, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan ,
+ 0,
+ };
diff --git a/bfd/cpu-z8k.c b/bfd/cpu-z8k.c
new file mode 100644
index 00000000000..5cce8eb0689
--- /dev/null
+++ b/bfd/cpu-z8k.c
@@ -0,0 +1,198 @@
+/* BFD library support routines for the Z800n architecture.
+ Copyright (C) 1992 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+#if 0 /* not used currently */
+/*
+Relocations for the Z8K
+
+*/
+static bfd_reloc_status_type
+howto16_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+ long x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+
+ HOWTO_PREPARE (relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_16 (abfd, x, (bfd_byte *) data + addr);
+ return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+howto8_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+ long x = bfd_get_8 (abfd, (bfd_byte *) data + addr);
+
+ HOWTO_PREPARE (relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_8 (abfd, x, (bfd_byte *) data + addr);
+ return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+
+ long x = bfd_get_8 (abfd, (bfd_byte *) data + addr);
+ abort ();
+ HOWTO_PREPARE (relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_8 (abfd, x, (bfd_byte *) data + addr);
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data,
+ ignore_input_section, ignore_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol_in;
+ PTR data;
+ asection *ignore_input_section;
+ bfd *ignore_bfd;
+{
+ long relocation = 0;
+ bfd_vma addr = reloc_entry->address;
+ long x = bfd_get_8 (abfd, (bfd_byte *) data + addr);
+ abort ();
+ HOWTO_PREPARE (relocation, symbol_in);
+
+ x = (x + relocation + reloc_entry->addend);
+
+ bfd_put_8 (abfd, x, (bfd_byte *) data + addr);
+ return bfd_reloc_ok;
+}
+
+
+
+static reloc_howto_type howto_16
+= NEWHOWTO (howto16_callback, "abs16", 1, false, false);
+static reloc_howto_type howto_8
+= NEWHOWTO (howto8_callback, "abs8", 0, false, false);
+
+static reloc_howto_type howto_8_FFnn
+= NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false);
+
+static reloc_howto_type howto_8_pcrel
+= NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true);
+
+
+static reloc_howto_type *
+local_bfd_reloc_type_lookup (arch, code)
+ const struct bfd_arch_info *arch;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_16:
+ return &howto_16;
+ case BFD_RELOC_8_FFnn:
+ return &howto_8_FFnn;
+ case BFD_RELOC_8:
+ return &howto_8;
+ case BFD_RELOC_8_PCREL:
+ return &howto_8_pcrel;
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+}
+#endif
+
+int bfd_default_scan_num_mach ();
+
+static boolean
+scan_mach (info, string)
+ const struct bfd_arch_info *info;
+ const char *string;
+{
+ if (strcmp (string, "z8001") == 0 || strcmp (string, "z8k") == 0)
+ {
+ return bfd_mach_z8001 == info->mach;
+ }
+ if (strcmp (string, "z8002") == 0)
+ {
+ return bfd_mach_z8002 == info->mach;
+ }
+ return false;
+}
+
+
+/* This routine is provided two arch_infos and returns whether
+ they'd be compatible */
+
+static const bfd_arch_info_type *
+compatible (a, b)
+ const bfd_arch_info_type *a;
+ const bfd_arch_info_type *b;
+{
+ if (a->arch != b->arch || a->mach != b->mach)
+ return NULL;
+ return a;
+}
+
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {32, 32, 8, bfd_arch_z8k, bfd_mach_z8001, "z8k", "z8001", 1, false, compatible, scan_mach, 0,},
+};
+
+const bfd_arch_info_type bfd_z8k_arch =
+{
+ 32, 16, 8, bfd_arch_z8k, bfd_mach_z8002, "z8k", "z8002", 1, true, compatible, scan_mach, &arch_info_struct[0],
+};
diff --git a/bfd/demo64.c b/bfd/demo64.c
new file mode 100644
index 00000000000..c91381d46e9
--- /dev/null
+++ b/bfd/demo64.c
@@ -0,0 +1,24 @@
+/* BFD backend for demonstration 64-bit a.out binaries.
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 64
+#define MY(OP) CAT(demo_64_,OP)
+#define TARGETNAME "demo64"
+#include "aoutf1.h"
diff --git a/bfd/dep-in.sed b/bfd/dep-in.sed
new file mode 100644
index 00000000000..444dde0c019
--- /dev/null
+++ b/bfd/dep-in.sed
@@ -0,0 +1,26 @@
+:loop
+/\\$/N
+s/\\\n */ /g
+t loop
+
+s!\.o:!.lo:!
+s! @BFD_H@!!g
+s!@INCDIR@!$(INCDIR)!g
+s!@SRCDIR@/!!g
+s!hosts/[^ ]*\.h ! !g
+s/ sysdep.h//g
+s! \.\./bfd/sysdep.h!!g
+s/ libbfd.h//g
+s/ config.h//g
+s! \$(INCDIR)/fopen-[^ ]*\.h!!g
+s! \$(INCDIR)/ansidecl\.h!!g
+
+s/\\\n */ /g
+
+s/ *$//
+s/ */ /g
+s/ *:/:/g
+/:$/d
+
+s/\(.\{50\}[^ ]*\) /\1 \\\
+ /g
diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog
new file mode 100644
index 00000000000..9e8207ac570
--- /dev/null
+++ b/bfd/doc/ChangeLog
@@ -0,0 +1,390 @@
+Thu Feb 4 23:21:36 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild with current autoconf/automake.
+
+Thu Jul 23 09:36:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * bfdint.texi (BFD ELF processor required): Add paragraph
+ describing the necessity to create "include/elf/CPU.h".
+
+Thu May 7 14:45:43 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (chew.o): Add -I options for intl srcdir and
+ objdir.
+ * Makefile.in: Rebuild.
+
+Mon Apr 27 20:19:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdint.texi: New file.
+ * Makefile.am (noinst_TEXINFOS): New variable.
+ * Makefile.in: Rebuild.
+
+Mon Apr 13 16:48:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild.
+
+Mon Apr 6 14:06:55 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (STAGESTUFF): Remove variable.
+ (CLEANFILES): Don't remove $(STAGESTUFF).
+ (DISTCLEANFILES, MAINTAINERCLEANFILES): New variables.
+ * Makefile.in: Rebuild.
+
+Fri Mar 27 16:25:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * chew.c (skip_white_and_starts): Remove unused declaration.
+ (skip_white_and_stars): Add casts to avoid warnings.
+ (skip_trailing_newlines, paramstuff, courierize): Likewise.
+ (bulletize, do_fancy_stuff, iscommand): Likewise.
+ (kill_bogus_lines, nextword, main): Likewise.
+ (manglecomments): Comment out.
+ (outputdots, kill_bogus_lines): Remove unused local variables.
+ (perform, compile): Likewise.
+ (courierize): Fully parenthesize expression.
+ (copy_past_newline): Declare return value.
+ (print): Change printf format string.
+ (main): Call usage for an unrecognized option.
+
+Fri Feb 13 14:37:14 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * Makefile.in: Rebuild.
+
+Mon Jan 26 15:38:36 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * doc.str (bodytext): Don't output @* at the end.
+ * chew.c (kill_bogus_lines): Make sure that a period at the
+ beginning is recognized.
+ (indent): Don't put indentation at the end.
+ (copy_past_newline): Expand tabs.
+ * Makefile.am (s-reloc, s-syms): Depend on doc.str.
+ * Makefile.in: Rebuild.
+
+Wed Oct 1 14:41:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (libbfd.h): Don't use cpu-h8300.c, cpu-i960.c, or
+ elfcode.h as input files; they don't contribute anything.
+ * Makefile.in: Rebuild.
+
+Fri Aug 15 04:55:15 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.am (libbfd.h, libcoff.h): Invoke $(MKDOC) as ./$(MKDOC).
+ * Makefile.in: Rebuild.
+
+Fri Aug 1 12:59:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (CC_FOR_BUILD): Don't set explicitly.
+ * Makefile.in: Rebuild.
+
+Thu Jul 31 20:00:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * Makefile.in: Now built with automake.
+
+Tue Jul 22 14:44:00 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * Makefile.in: Change stamp-* files to s-* files. Use bfdt.texi
+ rather than bfd.texi.
+ (DOCFILES): Change bfd.texi to bfdt.texi.
+ * bfd.texinfo: Include bfdt.texi, not bfd.texi.
+
+Mon Jun 16 15:33:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC, CFLAGS): Substitute from configure script.
+ From Jeff Makey <jeff@cts.com>.
+
+Tue Apr 15 12:37:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install-info): Use mkinstalldirs to build
+ $(infodir).
+
+Tue Apr 8 12:49:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install-info): Permit info files to be in srcdir.
+ (stamp-*): Add a stamp-X target for each X.texi target.
+ (*.texi): Just depend upon stamp-X.
+ (clean): Remove stamp-*.
+ (distclean): Depend upon mostlyclean. Remove stamp-*. Don't
+ remove $(DOCFILES).
+
+Mon Apr 7 15:23:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Don't remove *.info files.
+
+Thu Feb 13 20:50:02 1997 Klaus Kaempf (kkaempf@progis.de)
+
+ * makefile.vms: New file.
+
+Tue Jun 18 18:32:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * chew.c (kill_bogus_lines): Reset sl when not at the start of a
+ line. From Uwe Ohse <uwe@tirka.gun.de>.
+
+Tue Jan 30 14:10:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Ronald F. Guilmette <rfg@monkeys.com>:
+ * Makefile.in (libbfd.h): Depend upon proto.str.
+ (libcoff.h, bfd.h): Likewise.
+
+Fri Nov 3 14:46:48 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (SRCDOC, SRCPROT, core.texi, bfd.h): Use corefile.c,
+ renamed from core.c.
+
+Wed Nov 1 14:28:23 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * chew.c: Include <ctype.h>.
+
+Fri Oct 6 16:23:34 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Makefile.in (Makefile): Only remake this Makefile.
+
+Wed Oct 4 15:51:05 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * chew.c: Include <stdio.h>.
+
+Tue Sep 12 18:14:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target.
+
+Thu Aug 31 12:18:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (bfd.h): Add additional #endif at end of bfd.h if
+ __cplusplus is defined.
+
+Tue Nov 29 16:13:34 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * chew.c (write_buffer): New argument `f', all callers changed.
+ (stdout, stderr, print, drop, idrop): New forth words.
+ * proto.str (COMMENT): New command.
+ * doc.str (COMMENT): Likewise.
+
+Mon Sep 12 11:44:17 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (DOCFILES): Remove ctor.texi.
+ (IPROTOS): Remove ctor.ip.
+ (SRCIPROT): Remove $(srcdir)/../ctor.c.
+ (ctor.texi): Remove target.
+ (libbfd.h): Remove dependency on $(srcdir)/../ctor.c. Remove
+ $(MKDOC) run on $(srcdir)/../ctor.c.
+ * bfd.texinfo (Constructors): Remove section.
+
+Fri Sep 2 13:33:44 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * chew.c: Include assert.h. Added prototypes for most functions.
+ Changed most uses of int to long. Do bounds checking on the
+ stacks. Added comment at the beginning documenting most of the
+ intrinsics. Lots of whitespace changes. Re-ordered some
+ functions.
+ (die, check_range, icheck_range): New functions.
+ (strip_trailing_newlines, print_stack_level): New functions.
+ (translatecomments): Don't insert tab before "/*".
+ (iscommand): Minimum command length is now 4.
+ (nextword): Handle some \-sequences.
+ (push_addr): Deleted.
+ (main): Add new intrinsics strip_trailing_newlines and
+ print_stack_level. Complain at end if stack contains more than
+ one element, or less.
+ (remchar): Make sure the string is not empty before chopping off a
+ character.
+
+ * doc.str, proto.str: Handle new commands SENUM, ENUM, ENUMX,
+ ENUMEQ, ENUMEQX, ENUMDOC.
+
+Wed Jan 12 18:37:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.texinfo: Added Linker Functions node.
+ * doc/Makefile.in (DOCFILES): Added linker.texi.
+ (SRCDOC): Added linker.c.
+ (linker.texi): New target.
+
+Tue Jan 4 10:52:56 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * chew.c: Don't rely on a correct declaration of exit.
+ (chew_exit): New function which just calls exit.
+ (main): Use it.
+
+Mon Jan 3 11:40:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.texinfo: Added Hash Tables node.
+ * Makefile.in (DOCFILES): Added hash.texi.
+ (SRCDOC): Added hash.c.
+ (hash.texi): New target.
+
+Thu Dec 30 16:57:04 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in: Delete all references to seclet.c, since it's just
+ been deleted. Don't mention hash.c, linker.c, or genlink.h yet,
+ since they don't contain documentation yet (hint, hint!).
+
+Fri Nov 5 10:58:53 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * bfd.texinfo: Small cleanups.
+
+Fri Nov 19 03:46:11 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (archures.texi): Depends on $(MKDOC).
+
+Tue Aug 10 14:22:39 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * bfd.texinfo (BFD back end): Don't include elfcode.texi, since
+ it's empty now and that triggers a makeinfo bug.
+
+Mon Aug 9 16:27:30 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * bfd.texinfo (BFD back end): New section on ELF, includes
+ elf.texi and elfcode.texi.
+ * Makefile.in (DOCFILES): Include elf.texi, elfcode.texi.
+ (SRCDOC): Include elfcode.h, elf.c.
+ (elf.texi, elfcode.texi): New intermediate targets.
+
+Thu Jun 24 13:48:13 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (.c.o, chew.o): Put CFLAGS last.
+ * bfdsumm.texi: New file, broken out of bfd.texinfo, to share
+ with ld.texinfo.
+
+Mon Jun 14 12:07:07 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in (install-info): remove parentdir cruft,
+
+Wed Jun 9 16:00:32 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (mostlyclean): Remove chew.o.
+
+Tue May 25 14:46:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (libbfd.h): Use elfcode.h, not elf32.c.
+
+Mon May 24 15:50:07 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * chew.c (compile): Add a couple of missing casts.
+
+Wed May 12 14:45:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (CC_FOR_BUILD): New variable, define to be $(CC).
+ (chew.o, $(MKDOC)): Build using CC_FOR_BUILD rather than CC, since
+ it must run on the build machine.
+
+Tue Apr 6 22:38:10 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (chew): Don't compile from .c to executable in a
+ single step; it puts a temporary .o filename into the executable,
+ which makes multi-stage comparisons fail. Compile chew.c to
+ chew.o, and link that, which makes identical executables every time.
+
+Wed Mar 24 17:26:29 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: fix typo (bfd.texinfo not bfd.texino)
+
+Fri Mar 19 01:13:00 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * bfd.texinfo: Since BFD version number has been bumped, do same
+ to "version number" on title page, and elsewhere. Should be
+ fixed to extract real version number.
+
+Tue Mar 16 12:15:13 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Add *clean rules.
+
+Mon Jan 11 18:43:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (libbfd.h): Removed duplicate init.c and libbfd.c.
+ Added seclet.c.
+ (bfd.h): Added dependency on bfd.c and seclet.c. Added seclet.c
+ to build.
+
+Thu Dec 17 19:35:43 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added dvi target, define and use $(TEXI2DVI)
+
+Thu Dec 3 17:42:48 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (TEXIDIR): New variable.
+ (bfd.dvi): Look for bfd.texinfo in $(srcdir). Generate index.
+
+ * bfd.texinfo: Minor doc fixes.
+
+Thu Nov 5 03:13:55 1992 John Gilmore (gnu@cygnus.com)
+
+ Cleanup: Replace all uses of EXFUN in the BFD sources, with PARAMS.
+
+ * doc/chew.c (exfunstuff): Eliminate.
+ (paramstuff): Replace exfunstuff with function to generate PARAMS.
+ * doc/proto.str: Use paramstuff rather than exfunstuff.
+
+Mon Aug 17 12:40:32 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * chew.c: various patches provided by Howard Chu.
+
+Fri Jun 19 18:59:54 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (libbfd.h): Add elf.c as a source of prototypes.
+
+Mon May 11 18:55:59 1992 John Gilmore (gnu at cygnus.com)
+
+ * chew.c: exit() should be declared by config files, not by
+ portable source code. Its type could be int or void function.
+
+Mon May 4 13:45:57 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: another CFLAGS correction.
+
+Tue Apr 28 10:21:32 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: Do the CFLAGS thing.
+
+Fri Apr 10 22:34:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (MINUS_G): Add macro and default to -g.
+
+Fri Mar 6 18:53:18 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * chew.c: now has -w switch turn on warnings
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Tue Dec 10 22:11:05 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: build chew into the current directory. Complete
+ the MKDOC macro transition.
+
+Tue Dec 10 08:26:28 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * chew.c: don't core dump when can't open file
+ * Makefile.in: get proto.str from the right place when built in
+ odd directories
+
+Tue Dec 10 04:07:25 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Sat Dec 7 17:01:23 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * chew.c: Much modified
+ * proto.str, doc.str: New files for extracting to product
+ prototypes and documents respectively.
+
+
+Fri Dec 6 22:57:12 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: added standards.text support, host/site/target
+ inclusion hooks, install using INSTALL_DATA rather than cp,
+ don't echo on install.
+
+Thu Dec 5 22:46:17 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/bfd/doc/Makefile.am b/bfd/doc/Makefile.am
new file mode 100644
index 00000000000..0d5268e9608
--- /dev/null
+++ b/bfd/doc/Makefile.am
@@ -0,0 +1,250 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+DOCFILES = aoutx.texi archive.texi archures.texi \
+ bfdt.texi cache.texi coffcode.texi \
+ core.texi elf.texi elfcode.texi format.texi libbfd.texi \
+ opncls.texi reloc.texi section.texi \
+ syms.texi targets.texi init.texi hash.texi linker.texi
+
+PROTOS = archive.p archures.p bfd.p \
+ core.p format.p \
+ libbfd.p opncls.p reloc.p \
+ section.p syms.p targets.p \
+ format.p core.p init.p
+
+IPROTOS = cache.ip libbfd.ip reloc.ip init.ip archures.ip coffcode.ip
+
+# SRCDOC, SRCPROT, SRCIPROT only used to sidestep Sun Make bug in interaction
+# between VPATH and suffix rules. If you use GNU Make, perhaps other Makes,
+# you don't need these three:
+SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \
+ $(srcdir)/../archures.c $(srcdir)/../bfd.c \
+ $(srcdir)/../cache.c $(srcdir)/../coffcode.h \
+ $(srcdir)/../corefile.c $(srcdir)/../elf.c \
+ $(srcdir)/../elfcode.h $(srcdir)/../format.c \
+ $(srcdir)/../libbfd.c $(srcdir)/../opncls.c \
+ $(srcdir)/../reloc.c $(srcdir)/../section.c \
+ $(srcdir)/../syms.c $(srcdir)/../targets.c \
+ $(srcdir)/../hash.c $(srcdir)/../linker.c
+
+SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \
+ $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \
+ $(srcdir)/../format.c $(srcdir)/../libbfd.c \
+ $(srcdir)/../opncls.c $(srcdir)/../reloc.c \
+ $(srcdir)/../section.c $(srcdir)/../syms.c \
+ $(srcdir)/../targets.c $(srcdir)/../init.c
+
+SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \
+ $(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \
+ $(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \
+ $(srcdir)/../init.c
+
+TEXIDIR = $(srcdir)/../../texinfo/fsf
+
+info_TEXINFOS = bfd.texinfo
+
+MKDOC = chew$(EXEEXT_FOR_BUILD)
+
+$(MKDOC): chew.o
+ $(CC_FOR_BUILD) -o $(MKDOC) chew.o $(LOADLIBES) $(LDFLAGS)
+
+chew.o: chew.c
+ $(CC_FOR_BUILD) -c -I.. -I$(srcdir)/.. -I$(srcdir)/../../include -I$(srcdir)/../../intl -I../../intl $(H_CFLAGS) $(CFLAGS) $(srcdir)/chew.c
+
+protos: libbfd.h libcoff.h bfd.h
+
+bfd.info bfd.dvi: $(DOCFILES) bfdsumm.texi bfd.texinfo
+
+# We can't replace these rules with an implicit rule, because
+# makes without VPATH support couldn't find the .h files in `..'.
+
+# We use s-XXX targets so that we can distribute the info files,
+# and permit people to rebuild them, without requiring the makeinfo
+# program. If somebody tries to rebuild info, but none of the .texi
+# files have changed, then this Makefile will build chew, and will
+# build all of the stamp files, but will not actually have to rebuild
+# bfd.info.
+
+s-aoutx: $(MKDOC) $(srcdir)/../aoutx.h $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../aoutx.h >aoutx.tmp
+ $(srcdir)/../../move-if-change aoutx.tmp aoutx.texi
+ touch s-aoutx
+aoutx.texi: s-aoutx
+
+s-archive: $(MKDOC) $(srcdir)/../archive.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../archive.c >archive.tmp
+ $(srcdir)/../../move-if-change archive.tmp archive.texi
+ touch s-archive
+archive.texi: s-archive
+
+s-archures: $(MKDOC) $(srcdir)/../archures.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../archures.c >archures.tmp
+ $(srcdir)/../../move-if-change archures.tmp archures.texi
+ touch s-archures
+archures.texi: s-archures
+
+# We use bfdt.texi, rather than bfd.texi, to avoid conflicting with
+# bfd.texinfo on an 8.3 filesystem.
+s-bfd: $(MKDOC) $(srcdir)/../bfd.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfd.c >bfd.tmp
+ $(srcdir)/../../move-if-change bfd.tmp bfdt.texi
+ touch s-bfd
+bfdt.texi: s-bfd
+
+s-cache: $(MKDOC) $(srcdir)/../cache.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../cache.c >cache.tmp
+ $(srcdir)/../../move-if-change cache.tmp cache.texi
+ touch s-cache
+cache.texi: s-cache
+
+s-coffcode: $(MKDOC) $(srcdir)/../coffcode.h $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../coffcode.h >coffcode.tmp
+ $(srcdir)/../../move-if-change coffcode.tmp coffcode.texi
+ touch s-coffcode
+coffcode.texi: s-coffcode
+
+s-core: $(MKDOC) $(srcdir)/../corefile.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../corefile.c >core.tmp
+ $(srcdir)/../../move-if-change core.tmp core.texi
+ touch s-core
+core.texi: s-core
+
+s-elf: $(MKDOC) $(srcdir)/../elf.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../elf.c >elf.tmp
+ $(srcdir)/../../move-if-change elf.tmp elf.texi
+ touch s-elf
+elf.texi: s-elf
+
+s-elfcode: $(MKDOC) $(srcdir)/../elfcode.h $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../elfcode.h >elfcode.tmp
+ $(srcdir)/../../move-if-change elfcode.tmp elfcode.texi
+ touch s-elfcode
+elfcode.texi: s-elfcode
+
+s-format: $(MKDOC) $(srcdir)/../format.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../format.c >format.tmp
+ $(srcdir)/../../move-if-change format.tmp format.texi
+ touch s-format
+format.texi: s-format
+
+s-libbfd: $(MKDOC) $(srcdir)/../libbfd.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../libbfd.c >libbfd.tmp
+ $(srcdir)/../../move-if-change libbfd.tmp libbfd.texi
+ touch s-libbfd
+libbfd.texi: s-libbfd
+
+s-opncls: $(MKDOC) $(srcdir)/../opncls.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../opncls.c >opncls.tmp
+ $(srcdir)/../../move-if-change opncls.tmp opncls.texi
+ touch s-opncls
+opncls.texi: s-opncls
+
+s-reloc: $(MKDOC) $(srcdir)/../reloc.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../reloc.c >reloc.tmp
+ $(srcdir)/../../move-if-change reloc.tmp reloc.texi
+ touch s-reloc
+reloc.texi: s-reloc
+
+s-section: $(MKDOC) $(srcdir)/../section.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../section.c >section.tmp
+ $(srcdir)/../../move-if-change section.tmp section.texi
+ touch s-section
+section.texi: s-section
+
+s-syms: $(MKDOC) $(srcdir)/../syms.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../syms.c >syms.tmp
+ $(srcdir)/../../move-if-change syms.tmp syms.texi
+ touch s-syms
+syms.texi: s-syms
+
+s-targets: $(MKDOC) $(srcdir)/../targets.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../targets.c >targets.tmp
+ $(srcdir)/../../move-if-change targets.tmp targets.texi
+ touch s-targets
+targets.texi: s-targets
+
+s-init: $(MKDOC) $(srcdir)/../init.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../init.c >init.tmp
+ $(srcdir)/../../move-if-change init.tmp init.texi
+ touch s-init
+init.texi: s-init
+
+s-hash: $(MKDOC) $(srcdir)/../hash.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../hash.c >hash.tmp
+ $(srcdir)/../../move-if-change hash.tmp hash.texi
+ touch s-hash
+hash.texi: s-hash
+
+s-linker: $(MKDOC) $(srcdir)/../linker.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../linker.c >linker.tmp
+ $(srcdir)/../../move-if-change linker.tmp linker.texi
+ touch s-linker
+linker.texi: s-linker
+
+libbfd.h: $(srcdir)/../libbfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../cache.c \
+ $(srcdir)/../reloc.c \
+ $(srcdir)/../archures.c \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+ cat $(srcdir)/../libbfd-in.h >libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../init.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../libbfd.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../cache.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../reloc.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../archures.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../elf.c >>libbfd.h
+
+libcoff.h: $(srcdir)/../libcoff-in.h \
+ $(srcdir)/../coffcode.h \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+ cat $(srcdir)/../libcoff-in.h >libcoff.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../coffcode.h >>libcoff.h
+
+bfd.h: $(srcdir)/../bfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../opncls.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../section.c \
+ $(srcdir)/../archures.c \
+ $(srcdir)/../reloc.c \
+ $(srcdir)/../syms.c \
+ $(srcdir)/../bfd.c \
+ $(srcdir)/../archive.c \
+ $(srcdir)/../corefile.c \
+ $(srcdir)/../targets.c \
+ $(srcdir)/../format.c \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+ cat $(srcdir)/../bfd-in.h >bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../init.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../opncls.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../libbfd.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../section.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../archures.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../reloc.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../syms.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../bfd.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../archive.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../corefile.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../targets.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../format.c >>bfd.h
+ echo "#ifdef __cplusplus" >>bfd.h
+ echo "}" >>bfd.h
+ echo "#endif" >>bfd.h
+ echo "#endif" >>bfd.h
+
+noinst_TEXINFOS = bfdint.texi
+
+MOSTLYCLEANFILES = $(MKDOC) *.o
+
+CLEANFILES = s-* *.p *.ip
+
+DISTCLEANFILES = bfd.?? bfd.??? bfd.h libbfd.h libcoff.h texput.log
+
+MAINTAINERCLEANFILES = $(DOCFILES)
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
new file mode 100644
index 00000000000..6295c1002ee
--- /dev/null
+++ b/bfd/doc/Makefile.in
@@ -0,0 +1,600 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AR = @AR@
+AS = @AS@
+BFD_HOST_64BIT_LONG = @BFD_HOST_64BIT_LONG@
+BFD_HOST_64_BIT = @BFD_HOST_64_BIT@
+BFD_HOST_64_BIT_DEFINED = @BFD_HOST_64_BIT_DEFINED@
+BFD_HOST_U_64_BIT = @BFD_HOST_U_64_BIT@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+COREFILE = @COREFILE@
+COREFLAG = @COREFLAG@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+HDEFINES = @HDEFINES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+TDEFINES = @TDEFINES@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
+VERSION = @VERSION@
+WIN32LDFLAGS = @WIN32LDFLAGS@
+WIN32LIBADD = @WIN32LIBADD@
+all_backends = @all_backends@
+bfd_backends = @bfd_backends@
+bfd_machines = @bfd_machines@
+l = @l@
+tdefaults = @tdefaults@
+wordsize = @wordsize@
+
+AUTOMAKE_OPTIONS = cygnus
+
+DOCFILES = aoutx.texi archive.texi archures.texi \
+ bfdt.texi cache.texi coffcode.texi \
+ core.texi elf.texi elfcode.texi format.texi libbfd.texi \
+ opncls.texi reloc.texi section.texi \
+ syms.texi targets.texi init.texi hash.texi linker.texi
+
+
+PROTOS = archive.p archures.p bfd.p \
+ core.p format.p \
+ libbfd.p opncls.p reloc.p \
+ section.p syms.p targets.p \
+ format.p core.p init.p
+
+
+IPROTOS = cache.ip libbfd.ip reloc.ip init.ip archures.ip coffcode.ip
+
+# SRCDOC, SRCPROT, SRCIPROT only used to sidestep Sun Make bug in interaction
+# between VPATH and suffix rules. If you use GNU Make, perhaps other Makes,
+# you don't need these three:
+SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \
+ $(srcdir)/../archures.c $(srcdir)/../bfd.c \
+ $(srcdir)/../cache.c $(srcdir)/../coffcode.h \
+ $(srcdir)/../corefile.c $(srcdir)/../elf.c \
+ $(srcdir)/../elfcode.h $(srcdir)/../format.c \
+ $(srcdir)/../libbfd.c $(srcdir)/../opncls.c \
+ $(srcdir)/../reloc.c $(srcdir)/../section.c \
+ $(srcdir)/../syms.c $(srcdir)/../targets.c \
+ $(srcdir)/../hash.c $(srcdir)/../linker.c
+
+
+SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \
+ $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \
+ $(srcdir)/../format.c $(srcdir)/../libbfd.c \
+ $(srcdir)/../opncls.c $(srcdir)/../reloc.c \
+ $(srcdir)/../section.c $(srcdir)/../syms.c \
+ $(srcdir)/../targets.c $(srcdir)/../init.c
+
+
+SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \
+ $(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \
+ $(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \
+ $(srcdir)/../init.c
+
+
+TEXIDIR = $(srcdir)/../../texinfo/fsf
+
+info_TEXINFOS = bfd.texinfo
+
+MKDOC = chew$(EXEEXT_FOR_BUILD)
+
+noinst_TEXINFOS = bfdint.texi
+
+MOSTLYCLEANFILES = $(MKDOC) *.o
+
+CLEANFILES = s-* *.p *.ip
+
+DISTCLEANFILES = bfd.?? bfd.??? bfd.h libbfd.h libcoff.h texput.log
+
+MAINTAINERCLEANFILES = $(DOCFILES)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi`
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+INFO_DEPS = bfd.info
+DVIS = bfd.dvi
+TEXINFOS = bfd.texinfo
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .dvi .info .ps .texi .texinfo .txi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+bfd.info: bfd.texinfo
+bfd.dvi: bfd.texinfo
+
+
+DVIPS = dvips
+
+.texi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.txi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f bfd.aux bfd.cp bfd.cps bfd.dvi bfd.fn bfd.fns bfd.ky bfd.kys \
+ bfd.ps bfd.log bfd.pg bfd.toc bfd.tp bfd.tps bfd.vr bfd.vrs \
+ bfd.op bfd.tr bfd.cv bfd.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+clean-info: mostlyclean-aminfo
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+info-am: $(INFO_DEPS)
+info: info-am
+dvi-am: $(DVIS)
+dvi: dvi-am
+check-am:
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-info-am:
+install-info: install-info-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-aminfo clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-aminfo distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-aminfo maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: install-info-am uninstall-info mostlyclean-aminfo \
+distclean-aminfo clean-aminfo maintainer-clean-aminfo tags distdir \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-info-am install-info install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+$(MKDOC): chew.o
+ $(CC_FOR_BUILD) -o $(MKDOC) chew.o $(LOADLIBES) $(LDFLAGS)
+
+chew.o: chew.c
+ $(CC_FOR_BUILD) -c -I.. -I$(srcdir)/.. -I$(srcdir)/../../include -I$(srcdir)/../../intl -I../../intl $(H_CFLAGS) $(CFLAGS) $(srcdir)/chew.c
+
+protos: libbfd.h libcoff.h bfd.h
+
+bfd.info bfd.dvi: $(DOCFILES) bfdsumm.texi bfd.texinfo
+
+# We can't replace these rules with an implicit rule, because
+# makes without VPATH support couldn't find the .h files in `..'.
+
+# We use s-XXX targets so that we can distribute the info files,
+# and permit people to rebuild them, without requiring the makeinfo
+# program. If somebody tries to rebuild info, but none of the .texi
+# files have changed, then this Makefile will build chew, and will
+# build all of the stamp files, but will not actually have to rebuild
+# bfd.info.
+
+s-aoutx: $(MKDOC) $(srcdir)/../aoutx.h $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../aoutx.h >aoutx.tmp
+ $(srcdir)/../../move-if-change aoutx.tmp aoutx.texi
+ touch s-aoutx
+aoutx.texi: s-aoutx
+
+s-archive: $(MKDOC) $(srcdir)/../archive.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../archive.c >archive.tmp
+ $(srcdir)/../../move-if-change archive.tmp archive.texi
+ touch s-archive
+archive.texi: s-archive
+
+s-archures: $(MKDOC) $(srcdir)/../archures.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../archures.c >archures.tmp
+ $(srcdir)/../../move-if-change archures.tmp archures.texi
+ touch s-archures
+archures.texi: s-archures
+
+# We use bfdt.texi, rather than bfd.texi, to avoid conflicting with
+# bfd.texinfo on an 8.3 filesystem.
+s-bfd: $(MKDOC) $(srcdir)/../bfd.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../bfd.c >bfd.tmp
+ $(srcdir)/../../move-if-change bfd.tmp bfdt.texi
+ touch s-bfd
+bfdt.texi: s-bfd
+
+s-cache: $(MKDOC) $(srcdir)/../cache.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../cache.c >cache.tmp
+ $(srcdir)/../../move-if-change cache.tmp cache.texi
+ touch s-cache
+cache.texi: s-cache
+
+s-coffcode: $(MKDOC) $(srcdir)/../coffcode.h $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../coffcode.h >coffcode.tmp
+ $(srcdir)/../../move-if-change coffcode.tmp coffcode.texi
+ touch s-coffcode
+coffcode.texi: s-coffcode
+
+s-core: $(MKDOC) $(srcdir)/../corefile.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../corefile.c >core.tmp
+ $(srcdir)/../../move-if-change core.tmp core.texi
+ touch s-core
+core.texi: s-core
+
+s-elf: $(MKDOC) $(srcdir)/../elf.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../elf.c >elf.tmp
+ $(srcdir)/../../move-if-change elf.tmp elf.texi
+ touch s-elf
+elf.texi: s-elf
+
+s-elfcode: $(MKDOC) $(srcdir)/../elfcode.h $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../elfcode.h >elfcode.tmp
+ $(srcdir)/../../move-if-change elfcode.tmp elfcode.texi
+ touch s-elfcode
+elfcode.texi: s-elfcode
+
+s-format: $(MKDOC) $(srcdir)/../format.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../format.c >format.tmp
+ $(srcdir)/../../move-if-change format.tmp format.texi
+ touch s-format
+format.texi: s-format
+
+s-libbfd: $(MKDOC) $(srcdir)/../libbfd.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str < $(srcdir)/../libbfd.c >libbfd.tmp
+ $(srcdir)/../../move-if-change libbfd.tmp libbfd.texi
+ touch s-libbfd
+libbfd.texi: s-libbfd
+
+s-opncls: $(MKDOC) $(srcdir)/../opncls.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../opncls.c >opncls.tmp
+ $(srcdir)/../../move-if-change opncls.tmp opncls.texi
+ touch s-opncls
+opncls.texi: s-opncls
+
+s-reloc: $(MKDOC) $(srcdir)/../reloc.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../reloc.c >reloc.tmp
+ $(srcdir)/../../move-if-change reloc.tmp reloc.texi
+ touch s-reloc
+reloc.texi: s-reloc
+
+s-section: $(MKDOC) $(srcdir)/../section.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../section.c >section.tmp
+ $(srcdir)/../../move-if-change section.tmp section.texi
+ touch s-section
+section.texi: s-section
+
+s-syms: $(MKDOC) $(srcdir)/../syms.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../syms.c >syms.tmp
+ $(srcdir)/../../move-if-change syms.tmp syms.texi
+ touch s-syms
+syms.texi: s-syms
+
+s-targets: $(MKDOC) $(srcdir)/../targets.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../targets.c >targets.tmp
+ $(srcdir)/../../move-if-change targets.tmp targets.texi
+ touch s-targets
+targets.texi: s-targets
+
+s-init: $(MKDOC) $(srcdir)/../init.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../init.c >init.tmp
+ $(srcdir)/../../move-if-change init.tmp init.texi
+ touch s-init
+init.texi: s-init
+
+s-hash: $(MKDOC) $(srcdir)/../hash.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../hash.c >hash.tmp
+ $(srcdir)/../../move-if-change hash.tmp hash.texi
+ touch s-hash
+hash.texi: s-hash
+
+s-linker: $(MKDOC) $(srcdir)/../linker.c $(srcdir)/doc.str
+ ./$(MKDOC) -f $(srcdir)/doc.str <$(srcdir)/../linker.c >linker.tmp
+ $(srcdir)/../../move-if-change linker.tmp linker.texi
+ touch s-linker
+linker.texi: s-linker
+
+libbfd.h: $(srcdir)/../libbfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../cache.c \
+ $(srcdir)/../reloc.c \
+ $(srcdir)/../archures.c \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+ cat $(srcdir)/../libbfd-in.h >libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../init.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../libbfd.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../cache.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../reloc.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../archures.c >>libbfd.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../elf.c >>libbfd.h
+
+libcoff.h: $(srcdir)/../libcoff-in.h \
+ $(srcdir)/../coffcode.h \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+ cat $(srcdir)/../libcoff-in.h >libcoff.h
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $(srcdir)/../coffcode.h >>libcoff.h
+
+bfd.h: $(srcdir)/../bfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../opncls.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../section.c \
+ $(srcdir)/../archures.c \
+ $(srcdir)/../reloc.c \
+ $(srcdir)/../syms.c \
+ $(srcdir)/../bfd.c \
+ $(srcdir)/../archive.c \
+ $(srcdir)/../corefile.c \
+ $(srcdir)/../targets.c \
+ $(srcdir)/../format.c \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+ cat $(srcdir)/../bfd-in.h >bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../init.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../opncls.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../libbfd.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../section.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../archures.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../reloc.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../syms.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../bfd.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../archive.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../corefile.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../targets.c >>bfd.h
+ ./$(MKDOC) -f $(srcdir)/proto.str<$(srcdir)/../format.c >>bfd.h
+ echo "#ifdef __cplusplus" >>bfd.h
+ echo "}" >>bfd.h
+ echo "#endif" >>bfd.h
+ echo "#endif" >>bfd.h
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bfd/doc/bfd.texinfo b/bfd/doc/bfd.texinfo
new file mode 100644
index 00000000000..eadf87cc345
--- /dev/null
+++ b/bfd/doc/bfd.texinfo
@@ -0,0 +1,348 @@
+\input texinfo.tex
+@setfilename bfd.info
+@c $Id$
+@tex
+% NOTE LOCAL KLUGE TO AVOID TOO MUCH WHITESPACE
+\global\long\def\example{%
+\begingroup
+\let\aboveenvbreak=\par
+\let\afterenvbreak=\par
+\parskip=0pt
+\lisp}
+\global\long\def\Eexample{%
+\Elisp
+\endgroup
+\vskip -\parskip% to cancel out effect of following \par
+}
+@end tex
+@synindex fn cp
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Bfd: (bfd). The Binary File Descriptor library.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This file documents the BFD library.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, subject to the terms
+of the GNU General Public License, which includes the provision that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+@iftex
+@c@finalout
+@setchapternewpage on
+@c@setchapternewpage odd
+@settitle LIB BFD, the Binary File Descriptor Library
+@titlepage
+@title{libbfd}
+@subtitle{The Binary File Descriptor Library}
+@sp 1
+@subtitle First Edition---BFD version < 3.0
+@subtitle April 1991
+@author {Steve Chamberlain}
+@author {Cygnus Support}
+@page
+
+@tex
+\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
+\xdef\manvers{\$Revision$} % For use in headers, footers too
+{\parskip=0pt
+\hfill Cygnus Support\par
+\hfill sac\@cygnus.com\par
+\hfill {\it BFD}, \manvers\par
+\hfill \TeX{}info \texinfoversion\par
+}
+\global\parindent=0pt % Steve likes it this way
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1991 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, subject to the terms
+of the GNU General Public License, which includes the provision that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+@end iftex
+
+@node Top, Overview, (dir), (dir)
+@ifinfo
+This file documents the binary file descriptor library libbfd.
+@end ifinfo
+
+@menu
+* Overview:: Overview of BFD
+* BFD front end:: BFD front end
+* BFD back ends:: BFD back ends
+* Index:: Index
+@end menu
+
+@node Overview, BFD front end, Top, Top
+@chapter Introduction
+@cindex BFD
+@cindex what is it?
+BFD is a package which allows applications to use the
+same routines to operate on object files whatever the object file
+format. A new object file format can be supported simply by
+creating a new BFD back end and adding it to the library.
+
+BFD is split into two parts: the front end, and the back ends (one for
+each object file format).
+@itemize @bullet
+@item The front end of BFD provides the interface to the user. It manages
+memory and various canonical data structures. The front end also
+decides which back end to use and when to call back end routines.
+@item The back ends provide BFD its view of the real world. Each back
+end provides a set of calls which the BFD front end can use to maintain
+its canonical form. The back ends also may keep around information for
+their own use, for greater efficiency.
+@end itemize
+@menu
+* History:: History
+* How It Works:: How It Works
+* What BFD Version 2 Can Do:: What BFD Version 2 Can Do
+@end menu
+
+@node History, How It Works, Overview, Overview
+@section History
+
+One spur behind BFD was the desire, on the part of the GNU 960 team at
+Intel Oregon, for interoperability of applications on their COFF and
+b.out file formats. Cygnus was providing GNU support for the team, and
+was contracted to provide the required functionality.
+
+The name came from a conversation David Wallace was having with Richard
+Stallman about the library: RMS said that it would be quite hard---David
+said ``BFD''. Stallman was right, but the name stuck.
+
+At the same time, Ready Systems wanted much the same thing, but for
+different object file formats: IEEE-695, Oasys, Srecords, a.out and 68k
+coff.
+
+BFD was first implemented by members of Cygnus Support; Steve
+Chamberlain (@code{sac@@cygnus.com}), John Gilmore
+(@code{gnu@@cygnus.com}), K. Richard Pixley (@code{rich@@cygnus.com})
+and David Henkel-Wallace (@code{gumby@@cygnus.com}).
+
+
+
+@node How It Works, What BFD Version 2 Can Do, History, Overview
+@section How To Use BFD
+
+To use the library, include @file{bfd.h} and link with @file{libbfd.a}.
+
+BFD provides a common interface to the parts of an object file
+for a calling application.
+
+When an application sucessfully opens a target file (object, archive, or
+whatever), a pointer to an internal structure is returned. This pointer
+points to a structure called @code{bfd}, described in
+@file{bfd.h}. Our convention is to call this pointer a BFD, and
+instances of it within code @code{abfd}. All operations on
+the target object file are applied as methods to the BFD. The mapping is
+defined within @code{bfd.h} in a set of macros, all beginning
+with @samp{bfd_} to reduce namespace pollution.
+
+For example, this sequence does what you would probably expect:
+return the number of sections in an object file attached to a BFD
+@code{abfd}.
+
+@lisp
+@c @cartouche
+#include "bfd.h"
+
+unsigned int number_of_sections(abfd)
+bfd *abfd;
+@{
+ return bfd_count_sections(abfd);
+@}
+@c @end cartouche
+@end lisp
+
+The abstraction used within BFD is that an object file has:
+
+@itemize @bullet
+@item
+a header,
+@item
+a number of sections containing raw data (@pxref{Sections}),
+@item
+a set of relocations (@pxref{Relocations}), and
+@item
+some symbol information (@pxref{Symbols}).
+@end itemize
+@noindent
+Also, BFDs opened for archives have the additional attribute of an index
+and contain subordinate BFDs. This approach is fine for a.out and coff,
+but loses efficiency when applied to formats such as S-records and
+IEEE-695.
+
+@node What BFD Version 2 Can Do, , How It Works, Overview
+@section What BFD Version 2 Can Do
+@include bfdsumm.texi
+
+@node BFD front end, BFD back ends, Overview, Top
+@chapter BFD front end
+@include bfdt.texi
+
+@menu
+* Memory Usage::
+* Initialization::
+* Sections::
+* Symbols::
+* Archives::
+* Formats::
+* Relocations::
+* Core Files::
+* Targets::
+* Architectures::
+* Opening and Closing::
+* Internal::
+* File Caching::
+* Linker Functions::
+* Hash Tables::
+@end menu
+
+@node Memory Usage, Initialization, BFD front end, BFD front end
+@section Memory usage
+BFD keeps all of its internal structures in obstacks. There is one obstack
+per open BFD file, into which the current state is stored. When a BFD is
+closed, the obstack is deleted, and so everything which has been
+allocated by BFD for the closing file is thrown away.
+
+BFD does not free anything created by an application, but pointers into
+@code{bfd} structures become invalid on a @code{bfd_close}; for example,
+after a @code{bfd_close} the vector passed to
+@code{bfd_canonicalize_symtab} is still around, since it has been
+allocated by the application, but the data that it pointed to are
+lost.
+
+The general rule is to not close a BFD until all operations dependent
+upon data from the BFD have been completed, or all the data from within
+the file has been copied. To help with the management of memory, there
+is a function (@code{bfd_alloc_size}) which returns the number of bytes
+in obstacks associated with the supplied BFD. This could be used to
+select the greediest open BFD, close it to reclaim the memory, perform
+some operation and reopen the BFD again, to get a fresh copy of the data
+structures.
+
+@node Initialization, Sections, Memory Usage, BFD front end
+@include init.texi
+
+@node Sections, Symbols, Initialization, BFD front end
+@include section.texi
+
+@node Symbols, Archives, Sections, BFD front end
+@include syms.texi
+
+@node Archives, Formats, Symbols, BFD front end
+@include archive.texi
+
+@node Formats, Relocations, Archives, BFD front end
+@include format.texi
+
+@node Relocations, Core Files, Formats, BFD front end
+@include reloc.texi
+
+@node Core Files, Targets, Relocations, BFD front end
+@include core.texi
+
+@node Targets, Architectures, Core Files, BFD front end
+@include targets.texi
+
+@node Architectures, Opening and Closing, Targets, BFD front end
+@include archures.texi
+
+@node Opening and Closing, Internal, Architectures, BFD front end
+@include opncls.texi
+
+@node Internal, File Caching, Opening and Closing, BFD front end
+@include libbfd.texi
+
+@node File Caching, Linker Functions, Internal, BFD front end
+@include cache.texi
+
+@node Linker Functions, Hash Tables, File Caching, BFD front end
+@include linker.texi
+
+@node Hash Tables, , Linker Functions, BFD front end
+@include hash.texi
+
+@node BFD back ends, Index, BFD front end, Top
+@chapter BFD back ends
+@menu
+* What to Put Where::
+* aout :: a.out backends
+* coff :: coff backends
+* elf :: elf backends
+@ignore
+* oasys :: oasys backends
+* ieee :: ieee backend
+* srecord :: s-record backend
+@end ignore
+@end menu
+@node What to Put Where, aout, BFD back ends, BFD back ends
+All of BFD lives in one directory.
+
+@node aout, coff, What to Put Where, BFD back ends
+@include aoutx.texi
+
+@node coff, elf, aout, BFD back ends
+@include coffcode.texi
+
+@node elf, , coff, BFD back ends
+@include elf.texi
+@c Leave this out until the file has some actual contents...
+@c @include elfcode.texi
+
+@node Index, , BFD back ends , Top
+@unnumbered Index
+@printindex cp
+
+@tex
+% I think something like @colophon should be in texinfo. In the
+% meantime:
+\long\def\colophon{\hbox to0pt{}\vfill
+\centerline{The body of this manual is set in}
+\centerline{\fontname\tenrm,}
+\centerline{with headings in {\bf\fontname\tenbf}}
+\centerline{and examples in {\tt\fontname\tentt}.}
+\centerline{{\it\fontname\tenit\/} and}
+\centerline{{\sl\fontname\tensl\/}}
+\centerline{are used for emphasis.}\vfill}
+\page\colophon
+% Blame: doc@cygnus.com, 28mar91.
+@end tex
+
+@contents
+@bye
diff --git a/bfd/doc/bfdint.texi b/bfd/doc/bfdint.texi
new file mode 100644
index 00000000000..eb09b34a9d2
--- /dev/null
+++ b/bfd/doc/bfdint.texi
@@ -0,0 +1,1885 @@
+\input texinfo
+@setfilename bfdint.info
+
+@settitle BFD Internals
+@iftex
+@titlepage
+@title{BFD Internals}
+@author{Ian Lance Taylor}
+@author{Cygnus Solutions}
+@page
+@end iftex
+
+@node Top
+@top BFD Internals
+@raisesections
+@cindex bfd internals
+
+This document describes some BFD internal information which may be
+helpful when working on BFD. It is very incomplete.
+
+This document is not updated regularly, and may be out of date. It was
+last modified on $Date$.
+
+The initial version of this document was written by Ian Lance Taylor
+@email{ian@@cygnus.com}.
+
+@menu
+* BFD overview:: BFD overview
+* BFD guidelines:: BFD programming guidelines
+* BFD target vector:: BFD target vector
+* BFD generated files:: BFD generated files
+* BFD multiple compilations:: Files compiled multiple times in BFD
+* BFD relocation handling:: BFD relocation handling
+* BFD ELF support:: BFD ELF support
+* BFD glossary:: Glossary
+* Index:: Index
+@end menu
+
+@node BFD overview
+@section BFD overview
+
+BFD is a library which provides a single interface to read and write
+object files, executables, archive files, and core files in any format.
+
+@menu
+* BFD library interfaces:: BFD library interfaces
+* BFD library users:: BFD library users
+* BFD view:: The BFD view of a file
+* BFD blindness:: BFD loses information
+@end menu
+
+@node BFD library interfaces
+@subsection BFD library interfaces
+
+One way to look at the BFD library is to divide it into four parts by
+type of interface.
+
+The first interface is the set of generic functions which programs using
+the BFD library will call. These generic function normally translate
+directly or indirectly into calls to routines which are specific to a
+particular object file format. Many of these generic functions are
+actually defined as macros in @file{bfd.h}. These functions comprise
+the official BFD interface.
+
+The second interface is the set of functions which appear in the target
+vectors. This is the bulk of the code in BFD. A target vector is a set
+of function pointers specific to a particular object file format. The
+target vector is used to implement the generic BFD functions. These
+functions are always called through the target vector, and are never
+called directly. The target vector is described in detail in @ref{BFD
+target vector}. The set of functions which appear in a particular
+target vector is often referred to as a BFD backend.
+
+The third interface is a set of oddball functions which are typically
+specific to a particular object file format, are not generic functions,
+and are called from outside of the BFD library. These are used as hooks
+by the linker and the assembler when a particular object file format
+requires some action which the BFD generic interface does not provide.
+These functions are typically declared in @file{bfd.h}, but in many
+cases they are only provided when BFD is configured with support for a
+particular object file format. These functions live in a grey area, and
+are not really part of the official BFD interface.
+
+The fourth interface is the set of BFD support functions which are
+called by the other BFD functions. These manage issues like memory
+allocation, error handling, file access, hash tables, swapping, and the
+like. These functions are never called from outside of the BFD library.
+
+@node BFD library users
+@subsection BFD library users
+
+Another way to look at the BFD library is to divide it into three parts
+by the manner in which it is used.
+
+The first use is to read an object file. The object file readers are
+programs like @samp{gdb}, @samp{nm}, @samp{objdump}, and @samp{objcopy}.
+These programs use BFD to view an object file in a generic form. The
+official BFD interface is normally fully adequate for these programs.
+
+The second use is to write an object file. The object file writers are
+programs like @samp{gas} and @samp{objcopy}. These programs use BFD to
+create an object file. The official BFD interface is normally adequate
+for these programs, but for some object file formats the assembler needs
+some additional hooks in order to set particular flags or other
+information. The official BFD interface includes functions to copy
+private information from one object file to another, and these functions
+are used by @samp{objcopy} to avoid information loss.
+
+The third use is to link object files. There is only one object file
+linker, @samp{ld}. Originally, @samp{ld} was an object file reader and
+an object file writer, and it did the link operation using the generic
+BFD structures. However, this turned out to be too slow and too memory
+intensive.
+
+The official BFD linker functions were written to permit specific BFD
+backends to perform the link without translating through the generic
+structures, in the normal case where all the input files and output file
+have the same object file format. Not all of the backends currently
+implement the new interface, and there are default linking functions
+within BFD which use the generic structures and which work with all
+backends.
+
+For several object file formats the linker needs additional hooks which
+are not provided by the official BFD interface, particularly for dynamic
+linking support. These functions are typically called from the linker
+emulation template.
+
+@node BFD view
+@subsection The BFD view of a file
+
+BFD uses generic structures to manage information. It translates data
+into the generic form when reading files, and out of the generic form
+when writing files.
+
+BFD describes a file as a pointer to the @samp{bfd} type. A @samp{bfd}
+is composed of the following elements. The BFD information can be
+displayed using the @samp{objdump} program with various options.
+
+@table @asis
+@item general information
+The object file format, a few general flags, the start address.
+@item architecture
+The architecture, including both a general processor type (m68k, MIPS
+etc.) and a specific machine number (m68000, R4000, etc.).
+@item sections
+A list of sections.
+@item symbols
+A symbol table.
+@end table
+
+BFD represents a section as a pointer to the @samp{asection} type. Each
+section has a name and a size. Most sections also have an associated
+block of data, known as the section contents. Sections also have
+associated flags, a virtual memory address, a load memory address, a
+required alignment, a list of relocations, and other miscellaneous
+information.
+
+BFD represents a relocation as a pointer to the @samp{arelent} type. A
+relocation describes an action which the linker must take to modify the
+section contents. Relocations have a symbol, an address, an addend, and
+a pointer to a howto structure which describes how to perform the
+relocation. For more information, see @ref{BFD relocation handling}.
+
+BFD represents a symbol as a pointer to the @samp{asymbol} type. A
+symbol has a name, a pointer to a section, an offset within that
+section, and some flags.
+
+Archive files do not have any sections or symbols. Instead, BFD
+represents an archive file as a file which contains a list of
+@samp{bfd}s. BFD also provides access to the archive symbol map, as a
+list of symbol names. BFD provides a function to return the @samp{bfd}
+within the archive which corresponds to a particular entry in the
+archive symbol map.
+
+@node BFD blindness
+@subsection BFD loses information
+
+Most object file formats have information which BFD can not represent in
+its generic form, at least as currently defined.
+
+There is often explicit information which BFD can not represent. For
+example, the COFF version stamp, or the ELF program segments. BFD
+provides special hooks to handle this information when copying,
+printing, or linking an object file. The BFD support for a particular
+object file format will normally store this information in private data
+and handle it using the special hooks.
+
+In some cases there is also implicit information which BFD can not
+represent. For example, the MIPS processor distinguishes small and
+large symbols, and requires that all small symbls be within 32K of the
+GP register. This means that the MIPS assembler must be able to mark
+variables as either small or large, and the MIPS linker must know to put
+small symbols within range of the GP register. Since BFD can not
+represent this information, this means that the assembler and linker
+must have information that is specific to a particular object file
+format which is outside of the BFD library.
+
+This loss of information indicates areas where the BFD paradigm breaks
+down. It is not actually possible to represent the myriad differences
+among object file formats using a single generic interface, at least not
+in the manner which BFD does it today.
+
+Nevertheless, the BFD library does greatly simplify the task of dealing
+with object files, and particular problems caused by information loss
+can normally be solved using some sort of relatively constrained hook
+into the library.
+
+
+
+@node BFD guidelines
+@section BFD programming guidelines
+@cindex bfd programming guidelines
+@cindex programming guidelines for bfd
+@cindex guidelines, bfd programming
+
+There is a lot of poorly written and confusing code in BFD. New BFD
+code should be written to a higher standard. Merely because some BFD
+code is written in a particular manner does not mean that you should
+emulate it.
+
+Here are some general BFD programming guidelines:
+
+@itemize @bullet
+@item
+Follow the GNU coding standards.
+
+@item
+Avoid global variables. We ideally want BFD to be fully reentrant, so
+that it can be used in multiple threads. All uses of global or static
+variables interfere with that. Initialized constant variables are OK,
+and they should be explicitly marked with const. Instead of global
+variables, use data attached to a BFD or to a linker hash table.
+
+@item
+All externally visible functions should have names which start with
+@samp{bfd_}. All such functions should be declared in some header file,
+typically @file{bfd.h}. See, for example, the various declarations near
+the end of @file{bfd-in.h}, which mostly declare functions required by
+specific linker emulations.
+
+@item
+All functions which need to be visible from one file to another within
+BFD, but should not be visible outside of BFD, should start with
+@samp{_bfd_}. Although external names beginning with @samp{_} are
+prohibited by the ANSI standard, in practice this usage will always
+work, and it is required by the GNU coding standards.
+
+@item
+Always remember that people can compile using @samp{--enable-targets} to
+build several, or all, targets at once. It must be possible to link
+together the files for all targets.
+
+@item
+BFD code should compile with few or no warnings using @samp{gcc -Wall}.
+Some warnings are OK, like the absence of certain function declarations
+which may or may not be declared in system header files. Warnings about
+ambiguous expressions and the like should always be fixed.
+@end itemize
+
+@node BFD target vector
+@section BFD target vector
+@cindex bfd target vector
+@cindex target vector in bfd
+
+BFD supports multiple object file formats by using the @dfn{target
+vector}. This is simply a set of function pointers which implement
+behaviour that is specific to a particular object file format.
+
+In this section I list all of the entries in the target vector and
+describe what they do.
+
+@menu
+* BFD target vector miscellaneous:: Miscellaneous constants
+* BFD target vector swap:: Swapping functions
+* BFD target vector format:: Format type dependent functions
+* BFD_JUMP_TABLE macros:: BFD_JUMP_TABLE macros
+* BFD target vector generic:: Generic functions
+* BFD target vector copy:: Copy functions
+* BFD target vector core:: Core file support functions
+* BFD target vector archive:: Archive functions
+* BFD target vector symbols:: Symbol table functions
+* BFD target vector relocs:: Relocation support
+* BFD target vector write:: Output functions
+* BFD target vector link:: Linker functions
+* BFD target vector dynamic:: Dynamic linking information functions
+@end menu
+
+@node BFD target vector miscellaneous
+@subsection Miscellaneous constants
+
+The target vector starts with a set of constants.
+
+@table @samp
+@item name
+The name of the target vector. This is an arbitrary string. This is
+how the target vector is named in command line options for tools which
+use BFD, such as the @samp{-oformat} linker option.
+
+@item flavour
+A general description of the type of target. The following flavours are
+currently defined:
+
+@table @samp
+@item bfd_target_unknown_flavour
+Undefined or unknown.
+@item bfd_target_aout_flavour
+a.out.
+@item bfd_target_coff_flavour
+COFF.
+@item bfd_target_ecoff_flavour
+ECOFF.
+@item bfd_target_elf_flavour
+ELF.
+@item bfd_target_ieee_flavour
+IEEE-695.
+@item bfd_target_nlm_flavour
+NLM.
+@item bfd_target_oasys_flavour
+OASYS.
+@item bfd_target_tekhex_flavour
+Tektronix hex format.
+@item bfd_target_srec_flavour
+Motorola S-record format.
+@item bfd_target_ihex_flavour
+Intel hex format.
+@item bfd_target_som_flavour
+SOM (used on HP/UX).
+@item bfd_target_os9k_flavour
+os9000.
+@item bfd_target_versados_flavour
+VERSAdos.
+@item bfd_target_msdos_flavour
+MS-DOS.
+@item bfd_target_evax_flavour
+openVMS.
+@end table
+
+@item byteorder
+The byte order of data in the object file. One of
+@samp{BFD_ENDIAN_BIG}, @samp{BFD_ENDIAN_LITTLE}, or
+@samp{BFD_ENDIAN_UNKNOWN}. The latter would be used for a format such
+as S-records which do not record the architecture of the data.
+
+@item header_byteorder
+The byte order of header information in the object file. Normally the
+same as the @samp{byteorder} field, but there are certain cases where it
+may be different.
+
+@item object_flags
+Flags which may appear in the @samp{flags} field of a BFD with this
+format.
+
+@item section_flags
+Flags which may appear in the @samp{flags} field of a section within a
+BFD with this format.
+
+@item symbol_leading_char
+A character which the C compiler normally puts before a symbol. For
+example, an a.out compiler will typically generate the symbol
+@samp{_foo} for a function named @samp{foo} in the C source, in which
+case this field would be @samp{_}. If there is no such character, this
+field will be @samp{0}.
+
+@item ar_pad_char
+The padding character to use at the end of an archive name. Normally
+@samp{/}.
+
+@item ar_max_namelen
+The maximum length of a short name in an archive. Normally @samp{14}.
+
+@item backend_data
+A pointer to constant backend data. This is used by backends to store
+whatever additional information they need to distinguish similar target
+vectors which use the same sets of functions.
+@end table
+
+@node BFD target vector swap
+@subsection Swapping functions
+
+Every target vector has fuction pointers used for swapping information
+in and out of the target representation. There are two sets of
+functions: one for data information, and one for header information.
+Each set has three sizes: 64-bit, 32-bit, and 16-bit. Each size has
+three actual functions: put, get unsigned, and get signed.
+
+These 18 functions are used to convert data between the host and target
+representations.
+
+@node BFD target vector format
+@subsection Format type dependent functions
+
+Every target vector has three arrays of function pointers which are
+indexed by the BFD format type. The BFD format types are as follows:
+
+@table @samp
+@item bfd_unknown
+Unknown format. Not used for anything useful.
+@item bfd_object
+Object file.
+@item bfd_archive
+Archive file.
+@item bfd_core
+Core file.
+@end table
+
+The three arrays of function pointers are as follows:
+
+@table @samp
+@item bfd_check_format
+Check whether the BFD is of a particular format (object file, archive
+file, or core file) corresponding to this target vector. This is called
+by the @samp{bfd_check_format} function when examining an existing BFD.
+If the BFD matches the desired format, this function will initialize any
+format specific information such as the @samp{tdata} field of the BFD.
+This function must be called before any other BFD target vector function
+on a file opened for reading.
+
+@item bfd_set_format
+Set the format of a BFD which was created for output. This is called by
+the @samp{bfd_set_format} function after creating the BFD with a
+function such as @samp{bfd_openw}. This function will initialize format
+specific information required to write out an object file or whatever of
+the given format. This function must be called before any other BFD
+target vector function on a file opened for writing.
+
+@item bfd_write_contents
+Write out the contents of the BFD in the given format. This is called
+by @samp{bfd_close} function for a BFD opened for writing. This really
+should not be an array selected by format type, as the
+@samp{bfd_set_format} function provides all the required information.
+In fact, BFD will fail if a different format is used when calling
+through the @samp{bfd_set_format} and the @samp{bfd_write_contents}
+arrays; fortunately, since @samp{bfd_close} gets it right, this is a
+difficult error to make.
+@end table
+
+@node BFD_JUMP_TABLE macros
+@subsection @samp{BFD_JUMP_TABLE} macros
+@cindex @samp{BFD_JUMP_TABLE}
+
+Most target vectors are defined using @samp{BFD_JUMP_TABLE} macros.
+These macros take a single argument, which is a prefix applied to a set
+of functions. The macros are then used to initialize the fields in the
+target vector.
+
+For example, the @samp{BFD_JUMP_TABLE_RELOCS} macro defines three
+functions: @samp{_get_reloc_upper_bound}, @samp{_canonicalize_reloc},
+and @samp{_bfd_reloc_type_lookup}. A reference like
+@samp{BFD_JUMP_TABLE_RELOCS (foo)} will expand into three functions
+prefixed with @samp{foo}: @samp{foo_get_reloc_upper_found}, etc. The
+@samp{BFD_JUMP_TABLE_RELOCS} macro will be placed such that those three
+functions initialize the appropriate fields in the BFD target vector.
+
+This is done because it turns out that many different target vectors can
+share certain classes of functions. For example, archives are similar
+on most platforms, so most target vectors can use the same archive
+functions. Those target vectors all use @samp{BFD_JUMP_TABLE_ARCHIVE}
+with the same argument, calling a set of functions which is defined in
+@file{archive.c}.
+
+Each of the @samp{BFD_JUMP_TABLE} macros is mentioned below along with
+the description of the function pointers which it defines. The function
+pointers will be described using the name without the prefix which the
+@samp{BFD_JUMP_TABLE} macro defines. This name is normally the same as
+the name of the field in the target vector structure. Any differences
+will be noted.
+
+@node BFD target vector generic
+@subsection Generic functions
+@cindex @samp{BFD_JUMP_TABLE_GENERIC}
+
+The @samp{BFD_JUMP_TABLE_GENERIC} macro is used for some catch all
+functions which don't easily fit into other categories.
+
+@table @samp
+@item _close_and_cleanup
+Free any target specific information associated with the BFD. This is
+called when any BFD is closed (the @samp{bfd_write_contents} function
+mentioned earlier is only called for a BFD opened for writing). Most
+targets use @samp{bfd_alloc} to allocate all target specific
+information, and therefore don't have to do anything in this function.
+This function pointer is typically set to
+@samp{_bfd_generic_close_and_cleanup}, which simply returns true.
+
+@item _bfd_free_cached_info
+Free any cached information associated with the BFD which can be
+recreated later if necessary. This is used to reduce the memory
+consumption required by programs using BFD. This is normally called via
+the @samp{bfd_free_cached_info} macro. It is used by the default
+archive routines when computing the archive map. Most targets do not
+do anything special for this entry point, and just set it to
+@samp{_bfd_generic_free_cached_info}, which simply returns true.
+
+@item _new_section_hook
+This is called from @samp{bfd_make_section_anyway} whenever a new
+section is created. Most targets use it to initialize section specific
+information. This function is called whether or not the section
+corresponds to an actual section in an actual BFD.
+
+@item _get_section_contents
+Get the contents of a section. This is called from
+@samp{bfd_get_section_contents}. Most targets set this to
+@samp{_bfd_generic_get_section_contents}, which does a @samp{bfd_seek}
+based on the section's @samp{filepos} field and a @samp{bfd_read}. The
+corresponding field in the target vector is named
+@samp{_bfd_get_section_contents}.
+
+@item _get_section_contents_in_window
+Set a @samp{bfd_window} to hold the contents of a section. This is
+called from @samp{bfd_get_section_contents_in_window}. The
+@samp{bfd_window} idea never really caught on, and I don't think this is
+ever called. Pretty much all targets implement this as
+@samp{bfd_generic_get_section_contents_in_window}, which uses
+@samp{bfd_get_section_contents} to do the right thing. The
+corresponding field in the target vector is named
+@samp{_bfd_get_section_contents_in_window}.
+@end table
+
+@node BFD target vector copy
+@subsection Copy functions
+@cindex @samp{BFD_JUMP_TABLE_COPY}
+
+The @samp{BFD_JUMP_TABLE_COPY} macro is used for functions which are
+called when copying BFDs, and for a couple of functions which deal with
+internal BFD information.
+
+@table @samp
+@item _bfd_copy_private_bfd_data
+This is called when copying a BFD, via @samp{bfd_copy_private_bfd_data}.
+If the input and output BFDs have the same format, this will copy any
+private information over. This is called after all the section contents
+have been written to the output file. Only a few targets do anything in
+this function.
+
+@item _bfd_merge_private_bfd_data
+This is called when linking, via @samp{bfd_merge_private_bfd_data}. It
+gives the backend linker code a chance to set any special flags in the
+output file based on the contents of the input file. Only a few targets
+do anything in this function.
+
+@item _bfd_copy_private_section_data
+This is similar to @samp{_bfd_copy_private_bfd_data}, but it is called
+for each section, via @samp{bfd_copy_private_section_data}. This
+function is called before any section contents have been written. Only
+a few targets do anything in this function.
+
+@item _bfd_copy_private_symbol_data
+This is called via @samp{bfd_copy_private_symbol_data}, but I don't
+think anything actually calls it. If it were defined, it could be used
+to copy private symbol data from one BFD to another. However, most BFDs
+store extra symbol information by allocating space which is larger than
+the @samp{asymbol} structure and storing private information in the
+extra space. Since @samp{objcopy} and other programs copy symbol
+information by copying pointers to @samp{asymbol} structures, the
+private symbol information is automatically copied as well. Most
+targets do not do anything in this function.
+
+@item _bfd_set_private_flags
+This is called via @samp{bfd_set_private_flags}. It is basically a hook
+for the assembler to set magic information. For example, the PowerPC
+ELF assembler uses it to set flags which appear in the e_flags field of
+the ELF header. Most targets do not do anything in this function.
+
+@item _bfd_print_private_bfd_data
+This is called by @samp{objdump} when the @samp{-p} option is used. It
+is called via @samp{bfd_print_private_data}. It prints any interesting
+information about the BFD which can not be otherwise represented by BFD
+and thus can not be printed by @samp{objdump}. Most targets do not do
+anything in this function.
+@end table
+
+@node BFD target vector core
+@subsection Core file support functions
+@cindex @samp{BFD_JUMP_TABLE_CORE}
+
+The @samp{BFD_JUMP_TABLE_CORE} macro is used for functions which deal
+with core files. Obviously, these functions only do something
+interesting for targets which have core file support.
+
+@table @samp
+@item _core_file_failing_command
+Given a core file, this returns the command which was run to produce the
+core file.
+
+@item _core_file_failing_signal
+Given a core file, this returns the signal number which produced the
+core file.
+
+@item _core_file_matches_executable_p
+Given a core file and a BFD for an executable, this returns whether the
+core file was generated by the executable.
+@end table
+
+@node BFD target vector archive
+@subsection Archive functions
+@cindex @samp{BFD_JUMP_TABLE_ARCHIVE}
+
+The @samp{BFD_JUMP_TABLE_ARCHIVE} macro is used for functions which deal
+with archive files. Most targets use COFF style archive files
+(including ELF targets), and these use @samp{_bfd_archive_coff} as the
+argument to @samp{BFD_JUMP_TABLE_ARCHIVE}. Some targets use BSD/a.out
+style archives, and these use @samp{_bfd_archive_bsd}. (The main
+difference between BSD and COFF archives is the format of the archive
+symbol table). Targets with no archive support use
+@samp{_bfd_noarchive}. Finally, a few targets have unusual archive
+handling.
+
+@table @samp
+@item _slurp_armap
+Read in the archive symbol table, storing it in private BFD data. This
+is normally called from the archive @samp{check_format} routine. The
+corresponding field in the target vector is named
+@samp{_bfd_slurp_armap}.
+
+@item _slurp_extended_name_table
+Read in the extended name table from the archive, if there is one,
+storing it in private BFD data. This is normally called from the
+archive @samp{check_format} routine. The corresponding field in the
+target vector is named @samp{_bfd_slurp_extended_name_table}.
+
+@item construct_extended_name_table
+Build and return an extended name table if one is needed to write out
+the archive. This also adjusts the archive headers to refer to the
+extended name table appropriately. This is normally called from the
+archive @samp{write_contents} routine. The corresponding field in the
+target vector is named @samp{_bfd_construct_extended_name_table}.
+
+@item _truncate_arname
+This copies a file name into an archive header, truncating it as
+required. It is normally called from the archive @samp{write_contents}
+routine. This function is more interesting in targets which do not
+support extended name tables, but I think the GNU @samp{ar} program
+always uses extended name tables anyhow. The corresponding field in the
+target vector is named @samp{_bfd_truncate_arname}.
+
+@item _write_armap
+Write out the archive symbol table using calls to @samp{bfd_write}.
+This is normally called from the archive @samp{write_contents} routine.
+The corresponding field in the target vector is named @samp{write_armap}
+(no leading underscore).
+
+@item _read_ar_hdr
+Read and parse an archive header. This handles expanding the archive
+header name into the real file name using the extended name table. This
+is called by routines which read the archive symbol table or the archive
+itself. The corresponding field in the target vector is named
+@samp{_bfd_read_ar_hdr_fn}.
+
+@item _openr_next_archived_file
+Given an archive and a BFD representing a file stored within the
+archive, return a BFD for the next file in the archive. This is called
+via @samp{bfd_openr_next_archived_file}. The corresponding field in the
+target vector is named @samp{openr_next_archived_file} (no leading
+underscore).
+
+@item _get_elt_at_index
+Given an archive and an index, return a BFD for the file in the archive
+corresponding to that entry in the archive symbol table. This is called
+via @samp{bfd_get_elt_at_index}. The corresponding field in the target
+vector is named @samp{_bfd_get_elt_at_index}.
+
+@item _generic_stat_arch_elt
+Do a stat on an element of an archive, returning information read from
+the archive header (modification time, uid, gid, file mode, size). This
+is called via @samp{bfd_stat_arch_elt}. The corresponding field in the
+target vector is named @samp{_bfd_stat_arch_elt}.
+
+@item _update_armap_timestamp
+After the entire contents of an archive have been written out, update
+the timestamp of the archive symbol table to be newer than that of the
+file. This is required for a.out style archives. This is normally
+called by the archive @samp{write_contents} routine. The corresponding
+field in the target vector is named @samp{_bfd_update_armap_timestamp}.
+@end table
+
+@node BFD target vector symbols
+@subsection Symbol table functions
+@cindex @samp{BFD_JUMP_TABLE_SYMBOLS}
+
+The @samp{BFD_JUMP_TABLE_SYMBOLS} macro is used for functions which deal
+with symbols.
+
+@table @samp
+@item _get_symtab_upper_bound
+Return a sensible upper bound on the amount of memory which will be
+required to read the symbol table. In practice most targets return the
+amount of memory required to hold @samp{asymbol} pointers for all the
+symbols plus a trailing @samp{NULL} entry, and store the actual symbol
+information in BFD private data. This is called via
+@samp{bfd_get_symtab_upper_bound}. The corresponding field in the
+target vector is named @samp{_bfd_get_symtab_upper_bound}.
+
+@item _get_symtab
+Read in the symbol table. This is called via
+@samp{bfd_canonicalize_symtab}. The corresponding field in the target
+vector is named @samp{_bfd_canonicalize_symtab}.
+
+@item _make_empty_symbol
+Create an empty symbol for the BFD. This is needed because most targets
+store extra information with each symbol by allocating a structure
+larger than an @samp{asymbol} and storing the extra information at the
+end. This function will allocate the right amount of memory, and return
+what looks like a pointer to an empty @samp{asymbol}. This is called
+via @samp{bfd_make_empty_symbol}. The corresponding field in the target
+vector is named @samp{_bfd_make_empty_symbol}.
+
+@item _print_symbol
+Print information about the symbol. This is called via
+@samp{bfd_print_symbol}. One of the arguments indicates what sort of
+information should be printed:
+
+@table @samp
+@item bfd_print_symbol_name
+Just print the symbol name.
+@item bfd_print_symbol_more
+Print the symbol name and some interesting flags. I don't think
+anything actually uses this.
+@item bfd_print_symbol_all
+Print all information about the symbol. This is used by @samp{objdump}
+when run with the @samp{-t} option.
+@end table
+The corresponding field in the target vector is named
+@samp{_bfd_print_symbol}.
+
+@item _get_symbol_info
+Return a standard set of information about the symbol. This is called
+via @samp{bfd_symbol_info}. The corresponding field in the target
+vector is named @samp{_bfd_get_symbol_info}.
+
+@item _bfd_is_local_label_name
+Return whether the given string would normally represent the name of a
+local label. This is called via @samp{bfd_is_local_label} and
+@samp{bfd_is_local_label_name}. Local labels are normally discarded by
+the assembler. In the linker, this defines the difference between the
+@samp{-x} and @samp{-X} options.
+
+@item _get_lineno
+Return line number information for a symbol. This is only meaningful
+for a COFF target. This is called when writing out COFF line numbers.
+
+@item _find_nearest_line
+Given an address within a section, use the debugging information to find
+the matching file name, function name, and line number, if any. This is
+called via @samp{bfd_find_nearest_line}. The corresponding field in the
+target vector is named @samp{_bfd_find_nearest_line}.
+
+@item _bfd_make_debug_symbol
+Make a debugging symbol. This is only meaningful for a COFF target,
+where it simply returns a symbol which will be placed in the
+@samp{N_DEBUG} section when it is written out. This is called via
+@samp{bfd_make_debug_symbol}.
+
+@item _read_minisymbols
+Minisymbols are used to reduce the memory requirements of programs like
+@samp{nm}. A minisymbol is a cookie pointing to internal symbol
+information which the caller can use to extract complete symbol
+information. This permits BFD to not convert all the symbols into
+generic form, but to instead convert them one at a time. This is called
+via @samp{bfd_read_minisymbols}. Most targets do not implement this,
+and just use generic support which is based on using standard
+@samp{asymbol} structures.
+
+@item _minisymbol_to_symbol
+Convert a minisymbol to a standard @samp{asymbol}. This is called via
+@samp{bfd_minisymbol_to_symbol}.
+@end table
+
+@node BFD target vector relocs
+@subsection Relocation support
+@cindex @samp{BFD_JUMP_TABLE_RELOCS}
+
+The @samp{BFD_JUMP_TABLE_RELOCS} macro is used for functions which deal
+with relocations.
+
+@table @samp
+@item _get_reloc_upper_bound
+Return a sensible upper bound on the amount of memory which will be
+required to read the relocations for a section. In practice most
+targets return the amount of memory required to hold @samp{arelent}
+pointers for all the relocations plus a trailing @samp{NULL} entry, and
+store the actual relocation information in BFD private data. This is
+called via @samp{bfd_get_reloc_upper_bound}.
+
+@item _canonicalize_reloc
+Return the relocation information for a section. This is called via
+@samp{bfd_canonicalize_reloc}. The corresponding field in the target
+vector is named @samp{_bfd_canonicalize_reloc}.
+
+@item _bfd_reloc_type_lookup
+Given a relocation code, return the corresponding howto structure
+(@pxref{BFD relocation codes}). This is called via
+@samp{bfd_reloc_type_lookup}. The corresponding field in the target
+vector is named @samp{reloc_type_lookup}.
+@end table
+
+@node BFD target vector write
+@subsection Output functions
+@cindex @samp{BFD_JUMP_TABLE_WRITE}
+
+The @samp{BFD_JUMP_TABLE_WRITE} macro is used for functions which deal
+with writing out a BFD.
+
+@table @samp
+@item _set_arch_mach
+Set the architecture and machine number for a BFD. This is called via
+@samp{bfd_set_arch_mach}. Most targets implement this by calling
+@samp{bfd_default_set_arch_mach}. The corresponding field in the target
+vector is named @samp{_bfd_set_arch_mach}.
+
+@item _set_section_contents
+Write out the contents of a section. This is called via
+@samp{bfd_set_section_contents}. The corresponding field in the target
+vector is named @samp{_bfd_set_section_contents}.
+@end table
+
+@node BFD target vector link
+@subsection Linker functions
+@cindex @samp{BFD_JUMP_TABLE_LINK}
+
+The @samp{BFD_JUMP_TABLE_LINK} macro is used for functions called by the
+linker.
+
+@table @samp
+@item _sizeof_headers
+Return the size of the header information required for a BFD. This is
+used to implement the @samp{SIZEOF_HEADERS} linker script function. It
+is normally used to align the first section at an efficient position on
+the page. This is called via @samp{bfd_sizeof_headers}. The
+corresponding field in the target vector is named
+@samp{_bfd_sizeof_headers}.
+
+@item _bfd_get_relocated_section_contents
+Read the contents of a section and apply the relocation information.
+This handles both a final link and a relocateable link; in the latter
+case, it adjust the relocation information as well. This is called via
+@samp{bfd_get_relocated_section_contents}. Most targets implement it by
+calling @samp{bfd_generic_get_relocated_section_contents}.
+
+@item _bfd_relax_section
+Try to use relaxation to shrink the size of a section. This is called
+by the linker when the @samp{-relax} option is used. This is called via
+@samp{bfd_relax_section}. Most targets do not support any sort of
+relaxation.
+
+@item _bfd_link_hash_table_create
+Create the symbol hash table to use for the linker. This linker hook
+permits the backend to control the size and information of the elements
+in the linker symbol hash table. This is called via
+@samp{bfd_link_hash_table_create}.
+
+@item _bfd_link_add_symbols
+Given an object file or an archive, add all symbols into the linker
+symbol hash table. Use callbacks to the linker to include archive
+elements in the link. This is called via @samp{bfd_link_add_symbols}.
+
+@item _bfd_final_link
+Finish the linking process. The linker calls this hook after all of the
+input files have been read, when it is ready to finish the link and
+generate the output file. This is called via @samp{bfd_final_link}.
+
+@item _bfd_link_split_section
+I don't know what this is for. Nothing seems to call it. The only
+non-trivial definition is in @file{som.c}.
+@end table
+
+@node BFD target vector dynamic
+@subsection Dynamic linking information functions
+@cindex @samp{BFD_JUMP_TABLE_DYNAMIC}
+
+The @samp{BFD_JUMP_TABLE_DYNAMIC} macro is used for functions which read
+dynamic linking information.
+
+@table @samp
+@item _get_dynamic_symtab_upper_bound
+Return a sensible upper bound on the amount of memory which will be
+required to read the dynamic symbol table. In practice most targets
+return the amount of memory required to hold @samp{asymbol} pointers for
+all the symbols plus a trailing @samp{NULL} entry, and store the actual
+symbol information in BFD private data. This is called via
+@samp{bfd_get_dynamic_symtab_upper_bound}. The corresponding field in
+the target vector is named @samp{_bfd_get_dynamic_symtab_upper_bound}.
+
+@item _canonicalize_dynamic_symtab
+Read the dynamic symbol table. This is called via
+@samp{bfd_canonicalize_dynamic_symtab}. The corresponding field in the
+target vector is named @samp{_bfd_canonicalize_dynamic_symtab}.
+
+@item _get_dynamic_reloc_upper_bound
+Return a sensible upper bound on the amount of memory which will be
+required to read the dynamic relocations. In practice most targets
+return the amount of memory required to hold @samp{arelent} pointers for
+all the relocations plus a trailing @samp{NULL} entry, and store the
+actual relocation information in BFD private data. This is called via
+@samp{bfd_get_dynamic_reloc_upper_bound}. The corresponding field in
+the target vector is named @samp{_bfd_get_dynamic_reloc_upper_bound}.
+
+@item _canonicalize_dynamic_reloc
+Read the dynamic relocations. This is called via
+@samp{bfd_canonicalize_dynamic_reloc}. The corresponding field in the
+target vector is named @samp{_bfd_canonicalize_dynamic_reloc}.
+@end table
+
+@node BFD generated files
+@section BFD generated files
+@cindex generated files in bfd
+@cindex bfd generated files
+
+BFD contains several automatically generated files. This section
+describes them. Some files are created at configure time, when you
+configure BFD. Some files are created at make time, when you build
+time. Some files are automatically rebuilt at make time, but only if
+you configure with the @samp{--enable-maintainer-mode} option. Some
+files live in the object directory---the directory from which you run
+configure---and some live in the source directory. All files that live
+in the source directory are checked into the CVS repository.
+
+@table @file
+@item bfd.h
+@cindex @file{bfd.h}
+@cindex @file{bfd-in3.h}
+Lives in the object directory. Created at make time from
+@file{bfd-in2.h} via @file{bfd-in3.h}. @file{bfd-in3.h} is created at
+configure time from @file{bfd-in2.h}. There are automatic dependencies
+to rebuild @file{bfd-in3.h} and hence @file{bfd.h} if @file{bfd-in2.h}
+changes, so you can normally ignore @file{bfd-in3.h}, and just think
+about @file{bfd-in2.h} and @file{bfd.h}.
+
+@file{bfd.h} is built by replacing a few strings in @file{bfd-in2.h}.
+To see them, search for @samp{@@} in @file{bfd-in2.h}. They mainly
+control whether BFD is built for a 32 bit target or a 64 bit target.
+
+@item bfd-in2.h
+@cindex @file{bfd-in2.h}
+Lives in the source directory. Created from @file{bfd-in.h} and several
+other BFD source files. If you configure with the
+@samp{--enable-maintainer-mode} option, @file{bfd-in2.h} is rebuilt
+automatically when a source file changes.
+
+@item elf32-target.h
+@itemx elf64-target.h
+@cindex @file{elf32-target.h}
+@cindex @file{elf64-target.h}
+Live in the object directory. Created from @file{elfxx-target.h}.
+These files are versions of @file{elfxx-target.h} customized for either
+a 32 bit ELF target or a 64 bit ELF target.
+
+@item libbfd.h
+@cindex @file{libbfd.h}
+Lives in the source directory. Created from @file{libbfd-in.h} and
+several other BFD source files. If you configure with the
+@samp{--enable-maintainer-mode} option, @file{libbfd.h} is rebuilt
+automatically when a source file changes.
+
+@item libcoff.h
+@cindex @file{libcoff.h}
+Lives in the source directory. Created from @file{libcoff-in.h} and
+@file{coffcode.h}. If you configure with the
+@samp{--enable-maintainer-mode} option, @file{libcoff.h} is rebuilt
+automatically when a source file changes.
+
+@item targmatch.h
+@cindex @file{targmatch.h}
+Lives in the object directory. Created at make time from
+@file{config.bfd}. This file is used to map configuration triplets into
+BFD target vector variable names at run time.
+@end table
+
+@node BFD multiple compilations
+@section Files compiled multiple times in BFD
+Several files in BFD are compiled multiple times. By this I mean that
+there are header files which contain function definitions. These header
+files are included by other files, and thus the functions are compiled
+once per file which includes them.
+
+Preprocessor macros are used to control the compilation, so that each
+time the files are compiled the resulting functions are slightly
+different. Naturally, if they weren't different, there would be no
+reason to compile them multiple times.
+
+This is a not a particularly good programming technique, and future BFD
+work should avoid it.
+
+@itemize @bullet
+@item
+Since this technique is rarely used, even experienced C programmers find
+it confusing.
+
+@item
+It is difficult to debug programs which use BFD, since there is no way
+to describe which version of a particular function you are looking at.
+
+@item
+Programs which use BFD wind up incorporating two or more slightly
+different versions of the same function, which wastes space in the
+executable.
+
+@item
+This technique is never required nor is it especially efficient. It is
+always possible to use statically initialized structures holding
+function pointers and magic constants instead.
+@end itemize
+
+The following is a list of the files which are compiled multiple times.
+
+@table @file
+@item aout-target.h
+@cindex @file{aout-target.h}
+Describes a few functions and the target vector for a.out targets. This
+is used by individual a.out targets with different definitions of
+@samp{N_TXTADDR} and similar a.out macros.
+
+@item aoutf1.h
+@cindex @file{aoutf1.h}
+Implements standard SunOS a.out files. In principle it supports 64 bit
+a.out targets based on the preprocessor macro @samp{ARCH_SIZE}, but
+since all known a.out targets are 32 bits, this code may or may not
+work. This file is only included by a few other files, and it is
+difficult to justify its existence.
+
+@item aoutx.h
+@cindex @file{aoutx.h}
+Implements basic a.out support routines. This file can be compiled for
+either 32 or 64 bit support. Since all known a.out targets are 32 bits,
+the 64 bit support may or may not work. I believe the original
+intention was that this file would only be included by @samp{aout32.c}
+and @samp{aout64.c}, and that other a.out targets would simply refer to
+the functions it defined. Unfortunately, some other a.out targets
+started including it directly, leading to a somewhat confused state of
+affairs.
+
+@item coffcode.h
+@cindex @file{coffcode.h}
+Implements basic COFF support routines. This file is included by every
+COFF target. It implements code which handles COFF magic numbers as
+well as various hook functions called by the generic COFF functions in
+@file{coffgen.c}. This file is controlled by a number of different
+macros, and more are added regularly.
+
+@item coffswap.h
+@cindex @file{coffswap.h}
+Implements COFF swapping routines. This file is included by
+@file{coffcode.h}, and thus by every COFF target. It implements the
+routines which swap COFF structures between internal and external
+format. The main control for this file is the external structure
+definitions in the files in the @file{include/coff} directory. A COFF
+target file will include one of those files before including
+@file{coffcode.h} and thus @file{coffswap.h}. There are a few other
+macros which affect @file{coffswap.h} as well, mostly describing whether
+certain fields are present in the external structures.
+
+@item ecoffswap.h
+@cindex @file{ecoffswap.h}
+Implements ECOFF swapping routines. This is like @file{coffswap.h}, but
+for ECOFF. It is included by the ECOFF target files (of which there are
+only two). The control is the preprocessor macro @samp{ECOFF_32} or
+@samp{ECOFF_64}.
+
+@item elfcode.h
+@cindex @file{elfcode.h}
+Implements ELF functions that use external structure definitions. This
+file is included by two other files: @file{elf32.c} and @file{elf64.c}.
+It is controlled by the @samp{ARCH_SIZE} macro which is defined to be
+@samp{32} or @samp{64} before including it. The @samp{NAME} macro is
+used internally to give the functions different names for the two target
+sizes.
+
+@item elfcore.h
+@cindex @file{elfcore.h}
+Like @file{elfcode.h}, but for functions that are specific to ELF core
+files. This is included only by @file{elfcode.h}.
+
+@item elflink.h
+@cindex @file{elflink.h}
+Like @file{elfcode.h}, but for functions used by the ELF linker. This
+is included only by @file{elfcode.h}.
+
+@item elfxx-target.h
+@cindex @file{elfxx-target.h}
+This file is the source for the generated files @file{elf32-target.h}
+and @file{elf64-target.h}, one of which is included by every ELF target.
+It defines the ELF target vector.
+
+@item freebsd.h
+@cindex @file{freebsd.h}
+Presumably intended to be included by all FreeBSD targets, but in fact
+there is only one such target, @samp{i386-freebsd}. This defines a
+function used to set the right magic number for FreeBSD, as well as
+various macros, and includes @file{aout-target.h}.
+
+@item netbsd.h
+@cindex @file{netbsd.h}
+Like @file{freebsd.h}, except that there are several files which include
+it.
+
+@item nlm-target.h
+@cindex @file{nlm-target.h}
+Defines the target vector for a standard NLM target.
+
+@item nlmcode.h
+@cindex @file{nlmcode.h}
+Like @file{elfcode.h}, but for NLM targets. This is only included by
+@file{nlm32.c} and @file{nlm64.c}, both of which define the macro
+@samp{ARCH_SIZE} to an appropriate value. There are no 64 bit NLM
+targets anyhow, so this is sort of useless.
+
+@item nlmswap.h
+@cindex @file{nlmswap.h}
+Like @file{coffswap.h}, but for NLM targets. This is included by each
+NLM target, but I think it winds up compiling to the exact same code for
+every target, and as such is fairly useless.
+
+@item peicode.h
+@cindex @file{peicode.h}
+Provides swapping routines and other hooks for PE targets.
+@file{coffcode.h} will include this rather than @file{coffswap.h} for a
+PE target. This defines PE specific versions of the COFF swapping
+routines, and also defines some macros which control @file{coffcode.h}
+itself.
+@end table
+
+@node BFD relocation handling
+@section BFD relocation handling
+@cindex bfd relocation handling
+@cindex relocations in bfd
+
+The handling of relocations is one of the more confusing aspects of BFD.
+Relocation handling has been implemented in various different ways, all
+somewhat incompatible, none perfect.
+
+@menu
+* BFD relocation concepts:: BFD relocation concepts
+* BFD relocation functions:: BFD relocation functions
+* BFD relocation codes:: BFD relocation codes
+* BFD relocation future:: BFD relocation future
+@end menu
+
+@node BFD relocation concepts
+@subsection BFD relocation concepts
+
+A relocation is an action which the linker must take when linking. It
+describes a change to the contents of a section. The change is normally
+based on the final value of one or more symbols. Relocations are
+created by the assembler when it creates an object file.
+
+Most relocations are simple. A typical simple relocation is to set 32
+bits at a given offset in a section to the value of a symbol. This type
+of relocation would be generated for code like @code{int *p = &i;} where
+@samp{p} and @samp{i} are global variables. A relocation for the symbol
+@samp{i} would be generated such that the linker would initialize the
+area of memory which holds the value of @samp{p} to the value of the
+symbol @samp{i}.
+
+Slightly more complex relocations may include an addend, which is a
+constant to add to the symbol value before using it. In some cases a
+relocation will require adding the symbol value to the existing contents
+of the section in the object file. In others the relocation will simply
+replace the contents of the section with the symbol value. Some
+relocations are PC relative, so that the value to be stored in the
+section is the difference between the value of a symbol and the final
+address of the section contents.
+
+In general, relocations can be arbitrarily complex. For example,
+relocations used in dynamic linking systems often require the linker to
+allocate space in a different section and use the offset within that
+section as the value to store. In the IEEE object file format,
+relocations may involve arbitrary expressions.
+
+When doing a relocateable link, the linker may or may not have to do
+anything with a relocation, depending upon the definition of the
+relocation. Simple relocations generally do not require any special
+action.
+
+@node BFD relocation functions
+@subsection BFD relocation functions
+
+In BFD, each section has an array of @samp{arelent} structures. Each
+structure has a pointer to a symbol, an address within the section, an
+addend, and a pointer to a @samp{reloc_howto_struct} structure. The
+howto structure has a bunch of fields describing the reloc, including a
+type field. The type field is specific to the object file format
+backend; none of the generic code in BFD examines it.
+
+Originally, the function @samp{bfd_perform_relocation} was supposed to
+handle all relocations. In theory, many relocations would be simple
+enough to be described by the fields in the howto structure. For those
+that weren't, the howto structure included a @samp{special_function}
+field to use as an escape.
+
+While this seems plausible, a look at @samp{bfd_perform_relocation}
+shows that it failed. The function has odd special cases. Some of the
+fields in the howto structure, such as @samp{pcrel_offset}, were not
+adequately documented.
+
+The linker uses @samp{bfd_perform_relocation} to do all relocations when
+the input and output file have different formats (e.g., when generating
+S-records). The generic linker code, which is used by all targets which
+do not define their own special purpose linker, uses
+@samp{bfd_get_relocated_section_contents}, which for most targets turns
+into a call to @samp{bfd_generic_get_relocated_section_contents}, which
+calls @samp{bfd_perform_relocation}. So @samp{bfd_perform_relocation}
+is still widely used, which makes it difficult to change, since it is
+difficult to test all possible cases.
+
+The assembler used @samp{bfd_perform_relocation} for a while. This
+turned out to be the wrong thing to do, since
+@samp{bfd_perform_relocation} was written to handle relocations on an
+existing object file, while the assembler needed to create relocations
+in a new object file. The assembler was changed to use the new function
+@samp{bfd_install_relocation} instead, and @samp{bfd_install_relocation}
+was created as a copy of @samp{bfd_perform_relocation}.
+
+Unfortunately, the work did not progress any farther, so
+@samp{bfd_install_relocation} remains a simple copy of
+@samp{bfd_perform_relocation}, with all the odd special cases and
+confusing code. This again is difficult to change, because again any
+change can affect any assembler target, and so is difficult to test.
+
+The new linker, when using the same object file format for all input
+files and the output file, does not convert relocations into
+@samp{arelent} structures, so it can not use
+@samp{bfd_perform_relocation} at all. Instead, users of the new linker
+are expected to write a @samp{relocate_section} function which will
+handle relocations in a target specific fashion.
+
+There are two helper functions for target specific relocation:
+@samp{_bfd_final_link_relocate} and @samp{_bfd_relocate_contents}.
+These functions use a howto structure, but they @emph{do not} use the
+@samp{special_function} field. Since the functions are normally called
+from target specific code, the @samp{special_function} field adds
+little; any relocations which require special handling can be handled
+without calling those functions.
+
+So, if you want to add a new target, or add a new relocation to an
+existing target, you need to do the following:
+
+@itemize @bullet
+@item
+Make sure you clearly understand what the contents of the section should
+look like after assembly, after a relocateable link, and after a final
+link. Make sure you clearly understand the operations the linker must
+perform during a relocateable link and during a final link.
+
+@item
+Write a howto structure for the relocation. The howto structure is
+flexible enough to represent any relocation which should be handled by
+setting a contiguous bitfield in the destination to the value of a
+symbol, possibly with an addend, possibly adding the symbol value to the
+value already present in the destination.
+
+@item
+Change the assembler to generate your relocation. The assembler will
+call @samp{bfd_install_relocation}, so your howto structure has to be
+able to handle that. You may need to set the @samp{special_function}
+field to handle assembly correctly. Be careful to ensure that any code
+you write to handle the assembler will also work correctly when doing a
+relocateable link. For example, see @samp{bfd_elf_generic_reloc}.
+
+@item
+Test the assembler. Consider the cases of relocation against an
+undefined symbol, a common symbol, a symbol defined in the object file
+in the same section, and a symbol defined in the object file in a
+different section. These cases may not all be applicable for your
+reloc.
+
+@item
+If your target uses the new linker, which is recommended, add any
+required handling to the target specific relocation function. In simple
+cases this will just involve a call to @samp{_bfd_final_link_relocate}
+or @samp{_bfd_relocate_contents}, depending upon the definition of the
+relocation and whether the link is relocateable or not.
+
+@item
+Test the linker. Test the case of a final link. If the relocation can
+overflow, use a linker script to force an overflow and make sure the
+error is reported correctly. Test a relocateable link, whether the
+symbol is defined or undefined in the relocateable output. For both the
+final and relocateable link, test the case when the symbol is a common
+symbol, when the symbol looked like a common symbol but became a defined
+symbol, when the symbol is defined in a different object file, and when
+the symbol is defined in the same object file.
+
+@item
+In order for linking to another object file format, such as S-records,
+to work correctly, @samp{bfd_perform_relocation} has to do the right
+thing for the relocation. You may need to set the
+@samp{special_function} field to handle this correctly. Test this by
+doing a link in which the output object file format is S-records.
+
+@item
+Using the linker to generate relocateable output in a different object
+file format is impossible in the general case, so you generally don't
+have to worry about that. Linking input files of different object file
+formats together is quite unusual, but if you're really dedicated you
+may want to consider testing this case, both when the output object file
+format is the same as your format, and when it is different.
+@end itemize
+
+@node BFD relocation codes
+@subsection BFD relocation codes
+
+BFD has another way of describing relocations besides the howto
+structures described above: the enum @samp{bfd_reloc_code_real_type}.
+
+Every known relocation type can be described as a value in this
+enumeration. The enumeration contains many target specific relocations,
+but where two or more targets have the same relocation, a single code is
+used. For example, the single value @samp{BFD_RELOC_32} is used for all
+simple 32 bit relocation types.
+
+The main purpose of this relocation code is to give the assembler some
+mechanism to create @samp{arelent} structures. In order for the
+assembler to create an @samp{arelent} structure, it has to be able to
+obtain a howto structure. The function @samp{bfd_reloc_type_lookup},
+which simply calls the target vector entry point
+@samp{reloc_type_lookup}, takes a relocation code and returns a howto
+structure.
+
+The function @samp{bfd_get_reloc_code_name} returns the name of a
+relocation code. This is mainly used in error messages.
+
+Using both howto structures and relocation codes can be somewhat
+confusing. There are many processor specific relocation codes.
+However, the relocation is only fully defined by the howto structure.
+The same relocation code will map to different howto structures in
+different object file formats. For example, the addend handling may be
+different.
+
+Most of the relocation codes are not really general. The assembler can
+not use them without already understanding what sorts of relocations can
+be used for a particular target. It might be possible to replace the
+relocation codes with something simpler.
+
+@node BFD relocation future
+@subsection BFD relocation future
+
+Clearly the current BFD relocation support is in bad shape. A
+wholescale rewrite would be very difficult, because it would require
+thorough testing of every BFD target. So some sort of incremental
+change is required.
+
+My vague thoughts on this would involve defining a new, clearly defined,
+howto structure. Some mechanism would be used to determine which type
+of howto structure was being used by a particular format.
+
+The new howto structure would clearly define the relocation behaviour in
+the case of an assembly, a relocateable link, and a final link. At
+least one special function would be defined as an escape, and it might
+make sense to define more.
+
+One or more generic functions similar to @samp{bfd_perform_relocation}
+would be written to handle the new howto structure.
+
+This should make it possible to write a generic version of the relocate
+section functions used by the new linker. The target specific code
+would provide some mechanism (a function pointer or an initial
+conversion) to convert target specific relocations into howto
+structures.
+
+Ideally it would be possible to use this generic relocate section
+function for the generic linker as well. That is, it would replace the
+@samp{bfd_generic_get_relocated_section_contents} function which is
+currently normally used.
+
+For the special case of ELF dynamic linking, more consideration needs to
+be given to writing ELF specific but ELF target generic code to handle
+special relocation types such as GOT and PLT.
+
+@node BFD ELF support
+@section BFD ELF support
+@cindex elf support in bfd
+@cindex bfd elf support
+
+The ELF object file format is defined in two parts: a generic ABI and a
+processor specific supplement. The ELF support in BFD is split in a
+similar fashion. The processor specific support is largely kept within
+a single file. The generic support is provided by several other files.
+The processor specific support provides a set of function pointers and
+constants used by the generic support.
+
+@menu
+* BFD ELF sections and segments:: ELF sections and segments
+* BFD ELF generic support:: BFD ELF generic support
+* BFD ELF processor specific support:: BFD ELF processor specific support
+* BFD ELF core files:: BFD ELF core files
+* BFD ELF future:: BFD ELF future
+@end menu
+
+@node BFD ELF sections and segments
+@subsection ELF sections and segments
+
+The ELF ABI permits a file to have either sections or segments or both.
+Relocateable object files conventionally have only sections.
+Executables conventionally have both. Core files conventionally have
+only program segments.
+
+ELF sections are similar to sections in other object file formats: they
+have a name, a VMA, file contents, flags, and other miscellaneous
+information. ELF relocations are stored in sections of a particular
+type; BFD automatically converts these sections into internal relocation
+information.
+
+ELF program segments are intended for fast interpretation by a system
+loader. They have a type, a VMA, an LMA, file contents, and a couple of
+other fields. When an ELF executable is run on a Unix system, the
+system loader will examine the program segments to decide how to load
+it. The loader will ignore the section information. Loadable program
+segments (type @samp{PT_LOAD}) are directly loaded into memory. Other
+program segments are interpreted by the loader, and generally provide
+dynamic linking information.
+
+When an ELF file has both program segments and sections, an ELF program
+segment may encompass one or more ELF sections, in the sense that the
+portion of the file which corresponds to the program segment may include
+the portions of the file corresponding to one or more sections. When
+there is more than one section in a loadable program segment, the
+relative positions of the section contents in the file must correspond
+to the relative positions they should hold when the program segment is
+loaded. This requirement should be obvious if you consider that the
+system loader will load an entire program segment at a time.
+
+On a system which supports dynamic paging, such as any native Unix
+system, the contents of a loadable program segment must be at the same
+offset in the file as in memory, modulo the memory page size used on the
+system. This is because the system loader will map the file into memory
+starting at the start of a page. The system loader can easily remap
+entire pages to the correct load address. However, if the contents of
+the file were not correctly aligned within the page, the system loader
+would have to shift the contents around within the page, which is too
+expensive. For example, if the LMA of a loadable program segment is
+@samp{0x40080} and the page size is @samp{0x1000}, then the position of
+the segment contents within the file must equal @samp{0x80} modulo
+@samp{0x1000}.
+
+BFD has only a single set of sections. It does not provide any generic
+way to examine both sections and segments. When BFD is used to open an
+object file or executable, the BFD sections will represent ELF sections.
+When BFD is used to open a core file, the BFD sections will represent
+ELF program segments.
+
+When BFD is used to examine an object file or executable, any program
+segments will be read to set the LMA of the sections. This is because
+ELF sections only have a VMA, while ELF program segments have both a VMA
+and an LMA. Any program segments will be copied by the
+@samp{copy_private} entry points. They will be printed by the
+@samp{print_private} entry point. Otherwise, the program segments are
+ignored. In particular, programs which use BFD currently have no direct
+access to the program segments.
+
+When BFD is used to create an executable, the program segments will be
+created automatically based on the section information. This is done in
+the function @samp{assign_file_positions_for_segments} in @file{elf.c}.
+This function has been tweaked many times, and probably still has
+problems that arise in particular cases.
+
+There is a hook which may be used to explicitly define the program
+segments when creating an executable: the @samp{bfd_record_phdr}
+function in @file{bfd.c}. If this function is called, BFD will not
+create program segments itself, but will only create the program
+segments specified by the caller. The linker uses this function to
+implement the @samp{PHDRS} linker script command.
+
+@node BFD ELF generic support
+@subsection BFD ELF generic support
+
+In general, functions which do not read external data from the ELF file
+are found in @file{elf.c}. They operate on the internal forms of the
+ELF structures, which are defined in @file{include/elf/internal.h}. The
+internal structures are defined in terms of @samp{bfd_vma}, and so may
+be used for both 32 bit and 64 bit ELF targets.
+
+The file @file{elfcode.h} contains functions which operate on the
+external data. @file{elfcode.h} is compiled twice, once via
+@file{elf32.c} with @samp{ARCH_SIZE} defined as @samp{32}, and once via
+@file{elf64.c} with @samp{ARCH_SIZE} defined as @samp{64}.
+@file{elfcode.h} includes functions to swap the ELF structures in and
+out of external form, as well as a few more complex functions.
+
+Linker support is found in @file{elflink.c} and @file{elflink.h}. The
+latter file is compiled twice, for both 32 and 64 bit support. The
+linker support is only used if the processor specific file defines
+@samp{elf_backend_relocate_section}, which is required to relocate the
+section contents. If that macro is not defined, the generic linker code
+is used, and relocations are handled via @samp{bfd_perform_relocation}.
+
+The core file support is in @file{elfcore.h}, which is compiled twice,
+for both 32 and 64 bit support. The more interesting cases of core file
+support only work on a native system which has the @file{sys/procfs.h}
+header file. Without that file, the core file support does little more
+than read the ELF program segments as BFD sections.
+
+The BFD internal header file @file{elf-bfd.h} is used for communication
+among these files and the processor specific files.
+
+The default entries for the BFD ELF target vector are found mainly in
+@file{elf.c}. Some functions are found in @file{elfcode.h}.
+
+The processor specific files may override particular entries in the
+target vector, but most do not, with one exception: the
+@samp{bfd_reloc_type_lookup} entry point is always processor specific.
+
+@node BFD ELF processor specific support
+@subsection BFD ELF processor specific support
+
+By convention, the processor specific support for a particular processor
+will be found in @file{elf@var{nn}-@var{cpu}.c}, where @var{nn} is
+either 32 or 64, and @var{cpu} is the name of the processor.
+
+@menu
+* BFD ELF processor required:: Required processor specific support
+* BFD ELF processor linker:: Processor specific linker support
+* BFD ELF processor other:: Other processor specific support options
+@end menu
+
+@node BFD ELF processor required
+@subsubsection Required processor specific support
+
+When writing a @file{elf@var{nn}-@var{cpu}.c} file, you must do the
+following:
+
+@itemize @bullet
+@item
+Define either @samp{TARGET_BIG_SYM} or @samp{TARGET_LITTLE_SYM}, or
+both, to a unique C name to use for the target vector. This name should
+appear in the list of target vectors in @file{targets.c}, and will also
+have to appear in @file{config.bfd} and @file{configure.in}. Define
+@samp{TARGET_BIG_SYM} for a big-endian processor,
+@samp{TARGET_LITTLE_SYM} for a little-endian processor, and define both
+for a bi-endian processor.
+@item
+Define either @samp{TARGET_BIG_NAME} or @samp{TARGET_LITTLE_NAME}, or
+both, to a string used as the name of the target vector. This is the
+name which a user of the BFD tool would use to specify the object file
+format. It would normally appear in a linker emulation parameters
+file.
+@item
+Define @samp{ELF_ARCH} to the BFD architecture (an element of the
+@samp{bfd_architecture} enum, typically @samp{bfd_arch_@var{cpu}}).
+@item
+Define @samp{ELF_MACHINE_CODE} to the magic number which should appear
+in the @samp{e_machine} field of the ELF header. As of this writing,
+these magic numbers are assigned by SCO; if you want to get a magic
+number for a particular processor, try sending a note to
+@email{registry@@sco.com}. In the BFD sources, the magic numbers are
+found in @file{include/elf/common.h}; they have names beginning with
+@samp{EM_}.
+@item
+Define @samp{ELF_MAXPAGESIZE} to the maximum size of a virtual page in
+memory. This can normally be found at the start of chapter 5 in the
+processor specific supplement. For a processor which will only be used
+in an embedded system, or which has no memory management hardware, this
+can simply be @samp{1}.
+@item
+If the format should use @samp{Rel} rather than @samp{Rela} relocations,
+define @samp{USE_REL}. This is normally defined in chapter 4 of the
+processor specific supplement.
+
+In the absence of a supplement, it's easier to work with @samp{Rela}
+relocations. @samp{Rela} relocations will require more space in object
+files (but not in executables, except when using dynamic linking).
+However, this is outweighed by the simplicity of addend handling when
+using @samp{Rela} relocations. With @samp{Rel} relocations, the addend
+must be stored in the section contents, which makes relocateable links
+more complex.
+
+For example, consider C code like @code{i = a[1000];} where @samp{a} is
+a global array. The instructions which load the value of @samp{a[1000]}
+will most likely use a relocation which refers to the symbol
+representing @samp{a}, with an addend that gives the offset from the
+start of @samp{a} to element @samp{1000}. When using @samp{Rel}
+relocations, that addend must be stored in the instructions themselves.
+If you are adding support for a RISC chip which uses two or more
+instructions to load an address, then the addend may not fit in a single
+instruction, and will have to be somehow split among the instructions.
+This makes linking awkward, particularly when doing a relocateable link
+in which the addend may have to be updated. It can be done---the MIPS
+ELF support does it---but it should be avoided when possible.
+
+It is possible, though somewhat awkward, to support both @samp{Rel} and
+@samp{Rela} relocations for a single target; @file{elf64-mips.c} does it
+by overriding the relocation reading and writing routines.
+@item
+Define howto structures for all the relocation types.
+@item
+Define a @samp{bfd_reloc_type_lookup} routine. This must be named
+@samp{bfd_elf@var{nn}_bfd_reloc_type_lookup}, and may be either a
+function or a macro. It must translate a BFD relocation code into a
+howto structure. This is normally a table lookup or a simple switch.
+@item
+If using @samp{Rel} relocations, define @samp{elf_info_to_howto_rel}.
+If using @samp{Rela} relocations, define @samp{elf_info_to_howto}.
+Either way, this is a macro defined as the name of a function which
+takes an @samp{arelent} and a @samp{Rel} or @samp{Rela} structure, and
+sets the @samp{howto} field of the @samp{arelent} based on the
+@samp{Rel} or @samp{Rela} structure. This is normally uses
+@samp{ELF@var{nn}_R_TYPE} to get the ELF relocation type and uses it as
+an index into a table of howto structures.
+@end itemize
+
+You must also add the magic number for this processor to the
+@samp{prep_headers} function in @file{elf.c}.
+
+You must also create a header file in the @file{include/elf} directory
+called @file{@var{cpu}.h}. This file should define any target specific
+information which may be needed outside of the BFD code. In particular
+it should use the @samp{START_RELOC_NUMBERS}, @samp{RELOC_NUMBER},
+@samp{FAKE_RELOC}, @samp{EMPTY_RELOC} and @samp{END_RELOC_NUMBERS}
+macros to create a table mapping the number used to indentify a
+relocation to a name describing that relocation.
+
+@node BFD ELF processor linker
+@subsubsection Processor specific linker support
+
+The linker will be much more efficient if you define a relocate section
+function. This will permit BFD to use the ELF specific linker support.
+
+If you do not define a relocate section function, BFD must use the
+generic linker support, which requires converting all symbols and
+relocations into BFD @samp{asymbol} and @samp{arelent} structures. In
+this case, relocations will be handled by calling
+@samp{bfd_perform_relocation}, which will use the howto structures you
+have defined. @xref{BFD relocation handling}.
+
+In order to support linking into a different object file format, such as
+S-records, @samp{bfd_perform_relocation} must work correctly with your
+howto structures, so you can't skip that step. However, if you define
+the relocate section function, then in the normal case of linking into
+an ELF file the linker will not need to convert symbols and relocations,
+and will be much more efficient.
+
+To use a relocation section function, define the macro
+@samp{elf_backend_relocate_section} as the name of a function which will
+take the contents of a section, as well as relocation, symbol, and other
+information, and modify the section contents according to the relocation
+information. In simple cases, this is little more than a loop over the
+relocations which computes the value of each relocation and calls
+@samp{_bfd_final_link_relocate}. The function must check for a
+relocateable link, and in that case normally needs to do nothing other
+than adjust the addend for relocations against a section symbol.
+
+The complex cases generally have to do with dynamic linker support. GOT
+and PLT relocations must be handled specially, and the linker normally
+arranges to set up the GOT and PLT sections while handling relocations.
+When generating a shared library, random relocations must normally be
+copied into the shared library, or converted to RELATIVE relocations
+when possible.
+
+@node BFD ELF processor other
+@subsubsection Other processor specific support options
+
+There are many other macros which may be defined in
+@file{elf@var{nn}-@var{cpu}.c}. These macros may be found in
+@file{elfxx-target.h}.
+
+Macros may be used to override some of the generic ELF target vector
+functions.
+
+Several processor specific hook functions which may be defined as
+macros. These functions are found as function pointers in the
+@samp{elf_backend_data} structure defined in @file{elf-bfd.h}. In
+general, a hook function is set by defining a macro
+@samp{elf_backend_@var{name}}.
+
+There are a few processor specific constants which may also be defined.
+These are again found in the @samp{elf_backend_data} structure.
+
+I will not define the various functions and constants here; see the
+comments in @file{elf-bfd.h}.
+
+Normally any odd characteristic of a particular ELF processor is handled
+via a hook function. For example, the special @samp{SHN_MIPS_SCOMMON}
+section number found in MIPS ELF is handled via the hooks
+@samp{section_from_bfd_section}, @samp{symbol_processing},
+@samp{add_symbol_hook}, and @samp{output_symbol_hook}.
+
+Dynamic linking support, which involves processor specific relocations
+requiring special handling, is also implemented via hook functions.
+
+@node BFD ELF core files
+@subsection BFD ELF core files
+@cindex elf core files
+
+On native ELF Unix systems, core files are generated without any
+sections. Instead, they only have program segments.
+
+When BFD is used to read an ELF core file, the BFD sections will
+actually represent program segments. Since ELF program segments do not
+have names, BFD will invent names like @samp{segment@var{n}} where
+@var{n} is a number.
+
+A single ELF program segment may include both an initialized part and an
+uninitialized part. The size of the initialized part is given by the
+@samp{p_filesz} field. The total size of the segment is given by the
+@samp{p_memsz} field. If @samp{p_memsz} is larger than @samp{p_filesz},
+then the extra space is uninitialized, or, more precisely, initialized
+to zero.
+
+BFD will represent such a program segment as two different sections.
+The first, named @samp{segment@var{n}a}, will represent the initialized
+part of the program segment. The second, named @samp{segment@var{n}b},
+will represent the uninitialized part.
+
+ELF core files store special information such as register values in
+program segments with the type @samp{PT_NOTE}. BFD will attempt to
+interpret the information in these segments, and will create additional
+sections holding the information. Some of this interpretation requires
+information found in the host header file @file{sys/procfs.h}, and so
+will only work when BFD is built on a native system.
+
+BFD does not currently provide any way to create an ELF core file. In
+general, BFD does not provide a way to create core files. The way to
+implement this would be to write @samp{bfd_set_format} and
+@samp{bfd_write_contents} routines for the @samp{bfd_core} type; see
+@ref{BFD target vector format}.
+
+@node BFD ELF future
+@subsection BFD ELF future
+
+The current dynamic linking support has too much code duplication.
+While each processor has particular differences, much of the dynamic
+linking support is quite similar for each processor. The GOT and PLT
+are handled in fairly similar ways, the details of -Bsymbolic linking
+are generally similar, etc. This code should be reworked to use more
+generic functions, eliminating the duplication.
+
+Similarly, the relocation handling has too much duplication. Many of
+the @samp{reloc_type_lookup} and @samp{info_to_howto} functions are
+quite similar. The relocate section functions are also often quite
+similar, both in the standard linker handling and the dynamic linker
+handling. Many of the COFF processor specific backends share a single
+relocate section function (@samp{_bfd_coff_generic_relocate_section}),
+and it should be possible to do something like this for the ELF targets
+as well.
+
+The appearance of the processor specific magic number in
+@samp{prep_headers} in @file{elf.c} is somewhat bogus. It should be
+possible to add support for a new processor without changing the generic
+support.
+
+The processor function hooks and constants are ad hoc and need better
+documentation.
+
+When a linker script uses @samp{SIZEOF_HEADERS}, the ELF backend must
+guess at the number of program segments which will be required, in
+@samp{get_program_header_size}. This is because the linker calls
+@samp{bfd_sizeof_headers} before it knows all the section addresses and
+sizes. The ELF backend may later discover, when creating program
+segments, that more program segments are required. This is currently
+reported as an error in @samp{assign_file_positions_for_segments}.
+
+In practice this makes it difficult to use @samp{SIZEOF_HEADERS} except
+with a carefully defined linker script. Unfortunately,
+@samp{SIZEOF_HEADERS} is required for fast program loading on a native
+system, since it permits the initial code section to appear on the same
+page as the program segments, saving a page read when the program starts
+running. Fortunately, native systems permit careful definition of the
+linker script. Still, ideally it would be possible to use relaxation to
+compute the number of program segments.
+
+@node BFD glossary
+@section BFD glossary
+@cindex glossary for bfd
+@cindex bfd glossary
+
+This is a short glossary of some BFD terms.
+
+@table @asis
+@item a.out
+The a.out object file format. The original Unix object file format.
+Still used on SunOS, though not Solaris. Supports only three sections.
+
+@item archive
+A collection of object files produced and manipulated by the @samp{ar}
+program.
+
+@item backend
+The implementation within BFD of a particular object file format. The
+set of functions which appear in a particular target vector.
+
+@item BFD
+The BFD library itself. Also, each object file, archive, or exectable
+opened by the BFD library has the type @samp{bfd *}, and is sometimes
+referred to as a bfd.
+
+@item COFF
+The Common Object File Format. Used on Unix SVR3. Used by some
+embedded targets, although ELF is normally better.
+
+@item DLL
+A shared library on Windows.
+
+@item dynamic linker
+When a program linked against a shared library is run, the dynamic
+linker will locate the appropriate shared library and arrange to somehow
+include it in the running image.
+
+@item dynamic object
+Another name for an ELF shared library.
+
+@item ECOFF
+The Extended Common Object File Format. Used on Alpha Digital Unix
+(formerly OSF/1), as well as Ultrix and Irix 4. A variant of COFF.
+
+@item ELF
+The Executable and Linking Format. The object file format used on most
+modern Unix systems, including GNU/Linux, Solaris, Irix, and SVR4. Also
+used on many embedded systems.
+
+@item executable
+A program, with instructions and symbols, and perhaps dynamic linking
+information. Normally produced by a linker.
+
+@item LMA
+Load Memory Address. This is the address at which a section will be
+loaded. Compare with VMA, below.
+
+@item NLM
+NetWare Loadable Module. Used to describe the format of an object which
+be loaded into NetWare, which is some kind of PC based network server
+program.
+
+@item object file
+A binary file including machine instructions, symbols, and relocation
+information. Normally produced by an assembler.
+
+@item object file format
+The format of an object file. Typically object files and executables
+for a particular system are in the same format, although executables
+will not contain any relocation information.
+
+@item PE
+The Portable Executable format. This is the object file format used for
+Windows (specifically, Win32) object files. It is based closely on
+COFF, but has a few significant differences.
+
+@item PEI
+The Portable Executable Image format. This is the object file format
+used for Windows (specifically, Win32) executables. It is very similar
+to PE, but includes some additional header information.
+
+@item relocations
+Information used by the linker to adjust section contents. Also called
+relocs.
+
+@item section
+Object files and executable are composed of sections. Sections have
+optional data and optional relocation information.
+
+@item shared library
+A library of functions which may be used by many executables without
+actually being linked into each executable. There are several different
+implementations of shared libraries, each having slightly different
+features.
+
+@item symbol
+Each object file and executable may have a list of symbols, often
+referred to as the symbol table. A symbol is basically a name and an
+address. There may also be some additional information like the type of
+symbol, although the type of a symbol is normally something simple like
+function or object, and should be confused with the more complex C
+notion of type. Typically every global function and variable in a C
+program will have an associated symbol.
+
+@item target vector
+A set of functions which implement support for a particular object file
+format. The @samp{bfd_target} structure.
+
+@item Win32
+The current Windows API, implemented by Windows 95 and later and Windows
+NT 3.51 and later, but not by Windows 3.1.
+
+@item XCOFF
+The eXtended Common Object File Format. Used on AIX. A variant of
+COFF, with a completely different symbol table implementation.
+
+@item VMA
+Virtual Memory Address. This is the address a section will have when
+an executable is run. Compare with LMA, above.
+@end table
+
+@node Index
+@unnumberedsec Index
+@printindex cp
+
+@contents
+@bye
diff --git a/bfd/doc/bfdsumm.texi b/bfd/doc/bfdsumm.texi
new file mode 100644
index 00000000000..844531aff8c
--- /dev/null
+++ b/bfd/doc/bfdsumm.texi
@@ -0,0 +1,148 @@
+@c This summary of BFD is shared by the BFD and LD docs.
+When an object file is opened, BFD subroutines automatically determine
+the format of the input object file. They then build a descriptor in
+memory with pointers to routines that will be used to access elements of
+the object file's data structures.
+
+As different information from the the object files is required,
+BFD reads from different sections of the file and processes them.
+For example, a very common operation for the linker is processing symbol
+tables. Each BFD back end provides a routine for converting
+between the object file's representation of symbols and an internal
+canonical format. When the linker asks for the symbol table of an object
+file, it calls through a memory pointer to the routine from the
+relevant BFD back end which reads and converts the table into a canonical
+form. The linker then operates upon the canonical form. When the link is
+finished and the linker writes the output file's symbol table,
+another BFD back end routine is called to take the newly
+created symbol table and convert it into the chosen output format.
+
+@menu
+* BFD information loss:: Information Loss
+* Canonical format:: The BFD canonical object-file format
+@end menu
+
+@node BFD information loss
+@subsection Information Loss
+
+@emph{Information can be lost during output.} The output formats
+supported by BFD do not provide identical facilities, and
+information which can be described in one form has nowhere to go in
+another format. One example of this is alignment information in
+@code{b.out}. There is nowhere in an @code{a.out} format file to store
+alignment information on the contained data, so when a file is linked
+from @code{b.out} and an @code{a.out} image is produced, alignment
+information will not propagate to the output file. (The linker will
+still use the alignment information internally, so the link is performed
+correctly).
+
+Another example is COFF section names. COFF files may contain an
+unlimited number of sections, each one with a textual section name. If
+the target of the link is a format which does not have many sections (e.g.,
+@code{a.out}) or has sections without names (e.g., the Oasys format), the
+link cannot be done simply. You can circumvent this problem by
+describing the desired input-to-output section mapping with the linker command
+language.
+
+@emph{Information can be lost during canonicalization.} The BFD
+internal canonical form of the external formats is not exhaustive; there
+are structures in input formats for which there is no direct
+representation internally. This means that the BFD back ends
+cannot maintain all possible data richness through the transformation
+between external to internal and back to external formats.
+
+This limitation is only a problem when an application reads one
+format and writes another. Each BFD back end is responsible for
+maintaining as much data as possible, and the internal BFD
+canonical form has structures which are opaque to the BFD core,
+and exported only to the back ends. When a file is read in one format,
+the canonical form is generated for BFD and the application. At the
+same time, the back end saves away any information which may otherwise
+be lost. If the data is then written back in the same format, the back
+end routine will be able to use the canonical form provided by the
+BFD core as well as the information it prepared earlier. Since
+there is a great deal of commonality between back ends,
+there is no information lost when
+linking or copying big endian COFF to little endian COFF, or @code{a.out} to
+@code{b.out}. When a mixture of formats is linked, the information is
+only lost from the files whose format differs from the destination.
+
+@node Canonical format
+@subsection The BFD canonical object-file format
+
+The greatest potential for loss of information occurs when there is the least
+overlap between the information provided by the source format, that
+stored by the canonical format, and that needed by the
+destination format. A brief description of the canonical form may help
+you understand which kinds of data you can count on preserving across
+conversions.
+@cindex BFD canonical format
+@cindex internal object-file format
+
+@table @emph
+@item files
+Information stored on a per-file basis includes target machine
+architecture, particular implementation format type, a demand pageable
+bit, and a write protected bit. Information like Unix magic numbers is
+not stored here---only the magic numbers' meaning, so a @code{ZMAGIC}
+file would have both the demand pageable bit and the write protected
+text bit set. The byte order of the target is stored on a per-file
+basis, so that big- and little-endian object files may be used with one
+another.
+
+@item sections
+Each section in the input file contains the name of the section, the
+section's original address in the object file, size and alignment
+information, various flags, and pointers into other BFD data
+structures.
+
+@item symbols
+Each symbol contains a pointer to the information for the object file
+which originally defined it, its name, its value, and various flag
+bits. When a BFD back end reads in a symbol table, it relocates all
+symbols to make them relative to the base of the section where they were
+defined. Doing this ensures that each symbol points to its containing
+section. Each symbol also has a varying amount of hidden private data
+for the BFD back end. Since the symbol points to the original file, the
+private data format for that symbol is accessible. @code{ld} can
+operate on a collection of symbols of wildly different formats without
+problems.
+
+Normal global and simple local symbols are maintained on output, so an
+output file (no matter its format) will retain symbols pointing to
+functions and to global, static, and common variables. Some symbol
+information is not worth retaining; in @code{a.out}, type information is
+stored in the symbol table as long symbol names. This information would
+be useless to most COFF debuggers; the linker has command line switches
+to allow users to throw it away.
+
+There is one word of type information within the symbol, so if the
+format supports symbol type information within symbols (for example, COFF,
+IEEE, Oasys) and the type is simple enough to fit within one word
+(nearly everything but aggregates), the information will be preserved.
+
+@item relocation level
+Each canonical BFD relocation record contains a pointer to the symbol to
+relocate to, the offset of the data to relocate, the section the data
+is in, and a pointer to a relocation type descriptor. Relocation is
+performed by passing messages through the relocation type
+descriptor and the symbol pointer. Therefore, relocations can be performed
+on output data using a relocation method that is only available in one of the
+input formats. For instance, Oasys provides a byte relocation format.
+A relocation record requesting this relocation type would point
+indirectly to a routine to perform this, so the relocation may be
+performed on a byte being written to a 68k COFF file, even though 68k COFF
+has no such relocation type.
+
+@item line numbers
+Object formats can contain, for debugging purposes, some form of mapping
+between symbols, source line numbers, and addresses in the output file.
+These addresses have to be relocated along with the symbol information.
+Each symbol with an associated list of line number records points to the
+first record of the list. The head of a line number list consists of a
+pointer to the symbol, which allows finding out the address of the
+function whose line number is being described. The rest of the list is
+made up of pairs: offsets into the section and line numbers. Any format
+which can simply derive this information can pass it successfully
+between formats (COFF, IEEE and Oasys).
+@end table
diff --git a/bfd/doc/chew.c b/bfd/doc/chew.c
new file mode 100644
index 00000000000..eba69c2bb1d
--- /dev/null
+++ b/bfd/doc/chew.c
@@ -0,0 +1,1579 @@
+/* chew
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+ Contributed by steve chamberlain @cygnus
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Yet another way of extracting documentation from source.
+ No, I haven't finished it yet, but I hope you people like it better
+ than the old way
+
+ sac
+
+ Basically, this is a sort of string forth, maybe we should call it
+ struth?
+
+ You define new words thus:
+ : <newword> <oldwords> ;
+
+*/
+
+/* Primitives provided by the program:
+
+ Two stacks are provided, a string stack and an integer stack.
+
+ Internal state variables:
+ internal_wanted - indicates whether `-i' was passed
+ internal_mode - user-settable
+
+ Commands:
+ push_text
+ ! - pop top of integer stack for address, pop next for value; store
+ @ - treat value on integer stack as the address of an integer; push
+ that integer on the integer stack after popping the "address"
+ hello - print "hello\n" to stdout
+ stdout - put stdout marker on TOS
+ stderr - put stderr marker on TOS
+ print - print TOS-1 on TOS (eg: "hello\n" stdout print)
+ skip_past_newline
+ catstr - fn icatstr
+ copy_past_newline - append input, up to and including newline into TOS
+ dup - fn other_dup
+ drop - discard TOS
+ idrop - ditto
+ remchar - delete last character from TOS
+ get_stuff_in_command
+ do_fancy_stuff - translate <<foo>> to @code{foo} in TOS
+ bulletize - if "o" lines found, prepend @itemize @bullet to TOS
+ and @item to each "o" line; append @end itemize
+ courierize - put @example around . and | lines, translate {* *} { }
+ exit - fn chew_exit
+ swap
+ outputdots - strip out lines without leading dots
+ paramstuff - convert full declaration into "PARAMS" form if not already
+ maybecatstr - do catstr if internal_mode == internal_wanted, discard
+ value in any case
+ translatecomments - turn {* and *} into comment delimiters
+ kill_bogus_lines - get rid of extra newlines
+ indent
+ internalmode - pop from integer stack, set `internalmode' to that value
+ print_stack_level - print current stack depth to stderr
+ strip_trailing_newlines - go ahead, guess...
+ [quoted string] - push string onto string stack
+ [word starting with digit] - push atol(str) onto integer stack
+
+ A command must be all upper-case, and alone on a line.
+
+ Foo. */
+
+
+#include <ansidecl.h>
+#include "sysdep.h"
+#include <assert.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define DEF_SIZE 5000
+#define STACK 50
+
+int internal_wanted;
+int internal_mode;
+
+int warning;
+
+/* Here is a string type ... */
+
+typedef struct buffer
+{
+ char *ptr;
+ unsigned long write_idx;
+ unsigned long size;
+} string_type;
+
+
+#ifdef __STDC__
+static void init_string_with_size (string_type *, unsigned int);
+static void init_string (string_type *);
+static int find (string_type *, char *);
+static void write_buffer (string_type *, FILE *);
+static void delete_string (string_type *);
+static char *addr (string_type *, unsigned int);
+static char at (string_type *, unsigned int);
+static void catchar (string_type *, int);
+static void overwrite_string (string_type *, string_type *);
+static void catbuf (string_type *, char *, unsigned int);
+static void cattext (string_type *, char *);
+static void catstr (string_type *, string_type *);
+#endif
+
+
+static void DEFUN(init_string_with_size,(buffer, size),
+ string_type *buffer AND
+ unsigned int size )
+{
+ buffer->write_idx = 0;
+ buffer->size = size;
+ buffer->ptr = malloc(size);
+}
+
+static void DEFUN(init_string,(buffer),
+ string_type *buffer)
+{
+ init_string_with_size(buffer, DEF_SIZE);
+
+}
+
+static int DEFUN(find, (str, what),
+ string_type *str AND
+ char *what)
+{
+ unsigned int i;
+ char *p;
+ p = what;
+ for (i = 0; i < str->write_idx && *p; i++)
+ {
+ if (*p == str->ptr[i])
+ p++;
+ else
+ p = what;
+ }
+ return (*p == 0);
+
+}
+
+static void DEFUN(write_buffer,(buffer, f),
+ string_type *buffer AND
+ FILE *f)
+{
+ fwrite(buffer->ptr, buffer->write_idx, 1, f);
+}
+
+
+static void DEFUN(delete_string,(buffer),
+ string_type *buffer)
+{
+ free(buffer->ptr);
+}
+
+
+static char *DEFUN(addr, (buffer, idx),
+ string_type *buffer AND
+ unsigned int idx)
+{
+ return buffer->ptr + idx;
+}
+
+static char DEFUN(at,(buffer, pos),
+ string_type *buffer AND
+ unsigned int pos)
+{
+ if (pos >= buffer->write_idx)
+ return 0;
+ return buffer->ptr[pos];
+}
+
+static void DEFUN(catchar,(buffer, ch),
+ string_type *buffer AND
+ int ch)
+{
+ if (buffer->write_idx == buffer->size)
+ {
+ buffer->size *=2;
+ buffer->ptr = realloc(buffer->ptr, buffer->size);
+ }
+
+ buffer->ptr[buffer->write_idx ++ ] = ch;
+}
+
+
+static void DEFUN(overwrite_string,(dst, src),
+ string_type *dst AND
+ string_type *src)
+{
+ free(dst->ptr);
+ dst->size = src->size;
+ dst->write_idx = src->write_idx;
+ dst->ptr = src->ptr;
+}
+
+static void DEFUN(catbuf,(buffer, buf, len),
+ string_type *buffer AND
+ char *buf AND
+ unsigned int len)
+{
+ if (buffer->write_idx + len >= buffer->size)
+ {
+ while (buffer->write_idx + len >= buffer->size)
+ buffer->size *= 2;
+ buffer->ptr = realloc (buffer->ptr, buffer->size);
+ }
+ memcpy (buffer->ptr + buffer->write_idx, buf, len);
+ buffer->write_idx += len;
+}
+
+static void DEFUN(cattext,(buffer, string),
+ string_type *buffer AND
+ char *string)
+{
+ catbuf (buffer, string, (unsigned int) strlen (string));
+}
+
+static void DEFUN(catstr,(dst, src),
+ string_type *dst AND
+ string_type *src)
+{
+ catbuf (dst, src->ptr, src->write_idx);
+}
+
+
+static unsigned int
+DEFUN(skip_white_and_stars,(src, idx),
+ string_type *src AND
+ unsigned int idx)
+{
+ char c;
+ while ((c = at(src,idx)),
+ isspace ((unsigned char) c)
+ || (c == '*'
+ /* Don't skip past end-of-comment or star as first
+ character on its line. */
+ && at(src,idx +1) != '/'
+ && at(src,idx -1) != '\n'))
+ idx++;
+ return idx;
+}
+
+/***********************************************************************/
+
+
+string_type stack[STACK];
+string_type *tos;
+
+unsigned int idx = 0; /* Pos in input buffer */
+string_type *ptr; /* and the buffer */
+typedef void (*stinst_type)();
+stinst_type *pc;
+stinst_type sstack[STACK];
+stinst_type *ssp = &sstack[0];
+long istack[STACK];
+long *isp = &istack[0];
+
+typedef int *word_type;
+
+
+
+struct dict_struct
+{
+ char *word;
+ struct dict_struct *next;
+ stinst_type *code;
+ int code_length;
+ int code_end;
+ int var;
+
+};
+typedef struct dict_struct dict_type;
+#define WORD(x) static void x()
+
+static void
+die (msg)
+ char *msg;
+{
+ fprintf (stderr, "%s\n", msg);
+ exit (1);
+}
+
+static void
+check_range ()
+{
+ if (tos < stack)
+ die ("underflow in string stack");
+ if (tos >= stack + STACK)
+ die ("overflow in string stack");
+}
+
+static void
+icheck_range ()
+{
+ if (isp < istack)
+ die ("underflow in integer stack");
+ if (isp >= istack + STACK)
+ die ("overflow in integer stack");
+}
+
+#ifdef __STDC__
+static void exec (dict_type *);
+static void call (void);
+static void remchar (void), strip_trailing_newlines (void), push_number (void);
+static void push_text (void);
+static void remove_noncomments (string_type *, string_type *);
+static void print_stack_level (void);
+static void paramstuff (void), translatecomments (void);
+static void outputdots (void), courierize (void), bulletize (void);
+static void do_fancy_stuff (void);
+static int iscommand (string_type *, unsigned int);
+static int copy_past_newline (string_type *, unsigned int, string_type *);
+static void icopy_past_newline (void), kill_bogus_lines (void), indent (void);
+static void get_stuff_in_command (void), swap (void), other_dup (void);
+static void drop (void), idrop (void);
+static void icatstr (void), skip_past_newline (void), internalmode (void);
+static void maybecatstr (void);
+static char *nextword (char *, char **);
+dict_type *lookup_word (char *);
+static void perform (void);
+dict_type *newentry (char *);
+unsigned int add_to_definition (dict_type *, stinst_type);
+void add_intrinsic (char *, void (*)());
+void add_var (char *);
+void compile (char *);
+static void bang (void);
+static void atsign (void);
+static void hello (void);
+static void stdout_ (void);
+static void stderr_ (void);
+static void print (void);
+static void read_in (string_type *, FILE *);
+static void usage (void);
+static void chew_exit (void);
+#endif
+
+static void DEFUN(exec,(word),
+ dict_type *word)
+{
+ pc = word->code;
+ while (*pc)
+ (*pc)();
+}
+WORD(call)
+{
+ stinst_type *oldpc = pc;
+ dict_type *e;
+ e = (dict_type *)(pc [1]);
+ exec(e);
+ pc = oldpc + 2;
+
+}
+
+WORD(remchar)
+{
+ if (tos->write_idx)
+ tos->write_idx--;
+ pc++;
+}
+
+static void
+strip_trailing_newlines ()
+{
+ while ((isspace ((unsigned char) at (tos, tos->write_idx - 1))
+ || at (tos, tos->write_idx - 1) == '\n')
+ && tos->write_idx > 0)
+ tos->write_idx--;
+ pc++;
+}
+
+WORD(push_number)
+{
+ isp++;
+ icheck_range ();
+ pc++;
+ *isp = (long)(*pc);
+ pc++;
+}
+
+WORD(push_text)
+{
+ tos++;
+ check_range ();
+ init_string(tos);
+ pc++;
+ cattext(tos,*((char **)pc));
+ pc++;
+
+}
+
+
+/* This function removes everything not inside comments starting on
+ the first char of the line from the string, also when copying
+ comments, removes blank space and leading *'s.
+ Blank lines are turned into one blank line. */
+
+static void
+DEFUN(remove_noncomments,(src,dst),
+ string_type *src AND
+ string_type *dst)
+{
+ unsigned int idx = 0;
+
+ while (at(src,idx))
+ {
+ /* Now see if we have a comment at the start of the line */
+ if (at(src,idx) == '\n'
+ && at(src,idx+1) == '/'
+ && at(src,idx+2) == '*')
+ {
+ idx+=3;
+
+ idx = skip_white_and_stars(src,idx);
+
+ /* Remove leading dot */
+ if (at(src, idx) == '.')
+ idx++;
+
+ /* Copy to the end of the line, or till the end of the
+ comment */
+ while (at(src, idx))
+ {
+ if (at(src, idx) == '\n')
+ {
+ /* end of line, echo and scrape of leading blanks */
+ if (at(src,idx +1) == '\n')
+ catchar(dst,'\n');
+ catchar(dst,'\n');
+ idx++;
+ idx = skip_white_and_stars(src, idx);
+ }
+ else if (at(src, idx) == '*' && at(src,idx+1) == '/')
+ {
+ idx +=2 ;
+ cattext(dst,"\nENDDD\n");
+ break;
+ }
+ else
+ {
+ catchar(dst, at(src, idx));
+ idx++;
+ }
+ }
+ }
+ else idx++;
+ }
+}
+
+static void
+print_stack_level ()
+{
+ fprintf (stderr, "current string stack depth = %d, ", tos - stack);
+ fprintf (stderr, "current integer stack depth = %d\n", isp - istack);
+ pc++;
+}
+
+/* turn:
+ foobar name(stuff);
+ into:
+ foobar
+ name PARAMS ((stuff));
+ and a blank line.
+ */
+
+static void
+DEFUN_VOID(paramstuff)
+{
+ unsigned int openp;
+ unsigned int fname;
+ unsigned int idx;
+ string_type out;
+ init_string(&out);
+
+
+ /* make sure that it's not already param'd or proto'd */
+ if(find(tos,"PARAMS") || find(tos,"PROTO") || !find(tos,"(")) {
+ catstr(&out,tos);
+ }
+ else
+ {
+ /* Find the open paren */
+ for (openp = 0; at(tos, openp) != '(' && at(tos,openp); openp++)
+ ;
+
+ fname = openp;
+ /* Step back to the fname */
+ fname--;
+ while (fname && isspace((unsigned char) at(tos, fname)))
+ fname --;
+ while (fname
+ && !isspace((unsigned char) at(tos,fname))
+ && at(tos,fname) != '*')
+ fname--;
+
+ fname++;
+
+ for (idx = 0; idx < fname; idx++) /* Output type */
+ {
+ catchar(&out, at(tos,idx));
+ }
+
+ cattext(&out, "\n"); /* Insert a newline between type and fnname */
+
+ for (idx = fname; idx < openp; idx++) /* Output fnname */
+ {
+ catchar(&out, at(tos,idx));
+ }
+
+ cattext(&out," PARAMS (");
+
+ while (at(tos,idx) && at(tos,idx) !=';')
+ {
+ catchar(&out, at(tos, idx));
+ idx++;
+ }
+ cattext(&out,");\n\n");
+ }
+ overwrite_string(tos, &out);
+ pc++;
+
+}
+
+
+
+/* turn {*
+ and *} into comments */
+
+WORD(translatecomments)
+{
+ unsigned int idx = 0;
+ string_type out;
+ init_string(&out);
+
+ while (at(tos, idx))
+ {
+ if (at(tos,idx) == '{' && at(tos,idx+1) =='*')
+ {
+ cattext(&out,"/*");
+ idx+=2;
+ }
+ else if (at(tos,idx) == '*' && at(tos,idx+1) =='}')
+ {
+ cattext(&out,"*/");
+ idx+=2;
+ }
+ else
+ {
+ catchar(&out, at(tos, idx));
+ idx++;
+ }
+ }
+
+
+ overwrite_string(tos, &out);
+
+ pc++;
+
+}
+
+#if 0
+
+/* This is not currently used. */
+
+/* turn everything not starting with a . into a comment */
+
+WORD(manglecomments)
+{
+ unsigned int idx = 0;
+ string_type out;
+ init_string(&out);
+
+ while (at(tos, idx))
+ {
+ if (at(tos,idx) == '\n' && at(tos,idx+1) =='*')
+ {
+ cattext(&out," /*");
+ idx+=2;
+ }
+ else if (at(tos,idx) == '*' && at(tos,idx+1) =='}')
+ {
+ cattext(&out,"*/");
+ idx+=2;
+ }
+ else
+ {
+ catchar(&out, at(tos, idx));
+ idx++;
+ }
+ }
+
+
+ overwrite_string(tos, &out);
+
+ pc++;
+
+}
+
+#endif
+
+/* Mod tos so that only lines with leading dots remain */
+static void
+DEFUN_VOID(outputdots)
+{
+ unsigned int idx = 0;
+ string_type out;
+ init_string(&out);
+
+ while (at(tos, idx))
+ {
+ if (at(tos, idx) == '\n' && at(tos, idx+1) == '.')
+ {
+ char c;
+ idx += 2;
+
+ while ((c = at(tos, idx)) && c != '\n')
+ {
+ if (c == '{' && at(tos,idx+1) =='*')
+ {
+ cattext(&out," /*");
+ idx+=2;
+ }
+ else if (c == '*' && at(tos,idx+1) =='}')
+ {
+ cattext(&out,"*/");
+ idx+=2;
+ }
+ else
+ {
+ catchar(&out, c);
+ idx++;
+ }
+ }
+ catchar(&out,'\n');
+ }
+ else
+ {
+ idx++;
+ }
+ }
+
+ overwrite_string(tos, &out);
+ pc++;
+
+}
+
+/* Find lines starting with . and | and put example around them on tos */
+WORD(courierize)
+{
+ string_type out;
+ unsigned int idx = 0;
+ int command = 0;
+
+ init_string(&out);
+
+ while (at(tos, idx))
+ {
+ if (at(tos, idx) == '\n'
+ && (at(tos, idx +1 ) == '.'
+ || at(tos,idx+1) == '|'))
+ {
+ cattext(&out,"\n@example\n");
+ do
+ {
+ idx += 2;
+
+ while (at(tos, idx) && at(tos, idx)!='\n')
+ {
+ if (at(tos,idx)=='{' && at(tos,idx+1) =='*')
+ {
+ cattext(&out," /*");
+ idx+=2;
+ }
+ else if (at(tos,idx)=='*' && at(tos,idx+1) =='}')
+ {
+ cattext(&out,"*/");
+ idx+=2;
+ }
+ else if (at(tos,idx) == '{' && !command)
+ {
+ cattext(&out,"@{");
+ idx++;
+ }
+ else if (at(tos,idx) == '}' && !command)
+ {
+ cattext(&out,"@}");
+ idx++;
+ }
+ else
+ {
+ if (at(tos,idx) == '@')
+ command = 1;
+ else if (isspace((unsigned char) at(tos,idx))
+ || at(tos,idx) == '}')
+ command = 0;
+ catchar(&out, at(tos, idx));
+ idx++;
+ }
+
+ }
+ catchar(&out,'\n');
+ }
+ while (at(tos, idx) == '\n'
+ && ((at(tos, idx+1) == '.')
+ || (at(tos,idx+1) == '|')))
+ ;
+ cattext(&out,"@end example");
+ }
+ else
+ {
+ catchar(&out, at(tos, idx));
+ idx++;
+ }
+ }
+
+ overwrite_string(tos, &out);
+ pc++;
+
+
+}
+
+/* Finds any lines starting with "o ", if there are any, then turns
+ on @itemize @bullet, and @items each of them. Then ends with @end
+ itemize, inplace at TOS*/
+
+
+WORD(bulletize)
+{
+ unsigned int idx = 0;
+ int on = 0;
+ string_type out;
+ init_string(&out);
+
+ while (at(tos, idx)) {
+ if (at(tos, idx) == '@' &&
+ at(tos, idx+1) == '*')
+ {
+ cattext(&out,"*");
+ idx+=2;
+ }
+
+ else
+ if (at(tos, idx) == '\n' &&
+ at(tos, idx+1) == 'o' &&
+ isspace((unsigned char) at(tos, idx +2)))
+ {
+ if (!on)
+ {
+ cattext(&out,"\n@itemize @bullet\n");
+ on = 1;
+
+ }
+ cattext(&out,"\n@item\n");
+ idx+=3;
+ }
+ else
+ {
+ catchar(&out, at(tos, idx));
+ if (on && at(tos, idx) == '\n' &&
+ at(tos, idx+1) == '\n' &&
+ at(tos, idx+2) != 'o')
+ {
+ cattext(&out, "@end itemize");
+ on = 0;
+ }
+ idx++;
+
+ }
+ }
+ if (on)
+ {
+ cattext(&out,"@end itemize\n");
+ }
+
+ delete_string(tos);
+ *tos = out;
+ pc++;
+
+}
+
+/* Turn <<foo>> into @code{foo} in place at TOS*/
+
+
+WORD(do_fancy_stuff)
+{
+ unsigned int idx = 0;
+ string_type out;
+ init_string(&out);
+ while (at(tos, idx))
+ {
+ if (at(tos, idx) == '<'
+ && at(tos, idx+1) == '<'
+ && !isspace((unsigned char) at(tos,idx + 2)))
+ {
+ /* This qualifies as a << startup */
+ idx +=2;
+ cattext(&out,"@code{");
+ while(at(tos,idx) &&
+ at(tos,idx) != '>' )
+ {
+ catchar(&out, at(tos, idx));
+ idx++;
+
+ }
+ cattext(&out,"}");
+ idx+=2;
+ }
+ else
+ {
+ catchar(&out, at(tos, idx));
+ idx++;
+ }
+ }
+ delete_string(tos);
+ *tos = out;
+ pc++;
+
+}
+/* A command is all upper case,and alone on a line */
+static int
+DEFUN( iscommand,(ptr, idx),
+ string_type *ptr AND
+ unsigned int idx)
+{
+ unsigned int len = 0;
+ while (at(ptr,idx)) {
+ if (isupper((unsigned char) at(ptr,idx)) || at(ptr,idx) == ' ' ||
+ at(ptr,idx) == '_')
+ {
+ len++;
+ idx++;
+ }
+ else if(at(ptr,idx) == '\n')
+ {
+ if (len > 3) return 1;
+ return 0;
+ }
+ else return 0;
+ }
+ return 0;
+
+}
+
+
+static int
+DEFUN(copy_past_newline,(ptr, idx, dst),
+ string_type *ptr AND
+ unsigned int idx AND
+ string_type *dst)
+{
+ int column = 0;
+
+ while (at(ptr, idx) && at(ptr, idx) != '\n')
+ {
+ if (at (ptr, idx) == '\t')
+ {
+ /* Expand tabs. Neither makeinfo nor TeX can cope well with
+ them. */
+ do
+ catchar (dst, ' ');
+ while (++column & 7);
+ }
+ else
+ {
+ catchar(dst, at(ptr, idx));
+ column++;
+ }
+ idx++;
+
+ }
+ catchar(dst, at(ptr, idx));
+ idx++;
+ return idx;
+
+}
+
+WORD(icopy_past_newline)
+{
+ tos++;
+ check_range ();
+ init_string(tos);
+ idx = copy_past_newline(ptr, idx, tos);
+ pc++;
+}
+
+/* indent
+ Take the string at the top of the stack, do some prettying */
+
+
+WORD(kill_bogus_lines)
+{
+ int sl ;
+
+ int idx = 0;
+ int c;
+ int dot = 0 ;
+
+ string_type out;
+ init_string(&out);
+ /* Drop leading nl */
+ while (at(tos,idx) == '\n')
+ {
+ idx++;
+ }
+ c = idx;
+
+ /* If the first char is a '.' prepend a newline so that it is
+ recognized properly later. */
+ if (at (tos, idx) == '.')
+ catchar (&out, '\n');
+
+ /* Find the last char */
+ while (at(tos,idx))
+ {
+ idx++;
+ }
+
+ /* find the last non white before the nl */
+ idx--;
+
+ while (idx && isspace((unsigned char) at(tos,idx)))
+ idx--;
+ idx++;
+
+ /* Copy buffer upto last char, but blank lines before and after
+ dots don't count */
+ sl = 1;
+
+ while (c < idx)
+ {
+ if (at(tos,c) == '\n'
+ && at(tos,c+1) == '\n'
+ && at(tos,c+2) == '.')
+ {
+ /* Ignore two newlines before a dot*/
+ c++;
+ }
+ else if (at(tos,c) == '.' && sl)
+ {
+ /* remember that this line started with a dot */
+ dot=2;
+ }
+ else if (at(tos,c) == '\n'
+ && at(tos,c+1) == '\n'
+ && dot)
+ {
+ c++;
+ /* Ignore two newlines when last line was dot */
+ }
+
+ catchar(&out, at(tos,c));
+ if (at(tos,c) == '\n')
+ {
+ sl = 1;
+
+ if (dot == 2)dot=1;else dot = 0;
+ }
+ else
+ sl = 0;
+
+ c++;
+
+ }
+
+ /* Append nl*/
+ catchar(&out, '\n');
+ pc++;
+ delete_string(tos);
+ *tos = out;
+
+
+}
+
+WORD(indent)
+{
+ string_type out;
+ int tab = 0;
+ int idx = 0;
+ int ol =0;
+ init_string(&out);
+ while (at(tos,idx)) {
+ switch (at(tos,idx))
+ {
+ case '\n':
+ cattext(&out,"\n");
+ idx++;
+ if (tab && at(tos,idx))
+ {
+ cattext(&out," ");
+ }
+ ol = 0;
+ break;
+ case '(':
+ tab++;
+ if (ol == 0)
+ cattext(&out," ");
+ idx++;
+ cattext(&out,"(");
+ ol = 1;
+ break;
+ case ')':
+ tab--;
+ cattext(&out,")");
+ idx++;
+ ol=1;
+
+ break;
+ default:
+ catchar(&out,at(tos,idx));
+ ol=1;
+
+ idx++;
+ break;
+ }
+ }
+
+ pc++;
+ delete_string(tos);
+ *tos = out;
+
+}
+
+
+WORD(get_stuff_in_command)
+{
+ tos++;
+ check_range ();
+ init_string(tos);
+
+ while (at(ptr, idx)) {
+ if (iscommand(ptr, idx)) break;
+ idx = copy_past_newline(ptr, idx, tos);
+ }
+ pc++;
+}
+
+WORD(swap)
+{
+ string_type t;
+
+ t = tos[0];
+ tos[0] = tos[-1];
+ tos[-1] =t;
+ pc++;
+
+}
+
+WORD(other_dup)
+{
+ tos++;
+ check_range ();
+ init_string(tos);
+ catstr(tos, tos-1);
+ pc++;
+}
+
+WORD(drop)
+{
+ tos--;
+ check_range ();
+ pc++;
+}
+
+WORD(idrop)
+{
+ isp--;
+ icheck_range ();
+ pc++;
+}
+
+WORD(icatstr)
+{
+ tos--;
+ check_range ();
+ catstr(tos, tos+1);
+ delete_string(tos+1);
+ pc++;
+}
+
+WORD(skip_past_newline)
+{
+ while (at(ptr,idx)
+ && at(ptr,idx) != '\n')
+ idx++;
+ idx++;
+ pc++;
+}
+
+
+WORD(internalmode)
+{
+ internal_mode = *(isp);
+ isp--;
+ icheck_range ();
+ pc++;
+}
+
+WORD(maybecatstr)
+{
+ if (internal_wanted == internal_mode)
+ {
+ catstr(tos-1, tos);
+ }
+ delete_string(tos);
+ tos--;
+ check_range ();
+ pc++;
+}
+
+char *
+DEFUN(nextword,(string, word),
+ char *string AND
+ char **word)
+{
+ char *word_start;
+ int idx;
+ char *dst;
+ char *src;
+
+ int length = 0;
+
+ while (isspace((unsigned char) *string) || *string == '-') {
+ if (*string == '-')
+ {
+ while (*string && *string != '\n')
+ string++;
+
+ }
+ else {
+ string++;
+ }
+ }
+ if (!*string) return 0;
+
+ word_start = string;
+ if (*string == '"')
+ {
+ do
+ {
+ string++;
+ length++;
+ if (*string == '\\')
+ {
+ string += 2;
+ length += 2;
+ }
+ }
+ while (*string != '"');
+ }
+ else
+ {
+ while (!isspace((unsigned char) *string))
+ {
+ string++;
+ length++;
+
+ }
+ }
+
+ *word = malloc(length + 1);
+
+ dst = *word;
+ src = word_start;
+
+
+ for (idx= 0; idx < length; idx++)
+ {
+ if (src[idx] == '\\')
+ switch (src[idx+1])
+ {
+ case 'n':
+ *dst++ = '\n';
+ idx++;
+ break;
+ case '"':
+ case '\\':
+ *dst++ = src[idx+1];
+ idx++;
+ break;
+ default:
+ *dst++ = '\\';
+ break;
+ }
+ else
+ *dst++ = src[idx];
+ }
+ *dst++ = 0;
+
+
+
+
+
+ if(*string)
+ return string + 1;
+ else
+ return 0;
+
+}
+dict_type *root;
+dict_type *
+DEFUN(lookup_word,(word),
+ char *word)
+{
+ dict_type *ptr = root;
+ while (ptr) {
+ if (strcmp(ptr->word, word) == 0) return ptr;
+ ptr = ptr->next;
+
+ }
+ if (warning)
+ fprintf(stderr,"Can't find %s\n",word);
+ return 0;
+
+
+}
+
+static void DEFUN_VOID(perform)
+{
+ tos = stack;
+
+ while (at(ptr, idx)) {
+ /* It's worth looking through the command list */
+ if (iscommand(ptr, idx))
+ {
+ char *next;
+ dict_type *word ;
+
+ (void) nextword(addr(ptr, idx), &next);
+
+
+ word = lookup_word(next);
+
+
+
+
+ if (word)
+ {
+ exec(word);
+ }
+ else
+ {
+ if (warning)
+ fprintf(stderr,"warning, %s is not recognised\n", next);
+ skip_past_newline();
+ }
+
+ }
+ else skip_past_newline();
+
+ }
+}
+
+dict_type *
+DEFUN(newentry,(word),
+ char *word)
+{
+ dict_type *new = (dict_type *)malloc(sizeof(dict_type));
+ new->word = word;
+ new->next = root;
+ root = new;
+ new->code = (stinst_type *)malloc(sizeof(stinst_type ));
+ new->code_length = 1;
+ new->code_end = 0;
+ return new;
+
+}
+
+
+unsigned int
+DEFUN(add_to_definition,(entry, word),
+ dict_type *entry AND
+ stinst_type word)
+{
+ if (entry->code_end == entry->code_length)
+ {
+ entry->code_length += 2;
+ entry->code =
+ (stinst_type *) realloc((char *)(entry->code),
+ entry->code_length *sizeof(word_type));
+ }
+ entry->code[entry->code_end] = word;
+
+return entry->code_end++;
+}
+
+
+
+
+
+
+
+void
+DEFUN(add_intrinsic,(name, func),
+ char *name AND
+ void (*func)())
+{
+ dict_type *new = newentry(name);
+ add_to_definition(new, func);
+ add_to_definition(new, 0);
+}
+
+void
+DEFUN(add_var,(name),
+ char *name)
+{
+ dict_type *new = newentry(name);
+ add_to_definition(new, push_number);
+ add_to_definition(new, (stinst_type)(&(new->var)));
+ add_to_definition(new,0);
+}
+
+
+void
+DEFUN(compile, (string),
+ char *string)
+{
+ /* add words to the dictionary */
+ char *word;
+ string = nextword(string, &word);
+ while (string && *string && word[0])
+ {
+ if (strcmp(word,"var")==0)
+ {
+ string=nextword(string, &word);
+
+ add_var(word);
+ string=nextword(string, &word);
+ }
+else
+
+ if (word[0] == ':')
+ {
+ dict_type *ptr;
+ /* Compile a word and add to dictionary */
+ string = nextword(string, &word);
+
+ ptr = newentry(word);
+ string = nextword(string, &word);
+ while (word[0] != ';' )
+ {
+ switch (word[0])
+ {
+ case '"':
+ /* got a string, embed magic push string
+ function */
+ add_to_definition(ptr, push_text);
+ add_to_definition(ptr, (stinst_type)(word+1));
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* Got a number, embedd the magic push number
+ function */
+ add_to_definition(ptr, push_number);
+ add_to_definition(ptr, (stinst_type)atol(word));
+ break;
+ default:
+ add_to_definition(ptr, call);
+ add_to_definition(ptr, (stinst_type)lookup_word(word));
+ }
+
+ string = nextword(string, &word);
+ }
+ add_to_definition(ptr,0);
+ string = nextword(string, &word);
+ }
+ else
+ {
+ fprintf(stderr,"syntax error at %s\n",string-1);
+ }
+ }
+
+}
+
+
+static void DEFUN_VOID(bang)
+{
+ *(long *)((isp[0])) = isp[-1];
+ isp-=2;
+ icheck_range ();
+ pc++;
+}
+
+WORD(atsign)
+{
+ isp[0] = *(long *)(isp[0]);
+ pc++;
+}
+
+WORD(hello)
+{
+ printf("hello\n");
+ pc++;
+}
+
+WORD(stdout_)
+{
+ isp++;
+ icheck_range ();
+ *isp = 1;
+ pc++;
+}
+
+WORD(stderr_)
+{
+ isp++;
+ icheck_range ();
+ *isp = 2;
+ pc++;
+}
+
+WORD(print)
+{
+ if (*isp == 1)
+ write_buffer (tos, stdout);
+ else if (*isp == 2)
+ write_buffer (tos, stderr);
+ else
+ fprintf (stderr, "print: illegal print destination `%ld'\n", *isp);
+ isp--;
+ tos--;
+ icheck_range ();
+ check_range ();
+ pc++;
+}
+
+
+static void DEFUN(read_in, (str, file),
+ string_type *str AND
+ FILE *file)
+{
+ char buff[10000];
+ unsigned int r;
+ do
+ {
+ r = fread(buff, 1, sizeof(buff), file);
+ catbuf(str, buff, r);
+ }
+ while (r);
+ buff[0] = 0;
+
+ catbuf(str, buff,1);
+}
+
+
+static void DEFUN_VOID(usage)
+{
+ fprintf(stderr,"usage: -[d|i|g] <file >file\n");
+ exit(33);
+}
+
+/* There is no reliable way to declare exit. Sometimes it returns
+ int, and sometimes it returns void. Sometimes it changes between
+ OS releases. Trying to get it declared correctly in the hosts file
+ is a pointless waste of time. */
+
+static void
+chew_exit ()
+{
+ exit (0);
+}
+
+int DEFUN(main,(ac,av),
+int ac AND
+char *av[])
+{
+ unsigned int i;
+ string_type buffer;
+ string_type pptr;
+
+ init_string(&buffer);
+ init_string(&pptr);
+ init_string(stack+0);
+ tos=stack+1;
+ ptr = &pptr;
+
+ add_intrinsic("push_text", push_text);
+ add_intrinsic("!", bang);
+ add_intrinsic("@", atsign);
+ add_intrinsic("hello",hello);
+ add_intrinsic("stdout",stdout_);
+ add_intrinsic("stderr",stderr_);
+ add_intrinsic("print",print);
+ add_intrinsic("skip_past_newline", skip_past_newline );
+ add_intrinsic("catstr", icatstr );
+ add_intrinsic("copy_past_newline", icopy_past_newline );
+ add_intrinsic("dup", other_dup );
+ add_intrinsic("drop", drop);
+ add_intrinsic("idrop", idrop);
+ add_intrinsic("remchar", remchar );
+ add_intrinsic("get_stuff_in_command", get_stuff_in_command );
+ add_intrinsic("do_fancy_stuff", do_fancy_stuff );
+ add_intrinsic("bulletize", bulletize );
+ add_intrinsic("courierize", courierize );
+ /* If the following line gives an error, exit() is not declared in the
+ ../hosts/foo.h file for this host. Fix it there, not here! */
+ /* No, don't fix it anywhere; see comment on chew_exit--Ian Taylor. */
+ add_intrinsic("exit", chew_exit );
+ add_intrinsic("swap", swap );
+ add_intrinsic("outputdots", outputdots );
+ add_intrinsic("paramstuff", paramstuff );
+ add_intrinsic("maybecatstr", maybecatstr );
+ add_intrinsic("translatecomments", translatecomments );
+ add_intrinsic("kill_bogus_lines", kill_bogus_lines);
+ add_intrinsic("indent", indent);
+ add_intrinsic("internalmode", internalmode);
+ add_intrinsic("print_stack_level", print_stack_level);
+ add_intrinsic("strip_trailing_newlines", strip_trailing_newlines);
+
+ /* Put a nl at the start */
+ catchar(&buffer,'\n');
+
+ read_in(&buffer, stdin);
+ remove_noncomments(&buffer, ptr);
+ for (i= 1; i < (unsigned int) ac; i++)
+ {
+ if (av[i][0] == '-')
+ {
+ if (av[i][1] == 'f')
+ {
+ string_type b;
+ FILE *f;
+ init_string(&b);
+
+ f = fopen(av[i+1],"r");
+ if (!f)
+ {
+ fprintf(stderr,"Can't open the input file %s\n",av[i+1]);
+ return 33;
+ }
+
+ read_in(&b, f);
+ compile(b.ptr);
+ perform();
+ }
+ else if (av[i][1] == 'i')
+ {
+ internal_wanted = 1;
+ }
+ else if (av[i][1] == 'w')
+ {
+ warning = 1;
+ }
+ else
+ usage ();
+ }
+ }
+ write_buffer(stack+0, stdout);
+ if (tos != stack)
+ {
+ fprintf (stderr, "finishing with current stack level %d\n", tos - stack);
+ return 1;
+ }
+ return 0;
+}
diff --git a/bfd/doc/doc.str b/bfd/doc/doc.str
new file mode 100644
index 00000000000..7a276fe59e6
--- /dev/null
+++ b/bfd/doc/doc.str
@@ -0,0 +1,158 @@
+: DOCDD
+ skip_past_newline
+ get_stuff_in_command kill_bogus_lines catstr
+ ;
+
+: ENDDD
+ skip_past_newline
+ ;
+
+: EXAMPLE
+ skip_past_newline
+ get_stuff_in_command kill_bogus_lines do_fancy_stuff translatecomments
+ courierize catstr
+
+ ;
+
+: INODE
+ "@node " catstr skip_past_newline copy_past_newline catstr
+ ;
+
+: CODE_FRAGMENT
+ EXAMPLE
+ ;
+
+: COMMENT
+ skip_past_newline
+ get_stuff_in_command
+ drop
+ ;
+
+: SYNOPSIS
+ skip_past_newline
+ "@strong{Synopsis}\n" catstr
+ "@example\n" catstr
+ get_stuff_in_command
+ kill_bogus_lines
+ indent
+ catstr
+ "@end example\n" catstr
+
+ ;
+
+: func
+ "@findex " - a
+ skip_past_newline
+ copy_past_newline
+ dup - a x x
+ "@subsubsection @code{" - a x x b
+ swap
+ remchar
+ "}\n" - a x b x c
+ catstr catstr catstr catstr catstr
+ ;
+
+: FUNCTION
+ "@findex " - a
+ skip_past_newline
+ copy_past_newline
+ dup - a x x
+ "@subsubsection @code{" - a x x b
+ swap
+ remchar
+ "}\n" - a x b x c
+ catstr catstr catstr catstr catstr
+ ;
+
+: bodytext
+ get_stuff_in_command
+ bulletize
+ kill_bogus_lines
+ do_fancy_stuff
+ courierize
+ catstr
+ "\n" catstr
+ ;
+
+: asection
+ skip_past_newline
+ catstr
+ copy_past_newline
+ do_fancy_stuff catstr
+ bodytext
+ ;
+
+: SECTION
+ "@section " asection ;
+
+: SUBSECTION
+ "@subsection " asection ;
+
+: SUBSUBSECTION
+ "@subsubsection " asection ;
+
+: subhead
+ skip_past_newline
+ bodytext
+ ;
+
+
+
+
+: DESCRIPTION
+ "@strong{Description}@*\n" catstr subhead ;
+
+: RETURNS
+ "@strong{Returns}@*\n" catstr subhead ;
+
+: INTERNAL_FUNCTION
+ func ;
+
+
+: INTERNAL_DEFINITION
+ func ;
+
+
+: INTERNAL
+ func ;
+
+: TYPEDEF
+ FUNCTION ;
+
+: SENUM
+ skip_past_newline
+ "Here are the possible values for @code{enum "
+ copy_past_newline remchar catstr
+ "}:\n\n" catstr catstr
+ ;
+: ENUM
+ skip_past_newline
+ "@deffn {} "
+ copy_past_newline catstr catstr
+ ;
+: ENUMX
+ skip_past_newline
+ "@deffnx {} "
+ copy_past_newline catstr
+ catstr
+ ;
+: ENUMEQ
+ skip_past_newline
+ "@deffn {} "
+ copy_past_newline catstr catstr
+ skip_past_newline
+ ;
+: ENUMEQX
+ skip_past_newline
+ "@deffnx {} "
+ copy_past_newline catstr
+ catstr
+ skip_past_newline
+ ;
+: ENUMDOC
+ skip_past_newline
+ get_stuff_in_command
+ strip_trailing_newlines
+ catstr
+ "\n@end deffn\n" catstr
+ ;
diff --git a/bfd/doc/makefile.vms b/bfd/doc/makefile.vms
new file mode 100644
index 00000000000..a0857c0caaf
--- /dev/null
+++ b/bfd/doc/makefile.vms
@@ -0,0 +1,5 @@
+CFLAGS = /noopt/include=([],[-],[-.-.include])
+LDFLAGS = /nomap
+LDLIBS = ,sys$$library:vaxcrtl.olb/lib
+
+all: chew.exe
diff --git a/bfd/doc/proto.str b/bfd/doc/proto.str
new file mode 100644
index 00000000000..8431c16bd57
--- /dev/null
+++ b/bfd/doc/proto.str
@@ -0,0 +1,135 @@
+
+: SYNOPSIS
+ skip_past_newline
+ get_stuff_in_command
+ paramstuff
+ indent
+ maybecatstr
+;
+
+: ignore
+ skip_past_newline
+ get_stuff_in_command
+ outputdots
+ maybecatstr
+ ;
+
+: CODE_FRAGMENT
+ ignore ;
+
+: external
+ 0 internalmode ignore ;
+
+: internal
+ 1 internalmode ignore ;
+
+- input stack { a b } output b if internal, a if external
+: ifinternal
+ "" swap 1 internalmode maybecatstr
+ swap
+ "" swap 0 internalmode maybecatstr
+ catstr
+ ;
+
+- Put note in output string, regardless of internal mode.
+: COMMENT
+ skip_past_newline
+ get_stuff_in_command
+ translatecomments
+ catstr
+ ;
+
+- SENUM enum-type-name
+- ENUM enum-name
+- ENUMX addl-enum-name
+- ENUMDOC doc for preceding enums
+- ENDSENUM max-enum-name
+
+: make_enum_header
+ dup
+ "enum " swap catstr
+ " {\n" catstr
+ swap " _dummy_first_" swap catstr catstr
+ ",\n" catstr
+ ;
+: make_string_table_header
+ dup
+ "#ifdef _BFD_MAKE_TABLE_" swap catstr swap
+ "\n\nstatic const char *const " swap catstr catstr
+ "_names[] = { \"@@uninitialized@@\",\n" catstr
+ ;
+: SENUM
+ skip_past_newline
+ copy_past_newline
+ remchar
+ dup
+ make_enum_header
+ swap
+ make_string_table_header
+ ifinternal
+ catstr
+ get_stuff_in_command catstr
+ translatecomments ;
+: ENDSENUM
+ skip_past_newline
+ copy_past_newline strip_trailing_newlines
+ dup
+ " " swap catstr " };\n" catstr swap
+ " \"@@overflow: " swap catstr "@@\",\n};\n#endif\n\n" catstr
+ ifinternal
+ catstr
+ ;
+: make_enumerator
+ " " swap catstr
+ ",\n" catstr
+ ;
+: make_enumerator_string
+ " \"" swap catstr
+ "\",\n" catstr
+ ;
+: ENUM
+ skip_past_newline
+ copy_past_newline
+ remchar
+ dup
+ make_enumerator
+ swap
+ make_enumerator_string
+ ifinternal
+ ;
+: ENUMX ENUM catstr ;
+: ENUMEQ
+ skip_past_newline
+ "#define "
+ copy_past_newline remchar
+ catstr
+ " "
+ catstr
+ copy_past_newline
+ catstr
+ "" swap 0 internalmode maybecatstr
+ ;
+: ENUMEQX ENUMEQ catstr ;
+: ENUMDOC
+ skip_past_newline
+ get_stuff_in_command
+ strip_trailing_newlines
+ "\n{* " swap catstr " *}\n" catstr
+ translatecomments
+ - discard it if we're doing internal mode
+ "" swap 0 internalmode maybecatstr
+ swap
+ catstr catstr
+ ;
+: ENDDD external ;
+: SECTION ignore ;
+: SUBSECTION ignore ;
+: SUBSUBSECTION ignore ;
+: INTERNAL_DEFINITION internal ;
+: DESCRIPTION ignore ;
+: FUNCTION external ;
+: RETURNS ignore ;
+: TYPEDEF external ;
+: INTERNAL_FUNCTION internal ;
+: INTERNAL internal ;
+: INODE ignore ;
diff --git a/bfd/dwarf1.c b/bfd/dwarf1.c
new file mode 100644
index 00000000000..cbcc26b0035
--- /dev/null
+++ b/bfd/dwarf1.c
@@ -0,0 +1,576 @@
+/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
+ Copyright 1998 Free Software Foundation, Inc.
+
+Written by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com).
+
+This file is part of BFD.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/dwarf.h"
+
+/* dwarf1_debug is the starting point for all dwarf1 info. */
+
+struct dwarf1_debug {
+
+ /* The bfd we are working with. */
+ bfd* abfd;
+
+ /* List of already parsed compilation units. */
+ struct dwarf1_unit* lastUnit;
+
+ /* The buffer for the .debug section.
+ Zero indicates that the .debug section failed to load. */
+ char* debug_section;
+
+ /* Pointer to the end of the .debug_info section memory buffer. */
+ char* debug_section_end;
+
+ /* The buffer for the .line section. */
+ char* line_section;
+
+ /* End of that buffer. */
+ char* line_section_end;
+
+ /* The current or next unread die within the .debug section. */
+ char* currentDie;
+};
+
+/* One dwarf1_unit for each parsed compilation unit die. */
+
+struct dwarf1_unit {
+ /* Linked starting from stash->lastUnit. */
+ struct dwarf1_unit* prev;
+
+ /* Name of the compilation unit. */
+ char* name;
+
+ /* The highest and lowest address used in the compilation unit. */
+ unsigned long low_pc;
+ unsigned long high_pc;
+
+ /* Does this unit have a statement list? */
+ int has_stmt_list;
+
+ /* If any, the offset of the line number table in the .line section. */
+ unsigned long stmt_list_offset;
+
+ /* If non-zero, a pointer to the first child of this unit. */
+ char* first_child;
+
+ /* How many line entries? */
+ unsigned long line_count;
+
+ /* The decoded line number table (line_count entries). */
+ struct linenumber* linenumber_table;
+
+ /* The list of functions in this unit. */
+ struct dwarf1_func* func_list;
+};
+
+
+
+/* One dwarf1_func for each parsed function die. */
+
+struct dwarf1_func {
+ /* Linked starting from aUnit->func_list. */
+ struct dwarf1_func* prev;
+
+ /* Name of function. */
+ char* name;
+
+ /* The highest and lowest address used in the compilation unit. */
+ unsigned long low_pc;
+ unsigned long high_pc;
+};
+
+
+/* Used to return info about a parsed die. */
+struct die_info {
+ unsigned long length;
+ unsigned long sibling;
+ unsigned long low_pc;
+ unsigned long high_pc;
+ unsigned long stmt_list_offset;
+
+ char* name;
+
+ int has_stmt_list;
+
+ unsigned short tag;
+};
+
+
+/* Parsed line number information. */
+struct linenumber {
+ /* First address in the line. */
+ unsigned long addr;
+
+ /* The line number. */
+ unsigned long linenumber;
+};
+
+
+/* Find the form of an attr, from the attr field. */
+#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */
+
+
+/* Return a newly allocated dwarf1_unit. It should be cleared and
+ then attached into the 'stash' at 'stash->lastUnit'. */
+
+static struct dwarf1_unit*
+alloc_dwarf1_unit (stash)
+ struct dwarf1_debug* stash;
+{
+ struct dwarf1_unit* x =
+ (struct dwarf1_unit*) bfd_alloc (stash->abfd,
+ sizeof (struct dwarf1_unit));
+ x->prev = stash->lastUnit;
+ stash->lastUnit = x;
+
+ return x;
+}
+
+/* Return a newly allocated dwarf1_func. It must be cleared and
+ attached into 'aUnit' at 'aUnit->func_list'. */
+
+static struct dwarf1_func*
+alloc_dwarf1_func (stash, aUnit)
+ struct dwarf1_debug* stash;
+ struct dwarf1_unit* aUnit;
+{
+ struct dwarf1_func* x =
+ (struct dwarf1_func*) bfd_alloc (stash->abfd,
+ sizeof (struct dwarf1_func));
+ x->prev = aUnit->func_list;
+ aUnit->func_list = x;
+
+ return x;
+}
+
+/* parse_die - parse a Dwarf1 die.
+ Parse the die starting at 'aDiePtr' into 'aDieInfo'.
+ 'abfd' must be the bfd from which the section that 'aDiePtr'
+ points to was pulled from.
+
+ Return false if the die is invalidly formatted; true otherwise. */
+
+static boolean
+parse_die (abfd, aDieInfo, aDiePtr)
+ bfd* abfd;
+ struct die_info* aDieInfo;
+ char* aDiePtr;
+{
+ char* this_die = aDiePtr;
+ char* xptr = this_die;
+
+ memset (aDieInfo,0,sizeof(*aDieInfo));
+
+ /* First comes the length. */
+ aDieInfo->length = bfd_get_32 (abfd, xptr);
+ xptr += 4;
+ if (aDieInfo->length < 6)
+ {
+ /* Just padding bytes. */
+ aDieInfo->tag = TAG_padding;
+ return true;
+ }
+
+ /* Then the tag. */
+ aDieInfo->tag = bfd_get_16 (abfd, xptr);
+ xptr += 2;
+
+ /* Then the attributes. */
+ while (xptr < (this_die + aDieInfo->length))
+ {
+ unsigned short attr;
+
+ /* Parse the attribute based on its form. This section
+ must handle all dwarf1 forms, but need only handle the
+ actual attributes that we care about. */
+
+ attr = bfd_get_16 (abfd, xptr);
+ xptr += 2;
+
+ switch (FORM_FROM_ATTR (attr))
+ {
+ case FORM_DATA2:
+ xptr += 2;
+ break;
+ case FORM_DATA4:
+ case FORM_REF:
+ if (attr == AT_sibling)
+ aDieInfo->sibling = bfd_get_32 (abfd, xptr);
+ else if (attr == AT_stmt_list)
+ {
+ aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr);
+ aDieInfo->has_stmt_list = 1;
+ }
+ xptr += 4;
+ break;
+ case FORM_DATA8:
+ xptr += 8;
+ break;
+ case FORM_ADDR:
+ if (attr == AT_low_pc)
+ aDieInfo->low_pc = bfd_get_32 (abfd, xptr);
+ else if (attr == AT_high_pc)
+ aDieInfo->high_pc = bfd_get_32 (abfd, xptr);
+ xptr += 4;
+ break;
+ case FORM_BLOCK2:
+ xptr += 2 + bfd_get_16 (abfd, xptr);
+ break;
+ case FORM_BLOCK4:
+ xptr += 4 + bfd_get_32 (abfd, xptr);
+ break;
+ case FORM_STRING:
+ if (attr == AT_name)
+ aDieInfo->name = xptr;
+ xptr += strlen (xptr) + 1;
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
+ into 'aUnit->linenumber_table'. Return false if an error
+ occurs; true otherwise. */
+
+static boolean
+parse_line_table (stash, aUnit)
+ struct dwarf1_debug* stash;
+ struct dwarf1_unit* aUnit;
+{
+ char* xptr;
+
+ /* Load the ".line" section from the bfd if we haven't already. */
+ if (stash->line_section == 0)
+ {
+ asection *msec;
+ unsigned long size;
+
+ msec = bfd_get_section_by_name (stash->abfd, ".line");
+ if (! msec)
+ return false;
+
+ size = bfd_get_section_size_before_reloc (msec);
+ stash->line_section = (unsigned char*) bfd_alloc (stash->abfd, size);
+
+ if (! stash->line_section)
+ return false;
+
+ if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section, 0, size))
+ {
+ stash->line_section = 0;
+ return false;
+ }
+
+ stash->line_section_end = stash->line_section + size;
+ }
+
+ xptr = stash->line_section + aUnit->stmt_list_offset;
+ if (xptr < stash->line_section_end)
+ {
+ int eachLine;
+
+ char* tblend;
+ unsigned long base;
+
+ /* First comes the length. */
+ tblend = bfd_get_32 (stash->abfd, xptr) + xptr;
+ xptr += 4;
+
+ /* Then the base address for each address in the table. */
+ base = bfd_get_32 (stash->abfd, xptr);
+ xptr += 4;
+
+ /* How many line entrys?
+ 10 = 4 (line number) + 2 (pos in line) + 4 (address in line) */
+ aUnit->line_count = (tblend - xptr) / 10;
+
+ /* Allocate an array for the entries. */
+ aUnit->linenumber_table = (struct linenumber*)
+ bfd_alloc (stash->abfd,
+ sizeof (struct linenumber) * aUnit->line_count);
+
+ for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
+ {
+ /* A line number. */
+ aUnit->linenumber_table[eachLine].linenumber
+ = bfd_get_32 (stash->abfd, xptr);
+ xptr += 4;
+
+ /* Skip the position within the line. */
+ xptr += 2;
+
+ /* And finally the address. */
+ aUnit->linenumber_table[eachLine].addr
+ = base + bfd_get_32 (stash->abfd, xptr);
+ xptr += 4;
+ }
+ }
+
+ return true;
+}
+
+/* Parse each function die in a compilation unit 'aUnit'.
+ The first child die of 'aUnit' should be in 'aUnit->first_child',
+ the result is placed in 'aUnit->func_list'.
+ Return false if error; true otherwise. */
+
+static boolean
+parse_functions_in_unit (stash, aUnit)
+ struct dwarf1_debug* stash;
+ struct dwarf1_unit* aUnit;
+{
+ char* eachDie;
+
+ if (aUnit->first_child)
+ for (eachDie = aUnit->first_child;
+ eachDie < stash->debug_section_end;
+ )
+ {
+ struct die_info eachDieInfo;
+
+ if (! parse_die (stash->abfd, &eachDieInfo, eachDie))
+ return false;
+
+ if (eachDieInfo.tag == TAG_global_subroutine
+ || eachDieInfo.tag == TAG_subroutine
+ || eachDieInfo.tag == TAG_inlined_subroutine
+ || eachDieInfo.tag == TAG_entry_point)
+ {
+ struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit);
+
+ aFunc->name = eachDieInfo.name;
+ aFunc->low_pc = eachDieInfo.low_pc;
+ aFunc->high_pc = eachDieInfo.high_pc;
+ }
+
+ /* Move to next sibling, if none, end loop */
+ if (eachDieInfo.sibling)
+ eachDie = stash->debug_section + eachDieInfo.sibling;
+ else
+ break;
+ }
+
+ return true;
+}
+
+/* Find the nearest line to 'addr' in 'aUnit'.
+ Return whether we found the line (or a function) without error. */
+
+static boolean
+dwarf1_unit_find_nearest_line (stash, aUnit, addr,
+ filename_ptr, functionname_ptr,
+ linenumber_ptr)
+ struct dwarf1_debug* stash;
+ struct dwarf1_unit* aUnit;
+ unsigned long addr;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *linenumber_ptr;
+{
+ int line_p = false;
+ int func_p = false;
+
+ if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
+ {
+ if (aUnit->has_stmt_list)
+ {
+ int i;
+ struct dwarf1_func* eachFunc;
+
+ if (! aUnit->linenumber_table)
+ {
+ if (! parse_line_table (stash, aUnit))
+ return false;
+ }
+
+ if (! aUnit->func_list)
+ {
+ if (! parse_functions_in_unit (stash, aUnit))
+ return false;
+ }
+
+ for (i = 0; i < aUnit->line_count; i++)
+ {
+ if (aUnit->linenumber_table[i].addr <= addr
+ && addr < aUnit->linenumber_table[i+1].addr)
+ {
+ *filename_ptr = aUnit->name;
+ *linenumber_ptr = aUnit->linenumber_table[i].linenumber;
+ line_p = true;
+ break;
+ }
+ }
+
+ for (eachFunc = aUnit->func_list;
+ eachFunc;
+ eachFunc = eachFunc->prev)
+ {
+ if (eachFunc->low_pc <= addr
+ && addr < eachFunc->high_pc)
+ {
+ *functionname_ptr = eachFunc->name;
+ func_p = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return line_p || func_p;
+}
+
+
+
+
+/* The DWARF 1 version of find_nearest line.
+ Return true if the line is found without error. */
+
+boolean
+_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr, linenumber_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *linenumber_ptr;
+{
+ struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info;
+
+ struct dwarf1_unit* eachUnit;
+
+ /* What address are we looking for? */
+ bfd_vma addr = offset + section->vma;
+
+ *filename_ptr = NULL;
+ *functionname_ptr = NULL;
+ *linenumber_ptr = 0;
+
+
+ if (! stash)
+ {
+ asection *msec;
+ unsigned long size;
+
+ stash = elf_tdata (abfd)->dwarf1_find_line_info =
+ (struct dwarf1_debug*) bfd_zalloc (abfd, sizeof (struct dwarf1_debug));
+
+ if (! stash)
+ return false;
+
+ msec = bfd_get_section_by_name (abfd, ".debug");
+ if (! msec)
+ {
+ /* No dwarf1 info. Note that at this point the stash
+ has been allocated, but contains zeros, this lets
+ future calls to this function fail quicker. */
+ return false;
+ }
+
+ size = bfd_get_section_size_before_reloc (msec);
+ stash->debug_section = (unsigned char*) bfd_alloc (abfd, size);
+
+ if (! stash->debug_section)
+ return false;
+
+ if (! bfd_get_section_contents (abfd, msec, stash->debug_section, 0, size))
+ {
+ stash->debug_section = 0;
+ return false;
+ }
+
+ stash->debug_section_end = stash->debug_section + size;
+ stash->currentDie = stash->debug_section;
+ stash->abfd = abfd;
+ }
+
+ /* A null debug_section indicates that there was no dwarf1 info
+ or that an error occured while setting up the stash. */
+
+ if (! stash->debug_section)
+ return false;
+
+
+ /* Look at the previously parsed units to see if any contain
+ the addr. */
+ for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev)
+ {
+ if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc)
+ return dwarf1_unit_find_nearest_line (stash, eachUnit, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr);
+ }
+
+ while (stash->currentDie < stash->debug_section_end)
+ {
+ struct die_info aDieInfo;
+
+ if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie))
+ return false;
+
+ if (aDieInfo.tag == TAG_compile_unit)
+ {
+ struct dwarf1_unit* aUnit
+ = alloc_dwarf1_unit (stash);
+
+ aUnit->name = aDieInfo.name;
+ aUnit->low_pc = aDieInfo.low_pc;
+ aUnit->high_pc = aDieInfo.high_pc;
+ aUnit->has_stmt_list = aDieInfo.has_stmt_list;
+ aUnit->stmt_list_offset = aDieInfo.stmt_list_offset;
+
+ /* A die has a child if it's followed by a die that is
+ not it's sibling. */
+ if (aDieInfo.sibling
+ && stash->currentDie + aDieInfo.length
+ < stash->debug_section_end
+ && stash->currentDie + aDieInfo.length
+ != stash->debug_section + aDieInfo.sibling)
+ aUnit->first_child = stash->currentDie + aDieInfo.length;
+ else
+ aUnit->first_child = 0;
+
+ if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
+ return dwarf1_unit_find_nearest_line (stash, aUnit, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr);
+ }
+
+ if (aDieInfo.sibling != 0)
+ stash->currentDie = stash->debug_section + aDieInfo.sibling;
+ else
+ stash->currentDie += aDieInfo.length;
+ }
+
+ return false;
+}
+
+
+/* EOF */
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
new file mode 100644
index 00000000000..385bf821b6e
--- /dev/null
+++ b/bfd/dwarf2.c
@@ -0,0 +1,1466 @@
+/* DWARF 2 support.
+ Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
+ (gavin@cygnus.com).
+
+ From the dwarf2read.c header:
+ Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+ Inc. with support from Florida State University (under contract
+ with the Ada Joint Program Office), and Silicon Graphics, Inc.
+ Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+ based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+ support in dwarfread.c
+
+This file is part of BFD.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/dwarf2.h"
+
+/* The data in the .debug_line statement prologue looks like this. */
+struct line_head
+ {
+ unsigned int total_length;
+ unsigned short version;
+ unsigned int prologue_length;
+ unsigned char minimum_instruction_length;
+ unsigned char default_is_stmt;
+ int line_base;
+ unsigned char line_range;
+ unsigned char opcode_base;
+ unsigned char *standard_opcode_lengths;
+ };
+
+/* Attributes have a name and a value */
+struct attribute
+ {
+ enum dwarf_attribute name;
+ enum dwarf_form form;
+ union
+ {
+ char *str;
+ struct dwarf_block *blk;
+ unsigned int unsnd;
+ int snd;
+ bfd_vma addr;
+ }
+ u;
+ };
+
+/* Get at parts of an attribute structure */
+
+#define DW_STRING(attr) ((attr)->u.str)
+#define DW_UNSND(attr) ((attr)->u.unsnd)
+#define DW_BLOCK(attr) ((attr)->u.blk)
+#define DW_SND(attr) ((attr)->u.snd)
+#define DW_ADDR(attr) ((attr)->u.addr)
+
+/* Blocks are a bunch of untyped bytes. */
+struct dwarf_block
+ {
+ unsigned int size;
+ char *data;
+ };
+
+
+struct dwarf2_debug {
+
+ /* A list of all previously read comp_units. */
+ struct comp_unit* all_comp_units;
+
+ /* The next unread compilation unit within the .debug_info section.
+ Zero indicates that the .debug_info section has not been loaded
+ into a buffer yet.*/
+ char* info_ptr;
+
+ /* Pointer to the end of the .debug_info section memory buffer. */
+ char* info_ptr_end;
+
+ /* Pointer to the .debug_abbrev section loaded into memory. */
+ char* dwarf_abbrev_buffer;
+
+ /* Length of the loaded .debug_abbrev section. */
+ unsigned long dwarf_abbrev_size;
+};
+
+
+
+/* A minimal decoding of DWARF2 compilation units. We only decode
+ what's needed to get to the line number information. */
+
+struct comp_unit {
+
+ /* Chain the previously read compilation units. */
+ struct comp_unit* next_unit;
+
+ /* Keep the bdf convenient (for memory allocation). */
+ bfd* abfd;
+
+ /* The lowest and higest addresses contained in this compilation
+ unit as specified in the compilation unit header. */
+ bfd_vma low;
+ bfd_vma high;
+
+ /* The DW_AT_name attribute (for error messages). */
+ char* name;
+
+ /* The abbrev hash table. */
+ struct abbrev_info** abbrevs;
+
+ /* Note that an error was found by comp_unit_find_nearest_line. */
+ int error;
+
+ /* The DW_AT_comp_dir attribute */
+ char* comp_dir;
+
+ /* True if there is a line number table associated with this comp. unit. */
+ int stmtlist;
+
+ /* The offset into .debug_line of the line number table. */
+ unsigned long line_offset;
+
+ /* Pointer to the first child die for the comp unit. */
+ char *first_child_die_ptr;
+
+ /* The end of the comp unit. */
+ char *end_ptr;
+
+ /* The decoded line number, NULL if not yet decoded. */
+ struct line_info_table* line_table;
+
+ /* A list of the functions found in this comp. unit. */
+ struct funcinfo* function_table;
+
+ /* Address size for this unit - from unit header */
+ unsigned char addr_size;
+};
+
+
+
+/* VERBATIM
+ The following function up to the END VERBATIM mark are
+ copied directly from dwarf2read.c. */
+
+/* read dwarf information from a buffer */
+
+static unsigned int
+read_1_byte (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_8 (abfd, (bfd_byte *) buf);
+}
+
+static int
+read_1_signed_byte (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_signed_8 (abfd, (bfd_byte *) buf);
+}
+
+static unsigned int
+read_2_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_16 (abfd, (bfd_byte *) buf);
+}
+
+#if 0
+
+/* This is not used. */
+
+static int
+read_2_signed_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_signed_16 (abfd, (bfd_byte *) buf);
+}
+
+#endif
+
+static unsigned int
+read_4_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_32 (abfd, (bfd_byte *) buf);
+}
+
+#if 0
+
+/* This is not used. */
+
+static int
+read_4_signed_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_signed_32 (abfd, (bfd_byte *) buf);
+}
+
+#endif
+
+static unsigned int
+read_8_bytes (abfd, buf)
+ bfd *abfd;
+ char *buf;
+{
+ return bfd_get_64 (abfd, (bfd_byte *) buf);
+}
+
+static char *
+read_n_bytes (abfd, buf, size)
+ bfd * abfd;
+ char *buf;
+ unsigned int size;
+{
+ /* If the size of a host char is 8 bits, we can return a pointer
+ to the buffer, otherwise we have to copy the data to a buffer
+ allocated on the temporary obstack. */
+ return buf;
+}
+
+static char *
+read_string (abfd, buf, bytes_read_ptr)
+ bfd *abfd;
+ char *buf;
+ unsigned int *bytes_read_ptr;
+{
+ /* If the size of a host char is 8 bits, we can return a pointer
+ to the string, otherwise we have to copy the string to a buffer
+ allocated on the temporary obstack. */
+ if (*buf == '\0')
+ {
+ *bytes_read_ptr = 1;
+ return NULL;
+ }
+ *bytes_read_ptr = strlen (buf) + 1;
+ return buf;
+}
+
+static unsigned int
+read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
+ bfd *abfd;
+ char *buf;
+ unsigned int *bytes_read_ptr;
+{
+ unsigned int result;
+ unsigned int num_read;
+ int shift;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ num_read = 0;
+
+ do
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf ++;
+ num_read ++;
+ result |= ((byte & 0x7f) << shift);
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ * bytes_read_ptr = num_read;
+
+ return result;
+}
+
+static int
+read_signed_leb128 (abfd, buf, bytes_read_ptr)
+ bfd * abfd;
+ char * buf;
+ unsigned int * bytes_read_ptr;
+{
+ int result;
+ int shift;
+ int num_read;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ num_read = 0;
+
+ do
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf ++;
+ num_read ++;
+ result |= ((byte & 0x7f) << shift);
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ if ((shift < 32) && (byte & 0x40))
+ result |= -(1 << shift);
+
+ * bytes_read_ptr = num_read;
+
+ return result;
+}
+
+/* END VERBATIM */
+
+static bfd_vma
+read_address (unit, buf)
+ struct comp_unit* unit;
+ char *buf;
+{
+ bfd_vma retval = 0;
+
+ if (unit->addr_size == 4)
+ {
+ retval = bfd_get_32 (unit->abfd, (bfd_byte *) buf);
+ } else {
+ retval = bfd_get_64 (unit->abfd, (bfd_byte *) buf);
+ }
+ return retval;
+}
+
+
+
+
+
+/* This data structure holds the information of an abbrev. */
+struct abbrev_info
+ {
+ unsigned int number; /* number identifying abbrev */
+ enum dwarf_tag tag; /* dwarf tag */
+ int has_children; /* boolean */
+ unsigned int num_attrs; /* number of attributes */
+ struct attr_abbrev *attrs; /* an array of attribute descriptions */
+ struct abbrev_info *next; /* next in chain */
+ };
+
+struct attr_abbrev
+ {
+ enum dwarf_attribute name;
+ enum dwarf_form form;
+ };
+
+#ifndef ABBREV_HASH_SIZE
+#define ABBREV_HASH_SIZE 121
+#endif
+#ifndef ATTR_ALLOC_CHUNK
+#define ATTR_ALLOC_CHUNK 4
+#endif
+
+/* Lookup an abbrev_info structure in the abbrev hash table. */
+
+static struct abbrev_info *
+lookup_abbrev (number,abbrevs)
+ unsigned int number;
+ struct abbrev_info **abbrevs;
+{
+ unsigned int hash_number;
+ struct abbrev_info *abbrev;
+
+ hash_number = number % ABBREV_HASH_SIZE;
+ abbrev = abbrevs[hash_number];
+
+ while (abbrev)
+ {
+ if (abbrev->number == number)
+ return abbrev;
+ else
+ abbrev = abbrev->next;
+ }
+ return NULL;
+}
+
+/* In DWARF version 2, the description of the debugging information is
+ stored in a separate .debug_abbrev section. Before we read any
+ dies from a section we read in all abbreviations and install them
+ in a hash table. */
+
+static struct abbrev_info**
+read_abbrevs (abfd, offset)
+ bfd * abfd;
+ unsigned int offset;
+{
+ struct abbrev_info **abbrevs;
+ char *abbrev_ptr;
+ struct abbrev_info *cur_abbrev;
+ unsigned int abbrev_number, bytes_read, abbrev_name;
+ unsigned int abbrev_form, hash_number;
+ struct dwarf2_debug *stash;
+
+ stash = elf_tdata(abfd)->dwarf2_find_line_info;
+
+ if (! stash->dwarf_abbrev_buffer)
+ {
+ asection *msec;
+
+ msec = bfd_get_section_by_name (abfd, ".debug_abbrev");
+ if (! msec)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Can't find .debug_abbrev section."));
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ stash->dwarf_abbrev_size = bfd_get_section_size_before_reloc (msec);
+ stash->dwarf_abbrev_buffer = (unsigned char*) bfd_alloc (abfd, stash->dwarf_abbrev_size);
+ if (! stash->dwarf_abbrev_buffer)
+ return 0;
+
+ if (! bfd_get_section_contents (abfd, msec,
+ stash->dwarf_abbrev_buffer, 0,
+ stash->dwarf_abbrev_size))
+ return 0;
+ }
+
+ if (offset > stash->dwarf_abbrev_size)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Abbrev offset (%u) bigger than abbrev size (%u)."),
+ offset, stash->dwarf_abbrev_size );
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ abbrevs = (struct abbrev_info**) bfd_zalloc (abfd, sizeof(struct abbrev_info*) * ABBREV_HASH_SIZE);
+
+ abbrev_ptr = stash->dwarf_abbrev_buffer + offset;
+ abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+
+ /* loop until we reach an abbrev number of 0 */
+ while (abbrev_number)
+ {
+ cur_abbrev = (struct abbrev_info*)bfd_zalloc (abfd, sizeof (struct abbrev_info));
+
+ /* read in abbrev header */
+ cur_abbrev->number = abbrev_number;
+ cur_abbrev->tag = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
+ abbrev_ptr += 1;
+
+ /* now read in declarations */
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ while (abbrev_name)
+ {
+ if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
+ {
+ cur_abbrev->attrs = (struct attr_abbrev *)
+ bfd_realloc (cur_abbrev->attrs,
+ (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
+ * sizeof (struct attr_abbrev));
+ if (! cur_abbrev->attrs)
+ return 0;
+ }
+ cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
+ cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ }
+
+ hash_number = abbrev_number % ABBREV_HASH_SIZE;
+ cur_abbrev->next = abbrevs[hash_number];
+ abbrevs[hash_number] = cur_abbrev;
+
+ /* Get next abbreviation.
+ Under Irix6 the abbreviations for a compilation unit are not
+ always properly terminated with an abbrev number of 0.
+ Exit loop if we encounter an abbreviation which we have
+ already read (which means we are about to read the abbreviations
+ for the next compile unit) or if the end of the abbreviation
+ table is reached. */
+ if ((unsigned int) (abbrev_ptr - stash->dwarf_abbrev_buffer)
+ >= stash->dwarf_abbrev_size)
+ break;
+ abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ if (lookup_abbrev (abbrev_number,abbrevs) != NULL)
+ break;
+ }
+
+ return abbrevs;
+}
+
+/* Read an attribute described by an abbreviated attribute. */
+
+static char *
+read_attribute (attr, abbrev, unit, info_ptr)
+ struct attribute *attr;
+ struct attr_abbrev *abbrev;
+ struct comp_unit *unit;
+ char *info_ptr;
+{
+ bfd *abfd = unit->abfd;
+ unsigned int bytes_read;
+ struct dwarf_block *blk;
+
+ attr->name = abbrev->name;
+ attr->form = abbrev->form;
+ switch (abbrev->form)
+ {
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ DW_ADDR (attr) = read_address (unit, info_ptr);
+ info_ptr += unit->addr_size;
+ break;
+ case DW_FORM_block2:
+ blk = (struct dwarf_block *) bfd_alloc (abfd, sizeof (struct dwarf_block));
+ blk->size = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_block4:
+ blk = (struct dwarf_block *) bfd_alloc (abfd, sizeof (struct dwarf_block));
+ blk->size = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_data2:
+ DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_data4:
+ DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_data8:
+ DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_string:
+ DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_block:
+ blk = (struct dwarf_block *) bfd_alloc (abfd, sizeof (struct dwarf_block));
+ blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_block1:
+ blk = (struct dwarf_block *) bfd_alloc (abfd, sizeof (struct dwarf_block));
+ blk->size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ info_ptr += blk->size;
+ DW_BLOCK (attr) = blk;
+ break;
+ case DW_FORM_data1:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_flag:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_sdata:
+ DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_udata:
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_ref1:
+ DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_ref2:
+ DW_UNSND (attr) = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_ref4:
+ DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_ref_udata:
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_strp:
+ case DW_FORM_indirect:
+ default:
+ (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %d."),
+ abbrev->form);
+ bfd_set_error (bfd_error_bad_value);
+ }
+ return info_ptr;
+}
+
+
+/* Source line information table routines. */
+
+#define FILE_ALLOC_CHUNK 5
+#define DIR_ALLOC_CHUNK 5
+
+struct line_info {
+ struct line_info* prev_line;
+
+ bfd_vma address;
+ char* filename;
+ unsigned int line;
+ unsigned int column;
+};
+
+struct fileinfo {
+ char *name;
+ unsigned int dir;
+ unsigned int time;
+ unsigned int size;
+};
+
+struct line_info_table {
+ bfd* abfd;
+
+ unsigned int num_files;
+ unsigned int num_dirs;
+
+ char* comp_dir;
+ char** dirs;
+ struct fileinfo* files;
+ struct line_info* last_line;
+};
+
+static void
+add_line_info (table, address, filename, line, column)
+ struct line_info_table* table;
+ bfd_vma address;
+ char* filename;
+ unsigned int line;
+ unsigned int column;
+{
+ struct line_info* info = (struct line_info*)
+ bfd_alloc (table->abfd, sizeof (struct line_info));
+
+ info->prev_line = table->last_line;
+ table->last_line = info;
+
+ info->address = address;
+ info->filename = filename;
+ info->line = line;
+ info->column = column;
+}
+
+static char*
+concat_filename (table, file)
+ struct line_info_table* table;
+ unsigned int file;
+{
+ char* filename = table->files[file - 1].name;
+ if (*filename == '/')
+ return filename;
+
+ else
+ {
+ char* dirname = (table->files[file - 1].dir
+ ? table->dirs[table->files[file - 1].dir - 1]
+ : table->comp_dir);
+ return (char*) concat (dirname, "/", filename, NULL);
+ }
+}
+
+/* Decode the line number information for UNIT. */
+
+static struct line_info_table*
+decode_line_info (unit)
+ struct comp_unit *unit;
+{
+ bfd *abfd = unit->abfd;
+
+ static char* dwarf_line_buffer = 0;
+
+ struct line_info_table* table;
+
+ char *line_ptr;
+ char *line_end;
+ struct line_head lh;
+ unsigned int i, bytes_read;
+ char *cur_file, *cur_dir;
+ unsigned char op_code, extended_op, adj_opcode;
+
+ if (! dwarf_line_buffer)
+ {
+ asection *msec;
+ unsigned long size;
+
+ msec = bfd_get_section_by_name (abfd, ".debug_line");
+ if (! msec)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Can't find .debug_line section."));
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ size = bfd_get_section_size_before_reloc (msec);
+ dwarf_line_buffer = (unsigned char*) bfd_alloc (abfd, size);
+ if (! dwarf_line_buffer)
+ return 0;
+
+ if (! bfd_get_section_contents (abfd, msec,
+ dwarf_line_buffer, 0,
+ size))
+ return 0;
+
+ /* FIXME: We ought to apply the relocs against this section before
+ we process it.... */
+ }
+
+ table = (struct line_info_table*) bfd_alloc (abfd,
+ sizeof (struct line_info_table));
+ table->abfd = abfd;
+ table->comp_dir = unit->comp_dir;
+
+ table->num_files = 0;
+ table->files = NULL;
+
+ table->num_dirs = 0;
+ table->dirs = NULL;
+
+ line_ptr = dwarf_line_buffer + unit->line_offset;
+
+ /* read in the prologue */
+ lh.total_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ line_end = line_ptr + lh.total_length;
+ lh.version = read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ lh.prologue_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.default_is_stmt = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.line_base = read_1_signed_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.line_range = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.opcode_base = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ lh.standard_opcode_lengths = (unsigned char *)
+ bfd_alloc (abfd, lh.opcode_base * sizeof (unsigned char));
+
+ lh.standard_opcode_lengths[0] = 1;
+ for (i = 1; i < lh.opcode_base; ++i)
+ {
+ lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+
+ /* Read directory table */
+ while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0)
+ {
+ table->dirs = (char **)
+ bfd_realloc (table->dirs,
+ (table->num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
+ if (! table->dirs)
+ return 0;
+ }
+ table->dirs[table->num_dirs++] = cur_dir;
+ }
+ line_ptr += bytes_read;
+
+ /* Read file name table */
+ while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
+ {
+ table->files = (struct fileinfo *)
+ bfd_realloc (table->files,
+ (table->num_files + FILE_ALLOC_CHUNK)
+ * sizeof (struct fileinfo));
+ if (! table->files)
+ return 0;
+ }
+ table->files[table->num_files].name = cur_file;
+ table->files[table->num_files].dir =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ table->files[table->num_files].time =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ table->files[table->num_files].size =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ table->num_files++;
+ }
+ line_ptr += bytes_read;
+
+ /* Read the statement sequences until there's nothing left. */
+ while (line_ptr < line_end)
+ {
+ /* state machine registers */
+ bfd_vma address = 0;
+ char* filename = concat_filename (table, 1);
+ unsigned int line = 1;
+ unsigned int column = 0;
+ int is_stmt = lh.default_is_stmt;
+ int basic_block = 0;
+ int end_sequence = 0;
+
+ /* Decode the table. */
+ while (! end_sequence)
+ {
+ op_code = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ line_ptr += 1; /* ignore length */
+ extended_op = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ switch (extended_op)
+ {
+ case DW_LNE_end_sequence:
+ end_sequence = 1;
+ add_line_info (table, address, filename, line, column);
+ break;
+ case DW_LNE_set_address:
+ address = read_address (unit, line_ptr);
+ line_ptr += unit->addr_size;
+ break;
+ case DW_LNE_define_file:
+ cur_file = read_string (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
+ {
+ table->files = (struct fileinfo *)
+ bfd_realloc (table->files,
+ (table->num_files + FILE_ALLOC_CHUNK)
+ * sizeof (struct fileinfo));
+ if (! table->files)
+ return 0;
+ }
+ table->files[table->num_files].name = cur_file;
+ table->files[table->num_files].dir =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ table->files[table->num_files].time =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ table->files[table->num_files].size =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ table->num_files++;
+ break;
+ default:
+ (*_bfd_error_handler) (_("Dwarf Error: mangled line number section."));
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+ break;
+ case DW_LNS_copy:
+ add_line_info (table, address, filename, line, column);
+ basic_block = 0;
+ break;
+ case DW_LNS_advance_pc:
+ address += lh.minimum_instruction_length
+ * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_advance_line:
+ line += read_signed_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_set_file:
+ {
+ unsigned int file;
+
+ /* The file and directory tables are 0 based, the references
+ are 1 based. */
+ file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ filename = concat_filename (table, file);
+ break;
+ }
+ case DW_LNS_set_column:
+ column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNS_negate_stmt:
+ is_stmt = (!is_stmt);
+ break;
+ case DW_LNS_set_basic_block:
+ basic_block = 1;
+ break;
+ case DW_LNS_const_add_pc:
+ address += (255 - lh.opcode_base) / lh.line_range;
+ break;
+ case DW_LNS_fixed_advance_pc:
+ address += read_2_bytes (abfd, line_ptr);
+ line_ptr += 2;
+ break;
+ default: /* special operand */
+ adj_opcode = op_code - lh.opcode_base;
+ address += (adj_opcode / lh.line_range)
+ * lh.minimum_instruction_length;
+ line += lh.line_base + (adj_opcode % lh.line_range);
+ /* append row to matrix using current values */
+ add_line_info (table, address, filename, line, column);
+ basic_block = 1;
+ }
+ }
+ }
+
+ return table;
+}
+
+
+/* If ADDR is within TABLE set the output parameters and return true,
+ otherwise return false. The output parameters, FILENAME_PTR and
+ LINENUMBER_PTR, are pointers to the objects to be filled in. */
+
+static boolean
+lookup_address_in_line_info_table (table,
+ addr,
+ filename_ptr,
+ linenumber_ptr)
+ struct line_info_table* table;
+ bfd_vma addr;
+ const char **filename_ptr;
+ unsigned int *linenumber_ptr;
+{
+ struct line_info* each_line;
+ struct line_info* next_line;
+
+ for (next_line = 0, each_line = table->last_line;
+ each_line;
+ next_line = each_line, each_line = each_line->prev_line)
+ {
+ if (addr >= each_line->address
+ && (next_line == 0
+ || addr < next_line->address))
+ {
+ *filename_ptr = each_line->filename;
+ *linenumber_ptr = each_line->line;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+/* Function table functions. */
+
+struct funcinfo {
+ struct funcinfo *prev_func;
+
+ char* name;
+ bfd_vma low;
+ bfd_vma high;
+};
+
+
+/* If ADDR is within TABLE, set FUNCTIONNAME_PTR, and return true. */
+
+static boolean
+lookup_address_in_function_table (table,
+ addr,
+ functionname_ptr)
+ struct funcinfo* table;
+ bfd_vma addr;
+ const char **functionname_ptr;
+{
+ struct funcinfo* each_func;
+
+ for (each_func = table;
+ each_func;
+ each_func = each_func->prev_func)
+ {
+ if (addr >= each_func->low && addr < each_func->high)
+ {
+ *functionname_ptr = each_func->name;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+/* DWARF2 Compilation unit functions. */
+
+
+/* Scan over each die in a comp. unit looking for functions to add
+ to the function table. */
+
+static boolean
+scan_unit_for_functions (unit)
+ struct comp_unit *unit;
+{
+ bfd *abfd = unit->abfd;
+ char *info_ptr = unit->first_child_die_ptr;
+ int nesting_level = 1;
+
+ while (nesting_level)
+ {
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ struct attribute attr;
+ struct funcinfo *func;
+ char* name = 0;
+
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+
+ if (! abbrev_number)
+ {
+ nesting_level--;
+ continue;
+ }
+
+ abbrev = lookup_abbrev (abbrev_number,unit->abbrevs);
+ if (! abbrev)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %d."),
+ abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (abbrev->tag == DW_TAG_subprogram)
+ {
+ func = (struct funcinfo*) bfd_zalloc (abfd, sizeof (struct funcinfo));
+ func->prev_func = unit->function_table;
+ unit->function_table = func;
+ }
+ else
+ func = NULL;
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr);
+
+ if (func)
+ {
+ switch (attr.name)
+ {
+ case DW_AT_name:
+
+ name = DW_STRING (&attr);
+
+ /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */
+ if (func->name == NULL)
+ func->name = DW_STRING (&attr);
+ break;
+
+ case DW_AT_MIPS_linkage_name:
+ func->name = DW_STRING (&attr);
+ break;
+
+ case DW_AT_low_pc:
+ func->low = DW_ADDR (&attr);
+ break;
+
+ case DW_AT_high_pc:
+ func->high = DW_ADDR (&attr);
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (attr.name)
+ {
+ case DW_AT_name:
+ name = DW_STRING (&attr);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (abbrev->has_children)
+ nesting_level++;
+ }
+
+ return true;
+}
+
+
+
+
+
+
+/* Parse a DWARF2 compilation unit starting at INFO_PTR. This includes
+ the compilation unit header that proceeds the DIE's, but does not
+ include the length field that preceeds each compilation unit header.
+ END_PTR points one past the end of this comp unit.
+
+ This routine does not read the whole compilation unit; only enough
+ to get to the line number information for the compilation unit. */
+
+static struct comp_unit *
+parse_comp_unit (abfd, info_ptr, end_ptr)
+ bfd* abfd;
+ char* info_ptr;
+ char* end_ptr;
+{
+ struct comp_unit* unit;
+
+ unsigned short version;
+ unsigned int abbrev_offset;
+ unsigned char addr_size;
+ struct abbrev_info** abbrevs;
+
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ struct attribute attr;
+
+ version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ abbrev_offset = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+
+ if (version != 2)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%hu', this reader only handles version 2 information."), version );
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ if (addr_size > sizeof (bfd_vma))
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."),
+ addr_size,
+ sizeof (bfd_vma));
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ if (addr_size != 4 && addr_size != 8)
+ {
+ (*_bfd_error_handler) ("Dwarf Error: found address size '%u', this reader can only handle address sizes '4' and '8'.", addr_size );
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ /* Read the abbrevs for this compilation unit into a table */
+ abbrevs = read_abbrevs (abfd, abbrev_offset);
+ if (! abbrevs)
+ return 0;
+
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ if (! abbrev_number)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %d."),
+ abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ abbrev = lookup_abbrev (abbrev_number, abbrevs);
+ if (! abbrev)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %d."),
+ abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ unit = (struct comp_unit*) bfd_zalloc (abfd, sizeof (struct comp_unit));
+ unit->abfd = abfd;
+ unit->addr_size = addr_size;
+ unit->abbrevs = abbrevs;
+ unit->end_ptr = end_ptr;
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr);
+
+ /* Store the data if it is of an attribute we want to keep in a
+ partial symbol table. */
+ switch (attr.name)
+ {
+ case DW_AT_stmt_list:
+ unit->stmtlist = 1;
+ unit->line_offset = DW_UNSND (&attr);
+ break;
+
+ case DW_AT_name:
+ unit->name = DW_STRING (&attr);
+ break;
+
+ case DW_AT_low_pc:
+ unit->low = DW_ADDR (&attr);
+ break;
+
+ case DW_AT_high_pc:
+ unit->high = DW_ADDR (&attr);
+ break;
+
+ case DW_AT_comp_dir:
+ {
+ char* comp_dir = DW_STRING (&attr);
+ if (comp_dir)
+ {
+ /* Irix 6.2 native cc prepends <machine>.: to the compilation
+ directory, get rid of it. */
+ char *cp = (char*) strchr (comp_dir, ':');
+
+ if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+ comp_dir = cp + 1;
+ }
+ unit->comp_dir = comp_dir;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ unit->first_child_die_ptr = info_ptr;
+ return unit;
+}
+
+
+
+
+
+/* Return true if UNIT contains the address given by ADDR. */
+
+static boolean
+comp_unit_contains_address (unit, addr)
+ struct comp_unit* unit;
+ bfd_vma addr;
+{
+ return ! unit->error
+ && (addr >= unit->low && addr <= unit->high);
+}
+
+
+/* If UNIT contains ADDR, set the output parameters to the values for
+ the line containing ADDR. The output parameters, FILENAME_PTR,
+ FUNCTIONNAME_PTR, and LINENUMBER_PTR, are pointers to the objects
+ to be filled in.
+
+ Return true of UNIT contains ADDR, and no errors were encountered;
+ false otherwise. */
+
+static boolean
+comp_unit_find_nearest_line (unit, addr,
+ filename_ptr, functionname_ptr, linenumber_ptr)
+ struct comp_unit* unit;
+ bfd_vma addr;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *linenumber_ptr;
+{
+ boolean line_p;
+ boolean func_p;
+
+ if (unit->error)
+ return false;
+
+ if (! unit->line_table)
+ {
+ if (! unit->stmtlist)
+ {
+ unit->error = 1;
+ return false;
+ }
+
+ unit->line_table = decode_line_info (unit);
+
+ if (! unit->line_table)
+ {
+ unit->error = 1;
+ return false;
+ }
+
+ if (! scan_unit_for_functions (unit))
+ {
+ unit->error = 1;
+ return false;
+ }
+ }
+
+ line_p = lookup_address_in_line_info_table (unit->line_table,
+ addr,
+ filename_ptr,
+ linenumber_ptr);
+ func_p = lookup_address_in_function_table (unit->function_table,
+ addr,
+ functionname_ptr);
+ return line_p || func_p;
+}
+
+/* The DWARF2 version of find_nearest line.
+ Return true if the line is found without error. */
+
+boolean
+_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr, linenumber_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *linenumber_ptr;
+{
+ /* Read each compilation unit from the section .debug_info, and check
+ to see if it contains the address we are searching for. If yes,
+ lookup the address, and return the line number info. If no, go
+ on to the next compilation unit.
+
+ We keep a list of all the previously read compilation units, and
+ a pointer to the next un-read compilation unit. Check the
+ previously read units before reading more.
+ */
+
+ struct dwarf2_debug *stash = elf_tdata (abfd)->dwarf2_find_line_info;
+
+ /* What address are we looking for? */
+ bfd_vma addr = offset + section->vma;
+
+ struct comp_unit* each;
+
+ *filename_ptr = NULL;
+ *functionname_ptr = NULL;
+ *linenumber_ptr = 0;
+
+ if (! stash)
+ {
+ asection *msec;
+ unsigned long size;
+
+ stash = elf_tdata (abfd)->dwarf2_find_line_info =
+ (struct dwarf2_debug*) bfd_zalloc (abfd, sizeof (struct dwarf2_debug));
+
+ if (! stash)
+ return false;
+
+ msec = bfd_get_section_by_name (abfd, ".debug_info");
+ if (! msec)
+ {
+ /* No dwarf2 info. Note that at this point the stash
+ has been allocated, but contains zeros, this lets
+ future calls to this function fail quicker. */
+ return false;
+ }
+
+ size = bfd_get_section_size_before_reloc (msec);
+ if (size == 0)
+ return false;
+
+ stash->info_ptr = (char *) bfd_alloc (abfd, size);
+
+ if (! stash->info_ptr)
+ return false;
+
+ if (! bfd_get_section_contents (abfd, msec, stash->info_ptr, 0, size))
+ {
+ stash->info_ptr = 0;
+ return false;
+ }
+
+ stash->info_ptr_end = stash->info_ptr + size;
+
+ /* FIXME: There is a problem with the contents of the .debug_info section.
+ The 'low' and 'high' addresses of the comp_units are computed by relocs
+ against symbols in the .text segment. We need these addresses in
+ order to determine the nearest line number, and so we have to resolve
+ the relocs. There is a similar problem when the .debug_line section is
+ processed as well.
+
+ Unfortunately getting hold of the reloc information is hard... */
+ }
+
+ /* A null info_ptr indicates that there is no dwarf2 info
+ (or that an error occured while setting up the stash). */
+
+ if (! stash->info_ptr)
+ return false;
+
+ /* Check the previously read comp. units first. */
+
+ for (each = stash->all_comp_units; each; each = each->next_unit)
+ {
+ if (comp_unit_contains_address (each, addr))
+ return comp_unit_find_nearest_line (each, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr);
+ }
+
+ /* Read each remaining comp. units checking each as they are read. */
+ while (stash->info_ptr < stash->info_ptr_end)
+ {
+ struct comp_unit* each;
+ unsigned int length;
+
+ length = read_4_bytes (abfd, stash->info_ptr);
+ stash->info_ptr += 4;
+
+ if (length > 0)
+ {
+ each = parse_comp_unit (abfd, stash->info_ptr,
+ stash->info_ptr + length);
+ stash->info_ptr += length;
+
+ if (each)
+ {
+ each->next_unit = stash->all_comp_units;
+ stash->all_comp_units = each;
+
+ if (comp_unit_contains_address (each, addr))
+ return comp_unit_find_nearest_line (each, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr);
+ }
+ }
+ }
+
+ return false;
+}
+
+/* end of file */
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
new file mode 100644
index 00000000000..d5c6f85a717
--- /dev/null
+++ b/bfd/ecoff.c
@@ -0,0 +1,4825 @@
+/* Generic ECOFF (Extended-COFF) routines.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Original version by Per Bothner.
+ Full support added by Ian Lance Taylor, ian@cygnus.com.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+#include "aout/ranlib.h"
+#include "aout/stab_gnu.h"
+
+/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines
+ some other stuff which we don't want and which conflicts with stuff
+ we do want. */
+#include "libaout.h"
+#include "aout/aout64.h"
+#undef N_ABS
+#undef exec_hdr
+#undef obj_sym_filepos
+
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff.h"
+#include "libcoff.h"
+#include "libecoff.h"
+
+/* Prototypes for static functions. */
+
+static int ecoff_get_magic PARAMS ((bfd *abfd));
+static long ecoff_sec_to_styp_flags PARAMS ((const char *name,
+ flagword flags));
+static boolean ecoff_slurp_symbolic_header PARAMS ((bfd *abfd));
+static boolean ecoff_set_symbol_info PARAMS ((bfd *abfd, SYMR *ecoff_sym,
+ asymbol *asym, int ext, int weak));
+static void ecoff_emit_aggregate PARAMS ((bfd *abfd, FDR *fdr,
+ char *string,
+ RNDXR *rndx, long isym,
+ const char *which));
+static char *ecoff_type_to_string PARAMS ((bfd *abfd, FDR *fdr,
+ unsigned int indx));
+static boolean ecoff_slurp_reloc_table PARAMS ((bfd *abfd, asection *section,
+ asymbol **symbols));
+static int ecoff_sort_hdrs PARAMS ((const PTR, const PTR));
+static boolean ecoff_compute_section_file_positions PARAMS ((bfd *abfd));
+static bfd_size_type ecoff_compute_reloc_file_positions PARAMS ((bfd *abfd));
+static boolean ecoff_get_extr PARAMS ((asymbol *, EXTR *));
+static void ecoff_set_index PARAMS ((asymbol *, bfd_size_type));
+static unsigned int ecoff_armap_hash PARAMS ((CONST char *s,
+ unsigned int *rehash,
+ unsigned int size,
+ unsigned int hlog));
+
+/* This stuff is somewhat copied from coffcode.h. */
+
+static asection bfd_debug_section = { "*DEBUG*" };
+
+/* Create an ECOFF object. */
+
+boolean
+_bfd_ecoff_mkobject (abfd)
+ bfd *abfd;
+{
+ abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *)
+ bfd_zalloc (abfd, sizeof (ecoff_data_type)));
+ if (abfd->tdata.ecoff_obj_data == NULL)
+ return false;
+
+ return true;
+}
+
+/* This is a hook called by coff_real_object_p to create any backend
+ specific information. */
+
+PTR
+_bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
+ bfd *abfd;
+ PTR filehdr;
+ PTR aouthdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
+ ecoff_data_type *ecoff;
+
+ if (_bfd_ecoff_mkobject (abfd) == false)
+ return NULL;
+
+ ecoff = ecoff_data (abfd);
+ ecoff->gp_size = 8;
+ ecoff->sym_filepos = internal_f->f_symptr;
+
+ if (internal_a != (struct internal_aouthdr *) NULL)
+ {
+ int i;
+
+ ecoff->text_start = internal_a->text_start;
+ ecoff->text_end = internal_a->text_start + internal_a->tsize;
+ ecoff->gp = internal_a->gp_value;
+ ecoff->gprmask = internal_a->gprmask;
+ for (i = 0; i < 4; i++)
+ ecoff->cprmask[i] = internal_a->cprmask[i];
+ ecoff->fprmask = internal_a->fprmask;
+ if (internal_a->magic == ECOFF_AOUT_ZMAGIC)
+ abfd->flags |= D_PAGED;
+ else
+ abfd->flags &=~ D_PAGED;
+ }
+
+ /* It turns out that no special action is required by the MIPS or
+ Alpha ECOFF backends. They have different information in the
+ a.out header, but we just copy it all (e.g., gprmask, cprmask and
+ fprmask) and let the swapping routines ensure that only relevant
+ information is written out. */
+
+ return (PTR) ecoff;
+}
+
+/* Initialize a new section. */
+
+boolean
+_bfd_ecoff_new_section_hook (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ section->alignment_power = 4;
+
+ if (strcmp (section->name, _TEXT) == 0
+ || strcmp (section->name, _INIT) == 0
+ || strcmp (section->name, _FINI) == 0)
+ section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
+ else if (strcmp (section->name, _DATA) == 0
+ || strcmp (section->name, _SDATA) == 0)
+ section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
+ else if (strcmp (section->name, _RDATA) == 0
+ || strcmp (section->name, _LIT8) == 0
+ || strcmp (section->name, _LIT4) == 0
+ || strcmp (section->name, _RCONST) == 0
+ || strcmp (section->name, _PDATA) == 0)
+ section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
+ else if (strcmp (section->name, _BSS) == 0
+ || strcmp (section->name, _SBSS) == 0)
+ section->flags |= SEC_ALLOC;
+ else if (strcmp (section->name, _LIB) == 0)
+ {
+ /* An Irix 4 shared libary. */
+ section->flags |= SEC_COFF_SHARED_LIBRARY;
+ }
+
+ /* Probably any other section name is SEC_NEVER_LOAD, but I'm
+ uncertain about .init on some systems and I don't know how shared
+ libraries work. */
+
+ return true;
+}
+
+/* Determine the machine architecture and type. This is called from
+ the generic COFF routines. It is the inverse of ecoff_get_magic,
+ below. This could be an ECOFF backend routine, with one version
+ for each target, but there aren't all that many ECOFF targets. */
+
+boolean
+_bfd_ecoff_set_arch_mach_hook (abfd, filehdr)
+ bfd *abfd;
+ PTR filehdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ enum bfd_architecture arch;
+ unsigned long mach;
+
+ switch (internal_f->f_magic)
+ {
+ case MIPS_MAGIC_1:
+ case MIPS_MAGIC_LITTLE:
+ case MIPS_MAGIC_BIG:
+ arch = bfd_arch_mips;
+ mach = 3000;
+ break;
+
+ case MIPS_MAGIC_LITTLE2:
+ case MIPS_MAGIC_BIG2:
+ /* MIPS ISA level 2: the r6000 */
+ arch = bfd_arch_mips;
+ mach = 6000;
+ break;
+
+ case MIPS_MAGIC_LITTLE3:
+ case MIPS_MAGIC_BIG3:
+ /* MIPS ISA level 3: the r4000 */
+ arch = bfd_arch_mips;
+ mach = 4000;
+ break;
+
+ case ALPHA_MAGIC:
+ arch = bfd_arch_alpha;
+ mach = 0;
+ break;
+
+ default:
+ arch = bfd_arch_obscure;
+ mach = 0;
+ break;
+ }
+
+ return bfd_default_set_arch_mach (abfd, arch, mach);
+}
+
+/* Get the magic number to use based on the architecture and machine.
+ This is the inverse of _bfd_ecoff_set_arch_mach_hook, above. */
+
+static int
+ecoff_get_magic (abfd)
+ bfd *abfd;
+{
+ int big, little;
+
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_mips:
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case 0:
+ case 3000:
+ big = MIPS_MAGIC_BIG;
+ little = MIPS_MAGIC_LITTLE;
+ break;
+
+ case 6000:
+ big = MIPS_MAGIC_BIG2;
+ little = MIPS_MAGIC_LITTLE2;
+ break;
+
+ case 4000:
+ big = MIPS_MAGIC_BIG3;
+ little = MIPS_MAGIC_LITTLE3;
+ break;
+ }
+
+ return bfd_big_endian (abfd) ? big : little;
+
+ case bfd_arch_alpha:
+ return ALPHA_MAGIC;
+
+ default:
+ abort ();
+ return 0;
+ }
+}
+
+/* Get the section s_flags to use for a section. */
+
+static long
+ecoff_sec_to_styp_flags (name, flags)
+ const char *name;
+ flagword flags;
+{
+ long styp;
+
+ styp = 0;
+
+ if (strcmp (name, _TEXT) == 0)
+ styp = STYP_TEXT;
+ else if (strcmp (name, _DATA) == 0)
+ styp = STYP_DATA;
+ else if (strcmp (name, _SDATA) == 0)
+ styp = STYP_SDATA;
+ else if (strcmp (name, _RDATA) == 0)
+ styp = STYP_RDATA;
+ else if (strcmp (name, _LITA) == 0)
+ styp = STYP_LITA;
+ else if (strcmp (name, _LIT8) == 0)
+ styp = STYP_LIT8;
+ else if (strcmp (name, _LIT4) == 0)
+ styp = STYP_LIT4;
+ else if (strcmp (name, _BSS) == 0)
+ styp = STYP_BSS;
+ else if (strcmp (name, _SBSS) == 0)
+ styp = STYP_SBSS;
+ else if (strcmp (name, _INIT) == 0)
+ styp = STYP_ECOFF_INIT;
+ else if (strcmp (name, _FINI) == 0)
+ styp = STYP_ECOFF_FINI;
+ else if (strcmp (name, _PDATA) == 0)
+ styp = STYP_PDATA;
+ else if (strcmp (name, _XDATA) == 0)
+ styp = STYP_XDATA;
+ else if (strcmp (name, _LIB) == 0)
+ styp = STYP_ECOFF_LIB;
+ else if (strcmp (name, _GOT) == 0)
+ styp = STYP_GOT;
+ else if (strcmp (name, _HASH) == 0)
+ styp = STYP_HASH;
+ else if (strcmp (name, _DYNAMIC) == 0)
+ styp = STYP_DYNAMIC;
+ else if (strcmp (name, _LIBLIST) == 0)
+ styp = STYP_LIBLIST;
+ else if (strcmp (name, _RELDYN) == 0)
+ styp = STYP_RELDYN;
+ else if (strcmp (name, _CONFLIC) == 0)
+ styp = STYP_CONFLIC;
+ else if (strcmp (name, _DYNSTR) == 0)
+ styp = STYP_DYNSTR;
+ else if (strcmp (name, _DYNSYM) == 0)
+ styp = STYP_DYNSYM;
+ else if (strcmp (name, _COMMENT) == 0)
+ {
+ styp = STYP_COMMENT;
+ flags &=~ SEC_NEVER_LOAD;
+ }
+ else if (strcmp (name, _RCONST) == 0)
+ styp = STYP_RCONST;
+ else if (flags & SEC_CODE)
+ styp = STYP_TEXT;
+ else if (flags & SEC_DATA)
+ styp = STYP_DATA;
+ else if (flags & SEC_READONLY)
+ styp = STYP_RDATA;
+ else if (flags & SEC_LOAD)
+ styp = STYP_REG;
+ else
+ styp = STYP_BSS;
+
+ if (flags & SEC_NEVER_LOAD)
+ styp |= STYP_NOLOAD;
+
+ return styp;
+}
+
+/* Get the BFD flags to use for a section. */
+
+/*ARGSUSED*/
+flagword
+_bfd_ecoff_styp_to_sec_flags (abfd, hdr, name)
+ bfd *abfd;
+ PTR hdr;
+ const char *name;
+{
+ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+ long styp_flags = internal_s->s_flags;
+ flagword sec_flags=0;
+
+ if (styp_flags & STYP_NOLOAD)
+ sec_flags |= SEC_NEVER_LOAD;
+
+ /* For 386 COFF, at least, an unloadable text or data section is
+ actually a shared library section. */
+ if ((styp_flags & STYP_TEXT)
+ || (styp_flags & STYP_ECOFF_INIT)
+ || (styp_flags & STYP_ECOFF_FINI)
+ || (styp_flags & STYP_DYNAMIC)
+ || (styp_flags & STYP_LIBLIST)
+ || (styp_flags & STYP_RELDYN)
+ || styp_flags == STYP_CONFLIC
+ || (styp_flags & STYP_DYNSTR)
+ || (styp_flags & STYP_DYNSYM)
+ || (styp_flags & STYP_HASH))
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
+ }
+ else if ((styp_flags & STYP_DATA)
+ || (styp_flags & STYP_RDATA)
+ || (styp_flags & STYP_SDATA)
+ || styp_flags == STYP_PDATA
+ || styp_flags == STYP_XDATA
+ || (styp_flags & STYP_GOT)
+ || styp_flags == STYP_RCONST)
+ {
+ if (sec_flags & SEC_NEVER_LOAD)
+ sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
+ else
+ sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
+ if ((styp_flags & STYP_RDATA)
+ || styp_flags == STYP_PDATA
+ || styp_flags == STYP_RCONST)
+ sec_flags |= SEC_READONLY;
+ }
+ else if ((styp_flags & STYP_BSS)
+ || (styp_flags & STYP_SBSS))
+ {
+ sec_flags |= SEC_ALLOC;
+ }
+ else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT)
+ {
+ sec_flags |= SEC_NEVER_LOAD;
+ }
+ else if ((styp_flags & STYP_LITA)
+ || (styp_flags & STYP_LIT8)
+ || (styp_flags & STYP_LIT4))
+ {
+ sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
+ }
+ else if (styp_flags & STYP_ECOFF_LIB)
+ {
+ sec_flags |= SEC_COFF_SHARED_LIBRARY;
+ }
+ else
+ {
+ sec_flags |= SEC_ALLOC | SEC_LOAD;
+ }
+
+ return sec_flags;
+}
+
+/* Read in the symbolic header for an ECOFF object file. */
+
+static boolean
+ecoff_slurp_symbolic_header (abfd)
+ bfd *abfd;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ bfd_size_type external_hdr_size;
+ PTR raw = NULL;
+ HDRR *internal_symhdr;
+
+ /* See if we've already read it in. */
+ if (ecoff_data (abfd)->debug_info.symbolic_header.magic ==
+ backend->debug_swap.sym_magic)
+ return true;
+
+ /* See whether there is a symbolic header. */
+ if (ecoff_data (abfd)->sym_filepos == 0)
+ {
+ bfd_get_symcount (abfd) = 0;
+ return true;
+ }
+
+ /* At this point bfd_get_symcount (abfd) holds the number of symbols
+ as read from the file header, but on ECOFF this is always the
+ size of the symbolic information header. It would be cleaner to
+ handle this when we first read the file in coffgen.c. */
+ external_hdr_size = backend->debug_swap.external_hdr_size;
+ if (bfd_get_symcount (abfd) != external_hdr_size)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Read the symbolic information header. */
+ raw = (PTR) bfd_malloc ((size_t) external_hdr_size);
+ if (raw == NULL)
+ goto error_return;
+
+ if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) == -1
+ || (bfd_read (raw, external_hdr_size, 1, abfd)
+ != external_hdr_size))
+ goto error_return;
+ internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
+ (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr);
+
+ if (internal_symhdr->magic != backend->debug_swap.sym_magic)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Now we can get the correct number of symbols. */
+ bfd_get_symcount (abfd) = (internal_symhdr->isymMax
+ + internal_symhdr->iextMax);
+
+ if (raw != NULL)
+ free (raw);
+ return true;
+ error_return:
+ if (raw != NULL)
+ free (raw);
+ return false;
+}
+
+/* Read in and swap the important symbolic information for an ECOFF
+ object file. This is called by gdb via the read_debug_info entry
+ point in the backend structure. */
+
+/*ARGSUSED*/
+boolean
+_bfd_ecoff_slurp_symbolic_info (abfd, ignore, debug)
+ bfd *abfd;
+ asection *ignore;
+ struct ecoff_debug_info *debug;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ HDRR *internal_symhdr;
+ bfd_size_type raw_base;
+ bfd_size_type raw_size;
+ PTR raw;
+ bfd_size_type external_fdr_size;
+ char *fraw_src;
+ char *fraw_end;
+ struct fdr *fdr_ptr;
+ bfd_size_type raw_end;
+ bfd_size_type cb_end;
+
+ BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
+
+ /* Check whether we've already gotten it, and whether there's any to
+ get. */
+ if (ecoff_data (abfd)->raw_syments != (PTR) NULL)
+ return true;
+ if (ecoff_data (abfd)->sym_filepos == 0)
+ {
+ bfd_get_symcount (abfd) = 0;
+ return true;
+ }
+
+ if (! ecoff_slurp_symbolic_header (abfd))
+ return false;
+
+ internal_symhdr = &debug->symbolic_header;
+
+ /* Read all the symbolic information at once. */
+ raw_base = (ecoff_data (abfd)->sym_filepos
+ + backend->debug_swap.external_hdr_size);
+
+ /* Alpha ecoff makes the determination of raw_size difficult. It has
+ an undocumented debug data section between the symhdr and the first
+ documented section. And the ordering of the sections varies between
+ statically and dynamically linked executables.
+ If bfd supports SEEK_END someday, this code could be simplified. */
+
+ raw_end = 0;
+
+#define UPDATE_RAW_END(start, count, size) \
+ cb_end = internal_symhdr->start + internal_symhdr->count * (size); \
+ if (cb_end > raw_end) \
+ raw_end = cb_end
+
+ UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char));
+ UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size);
+ UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size);
+ UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size);
+ UPDATE_RAW_END (cbOptOffset, ioptMax, backend->debug_swap.external_opt_size);
+ UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext));
+ UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char));
+ UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char));
+ UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size);
+ UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size);
+ UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size);
+
+#undef UPDATE_RAW_END
+
+ raw_size = raw_end - raw_base;
+ if (raw_size == 0)
+ {
+ ecoff_data (abfd)->sym_filepos = 0;
+ return true;
+ }
+ raw = (PTR) bfd_alloc (abfd, raw_size);
+ if (raw == NULL)
+ return false;
+ if (bfd_seek (abfd,
+ (ecoff_data (abfd)->sym_filepos
+ + backend->debug_swap.external_hdr_size),
+ SEEK_SET) != 0
+ || bfd_read (raw, raw_size, 1, abfd) != raw_size)
+ {
+ bfd_release (abfd, raw);
+ return false;
+ }
+
+ ecoff_data (abfd)->raw_syments = raw;
+
+ /* Get pointers for the numeric offsets in the HDRR structure. */
+#define FIX(off1, off2, type) \
+ if (internal_symhdr->off1 == 0) \
+ debug->off2 = (type) NULL; \
+ else \
+ debug->off2 = (type) ((char *) raw \
+ + (internal_symhdr->off1 \
+ - raw_base))
+ FIX (cbLineOffset, line, unsigned char *);
+ FIX (cbDnOffset, external_dnr, PTR);
+ FIX (cbPdOffset, external_pdr, PTR);
+ FIX (cbSymOffset, external_sym, PTR);
+ FIX (cbOptOffset, external_opt, PTR);
+ FIX (cbAuxOffset, external_aux, union aux_ext *);
+ FIX (cbSsOffset, ss, char *);
+ FIX (cbSsExtOffset, ssext, char *);
+ FIX (cbFdOffset, external_fdr, PTR);
+ FIX (cbRfdOffset, external_rfd, PTR);
+ FIX (cbExtOffset, external_ext, PTR);
+#undef FIX
+
+ /* I don't want to always swap all the data, because it will just
+ waste time and most programs will never look at it. The only
+ time the linker needs most of the debugging information swapped
+ is when linking big-endian and little-endian MIPS object files
+ together, which is not a common occurrence.
+
+ We need to look at the fdr to deal with a lot of information in
+ the symbols, so we swap them here. */
+ debug->fdr = (struct fdr *) bfd_alloc (abfd,
+ (internal_symhdr->ifdMax *
+ sizeof (struct fdr)));
+ if (debug->fdr == NULL)
+ return false;
+ external_fdr_size = backend->debug_swap.external_fdr_size;
+ fdr_ptr = debug->fdr;
+ fraw_src = (char *) debug->external_fdr;
+ fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
+ for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
+ (*backend->debug_swap.swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
+
+ return true;
+}
+
+/* ECOFF symbol table routines. The ECOFF symbol table is described
+ in gcc/mips-tfile.c. */
+
+/* ECOFF uses two common sections. One is the usual one, and the
+ other is for small objects. All the small objects are kept
+ together, and then referenced via the gp pointer, which yields
+ faster assembler code. This is what we use for the small common
+ section. */
+static asection ecoff_scom_section;
+static asymbol ecoff_scom_symbol;
+static asymbol *ecoff_scom_symbol_ptr;
+
+/* Create an empty symbol. */
+
+asymbol *
+_bfd_ecoff_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ ecoff_symbol_type *new;
+
+ new = (ecoff_symbol_type *) bfd_alloc (abfd, sizeof (ecoff_symbol_type));
+ if (new == (ecoff_symbol_type *) NULL)
+ return (asymbol *) NULL;
+ memset ((PTR) new, 0, sizeof *new);
+ new->symbol.section = (asection *) NULL;
+ new->fdr = (FDR *) NULL;
+ new->local = false;
+ new->native = NULL;
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
+
+/* Set the BFD flags and section for an ECOFF symbol. */
+
+static boolean
+ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak)
+ bfd *abfd;
+ SYMR *ecoff_sym;
+ asymbol *asym;
+ int ext;
+ int weak;
+{
+ asym->the_bfd = abfd;
+ asym->value = ecoff_sym->value;
+ asym->section = &bfd_debug_section;
+ asym->udata.i = 0;
+
+ /* Most symbol types are just for debugging. */
+ switch (ecoff_sym->st)
+ {
+ case stGlobal:
+ case stStatic:
+ case stLabel:
+ case stProc:
+ case stStaticProc:
+ break;
+ case stNil:
+ if (ECOFF_IS_STAB (ecoff_sym))
+ {
+ asym->flags = BSF_DEBUGGING;
+ return true;
+ }
+ break;
+ default:
+ asym->flags = BSF_DEBUGGING;
+ return true;
+ }
+
+ if (weak)
+ asym->flags = BSF_EXPORT | BSF_WEAK;
+ else if (ext)
+ asym->flags = BSF_EXPORT | BSF_GLOBAL;
+ else
+ {
+ asym->flags = BSF_LOCAL;
+ /* Normally, a local stProc symbol will have a corresponding
+ external symbol. We mark the local symbol as a debugging
+ symbol, in order to prevent nm from printing both out.
+ Similarly, we mark stLabel and stabs symbols as debugging
+ symbols. In both cases, we do want to set the value
+ correctly based on the symbol class. */
+ if (ecoff_sym->st == stProc
+ || ecoff_sym->st == stLabel
+ || ECOFF_IS_STAB (ecoff_sym))
+ asym->flags |= BSF_DEBUGGING;
+ }
+ switch (ecoff_sym->sc)
+ {
+ case scNil:
+ /* Used for compiler generated labels. Leave them in the
+ debugging section, and mark them as local. If BSF_DEBUGGING
+ is set, then nm does not display them for some reason. If no
+ flags are set then the linker whines about them. */
+ asym->flags = BSF_LOCAL;
+ break;
+ case scText:
+ asym->section = bfd_make_section_old_way (abfd, ".text");
+ asym->value -= asym->section->vma;
+ break;
+ case scData:
+ asym->section = bfd_make_section_old_way (abfd, ".data");
+ asym->value -= asym->section->vma;
+ break;
+ case scBss:
+ asym->section = bfd_make_section_old_way (abfd, ".bss");
+ asym->value -= asym->section->vma;
+ break;
+ case scRegister:
+ asym->flags = BSF_DEBUGGING;
+ break;
+ case scAbs:
+ asym->section = bfd_abs_section_ptr;
+ break;
+ case scUndefined:
+ asym->section = bfd_und_section_ptr;
+ asym->flags = 0;
+ asym->value = 0;
+ break;
+ case scCdbLocal:
+ case scBits:
+ case scCdbSystem:
+ case scRegImage:
+ case scInfo:
+ case scUserStruct:
+ asym->flags = BSF_DEBUGGING;
+ break;
+ case scSData:
+ asym->section = bfd_make_section_old_way (abfd, ".sdata");
+ asym->value -= asym->section->vma;
+ break;
+ case scSBss:
+ asym->section = bfd_make_section_old_way (abfd, ".sbss");
+ asym->value -= asym->section->vma;
+ break;
+ case scRData:
+ asym->section = bfd_make_section_old_way (abfd, ".rdata");
+ asym->value -= asym->section->vma;
+ break;
+ case scVar:
+ asym->flags = BSF_DEBUGGING;
+ break;
+ case scCommon:
+ if (asym->value > ecoff_data (abfd)->gp_size)
+ {
+ asym->section = bfd_com_section_ptr;
+ asym->flags = 0;
+ break;
+ }
+ /* Fall through. */
+ case scSCommon:
+ if (ecoff_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ ecoff_scom_section.name = SCOMMON;
+ ecoff_scom_section.flags = SEC_IS_COMMON;
+ ecoff_scom_section.output_section = &ecoff_scom_section;
+ ecoff_scom_section.symbol = &ecoff_scom_symbol;
+ ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
+ ecoff_scom_symbol.name = SCOMMON;
+ ecoff_scom_symbol.flags = BSF_SECTION_SYM;
+ ecoff_scom_symbol.section = &ecoff_scom_section;
+ ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
+ }
+ asym->section = &ecoff_scom_section;
+ asym->flags = 0;
+ break;
+ case scVarRegister:
+ case scVariant:
+ asym->flags = BSF_DEBUGGING;
+ break;
+ case scSUndefined:
+ asym->section = bfd_und_section_ptr;
+ asym->flags = 0;
+ asym->value = 0;
+ break;
+ case scInit:
+ asym->section = bfd_make_section_old_way (abfd, ".init");
+ asym->value -= asym->section->vma;
+ break;
+ case scBasedVar:
+ case scXData:
+ case scPData:
+ asym->flags = BSF_DEBUGGING;
+ break;
+ case scFini:
+ asym->section = bfd_make_section_old_way (abfd, ".fini");
+ asym->value -= asym->section->vma;
+ break;
+ case scRConst:
+ asym->section = bfd_make_section_old_way (abfd, ".rconst");
+ asym->value -= asym->section->vma;
+ break;
+ default:
+ break;
+ }
+
+ /* Look for special constructors symbols and make relocation entries
+ in a special construction section. These are produced by the
+ -fgnu-linker argument to g++. */
+ if (ECOFF_IS_STAB (ecoff_sym))
+ {
+ switch (ECOFF_UNMARK_STAB (ecoff_sym->index))
+ {
+ default:
+ break;
+
+ case N_SETA:
+ case N_SETT:
+ case N_SETD:
+ case N_SETB:
+ {
+ /* This code is no longer needed. It used to be used to
+ make the linker handle set symbols, but they are now
+ handled in the add_symbols routine instead. */
+#if 0
+ const char *name;
+ asection *section;
+ arelent_chain *reloc_chain;
+ unsigned int bitsize;
+
+ /* Get a section with the same name as the symbol (usually
+ __CTOR_LIST__ or __DTOR_LIST__). FIXME: gcc uses the
+ name ___CTOR_LIST (three underscores). We need
+ __CTOR_LIST (two underscores), since ECOFF doesn't use
+ a leading underscore. This should be handled by gcc,
+ but instead we do it here. Actually, this should all
+ be done differently anyhow. */
+ name = bfd_asymbol_name (asym);
+ if (name[0] == '_' && name[1] == '_' && name[2] == '_')
+ {
+ ++name;
+ asym->name = name;
+ }
+ section = bfd_get_section_by_name (abfd, name);
+ if (section == (asection *) NULL)
+ {
+ char *copy;
+
+ copy = (char *) bfd_alloc (abfd, strlen (name) + 1);
+ if (!copy)
+ return false;
+ strcpy (copy, name);
+ section = bfd_make_section (abfd, copy);
+ }
+
+ /* Build a reloc pointing to this constructor. */
+ reloc_chain =
+ (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
+ if (!reloc_chain)
+ return false;
+ reloc_chain->relent.sym_ptr_ptr =
+ bfd_get_section (asym)->symbol_ptr_ptr;
+ reloc_chain->relent.address = section->_raw_size;
+ reloc_chain->relent.addend = asym->value;
+ reloc_chain->relent.howto =
+ ecoff_backend (abfd)->constructor_reloc;
+
+ /* Set up the constructor section to hold the reloc. */
+ section->flags = SEC_CONSTRUCTOR;
+ ++section->reloc_count;
+
+ /* Constructor sections must be rounded to a boundary
+ based on the bitsize. These are not real sections--
+ they are handled specially by the linker--so the ECOFF
+ 16 byte alignment restriction does not apply. */
+ bitsize = ecoff_backend (abfd)->constructor_bitsize;
+ section->alignment_power = 1;
+ while ((1 << section->alignment_power) < bitsize / 8)
+ ++section->alignment_power;
+
+ reloc_chain->next = section->constructor_chain;
+ section->constructor_chain = reloc_chain;
+ section->_raw_size += bitsize / 8;
+
+#endif /* 0 */
+
+ /* Mark the symbol as a constructor. */
+ asym->flags |= BSF_CONSTRUCTOR;
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+/* Read an ECOFF symbol table. */
+
+boolean
+_bfd_ecoff_slurp_symbol_table (abfd)
+ bfd *abfd;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ const bfd_size_type external_ext_size
+ = backend->debug_swap.external_ext_size;
+ const bfd_size_type external_sym_size
+ = backend->debug_swap.external_sym_size;
+ void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
+ = backend->debug_swap.swap_ext_in;
+ void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
+ = backend->debug_swap.swap_sym_in;
+ bfd_size_type internal_size;
+ ecoff_symbol_type *internal;
+ ecoff_symbol_type *internal_ptr;
+ char *eraw_src;
+ char *eraw_end;
+ FDR *fdr_ptr;
+ FDR *fdr_end;
+
+ /* If we've already read in the symbol table, do nothing. */
+ if (ecoff_data (abfd)->canonical_symbols != NULL)
+ return true;
+
+ /* Get the symbolic information. */
+ if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL,
+ &ecoff_data (abfd)->debug_info))
+ return false;
+ if (bfd_get_symcount (abfd) == 0)
+ return true;
+
+ internal_size = bfd_get_symcount (abfd) * sizeof (ecoff_symbol_type);
+ internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size);
+ if (internal == NULL)
+ return false;
+
+ internal_ptr = internal;
+ eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext;
+ eraw_end = (eraw_src
+ + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax
+ * external_ext_size));
+ for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++)
+ {
+ EXTR internal_esym;
+
+ (*swap_ext_in) (abfd, (PTR) eraw_src, &internal_esym);
+ internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
+ + internal_esym.asym.iss);
+ if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
+ &internal_ptr->symbol, 1,
+ internal_esym.weakext))
+ return false;
+ /* The alpha uses a negative ifd field for section symbols. */
+ if (internal_esym.ifd >= 0)
+ internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
+ + internal_esym.ifd);
+ else
+ internal_ptr->fdr = NULL;
+ internal_ptr->local = false;
+ internal_ptr->native = (PTR) eraw_src;
+ }
+
+ /* The local symbols must be accessed via the fdr's, because the
+ string and aux indices are relative to the fdr information. */
+ fdr_ptr = ecoff_data (abfd)->debug_info.fdr;
+ fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax;
+ for (; fdr_ptr < fdr_end; fdr_ptr++)
+ {
+ char *lraw_src;
+ char *lraw_end;
+
+ lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym
+ + fdr_ptr->isymBase * external_sym_size);
+ lraw_end = lraw_src + fdr_ptr->csym * external_sym_size;
+ for (;
+ lraw_src < lraw_end;
+ lraw_src += external_sym_size, internal_ptr++)
+ {
+ SYMR internal_sym;
+
+ (*swap_sym_in) (abfd, (PTR) lraw_src, &internal_sym);
+ internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss
+ + fdr_ptr->issBase
+ + internal_sym.iss);
+ if (!ecoff_set_symbol_info (abfd, &internal_sym,
+ &internal_ptr->symbol, 0, 0))
+ return false;
+ internal_ptr->fdr = fdr_ptr;
+ internal_ptr->local = true;
+ internal_ptr->native = (PTR) lraw_src;
+ }
+ }
+
+ ecoff_data (abfd)->canonical_symbols = internal;
+
+ return true;
+}
+
+/* Return the amount of space needed for the canonical symbols. */
+
+long
+_bfd_ecoff_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL,
+ &ecoff_data (abfd)->debug_info))
+ return -1;
+
+ if (bfd_get_symcount (abfd) == 0)
+ return 0;
+
+ return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *));
+}
+
+/* Get the canonical symbols. */
+
+long
+_bfd_ecoff_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ unsigned int counter = 0;
+ ecoff_symbol_type *symbase;
+ ecoff_symbol_type **location = (ecoff_symbol_type **) alocation;
+
+ if (_bfd_ecoff_slurp_symbol_table (abfd) == false)
+ return -1;
+ if (bfd_get_symcount (abfd) == 0)
+ return 0;
+
+ symbase = ecoff_data (abfd)->canonical_symbols;
+ while (counter < bfd_get_symcount (abfd))
+ {
+ *(location++) = symbase++;
+ counter++;
+ }
+ *location++ = (ecoff_symbol_type *) NULL;
+ return bfd_get_symcount (abfd);
+}
+
+/* Turn ECOFF type information into a printable string.
+ ecoff_emit_aggregate and ecoff_type_to_string are from
+ gcc/mips-tdump.c, with swapping added and used_ptr removed. */
+
+/* Write aggregate information to a string. */
+
+static void
+ecoff_emit_aggregate (abfd, fdr, string, rndx, isym, which)
+ bfd *abfd;
+ FDR *fdr;
+ char *string;
+ RNDXR *rndx;
+ long isym;
+ const char *which;
+{
+ const struct ecoff_debug_swap * const debug_swap =
+ &ecoff_backend (abfd)->debug_swap;
+ struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
+ unsigned int ifd = rndx->rfd;
+ unsigned int indx = rndx->index;
+ const char *name;
+
+ if (ifd == 0xfff)
+ ifd = isym;
+
+ /* An ifd of -1 is an opaque type. An escaped index of 0 is a
+ struct return type of a procedure compiled without -g. */
+ if (ifd == 0xffffffff
+ || (rndx->rfd == 0xfff && indx == 0))
+ name = "<undefined>";
+ else if (indx == indexNil)
+ name = "<no name>";
+ else
+ {
+ SYMR sym;
+
+ if (debug_info->external_rfd == NULL)
+ fdr = debug_info->fdr + ifd;
+ else
+ {
+ RFDT rfd;
+
+ (*debug_swap->swap_rfd_in) (abfd,
+ ((char *) debug_info->external_rfd
+ + ((fdr->rfdBase + ifd)
+ * debug_swap->external_rfd_size)),
+ &rfd);
+ fdr = debug_info->fdr + rfd;
+ }
+
+ indx += fdr->isymBase;
+
+ (*debug_swap->swap_sym_in) (abfd,
+ ((char *) debug_info->external_sym
+ + indx * debug_swap->external_sym_size),
+ &sym);
+
+ name = debug_info->ss + fdr->issBase + sym.iss;
+ }
+
+ sprintf (string,
+ "%s %s { ifd = %u, index = %lu }",
+ which, name, ifd,
+ ((long) indx
+ + debug_info->symbolic_header.iextMax));
+}
+
+/* Convert the type information to string format. */
+
+static char *
+ecoff_type_to_string (abfd, fdr, indx)
+ bfd *abfd;
+ FDR *fdr;
+ unsigned int indx;
+{
+ union aux_ext *aux_ptr;
+ int bigendian;
+ AUXU u;
+ struct qual {
+ unsigned int type;
+ int low_bound;
+ int high_bound;
+ int stride;
+ } qualifiers[7];
+ unsigned int basic_type;
+ int i;
+ char buffer1[1024];
+ static char buffer2[1024];
+ char *p1 = buffer1;
+ char *p2 = buffer2;
+ RNDXR rndx;
+
+ aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase;
+ bigendian = fdr->fBigendian;
+
+ for (i = 0; i < 7; i++)
+ {
+ qualifiers[i].low_bound = 0;
+ qualifiers[i].high_bound = 0;
+ qualifiers[i].stride = 0;
+ }
+
+ if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == (bfd_vma) -1)
+ return "-1 (no type)";
+ _bfd_ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti);
+
+ basic_type = u.ti.bt;
+ qualifiers[0].type = u.ti.tq0;
+ qualifiers[1].type = u.ti.tq1;
+ qualifiers[2].type = u.ti.tq2;
+ qualifiers[3].type = u.ti.tq3;
+ qualifiers[4].type = u.ti.tq4;
+ qualifiers[5].type = u.ti.tq5;
+ qualifiers[6].type = tqNil;
+
+ /*
+ * Go get the basic type.
+ */
+ switch (basic_type)
+ {
+ case btNil: /* undefined */
+ strcpy (p1, "nil");
+ break;
+
+ case btAdr: /* address - integer same size as pointer */
+ strcpy (p1, "address");
+ break;
+
+ case btChar: /* character */
+ strcpy (p1, "char");
+ break;
+
+ case btUChar: /* unsigned character */
+ strcpy (p1, "unsigned char");
+ break;
+
+ case btShort: /* short */
+ strcpy (p1, "short");
+ break;
+
+ case btUShort: /* unsigned short */
+ strcpy (p1, "unsigned short");
+ break;
+
+ case btInt: /* int */
+ strcpy (p1, "int");
+ break;
+
+ case btUInt: /* unsigned int */
+ strcpy (p1, "unsigned int");
+ break;
+
+ case btLong: /* long */
+ strcpy (p1, "long");
+ break;
+
+ case btULong: /* unsigned long */
+ strcpy (p1, "unsigned long");
+ break;
+
+ case btFloat: /* float (real) */
+ strcpy (p1, "float");
+ break;
+
+ case btDouble: /* Double (real) */
+ strcpy (p1, "double");
+ break;
+
+ /* Structures add 1-2 aux words:
+ 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
+ 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
+
+ case btStruct: /* Structure (Record) */
+ _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
+ ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
+ (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+ "struct");
+ indx++; /* skip aux words */
+ break;
+
+ /* Unions add 1-2 aux words:
+ 1st word is [ST_RFDESCAPE, offset] pointer to union def;
+ 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
+
+ case btUnion: /* Union */
+ _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
+ ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
+ (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+ "union");
+ indx++; /* skip aux words */
+ break;
+
+ /* Enumerations add 1-2 aux words:
+ 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
+ 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */
+
+ case btEnum: /* Enumeration */
+ _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
+ ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
+ (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+ "enum");
+ indx++; /* skip aux words */
+ break;
+
+ case btTypedef: /* defined via a typedef, isymRef points */
+ strcpy (p1, "typedef");
+ break;
+
+ case btRange: /* subrange of int */
+ strcpy (p1, "subrange");
+ break;
+
+ case btSet: /* pascal sets */
+ strcpy (p1, "set");
+ break;
+
+ case btComplex: /* fortran complex */
+ strcpy (p1, "complex");
+ break;
+
+ case btDComplex: /* fortran double complex */
+ strcpy (p1, "double complex");
+ break;
+
+ case btIndirect: /* forward or unnamed typedef */
+ strcpy (p1, "forward/unamed typedef");
+ break;
+
+ case btFixedDec: /* Fixed Decimal */
+ strcpy (p1, "fixed decimal");
+ break;
+
+ case btFloatDec: /* Float Decimal */
+ strcpy (p1, "float decimal");
+ break;
+
+ case btString: /* Varying Length Character String */
+ strcpy (p1, "string");
+ break;
+
+ case btBit: /* Aligned Bit String */
+ strcpy (p1, "bit");
+ break;
+
+ case btPicture: /* Picture */
+ strcpy (p1, "picture");
+ break;
+
+ case btVoid: /* Void */
+ strcpy (p1, "void");
+ break;
+
+ default:
+ sprintf (p1, _("Unknown basic type %d"), (int) basic_type);
+ break;
+ }
+
+ p1 += strlen (buffer1);
+
+ /*
+ * If this is a bitfield, get the bitsize.
+ */
+ if (u.ti.fBitfield)
+ {
+ int bitsize;
+
+ bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]);
+ sprintf (p1, " : %d", bitsize);
+ p1 += strlen (buffer1);
+ }
+
+
+ /*
+ * Deal with any qualifiers.
+ */
+ if (qualifiers[0].type != tqNil)
+ {
+ /*
+ * Snarf up any array bounds in the correct order. Arrays
+ * store 5 successive words in the aux. table:
+ * word 0 RNDXR to type of the bounds (ie, int)
+ * word 1 Current file descriptor index
+ * word 2 low bound
+ * word 3 high bound (or -1 if [])
+ * word 4 stride size in bits
+ */
+ for (i = 0; i < 7; i++)
+ {
+ if (qualifiers[i].type == tqArray)
+ {
+ qualifiers[i].low_bound =
+ AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]);
+ qualifiers[i].high_bound =
+ AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]);
+ qualifiers[i].stride =
+ AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]);
+ indx += 5;
+ }
+ }
+
+ /*
+ * Now print out the qualifiers.
+ */
+ for (i = 0; i < 6; i++)
+ {
+ switch (qualifiers[i].type)
+ {
+ case tqNil:
+ case tqMax:
+ break;
+
+ case tqPtr:
+ strcpy (p2, "ptr to ");
+ p2 += sizeof ("ptr to ")-1;
+ break;
+
+ case tqVol:
+ strcpy (p2, "volatile ");
+ p2 += sizeof ("volatile ")-1;
+ break;
+
+ case tqFar:
+ strcpy (p2, "far ");
+ p2 += sizeof ("far ")-1;
+ break;
+
+ case tqProc:
+ strcpy (p2, "func. ret. ");
+ p2 += sizeof ("func. ret. ");
+ break;
+
+ case tqArray:
+ {
+ int first_array = i;
+ int j;
+
+ /* Print array bounds reversed (ie, in the order the C
+ programmer writes them). C is such a fun language.... */
+
+ while (i < 5 && qualifiers[i+1].type == tqArray)
+ i++;
+
+ for (j = i; j >= first_array; j--)
+ {
+ strcpy (p2, "array [");
+ p2 += sizeof ("array [")-1;
+ if (qualifiers[j].low_bound != 0)
+ sprintf (p2,
+ "%ld:%ld {%ld bits}",
+ (long) qualifiers[j].low_bound,
+ (long) qualifiers[j].high_bound,
+ (long) qualifiers[j].stride);
+
+ else if (qualifiers[j].high_bound != -1)
+ sprintf (p2,
+ "%ld {%ld bits}",
+ (long) (qualifiers[j].high_bound + 1),
+ (long) (qualifiers[j].stride));
+
+ else
+ sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
+
+ p2 += strlen (p2);
+ strcpy (p2, "] of ");
+ p2 += sizeof ("] of ")-1;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ strcpy (p2, buffer1);
+ return buffer2;
+}
+
+/* Return information about ECOFF symbol SYMBOL in RET. */
+
+/*ARGSUSED*/
+void
+_bfd_ecoff_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd; /* Ignored. */
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* Return whether this is a local label. */
+
+/*ARGSUSED*/
+boolean
+_bfd_ecoff_bfd_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return name[0] == '$';
+}
+
+/* Print information about an ECOFF symbol. */
+
+void
+_bfd_ecoff_print_symbol (abfd, filep, symbol, how)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ const struct ecoff_debug_swap * const debug_swap
+ = &ecoff_backend (abfd)->debug_swap;
+ FILE *file = (FILE *)filep;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ if (ecoffsymbol (symbol)->local)
+ {
+ SYMR ecoff_sym;
+
+ (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
+ &ecoff_sym);
+ fprintf (file, "ecoff local ");
+ fprintf_vma (file, (bfd_vma) ecoff_sym.value);
+ fprintf (file, " %x %x", (unsigned) ecoff_sym.st,
+ (unsigned) ecoff_sym.sc);
+ }
+ else
+ {
+ EXTR ecoff_ext;
+
+ (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
+ &ecoff_ext);
+ fprintf (file, "ecoff extern ");
+ fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
+ fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st,
+ (unsigned) ecoff_ext.asym.sc);
+ }
+ break;
+ case bfd_print_symbol_all:
+ /* Print out the symbols in a reasonable way */
+ {
+ char type;
+ int pos;
+ EXTR ecoff_ext;
+ char jmptbl;
+ char cobol_main;
+ char weakext;
+
+ if (ecoffsymbol (symbol)->local)
+ {
+ (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
+ &ecoff_ext.asym);
+ type = 'l';
+ pos = ((((char *) ecoffsymbol (symbol)->native
+ - (char *) ecoff_data (abfd)->debug_info.external_sym)
+ / debug_swap->external_sym_size)
+ + ecoff_data (abfd)->debug_info.symbolic_header.iextMax);
+ jmptbl = ' ';
+ cobol_main = ' ';
+ weakext = ' ';
+ }
+ else
+ {
+ (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
+ &ecoff_ext);
+ type = 'e';
+ pos = (((char *) ecoffsymbol (symbol)->native
+ - (char *) ecoff_data (abfd)->debug_info.external_ext)
+ / debug_swap->external_ext_size);
+ jmptbl = ecoff_ext.jmptbl ? 'j' : ' ';
+ cobol_main = ecoff_ext.cobol_main ? 'c' : ' ';
+ weakext = ecoff_ext.weakext ? 'w' : ' ';
+ }
+
+ fprintf (file, "[%3d] %c ",
+ pos, type);
+ fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
+ fprintf (file, " st %x sc %x indx %x %c%c%c %s",
+ (unsigned) ecoff_ext.asym.st,
+ (unsigned) ecoff_ext.asym.sc,
+ (unsigned) ecoff_ext.asym.index,
+ jmptbl, cobol_main, weakext,
+ symbol->name);
+
+ if (ecoffsymbol (symbol)->fdr != NULL
+ && ecoff_ext.asym.index != indexNil)
+ {
+ FDR *fdr;
+ unsigned int indx;
+ int bigendian;
+ bfd_size_type sym_base;
+ union aux_ext *aux_base;
+
+ fdr = ecoffsymbol (symbol)->fdr;
+ indx = ecoff_ext.asym.index;
+
+ /* sym_base is used to map the fdr relative indices which
+ appear in the file to the position number which we are
+ using. */
+ sym_base = fdr->isymBase;
+ if (ecoffsymbol (symbol)->local)
+ sym_base +=
+ ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
+
+ /* aux_base is the start of the aux entries for this file;
+ asym.index is an offset from this. */
+ aux_base = (ecoff_data (abfd)->debug_info.external_aux
+ + fdr->iauxBase);
+
+ /* The aux entries are stored in host byte order; the
+ order is indicated by a bit in the fdr. */
+ bigendian = fdr->fBigendian;
+
+ /* This switch is basically from gcc/mips-tdump.c */
+ switch (ecoff_ext.asym.st)
+ {
+ case stNil:
+ case stLabel:
+ break;
+
+ case stFile:
+ case stBlock:
+ fprintf (file, _("\n End+1 symbol: %ld"),
+ (long) (indx + sym_base));
+ break;
+
+ case stEnd:
+ if (ecoff_ext.asym.sc == scText
+ || ecoff_ext.asym.sc == scInfo)
+ fprintf (file, _("\n First symbol: %ld"),
+ (long) (indx + sym_base));
+ else
+ fprintf (file, _("\n First symbol: %ld"),
+ ((long)
+ (AUX_GET_ISYM (bigendian,
+ &aux_base[ecoff_ext.asym.index])
+ + sym_base)));
+ break;
+
+ case stProc:
+ case stStaticProc:
+ if (ECOFF_IS_STAB (&ecoff_ext.asym))
+ ;
+ else if (ecoffsymbol (symbol)->local)
+ fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"),
+ ((long)
+ (AUX_GET_ISYM (bigendian,
+ &aux_base[ecoff_ext.asym.index])
+ + sym_base)),
+ ecoff_type_to_string (abfd, fdr, indx + 1));
+ else
+ fprintf (file, _("\n Local symbol: %ld"),
+ ((long) indx
+ + (long) sym_base
+ + (ecoff_data (abfd)
+ ->debug_info.symbolic_header.iextMax)));
+ break;
+
+ case stStruct:
+ fprintf (file, _("\n struct; End+1 symbol: %ld"),
+ (long) (indx + sym_base));
+ break;
+
+ case stUnion:
+ fprintf (file, _("\n union; End+1 symbol: %ld"),
+ (long) (indx + sym_base));
+ break;
+
+ case stEnum:
+ fprintf (file, _("\n enum; End+1 symbol: %ld"),
+ (long) (indx + sym_base));
+ break;
+
+ default:
+ if (! ECOFF_IS_STAB (&ecoff_ext.asym))
+ fprintf (file, _("\n Type: %s"),
+ ecoff_type_to_string (abfd, fdr, indx));
+ break;
+ }
+ }
+ }
+ break;
+ }
+}
+
+/* Read in the relocs for a section. */
+
+static boolean
+ecoff_slurp_reloc_table (abfd, section, symbols)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ arelent *internal_relocs;
+ bfd_size_type external_reloc_size;
+ bfd_size_type external_relocs_size;
+ char *external_relocs;
+ arelent *rptr;
+ unsigned int i;
+
+ if (section->relocation != (arelent *) NULL
+ || section->reloc_count == 0
+ || (section->flags & SEC_CONSTRUCTOR) != 0)
+ return true;
+
+ if (_bfd_ecoff_slurp_symbol_table (abfd) == false)
+ return false;
+
+ internal_relocs = (arelent *) bfd_alloc (abfd,
+ (sizeof (arelent)
+ * section->reloc_count));
+ external_reloc_size = backend->external_reloc_size;
+ external_relocs_size = external_reloc_size * section->reloc_count;
+ external_relocs = (char *) bfd_alloc (abfd, external_relocs_size);
+ if (internal_relocs == (arelent *) NULL
+ || external_relocs == (char *) NULL)
+ return false;
+ if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
+ return false;
+ if (bfd_read (external_relocs, 1, external_relocs_size, abfd)
+ != external_relocs_size)
+ return false;
+
+ for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++)
+ {
+ struct internal_reloc intern;
+
+ (*backend->swap_reloc_in) (abfd,
+ external_relocs + i * external_reloc_size,
+ &intern);
+
+ if (intern.r_extern)
+ {
+ /* r_symndx is an index into the external symbols. */
+ BFD_ASSERT (intern.r_symndx >= 0
+ && (intern.r_symndx
+ < (ecoff_data (abfd)
+ ->debug_info.symbolic_header.iextMax)));
+ rptr->sym_ptr_ptr = symbols + intern.r_symndx;
+ rptr->addend = 0;
+ }
+ else if (intern.r_symndx == RELOC_SECTION_NONE
+ || intern.r_symndx == RELOC_SECTION_ABS)
+ {
+ rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ rptr->addend = 0;
+ }
+ else
+ {
+ CONST char *sec_name;
+ asection *sec;
+
+ /* r_symndx is a section key. */
+ switch (intern.r_symndx)
+ {
+ case RELOC_SECTION_TEXT: sec_name = ".text"; break;
+ case RELOC_SECTION_RDATA: sec_name = ".rdata"; break;
+ case RELOC_SECTION_DATA: sec_name = ".data"; break;
+ case RELOC_SECTION_SDATA: sec_name = ".sdata"; break;
+ case RELOC_SECTION_SBSS: sec_name = ".sbss"; break;
+ case RELOC_SECTION_BSS: sec_name = ".bss"; break;
+ case RELOC_SECTION_INIT: sec_name = ".init"; break;
+ case RELOC_SECTION_LIT8: sec_name = ".lit8"; break;
+ case RELOC_SECTION_LIT4: sec_name = ".lit4"; break;
+ case RELOC_SECTION_XDATA: sec_name = ".xdata"; break;
+ case RELOC_SECTION_PDATA: sec_name = ".pdata"; break;
+ case RELOC_SECTION_FINI: sec_name = ".fini"; break;
+ case RELOC_SECTION_LITA: sec_name = ".lita"; break;
+ case RELOC_SECTION_RCONST: sec_name = ".rconst"; break;
+ default: abort ();
+ }
+
+ sec = bfd_get_section_by_name (abfd, sec_name);
+ if (sec == (asection *) NULL)
+ abort ();
+ rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;
+
+ rptr->addend = - bfd_get_section_vma (abfd, sec);
+ }
+
+ rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section);
+
+ /* Let the backend select the howto field and do any other
+ required processing. */
+ (*backend->adjust_reloc_in) (abfd, &intern, rptr);
+ }
+
+ bfd_release (abfd, external_relocs);
+
+ section->relocation = internal_relocs;
+
+ return true;
+}
+
+/* Get a canonical list of relocs. */
+
+long
+_bfd_ecoff_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ asection *section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ unsigned int count;
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ arelent_chain *chain;
+
+ /* This section has relocs made up by us, not the file, so take
+ them out of their chain and place them into the data area
+ provided. */
+ for (count = 0, chain = section->constructor_chain;
+ count < section->reloc_count;
+ count++, chain = chain->next)
+ *relptr++ = &chain->relent;
+ }
+ else
+ {
+ arelent *tblptr;
+
+ if (ecoff_slurp_reloc_table (abfd, section, symbols) == false)
+ return -1;
+
+ tblptr = section->relocation;
+
+ for (count = 0; count < section->reloc_count; count++)
+ *relptr++ = tblptr++;
+ }
+
+ *relptr = (arelent *) NULL;
+
+ return section->reloc_count;
+}
+
+/* Provided a BFD, a section and an offset into the section, calculate
+ and return the name of the source file and the line nearest to the
+ wanted location. */
+
+/*ARGSUSED*/
+boolean
+_bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
+ filename_ptr, functionname_ptr, retline_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **ignore_symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *retline_ptr;
+{
+ const struct ecoff_debug_swap * const debug_swap
+ = &ecoff_backend (abfd)->debug_swap;
+ struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
+ struct ecoff_find_line *line_info;
+
+ /* Make sure we have the FDR's. */
+ if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info)
+ || bfd_get_symcount (abfd) == 0)
+ return false;
+
+ if (ecoff_data (abfd)->find_line_info == NULL)
+ {
+ ecoff_data (abfd)->find_line_info =
+ ((struct ecoff_find_line *)
+ bfd_zalloc (abfd, sizeof (struct ecoff_find_line)));
+ if (ecoff_data (abfd)->find_line_info == NULL)
+ return false;
+ }
+ line_info = ecoff_data (abfd)->find_line_info;
+
+ return _bfd_ecoff_locate_line (abfd, section, offset, debug_info,
+ debug_swap, line_info, filename_ptr,
+ functionname_ptr, retline_ptr);
+}
+
+/* Copy private BFD data. This is called by objcopy and strip. We
+ use it to copy the ECOFF debugging information from one BFD to the
+ other. It would be theoretically possible to represent the ECOFF
+ debugging information in the symbol table. However, it would be a
+ lot of work, and there would be little gain (gas, gdb, and ld
+ already access the ECOFF debugging information via the
+ ecoff_debug_info structure, and that structure would have to be
+ retained in order to support ECOFF debugging in MIPS ELF).
+
+ The debugging information for the ECOFF external symbols comes from
+ the symbol table, so this function only handles the other debugging
+ information. */
+
+boolean
+_bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info;
+ struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info;
+ register int i;
+ asymbol **sym_ptr_ptr;
+ size_t c;
+ boolean local;
+
+ /* We only want to copy information over if both BFD's use ECOFF
+ format. */
+ if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour
+ || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour)
+ return true;
+
+ /* Copy the GP value and the register masks. */
+ ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp;
+ ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask;
+ ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask;
+ for (i = 0; i < 3; i++)
+ ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i];
+
+ /* Copy the version stamp. */
+ oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp;
+
+ /* If there are no symbols, don't copy any debugging information. */
+ c = bfd_get_symcount (obfd);
+ sym_ptr_ptr = bfd_get_outsymbols (obfd);
+ if (c == 0 || sym_ptr_ptr == (asymbol **) NULL)
+ return true;
+
+ /* See if there are any local symbols. */
+ local = false;
+ for (; c > 0; c--, sym_ptr_ptr++)
+ {
+ if (ecoffsymbol (*sym_ptr_ptr)->local)
+ {
+ local = true;
+ break;
+ }
+ }
+
+ if (local)
+ {
+ /* There are some local symbols. We just bring over all the
+ debugging information. FIXME: This is not quite the right
+ thing to do. If the user has asked us to discard all
+ debugging information, then we are probably going to wind up
+ keeping it because there will probably be some local symbol
+ which objcopy did not discard. We should actually break
+ apart the debugging information and only keep that which
+ applies to the symbols we want to keep. */
+ oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax;
+ oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine;
+ oinfo->line = iinfo->line;
+
+ oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax;
+ oinfo->external_dnr = iinfo->external_dnr;
+
+ oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax;
+ oinfo->external_pdr = iinfo->external_pdr;
+
+ oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax;
+ oinfo->external_sym = iinfo->external_sym;
+
+ oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax;
+ oinfo->external_opt = iinfo->external_opt;
+
+ oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax;
+ oinfo->external_aux = iinfo->external_aux;
+
+ oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax;
+ oinfo->ss = iinfo->ss;
+
+ oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax;
+ oinfo->external_fdr = iinfo->external_fdr;
+
+ oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd;
+ oinfo->external_rfd = iinfo->external_rfd;
+ }
+ else
+ {
+ /* We are discarding all the local symbol information. Look
+ through the external symbols and remove all references to FDR
+ or aux information. */
+ c = bfd_get_symcount (obfd);
+ sym_ptr_ptr = bfd_get_outsymbols (obfd);
+ for (; c > 0; c--, sym_ptr_ptr++)
+ {
+ EXTR esym;
+
+ (*(ecoff_backend (obfd)->debug_swap.swap_ext_in))
+ (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym);
+ esym.ifd = ifdNil;
+ esym.asym.index = indexNil;
+ (*(ecoff_backend (obfd)->debug_swap.swap_ext_out))
+ (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native);
+ }
+ }
+
+ return true;
+}
+
+/* Set the architecture. The supported architecture is stored in the
+ backend pointer. We always set the architecture anyhow, since many
+ callers ignore the return value. */
+
+boolean
+_bfd_ecoff_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ bfd_default_set_arch_mach (abfd, arch, machine);
+ return arch == ecoff_backend (abfd)->arch;
+}
+
+/* Get the size of the section headers. */
+
+/*ARGSUSED*/
+int
+_bfd_ecoff_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+ asection *current;
+ int c;
+ int ret;
+
+ c = 0;
+ for (current = abfd->sections;
+ current != (asection *)NULL;
+ current = current->next)
+ ++c;
+
+ ret = (bfd_coff_filhsz (abfd)
+ + bfd_coff_aoutsz (abfd)
+ + c * bfd_coff_scnhsz (abfd));
+ return BFD_ALIGN (ret, 16);
+}
+
+/* Get the contents of a section. */
+
+boolean
+_bfd_ecoff_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ return _bfd_generic_get_section_contents (abfd, section, location,
+ offset, count);
+}
+
+/* Sort sections by VMA, but put SEC_ALLOC sections first. This is
+ called via qsort. */
+
+static int
+ecoff_sort_hdrs (arg1, arg2)
+ const PTR arg1;
+ const PTR arg2;
+{
+ const asection *hdr1 = *(const asection **) arg1;
+ const asection *hdr2 = *(const asection **) arg2;
+
+ if ((hdr1->flags & SEC_ALLOC) != 0)
+ {
+ if ((hdr2->flags & SEC_ALLOC) == 0)
+ return -1;
+ }
+ else
+ {
+ if ((hdr2->flags & SEC_ALLOC) != 0)
+ return 1;
+ }
+ if (hdr1->vma < hdr2->vma)
+ return -1;
+ else if (hdr1->vma > hdr2->vma)
+ return 1;
+ else
+ return 0;
+}
+
+/* Calculate the file position for each section, and set
+ reloc_filepos. */
+
+static boolean
+ecoff_compute_section_file_positions (abfd)
+ bfd *abfd;
+{
+ file_ptr sofar, file_sofar;
+ asection **sorted_hdrs;
+ asection *current;
+ unsigned int i;
+ file_ptr old_sofar;
+ boolean rdata_in_text;
+ boolean first_data, first_nonalloc;
+ const bfd_vma round = ecoff_backend (abfd)->round;
+
+ sofar = _bfd_ecoff_sizeof_headers (abfd, false);
+ file_sofar = sofar;
+
+ /* Sort the sections by VMA. */
+ sorted_hdrs = (asection **) bfd_malloc (abfd->section_count
+ * sizeof (asection *));
+ if (sorted_hdrs == NULL)
+ return false;
+ for (current = abfd->sections, i = 0;
+ current != NULL;
+ current = current->next, i++)
+ sorted_hdrs[i] = current;
+ BFD_ASSERT (i == abfd->section_count);
+
+ qsort (sorted_hdrs, abfd->section_count, sizeof (asection *),
+ ecoff_sort_hdrs);
+
+ /* Some versions of the OSF linker put the .rdata section in the
+ text segment, and some do not. */
+ rdata_in_text = ecoff_backend (abfd)->rdata_in_text;
+ if (rdata_in_text)
+ {
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ current = sorted_hdrs[i];
+ if (strcmp (current->name, _RDATA) == 0)
+ break;
+ if ((current->flags & SEC_CODE) == 0
+ && strcmp (current->name, _PDATA) != 0
+ && strcmp (current->name, _RCONST) != 0)
+ {
+ rdata_in_text = false;
+ break;
+ }
+ }
+ }
+ ecoff_data (abfd)->rdata_in_text = rdata_in_text;
+
+ first_data = true;
+ first_nonalloc = true;
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ unsigned int alignment_power;
+
+ current = sorted_hdrs[i];
+
+ /* For the Alpha ECOFF .pdata section the lnnoptr field is
+ supposed to indicate the number of .pdata entries that are
+ really in the section. Each entry is 8 bytes. We store this
+ away in line_filepos before increasing the section size. */
+ if (strcmp (current->name, _PDATA) == 0)
+ current->line_filepos = current->_raw_size / 8;
+
+ alignment_power = current->alignment_power;
+
+ /* On Ultrix, the data sections in an executable file must be
+ aligned to a page boundary within the file. This does not
+ affect the section size, though. FIXME: Does this work for
+ other platforms? It requires some modification for the
+ Alpha, because .rdata on the Alpha goes with the text, not
+ the data. */
+ if ((abfd->flags & EXEC_P) != 0
+ && (abfd->flags & D_PAGED) != 0
+ && ! first_data
+ && (current->flags & SEC_CODE) == 0
+ && (! rdata_in_text
+ || strcmp (current->name, _RDATA) != 0)
+ && strcmp (current->name, _PDATA) != 0
+ && strcmp (current->name, _RCONST) != 0)
+ {
+ sofar = (sofar + round - 1) &~ (round - 1);
+ file_sofar = (file_sofar + round - 1) &~ (round - 1);
+ first_data = false;
+ }
+ else if (strcmp (current->name, _LIB) == 0)
+ {
+ /* On Irix 4, the location of contents of the .lib section
+ from a shared library section is also rounded up to a
+ page boundary. */
+
+ sofar = (sofar + round - 1) &~ (round - 1);
+ file_sofar = (file_sofar + round - 1) &~ (round - 1);
+ }
+ else if (first_nonalloc
+ && (current->flags & SEC_ALLOC) == 0
+ && (abfd->flags & D_PAGED) != 0)
+ {
+ /* Skip up to the next page for an unallocated section, such
+ as the .comment section on the Alpha. This leaves room
+ for the .bss section. */
+ first_nonalloc = false;
+ sofar = (sofar + round - 1) &~ (round - 1);
+ file_sofar = (file_sofar + round - 1) &~ (round - 1);
+ }
+
+ /* Align the sections in the file to the same boundary on
+ which they are aligned in virtual memory. */
+ sofar = BFD_ALIGN (sofar, 1 << alignment_power);
+ if ((current->flags & SEC_HAS_CONTENTS) != 0)
+ file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power);
+
+ if ((abfd->flags & D_PAGED) != 0
+ && (current->flags & SEC_ALLOC) != 0)
+ {
+ sofar += (current->vma - sofar) % round;
+ if ((current->flags & SEC_HAS_CONTENTS) != 0)
+ file_sofar += (current->vma - file_sofar) % round;
+ }
+
+ if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) != 0)
+ current->filepos = file_sofar;
+
+ sofar += current->_raw_size;
+ if ((current->flags & SEC_HAS_CONTENTS) != 0)
+ file_sofar += current->_raw_size;
+
+ /* make sure that this section is of the right size too */
+ old_sofar = sofar;
+ sofar = BFD_ALIGN (sofar, 1 << alignment_power);
+ if ((current->flags & SEC_HAS_CONTENTS) != 0)
+ file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power);
+ current->_raw_size += sofar - old_sofar;
+ }
+
+ free (sorted_hdrs);
+ sorted_hdrs = NULL;
+
+ ecoff_data (abfd)->reloc_filepos = file_sofar;
+
+ return true;
+}
+
+/* Determine the location of the relocs for all the sections in the
+ output file, as well as the location of the symbolic debugging
+ information. */
+
+static bfd_size_type
+ecoff_compute_reloc_file_positions (abfd)
+ bfd *abfd;
+{
+ const bfd_size_type external_reloc_size =
+ ecoff_backend (abfd)->external_reloc_size;
+ file_ptr reloc_base;
+ bfd_size_type reloc_size;
+ asection *current;
+ file_ptr sym_base;
+
+ if (! abfd->output_has_begun)
+ {
+ if (! ecoff_compute_section_file_positions (abfd))
+ abort ();
+ abfd->output_has_begun = true;
+ }
+
+ reloc_base = ecoff_data (abfd)->reloc_filepos;
+
+ reloc_size = 0;
+ for (current = abfd->sections;
+ current != (asection *)NULL;
+ current = current->next)
+ {
+ if (current->reloc_count == 0)
+ current->rel_filepos = 0;
+ else
+ {
+ bfd_size_type relsize;
+
+ current->rel_filepos = reloc_base;
+ relsize = current->reloc_count * external_reloc_size;
+ reloc_size += relsize;
+ reloc_base += relsize;
+ }
+ }
+
+ sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size;
+
+ /* At least on Ultrix, the symbol table of an executable file must
+ be aligned to a page boundary. FIXME: Is this true on other
+ platforms? */
+ if ((abfd->flags & EXEC_P) != 0
+ && (abfd->flags & D_PAGED) != 0)
+ sym_base = ((sym_base + ecoff_backend (abfd)->round - 1)
+ &~ (ecoff_backend (abfd)->round - 1));
+
+ ecoff_data (abfd)->sym_filepos = sym_base;
+
+ return reloc_size;
+}
+
+/* Set the contents of a section. */
+
+boolean
+_bfd_ecoff_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ /* This must be done first, because bfd_set_section_contents is
+ going to set output_has_begun to true. */
+ if (abfd->output_has_begun == false)
+ {
+ if (! ecoff_compute_section_file_positions (abfd))
+ return false;
+ }
+
+ /* Handle the .lib section specially so that Irix 4 shared libraries
+ work out. See coff_set_section_contents in coffcode.h. */
+ if (strcmp (section->name, _LIB) == 0)
+ {
+ bfd_byte *rec, *recend;
+
+ rec = (bfd_byte *) location;
+ recend = rec + count;
+ while (rec < recend)
+ {
+ ++section->lma;
+ rec += bfd_get_32 (abfd, rec) * 4;
+ }
+
+ BFD_ASSERT (rec == recend);
+ }
+
+ if (count == 0)
+ return true;
+
+ if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
+ || bfd_write (location, 1, count, abfd) != count)
+ return false;
+
+ return true;
+}
+
+/* Get the GP value for an ECOFF file. This is a hook used by
+ nlmconv. */
+
+bfd_vma
+bfd_ecoff_get_gp_value (abfd)
+ bfd *abfd;
+{
+ if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
+ || bfd_get_format (abfd) != bfd_object)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+
+ return ecoff_data (abfd)->gp;
+}
+
+/* Set the GP value for an ECOFF file. This is a hook used by the
+ assembler. */
+
+boolean
+bfd_ecoff_set_gp_value (abfd, gp_value)
+ bfd *abfd;
+ bfd_vma gp_value;
+{
+ if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
+ || bfd_get_format (abfd) != bfd_object)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ ecoff_data (abfd)->gp = gp_value;
+
+ return true;
+}
+
+/* Set the register masks for an ECOFF file. This is a hook used by
+ the assembler. */
+
+boolean
+bfd_ecoff_set_regmasks (abfd, gprmask, fprmask, cprmask)
+ bfd *abfd;
+ unsigned long gprmask;
+ unsigned long fprmask;
+ unsigned long *cprmask;
+{
+ ecoff_data_type *tdata;
+
+ if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
+ || bfd_get_format (abfd) != bfd_object)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ tdata = ecoff_data (abfd);
+ tdata->gprmask = gprmask;
+ tdata->fprmask = fprmask;
+ if (cprmask != (unsigned long *) NULL)
+ {
+ register int i;
+
+ for (i = 0; i < 3; i++)
+ tdata->cprmask[i] = cprmask[i];
+ }
+
+ return true;
+}
+
+/* Get ECOFF EXTR information for an external symbol. This function
+ is passed to bfd_ecoff_debug_externals. */
+
+static boolean
+ecoff_get_extr (sym, esym)
+ asymbol *sym;
+ EXTR *esym;
+{
+ ecoff_symbol_type *ecoff_sym_ptr;
+ bfd *input_bfd;
+
+ if (bfd_asymbol_flavour (sym) != bfd_target_ecoff_flavour
+ || ecoffsymbol (sym)->native == NULL)
+ {
+ /* Don't include debugging, local, or section symbols. */
+ if ((sym->flags & BSF_DEBUGGING) != 0
+ || (sym->flags & BSF_LOCAL) != 0
+ || (sym->flags & BSF_SECTION_SYM) != 0)
+ return false;
+
+ esym->jmptbl = 0;
+ esym->cobol_main = 0;
+ esym->weakext = (sym->flags & BSF_WEAK) != 0;
+ esym->reserved = 0;
+ esym->ifd = ifdNil;
+ /* FIXME: we can do better than this for st and sc. */
+ esym->asym.st = stGlobal;
+ esym->asym.sc = scAbs;
+ esym->asym.reserved = 0;
+ esym->asym.index = indexNil;
+ return true;
+ }
+
+ ecoff_sym_ptr = ecoffsymbol (sym);
+
+ if (ecoff_sym_ptr->local)
+ return false;
+
+ input_bfd = bfd_asymbol_bfd (sym);
+ (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in))
+ (input_bfd, ecoff_sym_ptr->native, esym);
+
+ /* If the symbol was defined by the linker, then esym will be
+ undefined but sym will not be. Get a better class for such a
+ symbol. */
+ if ((esym->asym.sc == scUndefined
+ || esym->asym.sc == scSUndefined)
+ && ! bfd_is_und_section (bfd_get_section (sym)))
+ esym->asym.sc = scAbs;
+
+ /* Adjust the FDR index for the symbol by that used for the input
+ BFD. */
+ if (esym->ifd != -1)
+ {
+ struct ecoff_debug_info *input_debug;
+
+ input_debug = &ecoff_data (input_bfd)->debug_info;
+ BFD_ASSERT (esym->ifd < input_debug->symbolic_header.ifdMax);
+ if (input_debug->ifdmap != (RFDT *) NULL)
+ esym->ifd = input_debug->ifdmap[esym->ifd];
+ }
+
+ return true;
+}
+
+/* Set the external symbol index. This routine is passed to
+ bfd_ecoff_debug_externals. */
+
+static void
+ecoff_set_index (sym, indx)
+ asymbol *sym;
+ bfd_size_type indx;
+{
+ ecoff_set_sym_index (sym, indx);
+}
+
+/* Write out an ECOFF file. */
+
+boolean
+_bfd_ecoff_write_object_contents (abfd)
+ bfd *abfd;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ const bfd_vma round = backend->round;
+ const bfd_size_type filhsz = bfd_coff_filhsz (abfd);
+ const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd);
+ const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd);
+ const bfd_size_type external_hdr_size
+ = backend->debug_swap.external_hdr_size;
+ const bfd_size_type external_reloc_size = backend->external_reloc_size;
+ void (* const adjust_reloc_out) PARAMS ((bfd *,
+ const arelent *,
+ struct internal_reloc *))
+ = backend->adjust_reloc_out;
+ void (* const swap_reloc_out) PARAMS ((bfd *,
+ const struct internal_reloc *,
+ PTR))
+ = backend->swap_reloc_out;
+ struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
+ HDRR * const symhdr = &debug->symbolic_header;
+ asection *current;
+ unsigned int count;
+ bfd_size_type reloc_size;
+ bfd_size_type text_size;
+ bfd_vma text_start;
+ boolean set_text_start;
+ bfd_size_type data_size;
+ bfd_vma data_start;
+ boolean set_data_start;
+ bfd_size_type bss_size;
+ PTR buff = NULL;
+ PTR reloc_buff = NULL;
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
+ int i;
+
+ /* Determine where the sections and relocs will go in the output
+ file. */
+ reloc_size = ecoff_compute_reloc_file_positions (abfd);
+
+ count = 1;
+ for (current = abfd->sections;
+ current != (asection *)NULL;
+ current = current->next)
+ {
+ current->target_index = count;
+ ++count;
+ }
+
+ if ((abfd->flags & D_PAGED) != 0)
+ text_size = _bfd_ecoff_sizeof_headers (abfd, false);
+ else
+ text_size = 0;
+ text_start = 0;
+ set_text_start = false;
+ data_size = 0;
+ data_start = 0;
+ set_data_start = false;
+ bss_size = 0;
+
+ /* Write section headers to the file. */
+
+ /* Allocate buff big enough to hold a section header,
+ file header, or a.out header. */
+ {
+ bfd_size_type siz;
+ siz = scnhsz;
+ if (siz < filhsz)
+ siz = filhsz;
+ if (siz < aoutsz)
+ siz = aoutsz;
+ buff = (PTR) bfd_malloc ((size_t) siz);
+ if (buff == NULL)
+ goto error_return;
+ }
+
+ internal_f.f_nscns = 0;
+ if (bfd_seek (abfd, (file_ptr) (filhsz + aoutsz), SEEK_SET) != 0)
+ goto error_return;
+ for (current = abfd->sections;
+ current != (asection *) NULL;
+ current = current->next)
+ {
+ struct internal_scnhdr section;
+ bfd_vma vma;
+
+ ++internal_f.f_nscns;
+
+ strncpy (section.s_name, current->name, sizeof section.s_name);
+
+ /* This seems to be correct for Irix 4 shared libraries. */
+ vma = bfd_get_section_vma (abfd, current);
+ if (strcmp (current->name, _LIB) == 0)
+ section.s_vaddr = 0;
+ else
+ section.s_vaddr = vma;
+
+ section.s_paddr = current->lma;
+ section.s_size = bfd_get_section_size_before_reloc (current);
+
+ /* If this section is unloadable then the scnptr will be 0. */
+ if ((current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ section.s_scnptr = 0;
+ else
+ section.s_scnptr = current->filepos;
+ section.s_relptr = current->rel_filepos;
+
+ /* FIXME: the lnnoptr of the .sbss or .sdata section of an
+ object file produced by the assembler is supposed to point to
+ information about how much room is required by objects of
+ various different sizes. I think this only matters if we
+ want the linker to compute the best size to use, or
+ something. I don't know what happens if the information is
+ not present. */
+ if (strcmp (current->name, _PDATA) != 0)
+ section.s_lnnoptr = 0;
+ else
+ {
+ /* The Alpha ECOFF .pdata section uses the lnnoptr field to
+ hold the number of entries in the section (each entry is
+ 8 bytes). We stored this in the line_filepos field in
+ ecoff_compute_section_file_positions. */
+ section.s_lnnoptr = current->line_filepos;
+ }
+
+ section.s_nreloc = current->reloc_count;
+ section.s_nlnno = 0;
+ section.s_flags = ecoff_sec_to_styp_flags (current->name,
+ current->flags);
+
+ if (bfd_coff_swap_scnhdr_out (abfd, (PTR) &section, buff) == 0
+ || bfd_write (buff, 1, scnhsz, abfd) != scnhsz)
+ goto error_return;
+
+ if ((section.s_flags & STYP_TEXT) != 0
+ || ((section.s_flags & STYP_RDATA) != 0
+ && ecoff_data (abfd)->rdata_in_text)
+ || section.s_flags == STYP_PDATA
+ || (section.s_flags & STYP_DYNAMIC) != 0
+ || (section.s_flags & STYP_LIBLIST) != 0
+ || (section.s_flags & STYP_RELDYN) != 0
+ || section.s_flags == STYP_CONFLIC
+ || (section.s_flags & STYP_DYNSTR) != 0
+ || (section.s_flags & STYP_DYNSYM) != 0
+ || (section.s_flags & STYP_HASH) != 0
+ || (section.s_flags & STYP_ECOFF_INIT) != 0
+ || (section.s_flags & STYP_ECOFF_FINI) != 0
+ || section.s_flags == STYP_RCONST)
+ {
+ text_size += bfd_get_section_size_before_reloc (current);
+ if (! set_text_start || text_start > vma)
+ {
+ text_start = vma;
+ set_text_start = true;
+ }
+ }
+ else if ((section.s_flags & STYP_RDATA) != 0
+ || (section.s_flags & STYP_DATA) != 0
+ || (section.s_flags & STYP_LITA) != 0
+ || (section.s_flags & STYP_LIT8) != 0
+ || (section.s_flags & STYP_LIT4) != 0
+ || (section.s_flags & STYP_SDATA) != 0
+ || section.s_flags == STYP_XDATA
+ || (section.s_flags & STYP_GOT) != 0)
+ {
+ data_size += bfd_get_section_size_before_reloc (current);
+ if (! set_data_start || data_start > vma)
+ {
+ data_start = vma;
+ set_data_start = true;
+ }
+ }
+ else if ((section.s_flags & STYP_BSS) != 0
+ || (section.s_flags & STYP_SBSS) != 0)
+ bss_size += bfd_get_section_size_before_reloc (current);
+ else if (section.s_flags == 0
+ || (section.s_flags & STYP_ECOFF_LIB) != 0
+ || section.s_flags == STYP_COMMENT)
+ /* Do nothing */ ;
+ else
+ abort ();
+ }
+
+ /* Set up the file header. */
+
+ internal_f.f_magic = ecoff_get_magic (abfd);
+
+ /* We will NOT put a fucking timestamp in the header here. Every
+ time you put it back, I will come in and take it out again. I'm
+ sorry. This field does not belong here. We fill it with a 0 so
+ it compares the same but is not a reasonable time. --
+ gnu@cygnus.com. */
+ internal_f.f_timdat = 0;
+
+ if (bfd_get_symcount (abfd) != 0)
+ {
+ /* The ECOFF f_nsyms field is not actually the number of
+ symbols, it's the size of symbolic information header. */
+ internal_f.f_nsyms = external_hdr_size;
+ internal_f.f_symptr = ecoff_data (abfd)->sym_filepos;
+ }
+ else
+ {
+ internal_f.f_nsyms = 0;
+ internal_f.f_symptr = 0;
+ }
+
+ internal_f.f_opthdr = aoutsz;
+
+ internal_f.f_flags = F_LNNO;
+ if (reloc_size == 0)
+ internal_f.f_flags |= F_RELFLG;
+ if (bfd_get_symcount (abfd) == 0)
+ internal_f.f_flags |= F_LSYMS;
+ if (abfd->flags & EXEC_P)
+ internal_f.f_flags |= F_EXEC;
+
+ if (bfd_little_endian (abfd))
+ internal_f.f_flags |= F_AR32WR;
+ else
+ internal_f.f_flags |= F_AR32W;
+
+ /* Set up the ``optional'' header. */
+ if ((abfd->flags & D_PAGED) != 0)
+ internal_a.magic = ECOFF_AOUT_ZMAGIC;
+ else
+ internal_a.magic = ECOFF_AOUT_OMAGIC;
+
+ /* FIXME: Is this really correct? */
+ internal_a.vstamp = symhdr->vstamp;
+
+ /* At least on Ultrix, these have to be rounded to page boundaries.
+ FIXME: Is this true on other platforms? */
+ if ((abfd->flags & D_PAGED) != 0)
+ {
+ internal_a.tsize = (text_size + round - 1) &~ (round - 1);
+ internal_a.text_start = text_start &~ (round - 1);
+ internal_a.dsize = (data_size + round - 1) &~ (round - 1);
+ internal_a.data_start = data_start &~ (round - 1);
+ }
+ else
+ {
+ internal_a.tsize = text_size;
+ internal_a.text_start = text_start;
+ internal_a.dsize = data_size;
+ internal_a.data_start = data_start;
+ }
+
+ /* On Ultrix, the initial portions of the .sbss and .bss segments
+ are at the end of the data section. The bsize field in the
+ optional header records how many bss bytes are required beyond
+ those in the data section. The value is not rounded to a page
+ boundary. */
+ if (bss_size < internal_a.dsize - data_size)
+ bss_size = 0;
+ else
+ bss_size -= internal_a.dsize - data_size;
+ internal_a.bsize = bss_size;
+ internal_a.bss_start = internal_a.data_start + internal_a.dsize;
+
+ internal_a.entry = bfd_get_start_address (abfd);
+
+ internal_a.gp_value = ecoff_data (abfd)->gp;
+
+ internal_a.gprmask = ecoff_data (abfd)->gprmask;
+ internal_a.fprmask = ecoff_data (abfd)->fprmask;
+ for (i = 0; i < 4; i++)
+ internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i];
+
+ /* Let the backend adjust the headers if necessary. */
+ if (backend->adjust_headers)
+ {
+ if (! (*backend->adjust_headers) (abfd, &internal_f, &internal_a))
+ goto error_return;
+ }
+
+ /* Write out the file header and the optional header. */
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto error_return;
+
+ bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, buff);
+ if (bfd_write (buff, 1, filhsz, abfd) != filhsz)
+ goto error_return;
+
+ bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, buff);
+ if (bfd_write (buff, 1, aoutsz, abfd) != aoutsz)
+ goto error_return;
+
+ /* Build the external symbol information. This must be done before
+ writing out the relocs so that we know the symbol indices. We
+ don't do this if this BFD was created by the backend linker,
+ since it will have already handled the symbols and relocs. */
+ if (! ecoff_data (abfd)->linker)
+ {
+ symhdr->iextMax = 0;
+ symhdr->issExtMax = 0;
+ debug->external_ext = debug->external_ext_end = NULL;
+ debug->ssext = debug->ssext_end = NULL;
+ if (bfd_ecoff_debug_externals (abfd, debug, &backend->debug_swap,
+ (((abfd->flags & EXEC_P) == 0)
+ ? true : false),
+ ecoff_get_extr, ecoff_set_index)
+ == false)
+ goto error_return;
+
+ /* Write out the relocs. */
+ for (current = abfd->sections;
+ current != (asection *) NULL;
+ current = current->next)
+ {
+ arelent **reloc_ptr_ptr;
+ arelent **reloc_end;
+ char *out_ptr;
+
+ if (current->reloc_count == 0)
+ continue;
+
+ reloc_buff =
+ bfd_alloc (abfd, current->reloc_count * external_reloc_size);
+ if (reloc_buff == NULL)
+ goto error_return;
+
+ reloc_ptr_ptr = current->orelocation;
+ reloc_end = reloc_ptr_ptr + current->reloc_count;
+ out_ptr = (char *) reloc_buff;
+ for (;
+ reloc_ptr_ptr < reloc_end;
+ reloc_ptr_ptr++, out_ptr += external_reloc_size)
+ {
+ arelent *reloc;
+ asymbol *sym;
+ struct internal_reloc in;
+
+ memset ((PTR) &in, 0, sizeof in);
+
+ reloc = *reloc_ptr_ptr;
+ sym = *reloc->sym_ptr_ptr;
+
+ in.r_vaddr = (reloc->address
+ + bfd_get_section_vma (abfd, current));
+ in.r_type = reloc->howto->type;
+
+ if ((sym->flags & BSF_SECTION_SYM) == 0)
+ {
+ in.r_symndx = ecoff_get_sym_index (*reloc->sym_ptr_ptr);
+ in.r_extern = 1;
+ }
+ else
+ {
+ CONST char *name;
+
+ name = bfd_get_section_name (abfd, bfd_get_section (sym));
+ if (strcmp (name, ".text") == 0)
+ in.r_symndx = RELOC_SECTION_TEXT;
+ else if (strcmp (name, ".rdata") == 0)
+ in.r_symndx = RELOC_SECTION_RDATA;
+ else if (strcmp (name, ".data") == 0)
+ in.r_symndx = RELOC_SECTION_DATA;
+ else if (strcmp (name, ".sdata") == 0)
+ in.r_symndx = RELOC_SECTION_SDATA;
+ else if (strcmp (name, ".sbss") == 0)
+ in.r_symndx = RELOC_SECTION_SBSS;
+ else if (strcmp (name, ".bss") == 0)
+ in.r_symndx = RELOC_SECTION_BSS;
+ else if (strcmp (name, ".init") == 0)
+ in.r_symndx = RELOC_SECTION_INIT;
+ else if (strcmp (name, ".lit8") == 0)
+ in.r_symndx = RELOC_SECTION_LIT8;
+ else if (strcmp (name, ".lit4") == 0)
+ in.r_symndx = RELOC_SECTION_LIT4;
+ else if (strcmp (name, ".xdata") == 0)
+ in.r_symndx = RELOC_SECTION_XDATA;
+ else if (strcmp (name, ".pdata") == 0)
+ in.r_symndx = RELOC_SECTION_PDATA;
+ else if (strcmp (name, ".fini") == 0)
+ in.r_symndx = RELOC_SECTION_FINI;
+ else if (strcmp (name, ".lita") == 0)
+ in.r_symndx = RELOC_SECTION_LITA;
+ else if (strcmp (name, "*ABS*") == 0)
+ in.r_symndx = RELOC_SECTION_ABS;
+ else if (strcmp (name, ".rconst") == 0)
+ in.r_symndx = RELOC_SECTION_RCONST;
+ else
+ abort ();
+ in.r_extern = 0;
+ }
+
+ (*adjust_reloc_out) (abfd, reloc, &in);
+
+ (*swap_reloc_out) (abfd, &in, (PTR) out_ptr);
+ }
+
+ if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0)
+ goto error_return;
+ if (bfd_write (reloc_buff,
+ external_reloc_size, current->reloc_count, abfd)
+ != external_reloc_size * current->reloc_count)
+ goto error_return;
+ bfd_release (abfd, reloc_buff);
+ reloc_buff = NULL;
+ }
+
+ /* Write out the symbolic debugging information. */
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ /* Write out the debugging information. */
+ if (bfd_ecoff_write_debug (abfd, debug, &backend->debug_swap,
+ ecoff_data (abfd)->sym_filepos)
+ == false)
+ goto error_return;
+ }
+ }
+
+ /* The .bss section of a demand paged executable must receive an
+ entire page. If there are symbols, the symbols will start on the
+ next page. If there are no symbols, we must fill out the page by
+ hand. */
+ if (bfd_get_symcount (abfd) == 0
+ && (abfd->flags & EXEC_P) != 0
+ && (abfd->flags & D_PAGED) != 0)
+ {
+ char c;
+
+ if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
+ SEEK_SET) != 0)
+ goto error_return;
+ if (bfd_read (&c, 1, 1, abfd) == 0)
+ c = 0;
+ if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
+ SEEK_SET) != 0)
+ goto error_return;
+ if (bfd_write (&c, 1, 1, abfd) != 1)
+ goto error_return;
+ }
+
+ if (reloc_buff != NULL)
+ bfd_release (abfd, reloc_buff);
+ if (buff != NULL)
+ free (buff);
+ return true;
+ error_return:
+ if (reloc_buff != NULL)
+ bfd_release (abfd, reloc_buff);
+ if (buff != NULL)
+ free (buff);
+ return false;
+}
+
+/* Archive handling. ECOFF uses what appears to be a unique type of
+ archive header (armap). The byte ordering of the armap and the
+ contents are encoded in the name of the armap itself. At least for
+ now, we only support archives with the same byte ordering in the
+ armap and the contents.
+
+ The first four bytes in the armap are the number of symbol
+ definitions. This is always a power of two.
+
+ This is followed by the symbol definitions. Each symbol definition
+ occupies 8 bytes. The first four bytes are the offset from the
+ start of the armap strings to the null-terminated string naming
+ this symbol. The second four bytes are the file offset to the
+ archive member which defines this symbol. If the second four bytes
+ are 0, then this is not actually a symbol definition, and it should
+ be ignored.
+
+ The symbols are hashed into the armap with a closed hashing scheme.
+ See the functions below for the details of the algorithm.
+
+ After the symbol definitions comes four bytes holding the size of
+ the string table, followed by the string table itself. */
+
+/* The name of an archive headers looks like this:
+ __________E[BL]E[BL]_ (with a trailing space).
+ The trailing space is changed to an X if the archive is changed to
+ indicate that the armap is out of date.
+
+ The Alpha seems to use ________64E[BL]E[BL]_. */
+
+#define ARMAP_BIG_ENDIAN 'B'
+#define ARMAP_LITTLE_ENDIAN 'L'
+#define ARMAP_MARKER 'E'
+#define ARMAP_START_LENGTH 10
+#define ARMAP_HEADER_MARKER_INDEX 10
+#define ARMAP_HEADER_ENDIAN_INDEX 11
+#define ARMAP_OBJECT_MARKER_INDEX 12
+#define ARMAP_OBJECT_ENDIAN_INDEX 13
+#define ARMAP_END_INDEX 14
+#define ARMAP_END "_ "
+
+/* This is a magic number used in the hashing algorithm. */
+#define ARMAP_HASH_MAGIC 0x9dd68ab5
+
+/* This returns the hash value to use for a string. It also sets
+ *REHASH to the rehash adjustment if the first slot is taken. SIZE
+ is the number of entries in the hash table, and HLOG is the log
+ base 2 of SIZE. */
+
+static unsigned int
+ecoff_armap_hash (s, rehash, size, hlog)
+ CONST char *s;
+ unsigned int *rehash;
+ unsigned int size;
+ unsigned int hlog;
+{
+ unsigned int hash;
+
+ if (hlog == 0)
+ return 0;
+ hash = *s++;
+ while (*s != '\0')
+ hash = ((hash >> 27) | (hash << 5)) + *s++;
+ hash *= ARMAP_HASH_MAGIC;
+ *rehash = (hash & (size - 1)) | 1;
+ return hash >> (32 - hlog);
+}
+
+/* Read in the armap. */
+
+boolean
+_bfd_ecoff_slurp_armap (abfd)
+ bfd *abfd;
+{
+ char nextname[17];
+ unsigned int i;
+ struct areltdata *mapdata;
+ bfd_size_type parsed_size;
+ char *raw_armap;
+ struct artdata *ardata;
+ unsigned int count;
+ char *raw_ptr;
+ struct symdef *symdef_ptr;
+ char *stringbase;
+
+ /* Get the name of the first element. */
+ i = bfd_read ((PTR) nextname, 1, 16, abfd);
+ if (i == 0)
+ return true;
+ if (i != 16)
+ return false;
+
+ if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
+ return false;
+
+ /* Irix 4.0.5F apparently can use either an ECOFF armap or a
+ standard COFF armap. We could move the ECOFF armap stuff into
+ bfd_slurp_armap, but that seems inappropriate since no other
+ target uses this format. Instead, we check directly for a COFF
+ armap. */
+ if (strncmp (nextname, "/ ", 16) == 0)
+ return bfd_slurp_armap (abfd);
+
+ /* See if the first element is an armap. */
+ if (strncmp (nextname, ecoff_backend (abfd)->armap_start,
+ ARMAP_START_LENGTH) != 0
+ || nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER
+ || (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
+ && nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
+ || nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER
+ || (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
+ && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
+ || strncmp (nextname + ARMAP_END_INDEX,
+ ARMAP_END, sizeof ARMAP_END - 1) != 0)
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ /* Make sure we have the right byte ordering. */
+ if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
+ ^ (bfd_header_big_endian (abfd)))
+ || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
+ ^ (bfd_big_endian (abfd))))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ /* Read in the armap. */
+ ardata = bfd_ardata (abfd);
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == (struct areltdata *) NULL)
+ return false;
+ parsed_size = mapdata->parsed_size;
+ bfd_release (abfd, (PTR) mapdata);
+
+ raw_armap = (char *) bfd_alloc (abfd, parsed_size);
+ if (raw_armap == (char *) NULL)
+ return false;
+
+ if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ bfd_release (abfd, (PTR) raw_armap);
+ return false;
+ }
+
+ ardata->tdata = (PTR) raw_armap;
+
+ count = bfd_h_get_32 (abfd, (PTR) raw_armap);
+
+ ardata->symdef_count = 0;
+ ardata->cache = (struct ar_cache *) NULL;
+
+ /* This code used to overlay the symdefs over the raw archive data,
+ but that doesn't work on a 64 bit host. */
+
+ stringbase = raw_armap + count * 8 + 8;
+
+#ifdef CHECK_ARMAP_HASH
+ {
+ unsigned int hlog;
+
+ /* Double check that I have the hashing algorithm right by making
+ sure that every symbol can be looked up successfully. */
+ hlog = 0;
+ for (i = 1; i < count; i <<= 1)
+ hlog++;
+ BFD_ASSERT (i == count);
+
+ raw_ptr = raw_armap + 4;
+ for (i = 0; i < count; i++, raw_ptr += 8)
+ {
+ unsigned int name_offset, file_offset;
+ unsigned int hash, rehash, srch;
+
+ name_offset = bfd_h_get_32 (abfd, (PTR) raw_ptr);
+ file_offset = bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4));
+ if (file_offset == 0)
+ continue;
+ hash = ecoff_armap_hash (stringbase + name_offset, &rehash, count,
+ hlog);
+ if (hash == i)
+ continue;
+
+ /* See if we can rehash to this location. */
+ for (srch = (hash + rehash) & (count - 1);
+ srch != hash && srch != i;
+ srch = (srch + rehash) & (count - 1))
+ BFD_ASSERT (bfd_h_get_32 (abfd, (PTR) (raw_armap + 8 + srch * 8))
+ != 0);
+ BFD_ASSERT (srch == i);
+ }
+ }
+
+#endif /* CHECK_ARMAP_HASH */
+
+ raw_ptr = raw_armap + 4;
+ for (i = 0; i < count; i++, raw_ptr += 8)
+ if (bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)) != 0)
+ ++ardata->symdef_count;
+
+ symdef_ptr = ((struct symdef *)
+ bfd_alloc (abfd,
+ ardata->symdef_count * sizeof (struct symdef)));
+ if (!symdef_ptr)
+ return false;
+
+ ardata->symdefs = (carsym *) symdef_ptr;
+
+ raw_ptr = raw_armap + 4;
+ for (i = 0; i < count; i++, raw_ptr += 8)
+ {
+ unsigned int name_offset, file_offset;
+
+ file_offset = bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4));
+ if (file_offset == 0)
+ continue;
+ name_offset = bfd_h_get_32 (abfd, (PTR) raw_ptr);
+ symdef_ptr->s.name = stringbase + name_offset;
+ symdef_ptr->file_offset = file_offset;
+ ++symdef_ptr;
+ }
+
+ ardata->first_file_filepos = bfd_tell (abfd);
+ /* Pad to an even boundary. */
+ ardata->first_file_filepos += ardata->first_file_filepos % 2;
+
+ bfd_has_map (abfd) = true;
+
+ return true;
+}
+
+/* Write out an armap. */
+
+boolean
+_bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx)
+ bfd *abfd;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int orl_count;
+ int stridx;
+{
+ unsigned int hashsize, hashlog;
+ unsigned int symdefsize;
+ int padit;
+ unsigned int stringsize;
+ unsigned int mapsize;
+ file_ptr firstreal;
+ struct ar_hdr hdr;
+ struct stat statbuf;
+ unsigned int i;
+ bfd_byte temp[4];
+ bfd_byte *hashtable;
+ bfd *current;
+ bfd *last_elt;
+
+ /* Ultrix appears to use as a hash table size the least power of two
+ greater than twice the number of entries. */
+ for (hashlog = 0; ((unsigned int) 1 << hashlog) <= 2 * orl_count; hashlog++)
+ ;
+ hashsize = 1 << hashlog;
+
+ symdefsize = hashsize * 8;
+ padit = stridx % 2;
+ stringsize = stridx + padit;
+
+ /* Include 8 bytes to store symdefsize and stringsize in output. */
+ mapsize = symdefsize + stringsize + 8;
+
+ firstreal = SARMAG + sizeof (struct ar_hdr) + mapsize + elength;
+
+ memset ((PTR) &hdr, 0, sizeof hdr);
+
+ /* Work out the ECOFF armap name. */
+ strcpy (hdr.ar_name, ecoff_backend (abfd)->armap_start);
+ hdr.ar_name[ARMAP_HEADER_MARKER_INDEX] = ARMAP_MARKER;
+ hdr.ar_name[ARMAP_HEADER_ENDIAN_INDEX] =
+ (bfd_header_big_endian (abfd)
+ ? ARMAP_BIG_ENDIAN
+ : ARMAP_LITTLE_ENDIAN);
+ hdr.ar_name[ARMAP_OBJECT_MARKER_INDEX] = ARMAP_MARKER;
+ hdr.ar_name[ARMAP_OBJECT_ENDIAN_INDEX] =
+ bfd_big_endian (abfd) ? ARMAP_BIG_ENDIAN : ARMAP_LITTLE_ENDIAN;
+ memcpy (hdr.ar_name + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1);
+
+ /* Write the timestamp of the archive header to be just a little bit
+ later than the timestamp of the file, otherwise the linker will
+ complain that the index is out of date. Actually, the Ultrix
+ linker just checks the archive name; the GNU linker may check the
+ date. */
+ stat (abfd->filename, &statbuf);
+ sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60));
+
+ /* The DECstation uses zeroes for the uid, gid and mode of the
+ armap. */
+ hdr.ar_uid[0] = '0';
+ hdr.ar_gid[0] = '0';
+ hdr.ar_mode[0] = '0';
+
+ sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+
+ hdr.ar_fmag[0] = '`';
+ hdr.ar_fmag[1] = '\012';
+
+ /* Turn all null bytes in the header into spaces. */
+ for (i = 0; i < sizeof (struct ar_hdr); i++)
+ if (((char *)(&hdr))[i] == '\0')
+ (((char *)(&hdr))[i]) = ' ';
+
+ if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd)
+ != sizeof (struct ar_hdr))
+ return false;
+
+ bfd_h_put_32 (abfd, (bfd_vma) hashsize, temp);
+ if (bfd_write ((PTR) temp, 1, 4, abfd) != 4)
+ return false;
+
+ hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize);
+ if (!hashtable)
+ return false;
+
+ current = abfd->archive_head;
+ last_elt = current;
+ for (i = 0; i < orl_count; i++)
+ {
+ unsigned int hash, rehash;
+
+ /* Advance firstreal to the file position of this archive
+ element. */
+ if (((bfd *) map[i].pos) != last_elt)
+ {
+ do
+ {
+ firstreal += arelt_size (current) + sizeof (struct ar_hdr);
+ firstreal += firstreal % 2;
+ current = current->next;
+ }
+ while (current != (bfd *) map[i].pos);
+ }
+
+ last_elt = current;
+
+ hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog);
+ if (bfd_h_get_32 (abfd, (PTR) (hashtable + (hash * 8) + 4)) != 0)
+ {
+ unsigned int srch;
+
+ /* The desired slot is already taken. */
+ for (srch = (hash + rehash) & (hashsize - 1);
+ srch != hash;
+ srch = (srch + rehash) & (hashsize - 1))
+ if (bfd_h_get_32 (abfd, (PTR) (hashtable + (srch * 8) + 4)) == 0)
+ break;
+
+ BFD_ASSERT (srch != hash);
+
+ hash = srch;
+ }
+
+ bfd_h_put_32 (abfd, (bfd_vma) map[i].namidx,
+ (PTR) (hashtable + hash * 8));
+ bfd_h_put_32 (abfd, (bfd_vma) firstreal,
+ (PTR) (hashtable + hash * 8 + 4));
+ }
+
+ if (bfd_write ((PTR) hashtable, 1, symdefsize, abfd) != symdefsize)
+ return false;
+
+ bfd_release (abfd, hashtable);
+
+ /* Now write the strings. */
+ bfd_h_put_32 (abfd, (bfd_vma) stringsize, temp);
+ if (bfd_write ((PTR) temp, 1, 4, abfd) != 4)
+ return false;
+ for (i = 0; i < orl_count; i++)
+ {
+ bfd_size_type len;
+
+ len = strlen (*map[i].name) + 1;
+ if (bfd_write ((PTR) (*map[i].name), 1, len, abfd) != len)
+ return false;
+ }
+
+ /* The spec sez this should be a newline. But in order to be
+ bug-compatible for DECstation ar we use a null. */
+ if (padit)
+ {
+ if (bfd_write ("", 1, 1, abfd) != 1)
+ return false;
+ }
+
+ return true;
+}
+
+/* See whether this BFD is an archive. If it is, read in the armap
+ and the extended name table. */
+
+const bfd_target *
+_bfd_ecoff_archive_p (abfd)
+ bfd *abfd;
+{
+ struct artdata *tdata_hold;
+ char armag[SARMAG + 1];
+
+ tdata_hold = abfd->tdata.aout_ar_data;
+
+ if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return (const bfd_target *) NULL;
+ }
+
+ if (strncmp (armag, ARMAG, SARMAG) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
+ involves a cast, we can't do it as the left operand of
+ assignment. */
+ abfd->tdata.aout_ar_data =
+ (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
+
+ if (bfd_ardata (abfd) == (struct artdata *) NULL)
+ {
+ abfd->tdata.aout_ar_data = tdata_hold;
+ return (const bfd_target *) NULL;
+ }
+
+ bfd_ardata (abfd)->first_file_filepos = SARMAG;
+ bfd_ardata (abfd)->cache = NULL;
+ bfd_ardata (abfd)->archive_head = NULL;
+ bfd_ardata (abfd)->symdefs = NULL;
+ bfd_ardata (abfd)->extended_names = NULL;
+ bfd_ardata (abfd)->tdata = NULL;
+
+ if (_bfd_ecoff_slurp_armap (abfd) == false
+ || _bfd_ecoff_slurp_extended_name_table (abfd) == false)
+ {
+ bfd_release (abfd, bfd_ardata (abfd));
+ abfd->tdata.aout_ar_data = tdata_hold;
+ return (const bfd_target *) NULL;
+ }
+
+ if (bfd_has_map (abfd))
+ {
+ bfd *first;
+
+ /* This archive has a map, so we may presume that the contents
+ are object files. Make sure that if the first file in the
+ archive can be recognized as an object file, it is for this
+ target. If not, assume that this is the wrong format. If
+ the first file is not an object file, somebody is doing
+ something weird, and we permit it so that ar -t will work. */
+
+ first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
+ if (first != NULL)
+ {
+ boolean fail;
+
+ first->target_defaulted = false;
+ fail = false;
+ if (bfd_check_format (first, bfd_object)
+ && first->xvec != abfd->xvec)
+ {
+ (void) bfd_close (first);
+ bfd_release (abfd, bfd_ardata (abfd));
+ abfd->tdata.aout_ar_data = tdata_hold;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* We ought to close first here, but we can't, because we
+ have no way to remove it from the archive cache. FIXME. */
+ }
+ }
+
+ return abfd->xvec;
+}
+
+/* ECOFF linker code. */
+
+static struct bfd_hash_entry *ecoff_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string));
+static boolean ecoff_link_add_archive_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean ecoff_link_check_archive_element
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
+static boolean ecoff_link_add_object_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean ecoff_link_add_externals
+ PARAMS ((bfd *, struct bfd_link_info *, PTR, char *));
+
+/* Routine to create an entry in an ECOFF link hash table. */
+
+static struct bfd_hash_entry *
+ecoff_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct ecoff_link_hash_entry *ret = (struct ecoff_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct ecoff_link_hash_entry *) NULL)
+ ret = ((struct ecoff_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct ecoff_link_hash_entry)));
+ if (ret == (struct ecoff_link_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct ecoff_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->indx = -1;
+ ret->abfd = NULL;
+ ret->written = 0;
+ ret->small = 0;
+ }
+ memset ((PTR) &ret->esym, 0, sizeof ret->esym);
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an ECOFF link hash table. */
+
+struct bfd_link_hash_table *
+_bfd_ecoff_bfd_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct ecoff_link_hash_table *ret;
+
+ ret = ((struct ecoff_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct ecoff_link_hash_table)));
+ if (ret == NULL)
+ return NULL;
+ if (! _bfd_link_hash_table_init (&ret->root, abfd,
+ ecoff_link_hash_newfunc))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+ return &ret->root;
+}
+
+/* Look up an entry in an ECOFF link hash table. */
+
+#define ecoff_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct ecoff_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
+
+/* Traverse an ECOFF link hash table. */
+
+#define ecoff_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the ECOFF link hash table from the info structure. This is
+ just a cast. */
+
+#define ecoff_hash_table(p) ((struct ecoff_link_hash_table *) ((p)->hash))
+
+/* Given an ECOFF BFD, add symbols to the global hash table as
+ appropriate. */
+
+boolean
+_bfd_ecoff_bfd_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return ecoff_link_add_object_symbols (abfd, info);
+ case bfd_archive:
+ return ecoff_link_add_archive_symbols (abfd, info);
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+}
+
+/* Add the symbols from an archive file to the global hash table.
+ This looks through the undefined symbols, looks each one up in the
+ archive hash table, and adds any associated object file. We do not
+ use _bfd_generic_link_add_archive_symbols because ECOFF archives
+ already have a hash table, so there is no reason to construct
+ another one. */
+
+static boolean
+ecoff_link_add_archive_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ const bfd_byte *raw_armap;
+ struct bfd_link_hash_entry **pundef;
+ unsigned int armap_count;
+ unsigned int armap_log;
+ unsigned int i;
+ const bfd_byte *hashtable;
+ const char *stringbase;
+
+ if (! bfd_has_map (abfd))
+ {
+ /* An empty archive is a special case. */
+ if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL)
+ return true;
+ bfd_set_error (bfd_error_no_armap);
+ return false;
+ }
+
+ /* If we don't have any raw data for this archive, as can happen on
+ Irix 4.0.5F, we call the generic routine.
+ FIXME: We should be more clever about this, since someday tdata
+ may get to something for a generic archive. */
+ raw_armap = (const bfd_byte *) bfd_ardata (abfd)->tdata;
+ if (raw_armap == (bfd_byte *) NULL)
+ return (_bfd_generic_link_add_archive_symbols
+ (abfd, info, ecoff_link_check_archive_element));
+
+ armap_count = bfd_h_get_32 (abfd, raw_armap);
+
+ armap_log = 0;
+ for (i = 1; i < armap_count; i <<= 1)
+ armap_log++;
+ BFD_ASSERT (i == armap_count);
+
+ hashtable = raw_armap + 4;
+ stringbase = (const char *) raw_armap + armap_count * 8 + 8;
+
+ /* Look through the list of undefined symbols. */
+ pundef = &info->hash->undefs;
+ while (*pundef != (struct bfd_link_hash_entry *) NULL)
+ {
+ struct bfd_link_hash_entry *h;
+ unsigned int hash, rehash;
+ unsigned int file_offset;
+ const char *name;
+ bfd *element;
+
+ h = *pundef;
+
+ /* When a symbol is defined, it is not necessarily removed from
+ the list. */
+ if (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common)
+ {
+ /* Remove this entry from the list, for general cleanliness
+ and because we are going to look through the list again
+ if we search any more libraries. We can't remove the
+ entry if it is the tail, because that would lose any
+ entries we add to the list later on. */
+ if (*pundef != info->hash->undefs_tail)
+ *pundef = (*pundef)->next;
+ else
+ pundef = &(*pundef)->next;
+ continue;
+ }
+
+ /* Native ECOFF linkers do not pull in archive elements merely
+ to satisfy common definitions, so neither do we. We leave
+ them on the list, though, in case we are linking against some
+ other object format. */
+ if (h->type != bfd_link_hash_undefined)
+ {
+ pundef = &(*pundef)->next;
+ continue;
+ }
+
+ /* Look for this symbol in the archive hash table. */
+ hash = ecoff_armap_hash (h->root.string, &rehash, armap_count,
+ armap_log);
+
+ file_offset = bfd_h_get_32 (abfd, hashtable + (hash * 8) + 4);
+ if (file_offset == 0)
+ {
+ /* Nothing in this slot. */
+ pundef = &(*pundef)->next;
+ continue;
+ }
+
+ name = stringbase + bfd_h_get_32 (abfd, hashtable + (hash * 8));
+ if (name[0] != h->root.string[0]
+ || strcmp (name, h->root.string) != 0)
+ {
+ unsigned int srch;
+ boolean found;
+
+ /* That was the wrong symbol. Try rehashing. */
+ found = false;
+ for (srch = (hash + rehash) & (armap_count - 1);
+ srch != hash;
+ srch = (srch + rehash) & (armap_count - 1))
+ {
+ file_offset = bfd_h_get_32 (abfd, hashtable + (srch * 8) + 4);
+ if (file_offset == 0)
+ break;
+ name = stringbase + bfd_h_get_32 (abfd, hashtable + (srch * 8));
+ if (name[0] == h->root.string[0]
+ && strcmp (name, h->root.string) == 0)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (! found)
+ {
+ pundef = &(*pundef)->next;
+ continue;
+ }
+
+ hash = srch;
+ }
+
+ element = (*backend->get_elt_at_filepos) (abfd, file_offset);
+ if (element == (bfd *) NULL)
+ return false;
+
+ if (! bfd_check_format (element, bfd_object))
+ return false;
+
+ /* Unlike the generic linker, we know that this element provides
+ a definition for an undefined symbol and we know that we want
+ to include it. We don't need to check anything. */
+ if (! (*info->callbacks->add_archive_element) (info, element, name))
+ return false;
+ if (! ecoff_link_add_object_symbols (element, info))
+ return false;
+
+ pundef = &(*pundef)->next;
+ }
+
+ return true;
+}
+
+/* This is called if we used _bfd_generic_link_add_archive_symbols
+ because we were not dealing with an ECOFF archive. */
+
+static boolean
+ecoff_link_check_archive_element (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
+ = backend->debug_swap.swap_ext_in;
+ HDRR *symhdr;
+ bfd_size_type external_ext_size;
+ PTR external_ext = NULL;
+ size_t esize;
+ char *ssext = NULL;
+ char *ext_ptr;
+ char *ext_end;
+
+ *pneeded = false;
+
+ if (! ecoff_slurp_symbolic_header (abfd))
+ goto error_return;
+
+ /* If there are no symbols, we don't want it. */
+ if (bfd_get_symcount (abfd) == 0)
+ goto successful_return;
+
+ symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
+
+ /* Read in the external symbols and external strings. */
+ external_ext_size = backend->debug_swap.external_ext_size;
+ esize = symhdr->iextMax * external_ext_size;
+ external_ext = (PTR) bfd_malloc (esize);
+ if (external_ext == NULL && esize != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0
+ || bfd_read (external_ext, 1, esize, abfd) != esize)
+ goto error_return;
+
+ ssext = (char *) bfd_malloc (symhdr->issExtMax);
+ if (ssext == NULL && symhdr->issExtMax != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0
+ || (bfd_read (ssext, 1, symhdr->issExtMax, abfd) !=
+ (bfd_size_type) symhdr->issExtMax))
+ goto error_return;
+
+ /* Look through the external symbols to see if they define some
+ symbol that is currently undefined. */
+ ext_ptr = (char *) external_ext;
+ ext_end = ext_ptr + esize;
+ for (; ext_ptr < ext_end; ext_ptr += external_ext_size)
+ {
+ EXTR esym;
+ boolean def;
+ const char *name;
+ struct bfd_link_hash_entry *h;
+
+ (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym);
+
+ /* See if this symbol defines something. */
+ if (esym.asym.st != stGlobal
+ && esym.asym.st != stLabel
+ && esym.asym.st != stProc)
+ continue;
+
+ switch (esym.asym.sc)
+ {
+ case scText:
+ case scData:
+ case scBss:
+ case scAbs:
+ case scSData:
+ case scSBss:
+ case scRData:
+ case scCommon:
+ case scSCommon:
+ case scInit:
+ case scFini:
+ case scRConst:
+ def = true;
+ break;
+ default:
+ def = false;
+ break;
+ }
+
+ if (! def)
+ continue;
+
+ name = ssext + esym.asym.iss;
+ h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+
+ /* Unlike the generic linker, we do not pull in elements because
+ of common symbols. */
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || h->type != bfd_link_hash_undefined)
+ continue;
+
+ /* Include this element. */
+ if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ goto error_return;
+ if (! ecoff_link_add_externals (abfd, info, external_ext, ssext))
+ goto error_return;
+
+ *pneeded = true;
+ goto successful_return;
+ }
+
+ successful_return:
+ if (external_ext != NULL)
+ free (external_ext);
+ if (ssext != NULL)
+ free (ssext);
+ return true;
+ error_return:
+ if (external_ext != NULL)
+ free (external_ext);
+ if (ssext != NULL)
+ free (ssext);
+ return false;
+}
+
+/* Add symbols from an ECOFF object file to the global linker hash
+ table. */
+
+static boolean
+ecoff_link_add_object_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ HDRR *symhdr;
+ bfd_size_type external_ext_size;
+ PTR external_ext = NULL;
+ size_t esize;
+ char *ssext = NULL;
+ boolean result;
+
+ if (! ecoff_slurp_symbolic_header (abfd))
+ return false;
+
+ /* If there are no symbols, we don't want it. */
+ if (bfd_get_symcount (abfd) == 0)
+ return true;
+
+ symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
+
+ /* Read in the external symbols and external strings. */
+ external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size;
+ esize = symhdr->iextMax * external_ext_size;
+ external_ext = (PTR) bfd_malloc (esize);
+ if (external_ext == NULL && esize != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0
+ || bfd_read (external_ext, 1, esize, abfd) != esize)
+ goto error_return;
+
+ ssext = (char *) bfd_malloc (symhdr->issExtMax);
+ if (ssext == NULL && symhdr->issExtMax != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0
+ || (bfd_read (ssext, 1, symhdr->issExtMax, abfd)
+ != (bfd_size_type) symhdr->issExtMax))
+ goto error_return;
+
+ result = ecoff_link_add_externals (abfd, info, external_ext, ssext);
+
+ if (ssext != NULL)
+ free (ssext);
+ if (external_ext != NULL)
+ free (external_ext);
+ return result;
+
+ error_return:
+ if (ssext != NULL)
+ free (ssext);
+ if (external_ext != NULL)
+ free (external_ext);
+ return false;
+}
+
+/* Add the external symbols of an object file to the global linker
+ hash table. The external symbols and strings we are passed are
+ just allocated on the stack, and will be discarded. We must
+ explicitly save any information we may need later on in the link.
+ We do not want to read the external symbol information again. */
+
+static boolean
+ecoff_link_add_externals (abfd, info, external_ext, ssext)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ PTR external_ext;
+ char *ssext;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
+ = backend->debug_swap.swap_ext_in;
+ bfd_size_type external_ext_size = backend->debug_swap.external_ext_size;
+ unsigned long ext_count;
+ struct ecoff_link_hash_entry **sym_hash;
+ char *ext_ptr;
+ char *ext_end;
+
+ ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
+
+ sym_hash = ((struct ecoff_link_hash_entry **)
+ bfd_alloc (abfd,
+ ext_count * sizeof (struct bfd_link_hash_entry *)));
+ if (!sym_hash)
+ return false;
+ ecoff_data (abfd)->sym_hashes = sym_hash;
+
+ ext_ptr = (char *) external_ext;
+ ext_end = ext_ptr + ext_count * external_ext_size;
+ for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++)
+ {
+ EXTR esym;
+ boolean skip;
+ bfd_vma value;
+ asection *section;
+ const char *name;
+ struct ecoff_link_hash_entry *h;
+
+ *sym_hash = NULL;
+
+ (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym);
+
+ /* Skip debugging symbols. */
+ skip = false;
+ switch (esym.asym.st)
+ {
+ case stGlobal:
+ case stStatic:
+ case stLabel:
+ case stProc:
+ case stStaticProc:
+ break;
+ default:
+ skip = true;
+ break;
+ }
+
+ if (skip)
+ continue;
+
+ /* Get the information for this symbol. */
+ value = esym.asym.value;
+ switch (esym.asym.sc)
+ {
+ default:
+ case scNil:
+ case scRegister:
+ case scCdbLocal:
+ case scBits:
+ case scCdbSystem:
+ case scRegImage:
+ case scInfo:
+ case scUserStruct:
+ case scVar:
+ case scVarRegister:
+ case scVariant:
+ case scBasedVar:
+ case scXData:
+ case scPData:
+ section = NULL;
+ break;
+ case scText:
+ section = bfd_make_section_old_way (abfd, ".text");
+ value -= section->vma;
+ break;
+ case scData:
+ section = bfd_make_section_old_way (abfd, ".data");
+ value -= section->vma;
+ break;
+ case scBss:
+ section = bfd_make_section_old_way (abfd, ".bss");
+ value -= section->vma;
+ break;
+ case scAbs:
+ section = bfd_abs_section_ptr;
+ break;
+ case scUndefined:
+ section = bfd_und_section_ptr;
+ break;
+ case scSData:
+ section = bfd_make_section_old_way (abfd, ".sdata");
+ value -= section->vma;
+ break;
+ case scSBss:
+ section = bfd_make_section_old_way (abfd, ".sbss");
+ value -= section->vma;
+ break;
+ case scRData:
+ section = bfd_make_section_old_way (abfd, ".rdata");
+ value -= section->vma;
+ break;
+ case scCommon:
+ if (value > ecoff_data (abfd)->gp_size)
+ {
+ section = bfd_com_section_ptr;
+ break;
+ }
+ /* Fall through. */
+ case scSCommon:
+ if (ecoff_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ ecoff_scom_section.name = SCOMMON;
+ ecoff_scom_section.flags = SEC_IS_COMMON;
+ ecoff_scom_section.output_section = &ecoff_scom_section;
+ ecoff_scom_section.symbol = &ecoff_scom_symbol;
+ ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
+ ecoff_scom_symbol.name = SCOMMON;
+ ecoff_scom_symbol.flags = BSF_SECTION_SYM;
+ ecoff_scom_symbol.section = &ecoff_scom_section;
+ ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
+ }
+ section = &ecoff_scom_section;
+ break;
+ case scSUndefined:
+ section = bfd_und_section_ptr;
+ break;
+ case scInit:
+ section = bfd_make_section_old_way (abfd, ".init");
+ value -= section->vma;
+ break;
+ case scFini:
+ section = bfd_make_section_old_way (abfd, ".fini");
+ value -= section->vma;
+ break;
+ case scRConst:
+ section = bfd_make_section_old_way (abfd, ".rconst");
+ value -= section->vma;
+ break;
+ }
+
+ if (section == (asection *) NULL)
+ continue;
+
+ name = ssext + esym.asym.iss;
+
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name,
+ esym.weakext ? BSF_WEAK : BSF_GLOBAL,
+ section, value, (const char *) NULL, true, true,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+
+ *sym_hash = h;
+
+ /* If we are building an ECOFF hash table, save the external
+ symbol information. */
+ if (info->hash->creator->flavour == bfd_get_flavour (abfd))
+ {
+ if (h->abfd == (bfd *) NULL
+ || (! bfd_is_und_section (section)
+ && (! bfd_is_com_section (section)
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak))))
+ {
+ h->abfd = abfd;
+ h->esym = esym;
+ }
+
+ /* Remember whether this symbol was small undefined. */
+ if (esym.asym.sc == scSUndefined)
+ h->small = 1;
+
+ /* If this symbol was ever small undefined, it needs to wind
+ up in a GP relative section. We can't control the
+ section of a defined symbol, but we can control the
+ section of a common symbol. This case is actually needed
+ on Ultrix 4.2 to handle the symbol cred in -lckrb. */
+ if (h->small
+ && h->root.type == bfd_link_hash_common
+ && strcmp (h->root.u.c.p->section->name, SCOMMON) != 0)
+ {
+ h->root.u.c.p->section = bfd_make_section_old_way (abfd,
+ SCOMMON);
+ h->root.u.c.p->section->flags = SEC_ALLOC;
+ if (h->esym.asym.sc == scCommon)
+ h->esym.asym.sc = scSCommon;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* ECOFF final link routines. */
+
+static boolean ecoff_final_link_debug_accumulate
+ PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *,
+ PTR handle));
+static boolean ecoff_link_write_external
+ PARAMS ((struct ecoff_link_hash_entry *, PTR));
+static boolean ecoff_indirect_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+static boolean ecoff_reloc_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* Structure used to pass information to ecoff_link_write_external. */
+
+struct extsym_info
+{
+ bfd *abfd;
+ struct bfd_link_info *info;
+};
+
+/* ECOFF final link routine. This looks through all the input BFDs
+ and gathers together all the debugging information, and then
+ processes all the link order information. This may cause it to
+ close and reopen some input BFDs; I'll see how bad this is. */
+
+boolean
+_bfd_ecoff_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
+ HDRR *symhdr;
+ PTR handle;
+ register bfd *input_bfd;
+ asection *o;
+ struct bfd_link_order *p;
+ struct extsym_info einfo;
+
+ /* We accumulate the debugging information counts in the symbolic
+ header. */
+ symhdr = &debug->symbolic_header;
+ symhdr->vstamp = 0;
+ symhdr->ilineMax = 0;
+ symhdr->cbLine = 0;
+ symhdr->idnMax = 0;
+ symhdr->ipdMax = 0;
+ symhdr->isymMax = 0;
+ symhdr->ioptMax = 0;
+ symhdr->iauxMax = 0;
+ symhdr->issMax = 0;
+ symhdr->issExtMax = 0;
+ symhdr->ifdMax = 0;
+ symhdr->crfd = 0;
+ symhdr->iextMax = 0;
+
+ /* We accumulate the debugging information itself in the debug_info
+ structure. */
+ debug->line = NULL;
+ debug->external_dnr = NULL;
+ debug->external_pdr = NULL;
+ debug->external_sym = NULL;
+ debug->external_opt = NULL;
+ debug->external_aux = NULL;
+ debug->ss = NULL;
+ debug->ssext = debug->ssext_end = NULL;
+ debug->external_fdr = NULL;
+ debug->external_rfd = NULL;
+ debug->external_ext = debug->external_ext_end = NULL;
+
+ handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info);
+ if (handle == (PTR) NULL)
+ return false;
+
+ /* Accumulate the debugging symbols from each input BFD. */
+ for (input_bfd = info->input_bfds;
+ input_bfd != (bfd *) NULL;
+ input_bfd = input_bfd->link_next)
+ {
+ boolean ret;
+
+ if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
+ {
+ /* Abitrarily set the symbolic header vstamp to the vstamp
+ of the first object file in the link. */
+ if (symhdr->vstamp == 0)
+ symhdr->vstamp
+ = ecoff_data (input_bfd)->debug_info.symbolic_header.vstamp;
+ ret = ecoff_final_link_debug_accumulate (abfd, input_bfd, info,
+ handle);
+ }
+ else
+ ret = bfd_ecoff_debug_accumulate_other (handle, abfd,
+ debug, &backend->debug_swap,
+ input_bfd, info);
+ if (! ret)
+ return false;
+
+ /* Combine the register masks. */
+ ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask;
+ ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask;
+ ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0];
+ ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1];
+ ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2];
+ ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3];
+ }
+
+ /* Write out the external symbols. */
+ einfo.abfd = abfd;
+ einfo.info = info;
+ ecoff_link_hash_traverse (ecoff_hash_table (info),
+ ecoff_link_write_external,
+ (PTR) &einfo);
+
+ if (info->relocateable)
+ {
+ /* We need to make a pass over the link_orders to count up the
+ number of relocations we will need to output, so that we know
+ how much space they will take up. */
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ if (p->type == bfd_indirect_link_order)
+ o->reloc_count += p->u.indirect.section->reloc_count;
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ ++o->reloc_count;
+ }
+ }
+
+ /* Compute the reloc and symbol file positions. */
+ ecoff_compute_reloc_file_positions (abfd);
+
+ /* Write out the debugging information. */
+ if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug,
+ &backend->debug_swap, info,
+ ecoff_data (abfd)->sym_filepos))
+ return false;
+
+ bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info);
+
+ if (info->relocateable)
+ {
+ /* Now reset the reloc_count field of the sections in the output
+ BFD to 0, so that we can use them to keep track of how many
+ relocs we have output thus far. */
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ o->reloc_count = 0;
+ }
+
+ /* Get a value for the GP register. */
+ if (ecoff_data (abfd)->gp == 0)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_defined)
+ ecoff_data (abfd)->gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ else if (info->relocateable)
+ {
+ bfd_vma lo;
+
+ /* Make up a value. */
+ lo = (bfd_vma) -1;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ if (o->vma < lo
+ && (strcmp (o->name, _SBSS) == 0
+ || strcmp (o->name, _SDATA) == 0
+ || strcmp (o->name, _LIT4) == 0
+ || strcmp (o->name, _LIT8) == 0
+ || strcmp (o->name, _LITA) == 0))
+ lo = o->vma;
+ }
+ ecoff_data (abfd)->gp = lo + 0x8000;
+ }
+ else
+ {
+ /* If the relocate_section function needs to do a reloc
+ involving the GP value, it should make a reloc_dangerous
+ callback to warn that GP is not defined. */
+ }
+ }
+
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour (p->u.indirect.section->owner)
+ == bfd_target_ecoff_flavour))
+ {
+ if (! ecoff_indirect_link_order (abfd, info, o, p))
+ return false;
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ if (! ecoff_reloc_link_order (abfd, info, o, p))
+ return false;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ return false;
+ }
+ }
+ }
+
+ bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax;
+
+ ecoff_data (abfd)->linker = true;
+
+ return true;
+}
+
+/* Accumulate the debugging information for an input BFD into the
+ output BFD. This must read in the symbolic information of the
+ input BFD. */
+
+static boolean
+ecoff_final_link_debug_accumulate (output_bfd, input_bfd, info, handle)
+ bfd *output_bfd;
+ bfd *input_bfd;
+ struct bfd_link_info *info;
+ PTR handle;
+{
+ struct ecoff_debug_info * const debug = &ecoff_data (input_bfd)->debug_info;
+ const struct ecoff_debug_swap * const swap =
+ &ecoff_backend (input_bfd)->debug_swap;
+ HDRR *symhdr = &debug->symbolic_header;
+ boolean ret;
+
+#define READ(ptr, offset, count, size, type) \
+ if (symhdr->count == 0) \
+ debug->ptr = NULL; \
+ else \
+ { \
+ debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \
+ if (debug->ptr == NULL) \
+ { \
+ ret = false; \
+ goto return_something; \
+ } \
+ if ((bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) \
+ != 0) \
+ || (bfd_read (debug->ptr, size, symhdr->count, \
+ input_bfd) != size * symhdr->count)) \
+ { \
+ ret = false; \
+ goto return_something; \
+ } \
+ }
+
+ /* If raw_syments is not NULL, then the data was already by read by
+ _bfd_ecoff_slurp_symbolic_info. */
+ if (ecoff_data (input_bfd)->raw_syments == NULL)
+ {
+ READ (line, cbLineOffset, cbLine, sizeof (unsigned char),
+ unsigned char *);
+ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
+ READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
+ union aux_ext *);
+ READ (ss, cbSsOffset, issMax, sizeof (char), char *);
+ READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
+ }
+#undef READ
+
+ /* We do not read the external strings or the external symbols. */
+
+ ret = (bfd_ecoff_debug_accumulate
+ (handle, output_bfd, &ecoff_data (output_bfd)->debug_info,
+ &ecoff_backend (output_bfd)->debug_swap,
+ input_bfd, debug, swap, info));
+
+ return_something:
+ if (ecoff_data (input_bfd)->raw_syments == NULL)
+ {
+ if (debug->line != NULL)
+ free (debug->line);
+ if (debug->external_dnr != NULL)
+ free (debug->external_dnr);
+ if (debug->external_pdr != NULL)
+ free (debug->external_pdr);
+ if (debug->external_sym != NULL)
+ free (debug->external_sym);
+ if (debug->external_opt != NULL)
+ free (debug->external_opt);
+ if (debug->external_aux != NULL)
+ free (debug->external_aux);
+ if (debug->ss != NULL)
+ free (debug->ss);
+ if (debug->external_fdr != NULL)
+ free (debug->external_fdr);
+ if (debug->external_rfd != NULL)
+ free (debug->external_rfd);
+
+ /* Make sure we don't accidentally follow one of these pointers
+ into freed memory. */
+ debug->line = NULL;
+ debug->external_dnr = NULL;
+ debug->external_pdr = NULL;
+ debug->external_sym = NULL;
+ debug->external_opt = NULL;
+ debug->external_aux = NULL;
+ debug->ss = NULL;
+ debug->external_fdr = NULL;
+ debug->external_rfd = NULL;
+ }
+
+ return ret;
+}
+
+/* Put out information for an external symbol. These come only from
+ the hash table. */
+
+static boolean
+ecoff_link_write_external (h, data)
+ struct ecoff_link_hash_entry *h;
+ PTR data;
+{
+ struct extsym_info *einfo = (struct extsym_info *) data;
+ bfd *output_bfd = einfo->abfd;
+ boolean strip;
+
+ /* We need to check if this symbol is being stripped. */
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ strip = false;
+ else if (einfo->info->strip == strip_all
+ || (einfo->info->strip == strip_some
+ && bfd_hash_lookup (einfo->info->keep_hash,
+ h->root.root.string,
+ false, false) == NULL))
+ strip = true;
+ else
+ strip = false;
+
+ if (strip || h->written)
+ return true;
+
+ if (h->abfd == (bfd *) NULL)
+ {
+ h->esym.jmptbl = 0;
+ h->esym.cobol_main = 0;
+ h->esym.weakext = 0;
+ h->esym.reserved = 0;
+ h->esym.ifd = ifdNil;
+ h->esym.asym.value = 0;
+ h->esym.asym.st = stGlobal;
+
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ h->esym.asym.sc = scAbs;
+ else
+ {
+ asection *output_section;
+ const char *name;
+
+ output_section = h->root.u.def.section->output_section;
+ name = bfd_section_name (output_section->owner, output_section);
+
+ if (strcmp (name, _TEXT) == 0)
+ h->esym.asym.sc = scText;
+ else if (strcmp (name, _DATA) == 0)
+ h->esym.asym.sc = scData;
+ else if (strcmp (name, _SDATA) == 0)
+ h->esym.asym.sc = scSData;
+ else if (strcmp (name, _RDATA) == 0)
+ h->esym.asym.sc = scRData;
+ else if (strcmp (name, _BSS) == 0)
+ h->esym.asym.sc = scBss;
+ else if (strcmp (name, _SBSS) == 0)
+ h->esym.asym.sc = scSBss;
+ else if (strcmp (name, _INIT) == 0)
+ h->esym.asym.sc = scInit;
+ else if (strcmp (name, _FINI) == 0)
+ h->esym.asym.sc = scFini;
+ else if (strcmp (name, _PDATA) == 0)
+ h->esym.asym.sc = scPData;
+ else if (strcmp (name, _XDATA) == 0)
+ h->esym.asym.sc = scXData;
+ else if (strcmp (name, _RCONST) == 0)
+ h->esym.asym.sc = scRConst;
+ else
+ h->esym.asym.sc = scAbs;
+ }
+
+ h->esym.asym.reserved = 0;
+ h->esym.asym.index = indexNil;
+ }
+ else if (h->esym.ifd != -1)
+ {
+ struct ecoff_debug_info *debug;
+
+ /* Adjust the FDR index for the symbol by that used for the
+ input BFD. */
+ debug = &ecoff_data (h->abfd)->debug_info;
+ BFD_ASSERT (h->esym.ifd >= 0
+ && h->esym.ifd < debug->symbolic_header.ifdMax);
+ h->esym.ifd = debug->ifdmap[h->esym.ifd];
+ }
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ abort ();
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ if (h->esym.asym.sc != scUndefined
+ && h->esym.asym.sc != scSUndefined)
+ h->esym.asym.sc = scUndefined;
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ if (h->esym.asym.sc == scUndefined
+ || h->esym.asym.sc == scSUndefined)
+ h->esym.asym.sc = scAbs;
+ else if (h->esym.asym.sc == scCommon)
+ h->esym.asym.sc = scBss;
+ else if (h->esym.asym.sc == scSCommon)
+ h->esym.asym.sc = scSBss;
+ h->esym.asym.value = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ break;
+ case bfd_link_hash_common:
+ if (h->esym.asym.sc != scCommon
+ && h->esym.asym.sc != scSCommon)
+ h->esym.asym.sc = scCommon;
+ h->esym.asym.value = h->root.u.c.size;
+ break;
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ /* FIXME: Ignore these for now. The circumstances under which
+ they should be written out are not clear to me. */
+ return true;
+ }
+
+ /* bfd_ecoff_debug_one_external uses iextMax to keep track of the
+ symbol number. */
+ h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax;
+ h->written = 1;
+
+ return (bfd_ecoff_debug_one_external
+ (output_bfd, &ecoff_data (output_bfd)->debug_info,
+ &ecoff_backend (output_bfd)->debug_swap, h->root.root.string,
+ &h->esym));
+}
+
+/* Relocate and write an ECOFF section into an ECOFF output file. */
+
+static boolean
+ecoff_indirect_link_order (output_bfd, info, output_section, link_order)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+{
+ asection *input_section;
+ bfd *input_bfd;
+ struct ecoff_section_tdata *section_tdata;
+ bfd_size_type raw_size;
+ bfd_size_type cooked_size;
+ bfd_byte *contents = NULL;
+ bfd_size_type external_reloc_size;
+ bfd_size_type external_relocs_size;
+ PTR external_relocs = NULL;
+
+ BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);
+
+ if (link_order->size == 0)
+ return true;
+
+ input_section = link_order->u.indirect.section;
+ input_bfd = input_section->owner;
+ section_tdata = ecoff_section_data (input_bfd, input_section);
+
+ raw_size = input_section->_raw_size;
+ cooked_size = input_section->_cooked_size;
+ if (cooked_size == 0)
+ cooked_size = raw_size;
+
+ BFD_ASSERT (input_section->output_section == output_section);
+ BFD_ASSERT (input_section->output_offset == link_order->offset);
+ BFD_ASSERT (cooked_size == link_order->size);
+
+ /* Get the section contents. We allocate memory for the larger of
+ the size before relocating and the size after relocating. */
+ contents = (bfd_byte *) bfd_malloc (raw_size >= cooked_size
+ ? (size_t) raw_size
+ : (size_t) cooked_size);
+ if (contents == NULL && raw_size != 0)
+ goto error_return;
+
+ /* If we are relaxing, the contents may have already been read into
+ memory, in which case we copy them into our new buffer. We don't
+ simply reuse the old buffer in case cooked_size > raw_size. */
+ if (section_tdata != (struct ecoff_section_tdata *) NULL
+ && section_tdata->contents != (bfd_byte *) NULL)
+ memcpy (contents, section_tdata->contents, (size_t) raw_size);
+ else
+ {
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (PTR) contents,
+ (file_ptr) 0, raw_size))
+ goto error_return;
+ }
+
+ /* Get the relocs. If we are relaxing MIPS code, they will already
+ have been read in. Otherwise, we read them in now. */
+ external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size;
+ external_relocs_size = external_reloc_size * input_section->reloc_count;
+
+ if (section_tdata != (struct ecoff_section_tdata *) NULL
+ && section_tdata->external_relocs != NULL)
+ external_relocs = section_tdata->external_relocs;
+ else
+ {
+ external_relocs = (PTR) bfd_malloc ((size_t) external_relocs_size);
+ if (external_relocs == NULL && external_relocs_size != 0)
+ goto error_return;
+
+ if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+ || (bfd_read (external_relocs, 1, external_relocs_size, input_bfd)
+ != external_relocs_size))
+ goto error_return;
+ }
+
+ /* Relocate the section contents. */
+ if (! ((*ecoff_backend (input_bfd)->relocate_section)
+ (output_bfd, info, input_bfd, input_section, contents,
+ external_relocs)))
+ goto error_return;
+
+ /* Write out the relocated section. */
+ if (! bfd_set_section_contents (output_bfd,
+ output_section,
+ (PTR) contents,
+ input_section->output_offset,
+ cooked_size))
+ goto error_return;
+
+ /* If we are producing relocateable output, the relocs were
+ modified, and we write them out now. We use the reloc_count
+ field of output_section to keep track of the number of relocs we
+ have output so far. */
+ if (info->relocateable)
+ {
+ if (bfd_seek (output_bfd,
+ (output_section->rel_filepos +
+ output_section->reloc_count * external_reloc_size),
+ SEEK_SET) != 0
+ || (bfd_write (external_relocs, 1, external_relocs_size, output_bfd)
+ != external_relocs_size))
+ goto error_return;
+ output_section->reloc_count += input_section->reloc_count;
+ }
+
+ if (contents != NULL)
+ free (contents);
+ if (external_relocs != NULL && section_tdata == NULL)
+ free (external_relocs);
+ return true;
+
+ error_return:
+ if (contents != NULL)
+ free (contents);
+ if (external_relocs != NULL && section_tdata == NULL)
+ free (external_relocs);
+ return false;
+}
+
+/* Generate a reloc when linking an ECOFF file. This is a reloc
+ requested by the linker, and does come from any input file. This
+ is used to build constructor and destructor tables when linking
+ with -Ur. */
+
+static boolean
+ecoff_reloc_link_order (output_bfd, info, output_section, link_order)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+{
+ enum bfd_link_order_type type;
+ asection *section;
+ bfd_vma addend;
+ arelent rel;
+ struct internal_reloc in;
+ bfd_size_type external_reloc_size;
+ bfd_byte *rbuf;
+ boolean ok;
+
+ type = link_order->type;
+ section = NULL;
+ addend = link_order->u.reloc.p->addend;
+
+ /* We set up an arelent to pass to the backend adjust_reloc_out
+ routine. */
+ rel.address = link_order->offset;
+
+ rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
+ if (rel.howto == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (type == bfd_section_reloc_link_order)
+ {
+ section = link_order->u.reloc.p->u.section;
+ rel.sym_ptr_ptr = section->symbol_ptr_ptr;
+ }
+ else
+ {
+ struct bfd_link_hash_entry *h;
+
+ /* Treat a reloc against a defined symbol as though it were
+ actually against the section. */
+ h = bfd_wrapped_link_hash_lookup (output_bfd, info,
+ link_order->u.reloc.p->u.name,
+ false, false, false);
+ if (h != NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ {
+ type = bfd_section_reloc_link_order;
+ section = h->u.def.section->output_section;
+ /* It seems that we ought to add the symbol value to the
+ addend here, but in practice it has already been added
+ because it was passed to constructor_callback. */
+ addend += section->vma + h->u.def.section->output_offset;
+ }
+ else
+ {
+ /* We can't set up a reloc against a symbol correctly,
+ because we have no asymbol structure. Currently no
+ adjust_reloc_out routine cares. */
+ rel.sym_ptr_ptr = (asymbol **) NULL;
+ }
+ }
+
+ /* All ECOFF relocs are in-place. Put the addend into the object
+ file. */
+
+ BFD_ASSERT (rel.howto->partial_inplace);
+ if (addend != 0)
+ {
+ bfd_size_type size;
+ bfd_reloc_status_type rstat;
+ bfd_byte *buf;
+ boolean ok;
+
+ size = bfd_get_reloc_size (rel.howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == (bfd_byte *) NULL)
+ return false;
+ rstat = _bfd_relocate_contents (rel.howto, output_bfd, addend, buf);
+ switch (rstat)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info,
+ (link_order->type == bfd_section_reloc_link_order
+ ? bfd_section_name (output_bfd, section)
+ : link_order->u.reloc.p->u.name),
+ rel.howto->name, addend, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return false;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
+ (file_ptr) link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return false;
+ }
+
+ rel.addend = 0;
+
+ /* Move the information into a internal_reloc structure. */
+ in.r_vaddr = (rel.address
+ + bfd_get_section_vma (output_bfd, output_section));
+ in.r_type = rel.howto->type;
+
+ if (type == bfd_symbol_reloc_link_order)
+ {
+ struct ecoff_link_hash_entry *h;
+
+ h = ((struct ecoff_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (output_bfd, info,
+ link_order->u.reloc.p->u.name,
+ false, false, true));
+ if (h != (struct ecoff_link_hash_entry *) NULL
+ && h->indx != -1)
+ in.r_symndx = h->indx;
+ else
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ in.r_symndx = 0;
+ }
+ in.r_extern = 1;
+ }
+ else
+ {
+ CONST char *name;
+
+ name = bfd_get_section_name (output_bfd, section);
+ if (strcmp (name, ".text") == 0)
+ in.r_symndx = RELOC_SECTION_TEXT;
+ else if (strcmp (name, ".rdata") == 0)
+ in.r_symndx = RELOC_SECTION_RDATA;
+ else if (strcmp (name, ".data") == 0)
+ in.r_symndx = RELOC_SECTION_DATA;
+ else if (strcmp (name, ".sdata") == 0)
+ in.r_symndx = RELOC_SECTION_SDATA;
+ else if (strcmp (name, ".sbss") == 0)
+ in.r_symndx = RELOC_SECTION_SBSS;
+ else if (strcmp (name, ".bss") == 0)
+ in.r_symndx = RELOC_SECTION_BSS;
+ else if (strcmp (name, ".init") == 0)
+ in.r_symndx = RELOC_SECTION_INIT;
+ else if (strcmp (name, ".lit8") == 0)
+ in.r_symndx = RELOC_SECTION_LIT8;
+ else if (strcmp (name, ".lit4") == 0)
+ in.r_symndx = RELOC_SECTION_LIT4;
+ else if (strcmp (name, ".xdata") == 0)
+ in.r_symndx = RELOC_SECTION_XDATA;
+ else if (strcmp (name, ".pdata") == 0)
+ in.r_symndx = RELOC_SECTION_PDATA;
+ else if (strcmp (name, ".fini") == 0)
+ in.r_symndx = RELOC_SECTION_FINI;
+ else if (strcmp (name, ".lita") == 0)
+ in.r_symndx = RELOC_SECTION_LITA;
+ else if (strcmp (name, "*ABS*") == 0)
+ in.r_symndx = RELOC_SECTION_ABS;
+ else if (strcmp (name, ".rconst") == 0)
+ in.r_symndx = RELOC_SECTION_RCONST;
+ else
+ abort ();
+ in.r_extern = 0;
+ }
+
+ /* Let the BFD backend adjust the reloc. */
+ (*ecoff_backend (output_bfd)->adjust_reloc_out) (output_bfd, &rel, &in);
+
+ /* Get some memory and swap out the reloc. */
+ external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size;
+ rbuf = (bfd_byte *) bfd_malloc ((size_t) external_reloc_size);
+ if (rbuf == (bfd_byte *) NULL)
+ return false;
+
+ (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (PTR) rbuf);
+
+ ok = (bfd_seek (output_bfd,
+ (output_section->rel_filepos +
+ output_section->reloc_count * external_reloc_size),
+ SEEK_SET) == 0
+ && (bfd_write ((PTR) rbuf, 1, external_reloc_size, output_bfd)
+ == external_reloc_size));
+
+ if (ok)
+ ++output_section->reloc_count;
+
+ free (rbuf);
+
+ return ok;
+}
diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c
new file mode 100644
index 00000000000..a120a2be7c5
--- /dev/null
+++ b/bfd/ecofflink.c
@@ -0,0 +1,2499 @@
+/* Routines to link ECOFF debugging information.
+ Copyright 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "objalloc.h"
+#include "aout/stab_gnu.h"
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff.h"
+#include "libcoff.h"
+#include "libecoff.h"
+
+static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
+ size_t need));
+static struct bfd_hash_entry *string_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *));
+static void ecoff_align_debug PARAMS ((bfd *abfd,
+ struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap));
+static boolean ecoff_write_symhdr PARAMS ((bfd *, struct ecoff_debug_info *,
+ const struct ecoff_debug_swap *,
+ file_ptr where));
+static int cmp_fdrtab_entry PARAMS ((const PTR, const PTR));
+static boolean mk_fdrtab PARAMS ((bfd *,
+ struct ecoff_debug_info * const,
+ const struct ecoff_debug_swap * const,
+ struct ecoff_find_line *));
+static long fdrtab_lookup PARAMS ((struct ecoff_find_line *, bfd_vma));
+static boolean lookup_line
+ PARAMS ((bfd *, struct ecoff_debug_info * const,
+ const struct ecoff_debug_swap * const, struct ecoff_find_line *));
+
+/* Routines to swap auxiliary information in and out. I am assuming
+ that the auxiliary information format is always going to be target
+ independent. */
+
+/* Swap in a type information record.
+ BIGEND says whether AUX symbols are big-endian or little-endian; this
+ info comes from the file header record (fh-fBigendian). */
+
+void
+_bfd_ecoff_swap_tir_in (bigend, ext_copy, intern)
+ int bigend;
+ const struct tir_ext *ext_copy;
+ TIR *intern;
+{
+ struct tir_ext ext[1];
+
+ *ext = *ext_copy; /* Make it reasonable to do in-place. */
+
+ /* now the fun stuff... */
+ if (bigend) {
+ intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
+ intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
+ intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_BIG)
+ >> TIR_BITS1_BT_SH_BIG;
+ intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG)
+ >> TIR_BITS_TQ4_SH_BIG;
+ intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG)
+ >> TIR_BITS_TQ5_SH_BIG;
+ intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG)
+ >> TIR_BITS_TQ0_SH_BIG;
+ intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG)
+ >> TIR_BITS_TQ1_SH_BIG;
+ intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG)
+ >> TIR_BITS_TQ2_SH_BIG;
+ intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG)
+ >> TIR_BITS_TQ3_SH_BIG;
+ } else {
+ intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE);
+ intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE);
+ intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE)
+ >> TIR_BITS1_BT_SH_LITTLE;
+ intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE)
+ >> TIR_BITS_TQ4_SH_LITTLE;
+ intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE)
+ >> TIR_BITS_TQ5_SH_LITTLE;
+ intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE)
+ >> TIR_BITS_TQ0_SH_LITTLE;
+ intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE)
+ >> TIR_BITS_TQ1_SH_LITTLE;
+ intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE)
+ >> TIR_BITS_TQ2_SH_LITTLE;
+ intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE)
+ >> TIR_BITS_TQ3_SH_LITTLE;
+ }
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out a type information record.
+ BIGEND says whether AUX symbols are big-endian or little-endian; this
+ info comes from the file header record (fh-fBigendian). */
+
+void
+_bfd_ecoff_swap_tir_out (bigend, intern_copy, ext)
+ int bigend;
+ const TIR *intern_copy;
+ struct tir_ext *ext;
+{
+ TIR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ /* now the fun stuff... */
+ if (bigend) {
+ ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
+ | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
+ | ((intern->bt << TIR_BITS1_BT_SH_BIG)
+ & TIR_BITS1_BT_BIG));
+ ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG)
+ & TIR_BITS_TQ4_BIG)
+ | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG)
+ & TIR_BITS_TQ5_BIG));
+ ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG)
+ & TIR_BITS_TQ0_BIG)
+ | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG)
+ & TIR_BITS_TQ1_BIG));
+ ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG)
+ & TIR_BITS_TQ2_BIG)
+ | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG)
+ & TIR_BITS_TQ3_BIG));
+ } else {
+ ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0)
+ | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0)
+ | ((intern->bt << TIR_BITS1_BT_SH_LITTLE)
+ & TIR_BITS1_BT_LITTLE));
+ ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE)
+ & TIR_BITS_TQ4_LITTLE)
+ | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE)
+ & TIR_BITS_TQ5_LITTLE));
+ ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE)
+ & TIR_BITS_TQ0_LITTLE)
+ | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE)
+ & TIR_BITS_TQ1_LITTLE));
+ ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE)
+ & TIR_BITS_TQ2_LITTLE)
+ | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE)
+ & TIR_BITS_TQ3_LITTLE));
+ }
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap in a relative symbol record. BIGEND says whether it is in
+ big-endian or little-endian format.*/
+
+void
+_bfd_ecoff_swap_rndx_in (bigend, ext_copy, intern)
+ int bigend;
+ const struct rndx_ext *ext_copy;
+ RNDXR *intern;
+{
+ struct rndx_ext ext[1];
+
+ *ext = *ext_copy; /* Make it reasonable to do in-place. */
+
+ /* now the fun stuff... */
+ if (bigend) {
+ intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
+ | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
+ >> RNDX_BITS1_RFD_SH_BIG);
+ intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG)
+ << RNDX_BITS1_INDEX_SH_LEFT_BIG)
+ | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG)
+ | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG);
+ } else {
+ intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE)
+ | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE)
+ << RNDX_BITS1_RFD_SH_LEFT_LITTLE);
+ intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE)
+ >> RNDX_BITS1_INDEX_SH_LITTLE)
+ | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE)
+ | ((unsigned int) ext->r_bits[3]
+ << RNDX_BITS3_INDEX_SH_LEFT_LITTLE);
+ }
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out a relative symbol record. BIGEND says whether it is in
+ big-endian or little-endian format.*/
+
+void
+_bfd_ecoff_swap_rndx_out (bigend, intern_copy, ext)
+ int bigend;
+ const RNDXR *intern_copy;
+ struct rndx_ext *ext;
+{
+ RNDXR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ /* now the fun stuff... */
+ if (bigend) {
+ ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
+ ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
+ & RNDX_BITS1_RFD_BIG)
+ | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG)
+ & RNDX_BITS1_INDEX_BIG));
+ ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG;
+ ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG;
+ } else {
+ ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE;
+ ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE)
+ & RNDX_BITS1_RFD_LITTLE)
+ | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE)
+ & RNDX_BITS1_INDEX_LITTLE));
+ ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE;
+ ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE;
+ }
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* The minimum amount of data to allocate. */
+#define ALLOC_SIZE (4064)
+
+/* Add bytes to a buffer. Return success. */
+
+static boolean
+ecoff_add_bytes (buf, bufend, need)
+ char **buf;
+ char **bufend;
+ size_t need;
+{
+ size_t have;
+ size_t want;
+ char *newbuf;
+
+ have = *bufend - *buf;
+ if (have > need)
+ want = ALLOC_SIZE;
+ else
+ {
+ want = need - have;
+ if (want < ALLOC_SIZE)
+ want = ALLOC_SIZE;
+ }
+ newbuf = (char *) bfd_realloc (*buf, have + want);
+ if (newbuf == NULL)
+ return false;
+ *buf = newbuf;
+ *bufend = *buf + have + want;
+ return true;
+}
+
+/* We keep a hash table which maps strings to numbers. We use it to
+ map FDR names to indices in the output file, and to map local
+ strings when combining stabs debugging information. */
+
+struct string_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* FDR index or string table offset. */
+ long val;
+ /* Next entry in string table. */
+ struct string_hash_entry *next;
+};
+
+struct string_hash_table
+{
+ struct bfd_hash_table table;
+};
+
+/* Routine to create an entry in a string hash table. */
+
+static struct bfd_hash_entry *
+string_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct string_hash_entry *ret = (struct string_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct string_hash_entry *) NULL)
+ ret = ((struct string_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
+ if (ret == (struct string_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct string_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->val = -1;
+ ret->next = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in an string hash table. */
+
+#define string_hash_lookup(t, string, create, copy) \
+ ((struct string_hash_entry *) \
+ bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
+
+/* We can't afford to read in all the debugging information when we do
+ a link. Instead, we build a list of these structures to show how
+ different parts of the input file map to the output file. */
+
+struct shuffle
+{
+ /* The next entry in this linked list. */
+ struct shuffle *next;
+ /* The length of the information. */
+ unsigned long size;
+ /* Whether this information comes from a file or not. */
+ boolean filep;
+ union
+ {
+ struct
+ {
+ /* The BFD the data comes from. */
+ bfd *input_bfd;
+ /* The offset within input_bfd. */
+ file_ptr offset;
+ } file;
+ /* The data to be written out. */
+ PTR memory;
+ } u;
+};
+
+/* This structure holds information across calls to
+ bfd_ecoff_debug_accumulate. */
+
+struct accumulate
+{
+ /* The FDR hash table. */
+ struct string_hash_table fdr_hash;
+ /* The strings hash table. */
+ struct string_hash_table str_hash;
+ /* Linked lists describing how to shuffle the input debug
+ information into the output file. We keep a pointer to both the
+ head and the tail. */
+ struct shuffle *line;
+ struct shuffle *line_end;
+ struct shuffle *pdr;
+ struct shuffle *pdr_end;
+ struct shuffle *sym;
+ struct shuffle *sym_end;
+ struct shuffle *opt;
+ struct shuffle *opt_end;
+ struct shuffle *aux;
+ struct shuffle *aux_end;
+ struct shuffle *ss;
+ struct shuffle *ss_end;
+ struct string_hash_entry *ss_hash;
+ struct string_hash_entry *ss_hash_end;
+ struct shuffle *fdr;
+ struct shuffle *fdr_end;
+ struct shuffle *rfd;
+ struct shuffle *rfd_end;
+ /* The size of the largest file shuffle. */
+ unsigned long largest_file_shuffle;
+ /* An objalloc for debugging information. */
+ struct objalloc *memory;
+};
+
+/* Add a file entry to a shuffle list. */
+
+static boolean add_file_shuffle PARAMS ((struct accumulate *,
+ struct shuffle **,
+ struct shuffle **, bfd *, file_ptr,
+ unsigned long));
+
+static boolean
+add_file_shuffle (ainfo, head, tail, input_bfd, offset, size)
+ struct accumulate *ainfo;
+ struct shuffle **head;
+ struct shuffle **tail;
+ bfd *input_bfd;
+ file_ptr offset;
+ unsigned long size;
+{
+ struct shuffle *n;
+
+ if (*tail != (struct shuffle *) NULL
+ && (*tail)->filep
+ && (*tail)->u.file.input_bfd == input_bfd
+ && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset)
+ {
+ /* Just merge this entry onto the existing one. */
+ (*tail)->size += size;
+ if ((*tail)->size > ainfo->largest_file_shuffle)
+ ainfo->largest_file_shuffle = (*tail)->size;
+ return true;
+ }
+
+ n = (struct shuffle *) objalloc_alloc (ainfo->memory,
+ sizeof (struct shuffle));
+ if (!n)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ n->next = NULL;
+ n->size = size;
+ n->filep = true;
+ n->u.file.input_bfd = input_bfd;
+ n->u.file.offset = offset;
+ if (*head == (struct shuffle *) NULL)
+ *head = n;
+ if (*tail != (struct shuffle *) NULL)
+ (*tail)->next = n;
+ *tail = n;
+ if (size > ainfo->largest_file_shuffle)
+ ainfo->largest_file_shuffle = size;
+ return true;
+}
+
+/* Add a memory entry to a shuffle list. */
+
+static boolean add_memory_shuffle PARAMS ((struct accumulate *,
+ struct shuffle **head,
+ struct shuffle **tail,
+ bfd_byte *data, unsigned long size));
+
+static boolean
+add_memory_shuffle (ainfo, head, tail, data, size)
+ struct accumulate *ainfo;
+ struct shuffle **head;
+ struct shuffle **tail;
+ bfd_byte *data;
+ unsigned long size;
+{
+ struct shuffle *n;
+
+ n = (struct shuffle *) objalloc_alloc (ainfo->memory,
+ sizeof (struct shuffle));
+ if (!n)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ n->next = NULL;
+ n->size = size;
+ n->filep = false;
+ n->u.memory = (PTR) data;
+ if (*head == (struct shuffle *) NULL)
+ *head = n;
+ if (*tail != (struct shuffle *) NULL)
+ (*tail)->next = n;
+ *tail = n;
+ return true;
+}
+
+/* Initialize the FDR hash table. This returns a handle which is then
+ passed in to bfd_ecoff_debug_accumulate, et. al. */
+
+/*ARGSUSED*/
+PTR
+bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info)
+ bfd *output_bfd;
+ struct ecoff_debug_info *output_debug;
+ const struct ecoff_debug_swap *output_swap;
+ struct bfd_link_info *info;
+{
+ struct accumulate *ainfo;
+
+ ainfo = (struct accumulate *) bfd_malloc (sizeof (struct accumulate));
+ if (!ainfo)
+ return NULL;
+ if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
+ 1021))
+ return NULL;
+
+ ainfo->line = NULL;
+ ainfo->line_end = NULL;
+ ainfo->pdr = NULL;
+ ainfo->pdr_end = NULL;
+ ainfo->sym = NULL;
+ ainfo->sym_end = NULL;
+ ainfo->opt = NULL;
+ ainfo->opt_end = NULL;
+ ainfo->aux = NULL;
+ ainfo->aux_end = NULL;
+ ainfo->ss = NULL;
+ ainfo->ss_end = NULL;
+ ainfo->ss_hash = NULL;
+ ainfo->ss_hash_end = NULL;
+ ainfo->fdr = NULL;
+ ainfo->fdr_end = NULL;
+ ainfo->rfd = NULL;
+ ainfo->rfd_end = NULL;
+
+ ainfo->largest_file_shuffle = 0;
+
+ if (! info->relocateable)
+ {
+ if (! bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc))
+ return NULL;
+
+ /* The first entry in the string table is the empty string. */
+ output_debug->symbolic_header.issMax = 1;
+ }
+
+ ainfo->memory = objalloc_create ();
+ if (ainfo->memory == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ return (PTR) ainfo;
+}
+
+/* Free the accumulated debugging information. */
+
+/*ARGSUSED*/
+void
+bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info)
+ PTR handle;
+ bfd *output_bfd;
+ struct ecoff_debug_info *output_debug;
+ const struct ecoff_debug_swap *output_swap;
+ struct bfd_link_info *info;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+
+ bfd_hash_table_free (&ainfo->fdr_hash.table);
+
+ if (! info->relocateable)
+ bfd_hash_table_free (&ainfo->str_hash.table);
+
+ objalloc_free (ainfo->memory);
+
+ free (ainfo);
+}
+
+/* Accumulate the debugging information from INPUT_BFD into
+ OUTPUT_BFD. The INPUT_DEBUG argument points to some ECOFF
+ debugging information which we want to link into the information
+ pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and
+ INPUT_SWAP point to the swapping information needed. INFO is the
+ linker information structure. HANDLE is returned by
+ bfd_ecoff_debug_init. */
+
+/*ARGSUSED*/
+boolean
+bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
+ input_bfd, input_debug, input_swap,
+ info)
+ PTR handle;
+ bfd *output_bfd;
+ struct ecoff_debug_info *output_debug;
+ const struct ecoff_debug_swap *output_swap;
+ bfd *input_bfd;
+ struct ecoff_debug_info *input_debug;
+ const struct ecoff_debug_swap *input_swap;
+ struct bfd_link_info *info;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+ void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
+ = input_swap->swap_sym_in;
+ void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
+ = input_swap->swap_rfd_in;
+ void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
+ = output_swap->swap_sym_out;
+ void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
+ = output_swap->swap_fdr_out;
+ void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR))
+ = output_swap->swap_rfd_out;
+ bfd_size_type external_pdr_size = output_swap->external_pdr_size;
+ bfd_size_type external_sym_size = output_swap->external_sym_size;
+ bfd_size_type external_opt_size = output_swap->external_opt_size;
+ bfd_size_type external_fdr_size = output_swap->external_fdr_size;
+ bfd_size_type external_rfd_size = output_swap->external_rfd_size;
+ HDRR * const output_symhdr = &output_debug->symbolic_header;
+ HDRR * const input_symhdr = &input_debug->symbolic_header;
+ bfd_vma section_adjust[scMax];
+ asection *sec;
+ bfd_byte *fdr_start;
+ bfd_byte *fdr_ptr;
+ bfd_byte *fdr_end;
+ bfd_size_type fdr_add;
+ unsigned int copied;
+ RFDT i;
+ unsigned long sz;
+ bfd_byte *rfd_out;
+ bfd_byte *rfd_in;
+ bfd_byte *rfd_end;
+ long newrfdbase = 0;
+ long oldrfdbase = 0;
+ bfd_byte *fdr_out;
+
+ /* Use section_adjust to hold the value to add to a symbol in a
+ particular section. */
+ memset ((PTR) section_adjust, 0, sizeof section_adjust);
+
+#define SET(name, indx) \
+ sec = bfd_get_section_by_name (input_bfd, name); \
+ if (sec != NULL) \
+ section_adjust[indx] = (sec->output_section->vma \
+ + sec->output_offset \
+ - sec->vma);
+
+ SET (".text", scText);
+ SET (".data", scData);
+ SET (".bss", scBss);
+ SET (".sdata", scSData);
+ SET (".sbss", scSBss);
+ /* scRdata section may be either .rdata or .rodata. */
+ SET (".rdata", scRData);
+ SET (".rodata", scRData);
+ SET (".init", scInit);
+ SET (".fini", scFini);
+ SET (".rconst", scRConst);
+
+#undef SET
+
+ /* Find all the debugging information based on the FDR's. We need
+ to handle them whether they are swapped or not. */
+ if (input_debug->fdr != (FDR *) NULL)
+ {
+ fdr_start = (bfd_byte *) input_debug->fdr;
+ fdr_add = sizeof (FDR);
+ }
+ else
+ {
+ fdr_start = (bfd_byte *) input_debug->external_fdr;
+ fdr_add = input_swap->external_fdr_size;
+ }
+ fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
+
+ input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd,
+ (input_symhdr->ifdMax
+ * sizeof (RFDT)));
+
+ sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
+ rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
+ if (!input_debug->ifdmap || !rfd_out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
+ return false;
+
+ copied = 0;
+
+ /* Look through the FDR's to see which ones we are going to include
+ in the final output. We do not want duplicate FDR information
+ for header files, because ECOFF debugging is often very large.
+ When we find an FDR with no line information which can be merged,
+ we look it up in a hash table to ensure that we only include it
+ once. We keep a table mapping FDR numbers to the final number
+ they get with the BFD, so that we can refer to it when we write
+ out the external symbols. */
+ for (fdr_ptr = fdr_start, i = 0;
+ fdr_ptr < fdr_end;
+ fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
+ {
+ FDR fdr;
+
+ if (input_debug->fdr != (FDR *) NULL)
+ fdr = *(FDR *) fdr_ptr;
+ else
+ (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
+
+ /* See if this FDR can be merged with an existing one. */
+ if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
+ {
+ const char *name;
+ char *lookup;
+ struct string_hash_entry *fh;
+
+ /* We look up a string formed from the file name and the
+ number of symbols and aux entries. Sometimes an include
+ file will conditionally define a typedef or something
+ based on the order of include files. Using the number of
+ symbols and aux entries as a hash reduces the chance that
+ we will merge symbol information that should not be
+ merged. */
+ name = input_debug->ss + fdr.issBase + fdr.rss;
+
+ lookup = (char *) bfd_malloc (strlen (name) + 20);
+ if (lookup == NULL)
+ return false;
+ sprintf (lookup, "%s %lx %lx", name, fdr.csym, fdr.caux);
+
+ fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true);
+ free (lookup);
+ if (fh == (struct string_hash_entry *) NULL)
+ return false;
+
+ if (fh->val != -1)
+ {
+ input_debug->ifdmap[i] = fh->val;
+ (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i,
+ (PTR) rfd_out);
+
+ /* Don't copy this FDR. */
+ continue;
+ }
+
+ fh->val = output_symhdr->ifdMax + copied;
+ }
+
+ input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
+ (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out);
+ ++copied;
+ }
+
+ newrfdbase = output_symhdr->crfd;
+ output_symhdr->crfd += input_symhdr->ifdMax;
+
+ /* Copy over any existing RFD's. RFD's are only created by the
+ linker, so this will only happen for input files which are the
+ result of a partial link. */
+ rfd_in = (bfd_byte *) input_debug->external_rfd;
+ rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
+ for (;
+ rfd_in < rfd_end;
+ rfd_in += input_swap->external_rfd_size)
+ {
+ RFDT rfd;
+
+ (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd);
+ BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
+ rfd = input_debug->ifdmap[rfd];
+ (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out);
+ rfd_out += external_rfd_size;
+ }
+
+ oldrfdbase = output_symhdr->crfd;
+ output_symhdr->crfd += input_symhdr->crfd;
+
+ /* Look through the FDR's and copy over all associated debugging
+ information. */
+ sz = copied * external_fdr_size;
+ fdr_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
+ if (!fdr_out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
+ return false;
+ for (fdr_ptr = fdr_start, i = 0;
+ fdr_ptr < fdr_end;
+ fdr_ptr += fdr_add, i++)
+ {
+ FDR fdr;
+ bfd_vma fdr_adr;
+ bfd_byte *sym_out;
+ bfd_byte *lraw_src;
+ bfd_byte *lraw_end;
+ boolean fgotfilename;
+
+ if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
+ {
+ /* We are not copying this FDR. */
+ continue;
+ }
+
+ if (input_debug->fdr != (FDR *) NULL)
+ fdr = *(FDR *) fdr_ptr;
+ else
+ (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
+
+ fdr_adr = fdr.adr;
+
+ /* Adjust the FDR address for any changes that may have been
+ made by relaxing. */
+ if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
+ {
+ struct ecoff_value_adjust *adjust;
+
+ for (adjust = input_debug->adjust;
+ adjust != (struct ecoff_value_adjust *) NULL;
+ adjust = adjust->next)
+ if (fdr_adr >= adjust->start
+ && fdr_adr < adjust->end)
+ fdr.adr += adjust->adjust;
+ }
+
+ /* FIXME: It is conceivable that this FDR points to the .init or
+ .fini section, in which case this will not do the right
+ thing. */
+ fdr.adr += section_adjust[scText];
+
+ /* Swap in the local symbols, adjust their values, and swap them
+ out again. */
+ fgotfilename = false;
+ sz = fdr.csym * external_sym_size;
+ sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
+ if (!sym_out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
+ sz))
+ return false;
+ lraw_src = ((bfd_byte *) input_debug->external_sym
+ + fdr.isymBase * input_swap->external_sym_size);
+ lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
+ for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size)
+ {
+ SYMR internal_sym;
+
+ (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym);
+
+ BFD_ASSERT (internal_sym.sc != scCommon
+ && internal_sym.sc != scSCommon);
+
+ /* Adjust the symbol value if appropriate. */
+ switch (internal_sym.st)
+ {
+ case stNil:
+ if (ECOFF_IS_STAB (&internal_sym))
+ break;
+ /* Fall through. */
+ case stGlobal:
+ case stStatic:
+ case stLabel:
+ case stProc:
+ case stStaticProc:
+ if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
+ {
+ bfd_vma value;
+ struct ecoff_value_adjust *adjust;
+
+ value = internal_sym.value;
+ for (adjust = input_debug->adjust;
+ adjust != (struct ecoff_value_adjust *) NULL;
+ adjust = adjust->next)
+ if (value >= adjust->start
+ && value < adjust->end)
+ internal_sym.value += adjust->adjust;
+ }
+ internal_sym.value += section_adjust[internal_sym.sc];
+ break;
+
+ default:
+ break;
+ }
+
+ /* If we are doing a final link, we hash all the strings in
+ the local symbol table together. This reduces the amount
+ of space required by debugging information. We don't do
+ this when performing a relocateable link because it would
+ prevent us from easily merging different FDR's. */
+ if (! info->relocateable)
+ {
+ boolean ffilename;
+ const char *name;
+
+ if (! fgotfilename && internal_sym.iss == fdr.rss)
+ ffilename = true;
+ else
+ ffilename = false;
+
+ /* Hash the name into the string table. */
+ name = input_debug->ss + fdr.issBase + internal_sym.iss;
+ if (*name == '\0')
+ internal_sym.iss = 0;
+ else
+ {
+ struct string_hash_entry *sh;
+
+ sh = string_hash_lookup (&ainfo->str_hash, name, true, true);
+ if (sh == (struct string_hash_entry *) NULL)
+ return false;
+ if (sh->val == -1)
+ {
+ sh->val = output_symhdr->issMax;
+ output_symhdr->issMax += strlen (name) + 1;
+ if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
+ ainfo->ss_hash = sh;
+ if (ainfo->ss_hash_end
+ != (struct string_hash_entry *) NULL)
+ ainfo->ss_hash_end->next = sh;
+ ainfo->ss_hash_end = sh;
+ }
+ internal_sym.iss = sh->val;
+ }
+
+ if (ffilename)
+ {
+ fdr.rss = internal_sym.iss;
+ fgotfilename = true;
+ }
+ }
+
+ (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
+ sym_out += external_sym_size;
+ }
+
+ fdr.isymBase = output_symhdr->isymMax;
+ output_symhdr->isymMax += fdr.csym;
+
+ /* Copy the information that does not need swapping. */
+
+ /* FIXME: If we are relaxing, we need to adjust the line
+ numbers. Frankly, forget it. Anybody using stabs debugging
+ information will not use this line number information, and
+ stabs are adjusted correctly. */
+ if (fdr.cbLine > 0)
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
+ input_bfd,
+ input_symhdr->cbLineOffset + fdr.cbLineOffset,
+ fdr.cbLine))
+ return false;
+ fdr.ilineBase = output_symhdr->ilineMax;
+ fdr.cbLineOffset = output_symhdr->cbLine;
+ output_symhdr->ilineMax += fdr.cline;
+ output_symhdr->cbLine += fdr.cbLine;
+ }
+ if (fdr.caux > 0)
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
+ input_bfd,
+ (input_symhdr->cbAuxOffset
+ + fdr.iauxBase * sizeof (union aux_ext)),
+ fdr.caux * sizeof (union aux_ext)))
+ return false;
+ fdr.iauxBase = output_symhdr->iauxMax;
+ output_symhdr->iauxMax += fdr.caux;
+ }
+ if (! info->relocateable)
+ {
+
+ /* When are are hashing strings, we lie about the number of
+ strings attached to each FDR. We need to set cbSs
+ because some versions of dbx apparently use it to decide
+ how much of the string table to read in. */
+ fdr.issBase = 0;
+ fdr.cbSs = output_symhdr->issMax;
+ }
+ else if (fdr.cbSs > 0)
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
+ input_bfd,
+ input_symhdr->cbSsOffset + fdr.issBase,
+ fdr.cbSs))
+ return false;
+ fdr.issBase = output_symhdr->issMax;
+ output_symhdr->issMax += fdr.cbSs;
+ }
+
+ if ((output_bfd->xvec->header_byteorder
+ == input_bfd->xvec->header_byteorder)
+ && input_debug->adjust == (struct ecoff_value_adjust *) NULL)
+ {
+ /* The two BFD's have the same endianness, and we don't have
+ to adjust the PDR addresses, so simply copying the
+ information will suffice. */
+ BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
+ if (fdr.cpd > 0)
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
+ input_bfd,
+ (input_symhdr->cbPdOffset
+ + fdr.ipdFirst * external_pdr_size),
+ fdr.cpd * external_pdr_size))
+ return false;
+ }
+ BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
+ if (fdr.copt > 0)
+ {
+ if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
+ input_bfd,
+ (input_symhdr->cbOptOffset
+ + fdr.ioptBase * external_opt_size),
+ fdr.copt * external_opt_size))
+ return false;
+ }
+ }
+ else
+ {
+ bfd_size_type outsz, insz;
+ bfd_byte *in;
+ bfd_byte *end;
+ bfd_byte *out;
+
+ /* The two BFD's have different endianness, so we must swap
+ everything in and out. This code would always work, but
+ it would be unnecessarily slow in the normal case. */
+ outsz = external_pdr_size;
+ insz = input_swap->external_pdr_size;
+ in = ((bfd_byte *) input_debug->external_pdr
+ + fdr.ipdFirst * insz);
+ end = in + fdr.cpd * insz;
+ sz = fdr.cpd * outsz;
+ out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
+ if (!out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
+ sz))
+ return false;
+ for (; in < end; in += insz, out += outsz)
+ {
+ PDR pdr;
+
+ (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
+
+ /* If we have been relaxing, we may have to adjust the
+ address. */
+ if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
+ {
+ bfd_vma adr;
+ struct ecoff_value_adjust *adjust;
+
+ adr = fdr_adr + pdr.adr;
+ for (adjust = input_debug->adjust;
+ adjust != (struct ecoff_value_adjust *) NULL;
+ adjust = adjust->next)
+ if (adr >= adjust->start
+ && adr < adjust->end)
+ pdr.adr += adjust->adjust;
+ }
+
+ (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
+ }
+
+ /* Swap over the optimization information. */
+ outsz = external_opt_size;
+ insz = input_swap->external_opt_size;
+ in = ((bfd_byte *) input_debug->external_opt
+ + fdr.ioptBase * insz);
+ end = in + fdr.copt * insz;
+ sz = fdr.copt * outsz;
+ out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
+ if (!out)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
+ sz))
+ return false;
+ for (; in < end; in += insz, out += outsz)
+ {
+ OPTR opt;
+
+ (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt);
+ (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out);
+ }
+ }
+
+ fdr.ipdFirst = output_symhdr->ipdMax;
+ output_symhdr->ipdMax += fdr.cpd;
+ fdr.ioptBase = output_symhdr->ioptMax;
+ output_symhdr->ioptMax += fdr.copt;
+
+ if (fdr.crfd <= 0)
+ {
+ /* Point this FDR at the table of RFD's we created. */
+ fdr.rfdBase = newrfdbase;
+ fdr.crfd = input_symhdr->ifdMax;
+ }
+ else
+ {
+ /* Point this FDR at the remapped RFD's. */
+ fdr.rfdBase += oldrfdbase;
+ }
+
+ (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
+ fdr_out += external_fdr_size;
+ ++output_symhdr->ifdMax;
+ }
+
+ return true;
+}
+
+/* Add a string to the debugging information we are accumulating.
+ Return the offset from the fdr string base. */
+
+static long ecoff_add_string PARAMS ((struct accumulate *,
+ struct bfd_link_info *,
+ struct ecoff_debug_info *,
+ FDR *fdr, const char *string));
+
+static long
+ecoff_add_string (ainfo, info, debug, fdr, string)
+ struct accumulate *ainfo;
+ struct bfd_link_info *info;
+ struct ecoff_debug_info *debug;
+ FDR *fdr;
+ const char *string;
+{
+ HDRR *symhdr;
+ size_t len;
+ bfd_size_type ret;
+
+ symhdr = &debug->symbolic_header;
+ len = strlen (string);
+ if (info->relocateable)
+ {
+ if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
+ len + 1))
+ return -1;
+ ret = symhdr->issMax;
+ symhdr->issMax += len + 1;
+ fdr->cbSs += len + 1;
+ }
+ else
+ {
+ struct string_hash_entry *sh;
+
+ sh = string_hash_lookup (&ainfo->str_hash, string, true, true);
+ if (sh == (struct string_hash_entry *) NULL)
+ return -1;
+ if (sh->val == -1)
+ {
+ sh->val = symhdr->issMax;
+ symhdr->issMax += len + 1;
+ if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
+ ainfo->ss_hash = sh;
+ if (ainfo->ss_hash_end
+ != (struct string_hash_entry *) NULL)
+ ainfo->ss_hash_end->next = sh;
+ ainfo->ss_hash_end = sh;
+ }
+ ret = sh->val;
+ }
+
+ return ret;
+}
+
+/* Add debugging information from a non-ECOFF file. */
+
+boolean
+bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
+ output_swap, input_bfd, info)
+ PTR handle;
+ bfd *output_bfd;
+ struct ecoff_debug_info *output_debug;
+ const struct ecoff_debug_swap *output_swap;
+ bfd *input_bfd;
+ struct bfd_link_info *info;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+ void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
+ = output_swap->swap_sym_out;
+ HDRR *output_symhdr = &output_debug->symbolic_header;
+ FDR fdr;
+ asection *sec;
+ asymbol **symbols;
+ asymbol **sym_ptr;
+ asymbol **sym_end;
+ long symsize;
+ long symcount;
+ PTR external_fdr;
+
+ memset ((PTR) &fdr, 0, sizeof fdr);
+
+ sec = bfd_get_section_by_name (input_bfd, ".text");
+ if (sec != NULL)
+ fdr.adr = sec->output_section->vma + sec->output_offset;
+ else
+ {
+ /* FIXME: What about .init or .fini? */
+ fdr.adr = 0;
+ }
+
+ fdr.issBase = output_symhdr->issMax;
+ fdr.cbSs = 0;
+ fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
+ bfd_get_filename (input_bfd));
+ if (fdr.rss == -1)
+ return false;
+ fdr.isymBase = output_symhdr->isymMax;
+
+ /* Get the local symbols from the input BFD. */
+ symsize = bfd_get_symtab_upper_bound (input_bfd);
+ if (symsize < 0)
+ return false;
+ symbols = (asymbol **) bfd_alloc (output_bfd, symsize);
+ if (symbols == (asymbol **) NULL)
+ return false;
+ symcount = bfd_canonicalize_symtab (input_bfd, symbols);
+ if (symcount < 0)
+ return false;
+ sym_end = symbols + symcount;
+
+ /* Handle the local symbols. Any external symbols are handled
+ separately. */
+ fdr.csym = 0;
+ for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
+ {
+ SYMR internal_sym;
+ PTR external_sym;
+
+ if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
+ continue;
+ memset ((PTR) &internal_sym, 0, sizeof internal_sym);
+ internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
+ (*sym_ptr)->name);
+
+ if (internal_sym.iss == -1)
+ return false;
+ if (bfd_is_com_section ((*sym_ptr)->section)
+ || bfd_is_und_section ((*sym_ptr)->section))
+ internal_sym.value = (*sym_ptr)->value;
+ else
+ internal_sym.value = ((*sym_ptr)->value
+ + (*sym_ptr)->section->output_offset
+ + (*sym_ptr)->section->output_section->vma);
+ internal_sym.st = stNil;
+ internal_sym.sc = scUndefined;
+ internal_sym.index = indexNil;
+
+ external_sym = (PTR) objalloc_alloc (ainfo->memory,
+ output_swap->external_sym_size);
+ if (!external_sym)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
+ add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
+ external_sym, output_swap->external_sym_size);
+ ++fdr.csym;
+ ++output_symhdr->isymMax;
+ }
+
+ bfd_release (output_bfd, (PTR) symbols);
+
+ /* Leave everything else in the FDR zeroed out. This will cause
+ the lang field to be langC. The fBigendian field will
+ indicate little endian format, but it doesn't matter because
+ it only applies to aux fields and there are none. */
+ external_fdr = (PTR) objalloc_alloc (ainfo->memory,
+ output_swap->external_fdr_size);
+ if (!external_fdr)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
+ add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
+ external_fdr, output_swap->external_fdr_size);
+
+ ++output_symhdr->ifdMax;
+
+ return true;
+}
+
+/* Set up ECOFF debugging information for the external symbols.
+ FIXME: This is done using a memory buffer, but it should be
+ probably be changed to use a shuffle structure. The assembler uses
+ this interface, so that must be changed to do something else. */
+
+boolean
+bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
+ set_index)
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ boolean relocateable;
+ boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
+ void (*set_index) PARAMS ((asymbol *, bfd_size_type));
+{
+ HDRR * const symhdr = &debug->symbolic_header;
+ asymbol **sym_ptr_ptr;
+ size_t c;
+
+ sym_ptr_ptr = bfd_get_outsymbols (abfd);
+ if (sym_ptr_ptr == NULL)
+ return true;
+
+ for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
+ {
+ asymbol *sym_ptr;
+ EXTR esym;
+
+ sym_ptr = *sym_ptr_ptr;
+
+ /* Get the external symbol information. */
+ if ((*get_extr) (sym_ptr, &esym) == false)
+ continue;
+
+ /* If we're producing an executable, move common symbols into
+ bss. */
+ if (relocateable == false)
+ {
+ if (esym.asym.sc == scCommon)
+ esym.asym.sc = scBss;
+ else if (esym.asym.sc == scSCommon)
+ esym.asym.sc = scSBss;
+ }
+
+ if (bfd_is_com_section (sym_ptr->section)
+ || bfd_is_und_section (sym_ptr->section)
+ || sym_ptr->section->output_section == (asection *) NULL)
+ {
+ /* FIXME: gas does not keep the value of a small undefined
+ symbol in the symbol itself, because of relocation
+ problems. */
+ if (esym.asym.sc != scSUndefined
+ || esym.asym.value == 0
+ || sym_ptr->value != 0)
+ esym.asym.value = sym_ptr->value;
+ }
+ else
+ esym.asym.value = (sym_ptr->value
+ + sym_ptr->section->output_offset
+ + sym_ptr->section->output_section->vma);
+
+ if (set_index)
+ (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
+
+ if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
+ sym_ptr->name, &esym))
+ return false;
+ }
+
+ return true;
+}
+
+/* Add a single external symbol to the debugging information. */
+
+boolean
+bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ const char *name;
+ EXTR *esym;
+{
+ const bfd_size_type external_ext_size = swap->external_ext_size;
+ void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
+ = swap->swap_ext_out;
+ HDRR * const symhdr = &debug->symbolic_header;
+ size_t namelen;
+
+ namelen = strlen (name);
+
+ if ((size_t) (debug->ssext_end - debug->ssext)
+ < symhdr->issExtMax + namelen + 1)
+ {
+ if (ecoff_add_bytes ((char **) &debug->ssext,
+ (char **) &debug->ssext_end,
+ symhdr->issExtMax + namelen + 1)
+ == false)
+ return false;
+ }
+ if ((size_t) ((char *) debug->external_ext_end
+ - (char *) debug->external_ext)
+ < (symhdr->iextMax + 1) * external_ext_size)
+ {
+ if (ecoff_add_bytes ((char **) &debug->external_ext,
+ (char **) &debug->external_ext_end,
+ (symhdr->iextMax + 1) * external_ext_size)
+ == false)
+ return false;
+ }
+
+ esym->asym.iss = symhdr->issExtMax;
+
+ (*swap_ext_out) (abfd, esym,
+ ((char *) debug->external_ext
+ + symhdr->iextMax * swap->external_ext_size));
+
+ ++symhdr->iextMax;
+
+ strcpy (debug->ssext + symhdr->issExtMax, name);
+ symhdr->issExtMax += namelen + 1;
+
+ return true;
+}
+
+/* Align the ECOFF debugging information. */
+
+/*ARGSUSED*/
+static void
+ecoff_align_debug (abfd, debug, swap)
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+{
+ HDRR * const symhdr = &debug->symbolic_header;
+ bfd_size_type debug_align, aux_align, rfd_align;
+ size_t add;
+
+ /* Adjust the counts so that structures are aligned. */
+ debug_align = swap->debug_align;
+ aux_align = debug_align / sizeof (union aux_ext);
+ rfd_align = debug_align / swap->external_rfd_size;
+
+ add = debug_align - (symhdr->cbLine & (debug_align - 1));
+ if (add != debug_align)
+ {
+ if (debug->line != (unsigned char *) NULL)
+ memset ((PTR) (debug->line + symhdr->cbLine), 0, add);
+ symhdr->cbLine += add;
+ }
+
+ add = debug_align - (symhdr->issMax & (debug_align - 1));
+ if (add != debug_align)
+ {
+ if (debug->ss != (char *) NULL)
+ memset ((PTR) (debug->ss + symhdr->issMax), 0, add);
+ symhdr->issMax += add;
+ }
+
+ add = debug_align - (symhdr->issExtMax & (debug_align - 1));
+ if (add != debug_align)
+ {
+ if (debug->ssext != (char *) NULL)
+ memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add);
+ symhdr->issExtMax += add;
+ }
+
+ add = aux_align - (symhdr->iauxMax & (aux_align - 1));
+ if (add != aux_align)
+ {
+ if (debug->external_aux != (union aux_ext *) NULL)
+ memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0,
+ add * sizeof (union aux_ext));
+ symhdr->iauxMax += add;
+ }
+
+ add = rfd_align - (symhdr->crfd & (rfd_align - 1));
+ if (add != rfd_align)
+ {
+ if (debug->external_rfd != (PTR) NULL)
+ memset ((PTR) ((char *) debug->external_rfd
+ + symhdr->crfd * swap->external_rfd_size),
+ 0, (size_t) (add * swap->external_rfd_size));
+ symhdr->crfd += add;
+ }
+}
+
+/* Return the size required by the ECOFF debugging information. */
+
+bfd_size_type
+bfd_ecoff_debug_size (abfd, debug, swap)
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+{
+ bfd_size_type tot;
+
+ ecoff_align_debug (abfd, debug, swap);
+ tot = swap->external_hdr_size;
+
+#define ADD(count, size) \
+ tot += debug->symbolic_header.count * size
+
+ ADD (cbLine, sizeof (unsigned char));
+ ADD (idnMax, swap->external_dnr_size);
+ ADD (ipdMax, swap->external_pdr_size);
+ ADD (isymMax, swap->external_sym_size);
+ ADD (ioptMax, swap->external_opt_size);
+ ADD (iauxMax, sizeof (union aux_ext));
+ ADD (issMax, sizeof (char));
+ ADD (issExtMax, sizeof (char));
+ ADD (ifdMax, swap->external_fdr_size);
+ ADD (crfd, swap->external_rfd_size);
+ ADD (iextMax, swap->external_ext_size);
+
+#undef ADD
+
+ return tot;
+}
+
+/* Write out the ECOFF symbolic header, given the file position it is
+ going to be placed at. This assumes that the counts are set
+ correctly. */
+
+static boolean
+ecoff_write_symhdr (abfd, debug, swap, where)
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ file_ptr where;
+{
+ HDRR * const symhdr = &debug->symbolic_header;
+ char *buff = NULL;
+
+ ecoff_align_debug (abfd, debug, swap);
+
+ /* Go to the right location in the file. */
+ if (bfd_seek (abfd, where, SEEK_SET) != 0)
+ return false;
+
+ where += swap->external_hdr_size;
+
+ symhdr->magic = swap->sym_magic;
+
+ /* Fill in the file offsets. */
+#define SET(offset, count, size) \
+ if (symhdr->count == 0) \
+ symhdr->offset = 0; \
+ else \
+ { \
+ symhdr->offset = where; \
+ where += symhdr->count * size; \
+ }
+
+ SET (cbLineOffset, cbLine, sizeof (unsigned char));
+ SET (cbDnOffset, idnMax, swap->external_dnr_size);
+ SET (cbPdOffset, ipdMax, swap->external_pdr_size);
+ SET (cbSymOffset, isymMax, swap->external_sym_size);
+ SET (cbOptOffset, ioptMax, swap->external_opt_size);
+ SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
+ SET (cbSsOffset, issMax, sizeof (char));
+ SET (cbSsExtOffset, issExtMax, sizeof (char));
+ SET (cbFdOffset, ifdMax, swap->external_fdr_size);
+ SET (cbRfdOffset, crfd, swap->external_rfd_size);
+ SET (cbExtOffset, iextMax, swap->external_ext_size);
+#undef SET
+
+ buff = (PTR) bfd_malloc ((size_t) swap->external_hdr_size);
+ if (buff == NULL && swap->external_hdr_size != 0)
+ goto error_return;
+
+ (*swap->swap_hdr_out) (abfd, symhdr, buff);
+ if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
+ != swap->external_hdr_size)
+ goto error_return;
+
+ if (buff != NULL)
+ free (buff);
+ return true;
+ error_return:
+ if (buff != NULL)
+ free (buff);
+ return false;
+}
+
+/* Write out the ECOFF debugging information. This function assumes
+ that the information (the pointers and counts) in *DEBUG have been
+ set correctly. WHERE is the position in the file to write the
+ information to. This function fills in the file offsets in the
+ symbolic header. */
+
+boolean
+bfd_ecoff_write_debug (abfd, debug, swap, where)
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ file_ptr where;
+{
+ HDRR * const symhdr = &debug->symbolic_header;
+
+ if (! ecoff_write_symhdr (abfd, debug, swap, where))
+ return false;
+
+#define WRITE(ptr, count, size, offset) \
+ BFD_ASSERT (symhdr->offset == 0 \
+ || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
+ if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
+ != size * symhdr->count) \
+ return false;
+
+ WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
+ WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
+ WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
+ WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
+ WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
+ WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
+ WRITE (ss, issMax, sizeof (char), cbSsOffset);
+ WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
+ WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
+ WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
+ WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
+#undef WRITE
+
+ return true;
+}
+
+/* Write out a shuffle list. */
+
+static boolean ecoff_write_shuffle PARAMS ((bfd *,
+ const struct ecoff_debug_swap *,
+ struct shuffle *, PTR space));
+
+static boolean
+ecoff_write_shuffle (abfd, swap, shuffle, space)
+ bfd *abfd;
+ const struct ecoff_debug_swap *swap;
+ struct shuffle *shuffle;
+ PTR space;
+{
+ register struct shuffle *l;
+ unsigned long total;
+
+ total = 0;
+ for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
+ {
+ if (! l->filep)
+ {
+ if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)
+ return false;
+ }
+ else
+ {
+ if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
+ || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size
+ || bfd_write (space, 1, l->size, abfd) != l->size)
+ return false;
+ }
+ total += l->size;
+ }
+
+ if ((total & (swap->debug_align - 1)) != 0)
+ {
+ unsigned int i;
+ bfd_byte *s;
+
+ i = swap->debug_align - (total & (swap->debug_align - 1));
+ s = (bfd_byte *) bfd_malloc (i);
+ if (s == NULL && i != 0)
+ return false;
+
+ memset ((PTR) s, 0, i);
+ if (bfd_write ((PTR) s, 1, i, abfd) != i)
+ {
+ free (s);
+ return false;
+ }
+ free (s);
+ }
+
+ return true;
+}
+
+/* Write out debugging information using accumulated linker
+ information. */
+
+boolean
+bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
+ PTR handle;
+ bfd *abfd;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ struct bfd_link_info *info;
+ file_ptr where;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+ PTR space = NULL;
+
+ if (! ecoff_write_symhdr (abfd, debug, swap, where))
+ goto error_return;
+
+ space = (PTR) bfd_malloc (ainfo->largest_file_shuffle);
+ if (space == NULL && ainfo->largest_file_shuffle != 0)
+ goto error_return;
+
+ if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
+ || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
+ || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
+ || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
+ || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
+ goto error_return;
+
+ /* The string table is written out from the hash table if this is a
+ final link. */
+ if (info->relocateable)
+ {
+ BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
+ if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
+ goto error_return;
+ }
+ else
+ {
+ unsigned long total;
+ bfd_byte null;
+ struct string_hash_entry *sh;
+
+ BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
+ null = 0;
+ if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
+ goto error_return;
+ total = 1;
+ BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
+ for (sh = ainfo->ss_hash;
+ sh != (struct string_hash_entry *) NULL;
+ sh = sh->next)
+ {
+ size_t len;
+
+ len = strlen (sh->root.string);
+ if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
+ goto error_return;
+ total += len + 1;
+ }
+
+ if ((total & (swap->debug_align - 1)) != 0)
+ {
+ unsigned int i;
+ bfd_byte *s;
+
+ i = swap->debug_align - (total & (swap->debug_align - 1));
+ s = (bfd_byte *) bfd_malloc (i);
+ if (s == NULL && i != 0)
+ goto error_return;
+ memset ((PTR) s, 0, i);
+ if (bfd_write ((PTR) s, 1, i, abfd) != i)
+ {
+ free (s);
+ goto error_return;
+ }
+ free (s);
+ }
+ }
+
+ /* The external strings and symbol are not converted over to using
+ shuffles. FIXME: They probably should be. */
+ if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
+ != (bfd_size_type) debug->symbolic_header.issExtMax)
+ goto error_return;
+ if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
+ {
+ unsigned int i;
+ bfd_byte *s;
+
+ i = (swap->debug_align
+ - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
+ s = (bfd_byte *) bfd_malloc (i);
+ if (s == NULL && i != 0)
+ goto error_return;
+ memset ((PTR) s, 0, i);
+ if (bfd_write ((PTR) s, 1, i, abfd) != i)
+ {
+ free (s);
+ goto error_return;
+ }
+ free (s);
+ }
+
+ if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
+ || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
+ goto error_return;
+
+ BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
+ || (debug->symbolic_header.cbExtOffset
+ == (bfd_vma) bfd_tell (abfd)));
+
+ if (bfd_write (debug->external_ext, swap->external_ext_size,
+ debug->symbolic_header.iextMax, abfd)
+ != debug->symbolic_header.iextMax * swap->external_ext_size)
+ goto error_return;
+
+ if (space != NULL)
+ free (space);
+ return true;
+
+ error_return:
+ if (space != NULL)
+ free (space);
+ return false;
+}
+
+/* Handle the find_nearest_line function for both ECOFF and MIPS ELF
+ files. */
+
+/* Compare FDR entries. This is called via qsort. */
+
+static int
+cmp_fdrtab_entry (leftp, rightp)
+ const PTR leftp;
+ const PTR rightp;
+{
+ const struct ecoff_fdrtab_entry *lp =
+ (const struct ecoff_fdrtab_entry *) leftp;
+ const struct ecoff_fdrtab_entry *rp =
+ (const struct ecoff_fdrtab_entry *) rightp;
+
+ if (lp->base_addr < rp->base_addr)
+ return -1;
+ if (lp->base_addr > rp->base_addr)
+ return 1;
+ return 0;
+}
+
+/* Each file descriptor (FDR) has a memory address, to simplify
+ looking up an FDR by address, we build a table covering all FDRs
+ that have a least one procedure descriptor in them. The final
+ table will be sorted by address so we can look it up via binary
+ search. */
+
+static boolean
+mk_fdrtab (abfd, debug_info, debug_swap, line_info)
+ bfd *abfd;
+ struct ecoff_debug_info * const debug_info;
+ const struct ecoff_debug_swap * const debug_swap;
+ struct ecoff_find_line *line_info;
+{
+ struct ecoff_fdrtab_entry *tab;
+ FDR *fdr_ptr;
+ FDR *fdr_start;
+ FDR *fdr_end;
+ boolean stabs;
+ long len;
+
+ fdr_start = debug_info->fdr;
+ fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
+
+ /* First, let's see how long the table needs to be: */
+ for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
+ {
+ if (fdr_ptr->cpd == 0) /* skip FDRs that have no PDRs */
+ continue;
+ ++len;
+ }
+
+ /* Now, create and fill in the table: */
+
+ line_info->fdrtab = ((struct ecoff_fdrtab_entry*)
+ bfd_zalloc (abfd,
+ len * sizeof (struct ecoff_fdrtab_entry)));
+ if (line_info->fdrtab == NULL)
+ return false;
+ line_info->fdrtab_len = len;
+
+ tab = line_info->fdrtab;
+ for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
+ {
+ if (fdr_ptr->cpd == 0)
+ continue;
+
+ /* Check whether this file has stabs debugging information. In
+ a file with stabs debugging information, the second local
+ symbol is named @stabs. */
+ stabs = false;
+ if (fdr_ptr->csym >= 2)
+ {
+ char *sym_ptr;
+ SYMR sym;
+
+ sym_ptr = ((char *) debug_info->external_sym
+ + (fdr_ptr->isymBase + 1)*debug_swap->external_sym_size);
+ (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
+ if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
+ STABS_SYMBOL) == 0)
+ stabs = true;
+ }
+
+ if (!stabs)
+ {
+ bfd_size_type external_pdr_size;
+ char *pdr_ptr;
+ PDR pdr;
+
+ external_pdr_size = debug_swap->external_pdr_size;
+
+ pdr_ptr = ((char *) debug_info->external_pdr
+ + fdr_ptr->ipdFirst * external_pdr_size);
+ (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
+ /* The address of the first PDR is the offset of that
+ procedure relative to the beginning of file FDR. */
+ tab->base_addr = fdr_ptr->adr - pdr.adr;
+ }
+ else
+ {
+ /* XXX I don't know about stabs, so this is a guess
+ (davidm@cs.arizona.edu): */
+ tab->base_addr = fdr_ptr->adr;
+ }
+ tab->fdr = fdr_ptr;
+ ++tab;
+ }
+
+ /* Finally, the table is sorted in increasing memory-address order.
+ The table is mostly sorted already, but there are cases (e.g.,
+ static functions in include files), where this does not hold.
+ Use "odump -PFv" to verify... */
+ qsort ((PTR) line_info->fdrtab, len,
+ sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
+
+ return true;
+}
+
+/* Return index of first FDR that covers to OFFSET. */
+
+static long
+fdrtab_lookup (line_info, offset)
+ struct ecoff_find_line *line_info;
+ bfd_vma offset;
+{
+ long low, high, len;
+ long mid = -1;
+ struct ecoff_fdrtab_entry *tab;
+
+ len = line_info->fdrtab_len;
+ if (len == 0)
+ return -1;
+
+ tab = line_info->fdrtab;
+ for (low = 0, high = len - 1 ; low != high ;)
+ {
+ mid = (high + low) / 2;
+ if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
+ goto find_min;
+
+ if (tab[mid].base_addr > offset)
+ high = mid;
+ else
+ low = mid + 1;
+ }
+ ++mid;
+
+ /* last entry is catch-all for all higher addresses: */
+ if (offset < tab[mid].base_addr)
+ return -1;
+
+ find_min:
+
+ while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
+ --mid;
+
+ return mid;
+}
+
+/* Look up a line given an address, storing the information in
+ LINE_INFO->cache. */
+
+static boolean
+lookup_line (abfd, debug_info, debug_swap, line_info)
+ bfd *abfd;
+ struct ecoff_debug_info * const debug_info;
+ const struct ecoff_debug_swap * const debug_swap;
+ struct ecoff_find_line *line_info;
+{
+ struct ecoff_fdrtab_entry *tab;
+ bfd_vma offset;
+ boolean stabs;
+ FDR *fdr_ptr;
+ int i;
+
+ offset = line_info->cache.start;
+
+ /* Build FDR table (sorted by object file's base-address) if we
+ don't have it already. */
+ if (line_info->fdrtab == NULL
+ && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
+ return false;
+
+ tab = line_info->fdrtab;
+
+ /* find first FDR for address OFFSET */
+ i = fdrtab_lookup (line_info, offset);
+ if (i < 0)
+ return false; /* no FDR, no fun... */
+ fdr_ptr = tab[i].fdr;
+
+ /* Check whether this file has stabs debugging information. In a
+ file with stabs debugging information, the second local symbol is
+ named @stabs. */
+ stabs = false;
+ if (fdr_ptr->csym >= 2)
+ {
+ char *sym_ptr;
+ SYMR sym;
+
+ sym_ptr = ((char *) debug_info->external_sym
+ + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
+ (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
+ if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
+ STABS_SYMBOL) == 0)
+ stabs = true;
+ }
+
+ if (!stabs)
+ {
+ bfd_size_type external_pdr_size;
+ char *pdr_ptr;
+ char *best_pdr = NULL;
+ FDR *best_fdr;
+ bfd_vma best_dist = ~0;
+ PDR pdr;
+ unsigned char *line_ptr;
+ unsigned char *line_end;
+ int lineno;
+ /* This file uses ECOFF debugging information. Each FDR has a
+ list of procedure descriptors (PDR). The address in the FDR
+ is the absolute address of the first procedure. The address
+ in the first PDR gives the offset of that procedure relative
+ to the object file's base-address. The addresses in
+ subsequent PDRs specify each procedure's address relative to
+ the object file's base-address. To make things more juicy,
+ whenever the PROF bit in the PDR is set, the real entry point
+ of the procedure may be 16 bytes below what would normally be
+ the procedure's entry point. Instead, DEC came up with a
+ wicked scheme to create profiled libraries "on the fly":
+ instead of shipping a regular and a profiled version of each
+ library, they insert 16 bytes of unused space in front of
+ each procedure and set the "prof" bit in the PDR to indicate
+ that there is a gap there (this is done automagically by "as"
+ when option "-pg" is specified). Thus, normally, you link
+ against such a library and, except for lots of 16 byte gaps
+ between functions, things will behave as usual. However,
+ when invoking "ld" with option "-pg", it will fill those gaps
+ with code that calls mcount(). It then moves the function's
+ entry point down by 16 bytes, and out pops a binary that has
+ all functions profiled.
+
+ NOTE: Neither FDRs nor PDRs are strictly sorted in memory
+ order. For example, when including header-files that
+ define functions, the FDRs follow behind the including
+ file, even though their code may have been generated at
+ a lower address. File coff-alpha.c from libbfd
+ illustrates this (use "odump -PFv" to look at a file's
+ FDR/PDR). Similarly, PDRs are sometimes out of order
+ as well. An example of this is OSF/1 v3.0 libc's
+ malloc.c. I'm not sure why this happens, but it could
+ be due to optimizations that reorder a function's
+ position within an object-file.
+
+ Strategy:
+
+ On the first call to this function, we build a table of FDRs
+ that is sorted by the base-address of the object-file the FDR
+ is referring to. Notice that each object-file may contain
+ code from multiple source files (e.g., due to code defined in
+ include files). Thus, for any given base-address, there may
+ be multiple FDRs (but this case is, fortunately, uncommon).
+ lookup(addr) guarantees to return the first FDR that applies
+ to address ADDR. Thus, after invoking lookup(), we have a
+ list of FDRs that may contain the PDR for ADDR. Next, we
+ walk through the PDRs of these FDRs and locate the one that
+ is closest to ADDR (i.e., for which the difference between
+ ADDR and the PDR's entry point is positive and minimal).
+ Once, the right FDR and PDR are located, we simply walk
+ through the line-number table to lookup the line-number that
+ best matches ADDR. Obviously, things could be sped up by
+ keeping a sorted list of PDRs instead of a sorted list of
+ FDRs. However, this would increase space requirements
+ considerably, which is undesirable. */
+ external_pdr_size = debug_swap->external_pdr_size;
+
+ /* Make offset relative to object file's start-address: */
+ offset -= tab[i].base_addr;
+ /* Search FDR list starting at tab[i] for the PDR that best matches
+ OFFSET. Normally, the FDR list is only one entry long. */
+ best_fdr = NULL;
+ do
+ {
+ bfd_vma dist, min_dist = 0;
+ char *pdr_hold;
+ char *pdr_end;
+
+ fdr_ptr = tab[i].fdr;
+
+ pdr_ptr = ((char *) debug_info->external_pdr
+ + fdr_ptr->ipdFirst * external_pdr_size);
+ pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
+ (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
+ /* Find PDR that is closest to OFFSET. If pdr.prof is set,
+ the procedure entry-point *may* be 0x10 below pdr.adr. We
+ simply pretend that pdr.prof *implies* a lower entry-point.
+ This is safe because it just means that may identify 4 NOPs
+ in front of the function as belonging to the function. */
+ for (pdr_hold = NULL;
+ pdr_ptr < pdr_end;
+ (pdr_ptr += external_pdr_size,
+ (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr)))
+ {
+ if (offset >= (pdr.adr - 0x10 * pdr.prof))
+ {
+ dist = offset - (pdr.adr - 0x10 * pdr.prof);
+ if (!pdr_hold || dist < min_dist)
+ {
+ min_dist = dist;
+ pdr_hold = pdr_ptr;
+ }
+ }
+ }
+
+ if (!best_pdr || min_dist < best_dist)
+ {
+ best_dist = min_dist;
+ best_fdr = fdr_ptr;
+ best_pdr = pdr_hold;
+ }
+ /* continue looping until base_addr of next entry is different: */
+ }
+ while (++i < line_info->fdrtab_len
+ && tab[i].base_addr == tab[i - 1].base_addr);
+
+ if (!best_fdr || !best_pdr)
+ return false; /* shouldn't happen... */
+
+ /* phew, finally we got something that we can hold onto: */
+ fdr_ptr = best_fdr;
+ pdr_ptr = best_pdr;
+ (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
+ /* Now we can look for the actual line number. The line numbers
+ are stored in a very funky format, which I won't try to
+ describe. The search is bounded by the end of the FDRs line
+ number entries. */
+ line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
+
+ /* Make offset relative to procedure entry: */
+ offset -= pdr.adr - 0x10 * pdr.prof;
+ lineno = pdr.lnLow;
+ line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
+ while (line_ptr < line_end)
+ {
+ int delta;
+ unsigned int count;
+
+ delta = *line_ptr >> 4;
+ if (delta >= 0x8)
+ delta -= 0x10;
+ count = (*line_ptr & 0xf) + 1;
+ ++line_ptr;
+ if (delta == -8)
+ {
+ delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
+ if (delta >= 0x8000)
+ delta -= 0x10000;
+ line_ptr += 2;
+ }
+ lineno += delta;
+ if (offset < count * 4)
+ {
+ line_info->cache.stop += count * 4 - offset;
+ break;
+ }
+ offset -= count * 4;
+ }
+
+ /* If fdr_ptr->rss is -1, then this file does not have full
+ symbols, at least according to gdb/mipsread.c. */
+ if (fdr_ptr->rss == -1)
+ {
+ line_info->cache.filename = NULL;
+ if (pdr.isym == -1)
+ line_info->cache.functionname = NULL;
+ else
+ {
+ EXTR proc_ext;
+
+ (*debug_swap->swap_ext_in)
+ (abfd,
+ ((char *) debug_info->external_ext
+ + pdr.isym * debug_swap->external_ext_size),
+ &proc_ext);
+ line_info->cache.functionname = (debug_info->ssext
+ + proc_ext.asym.iss);
+ }
+ }
+ else
+ {
+ SYMR proc_sym;
+
+ line_info->cache.filename = (debug_info->ss
+ + fdr_ptr->issBase
+ + fdr_ptr->rss);
+ (*debug_swap->swap_sym_in)
+ (abfd,
+ ((char *) debug_info->external_sym
+ + ((fdr_ptr->isymBase + pdr.isym)
+ * debug_swap->external_sym_size)),
+ &proc_sym);
+ line_info->cache.functionname = (debug_info->ss
+ + fdr_ptr->issBase
+ + proc_sym.iss);
+ }
+ if (lineno == ilineNil)
+ lineno = 0;
+ line_info->cache.line_num = lineno;
+ }
+ else
+ {
+ bfd_size_type external_sym_size;
+ const char *directory_name;
+ const char *main_file_name;
+ const char *current_file_name;
+ const char *function_name;
+ const char *line_file_name;
+ bfd_vma low_func_vma;
+ bfd_vma low_line_vma;
+ boolean past_line;
+ boolean past_fn;
+ char *sym_ptr, *sym_ptr_end;
+ size_t len, funclen;
+ char *buffer = NULL;
+
+ /* This file uses stabs debugging information. When gcc is not
+ optimizing, it will put the line number information before
+ the function name stabs entry. When gcc is optimizing, it
+ will put the stabs entry for all the function first, followed
+ by the line number information. (This appears to happen
+ because of the two output files used by the -mgpopt switch,
+ which is implied by -O). This means that we must keep
+ looking through the symbols until we find both a line number
+ and a function name which are beyond the address we want. */
+
+ line_info->cache.filename = NULL;
+ line_info->cache.functionname = NULL;
+ line_info->cache.line_num = 0;
+
+ directory_name = NULL;
+ main_file_name = NULL;
+ current_file_name = NULL;
+ function_name = NULL;
+ line_file_name = NULL;
+ low_func_vma = 0;
+ low_line_vma = 0;
+ past_line = false;
+ past_fn = false;
+
+ external_sym_size = debug_swap->external_sym_size;
+
+ sym_ptr = ((char *) debug_info->external_sym
+ + (fdr_ptr->isymBase + 2) * external_sym_size);
+ sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size;
+ for (;
+ sym_ptr < sym_ptr_end && (! past_line || ! past_fn);
+ sym_ptr += external_sym_size)
+ {
+ SYMR sym;
+
+ (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
+
+ if (ECOFF_IS_STAB (&sym))
+ {
+ switch (ECOFF_UNMARK_STAB (sym.index))
+ {
+ case N_SO:
+ main_file_name = current_file_name =
+ debug_info->ss + fdr_ptr->issBase + sym.iss;
+
+ /* Check the next symbol to see if it is also an
+ N_SO symbol. */
+ if (sym_ptr + external_sym_size < sym_ptr_end)
+ {
+ SYMR nextsym;
+
+ (*debug_swap->swap_sym_in) (abfd,
+ sym_ptr + external_sym_size,
+ &nextsym);
+ if (ECOFF_IS_STAB (&nextsym)
+ && ECOFF_UNMARK_STAB (nextsym.index) == N_SO)
+ {
+ directory_name = current_file_name;
+ main_file_name = current_file_name =
+ debug_info->ss + fdr_ptr->issBase + nextsym.iss;
+ sym_ptr += external_sym_size;
+ }
+ }
+ break;
+
+ case N_SOL:
+ current_file_name =
+ debug_info->ss + fdr_ptr->issBase + sym.iss;
+ break;
+
+ case N_FUN:
+ if (sym.value > offset)
+ past_fn = true;
+ else if (sym.value >= low_func_vma)
+ {
+ low_func_vma = sym.value;
+ function_name =
+ debug_info->ss + fdr_ptr->issBase + sym.iss;
+ }
+ break;
+ }
+ }
+ else if (sym.st == stLabel && sym.index != indexNil)
+ {
+ if (sym.value > offset)
+ past_line = true;
+ else if (sym.value >= low_line_vma)
+ {
+ low_line_vma = sym.value;
+ line_file_name = current_file_name;
+ line_info->cache.line_num = sym.index;
+ }
+ }
+ }
+
+ if (line_info->cache.line_num != 0)
+ main_file_name = line_file_name;
+
+ /* We need to remove the stuff after the colon in the function
+ name. We also need to put the directory name and the file
+ name together. */
+ if (function_name == NULL)
+ len = funclen = 0;
+ else
+ len = funclen = strlen (function_name) + 1;
+
+ if (main_file_name != NULL
+ && directory_name != NULL
+ && main_file_name[0] != '/')
+ len += strlen (directory_name) + strlen (main_file_name) + 1;
+
+ if (len != 0)
+ {
+ if (line_info->find_buffer != NULL)
+ free (line_info->find_buffer);
+ buffer = (char *) bfd_malloc (len);
+ if (buffer == NULL)
+ return false;
+ line_info->find_buffer = buffer;
+ }
+
+ if (function_name != NULL)
+ {
+ char *colon;
+
+ strcpy (buffer, function_name);
+ colon = strchr (buffer, ':');
+ if (colon != NULL)
+ *colon = '\0';
+ line_info->cache.functionname = buffer;
+ }
+
+ if (main_file_name != NULL)
+ {
+ if (directory_name == NULL || main_file_name[0] == '/')
+ line_info->cache.filename = main_file_name;
+ else
+ {
+ sprintf (buffer + funclen, "%s%s", directory_name,
+ main_file_name);
+ line_info->cache.filename = buffer + funclen;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Do the work of find_nearest_line. */
+
+boolean
+_bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap,
+ line_info, filename_ptr, functionname_ptr, retline_ptr)
+ bfd *abfd;
+ asection *section;
+ bfd_vma offset;
+ struct ecoff_debug_info * const debug_info;
+ const struct ecoff_debug_swap * const debug_swap;
+ struct ecoff_find_line *line_info;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *retline_ptr;
+{
+ offset += section->vma;
+
+ if (line_info->cache.sect == NULL
+ || line_info->cache.sect != section
+ || offset < line_info->cache.start
+ || offset >= line_info->cache.stop)
+ {
+ line_info->cache.sect = section;
+ line_info->cache.start = offset;
+ line_info->cache.stop = offset;
+ if (! lookup_line (abfd, debug_info, debug_swap, line_info))
+ {
+ line_info->cache.sect = NULL;
+ return false;
+ }
+ }
+
+ *filename_ptr = line_info->cache.filename;
+ *functionname_ptr = line_info->cache.functionname;
+ *retline_ptr = line_info->cache.line_num;
+
+ return true;
+}
+
+/* These routines copy symbolic information into a memory buffer.
+
+ FIXME: The whole point of the shuffle code is to avoid storing
+ everything in memory, since the linker is such a memory hog. This
+ code makes that effort useless. It is only called by the MIPS ELF
+ code when generating a shared library, so it is not that big a
+ deal, but it should be fixed eventually. */
+
+/* Collect a shuffle into a memory buffer. */
+
+static boolean ecoff_collect_shuffle PARAMS ((struct shuffle *, bfd_byte *));
+
+static boolean
+ecoff_collect_shuffle (l, buff)
+ struct shuffle *l;
+ bfd_byte *buff;
+{
+ unsigned long total;
+
+ total = 0;
+ for (; l != (struct shuffle *) NULL; l = l->next)
+ {
+ if (! l->filep)
+ memcpy (buff, l->u.memory, l->size);
+ else
+ {
+ if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
+ || bfd_read (buff, 1, l->size, l->u.file.input_bfd) != l->size)
+ return false;
+ }
+ total += l->size;
+ buff += l->size;
+ }
+
+ return true;
+}
+
+/* Copy PDR information into a memory buffer. */
+
+boolean
+_bfd_ecoff_get_accumulated_pdr (handle, buff)
+ PTR handle;
+ bfd_byte *buff;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+
+ return ecoff_collect_shuffle (ainfo->pdr, buff);
+}
+
+/* Copy symbol information into a memory buffer. */
+
+boolean
+_bfd_ecoff_get_accumulated_sym (handle, buff)
+ PTR handle;
+ bfd_byte *buff;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+
+ return ecoff_collect_shuffle (ainfo->sym, buff);
+}
+
+/* Copy the string table into a memory buffer. */
+
+boolean
+_bfd_ecoff_get_accumulated_ss (handle, buff)
+ PTR handle;
+ bfd_byte *buff;
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+ struct string_hash_entry *sh;
+ unsigned long total;
+
+ /* The string table is written out from the hash table if this is a
+ final link. */
+ BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
+ *buff++ = '\0';
+ total = 1;
+ BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
+ for (sh = ainfo->ss_hash;
+ sh != (struct string_hash_entry *) NULL;
+ sh = sh->next)
+ {
+ size_t len;
+
+ len = strlen (sh->root.string);
+ memcpy (buff, (PTR) sh->root.string, len + 1);
+ total += len + 1;
+ buff += len + 1;
+ }
+
+ return true;
+}
diff --git a/bfd/ecoffswap.h b/bfd/ecoffswap.h
new file mode 100644
index 00000000000..0d28d16883e
--- /dev/null
+++ b/bfd/ecoffswap.h
@@ -0,0 +1,853 @@
+/* Generic ECOFF swapping routines, for BFD.
+ Copyright 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* NOTE: This is a header file, but it contains executable routines.
+ This is done this way because these routines are substantially
+ similar, but are not identical, for all ECOFF targets.
+
+ These are routines to swap the ECOFF symbolic information in and
+ out. The routines are defined statically. You can set breakpoints
+ on them in gdb by naming the including source file; e.g.,
+ 'coff-mips.c':ecoff_swap_hdr_in.
+
+ Before including this header file, one of ECOFF_32 or ECOFF_64 must
+ be defined. These are checked when swapping information that
+ depends upon the target size. This code works for 32 bit and 64
+ bit ECOFF, but may need to be generalized in the future.
+
+ Some header file which defines the external forms of these
+ structures must also be included before including this header file.
+ Currently this is either coff/mips.h or coff/alpha.h.
+
+ If the symbol TEST is defined when this file is compiled, a
+ comparison is made to ensure that, in fact, the output is
+ bit-for-bit the same as the input. Of course, this symbol should
+ only be defined when deliberately testing the code on a machine
+ with the proper byte sex and such. */
+
+#ifdef ECOFF_32
+#define ecoff_get_off bfd_h_get_32
+#define ecoff_put_off bfd_h_put_32
+#endif
+#ifdef ECOFF_64
+#define ecoff_get_off bfd_h_get_64
+#define ecoff_put_off bfd_h_put_64
+#endif
+
+/* ECOFF auxiliary information swapping routines. These are the same
+ for all ECOFF targets, so they are defined in ecofflink.c. */
+
+extern void _bfd_ecoff_swap_tir_in
+ PARAMS ((int, const struct tir_ext *, TIR *));
+extern void _bfd_ecoff_swap_tir_out
+ PARAMS ((int, const TIR *, struct tir_ext *));
+extern void _bfd_ecoff_swap_rndx_in
+ PARAMS ((int, const struct rndx_ext *, RNDXR *));
+extern void _bfd_ecoff_swap_rndx_out
+ PARAMS ((int, const RNDXR *, struct rndx_ext *));
+
+/* Prototypes for functions defined in this file. */
+
+static void ecoff_swap_hdr_in PARAMS ((bfd *, PTR, HDRR *));
+static void ecoff_swap_hdr_out PARAMS ((bfd *, const HDRR *, PTR));
+static void ecoff_swap_fdr_in PARAMS ((bfd *, PTR, FDR *));
+static void ecoff_swap_fdr_out PARAMS ((bfd *, const FDR *, PTR));
+static void ecoff_swap_pdr_in PARAMS ((bfd *, PTR, PDR *));
+static void ecoff_swap_pdr_out PARAMS ((bfd *, const PDR *, PTR));
+static void ecoff_swap_sym_in PARAMS ((bfd *, PTR, SYMR *));
+static void ecoff_swap_sym_out PARAMS ((bfd *, const SYMR *, PTR));
+static void ecoff_swap_ext_in PARAMS ((bfd *, PTR, EXTR *));
+static void ecoff_swap_ext_out PARAMS ((bfd *, const EXTR *, PTR));
+static void ecoff_swap_rfd_in PARAMS ((bfd *, PTR, RFDT *));
+static void ecoff_swap_rfd_out PARAMS ((bfd *, const RFDT *, PTR));
+static void ecoff_swap_opt_in PARAMS ((bfd *, PTR, OPTR *));
+static void ecoff_swap_opt_out PARAMS ((bfd *, const OPTR *, PTR));
+static void ecoff_swap_dnr_in PARAMS ((bfd *, PTR, DNR *));
+static void ecoff_swap_dnr_out PARAMS ((bfd *, const DNR *, PTR));
+
+/* Swap in the symbolic header. */
+
+static void
+ecoff_swap_hdr_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ HDRR *intern;
+{
+ struct hdr_ext ext[1];
+
+ *ext = *(struct hdr_ext *) ext_copy;
+
+ intern->magic = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_magic);
+ intern->vstamp = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_vstamp);
+ intern->ilineMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ilineMax);
+ intern->cbLine = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLine);
+ intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLineOffset);
+ intern->idnMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_idnMax);
+ intern->cbDnOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbDnOffset);
+ intern->ipdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ipdMax);
+ intern->cbPdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbPdOffset);
+ intern->isymMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_isymMax);
+ intern->cbSymOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSymOffset);
+ intern->ioptMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ioptMax);
+ intern->cbOptOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbOptOffset);
+ intern->iauxMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iauxMax);
+ intern->cbAuxOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbAuxOffset);
+ intern->issMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issMax);
+ intern->cbSsOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsOffset);
+ intern->issExtMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issExtMax);
+ intern->cbSsExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsExtOffset);
+ intern->ifdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ifdMax);
+ intern->cbFdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbFdOffset);
+ intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_crfd);
+ intern->cbRfdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbRfdOffset);
+ intern->iextMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iextMax);
+ intern->cbExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbExtOffset);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out the symbolic header. */
+
+static void
+ecoff_swap_hdr_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const HDRR *intern_copy;
+ PTR ext_ptr;
+{
+ struct hdr_ext *ext = (struct hdr_ext *) ext_ptr;
+ HDRR intern[1];
+
+ *intern = *intern_copy;
+
+ bfd_h_put_signed_16 (abfd, intern->magic, (bfd_byte *)ext->h_magic);
+ bfd_h_put_signed_16 (abfd, intern->vstamp, (bfd_byte *)ext->h_vstamp);
+ bfd_h_put_32 (abfd, intern->ilineMax, (bfd_byte *)ext->h_ilineMax);
+ ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->h_cbLine);
+ ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->h_cbLineOffset);
+ bfd_h_put_32 (abfd, intern->idnMax, (bfd_byte *)ext->h_idnMax);
+ ecoff_put_off (abfd, intern->cbDnOffset, (bfd_byte *)ext->h_cbDnOffset);
+ bfd_h_put_32 (abfd, intern->ipdMax, (bfd_byte *)ext->h_ipdMax);
+ ecoff_put_off (abfd, intern->cbPdOffset, (bfd_byte *)ext->h_cbPdOffset);
+ bfd_h_put_32 (abfd, intern->isymMax, (bfd_byte *)ext->h_isymMax);
+ ecoff_put_off (abfd, intern->cbSymOffset, (bfd_byte *)ext->h_cbSymOffset);
+ bfd_h_put_32 (abfd, intern->ioptMax, (bfd_byte *)ext->h_ioptMax);
+ ecoff_put_off (abfd, intern->cbOptOffset, (bfd_byte *)ext->h_cbOptOffset);
+ bfd_h_put_32 (abfd, intern->iauxMax, (bfd_byte *)ext->h_iauxMax);
+ ecoff_put_off (abfd, intern->cbAuxOffset, (bfd_byte *)ext->h_cbAuxOffset);
+ bfd_h_put_32 (abfd, intern->issMax, (bfd_byte *)ext->h_issMax);
+ ecoff_put_off (abfd, intern->cbSsOffset, (bfd_byte *)ext->h_cbSsOffset);
+ bfd_h_put_32 (abfd, intern->issExtMax, (bfd_byte *)ext->h_issExtMax);
+ ecoff_put_off (abfd, intern->cbSsExtOffset, (bfd_byte *)ext->h_cbSsExtOffset);
+ bfd_h_put_32 (abfd, intern->ifdMax, (bfd_byte *)ext->h_ifdMax);
+ ecoff_put_off (abfd, intern->cbFdOffset, (bfd_byte *)ext->h_cbFdOffset);
+ bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->h_crfd);
+ ecoff_put_off (abfd, intern->cbRfdOffset, (bfd_byte *)ext->h_cbRfdOffset);
+ bfd_h_put_32 (abfd, intern->iextMax, (bfd_byte *)ext->h_iextMax);
+ ecoff_put_off (abfd, intern->cbExtOffset, (bfd_byte *)ext->h_cbExtOffset);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap in the file descriptor record. */
+
+static void
+ecoff_swap_fdr_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ FDR *intern;
+{
+ struct fdr_ext ext[1];
+
+ *ext = *(struct fdr_ext *) ext_copy;
+
+ intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->f_adr);
+ intern->rss = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rss);
+#ifdef ECOFF_64
+ if (intern->rss == 0xffffffff)
+ intern->rss = -1;
+#endif
+ intern->issBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_issBase);
+ intern->cbSs = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbSs);
+ intern->isymBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_isymBase);
+ intern->csym = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_csym);
+ intern->ilineBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ilineBase);
+ intern->cline = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cline);
+ intern->ioptBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ioptBase);
+ intern->copt = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_copt);
+#ifdef ECOFF_32
+ intern->ipdFirst = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_ipdFirst);
+ intern->cpd = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_cpd);
+#endif
+#ifdef ECOFF_64
+ intern->ipdFirst = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ipdFirst);
+ intern->cpd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cpd);
+#endif
+ intern->iauxBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_iauxBase);
+ intern->caux = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_caux);
+ intern->rfdBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rfdBase);
+ intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_crfd);
+
+ /* now the fun stuff... */
+ if (bfd_header_big_endian (abfd)) {
+ intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_BIG)
+ >> FDR_BITS1_LANG_SH_BIG;
+ intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG);
+ intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG);
+ intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG);
+ intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG)
+ >> FDR_BITS2_GLEVEL_SH_BIG;
+ } else {
+ intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE)
+ >> FDR_BITS1_LANG_SH_LITTLE;
+ intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE);
+ intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE);
+ intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE);
+ intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE)
+ >> FDR_BITS2_GLEVEL_SH_LITTLE;
+ }
+ intern->reserved = 0;
+
+ intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLineOffset);
+ intern->cbLine = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLine);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out the file descriptor record. */
+
+static void
+ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const FDR *intern_copy;
+ PTR ext_ptr;
+{
+ struct fdr_ext *ext = (struct fdr_ext *) ext_ptr;
+ FDR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->f_adr);
+ bfd_h_put_32 (abfd, intern->rss, (bfd_byte *)ext->f_rss);
+ bfd_h_put_32 (abfd, intern->issBase, (bfd_byte *)ext->f_issBase);
+ ecoff_put_off (abfd, intern->cbSs, (bfd_byte *)ext->f_cbSs);
+ bfd_h_put_32 (abfd, intern->isymBase, (bfd_byte *)ext->f_isymBase);
+ bfd_h_put_32 (abfd, intern->csym, (bfd_byte *)ext->f_csym);
+ bfd_h_put_32 (abfd, intern->ilineBase, (bfd_byte *)ext->f_ilineBase);
+ bfd_h_put_32 (abfd, intern->cline, (bfd_byte *)ext->f_cline);
+ bfd_h_put_32 (abfd, intern->ioptBase, (bfd_byte *)ext->f_ioptBase);
+ bfd_h_put_32 (abfd, intern->copt, (bfd_byte *)ext->f_copt);
+#ifdef ECOFF_32
+ bfd_h_put_16 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst);
+ bfd_h_put_16 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd);
+#endif
+#ifdef ECOFF_64
+ bfd_h_put_32 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst);
+ bfd_h_put_32 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd);
+#endif
+ bfd_h_put_32 (abfd, intern->iauxBase, (bfd_byte *)ext->f_iauxBase);
+ bfd_h_put_32 (abfd, intern->caux, (bfd_byte *)ext->f_caux);
+ bfd_h_put_32 (abfd, intern->rfdBase, (bfd_byte *)ext->f_rfdBase);
+ bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->f_crfd);
+
+ /* now the fun stuff... */
+ if (bfd_header_big_endian (abfd)) {
+ ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_BIG)
+ & FDR_BITS1_LANG_BIG)
+ | (intern->fMerge ? FDR_BITS1_FMERGE_BIG : 0)
+ | (intern->fReadin ? FDR_BITS1_FREADIN_BIG : 0)
+ | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_BIG : 0));
+ ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_BIG)
+ & FDR_BITS2_GLEVEL_BIG);
+ ext->f_bits2[1] = 0;
+ ext->f_bits2[2] = 0;
+ } else {
+ ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_LITTLE)
+ & FDR_BITS1_LANG_LITTLE)
+ | (intern->fMerge ? FDR_BITS1_FMERGE_LITTLE : 0)
+ | (intern->fReadin ? FDR_BITS1_FREADIN_LITTLE : 0)
+ | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_LITTLE : 0));
+ ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_LITTLE)
+ & FDR_BITS2_GLEVEL_LITTLE);
+ ext->f_bits2[1] = 0;
+ ext->f_bits2[2] = 0;
+ }
+
+ ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->f_cbLineOffset);
+ ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->f_cbLine);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+#ifndef MPW_C
+
+/* Swap in the procedure descriptor record. */
+
+static void
+ecoff_swap_pdr_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ PDR *intern;
+{
+ struct pdr_ext ext[1];
+
+ *ext = *(struct pdr_ext *) ext_copy;
+
+ memset ((PTR) intern, 0, sizeof (*intern));
+
+ intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr);
+ intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym);
+ intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline);
+ intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask);
+ intern->regoffset = bfd_h_get_signed_32 (abfd,
+ (bfd_byte *)ext->p_regoffset);
+ intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt);
+ intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask);
+ intern->fregoffset = bfd_h_get_signed_32 (abfd,
+ (bfd_byte *)ext->p_fregoffset);
+ intern->frameoffset = bfd_h_get_signed_32 (abfd,
+ (bfd_byte *)ext->p_frameoffset);
+ intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg);
+ intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg);
+ intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow);
+ intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh);
+ intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset);
+
+#ifdef ECOFF_64
+ intern->gp_prologue = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_gp_prologue);
+ if (bfd_header_big_endian (abfd))
+ {
+ intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG);
+ intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG);
+ intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG);
+ intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG)
+ << PDR_BITS1_RESERVED_SH_LEFT_BIG)
+ | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG)
+ >> PDR_BITS2_RESERVED_SH_BIG));
+ }
+ else
+ {
+ intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE);
+ intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE);
+ intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE);
+ intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE)
+ >> PDR_BITS1_RESERVED_SH_LITTLE)
+ | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE)
+ << PDR_BITS2_RESERVED_SH_LEFT_LITTLE));
+ }
+ intern->localoff = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_localoff);
+#endif
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out the procedure descriptor record. */
+
+static void
+ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const PDR *intern_copy;
+ PTR ext_ptr;
+{
+ struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
+ PDR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr);
+ bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym);
+ bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline);
+ bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask);
+ bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset);
+ bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt);
+ bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask);
+ bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset);
+ bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset);
+ bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg);
+ bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg);
+ bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow);
+ bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh);
+ ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset);
+
+#ifdef ECOFF_64
+ bfd_h_put_8 (abfd, intern->gp_prologue, (bfd_byte *) ext->p_gp_prologue);
+ if (bfd_header_big_endian (abfd))
+ {
+ ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0)
+ | (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0)
+ | (intern->prof ? PDR_BITS1_PROF_BIG : 0)
+ | ((intern->reserved
+ >> PDR_BITS1_RESERVED_SH_LEFT_BIG)
+ & PDR_BITS1_RESERVED_BIG));
+ ext->p_bits2[0] = ((intern->reserved << PDR_BITS2_RESERVED_SH_BIG)
+ & PDR_BITS2_RESERVED_BIG);
+ }
+ else
+ {
+ ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0)
+ | (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0)
+ | (intern->prof ? PDR_BITS1_PROF_LITTLE : 0)
+ | ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE)
+ & PDR_BITS1_RESERVED_LITTLE));
+ ext->p_bits2[0] = ((intern->reserved >>
+ PDR_BITS2_RESERVED_SH_LEFT_LITTLE)
+ & PDR_BITS2_RESERVED_LITTLE);
+ }
+ bfd_h_put_8 (abfd, intern->localoff, (bfd_byte *) ext->p_localoff);
+#endif
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+#else /* MPW_C */
+/* Same routines, but with ECOFF_64 code removed, so ^&%$#&! MPW C doesn't
+ corrupt itself and then freak out. */
+/* Swap in the procedure descriptor record. */
+
+static void
+ecoff_swap_pdr_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ PDR *intern;
+{
+ struct pdr_ext ext[1];
+
+ *ext = *(struct pdr_ext *) ext_copy;
+
+ intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr);
+ intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym);
+ intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline);
+ intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask);
+ intern->regoffset = bfd_h_get_signed_32 (abfd,
+ (bfd_byte *)ext->p_regoffset);
+ intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt);
+ intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask);
+ intern->fregoffset = bfd_h_get_signed_32 (abfd,
+ (bfd_byte *)ext->p_fregoffset);
+ intern->frameoffset = bfd_h_get_signed_32 (abfd,
+ (bfd_byte *)ext->p_frameoffset);
+ intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg);
+ intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg);
+ intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow);
+ intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh);
+ intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out the procedure descriptor record. */
+
+static void
+ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const PDR *intern_copy;
+ PTR ext_ptr;
+{
+ struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
+ PDR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr);
+ bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym);
+ bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline);
+ bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask);
+ bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset);
+ bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt);
+ bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask);
+ bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset);
+ bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset);
+ bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg);
+ bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg);
+ bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow);
+ bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh);
+ ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+#endif /* MPW_C */
+
+/* Swap in a symbol record. */
+
+static void
+ecoff_swap_sym_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ SYMR *intern;
+{
+ struct sym_ext ext[1];
+
+ *ext = *(struct sym_ext *) ext_copy;
+
+ intern->iss = bfd_h_get_32 (abfd, (bfd_byte *)ext->s_iss);
+ intern->value = ecoff_get_off (abfd, (bfd_byte *)ext->s_value);
+
+ /* now the fun stuff... */
+ if (bfd_header_big_endian (abfd)) {
+ intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_BIG)
+ >> SYM_BITS1_ST_SH_BIG;
+ intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG)
+ << SYM_BITS1_SC_SH_LEFT_BIG)
+ | ((ext->s_bits2[0] & SYM_BITS2_SC_BIG)
+ >> SYM_BITS2_SC_SH_BIG);
+ intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG);
+ intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG)
+ << SYM_BITS2_INDEX_SH_LEFT_BIG)
+ | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG)
+ | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG);
+ } else {
+ intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE)
+ >> SYM_BITS1_ST_SH_LITTLE;
+ intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE)
+ >> SYM_BITS1_SC_SH_LITTLE)
+ | ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE)
+ << SYM_BITS2_SC_SH_LEFT_LITTLE);
+ intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE);
+ intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE)
+ >> SYM_BITS2_INDEX_SH_LITTLE)
+ | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE)
+ | ((unsigned int) ext->s_bits4[0]
+ << SYM_BITS4_INDEX_SH_LEFT_LITTLE);
+ }
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out a symbol record. */
+
+static void
+ecoff_swap_sym_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const SYMR *intern_copy;
+ PTR ext_ptr;
+{
+ struct sym_ext *ext = (struct sym_ext *) ext_ptr;
+ SYMR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ bfd_h_put_32 (abfd, intern->iss, (bfd_byte *)ext->s_iss);
+ ecoff_put_off (abfd, intern->value, (bfd_byte *)ext->s_value);
+
+ /* now the fun stuff... */
+ if (bfd_header_big_endian (abfd)) {
+ ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_BIG)
+ & SYM_BITS1_ST_BIG)
+ | ((intern->sc >> SYM_BITS1_SC_SH_LEFT_BIG)
+ & SYM_BITS1_SC_BIG));
+ ext->s_bits2[0] = (((intern->sc << SYM_BITS2_SC_SH_BIG)
+ & SYM_BITS2_SC_BIG)
+ | (intern->reserved ? SYM_BITS2_RESERVED_BIG : 0)
+ | ((intern->index >> SYM_BITS2_INDEX_SH_LEFT_BIG)
+ & SYM_BITS2_INDEX_BIG));
+ ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_BIG) & 0xff;
+ ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_BIG) & 0xff;
+ } else {
+ ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_LITTLE)
+ & SYM_BITS1_ST_LITTLE)
+ | ((intern->sc << SYM_BITS1_SC_SH_LITTLE)
+ & SYM_BITS1_SC_LITTLE));
+ ext->s_bits2[0] = (((intern->sc >> SYM_BITS2_SC_SH_LEFT_LITTLE)
+ & SYM_BITS2_SC_LITTLE)
+ | (intern->reserved ? SYM_BITS2_RESERVED_LITTLE : 0)
+ | ((intern->index << SYM_BITS2_INDEX_SH_LITTLE)
+ & SYM_BITS2_INDEX_LITTLE));
+ ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_LITTLE) & 0xff;
+ ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_LITTLE) & 0xff;
+ }
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap in an external symbol record. */
+
+static void
+ecoff_swap_ext_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ EXTR *intern;
+{
+ struct ext_ext ext[1];
+
+ *ext = *(struct ext_ext *) ext_copy;
+
+ /* now the fun stuff... */
+ if (bfd_header_big_endian (abfd)) {
+ intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG);
+ intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG);
+ intern->weakext = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_BIG);
+ } else {
+ intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE);
+ intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE);
+ intern->weakext = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_LITTLE);
+ }
+ intern->reserved = 0;
+
+#ifdef ECOFF_32
+ intern->ifd = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->es_ifd);
+#endif
+#ifdef ECOFF_64
+ intern->ifd = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->es_ifd);
+#endif
+
+ ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out an external symbol record. */
+
+static void
+ecoff_swap_ext_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const EXTR *intern_copy;
+ PTR ext_ptr;
+{
+ struct ext_ext *ext = (struct ext_ext *) ext_ptr;
+ EXTR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ /* now the fun stuff... */
+ if (bfd_header_big_endian (abfd)) {
+ ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_BIG : 0)
+ | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0)
+ | (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0));
+ ext->es_bits2[0] = 0;
+#ifdef ECOFF_64
+ ext->es_bits2[1] = 0;
+ ext->es_bits2[2] = 0;
+#endif
+ } else {
+ ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0)
+ | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0)
+ | (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0));
+ ext->es_bits2[0] = 0;
+#ifdef ECOFF_64
+ ext->es_bits2[1] = 0;
+ ext->es_bits2[2] = 0;
+#endif
+ }
+
+#ifdef ECOFF_32
+ bfd_h_put_signed_16 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd);
+#endif
+#ifdef ECOFF_64
+ bfd_h_put_signed_32 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd);
+#endif
+
+ ecoff_swap_sym_out (abfd, &intern->asym, &ext->es_asym);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap in a relative file descriptor. */
+
+static void
+ecoff_swap_rfd_in (abfd, ext_ptr, intern)
+ bfd *abfd;
+ PTR ext_ptr;
+ RFDT *intern;
+{
+ struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
+
+ *intern = bfd_h_get_32 (abfd, (bfd_byte *)ext->rfd);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out a relative file descriptor. */
+
+static void
+ecoff_swap_rfd_out (abfd, intern, ext_ptr)
+ bfd *abfd;
+ const RFDT *intern;
+ PTR ext_ptr;
+{
+ struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
+
+ bfd_h_put_32 (abfd, *intern, (bfd_byte *)ext->rfd);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap in an optimization symbol. */
+
+static void
+ecoff_swap_opt_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ OPTR *intern;
+{
+ struct opt_ext ext[1];
+
+ *ext = *(struct opt_ext *) ext_copy;
+
+ if (bfd_header_big_endian (abfd))
+ {
+ intern->ot = ext->o_bits1[0];
+ intern->value = (((unsigned int) ext->o_bits2[0]
+ << OPT_BITS2_VALUE_SH_LEFT_BIG)
+ | ((unsigned int) ext->o_bits3[0]
+ << OPT_BITS2_VALUE_SH_LEFT_BIG)
+ | ((unsigned int) ext->o_bits4[0]
+ << OPT_BITS2_VALUE_SH_LEFT_BIG));
+ }
+ else
+ {
+ intern->ot = ext->o_bits1[0];
+ intern->value = ((ext->o_bits2[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
+ | (ext->o_bits3[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
+ | (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE));
+ }
+
+ _bfd_ecoff_swap_rndx_in (bfd_header_big_endian (abfd),
+ &ext->o_rndx, &intern->rndx);
+
+ intern->offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->o_offset);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out an optimization symbol. */
+
+static void
+ecoff_swap_opt_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const OPTR *intern_copy;
+ PTR ext_ptr;
+{
+ struct opt_ext *ext = (struct opt_ext *) ext_ptr;
+ OPTR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ if (bfd_header_big_endian (abfd))
+ {
+ ext->o_bits1[0] = intern->ot;
+ ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_BIG;
+ ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_BIG;
+ ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_BIG;
+ }
+ else
+ {
+ ext->o_bits1[0] = intern->ot;
+ ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_LITTLE;
+ ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_LITTLE;
+ ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE;
+ }
+
+ _bfd_ecoff_swap_rndx_out (bfd_header_big_endian (abfd),
+ &intern->rndx, &ext->o_rndx);
+
+ bfd_h_put_32 (abfd, intern->value, (bfd_byte *) ext->o_offset);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap in a dense number. */
+
+static void
+ecoff_swap_dnr_in (abfd, ext_copy, intern)
+ bfd *abfd;
+ PTR ext_copy;
+ DNR *intern;
+{
+ struct dnr_ext ext[1];
+
+ *ext = *(struct dnr_ext *) ext_copy;
+
+ intern->rfd = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_rfd);
+ intern->index = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_index);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
+
+/* Swap out a dense number. */
+
+static void
+ecoff_swap_dnr_out (abfd, intern_copy, ext_ptr)
+ bfd *abfd;
+ const DNR *intern_copy;
+ PTR ext_ptr;
+{
+ struct dnr_ext *ext = (struct dnr_ext *) ext_ptr;
+ DNR intern[1];
+
+ *intern = *intern_copy; /* Make it reasonable to do in-place. */
+
+ bfd_h_put_32 (abfd, intern->rfd, (bfd_byte *) ext->d_rfd);
+ bfd_h_put_32 (abfd, intern->index, (bfd_byte *) ext->d_index);
+
+#ifdef TEST
+ if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
+ abort();
+#endif
+}
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
new file mode 100644
index 00000000000..82ffe2add97
--- /dev/null
+++ b/bfd/elf-bfd.h
@@ -0,0 +1,1114 @@
+/* BFD back-end data structures for ELF files.
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _LIBELF_H_
+#define _LIBELF_H_ 1
+
+#include "elf/common.h"
+#include "elf/internal.h"
+#include "elf/external.h"
+#include "bfdlink.h"
+
+/* If size isn't specified as 64 or 32, NAME macro should fail. */
+#ifndef NAME
+#if ARCH_SIZE==64
+#define NAME(x,y) CAT4(x,64,_,y)
+#endif
+#if ARCH_SIZE==32
+#define NAME(x,y) CAT4(x,32,_,y)
+#endif
+#endif
+
+#ifndef NAME
+#define NAME(x,y) CAT4(x,NOSIZE,_,y)
+#endif
+
+#define ElfNAME(X) NAME(Elf,X)
+#define elfNAME(X) NAME(elf,X)
+
+/* Information held for an ELF symbol. The first field is the
+ corresponding asymbol. Every symbol is an ELF file is actually a
+ pointer to this structure, although it is often handled as a
+ pointer to an asymbol. */
+
+typedef struct
+{
+ /* The BFD symbol. */
+ asymbol symbol;
+ /* ELF symbol information. */
+ Elf_Internal_Sym internal_elf_sym;
+ /* Backend specific information. */
+ union
+ {
+ unsigned int hppa_arg_reloc;
+ PTR mips_extr;
+ PTR any;
+ }
+ tc_data;
+
+ /* Version information. This is from an Elf_Internal_Versym
+ structure in a SHT_GNU_versym section. It is zero if there is no
+ version information. */
+ unsigned short version;
+
+} elf_symbol_type;
+
+/* ELF linker hash table entries. */
+
+struct elf_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+
+ /* Symbol index in output file. This is initialized to -1. It is
+ set to -2 if the symbol is used by a reloc. */
+ long indx;
+
+ /* Symbol size. */
+ bfd_size_type size;
+
+ /* Symbol index as a dynamic symbol. Initialized to -1, and remains
+ -1 if this is not a dynamic symbol. */
+ long dynindx;
+
+ /* String table index in .dynstr if this is a dynamic symbol. */
+ unsigned long dynstr_index;
+
+ /* If this is a weak defined symbol from a dynamic object, this
+ field points to a defined symbol with the same value, if there is
+ one. Otherwise it is NULL. */
+ struct elf_link_hash_entry *weakdef;
+
+ /* If this symbol requires an entry in the global offset table, the
+ processor specific backend uses this field to track usage and
+ final offset. We use a union and two names primarily to document
+ the intent of any particular piece of code. The field should be
+ used as a count until size_dynamic_sections, at which point the
+ contents of the .got is fixed. Afterward, if this field is -1,
+ then the symbol does not require a global offset table entry. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } got;
+
+ /* Same, but tracks a procedure linkage table entry. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } plt;
+
+ /* If this symbol is used in the linker created sections, the processor
+ specific backend uses this field to map the field into the offset
+ from the beginning of the section. */
+ struct elf_linker_section_pointers *linker_section_pointer;
+
+ /* Version information. */
+ union
+ {
+ /* This field is used for a symbol which is not defined in a
+ regular object. It points to the version information read in
+ from the dynamic object. */
+ Elf_Internal_Verdef *verdef;
+ /* This field is used for a symbol which is defined in a regular
+ object. It is set up in size_dynamic_sections. It points to
+ the version information we should write out for this symbol. */
+ struct bfd_elf_version_tree *vertree;
+ } verinfo;
+
+ /* Virtual table entry use information. This array is nominally of size
+ size/sizeof(target_void_pointer), though we have to be able to assume
+ and track a size while the symbol is still undefined. It is indexed
+ via offset/sizeof(target_void_pointer). */
+ size_t vtable_entries_size;
+ boolean *vtable_entries_used;
+
+ /* Virtual table derivation info. */
+ struct elf_link_hash_entry *vtable_parent;
+
+ /* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
+ char type;
+
+ /* Symbol st_other value. */
+ unsigned char other;
+
+ /* Hash value of the name computed using the ELF hash function. */
+ unsigned long elf_hash_value;
+
+ /* Some flags; legal values follow. */
+ unsigned short elf_link_hash_flags;
+ /* Symbol is referenced by a non-shared object. */
+#define ELF_LINK_HASH_REF_REGULAR 01
+ /* Symbol is defined by a non-shared object. */
+#define ELF_LINK_HASH_DEF_REGULAR 02
+ /* Symbol is referenced by a shared object. */
+#define ELF_LINK_HASH_REF_DYNAMIC 04
+ /* Symbol is defined by a shared object. */
+#define ELF_LINK_HASH_DEF_DYNAMIC 010
+ /* Symbol has a non-weak reference from a non-shared object. */
+#define ELF_LINK_HASH_REF_REGULAR_NONWEAK 020
+ /* Dynamic symbol has been adjustd. */
+#define ELF_LINK_HASH_DYNAMIC_ADJUSTED 040
+ /* Symbol needs a copy reloc. */
+#define ELF_LINK_HASH_NEEDS_COPY 0100
+ /* Symbol needs a procedure linkage table entry. */
+#define ELF_LINK_HASH_NEEDS_PLT 0200
+ /* Symbol appears in a non-ELF input file. */
+#define ELF_LINK_NON_ELF 0400
+ /* Symbol should be marked as hidden in the version information. */
+#define ELF_LINK_HIDDEN 01000
+ /* Symbol was forced to local scope due to a version script file. */
+#define ELF_LINK_FORCED_LOCAL 02000
+ /* Symbol was marked during garbage collection. */
+#define ELF_LINK_HASH_MARK 04000
+};
+
+/* ELF linker hash table. */
+
+struct elf_link_hash_table
+{
+ struct bfd_link_hash_table root;
+ /* Whether we have created the special dynamic sections required
+ when linking against or generating a shared object. */
+ boolean dynamic_sections_created;
+ /* The BFD used to hold special sections created by the linker.
+ This will be the first BFD found which requires these sections to
+ be created. */
+ bfd *dynobj;
+ /* The number of symbols found in the link which must be put into
+ the .dynsym section. */
+ bfd_size_type dynsymcount;
+ /* The string table of dynamic symbols, which becomes the .dynstr
+ section. */
+ struct bfd_strtab_hash *dynstr;
+ /* The number of buckets in the hash table in the .hash section.
+ This is based on the number of dynamic symbols. */
+ bfd_size_type bucketcount;
+ /* A linked list of DT_NEEDED names found in dynamic objects
+ included in the link. */
+ struct bfd_link_needed_list *needed;
+ /* The _GLOBAL_OFFSET_TABLE_ symbol. */
+ struct elf_link_hash_entry *hgot;
+ /* A pointer to information used to link stabs in sections. */
+ PTR stab_info;
+};
+
+/* Look up an entry in an ELF linker hash table. */
+
+#define elf_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct elf_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), \
+ (copy), (follow)))
+
+/* Traverse an ELF linker hash table. */
+
+#define elf_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the ELF linker hash table from a link_info structure. */
+
+#define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash))
+
+/* Constant information held for an ELF backend. */
+
+struct elf_size_info {
+ unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr;
+ unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note;
+
+ unsigned char arch_size, file_align;
+ unsigned char elfclass, ev_current;
+ int (*write_out_phdrs) PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
+ boolean (*write_shdrs_and_ehdr) PARAMS ((bfd *));
+ void (*write_relocs) PARAMS ((bfd *, asection *, PTR));
+ void (*swap_symbol_out) PARAMS ((bfd *, const Elf_Internal_Sym *, PTR));
+ boolean (*slurp_reloc_table)
+ PARAMS ((bfd *, asection *, asymbol **, boolean));
+ long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean));
+ void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+};
+
+#define elf_symbol_from(ABFD,S) \
+ (((S)->the_bfd->xvec->flavour == bfd_target_elf_flavour \
+ && (S)->the_bfd->tdata.elf_obj_data != 0) \
+ ? (elf_symbol_type *) (S) \
+ : 0)
+
+struct elf_backend_data
+{
+ /* Whether the backend uses REL or RELA relocations. FIXME: some
+ ELF backends use both. When we need to support one, this whole
+ approach will need to be changed. */
+ int use_rela_p;
+
+ /* The architecture for this backend. */
+ enum bfd_architecture arch;
+
+ /* The ELF machine code (EM_xxxx) for this backend. */
+ int elf_machine_code;
+
+ /* The maximum page size for this backend. */
+ bfd_vma maxpagesize;
+
+ /* This is true if the linker should act like collect and gather
+ global constructors and destructors by name. This is true for
+ MIPS ELF because the Irix 5 tools can not handle the .init
+ section. */
+ boolean collect;
+
+ /* This is true if the linker should ignore changes to the type of a
+ symbol. This is true for MIPS ELF because some Irix 5 objects
+ record undefined functions as STT_OBJECT although the definitions
+ are STT_FUNC. */
+ boolean type_change_ok;
+
+ /* A function to translate an ELF RELA relocation to a BFD arelent
+ structure. */
+ void (*elf_info_to_howto) PARAMS ((bfd *, arelent *,
+ Elf_Internal_Rela *));
+
+ /* A function to translate an ELF REL relocation to a BFD arelent
+ structure. */
+ void (*elf_info_to_howto_rel) PARAMS ((bfd *, arelent *,
+ Elf_Internal_Rel *));
+
+ /* A function to determine whether a symbol is global when
+ partitioning the symbol table into local and global symbols.
+ This should be NULL for most targets, in which case the correct
+ thing will be done. MIPS ELF, at least on the Irix 5, has
+ special requirements. */
+ boolean (*elf_backend_sym_is_global) PARAMS ((bfd *, asymbol *));
+
+ /* The remaining functions are hooks which are called only if they
+ are not NULL. */
+
+ /* A function to permit a backend specific check on whether a
+ particular BFD format is relevant for an object file, and to
+ permit the backend to set any global information it wishes. When
+ this is called elf_elfheader is set, but anything else should be
+ used with caution. If this returns false, the check_format
+ routine will return a bfd_error_wrong_format error. */
+ boolean (*elf_backend_object_p) PARAMS ((bfd *));
+
+ /* A function to do additional symbol processing when reading the
+ ELF symbol table. This is where any processor-specific special
+ section indices are handled. */
+ void (*elf_backend_symbol_processing) PARAMS ((bfd *, asymbol *));
+
+ /* A function to do additional symbol processing after reading the
+ entire ELF symbol table. */
+ boolean (*elf_backend_symbol_table_processing) PARAMS ((bfd *,
+ elf_symbol_type *,
+ unsigned int));
+
+ /* A function to set the type of the info field. Processor-specific
+ types should be handled here. */
+ int (*elf_backend_get_symbol_type) PARAMS (( Elf_Internal_Sym *, int));
+
+ /* A function to do additional processing on the ELF section header
+ just before writing it out. This is used to set the flags and
+ type fields for some sections, or to actually write out data for
+ unusual sections. */
+ boolean (*elf_backend_section_processing) PARAMS ((bfd *,
+ Elf32_Internal_Shdr *));
+
+ /* A function to handle unusual section types when creating BFD
+ sections from ELF sections. */
+ boolean (*elf_backend_section_from_shdr) PARAMS ((bfd *,
+ Elf32_Internal_Shdr *,
+ char *));
+
+ /* A function to set up the ELF section header for a BFD section in
+ preparation for writing it out. This is where the flags and type
+ fields are set for unusual sections. */
+ boolean (*elf_backend_fake_sections) PARAMS ((bfd *, Elf32_Internal_Shdr *,
+ asection *));
+
+ /* A function to get the ELF section index for a BFD section. If
+ this returns true, the section was found. If it is a normal ELF
+ section, *RETVAL should be left unchanged. If it is not a normal
+ ELF section *RETVAL should be set to the SHN_xxxx index. */
+ boolean (*elf_backend_section_from_bfd_section)
+ PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *retval));
+
+ /* If this field is not NULL, it is called by the add_symbols phase
+ of a link just before adding a symbol to the global linker hash
+ table. It may modify any of the fields as it wishes. If *NAME
+ is set to NULL, the symbol will be skipped rather than being
+ added to the hash table. This function is responsible for
+ handling all processor dependent symbol bindings and section
+ indices, and must set at least *FLAGS and *SEC for each processor
+ dependent case; failure to do so will cause a link error. */
+ boolean (*elf_add_symbol_hook)
+ PARAMS ((bfd *abfd, struct bfd_link_info *info,
+ const Elf_Internal_Sym *, const char **name,
+ flagword *flags, asection **sec, bfd_vma *value));
+
+ /* If this field is not NULL, it is called by the elf_link_output_sym
+ phase of a link for each symbol which will appear in the object file. */
+ boolean (*elf_backend_link_output_symbol_hook)
+ PARAMS ((bfd *, struct bfd_link_info *info, const char *,
+ Elf_Internal_Sym *, asection *));
+
+ /* The CREATE_DYNAMIC_SECTIONS function is called by the ELF backend
+ linker the first time it encounters a dynamic object in the link.
+ This function must create any sections required for dynamic
+ linking. The ABFD argument is a dynamic object. The .interp,
+ .dynamic, .dynsym, .dynstr, and .hash functions have already been
+ created, and this function may modify the section flags if
+ desired. This function will normally create the .got and .plt
+ sections, but different backends have different requirements. */
+ boolean (*elf_backend_create_dynamic_sections)
+ PARAMS ((bfd *abfd, struct bfd_link_info *info));
+
+ /* The CHECK_RELOCS function is called by the add_symbols phase of
+ the ELF backend linker. It is called once for each section with
+ relocs of an object file, just after the symbols for the object
+ file have been added to the global linker hash table. The
+ function must look through the relocs and do any special handling
+ required. This generally means allocating space in the global
+ offset table, and perhaps allocating space for a reloc. The
+ relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero. */
+ boolean (*check_relocs)
+ PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *o,
+ const Elf_Internal_Rela *relocs));
+
+ /* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend
+ linker for every symbol which is defined by a dynamic object and
+ referenced by a regular object. This is called after all the
+ input files have been seen, but before the SIZE_DYNAMIC_SECTIONS
+ function has been called. The hash table entry should be
+ bfd_link_hash_defined ore bfd_link_hash_defweak, and it should be
+ defined in a section from a dynamic object. Dynamic object
+ sections are not included in the final link, and this function is
+ responsible for changing the value to something which the rest of
+ the link can deal with. This will normally involve adding an
+ entry to the .plt or .got or some such section, and setting the
+ symbol to point to that. */
+ boolean (*elf_backend_adjust_dynamic_symbol)
+ PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
+
+ /* The ALWAYS_SIZE_SECTIONS function is called by the backend linker
+ after all the linker input files have been seen but before the
+ section sizes have been set. This is called after
+ ADJUST_DYNAMIC_SYMBOL, but before SIZE_DYNAMIC_SECTIONS. */
+ boolean (*elf_backend_always_size_sections)
+ PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
+
+ /* The SIZE_DYNAMIC_SECTIONS function is called by the ELF backend
+ linker after all the linker input files have been seen but before
+ the sections sizes have been set. This is called after
+ ADJUST_DYNAMIC_SYMBOL has been called on all appropriate symbols.
+ It is only called when linking against a dynamic object. It must
+ set the sizes of the dynamic sections, and may fill in their
+ contents as well. The generic ELF linker can handle the .dynsym,
+ .dynstr and .hash sections. This function must handle the
+ .interp section and any sections created by the
+ CREATE_DYNAMIC_SECTIONS entry point. */
+ boolean (*elf_backend_size_dynamic_sections)
+ PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
+
+ /* The RELOCATE_SECTION function is called by the ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjust the section contents as
+ necessary, and (if using Rela relocs and generating a
+ relocateable output file) adjusting the reloc addend as
+ necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+ boolean (*elf_backend_relocate_section)
+ PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
+ bfd *input_bfd, asection *input_section, bfd_byte *contents,
+ Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
+ asection **local_sections));
+
+ /* The FINISH_DYNAMIC_SYMBOL function is called by the ELF backend
+ linker just before it writes a symbol out to the .dynsym section.
+ The processor backend may make any required adjustment to the
+ symbol. It may also take the opportunity to set contents of the
+ dynamic sections. Note that FINISH_DYNAMIC_SYMBOL is called on
+ all .dynsym symbols, while ADJUST_DYNAMIC_SYMBOL is only called
+ on those symbols which are defined by a dynamic object. */
+ boolean (*elf_backend_finish_dynamic_symbol)
+ PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
+ struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
+
+ /* The FINISH_DYNAMIC_SECTIONS function is called by the ELF backend
+ linker just before it writes all the dynamic sections out to the
+ output file. The FINISH_DYNAMIC_SYMBOL will have been called on
+ all dynamic symbols. */
+ boolean (*elf_backend_finish_dynamic_sections)
+ PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
+
+ /* A function to do any beginning processing needed for the ELF file
+ before building the ELF headers and computing file positions. */
+ void (*elf_backend_begin_write_processing)
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+ /* A function to do any final processing needed for the ELF file
+ before writing it out. The LINKER argument is true if this BFD
+ was created by the ELF backend linker. */
+ void (*elf_backend_final_write_processing)
+ PARAMS ((bfd *, boolean linker));
+
+ /* This function is called by get_program_header_size. It should
+ return the number of additional program segments which this BFD
+ will need. It should return -1 on error. */
+ int (*elf_backend_additional_program_headers) PARAMS ((bfd *));
+
+ /* This function is called to modify an existing segment map in a
+ backend specific fashion. */
+ boolean (*elf_backend_modify_segment_map) PARAMS ((bfd *));
+
+ /* This function is called during section gc to discover the section a
+ particular relocation refers to. It need not be defined for hosts
+ that have no queer relocation types. */
+ asection * (*gc_mark_hook)
+ PARAMS ((bfd *abfd, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *h, Elf_Internal_Sym *));
+
+ /* This function, if defined, is called during the sweep phase of gc
+ in order that a backend might update any data structures it might
+ be maintaining. */
+ boolean (*gc_sweep_hook)
+ PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *o,
+ const Elf_Internal_Rela *relocs));
+
+ /* The swapping table to use when dealing with ECOFF information.
+ Used for the MIPS ELF .mdebug section. */
+ const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
+
+ /* Alternate EM_xxxx machine codes for this backend. */
+ int elf_machine_alt1;
+ int elf_machine_alt2;
+
+ const struct elf_size_info *s;
+
+ /* offset of the _GLOBAL_OFFSET_TABLE_ symbol from the start of the
+ .got section */
+ bfd_vma got_symbol_offset;
+
+ /* The size in bytes of the headers for the GOT and PLT. This includes
+ the so-called reserved entries on some systems. */
+ bfd_vma got_header_size;
+ bfd_vma plt_header_size;
+
+ unsigned want_got_plt : 1;
+ unsigned plt_readonly : 1;
+ unsigned want_plt_sym : 1;
+ unsigned plt_not_loaded : 1;
+ unsigned plt_alignment : 4;
+ unsigned can_gc_sections : 1;
+};
+
+/* Information stored for each BFD section in an ELF file. This
+ structure is allocated by elf_new_section_hook. */
+
+struct bfd_elf_section_data
+{
+ /* The ELF header for this section. */
+ Elf_Internal_Shdr this_hdr;
+ /* The ELF header for the reloc section associated with this
+ section, if any. */
+ Elf_Internal_Shdr rel_hdr;
+ /* If there is a second reloc section associated with this section,
+ as can happen on Irix 6, this field points to the header. */
+ Elf_Internal_Shdr *rel_hdr2;
+ /* The ELF section number of this section. Only used for an output
+ file. */
+ int this_idx;
+ /* The ELF section number of the reloc section associated with this
+ section, if any. Only used for an output file. */
+ int rel_idx;
+ /* Used by the backend linker to store the symbol hash table entries
+ associated with relocs against global symbols. */
+ struct elf_link_hash_entry **rel_hashes;
+ /* A pointer to the swapped relocs. If the section uses REL relocs,
+ rather than RELA, all the r_addend fields will be zero. This
+ pointer may be NULL. It is used by the backend linker. */
+ Elf_Internal_Rela *relocs;
+ /* Used by the backend linker when generating a shared library to
+ record the dynamic symbol index for a section symbol
+ corresponding to this section. */
+ long dynindx;
+ /* A pointer used for .stab linking optimizations. */
+ PTR stab_info;
+ /* A pointer available for the processor specific ELF backend. */
+ PTR tdata;
+};
+
+#define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd)
+
+#define get_elf_backend_data(abfd) \
+ ((struct elf_backend_data *) (abfd)->xvec->backend_data)
+
+/* Enumeration to specify the special section. */
+typedef enum elf_linker_section_enum
+{
+ LINKER_SECTION_UNKNOWN, /* not used */
+ LINKER_SECTION_GOT, /* .got section for global offset pointers */
+ LINKER_SECTION_PLT, /* .plt section for generated procedure stubs */
+ LINKER_SECTION_SDATA, /* .sdata/.sbss section for PowerPC */
+ LINKER_SECTION_SDATA2, /* .sdata2/.sbss2 section for PowerPC */
+ LINKER_SECTION_MAX /* # of linker sections */
+} elf_linker_section_enum_t;
+
+/* Sections created by the linker. */
+
+typedef struct elf_linker_section
+{
+ char *name; /* name of the section */
+ char *rel_name; /* name of the associated .rel{,a}. section */
+ char *bss_name; /* name of a related .bss section */
+ char *sym_name; /* name of symbol to reference this section */
+ asection *section; /* pointer to the section */
+ asection *bss_section; /* pointer to the bss section associated with this */
+ asection *rel_section; /* pointer to the relocations needed for this section */
+ struct elf_link_hash_entry *sym_hash; /* pointer to the created symbol hash value */
+ bfd_vma initial_size; /* initial size before any linker generated allocations */
+ bfd_vma sym_offset; /* offset of symbol from beginning of section */
+ bfd_vma hole_size; /* size of reserved address hole in allocation */
+ bfd_vma hole_offset; /* current offset for the hole */
+ bfd_vma max_hole_offset; /* maximum offset for the hole */
+ elf_linker_section_enum_t which; /* which section this is */
+ boolean hole_written_p; /* whether the hole has been initialized */
+ unsigned int alignment; /* alignment for the section */
+ flagword flags; /* flags to use to create the section */
+} elf_linker_section_t;
+
+/* Linked list of allocated pointer entries. This hangs off of the symbol lists, and
+ provides allows us to return different pointers, based on different addend's. */
+
+typedef struct elf_linker_section_pointers
+{
+ struct elf_linker_section_pointers *next; /* next allocated pointer for this symbol */
+ bfd_vma offset; /* offset of pointer from beginning of section */
+ bfd_signed_vma addend; /* addend used */
+ elf_linker_section_enum_t which; /* which linker section this is */
+ boolean written_address_p; /* whether address was written yet */
+} elf_linker_section_pointers_t;
+
+/* Some private data is stashed away for future use using the tdata pointer
+ in the bfd structure. */
+
+struct elf_obj_tdata
+{
+ Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */
+ Elf_Internal_Shdr **elf_sect_ptr;
+ Elf_Internal_Phdr *phdr;
+ struct elf_segment_map *segment_map;
+ struct bfd_strtab_hash *strtab_ptr;
+ int num_locals;
+ int num_globals;
+ asymbol **section_syms; /* STT_SECTION symbols for each section */
+ Elf_Internal_Shdr symtab_hdr;
+ Elf_Internal_Shdr shstrtab_hdr;
+ Elf_Internal_Shdr strtab_hdr;
+ Elf_Internal_Shdr dynsymtab_hdr;
+ Elf_Internal_Shdr dynstrtab_hdr;
+ Elf_Internal_Shdr dynversym_hdr;
+ Elf_Internal_Shdr dynverref_hdr;
+ Elf_Internal_Shdr dynverdef_hdr;
+ unsigned int symtab_section, shstrtab_section;
+ unsigned int strtab_section, dynsymtab_section;
+ unsigned int dynversym_section, dynverdef_section, dynverref_section;
+ file_ptr next_file_pos;
+#if 0
+ /* we don't need these inside bfd anymore, and I think
+ these weren't used outside bfd. */
+ void *prstatus; /* The raw /proc prstatus structure */
+ void *prpsinfo; /* The raw /proc prpsinfo structure */
+#endif
+ bfd_vma gp; /* The gp value (MIPS only, for now) */
+ unsigned int gp_size; /* The gp size (MIPS only, for now) */
+
+ /* Information grabbed from an elf core file. */
+ int core_signal;
+ int core_pid;
+ int core_lwpid;
+ char* core_program;
+ char* core_command;
+
+ /* This is set to true if the object was created by the backend
+ linker. */
+ boolean linker;
+
+ /* A mapping from external symbols to entries in the linker hash
+ table, used when linking. This is indexed by the symbol index
+ minus the sh_info field of the symbol table header. */
+ struct elf_link_hash_entry **sym_hashes;
+
+ /* A mapping from local symbols to offsets into the global offset
+ table, used when linking. This is indexed by the symbol index.
+ Like for the globals, we use a union and two names primarily to
+ document the intent of any particular piece of code. The field
+ should be used as a count until size_dynamic_sections, at which
+ point the contents of the .got is fixed. Afterward, if an entry
+ is -1, then the symbol does not require a global offset table entry. */
+ union
+ {
+ bfd_signed_vma *refcounts;
+ bfd_vma *offsets;
+ } local_got;
+
+ /* A mapping from local symbols to offsets into the various linker
+ sections added. This is index by the symbol index. */
+ elf_linker_section_pointers_t **linker_section_pointers;
+
+ /* The linker ELF emulation code needs to let the backend ELF linker
+ know what filename should be used for a dynamic object if the
+ dynamic object is found using a search. The emulation code then
+ sometimes needs to know what name was actually used. Until the
+ file has been added to the linker symbol table, this field holds
+ the name the linker wants. After it has been added, it holds the
+ name actually used, which will be the DT_SONAME entry if there is
+ one. */
+ const char *dt_name;
+
+ /* Irix 5 often screws up the symbol table, sorting local symbols
+ after global symbols. This flag is set if the symbol table in
+ this BFD appears to be screwed up. If it is, we ignore the
+ sh_info field in the symbol table header, and always read all the
+ symbols. */
+ boolean bad_symtab;
+
+ /* Records the result of `get_program_header_size'. */
+ bfd_size_type program_header_size;
+
+ /* Used by find_nearest_line entry point. */
+ PTR line_info;
+
+ /* Used by MIPS ELF find_nearest_line entry point. The structure
+ could be included directly in this one, but there's no point to
+ wasting the memory just for the infrequently called
+ find_nearest_line. */
+ struct mips_elf_find_line *find_line_info;
+
+ /* A place to stash dwarf1 info for this bfd. */
+ struct dwarf1_debug *dwarf1_find_line_info;
+
+ /* A place to stash dwarf2 info for this bfd. */
+ struct dwarf2_debug *dwarf2_find_line_info;
+
+ /* An array of stub sections indexed by symbol number, used by the
+ MIPS ELF linker. FIXME: We should figure out some way to only
+ include this field for a MIPS ELF target. */
+ asection **local_stubs;
+
+ /* Used to determine if the e_flags field has been initialized */
+ boolean flags_init;
+
+ /* Number of symbol version definitions we are about to emit. */
+ unsigned int cverdefs;
+
+ /* Number of symbol version references we are about to emit. */
+ unsigned int cverrefs;
+
+ /* Symbol version definitions in external objects. */
+ Elf_Internal_Verdef *verdef;
+
+ /* Symbol version references to external objects. */
+ Elf_Internal_Verneed *verref;
+
+ /* Linker sections that we are interested in. */
+ struct elf_linker_section *linker_section[ (int)LINKER_SECTION_MAX ];
+};
+
+#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
+#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header)
+#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
+#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr)
+#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
+#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section)
+#define elf_dynversym(bfd) (elf_tdata(bfd) -> dynversym_section)
+#define elf_dynverdef(bfd) (elf_tdata(bfd) -> dynverdef_section)
+#define elf_dynverref(bfd) (elf_tdata(bfd) -> dynverref_section)
+#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals)
+#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals)
+#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms)
+#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo)
+#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus)
+#define elf_gp(bfd) (elf_tdata(bfd) -> gp)
+#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size)
+#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes)
+#define elf_local_got_refcounts(bfd) (elf_tdata(bfd) -> local_got.refcounts)
+#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
+#define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers)
+#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
+#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
+#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
+#define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n])
+
+extern void _bfd_elf_swap_verdef_in
+ PARAMS ((bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *));
+extern void _bfd_elf_swap_verdef_out
+ PARAMS ((bfd *, const Elf_Internal_Verdef *, Elf_External_Verdef *));
+extern void _bfd_elf_swap_verdaux_in
+ PARAMS ((bfd *, const Elf_External_Verdaux *, Elf_Internal_Verdaux *));
+extern void _bfd_elf_swap_verdaux_out
+ PARAMS ((bfd *, const Elf_Internal_Verdaux *, Elf_External_Verdaux *));
+extern void _bfd_elf_swap_verneed_in
+ PARAMS ((bfd *, const Elf_External_Verneed *, Elf_Internal_Verneed *));
+extern void _bfd_elf_swap_verneed_out
+ PARAMS ((bfd *, const Elf_Internal_Verneed *, Elf_External_Verneed *));
+extern void _bfd_elf_swap_vernaux_in
+ PARAMS ((bfd *, const Elf_External_Vernaux *, Elf_Internal_Vernaux *));
+extern void _bfd_elf_swap_vernaux_out
+ PARAMS ((bfd *, const Elf_Internal_Vernaux *, Elf_External_Vernaux *));
+extern void _bfd_elf_swap_versym_in
+ PARAMS ((bfd *, const Elf_External_Versym *, Elf_Internal_Versym *));
+extern void _bfd_elf_swap_versym_out
+ PARAMS ((bfd *, const Elf_Internal_Versym *, Elf_External_Versym *));
+
+extern int _bfd_elf_section_from_bfd_section PARAMS ((bfd *, asection *));
+extern char *bfd_elf_string_from_elf_section
+ PARAMS ((bfd *, unsigned, unsigned));
+extern char *bfd_elf_get_str_section PARAMS ((bfd *, unsigned));
+
+extern boolean _bfd_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
+extern void bfd_elf_print_symbol PARAMS ((bfd *, PTR, asymbol *,
+ bfd_print_symbol_type));
+#define elf_string_from_elf_strtab(abfd,strindex) \
+ bfd_elf_string_from_elf_section(abfd,elf_elfheader(abfd)->e_shstrndx,strindex)
+
+#define bfd_elf32_print_symbol bfd_elf_print_symbol
+#define bfd_elf64_print_symbol bfd_elf_print_symbol
+
+extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *));
+
+extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
+ arelent *,
+ asymbol *,
+ PTR,
+ asection *,
+ bfd *,
+ char **));
+extern boolean bfd_elf_mkobject PARAMS ((bfd *));
+extern boolean bfd_elf_mkcorefile PARAMS ((bfd *));
+extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
+extern boolean _bfd_elf_make_section_from_shdr
+ PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, const char *name));
+extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
+ PARAMS ((bfd *));
+extern boolean _bfd_elf_link_hash_table_init
+ PARAMS ((struct elf_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+extern boolean _bfd_elf_slurp_version_tables PARAMS ((bfd *));
+
+extern boolean _bfd_elf_copy_private_symbol_data
+ PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
+extern boolean _bfd_elf_copy_private_section_data
+ PARAMS ((bfd *, asection *, bfd *, asection *));
+extern boolean _bfd_elf_write_object_contents PARAMS ((bfd *));
+extern boolean _bfd_elf_write_corefile_contents PARAMS ((bfd *));
+extern boolean _bfd_elf_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
+ file_ptr,
+ bfd_size_type));
+extern long _bfd_elf_get_symtab_upper_bound PARAMS ((bfd *));
+extern long _bfd_elf_get_symtab PARAMS ((bfd *, asymbol **));
+extern long _bfd_elf_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
+extern long _bfd_elf_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **));
+extern long _bfd_elf_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
+extern long _bfd_elf_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
+ arelent **, asymbol **));
+extern long _bfd_elf_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
+extern long _bfd_elf_canonicalize_dynamic_reloc PARAMS ((bfd *, arelent **,
+ asymbol **));
+extern asymbol *_bfd_elf_make_empty_symbol PARAMS ((bfd *));
+extern void _bfd_elf_get_symbol_info PARAMS ((bfd *, asymbol *,
+ symbol_info *));
+extern boolean _bfd_elf_is_local_label_name PARAMS ((bfd *, const char *));
+extern alent *_bfd_elf_get_lineno PARAMS ((bfd *, asymbol *));
+extern boolean _bfd_elf_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
+ unsigned long));
+extern boolean _bfd_elf_find_nearest_line PARAMS ((bfd *, asection *,
+ asymbol **,
+ bfd_vma, CONST char **,
+ CONST char **,
+ unsigned int *));
+#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
+#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+extern int _bfd_elf_sizeof_headers PARAMS ((bfd *, boolean));
+extern boolean _bfd_elf_new_section_hook PARAMS ((bfd *, asection *));
+
+/* If the target doesn't have reloc handling written yet: */
+extern void _bfd_elf_no_info_to_howto PARAMS ((bfd *, arelent *,
+ Elf_Internal_Rela *));
+
+extern boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex));
+extern boolean bfd_section_from_phdr PARAMS ((bfd *, Elf_Internal_Phdr *, int));
+
+extern int _bfd_elf_symbol_from_bfd_symbol PARAMS ((bfd *, asymbol **));
+
+asection *bfd_section_from_elf_index PARAMS ((bfd *, unsigned int));
+boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *,
+ struct bfd_link_info *));
+struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void));
+boolean
+_bfd_elf_link_record_dynamic_symbol PARAMS ((struct bfd_link_info *,
+ struct elf_link_hash_entry *));
+boolean
+_bfd_elf_compute_section_file_positions PARAMS ((bfd *,
+ struct bfd_link_info *));
+void _bfd_elf_assign_file_positions_for_relocs PARAMS ((bfd *));
+file_ptr _bfd_elf_assign_file_position_for_section PARAMS ((Elf_Internal_Shdr *,
+ file_ptr,
+ boolean));
+
+extern boolean _bfd_elf_validate_reloc PARAMS ((bfd *, arelent *));
+
+boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *,
+ struct bfd_link_info *));
+boolean _bfd_elf_create_got_section PARAMS ((bfd *,
+ struct bfd_link_info *));
+
+elf_linker_section_t *_bfd_elf_create_linker_section
+ PARAMS ((bfd *abfd,
+ struct bfd_link_info *info,
+ enum elf_linker_section_enum,
+ elf_linker_section_t *defaults));
+
+elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section
+ PARAMS ((elf_linker_section_pointers_t *linker_pointers,
+ bfd_signed_vma addend,
+ elf_linker_section_enum_t which));
+
+boolean bfd_elf32_create_pointer_linker_section
+ PARAMS ((bfd *abfd,
+ struct bfd_link_info *info,
+ elf_linker_section_t *lsect,
+ struct elf_link_hash_entry *h,
+ const Elf32_Internal_Rela *rel));
+
+bfd_vma bfd_elf32_finish_pointer_linker_section
+ PARAMS ((bfd *output_abfd,
+ bfd *input_bfd,
+ struct bfd_link_info *info,
+ elf_linker_section_t *lsect,
+ struct elf_link_hash_entry *h,
+ bfd_vma relocation,
+ const Elf32_Internal_Rela *rel,
+ int relative_reloc));
+
+boolean bfd_elf64_create_pointer_linker_section
+ PARAMS ((bfd *abfd,
+ struct bfd_link_info *info,
+ elf_linker_section_t *lsect,
+ struct elf_link_hash_entry *h,
+ const Elf64_Internal_Rela *rel));
+
+bfd_vma bfd_elf64_finish_pointer_linker_section
+ PARAMS ((bfd *output_abfd,
+ bfd *input_bfd,
+ struct bfd_link_info *info,
+ elf_linker_section_t *lsect,
+ struct elf_link_hash_entry *h,
+ bfd_vma relocation,
+ const Elf64_Internal_Rela *rel,
+ int relative_reloc));
+
+boolean _bfd_elf_make_linker_section_rela
+ PARAMS ((bfd *dynobj,
+ elf_linker_section_t *lsect,
+ int alignment));
+
+boolean _bfd_elfcore_section_from_phdr
+ PARAMS ((bfd *, Elf_Internal_Phdr *, int));
+
+extern const bfd_target *bfd_elf32_object_p PARAMS ((bfd *));
+extern const bfd_target *bfd_elf32_core_file_p PARAMS ((bfd *));
+extern char *bfd_elf32_core_file_failing_command PARAMS ((bfd *));
+extern int bfd_elf32_core_file_failing_signal PARAMS ((bfd *));
+extern boolean bfd_elf32_core_file_matches_executable_p PARAMS ((bfd *,
+ bfd *));
+
+extern boolean bfd_elf32_bfd_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_elf32_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+extern void bfd_elf32_swap_symbol_in
+ PARAMS ((bfd *, const Elf32_External_Sym *, Elf_Internal_Sym *));
+extern void bfd_elf32_swap_symbol_out
+ PARAMS ((bfd *, const Elf_Internal_Sym *, PTR));
+extern void bfd_elf32_swap_reloc_in
+ PARAMS ((bfd *, const Elf32_External_Rel *, Elf_Internal_Rel *));
+extern void bfd_elf32_swap_reloc_out
+ PARAMS ((bfd *, const Elf_Internal_Rel *, Elf32_External_Rel *));
+extern void bfd_elf32_swap_reloca_in
+ PARAMS ((bfd *, const Elf32_External_Rela *, Elf_Internal_Rela *));
+extern void bfd_elf32_swap_reloca_out
+ PARAMS ((bfd *, const Elf_Internal_Rela *, Elf32_External_Rela *));
+extern void bfd_elf32_swap_phdr_in
+ PARAMS ((bfd *, const Elf32_External_Phdr *, Elf_Internal_Phdr *));
+extern void bfd_elf32_swap_phdr_out
+ PARAMS ((bfd *, const Elf_Internal_Phdr *, Elf32_External_Phdr *));
+extern void bfd_elf32_swap_dyn_in
+ PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+extern void bfd_elf32_swap_dyn_out
+ PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf32_External_Dyn *));
+extern long bfd_elf32_slurp_symbol_table
+ PARAMS ((bfd *, asymbol **, boolean));
+extern boolean bfd_elf32_write_shdrs_and_ehdr PARAMS ((bfd *));
+extern int bfd_elf32_write_out_phdrs
+ PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
+extern boolean bfd_elf32_add_dynamic_entry
+ PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
+extern boolean bfd_elf32_link_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern Elf_Internal_Rela *_bfd_elf32_link_read_relocs
+ PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
+
+extern const bfd_target *bfd_elf64_object_p PARAMS ((bfd *));
+extern const bfd_target *bfd_elf64_core_file_p PARAMS ((bfd *));
+extern char *bfd_elf64_core_file_failing_command PARAMS ((bfd *));
+extern int bfd_elf64_core_file_failing_signal PARAMS ((bfd *));
+extern boolean bfd_elf64_core_file_matches_executable_p PARAMS ((bfd *,
+ bfd *));
+extern boolean bfd_elf64_bfd_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean bfd_elf64_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+extern void bfd_elf64_swap_symbol_in
+ PARAMS ((bfd *, const Elf64_External_Sym *, Elf_Internal_Sym *));
+extern void bfd_elf64_swap_symbol_out
+ PARAMS ((bfd *, const Elf_Internal_Sym *, PTR));
+extern void bfd_elf64_swap_reloc_in
+ PARAMS ((bfd *, const Elf64_External_Rel *, Elf_Internal_Rel *));
+extern void bfd_elf64_swap_reloc_out
+ PARAMS ((bfd *, const Elf_Internal_Rel *, Elf64_External_Rel *));
+extern void bfd_elf64_swap_reloca_in
+ PARAMS ((bfd *, const Elf64_External_Rela *, Elf_Internal_Rela *));
+extern void bfd_elf64_swap_reloca_out
+ PARAMS ((bfd *, const Elf_Internal_Rela *, Elf64_External_Rela *));
+extern void bfd_elf64_swap_phdr_in
+ PARAMS ((bfd *, const Elf64_External_Phdr *, Elf_Internal_Phdr *));
+extern void bfd_elf64_swap_phdr_out
+ PARAMS ((bfd *, const Elf_Internal_Phdr *, Elf64_External_Phdr *));
+extern void bfd_elf64_swap_dyn_in
+ PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+extern void bfd_elf64_swap_dyn_out
+ PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf64_External_Dyn *));
+extern long bfd_elf64_slurp_symbol_table
+ PARAMS ((bfd *, asymbol **, boolean));
+extern boolean bfd_elf64_write_shdrs_and_ehdr PARAMS ((bfd *));
+extern int bfd_elf64_write_out_phdrs
+ PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
+extern boolean bfd_elf64_add_dynamic_entry
+ PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
+extern boolean bfd_elf64_link_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
+ PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
+
+#define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
+#define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
+
+extern boolean _bfd_elf_close_and_cleanup PARAMS ((bfd *));
+extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
+ PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR,
+ asection *, bfd *, char **));
+
+boolean _bfd_elf32_gc_sections
+ PARAMS ((bfd *abfd, struct bfd_link_info *info));
+boolean _bfd_elf32_gc_common_finalize_got_offsets
+ PARAMS ((bfd *abfd, struct bfd_link_info *info));
+boolean _bfd_elf32_gc_common_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+boolean _bfd_elf32_gc_record_vtinherit
+ PARAMS ((bfd *, asection *, struct elf_link_hash_entry *, bfd_vma));
+boolean _bfd_elf32_gc_record_vtentry
+ PARAMS ((bfd *, asection *, struct elf_link_hash_entry *, bfd_vma));
+
+boolean _bfd_elf64_gc_sections
+ PARAMS ((bfd *abfd, struct bfd_link_info *info));
+boolean _bfd_elf64_gc_common_finalize_got_offsets
+ PARAMS ((bfd *abfd, struct bfd_link_info *info));
+boolean _bfd_elf64_gc_common_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+boolean _bfd_elf64_gc_record_vtinherit
+ PARAMS ((bfd *, asection *, struct elf_link_hash_entry *, bfd_vma));
+boolean _bfd_elf64_gc_record_vtentry
+ PARAMS ((bfd *, asection *, struct elf_link_hash_entry *, bfd_vma));
+
+/* MIPS ELF specific routines. */
+
+extern boolean _bfd_mips_elf_object_p PARAMS ((bfd *));
+extern boolean _bfd_mips_elf_section_from_shdr
+ PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
+extern boolean _bfd_mips_elf_fake_sections
+ PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
+extern boolean _bfd_mips_elf_section_from_bfd_section
+ PARAMS ((bfd *, Elf_Internal_Shdr *, asection *, int *));
+extern boolean _bfd_mips_elf_section_processing
+ PARAMS ((bfd *, Elf_Internal_Shdr *));
+extern void _bfd_mips_elf_symbol_processing PARAMS ((bfd *, asymbol *));
+extern boolean _bfd_mips_elf_read_ecoff_info
+ PARAMS ((bfd *, asection *, struct ecoff_debug_info *));
+extern void _bfd_mips_elf_final_write_processing PARAMS ((bfd *, boolean));
+extern bfd_reloc_status_type _bfd_mips_elf_hi16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+extern bfd_reloc_status_type _bfd_mips_elf_lo16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+extern bfd_reloc_status_type _bfd_mips_elf_gprel16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+extern bfd_reloc_status_type _bfd_mips_elf_got16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+extern bfd_reloc_status_type _bfd_mips_elf_gprel32_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+extern boolean _bfd_mips_elf_set_private_flags PARAMS ((bfd *, flagword));
+extern boolean _bfd_mips_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+extern boolean _bfd_mips_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+extern boolean _bfd_mips_elf_find_nearest_line
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
+ const char **, unsigned int *));
+extern boolean _bfd_mips_elf_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+
+#endif /* _LIBELF_H_ */
diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c
new file mode 100644
index 00000000000..53d193d8704
--- /dev/null
+++ b/bfd/elf-m10200.c
@@ -0,0 +1,1525 @@
+/* Matsushita 10200 specific support for 32-bit ELF
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void mn10200_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static boolean mn10200_elf_relax_delete_bytes
+ PARAMS ((bfd *, asection *, bfd_vma, int));
+static boolean mn10200_elf_symbol_address_p
+ PARAMS ((bfd *, asection *, Elf32_External_Sym *, bfd_vma));
+
+/* We have to use RELA instructions since md_apply_fix3 in the assembler
+ does absolutely nothing. */
+#define USE_RELA
+
+enum reloc_type
+{
+ R_MN10200_NONE = 0,
+ R_MN10200_32,
+ R_MN10200_16,
+ R_MN10200_8,
+ R_MN10200_24,
+ R_MN10200_PCREL8,
+ R_MN10200_PCREL16,
+ R_MN10200_PCREL24,
+ R_MN10200_MAX
+};
+
+static reloc_howto_type elf_mn10200_howto_table[] =
+{
+ /* Dummy relocation. Does nothing. */
+ HOWTO (R_MN10200_NONE,
+ 0,
+ 2,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_NONE",
+ false,
+ 0,
+ 0,
+ false),
+ /* Standard 32 bit reloc. */
+ HOWTO (R_MN10200_32,
+ 0,
+ 2,
+ 32,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_32",
+ false,
+ 0xffffffff,
+ 0xffffffff,
+ false),
+ /* Standard 16 bit reloc. */
+ HOWTO (R_MN10200_16,
+ 0,
+ 1,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_16",
+ false,
+ 0xffff,
+ 0xffff,
+ false),
+ /* Standard 8 bit reloc. */
+ HOWTO (R_MN10200_8,
+ 0,
+ 0,
+ 8,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_8",
+ false,
+ 0xff,
+ 0xff,
+ false),
+ /* Standard 24 bit reloc. */
+ HOWTO (R_MN10200_24,
+ 0,
+ 2,
+ 24,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_24",
+ false,
+ 0xffffff,
+ 0xffffff,
+ false),
+ /* Simple 8 pc-relative reloc. */
+ HOWTO (R_MN10200_PCREL8,
+ 0,
+ 0,
+ 8,
+ true,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_PCREL8",
+ false,
+ 0xff,
+ 0xff,
+ true),
+ /* Simple 16 pc-relative reloc. */
+ HOWTO (R_MN10200_PCREL16,
+ 0,
+ 1,
+ 16,
+ true,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_PCREL16",
+ false,
+ 0xffff,
+ 0xffff,
+ true),
+ /* Simple 32bit pc-relative reloc with a 1 byte adjustment
+ to get the pc-relative offset correct. */
+ HOWTO (R_MN10200_PCREL24,
+ 0,
+ 2,
+ 24,
+ true,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10200_PCREL24",
+ false,
+ 0xffffff,
+ 0xffffff,
+ true),
+};
+
+struct mn10200_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct mn10200_reloc_map mn10200_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_MN10200_NONE, },
+ { BFD_RELOC_32, R_MN10200_32, },
+ { BFD_RELOC_16, R_MN10200_16, },
+ { BFD_RELOC_8, R_MN10200_8, },
+ { BFD_RELOC_24, R_MN10200_24, },
+ { BFD_RELOC_8_PCREL, R_MN10200_PCREL8, },
+ { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
+ { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
+ i++)
+ {
+ if (mn10200_reloc_map[i].bfd_reloc_val == code)
+ return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an MN10200 ELF reloc. */
+
+static void
+mn10200_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_MN10200_MAX);
+ cache_ptr->howto = &elf_mn10200_howto_table[r_type];
+}
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, offset, value,
+ addend, info, sym_sec, is_local)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma offset;
+ bfd_vma value;
+ bfd_vma addend;
+ struct bfd_link_info *info;
+ asection *sym_sec;
+ int is_local;
+{
+ unsigned long r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+
+ switch (r_type)
+ {
+
+ case R_MN10200_NONE:
+ return bfd_reloc_ok;
+
+ case R_MN10200_32:
+ value += addend;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10200_16:
+ value += addend;
+
+ if ((long)value > 0x7fff || (long)value < -0x8000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10200_8:
+ value += addend;
+
+ if ((long)value > 0x7f || (long)value < -0x80)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10200_24:
+ value += addend;
+
+ if ((long)value > 0x7fffff || (long)value < -0x800000)
+ return bfd_reloc_overflow;
+
+ value &= 0xffffff;
+ value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10200_PCREL8:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= (offset + 1);
+ value += addend;
+
+ if ((long)value > 0xff || (long)value < -0x100)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10200_PCREL16:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= (offset + 2);
+ value += addend;
+
+ if ((long)value > 0xffff || (long)value < -0x10000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10200_PCREL24:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= (offset + 3);
+ value += addend;
+
+ if ((long)value > 0xffffff || (long)value < -0x1000000)
+ return bfd_reloc_overflow;
+
+ value &= 0xffffff;
+ value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+
+/* Relocate an MN10200 ELF section. */
+static boolean
+mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel, *relend;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ howto = elf_mn10200_howto_table + r_type;
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ info, sec, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *name;
+ const char *msg = (const char *)0;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_undefined:
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous error");
+ goto common_error;
+
+ default:
+ msg = _("internal error: unknown error");
+ /* fall through */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, msg, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* This function handles relaxing for the mn10200.
+
+ There's quite a few relaxing opportunites available on the mn10200:
+
+ * jsr:24 -> jsr:16 2 bytes
+
+ * jmp:24 -> jmp:16 2 bytes
+ * jmp:16 -> bra:8 1 byte
+
+ * If the previous instruction is a conditional branch
+ around the jump/bra, we may be able to reverse its condition
+ and change its target to the jump's target. The jump/bra
+ can then be deleted. 2 bytes
+
+ * mov abs24 -> mov abs16 2 byte savings
+
+ * Most instructions which accept imm24 can relax to imm16 2 bytes
+ - Most instructions which accept imm16 can relax to imm8 1 byte
+
+ * Most instructions which accept d24 can relax to d16 2 bytes
+ - Most instructions which accept d16 can relax to d8 1 byte
+
+ abs24, imm24, d24 all look the same at the reloc level. It
+ might make the code simpler if we had different relocs for
+ the various relaxable operand types.
+
+ We don't handle imm16->imm8 or d16->d8 as they're very rare
+ and somewhat more difficult to support. */
+
+static boolean
+mn10200_elf_relax_section (abfd, sec, link_info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+ Elf32_External_Sym *extsyms = NULL;
+ Elf32_External_Sym *free_extsyms = NULL;
+
+ /* Assume nothing changes. */
+ *again = false;
+
+ /* We don't have to do anything for a relocateable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocateable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return true;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
+ continue;
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (extsyms == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ /* Go get them off disk. */
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym isym;
+ asection *sym_sec;
+
+ /* A local symbol. */
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irel->r_info),
+ &isym);
+
+ sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ symval = (isym.st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+
+ /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
+ branch/call. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
+ {
+ bfd_vma value = symval;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= (irel->r_offset + 3);
+ value += irel->r_addend;
+
+ /* See if the value will fit in 16 bits, note the high value is
+ 0x7fff + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long)value < 0x8001 && (long)value > -0x8000)
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if (code != 0xe0 && code != 0xe1)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ if (code == 0xe0)
+ bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
+ else if (code == 0xe1)
+ bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10200_PCREL16);
+
+ /* The opcode got shorter too, so we have to fix the offset. */
+ irel->r_offset -= 1;
+
+ /* Delete two bytes of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+ }
+
+ /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
+ branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
+ {
+ bfd_vma value = symval;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= (irel->r_offset + 2);
+ value += irel->r_addend;
+
+ /* See if the value will fit in 8 bits, note the high value is
+ 0x7f + 1 as the target will be one bytes closer if we are
+ able to relax. */
+ if ((long)value < 0x80 && (long)value > -0x80)
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if (code != 0xfc)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10200_PCREL8);
+
+ /* Delete one byte of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+ }
+
+ /* Try to eliminate an unconditional 8 bit pc-relative branch
+ which immediately follows a conditional 8 bit pc-relative
+ branch around the unconditional branch.
+
+ original: new:
+ bCC lab1 bCC' lab2
+ bra lab2
+ lab1: lab1:
+
+
+ This happens when the bCC can't reach lab2 at assembly time,
+ but due to other relaxations it can reach at link time. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
+ {
+ Elf_Internal_Rela *nrel;
+ bfd_vma value = symval;
+ unsigned char code;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= (irel->r_offset + 1);
+ value += irel->r_addend;
+
+ /* Do nothing if this reloc is the last byte in the section. */
+ if (irel->r_offset == sec->_cooked_size)
+ continue;
+
+ /* See if the next instruction is an unconditional pc-relative
+ branch, more often than not this test will fail, so we
+ test it first to speed things up. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+ if (code != 0xea)
+ continue;
+
+ /* Also make sure the next relocation applies to the next
+ instruction and that it's a pc-relative 8 bit branch. */
+ nrel = irel + 1;
+ if (nrel == irelend
+ || irel->r_offset + 2 != nrel->r_offset
+ || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
+ continue;
+
+ /* Make sure our destination immediately follows the
+ unconditional branch. */
+ if (symval != (sec->output_section->vma + sec->output_offset
+ + irel->r_offset + 3))
+ continue;
+
+ /* Now make sure we are a conditional branch. This may not
+ be necessary, but why take the chance.
+
+ Note these checks assume that R_MN10200_PCREL8 relocs
+ only occur on bCC and bCCx insns. If they occured
+ elsewhere, we'd need to know the start of this insn
+ for this check to be accurate. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ if (code != 0xe0 && code != 0xe1 && code != 0xe2
+ && code != 0xe3 && code != 0xe4 && code != 0xe5
+ && code != 0xe6 && code != 0xe7 && code != 0xe8
+ && code != 0xe9 && code != 0xec && code != 0xed
+ && code != 0xee && code != 0xef && code != 0xfc
+ && code != 0xfd && code != 0xfe && code != 0xff)
+ continue;
+
+ /* We also have to be sure there is no symbol/label
+ at the unconditional branch. */
+ if (mn10200_elf_symbol_address_p (abfd, sec, extsyms,
+ irel->r_offset + 1))
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Reverse the condition of the first branch. */
+ switch (code)
+ {
+ case 0xfc:
+ code = 0xfd;
+ break;
+ case 0xfd:
+ code = 0xfc;
+ break;
+ case 0xfe:
+ code = 0xff;
+ break;
+ case 0xff:
+ code = 0xfe;
+ break;
+ case 0xe8:
+ code = 0xe9;
+ break;
+ case 0xe9:
+ code = 0xe8;
+ break;
+ case 0xe0:
+ code = 0xe2;
+ break;
+ case 0xe2:
+ code = 0xe0;
+ break;
+ case 0xe3:
+ code = 0xe1;
+ break;
+ case 0xe1:
+ code = 0xe3;
+ break;
+ case 0xe4:
+ code = 0xe6;
+ break;
+ case 0xe6:
+ code = 0xe4;
+ break;
+ case 0xe7:
+ code = 0xe5;
+ break;
+ case 0xe5:
+ code = 0xe7;
+ break;
+ case 0xec:
+ code = 0xed;
+ break;
+ case 0xed:
+ code = 0xec;
+ break;
+ case 0xee:
+ code = 0xef;
+ break;
+ case 0xef:
+ code = 0xee;
+ break;
+ }
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ /* Set the reloc type and symbol for the first branch
+ from the second branch. */
+ irel->r_info = nrel->r_info;
+
+ /* Make the reloc for the second branch a null reloc. */
+ nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
+ R_MN10200_NONE);
+
+ /* Delete two bytes of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+
+ /* Try to turn a 24bit immediate, displacement or absolute address
+ into a 16bit immediate, displacement or absolute address. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
+ {
+ bfd_vma value = symval;
+
+ /* See if the value will fit in 16 bits.
+ We allow any 16bit match here. We prune those we can't
+ handle below. */
+ if ((long)value < 0x7fff && (long)value > -0x8000)
+ {
+ unsigned char code;
+
+ /* All insns which have 24bit operands are 5 bytes long,
+ the first byte will always be 0xf4, but we double check
+ it just in case. */
+
+ /* Get the first opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ if (code != 0xf4)
+ continue;
+
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ switch (code & 0xfc)
+ {
+ /* mov imm24,dn -> mov imm16,dn */
+ case 0x70:
+ /* Not safe if the high bit is on as relaxing may
+ move the value out of high mem and thus not fit
+ in a signed 16bit value. */
+ if (value & 0x8000)
+ continue;
+
+ /* Note that we've changed the reldection contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xf8 + (code & 0x03),
+ contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10200_16);
+
+ /* The opcode got shorter too, so we have to fix the
+ offset. */
+ irel->r_offset -= 1;
+
+ /* Delete two bytes of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+
+ /* mov imm24,an -> mov imm16,an
+ cmp imm24,an -> cmp imm16,an
+ mov (abs24),dn -> mov (abs16),dn
+ mov dn,(abs24) -> mov dn,(abs16)
+ movb dn,(abs24) -> movb dn,(abs16)
+ movbu (abs24),dn -> movbu (abs16),dn */
+ case 0x74:
+ case 0x7c:
+ case 0xc0:
+ case 0x40:
+ case 0x44:
+ case 0xc8:
+ /* Note that we've changed the reldection contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ if ((code & 0xfc) == 0x74)
+ code = 0xdc + (code & 0x03);
+ else if ((code & 0xfc) == 0x7c)
+ code = 0xec + (code & 0x03);
+ else if ((code & 0xfc) == 0xc0)
+ code = 0xc8 + (code & 0x03);
+ else if ((code & 0xfc) == 0x40)
+ code = 0xc0 + (code & 0x03);
+ else if ((code & 0xfc) == 0x44)
+ code = 0xc4 + (code & 0x03);
+ else if ((code & 0xfc) == 0xc8)
+ code = 0xcc + (code & 0x03);
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10200_16);
+
+ /* The opcode got shorter too, so we have to fix the
+ offset. */
+ irel->r_offset -= 1;
+
+ /* Delete two bytes of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+
+ /* cmp imm24,dn -> cmp imm16,dn
+ mov (abs24),an -> mov (abs16),an
+ mov an,(abs24) -> mov an,(abs16)
+ add imm24,dn -> add imm16,dn
+ add imm24,an -> add imm16,an
+ sub imm24,dn -> sub imm16,dn
+ sub imm24,an -> sub imm16,an
+ And all d24->d16 in memory ops. */
+ case 0x78:
+ case 0xd0:
+ case 0x50:
+ case 0x60:
+ case 0x64:
+ case 0x68:
+ case 0x6c:
+ case 0x80:
+ case 0xf0:
+ case 0x00:
+ case 0x10:
+ case 0xb0:
+ case 0x30:
+ case 0xa0:
+ case 0x20:
+ case 0x90:
+ /* Not safe if the high bit is on as relaxing may
+ move the value out of high mem and thus not fit
+ in a signed 16bit value. */
+ if (((code & 0xfc) == 0x78
+ || (code & 0xfc) == 0x60
+ || (code & 0xfc) == 0x64
+ || (code & 0xfc) == 0x68
+ || (code & 0xfc) == 0x6c
+ || (code & 0xfc) == 0x80
+ || (code & 0xfc) == 0xf0
+ || (code & 0xfc) == 0x00
+ || (code & 0xfc) == 0x10
+ || (code & 0xfc) == 0xb0
+ || (code & 0xfc) == 0x30
+ || (code & 0xfc) == 0xa0
+ || (code & 0xfc) == 0x20
+ || (code & 0xfc) == 0x90)
+ && (value & 0x8000) != 0)
+ continue;
+
+ /* Note that we've changed the reldection contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
+
+ if ((code & 0xfc) == 0x78)
+ code = 0x48 + (code & 0x03);
+ else if ((code & 0xfc) == 0xd0)
+ code = 0x30 + (code & 0x03);
+ else if ((code & 0xfc) == 0x50)
+ code = 0x20 + (code & 0x03);
+ else if ((code & 0xfc) == 0x60)
+ code = 0x18 + (code & 0x03);
+ else if ((code & 0xfc) == 0x64)
+ code = 0x08 + (code & 0x03);
+ else if ((code & 0xfc) == 0x68)
+ code = 0x1c + (code & 0x03);
+ else if ((code & 0xfc) == 0x6c)
+ code = 0x0c + (code & 0x03);
+ else if ((code & 0xfc) == 0x80)
+ code = 0xc0 + (code & 0x07);
+ else if ((code & 0xfc) == 0xf0)
+ code = 0xb0 + (code & 0x07);
+ else if ((code & 0xfc) == 0x00)
+ code = 0x80 + (code & 0x07);
+ else if ((code & 0xfc) == 0x10)
+ code = 0xa0 + (code & 0x07);
+ else if ((code & 0xfc) == 0xb0)
+ code = 0x70 + (code & 0x07);
+ else if ((code & 0xfc) == 0x30)
+ code = 0x60 + (code & 0x07);
+ else if ((code & 0xfc) == 0xa0)
+ code = 0xd0 + (code & 0x07);
+ else if ((code & 0xfc) == 0x20)
+ code = 0x90 + (code & 0x07);
+ else if ((code & 0xfc) == 0x90)
+ code = 0x50 + (code & 0x07);
+
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10200_16);
+
+ /* Delete one bytes of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 1))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+
+ /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
+ case 0xc4:
+ /* Note that we've changed the reldection contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ bfd_put_8 (abfd, 0xcc + (code & 0x03),
+ contents + irel->r_offset - 2);
+
+ bfd_put_8 (abfd, 0xb8 + (code & 0x03),
+ contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10200_16);
+
+ /* The reloc will be applied one byte in front of its
+ current location. */
+ irel->r_offset -= 1;
+
+ /* Delete one bytes of data. */
+ if (!mn10200_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 1))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ free_extsyms = NULL;
+ }
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (free_extsyms != NULL)
+ free (free_extsyms);
+ return false;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static boolean
+mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
+ bfd *abfd;
+ asection *sec;
+ bfd_vma addr;
+ int count;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf32_External_Sym *extsyms;
+ int shndx, index;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf32_External_Sym *esym, *esymend;
+ struct elf_link_hash_entry *sym_hash;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ toaddr = sec->_cooked_size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+ sec->_cooked_size -= count;
+
+ /* Adjust all the relocs. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+
+ if (isym.st_shndx == shndx
+ && isym.st_value > addr
+ && isym.st_value < toaddr)
+ {
+ isym.st_value -= count;
+ bfd_elf32_swap_symbol_out (abfd, &isym, esym);
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ esym = extsyms + symtab_hdr->sh_info;
+ esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
+ for (index = 0; esym < esymend; esym++, index++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+ sym_hash = elf_sym_hashes (abfd)[index];
+ if (isym.st_shndx == shndx
+ && ((sym_hash)->root.type == bfd_link_hash_defined
+ || (sym_hash)->root.type == bfd_link_hash_defweak)
+ && (sym_hash)->root.u.def.section == sec
+ && (sym_hash)->root.u.def.value > addr
+ && (sym_hash)->root.u.def.value < toaddr)
+ {
+ (sym_hash)->root.u.def.value -= count;
+ }
+ }
+
+ return true;
+}
+
+/* Return true if a symbol exists at the given address, else return
+ false. */
+static boolean
+mn10200_elf_symbol_address_p (abfd, sec, extsyms, addr)
+ bfd *abfd;
+ asection *sec;
+ Elf32_External_Sym *extsyms;
+ bfd_vma addr;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ int shndx;
+ Elf32_External_Sym *esym, *esymend;
+ struct elf_link_hash_entry **sym_hash, **sym_hash_end;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Examine all the symbols. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+
+ if (isym.st_shndx == shndx
+ && isym.st_value == addr)
+ return true;
+ }
+
+ sym_hash = elf_sym_hashes (abfd);
+ sym_hash_end = (sym_hash
+ + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info));
+ for (; sym_hash < sym_hash_end; sym_hash++)
+ {
+ if (((*sym_hash)->root.type == bfd_link_hash_defined
+ || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ && (*sym_hash)->root.u.def.section == sec
+ && (*sym_hash)->root.u.def.value == addr)
+ return true;
+ }
+ return false;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses mn10200_elf_relocate_section. */
+
+static bfd_byte *
+mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *input_section = link_order->u.indirect.section;
+ bfd *input_bfd = input_section->owner;
+ asection **sections = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf32_External_Sym *external_syms = NULL;
+ Elf_Internal_Sym *internal_syms = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocateable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocateable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ input_section->_raw_size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isymp;
+ asection **secpp;
+ Elf32_External_Sym *esym, *esymend;
+
+ if (symtab_hdr->contents != NULL)
+ external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ external_syms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf32_External_Sym)));
+ if (external_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (external_syms, sizeof (Elf32_External_Sym),
+ symtab_hdr->sh_info, input_bfd)
+ != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
+ goto error_return;
+ }
+
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (input_bfd, input_section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL, false));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ internal_syms = ((Elf_Internal_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf_Internal_Sym)));
+ if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ sections = (asection **) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (asection *));
+ if (sections == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ isymp = internal_syms;
+ secpp = sections;
+ esym = external_syms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; ++esym, ++isymp, ++secpp)
+ {
+ asection *isec;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
+
+ if (isymp->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
+ isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+ else if (isymp->st_shndx == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isymp->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else
+ {
+ /* Who knows? */
+ isec = NULL;
+ }
+
+ *secpp = isec;
+ }
+
+ if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ internal_syms, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ sections = NULL;
+ if (internal_syms != NULL)
+ free (internal_syms);
+ internal_syms = NULL;
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ external_syms = NULL;
+ if (internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+ }
+
+ return data;
+
+ error_return:
+ if (internal_relocs != NULL
+ && internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ if (internal_syms != NULL)
+ free (internal_syms);
+ if (sections != NULL)
+ free (sections);
+ return NULL;
+}
+
+
+#define TARGET_LITTLE_SYM bfd_elf32_mn10200_vec
+#define TARGET_LITTLE_NAME "elf32-mn10200"
+#define ELF_ARCH bfd_arch_mn10200
+#define ELF_MACHINE_CODE EM_CYGNUS_MN10200
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_info_to_howto mn10200_info_to_howto
+#define elf_info_to_howto_rel 0
+#define elf_backend_relocate_section mn10200_elf_relocate_section
+#define bfd_elf32_bfd_relax_section mn10200_elf_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ mn10200_elf_get_relocated_section_contents
+
+#define elf_symbol_leading_char '_'
+
+#include "elf32-target.h"
diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
new file mode 100644
index 00000000000..9ba09a88d61
--- /dev/null
+++ b/bfd/elf-m10300.c
@@ -0,0 +1,2821 @@
+/* Matsushita 10300 specific support for 32-bit ELF
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mn10300.h"
+
+struct elf32_mn10300_link_hash_entry
+{
+ /* The basic elf link hash table entry. */
+ struct elf_link_hash_entry root;
+
+ /* For function symbols, the number of times this function is
+ called directly (ie by name). */
+ unsigned int direct_calls;
+
+ /* For function symbols, the size of this function's stack
+ (if <= 255 bytes). We stuff this into "call" instructions
+ to this target when it's valid and profitable to do so.
+
+ This does not include stack allocated by movm! */
+ unsigned char stack_size;
+
+ /* For function symbols, arguments (if any) for movm instruction
+ in the prologue. We stuff this value into "call" instructions
+ to the target when it's valid and profitable to do so. */
+ unsigned char movm_args;
+
+ /* For funtion symbols, the amount of stack space that would be allocated
+ by the movm instruction. This is redundant with movm_args, but we
+ add it to the hash table to avoid computing it over and over. */
+ unsigned char movm_stack_size;
+
+/* When set, convert all "call" instructions to this target into "calls"
+ instructions. */
+#define MN10300_CONVERT_CALL_TO_CALLS 0x1
+
+/* Used to mark functions which have had redundant parts of their
+ prologue deleted. */
+#define MN10300_DELETED_PROLOGUE_BYTES 0x2
+ unsigned char flags;
+};
+
+/* We derive a hash table from the main elf linker hash table so
+ we can store state variables and a secondary hash table without
+ resorting to global variables. */
+struct elf32_mn10300_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ /* A hash table for static functions. We could derive a new hash table
+ instead of using the full elf32_mn10300_link_hash_table if we wanted
+ to save some memory. */
+ struct elf32_mn10300_link_hash_table *static_hash_table;
+
+ /* Random linker state flags. */
+#define MN10300_HASH_ENTRIES_INITIALIZED 0x1
+ char flags;
+};
+
+/* For MN10300 linker hash table. */
+
+/* Get the MN10300 ELF linker hash table from a link_info structure. */
+
+#define elf32_mn10300_hash_table(p) \
+ ((struct elf32_mn10300_link_hash_table *) ((p)->hash))
+
+#define elf32_mn10300_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+static struct bfd_hash_entry *elf32_mn10300_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *elf32_mn10300_link_hash_table_create
+ PARAMS ((bfd *));
+
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void mn10300_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static boolean mn10300_elf_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static asection *mn10300_elf_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *info, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static boolean mn10300_elf_relax_delete_bytes
+ PARAMS ((bfd *, asection *, bfd_vma, int));
+static boolean mn10300_elf_symbol_address_p
+ PARAMS ((bfd *, asection *, Elf32_External_Sym *, bfd_vma));
+static boolean elf32_mn10300_finish_hash_table_entry
+ PARAMS ((struct bfd_hash_entry *, PTR));
+static void compute_function_info
+ PARAMS ((bfd *, struct elf32_mn10300_link_hash_entry *,
+ bfd_vma, unsigned char *));
+
+/* We have to use RELA instructions since md_apply_fix3 in the assembler
+ does absolutely nothing. */
+#define USE_RELA
+
+
+static reloc_howto_type elf_mn10300_howto_table[] =
+{
+ /* Dummy relocation. Does nothing. */
+ HOWTO (R_MN10300_NONE,
+ 0,
+ 2,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_NONE",
+ false,
+ 0,
+ 0,
+ false),
+ /* Standard 32 bit reloc. */
+ HOWTO (R_MN10300_32,
+ 0,
+ 2,
+ 32,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_32",
+ false,
+ 0xffffffff,
+ 0xffffffff,
+ false),
+ /* Standard 16 bit reloc. */
+ HOWTO (R_MN10300_16,
+ 0,
+ 1,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_16",
+ false,
+ 0xffff,
+ 0xffff,
+ false),
+ /* Standard 8 bit reloc. */
+ HOWTO (R_MN10300_8,
+ 0,
+ 0,
+ 8,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_8",
+ false,
+ 0xff,
+ 0xff,
+ false),
+ /* Standard 32bit pc-relative reloc. */
+ HOWTO (R_MN10300_PCREL32,
+ 0,
+ 2,
+ 32,
+ true,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_PCREL32",
+ false,
+ 0xffffffff,
+ 0xffffffff,
+ true),
+ /* Standard 16bit pc-relative reloc. */
+ HOWTO (R_MN10300_PCREL16,
+ 0,
+ 1,
+ 16,
+ true,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_PCREL16",
+ false,
+ 0xffff,
+ 0xffff,
+ true),
+ /* Standard 8 pc-relative reloc. */
+ HOWTO (R_MN10300_PCREL8,
+ 0,
+ 0,
+ 8,
+ true,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_PCREL8",
+ false,
+ 0xff,
+ 0xff,
+ true),
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_MN10300_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_MN10300_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_MN10300_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_MN10300_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Standard 24 bit reloc. */
+ HOWTO (R_MN10300_24,
+ 0,
+ 2,
+ 24,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_MN10300_24",
+ false,
+ 0xffffff,
+ 0xffffff,
+ false),
+
+};
+
+struct mn10300_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct mn10300_reloc_map mn10300_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_MN10300_NONE, },
+ { BFD_RELOC_32, R_MN10300_32, },
+ { BFD_RELOC_16, R_MN10300_16, },
+ { BFD_RELOC_8, R_MN10300_8, },
+ { BFD_RELOC_32_PCREL, R_MN10300_PCREL32, },
+ { BFD_RELOC_16_PCREL, R_MN10300_PCREL16, },
+ { BFD_RELOC_8_PCREL, R_MN10300_PCREL8, },
+ { BFD_RELOC_24, R_MN10300_24, },
+ { BFD_RELOC_VTABLE_INHERIT, R_MN10300_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_MN10300_GNU_VTENTRY },
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mn10300_reloc_map) / sizeof (struct mn10300_reloc_map);
+ i++)
+ {
+ if (mn10300_reloc_map[i].bfd_reloc_val == code)
+ return &elf_mn10300_howto_table[mn10300_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an MN10300 ELF reloc. */
+
+static void
+mn10300_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_MN10300_MAX);
+ cache_ptr->howto = &elf_mn10300_howto_table[r_type];
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+mn10300_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_MN10300_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_MN10300_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+mn10300_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MN10300_GNU_VTINHERIT:
+ case R_MN10300_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, offset, value,
+ addend, info, sym_sec, is_local)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma offset;
+ bfd_vma value;
+ bfd_vma addend;
+ struct bfd_link_info *info;
+ asection *sym_sec;
+ int is_local;
+{
+ unsigned long r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+
+ switch (r_type)
+ {
+ case R_MN10300_NONE:
+ return bfd_reloc_ok;
+
+ case R_MN10300_32:
+ value += addend;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_24:
+ value += addend;
+
+ if ((long)value > 0x7fffff || (long)value < -0x800000)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value & 0xff, hit_data);
+ bfd_put_8 (input_bfd, (value >> 8) & 0xff, hit_data + 1);
+ bfd_put_8 (input_bfd, (value >> 16) & 0xff, hit_data + 2);
+ return bfd_reloc_ok;
+
+ case R_MN10300_16:
+ value += addend;
+
+ if ((long)value > 0x7fff || (long)value < -0x8000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_8:
+ value += addend;
+
+ if ((long)value > 0x7f || (long)value < -0x80)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_PCREL8:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ value += addend;
+
+ if ((long)value > 0xff || (long)value < -0x100)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_PCREL16:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ value += addend;
+
+ if ((long)value > 0xffff || (long)value < -0x10000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_PCREL32:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ value += addend;
+
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_GNU_VTINHERIT:
+ case R_MN10300_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+
+/* Relocate an MN10300 ELF section. */
+static boolean
+mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf32_mn10300_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel, *relend;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = (struct elf32_mn10300_link_hash_entry **)
+ (elf_sym_hashes (input_bfd));
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf32_mn10300_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ howto = elf_mn10300_howto_table + r_type;
+
+ /* Just skip the vtable gc relocs. */
+ if (r_type == R_MN10300_GNU_VTINHERIT
+ || r_type == R_MN10300_GNU_VTENTRY)
+ continue;
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf32_mn10300_link_hash_entry *) h->root.root.u.i.link;
+ if (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.root.u.def.section;
+ relocation = (h->root.root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ info, sec, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *name;
+ const char *msg = (const char *)0;
+
+ if (h != NULL)
+ name = h->root.root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_undefined:
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous error");
+ goto common_error;
+
+ default:
+ msg = _("internal error: unknown error");
+ /* fall through */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, msg, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Finish initializing one hash table entry. */
+static boolean
+elf32_mn10300_finish_hash_table_entry (gen_entry, in_args)
+ struct bfd_hash_entry *gen_entry;
+ PTR in_args;
+{
+ struct elf32_mn10300_link_hash_entry *entry;
+ unsigned int byte_count = 0;
+
+ entry = (struct elf32_mn10300_link_hash_entry *)gen_entry;
+
+ /* If we already know we want to convert "call" to "calls" for calls
+ to this symbol, then return now. */
+ if (entry->flags == MN10300_CONVERT_CALL_TO_CALLS)
+ return true;
+
+ /* If there are no named calls to this symbol, or there's nothing we
+ can move from the function itself into the "call" instruction, then
+ note that all "call" instructions should be converted into "calls"
+ instructions and return. */
+ if (entry->direct_calls == 0
+ || (entry->stack_size == 0 && entry->movm_args == 0))
+ {
+ /* Make a note that we should convert "call" instructions to "calls"
+ instructions for calls to this symbol. */
+ entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+ return true;
+ }
+
+ /* We may be able to move some instructions from the function itself into
+ the "call" instruction. Count how many bytes we might be able to
+ eliminate in the function itself. */
+
+ /* A movm instruction is two bytes. */
+ if (entry->movm_args)
+ byte_count += 2;
+
+ /* Count the insn to allocate stack space too. */
+ if (entry->stack_size > 0 && entry->stack_size <= 128)
+ byte_count += 3;
+ else if (entry->stack_size > 0 && entry->stack_size < 256)
+ byte_count += 4;
+
+ /* If using "call" will result in larger code, then turn all
+ the associated "call" instructions into "calls" instrutions. */
+ if (byte_count < entry->direct_calls)
+ entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+
+ /* This routine never fails. */
+ return true;
+}
+
+/* This function handles relaxing for the mn10300.
+
+ There's quite a few relaxing opportunites available on the mn10300:
+
+ * calls:32 -> calls:16 2 bytes
+ * call:32 -> call:16 2 bytes
+
+ * call:32 -> calls:32 1 byte
+ * call:16 -> calls:16 1 byte
+ * These are done anytime using "calls" would result
+ in smaller code, or when necessary to preserve the
+ meaning of the program.
+
+ * call:32 varies
+ * call:16
+ * In some circumstances we can move instructions
+ from a function prologue into a "call" instruction.
+ This is only done if the resulting code is no larger
+ than the original code.
+
+
+ * jmp:32 -> jmp:16 2 bytes
+ * jmp:16 -> bra:8 1 byte
+
+ * If the previous instruction is a conditional branch
+ around the jump/bra, we may be able to reverse its condition
+ and change its target to the jump's target. The jump/bra
+ can then be deleted. 2 bytes
+
+ * mov abs32 -> mov abs16 1 or 2 bytes
+
+ * Most instructions which accept imm32 can relax to imm16 1 or 2 bytes
+ - Most instructions which accept imm16 can relax to imm8 1 or 2 bytes
+
+ * Most instructions which accept d32 can relax to d16 1 or 2 bytes
+ - Most instructions which accept d16 can relax to d8 1 or 2 bytes
+
+ We don't handle imm16->imm8 or d16->d8 as they're very rare
+ and somewhat more difficult to support. */
+
+static boolean
+mn10300_elf_relax_section (abfd, sec, link_info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+ Elf32_External_Sym *extsyms = NULL;
+ Elf32_External_Sym *free_extsyms = NULL;
+ struct elf32_mn10300_link_hash_table *hash_table;
+
+ /* Assume nothing changes. */
+ *again = false;
+
+ /* We need a pointer to the mn10300 specific hash table. */
+ hash_table = elf32_mn10300_hash_table (link_info);
+
+ /* Initialize fields in each hash table entry the first time through. */
+ if ((hash_table->flags & MN10300_HASH_ENTRIES_INITIALIZED) == 0)
+ {
+ bfd *input_bfd;
+
+ /* Iterate over all the input bfds. */
+ for (input_bfd = link_info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link_next)
+ {
+ asection *section;
+
+ /* We're going to need all the symbols for each bfd. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ /* Go get them off disk. */
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, input_bfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+
+ /* Iterate over each section in this bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ struct elf32_mn10300_link_hash_entry *hash;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ const char *sym_name;
+ char *new_name;
+ Elf_Internal_Shdr *hdr;
+
+ /* Get cached copy of section contents if it exists. */
+ if (elf_section_data (section)->this_hdr.contents != NULL)
+ contents = elf_section_data (section)->this_hdr.contents;
+ else if (section->_raw_size != 0)
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *)bfd_malloc (section->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (!bfd_get_section_contents (input_bfd, section,
+ contents, (file_ptr) 0,
+ section->_raw_size))
+ goto error_return;
+ }
+ else
+ {
+ contents = NULL;
+ free_contents = NULL;
+ }
+
+ /* If there aren't any relocs, then there's nothing to do. */
+ if ((section->flags & SEC_RELOC) != 0
+ && section->reloc_count != 0)
+ {
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (input_bfd, section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ /* Now examine each relocation. */
+ irel = internal_relocs;
+ irelend = irel + section->reloc_count;
+ for (; irel < irelend; irel++)
+ {
+ long r_type;
+ unsigned long r_index;
+ unsigned char code;
+
+ r_type = ELF32_R_TYPE (irel->r_info);
+ r_index = ELF32_R_SYM (irel->r_info);
+
+ if (r_type < 0 || r_type >= (int)R_MN10300_MAX)
+ goto error_return;
+
+ /* We need the name and hash table entry of the target
+ symbol! */
+ hash = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+
+ if (r_index < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (input_bfd,
+ extsyms + r_index, &isym);
+
+ if (isym.st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym.st_shndx > 0
+ && isym.st_shndx < SHN_LORESERVE)
+ sym_sec
+ = bfd_section_from_elf_index (input_bfd,
+ isym.st_shndx);
+ else if (isym.st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym.st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ isym.st_name);
+
+ /* If it isn't a function, then we don't care
+ about it. */
+ if (r_index < symtab_hdr->sh_info
+ && ELF_ST_TYPE (isym.st_info) != STT_FUNC)
+ continue;
+
+ /* Tack on an ID so we can uniquely identify this
+ local symbol in the global hash table. */
+ new_name = bfd_malloc (strlen (sym_name) + 10);
+ if (new_name == 0)
+ goto error_return;
+
+ sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+ sym_name = new_name;
+
+ hash = (struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (&hash_table->static_hash_table->root,
+ sym_name, true,
+ true, false);
+ free (new_name);
+ }
+ else
+ {
+ r_index -= symtab_hdr->sh_info;
+ hash = (struct elf32_mn10300_link_hash_entry *)
+ elf_sym_hashes (input_bfd)[r_index];
+ }
+
+ /* If this is not a "call" instruction, then we
+ should convert "call" instructions to "calls"
+ instructions. */
+ code = bfd_get_8 (input_bfd,
+ contents + irel->r_offset - 1);
+ if (code != 0xdd && code != 0xcd)
+ hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+
+ /* If this is a jump/call, then bump the direct_calls
+ counter. Else force "call" to "calls" conversions. */
+ if (r_type == R_MN10300_PCREL32
+ || r_type == R_MN10300_PCREL16)
+ hash->direct_calls++;
+ else
+ hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+ }
+ }
+
+ /* Now look at the actual contents to get the stack size,
+ and a list of what registers were saved in the prologue
+ (ie movm_args). */
+ if ((section->flags & SEC_CODE) != 0)
+ {
+
+ Elf32_External_Sym *esym, *esymend;
+ int idx, shndx;
+
+ shndx = _bfd_elf_section_from_bfd_section (input_bfd,
+ section);
+
+
+ /* Look at each function defined in this section and
+ update info for that function. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);
+ if (isym.st_shndx == shndx
+ && ELF_ST_TYPE (isym.st_info) == STT_FUNC)
+ {
+ if (isym.st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym.st_shndx > 0
+ && isym.st_shndx < SHN_LORESERVE)
+ sym_sec
+ = bfd_section_from_elf_index (input_bfd,
+ isym.st_shndx);
+ else if (isym.st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym.st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ isym.st_name);
+
+ /* Tack on an ID so we can uniquely identify this
+ local symbol in the global hash table. */
+ new_name = bfd_malloc (strlen (sym_name) + 10);
+ if (new_name == 0)
+ goto error_return;
+
+ sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+ sym_name = new_name;
+
+ hash = (struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (&hash_table->static_hash_table->root,
+ sym_name, true,
+ true, false);
+ free (new_name);
+ compute_function_info (input_bfd, hash,
+ isym.st_value, contents);
+ }
+ }
+
+ esym = extsyms + symtab_hdr->sh_info;
+ esymend = extsyms + (symtab_hdr->sh_size
+ / sizeof (Elf32_External_Sym));
+ for (idx = 0; esym < esymend; esym++, idx++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);
+ hash = (struct elf32_mn10300_link_hash_entry *)
+ elf_sym_hashes (input_bfd)[idx];
+ if (isym.st_shndx == shndx
+ && ELF_ST_TYPE (isym.st_info) == STT_FUNC
+ && (hash)->root.root.u.def.section == section
+ && ((hash)->root.root.type == bfd_link_hash_defined
+ || (hash)->root.root.type == bfd_link_hash_defweak))
+ compute_function_info (input_bfd, hash,
+ (hash)->root.root.u.def.value,
+ contents);
+ }
+ }
+
+ /* Cache or free any memory we allocated for the relocs. */
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ /* Cache or free any memory we allocated for the contents. */
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (section)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+ }
+
+ /* Cache or free any memory we allocated for the symbols. */
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ free_extsyms = NULL;
+ }
+ }
+
+ /* Now iterate on each symbol in the hash table and perform
+ the final initialization steps on each. */
+ elf32_mn10300_link_hash_traverse (hash_table,
+ elf32_mn10300_finish_hash_table_entry,
+ NULL);
+ elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
+ elf32_mn10300_finish_hash_table_entry,
+ NULL);
+
+ /* All entries in the hash table are fully initialized. */
+ hash_table->flags |= MN10300_HASH_ENTRIES_INITIALIZED;
+
+ /* Now that everything has been initialized, go through each
+ code section and delete any prologue insns which will be
+ redundant because their operations will be performed by
+ a "call" instruction. */
+ for (input_bfd = link_info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link_next)
+ {
+ asection *section;
+
+ /* We're going to need all the symbols for each bfd. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ /* Go get them off disk. */
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, input_bfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+
+ /* Walk over each section in this bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ int shndx;
+ Elf32_External_Sym *esym, *esymend;
+ int idx;
+
+ /* Skip non-code sections and empty sections. */
+ if ((section->flags & SEC_CODE) == 0 || section->_raw_size == 0)
+ continue;
+
+ if (section->reloc_count != 0)
+ {
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (input_bfd, section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+ }
+
+ /* Get cached copy of section contents if it exists. */
+ if (elf_section_data (section)->this_hdr.contents != NULL)
+ contents = elf_section_data (section)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *)bfd_malloc (section->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (!bfd_get_section_contents (input_bfd, section,
+ contents, (file_ptr) 0,
+ section->_raw_size))
+ goto error_return;
+ }
+
+
+ shndx = _bfd_elf_section_from_bfd_section (input_bfd, section);
+
+ /* Now look for any function in this section which needs
+ insns deleted from its prologue. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+ struct elf32_mn10300_link_hash_entry *sym_hash;
+ asection *sym_sec;
+ const char *sym_name;
+ Elf_Internal_Shdr *hdr;
+ char *new_name;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);
+
+ if (isym.st_shndx != shndx)
+ continue;
+
+ if (isym.st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
+ sym_sec
+ = bfd_section_from_elf_index (input_bfd, isym.st_shndx);
+ else if (isym.st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym.st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ isym.st_name);
+
+ /* Tack on an ID so we can uniquely identify this
+ local symbol in the global hash table. */
+ new_name = bfd_malloc (strlen (sym_name) + 10);
+ if (new_name == 0)
+ goto error_return;
+ sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+ sym_name = new_name;
+
+ sym_hash = (struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (&hash_table->static_hash_table->root,
+ sym_name, false,
+ false, false);
+
+ free (new_name);
+ if (sym_hash == NULL)
+ continue;
+
+ if (! ((sym_hash)->flags & MN10300_CONVERT_CALL_TO_CALLS)
+ && ! ((sym_hash)->flags & MN10300_DELETED_PROLOGUE_BYTES))
+ {
+ int bytes = 0;
+
+ /* Note that we've changed things. */
+ elf_section_data (section)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (section)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *)extsyms;
+ free_extsyms = NULL;
+
+ /* Count how many bytes we're going to delete. */
+ if (sym_hash->movm_args)
+ bytes += 2;
+
+ if (sym_hash->stack_size && sym_hash->stack_size <= 128)
+ bytes += 3;
+ else if (sym_hash->stack_size
+ && sym_hash->stack_size < 256)
+ bytes += 4;
+
+ /* Note that we've deleted prologue bytes for this
+ function. */
+ sym_hash->flags |= MN10300_DELETED_PROLOGUE_BYTES;
+
+ /* Actually delete the bytes. */
+ if (!mn10300_elf_relax_delete_bytes (input_bfd,
+ section,
+ isym.st_value,
+ bytes))
+ goto error_return;
+
+ /* Something changed. Not strictly necessary, but
+ may lead to more relaxing opportunities. */
+ *again = true;
+ }
+ }
+
+ /* Look for any global functions in this section which
+ need insns deleted from their prologues. */
+ esym = extsyms + symtab_hdr->sh_info;
+ esymend = extsyms + (symtab_hdr->sh_size
+ / sizeof (Elf32_External_Sym));
+ for (idx = 0; esym < esymend; esym++, idx++)
+ {
+ Elf_Internal_Sym isym;
+ struct elf32_mn10300_link_hash_entry *sym_hash;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, &isym);
+ sym_hash = (struct elf32_mn10300_link_hash_entry *)
+ (elf_sym_hashes (input_bfd)[idx]);
+ if (isym.st_shndx == shndx
+ && (sym_hash)->root.root.u.def.section == section
+ && ! ((sym_hash)->flags & MN10300_CONVERT_CALL_TO_CALLS)
+ && ! ((sym_hash)->flags & MN10300_DELETED_PROLOGUE_BYTES))
+ {
+ int bytes = 0;
+
+ /* Note that we've changed things. */
+ elf_section_data (section)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (section)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *)extsyms;
+ free_extsyms = NULL;
+
+ /* Count how many bytes we're going to delete. */
+ if (sym_hash->movm_args)
+ bytes += 2;
+
+ if (sym_hash->stack_size && sym_hash->stack_size <= 128)
+ bytes += 3;
+ else if (sym_hash->stack_size
+ && sym_hash->stack_size < 256)
+ bytes += 4;
+
+ /* Note that we've deleted prologue bytes for this
+ function. */
+ sym_hash->flags |= MN10300_DELETED_PROLOGUE_BYTES;
+
+ /* Actually delete the bytes. */
+ if (!mn10300_elf_relax_delete_bytes (input_bfd,
+ section,
+ (sym_hash)->root.root.u.def.value,
+ bytes))
+ goto error_return;
+
+ /* Something changed. Not strictly necessary, but
+ may lead to more relaxing opportunities. */
+ *again = true;
+ }
+ }
+
+ /* Cache or free any memory we allocated for the relocs. */
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ /* Cache or free any memory we allocated for the contents. */
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (section)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+ }
+
+ /* Cache or free any memory we allocated for the symbols. */
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ free_extsyms = NULL;
+ }
+ }
+ }
+
+
+ /* (Re)initialize for the basic instruction shortening/relaxing pass. */
+ contents = NULL;
+ extsyms = NULL;
+ internal_relocs = NULL;
+ free_relocs = NULL;
+ free_contents = NULL;
+ free_extsyms = NULL;
+
+ /* We don't have to do anything for a relocateable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocateable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return true;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ struct elf32_mn10300_link_hash_entry *h = NULL;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_NONE
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_8
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_MAX)
+ continue;
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (extsyms == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ /* Go get them off disk. */
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym isym;
+ asection *sym_sec;
+ Elf_Internal_Shdr *hdr;
+ const char *sym_name;
+ char *new_name;
+
+ /* A local symbol. */
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irel->r_info),
+ &isym);
+
+ if (isym.st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
+ sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ else if (isym.st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (isym.st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+
+ symval = (isym.st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ sym_name = bfd_elf_string_from_elf_section (abfd,
+ symtab_hdr->sh_link,
+ isym.st_name);
+
+ /* Tack on an ID so we can uniquely identify this
+ local symbol in the global hash table. */
+ new_name = bfd_malloc (strlen (sym_name) + 10);
+ if (new_name == 0)
+ goto error_return;
+ sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+ sym_name = new_name;
+
+ h = (struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (&hash_table->static_hash_table->root,
+ sym_name, false, false, false);
+ free (new_name);
+ }
+ else
+ {
+ unsigned long indx;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = (struct elf32_mn10300_link_hash_entry *)
+ (elf_sym_hashes (abfd)[indx]);
+ BFD_ASSERT (h != NULL);
+ if (h->root.root.type != bfd_link_hash_defined
+ && h->root.root.type != bfd_link_hash_defweak)
+ {
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+ }
+
+ symval = (h->root.root.u.def.value
+ + h->root.root.u.def.section->output_section->vma
+ + h->root.root.u.def.section->output_offset);
+ }
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ /* Try to turn a 32bit pc-relative branch/call into a 16bit pc-relative
+ branch/call, also deal with "call" -> "calls" conversions and
+ insertion of prologue data into "call" instructions. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_PCREL32)
+ {
+ bfd_vma value = symval;
+
+ /* If we've got a "call" instruction that needs to be turned
+ into a "calls" instruction, do so now. It saves a byte. */
+ if (h && (h->flags & MN10300_CONVERT_CALL_TO_CALLS))
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* Make sure we're working with a "call" instruction! */
+ if (code == 0xdd)
+ {
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 1);
+ bfd_put_8 (abfd, 0xff, contents + irel->r_offset);
+
+ /* Fix irel->r_offset and irel->r_addend. */
+ irel->r_offset += 1;
+ irel->r_addend += 1;
+
+ /* Delete one byte of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 3, 1))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+ }
+ else if (h)
+ {
+ /* We've got a "call" instruction which needs some data
+ from target function filled in. */
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* Insert data from the target function into the "call"
+ instruction if needed. */
+ if (code == 0xdd)
+ {
+ bfd_put_8 (abfd, h->movm_args, contents + irel->r_offset + 4);
+ bfd_put_8 (abfd, h->stack_size + h->movm_stack_size,
+ contents + irel->r_offset + 5);
+ }
+ }
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 16 bits, note the high value is
+ 0x7fff + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long)value < 0x8001 && (long)value > -0x8000)
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if (code != 0xdc && code != 0xdd && code != 0xff)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ if (code == 0xdc)
+ bfd_put_8 (abfd, 0xcc, contents + irel->r_offset - 1);
+ else if (code == 0xdd)
+ bfd_put_8 (abfd, 0xcd, contents + irel->r_offset - 1);
+ else if (code == 0xff)
+ bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_PCREL16);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+ }
+
+ /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
+ branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_PCREL16)
+ {
+ bfd_vma value = symval;
+
+ /* If we've got a "call" instruction that needs to be turned
+ into a "calls" instruction, do so now. It saves a byte. */
+ if (h && (h->flags & MN10300_CONVERT_CALL_TO_CALLS))
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* Make sure we're working with a "call" instruction! */
+ if (code == 0xcd)
+ {
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 1);
+ bfd_put_8 (abfd, 0xff, contents + irel->r_offset);
+
+ /* Fix irel->r_offset and irel->r_addend. */
+ irel->r_offset += 1;
+ irel->r_addend += 1;
+
+ /* Delete one byte of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+ }
+ else if (h)
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* Insert data from the target function into the "call"
+ instruction if needed. */
+ if (code == 0xcd)
+ {
+ bfd_put_8 (abfd, h->movm_args, contents + irel->r_offset + 2);
+ bfd_put_8 (abfd, h->stack_size + h->movm_stack_size,
+ contents + irel->r_offset + 3);
+ }
+ }
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 8 bits, note the high value is
+ 0x7f + 1 as the target will be one bytes closer if we are
+ able to relax. */
+ if ((long)value < 0x80 && (long)value > -0x80)
+ {
+ unsigned char code;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if (code != 0xcc)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xca, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_PCREL8);
+
+ /* Delete one byte of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+ }
+
+ /* Try to eliminate an unconditional 8 bit pc-relative branch
+ which immediately follows a conditional 8 bit pc-relative
+ branch around the unconditional branch.
+
+ original: new:
+ bCC lab1 bCC' lab2
+ bra lab2
+ lab1: lab1:
+
+
+ This happens when the bCC can't reach lab2 at assembly time,
+ but due to other relaxations it can reach at link time. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_PCREL8)
+ {
+ Elf_Internal_Rela *nrel;
+ bfd_vma value = symval;
+ unsigned char code;
+
+ /* Deal with pc-relative gunk. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value += irel->r_addend;
+
+ /* Do nothing if this reloc is the last byte in the section. */
+ if (irel->r_offset == sec->_cooked_size)
+ continue;
+
+ /* See if the next instruction is an unconditional pc-relative
+ branch, more often than not this test will fail, so we
+ test it first to speed things up. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+ if (code != 0xca)
+ continue;
+
+ /* Also make sure the next relocation applies to the next
+ instruction and that it's a pc-relative 8 bit branch. */
+ nrel = irel + 1;
+ if (nrel == irelend
+ || irel->r_offset + 2 != nrel->r_offset
+ || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10300_PCREL8)
+ continue;
+
+ /* Make sure our destination immediately follows the
+ unconditional branch. */
+ if (symval != (sec->output_section->vma + sec->output_offset
+ + irel->r_offset + 3))
+ continue;
+
+ /* Now make sure we are a conditional branch. This may not
+ be necessary, but why take the chance.
+
+ Note these checks assume that R_MN10300_PCREL8 relocs
+ only occur on bCC and bCCx insns. If they occured
+ elsewhere, we'd need to know the start of this insn
+ for this check to be accurate. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ if (code != 0xc0 && code != 0xc1 && code != 0xc2
+ && code != 0xc3 && code != 0xc4 && code != 0xc5
+ && code != 0xc6 && code != 0xc7 && code != 0xc8
+ && code != 0xc9 && code != 0xe8 && code != 0xe9
+ && code != 0xea && code != 0xeb)
+ continue;
+
+ /* We also have to be sure there is no symbol/label
+ at the unconditional branch. */
+ if (mn10300_elf_symbol_address_p (abfd, sec, extsyms,
+ irel->r_offset + 1))
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Reverse the condition of the first branch. */
+ switch (code)
+ {
+ case 0xc8:
+ code = 0xc9;
+ break;
+ case 0xc9:
+ code = 0xc8;
+ break;
+ case 0xc0:
+ code = 0xc2;
+ break;
+ case 0xc2:
+ code = 0xc0;
+ break;
+ case 0xc3:
+ code = 0xc1;
+ break;
+ case 0xc1:
+ code = 0xc3;
+ break;
+ case 0xc4:
+ code = 0xc6;
+ break;
+ case 0xc6:
+ code = 0xc4;
+ break;
+ case 0xc7:
+ code = 0xc5;
+ break;
+ case 0xc5:
+ code = 0xc7;
+ break;
+ case 0xe8:
+ code = 0xe9;
+ break;
+ case 0x9d:
+ code = 0xe8;
+ break;
+ case 0xea:
+ code = 0xeb;
+ break;
+ case 0xeb:
+ code = 0xea;
+ break;
+ }
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ /* Set the reloc type and symbol for the first branch
+ from the second branch. */
+ irel->r_info = nrel->r_info;
+
+ /* Make the reloc for the second branch a null reloc. */
+ nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
+ R_MN10300_NONE);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ }
+
+
+ /* Try to turn a 32bit immediate, displacement or absolute address
+ into a 16bit immediate, displacement or absolute address. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_32)
+ {
+ bfd_vma value = symval;
+ value += irel->r_addend;
+
+
+ /* See if the value will fit in 16 bits.
+ We allow any 16bit match here. We prune those we can't
+ handle below. */
+ if ((long)value < 0x7fff && (long)value > -0x8000)
+ {
+ unsigned char code;
+
+ /* Most insns which have 32bit operands are 6 bytes long;
+ exceptions are pcrel insns and bit insns.
+
+ We handle pcrel insns above. We don't bother trying
+ to handle the bit insns here.
+
+ The first byte of the remaining insns will be 0xfc. */
+
+ /* Get the first opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ if (code != 0xfc)
+ continue;
+
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if ((code & 0xf0) < 0x80)
+ switch (code & 0xf0)
+ {
+ /* mov (d32,am),dn -> mov (d32,am),dn
+ mov dm,(d32,am) -> mov dn,(d32,am)
+ mov (d32,am),an -> mov (d32,am),an
+ mov dm,(d32,am) -> mov dn,(d32,am)
+ movbu (d32,am),dn -> movbu (d32,am),dn
+ movbu dm,(d32,am) -> movbu dn,(d32,am)
+ movhu (d32,am),dn -> movhu (d32,am),dn
+ movhu dm,(d32,am) -> movhu dn,(d32,am) */
+ case 0x00:
+ case 0x10:
+ case 0x20:
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70:
+ /* Not safe if the high bit is on as relaxing may
+ move the value out of high mem and thus not fit
+ in a signed 16bit value. */
+ if (code == 0xcc
+ && (value & 0x8000))
+ continue;
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_16);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+ }
+ else if ((code & 0xf0) == 0x80
+ || (code & 0xf0) == 0x90)
+ switch (code & 0xf3)
+ {
+ /* mov dn,(abs32) -> mov dn,(abs16)
+ movbu dn,(abs32) -> movbu dn,(abs16)
+ movhu dn,(abs32) -> movhu dn,(abs16) */
+ case 0x81:
+ case 0x82:
+ case 0x83:
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ if ((code & 0xf3) == 0x81)
+ code = 0x01 + (code & 0x0c);
+ else if ((code & 0xf3) == 0x82)
+ code = 0x02 + (code & 0x0c);
+ else if ((code & 0xf3) == 0x83)
+ code = 0x03 + (code & 0x0c);
+ else
+ abort ();
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_16);
+
+ /* The opcode got shorter too, so we have to fix the
+ addend and offset too! */
+ irel->r_offset -= 1;
+
+ /* Delete three bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 3))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+
+ /* mov am,(abs32) -> mov am,(abs16)
+ mov am,(d32,sp) -> mov am,(d16,sp)
+ mov dm,(d32,sp) -> mov dm,(d32,sp)
+ movbu dm,(d32,sp) -> movbu dm,(d32,sp)
+ movhu dm,(d32,sp) -> movhu dm,(d32,sp) */
+ case 0x80:
+ case 0x90:
+ case 0x91:
+ case 0x92:
+ case 0x93:
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_16);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+ }
+ else if ((code & 0xf0) < 0xf0)
+ switch (code & 0xfc)
+ {
+ /* mov imm32,dn -> mov imm16,dn
+ mov imm32,an -> mov imm16,an
+ mov (abs32),dn -> mov (abs16),dn
+ movbu (abs32),dn -> movbu (abs16),dn
+ movhu (abs32),dn -> movhu (abs16),dn */
+ case 0xcc:
+ case 0xdc:
+ case 0xa4:
+ case 0xa8:
+ case 0xac:
+ /* Not safe if the high bit is on as relaxing may
+ move the value out of high mem and thus not fit
+ in a signed 16bit value. */
+ if (code == 0xcc
+ && (value & 0x8000))
+ continue;
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ if ((code & 0xfc) == 0xcc)
+ code = 0x2c + (code & 0x03);
+ else if ((code & 0xfc) == 0xdc)
+ code = 0x24 + (code & 0x03);
+ else if ((code & 0xfc) == 0xa4)
+ code = 0x30 + (code & 0x03);
+ else if ((code & 0xfc) == 0xa8)
+ code = 0x34 + (code & 0x03);
+ else if ((code & 0xfc) == 0xac)
+ code = 0x38 + (code & 0x03);
+ else
+ abort ();
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_16);
+
+ /* The opcode got shorter too, so we have to fix the
+ addend and offset too! */
+ irel->r_offset -= 1;
+
+ /* Delete three bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 3))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+
+ /* mov (abs32),an -> mov (abs16),an
+ mov (d32,sp),an -> mov (d32,sp),an
+ mov (d32,sp),dn -> mov (d32,sp),dn
+ movbu (d32,sp),dn -> movbu (d32,sp),dn
+ movhu (d32,sp),dn -> movhu (d32,sp),dn
+ add imm32,dn -> add imm16,dn
+ cmp imm32,dn -> cmp imm16,dn
+ add imm32,an -> add imm16,an
+ cmp imm32,an -> cmp imm16,an
+ and imm32,dn -> and imm32,dn
+ or imm32,dn -> or imm32,dn
+ xor imm32,dn -> xor imm32,dn
+ btst imm32,dn -> btst imm32,dn */
+
+ case 0xa0:
+ case 0xb0:
+ case 0xb1:
+ case 0xb2:
+ case 0xb3:
+ case 0xc0:
+ case 0xc8:
+
+ case 0xd0:
+ case 0xd8:
+ case 0xe0:
+ case 0xe1:
+ case 0xe2:
+ case 0xe3:
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_16);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+ }
+ else if (code == 0xfe)
+ {
+ /* add imm32,sp -> add imm16,sp */
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
+ bfd_put_8 (abfd, 0xfe, contents + irel->r_offset - 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MN10300_16);
+
+ /* Delete two bytes of data. */
+ if (!mn10300_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, 2))
+ goto error_return;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ free_extsyms = NULL;
+ }
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (free_extsyms != NULL)
+ free (free_extsyms);
+ return false;
+}
+
+/* Compute the stack size and movm arguments for the function
+ referred to by HASH at address ADDR in section with
+ contents CONTENTS, store the information in the hash table. */
+static void
+compute_function_info (abfd, hash, addr, contents)
+ bfd *abfd;
+ struct elf32_mn10300_link_hash_entry *hash;
+ bfd_vma addr;
+ unsigned char *contents;
+{
+ unsigned char byte1, byte2;
+ /* We only care about a very small subset of the possible prologue
+ sequences here. Basically we look for:
+
+ movm [d2,d3,a2,a3],sp (optional)
+ add <size>,sp (optional, and only for sizes which fit in an unsigned
+ 8 bit number)
+
+ If we find anything else, we quit. */
+
+ /* Look for movm [regs],sp */
+ byte1 = bfd_get_8 (abfd, contents + addr);
+ byte2 = bfd_get_8 (abfd, contents + addr + 1);
+
+ if (byte1 == 0xcf)
+ {
+ hash->movm_args = byte2;
+ addr += 2;
+ byte1 = bfd_get_8 (abfd, contents + addr);
+ byte2 = bfd_get_8 (abfd, contents + addr + 1);
+ }
+
+ /* Now figure out how much stack space will be allocated by the movm
+ instruction. We need this kept separate from the funtion's normal
+ stack space. */
+ if (hash->movm_args)
+ {
+ /* Space for d2. */
+ if (hash->movm_args & 0x80)
+ hash->movm_stack_size += 4;
+
+ /* Space for d3. */
+ if (hash->movm_args & 0x40)
+ hash->movm_stack_size += 4;
+
+ /* Space for a2. */
+ if (hash->movm_args & 0x20)
+ hash->movm_stack_size += 4;
+
+ /* Space for a3. */
+ if (hash->movm_args & 0x10)
+ hash->movm_stack_size += 4;
+
+ /* "other" space. d0, d1, a0, a1, mdr, lir, lar, 4 byte pad. */
+ if (hash->movm_args & 0x08)
+ hash->movm_stack_size += 8 * 4;
+
+ }
+
+ /* Now look for the two stack adjustment variants. */
+ if (byte1 == 0xf8 && byte2 == 0xfe)
+ {
+ int temp = bfd_get_8 (abfd, contents + addr + 2);
+ temp = ((temp & 0xff) ^ (~0x7f)) + 0x80;
+
+ hash->stack_size = -temp;
+ }
+ else if (byte1 == 0xfa && byte2 == 0xfe)
+ {
+ int temp = bfd_get_16 (abfd, contents + addr + 2);
+ temp = ((temp & 0xffff) ^ (~0x7fff)) + 0x8000;
+ temp = -temp;
+
+ if (temp < 255)
+ hash->stack_size = temp;
+ }
+
+ /* If the total stack to be allocated by the call instruction is more
+ than 255 bytes, then we can't remove the stack adjustment by using
+ "call" (we might still be able to remove the "movm" instruction. */
+ if (hash->stack_size + hash->movm_stack_size > 255)
+ hash->stack_size = 0;
+
+ return;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static boolean
+mn10300_elf_relax_delete_bytes (abfd, sec, addr, count)
+ bfd *abfd;
+ asection *sec;
+ bfd_vma addr;
+ int count;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf32_External_Sym *extsyms;
+ int shndx, index;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf32_External_Sym *esym, *esymend;
+ struct elf32_mn10300_link_hash_entry *sym_hash;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ toaddr = sec->_cooked_size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+ sec->_cooked_size -= count;
+
+ /* Adjust all the relocs. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+
+ if (isym.st_shndx == shndx
+ && isym.st_value > addr
+ && isym.st_value < toaddr)
+ {
+ isym.st_value -= count;
+ bfd_elf32_swap_symbol_out (abfd, &isym, esym);
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ esym = extsyms + symtab_hdr->sh_info;
+ esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
+ for (index = 0; esym < esymend; esym++, index++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+ sym_hash = (struct elf32_mn10300_link_hash_entry *)
+ (elf_sym_hashes (abfd)[index]);
+ if (isym.st_shndx == shndx
+ && ((sym_hash)->root.root.type == bfd_link_hash_defined
+ || (sym_hash)->root.root.type == bfd_link_hash_defweak)
+ && (sym_hash)->root.root.u.def.section == sec
+ && (sym_hash)->root.root.u.def.value > addr
+ && (sym_hash)->root.root.u.def.value < toaddr)
+ {
+ (sym_hash)->root.root.u.def.value -= count;
+ }
+ }
+
+ return true;
+}
+
+/* Return true if a symbol exists at the given address, else return
+ false. */
+static boolean
+mn10300_elf_symbol_address_p (abfd, sec, extsyms, addr)
+ bfd *abfd;
+ asection *sec;
+ Elf32_External_Sym *extsyms;
+ bfd_vma addr;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ int shndx;
+ Elf32_External_Sym *esym, *esymend;
+ struct elf32_mn10300_link_hash_entry **sym_hash, **sym_hash_end;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Examine all the symbols. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+
+ if (isym.st_shndx == shndx
+ && isym.st_value == addr)
+ return true;
+ }
+
+ sym_hash = (struct elf32_mn10300_link_hash_entry **)(elf_sym_hashes (abfd));
+ sym_hash_end = (sym_hash
+ + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info));
+ for (; sym_hash < sym_hash_end; sym_hash++)
+ {
+ if (((*sym_hash)->root.root.type == bfd_link_hash_defined
+ || (*sym_hash)->root.root.type == bfd_link_hash_defweak)
+ && (*sym_hash)->root.root.u.def.section == sec
+ && (*sym_hash)->root.root.u.def.value == addr)
+ return true;
+ }
+ return false;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses mn10300_elf_relocate_section. */
+
+static bfd_byte *
+mn10300_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *input_section = link_order->u.indirect.section;
+ bfd *input_bfd = input_section->owner;
+ asection **sections = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf32_External_Sym *external_syms = NULL;
+ Elf_Internal_Sym *internal_syms = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocateable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocateable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ input_section->_raw_size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isymp;
+ asection **secpp;
+ Elf32_External_Sym *esym, *esymend;
+
+ if (symtab_hdr->contents != NULL)
+ external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ external_syms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf32_External_Sym)));
+ if (external_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (external_syms, sizeof (Elf32_External_Sym),
+ symtab_hdr->sh_info, input_bfd)
+ != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
+ goto error_return;
+ }
+
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (input_bfd, input_section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL, false));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ internal_syms = ((Elf_Internal_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf_Internal_Sym)));
+ if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ sections = (asection **) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (asection *));
+ if (sections == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ isymp = internal_syms;
+ secpp = sections;
+ esym = external_syms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; ++esym, ++isymp, ++secpp)
+ {
+ asection *isec;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
+
+ if (isymp->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
+ isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+ else if (isymp->st_shndx == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isymp->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else
+ {
+ /* Who knows? */
+ isec = NULL;
+ }
+
+ *secpp = isec;
+ }
+
+ if (! mn10300_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ internal_syms, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ sections = NULL;
+ if (internal_syms != NULL)
+ free (internal_syms);
+ internal_syms = NULL;
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ external_syms = NULL;
+ if (internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+ }
+
+ return data;
+
+ error_return:
+ if (internal_relocs != NULL
+ && internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ if (internal_syms != NULL)
+ free (internal_syms);
+ if (sections != NULL)
+ free (sections);
+ return NULL;
+}
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the link hash table. */
+
+/* Create an entry in an MN10300 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf32_mn10300_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct elf32_mn10300_link_hash_entry *ret =
+ (struct elf32_mn10300_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf32_mn10300_link_hash_entry *) NULL)
+ ret = ((struct elf32_mn10300_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf32_mn10300_link_hash_entry)));
+ if (ret == (struct elf32_mn10300_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf32_mn10300_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf32_mn10300_link_hash_entry *) NULL)
+ {
+ ret->direct_calls = 0;
+ ret->stack_size = 0;
+ ret->movm_stack_size = 0;
+ ret->flags = 0;
+ ret->movm_args = 0;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an mn10300 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf32_mn10300_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct elf32_mn10300_link_hash_table *ret;
+
+ ret = ((struct elf32_mn10300_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf32_mn10300_link_hash_table)));
+ if (ret == (struct elf32_mn10300_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf32_mn10300_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ ret->flags = 0;
+ ret->static_hash_table
+ = ((struct elf32_mn10300_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf_link_hash_table)));
+ if (ret->static_hash_table == NULL)
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ if (! _bfd_elf_link_hash_table_init (&ret->static_hash_table->root, abfd,
+ elf32_mn10300_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret->static_hash_table);
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+ return &ret->root.root;
+}
+
+static int
+elf_mn10300_mach (flags)
+ flagword flags;
+{
+ switch (flags & EF_MN10300_MACH)
+ {
+ case E_MN10300_MACH_MN10300:
+ default:
+ return bfd_mach_mn10300;
+
+ }
+}
+
+/* The final processing done just before writing out a MN10300 ELF object
+ file. This gets the MN10300 architecture right based on the machine
+ number. */
+
+/*ARGSUSED*/
+void
+_bfd_mn10300_elf_final_write_processing (abfd, linker)
+ bfd *abfd;
+ boolean linker;
+{
+ unsigned long val;
+ unsigned int i;
+ Elf_Internal_Shdr **hdrpp;
+ const char *name;
+ asection *sec;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_mn10300:
+ val = E_MN10300_MACH_MN10300;
+ break;
+
+ }
+
+ elf_elfheader (abfd)->e_flags &= ~ (EF_MN10300_MACH);
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+boolean
+_bfd_mn10300_elf_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_mn10300,
+ elf_mn10300_mach (elf_elfheader (abfd)->e_flags));
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+boolean
+_bfd_mn10300_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
+ && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
+ {
+ if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
+ bfd_get_mach (ibfd)))
+ return false;
+ }
+
+ return true;
+}
+
+
+#define TARGET_LITTLE_SYM bfd_elf32_mn10300_vec
+#define TARGET_LITTLE_NAME "elf32-mn10300"
+#define ELF_ARCH bfd_arch_mn10300
+#define ELF_MACHINE_CODE EM_CYGNUS_MN10300
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_info_to_howto mn10300_info_to_howto
+#define elf_info_to_howto_rel 0
+#define elf_backend_can_gc_sections 1
+#define elf_backend_check_relocs mn10300_elf_check_relocs
+#define elf_backend_gc_mark_hook mn10300_elf_gc_mark_hook
+#define elf_backend_relocate_section mn10300_elf_relocate_section
+#define bfd_elf32_bfd_relax_section mn10300_elf_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ mn10300_elf_get_relocated_section_contents
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf32_mn10300_link_hash_table_create
+
+#define elf_symbol_leading_char '_'
+
+/* So we can set bits in e_flags. */
+#define elf_backend_final_write_processing \
+ _bfd_mn10300_elf_final_write_processing
+#define elf_backend_object_p _bfd_mn10300_elf_object_p
+
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ _bfd_mn10300_elf_merge_private_bfd_data
+
+
+#include "elf32-target.h"
diff --git a/bfd/elf.c b/bfd/elf.c
new file mode 100644
index 00000000000..ab010d46f4b
--- /dev/null
+++ b/bfd/elf.c
@@ -0,0 +1,5250 @@
+/* ELF executable support for BFD.
+ Copyright 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+
+SECTION
+ ELF backends
+
+ BFD support for ELF formats is being worked on.
+ Currently, the best supported back ends are for sparc and i386
+ (running svr4 or Solaris 2).
+
+ Documentation of the internals of the support code still needs
+ to be written. The code is changing quickly enough that we
+ haven't bothered yet.
+ */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#define ARCH_SIZE 0
+#include "elf-bfd.h"
+
+static INLINE struct elf_segment_map *make_mapping
+ PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean));
+static boolean map_sections_to_segments PARAMS ((bfd *));
+static int elf_sort_sections PARAMS ((const PTR, const PTR));
+static boolean assign_file_positions_for_segments PARAMS ((bfd *));
+static boolean assign_file_positions_except_relocs PARAMS ((bfd *));
+static boolean prep_headers PARAMS ((bfd *));
+static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int));
+static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static char *elf_read PARAMS ((bfd *, long, unsigned int));
+static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
+static boolean assign_section_numbers PARAMS ((bfd *));
+static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));
+static boolean elf_map_symbols PARAMS ((bfd *));
+static bfd_size_type get_program_header_size PARAMS ((bfd *));
+
+/* Swap version information in and out. The version information is
+ currently size independent. If that ever changes, this code will
+ need to move into elfcode.h. */
+
+/* Swap in a Verdef structure. */
+
+void
+_bfd_elf_swap_verdef_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Verdef *src;
+ Elf_Internal_Verdef *dst;
+{
+ dst->vd_version = bfd_h_get_16 (abfd, src->vd_version);
+ dst->vd_flags = bfd_h_get_16 (abfd, src->vd_flags);
+ dst->vd_ndx = bfd_h_get_16 (abfd, src->vd_ndx);
+ dst->vd_cnt = bfd_h_get_16 (abfd, src->vd_cnt);
+ dst->vd_hash = bfd_h_get_32 (abfd, src->vd_hash);
+ dst->vd_aux = bfd_h_get_32 (abfd, src->vd_aux);
+ dst->vd_next = bfd_h_get_32 (abfd, src->vd_next);
+}
+
+/* Swap out a Verdef structure. */
+
+void
+_bfd_elf_swap_verdef_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Verdef *src;
+ Elf_External_Verdef *dst;
+{
+ bfd_h_put_16 (abfd, src->vd_version, dst->vd_version);
+ bfd_h_put_16 (abfd, src->vd_flags, dst->vd_flags);
+ bfd_h_put_16 (abfd, src->vd_ndx, dst->vd_ndx);
+ bfd_h_put_16 (abfd, src->vd_cnt, dst->vd_cnt);
+ bfd_h_put_32 (abfd, src->vd_hash, dst->vd_hash);
+ bfd_h_put_32 (abfd, src->vd_aux, dst->vd_aux);
+ bfd_h_put_32 (abfd, src->vd_next, dst->vd_next);
+}
+
+/* Swap in a Verdaux structure. */
+
+void
+_bfd_elf_swap_verdaux_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Verdaux *src;
+ Elf_Internal_Verdaux *dst;
+{
+ dst->vda_name = bfd_h_get_32 (abfd, src->vda_name);
+ dst->vda_next = bfd_h_get_32 (abfd, src->vda_next);
+}
+
+/* Swap out a Verdaux structure. */
+
+void
+_bfd_elf_swap_verdaux_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Verdaux *src;
+ Elf_External_Verdaux *dst;
+{
+ bfd_h_put_32 (abfd, src->vda_name, dst->vda_name);
+ bfd_h_put_32 (abfd, src->vda_next, dst->vda_next);
+}
+
+/* Swap in a Verneed structure. */
+
+void
+_bfd_elf_swap_verneed_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Verneed *src;
+ Elf_Internal_Verneed *dst;
+{
+ dst->vn_version = bfd_h_get_16 (abfd, src->vn_version);
+ dst->vn_cnt = bfd_h_get_16 (abfd, src->vn_cnt);
+ dst->vn_file = bfd_h_get_32 (abfd, src->vn_file);
+ dst->vn_aux = bfd_h_get_32 (abfd, src->vn_aux);
+ dst->vn_next = bfd_h_get_32 (abfd, src->vn_next);
+}
+
+/* Swap out a Verneed structure. */
+
+void
+_bfd_elf_swap_verneed_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Verneed *src;
+ Elf_External_Verneed *dst;
+{
+ bfd_h_put_16 (abfd, src->vn_version, dst->vn_version);
+ bfd_h_put_16 (abfd, src->vn_cnt, dst->vn_cnt);
+ bfd_h_put_32 (abfd, src->vn_file, dst->vn_file);
+ bfd_h_put_32 (abfd, src->vn_aux, dst->vn_aux);
+ bfd_h_put_32 (abfd, src->vn_next, dst->vn_next);
+}
+
+/* Swap in a Vernaux structure. */
+
+void
+_bfd_elf_swap_vernaux_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Vernaux *src;
+ Elf_Internal_Vernaux *dst;
+{
+ dst->vna_hash = bfd_h_get_32 (abfd, src->vna_hash);
+ dst->vna_flags = bfd_h_get_16 (abfd, src->vna_flags);
+ dst->vna_other = bfd_h_get_16 (abfd, src->vna_other);
+ dst->vna_name = bfd_h_get_32 (abfd, src->vna_name);
+ dst->vna_next = bfd_h_get_32 (abfd, src->vna_next);
+}
+
+/* Swap out a Vernaux structure. */
+
+void
+_bfd_elf_swap_vernaux_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Vernaux *src;
+ Elf_External_Vernaux *dst;
+{
+ bfd_h_put_32 (abfd, src->vna_hash, dst->vna_hash);
+ bfd_h_put_16 (abfd, src->vna_flags, dst->vna_flags);
+ bfd_h_put_16 (abfd, src->vna_other, dst->vna_other);
+ bfd_h_put_32 (abfd, src->vna_name, dst->vna_name);
+ bfd_h_put_32 (abfd, src->vna_next, dst->vna_next);
+}
+
+/* Swap in a Versym structure. */
+
+void
+_bfd_elf_swap_versym_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Versym *src;
+ Elf_Internal_Versym *dst;
+{
+ dst->vs_vers = bfd_h_get_16 (abfd, src->vs_vers);
+}
+
+/* Swap out a Versym structure. */
+
+void
+_bfd_elf_swap_versym_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Versym *src;
+ Elf_External_Versym *dst;
+{
+ bfd_h_put_16 (abfd, src->vs_vers, dst->vs_vers);
+}
+
+/* Standard ELF hash function. Do not change this function; you will
+ cause invalid hash tables to be generated. */
+unsigned long
+bfd_elf_hash (name)
+ CONST unsigned char *name;
+{
+ unsigned long h = 0;
+ unsigned long g;
+ int ch;
+
+ while ((ch = *name++) != '\0')
+ {
+ h = (h << 4) + ch;
+ if ((g = (h & 0xf0000000)) != 0)
+ {
+ h ^= g >> 24;
+ /* The ELF ABI says `h &= ~g', but this is equivalent in
+ this case and on some machines one insn instead of two. */
+ h ^= g;
+ }
+ }
+ return h;
+}
+
+/* Read a specified number of bytes at a specified offset in an ELF
+ file, into a newly allocated buffer, and return a pointer to the
+ buffer. */
+
+static char *
+elf_read (abfd, offset, size)
+ bfd * abfd;
+ long offset;
+ unsigned int size;
+{
+ char *buf;
+
+ if ((buf = bfd_alloc (abfd, size)) == NULL)
+ return NULL;
+ if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+ return NULL;
+ if (bfd_read ((PTR) buf, size, 1, abfd) != size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_file_truncated);
+ return NULL;
+ }
+ return buf;
+}
+
+boolean
+bfd_elf_mkobject (abfd)
+ bfd * abfd;
+{
+ /* this just does initialization */
+ /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
+ elf_tdata (abfd) = (struct elf_obj_tdata *)
+ bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
+ if (elf_tdata (abfd) == 0)
+ return false;
+ /* since everything is done at close time, do we need any
+ initialization? */
+
+ return true;
+}
+
+boolean
+bfd_elf_mkcorefile (abfd)
+ bfd * abfd;
+{
+ /* I think this can be done just like an object file. */
+ return bfd_elf_mkobject (abfd);
+}
+
+char *
+bfd_elf_get_str_section (abfd, shindex)
+ bfd * abfd;
+ unsigned int shindex;
+{
+ Elf_Internal_Shdr **i_shdrp;
+ char *shstrtab = NULL;
+ unsigned int offset;
+ unsigned int shstrtabsize;
+
+ i_shdrp = elf_elfsections (abfd);
+ if (i_shdrp == 0 || i_shdrp[shindex] == 0)
+ return 0;
+
+ shstrtab = (char *) i_shdrp[shindex]->contents;
+ if (shstrtab == NULL)
+ {
+ /* No cached one, attempt to read, and cache what we read. */
+ offset = i_shdrp[shindex]->sh_offset;
+ shstrtabsize = i_shdrp[shindex]->sh_size;
+ shstrtab = elf_read (abfd, offset, shstrtabsize);
+ i_shdrp[shindex]->contents = (PTR) shstrtab;
+ }
+ return shstrtab;
+}
+
+char *
+bfd_elf_string_from_elf_section (abfd, shindex, strindex)
+ bfd * abfd;
+ unsigned int shindex;
+ unsigned int strindex;
+{
+ Elf_Internal_Shdr *hdr;
+
+ if (strindex == 0)
+ return "";
+
+ hdr = elf_elfsections (abfd)[shindex];
+
+ if (hdr->contents == NULL
+ && bfd_elf_get_str_section (abfd, shindex) == NULL)
+ return NULL;
+
+ if (strindex >= hdr->sh_size)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid string offset %u >= %lu for section `%s'"),
+ bfd_get_filename (abfd), strindex, (unsigned long) hdr->sh_size,
+ ((shindex == elf_elfheader(abfd)->e_shstrndx
+ && strindex == hdr->sh_name)
+ ? ".shstrtab"
+ : elf_string_from_elf_strtab (abfd, hdr->sh_name)));
+ return "";
+ }
+
+ return ((char *) hdr->contents) + strindex;
+}
+
+/* Make a BFD section from an ELF section. We store a pointer to the
+ BFD section in the bfd_section field of the header. */
+
+boolean
+_bfd_elf_make_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ const char *name;
+{
+ asection *newsect;
+ flagword flags;
+
+ if (hdr->bfd_section != NULL)
+ {
+ BFD_ASSERT (strcmp (name,
+ bfd_get_section_name (abfd, hdr->bfd_section)) == 0);
+ return true;
+ }
+
+ newsect = bfd_make_section_anyway (abfd, name);
+ if (newsect == NULL)
+ return false;
+
+ newsect->filepos = hdr->sh_offset;
+
+ if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
+ || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
+ || ! bfd_set_section_alignment (abfd, newsect,
+ bfd_log2 (hdr->sh_addralign)))
+ return false;
+
+ flags = SEC_NO_FLAGS;
+ if (hdr->sh_type != SHT_NOBITS)
+ flags |= SEC_HAS_CONTENTS;
+ if ((hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ flags |= SEC_ALLOC;
+ if (hdr->sh_type != SHT_NOBITS)
+ flags |= SEC_LOAD;
+ }
+ if ((hdr->sh_flags & SHF_WRITE) == 0)
+ flags |= SEC_READONLY;
+ if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
+ flags |= SEC_CODE;
+ else if ((flags & SEC_LOAD) != 0)
+ flags |= SEC_DATA;
+
+ /* The debugging sections appear to be recognized only by name, not
+ any sort of flag. */
+ if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
+ || strncmp (name, ".line", sizeof ".line" - 1) == 0
+ || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
+ flags |= SEC_DEBUGGING;
+
+ /* As a GNU extension, if the name begins with .gnu.linkonce, we
+ only link a single copy of the section. This is used to support
+ g++. g++ will emit each template expansion in its own section.
+ The symbols will be defined as weak, so that multiple definitions
+ are permitted. The GNU linker extension is to actually discard
+ all but one of the sections. */
+ if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0)
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+
+ if (! bfd_set_section_flags (abfd, newsect, flags))
+ return false;
+
+ if ((flags & SEC_ALLOC) != 0)
+ {
+ Elf_Internal_Phdr *phdr;
+ unsigned int i;
+
+ /* Look through the phdrs to see if we need to adjust the lma.
+ If all the p_paddr fields are zero, we ignore them, since
+ some ELF linkers produce such output. */
+ phdr = elf_tdata (abfd)->phdr;
+ for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+ {
+ if (phdr->p_paddr != 0)
+ break;
+ }
+ if (i < elf_elfheader (abfd)->e_phnum)
+ {
+ phdr = elf_tdata (abfd)->phdr;
+ for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+ {
+ if (phdr->p_type == PT_LOAD
+ && phdr->p_vaddr != phdr->p_paddr
+ && phdr->p_vaddr <= hdr->sh_addr
+ && (phdr->p_vaddr + phdr->p_memsz
+ >= hdr->sh_addr + hdr->sh_size)
+ && ((flags & SEC_LOAD) == 0
+ || (phdr->p_offset <= (bfd_vma) hdr->sh_offset
+ && (phdr->p_offset + phdr->p_filesz
+ >= hdr->sh_offset + hdr->sh_size))))
+ {
+ newsect->lma += phdr->p_paddr - phdr->p_vaddr;
+ break;
+ }
+ }
+ }
+ }
+
+ hdr->bfd_section = newsect;
+ elf_section_data (newsect)->this_hdr = *hdr;
+
+ return true;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_elf_find_section
+
+SYNOPSIS
+ struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);
+
+DESCRIPTION
+ Helper functions for GDB to locate the string tables.
+ Since BFD hides string tables from callers, GDB needs to use an
+ internal hook to find them. Sun's .stabstr, in particular,
+ isn't even pointed to by the .stab section, so ordinary
+ mechanisms wouldn't work to find it, even if we had some.
+*/
+
+struct elf_internal_shdr *
+bfd_elf_find_section (abfd, name)
+ bfd * abfd;
+ char *name;
+{
+ Elf_Internal_Shdr **i_shdrp;
+ char *shstrtab;
+ unsigned int max;
+ unsigned int i;
+
+ i_shdrp = elf_elfsections (abfd);
+ if (i_shdrp != NULL)
+ {
+ shstrtab = bfd_elf_get_str_section
+ (abfd, elf_elfheader (abfd)->e_shstrndx);
+ if (shstrtab != NULL)
+ {
+ max = elf_elfheader (abfd)->e_shnum;
+ for (i = 1; i < max; i++)
+ if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
+ return i_shdrp[i];
+ }
+ }
+ return 0;
+}
+
+const char *const bfd_elf_section_type_names[] = {
+ "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
+ "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
+ "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
+};
+
+/* ELF relocs are against symbols. If we are producing relocateable
+ output, and the reloc is against an external symbol, and nothing
+ has given us any additional addend, the resulting reloc will also
+ be against the same symbol. In such a case, we don't want to
+ change anything about the way the reloc is handled, since it will
+ all be done at final link time. Rather than put special case code
+ into bfd_perform_relocation, all the reloc types use this howto
+ function. It just short circuits the reloc if producing
+ relocateable output against an external symbol. */
+
+/*ARGSUSED*/
+bfd_reloc_status_type
+bfd_elf_generic_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ return bfd_reloc_continue;
+}
+
+/* Print out the program headers. */
+
+boolean
+_bfd_elf_print_private_bfd_data (abfd, farg)
+ bfd *abfd;
+ PTR farg;
+{
+ FILE *f = (FILE *) farg;
+ Elf_Internal_Phdr *p;
+ asection *s;
+ bfd_byte *dynbuf = NULL;
+
+ p = elf_tdata (abfd)->phdr;
+ if (p != NULL)
+ {
+ unsigned int i, c;
+
+ fprintf (f, _("\nProgram Header:\n"));
+ c = elf_elfheader (abfd)->e_phnum;
+ for (i = 0; i < c; i++, p++)
+ {
+ const char *s;
+ char buf[20];
+
+ switch (p->p_type)
+ {
+ case PT_NULL: s = "NULL"; break;
+ case PT_LOAD: s = "LOAD"; break;
+ case PT_DYNAMIC: s = "DYNAMIC"; break;
+ case PT_INTERP: s = "INTERP"; break;
+ case PT_NOTE: s = "NOTE"; break;
+ case PT_SHLIB: s = "SHLIB"; break;
+ case PT_PHDR: s = "PHDR"; break;
+ default: sprintf (buf, "0x%lx", p->p_type); s = buf; break;
+ }
+ fprintf (f, "%8s off 0x", s);
+ fprintf_vma (f, p->p_offset);
+ fprintf (f, " vaddr 0x");
+ fprintf_vma (f, p->p_vaddr);
+ fprintf (f, " paddr 0x");
+ fprintf_vma (f, p->p_paddr);
+ fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
+ fprintf (f, " filesz 0x");
+ fprintf_vma (f, p->p_filesz);
+ fprintf (f, " memsz 0x");
+ fprintf_vma (f, p->p_memsz);
+ fprintf (f, " flags %c%c%c",
+ (p->p_flags & PF_R) != 0 ? 'r' : '-',
+ (p->p_flags & PF_W) != 0 ? 'w' : '-',
+ (p->p_flags & PF_X) != 0 ? 'x' : '-');
+ if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0)
+ fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X));
+ fprintf (f, "\n");
+ }
+ }
+
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ int elfsec;
+ unsigned long link;
+ bfd_byte *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+
+ fprintf (f, _("\nDynamic Section:\n"));
+
+ dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size);
+ if (dynbuf == NULL)
+ goto error_return;
+ if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0,
+ s->_raw_size))
+ goto error_return;
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == -1)
+ goto error_return;
+ link = elf_elfsections (abfd)[elfsec]->sh_link;
+
+ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
+ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
+
+ extdyn = dynbuf;
+ extdynend = extdyn + s->_raw_size;
+ for (; extdyn < extdynend; extdyn += extdynsize)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ char ab[20];
+ boolean stringp;
+
+ (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ stringp = false;
+ switch (dyn.d_tag)
+ {
+ default:
+ sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
+ name = ab;
+ break;
+
+ case DT_NEEDED: name = "NEEDED"; stringp = true; break;
+ case DT_PLTRELSZ: name = "PLTRELSZ"; break;
+ case DT_PLTGOT: name = "PLTGOT"; break;
+ case DT_HASH: name = "HASH"; break;
+ case DT_STRTAB: name = "STRTAB"; break;
+ case DT_SYMTAB: name = "SYMTAB"; break;
+ case DT_RELA: name = "RELA"; break;
+ case DT_RELASZ: name = "RELASZ"; break;
+ case DT_RELAENT: name = "RELAENT"; break;
+ case DT_STRSZ: name = "STRSZ"; break;
+ case DT_SYMENT: name = "SYMENT"; break;
+ case DT_INIT: name = "INIT"; break;
+ case DT_FINI: name = "FINI"; break;
+ case DT_SONAME: name = "SONAME"; stringp = true; break;
+ case DT_RPATH: name = "RPATH"; stringp = true; break;
+ case DT_SYMBOLIC: name = "SYMBOLIC"; break;
+ case DT_REL: name = "REL"; break;
+ case DT_RELSZ: name = "RELSZ"; break;
+ case DT_RELENT: name = "RELENT"; break;
+ case DT_PLTREL: name = "PLTREL"; break;
+ case DT_DEBUG: name = "DEBUG"; break;
+ case DT_TEXTREL: name = "TEXTREL"; break;
+ case DT_JMPREL: name = "JMPREL"; break;
+ case DT_AUXILIARY: name = "AUXILIARY"; stringp = true; break;
+ case DT_FILTER: name = "FILTER"; stringp = true; break;
+ case DT_VERSYM: name = "VERSYM"; break;
+ case DT_VERDEF: name = "VERDEF"; break;
+ case DT_VERDEFNUM: name = "VERDEFNUM"; break;
+ case DT_VERNEED: name = "VERNEED"; break;
+ case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
+ }
+
+ fprintf (f, " %-11s ", name);
+ if (! stringp)
+ fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
+ else
+ {
+ const char *string;
+
+ string = bfd_elf_string_from_elf_section (abfd, link,
+ dyn.d_un.d_val);
+ if (string == NULL)
+ goto error_return;
+ fprintf (f, "%s", string);
+ }
+ fprintf (f, "\n");
+ }
+
+ free (dynbuf);
+ dynbuf = NULL;
+ }
+
+ if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
+ || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
+ {
+ if (! _bfd_elf_slurp_version_tables (abfd))
+ return false;
+ }
+
+ if (elf_dynverdef (abfd) != 0)
+ {
+ Elf_Internal_Verdef *t;
+
+ fprintf (f, _("\nVersion definitions:\n"));
+ for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
+ {
+ fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
+ t->vd_flags, t->vd_hash, t->vd_nodename);
+ if (t->vd_auxptr->vda_nextptr != NULL)
+ {
+ Elf_Internal_Verdaux *a;
+
+ fprintf (f, "\t");
+ for (a = t->vd_auxptr->vda_nextptr;
+ a != NULL;
+ a = a->vda_nextptr)
+ fprintf (f, "%s ", a->vda_nodename);
+ fprintf (f, "\n");
+ }
+ }
+ }
+
+ if (elf_dynverref (abfd) != 0)
+ {
+ Elf_Internal_Verneed *t;
+
+ fprintf (f, _("\nVersion References:\n"));
+ for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
+ {
+ Elf_Internal_Vernaux *a;
+
+ fprintf (f, _(" required from %s:\n"), t->vn_filename);
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
+ a->vna_flags, a->vna_other, a->vna_nodename);
+ }
+ }
+
+ return true;
+
+ error_return:
+ if (dynbuf != NULL)
+ free (dynbuf);
+ return false;
+}
+
+/* Display ELF-specific fields of a symbol. */
+
+void
+bfd_elf_print_symbol (abfd, filep, symbol, how)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) filep;
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ fprintf (file, "elf ");
+ fprintf_vma (file, symbol->value);
+ fprintf (file, " %lx", (long) symbol->flags);
+ break;
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name;
+ section_name = symbol->section ? symbol->section->name : "(*none*)";
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %s\t", section_name);
+ /* Print the "other" value for a symbol. For common symbols,
+ we've already printed the size; now print the alignment.
+ For other symbols, we have no specified alignment, and
+ we've printed the address; now print the size. */
+ fprintf_vma (file,
+ (bfd_is_com_section (symbol->section)
+ ? ((elf_symbol_type *) symbol)->internal_elf_sym.st_value
+ : ((elf_symbol_type *) symbol)->internal_elf_sym.st_size));
+
+ /* If we have version information, print it. */
+ if (elf_tdata (abfd)->dynversym_section != 0
+ && (elf_tdata (abfd)->dynverdef_section != 0
+ || elf_tdata (abfd)->dynverref_section != 0))
+ {
+ unsigned int vernum;
+ const char *version_string;
+
+ vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION;
+
+ if (vernum == 0)
+ version_string = "";
+ else if (vernum == 1)
+ version_string = "Base";
+ else if (vernum <= elf_tdata (abfd)->cverdefs)
+ version_string =
+ elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+ else
+ {
+ Elf_Internal_Verneed *t;
+
+ version_string = "";
+ for (t = elf_tdata (abfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ Elf_Internal_Vernaux *a;
+
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ {
+ if (a->vna_other == vernum)
+ {
+ version_string = a->vna_nodename;
+ break;
+ }
+ }
+ }
+ }
+
+ if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0)
+ fprintf (file, " %-11s", version_string);
+ else
+ {
+ int i;
+
+ fprintf (file, " (%s)", version_string);
+ for (i = 10 - strlen (version_string); i > 0; --i)
+ putc (' ', file);
+ }
+ }
+
+ /* If the st_other field is not zero, print it. */
+ if (((elf_symbol_type *) symbol)->internal_elf_sym.st_other != 0)
+ fprintf (file, " 0x%02x",
+ ((unsigned int)
+ ((elf_symbol_type *) symbol)->internal_elf_sym.st_other));
+
+ fprintf (file, " %s", symbol->name);
+ }
+ break;
+ }
+}
+
+/* Create an entry in an ELF linker hash table. */
+
+struct bfd_hash_entry *
+_bfd_elf_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf_link_hash_entry *) NULL)
+ ret = ((struct elf_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)));
+ if (ret == (struct elf_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf_link_hash_entry *) NULL)
+ {
+ /* Set local fields. */
+ ret->indx = -1;
+ ret->size = 0;
+ ret->dynindx = -1;
+ ret->dynstr_index = 0;
+ ret->weakdef = NULL;
+ ret->got.offset = (bfd_vma) -1;
+ ret->plt.offset = (bfd_vma) -1;
+ ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
+ ret->verinfo.verdef = NULL;
+ ret->vtable_entries_used = NULL;
+ ret->vtable_entries_size = 0;
+ ret->vtable_parent = NULL;
+ ret->type = STT_NOTYPE;
+ ret->other = 0;
+ /* Assume that we have been called by a non-ELF symbol reader.
+ This flag is then reset by the code which reads an ELF input
+ file. This ensures that a symbol created by a non-ELF symbol
+ reader will have the flag set correctly. */
+ ret->elf_link_hash_flags = ELF_LINK_NON_ELF;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize an ELF linker hash table. */
+
+boolean
+_bfd_elf_link_hash_table_init (table, abfd, newfunc)
+ struct elf_link_hash_table *table;
+ bfd *abfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ table->dynamic_sections_created = false;
+ table->dynobj = NULL;
+ /* The first dynamic symbol is a dummy. */
+ table->dynsymcount = 1;
+ table->dynstr = NULL;
+ table->bucketcount = 0;
+ table->needed = NULL;
+ table->hgot = NULL;
+ table->stab_info = NULL;
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+}
+
+/* Create an ELF linker hash table. */
+
+struct bfd_link_hash_table *
+_bfd_elf_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct elf_link_hash_table *ret;
+
+ ret = ((struct elf_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf_link_hash_table)));
+ if (ret == (struct elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ return &ret->root;
+}
+
+/* This is a hook for the ELF emulation code in the generic linker to
+ tell the backend linker what file name to use for the DT_NEEDED
+ entry for a dynamic object. The generic linker passes name as an
+ empty string to indicate that no DT_NEEDED entry should be made. */
+
+void
+bfd_elf_set_dt_needed_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_get_format (abfd) == bfd_object)
+ elf_dt_name (abfd) = name;
+}
+
+/* Get the list of DT_NEEDED entries for a link. This is a hook for
+ the linker ELF emulation code. */
+
+struct bfd_link_needed_list *
+bfd_elf_get_needed_list (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ if (info->hash->creator->flavour != bfd_target_elf_flavour)
+ return NULL;
+ return elf_hash_table (info)->needed;
+}
+
+/* Get the name actually used for a dynamic object for a link. This
+ is the SONAME entry if there is one. Otherwise, it is the string
+ passed to bfd_elf_set_dt_needed_name, or it is the filename. */
+
+const char *
+bfd_elf_get_dt_soname (abfd)
+ bfd *abfd;
+{
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_get_format (abfd) == bfd_object)
+ return elf_dt_name (abfd);
+ return NULL;
+}
+
+/* Get the list of DT_NEEDED entries from a BFD. This is a hook for
+ the ELF linker emulation code. */
+
+boolean
+bfd_elf_get_bfd_needed_list (abfd, pneeded)
+ bfd *abfd;
+ struct bfd_link_needed_list **pneeded;
+{
+ asection *s;
+ bfd_byte *dynbuf = NULL;
+ int elfsec;
+ unsigned long link;
+ bfd_byte *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+
+ *pneeded = NULL;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
+ || bfd_get_format (abfd) != bfd_object)
+ return true;
+
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s == NULL || s->_raw_size == 0)
+ return true;
+
+ dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size);
+ if (dynbuf == NULL)
+ goto error_return;
+
+ if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0,
+ s->_raw_size))
+ goto error_return;
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == -1)
+ goto error_return;
+
+ link = elf_elfsections (abfd)[elfsec]->sh_link;
+
+ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
+ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
+
+ extdyn = dynbuf;
+ extdynend = extdyn + s->_raw_size;
+ for (; extdyn < extdynend; extdyn += extdynsize)
+ {
+ Elf_Internal_Dyn dyn;
+
+ (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ if (dyn.d_tag == DT_NEEDED)
+ {
+ const char *string;
+ struct bfd_link_needed_list *l;
+
+ string = bfd_elf_string_from_elf_section (abfd, link,
+ dyn.d_un.d_val);
+ if (string == NULL)
+ goto error_return;
+
+ l = (struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof *l);
+ if (l == NULL)
+ goto error_return;
+
+ l->by = abfd;
+ l->name = string;
+ l->next = *pneeded;
+ *pneeded = l;
+ }
+ }
+
+ free (dynbuf);
+
+ return true;
+
+ error_return:
+ if (dynbuf != NULL)
+ free (dynbuf);
+ return false;
+}
+
+/* Allocate an ELF string table--force the first byte to be zero. */
+
+struct bfd_strtab_hash *
+_bfd_elf_stringtab_init ()
+{
+ struct bfd_strtab_hash *ret;
+
+ ret = _bfd_stringtab_init ();
+ if (ret != NULL)
+ {
+ bfd_size_type loc;
+
+ loc = _bfd_stringtab_add (ret, "", true, false);
+ BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1);
+ if (loc == (bfd_size_type) -1)
+ {
+ _bfd_stringtab_free (ret);
+ ret = NULL;
+ }
+ }
+ return ret;
+}
+
+/* ELF .o/exec file reading */
+
+/* Create a new bfd section from an ELF section header. */
+
+boolean
+bfd_section_from_shdr (abfd, shindex)
+ bfd *abfd;
+ unsigned int shindex;
+{
+ Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
+ Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ char *name;
+
+ name = elf_string_from_elf_strtab (abfd, hdr->sh_name);
+
+ switch (hdr->sh_type)
+ {
+ case SHT_NULL:
+ /* Inactive section. Throw it away. */
+ return true;
+
+ case SHT_PROGBITS: /* Normal section with contents. */
+ case SHT_DYNAMIC: /* Dynamic linking information. */
+ case SHT_NOBITS: /* .bss section. */
+ case SHT_HASH: /* .hash section. */
+ case SHT_NOTE: /* .note section. */
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+
+ case SHT_SYMTAB: /* A symbol table */
+ if (elf_onesymtab (abfd) == shindex)
+ return true;
+
+ BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym);
+ BFD_ASSERT (elf_onesymtab (abfd) == 0);
+ elf_onesymtab (abfd) = shindex;
+ elf_tdata (abfd)->symtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
+ abfd->flags |= HAS_SYMS;
+
+ /* Sometimes a shared object will map in the symbol table. If
+ SHF_ALLOC is set, and this is a shared object, then we also
+ treat this section as a BFD section. We can not base the
+ decision purely on SHF_ALLOC, because that flag is sometimes
+ set in a relocateable object file, which would confuse the
+ linker. */
+ if ((hdr->sh_flags & SHF_ALLOC) != 0
+ && (abfd->flags & DYNAMIC) != 0
+ && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+
+ return true;
+
+ case SHT_DYNSYM: /* A dynamic symbol table */
+ if (elf_dynsymtab (abfd) == shindex)
+ return true;
+
+ BFD_ASSERT (hdr->sh_entsize == bed->s->sizeof_sym);
+ BFD_ASSERT (elf_dynsymtab (abfd) == 0);
+ elf_dynsymtab (abfd) = shindex;
+ elf_tdata (abfd)->dynsymtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ abfd->flags |= HAS_SYMS;
+
+ /* Besides being a symbol table, we also treat this as a regular
+ section, so that objcopy can handle it. */
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+
+ case SHT_STRTAB: /* A string table */
+ if (hdr->bfd_section != NULL)
+ return true;
+ if (ehdr->e_shstrndx == shindex)
+ {
+ elf_tdata (abfd)->shstrtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
+ return true;
+ }
+ {
+ unsigned int i;
+
+ for (i = 1; i < ehdr->e_shnum; i++)
+ {
+ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
+ if (hdr2->sh_link == shindex)
+ {
+ if (! bfd_section_from_shdr (abfd, i))
+ return false;
+ if (elf_onesymtab (abfd) == i)
+ {
+ elf_tdata (abfd)->strtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] =
+ &elf_tdata (abfd)->strtab_hdr;
+ return true;
+ }
+ if (elf_dynsymtab (abfd) == i)
+ {
+ elf_tdata (abfd)->dynstrtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = hdr =
+ &elf_tdata (abfd)->dynstrtab_hdr;
+ /* We also treat this as a regular section, so
+ that objcopy can handle it. */
+ break;
+ }
+#if 0 /* Not handling other string tables specially right now. */
+ hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */
+ /* We have a strtab for some random other section. */
+ newsect = (asection *) hdr2->bfd_section;
+ if (!newsect)
+ break;
+ hdr->bfd_section = newsect;
+ hdr2 = &elf_section_data (newsect)->str_hdr;
+ *hdr2 = *hdr;
+ elf_elfsections (abfd)[shindex] = hdr2;
+#endif
+ }
+ }
+ }
+
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+
+ case SHT_REL:
+ case SHT_RELA:
+ /* *These* do a lot of work -- but build no sections! */
+ {
+ asection *target_sect;
+ Elf_Internal_Shdr *hdr2;
+
+ /* For some incomprehensible reason Oracle distributes
+ libraries for Solaris in which some of the objects have
+ bogus sh_link fields. It would be nice if we could just
+ reject them, but, unfortunately, some people need to use
+ them. We scan through the section headers; if we find only
+ one suitable symbol table, we clobber the sh_link to point
+ to it. I hope this doesn't break anything. */
+ if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
+ && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
+ {
+ int scan;
+ int found;
+
+ found = 0;
+ for (scan = 1; scan < ehdr->e_shnum; scan++)
+ {
+ if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
+ || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
+ {
+ if (found != 0)
+ {
+ found = 0;
+ break;
+ }
+ found = scan;
+ }
+ }
+ if (found != 0)
+ hdr->sh_link = found;
+ }
+
+ /* Get the symbol table. */
+ if (elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
+ && ! bfd_section_from_shdr (abfd, hdr->sh_link))
+ return false;
+
+ /* If this reloc section does not use the main symbol table we
+ don't treat it as a reloc section. BFD can't adequately
+ represent such a section, so at least for now, we don't
+ try. We just present it as a normal section. */
+ if (hdr->sh_link != elf_onesymtab (abfd))
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+
+ if (! bfd_section_from_shdr (abfd, hdr->sh_info))
+ return false;
+ target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
+ if (target_sect == NULL)
+ return false;
+
+ if ((target_sect->flags & SEC_RELOC) == 0
+ || target_sect->reloc_count == 0)
+ hdr2 = &elf_section_data (target_sect)->rel_hdr;
+ else
+ {
+ BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
+ hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
+ elf_section_data (target_sect)->rel_hdr2 = hdr2;
+ }
+ *hdr2 = *hdr;
+ elf_elfsections (abfd)[shindex] = hdr2;
+ target_sect->reloc_count += hdr->sh_size / hdr->sh_entsize;
+ target_sect->flags |= SEC_RELOC;
+ target_sect->relocation = NULL;
+ target_sect->rel_filepos = hdr->sh_offset;
+ abfd->flags |= HAS_RELOC;
+ return true;
+ }
+ break;
+
+ case SHT_GNU_verdef:
+ elf_dynverdef (abfd) = shindex;
+ elf_tdata (abfd)->dynverdef_hdr = *hdr;
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+ break;
+
+ case SHT_GNU_versym:
+ elf_dynversym (abfd) = shindex;
+ elf_tdata (abfd)->dynversym_hdr = *hdr;
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+ break;
+
+ case SHT_GNU_verneed:
+ elf_dynverref (abfd) = shindex;
+ elf_tdata (abfd)->dynverref_hdr = *hdr;
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+ break;
+
+ case SHT_SHLIB:
+ return true;
+
+ default:
+ /* Check for any processor-specific section types. */
+ {
+ if (bed->elf_backend_section_from_shdr)
+ (*bed->elf_backend_section_from_shdr) (abfd, hdr, name);
+ }
+ break;
+ }
+
+ return true;
+}
+
+/* Given an ELF section number, retrieve the corresponding BFD
+ section. */
+
+asection *
+bfd_section_from_elf_index (abfd, index)
+ bfd *abfd;
+ unsigned int index;
+{
+ BFD_ASSERT (index > 0 && index < SHN_LORESERVE);
+ if (index >= elf_elfheader (abfd)->e_shnum)
+ return NULL;
+ return elf_elfsections (abfd)[index]->bfd_section;
+}
+
+boolean
+_bfd_elf_new_section_hook (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ struct bfd_elf_section_data *sdata;
+
+ sdata = (struct bfd_elf_section_data *) bfd_alloc (abfd, sizeof (*sdata));
+ if (!sdata)
+ return false;
+ sec->used_by_bfd = (PTR) sdata;
+ memset (sdata, 0, sizeof (*sdata));
+ return true;
+}
+
+/* Create a new bfd section from an ELF program header.
+
+ Since program segments have no names, we generate a synthetic name
+ of the form segment<NUM>, where NUM is generally the index in the
+ program header table. For segments that are split (see below) we
+ generate the names segment<NUM>a and segment<NUM>b.
+
+ Note that some program segments may have a file size that is different than
+ (less than) the memory size. All this means is that at execution the
+ system must allocate the amount of memory specified by the memory size,
+ but only initialize it with the first "file size" bytes read from the
+ file. This would occur for example, with program segments consisting
+ of combined data+bss.
+
+ To handle the above situation, this routine generates TWO bfd sections
+ for the single program segment. The first has the length specified by
+ the file size of the segment, and the second has the length specified
+ by the difference between the two sizes. In effect, the segment is split
+ into it's initialized and uninitialized parts.
+
+ */
+
+boolean
+bfd_section_from_phdr (abfd, hdr, index)
+ bfd *abfd;
+ Elf_Internal_Phdr *hdr;
+ int index;
+{
+ asection *newsect;
+ char *name;
+ char namebuf[64];
+ int split;
+
+ split = ((hdr->p_memsz > 0)
+ && (hdr->p_filesz > 0)
+ && (hdr->p_memsz > hdr->p_filesz));
+ sprintf (namebuf, split ? "segment%da" : "segment%d", index);
+ name = bfd_alloc (abfd, strlen (namebuf) + 1);
+ if (!name)
+ return false;
+ strcpy (name, namebuf);
+ newsect = bfd_make_section (abfd, name);
+ if (newsect == NULL)
+ return false;
+ newsect->vma = hdr->p_vaddr;
+ newsect->lma = hdr->p_paddr;
+ newsect->_raw_size = hdr->p_filesz;
+ newsect->filepos = hdr->p_offset;
+ newsect->flags |= SEC_HAS_CONTENTS;
+ if (hdr->p_type == PT_LOAD)
+ {
+ newsect->flags |= SEC_ALLOC;
+ newsect->flags |= SEC_LOAD;
+ if (hdr->p_flags & PF_X)
+ {
+ /* FIXME: all we known is that it has execute PERMISSION,
+ may be data. */
+ newsect->flags |= SEC_CODE;
+ }
+ }
+ if (!(hdr->p_flags & PF_W))
+ {
+ newsect->flags |= SEC_READONLY;
+ }
+
+ if (split)
+ {
+ sprintf (namebuf, "segment%db", index);
+ name = bfd_alloc (abfd, strlen (namebuf) + 1);
+ if (!name)
+ return false;
+ strcpy (name, namebuf);
+ newsect = bfd_make_section (abfd, name);
+ if (newsect == NULL)
+ return false;
+ newsect->vma = hdr->p_vaddr + hdr->p_filesz;
+ newsect->lma = hdr->p_paddr + hdr->p_filesz;
+ newsect->_raw_size = hdr->p_memsz - hdr->p_filesz;
+ if (hdr->p_type == PT_LOAD)
+ {
+ newsect->flags |= SEC_ALLOC;
+ if (hdr->p_flags & PF_X)
+ newsect->flags |= SEC_CODE;
+ }
+ if (!(hdr->p_flags & PF_W))
+ newsect->flags |= SEC_READONLY;
+ }
+
+ return true;
+}
+
+/* Set up an ELF internal section header for a section. */
+
+/*ARGSUSED*/
+static void
+elf_fake_sections (abfd, asect, failedptrarg)
+ bfd *abfd;
+ asection *asect;
+ PTR failedptrarg;
+{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ boolean *failedptr = (boolean *) failedptrarg;
+ Elf_Internal_Shdr *this_hdr;
+
+ if (*failedptr)
+ {
+ /* We already failed; just get out of the bfd_map_over_sections
+ loop. */
+ return;
+ }
+
+ this_hdr = &elf_section_data (asect)->this_hdr;
+
+ this_hdr->sh_name = (unsigned long) _bfd_stringtab_add (elf_shstrtab (abfd),
+ asect->name,
+ true, false);
+ if (this_hdr->sh_name == (unsigned long) -1)
+ {
+ *failedptr = true;
+ return;
+ }
+
+ this_hdr->sh_flags = 0;
+
+ if ((asect->flags & SEC_ALLOC) != 0
+ || asect->user_set_vma)
+ this_hdr->sh_addr = asect->vma;
+ else
+ this_hdr->sh_addr = 0;
+
+ this_hdr->sh_offset = 0;
+ this_hdr->sh_size = asect->_raw_size;
+ this_hdr->sh_link = 0;
+ this_hdr->sh_addralign = 1 << asect->alignment_power;
+ /* The sh_entsize and sh_info fields may have been set already by
+ copy_private_section_data. */
+
+ this_hdr->bfd_section = asect;
+ this_hdr->contents = NULL;
+
+ /* FIXME: This should not be based on section names. */
+ if (strcmp (asect->name, ".dynstr") == 0)
+ this_hdr->sh_type = SHT_STRTAB;
+ else if (strcmp (asect->name, ".hash") == 0)
+ {
+ this_hdr->sh_type = SHT_HASH;
+ this_hdr->sh_entsize = bed->s->arch_size / 8;
+ }
+ else if (strcmp (asect->name, ".dynsym") == 0)
+ {
+ this_hdr->sh_type = SHT_DYNSYM;
+ this_hdr->sh_entsize = bed->s->sizeof_sym;
+ }
+ else if (strcmp (asect->name, ".dynamic") == 0)
+ {
+ this_hdr->sh_type = SHT_DYNAMIC;
+ this_hdr->sh_entsize = bed->s->sizeof_dyn;
+ }
+ else if (strncmp (asect->name, ".rela", 5) == 0
+ && get_elf_backend_data (abfd)->use_rela_p)
+ {
+ this_hdr->sh_type = SHT_RELA;
+ this_hdr->sh_entsize = bed->s->sizeof_rela;
+ }
+ else if (strncmp (asect->name, ".rel", 4) == 0
+ && ! get_elf_backend_data (abfd)->use_rela_p)
+ {
+ this_hdr->sh_type = SHT_REL;
+ this_hdr->sh_entsize = bed->s->sizeof_rel;
+ }
+ else if (strncmp (asect->name, ".note", 5) == 0)
+ this_hdr->sh_type = SHT_NOTE;
+ else if (strncmp (asect->name, ".stab", 5) == 0
+ && strcmp (asect->name + strlen (asect->name) - 3, "str") == 0)
+ this_hdr->sh_type = SHT_STRTAB;
+ else if (strcmp (asect->name, ".gnu.version") == 0)
+ {
+ this_hdr->sh_type = SHT_GNU_versym;
+ this_hdr->sh_entsize = sizeof (Elf_External_Versym);
+ }
+ else if (strcmp (asect->name, ".gnu.version_d") == 0)
+ {
+ this_hdr->sh_type = SHT_GNU_verdef;
+ this_hdr->sh_entsize = 0;
+ /* objcopy or strip will copy over sh_info, but may not set
+ cverdefs. The linker will set cverdefs, but sh_info will be
+ zero. */
+ if (this_hdr->sh_info == 0)
+ this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
+ else
+ BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
+ || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
+ }
+ else if (strcmp (asect->name, ".gnu.version_r") == 0)
+ {
+ this_hdr->sh_type = SHT_GNU_verneed;
+ this_hdr->sh_entsize = 0;
+ /* objcopy or strip will copy over sh_info, but may not set
+ cverrefs. The linker will set cverrefs, but sh_info will be
+ zero. */
+ if (this_hdr->sh_info == 0)
+ this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
+ else
+ BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
+ || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
+ }
+ else if ((asect->flags & SEC_ALLOC) != 0
+ && (asect->flags & SEC_LOAD) != 0)
+ this_hdr->sh_type = SHT_PROGBITS;
+ else if ((asect->flags & SEC_ALLOC) != 0
+ && ((asect->flags & SEC_LOAD) == 0))
+ this_hdr->sh_type = SHT_NOBITS;
+ else
+ {
+ /* Who knows? */
+ this_hdr->sh_type = SHT_PROGBITS;
+ }
+
+ if ((asect->flags & SEC_ALLOC) != 0)
+ this_hdr->sh_flags |= SHF_ALLOC;
+ if ((asect->flags & SEC_READONLY) == 0)
+ this_hdr->sh_flags |= SHF_WRITE;
+ if ((asect->flags & SEC_CODE) != 0)
+ this_hdr->sh_flags |= SHF_EXECINSTR;
+
+ /* Check for processor-specific section types. */
+ {
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (bed->elf_backend_fake_sections)
+ (*bed->elf_backend_fake_sections) (abfd, this_hdr, asect);
+ }
+
+ /* If the section has relocs, set up a section header for the
+ SHT_REL[A] section. */
+ if ((asect->flags & SEC_RELOC) != 0)
+ {
+ Elf_Internal_Shdr *rela_hdr;
+ int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
+ char *name;
+
+ rela_hdr = &elf_section_data (asect)->rel_hdr;
+ name = bfd_alloc (abfd, sizeof ".rela" + strlen (asect->name));
+ if (name == NULL)
+ {
+ *failedptr = true;
+ return;
+ }
+ sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
+ rela_hdr->sh_name =
+ (unsigned int) _bfd_stringtab_add (elf_shstrtab (abfd), name,
+ true, false);
+ if (rela_hdr->sh_name == (unsigned int) -1)
+ {
+ *failedptr = true;
+ return;
+ }
+ rela_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
+ rela_hdr->sh_entsize = (use_rela_p
+ ? bed->s->sizeof_rela
+ : bed->s->sizeof_rel);
+ rela_hdr->sh_addralign = bed->s->file_align;
+ rela_hdr->sh_flags = 0;
+ rela_hdr->sh_addr = 0;
+ rela_hdr->sh_size = 0;
+ rela_hdr->sh_offset = 0;
+ }
+}
+
+/* Assign all ELF section numbers. The dummy first section is handled here
+ too. The link/info pointers for the standard section types are filled
+ in here too, while we're at it. */
+
+static boolean
+assign_section_numbers (abfd)
+ bfd *abfd;
+{
+ struct elf_obj_tdata *t = elf_tdata (abfd);
+ asection *sec;
+ unsigned int section_number;
+ Elf_Internal_Shdr **i_shdrp;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ section_number = 1;
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ struct bfd_elf_section_data *d = elf_section_data (sec);
+
+ d->this_idx = section_number++;
+ if ((sec->flags & SEC_RELOC) == 0)
+ d->rel_idx = 0;
+ else
+ d->rel_idx = section_number++;
+ }
+
+ t->shstrtab_section = section_number++;
+ elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
+ t->shstrtab_hdr.sh_size = _bfd_stringtab_size (elf_shstrtab (abfd));
+
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ t->symtab_section = section_number++;
+ t->strtab_section = section_number++;
+ }
+
+ elf_elfheader (abfd)->e_shnum = section_number;
+
+ /* Set up the list of section header pointers, in agreement with the
+ indices. */
+ i_shdrp = ((Elf_Internal_Shdr **)
+ bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *)));
+ if (i_shdrp == NULL)
+ return false;
+
+ i_shdrp[0] = ((Elf_Internal_Shdr *)
+ bfd_alloc (abfd, sizeof (Elf_Internal_Shdr)));
+ if (i_shdrp[0] == NULL)
+ {
+ bfd_release (abfd, i_shdrp);
+ return false;
+ }
+ memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr));
+
+ elf_elfsections (abfd) = i_shdrp;
+
+ i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ i_shdrp[t->symtab_section] = &t->symtab_hdr;
+ i_shdrp[t->strtab_section] = &t->strtab_hdr;
+ t->symtab_hdr.sh_link = t->strtab_section;
+ }
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ struct bfd_elf_section_data *d = elf_section_data (sec);
+ asection *s;
+ const char *name;
+
+ i_shdrp[d->this_idx] = &d->this_hdr;
+ if (d->rel_idx != 0)
+ i_shdrp[d->rel_idx] = &d->rel_hdr;
+
+ /* Fill in the sh_link and sh_info fields while we're at it. */
+
+ /* sh_link of a reloc section is the section index of the symbol
+ table. sh_info is the section index of the section to which
+ the relocation entries apply. */
+ if (d->rel_idx != 0)
+ {
+ d->rel_hdr.sh_link = t->symtab_section;
+ d->rel_hdr.sh_info = d->this_idx;
+ }
+
+ switch (d->this_hdr.sh_type)
+ {
+ case SHT_REL:
+ case SHT_RELA:
+ /* A reloc section which we are treating as a normal BFD
+ section. sh_link is the section index of the symbol
+ table. sh_info is the section index of the section to
+ which the relocation entries apply. We assume that an
+ allocated reloc section uses the dynamic symbol table.
+ FIXME: How can we be sure? */
+ s = bfd_get_section_by_name (abfd, ".dynsym");
+ if (s != NULL)
+ d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+
+ /* We look up the section the relocs apply to by name. */
+ name = sec->name;
+ if (d->this_hdr.sh_type == SHT_REL)
+ name += 4;
+ else
+ name += 5;
+ s = bfd_get_section_by_name (abfd, name);
+ if (s != NULL)
+ d->this_hdr.sh_info = elf_section_data (s)->this_idx;
+ break;
+
+ case SHT_STRTAB:
+ /* We assume that a section named .stab*str is a stabs
+ string section. We look for a section with the same name
+ but without the trailing ``str'', and set its sh_link
+ field to point to this section. */
+ if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0
+ && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
+ {
+ size_t len;
+ char *alc;
+
+ len = strlen (sec->name);
+ alc = (char *) bfd_malloc (len - 2);
+ if (alc == NULL)
+ return false;
+ strncpy (alc, sec->name, len - 3);
+ alc[len - 3] = '\0';
+ s = bfd_get_section_by_name (abfd, alc);
+ free (alc);
+ if (s != NULL)
+ {
+ elf_section_data (s)->this_hdr.sh_link = d->this_idx;
+
+ /* This is a .stab section. */
+ elf_section_data (s)->this_hdr.sh_entsize =
+ 4 + 2 * (bed->s->arch_size / 8);
+ }
+ }
+ break;
+
+ case SHT_DYNAMIC:
+ case SHT_DYNSYM:
+ case SHT_GNU_verneed:
+ case SHT_GNU_verdef:
+ /* sh_link is the section header index of the string table
+ used for the dynamic entries, or the symbol table, or the
+ version strings. */
+ s = bfd_get_section_by_name (abfd, ".dynstr");
+ if (s != NULL)
+ d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+ break;
+
+ case SHT_HASH:
+ case SHT_GNU_versym:
+ /* sh_link is the section header index of the symbol table
+ this hash table or version table is for. */
+ s = bfd_get_section_by_name (abfd, ".dynsym");
+ if (s != NULL)
+ d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Map symbol from it's internal number to the external number, moving
+ all local symbols to be at the head of the list. */
+
+static INLINE int
+sym_is_global (abfd, sym)
+ bfd *abfd;
+ asymbol *sym;
+{
+ /* If the backend has a special mapping, use it. */
+ if (get_elf_backend_data (abfd)->elf_backend_sym_is_global)
+ return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global)
+ (abfd, sym));
+
+ return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)));
+}
+
+static boolean
+elf_map_symbols (abfd)
+ bfd *abfd;
+{
+ int symcount = bfd_get_symcount (abfd);
+ asymbol **syms = bfd_get_outsymbols (abfd);
+ asymbol **sect_syms;
+ int num_locals = 0;
+ int num_globals = 0;
+ int num_locals2 = 0;
+ int num_globals2 = 0;
+ int max_index = 0;
+ int num_sections = 0;
+ int idx;
+ asection *asect;
+ asymbol **new_syms;
+ asymbol *sym;
+
+#ifdef DEBUG
+ fprintf (stderr, "elf_map_symbols\n");
+ fflush (stderr);
+#endif
+
+ /* Add a section symbol for each BFD section. FIXME: Is this really
+ necessary? */
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (max_index < asect->index)
+ max_index = asect->index;
+ }
+
+ max_index++;
+ sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *));
+ if (sect_syms == NULL)
+ return false;
+ elf_section_syms (abfd) = sect_syms;
+
+ for (idx = 0; idx < symcount; idx++)
+ {
+ sym = syms[idx];
+
+ if ((sym->flags & BSF_SECTION_SYM) != 0
+ && sym->value == 0)
+ {
+ asection *sec;
+
+ sec = sym->section;
+
+ if (sec->owner != NULL)
+ {
+ if (sec->owner != abfd)
+ {
+ if (sec->output_offset != 0)
+ continue;
+
+ sec = sec->output_section;
+
+ /* Empty sections in the input files may have had a section
+ symbol created for them. (See the comment near the end of
+ _bfd_generic_link_output_symbols in linker.c). If the linker
+ script discards such sections then we will reach this point.
+ Since we know that we cannot avoid this case, we detect it
+ and skip the abort and the assignment to the sect_syms array.
+ To reproduce this particular case try running the linker
+ testsuite test ld-scripts/weak.exp for an ELF port that uses
+ the generic linker. */
+ if (sec->owner == NULL)
+ continue;
+
+ BFD_ASSERT (sec->owner == abfd);
+ }
+ sect_syms[sec->index] = syms[idx];
+ }
+ }
+ }
+
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (sect_syms[asect->index] != NULL)
+ continue;
+
+ sym = bfd_make_empty_symbol (abfd);
+ if (sym == NULL)
+ return false;
+ sym->the_bfd = abfd;
+ sym->name = asect->name;
+ sym->value = 0;
+ /* Set the flags to 0 to indicate that this one was newly added. */
+ sym->flags = 0;
+ sym->section = asect;
+ sect_syms[asect->index] = sym;
+ num_sections++;
+#ifdef DEBUG
+ fprintf (stderr,
+ _("creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n"),
+ asect->name, (long) asect->vma, asect->index, (long) asect);
+#endif
+ }
+
+ /* Classify all of the symbols. */
+ for (idx = 0; idx < symcount; idx++)
+ {
+ if (!sym_is_global (abfd, syms[idx]))
+ num_locals++;
+ else
+ num_globals++;
+ }
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (sect_syms[asect->index] != NULL
+ && sect_syms[asect->index]->flags == 0)
+ {
+ sect_syms[asect->index]->flags = BSF_SECTION_SYM;
+ if (!sym_is_global (abfd, sect_syms[asect->index]))
+ num_locals++;
+ else
+ num_globals++;
+ sect_syms[asect->index]->flags = 0;
+ }
+ }
+
+ /* Now sort the symbols so the local symbols are first. */
+ new_syms = ((asymbol **)
+ bfd_alloc (abfd,
+ (num_locals + num_globals) * sizeof (asymbol *)));
+ if (new_syms == NULL)
+ return false;
+
+ for (idx = 0; idx < symcount; idx++)
+ {
+ asymbol *sym = syms[idx];
+ int i;
+
+ if (!sym_is_global (abfd, sym))
+ i = num_locals2++;
+ else
+ i = num_locals + num_globals2++;
+ new_syms[i] = sym;
+ sym->udata.i = i + 1;
+ }
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (sect_syms[asect->index] != NULL
+ && sect_syms[asect->index]->flags == 0)
+ {
+ asymbol *sym = sect_syms[asect->index];
+ int i;
+
+ sym->flags = BSF_SECTION_SYM;
+ if (!sym_is_global (abfd, sym))
+ i = num_locals2++;
+ else
+ i = num_locals + num_globals2++;
+ new_syms[i] = sym;
+ sym->udata.i = i + 1;
+ }
+ }
+
+ bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
+
+ elf_num_locals (abfd) = num_locals;
+ elf_num_globals (abfd) = num_globals;
+ return true;
+}
+
+/* Align to the maximum file alignment that could be required for any
+ ELF data structure. */
+
+static INLINE file_ptr align_file_position PARAMS ((file_ptr, int));
+static INLINE file_ptr
+align_file_position (off, align)
+ file_ptr off;
+ int align;
+{
+ return (off + align - 1) & ~(align - 1);
+}
+
+/* Assign a file position to a section, optionally aligning to the
+ required section alignment. */
+
+INLINE file_ptr
+_bfd_elf_assign_file_position_for_section (i_shdrp, offset, align)
+ Elf_Internal_Shdr *i_shdrp;
+ file_ptr offset;
+ boolean align;
+{
+ if (align)
+ {
+ unsigned int al;
+
+ al = i_shdrp->sh_addralign;
+ if (al > 1)
+ offset = BFD_ALIGN (offset, al);
+ }
+ i_shdrp->sh_offset = offset;
+ if (i_shdrp->bfd_section != NULL)
+ i_shdrp->bfd_section->filepos = offset;
+ if (i_shdrp->sh_type != SHT_NOBITS)
+ offset += i_shdrp->sh_size;
+ return offset;
+}
+
+/* Compute the file positions we are going to put the sections at, and
+ otherwise prepare to begin writing out the ELF file. If LINK_INFO
+ is not NULL, this is being called by the ELF backend linker. */
+
+boolean
+_bfd_elf_compute_section_file_positions (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ boolean failed;
+ struct bfd_strtab_hash *strtab;
+ Elf_Internal_Shdr *shstrtab_hdr;
+
+ if (abfd->output_has_begun)
+ return true;
+
+ /* Do any elf backend specific processing first. */
+ if (bed->elf_backend_begin_write_processing)
+ (*bed->elf_backend_begin_write_processing) (abfd, link_info);
+
+ if (! prep_headers (abfd))
+ return false;
+
+ failed = false;
+ bfd_map_over_sections (abfd, elf_fake_sections, &failed);
+ if (failed)
+ return false;
+
+ if (!assign_section_numbers (abfd))
+ return false;
+
+ /* The backend linker builds symbol table information itself. */
+ if (link_info == NULL && bfd_get_symcount (abfd) > 0)
+ {
+ /* Non-zero if doing a relocatable link. */
+ int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
+
+ if (! swap_out_syms (abfd, &strtab, relocatable_p))
+ return false;
+ }
+
+ shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
+ /* sh_name was set in prep_headers. */
+ shstrtab_hdr->sh_type = SHT_STRTAB;
+ shstrtab_hdr->sh_flags = 0;
+ shstrtab_hdr->sh_addr = 0;
+ shstrtab_hdr->sh_size = _bfd_stringtab_size (elf_shstrtab (abfd));
+ shstrtab_hdr->sh_entsize = 0;
+ shstrtab_hdr->sh_link = 0;
+ shstrtab_hdr->sh_info = 0;
+ /* sh_offset is set in assign_file_positions_except_relocs. */
+ shstrtab_hdr->sh_addralign = 1;
+
+ if (!assign_file_positions_except_relocs (abfd))
+ return false;
+
+ if (link_info == NULL && bfd_get_symcount (abfd) > 0)
+ {
+ file_ptr off;
+ Elf_Internal_Shdr *hdr;
+
+ off = elf_tdata (abfd)->next_file_pos;
+
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+
+ hdr = &elf_tdata (abfd)->strtab_hdr;
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+
+ elf_tdata (abfd)->next_file_pos = off;
+
+ /* Now that we know where the .strtab section goes, write it
+ out. */
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
+ || ! _bfd_stringtab_emit (abfd, strtab))
+ return false;
+ _bfd_stringtab_free (strtab);
+ }
+
+ abfd->output_has_begun = true;
+
+ return true;
+}
+
+/* Create a mapping from a set of sections to a program segment. */
+
+static INLINE struct elf_segment_map *
+make_mapping (abfd, sections, from, to, phdr)
+ bfd *abfd;
+ asection **sections;
+ unsigned int from;
+ unsigned int to;
+ boolean phdr;
+{
+ struct elf_segment_map *m;
+ unsigned int i;
+ asection **hdrpp;
+
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd,
+ (sizeof (struct elf_segment_map)
+ + (to - from - 1) * sizeof (asection *))));
+ if (m == NULL)
+ return NULL;
+ m->next = NULL;
+ m->p_type = PT_LOAD;
+ for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
+ m->sections[i - from] = *hdrpp;
+ m->count = to - from;
+
+ if (from == 0 && phdr)
+ {
+ /* Include the headers in the first PT_LOAD segment. */
+ m->includes_filehdr = 1;
+ m->includes_phdrs = 1;
+ }
+
+ return m;
+}
+
+/* Set up a mapping from BFD sections to program segments. */
+
+static boolean
+map_sections_to_segments (abfd)
+ bfd *abfd;
+{
+ asection **sections = NULL;
+ asection *s;
+ unsigned int i;
+ unsigned int count;
+ struct elf_segment_map *mfirst;
+ struct elf_segment_map **pm;
+ struct elf_segment_map *m;
+ asection *last_hdr;
+ unsigned int phdr_index;
+ bfd_vma maxpagesize;
+ asection **hdrpp;
+ boolean phdr_in_segment = true;
+ boolean writable;
+ asection *dynsec;
+
+ if (elf_tdata (abfd)->segment_map != NULL)
+ return true;
+
+ if (bfd_count_sections (abfd) == 0)
+ return true;
+
+ /* Select the allocated sections, and sort them. */
+
+ sections = (asection **) bfd_malloc (bfd_count_sections (abfd)
+ * sizeof (asection *));
+ if (sections == NULL)
+ goto error_return;
+
+ i = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_ALLOC) != 0)
+ {
+ sections[i] = s;
+ ++i;
+ }
+ }
+ BFD_ASSERT (i <= bfd_count_sections (abfd));
+ count = i;
+
+ qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);
+
+ /* Build the mapping. */
+
+ mfirst = NULL;
+ pm = &mfirst;
+
+ /* If we have a .interp section, then create a PT_PHDR segment for
+ the program headers and a PT_INTERP segment for the .interp
+ section. */
+ s = bfd_get_section_by_name (abfd, ".interp");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0)
+ {
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_PHDR;
+ /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */
+ m->p_flags = PF_R | PF_X;
+ m->p_flags_valid = 1;
+ m->includes_phdrs = 1;
+
+ *pm = m;
+ pm = &m->next;
+
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_INTERP;
+ m->count = 1;
+ m->sections[0] = s;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
+ /* Look through the sections. We put sections in the same program
+ segment when the start of the second section can be placed within
+ a few bytes of the end of the first section. */
+ last_hdr = NULL;
+ phdr_index = 0;
+ maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
+ writable = false;
+ dynsec = bfd_get_section_by_name (abfd, ".dynamic");
+ if (dynsec != NULL
+ && (dynsec->flags & SEC_LOAD) == 0)
+ dynsec = NULL;
+
+ /* Deal with -Ttext or something similar such that the first section
+ is not adjacent to the program headers. This is an
+ approximation, since at this point we don't know exactly how many
+ program headers we will need. */
+ if (count > 0)
+ {
+ bfd_size_type phdr_size;
+
+ phdr_size = elf_tdata (abfd)->program_header_size;
+ if (phdr_size == 0)
+ phdr_size = get_elf_backend_data (abfd)->s->sizeof_phdr;
+ if ((abfd->flags & D_PAGED) == 0
+ || sections[0]->lma < phdr_size
+ || sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
+ phdr_in_segment = false;
+ }
+
+ for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
+ {
+ asection *hdr;
+ boolean new_segment;
+
+ hdr = *hdrpp;
+
+ /* See if this section and the last one will fit in the same
+ segment. */
+
+ if (last_hdr == NULL)
+ {
+ /* If we don't have a segment yet, then we don't need a new
+ one (we build the last one after this loop). */
+ new_segment = false;
+ }
+ else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
+ {
+ /* If this section has a different relation between the
+ virtual address and the load address, then we need a new
+ segment. */
+ new_segment = true;
+ }
+ else if (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize)
+ < BFD_ALIGN (hdr->lma, maxpagesize))
+ {
+ /* If putting this section in this segment would force us to
+ skip a page in the segment, then we need a new segment. */
+ new_segment = true;
+ }
+ else if ((last_hdr->flags & SEC_LOAD) == 0
+ && (hdr->flags & SEC_LOAD) != 0)
+ {
+ /* We don't want to put a loadable section after a
+ nonloadable section in the same segment. */
+ new_segment = true;
+ }
+ else if ((abfd->flags & D_PAGED) == 0)
+ {
+ /* If the file is not demand paged, which means that we
+ don't require the sections to be correctly aligned in the
+ file, then there is no other reason for a new segment. */
+ new_segment = false;
+ }
+ else if (! writable
+ && (hdr->flags & SEC_READONLY) == 0
+ && (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize)
+ == hdr->lma))
+ {
+ /* We don't want to put a writable section in a read only
+ segment, unless they are on the same page in memory
+ anyhow. We already know that the last section does not
+ bring us past the current section on the page, so the
+ only case in which the new section is not on the same
+ page as the previous section is when the previous section
+ ends precisely on a page boundary. */
+ new_segment = true;
+ }
+ else
+ {
+ /* Otherwise, we can use the same segment. */
+ new_segment = false;
+ }
+
+ if (! new_segment)
+ {
+ if ((hdr->flags & SEC_READONLY) == 0)
+ writable = true;
+ last_hdr = hdr;
+ continue;
+ }
+
+ /* We need a new program segment. We must create a new program
+ header holding all the sections from phdr_index until hdr. */
+
+ m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
+ if (m == NULL)
+ goto error_return;
+
+ *pm = m;
+ pm = &m->next;
+
+ if ((hdr->flags & SEC_READONLY) == 0)
+ writable = true;
+ else
+ writable = false;
+
+ last_hdr = hdr;
+ phdr_index = i;
+ phdr_in_segment = false;
+ }
+
+ /* Create a final PT_LOAD program segment. */
+ if (last_hdr != NULL)
+ {
+ m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
+ if (m == NULL)
+ goto error_return;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
+ /* If there is a .dynamic section, throw in a PT_DYNAMIC segment. */
+ if (dynsec != NULL)
+ {
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_DYNAMIC;
+ m->count = 1;
+ m->sections[0] = dynsec;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
+ /* For each loadable .note section, add a PT_NOTE segment. We don't
+ use bfd_get_section_by_name, because if we link together
+ nonloadable .note sections and loadable .note sections, we will
+ generate two .note sections in the output file. FIXME: Using
+ names for section types is bogus anyhow. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LOAD) != 0
+ && strncmp (s->name, ".note", 5) == 0)
+ {
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_NOTE;
+ m->count = 1;
+ m->sections[0] = s;
+
+ *pm = m;
+ pm = &m->next;
+ }
+ }
+
+ free (sections);
+ sections = NULL;
+
+ elf_tdata (abfd)->segment_map = mfirst;
+ return true;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ return false;
+}
+
+/* Sort sections by address. */
+
+static int
+elf_sort_sections (arg1, arg2)
+ const PTR arg1;
+ const PTR arg2;
+{
+ const asection *sec1 = *(const asection **) arg1;
+ const asection *sec2 = *(const asection **) arg2;
+
+ /* Sort by LMA first, since this is the address used to
+ place the section into a segment. */
+ if (sec1->lma < sec2->lma)
+ return -1;
+ else if (sec1->lma > sec2->lma)
+ return 1;
+
+ /* Then sort by VMA. Normally the LMA and the VMA will be
+ the same, and this will do nothing. */
+ if (sec1->vma < sec2->vma)
+ return -1;
+ else if (sec1->vma > sec2->vma)
+ return 1;
+
+ /* Put !SEC_LOAD sections after SEC_LOAD ones. */
+
+#define TOEND(x) (((x)->flags & SEC_LOAD) == 0)
+
+ if (TOEND (sec1))
+ {
+ if (TOEND (sec2))
+ return sec1->target_index - sec2->target_index;
+ else
+ return 1;
+ }
+
+ if (TOEND (sec2))
+ return -1;
+
+#undef TOEND
+
+ /* Sort by size, to put zero sized sections before others at the
+ same address. */
+
+ if (sec1->_raw_size < sec2->_raw_size)
+ return -1;
+ if (sec1->_raw_size > sec2->_raw_size)
+ return 1;
+
+ return sec1->target_index - sec2->target_index;
+}
+
+/* Assign file positions to the sections based on the mapping from
+ sections to segments. This function also sets up some fields in
+ the file header, and writes out the program headers. */
+
+static boolean
+assign_file_positions_for_segments (abfd)
+ bfd *abfd;
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ unsigned int count;
+ struct elf_segment_map *m;
+ unsigned int alloc;
+ Elf_Internal_Phdr *phdrs;
+ file_ptr off, voff;
+ bfd_vma filehdr_vaddr, filehdr_paddr;
+ bfd_vma phdrs_vaddr, phdrs_paddr;
+ Elf_Internal_Phdr *p;
+
+ if (elf_tdata (abfd)->segment_map == NULL)
+ {
+ if (! map_sections_to_segments (abfd))
+ return false;
+ }
+
+ if (bed->elf_backend_modify_segment_map)
+ {
+ if (! (*bed->elf_backend_modify_segment_map) (abfd))
+ return false;
+ }
+
+ count = 0;
+ for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+ ++count;
+
+ elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
+ elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
+ elf_elfheader (abfd)->e_phnum = count;
+
+ if (count == 0)
+ return true;
+
+ /* If we already counted the number of program segments, make sure
+ that we allocated enough space. This happens when SIZEOF_HEADERS
+ is used in a linker script. */
+ alloc = elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr;
+ if (alloc != 0 && count > alloc)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: Not enough room for program headers (allocated %u, need %u)"),
+ bfd_get_filename (abfd), alloc, count));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (alloc == 0)
+ alloc = count;
+
+ phdrs = ((Elf_Internal_Phdr *)
+ bfd_alloc (abfd, alloc * sizeof (Elf_Internal_Phdr)));
+ if (phdrs == NULL)
+ return false;
+
+ off = bed->s->sizeof_ehdr;
+ off += alloc * bed->s->sizeof_phdr;
+
+ filehdr_vaddr = 0;
+ filehdr_paddr = 0;
+ phdrs_vaddr = 0;
+ phdrs_paddr = 0;
+
+ for (m = elf_tdata (abfd)->segment_map, p = phdrs;
+ m != NULL;
+ m = m->next, p++)
+ {
+ unsigned int i;
+ asection **secpp;
+
+ /* If elf_segment_map is not from map_sections_to_segments, the
+ sections may not be correctly ordered. */
+ if (m->count > 0)
+ qsort (m->sections, (size_t) m->count, sizeof (asection *),
+ elf_sort_sections);
+
+ p->p_type = m->p_type;
+
+ if (m->p_flags_valid)
+ p->p_flags = m->p_flags;
+ else
+ p->p_flags = 0;
+
+ if (p->p_type == PT_LOAD
+ && m->count > 0
+ && (m->sections[0]->flags & SEC_ALLOC) != 0)
+ {
+ if ((abfd->flags & D_PAGED) != 0)
+ off += (m->sections[0]->vma - off) % bed->maxpagesize;
+ else
+ {
+ bfd_size_type align;
+
+ align = 0;
+ for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
+ {
+ bfd_size_type secalign;
+
+ secalign = bfd_get_section_alignment (abfd, *secpp);
+ if (secalign > align)
+ align = secalign;
+ }
+
+ off += (m->sections[0]->vma - off) % (1 << align);
+ }
+ }
+
+ if (m->count == 0)
+ p->p_vaddr = 0;
+ else
+ p->p_vaddr = m->sections[0]->vma;
+
+ if (m->p_paddr_valid)
+ p->p_paddr = m->p_paddr;
+ else if (m->count == 0)
+ p->p_paddr = 0;
+ else
+ p->p_paddr = m->sections[0]->lma;
+
+ if (p->p_type == PT_LOAD
+ && (abfd->flags & D_PAGED) != 0)
+ p->p_align = bed->maxpagesize;
+ else if (m->count == 0)
+ p->p_align = bed->s->file_align;
+ else
+ p->p_align = 0;
+
+ p->p_offset = 0;
+ p->p_filesz = 0;
+ p->p_memsz = 0;
+
+ if (m->includes_filehdr)
+ {
+ if (! m->p_flags_valid)
+ p->p_flags |= PF_R;
+ p->p_offset = 0;
+ p->p_filesz = bed->s->sizeof_ehdr;
+ p->p_memsz = bed->s->sizeof_ehdr;
+ if (m->count > 0)
+ {
+ BFD_ASSERT (p->p_type == PT_LOAD);
+
+ if (p->p_vaddr < (bfd_vma) off)
+ {
+ _bfd_error_handler (_("%s: Not enough room for program headers, try linking with -N"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ p->p_vaddr -= off;
+ if (! m->p_paddr_valid)
+ p->p_paddr -= off;
+ }
+ if (p->p_type == PT_LOAD)
+ {
+ filehdr_vaddr = p->p_vaddr;
+ filehdr_paddr = p->p_paddr;
+ }
+ }
+
+ if (m->includes_phdrs)
+ {
+ if (! m->p_flags_valid)
+ p->p_flags |= PF_R;
+
+ if (m->includes_filehdr)
+ {
+ if (p->p_type == PT_LOAD)
+ {
+ phdrs_vaddr = p->p_vaddr + bed->s->sizeof_ehdr;
+ phdrs_paddr = p->p_paddr + bed->s->sizeof_ehdr;
+ }
+ }
+ else
+ {
+ p->p_offset = bed->s->sizeof_ehdr;
+
+ if (m->count > 0)
+ {
+ BFD_ASSERT (p->p_type == PT_LOAD);
+ p->p_vaddr -= off - p->p_offset;
+ if (! m->p_paddr_valid)
+ p->p_paddr -= off - p->p_offset;
+ }
+
+ if (p->p_type == PT_LOAD)
+ {
+ phdrs_vaddr = p->p_vaddr;
+ phdrs_paddr = p->p_paddr;
+ }
+ else
+ phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
+ }
+
+ p->p_filesz += alloc * bed->s->sizeof_phdr;
+ p->p_memsz += alloc * bed->s->sizeof_phdr;
+ }
+
+ if (p->p_type == PT_LOAD
+ || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
+ {
+ if (! m->includes_filehdr && ! m->includes_phdrs)
+ p->p_offset = off;
+ else
+ {
+ file_ptr adjust;
+
+ adjust = off - (p->p_offset + p->p_filesz);
+ p->p_filesz += adjust;
+ p->p_memsz += adjust;
+ }
+ }
+
+ voff = off;
+
+ for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
+ {
+ asection *sec;
+ flagword flags;
+ bfd_size_type align;
+
+ sec = *secpp;
+ flags = sec->flags;
+ align = 1 << bfd_get_section_alignment (abfd, sec);
+
+ /* The section may have artificial alignment forced by a
+ link script. Notice this case by the gap between the
+ cumulative phdr vma and the section's vma. */
+ if (p->p_vaddr + p->p_memsz < sec->vma)
+ {
+ bfd_vma adjust = sec->vma - (p->p_vaddr + p->p_memsz);
+
+ p->p_memsz += adjust;
+ off += adjust;
+ voff += adjust;
+ if ((flags & SEC_LOAD) != 0)
+ p->p_filesz += adjust;
+ }
+
+ if (p->p_type == PT_LOAD)
+ {
+ bfd_signed_vma adjust;
+
+ if ((flags & SEC_LOAD) != 0)
+ {
+ adjust = sec->lma - (p->p_paddr + p->p_memsz);
+ if (adjust < 0)
+ adjust = 0;
+ }
+ else if ((flags & SEC_ALLOC) != 0)
+ {
+ /* The section VMA must equal the file position
+ modulo the page size. FIXME: I'm not sure if
+ this adjustment is really necessary. We used to
+ not have the SEC_LOAD case just above, and then
+ this was necessary, but now I'm not sure. */
+ if ((abfd->flags & D_PAGED) != 0)
+ adjust = (sec->vma - voff) % bed->maxpagesize;
+ else
+ adjust = (sec->vma - voff) % align;
+ }
+ else
+ adjust = 0;
+
+ if (adjust != 0)
+ {
+ if (i == 0)
+ {
+ (* _bfd_error_handler)
+ (_("Error: First section in segment (%s) starts at 0x%x"),
+ bfd_section_name (abfd, sec), sec->lma);
+ (* _bfd_error_handler)
+ (_(" whereas segment starts at 0x%x"),
+ p->p_paddr);
+
+ return false;
+ }
+ p->p_memsz += adjust;
+ off += adjust;
+ voff += adjust;
+ if ((flags & SEC_LOAD) != 0)
+ p->p_filesz += adjust;
+ }
+
+ sec->filepos = off;
+
+ /* We check SEC_HAS_CONTENTS here because if NOLOAD is
+ used in a linker script we may have a section with
+ SEC_LOAD clear but which is supposed to have
+ contents. */
+ if ((flags & SEC_LOAD) != 0
+ || (flags & SEC_HAS_CONTENTS) != 0)
+ off += sec->_raw_size;
+
+ if ((flags & SEC_ALLOC) != 0)
+ voff += sec->_raw_size;
+ }
+
+ if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
+ {
+ if (i == 0) /* the actual "note" segment */
+ { /* this one actually contains everything. */
+ sec->filepos = off;
+ p->p_filesz = sec->_raw_size;
+ off += sec->_raw_size;
+ voff = off;
+ }
+ else /* fake sections -- don't need to be written */
+ {
+ sec->filepos = 0;
+ sec->_raw_size = 0;
+ flags = sec->flags = 0; /* no contents */
+ }
+ p->p_memsz = 0;
+ p->p_align = 1;
+ }
+ else
+ {
+ p->p_memsz += sec->_raw_size;
+
+ if ((flags & SEC_LOAD) != 0)
+ p->p_filesz += sec->_raw_size;
+
+ if (align > p->p_align
+ && (p->p_type != PT_LOAD || (abfd->flags & D_PAGED) == 0))
+ p->p_align = align;
+ }
+
+ if (! m->p_flags_valid)
+ {
+ p->p_flags |= PF_R;
+ if ((flags & SEC_CODE) != 0)
+ p->p_flags |= PF_X;
+ if ((flags & SEC_READONLY) == 0)
+ p->p_flags |= PF_W;
+ }
+ }
+ }
+
+ /* Now that we have set the section file positions, we can set up
+ the file positions for the non PT_LOAD segments. */
+ for (m = elf_tdata (abfd)->segment_map, p = phdrs;
+ m != NULL;
+ m = m->next, p++)
+ {
+ if (p->p_type != PT_LOAD && m->count > 0)
+ {
+ BFD_ASSERT (! m->includes_filehdr && ! m->includes_phdrs);
+ p->p_offset = m->sections[0]->filepos;
+ }
+ if (m->count == 0)
+ {
+ if (m->includes_filehdr)
+ {
+ p->p_vaddr = filehdr_vaddr;
+ if (! m->p_paddr_valid)
+ p->p_paddr = filehdr_paddr;
+ }
+ else if (m->includes_phdrs)
+ {
+ p->p_vaddr = phdrs_vaddr;
+ if (! m->p_paddr_valid)
+ p->p_paddr = phdrs_paddr;
+ }
+ }
+ }
+
+ /* Clear out any program headers we allocated but did not use. */
+ for (; count < alloc; count++, p++)
+ {
+ memset (p, 0, sizeof *p);
+ p->p_type = PT_NULL;
+ }
+
+ elf_tdata (abfd)->phdr = phdrs;
+
+ elf_tdata (abfd)->next_file_pos = off;
+
+ /* Write out the program headers. */
+ if (bfd_seek (abfd, bed->s->sizeof_ehdr, SEEK_SET) != 0
+ || bed->s->write_out_phdrs (abfd, phdrs, alloc) != 0)
+ return false;
+
+ return true;
+}
+
+/* Get the size of the program header.
+
+ If this is called by the linker before any of the section VMA's are set, it
+ can't calculate the correct value for a strange memory layout. This only
+ happens when SIZEOF_HEADERS is used in a linker script. In this case,
+ SORTED_HDRS is NULL and we assume the normal scenario of one text and one
+ data segment (exclusive of .interp and .dynamic).
+
+ ??? User written scripts must either not use SIZEOF_HEADERS, or assume there
+ will be two segments. */
+
+static bfd_size_type
+get_program_header_size (abfd)
+ bfd *abfd;
+{
+ size_t segs;
+ asection *s;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ /* We can't return a different result each time we're called. */
+ if (elf_tdata (abfd)->program_header_size != 0)
+ return elf_tdata (abfd)->program_header_size;
+
+ if (elf_tdata (abfd)->segment_map != NULL)
+ {
+ struct elf_segment_map *m;
+
+ segs = 0;
+ for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+ ++segs;
+ elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
+ return elf_tdata (abfd)->program_header_size;
+ }
+
+ /* Assume we will need exactly two PT_LOAD segments: one for text
+ and one for data. */
+ segs = 2;
+
+ s = bfd_get_section_by_name (abfd, ".interp");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0)
+ {
+ /* If we have a loadable interpreter section, we need a
+ PT_INTERP segment. In this case, assume we also need a
+ PT_PHDR segment, although that may not be true for all
+ targets. */
+ segs += 2;
+ }
+
+ if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
+ {
+ /* We need a PT_DYNAMIC segment. */
+ ++segs;
+ }
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LOAD) != 0
+ && strncmp (s->name, ".note", 5) == 0)
+ {
+ /* We need a PT_NOTE segment. */
+ ++segs;
+ }
+ }
+
+ /* Let the backend count up any program headers it might need. */
+ if (bed->elf_backend_additional_program_headers)
+ {
+ int a;
+
+ a = (*bed->elf_backend_additional_program_headers) (abfd);
+ if (a == -1)
+ abort ();
+ segs += a;
+ }
+
+ elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
+ return elf_tdata (abfd)->program_header_size;
+}
+
+/* Work out the file positions of all the sections. This is called by
+ _bfd_elf_compute_section_file_positions. All the section sizes and
+ VMAs must be known before this is called.
+
+ We do not consider reloc sections at this point, unless they form
+ part of the loadable image. Reloc sections are assigned file
+ positions in assign_file_positions_for_relocs, which is called by
+ write_object_contents and final_link.
+
+ We also don't set the positions of the .symtab and .strtab here. */
+
+static boolean
+assign_file_positions_except_relocs (abfd)
+ bfd *abfd;
+{
+ struct elf_obj_tdata * const tdata = elf_tdata (abfd);
+ Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
+ Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
+ file_ptr off;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
+ && bfd_get_format (abfd) != bfd_core)
+ {
+ Elf_Internal_Shdr **hdrpp;
+ unsigned int i;
+
+ /* Start after the ELF header. */
+ off = i_ehdrp->e_ehsize;
+
+ /* We are not creating an executable, which means that we are
+ not creating a program header, and that the actual order of
+ the sections in the file is unimportant. */
+ for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = *hdrpp;
+ if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
+ {
+ hdr->sh_offset = -1;
+ continue;
+ }
+ if (i == tdata->symtab_section
+ || i == tdata->strtab_section)
+ {
+ hdr->sh_offset = -1;
+ continue;
+ }
+
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+ }
+ }
+ else
+ {
+ unsigned int i;
+ Elf_Internal_Shdr **hdrpp;
+
+ /* Assign file positions for the loaded sections based on the
+ assignment of sections to segments. */
+ if (! assign_file_positions_for_segments (abfd))
+ return false;
+
+ /* Assign file positions for the other sections. */
+
+ off = elf_tdata (abfd)->next_file_pos;
+ for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = *hdrpp;
+ if (hdr->bfd_section != NULL
+ && hdr->bfd_section->filepos != 0)
+ hdr->sh_offset = hdr->bfd_section->filepos;
+ else if ((hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: warning: allocated section `%s' not in segment"),
+ bfd_get_filename (abfd),
+ (hdr->bfd_section == NULL
+ ? "*unknown*"
+ : hdr->bfd_section->name)));
+ if ((abfd->flags & D_PAGED) != 0)
+ off += (hdr->sh_addr - off) % bed->maxpagesize;
+ else
+ off += (hdr->sh_addr - off) % hdr->sh_addralign;
+ off = _bfd_elf_assign_file_position_for_section (hdr, off,
+ false);
+ }
+ else if (hdr->sh_type == SHT_REL
+ || hdr->sh_type == SHT_RELA
+ || hdr == i_shdrpp[tdata->symtab_section]
+ || hdr == i_shdrpp[tdata->strtab_section])
+ hdr->sh_offset = -1;
+ else
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+ }
+ }
+
+ /* Place the section headers. */
+ off = align_file_position (off, bed->s->file_align);
+ i_ehdrp->e_shoff = off;
+ off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
+
+ elf_tdata (abfd)->next_file_pos = off;
+
+ return true;
+}
+
+static boolean
+prep_headers (abfd)
+ bfd *abfd;
+{
+ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
+ Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
+ Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
+ int count;
+ struct bfd_strtab_hash *shstrtab;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ i_ehdrp = elf_elfheader (abfd);
+ i_shdrp = elf_elfsections (abfd);
+
+ shstrtab = _bfd_elf_stringtab_init ();
+ if (shstrtab == NULL)
+ return false;
+
+ elf_shstrtab (abfd) = shstrtab;
+
+ i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
+ i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
+ i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
+ i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;
+
+ i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
+ i_ehdrp->e_ident[EI_DATA] =
+ bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
+ i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
+
+ for (count = EI_PAD; count < EI_NIDENT; count++)
+ i_ehdrp->e_ident[count] = 0;
+
+ if ((abfd->flags & DYNAMIC) != 0)
+ i_ehdrp->e_type = ET_DYN;
+ else if ((abfd->flags & EXEC_P) != 0)
+ i_ehdrp->e_type = ET_EXEC;
+ else if (bfd_get_format (abfd) == bfd_core)
+ i_ehdrp->e_type = ET_CORE;
+ else
+ i_ehdrp->e_type = ET_REL;
+
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_unknown:
+ i_ehdrp->e_machine = EM_NONE;
+ break;
+ case bfd_arch_sparc:
+ if (bed->s->arch_size == 64)
+ i_ehdrp->e_machine = EM_SPARCV9;
+ else
+ i_ehdrp->e_machine = EM_SPARC;
+ break;
+ case bfd_arch_i386:
+ i_ehdrp->e_machine = EM_386;
+ break;
+ case bfd_arch_m68k:
+ i_ehdrp->e_machine = EM_68K;
+ break;
+ case bfd_arch_m88k:
+ i_ehdrp->e_machine = EM_88K;
+ break;
+ case bfd_arch_i860:
+ i_ehdrp->e_machine = EM_860;
+ break;
+ case bfd_arch_mips: /* MIPS Rxxxx */
+ i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */
+ break;
+ case bfd_arch_hppa:
+ i_ehdrp->e_machine = EM_PARISC;
+ break;
+ case bfd_arch_powerpc:
+ i_ehdrp->e_machine = EM_PPC;
+ break;
+ case bfd_arch_alpha:
+ i_ehdrp->e_machine = EM_ALPHA;
+ break;
+ case bfd_arch_sh:
+ i_ehdrp->e_machine = EM_SH;
+ break;
+ case bfd_arch_d10v:
+ i_ehdrp->e_machine = EM_CYGNUS_D10V;
+ break;
+ case bfd_arch_d30v:
+ i_ehdrp->e_machine = EM_CYGNUS_D30V;
+ break;
+ case bfd_arch_fr30:
+ i_ehdrp->e_machine = EM_CYGNUS_FR30;
+ break;
+ case bfd_arch_mcore:
+ i_ehdrp->e_machine = EM_MCORE;
+ break;
+ case bfd_arch_v850:
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case 0: i_ehdrp->e_machine = EM_CYGNUS_V850; break;
+ }
+ break;
+ case bfd_arch_arc:
+ i_ehdrp->e_machine = EM_CYGNUS_ARC;
+ break;
+ case bfd_arch_arm:
+ i_ehdrp->e_machine = EM_ARM;
+ break;
+ case bfd_arch_m32r:
+ i_ehdrp->e_machine = EM_CYGNUS_M32R;
+ break;
+ case bfd_arch_mn10200:
+ i_ehdrp->e_machine = EM_CYGNUS_MN10200;
+ break;
+ case bfd_arch_mn10300:
+ i_ehdrp->e_machine = EM_CYGNUS_MN10300;
+ break;
+ /* also note that EM_M32, AT&T WE32100 is unknown to bfd */
+ default:
+ i_ehdrp->e_machine = EM_NONE;
+ }
+ i_ehdrp->e_version = bed->s->ev_current;
+ i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
+
+ /* no program header, for now. */
+ i_ehdrp->e_phoff = 0;
+ i_ehdrp->e_phentsize = 0;
+ i_ehdrp->e_phnum = 0;
+
+ /* each bfd section is section header entry */
+ i_ehdrp->e_entry = bfd_get_start_address (abfd);
+ i_ehdrp->e_shentsize = bed->s->sizeof_shdr;
+
+ /* if we're building an executable, we'll need a program header table */
+ if (abfd->flags & EXEC_P)
+ {
+ /* it all happens later */
+#if 0
+ i_ehdrp->e_phentsize = sizeof (Elf_External_Phdr);
+
+ /* elf_build_phdrs() returns a (NULL-terminated) array of
+ Elf_Internal_Phdrs */
+ i_phdrp = elf_build_phdrs (abfd, i_ehdrp, i_shdrp, &i_ehdrp->e_phnum);
+ i_ehdrp->e_phoff = outbase;
+ outbase += i_ehdrp->e_phentsize * i_ehdrp->e_phnum;
+#endif
+ }
+ else
+ {
+ i_ehdrp->e_phentsize = 0;
+ i_phdrp = 0;
+ i_ehdrp->e_phoff = 0;
+ }
+
+ elf_tdata (abfd)->symtab_hdr.sh_name =
+ (unsigned int) _bfd_stringtab_add (shstrtab, ".symtab", true, false);
+ elf_tdata (abfd)->strtab_hdr.sh_name =
+ (unsigned int) _bfd_stringtab_add (shstrtab, ".strtab", true, false);
+ elf_tdata (abfd)->shstrtab_hdr.sh_name =
+ (unsigned int) _bfd_stringtab_add (shstrtab, ".shstrtab", true, false);
+ if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
+ || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
+ || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
+ return false;
+
+ return true;
+}
+
+/* Assign file positions for all the reloc sections which are not part
+ of the loadable file image. */
+
+void
+_bfd_elf_assign_file_positions_for_relocs (abfd)
+ bfd *abfd;
+{
+ file_ptr off;
+ unsigned int i;
+ Elf_Internal_Shdr **shdrpp;
+
+ off = elf_tdata (abfd)->next_file_pos;
+
+ for (i = 1, shdrpp = elf_elfsections (abfd) + 1;
+ i < elf_elfheader (abfd)->e_shnum;
+ i++, shdrpp++)
+ {
+ Elf_Internal_Shdr *shdrp;
+
+ shdrp = *shdrpp;
+ if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
+ && shdrp->sh_offset == -1)
+ off = _bfd_elf_assign_file_position_for_section (shdrp, off, true);
+ }
+
+ elf_tdata (abfd)->next_file_pos = off;
+}
+
+boolean
+_bfd_elf_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ Elf_Internal_Ehdr *i_ehdrp;
+ Elf_Internal_Shdr **i_shdrp;
+ boolean failed;
+ unsigned int count;
+
+ if (! abfd->output_has_begun
+ && ! _bfd_elf_compute_section_file_positions
+ (abfd, (struct bfd_link_info *) NULL))
+ return false;
+
+ i_shdrp = elf_elfsections (abfd);
+ i_ehdrp = elf_elfheader (abfd);
+
+ failed = false;
+ bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
+ if (failed)
+ return false;
+
+ _bfd_elf_assign_file_positions_for_relocs (abfd);
+
+ /* After writing the headers, we need to write the sections too... */
+ for (count = 1; count < i_ehdrp->e_shnum; count++)
+ {
+ if (bed->elf_backend_section_processing)
+ (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
+ if (i_shdrp[count]->contents)
+ {
+ if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
+ || (bfd_write (i_shdrp[count]->contents, i_shdrp[count]->sh_size,
+ 1, abfd)
+ != i_shdrp[count]->sh_size))
+ return false;
+ }
+ }
+
+ /* Write out the section header names. */
+ if (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
+ || ! _bfd_stringtab_emit (abfd, elf_shstrtab (abfd)))
+ return false;
+
+ if (bed->elf_backend_final_write_processing)
+ (*bed->elf_backend_final_write_processing) (abfd,
+ elf_tdata (abfd)->linker);
+
+ return bed->s->write_shdrs_and_ehdr (abfd);
+}
+
+boolean
+_bfd_elf_write_corefile_contents (abfd)
+ bfd *abfd;
+{
+ /* Hopefully this can be done just like an object file. */
+ return _bfd_elf_write_object_contents (abfd);
+}
+/* given a section, search the header to find them... */
+int
+_bfd_elf_section_from_bfd_section (abfd, asect)
+ bfd *abfd;
+ struct sec *asect;
+{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
+ int index;
+ Elf_Internal_Shdr *hdr;
+ int maxindex = elf_elfheader (abfd)->e_shnum;
+
+ for (index = 0; index < maxindex; index++)
+ {
+ hdr = i_shdrp[index];
+ if (hdr->bfd_section == asect)
+ return index;
+ }
+
+ if (bed->elf_backend_section_from_bfd_section)
+ {
+ for (index = 0; index < maxindex; index++)
+ {
+ int retval;
+
+ hdr = i_shdrp[index];
+ retval = index;
+ if ((*bed->elf_backend_section_from_bfd_section)
+ (abfd, hdr, asect, &retval))
+ return retval;
+ }
+ }
+
+ if (bfd_is_abs_section (asect))
+ return SHN_ABS;
+ if (bfd_is_com_section (asect))
+ return SHN_COMMON;
+ if (bfd_is_und_section (asect))
+ return SHN_UNDEF;
+
+ bfd_set_error (bfd_error_nonrepresentable_section);
+
+ return -1;
+}
+
+/* Given a BFD symbol, return the index in the ELF symbol table, or -1
+ on error. */
+
+int
+_bfd_elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr)
+ bfd *abfd;
+ asymbol **asym_ptr_ptr;
+{
+ asymbol *asym_ptr = *asym_ptr_ptr;
+ int idx;
+ flagword flags = asym_ptr->flags;
+
+ /* When gas creates relocations against local labels, it creates its
+ own symbol for the section, but does put the symbol into the
+ symbol chain, so udata is 0. When the linker is generating
+ relocatable output, this section symbol may be for one of the
+ input sections rather than the output section. */
+ if (asym_ptr->udata.i == 0
+ && (flags & BSF_SECTION_SYM)
+ && asym_ptr->section)
+ {
+ int indx;
+
+ if (asym_ptr->section->output_section != NULL)
+ indx = asym_ptr->section->output_section->index;
+ else
+ indx = asym_ptr->section->index;
+ if (elf_section_syms (abfd)[indx])
+ asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
+ }
+
+ idx = asym_ptr->udata.i;
+
+ if (idx == 0)
+ {
+ /* This case can occur when using --strip-symbol on a symbol
+ which is used in a relocation entry. */
+ (*_bfd_error_handler)
+ (_("%s: symbol `%s' required but not present"),
+ bfd_get_filename (abfd), bfd_asymbol_name (asym_ptr));
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+#if DEBUG & 4
+ {
+ fprintf (stderr,
+ _("elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n"),
+ (long) asym_ptr, asym_ptr->name, idx, flags,
+ elf_symbol_flags (flags));
+ fflush (stderr);
+ }
+#endif
+
+ return idx;
+}
+
+/* Copy private BFD data. This copies any program header information. */
+
+static boolean
+copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ Elf_Internal_Ehdr *iehdr;
+ struct elf_segment_map *mfirst;
+ struct elf_segment_map **pm;
+ struct elf_segment_map *m;
+ Elf_Internal_Phdr *p;
+ unsigned int i;
+ unsigned int num_segments;
+ boolean phdr_included = false;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ if (elf_tdata (ibfd)->phdr == NULL)
+ return true;
+
+ iehdr = elf_elfheader (ibfd);
+
+ mfirst = NULL;
+ pm = &mfirst;
+
+ num_segments = elf_elfheader (ibfd)->e_phnum;
+
+#define IS_CONTAINED_BY(addr, len, bottom, phdr) \
+ ((addr) >= (bottom) \
+ && ( ((addr) + (len)) <= ((bottom) + (phdr)->p_memsz) \
+ || ((addr) + (len)) <= ((bottom) + (phdr)->p_filesz)))
+
+ /* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */
+
+#define IS_COREFILE_NOTE(p, s) \
+ (p->p_type == PT_NOTE \
+ && bfd_get_format (ibfd) == bfd_core \
+ && s->vma == 0 && s->lma == 0 \
+ && (bfd_vma) s->filepos >= p->p_offset \
+ && (bfd_vma) s->filepos + s->_raw_size \
+ <= p->p_offset + p->p_filesz)
+
+ /* The complicated case when p_vaddr is 0 is to handle the Solaris
+ linker, which generates a PT_INTERP section with p_vaddr and
+ p_memsz set to 0. */
+
+#define IS_SOLARIS_PT_INTERP(p, s) \
+ (p->p_vaddr == 0 \
+ && p->p_filesz > 0 \
+ && (s->flags & SEC_HAS_CONTENTS) != 0 \
+ && s->_raw_size > 0 \
+ && (bfd_vma) s->filepos >= p->p_offset \
+ && ((bfd_vma) s->filepos + s->_raw_size \
+ <= p->p_offset + p->p_filesz))
+
+ /* Scan through the segments specified in the program header
+ of the input BFD. */
+ for (i = 0, p = elf_tdata (ibfd)->phdr; i < num_segments; i++, p++)
+ {
+ unsigned int csecs;
+ asection *s;
+ asection **sections;
+ asection *os;
+ unsigned int isec;
+ bfd_vma matching_lma;
+ bfd_vma suggested_lma;
+ unsigned int j;
+
+ /* For each section in the input BFD, decide if it should be
+ included in the current segment. A section will be included
+ if it is within the address space of the segment, and it is
+ an allocated segment, and there is an output section
+ associated with it. */
+ csecs = 0;
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ if (s->output_section != NULL)
+ {
+ if ((IS_CONTAINED_BY (s->vma, s->_raw_size, p->p_vaddr, p)
+ || IS_SOLARIS_PT_INTERP (p, s))
+ && (s->flags & SEC_ALLOC) != 0)
+ ++csecs;
+ else if (IS_COREFILE_NOTE (p, s))
+ ++csecs;
+ }
+
+ /* Allocate a segment map big enough to contain all of the
+ sections we have selected. */
+ m = ((struct elf_segment_map *)
+ bfd_alloc (obfd,
+ (sizeof (struct elf_segment_map)
+ + ((size_t) csecs - 1) * sizeof (asection *))));
+ if (m == NULL)
+ return false;
+
+ /* Initialise the fields of the segment map. Default to
+ using the physical address of the segment in the input BFD. */
+ m->next = NULL;
+ m->p_type = p->p_type;
+ m->p_flags = p->p_flags;
+ m->p_flags_valid = 1;
+ m->p_paddr = p->p_paddr;
+ m->p_paddr_valid = 1;
+
+ /* Determine if this segment contains the ELF file header
+ and if it contains the program headers themselves. */
+ m->includes_filehdr = (p->p_offset == 0
+ && p->p_filesz >= iehdr->e_ehsize);
+
+ m->includes_phdrs = 0;
+
+ if (! phdr_included || p->p_type != PT_LOAD)
+ {
+ m->includes_phdrs =
+ (p->p_offset <= (bfd_vma) iehdr->e_phoff
+ && (p->p_offset + p->p_filesz
+ >= ((bfd_vma) iehdr->e_phoff
+ + iehdr->e_phnum * iehdr->e_phentsize)));
+ if (p->p_type == PT_LOAD && m->includes_phdrs)
+ phdr_included = true;
+ }
+
+ if (csecs == 0)
+ {
+ /* Special segments, such as the PT_PHDR segment, may contain
+ no sections, but ordinary, loadable segments should contain
+ something. */
+
+ if (p->p_type == PT_LOAD)
+ _bfd_error_handler
+ (_("%s: warning: Empty loadable segment detected\n"),
+ bfd_get_filename (ibfd));
+
+ m->count = 0;
+ *pm = m;
+ pm = &m->next;
+
+ continue;
+ }
+
+ /* Now scan the sections in the input BFD again and attempt
+ to add their corresponding output sections to the segment map.
+ The problem here is how to handle an output section which has
+ been moved (ie had its LMA changed). There are four possibilities:
+
+ 1. None of the sections have been moved.
+ In this case we can continue to use the segment LMA from the
+ input BFD.
+
+ 2. All of the sections have been moved by the same amount.
+ In this case we can change the segment's LMA to match the LMA
+ of the first section.
+
+ 3. Some of the sections have been moved, others have not.
+ In this case those sections which have not been moved can be
+ placed in the current segment which will have to have its size,
+ and possibly its LMA changed, and a new segment or segments will
+ have to be created to contain the other sections.
+
+ 4. The sections have been moved, but not be the same amount.
+ In this case we can change the segment's LMA to match the LMA
+ of the first section and we will have to create a new segment
+ or segments to contain the other sections.
+
+ In order to save time, we allocate an array to hold the section
+ pointers that we are interested in. As these sections get assigned
+ to a segment, they are removed from this array. */
+
+ sections = (asection **) bfd_malloc (sizeof (asection *) * csecs);
+ if (sections == NULL)
+ return false;
+
+ /* Step One: Scan for segment vs section LMA conflicts.
+ Also add the sections to the section array allocated above.
+ Also add the sections to the current segment. In the common
+ case, where the sections have not been moved, this means that
+ we have completely filled the segment, and there is nothing
+ more to do. */
+
+ isec = 0;
+ matching_lma = false;
+ suggested_lma = 0;
+
+ for (j = 0, s = ibfd->sections; s != NULL; s = s->next)
+ {
+ os = s->output_section;
+
+ if ((((IS_CONTAINED_BY (s->vma, s->_raw_size, p->p_vaddr, p)
+ || IS_SOLARIS_PT_INTERP (p, s))
+ && (s->flags & SEC_ALLOC) != 0)
+ || IS_COREFILE_NOTE (p, s))
+ && os != NULL)
+ {
+ sections[j++] = s;
+
+ /* The Solaris native linker always sets p_paddr to 0.
+ We try to catch that case here, and set it to the
+ correct value. */
+ if (p->p_paddr == 0
+ && p->p_vaddr != 0
+ && isec == 0
+ && os->lma != 0
+ && (os->vma == (p->p_vaddr
+ + (m->includes_filehdr
+ ? iehdr->e_ehsize
+ : 0)
+ + (m->includes_phdrs
+ ? iehdr->e_phnum * iehdr->e_phentsize
+ : 0))))
+ m->p_paddr = p->p_vaddr;
+
+ /* Match up the physical address of the segment with the
+ LMA address of the output section. */
+ if (IS_CONTAINED_BY (os->lma, os->_raw_size, m->p_paddr, p)
+ || IS_COREFILE_NOTE (p, s))
+ {
+ if (matching_lma == 0)
+ matching_lma = os->lma;
+
+ /* We assume that if the section fits within the segment
+ that it does not overlap any other section within that
+ segment. */
+ m->sections[isec++] = os;
+ }
+ else if (suggested_lma == 0)
+ suggested_lma = os->lma;
+ }
+ }
+
+ BFD_ASSERT (j == csecs);
+
+ /* Step Two: Adjust the physical address of the current segment,
+ if necessary. */
+ if (isec == csecs)
+ {
+ /* All of the sections fitted within the segment as currently
+ specified. This is the default case. Add the segment to
+ the list of built segments and carry on to process the next
+ program header in the input BFD. */
+ m->count = csecs;
+ *pm = m;
+ pm = &m->next;
+
+ free (sections);
+ continue;
+ }
+ else if (matching_lma != 0)
+ {
+ /* At least one section fits inside the current segment.
+ Keep it, but modify its physical address to match the
+ LMA of the first section that fitted. */
+
+ m->p_paddr = matching_lma;
+ }
+ else
+ {
+ /* None of the sections fitted inside the current segment.
+ Change the current segment's physical address to match
+ the LMA of the first section. */
+
+ m->p_paddr = suggested_lma;
+ }
+
+ /* Step Three: Loop over the sections again, this time assigning
+ those that fit to the current segment and remvoing them from the
+ sections array; but making sure not to leave large gaps. Once all
+ possible sections have been assigned to the current segment it is
+ added to the list of built segments and if sections still remain
+ to be assigned, a new segment is constructed before repeating
+ the loop. */
+ isec = 0;
+ do
+ {
+ m->count = 0;
+ suggested_lma = 0;
+
+ /* Fill the current segment with sections that fit. */
+ for (j = 0; j < csecs; j++)
+ {
+ s = sections[j];
+
+ if (s == NULL)
+ continue;
+
+ os = s->output_section;
+
+ if (IS_CONTAINED_BY (os->lma, os->_raw_size, m->p_paddr, p)
+ || IS_COREFILE_NOTE (p, s))
+ {
+ if (m->count == 0)
+ {
+ /* If the first section in a segment does not start at
+ the beginning of the segment, then something is wrong. */
+ if (os->lma != m->p_paddr)
+ abort ();
+ }
+ else
+ {
+ asection * prev_sec;
+ bfd_vma maxpagesize;
+
+ prev_sec = m->sections[m->count - 1];
+ maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
+
+ /* If the gap between the end of the previous section
+ and the start of this section is more than maxpagesize
+ then we need to start a new segment. */
+ if (BFD_ALIGN (prev_sec->lma + prev_sec->_raw_size, maxpagesize)
+ < BFD_ALIGN (os->lma, maxpagesize))
+ {
+ if (suggested_lma == 0)
+ suggested_lma = os->lma;
+
+ continue;
+ }
+ }
+
+ m->sections[m->count++] = os;
+ ++isec;
+ sections[j] = NULL;
+ }
+ else if (suggested_lma == 0)
+ suggested_lma = os->lma;
+ }
+
+ BFD_ASSERT (m->count > 0);
+
+ /* Add the current segment to the list of built segments. */
+ *pm = m;
+ pm = &m->next;
+
+ if (isec < csecs)
+ {
+ /* We still have not allocated all of the sections to
+ segments. Create a new segment here, initialise it
+ and carry on looping. */
+
+ m = ((struct elf_segment_map *)
+ bfd_alloc (obfd,
+ (sizeof (struct elf_segment_map)
+ + ((size_t) csecs - 1) * sizeof (asection *))));
+ if (m == NULL)
+ return false;
+
+ /* Initialise the fields of the segment map. Set the physical
+ physical address to the LMA of the first section that has
+ not yet been assigned. */
+
+ m->next = NULL;
+ m->p_type = p->p_type;
+ m->p_flags = p->p_flags;
+ m->p_flags_valid = 1;
+ m->p_paddr = suggested_lma;
+ m->p_paddr_valid = 1;
+ m->includes_filehdr = 0;
+ m->includes_phdrs = 0;
+ }
+ }
+ while (isec < csecs);
+
+ free (sections);
+ }
+
+ /* The Solaris linker creates program headers in which all the
+ p_paddr fields are zero. When we try to objcopy or strip such a
+ file, we get confused. Check for this case, and if we find it
+ reset the p_paddr_valid fields. */
+ for (m = mfirst; m != NULL; m = m->next)
+ if (m->p_paddr != 0)
+ break;
+ if (m == NULL)
+ {
+ for (m = mfirst; m != NULL; m = m->next)
+ m->p_paddr_valid = 0;
+ }
+
+ elf_tdata (obfd)->segment_map = mfirst;
+
+#if 0
+ /* Final Step: Sort the segments into ascending order of physical address. */
+ if (mfirst != NULL)
+ {
+ struct elf_segment_map* prev;
+
+ prev = mfirst;
+ for (m = mfirst->next; m != NULL; prev = m, m = m->next)
+ {
+ /* Yes I know - its a bubble sort....*/
+ if (m->next != NULL && (m->next->p_paddr < m->p_paddr))
+ {
+ /* swap m and m->next */
+ prev->next = m->next;
+ m->next = m->next->next;
+ prev->next->next = m;
+
+ /* restart loop. */
+ m = mfirst;
+ }
+ }
+ }
+#endif
+
+#undef IS_CONTAINED_BY
+#undef IS_SOLARIS_PT_INTERP
+#undef IS_COREFILE_NOTE
+ return true;
+}
+
+/* Copy private section information. This copies over the entsize
+ field, and sometimes the info field. */
+
+boolean
+_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec)
+ bfd *ibfd;
+ asection *isec;
+ bfd *obfd;
+ asection *osec;
+{
+ Elf_Internal_Shdr *ihdr, *ohdr;
+
+ if (ibfd->xvec->flavour != bfd_target_elf_flavour
+ || obfd->xvec->flavour != bfd_target_elf_flavour)
+ return true;
+
+ /* Copy over private BFD data if it has not already been copied.
+ This must be done here, rather than in the copy_private_bfd_data
+ entry point, because the latter is called after the section
+ contents have been set, which means that the program headers have
+ already been worked out. */
+ if (elf_tdata (obfd)->segment_map == NULL
+ && elf_tdata (ibfd)->phdr != NULL)
+ {
+ asection *s;
+
+ /* Only set up the segments if there are no more SEC_ALLOC
+ sections. FIXME: This won't do the right thing if objcopy is
+ used to remove the last SEC_ALLOC section, since objcopy
+ won't call this routine in that case. */
+ for (s = isec->next; s != NULL; s = s->next)
+ if ((s->flags & SEC_ALLOC) != 0)
+ break;
+ if (s == NULL)
+ {
+ if (! copy_private_bfd_data (ibfd, obfd))
+ return false;
+ }
+ }
+
+ ihdr = &elf_section_data (isec)->this_hdr;
+ ohdr = &elf_section_data (osec)->this_hdr;
+
+ ohdr->sh_entsize = ihdr->sh_entsize;
+
+ if (ihdr->sh_type == SHT_SYMTAB
+ || ihdr->sh_type == SHT_DYNSYM
+ || ihdr->sh_type == SHT_GNU_verneed
+ || ihdr->sh_type == SHT_GNU_verdef)
+ ohdr->sh_info = ihdr->sh_info;
+
+ return true;
+}
+
+/* Copy private symbol information. If this symbol is in a section
+ which we did not map into a BFD section, try to map the section
+ index correctly. We use special macro definitions for the mapped
+ section indices; these definitions are interpreted by the
+ swap_out_syms function. */
+
+#define MAP_ONESYMTAB (SHN_LORESERVE - 1)
+#define MAP_DYNSYMTAB (SHN_LORESERVE - 2)
+#define MAP_STRTAB (SHN_LORESERVE - 3)
+#define MAP_SHSTRTAB (SHN_LORESERVE - 4)
+
+boolean
+_bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg)
+ bfd *ibfd;
+ asymbol *isymarg;
+ bfd *obfd;
+ asymbol *osymarg;
+{
+ elf_symbol_type *isym, *osym;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ isym = elf_symbol_from (ibfd, isymarg);
+ osym = elf_symbol_from (obfd, osymarg);
+
+ if (isym != NULL
+ && osym != NULL
+ && bfd_is_abs_section (isym->symbol.section))
+ {
+ unsigned int shndx;
+
+ shndx = isym->internal_elf_sym.st_shndx;
+ if (shndx == elf_onesymtab (ibfd))
+ shndx = MAP_ONESYMTAB;
+ else if (shndx == elf_dynsymtab (ibfd))
+ shndx = MAP_DYNSYMTAB;
+ else if (shndx == elf_tdata (ibfd)->strtab_section)
+ shndx = MAP_STRTAB;
+ else if (shndx == elf_tdata (ibfd)->shstrtab_section)
+ shndx = MAP_SHSTRTAB;
+ osym->internal_elf_sym.st_shndx = shndx;
+ }
+
+ return true;
+}
+
+/* Swap out the symbols. */
+
+static boolean
+swap_out_syms (abfd, sttp, relocatable_p)
+ bfd *abfd;
+ struct bfd_strtab_hash **sttp;
+ int relocatable_p;
+{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (!elf_map_symbols (abfd))
+ return false;
+
+ /* Dump out the symtabs. */
+ {
+ int symcount = bfd_get_symcount (abfd);
+ asymbol **syms = bfd_get_outsymbols (abfd);
+ struct bfd_strtab_hash *stt;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *symstrtab_hdr;
+ char *outbound_syms;
+ int idx;
+
+ stt = _bfd_elf_stringtab_init ();
+ if (stt == NULL)
+ return false;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ symtab_hdr->sh_type = SHT_SYMTAB;
+ symtab_hdr->sh_entsize = bed->s->sizeof_sym;
+ symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
+ symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
+ symtab_hdr->sh_addralign = bed->s->file_align;
+
+ symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
+ symstrtab_hdr->sh_type = SHT_STRTAB;
+
+ outbound_syms = bfd_alloc (abfd,
+ (1 + symcount) * bed->s->sizeof_sym);
+ if (outbound_syms == NULL)
+ return false;
+ symtab_hdr->contents = (PTR) outbound_syms;
+
+ /* now generate the data (for "contents") */
+ {
+ /* Fill in zeroth symbol and swap it out. */
+ Elf_Internal_Sym sym;
+ sym.st_name = 0;
+ sym.st_value = 0;
+ sym.st_size = 0;
+ sym.st_info = 0;
+ sym.st_other = 0;
+ sym.st_shndx = SHN_UNDEF;
+ bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ outbound_syms += bed->s->sizeof_sym;
+ }
+ for (idx = 0; idx < symcount; idx++)
+ {
+ Elf_Internal_Sym sym;
+ bfd_vma value = syms[idx]->value;
+ elf_symbol_type *type_ptr;
+ flagword flags = syms[idx]->flags;
+ int type;
+
+ if (flags & BSF_SECTION_SYM)
+ /* Section symbols have no names. */
+ sym.st_name = 0;
+ else
+ {
+ sym.st_name = (unsigned long) _bfd_stringtab_add (stt,
+ syms[idx]->name,
+ true, false);
+ if (sym.st_name == (unsigned long) -1)
+ return false;
+ }
+
+ type_ptr = elf_symbol_from (abfd, syms[idx]);
+
+ if ((flags & BSF_SECTION_SYM) == 0
+ && bfd_is_com_section (syms[idx]->section))
+ {
+ /* ELF common symbols put the alignment into the `value' field,
+ and the size into the `size' field. This is backwards from
+ how BFD handles it, so reverse it here. */
+ sym.st_size = value;
+ if (type_ptr == NULL
+ || type_ptr->internal_elf_sym.st_value == 0)
+ sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
+ else
+ sym.st_value = type_ptr->internal_elf_sym.st_value;
+ sym.st_shndx = _bfd_elf_section_from_bfd_section
+ (abfd, syms[idx]->section);
+ }
+ else
+ {
+ asection *sec = syms[idx]->section;
+ int shndx;
+
+ if (sec->output_section)
+ {
+ value += sec->output_offset;
+ sec = sec->output_section;
+ }
+ /* Don't add in the section vma for relocatable output. */
+ if (! relocatable_p)
+ value += sec->vma;
+ sym.st_value = value;
+ sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;
+
+ if (bfd_is_abs_section (sec)
+ && type_ptr != NULL
+ && type_ptr->internal_elf_sym.st_shndx != 0)
+ {
+ /* This symbol is in a real ELF section which we did
+ not create as a BFD section. Undo the mapping done
+ by copy_private_symbol_data. */
+ shndx = type_ptr->internal_elf_sym.st_shndx;
+ switch (shndx)
+ {
+ case MAP_ONESYMTAB:
+ shndx = elf_onesymtab (abfd);
+ break;
+ case MAP_DYNSYMTAB:
+ shndx = elf_dynsymtab (abfd);
+ break;
+ case MAP_STRTAB:
+ shndx = elf_tdata (abfd)->strtab_section;
+ break;
+ case MAP_SHSTRTAB:
+ shndx = elf_tdata (abfd)->shstrtab_section;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ if (shndx == -1)
+ {
+ asection *sec2;
+
+ /* Writing this would be a hell of a lot easier if
+ we had some decent documentation on bfd, and
+ knew what to expect of the library, and what to
+ demand of applications. For example, it
+ appears that `objcopy' might not set the
+ section of a symbol to be a section that is
+ actually in the output file. */
+ sec2 = bfd_get_section_by_name (abfd, sec->name);
+ BFD_ASSERT (sec2 != 0);
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
+ BFD_ASSERT (shndx != -1);
+ }
+ }
+
+ sym.st_shndx = shndx;
+ }
+
+ if ((flags & BSF_FUNCTION) != 0)
+ type = STT_FUNC;
+ else if ((flags & BSF_OBJECT) != 0)
+ type = STT_OBJECT;
+ else
+ type = STT_NOTYPE;
+
+ /* Processor-specific types */
+ if (bed->elf_backend_get_symbol_type)
+ type = (*bed->elf_backend_get_symbol_type) (&type_ptr->internal_elf_sym, type);
+
+ if (flags & BSF_SECTION_SYM)
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ else if (bfd_is_com_section (syms[idx]->section))
+ sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
+ else if (bfd_is_und_section (syms[idx]->section))
+ sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
+ ? STB_WEAK
+ : STB_GLOBAL),
+ type);
+ else if (flags & BSF_FILE)
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
+ else
+ {
+ int bind = STB_LOCAL;
+
+ if (flags & BSF_LOCAL)
+ bind = STB_LOCAL;
+ else if (flags & BSF_WEAK)
+ bind = STB_WEAK;
+ else if (flags & BSF_GLOBAL)
+ bind = STB_GLOBAL;
+
+ sym.st_info = ELF_ST_INFO (bind, type);
+ }
+
+ if (type_ptr != NULL)
+ sym.st_other = type_ptr->internal_elf_sym.st_other;
+ else
+ sym.st_other = 0;
+
+ bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ outbound_syms += bed->s->sizeof_sym;
+ }
+
+ *sttp = stt;
+ symstrtab_hdr->sh_size = _bfd_stringtab_size (stt);
+ symstrtab_hdr->sh_type = SHT_STRTAB;
+
+ symstrtab_hdr->sh_flags = 0;
+ symstrtab_hdr->sh_addr = 0;
+ symstrtab_hdr->sh_entsize = 0;
+ symstrtab_hdr->sh_link = 0;
+ symstrtab_hdr->sh_info = 0;
+ symstrtab_hdr->sh_addralign = 1;
+ }
+
+ return true;
+}
+
+/* Return the number of bytes required to hold the symtab vector.
+
+ Note that we base it on the count plus 1, since we will null terminate
+ the vector allocated based on this size. However, the ELF symbol table
+ always has a dummy entry as symbol #0, so it ends up even. */
+
+long
+_bfd_elf_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ long symcount;
+ long symtab_size;
+ Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
+ symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *));
+
+ return symtab_size;
+}
+
+long
+_bfd_elf_get_dynamic_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ long symcount;
+ long symtab_size;
+ Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ if (elf_dynsymtab (abfd) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
+ symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *));
+
+ return symtab_size;
+}
+
+long
+_bfd_elf_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+/* Canonicalize the relocs. */
+
+long
+_bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr;
+ unsigned int i;
+
+ if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd,
+ section,
+ symbols,
+ false))
+ return -1;
+
+ tblptr = section->relocation;
+ for (i = 0; i < section->reloc_count; i++)
+ *relptr++ = tblptr++;
+
+ *relptr = NULL;
+
+ return section->reloc_count;
+}
+
+long
+_bfd_elf_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ long symcount = get_elf_backend_data (abfd)->s->slurp_symbol_table
+ (abfd, alocation, false);
+
+ if (symcount >= 0)
+ bfd_get_symcount (abfd) = symcount;
+ return symcount;
+}
+
+long
+_bfd_elf_canonicalize_dynamic_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ return get_elf_backend_data (abfd)->s->slurp_symbol_table
+ (abfd, alocation, true);
+}
+
+/* Return the size required for the dynamic reloc entries. Any
+ section that was actually installed in the BFD, and has type
+ SHT_REL or SHT_RELA, and uses the dynamic symbol table, is
+ considered to be a dynamic reloc section. */
+
+long
+_bfd_elf_get_dynamic_reloc_upper_bound (abfd)
+ bfd *abfd;
+{
+ long ret;
+ asection *s;
+
+ if (elf_dynsymtab (abfd) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ ret = sizeof (arelent *);
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
+ && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
+ || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
+ ret += ((s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize)
+ * sizeof (arelent *));
+
+ return ret;
+}
+
+/* Canonicalize the dynamic relocation entries. Note that we return
+ the dynamic relocations as a single block, although they are
+ actually associated with particular sections; the interface, which
+ was designed for SunOS style shared libraries, expects that there
+ is only one set of dynamic relocs. Any section that was actually
+ installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
+ the dynamic symbol table, is considered to be a dynamic reloc
+ section. */
+
+long
+_bfd_elf_canonicalize_dynamic_reloc (abfd, storage, syms)
+ bfd *abfd;
+ arelent **storage;
+ asymbol **syms;
+{
+ boolean (*slurp_relocs) PARAMS ((bfd *, asection *, asymbol **, boolean));
+ asection *s;
+ long ret;
+
+ if (elf_dynsymtab (abfd) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ ret = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
+ && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
+ || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
+ {
+ arelent *p;
+ long count, i;
+
+ if (! (*slurp_relocs) (abfd, s, syms, true))
+ return -1;
+ count = s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize;
+ p = s->relocation;
+ for (i = 0; i < count; i++)
+ *storage++ = p++;
+ ret += count;
+ }
+ }
+
+ *storage = NULL;
+
+ return ret;
+}
+
+/* Read in the version information. */
+
+boolean
+_bfd_elf_slurp_version_tables (abfd)
+ bfd *abfd;
+{
+ bfd_byte *contents = NULL;
+
+ if (elf_dynverdef (abfd) != 0)
+ {
+ Elf_Internal_Shdr *hdr;
+ Elf_External_Verdef *everdef;
+ Elf_Internal_Verdef *iverdef;
+ unsigned int i;
+
+ hdr = &elf_tdata (abfd)->dynverdef_hdr;
+
+ elf_tdata (abfd)->verdef =
+ ((Elf_Internal_Verdef *)
+ bfd_zalloc (abfd, hdr->sh_info * sizeof (Elf_Internal_Verdef)));
+ if (elf_tdata (abfd)->verdef == NULL)
+ goto error_return;
+
+ elf_tdata (abfd)->cverdefs = hdr->sh_info;
+
+ contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
+ if (contents == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
+ || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
+ goto error_return;
+
+ everdef = (Elf_External_Verdef *) contents;
+ iverdef = elf_tdata (abfd)->verdef;
+ for (i = 0; i < hdr->sh_info; i++, iverdef++)
+ {
+ Elf_External_Verdaux *everdaux;
+ Elf_Internal_Verdaux *iverdaux;
+ unsigned int j;
+
+ _bfd_elf_swap_verdef_in (abfd, everdef, iverdef);
+
+ iverdef->vd_bfd = abfd;
+
+ iverdef->vd_auxptr = ((Elf_Internal_Verdaux *)
+ bfd_alloc (abfd,
+ (iverdef->vd_cnt
+ * sizeof (Elf_Internal_Verdaux))));
+ if (iverdef->vd_auxptr == NULL)
+ goto error_return;
+
+ everdaux = ((Elf_External_Verdaux *)
+ ((bfd_byte *) everdef + iverdef->vd_aux));
+ iverdaux = iverdef->vd_auxptr;
+ for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
+ {
+ _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);
+
+ iverdaux->vda_nodename =
+ bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ iverdaux->vda_name);
+ if (iverdaux->vda_nodename == NULL)
+ goto error_return;
+
+ if (j + 1 < iverdef->vd_cnt)
+ iverdaux->vda_nextptr = iverdaux + 1;
+ else
+ iverdaux->vda_nextptr = NULL;
+
+ everdaux = ((Elf_External_Verdaux *)
+ ((bfd_byte *) everdaux + iverdaux->vda_next));
+ }
+
+ iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
+
+ if (i + 1 < hdr->sh_info)
+ iverdef->vd_nextdef = iverdef + 1;
+ else
+ iverdef->vd_nextdef = NULL;
+
+ everdef = ((Elf_External_Verdef *)
+ ((bfd_byte *) everdef + iverdef->vd_next));
+ }
+
+ free (contents);
+ contents = NULL;
+ }
+
+ if (elf_dynverref (abfd) != 0)
+ {
+ Elf_Internal_Shdr *hdr;
+ Elf_External_Verneed *everneed;
+ Elf_Internal_Verneed *iverneed;
+ unsigned int i;
+
+ hdr = &elf_tdata (abfd)->dynverref_hdr;
+
+ elf_tdata (abfd)->verref =
+ ((Elf_Internal_Verneed *)
+ bfd_zalloc (abfd, hdr->sh_info * sizeof (Elf_Internal_Verneed)));
+ if (elf_tdata (abfd)->verref == NULL)
+ goto error_return;
+
+ elf_tdata (abfd)->cverrefs = hdr->sh_info;
+
+ contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
+ if (contents == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
+ || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
+ goto error_return;
+
+ everneed = (Elf_External_Verneed *) contents;
+ iverneed = elf_tdata (abfd)->verref;
+ for (i = 0; i < hdr->sh_info; i++, iverneed++)
+ {
+ Elf_External_Vernaux *evernaux;
+ Elf_Internal_Vernaux *ivernaux;
+ unsigned int j;
+
+ _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
+
+ iverneed->vn_bfd = abfd;
+
+ iverneed->vn_filename =
+ bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ iverneed->vn_file);
+ if (iverneed->vn_filename == NULL)
+ goto error_return;
+
+ iverneed->vn_auxptr =
+ ((Elf_Internal_Vernaux *)
+ bfd_alloc (abfd,
+ iverneed->vn_cnt * sizeof (Elf_Internal_Vernaux)));
+
+ evernaux = ((Elf_External_Vernaux *)
+ ((bfd_byte *) everneed + iverneed->vn_aux));
+ ivernaux = iverneed->vn_auxptr;
+ for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
+ {
+ _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
+
+ ivernaux->vna_nodename =
+ bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ ivernaux->vna_name);
+ if (ivernaux->vna_nodename == NULL)
+ goto error_return;
+
+ if (j + 1 < iverneed->vn_cnt)
+ ivernaux->vna_nextptr = ivernaux + 1;
+ else
+ ivernaux->vna_nextptr = NULL;
+
+ evernaux = ((Elf_External_Vernaux *)
+ ((bfd_byte *) evernaux + ivernaux->vna_next));
+ }
+
+ if (i + 1 < hdr->sh_info)
+ iverneed->vn_nextref = iverneed + 1;
+ else
+ iverneed->vn_nextref = NULL;
+
+ everneed = ((Elf_External_Verneed *)
+ ((bfd_byte *) everneed + iverneed->vn_next));
+ }
+
+ free (contents);
+ contents = NULL;
+ }
+
+ return true;
+
+ error_return:
+ if (contents == NULL)
+ free (contents);
+ return false;
+}
+
+asymbol *
+_bfd_elf_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ elf_symbol_type *newsym;
+
+ newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type));
+ if (!newsym)
+ return NULL;
+ else
+ {
+ newsym->symbol.the_bfd = abfd;
+ return &newsym->symbol;
+ }
+}
+
+void
+_bfd_elf_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* Return whether a symbol name implies a local symbol. Most targets
+ use this function for the is_local_label_name entry point, but some
+ override it. */
+
+boolean
+_bfd_elf_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ /* Normal local symbols start with ``.L''. */
+ if (name[0] == '.' && name[1] == 'L')
+ return true;
+
+ /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
+ DWARF debugging symbols starting with ``..''. */
+ if (name[0] == '.' && name[1] == '.')
+ return true;
+
+ /* gcc will sometimes generate symbols beginning with ``_.L_'' when
+ emitting DWARF debugging output. I suspect this is actually a
+ small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
+ ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
+ underscore to be emitted on some ELF targets). For ease of use,
+ we treat such symbols as local. */
+ if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
+ return true;
+
+ return false;
+}
+
+alent *
+_bfd_elf_get_lineno (ignore_abfd, symbol)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+{
+ abort ();
+ return NULL;
+}
+
+boolean
+_bfd_elf_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ /* If this isn't the right architecture for this backend, and this
+ isn't the generic backend, fail. */
+ if (arch != get_elf_backend_data (abfd)->arch
+ && arch != bfd_arch_unknown
+ && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
+ return false;
+
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+/* Find the nearest line to a particular section and offset, for error
+ reporting. */
+
+boolean
+_bfd_elf_find_nearest_line (abfd,
+ section,
+ symbols,
+ offset,
+ filename_ptr,
+ functionname_ptr,
+ line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ boolean found;
+ const char *filename;
+ asymbol *func;
+ bfd_vma low_func;
+ asymbol **p;
+
+ if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
+ return true;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
+ return true;
+
+ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+ &found, filename_ptr,
+ functionname_ptr, line_ptr,
+ &elf_tdata (abfd)->line_info))
+ return false;
+ if (found)
+ return true;
+
+ if (symbols == NULL)
+ return false;
+
+ filename = NULL;
+ func = NULL;
+ low_func = 0;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ elf_symbol_type *q;
+
+ q = (elf_symbol_type *) *p;
+
+ if (bfd_get_section (&q->symbol) != section)
+ continue;
+
+ switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
+ {
+ default:
+ break;
+ case STT_FILE:
+ filename = bfd_asymbol_name (&q->symbol);
+ break;
+ case STT_NOTYPE:
+ case STT_FUNC:
+ if (q->symbol.section == section
+ && q->symbol.value >= low_func
+ && q->symbol.value <= offset)
+ {
+ func = (asymbol *) q;
+ low_func = q->symbol.value;
+ }
+ break;
+ }
+ }
+
+ if (func == NULL)
+ return false;
+
+ *filename_ptr = filename;
+ *functionname_ptr = bfd_asymbol_name (func);
+ *line_ptr = 0;
+ return true;
+}
+
+int
+_bfd_elf_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+ int ret;
+
+ ret = get_elf_backend_data (abfd)->s->sizeof_ehdr;
+ if (! reloc)
+ ret += get_program_header_size (abfd);
+ return ret;
+}
+
+boolean
+_bfd_elf_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ Elf_Internal_Shdr *hdr;
+
+ if (! abfd->output_has_begun
+ && ! _bfd_elf_compute_section_file_positions
+ (abfd, (struct bfd_link_info *) NULL))
+ return false;
+
+ hdr = &elf_section_data (section)->this_hdr;
+
+ if (bfd_seek (abfd, hdr->sh_offset + offset, SEEK_SET) == -1)
+ return false;
+ if (bfd_write (location, 1, count, abfd) != count)
+ return false;
+
+ return true;
+}
+
+void
+_bfd_elf_no_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf_Internal_Rela *dst;
+{
+ abort ();
+}
+
+#if 0
+void
+_bfd_elf_no_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf_Internal_Rel *dst;
+{
+ abort ();
+}
+#endif
+
+/* Try to convert a non-ELF reloc into an ELF one. */
+
+boolean
+_bfd_elf_validate_reloc (abfd, areloc)
+ bfd *abfd;
+ arelent *areloc;
+{
+ /* Check whether we really have an ELF howto. */
+
+ if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
+ {
+ bfd_reloc_code_real_type code;
+ reloc_howto_type *howto;
+
+ /* Alien reloc: Try to determine its type to replace it with an
+ equivalent ELF reloc. */
+
+ if (areloc->howto->pc_relative)
+ {
+ switch (areloc->howto->bitsize)
+ {
+ case 8:
+ code = BFD_RELOC_8_PCREL;
+ break;
+ case 12:
+ code = BFD_RELOC_12_PCREL;
+ break;
+ case 16:
+ code = BFD_RELOC_16_PCREL;
+ break;
+ case 24:
+ code = BFD_RELOC_24_PCREL;
+ break;
+ case 32:
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case 64:
+ code = BFD_RELOC_64_PCREL;
+ break;
+ default:
+ goto fail;
+ }
+
+ howto = bfd_reloc_type_lookup (abfd, code);
+
+ if (areloc->howto->pcrel_offset != howto->pcrel_offset)
+ {
+ if (howto->pcrel_offset)
+ areloc->addend += areloc->address;
+ else
+ areloc->addend -= areloc->address; /* addend is unsigned!! */
+ }
+ }
+ else
+ {
+ switch (areloc->howto->bitsize)
+ {
+ case 8:
+ code = BFD_RELOC_8;
+ break;
+ case 14:
+ code = BFD_RELOC_14;
+ break;
+ case 16:
+ code = BFD_RELOC_16;
+ break;
+ case 26:
+ code = BFD_RELOC_26;
+ break;
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ case 64:
+ code = BFD_RELOC_64;
+ break;
+ default:
+ goto fail;
+ }
+
+ howto = bfd_reloc_type_lookup (abfd, code);
+ }
+
+ if (howto)
+ areloc->howto = howto;
+ else
+ goto fail;
+ }
+
+ return true;
+
+ fail:
+ (*_bfd_error_handler)
+ (_("%s: unsupported relocation type %s"),
+ bfd_get_filename (abfd), areloc->howto->name);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+}
+
+boolean
+_bfd_elf_close_and_cleanup (abfd)
+ bfd *abfd;
+{
+ if (bfd_get_format (abfd) == bfd_object)
+ {
+ if (elf_shstrtab (abfd) != NULL)
+ _bfd_stringtab_free (elf_shstrtab (abfd));
+ }
+
+ return _bfd_generic_close_and_cleanup (abfd);
+}
+
+/* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY
+ in the relocation's offset. Thus we cannot allow any sort of sanity
+ range-checking to interfere. There is nothing else to do in processing
+ this reloc. */
+
+bfd_reloc_status_type
+_bfd_elf_rel_vtable_reloc_fn (abfd, re, symbol, data, is, obfd, errmsg)
+ bfd *abfd;
+ arelent *re;
+ struct symbol_cache_entry *symbol;
+ PTR data;
+ asection *is;
+ bfd *obfd;
+ char **errmsg;
+{
+ return bfd_reloc_ok;
+}
+
+
+/* Elf core file support. Much of this only works on native
+ toolchains, since we rely on knowing the
+ machine-dependent procfs structure in order to pick
+ out details about the corefile. */
+
+#ifdef HAVE_SYS_PROCFS_H
+# include <sys/procfs.h>
+#endif
+
+
+/* Define offsetof for those systems which lack it. */
+
+#ifndef offsetof
+# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+
+/* FIXME: this is kinda wrong, but it's what gdb wants. */
+
+static int
+elfcore_make_pid (abfd)
+ bfd* abfd;
+{
+ return ((elf_tdata (abfd)->core_lwpid << 16)
+ + (elf_tdata (abfd)->core_pid));
+}
+
+
+/* If there isn't a section called NAME, make one, using
+ data from SECT. Note, this function will generate a
+ reference to NAME, so you shouldn't deallocate or
+ overwrite it. */
+
+static boolean
+elfcore_maybe_make_sect (abfd, name, sect)
+ bfd* abfd;
+ char* name;
+ asection* sect;
+{
+ asection* sect2;
+
+ if (bfd_get_section_by_name (abfd, name) != NULL)
+ return true;
+
+ sect2 = bfd_make_section (abfd, name);
+ if (sect2 == NULL)
+ return false;
+
+ sect2->_raw_size = sect->_raw_size;
+ sect2->filepos = sect->filepos;
+ sect2->flags = sect->flags;
+ sect2->alignment_power = sect->alignment_power;
+ return true;
+}
+
+
+/* prstatus_t exists on:
+ solaris 2.[567]
+ linux 2.[01] + glibc
+ unixware 4.2
+*/
+
+#if defined (HAVE_PRSTATUS_T)
+static boolean
+elfcore_grok_prstatus (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ prstatus_t prstat;
+ char buf[100];
+ char* name;
+ asection* sect;
+
+ if (note->descsz != sizeof (prstat))
+ return true;
+
+ memcpy (&prstat, note->descdata, sizeof (prstat));
+
+ elf_tdata (abfd)->core_signal = prstat.pr_cursig;
+ elf_tdata (abfd)->core_pid = prstat.pr_pid;
+
+ /* pr_who exists on:
+ solaris 2.[567]
+ unixware 4.2
+ pr_who doesn't exist on:
+ linux 2.[01]
+ */
+#if defined (HAVE_PRSTATUS_T_PR_WHO)
+ elf_tdata (abfd)->core_lwpid = prstat.pr_who;
+#endif
+
+ /* Make a ".reg/999" section. */
+
+ sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
+ name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return false;
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return false;
+ sect->_raw_size = sizeof (prstat.pr_reg);
+ sect->filepos = note->descpos + offsetof (prstatus_t, pr_reg);
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
+ return false;
+
+ return true;
+}
+#endif /* defined (HAVE_PRSTATUS_T) */
+
+
+/* There isn't a consistent prfpregset_t across platforms,
+ but it doesn't matter, because we don't have to pick this
+ data structure apart. */
+
+static boolean
+elfcore_grok_prfpreg (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ char buf[100];
+ char* name;
+ asection* sect;
+
+ /* Make a ".reg2/999" section. */
+
+ sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
+ name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return false;
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return false;
+ sect->_raw_size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ if (! elfcore_maybe_make_sect (abfd, ".reg2", sect))
+ return false;
+
+ return true;
+}
+
+#if defined (HAVE_PRPSINFO_T)
+# define elfcore_psinfo_t prpsinfo_t
+#endif
+
+#if defined (HAVE_PSINFO_T)
+# define elfcore_psinfo_t psinfo_t
+#endif
+
+
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+
+/* return a malloc'ed copy of a string at START which is at
+ most MAX bytes long, possibly without a terminating '\0'.
+ the copy will always have a terminating '\0'. */
+
+static char*
+elfcore_strndup (abfd, start, max)
+ bfd* abfd;
+ char* start;
+ int max;
+{
+ char* dup;
+ char* end = memchr (start, '\0', max);
+ int len;
+
+ if (end == NULL)
+ len = max;
+ else
+ len = end - start;
+
+ dup = bfd_alloc (abfd, len + 1);
+ if (dup == NULL)
+ return NULL;
+
+ memcpy (dup, start, len);
+ dup[len] = '\0';
+
+ return dup;
+}
+
+static boolean
+elfcore_grok_psinfo (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ elfcore_psinfo_t psinfo;
+
+ if (note->descsz != sizeof (elfcore_psinfo_t))
+ return true;
+
+ memcpy (&psinfo, note->descdata, note->descsz);
+
+ elf_tdata (abfd)->core_program
+ = elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+
+ elf_tdata (abfd)->core_command
+ = elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+
+ /* Note that for some reason, a spurious space is tacked
+ onto the end of the args in some (at least one anyway)
+ implementations, so strip it off if it exists. */
+
+ {
+ char* command = elf_tdata (abfd)->core_command;
+ int n = strlen (command);
+
+ if (0 < n && command[n - 1] == ' ')
+ command[n - 1] = '\0';
+ }
+
+ return true;
+}
+#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
+
+
+#if defined (HAVE_PSTATUS_T)
+static boolean
+elfcore_grok_pstatus (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ pstatus_t pstat;
+
+ if (note->descsz != sizeof (pstat))
+ return true;
+
+ memcpy (&pstat, note->descdata, sizeof (pstat));
+
+ elf_tdata (abfd)->core_pid = pstat.pr_pid;
+
+ /* Could grab some more details from the "representative"
+ lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
+ NT_LWPSTATUS note, presumably. */
+
+ return true;
+}
+#endif /* defined (HAVE_PSTATUS_T) */
+
+
+#if defined (HAVE_LWPSTATUS_T)
+static boolean
+elfcore_grok_lwpstatus (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ lwpstatus_t lwpstat;
+ char buf[100];
+ char* name;
+ asection* sect;
+
+ if (note->descsz != sizeof (lwpstat))
+ return true;
+
+ memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
+
+ elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid;
+ elf_tdata (abfd)->core_signal = lwpstat.pr_cursig;
+
+ /* Make a ".reg/999" section. */
+
+ sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
+ name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return false;
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return false;
+
+#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
+ sect->_raw_size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
+ sect->filepos = note->descpos
+ + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
+#endif
+
+#if defined (HAVE_LWPSTATUS_T_PR_REG)
+ sect->_raw_size = sizeof (lwpstat.pr_reg);
+ sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
+#endif
+
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
+ return false;
+
+ /* Make a ".reg2/999" section */
+
+ sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
+ name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return false;
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return false;
+
+#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
+ sect->_raw_size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
+ sect->filepos = note->descpos
+ + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
+#endif
+
+#if defined (HAVE_LWPSTATUS_T_PR_FPREG)
+ sect->_raw_size = sizeof (lwpstat.pr_fpreg);
+ sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
+#endif
+
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ if (!elfcore_maybe_make_sect (abfd, ".reg2", sect))
+ return false;
+
+ return true;
+}
+#endif /* defined (HAVE_LWPSTATUS_T) */
+
+
+
+static boolean
+elfcore_grok_note (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ switch (note->type)
+ {
+ default:
+ return true;
+
+#if defined (HAVE_PRSTATUS_T)
+ case NT_PRSTATUS:
+ return elfcore_grok_prstatus (abfd, note);
+#endif
+
+#if defined (HAVE_PSTATUS_T)
+ case NT_PSTATUS:
+ return elfcore_grok_pstatus (abfd, note);
+#endif
+
+#if defined (HAVE_LWPSTATUS_T)
+ case NT_LWPSTATUS:
+ return elfcore_grok_lwpstatus (abfd, note);
+#endif
+
+ case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */
+ return elfcore_grok_prfpreg (abfd, note);
+
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+ case NT_PRPSINFO:
+ case NT_PSINFO:
+ return elfcore_grok_psinfo (abfd, note);
+#endif
+ }
+}
+
+
+static boolean
+elfcore_read_notes (abfd, offset, size)
+ bfd* abfd;
+ bfd_vma offset;
+ bfd_vma size;
+{
+ char* buf;
+ char* p;
+
+ if (size <= 0)
+ return true;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+ return false;
+
+ buf = bfd_malloc ((size_t) size);
+ if (buf == NULL)
+ return false;
+
+ if (bfd_read (buf, size, 1, abfd) != size)
+ {
+ error:
+ free (buf);
+ return false;
+ }
+
+ p = buf;
+ while (p < buf + size)
+ {
+ /* FIXME: bad alignment assumption. */
+ Elf_External_Note* xnp = (Elf_External_Note*) p;
+ Elf_Internal_Note in;
+
+ in.type = bfd_h_get_32 (abfd, (bfd_byte *) xnp->type);
+
+ in.namesz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->namesz);
+ in.namedata = xnp->name;
+
+ in.descsz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->descsz);
+ in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
+ in.descpos = offset + (in.descdata - buf);
+
+ if (! elfcore_grok_note (abfd, &in))
+ goto error;
+
+ p = in.descdata + BFD_ALIGN (in.descsz, 4);
+ }
+
+ free (buf);
+ return true;
+}
+
+
+
+boolean
+_bfd_elfcore_section_from_phdr (abfd, phdr, sec_num)
+ bfd* abfd;
+ Elf_Internal_Phdr* phdr;
+ int sec_num;
+{
+ if (! bfd_section_from_phdr (abfd, phdr, sec_num))
+ return false;
+
+ if (phdr->p_type == PT_NOTE
+ && ! elfcore_read_notes (abfd, phdr->p_offset, phdr->p_filesz))
+ return false;
+
+ return true;
+}
+
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
new file mode 100644
index 00000000000..a490a246b07
--- /dev/null
+++ b/bfd/elf32-arc.c
@@ -0,0 +1,213 @@
+/* ARC-specific support for 32-bit ELF
+ Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/arc.h"
+
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void arc_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static boolean arc_elf_object_p PARAMS ((bfd *));
+static void arc_elf_final_write_processing PARAMS ((bfd *, boolean));
+
+/* Try to minimize the amount of space occupied by relocation tables
+ on the ROM (not that the ROM won't be swamped by other ELF overhead). */
+#define USE_REL
+
+static reloc_howto_type elf_arc_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_ARC_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARC_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A standard 32 bit relocation. */
+ HOWTO (R_ARC_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARC_32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 26 bit absolute branch, right shifted by 2. */
+ HOWTO (R_ARC_B26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARC_B26", /* name */
+ false, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 22 bit branch; bits 21-2 are stored in bits 26-7. */
+ HOWTO (R_ARC_B22_PCREL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 22, /* bitsize */
+ true, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARC_B22_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x07ffff80, /* src_mask */
+ 0x07ffff80, /* dst_mask */
+ true), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to ARC ELF reloc types. */
+
+struct arc_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct arc_reloc_map arc_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_ARC_NONE, },
+ { BFD_RELOC_32, R_ARC_32 },
+ { BFD_RELOC_CTOR, R_ARC_32 },
+ { BFD_RELOC_ARC_B26, R_ARC_B26 },
+ { BFD_RELOC_ARC_B22_PCREL, R_ARC_B22_PCREL },
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (arc_reloc_map) / sizeof (struct arc_reloc_map);
+ i++)
+ {
+ if (arc_reloc_map[i].bfd_reloc_val == code)
+ return &elf_arc_howto_table[arc_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an ARC ELF reloc. */
+
+static void
+arc_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
+ cache_ptr->howto = &elf_arc_howto_table[r_type];
+}
+
+/* Set the right machine number for an ARC ELF file. */
+
+static boolean
+arc_elf_object_p (abfd)
+ bfd *abfd;
+{
+ int mach;
+ unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH;
+
+ switch (arch)
+ {
+ case E_ARC_MACH_BASE:
+ mach = bfd_mach_arc_base;
+ break;
+ default:
+ /* Unknown cpu type. ??? What to do? */
+ return false;
+ }
+
+ (void) bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
+ return true;
+}
+
+/* The final processing done just before writing out an ARC ELF object file.
+ This gets the ARC architecture right based on the machine number. */
+
+static void
+arc_elf_final_write_processing (abfd, linker)
+ bfd *abfd;
+ boolean linker;
+{
+ int mach;
+ unsigned long val;
+
+ switch (mach = bfd_get_mach (abfd))
+ {
+ case bfd_mach_arc_base:
+ val = E_ARC_MACH_BASE;
+ break;
+ default:
+ return;
+ }
+
+ elf_elfheader (abfd)->e_flags &=~ EF_ARC_MACH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+#define TARGET_LITTLE_SYM bfd_elf32_littlearc_vec
+#define TARGET_LITTLE_NAME "elf32-littlearc"
+#define TARGET_BIG_SYM bfd_elf32_bigarc_vec
+#define TARGET_BIG_NAME "elf32-bigarc"
+#define ELF_ARCH bfd_arch_arc
+#define ELF_MACHINE_CODE EM_CYGNUS_ARC
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel arc_info_to_howto_rel
+#define elf_backend_object_p arc_elf_object_p
+#define elf_backend_final_write_processing \
+ arc_elf_final_write_processing
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
new file mode 100644
index 00000000000..d4e97d6b9bf
--- /dev/null
+++ b/bfd/elf32-arm.h
@@ -0,0 +1,3010 @@
+/* 32-bit ELF support for ARM
+ Copyright 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+typedef unsigned long int insn32;
+typedef unsigned short int insn16;
+
+static boolean elf32_arm_set_private_flags
+ PARAMS ((bfd *, flagword));
+static boolean elf32_arm_copy_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean elf32_arm_merge_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean elf32_arm_print_private_bfd_data
+ PARAMS ((bfd *, PTR));
+static int elf32_arm_get_symbol_type
+ PARAMS (( Elf_Internal_Sym *, int));
+static struct bfd_link_hash_table *elf32_arm_link_hash_table_create
+ PARAMS ((bfd *));
+static bfd_reloc_status_type elf32_arm_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *, const char *, unsigned char));
+
+static insn32 insert_thumb_branch
+ PARAMS ((insn32, int));
+static struct elf_link_hash_entry *find_thumb_glue
+ PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
+static struct elf_link_hash_entry *find_arm_glue
+ PARAMS ((struct bfd_link_info *, CONST char *, bfd *));
+static void record_arm_to_thumb_glue
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static void record_thumb_to_arm_glue
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+
+/* The linker script knows the section names for placement.
+ The entry_names are used to do simple name mangling on the stubs.
+ Given a function name, and its type, the stub can be found. The
+ name can be changed. The only requirement is the %s be present.
+ */
+
+#define INTERWORK_FLAG( abfd ) (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
+
+#define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"
+#define THUMB2ARM_GLUE_ENTRY_NAME "__%s_from_thumb"
+
+#define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"
+#define ARM2THUMB_GLUE_ENTRY_NAME "__%s_from_arm"
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 16
+
+/* The first entry in a procedure linkage table looks like
+ this. It is set up so that any shared library function that is
+ called before the relocation has been set up calles the dynamic
+ linker first */
+
+static const bfd_byte elf32_arm_plt0_entry [PLT_ENTRY_SIZE] =
+{
+ 0x04, 0xe0, 0x2d, 0xe5, /* str lr, [sp, #-4]! */
+ 0x10, 0xe0, 0x9f, 0xe5, /* ldr lr, [pc, #16] */
+ 0x0e, 0xe0, 0x8f, 0xe0, /* adr lr, pc, lr */
+ 0x08, 0xf0, 0xbe, 0xe5 /* ldr pc, [lr, #-4] */
+};
+
+/* Subsequent entries in a procedure linkage table look like
+ this. */
+
+static const bfd_byte elf32_arm_plt_entry [PLT_ENTRY_SIZE] =
+{
+ 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc, #4] */
+ 0x0c, 0xc0, 0x8f, 0xe0, /* add ip, pc, ip */
+ 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
+ 0x00, 0x00, 0x00, 0x00 /* offset to symbol in got */
+};
+
+
+/* The ARM linker needs to keep track of the number of relocs that it
+ decides to copy in check_relocs for each symbol. This is so that
+ it can discard PC relative relocs if it doesn't need them when
+ linking with -Bsymbolic. We store the information in a field
+ extending the regular ELF linker hash table. */
+
+/* This structure keeps track of the number of PC relative relocs we
+ have copied for a given symbol. */
+
+struct elf32_arm_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf32_arm_pcrel_relocs_copied * next;
+ /* A section in dynobj. */
+ asection * section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* arm ELF linker hash entry. */
+
+struct elf32_arm_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct elf32_arm_pcrel_relocs_copied * pcrel_relocs_copied;
+};
+
+/* Declare this now that the above structures are defined. */
+
+static boolean elf32_arm_discard_copies
+ PARAMS ((struct elf32_arm_link_hash_entry *, PTR));
+
+/* Traverse an arm ELF linker hash table. */
+
+#define elf32_arm_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the ARM elf linker hash table from a link_info structure. */
+#define elf32_arm_hash_table(info) \
+ ((struct elf32_arm_link_hash_table *) ((info)->hash))
+
+/* ARM ELF linker hash table */
+struct elf32_arm_link_hash_table
+ {
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ /* The size in bytes of the section containg the Thumb-to-ARM glue. */
+ long int thumb_glue_size;
+
+ /* The size in bytes of the section containg the ARM-to-Thumb glue. */
+ long int arm_glue_size;
+
+ /* An arbitary input BFD chosen to hold the glue sections. */
+ bfd * bfd_of_glue_owner;
+ };
+
+
+/* Create an ARM elf linker hash table */
+
+static struct bfd_link_hash_table *
+elf32_arm_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct elf32_arm_link_hash_table *ret;
+
+ ret = ((struct elf32_arm_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf32_arm_link_hash_table)));
+ if (ret == (struct elf32_arm_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ _bfd_elf_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ ret->thumb_glue_size = 0;
+ ret->arm_glue_size = 0;
+ ret->bfd_of_glue_owner = NULL;
+
+ return &ret->root.root;
+}
+
+static struct elf_link_hash_entry *
+find_thumb_glue (link_info, name, input_bfd)
+ struct bfd_link_info *link_info;
+ CONST char *name;
+ bfd *input_bfd;
+{
+ char *tmp_name;
+ struct elf_link_hash_entry *hash;
+ struct elf32_arm_link_hash_table *hash_table;
+
+ /* We need a pointer to the armelf specific hash table. */
+ hash_table = elf32_arm_hash_table (link_info);
+
+
+ tmp_name = ((char *)
+ bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1));
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
+
+ hash = elf_link_hash_lookup
+ (&(hash_table)->root, tmp_name, false, false, true);
+
+ if (hash == NULL)
+ /* xgettext:c-format */
+ _bfd_error_handler (_ ("%s: unable to find THUMB glue '%s' for `%s'"),
+ bfd_get_filename (input_bfd), tmp_name, name);
+
+ free (tmp_name);
+
+ return hash;
+}
+
+static struct elf_link_hash_entry *
+find_arm_glue (link_info, name, input_bfd)
+ struct bfd_link_info *link_info;
+ CONST char *name;
+ bfd *input_bfd;
+{
+ char *tmp_name;
+ struct elf_link_hash_entry *myh;
+ struct elf32_arm_link_hash_table *hash_table;
+
+ /* We need a pointer to the elfarm specific hash table. */
+ hash_table = elf32_arm_hash_table (link_info);
+
+ tmp_name = ((char *)
+ bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
+
+ myh = elf_link_hash_lookup
+ (&(hash_table)->root, tmp_name, false, false, true);
+
+ if (myh == NULL)
+ /* xgettext:c-format */
+ _bfd_error_handler (_ ("%s: unable to find ARM glue '%s' for `%s'"),
+ bfd_get_filename (input_bfd), tmp_name, name);
+
+ free (tmp_name);
+
+ return myh;
+}
+
+/*
+ ARM->Thumb glue:
+
+ .arm
+ __func_from_arm:
+ ldr r12, __func_addr
+ bx r12
+ __func_addr:
+ .word func @ behave as if you saw a ARM_32 reloc
+ */
+
+#define ARM2THUMB_GLUE_SIZE 12
+static const insn32 a2t1_ldr_insn = 0xe59fc000;
+static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
+static const insn32 a2t3_func_addr_insn = 0x00000001;
+
+/*
+ Thumb->ARM: Thumb->(non-interworking aware) ARM
+
+ .thumb .thumb
+ .align 2 .align 2
+ __func_from_thumb: __func_from_thumb:
+ bx pc push {r6, lr}
+ nop ldr r6, __func_addr
+ .arm mov lr, pc
+ __func_change_to_arm: bx r6
+ b func .arm
+ __func_back_to_thumb:
+ ldmia r13! {r6, lr}
+ bx lr
+ __func_addr:
+ .word func
+ */
+
+#define THUMB2ARM_GLUE_SIZE 8
+static const insn16 t2a1_bx_pc_insn = 0x4778;
+static const insn16 t2a2_noop_insn = 0x46c0;
+static const insn32 t2a3_b_insn = 0xea000000;
+
+static const insn16 t2a1_push_insn = 0xb540;
+static const insn16 t2a2_ldr_insn = 0x4e03;
+static const insn16 t2a3_mov_insn = 0x46fe;
+static const insn16 t2a4_bx_insn = 0x4730;
+static const insn32 t2a5_pop_insn = 0xe8bd4040;
+static const insn32 t2a6_bx_insn = 0xe12fff1e;
+
+boolean
+bfd_elf32_arm_allocate_interworking_sections (info)
+ struct bfd_link_info * info;
+{
+ asection * s;
+ bfd_byte * foo;
+ struct elf32_arm_link_hash_table * globals;
+
+ globals = elf32_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+
+ if (globals->arm_glue_size != 0)
+ {
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ foo = (bfd_byte *) bfd_alloc
+ (globals->bfd_of_glue_owner, globals->arm_glue_size);
+
+ s->_raw_size = s->_cooked_size = globals->arm_glue_size;
+ s->contents = foo;
+ }
+
+ if (globals->thumb_glue_size != 0)
+ {
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ foo = (bfd_byte *) bfd_alloc
+ (globals->bfd_of_glue_owner, globals->thumb_glue_size);
+
+ s->_raw_size = s->_cooked_size = globals->thumb_glue_size;
+ s->contents = foo;
+ }
+
+ return true;
+}
+
+static void
+record_arm_to_thumb_glue (link_info, h)
+ struct bfd_link_info * link_info;
+ struct elf_link_hash_entry * h;
+{
+ const char * name = h->root.root.string;
+ register asection * s;
+ char * tmp_name;
+ struct elf_link_hash_entry * myh;
+ struct elf32_arm_link_hash_table * globals;
+
+ globals = elf32_arm_hash_table (link_info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+
+
+ BFD_ASSERT (s != NULL);
+
+ tmp_name = ((char *)
+ bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);
+
+ myh = elf_link_hash_lookup
+ (&(globals)->root, tmp_name, false, false, true);
+
+ if (myh != NULL)
+ {
+ free (tmp_name);
+ return; /* we've already seen this guy */
+ }
+
+ /* The only trick here is using hash_table->arm_glue_size as the value. Even
+ though the section isn't allocated yet, this is where we will be putting
+ it. */
+
+ _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL,
+ s, globals->arm_glue_size + 1,
+ NULL, true, false,
+ (struct bfd_link_hash_entry **) &myh);
+
+ free (tmp_name);
+
+ globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
+
+ return;
+}
+
+static void
+record_thumb_to_arm_glue (link_info, h)
+ struct bfd_link_info *link_info;
+ struct elf_link_hash_entry *h;
+{
+ const char *name = h->root.root.string;
+ register asection *s;
+ char *tmp_name;
+ struct elf_link_hash_entry *myh;
+ struct elf32_arm_link_hash_table *hash_table;
+ char bind;
+
+ hash_table = elf32_arm_hash_table (link_info);
+
+ BFD_ASSERT (hash_table != NULL);
+ BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_section_by_name
+ (hash_table->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ tmp_name = (char *) bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);
+
+ myh = elf_link_hash_lookup
+ (&(hash_table)->root, tmp_name, false, false, true);
+
+ if (myh != NULL)
+ {
+ free (tmp_name);
+ return; /* we've already seen this guy */
+ }
+
+ _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, hash_table->thumb_glue_size + 1,
+ NULL, true, false,
+ (struct bfd_link_hash_entry **) &myh);
+
+ /* If we mark it 'thumb', the disassembler will do a better job. */
+ bind = ELF_ST_BIND (myh->type);
+ myh->type = ELF_ST_INFO (bind, STT_ARM_TFUNC);
+
+ free (tmp_name);
+
+ /* Allocate another symbol to mark where we switch to arm mode. */
+
+#define CHANGE_TO_ARM "__%s_change_to_arm"
+#define BACK_FROM_ARM "__%s_back_from_arm"
+
+ tmp_name = (char *) bfd_malloc (strlen (name) + strlen (CHANGE_TO_ARM) + 1);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, CHANGE_TO_ARM, name);
+
+ myh = NULL;
+
+ _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner, tmp_name,
+ BSF_LOCAL, s, hash_table->thumb_glue_size + 4,
+ NULL, true, false,
+ (struct bfd_link_hash_entry **) &myh);
+
+ free (tmp_name);
+
+ hash_table->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
+
+ return;
+}
+
+/* Select a BFD to be used to hold the sections used by the glue code.
+ This function is called from the linker scripts in ld/emultempl/
+ {armelf/pe}.em */
+boolean
+bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ struct elf32_arm_link_hash_table *globals;
+ flagword flags;
+ asection *sec;
+
+ /* If we are only performing a partial link do not bother
+ getting a bfd to hold the glue. */
+ if (info->relocateable)
+ return true;
+
+ globals = elf32_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+
+ if (globals->bfd_of_glue_owner != NULL)
+ return true;
+
+ sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
+
+ if (sec == NULL)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
+
+ if (sec == NULL
+ || !bfd_set_section_flags (abfd, sec, flags)
+ || !bfd_set_section_alignment (abfd, sec, 2))
+ return false;
+ }
+
+ sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
+
+ if (sec == NULL)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
+
+ if (sec == NULL
+ || !bfd_set_section_flags (abfd, sec, flags)
+ || !bfd_set_section_alignment (abfd, sec, 2))
+ return false;
+ }
+
+ /* Save the bfd for later use. */
+ globals->bfd_of_glue_owner = abfd;
+
+ return true;
+}
+
+boolean
+bfd_elf32_arm_process_before_allocation (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+ Elf32_External_Sym *extsyms = NULL;
+ Elf32_External_Sym *free_extsyms = NULL;
+
+ asection *sec;
+ struct elf32_arm_link_hash_table *globals;
+
+ /* If we are only performing a partial link do not bother
+ to construct any glue. */
+ if (link_info->relocateable)
+ return true;
+
+ /* Here we have a bfd that is to be included on the link. We have a hook
+ to do reloc rummaging, before section sizes are nailed down. */
+
+ globals = elf32_arm_hash_table (link_info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ /* Rummage around all the relocs and map the glue vectors. */
+ sec = abfd->sections;
+
+ if (sec == NULL)
+ return true;
+
+ for (; sec != NULL; sec = sec->next)
+ {
+ if (sec->reloc_count == 0)
+ continue;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ /* Load the relocs. */
+
+ irel = (_bfd_elf32_link_read_relocs (abfd, sec, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL, false));
+
+ BFD_ASSERT (irel != 0);
+
+ irelend = irel + sec->reloc_count;
+ for (; irel < irelend; irel++)
+ {
+ long r_type;
+ unsigned long r_index;
+ unsigned char code;
+
+ struct elf_link_hash_entry *h;
+
+ r_type = ELF32_R_TYPE (irel->r_info);
+ r_index = ELF32_R_SYM (irel->r_info);
+
+ /* These are the only relocation types we care about */
+ if (r_type != R_ARM_PC24
+ && r_type != R_ARM_THM_PC22)
+ continue;
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (!bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (extsyms == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ /* Go get them off disk. */
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ /* If the relocation is not against a symbol it cannot concern us. */
+
+ h = NULL;
+
+ /* We don't care about local symbols */
+ if (r_index < symtab_hdr->sh_info)
+ continue;
+
+ /* This is an external symbol */
+ r_index -= symtab_hdr->sh_info;
+ h = (struct elf_link_hash_entry *)
+ elf_sym_hashes (abfd)[r_index];
+
+ /* If the relocation is against a static symbol it must be within
+ the current section and so cannot be a cross ARM/Thumb relocation. */
+ if (h == NULL)
+ continue;
+
+ switch (r_type)
+ {
+ case R_ARM_PC24:
+ /* This one is a call from arm code. We need to look up
+ the target of the call. If it is a thumb target, we
+ insert glue. */
+
+ if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
+ record_arm_to_thumb_glue (link_info, h);
+ break;
+
+ case R_ARM_THM_PC22:
+ /* This one is a call from thumb code. We look
+ up the target of the call. If it is not a thumb
+ target, we insert glue. */
+
+ if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
+ record_thumb_to_arm_glue (link_info, h);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return true;
+error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (free_extsyms != NULL)
+ free (free_extsyms);
+ return false;
+
+}
+
+/* The thumb form of a long branch is a bit finicky, because the offset
+ encoding is split over two fields, each in it's own instruction. They
+ can occur in any order. So given a thumb form of long branch, and an
+ offset, insert the offset into the thumb branch and return finished
+ instruction.
+
+ It takes two thumb instructions to encode the target address. Each has
+ 11 bits to invest. The upper 11 bits are stored in one (identifed by
+ H-0.. see below), the lower 11 bits are stored in the other (identified
+ by H-1).
+
+ Combine together and shifted left by 1 (it's a half word address) and
+ there you have it.
+
+ Op: 1111 = F,
+ H-0, upper address-0 = 000
+ Op: 1111 = F,
+ H-1, lower address-0 = 800
+
+ They can be ordered either way, but the arm tools I've seen always put
+ the lower one first. It probably doesn't matter. krk@cygnus.com
+
+ XXX: Actually the order does matter. The second instruction (H-1)
+ moves the computed address into the PC, so it must be the second one
+ in the sequence. The problem, however is that whilst little endian code
+ stores the instructions in HI then LOW order, big endian code does the
+ reverse. nickc@cygnus.com */
+
+#define LOW_HI_ORDER 0xF800F000
+#define HI_LOW_ORDER 0xF000F800
+
+static insn32
+insert_thumb_branch (br_insn, rel_off)
+ insn32 br_insn;
+ int rel_off;
+{
+ unsigned int low_bits;
+ unsigned int high_bits;
+
+
+ BFD_ASSERT ((rel_off & 1) != 1);
+
+ rel_off >>= 1; /* half word aligned address */
+ low_bits = rel_off & 0x000007FF; /* the bottom 11 bits */
+ high_bits = (rel_off >> 11) & 0x000007FF; /* the top 11 bits */
+
+ if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
+ br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
+ else if ((br_insn & HI_LOW_ORDER) == HI_LOW_ORDER)
+ br_insn = HI_LOW_ORDER | (high_bits << 16) | low_bits;
+ else
+ abort (); /* error - not a valid branch instruction form */
+
+ /* FIXME: abort is probably not the right call. krk@cygnus.com */
+
+ return br_insn;
+}
+
+/* Thumb code calling an ARM function */
+static int
+elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
+ hit_data, sym_sec, offset, addend, val)
+ struct bfd_link_info *info;
+ char *name;
+ bfd *input_bfd;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_byte *hit_data;
+ asection *sym_sec;
+ int offset;
+ int addend;
+ bfd_vma val;
+{
+ asection *s = 0;
+ long int my_offset;
+ unsigned long int tmp;
+ long int ret_offset;
+ struct elf_link_hash_entry *myh;
+ struct elf32_arm_link_hash_table *globals;
+
+ myh = find_thumb_glue (info, name, input_bfd);
+ if (myh == NULL)
+ return false;
+
+ globals = elf32_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ my_offset = myh->root.u.def.value;
+
+ s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
+ THUMB2ARM_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ if ((my_offset & 0x01) == 0x01)
+ {
+ if (sym_sec != NULL
+ && sym_sec->owner != NULL
+ && !INTERWORK_FLAG (sym_sec->owner))
+ {
+ _bfd_error_handler
+ (_ ("%s(%s): warning: interworking not enabled."),
+ bfd_get_filename (sym_sec->owner), name);
+ _bfd_error_handler
+ (_ (" first occurrence: %s: thumb call to arm"),
+ bfd_get_filename (input_bfd));
+
+ return false;
+ }
+
+ --my_offset;
+ myh->root.u.def.value = my_offset;
+
+ bfd_put_16 (output_bfd, t2a1_bx_pc_insn,
+ s->contents + my_offset);
+
+ bfd_put_16 (output_bfd, t2a2_noop_insn,
+ s->contents + my_offset + 2);
+
+ ret_offset =
+ ((bfd_signed_vma) val) /* Address of destination of the stub */
+ - ((bfd_signed_vma)
+ (s->output_offset /* Offset from the start of the current section to the start of the stubs. */
+ + my_offset /* Offset of the start of this stub from the start of the stubs. */
+ + s->output_section->vma) /* Address of the start of the current section. */
+ + 4 /* The branch instruction is 4 bytes into the stub. */
+ + 8); /* ARM branches work from the pc of the instruction + 8. */
+
+ bfd_put_32 (output_bfd,
+ t2a3_b_insn | ((ret_offset >> 2) & 0x00FFFFFF),
+ s->contents + my_offset + 4);
+ }
+
+ BFD_ASSERT (my_offset <= globals->thumb_glue_size);
+
+ /* Now go back and fix up the original BL insn to point
+ to here. */
+ ret_offset =
+ s->output_offset
+ + my_offset
+ - (input_section->output_offset
+ + offset + addend)
+ - 4;
+
+ tmp = bfd_get_32 (input_bfd, hit_data
+ - input_section->vma);
+
+ bfd_put_32 (output_bfd,
+ insert_thumb_branch (tmp, ret_offset),
+ hit_data - input_section->vma);
+
+ return true;
+}
+
+/* Arm code calling a Thumb function */
+static int
+elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
+ hit_data, sym_sec, offset, addend, val)
+
+ struct bfd_link_info *info;
+ char *name;
+ bfd *input_bfd;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_byte *hit_data;
+ asection *sym_sec;
+ int offset;
+ int addend;
+ bfd_vma val;
+{
+ unsigned long int tmp;
+ long int my_offset;
+ asection *s;
+ long int ret_offset;
+ struct elf_link_hash_entry *myh;
+ struct elf32_arm_link_hash_table *globals;
+
+ myh = find_arm_glue (info, name, input_bfd);
+ if (myh == NULL)
+ return false;
+
+ globals = elf32_arm_hash_table (info);
+
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ my_offset = myh->root.u.def.value;
+ s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ if ((my_offset & 0x01) == 0x01)
+ {
+ if (sym_sec != NULL
+ && sym_sec->owner != NULL
+ && !INTERWORK_FLAG (sym_sec->owner))
+ {
+ _bfd_error_handler
+ (_ ("%s(%s): warning: interworking not enabled."),
+ bfd_get_filename (sym_sec->owner), name);
+ _bfd_error_handler
+ (_ (" first occurrence: %s: arm call to thumb"),
+ bfd_get_filename (input_bfd));
+ }
+ --my_offset;
+ myh->root.u.def.value = my_offset;
+
+ bfd_put_32 (output_bfd, a2t1_ldr_insn,
+ s->contents + my_offset);
+
+ bfd_put_32 (output_bfd, a2t2_bx_r12_insn,
+ s->contents + my_offset + 4);
+
+ /* It's a thumb address. Add the low order bit. */
+ bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
+ s->contents + my_offset + 8);
+ }
+
+ BFD_ASSERT (my_offset <= globals->arm_glue_size);
+
+ tmp = bfd_get_32 (input_bfd, hit_data);
+ tmp = tmp & 0xFF000000;
+
+ /* Somehow these are both 4 too far, so subtract 8. */
+ ret_offset = s->output_offset
+ + my_offset
+ + s->output_section->vma
+ - (input_section->output_offset
+ + input_section->output_section->vma
+ + offset + addend)
+ - 8;
+
+ tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
+
+ bfd_put_32 (output_bfd, tmp, hit_data
+ - input_section->vma);
+
+
+ return true;
+}
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel, value,
+ info, sym_sec, sym_name, sym_flags)
+ reloc_howto_type * howto;
+ bfd * input_bfd;
+ bfd * output_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * rel;
+ bfd_vma value;
+ struct bfd_link_info * info;
+ asection * sym_sec;
+ const char * sym_name;
+ unsigned char sym_flags;
+{
+ unsigned long r_type = howto->type;
+ unsigned long r_symndx;
+ bfd_byte * hit_data = contents + rel->r_offset;
+ bfd * dynobj = NULL;
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ bfd_vma * local_got_offsets;
+ asection * sgot = NULL;
+ asection * splt = NULL;
+ asection * sreloc = NULL;
+ struct elf_link_hash_entry * h = NULL;
+ bfd_vma addend;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ }
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+#ifdef USE_REL
+ addend = (bfd_get_32 (input_bfd, hit_data) & howto->src_mask);
+#else
+ addend = rel->r_addend;
+#endif
+
+ switch (r_type)
+ {
+ case R_ARM_NONE:
+ return bfd_reloc_ok;
+
+ case R_ARM_PC24:
+ case R_ARM_ABS32:
+ case R_ARM_REL32:
+ /* When generating a shared object, these relocations are copied
+ into the output file to be resolved at run time. */
+
+ if (info->shared
+ && (r_type != R_ARM_PC24
+ || (h != NULL
+ && h->dynindx != -1
+ && (! info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ {
+ Elf_Internal_Rel outrel;
+ boolean skip, relocate;
+
+ if (sreloc == NULL)
+ {
+ const char * name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return bfd_reloc_notsupported;
+
+ BFD_ASSERT (strncmp (name, ".rel", 4) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 4) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ & elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ {
+ memset (&outrel, 0, sizeof outrel);
+ relocate = false;
+ }
+ else if (r_type == R_ARM_PC24)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ if ((input_section->flags & SEC_ALLOC) != 0)
+ relocate = false;
+ else
+ relocate = true;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_PC24);
+ }
+ else
+ {
+ if (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ {
+ relocate = true;
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ if ((input_section->flags & SEC_ALLOC) != 0)
+ relocate = false;
+ else
+ relocate = true;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_ABS32);
+ }
+ }
+
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ (((Elf32_External_Rel *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ /* If this reloc is against an external symbol, we do not want to
+ fiddle with the addend. Otherwise, we need to include the symbol
+ value so that it becomes an addend for the dynamic reloc. */
+ if (! relocate)
+ return bfd_reloc_ok;
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+ }
+ else switch (r_type)
+ {
+ case R_ARM_PC24:
+ /* Arm B/BL instruction */
+
+ /* Check for arm calling thumb function. */
+ if (sym_flags == STT_ARM_TFUNC)
+ {
+ elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
+ input_section, hit_data, sym_sec, rel->r_offset, addend, value);
+ return bfd_reloc_ok;
+ }
+
+ value = value + addend;
+ value -= (input_section->output_section->vma
+ + input_section->output_offset + 8);
+ value -= rel->r_offset;
+ value = value >> howto->rightshift;
+
+ value &= 0xffffff;
+ value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
+ break;
+
+ case R_ARM_ABS32:
+ value += addend;
+ if (sym_flags == STT_ARM_TFUNC)
+ value |= 1;
+ break;
+
+ case R_ARM_REL32:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value += addend;
+ break;
+ }
+
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_ABS8:
+ value += addend;
+ if ((long) value > 0x7f || (long) value < -0x80)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_ABS16:
+ value += addend;
+
+ if ((long) value > 0x7fff || (long) value < -0x8000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_ABS12:
+ /* Support ldr and str instruction for the arm */
+ /* Also thumb b (unconditional branch). ??? Really? */
+ value += addend;
+
+ if ((long) value > 0x7ff || (long) value < -0x800)
+ return bfd_reloc_overflow;
+
+ value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_THM_ABS5:
+ /* Support ldr and str instructions for the thumb. */
+#ifdef USE_REL
+ /* Need to refetch addend. */
+ addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
+ /* ??? Need to determine shift amount from operand size. */
+ addend >>= howto->rightshift;
+#endif
+ value += addend;
+
+ /* ??? Isn't value unsigned? */
+ if ((long) value > 0x1f || (long) value < -0x10)
+ return bfd_reloc_overflow;
+
+ /* ??? Value needs to be properly shifted into place first. */
+ value |= bfd_get_16 (input_bfd, hit_data) & 0xf83f;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_THM_PC22:
+ /* Thumb BL (branch long instruction). */
+ {
+ bfd_vma relocation;
+ boolean overflow = false;
+ bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data);
+ bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
+ bfd_vma src_mask = 0x007FFFFE;
+ bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+ bfd_vma add;
+ bfd_signed_vma signed_add;
+
+#ifdef USE_REL
+ /* Need to refetch the addend and squish the two 11 bit pieces
+ together. */
+ {
+ bfd_vma upper = bfd_get_16 (input_bfd, hit_data) & 0x7ff;
+ bfd_vma lower = bfd_get_16 (input_bfd, hit_data + 2) & 0x7ff;
+ upper = (upper ^ 0x400) - 0x400; /* sign extend */
+ addend = (upper << 12) | (lower << 1);
+ }
+#endif
+
+ /* If it's not a call to thumb, assume call to arm */
+ if (sym_flags != STT_ARM_TFUNC)
+ {
+ if (elf32_thumb_to_arm_stub
+ (info, sym_name, input_bfd, output_bfd, input_section,
+ hit_data, sym_sec, rel->r_offset, addend, value))
+ return bfd_reloc_ok;
+ else
+ return bfd_reloc_dangerous;
+ }
+
+ /* +4: pc is offset by 4 */
+ relocation = value + addend + 4;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ relocation -= rel->r_offset;
+
+ check = relocation >> howto->rightshift;
+
+ /* If this is a signed value, the rightshift just dropped
+ leading 1 bits (assuming twos complement). */
+ if ((bfd_signed_vma) relocation >= 0)
+ signed_check = check;
+ else
+ signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
+
+ add = ((upper_insn & 0x7ff) << 12) | ((lower_insn & 0x7ff) << 1);
+ /* sign extend */
+ signed_add = (add ^ 0x400000) - 0x400000;
+
+ /* Add the value from the object file. */
+ signed_check += signed_add;
+ relocation += signed_add;
+
+ /* Assumes two's complement. */
+ if (signed_check > reloc_signed_max
+ || signed_check < reloc_signed_min)
+ overflow = true;
+
+ /* Put RELOCATION back into the insn. */
+ upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
+ lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
+
+ /* Put the relocated value back in the object file: */
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+
+ return (overflow ? bfd_reloc_overflow : bfd_reloc_ok);
+ }
+ break;
+
+ case R_ARM_GNU_VTINHERIT:
+ case R_ARM_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ case R_ARM_COPY:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_GLOB_DAT:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_JUMP_SLOT:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_RELATIVE:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_GOTOFF:
+ /* Relocation is relative to the start of the
+ global offset table. */
+
+ BFD_ASSERT (sgot != NULL);
+ if (sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ /* Note that sgot->output_offset is not involved in this
+ calculation. We always want the start of .got. If we
+ define _GLOBAL_OFFSET_TABLE in a different way, as is
+ permitted by the ABI, we might have to change this
+ calculation. */
+
+ value -= sgot->output_section->vma;
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+
+ case R_ARM_GOTPC:
+ /* Use global offset table as symbol value. */
+
+ BFD_ASSERT (sgot != NULL);
+
+ if (sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ value = sgot->output_section->vma;
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+
+ case R_ARM_GOT32:
+ /* Relocation is to the entry for this symbol in the
+ global offset table. */
+ if (sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (!elf_hash_table (info)->dynamic_sections_created ||
+ (info->shared && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a -Bsymbolic link
+ and the symbol is defined locally. We must initialize this
+ entry in the global offset table. Since the offset must
+ always be a multiple of 4, we use the least significant bit
+ to record whether we have initialized it already.
+
+ When doing a dynamic link, we create a .rel.got relocation
+ entry to initialize the value. This is done in the
+ finish_dynamic_symbol routine. */
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, value, sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+
+ value = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+
+ BFD_ASSERT (local_got_offsets != NULL &&
+ local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use the
+ least significant bit to record whether we have already
+ generated the necessary reloc. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, value, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection * srelgot;
+ Elf_Internal_Rel outrel;
+
+ srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ (((Elf32_External_Rel *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ value = sgot->output_offset + off;
+ }
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+
+ case R_ARM_PLT32:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLT32 reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL)
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+
+ if (h->plt.offset == (bfd_vma) -1)
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+
+ BFD_ASSERT(splt != NULL);
+ if (splt == NULL)
+ return bfd_reloc_notsupported;
+
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ (bfd_vma) 0);
+
+ case R_ARM_SBREL32:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_AMP_VCALL9:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_RSBREL32:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_THM_RPC22:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_RREL32:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_RABS32:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_RPC24:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_RBASE:
+ return bfd_reloc_notsupported;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+
+/* Relocate an ARM ELF section. */
+static boolean
+elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * relocs;
+ Elf_Internal_Sym * local_syms;
+ asection ** local_sections;
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+ const char * name;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type * howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym * sym;
+ asection * sec;
+ struct elf_link_hash_entry * h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_ARM_GNU_VTENTRY
+ || r_type == R_ARM_GNU_VTINHERIT )
+ continue;
+
+ /* ScottB: range check r_type here. */
+
+ howto = elf32_arm_howto_table + r_type;
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+#ifdef USE_REL
+ {
+ bfd_vma val;
+ val = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ val += (sec->output_offset + sym->st_value) >> howto->rightshift;
+ bfd_put_32 (input_bfd, val, contents + rel->r_offset);
+ }
+#else
+ rel->r_addend += (sec->output_offset + sym->st_value)
+ >> howto->rightshift;
+#endif
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+
+ /* In these cases, we don't need the relocation value.
+ We check specially because in some obscure cases
+ sec->output_section will be NULL. */
+ switch (r_type)
+ {
+ case R_ARM_PC24:
+ case R_ARM_ABS32:
+ if (info->shared
+ && (
+ (!info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR == 0)
+ )
+ && ((input_section->flags & SEC_ALLOC) != 0)
+ )
+ relocation = 0;
+ break;
+
+ case R_ARM_GOTPC:
+ relocation = 0;
+ break;
+
+ case R_ARM_GOT32:
+ if (elf_hash_table(info)->dynamic_sections_created
+ && (!info->shared
+ || (!info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+ )
+ )
+ relocation = 0;
+ break;
+
+ case R_ARM_PLT32:
+ if (h->plt.offset != (bfd_vma)-1)
+ relocation = 0;
+ break;
+
+ default:
+ if (sec->output_section == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
+ bfd_get_filename (input_bfd), h->root.root.string,
+ bfd_get_section_name (input_bfd, input_section));
+ relocation = 0;
+ }
+ }
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (!((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel,
+ relocation, info, sec, name,
+ (h ? ELF_ST_TYPE (h->type) :
+ ELF_ST_TYPE (sym->st_info)));
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) 0;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (!((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_undefined:
+ if (!((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _ ("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ msg = _ ("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ msg = _ ("internal error: dangerous error");
+ goto common_error;
+
+ default:
+ msg = _ ("internal error: unknown error");
+ /* fall through */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, msg, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Function to keep ARM specific flags in the ELF header. */
+static boolean
+elf32_arm_set_private_flags (abfd, flags)
+ bfd *abfd;
+ flagword flags;
+{
+ if (elf_flags_init (abfd)
+ && elf_elfheader (abfd)->e_flags != flags)
+ {
+ if (flags & EF_INTERWORK)
+ _bfd_error_handler (_ ("\
+Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
+ bfd_get_filename (abfd));
+ else
+ _bfd_error_handler (_ ("\
+Warning: Clearing the interwork flag of %s due to outside request"),
+ bfd_get_filename (abfd));
+ }
+ else
+ {
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ }
+
+ return true;
+}
+
+/* Copy backend specific data from one object module to another */
+static boolean
+elf32_arm_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ flagword in_flags;
+ flagword out_flags;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (elf_flags_init (obfd) && in_flags != out_flags)
+ {
+ /* Cannot mix PIC and non-PIC code. */
+ if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
+ return false;
+
+ /* Cannot mix APCS26 and APCS32 code. */
+ if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
+ return false;
+
+ /* Cannot mix float APCS and non-float APCS code. */
+ if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
+ return false;
+
+ /* If the src and dest have different interworking flags
+ then turn off the interworking bit. */
+ if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
+ {
+ if (out_flags & EF_INTERWORK)
+ _bfd_error_handler (_ ("\
+Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"),
+ bfd_get_filename (obfd), bfd_get_filename (ibfd));
+
+ in_flags &= ~EF_INTERWORK;
+ }
+ }
+
+ elf_elfheader (obfd)->e_flags = in_flags;
+ elf_flags_init (obfd) = true;
+
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static boolean
+elf32_arm_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ flagword out_flags;
+ flagword in_flags;
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ /* Check if we have the same endianess */
+ if ( ibfd->xvec->byteorder != obfd->xvec->byteorder
+ && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
+ && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ (*_bfd_error_handler)
+ (_("%s: compiled for a %s endian system and target is %s endian"),
+ bfd_get_filename (ibfd),
+ bfd_big_endian (ibfd) ? "big" : "little",
+ bfd_big_endian (obfd) ? "big" : "little");
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ /* The input BFD must have had its flags initialised. */
+ /* The following seems bogus to me -- The flags are initialized in
+ the assembler but I don't think an elf_flags_init field is
+ written into the object */
+ /* BFD_ASSERT (elf_flags_init (ibfd)); */
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (!elf_flags_init (obfd))
+ {
+ /* If the input is the default architecture then do not
+ bother setting the flags for the output architecture,
+ instead allow future merges to do this. If no future
+ merges ever set these flags then they will retain their
+ unitialised values, which surprise surprise, correspond
+ to the default values. */
+ if (bfd_get_arch_info (ibfd)->the_default)
+ return true;
+
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = in_flags;
+
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
+ && bfd_get_arch_info (obfd)->the_default)
+ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
+
+ return true;
+ }
+
+ /* Check flag compatibility. */
+ if (in_flags == out_flags)
+ return true;
+
+ /* Complain about various flag mismatches. */
+
+ if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
+ _bfd_error_handler (_ ("\
+Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
+ bfd_get_filename (ibfd),
+ in_flags & EF_APCS_26 ? 26 : 32,
+ bfd_get_filename (obfd),
+ out_flags & EF_APCS_26 ? 26 : 32);
+
+ if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
+ _bfd_error_handler (_ ("\
+Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
+ bfd_get_filename (ibfd),
+ in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
+ bfd_get_filename (obfd),
+ out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
+
+ if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
+ _bfd_error_handler (_ ("\
+Error: %s is compiled as position %s code, whereas %s is not"),
+ bfd_get_filename (ibfd),
+ in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
+ bfd_get_filename (obfd));
+
+ /* Interworking mismatch is only a warning. */
+ if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
+ {
+ _bfd_error_handler (_ ("\
+Warning: %s %s interworking, whereas %s %s"),
+ bfd_get_filename (ibfd),
+ in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
+ bfd_get_filename (obfd),
+ out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
+ return true;
+ }
+
+ return false;
+}
+
+/* Display the flags field */
+static boolean
+elf32_arm_print_private_bfd_data (abfd, ptr)
+ bfd *abfd;
+ PTR ptr;
+{
+ FILE *file = (FILE *) ptr;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
+
+ /* xgettext:c-format */
+ fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
+
+ if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
+ fprintf (file, _ (" [interworking enabled]"));
+ else
+ fprintf (file, _ (" [interworking not enabled]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
+ fprintf (file, _ (" [APCS-26]"));
+ else
+ fprintf (file, _ (" [APCS-32]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
+ fprintf (file, _ (" [floats passed in float registers]"));
+ else
+ fprintf (file, _ (" [floats passed in integer registers]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_PIC)
+ fprintf (file, _ (" [position independent]"));
+ else
+ fprintf (file, _ (" [absolute position]"));
+
+ fputc ('\n', file);
+
+ return true;
+}
+
+static int
+elf32_arm_get_symbol_type (elf_sym, type)
+ Elf_Internal_Sym * elf_sym;
+ int type;
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_ARM_TFUNC)
+ return ELF_ST_TYPE (elf_sym->st_info);
+ else
+ return type;
+}
+
+static asection *
+elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_ARM_GNU_VTINHERIT:
+ case R_ARM_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+ return NULL;
+}
+
+static boolean
+elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ /* we don't use got and plt entries for armelf */
+ return true;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+elf32_arm_check_relocs (abfd, info, sec, relocs)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ asection * sec;
+ const Elf_Internal_Rela * relocs;
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** sym_hashes_end;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+ bfd * dynobj;
+ asection * sgot, *srelgot, *sreloc;
+ bfd_vma * local_got_offsets;
+
+ if (info->relocateable)
+ return true;
+
+ sgot = srelgot = sreloc = NULL;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ local_got_offsets = elf_local_got_offsets (abfd);
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_ARM_GOT32:
+ case R_ARM_GOTOFF:
+ case R_ARM_GOTPC:
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_ARM_GOT32:
+ /* This symbol requires a global offset table entry. */
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ /* Get the got relocation section if necessary. */
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
+
+ /* If no got relocation section, make one and initialize. */
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rel.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.offset != (bfd_vma) -1)
+ /* We have already allocated space in the .got. */
+ break;
+
+ h->got.offset = sgot->_raw_size;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+
+ srelgot->_raw_size += sizeof (Elf32_External_Rel);
+ }
+ else
+ {
+ /* This is a global offset table entry for a local
+ symbol. */
+ if (local_got_offsets == NULL)
+ {
+ size_t size;
+ register unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+ if (local_got_offsets == NULL)
+ return false;
+ elf_local_got_offsets (abfd) = local_got_offsets;
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_got_offsets[i] = (bfd_vma) -1;
+ }
+
+ if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+ /* We have already allocated space in the .got. */
+ break;
+
+ local_got_offsets[r_symndx] = sgot->_raw_size;
+
+ if (info->shared)
+ /* If we are generating a shared object, we need to
+ output a R_ARM_RELATIVE reloc so that the dynamic
+ linker can adjust this GOT entry. */
+ srelgot->_raw_size += sizeof (Elf32_External_Rel);
+ }
+
+ sgot->_raw_size += 4;
+ break;
+
+ case R_ARM_PLT32:
+ /* This symbol requires a procedure linkage table entry. We
+ actually build the entry in adjust_dynamic_symbol,
+ because this might be a case of linking PIC code which is
+ never referenced by a dynamic object, in which case we
+ don't need to generate a procedure linkage table entry
+ after all. */
+
+ /* If this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (h == NULL)
+ continue;
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ break;
+
+ case R_ARM_ABS32:
+ case R_ARM_REL32:
+ case R_ARM_PC24:
+ /* If we are creating a shared library, and this is a reloc
+ against a global symbol, or a non PC relative reloc
+ against a local symbol, then we need to copy the reloc
+ into the shared library. However, if we are linking with
+ -Bsymbolic, we do not need to copy a reloc against a
+ global symbol which is defined in an object we are
+ including in the link (i.e., DEF_REGULAR is set). At
+ this point we have not seen all the input files, so it is
+ possible that DEF_REGULAR is not set now but will be set
+ later (it is never cleared). We account for that
+ possibility below by storing information in the
+ pcrel_relocs_copied field of the hash table entry. */
+ if (info->shared
+ && (ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
+ || (h != NULL
+ && (! info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file. We create a reloc
+ section in dynobj and make room for this reloc. */
+ if (sreloc == NULL)
+ {
+ const char * name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rel", 4) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 4) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ flagword flags;
+
+ sreloc = bfd_make_section (dynobj, name);
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc, flags)
+ || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+ return false;
+ }
+ }
+
+ sreloc->_raw_size += sizeof (Elf32_External_Rel);
+ /* If we are linking with -Bsymbolic, and this is a
+ global symbol, we count the number of PC relative
+ relocations we have entered for this symbol, so that
+ we can discard them again if the symbol is later
+ defined by a regular object. Note that this function
+ is only called if we are using an elf_i386 linker
+ hash table, which means that h is really a pointer to
+ an elf_i386_link_hash_entry. */
+ if (h != NULL && info->symbolic
+ && ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)
+ {
+ struct elf32_arm_link_hash_entry * eh;
+ struct elf32_arm_pcrel_relocs_copied * p;
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
+ if (p->section == sreloc)
+ break;
+
+ if (p == NULL)
+ {
+ p = ((struct elf32_arm_pcrel_relocs_copied *)
+ bfd_alloc (dynobj, sizeof * p));
+
+ if (p == NULL)
+ return false;
+ p->next = eh->pcrel_relocs_copied;
+ eh->pcrel_relocs_copied = p;
+ p->section = sreloc;
+ p->count = 0;
+ }
+
+ ++p->count;
+ }
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_ARM_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_ARM_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+
+/* Find the nearest line to a particular section and offset, for error
+ reporting. This code is a duplicate of the code in elf.c, except
+ that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
+
+static boolean
+elf32_arm_find_nearest_line
+ (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
+ bfd * abfd;
+ asection * section;
+ asymbol ** symbols;
+ bfd_vma offset;
+ CONST char ** filename_ptr;
+ CONST char ** functionname_ptr;
+ unsigned int * line_ptr;
+{
+ boolean found;
+ const char * filename;
+ asymbol * func;
+ bfd_vma low_func;
+ asymbol ** p;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
+ return true;
+
+ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+ &found, filename_ptr,
+ functionname_ptr, line_ptr,
+ &elf_tdata (abfd)->line_info))
+ return false;
+
+ if (found)
+ return true;
+
+ if (symbols == NULL)
+ return false;
+
+ filename = NULL;
+ func = NULL;
+ low_func = 0;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ elf_symbol_type *q;
+
+ q = (elf_symbol_type *) *p;
+
+ if (bfd_get_section (&q->symbol) != section)
+ continue;
+
+ switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
+ {
+ default:
+ break;
+ case STT_FILE:
+ filename = bfd_asymbol_name (&q->symbol);
+ break;
+ case STT_NOTYPE:
+ case STT_FUNC:
+ case STT_ARM_TFUNC:
+ if (q->symbol.section == section
+ && q->symbol.value >= low_func
+ && q->symbol.value <= offset)
+ {
+ func = (asymbol *) q;
+ low_func = q->symbol.value;
+ }
+ break;
+ }
+ }
+
+ if (func == NULL)
+ return false;
+
+ *filename_ptr = filename;
+ *functionname_ptr = bfd_asymbol_name (func);
+ *line_ptr = 0;
+
+ return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+elf32_arm_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info * info;
+ struct elf_link_hash_entry * h;
+{
+ bfd * dynobj;
+ asection * s;
+ unsigned int power_of_two;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later,
+ when we know the address of the .got section. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+ {
+ /* This case can occur if we saw a PLT32 reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object. In such a case, we don't actually need to build
+ a procedure linkage table, and we can just do a PC32
+ reloc instead. */
+ BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ return true;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->_raw_size == 0)
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+ }
+
+ h->plt.offset = s->_raw_size;
+
+ /* Make room for this entry. */
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .got.plt section, which
+ will be placed in the .got section by the linker script. */
+
+ s = bfd_get_section_by_name (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+
+ s = bfd_get_section_by_name (dynobj, ".rel.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += sizeof (Elf32_External_Rel);
+
+ return true;
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (info->shared)
+ return true;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. We need to remember the offset into the
+ .rel.bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_section_by_name (dynobj, ".rel.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf32_External_Rel);
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ }
+
+ /* We need to figure out the alignment required for this symbol. I
+ have no idea how ELF linkers handle this. */
+ power_of_two = bfd_log2 (h->size);
+ if (power_of_two > 3)
+ power_of_two = 3;
+
+ /* Apply the required alignment. */
+ s->_raw_size = BFD_ALIGN (s->_raw_size,
+ (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ {
+ if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+ return false;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->_raw_size += h->size;
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+elf32_arm_size_dynamic_sections (output_bfd, info)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+{
+ bfd * dynobj;
+ asection * s;
+ boolean plt;
+ boolean relocs;
+ boolean reltext;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (! info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+ else
+ {
+ /* We may have created entries in the .rel.got section.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rel.got,
+ which will cause it to get stripped from the output file
+ below. */
+ s = bfd_get_section_by_name (dynobj, ".rel.got");
+ if (s != NULL)
+ s->_raw_size = 0;
+ }
+
+ /* If this is a -Bsymbolic shared link, then we need to discard all
+ PC relative relocs against symbols defined in a regular object.
+ We allocated space for them in the check_relocs routine, but we
+ will not fill them in in the relocate_section routine. */
+ if (info->shared && info->symbolic)
+ elf32_arm_link_hash_traverse (elf32_arm_hash_table (info),
+ elf32_arm_discard_copies,
+ (PTR) NULL);
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ plt = false;
+ relocs = false;
+ reltext = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char * name;
+ boolean strip;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ strip = false;
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ strip = true;
+ }
+ else
+ {
+ /* Remember whether there is a PLT. */
+ plt = true;
+ }
+ }
+ else if (strncmp (name, ".rel", 4) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rel.bss and
+ .rel.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ strip = true;
+ }
+ else
+ {
+ asection * target;
+
+ /* Remember whether there are any reloc sections other
+ than .rel.plt. */
+ if (strcmp (name, ".rel.plt") != 0)
+ {
+ const char *outname;
+
+ relocs = true;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL
+ entry. The entries in the .rel.plt section
+ really apply to the .got section, which we
+ created ourselves and so know is not readonly. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 4);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ reltext = true;
+ }
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strncmp (name, ".got", 4) != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ asection ** spp;
+
+ for (spp = &s->output_section->owner->sections;
+ *spp != s->output_section;
+ spp = &(*spp)->next)
+ ;
+ *spp = s->output_section->next;
+ --s->output_section->owner->section_count;
+
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf32_arm_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (! info->shared)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (plt)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ return false;
+ }
+
+ if (relocs)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT,
+ sizeof (Elf32_External_Rel)))
+ return false;
+ }
+
+ if (reltext)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* This function is called via elf32_arm_link_hash_traverse if we are
+ creating a shared object with -Bsymbolic. It discards the space
+ allocated to copy PC relative relocs against symbols which are
+ defined in regular objects. We allocated space for them in the
+ check_relocs routine, but we won't fill them in in the
+ relocate_section routine. */
+
+static boolean
+elf32_arm_discard_copies (h, ignore)
+ struct elf32_arm_link_hash_entry * h;
+ PTR ignore;
+{
+ struct elf32_arm_pcrel_relocs_copied * s;
+
+ /* We only discard relocs for symbols defined in a regular object. */
+ if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ return true;
+
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ s->section->_raw_size -= s->count * sizeof (Elf32_External_Rel);
+
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+elf32_arm_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+ struct elf_link_hash_entry * h;
+ Elf_Internal_Sym * sym;
+{
+ bfd * dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection * splt;
+ asection * sgot;
+ asection * srel;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rel rel;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ srel = bfd_get_section_by_name (dynobj, ".rel.plt");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+ /* Get the index in the procedure linkage table which
+ corresponds to this symbol. This is the index of this symbol
+ in all the symbols for which we are making plt entries. The
+ first entry in the procedure linkage table is reserved. */
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
+
+ /* Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is 4 bytes.
+ The first three are reserved. */
+ got_offset = (plt_index + 3) * 4;
+
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (splt->contents + h->plt.offset,
+ elf32_arm_plt_entry,
+ PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset
+ - splt->output_section->vma
+ - splt->output_offset
+ - h->plt.offset - 12),
+ splt->contents + h->plt.offset + 12);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset),
+ sgot->contents + got_offset);
+
+ /* Fill in the entry in the .rel.plt section. */
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_JUMP_SLOT);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ ((Elf32_External_Rel *) srel->contents
+ + plt_index));
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection * sgot;
+ asection * srel;
+ Elf_Internal_Rel rel;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srel = bfd_get_section_by_name (dynobj, ".rel.got");
+ BFD_ASSERT (sgot != NULL && srel != NULL);
+
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ 1));
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. The entry in
+ the global offset table will already have been initialized in
+ the relocate_section function. */
+ if (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
+ }
+
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ ((Elf32_External_Rel *) srel->contents
+ + srel->reloc_count));
+ ++srel->reloc_count;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ {
+ asection * s;
+ Elf_Internal_Rel rel;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak));
+
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rel.bss");
+ BFD_ASSERT (s != NULL);
+
+ rel.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_COPY);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ ((Elf32_External_Rel *) s->contents
+ + s->reloc_count));
+ ++s->reloc_count;
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+elf32_arm_finish_dynamic_sections (output_bfd, info)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+{
+ bfd * dynobj;
+ asection * sgot;
+ asection * sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char * name;
+ asection * s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ name = ".got";
+ goto get_vma;
+ case DT_JMPREL:
+ name = ".rel.plt";
+ get_vma:
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ s = bfd_get_section_by_name (output_bfd, ".rel.plt");
+ BFD_ASSERT (s != NULL);
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
+ else
+ dyn.d_un.d_val = s->_raw_size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELSZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_REL). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. Therefore, we override the DT_RELSZ entry
+ here to make it not include the JMPREL relocs. Since
+ the linker script arranges for .rel.plt to follow all
+ other relocation sections, we don't have to worry
+ about changing the DT_REL entry. */
+ s = bfd_get_section_by_name (output_bfd, ".rel.plt");
+ if (s != NULL)
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val -= s->_cooked_size;
+ else
+ dyn.d_un.d_val -= s->_raw_size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->_raw_size > 0)
+ memcpy (splt->contents, elf32_arm_plt0_entry, PLT_ENTRY_SIZE);
+
+ /* UnixWare sets the entsize of .plt to 4, although that doesn't
+ really seem like the right value. */
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->_raw_size > 0)
+ {
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgot->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ return true;
+}
+
+#define ELF_ARCH bfd_arch_arm
+#define ELF_MACHINE_CODE EM_ARM
+#define ELF_MAXPAGE_SIZE 0x8000
+
+
+#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data elf32_arm_print_private_bfd_data
+#define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
+#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
+#define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
+
+#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
+#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
+#define elf_backend_check_relocs elf32_arm_check_relocs
+#define elf_backend_relocate_section elf32_arm_relocate_section
+#define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol
+#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf32_arm_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections elf32_arm_finish_dynamic_sections
+#define elf_backend_size_dynamic_sections elf32_arm_size_dynamic_sections
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_want_plt_sym 0
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c
new file mode 100644
index 00000000000..be80bae2e9b
--- /dev/null
+++ b/bfd/elf32-d10v.c
@@ -0,0 +1,534 @@
+/* D10V-specific support for 32-bit ELF
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Martin Hunt (hunt@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+/* #include "elf/d10v.h" */
+
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void d10v_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+
+
+/* Use REL instead of RELA to save space */
+#define USE_REL
+
+enum reloc_type
+{
+ R_D10V_NONE = 0,
+ R_D10V_10_PCREL_R,
+ R_D10V_10_PCREL_L,
+ R_D10V_16,
+ R_D10V_18,
+ R_D10V_18_PCREL,
+ R_D10V_32,
+ R_D10V_GNU_VTINHERIT,
+ R_D10V_GNU_VTENTRY,
+ R_D10V_max
+};
+
+static reloc_howto_type elf_d10v_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_D10V_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An PC Relative 10-bit relocation, shifted by 2 */
+ /* right container */
+ HOWTO (R_D10V_10_PCREL_R, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_10_PCREL_R", /* name */
+ false, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* An PC Relative 10-bit relocation, shifted by 2 */
+ /* left container */
+ HOWTO (R_D10V_10_PCREL_L, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ true, /* pc_relative */
+ 15, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_10_PCREL_L", /* name */
+ false, /* partial_inplace */
+ 0x07f8000, /* src_mask */
+ 0x07f8000, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation */
+ HOWTO (R_D10V_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An 18 bit absolute relocation, right shifted 2 */
+ HOWTO (R_D10V_18, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_18", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 18 bit relocation, right shifted by 2 */
+ HOWTO (R_D10V_18_PCREL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_18_PCREL", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation */
+ HOWTO (R_D10V_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D10V_32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_D10V_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_D10V_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_D10V_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_D10V_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to D10V ELF reloc types. */
+
+struct d10v_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+ static const struct d10v_reloc_map d10v_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_D10V_NONE, },
+ { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
+ { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
+ { BFD_RELOC_16, R_D10V_16 },
+ { BFD_RELOC_D10V_18, R_D10V_18 },
+ { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
+ { BFD_RELOC_32, R_D10V_32 },
+ { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map);
+ i++)
+ {
+ if (d10v_reloc_map[i].bfd_reloc_val == code)
+ return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an D10V ELF reloc. */
+
+static void
+d10v_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_D10V_max);
+ cache_ptr->howto = &elf_d10v_howto_table[r_type];
+}
+
+static asection *
+elf32_d10v_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_D10V_GNU_VTINHERIT:
+ case R_D10V_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+ return NULL;
+}
+
+static boolean
+elf32_d10v_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ /* we don't use got and plt entries for d10v */
+ return true;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+elf32_d10v_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_D10V_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_D10V_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Relocate a D10V ELF section. */
+static boolean
+elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel, *relend;
+ const char *name;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_D10V_GNU_VTENTRY
+ || r_type == R_D10V_GNU_VTINHERIT )
+ continue;
+
+ howto = elf_d10v_howto_table + r_type;
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (!((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) 0;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (!((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_undefined:
+ if (!((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _ ("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ msg = _ ("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ msg = _ ("internal error: dangerous error");
+ goto common_error;
+
+ default:
+ msg = _ ("internal error: unknown error");
+ /* fall through */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, msg, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+#define ELF_ARCH bfd_arch_d10v
+#define ELF_MACHINE_CODE EM_CYGNUS_D10V
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM bfd_elf32_d10v_vec
+#define TARGET_BIG_NAME "elf32-d10v"
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel d10v_info_to_howto_rel
+#define elf_backend_object_p 0
+#define elf_backend_final_write_processing 0
+#define elf_backend_gc_mark_hook elf32_d10v_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_d10v_gc_sweep_hook
+#define elf_backend_check_relocs elf32_d10v_check_relocs
+#define elf_backend_relocate_section elf32_d10v_relocate_section
+#define elf_backend_can_gc_sections 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-d30v.c b/bfd/elf32-d30v.c
new file mode 100644
index 00000000000..0b0e9e9e6cd
--- /dev/null
+++ b/bfd/elf32-d30v.c
@@ -0,0 +1,601 @@
+/* D30V-specific support for 32-bit ELF
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Martin Hunt (hunt@cygnus.com).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void d30v_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static void d30v_info_to_howto_rela
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static bfd_reloc_status_type bfd_elf_d30v_reloc PARAMS ((
+ bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ PTR data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message));
+static bfd_reloc_status_type bfd_elf_d30v_reloc_21 PARAMS ((
+ bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ PTR data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message));
+
+enum reloc_type
+{
+ R_D30V_NONE = 0,
+ R_D30V_6,
+ R_D30V_9_PCREL,
+ R_D30V_9_PCREL_R,
+ R_D30V_15,
+ R_D30V_15_PCREL,
+ R_D30V_15_PCREL_R,
+ R_D30V_21,
+ R_D30V_21_PCREL,
+ R_D30V_21_PCREL_R,
+ R_D30V_32,
+ R_D30V_32_PCREL,
+ R_D30V_32_NORMAL,
+ R_D30V_max
+};
+
+static reloc_howto_type elf_d30v_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_D30V_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D30V_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 6 bit absolute relocation */
+ HOWTO (R_D30V_6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D30V_6", /* name */
+ false, /* partial_inplace */
+ 0x3f, /* src_mask */
+ 0x3f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 9 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_9_PCREL, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc_21, /* special_function */
+ "R_D30V_9_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x3f, /* src_mask */
+ 0x3f, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 9 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_9_PCREL_R, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc_21, /* special_function */
+ "R_D30V_9_PCREL_R", /* name */
+ false, /* partial_inplace */
+ 0x3f, /* src_mask */
+ 0x3f, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* An absolute 15 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_15, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D30V_15", /* name */
+ false, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 15 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_15_PCREL, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc_21, /* special_function */
+ "R_D30V_15_PCREL", /* name */
+ false, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 15 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_15_PCREL_R, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc_21, /* special_function */
+ "R_D30V_15_PCREL_R", /* name */
+ false, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* An absolute 21 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_21, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D30V_21", /* name */
+ false, /* partial_inplace */
+ 0x3ffff, /* src_mask */
+ 0x3ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 21 bit relocation, right shifted by 3 */
+ HOWTO (R_D30V_21_PCREL, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc_21, /* special_function */
+ "R_D30V_21_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x3ffff, /* src_mask */
+ 0x3ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 21 bit relocation, right shifted by 3, in the Right container */
+ HOWTO (R_D30V_21_PCREL_R, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc_21, /* special_function */
+ "R_D30V_21_PCREL_R", /* name */
+ false, /* partial_inplace */
+ 0x3ffff, /* src_mask */
+ 0x3ffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A D30V 32 bit absolute relocation */
+ HOWTO (R_D30V_32, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_d30v_reloc, /* special_function */
+ "R_D30V_32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 32 bit relocation */
+ HOWTO (R_D30V_32_PCREL, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_d30v_reloc, /* special_function */
+ "R_D30V_32_PCREL", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A regular 32 bit absolute relocation */
+ HOWTO (R_D30V_32_NORMAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_D30V_32_NORMAL", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+#define MIN32 (long long)0xffffffff80000000LL
+#define MAX32 0x7fffffffLL
+
+static bfd_reloc_status_type
+bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ long long relocation;
+ bfd_vma in1, in2, num;
+ bfd_vma tmp_addr = 0;
+ bfd_reloc_status_type r;
+ asection *reloc_target_output_section;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ int make_absolute = 0;
+
+ r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+ if (r != bfd_reloc_continue)
+ return r;
+
+ /* a hacked-up version of bfd_perform_reloc() follows */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && output_bfd == (bfd *) NULL)
+ flag = bfd_reloc_undefined;
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (output_bfd)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ if (howto->pc_relative == true)
+ {
+ tmp_addr = input_section->output_section->vma + input_section->output_offset
+ + reloc_entry->address;
+ relocation -= tmp_addr;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Modify the reloc
+ inplace to reflect what we now know. */
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return flag;
+ }
+ else
+ reloc_entry->addend = 0;
+
+ in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ in2 = bfd_get_32 (abfd, (bfd_byte *) data + addr + 4);
+
+ /* extract the addend */
+ num = ((in2 & 0x3FFFF)
+ | ((in2 & 0xFF00000) >> 2)
+ | ((in1 & 0x3F) << 26));
+ in1 &= 0xFFFFFFC0;
+ in2 = 0x80000000;
+
+ relocation += num;
+
+ if (howto->pc_relative == true && howto->bitsize == 32)
+ {
+ /* the D30V has a PC that doesn't wrap and PC-relative jumps */
+ /* are signed, so a PC-relative jump can'tbe more than +/- 2^31 byrtes */
+ /* if one exceeds this, change it to an absolute jump */
+ if (relocation > MAX32)
+ {
+ relocation = (relocation + tmp_addr) & 0xffffffff;
+ make_absolute = 1;
+ }
+ else if (relocation < MIN32)
+ {
+ relocation = (relocation + tmp_addr) & 0xffffffff;
+ make_absolute = 1;
+ }
+ }
+
+ in1 |= (relocation >> 26) & 0x3F; /* top 6 bits */
+ in2 |= ((relocation & 0x03FC0000) << 2); /* next 8 bits */
+ in2 |= relocation & 0x0003FFFF; /* bottom 18 bits */
+
+ /* change a PC-relative instruction to its absolute equivalent */
+ /* with this simple hack */
+ if (make_absolute)
+ in1 |= 0x00100000;
+
+ bfd_put_32 (abfd, in1, (bfd_byte *) data + addr);
+ bfd_put_32 (abfd, in2, (bfd_byte *) data + addr + 4);
+
+ return flag;
+}
+
+
+static bfd_reloc_status_type
+bfd_elf_d30v_reloc_21 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_vma in1, num;
+ bfd_reloc_status_type r;
+ asection *reloc_target_output_section;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ int mask, max;
+
+ r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+ if (r != bfd_reloc_continue)
+ return r;
+
+ /* a hacked-up version of bfd_perform_reloc() follows */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && output_bfd == (bfd *) NULL)
+ flag = bfd_reloc_undefined;
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (output_bfd)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ if (howto->pc_relative == true)
+ {
+ relocation -= input_section->output_section->vma + input_section->output_offset;
+ if (howto->pcrel_offset == true)
+ relocation -= reloc_entry->address;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Modify the reloc
+ inplace to reflect what we now know. */
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return flag;
+ }
+ else
+ reloc_entry->addend = 0;
+
+ in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+
+ mask = (1 << howto->bitsize) - 1;
+ if (howto->bitsize == 6)
+ mask <<= 12;
+ max = (1 << (howto->bitsize + 2)) - 1;
+
+ /* extract the addend */
+ num = in1 & mask; /* 18 bits */
+ if (howto->bitsize == 6)
+ num >>= 12;
+ num <<= 3; /* shift left 3 */
+ in1 &= ~mask; /* mask out addend */
+
+ relocation += num;
+ if (howto->type == R_D30V_21_PCREL_R || howto->type == R_D30V_15_PCREL_R ||
+ howto->type == R_D30V_9_PCREL_R )
+ {
+ relocation += 4;
+ }
+
+ if ((int)relocation < 0 )
+ {
+ if (~(int)relocation > max)
+ flag = bfd_reloc_overflow;
+ }
+ else
+ {
+ if ((int)relocation > max)
+ flag = bfd_reloc_overflow;
+ }
+ relocation >>= 3;
+ if (howto->bitsize == 6)
+ in1 |= ((relocation & (mask >> 12)) << 12);
+ else
+ in1 |= relocation & mask;
+
+ bfd_put_32 (abfd, in1, (bfd_byte *) data + addr);
+
+ return flag;
+}
+
+/* Map BFD reloc types to D30V ELF reloc types. */
+
+struct d30v_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+
+static const struct d30v_reloc_map d30v_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_D30V_NONE, },
+ { BFD_RELOC_D30V_6, R_D30V_6 },
+ { BFD_RELOC_D30V_9_PCREL, R_D30V_9_PCREL },
+ { BFD_RELOC_D30V_9_PCREL_R, R_D30V_9_PCREL_R },
+ { BFD_RELOC_D30V_15, R_D30V_15 },
+ { BFD_RELOC_D30V_15_PCREL, R_D30V_15_PCREL },
+ { BFD_RELOC_D30V_15_PCREL_R, R_D30V_15_PCREL_R },
+ { BFD_RELOC_D30V_21, R_D30V_21 },
+ { BFD_RELOC_D30V_21_PCREL, R_D30V_21_PCREL },
+ { BFD_RELOC_D30V_21_PCREL_R, R_D30V_21_PCREL_R },
+ { BFD_RELOC_D30V_32, R_D30V_32 },
+ { BFD_RELOC_D30V_32_PCREL, R_D30V_32_PCREL },
+ { BFD_RELOC_32, R_D30V_32_NORMAL },
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (d30v_reloc_map) / sizeof (struct d30v_reloc_map);
+ i++)
+ {
+ if (d30v_reloc_map[i].bfd_reloc_val == code)
+ return &elf_d30v_howto_table[d30v_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an D30V ELF reloc (type REL). */
+
+static void
+d30v_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_D30V_max);
+ cache_ptr->howto = &elf_d30v_howto_table[r_type];
+}
+
+/* Set the howto pointer for an D30V ELF reloc (type RELA). */
+
+static void
+d30v_info_to_howto_rela (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_D30V_max);
+ cache_ptr->howto = &elf_d30v_howto_table[r_type];
+}
+
+#define ELF_ARCH bfd_arch_d30v
+#define ELF_MACHINE_CODE EM_CYGNUS_D30V
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM bfd_elf32_d30v_vec
+#define TARGET_BIG_NAME "elf32-d30v"
+
+#define elf_info_to_howto d30v_info_to_howto_rela
+#define elf_info_to_howto_rel d30v_info_to_howto_rel
+#define elf_backend_object_p 0
+#define elf_backend_final_write_processing 0
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c
new file mode 100644
index 00000000000..7c8725f5562
--- /dev/null
+++ b/bfd/elf32-fr30.c
@@ -0,0 +1,811 @@
+/* FR30-specific support for 32-bit ELF.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/fr30.h"
+
+/* Forward declarations. */
+static bfd_reloc_status_type fr30_elf_i20_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type fr30_elf_i32_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type * fr30_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void fr30_info_to_howto_rela
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static boolean fr30_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static bfd_reloc_status_type fr30_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
+static boolean fr30_elf_gc_sweep_hook
+ PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
+static asection * fr30_elf_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
+
+static reloc_howto_type fr30_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_FR30_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FR30_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_FR30_8, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FR30_8", /* name */
+ true, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x0ff0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 20 bit absolute relocation. */
+ HOWTO (R_FR30_20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ fr30_elf_i20_reloc, /* special_function */
+ "R_FR30_20", /* name */
+ true, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00f0ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_FR30_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FR30_32", /* name */
+ true, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit into 48 bits absolute relocation. */
+ HOWTO (R_FR30_48, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ fr30_elf_i32_reloc, /* special_function */
+ "R_FR30_48", /* name */
+ true, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 6 bit absolute relocation. */
+ HOWTO (R_FR30_6_IN_4, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ false, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FR30_6_IN_4", /* name */
+ true, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x00f0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_FR30_8_IN_8, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc,/* special_function */
+ "R_FR30_8_IN_8", /* name */
+ true, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x0ff0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 9 bit absolute relocation. */
+ HOWTO (R_FR30_9_IN_8, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ false, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc,/* special_function */
+ "R_FR30_9_IN_8", /* name */
+ true, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x0ff0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 10 bit absolute relocation. */
+ HOWTO (R_FR30_10_IN_8, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ false, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc,/* special_function */
+ "R_FR30_10_IN_8", /* name */
+ true, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x0ff0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A PC relative 9 bit relocation, right shifted by 1. */
+ HOWTO (R_FR30_9_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FR30_9_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x00ff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A PC relative 12 bit relocation, right shifted by 1. */
+ HOWTO (R_FR30_12_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FR30_12_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x07ff, /* dst_mask */
+ false), /* pcrel_offset */
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_FR30_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_FR30_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_FR30_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_FR30_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+/* Utility to actually perform an R_FR30_20 reloc. */
+
+static bfd_reloc_status_type
+fr30_elf_i20_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd * abfd;
+ arelent * reloc_entry;
+ asymbol * symbol;
+ PTR data;
+ asection * input_section;
+ bfd * output_bfd;
+ char ** error_message;
+{
+ bfd_vma relocation;
+ unsigned long x;
+
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ relocation =
+ symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset
+ + reloc_entry->addend;
+
+ if (relocation > ((1U << 20) - 1))
+ return bfd_reloc_overflow;
+
+ x = bfd_get_32 (abfd, data + reloc_entry->address);
+ x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
+ bfd_put_32 (abfd, x, data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+
+/* Utility to actually perform a R_FR30_48 reloc. */
+
+static bfd_reloc_status_type
+fr30_elf_i32_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd * abfd;
+ arelent * reloc_entry;
+ asymbol * symbol;
+ PTR data;
+ asection * input_section;
+ bfd * output_bfd;
+ char ** error_message;
+{
+ bfd_vma relocation;
+
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_ok;
+
+ relocation =
+ symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset
+ + reloc_entry->addend;
+
+ bfd_put_32 (abfd, relocation, data + reloc_entry->address + 2);
+
+ return bfd_reloc_ok;
+}
+
+/* Map BFD reloc types to FR30 ELF reloc types. */
+
+struct fr30_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int fr30_reloc_val;
+};
+
+static const struct fr30_reloc_map fr30_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_FR30_NONE },
+ { BFD_RELOC_8, R_FR30_8 },
+ { BFD_RELOC_FR30_20, R_FR30_20 },
+ { BFD_RELOC_32, R_FR30_32 },
+ { BFD_RELOC_FR30_48, R_FR30_48 },
+ { BFD_RELOC_FR30_6_IN_4, R_FR30_6_IN_4 },
+ { BFD_RELOC_FR30_8_IN_8, R_FR30_8_IN_8 },
+ { BFD_RELOC_FR30_9_IN_8, R_FR30_9_IN_8 },
+ { BFD_RELOC_FR30_10_IN_8, R_FR30_10_IN_8 },
+ { BFD_RELOC_FR30_9_PCREL, R_FR30_9_PCREL },
+ { BFD_RELOC_FR30_12_PCREL, R_FR30_12_PCREL },
+ { BFD_RELOC_VTABLE_INHERIT, R_FR30_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_FR30_GNU_VTENTRY },
+};
+
+static reloc_howto_type *
+fr30_reloc_type_lookup (abfd, code)
+ bfd * abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = sizeof (fr30_reloc_map) / sizeof (fr30_reloc_map[0]);
+ --i;)
+ if (fr30_reloc_map [i].bfd_reloc_val == code)
+ return & fr30_elf_howto_table [fr30_reloc_map[i].fr30_reloc_val];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an FR30 ELF reloc. */
+
+static void
+fr30_info_to_howto_rela (abfd, cache_ptr, dst)
+ bfd * abfd;
+ arelent * cache_ptr;
+ Elf32_Internal_Rela * dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_FR30_max);
+ cache_ptr->howto = & fr30_elf_howto_table [r_type];
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines, but a few relocs, we have to do them ourselves. */
+
+static bfd_reloc_status_type
+fr30_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
+ reloc_howto_type * howto;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * rel;
+ bfd_vma relocation;
+{
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ bfd_vma x;
+ bfd_signed_vma srel;
+
+ switch (howto->type)
+ {
+ case R_FR30_20:
+ contents += rel->r_offset;
+ relocation += rel->r_addend;
+
+ if (relocation > ((1 << 20) - 1))
+ return bfd_reloc_overflow;
+
+ x = bfd_get_32 (input_bfd, contents);
+ x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
+ bfd_put_32 (input_bfd, x, contents);
+ break;
+
+ case R_FR30_48:
+ contents += rel->r_offset + 2;
+ relocation += rel->r_addend;
+ bfd_put_32 (input_bfd, relocation, contents);
+ break;
+
+ case R_FR30_9_PCREL:
+ contents += rel->r_offset + 1;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= 2; /* Branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ if (srel > ((1 << 8) - 1) || (srel < - (1 << 8)))
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, srel >> 1, contents);
+ break;
+
+ case R_FR30_12_PCREL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= 2; /* Branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ if (srel > ((1 << 11) - 1) || (srel < - (1 << 11)))
+ return bfd_reloc_overflow;
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf800) | ((srel >> 1) & 0x7ff);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+
+ return r;
+}
+
+
+/* Relocate an FR30 ELF section.
+ There is some attempt to make this function usable for many architectures,
+ both USE_REL and USE_RELA ['twould be nice if such a critter existed],
+ if only to serve as a learning tool.
+
+ The RELOCATE_SECTION function is called by the new ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjusting the section contents as
+ necessary, and (if using Rela relocs and generating a relocateable
+ output file) adjusting the reloc addend as necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+
+static boolean
+fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * relocs;
+ Elf_Internal_Sym * local_syms;
+ asection ** local_sections;
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ for (rel = relocs; rel < relend; rel ++)
+ {
+ reloc_howto_type * howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym * sym;
+ asection * sec;
+ struct elf_link_hash_entry * h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char * name = NULL;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if ( r_type == R_FR30_GNU_VTINHERIT
+ || r_type == R_FR30_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections [r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ howto = fr30_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+#if 0
+ fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ sec->name, name, sym->st_name,
+ sec->output_section->vma, sec->output_offset,
+ sym->st_value, rel->r_addend);
+#endif
+ }
+ else
+ {
+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ name = h->root.root.string;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+#if 0
+ fprintf (stderr,
+ "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
+ sec->name, name, h->root.u.def.value,
+ sec->output_section->vma, sec->output_offset, relocation);
+#endif
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ {
+#if 0
+ fprintf (stderr, "undefined: sec: %s, name: %s\n",
+ sec->name, name);
+#endif
+ relocation = 0;
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+#if 0
+ fprintf (stderr, "unknown: name: %s\n", name);
+#endif
+ relocation = 0;
+ }
+ }
+
+ r = fr30_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_undefined:
+ r = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ break;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ break;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous relocation");
+ break;
+
+ default:
+ msg = _("internal error: unknown error");
+ break;
+ }
+
+ if (msg)
+ r = info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+ if (! r)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+fr30_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ Elf_Internal_Rela * rel;
+ struct elf_link_hash_entry * h;
+ Elf_Internal_Sym * sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_FR30_GNU_VTINHERIT:
+ case R_FR30_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+fr30_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ asection * sec;
+ const Elf_Internal_Rela * relocs;
+{
+ return true;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+fr30_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_FR30_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_FR30_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+#define ELF_ARCH bfd_arch_fr30
+#define ELF_MACHINE_CODE EM_CYGNUS_FR30
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM bfd_elf32_fr30_vec
+#define TARGET_BIG_NAME "elf32-fr30"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto fr30_info_to_howto_rela
+#define elf_backend_relocate_section fr30_elf_relocate_section
+#define elf_backend_gc_mark_hook fr30_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook fr30_elf_gc_sweep_hook
+#define elf_backend_check_relocs fr30_elf_check_relocs
+
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_reloc_type_lookup fr30_reloc_type_lookup
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-gen.c b/bfd/elf32-gen.c
new file mode 100644
index 00000000000..a4d3cac0850
--- /dev/null
+++ b/bfd/elf32-gen.c
@@ -0,0 +1,71 @@
+/* Generic support for 32-bit ELF
+ Copyright 1993, 1995, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* This does not include any relocation information, but should be
+ good enough for GDB or objdump to read the file. */
+
+static reloc_howto_type dummy =
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "UNKNOWN", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+static void
+elf_generic_info_to_howto (abfd, bfd_reloc, elf_reloc)
+ bfd *abfd;
+ arelent *bfd_reloc;
+ Elf32_Internal_Rela *elf_reloc;
+{
+ bfd_reloc->howto = &dummy;
+}
+
+static void
+elf_generic_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
+ bfd *abfd;
+ arelent *bfd_reloc;
+ Elf32_Internal_Rel *elf_reloc;
+{
+ bfd_reloc->howto = &dummy;
+}
+
+#define TARGET_LITTLE_SYM bfd_elf32_little_generic_vec
+#define TARGET_LITTLE_NAME "elf32-little"
+#define TARGET_BIG_SYM bfd_elf32_big_generic_vec
+#define TARGET_BIG_NAME "elf32-big"
+#define ELF_ARCH bfd_arch_unknown
+#define ELF_MACHINE_CODE EM_NONE
+#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define elf_info_to_howto elf_generic_info_to_howto
+#define elf_info_to_howto_rel elf_generic_info_to_howto_rel
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
new file mode 100644
index 00000000000..6bd7f67a0ab
--- /dev/null
+++ b/bfd/elf32-hppa.c
@@ -0,0 +1,2988 @@
+/* BFD back-end for HP PA-RISC ELF files.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+ Written by
+
+ Center for Software Science
+ Department of Computer Science
+ University of Utah
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* The internal type of a symbol table extension entry. */
+typedef unsigned long symext_entryS;
+
+/* The external type of a symbol table extension entry. */
+#define ELF32_PARISC_SX_SIZE (4)
+#define ELF32_PARISC_SX_GET(bfd, addr) bfd_h_get_32 ((bfd), (addr))
+#define ELF32_PARISC_SX_PUT(bfd, val, addr) \
+ bfd_h_put_32 ((bfd), (val), (addr))
+
+/* HPPA symbol table extension entry types */
+enum elf32_hppa_symextn_types
+{
+ PARISC_SXT_NULL,
+ PARISC_SXT_SYMNDX,
+ PARISC_SXT_ARG_RELOC,
+};
+
+/* These macros compose and decompose the value of a symextn entry:
+
+ entry_type = ELF32_PARISC_SX_TYPE(word);
+ entry_value = ELF32_PARISC_SX_VAL(word);
+ word = ELF32_PARISC_SX_WORD(type,val); */
+
+#define ELF32_PARISC_SX_TYPE(p) ((p) >> 24)
+#define ELF32_PARISC_SX_VAL(p) ((p) & 0xFFFFFF)
+#define ELF32_PARISC_SX_WORD(type,val) (((type) << 24) + (val & 0xFFFFFF))
+
+/* The following was added facilitate implementation of the .hppa_symextn
+ section. This section is built after the symbol table is built in the
+ elf_write_object_contents routine (called from bfd_close). It is built
+ so late because it requires information that is not known until
+ the symbol and string table sections have been allocated, and
+ the symbol table has been built. */
+
+#define SYMEXTN_SECTION_NAME ".PARISC.symext"
+
+struct symext_chain
+ {
+ symext_entryS entry;
+ struct symext_chain *next;
+ };
+
+typedef struct symext_chain symext_chainS;
+
+/* We use three different hash tables to hold information for
+ linking PA ELF objects.
+
+ The first is the elf32_hppa_link_hash_table which is derived
+ from the standard ELF linker hash table. We use this as a place to
+ attach other hash tables and static information.
+
+ The second is the stub hash table which is derived from the
+ base BFD hash table. The stub hash table holds the information
+ necessary to build the linker stubs during a link.
+
+ The last hash table keeps track of argument location information needed
+ to build hash tables. Each function with nonzero argument location
+ bits will have an entry in this table. */
+
+/* Hash table for linker stubs. */
+
+struct elf32_hppa_stub_hash_entry
+{
+ /* Base hash table entry structure, we can get the name of the stub
+ (and thus know exactly what actions it performs) from the base
+ hash table entry. */
+ struct bfd_hash_entry root;
+
+ /* Offset of the beginning of this stub. */
+ bfd_vma offset;
+
+ /* Given the symbol's value and its section we can determine its final
+ value when building the stubs (so the stub knows where to jump. */
+ symvalue target_value;
+ asection *target_section;
+};
+
+struct elf32_hppa_stub_hash_table
+{
+ /* The hash table itself. */
+ struct bfd_hash_table root;
+
+ /* The stub BFD. */
+ bfd *stub_bfd;
+
+ /* Where to place the next stub. */
+ bfd_byte *location;
+
+ /* Current offset in the stub section. */
+ unsigned int offset;
+
+};
+
+/* Hash table for argument location information. */
+
+struct elf32_hppa_args_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ /* The argument location bits for this entry. */
+ int arg_bits;
+};
+
+struct elf32_hppa_args_hash_table
+{
+ /* The hash table itself. */
+ struct bfd_hash_table root;
+};
+
+struct elf32_hppa_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+};
+
+struct elf32_hppa_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ /* The stub hash table. */
+ struct elf32_hppa_stub_hash_table *stub_hash_table;
+
+ /* The argument relocation bits hash table. */
+ struct elf32_hppa_args_hash_table *args_hash_table;
+
+ /* A count of the number of output symbols. */
+ unsigned int output_symbol_count;
+
+ /* Stuff so we can handle DP relative relocations. */
+ long global_value;
+ int global_sym_defined;
+};
+
+/* FIXME. */
+#define ARGUMENTS 0
+#define RETURN_VALUE 1
+
+/* The various argument relocations that may be performed. */
+typedef enum
+{
+ /* No relocation. */
+ NO,
+ /* Relocate 32 bits from GR to FP register. */
+ GF,
+ /* Relocate 64 bits from a GR pair to FP pair. */
+ GD,
+ /* Relocate 32 bits from FP to GR. */
+ FG,
+ /* Relocate 64 bits from FP pair to GR pair. */
+ DG,
+} arg_reloc_type;
+
+/* What is being relocated (eg which argument or the return value). */
+typedef enum
+{
+ ARG0, ARG1, ARG2, ARG3, RET,
+} arg_reloc_location;
+
+
+/* ELF32/HPPA relocation support
+
+ This file contains ELF32/HPPA relocation support as specified
+ in the Stratus FTX/Golf Object File Format (SED-1762) dated
+ February 1994. */
+
+#include "elf32-hppa.h"
+#include "hppa_stubs.h"
+
+static bfd_reloc_status_type hppa_elf_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static unsigned long hppa_elf_relocate_insn
+ PARAMS ((bfd *, asection *, unsigned long, unsigned long, long,
+ long, unsigned long, unsigned long, unsigned long));
+
+static bfd_reloc_status_type hppa_elf_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd*, char **));
+
+static reloc_howto_type * elf_hppa_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+
+static boolean elf32_hppa_set_section_contents
+ PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+
+static void elf32_hppa_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+
+static boolean elf32_hppa_backend_symbol_table_processing
+ PARAMS ((bfd *, elf_symbol_type *, unsigned int));
+
+static void elf32_hppa_backend_begin_write_processing
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+static void elf32_hppa_backend_final_write_processing
+ PARAMS ((bfd *, boolean));
+
+static void add_entry_to_symext_chain
+ PARAMS ((bfd *, unsigned int, unsigned int, symext_chainS **,
+ symext_chainS **));
+
+static void
+elf_hppa_tc_make_sections PARAMS ((bfd *, symext_chainS *));
+
+static boolean hppa_elf_is_local_label_name PARAMS ((bfd *, const char *));
+
+static boolean elf32_hppa_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+
+static bfd_reloc_status_type elf32_hppa_bfd_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma, struct bfd_link_info *,
+ asection *, const char *, int));
+
+static struct bfd_link_hash_table *elf32_hppa_link_hash_table_create
+ PARAMS ((bfd *));
+
+static struct bfd_hash_entry *
+elf32_hppa_stub_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+static struct bfd_hash_entry *
+elf32_hppa_args_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+static boolean
+elf32_hppa_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
+ bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+
+static boolean
+elf32_hppa_stub_hash_table_init
+ PARAMS ((struct elf32_hppa_stub_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *))));
+
+static boolean
+elf32_hppa_build_one_stub PARAMS ((struct bfd_hash_entry *, PTR));
+
+static boolean
+elf32_hppa_read_symext_info
+ PARAMS ((bfd *, Elf_Internal_Shdr *, struct elf32_hppa_args_hash_table *,
+ Elf_Internal_Sym *));
+
+static unsigned int elf32_hppa_size_of_stub
+ PARAMS ((unsigned int, unsigned int, bfd_vma, bfd_vma, const char *));
+
+static boolean elf32_hppa_arg_reloc_needed
+ PARAMS ((unsigned int, unsigned int, arg_reloc_type []));
+
+static void elf32_hppa_name_of_stub
+ PARAMS ((unsigned int, unsigned int, bfd_vma, bfd_vma, char *));
+
+static boolean elf32_hppa_size_symext PARAMS ((struct bfd_hash_entry *, PTR));
+
+static boolean elf32_hppa_link_output_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const char *,
+ Elf_Internal_Sym *, asection *));
+
+/* ELF/PA relocation howto entries. */
+
+static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
+{
+ {R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_NONE"},
+ /* The values in DIR32 are to placate the check in
+ _bfd_stab_section_find_nearest_line. */
+ {R_PARISC_DIR32, 0, 2, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR32", false, 0, 0xffffffff, false},
+ {R_PARISC_DIR21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR21L"},
+ {R_PARISC_DIR17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17R"},
+ {R_PARISC_DIR17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17F"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DIR14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR14R"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_PCREL21L, 0, 0, 21, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL21L"},
+ {R_PARISC_PCREL17R, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17R"},
+ {R_PARISC_PCREL17F, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17F"},
+ {R_PARISC_PCREL17C, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17C"},
+ {R_PARISC_PCREL14R, 0, 0, 14, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL14R"},
+ {R_PARISC_PCREL14F, 0, 0, 14, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL14F"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DPREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL21L"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DPREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL14R"},
+ {R_PARISC_DPREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL14F"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DLTREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL21L"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DLTREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL14R"},
+ {R_PARISC_DLTREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL14F"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DLTIND21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND21L"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DLTIND14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND14R"},
+ {R_PARISC_DLTIND14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND14F"},
+
+ {R_PARISC_SETBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_SETBASE"},
+ {R_PARISC_BASEREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL32"},
+ {R_PARISC_BASEREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL21L"},
+ {R_PARISC_BASEREL17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL17R"},
+ {R_PARISC_BASEREL17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL17F"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_BASEREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL14R"},
+ {R_PARISC_BASEREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL14F"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_TEXTREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_TEXTREL32"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_DATAREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_PLABEL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL32"},
+ {R_PARISC_PLABEL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL21L"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_PLABEL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL14R"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_PLTIND21L, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND21L"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"},
+ {R_PARISC_PLTIND14R, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND14R"},
+ {R_PARISC_PLTIND14F, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND14F"},
+
+
+ {R_PARISC_COPY, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_COPY"},
+ {R_PARISC_GLOB_DAT, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_GLOB_DAT"},
+ {R_PARISC_JMP_SLOT, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_JMP_SLOT"},
+ {R_PARISC_RELATIVE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_RELATIVE"},
+
+ {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"},
+};
+
+/* Where (what register type) is an argument comming from? */
+typedef enum
+{
+ AR_NO,
+ AR_GR,
+ AR_FR,
+ AR_FU,
+ AR_FPDBL1,
+ AR_FPDBL2,
+} arg_location;
+
+/* Horizontal represents the callee's argument location information,
+ vertical represents caller's argument location information. Value at a
+ particular X,Y location represents what (if any) argument relocation
+ needs to be performed to make caller and callee agree. */
+
+static CONST arg_reloc_type arg_mismatches[6][6] =
+{
+ {NO, NO, NO, NO, NO, NO},
+ {NO, NO, GF, NO, GD, NO},
+ {NO, FG, NO, NO, NO, NO},
+ {NO, NO, NO, NO, NO, NO},
+ {NO, DG, NO, NO, NO, NO},
+ {NO, DG, NO, NO, NO, NO},
+};
+
+/* Likewise, but reversed for the return value. */
+static CONST arg_reloc_type ret_mismatches[6][6] =
+{
+ {NO, NO, NO, NO, NO, NO},
+ {NO, NO, FG, NO, DG, NO},
+ {NO, GF, NO, NO, NO, NO},
+ {NO, NO, NO, NO, NO, NO},
+ {NO, GD, NO, NO, NO, NO},
+ {NO, GD, NO, NO, NO, NO},
+};
+
+/* Misc static crud for symbol extension records. */
+static symext_chainS *symext_rootP;
+static symext_chainS *symext_lastP;
+static bfd_size_type symext_chain_size;
+
+/* FIXME: We should be able to try this static variable! */
+static bfd_byte *symextn_contents;
+
+
+/* For linker stub hash tables. */
+#define elf32_hppa_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_hppa_stub_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+#define elf32_hppa_stub_hash_traverse(table, func, info) \
+ (bfd_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* For linker args hash tables. */
+#define elf32_hppa_args_hash_lookup(table, string, create, copy) \
+ ((struct elf32_hppa_args_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+#define elf32_hppa_args_hash_traverse(table, func, info) \
+ (bfd_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
+ (info)))
+
+#define elf32_hppa_args_hash_table_init(table, newfunc) \
+ (bfd_hash_table_init \
+ (&(table)->root, \
+ (struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *, \
+ struct bfd_hash_table *, \
+ const char *))) (newfunc)))
+
+/* For HPPA linker hash table. */
+
+#define elf32_hppa_link_hash_lookup(table, string, create, copy, follow)\
+ ((struct elf32_hppa_link_hash_entry *) \
+ elf_link_hash_lookup (&(table)->root, (string), (create), \
+ (copy), (follow)))
+
+#define elf32_hppa_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the PA ELF linker hash table from a link_info structure. */
+
+#define elf32_hppa_hash_table(p) \
+ ((struct elf32_hppa_link_hash_table *) ((p)->hash))
+
+
+/* Extract specific argument location bits for WHICH from
+ the full argument location in AR. */
+#define EXTRACT_ARBITS(ar, which) ((ar) >> (8 - ((which) * 2))) & 3
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+elf32_hppa_stub_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct elf32_hppa_stub_hash_entry *ret;
+
+ ret = (struct elf32_hppa_stub_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct elf32_hppa_stub_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf32_hppa_stub_hash_entry)));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf32_hppa_stub_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->offset = 0;
+ ret->target_value = 0;
+ ret->target_section = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize a stub hash table. */
+
+static boolean
+elf32_hppa_stub_hash_table_init (table, stub_bfd, newfunc)
+ struct elf32_hppa_stub_hash_table *table;
+ bfd *stub_bfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ table->offset = 0;
+ table->location = 0;
+ table->stub_bfd = stub_bfd;
+ return (bfd_hash_table_init (&table->root, newfunc));
+}
+
+/* Initialize an entry in the argument location hash table. */
+
+static struct bfd_hash_entry *
+elf32_hppa_args_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct elf32_hppa_args_hash_entry *ret;
+
+ ret = (struct elf32_hppa_args_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct elf32_hppa_args_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf32_hppa_args_hash_entry)));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf32_hppa_args_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ /* Initialize the local fields. */
+ if (ret)
+ ret->arg_bits = 0;
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create the derived linker hash table. The PA ELF port uses the derived
+ hash table to keep information specific to the PA ELF linker (without
+ using static variables). */
+
+static struct bfd_link_hash_table *
+elf32_hppa_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct elf32_hppa_link_hash_table *ret;
+
+ ret = ((struct elf32_hppa_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf32_hppa_link_hash_table)));
+ if (ret == NULL)
+ return NULL;
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ _bfd_elf_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+ ret->stub_hash_table = NULL;
+ ret->args_hash_table = NULL;
+ ret->output_symbol_count = 0;
+ ret->global_value = 0;
+ ret->global_sym_defined = 0;
+
+ return &ret->root.root;
+}
+
+/* Relocate the given INSN given the various input parameters.
+
+ FIXME: endianness and sizeof (long) issues abound here. */
+
+static unsigned long
+hppa_elf_relocate_insn (abfd, input_sect, insn, address, sym_value,
+ r_addend, r_format, r_field, pcrel)
+ bfd *abfd;
+ asection *input_sect;
+ unsigned long insn;
+ unsigned long address;
+ long sym_value;
+ long r_addend;
+ unsigned long r_format;
+ unsigned long r_field;
+ unsigned long pcrel;
+{
+ unsigned char opcode = get_opcode (insn);
+ long constant_value;
+
+ switch (opcode)
+ {
+ case LDO:
+ case LDB:
+ case LDH:
+ case LDW:
+ case LDWM:
+ case STB:
+ case STH:
+ case STW:
+ case STWM:
+ case COMICLR:
+ case SUBI:
+ case ADDIT:
+ case ADDI:
+ case LDIL:
+ case ADDIL:
+ constant_value = HPPA_R_CONSTANT (r_addend);
+
+ if (pcrel)
+ sym_value -= address;
+
+ sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
+ return hppa_rebuild_insn (abfd, insn, sym_value, r_format);
+
+ case BL:
+ case BE:
+ case BLE:
+ /* XXX computing constant_value is not needed??? */
+ constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
+ (insn & 0x00001ffc) >> 2,
+ insn & 1);
+
+ constant_value = (constant_value << 15) >> 15;
+ if (pcrel)
+ {
+ sym_value -=
+ address + input_sect->output_offset
+ + input_sect->output_section->vma;
+ sym_value = hppa_field_adjust (sym_value, -8, r_field);
+ }
+ else
+ sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
+
+ return hppa_rebuild_insn (abfd, insn, sym_value >> 2, r_format);
+
+ default:
+ if (opcode == 0)
+ {
+ constant_value = HPPA_R_CONSTANT (r_addend);
+
+ if (pcrel)
+ sym_value -= address;
+
+ return hppa_field_adjust (sym_value, constant_value, r_field);
+ }
+ else
+ abort ();
+ }
+}
+
+/* Relocate an HPPA ELF section. */
+
+static boolean
+elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char *sym_name;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto = elf_hppa_howto_table + r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sym_sec = local_sections[r_symndx];
+ rel->r_addend += sym_sec->output_offset;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sym_sec = local_sections[r_symndx];
+ relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ ? 0 : sym->st_value)
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else
+ {
+ long indx;
+
+ indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (input_bfd)[indx];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (!((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ break;
+ }
+ }
+
+ if (h != NULL)
+ sym_name = h->root.root.string;
+ else
+ {
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (sym_name == NULL)
+ return false;
+ if (*sym_name == '\0')
+ sym_name = bfd_section_name (input_bfd, sym_sec);
+ }
+
+ /* If args_hash_table is NULL, then we have encountered some
+ kind of link error (ex. undefined symbols). Do not try to
+ apply any relocations, continue the loop so we can notify
+ the user of several errors in a single attempted link. */
+ if (elf32_hppa_hash_table (info)->args_hash_table == NULL)
+ continue;
+
+ r = elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend, info, sym_sec,
+ sym_name, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ /* This can happen for DP relative relocs if $global$ is
+ undefined. This is a panic situation so we don't try
+ to continue. */
+ case bfd_reloc_undefined:
+ case bfd_reloc_notsupported:
+ if (!((*info->callbacks->undefined_symbol)
+ (info, "$global$", input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ return false;
+ case bfd_reloc_dangerous:
+ {
+ /* We use this return value to indicate that we performed
+ a "dangerous" relocation. This doesn't mean we did
+ the wrong thing, it just means there may be some cleanup
+ that needs to be done here.
+
+ In particular we had to swap the last call insn and its
+ delay slot. If the delay slot insn needed a relocation,
+ then we'll need to adjust the next relocation entry's
+ offset to account for the fact that the insn moved.
+
+ This hair wouldn't be necessary if we inserted stubs
+ between procedures and used a "bl" to get to the stub. */
+ if (rel != relend)
+ {
+ Elf_Internal_Rela *next_rel = rel + 1;
+
+ if (rel->r_offset + 4 == next_rel->r_offset)
+ next_rel->r_offset -= 4;
+ }
+ break;
+ }
+ default:
+ case bfd_reloc_outofrange:
+ case bfd_reloc_overflow:
+ {
+ if (!((*info->callbacks->reloc_overflow)
+ (info, sym_name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Return one (or more) BFD relocations which implement the base
+ relocation with modifications based on format and field. */
+
+elf32_hppa_reloc_type **
+hppa_elf_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
+ bfd *abfd;
+ elf32_hppa_reloc_type base_type;
+ int format;
+ int field;
+ int ignore;
+ asymbol *sym;
+{
+ elf32_hppa_reloc_type *finaltype;
+ elf32_hppa_reloc_type **final_types;
+
+ /* Allocate slots for the BFD relocation. */
+ final_types = ((elf32_hppa_reloc_type **)
+ bfd_alloc (abfd, sizeof (elf32_hppa_reloc_type *) * 2));
+ if (final_types == NULL)
+ return NULL;
+
+ /* Allocate space for the relocation itself. */
+ finaltype = ((elf32_hppa_reloc_type *)
+ bfd_alloc (abfd, sizeof (elf32_hppa_reloc_type)));
+ if (finaltype == NULL)
+ return NULL;
+
+ /* Some reasonable defaults. */
+ final_types[0] = finaltype;
+ final_types[1] = NULL;
+
+#define final_type finaltype[0]
+
+ final_type = base_type;
+
+ /* Just a tangle of nested switch statements to deal with the braindamage
+ that a different field selector means a completely different relocation
+ for PA ELF. */
+ switch (base_type)
+ {
+ case R_HPPA:
+ case R_HPPA_ABS_CALL:
+ switch (format)
+ {
+ case 14:
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ final_type = R_PARISC_DIR14R;
+ break;
+ case e_rtsel:
+ final_type = R_PARISC_DLTREL14R;
+ break;
+ case e_tsel:
+ final_type = R_PARISC_DLTREL14F;
+ break;
+ case e_rpsel:
+ final_type = R_PARISC_PLABEL14R;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case 17:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_DIR17F;
+ break;
+ case e_rsel:
+ case e_rrsel:
+ final_type = R_PARISC_DIR17R;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case 21:
+ switch (field)
+ {
+ case e_lsel:
+ case e_lrsel:
+ final_type = R_PARISC_DIR21L;
+ break;
+ case e_ltsel:
+ final_type = R_PARISC_DLTREL21L;
+ break;
+ case e_lpsel:
+ final_type = R_PARISC_PLABEL21L;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case 32:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_DIR32;
+ break;
+ case e_psel:
+ final_type = R_PARISC_PLABEL32;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+ break;
+
+
+ case R_HPPA_GOTOFF:
+ switch (format)
+ {
+ case 14:
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ final_type = R_PARISC_DPREL14R;
+ break;
+ case e_fsel:
+ final_type = R_PARISC_DPREL14F;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case 21:
+ switch (field)
+ {
+ case e_lrsel:
+ case e_lsel:
+ final_type = R_PARISC_DPREL21L;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+ break;
+
+
+ case R_HPPA_PCREL_CALL:
+ switch (format)
+ {
+ case 14:
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ final_type = R_PARISC_PCREL14R;
+ break;
+ case e_fsel:
+ final_type = R_PARISC_PCREL14F;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case 17:
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ final_type = R_PARISC_PCREL17R;
+ break;
+ case e_fsel:
+ final_type = R_PARISC_PCREL17F;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ case 21:
+ switch (field)
+ {
+ case e_lsel:
+ case e_lrsel:
+ final_type = R_PARISC_PCREL21L;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+
+ return final_types;
+}
+
+#undef final_type
+
+/* Set the contents of a particular section at a particular location. */
+
+static boolean
+elf32_hppa_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ /* Ignore write requests for the symbol extension section until we've
+ had the chance to rebuild it ourselves. */
+ if (!strcmp (section->name, ".PARISC.symextn") && !symext_chain_size)
+ return true;
+ else
+ return _bfd_elf_set_section_contents (abfd, section, location,
+ offset, count);
+}
+
+/* Translate from an elf into field into a howto relocation pointer. */
+
+static void
+elf32_hppa_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_PARISC_UNIMPLEMENTED);
+ cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE (dst->r_info)];
+}
+
+
+/* Actually perform a relocation. NOTE this is (mostly) superceeded
+ by elf32_hppa_bfd_final_link_relocate which is called by the new
+ fast linker. */
+
+static bfd_reloc_status_type
+hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* It is no longer valid to call hppa_elf_reloc when creating
+ a final executable. */
+ if (output_bfd)
+ {
+ reloc_entry->address += input_section->output_offset;
+
+ /* Work around lossage in generic elf code to write relocations.
+ (maps different section symbols into the same symbol index). */
+ if ((symbol_in->flags & BSF_SECTION_SYM)
+ && symbol_in->section)
+ reloc_entry->addend += symbol_in->section->output_offset;
+ return bfd_reloc_ok;
+ }
+ else
+ {
+ *error_message = (char *) _("Unsupported call to hppa_elf_reloc");
+ return bfd_reloc_notsupported;
+ }
+}
+
+/* Actually perform a relocation as part of a final link. This can get
+ rather hairy when linker stubs are needed. */
+
+static bfd_reloc_status_type
+elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, offset, value,
+ addend, info, sym_sec, sym_name, is_local)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd *output_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma offset;
+ bfd_vma value;
+ bfd_vma addend;
+ struct bfd_link_info *info;
+ asection *sym_sec;
+ const char *sym_name;
+ int is_local;
+{
+ unsigned long insn;
+ unsigned long r_type = howto->type;
+ unsigned long r_format = howto->bitsize;
+ unsigned long r_field = e_fsel;
+ bfd_byte *hit_data = contents + offset;
+ boolean r_pcrel = howto->pc_relative;
+
+ insn = bfd_get_32 (input_bfd, hit_data);
+
+ /* Make sure we have a value for $global$. FIXME isn't this effectively
+ just like the gp pointer on MIPS? Can we use those routines for this
+ purpose? */
+ if (!elf32_hppa_hash_table (info)->global_sym_defined)
+ {
+ struct elf_link_hash_entry *h;
+ asection *sec;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), "$global$", false,
+ false, false);
+
+ /* If there isn't a $global$, then we're in deep trouble. */
+ if (h == NULL)
+ return bfd_reloc_notsupported;
+
+ /* If $global$ isn't a defined symbol, then we're still in deep
+ trouble. */
+ if (h->root.type != bfd_link_hash_defined)
+ return bfd_reloc_undefined;
+
+ sec = h->root.u.def.section;
+ elf32_hppa_hash_table (info)->global_value = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ elf32_hppa_hash_table (info)->global_sym_defined = 1;
+ }
+
+ switch (r_type)
+ {
+ case R_PARISC_NONE:
+ break;
+
+ case R_PARISC_DIR32:
+ case R_PARISC_DIR17F:
+ case R_PARISC_PCREL17C:
+ r_field = e_fsel;
+ goto do_basic_type_1;
+ case R_PARISC_DIR21L:
+ case R_PARISC_PCREL21L:
+ r_field = e_lrsel;
+ goto do_basic_type_1;
+ case R_PARISC_DIR17R:
+ case R_PARISC_PCREL17R:
+ case R_PARISC_DIR14R:
+ case R_PARISC_PCREL14R:
+ r_field = e_rrsel;
+ goto do_basic_type_1;
+
+ /* For all the DP relative relocations, we need to examine the symbol's
+ section. If it's a code section, then "data pointer relative" makes
+ no sense. In that case we don't adjust the "value", and for 21 bit
+ addil instructions, we change the source addend register from %dp to
+ %r0. */
+ case R_PARISC_DPREL21L:
+ r_field = e_lrsel;
+ if (sym_sec->flags & SEC_CODE)
+ {
+ if ((insn & 0xfc000000) >> 26 == 0xa
+ && (insn & 0x03e00000) >> 21 == 0x1b)
+ insn &= ~0x03e00000;
+ }
+ else
+ value -= elf32_hppa_hash_table (info)->global_value;
+ goto do_basic_type_1;
+ case R_PARISC_DPREL14R:
+ r_field = e_rrsel;
+ if ((sym_sec->flags & SEC_CODE) == 0)
+ value -= elf32_hppa_hash_table (info)->global_value;
+ goto do_basic_type_1;
+ case R_PARISC_DPREL14F:
+ r_field = e_fsel;
+ if ((sym_sec->flags & SEC_CODE) == 0)
+ value -= elf32_hppa_hash_table (info)->global_value;
+ goto do_basic_type_1;
+
+ /* These cases are separate as they may involve a lot more work
+ to deal with linker stubs. */
+ case R_PARISC_PLABEL32:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_PCREL17F:
+ {
+ bfd_vma location;
+ unsigned int len, caller_args, callee_args;
+ arg_reloc_type arg_reloc_types[5];
+ struct elf32_hppa_args_hash_table *args_hash_table;
+ struct elf32_hppa_args_hash_entry *args_hash;
+ char *new_name, *stub_name;
+
+ /* Get the field selector right. We'll need it in a minute. */
+ if (r_type == R_PARISC_PCREL17F
+ || r_type == R_PARISC_PLABEL32)
+ r_field = e_fsel;
+ else if (r_type == R_PARISC_PLABEL21L)
+ r_field = e_lrsel;
+ else if (r_type == R_PARISC_PLABEL14R)
+ r_field = e_rrsel;
+
+ /* Find out where we are and where we're going. */
+ location = (offset +
+ input_section->output_offset +
+ input_section->output_section->vma);
+
+ /* Now look for the argument relocation bits associated with the
+ target. */
+ len = strlen (sym_name) + 1;
+ if (is_local)
+ len += 9;
+ new_name = bfd_malloc (len);
+ if (!new_name)
+ return bfd_reloc_notsupported;
+ strcpy (new_name, sym_name);
+
+ /* Local symbols have unique IDs. */
+ if (is_local)
+ sprintf (new_name + len - 10, "_%08x", (int)sym_sec);
+
+ args_hash_table = elf32_hppa_hash_table (info)->args_hash_table;
+
+ args_hash = elf32_hppa_args_hash_lookup (args_hash_table,
+ new_name, false, false);
+ if (args_hash == NULL)
+ callee_args = 0;
+ else
+ callee_args = args_hash->arg_bits;
+
+ /* If this is a CALL relocation, then get the caller's bits
+ from the addend. Else use the magic 0x155 value for PLABELS.
+
+ Also we don't care about the destination (value) for PLABELS. */
+ if (r_type == R_PARISC_PCREL17F)
+ caller_args = HPPA_R_ARG_RELOC (addend);
+ else
+ {
+ caller_args = 0x155;
+ location = value;
+ }
+
+ /* Any kind of linker stub needed? */
+ if (((int)(value - location) > 0x3ffff)
+ || ((int)(value - location) < (int)0xfffc0000)
+ || elf32_hppa_arg_reloc_needed (caller_args, callee_args,
+ arg_reloc_types))
+ {
+ struct elf32_hppa_stub_hash_table *stub_hash_table;
+ struct elf32_hppa_stub_hash_entry *stub_hash;
+ asection *stub_section;
+
+ /* Build a name for the stub. */
+
+ len = strlen (new_name);
+ len += 23;
+ stub_name = bfd_malloc (len);
+ if (!stub_name)
+ return bfd_reloc_notsupported;
+ elf32_hppa_name_of_stub (caller_args, callee_args,
+ location, value, stub_name);
+ strcat (stub_name, new_name);
+ free (new_name);
+
+ stub_hash_table = elf32_hppa_hash_table (info)->stub_hash_table;
+
+ stub_hash
+ = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name,
+ false, false);
+
+ /* We're done with that name. */
+ free (stub_name);
+
+ /* The stub BFD only has one section. */
+ stub_section = stub_hash_table->stub_bfd->sections;
+
+ if (stub_hash != NULL)
+ {
+
+ if (r_type == R_PARISC_PCREL17F)
+ {
+ unsigned long delay_insn;
+ unsigned int opcode, rtn_reg, ldo_target_reg, ldo_src_reg;
+
+ /* We'll need to peek at the next insn. */
+ delay_insn = bfd_get_32 (input_bfd, hit_data + 4);
+ opcode = get_opcode (delay_insn);
+
+ /* We also need to know the return register for this
+ call. */
+ rtn_reg = (insn & 0x03e00000) >> 21;
+
+ ldo_src_reg = (delay_insn & 0x03e00000) >> 21;
+ ldo_target_reg = (delay_insn & 0x001f0000) >> 16;
+
+ /* Munge up the value and other parameters for
+ hppa_elf_relocate_insn. */
+
+ value = (stub_hash->offset
+ + stub_section->output_offset
+ + stub_section->output_section->vma);
+
+ r_format = 17;
+ r_field = e_fsel;
+ r_pcrel = 0;
+ addend = 0;
+
+ /* We need to peek at the delay insn and determine if
+ we'll need to swap the branch and its delay insn. */
+ if ((insn & 2)
+ || (opcode == LDO
+ && ldo_target_reg == rtn_reg)
+ || (delay_insn == 0x08000240))
+ {
+ /* No need to swap the branch and its delay slot, but
+ we do need to make sure to jump past the return
+ pointer update in the stub. */
+ value += 4;
+
+ /* If the delay insn does a return pointer adjustment,
+ then we have to make sure it stays valid. */
+ if (opcode == LDO
+ && ldo_target_reg == rtn_reg)
+ {
+ delay_insn &= 0xfc00ffff;
+ delay_insn |= ((31 << 21) | (31 << 16));
+ bfd_put_32 (input_bfd, delay_insn, hit_data + 4);
+ }
+ /* Use a BLE to reach the stub. */
+ insn = BLE_SR4_R0;
+ }
+ else
+ {
+ /* Wonderful, we have to swap the call insn and its
+ delay slot. */
+ bfd_put_32 (input_bfd, delay_insn, hit_data);
+ /* Use a BLE,n to reach the stub. */
+ insn = (BLE_SR4_R0 | 0x2);
+ bfd_put_32 (input_bfd, insn, hit_data + 4);
+ insn = hppa_elf_relocate_insn (input_bfd,
+ input_section,
+ insn, offset + 4,
+ value, addend,
+ r_format, r_field,
+ r_pcrel);
+ /* Update the instruction word. */
+ bfd_put_32 (input_bfd, insn, hit_data + 4);
+ return bfd_reloc_dangerous;
+ }
+ }
+ else
+ {
+ /* PLABEL stuff is easy. */
+
+ value = (stub_hash->offset
+ + stub_section->output_offset
+ + stub_section->output_section->vma);
+ /* We don't need the RP adjustment for PLABELs. */
+ value += 4;
+ if (r_type == R_PARISC_PLABEL32)
+ r_format = 32;
+ else if (r_type == R_PARISC_PLABEL21L)
+ r_format = 21;
+ else if (r_type == R_PARISC_PLABEL14R)
+ r_format = 14;
+
+ r_pcrel = 0;
+ addend = 0;
+ }
+ }
+ else
+ return bfd_reloc_notsupported;
+ }
+ goto do_basic_type_1;
+ }
+
+do_basic_type_1:
+ insn = hppa_elf_relocate_insn (input_bfd, input_section, insn,
+ offset, value, addend, r_format,
+ r_field, r_pcrel);
+ break;
+
+ /* Something we don't know how to handle. */
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ /* Update the instruction word. */
+ bfd_put_32 (input_bfd, insn, hit_data);
+ return (bfd_reloc_ok);
+}
+
+/* Return the address of the howto table entry to perform the CODE
+ relocation for an ARCH machine. */
+
+static reloc_howto_type *
+elf_hppa_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ if ((int) code < (int) R_PARISC_UNIMPLEMENTED)
+ {
+ BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
+ return &elf_hppa_howto_table[(int) code];
+ }
+ return NULL;
+}
+
+/* Return true if SYM represents a local label symbol. */
+
+static boolean
+hppa_elf_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return (name[0] == 'L' && name[1] == '$');
+}
+
+/* Do any backend specific processing when beginning to write an object
+ file. For PA ELF we need to determine the size of the symbol extension
+ section *before* any other output processing happens. */
+
+static void
+elf32_hppa_backend_begin_write_processing (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ unsigned int i;
+ asection *symextn_sec;
+
+ /* Size up the symbol extension section. */
+ if ((abfd->outsymbols == NULL
+ && info == NULL)
+ || symext_chain_size != 0)
+ return;
+
+ if (info == NULL)
+ {
+ /* We were not called from the BFD ELF linker code, so we need
+ to examine the output BFD's outsymbols.
+
+ Note we can not build the symbol extensions now as the symbol
+ map hasn't been set up. */
+ for (i = 0; i < abfd->symcount; i++)
+ {
+ elf_symbol_type *symbol = (elf_symbol_type *)abfd->outsymbols[i];
+
+ /* Only functions ever need an entry in the symbol extension
+ section. */
+ if (!(symbol->symbol.flags & BSF_FUNCTION))
+ continue;
+
+ /* And only if they specify the locations of their arguments. */
+ if (symbol->tc_data.hppa_arg_reloc == 0)
+ continue;
+
+ /* Yup. This function symbol needs an entry. */
+ symext_chain_size += 2 * ELF32_PARISC_SX_SIZE;
+ }
+ }
+ else if (info->relocateable == true)
+ {
+ struct elf32_hppa_args_hash_table *table;
+ table = elf32_hppa_hash_table (info)->args_hash_table;
+
+ /* Determine the size of the symbol extension section. */
+ elf32_hppa_args_hash_traverse (table,
+ elf32_hppa_size_symext,
+ &symext_chain_size);
+ }
+
+ /* Now create the section and set its size. We'll fill in the
+ contents later. */
+ symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
+ if (symextn_sec == NULL)
+ symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
+
+ bfd_set_section_flags (abfd, symextn_sec,
+ SEC_LOAD | SEC_HAS_CONTENTS | SEC_DATA);
+ symextn_sec->output_section = symextn_sec;
+ symextn_sec->output_offset = 0;
+ bfd_set_section_alignment (abfd, symextn_sec, 2);
+ bfd_set_section_size (abfd, symextn_sec, symext_chain_size);
+}
+
+/* Called for each entry in the args location hash table. For each
+ entry we bump the size pointer by 2 records (16 bytes). */
+
+static boolean
+elf32_hppa_size_symext (gen_entry, in_args)
+ struct bfd_hash_entry *gen_entry;
+ PTR in_args;
+{
+ bfd_size_type *sizep = (bfd_size_type *)in_args;
+
+ *sizep += 2 * ELF32_PARISC_SX_SIZE;
+ return true;
+}
+
+/* Backend routine called by the linker for each output symbol.
+
+ For PA ELF we use this opportunity to add an appropriate entry
+ to the symbol extension chain for function symbols. */
+
+static boolean
+elf32_hppa_link_output_symbol_hook (abfd, info, name, sym, section)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const char *name;
+ Elf_Internal_Sym *sym;
+ asection *section;
+{
+ char *new_name;
+ unsigned int len, index;
+ struct elf32_hppa_args_hash_table *args_hash_table;
+ struct elf32_hppa_args_hash_entry *args_hash;
+
+ /* If the args hash table is NULL, then we've encountered an error
+ of some sorts (for example, an undefined symbol). In that case
+ we've got nothing else to do.
+
+ NOTE: elf_link_output_symbol will abort if we return false here! */
+ if (elf32_hppa_hash_table (info)->args_hash_table == NULL)
+ return true;
+
+ index = elf32_hppa_hash_table (info)->output_symbol_count++;
+
+ /* We need to look up this symbol in the args hash table to see if
+ it has argument relocation bits. */
+ if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
+ return true;
+
+ /* We know it's a function symbol of some kind. */
+ len = strlen (name) + 1;
+ if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
+ len += 9;
+
+ new_name = bfd_malloc (len);
+ if (new_name == NULL)
+ return false;
+
+ strcpy (new_name, name);
+ if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
+ sprintf (new_name + len - 10, "_%08x", (int)section);
+
+ /* Now that we have the unique name, we can look it up in the
+ args hash table. */
+ args_hash_table = elf32_hppa_hash_table (info)->args_hash_table;
+ args_hash = elf32_hppa_args_hash_lookup (args_hash_table, new_name,
+ false, false);
+ free (new_name);
+ if (args_hash == NULL)
+ return true;
+
+ /* We know this symbol has arg reloc bits. */
+ add_entry_to_symext_chain (abfd, args_hash->arg_bits,
+ index, &symext_rootP, &symext_lastP);
+ return true;
+}
+
+/* Perform any processing needed late in the object file writing process.
+ For PA ELF we build and set the contents of the symbol extension
+ section. */
+
+static void
+elf32_hppa_backend_final_write_processing (abfd, linker)
+ bfd *abfd;
+ boolean linker;
+{
+ asection *symextn_sec;
+ unsigned int i;
+
+ /* Now build the symbol extension section. */
+ if (symext_chain_size == 0)
+ return;
+
+ if (! linker)
+ {
+ /* We were not called from the backend linker, so we still need
+ to build the symbol extension chain.
+
+ Look at each symbol, adding the appropriate information to the
+ symbol extension section list as necessary. */
+ for (i = 0; i < abfd->symcount; i++)
+ {
+ elf_symbol_type *symbol = (elf_symbol_type *) abfd->outsymbols[i];
+
+ /* Only functions ever need an entry in the symbol extension
+ section. */
+ if (!(symbol->symbol.flags & BSF_FUNCTION))
+ continue;
+
+ /* And only if they specify the locations of their arguments. */
+ if (symbol->tc_data.hppa_arg_reloc == 0)
+ continue;
+
+ /* Add this symbol's information to the chain. */
+ add_entry_to_symext_chain (abfd, symbol->tc_data.hppa_arg_reloc,
+ symbol->symbol.udata.i, &symext_rootP,
+ &symext_lastP);
+ }
+ }
+
+ /* Now fill in the contents of the symbol extension section. */
+ elf_hppa_tc_make_sections (abfd, symext_rootP);
+
+ /* And attach that as the section's contents. */
+ symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
+ if (symextn_sec == (asection *) 0)
+ abort();
+
+ symextn_sec->contents = (void *)symextn_contents;
+
+ bfd_set_section_contents (abfd, symextn_sec, symextn_sec->contents,
+ symextn_sec->output_offset, symextn_sec->_raw_size);
+}
+
+/* Update the symbol extention chain to include the symbol pointed to
+ by SYMBOLP if SYMBOLP is a function symbol. Used internally and by GAS. */
+
+static void
+add_entry_to_symext_chain (abfd, arg_reloc, sym_idx, symext_root, symext_last)
+ bfd *abfd;
+ unsigned int arg_reloc;
+ unsigned int sym_idx;
+ symext_chainS **symext_root;
+ symext_chainS **symext_last;
+{
+ symext_chainS *symextP;
+
+ /* Allocate memory and initialize this entry. */
+ symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
+ if (!symextP)
+ abort(); /* FIXME */
+
+ symextP[0].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_SYMNDX, sym_idx);
+ symextP[0].next = &symextP[1];
+
+ symextP[1].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_ARG_RELOC, arg_reloc);
+ symextP[1].next = NULL;
+
+ /* Now update the chain itself so it can be walked later to build
+ the symbol extension section. */
+ if (*symext_root == NULL)
+ {
+ *symext_root = &symextP[0];
+ *symext_last = &symextP[1];
+ }
+ else
+ {
+ (*symext_last)->next = &symextP[0];
+ *symext_last = &symextP[1];
+ }
+}
+
+/* Build the symbol extension section. */
+
+static void
+elf_hppa_tc_make_sections (abfd, symext_root)
+ bfd *abfd;
+ symext_chainS *symext_root;
+{
+ symext_chainS *symextP;
+ unsigned int i;
+ asection *symextn_sec;
+
+ symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
+
+ /* Grab some memory for the contents of the symbol extension section
+ itself. */
+ symextn_contents = (bfd_byte *) bfd_zalloc (abfd,
+ symextn_sec->_raw_size);
+ if (!symextn_contents)
+ abort(); /* FIXME */
+
+ /* Fill in the contents of the symbol extension chain. */
+ for (i = 0, symextP = symext_root; symextP; symextP = symextP->next, ++i)
+ ELF32_PARISC_SX_PUT (abfd, (bfd_vma) symextP->entry,
+ symextn_contents + i * ELF32_PARISC_SX_SIZE);
+
+ return;
+}
+
+/* Do some PA ELF specific work after reading in the symbol table.
+ In particular attach the argument relocation from the
+ symbol extension section to the appropriate symbols. */
+
+static boolean
+elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt)
+ bfd *abfd;
+ elf_symbol_type *esyms;
+ unsigned int symcnt;
+{
+ Elf32_Internal_Shdr *symextn_hdr =
+ bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
+ unsigned int i, current_sym_idx = 0;
+
+ /* If no symbol extension existed, then all symbol extension information
+ is assumed to be zero. */
+ if (symextn_hdr == NULL)
+ {
+ for (i = 0; i < symcnt; i++)
+ esyms[i].tc_data.hppa_arg_reloc = 0;
+ return (true);
+ }
+
+ /* FIXME: Why not use bfd_get_section_contents here? Also should give
+ memory back when we're done. */
+ /* Allocate a buffer of the appropriate size for the symextn section. */
+ symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
+ if (!symextn_hdr->contents)
+ return false;
+
+ /* Read in the symextn section. */
+ if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
+ return false;
+ if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->sh_size, abfd)
+ != symextn_hdr->sh_size)
+ return false;
+
+ /* Parse entries in the symbol extension section, updating the symtab
+ entries as we go */
+ for (i = 0; i < symextn_hdr->sh_size / ELF32_PARISC_SX_SIZE; i++)
+ {
+ symext_entryS se =
+ ELF32_PARISC_SX_GET (abfd,
+ ((unsigned char *)symextn_hdr->contents
+ + i * ELF32_PARISC_SX_SIZE));
+ unsigned int se_value = ELF32_PARISC_SX_VAL (se);
+ unsigned int se_type = ELF32_PARISC_SX_TYPE (se);
+
+ switch (se_type)
+ {
+ case PARISC_SXT_NULL:
+ break;
+
+ case PARISC_SXT_SYMNDX:
+ if (se_value >= symcnt)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return (false);
+ }
+ current_sym_idx = se_value - 1;
+ break;
+
+ case PARISC_SXT_ARG_RELOC:
+ esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return (false);
+ }
+ }
+ return (true);
+}
+
+/* Read and attach the symbol extension information for the symbols
+ in INPUT_BFD to the argument location hash table. Handle locals
+ if DO_LOCALS is true; likewise for globals when DO_GLOBALS is true. */
+
+static boolean
+elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, local_syms)
+ bfd *input_bfd;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf32_hppa_args_hash_table *args_hash_table;
+ Elf_Internal_Sym *local_syms;
+{
+ asection *symextn_sec;
+ bfd_byte *contents;
+ unsigned int i, n_entries, current_index = 0;
+
+ /* Get the symbol extension section for this BFD. If no section exists
+ then there's nothing to do. Likewise if the section exists, but
+ has no contents. */
+ symextn_sec = bfd_get_section_by_name (input_bfd, SYMEXTN_SECTION_NAME);
+ if (symextn_sec == NULL)
+ return true;
+
+ /* Done separately so we can turn off SEC_HAS_CONTENTS (see below). */
+ if (symextn_sec->_raw_size == 0)
+ {
+ symextn_sec->flags &= ~SEC_HAS_CONTENTS;
+ return true;
+ }
+
+ contents = (bfd_byte *) bfd_malloc ((size_t) symextn_sec->_raw_size);
+ if (contents == NULL)
+ return false;
+
+ /* How gross. We turn off SEC_HAS_CONTENTS for the input symbol extension
+ sections to keep the generic ELF/BFD code from trying to do anything
+ with them. We have to undo that hack temporarily so that we can read
+ in the contents with the generic code. */
+ symextn_sec->flags |= SEC_HAS_CONTENTS;
+ if (bfd_get_section_contents (input_bfd, symextn_sec, contents,
+ 0, symextn_sec->_raw_size) == false)
+ {
+ symextn_sec->flags &= ~SEC_HAS_CONTENTS;
+ free (contents);
+ return false;
+ }
+
+ /* Gross. Turn off SEC_HAS_CONTENTS for the input symbol extension
+ sections (see above). */
+ symextn_sec->flags &= ~SEC_HAS_CONTENTS;
+
+ n_entries = symextn_sec->_raw_size / ELF32_PARISC_SX_SIZE;
+ for (i = 0; i < n_entries; i++)
+ {
+ symext_entryS entry =
+ ELF32_PARISC_SX_GET (input_bfd, contents + i * ELF32_PARISC_SX_SIZE);
+ unsigned int value = ELF32_PARISC_SX_VAL (entry);
+ unsigned int type = ELF32_PARISC_SX_TYPE (entry);
+ struct elf32_hppa_args_hash_entry *args_hash;
+
+ switch (type)
+ {
+ case PARISC_SXT_NULL:
+ break;
+
+ case PARISC_SXT_SYMNDX:
+ if (value >= symtab_hdr->sh_size / sizeof (Elf32_External_Sym))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ free (contents);
+ return false;
+ }
+ current_index = value;
+ break;
+
+ case PARISC_SXT_ARG_RELOC:
+ if (current_index < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Shdr *hdr;
+ char *new_name;
+ const char *sym_name;
+ asection *sym_sec;
+ unsigned int len;
+
+ hdr = elf_elfsections (input_bfd)[local_syms[current_index].st_shndx];
+ sym_sec = hdr->bfd_section;
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ local_syms[current_index].st_name);
+ len = strlen (sym_name) + 10;
+ new_name = bfd_malloc (len);
+ if (new_name == NULL)
+ {
+ free (contents);
+ return false;
+ }
+ strcpy (new_name, sym_name);
+ sprintf (new_name + len - 10, "_%08x", (int)sym_sec);
+
+ /* This is a global symbol with argument location info.
+ We need to enter it into the hash table. */
+ args_hash = elf32_hppa_args_hash_lookup (args_hash_table,
+ new_name, true,
+ true);
+ free (new_name);
+ if (args_hash == NULL)
+ {
+ free (contents);
+ return false;
+ }
+ args_hash->arg_bits = value;
+ break;
+ }
+ else if (current_index >= symtab_hdr->sh_info)
+ {
+ struct elf_link_hash_entry *h;
+
+ current_index -= symtab_hdr->sh_info;
+ h = elf_sym_hashes(input_bfd)[current_index];
+ /* This is a global symbol with argument location
+ information. We need to enter it into the hash table. */
+ args_hash = elf32_hppa_args_hash_lookup (args_hash_table,
+ h->root.root.string,
+ true, true);
+ if (args_hash == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ free (contents);
+ return false;
+ }
+ args_hash->arg_bits = value;
+ break;
+ }
+ else
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ free (contents);
+ return false;
+ }
+ }
+ free (contents);
+ return true;
+}
+
+/* Undo the generic ELF code's subtraction of section->vma from the
+ value of each external symbol. */
+
+static boolean
+elf32_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ *valp += (*secp)->vma;
+ return true;
+}
+
+/* Determine the name of the stub needed to perform a call assuming the
+ argument relocation bits for caller and callee are in CALLER and CALLEE
+ for a call from LOCATION to DESTINATION. Copy the name into STUB_NAME. */
+
+static void
+elf32_hppa_name_of_stub (caller, callee, location, destination, stub_name)
+ unsigned int caller, callee;
+ bfd_vma location, destination;
+ char *stub_name;
+{
+ arg_reloc_type arg_reloc_types[5];
+
+ if (elf32_hppa_arg_reloc_needed (caller, callee, arg_reloc_types))
+ {
+ arg_reloc_location i;
+ /* Fill in the basic template. */
+ strcpy (stub_name, "__XX_XX_XX_XX_XX_stub_");
+
+ /* Now fix the specifics. */
+ for (i = ARG0; i <= RET; i++)
+ switch (arg_reloc_types[i])
+ {
+ case NO:
+ stub_name[3 * i + 2] = 'N';
+ stub_name[3 * i + 3] = 'O';
+ break;
+ case GF:
+ stub_name[3 * i + 2] = 'G';
+ stub_name[3 * i + 3] = 'F';
+ break;
+ case FG:
+ stub_name[3 * i + 2] = 'F';
+ stub_name[3 * i + 3] = 'G';
+ break;
+ case GD:
+ stub_name[3 * i + 2] = 'G';
+ stub_name[3 * i + 3] = 'D';
+ break;
+ case DG:
+ stub_name[3 * i + 2] = 'D';
+ stub_name[3 * i + 3] = 'G';
+ break;
+ }
+ }
+ else
+ strcpy (stub_name, "_____long_branch_stub_");
+}
+
+/* Determine if an argument relocation stub is needed to perform a
+ call assuming the argument relocation bits for caller and callee
+ are in CALLER and CALLEE. Place the type of relocations (if any)
+ into stub_types_p. */
+
+static boolean
+elf32_hppa_arg_reloc_needed (caller, callee, stub_types)
+ unsigned int caller, callee;
+ arg_reloc_type stub_types[5];
+{
+ /* Special case for no relocations. */
+ if (caller == 0 || callee == 0)
+ return 0;
+ else
+ {
+ arg_location caller_loc[5];
+ arg_location callee_loc[5];
+
+ /* Extract the location information for the argument and return
+ value on both the caller and callee sides. */
+ caller_loc[ARG0] = EXTRACT_ARBITS (caller, ARG0);
+ callee_loc[ARG0] = EXTRACT_ARBITS (callee, ARG0);
+ caller_loc[ARG1] = EXTRACT_ARBITS (caller, ARG1);
+ callee_loc[ARG1] = EXTRACT_ARBITS (callee, ARG1);
+ caller_loc[ARG2] = EXTRACT_ARBITS (caller, ARG2);
+ callee_loc[ARG2] = EXTRACT_ARBITS (callee, ARG2);
+ caller_loc[ARG3] = EXTRACT_ARBITS (caller, ARG3);
+ callee_loc[ARG3] = EXTRACT_ARBITS (callee, ARG3);
+ caller_loc[RET] = EXTRACT_ARBITS (caller, RET);
+ callee_loc[RET] = EXTRACT_ARBITS (callee, RET);
+
+ /* Check some special combinations. This is necessary to
+ deal with double precision FP arguments. */
+ if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
+ {
+ caller_loc[ARG0] = AR_FPDBL1;
+ caller_loc[ARG1] = AR_NO;
+ }
+ if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
+ {
+ caller_loc[ARG2] = AR_FPDBL2;
+ caller_loc[ARG3] = AR_NO;
+ }
+ if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
+ {
+ callee_loc[ARG0] = AR_FPDBL1;
+ callee_loc[ARG1] = AR_NO;
+ }
+ if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
+ {
+ callee_loc[ARG2] = AR_FPDBL2;
+ callee_loc[ARG3] = AR_NO;
+ }
+
+ /* Now look up any relocation needed for each argument and the
+ return value. */
+ stub_types[ARG0] = arg_mismatches[caller_loc[ARG0]][callee_loc[ARG0]];
+ stub_types[ARG1] = arg_mismatches[caller_loc[ARG1]][callee_loc[ARG1]];
+ stub_types[ARG2] = arg_mismatches[caller_loc[ARG2]][callee_loc[ARG2]];
+ stub_types[ARG3] = arg_mismatches[caller_loc[ARG3]][callee_loc[ARG3]];
+ stub_types[RET] = ret_mismatches[caller_loc[RET]][callee_loc[RET]];
+
+ return (stub_types[ARG0] != NO
+ || stub_types[ARG1] != NO
+ || stub_types[ARG2] != NO
+ || stub_types[ARG3] != NO
+ || stub_types[RET] != NO);
+ }
+}
+
+/* Compute the size of the stub needed to call from LOCATION to DESTINATION
+ (a function named SYM_NAME), with argument relocation bits CALLER and
+ CALLEE. Return zero if no stub is needed to perform such a call. */
+
+static unsigned int
+elf32_hppa_size_of_stub (callee, caller, location, destination, sym_name)
+ unsigned int callee, caller;
+ bfd_vma location, destination;
+ const char *sym_name;
+{
+ arg_reloc_type arg_reloc_types[5];
+
+ /* Determine if a long branch or argument relocation stub is needed.
+ If an argument relocation stub is needed, the relocation will be
+ stored into arg_reloc_types. */
+ if (!(((int)(location - destination) > 0x3ffff)
+ || ((int)(location - destination) < (int)0xfffc0000)
+ || elf32_hppa_arg_reloc_needed (caller, callee, arg_reloc_types)))
+ return 0;
+
+ /* Some kind of stub is needed. Determine how big it needs to be.
+ First check for argument relocation stubs as they also handle
+ long calls. Then check for long calls to millicode and finally
+ the normal long calls. */
+ if (arg_reloc_types[ARG0] != NO
+ || arg_reloc_types[ARG1] != NO
+ || arg_reloc_types[ARG2] != NO
+ || arg_reloc_types[ARG3] != NO
+ || arg_reloc_types[RET] != NO)
+ {
+ /* Some kind of argument relocation stub is needed. */
+ unsigned int len = 16;
+ arg_reloc_location i;
+
+ /* Each GR or FG relocation takes 2 insns, each GD or DG
+ relocation takes 3 insns. Plus 4 more insns for the
+ RP adjustment, ldil & (be | ble) and copy. */
+ for (i = ARG0; i <= RET; i++)
+ switch (arg_reloc_types[i])
+ {
+ case GF:
+ case FG:
+ len += 8;
+ break;
+
+ case GD:
+ case DG:
+ len += 12;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Extra instructions are needed if we're relocating a return value. */
+ if (arg_reloc_types[RET] != NO)
+ len += 12;
+
+ return len;
+ }
+ else if (!strncmp ("$$", sym_name, 2)
+ && strcmp ("$$dyncall", sym_name))
+ return 12;
+ else
+ return 16;
+}
+
+/* Build one linker stub as defined by the stub hash table entry GEN_ENTRY.
+ IN_ARGS contains the stub BFD and link info pointers. */
+
+static boolean
+elf32_hppa_build_one_stub (gen_entry, in_args)
+ struct bfd_hash_entry *gen_entry;
+ PTR in_args;
+{
+ void **args = (void **)in_args;
+ bfd *stub_bfd = (bfd *)args[0];
+ struct bfd_link_info *info = (struct bfd_link_info *)args[1];
+ struct elf32_hppa_stub_hash_entry *entry;
+ struct elf32_hppa_stub_hash_table *stub_hash_table;
+ bfd_byte *loc;
+ symvalue sym_value;
+ const char *sym_name;
+
+ /* Initialize pointers to the stub hash table, the particular entry we
+ are building a stub for, and where (in memory) we should place the stub
+ instructions. */
+ entry = (struct elf32_hppa_stub_hash_entry *)gen_entry;
+ stub_hash_table = elf32_hppa_hash_table(info)->stub_hash_table;
+ loc = stub_hash_table->location;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ entry->offset = stub_hash_table->offset;
+
+ /* The symbol's name starts at offset 22. */
+ sym_name = entry->root.string + 22;
+
+ sym_value = (entry->target_value
+ + entry->target_section->output_offset
+ + entry->target_section->output_section->vma);
+
+ if (strncmp ("_____long_branch_stub_", entry->root.string, 22))
+ {
+ /* This must be an argument or return value relocation stub. */
+ unsigned long insn;
+ arg_reloc_location i;
+ bfd_byte *begin_loc = loc;
+
+ /* First the return pointer adjustment. Depending on exact calling
+ sequence this instruction may be skipped. */
+ bfd_put_32 (stub_bfd, LDO_M4_R31_R31, loc);
+ loc += 4;
+
+ /* If we are relocating a return value, then we're going to have
+ to return into the stub. So we have to save off the user's
+ return pointer into the stack at RP'. */
+ if (strncmp (entry->root.string + 14, "NO", 2))
+ {
+ bfd_put_32 (stub_bfd, STW_R31_M8R30, loc);
+ loc += 4;
+ }
+
+ /* Iterate over the argument relocations, emitting instructions
+ to move them around as necessary. */
+ for (i = ARG0; i <= ARG3; i++)
+ {
+ if (!strncmp (entry->root.string + 3 * i + 2, "GF", 2))
+ {
+ bfd_put_32 (stub_bfd, STW_ARG_M16R30 | ((26 - i) << 16), loc);
+ bfd_put_32 (stub_bfd, FLDW_M16R30_FARG | (4 + i), loc + 4);
+ loc += 8;
+ }
+ else if (!strncmp (entry->root.string + 3 * i + 2, "FG", 2))
+ {
+ bfd_put_32 (stub_bfd, FSTW_FARG_M16R30 | (4 + i), loc);
+ bfd_put_32 (stub_bfd, LDW_M16R30_ARG | ((26 - i) << 16), loc + 4);
+ loc += 8;
+ }
+ else if (!strncmp (entry->root.string + 3 * i + 2, "GD", 2))
+ {
+ bfd_put_32 (stub_bfd, STW_ARG_M12R30 | ((26 - i) << 16), loc);
+ bfd_put_32 (stub_bfd, STW_ARG_M16R30 | ((25 - i) << 16), loc + 4);
+ bfd_put_32 (stub_bfd, FLDD_M16R30_FARG | (5 + i), loc + 8);
+ loc += 12;
+ }
+ else if (!strncmp (entry->root.string + 3 * i + 2, "DG", 2))
+ {
+ bfd_put_32 (stub_bfd, FSTD_FARG_M16R30 | (5 + i), loc);
+ bfd_put_32 (stub_bfd, LDW_M12R30_ARG | ((26 - i) << 16), loc + 4);
+ bfd_put_32 (stub_bfd, LDW_M16R30_ARG | ((25 - i) << 16), loc + 8);
+ loc += 12;
+ }
+ }
+
+ /* Load the high bits of the target address into %r1. */
+ insn = hppa_rebuild_insn (stub_bfd, LDIL_R1,
+ hppa_field_adjust (sym_value, 0, e_lrsel), 21);
+ bfd_put_32 (stub_bfd, insn, loc);
+ loc += 4;
+
+ /* If we are relocating a return value, then we're going to have
+ to return into the stub, then perform the return value relocation. */
+ if (strncmp (entry->root.string + 14, "NO", 2))
+ {
+ /* To return to the stub we "ble" to the target and copy the return
+ pointer from %r31 into %r2. */
+ insn = hppa_rebuild_insn (stub_bfd,
+ BLE_SR4_R1,
+ hppa_field_adjust (sym_value, 0,
+ e_rrsel) >> 2,
+ 17);
+ bfd_put_32 (stub_bfd, insn, loc);
+ bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 4);
+
+ /* Reload the return pointer for our caller from the stack. */
+ bfd_put_32 (stub_bfd, LDW_M8R30_R31, loc + 8);
+ loc += 12;
+
+ /* Perform the return value relocation. */
+ if (!strncmp (entry->root.string + 14, "GF", 2))
+ {
+ bfd_put_32 (stub_bfd, STW_ARG_M16R30 | (28 << 16), loc);
+ bfd_put_32 (stub_bfd, FLDW_M16R30_FARG | 4, loc + 4);
+ loc += 8;
+ }
+ else if (!strncmp (entry->root.string + 14, "FG", 2))
+ {
+ bfd_put_32 (stub_bfd, FSTW_FARG_M16R30 | 4, loc);
+ bfd_put_32 (stub_bfd, LDW_M16R30_ARG | (28 << 16), loc + 4);
+ loc += 8;
+ }
+ else if (!strncmp (entry->root.string + 2, "GD", 2))
+ {
+ bfd_put_32 (stub_bfd, STW_ARG_M12R30 | (28 << 16), loc);
+ bfd_put_32 (stub_bfd, STW_ARG_M16R30 | (29 << 16), loc + 4);
+ bfd_put_32 (stub_bfd, FLDD_M16R30_FARG | 4, loc + 8);
+ loc += 12;
+ }
+ else if (!strncmp (entry->root.string + 2, "DG", 2))
+ {
+ bfd_put_32 (stub_bfd, FSTD_FARG_M16R30 | 4, loc);
+ bfd_put_32 (stub_bfd, LDW_M12R30_ARG | (28 << 16), loc + 4);
+ bfd_put_32 (stub_bfd, LDW_M16R30_ARG | (29 << 16), loc + 8);
+ loc += 12;
+ }
+ /* Branch back to the user's code now. */
+ bfd_put_32 (stub_bfd, BV_N_0_R31, loc);
+ loc += 4;
+ }
+ else
+ {
+ /* No return value relocation, so we can simply "be" to the
+ target and copy out return pointer into %r2. */
+ insn = hppa_rebuild_insn (stub_bfd, BE_SR4_R1,
+ hppa_field_adjust (sym_value, 0,
+ e_rrsel) >> 2, 17);
+ bfd_put_32 (stub_bfd, insn, loc);
+ bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 4);
+ loc += 8;
+ }
+
+ /* Update the location and offsets. */
+ stub_hash_table->location += (loc - begin_loc);
+ stub_hash_table->offset += (loc - begin_loc);
+ }
+ else
+ {
+ /* Create one of two variant long branch stubs. One for $$dyncall and
+ normal calls, the other for calls to millicode. */
+ unsigned long insn;
+ int millicode_call = 0;
+
+ if (!strncmp ("$$", sym_name, 2) && strcmp ("$$dyncall", sym_name))
+ millicode_call = 1;
+
+ /* First the return pointer adjustment. Depending on exact calling
+ sequence this instruction may be skipped. */
+ bfd_put_32 (stub_bfd, LDO_M4_R31_R31, loc);
+
+ /* The next two instructions are the long branch itself. A long branch
+ is formed with "ldil" loading the upper bits of the target address
+ into a register, then branching with "be" which adds in the lower bits.
+ Long branches to millicode nullify the delay slot of the "be". */
+ insn = hppa_rebuild_insn (stub_bfd, LDIL_R1,
+ hppa_field_adjust (sym_value, 0, e_lrsel), 21);
+ bfd_put_32 (stub_bfd, insn, loc + 4);
+ insn = hppa_rebuild_insn (stub_bfd, BE_SR4_R1 | (millicode_call ? 2 : 0),
+ hppa_field_adjust (sym_value, 0, e_rrsel) >> 2,
+ 17);
+ bfd_put_32 (stub_bfd, insn, loc + 8);
+
+ if (!millicode_call)
+ {
+ /* The sequence to call this stub places the return pointer into %r31,
+ the final target expects the return pointer in %r2, so copy the
+ return pointer into the proper register. */
+ bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 12);
+
+ /* Update the location and offsets. */
+ stub_hash_table->location += 16;
+ stub_hash_table->offset += 16;
+ }
+ else
+ {
+ /* Update the location and offsets. */
+ stub_hash_table->location += 12;
+ stub_hash_table->offset += 12;
+ }
+
+ }
+ return true;
+}
+
+/* External entry points for sizing and building linker stubs. */
+
+/* Build all the stubs associated with the current output file. The
+ stubs are kept in a hash table attached to the main linker hash
+ table. This is called via hppaelf_finish in the linker. */
+
+boolean
+elf32_hppa_build_stubs (stub_bfd, info)
+ bfd *stub_bfd;
+ struct bfd_link_info *info;
+{
+ /* The stub BFD only has one section. */
+ asection *stub_sec = stub_bfd->sections;
+ struct elf32_hppa_stub_hash_table *table;
+ unsigned int size;
+ void *args[2];
+
+ /* So we can pass both the BFD for the stubs and the link info
+ structure to the routine which actually builds stubs. */
+ args[0] = stub_bfd;
+ args[1] = info;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = bfd_section_size (stub_bfd, stub_sec);
+ stub_sec->contents = (unsigned char *) bfd_zalloc (stub_bfd, size);
+ if (stub_sec->contents == NULL)
+ return false;
+ table = elf32_hppa_hash_table(info)->stub_hash_table;
+ table->location = stub_sec->contents;
+
+ /* Build the stubs as directed by the stub hash table. */
+ elf32_hppa_stub_hash_traverse (table, elf32_hppa_build_one_stub, args);
+
+ return true;
+}
+
+/* Determine and set the size of the stub section for a final link.
+
+ The basic idea here is to examine all the relocations looking for
+ PC-relative calls to a target that is unreachable with a "bl"
+ instruction or calls where the caller and callee disagree on the
+ location of their arguments or return value. */
+
+boolean
+elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info)
+ bfd *stub_bfd;
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+{
+ bfd *input_bfd;
+ asection *section, *stub_sec = 0;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *local_syms, *isym, **all_local_syms;
+ Elf32_External_Sym *ext_syms, *esym;
+ unsigned int i, index, bfd_count = 0;
+ struct elf32_hppa_stub_hash_table *stub_hash_table = 0;
+ struct elf32_hppa_args_hash_table *args_hash_table = 0;
+
+ /* Create and initialize the stub hash table. */
+ stub_hash_table = ((struct elf32_hppa_stub_hash_table *)
+ bfd_malloc (sizeof (struct elf32_hppa_stub_hash_table)));
+ if (!stub_hash_table)
+ goto error_return;
+
+ if (!elf32_hppa_stub_hash_table_init (stub_hash_table, stub_bfd,
+ elf32_hppa_stub_hash_newfunc))
+ goto error_return;
+
+ /* Likewise for the argument location hash table. */
+ args_hash_table = ((struct elf32_hppa_args_hash_table *)
+ bfd_malloc (sizeof (struct elf32_hppa_args_hash_table)));
+ if (!args_hash_table)
+ goto error_return;
+
+ if (!elf32_hppa_args_hash_table_init (args_hash_table,
+ elf32_hppa_args_hash_newfunc))
+ goto error_return;
+
+ /* Attach the hash tables to the main hash table. */
+ elf32_hppa_hash_table(link_info)->stub_hash_table = stub_hash_table;
+ elf32_hppa_hash_table(link_info)->args_hash_table = args_hash_table;
+
+ /* Count the number of input BFDs. */
+ for (input_bfd = link_info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link_next)
+ bfd_count++;
+
+ /* We want to read in symbol extension records only once. To do this
+ we need to read in the local symbols in parallel and save them for
+ later use; so hold pointers to the local symbols in an array. */
+ all_local_syms
+ = (Elf_Internal_Sym **) bfd_malloc (sizeof (Elf_Internal_Sym *)
+ * bfd_count);
+ if (all_local_syms == NULL)
+ goto error_return;
+ memset (all_local_syms, 0, sizeof (Elf_Internal_Sym *) * bfd_count);
+
+ /* Walk over all the input BFDs adding entries to the args hash table
+ for all the external functions. */
+ for (input_bfd = link_info->input_bfds, index = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link_next, index++)
+ {
+ /* We'll need the symbol table in a second. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (symtab_hdr->sh_info == 0)
+ continue;
+
+ /* We need an array of the local symbols attached to the input bfd.
+ Unfortunately, we're going to have to read & swap them in. */
+ local_syms
+ = (Elf_Internal_Sym *) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf_Internal_Sym));
+ if (local_syms == NULL)
+ {
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+ all_local_syms[index] = local_syms;
+
+ ext_syms
+ = (Elf32_External_Sym *) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf32_External_Sym));
+ if (ext_syms == NULL)
+ {
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || bfd_read (ext_syms, 1,
+ (symtab_hdr->sh_info
+ * sizeof (Elf32_External_Sym)), input_bfd)
+ != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym)))
+ {
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ free (ext_syms);
+ goto error_return;
+ }
+
+ /* Swap the local symbols in. */
+ isym = local_syms;
+ esym = ext_syms;
+ for (i = 0; i < symtab_hdr->sh_info; i++, esym++, isym++)
+ bfd_elf32_swap_symbol_in (input_bfd, esym, isym);
+
+ /* Now we can free the external symbols. */
+ free (ext_syms);
+
+ if (elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table,
+ local_syms) == false)
+ {
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+ }
+
+ /* Magic as we know the stub bfd only has one section. */
+ stub_sec = stub_bfd->sections;
+
+ /* If generating a relocateable output file, then we don't
+ have to examine the relocs. */
+ if (link_info->relocateable)
+ {
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ return true;
+ }
+
+ /* Now that we have argument location information for all the global
+ functions we can start looking for stubs. */
+ for (input_bfd = link_info->input_bfds, index = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link_next, index++)
+ {
+ /* We'll need the symbol table in a second. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (symtab_hdr->sh_info == 0)
+ continue;
+
+ local_syms = all_local_syms[index];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Shdr *input_rel_hdr;
+ Elf32_External_Rela *external_relocs, *erelaend, *erela;
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* Allocate space for the external relocations. */
+ external_relocs
+ = ((Elf32_External_Rela *)
+ bfd_malloc (section->reloc_count
+ * sizeof (Elf32_External_Rela)));
+ if (external_relocs == NULL)
+ {
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+
+ /* Likewise for the internal relocations. */
+ internal_relocs
+ = ((Elf_Internal_Rela *)
+ bfd_malloc (section->reloc_count * sizeof (Elf_Internal_Rela)));
+ if (internal_relocs == NULL)
+ {
+ free (external_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+
+ /* Read in the external relocs. */
+ input_rel_hdr = &elf_section_data (section)->rel_hdr;
+ if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0
+ || bfd_read (external_relocs, 1, input_rel_hdr->sh_size,
+ input_bfd) != input_rel_hdr->sh_size)
+ {
+ free (external_relocs);
+ free (internal_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+
+ /* Swap in the relocs. */
+ erela = external_relocs;
+ erelaend = erela + section->reloc_count;
+ irela = internal_relocs;
+ for (; erela < erelaend; erela++, irela++)
+ bfd_elf32_swap_reloca_in (input_bfd, erela, irela);
+
+ /* We're done with the external relocs, free them. */
+ free (external_relocs);
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ long r_type, callee_args, caller_args, size_of_stub;
+ unsigned long r_index;
+ struct elf_link_hash_entry *hash;
+ struct elf32_hppa_stub_hash_entry *stub_hash;
+ struct elf32_hppa_args_hash_entry *args_hash;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ const char *sym_name;
+ symvalue sym_value;
+ bfd_vma location, destination;
+ char *new_name = NULL;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_index = ELF32_R_SYM (irela->r_info);
+
+ if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ free (internal_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+
+ /* Only look for stubs on call instructions or plabel
+ references. */
+ if (r_type != R_PARISC_PCREL17F
+ && r_type != R_PARISC_PLABEL32
+ && r_type != R_PARISC_PLABEL21L
+ && r_type != R_PARISC_PLABEL14R)
+ continue;
+
+ /* Now determine the call target, its name, value, section
+ and argument relocation bits. */
+ hash = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+ if (r_index < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Shdr *hdr;
+
+ sym = local_syms + r_index;
+ hdr = elf_elfsections (input_bfd)[sym->st_shndx];
+ sym_sec = hdr->bfd_section;
+ sym_name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ sym_value = (ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ ? 0 : sym->st_value);
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+
+ /* Tack on an ID so we can uniquely identify this local
+ symbol in the stub or arg info hash tables. */
+ new_name = bfd_malloc (strlen (sym_name) + 10);
+ if (new_name == 0)
+ {
+ free (internal_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+ sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);
+ sym_name = new_name;
+ }
+ else
+ {
+ /* It's an external symbol. */
+ long index;
+
+ index = r_index - symtab_hdr->sh_info;
+ hash = elf_sym_hashes (input_bfd)[index];
+ if (hash->root.type == bfd_link_hash_defined
+ || hash->root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hash->root.u.def.section;
+ sym_name = hash->root.root.string;
+ sym_value = hash->root.u.def.value;
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ free (internal_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+ }
+
+ args_hash = elf32_hppa_args_hash_lookup (args_hash_table,
+ sym_name, false, false);
+
+ /* Get both caller and callee argument information. */
+ if (args_hash == NULL)
+ callee_args = 0;
+ else
+ callee_args = args_hash->arg_bits;
+
+ /* For calls get the caller's bits from the addend of
+ the call relocation. For PLABELS the caller's bits
+ are assumed to have all args & return values in general
+ registers (0x155). */
+ if (r_type == R_PARISC_PCREL17F)
+ caller_args = HPPA_R_ARG_RELOC (irela->r_addend);
+ else
+ caller_args = 0x155;
+
+ /* Now determine where the call point is. */
+ location = (section->output_offset
+ + section->output_section->vma
+ + irela->r_offset);
+
+ /* We only care about the destination for PCREL function
+ calls (eg. we don't care for PLABELS). */
+ if (r_type != R_PARISC_PCREL17F)
+ location = destination;
+
+ /* Determine what (if any) linker stub is needed and its
+ size (in bytes). */
+ size_of_stub = elf32_hppa_size_of_stub (callee_args,
+ caller_args,
+ location,
+ destination,
+ sym_name);
+ if (size_of_stub != 0)
+ {
+ char *stub_name;
+ unsigned int len;
+
+ /* Get the name of this stub. */
+ len = strlen (sym_name);
+ len += 23;
+
+ stub_name = bfd_malloc (len);
+ if (!stub_name)
+ {
+ /* Because sym_name was mallocd above for local
+ symbols. */
+ if (r_index < symtab_hdr->sh_info)
+ free (new_name);
+
+ free (internal_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+ elf32_hppa_name_of_stub (caller_args, callee_args,
+ location, destination, stub_name);
+ strcat (stub_name + 22, sym_name);
+
+ /* Because sym_name was malloced above for local symbols. */
+ if (r_index < symtab_hdr->sh_info)
+ free (new_name);
+
+ stub_hash
+ = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name,
+ false, false);
+ if (stub_hash != NULL)
+ {
+ /* The proper stub has already been created, nothing
+ else to do. */
+ free (stub_name);
+ }
+ else
+ {
+ bfd_set_section_size (stub_bfd, stub_sec,
+ (bfd_section_size (stub_bfd,
+ stub_sec)
+ + size_of_stub));
+
+ /* Enter this entry into the linker stub hash table. */
+ stub_hash
+ = elf32_hppa_stub_hash_lookup (stub_hash_table,
+ stub_name, true, true);
+ if (stub_hash == NULL)
+ {
+ free (stub_name);
+ free (internal_relocs);
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ goto error_return;
+ }
+
+ /* We'll need these to determine the address that the
+ stub will branch to. */
+ stub_hash->target_value = sym_value;
+ stub_hash->target_section = sym_sec;
+ }
+ free (stub_name);
+ }
+ }
+ /* We're done with the internal relocs, free them. */
+ free (internal_relocs);
+ }
+ }
+ /* We're done with the local symbols, free them. */
+ for (i = 0; i < bfd_count; i++)
+ if (all_local_syms[i])
+ free (all_local_syms[i]);
+ free (all_local_syms);
+ return true;
+
+error_return:
+ /* Return gracefully, avoiding dangling references to the hash tables. */
+ if (stub_hash_table)
+ {
+ elf32_hppa_hash_table(link_info)->stub_hash_table = NULL;
+ free (stub_hash_table);
+ }
+ if (args_hash_table)
+ {
+ elf32_hppa_hash_table(link_info)->args_hash_table = NULL;
+ free (args_hash_table);
+ }
+ /* Set the size of the stub section to zero since we're never going
+ to create them. Avoids losing when we try to get its contents
+ too. */
+ bfd_set_section_size (stub_bfd, stub_sec, 0);
+ return false;
+}
+
+/* Misc BFD support code. */
+#define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
+#define bfd_elf32_bfd_is_local_label_name hppa_elf_is_local_label_name
+
+/* Symbol extension stuff. */
+#define bfd_elf32_set_section_contents elf32_hppa_set_section_contents
+#define elf_info_to_howto elf32_hppa_info_to_howto
+#define elf_backend_symbol_table_processing \
+ elf32_hppa_backend_symbol_table_processing
+#define elf_backend_begin_write_processing \
+ elf32_hppa_backend_begin_write_processing
+#define elf_backend_final_write_processing \
+ elf32_hppa_backend_final_write_processing
+
+/* Stuff for the BFD linker. */
+#define elf_backend_relocate_section elf32_hppa_relocate_section
+#define elf_backend_add_symbol_hook elf32_hppa_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ elf32_hppa_link_output_symbol_hook
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf32_hppa_link_hash_table_create
+
+#define TARGET_BIG_SYM bfd_elf32_hppa_vec
+#define TARGET_BIG_NAME "elf32-hppa"
+#define ELF_ARCH bfd_arch_hppa
+#define ELF_MACHINE_CODE EM_PARISC
+#define ELF_MAXPAGESIZE 0x1000
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-hppa.h b/bfd/elf32-hppa.h
new file mode 100644
index 00000000000..b2339204592
--- /dev/null
+++ b/bfd/elf32-hppa.h
@@ -0,0 +1,66 @@
+/* ELF32/HPPA support
+
+ This file contains ELF32/HPPA relocation support as specified
+ in the Stratus FTX/Golf Object File Format (SED-1762) dated
+ February 1994.
+
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+ Written by:
+
+ Center for Software Science
+ Department of Computer Science
+ University of Utah
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF32_HPPA_H
+#define _ELF32_HPPA_H
+
+#include "elf-bfd.h"
+#include "libhppa.h"
+#include "elf/hppa.h"
+
+#define ELF_HOWTO_TABLE_SIZE R_PARISC_UNIMPLEMENTED + 1
+#define N_PARISC_RELOCS R_PARISC_UNIMPLEMENTED + 1
+
+/* Define groups of basic relocations. FIXME: These should
+ be the only basic relocations created by GAS. The rest
+ should be internal to the BFD backend.
+
+ The idea is both SOM and ELF define these basic relocation
+ types so they map into a SOM or ELF specific relocation
+ as appropriate. This allows GAS to share much more code
+ between the two target object formats. */
+
+#define R_HPPA_NONE R_PARISC_NONE
+#define R_HPPA R_PARISC_DIR32
+#define R_HPPA_GOTOFF R_PARISC_DPREL21L
+#define R_HPPA_PCREL_CALL R_PARISC_PCREL21L
+#define R_HPPA_ABS_CALL R_PARISC_DIR17F
+#define R_HPPA_COMPLEX R_PARISC_UNIMPLEMENTED
+
+elf32_hppa_reloc_type ** hppa_elf_gen_reloc_type
+ PARAMS ((bfd *, elf32_hppa_reloc_type, int, int, int, asymbol *));
+
+boolean elf32_hppa_size_stubs
+ PARAMS ((bfd *, bfd *, struct bfd_link_info *));
+
+boolean elf32_hppa_build_stubs
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+#endif /* _ELF32_HPPA_H */
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
new file mode 100644
index 00000000000..830c680e885
--- /dev/null
+++ b/bfd/elf32-i386.c
@@ -0,0 +1,1943 @@
+/* Intel 80386/80486-specific support for 32-bit ELF
+ Copyright 1993-1998, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+static reloc_howto_type *elf_i386_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void elf_i386_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static void elf_i386_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static boolean elf_i386_is_local_label_name PARAMS ((bfd *, const char *));
+static struct bfd_hash_entry *elf_i386_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *elf_i386_link_hash_table_create
+ PARAMS ((bfd *));
+static boolean elf_i386_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static boolean elf_i386_adjust_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean elf_i386_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf_i386_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean elf_i386_finish_dynamic_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+static boolean elf_i386_finish_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+#define USE_REL 1 /* 386 uses REL relocations instead of RELA */
+
+#include "elf/i386.h"
+
+static reloc_howto_type elf_howto_table[]=
+{
+ HOWTO(R_386_NONE, 0,0, 0,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_NONE", true,0x00000000,0x00000000,false),
+ HOWTO(R_386_32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_32", true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_PC32, 0,2,32,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC32", true,0xffffffff,0xffffffff,true),
+ HOWTO(R_386_GOT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOT32", true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_PLT32, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PLT32", true,0xffffffff,0xffffffff,true),
+ HOWTO(R_386_COPY, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_COPY", true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_GLOB_DAT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GLOB_DAT", true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_JUMP_SLOT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_JUMP_SLOT",true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_RELATIVE, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_RELATIVE", true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_GOTOFF, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTOFF", true,0xffffffff,0xffffffff,false),
+ HOWTO(R_386_GOTPC, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTPC", true,0xffffffff,0xffffffff,true),
+ { 11 },
+ { 12 },
+ { 13 },
+ { 14 },
+ { 15 },
+ { 16 },
+ { 17 },
+ { 18 },
+ { 19 },
+ /* The remaining relocs are a GNU extension. */
+ HOWTO(R_386_16, 0,1,16,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_16", true,0xffff,0xffff,false),
+ HOWTO(R_386_PC16, 0,1,16,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC16", true,0xffff,0xffff,true),
+ HOWTO(R_386_8, 0,0,8,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_8", true,0xff,0xff,false),
+ HOWTO(R_386_PC8, 0,0,8,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC8", true,0xff,0xff,true),
+};
+
+/* GNU extension to record C++ vtable hierarchy. */
+static reloc_howto_type elf32_i386_vtinherit_howto =
+ HOWTO (R_386_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_386_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false);
+
+/* GNU extension to record C++ vtable member usage. */
+static reloc_howto_type elf32_i386_vtentry_howto =
+ HOWTO (R_386_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_386_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false);
+
+#ifdef DEBUG_GEN_RELOC
+#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
+#else
+#define TRACE(str)
+#endif
+
+static reloc_howto_type *
+elf_i386_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ TRACE ("BFD_RELOC_NONE");
+ return &elf_howto_table[ (int)R_386_NONE ];
+
+ case BFD_RELOC_32:
+ TRACE ("BFD_RELOC_32");
+ return &elf_howto_table[ (int)R_386_32 ];
+
+ case BFD_RELOC_CTOR:
+ TRACE ("BFD_RELOC_CTOR");
+ return &elf_howto_table[ (int)R_386_32 ];
+
+ case BFD_RELOC_32_PCREL:
+ TRACE ("BFD_RELOC_PC32");
+ return &elf_howto_table[ (int)R_386_PC32 ];
+
+ case BFD_RELOC_386_GOT32:
+ TRACE ("BFD_RELOC_386_GOT32");
+ return &elf_howto_table[ (int)R_386_GOT32 ];
+
+ case BFD_RELOC_386_PLT32:
+ TRACE ("BFD_RELOC_386_PLT32");
+ return &elf_howto_table[ (int)R_386_PLT32 ];
+
+ case BFD_RELOC_386_COPY:
+ TRACE ("BFD_RELOC_386_COPY");
+ return &elf_howto_table[ (int)R_386_COPY ];
+
+ case BFD_RELOC_386_GLOB_DAT:
+ TRACE ("BFD_RELOC_386_GLOB_DAT");
+ return &elf_howto_table[ (int)R_386_GLOB_DAT ];
+
+ case BFD_RELOC_386_JUMP_SLOT:
+ TRACE ("BFD_RELOC_386_JUMP_SLOT");
+ return &elf_howto_table[ (int)R_386_JUMP_SLOT ];
+
+ case BFD_RELOC_386_RELATIVE:
+ TRACE ("BFD_RELOC_386_RELATIVE");
+ return &elf_howto_table[ (int)R_386_RELATIVE ];
+
+ case BFD_RELOC_386_GOTOFF:
+ TRACE ("BFD_RELOC_386_GOTOFF");
+ return &elf_howto_table[ (int)R_386_GOTOFF ];
+
+ case BFD_RELOC_386_GOTPC:
+ TRACE ("BFD_RELOC_386_GOTPC");
+ return &elf_howto_table[ (int)R_386_GOTPC ];
+
+ /* The remaining relocs are a GNU extension. */
+ case BFD_RELOC_16:
+ TRACE ("BFD_RELOC_16");
+ return &elf_howto_table[(int) R_386_16];
+
+ case BFD_RELOC_16_PCREL:
+ TRACE ("BFD_RELOC_16_PCREL");
+ return &elf_howto_table[(int) R_386_PC16];
+
+ case BFD_RELOC_8:
+ TRACE ("BFD_RELOC_8");
+ return &elf_howto_table[(int) R_386_8];
+
+ case BFD_RELOC_8_PCREL:
+ TRACE ("BFD_RELOC_8_PCREL");
+ return &elf_howto_table[(int) R_386_PC8];
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ TRACE ("BFD_RELOC_VTABLE_INHERIT");
+ return &elf32_i386_vtinherit_howto;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ TRACE ("BFD_RELOC_VTABLE_ENTRY");
+ return &elf32_i386_vtentry_howto;
+
+ default:
+ break;
+ }
+
+ TRACE ("Unknown");
+ return 0;
+}
+
+static void
+elf_i386_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ abort ();
+}
+
+static void
+elf_i386_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ enum elf_i386_reloc_type type;
+
+ type = (enum elf_i386_reloc_type) ELF32_R_TYPE (dst->r_info);
+ if (type == R_386_GNU_VTINHERIT)
+ cache_ptr->howto = &elf32_i386_vtinherit_howto;
+ else if (type == R_386_GNU_VTENTRY)
+ cache_ptr->howto = &elf32_i386_vtentry_howto;
+ else
+ {
+ BFD_ASSERT (type < R_386_max);
+ BFD_ASSERT (type < FIRST_INVALID_RELOC || type > LAST_INVALID_RELOC);
+ cache_ptr->howto = &elf_howto_table[(int) type];
+ }
+}
+
+/* Return whether a symbol name implies a local label. The UnixWare
+ 2.1 cc generates temporary symbols that start with .X, so we
+ recognize them here. FIXME: do other SVR4 compilers also use .X?.
+ If so, we should move the .X recognition into
+ _bfd_elf_is_local_label_name. */
+
+static boolean
+elf_i386_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ if (name[0] == '.' && name[1] == 'X')
+ return true;
+
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Functions for the i386 ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 16
+
+/* The first entry in an absolute procedure linkage table looks like
+ this. See the SVR4 ABI i386 supplement to see how this works. */
+
+static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0x35, /* pushl contents of address */
+ 0, 0, 0, 0, /* replaced with address of .got + 4. */
+ 0xff, 0x25, /* jmp indirect */
+ 0, 0, 0, 0, /* replaced with address of .got + 8. */
+ 0, 0, 0, 0 /* pad out to 16 bytes. */
+};
+
+/* Subsequent entries in an absolute procedure linkage table look like
+ this. */
+
+static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0x25, /* jmp indirect */
+ 0, 0, 0, 0, /* replaced with address of this symbol in .got. */
+ 0x68, /* pushl immediate */
+ 0, 0, 0, 0, /* replaced with offset into relocation table. */
+ 0xe9, /* jmp relative */
+ 0, 0, 0, 0 /* replaced with offset to start of .plt. */
+};
+
+/* The first entry in a PIC procedure linkage table look like this. */
+
+static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
+ 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
+ 0, 0, 0, 0 /* pad out to 16 bytes. */
+};
+
+/* Subsequent entries in a PIC procedure linkage table look like this. */
+
+static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0xa3, /* jmp *offset(%ebx) */
+ 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
+ 0x68, /* pushl immediate */
+ 0, 0, 0, 0, /* replaced with offset into relocation table. */
+ 0xe9, /* jmp relative */
+ 0, 0, 0, 0 /* replaced with offset to start of .plt. */
+};
+
+/* The i386 linker needs to keep track of the number of relocs that it
+ decides to copy in check_relocs for each symbol. This is so that
+ it can discard PC relative relocs if it doesn't need them when
+ linking with -Bsymbolic. We store the information in a field
+ extending the regular ELF linker hash table. */
+
+/* This structure keeps track of the number of PC relative relocs we
+ have copied for a given symbol. */
+
+struct elf_i386_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_i386_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* i386 ELF linker hash entry. */
+
+struct elf_i386_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct elf_i386_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* i386 ELF linker hash table. */
+
+struct elf_i386_link_hash_table
+{
+ struct elf_link_hash_table root;
+};
+
+/* Declare this now that the above structures are defined. */
+
+static boolean elf_i386_discard_copies
+ PARAMS ((struct elf_i386_link_hash_entry *, PTR));
+
+/* Traverse an i386 ELF linker hash table. */
+
+#define elf_i386_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the i386 ELF linker hash table from a link_info structure. */
+
+#define elf_i386_hash_table(p) \
+ ((struct elf_i386_link_hash_table *) ((p)->hash))
+
+/* Create an entry in an i386 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_i386_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct elf_i386_link_hash_entry *ret =
+ (struct elf_i386_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf_i386_link_hash_entry *) NULL)
+ ret = ((struct elf_i386_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_i386_link_hash_entry)));
+ if (ret == (struct elf_i386_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_i386_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf_i386_link_hash_entry *) NULL)
+ {
+ ret->pcrel_relocs_copied = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an i386 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_i386_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct elf_i386_link_hash_table *ret;
+
+ ret = ((struct elf_i386_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf_i386_link_hash_table)));
+ if (ret == (struct elf_i386_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf_i386_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static boolean
+elf_i386_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+
+ if (info->relocateable)
+ return true;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_offsets = elf_local_got_offsets (abfd);
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_386_GOT32:
+ case R_386_GOTOFF:
+ case R_386_GOTPC:
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_386_GOT32:
+ /* This symbol requires a global offset table entry. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rel.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ h->got.offset = sgot->_raw_size;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ srelgot->_raw_size += sizeof (Elf32_External_Rel);
+ }
+ else
+ {
+ /* This is a global offset table entry for a local
+ symbol. */
+ if (local_got_offsets == NULL)
+ {
+ size_t size;
+ register unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+ if (local_got_offsets == NULL)
+ return false;
+ elf_local_got_offsets (abfd) = local_got_offsets;
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_got_offsets[i] = (bfd_vma) -1;
+ }
+ if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ local_got_offsets[r_symndx] = sgot->_raw_size;
+
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_386_RELATIVE reloc so that the dynamic
+ linker can adjust this GOT entry. */
+ srelgot->_raw_size += sizeof (Elf32_External_Rel);
+ }
+ }
+
+ sgot->_raw_size += 4;
+
+ break;
+
+ case R_386_PLT32:
+ /* This symbol requires a procedure linkage table entry. We
+ actually build the entry in adjust_dynamic_symbol,
+ because this might be a case of linking PIC code which is
+ never referenced by a dynamic object, in which case we
+ don't need to generate a procedure linkage table entry
+ after all. */
+
+ /* If this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (h == NULL)
+ continue;
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+ break;
+
+ case R_386_32:
+ case R_386_PC32:
+ /* If we are creating a shared library, and this is a reloc
+ against a global symbol, or a non PC relative reloc
+ against a local symbol, then we need to copy the reloc
+ into the shared library. However, if we are linking with
+ -Bsymbolic, we do not need to copy a reloc against a
+ global symbol which is defined in an object we are
+ including in the link (i.e., DEF_REGULAR is set). At
+ this point we have not seen all the input files, so it is
+ possible that DEF_REGULAR is not set now but will be set
+ later (it is never cleared). We account for that
+ possibility below by storing information in the
+ pcrel_relocs_copied field of the hash table entry. */
+ if (info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (ELF32_R_TYPE (rel->r_info) != R_386_PC32
+ || (h != NULL
+ && (! info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file. We create a reloc
+ section in dynobj and make room for this reloc. */
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rel", 4) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 4) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ flagword flags;
+
+ sreloc = bfd_make_section (dynobj, name);
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc, flags)
+ || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+ return false;
+ }
+ }
+
+ sreloc->_raw_size += sizeof (Elf32_External_Rel);
+
+ /* If we are linking with -Bsymbolic, and this is a
+ global symbol, we count the number of PC relative
+ relocations we have entered for this symbol, so that
+ we can discard them again if the symbol is later
+ defined by a regular object. Note that this function
+ is only called if we are using an elf_i386 linker
+ hash table, which means that h is really a pointer to
+ an elf_i386_link_hash_entry. */
+ if (h != NULL && info->symbolic
+ && ELF32_R_TYPE (rel->r_info) == R_386_PC32)
+ {
+ struct elf_i386_link_hash_entry *eh;
+ struct elf_i386_pcrel_relocs_copied *p;
+
+ eh = (struct elf_i386_link_hash_entry *) h;
+
+ for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
+ if (p->section == sreloc)
+ break;
+
+ if (p == NULL)
+ {
+ p = ((struct elf_i386_pcrel_relocs_copied *)
+ bfd_alloc (dynobj, sizeof *p));
+ if (p == NULL)
+ return false;
+ p->next = eh->pcrel_relocs_copied;
+ eh->pcrel_relocs_copied = p;
+ p->section = sreloc;
+ p->count = 0;
+ }
+
+ ++p->count;
+ }
+ }
+
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_386_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_386_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf_i386_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_386_GNU_VTINHERIT:
+ case R_386_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ /* ??? It would seem that the existing i386 code does no sort
+ of reference counting or whatnot on its GOT and PLT entries,
+ so it is not possible to garbage collect them at this time. */
+
+ return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+elf_i386_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj;
+ asection *s;
+ unsigned int power_of_two;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later,
+ when we know the address of the .got section. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+ {
+ /* This case can occur if we saw a PLT32 reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object. In such a case, we don't actually need to build
+ a procedure linkage table, and we can just do a PC32
+ reloc instead. */
+ BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ return true;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->_raw_size == 0)
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+ }
+
+ h->plt.offset = s->_raw_size;
+
+ /* Make room for this entry. */
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .got.plt section, which
+ will be placed in the .got section by the linker script. */
+
+ s = bfd_get_section_by_name (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+
+ s = bfd_get_section_by_name (dynobj, ".rel.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += sizeof (Elf32_External_Rel);
+
+ return true;
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (info->shared)
+ return true;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_386_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. We need to remember the offset into the
+ .rel.bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_section_by_name (dynobj, ".rel.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf32_External_Rel);
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ }
+
+ /* We need to figure out the alignment required for this symbol. I
+ have no idea how ELF linkers handle this. */
+ power_of_two = bfd_log2 (h->size);
+ if (power_of_two > 3)
+ power_of_two = 3;
+
+ /* Apply the required alignment. */
+ s->_raw_size = BFD_ALIGN (s->_raw_size,
+ (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ {
+ if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+ return false;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->_raw_size += h->size;
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+elf_i386_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean plt;
+ boolean relocs;
+ boolean reltext;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (! info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+ else
+ {
+ /* We may have created entries in the .rel.got section.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rel.got,
+ which will cause it to get stripped from the output file
+ below. */
+ s = bfd_get_section_by_name (dynobj, ".rel.got");
+ if (s != NULL)
+ s->_raw_size = 0;
+ }
+
+ /* If this is a -Bsymbolic shared link, then we need to discard all
+ PC relative relocs against symbols defined in a regular object.
+ We allocated space for them in the check_relocs routine, but we
+ will not fill them in in the relocate_section routine. */
+ if (info->shared && info->symbolic)
+ elf_i386_link_hash_traverse (elf_i386_hash_table (info),
+ elf_i386_discard_copies,
+ (PTR) NULL);
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ plt = false;
+ relocs = false;
+ reltext = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ strip = false;
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ strip = true;
+ }
+ else
+ {
+ /* Remember whether there is a PLT. */
+ plt = true;
+ }
+ }
+ else if (strncmp (name, ".rel", 4) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rel.bss and
+ .rel.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ strip = true;
+ }
+ else
+ {
+ asection *target;
+
+ /* Remember whether there are any reloc sections other
+ than .rel.plt. */
+ if (strcmp (name, ".rel.plt") != 0)
+ {
+ const char *outname;
+
+ relocs = true;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL
+ entry. The entries in the .rel.plt section
+ really apply to the .got section, which we
+ created ourselves and so know is not readonly. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 4);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ reltext = true;
+ }
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strncmp (name, ".got", 4) != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ _bfd_strip_section_from_output (s);
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_i386_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (! info->shared)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (plt)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ return false;
+ }
+
+ if (relocs)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT,
+ sizeof (Elf32_External_Rel)))
+ return false;
+ }
+
+ if (reltext)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* This function is called via elf_i386_link_hash_traverse if we are
+ creating a shared object with -Bsymbolic. It discards the space
+ allocated to copy PC relative relocs against symbols which are
+ defined in regular objects. We allocated space for them in the
+ check_relocs routine, but we won't fill them in in the
+ relocate_section routine. */
+
+/*ARGSUSED*/
+static boolean
+elf_i386_discard_copies (h, ignore)
+ struct elf_i386_link_hash_entry *h;
+ PTR ignore;
+{
+ struct elf_i386_pcrel_relocs_copied *s;
+
+ /* We only discard relocs for symbols defined in a regular object. */
+ if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ return true;
+
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ s->section->_raw_size -= s->count * sizeof (Elf32_External_Rel);
+
+ return true;
+}
+
+/* Relocate an i386 ELF section. */
+
+static boolean
+elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ asection *sgot;
+ asection *splt;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sgot = NULL;
+ splt = NULL;
+ sreloc = NULL;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_386_GNU_VTINHERIT
+ || r_type == R_386_GNU_VTENTRY)
+ continue;
+ if (r_type < 0
+ || r_type >= (int) R_386_max
+ || (r_type >= (int) FIRST_INVALID_RELOC
+ && r_type <= (int) LAST_INVALID_RELOC))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto = elf_howto_table + r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ bfd_vma val;
+
+ sec = local_sections[r_symndx];
+ val = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ val += sec->output_offset + sym->st_value;
+ bfd_put_32 (input_bfd, val, contents + rel->r_offset);
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if (r_type == R_386_GOTPC
+ || (r_type == R_386_PLT32
+ && h->plt.offset != (bfd_vma) -1)
+ || (r_type == R_386_GOT32
+ && elf_hash_table (info)->dynamic_sections_created
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ && (r_type == R_386_32
+ || r_type == R_386_PC32)
+ && ((input_section->flags & SEC_ALLOC) != 0
+ /* DWARF will emit R_386_32 relocations in its
+ sections against symbols defined externally
+ in shared libraries. We can't do anything
+ with them here. */
+ || (input_section->flags & SEC_DEBUGGING) != 0)))
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ relocation = 0;
+ }
+ else if (sec->output_section == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
+ bfd_get_filename (input_bfd), h->root.root.string,
+ bfd_get_section_name (input_bfd, input_section));
+ relocation = 0;
+ }
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_386_GOT32:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined
+ locally, or the symbol was forced to be local
+ because of a version file. We must initialize
+ this entry in the global offset table. Since the
+ offset must always be a multiple of 4, we use the
+ least significant bit to record whether we have
+ initialized it already.
+
+ When doing a dynamic link, we create a .rel.got
+ relocation entry to initialize the value. This
+ is done in the finish_dynamic_symbol routine. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation,
+ sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use
+ the least significant bit to record whether we have
+ already generated the necessary reloc. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rel outrel;
+
+ srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ (((Elf32_External_Rel *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+
+ break;
+
+ case R_386_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ /* Note that sgot->output_offset is not involved in this
+ calculation. We always want the start of .got. If we
+ defined _GLOBAL_OFFSET_TABLE in a different way, as is
+ permitted by the ABI, we might have to change this
+ calculation. */
+ relocation -= sgot->output_section->vma;
+
+ break;
+
+ case R_386_GOTPC:
+ /* Use global offset table as symbol value. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ relocation = sgot->output_section->vma;
+
+ break;
+
+ case R_386_PLT32:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLT32 reloc again a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+
+ break;
+
+ case R_386_32:
+ case R_386_PC32:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type != R_386_PC32
+ || (h != NULL
+ && h->dynindx != -1
+ && (! info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ {
+ Elf_Internal_Rel outrel;
+ boolean skip, relocate;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rel", 4) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 4) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ {
+ memset (&outrel, 0, sizeof outrel);
+ relocate = false;
+ }
+ else if (r_type == R_386_PC32)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ relocate = false;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32);
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ {
+ relocate = true;
+ outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ relocate = false;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32);
+ }
+ }
+
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ (((Elf32_External_Rel *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ /* If this reloc is against an external symbol, we do
+ not want to fiddle with the addend. Otherwise, we
+ need to include the symbol value so that it becomes
+ an addend for the dynamic reloc. */
+ if (! relocate)
+ continue;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, (bfd_vma) 0);
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgot;
+ asection *srel;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rel rel;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ srel = bfd_get_section_by_name (dynobj, ".rel.plt");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+ /* Get the index in the procedure linkage table which
+ corresponds to this symbol. This is the index of this symbol
+ in all the symbols for which we are making plt entries. The
+ first entry in the procedure linkage table is reserved. */
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
+
+ /* Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is 4 bytes.
+ The first three are reserved. */
+ got_offset = (plt_index + 3) * 4;
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (! info->shared)
+ {
+ memcpy (splt->contents + h->plt.offset, elf_i386_plt_entry,
+ PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset),
+ splt->contents + h->plt.offset + 2);
+ }
+ else
+ {
+ memcpy (splt->contents + h->plt.offset, elf_i386_pic_plt_entry,
+ PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd, got_offset,
+ splt->contents + h->plt.offset + 2);
+ }
+
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
+ splt->contents + h->plt.offset + 7);
+ bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
+ splt->contents + h->plt.offset + 12);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + 6),
+ sgot->contents + got_offset);
+
+ /* Fill in the entry in the .rel.plt section. */
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ ((Elf32_External_Rel *) srel->contents
+ + plt_index));
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srel;
+ Elf_Internal_Rel rel;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srel = bfd_get_section_by_name (dynobj, ".rel.got");
+ BFD_ASSERT (sgot != NULL && srel != NULL);
+
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ 1));
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. Likewise if
+ the symbol was forced to be local because of a version file.
+ The entry in the global offset table will already have been
+ initialized in the relocate_section function. */
+ if (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
+ }
+
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ ((Elf32_External_Rel *) srel->contents
+ + srel->reloc_count));
+ ++srel->reloc_count;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ {
+ asection *s;
+ Elf_Internal_Rel rel;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak));
+
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rel.bss");
+ BFD_ASSERT (s != NULL);
+
+ rel.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ ((Elf32_External_Rel *) s->contents
+ + s->reloc_count));
+ ++s->reloc_count;
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+elf_i386_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *sgot;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ name = ".got";
+ goto get_vma;
+ case DT_JMPREL:
+ name = ".rel.plt";
+ get_vma:
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ s = bfd_get_section_by_name (output_bfd, ".rel.plt");
+ BFD_ASSERT (s != NULL);
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
+ else
+ dyn.d_un.d_val = s->_raw_size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELSZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_REL). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. Therefore, we override the DT_RELSZ entry
+ here to make it not include the JMPREL relocs. Since
+ the linker script arranges for .rel.plt to follow all
+ other relocation sections, we don't have to worry
+ about changing the DT_REL entry. */
+ s = bfd_get_section_by_name (output_bfd, ".rel.plt");
+ if (s != NULL)
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val -= s->_cooked_size;
+ else
+ dyn.d_un.d_val -= s->_raw_size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ if (splt && splt->_raw_size > 0)
+ {
+ if (info->shared)
+ memcpy (splt->contents, elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE);
+ else
+ {
+ memcpy (splt->contents, elf_i386_plt0_entry, PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma + sgot->output_offset + 4,
+ splt->contents + 2);
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma + sgot->output_offset + 8,
+ splt->contents + 8);
+ }
+
+ /* UnixWare sets the entsize of .plt to 4, although that doesn't
+ really seem like the right value. */
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+ }
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->_raw_size > 0)
+ {
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgot->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ return true;
+}
+
+#define TARGET_LITTLE_SYM bfd_elf32_i386_vec
+#define TARGET_LITTLE_NAME "elf32-i386"
+#define ELF_ARCH bfd_arch_i386
+#define ELF_MACHINE_CODE EM_386
+#define ELF_MAXPAGESIZE 0x1000
+#define elf_info_to_howto elf_i386_info_to_howto
+#define elf_info_to_howto_rel elf_i386_info_to_howto_rel
+#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup
+#define bfd_elf32_bfd_is_local_label_name \
+ elf_i386_is_local_label_name
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_i386_link_hash_table_create
+#define elf_backend_check_relocs elf_i386_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ elf_i386_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ elf_i386_size_dynamic_sections
+#define elf_backend_relocate_section elf_i386_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elf_i386_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf_i386_finish_dynamic_sections
+#define elf_backend_gc_mark_hook elf_i386_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_i386_gc_sweep_hook
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 12
+#define elf_backend_plt_header_size PLT_ENTRY_SIZE
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c
new file mode 100644
index 00000000000..a8537a75508
--- /dev/null
+++ b/bfd/elf32-i860.c
@@ -0,0 +1,33 @@
+/* Intel 860 specific support for 32-bit ELF
+ Copyright 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define elf_info_to_howto _bfd_elf_no_info_to_howto
+
+#define TARGET_BIG_SYM bfd_elf32_i860_vec
+#define TARGET_BIG_NAME "elf32-i860"
+#define ELF_ARCH bfd_arch_i860
+#define ELF_MACHINE_CODE EM_860
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
new file mode 100644
index 00000000000..b2f852370e9
--- /dev/null
+++ b/bfd/elf32-m32r.c
@@ -0,0 +1,2082 @@
+/* M32R-specific support for 32-bit ELF.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/m32r.h"
+
+static bfd_reloc_status_type m32r_elf_10_pcrel_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type m32r_elf_do_10_pcrel_reloc
+ PARAMS ((bfd *, reloc_howto_type *, asection *,
+ bfd_byte *, bfd_vma, asection *, bfd_vma, bfd_vma));
+static bfd_reloc_status_type m32r_elf_hi16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static void m32r_elf_relocate_hi16
+ PARAMS ((bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *,
+ bfd_byte *, bfd_vma));
+bfd_reloc_status_type m32r_elf_lo16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type m32r_elf_sda16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void m32r_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+boolean _bfd_m32r_elf_section_from_bfd_section
+ PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *));
+void _bfd_m32r_elf_symbol_processing
+ PARAMS ((bfd *, asymbol *));
+static boolean m32r_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+static boolean m32r_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+#if 0 /* not yet */
+static boolean m32r_elf_relax_delete_bytes
+ PARAMS ((bfd *, asection *, bfd_vma, int));
+#endif
+
+static bfd_reloc_status_type m32r_elf_final_sda_base
+ PARAMS ((bfd *, struct bfd_link_info *, const char **, bfd_vma *));
+static boolean m32r_elf_object_p
+ PARAMS ((bfd *));
+static void m32r_elf_final_write_processing
+ PARAMS ((bfd *, boolean));
+static boolean m32r_elf_set_private_flags
+ PARAMS ((bfd *, flagword));
+static boolean m32r_elf_copy_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean m32r_elf_merge_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean m32r_elf_print_private_bfd_data
+ PARAMS ((bfd *, PTR));
+
+#define NOP_INSN 0x7000
+#define MAKE_PARALLEL(insn) ((insn) | 0x8000)
+
+/* Use REL instead of RELA to save space.
+ This only saves space in libraries and object files, but perhaps
+ relocs will be put in ROM? All in all though, REL relocs are a pain
+ to work with. */
+#define USE_REL
+
+static reloc_howto_type m32r_elf_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_M32R_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_M32R_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_M32R_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 24 bit address. */
+ HOWTO (R_M32R_24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_24", /* name */
+ true, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An PC Relative 10-bit relocation, shifted by 2.
+ This reloc is complicated because relocations are relative to pc & -4.
+ i.e. branches in the right insn slot use the address of the left insn
+ slot for pc. */
+ /* ??? It's not clear whether this should have partial_inplace set or not.
+ Branch relaxing in the assembler can store the addend in the insn,
+ and if bfd_install_relocation gets called the addend may get added
+ again. */
+ HOWTO (R_M32R_10_PCREL, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ m32r_elf_10_pcrel_reloc, /* special_function */
+ "R_M32R_10_PCREL", /* name */
+ false, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 18 bit relocation, right shifted by 2. */
+ HOWTO (R_M32R_18_PCREL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_18_PCREL", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 26 bit relocation, right shifted by 2. */
+ /* ??? It's not clear whether this should have partial_inplace set or not.
+ Branch relaxing in the assembler can store the addend in the insn,
+ and if bfd_install_relocation gets called the addend may get added
+ again. */
+ HOWTO (R_M32R_26_PCREL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_26_PCREL", /* name */
+ false, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* High 16 bits of address when lower 16 is or'd in. */
+ HOWTO (R_M32R_HI16_ULO, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m32r_elf_hi16_reloc, /* special_function */
+ "R_M32R_HI16_ULO", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of address when lower 16 is added in. */
+ HOWTO (R_M32R_HI16_SLO, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m32r_elf_hi16_reloc, /* special_function */
+ "R_M32R_HI16_SLO", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Lower 16 bits of address. */
+ HOWTO (R_M32R_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m32r_elf_lo16_reloc, /* special_function */
+ "R_M32R_LO16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Small data area 16 bits offset. */
+ HOWTO (R_M32R_SDA16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ m32r_elf_sda16_reloc, /* special_function */
+ "R_M32R_SDA16", /* name */
+ true, /* partial_inplace */ /* FIXME: correct? */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_M32R_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_M32R_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_M32R_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_M32R_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+/* Handle the R_M32R_10_PCREL reloc. */
+
+static bfd_reloc_status_type
+m32r_elf_10_pcrel_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd * abfd;
+ arelent * reloc_entry;
+ asymbol * symbol;
+ PTR data;
+ asection * input_section;
+ bfd * output_bfd;
+ char ** error_message;
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ {
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_continue;
+ }
+
+ return m32r_elf_do_10_pcrel_reloc (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ symbol->section,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+/* Utility to actually perform an R_M32R_10_PCREL reloc. */
+
+static bfd_reloc_status_type
+m32r_elf_do_10_pcrel_reloc (abfd, howto, input_section, data, offset,
+ symbol_section, symbol_value, addend)
+ bfd *abfd;
+ reloc_howto_type *howto;
+ asection *input_section;
+ bfd_byte *data;
+ bfd_vma offset;
+ asection *symbol_section;
+ bfd_vma symbol_value;
+ bfd_vma addend;
+{
+ bfd_signed_vma relocation;
+ unsigned long x;
+ bfd_reloc_status_type status;
+
+ /* Sanity check the address (offset in section). */
+ if (offset > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ relocation = symbol_value + addend;
+ /* Make it pc relative. */
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ /* These jumps mask off the lower two bits of the current address
+ before doing pcrel calculations. */
+ relocation -= (offset & -4L);
+
+ if (relocation < -0x200 || relocation > 0x1ff)
+ status = bfd_reloc_overflow;
+ else
+ status = bfd_reloc_ok;
+
+ x = bfd_get_16 (abfd, data + offset);
+ relocation >>= howto->rightshift;
+ relocation <<= howto->bitpos;
+ x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask);
+ bfd_put_16 (abfd, x, data + offset);
+
+ return status;
+}
+
+/* Handle the R_M32R_HI16_[SU]LO relocs.
+ HI16_SLO is for the add3 and load/store with displacement instructions.
+ HI16_ULO is for the or3 instruction.
+ For R_M32R_HI16_SLO, the lower 16 bits are sign extended when added to
+ the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then
+ we must add one to the high 16 bytes (which will get subtracted off when
+ the low 16 bits are added).
+ These relocs have to be done in combination with an R_M32R_LO16 reloc
+ because there is a carry from the LO16 to the HI16. Here we just save
+ the information we need; we do the actual relocation when we see the LO16.
+ This code is copied from the elf32-mips.c. We also support an arbitrary
+ number of HI16 relocs to be associated with a single LO16 reloc. The
+ assembler sorts the relocs to ensure each HI16 immediately precedes its
+ LO16. However if there are multiple copies, the assembler may not find
+ the real LO16 so it picks the first one it finds. */
+
+struct m32r_hi16
+{
+ struct m32r_hi16 *next;
+ bfd_byte *addr;
+ bfd_vma addend;
+};
+
+/* FIXME: This should not be a static variable. */
+
+static struct m32r_hi16 *m32r_hi16_list;
+
+static bfd_reloc_status_type
+m32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ struct m32r_hi16 *n;
+
+ /* This part is from bfd_elf_generic_reloc.
+ If we're relocating, and this an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Sanity check the address (offset in section). */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ ret = bfd_reloc_ok;
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ ret = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ /* Save the information, and let LO16 do the actual relocation. */
+ n = (struct m32r_hi16 *) bfd_malloc (sizeof *n);
+ if (n == NULL)
+ return bfd_reloc_outofrange;
+ n->addr = (bfd_byte *) data + reloc_entry->address;
+ n->addend = relocation;
+ n->next = m32r_hi16_list;
+ m32r_hi16_list = n;
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Handle an M32R ELF HI16 reloc. */
+
+static void
+m32r_elf_relocate_hi16 (input_bfd, type, relhi, rello, contents, addend)
+ bfd *input_bfd;
+ int type;
+ Elf_Internal_Rela *relhi;
+ Elf_Internal_Rela *rello;
+ bfd_byte *contents;
+ bfd_vma addend;
+{
+ unsigned long insn;
+ bfd_vma addlo;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ addlo = bfd_get_32 (input_bfd, contents + rello->r_offset);
+ if (type == R_M32R_HI16_SLO)
+ addlo = ((addlo & 0xffff) ^ 0x8000) - 0x8000;
+ else
+ addlo &= 0xffff;
+
+ addend += ((insn & 0xffff) << 16) + addlo;
+
+ /* Reaccount for sign extension of low part. */
+ if (type == R_M32R_HI16_SLO
+ && (addend & 0x8000) != 0)
+ addend += 0x10000;
+
+ bfd_put_32 (input_bfd,
+ (insn & 0xffff0000) | ((addend >> 16) & 0xffff),
+ contents + relhi->r_offset);
+}
+
+/* Do an R_M32R_LO16 relocation. This is a straightforward 16 bit
+ inplace relocation; this function exists in order to do the
+ R_M32R_HI16_[SU]LO relocation described above. */
+
+bfd_reloc_status_type
+m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (m32r_hi16_list != NULL)
+ {
+ struct m32r_hi16 *l;
+
+ l = m32r_hi16_list;
+ while (l != NULL)
+ {
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+ struct m32r_hi16 *next;
+
+ /* Do the HI16 relocation. Note that we actually don't need
+ to know anything about the LO16 itself, except where to
+ find the low 16 bits of the addend needed by the LO16. */
+ insn = bfd_get_32 (abfd, l->addr);
+ vallo = ((bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
+ & 0xffff) ^ 0x8000) - 0x8000;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += l->addend;
+
+ /* Reaccount for sign extension of low part. */
+ if ((val & 0x8000) != 0)
+ val += 0x10000;
+
+ insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (abfd, insn, l->addr);
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ m32r_hi16_list = NULL;
+ }
+
+ /* Now do the LO16 reloc in the usual way. */
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* Handle the R_M32R_SDA16 reloc.
+ This reloc is used to compute the address of objects in the small data area
+ and to perform loads and stores from that area.
+ The lower 16 bits are sign extended and added to the register specified
+ in the instruction, which is assumed to point to _SDA_BASE_. */
+
+static bfd_reloc_status_type
+m32r_elf_sda16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ {
+ /* FIXME: See bfd_perform_relocation. Is this right? */
+ return bfd_reloc_continue;
+ }
+
+ /* FIXME: not sure what to do here yet. But then again, the linker
+ may never call us. */
+ abort ();
+}
+
+/* Map BFD reloc types to M32R ELF reloc types. */
+
+struct m32r_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct m32r_reloc_map m32r_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_M32R_NONE },
+ { BFD_RELOC_16, R_M32R_16 },
+ { BFD_RELOC_32, R_M32R_32 },
+ { BFD_RELOC_M32R_24, R_M32R_24 },
+ { BFD_RELOC_M32R_10_PCREL, R_M32R_10_PCREL },
+ { BFD_RELOC_M32R_18_PCREL, R_M32R_18_PCREL },
+ { BFD_RELOC_M32R_26_PCREL, R_M32R_26_PCREL },
+ { BFD_RELOC_M32R_HI16_ULO, R_M32R_HI16_ULO },
+ { BFD_RELOC_M32R_HI16_SLO, R_M32R_HI16_SLO },
+ { BFD_RELOC_M32R_LO16, R_M32R_LO16 },
+ { BFD_RELOC_M32R_SDA16, R_M32R_SDA16 },
+ { BFD_RELOC_VTABLE_INHERIT, R_M32R_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_M32R_GNU_VTENTRY },
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (m32r_reloc_map) / sizeof (struct m32r_reloc_map);
+ i++)
+ {
+ if (m32r_reloc_map[i].bfd_reloc_val == code)
+ return &m32r_elf_howto_table[m32r_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an M32R ELF reloc. */
+
+static void
+m32r_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_M32R_max);
+ cache_ptr->howto = &m32r_elf_howto_table[r_type];
+}
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. */
+
+boolean
+_bfd_m32r_elf_section_from_bfd_section (abfd, hdr, sec, retval)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+ asection *sec;
+ int *retval;
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+ {
+ *retval = SHN_M32R_SCOMMON;
+ return true;
+ }
+ return false;
+}
+
+/* M32R ELF uses two common sections. One is the usual one, and the other
+ is for small objects. All the small objects are kept together, and then
+ referenced via one register, which yields faster assembler code. It is
+ up to the compiler to emit an instruction to load the register with
+ _SDA_BASE. This is what we use for the small common section. This
+ approach is copied from elf32-mips.c. */
+static asection m32r_elf_scom_section;
+static asymbol m32r_elf_scom_symbol;
+static asymbol *m32r_elf_scom_symbol_ptr;
+
+/* Handle the special M32R section numbers that a symbol may use. */
+
+void
+_bfd_m32r_elf_symbol_processing (abfd, asym)
+ bfd *abfd;
+ asymbol *asym;
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_M32R_SCOMMON:
+ if (m32r_elf_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ m32r_elf_scom_section.name = ".scommon";
+ m32r_elf_scom_section.flags = SEC_IS_COMMON;
+ m32r_elf_scom_section.output_section = &m32r_elf_scom_section;
+ m32r_elf_scom_section.symbol = &m32r_elf_scom_symbol;
+ m32r_elf_scom_section.symbol_ptr_ptr = &m32r_elf_scom_symbol_ptr;
+ m32r_elf_scom_symbol.name = ".scommon";
+ m32r_elf_scom_symbol.flags = BSF_SECTION_SYM;
+ m32r_elf_scom_symbol.section = &m32r_elf_scom_section;
+ m32r_elf_scom_symbol_ptr = &m32r_elf_scom_symbol;
+ }
+ asym->section = &m32r_elf_scom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+ }
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must handle the special M32R section numbers here.
+ We also keep watching for whether we need to create the sdata special
+ linker sections. */
+
+static boolean
+m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ if (! info->relocateable
+ && (*namep)[0] == '_' && (*namep)[1] == 'S'
+ && strcmp (*namep, "_SDA_BASE_") == 0)
+ {
+ /* This is simpler than using _bfd_elf_create_linker_section
+ (our needs are simpler than ppc's needs). Also
+ _bfd_elf_create_linker_section currently has a bug where if a .sdata
+ section already exists a new one is created that follows it which
+ screws of _SDA_BASE_ address calcs because output_offset != 0. */
+ struct elf_link_hash_entry *h;
+ asection *s = bfd_get_section_by_name (abfd, ".sdata");
+
+ /* The following code was cobbled from elf32-ppc.c and elflink.c. */
+
+ if (s == NULL)
+ {
+ int flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+
+ s = bfd_make_section_anyway (abfd, ".sdata");
+ if (s == NULL)
+ return false;
+ bfd_set_section_flags (abfd, s, flags);
+ bfd_set_section_alignment (abfd, s, 2);
+ }
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, "_SDA_BASE_", false, false, false);
+
+ if ((h == NULL || h->root.type == bfd_link_hash_undefined)
+ && !(_bfd_generic_link_add_one_symbol (info,
+ abfd,
+ "_SDA_BASE_",
+ BSF_GLOBAL,
+ s,
+ 32768,
+ (const char *) NULL,
+ false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->type = STT_OBJECT;
+ }
+
+ switch (sym->st_shndx)
+ {
+ case SHN_M32R_SCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".scommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return true;
+}
+
+/* We have to figure out the SDA_BASE value, so that we can adjust the
+ symbol value correctly. We look up the symbol _SDA_BASE_ in the output
+ BFD. If we can't find it, we're stuck. We cache it in the ELF
+ target data. We don't need to adjust the symbol value for an
+ external symbol if we are producing relocateable output. */
+
+static bfd_reloc_status_type
+m32r_elf_final_sda_base (output_bfd, info, error_message, psb)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ const char **error_message;
+ bfd_vma *psb;
+{
+ if (elf_gp (output_bfd) == 0)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_defined)
+ elf_gp (output_bfd) = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ else
+ {
+ /* Only get the error once. */
+ *psb = elf_gp (output_bfd) = 4;
+ *error_message =
+ (const char *) _("SDA relocation when _SDA_BASE_ not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+ *psb = elf_gp (output_bfd);
+ return bfd_reloc_ok;
+}
+
+/* Relocate an M32R/D ELF section.
+ There is some attempt to make this function usable for many architectures,
+ both USE_REL and USE_RELA ['twould be nice if such a critter existed],
+ if only to serve as a learning tool.
+
+ The RELOCATE_SECTION function is called by the new ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjust the section contents as
+ necessary, and (if using Rela relocs and generating a
+ relocateable output file) adjusting the reloc addend as
+ necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+
+static boolean
+m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+ Elf_Internal_Rela *rel, *relend;
+ /* Assume success. */
+ boolean ret = true;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ /* We can't modify r_addend here as elf_link_input_bfd has an assert to
+ ensure it's zero (we use REL relocs, not RELA). Therefore this
+ should be assigning zero to `addend', but for clarity we use
+ `r_addend'. */
+ bfd_vma addend = rel->r_addend;
+ bfd_vma offset = rel->r_offset;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ const char *sym_name;
+ bfd_reloc_status_type r;
+ const char *errmsg = NULL;
+
+ h = NULL;
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_M32R_max)
+ {
+ (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
+ bfd_get_filename (input_bfd),
+ (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+ }
+
+ if (r_type == R_M32R_GNU_VTENTRY
+ || r_type == R_M32R_GNU_VTINHERIT)
+ continue;
+
+ howto = m32r_elf_howto_table + r_type;
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ sec = NULL;
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ /* External symbol. */
+ continue;
+ }
+
+ /* Local symbol. */
+ sym = local_syms + r_symndx;
+ sym_name = "<local symbol>";
+ /* STT_SECTION: symbol is associated with a section. */
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ {
+ /* Symbol isn't associated with a section. Nothing to do. */
+ continue;
+ }
+
+ sec = local_sections[r_symndx];
+ addend += sec->output_offset + sym->st_value;
+#ifndef USE_REL
+ /* This can't be done for USE_REL because it doesn't mean anything
+ and elf_link_input_bfd asserts this stays zero. */
+ rel->r_addend = addend;
+#endif
+
+#ifndef USE_REL
+ /* Addends are stored with relocs. We're done. */
+ continue;
+#else /* USE_REL */
+ /* If partial_inplace, we need to store any additional addend
+ back in the section. */
+ if (! howto->partial_inplace)
+ continue;
+ /* ??? Here is a nice place to call a special_function
+ like handler. */
+ if (r_type != R_M32R_HI16_SLO && r_type != R_M32R_HI16_ULO)
+ r = _bfd_relocate_contents (howto, input_bfd,
+ addend, contents + offset);
+ else
+ {
+ Elf_Internal_Rela *lorel;
+
+ /* We allow an arbitrary number of HI16 relocs before the
+ LO16 reloc. This permits gcc to emit the HI and LO relocs
+ itself. */
+ for (lorel = rel + 1;
+ (lorel < relend
+ && (ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_SLO
+ || ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_ULO));
+ lorel++)
+ continue;
+ if (lorel < relend
+ && ELF32_R_TYPE (lorel->r_info) == R_M32R_LO16)
+ {
+ m32r_elf_relocate_hi16 (input_bfd, r_type, rel, lorel,
+ contents, addend);
+ r = bfd_reloc_ok;
+ }
+ else
+ r = _bfd_relocate_contents (howto, input_bfd,
+ addend, contents + offset);
+ }
+#endif /* USE_REL */
+ }
+ else
+ {
+ bfd_vma relocation;
+
+ /* This is a final link. */
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = "<local symbol>";
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ /* External symbol. */
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ sym_name = h->root.root.string;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if (sec->output_section == NULL)
+ relocation = 0;
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ /* Sanity check the address. */
+ if (offset > input_section->_raw_size)
+ {
+ r = bfd_reloc_outofrange;
+ goto check_reloc;
+ }
+
+ switch ((int) r_type)
+ {
+ case (int) R_M32R_10_PCREL :
+ r = m32r_elf_do_10_pcrel_reloc (input_bfd, howto, input_section,
+ contents, offset,
+ sec, relocation, addend);
+ break;
+
+ case (int) R_M32R_HI16_SLO :
+ case (int) R_M32R_HI16_ULO :
+ {
+ Elf_Internal_Rela *lorel;
+
+ /* We allow an arbitrary number of HI16 relocs before the
+ LO16 reloc. This permits gcc to emit the HI and LO relocs
+ itself. */
+ for (lorel = rel + 1;
+ (lorel < relend
+ && (ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_SLO
+ || ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_ULO));
+ lorel++)
+ continue;
+ if (lorel < relend
+ && ELF32_R_TYPE (lorel->r_info) == R_M32R_LO16)
+ {
+ m32r_elf_relocate_hi16 (input_bfd, r_type, rel, lorel,
+ contents, relocation + addend);
+ r = bfd_reloc_ok;
+ }
+ else
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, offset,
+ relocation, addend);
+ }
+ break;
+
+ case (int) R_M32R_SDA16 :
+ {
+ const char *name;
+
+ BFD_ASSERT (sec != NULL);
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0
+ || strcmp (name, ".scommon") == 0)
+ {
+ bfd_vma sda_base;
+ bfd *out_bfd = sec->output_section->owner;
+
+ r = m32r_elf_final_sda_base (out_bfd, info,
+ &errmsg,
+ &sda_base);
+ if (r != bfd_reloc_ok)
+ {
+ ret = false;
+ goto check_reloc;
+ }
+
+ /* At this point `relocation' contains the object's
+ address. */
+ relocation -= sda_base;
+ /* Now it contains the offset from _SDA_BASE_. */
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
+ bfd_get_filename (input_bfd),
+ sym_name,
+ m32r_elf_howto_table[(int) r_type].name,
+ bfd_get_section_name (abfd, sec));
+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
+ ret = false;
+ continue;
+ }
+ }
+ /* fall through */
+
+ default :
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, offset,
+ relocation, addend);
+ break;
+ }
+ }
+
+ check_reloc:
+
+ if (r != bfd_reloc_ok)
+ {
+ /* FIXME: This should be generic enough to go in a utility. */
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ if (errmsg != NULL)
+ goto common_error;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, offset)))
+ return false;
+ break;
+
+ case bfd_reloc_undefined:
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ offset)))
+ return false;
+ break;
+
+ case bfd_reloc_outofrange:
+ errmsg = _("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ errmsg = _("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ errmsg = _("internal error: dangerous error");
+ goto common_error;
+
+ default:
+ errmsg = _("internal error: unknown error");
+ /* fall through */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, errmsg, name, input_bfd, input_section,
+ offset)))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#if 0 /* relaxing not supported yet */
+
+/* This function handles relaxing for the m32r.
+ Relaxing on the m32r is tricky because of instruction alignment
+ requirements (4 byte instructions must be aligned on 4 byte boundaries).
+
+ The following relaxing opportunities are handled:
+
+ seth/add3/jl -> bl24 or bl8
+ seth/add3 -> ld24
+
+ It would be nice to handle bl24 -> bl8 but given:
+
+ - 4 byte insns must be on 4 byte boundaries
+ - branch instructions only branch to insns on 4 byte boundaries
+
+ this isn't much of a win because the insn in the 2 "deleted" bytes
+ must become a nop. With some complexity some real relaxation could be
+ done but the frequency just wouldn't make it worth it; it's better to
+ try to do all the code compaction one can elsewhere.
+ When the chip supports parallel 16 bit insns, things may change.
+*/
+
+static boolean
+m32r_elf_relax_section (abfd, sec, link_info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ /* The Rela structures are used here because that's what
+ _bfd_elf32_link_read_relocs uses [for convenience - it sets the addend
+ field to 0]. */
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+ Elf32_External_Sym *extsyms = NULL;
+ Elf32_External_Sym *free_extsyms = NULL;
+
+ /* Assume nothing changes. */
+ *again = false;
+
+ /* We don't have to do anything for a relocateable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocateable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0
+ || 0 /* FIXME: check SHF_M32R_CAN_RELAX */)
+ return true;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_M32R_HI16_SLO)
+ continue;
+
+ /* Get the section contents if we haven't done so already. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (extsyms == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ /* Go get them off disk. */
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym isym;
+ asection *sym_sec;
+
+ /* A local symbol. */
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irel->r_info),
+ &isym);
+
+ sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ symval = (isym.st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ /* Try to change a seth/add3/jl subroutine call to bl24 or bl8.
+ This sequence is generated by the compiler when compiling in
+ 32 bit mode. Also look for seth/add3 -> ld24. */
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_M32R_HI16_SLO)
+ {
+ Elf_Internal_Rela *nrel;
+ bfd_vma pc = (sec->output_section->vma + sec->output_offset
+ + irel->r_offset);
+ bfd_signed_vma pcrel_value = symval - pc;
+ unsigned int code,reg;
+ int addend,nop_p,bl8_p,to_delete;
+
+ /* The tests are ordered so that we get out as quickly as possible
+ if this isn't something we can relax, taking into account that
+ we are looking for two separate possibilities (jl/ld24). */
+
+ /* Do nothing if no room in the section for this to be what we're
+ looking for. */
+ if (irel->r_offset > sec->_cooked_size - 8)
+ continue;
+
+ /* Make sure the next relocation applies to the next
+ instruction and that it's the add3's reloc. */
+ nrel = irel + 1;
+ if (nrel == irelend
+ || irel->r_offset + 4 != nrel->r_offset
+ || ELF32_R_TYPE (nrel->r_info) != (int) R_M32R_LO16)
+ continue;
+
+ /* See if the instructions are seth/add3. */
+ /* FIXME: This is where macros from cgen can come in. */
+ code = bfd_get_16 (abfd, contents + irel->r_offset + 0);
+ if ((code & 0xf0ff) != 0xd0c0)
+ continue; /* not seth rN,foo */
+ reg = (code & 0x0f00) >> 8;
+ code = bfd_get_16 (abfd, contents + irel->r_offset + 4);
+ if (code != (0x80a0 | reg | (reg << 8)))
+ continue; /* not add3 rN,rN,foo */
+
+ /* At this point we've confirmed we have seth/add3. Now check
+ whether the next insn is a jl, in which case try to change this
+ to bl24 or bl8. */
+
+ /* Ensure the branch target is in range.
+ The bl24 instruction has a 24 bit operand which is the target
+ address right shifted by 2, giving a signed range of 26 bits.
+ Note that 4 bytes are added to the high value because the target
+ will be at least 4 bytes closer if we can relax. It'll actually
+ be 4 or 8 bytes closer, but we don't know which just yet and
+ the difference isn't significant enough to worry about. */
+#ifndef USE_REL /* put in for learning purposes */
+ pcrel_value += irel->r_addend;
+#else
+ addend = bfd_get_signed_16 (abfd, contents + irel->r_offset + 2);
+ pcrel_value += addend;
+#endif
+
+ if (pcrel_value >= -(1 << 25) && pcrel_value < (1 << 25) + 4
+ /* Do nothing if no room in the section for this to be what we're
+ looking for. */
+ && (irel->r_offset <= sec->_cooked_size - 12)
+ /* Ensure the next insn is "jl rN". */
+ && ((code = bfd_get_16 (abfd, contents + irel->r_offset + 8)),
+ code != (0x1ec0 | reg)))
+ {
+ /* We can relax to bl24/bl8. */
+
+ /* See if there's a nop following the jl.
+ Also see if we can use a bl8 insn. */
+ code = bfd_get_16 (abfd, contents + irel->r_offset + 10);
+ nop_p = (code & 0x7fff) == NOP_INSN;
+ bl8_p = pcrel_value >= -0x200 && pcrel_value < 0x200;
+
+ if (bl8_p)
+ {
+ /* Change "seth rN,foo" to "bl8 foo || nop".
+ We OR in CODE just in case it's not a nop (technically,
+ CODE currently must be a nop, but for cleanness we
+ allow it to be anything). */
+#ifndef USE_REL /* put in for learning purposes */
+ code = 0x7e000000 | MAKE_PARALLEL (code);
+#else
+ code = (0x7e000000 + (((addend >> 2) & 0xff) << 16)) | MAKE_PARALLEL (code);
+#endif
+ to_delete = 8;
+ }
+ else
+ {
+ /* Change the seth rN,foo to a bl24 foo. */
+#ifndef USE_REL /* put in for learning purposes */
+ code = 0xfe000000;
+#else
+ code = 0xfe000000 + ((addend >> 2) & 0xffffff);
+#endif
+ to_delete = nop_p ? 8 : 4;
+ }
+
+ bfd_put_32 (abfd, code, contents + irel->r_offset);
+
+ /* Set the new reloc type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
+ bl8_p ? R_M32R_10_PCREL : R_M32R_26_PCREL);
+
+ /* Delete the add3 reloc by making it a null reloc. */
+ nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
+ R_M32R_NONE);
+ }
+ else if (addend >= 0
+ && symval + addend <= 0xffffff)
+ {
+ /* We can relax to ld24. */
+
+ code = 0xe0000000 | (reg << 24) | (addend & 0xffffff);
+ bfd_put_32 (abfd, code, contents + irel->r_offset);
+ to_delete = 4;
+ /* Tell the following code a nop filler isn't needed. */
+ nop_p = 1;
+ }
+ else
+ {
+ /* Can't do anything here. */
+ continue;
+ }
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Delete TO_DELETE bytes of data. */
+ if (!m32r_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, to_delete))
+ goto error_return;
+
+ /* Now that the following bytes have been moved into place, see if
+ we need to replace the jl with a nop. This happens when we had
+ to use a bl24 insn and the insn following the jl isn't a nop.
+ Technically, this situation can't happen (since the insn can
+ never be executed) but to be clean we do this. When the chip
+ supports parallel 16 bit insns things may change.
+ We don't need to do this in the case of relaxing to ld24,
+ and the above code sets nop_p so this isn't done. */
+ if (! nop_p && to_delete == 4)
+ bfd_put_16 (abfd, NOP_INSN, contents + irel->r_offset + 4);
+
+ /* That will change things, so we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = true;
+
+ continue;
+ }
+
+ /* loop to try the next reloc */
+ }
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ free_extsyms = NULL;
+ }
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (free_extsyms != NULL)
+ free (free_extsyms);
+ return false;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static boolean
+m32r_elf_relax_delete_bytes (abfd, sec, addr, count)
+ bfd *abfd;
+ asection *sec;
+ bfd_vma addr;
+ int count;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf32_External_Sym *extsyms;
+ int shndx, index;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf32_External_Sym *esym, *esymend;
+ struct elf_link_hash_entry *sym_hash;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ toaddr = sec->_cooked_size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+ sec->_cooked_size -= count;
+
+ /* Adjust all the relocs. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+
+ if (isym.st_shndx == shndx
+ && isym.st_value > addr
+ && isym.st_value < toaddr)
+ {
+ isym.st_value -= count;
+ bfd_elf32_swap_symbol_out (abfd, &isym, esym);
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ esym = extsyms + symtab_hdr->sh_info;
+ esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
+ for (index = 0; esym < esymend; esym++, index++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+ sym_hash = elf_sym_hashes (abfd)[index];
+ if (isym.st_shndx == shndx
+ && ((sym_hash)->root.type == bfd_link_hash_defined
+ || (sym_hash)->root.type == bfd_link_hash_defweak)
+ && (sym_hash)->root.u.def.section == sec
+ && (sym_hash)->root.u.def.value > addr
+ && (sym_hash)->root.u.def.value < toaddr)
+ {
+ (sym_hash)->root.u.def.value -= count;
+ }
+ }
+
+ return true;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses m32r_elf_relocate_section. */
+
+static bfd_byte *
+m32r_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *input_section = link_order->u.indirect.section;
+ bfd *input_bfd = input_section->owner;
+ asection **sections = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf32_External_Sym *external_syms = NULL;
+ Elf_Internal_Sym *internal_syms = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocateable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocateable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ input_section->_raw_size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isymp;
+ asection **secpp;
+ Elf32_External_Sym *esym, *esymend;
+
+ if (symtab_hdr->contents != NULL)
+ external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ external_syms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf32_External_Sym)));
+ if (external_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (external_syms, sizeof (Elf32_External_Sym),
+ symtab_hdr->sh_info, input_bfd)
+ != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
+ goto error_return;
+ }
+
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (input_bfd, input_section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL, false));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ internal_syms = ((Elf_Internal_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf_Internal_Sym)));
+ if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ sections = (asection **) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (asection *));
+ if (sections == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ isymp = internal_syms;
+ secpp = sections;
+ esym = external_syms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; ++esym, ++isymp, ++secpp)
+ {
+ asection *isec;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
+
+ if (isymp->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
+ isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+ else if (isymp->st_shndx == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isymp->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else if (isymp->st_shndx == SHN_M32R_SCOMMON)
+ isec = &m32r_elf_scom_section;
+ else
+ {
+ /* Who knows? */
+ isec = NULL;
+ }
+
+ *secpp = isec;
+ }
+
+ if (! m32r_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ internal_syms, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ sections = NULL;
+ if (internal_syms != NULL)
+ free (internal_syms);
+ internal_syms = NULL;
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ external_syms = NULL;
+ if (internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+ }
+
+ return data;
+
+ error_return:
+ if (internal_relocs != NULL
+ && internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ if (internal_syms != NULL)
+ free (internal_syms);
+ if (sections != NULL)
+ free (sections);
+ return NULL;
+}
+
+#endif /* #if 0 */
+
+/* Set the right machine number. */
+static boolean
+m32r_elf_object_p (abfd)
+ bfd *abfd;
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_M32R_ARCH)
+ {
+ default:
+ case E_M32R_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_m32r, bfd_mach_m32r); break;
+ }
+ return true;
+}
+
+/* Store the machine number in the flags field. */
+static void
+m32r_elf_final_write_processing (abfd, linker)
+ bfd * abfd;
+ boolean linker;
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_m32r: val = E_M32R_ARCH; break;
+ }
+
+ elf_elfheader (abfd)->e_flags &=~ EF_M32R_ARCH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+/* Function to keep M32R specific file flags. */
+static boolean
+m32r_elf_set_private_flags (abfd, flags)
+ bfd * abfd;
+ flagword flags;
+{
+ BFD_ASSERT (!elf_flags_init (abfd)
+ || elf_elfheader (abfd)->e_flags == flags);
+
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ return true;
+}
+
+/* Copy backend specific data from one object module to another */
+static boolean
+m32r_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || (elf_elfheader (obfd)->e_flags
+ == elf_elfheader (ibfd)->e_flags));
+
+ elf_gp (obfd) = elf_gp (ibfd);
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static boolean
+m32r_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ flagword out_flags;
+ flagword in_flags;
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd))
+ {
+ /* If the input is the default architecture then do not
+ bother setting the flags for the output architecture,
+ instead allow future merges to do this. If no future
+ merges ever set these flags then they will retain their
+ unitialised values, which surprise surprise, correspond
+ to the default values. */
+ if (bfd_get_arch_info (ibfd)->the_default)
+ return true;
+
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = in_flags;
+
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
+ && bfd_get_arch_info (obfd)->the_default)
+ {
+ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
+ }
+
+ return true;
+ }
+
+ /* Check flag compatibility. */
+ if (in_flags == out_flags)
+ return true;
+
+ if ((in_flags & EF_M32R_ARCH) != (out_flags & EF_M32R_ARCH))
+ {
+ if ((in_flags & EF_M32R_ARCH) != E_M32R_ARCH)
+ {
+ _bfd_error_handler (_("%s: Instruction set mismatch with previous modules"),
+ bfd_get_filename (ibfd));
+
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Display the flags field */
+static boolean
+m32r_elf_print_private_bfd_data (abfd, ptr)
+ bfd * abfd;
+ PTR ptr;
+{
+ FILE * file = (FILE *) ptr;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL)
+
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ fprintf (file, _("private flags = %lx"), elf_elfheader (abfd)->e_flags);
+
+ switch (elf_elfheader (abfd)->e_flags & EF_M32R_ARCH)
+ {
+ default:
+ case E_M32R_ARCH: fprintf (file, _(": m32r instructions")); break;
+ }
+
+ fputc ('\n', file);
+
+ return true;
+}
+
+asection *
+m32r_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_M32R_GNU_VTINHERIT:
+ case R_M32R_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+ return NULL;
+}
+
+static boolean
+m32r_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ /* we don't use got and plt entries for m32r */
+ return true;
+}
+
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+m32r_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_M32R_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_M32R_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+#define ELF_ARCH bfd_arch_m32r
+#define ELF_MACHINE_CODE EM_CYGNUS_M32R
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM bfd_elf32_m32r_vec
+#define TARGET_BIG_NAME "elf32-m32r"
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel m32r_info_to_howto_rel
+#define elf_backend_section_from_bfd_section _bfd_m32r_elf_section_from_bfd_section
+#define elf_backend_symbol_processing _bfd_m32r_elf_symbol_processing
+#define elf_backend_add_symbol_hook m32r_elf_add_symbol_hook
+#define elf_backend_relocate_section m32r_elf_relocate_section
+#define elf_backend_gc_mark_hook m32r_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook m32r_elf_gc_sweep_hook
+#define elf_backend_check_relocs m32r_elf_check_relocs
+
+#define elf_backend_can_gc_sections 1
+#if 0 /* not yet */
+/* relax support */
+#define bfd_elf32_bfd_relax_section m32r_elf_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ m32r_elf_get_relocated_section_contents
+#endif
+
+#define elf_backend_object_p m32r_elf_object_p
+#define elf_backend_final_write_processing m32r_elf_final_write_processing
+#define bfd_elf32_bfd_copy_private_bfd_data m32r_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data m32r_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags m32r_elf_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data m32r_elf_print_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
new file mode 100644
index 00000000000..2d0aba210fb
--- /dev/null
+++ b/bfd/elf32-m68k.c
@@ -0,0 +1,2128 @@
+/* Motorola 68k series support for 32-bit ELF
+ Copyright 1993, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/m68k.h"
+
+static reloc_howto_type *reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void rtype_to_howto
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static struct bfd_hash_entry *elf_m68k_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *elf_m68k_link_hash_table_create
+ PARAMS ((bfd *));
+static boolean elf_m68k_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static asection *elf_m68k_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static boolean elf_m68k_gc_sweep_hook
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static boolean elf_m68k_adjust_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean elf_m68k_adjust_dynindx
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_m68k_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf_m68k_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean elf_m68k_finish_dynamic_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+static boolean elf_m68k_finish_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+static reloc_howto_type howto_table[] = {
+ HOWTO(R_68K_NONE, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_NONE", false, 0, 0x00000000,false),
+ HOWTO(R_68K_32, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32", false, 0, 0xffffffff,false),
+ HOWTO(R_68K_16, 0, 1,16, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16", false, 0, 0x0000ffff,false),
+ HOWTO(R_68K_8, 0, 0, 8, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8", false, 0, 0x000000ff,false),
+ HOWTO(R_68K_PC32, 0, 2,32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PC32", false, 0, 0xffffffff,true),
+ HOWTO(R_68K_PC16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC16", false, 0, 0x0000ffff,true),
+ HOWTO(R_68K_PC8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC8", false, 0, 0x000000ff,true),
+ HOWTO(R_68K_GOT32, 0, 2,32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32", false, 0, 0xffffffff,true),
+ HOWTO(R_68K_GOT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16", false, 0, 0x0000ffff,true),
+ HOWTO(R_68K_GOT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8", false, 0, 0x000000ff,true),
+ HOWTO(R_68K_GOT32O, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32O", false, 0, 0xffffffff,false),
+ HOWTO(R_68K_GOT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16O", false, 0, 0x0000ffff,false),
+ HOWTO(R_68K_GOT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8O", false, 0, 0x000000ff,false),
+ HOWTO(R_68K_PLT32, 0, 2,32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32", false, 0, 0xffffffff,true),
+ HOWTO(R_68K_PLT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16", false, 0, 0x0000ffff,true),
+ HOWTO(R_68K_PLT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8", false, 0, 0x000000ff,true),
+ HOWTO(R_68K_PLT32O, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32O", false, 0, 0xffffffff,false),
+ HOWTO(R_68K_PLT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16O", false, 0, 0x0000ffff,false),
+ HOWTO(R_68K_PLT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8O", false, 0, 0x000000ff,false),
+ HOWTO(R_68K_COPY, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_COPY", false, 0, 0xffffffff,false),
+ HOWTO(R_68K_GLOB_DAT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_GLOB_DAT", false, 0, 0xffffffff,false),
+ HOWTO(R_68K_JMP_SLOT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_JMP_SLOT", false, 0, 0xffffffff,false),
+ HOWTO(R_68K_RELATIVE, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_RELATIVE", false, 0, 0xffffffff,false),
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_68K_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_68K_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false),
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_68K_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_68K_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false),
+};
+
+static void
+rtype_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf_Internal_Rela *dst;
+{
+ BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K_max);
+ cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
+}
+
+#define elf_info_to_howto rtype_to_howto
+
+static const struct
+{
+ bfd_reloc_code_real_type bfd_val;
+ int elf_val;
+} reloc_map[] = {
+ { BFD_RELOC_NONE, R_68K_NONE },
+ { BFD_RELOC_32, R_68K_32 },
+ { BFD_RELOC_16, R_68K_16 },
+ { BFD_RELOC_8, R_68K_8 },
+ { BFD_RELOC_32_PCREL, R_68K_PC32 },
+ { BFD_RELOC_16_PCREL, R_68K_PC16 },
+ { BFD_RELOC_8_PCREL, R_68K_PC8 },
+ { BFD_RELOC_32_GOT_PCREL, R_68K_GOT32 },
+ { BFD_RELOC_16_GOT_PCREL, R_68K_GOT16 },
+ { BFD_RELOC_8_GOT_PCREL, R_68K_GOT8 },
+ { BFD_RELOC_32_GOTOFF, R_68K_GOT32O },
+ { BFD_RELOC_16_GOTOFF, R_68K_GOT16O },
+ { BFD_RELOC_8_GOTOFF, R_68K_GOT8O },
+ { BFD_RELOC_32_PLT_PCREL, R_68K_PLT32 },
+ { BFD_RELOC_16_PLT_PCREL, R_68K_PLT16 },
+ { BFD_RELOC_8_PLT_PCREL, R_68K_PLT8 },
+ { BFD_RELOC_32_PLTOFF, R_68K_PLT32O },
+ { BFD_RELOC_16_PLTOFF, R_68K_PLT16O },
+ { BFD_RELOC_8_PLTOFF, R_68K_PLT8O },
+ { BFD_RELOC_NONE, R_68K_COPY },
+ { BFD_RELOC_68K_GLOB_DAT, R_68K_GLOB_DAT },
+ { BFD_RELOC_68K_JMP_SLOT, R_68K_JMP_SLOT },
+ { BFD_RELOC_68K_RELATIVE, R_68K_RELATIVE },
+ { BFD_RELOC_CTOR, R_68K_32 },
+ { BFD_RELOC_VTABLE_INHERIT, R_68K_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_68K_GNU_VTENTRY },
+};
+
+static reloc_howto_type *
+reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+ for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
+ {
+ if (reloc_map[i].bfd_val == code)
+ return &howto_table[reloc_map[i].elf_val];
+ }
+ return 0;
+}
+
+#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
+#define ELF_ARCH bfd_arch_m68k
+/* end code generated by elf.el */
+
+#define USE_RELA
+
+
+/* Functions for the m68k ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 20
+
+/* The first entry in a procedure linkage table looks like this. See
+ the SVR4 ABI m68k supplement to see how this works. */
+
+static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
+ 0, 0, 0, 0, /* replaced with offset to .got + 4. */
+ 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
+ 0, 0, 0, 0, /* replaced with offset to .got + 8. */
+ 0, 0, 0, 0 /* pad out to 20 bytes. */
+};
+
+/* Subsequent entries in a procedure linkage table look like this. */
+
+static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */
+ 0, 0, 0, 0, /* replaced with offset to symbol's .got entry. */
+ 0x2f, 0x3c, /* move.l #offset,-(%sp) */
+ 0, 0, 0, 0, /* replaced with offset into relocation table. */
+ 0x60, 0xff, /* bra.l .plt */
+ 0, 0, 0, 0 /* replaced with offset to start of .plt. */
+};
+
+/* The m68k linker needs to keep track of the number of relocs that it
+ decides to copy in check_relocs for each symbol. This is so that it
+ can discard PC relative relocs if it doesn't need them when linking
+ with -Bsymbolic. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+/* This structure keeps track of the number of PC relative relocs we have
+ copied for a given symbol. */
+
+struct elf_m68k_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_m68k_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* m68k ELF linker hash entry. */
+
+struct elf_m68k_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct elf_m68k_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* m68k ELF linker hash table. */
+
+struct elf_m68k_link_hash_table
+{
+ struct elf_link_hash_table root;
+};
+
+/* Declare this now that the above structures are defined. */
+
+static boolean elf_m68k_discard_copies
+ PARAMS ((struct elf_m68k_link_hash_entry *, PTR));
+
+/* Traverse an m68k ELF linker hash table. */
+
+#define elf_m68k_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the m68k ELF linker hash table from a link_info structure. */
+
+#define elf_m68k_hash_table(p) \
+ ((struct elf_m68k_link_hash_table *) (p)->hash)
+
+/* Create an entry in an m68k ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_m68k_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct elf_m68k_link_hash_entry *ret =
+ (struct elf_m68k_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf_m68k_link_hash_entry *) NULL)
+ ret = ((struct elf_m68k_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_m68k_link_hash_entry)));
+ if (ret == (struct elf_m68k_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_m68k_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf_m68k_link_hash_entry *) NULL)
+ {
+ ret->pcrel_relocs_copied = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an m68k ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_m68k_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct elf_m68k_link_hash_table *ret;
+
+ ret = ((struct elf_m68k_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct elf_m68k_link_hash_table)));
+ if (ret == (struct elf_m68k_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf_m68k_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static boolean
+elf_m68k_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+
+ if (info->relocateable)
+ return true;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_68K_GOT8:
+ case R_68K_GOT16:
+ case R_68K_GOT32:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_68K_GOT8O:
+ case R_68K_GOT16O:
+ case R_68K_GOT32O:
+ /* This symbol requires a global offset table entry. */
+
+ if (dynobj == NULL)
+ {
+ /* Create the .got section. */
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return false;
+ }
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rela.got");
+ if (srelgot == NULL
+ || !bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || !bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.refcount == -1)
+ {
+ h->got.refcount = 1;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (!bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ /* Allocate space in the .got section. */
+ sgot->_raw_size += 4;
+ /* Allocate relocation space. */
+ srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.refcount++;
+ }
+ else
+ {
+ /* This is a global offset table entry for a local symbol. */
+ if (local_got_refcounts == NULL)
+ {
+ size_t size;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_signed_vma);
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_alloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return false;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ memset (local_got_refcounts, -1, size);
+ }
+ if (local_got_refcounts[r_symndx] == -1)
+ {
+ local_got_refcounts[r_symndx] = 1;
+
+ sgot->_raw_size += 4;
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_68K_RELATIVE reloc so that the dynamic
+ linker can adjust this GOT entry. */
+ srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ local_got_refcounts[r_symndx]++;
+ }
+ break;
+
+ case R_68K_PLT8:
+ case R_68K_PLT16:
+ case R_68K_PLT32:
+ /* This symbol requires a procedure linkage table entry. We
+ actually build the entry in adjust_dynamic_symbol,
+ because this might be a case of linking PIC code which is
+ never referenced by a dynamic object, in which case we
+ don't need to generate a procedure linkage table entry
+ after all. */
+
+ /* If this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (h == NULL)
+ continue;
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ if (h->plt.refcount == -1)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount++;
+ break;
+
+ case R_68K_PLT8O:
+ case R_68K_PLT16O:
+ case R_68K_PLT32O:
+ /* This symbol requires a procedure linkage table entry. */
+
+ if (h == NULL)
+ {
+ /* It does not make sense to have this relocation for a
+ local symbol. FIXME: does it? How to handle it if
+ it does make sense? */
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (!bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ if (h->plt.refcount == -1)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount++;
+ break;
+
+ case R_68K_PC8:
+ case R_68K_PC16:
+ case R_68K_PC32:
+ /* If we are creating a shared library and this is not a local
+ symbol, we need to copy the reloc into the shared library.
+ However when linking with -Bsymbolic and this is a global
+ symbol which is defined in an object we are including in the
+ link (i.e., DEF_REGULAR is set), then we can resolve the
+ reloc directly. At this point we have not seen all the input
+ files, so it is possible that DEF_REGULAR is not set now but
+ will be set later (it is never cleared). We account for that
+ possibility below by storing information in the
+ pcrel_relocs_copied field of the hash table entry. */
+ if (!(info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (!info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+ {
+ if (h != NULL)
+ {
+ /* Make sure a plt entry is created for this symbol if
+ it turns out to be a function defined by a dynamic
+ object. */
+ if (h->plt.refcount == -1)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount++;
+ }
+ break;
+ }
+ /* Fall through. */
+ case R_68K_8:
+ case R_68K_16:
+ case R_68K_32:
+ if (h != NULL)
+ {
+ /* Make sure a plt entry is created for this symbol if it
+ turns out to be a function defined by a dynamic object. */
+ if (h->plt.refcount == -1)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount++;
+ }
+
+ /* If we are creating a shared library, we need to copy the
+ reloc into the shared library. */
+ if (info->shared
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file. We create a reloc
+ section in dynobj and make room for this reloc. */
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ sreloc = bfd_make_section (dynobj, name);
+ if (sreloc == NULL
+ || !bfd_set_section_flags (dynobj, sreloc,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || !bfd_set_section_alignment (dynobj, sreloc, 2))
+ return false;
+ }
+ }
+
+ sreloc->_raw_size += sizeof (Elf32_External_Rela);
+
+ /* If we are linking with -Bsymbolic, we count the number of
+ PC relative relocations we have entered for this symbol,
+ so that we can discard them again if the symbol is later
+ defined by a regular object. Note that this function is
+ only called if we are using an m68kelf linker hash table,
+ which means that h is really a pointer to an
+ elf_m68k_link_hash_entry. */
+ if ((ELF32_R_TYPE (rel->r_info) == R_68K_PC8
+ || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
+ || ELF32_R_TYPE (rel->r_info) == R_68K_PC32)
+ && info->symbolic)
+ {
+ struct elf_m68k_link_hash_entry *eh;
+ struct elf_m68k_pcrel_relocs_copied *p;
+
+ eh = (struct elf_m68k_link_hash_entry *) h;
+
+ for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
+ if (p->section == sreloc)
+ break;
+
+ if (p == NULL)
+ {
+ p = ((struct elf_m68k_pcrel_relocs_copied *)
+ bfd_alloc (dynobj, sizeof *p));
+ if (p == NULL)
+ return false;
+ p->next = eh->pcrel_relocs_copied;
+ eh->pcrel_relocs_copied = p;
+ p->section = sreloc;
+ p->count = 0;
+ }
+
+ ++p->count;
+ }
+ }
+
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_68K_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_68K_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf_m68k_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_68K_GNU_VTINHERIT:
+ case R_68K_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ default:
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+elf_m68k_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ bfd *dynobj;
+ asection *sgot;
+ asection *srelgot;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ }
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_68K_GOT8:
+ case R_68K_GOT16:
+ case R_68K_GOT32:
+ case R_68K_GOT8O:
+ case R_68K_GOT16O:
+ case R_68K_GOT32O:
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (h->got.refcount > 0)
+ {
+ --h->got.refcount;
+ if (h->got.refcount == 0)
+ {
+ /* We don't need the .got entry any more. */
+ sgot->_raw_size -= 4;
+ srelgot->_raw_size -= sizeof (Elf32_External_Rela);
+ }
+ }
+ }
+ else
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ {
+ --local_got_refcounts[r_symndx];
+ if (local_got_refcounts[r_symndx] == 0)
+ {
+ /* We don't need the .got entry any more. */
+ sgot->_raw_size -= 4;
+ if (info->shared)
+ srelgot->_raw_size -= sizeof (Elf32_External_Rela);
+ }
+ }
+ }
+ break;
+
+ case R_68K_PLT8:
+ case R_68K_PLT16:
+ case R_68K_PLT32:
+ case R_68K_PLT8O:
+ case R_68K_PLT16O:
+ case R_68K_PLT32O:
+ case R_68K_PC8:
+ case R_68K_PC16:
+ case R_68K_PC32:
+ case R_68K_8:
+ case R_68K_16:
+ case R_68K_32:
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (h->plt.refcount > 0)
+ --h->plt.refcount;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+elf_m68k_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj;
+ asection *s;
+ unsigned int power_of_two;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later,
+ when we know the address of the .got section. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
+ /* We must always create the plt entry if it was referenced
+ by a PLTxxO relocation. In this case we already recorded
+ it as a dynamic symbol. */
+ && h->dynindx == -1)
+ {
+ /* This case can occur if we saw a PLTxx reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object. In such a case, we don't actually need to build
+ a procedure linkage table, and we can just do a PCxx
+ reloc instead. */
+ BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ h->plt.offset = (bfd_vma) -1;
+ return true;
+ }
+
+ /* GC may have rendered this entry unused. */
+ if (h->plt.refcount <= 0)
+ {
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.offset = (bfd_vma) -1;
+ return true;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->_raw_size == 0)
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (!info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+ }
+
+ h->plt.offset = s->_raw_size;
+
+ /* Make room for this entry. */
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .got.plt section, which
+ will be placed in the .got section by the linker script. */
+
+ s = bfd_get_section_by_name (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += sizeof (Elf32_External_Rela);
+
+ return true;
+ }
+
+ /* Reinitialize the plt offset now that it is not used as a reference
+ count any more. */
+ h->plt.offset = (bfd_vma) -1;
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (info->shared)
+ return true;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. We need to remember the offset into the
+ .rela.bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf32_External_Rela);
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ }
+
+ /* We need to figure out the alignment required for this symbol. I
+ have no idea how ELF linkers handle this. */
+ power_of_two = bfd_log2 (h->size);
+ if (power_of_two > 3)
+ power_of_two = 3;
+
+ /* Apply the required alignment. */
+ s->_raw_size = BFD_ALIGN (s->_raw_size,
+ (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ {
+ if (!bfd_set_section_alignment (dynobj, s, power_of_two))
+ return false;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->_raw_size += h->size;
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+elf_m68k_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean plt;
+ boolean relocs;
+ boolean reltext;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (!info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+ else
+ {
+ /* We may have created entries in the .rela.got section.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rela.got,
+ which will cause it to get stripped from the output file
+ below. */
+ s = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (s != NULL)
+ s->_raw_size = 0;
+ }
+
+ /* If this is a -Bsymbolic shared link, then we need to discard all PC
+ relative relocs against symbols defined in a regular object. We
+ allocated space for them in the check_relocs routine, but we will not
+ fill them in in the relocate_section routine. */
+ if (info->shared && info->symbolic)
+ elf_m68k_link_hash_traverse (elf_m68k_hash_table (info),
+ elf_m68k_discard_copies,
+ (PTR) NULL);
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ plt = false;
+ relocs = false;
+ reltext = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ strip = false;
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ strip = true;
+ }
+ else
+ {
+ /* Remember whether there is a PLT. */
+ plt = true;
+ }
+ }
+ else if (strncmp (name, ".rela", 5) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rela.bss and
+ .rela.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ strip = true;
+ }
+ else
+ {
+ asection *target;
+
+ /* Remember whether there are any reloc sections other
+ than .rela.plt. */
+ if (strcmp (name, ".rela.plt") != 0)
+ {
+ const char *outname;
+
+ relocs = true;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL
+ entry. .rela.plt is actually associated with
+ .got.plt, which is never readonly. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 5);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ reltext = true;
+ }
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strncmp (name, ".got", 4) != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ _bfd_strip_section_from_output (s);
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_m68k_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (!info->shared)
+ {
+ if (!bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (plt)
+ {
+ if (!bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ return false;
+ }
+
+ if (relocs)
+ {
+ if (!bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
+ || !bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return false;
+ }
+
+ if (reltext)
+ {
+ if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ /* If we are generating a shared library, we generate a section
+ symbol for each output section for which we might need to copy
+ relocs. These are local symbols, which means that they must come
+ first in the dynamic symbol table. That means we must increment
+ the dynamic symbol index of every other dynamic symbol. */
+ if (info->shared)
+ {
+ int c;
+
+ c = 0;
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) != 0
+ || (s->flags & SEC_ALLOC) == 0)
+ continue;
+
+ elf_section_data (s)->dynindx = c + 1;
+
+ /* These symbols will have no names, so we don't need to
+ fiddle with dynstr_index. */
+
+ ++c;
+ }
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_m68k_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+ }
+
+ return true;
+}
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+
+static boolean
+elf_m68k_adjust_dynindx (h, cparg)
+ struct elf_link_hash_entry *h;
+ PTR cparg;
+{
+ int *cp = (int *) cparg;
+
+ if (h->dynindx != -1)
+ h->dynindx += *cp;
+ return true;
+}
+
+/* This function is called via elf_m68k_link_hash_traverse if we are
+ creating a shared object with -Bsymbolic. It discards the space
+ allocated to copy PC relative relocs against symbols which are defined
+ in regular objects. We allocated space for them in the check_relocs
+ routine, but we won't fill them in in the relocate_section routine. */
+
+/*ARGSUSED*/
+static boolean
+elf_m68k_discard_copies (h, ignore)
+ struct elf_m68k_link_hash_entry *h;
+ PTR ignore;
+{
+ struct elf_m68k_pcrel_relocs_copied *s;
+
+ /* We only discard relocs for symbols defined in a regular object. */
+ if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ return true;
+
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ s->section->_raw_size -= s->count * sizeof (Elf32_External_Rela);
+
+ return true;
+}
+
+/* Relocate an M68K ELF section. */
+
+static boolean
+elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ asection *sgot;
+ asection *splt;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sgot = NULL;
+ splt = NULL;
+ sreloc = NULL;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_68K_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto = howto_table + r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if (((r_type == R_68K_PLT8
+ || r_type == R_68K_PLT16
+ || r_type == R_68K_PLT32
+ || r_type == R_68K_PLT8O
+ || r_type == R_68K_PLT16O
+ || r_type == R_68K_PLT32O)
+ && h->plt.offset != (bfd_vma) -1
+ && elf_hash_table (info)->dynamic_sections_created)
+ || ((r_type == R_68K_GOT8O
+ || r_type == R_68K_GOT16O
+ || r_type == R_68K_GOT32O
+ || ((r_type == R_68K_GOT8
+ || r_type == R_68K_GOT16
+ || r_type == R_68K_GOT32)
+ && strcmp (h->root.root.string,
+ "_GLOBAL_OFFSET_TABLE_") != 0))
+ && elf_hash_table (info)->dynamic_sections_created
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type == R_68K_8
+ || r_type == R_68K_16
+ || r_type == R_68K_32
+ || r_type == R_68K_PC8
+ || r_type == R_68K_PC16
+ || r_type == R_68K_PC32)))
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ relocation = 0;
+ }
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else
+ {
+ if (!(info->callbacks->undefined_symbol
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_68K_GOT8:
+ case R_68K_GOT16:
+ case R_68K_GOT32:
+ /* Relocation is to the address of the entry for this symbol
+ in the global offset table. */
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_68K_GOT8O:
+ case R_68K_GOT16O:
+ case R_68K_GOT32O:
+ /* Relocation is the offset of the entry for this symbol in
+ the global offset table. */
+
+ {
+ bfd_vma off;
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (!elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined
+ locally, or the symbol was forced to be local
+ because of a version file.. We must initialize
+ this entry in the global offset table. Since
+ the offset must always be a multiple of 4, we
+ use the least significant bit to record whether
+ we have initialized it already.
+
+ When doing a dynamic link, we create a .rela.got
+ relocation entry to initialize the value. This
+ is done in the finish_dynamic_symbol routine. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation,
+ sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ }
+ else
+ {
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use
+ the least significant bit to record whether we have
+ already generated the necessary reloc. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+ outrel.r_addend = relocation;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ if (r_type == R_68K_GOT8O
+ || r_type == R_68K_GOT16O
+ || r_type == R_68K_GOT32O)
+ {
+ /* This relocation does not use the addend. */
+ rel->r_addend = 0;
+ }
+ else
+ relocation += sgot->output_section->vma;
+ }
+ break;
+
+ case R_68K_PLT8:
+ case R_68K_PLT16:
+ case R_68K_PLT32:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLTxx reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1
+ || !elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ break;
+
+ case R_68K_PLT8O:
+ case R_68K_PLT16O:
+ case R_68K_PLT32O:
+ /* Relocation is the offset of the entry for this symbol in
+ the procedure linkage table. */
+ BFD_ASSERT (h != NULL && h->plt.offset != (bfd_vma) -1);
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = h->plt.offset;
+
+ /* This relocation does not use the addend. */
+ rel->r_addend = 0;
+
+ break;
+
+ case R_68K_PC8:
+ case R_68K_PC16:
+ case R_68K_PC32:
+ if (h == NULL)
+ break;
+ /* Fall through. */
+ case R_68K_8:
+ case R_68K_16:
+ case R_68K_32:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && ((r_type != R_68K_PC8
+ && r_type != R_68K_PC16
+ && r_type != R_68K_PC32)
+ || (!info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+ {
+ Elf_Internal_Rela outrel;
+ boolean skip, relocate;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ {
+ memset (&outrel, 0, sizeof outrel);
+ relocate = false;
+ }
+ /* h->dynindx may be -1 if the symbol was marked to
+ become local. */
+ else if (h != NULL
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ relocate = false;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_68K_32)
+ {
+ relocate = true;
+ outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ if (h == NULL)
+ sec = local_sections[r_symndx];
+ else
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || (h->root.type
+ == bfd_link_hash_defweak));
+ sec = h->root.u.def.section;
+ }
+ if (sec != NULL && bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ BFD_ASSERT (indx > 0);
+ }
+
+ relocate = false;
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, except for R_68K_32
+ relocations that have been turned into
+ R_68K_RELATIVE. */
+ if (!relocate)
+ continue;
+ }
+
+ break;
+
+ case R_68K_GNU_VTINHERIT:
+ case R_68K_GNU_VTENTRY:
+ /* These are no-ops in the end. */
+ continue;
+
+ default:
+ break;
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (!(info->callbacks->reloc_overflow
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgot;
+ asection *srela;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
+
+ /* Get the index in the procedure linkage table which
+ corresponds to this symbol. This is the index of this symbol
+ in all the symbols for which we are making plt entries. The
+ first entry in the procedure linkage table is reserved. */
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
+
+ /* Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is 4 bytes.
+ The first three are reserved. */
+ got_offset = (plt_index + 3) * 4;
+
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (splt->contents + h->plt.offset, elf_m68k_plt_entry,
+ PLT_ENTRY_SIZE);
+ /* The offset is relative to the first extension word. */
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset
+ - (splt->output_section->vma
+ + h->plt.offset + 2)),
+ splt->contents + h->plt.offset + 4);
+
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+ splt->contents + h->plt.offset + 10);
+ bfd_put_32 (output_bfd, - (h->plt.offset + 16),
+ splt->contents + h->plt.offset + 16);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + 8),
+ sgot->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_JMP_SLOT);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) srela->contents
+ + plt_index));
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srela = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ 1));
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. Likewise if
+ the symbol was forced to be local because of a version file.
+ The entry in the global offset table will already have been
+ initialized in the relocate_section function. */
+ if (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ {
+ rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+ rela.r_addend = bfd_get_signed_32 (output_bfd,
+ (sgot->contents
+ + (h->got.offset & ~1)));
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ sgot->contents + (h->got.offset & ~1));
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) srela->contents
+ + srela->reloc_count));
+ ++srela->reloc_count;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak));
+
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rela.bss");
+ BFD_ASSERT (s != NULL);
+
+ rela.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_COPY);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) s->contents
+ + s->reloc_count));
+ ++s->reloc_count;
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+elf_m68k_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *sgot;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ name = ".got";
+ goto get_vma;
+ case DT_JMPREL:
+ name = ".rela.plt";
+ get_vma:
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
+ else
+ dyn.d_un.d_val = s->_raw_size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* The procedure linkage table relocs (DT_JMPREL) should
+ not be included in the overall relocs (DT_RELA).
+ Therefore, we override the DT_RELASZ entry here to
+ make it not include the JMPREL relocs. Since the
+ linker script arranges for .rela.plt to follow all
+ other relocation sections, we don't have to worry
+ about changing the DT_RELA entry. */
+ s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+ if (s != NULL)
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val -= s->_cooked_size;
+ else
+ dyn.d_un.d_val -= s->_raw_size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->_raw_size > 0)
+ {
+ memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset + 4
+ - (splt->output_section->vma + 2)),
+ splt->contents + 4);
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset + 8
+ - (splt->output_section->vma + 10)),
+ splt->contents + 12);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE;
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->_raw_size > 0)
+ {
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgot->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ if (info->shared)
+ {
+ asection *sdynsym;
+ asection *s;
+ Elf_Internal_Sym sym;
+ int c;
+
+ /* Set up the section symbols for the output sections. */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (sdynsym != NULL);
+
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+
+ c = 0;
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx;
+
+ if (elf_section_data (s)->dynindx == 0)
+ continue;
+
+ sym.st_value = s->vma;
+
+ indx = elf_section_data (s)->this_idx;
+ BFD_ASSERT (indx > 0);
+ sym.st_shndx = indx;
+
+ bfd_elf32_swap_symbol_out (output_bfd, &sym,
+ (PTR) (((Elf32_External_Sym *)
+ sdynsym->contents)
+ + elf_section_data (s)->dynindx));
+
+ ++c;
+ }
+
+ /* Set the sh_info field of the output .dynsym section to the
+ index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
+ }
+
+ return true;
+}
+
+#define TARGET_BIG_SYM bfd_elf32_m68k_vec
+#define TARGET_BIG_NAME "elf32-m68k"
+#define ELF_MACHINE_CODE EM_68K
+#define ELF_MAXPAGESIZE 0x2000
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_m68k_link_hash_table_create
+#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link
+
+#define elf_backend_check_relocs elf_m68k_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ elf_m68k_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ elf_m68k_size_dynamic_sections
+#define elf_backend_relocate_section elf_m68k_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elf_m68k_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf_m68k_finish_dynamic_sections
+#define elf_backend_gc_mark_hook elf_m68k_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_m68k_gc_sweep_hook
+#define elf_backend_can_gc_sections 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 12
+#define elf_backend_plt_header_size PLT_ENTRY_SIZE
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m88k.c b/bfd/elf32-m88k.c
new file mode 100644
index 00000000000..f3c535e0776
--- /dev/null
+++ b/bfd/elf32-m88k.c
@@ -0,0 +1,35 @@
+/* Motorola 88k-specific support for 32-bit ELF
+ Copyright 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* This does not include any relocations, but should be good enough
+ for GDB. */
+
+#define TARGET_BIG_SYM bfd_elf32_m88k_vec
+#define TARGET_BIG_NAME "elf32-m88k"
+#define ELF_ARCH bfd_arch_m88k
+#define ELF_MACHINE_CODE EM_88K
+#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define elf_info_to_howto _bfd_elf_no_info_to_howto
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c
new file mode 100644
index 00000000000..ef3a39f1957
--- /dev/null
+++ b/bfd/elf32-mcore.c
@@ -0,0 +1,747 @@
+/* Motorolla MCore specific support for 32-bit ELF
+ Copyright 1994, 1995, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file is based on a preliminary RCE ELF ABI. The
+ information may not match the final RCE ELF ABI. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mcore.h"
+#include <assert.h>
+
+#define USE_RELA /* Only USE_REL is actually significant, but this is
+ here are a reminder... */
+
+static void mcore_elf_howto_init
+ PARAMS ((void));
+static reloc_howto_type * mcore_elf_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void mcore_elf_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static boolean mcore_elf_set_private_flags
+ PARAMS ((bfd *, flagword));
+static boolean mcore_elf_copy_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean mcore_elf_merge_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static bfd_reloc_status_type mcore_elf_unsupported_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean mcore_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+
+static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
+
+static reloc_howto_type mcore_elf_howto_raw[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_MCORE_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 1, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mcore_elf_unsupported_reloc, /* special_function */
+ "R_MCORE_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A standard 32 bit relocation. */
+ HOWTO (R_MCORE_ADDR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "ADDR32", /* name *//* For compatability with coff/pe port. */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
+ Should not appear in object files. */
+ HOWTO (R_MCORE_PCRELIMM8BY4, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mcore_elf_unsupported_reloc, /* special_function */
+ "R_MCORE_PCRELIMM8BY4",/* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
+ Span 2k instructions == 4k bytes.
+ Only useful pieces at the relocated address are the opcode (5 bits) */
+ HOWTO (R_MCORE_PCRELIMM11BY2,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MCORE_PCRELIMM11BY2",/* name */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x7ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
+ HOWTO (R_MCORE_PCRELIMM4BY2, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mcore_elf_unsupported_reloc,/* special_function */
+ "R_MCORE_PCRELIMM4BY2",/* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 32-bit pc-relative. Eventually this will help support PIC code. */
+ HOWTO (R_MCORE_PCREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MCORE_PCREL32", /* name */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Like PCRELIMM11BY2, this relocation indicates that there is a
+ 'jsri' at the specified address. There is a separate relocation
+ entry for the literal pool entry that it references, but we
+ might be able to change the jsri to a bsr if the target turns out
+ to be close enough [even though we won't reclaim the literal pool
+ entry, we'll get some runtime efficiency back]. Note that this
+ is a relocation that we are allowed to safely ignore. */
+ HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MCORE_PCRELJSR_IMM11BY2", /* name */
+ false, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x7ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_MCORE_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_MCORE_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_MCORE_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_MCORE_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+};
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
+#endif
+
+/* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */
+static void
+mcore_elf_howto_init ()
+{
+ unsigned int i;
+
+ for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
+ {
+ unsigned int type;
+
+ type = mcore_elf_howto_raw[i].type;
+
+ BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
+
+ mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
+ }
+}
+
+
+static reloc_howto_type *
+mcore_elf_reloc_type_lookup (abfd, code)
+ bfd * abfd;
+ bfd_reloc_code_real_type code;
+{
+ enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break;
+ case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break;
+ case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
+ case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
+ case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
+ case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break;
+ case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
+ case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
+ case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break;
+ default:
+ return (reloc_howto_type *)NULL;
+ }
+
+ if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
+ mcore_elf_howto_init ();
+
+ return mcore_elf_howto_table [(int) mcore_reloc];
+};
+
+/* Set the howto pointer for a RCE ELF reloc. */
+static void
+mcore_elf_info_to_howto (abfd, cache_ptr, dst)
+ bfd * abfd;
+ arelent * cache_ptr;
+ Elf32_Internal_Rela * dst;
+{
+ if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
+ mcore_elf_howto_init ();
+
+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
+
+ cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
+}
+
+/* Function to set whether a module needs the -mrelocatable bit set. */
+static boolean
+mcore_elf_set_private_flags (abfd, flags)
+ bfd * abfd;
+ flagword flags;
+{
+ BFD_ASSERT (! elf_flags_init (abfd)
+ || elf_elfheader (abfd)->e_flags == flags);
+
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ return true;
+}
+
+/* Copy backend specific data from one object module to another. */
+static boolean
+mcore_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (! elf_flags_init (obfd)
+ || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
+
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static boolean
+mcore_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ flagword old_flags;
+ flagword new_flags;
+ boolean error;
+
+ /* Check if we have the same endianess */
+ if ( ibfd->xvec->byteorder != obfd->xvec->byteorder
+ && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ (*_bfd_error_handler)
+ (_("%s: compiled for a %s endian system and target is %s endian.\n"),
+ bfd_get_filename (ibfd),
+ bfd_big_endian (ibfd) ? "big" : "little",
+ bfd_big_endian (obfd) ? "big" : "little");
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd)) /* First call, no flags set */
+ {
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = new_flags;
+ }
+ else if (new_flags == old_flags) /* Compatible flags are ok */
+ ;
+
+ return true;
+}
+
+
+/* Don't pretend we can deal with unsupported relocs. */
+
+/*ARGSUSED*/
+static bfd_reloc_status_type
+mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd * abfd;
+ arelent * reloc_entry;
+ asymbol * symbol;
+ PTR data;
+ asection * input_section;
+ bfd * output_bfd;
+ char ** error_message;
+{
+ BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
+
+ _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
+ bfd_get_filename (abfd),
+ reloc_entry->howto->name,
+ reloc_entry->howto->type);
+
+ return bfd_reloc_notsupported;
+}
+
+
+/* The RELOCATE_SECTION function is called by the ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjust the section contents as
+ necessary, and (if using Rela relocs and generating a
+ relocateable output file) adjusting the reloc addend as
+ necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+
+static boolean
+mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * relocs;
+ Elf_Internal_Sym * local_syms;
+ asection ** local_sections;
+{
+ Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
+ Elf_Internal_Rela * rel = relocs;
+ Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
+ boolean ret = true;
+ long insn;
+
+#ifdef DEBUG
+ fprintf (stderr,
+ "mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n",
+ bfd_get_filename (input_bfd),
+ bfd_section_name(input_bfd, input_section),
+ (long) input_section->reloc_count,
+ (info->relocateable) ? " (relocatable)" : "");
+#endif
+
+ if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
+ mcore_elf_howto_init ();
+
+ for (; rel < relend; rel++)
+ {
+ enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
+ bfd_vma offset = rel->r_offset;
+ bfd_vma addend = rel->r_addend;
+ bfd_reloc_status_type r = bfd_reloc_other;
+ asection * sec = (asection *) 0;
+ reloc_howto_type * howto;
+ bfd_vma relocation;
+ Elf_Internal_Sym * sym = (Elf_Internal_Sym *) 0;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
+ unsigned short oldinst;
+
+ /* Unknown relocation handling */
+ if ((unsigned) r_type >= (unsigned) R_MCORE_max
+ || ! mcore_elf_howto_table [(int)r_type])
+ {
+ _bfd_error_handler (_("%s: Unknown relocation type %d\n"),
+ bfd_get_filename (input_bfd),
+ (int) r_type);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+ }
+
+ howto = mcore_elf_howto_table [(int) r_type];
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+
+ if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ addend = rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
+ howto->name, (int) r_type, r_symndx, (long) offset, (long) addend);
+#endif
+ continue;
+ }
+
+ /* This is a final link. */
+
+ /* Complain about known relocation that are not yet supported */
+ if (howto->special_function == mcore_elf_unsupported_reloc)
+ {
+ _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
+ bfd_get_filename (input_bfd),
+ howto->name,
+ (int)r_type);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+ if ( h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+
+ ret = false;
+ continue;
+ }
+ }
+
+ switch (r_type)
+ {
+ default:
+ case R_MCORE_PCRELIMM8BY4:
+ case R_MCORE_PCRELIMM11BY2:
+ case R_MCORE_PCRELIMM4BY2:
+ break;
+
+ case R_MCORE_PCRELJSR_IMM11BY2:
+ oldinst = bfd_get_16 (input_bfd, contents + offset);
+#define MCORE_INST_BSR 0xF800
+ bfd_put_16 (input_bfd, MCORE_INST_BSR, contents + offset);
+ break;
+ }
+
+
+#ifdef DEBUG
+ fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
+ howto->name, r_type, r_symndx, (long) offset, (long) addend);
+#endif
+
+ r = _bfd_final_link_relocate
+ (howto, input_bfd, input_section, contents, offset, relocation, addend);
+
+ if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
+ {
+ /* Wasn't ok, back it out and give up. */
+ bfd_put_16 (input_bfd, oldinst, contents + offset);
+ r = bfd_reloc_ok;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ ret = false;
+
+ switch (r)
+ {
+ default:
+ break;
+
+ case bfd_reloc_overflow:
+ {
+ const char * name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+
+ if (name == NULL)
+ break;
+
+ if (* name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ (*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section,
+ offset);
+ }
+ break;
+ }
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\n");
+#endif
+
+ return ret;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+mcore_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ Elf_Internal_Rela * rel;
+ struct elf_link_hash_entry * h;
+ Elf_Internal_Sym * sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MCORE_GNU_VTINHERIT:
+ case R_MCORE_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ asection * sec;
+ const Elf_Internal_Rela * relocs;
+{
+ return true;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+mcore_elf_check_relocs (abfd, info, sec, relocs)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ asection * sec;
+ const Elf_Internal_Rela * relocs;
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** sym_hashes_end;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry * h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_MCORE_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_MCORE_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+#define TARGET_BIG_SYM bfd_elf32_mcore_big_vec
+#define TARGET_BIG_NAME "elf32-mcore-big"
+#define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec
+#define TARGET_LITTLE_NAME "elf32-mcore-little"
+
+#define ELF_ARCH bfd_arch_mcore
+#define ELF_MACHINE_CODE EM_MCORE
+#define ELF_MAXPAGESIZE 0x1000 /* 4k, if we ever have 'em */
+#define elf_info_to_howto mcore_elf_info_to_howto
+#define elf_info_to_howto_rel NULL
+
+
+#define bfd_elf32_bfd_copy_private_bfd_data mcore_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags
+#define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup
+#define elf_backend_relocate_section mcore_elf_relocate_section
+#define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook
+#define elf_backend_check_relocs mcore_elf_check_relocs
+
+#define elf_backend_can_gc_sections 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
new file mode 100644
index 00000000000..9f03262eb38
--- /dev/null
+++ b/bfd/elf32-mips.c
@@ -0,0 +1,7800 @@
+/* MIPS-specific support for 32-bit ELF
+ Copyright 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+ Most of the information added by Ian Lance Taylor, Cygnus Support,
+ <ian@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file handles MIPS ELF targets. SGI Irix 5 uses a slightly
+ different MIPS ELF from other targets. This matters when linking.
+ This file supports both, switching at runtime. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elf/mips.h"
+
+/* Get the ECOFF swapping routines. */
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/internal.h"
+#include "coff/ecoff.h"
+#include "coff/mips.h"
+#define ECOFF_32
+#include "ecoffswap.h"
+
+static bfd_reloc_status_type mips32_64bit_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void mips_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static void bfd_mips_elf32_swap_gptab_in
+ PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *));
+static void bfd_mips_elf32_swap_gptab_out
+ PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *));
+static boolean mips_elf_sym_is_global PARAMS ((bfd *, asymbol *));
+static boolean mips_elf32_object_p PARAMS ((bfd *));
+static boolean mips_elf_create_procedure_table
+ PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *,
+ struct ecoff_debug_info *));
+static int mips_elf_additional_program_headers PARAMS ((bfd *));
+static boolean mips_elf_modify_segment_map PARAMS ((bfd *));
+static INLINE int elf_mips_isa PARAMS ((flagword));
+static INLINE int elf_mips_mach PARAMS ((flagword));
+static INLINE char* elf_mips_abi_name PARAMS ((flagword));
+static boolean mips_elf32_section_from_shdr
+ PARAMS ((bfd *, Elf32_Internal_Shdr *, char *));
+static boolean mips_elf32_section_processing
+ PARAMS ((bfd *, Elf32_Internal_Shdr *));
+static boolean mips_elf_is_local_label_name
+ PARAMS ((bfd *, const char *));
+static struct bfd_hash_entry *mips_elf_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *mips_elf_link_hash_table_create
+ PARAMS ((bfd *));
+static int gptab_compare PARAMS ((const void *, const void *));
+static boolean mips_elf_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+static void mips_elf_relocate_hi16
+ PARAMS ((bfd *, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *,
+ bfd_vma));
+static boolean mips_elf_relocate_got_local
+ PARAMS ((bfd *, bfd *, asection *, Elf_Internal_Rela *,
+ Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static void mips_elf_relocate_global_got
+ PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static bfd_reloc_status_type mips16_jump_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type mips16_gprel_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean mips_elf_adjust_dynindx
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean mips_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean mips_elf_link_output_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+ asection *));
+static boolean mips_elf_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean mips_elf_create_compact_rel_section
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean mips_elf_create_got_section
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean mips_elf_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static boolean mips_elf_adjust_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean mips_elf_always_size_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean mips_elf_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean mips_elf_finish_dynamic_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+static boolean mips_elf_finish_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean mips_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+static bfd_reloc_status_type mips_elf_final_gp
+ PARAMS ((bfd *, asymbol *, boolean, char **, bfd_vma *));
+static bfd_byte *elf32_mips_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, boolean, asymbol **));
+
+/* This is true for Irix 5 executables, false for normal MIPS ELF ABI
+ executables. FIXME: At the moment, we default to always generating
+ Irix 5 executables. */
+
+#define SGI_COMPAT(abfd) (1)
+
+/* This structure is used to hold .got information when linking. It
+ is stored in the tdata field of the bfd_elf_section_data structure. */
+
+struct mips_got_info
+{
+ /* The symbol index of the first global .got symbol. */
+ unsigned long global_gotsym;
+ /* The number of local .got entries. */
+ unsigned int local_gotno;
+ /* The number of local .got entries we have used. */
+ unsigned int assigned_gotno;
+};
+
+/* The number of local .got entries we reserve. */
+#define MIPS_RESERVED_GOTNO (2)
+
+/* Instructions which appear in a stub. For some reason the stub is
+ slightly different on an SGI system. */
+#define ELF_MIPS_GP_OFFSET(abfd) (SGI_COMPAT (abfd) ? 0x7ff0 : 0x8000)
+#define STUB_LW(abfd) \
+ (SGI_COMPAT (abfd) \
+ ? 0x8f998010 /* lw t9,0x8010(gp) */ \
+ : 0x8f998000) /* lw t9,0x8000(gp) */
+#define STUB_MOVE 0x03e07825 /* move t7,ra */
+#define STUB_JALR 0x0320f809 /* jal t9 */
+#define STUB_LI16 0x34180000 /* ori t8,zero,0 */
+#define MIPS_FUNCTION_STUB_SIZE (16)
+
+#if 0
+/* We no longer try to identify particular sections for the .dynsym
+ section. When we do, we wind up crashing if there are other random
+ sections with relocations. */
+
+/* Names of sections which appear in the .dynsym section in an Irix 5
+ executable. */
+
+static const char * const mips_elf_dynsym_sec_names[] =
+{
+ ".text",
+ ".init",
+ ".fini",
+ ".data",
+ ".rodata",
+ ".sdata",
+ ".sbss",
+ ".bss",
+ NULL
+};
+
+#define SIZEOF_MIPS_DYNSYM_SECNAMES \
+ (sizeof mips_elf_dynsym_sec_names / sizeof mips_elf_dynsym_sec_names[0])
+
+/* The number of entries in mips_elf_dynsym_sec_names which go in the
+ text segment. */
+
+#define MIPS_TEXT_DYNSYM_SECNO (3)
+
+#endif /* 0 */
+
+/* The names of the runtime procedure table symbols used on Irix 5. */
+
+static const char * const mips_elf_dynsym_rtproc_names[] =
+{
+ "_procedure_table",
+ "_procedure_string_table",
+ "_procedure_table_size",
+ NULL
+};
+
+/* These structures are used to generate the .compact_rel section on
+ Irix 5. */
+
+typedef struct
+{
+ unsigned long id1; /* Always one? */
+ unsigned long num; /* Number of compact relocation entries. */
+ unsigned long id2; /* Always two? */
+ unsigned long offset; /* The file offset of the first relocation. */
+ unsigned long reserved0; /* Zero? */
+ unsigned long reserved1; /* Zero? */
+} Elf32_compact_rel;
+
+typedef struct
+{
+ bfd_byte id1[4];
+ bfd_byte num[4];
+ bfd_byte id2[4];
+ bfd_byte offset[4];
+ bfd_byte reserved0[4];
+ bfd_byte reserved1[4];
+} Elf32_External_compact_rel;
+
+typedef struct
+{
+ unsigned int ctype : 1; /* 1: long 0: short format. See below. */
+ unsigned int rtype : 4; /* Relocation types. See below. */
+ unsigned int dist2to : 8;
+ unsigned int relvaddr : 19; /* (VADDR - vaddr of the previous entry)/ 4 */
+ unsigned long konst; /* KONST field. See below. */
+ unsigned long vaddr; /* VADDR to be relocated. */
+} Elf32_crinfo;
+
+typedef struct
+{
+ unsigned int ctype : 1; /* 1: long 0: short format. See below. */
+ unsigned int rtype : 4; /* Relocation types. See below. */
+ unsigned int dist2to : 8;
+ unsigned int relvaddr : 19; /* (VADDR - vaddr of the previous entry)/ 4 */
+ unsigned long konst; /* KONST field. See below. */
+} Elf32_crinfo2;
+
+typedef struct
+{
+ bfd_byte info[4];
+ bfd_byte konst[4];
+ bfd_byte vaddr[4];
+} Elf32_External_crinfo;
+
+typedef struct
+{
+ bfd_byte info[4];
+ bfd_byte konst[4];
+} Elf32_External_crinfo2;
+
+/* These are the constants used to swap the bitfields in a crinfo. */
+
+#define CRINFO_CTYPE (0x1)
+#define CRINFO_CTYPE_SH (31)
+#define CRINFO_RTYPE (0xf)
+#define CRINFO_RTYPE_SH (27)
+#define CRINFO_DIST2TO (0xff)
+#define CRINFO_DIST2TO_SH (19)
+#define CRINFO_RELVADDR (0x7ffff)
+#define CRINFO_RELVADDR_SH (0)
+
+/* A compact relocation info has long (3 words) or short (2 words)
+ formats. A short format doesn't have VADDR field and relvaddr
+ fields contains ((VADDR - vaddr of the previous entry) >> 2). */
+#define CRF_MIPS_LONG 1
+#define CRF_MIPS_SHORT 0
+
+/* There are 4 types of compact relocation at least. The value KONST
+ has different meaning for each type:
+
+ (type) (konst)
+ CT_MIPS_REL32 Address in data
+ CT_MIPS_WORD Address in word (XXX)
+ CT_MIPS_GPHI_LO GP - vaddr
+ CT_MIPS_JMPAD Address to jump
+ */
+
+#define CRT_MIPS_REL32 0xa
+#define CRT_MIPS_WORD 0xb
+#define CRT_MIPS_GPHI_LO 0xc
+#define CRT_MIPS_JMPAD 0xd
+
+#define mips_elf_set_cr_format(x,format) ((x).ctype = (format))
+#define mips_elf_set_cr_type(x,type) ((x).rtype = (type))
+#define mips_elf_set_cr_dist2to(x,v) ((x).dist2to = (v))
+#define mips_elf_set_cr_relvaddr(x,d) ((x).relvaddr = (d)<<2)
+
+static void bfd_elf32_swap_compact_rel_out
+ PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *));
+static void bfd_elf32_swap_crinfo_out
+ PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *));
+
+#define USE_REL 1 /* MIPS uses REL relocations instead of RELA */
+
+static reloc_howto_type elf_mips_howto_table[] =
+{
+ /* No relocation. */
+ HOWTO (R_MIPS_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit relocation. */
+ HOWTO (R_MIPS_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit relocation. */
+ HOWTO (R_MIPS_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit symbol relative relocation. */
+ HOWTO (R_MIPS_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 26 bit branch address. */
+ HOWTO (R_MIPS_26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ /* This needs complex overflow
+ detection, because the upper four
+ bits must match the PC. */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ true, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_hi16_reloc, /* special_function */
+ "R_MIPS_HI16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MIPS_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_lo16_reloc, /* special_function */
+ "R_MIPS_LO16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MIPS_GPREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MIPS_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MIPS_GOT16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_got16_reloc, /* special_function */
+ "R_MIPS_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. */
+ HOWTO (R_MIPS_PC16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ /* FIXME: This is not handled correctly. */
+ HOWTO (R_MIPS_CALL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit GP relative reference. */
+ HOWTO (R_MIPS_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ _bfd_mips_elf_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The remaining relocs are defined on Irix 5, although they are
+ not defined by the ABI. */
+ { 13 },
+ { 14 },
+ { 15 },
+
+ /* A 5 bit shift field. */
+ HOWTO (R_MIPS_SHIFT5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT5", /* name */
+ true, /* partial_inplace */
+ 0x000007c0, /* src_mask */
+ 0x000007c0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 6 bit shift field. */
+ /* FIXME: This is not handled correctly; a special function is
+ needed to put the most significant bit in the right place. */
+ HOWTO (R_MIPS_SHIFT6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ true, /* partial_inplace */
+ 0x000007c4, /* src_mask */
+ 0x000007c4, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit relocation. This is used in 32 bit ELF when addresses
+ are 64 bits long; the upper 32 bits are simply a sign extension.
+ The fields of the howto should be the same as for R_MIPS_32,
+ other than the type, name, and special_function. */
+ HOWTO (R_MIPS_64, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mips32_64bit_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_DISP", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_PAGE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_PAGE", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_OFST, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_OFST", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_HI16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_LO16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit subtraction. Presumably not used in 32 bit ELF. */
+ { R_MIPS_SUB },
+
+ /* Used to cause the linker to insert and delete instructions? */
+ { R_MIPS_INSERT_A },
+ { R_MIPS_INSERT_B },
+ { R_MIPS_DELETE },
+
+ /* Get the higher values of a 64 bit addend. Presumably not used in
+ 32 bit ELF. */
+ { R_MIPS_HIGHER },
+ { R_MIPS_HIGHEST },
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_CALL_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_HI16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_CALL_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { R_MIPS_SCN_DISP },
+ { R_MIPS_REL16 },
+ { R_MIPS_ADD_IMMEDIATE },
+ { R_MIPS_PJUMP },
+ { R_MIPS_RELGOT }
+};
+
+/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
+ is a hack to make the linker think that we need 64 bit values. */
+static reloc_howto_type elf_mips_ctor64_howto =
+ HOWTO (R_MIPS_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mips32_64bit_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* The reloc used for the mips16 jump instruction. */
+static reloc_howto_type elf_mips16_jump_howto =
+ HOWTO (R_MIPS16_26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ /* This needs complex overflow
+ detection, because the upper four
+ bits must match the PC. */
+ mips16_jump_reloc, /* special_function */
+ "R_MIPS16_26", /* name */
+ true, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* The reloc used for the mips16 gprel instruction. The src_mask and
+ dsk_mask for this howto do not reflect the actual instruction, in
+ which the value is not contiguous; the masks are for the
+ convenience of the relocate_section routine. */
+static reloc_howto_type elf_mips16_gprel_howto =
+ HOWTO (R_MIPS16_GPREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mips16_gprel_reloc, /* special_function */
+ "R_MIPS16_GPREL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false); /* pcrel_offset */
+
+
+/* GNU extension to record C++ vtable hierarchy */
+static reloc_howto_type elf_mips_gnu_vtinherit_howto =
+ HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_MIPS_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* GNU extension to record C++ vtable member usage */
+static reloc_howto_type elf_mips_gnu_vtentry_howto =
+ HOWTO (R_MIPS_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_MIPS_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* Do a R_MIPS_HI16 relocation. This has to be done in combination
+ with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
+ the HI16. Here we just save the information we need; we do the
+ actual relocation when we see the LO16. MIPS ELF requires that the
+ LO16 immediately follow the HI16. As a GNU extension, we permit an
+ arbitrary number of HI16 relocs to be associated with a single LO16
+ reloc. This extension permits gcc to output the HI and LO relocs
+ itself. */
+
+struct mips_hi16
+{
+ struct mips_hi16 *next;
+ bfd_byte *addr;
+ bfd_vma addend;
+};
+
+/* FIXME: This should not be a static variable. */
+
+static struct mips_hi16 *mips_hi16_list;
+
+bfd_reloc_status_type
+_bfd_mips_elf_hi16_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ struct mips_hi16 *n;
+
+ /* If we're relocating, and this an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ ret = bfd_reloc_ok;
+
+ if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
+ {
+ boolean relocateable;
+ bfd_vma gp;
+
+ if (ret == bfd_reloc_undefined)
+ abort ();
+
+ if (output_bfd != NULL)
+ relocateable = true;
+ else
+ {
+ relocateable = false;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocateable,
+ error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ relocation = gp - reloc_entry->address;
+ }
+ else
+ {
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ ret = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+ }
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Save the information, and let LO16 do the actual relocation. */
+ n = (struct mips_hi16 *) bfd_malloc (sizeof *n);
+ if (n == NULL)
+ return bfd_reloc_outofrange;
+ n->addr = (bfd_byte *) data + reloc_entry->address;
+ n->addend = relocation;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit
+ inplace relocation; this function exists in order to do the
+ R_MIPS_HI16 relocation described above. */
+
+bfd_reloc_status_type
+_bfd_mips_elf_lo16_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ arelent gp_disp_relent;
+
+ if (mips_hi16_list != NULL)
+ {
+ struct mips_hi16 *l;
+
+ l = mips_hi16_list;
+ while (l != NULL)
+ {
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+ struct mips_hi16 *next;
+
+ /* Do the HI16 relocation. Note that we actually don't need
+ to know anything about the LO16 itself, except where to
+ find the low 16 bits of the addend needed by the LO16. */
+ insn = bfd_get_32 (abfd, l->addr);
+ vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
+ & 0xffff);
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += l->addend;
+
+ /* The low order 16 bits are always treated as a signed
+ value. Therefore, a negative value in the low order bits
+ requires an adjustment in the high order bits. We need
+ to make this adjustment in two ways: once for the bits we
+ took from the data, and once for the bits we are putting
+ back in to the data. */
+ if ((vallo & 0x8000) != 0)
+ val -= 0x10000;
+ if ((val & 0x8000) != 0)
+ val += 0x10000;
+
+ insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (abfd, insn, l->addr);
+
+ if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
+ {
+ gp_disp_relent = *reloc_entry;
+ reloc_entry = &gp_disp_relent;
+ reloc_entry->addend = l->addend;
+ }
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+ else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
+ {
+ bfd_reloc_status_type ret;
+ bfd_vma gp, relocation;
+
+ /* FIXME: Does this case ever occur? */
+
+ ret = mips_elf_final_gp (output_bfd, symbol, true, error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ relocation = gp - reloc_entry->address;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ gp_disp_relent = *reloc_entry;
+ reloc_entry = &gp_disp_relent;
+ reloc_entry->addend = relocation - 4;
+ }
+
+ /* Now do the LO16 reloc in the usual way. */
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
+ table used for PIC code. If the symbol is an external symbol, the
+ instruction is modified to contain the offset of the appropriate
+ entry in the global offset table. If the symbol is a section
+ symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
+ addends are combined to form the real addend against the section
+ symbol; the GOT16 is modified to contain the offset of an entry in
+ the global offset table, and the LO16 is modified to offset it
+ appropriately. Thus an offset larger than 16 bits requires a
+ modified value in the global offset table.
+
+ This implementation suffices for the assembler, but the linker does
+ not yet know how to create global offset tables. */
+
+bfd_reloc_status_type
+_bfd_mips_elf_got16_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* If we're relocating, and this an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* If we're relocating, and this is a local symbol, we can handle it
+ just like HI16. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) != 0)
+ return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ abort ();
+}
+
+/* We have to figure out the gp value, so that we can adjust the
+ symbol value correctly. We look up the symbol _gp in the output
+ BFD. If we can't find it, we're stuck. We cache it in the ELF
+ target data. We don't need to adjust the symbol value for an
+ external symbol if we are producing relocateable output. */
+
+static bfd_reloc_status_type
+mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
+ bfd *output_bfd;
+ asymbol *symbol;
+ boolean relocateable;
+ char **error_message;
+ bfd_vma *pgp;
+{
+ if (bfd_is_und_section (symbol->section)
+ && ! relocateable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0
+ && (! relocateable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocateable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else
+ {
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ if (sym == (asymbol **) NULL)
+ i = count;
+ else
+ {
+ for (i = 0; i < count; i++, sym++)
+ {
+ register CONST char *name;
+
+ name = bfd_asymbol_name (*sym);
+ if (*name == '_' && strcmp (name, "_gp") == 0)
+ {
+ *pgp = bfd_asymbol_value (*sym);
+ _bfd_set_gp_value (output_bfd, *pgp);
+ break;
+ }
+ }
+ }
+
+ if (i >= count)
+ {
+ /* Only get the error once. */
+ *pgp = 4;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ *error_message =
+ (char *) _("GP relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
+ become the offset from the gp register. This function also handles
+ R_MIPS_LITERAL relocations, although those can be handled more
+ cleverly because the entries in the .lit8 and .lit4 sections can be
+ merged. */
+
+static bfd_reloc_status_type gprel16_with_gp PARAMS ((bfd *, asymbol *,
+ arelent *, asection *,
+ boolean, PTR, bfd_vma));
+
+bfd_reloc_status_type
+_bfd_mips_elf_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ boolean relocateable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* If we're relocating, and this is an external symbol with no
+ addend, we don't want to change anything. We will only have an
+ addend if this is a newly created reloc, not read from an ELF
+ file. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ relocateable = true;
+ else
+ {
+ relocateable = false;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocateable, data, gp);
+}
+
+static bfd_reloc_status_type
+gprel16_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data,
+ gp)
+ bfd *abfd;
+ asymbol *symbol;
+ arelent *reloc_entry;
+ asection *input_section;
+ boolean relocateable;
+ PTR data;
+ bfd_vma gp;
+{
+ bfd_vma relocation;
+ unsigned long insn;
+ unsigned long val;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Set val to the offset into the section or symbol. */
+ if (reloc_entry->howto->src_mask == 0)
+ {
+ /* This case occurs with the 64-bit MIPS ELF ABI. */
+ val = reloc_entry->addend;
+ }
+ else
+ {
+ val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
+ if (val & 0x8000)
+ val -= 0x10000;
+ }
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocateable output, we don't want to do this for
+ an external symbol. */
+ if (! relocateable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ insn = (insn &~ 0xffff) | (val & 0xffff);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if (relocateable)
+ reloc_entry->address += input_section->output_offset;
+
+ /* Make sure it fit in 16 bits. */
+ if (val >= 0x8000 && val < 0xffff8000)
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_ok;
+}
+
+/* Do a R_MIPS_GPREL32 relocation. Is this 32 bit value the offset
+ from the gp register? XXX */
+
+static bfd_reloc_status_type gprel32_with_gp PARAMS ((bfd *, asymbol *,
+ arelent *, asection *,
+ boolean, PTR, bfd_vma));
+
+bfd_reloc_status_type
+_bfd_mips_elf_gprel32_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ boolean relocateable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* If we're relocating, and this is an external symbol with no
+ addend, we don't want to change anything. We will only have an
+ addend if this is a newly created reloc, not read from an ELF
+ file. */
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ *error_message = (char *)
+ _("32bits gp relative relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ relocateable = true;
+ gp = _bfd_get_gp_value (output_bfd);
+ }
+ else
+ {
+ relocateable = false;
+ output_bfd = symbol->section->output_section->owner;
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocateable,
+ error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+ }
+
+ return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocateable, data, gp);
+}
+
+static bfd_reloc_status_type
+gprel32_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data,
+ gp)
+ bfd *abfd;
+ asymbol *symbol;
+ arelent *reloc_entry;
+ asection *input_section;
+ boolean relocateable;
+ PTR data;
+ bfd_vma gp;
+{
+ bfd_vma relocation;
+ unsigned long val;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ if (reloc_entry->howto->src_mask == 0)
+ {
+ /* This case arises with the 64-bit MIPS ELF ABI. */
+ val = 0;
+ }
+ else
+ val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Set val to the offset into the section or symbol. */
+ val += reloc_entry->addend;
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocateable output, we don't want to do this for
+ an external symbol. */
+ if (! relocateable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+
+ if (relocateable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+/* Handle a 64 bit reloc in a 32 bit MIPS ELF file. These are
+ generated when addreses are 64 bits. The upper 32 bits are a simle
+ sign extension. */
+
+static bfd_reloc_status_type
+mips32_64bit_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_reloc_status_type r;
+ arelent reloc32;
+ unsigned long val;
+ bfd_size_type addr;
+
+ r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+ if (r != bfd_reloc_continue)
+ return r;
+
+ /* Do a normal 32 bit relocation on the lower 32 bits. */
+ reloc32 = *reloc_entry;
+ if (bfd_big_endian (abfd))
+ reloc32.address += 4;
+ reloc32.howto = &elf_mips_howto_table[R_MIPS_32];
+ r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
+ output_bfd, error_message);
+
+ /* Sign extend into the upper 32 bits. */
+ val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
+ if ((val & 0x80000000) != 0)
+ val = 0xffffffff;
+ else
+ val = 0;
+ addr = reloc_entry->address;
+ if (bfd_little_endian (abfd))
+ addr += 4;
+ bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
+
+ return r;
+}
+
+/* Handle a mips16 jump. */
+
+static bfd_reloc_status_type
+mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* FIXME. */
+ {
+ static boolean warned;
+
+ if (! warned)
+ (*_bfd_error_handler)
+ (_("Linking mips16 objects into %s format is not supported"),
+ bfd_get_target (input_section->output_section->owner));
+ warned = true;
+ }
+
+ return bfd_reloc_undefined;
+}
+
+/* Handle a mips16 GP relative reloc. */
+
+static bfd_reloc_status_type
+mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ boolean relocateable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+ unsigned short extend, insn;
+ unsigned long final;
+
+ /* If we're relocating, and this is an external symbol with no
+ addend, we don't want to change anything. We will only have an
+ addend if this is a newly created reloc, not read from an ELF
+ file. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ relocateable = true;
+ else
+ {
+ relocateable = false;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Pick up the mips16 extend instruction and the real instruction. */
+ extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
+ insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
+
+ /* Stuff the current addend back as a 32 bit value, do the usual
+ relocation, and then clean up. */
+ bfd_put_32 (abfd,
+ (((extend & 0x1f) << 11)
+ | (extend & 0x7e0)
+ | (insn & 0x1f)),
+ (bfd_byte *) data + reloc_entry->address);
+
+ ret = gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocateable, data, gp);
+
+ final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ bfd_put_16 (abfd,
+ ((extend & 0xf800)
+ | ((final >> 11) & 0x1f)
+ | (final & 0x7e0)),
+ (bfd_byte *) data + reloc_entry->address);
+ bfd_put_16 (abfd,
+ ((insn & 0xffe0)
+ | (final & 0x1f)),
+ (bfd_byte *) data + reloc_entry->address + 2);
+
+ return ret;
+}
+
+/* Return the ISA for a MIPS e_flags value. */
+
+static INLINE int
+elf_mips_isa (flags)
+ flagword flags;
+{
+ switch (flags & EF_MIPS_ARCH)
+ {
+ case E_MIPS_ARCH_1:
+ return 1;
+ case E_MIPS_ARCH_2:
+ return 2;
+ case E_MIPS_ARCH_3:
+ return 3;
+ case E_MIPS_ARCH_4:
+ return 4;
+ }
+ return 4;
+}
+
+/* Return the MACH for a MIPS e_flags value. */
+
+static INLINE int
+elf_mips_mach (flags)
+ flagword flags;
+{
+ switch (flags & EF_MIPS_MACH)
+ {
+ case E_MIPS_MACH_3900:
+ return bfd_mach_mips3900;
+
+ case E_MIPS_MACH_4010:
+ return bfd_mach_mips4010;
+
+ case E_MIPS_MACH_4100:
+ return bfd_mach_mips4100;
+
+ case E_MIPS_MACH_4111:
+ return bfd_mach_mips4111;
+
+ case E_MIPS_MACH_4650:
+ return bfd_mach_mips4650;
+
+ default:
+ switch (flags & EF_MIPS_ARCH)
+ {
+ default:
+ case E_MIPS_ARCH_1:
+ return bfd_mach_mips3000;
+ break;
+
+ case E_MIPS_ARCH_2:
+ return bfd_mach_mips6000;
+ break;
+
+ case E_MIPS_ARCH_3:
+ return bfd_mach_mips4000;
+ break;
+
+ case E_MIPS_ARCH_4:
+ return bfd_mach_mips8000;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* Return printable name for ABI from flagword. */
+
+static INLINE char*
+elf_mips_abi_name (flags)
+ flagword flags;
+{
+ switch (flags & EF_MIPS_ABI)
+ {
+ case 0:
+ return "none";
+ case E_MIPS_ABI_O32:
+ return "O32";
+ case E_MIPS_ABI_O64:
+ return "O64";
+ case E_MIPS_ABI_EABI32:
+ return "EABI32";
+ case E_MIPS_ABI_EABI64:
+ return "EABI64";
+ default:
+ return "unknown abi";
+ }
+}
+
+/* A mapping from BFD reloc types to MIPS ELF reloc types. */
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ enum elf_mips_reloc_type elf_reloc_val;
+};
+
+static CONST struct elf_reloc_map mips_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_MIPS_NONE, },
+ { BFD_RELOC_16, R_MIPS_16 },
+ { BFD_RELOC_32, R_MIPS_32 },
+ { BFD_RELOC_64, R_MIPS_64 },
+ { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
+ { BFD_RELOC_HI16_S, R_MIPS_HI16 },
+ { BFD_RELOC_LO16, R_MIPS_LO16 },
+ { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
+ { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
+ { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
+ { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
+ { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
+ { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
+ { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
+ { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
+ { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
+ { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }
+};
+
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (mips_reloc_map[i].bfd_reloc_val == code)
+ return &elf_mips_howto_table[(int) mips_reloc_map[i].elf_reloc_val];
+ }
+
+ switch (code)
+ {
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+
+ case BFD_RELOC_CTOR:
+ /* We need to handle BFD_RELOC_CTOR specially.
+ Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
+ size of addresses on this architecture. */
+ if (bfd_arch_bits_per_address (abfd) == 32)
+ return &elf_mips_howto_table[(int) R_MIPS_32];
+ else
+ return &elf_mips_ctor64_howto;
+
+ case BFD_RELOC_MIPS16_JMP:
+ return &elf_mips16_jump_howto;
+ case BFD_RELOC_MIPS16_GPREL:
+ return &elf_mips16_gprel_howto;
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ }
+}
+
+/* Given a MIPS reloc type, fill in an arelent structure. */
+
+static void
+mips_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rel *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ switch (r_type)
+ {
+ case R_MIPS16_26:
+ cache_ptr->howto = &elf_mips16_jump_howto;
+ break;
+ case R_MIPS16_GPREL:
+ cache_ptr->howto = &elf_mips16_gprel_howto;
+ break;
+ case R_MIPS_GNU_VTINHERIT:
+ cache_ptr->howto = &elf_mips_gnu_vtinherit_howto;
+ break;
+ case R_MIPS_GNU_VTENTRY:
+ cache_ptr->howto = &elf_mips_gnu_vtentry_howto;
+ break;
+
+ default:
+ BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
+ cache_ptr->howto = &elf_mips_howto_table[r_type];
+ break;
+ }
+
+ /* The addend for a GPREL16 or LITERAL relocation comes from the GP
+ value for the object file. We get the addend now, rather than
+ when we do the relocation, because the symbol manipulations done
+ by the linker may cause us to lose track of the input BFD. */
+ if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
+ && (r_type == (unsigned int) R_MIPS_GPREL16
+ || r_type == (unsigned int) R_MIPS_LITERAL))
+ cache_ptr->addend = elf_gp (abfd);
+}
+
+/* A .reginfo section holds a single Elf32_RegInfo structure. These
+ routines swap this structure in and out. They are used outside of
+ BFD, so they are globally visible. */
+
+void
+bfd_mips_elf32_swap_reginfo_in (abfd, ex, in)
+ bfd *abfd;
+ const Elf32_External_RegInfo *ex;
+ Elf32_RegInfo *in;
+{
+ in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
+ in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
+ in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
+ in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
+ in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
+ in->ri_gp_value = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gp_value);
+}
+
+void
+bfd_mips_elf32_swap_reginfo_out (abfd, in, ex)
+ bfd *abfd;
+ const Elf32_RegInfo *in;
+ Elf32_External_RegInfo *ex;
+{
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
+ (bfd_byte *) ex->ri_gprmask);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
+ (bfd_byte *) ex->ri_cprmask[0]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
+ (bfd_byte *) ex->ri_cprmask[1]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
+ (bfd_byte *) ex->ri_cprmask[2]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
+ (bfd_byte *) ex->ri_cprmask[3]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_gp_value,
+ (bfd_byte *) ex->ri_gp_value);
+}
+
+/* In the 64 bit ABI, the .MIPS.options section holds register
+ information in an Elf64_Reginfo structure. These routines swap
+ them in and out. They are globally visible because they are used
+ outside of BFD. These routines are here so that gas can call them
+ without worrying about whether the 64 bit ABI has been included. */
+
+void
+bfd_mips_elf64_swap_reginfo_in (abfd, ex, in)
+ bfd *abfd;
+ const Elf64_External_RegInfo *ex;
+ Elf64_Internal_RegInfo *in;
+{
+ in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
+ in->ri_pad = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_pad);
+ in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
+ in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
+ in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
+ in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
+ in->ri_gp_value = bfd_h_get_64 (abfd, (bfd_byte *) ex->ri_gp_value);
+}
+
+void
+bfd_mips_elf64_swap_reginfo_out (abfd, in, ex)
+ bfd *abfd;
+ const Elf64_Internal_RegInfo *in;
+ Elf64_External_RegInfo *ex;
+{
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
+ (bfd_byte *) ex->ri_gprmask);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_pad,
+ (bfd_byte *) ex->ri_pad);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
+ (bfd_byte *) ex->ri_cprmask[0]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
+ (bfd_byte *) ex->ri_cprmask[1]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
+ (bfd_byte *) ex->ri_cprmask[2]);
+ bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
+ (bfd_byte *) ex->ri_cprmask[3]);
+ bfd_h_put_64 (abfd, (bfd_vma) in->ri_gp_value,
+ (bfd_byte *) ex->ri_gp_value);
+}
+
+/* Swap an entry in a .gptab section. Note that these routines rely
+ on the equivalence of the two elements of the union. */
+
+static void
+bfd_mips_elf32_swap_gptab_in (abfd, ex, in)
+ bfd *abfd;
+ const Elf32_External_gptab *ex;
+ Elf32_gptab *in;
+{
+ in->gt_entry.gt_g_value = bfd_h_get_32 (abfd, ex->gt_entry.gt_g_value);
+ in->gt_entry.gt_bytes = bfd_h_get_32 (abfd, ex->gt_entry.gt_bytes);
+}
+
+static void
+bfd_mips_elf32_swap_gptab_out (abfd, in, ex)
+ bfd *abfd;
+ const Elf32_gptab *in;
+ Elf32_External_gptab *ex;
+{
+ bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_g_value,
+ ex->gt_entry.gt_g_value);
+ bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_bytes,
+ ex->gt_entry.gt_bytes);
+}
+
+static void
+bfd_elf32_swap_compact_rel_out (abfd, in, ex)
+ bfd *abfd;
+ const Elf32_compact_rel *in;
+ Elf32_External_compact_rel *ex;
+{
+ bfd_h_put_32 (abfd, (bfd_vma) in->id1, ex->id1);
+ bfd_h_put_32 (abfd, (bfd_vma) in->num, ex->num);
+ bfd_h_put_32 (abfd, (bfd_vma) in->id2, ex->id2);
+ bfd_h_put_32 (abfd, (bfd_vma) in->offset, ex->offset);
+ bfd_h_put_32 (abfd, (bfd_vma) in->reserved0, ex->reserved0);
+ bfd_h_put_32 (abfd, (bfd_vma) in->reserved1, ex->reserved1);
+}
+
+static void
+bfd_elf32_swap_crinfo_out (abfd, in, ex)
+ bfd *abfd;
+ const Elf32_crinfo *in;
+ Elf32_External_crinfo *ex;
+{
+ unsigned long l;
+
+ l = (((in->ctype & CRINFO_CTYPE) << CRINFO_CTYPE_SH)
+ | ((in->rtype & CRINFO_RTYPE) << CRINFO_RTYPE_SH)
+ | ((in->dist2to & CRINFO_DIST2TO) << CRINFO_DIST2TO_SH)
+ | ((in->relvaddr & CRINFO_RELVADDR) << CRINFO_RELVADDR_SH));
+ bfd_h_put_32 (abfd, (bfd_vma) l, ex->info);
+ bfd_h_put_32 (abfd, (bfd_vma) in->konst, ex->konst);
+ bfd_h_put_32 (abfd, (bfd_vma) in->vaddr, ex->vaddr);
+}
+
+/* Swap in an options header. */
+
+void
+bfd_mips_elf_swap_options_in (abfd, ex, in)
+ bfd *abfd;
+ const Elf_External_Options *ex;
+ Elf_Internal_Options *in;
+{
+ in->kind = bfd_h_get_8 (abfd, ex->kind);
+ in->size = bfd_h_get_8 (abfd, ex->size);
+ in->section = bfd_h_get_16 (abfd, ex->section);
+ in->info = bfd_h_get_32 (abfd, ex->info);
+}
+
+/* Swap out an options header. */
+
+void
+bfd_mips_elf_swap_options_out (abfd, in, ex)
+ bfd *abfd;
+ const Elf_Internal_Options *in;
+ Elf_External_Options *ex;
+{
+ bfd_h_put_8 (abfd, in->kind, ex->kind);
+ bfd_h_put_8 (abfd, in->size, ex->size);
+ bfd_h_put_16 (abfd, in->section, ex->section);
+ bfd_h_put_32 (abfd, in->info, ex->info);
+}
+
+/* Determine whether a symbol is global for the purposes of splitting
+ the symbol table into global symbols and local symbols. At least
+ on Irix 5, this split must be between section symbols and all other
+ symbols. On most ELF targets the split is between static symbols
+ and externally visible symbols. */
+
+/*ARGSUSED*/
+static boolean
+mips_elf_sym_is_global (abfd, sym)
+ bfd *abfd;
+ asymbol *sym;
+{
+ return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
+}
+
+/* Set the right machine number for a MIPS ELF file. This is used for
+ both the 32-bit and the 64-bit ABI. */
+
+boolean
+_bfd_mips_elf_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_mips,
+ elf_mips_mach (elf_elfheader (abfd)->e_flags));
+ return true;
+}
+
+/* Set the right machine number for a 32-bit MIPS ELF file. */
+
+static boolean
+mips_elf32_object_p (abfd)
+ bfd *abfd;
+{
+ /* Irix 5 is broken. Object file symbol tables are not always
+ sorted correctly such that local symbols precede global symbols,
+ and the sh_info field in the symbol table is not always right. */
+ elf_bad_symtab (abfd) = true;
+
+ return _bfd_mips_elf_object_p (abfd);
+}
+
+/* The final processing done just before writing out a MIPS ELF object
+ file. This gets the MIPS architecture right based on the machine
+ number. This is used by both the 32-bit and the 64-bit ABI. */
+
+/*ARGSUSED*/
+void
+_bfd_mips_elf_final_write_processing (abfd, linker)
+ bfd *abfd;
+ boolean linker;
+{
+ unsigned long val;
+ unsigned int i;
+ Elf_Internal_Shdr **hdrpp;
+ const char *name;
+ asection *sec;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_mips3000:
+ val = E_MIPS_ARCH_1;
+ break;
+
+ case bfd_mach_mips3900:
+ val = E_MIPS_ARCH_1 | E_MIPS_MACH_3900;
+ break;
+
+ case bfd_mach_mips6000:
+ val = E_MIPS_ARCH_2;
+ break;
+
+ case bfd_mach_mips4000:
+ case bfd_mach_mips4300:
+ val = E_MIPS_ARCH_3;
+ break;
+
+ case bfd_mach_mips4010:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4010;
+ break;
+
+ case bfd_mach_mips4100:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4100;
+ break;
+
+ case bfd_mach_mips4111:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4111;
+ break;
+
+ case bfd_mach_mips4650:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650;
+ break;
+
+ case bfd_mach_mips8000:
+ val = E_MIPS_ARCH_4;
+ break;
+ }
+
+ elf_elfheader (abfd)->e_flags &= ~ (EF_MIPS_ARCH | EF_MIPS_MACH);
+ elf_elfheader (abfd)->e_flags |= val;
+
+ /* Set the sh_info field for .gptab sections and other appropriate
+ info for each special section. */
+ for (i = 1, hdrpp = elf_elfsections (abfd) + 1;
+ i < elf_elfheader (abfd)->e_shnum;
+ i++, hdrpp++)
+ {
+ switch ((*hdrpp)->sh_type)
+ {
+ case SHT_MIPS_LIBLIST:
+ sec = bfd_get_section_by_name (abfd, ".dynstr");
+ if (sec != NULL)
+ (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
+ break;
+
+ case SHT_MIPS_GPTAB:
+ BFD_ASSERT ((*hdrpp)->bfd_section != NULL);
+ name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section);
+ BFD_ASSERT (name != NULL
+ && strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0);
+ sec = bfd_get_section_by_name (abfd, name + sizeof ".gptab" - 1);
+ BFD_ASSERT (sec != NULL);
+ (*hdrpp)->sh_info = elf_section_data (sec)->this_idx;
+ break;
+
+ case SHT_MIPS_CONTENT:
+ BFD_ASSERT ((*hdrpp)->bfd_section != NULL);
+ name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section);
+ BFD_ASSERT (name != NULL
+ && strncmp (name, ".MIPS.content",
+ sizeof ".MIPS.content" - 1) == 0);
+ sec = bfd_get_section_by_name (abfd,
+ name + sizeof ".MIPS.content" - 1);
+ BFD_ASSERT (sec != NULL);
+ (*hdrpp)->sh_info = elf_section_data (sec)->this_idx;
+ break;
+
+ case SHT_MIPS_SYMBOL_LIB:
+ sec = bfd_get_section_by_name (abfd, ".dynsym");
+ if (sec != NULL)
+ (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
+ sec = bfd_get_section_by_name (abfd, ".liblist");
+ if (sec != NULL)
+ (*hdrpp)->sh_info = elf_section_data (sec)->this_idx;
+ break;
+
+ case SHT_MIPS_EVENTS:
+ BFD_ASSERT ((*hdrpp)->bfd_section != NULL);
+ name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section);
+ BFD_ASSERT (name != NULL);
+ if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) == 0)
+ sec = bfd_get_section_by_name (abfd,
+ name + sizeof ".MIPS.events" - 1);
+ else
+ {
+ BFD_ASSERT (strncmp (name, ".MIPS.post_rel",
+ sizeof ".MIPS.post_rel" - 1) == 0);
+ sec = bfd_get_section_by_name (abfd,
+ (name
+ + sizeof ".MIPS.post_rel" - 1));
+ }
+ BFD_ASSERT (sec != NULL);
+ (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
+ break;
+
+ }
+ }
+}
+
+/* Function to keep MIPS specific file flags like as EF_MIPS_PIC. */
+
+boolean
+_bfd_mips_elf_set_private_flags (abfd, flags)
+ bfd *abfd;
+ flagword flags;
+{
+ BFD_ASSERT (!elf_flags_init (abfd)
+ || elf_elfheader (abfd)->e_flags == flags);
+
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ return true;
+}
+
+/* Copy backend specific data from one object module to another */
+
+boolean
+_bfd_mips_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || (elf_elfheader (obfd)->e_flags
+ == elf_elfheader (ibfd)->e_flags));
+
+ elf_gp (obfd) = elf_gp (ibfd);
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+boolean
+_bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ flagword old_flags;
+ flagword new_flags;
+ boolean ok;
+
+ /* Check if we have the same endianess */
+ if (ibfd->xvec->byteorder != obfd->xvec->byteorder
+ && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ const char *msg;
+
+ if (bfd_big_endian (ibfd))
+ msg = _("%s: compiled for a big endian system and target is little endian");
+ else
+ msg = _("%s: compiled for a little endian system and target is big endian");
+
+ (*_bfd_error_handler) (msg, bfd_get_filename (ibfd));
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = new_flags;
+
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
+ && bfd_get_arch_info (obfd)->the_default)
+ {
+ if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
+ bfd_get_mach (ibfd)))
+ return false;
+ }
+
+ return true;
+ }
+
+ /* Check flag compatibility. */
+
+ new_flags &= ~EF_MIPS_NOREORDER;
+ old_flags &= ~EF_MIPS_NOREORDER;
+
+ if (new_flags == old_flags)
+ return true;
+
+ ok = true;
+
+ if ((new_flags & EF_MIPS_PIC) != (old_flags & EF_MIPS_PIC))
+ {
+ new_flags &= ~EF_MIPS_PIC;
+ old_flags &= ~EF_MIPS_PIC;
+ (*_bfd_error_handler)
+ (_("%s: linking PIC files with non-PIC files"),
+ bfd_get_filename (ibfd));
+ ok = false;
+ }
+
+ if ((new_flags & EF_MIPS_CPIC) != (old_flags & EF_MIPS_CPIC))
+ {
+ new_flags &= ~EF_MIPS_CPIC;
+ old_flags &= ~EF_MIPS_CPIC;
+ (*_bfd_error_handler)
+ (_("%s: linking abicalls files with non-abicalls files"),
+ bfd_get_filename (ibfd));
+ ok = false;
+ }
+
+ /* Compare the ISA's. */
+ if ((new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH))
+ != (old_flags & (EF_MIPS_ARCH | EF_MIPS_MACH)))
+ {
+ int new_mach = new_flags & EF_MIPS_MACH;
+ int old_mach = old_flags & EF_MIPS_MACH;
+ int new_isa = elf_mips_isa (new_flags);
+ int old_isa = elf_mips_isa (old_flags);
+
+ /* If either has no machine specified, just compare the general isa's.
+ Some combinations of machines are ok, if the isa's match. */
+ if (! new_mach
+ || ! old_mach
+ || new_mach == old_mach
+ )
+ {
+ /* Don't warn about mixing -mips1 and -mips2 code, or mixing -mips3
+ and -mips4 code. They will normally use the same data sizes and
+ calling conventions. */
+
+ if ((new_isa == 1 || new_isa == 2)
+ ? (old_isa != 1 && old_isa != 2)
+ : (old_isa == 1 || old_isa == 2))
+ {
+ (*_bfd_error_handler)
+ (_("%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"),
+ bfd_get_filename (ibfd), new_isa, old_isa);
+ ok = false;
+ }
+ }
+
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: ISA mismatch (%d) with previous modules (%d)"),
+ bfd_get_filename (ibfd),
+ elf_mips_mach (new_flags),
+ elf_mips_mach (old_flags));
+ ok = false;
+ }
+
+ new_flags &= ~ (EF_MIPS_ARCH | EF_MIPS_MACH);
+ old_flags &= ~ (EF_MIPS_ARCH | EF_MIPS_MACH);
+ }
+
+ /* Compare ABI's */
+ if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI))
+ {
+ /* Only error if both are set (to different values). */
+ if ((new_flags & EF_MIPS_ABI)
+ && (old_flags & EF_MIPS_ABI))
+ {
+ (*_bfd_error_handler)
+ (_("%s: ABI mismatch: linking %s module with previous %s modules"),
+ bfd_get_filename (ibfd),
+ elf_mips_abi_name (new_flags),
+ elf_mips_abi_name (old_flags));
+ ok = false;
+ }
+ new_flags &= ~EF_MIPS_ABI;
+ old_flags &= ~EF_MIPS_ABI;
+ }
+
+ /* Warn about any other mismatches */
+ if (new_flags != old_flags)
+ {
+ (*_bfd_error_handler)
+ (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ bfd_get_filename (ibfd), (unsigned long) new_flags,
+ (unsigned long) old_flags);
+ ok = false;
+ }
+
+ if (! ok)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ return true;
+}
+
+static boolean
+_bfd_mips_elf_print_private_bfd_data (abfd, ptr)
+ bfd *abfd;
+ PTR ptr;
+{
+ FILE *file = (FILE *) ptr;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ /* xgettext:c-format */
+ fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
+
+ if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_O32)
+ fprintf (file, _ (" [abi=O32]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_O64)
+ fprintf (file, _ (" [abi=O64]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32)
+ fprintf (file, _ (" [abi=EABI32]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64)
+ fprintf (file, _ (" [abi=EABI64]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI))
+ fprintf (file, _ (" [abi unknown]"));
+ else
+ fprintf (file, _ (" [no abi set]"));
+
+ if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
+ fprintf (file, _ (" [mips1]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
+ fprintf (file, _ (" [mips2]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
+ fprintf (file, _ (" [mips3]"));
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
+ fprintf (file, _ (" [mips4]"));
+ else
+ fprintf (file, _ (" [unknown ISA]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_32BITMODE)
+ fprintf (file, _ (" [32bitmode]"));
+ else
+ fprintf (file, _ (" [not 32bitmode]"));
+
+ fputc ('\n', file);
+
+ return true;
+}
+
+/* Handle a MIPS specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type.
+ This routine supports both the 32-bit and 64-bit ELF ABI.
+
+ FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure
+ how to. */
+
+boolean
+_bfd_mips_elf_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ const char *name;
+{
+ flagword flags = 0;
+
+ /* There ought to be a place to keep ELF backend specific flags, but
+ at the moment there isn't one. We just keep track of the
+ sections by their name, instead. Fortunately, the ABI gives
+ suggested names for all the MIPS specific sections, so we will
+ probably get away with this. */
+ switch (hdr->sh_type)
+ {
+ case SHT_MIPS_LIBLIST:
+ if (strcmp (name, ".liblist") != 0)
+ return false;
+ break;
+ case SHT_MIPS_MSYM:
+ if (strcmp (name, ".msym") != 0)
+ return false;
+ break;
+ case SHT_MIPS_CONFLICT:
+ if (strcmp (name, ".conflict") != 0)
+ return false;
+ break;
+ case SHT_MIPS_GPTAB:
+ if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) != 0)
+ return false;
+ break;
+ case SHT_MIPS_UCODE:
+ if (strcmp (name, ".ucode") != 0)
+ return false;
+ break;
+ case SHT_MIPS_DEBUG:
+ if (strcmp (name, ".mdebug") != 0)
+ return false;
+ flags = SEC_DEBUGGING;
+ break;
+ case SHT_MIPS_REGINFO:
+ if (strcmp (name, ".reginfo") != 0
+ || hdr->sh_size != sizeof (Elf32_External_RegInfo))
+ return false;
+ flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE);
+ break;
+ case SHT_MIPS_IFACE:
+ if (strcmp (name, ".MIPS.interfaces") != 0)
+ return false;
+ break;
+ case SHT_MIPS_CONTENT:
+ if (strncmp (name, ".MIPS.content", sizeof ".MIPS.content" - 1) != 0)
+ return false;
+ break;
+ case SHT_MIPS_OPTIONS:
+ if (strcmp (name, ".options") != 0
+ && strcmp (name, ".MIPS.options") != 0)
+ return false;
+ break;
+ case SHT_MIPS_DWARF:
+ if (strncmp (name, ".debug_", sizeof ".debug_" - 1) != 0)
+ return false;
+ break;
+ case SHT_MIPS_SYMBOL_LIB:
+ if (strcmp (name, ".MIPS.symlib") != 0)
+ return false;
+ break;
+ case SHT_MIPS_EVENTS:
+ if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) != 0
+ && strncmp (name, ".MIPS.post_rel",
+ sizeof ".MIPS.post_rel" - 1) != 0)
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+
+ if (flags)
+ {
+ if (! bfd_set_section_flags (abfd, hdr->bfd_section,
+ (bfd_get_section_flags (abfd,
+ hdr->bfd_section)
+ | flags)))
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle a 32-bit MIPS ELF specific section. */
+
+static boolean
+mips_elf32_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ char *name;
+{
+ if (! _bfd_mips_elf_section_from_shdr (abfd, hdr, name))
+ return false;
+
+ /* FIXME: We should record sh_info for a .gptab section. */
+
+ /* For a .reginfo section, set the gp value in the tdata information
+ from the contents of this section. We need the gp value while
+ processing relocs, so we just get it now. The .reginfo section
+ is not used in the 64-bit MIPS ELF ABI. */
+ if (hdr->sh_type == SHT_MIPS_REGINFO)
+ {
+ Elf32_External_RegInfo ext;
+ Elf32_RegInfo s;
+
+ if (! bfd_get_section_contents (abfd, hdr->bfd_section, (PTR) &ext,
+ (file_ptr) 0, sizeof ext))
+ return false;
+ bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
+ elf_gp (abfd) = s.ri_gp_value;
+ }
+
+ /* For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and
+ set the gp value based on what we find. We may see both
+ SHT_MIPS_REGINFO and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case,
+ they should agree. */
+ if (hdr->sh_type == SHT_MIPS_OPTIONS)
+ {
+ bfd_byte *contents, *l, *lend;
+
+ contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
+ if (contents == NULL)
+ return false;
+ if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
+ (file_ptr) 0, hdr->sh_size))
+ {
+ free (contents);
+ return false;
+ }
+ l = contents;
+ lend = contents + hdr->sh_size;
+ while (l + sizeof (Elf_External_Options) <= lend)
+ {
+ Elf_Internal_Options intopt;
+
+ bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
+ &intopt);
+ if (intopt.kind == ODK_REGINFO)
+ {
+ Elf32_RegInfo intreg;
+
+ bfd_mips_elf32_swap_reginfo_in
+ (abfd,
+ ((Elf32_External_RegInfo *)
+ (l + sizeof (Elf_External_Options))),
+ &intreg);
+ elf_gp (abfd) = intreg.ri_gp_value;
+ }
+ l += intopt.size;
+ }
+ free (contents);
+ }
+
+ return true;
+}
+
+/* Set the correct type for a MIPS ELF section. We do this by the
+ section name, which is a hack, but ought to work. This routine is
+ used by both the 32-bit and the 64-bit ABI. */
+
+boolean
+_bfd_mips_elf_fake_sections (abfd, hdr, sec)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+ asection *sec;
+{
+ register const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".liblist") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_LIBLIST;
+ hdr->sh_info = sec->_raw_size / sizeof (Elf32_Lib);
+ /* The sh_link field is set in final_write_processing. */
+ }
+ else if (strcmp (name, ".msym") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_MSYM;
+ hdr->sh_entsize = 8;
+ /* FIXME: Set the sh_info field. */
+ }
+ else if (strcmp (name, ".conflict") == 0)
+ hdr->sh_type = SHT_MIPS_CONFLICT;
+ else if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0)
+ {
+ hdr->sh_type = SHT_MIPS_GPTAB;
+ hdr->sh_entsize = sizeof (Elf32_External_gptab);
+ /* The sh_info field is set in final_write_processing. */
+ }
+ else if (strcmp (name, ".ucode") == 0)
+ hdr->sh_type = SHT_MIPS_UCODE;
+ else if (strcmp (name, ".mdebug") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_DEBUG;
+ /* In a shared object on Irix 5.3, the .mdebug section has an
+ entsize of 0. FIXME: Does this matter? */
+ if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0)
+ hdr->sh_entsize = 0;
+ else
+ hdr->sh_entsize = 1;
+ }
+ else if (strcmp (name, ".reginfo") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_REGINFO;
+ /* In a shared object on Irix 5.3, the .reginfo section has an
+ entsize of 0x18. FIXME: Does this matter? */
+ if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0)
+ hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
+ else
+ hdr->sh_entsize = 1;
+ }
+ else if (SGI_COMPAT (abfd)
+ && (strcmp (name, ".hash") == 0
+ || strcmp (name, ".dynamic") == 0
+ || strcmp (name, ".dynstr") == 0))
+ {
+ hdr->sh_entsize = 0;
+#if 0
+ /* This isn't how the Irix 6 linker behaves. */
+ hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#endif
+ }
+ else if (strcmp (name, ".got") == 0
+ || strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0
+ || strcmp (name, ".lit4") == 0
+ || strcmp (name, ".lit8") == 0)
+ hdr->sh_flags |= SHF_MIPS_GPREL;
+ else if (strcmp (name, ".MIPS.interfaces") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_IFACE;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ }
+ else if (strcmp (name, ".MIPS.content") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_CONTENT;
+ /* The sh_info field is set in final_write_processing. */
+ }
+ else if (strcmp (name, ".options") == 0
+ || strcmp (name, ".MIPS.options") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_OPTIONS;
+ hdr->sh_entsize = 1;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ }
+ else if (strncmp (name, ".debug_", sizeof ".debug_" - 1) == 0)
+ hdr->sh_type = SHT_MIPS_DWARF;
+ else if (strcmp (name, ".MIPS.symlib") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_SYMBOL_LIB;
+ /* The sh_link and sh_info fields are set in
+ final_write_processing. */
+ }
+ else if (strncmp (name, ".MIPS.events", sizeof ".MIPS.events" - 1) == 0
+ || strncmp (name, ".MIPS.post_rel",
+ sizeof ".MIPS.post_rel" - 1) == 0)
+ {
+ hdr->sh_type = SHT_MIPS_EVENTS;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ /* The sh_link field is set in final_write_processing. */
+ }
+
+ return true;
+}
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. This is used by both the 32-bit and the 64-bit ABI.
+ Actually, it's not clear to me that the 64-bit ABI supports these,
+ but for non-PIC objects we will certainly want support for at least
+ the .scommon section. */
+
+boolean
+_bfd_mips_elf_section_from_bfd_section (abfd, hdr, sec, retval)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+ asection *sec;
+ int *retval;
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+ {
+ *retval = SHN_MIPS_SCOMMON;
+ return true;
+ }
+ if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0)
+ {
+ *retval = SHN_MIPS_ACOMMON;
+ return true;
+ }
+ return false;
+}
+
+/* When are writing out the .options or .MIPS.options section,
+ remember the bytes we are writing out, so that we can install the
+ GP value in the section_processing routine. */
+
+boolean
+_bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (strcmp (section->name, ".options") == 0
+ || strcmp (section->name, ".MIPS.options") == 0)
+ {
+ bfd_byte *c;
+
+ if (elf_section_data (section) == NULL)
+ {
+ section->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data));
+ if (elf_section_data (section) == NULL)
+ return false;
+ }
+ c = (bfd_byte *) elf_section_data (section)->tdata;
+ if (c == NULL)
+ {
+ bfd_size_type size;
+
+ if (section->_cooked_size != 0)
+ size = section->_cooked_size;
+ else
+ size = section->_raw_size;
+ c = (bfd_byte *) bfd_zalloc (abfd, size);
+ if (c == NULL)
+ return false;
+ elf_section_data (section)->tdata = (PTR) c;
+ }
+
+ memcpy (c + offset, location, count);
+ }
+
+ return _bfd_elf_set_section_contents (abfd, section, location, offset,
+ count);
+}
+
+/* Work over a section just before writing it out. This routine is
+ used by both the 32-bit and the 64-bit ABI. FIXME: We recognize
+ sections that need the SHF_MIPS_GPREL flag by name; there has to be
+ a better way. */
+
+boolean
+_bfd_mips_elf_section_processing (abfd, hdr)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+{
+ if (hdr->bfd_section != NULL)
+ {
+ const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
+
+ if (strcmp (name, ".sdata") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ else if (strcmp (name, ".sbss") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+ hdr->sh_type = SHT_NOBITS;
+ }
+ else if (strcmp (name, ".lit8") == 0
+ || strcmp (name, ".lit4") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ else if (strcmp (name, ".compact_rel") == 0)
+ {
+ hdr->sh_flags = 0;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ else if (strcmp (name, ".rtproc") == 0)
+ {
+ if (hdr->sh_addralign != 0 && hdr->sh_entsize == 0)
+ {
+ unsigned int adjust;
+
+ adjust = hdr->sh_size % hdr->sh_addralign;
+ if (adjust != 0)
+ hdr->sh_size += hdr->sh_addralign - adjust;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Work over a section just before writing it out. We update the GP
+ value in the SHT_MIPS_REGINFO and SHT_MIPS_OPTIONS sections based
+ on the value we are using. */
+
+static boolean
+mips_elf32_section_processing (abfd, hdr)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+{
+ if (hdr->sh_type == SHT_MIPS_REGINFO)
+ {
+ bfd_byte buf[4];
+
+ BFD_ASSERT (hdr->sh_size == sizeof (Elf32_External_RegInfo));
+ BFD_ASSERT (hdr->contents == NULL);
+
+ if (bfd_seek (abfd,
+ hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4,
+ SEEK_SET) == -1)
+ return false;
+ bfd_h_put_32 (abfd, (bfd_vma) elf_gp (abfd), buf);
+ if (bfd_write (buf, (bfd_size_type) 1, (bfd_size_type) 4, abfd) != 4)
+ return false;
+ }
+
+ if (hdr->sh_type == SHT_MIPS_OPTIONS
+ && hdr->bfd_section != NULL
+ && elf_section_data (hdr->bfd_section) != NULL
+ && elf_section_data (hdr->bfd_section)->tdata != NULL)
+ {
+ bfd_byte *contents, *l, *lend;
+
+ /* We stored the section contents in the elf_section_data tdata
+ field in the set_section_contents routine. We save the
+ section contents so that we don't have to read them again.
+ At this point we know that elf_gp is set, so we can look
+ through the section contents to see if there is an
+ ODK_REGINFO structure. */
+
+ contents = (bfd_byte *) elf_section_data (hdr->bfd_section)->tdata;
+ l = contents;
+ lend = contents + hdr->sh_size;
+ while (l + sizeof (Elf_External_Options) <= lend)
+ {
+ Elf_Internal_Options intopt;
+
+ bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
+ &intopt);
+ if (intopt.kind == ODK_REGINFO)
+ {
+ bfd_byte buf[4];
+
+ if (bfd_seek (abfd,
+ (hdr->sh_offset
+ + (l - contents)
+ + sizeof (Elf_External_Options)
+ + (sizeof (Elf32_External_RegInfo) - 4)),
+ SEEK_SET) == -1)
+ return false;
+ bfd_h_put_32 (abfd, elf_gp (abfd), buf);
+ if (bfd_write (buf, 1, 4, abfd) != 4)
+ return false;
+ }
+ l += intopt.size;
+ }
+ }
+
+ return _bfd_mips_elf_section_processing (abfd, hdr);
+}
+
+/* MIPS ELF uses two common sections. One is the usual one, and the
+ other is for small objects. All the small objects are kept
+ together, and then referenced via the gp pointer, which yields
+ faster assembler code. This is what we use for the small common
+ section. This approach is copied from ecoff.c. */
+static asection mips_elf_scom_section;
+static asymbol mips_elf_scom_symbol;
+static asymbol *mips_elf_scom_symbol_ptr;
+
+/* MIPS ELF also uses an acommon section, which represents an
+ allocated common symbol which may be overridden by a
+ definition in a shared library. */
+static asection mips_elf_acom_section;
+static asymbol mips_elf_acom_symbol;
+static asymbol *mips_elf_acom_symbol_ptr;
+
+/* The Irix 5 support uses two virtual sections, which represent
+ text/data symbols defined in dynamic objects. */
+static asection mips_elf_text_section;
+static asection *mips_elf_text_section_ptr;
+static asymbol mips_elf_text_symbol;
+static asymbol *mips_elf_text_symbol_ptr;
+
+static asection mips_elf_data_section;
+static asection *mips_elf_data_section_ptr;
+static asymbol mips_elf_data_symbol;
+static asymbol *mips_elf_data_symbol_ptr;
+
+/* Handle the special MIPS section numbers that a symbol may use.
+ This is used for both the 32-bit and the 64-bit ABI. */
+
+void
+_bfd_mips_elf_symbol_processing (abfd, asym)
+ bfd *abfd;
+ asymbol *asym;
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_MIPS_ACOMMON:
+ /* This section is used in a dynamically linked executable file.
+ It is an allocated common section. The dynamic linker can
+ either resolve these symbols to something in a shared
+ library, or it can just leave them here. For our purposes,
+ we can consider these symbols to be in a new section. */
+ if (mips_elf_acom_section.name == NULL)
+ {
+ /* Initialize the acommon section. */
+ mips_elf_acom_section.name = ".acommon";
+ mips_elf_acom_section.flags = SEC_ALLOC;
+ mips_elf_acom_section.output_section = &mips_elf_acom_section;
+ mips_elf_acom_section.symbol = &mips_elf_acom_symbol;
+ mips_elf_acom_section.symbol_ptr_ptr = &mips_elf_acom_symbol_ptr;
+ mips_elf_acom_symbol.name = ".acommon";
+ mips_elf_acom_symbol.flags = BSF_SECTION_SYM;
+ mips_elf_acom_symbol.section = &mips_elf_acom_section;
+ mips_elf_acom_symbol_ptr = &mips_elf_acom_symbol;
+ }
+ asym->section = &mips_elf_acom_section;
+ break;
+
+ case SHN_COMMON:
+ /* Common symbols less than the GP size are automatically
+ treated as SHN_MIPS_SCOMMON symbols. */
+ if (asym->value > elf_gp_size (abfd))
+ break;
+ /* Fall through. */
+ case SHN_MIPS_SCOMMON:
+ if (mips_elf_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ mips_elf_scom_section.name = ".scommon";
+ mips_elf_scom_section.flags = SEC_IS_COMMON;
+ mips_elf_scom_section.output_section = &mips_elf_scom_section;
+ mips_elf_scom_section.symbol = &mips_elf_scom_symbol;
+ mips_elf_scom_section.symbol_ptr_ptr = &mips_elf_scom_symbol_ptr;
+ mips_elf_scom_symbol.name = ".scommon";
+ mips_elf_scom_symbol.flags = BSF_SECTION_SYM;
+ mips_elf_scom_symbol.section = &mips_elf_scom_section;
+ mips_elf_scom_symbol_ptr = &mips_elf_scom_symbol;
+ }
+ asym->section = &mips_elf_scom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+
+ case SHN_MIPS_SUNDEFINED:
+ asym->section = bfd_und_section_ptr;
+ break;
+
+#if 0 /* for SGI_COMPAT */
+ case SHN_MIPS_TEXT:
+ asym->section = mips_elf_text_section_ptr;
+ break;
+
+ case SHN_MIPS_DATA:
+ asym->section = mips_elf_data_section_ptr;
+ break;
+#endif
+ }
+}
+
+/* When creating an Irix 5 executable, we need REGINFO and RTPROC
+ segments. */
+
+static int
+mips_elf_additional_program_headers (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ int ret;
+
+ ret = 0;
+
+ if (! SGI_COMPAT (abfd))
+ return ret;
+
+ s = bfd_get_section_by_name (abfd, ".reginfo");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0)
+ {
+ /* We need a PT_MIPS_REGINFO segment. */
+ ++ret;
+ }
+
+ if (bfd_get_section_by_name (abfd, ".dynamic") != NULL
+ && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
+ {
+ /* We need a PT_MIPS_RTPROC segment. */
+ ++ret;
+ }
+
+ return ret;
+}
+
+/* Modify the segment map for an Irix 5 executable. */
+
+static boolean
+mips_elf_modify_segment_map (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ struct elf_segment_map *m, **pm;
+
+ if (! SGI_COMPAT (abfd))
+ return true;
+
+ /* If there is a .reginfo section, we need a PT_MIPS_REGINFO
+ segment. */
+ s = bfd_get_section_by_name (abfd, ".reginfo");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0)
+ {
+ for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+ if (m->p_type == PT_MIPS_REGINFO)
+ break;
+ if (m == NULL)
+ {
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+ if (m == NULL)
+ return false;
+
+ m->p_type = PT_MIPS_REGINFO;
+ m->count = 1;
+ m->sections[0] = s;
+
+ /* We want to put it after the PHDR and INTERP segments. */
+ pm = &elf_tdata (abfd)->segment_map;
+ while (*pm != NULL
+ && ((*pm)->p_type == PT_PHDR
+ || (*pm)->p_type == PT_INTERP))
+ pm = &(*pm)->next;
+
+ m->next = *pm;
+ *pm = m;
+ }
+ }
+
+ /* If there are .dynamic and .mdebug sections, we make a room for
+ the RTPROC header. FIXME: Rewrite without section names. */
+ if (bfd_get_section_by_name (abfd, ".interp") == NULL
+ && bfd_get_section_by_name (abfd, ".dynamic") != NULL
+ && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
+ {
+ for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+ if (m->p_type == PT_MIPS_RTPROC)
+ break;
+ if (m == NULL)
+ {
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+ if (m == NULL)
+ return false;
+
+ m->p_type = PT_MIPS_RTPROC;
+
+ s = bfd_get_section_by_name (abfd, ".rtproc");
+ if (s == NULL)
+ {
+ m->count = 0;
+ m->p_flags = 0;
+ m->p_flags_valid = 1;
+ }
+ else
+ {
+ m->count = 1;
+ m->sections[0] = s;
+ }
+
+ /* We want to put it after the DYNAMIC segment. */
+ pm = &elf_tdata (abfd)->segment_map;
+ while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
+ pm = &(*pm)->next;
+ if (*pm != NULL)
+ pm = &(*pm)->next;
+
+ m->next = *pm;
+ *pm = m;
+ }
+ }
+
+ /* On Irix 5, the PT_DYNAMIC segment includes the .dynamic, .dynstr,
+ .dynsym, and .hash sections, and everything in between. */
+ for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
+ if ((*pm)->p_type == PT_DYNAMIC)
+ break;
+ m = *pm;
+ if (m != NULL
+ && m->count == 1
+ && strcmp (m->sections[0]->name, ".dynamic") == 0)
+ {
+ static const char *sec_names[] =
+ { ".dynamic", ".dynstr", ".dynsym", ".hash" };
+ bfd_vma low, high;
+ unsigned int i, c;
+ struct elf_segment_map *n;
+
+ low = 0xffffffff;
+ high = 0;
+ for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++)
+ {
+ s = bfd_get_section_by_name (abfd, sec_names[i]);
+ if (s != NULL && (s->flags & SEC_LOAD) != 0)
+ {
+ bfd_size_type sz;
+
+ if (low > s->vma)
+ low = s->vma;
+ sz = s->_cooked_size;
+ if (sz == 0)
+ sz = s->_raw_size;
+ if (high < s->vma + sz)
+ high = s->vma + sz;
+ }
+ }
+
+ c = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if ((s->flags & SEC_LOAD) != 0
+ && s->vma >= low
+ && ((s->vma
+ + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size))
+ <= high))
+ ++c;
+
+ n = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *)));
+ if (n == NULL)
+ return false;
+ *n = *m;
+ n->count = c;
+
+ i = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LOAD) != 0
+ && s->vma >= low
+ && ((s->vma
+ + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size))
+ <= high))
+ {
+ n->sections[i] = s;
+ ++i;
+ }
+ }
+
+ *pm = n;
+ }
+
+ return true;
+}
+
+/* The structure of the runtime procedure descriptor created by the
+ loader for use by the static exception system. */
+
+typedef struct runtime_pdr {
+ bfd_vma adr; /* memory address of start of procedure */
+ long regmask; /* save register mask */
+ long regoffset; /* save register offset */
+ long fregmask; /* save floating point register mask */
+ long fregoffset; /* save floating point register offset */
+ long frameoffset; /* frame size */
+ short framereg; /* frame pointer register */
+ short pcreg; /* offset or reg of return pc */
+ long irpss; /* index into the runtime string table */
+ long reserved;
+ struct exception_info *exception_info;/* pointer to exception array */
+} RPDR, *pRPDR;
+#define cbRPDR sizeof(RPDR)
+#define rpdNil ((pRPDR) 0)
+
+/* Swap RPDR (runtime procedure table entry) for output. */
+
+static void ecoff_swap_rpdr_out
+ PARAMS ((bfd *, const RPDR *, struct rpdr_ext *));
+
+static void
+ecoff_swap_rpdr_out (abfd, in, ex)
+ bfd *abfd;
+ const RPDR *in;
+ struct rpdr_ext *ex;
+{
+ /* ecoff_put_off was defined in ecoffswap.h. */
+ ecoff_put_off (abfd, in->adr, (bfd_byte *) ex->p_adr);
+ bfd_h_put_32 (abfd, in->regmask, (bfd_byte *) ex->p_regmask);
+ bfd_h_put_32 (abfd, in->regoffset, (bfd_byte *) ex->p_regoffset);
+ bfd_h_put_32 (abfd, in->fregmask, (bfd_byte *) ex->p_fregmask);
+ bfd_h_put_32 (abfd, in->fregoffset, (bfd_byte *) ex->p_fregoffset);
+ bfd_h_put_32 (abfd, in->frameoffset, (bfd_byte *) ex->p_frameoffset);
+
+ bfd_h_put_16 (abfd, in->framereg, (bfd_byte *) ex->p_framereg);
+ bfd_h_put_16 (abfd, in->pcreg, (bfd_byte *) ex->p_pcreg);
+
+ bfd_h_put_32 (abfd, in->irpss, (bfd_byte *) ex->p_irpss);
+#if 0 /* FIXME */
+ ecoff_put_off (abfd, in->exception_info, (bfd_byte *) ex->p_exception_info);
+#endif
+}
+
+/* Read ECOFF debugging information from a .mdebug section into a
+ ecoff_debug_info structure. */
+
+boolean
+_bfd_mips_elf_read_ecoff_info (abfd, section, debug)
+ bfd *abfd;
+ asection *section;
+ struct ecoff_debug_info *debug;
+{
+ HDRR *symhdr;
+ const struct ecoff_debug_swap *swap;
+ char *ext_hdr = NULL;
+
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ memset (debug, 0, sizeof(*debug));
+
+ ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size);
+ if (ext_hdr == NULL && swap->external_hdr_size != 0)
+ goto error_return;
+
+ if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
+ swap->external_hdr_size)
+ == false)
+ goto error_return;
+
+ symhdr = &debug->symbolic_header;
+ (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
+
+ /* The symbolic header contains absolute file offsets and sizes to
+ read. */
+#define READ(ptr, offset, count, size, type) \
+ if (symhdr->count == 0) \
+ debug->ptr = NULL; \
+ else \
+ { \
+ debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \
+ if (debug->ptr == NULL) \
+ goto error_return; \
+ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
+ || (bfd_read (debug->ptr, size, symhdr->count, \
+ abfd) != size * symhdr->count)) \
+ goto error_return; \
+ }
+
+ READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
+ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
+ READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
+ union aux_ext *);
+ READ (ss, cbSsOffset, issMax, sizeof (char), char *);
+ READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
+ READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
+ READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
+#undef READ
+
+ debug->fdr = NULL;
+ debug->adjust = NULL;
+
+ return true;
+
+ error_return:
+ if (ext_hdr != NULL)
+ free (ext_hdr);
+ if (debug->line != NULL)
+ free (debug->line);
+ if (debug->external_dnr != NULL)
+ free (debug->external_dnr);
+ if (debug->external_pdr != NULL)
+ free (debug->external_pdr);
+ if (debug->external_sym != NULL)
+ free (debug->external_sym);
+ if (debug->external_opt != NULL)
+ free (debug->external_opt);
+ if (debug->external_aux != NULL)
+ free (debug->external_aux);
+ if (debug->ss != NULL)
+ free (debug->ss);
+ if (debug->ssext != NULL)
+ free (debug->ssext);
+ if (debug->external_fdr != NULL)
+ free (debug->external_fdr);
+ if (debug->external_rfd != NULL)
+ free (debug->external_rfd);
+ if (debug->external_ext != NULL)
+ free (debug->external_ext);
+ return false;
+}
+
+/* MIPS ELF local labels start with '$', not 'L'. */
+
+/*ARGSUSED*/
+static boolean
+mips_elf_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ if (name[0] == '$')
+ return true;
+
+ /* On Irix 6, the labels go back to starting with '.', so we accept
+ the generic ELF local label syntax as well. */
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* MIPS ELF uses a special find_nearest_line routine in order the
+ handle the ECOFF debugging information. */
+
+struct mips_elf_find_line
+{
+ struct ecoff_debug_info d;
+ struct ecoff_find_line i;
+};
+
+boolean
+_bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
+ functionname_ptr, line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ asection *msec;
+
+ if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
+ return true;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
+ return true;
+
+ msec = bfd_get_section_by_name (abfd, ".mdebug");
+ if (msec != NULL)
+ {
+ flagword origflags;
+ struct mips_elf_find_line *fi;
+ const struct ecoff_debug_swap * const swap =
+ get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+
+ /* If we are called during a link, mips_elf_final_link may have
+ cleared the SEC_HAS_CONTENTS field. We force it back on here
+ if appropriate (which it normally will be). */
+ origflags = msec->flags;
+ if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
+ msec->flags |= SEC_HAS_CONTENTS;
+
+ fi = elf_tdata (abfd)->find_line_info;
+ if (fi == NULL)
+ {
+ bfd_size_type external_fdr_size;
+ char *fraw_src;
+ char *fraw_end;
+ struct fdr *fdr_ptr;
+
+ fi = ((struct mips_elf_find_line *)
+ bfd_zalloc (abfd, sizeof (struct mips_elf_find_line)));
+ if (fi == NULL)
+ {
+ msec->flags = origflags;
+ return false;
+ }
+
+ if (! _bfd_mips_elf_read_ecoff_info (abfd, msec, &fi->d))
+ {
+ msec->flags = origflags;
+ return false;
+ }
+
+ /* Swap in the FDR information. */
+ fi->d.fdr = ((struct fdr *)
+ bfd_alloc (abfd,
+ (fi->d.symbolic_header.ifdMax *
+ sizeof (struct fdr))));
+ if (fi->d.fdr == NULL)
+ {
+ msec->flags = origflags;
+ return false;
+ }
+ external_fdr_size = swap->external_fdr_size;
+ fdr_ptr = fi->d.fdr;
+ fraw_src = (char *) fi->d.external_fdr;
+ fraw_end = (fraw_src
+ + fi->d.symbolic_header.ifdMax * external_fdr_size);
+ for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
+ (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
+
+ elf_tdata (abfd)->find_line_info = fi;
+
+ /* Note that we don't bother to ever free this information.
+ find_nearest_line is either called all the time, as in
+ objdump -l, so the information should be saved, or it is
+ rarely called, as in ld error messages, so the memory
+ wasted is unimportant. Still, it would probably be a
+ good idea for free_cached_info to throw it away. */
+ }
+
+ if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
+ &fi->i, filename_ptr, functionname_ptr,
+ line_ptr))
+ {
+ msec->flags = origflags;
+ return true;
+ }
+
+ msec->flags = origflags;
+ }
+
+ /* Fall back on the generic ELF find_nearest_line routine. */
+
+ return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr);
+}
+
+ /* The mips16 compiler uses a couple of special sections to handle
+ floating point arguments.
+
+ Section names that look like .mips16.fn.FNNAME contain stubs that
+ copy floating point arguments from the fp regs to the gp regs and
+ then jump to FNNAME. If any 32 bit function calls FNNAME, the
+ call should be redirected to the stub instead. If no 32 bit
+ function calls FNNAME, the stub should be discarded. We need to
+ consider any reference to the function, not just a call, because
+ if the address of the function is taken we will need the stub,
+ since the address might be passed to a 32 bit function.
+
+ Section names that look like .mips16.call.FNNAME contain stubs
+ that copy floating point arguments from the gp regs to the fp
+ regs and then jump to FNNAME. If FNNAME is a 32 bit function,
+ then any 16 bit function that calls FNNAME should be redirected
+ to the stub instead. If FNNAME is not a 32 bit function, the
+ stub should be discarded.
+
+ .mips16.call.fp.FNNAME sections are similar, but contain stubs
+ which call FNNAME and then copy the return value from the fp regs
+ to the gp regs. These stubs store the return value in $18 while
+ calling FNNAME; any function which might call one of these stubs
+ must arrange to save $18 around the call. (This case is not
+ needed for 32 bit functions that call 16 bit functions, because
+ 16 bit functions always return floating point values in both
+ $f0/$f1 and $2/$3.)
+
+ Note that in all cases FNNAME might be defined statically.
+ Therefore, FNNAME is not used literally. Instead, the relocation
+ information will indicate which symbol the section is for.
+
+ We record any stubs that we find in the symbol table. */
+
+#define FN_STUB ".mips16.fn."
+#define CALL_STUB ".mips16.call."
+#define CALL_FP_STUB ".mips16.call.fp."
+
+/* The MIPS ELF linker needs additional information for each symbol in
+ the global hash table. */
+
+struct mips_elf_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* External symbol information. */
+ EXTR esym;
+
+ /* Number of MIPS_32 or MIPS_REL32 relocs against this symbol. */
+ unsigned int mips_32_relocs;
+
+ /* If there is a stub that 32 bit functions should use to call this
+ 16 bit function, this points to the section containing the stub. */
+ asection *fn_stub;
+
+ /* Whether we need the fn_stub; this is set if this symbol appears
+ in any relocs other than a 16 bit call. */
+ boolean need_fn_stub;
+
+ /* If there is a stub that 16 bit functions should use to call this
+ 32 bit function, this points to the section containing the stub. */
+ asection *call_stub;
+
+ /* This is like the call_stub field, but it is used if the function
+ being called returns a floating point value. */
+ asection *call_fp_stub;
+};
+
+/* MIPS ELF linker hash table. */
+
+struct mips_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+#if 0
+ /* We no longer use this. */
+ /* String section indices for the dynamic section symbols. */
+ bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES];
+#endif
+ /* The number of .rtproc entries. */
+ bfd_size_type procedure_count;
+ /* The size of the .compact_rel section (if SGI_COMPAT). */
+ bfd_size_type compact_rel_size;
+ /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic
+ entry is set to the address of __rld_obj_head as in Irix 5. */
+ boolean use_rld_obj_head;
+ /* This is the value of the __rld_map or __rld_obj_head symbol. */
+ bfd_vma rld_value;
+ /* This is set if we see any mips16 stub sections. */
+ boolean mips16_stubs_seen;
+};
+
+/* Look up an entry in a MIPS ELF linker hash table. */
+
+#define mips_elf_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct mips_elf_link_hash_entry *) \
+ elf_link_hash_lookup (&(table)->root, (string), (create), \
+ (copy), (follow)))
+
+/* Traverse a MIPS ELF linker hash table. */
+
+#define mips_elf_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the MIPS ELF linker hash table from a link_info structure. */
+
+#define mips_elf_hash_table(p) \
+ ((struct mips_elf_link_hash_table *) ((p)->hash))
+
+static boolean mips_elf_output_extsym
+ PARAMS ((struct mips_elf_link_hash_entry *, PTR));
+
+/* Create an entry in a MIPS ELF linker hash table. */
+
+static struct bfd_hash_entry *
+mips_elf_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct mips_elf_link_hash_entry *ret =
+ (struct mips_elf_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct mips_elf_link_hash_entry *) NULL)
+ ret = ((struct mips_elf_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct mips_elf_link_hash_entry)));
+ if (ret == (struct mips_elf_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct mips_elf_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct mips_elf_link_hash_entry *) NULL)
+ {
+ /* Set local fields. */
+ memset (&ret->esym, 0, sizeof (EXTR));
+ /* We use -2 as a marker to indicate that the information has
+ not been set. -1 means there is no associated ifd. */
+ ret->esym.ifd = -2;
+ ret->mips_32_relocs = 0;
+ ret->fn_stub = NULL;
+ ret->need_fn_stub = false;
+ ret->call_stub = NULL;
+ ret->call_fp_stub = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a MIPS ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+mips_elf_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct mips_elf_link_hash_table *ret;
+
+ ret = ((struct mips_elf_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table)));
+ if (ret == (struct mips_elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ mips_elf_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+#if 0
+ /* We no longer use this. */
+ for (i = 0; i < SIZEOF_MIPS_DYNSYM_SECNAMES; i++)
+ ret->dynsym_sec_strindex[i] = (bfd_size_type) -1;
+#endif
+ ret->procedure_count = 0;
+ ret->compact_rel_size = 0;
+ ret->use_rld_obj_head = false;
+ ret->rld_value = 0;
+ ret->mips16_stubs_seen = false;
+
+ return &ret->root.root;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must handle the special MIPS section numbers here. */
+
+/*ARGSUSED*/
+static boolean
+mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ if (SGI_COMPAT (abfd)
+ && (abfd->flags & DYNAMIC) != 0
+ && strcmp (*namep, "_rld_new_interface") == 0)
+ {
+ /* Skip Irix 5 rld entry name. */
+ *namep = NULL;
+ return true;
+ }
+
+ switch (sym->st_shndx)
+ {
+ case SHN_COMMON:
+ /* Common symbols less than the GP size are automatically
+ treated as SHN_MIPS_SCOMMON symbols. */
+ if (sym->st_size > elf_gp_size (abfd))
+ break;
+ /* Fall through. */
+ case SHN_MIPS_SCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".scommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+
+ case SHN_MIPS_TEXT:
+ /* This section is used in a shared object. */
+ if (mips_elf_text_section_ptr == NULL)
+ {
+ /* Initialize the section. */
+ mips_elf_text_section.name = ".text";
+ mips_elf_text_section.flags = SEC_NO_FLAGS;
+ mips_elf_text_section.output_section = NULL;
+ mips_elf_text_section.symbol = &mips_elf_text_symbol;
+ mips_elf_text_section.symbol_ptr_ptr = &mips_elf_text_symbol_ptr;
+ mips_elf_text_symbol.name = ".text";
+ mips_elf_text_symbol.flags = BSF_SECTION_SYM;
+ mips_elf_text_symbol.section = &mips_elf_text_section;
+ mips_elf_text_symbol_ptr = &mips_elf_text_symbol;
+ mips_elf_text_section_ptr = &mips_elf_text_section;
+ }
+ /* This code used to do *secp = bfd_und_section_ptr if
+ info->shared. I don't know why, and that doesn't make sense,
+ so I took it out. */
+ *secp = mips_elf_text_section_ptr;
+ break;
+
+ case SHN_MIPS_ACOMMON:
+ /* Fall through. XXX Can we treat this as allocated data? */
+ case SHN_MIPS_DATA:
+ /* This section is used in a shared object. */
+ if (mips_elf_data_section_ptr == NULL)
+ {
+ /* Initialize the section. */
+ mips_elf_data_section.name = ".data";
+ mips_elf_data_section.flags = SEC_NO_FLAGS;
+ mips_elf_data_section.output_section = NULL;
+ mips_elf_data_section.symbol = &mips_elf_data_symbol;
+ mips_elf_data_section.symbol_ptr_ptr = &mips_elf_data_symbol_ptr;
+ mips_elf_data_symbol.name = ".data";
+ mips_elf_data_symbol.flags = BSF_SECTION_SYM;
+ mips_elf_data_symbol.section = &mips_elf_data_section;
+ mips_elf_data_symbol_ptr = &mips_elf_data_symbol;
+ mips_elf_data_section_ptr = &mips_elf_data_section;
+ }
+ /* This code used to do *secp = bfd_und_section_ptr if
+ info->shared. I don't know why, and that doesn't make sense,
+ so I took it out. */
+ *secp = mips_elf_data_section_ptr;
+ break;
+
+ case SHN_MIPS_SUNDEFINED:
+ *secp = bfd_und_section_ptr;
+ break;
+ }
+
+ if (SGI_COMPAT (abfd)
+ && ! info->shared
+ && info->hash->creator == abfd->xvec
+ && strcmp (*namep, "__rld_obj_head") == 0)
+ {
+ struct elf_link_hash_entry *h;
+
+ /* Mark __rld_obj_head as dynamic. */
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, *namep, BSF_GLOBAL, *secp,
+ (bfd_vma) *valp, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+
+ mips_elf_hash_table (info)->use_rld_obj_head = true;
+ }
+
+ /* If this is a mips16 text symbol, add 1 to the value to make it
+ odd. This will cause something like .word SYM to come up with
+ the right value when it is loaded into the PC. */
+ if (sym->st_other == STO_MIPS16)
+ ++*valp;
+
+ return true;
+}
+
+/* Structure used to pass information to mips_elf_output_extsym. */
+
+struct extsym_info
+{
+ bfd *abfd;
+ struct bfd_link_info *info;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ boolean failed;
+};
+
+/* This routine is used to write out ECOFF debugging external symbol
+ information. It is called via mips_elf_link_hash_traverse. The
+ ECOFF external symbol information must match the ELF external
+ symbol information. Unfortunately, at this point we don't know
+ whether a symbol is required by reloc information, so the two
+ tables may wind up being different. We must sort out the external
+ symbol information before we can set the final size of the .mdebug
+ section, and we must set the size of the .mdebug section before we
+ can relocate any sections, and we can't know which symbols are
+ required by relocation until we relocate the sections.
+ Fortunately, it is relatively unlikely that any symbol will be
+ stripped but required by a reloc. In particular, it can not happen
+ when generating a final executable. */
+
+static boolean
+mips_elf_output_extsym (h, data)
+ struct mips_elf_link_hash_entry *h;
+ PTR data;
+{
+ struct extsym_info *einfo = (struct extsym_info *) data;
+ boolean strip;
+ asection *sec, *output_section;
+
+ if (h->root.indx == -2)
+ strip = false;
+ else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
+ && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+ && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
+ strip = true;
+ else if (einfo->info->strip == strip_all
+ || (einfo->info->strip == strip_some
+ && bfd_hash_lookup (einfo->info->keep_hash,
+ h->root.root.root.string,
+ false, false) == NULL))
+ strip = true;
+ else
+ strip = false;
+
+ if (strip)
+ return true;
+
+ if (h->esym.ifd == -2)
+ {
+ h->esym.jmptbl = 0;
+ h->esym.cobol_main = 0;
+ h->esym.weakext = 0;
+ h->esym.reserved = 0;
+ h->esym.ifd = ifdNil;
+ h->esym.asym.value = 0;
+ h->esym.asym.st = stGlobal;
+
+ if (SGI_COMPAT (einfo->abfd)
+ && (h->root.root.type == bfd_link_hash_undefined
+ || h->root.root.type == bfd_link_hash_undefweak))
+ {
+ const char *name;
+
+ /* Use undefined class. Also, set class and type for some
+ special symbols. */
+ name = h->root.root.root.string;
+ if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
+ || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0)
+ {
+ h->esym.asym.sc = scData;
+ h->esym.asym.st = stLabel;
+ h->esym.asym.value = 0;
+ }
+ else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0)
+ {
+ h->esym.asym.sc = scAbs;
+ h->esym.asym.st = stLabel;
+ h->esym.asym.value =
+ mips_elf_hash_table (einfo->info)->procedure_count;
+ }
+ else if (strcmp (name, "_gp_disp") == 0)
+ {
+ h->esym.asym.sc = scAbs;
+ h->esym.asym.st = stLabel;
+ h->esym.asym.value = elf_gp (einfo->abfd);
+ }
+ else
+ h->esym.asym.sc = scUndefined;
+ }
+ else if (h->root.root.type != bfd_link_hash_defined
+ && h->root.root.type != bfd_link_hash_defweak)
+ h->esym.asym.sc = scAbs;
+ else
+ {
+ const char *name;
+
+ sec = h->root.root.u.def.section;
+ output_section = sec->output_section;
+
+ /* When making a shared library and symbol h is the one from
+ the another shared library, OUTPUT_SECTION may be null. */
+ if (output_section == NULL)
+ h->esym.asym.sc = scUndefined;
+ else
+ {
+ name = bfd_section_name (output_section->owner, output_section);
+
+ if (strcmp (name, ".text") == 0)
+ h->esym.asym.sc = scText;
+ else if (strcmp (name, ".data") == 0)
+ h->esym.asym.sc = scData;
+ else if (strcmp (name, ".sdata") == 0)
+ h->esym.asym.sc = scSData;
+ else if (strcmp (name, ".rodata") == 0
+ || strcmp (name, ".rdata") == 0)
+ h->esym.asym.sc = scRData;
+ else if (strcmp (name, ".bss") == 0)
+ h->esym.asym.sc = scBss;
+ else if (strcmp (name, ".sbss") == 0)
+ h->esym.asym.sc = scSBss;
+ else if (strcmp (name, ".init") == 0)
+ h->esym.asym.sc = scInit;
+ else if (strcmp (name, ".fini") == 0)
+ h->esym.asym.sc = scFini;
+ else
+ h->esym.asym.sc = scAbs;
+ }
+ }
+
+ h->esym.asym.reserved = 0;
+ h->esym.asym.index = indexNil;
+ }
+
+ if (h->root.root.type == bfd_link_hash_common)
+ h->esym.asym.value = h->root.root.u.c.size;
+ else if (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ {
+ if (h->esym.asym.sc == scCommon)
+ h->esym.asym.sc = scBss;
+ else if (h->esym.asym.sc == scSCommon)
+ h->esym.asym.sc = scSBss;
+
+ sec = h->root.root.u.def.section;
+ output_section = sec->output_section;
+ if (output_section != NULL)
+ h->esym.asym.value = (h->root.root.u.def.value
+ + sec->output_offset
+ + output_section->vma);
+ else
+ h->esym.asym.value = 0;
+ }
+ else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ /* Set type and value for a symbol with a function stub. */
+ h->esym.asym.st = stProc;
+ sec = h->root.root.u.def.section;
+ if (sec == NULL)
+ h->esym.asym.value = 0;
+ else
+ {
+ output_section = sec->output_section;
+ if (output_section != NULL)
+ h->esym.asym.value = (h->root.plt.offset
+ + sec->output_offset
+ + output_section->vma);
+ else
+ h->esym.asym.value = 0;
+ }
+#if 0 /* FIXME? */
+ h->esym.ifd = 0;
+#endif
+ }
+
+ if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
+ h->root.root.root.string,
+ &h->esym))
+ {
+ einfo->failed = true;
+ return false;
+ }
+
+ return true;
+}
+
+/* Create a runtime procedure table from the .mdebug section. */
+
+static boolean
+mips_elf_create_procedure_table (handle, abfd, info, s, debug)
+ PTR handle;
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *s;
+ struct ecoff_debug_info *debug;
+{
+ const struct ecoff_debug_swap *swap;
+ HDRR *hdr = &debug->symbolic_header;
+ RPDR *rpdr, *rp;
+ struct rpdr_ext *erp;
+ PTR rtproc;
+ struct pdr_ext *epdr;
+ struct sym_ext *esym;
+ char *ss, **sv;
+ char *str;
+ unsigned long size, count;
+ unsigned long sindex;
+ unsigned long i;
+ PDR pdr;
+ SYMR sym;
+ const char *no_name_func = _("static procedure (no name)");
+
+ epdr = NULL;
+ rpdr = NULL;
+ esym = NULL;
+ ss = NULL;
+ sv = NULL;
+
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+
+ sindex = strlen (no_name_func) + 1;
+ count = hdr->ipdMax;
+ if (count > 0)
+ {
+ size = swap->external_pdr_size;
+
+ epdr = (struct pdr_ext *) bfd_malloc (size * count);
+ if (epdr == NULL)
+ goto error_return;
+
+ if (! _bfd_ecoff_get_accumulated_pdr (handle, (PTR) epdr))
+ goto error_return;
+
+ size = sizeof (RPDR);
+ rp = rpdr = (RPDR *) bfd_malloc (size * count);
+ if (rpdr == NULL)
+ goto error_return;
+
+ sv = (char **) bfd_malloc (sizeof (char *) * count);
+ if (sv == NULL)
+ goto error_return;
+
+ count = hdr->isymMax;
+ size = swap->external_sym_size;
+ esym = (struct sym_ext *) bfd_malloc (size * count);
+ if (esym == NULL)
+ goto error_return;
+
+ if (! _bfd_ecoff_get_accumulated_sym (handle, (PTR) esym))
+ goto error_return;
+
+ count = hdr->issMax;
+ ss = (char *) bfd_malloc (count);
+ if (ss == NULL)
+ goto error_return;
+ if (! _bfd_ecoff_get_accumulated_ss (handle, (PTR) ss))
+ goto error_return;
+
+ count = hdr->ipdMax;
+ for (i = 0; i < count; i++, rp++)
+ {
+ (*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr);
+ (*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym);
+ rp->adr = sym.value;
+ rp->regmask = pdr.regmask;
+ rp->regoffset = pdr.regoffset;
+ rp->fregmask = pdr.fregmask;
+ rp->fregoffset = pdr.fregoffset;
+ rp->frameoffset = pdr.frameoffset;
+ rp->framereg = pdr.framereg;
+ rp->pcreg = pdr.pcreg;
+ rp->irpss = sindex;
+ sv[i] = ss + sym.iss;
+ sindex += strlen (sv[i]) + 1;
+ }
+ }
+
+ size = sizeof (struct rpdr_ext) * (count + 2) + sindex;
+ size = BFD_ALIGN (size, 16);
+ rtproc = (PTR) bfd_alloc (abfd, size);
+ if (rtproc == NULL)
+ {
+ mips_elf_hash_table (info)->procedure_count = 0;
+ goto error_return;
+ }
+
+ mips_elf_hash_table (info)->procedure_count = count + 2;
+
+ erp = (struct rpdr_ext *) rtproc;
+ memset (erp, 0, sizeof (struct rpdr_ext));
+ erp++;
+ str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2);
+ strcpy (str, no_name_func);
+ str += strlen (no_name_func) + 1;
+ for (i = 0; i < count; i++)
+ {
+ ecoff_swap_rpdr_out (abfd, rpdr + i, erp + i);
+ strcpy (str, sv[i]);
+ str += strlen (sv[i]) + 1;
+ }
+ ecoff_put_off (abfd, (bfd_vma) -1, (bfd_byte *) (erp + count)->p_adr);
+
+ /* Set the size and contents of .rtproc section. */
+ s->_raw_size = size;
+ s->contents = (bfd_byte *) rtproc;
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ s->link_order_head = (struct bfd_link_order *) NULL;
+
+ if (epdr != NULL)
+ free (epdr);
+ if (rpdr != NULL)
+ free (rpdr);
+ if (esym != NULL)
+ free (esym);
+ if (ss != NULL)
+ free (ss);
+ if (sv != NULL)
+ free (sv);
+
+ return true;
+
+ error_return:
+ if (epdr != NULL)
+ free (epdr);
+ if (rpdr != NULL)
+ free (rpdr);
+ if (esym != NULL)
+ free (esym);
+ if (ss != NULL)
+ free (ss);
+ if (sv != NULL)
+ free (sv);
+ return false;
+}
+
+/* A comparison routine used to sort .gptab entries. */
+
+static int
+gptab_compare (p1, p2)
+ const PTR p1;
+ const PTR p2;
+{
+ const Elf32_gptab *a1 = (const Elf32_gptab *) p1;
+ const Elf32_gptab *a2 = (const Elf32_gptab *) p2;
+
+ return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value;
+}
+
+/* We need to use a special link routine to handle the .reginfo and
+ the .mdebug sections. We need to merge all instances of these
+ sections together, not write them all out sequentially. */
+
+static boolean
+mips_elf_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection **secpp;
+ asection *o;
+ struct bfd_link_order *p;
+ asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec;
+ asection *rtproc_sec;
+ Elf32_RegInfo reginfo;
+ struct ecoff_debug_info debug;
+ const struct ecoff_debug_swap *swap
+ = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ HDRR *symhdr = &debug.symbolic_header;
+ PTR mdebug_handle = NULL;
+
+ /* Drop the .options section, since it has special semantics which I
+ haven't bothered to figure out. */
+ for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
+ {
+ if (strcmp ((*secpp)->name, ".options") == 0)
+ {
+ for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
+ if (p->type == bfd_indirect_link_order)
+ p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
+ (*secpp)->link_order_head = NULL;
+ *secpp = (*secpp)->next;
+ --abfd->section_count;
+ break;
+ }
+ }
+
+ /* Get a value for the GP register. */
+ if (elf_gp (abfd) == 0)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_defined)
+ elf_gp (abfd) = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ else if (info->relocateable)
+ {
+ bfd_vma lo;
+
+ /* Make up a value. */
+ lo = (bfd_vma) -1;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ if (o->vma < lo
+ && (strcmp (o->name, ".sbss") == 0
+ || strcmp (o->name, ".sdata") == 0
+ || strcmp (o->name, ".lit4") == 0
+ || strcmp (o->name, ".lit8") == 0))
+ lo = o->vma;
+ }
+ elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (abfd);
+ }
+ else
+ {
+ /* If the relocate_section function needs to do a reloc
+ involving the GP value, it should make a reloc_dangerous
+ callback to warn that GP is not defined. */
+ }
+ }
+
+ /* Go through the sections and collect the .reginfo and .mdebug
+ information. */
+ reginfo_sec = NULL;
+ mdebug_sec = NULL;
+ gptab_data_sec = NULL;
+ gptab_bss_sec = NULL;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ if (strcmp (o->name, ".reginfo") == 0)
+ {
+ memset (&reginfo, 0, sizeof reginfo);
+
+ /* We have found the .reginfo section in the output file.
+ Look through all the link_orders comprising it and merge
+ the information together. */
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ Elf32_External_RegInfo ext;
+ Elf32_RegInfo sub;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ /* The linker emulation code has probably clobbered the
+ size to be zero bytes. */
+ if (input_section->_raw_size == 0)
+ input_section->_raw_size = sizeof (Elf32_External_RegInfo);
+
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (PTR) &ext,
+ (file_ptr) 0,
+ sizeof ext))
+ return false;
+
+ bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);
+
+ reginfo.ri_gprmask |= sub.ri_gprmask;
+ reginfo.ri_cprmask[0] |= sub.ri_cprmask[0];
+ reginfo.ri_cprmask[1] |= sub.ri_cprmask[1];
+ reginfo.ri_cprmask[2] |= sub.ri_cprmask[2];
+ reginfo.ri_cprmask[3] |= sub.ri_cprmask[3];
+
+ /* ri_gp_value is set by the function
+ mips_elf32_section_processing when the section is
+ finally written out. */
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ /* Size has been set in mips_elf_always_size_sections */
+ BFD_ASSERT(o->_raw_size == sizeof (Elf32_External_RegInfo));
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+
+ reginfo_sec = o;
+ }
+
+ if (strcmp (o->name, ".mdebug") == 0)
+ {
+ struct extsym_info einfo;
+
+ /* We have found the .mdebug section in the output file.
+ Look through all the link_orders comprising it and merge
+ the information together. */
+ symhdr->magic = swap->sym_magic;
+ /* FIXME: What should the version stamp be? */
+ symhdr->vstamp = 0;
+ symhdr->ilineMax = 0;
+ symhdr->cbLine = 0;
+ symhdr->idnMax = 0;
+ symhdr->ipdMax = 0;
+ symhdr->isymMax = 0;
+ symhdr->ioptMax = 0;
+ symhdr->iauxMax = 0;
+ symhdr->issMax = 0;
+ symhdr->issExtMax = 0;
+ symhdr->ifdMax = 0;
+ symhdr->crfd = 0;
+ symhdr->iextMax = 0;
+
+ /* We accumulate the debugging information itself in the
+ debug_info structure. */
+ debug.line = NULL;
+ debug.external_dnr = NULL;
+ debug.external_pdr = NULL;
+ debug.external_sym = NULL;
+ debug.external_opt = NULL;
+ debug.external_aux = NULL;
+ debug.ss = NULL;
+ debug.ssext = debug.ssext_end = NULL;
+ debug.external_fdr = NULL;
+ debug.external_rfd = NULL;
+ debug.external_ext = debug.external_ext_end = NULL;
+
+ mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
+ if (mdebug_handle == (PTR) NULL)
+ return false;
+
+ if (SGI_COMPAT (abfd))
+ {
+ asection *s;
+ EXTR esym;
+ bfd_vma last;
+ unsigned int i;
+ static const char * const name[] =
+ { ".text", ".init", ".fini", ".data",
+ ".rodata", ".sdata", ".sbss", ".bss" };
+ static const int sc[] = { scText, scInit, scFini, scData,
+ scRData, scSData, scSBss, scBss };
+
+ esym.jmptbl = 0;
+ esym.cobol_main = 0;
+ esym.weakext = 0;
+ esym.reserved = 0;
+ esym.ifd = ifdNil;
+ esym.asym.iss = issNil;
+ esym.asym.st = stLocal;
+ esym.asym.reserved = 0;
+ esym.asym.index = indexNil;
+ last = 0;
+ for (i = 0; i < 8; i++)
+ {
+ esym.asym.sc = sc[i];
+ s = bfd_get_section_by_name (abfd, name[i]);
+ if (s != NULL)
+ {
+ esym.asym.value = s->vma;
+ last = s->vma + s->_raw_size;
+ }
+ else
+ esym.asym.value = last;
+
+ if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
+ name[i], &esym))
+ return false;
+ }
+ }
+
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ const struct ecoff_debug_swap *input_swap;
+ struct ecoff_debug_info input_debug;
+ char *eraw_src;
+ char *eraw_end;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
+ || (get_elf_backend_data (input_bfd)
+ ->elf_backend_ecoff_debug_swap) == NULL)
+ {
+ /* I don't know what a non MIPS ELF bfd would be
+ doing with a .mdebug section, but I don't really
+ want to deal with it. */
+ continue;
+ }
+
+ input_swap = (get_elf_backend_data (input_bfd)
+ ->elf_backend_ecoff_debug_swap);
+
+ BFD_ASSERT (p->size == input_section->_raw_size);
+
+ /* The ECOFF linking code expects that we have already
+ read in the debugging information and set up an
+ ecoff_debug_info structure, so we do that now. */
+ if (! _bfd_mips_elf_read_ecoff_info (input_bfd, input_section,
+ &input_debug))
+ return false;
+
+ if (! (bfd_ecoff_debug_accumulate
+ (mdebug_handle, abfd, &debug, swap, input_bfd,
+ &input_debug, input_swap, info)))
+ return false;
+
+ /* Loop through the external symbols. For each one with
+ interesting information, try to find the symbol in
+ the linker global hash table and save the information
+ for the output external symbols. */
+ eraw_src = input_debug.external_ext;
+ eraw_end = (eraw_src
+ + (input_debug.symbolic_header.iextMax
+ * input_swap->external_ext_size));
+ for (;
+ eraw_src < eraw_end;
+ eraw_src += input_swap->external_ext_size)
+ {
+ EXTR ext;
+ const char *name;
+ struct mips_elf_link_hash_entry *h;
+
+ (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
+ if (ext.asym.sc == scNil
+ || ext.asym.sc == scUndefined
+ || ext.asym.sc == scSUndefined)
+ continue;
+
+ name = input_debug.ssext + ext.asym.iss;
+ h = mips_elf_link_hash_lookup (mips_elf_hash_table (info),
+ name, false, false, true);
+ if (h == NULL || h->esym.ifd != -2)
+ continue;
+
+ if (ext.ifd != -1)
+ {
+ BFD_ASSERT (ext.ifd
+ < input_debug.symbolic_header.ifdMax);
+ ext.ifd = input_debug.ifdmap[ext.ifd];
+ }
+
+ h->esym = ext;
+ }
+
+ /* Free up the information we just read. */
+ free (input_debug.line);
+ free (input_debug.external_dnr);
+ free (input_debug.external_pdr);
+ free (input_debug.external_sym);
+ free (input_debug.external_opt);
+ free (input_debug.external_aux);
+ free (input_debug.ss);
+ free (input_debug.ssext);
+ free (input_debug.external_fdr);
+ free (input_debug.external_rfd);
+ free (input_debug.external_ext);
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ if (SGI_COMPAT (abfd) && info->shared)
+ {
+ /* Create .rtproc section. */
+ rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
+ if (rtproc_sec == NULL)
+ {
+ flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ rtproc_sec = bfd_make_section (abfd, ".rtproc");
+ if (rtproc_sec == NULL
+ || ! bfd_set_section_flags (abfd, rtproc_sec, flags)
+ || ! bfd_set_section_alignment (abfd, rtproc_sec, 4))
+ return false;
+ }
+
+ if (! mips_elf_create_procedure_table (mdebug_handle, abfd,
+ info, rtproc_sec, &debug))
+ return false;
+ }
+
+ /* Build the external symbol information. */
+ einfo.abfd = abfd;
+ einfo.info = info;
+ einfo.debug = &debug;
+ einfo.swap = swap;
+ einfo.failed = false;
+ mips_elf_link_hash_traverse (mips_elf_hash_table (info),
+ mips_elf_output_extsym,
+ (PTR) &einfo);
+ if (einfo.failed)
+ return false;
+
+ /* Set the size of the .mdebug section. */
+ o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+
+ mdebug_sec = o;
+ }
+
+ if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0)
+ {
+ const char *subname;
+ unsigned int c;
+ Elf32_gptab *tab;
+ Elf32_External_gptab *ext_tab;
+ unsigned int i;
+
+ /* The .gptab.sdata and .gptab.sbss sections hold
+ information describing how the small data area would
+ change depending upon the -G switch. These sections
+ not used in executables files. */
+ if (! info->relocateable)
+ {
+ asection **secpp;
+
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ /* Skip this section later on (I don't think this
+ currently matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+
+ /* Really remove the section. */
+ for (secpp = &abfd->sections;
+ *secpp != o;
+ secpp = &(*secpp)->next)
+ ;
+ *secpp = (*secpp)->next;
+ --abfd->section_count;
+
+ continue;
+ }
+
+ /* There is one gptab for initialized data, and one for
+ uninitialized data. */
+ if (strcmp (o->name, ".gptab.sdata") == 0)
+ gptab_data_sec = o;
+ else if (strcmp (o->name, ".gptab.sbss") == 0)
+ gptab_bss_sec = o;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: illegal section name `%s'"),
+ bfd_get_filename (abfd), o->name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+
+ /* The linker script always combines .gptab.data and
+ .gptab.sdata into .gptab.sdata, and likewise for
+ .gptab.bss and .gptab.sbss. It is possible that there is
+ no .sdata or .sbss section in the output file, in which
+ case we must change the name of the output section. */
+ subname = o->name + sizeof ".gptab" - 1;
+ if (bfd_get_section_by_name (abfd, subname) == NULL)
+ {
+ if (o == gptab_data_sec)
+ o->name = ".gptab.data";
+ else
+ o->name = ".gptab.bss";
+ subname = o->name + sizeof ".gptab" - 1;
+ BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL);
+ }
+
+ /* Set up the first entry. */
+ c = 1;
+ tab = (Elf32_gptab *) bfd_malloc (c * sizeof (Elf32_gptab));
+ if (tab == NULL)
+ return false;
+ tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
+ tab[0].gt_header.gt_unused = 0;
+
+ /* Combine the input sections. */
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ bfd_size_type size;
+ unsigned long last;
+ bfd_size_type gpentry;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ /* Combine the gptab entries for this input section one
+ by one. We know that the input gptab entries are
+ sorted by ascending -G value. */
+ size = bfd_section_size (input_bfd, input_section);
+ last = 0;
+ for (gpentry = sizeof (Elf32_External_gptab);
+ gpentry < size;
+ gpentry += sizeof (Elf32_External_gptab))
+ {
+ Elf32_External_gptab ext_gptab;
+ Elf32_gptab int_gptab;
+ unsigned long val;
+ unsigned long add;
+ boolean exact;
+ unsigned int look;
+
+ if (! (bfd_get_section_contents
+ (input_bfd, input_section, (PTR) &ext_gptab,
+ gpentry, sizeof (Elf32_External_gptab))))
+ {
+ free (tab);
+ return false;
+ }
+
+ bfd_mips_elf32_swap_gptab_in (input_bfd, &ext_gptab,
+ &int_gptab);
+ val = int_gptab.gt_entry.gt_g_value;
+ add = int_gptab.gt_entry.gt_bytes - last;
+
+ exact = false;
+ for (look = 1; look < c; look++)
+ {
+ if (tab[look].gt_entry.gt_g_value >= val)
+ tab[look].gt_entry.gt_bytes += add;
+
+ if (tab[look].gt_entry.gt_g_value == val)
+ exact = true;
+ }
+
+ if (! exact)
+ {
+ Elf32_gptab *new_tab;
+ unsigned int max;
+
+ /* We need a new table entry. */
+ new_tab = ((Elf32_gptab *)
+ bfd_realloc ((PTR) tab,
+ (c + 1) * sizeof (Elf32_gptab)));
+ if (new_tab == NULL)
+ {
+ free (tab);
+ return false;
+ }
+ tab = new_tab;
+ tab[c].gt_entry.gt_g_value = val;
+ tab[c].gt_entry.gt_bytes = add;
+
+ /* Merge in the size for the next smallest -G
+ value, since that will be implied by this new
+ value. */
+ max = 0;
+ for (look = 1; look < c; look++)
+ {
+ if (tab[look].gt_entry.gt_g_value < val
+ && (max == 0
+ || (tab[look].gt_entry.gt_g_value
+ > tab[max].gt_entry.gt_g_value)))
+ max = look;
+ }
+ if (max != 0)
+ tab[c].gt_entry.gt_bytes +=
+ tab[max].gt_entry.gt_bytes;
+
+ ++c;
+ }
+
+ last = int_gptab.gt_entry.gt_bytes;
+ }
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ /* The table must be sorted by -G value. */
+ if (c > 2)
+ qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare);
+
+ /* Swap out the table. */
+ ext_tab = ((Elf32_External_gptab *)
+ bfd_alloc (abfd, c * sizeof (Elf32_External_gptab)));
+ if (ext_tab == NULL)
+ {
+ free (tab);
+ return false;
+ }
+
+ for (i = 0; i < c; i++)
+ bfd_mips_elf32_swap_gptab_out (abfd, tab + i, ext_tab + i);
+ free (tab);
+
+ o->_raw_size = c * sizeof (Elf32_External_gptab);
+ o->contents = (bfd_byte *) ext_tab;
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+ }
+ }
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (! bfd_elf32_bfd_final_link (abfd, info))
+ return false;
+
+ /* Now write out the computed sections. */
+
+ if (reginfo_sec != (asection *) NULL)
+ {
+ Elf32_External_RegInfo ext;
+
+ bfd_mips_elf32_swap_reginfo_out (abfd, &reginfo, &ext);
+ if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext,
+ (file_ptr) 0, sizeof ext))
+ return false;
+ }
+
+ if (mdebug_sec != (asection *) NULL)
+ {
+ BFD_ASSERT (abfd->output_has_begun);
+ if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
+ swap, info,
+ mdebug_sec->filepos))
+ return false;
+
+ bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
+ }
+
+ if (gptab_data_sec != (asection *) NULL)
+ {
+ if (! bfd_set_section_contents (abfd, gptab_data_sec,
+ gptab_data_sec->contents,
+ (file_ptr) 0,
+ gptab_data_sec->_raw_size))
+ return false;
+ }
+
+ if (gptab_bss_sec != (asection *) NULL)
+ {
+ if (! bfd_set_section_contents (abfd, gptab_bss_sec,
+ gptab_bss_sec->contents,
+ (file_ptr) 0,
+ gptab_bss_sec->_raw_size))
+ return false;
+ }
+
+ if (SGI_COMPAT (abfd))
+ {
+ rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
+ if (rtproc_sec != NULL)
+ {
+ if (! bfd_set_section_contents (abfd, rtproc_sec,
+ rtproc_sec->contents,
+ (file_ptr) 0,
+ rtproc_sec->_raw_size))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Handle a MIPS ELF HI16 reloc. */
+
+static void
+mips_elf_relocate_hi16 (input_bfd, relhi, rello, contents, addend)
+ bfd *input_bfd;
+ Elf_Internal_Rela *relhi;
+ Elf_Internal_Rela *rello;
+ bfd_byte *contents;
+ bfd_vma addend;
+{
+ bfd_vma insn;
+ bfd_vma addlo;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ addlo = bfd_get_32 (input_bfd, contents + rello->r_offset);
+ addlo &= 0xffff;
+
+ addend += ((insn & 0xffff) << 16) + addlo;
+
+ if ((addlo & 0x8000) != 0)
+ addend -= 0x10000;
+ if ((addend & 0x8000) != 0)
+ addend += 0x10000;
+
+ bfd_put_32 (input_bfd,
+ (insn & 0xffff0000) | ((addend >> 16) & 0xffff),
+ contents + relhi->r_offset);
+}
+
+/* Handle a MIPS ELF local GOT16 reloc. */
+
+static boolean
+mips_elf_relocate_got_local (output_bfd, input_bfd, sgot, relhi, rello,
+ contents, addend)
+ bfd *output_bfd;
+ bfd *input_bfd;
+ asection *sgot;
+ Elf_Internal_Rela *relhi;
+ Elf_Internal_Rela *rello;
+ bfd_byte *contents;
+ bfd_vma addend;
+{
+ unsigned int assigned_gotno;
+ unsigned int i;
+ bfd_vma insn;
+ bfd_vma addlo;
+ bfd_vma address;
+ bfd_vma hipage;
+ bfd_byte *got_contents;
+ struct mips_got_info *g;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ addlo = bfd_get_32 (input_bfd, contents + rello->r_offset);
+ addlo &= 0xffff;
+
+ addend += ((insn & 0xffff) << 16) + addlo;
+
+ if ((addlo & 0x8000) != 0)
+ addend -= 0x10000;
+ if ((addend & 0x8000) != 0)
+ addend += 0x10000;
+
+ /* Get a got entry representing requested hipage. */
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+
+ assigned_gotno = g->assigned_gotno;
+ got_contents = sgot->contents;
+ hipage = addend & 0xffff0000;
+
+ for (i = MIPS_RESERVED_GOTNO; i < assigned_gotno; i++)
+ {
+ address = bfd_get_32 (input_bfd, got_contents + i * 4);
+ if (hipage == (address & 0xffff0000))
+ break;
+ }
+
+ if (i == assigned_gotno)
+ {
+ if (assigned_gotno >= g->local_gotno)
+ {
+ (*_bfd_error_handler)
+ (_("more got entries are needed for hipage relocations"));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ bfd_put_32 (input_bfd, hipage, got_contents + assigned_gotno * 4);
+ ++g->assigned_gotno;
+ }
+
+ i = - ELF_MIPS_GP_OFFSET (output_bfd) + i * 4;
+ bfd_put_32 (input_bfd, (insn & 0xffff0000) | (i & 0xffff),
+ contents + relhi->r_offset);
+
+ return true;
+}
+
+/* Handle MIPS ELF CALL16 reloc and global GOT16 reloc. */
+
+static void
+mips_elf_relocate_global_got (input_bfd, rel, contents, offset)
+ bfd *input_bfd;
+ Elf_Internal_Rela *rel;
+ bfd_byte *contents;
+ bfd_vma offset;
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ bfd_put_32 (input_bfd,
+ (insn & 0xffff0000) | (offset & 0xffff),
+ contents + rel->r_offset);
+}
+
+/* Relocate a MIPS ELF section. */
+
+static boolean
+mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t locsymcount;
+ size_t extsymoff;
+ asection *sgot, *sreloc, *scpt;
+ bfd *dynobj;
+ bfd_vma gp;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ struct mips_got_info *g;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ sgot = NULL;
+ sreloc = NULL;
+ if (dynobj == NULL || ! SGI_COMPAT (output_bfd))
+ scpt = NULL;
+ else
+ scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
+ g = NULL;
+
+ if (elf_bad_symtab (input_bfd))
+ {
+ locsymcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ extsymoff = 0;
+ }
+ else
+ {
+ locsymcount = symtab_hdr->sh_info;
+ extsymoff = symtab_hdr->sh_info;
+ }
+
+ gp = _bfd_get_gp_value (output_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ bfd_vma addend;
+ struct elf_link_hash_entry *h;
+ asection *sec;
+ Elf_Internal_Sym *sym;
+ struct mips_elf_link_hash_entry *mh;
+ int other;
+ bfd_reloc_status_type r;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_MIPS_GNU_VTINHERIT
+ || r_type == R_MIPS_GNU_VTENTRY)
+ continue;
+ if ((r_type < 0 || r_type >= (int) R_MIPS_max)
+ && r_type != R_MIPS16_26
+ && r_type != R_MIPS16_GPREL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ if (r_type == R_MIPS16_26)
+ howto = &elf_mips16_jump_howto;
+ else if (r_type == R_MIPS16_GPREL)
+ howto = &elf_mips16_gprel_howto;
+ else
+ howto = elf_mips_howto_table + r_type;
+
+ if (dynobj != NULL
+ && (r_type == R_MIPS_CALL16
+ || r_type == R_MIPS_GOT16
+ || r_type == R_MIPS_CALL_HI16
+ || r_type == R_MIPS_CALL_LO16
+ || r_type == R_MIPS_GOT_HI16
+ || r_type == R_MIPS_GOT_LO16))
+ {
+ /* We need the .got section. */
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+ }
+ }
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ /* Mix in the change in GP address for a GP relative reloc. */
+ if (r_type != R_MIPS_GPREL16
+ && r_type != R_MIPS_LITERAL
+ && r_type != R_MIPS_GPREL32
+ && r_type != R_MIPS16_GPREL)
+ addend = 0;
+ else
+ {
+ if (gp == 0)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info,
+ _("GP relative relocation when GP not defined"),
+ input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ /* Only give the error once per link. */
+ gp = 4;
+ _bfd_set_gp_value (output_bfd, gp);
+ }
+
+ if (r_symndx < extsymoff
+ || (elf_bad_symtab (input_bfd)
+ && local_sections[r_symndx] != NULL))
+ {
+ /* This is a relocation against a section. The current
+ addend in the instruction is the difference between
+ INPUT_SECTION->vma and the GP value of INPUT_BFD. We
+ must change this to be the difference between the
+ final definition (which will end up in RELOCATION)
+ and the GP value of OUTPUT_BFD (which is in GP). */
+ addend = elf_gp (input_bfd) - gp;
+ }
+ else if (! info->relocateable)
+ {
+ /* We are doing a final link. The current addend in the
+ instruction is simply the desired offset into the
+ symbol (normally zero). We want the instruction to
+ hold the difference between the final definition of
+ the symbol (which will end up in RELOCATION) and the
+ GP value of OUTPUT_BFD (which is in GP). */
+ addend = - gp;
+ }
+ else
+ {
+ /* We are generating relocateable output, and we aren't
+ going to define this symbol, so we just leave the
+ instruction alone. */
+ addend = 0;
+ }
+ }
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx >= locsymcount
+ || (elf_bad_symtab (input_bfd)
+ && local_sections[r_symndx] == NULL))
+ r = bfd_reloc_ok;
+ else
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ r = bfd_reloc_ok;
+ else
+ {
+ sec = local_sections[r_symndx];
+
+ /* It would be logical to add sym->st_value here,
+ but Irix 5 sometimes generates a garbage symbol
+ value. */
+ addend += sec->output_offset;
+
+ /* If this is HI16 or GOT16 with an associated LO16,
+ adjust the addend accordingly. Otherwise, just
+ relocate. */
+ if (r_type == R_MIPS_64 && bfd_big_endian (input_bfd))
+ r = _bfd_relocate_contents (howto, input_bfd,
+ addend,
+ contents + rel->r_offset + 4);
+ else if (r_type != R_MIPS_HI16 && r_type != R_MIPS_GOT16)
+ r = _bfd_relocate_contents (howto, input_bfd,
+ addend,
+ contents + rel->r_offset);
+ else
+ {
+ Elf_Internal_Rela *lorel;
+
+ /* As a GNU extension, permit an arbitrary
+ number of R_MIPS_HI16 relocs before the
+ R_MIPS_LO16 reloc. This permits gcc to emit
+ the HI and LO relocs itself. */
+ if (r_type == R_MIPS_GOT16)
+ lorel = rel + 1;
+ else
+ {
+ for (lorel = rel + 1;
+ (lorel < relend
+ && (ELF32_R_TYPE (lorel->r_info)
+ == R_MIPS_HI16));
+ lorel++)
+ ;
+ }
+ if (lorel < relend
+ && ELF32_R_TYPE (lorel->r_info) == R_MIPS_LO16)
+ {
+ mips_elf_relocate_hi16 (input_bfd, rel, lorel,
+ contents, addend);
+ r = bfd_reloc_ok;
+ }
+ else
+ r = _bfd_relocate_contents (howto, input_bfd,
+ addend,
+ contents + rel->r_offset);
+ }
+ }
+ }
+ }
+ else
+ {
+ bfd_vma relocation;
+ boolean local;
+ boolean undefined_error;
+
+ /* This is a final link. */
+ undefined_error = false;
+ sym = NULL;
+ if (r_symndx < extsymoff
+ || (elf_bad_symtab (input_bfd)
+ && local_sections[r_symndx] != NULL))
+ {
+ local = true;
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset);
+
+ /* It would be logical to always add sym->st_value here,
+ but Irix 5 sometimes generates a garbage symbol
+ value. */
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ relocation += sym->st_value;
+
+ /* mips16 text labels should be treated as odd. */
+ if (sym->st_other == STO_MIPS16)
+ ++relocation;
+ }
+ else
+ {
+ long indx;
+
+ local = false;
+ indx = r_symndx - extsymoff;
+ h = elf_sym_hashes (input_bfd)[indx];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (strcmp (h->root.root.string, "_gp_disp") == 0)
+ {
+ if (gp == 0)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info,
+ _("_gp_disp used when GP not defined"),
+ input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ /* Only give the error once per link. */
+ gp = 4;
+ _bfd_set_gp_value (output_bfd, gp);
+ relocation = 0;
+ }
+ else
+ {
+ sec = input_section;
+ if (sec->output_section != NULL)
+ relocation = (gp
+ - (rel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset));
+ else
+ relocation = gp - rel->r_offset;
+ if (r_type == R_MIPS_LO16)
+ relocation += 4;
+ }
+ }
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if (sec->output_section == NULL)
+ relocation = 0;
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0)
+ {
+ /* If this is a dynamic link, we should have created
+ a _DYNAMIC_LINK symbol in
+ mips_elf_create_dynamic_sections. Otherwise, we
+ should define the symbol with a value of 0.
+ FIXME: It should probably get into the symbol
+ table somehow as well. */
+ BFD_ASSERT (! info->shared);
+ BFD_ASSERT (bfd_get_section_by_name (output_bfd,
+ ".dynamic") == NULL);
+ relocation = 0;
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ undefined_error = true;
+ relocation = 0;
+ }
+ }
+
+ mh = (struct mips_elf_link_hash_entry *) h;
+ if (h != NULL)
+ other = h->other;
+ else if (sym != NULL)
+ other = sym->st_other;
+ else
+ other = 0;
+
+ /* If this function has an fn_stub, then it is a mips16
+ function which needs a stub if it is called by a 32 bit
+ function. If this reloc is anything other than a 16 bit
+ call, redirect the reloc to the stub. We don't redirect
+ relocs from other stub functions. */
+ if (r_type != R_MIPS16_26
+ && ((mh != NULL
+ && mh->fn_stub != NULL)
+ || (mh == NULL
+ && elf_tdata (input_bfd)->local_stubs != NULL
+ && elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL))
+ && strncmp (bfd_get_section_name (input_bfd, input_section),
+ FN_STUB, sizeof FN_STUB - 1) != 0
+ && strncmp (bfd_get_section_name (input_bfd, input_section),
+ CALL_STUB, sizeof CALL_STUB - 1) != 0
+ && strncmp (bfd_get_section_name (input_bfd, input_section),
+ CALL_FP_STUB, sizeof CALL_FP_STUB - 1) != 0)
+ {
+ if (mh != NULL)
+ {
+ BFD_ASSERT (mh->need_fn_stub);
+ relocation = (mh->fn_stub->output_section->vma
+ + mh->fn_stub->output_offset);
+ }
+ else
+ {
+ asection *fn_stub;
+
+ fn_stub = elf_tdata (input_bfd)->local_stubs[r_symndx];
+ relocation = (fn_stub->output_section->vma
+ + fn_stub->output_offset);
+ }
+
+ /* RELOCATION now points to 32 bit code. */
+ other = 0;
+ }
+
+ /* If this function has a call_stub, then it is called by a
+ mips16 function; the call needs to go through a stub if
+ this function is a 32 bit function. If this reloc is a
+ 16 bit call, and the symbol is not a 16 bit function,
+ then redirect the reloc to the stub. Note that we don't
+ need to worry about calling the function through a
+ function pointer; such calls are handled by routing
+ through a special mips16 routine. We don't have to check
+ whether this call is from a stub; it can't be, because a
+ stub contains 32 bit code, and hence can not have a 16
+ bit reloc. */
+ if (r_type == R_MIPS16_26
+ && mh != NULL
+ && (mh->call_stub != NULL || mh->call_fp_stub != NULL)
+ && other != STO_MIPS16)
+ {
+ asection *stub;
+
+ /* If both call_stub and call_fp_stub are defined, we
+ can figure out which one to use by seeing which one
+ appears in the input file. */
+ if (mh->call_stub != NULL && mh->call_fp_stub != NULL)
+ {
+ asection *o;
+
+ stub = NULL;
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ if (strncmp (bfd_get_section_name (input_bfd, o),
+ CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
+ {
+ stub = mh->call_fp_stub;
+ break;
+ }
+ }
+ if (stub == NULL)
+ stub = mh->call_stub;
+ }
+ else if (mh->call_stub != NULL)
+ stub = mh->call_stub;
+ else
+ stub = mh->call_fp_stub;
+
+ BFD_ASSERT (stub->_raw_size > 0);
+ relocation = stub->output_section->vma + stub->output_offset;
+ }
+
+ if (r_type == R_MIPS_HI16)
+ {
+ Elf_Internal_Rela *lorel;
+
+ /* As a GNU extension, permit an arbitrary number of
+ R_MIPS_HI16 relocs before the R_MIPS_LO16 reloc.
+ This permits gcc to emit the HI and LO relocs itself. */
+ for (lorel = rel + 1;
+ (lorel < relend
+ && ELF32_R_TYPE (lorel->r_info) == R_MIPS_HI16);
+ lorel++)
+ ;
+ if (lorel < relend
+ && ELF32_R_TYPE (lorel->r_info) == R_MIPS_LO16)
+ {
+ mips_elf_relocate_hi16 (input_bfd, rel, lorel,
+ contents, relocation + addend);
+ r = bfd_reloc_ok;
+ }
+ else
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+ }
+ else if (r_type == R_MIPS_GOT16 && local)
+ {
+ /* GOT16 must also have an associated LO16 in the local
+ case. In this case, the addend is extracted and the
+ section in which the referenced object is determined.
+ Then the final address of the object is computed and
+ the GOT entry for the hipage (an aligned 64kb chunk)
+ is added to .got section if needed. The offset field
+ of the GOT16-relocated instruction is replaced by the
+ index of this GOT entry for the hipage. */
+ if ((rel + 1) < relend
+ && ELF32_R_TYPE ((rel + 1)->r_info) == R_MIPS_LO16)
+ {
+ if (! mips_elf_relocate_got_local (output_bfd, input_bfd,
+ sgot, rel, rel + 1,
+ contents,
+ relocation + addend))
+ return false;
+ r = bfd_reloc_ok;
+ }
+ else
+ r = bfd_reloc_outofrange;
+ }
+ else if (r_type == R_MIPS_CALL16
+ || r_type == R_MIPS_GOT16
+ || r_type == R_MIPS_CALL_LO16
+ || r_type == R_MIPS_GOT_LO16)
+ {
+ bfd_vma offset;
+
+ /* This symbol must be registered as a global symbol
+ having the corresponding got entry. */
+ BFD_ASSERT (h->got.offset != (bfd_vma) -1);
+
+ offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4;
+ BFD_ASSERT (g->local_gotno <= offset
+ && offset < sgot->_raw_size);
+ bfd_put_32 (output_bfd, relocation + addend,
+ sgot->contents + offset);
+ offset = (sgot->output_section->vma + sgot->output_offset
+ + offset - gp);
+ mips_elf_relocate_global_got (input_bfd, rel, contents,
+ offset);
+ r = bfd_reloc_ok;
+ }
+ else if (r_type == R_MIPS_CALL_HI16
+ || r_type == R_MIPS_GOT_HI16)
+ {
+ bfd_vma offset;
+
+ /* This must be a global symbol with a got entry. The
+ next reloc must be the corresponding LO16 reloc. */
+ BFD_ASSERT (h != NULL && h->got.offset != (bfd_vma) -1);
+ BFD_ASSERT ((rel + 1) < relend);
+ BFD_ASSERT ((int) ELF32_R_TYPE ((rel + 1)->r_info)
+ == (r_type == R_MIPS_CALL_HI16
+ ? (int) R_MIPS_CALL_LO16
+ : (int) R_MIPS_GOT_LO16));
+
+ offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4;
+ BFD_ASSERT (g->local_gotno <= offset
+ && offset < sgot->_raw_size);
+ bfd_put_32 (output_bfd, relocation + addend,
+ sgot->contents + offset);
+ offset = (sgot->output_section->vma + sgot->output_offset
+ + offset - gp);
+ mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, contents,
+ offset);
+ r = bfd_reloc_ok;
+ }
+ else if (r_type == R_MIPS_REL32
+ || r_type == R_MIPS_32)
+ {
+ Elf_Internal_Rel outrel;
+ Elf32_crinfo cptrel;
+ bfd_byte *cr;
+
+ if ((info->shared
+ || (elf_hash_table (info)->dynamic_sections_created
+ && h != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
+ == 0)))
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ boolean skip;
+
+ /* When generating a shared object, these
+ relocations are copied into the output file to be
+ resolved at run time. */
+ if (sreloc == NULL)
+ {
+ sreloc = bfd_get_section_by_name (dynobj, ".rel.dyn");
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && (! info->symbolic
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_REL32);
+ sec = input_section;
+ }
+ else
+ {
+ long indx;
+
+ if (h == NULL)
+ sec = local_sections[r_symndx];
+ else
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || (h->root.type
+ == bfd_link_hash_defweak));
+ sec = h->root.u.def.section;
+ }
+ if (sec != NULL && bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ abort ();
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, R_MIPS_REL32);
+ addend += relocation;
+ }
+
+ if (! skip)
+ bfd_put_32 (output_bfd, addend, contents + rel->r_offset);
+
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ (((Elf32_External_Rel *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ if (! skip && SGI_COMPAT (output_bfd))
+ {
+ if (scpt == NULL)
+ continue;
+
+ /* Make an entry of compact relocation info. */
+ mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG);
+ cptrel.vaddr = (rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset);
+ if (r_type == R_MIPS_REL32)
+ mips_elf_set_cr_type (cptrel, CRT_MIPS_REL32);
+ else
+ mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
+ mips_elf_set_cr_dist2to (cptrel, 0);
+ cptrel.konst = addend;
+
+ cr = (scpt->contents
+ + sizeof (Elf32_External_compact_rel));
+ bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
+ ((Elf32_External_crinfo *) cr
+ + scpt->reloc_count));
+ ++scpt->reloc_count;
+ }
+
+ /* This reloc will be computed at runtime, so
+ there's no need to do anything now. */
+ continue;
+ }
+ else
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+ }
+ else if (r_type == R_MIPS_64)
+ {
+ bfd_size_type addr;
+ unsigned long val;
+
+ /* Do a 32 bit relocation, and sign extend to 64 bits. */
+ addr = rel->r_offset;
+ if (bfd_big_endian (input_bfd))
+ addr += 4;
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, addr, relocation,
+ addend);
+ val = bfd_get_32 (input_bfd, contents + addr);
+ if ((val & 0x80000000) != 0)
+ val = 0xffffffff;
+ else
+ val = 0;
+ addr = rel->r_offset;
+ if (bfd_little_endian (input_bfd))
+ addr += 4;
+ bfd_put_32 (input_bfd, val, contents + addr);
+ }
+ else if (r_type == R_MIPS_26 && other == STO_MIPS16)
+ {
+ unsigned long insn;
+
+ /* This is a jump to a mips16 routine from a mips32
+ routine. We need to change jal into jalx. */
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if (((insn >> 26) & 0x3f) != 0x3
+ && ((insn >> 26) & 0x3f) != 0x1d)
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s+0x%lx: jump to mips16 routine which is not jal"),
+ bfd_get_filename (input_bfd),
+ input_section->name,
+ (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ insn = (insn & 0x3ffffff) | (0x1d << 26);
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+ }
+ else if (r_type == R_MIPS16_26)
+ {
+ /* It's easiest to do the normal relocation, and then
+ dig out the instruction and swap the first word the
+ way the mips16 expects it. If this is little endian,
+ though, we need to swap the two words first, and then
+ swap them back again later, so that the address looks
+ right. */
+
+ if (bfd_little_endian (input_bfd))
+ {
+ unsigned long insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn = ((insn >> 16) & 0xffff) | ((insn & 0xffff) << 16);
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+ if (r == bfd_reloc_ok)
+ {
+ unsigned long insn;
+
+ if (bfd_little_endian (input_bfd))
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn = ((insn >> 16) & 0xffff) | ((insn & 0xffff) << 16);
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ }
+
+ insn = bfd_get_16 (input_bfd, contents + rel->r_offset);
+ insn = ((insn & 0xfc00)
+ | ((insn & 0x1f) << 5)
+ | ((insn & 0x3e0) >> 5));
+ /* If this is a jump to a 32 bit routine, then make
+ it jalx. */
+ if (other != STO_MIPS16)
+ insn |= 0x400;
+ bfd_put_16 (input_bfd, insn, contents + rel->r_offset);
+ }
+ }
+ else if (r_type == R_MIPS16_GPREL)
+ {
+ unsigned short extend, insn;
+ bfd_byte buf[4];
+ unsigned long final;
+
+ /* Extract the addend into buf, run the regular reloc,
+ and stuff the resulting value back into the
+ instructions. */
+ if (rel->r_offset > input_section->_raw_size)
+ r = bfd_reloc_outofrange;
+ else
+ {
+ extend = bfd_get_16 (input_bfd, contents + rel->r_offset);
+ insn = bfd_get_16 (input_bfd, contents + rel->r_offset + 2);
+ bfd_put_32 (input_bfd,
+ (((extend & 0x1f) << 11)
+ | (extend & 0x7e0)
+ | (insn & 0x1f)),
+ buf);
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, buf,
+ (bfd_vma) 0, relocation,
+ addend);
+ final = bfd_get_32 (input_bfd, buf);
+ bfd_put_16 (input_bfd,
+ ((extend & 0xf800)
+ | ((final >> 11) & 0x1f)
+ | (final & 0x7e0)),
+ contents + rel->r_offset);
+ bfd_put_16 (input_bfd,
+ ((insn & 0xffe0)
+ | (final & 0x1f)),
+ contents + rel->r_offset + 2);
+ }
+ }
+ else
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+
+ /* The jal instruction can only jump to an address which is
+ divisible by 4, and it can only jump to an address with
+ the same upper 4 bits as the PC. */
+ if (r == bfd_reloc_ok
+ && (r_type == R_MIPS16_26 || r_type == R_MIPS_26))
+ {
+ bfd_vma addr;
+ bfd_vma pc;
+ bfd_vma target;
+
+ pc = ((input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset)
+ & 0xf0000000);
+ target = bfd_get_32 (input_bfd, contents + rel->r_offset)
+ & (howto->dst_mask);
+ addr = (target << 2) + pc;
+ if (other == STO_MIPS16)
+ addr &= ~ (bfd_vma) 1;
+ if ((addr & 3) != 0
+ || ((addr & 0xf0000000)
+ != pc))
+ r = bfd_reloc_overflow;
+ }
+
+ /* Don't bother to report a relocation overflow for a call
+ to a weak undefined symbol with a value of zero. This
+ permits us to use
+ if (!f) f();
+ even if we aren't in range to call address zero. */
+ if (r == bfd_reloc_overflow
+ && (r_type == R_MIPS16_26 || r_type == R_MIPS_26)
+ && relocation + addend == 0
+ && h != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ r = bfd_reloc_ok;
+
+ /* If we've already issued an error for an undefined symbol,
+ don't issue another useless error. */
+ if (undefined_error
+ && (r == bfd_reloc_undefined || r == bfd_reloc_overflow))
+ r = bfd_reloc_ok;
+
+ if (SGI_COMPAT (abfd)
+ && scpt != NULL
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ Elf32_crinfo cptrel;
+ bfd_byte *cr;
+
+ /* Make an entry of compact relocation info. */
+ mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG);
+ cptrel.vaddr = (rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset);
+
+ switch (r_type)
+ {
+ case R_MIPS_26:
+ mips_elf_set_cr_type (cptrel, CRT_MIPS_JMPAD);
+ /* XXX How should we set dist2to in this case. */
+ mips_elf_set_cr_dist2to (cptrel, 8);
+ cptrel.konst = addend + relocation;
+ cr = scpt->contents + sizeof (Elf32_External_compact_rel);
+ bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
+ ((Elf32_External_crinfo *) cr
+ + scpt->reloc_count));
+ ++scpt->reloc_count;
+ break;
+
+ case R_MIPS_GPREL16:
+ case R_MIPS_LITERAL:
+ case R_MIPS_GPREL32:
+ mips_elf_set_cr_type (cptrel, CRT_MIPS_GPHI_LO);
+ cptrel.konst = gp - cptrel.vaddr;
+ mips_elf_set_cr_dist2to (cptrel, 4);
+ cr = scpt->contents + sizeof (Elf32_External_compact_rel);
+ bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
+ ((Elf32_External_crinfo *) cr
+ + scpt->reloc_count));
+ ++scpt->reloc_count;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* This hook function is called before the linker writes out a global
+ symbol. We mark symbols as small common if appropriate. This is
+ also where we undo the increment of the value for a mips16 symbol. */
+
+/*ARGSIGNORED*/
+static boolean
+mips_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const char *name;
+ Elf_Internal_Sym *sym;
+ asection *input_sec;
+{
+ /* If we see a common symbol, which implies a relocatable link, then
+ if a symbol was small common in an input file, mark it as small
+ common in the output file. */
+ if (sym->st_shndx == SHN_COMMON
+ && strcmp (input_sec->name, ".scommon") == 0)
+ sym->st_shndx = SHN_MIPS_SCOMMON;
+
+ if (sym->st_other == STO_MIPS16
+ && (sym->st_value & 1) != 0)
+ --sym->st_value;
+
+ return true;
+}
+
+/* Functions for the dynamic linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static boolean
+mips_elf_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ struct elf_link_hash_entry *h;
+ flagword flags;
+ register asection *s;
+ const char * const *namep;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ /* Mips ABI requests the .dynamic section to be read only. */
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ if (! bfd_set_section_flags (abfd, s, flags))
+ return false;
+ }
+
+ /* We need to create .got section. */
+ if (! mips_elf_create_got_section (abfd, info))
+ return false;
+
+ /* Create .stub section. */
+ if (bfd_get_section_by_name (abfd, ".stub") == NULL)
+ {
+ s = bfd_make_section (abfd, ".stub");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+ }
+
+ if (SGI_COMPAT (abfd)
+ && !info->shared
+ && bfd_get_section_by_name (abfd, ".rld_map") == NULL)
+ {
+ s = bfd_make_section (abfd, ".rld_map");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags & ~SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+ }
+
+ if (SGI_COMPAT (abfd))
+ {
+ for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
+ {
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_SECTION;
+
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ /* We need to create a .compact_rel section. */
+ if (! mips_elf_create_compact_rel_section (abfd, info))
+ return false;
+
+ /* Change aligments of some sections. */
+ s = bfd_get_section_by_name (abfd, ".hash");
+ if (s != NULL)
+ bfd_set_section_alignment (abfd, s, 4);
+ s = bfd_get_section_by_name (abfd, ".dynsym");
+ if (s != NULL)
+ bfd_set_section_alignment (abfd, s, 4);
+ s = bfd_get_section_by_name (abfd, ".dynstr");
+ if (s != NULL)
+ bfd_set_section_alignment (abfd, s, 4);
+ s = bfd_get_section_by_name (abfd, ".reginfo");
+ if (s != NULL)
+ bfd_set_section_alignment (abfd, s, 4);
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ bfd_set_section_alignment (abfd, s, 4);
+ }
+
+ if (!info->shared)
+ {
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_SECTION;
+
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+
+ if (! mips_elf_hash_table (info)->use_rld_obj_head)
+ {
+ /* __rld_map is a four byte word located in the .data section
+ and is filled in by the rtld to contain a pointer to
+ the _r_debug structure. Its symbol value will be set in
+ mips_elf_finish_dynamic_symbol. */
+ s = bfd_get_section_by_name (abfd, ".rld_map");
+ BFD_ASSERT (s != NULL);
+
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "__rld_map", BSF_GLOBAL, s,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Create the .compact_rel section. */
+
+static boolean
+mips_elf_create_compact_rel_section (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+
+ if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL)
+ {
+ flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+
+ s = bfd_make_section (abfd, ".compact_rel");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ s->_raw_size = sizeof (Elf32_External_compact_rel);
+ }
+
+ return true;
+}
+
+/* Create the .got section to hold the global offset table. */
+
+static boolean
+mips_elf_create_got_section (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+ struct elf_link_hash_entry *h;
+ struct mips_got_info *g;
+
+ /* This function may be called more than once. */
+ if (bfd_get_section_by_name (abfd, ".got") != NULL)
+ return true;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ s = bfd_make_section (abfd, ".got");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 4))
+ return false;
+
+ /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
+ linker script because we don't want to define the symbol if we
+ are not creating a global offset table. */
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (info->shared
+ && ! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+
+ /* The first several global offset table entries are reserved. */
+ s->_raw_size = MIPS_RESERVED_GOTNO * 4;
+
+ g = (struct mips_got_info *) bfd_alloc (abfd,
+ sizeof (struct mips_got_info));
+ if (g == NULL)
+ return false;
+ g->global_gotsym = 0;
+ g->local_gotno = MIPS_RESERVED_GOTNO;
+ g->assigned_gotno = MIPS_RESERVED_GOTNO;
+ if (elf_section_data (s) == NULL)
+ {
+ s->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data));
+ if (elf_section_data (s) == NULL)
+ return false;
+ }
+ elf_section_data (s)->tdata = (PTR) g;
+
+ return true;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table. */
+
+static boolean
+mips_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ const char *name;
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ struct mips_got_info *g;
+ size_t extsymoff;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *sreloc;
+
+ if (info->relocateable)
+ return true;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
+
+ /* Check for the mips16 stub sections. */
+
+ name = bfd_get_section_name (abfd, sec);
+ if (strncmp (name, FN_STUB, sizeof FN_STUB - 1) == 0)
+ {
+ unsigned long r_symndx;
+
+ /* Look at the relocation information to figure out which symbol
+ this is for. */
+
+ r_symndx = ELF32_R_SYM (relocs->r_info);
+
+ if (r_symndx < extsymoff
+ || sym_hashes[r_symndx - extsymoff] == NULL)
+ {
+ asection *o;
+
+ /* This stub is for a local symbol. This stub will only be
+ needed if there is some relocation in this BFD, other
+ than a 16 bit function call, which refers to this symbol. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *sec_relocs;
+ const Elf_Internal_Rela *r, *rend;
+
+ /* We can ignore stub sections when looking for relocs. */
+ if ((o->flags & SEC_RELOC) == 0
+ || o->reloc_count == 0
+ || strncmp (bfd_get_section_name (abfd, o), FN_STUB,
+ sizeof FN_STUB - 1) == 0
+ || strncmp (bfd_get_section_name (abfd, o), CALL_STUB,
+ sizeof CALL_STUB - 1) == 0
+ || strncmp (bfd_get_section_name (abfd, o), CALL_FP_STUB,
+ sizeof CALL_FP_STUB - 1) == 0)
+ continue;
+
+ sec_relocs = (_bfd_elf32_link_read_relocs
+ (abfd, o, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory));
+ if (sec_relocs == NULL)
+ return false;
+
+ rend = sec_relocs + o->reloc_count;
+ for (r = sec_relocs; r < rend; r++)
+ if (ELF32_R_SYM (r->r_info) == r_symndx
+ && ELF32_R_TYPE (r->r_info) != R_MIPS16_26)
+ break;
+
+ if (! info->keep_memory)
+ free (sec_relocs);
+
+ if (r < rend)
+ break;
+ }
+
+ if (o == NULL)
+ {
+ /* There is no non-call reloc for this stub, so we do
+ not need it. Since this function is called before
+ the linker maps input sections to output sections, we
+ can easily discard it by setting the SEC_EXCLUDE
+ flag. */
+ sec->flags |= SEC_EXCLUDE;
+ return true;
+ }
+
+ /* Record this stub in an array of local symbol stubs for
+ this BFD. */
+ if (elf_tdata (abfd)->local_stubs == NULL)
+ {
+ unsigned long symcount;
+ asection **n;
+
+ if (elf_bad_symtab (abfd))
+ symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ else
+ symcount = symtab_hdr->sh_info;
+ n = (asection **) bfd_zalloc (abfd,
+ symcount * sizeof (asection *));
+ if (n == NULL)
+ return false;
+ elf_tdata (abfd)->local_stubs = n;
+ }
+
+ elf_tdata (abfd)->local_stubs[r_symndx] = sec;
+
+ /* We don't need to set mips16_stubs_seen in this case.
+ That flag is used to see whether we need to look through
+ the global symbol table for stubs. We don't need to set
+ it here, because we just have a local stub. */
+ }
+ else
+ {
+ struct mips_elf_link_hash_entry *h;
+
+ h = ((struct mips_elf_link_hash_entry *)
+ sym_hashes[r_symndx - extsymoff]);
+
+ /* H is the symbol this stub is for. */
+
+ h->fn_stub = sec;
+ mips_elf_hash_table (info)->mips16_stubs_seen = true;
+ }
+ }
+ else if (strncmp (name, CALL_STUB, sizeof CALL_STUB - 1) == 0
+ || strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
+ {
+ unsigned long r_symndx;
+ struct mips_elf_link_hash_entry *h;
+ asection **loc;
+
+ /* Look at the relocation information to figure out which symbol
+ this is for. */
+
+ r_symndx = ELF32_R_SYM (relocs->r_info);
+
+ if (r_symndx < extsymoff
+ || sym_hashes[r_symndx - extsymoff] == NULL)
+ {
+ /* This stub was actually built for a static symbol defined
+ in the same file. We assume that all static symbols in
+ mips16 code are themselves mips16, so we can simply
+ discard this stub. Since this function is called before
+ the linker maps input sections to output sections, we can
+ easily discard it by setting the SEC_EXCLUDE flag. */
+ sec->flags |= SEC_EXCLUDE;
+ return true;
+ }
+
+ h = ((struct mips_elf_link_hash_entry *)
+ sym_hashes[r_symndx - extsymoff]);
+
+ /* H is the symbol this stub is for. */
+
+ if (strncmp (name, CALL_FP_STUB, sizeof CALL_FP_STUB - 1) == 0)
+ loc = &h->call_fp_stub;
+ else
+ loc = &h->call_stub;
+
+ /* If we already have an appropriate stub for this function, we
+ don't need another one, so we can discard this one. Since
+ this function is called before the linker maps input sections
+ to output sections, we can easily discard it by setting the
+ SEC_EXCLUDE flag. We can also discard this section if we
+ happen to already know that this is a mips16 function; it is
+ not necessary to check this here, as it is checked later, but
+ it is slightly faster to check now. */
+ if (*loc != NULL || h->root.other == STO_MIPS16)
+ {
+ sec->flags |= SEC_EXCLUDE;
+ return true;
+ }
+
+ *loc = sec;
+ mips_elf_hash_table (info)->mips16_stubs_seen = true;
+ }
+
+ if (dynobj == NULL)
+ {
+ sgot = NULL;
+ g = NULL;
+ }
+ else
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ if (sgot == NULL)
+ g = NULL;
+ else
+ {
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+ }
+ }
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx < extsymoff)
+ h = NULL;
+ else
+ {
+ h = sym_hashes[r_symndx - extsymoff];
+
+ /* This may be an indirect symbol created because of a version. */
+ if (h != NULL)
+ {
+ while (h->root.type == bfd_link_hash_indirect)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+ }
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL || sgot == NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MIPS_GOT16:
+ case R_MIPS_CALL16:
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_CALL_LO16:
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_GOT_LO16:
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! mips_elf_create_got_section (dynobj, info))
+ return false;
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+ break;
+
+ case R_MIPS_32:
+ case R_MIPS_REL32:
+ if (dynobj == NULL
+ && (info->shared || h != NULL)
+ && (sec->flags & SEC_ALLOC) != 0)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MIPS_CALL16:
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_CALL_LO16:
+ /* This symbol requires a global offset table entry. */
+
+ if (h == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: CALL16 reloc at 0x%lx not against global symbol"),
+ bfd_get_filename (abfd), (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+
+ /* Note the index of the first global got symbol in .dynsym. */
+ if (g->global_gotsym == 0
+ || g->global_gotsym > (unsigned long) h->dynindx)
+ g->global_gotsym = h->dynindx;
+
+ /* Make this symbol to have the corresponding got entry. */
+ h->got.offset = 0;
+
+ /* We need a stub, not a plt entry for the undefined
+ function. But we record it as if it needs plt. See
+ elf_adjust_dynamic_symbol in elflink.h. */
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->type = STT_FUNC;
+
+ break;
+
+ case R_MIPS_GOT16:
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_GOT_LO16:
+ /* This symbol requires a global offset table entry. */
+
+ if (h != NULL)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ /* Note the index of the first global got symbol in
+ .dynsym. */
+ if (g->global_gotsym == 0
+ || g->global_gotsym > (unsigned long) h->dynindx)
+ g->global_gotsym = h->dynindx;
+
+ /* Make this symbol to be the global got symbol. */
+ h->got.offset = 0;
+ }
+
+ break;
+
+ case R_MIPS_32:
+ case R_MIPS_REL32:
+ if ((info->shared || h != NULL)
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ if (sreloc == NULL)
+ {
+ const char *name = ".rel.dyn";
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ sreloc = bfd_make_section (dynobj, name);
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, sreloc,
+ 4))
+ return false;
+ }
+ }
+ if (info->shared)
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file as R_MIPS_REL32
+ relocs. We make room for this reloc in the
+ .rel.dyn reloc section */
+ if (sreloc->_raw_size == 0)
+ {
+ /* Add a null element. */
+ sreloc->_raw_size += sizeof (Elf32_External_Rel);
+ ++sreloc->reloc_count;
+ }
+ sreloc->_raw_size += sizeof (Elf32_External_Rel);
+ }
+ else
+ {
+ struct mips_elf_link_hash_entry *hmips;
+
+ /* We only need to copy this reloc if the symbol is
+ defined in a dynamic object. */
+ hmips = (struct mips_elf_link_hash_entry *) h;
+ ++hmips->mips_32_relocs;
+ }
+ }
+
+ if (SGI_COMPAT (abfd))
+ mips_elf_hash_table (info)->compact_rel_size +=
+ sizeof (Elf32_External_crinfo);
+
+ break;
+
+ case R_MIPS_26:
+ case R_MIPS_GPREL16:
+ case R_MIPS_LITERAL:
+ case R_MIPS_GPREL32:
+ if (SGI_COMPAT (abfd))
+ mips_elf_hash_table (info)->compact_rel_size +=
+ sizeof (Elf32_External_crinfo);
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_MIPS_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_MIPS_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+
+ /* If this reloc is not a 16 bit call, and it has a global
+ symbol, then we will need the fn_stub if there is one.
+ References from a stub section do not count. */
+ if (h != NULL
+ && ELF32_R_TYPE (rel->r_info) != R_MIPS16_26
+ && strncmp (bfd_get_section_name (abfd, sec), FN_STUB,
+ sizeof FN_STUB - 1) != 0
+ && strncmp (bfd_get_section_name (abfd, sec), CALL_STUB,
+ sizeof CALL_STUB - 1) != 0
+ && strncmp (bfd_get_section_name (abfd, sec), CALL_FP_STUB,
+ sizeof CALL_FP_STUB - 1) != 0)
+ {
+ struct mips_elf_link_hash_entry *mh;
+
+ mh = (struct mips_elf_link_hash_entry *) h;
+ mh->need_fn_stub = true;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+mips_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ /* ??? Do mips16 stub sections need to be handled special? */
+
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MIPS_GNU_VTINHERIT:
+ case R_MIPS_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+mips_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+#if 0
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_MIPS_GOT16:
+ case R_MIPS_CALL16:
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_CALL_LO16:
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_GOT_LO16:
+ /* ??? It would seem that the existing MIPS code does no sort
+ of reference counting or whatnot on its GOT and PLT entries,
+ so it is not possible to garbage collect them at this time. */
+ break;
+
+ default:
+ break;
+ }
+#endif
+
+ return true;
+}
+
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+mips_elf_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj;
+ struct mips_elf_link_hash_entry *hmips;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+ /* If this symbol is defined in a dynamic object, we need to copy
+ any R_MIPS_32 or R_MIPS_REL32 relocs against it into the output
+ file. */
+ hmips = (struct mips_elf_link_hash_entry *) h;
+ if (! info->relocateable
+ && hmips->mips_32_relocs != 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ s = bfd_get_section_by_name (dynobj, ".rel.dyn");
+ BFD_ASSERT (s != NULL);
+
+ if (s->_raw_size == 0)
+ {
+ /* Make room for a null element. */
+ s->_raw_size += sizeof (Elf32_External_Rel);
+ ++s->reloc_count;
+ }
+ s->_raw_size += hmips->mips_32_relocs * sizeof (Elf32_External_Rel);
+ }
+
+ /* For a function, create a stub, if needed. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ if (! elf_hash_table (info)->dynamic_sections_created)
+ return true;
+
+ /* If this symbol is not defined in a regular file, then set
+ the symbol to the stub location. This is required to make
+ function pointers compare as equal between the normal
+ executable and the shared library. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* We need .stub section. */
+ s = bfd_get_section_by_name (dynobj, ".stub");
+ BFD_ASSERT (s != NULL);
+
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* XXX Write this stub address somewhere. */
+ h->plt.offset = s->_raw_size;
+
+ /* Make room for this stub code. */
+ s->_raw_size += MIPS_FUNCTION_STUB_SIZE;
+
+ /* The last half word of the stub will be filled with the index
+ of this symbol in .dynsym section. */
+ return true;
+ }
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ return true;
+}
+
+/* This function is called after all the input files have been read,
+ and the input sections have been assigned to output sections. We
+ check for any mips16 stub sections that we can discard. */
+
+static boolean mips_elf_check_mips16_stubs
+ PARAMS ((struct mips_elf_link_hash_entry *, PTR));
+
+static boolean
+mips_elf_always_size_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ asection *ri;
+
+ /* The .reginfo section has a fixed size. */
+ ri = bfd_get_section_by_name (output_bfd, ".reginfo");
+ if (ri != NULL)
+ bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo));
+
+ if (info->relocateable
+ || ! mips_elf_hash_table (info)->mips16_stubs_seen)
+ return true;
+
+ mips_elf_link_hash_traverse (mips_elf_hash_table (info),
+ mips_elf_check_mips16_stubs,
+ (PTR) NULL);
+
+ return true;
+}
+
+/* Check the mips16 stubs for a particular symbol, and see if we can
+ discard them. */
+
+/*ARGSUSED*/
+static boolean
+mips_elf_check_mips16_stubs (h, data)
+ struct mips_elf_link_hash_entry *h;
+ PTR data;
+{
+ if (h->fn_stub != NULL
+ && ! h->need_fn_stub)
+ {
+ /* We don't need the fn_stub; the only references to this symbol
+ are 16 bit calls. Clobber the size to 0 to prevent it from
+ being included in the link. */
+ h->fn_stub->_raw_size = 0;
+ h->fn_stub->_cooked_size = 0;
+ h->fn_stub->flags &= ~ SEC_RELOC;
+ h->fn_stub->reloc_count = 0;
+ h->fn_stub->flags |= SEC_EXCLUDE;
+ }
+
+ if (h->call_stub != NULL
+ && h->root.other == STO_MIPS16)
+ {
+ /* We don't need the call_stub; this is a 16 bit function, so
+ calls from other 16 bit functions are OK. Clobber the size
+ to 0 to prevent it from being included in the link. */
+ h->call_stub->_raw_size = 0;
+ h->call_stub->_cooked_size = 0;
+ h->call_stub->flags &= ~ SEC_RELOC;
+ h->call_stub->reloc_count = 0;
+ h->call_stub->flags |= SEC_EXCLUDE;
+ }
+
+ if (h->call_fp_stub != NULL
+ && h->root.other == STO_MIPS16)
+ {
+ /* We don't need the call_stub; this is a 16 bit function, so
+ calls from other 16 bit functions are OK. Clobber the size
+ to 0 to prevent it from being included in the link. */
+ h->call_fp_stub->_raw_size = 0;
+ h->call_fp_stub->_cooked_size = 0;
+ h->call_fp_stub->flags &= ~ SEC_RELOC;
+ h->call_fp_stub->reloc_count = 0;
+ h->call_fp_stub->flags |= SEC_EXCLUDE;
+ }
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+mips_elf_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean reltext;
+ asection *sgot;
+ struct mips_got_info *g;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (! info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Recompute the size of .got for local entires (reserved and
+ hipages) if needed. To estimate it, get the upper bound of total
+ size of loadable sections. */
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+
+ if (sgot != NULL)
+ {
+ bfd_size_type loadable_size = 0;
+ bfd_size_type local_gotno;
+ struct _bfd *sub;
+
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+
+ for (sub = info->input_bfds; sub; sub = sub->link_next)
+ for (s = sub->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_ALLOC) == 0)
+ continue;
+ loadable_size += (s->_raw_size + 0xf) & ~0xf;
+ }
+
+ loadable_size += MIPS_FUNCTION_STUB_SIZE;
+
+ /* Assume there are two loadable segments consisting of
+ contiguous sections. Is 5 enough? */
+ local_gotno = (loadable_size >> 16) + 5 + MIPS_RESERVED_GOTNO;
+ g->local_gotno = local_gotno;
+ sgot->_raw_size += local_gotno * 4;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ reltext = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ strip = false;
+
+ if (strncmp (name, ".rel", 4) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* We only strip the section if the output section name
+ has the same name. Otherwise, there might be several
+ input sections for this output section. FIXME: This
+ code is probably not needed these days anyhow, since
+ the linker now does not create empty output sections. */
+ if (s->output_section != NULL
+ && strcmp (name,
+ bfd_get_section_name (s->output_section->owner,
+ s->output_section)) == 0)
+ strip = true;
+ }
+ else
+ {
+ const char *outname;
+ asection *target;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL entry.
+ If the relocation section is .rel.dyn, we always
+ assert a DT_TEXTREL entry rather than testing whether
+ there exists a relocation to a read only section or
+ not. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 4);
+ if ((target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ || strcmp (outname, ".rel.dyn") == 0)
+ reltext = true;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ if (strcmp (name, ".rel.dyn") != 0)
+ s->reloc_count = 0;
+ }
+ }
+ else if (strncmp (name, ".got", 4) == 0)
+ {
+ int i;
+
+ BFD_ASSERT (elf_section_data (s) != NULL);
+ g = (struct mips_got_info *) elf_section_data (s)->tdata;
+ BFD_ASSERT (g != NULL);
+
+ /* Fix the size of .got section for the correspondence of
+ global symbols and got entries. This adds some useless
+ got entries. Is this required by ABI really? */
+ i = elf_hash_table (info)->dynsymcount - g->global_gotsym;
+ s->_raw_size += i * 4;
+ }
+ else if (strncmp (name, ".stub", 5) == 0)
+ {
+ /* Irix rld assumes that the function stub isn't at the end
+ of .text section. So put a dummy. XXX */
+ s->_raw_size += MIPS_FUNCTION_STUB_SIZE;
+ }
+ else if (! info->shared
+ && ! mips_elf_hash_table (info)->use_rld_obj_head
+ && strncmp (name, ".rld_map", 8) == 0)
+ {
+ /* We add a room for __rld_map. It will be filled in by the
+ rtld to contain a pointer to the _r_debug structure. */
+ s->_raw_size += 4;
+ }
+ else if (SGI_COMPAT (output_bfd)
+ && strncmp (name, ".compact_rel", 12) == 0)
+ s->_raw_size += mips_elf_hash_table (info)->compact_rel_size;
+ else if (strncmp (name, ".init", 5) != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ _bfd_strip_section_from_output (s);
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ memset (s->contents, 0, s->_raw_size);
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_mips_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (! info->shared)
+ {
+ if (SGI_COMPAT (output_bfd))
+ {
+ /* SGI object has the equivalence of DT_DEBUG in the
+ DT_MIPS_RLD_MAP entry. */
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_RLD_MAP, 0))
+ return false;
+ }
+ else
+ if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (reltext)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0))
+ return false;
+
+ if (bfd_get_section_by_name (dynobj, ".rel.dyn"))
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_RELENT, 0))
+ return false;
+ }
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICTNO, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLISTNO, 0))
+ return false;
+
+ if (bfd_get_section_by_name (dynobj, ".conflict") != NULL)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICT, 0))
+ return false;
+
+ s = bfd_get_section_by_name (dynobj, ".liblist");
+ BFD_ASSERT (s != NULL);
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLIST, 0))
+ return false;
+ }
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_RLD_VERSION, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_FLAGS, 0))
+ return false;
+
+#if 0
+ /* Time stamps in executable files are a bad idea. */
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_TIME_STAMP, 0))
+ return false;
+#endif
+
+#if 0 /* FIXME */
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_ICHECKSUM, 0))
+ return false;
+#endif
+
+#if 0 /* FIXME */
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_IVERSION, 0))
+ return false;
+#endif
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_BASE_ADDRESS, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LOCAL_GOTNO, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_SYMTABNO, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_UNREFEXTNO, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_GOTSYM, 0))
+ return false;
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_HIPAGENO, 0))
+ return false;
+
+#if 0 /* (SGI_COMPAT) */
+ if (! bfd_get_section_by_name (dynobj, ".init"))
+ if (! bfd_elf32_add_dynamic_entry (info, DT_INIT, 0))
+ return false;
+
+ if (! bfd_get_section_by_name (dynobj, ".fini"))
+ if (! bfd_elf32_add_dynamic_entry (info, DT_FINI, 0))
+ return false;
+#endif
+ }
+
+ /* If we use dynamic linking, we generate a section symbol for each
+ output section. These are local symbols, which means that they
+ must come first in the dynamic symbol table.
+ That means we must increment the dynamic symbol index of every
+ other dynamic symbol. */
+ {
+ unsigned int c, i;
+ struct mips_got_info *g;
+
+ c = 0;
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+#if 0
+ /* We no longer try to restrict the set of sections which get
+ dynamic symbol table entries, since it fails if we have
+ other random sections which need dynamic relocations. */
+ const char * const *namep;
+ bfd_size_type strindex;
+ struct bfd_strtab_hash *dynstr;
+
+ if (SGI_COMPAT (output_bfd))
+ {
+ c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1;
+ elf_link_hash_traverse (elf_hash_table (info),
+ mips_elf_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+
+ dynstr = elf_hash_table (info)->dynstr;
+ BFD_ASSERT (dynstr != NULL);
+
+ for (i = 1, namep = mips_elf_dynsym_sec_names;
+ *namep != NULL;
+ i++, namep++)
+ {
+ s = bfd_get_section_by_name (output_bfd, *namep);
+ if (s != NULL)
+ elf_section_data (s)->dynindx = i;
+
+ strindex = _bfd_stringtab_add (dynstr, *namep, true, false);
+ if (strindex == (bfd_size_type) -1)
+ return false;
+
+ mips_elf_hash_table (info)->dynsym_sec_strindex[i] = strindex;
+ }
+ }
+ else
+#endif /* 0 */
+ {
+ c = bfd_count_sections (output_bfd);
+ elf_link_hash_traverse (elf_hash_table (info),
+ mips_elf_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+
+ for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++)
+ {
+ elf_section_data (s)->dynindx = i;
+ /* These symbols will have no names, so we don't need to
+ fiddle with dynstr_index. */
+ }
+ }
+ }
+
+ if (sgot != NULL)
+ {
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+
+ /* If there are no global got symbols, fake the last symbol so
+ for safety. */
+ if (g->global_gotsym)
+ g->global_gotsym += c;
+ else
+ g->global_gotsym = elf_hash_table (info)->dynsymcount - 1;
+ }
+ }
+
+ return true;
+}
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+
+static boolean
+mips_elf_adjust_dynindx (h, cparg)
+ struct elf_link_hash_entry *h;
+ PTR cparg;
+{
+ unsigned int *cp = (unsigned int *) cparg;
+
+ if (h->dynindx != -1)
+ h->dynindx += *cp;
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj;
+ bfd_vma gval;
+ asection *sgot;
+ struct mips_got_info *g;
+ const char *name;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ gval = sym->st_value;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *s;
+ bfd_byte *p;
+ bfd_byte stub[MIPS_FUNCTION_STUB_SIZE];
+
+ /* This symbol has a stub. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_section_by_name (dynobj, ".stub");
+ BFD_ASSERT (s != NULL);
+
+ /* Fill the stub. */
+ p = stub;
+ bfd_put_32 (output_bfd, STUB_LW(output_bfd), p);
+ p += 4;
+ bfd_put_32 (output_bfd, STUB_MOVE, p);
+ p += 4;
+
+ /* FIXME: Can h->dynindex be more than 64K? */
+ if (h->dynindx & 0xffff0000)
+ return false;
+
+ bfd_put_32 (output_bfd, STUB_JALR, p);
+ p += 4;
+ bfd_put_32 (output_bfd, STUB_LI16 + h->dynindx, p);
+
+ BFD_ASSERT (h->plt.offset <= s->_raw_size);
+ memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
+
+ /* Mark the symbol as undefined. plt.offset != -1 occurs
+ only for the referenced symbol. */
+ sym->st_shndx = SHN_UNDEF;
+
+ /* The run-time linker uses the st_value field of the symbol
+ to reset the global offset table entry for this external
+ to its stub address when unlinking a shared object. */
+ gval = s->output_section->vma + s->output_offset + h->plt.offset;
+ sym->st_value = gval;
+ }
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+
+ if ((unsigned long) h->dynindx >= g->global_gotsym)
+ {
+ bfd_size_type offset;
+
+ /* This symbol has an entry in the global offset table. Set its
+ value to the corresponding got entry, if needed. */
+ if (h->got.offset == (bfd_vma) -1)
+ {
+ offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4;
+ BFD_ASSERT (g->local_gotno * 4 <= offset
+ && offset < sgot->_raw_size);
+ bfd_put_32 (output_bfd, gval, sgot->contents + offset);
+ }
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ name = h->root.root.string;
+ if (strcmp (name, "_DYNAMIC") == 0
+ || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+ else if (strcmp (name, "_DYNAMIC_LINK") == 0)
+ {
+ sym->st_shndx = SHN_ABS;
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_value = 1;
+ }
+ else if (SGI_COMPAT (output_bfd))
+ {
+ if (strcmp (name, "_gp_disp") == 0)
+ {
+ sym->st_shndx = SHN_ABS;
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_value = elf_gp (output_bfd);
+ }
+ else if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
+ || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0)
+ {
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_other = STO_PROTECTED;
+ sym->st_value = 0;
+ sym->st_shndx = SHN_MIPS_DATA;
+ }
+ else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0)
+ {
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_other = STO_PROTECTED;
+ sym->st_value = mips_elf_hash_table (info)->procedure_count;
+ sym->st_shndx = SHN_ABS;
+ }
+ else if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS)
+ {
+ if (h->type == STT_FUNC)
+ sym->st_shndx = SHN_MIPS_TEXT;
+ else if (h->type == STT_OBJECT)
+ sym->st_shndx = SHN_MIPS_DATA;
+ }
+ }
+
+ if (SGI_COMPAT (output_bfd)
+ && ! info->shared)
+ {
+ if (! mips_elf_hash_table (info)->use_rld_obj_head
+ && strcmp (name, "__rld_map") == 0)
+ {
+ asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
+ BFD_ASSERT (s != NULL);
+ sym->st_value = s->output_section->vma + s->output_offset;
+ bfd_put_32 (output_bfd, (bfd_vma) 0, s->contents);
+ if (mips_elf_hash_table (info)->rld_value == 0)
+ mips_elf_hash_table (info)->rld_value = sym->st_value;
+ }
+ else if (mips_elf_hash_table (info)->use_rld_obj_head
+ && strcmp (name, "__rld_obj_head") == 0)
+ {
+ asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
+ BFD_ASSERT (s != NULL);
+ mips_elf_hash_table (info)->rld_value = sym->st_value;
+ }
+ }
+
+ /* If this is a mips16 symbol, force the value to be even. */
+ if (sym->st_other == STO_MIPS16
+ && (sym->st_value & 1) != 0)
+ --sym->st_value;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+mips_elf_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+ struct mips_got_info *g;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ if (sgot == NULL)
+ g = NULL;
+ else
+ {
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = (struct mips_got_info *) elf_section_data (sgot)->tdata;
+ BFD_ASSERT (g != NULL);
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+ BFD_ASSERT (g != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ size_t elemsize;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_RELENT:
+ s = bfd_get_section_by_name (dynobj, ".rel.dyn");
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = sizeof (Elf32_External_Rel);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_STRSZ:
+ /* Rewrite DT_STRSZ. */
+ dyn.d_un.d_val =
+ _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTGOT:
+ name = ".got";
+ goto get_vma;
+ case DT_MIPS_CONFLICT:
+ name = ".conflict";
+ goto get_vma;
+ case DT_MIPS_LIBLIST:
+ name = ".liblist";
+ get_vma:
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_RLD_VERSION:
+ dyn.d_un.d_val = 1; /* XXX */
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_FLAGS:
+ dyn.d_un.d_val = RHF_NOTPOT; /* XXX */
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_CONFLICTNO:
+ name = ".conflict";
+ elemsize = sizeof (Elf32_Conflict);
+ goto set_elemno;
+
+ case DT_MIPS_LIBLISTNO:
+ name = ".liblist";
+ elemsize = sizeof (Elf32_Lib);
+ set_elemno:
+ s = bfd_get_section_by_name (output_bfd, name);
+ if (s != NULL)
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size / elemsize;
+ else
+ dyn.d_un.d_val = s->_raw_size / elemsize;
+ }
+ else
+ dyn.d_un.d_val = 0;
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_TIME_STAMP:
+ time ((time_t *) &dyn.d_un.d_val);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_ICHECKSUM:
+ /* XXX FIXME: */
+ break;
+
+ case DT_MIPS_IVERSION:
+ /* XXX FIXME: */
+ break;
+
+ case DT_MIPS_BASE_ADDRESS:
+ s = output_bfd->sections;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma & ~(0xffff);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_LOCAL_GOTNO:
+ dyn.d_un.d_val = g->local_gotno;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_SYMTABNO:
+ name = ".dynsym";
+ elemsize = sizeof (Elf32_External_Sym);
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size / elemsize;
+ else
+ dyn.d_un.d_val = s->_raw_size / elemsize;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_UNREFEXTNO:
+#if 0
+ dyn.d_un.d_val = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#else
+ dyn.d_un.d_val = bfd_count_sections (output_bfd);
+#endif
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_GOTSYM:
+ dyn.d_un.d_val = g->global_gotsym;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_HIPAGENO:
+ dyn.d_un.d_val = g->local_gotno - MIPS_RESERVED_GOTNO;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_MIPS_RLD_MAP:
+ dyn.d_un.d_ptr = mips_elf_hash_table (info)->rld_value;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ }
+ }
+ }
+
+ /* The first entry of the global offset table will be filled at
+ runtime. The second entry will be used by some runtime loaders.
+ This isn't the case of Irix rld. */
+ if (sgot != NULL && sgot->_raw_size > 0)
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, sgot->contents + 4);
+ }
+
+ if (sgot != NULL)
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ {
+ asection *sdynsym;
+ asection *s;
+ Elf_Internal_Sym sym;
+ Elf32_compact_rel cpt;
+
+ /* Set up the section symbols for the output sections. SGI sets
+ the STT_NOTYPE attribute for these symbols. Should we do so? */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ if (sdynsym != NULL)
+ {
+#if 0
+ const char *name;
+ const char * const * namep = mips_elf_dynsym_sec_names;
+ unsigned int i;
+ bfd_vma last;
+ long dindx;
+
+ /* We no longer try to restrict the set of sections which get
+ dynamic symbol table entries, since it fails if we have
+ other random sections which need dynamic relocations. */
+ if (SGI_COMPAT (output_bfd))
+ {
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
+ sym.st_other = 0;
+
+ i = 0;
+ last = 0;
+ dindx = 0;
+ while ((name = *namep++) != NULL)
+ {
+ s = bfd_get_section_by_name (output_bfd, name);
+ if (s != NULL)
+ {
+ sym.st_value = s->vma;
+ dindx = elf_section_data (s)->dynindx;
+ last = s->vma + s->_raw_size;
+ }
+ else
+ {
+ sym.st_value = last;
+ dindx++;
+ }
+
+ sym.st_shndx = (i < MIPS_TEXT_DYNSYM_SECNO
+ ? SHN_MIPS_TEXT
+ : SHN_MIPS_DATA);
+ ++i;
+ sym.st_name =
+ mips_elf_hash_table (info)->dynsym_sec_strindex[dindx];
+
+ bfd_elf32_swap_symbol_out (output_bfd, &sym,
+ (((Elf32_External_Sym *)
+ sdynsym->contents)
+ + dindx));
+ }
+
+ /* Set the sh_info field of the output .dynsym section to
+ the index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
+ SIZEOF_MIPS_DYNSYM_SECNAMES;
+ }
+ else
+#endif /* 0 */
+ {
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx;
+
+ sym.st_value = s->vma;
+
+ indx = elf_section_data (s)->this_idx;
+ BFD_ASSERT (indx > 0);
+ sym.st_shndx = indx;
+
+ bfd_elf32_swap_symbol_out (output_bfd, &sym,
+ (((Elf32_External_Sym *)
+ sdynsym->contents)
+ + elf_section_data (s)->dynindx));
+ }
+
+ /* Set the sh_info field of the output .dynsym section to
+ the index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
+ bfd_count_sections (output_bfd) + 1;
+ }
+ }
+
+ if (SGI_COMPAT (output_bfd))
+ {
+ /* Write .compact_rel section out. */
+ s = bfd_get_section_by_name (dynobj, ".compact_rel");
+ if (s != NULL)
+ {
+ cpt.id1 = 1;
+ cpt.num = s->reloc_count;
+ cpt.id2 = 2;
+ cpt.offset = (s->output_section->filepos
+ + sizeof (Elf32_External_compact_rel));
+ cpt.reserved0 = 0;
+ cpt.reserved1 = 0;
+ bfd_elf32_swap_compact_rel_out (output_bfd, &cpt,
+ ((Elf32_External_compact_rel *)
+ s->contents));
+
+ /* Clean up a dummy stub function entry in .text. */
+ s = bfd_get_section_by_name (dynobj, ".stub");
+ if (s != NULL)
+ {
+ file_ptr dummy_offset;
+
+ BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE);
+ dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE;
+ memset (s->contents + dummy_offset, 0,
+ MIPS_FUNCTION_STUB_SIZE);
+ }
+ }
+ }
+
+ /* Clean up a first relocation in .rel.dyn. */
+ s = bfd_get_section_by_name (dynobj, ".rel.dyn");
+ if (s != NULL && s->_raw_size > 0)
+ memset (s->contents, 0, sizeof (Elf32_External_Rel));
+ }
+
+ return true;
+}
+
+/* This is almost identical to bfd_generic_get_... except that some
+ MIPS relocations need to be handled specially. Sigh. */
+
+static bfd_byte *
+elf32_mips_get_relocated_section_contents (abfd, link_info, link_order, data,
+ relocateable, symbols)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ /* Get enough memory to hold the stuff */
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ arelent **reloc_vector = NULL;
+ long reloc_count;
+
+ if (reloc_size < 0)
+ goto error_return;
+
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ /* read in the section */
+ if (!bfd_get_section_contents (input_bfd,
+ input_section,
+ (PTR) data,
+ 0,
+ input_section->_raw_size))
+ goto error_return;
+
+ /* We're not relaxing the section, so just copy the size info */
+ input_section->_cooked_size = input_section->_raw_size;
+ input_section->reloc_done = true;
+
+ reloc_count = bfd_canonicalize_reloc (input_bfd,
+ input_section,
+ reloc_vector,
+ symbols);
+ if (reloc_count < 0)
+ goto error_return;
+
+ if (reloc_count > 0)
+ {
+ arelent **parent;
+ /* for mips */
+ int gp_found;
+ bfd_vma gp = 0x12345678; /* initialize just to shut gcc up */
+
+ {
+ struct bfd_hash_entry *h;
+ struct bfd_link_hash_entry *lh;
+ /* Skip all this stuff if we aren't mixing formats. */
+ if (abfd && input_bfd
+ && abfd->xvec == input_bfd->xvec)
+ lh = 0;
+ else
+ {
+ h = bfd_hash_lookup (&link_info->hash->table, "_gp", false, false);
+ lh = (struct bfd_link_hash_entry *) h;
+ }
+ lookup:
+ if (lh)
+ {
+ switch (lh->type)
+ {
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ case bfd_link_hash_common:
+ gp_found = 0;
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ gp_found = 1;
+ gp = lh->u.def.value;
+ break;
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ lh = lh->u.i.link;
+ /* @@FIXME ignoring warning for now */
+ goto lookup;
+ case bfd_link_hash_new:
+ default:
+ abort ();
+ }
+ }
+ else
+ gp_found = 0;
+ }
+ /* end mips */
+ for (parent = reloc_vector; *parent != (arelent *) NULL;
+ parent++)
+ {
+ char *error_message = (char *) NULL;
+ bfd_reloc_status_type r;
+
+ /* Specific to MIPS: Deal with relocation types that require
+ knowing the gp of the output bfd. */
+ asymbol *sym = *(*parent)->sym_ptr_ptr;
+ if (bfd_is_abs_section (sym->section) && abfd)
+ {
+ /* The special_function wouldn't get called anyways. */
+ }
+ else if (!gp_found)
+ {
+ /* The gp isn't there; let the special function code
+ fall over on its own. */
+ }
+ else if ((*parent)->howto->special_function
+ == _bfd_mips_elf_gprel16_reloc)
+ {
+ /* bypass special_function call */
+ r = gprel16_with_gp (input_bfd, sym, *parent, input_section,
+ relocateable, (PTR) data, gp);
+ goto skip_bfd_perform_relocation;
+ }
+ /* end mips specific stuff */
+
+ r = bfd_perform_relocation (input_bfd,
+ *parent,
+ (PTR) data,
+ input_section,
+ relocateable ? abfd : (bfd *) NULL,
+ &error_message);
+ skip_bfd_perform_relocation:
+
+ if (relocateable)
+ {
+ asection *os = input_section->output_section;
+
+ /* A partial link, so keep the relocs */
+ os->orelocation[os->reloc_count] = *parent;
+ os->reloc_count++;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ case bfd_reloc_undefined:
+ if (!((*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ input_bfd, input_section, (*parent)->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_dangerous:
+ BFD_ASSERT (error_message != (char *) NULL);
+ if (!((*link_info->callbacks->reloc_dangerous)
+ (link_info, error_message, input_bfd, input_section,
+ (*parent)->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_overflow:
+ if (!((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ (*parent)->howto->name, (*parent)->addend,
+ input_bfd, input_section, (*parent)->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_outofrange:
+ default:
+ abort ();
+ break;
+ }
+
+ }
+ }
+ }
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return data;
+
+error_return:
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return NULL;
+}
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ elf32_mips_get_relocated_section_contents
+
+/* ECOFF swapping routines. These are used when dealing with the
+ .mdebug section, which is in the ECOFF debugging format. */
+static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap =
+{
+ /* Symbol table magic number. */
+ magicSym,
+ /* Alignment of debugging information. E.g., 4. */
+ 4,
+ /* Sizes of external symbolic information. */
+ sizeof (struct hdr_ext),
+ sizeof (struct dnr_ext),
+ sizeof (struct pdr_ext),
+ sizeof (struct sym_ext),
+ sizeof (struct opt_ext),
+ sizeof (struct fdr_ext),
+ sizeof (struct rfd_ext),
+ sizeof (struct ext_ext),
+ /* Functions to swap in external symbolic data. */
+ ecoff_swap_hdr_in,
+ ecoff_swap_dnr_in,
+ ecoff_swap_pdr_in,
+ ecoff_swap_sym_in,
+ ecoff_swap_opt_in,
+ ecoff_swap_fdr_in,
+ ecoff_swap_rfd_in,
+ ecoff_swap_ext_in,
+ _bfd_ecoff_swap_tir_in,
+ _bfd_ecoff_swap_rndx_in,
+ /* Functions to swap out external symbolic data. */
+ ecoff_swap_hdr_out,
+ ecoff_swap_dnr_out,
+ ecoff_swap_pdr_out,
+ ecoff_swap_sym_out,
+ ecoff_swap_opt_out,
+ ecoff_swap_fdr_out,
+ ecoff_swap_rfd_out,
+ ecoff_swap_ext_out,
+ _bfd_ecoff_swap_tir_out,
+ _bfd_ecoff_swap_rndx_out,
+ /* Function to read in symbolic data. */
+ _bfd_mips_elf_read_ecoff_info
+};
+
+#define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec
+#define TARGET_LITTLE_NAME "elf32-littlemips"
+#define TARGET_BIG_SYM bfd_elf32_bigmips_vec
+#define TARGET_BIG_NAME "elf32-bigmips"
+#define ELF_ARCH bfd_arch_mips
+#define ELF_MACHINE_CODE EM_MIPS
+
+/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
+ a value of 0x1000, and we are compatible. */
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_backend_collect true
+#define elf_backend_type_change_ok true
+#define elf_backend_can_gc_sections true
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel mips_info_to_howto_rel
+#define elf_backend_sym_is_global mips_elf_sym_is_global
+#define elf_backend_object_p mips_elf32_object_p
+#define elf_backend_section_from_shdr mips_elf32_section_from_shdr
+#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
+#define elf_backend_section_from_bfd_section \
+ _bfd_mips_elf_section_from_bfd_section
+#define elf_backend_section_processing mips_elf32_section_processing
+#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
+#define elf_backend_additional_program_headers \
+ mips_elf_additional_program_headers
+#define elf_backend_modify_segment_map mips_elf_modify_segment_map
+#define elf_backend_final_write_processing \
+ _bfd_mips_elf_final_write_processing
+#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
+
+#define bfd_elf32_bfd_is_local_label_name \
+ mips_elf_is_local_label_name
+#define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
+#define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
+#define bfd_elf32_bfd_link_hash_table_create \
+ mips_elf_link_hash_table_create
+#define bfd_elf32_bfd_final_link mips_elf_final_link
+#define bfd_elf32_bfd_copy_private_bfd_data \
+ _bfd_mips_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ _bfd_mips_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+ _bfd_mips_elf_print_private_bfd_data
+#define elf_backend_add_symbol_hook mips_elf_add_symbol_hook
+#define elf_backend_create_dynamic_sections \
+ mips_elf_create_dynamic_sections
+#define elf_backend_check_relocs mips_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ mips_elf_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ mips_elf_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ mips_elf_size_dynamic_sections
+#define elf_backend_relocate_section mips_elf_relocate_section
+#define elf_backend_link_output_symbol_hook \
+ mips_elf_link_output_symbol_hook
+#define elf_backend_finish_dynamic_symbol \
+ mips_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ mips_elf_finish_dynamic_sections
+#define elf_backend_gc_mark_hook mips_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook mips_elf_gc_sweep_hook
+
+#define elf_backend_got_header_size (4*MIPS_RESERVED_GOTNO)
+#define elf_backend_plt_header_size 0
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
new file mode 100644
index 00000000000..25bb24ae4f9
--- /dev/null
+++ b/bfd/elf32-ppc.c
@@ -0,0 +1,3848 @@
+/* PowerPC-specific support for 32-bit ELF
+ Copyright 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file is based on a preliminary PowerPC ELF ABI. The
+ information may not match the final PowerPC ELF ABI. It includes
+ suggestions from the in-progress Embedded PowerPC ABI, and that
+ information may also not match. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ppc.h"
+
+#define USE_RELA /* we want RELA relocations, not REL */
+
+
+static reloc_howto_type *ppc_elf_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void ppc_elf_info_to_howto
+ PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst));
+static void ppc_elf_howto_init PARAMS ((void));
+static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword));
+static boolean ppc_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+
+static int ppc_elf_additional_program_headers PARAMS ((bfd *));
+static boolean ppc_elf_modify_segment_map PARAMS ((bfd *));
+
+static boolean ppc_elf_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+static boolean ppc_elf_section_from_shdr PARAMS ((bfd *,
+ Elf32_Internal_Shdr *,
+ char *));
+static boolean ppc_elf_fake_sections
+ PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
+
+static elf_linker_section_t *ppc_elf_create_linker_section
+ PARAMS ((bfd *abfd,
+ struct bfd_link_info *info,
+ enum elf_linker_section_enum));
+
+static boolean ppc_elf_check_relocs PARAMS ((bfd *,
+ struct bfd_link_info *,
+ asection *,
+ const Elf_Internal_Rela *));
+
+static asection * ppc_elf_gc_mark_hook PARAMS ((bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym));
+
+static boolean ppc_elf_gc_sweep_hook PARAMS ((bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs));
+
+static boolean ppc_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *,
+ struct elf_link_hash_entry *));
+
+static boolean ppc_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR));
+
+static boolean ppc_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
+
+static boolean ppc_elf_relocate_section PARAMS ((bfd *,
+ struct bfd_link_info *info,
+ bfd *,
+ asection *,
+ bfd_byte *,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Sym *local_syms,
+ asection **));
+
+static boolean ppc_elf_add_symbol_hook PARAMS ((bfd *,
+ struct bfd_link_info *,
+ const Elf_Internal_Sym *,
+ const char **,
+ flagword *,
+ asection **,
+ bfd_vma *));
+
+static boolean ppc_elf_finish_dynamic_symbol PARAMS ((bfd *,
+ struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+
+static boolean ppc_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));
+
+#define BRANCH_PREDICT_BIT 0x200000 /* branch prediction bit for branch taken relocs */
+#define RA_REGISTER_MASK 0x001f0000 /* mask to set RA in memory instructions */
+#define RA_REGISTER_SHIFT 16 /* value to shift register by to insert RA */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* The size in bytes of an entry in the procedure linkage table. */
+#define PLT_ENTRY_SIZE 12
+/* The initial size of the plt reserved for the dynamic linker. */
+#define PLT_INITIAL_ENTRY_SIZE 72
+/* The size of the gap between entries in the PLT. */
+#define PLT_SLOT_SIZE 8
+/* The number of single-slot PLT entries (the rest use two slots). */
+#define PLT_NUM_SINGLE_ENTRIES 8192
+
+
+static reloc_howto_type *ppc_elf_howto_table[ (int)R_PPC_max ];
+
+static reloc_howto_type ppc_elf_howto_raw[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_PPC_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A standard 32 bit relocation. */
+ HOWTO (R_PPC_ADDR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An absolute 26 bit branch; the lower two bits must be zero.
+ FIXME: we don't check that, we just clear them. */
+ HOWTO (R_PPC_ADDR24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR24", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A standard 16 bit relocation. */
+ HOWTO (R_PPC_ADDR16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_PPC_ADDR16_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR16_LO", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high order 16 bits of an address. */
+ HOWTO (R_PPC_ADDR16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR16_HI", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high order 16 bits of an address, plus 1 if the contents of
+ the low 16 bits, treated as a signed number, is negative. */
+ HOWTO (R_PPC_ADDR16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_addr16_ha_reloc, /* special_function */
+ "R_PPC_ADDR16_HA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An absolute 16 bit branch; the lower two bits must be zero.
+ FIXME: we don't check that, we just clear them. */
+ HOWTO (R_PPC_ADDR14, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR14", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An absolute 16 bit branch, for which bit 10 should be set to
+ indicate that the branch is expected to be taken. The lower two
+ bits must be zero. */
+ HOWTO (R_PPC_ADDR14_BRTAKEN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR14_BRTAKEN",/* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* An absolute 16 bit branch, for which bit 10 should be set to
+ indicate that the branch is not expected to be taken. The lower
+ two bits must be zero. */
+ HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_ADDR14_BRNTAKEN",/* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A relative 26 bit branch; the lower two bits must be zero. */
+ HOWTO (R_PPC_REL24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL24", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 16 bit branch; the lower two bits must be zero. */
+ HOWTO (R_PPC_REL14, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL14", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 16 bit branch. Bit 10 should be set to indicate that
+ the branch is expected to be taken. The lower two bits must be
+ zero. */
+ HOWTO (R_PPC_REL14_BRTAKEN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL14_BRTAKEN", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A relative 16 bit branch. Bit 10 should be set to indicate that
+ the branch is not expected to be taken. The lower two bits must
+ be zero. */
+ HOWTO (R_PPC_REL14_BRNTAKEN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL14_BRNTAKEN",/* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
+ symbol. */
+ HOWTO (R_PPC_GOT16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_PPC_GOT16_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_GOT16_LO", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_PPC_GOT16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_GOT16_HI", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_PPC_GOT16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ ppc_elf_addr16_ha_reloc, /* special_function */
+ "R_PPC_GOT16_HA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_REL24, but referring to the procedure linkage table
+ entry for the symbol. */
+ HOWTO (R_PPC_PLTREL24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_PLTREL24", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* This is used only by the dynamic linker. The symbol should exist
+ both in the object being run and in some shared library. The
+ dynamic linker copies the data addressed by the symbol from the
+ shared library into the object, because the object being
+ run has to have the data at some particular address. */
+ HOWTO (R_PPC_COPY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_COPY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR32, but used when setting global offset table
+ entries. */
+ HOWTO (R_PPC_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_GLOB_DAT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Marks a procedure linkage table entry for a symbol. */
+ HOWTO (R_PPC_JMP_SLOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_JMP_SLOT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Used only by the dynamic linker. When the object is run, this
+ longword is set to the load address of the object, plus the
+ addend. */
+ HOWTO (R_PPC_RELATIVE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_RELATIVE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_REL24, but uses the value of the symbol within the
+ object rather than the final value. Normally used for
+ _GLOBAL_OFFSET_TABLE_. */
+ HOWTO (R_PPC_LOCAL24PC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_LOCAL24PC", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR32, but may be unaligned. */
+ HOWTO (R_PPC_UADDR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_UADDR32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16, but may be unaligned. */
+ HOWTO (R_PPC_UADDR16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_UADDR16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32-bit PC relative */
+ HOWTO (R_PPC_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 32-bit relocation to the symbol's procedure linkage table.
+ FIXME: not supported. */
+ HOWTO (R_PPC_PLT32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_PLT32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32-bit PC relative relocation to the symbol's procedure linkage table.
+ FIXME: not supported. */
+ HOWTO (R_PPC_PLTREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_PLTREL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
+ the symbol. */
+ HOWTO (R_PPC_PLT16_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_PLT16_LO", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
+ the symbol. */
+ HOWTO (R_PPC_PLT16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_PLT16_HI", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
+ the symbol. */
+ HOWTO (R_PPC_PLT16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ ppc_elf_addr16_ha_reloc, /* special_function */
+ "R_PPC_PLT16_HA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
+ small data items. */
+ HOWTO (R_PPC_SDAREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_SDAREL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32-bit section relative relocation. */
+ HOWTO (R_PPC_SECTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_SECTOFF", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 16-bit lower half section relative relocation. */
+ HOWTO (R_PPC_SECTOFF_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_SECTOFF_LO", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16-bit upper half section relative relocation. */
+ HOWTO (R_PPC_SECTOFF_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_SECTOFF_HI", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16-bit upper half adjusted section relative relocation. */
+ HOWTO (R_PPC_SECTOFF_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ ppc_elf_addr16_ha_reloc, /* special_function */
+ "R_PPC_SECTOFF_HA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The remaining relocs are from the Embedded ELF ABI, and are not
+ in the SVR4 ELF ABI. */
+
+ /* 32 bit value resulting from the addend minus the symbol */
+ HOWTO (R_PPC_EMB_NADDR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_NADDR32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit value resulting from the addend minus the symbol */
+ HOWTO (R_PPC_EMB_NADDR16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_NADDR16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit value resulting from the addend minus the symbol */
+ HOWTO (R_PPC_EMB_NADDR16_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_ADDR16_LO", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high order 16 bits of the addend minus the symbol */
+ HOWTO (R_PPC_EMB_NADDR16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_NADDR16_HI", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high order 16 bits of the result of the addend minus the address,
+ plus 1 if the contents of the low 16 bits, treated as a signed number,
+ is negative. */
+ HOWTO (R_PPC_EMB_NADDR16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_addr16_ha_reloc, /* special_function */
+ "R_PPC_EMB_NADDR16_HA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit value resulting from allocating a 4 byte word to hold an
+ address in the .sdata section, and returning the offset from
+ _SDA_BASE_ for that relocation */
+ HOWTO (R_PPC_EMB_SDAI16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_SDAI16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit value resulting from allocating a 4 byte word to hold an
+ address in the .sdata2 section, and returning the offset from
+ _SDA2_BASE_ for that relocation */
+ HOWTO (R_PPC_EMB_SDA2I16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_SDA2I16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with
+ small data items. */
+ HOWTO (R_PPC_EMB_SDA2REL, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_SDA2REL", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit
+ signed offset from the appropriate base, and filling in the register
+ field with the appropriate register (0, 2, or 13). */
+ HOWTO (R_PPC_EMB_SDA21, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_SDA21", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Relocation not handled: R_PPC_EMB_MRKREF */
+ /* Relocation not handled: R_PPC_EMB_RELSEC16 */
+ /* Relocation not handled: R_PPC_EMB_RELST_LO */
+ /* Relocation not handled: R_PPC_EMB_RELST_HI */
+ /* Relocation not handled: R_PPC_EMB_RELST_HA */
+ /* Relocation not handled: R_PPC_EMB_BIT_FLD */
+
+ /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling
+ in the 16 bit signed offset from the appropriate base, and filling in the
+ register field with the appropriate register (0, 2, or 13). */
+ HOWTO (R_PPC_EMB_RELSDA, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_EMB_RELSDA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_PPC_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_PPC_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_PPC_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_PPC_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Phony reloc to handle AIX style TOC entries */
+ HOWTO (R_PPC_TOC16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_TOC16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+};
+
+
+/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
+
+static void
+ppc_elf_howto_init ()
+{
+ unsigned int i, type;
+
+ for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++)
+ {
+ type = ppc_elf_howto_raw[i].type;
+ BFD_ASSERT (type < sizeof(ppc_elf_howto_table) / sizeof(ppc_elf_howto_table[0]));
+ ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
+ }
+}
+
+
+/* This function handles relaxing for the PPC with option --mpc860c0[=<n>].
+
+ The MPC860, revision C0 or earlier contains a bug in the die.
+ If all of the following conditions are true, the next instruction
+ to be executed *may* be treated as a no-op.
+ 1/ A forward branch is executed.
+ 2/ The branch is predicted as not taken.
+ 3/ The branch is taken.
+ 4/ The branch is located in the last 5 words of a page.
+ (The EOP limit is 5 by default but may be specified as any value from 1-10.)
+
+ Our software solution is to detect these problematic branches in a
+ linker pass and modify them as follows:
+ 1/ Unconditional branches - Since these are always predicted taken,
+ there is no problem and no action is required.
+ 2/ Conditional backward branches - No problem, no action required.
+ 3/ Conditional forward branches - Ensure that the "inverse prediction
+ bit" is set (ensure it is predicted taken).
+ 4/ Conditional register branches - Ensure that the "y bit" is set
+ (ensure it is predicted taken).
+*/
+
+/* Sort sections by address. */
+
+static int
+ppc_elf_sort_rela (arg1, arg2)
+ const void *arg1;
+ const void *arg2;
+{
+ const Elf_Internal_Rela **rela1 = (const Elf_Internal_Rela**) arg1;
+ const Elf_Internal_Rela **rela2 = (const Elf_Internal_Rela**) arg2;
+
+ /* Sort by offset. */
+ return ((*rela1)->r_offset - (*rela2)->r_offset);
+}
+
+static boolean
+ppc_elf_relax_section (abfd, isec, link_info, again)
+ bfd *abfd;
+ asection *isec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+#define PAGESIZE 0x1000
+
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela **rela_comb = NULL;
+ int comb_curr, comb_count;
+
+ /* We never have to do this more than once per input section. */
+ *again = false;
+
+ /* If needed, initialize this section's cooked size. */
+ if (isec->_cooked_size == 0)
+ isec->_cooked_size = isec->_raw_size;
+
+ /* We're only interested in text sections which overlap the
+ troublesome area at the end of a page. */
+ if (link_info->mpc860c0 && (isec->flags & SEC_CODE) && isec->_cooked_size)
+ {
+ bfd_vma dot, end_page, end_section;
+ boolean section_modified;
+
+ /* Get the section contents. */
+ /* Get cached copy if it exists. */
+ if (elf_section_data (isec)->this_hdr.contents != NULL)
+ contents = elf_section_data (isec)->this_hdr.contents;
+ else
+ {
+ /* Go get them off disk. */
+ contents = (bfd_byte *) bfd_malloc (isec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, isec, contents,
+ (file_ptr) 0, isec->_raw_size))
+ goto error_return;
+ }
+
+ comb_curr = 0;
+ comb_count = 0;
+ if (isec->reloc_count)
+ {
+ unsigned n;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = _bfd_elf32_link_read_relocs (
+ abfd, isec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ /* Setup a faster access method for the reloc info we need. */
+ rela_comb = (Elf_Internal_Rela**)
+ bfd_malloc (isec->reloc_count*sizeof(Elf_Internal_Rela*));
+ if (rela_comb == NULL)
+ goto error_return;
+ for (n=0; n<isec->reloc_count; ++n)
+ {
+ long r_type;
+
+ r_type = ELF32_R_TYPE (internal_relocs[n].r_info);
+ if (r_type < 0 || r_type >= (int)R_PPC_max)
+ goto error_return;
+
+ /* Prologue constants are sometimes present in the ".text"
+ sections and they can be identified by their associated relocation.
+ We don't want to process those words and some others which
+ can also be identified by their relocations. However, not all
+ conditional branches will have a relocation so we will
+ only ignore words that 1) have a reloc, and 2) the reloc
+ is not applicable to a conditional branch.
+ The array rela_comb is built here for use in the EOP scan loop. */
+ switch (r_type)
+ {
+ case R_PPC_ADDR14_BRNTAKEN: /* absolute, predicted not taken */
+ case R_PPC_REL14: /* relative cond. br. */
+ case R_PPC_REL14_BRNTAKEN: /* rel. cond. br., predicted not taken */
+ /* We should check the instruction. */
+ break;
+ default:
+ /* The word is not a conditional branch - ignore it. */
+ rela_comb[comb_count++] = &internal_relocs[n];
+ break;
+ }
+ }
+ if (comb_count > 1)
+ qsort (rela_comb, (size_t) comb_count, sizeof (int), ppc_elf_sort_rela);
+ }
+
+ /* Enumerate each EOP region that overlaps this section. */
+ end_section = isec->vma + isec->_cooked_size;
+ dot = end_page = (isec->vma | (PAGESIZE - 1)) + 1;
+ dot -= link_info->mpc860c0;
+ section_modified = false;
+ if (dot < isec->vma) /* Increment the start position if this section */
+ dot = isec->vma; /* begins in the middle of its first EOP region. */
+ for (;
+ dot < end_section;
+ dot += PAGESIZE, end_page += PAGESIZE)
+ {
+
+ /* Check each word in this EOP region. */
+ for (; dot < end_page; dot += 4)
+ {
+ bfd_vma isec_offset;
+ unsigned long insn;
+ boolean skip, modified;
+
+ /* Don't process this word if there is a relocation for it and
+ the relocation indicates the word is not a conditional branch. */
+ skip = false;
+ isec_offset = dot - isec->vma;
+ for (; comb_curr<comb_count; ++comb_curr)
+ {
+ bfd_vma r_offset;
+
+ r_offset = rela_comb[comb_curr]->r_offset;
+ if (r_offset >= isec_offset)
+ {
+ if (r_offset == isec_offset) skip = true;
+ break;
+ }
+ }
+ if (skip) continue;
+
+ /* Check the current word for a problematic conditional branch. */
+#define BO0(insn) ((insn) & 0x02000000)
+#define BO2(insn) ((insn) & 0x00800000)
+#define BO4(insn) ((insn) & 0x00200000)
+ insn = (unsigned long) bfd_get_32 (abfd, contents + isec_offset);
+ modified = false;
+ if ((insn & 0xFc000000) == 0x40000000)
+ {
+ /* Instruction is BCx */
+ if ((!BO0(insn) || !BO2(insn)) && !BO4(insn))
+ {
+ bfd_vma target;
+ /* This branch is predicted as "normal".
+ If this is a forward branch, it is problematic. */
+
+ target = insn & 0x0000Fffc; /*extract*/
+ target = (target ^ 0x8000) - 0x8000; /*sign extend*/
+ if ((insn & 0x00000002) == 0)
+ target += dot; /*convert to abs*/
+ if (target > dot)
+ {
+ insn |= 0x00200000; /* set the prediction bit */
+ modified = true;
+ }
+ }
+ }
+ else if ((insn & 0xFc00Fffe) == 0x4c000420)
+ {
+ /* Instruction is BCCTRx */
+ if ((!BO0(insn) || !BO2(insn)) && !BO4(insn))
+ {
+ /* This branch is predicted as not-taken.
+ If this is a forward branch, it is problematic.
+ Since we can't tell statically if it will branch forward,
+ always set the prediction bit. */
+ insn |= 0x00200000; /* set the prediction bit */
+ modified = true;
+ }
+ }
+ else if ((insn & 0xFc00Fffe) == 0x4c000020)
+ {
+ /* Instruction is BCLRx */
+ if ((!BO0(insn) || !BO2(insn)) && !BO4(insn))
+ {
+ /* This branch is predicted as not-taken.
+ If this is a forward branch, it is problematic.
+ Since we can't tell statically if it will branch forward,
+ always set the prediction bit. */
+ insn |= 0x00200000; /* set the prediction bit */
+ modified = true;
+ }
+ }
+#undef BO0
+#undef BO2
+#undef BO4
+ if (modified)
+ {
+ bfd_put_32 (abfd, insn, contents + isec_offset);
+ section_modified = true;
+ }
+ }
+ }
+ if (section_modified)
+ {
+ elf_section_data (isec)->this_hdr.contents = contents;
+ free_contents = NULL;
+ }
+ }
+
+ if (rela_comb != NULL)
+ {
+ free (rela_comb);
+ rela_comb = NULL;
+ }
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (isec)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+
+ return true;
+
+error_return:
+ if (rela_comb != NULL)
+ free (rela_comb);
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ return false;
+}
+
+
+static reloc_howto_type *
+ppc_elf_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ enum elf_ppc_reloc_type ppc_reloc = R_PPC_NONE;
+
+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
+ /* Initialize howto table if needed */
+ ppc_elf_howto_init ();
+
+ switch ((int)code)
+ {
+ default:
+ return (reloc_howto_type *)NULL;
+
+ case BFD_RELOC_NONE: ppc_reloc = R_PPC_NONE; break;
+ case BFD_RELOC_32: ppc_reloc = R_PPC_ADDR32; break;
+ case BFD_RELOC_PPC_BA26: ppc_reloc = R_PPC_ADDR24; break;
+ case BFD_RELOC_16: ppc_reloc = R_PPC_ADDR16; break;
+ case BFD_RELOC_LO16: ppc_reloc = R_PPC_ADDR16_LO; break;
+ case BFD_RELOC_HI16: ppc_reloc = R_PPC_ADDR16_HI; break;
+ case BFD_RELOC_HI16_S: ppc_reloc = R_PPC_ADDR16_HA; break;
+ case BFD_RELOC_PPC_BA16: ppc_reloc = R_PPC_ADDR14; break;
+ case BFD_RELOC_PPC_BA16_BRTAKEN: ppc_reloc = R_PPC_ADDR14_BRTAKEN; break;
+ case BFD_RELOC_PPC_BA16_BRNTAKEN: ppc_reloc = R_PPC_ADDR14_BRNTAKEN; break;
+ case BFD_RELOC_PPC_B26: ppc_reloc = R_PPC_REL24; break;
+ case BFD_RELOC_PPC_B16: ppc_reloc = R_PPC_REL14; break;
+ case BFD_RELOC_PPC_B16_BRTAKEN: ppc_reloc = R_PPC_REL14_BRTAKEN; break;
+ case BFD_RELOC_PPC_B16_BRNTAKEN: ppc_reloc = R_PPC_REL14_BRNTAKEN; break;
+ case BFD_RELOC_16_GOTOFF: ppc_reloc = R_PPC_GOT16; break;
+ case BFD_RELOC_LO16_GOTOFF: ppc_reloc = R_PPC_GOT16_LO; break;
+ case BFD_RELOC_HI16_GOTOFF: ppc_reloc = R_PPC_GOT16_HI; break;
+ case BFD_RELOC_HI16_S_GOTOFF: ppc_reloc = R_PPC_GOT16_HA; break;
+ case BFD_RELOC_24_PLT_PCREL: ppc_reloc = R_PPC_PLTREL24; break;
+ case BFD_RELOC_PPC_COPY: ppc_reloc = R_PPC_COPY; break;
+ case BFD_RELOC_PPC_GLOB_DAT: ppc_reloc = R_PPC_GLOB_DAT; break;
+ case BFD_RELOC_PPC_LOCAL24PC: ppc_reloc = R_PPC_LOCAL24PC; break;
+ case BFD_RELOC_32_PCREL: ppc_reloc = R_PPC_REL32; break;
+ case BFD_RELOC_32_PLTOFF: ppc_reloc = R_PPC_PLT32; break;
+ case BFD_RELOC_32_PLT_PCREL: ppc_reloc = R_PPC_PLTREL32; break;
+ case BFD_RELOC_LO16_PLTOFF: ppc_reloc = R_PPC_PLT16_LO; break;
+ case BFD_RELOC_HI16_PLTOFF: ppc_reloc = R_PPC_PLT16_HI; break;
+ case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC_PLT16_HA; break;
+ case BFD_RELOC_GPREL16: ppc_reloc = R_PPC_SDAREL16; break;
+ case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC_SECTOFF; break;
+ case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC_SECTOFF_LO; break;
+ case BFD_RELOC_HI16_BASEREL: ppc_reloc = R_PPC_SECTOFF_HI; break;
+ case BFD_RELOC_HI16_S_BASEREL: ppc_reloc = R_PPC_SECTOFF_HA; break;
+ case BFD_RELOC_CTOR: ppc_reloc = R_PPC_ADDR32; break;
+ case BFD_RELOC_PPC_TOC16: ppc_reloc = R_PPC_TOC16; break;
+ case BFD_RELOC_PPC_EMB_NADDR32: ppc_reloc = R_PPC_EMB_NADDR32; break;
+ case BFD_RELOC_PPC_EMB_NADDR16: ppc_reloc = R_PPC_EMB_NADDR16; break;
+ case BFD_RELOC_PPC_EMB_NADDR16_LO: ppc_reloc = R_PPC_EMB_NADDR16_LO; break;
+ case BFD_RELOC_PPC_EMB_NADDR16_HI: ppc_reloc = R_PPC_EMB_NADDR16_HI; break;
+ case BFD_RELOC_PPC_EMB_NADDR16_HA: ppc_reloc = R_PPC_EMB_NADDR16_HA; break;
+ case BFD_RELOC_PPC_EMB_SDAI16: ppc_reloc = R_PPC_EMB_SDAI16; break;
+ case BFD_RELOC_PPC_EMB_SDA2I16: ppc_reloc = R_PPC_EMB_SDA2I16; break;
+ case BFD_RELOC_PPC_EMB_SDA2REL: ppc_reloc = R_PPC_EMB_SDA2REL; break;
+ case BFD_RELOC_PPC_EMB_SDA21: ppc_reloc = R_PPC_EMB_SDA21; break;
+ case BFD_RELOC_PPC_EMB_MRKREF: ppc_reloc = R_PPC_EMB_MRKREF; break;
+ case BFD_RELOC_PPC_EMB_RELSEC16: ppc_reloc = R_PPC_EMB_RELSEC16; break;
+ case BFD_RELOC_PPC_EMB_RELST_LO: ppc_reloc = R_PPC_EMB_RELST_LO; break;
+ case BFD_RELOC_PPC_EMB_RELST_HI: ppc_reloc = R_PPC_EMB_RELST_HI; break;
+ case BFD_RELOC_PPC_EMB_RELST_HA: ppc_reloc = R_PPC_EMB_RELST_HA; break;
+ case BFD_RELOC_PPC_EMB_BIT_FLD: ppc_reloc = R_PPC_EMB_BIT_FLD; break;
+ case BFD_RELOC_PPC_EMB_RELSDA: ppc_reloc = R_PPC_EMB_RELSDA; break;
+ case BFD_RELOC_VTABLE_INHERIT: ppc_reloc = R_PPC_GNU_VTINHERIT; break;
+ case BFD_RELOC_VTABLE_ENTRY: ppc_reloc = R_PPC_GNU_VTENTRY; break;
+ }
+
+ return ppc_elf_howto_table[ (int)ppc_reloc ];
+};
+
+/* Set the howto pointer for a PowerPC ELF reloc. */
+
+static void
+ppc_elf_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */
+ ppc_elf_howto_init ();
+
+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
+ cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
+}
+
+/* Handle the R_PPC_ADDR16_HA reloc. */
+
+static bfd_reloc_status_type
+ppc_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+
+ if (output_bfd != NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ reloc_entry->addend += (relocation & 0x8000) << 1;
+
+ return bfd_reloc_continue;
+}
+
+/* Function to set whether a module needs the -mrelocatable bit set. */
+
+static boolean
+ppc_elf_set_private_flags (abfd, flags)
+ bfd *abfd;
+ flagword flags;
+{
+ BFD_ASSERT (!elf_flags_init (abfd)
+ || elf_elfheader (abfd)->e_flags == flags);
+
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ return true;
+}
+
+/* Copy backend specific data from one object module to another */
+static boolean
+ppc_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
+
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking */
+static boolean
+ppc_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ flagword old_flags;
+ flagword new_flags;
+ boolean error;
+
+ /* Check if we have the same endianess */
+ if (ibfd->xvec->byteorder != obfd->xvec->byteorder
+ && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ const char *msg;
+
+ if (bfd_big_endian (ibfd))
+ msg = _("%s: compiled for a big endian system and target is little endian");
+ else
+ msg = _("%s: compiled for a little endian system and target is big endian");
+
+ (*_bfd_error_handler) (msg, bfd_get_filename (ibfd));
+
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+ if (!elf_flags_init (obfd)) /* First call, no flags set */
+ {
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = new_flags;
+ }
+
+ else if (new_flags == old_flags) /* Compatible flags are ok */
+ ;
+
+ else /* Incompatible flags */
+ {
+ /* Warn about -mrelocatable mismatch. Allow -mrelocatable-lib to be linked
+ with either. */
+ error = false;
+ if ((new_flags & EF_PPC_RELOCATABLE) != 0
+ && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0)
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled with -mrelocatable and linked with modules compiled normally"),
+ bfd_get_filename (ibfd));
+ }
+ else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
+ && (old_flags & EF_PPC_RELOCATABLE) != 0)
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled normally and linked with modules compiled with -mrelocatable"),
+ bfd_get_filename (ibfd));
+ }
+
+ /* The output is -mrelocatable-lib iff both the input files are. */
+ if (! (new_flags & EF_PPC_RELOCATABLE_LIB))
+ elf_elfheader (obfd)->e_flags &= ~EF_PPC_RELOCATABLE_LIB;
+
+ /* The output is -mrelocatable iff it can't be -mrelocatable-lib,
+ but each input file is either -mrelocatable or -mrelocatable-lib. */
+ if (! (elf_elfheader (obfd)->e_flags & EF_PPC_RELOCATABLE_LIB)
+ && (new_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE))
+ && (old_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE)))
+ elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE;
+
+ /* Do not warn about eabi vs. V.4 mismatch, just or in the bit if any module uses it */
+ elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB);
+
+ new_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
+ old_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
+
+ /* Warn about any other mismatches */
+ if (new_flags != old_flags)
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
+ }
+
+ if (error)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+/* Handle a PowerPC specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type. */
+
+static boolean
+ppc_elf_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf32_Internal_Shdr *hdr;
+ char *name;
+{
+ asection *newsect;
+ flagword flags;
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+
+ newsect = hdr->bfd_section;
+ flags = bfd_get_section_flags (abfd, newsect);
+ if (hdr->sh_flags & SHF_EXCLUDE)
+ flags |= SEC_EXCLUDE;
+
+ if (hdr->sh_type == SHT_ORDERED)
+ flags |= SEC_SORT_ENTRIES;
+
+ bfd_set_section_flags (abfd, newsect, flags);
+ return true;
+}
+
+
+/* Set up any other section flags and such that may be necessary. */
+
+static boolean
+ppc_elf_fake_sections (abfd, shdr, asect)
+ bfd *abfd;
+ Elf32_Internal_Shdr *shdr;
+ asection *asect;
+{
+ if ((asect->flags & SEC_EXCLUDE) != 0)
+ shdr->sh_flags |= SHF_EXCLUDE;
+
+ if ((asect->flags & SEC_SORT_ENTRIES) != 0)
+ shdr->sh_type = SHT_ORDERED;
+
+ return true;
+}
+
+
+/* Create a special linker section */
+static elf_linker_section_t *
+ppc_elf_create_linker_section (abfd, info, which)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ enum elf_linker_section_enum which;
+{
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ elf_linker_section_t *lsect;
+
+ /* Record the first bfd section that needs the special section */
+ if (!dynobj)
+ dynobj = elf_hash_table (info)->dynobj = abfd;
+
+ /* If this is the first time, create the section */
+ lsect = elf_linker_section (dynobj, which);
+ if (!lsect)
+ {
+ elf_linker_section_t defaults;
+ static elf_linker_section_t zero_section;
+
+ defaults = zero_section;
+ defaults.which = which;
+ defaults.hole_written_p = false;
+ defaults.alignment = 2;
+
+ /* Both of these sections are (technically) created by the user
+ putting data in them, so they shouldn't be marked
+ SEC_LINKER_CREATED.
+
+ The linker creates them so it has somewhere to attach their
+ respective symbols. In fact, if they were empty it would
+ be OK to leave the symbol set to 0 (or any random number), because
+ the appropriate register should never be used. */
+ defaults.flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+
+ switch (which)
+ {
+ default:
+ (*_bfd_error_handler) (_("%s: Unknown special linker type %d"),
+ bfd_get_filename (abfd),
+ (int)which);
+
+ bfd_set_error (bfd_error_bad_value);
+ return (elf_linker_section_t *)0;
+
+ case LINKER_SECTION_SDATA: /* .sdata/.sbss section */
+ defaults.name = ".sdata";
+ defaults.rel_name = ".rela.sdata";
+ defaults.bss_name = ".sbss";
+ defaults.sym_name = "_SDA_BASE_";
+ defaults.sym_offset = 32768;
+ break;
+
+ case LINKER_SECTION_SDATA2: /* .sdata2/.sbss2 section */
+ defaults.name = ".sdata2";
+ defaults.rel_name = ".rela.sdata2";
+ defaults.bss_name = ".sbss2";
+ defaults.sym_name = "_SDA2_BASE_";
+ defaults.sym_offset = 32768;
+ defaults.flags |= SEC_READONLY;
+ break;
+ }
+
+ lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults);
+ }
+
+ return lsect;
+}
+
+
+/* If we have a non-zero sized .sbss2 or .PPC.EMB.sbss0 sections, we need to bump up
+ the number of section headers. */
+
+static int
+ppc_elf_additional_program_headers (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ int ret;
+
+ ret = 0;
+
+ s = bfd_get_section_by_name (abfd, ".interp");
+ if (s != NULL)
+ ++ret;
+
+ s = bfd_get_section_by_name (abfd, ".sbss2");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0)
+ ++ret;
+
+ s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0)
+ ++ret;
+
+ return ret;
+}
+
+/* Modify the segment map if needed */
+
+static boolean
+ppc_elf_modify_segment_map (abfd)
+ bfd *abfd;
+{
+ return true;
+}
+
+/* We have to create .dynsbss and .rela.sbss here so that they get mapped
+ to output sections (just like _bfd_elf_create_dynamic_sections has
+ to create .dynbss and .rela.bss). */
+
+static boolean
+ppc_elf_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ register asection *s;
+ flagword flags;
+
+ if (!_bfd_elf_create_dynamic_sections(abfd, info))
+ return false;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ s = bfd_make_section (abfd, ".dynsbss");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
+ return false;
+
+ if (! info->shared)
+ {
+ s = bfd_make_section (abfd, ".rela.sbss");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+ }
+ return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+ppc_elf_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ asection *s;
+ unsigned int power_of_two;
+ bfd_vma plt_offset;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called for %s\n", h->root.root.string);
+#endif
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later,
+ when we know the address of the .got section. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || ((!info->shared || info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0)
+ || (info->shared && h->plt.refcount <= 0))
+ {
+ /* A PLT entry is not required/allowed when:
+
+ 1. We are not using ld.so; because then the PLT entry
+ can't be set up, so we can't use one.
+
+ 2. We know for certain that a symbol is defined in
+ this object, because this object is the application,
+ is linked with -Bsymbolic, or because the symbol is local.
+
+ 3. GC has rendered the entry unused.
+ Note, however, that in an executable all references to the
+ symbol go to the PLT, so we can't turn it off in that case.
+ ??? The correct thing to do here is to reference count
+ all uses of the symbol, not just those to the GOT or PLT. */
+ h->plt.offset = (bfd_vma) -1;
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+ return true;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->_raw_size == 0)
+ s->_raw_size += PLT_INITIAL_ENTRY_SIZE;
+
+ /* The PowerPC PLT is actually composed of two parts, the first part
+ is 2 words (for a load and a jump), and then there is a remaining
+ word available at the end. */
+ plt_offset = (PLT_INITIAL_ENTRY_SIZE
+ + (PLT_SLOT_SIZE
+ * ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE)
+ / PLT_ENTRY_SIZE)));
+
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = plt_offset;
+ }
+
+ h->plt.offset = plt_offset;
+
+ /* Make room for this entry. After the 8192nd entry, room
+ for two entries is allocated. */
+ if ((s->_raw_size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
+ >= PLT_NUM_SINGLE_ENTRIES)
+ s->_raw_size += 2 * PLT_ENTRY_SIZE;
+ else
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += sizeof (Elf32_External_Rela);
+
+ return true;
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (info->shared)
+ return true;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable.
+
+ Of course, if the symbol is sufficiently small, we must instead
+ allocate it in .sbss. FIXME: It would be better to do this if and
+ only if there were actually SDAREL relocs for that symbol. */
+
+ if (h->size <= elf_gp_size (dynobj))
+ s = bfd_get_section_by_name (dynobj, ".dynsbss");
+ else
+ s = bfd_get_section_by_name (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_PPC_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. We need to remember the offset into the
+ .rela.bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ asection *srel;
+
+ if (h->size <= elf_gp_size (dynobj))
+ srel = bfd_get_section_by_name (dynobj, ".rela.sbss");
+ else
+ srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf32_External_Rela);
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ }
+
+ /* We need to figure out the alignment required for this symbol. I
+ have no idea how ELF linkers handle this. */
+ power_of_two = bfd_log2 (h->size);
+ if (power_of_two > 4)
+ power_of_two = 4;
+
+ /* Apply the required alignment. */
+ s->_raw_size = BFD_ALIGN (s->_raw_size,
+ (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ {
+ if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+ return false;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->_raw_size += h->size;
+
+ return true;
+}
+
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+
+static boolean
+ppc_elf_adjust_dynindx (h, cparg)
+ struct elf_link_hash_entry *h;
+ PTR cparg;
+{
+ int *cp = (int *) cparg;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n", h->dynindx, *cp);
+#endif
+
+ if (h->dynindx != -1)
+ h->dynindx += *cp;
+
+ return true;
+}
+
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+ppc_elf_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean plt;
+ boolean relocs;
+ boolean reltext;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
+#endif
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (! info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+ else
+ {
+ /* We may have created entries in the .rela.got, .rela.sdata, and
+ .rela.sdata2 sections. However, if we are not creating the
+ dynamic sections, we will not actually use these entries. Reset
+ the size of .rela.got, et al, which will cause it to get
+ stripped from the output file below. */
+ static char *rela_sections[] = { ".rela.got", ".rela.sdata",
+ ".rela.sdata2", ".rela.sbss",
+ (char *)0 };
+ char **p;
+
+ for (p = rela_sections; *p != (char *)0; p++)
+ {
+ s = bfd_get_section_by_name (dynobj, *p);
+ if (s != NULL)
+ s->_raw_size = 0;
+ }
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ plt = false;
+ relocs = false;
+ reltext = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ strip = false;
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ strip = true;
+ }
+ else
+ {
+ /* Remember whether there is a PLT. */
+ plt = true;
+ }
+ }
+ else if (strncmp (name, ".rela", 5) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rela.bss and
+ .rela.plt. We must create both sections in
+ create_dynamic_sections, because they must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ strip = true;
+ }
+ else
+ {
+ asection *target;
+ const char *outname;
+
+ /* Remember whether there are any relocation sections. */
+ relocs = true;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL entry. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 5);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ reltext = true;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strcmp (name, ".got") != 0
+ && strcmp (name, ".sdata") != 0
+ && strcmp (name, ".sdata2") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ _bfd_strip_section_from_output (s);
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in ppc_elf_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (! info->shared)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (plt)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ return false;
+ }
+
+ if (relocs)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return false;
+ }
+
+ if (reltext)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ /* If we are generating a shared library, we generate a section
+ symbol for each output section. These are local symbols, which
+ means that they must come first in the dynamic symbol table.
+ That means we must increment the dynamic symbol index of every
+ other dynamic symbol.
+
+ FIXME: We assume that there will never be relocations to
+ locations in linker-created sections that do not have
+ externally-visible names. Instead, we should work out precisely
+ which sections relocations are targetted at. */
+ if (info->shared)
+ {
+ int c;
+
+ for (c = 0, s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) != 0
+ || (s->flags & SEC_ALLOC) == 0)
+ {
+ elf_section_data (s)->dynindx = -1;
+ continue;
+ }
+
+ /* These symbols will have no names, so we don't need to
+ fiddle with dynstr_index. */
+
+ elf_section_data (s)->dynindx = c + 1;
+
+ c++;
+ }
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ ppc_elf_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+ }
+
+ return true;
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static boolean
+ppc_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd_signed_vma *local_got_refcounts;
+ elf_linker_section_t *sdata;
+ elf_linker_section_t *sdata2;
+ asection *sreloc;
+ asection *sgot = NULL;
+ asection *srelgot = NULL;
+
+ if (info->relocateable)
+ return true;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_check_relocs called for section %s in %s\n",
+ bfd_get_section_name (abfd, sec),
+ bfd_get_filename (abfd));
+#endif
+
+ /* Create the linker generated sections all the time so that the
+ special symbols are created. */
+
+ if ((sdata = elf_linker_section (abfd, LINKER_SECTION_SDATA)) == NULL)
+ {
+ sdata = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA);
+ if (!sdata)
+ return false;
+ }
+
+
+ if ((sdata2 = elf_linker_section (abfd, LINKER_SECTION_SDATA2)) == NULL)
+ {
+ sdata2 = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA2);
+ if (!sdata2)
+ return false;
+ }
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
+ This shows up in particular in an R_PPC_ADDR32 in the eabi
+ startup code. */
+ if (h && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ if (sgot == NULL)
+ {
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return false;
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* GOT16 relocations */
+ case R_PPC_GOT16:
+ case R_PPC_GOT16_LO:
+ case R_PPC_GOT16_HI:
+ case R_PPC_GOT16_HA:
+ /* This symbol requires a global offset table entry. */
+
+ if (sgot == NULL)
+ {
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return false;
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rela.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.refcount == -1)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ if (!bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+
+ /* Allocate space in the .got. */
+ sgot->_raw_size += 4;
+ /* Allocate relocation space. */
+ srelgot->_raw_size += sizeof (Elf32_External_Rela);
+
+ h->got.refcount = 1;
+ }
+ else
+ h->got.refcount++;
+ }
+ else
+ {
+ /* This is a global offset table entry for a local symbol. */
+ if (local_got_refcounts == NULL)
+ {
+ size_t size;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_signed_vma);
+ local_got_refcounts = (bfd_signed_vma *)
+ bfd_alloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return false;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ memset (local_got_refcounts, -1, size);
+ }
+ if (local_got_refcounts[r_symndx] == -1)
+ {
+ sgot->_raw_size += 4;
+
+ /* If we are generating a shared object, we need to
+ output a R_PPC_RELATIVE reloc so that the
+ dynamic linker can adjust this GOT entry. */
+ if (info->shared)
+ srelgot->_raw_size += sizeof (Elf32_External_Rela);
+
+ local_got_refcounts[r_symndx] = 1;
+ }
+ else
+ local_got_refcounts[r_symndx]++;
+ }
+ break;
+
+ /* Indirect .sdata relocation */
+ case R_PPC_EMB_SDAI16:
+ if (info->shared)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: relocation %s cannot be used when making a shared object"),
+ bfd_get_filename (abfd), "R_PPC_EMB_SDAI16"));
+ return false;
+ }
+
+ if (srelgot == NULL && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rela.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata, h, rel))
+ return false;
+
+ break;
+
+ /* Indirect .sdata2 relocation */
+ case R_PPC_EMB_SDA2I16:
+ if (info->shared)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: relocation %s cannot be used when making a shared object"),
+ bfd_get_filename (abfd), "R_PPC_EMB_SDA2I16"));
+ return false;
+ }
+
+ if (srelgot == NULL && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rela.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata2, h, rel))
+ return false;
+
+ break;
+
+ case R_PPC_SDAREL16:
+ case R_PPC_EMB_SDA2REL:
+ case R_PPC_EMB_SDA21:
+ if (info->shared)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: relocation %s cannot be used when making a shared object"),
+ bfd_get_filename (abfd),
+ ppc_elf_howto_table[(int)ELF32_R_TYPE (rel->r_info)]->name));
+ return false;
+ }
+ break;
+
+ case R_PPC_PLT32:
+ case R_PPC_PLTREL24:
+ case R_PPC_PLT16_LO:
+ case R_PPC_PLT16_HI:
+ case R_PPC_PLT16_HA:
+#ifdef DEBUG
+ fprintf (stderr, "Reloc requires a PLT entry\n");
+#endif
+ /* This symbol requires a procedure linkage table entry. We
+ actually build the entry in adjust_dynamic_symbol,
+ because this might be a case of linking PIC code without
+ linking in any dynamic objects, in which case we don't
+ need to generate a procedure linkage table after all. */
+
+ if (h == NULL)
+ {
+ /* It does not make sense to have a procedure linkage
+ table entry for a local symbol. */
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+ if (h->plt.refcount == -1)
+ {
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.refcount = 1;
+ }
+ else
+ h->plt.refcount++;
+ break;
+
+ /* The following relocations don't need to propagate the
+ relocation if linking a shared object since they are
+ section relative. */
+ case R_PPC_SECTOFF:
+ case R_PPC_SECTOFF_LO:
+ case R_PPC_SECTOFF_HI:
+ case R_PPC_SECTOFF_HA:
+ break;
+
+ /* This refers only to functions defined in the shared library */
+ case R_PPC_LOCAL24PC:
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_PPC_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_PPC_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+
+ /* When creating a shared object, we must copy these
+ relocs into the output file. We create a reloc
+ section in dynobj and make room for the reloc. */
+ case R_PPC_REL24:
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ case R_PPC_REL32:
+ if (h == NULL
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* fall through */
+
+ default:
+ if (info->shared)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_check_relocs need to create relocation for %s\n",
+ (h && h->root.root.string) ? h->root.root.string : "<unknown>");
+#endif
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ flagword flags;
+
+ sreloc = bfd_make_section (dynobj, name);
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc, flags)
+ || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+ return false;
+ }
+ }
+
+ sreloc->_raw_size += sizeof (Elf32_External_Rela);
+
+ /* FIXME: We should here do what the m68k and i386
+ backends do: if the reloc is pc-relative, record it
+ in case it turns out that the reloc is unnecessary
+ because the symbol is forced local by versioning or
+ we are linking with -Bdynamic. Fortunately this
+ case is not frequent. */
+ }
+
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+ppc_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_PPC_GNU_VTINHERIT:
+ case R_PPC_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static boolean
+ppc_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_PPC_GOT16:
+ case R_PPC_GOT16_LO:
+ case R_PPC_GOT16_HI:
+ case R_PPC_GOT16_HA:
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ case R_PPC_PLT32:
+ case R_PPC_PLTREL24:
+ case R_PPC_PLT16_LO:
+ case R_PPC_PLT16_HI:
+ case R_PPC_PLT16_HA:
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (h->plt.refcount > 0)
+ h->plt.refcount--;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it to put .comm items in .sbss, and not .bss. */
+
+/*ARGSUSED*/
+static boolean
+ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocateable
+ && sym->st_size <= (bfd_vma) bfd_get_gp_size (abfd))
+ {
+ /* Common symbols less than or equal to -G nn bytes are automatically
+ put into .sdata. */
+ elf_linker_section_t *sdata
+ = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA);
+
+ if (!sdata->bss_section)
+ {
+ /* We don't go through bfd_make_section, because we don't
+ want to attach this common section to DYNOBJ. The linker
+ will move the symbols to the appropriate output section
+ when it defines common symbols. */
+ sdata->bss_section = ((asection *)
+ bfd_zalloc (abfd, sizeof (asection)));
+ if (sdata->bss_section == NULL)
+ return false;
+ sdata->bss_section->name = sdata->bss_name;
+ sdata->bss_section->flags = SEC_IS_COMMON;
+ sdata->bss_section->output_section = sdata->bss_section;
+ sdata->bss_section->symbol =
+ (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ sdata->bss_section->symbol_ptr_ptr =
+ (asymbol **) bfd_zalloc (abfd, sizeof (asymbol *));
+ if (sdata->bss_section->symbol == NULL
+ || sdata->bss_section->symbol_ptr_ptr == NULL)
+ return false;
+ sdata->bss_section->symbol->name = sdata->bss_name;
+ sdata->bss_section->symbol->flags = BSF_SECTION_SYM;
+ sdata->bss_section->symbol->section = sdata->bss_section;
+ *sdata->bss_section->symbol_ptr_ptr = sdata->bss_section->symbol;
+ }
+
+ *secp = sdata->bss_section;
+ *valp = sym->st_size;
+ }
+
+ return true;
+}
+
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s",
+ h->root.root.string);
+#endif
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ Elf_Internal_Rela rela;
+ bfd_vma reloc_index;
+
+#ifdef DEBUG
+ fprintf (stderr, ", plt_offset = %d", h->plt.offset);
+#endif
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (splt != NULL && srela != NULL);
+
+ /* We don't need to fill in the .plt. The ppc dynamic linker
+ will fill it in. */
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
+ rela.r_addend = 0;
+
+ reloc_index = (h->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_SLOT_SIZE;
+ if (reloc_index > PLT_NUM_SINGLE_ENTRIES)
+ reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) srela->contents
+ + reloc_index));
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srela = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ 1));
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. The entry in
+ the global offset table will already have been initialized in
+ the relocate_section function. */
+ if (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ {
+ rela.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ BFD_ASSERT((h->got.offset & 1) == 0);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) srela->contents
+ + srela->reloc_count));
+ ++srela->reloc_count;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+#ifdef DEBUG
+ fprintf (stderr, ", copy");
+#endif
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ if (h->size <= elf_gp_size (dynobj))
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rela.sbss");
+ else
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rela.bss");
+ BFD_ASSERT (s != NULL);
+
+ rela.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) s->contents
+ + s->reloc_count));
+ ++s->reloc_count;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\n");
+#endif
+
+ /* Mark some specially defined symbols as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
+ || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+
+/* Finish up the dynamic sections. */
+
+static boolean
+ppc_elf_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ asection *sdyn;
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ asection *sgot = bfd_get_section_by_name (dynobj, ".got");
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
+#endif
+
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ boolean size;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT: name = ".plt"; size = false; break;
+ case DT_PLTRELSZ: name = ".rela.plt"; size = true; break;
+ case DT_JMPREL: name = ".rela.plt"; size = false; break;
+ default: name = NULL; size = false; break;
+ }
+
+ if (name != NULL)
+ {
+ asection *s;
+
+ s = bfd_get_section_by_name (output_bfd, name);
+ if (s == NULL)
+ dyn.d_un.d_val = 0;
+ else
+ {
+ if (! size)
+ dyn.d_un.d_ptr = s->vma;
+ else
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
+ else
+ dyn.d_un.d_val = s->_raw_size;
+ }
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ }
+
+ /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4 so that a function can
+ easily find the address of the _GLOBAL_OFFSET_TABLE_. */
+ if (sgot)
+ {
+ unsigned char *contents = sgot->contents;
+ bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, contents);
+
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ contents+4);
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+ }
+
+ if (info->shared)
+ {
+ asection *sdynsym;
+ asection *s;
+ Elf_Internal_Sym sym;
+ int maxdindx = 0;
+
+ /* Set up the section symbols for the output sections. */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (sdynsym != NULL);
+
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx, dindx;
+
+ sym.st_value = s->vma;
+
+ indx = elf_section_data (s)->this_idx;
+ dindx = elf_section_data (s)->dynindx;
+ if (dindx != -1)
+ {
+ BFD_ASSERT(indx > 0);
+ BFD_ASSERT(dindx > 0);
+
+ if (dindx > maxdindx)
+ maxdindx = dindx;
+
+ sym.st_shndx = indx;
+
+ bfd_elf32_swap_symbol_out (output_bfd, &sym,
+ (PTR) (((Elf32_External_Sym *)
+ sdynsym->contents)
+ + dindx));
+ }
+ }
+
+ /* Set the sh_info field of the output .dynsym section to the
+ index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
+ maxdindx + 1;
+ }
+
+ return true;
+}
+
+
+/* The RELOCATE_SECTION function is called by the ELF backend linker
+ to handle the relocations for a section.
+
+ The relocs are always passed as Rela structures; if the section
+ actually uses Rel structures, the r_addend field will always be
+ zero.
+
+ This function is responsible for adjust the section contents as
+ necessary, and (if using Rela relocs and generating a
+ relocateable output file) adjusting the reloc addend as
+ necessary.
+
+ This function does not have to worry about setting the reloc
+ address or the reloc symbol index.
+
+ LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+ LOCAL_SECTIONS is an array giving the section in the input file
+ corresponding to the st_shndx field of each local symbol.
+
+ The global hash table entry for the global symbols can be found
+ via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, this function must handle
+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
+ going to be the section symbol corresponding to the output
+ section, which means that the addend must be adjusted
+ accordingly. */
+
+static boolean
+ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ elf_linker_section_t *sdata = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA) : NULL;
+ elf_linker_section_t *sdata2 = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA2) : NULL;
+ Elf_Internal_Rela *rel = relocs;
+ Elf_Internal_Rela *relend = relocs + input_section->reloc_count;
+ asection *sreloc = NULL;
+ asection *splt;
+ asection *sgot;
+ bfd_vma *local_got_offsets;
+ boolean ret = true;
+ long insn;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n",
+ bfd_get_filename (input_bfd),
+ bfd_section_name(input_bfd, input_section),
+ (long)input_section->reloc_count,
+ (info->relocateable) ? " (relocatable)" : "");
+#endif
+
+ if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */
+ ppc_elf_howto_init ();
+
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ splt = sgot = NULL;
+ if (dynobj != NULL)
+ {
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ }
+
+ for (; rel < relend; rel++)
+ {
+ enum elf_ppc_reloc_type r_type = (enum elf_ppc_reloc_type)ELF32_R_TYPE (rel->r_info);
+ bfd_vma offset = rel->r_offset;
+ bfd_vma addend = rel->r_addend;
+ bfd_reloc_status_type r = bfd_reloc_other;
+ Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0;
+ asection *sec = (asection *)0;
+ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0;
+ const char *sym_name = (const char *)0;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ bfd_vma relocation;
+
+ /* Unknown relocation handling */
+ if ((unsigned)r_type >= (unsigned)R_PPC_max || !ppc_elf_howto_table[(int)r_type])
+ {
+ (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
+ bfd_get_filename (input_bfd),
+ (int)r_type);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+ }
+
+ howto = ppc_elf_howto_table[(int)r_type];
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ addend = rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
+ howto->name,
+ (int)r_type,
+ r_symndx,
+ (long)offset,
+ (long)addend);
+#endif
+ continue;
+ }
+
+ /* This is a final link. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = "<local symbol>";
+
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ sym_name = h->root.root.string;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if ((r_type == R_PPC_PLT32
+ && h->plt.offset != (bfd_vma) -1)
+ || (r_type == R_PPC_LOCAL24PC
+ && sec->output_section == NULL)
+ || ((r_type == R_PPC_GOT16
+ || r_type == R_PPC_GOT16_LO
+ || r_type == R_PPC_GOT16_HI
+ || r_type == R_PPC_GOT16_HA)
+ && elf_hash_table (info)->dynamic_sections_created
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type == R_PPC_ADDR32
+ || r_type == R_PPC_ADDR24
+ || r_type == R_PPC_ADDR16
+ || r_type == R_PPC_ADDR16_LO
+ || r_type == R_PPC_ADDR16_HI
+ || r_type == R_PPC_ADDR16_HA
+ || r_type == R_PPC_ADDR14
+ || r_type == R_PPC_ADDR14_BRTAKEN
+ || r_type == R_PPC_ADDR14_BRNTAKEN
+ || r_type == R_PPC_PLTREL24
+ || r_type == R_PPC_COPY
+ || r_type == R_PPC_GLOB_DAT
+ || r_type == R_PPC_JMP_SLOT
+ || r_type == R_PPC_UADDR32
+ || r_type == R_PPC_UADDR16
+ || r_type == R_PPC_SDAREL16
+ || r_type == R_PPC_EMB_NADDR32
+ || r_type == R_PPC_EMB_NADDR16
+ || r_type == R_PPC_EMB_NADDR16_LO
+ || r_type == R_PPC_EMB_NADDR16_HI
+ || r_type == R_PPC_EMB_NADDR16_HA
+ || r_type == R_PPC_EMB_SDAI16
+ || r_type == R_PPC_EMB_SDA2I16
+ || r_type == R_PPC_EMB_SDA2REL
+ || r_type == R_PPC_EMB_SDA21
+ || r_type == R_PPC_EMB_MRKREF
+ || r_type == R_PPC_EMB_BIT_FLD
+ || r_type == R_PPC_EMB_RELSDA
+ || ((r_type == R_PPC_REL24
+ || r_type == R_PPC_REL32
+ || r_type == R_PPC_REL14
+ || r_type == R_PPC_REL14_BRTAKEN
+ || r_type == R_PPC_REL14_BRNTAKEN
+ || r_type == R_PPC_RELATIVE)
+ && strcmp (h->root.root.string,
+ "_GLOBAL_OFFSET_TABLE_") != 0))))
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ relocation = 0;
+ }
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else
+ {
+ (*info->callbacks->undefined_symbol)(info,
+ h->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset);
+ ret = false;
+ continue;
+ }
+ }
+
+ switch ((int)r_type)
+ {
+ default:
+ (*_bfd_error_handler) (_("%s: unknown relocation type %d for symbol %s"),
+ bfd_get_filename (input_bfd),
+ (int)r_type, sym_name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+
+ /* Relocations that need no special processing. */
+ case (int)R_PPC_LOCAL24PC:
+ /* It makes no sense to point a local relocation
+ at a symbol not in this object. */
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && sec->output_section == NULL)
+ {
+ (*info->callbacks->undefined_symbol) (info,
+ h->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset);
+ ret = false;
+ continue;
+ }
+ break;
+
+ /* Relocations that may need to be propagated if this is a shared
+ object. */
+ case (int)R_PPC_REL24:
+ case (int)R_PPC_REL32:
+ case (int)R_PPC_REL14:
+ /* If these relocations are not to a named symbol, they can be
+ handled right here, no need to bother the dynamic linker. */
+ if (h == NULL
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* fall through */
+
+ /* Relocations that always need to be propagated if this is a shared
+ object. */
+ case (int)R_PPC_NONE:
+ case (int)R_PPC_ADDR32:
+ case (int)R_PPC_ADDR24:
+ case (int)R_PPC_ADDR16:
+ case (int)R_PPC_ADDR16_LO:
+ case (int)R_PPC_ADDR16_HI:
+ case (int)R_PPC_ADDR16_HA:
+ case (int)R_PPC_ADDR14:
+ case (int)R_PPC_UADDR32:
+ case (int)R_PPC_UADDR16:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ boolean skip;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_relocate_section need to create relocation for %s\n",
+ (h && h->root.root.string) ? h->root.root.string : "<unknown>");
+#endif
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ else if (h != NULL
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_PPC_ADDR32)
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ if (h == NULL)
+ sec = local_sections[r_symndx];
+ else
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || (h->root.type
+ == bfd_link_hash_defweak));
+ sec = h->root.u.def.section;
+ }
+ if (sec != NULL && bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ BFD_ASSERT(indx > 0);
+#ifdef DEBUG
+ if (indx <= 0)
+ {
+ printf("indx=%d section=%s flags=%08x name=%s\n",
+ indx, osec->name, osec->flags,
+ h->root.root.string);
+ }
+#endif
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, unless this is a RELATIVE
+ reloc in an unallocated section. */
+ if (skip
+ || (input_section->flags & SEC_ALLOC) != 0
+ || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE)
+ continue;
+ }
+
+ /* Arithmetic adjust relocations that aren't going into a
+ shared object. */
+ if (r_type == R_PPC_ADDR16_HA
+ /* It's just possible that this symbol is a weak symbol
+ that's not actually defined anywhere. In that case,
+ 'sec' would be NULL, and we should leave the symbol
+ alone (it will be set to zero elsewhere in the link). */
+ && sec != NULL)
+ {
+ addend += ((relocation + addend) & 0x8000) << 1;
+ }
+ break;
+
+ /* branch taken prediction relocations */
+ case (int)R_PPC_ADDR14_BRTAKEN:
+ case (int)R_PPC_REL14_BRTAKEN:
+ insn = bfd_get_32 (output_bfd, contents + offset);
+ if ((relocation - offset) & 0x8000)
+ insn &= ~BRANCH_PREDICT_BIT;
+ else
+ insn |= BRANCH_PREDICT_BIT;
+ bfd_put_32 (output_bfd, insn, contents + offset);
+ break;
+
+ /* branch not taken predicition relocations */
+ case (int)R_PPC_ADDR14_BRNTAKEN:
+ case (int)R_PPC_REL14_BRNTAKEN:
+ insn = bfd_get_32 (output_bfd, contents + offset);
+ if ((relocation - offset) & 0x8000)
+ insn |= BRANCH_PREDICT_BIT;
+ else
+ insn &= ~BRANCH_PREDICT_BIT;
+ bfd_put_32 (output_bfd, insn, contents + offset);
+ break;
+
+ /* GOT16 relocations */
+ case (int)R_PPC_GOT16:
+ case (int)R_PPC_GOT16_LO:
+ case (int)R_PPC_GOT16_HI:
+ case (int)R_PPC_GOT16_HA:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ BFD_ASSERT (sgot != NULL);
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined
+ locally. We must initialize this entry in the
+ global offset table. Since the offset must
+ always be a multiple of 4, we use the least
+ significant bit to record whether we have
+ initialized it already.
+
+ When doing a dynamic link, we create a .rela.got
+ relocation entry to initialize the value. This
+ is done in the finish_dynamic_symbol routine. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation,
+ sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off - 4;
+ }
+ else
+ {
+ bfd_vma off;
+
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use
+ the least significant bit to record whether we have
+ already processed this entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_PPC_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
+ outrel.r_addend = relocation;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ relocation = sgot->output_offset + off - 4;
+ }
+ break;
+
+ /* Indirect .sdata relocation */
+ case (int)R_PPC_EMB_SDAI16:
+ BFD_ASSERT (sdata != NULL);
+ relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info,
+ sdata, h, relocation, rel,
+ R_PPC_RELATIVE);
+ break;
+
+ /* Indirect .sdata2 relocation */
+ case (int)R_PPC_EMB_SDA2I16:
+ BFD_ASSERT (sdata2 != NULL);
+ relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info,
+ sdata2, h, relocation, rel,
+ R_PPC_RELATIVE);
+ break;
+
+ /* Handle the TOC16 reloc. We want to use the offset within the .got
+ section, not the actual VMA. This is appropriate when generating
+ an embedded ELF object, for which the .got section acts like the
+ AIX .toc section. */
+ case (int)R_PPC_TOC16: /* phony GOT16 relocations */
+ BFD_ASSERT (sec != (asection *)0);
+ BFD_ASSERT (bfd_is_und_section (sec)
+ || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
+ || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0)
+
+ addend -= sec->output_section->vma + sec->output_offset + 0x8000;
+ break;
+
+ case (int)R_PPC_PLTREL24:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+ BFD_ASSERT (h != NULL);
+
+ if (h->plt.offset == (bfd_vma) -1
+ || splt == NULL)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ break;
+
+ /* relocate against _SDA_BASE_ */
+ case (int)R_PPC_SDAREL16:
+ {
+ const char *name;
+
+ BFD_ASSERT (sec != (asection *)0);
+ name = bfd_get_section_name (abfd, sec->output_section);
+ if (strcmp (name, ".sdata") != 0
+ && strcmp (name, ".sbss") != 0)
+ {
+ (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
+ bfd_get_filename (input_bfd),
+ sym_name,
+ ppc_elf_howto_table[ (int)r_type ]->name,
+ name);
+ }
+ addend -= (sdata->sym_hash->root.u.def.value
+ + sdata->sym_hash->root.u.def.section->output_section->vma
+ + sdata->sym_hash->root.u.def.section->output_offset);
+ }
+ break;
+
+
+ /* relocate against _SDA2_BASE_ */
+ case (int)R_PPC_EMB_SDA2REL:
+ {
+ const char *name;
+
+ BFD_ASSERT (sec != (asection *)0);
+ name = bfd_get_section_name (abfd, sec->output_section);
+ if (strcmp (name, ".sdata2") != 0 && strcmp (name, ".sbss2") != 0)
+ {
+ (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
+ bfd_get_filename (input_bfd),
+ sym_name,
+ ppc_elf_howto_table[ (int)r_type ]->name,
+ name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+ }
+ addend -= (sdata2->sym_hash->root.u.def.value
+ + sdata2->sym_hash->root.u.def.section->output_section->vma
+ + sdata2->sym_hash->root.u.def.section->output_offset);
+ }
+ break;
+
+
+ /* relocate against either _SDA_BASE_, _SDA2_BASE_, or 0 */
+ case (int)R_PPC_EMB_SDA21:
+ case (int)R_PPC_EMB_RELSDA:
+ {
+ const char *name;
+ int reg;
+
+ BFD_ASSERT (sec != (asection *)0);
+ name = bfd_get_section_name (abfd, sec->output_section);
+ if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0)
+ {
+ reg = 13;
+ addend -= (sdata->sym_hash->root.u.def.value
+ + sdata->sym_hash->root.u.def.section->output_section->vma
+ + sdata->sym_hash->root.u.def.section->output_offset);
+ }
+
+ else if (strcmp (name, ".sdata2") == 0 || strcmp (name, ".sbss2") == 0)
+ {
+ reg = 2;
+ addend -= (sdata2->sym_hash->root.u.def.value
+ + sdata2->sym_hash->root.u.def.section->output_section->vma
+ + sdata2->sym_hash->root.u.def.section->output_offset);
+ }
+
+ else if (strcmp (name, ".PPC.EMB.sdata0") == 0 || strcmp (name, ".PPC.EMB.sbss0") == 0)
+ {
+ reg = 0;
+ }
+
+ else
+ {
+ (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
+ bfd_get_filename (input_bfd),
+ sym_name,
+ ppc_elf_howto_table[ (int)r_type ]->name,
+ name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = false;
+ continue;
+ }
+
+ if (r_type == R_PPC_EMB_SDA21)
+ { /* fill in register field */
+ insn = bfd_get_32 (output_bfd, contents + offset);
+ insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
+ bfd_put_32 (output_bfd, insn, contents + offset);
+ }
+ }
+ break;
+
+ /* Relocate against the beginning of the section */
+ case (int)R_PPC_SECTOFF:
+ case (int)R_PPC_SECTOFF_LO:
+ case (int)R_PPC_SECTOFF_HI:
+ BFD_ASSERT (sec != (asection *)0);
+ addend -= sec->output_section->vma;
+ break;
+
+ case (int)R_PPC_SECTOFF_HA:
+ BFD_ASSERT (sec != (asection *)0);
+ addend -= sec->output_section->vma;
+ addend += ((relocation + addend) & 0x8000) << 1;
+ break;
+
+ /* Negative relocations */
+ case (int)R_PPC_EMB_NADDR32:
+ case (int)R_PPC_EMB_NADDR16:
+ case (int)R_PPC_EMB_NADDR16_LO:
+ case (int)R_PPC_EMB_NADDR16_HI:
+ addend -= 2*relocation;
+ break;
+
+ case (int)R_PPC_EMB_NADDR16_HA:
+ addend -= 2*relocation;
+ addend += ((relocation + addend) & 0x8000) << 1;
+ break;
+
+ /* NOP relocation that prevents garbage collecting linkers from omitting a
+ reference. */
+ case (int)R_PPC_EMB_MRKREF:
+ continue;
+
+ case (int)R_PPC_COPY:
+ case (int)R_PPC_GLOB_DAT:
+ case (int)R_PPC_JMP_SLOT:
+ case (int)R_PPC_RELATIVE:
+ case (int)R_PPC_PLT32:
+ case (int)R_PPC_PLTREL32:
+ case (int)R_PPC_PLT16_LO:
+ case (int)R_PPC_PLT16_HI:
+ case (int)R_PPC_PLT16_HA:
+ case (int)R_PPC_EMB_RELSEC16:
+ case (int)R_PPC_EMB_RELST_LO:
+ case (int)R_PPC_EMB_RELST_HI:
+ case (int)R_PPC_EMB_RELST_HA:
+ case (int)R_PPC_EMB_BIT_FLD:
+ (*_bfd_error_handler) (_("%s: Relocation %s is not yet supported for symbol %s."),
+ bfd_get_filename (input_bfd),
+ ppc_elf_howto_table[ (int)r_type ]->name,
+ sym_name);
+
+ bfd_set_error (bfd_error_invalid_operation);
+ ret = false;
+ continue;
+
+ case (int)R_PPC_GNU_VTINHERIT:
+ case (int)R_PPC_GNU_VTENTRY:
+ /* These are no-ops in the end. */
+ continue;
+ }
+
+
+#ifdef DEBUG
+ fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n",
+ howto->name,
+ (int)r_type,
+ sym_name,
+ r_symndx,
+ (long)offset,
+ (long)addend);
+#endif
+
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ offset,
+ relocation,
+ addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ ret = false;
+ switch (r)
+ {
+ default:
+ break;
+
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (name == NULL)
+ break;
+
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ (*info->callbacks->reloc_overflow)(info,
+ name,
+ howto->name,
+ (bfd_vma) 0,
+ input_bfd,
+ input_section,
+ offset);
+ }
+ break;
+
+ }
+ }
+ }
+
+
+#ifdef DEBUG
+ fprintf (stderr, "\n");
+#endif
+
+ return ret;
+}
+
+
+#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec
+#define TARGET_LITTLE_NAME "elf32-powerpcle"
+#define TARGET_BIG_SYM bfd_elf32_powerpc_vec
+#define TARGET_BIG_NAME "elf32-powerpc"
+#define ELF_ARCH bfd_arch_powerpc
+#define ELF_MACHINE_CODE EM_PPC
+#define ELF_MAXPAGESIZE 0x10000
+#define elf_info_to_howto ppc_elf_info_to_howto
+
+#ifdef EM_CYGNUS_POWERPC
+#define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC
+#endif
+
+#ifdef EM_PPC_OLD
+#define ELF_MACHINE_ALT2 EM_PPC_OLD
+#endif
+
+#define elf_backend_plt_not_loaded 1
+#define elf_backend_got_symbol_offset 4
+#define elf_backend_can_gc_sections 1
+#define elf_backend_got_header_size 12
+#define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE
+
+#define bfd_elf32_bfd_copy_private_bfd_data ppc_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_relax_section ppc_elf_relax_section
+#define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup
+#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
+#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link
+
+#define elf_backend_gc_mark_hook ppc_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook ppc_elf_gc_sweep_hook
+#define elf_backend_section_from_shdr ppc_elf_section_from_shdr
+#define elf_backend_relocate_section ppc_elf_relocate_section
+#define elf_backend_create_dynamic_sections ppc_elf_create_dynamic_sections
+#define elf_backend_check_relocs ppc_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol
+#define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook
+#define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections
+#define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections
+#define elf_backend_fake_sections ppc_elf_fake_sections
+#define elf_backend_additional_program_headers ppc_elf_additional_program_headers
+#define elf_backend_modify_segment_map ppc_elf_modify_segment_map
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
new file mode 100644
index 00000000000..ebbe352456e
--- /dev/null
+++ b/bfd/elf32-sh.c
@@ -0,0 +1,2059 @@
+/* Hitachi SH specific support for 32-bit ELF
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sh.h"
+
+static bfd_reloc_status_type sh_elf_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type sh_elf_ignore_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static reloc_howto_type *sh_elf_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void sh_elf_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static boolean sh_elf_relax_section
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+static boolean sh_elf_relax_delete_bytes
+ PARAMS ((bfd *, asection *, bfd_vma, int));
+static boolean sh_elf_align_loads
+ PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, boolean *));
+static boolean sh_elf_swap_insns
+ PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma));
+static boolean sh_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static bfd_byte *sh_elf_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, boolean, asymbol **));
+
+static reloc_howto_type sh_elf_howto_table[] =
+{
+ /* No relocation. */
+ HOWTO (R_SH_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit absolute relocation. Setting partial_inplace to true and
+ src_mask to a non-zero value is similar to the COFF toolchain. */
+ HOWTO (R_SH_DIR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative relocation. */
+ HOWTO (R_SH_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_REL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit PC relative branch divided by 2. */
+ HOWTO (R_SH_DIR8WPN, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR8WPN", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 12 bit PC relative branch divided by 2. */
+ HOWTO (R_SH_IND12W, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_IND12W", /* name */
+ true, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit unsigned PC relative divided by 4. */
+ HOWTO (R_SH_DIR8WPL, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR8WPL", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit unsigned PC relative divided by 2. */
+ HOWTO (R_SH_DIR8WPZ, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR8WPZ", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit GBR relative. FIXME: This only makes sense if we have some
+ special symbol for the GBR relative area, and that is not
+ implemented. */
+ HOWTO (R_SH_DIR8BP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR8BP", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit GBR relative divided by 2. FIXME: This only makes sense if
+ we have some special symbol for the GBR relative area, and that
+ is not implemented. */
+ HOWTO (R_SH_DIR8W, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR8W", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit GBR relative divided by 4. FIXME: This only makes sense if
+ we have some special symbol for the GBR relative area, and that
+ is not implemented. */
+ HOWTO (R_SH_DIR8L, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_reloc, /* special_function */
+ "R_SH_DIR8L", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ { 10 },
+ { 11 },
+ { 12 },
+ { 13 },
+ { 14 },
+ { 15 },
+ { 16 },
+ { 17 },
+ { 18 },
+ { 19 },
+ { 20 },
+ { 21 },
+ { 22 },
+ { 23 },
+ { 24 },
+
+ /* The remaining relocs are a GNU extension used for relaxing. The
+ final pass of the linker never needs to do anything with any of
+ these relocs. Any required operations are handled by the
+ relaxation code. */
+
+ /* A 16 bit switch table entry. This is generated for an expression
+ such as ``.word L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_SH_SWITCH16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_SWITCH16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 32 bit switch table entry. This is generated for an expression
+ such as ``.long L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_SH_SWITCH32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_SWITCH32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Indicates a .uses pseudo-op. The compiler will generate .uses
+ pseudo-ops when it finds a function call which can be relaxed.
+ The offset field holds the PC relative offset to the instruction
+ which loads the register used in the function call. */
+ HOWTO (R_SH_USES, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_USES", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* The assembler will generate this reloc for addresses referred to
+ by the register loads associated with USES relocs. The offset
+ field holds the number of times the address is referenced in the
+ object file. */
+ HOWTO (R_SH_COUNT, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_COUNT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* Indicates an alignment statement. The offset field is the power
+ of 2 to which subsequent portions of the object file must be
+ aligned. */
+ HOWTO (R_SH_ALIGN, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_ALIGN", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* The assembler will generate this reloc before a block of
+ instructions. A section should be processed as assumining it
+ contains data, unless this reloc is seen. */
+ HOWTO (R_SH_CODE, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_CODE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* The assembler will generate this reloc after a block of
+ instructions when it sees data that is not instructions. */
+ HOWTO (R_SH_DATA, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_DATA", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* The assembler generates this reloc for each label within a block
+ of instructions. This permits the linker to avoid swapping
+ instructions which are the targets of branches. */
+ HOWTO (R_SH_LABEL, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_LABEL", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* An 8 bit switch table entry. This is generated for an expression
+ such as ``.word L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_SH_SWITCH8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_SWITCH8", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_SH_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_SH_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_SH_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_SH_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+/* This function is used for normal relocs. This is like the COFF
+ function, and is almost certainly incorrect for other ELF targets. */
+
+static bfd_reloc_status_type
+sh_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ unsigned long insn;
+ bfd_vma sym_value;
+ enum elf_sh_reloc_type r_type;
+ bfd_vma addr = reloc_entry->address;
+ bfd_byte *hit_data = addr + (bfd_byte *) data;
+
+ r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type;
+
+ if (output_bfd != NULL)
+ {
+ /* Partial linking--do nothing. */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Almost all relocs have to do with relaxing. If any work must be
+ done for them, it has been done in sh_relax_section. */
+ if (r_type != R_SH_DIR32
+ && (r_type != R_SH_IND12W
+ || (symbol_in->flags & BSF_LOCAL) != 0))
+ return bfd_reloc_ok;
+
+ if (symbol_in != NULL
+ && bfd_is_und_section (symbol_in->section))
+ return bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol_in->section))
+ sym_value = 0;
+ else
+ sym_value = (symbol_in->value +
+ symbol_in->section->output_section->vma +
+ symbol_in->section->output_offset);
+
+ switch (r_type)
+ {
+ case R_SH_DIR32:
+ insn = bfd_get_32 (abfd, hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_put_32 (abfd, insn, hit_data);
+ break;
+ case R_SH_IND12W:
+ insn = bfd_get_16 (abfd, hit_data);
+ sym_value += reloc_entry->addend;
+ sym_value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + addr
+ + 4);
+ sym_value += (insn & 0xfff) << 1;
+ if (insn & 0x800)
+ sym_value -= 0x1000;
+ insn = (insn & 0xf000) | (sym_value & 0xfff);
+ bfd_put_16 (abfd, insn, hit_data);
+ if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000)
+ return bfd_reloc_overflow;
+ break;
+ default:
+ abort ();
+ break;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* This function is used for relocs which are only used for relaxing,
+ which the linker should otherwise ignore. */
+
+static bfd_reloc_status_type
+sh_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+/* This structure is used to map BFD reloc codes to SH ELF relocs. */
+
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+/* An array mapping BFD reloc codes to SH ELF relocs. */
+
+static const struct elf_reloc_map sh_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_SH_NONE },
+ { BFD_RELOC_32, R_SH_DIR32 },
+ { BFD_RELOC_CTOR, R_SH_DIR32 },
+ { BFD_RELOC_32_PCREL, R_SH_REL32 },
+ { BFD_RELOC_SH_PCDISP8BY2, R_SH_DIR8WPN },
+ { BFD_RELOC_SH_PCDISP12BY2, R_SH_IND12W },
+ { BFD_RELOC_SH_PCRELIMM8BY2, R_SH_DIR8WPZ },
+ { BFD_RELOC_SH_PCRELIMM8BY4, R_SH_DIR8WPL },
+ { BFD_RELOC_8_PCREL, R_SH_SWITCH8 },
+ { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
+ { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
+ { BFD_RELOC_SH_USES, R_SH_USES },
+ { BFD_RELOC_SH_COUNT, R_SH_COUNT },
+ { BFD_RELOC_SH_ALIGN, R_SH_ALIGN },
+ { BFD_RELOC_SH_CODE, R_SH_CODE },
+ { BFD_RELOC_SH_DATA, R_SH_DATA },
+ { BFD_RELOC_SH_LABEL, R_SH_LABEL },
+ { BFD_RELOC_VTABLE_INHERIT, R_SH_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
+};
+
+/* Given a BFD reloc code, return the howto structure for the
+ corresponding SH ELf reloc. */
+
+static reloc_howto_type *
+sh_elf_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (sh_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (sh_reloc_map[i].bfd_reloc_val == code)
+ return &sh_elf_howto_table[(int) sh_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+/* Given an ELF reloc, fill in the howto field of a relent. */
+
+static void
+sh_elf_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf_Internal_Rela *dst;
+{
+ unsigned int r;
+
+ r = ELF32_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (r < (unsigned int) R_SH_max);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
+
+ cache_ptr->howto = &sh_elf_howto_table[r];
+}
+
+/* This function handles relaxing for SH ELF. See the corresponding
+ function in coff-sh.c for a description of what this does. FIXME:
+ There is a lot of duplication here between this code and the COFF
+ specific code. The format of relocs and symbols is wound deeply
+ into this code, but it would still be better if the duplication
+ could be eliminated somehow. Note in particular that although both
+ functions use symbols like R_SH_CODE, those symbols have different
+ values; in coff-sh.c they come from include/coff/sh.h, whereas here
+ they come from enum elf_sh_reloc_type in include/elf/sh.h. */
+
+static boolean
+sh_elf_relax_section (abfd, sec, link_info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *free_relocs = NULL;
+ boolean have_code;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ bfd_byte *free_contents = NULL;
+ Elf32_External_Sym *extsyms = NULL;
+ Elf32_External_Sym *free_extsyms = NULL;
+
+ *again = false;
+
+ if (link_info->relocateable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return true;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ have_code = false;
+
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma laddr, paddr, symval;
+ unsigned short insn;
+ Elf_Internal_Rela *irelfn, *irelscan, *irelcount;
+ bfd_signed_vma foff;
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_CODE)
+ have_code = true;
+
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_SH_USES)
+ continue;
+
+ /* Get the section contents. */
+ if (contents == NULL)
+ {
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* The r_addend field of the R_SH_USES reloc will point us to
+ the register load. The 4 is because the r_addend field is
+ computed as though it were a jump offset, which are based
+ from 4 bytes after the jump instruction. */
+ laddr = irel->r_offset + 4 + irel->r_addend;
+ if (laddr >= sec->_raw_size)
+ {
+ (*_bfd_error_handler) (_("%s: 0x%lx: warning: bad R_SH_USES offset"),
+ bfd_get_filename (abfd),
+ (unsigned long) irel->r_offset);
+ continue;
+ }
+ insn = bfd_get_16 (abfd, contents + laddr);
+
+ /* If the instruction is not mov.l NN,rN, we don't know what to
+ do. */
+ if ((insn & 0xf000) != 0xd000)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset, insn));
+ continue;
+ }
+
+ /* Get the address from which the register is being loaded. The
+ displacement in the mov.l instruction is quadrupled. It is a
+ displacement from four bytes after the movl instruction, but,
+ before adding in the PC address, two least significant bits
+ of the PC are cleared. We assume that the section is aligned
+ on a four byte boundary. */
+ paddr = insn & 0xff;
+ paddr *= 4;
+ paddr += (laddr + 4) &~ 3;
+ if (paddr >= sec->_raw_size)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: warning: bad R_SH_USES load offset"),
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ continue;
+ }
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ for (irelfn = internal_relocs; irelfn < irelend; irelfn++)
+ if (irelfn->r_offset == paddr
+ && ELF32_R_TYPE (irelfn->r_info) == (int) R_SH_DIR32)
+ break;
+ if (irelfn >= irelend)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: warning: could not find expected reloc"),
+ bfd_get_filename (abfd), (unsigned long) paddr));
+ continue;
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (extsyms == NULL)
+ {
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ extsyms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym isym;
+
+ /* A local symbol. */
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irelfn->r_info),
+ &isym);
+
+ if (isym.st_shndx != _bfd_elf_section_from_bfd_section (abfd, sec))
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: warning: symbol in unexpected section"),
+ bfd_get_filename (abfd), (unsigned long) paddr));
+ continue;
+ }
+
+ symval = (isym.st_value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ indx = ELF32_R_SYM (irelfn->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ continue;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ symval += bfd_get_32 (abfd, contents + paddr);
+
+ /* See if this function call can be shortened. */
+ foff = (symval
+ - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset
+ + 4));
+ if (foff < -0x1000 || foff >= 0x1000)
+ {
+ /* After all that work, we can't shorten this function call. */
+ continue;
+ }
+
+ /* Shorten the function call. */
+
+ /* For simplicity of coding, we are going to modify the section
+ contents, the section relocs, and the BFD symbol table. We
+ must tell the rest of the code not to free up this
+ information. It would be possible to instead create a table
+ of changes which have to be made, as is done in coff-mips.c;
+ that would be more work, but would require less memory when
+ the linker is run. */
+
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+
+ /* Replace the jsr with a bsr. */
+
+ /* Change the R_SH_USES reloc into an R_SH_IND12W reloc, and
+ replace the jsr with a bsr. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W);
+ if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
+ {
+ /* If this needs to be changed because of future relaxing,
+ it will be handled here like other internal IND12W
+ relocs. */
+ bfd_put_16 (abfd,
+ 0xb000 | ((foff >> 1) & 0xfff),
+ contents + irel->r_offset);
+ }
+ else
+ {
+ /* We can't fully resolve this yet, because the external
+ symbol value may be changed by future relaxing. We let
+ the final link phase handle it. */
+ bfd_put_16 (abfd, 0xb000, contents + irel->r_offset);
+ }
+
+ /* See if there is another R_SH_USES reloc referring to the same
+ register load. */
+ for (irelscan = internal_relocs; irelscan < irelend; irelscan++)
+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_USES
+ && laddr == irelscan->r_offset + 4 + irelscan->r_addend)
+ break;
+ if (irelscan < irelend)
+ {
+ /* Some other function call depends upon this register load,
+ and we have not yet converted that function call.
+ Indeed, we may never be able to convert it. There is
+ nothing else we can do at this point. */
+ continue;
+ }
+
+ /* Look for a R_SH_COUNT reloc on the location where the
+ function address is stored. Do this before deleting any
+ bytes, to avoid confusion about the address. */
+ for (irelcount = internal_relocs; irelcount < irelend; irelcount++)
+ if (irelcount->r_offset == paddr
+ && ELF32_R_TYPE (irelcount->r_info) == (int) R_SH_COUNT)
+ break;
+
+ /* Delete the register load. */
+ if (! sh_elf_relax_delete_bytes (abfd, sec, laddr, 2))
+ goto error_return;
+
+ /* That will change things, so, just in case it permits some
+ other function call to come within range, we should relax
+ again. Note that this is not required, and it may be slow. */
+ *again = true;
+
+ /* Now check whether we got a COUNT reloc. */
+ if (irelcount >= irelend)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: warning: could not find expected COUNT reloc"),
+ bfd_get_filename (abfd), (unsigned long) paddr));
+ continue;
+ }
+
+ /* The number of uses is stored in the r_addend field. We've
+ just deleted one. */
+ if (irelcount->r_addend == 0)
+ {
+ ((*_bfd_error_handler) (_("%s: 0x%lx: warning: bad count"),
+ bfd_get_filename (abfd),
+ (unsigned long) paddr));
+ continue;
+ }
+
+ --irelcount->r_addend;
+
+ /* If there are no more uses, we can delete the address. Reload
+ the address from irelfn, in case it was changed by the
+ previous call to sh_elf_relax_delete_bytes. */
+ if (irelcount->r_addend == 0)
+ {
+ if (! sh_elf_relax_delete_bytes (abfd, sec, irelfn->r_offset, 4))
+ goto error_return;
+ }
+
+ /* We've done all we can with that function call. */
+ }
+
+ /* Look for load and store instructions that we can align on four
+ byte boundaries. */
+ if (have_code)
+ {
+ boolean swapped;
+
+ /* Get the section contents. */
+ if (contents == NULL)
+ {
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (! bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ if (! sh_elf_align_loads (abfd, sec, internal_relocs, contents,
+ &swapped))
+ goto error_return;
+
+ if (swapped)
+ {
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) extsyms;
+ free_extsyms = NULL;
+ }
+ }
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ free_contents = NULL;
+ }
+
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ free_extsyms = NULL;
+ }
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (free_extsyms != NULL)
+ free (free_extsyms);
+ return false;
+}
+
+/* Delete some bytes from a section while relaxing. FIXME: There is a
+ lot of duplication between this function and sh_relax_delete_bytes
+ in coff-sh.c. */
+
+static boolean
+sh_elf_relax_delete_bytes (abfd, sec, addr, count)
+ bfd *abfd;
+ asection *sec;
+ bfd_vma addr;
+ int count;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf32_External_Sym *extsyms;
+ int shndx, index;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf32_External_Sym *esym, *esymend;
+ struct elf_link_hash_entry *sym_hash;
+ asection *o;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than the number of bytes we are deleting. */
+
+ irelalign = NULL;
+ toaddr = sec->_cooked_size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+ for (; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_ALIGN
+ && irel->r_offset > addr
+ && count < (1 << irel->r_addend))
+ {
+ irelalign = irel;
+ toaddr = irel->r_offset;
+ break;
+ }
+ }
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
+ if (irelalign == NULL)
+ sec->_cooked_size -= count;
+ else
+ {
+ int i;
+
+#define NOP_OPCODE (0x0009)
+
+ BFD_ASSERT ((count & 1) == 0);
+ for (i = 0; i < count; i += 2)
+ bfd_put_16 (abfd, NOP_OPCODE, contents + toaddr - count + i);
+ }
+
+ /* Adjust all the relocs. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ bfd_vma nraddr, stop;
+ bfd_vma start = 0;
+ int insn = 0;
+ Elf_Internal_Sym sym;
+ int off, adjust, oinsn;
+ bfd_signed_vma voff = 0;
+ boolean overflow;
+
+ /* Get the new reloc address. */
+ nraddr = irel->r_offset;
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr)
+ || (ELF32_R_TYPE (irel->r_info) == (int) R_SH_ALIGN
+ && irel->r_offset == toaddr))
+ nraddr -= count;
+
+ /* See if this reloc was for the bytes we have deleted, in which
+ case we no longer care about it. Don't delete relocs which
+ represent addresses, though. */
+ if (irel->r_offset >= addr
+ && irel->r_offset < addr + count
+ && ELF32_R_TYPE (irel->r_info) != (int) R_SH_ALIGN
+ && ELF32_R_TYPE (irel->r_info) != (int) R_SH_CODE
+ && ELF32_R_TYPE (irel->r_info) != (int) R_SH_DATA
+ && ELF32_R_TYPE (irel->r_info) != (int) R_SH_LABEL)
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ (int) R_SH_NONE);
+
+ /* If this is a PC relative reloc, see if the range it covers
+ includes the bytes we have deleted. */
+ switch ((enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info))
+ {
+ default:
+ break;
+
+ case R_SH_DIR8WPN:
+ case R_SH_IND12W:
+ case R_SH_DIR8WPZ:
+ case R_SH_DIR8WPL:
+ start = irel->r_offset;
+ insn = bfd_get_16 (abfd, contents + nraddr);
+ break;
+ }
+
+ switch ((enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info))
+ {
+ default:
+ start = stop = addr;
+ break;
+
+ case R_SH_DIR32:
+ /* If this reloc is against a symbol defined in this
+ section, and the symbol will not be adjusted below, we
+ must check the addend to see it will put the value in
+ range to be adjusted, and hence must be changed. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irel->r_info),
+ &sym);
+ if (sym.st_shndx == shndx
+ && (sym.st_value <= addr
+ || sym.st_value >= toaddr))
+ {
+ bfd_vma val;
+
+ val = bfd_get_32 (abfd, contents + nraddr);
+ val += sym.st_value;
+ if (val > addr && val < toaddr)
+ bfd_put_32 (abfd, val - count, contents + nraddr);
+ }
+ }
+ start = stop = addr;
+ break;
+
+ case R_SH_DIR8WPN:
+ off = insn & 0xff;
+ if (off & 0x80)
+ off -= 0x100;
+ stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
+ break;
+
+ case R_SH_IND12W:
+ if (ELF32_R_SYM (irel->r_info) >= symtab_hdr->sh_info)
+ start = stop = addr;
+ else
+ {
+ off = insn & 0xfff;
+ if (off & 0x800)
+ off -= 0x1000;
+ stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
+ }
+ break;
+
+ case R_SH_DIR8WPZ:
+ off = insn & 0xff;
+ stop = start + 4 + off * 2;
+ break;
+
+ case R_SH_DIR8WPL:
+ off = insn & 0xff;
+ stop = (start &~ (bfd_vma) 3) + 4 + off * 4;
+ break;
+
+ case R_SH_SWITCH8:
+ case R_SH_SWITCH16:
+ case R_SH_SWITCH32:
+ /* These relocs types represent
+ .word L2-L1
+ The r_offset field holds the difference between the reloc
+ address and L1. That is the start of the reloc, and
+ adding in the contents gives us the top. We must adjust
+ both the r_offset field and the section contents. */
+
+ start = irel->r_offset;
+ stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_addend);
+
+ if (start > addr
+ && start < toaddr
+ && (stop <= addr || stop >= toaddr))
+ irel->r_addend += count;
+ else if (stop > addr
+ && stop < toaddr
+ && (start <= addr || start >= toaddr))
+ irel->r_addend -= count;
+
+ start = stop;
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_SWITCH16)
+ voff = bfd_get_signed_16 (abfd, contents + nraddr);
+ else if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_SWITCH8)
+ voff = bfd_get_8 (abfd, contents + nraddr);
+ else
+ voff = bfd_get_signed_32 (abfd, contents + nraddr);
+ stop = (bfd_vma) ((bfd_signed_vma) start + voff);
+
+ break;
+
+ case R_SH_USES:
+ start = irel->r_offset;
+ stop = (bfd_vma) ((bfd_signed_vma) start
+ + (long) irel->r_addend
+ + 4);
+ break;
+ }
+
+ if (start > addr
+ && start < toaddr
+ && (stop <= addr || stop >= toaddr))
+ adjust = count;
+ else if (stop > addr
+ && stop < toaddr
+ && (start <= addr || start >= toaddr))
+ adjust = - count;
+ else
+ adjust = 0;
+
+ if (adjust != 0)
+ {
+ oinsn = insn;
+ overflow = false;
+ switch ((enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info))
+ {
+ default:
+ abort ();
+ break;
+
+ case R_SH_DIR8WPN:
+ case R_SH_DIR8WPZ:
+ insn += adjust / 2;
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, contents + nraddr);
+ break;
+
+ case R_SH_IND12W:
+ insn += adjust / 2;
+ if ((oinsn & 0xf000) != (insn & 0xf000))
+ overflow = true;
+ bfd_put_16 (abfd, insn, contents + nraddr);
+ break;
+
+ case R_SH_DIR8WPL:
+ BFD_ASSERT (adjust == count || count >= 4);
+ if (count >= 4)
+ insn += adjust / 4;
+ else
+ {
+ if ((irel->r_offset & 3) == 0)
+ ++insn;
+ }
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH16:
+ voff += adjust;
+ if (voff < - 0x8000 || voff >= 0x8000)
+ overflow = true;
+ bfd_put_signed_16 (abfd, voff, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH32:
+ voff += adjust;
+ bfd_put_signed_32 (abfd, voff, contents + nraddr);
+ break;
+
+ case R_SH_USES:
+ irel->r_addend += adjust;
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ irel->r_offset = nraddr;
+ }
+
+ /* Look through all the other sections. If there contain any IMM32
+ relocs against internal symbols which we are not going to adjust
+ below, we may need to adjust the addends. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irelscan, *irelscanend;
+ bfd_byte *ocontents;
+
+ if (o == sec
+ || (o->flags & SEC_RELOC) == 0
+ || o->reloc_count == 0)
+ continue;
+
+ /* We always cache the relocs. Perhaps, if info->keep_memory is
+ false, we should free them, if we are permitted to, when we
+ leave sh_coff_relax_section. */
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (abfd, o, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ true));
+ if (internal_relocs == NULL)
+ return false;
+
+ ocontents = NULL;
+ irelscanend = internal_relocs + o->reloc_count;
+ for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++)
+ {
+ Elf_Internal_Sym sym;
+
+ if (ELF32_R_TYPE (irelscan->r_info) != (int) R_SH_DIR32)
+ continue;
+
+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+ continue;
+
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irelscan->r_info),
+ &sym);
+
+ if (sym.st_shndx == shndx
+ && (sym.st_value <= addr
+ || sym.st_value >= toaddr))
+ {
+ bfd_vma val;
+
+ if (ocontents == NULL)
+ {
+ if (elf_section_data (o)->this_hdr.contents != NULL)
+ ocontents = elf_section_data (o)->this_hdr.contents;
+ else
+ {
+ /* We always cache the section contents.
+ Perhaps, if info->keep_memory is false, we
+ should free them, if we are permitted to,
+ when we leave sh_coff_relax_section. */
+ ocontents = (bfd_byte *) bfd_malloc (o->_raw_size);
+ if (ocontents == NULL)
+ return false;
+ if (! bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->_raw_size))
+ return false;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+
+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
+ val += sym.st_value;
+ if (val > addr && val < toaddr)
+ bfd_put_32 (abfd, val - count,
+ ocontents + irelscan->r_offset);
+ }
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; esym++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+
+ if (isym.st_shndx == shndx
+ && isym.st_value > addr
+ && isym.st_value < toaddr)
+ {
+ isym.st_value -= count;
+ bfd_elf32_swap_symbol_out (abfd, &isym, esym);
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ esym = extsyms + symtab_hdr->sh_info;
+ esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
+ for (index = 0; esym < esymend; esym++, index++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+ sym_hash = elf_sym_hashes (abfd)[index];
+ if (isym.st_shndx == shndx
+ && ((sym_hash)->root.type == bfd_link_hash_defined
+ || (sym_hash)->root.type == bfd_link_hash_defweak)
+ && (sym_hash)->root.u.def.section == sec
+ && (sym_hash)->root.u.def.value > addr
+ && (sym_hash)->root.u.def.value < toaddr)
+ {
+ (sym_hash)->root.u.def.value -= count;
+ }
+ }
+
+ /* See if we can move the ALIGN reloc forward. We have adjusted
+ r_offset for it already. */
+ if (irelalign != NULL)
+ {
+ bfd_vma alignto, alignaddr;
+
+ alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend);
+ alignaddr = BFD_ALIGN (irelalign->r_offset,
+ 1 << irelalign->r_addend);
+ if (alignto != alignaddr)
+ {
+ /* Tail recursion. */
+ return sh_elf_relax_delete_bytes (abfd, sec, alignaddr,
+ alignto - alignaddr);
+ }
+ }
+
+ return true;
+}
+
+/* Look for loads and stores which we can align to four byte
+ boundaries. This is like sh_align_loads in coff-sh.c. */
+
+static boolean
+sh_elf_align_loads (abfd, sec, internal_relocs, contents, pswapped)
+ bfd *abfd;
+ asection *sec;
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents;
+ boolean *pswapped;
+{
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_vma *labels = NULL;
+ bfd_vma *label, *label_end;
+
+ *pswapped = false;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Get all the addresses with labels on them. */
+ labels = (bfd_vma *) bfd_malloc (sec->reloc_count * sizeof (bfd_vma));
+ if (labels == NULL)
+ goto error_return;
+ label_end = labels;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_LABEL)
+ {
+ *label_end = irel->r_offset;
+ ++label_end;
+ }
+ }
+
+ /* Note that the assembler currently always outputs relocs in
+ address order. If that ever changes, this code will need to sort
+ the label values and the relocs. */
+
+ label = labels;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma start, stop;
+
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_SH_CODE)
+ continue;
+
+ start = irel->r_offset;
+
+ for (irel++; irel < irelend; irel++)
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_DATA)
+ break;
+ if (irel < irelend)
+ stop = irel->r_offset;
+ else
+ stop = sec->_cooked_size;
+
+ if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_elf_swap_insns,
+ (PTR) internal_relocs, &label,
+ label_end, start, stop, pswapped))
+ goto error_return;
+ }
+
+ free (labels);
+
+ return true;
+
+ error_return:
+ if (labels != NULL)
+ free (labels);
+ return false;
+}
+
+/* Swap two SH instructions. This is like sh_swap_insns in coff-sh.c. */
+
+static boolean
+sh_elf_swap_insns (abfd, sec, relocs, contents, addr)
+ bfd *abfd;
+ asection *sec;
+ PTR relocs;
+ bfd_byte *contents;
+ bfd_vma addr;
+{
+ Elf_Internal_Rela *internal_relocs = (Elf_Internal_Rela *) relocs;
+ unsigned short i1, i2;
+ Elf_Internal_Rela *irel, *irelend;
+
+ /* Swap the instructions themselves. */
+ i1 = bfd_get_16 (abfd, contents + addr);
+ i2 = bfd_get_16 (abfd, contents + addr + 2);
+ bfd_put_16 (abfd, i2, contents + addr);
+ bfd_put_16 (abfd, i1, contents + addr + 2);
+
+ /* Adjust all reloc addresses. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ enum elf_sh_reloc_type type;
+ int add;
+
+ /* There are a few special types of relocs that we don't want to
+ adjust. These relocs do not apply to the instruction itself,
+ but are only associated with the address. */
+ type = (enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info);
+ if (type == R_SH_ALIGN
+ || type == R_SH_CODE
+ || type == R_SH_DATA
+ || type == R_SH_LABEL)
+ continue;
+
+ /* If an R_SH_USES reloc points to one of the addresses being
+ swapped, we must adjust it. It would be incorrect to do this
+ for a jump, though, since we want to execute both
+ instructions after the jump. (We have avoided swapping
+ around a label, so the jump will not wind up executing an
+ instruction it shouldn't). */
+ if (type == R_SH_USES)
+ {
+ bfd_vma off;
+
+ off = irel->r_offset + 4 + irel->r_addend;
+ if (off == addr)
+ irel->r_offset += 2;
+ else if (off == addr + 2)
+ irel->r_offset -= 2;
+ }
+
+ if (irel->r_offset == addr)
+ {
+ irel->r_offset += 2;
+ add = -2;
+ }
+ else if (irel->r_offset == addr + 2)
+ {
+ irel->r_offset -= 2;
+ add = 2;
+ }
+ else
+ add = 0;
+
+ if (add != 0)
+ {
+ bfd_byte *loc;
+ unsigned short insn, oinsn;
+ boolean overflow;
+
+ loc = contents + irel->r_offset;
+ overflow = false;
+ switch (type)
+ {
+ default:
+ break;
+
+ case R_SH_DIR8WPN:
+ case R_SH_DIR8WPZ:
+ insn = bfd_get_16 (abfd, loc);
+ oinsn = insn;
+ insn += add / 2;
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, loc);
+ break;
+
+ case R_SH_IND12W:
+ insn = bfd_get_16 (abfd, loc);
+ oinsn = insn;
+ insn += add / 2;
+ if ((oinsn & 0xf000) != (insn & 0xf000))
+ overflow = true;
+ bfd_put_16 (abfd, insn, loc);
+ break;
+
+ case R_SH_DIR8WPL:
+ /* This reloc ignores the least significant 3 bits of
+ the program counter before adding in the offset.
+ This means that if ADDR is at an even address, the
+ swap will not affect the offset. If ADDR is an at an
+ odd address, then the instruction will be crossing a
+ four byte boundary, and must be adjusted. */
+ if ((addr & 3) != 0)
+ {
+ insn = bfd_get_16 (abfd, loc);
+ oinsn = insn;
+ insn += add / 2;
+ if ((oinsn & 0xff00) != (insn & 0xff00))
+ overflow = true;
+ bfd_put_16 (abfd, insn, loc);
+ }
+
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Relocate an SH ELF section. */
+
+static boolean
+sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel, *relend;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_vma addend = (bfd_vma)0;
+ bfd_reloc_status_type r;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ /* Many of the relocs are only used for relaxing, and are
+ handled entirely by the relaxation code. */
+ if (r_type > (int) R_SH_LAST_INVALID_RELOC)
+ continue;
+
+ if (r_type < 0
+ || r_type >= (int) R_SH_FIRST_INVALID_RELOC)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* FIXME: This is certainly incorrect. However, it is how the
+ COFF linker works. */
+ if (r_type != (int) R_SH_DIR32
+ && r_type != (int) R_SH_IND12W)
+ continue;
+
+ howto = sh_elf_howto_table + r_type;
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* There is nothing to be done for an internal IND12W
+ relocation. FIXME: This is probably wrong, but it's how
+ the COFF relocations work. */
+ if (r_type == (int) R_SH_IND12W)
+ continue;
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ /* FIXME: This is how the COFF relocations work. */
+ if (r_type == (int) R_SH_IND12W)
+ relocation -= 4;
+
+ switch ((int)r_type)
+ {
+ case (int)R_SH_DIR32:
+ addend = rel->r_addend;
+ break;
+ }
+
+ /* COFF relocs don't use the addend. The addend is used for R_SH_DIR32
+ to be compatible with other compilers. */
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses sh_elf_relocate_section. */
+
+static bfd_byte *
+sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
+ data, relocateable, symbols)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *input_section = link_order->u.indirect.section;
+ bfd *input_bfd = input_section->owner;
+ asection **sections = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf32_External_Sym *external_syms = NULL;
+ Elf_Internal_Sym *internal_syms = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocateable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocateable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ input_section->_raw_size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isymp;
+ asection **secpp;
+ Elf32_External_Sym *esym, *esymend;
+
+ if (symtab_hdr->contents != NULL)
+ external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ external_syms = ((Elf32_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf32_External_Sym)));
+ if (external_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (external_syms, sizeof (Elf32_External_Sym),
+ symtab_hdr->sh_info, input_bfd)
+ != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))))
+ goto error_return;
+ }
+
+ internal_relocs = (_bfd_elf32_link_read_relocs
+ (input_bfd, input_section, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL, false));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ internal_syms = ((Elf_Internal_Sym *)
+ bfd_malloc (symtab_hdr->sh_info
+ * sizeof (Elf_Internal_Sym)));
+ if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ sections = (asection **) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (asection *));
+ if (sections == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ isymp = internal_syms;
+ secpp = sections;
+ esym = external_syms;
+ esymend = esym + symtab_hdr->sh_info;
+ for (; esym < esymend; ++esym, ++isymp, ++secpp)
+ {
+ asection *isec;
+
+ bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
+
+ if (isymp->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
+ isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+ else if (isymp->st_shndx == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isymp->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else
+ {
+ /* Who knows? */
+ isec = NULL;
+ }
+
+ *secpp = isec;
+ }
+
+ if (! sh_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ internal_syms, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ sections = NULL;
+ if (internal_syms != NULL)
+ free (internal_syms);
+ internal_syms = NULL;
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ external_syms = NULL;
+ if (internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+ }
+
+ return data;
+
+ error_return:
+ if (internal_relocs != NULL
+ && internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ if (external_syms != NULL && symtab_hdr->contents == NULL)
+ free (external_syms);
+ if (internal_syms != NULL)
+ free (internal_syms);
+ if (sections != NULL)
+ free (sections);
+ return NULL;
+}
+static asection *
+sh_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_SH_GNU_VTINHERIT:
+ case R_SH_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+ return NULL;
+}
+
+static boolean
+sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ /* we don't use got and plt entries for sh. */
+ return true;
+}
+
+/* Look through the relocs for a section during the first phase.
+ Since we don't do .gots or .plts, we just need to consider the
+ virtual table relocs for gc. */
+
+static boolean
+sh_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocateable)
+ return true;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ sym_hashes_end -= symtab_hdr->sh_info;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_SH_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_SH_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
+
+#define TARGET_BIG_SYM bfd_elf32_sh_vec
+#define TARGET_BIG_NAME "elf32-sh"
+#define TARGET_LITTLE_SYM bfd_elf32_shl_vec
+#define TARGET_LITTLE_NAME "elf32-shl"
+#define ELF_ARCH bfd_arch_sh
+#define ELF_MACHINE_CODE EM_SH
+#define ELF_MAXPAGESIZE 0x1
+
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup sh_elf_reloc_type_lookup
+#define elf_info_to_howto sh_elf_info_to_howto
+#define bfd_elf32_bfd_relax_section sh_elf_relax_section
+#define elf_backend_relocate_section sh_elf_relocate_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ sh_elf_get_relocated_section_contents
+
+#define elf_backend_gc_mark_hook sh_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook sh_elf_gc_sweep_hook
+#define elf_backend_check_relocs sh_elf_check_relocs
+
+#define elf_backend_can_gc_sections 1
+#include "elf32-target.h"
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
new file mode 100644
index 00000000000..ec57c8cb35f
--- /dev/null
+++ b/bfd/elf32-sparc.c
@@ -0,0 +1,2059 @@
+/* SPARC-specific support for 32-bit ELF
+ Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sparc.h"
+
+static reloc_howto_type *elf32_sparc_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void elf32_sparc_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static boolean elf32_sparc_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
+static boolean elf32_sparc_adjust_dynamic_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean elf32_sparc_adjust_dynindx
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf32_sparc_size_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf32_sparc_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean elf32_sparc_finish_dynamic_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+static boolean elf32_sparc_finish_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf32_sparc_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+static boolean elf32_sparc_object_p
+ PARAMS ((bfd *));
+static void elf32_sparc_final_write_processing
+ PARAMS ((bfd *, boolean));
+
+/* The relocation "howto" table. */
+
+static bfd_reloc_status_type sparc_elf_notsupported_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type sparc_elf_wdisp16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+reloc_howto_type _bfd_sparc_elf_howto_table[] =
+{
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true),
+ HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true),
+ HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true),
+ HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true),
+ HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PLT32", false,0,0x00000000,true),
+ HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true),
+ HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true),
+ /* These are for sparc64 in a 64 bit environment.
+ Values need to be here because the table is indexed by reloc number. */
+ HOWTO(R_SPARC_64, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_64", false,0,0x00000000,true),
+ HOWTO(R_SPARC_OLO10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_OLO10", false,0,0x00000000,true),
+ HOWTO(R_SPARC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HH22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HM10", false,0,0x00000000,true),
+ HOWTO(R_SPARC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LM22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HH22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HM10", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_LM22", false,0,0x00000000,true),
+ /* End sparc64 in 64 bit environment values.
+ The following are for sparc64 in a 32 bit environment. */
+ HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true),
+ HOWTO(R_SPARC_WDISP19, 2,2,19,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true),
+ HOWTO(R_SPARC_UNUSED_42, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UNUSED_42",false,0,0x00000000,true),
+ HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true),
+ HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true),
+ HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_REV32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_REV32", false,0,0xffffffff,true),
+};
+static reloc_howto_type elf32_sparc_vtinherit_howto =
+ HOWTO (R_SPARC_GNU_VTINHERIT, 0,2,0,false,0,complain_overflow_dont, NULL, "R_SPARC_GNU_VTINHERIT", false,0, 0, false);
+static reloc_howto_type elf32_sparc_vtentry_howto =
+ HOWTO (R_SPARC_GNU_VTENTRY, 0,2,0,false,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_SPARC_GNU_VTENTRY", false,0,0, false);
+
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static CONST struct elf_reloc_map sparc_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_SPARC_NONE, },
+ { BFD_RELOC_16, R_SPARC_16, },
+ { BFD_RELOC_8, R_SPARC_8 },
+ { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
+ { BFD_RELOC_CTOR, R_SPARC_32 },
+ { BFD_RELOC_32, R_SPARC_32 },
+ { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
+ { BFD_RELOC_HI22, R_SPARC_HI22 },
+ { BFD_RELOC_LO10, R_SPARC_LO10, },
+ { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
+ { BFD_RELOC_SPARC22, R_SPARC_22 },
+ { BFD_RELOC_SPARC13, R_SPARC_13 },
+ { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
+ { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
+ { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
+ { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
+ { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
+ { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
+ { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
+ { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
+ { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
+ { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
+ { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
+ /* ??? Doesn't dwarf use this? */
+/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
+ {BFD_RELOC_SPARC_10, R_SPARC_10},
+ {BFD_RELOC_SPARC_11, R_SPARC_11},
+ {BFD_RELOC_SPARC_64, R_SPARC_64},
+ {BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10},
+ {BFD_RELOC_SPARC_HH22, R_SPARC_HH22},
+ {BFD_RELOC_SPARC_HM10, R_SPARC_HM10},
+ {BFD_RELOC_SPARC_LM22, R_SPARC_LM22},
+ {BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22},
+ {BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10},
+ {BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22},
+ {BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16},
+ {BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19},
+ {BFD_RELOC_SPARC_7, R_SPARC_7},
+ {BFD_RELOC_SPARC_5, R_SPARC_5},
+ {BFD_RELOC_SPARC_6, R_SPARC_6},
+ {BFD_RELOC_SPARC_REV32, R_SPARC_REV32 },
+ {BFD_RELOC_VTABLE_INHERIT, R_SPARC_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_SPARC_GNU_VTENTRY},
+};
+
+static reloc_howto_type *
+elf32_sparc_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ switch (code)
+ {
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf32_sparc_vtinherit_howto;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf32_sparc_vtentry_howto;
+
+ default:
+ for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (sparc_reloc_map[i].bfd_reloc_val == code)
+ return &_bfd_sparc_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
+ }
+ }
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+/* We need to use ELF32_R_TYPE so we have our own copy of this function,
+ and elf64-sparc.c has its own copy. */
+
+static void
+elf32_sparc_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf_Internal_Rela *dst;
+{
+ BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_SPARC_max);
+ cache_ptr->howto = &_bfd_sparc_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
+}
+
+/* For unsupported relocs. */
+
+static bfd_reloc_status_type
+sparc_elf_notsupported_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return bfd_reloc_notsupported;
+}
+
+/* Handle the WDISP16 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_wdisp16_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_vma x;
+
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc_entry->howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ relocation = (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset);
+ relocation += reloc_entry->addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ relocation -= reloc_entry->address;
+
+ x = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ x |= ((((relocation >> 2) & 0xc000) << 6)
+ | ((relocation >> 2) & 0x3fff));
+ bfd_put_32 (abfd, x, (bfd_byte *) data + reloc_entry->address);
+
+ if ((bfd_signed_vma) relocation < - 0x40000
+ || (bfd_signed_vma) relocation > 0x3ffff)
+ return bfd_reloc_overflow;
+ else
+ return bfd_reloc_ok;
+}
+
+/* Functions for the SPARC ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* The nop opcode we use. */
+
+#define SPARC_NOP 0x01000000
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 12
+
+/* The first four entries in a procedure linkage table are reserved,
+ and the initial contents are unimportant (we zero them out).
+ Subsequent entries look like this. See the SVR4 ABI SPARC
+ supplement to see how this works. */
+
+/* sethi %hi(.-.plt0),%g1. We fill in the address later. */
+#define PLT_ENTRY_WORD0 0x03000000
+/* b,a .plt0. We fill in the offset later. */
+#define PLT_ENTRY_WORD1 0x30800000
+/* nop. */
+#define PLT_ENTRY_WORD2 SPARC_NOP
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static boolean
+elf32_sparc_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+
+ if (info->relocateable)
+ return true;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_offsets = elf_local_got_offsets (abfd);
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ /* This symbol requires a global offset table entry. */
+
+ if (dynobj == NULL)
+ {
+ /* Create the .got section. */
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return false;
+ }
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rela.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return false;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ h->got.offset = sgot->_raw_size;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ /* This is a global offset table entry for a local
+ symbol. */
+ if (local_got_offsets == NULL)
+ {
+ size_t size;
+ register unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+ if (local_got_offsets == NULL)
+ return false;
+ elf_local_got_offsets (abfd) = local_got_offsets;
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_got_offsets[i] = (bfd_vma) -1;
+ }
+ if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ local_got_offsets[r_symndx] = sgot->_raw_size;
+
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_SPARC_RELATIVE reloc so that the
+ dynamic linker can adjust this GOT entry. */
+ srelgot->_raw_size += sizeof (Elf32_External_Rela);
+ }
+ }
+
+ sgot->_raw_size += 4;
+
+ /* If the .got section is more than 0x1000 bytes, we add
+ 0x1000 to the value of _GLOBAL_OFFSET_TABLE_, so that 13
+ bit relocations have a greater chance of working. */
+ if (sgot->_raw_size >= 0x1000
+ && elf_hash_table (info)->hgot->root.u.def.value == 0)
+ elf_hash_table (info)->hgot->root.u.def.value = 0x1000;
+
+ break;
+
+ case R_SPARC_WPLT30:
+ /* This symbol requires a procedure linkage table entry. We
+ actually build the entry in adjust_dynamic_symbol,
+ because this might be a case of linking PIC code without
+ linking in any dynamic objects, in which case we don't
+ need to generate a procedure linkage table after all. */
+
+ if (h == NULL)
+ {
+ /* The Solaris native assembler will generate a WPLT30
+ reloc for a local symbol if you assemble a call from
+ one section to another when using -K pic. We treat
+ it as WDISP30. */
+ break;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+ break;
+
+ case R_SPARC_PC10:
+ case R_SPARC_PC22:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_SPARC_DISP8:
+ case R_SPARC_DISP16:
+ case R_SPARC_DISP32:
+ case R_SPARC_WDISP30:
+ case R_SPARC_WDISP22:
+ case R_SPARC_WDISP19:
+ case R_SPARC_WDISP16:
+ /* If we are linking with -Bsymbolic, we do not need to copy
+ a PC relative reloc against a global symbol which is
+ defined in an object we are including in the link (i.e.,
+ DEF_REGULAR is set). FIXME: At this point we have not
+ seen all the input files, so it is possible that
+ DEF_REGULAR is not set now but will be set later (it is
+ never cleared). This needs to be handled as in
+ elf32-i386.c. */
+ if (h == NULL
+ || (info->symbolic
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ break;
+ /* Fall through. */
+ case R_SPARC_8:
+ case R_SPARC_16:
+ case R_SPARC_32:
+ case R_SPARC_HI22:
+ case R_SPARC_22:
+ case R_SPARC_13:
+ case R_SPARC_LO10:
+ case R_SPARC_UA32:
+ if (info->shared)
+ {
+ /* When creating a shared object, we must copy these
+ relocs into the output file. We create a reloc
+ section in dynobj and make room for the reloc. */
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ flagword flags;
+
+ sreloc = bfd_make_section (dynobj, name);
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc, flags)
+ || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+ return false;
+ }
+ }
+
+ sreloc->_raw_size += sizeof (Elf32_External_Rela);
+ }
+
+ break;
+
+ case R_SPARC_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ case R_SPARC_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+static asection *
+elf32_sparc_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_GNU_VTINHERIT:
+ case R_SPARC_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+static boolean
+elf32_sparc_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ case R_SPARC_PLT32:
+ case R_SPARC_HIPLT22:
+ case R_SPARC_LOPLT10:
+ case R_SPARC_PCPLT32:
+ case R_SPARC_PCPLT10:
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (h->plt.refcount > 0)
+ h->plt.refcount--;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+elf32_sparc_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj;
+ asection *s;
+ unsigned int power_of_two;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later
+ (although we could actually do it here). The STT_NOTYPE
+ condition is a hack specifically for the Oracle libraries
+ delivered for Solaris; for some inexplicable reason, they define
+ some of their functions as STT_NOTYPE when they really should be
+ STT_FUNC. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
+ || (h->type == STT_NOTYPE
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.section->flags & SEC_CODE) != 0))
+ {
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || ((!info->shared || info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ {
+ /* This case can occur if we saw a WPLT30 reloc in an input
+ file, but none of the input files were dynamic objects.
+ Or, when linking the main application or a -Bsymbolic
+ shared library against PIC code. Or when a global symbol
+ has been made private, e.g. via versioning.
+
+ In these cases we know what value the symbol will resolve
+ to, so we don't actually need to build a procedure linkage
+ table, and we can just do a WDISP30 reloc instead. */
+
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+ return true;
+ }
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* The first four entries in .plt are reserved. */
+ if (s->_raw_size == 0)
+ s->_raw_size = 4 * PLT_ENTRY_SIZE;
+
+ /* The procedure linkage table has a maximum size. */
+ if (s->_raw_size >= 0x400000)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+ }
+
+ h->plt.offset = s->_raw_size;
+
+ /* Make room for this entry. */
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += sizeof (Elf32_External_Rela);
+
+ return true;
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (info->shared)
+ return true;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_SPARC_COPY reloc to tell the dynamic linker
+ to copy the initial value out of the dynamic object and into the
+ runtime process image. We need to remember the offset into the
+ .rel.bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf32_External_Rela);
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ }
+
+ /* We need to figure out the alignment required for this symbol. I
+ have no idea how ELF linkers handle this. */
+ power_of_two = bfd_log2 (h->size);
+ if (power_of_two > 3)
+ power_of_two = 3;
+
+ /* Apply the required alignment. */
+ s->_raw_size = BFD_ALIGN (s->_raw_size,
+ (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ {
+ if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+ return false;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->_raw_size += h->size;
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+elf32_sparc_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean reltext;
+ boolean relplt;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (! info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+
+ /* Make space for the trailing nop in .plt. */
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+ if (s->_raw_size > 0)
+ s->_raw_size += 4;
+ }
+ else
+ {
+ /* We may have created entries in the .rela.got section.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rela.got,
+ which will cause it to get stripped from the output file
+ below. */
+ s = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (s != NULL)
+ s->_raw_size = 0;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ reltext = false;
+ relplt = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ strip = false;
+
+ if (strncmp (name, ".rela", 5) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is to handle .rela.bss and
+ .rel.plt. We must create it in
+ create_dynamic_sections, because it must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ strip = true;
+ }
+ else
+ {
+ const char *outname;
+ asection *target;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL entry. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 5);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ reltext = true;
+
+ if (strcmp (name, ".rela.plt") == 0)
+ relplt = true;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strcmp (name, ".plt") != 0
+ && strcmp (name, ".got") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ _bfd_strip_section_from_output (s);
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf32_sparc_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (! info->shared)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (relplt)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ return false;
+ }
+
+ if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
+ || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return false;
+
+ if (reltext)
+ {
+ if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ /* If we are generating a shared library, we generate a section
+ symbol for each output section for which we might need to copy
+ relocs. These are local symbols, which means that they must come
+ first in the dynamic symbol table. That means we must increment
+ the dynamic symbol index of every other dynamic symbol. */
+ if (info->shared)
+ {
+ int c;
+
+ c = 0;
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) != 0
+ || (s->flags & SEC_ALLOC) == 0)
+ continue;
+
+ elf_section_data (s)->dynindx = c + 1;
+
+ /* These symbols will have no names, so we don't need to
+ fiddle with dynstr_index. */
+
+ ++c;
+ }
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf32_sparc_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+ }
+
+ return true;
+}
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+
+static boolean
+elf32_sparc_adjust_dynindx (h, cparg)
+ struct elf_link_hash_entry *h;
+ PTR cparg;
+{
+ int *cp = (int *) cparg;
+
+ if (h->dynindx != -1)
+ h->dynindx += *cp;
+ return true;
+}
+
+/* Relocate a SPARC ELF section. */
+
+static boolean
+elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma got_base;
+ asection *sgot;
+ asection *splt;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ if (elf_hash_table (info)->hgot == NULL)
+ got_base = 0;
+ else
+ got_base = elf_hash_table (info)->hgot->root.u.def.value;
+
+ sgot = NULL;
+ splt = NULL;
+ sreloc = NULL;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_SPARC_GNU_VTINHERIT
+ || r_type == R_SPARC_GNU_VTENTRY)
+ continue;
+
+ if (r_type < 0 || r_type >= (int) R_SPARC_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto = _bfd_sparc_elf_howto_table + r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if ((r_type == R_SPARC_WPLT30
+ && h->plt.offset != (bfd_vma) -1)
+ || ((r_type == R_SPARC_GOT10
+ || r_type == R_SPARC_GOT13
+ || r_type == R_SPARC_GOT22)
+ && elf_hash_table (info)->dynamic_sections_created
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ && (r_type == R_SPARC_8
+ || r_type == R_SPARC_16
+ || r_type == R_SPARC_32
+ || r_type == R_SPARC_DISP8
+ || r_type == R_SPARC_DISP16
+ || r_type == R_SPARC_DISP32
+ || r_type == R_SPARC_WDISP30
+ || r_type == R_SPARC_WDISP22
+ || r_type == R_SPARC_WDISP19
+ || r_type == R_SPARC_WDISP16
+ || r_type == R_SPARC_HI22
+ || r_type == R_SPARC_22
+ || r_type == R_SPARC_13
+ || r_type == R_SPARC_LO10
+ || r_type == R_SPARC_UA32
+ || ((r_type == R_SPARC_PC10
+ || r_type == R_SPARC_PC22)
+ && strcmp (h->root.root.string,
+ "_GLOBAL_OFFSET_TABLE_") != 0))))
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ relocation = 0;
+ }
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined
+ locally, or the symbol was forced to be local
+ because of a version file. We must initialize
+ this entry in the global offset table. Since the
+ offset must always be a multiple of 4, we use the
+ least significant bit to record whether we have
+ initialized it already.
+
+ When doing a dynamic link, we create a .rela.got
+ relocation entry to initialize the value. This
+ is done in the finish_dynamic_symbol routine. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation,
+ sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off - got_base;
+ }
+ else
+ {
+ bfd_vma off;
+
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 4. We use
+ the least significant bit to record whether we have
+ already processed this entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_SPARC_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
+ outrel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ relocation = sgot->output_offset + off - got_base;
+ }
+
+ break;
+
+ case R_SPARC_WPLT30:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* The Solaris native assembler will generate a WPLT30 reloc
+ for a local symbol if you assemble a call from one
+ section to another when using -K pic. We treat it as
+ WDISP30. */
+ if (h == NULL)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ break;
+
+ case R_SPARC_PC10:
+ case R_SPARC_PC22:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_SPARC_DISP8:
+ case R_SPARC_DISP16:
+ case R_SPARC_DISP32:
+ case R_SPARC_WDISP30:
+ case R_SPARC_WDISP22:
+ case R_SPARC_WDISP19:
+ case R_SPARC_WDISP16:
+ if (h == NULL
+ || (info->symbolic
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0))
+ break;
+ /* Fall through. */
+ case R_SPARC_8:
+ case R_SPARC_16:
+ case R_SPARC_32:
+ case R_SPARC_HI22:
+ case R_SPARC_22:
+ case R_SPARC_13:
+ case R_SPARC_LO10:
+ case R_SPARC_UA32:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ boolean skip;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ /* h->dynindx may be -1 if the symbol was marked to
+ become local. */
+ else if (h != NULL
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_SPARC_32)
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ if (h == NULL)
+ sec = local_sections[r_symndx];
+ else
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || (h->root.type
+ == bfd_link_hash_defweak));
+ sec = h->root.u.def.section;
+ }
+ if (sec != NULL && bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+
+ /* FIXME: we really should be able to link non-pic
+ shared libraries. */
+ if (indx == 0)
+ {
+ BFD_FAIL ();
+ (*_bfd_error_handler)
+ (_("%s: probably compiled without -fPIC?"),
+ bfd_get_filename (input_bfd));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+
+ /* For non-RELATIVE dynamic relocations, we keep the
+ same symbol, and so generally the same addend. But
+ we do need to adjust those relocations referencing
+ sections. */
+ outrel.r_addend = rel->r_addend;
+ if (r_symndx < symtab_hdr->sh_info
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ outrel.r_addend += sec->output_offset+sym->st_value;
+ }
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (((Elf32_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, unless this is a RELATIVE
+ reloc in an unallocated section. */
+ if (skip
+ || (input_section->flags & SEC_ALLOC) != 0
+ || ELF32_R_TYPE (outrel.r_info) != R_SPARC_RELATIVE)
+ continue;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (r_type == R_SPARC_WDISP16)
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ relocation -= rel->r_offset;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x |= ((((relocation >> 2) & 0xc000) << 6)
+ | ((relocation >> 2) & 0x3fff));
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ if ((bfd_signed_vma) relocation < - 0x40000
+ || (bfd_signed_vma) relocation > 0x3ffff)
+ r = bfd_reloc_overflow;
+ else
+ r = bfd_reloc_ok;
+ }
+ else if (r_type == R_SPARC_REV32)
+ {
+ bfd_vma x;
+
+ relocation = relocation + rel->r_addend;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = x + relocation;
+ bfd_putl32 (/*input_bfd,*/ x, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ }
+ else
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (splt != NULL && srela != NULL);
+
+ /* Fill in the entry in the procedure linkage table. */
+ bfd_put_32 (output_bfd,
+ PLT_ENTRY_WORD0 + h->plt.offset,
+ splt->contents + h->plt.offset);
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD1
+ + (((- (h->plt.offset + 4)) >> 2) & 0x3fffff)),
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD2,
+ splt->contents + h->plt.offset + 8);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_JMP_SLOT);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) srela->contents
+ + h->plt.offset / PLT_ENTRY_SIZE - 4));
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srela = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ 1));
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. Likewise if
+ the symbol was forced to be local because of a version file.
+ The entry in the global offset table will already have been
+ initialized in the relocate_section function. */
+ if (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ rela.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_GLOB_DAT);
+ }
+
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) srela->contents
+ + srela->reloc_count));
+ ++srela->reloc_count;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rela.bss");
+ BFD_ASSERT (s != NULL);
+
+ rela.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_COPY);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela,
+ ((Elf32_External_Rela *) s->contents
+ + s->reloc_count));
+ ++s->reloc_count;
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
+ || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+elf32_sparc_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ boolean size;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT: name = ".plt"; size = false; break;
+ case DT_PLTRELSZ: name = ".rela.plt"; size = true; break;
+ case DT_JMPREL: name = ".rela.plt"; size = false; break;
+ default: name = NULL; size = false; break;
+ }
+
+ if (name != NULL)
+ {
+ asection *s;
+
+ s = bfd_get_section_by_name (output_bfd, name);
+ if (s == NULL)
+ dyn.d_un.d_val = 0;
+ else
+ {
+ if (! size)
+ dyn.d_un.d_ptr = s->vma;
+ else
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
+ else
+ dyn.d_un.d_val = s->_raw_size;
+ }
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+
+ /* Clear the first four entries in the procedure linkage table,
+ and put a nop in the last four bytes. */
+ if (splt->_raw_size > 0)
+ {
+ memset (splt->contents, 0, 4 * PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd, SPARC_NOP,
+ splt->contents + splt->_raw_size - 4);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize =
+ PLT_ENTRY_SIZE;
+ }
+
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ if (sgot->_raw_size > 0)
+ {
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgot->contents);
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ if (info->shared)
+ {
+ asection *sdynsym;
+ asection *s;
+ Elf_Internal_Sym sym;
+ int c;
+
+ /* Set up the section symbols for the output sections. */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (sdynsym != NULL);
+
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+
+ c = 0;
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx;
+
+ if (elf_section_data (s)->dynindx == 0)
+ continue;
+
+ sym.st_value = s->vma;
+
+ indx = elf_section_data (s)->this_idx;
+ BFD_ASSERT (indx > 0);
+ sym.st_shndx = indx;
+
+ bfd_elf32_swap_symbol_out (output_bfd, &sym,
+ (PTR) (((Elf32_External_Sym *)
+ sdynsym->contents)
+ + elf_section_data (s)->dynindx));
+
+ ++c;
+ }
+
+ /* Set the sh_info field of the output .dynsym section to the
+ index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
+ }
+
+ return true;
+}
+
+/* Functions for dealing with the e_flags field.
+
+ We don't define set_private_flags or copy_private_bfd_data because
+ the only currently defined values are based on the bfd mach number,
+ so we use the latter instead and defer setting e_flags until the
+ file is written out. */
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static boolean
+elf32_sparc_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ boolean error;
+ static int previous_ibfd_e_flags = -1;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ error = false;
+
+#if 0
+ /* ??? The native linker doesn't do this so we can't (otherwise gcc would
+ have to know which linker is being used). Instead, the native linker
+ bumps up the architecture level when it has to. However, I still think
+ warnings like these are good, so it would be nice to have them turned on
+ by some option. */
+
+ /* If the output machine is normal sparc, we can't allow v9 input files. */
+ if (bfd_get_mach (obfd) == bfd_mach_sparc
+ && (bfd_get_mach (ibfd) == bfd_mach_sparc_v8plus
+ || bfd_get_mach (ibfd) == bfd_mach_sparc_v8plusa))
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled for a v8plus system and target is v8"),
+ bfd_get_filename (ibfd));
+ }
+ /* If the output machine is v9, we can't allow v9+vis input files. */
+ if (bfd_get_mach (obfd) == bfd_mach_sparc_v8plus
+ && bfd_get_mach (ibfd) == bfd_mach_sparc_v8plusa)
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled for a v8plusa system and target is v8plus"),
+ bfd_get_filename (ibfd));
+ }
+#else
+ if (bfd_get_mach (ibfd) >= bfd_mach_sparc_v9)
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: compiled for a 64 bit system and target is 32 bit"),
+ bfd_get_filename (ibfd));
+ }
+ else if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
+ bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd));
+#endif
+
+ if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA)
+ != previous_ibfd_e_flags)
+ && previous_ibfd_e_flags >= 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: linking little endian files with big endian files"),
+ bfd_get_filename (ibfd));
+ error = true;
+ }
+ previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA;
+
+ if (error)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ return true;
+}
+
+/* Set the right machine number. */
+
+static boolean
+elf32_sparc_object_p (abfd)
+ bfd *abfd;
+{
+ if (elf_elfheader (abfd)->e_machine == EM_SPARC32PLUS)
+ {
+ if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
+ return bfd_default_set_arch_mach (abfd, bfd_arch_sparc,
+ bfd_mach_sparc_v8plusa);
+ else if (elf_elfheader (abfd)->e_flags & EF_SPARC_32PLUS)
+ return bfd_default_set_arch_mach (abfd, bfd_arch_sparc,
+ bfd_mach_sparc_v8plus);
+ else
+ return false;
+ }
+ else if (elf_elfheader (abfd)->e_flags & EF_SPARC_LEDATA)
+ return bfd_default_set_arch_mach (abfd, bfd_arch_sparc,
+ bfd_mach_sparc_sparclite_le);
+ else
+ return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
+}
+
+/* The final processing done just before writing out the object file.
+ We need to set the e_machine field appropriately. */
+
+static void
+elf32_sparc_final_write_processing (abfd, linker)
+ bfd *abfd;
+ boolean linker;
+{
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_sparc :
+ break; /* nothing to do */
+ case bfd_mach_sparc_v8plus :
+ elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
+ elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
+ elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS;
+ break;
+ case bfd_mach_sparc_v8plusa :
+ elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
+ elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
+ elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1;
+ break;
+ case bfd_mach_sparc_sparclite_le :
+ elf_elfheader (abfd)->e_machine = EM_SPARC;
+ elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA;
+ break;
+ default :
+ abort ();
+ break;
+ }
+}
+
+#define TARGET_BIG_SYM bfd_elf32_sparc_vec
+#define TARGET_BIG_NAME "elf32-sparc"
+#define ELF_ARCH bfd_arch_sparc
+#define ELF_MACHINE_CODE EM_SPARC
+#define ELF_MACHINE_ALT1 EM_SPARC32PLUS
+#define ELF_MAXPAGESIZE 0x10000
+
+#define bfd_elf32_bfd_reloc_type_lookup elf32_sparc_reloc_type_lookup
+#define elf_info_to_howto elf32_sparc_info_to_howto
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define elf_backend_check_relocs elf32_sparc_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ elf32_sparc_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ elf32_sparc_size_dynamic_sections
+#define elf_backend_relocate_section elf32_sparc_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elf32_sparc_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf32_sparc_finish_dynamic_sections
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ elf32_sparc_merge_private_bfd_data
+#define elf_backend_object_p elf32_sparc_object_p
+#define elf_backend_final_write_processing \
+ elf32_sparc_final_write_processing
+#define elf_backend_gc_mark_hook elf32_sparc_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_sparc_gc_sweep_hook
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 1
+#define elf_backend_got_header_size 4
+#define elf_backend_plt_header_size (4*PLT_ENTRY_SIZE)
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
new file mode 100644
index 00000000000..e71353df55f
--- /dev/null
+++ b/bfd/elf32-v850.c
@@ -0,0 +1,2230 @@
+/* V850-specific support for 32-bit ELF
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+
+/* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
+ dependencies. As is the gas & simulator code or the v850. */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/v850.h"
+
+/* sign-extend a 24-bit number */
+#define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
+
+static reloc_howto_type *v850_elf_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static void v850_elf_info_to_howto_rel
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static void v850_elf_info_to_howto_rela
+ PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
+static bfd_reloc_status_type v850_elf_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static boolean v850_elf_is_local_label_name
+ PARAMS ((bfd *, const char *));
+static boolean v850_elf_relocate_section
+ PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static bfd_reloc_status_type v850_elf_perform_relocation
+ PARAMS ((bfd *, int, bfd_vma, bfd_byte *));
+static boolean v850_elf_check_relocs
+ PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
+static void remember_hi16s_reloc
+ PARAMS ((bfd *, bfd_vma, bfd_byte *));
+static bfd_byte * find_remembered_hi16s_reloc
+ PARAMS ((bfd_vma, boolean *));
+static bfd_reloc_status_type v850_elf_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, bfd_vma,
+ bfd_vma, bfd_vma, struct bfd_link_info *, asection *, int));
+static boolean v850_elf_object_p
+ PARAMS ((bfd *));
+static boolean v850_elf_fake_sections
+ PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
+static void v850_elf_final_write_processing
+ PARAMS ((bfd *, boolean));
+static boolean v850_elf_set_private_flags
+ PARAMS ((bfd *, flagword));
+static boolean v850_elf_copy_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean v850_elf_merge_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+static boolean v850_elf_print_private_bfd_data
+ PARAMS ((bfd *, PTR));
+static boolean v850_elf_section_from_bfd_section
+ PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *));
+static void v850_elf_symbol_processing
+ PARAMS ((bfd *, asymbol *));
+static boolean v850_elf_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+static boolean v850_elf_link_output_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const char *,
+ Elf_Internal_Sym *, asection *));
+static boolean v850_elf_section_from_shdr
+ PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
+
+/* Note: It is REQUIRED that the 'type' value of each entry in this array
+ match the index of the entry in the array. */
+static reloc_howto_type v850_elf_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_V850_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_V850_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A PC relative 9 bit branch. */
+ HOWTO (R_V850_9_PCREL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_9_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A PC relative 22 bit branch. */
+ HOWTO (R_V850_22_PCREL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 22, /* bitsize */
+ true, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_22_PCREL", /* name */
+ false, /* partial_inplace */
+ 0x07ffff80, /* src_mask */
+ 0x07ffff80, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_V850_HI16_S, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_HI16_S", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_V850_HI16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_HI16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_V850_LO16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_LO16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Simple 32bit reloc. */
+ HOWTO (R_V850_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Simple 16bit reloc. */
+ HOWTO (R_V850_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_V850_16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Simple 8bit reloc. */
+ HOWTO (R_V850_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_V850_8", /* name */
+ true, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit offset from the short data area pointer. */
+ HOWTO (R_V850_SDA_16_16_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_SDA_16_16_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 15 bit offset from the short data area pointer. */
+ HOWTO (R_V850_SDA_15_16_OFFSET, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_SDA_15_16_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0xfffe, /* src_mask */
+ 0xfffe, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit offset from the zero data area pointer. */
+ HOWTO (R_V850_ZDA_16_16_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_ZDA_16_16_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 15 bit offset from the zero data area pointer. */
+ HOWTO (R_V850_ZDA_15_16_OFFSET, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_ZDA_15_16_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0xfffe, /* src_mask */
+ 0xfffe, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 6 bit offset from the tiny data area pointer. */
+ HOWTO (R_V850_TDA_6_8_OFFSET, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_TDA_6_8_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0x7e, /* src_mask */
+ 0x7e, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 8 bit offset from the tiny data area pointer. */
+ HOWTO (R_V850_TDA_7_8_OFFSET, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_TDA_7_8_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0x7f, /* src_mask */
+ 0x7f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 7 bit offset from the tiny data area pointer. */
+ HOWTO (R_V850_TDA_7_7_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_TDA_7_7_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0x7f, /* src_mask */
+ 0x7f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit offset from the tiny data area pointer! */
+ HOWTO (R_V850_TDA_16_16_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_TDA_16_16_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xfff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 5 bit offset from the tiny data area pointer. */
+ HOWTO (R_V850_TDA_4_5_OFFSET, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_TDA_4_5_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0x0f, /* src_mask */
+ 0x0f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 4 bit offset from the tiny data area pointer. */
+ HOWTO (R_V850_TDA_4_4_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_TDA_4_4_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0x0f, /* src_mask */
+ 0x0f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit offset from the short data area pointer. */
+ HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */
+ false, /* partial_inplace */
+ 0xfffe0020, /* src_mask */
+ 0xfffe0020, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit offset from the zero data area pointer. */
+ HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */
+ false, /* partial_inplace */
+ 0xfffe0020, /* src_mask */
+ 0xfffe0020, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 6 bit offset from the call table base pointer. */
+ HOWTO (R_V850_CALLT_6_7_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_CALLT_6_7_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0x3f, /* src_mask */
+ 0x3f, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit offset from the call table base pointer. */
+ HOWTO (R_V850_CALLT_16_16_OFFSET, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ v850_elf_reloc, /* special_function */
+ "R_V850_CALLT_16_16_OFFSET", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_V850_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_V850_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_V850_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_V850_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to V850 ELF reloc types. */
+
+struct v850_elf_reloc_map
+{
+ /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an
+ unsigned char. */
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_V850_NONE },
+ { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL },
+ { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL },
+ { BFD_RELOC_HI16_S, R_V850_HI16_S },
+ { BFD_RELOC_HI16, R_V850_HI16 },
+ { BFD_RELOC_LO16, R_V850_LO16 },
+ { BFD_RELOC_32, R_V850_32 },
+ { BFD_RELOC_16, R_V850_16 },
+ { BFD_RELOC_8, R_V850_8 },
+ { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET },
+ { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET },
+ { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET },
+ { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET },
+ { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET },
+ { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET },
+ { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET },
+ { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
+ { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET },
+ { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET },
+ { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
+ { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
+ { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET },
+ { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET },
+ { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY },
+
+};
+
+
+/* Map a bfd relocation into the appropriate howto structure */
+static reloc_howto_type *
+v850_elf_reloc_type_lookup (abfd, code)
+ bfd * abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map);
+ i++)
+ {
+ if (v850_elf_reloc_map[i].bfd_reloc_val == code)
+ {
+ BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val);
+
+ return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val];
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Set the howto pointer for an V850 ELF reloc. */
+static void
+v850_elf_info_to_howto_rel (abfd, cache_ptr, dst)
+ bfd * abfd;
+ arelent * cache_ptr;
+ Elf32_Internal_Rel * dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_V850_max);
+ cache_ptr->howto = &v850_elf_howto_table[r_type];
+}
+
+/* Set the howto pointer for a V850 ELF reloc (type RELA). */
+static void
+v850_elf_info_to_howto_rela (abfd, cache_ptr, dst)
+ bfd * abfd;
+ arelent * cache_ptr;
+ Elf32_Internal_Rela *dst;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_V850_max);
+ cache_ptr->howto = &v850_elf_howto_table[r_type];
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static boolean
+v850_elf_check_relocs (abfd, info, sec, relocs)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ asection * sec;
+ const Elf_Internal_Rela * relocs;
+{
+ boolean ret = true;
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sreloc;
+ enum v850_reloc_type r_type;
+ int other = 0;
+ const char *common = (const char *)0;
+
+ if (info->relocateable)
+ return true;
+
+#ifdef DEBUG
+ fprintf (stderr, "v850_elf_check_relocs called for section %s in %s\n",
+ bfd_get_section_name (abfd, sec),
+ bfd_get_filename (abfd));
+#endif
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ default:
+ case R_V850_NONE:
+ case R_V850_9_PCREL:
+ case R_V850_22_PCREL:
+ case R_V850_HI16_S:
+ case R_V850_HI16:
+ case R_V850_LO16:
+ case R_V850_32:
+ case R_V850_16:
+ case R_V850_8:
+ case R_V850_CALLT_6_7_OFFSET:
+ case R_V850_CALLT_16_16_OFFSET:
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_V850_GNU_VTINHERIT:
+ if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return false;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_V850_GNU_VTENTRY:
+ if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return false;
+ break;
+
+ case R_V850_SDA_16_16_SPLIT_OFFSET:
+ case R_V850_SDA_16_16_OFFSET:
+ case R_V850_SDA_15_16_OFFSET:
+ other = V850_OTHER_SDA;
+ common = ".scommon";
+ goto small_data_common;
+
+ case R_V850_ZDA_16_16_SPLIT_OFFSET:
+ case R_V850_ZDA_16_16_OFFSET:
+ case R_V850_ZDA_15_16_OFFSET:
+ other = V850_OTHER_ZDA;
+ common = ".zcommon";
+ goto small_data_common;
+
+ case R_V850_TDA_4_5_OFFSET:
+ case R_V850_TDA_4_4_OFFSET:
+ case R_V850_TDA_6_8_OFFSET:
+ case R_V850_TDA_7_8_OFFSET:
+ case R_V850_TDA_7_7_OFFSET:
+ case R_V850_TDA_16_16_OFFSET:
+ other = V850_OTHER_TDA;
+ common = ".tcommon";
+ /* fall through */
+
+#define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
+
+ small_data_common:
+ if (h)
+ {
+ h->other |= other; /* flag which type of relocation was used */
+ if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
+ && (h->other & V850_OTHER_ERROR) == 0)
+ {
+ const char * msg;
+ static char buff[200]; /* XXX */
+
+ switch (h->other & V850_OTHER_MASK)
+ {
+ default:
+ msg = _("Variable `%s' cannot occupy in multiple small data regions");
+ break;
+ case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
+ msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
+ break;
+ case V850_OTHER_SDA | V850_OTHER_ZDA:
+ msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
+ break;
+ case V850_OTHER_SDA | V850_OTHER_TDA:
+ msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
+ break;
+ case V850_OTHER_ZDA | V850_OTHER_TDA:
+ msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
+ break;
+ }
+
+ sprintf (buff, msg, h->root.root.string);
+ info->callbacks->warning (info, buff, h->root.root.string,
+ abfd, h->root.u.def.section, 0);
+
+ bfd_set_error (bfd_error_bad_value);
+ h->other |= V850_OTHER_ERROR;
+ ret = false;
+ }
+ }
+
+ if (h && h->root.type == bfd_link_hash_common
+ && h->root.u.c.p
+ && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
+ {
+ asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
+ section->flags |= SEC_IS_COMMON;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
+ v850_elf_howto_table[ (int)r_type ].name,
+ (h && h->root.root.string) ? h->root.root.string : "<unknown>",
+ (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
+#endif
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * In the old version, when an entry was checked out from the table,
+ * it was deleted. This produced an error if the entry was needed
+ * more than once, as the second attempted retry failed.
+ *
+ * In the current version, the entry is not deleted, instead we set
+ * the field 'found' to true. If a second lookup matches the same
+ * entry, then we know that the hi16s reloc has already been updated
+ * and does not need to be updated a second time.
+ *
+ * TODO - TOFIX: If it is possible that we need to restore 2 different
+ * addresses from the same table entry, where the first generates an
+ * overflow, whilst the second do not, then this code will fail.
+ */
+
+typedef struct hi16s_location
+{
+ bfd_vma addend;
+ bfd_byte * address;
+ unsigned long counter;
+ boolean found;
+ struct hi16s_location * next;
+}
+hi16s_location;
+
+static hi16s_location * previous_hi16s;
+static hi16s_location * free_hi16s;
+static unsigned long hi16s_counter;
+
+static void
+remember_hi16s_reloc (abfd, addend, address)
+ bfd * abfd;
+ bfd_vma addend;
+ bfd_byte * address;
+{
+ hi16s_location * entry = NULL;
+
+ /* Find a free structure. */
+ if (free_hi16s == NULL)
+ free_hi16s = (hi16s_location *) bfd_zalloc (abfd, sizeof (* free_hi16s));
+
+ entry = free_hi16s;
+ free_hi16s = free_hi16s->next;
+
+ entry->addend = addend;
+ entry->address = address;
+ entry->counter = hi16s_counter ++;
+ entry->found = false;
+ entry->next = previous_hi16s;
+ previous_hi16s = entry;
+
+ /* Cope with wrap around of our counter. */
+ if (hi16s_counter == 0)
+ {
+ /* XXX - Assume that all counter entries differ only in their low 16 bits. */
+ for (entry = previous_hi16s; entry != NULL; entry = entry->next)
+ entry->counter &= 0xffff;
+
+ hi16s_counter = 0x10000;
+ }
+
+ return;
+}
+
+static bfd_byte *
+find_remembered_hi16s_reloc (addend, already_found)
+ bfd_vma addend;
+ boolean * already_found;
+{
+ hi16s_location * match = NULL;
+ hi16s_location * entry;
+ hi16s_location * previous = NULL;
+ hi16s_location * prev;
+ int i;
+ bfd_byte * addr;
+
+ /* Search the table. Record the most recent entry that matches. */
+ for (entry = previous_hi16s; entry; entry = entry->next)
+ {
+ if (entry->addend == addend
+ && (match == NULL || match->counter < entry->counter))
+ {
+ previous = prev;
+ match = entry;
+ }
+
+ prev = entry;
+ }
+
+ if (match == NULL)
+ return NULL;
+
+ /* Extract the address. */
+ addr = match->address;
+
+ /* Remeber if this entry has already been used before. */
+ if (already_found)
+ * already_found = match->found;
+
+ /* Note that this entry has now been used. */
+ match->found = true;
+
+ return addr;
+}
+
+/* FIXME: The code here probably ought to be removed and the code in reloc.c
+ allowed to do its stuff instead. At least for most of the relocs, anwyay. */
+static bfd_reloc_status_type
+v850_elf_perform_relocation (abfd, r_type, addend, address)
+ bfd * abfd;
+ int r_type;
+ bfd_vma addend;
+ bfd_byte * address;
+{
+ unsigned long insn;
+ bfd_signed_vma saddend = (bfd_signed_vma) addend;
+
+ switch (r_type)
+ {
+ default:
+ /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */
+ return bfd_reloc_notsupported;
+
+ case R_V850_32:
+ bfd_put_32 (abfd, addend, address);
+ return bfd_reloc_ok;
+
+ case R_V850_22_PCREL:
+ if (saddend > 0x1fffff || saddend < -0x200000)
+ return bfd_reloc_overflow;
+
+ if ((addend % 2) != 0)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_32 (abfd, address);
+ insn &= ~0xfffe003f;
+ insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
+ bfd_put_32 (abfd, insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_9_PCREL:
+ if (saddend > 0xff || saddend < -0x100)
+ return bfd_reloc_overflow;
+
+ if ((addend % 2) != 0)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, address);
+ insn &= ~ 0xf870;
+ insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
+ break;
+
+ case R_V850_HI16:
+ addend += (bfd_get_16 (abfd, address) << 16);
+ addend = (addend >> 16);
+ insn = addend;
+ break;
+
+ case R_V850_HI16_S:
+ /* Remember where this relocation took place. */
+ remember_hi16s_reloc (abfd, addend, address);
+
+ addend += (bfd_get_16 (abfd, address) << 16);
+ addend = (addend >> 16) + ((addend & 0x8000) != 0);
+
+ /* This relocation cannot overflow. */
+ if (addend > 0x7fff)
+ addend = 0;
+
+ insn = addend;
+ break;
+
+ case R_V850_LO16:
+ /* Calculate the sum of the value stored in the instruction and the
+ addend and check for overflow from the low 16 bits into the high
+ 16 bits. The assembler has already done some of this: If the
+ value stored in the instruction has its 15th bit set, (counting
+ from zero) then the assembler will have added 1 to the value
+ stored in the associated HI16S reloc. So for example, these
+ relocations:
+
+ movhi hi( fred ), r0, r1
+ movea lo( fred ), r1, r1
+
+ will store 0 in the value fields for the MOVHI and MOVEA instructions
+ and addend will be the address of fred, but for these instructions:
+
+ movhi hi( fred + 0x123456), r0, r1
+ movea lo( fred + 0x123456), r1, r1
+
+ the value stored in the MOVHI instruction will be 0x12 and the value
+ stored in the MOVEA instruction will be 0x3456. If however the
+ instructions were:
+
+ movhi hi( fred + 0x10ffff), r0, r1
+ movea lo( fred + 0x10ffff), r1, r1
+
+ then the value stored in the MOVHI instruction would be 0x11 (not
+ 0x10) and the value stored in the MOVEA instruction would be 0xffff.
+ Thus (assuming for the moment that the addend is 0), at run time the
+ MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
+ adds 0xffffffff (sign extension!) producing 0x10ffff. Similarly if
+ the instructions were:
+
+ movhi hi( fred - 1), r0, r1
+ movea lo( fred - 1), r1, r1
+
+ then 0 is stored in the MOVHI instruction and -1 is stored in the
+ MOVEA instruction.
+
+ Overflow can occur if the addition of the value stored in the
+ instruction plus the addend sets the 15th bit when before it was clear.
+ This is because the 15th bit will be sign extended into the high part,
+ thus reducing its value by one, but since the 15th bit was originally
+ clear, the assembler will not have added 1 to the previous HI16S reloc
+ to compensate for this effect. For example:
+
+ movhi hi( fred + 0x123456), r0, r1
+ movea lo( fred + 0x123456), r1, r1
+
+ The value stored in HI16S reloc is 0x12, the value stored in the LO16
+ reloc is 0x3456. If we assume that the address of fred is 0x00007000
+ then the relocations become:
+
+ HI16S: 0x0012 + (0x00007000 >> 16) = 0x12
+ LO16: 0x3456 + (0x00007000 & 0xffff) = 0xa456
+
+ but when the instructions are executed, the MOVEA instruction's value
+ is signed extended, so the sum becomes:
+
+ 0x00120000
+ + 0xffffa456
+ ------------
+ 0x0011a456 but 'fred + 0x123456' = 0x0012a456
+
+ Note that if the 15th bit was set in the value stored in the LO16
+ reloc, then we do not have to do anything:
+
+ movhi hi( fred + 0x10ffff), r0, r1
+ movea lo( fred + 0x10ffff), r1, r1
+
+ HI16S: 0x0011 + (0x00007000 >> 16) = 0x11
+ LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff
+
+ 0x00110000
+ + 0x00006fff
+ ------------
+ 0x00116fff = fred + 0x10ffff = 0x7000 + 0x10ffff
+
+
+ Overflow can also occur if the computation carries into the 16th bit
+ and it also results in the 15th bit having the same value as the 15th
+ bit of the original value. What happens is that the HI16S reloc
+ will have already examined the 15th bit of the original value and
+ added 1 to the high part if the bit is set. This compensates for the
+ sign extension of 15th bit of the result of the computation. But now
+ there is a carry into the 16th bit, and this has not been allowed for.
+
+ So, for example if fred is at address 0xf000:
+
+ movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
+ movea lo( fred + 0xffff), r1, r1
+
+ HI16S: 0x0001 + (0x0000f000 >> 16) = 0x0001
+ LO16: 0xffff + (0x0000f000 & 0xffff) = 0xefff (carry into bit 16 is lost)
+
+ 0x00010000
+ + 0xffffefff
+ ------------
+ 0x0000efff but 'fred + 0xffff' = 0x0001efff
+
+ Similarly, if the 15th bit remains clear, but overflow occurs into
+ the 16th bit then (assuming the address of fred is 0xf000):
+
+ movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
+ movea lo( fred + 0x7000), r1, r1
+
+ HI16S: 0x0000 + (0x0000f000 >> 16) = 0x0000
+ LO16: 0x7000 + (0x0000f000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
+
+ 0x00000000
+ + 0x00006fff
+ ------------
+ 0x00006fff but 'fred + 0x7000' = 0x00016fff
+
+ Note - there is no need to change anything if a carry occurs, and the
+ 15th bit changes its value from being set to being clear, as the HI16S
+ reloc will have already added in 1 to the high part for us:
+
+ movhi hi( fred + 0xffff), r0, r1 [bit 15 of the offset is set]
+ movea lo( fred + 0xffff), r1, r1
+
+ HI16S: 0x0001 + (0x00007000 >> 16)
+ LO16: 0xffff + (0x00007000 & 0xffff) = 0x6fff (carry into bit 16 is lost)
+
+ 0x00010000
+ + 0x00006fff (bit 15 not set, so the top half is zero)
+ ------------
+ 0x00016fff which is right (assuming that fred is at 0x7000)
+
+ but if the 15th bit goes from being clear to being set, then we must
+ once again handle overflow:
+
+ movhi hi( fred + 0x7000), r0, r1 [bit 15 of the offset is clear]
+ movea lo( fred + 0x7000), r1, r1
+
+ HI16S: 0x0000 + (0x0000ffff >> 16)
+ LO16: 0x7000 + (0x0000ffff & 0xffff) = 0x6fff (carry into bit 16)
+
+ 0x00000000
+ + 0x00006fff (bit 15 not set, so the top half is zero)
+ ------------
+ 0x00006fff which is wrong (assuming that fred is at 0xffff)
+ */
+
+ {
+ long result;
+
+ insn = bfd_get_16 (abfd, address);
+ result = insn + addend;
+
+#define BIT15_SET(x) ((x) & 0x8000)
+#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
+
+ if ((BIT15_SET (result) && ! BIT15_SET (addend))
+ || (OVERFLOWS (addend, insn)
+ && ((! BIT15_SET (insn)) || (BIT15_SET (addend)))))
+ {
+ boolean already_updated;
+ bfd_byte * hi16s_address = find_remembered_hi16s_reloc
+ (addend, & already_updated);
+
+ /* Amend the matching HI16_S relocation. */
+ if (hi16s_address != NULL)
+ {
+ if (! already_updated)
+ {
+ insn = bfd_get_16 (abfd, hi16s_address);
+ insn += 1;
+ bfd_put_16 (abfd, insn, hi16s_address);
+ }
+ }
+ else
+ {
+ fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
+ return bfd_reloc_overflow;
+ }
+ }
+
+ /* Do not complain if value has top bit set, as this has been anticipated. */
+ insn = result & 0xffff;
+ break;
+ }
+
+ case R_V850_8:
+ addend += (char) bfd_get_8 (abfd, address);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x7f || saddend < -0x80)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (abfd, addend, address);
+ return bfd_reloc_ok;
+
+ case R_V850_CALLT_16_16_OFFSET:
+ addend += bfd_get_16 (abfd, address);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0xffff || saddend < 0)
+ return bfd_reloc_overflow;
+
+ insn = addend;
+ break;
+
+ case R_V850_16:
+
+ /* drop through */
+ case R_V850_SDA_16_16_OFFSET:
+ case R_V850_ZDA_16_16_OFFSET:
+ case R_V850_TDA_16_16_OFFSET:
+ addend += bfd_get_16 (abfd, address);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x7fff || saddend < -0x8000)
+ return bfd_reloc_overflow;
+
+ insn = addend;
+ break;
+
+ case R_V850_SDA_15_16_OFFSET:
+ case R_V850_ZDA_15_16_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += (insn & 0xfffe);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x7ffe || saddend < -0x8000)
+ return bfd_reloc_overflow;
+
+ if (addend & 1)
+ return bfd_reloc_dangerous;
+
+ insn = (addend & ~1) | (insn & 1);
+ break;
+
+ case R_V850_TDA_6_8_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += ((insn & 0x7e) << 1);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0xfc || saddend < 0)
+ return bfd_reloc_overflow;
+
+ if (addend & 3)
+ return bfd_reloc_dangerous;
+
+ insn &= 0xff81;
+ insn |= (addend >> 1);
+ break;
+
+ case R_V850_TDA_7_8_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += ((insn & 0x7f) << 1);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0xfe || saddend < 0)
+ return bfd_reloc_overflow;
+
+ if (addend & 1)
+ return bfd_reloc_dangerous;
+
+ insn &= 0xff80;
+ insn |= (addend >> 1);
+ break;
+
+ case R_V850_TDA_7_7_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += insn & 0x7f;
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x7f || saddend < 0)
+ return bfd_reloc_overflow;
+
+ insn &= 0xff80;
+ insn |= addend;
+ break;
+
+ case R_V850_TDA_4_5_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += ((insn & 0xf) << 1);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x1e || saddend < 0)
+ return bfd_reloc_overflow;
+
+ if (addend & 1)
+ return bfd_reloc_dangerous;
+
+ insn &= 0xfff0;
+ insn |= (addend >> 1);
+ break;
+
+ case R_V850_TDA_4_4_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += insn & 0xf;
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0xf || saddend < 0)
+ return bfd_reloc_overflow;
+
+ insn &= 0xfff0;
+ insn |= addend;
+ break;
+
+ case R_V850_ZDA_16_16_SPLIT_OFFSET:
+ case R_V850_SDA_16_16_SPLIT_OFFSET:
+ insn = bfd_get_32 (abfd, address);
+ addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x7fff || saddend < -0x8000)
+ return bfd_reloc_overflow;
+
+ insn &= 0x0001ffdf;
+ insn |= (addend & 1) << 5;
+ insn |= (addend & ~1) << 16;
+
+ bfd_put_32 (abfd, insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_CALLT_6_7_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+ addend += ((insn & 0x3f) << 1);
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0x7e || saddend < 0)
+ return bfd_reloc_overflow;
+
+ if (addend & 1)
+ return bfd_reloc_dangerous;
+
+ insn &= 0xff80;
+ insn |= (addend >> 1);
+ break;
+
+ case R_V850_GNU_VTINHERIT:
+ case R_V850_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ }
+
+ bfd_put_16 (abfd, insn, address);
+ return bfd_reloc_ok;
+}
+
+
+/* Insert the addend into the instruction. */
+static bfd_reloc_status_type
+v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
+ bfd * abfd;
+ arelent * reloc;
+ asymbol * symbol;
+ PTR data;
+ asection * isection;
+ bfd * obfd;
+ char ** err;
+{
+ long relocation;
+
+ /* If there is an output BFD,
+ and the symbol is not a section name (which is only defined at final link time),
+ and either we are not putting the addend into the instruction
+ or the addend is zero, so there is nothing to add into the instruction
+ then just fixup the address and return. */
+ if (obfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc->howto->partial_inplace
+ || reloc->addend == 0))
+ {
+ reloc->address += isection->output_offset;
+ return bfd_reloc_ok;
+ }
+#if 0
+ else if (obfd != NULL)
+ {
+ return bfd_reloc_continue;
+ }
+#endif
+
+ /* Catch relocs involving undefined symbols. */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && obfd == NULL)
+ return bfd_reloc_undefined;
+
+ /* We handle final linking of some relocs ourselves. */
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc->address > isection->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ /* Convert input-section-relative symbol value to absolute + addend. */
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc->addend;
+
+ if (reloc->howto->pc_relative == true)
+ {
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+ relocation -= isection->output_section->vma + isection->output_offset;
+
+ /* Deal with pcrel_offset */
+ relocation -= reloc->address;
+ }
+
+ reloc->addend = relocation;
+ return bfd_reloc_ok;
+}
+
+
+/*ARGSUSED*/
+static boolean
+v850_elf_is_local_label_name (abfd, name)
+ bfd * abfd;
+ const char * name;
+{
+ return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
+ || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
+}
+
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, offset, value,
+ addend, info, sym_sec, is_local)
+ reloc_howto_type * howto;
+ bfd * input_bfd;
+ bfd * output_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ bfd_vma offset;
+ bfd_vma value;
+ bfd_vma addend;
+ struct bfd_link_info * info;
+ asection * sym_sec;
+ int is_local;
+{
+ unsigned long r_type = howto->type;
+ bfd_byte * hit_data = contents + offset;
+
+ /* Adjust the value according to the relocation. */
+ switch (r_type)
+ {
+ case R_V850_9_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ break;
+
+ case R_V850_22_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+
+ value = SEXT24 (value); /* Only the bottom 24 bits of the PC are valid */
+ break;
+
+ case R_V850_HI16_S:
+ case R_V850_HI16:
+ case R_V850_LO16:
+ case R_V850_16:
+ case R_V850_32:
+ case R_V850_8:
+ break;
+
+ case R_V850_ZDA_15_16_OFFSET:
+ case R_V850_ZDA_16_16_OFFSET:
+ case R_V850_ZDA_16_16_SPLIT_OFFSET:
+ if (sym_sec == NULL)
+ return bfd_reloc_undefined;
+
+ value -= sym_sec->output_section->vma;
+ break;
+
+ case R_V850_SDA_15_16_OFFSET:
+ case R_V850_SDA_16_16_OFFSET:
+ case R_V850_SDA_16_16_SPLIT_OFFSET:
+ {
+ unsigned long gp;
+ struct bfd_link_hash_entry * h;
+
+ if (sym_sec == NULL)
+ return bfd_reloc_undefined;
+
+ /* Get the value of __gp. */
+ h = bfd_link_hash_lookup (info->hash, "__gp", false, false, true);
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || h->type != bfd_link_hash_defined)
+ return bfd_reloc_other;
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= sym_sec->output_section->vma;
+ value -= (gp - sym_sec->output_section->vma);
+ }
+ break;
+
+ case R_V850_TDA_4_4_OFFSET:
+ case R_V850_TDA_4_5_OFFSET:
+ case R_V850_TDA_16_16_OFFSET:
+ case R_V850_TDA_7_7_OFFSET:
+ case R_V850_TDA_7_8_OFFSET:
+ case R_V850_TDA_6_8_OFFSET:
+ {
+ unsigned long ep;
+ struct bfd_link_hash_entry * h;
+
+ /* Get the value of __ep. */
+ h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || h->type != bfd_link_hash_defined)
+ return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */
+
+ ep = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= ep;
+ }
+ break;
+
+ case R_V850_CALLT_6_7_OFFSET:
+ {
+ unsigned long ctbp;
+ struct bfd_link_hash_entry * h;
+
+ /* Get the value of __ctbp. */
+ h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || h->type != bfd_link_hash_defined)
+ return (bfd_reloc_dangerous + 1); /* Actually this indicates that __ctbp could not be found. */
+
+ ctbp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ value -= ctbp;
+ }
+ break;
+
+ case R_V850_CALLT_16_16_OFFSET:
+ {
+ unsigned long ctbp;
+ struct bfd_link_hash_entry * h;
+
+ if (sym_sec == NULL)
+ return bfd_reloc_undefined;
+
+ /* Get the value of __ctbp. */
+ h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true);
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || h->type != bfd_link_hash_defined)
+ return (bfd_reloc_dangerous + 1);
+
+ ctbp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= sym_sec->output_section->vma;
+ value -= (ctbp - sym_sec->output_section->vma);
+ }
+ break;
+
+ case R_V850_NONE:
+ case R_V850_GNU_VTINHERIT:
+ case R_V850_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ /* Perform the relocation. */
+ return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
+}
+
+
+/* Relocate an V850 ELF section. */
+static boolean
+v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd * output_bfd;
+ struct bfd_link_info * info;
+ bfd * input_bfd;
+ asection * input_section;
+ bfd_byte * contents;
+ Elf_Internal_Rela * relocs;
+ Elf_Internal_Sym * local_syms;
+ asection ** local_sections;
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ if (sym_hashes == NULL)
+ {
+ info->callbacks->warning
+ (info, "no hash table available", NULL, input_bfd, input_section, 0);
+
+ return false;
+ }
+
+ /* Reset the list of remembered HI16S relocs to empty. */
+ free_hi16s = previous_hi16s;
+ previous_hi16s = NULL;
+ hi16s_counter = 0;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type * howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym * sym;
+ asection * sec;
+ struct elf_link_hash_entry * h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_V850_GNU_VTENTRY
+ || r_type == R_V850_GNU_VTINHERIT)
+ continue;
+
+ howto = v850_elf_howto_table + r_type;
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+#if 0
+ {
+ char * name;
+ name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (name == NULL) ? "<none>" : name;
+fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ sec->name, name, sym->st_name,
+ sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend);
+ }
+#endif
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+#if 0
+fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
+ sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
+#endif
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ {
+#if 0
+fprintf (stderr, "undefined: sec: %s, name: %s\n",
+ sec->name, h->root.root.string);
+#endif
+ relocation = 0;
+ }
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+#if 0
+fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
+#endif
+ relocation = 0;
+ }
+ }
+
+ /* FIXME: We should use the addend, but the COFF relocations
+ don't. */
+ r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ info, sec, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * name;
+ const char * msg = (const char *)0;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL || *name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_undefined:
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ msg = _("internal error: dangerous relocation");
+ goto common_error;
+
+ case bfd_reloc_other:
+ msg = _("could not locate special linker symbol __gp");
+ goto common_error;
+
+ case bfd_reloc_continue:
+ msg = _("could not locate special linker symbol __ep");
+ goto common_error;
+
+ case (bfd_reloc_dangerous + 1):
+ msg = _("could not locate special linker symbol __ctbp");
+ goto common_error;
+
+ default:
+ msg = _("internal error: unknown error");
+ /* fall through */
+
+ common_error:
+ if (!((*info->callbacks->warning)
+ (info, msg, name, input_bfd, input_section,
+ rel->r_offset)))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+static boolean
+v850_elf_gc_sweep_hook (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ /* No got and plt entries for v850-elf */
+ return true;
+}
+
+static asection *
+v850_elf_gc_mark_hook (abfd, info, rel, h, sym)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ Elf_Internal_Rela *rel;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ if (h != NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_V850_GNU_VTINHERIT:
+ case R_V850_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
+ }
+ }
+ }
+ else
+ {
+ if (!(elf_bad_symtab (abfd)
+ && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+ && sym->st_shndx != SHN_COMMON))
+ {
+ return bfd_section_from_elf_index (abfd, sym->st_shndx);
+ }
+ }
+ return NULL;
+}
+/* Set the right machine number. */
+static boolean
+v850_elf_object_p (abfd)
+ bfd *abfd;
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
+ {
+ default:
+ case E_V850_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
+ case E_V850E_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
+ case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;
+ }
+ return true;
+}
+
+/* Store the machine number in the flags field. */
+static void
+v850_elf_final_write_processing (abfd, linker)
+ bfd * abfd;
+ boolean linker;
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case 0: val = E_V850_ARCH; break;
+ case bfd_mach_v850e: val = E_V850E_ARCH; break;
+ case bfd_mach_v850ea: val = E_V850EA_ARCH; break;
+ }
+
+ elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+/* Function to keep V850 specific file flags. */
+static boolean
+v850_elf_set_private_flags (abfd, flags)
+ bfd * abfd;
+ flagword flags;
+{
+ BFD_ASSERT (!elf_flags_init (abfd)
+ || elf_elfheader (abfd)->e_flags == flags);
+
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = true;
+ return true;
+}
+
+/* Copy backend specific data from one object module to another */
+static boolean
+v850_elf_copy_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ BFD_ASSERT (!elf_flags_init (obfd)
+ || (elf_elfheader (obfd)->e_flags
+ == elf_elfheader (ibfd)->e_flags));
+
+ elf_gp (obfd) = elf_gp (ibfd);
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = true;
+ return true;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static boolean
+v850_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd * ibfd;
+ bfd * obfd;
+{
+ flagword out_flags;
+ flagword in_flags;
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd))
+ {
+ /* If the input is the default architecture then do not
+ bother setting the flags for the output architecture,
+ instead allow future merges to do this. If no future
+ merges ever set these flags then they will retain their
+ unitialised values, which surprise surprise, correspond
+ to the default values. */
+ if (bfd_get_arch_info (ibfd)->the_default)
+ return true;
+
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = in_flags;
+
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
+ && bfd_get_arch_info (obfd)->the_default)
+ {
+ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
+ }
+
+ return true;
+ }
+
+ /* Check flag compatibility. */
+ if (in_flags == out_flags)
+ return true;
+
+ if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
+ && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
+ _bfd_error_handler (_("%s: Architecture mismatch with previous modules"),
+ bfd_get_filename (ibfd));
+
+ return true;
+}
+/* Display the flags field */
+
+static boolean
+v850_elf_print_private_bfd_data (abfd, ptr)
+ bfd * abfd;
+ PTR ptr;
+{
+ FILE * file = (FILE *) ptr;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ /* xgettext:c-format */
+ fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
+
+ switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
+ {
+ default:
+ case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
+ case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
+ case E_V850EA_ARCH: fprintf (file, _("v850ea architecture")); break;
+ }
+
+ fputc ('\n', file);
+
+ return true;
+}
+
+/* V850 ELF uses four common sections. One is the usual one, and the
+ others are for (small) objects in one of the special data areas:
+ small, tiny and zero. All the objects are kept together, and then
+ referenced via the gp register, the ep register or the r0 register
+ respectively, which yields smaller, faster assembler code. This
+ approach is copied from elf32-mips.c. */
+
+static asection v850_elf_scom_section;
+static asymbol v850_elf_scom_symbol;
+static asymbol * v850_elf_scom_symbol_ptr;
+static asection v850_elf_tcom_section;
+static asymbol v850_elf_tcom_symbol;
+static asymbol * v850_elf_tcom_symbol_ptr;
+static asection v850_elf_zcom_section;
+static asymbol v850_elf_zcom_symbol;
+static asymbol * v850_elf_zcom_symbol_ptr;
+
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. */
+
+static boolean
+v850_elf_section_from_bfd_section (abfd, hdr, sec, retval)
+ bfd * abfd;
+ Elf32_Internal_Shdr * hdr;
+ asection * sec;
+ int * retval;
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+ *retval = SHN_V850_SCOMMON;
+ else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
+ *retval = SHN_V850_TCOMMON;
+ else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
+ *retval = SHN_V850_ZCOMMON;
+ else
+ return false;
+
+ return true;
+}
+
+/* Handle the special V850 section numbers that a symbol may use. */
+
+static void
+v850_elf_symbol_processing (abfd, asym)
+ bfd * abfd;
+ asymbol * asym;
+{
+ elf_symbol_type * elfsym = (elf_symbol_type *) asym;
+ unsigned short index;
+
+ index = elfsym->internal_elf_sym.st_shndx;
+
+ /* If the section index is an "ordinary" index, then it may
+ refer to a v850 specific section created by the assembler.
+ Check the section's type and change the index it matches.
+
+ FIXME: Should we alter the st_shndx field as well ? */
+
+ if (index < elf_elfheader(abfd)[0].e_shnum)
+ switch (elf_elfsections(abfd)[index]->sh_type)
+ {
+ case SHT_V850_SCOMMON:
+ index = SHN_V850_SCOMMON;
+ break;
+
+ case SHT_V850_TCOMMON:
+ index = SHN_V850_TCOMMON;
+ break;
+
+ case SHT_V850_ZCOMMON:
+ index = SHN_V850_ZCOMMON;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (index)
+ {
+ case SHN_V850_SCOMMON:
+ if (v850_elf_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ v850_elf_scom_section.name = ".scommon";
+ v850_elf_scom_section.flags = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
+ v850_elf_scom_section.output_section = & v850_elf_scom_section;
+ v850_elf_scom_section.symbol = & v850_elf_scom_symbol;
+ v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
+ v850_elf_scom_symbol.name = ".scommon";
+ v850_elf_scom_symbol.flags = BSF_SECTION_SYM;
+ v850_elf_scom_symbol.section = & v850_elf_scom_section;
+ v850_elf_scom_symbol_ptr = & v850_elf_scom_symbol;
+ }
+ asym->section = & v850_elf_scom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+
+ case SHN_V850_TCOMMON:
+ if (v850_elf_tcom_section.name == NULL)
+ {
+ /* Initialize the tcommon section. */
+ v850_elf_tcom_section.name = ".tcommon";
+ v850_elf_tcom_section.flags = SEC_IS_COMMON;
+ v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
+ v850_elf_tcom_section.symbol = & v850_elf_tcom_symbol;
+ v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
+ v850_elf_tcom_symbol.name = ".tcommon";
+ v850_elf_tcom_symbol.flags = BSF_SECTION_SYM;
+ v850_elf_tcom_symbol.section = & v850_elf_tcom_section;
+ v850_elf_tcom_symbol_ptr = & v850_elf_tcom_symbol;
+ }
+ asym->section = & v850_elf_tcom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+
+ case SHN_V850_ZCOMMON:
+ if (v850_elf_zcom_section.name == NULL)
+ {
+ /* Initialize the zcommon section. */
+ v850_elf_zcom_section.name = ".zcommon";
+ v850_elf_zcom_section.flags = SEC_IS_COMMON;
+ v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
+ v850_elf_zcom_section.symbol = & v850_elf_zcom_symbol;
+ v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
+ v850_elf_zcom_symbol.name = ".zcommon";
+ v850_elf_zcom_symbol.flags = BSF_SECTION_SYM;
+ v850_elf_zcom_symbol.section = & v850_elf_zcom_section;
+ v850_elf_zcom_symbol_ptr = & v850_elf_zcom_symbol;
+ }
+ asym->section = & v850_elf_zcom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+ }
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must handle the special v850 section numbers here. */
+
+/*ARGSUSED*/
+static boolean
+v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ const Elf_Internal_Sym * sym;
+ const char ** namep;
+ flagword * flagsp;
+ asection ** secp;
+ bfd_vma * valp;
+{
+ int index = sym->st_shndx;
+
+ /* If the section index is an "ordinary" index, then it may
+ refer to a v850 specific section created by the assembler.
+ Check the section's type and change the index it matches.
+
+ FIXME: Should we alter the st_shndx field as well ? */
+
+ if (index < elf_elfheader(abfd)[0].e_shnum)
+ switch (elf_elfsections(abfd)[index]->sh_type)
+ {
+ case SHT_V850_SCOMMON:
+ index = SHN_V850_SCOMMON;
+ break;
+
+ case SHT_V850_TCOMMON:
+ index = SHN_V850_TCOMMON;
+ break;
+
+ case SHT_V850_ZCOMMON:
+ index = SHN_V850_ZCOMMON;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (index)
+ {
+ case SHN_V850_SCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".scommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+
+ case SHN_V850_TCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".tcommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+
+ case SHN_V850_ZCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".zcommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return true;
+}
+
+/*ARGSIGNORED*/
+static boolean
+v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
+ bfd * abfd;
+ struct bfd_link_info * info;
+ const char * name;
+ Elf_Internal_Sym * sym;
+ asection * input_sec;
+{
+ /* If we see a common symbol, which implies a relocatable link, then
+ if a symbol was in a special common section in an input file, mark
+ it as a special common in the output file. */
+
+ if (sym->st_shndx == SHN_COMMON)
+ {
+ if (strcmp (input_sec->name, ".scommon") == 0)
+ sym->st_shndx = SHN_V850_SCOMMON;
+ else if (strcmp (input_sec->name, ".tcommon") == 0)
+ sym->st_shndx = SHN_V850_TCOMMON;
+ else if (strcmp (input_sec->name, ".zcommon") == 0)
+ sym->st_shndx = SHN_V850_ZCOMMON;
+ }
+
+ return true;
+}
+
+static boolean
+v850_elf_section_from_shdr (abfd, hdr, name)
+ bfd * abfd;
+ Elf_Internal_Shdr * hdr;
+ char * name;
+{
+ /* There ought to be a place to keep ELF backend specific flags, but
+ at the moment there isn't one. We just keep track of the
+ sections by their name, instead. */
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+
+ switch (hdr->sh_type)
+ {
+ case SHT_V850_SCOMMON:
+ case SHT_V850_TCOMMON:
+ case SHT_V850_ZCOMMON:
+ if (! bfd_set_section_flags (abfd, hdr->bfd_section,
+ (bfd_get_section_flags (abfd,
+ hdr->bfd_section)
+ | SEC_IS_COMMON)))
+ return false;
+ }
+
+ return true;
+}
+
+/* Set the correct type for a V850 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+static boolean
+v850_elf_fake_sections (abfd, hdr, sec)
+ bfd * abfd;
+ Elf32_Internal_Shdr * hdr;
+ asection * sec;
+{
+ register const char * name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".scommon") == 0)
+ {
+ hdr->sh_type = SHT_V850_SCOMMON;
+ }
+ else if (strcmp (name, ".tcommon") == 0)
+ {
+ hdr->sh_type = SHT_V850_TCOMMON;
+ }
+ else if (strcmp (name, ".zcommon") == 0)
+ hdr->sh_type = SHT_V850_ZCOMMON;
+
+ return true;
+}
+
+
+
+#define TARGET_LITTLE_SYM bfd_elf32_v850_vec
+#define TARGET_LITTLE_NAME "elf32-v850"
+#define ELF_ARCH bfd_arch_v850
+#define ELF_MACHINE_CODE EM_CYGNUS_V850
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_info_to_howto v850_elf_info_to_howto_rela
+#define elf_info_to_howto_rel v850_elf_info_to_howto_rel
+
+#define elf_backend_check_relocs v850_elf_check_relocs
+#define elf_backend_relocate_section v850_elf_relocate_section
+#define elf_backend_object_p v850_elf_object_p
+#define elf_backend_final_write_processing v850_elf_final_write_processing
+#define elf_backend_section_from_bfd_section v850_elf_section_from_bfd_section
+#define elf_backend_symbol_processing v850_elf_symbol_processing
+#define elf_backend_add_symbol_hook v850_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook v850_elf_link_output_symbol_hook
+#define elf_backend_section_from_shdr v850_elf_section_from_shdr
+#define elf_backend_fake_sections v850_elf_fake_sections
+#define elf_backend_gc_mark_hook v850_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook v850_elf_gc_sweep_hook
+
+#define elf_backend_can_gc_sections 1
+
+
+#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
+#define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
+#define bfd_elf32_bfd_copy_private_bfd_data v850_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data v850_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags v850_elf_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data v850_elf_print_private_bfd_data
+
+#define elf_symbol_leading_char '_'
+
+#include "elf32-target.h"
diff --git a/bfd/elf32.c b/bfd/elf32.c
new file mode 100644
index 00000000000..f2229694406
--- /dev/null
+++ b/bfd/elf32.c
@@ -0,0 +1,23 @@
+/* ELF 32-bit executable support for BFD.
+ Copyright 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 32
+
+
+#include "elfcode.h"
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
new file mode 100644
index 00000000000..1964f86e859
--- /dev/null
+++ b/bfd/elf64-alpha.c
@@ -0,0 +1,4768 @@
+/* Alpha specific support for 64-bit ELF
+ Copyright 1996, 97, 98, 1999 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@tamu.edu>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* We need a published ABI spec for this. Until one comes out, don't
+ assume this'll remain unchanged forever. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+#include "elf/alpha.h"
+
+#define ALPHAECOFF
+
+#define NO_COFF_RELOCS
+#define NO_COFF_SYMBOLS
+#define NO_COFF_LINENOS
+
+/* Get the ECOFF swapping routines. Needed for the debug information. */
+#include "coff/internal.h"
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff.h"
+#include "coff/alpha.h"
+#include "aout/ar.h"
+#include "libcoff.h"
+#include "libecoff.h"
+#define ECOFF_64
+#include "ecoffswap.h"
+
+static boolean elf64_alpha_mkobject PARAMS ((bfd *));
+static struct bfd_hash_entry * elf64_alpha_link_hash_newfunc
+ PARAMS((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table * elf64_alpha_bfd_link_hash_table_create
+ PARAMS((bfd *));
+
+static bfd_reloc_status_type elf64_alpha_reloc_nil
+ PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type elf64_alpha_reloc_bad
+ PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type elf64_alpha_do_reloc_gpdisp
+ PARAMS((bfd *, bfd_vma, bfd_byte *, bfd_byte *));
+static bfd_reloc_status_type elf64_alpha_reloc_gpdisp
+ PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static reloc_howto_type * elf64_alpha_bfd_reloc_type_lookup
+ PARAMS((bfd *, bfd_reloc_code_real_type));
+static void elf64_alpha_info_to_howto
+ PARAMS((bfd *, arelent *, Elf64_Internal_Rela *));
+
+static boolean elf64_alpha_object_p
+ PARAMS((bfd *));
+static boolean elf64_alpha_section_from_shdr
+ PARAMS((bfd *, Elf64_Internal_Shdr *, char *));
+static boolean elf64_alpha_fake_sections
+ PARAMS((bfd *, Elf64_Internal_Shdr *, asection *));
+static boolean elf64_alpha_create_got_section
+ PARAMS((bfd *, struct bfd_link_info *));
+static boolean elf64_alpha_create_dynamic_sections
+ PARAMS((bfd *, struct bfd_link_info *));
+
+static boolean elf64_alpha_read_ecoff_info
+ PARAMS((bfd *, asection *, struct ecoff_debug_info *));
+static boolean elf64_alpha_is_local_label_name
+ PARAMS((bfd *, const char *));
+static boolean elf64_alpha_find_nearest_line
+ PARAMS((bfd *, asection *, asymbol **, bfd_vma, const char **,
+ const char **, unsigned int *));
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct alpha_elf_link_hash_entry;
+#endif
+
+static boolean elf64_alpha_output_extsym
+ PARAMS((struct alpha_elf_link_hash_entry *, PTR));
+
+static boolean elf64_alpha_can_merge_gots
+ PARAMS((bfd *, bfd *));
+static void elf64_alpha_merge_gots
+ PARAMS((bfd *, bfd *));
+static boolean elf64_alpha_calc_got_offsets_for_symbol
+ PARAMS ((struct alpha_elf_link_hash_entry *, PTR));
+static void elf64_alpha_calc_got_offsets PARAMS ((struct bfd_link_info *));
+static boolean elf64_alpha_size_got_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf64_alpha_always_size_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf64_alpha_calc_dynrel_sizes
+ PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *));
+static boolean elf64_alpha_add_symbol_hook
+ PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *));
+static boolean elf64_alpha_check_relocs
+ PARAMS((bfd *, struct bfd_link_info *, asection *sec,
+ const Elf_Internal_Rela *));
+static boolean elf64_alpha_adjust_dynamic_symbol
+ PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean elf64_alpha_size_dynamic_sections
+ PARAMS((bfd *, struct bfd_link_info *));
+static boolean elf64_alpha_adjust_dynindx
+ PARAMS((struct elf_link_hash_entry *, PTR));
+static boolean elf64_alpha_relocate_section
+ PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean elf64_alpha_finish_dynamic_symbol
+ PARAMS((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *));
+static boolean elf64_alpha_finish_dynamic_sections
+ PARAMS((bfd *, struct bfd_link_info *));
+static boolean elf64_alpha_final_link
+ PARAMS((bfd *, struct bfd_link_info *));
+
+
+struct alpha_elf_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* External symbol information. */
+ EXTR esym;
+
+ /* Cumulative flags for all the .got entries. */
+ int flags;
+
+ /* Contexts (LITUSE) in which a literal was referenced. */
+#define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01
+#define ALPHA_ELF_LINK_HASH_LU_MEM 0x02
+#define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04
+#define ALPHA_ELF_LINK_HASH_LU_FUNC 0x08
+
+ /* Used to implement multiple .got subsections. */
+ struct alpha_elf_got_entry
+ {
+ struct alpha_elf_got_entry *next;
+
+ /* which .got subsection? */
+ bfd *gotobj;
+
+ /* the addend in effect for this entry. */
+ bfd_vma addend;
+
+ /* the .got offset for this entry. */
+ int got_offset;
+
+ int flags;
+
+ /* An additional flag. */
+#define ALPHA_ELF_GOT_ENTRY_RELOCS_DONE 0x10
+
+ int use_count;
+ } *got_entries;
+
+ /* used to count non-got, non-plt relocations for delayed sizing
+ of relocation sections. */
+ struct alpha_elf_reloc_entry
+ {
+ struct alpha_elf_reloc_entry *next;
+
+ /* which .reloc section? */
+ asection *srel;
+
+ /* what kind of relocation? */
+ unsigned long rtype;
+
+ /* how many did we find? */
+ unsigned long count;
+ } *reloc_entries;
+};
+
+/* Alpha ELF linker hash table. */
+
+struct alpha_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* The head of a list of .got subsections linked through
+ alpha_elf_tdata(abfd)->got_link_next. */
+ bfd *got_list;
+};
+
+/* Look up an entry in a Alpha ELF linker hash table. */
+
+#define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct alpha_elf_link_hash_entry *) \
+ elf_link_hash_lookup (&(table)->root, (string), (create), \
+ (copy), (follow)))
+
+/* Traverse a Alpha ELF linker hash table. */
+
+#define alpha_elf_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the Alpha ELF linker hash table from a link_info structure. */
+
+#define alpha_elf_hash_table(p) \
+ ((struct alpha_elf_link_hash_table *) ((p)->hash))
+
+/* Get the object's symbols as our own entry type. */
+
+#define alpha_elf_sym_hashes(abfd) \
+ ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
+
+/* Should we do dynamic things to this symbol? */
+
+#define alpha_elf_dynamic_symbol_p(h, info) \
+ ((((info)->shared && !(info)->symbolic) \
+ || (((h)->elf_link_hash_flags \
+ & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)) \
+ == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)) \
+ || (h)->root.type == bfd_link_hash_undefweak \
+ || (h)->root.type == bfd_link_hash_defweak) \
+ && (h)->dynindx != -1)
+
+/* Create an entry in a Alpha ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf64_alpha_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct alpha_elf_link_hash_entry *ret =
+ (struct alpha_elf_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct alpha_elf_link_hash_entry *) NULL)
+ ret = ((struct alpha_elf_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct alpha_elf_link_hash_entry)));
+ if (ret == (struct alpha_elf_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct alpha_elf_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct alpha_elf_link_hash_entry *) NULL)
+ {
+ /* Set local fields. */
+ memset (&ret->esym, 0, sizeof (EXTR));
+ /* We use -2 as a marker to indicate that the information has
+ not been set. -1 means there is no associated ifd. */
+ ret->esym.ifd = -2;
+ ret->flags = 0;
+ ret->got_entries = NULL;
+ ret->reloc_entries = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a Alpha ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf64_alpha_bfd_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct alpha_elf_link_hash_table *ret;
+
+ ret = ((struct alpha_elf_link_hash_table *)
+ bfd_zalloc (abfd, sizeof (struct alpha_elf_link_hash_table)));
+ if (ret == (struct alpha_elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf64_alpha_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+/* We have some private fields hanging off of the elf_tdata structure. */
+
+struct alpha_elf_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* For every input file, these are the got entries for that object's
+ local symbols. */
+ struct alpha_elf_got_entry ** local_got_entries;
+
+ /* For every input file, this is the object that owns the got that
+ this input file uses. */
+ bfd *gotobj;
+
+ /* For every got, this is a linked list through the objects using this got */
+ bfd *in_got_link_next;
+
+ /* For every got, this is a link to the next got subsegment. */
+ bfd *got_link_next;
+
+ /* For every got, this is the section. */
+ asection *got;
+
+ /* For every got, this is it's total number of *entries*. */
+ int total_got_entries;
+
+ /* For every got, this is the sum of the number of *entries* required
+ to hold all of the member object's local got. */
+ int n_local_got_entries;
+};
+
+#define alpha_elf_tdata(abfd) \
+ ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
+
+static boolean
+elf64_alpha_mkobject (abfd)
+ bfd *abfd;
+{
+ abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata));
+ if (abfd->tdata.any == NULL)
+ return false;
+ return true;
+}
+
+static boolean
+elf64_alpha_object_p (abfd)
+ bfd *abfd;
+{
+ /* Allocate our special target data. */
+ struct alpha_elf_obj_tdata *new_tdata;
+ new_tdata = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata));
+ if (new_tdata == NULL)
+ return false;
+ new_tdata->root = *abfd->tdata.elf_obj_data;
+ abfd->tdata.any = new_tdata;
+
+ /* Set the right machine number for an Alpha ELF file. */
+ return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
+}
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+ from smaller values. Start with zero, widen, *then* decrement. */
+#define MINUS_ONE (((bfd_vma)0) - 1)
+
+static reloc_howto_type elf64_alpha_howto_table[] =
+{
+ HOWTO (R_ALPHA_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_nil, /* special_function */
+ "NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 32 bit reference to a symbol. */
+ HOWTO (R_ALPHA_REFLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "REFLONG", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit reference to a symbol. */
+ HOWTO (R_ALPHA_REFQUAD, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "REFQUAD", /* name */
+ false, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit GP relative offset. This is just like REFLONG except
+ that when the value is used the value of the gp register will be
+ added in. */
+ HOWTO (R_ALPHA_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "GPREL32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Used for an instruction that refers to memory off the GP register. */
+ HOWTO (R_ALPHA_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "ELF_LITERAL", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* This reloc only appears immediately following an ELF_LITERAL reloc.
+ It identifies a use of the literal. The symbol index is special:
+ 1 means the literal address is in the base register of a memory
+ format instruction; 2 means the literal address is in the byte
+ offset register of a byte-manipulation instruction; 3 means the
+ literal address is in the target register of a jsr instruction.
+ This does not actually do any relocation. */
+ HOWTO (R_ALPHA_LITUSE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_nil, /* special_function */
+ "LITUSE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Load the gp register. This is always used for a ldah instruction
+ which loads the upper 16 bits of the gp register. The symbol
+ index of the GPDISP instruction is an offset in bytes to the lda
+ instruction that loads the lower 16 bits. The value to use for
+ the relocation is the difference between the GP value and the
+ current location; the load will always be done against a register
+ holding the current address.
+
+ NOTE: Unlike ECOFF, partial in-place relocation is not done. If
+ any offset is present in the instructions, it is an offset from
+ the register to the ldah instruction. This lets us avoid any
+ stupid hackery like inventing a gp value to do partial relocation
+ against. Also unlike ECOFF, we do the whole relocation off of
+ the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd,
+ space consuming bit, that, since all the information was present
+ in the GPDISP_HI16 reloc. */
+ HOWTO (R_ALPHA_GPDISP, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_gpdisp, /* special_function */
+ "GPDISP", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 21 bit branch. */
+ HOWTO (R_ALPHA_BRADDR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "BRADDR", /* name */
+ false, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A hint for a jump to a register. */
+ HOWTO (R_ALPHA_HINT, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "HINT", /* name */
+ false, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 16 bit PC relative offset. */
+ HOWTO (R_ALPHA_SREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative offset. */
+ HOWTO (R_ALPHA_SREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit PC relative offset. */
+ HOWTO (R_ALPHA_SREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL64", /* name */
+ false, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Push a value on the reloc evaluation stack. */
+ /* Not implemented -- it's dumb. */
+ HOWTO (R_ALPHA_OP_PUSH, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "OP_PUSH", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Store the value from the stack at the given address. Store it in
+ a bitfield of size r_size starting at bit position r_offset. */
+ /* Not implemented -- it's dumb. */
+ HOWTO (R_ALPHA_OP_STORE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "OP_STORE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Subtract the reloc address from the value on the top of the
+ relocation stack. */
+ /* Not implemented -- it's dumb. */
+ HOWTO (R_ALPHA_OP_PSUB, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "OP_PSUB", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Shift the value on the top of the relocation stack right by the
+ given value. */
+ /* Not implemented -- it's dumb. */
+ HOWTO (R_ALPHA_OP_PRSHIFT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "OP_PRSHIFT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Change the value of GP used by +r_addend until the next GPVALUE or the
+ end of the input bfd. */
+ /* Not implemented -- it's dumb. */
+ HOWTO (R_ALPHA_GPVALUE,
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "GPVALUE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high 16 bits of the displacement from GP to the target. */
+ HOWTO (R_ALPHA_GPRELHIGH,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "GPRELHIGH", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The low 16 bits of the displacement from GP to the target. */
+ HOWTO (R_ALPHA_GPRELLOW,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "GPRELLOW", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 16-bit displacement from the GP to the target. */
+ /* XXX: Not implemented. */
+ HOWTO (R_ALPHA_IMMED_GP_16,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "IMMED_GP_16", /* name */
+ false, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high bits of a 32-bit displacement from the GP to the target; the
+ low bits are supplied in the subsequent R_ALPHA_IMMED_LO32 relocs. */
+ /* XXX: Not implemented. */
+ HOWTO (R_ALPHA_IMMED_GP_HI32,
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "IMMED_GP_HI32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high bits of a 32-bit displacement to the starting address of the
+ current section (the relocation target is ignored); the low bits are
+ supplied in the subsequent R_ALPHA_IMMED_LO32 relocs. */
+ /* XXX: Not implemented. */
+ HOWTO (R_ALPHA_IMMED_SCN_HI32,
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "IMMED_SCN_HI32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The high bits of a 32-bit displacement from the previous br, bsr, jsr
+ or jmp insn (as tagged by a BRADDR or HINT reloc) to the target; the
+ low bits are supplied by subsequent R_ALPHA_IMMED_LO32 relocs. */
+ /* XXX: Not implemented. */
+ HOWTO (R_ALPHA_IMMED_BR_HI32,
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "IMMED_BR_HI32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* The low 16 bits of a displacement calculated in a previous HI32 reloc. */
+ /* XXX: Not implemented. */
+ HOWTO (R_ALPHA_IMMED_LO32,
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ elf64_alpha_reloc_bad, /* special_function */
+ "IMMED_LO32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Misc ELF relocations. */
+
+ /* A dynamic relocation to copy the target into our .dynbss section. */
+ /* Not generated, as all Alpha objects use PIC, so it is not needed. It
+ is present because every other ELF has one, but should not be used
+ because .dynbss is an ugly thing. */
+ HOWTO (R_ALPHA_COPY,
+ 0,
+ 0,
+ 0,
+ false,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "COPY",
+ false,
+ 0,
+ 0,
+ true),
+
+ /* A dynamic relocation for a .got entry. */
+ HOWTO (R_ALPHA_GLOB_DAT,
+ 0,
+ 0,
+ 0,
+ false,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "GLOB_DAT",
+ false,
+ 0,
+ 0,
+ true),
+
+ /* A dynamic relocation for a .plt entry. */
+ HOWTO (R_ALPHA_JMP_SLOT,
+ 0,
+ 0,
+ 0,
+ false,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "JMP_SLOT",
+ false,
+ 0,
+ 0,
+ true),
+
+ /* A dynamic relocation to add the base of the DSO to a 64-bit field. */
+ HOWTO (R_ALPHA_RELATIVE,
+ 0,
+ 0,
+ 0,
+ false,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "RELATIVE",
+ false,
+ 0,
+ 0,
+ true)
+};
+
+/* A relocation function which doesn't do anything. */
+
+static bfd_reloc_status_type
+elf64_alpha_reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc;
+ asymbol *sym;
+ PTR data;
+ asection *sec;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd)
+ reloc->address += sec->output_offset;
+ return bfd_reloc_ok;
+}
+
+/* A relocation function used for an unsupported reloc. */
+
+static bfd_reloc_status_type
+elf64_alpha_reloc_bad (abfd, reloc, sym, data, sec, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc;
+ asymbol *sym;
+ PTR data;
+ asection *sec;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd)
+ reloc->address += sec->output_offset;
+ return bfd_reloc_notsupported;
+}
+
+/* Do the work of the GPDISP relocation. */
+
+static bfd_reloc_status_type
+elf64_alpha_do_reloc_gpdisp (abfd, gpdisp, p_ldah, p_lda)
+ bfd *abfd;
+ bfd_vma gpdisp;
+ bfd_byte *p_ldah;
+ bfd_byte *p_lda;
+{
+ bfd_reloc_status_type ret = bfd_reloc_ok;
+ bfd_vma addend;
+ unsigned long i_ldah, i_lda;
+
+ i_ldah = bfd_get_32 (abfd, p_ldah);
+ i_lda = bfd_get_32 (abfd, p_lda);
+
+ /* Complain if the instructions are not correct. */
+ if (((i_ldah >> 26) & 0x3f) != 0x09
+ || ((i_lda >> 26) & 0x3f) != 0x08)
+ ret = bfd_reloc_dangerous;
+
+ /* Extract the user-supplied offset, mirroring the sign extensions
+ that the instructions perform. */
+ addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
+ addend = (addend ^ 0x80008000) - 0x80008000;
+
+ gpdisp += addend;
+
+ if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
+ || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
+ ret = bfd_reloc_overflow;
+
+ /* compensate for the sign extension again. */
+ i_ldah = ((i_ldah & 0xffff0000)
+ | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
+ i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
+
+ bfd_put_32 (abfd, i_ldah, p_ldah);
+ bfd_put_32 (abfd, i_lda, p_lda);
+
+ return ret;
+}
+
+/* The special function for the GPDISP reloc. */
+
+static bfd_reloc_status_type
+elf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section,
+ output_bfd, err_msg)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *sym;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **err_msg;
+{
+ bfd_reloc_status_type ret;
+ bfd_vma gp, relocation;
+ bfd_byte *p_ldah, *p_lda;
+
+ /* Don't do anything if we're not doing a final link. */
+ if (output_bfd)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (reloc_entry->address > input_section->_cooked_size ||
+ reloc_entry->address + reloc_entry->addend > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* The gp used in the portion of the output object to which this
+ input object belongs is cached on the input bfd. */
+ gp = _bfd_get_gp_value (abfd);
+
+ relocation = (input_section->output_section->vma
+ + input_section->output_offset
+ + reloc_entry->address);
+
+ p_ldah = (bfd_byte *) data + reloc_entry->address;
+ p_lda = p_ldah + reloc_entry->addend;
+
+ ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
+
+ /* Complain if the instructions are not correct. */
+ if (ret == bfd_reloc_dangerous)
+ *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
+
+ return ret;
+}
+
+/* A mapping from BFD reloc types to Alpha ELF reloc types. */
+
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ int elf_reloc_val;
+};
+
+static const struct elf_reloc_map elf64_alpha_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_ALPHA_NONE},
+ {BFD_RELOC_32, R_ALPHA_REFLONG},
+ {BFD_RELOC_64, R_ALPHA_REFQUAD},
+ {BFD_RELOC_CTOR, R_ALPHA_REFQUAD},
+ {BFD_RELOC_GPREL32, R_ALPHA_GPREL32},
+ {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL},
+ {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE},
+ {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP},
+ {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR},
+ {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT},
+ {BFD_RELOC_16_PCREL, R_ALPHA_SREL16},
+ {BFD_RELOC_32_PCREL, R_ALPHA_SREL32},
+ {BFD_RELOC_64_PCREL, R_ALPHA_SREL64},
+};
+
+/* Given a BFD reloc type, return a HOWTO structure. */
+
+static reloc_howto_type *
+elf64_alpha_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ const struct elf_reloc_map *i, *e;
+ i = e = elf64_alpha_reloc_map;
+ e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
+ for (; i != e; ++i)
+ {
+ if (i->bfd_reloc_val == code)
+ return &elf64_alpha_howto_table[i->elf_reloc_val];
+ }
+ return 0;
+}
+
+/* Given an Alpha ELF reloc type, fill in an arelent structure. */
+
+static void
+elf64_alpha_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf64_Internal_Rela *dst;
+{
+ unsigned r_type;
+
+ r_type = ELF64_R_TYPE(dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
+ cache_ptr->howto = &elf64_alpha_howto_table[r_type];
+}
+
+/* These functions do relaxation for Alpha ELF.
+
+ Currently I'm only handling what I can do with existing compiler
+ and assembler support, which means no instructions are removed,
+ though some may be nopped. At this time GCC does not emit enough
+ information to do all of the relaxing that is possible. It will
+ take some not small amount of work for that to happen.
+
+ There are a couple of interesting papers that I once read on this
+ subject, that I cannot find references to at the moment, that
+ related to Alpha in particular. They are by David Wall, then of
+ DEC WRL. */
+
+#define OP_LDA 0x08
+#define OP_LDAH 0x09
+#define INSN_JSR 0x68004000
+#define INSN_JSR_MASK 0xfc00c000
+#define OP_LDQ 0x29
+#define OP_BR 0x30
+#define OP_BSR 0x34
+#define INSN_UNOP 0x2fe00000
+
+struct alpha_relax_info
+{
+ bfd *abfd;
+ asection *sec;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs, *relend;
+ struct bfd_link_info *link_info;
+ boolean changed_contents;
+ boolean changed_relocs;
+ bfd_vma gp;
+ bfd *gotobj;
+ asection *tsec;
+ struct alpha_elf_link_hash_entry *h;
+ struct alpha_elf_got_entry *gotent;
+ unsigned char other;
+};
+
+static Elf_Internal_Rela * elf64_alpha_relax_with_lituse
+ PARAMS((struct alpha_relax_info *info, bfd_vma symval,
+ Elf_Internal_Rela *irel, Elf_Internal_Rela *irelend));
+
+static boolean elf64_alpha_relax_without_lituse
+ PARAMS((struct alpha_relax_info *info, bfd_vma symval,
+ Elf_Internal_Rela *irel));
+
+static bfd_vma elf64_alpha_relax_opt_call
+ PARAMS((struct alpha_relax_info *info, bfd_vma symval));
+
+static boolean elf64_alpha_relax_section
+ PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
+ boolean *again));
+
+static Elf_Internal_Rela *
+elf64_alpha_find_reloc_at_ofs (rel, relend, offset, type)
+ Elf_Internal_Rela *rel, *relend;
+ bfd_vma offset;
+ int type;
+{
+ while (rel < relend)
+ {
+ if (rel->r_offset == offset && ELF64_R_TYPE (rel->r_info) == type)
+ return rel;
+ ++rel;
+ }
+ return NULL;
+}
+
+static Elf_Internal_Rela *
+elf64_alpha_relax_with_lituse (info, symval, irel, irelend)
+ struct alpha_relax_info *info;
+ bfd_vma symval;
+ Elf_Internal_Rela *irel, *irelend;
+{
+ Elf_Internal_Rela *urel;
+ int flags, count, i;
+ bfd_signed_vma disp;
+ boolean fits16;
+ boolean fits32;
+ boolean lit_reused = false;
+ boolean all_optimized = true;
+ unsigned int lit_insn;
+
+ lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
+ if (lit_insn >> 26 != OP_LDQ)
+ {
+ ((*_bfd_error_handler)
+ ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
+ bfd_get_filename (info->abfd), info->sec->name,
+ (unsigned long)irel->r_offset));
+ return irel;
+ }
+
+ /* Summarize how this particular LITERAL is used. */
+ for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
+ {
+ if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
+ break;
+ if (urel->r_addend >= 0 && urel->r_addend <= 3)
+ flags |= 1 << urel->r_addend;
+ }
+
+ /* A little preparation for the loop... */
+ disp = symval - info->gp;
+ fits16 = (disp >= -(bfd_signed_vma)0x8000 && disp < 0x8000);
+ fits32 = (disp >= -(bfd_signed_vma)0x80000000 && disp < 0x7fff8000);
+
+ for (urel = irel+1, i = 0; i < count; ++i, ++urel)
+ {
+ unsigned int insn;
+ insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
+
+ switch (urel->r_addend)
+ {
+ default: /* 0 = ADDRESS FORMAT */
+ /* This type is really just a placeholder to note that all
+ uses cannot be optimized, but to still allow some. */
+ all_optimized = false;
+ break;
+
+ case 1: /* MEM FORMAT */
+ /* We can always optimize 16-bit displacements. */
+ if (fits16)
+ {
+ /* FIXME: sanity check the insn for mem format with
+ zero addend. */
+
+ /* Take the op code and dest from this insn, take the base
+ register from the literal insn. Leave the offset alone. */
+ insn = (insn & 0xffe00000) | (lit_insn & 0x001f0000);
+ urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_GPRELLOW);
+ urel->r_addend = irel->r_addend;
+ info->changed_relocs = true;
+
+ bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset);
+ info->changed_contents = true;
+ }
+
+ /* If all mem+byte, we can optimize 32-bit mem displacements. */
+ else if (fits32 && !(flags & ~6))
+ {
+ /* FIXME: sanity check that lit insn Ra is mem insn Rb, and
+ that mem_insn disp is zero. */
+
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_GPRELHIGH);
+ lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
+ bfd_put_32 (info->abfd, lit_insn,
+ info->contents + irel->r_offset);
+ lit_reused = true;
+ info->changed_contents = true;
+
+ urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_GPRELLOW);
+ urel->r_addend = irel->r_addend;
+ info->changed_relocs = true;
+ }
+ else
+ all_optimized = false;
+ break;
+
+ case 2: /* BYTE OFFSET FORMAT */
+ /* We can always optimize byte instructions. */
+
+ /* FIXME: sanity check the insn for byte op. Check that the
+ literal dest reg is indeed Rb in the byte insn. */
+
+ insn = (insn & ~0x001ff000) | ((symval & 7) << 13) | 0x1000;
+
+ urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ urel->r_addend = 0;
+ info->changed_relocs = true;
+
+ bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset);
+ info->changed_contents = true;
+ break;
+
+ case 3: /* CALL FORMAT */
+ {
+ /* If not zero, place to jump without needing pv. */
+ bfd_vma optdest = elf64_alpha_relax_opt_call (info, symval);
+ bfd_vma org = (info->sec->output_section->vma
+ + info->sec->output_offset
+ + urel->r_offset + 4);
+ bfd_signed_vma odisp;
+
+ odisp = (optdest ? optdest : symval) - org;
+ if (odisp >= -0x400000 && odisp < 0x400000)
+ {
+ Elf_Internal_Rela *xrel;
+
+ /* Preserve branch prediction call stack when possible. */
+ if ((insn & INSN_JSR_MASK) == INSN_JSR)
+ insn = (OP_BSR << 26) | (insn & 0x03e00000);
+ else
+ insn = (OP_BR << 26) | (insn & 0x03e00000);
+
+ urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_BRADDR);
+ urel->r_addend = irel->r_addend;
+
+ if (optdest)
+ urel->r_addend += optdest - symval;
+ else
+ all_optimized = false;
+
+ bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset);
+
+ /* Kill any HINT reloc that might exist for this insn. */
+ xrel = (elf64_alpha_find_reloc_at_ofs
+ (info->relocs, info->relend, urel->r_offset,
+ R_ALPHA_HINT));
+ if (xrel)
+ xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+
+ info->changed_contents = true;
+ info->changed_relocs = true;
+ }
+ else
+ all_optimized = false;
+
+ /* ??? If target gp == current gp we can eliminate the gp reload.
+ This does depend on every place a gp could be reloaded will
+ be, which currently happens for all code produced by gcc, but
+ not necessarily by hand-coded assembly, or if sibling calls
+ are enabled in gcc.
+
+ Perhaps conditionalize this on a flag being set in the target
+ object file's header, and have gcc set it? */
+ }
+ break;
+ }
+ }
+
+ /* If all cases were optimized, we can reduce the use count on this
+ got entry by one, possibly eliminating it. */
+ if (all_optimized)
+ {
+ info->gotent->use_count -= 1;
+ alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1;
+ if (!info->h)
+ alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1;
+
+ /* If the literal instruction is no longer needed (it may have been
+ reused. We can eliminate it.
+ ??? For now, I don't want to deal with compacting the section,
+ so just nop it out. */
+ if (!lit_reused)
+ {
+ irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ info->changed_relocs = true;
+
+ bfd_put_32 (info->abfd, INSN_UNOP, info->contents + irel->r_offset);
+ info->changed_contents = true;
+ }
+ }
+
+ return irel + count;
+}
+
+static bfd_vma
+elf64_alpha_relax_opt_call (info, symval)
+ struct alpha_relax_info *info;
+ bfd_vma symval;
+{
+ /* If the function has the same gp, and we can identify that the
+ function does not use its function pointer, we can eliminate the
+ address load. */
+
+ /* If the symbol is marked NOPV, we are being told the function never
+ needs its procedure value. */
+ if (info->other == STO_ALPHA_NOPV)
+ return symval;
+
+ /* If the symbol is marked STD_GP, we are being told the function does
+ a normal ldgp in the first two words. */
+ else if (info->other == STO_ALPHA_STD_GPLOAD)
+ ;
+
+ /* Otherwise, we may be able to identify a GP load in the first two
+ words, which we can then skip. */
+ else
+ {
+ Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
+ bfd_vma ofs;
+
+ /* Load the relocations from the section that the target symbol is in. */
+ if (info->sec == info->tsec)
+ {
+ tsec_relocs = info->relocs;
+ tsec_relend = info->relend;
+ tsec_free = NULL;
+ }
+ else
+ {
+ tsec_relocs = (_bfd_elf64_link_read_relocs
+ (info->abfd, info->tsec, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->link_info->keep_memory));
+ if (tsec_relocs == NULL)
+ return 0;
+ tsec_relend = tsec_relocs + info->tsec->reloc_count;
+ tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
+ }
+
+ /* Recover the symbol's offset within the section. */
+ ofs = (symval - info->tsec->output_section->vma
+ - info->tsec->output_offset);
+
+ /* Look for a GPDISP reloc. */
+ gpdisp = (elf64_alpha_find_reloc_at_ofs
+ (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
+
+ if (!gpdisp || gpdisp->r_addend != 4)
+ {
+ if (tsec_free)
+ free (tsec_free);
+ return 0;
+ }
+ if (tsec_free)
+ free (tsec_free);
+ }
+
+ /* We've now determined that we can skip an initial gp load. Verify
+ that the call and the target use the same gp. */
+ if (info->link_info->hash->creator != info->tsec->owner->xvec
+ || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
+ return 0;
+
+ return symval + 8;
+}
+
+static boolean
+elf64_alpha_relax_without_lituse (info, symval, irel)
+ struct alpha_relax_info *info;
+ bfd_vma symval;
+ Elf_Internal_Rela *irel;
+{
+ unsigned int insn;
+ bfd_signed_vma disp;
+
+ /* Get the instruction. */
+ insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
+
+ if (insn >> 26 != OP_LDQ)
+ {
+ ((*_bfd_error_handler)
+ ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
+ bfd_get_filename (info->abfd), info->sec->name,
+ (unsigned long) irel->r_offset));
+ return true;
+ }
+
+ /* So we aren't told much. Do what we can with the address load and
+ fake the rest. All of the optimizations here require that the
+ offset from the GP fit in 16 bits. */
+
+ disp = symval - info->gp;
+ if (disp < -0x8000 || disp >= 0x8000)
+ return true;
+
+ /* On the LITERAL instruction itself, consider exchanging
+ `ldq R,X(gp)' for `lda R,Y(gp)'. */
+
+ insn = (OP_LDA << 26) | (insn & 0x03ff0000);
+ bfd_put_32 (info->abfd, insn, info->contents + irel->r_offset);
+ info->changed_contents = true;
+
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), R_ALPHA_GPRELLOW);
+ info->changed_relocs = true;
+
+ /* Reduce the use count on this got entry by one, possibly
+ eliminating it. */
+ info->gotent->use_count -= 1;
+ alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1;
+ if (!info->h)
+ alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1;
+
+ /* ??? Search forward through this basic block looking for insns
+ that use the target register. Stop after an insn modifying the
+ register is seen, or after a branch or call.
+
+ Any such memory load insn may be substituted by a load directly
+ off the GP. This allows the memory load insn to be issued before
+ the calculated GP register would otherwise be ready.
+
+ Any such jsr insn can be replaced by a bsr if it is in range.
+
+ This would mean that we'd have to _add_ relocations, the pain of
+ which gives one pause. */
+
+ return true;
+}
+
+static boolean
+elf64_alpha_relax_section (abfd, sec, link_info, again)
+ bfd *abfd;
+ asection *sec;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *free_contents = NULL;
+ Elf64_External_Sym *extsyms = NULL;
+ Elf64_External_Sym *free_extsyms = NULL;
+ struct alpha_elf_got_entry **local_got_entries;
+ struct alpha_relax_info info;
+
+ /* We are not currently changing any sizes, so only one pass. */
+ *again = false;
+
+ if (link_info->relocateable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return true;
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
+
+ /* Load the relocations for this section. */
+ internal_relocs = (_bfd_elf64_link_read_relocs
+ (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ memset(&info, 0, sizeof(info));
+ info.abfd = abfd;
+ info.sec = sec;
+ info.link_info = link_info;
+ info.relocs = internal_relocs;
+ info.relend = irelend = internal_relocs + sec->reloc_count;
+
+ /* Find the GP for this object. */
+ info.gotobj = alpha_elf_tdata (abfd)->gotobj;
+ if (info.gotobj)
+ {
+ asection *sgot = alpha_elf_tdata (info.gotobj)->got;
+ info.gp = _bfd_get_gp_value (info.gotobj);
+ if (info.gp == 0)
+ {
+ info.gp = (sgot->output_section->vma
+ + sgot->output_offset
+ + 0x8000);
+ _bfd_set_gp_value (info.gotobj, info.gp);
+ }
+ }
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ Elf_Internal_Sym isym;
+ struct alpha_elf_got_entry *gotent;
+
+ if (ELF64_R_TYPE (irel->r_info) != (int) R_ALPHA_LITERAL)
+ continue;
+
+ /* Get the section contents. */
+ if (info.contents == NULL)
+ {
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ info.contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (info.contents == NULL)
+ goto error_return;
+ free_contents = info.contents;
+
+ if (! bfd_get_section_contents (abfd, sec, info.contents,
+ (file_ptr) 0, sec->_raw_size))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (extsyms == NULL)
+ {
+ if (symtab_hdr->contents != NULL)
+ extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
+ else
+ {
+ extsyms = ((Elf64_External_Sym *)
+ bfd_malloc (symtab_hdr->sh_size));
+ if (extsyms == NULL)
+ goto error_return;
+ free_extsyms = extsyms;
+ if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ != symtab_hdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ bfd_elf64_swap_symbol_in (abfd,
+ extsyms + ELF64_R_SYM (irel->r_info),
+ &isym);
+ if (isym.st_shndx == SHN_UNDEF)
+ info.tsec = bfd_und_section_ptr;
+ else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
+ info.tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ else if (isym.st_shndx == SHN_ABS)
+ info.tsec = bfd_abs_section_ptr;
+ else if (isym.st_shndx == SHN_COMMON)
+ info.tsec = bfd_com_section_ptr;
+ else
+ continue; /* who knows. */
+
+ info.h = NULL;
+ info.other = isym.st_other;
+ gotent = local_got_entries[ELF64_R_SYM(irel->r_info)];
+ symval = isym.st_value;
+ }
+ else
+ {
+ unsigned long indx;
+ struct alpha_elf_link_hash_entry *h;
+
+ indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = alpha_elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
+
+ /* We can't do anthing with undefined or dynamic symbols. */
+ if (h->root.root.type == bfd_link_hash_undefined
+ || h->root.root.type == bfd_link_hash_undefweak
+ || alpha_elf_dynamic_symbol_p (&h->root, link_info))
+ continue;
+
+ info.h = h;
+ info.gotent = gotent;
+ info.tsec = h->root.root.u.def.section;
+ info.other = h->root.other;
+ gotent = h->got_entries;
+ symval = h->root.root.u.def.value;
+ }
+
+ /* Search for the got entry to be used by this relocation. */
+ while (gotent->gotobj != info.gotobj || gotent->addend != irel->r_addend)
+ gotent = gotent->next;
+ info.gotent = gotent;
+
+ symval += info.tsec->output_section->vma + info.tsec->output_offset;
+ symval += irel->r_addend;
+
+ BFD_ASSERT(info.gotent != NULL);
+
+ /* If there exist LITUSE relocations immediately following, this
+ opens up all sorts of interesting optimizations, because we
+ now know every location that this address load is used. */
+
+ if (irel+1 < irelend && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
+ {
+ irel = elf64_alpha_relax_with_lituse (&info, symval, irel, irelend);
+ if (irel == NULL)
+ goto error_return;
+ }
+ else
+ {
+ if (!elf64_alpha_relax_without_lituse (&info, symval, irel))
+ goto error_return;
+ }
+ }
+
+ if (!elf64_alpha_size_got_sections (abfd, link_info))
+ return false;
+
+ if (info.changed_relocs)
+ {
+ elf_section_data (sec)->relocs = internal_relocs;
+ }
+ else if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ }
+
+ if (info.changed_contents)
+ {
+ elf_section_data (sec)->this_hdr.contents = info.contents;
+ }
+ else if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = info.contents;
+ }
+ }
+
+ if (free_extsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_extsyms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = extsyms;
+ }
+ }
+
+ *again = info.changed_contents || info.changed_relocs;
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (free_extsyms != NULL)
+ free (free_extsyms);
+ return false;
+}
+
+/* PLT/GOT Stuff */
+#define PLT_HEADER_SIZE 32
+#define PLT_HEADER_WORD1 0xc3600000 /* br $27,.+4 */
+#define PLT_HEADER_WORD2 0xa77b000c /* ldq $27,12($27) */
+#define PLT_HEADER_WORD3 0x47ff041f /* nop */
+#define PLT_HEADER_WORD4 0x6b7b0000 /* jmp $27,($27) */
+
+#define PLT_ENTRY_SIZE 12
+#define PLT_ENTRY_WORD1 0xc3800000 /* br $28, plt0 */
+#define PLT_ENTRY_WORD2 0
+#define PLT_ENTRY_WORD3 0
+
+#define MAX_GOT_ENTRIES (64*1024 / 8)
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
+
+/* Handle an Alpha specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type.
+ FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
+ how to. */
+
+static boolean
+elf64_alpha_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf64_Internal_Shdr *hdr;
+ char *name;
+{
+ asection *newsect;
+
+ /* There ought to be a place to keep ELF backend specific flags, but
+ at the moment there isn't one. We just keep track of the
+ sections by their name, instead. Fortunately, the ABI gives
+ suggested names for all the MIPS specific sections, so we will
+ probably get away with this. */
+ switch (hdr->sh_type)
+ {
+ case SHT_ALPHA_DEBUG:
+ if (strcmp (name, ".mdebug") != 0)
+ return false;
+ break;
+#ifdef ERIC_neverdef
+ case SHT_ALPHA_REGINFO:
+ if (strcmp (name, ".reginfo") != 0
+ || hdr->sh_size != sizeof (Elf64_External_RegInfo))
+ return false;
+ break;
+#endif
+ default:
+ return false;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+ newsect = hdr->bfd_section;
+
+ if (hdr->sh_type == SHT_ALPHA_DEBUG)
+ {
+ if (! bfd_set_section_flags (abfd, newsect,
+ (bfd_get_section_flags (abfd, newsect)
+ | SEC_DEBUGGING)))
+ return false;
+ }
+
+#ifdef ERIC_neverdef
+ /* For a .reginfo section, set the gp value in the tdata information
+ from the contents of this section. We need the gp value while
+ processing relocs, so we just get it now. */
+ if (hdr->sh_type == SHT_ALPHA_REGINFO)
+ {
+ Elf64_External_RegInfo ext;
+ Elf64_RegInfo s;
+
+ if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext,
+ (file_ptr) 0, sizeof ext))
+ return false;
+ bfd_alpha_elf64_swap_reginfo_in (abfd, &ext, &s);
+ elf_gp (abfd) = s.ri_gp_value;
+ }
+#endif
+
+ return true;
+}
+
+/* Set the correct type for an Alpha ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static boolean
+elf64_alpha_fake_sections (abfd, hdr, sec)
+ bfd *abfd;
+ Elf64_Internal_Shdr *hdr;
+ asection *sec;
+{
+ register const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".mdebug") == 0)
+ {
+ hdr->sh_type = SHT_ALPHA_DEBUG;
+ /* In a shared object on Irix 5.3, the .mdebug section has an
+ entsize of 0. FIXME: Does this matter? */
+ if ((abfd->flags & DYNAMIC) != 0 )
+ hdr->sh_entsize = 0;
+ else
+ hdr->sh_entsize = 1;
+ }
+#ifdef ERIC_neverdef
+ else if (strcmp (name, ".reginfo") == 0)
+ {
+ hdr->sh_type = SHT_ALPHA_REGINFO;
+ /* In a shared object on Irix 5.3, the .reginfo section has an
+ entsize of 0x18. FIXME: Does this matter? */
+ if ((abfd->flags & DYNAMIC) != 0)
+ hdr->sh_entsize = sizeof (Elf64_External_RegInfo);
+ else
+ hdr->sh_entsize = 1;
+
+ /* Force the section size to the correct value, even if the
+ linker thinks it is larger. The link routine below will only
+ write out this much data for .reginfo. */
+ hdr->sh_size = sec->_raw_size = sizeof (Elf64_External_RegInfo);
+ }
+ else if (strcmp (name, ".hash") == 0
+ || strcmp (name, ".dynamic") == 0
+ || strcmp (name, ".dynstr") == 0)
+ {
+ hdr->sh_entsize = 0;
+ hdr->sh_info = SIZEOF_ALPHA_DYNSYM_SECNAMES;
+ }
+#endif
+ else if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0
+ || strcmp (name, ".lit4") == 0
+ || strcmp (name, ".lit8") == 0)
+ hdr->sh_flags |= SHF_ALPHA_GPREL;
+
+ return true;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it to put .comm items in .sbss, and not .bss. */
+
+static boolean
+elf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const Elf_Internal_Sym *sym;
+ const char **namep;
+ flagword *flagsp;
+ asection **secp;
+ bfd_vma *valp;
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocateable
+ && sym->st_size <= bfd_get_gp_size (abfd))
+ {
+ /* Common symbols less than or equal to -G nn bytes are
+ automatically put into .sbss. */
+
+ asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
+
+ if (scomm == NULL)
+ {
+ scomm = bfd_make_section (abfd, ".scommon");
+ if (scomm == NULL
+ || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED)))
+ return false;
+ }
+
+ *secp = scomm;
+ *valp = sym->st_size;
+ }
+
+ return true;
+}
+
+/* Create the .got section. */
+
+static boolean
+elf64_alpha_create_got_section(abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *s;
+
+ if (bfd_get_section_by_name (abfd, ".got"))
+ return true;
+
+ s = bfd_make_section (abfd, ".got");
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED))
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return false;
+
+ alpha_elf_tdata (abfd)->got = s;
+
+ return true;
+}
+
+/* Create all the dynamic sections. */
+
+static boolean
+elf64_alpha_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *s;
+ struct elf_link_hash_entry *h;
+
+ /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
+
+ s = bfd_make_section (abfd, ".plt");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_CODE))
+ || ! bfd_set_section_alignment (abfd, s, 3))
+ return false;
+
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (info->shared
+ && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ s = bfd_make_section (abfd, ".rela.plt");
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (abfd, s, 3))
+ return false;
+
+ /* We may or may not have created a .got section for this object, but
+ we definitely havn't done the rest of the work. */
+
+ if (!elf64_alpha_create_got_section (abfd, info))
+ return false;
+
+ s = bfd_make_section(abfd, ".rela.got");
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return false;
+
+ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
+ dynobj's .got section. We don't do this in the linker script
+ because we don't want to define the symbol if we are not creating
+ a global offset table. */
+ h = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL,
+ alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL,
+ false, get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (info->shared
+ && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ elf_hash_table (info)->hgot = h;
+
+ return true;
+}
+
+/* Read ECOFF debugging information from a .mdebug section into a
+ ecoff_debug_info structure. */
+
+static boolean
+elf64_alpha_read_ecoff_info (abfd, section, debug)
+ bfd *abfd;
+ asection *section;
+ struct ecoff_debug_info *debug;
+{
+ HDRR *symhdr;
+ const struct ecoff_debug_swap *swap;
+ char *ext_hdr = NULL;
+
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ memset (debug, 0, sizeof(*debug));
+
+ ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size);
+ if (ext_hdr == NULL && swap->external_hdr_size != 0)
+ goto error_return;
+
+ if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
+ swap->external_hdr_size)
+ == false)
+ goto error_return;
+
+ symhdr = &debug->symbolic_header;
+ (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
+
+ /* The symbolic header contains absolute file offsets and sizes to
+ read. */
+#define READ(ptr, offset, count, size, type) \
+ if (symhdr->count == 0) \
+ debug->ptr = NULL; \
+ else \
+ { \
+ debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \
+ if (debug->ptr == NULL) \
+ goto error_return; \
+ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
+ || (bfd_read (debug->ptr, size, symhdr->count, \
+ abfd) != size * symhdr->count)) \
+ goto error_return; \
+ }
+
+ READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
+ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
+ READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
+ union aux_ext *);
+ READ (ss, cbSsOffset, issMax, sizeof (char), char *);
+ READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
+ READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
+ READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
+#undef READ
+
+ debug->fdr = NULL;
+ debug->adjust = NULL;
+
+ return true;
+
+ error_return:
+ if (ext_hdr != NULL)
+ free (ext_hdr);
+ if (debug->line != NULL)
+ free (debug->line);
+ if (debug->external_dnr != NULL)
+ free (debug->external_dnr);
+ if (debug->external_pdr != NULL)
+ free (debug->external_pdr);
+ if (debug->external_sym != NULL)
+ free (debug->external_sym);
+ if (debug->external_opt != NULL)
+ free (debug->external_opt);
+ if (debug->external_aux != NULL)
+ free (debug->external_aux);
+ if (debug->ss != NULL)
+ free (debug->ss);
+ if (debug->ssext != NULL)
+ free (debug->ssext);
+ if (debug->external_fdr != NULL)
+ free (debug->external_fdr);
+ if (debug->external_rfd != NULL)
+ free (debug->external_rfd);
+ if (debug->external_ext != NULL)
+ free (debug->external_ext);
+ return false;
+}
+
+/* Alpha ELF local labels start with '$'. */
+
+static boolean
+elf64_alpha_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return name[0] == '$';
+}
+
+/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
+ routine in order to handle the ECOFF debugging information. We
+ still call this mips_elf_find_line because of the slot
+ find_line_info in elf_obj_tdata is declared that way. */
+
+struct mips_elf_find_line
+{
+ struct ecoff_debug_info d;
+ struct ecoff_find_line i;
+};
+
+static boolean
+elf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
+ functionname_ptr, line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ asection *msec;
+
+ msec = bfd_get_section_by_name (abfd, ".mdebug");
+ if (msec != NULL)
+ {
+ flagword origflags;
+ struct mips_elf_find_line *fi;
+ const struct ecoff_debug_swap * const swap =
+ get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+
+ /* If we are called during a link, alpha_elf_final_link may have
+ cleared the SEC_HAS_CONTENTS field. We force it back on here
+ if appropriate (which it normally will be). */
+ origflags = msec->flags;
+ if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
+ msec->flags |= SEC_HAS_CONTENTS;
+
+ fi = elf_tdata (abfd)->find_line_info;
+ if (fi == NULL)
+ {
+ bfd_size_type external_fdr_size;
+ char *fraw_src;
+ char *fraw_end;
+ struct fdr *fdr_ptr;
+
+ fi = ((struct mips_elf_find_line *)
+ bfd_zalloc (abfd, sizeof (struct mips_elf_find_line)));
+ if (fi == NULL)
+ {
+ msec->flags = origflags;
+ return false;
+ }
+
+ if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
+ {
+ msec->flags = origflags;
+ return false;
+ }
+
+ /* Swap in the FDR information. */
+ fi->d.fdr = ((struct fdr *)
+ bfd_alloc (abfd,
+ (fi->d.symbolic_header.ifdMax *
+ sizeof (struct fdr))));
+ if (fi->d.fdr == NULL)
+ {
+ msec->flags = origflags;
+ return false;
+ }
+ external_fdr_size = swap->external_fdr_size;
+ fdr_ptr = fi->d.fdr;
+ fraw_src = (char *) fi->d.external_fdr;
+ fraw_end = (fraw_src
+ + fi->d.symbolic_header.ifdMax * external_fdr_size);
+ for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
+ (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
+
+ elf_tdata (abfd)->find_line_info = fi;
+
+ /* Note that we don't bother to ever free this information.
+ find_nearest_line is either called all the time, as in
+ objdump -l, so the information should be saved, or it is
+ rarely called, as in ld error messages, so the memory
+ wasted is unimportant. Still, it would probably be a
+ good idea for free_cached_info to throw it away. */
+ }
+
+ if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
+ &fi->i, filename_ptr, functionname_ptr,
+ line_ptr))
+ {
+ msec->flags = origflags;
+ return true;
+ }
+
+ msec->flags = origflags;
+ }
+
+ /* Fall back on the generic ELF find_nearest_line routine. */
+
+ return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr);
+}
+
+/* Structure used to pass information to alpha_elf_output_extsym. */
+
+struct extsym_info
+{
+ bfd *abfd;
+ struct bfd_link_info *info;
+ struct ecoff_debug_info *debug;
+ const struct ecoff_debug_swap *swap;
+ boolean failed;
+};
+
+static boolean
+elf64_alpha_output_extsym (h, data)
+ struct alpha_elf_link_hash_entry *h;
+ PTR data;
+{
+ struct extsym_info *einfo = (struct extsym_info *) data;
+ boolean strip;
+ asection *sec, *output_section;
+
+ if (h->root.indx == -2)
+ strip = false;
+ else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
+ && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+ && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
+ strip = true;
+ else if (einfo->info->strip == strip_all
+ || (einfo->info->strip == strip_some
+ && bfd_hash_lookup (einfo->info->keep_hash,
+ h->root.root.root.string,
+ false, false) == NULL))
+ strip = true;
+ else
+ strip = false;
+
+ if (strip)
+ return true;
+
+ if (h->esym.ifd == -2)
+ {
+ h->esym.jmptbl = 0;
+ h->esym.cobol_main = 0;
+ h->esym.weakext = 0;
+ h->esym.reserved = 0;
+ h->esym.ifd = ifdNil;
+ h->esym.asym.value = 0;
+ h->esym.asym.st = stGlobal;
+
+ if (h->root.root.type != bfd_link_hash_defined
+ && h->root.root.type != bfd_link_hash_defweak)
+ h->esym.asym.sc = scAbs;
+ else
+ {
+ const char *name;
+
+ sec = h->root.root.u.def.section;
+ output_section = sec->output_section;
+
+ /* When making a shared library and symbol h is the one from
+ the another shared library, OUTPUT_SECTION may be null. */
+ if (output_section == NULL)
+ h->esym.asym.sc = scUndefined;
+ else
+ {
+ name = bfd_section_name (output_section->owner, output_section);
+
+ if (strcmp (name, ".text") == 0)
+ h->esym.asym.sc = scText;
+ else if (strcmp (name, ".data") == 0)
+ h->esym.asym.sc = scData;
+ else if (strcmp (name, ".sdata") == 0)
+ h->esym.asym.sc = scSData;
+ else if (strcmp (name, ".rodata") == 0
+ || strcmp (name, ".rdata") == 0)
+ h->esym.asym.sc = scRData;
+ else if (strcmp (name, ".bss") == 0)
+ h->esym.asym.sc = scBss;
+ else if (strcmp (name, ".sbss") == 0)
+ h->esym.asym.sc = scSBss;
+ else if (strcmp (name, ".init") == 0)
+ h->esym.asym.sc = scInit;
+ else if (strcmp (name, ".fini") == 0)
+ h->esym.asym.sc = scFini;
+ else
+ h->esym.asym.sc = scAbs;
+ }
+ }
+
+ h->esym.asym.reserved = 0;
+ h->esym.asym.index = indexNil;
+ }
+
+ if (h->root.root.type == bfd_link_hash_common)
+ h->esym.asym.value = h->root.root.u.c.size;
+ else if (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ {
+ if (h->esym.asym.sc == scCommon)
+ h->esym.asym.sc = scBss;
+ else if (h->esym.asym.sc == scSCommon)
+ h->esym.asym.sc = scSBss;
+
+ sec = h->root.root.u.def.section;
+ output_section = sec->output_section;
+ if (output_section != NULL)
+ h->esym.asym.value = (h->root.root.u.def.value
+ + sec->output_offset
+ + output_section->vma);
+ else
+ h->esym.asym.value = 0;
+ }
+ else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+ {
+ /* Set type and value for a symbol with a function stub. */
+ h->esym.asym.st = stProc;
+ sec = bfd_get_section_by_name (einfo->abfd, ".plt");
+ if (sec == NULL)
+ h->esym.asym.value = 0;
+ else
+ {
+ output_section = sec->output_section;
+ if (output_section != NULL)
+ h->esym.asym.value = (h->root.plt.offset
+ + sec->output_offset
+ + output_section->vma);
+ else
+ h->esym.asym.value = 0;
+ }
+#if 0 /* FIXME? */
+ h->esym.ifd = 0;
+#endif
+ }
+
+ if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
+ h->root.root.root.string,
+ &h->esym))
+ {
+ einfo->failed = true;
+ return false;
+ }
+
+ return true;
+}
+
+/* FIXME: Create a runtime procedure table from the .mdebug section.
+
+static boolean
+mips_elf_create_procedure_table (handle, abfd, info, s, debug)
+ PTR handle;
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *s;
+ struct ecoff_debug_info *debug;
+*/
+
+/* Handle dynamic relocations when doing an Alpha ELF link. */
+
+static boolean
+elf64_alpha_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ bfd *dynobj;
+ asection *sreloc;
+ const char *rel_sec_name;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct alpha_elf_link_hash_entry **sym_hashes;
+ struct alpha_elf_got_entry **local_got_entries;
+ const Elf_Internal_Rela *rel, *relend;
+ int got_created;
+
+ if (info->relocateable)
+ return true;
+
+ dynobj = elf_hash_table(info)->dynobj;
+ if (dynobj == NULL)
+ elf_hash_table(info)->dynobj = dynobj = abfd;
+
+ sreloc = NULL;
+ rel_sec_name = NULL;
+ symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
+ sym_hashes = alpha_elf_sym_hashes(abfd);
+ local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
+ got_created = 0;
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ unsigned long r_symndx, r_type;
+ struct alpha_elf_link_hash_entry *h;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
+
+ h->root.elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
+ }
+ r_type = ELF64_R_TYPE (rel->r_info);
+
+ switch (r_type)
+ {
+ case R_ALPHA_LITERAL:
+ {
+ struct alpha_elf_got_entry *gotent;
+ int flags = 0;
+
+ if (h)
+ {
+ /* Search for and possibly create a got entry. */
+ for (gotent = h->got_entries; gotent ; gotent = gotent->next)
+ if (gotent->gotobj == abfd &&
+ gotent->addend == rel->r_addend)
+ break;
+
+ if (!gotent)
+ {
+ gotent = ((struct alpha_elf_got_entry *)
+ bfd_alloc (abfd,
+ sizeof (struct alpha_elf_got_entry)));
+ if (!gotent)
+ return false;
+
+ gotent->gotobj = abfd;
+ gotent->addend = rel->r_addend;
+ gotent->got_offset = -1;
+ gotent->flags = 0;
+ gotent->use_count = 1;
+
+ gotent->next = h->got_entries;
+ h->got_entries = gotent;
+
+ alpha_elf_tdata (abfd)->total_got_entries++;
+ }
+ else
+ gotent->use_count += 1;
+ }
+ else
+ {
+ /* This is a local .got entry -- record for merge. */
+ if (!local_got_entries)
+ {
+ size_t size;
+ size = (symtab_hdr->sh_info
+ * sizeof (struct alpha_elf_got_entry *));
+
+ local_got_entries = ((struct alpha_elf_got_entry **)
+ bfd_alloc (abfd, size));
+ if (!local_got_entries)
+ return false;
+
+ memset (local_got_entries, 0, size);
+ alpha_elf_tdata (abfd)->local_got_entries =
+ local_got_entries;
+ }
+
+ for (gotent = local_got_entries[ELF64_R_SYM(rel->r_info)];
+ gotent != NULL && gotent->addend != rel->r_addend;
+ gotent = gotent->next)
+ continue;
+ if (!gotent)
+ {
+ gotent = ((struct alpha_elf_got_entry *)
+ bfd_alloc (abfd,
+ sizeof (struct alpha_elf_got_entry)));
+ if (!gotent)
+ return false;
+
+ gotent->gotobj = abfd;
+ gotent->addend = rel->r_addend;
+ gotent->got_offset = -1;
+ gotent->flags = 0;
+ gotent->use_count = 1;
+
+ gotent->next = local_got_entries[ELF64_R_SYM(rel->r_info)];
+ local_got_entries[ELF64_R_SYM(rel->r_info)] = gotent;
+
+ alpha_elf_tdata(abfd)->total_got_entries++;
+ alpha_elf_tdata(abfd)->n_local_got_entries++;
+ }
+ else
+ gotent->use_count += 1;
+ }
+
+ /* Remember how this literal is used from its LITUSEs.
+ This will be important when it comes to decide if we can
+ create a .plt entry for a function symbol. */
+ if (rel+1 < relend
+ && ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE)
+ {
+ do
+ {
+ ++rel;
+ if (rel->r_addend >= 1 && rel->r_addend <= 3)
+ flags |= 1 << rel->r_addend;
+ }
+ while (rel+1 < relend &&
+ ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE);
+ }
+ else
+ {
+ /* No LITUSEs -- presumably the address is not being
+ loaded for nothing. */
+ flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
+ }
+
+ gotent->flags |= flags;
+ if (h)
+ {
+ /* Make a guess as to whether a .plt entry will be needed. */
+ if ((h->flags |= flags) == ALPHA_ELF_LINK_HASH_LU_FUNC)
+ h->root.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ else
+ h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+ }
+ }
+ /* FALLTHRU */
+
+ case R_ALPHA_GPDISP:
+ case R_ALPHA_GPREL32:
+ case R_ALPHA_GPRELHIGH:
+ case R_ALPHA_GPRELLOW:
+ /* We don't actually use the .got here, but the sections must
+ be created before the linker maps input sections to output
+ sections. */
+ if (!got_created)
+ {
+ if (!elf64_alpha_create_got_section (abfd, info))
+ return false;
+
+ /* Make sure the object's gotobj is set to itself so
+ that we default to every object with its own .got.
+ We'll merge .gots later once we've collected each
+ object's info. */
+ alpha_elf_tdata(abfd)->gotobj = abfd;
+
+ got_created = 1;
+ }
+ break;
+
+ case R_ALPHA_SREL16:
+ case R_ALPHA_SREL32:
+ case R_ALPHA_SREL64:
+ if (h == NULL)
+ break;
+ /* FALLTHRU */
+
+ case R_ALPHA_REFLONG:
+ case R_ALPHA_REFQUAD:
+ if (rel_sec_name == NULL)
+ {
+ rel_sec_name = (bfd_elf_string_from_elf_section
+ (abfd, elf_elfheader(abfd)->e_shstrndx,
+ elf_section_data(sec)->rel_hdr.sh_name));
+ if (rel_sec_name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (rel_sec_name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ rel_sec_name+5) == 0);
+ }
+
+ /* We need to create the section here now whether we eventually
+ use it or not so that it gets mapped to an output section by
+ the linker. If not used, we'll kill it in
+ size_dynamic_sections. */
+ if (sreloc == NULL)
+ {
+ sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
+ if (sreloc == NULL)
+ {
+ sreloc = bfd_make_section (dynobj, rel_sec_name);
+ if (sreloc == NULL
+ || !bfd_set_section_flags (dynobj, sreloc,
+ (SEC_ALLOC|SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || !bfd_set_section_alignment (dynobj, sreloc, 3))
+ return false;
+ }
+ }
+
+ if (h)
+ {
+ /* Since we havn't seen all of the input symbols yet, we
+ don't know whether we'll actually need a dynamic relocation
+ entry for this reloc. So make a record of it. Once we
+ find out if this thing needs dynamic relocation we'll
+ expand the relocation sections by the appropriate amount. */
+
+ struct alpha_elf_reloc_entry *rent;
+
+ for (rent = h->reloc_entries; rent; rent = rent->next)
+ if (rent->rtype == r_type && rent->srel == sreloc)
+ break;
+
+ if (!rent)
+ {
+ rent = ((struct alpha_elf_reloc_entry *)
+ bfd_alloc (abfd,
+ sizeof (struct alpha_elf_reloc_entry)));
+ if (!rent)
+ return false;
+
+ rent->srel = sreloc;
+ rent->rtype = r_type;
+ rent->count = 1;
+
+ rent->next = h->reloc_entries;
+ h->reloc_entries = rent;
+ }
+ else
+ rent->count++;
+ }
+ else if (info->shared)
+ {
+ /* If this is a shared library, we need a RELATIVE reloc. */
+ sreloc->_raw_size += sizeof (Elf64_External_Rela);
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+elf64_alpha_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj;
+ asection *s;
+ struct alpha_elf_link_hash_entry *ah;
+
+ dynobj = elf_hash_table(info)->dynobj;
+ ah = (struct alpha_elf_link_hash_entry *)h;
+
+ /* Now that we've seen all of the input symbols, finalize our decision
+ about whether this symbol should get a .plt entry. */
+
+ if (h->root.type != bfd_link_hash_undefweak
+ && alpha_elf_dynamic_symbol_p (h, info)
+ && ((h->type == STT_FUNC
+ && !(ah->flags & ALPHA_ELF_LINK_HASH_LU_ADDR))
+ || (h->type == STT_NOTYPE
+ && ah->flags == ALPHA_ELF_LINK_HASH_LU_FUNC))
+ /* Don't prevent otherwise valid programs from linking by attempting
+ to create a new .got entry somewhere. A Correct Solution would be
+ to add a new .got section to a new object file and let it be merged
+ somewhere later. But for now don't bother. */
+ && ah->got_entries)
+ {
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+ s = bfd_get_section_by_name(dynobj, ".plt");
+ if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
+ return false;
+
+ /* The first bit of the .plt is reserved. */
+ if (s->_raw_size == 0)
+ s->_raw_size = PLT_HEADER_SIZE;
+
+ h->plt.offset = s->_raw_size;
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* If this symbol is not defined in a regular file, and we are not
+ generating a shared library, then set the symbol to the location
+ in the .plt. This is required to make function pointers compare
+ equal between the normal executable and the shared library. */
+ if (! info->shared
+ && h->root.type != bfd_link_hash_defweak)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* We also need a JMP_SLOT entry in the .rela.plt section. */
+ s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size += sizeof (Elf64_External_Rela);
+
+ return true;
+ }
+ else
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. The Alpha, since it uses .got entries for all
+ symbols even in regular objects, does not need the hackery of a
+ .dynbss section and COPY dynamic relocations. */
+
+ return true;
+}
+
+/* Symbol versioning can create new symbols, and make our old symbols
+ indirect to the new ones. Consolidate the got and reloc information
+ in these situations. */
+
+static boolean
+elf64_alpha_merge_ind_symbols (hi, dummy)
+ struct alpha_elf_link_hash_entry *hi;
+ PTR dummy;
+{
+ struct alpha_elf_link_hash_entry *hs;
+
+ if (hi->root.root.type != bfd_link_hash_indirect)
+ return true;
+ hs = hi;
+ do {
+ hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
+ } while (hs->root.root.type == bfd_link_hash_indirect);
+
+ /* Merge the flags. Whee. */
+
+ hs->flags |= hi->flags;
+
+ /* Merge the .got entries. Cannibalize the old symbol's list in
+ doing so, since we don't need it anymore. */
+
+ if (hs->got_entries == NULL)
+ hs->got_entries = hi->got_entries;
+ else
+ {
+ struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
+
+ gsh = hs->got_entries;
+ for (gi = hi->got_entries; gi ; gi = gin)
+ {
+ gin = gi->next;
+ for (gs = gsh; gs ; gs = gs->next)
+ if (gi->gotobj == gs->gotobj && gi->addend == gs->addend)
+ goto got_found;
+ gi->next = hs->got_entries;
+ hs->got_entries = gi;
+ got_found:;
+ }
+ }
+ hi->got_entries = NULL;
+
+ /* And similar for the reloc entries. */
+
+ if (hs->reloc_entries == NULL)
+ hs->reloc_entries = hi->reloc_entries;
+ else
+ {
+ struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
+
+ rsh = hs->reloc_entries;
+ for (ri = hi->reloc_entries; ri ; ri = rin)
+ {
+ rin = ri->next;
+ for (rs = rsh; rs ; rs = rs->next)
+ if (ri->rtype == rs->rtype)
+ {
+ rs->count += ri->count;
+ goto found_reloc;
+ }
+ ri->next = hs->reloc_entries;
+ hs->reloc_entries = ri;
+ found_reloc:;
+ }
+ }
+ hi->reloc_entries = NULL;
+
+ return true;
+}
+
+/* Is it possible to merge two object file's .got tables? */
+
+static boolean
+elf64_alpha_can_merge_gots (a, b)
+ bfd *a, *b;
+{
+ int total = alpha_elf_tdata (a)->total_got_entries;
+ bfd *bsub;
+
+ /* Trivial quick fallout test. */
+ if (total + alpha_elf_tdata (b)->total_got_entries <= MAX_GOT_ENTRIES)
+ return true;
+
+ /* By their nature, local .got entries cannot be merged. */
+ if ((total += alpha_elf_tdata (b)->n_local_got_entries) > MAX_GOT_ENTRIES)
+ return false;
+
+ /* Failing the common trivial comparison, we must effectively
+ perform the merge. Not actually performing the merge means that
+ we don't have to store undo information in case we fail. */
+ for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
+ {
+ struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
+ int i, n;
+
+ n = symtab_hdr->sh_size / symtab_hdr->sh_entsize - symtab_hdr->sh_info;
+ for (i = 0; i < n; ++i)
+ {
+ struct alpha_elf_got_entry *ae, *be;
+ struct alpha_elf_link_hash_entry *h;
+
+ h = hashes[i];
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
+
+ for (be = h->got_entries; be ; be = be->next)
+ {
+ if (be->use_count == 0)
+ continue;
+ if (be->gotobj != b)
+ continue;
+
+ for (ae = h->got_entries; ae ; ae = ae->next)
+ if (ae->gotobj == a && ae->addend == be->addend)
+ goto global_found;
+
+ if (++total > MAX_GOT_ENTRIES)
+ return false;
+ global_found:;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Actually merge two .got tables. */
+
+static void
+elf64_alpha_merge_gots (a, b)
+ bfd *a, *b;
+{
+ int total = alpha_elf_tdata (a)->total_got_entries;
+ bfd *bsub;
+
+ /* Remember local expansion. */
+ {
+ int e = alpha_elf_tdata (b)->n_local_got_entries;
+ total += e;
+ alpha_elf_tdata (a)->n_local_got_entries += e;
+ }
+
+ for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
+ {
+ struct alpha_elf_got_entry **local_got_entries;
+ struct alpha_elf_link_hash_entry **hashes;
+ Elf_Internal_Shdr *symtab_hdr;
+ int i, n;
+
+ /* Let the local .got entries know they are part of a new subsegment. */
+ local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
+ if (local_got_entries)
+ {
+ n = elf_tdata (bsub)->symtab_hdr.sh_info;
+ for (i = 0; i < n; ++i)
+ {
+ struct alpha_elf_got_entry *ent;
+ for (ent = local_got_entries[i]; ent; ent = ent->next)
+ ent->gotobj = a;
+ }
+ }
+
+ /* Merge the global .got entries. */
+ hashes = alpha_elf_sym_hashes (bsub);
+ symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
+
+ n = symtab_hdr->sh_size / symtab_hdr->sh_entsize - symtab_hdr->sh_info;
+ for (i = 0; i < n; ++i)
+ {
+ struct alpha_elf_got_entry *ae, *be, **pbe, **start;
+ struct alpha_elf_link_hash_entry *h;
+
+ h = hashes[i];
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
+
+ start = &h->got_entries;
+ for (pbe = start, be = *start; be ; pbe = &be->next, be = be->next)
+ {
+ if (be->use_count == 0)
+ {
+ *pbe = be->next;
+ continue;
+ }
+ if (be->gotobj != b)
+ continue;
+
+ for (ae = *start; ae ; ae = ae->next)
+ if (ae->gotobj == a && ae->addend == be->addend)
+ {
+ ae->flags |= be->flags;
+ ae->use_count += be->use_count;
+ *pbe = be->next;
+ goto global_found;
+ }
+ be->gotobj = a;
+ total += 1;
+
+ global_found:;
+ }
+ }
+
+ alpha_elf_tdata (bsub)->gotobj = a;
+ }
+ alpha_elf_tdata (a)->total_got_entries = total;
+
+ /* Merge the two in_got chains. */
+ {
+ bfd *next;
+
+ bsub = a;
+ while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
+ bsub = next;
+
+ alpha_elf_tdata (bsub)->in_got_link_next = b;
+ }
+}
+
+/* Calculate the offsets for the got entries. */
+
+static boolean
+elf64_alpha_calc_got_offsets_for_symbol (h, arg)
+ struct alpha_elf_link_hash_entry *h;
+ PTR arg;
+{
+ struct alpha_elf_got_entry *gotent;
+
+ for (gotent = h->got_entries; gotent; gotent = gotent->next)
+ if (gotent->use_count > 0)
+ {
+ bfd_size_type *plge
+ = &alpha_elf_tdata (gotent->gotobj)->got->_raw_size;
+
+ gotent->got_offset = *plge;
+ *plge += 8;
+ }
+
+ return true;
+}
+
+static void
+elf64_alpha_calc_got_offsets (info)
+ struct bfd_link_info *info;
+{
+ bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
+
+ /* First, zero out the .got sizes, as we may be recalculating the
+ .got after optimizing it. */
+ for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
+ alpha_elf_tdata(i)->got->_raw_size = 0;
+
+ /* Next, fill in the offsets for all the global entries. */
+ alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
+ elf64_alpha_calc_got_offsets_for_symbol,
+ NULL);
+
+ /* Finally, fill in the offsets for the local entries. */
+ for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
+ {
+ bfd_size_type got_offset = alpha_elf_tdata(i)->got->_raw_size;
+ bfd *j;
+
+ for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
+ {
+ struct alpha_elf_got_entry **local_got_entries, *gotent;
+ int k, n;
+
+ local_got_entries = alpha_elf_tdata(j)->local_got_entries;
+ if (!local_got_entries)
+ continue;
+
+ for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
+ for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
+ if (gotent->use_count > 0)
+ {
+ gotent->got_offset = got_offset;
+ got_offset += 8;
+ }
+ }
+
+ alpha_elf_tdata(i)->got->_raw_size = got_offset;
+ alpha_elf_tdata(i)->got->_cooked_size = got_offset;
+ }
+}
+
+/* Constructs the gots. */
+
+static boolean
+elf64_alpha_size_got_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *i, *got_list, *cur_got_obj;
+ int something_changed = 0;
+
+ got_list = alpha_elf_hash_table (info)->got_list;
+
+ /* On the first time through, pretend we have an existing got list
+ consisting of all of the input files. */
+ if (got_list == NULL)
+ {
+ for (i = info->input_bfds; i ; i = i->link_next)
+ {
+ bfd *this_got = alpha_elf_tdata (i)->gotobj;
+ if (this_got == NULL)
+ continue;
+
+ /* We are assuming no merging has yet ocurred. */
+ BFD_ASSERT (this_got == i);
+
+ if (alpha_elf_tdata (this_got)->total_got_entries > MAX_GOT_ENTRIES)
+ {
+ /* Yikes! A single object file has too many entries. */
+ (*_bfd_error_handler)
+ (_("%s: .got subsegment exceeds 64K (size %d)"),
+ bfd_get_filename (i),
+ alpha_elf_tdata (this_got)->total_got_entries * 8);
+ return false;
+ }
+
+ if (got_list == NULL)
+ got_list = this_got;
+ else
+ alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
+ cur_got_obj = this_got;
+ }
+
+ /* Strange degenerate case of no got references. */
+ if (got_list == NULL)
+ return true;
+
+ alpha_elf_hash_table (info)->got_list = got_list;
+
+ /* Force got offsets to be recalculated. */
+ something_changed = 1;
+ }
+
+ cur_got_obj = got_list;
+ i = alpha_elf_tdata(cur_got_obj)->got_link_next;
+ while (i != NULL)
+ {
+ if (elf64_alpha_can_merge_gots (cur_got_obj, i))
+ {
+ elf64_alpha_merge_gots (cur_got_obj, i);
+ i = alpha_elf_tdata(i)->got_link_next;
+ alpha_elf_tdata(cur_got_obj)->got_link_next = i;
+ something_changed = 1;
+ }
+ else
+ {
+ cur_got_obj = i;
+ i = alpha_elf_tdata(i)->got_link_next;
+ }
+ }
+
+ /* Once the gots have been merged, fill in the got offsets for
+ everything therein. */
+ if (1 || something_changed)
+ elf64_alpha_calc_got_offsets (info);
+
+ return true;
+}
+
+static boolean
+elf64_alpha_always_size_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *i;
+
+ if (info->relocateable)
+ return true;
+
+ /* First, take care of the indirect symbols created by versioning. */
+ alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
+ elf64_alpha_merge_ind_symbols,
+ NULL);
+
+ if (!elf64_alpha_size_got_sections (output_bfd, info))
+ return false;
+
+ /* Allocate space for all of the .got subsections. */
+ i = alpha_elf_hash_table (info)->got_list;
+ for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
+ {
+ asection *s = alpha_elf_tdata(i)->got;
+ if (s->_raw_size > 0)
+ {
+ s->contents = (bfd_byte *) bfd_zalloc (i, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Work out the sizes of the dynamic relocation entries. */
+
+static boolean
+elf64_alpha_calc_dynrel_sizes (h, info)
+ struct alpha_elf_link_hash_entry *h;
+ struct bfd_link_info *info;
+{
+ /* If the symbol was defined as a common symbol in a regular object
+ file, and there was no definition in any dynamic object, then the
+ linker will have allocated space for the symbol in a common
+ section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
+ set. This is done for dynamic symbols in
+ elf_adjust_dynamic_symbol but this is not done for non-dynamic
+ symbols, somehow. */
+ if (((h->root.elf_link_hash_flags
+ & (ELF_LINK_HASH_DEF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_DEF_DYNAMIC))
+ == ELF_LINK_HASH_REF_REGULAR)
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
+ {
+ h->root.elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ }
+
+ /* If the symbol is dynamic, we'll need all the relocations in their
+ natural form. If this is a shared object, and it has been forced
+ local, we'll need the same number of RELATIVE relocations. */
+
+ if (alpha_elf_dynamic_symbol_p (&h->root, info) || info->shared)
+ {
+ struct alpha_elf_reloc_entry *relent;
+ bfd *dynobj;
+ struct alpha_elf_got_entry *gotent;
+ bfd_size_type count;
+ asection *srel;
+
+ for (relent = h->reloc_entries; relent; relent = relent->next)
+ if (relent->rtype == R_ALPHA_REFLONG
+ || relent->rtype == R_ALPHA_REFQUAD)
+ {
+ relent->srel->_raw_size +=
+ sizeof(Elf64_External_Rela) * relent->count;
+ }
+
+ dynobj = elf_hash_table(info)->dynobj;
+ count = 0;
+
+ for (gotent = h->got_entries; gotent ; gotent = gotent->next)
+ count++;
+
+ /* If we are using a .plt entry, subtract one, as the first
+ reference uses a .rela.plt entry instead. */
+ if (h->root.plt.offset != MINUS_ONE)
+ count--;
+
+ if (count > 0)
+ {
+ srel = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf64_External_Rela) * count;
+ }
+ }
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+elf64_alpha_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean reltext;
+ boolean relplt;
+
+ dynobj = elf_hash_table(info)->dynobj;
+ BFD_ASSERT(dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (!info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+
+ /* Now that we've seen all of the input files, we can decide which
+ symbols need dynamic relocation entries and which don't. We've
+ collected information in check_relocs that we can now apply to
+ size the dynamic relocation sections. */
+ alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
+ elf64_alpha_calc_dynrel_sizes,
+ info);
+
+ /* When building shared libraries, each local .got entry needs a
+ RELATIVE reloc. */
+ if (info->shared)
+ {
+ bfd *i;
+ asection *srel;
+ bfd_size_type count;
+
+ srel = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srel != NULL);
+
+ for (i = alpha_elf_hash_table(info)->got_list, count = 0;
+ i != NULL;
+ i = alpha_elf_tdata(i)->got_link_next)
+ count += alpha_elf_tdata(i)->n_local_got_entries;
+
+ srel->_raw_size += count * sizeof(Elf64_External_Rela);
+ }
+ }
+ /* else we're not dynamic and by definition we don't need such things. */
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ reltext = false;
+ relplt = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ if (!(s->flags & SEC_LINKER_CREATED))
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ /* If we don't need this section, strip it from the output file.
+ This is to handle .rela.bss and .rela.plt. We must create it
+ in create_dynamic_sections, because it must be created before
+ the linker maps input sections to output sections. The
+ linker does that before adjust_dynamic_symbol is called, and
+ it is that function which decides whether anything needs to
+ go into these sections. */
+
+ strip = false;
+
+ if (strncmp (name, ".rela", 5) == 0)
+ {
+ strip = (s->_raw_size == 0);
+
+ if (!strip)
+ {
+ const char *outname;
+ asection *target;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL entry. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 5);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0
+ && (target->flags & SEC_ALLOC) != 0)
+ reltext = true;
+
+ if (strcmp(name, ".rela.plt") == 0)
+ relplt = true;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strcmp (name, ".plt") != 0)
+ {
+ /* It's not one of our dynamic sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ _bfd_strip_section_from_output (s);
+ else
+ {
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc(dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+ }
+
+ /* If we are generating a shared library, we generate a section
+ symbol for each output section. These are local symbols, which
+ means that they must come first in the dynamic symbol table.
+ That means we must increment the dynamic symbol index of every
+ other dynamic symbol. */
+ if (info->shared)
+ {
+ long c[2], i;
+ asection *p;
+
+ c[0] = 0;
+ c[1] = bfd_count_sections (output_bfd);
+
+ elf_hash_table (info)->dynsymcount += c[1];
+ elf_link_hash_traverse (elf_hash_table(info),
+ elf64_alpha_adjust_dynindx,
+ (PTR) c);
+
+ for (i = 1, p = output_bfd->sections;
+ p != NULL;
+ p = p->next, i++)
+ {
+ elf_section_data (p)->dynindx = i;
+ /* These symbols will have no names, so we don't need to
+ fiddle with dynstr_index. */
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf64_alpha_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (!info->shared)
+ {
+ if (!bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0))
+ return false;
+
+ if (relplt)
+ {
+ if (! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
+ return false;
+ }
+
+ if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
+ sizeof(Elf64_External_Rela)))
+ return false;
+
+ if (reltext)
+ {
+ if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+
+static boolean
+elf64_alpha_adjust_dynindx (h, cparg)
+ struct elf_link_hash_entry *h;
+ PTR cparg;
+{
+ long *cp = (long *)cparg;
+
+ if (h->dynindx >= cp[0])
+ h->dynindx += cp[1];
+
+ return true;
+}
+
+/* Relocate an Alpha ELF section. */
+
+static boolean
+elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ asection *sec, *sgot, *srel, *srelgot;
+ bfd *dynobj, *gotobj;
+ bfd_vma gp;
+
+ srelgot = srel = NULL;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj)
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ }
+
+ /* Find the gp value for this input bfd. */
+ sgot = NULL;
+ gp = 0;
+ gotobj = alpha_elf_tdata (input_bfd)->gotobj;
+ if (gotobj)
+ {
+ sgot = alpha_elf_tdata (gotobj)->got;
+ gp = _bfd_get_gp_value (gotobj);
+ if (gp == 0)
+ {
+ gp = (sgot->output_section->vma
+ + sgot->output_offset
+ + 0x8000);
+ _bfd_set_gp_value (gotobj, gp);
+ }
+ }
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct alpha_elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ bfd_vma relocation;
+ bfd_vma addend;
+ bfd_reloc_status_type r;
+
+ r_type = ELF64_R_TYPE(rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_ALPHA_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto = elf64_alpha_howto_table + r_type;
+
+ r_symndx = ELF64_R_SYM(rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info];
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
+
+ if (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.root.u.def.section;
+
+#if rth_notdef
+ if ((r_type == R_ALPHA_LITERAL
+ && elf_hash_table(info)->dynamic_sections_created
+ && (!info->shared
+ || !info->symbolic
+ || !(h->root.elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR)))
+ || (info->shared
+ && (!info->symbolic
+ || !(h->root.elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR))
+ && (input_section->flags & SEC_ALLOC)
+ && (r_type == R_ALPHA_REFLONG
+ || r_type == R_ALPHA_REFQUAD
+ || r_type == R_ALPHA_LITERAL)))
+ {
+ /* In these cases, we don't need the relocation value.
+ We check specially because in some obscure cases
+ sec->output_section will be NULL. */
+ relocation = 0;
+ }
+#else
+ /* FIXME: Are not these obscure cases simply bugs? Let's
+ get something working and come back to this. */
+ if (sec->output_section == NULL)
+ relocation = 0;
+#endif /* rth_notdef */
+ else
+ {
+ relocation = (h->root.root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ }
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else
+ {
+ if (!((*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+ addend = rel->r_addend;
+
+ switch (r_type)
+ {
+ case R_ALPHA_GPDISP:
+ {
+ bfd_byte *p_ldah, *p_lda;
+
+ BFD_ASSERT(gp != 0);
+
+ relocation = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ p_ldah = contents + rel->r_offset - input_section->vma;
+ p_lda = p_ldah + rel->r_addend;
+
+ r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - relocation,
+ p_ldah, p_lda);
+ }
+ break;
+
+ case R_ALPHA_OP_PUSH:
+ case R_ALPHA_OP_STORE:
+ case R_ALPHA_OP_PSUB:
+ case R_ALPHA_OP_PRSHIFT:
+ /* We hate these silly beasts. */
+ abort();
+
+ case R_ALPHA_LITERAL:
+ {
+ struct alpha_elf_got_entry *gotent;
+ boolean dynamic_symbol;
+
+ BFD_ASSERT(sgot != NULL);
+ BFD_ASSERT(gp != 0);
+
+ if (h != NULL)
+ {
+ gotent = h->got_entries;
+ dynamic_symbol = alpha_elf_dynamic_symbol_p (&h->root, info);
+ }
+ else
+ {
+ gotent = (alpha_elf_tdata(input_bfd)->
+ local_got_entries[r_symndx]);
+ dynamic_symbol = false;
+ }
+
+ BFD_ASSERT(gotent != NULL);
+
+ while (gotent->gotobj != gotobj || gotent->addend != addend)
+ gotent = gotent->next;
+
+ BFD_ASSERT(gotent->use_count >= 1);
+
+ /* Initialize the .got entry's value. */
+ if (!(gotent->flags & ALPHA_ELF_GOT_ENTRY_RELOCS_DONE))
+ {
+ bfd_put_64 (output_bfd, relocation+addend,
+ sgot->contents + gotent->got_offset);
+
+ /* If the symbol has been forced local, output a
+ RELATIVE reloc, otherwise it will be handled in
+ finish_dynamic_symbol. */
+ if (info->shared && !dynamic_symbol)
+ {
+ Elf_Internal_Rela outrel;
+
+ BFD_ASSERT(srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
+ outrel.r_addend = 0;
+
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ ((Elf64_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count++);
+ BFD_ASSERT (sizeof(Elf64_External_Rela)
+ * srelgot->reloc_count
+ <= srelgot->_cooked_size);
+ }
+
+ gotent->flags |= ALPHA_ELF_GOT_ENTRY_RELOCS_DONE;
+ }
+
+ /* Figure the gprel relocation. */
+ addend = 0;
+ relocation = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ relocation -= gp;
+ }
+ /* overflow handled by _bfd_final_link_relocate */
+ goto default_reloc;
+
+ case R_ALPHA_GPREL32:
+ case R_ALPHA_GPRELLOW:
+ BFD_ASSERT(gp != 0);
+ relocation -= gp;
+ goto default_reloc;
+
+ case R_ALPHA_GPRELHIGH:
+ BFD_ASSERT(gp != 0);
+ relocation -= gp;
+ relocation += addend;
+ addend = 0;
+ relocation = (((bfd_signed_vma) relocation >> 16)
+ + ((relocation >> 15) & 1));
+ goto default_reloc;
+
+ case R_ALPHA_BRADDR:
+ case R_ALPHA_HINT:
+ /* The regular PC-relative stuff measures from the start of
+ the instruction rather than the end. */
+ addend -= 4;
+ goto default_reloc;
+
+ case R_ALPHA_REFLONG:
+ case R_ALPHA_REFQUAD:
+ {
+ Elf_Internal_Rela outrel;
+ boolean skip;
+
+ /* Careful here to remember RELATIVE relocations for global
+ variables for symbolic shared objects. */
+
+ if (h && alpha_elf_dynamic_symbol_p (&h->root, info))
+ {
+ BFD_ASSERT(h->root.dynindx != -1);
+ outrel.r_info = ELF64_R_INFO(h->root.dynindx, r_type);
+ outrel.r_addend = addend;
+ addend = 0, relocation = 0;
+ }
+ else if (info->shared)
+ {
+ outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
+ outrel.r_addend = 0;
+ }
+ else
+ goto default_reloc;
+
+ if (!srel)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
+ elf_section_data(input_section)->rel_hdr.sh_name));
+ BFD_ASSERT(name != NULL);
+
+ srel = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT(srel != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == (bfd_vma) -1)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ if (! skip)
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ else
+ memset (&outrel, 0, sizeof outrel);
+
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ ((Elf64_External_Rela *)
+ srel->contents)
+ + srel->reloc_count++);
+ BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count
+ <= srel->_cooked_size);
+ }
+ goto default_reloc;
+
+ default:
+ default_reloc:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, relocation,
+ addend);
+ break;
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.root.string;
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ }
+ }
+
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+elf64_alpha_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj = elf_hash_table(info)->dynobj;
+
+ if (h->plt.offset != MINUS_ONE)
+ {
+ /* Fill in the .plt entry for this symbol. */
+ asection *splt, *sgot, *srel;
+ Elf_Internal_Rela outrel;
+ bfd_vma got_addr, plt_addr;
+ bfd_vma plt_index;
+ struct alpha_elf_got_entry *gotent;
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ /* The first .got entry will be updated by the .plt with the
+ address of the target function. */
+ gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
+ BFD_ASSERT (gotent && gotent->addend == 0);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ srel = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (srel != NULL);
+ sgot = alpha_elf_tdata (gotent->gotobj)->got;
+ BFD_ASSERT (sgot != NULL);
+
+ got_addr = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ plt_addr = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+
+ plt_index = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
+
+ /* Fill in the entry in the procedure linkage table. */
+ {
+ unsigned insn1, insn2, insn3;
+
+ insn1 = PLT_ENTRY_WORD1 | ((-(h->plt.offset + 4) >> 2) & 0x1fffff);
+ insn2 = PLT_ENTRY_WORD2;
+ insn3 = PLT_ENTRY_WORD3;
+
+ bfd_put_32 (output_bfd, insn1, splt->contents + h->plt.offset);
+ bfd_put_32 (output_bfd, insn2, splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, insn3, splt->contents + h->plt.offset + 8);
+ }
+
+ /* Fill in the entry in the .rela.plt section. */
+ outrel.r_offset = got_addr;
+ outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
+ outrel.r_addend = 0;
+
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ ((Elf64_External_Rela *)srel->contents
+ + plt_index));
+
+ if (!(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ {
+ /* Mark the symbol as undefined, rather than as defined in the
+ .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+
+ /* Fill in the entries in the .got. */
+ bfd_put_64 (output_bfd, plt_addr, sgot->contents + gotent->got_offset);
+
+ /* Subsequent .got entries will continue to bounce through the .plt. */
+ if (gotent->next)
+ {
+ srel = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (! info->shared || srel != NULL);
+
+ gotent = gotent->next;
+ do
+ {
+ sgot = alpha_elf_tdata(gotent->gotobj)->got;
+ BFD_ASSERT(sgot != NULL);
+ BFD_ASSERT(gotent->addend == 0);
+
+ bfd_put_64 (output_bfd, plt_addr,
+ sgot->contents + gotent->got_offset);
+
+ if (info->shared)
+ {
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
+ outrel.r_addend = 0;
+
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ ((Elf64_External_Rela *)
+ srel->contents)
+ + srel->reloc_count++);
+ BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count
+ <= srel->_cooked_size);
+ }
+
+ gotent = gotent->next;
+ }
+ while (gotent != NULL);
+ }
+ }
+ else if (alpha_elf_dynamic_symbol_p (h, info))
+ {
+ /* Fill in the dynamic relocations for this symbol's .got entries. */
+ asection *srel;
+ Elf_Internal_Rela outrel;
+ struct alpha_elf_got_entry *gotent;
+
+ srel = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srel != NULL);
+
+ outrel.r_info = ELF64_R_INFO (h->dynindx, R_ALPHA_GLOB_DAT);
+ for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
+ gotent != NULL;
+ gotent = gotent->next)
+ {
+ asection *sgot = alpha_elf_tdata (gotent->gotobj)->got;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ outrel.r_addend = gotent->addend;
+
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ ((Elf64_External_Rela *)srel->contents
+ + srel->reloc_count++));
+ BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count
+ <= srel->_cooked_size);
+ }
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
+ || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+elf64_alpha_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf64_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ asection *s;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT:
+ name = ".plt";
+ goto get_vma;
+ case DT_PLTRELSZ:
+ name = ".rela.plt";
+ goto get_size;
+ case DT_JMPREL:
+ name = ".rela.plt";
+ goto get_vma;
+
+ case DT_RELASZ:
+ /* My interpretation of the TIS v1.1 ELF document indicates
+ that RELASZ should not include JMPREL. This is not what
+ the rest of the BFD does. It is, however, what the
+ glibc ld.so wants. Do this fixup here until we found
+ out who is right. */
+ s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+ if (s)
+ {
+ dyn.d_un.d_val -=
+ (s->_cooked_size ? s->_cooked_size : s->_raw_size);
+ }
+ break;
+
+ get_vma:
+ s = bfd_get_section_by_name (output_bfd, name);
+ dyn.d_un.d_ptr = (s ? s->vma : 0);
+ break;
+
+ get_size:
+ s = bfd_get_section_by_name (output_bfd, name);
+ dyn.d_un.d_val =
+ (s->_cooked_size ? s->_cooked_size : s->_raw_size);
+ break;
+ }
+
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ /* Initialize the PLT0 entry */
+ if (splt->_raw_size > 0)
+ {
+ bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents);
+ bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT_HEADER_WORD3, splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT_HEADER_WORD4, splt->contents + 12);
+
+ /* The next two words will be filled in by ld.so */
+ bfd_put_64 (output_bfd, 0, splt->contents + 16);
+ bfd_put_64 (output_bfd, 0, splt->contents + 24);
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize =
+ PLT_HEADER_SIZE;
+ }
+ }
+
+ if (info->shared)
+ {
+ asection *sdynsym;
+ asection *s;
+ Elf_Internal_Sym sym;
+
+ /* Set up the section symbols for the output sections. */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (sdynsym != NULL);
+
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx;
+
+ sym.st_value = s->vma;
+
+ indx = elf_section_data (s)->this_idx;
+ BFD_ASSERT (indx > 0);
+ sym.st_shndx = indx;
+
+ bfd_elf64_swap_symbol_out (output_bfd, &sym,
+ (PTR) (((Elf64_External_Sym *)
+ sdynsym->contents)
+ + elf_section_data (s)->dynindx));
+ }
+
+ /* Set the sh_info field of the output .dynsym section to the
+ index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
+ bfd_count_sections (output_bfd) + 1;
+ }
+
+ return true;
+}
+
+/* We need to use a special link routine to handle the .reginfo and
+ the .mdebug sections. We need to merge all instances of these
+ sections together, not write them all out sequentially. */
+
+static boolean
+elf64_alpha_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *o;
+ struct bfd_link_order *p;
+ asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec;
+ struct ecoff_debug_info debug;
+ const struct ecoff_debug_swap *swap
+ = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ HDRR *symhdr = &debug.symbolic_header;
+ PTR mdebug_handle = NULL;
+
+#if 0
+ if (++ngots == 2)
+ {
+ (*info->callbacks->warning)
+ (info, _("using multiple gp values"), (char *) NULL,
+ output_bfd, (asection *) NULL, (bfd_vma) 0);
+ }
+#endif
+
+ /* Go through the sections and collect the .reginfo and .mdebug
+ information. */
+ reginfo_sec = NULL;
+ mdebug_sec = NULL;
+ gptab_data_sec = NULL;
+ gptab_bss_sec = NULL;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+#ifdef ERIC_neverdef
+ if (strcmp (o->name, ".reginfo") == 0)
+ {
+ memset (&reginfo, 0, sizeof reginfo);
+
+ /* We have found the .reginfo section in the output file.
+ Look through all the link_orders comprising it and merge
+ the information together. */
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ Elf64_External_RegInfo ext;
+ Elf64_RegInfo sub;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ /* The linker emulation code has probably clobbered the
+ size to be zero bytes. */
+ if (input_section->_raw_size == 0)
+ input_section->_raw_size = sizeof (Elf64_External_RegInfo);
+
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (PTR) &ext,
+ (file_ptr) 0,
+ sizeof ext))
+ return false;
+
+ bfd_alpha_elf64_swap_reginfo_in (input_bfd, &ext, &sub);
+
+ reginfo.ri_gprmask |= sub.ri_gprmask;
+ reginfo.ri_cprmask[0] |= sub.ri_cprmask[0];
+ reginfo.ri_cprmask[1] |= sub.ri_cprmask[1];
+ reginfo.ri_cprmask[2] |= sub.ri_cprmask[2];
+ reginfo.ri_cprmask[3] |= sub.ri_cprmask[3];
+
+ /* ri_gp_value is set by the function
+ alpha_elf_section_processing when the section is
+ finally written out. */
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ /* Force the section size to the value we want. */
+ o->_raw_size = sizeof (Elf64_External_RegInfo);
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+
+ reginfo_sec = o;
+ }
+#endif
+
+ if (strcmp (o->name, ".mdebug") == 0)
+ {
+ struct extsym_info einfo;
+
+ /* We have found the .mdebug section in the output file.
+ Look through all the link_orders comprising it and merge
+ the information together. */
+ symhdr->magic = swap->sym_magic;
+ /* FIXME: What should the version stamp be? */
+ symhdr->vstamp = 0;
+ symhdr->ilineMax = 0;
+ symhdr->cbLine = 0;
+ symhdr->idnMax = 0;
+ symhdr->ipdMax = 0;
+ symhdr->isymMax = 0;
+ symhdr->ioptMax = 0;
+ symhdr->iauxMax = 0;
+ symhdr->issMax = 0;
+ symhdr->issExtMax = 0;
+ symhdr->ifdMax = 0;
+ symhdr->crfd = 0;
+ symhdr->iextMax = 0;
+
+ /* We accumulate the debugging information itself in the
+ debug_info structure. */
+ debug.line = NULL;
+ debug.external_dnr = NULL;
+ debug.external_pdr = NULL;
+ debug.external_sym = NULL;
+ debug.external_opt = NULL;
+ debug.external_aux = NULL;
+ debug.ss = NULL;
+ debug.ssext = debug.ssext_end = NULL;
+ debug.external_fdr = NULL;
+ debug.external_rfd = NULL;
+ debug.external_ext = debug.external_ext_end = NULL;
+
+ mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
+ if (mdebug_handle == (PTR) NULL)
+ return false;
+
+ if (1)
+ {
+ asection *s;
+ EXTR esym;
+ bfd_vma last;
+ unsigned int i;
+ static const char * const name[] =
+ {
+ ".text", ".init", ".fini", ".data",
+ ".rodata", ".sdata", ".sbss", ".bss"
+ };
+ static const int sc[] = { scText, scInit, scFini, scData,
+ scRData, scSData, scSBss, scBss };
+
+ esym.jmptbl = 0;
+ esym.cobol_main = 0;
+ esym.weakext = 0;
+ esym.reserved = 0;
+ esym.ifd = ifdNil;
+ esym.asym.iss = issNil;
+ esym.asym.st = stLocal;
+ esym.asym.reserved = 0;
+ esym.asym.index = indexNil;
+ for (i = 0; i < 8; i++)
+ {
+ esym.asym.sc = sc[i];
+ s = bfd_get_section_by_name (abfd, name[i]);
+ if (s != NULL)
+ {
+ esym.asym.value = s->vma;
+ last = s->vma + s->_raw_size;
+ }
+ else
+ esym.asym.value = last;
+
+ if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
+ name[i], &esym))
+ return false;
+ }
+ }
+
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ const struct ecoff_debug_swap *input_swap;
+ struct ecoff_debug_info input_debug;
+ char *eraw_src;
+ char *eraw_end;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
+ || (get_elf_backend_data (input_bfd)
+ ->elf_backend_ecoff_debug_swap) == NULL)
+ {
+ /* I don't know what a non ALPHA ELF bfd would be
+ doing with a .mdebug section, but I don't really
+ want to deal with it. */
+ continue;
+ }
+
+ input_swap = (get_elf_backend_data (input_bfd)
+ ->elf_backend_ecoff_debug_swap);
+
+ BFD_ASSERT (p->size == input_section->_raw_size);
+
+ /* The ECOFF linking code expects that we have already
+ read in the debugging information and set up an
+ ecoff_debug_info structure, so we do that now. */
+ if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
+ &input_debug))
+ return false;
+
+ if (! (bfd_ecoff_debug_accumulate
+ (mdebug_handle, abfd, &debug, swap, input_bfd,
+ &input_debug, input_swap, info)))
+ return false;
+
+ /* Loop through the external symbols. For each one with
+ interesting information, try to find the symbol in
+ the linker global hash table and save the information
+ for the output external symbols. */
+ eraw_src = input_debug.external_ext;
+ eraw_end = (eraw_src
+ + (input_debug.symbolic_header.iextMax
+ * input_swap->external_ext_size));
+ for (;
+ eraw_src < eraw_end;
+ eraw_src += input_swap->external_ext_size)
+ {
+ EXTR ext;
+ const char *name;
+ struct alpha_elf_link_hash_entry *h;
+
+ (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
+ if (ext.asym.sc == scNil
+ || ext.asym.sc == scUndefined
+ || ext.asym.sc == scSUndefined)
+ continue;
+
+ name = input_debug.ssext + ext.asym.iss;
+ h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
+ name, false, false, true);
+ if (h == NULL || h->esym.ifd != -2)
+ continue;
+
+ if (ext.ifd != -1)
+ {
+ BFD_ASSERT (ext.ifd
+ < input_debug.symbolic_header.ifdMax);
+ ext.ifd = input_debug.ifdmap[ext.ifd];
+ }
+
+ h->esym = ext;
+ }
+
+ /* Free up the information we just read. */
+ free (input_debug.line);
+ free (input_debug.external_dnr);
+ free (input_debug.external_pdr);
+ free (input_debug.external_sym);
+ free (input_debug.external_opt);
+ free (input_debug.external_aux);
+ free (input_debug.ss);
+ free (input_debug.ssext);
+ free (input_debug.external_fdr);
+ free (input_debug.external_rfd);
+ free (input_debug.external_ext);
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+#ifdef ERIC_neverdef
+ if (info->shared)
+ {
+ /* Create .rtproc section. */
+ rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
+ if (rtproc_sec == NULL)
+ {
+ flagword flags = (SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY);
+
+ rtproc_sec = bfd_make_section (abfd, ".rtproc");
+ if (rtproc_sec == NULL
+ || ! bfd_set_section_flags (abfd, rtproc_sec, flags)
+ || ! bfd_set_section_alignment (abfd, rtproc_sec, 12))
+ return false;
+ }
+
+ if (! alpha_elf_create_procedure_table (mdebug_handle, abfd,
+ info, rtproc_sec, &debug))
+ return false;
+ }
+#endif
+
+
+ /* Build the external symbol information. */
+ einfo.abfd = abfd;
+ einfo.info = info;
+ einfo.debug = &debug;
+ einfo.swap = swap;
+ einfo.failed = false;
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf64_alpha_output_extsym,
+ (PTR) &einfo);
+ if (einfo.failed)
+ return false;
+
+ /* Set the size of the .mdebug section. */
+ o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+
+ mdebug_sec = o;
+ }
+
+#ifdef ERIC_neverdef
+ if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0)
+ {
+ const char *subname;
+ unsigned int c;
+ Elf64_gptab *tab;
+ Elf64_External_gptab *ext_tab;
+ unsigned int i;
+
+ /* The .gptab.sdata and .gptab.sbss sections hold
+ information describing how the small data area would
+ change depending upon the -G switch. These sections
+ not used in executables files. */
+ if (! info->relocateable)
+ {
+ asection **secpp;
+
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ /* Skip this section later on (I don't think this
+ currently matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+
+ /* Really remove the section. */
+ for (secpp = &abfd->sections;
+ *secpp != o;
+ secpp = &(*secpp)->next)
+ ;
+ *secpp = (*secpp)->next;
+ --abfd->section_count;
+
+ continue;
+ }
+
+ /* There is one gptab for initialized data, and one for
+ uninitialized data. */
+ if (strcmp (o->name, ".gptab.sdata") == 0)
+ gptab_data_sec = o;
+ else if (strcmp (o->name, ".gptab.sbss") == 0)
+ gptab_bss_sec = o;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: illegal section name `%s'"),
+ bfd_get_filename (abfd), o->name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+
+ /* The linker script always combines .gptab.data and
+ .gptab.sdata into .gptab.sdata, and likewise for
+ .gptab.bss and .gptab.sbss. It is possible that there is
+ no .sdata or .sbss section in the output file, in which
+ case we must change the name of the output section. */
+ subname = o->name + sizeof ".gptab" - 1;
+ if (bfd_get_section_by_name (abfd, subname) == NULL)
+ {
+ if (o == gptab_data_sec)
+ o->name = ".gptab.data";
+ else
+ o->name = ".gptab.bss";
+ subname = o->name + sizeof ".gptab" - 1;
+ BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL);
+ }
+
+ /* Set up the first entry. */
+ c = 1;
+ tab = (Elf64_gptab *) bfd_malloc (c * sizeof (Elf64_gptab));
+ if (tab == NULL)
+ return false;
+ tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
+ tab[0].gt_header.gt_unused = 0;
+
+ /* Combine the input sections. */
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ bfd_size_type size;
+ unsigned long last;
+ bfd_size_type gpentry;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_fill_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ /* Combine the gptab entries for this input section one
+ by one. We know that the input gptab entries are
+ sorted by ascending -G value. */
+ size = bfd_section_size (input_bfd, input_section);
+ last = 0;
+ for (gpentry = sizeof (Elf64_External_gptab);
+ gpentry < size;
+ gpentry += sizeof (Elf64_External_gptab))
+ {
+ Elf64_External_gptab ext_gptab;
+ Elf64_gptab int_gptab;
+ unsigned long val;
+ unsigned long add;
+ boolean exact;
+ unsigned int look;
+
+ if (! (bfd_get_section_contents
+ (input_bfd, input_section, (PTR) &ext_gptab,
+ gpentry, sizeof (Elf64_External_gptab))))
+ {
+ free (tab);
+ return false;
+ }
+
+ bfd_alpha_elf64_swap_gptab_in (input_bfd, &ext_gptab,
+ &int_gptab);
+ val = int_gptab.gt_entry.gt_g_value;
+ add = int_gptab.gt_entry.gt_bytes - last;
+
+ exact = false;
+ for (look = 1; look < c; look++)
+ {
+ if (tab[look].gt_entry.gt_g_value >= val)
+ tab[look].gt_entry.gt_bytes += add;
+
+ if (tab[look].gt_entry.gt_g_value == val)
+ exact = true;
+ }
+
+ if (! exact)
+ {
+ Elf64_gptab *new_tab;
+ unsigned int max;
+
+ /* We need a new table entry. */
+ new_tab = ((Elf64_gptab *)
+ bfd_realloc ((PTR) tab,
+ (c + 1) * sizeof (Elf64_gptab)));
+ if (new_tab == NULL)
+ {
+ free (tab);
+ return false;
+ }
+ tab = new_tab;
+ tab[c].gt_entry.gt_g_value = val;
+ tab[c].gt_entry.gt_bytes = add;
+
+ /* Merge in the size for the next smallest -G
+ value, since that will be implied by this new
+ value. */
+ max = 0;
+ for (look = 1; look < c; look++)
+ {
+ if (tab[look].gt_entry.gt_g_value < val
+ && (max == 0
+ || (tab[look].gt_entry.gt_g_value
+ > tab[max].gt_entry.gt_g_value)))
+ max = look;
+ }
+ if (max != 0)
+ tab[c].gt_entry.gt_bytes +=
+ tab[max].gt_entry.gt_bytes;
+
+ ++c;
+ }
+
+ last = int_gptab.gt_entry.gt_bytes;
+ }
+
+ /* Hack: reset the SEC_HAS_CONTENTS flag so that
+ elf_link_input_bfd ignores this section. */
+ input_section->flags &=~ SEC_HAS_CONTENTS;
+ }
+
+ /* The table must be sorted by -G value. */
+ if (c > 2)
+ qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare);
+
+ /* Swap out the table. */
+ ext_tab = ((Elf64_External_gptab *)
+ bfd_alloc (abfd, c * sizeof (Elf64_External_gptab)));
+ if (ext_tab == NULL)
+ {
+ free (tab);
+ return false;
+ }
+
+ for (i = 0; i < c; i++)
+ bfd_alpha_elf64_swap_gptab_out (abfd, tab + i, ext_tab + i);
+ free (tab);
+
+ o->_raw_size = c * sizeof (Elf64_External_gptab);
+ o->contents = (bfd_byte *) ext_tab;
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->link_order_head = (struct bfd_link_order *) NULL;
+ }
+#endif
+
+ }
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (! bfd_elf64_bfd_final_link (abfd, info))
+ return false;
+
+ /* Now write out the computed sections. */
+
+ /* The .got subsections... */
+ {
+ bfd *i, *dynobj = elf_hash_table(info)->dynobj;
+ for (i = alpha_elf_hash_table(info)->got_list;
+ i != NULL;
+ i = alpha_elf_tdata(i)->got_link_next)
+ {
+ asection *sgot;
+
+ /* elf_bfd_final_link already did everything in dynobj. */
+ if (i == dynobj)
+ continue;
+
+ sgot = alpha_elf_tdata(i)->got;
+ if (! bfd_set_section_contents (abfd, sgot->output_section,
+ sgot->contents, sgot->output_offset,
+ sgot->_raw_size))
+ return false;
+ }
+ }
+
+#ifdef ERIC_neverdef
+ if (reginfo_sec != (asection *) NULL)
+ {
+ Elf64_External_RegInfo ext;
+
+ bfd_alpha_elf64_swap_reginfo_out (abfd, &reginfo, &ext);
+ if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext,
+ (file_ptr) 0, sizeof ext))
+ return false;
+ }
+#endif
+
+ if (mdebug_sec != (asection *) NULL)
+ {
+ BFD_ASSERT (abfd->output_has_begun);
+ if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
+ swap, info,
+ mdebug_sec->filepos))
+ return false;
+
+ bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
+ }
+
+ if (gptab_data_sec != (asection *) NULL)
+ {
+ if (! bfd_set_section_contents (abfd, gptab_data_sec,
+ gptab_data_sec->contents,
+ (file_ptr) 0,
+ gptab_data_sec->_raw_size))
+ return false;
+ }
+
+ if (gptab_bss_sec != (asection *) NULL)
+ {
+ if (! bfd_set_section_contents (abfd, gptab_bss_sec,
+ gptab_bss_sec->contents,
+ (file_ptr) 0,
+ gptab_bss_sec->_raw_size))
+ return false;
+ }
+
+ return true;
+}
+
+/* ECOFF swapping routines. These are used when dealing with the
+ .mdebug section, which is in the ECOFF debugging format. Copied
+ from elf32-mips.c. */
+static const struct ecoff_debug_swap
+elf64_alpha_ecoff_debug_swap =
+{
+ /* Symbol table magic number. */
+ magicSym2,
+ /* Alignment of debugging information. E.g., 4. */
+ 8,
+ /* Sizes of external symbolic information. */
+ sizeof (struct hdr_ext),
+ sizeof (struct dnr_ext),
+ sizeof (struct pdr_ext),
+ sizeof (struct sym_ext),
+ sizeof (struct opt_ext),
+ sizeof (struct fdr_ext),
+ sizeof (struct rfd_ext),
+ sizeof (struct ext_ext),
+ /* Functions to swap in external symbolic data. */
+ ecoff_swap_hdr_in,
+ ecoff_swap_dnr_in,
+ ecoff_swap_pdr_in,
+ ecoff_swap_sym_in,
+ ecoff_swap_opt_in,
+ ecoff_swap_fdr_in,
+ ecoff_swap_rfd_in,
+ ecoff_swap_ext_in,
+ _bfd_ecoff_swap_tir_in,
+ _bfd_ecoff_swap_rndx_in,
+ /* Functions to swap out external symbolic data. */
+ ecoff_swap_hdr_out,
+ ecoff_swap_dnr_out,
+ ecoff_swap_pdr_out,
+ ecoff_swap_sym_out,
+ ecoff_swap_opt_out,
+ ecoff_swap_fdr_out,
+ ecoff_swap_rfd_out,
+ ecoff_swap_ext_out,
+ _bfd_ecoff_swap_tir_out,
+ _bfd_ecoff_swap_rndx_out,
+ /* Function to read in symbolic data. */
+ elf64_alpha_read_ecoff_info
+};
+
+#define TARGET_LITTLE_SYM bfd_elf64_alpha_vec
+#define TARGET_LITTLE_NAME "elf64-alpha"
+#define ELF_ARCH bfd_arch_alpha
+#define ELF_MACHINE_CODE EM_ALPHA
+#define ELF_MAXPAGESIZE 0x10000
+
+#define bfd_elf64_bfd_link_hash_table_create \
+ elf64_alpha_bfd_link_hash_table_create
+
+#define bfd_elf64_bfd_reloc_type_lookup \
+ elf64_alpha_bfd_reloc_type_lookup
+#define elf_info_to_howto \
+ elf64_alpha_info_to_howto
+
+#define bfd_elf64_mkobject \
+ elf64_alpha_mkobject
+#define elf_backend_object_p \
+ elf64_alpha_object_p
+
+#define elf_backend_section_from_shdr \
+ elf64_alpha_section_from_shdr
+#define elf_backend_fake_sections \
+ elf64_alpha_fake_sections
+
+#define bfd_elf64_bfd_is_local_label_name \
+ elf64_alpha_is_local_label_name
+#define bfd_elf64_find_nearest_line \
+ elf64_alpha_find_nearest_line
+#define bfd_elf64_bfd_relax_section \
+ elf64_alpha_relax_section
+
+#define elf_backend_add_symbol_hook \
+ elf64_alpha_add_symbol_hook
+#define elf_backend_check_relocs \
+ elf64_alpha_check_relocs
+#define elf_backend_create_dynamic_sections \
+ elf64_alpha_create_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol \
+ elf64_alpha_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ elf64_alpha_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ elf64_alpha_size_dynamic_sections
+#define elf_backend_relocate_section \
+ elf64_alpha_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elf64_alpha_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf64_alpha_finish_dynamic_sections
+#define bfd_elf64_bfd_final_link \
+ elf64_alpha_final_link
+
+#define elf_backend_ecoff_debug_swap \
+ &elf64_alpha_ecoff_debug_swap
+
+/*
+ * A few constants that determine how the .plt section is set up.
+ */
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 1
+#define elf_backend_got_header_size 0
+#define elf_backend_plt_header_size PLT_HEADER_SIZE
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-gen.c b/bfd/elf64-gen.c
new file mode 100644
index 00000000000..2f470ff057f
--- /dev/null
+++ b/bfd/elf64-gen.c
@@ -0,0 +1,71 @@
+/* Generic support for 64-bit ELF
+ Copyright 1993, 1995, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* This does not include any relocation information, but should be
+ good enough for GDB or objdump to read the file. */
+
+static reloc_howto_type dummy =
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "UNKNOWN", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+static void
+elf_generic_info_to_howto (abfd, bfd_reloc, elf_reloc)
+ bfd *abfd;
+ arelent *bfd_reloc;
+ Elf64_Internal_Rela *elf_reloc;
+{
+ bfd_reloc->howto = &dummy;
+}
+
+static void
+elf_generic_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
+ bfd *abfd;
+ arelent *bfd_reloc;
+ Elf64_Internal_Rel *elf_reloc;
+{
+ bfd_reloc->howto = &dummy;
+}
+
+#define TARGET_LITTLE_SYM bfd_elf64_little_generic_vec
+#define TARGET_LITTLE_NAME "elf64-little"
+#define TARGET_BIG_SYM bfd_elf64_big_generic_vec
+#define TARGET_BIG_NAME "elf64-big"
+#define ELF_ARCH bfd_arch_unknown
+#define ELF_MACHINE_CODE EM_NONE
+#define bfd_elf64_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define elf_info_to_howto elf_generic_info_to_howto
+#define elf_info_to_howto_rel elf_generic_info_to_howto_rel
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
new file mode 100644
index 00000000000..9fb8bb9c85e
--- /dev/null
+++ b/bfd/elf64-mips.c
@@ -0,0 +1,2127 @@
+/* MIPS-specific support for 64-bit ELF
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+ Ian Lance Taylor, Cygnus Support
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file supports the 64-bit MIPS ELF ABI.
+
+ The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
+ overrides the usual ELF reloc handling, and handles reading and
+ writing the relocations here.
+
+ The MIPS 64-bit ELF ABI also uses an unusual archive map format. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elf/mips.h"
+
+/* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
+ use ECOFF. However, we support it anyhow for an easier changeover. */
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/internal.h"
+#include "coff/ecoff.h"
+/* The 64 bit versions of the mdebug data structures are in alpha.h. */
+#include "coff/alpha.h"
+#define ECOFF_64
+#include "ecoffswap.h"
+
+static void mips_elf64_swap_reloc_in
+ PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
+ Elf64_Mips_Internal_Rel *));
+static void mips_elf64_swap_reloca_in
+ PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
+ Elf64_Mips_Internal_Rela *));
+#if 0
+static void mips_elf64_swap_reloc_out
+ PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
+ Elf64_Mips_External_Rel *));
+#endif
+static void mips_elf64_swap_reloca_out
+ PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
+ Elf64_Mips_External_Rela *));
+static reloc_howto_type *mips_elf64_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *));
+static boolean mips_elf64_slurp_one_reloc_table
+ PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *));
+static boolean mips_elf64_slurp_reloc_table
+ PARAMS ((bfd *, asection *, asymbol **, boolean));
+static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
+static boolean mips_elf64_section_from_shdr
+ PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
+static boolean mips_elf64_section_processing
+ PARAMS ((bfd *, Elf_Internal_Shdr *));
+static boolean mips_elf64_slurp_armap PARAMS ((bfd *));
+static boolean mips_elf64_write_armap
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+ from smaller values. Start with zero, widen, *then* decrement. */
+#define MINUS_ONE (((bfd_vma)0) - 1)
+
+/* The relocation table used for SHT_REL sections. */
+
+static reloc_howto_type mips_elf64_howto_table_rel[] =
+{
+ /* No relocation. */
+ HOWTO (R_MIPS_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit relocation. */
+ HOWTO (R_MIPS_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit relocation. */
+ HOWTO (R_MIPS_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit symbol relative relocation. */
+ HOWTO (R_MIPS_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 26 bit branch address. */
+ HOWTO (R_MIPS_26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ /* This needs complex overflow
+ detection, because the upper four
+ bits must match the PC. */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ true, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_hi16_reloc, /* special_function */
+ "R_MIPS_HI16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MIPS_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_lo16_reloc, /* special_function */
+ "R_MIPS_LO16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MIPS_GPREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MIPS_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MIPS_GOT16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_got16_reloc, /* special_function */
+ "R_MIPS_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. */
+ HOWTO (R_MIPS_PC16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ /* FIXME: This is not handled correctly. */
+ HOWTO (R_MIPS_CALL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit GP relative reference. */
+ HOWTO (R_MIPS_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ _bfd_mips_elf_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 13 },
+ { 14 },
+ { 15 },
+
+ /* A 5 bit shift field. */
+ HOWTO (R_MIPS_SHIFT5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT5", /* name */
+ true, /* partial_inplace */
+ 0x000007c0, /* src_mask */
+ 0x000007c0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 6 bit shift field. */
+ /* FIXME: This is not handled correctly; a special function is
+ needed to put the most significant bit in the right place. */
+ HOWTO (R_MIPS_SHIFT6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ true, /* partial_inplace */
+ 0x000007c4, /* src_mask */
+ 0x000007c4, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit relocation. */
+ HOWTO (R_MIPS_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_DISP", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_PAGE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_PAGE", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_OFST, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_OFST", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_HI16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_LO16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit substraction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Insert the addend as an instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_INSERT_A, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Insert the addend as an instruction, and change all relocations
+ to refer to the old instruction at the address. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_INSERT_B, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_HIGHER, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHER", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_HIGHEST, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHEST", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_CALL_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_HI16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_CALL_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ true, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* I'm not sure what the remaining relocs are, but they are defined
+ on Irix 6. */
+
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_REL16, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_ADD_IMMEDIATE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PJUMP, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_PJUMP", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+/* The relocation table used for SHT_RELA sections. */
+
+static reloc_howto_type mips_elf64_howto_table_rela[] =
+{
+ /* No relocation. */
+ HOWTO (R_MIPS_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit relocation. */
+ HOWTO (R_MIPS_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit relocation. */
+ HOWTO (R_MIPS_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_32", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit symbol relative relocation. */
+ HOWTO (R_MIPS_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 26 bit branch address. */
+ HOWTO (R_MIPS_26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ /* This needs complex overflow
+ detection, because the upper four
+ bits must match the PC. */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_HI16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MIPS_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_LO16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MIPS_GPREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MIPS_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ /* FIXME: This is not handled correctly. */
+ HOWTO (R_MIPS_GOT16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. */
+ HOWTO (R_MIPS_PC16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ /* FIXME: This is not handled correctly. */
+ HOWTO (R_MIPS_CALL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit GP relative reference. */
+ HOWTO (R_MIPS_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ _bfd_mips_elf_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 13 },
+ { 14 },
+ { 15 },
+
+ /* A 5 bit shift field. */
+ HOWTO (R_MIPS_SHIFT5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT5", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000007c0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 6 bit shift field. */
+ /* FIXME: This is not handled correctly; a special function is
+ needed to put the most significant bit in the right place. */
+ HOWTO (R_MIPS_SHIFT6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ false, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000007c4, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit relocation. */
+ HOWTO (R_MIPS_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_DISP", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_PAGE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_PAGE", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_OFST, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_OFST", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_HI16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_GOT_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_LO16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 64 bit substraction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Insert the addend as an instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_INSERT_A, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Insert the addend as an instruction, and change all relocations
+ to refer to the old instruction at the address. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_INSERT_B, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_HIGHER, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHER", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_HIGHEST, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHEST", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_CALL_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_HI16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_CALL_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* I'm not sure what the remaining relocs are, but they are defined
+ on Irix 6. */
+
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_REL16, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_ADD_IMMEDIATE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PJUMP, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_PJUMP", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+/* Swap in a MIPS 64-bit Rel reloc. */
+
+static void
+mips_elf64_swap_reloc_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf64_Mips_External_Rel *src;
+ Elf64_Mips_Internal_Rel *dst;
+{
+ dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset);
+ dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym);
+ dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym);
+ dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3);
+ dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2);
+ dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type);
+}
+
+/* Swap in a MIPS 64-bit Rela reloc. */
+
+static void
+mips_elf64_swap_reloca_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf64_Mips_External_Rela *src;
+ Elf64_Mips_Internal_Rela *dst;
+{
+ dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset);
+ dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym);
+ dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym);
+ dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3);
+ dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2);
+ dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type);
+ dst->r_addend = bfd_h_get_signed_64 (abfd, (bfd_byte *) src->r_addend);
+}
+
+#if 0
+
+/* This is not currently used. */
+
+/* Swap out a MIPS 64-bit Rel reloc. */
+
+static void
+mips_elf64_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf64_Mips_Internal_Rel *src;
+ Elf64_Mips_External_Rel *dst;
+{
+ bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset);
+ bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym);
+ bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym);
+ bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3);
+ bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2);
+ bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
+}
+
+#endif /* 0 */
+
+/* Swap out a MIPS 64-bit Rela reloc. */
+
+static void
+mips_elf64_swap_reloca_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf64_Mips_Internal_Rela *src;
+ Elf64_Mips_External_Rela *dst;
+{
+ bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset);
+ bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym);
+ bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym);
+ bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3);
+ bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2);
+ bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
+ bfd_h_put_64 (abfd, src->r_addend, (bfd_byte *) dst->r_addend);
+}
+
+/* A mapping from BFD reloc types to MIPS ELF reloc types. */
+
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ enum elf_mips_reloc_type elf_reloc_val;
+};
+
+static CONST struct elf_reloc_map mips_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_MIPS_NONE, },
+ { BFD_RELOC_16, R_MIPS_16 },
+ { BFD_RELOC_32, R_MIPS_32 },
+ { BFD_RELOC_64, R_MIPS_64 },
+ { BFD_RELOC_CTOR, R_MIPS_64 },
+ { BFD_RELOC_32_PCREL, R_MIPS_REL32 },
+ { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
+ { BFD_RELOC_HI16_S, R_MIPS_HI16 },
+ { BFD_RELOC_LO16, R_MIPS_LO16 },
+ { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
+ { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
+ { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
+ { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
+ { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
+ { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
+ { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
+ { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
+ { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
+ { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }
+};
+
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+mips_elf64_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (mips_reloc_map[i].bfd_reloc_val == code)
+ {
+ int v;
+
+ v = (int) mips_reloc_map[i].elf_reloc_val;
+ return &mips_elf64_howto_table_rel[v];
+ }
+ }
+
+ return NULL;
+}
+
+/* Since each entry in an SHT_REL or SHT_RELA section can represent up
+ to three relocs, we must tell the user to allocate more space. */
+
+static long
+mips_elf64_get_reloc_upper_bound (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
+}
+
+/* Read the relocations from one reloc section. */
+
+static boolean
+mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
+ bfd *abfd;
+ asection *asect;
+ asymbol **symbols;
+ const Elf_Internal_Shdr *rel_hdr;
+{
+ PTR allocated = NULL;
+ bfd_byte *native_relocs;
+ arelent *relents;
+ arelent *relent;
+ unsigned int count;
+ unsigned int i;
+ int entsize;
+ reloc_howto_type *howto_table;
+
+ allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
+ if (allocated == NULL)
+ goto error_return;
+
+ if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
+ goto error_return;
+
+ native_relocs = (bfd_byte *) allocated;
+
+ relents = asect->relocation + asect->reloc_count;
+
+ entsize = rel_hdr->sh_entsize;
+ BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
+ || entsize == sizeof (Elf64_Mips_External_Rela));
+
+ count = rel_hdr->sh_size / entsize;
+
+ if (entsize == sizeof (Elf64_Mips_External_Rel))
+ howto_table = mips_elf64_howto_table_rel;
+ else
+ howto_table = mips_elf64_howto_table_rela;
+
+ relent = relents;
+ for (i = 0; i < count; i++, native_relocs += entsize)
+ {
+ Elf64_Mips_Internal_Rela rela;
+ boolean used_sym, used_ssym;
+ int ir;
+
+ if (entsize == sizeof (Elf64_Mips_External_Rela))
+ mips_elf64_swap_reloca_in (abfd,
+ (Elf64_Mips_External_Rela *) native_relocs,
+ &rela);
+ else
+ {
+ Elf64_Mips_Internal_Rel rel;
+
+ mips_elf64_swap_reloc_in (abfd,
+ (Elf64_Mips_External_Rel *) native_relocs,
+ &rel);
+ rela.r_offset = rel.r_offset;
+ rela.r_sym = rel.r_sym;
+ rela.r_ssym = rel.r_ssym;
+ rela.r_type3 = rel.r_type3;
+ rela.r_type2 = rel.r_type2;
+ rela.r_type = rel.r_type;
+ rela.r_addend = 0;
+ }
+
+ /* Each entry represents up to three actual relocations. */
+
+ used_sym = false;
+ used_ssym = false;
+ for (ir = 0; ir < 3; ir++)
+ {
+ enum elf_mips_reloc_type type;
+
+ switch (ir)
+ {
+ default:
+ abort ();
+ case 0:
+ type = (enum elf_mips_reloc_type) rela.r_type;
+ break;
+ case 1:
+ type = (enum elf_mips_reloc_type) rela.r_type2;
+ break;
+ case 2:
+ type = (enum elf_mips_reloc_type) rela.r_type3;
+ break;
+ }
+
+ if (type == R_MIPS_NONE)
+ {
+ /* There are no more relocations in this entry. If this
+ is the first entry, we need to generate a dummy
+ relocation so that the generic linker knows that
+ there has been a break in the sequence of relocations
+ applying to a particular address. */
+ if (ir == 0)
+ {
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ relent->address = rela.r_offset;
+ else
+ relent->address = rela.r_offset - asect->vma;
+ relent->addend = 0;
+ relent->howto = &howto_table[(int) R_MIPS_NONE];
+ ++relent;
+ }
+ break;
+ }
+
+ /* Some types require symbols, whereas some do not. */
+ switch (type)
+ {
+ case R_MIPS_NONE:
+ case R_MIPS_LITERAL:
+ case R_MIPS_INSERT_A:
+ case R_MIPS_INSERT_B:
+ case R_MIPS_DELETE:
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ break;
+
+ default:
+ if (! used_sym)
+ {
+ if (rela.r_sym == 0)
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ else
+ {
+ asymbol **ps, *s;
+
+ ps = symbols + rela.r_sym - 1;
+ s = *ps;
+ if ((s->flags & BSF_SECTION_SYM) == 0)
+ relent->sym_ptr_ptr = ps;
+ else
+ relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
+ }
+
+ used_sym = true;
+ }
+ else if (! used_ssym)
+ {
+ switch (rela.r_ssym)
+ {
+ case RSS_UNDEF:
+ relent->sym_ptr_ptr =
+ bfd_abs_section_ptr->symbol_ptr_ptr;
+ break;
+
+ case RSS_GP:
+ case RSS_GP0:
+ case RSS_LOC:
+ /* FIXME: I think these need to be handled using
+ special howto structures. */
+ BFD_ASSERT (0);
+ break;
+
+ default:
+ BFD_ASSERT (0);
+ break;
+ }
+
+ used_ssym = true;
+ }
+ else
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+
+ break;
+ }
+
+ /* The address of an ELF reloc is section relative for an
+ object file, and absolute for an executable file or
+ shared library. The address of a BFD reloc is always
+ section relative. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ relent->address = rela.r_offset;
+ else
+ relent->address = rela.r_offset - asect->vma;
+
+ relent->addend = rela.r_addend;
+
+ relent->howto = &howto_table[(int) type];
+
+ ++relent;
+ }
+ }
+
+ asect->reloc_count += relent - relents;
+
+ if (allocated != NULL)
+ free (allocated);
+
+ return true;
+
+ error_return:
+ if (allocated != NULL)
+ free (allocated);
+ return false;
+}
+
+/* Read the relocations. On Irix 6, there can be two reloc sections
+ associated with a single data section. */
+
+static boolean
+mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
+ bfd *abfd;
+ asection *asect;
+ asymbol **symbols;
+ boolean dynamic;
+{
+ struct bfd_elf_section_data * const d = elf_section_data (asect);
+
+ if (dynamic)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ if (asect->relocation != NULL
+ || (asect->flags & SEC_RELOC) == 0
+ || asect->reloc_count == 0)
+ return true;
+
+ /* Allocate space for 3 arelent structures for each Rel structure. */
+ asect->relocation = ((arelent *)
+ bfd_alloc (abfd,
+ asect->reloc_count * 3 * sizeof (arelent)));
+ if (asect->relocation == NULL)
+ return false;
+
+ /* The slurp_one_reloc_table routine increments reloc_count. */
+ asect->reloc_count = 0;
+
+ if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
+ return false;
+ if (d->rel_hdr2 != NULL)
+ {
+ if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
+ d->rel_hdr2))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out the relocations. */
+
+static void
+mips_elf64_write_relocs (abfd, sec, data)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+{
+ boolean *failedp = (boolean *) data;
+ unsigned int count;
+ Elf_Internal_Shdr *rela_hdr;
+ Elf64_Mips_External_Rela *ext_rela;
+ unsigned int idx;
+ asymbol *last_sym = 0;
+ int last_sym_idx = 0;
+
+ /* If we have already failed, don't do anything. */
+ if (*failedp)
+ return;
+
+ if ((sec->flags & SEC_RELOC) == 0)
+ return;
+
+ /* The linker backend writes the relocs out itself, and sets the
+ reloc_count field to zero to inhibit writing them here. Also,
+ sometimes the SEC_RELOC flag gets set even when there aren't any
+ relocs. */
+ if (sec->reloc_count == 0)
+ return;
+
+ /* We can combine up to three relocs that refer to the same address
+ if the latter relocs have no associated symbol. */
+ count = 0;
+ for (idx = 0; idx < sec->reloc_count; idx++)
+ {
+ bfd_vma addr;
+ unsigned int i;
+
+ ++count;
+
+ addr = sec->orelocation[idx]->address;
+ for (i = 0; i < 2; i++)
+ {
+ arelent *r;
+
+ if (idx + 1 >= sec->reloc_count)
+ break;
+ r = sec->orelocation[idx + 1];
+ if (r->address != addr
+ || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
+ || (*r->sym_ptr_ptr)->value != 0)
+ break;
+
+ /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
+
+ ++idx;
+ }
+ }
+
+ rela_hdr = &elf_section_data (sec)->rel_hdr;
+
+ rela_hdr->sh_size = rela_hdr->sh_entsize * count;
+ rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
+ if (rela_hdr->contents == NULL)
+ {
+ *failedp = true;
+ return;
+ }
+
+ ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
+ for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
+ {
+ arelent *ptr;
+ Elf64_Mips_Internal_Rela int_rela;
+ asymbol *sym;
+ int n;
+ unsigned int i;
+
+ ptr = sec->orelocation[idx];
+
+ /* The address of an ELF reloc is section relative for an object
+ file, and absolute for an executable file or shared library.
+ The address of a BFD reloc is always section relative. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ int_rela.r_offset = ptr->address;
+ else
+ int_rela.r_offset = ptr->address + sec->vma;
+
+ sym = *ptr->sym_ptr_ptr;
+ if (sym == last_sym)
+ n = last_sym_idx;
+ else
+ {
+ last_sym = sym;
+ n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
+ if (n < 0)
+ {
+ *failedp = true;
+ return;
+ }
+ last_sym_idx = n;
+ }
+
+ int_rela.r_sym = n;
+
+ int_rela.r_addend = ptr->addend;
+
+ int_rela.r_ssym = RSS_UNDEF;
+
+ if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
+ {
+ *failedp = true;
+ return;
+ }
+
+ int_rela.r_type = ptr->howto->type;
+ int_rela.r_type2 = (int) R_MIPS_NONE;
+ int_rela.r_type3 = (int) R_MIPS_NONE;
+
+ for (i = 0; i < 2; i++)
+ {
+ arelent *r;
+
+ if (idx + 1 >= sec->reloc_count)
+ break;
+ r = sec->orelocation[idx + 1];
+ if (r->address != ptr->address
+ || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
+ || (*r->sym_ptr_ptr)->value != 0)
+ break;
+
+ /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
+
+ if (i == 0)
+ int_rela.r_type2 = r->howto->type;
+ else
+ int_rela.r_type3 = r->howto->type;
+
+ ++idx;
+ }
+
+ mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
+ }
+
+ BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
+ == count);
+}
+
+/* Handle a 64-bit MIPS ELF specific section. */
+
+static boolean
+mips_elf64_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ char *name;
+{
+ if (! _bfd_mips_elf_section_from_shdr (abfd, hdr, name))
+ return false;
+
+ /* For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and
+ set the gp value based on what we find. We may see both
+ SHT_MIPS_REGINFO and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case,
+ they should agree. */
+ if (hdr->sh_type == SHT_MIPS_OPTIONS)
+ {
+ bfd_byte *contents, *l, *lend;
+
+ contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
+ if (contents == NULL)
+ return false;
+ if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
+ (file_ptr) 0, hdr->sh_size))
+ {
+ free (contents);
+ return false;
+ }
+ l = contents;
+ lend = contents + hdr->sh_size;
+ while (l + sizeof (Elf_External_Options) <= lend)
+ {
+ Elf_Internal_Options intopt;
+
+ bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
+ &intopt);
+ if (intopt.kind == ODK_REGINFO)
+ {
+ Elf64_Internal_RegInfo intreg;
+
+ bfd_mips_elf64_swap_reginfo_in
+ (abfd,
+ ((Elf64_External_RegInfo *)
+ (l + sizeof (Elf_External_Options))),
+ &intreg);
+ elf_gp (abfd) = intreg.ri_gp_value;
+ }
+ l += intopt.size;
+ }
+ free (contents);
+ }
+
+ return true;
+}
+
+/* Work over a section just before writing it out. We update the GP
+ value in the SHT_MIPS_OPTIONS section based on the value we are
+ using. */
+
+static boolean
+mips_elf64_section_processing (abfd, hdr)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+{
+ if (hdr->sh_type == SHT_MIPS_OPTIONS
+ && hdr->bfd_section != NULL
+ && elf_section_data (hdr->bfd_section) != NULL
+ && elf_section_data (hdr->bfd_section)->tdata != NULL)
+ {
+ bfd_byte *contents, *l, *lend;
+
+ /* We stored the section contents in the elf_section_data tdata
+ field in the set_section_contents routine. We save the
+ section contents so that we don't have to read them again.
+ At this point we know that elf_gp is set, so we can look
+ through the section contents to see if there is an
+ ODK_REGINFO structure. */
+
+ contents = (bfd_byte *) elf_section_data (hdr->bfd_section)->tdata;
+ l = contents;
+ lend = contents + hdr->sh_size;
+ while (l + sizeof (Elf_External_Options) <= lend)
+ {
+ Elf_Internal_Options intopt;
+
+ bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
+ &intopt);
+ if (intopt.kind == ODK_REGINFO)
+ {
+ bfd_byte buf[8];
+
+ if (bfd_seek (abfd,
+ (hdr->sh_offset
+ + (l - contents)
+ + sizeof (Elf_External_Options)
+ + (sizeof (Elf64_External_RegInfo) - 8)),
+ SEEK_SET) == -1)
+ return false;
+ bfd_h_put_64 (abfd, elf_gp (abfd), buf);
+ if (bfd_write (buf, 1, 8, abfd) != 8)
+ return false;
+ }
+ l += intopt.size;
+ }
+ }
+
+ return _bfd_mips_elf_section_processing (abfd, hdr);
+}
+
+/* Irix 6 defines a brand new archive map format, so that they can
+ have archives more than 4 GB in size. */
+
+/* Read an Irix 6 armap. */
+
+static boolean
+mips_elf64_slurp_armap (abfd)
+ bfd *abfd;
+{
+ struct artdata *ardata = bfd_ardata (abfd);
+ char nextname[17];
+ file_ptr arhdrpos;
+ bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
+ struct areltdata *mapdata;
+ bfd_byte int_buf[8];
+ char *stringbase;
+ bfd_byte *raw_armap = NULL;
+ carsym *carsyms;
+
+ ardata->symdefs = NULL;
+
+ /* Get the name of the first element. */
+ arhdrpos = bfd_tell (abfd);
+ i = bfd_read ((PTR) nextname, 1, 16, abfd);
+ if (i == 0)
+ return true;
+ if (i != 16)
+ return false;
+
+ if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
+ return false;
+
+ /* Archives with traditional armaps are still permitted. */
+ if (strncmp (nextname, "/ ", 16) == 0)
+ return bfd_slurp_armap (abfd);
+
+ if (strncmp (nextname, "/SYM64/ ", 16) != 0)
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return false;
+ parsed_size = mapdata->parsed_size;
+ bfd_release (abfd, (PTR) mapdata);
+
+ if (bfd_read (int_buf, 1, 8, abfd) != 8)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
+ }
+
+ nsymz = bfd_getb64 (int_buf);
+ stringsize = parsed_size - 8 * nsymz - 8;
+
+ carsym_size = nsymz * sizeof (carsym);
+ ptrsize = 8 * nsymz;
+
+ ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
+ if (ardata->symdefs == NULL)
+ return false;
+ carsyms = ardata->symdefs;
+ stringbase = ((char *) ardata->symdefs) + carsym_size;
+
+ raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
+ if (raw_armap == NULL)
+ goto error_return;
+
+ if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize
+ || bfd_read (stringbase, 1, stringsize, abfd) != stringsize)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ goto error_return;
+ }
+
+ for (i = 0; i < nsymz; i++)
+ {
+ carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
+ carsyms->name = stringbase;
+ stringbase += strlen (stringbase) + 1;
+ ++carsyms;
+ }
+ *stringbase = '\0';
+
+ ardata->symdef_count = nsymz;
+ ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size;
+
+ bfd_has_map (abfd) = true;
+ bfd_release (abfd, raw_armap);
+
+ return true;
+
+ error_return:
+ if (raw_armap != NULL)
+ bfd_release (abfd, raw_armap);
+ if (ardata->symdefs != NULL)
+ bfd_release (abfd, ardata->symdefs);
+ return false;
+}
+
+/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
+ able to handle ordinary ELF armaps, but at least on Irix 6.2 the
+ linker crashes. */
+
+static boolean
+mips_elf64_write_armap (arch, elength, map, symbol_count, stridx)
+ bfd *arch;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int symbol_count;
+ int stridx;
+{
+ unsigned int ranlibsize = (symbol_count * 8) + 8;
+ unsigned int stringsize = stridx;
+ unsigned int mapsize = stringsize + ranlibsize;
+ file_ptr archive_member_file_ptr;
+ bfd *current = arch->archive_head;
+ unsigned int count;
+ struct ar_hdr hdr;
+ unsigned int i;
+ int padding;
+ bfd_byte buf[8];
+
+ padding = BFD_ALIGN (mapsize, 8) - mapsize;
+ mapsize += padding;
+
+ /* work out where the first object file will go in the archive */
+ archive_member_file_ptr = (mapsize
+ + elength
+ + sizeof (struct ar_hdr)
+ + SARMAG);
+
+ memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
+ strcpy (hdr.ar_name, "/SYM64/");
+ sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+ sprintf (hdr.ar_date, "%ld", (long) time (NULL));
+ /* This, at least, is what Intel coff sets the values to.: */
+ sprintf ((hdr.ar_uid), "%d", 0);
+ sprintf ((hdr.ar_gid), "%d", 0);
+ sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
+ strncpy (hdr.ar_fmag, ARFMAG, 2);
+
+ for (i = 0; i < sizeof (struct ar_hdr); i++)
+ if (((char *) (&hdr))[i] == '\0')
+ (((char *) (&hdr))[i]) = ' ';
+
+ /* Write the ar header for this item and the number of symbols */
+
+ if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ return false;
+
+ bfd_putb64 (symbol_count, buf);
+ if (bfd_write (buf, 1, 8, arch) != 8)
+ return false;
+
+ /* Two passes, first write the file offsets for each symbol -
+ remembering that each offset is on a two byte boundary. */
+
+ /* Write out the file offset for the file associated with each
+ symbol, and remember to keep the offsets padded out. */
+
+ current = arch->archive_head;
+ count = 0;
+ while (current != (bfd *) NULL && count < symbol_count)
+ {
+ /* For each symbol which is used defined in this object, write out
+ the object file's address in the archive */
+
+ while (((bfd *) (map[count]).pos) == current)
+ {
+ bfd_putb64 (archive_member_file_ptr, buf);
+ if (bfd_write (buf, 1, 8, arch) != 8)
+ return false;
+ count++;
+ }
+ /* Add size of this archive entry */
+ archive_member_file_ptr += (arelt_size (current)
+ + sizeof (struct ar_hdr));
+ /* remember about the even alignment */
+ archive_member_file_ptr += archive_member_file_ptr % 2;
+ current = current->next;
+ }
+
+ /* now write the strings themselves */
+ for (count = 0; count < symbol_count; count++)
+ {
+ size_t len = strlen (*map[count].name) + 1;
+
+ if (bfd_write (*map[count].name, 1, len, arch) != len)
+ return false;
+ }
+
+ /* The spec says that this should be padded to an 8 byte boundary.
+ However, the Irix 6.2 tools do not appear to do this. */
+ while (padding != 0)
+ {
+ if (bfd_write ("", 1, 1, arch) != 1)
+ return false;
+ --padding;
+ }
+
+ return true;
+}
+
+/* ECOFF swapping routines. These are used when dealing with the
+ .mdebug section, which is in the ECOFF debugging format. */
+static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
+{
+ /* Symbol table magic number. */
+ magicSym2,
+ /* Alignment of debugging information. E.g., 4. */
+ 8,
+ /* Sizes of external symbolic information. */
+ sizeof (struct hdr_ext),
+ sizeof (struct dnr_ext),
+ sizeof (struct pdr_ext),
+ sizeof (struct sym_ext),
+ sizeof (struct opt_ext),
+ sizeof (struct fdr_ext),
+ sizeof (struct rfd_ext),
+ sizeof (struct ext_ext),
+ /* Functions to swap in external symbolic data. */
+ ecoff_swap_hdr_in,
+ ecoff_swap_dnr_in,
+ ecoff_swap_pdr_in,
+ ecoff_swap_sym_in,
+ ecoff_swap_opt_in,
+ ecoff_swap_fdr_in,
+ ecoff_swap_rfd_in,
+ ecoff_swap_ext_in,
+ _bfd_ecoff_swap_tir_in,
+ _bfd_ecoff_swap_rndx_in,
+ /* Functions to swap out external symbolic data. */
+ ecoff_swap_hdr_out,
+ ecoff_swap_dnr_out,
+ ecoff_swap_pdr_out,
+ ecoff_swap_sym_out,
+ ecoff_swap_opt_out,
+ ecoff_swap_fdr_out,
+ ecoff_swap_rfd_out,
+ ecoff_swap_ext_out,
+ _bfd_ecoff_swap_tir_out,
+ _bfd_ecoff_swap_rndx_out,
+ /* Function to read in symbolic data. */
+ _bfd_mips_elf_read_ecoff_info
+};
+
+/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
+ standard ELF. This structure is used to redirect the relocation
+ handling routines. */
+
+const struct elf_size_info mips_elf64_size_info =
+{
+ sizeof (Elf64_External_Ehdr),
+ sizeof (Elf64_External_Phdr),
+ sizeof (Elf64_External_Shdr),
+ sizeof (Elf64_Mips_External_Rel),
+ sizeof (Elf64_Mips_External_Rela),
+ sizeof (Elf64_External_Sym),
+ sizeof (Elf64_External_Dyn),
+ sizeof (Elf_External_Note),
+ 64, /* arch_size */
+ 8, /* file_align */
+ ELFCLASS64,
+ EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ bfd_elf64_write_shdrs_and_ehdr,
+ mips_elf64_write_relocs,
+ bfd_elf64_swap_symbol_out,
+ mips_elf64_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in
+};
+
+#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
+#define TARGET_LITTLE_NAME "elf64-littlemips"
+#define TARGET_BIG_SYM bfd_elf64_bigmips_vec
+#define TARGET_BIG_NAME "elf64-bigmips"
+#define ELF_ARCH bfd_arch_mips
+#define ELF_MACHINE_CODE EM_MIPS
+#define ELF_MAXPAGESIZE 0x1000
+#define elf_backend_size_info mips_elf64_size_info
+#define elf_backend_object_p _bfd_mips_elf_object_p
+#define elf_backend_section_from_shdr mips_elf64_section_from_shdr
+#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
+#define elf_backend_section_from_bfd_section \
+ _bfd_mips_elf_section_from_bfd_section
+#define elf_backend_section_processing mips_elf64_section_processing
+#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
+#define elf_backend_final_write_processing \
+ _bfd_mips_elf_final_write_processing
+#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
+
+#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
+#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
+#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
+#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
+#define bfd_elf64_bfd_copy_private_bfd_data \
+ _bfd_mips_elf_copy_private_bfd_data
+#define bfd_elf64_bfd_merge_private_bfd_data \
+ _bfd_mips_elf_merge_private_bfd_data
+#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
+
+#define bfd_elf64_archive_functions
+#define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap
+#define bfd_elf64_archive_slurp_extended_name_table \
+ _bfd_archive_coff_slurp_extended_name_table
+#define bfd_elf64_archive_construct_extended_name_table \
+ _bfd_archive_coff_construct_extended_name_table
+#define bfd_elf64_archive_truncate_arname \
+ _bfd_archive_coff_truncate_arname
+#define bfd_elf64_archive_write_armap mips_elf64_write_armap
+#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
+#define bfd_elf64_archive_openr_next_archived_file \
+ _bfd_archive_coff_openr_next_archived_file
+#define bfd_elf64_archive_get_elt_at_index \
+ _bfd_archive_coff_get_elt_at_index
+#define bfd_elf64_archive_generic_stat_arch_elt \
+ _bfd_archive_coff_generic_stat_arch_elt
+#define bfd_elf64_archive_update_armap_timestamp \
+ _bfd_archive_coff_update_armap_timestamp
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
new file mode 100644
index 00000000000..17fe98dafc2
--- /dev/null
+++ b/bfd/elf64-sparc.c
@@ -0,0 +1,2275 @@
+/* SPARC-specific support for 64-bit ELF
+ Copyright (C) 1993, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* This is defined if one wants to build upward compatible binaries
+ with the original sparc64-elf toolchain. The support is kept in for
+ now but is turned off by default. dje 970930 */
+/*#define SPARC64_OLD_RELOCS*/
+
+#include "elf/sparc.h"
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
+#define MINUS_ONE (~ (bfd_vma) 0)
+
+static reloc_howto_type *sparc64_elf_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void sparc64_elf_info_to_howto
+ PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+
+static void sparc64_elf_build_plt
+ PARAMS((bfd *, unsigned char *, int));
+static bfd_vma sparc64_elf_plt_entry_offset
+ PARAMS((int));
+static bfd_vma sparc64_elf_plt_ptr_offset
+ PARAMS((int, int));
+
+static boolean sparc64_elf_check_relocs
+ PARAMS((bfd *, struct bfd_link_info *, asection *sec,
+ const Elf_Internal_Rela *));
+static boolean sparc64_elf_adjust_dynamic_symbol
+ PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean sparc64_elf_size_dynamic_sections
+ PARAMS((bfd *, struct bfd_link_info *));
+static boolean sparc64_elf_adjust_dynindx
+ PARAMS((struct elf_link_hash_entry *, PTR));
+
+static boolean sparc64_elf_merge_private_bfd_data
+ PARAMS ((bfd *, bfd *));
+
+static boolean sparc64_elf_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean sparc64_elf_object_p PARAMS ((bfd *));
+
+/* The relocation "howto" table. */
+
+static bfd_reloc_status_type sparc_elf_notsup_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type sparc_elf_wdisp16_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type sparc_elf_hix22_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static bfd_reloc_status_type sparc_elf_lox10_reloc
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+static reloc_howto_type sparc64_elf_howto_table[] =
+{
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true),
+ HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true),
+ HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true),
+ HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true),
+ HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true),
+#ifndef SPARC64_OLD_RELOCS
+ /* These aren't implemented yet. */
+ HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PLT32", false,0,0x00000000,true),
+ HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true),
+ HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsup_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true),
+#endif
+ HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true),
+ HOWTO(R_SPARC_64, 0,4,64,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", false,0,MINUS_ONE, true),
+ HOWTO(R_SPARC_OLO10, 0,2,13,false,0,complain_overflow_signed, sparc_elf_notsup_reloc, "R_SPARC_OLO10", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_HH22, 42,2,22,false,0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_HM10, 32,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_LM22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC_HH22, 42,2,22,true, 0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_PC_HH22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC_HM10, 32,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC_HM10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_PC_LM22, 10,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC_LM22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true),
+ HOWTO(R_SPARC_WDISP19, 2,2,19,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true),
+ HOWTO(R_SPARC_UNUSED_42, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UNUSED_42",false,0,0x00000000,true),
+ HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true),
+ HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true),
+ HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true),
+ HOWTO(R_SPARC_DISP64, 0,4,64,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP64", false,0,MINUS_ONE, true),
+ HOWTO(R_SPARC_PLT64, 0,4,64,false,0,complain_overflow_bitfield,sparc_elf_notsup_reloc, "R_SPARC_PLT64", false,0,MINUS_ONE, false),
+ HOWTO(R_SPARC_HIX22, 0,4, 0,false,0,complain_overflow_bitfield,sparc_elf_hix22_reloc, "R_SPARC_HIX22", false,0,MINUS_ONE, false),
+ HOWTO(R_SPARC_LOX10, 0,4, 0,false,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_LOX10", false,0,MINUS_ONE, false),
+ HOWTO(R_SPARC_H44, 22,2,22,false,0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_H44", false,0,0x003fffff,false),
+ HOWTO(R_SPARC_M44, 12,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_M44", false,0,0x000003ff,false),
+ HOWTO(R_SPARC_L44, 0,2,13,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_L44", false,0,0x00000fff,false),
+ HOWTO(R_SPARC_REGISTER, 0,4, 0,false,0,complain_overflow_bitfield,sparc_elf_notsup_reloc, "R_SPARC_REGISTER",false,0,MINUS_ONE, false),
+ HOWTO(R_SPARC_UA64, 0,4,64,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_UA64", false,0,MINUS_ONE, true),
+ HOWTO(R_SPARC_UA16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_UA16", false,0,0x0000ffff,true)
+};
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static CONST struct elf_reloc_map sparc_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_SPARC_NONE, },
+ { BFD_RELOC_16, R_SPARC_16, },
+ { BFD_RELOC_8, R_SPARC_8 },
+ { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
+ { BFD_RELOC_CTOR, R_SPARC_64 },
+ { BFD_RELOC_32, R_SPARC_32 },
+ { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
+ { BFD_RELOC_HI22, R_SPARC_HI22 },
+ { BFD_RELOC_LO10, R_SPARC_LO10, },
+ { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
+ { BFD_RELOC_SPARC22, R_SPARC_22 },
+ { BFD_RELOC_SPARC13, R_SPARC_13 },
+ { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
+ { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
+ { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
+ { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
+ { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
+ { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
+ { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
+ { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
+ { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
+ { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
+ { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
+ /* ??? Doesn't dwarf use this? */
+/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
+ {BFD_RELOC_SPARC_10, R_SPARC_10},
+ {BFD_RELOC_SPARC_11, R_SPARC_11},
+ {BFD_RELOC_SPARC_64, R_SPARC_64},
+ {BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10},
+ {BFD_RELOC_SPARC_HH22, R_SPARC_HH22},
+ {BFD_RELOC_SPARC_HM10, R_SPARC_HM10},
+ {BFD_RELOC_SPARC_LM22, R_SPARC_LM22},
+ {BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22},
+ {BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10},
+ {BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22},
+ {BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16},
+ {BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19},
+ {BFD_RELOC_SPARC_7, R_SPARC_7},
+ {BFD_RELOC_SPARC_5, R_SPARC_5},
+ {BFD_RELOC_SPARC_6, R_SPARC_6},
+ {BFD_RELOC_SPARC_DISP64, R_SPARC_DISP64},
+ {BFD_RELOC_SPARC_PLT64, R_SPARC_PLT64},
+ {BFD_RELOC_SPARC_HIX22, R_SPARC_HIX22},
+ {BFD_RELOC_SPARC_LOX10, R_SPARC_LOX10},
+ {BFD_RELOC_SPARC_H44, R_SPARC_H44},
+ {BFD_RELOC_SPARC_M44, R_SPARC_M44},
+ {BFD_RELOC_SPARC_L44, R_SPARC_L44},
+ {BFD_RELOC_SPARC_REGISTER, R_SPARC_REGISTER}
+};
+
+static reloc_howto_type *
+sparc64_elf_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+ for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (sparc_reloc_map[i].bfd_reloc_val == code)
+ return &sparc64_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
+ }
+ return 0;
+}
+
+static void
+sparc64_elf_info_to_howto (abfd, cache_ptr, dst)
+ bfd *abfd;
+ arelent *cache_ptr;
+ Elf64_Internal_Rela *dst;
+{
+ BFD_ASSERT (ELF64_R_TYPE (dst->r_info) < (unsigned int) R_SPARC_max);
+ cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE (dst->r_info)];
+}
+
+/* Utility for performing the standard initial work of an instruction
+ relocation.
+ *PRELOCATION will contain the relocated item.
+ *PINSN will contain the instruction from the input stream.
+ If the result is `bfd_reloc_other' the caller can continue with
+ performing the relocation. Otherwise it must stop and return the
+ value to its caller. */
+
+static bfd_reloc_status_type
+init_insn_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ prelocation,
+ pinsn)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ bfd_vma *prelocation;
+ bfd_vma *pinsn;
+{
+ bfd_vma relocation;
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! howto->partial_inplace
+ || reloc_entry->addend == 0))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* This works because partial_inplace == false. */
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ relocation = (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset);
+ relocation += reloc_entry->addend;
+ if (howto->pc_relative)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ relocation -= reloc_entry->address;
+ }
+
+ *prelocation = relocation;
+ *pinsn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_other;
+}
+
+/* For unsupported relocs. */
+
+static bfd_reloc_status_type
+sparc_elf_notsup_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ return bfd_reloc_notsupported;
+}
+
+/* Handle the WDISP16 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_wdisp16_reloc (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_vma insn;
+ bfd_reloc_status_type status;
+
+ status = init_insn_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, &relocation, &insn);
+ if (status != bfd_reloc_other)
+ return status;
+
+ insn = (insn & ~0x303fff) | ((((relocation >> 2) & 0xc000) << 6)
+ | ((relocation >> 2) & 0x3fff));
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if ((bfd_signed_vma) relocation < - 0x40000
+ || (bfd_signed_vma) relocation > 0x3ffff)
+ return bfd_reloc_overflow;
+ else
+ return bfd_reloc_ok;
+}
+
+/* Handle the HIX22 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_hix22_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_vma insn;
+ bfd_reloc_status_type status;
+
+ status = init_insn_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, &relocation, &insn);
+ if (status != bfd_reloc_other)
+ return status;
+
+ relocation ^= MINUS_ONE;
+ insn = (insn & ~0x3fffff) | ((relocation >> 10) & 0x3fffff);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if ((relocation & ~ (bfd_vma) 0xffffffff) != 0)
+ return bfd_reloc_overflow;
+ else
+ return bfd_reloc_ok;
+}
+
+/* Handle the LOX10 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_lox10_reloc (abfd,
+ reloc_entry,
+ symbol,
+ data,
+ input_section,
+ output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_vma insn;
+ bfd_reloc_status_type status;
+
+ status = init_insn_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, &relocation, &insn);
+ if (status != bfd_reloc_other)
+ return status;
+
+ insn = (insn & ~0x1fff) | 0x1c00 | (relocation & 0x3ff);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+/* PLT/GOT stuff */
+
+/* Both the headers and the entries are icache aligned. */
+#define PLT_ENTRY_SIZE 32
+#define PLT_HEADER_SIZE (4 * PLT_ENTRY_SIZE)
+#define LARGE_PLT_THRESHOLD 32768
+#define GOT_RESERVED_ENTRIES 1
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/sparcv9/ld.so.1"
+
+
+/* Fill in the .plt section. */
+
+static void
+sparc64_elf_build_plt (output_bfd, contents, nentries)
+ bfd *output_bfd;
+ unsigned char *contents;
+ int nentries;
+{
+ const unsigned int nop = 0x01000000;
+ int i, j;
+
+ /* The first four entries are reserved, and are initially undefined.
+ We fill them with `illtrap 0' to force ld.so to do something. */
+
+ for (i = 0; i < PLT_HEADER_SIZE/4; ++i)
+ bfd_put_32 (output_bfd, 0, contents+i*4);
+
+ /* The first 32768 entries are close enough to plt1 to get there via
+ a straight branch. */
+
+ for (i = 4; i < LARGE_PLT_THRESHOLD && i < nentries; ++i)
+ {
+ unsigned char *entry = contents + i * PLT_ENTRY_SIZE;
+ unsigned int sethi, ba;
+
+ /* sethi (. - plt0), %g1 */
+ sethi = 0x03000000 | (i * PLT_ENTRY_SIZE);
+
+ /* ba,a,pt %icc, plt1 */
+ ba = 0x30480000 | (((contents+PLT_ENTRY_SIZE) - (entry+4)) / 4 & 0x7ffff);
+
+ bfd_put_32 (output_bfd, sethi, entry);
+ bfd_put_32 (output_bfd, ba, entry+4);
+ bfd_put_32 (output_bfd, nop, entry+8);
+ bfd_put_32 (output_bfd, nop, entry+12);
+ bfd_put_32 (output_bfd, nop, entry+16);
+ bfd_put_32 (output_bfd, nop, entry+20);
+ bfd_put_32 (output_bfd, nop, entry+24);
+ bfd_put_32 (output_bfd, nop, entry+28);
+ }
+
+ /* Now the tricky bit. Entries 32768 and higher are grouped in blocks of
+ 160: 160 entries and 160 pointers. This is to separate code from data,
+ which is much friendlier on the cache. */
+
+ for (; i < nentries; i += 160)
+ {
+ int block = (i + 160 <= nentries ? 160 : nentries - i);
+ for (j = 0; j < block; ++j)
+ {
+ unsigned char *entry, *ptr;
+ unsigned int ldx;
+
+ entry = contents + i*PLT_ENTRY_SIZE + j*4*6;
+ ptr = contents + i*PLT_ENTRY_SIZE + block*4*6 + j*8;
+
+ /* ldx [%o7 + ptr - entry+4], %g1 */
+ ldx = 0xc25be000 | ((ptr - entry+4) & 0x1fff);
+
+ bfd_put_32 (output_bfd, 0x8a10000f, entry); /* mov %o7,%g5 */
+ bfd_put_32 (output_bfd, 0x40000002, entry+4); /* call .+8 */
+ bfd_put_32 (output_bfd, nop, entry+8); /* nop */
+ bfd_put_32 (output_bfd, ldx, entry+12); /* ldx [%o7+P],%g1 */
+ bfd_put_32 (output_bfd, 0x83c3c001, entry+16); /* jmpl %o7+%g1,%g1 */
+ bfd_put_32 (output_bfd, 0x9e100005, entry+20); /* mov %g5,%o7 */
+
+ bfd_put_64 (output_bfd, contents - entry+4, ptr);
+ }
+ }
+}
+
+/* Return the offset of a particular plt entry within the .plt section. */
+
+static bfd_vma
+sparc64_elf_plt_entry_offset (index)
+ int index;
+{
+ int block, ofs;
+
+ if (index < LARGE_PLT_THRESHOLD)
+ return index * PLT_ENTRY_SIZE;
+
+ /* See above for details. */
+
+ block = (index - LARGE_PLT_THRESHOLD) / 160;
+ ofs = (index - LARGE_PLT_THRESHOLD) % 160;
+
+ return ((bfd_vma)(LARGE_PLT_THRESHOLD + block*160) * PLT_ENTRY_SIZE
+ + ofs * 6*4);
+}
+
+static bfd_vma
+sparc64_elf_plt_ptr_offset (index, max)
+ int index, max;
+{
+ int block, ofs, last;
+
+ BFD_ASSERT(index >= LARGE_PLT_THRESHOLD);
+
+ /* See above for details. */
+
+ block = (index - LARGE_PLT_THRESHOLD) / 160;
+ ofs = (index - LARGE_PLT_THRESHOLD) % 160;
+ last = (max - LARGE_PLT_THRESHOLD) % 160;
+
+ return ((LARGE_PLT_THRESHOLD + block*160) * PLT_ENTRY_SIZE
+ + last * 6*4
+ + ofs * 8);
+}
+
+
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static boolean
+sparc64_elf_check_relocs (abfd, info, sec, relocs)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ const Elf_Internal_Rela *relocs;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+
+ if (info->relocateable || !(sec->flags & SEC_ALLOC))
+ return true;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_offsets = elf_local_got_offsets (abfd);
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ /* This symbol requires a global offset table entry. */
+
+ if (dynobj == NULL)
+ {
+ /* Create the .got section. */
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return false;
+ }
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_make_section (dynobj, ".rela.got");
+ if (srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, srelgot,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, srelgot, 3))
+ return false;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ h->got.offset = sgot->_raw_size;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ srelgot->_raw_size += sizeof (Elf64_External_Rela);
+ }
+ else
+ {
+ /* This is a global offset table entry for a local
+ symbol. */
+ if (local_got_offsets == NULL)
+ {
+ size_t size;
+ register unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+ if (local_got_offsets == NULL)
+ return false;
+ elf_local_got_offsets (abfd) = local_got_offsets;
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_got_offsets[i] = (bfd_vma) -1;
+ }
+ if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ local_got_offsets[r_symndx] = sgot->_raw_size;
+
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_SPARC_RELATIVE reloc so that the
+ dynamic linker can adjust this GOT entry. */
+ srelgot->_raw_size += sizeof (Elf64_External_Rela);
+ }
+ }
+
+ sgot->_raw_size += 8;
+
+#if 0
+ /* Doesn't work for 64-bit -fPIC, since sethi/or builds
+ unsigned numbers. If we permit ourselves to modify
+ code so we get sethi/xor, this could work.
+ Question: do we consider conditionally re-enabling
+ this for -fpic, once we know about object code models? */
+ /* If the .got section is more than 0x1000 bytes, we add
+ 0x1000 to the value of _GLOBAL_OFFSET_TABLE_, so that 13
+ bit relocations have a greater chance of working. */
+ if (sgot->_raw_size >= 0x1000
+ && elf_hash_table (info)->hgot->root.u.def.value == 0)
+ elf_hash_table (info)->hgot->root.u.def.value = 0x1000;
+#endif
+
+ break;
+
+ case R_SPARC_WPLT30:
+ case R_SPARC_PLT32:
+ case R_SPARC_HIPLT22:
+ case R_SPARC_LOPLT10:
+ case R_SPARC_PCPLT32:
+ case R_SPARC_PCPLT22:
+ case R_SPARC_PCPLT10:
+ case R_SPARC_PLT64:
+ /* This symbol requires a procedure linkage table entry. We
+ actually build the entry in adjust_dynamic_symbol,
+ because this might be a case of linking PIC code without
+ linking in any dynamic objects, in which case we don't
+ need to generate a procedure linkage table after all. */
+
+ if (h == NULL)
+ {
+ /* It does not make sense to have a procedure linkage
+ table entry for a local symbol. */
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+ break;
+
+ case R_SPARC_PC10:
+ case R_SPARC_PC22:
+ case R_SPARC_PC_HH22:
+ case R_SPARC_PC_HM10:
+ case R_SPARC_PC_LM22:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_SPARC_DISP8:
+ case R_SPARC_DISP16:
+ case R_SPARC_DISP32:
+ case R_SPARC_DISP64:
+ case R_SPARC_WDISP30:
+ case R_SPARC_WDISP22:
+ case R_SPARC_WDISP19:
+ case R_SPARC_WDISP16:
+ if (h == NULL)
+ break;
+ /* Fall through. */
+ case R_SPARC_8:
+ case R_SPARC_16:
+ case R_SPARC_32:
+ case R_SPARC_HI22:
+ case R_SPARC_22:
+ case R_SPARC_13:
+ case R_SPARC_LO10:
+ case R_SPARC_UA32:
+ case R_SPARC_10:
+ case R_SPARC_11:
+ case R_SPARC_64:
+ case R_SPARC_OLO10:
+ case R_SPARC_HH22:
+ case R_SPARC_HM10:
+ case R_SPARC_LM22:
+ case R_SPARC_7:
+ case R_SPARC_5:
+ case R_SPARC_6:
+ case R_SPARC_HIX22:
+ case R_SPARC_LOX10:
+ case R_SPARC_H44:
+ case R_SPARC_M44:
+ case R_SPARC_L44:
+ case R_SPARC_UA64:
+ case R_SPARC_UA16:
+ /* When creating a shared object, we must copy these relocs
+ into the output file. We create a reloc section in
+ dynobj and make room for the reloc.
+
+ But don't do this for debugging sections -- this shows up
+ with DWARF2 -- first because they are not loaded, and
+ second because DWARF sez the debug info is not to be
+ biased by the load address. */
+ if (info->shared && (sec->flags & SEC_ALLOC))
+ {
+ if (sreloc == NULL)
+ {
+ const char *name;
+
+ name = (bfd_elf_string_from_elf_section
+ (abfd,
+ elf_elfheader (abfd)->e_shstrndx,
+ elf_section_data (sec)->rel_hdr.sh_name));
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name (abfd, sec),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ flagword flags;
+
+ sreloc = bfd_make_section (dynobj, name);
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ if (sreloc == NULL
+ || ! bfd_set_section_flags (dynobj, sreloc, flags)
+ || ! bfd_set_section_alignment (dynobj, sreloc, 3))
+ return false;
+ }
+ }
+
+ sreloc->_raw_size += sizeof (Elf64_External_Rela);
+ }
+ break;
+
+ case R_SPARC_REGISTER:
+ /* Nothing to do. */
+ break;
+
+ default:
+ (*_bfd_error_handler)(_("%s: check_relocs: unhandled reloc type %d"),
+ bfd_get_filename(abfd),
+ ELF64_R_TYPE (rel->r_info));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. The current definition is in some section of the
+ dynamic object, but we're not including those sections. We have to
+ change the definition to something the rest of the link can
+ understand. */
+
+static boolean
+sparc64_elf_adjust_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ bfd *dynobj;
+ asection *s;
+ unsigned int power_of_two;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+ || h->weakdef != NULL
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later
+ (although we could actually do it here). The STT_NOTYPE
+ condition is a hack specifically for the Oracle libraries
+ delivered for Solaris; for some inexplicable reason, they define
+ some of their functions as STT_NOTYPE when they really should be
+ STT_FUNC. */
+ if (h->type == STT_FUNC
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
+ || (h->type == STT_NOTYPE
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.section->flags & SEC_CODE) != 0))
+ {
+ if (! elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* This case can occur if we saw a WPLT30 reloc in an input
+ file, but none of the input files were dynamic objects.
+ In such a case, we don't actually need to build a
+ procedure linkage table, and we can just do a WDISP30
+ reloc instead. */
+ BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ return true;
+ }
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* The first four bit in .plt is reserved. */
+ if (s->_raw_size == 0)
+ s->_raw_size = PLT_HEADER_SIZE;
+
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+ }
+
+ /* To simplify matters later, just store the plt index here. */
+ h->plt.offset = s->_raw_size / PLT_ENTRY_SIZE;
+
+ /* Make room for this entry. */
+ s->_raw_size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+
+ /* The first plt entries are reserved, and the relocations must
+ pair up exactly. */
+ if (s->_raw_size == 0)
+ s->_raw_size += (PLT_HEADER_SIZE/PLT_ENTRY_SIZE
+ * sizeof (Elf64_External_Rela));
+
+ s->_raw_size += sizeof (Elf64_External_Rela);
+
+ /* The procedure linkage table size is bounded by the magnitude
+ of the offset we can describe in the entry. */
+ if (s->_raw_size >= (bfd_vma)1 << 32)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ return true;
+ }
+
+ /* If this is a weak symbol, and there is a real definition, the
+ processor independent code will have arranged for us to see the
+ real definition first, and we can just use the same value. */
+ if (h->weakdef != NULL)
+ {
+ BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+ || h->weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->weakdef->root.u.def.section;
+ h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* If we are creating a shared library, we must presume that the
+ only references to the symbol are via the global offset table.
+ For such cases we need not do anything here; the relocations will
+ be handled correctly by relocate_section. */
+ if (info->shared)
+ return true;
+
+ /* We must allocate the symbol in our .dynbss section, which will
+ become part of the .bss section of the executable. There will be
+ an entry for this symbol in the .dynsym section. The dynamic
+ object will contain position independent code, so all references
+ from the dynamic object to this symbol will go through the global
+ offset table. The dynamic linker will use the .dynsym entry to
+ determine the address it must put in the global offset table, so
+ both the dynamic object and the regular object will refer to the
+ same memory location for the variable. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_SPARC_COPY reloc to tell the dynamic linker
+ to copy the initial value out of the dynamic object and into the
+ runtime process image. We need to remember the offset into the
+ .rel.bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->_raw_size += sizeof (Elf64_External_Rela);
+ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+ }
+
+ /* We need to figure out the alignment required for this symbol. I
+ have no idea how ELF linkers handle this. 16-bytes is the size
+ of the largest type that requires hard alignment -- long double. */
+ power_of_two = bfd_log2 (h->size);
+ if (power_of_two > 4)
+ power_of_two = 4;
+
+ /* Apply the required alignment. */
+ s->_raw_size = BFD_ALIGN (s->_raw_size,
+ (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, s))
+ {
+ if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+ return false;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->_raw_size += h->size;
+
+ return true;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static boolean
+sparc64_elf_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *s;
+ boolean reltext;
+ boolean relplt;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (! info->shared)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+ else
+ {
+ /* We may have created entries in the .rela.got section.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rela.got,
+ which will cause it to get stripped from the output file
+ below. */
+ s = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (s != NULL)
+ s->_raw_size = 0;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ reltext = false;
+ relplt = false;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ boolean strip;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ /* It's OK to base decisions on the section name, because none
+ of the dynobj section names depend upon the input files. */
+ name = bfd_get_section_name (dynobj, s);
+
+ strip = false;
+
+ if (strncmp (name, ".rela", 5) == 0)
+ {
+ if (s->_raw_size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is to handle .rela.bss and
+ .rel.plt. We must create it in
+ create_dynamic_sections, because it must be created
+ before the linker maps input sections to output
+ sections. The linker does that before
+ adjust_dynamic_symbol is called, and it is that
+ function which decides whether anything needs to go
+ into these sections. */
+ strip = true;
+ }
+ else
+ {
+ const char *outname;
+ asection *target;
+
+ /* If this relocation section applies to a read only
+ section, then we probably need a DT_TEXTREL entry. */
+ outname = bfd_get_section_name (output_bfd,
+ s->output_section);
+ target = bfd_get_section_by_name (output_bfd, outname + 5);
+ if (target != NULL
+ && (target->flags & SEC_READONLY) != 0)
+ reltext = true;
+
+ if (strcmp (name, ".rela.plt") == 0)
+ relplt = true;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else if (strcmp (name, ".plt") != 0
+ && strncmp (name, ".got", 4) != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ _bfd_strip_section_from_output (s);
+ continue;
+ }
+
+ /* Allocate memory for the section contents. Zero the memory
+ for the benefit of .rela.plt, which has 4 unused entries
+ at the beginning, and we don't want garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in sparc64_elf_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. The DT_DEBUG entry is filled in by the
+ dynamic linker and used by the debugger. */
+ if (! info->shared)
+ {
+ if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+ return false;
+ }
+
+ if (relplt)
+ {
+ if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_SPARC_PLTFMT,
+ (info->shared != 0) + 1))
+ return false;
+ }
+
+ if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
+ || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf64_External_Rela)))
+ return false;
+
+ if (reltext)
+ {
+ if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return false;
+ }
+ }
+
+ /* If we are generating a shared library, we generate a section
+ symbol for each output section for which we might need to copy
+ relocs. These are local symbols, which means that they must come
+ first in the dynamic symbol table. That means we must increment
+ the dynamic symbol index of every other dynamic symbol. */
+ if (info->shared)
+ {
+ int c;
+
+ c = 0;
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) != 0
+ || (s->flags & SEC_ALLOC) == 0)
+ continue;
+
+ elf_section_data (s)->dynindx = c + 1;
+
+ /* These symbols will have no names, so we don't need to
+ fiddle with dynstr_index. */
+
+ ++c;
+ }
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ sparc64_elf_adjust_dynindx,
+ (PTR) &c);
+ elf_hash_table (info)->dynsymcount += c;
+ }
+
+ return true;
+}
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+
+static boolean
+sparc64_elf_adjust_dynindx (h, cparg)
+ struct elf_link_hash_entry *h;
+ PTR cparg;
+{
+ int *cp = (int *) cparg;
+
+ if (h->dynindx != -1)
+ h->dynindx += *cp;
+ return true;
+}
+
+
+/* Relocate a SPARC64 ELF section. */
+
+static boolean
+sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Sym *local_syms;
+ asection **local_sections;
+{
+ bfd *dynobj;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma got_base;
+ asection *sgot;
+ asection *splt;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ if (elf_hash_table(info)->hgot == NULL)
+ got_base = 0;
+ else
+ got_base = elf_hash_table (info)->hgot->root.u.def.value;
+
+ sgot = splt = sreloc = NULL;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ reloc_howto_type *howto;
+ long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_SPARC_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ howto = sparc64_elf_howto_table + r_type;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+
+ if (info->relocateable)
+ {
+ /* This is a relocateable link. We don't have to change
+ anything, unless the reloc is against a section symbol,
+ in which case we have to adjust according to where the
+ section symbol winds up in the output section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ rel->r_addend += sec->output_offset + sym->st_value;
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a final link. */
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ boolean skip_it = false;
+ sec = h->root.u.def.section;
+
+ switch (r_type)
+ {
+ case R_SPARC_WPLT30:
+ case R_SPARC_PLT32:
+ case R_SPARC_HIPLT22:
+ case R_SPARC_LOPLT10:
+ case R_SPARC_PCPLT32:
+ case R_SPARC_PCPLT22:
+ case R_SPARC_PCPLT10:
+ case R_SPARC_PLT64:
+ if (h->plt.offset != (bfd_vma) -1)
+ skip_it = true;
+ break;
+
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ if (elf_hash_table(info)->dynamic_sections_created
+ && (!info->shared
+ || (!info->symbolic && h->dynindx != -1)
+ || !(h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR)))
+ skip_it = true;
+ break;
+
+ case R_SPARC_PC10:
+ case R_SPARC_PC22:
+ case R_SPARC_PC_HH22:
+ case R_SPARC_PC_HM10:
+ case R_SPARC_PC_LM22:
+ if (!strcmp(h->root.root.string, "_GLOBAL_OFFSET_TABLE_"))
+ break;
+ /* FALLTHRU */
+
+ case R_SPARC_8:
+ case R_SPARC_16:
+ case R_SPARC_32:
+ case R_SPARC_DISP8:
+ case R_SPARC_DISP16:
+ case R_SPARC_DISP32:
+ case R_SPARC_WDISP30:
+ case R_SPARC_WDISP22:
+ case R_SPARC_HI22:
+ case R_SPARC_22:
+ case R_SPARC_13:
+ case R_SPARC_LO10:
+ case R_SPARC_UA32:
+ case R_SPARC_10:
+ case R_SPARC_11:
+ case R_SPARC_64:
+ case R_SPARC_OLO10:
+ case R_SPARC_HH22:
+ case R_SPARC_HM10:
+ case R_SPARC_LM22:
+ case R_SPARC_WDISP19:
+ case R_SPARC_WDISP16:
+ case R_SPARC_7:
+ case R_SPARC_5:
+ case R_SPARC_6:
+ case R_SPARC_DISP64:
+ case R_SPARC_HIX22:
+ case R_SPARC_LOX10:
+ case R_SPARC_H44:
+ case R_SPARC_M44:
+ case R_SPARC_L44:
+ case R_SPARC_UA64:
+ case R_SPARC_UA16:
+ if (info->shared
+ && ((!info->symbolic && h->dynindx != -1)
+ || !(h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR)))
+ skip_it = true;
+ break;
+ }
+
+ if (skip_it)
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ relocation = 0;
+ }
+ else
+ {
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else if (info->shared && !info->symbolic && !info->no_undefined)
+ relocation = 0;
+ else
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset)))
+ return false;
+ relocation = 0;
+ }
+ }
+
+ /* When generating a shared object, these relocations are copied
+ into the output file to be resolved at run time. */
+ if (info->shared && (input_section->flags & SEC_ALLOC))
+ {
+ switch (r_type)
+ {
+ case R_SPARC_PC10:
+ case R_SPARC_PC22:
+ case R_SPARC_PC_HH22:
+ case R_SPARC_PC_HM10:
+ case R_SPARC_PC_LM22:
+ if (h != NULL
+ && !strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_"))
+ break;
+ /* Fall through. */
+ case R_SPARC_DISP8:
+ case R_SPARC_DISP16:
+ case R_SPARC_DISP32:
+ case R_SPARC_WDISP30:
+ case R_SPARC_WDISP22:
+ case R_SPARC_WDISP19:
+ case R_SPARC_WDISP16:
+ case R_SPARC_DISP64:
+ if (h == NULL)
+ break;
+ /* Fall through. */
+ case R_SPARC_8:
+ case R_SPARC_16:
+ case R_SPARC_32:
+ case R_SPARC_HI22:
+ case R_SPARC_22:
+ case R_SPARC_13:
+ case R_SPARC_LO10:
+ case R_SPARC_UA32:
+ case R_SPARC_10:
+ case R_SPARC_11:
+ case R_SPARC_64:
+ case R_SPARC_OLO10:
+ case R_SPARC_HH22:
+ case R_SPARC_HM10:
+ case R_SPARC_LM22:
+ case R_SPARC_7:
+ case R_SPARC_5:
+ case R_SPARC_6:
+ case R_SPARC_HIX22:
+ case R_SPARC_LOX10:
+ case R_SPARC_H44:
+ case R_SPARC_M44:
+ case R_SPARC_L44:
+ case R_SPARC_UA64:
+ case R_SPARC_UA16:
+ {
+ Elf_Internal_Rela outrel;
+ boolean skip;
+
+ if (sreloc == NULL)
+ {
+ const char *name =
+ (bfd_elf_string_from_elf_section
+ (input_bfd,
+ elf_elfheader (input_bfd)->e_shstrndx,
+ elf_section_data (input_section)->rel_hdr.sh_name));
+
+ if (name == NULL)
+ return false;
+
+ BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+ && strcmp (bfd_get_section_name(input_bfd,
+ input_section),
+ name + 5) == 0);
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ BFD_ASSERT (sreloc != NULL);
+ }
+
+ skip = false;
+
+ if (elf_section_data (input_section)->stab_info == NULL)
+ outrel.r_offset = rel->r_offset;
+ else
+ {
+ bfd_vma off;
+
+ off = (_bfd_stab_section_offset
+ (output_bfd, &elf_hash_table (info)->stab_info,
+ input_section,
+ &elf_section_data (input_section)->stab_info,
+ rel->r_offset));
+ if (off == MINUS_ONE)
+ skip = true;
+ outrel.r_offset = off;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* Optimize unaligned reloc usage now that we know where
+ it finally resides. */
+ switch (r_type)
+ {
+ case R_SPARC_16:
+ if (outrel.r_offset & 1) r_type = R_SPARC_UA16;
+ break;
+ case R_SPARC_UA16:
+ if (!(outrel.r_offset & 1)) r_type = R_SPARC_16;
+ break;
+ case R_SPARC_32:
+ if (outrel.r_offset & 3) r_type = R_SPARC_UA32;
+ break;
+ case R_SPARC_UA32:
+ if (!(outrel.r_offset & 3)) r_type = R_SPARC_32;
+ break;
+ case R_SPARC_64:
+ if (outrel.r_offset & 7) r_type = R_SPARC_UA64;
+ break;
+ case R_SPARC_UA64:
+ if (!(outrel.r_offset & 7)) r_type = R_SPARC_64;
+ break;
+ }
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ /* h->dynindx may be -1 if the symbol was marked to
+ become local. */
+ else if (h != NULL
+ && ((! info->symbolic && h->dynindx != -1)
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) == 0))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_SPARC_64)
+ {
+ outrel.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ if (h == NULL)
+ sec = local_sections[r_symndx];
+ else
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || (h->root.type
+ == bfd_link_hash_defweak));
+ sec = h->root.u.def.section;
+ }
+ if (sec != NULL && bfd_is_abs_section (sec))
+ indx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+
+ /* FIXME: we really should be able to link non-pic
+ shared libraries. */
+ if (indx == 0)
+ {
+ BFD_FAIL ();
+ (*_bfd_error_handler)
+ (_("%s: probably compiled without -fPIC?"),
+ bfd_get_filename (input_bfd));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ outrel.r_info = ELF64_R_INFO (indx, r_type);
+
+ /* For non-RELATIVE dynamic relocations, we keep the
+ same symbol, and so generally the same addend. But
+ we do need to adjust those relocations referencing
+ sections. */
+ outrel.r_addend = rel->r_addend;
+ if (r_symndx < symtab_hdr->sh_info
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ outrel.r_addend += sec->output_offset+sym->st_value;
+ }
+ }
+
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ (((Elf64_External_Rela *)
+ sreloc->contents)
+ + sreloc->reloc_count));
+ ++sreloc->reloc_count;
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, unless this is a RELATIVE
+ reloc in an unallocated section. */
+ if (skip
+ || (input_section->flags & SEC_ALLOC) != 0
+ || ELF64_R_TYPE (outrel.r_info) != R_SPARC_RELATIVE)
+ continue;
+ }
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ bfd_vma off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a -Bsymbolic
+ link and the symbol is defined locally, or the symbol
+ was forced to be local because of a version file. We
+ must initialize this entry in the global offset table.
+ Since the offset must always be a multiple of 8, we
+ use the least significant bit to record whether we
+ have initialized it already.
+
+ When doing a dynamic link, we create a .rela.got
+ relocation entry to initialize the value. This is
+ done in the finish_dynamic_symbol routine. */
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_64 (output_bfd, relocation,
+ sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ relocation = sgot->output_offset + off - got_base;
+ }
+ else
+ {
+ bfd_vma off;
+
+ BFD_ASSERT (local_got_offsets != NULL);
+ off = local_got_offsets[r_symndx];
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ /* The offset must always be a multiple of 8. We use
+ the least significant bit to record whether we have
+ already processed this entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_put_64 (output_bfd, relocation, sgot->contents + off);
+ local_got_offsets[r_symndx] |= 1;
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_SPARC_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_section_by_name(dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
+ outrel.r_addend = relocation;
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel,
+ (((Elf64_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++srelgot->reloc_count;
+ }
+ }
+ relocation = sgot->output_offset + off - got_base;
+ }
+ goto do_default;
+
+ case R_SPARC_WPLT30:
+ case R_SPARC_PLT32:
+ case R_SPARC_HIPLT22:
+ case R_SPARC_LOPLT10:
+ case R_SPARC_PCPLT32:
+ case R_SPARC_PCPLT22:
+ case R_SPARC_PCPLT10:
+ case R_SPARC_PLT64:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+ BFD_ASSERT (h != NULL);
+
+ if (h->plt.offset == (bfd_vma) -1)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ goto do_default;
+ }
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + sparc64_elf_plt_entry_offset (h->plt.offset));
+ goto do_default;
+
+ case R_SPARC_OLO10:
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ relocation = (relocation & 0x3ff) + ELF64_R_TYPE_DATA (rel->r_info);
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~0x1fff) | (relocation & 0x1fff);
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ r = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize, howto->rightshift,
+ bfd_arch_bits_per_address (input_bfd),
+ relocation);
+ }
+ break;
+
+ case R_SPARC_WDISP16:
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ /* Adjust for pc-relative-ness. */
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ relocation -= rel->r_offset;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~0x303fff) | ((((relocation >> 2) & 0xc000) << 6)
+ | ((relocation >> 2) & 0x3fff));
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ r = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize, howto->rightshift,
+ bfd_arch_bits_per_address (input_bfd),
+ relocation);
+ }
+ break;
+
+ case R_SPARC_HIX22:
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ relocation = relocation ^ MINUS_ONE;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~0x3fffff) | ((relocation >> 10) & 0x3fffff);
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ r = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize, howto->rightshift,
+ bfd_arch_bits_per_address (input_bfd),
+ relocation);
+ }
+ break;
+
+ case R_SPARC_LOX10:
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ relocation = (relocation & 0x3ff) | 0x1c00;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~0x1fff) | relocation;
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ r = bfd_reloc_ok;
+ }
+ break;
+
+ default:
+ do_default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ {
+ if (h->root.type == bfd_link_hash_undefweak
+ && howto->pc_relative)
+ {
+ /* Assume this is a call protected by other code that
+ detect the symbol is undefined. If this is the case,
+ we can safely ignore the overflow. If not, the
+ program is hosed anyway, and a little warning isn't
+ going to help. */
+ break;
+ }
+
+ name = h->root.root.string;
+ }
+ else
+ {
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name));
+ if (name == NULL)
+ return false;
+ if (*name == '\0')
+ name = bfd_section_name (input_bfd, sec);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return false;
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static boolean
+sparc64_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+{
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the PLT. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+ BFD_ASSERT (splt != NULL && srela != NULL);
+
+ /* Fill in the entry in the .rela.plt section. */
+
+ if (h->plt.offset < LARGE_PLT_THRESHOLD)
+ {
+ rela.r_offset = sparc64_elf_plt_entry_offset (h->plt.offset);
+ rela.r_addend = 0;
+ }
+ else
+ {
+ int max = splt->_raw_size / PLT_ENTRY_SIZE;
+ rela.r_offset = sparc64_elf_plt_ptr_offset (h->plt.offset, max);
+ rela.r_addend = -(sparc64_elf_plt_entry_offset (h->plt.offset) + 4);
+ }
+ rela.r_offset += (splt->output_section->vma + splt->output_offset);
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_JMP_SLOT);
+
+ bfd_elf64_swap_reloca_out (output_bfd, &rela,
+ ((Elf64_External_Rela *) srela->contents
+ + h->plt.offset));
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the GOT. Set it up. */
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srela = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ 1));
+
+ /* If this is a -Bsymbolic link, and the symbol is defined
+ locally, we just want to emit a RELATIVE reloc. Likewise if
+ the symbol was forced to be local because of a version file.
+ The entry in the global offset table will already have been
+ initialized in the relocate_section function. */
+ if (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ {
+ asection *sec = h->root.u.def.section;
+ rela.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ bfd_elf64_swap_reloca_out (output_bfd, &rela,
+ ((Elf64_External_Rela *) srela->contents
+ + srela->reloc_count));
+ ++srela->reloc_count;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_section_by_name (h->root.u.def.section->owner,
+ ".rela.bss");
+ BFD_ASSERT (s != NULL);
+
+ rela.r_offset = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_COPY);
+ rela.r_addend = 0;
+ bfd_elf64_swap_reloca_out (output_bfd, &rela,
+ ((Elf64_External_Rela *) s->contents
+ + s->reloc_count));
+ ++s->reloc_count;
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
+ || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
+ sym->st_shndx = SHN_ABS;
+
+ return true;
+}
+
+/* Finish up the dynamic sections. */
+
+static boolean
+sparc64_elf_finish_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf64_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ boolean size;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT: name = ".plt"; size = false; break;
+ case DT_PLTRELSZ: name = ".rela.plt"; size = true; break;
+ case DT_JMPREL: name = ".rela.plt"; size = false; break;
+ default: name = NULL; size = false; break;
+ }
+
+ if (name != NULL)
+ {
+ asection *s;
+
+ s = bfd_get_section_by_name (output_bfd, name);
+ if (s == NULL)
+ dyn.d_un.d_val = 0;
+ else
+ {
+ if (! size)
+ dyn.d_un.d_ptr = s->vma;
+ else
+ {
+ if (s->_cooked_size != 0)
+ dyn.d_un.d_val = s->_cooked_size;
+ else
+ dyn.d_un.d_val = s->_raw_size;
+ }
+ }
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+
+ /* Initialize the contents of the .plt section. */
+ if (splt->_raw_size > 0)
+ {
+ sparc64_elf_build_plt(output_bfd, splt->contents,
+ splt->_raw_size / PLT_ENTRY_SIZE);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize =
+ PLT_ENTRY_SIZE;
+ }
+
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ if (sgot->_raw_size > 0)
+ {
+ if (sdyn == NULL)
+ bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);
+ else
+ bfd_put_64 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgot->contents);
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
+
+ if (info->shared)
+ {
+ asection *sdynsym;
+ asection *s;
+ Elf_Internal_Sym sym;
+ int c;
+
+ /* Set up the section symbols for the output sections. */
+
+ sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (sdynsym != NULL);
+
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+
+ c = 0;
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx;
+
+ if (elf_section_data (s)->dynindx == 0)
+ continue;
+
+ sym.st_value = s->vma;
+
+ indx = elf_section_data (s)->this_idx;
+ BFD_ASSERT (indx > 0);
+ sym.st_shndx = indx;
+
+ bfd_elf64_swap_symbol_out (output_bfd, &sym,
+ (PTR) (((Elf64_External_Sym *)
+ sdynsym->contents)
+ + elf_section_data (s)->dynindx));
+
+ ++c;
+ }
+
+ /* Set the sh_info field of the output .dynsym section to the
+ index of the first global symbol. */
+ elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
+ }
+
+ return true;
+}
+
+/* Functions for dealing with the e_flags field. */
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static boolean
+sparc64_elf_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ boolean error;
+ flagword new_flags, old_flags;
+ int new_mm, old_mm;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return true;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ if (!elf_flags_init (obfd)) /* First call, no flags set */
+ {
+ elf_flags_init (obfd) = true;
+ elf_elfheader (obfd)->e_flags = new_flags;
+ }
+
+ else if (new_flags == old_flags) /* Compatible flags are ok */
+ ;
+
+ else /* Incompatible flags */
+ {
+ error = false;
+
+ old_flags |= (new_flags & (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1));
+ new_flags |= (old_flags & (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1));
+ if ((old_flags & (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1)) ==
+ (EF_SPARC_SUN_US1|EF_SPARC_HAL_R1))
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: linking UltraSPARC specific with HAL specific code"),
+ bfd_get_filename (ibfd));
+ }
+
+ /* Choose the most restrictive memory ordering */
+ old_mm = (old_flags & EF_SPARCV9_MM);
+ new_mm = (new_flags & EF_SPARCV9_MM);
+ old_flags &= ~EF_SPARCV9_MM;
+ new_flags &= ~EF_SPARCV9_MM;
+ if (new_mm < old_mm) old_mm = new_mm;
+ old_flags |= old_mm;
+ new_flags |= old_mm;
+
+ /* Warn about any other mismatches */
+ if (new_flags != old_flags)
+ {
+ error = true;
+ (*_bfd_error_handler)
+ (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
+ }
+
+ elf_elfheader (obfd)->e_flags = old_flags;
+
+ if (error)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/* Set the right machine number for a SPARC64 ELF file. */
+
+static boolean
+sparc64_elf_object_p (abfd)
+ bfd *abfd;
+{
+ unsigned long mach = bfd_mach_sparc_v9;
+
+ if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
+ mach = bfd_mach_sparc_v9a;
+ return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, mach);
+}
+
+#define TARGET_BIG_SYM bfd_elf64_sparc_vec
+#define TARGET_BIG_NAME "elf64-sparc"
+#define ELF_ARCH bfd_arch_sparc
+#define ELF_MAXPAGESIZE 0x100000
+
+/* This is the official ABI value. */
+#define ELF_MACHINE_CODE EM_SPARCV9
+
+/* This is the value that we used before the ABI was released. */
+#define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
+
+#define elf_info_to_howto \
+ sparc64_elf_info_to_howto
+#define bfd_elf64_bfd_reloc_type_lookup \
+ sparc64_elf_reloc_type_lookup
+
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define elf_backend_check_relocs \
+ sparc64_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ sparc64_elf_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ sparc64_elf_size_dynamic_sections
+#define elf_backend_relocate_section \
+ sparc64_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ sparc64_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ sparc64_elf_finish_dynamic_sections
+
+#define bfd_elf64_bfd_merge_private_bfd_data \
+ sparc64_elf_merge_private_bfd_data
+
+#define elf_backend_object_p \
+ sparc64_elf_object_p
+
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 1
+
+/* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table. */
+#define elf_backend_plt_alignment 8
+
+#define elf_backend_got_header_size 8
+#define elf_backend_plt_header_size PLT_HEADER_SIZE
+
+#include "elf64-target.h"
diff --git a/bfd/elf64.c b/bfd/elf64.c
new file mode 100644
index 00000000000..69fb5b5e6e1
--- /dev/null
+++ b/bfd/elf64.c
@@ -0,0 +1,22 @@
+/* ELF 64-bit executable support for BFD.
+ Copyright 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 64
+
+#include "elfcode.h"
diff --git a/bfd/elfarm-nabi.c b/bfd/elfarm-nabi.c
new file mode 100644
index 00000000000..5952e74e5ef
--- /dev/null
+++ b/bfd/elfarm-nabi.c
@@ -0,0 +1,670 @@
+/* 32-bit ELF support for ARM new abi option.
+ Copyright 1999 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "elf/arm.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
+#endif
+
+#define USE_REL
+
+#define TARGET_LITTLE_SYM bfd_elf32_littlearm_vec
+#define TARGET_LITTLE_NAME "elf32-littlearm"
+#define TARGET_BIG_SYM bfd_elf32_bigarm_vec
+#define TARGET_BIG_NAME "elf32-bigarm"
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel elf32_arm_info_to_howto_rel
+
+
+static reloc_howto_type * elf32_arm_reloc_type_lookup
+ PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
+
+static reloc_howto_type elf32_arm_howto_table[] =
+{
+ /* No relocation */
+ HOWTO (R_ARM_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_PC24, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PC24", /* name */
+ false, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 32 bit absolute */
+ HOWTO (R_ARM_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* standard 32bit pc-relative reloc */
+ HOWTO (R_ARM_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_REL32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit absolute */
+ HOWTO (R_ARM_PC13, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PC13", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit absolute */
+ HOWTO (R_ARM_ABS16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 12 bit absolute */
+ HOWTO (R_ARM_ABS12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS12", /* name */
+ false, /* partial_inplace */
+ 0x000008ff, /* src_mask */
+ 0x000008ff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_ABS5, /* type */
+ 6, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_ABS5", /* name */
+ false, /* partial_inplace */
+ 0x000007e0, /* src_mask */
+ 0x000007e0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 8 bit absolute */
+ HOWTO (R_ARM_ABS8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS8", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_SBREL32, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_SBREL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_PC22, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 23, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC22", /* name */
+ false, /* partial_inplace */
+ 0x07ff07ff, /* src_mask */
+ 0x07ff07ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_PC8, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC8", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_ARM_AMP_VCALL9, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_AMP_VCALL9", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_ARM_SWI24, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_SWI24", /* name */
+ false, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_SWI8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_SWI8", /* name */
+ false, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* These next two relocs are defined, but I do not know what they do. */
+
+ HOWTO (R_ARM_XPC25, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_XPC25", /* name */
+ false, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_XPC22, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_XPC22", /* name */
+ false, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* These next three relocs are not defined, but we need to fill the space. */
+
+ HOWTO (R_ARM_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_unknown_17", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_unknown_18", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_unknown_19", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Relocs used in ARM Linux */
+
+ HOWTO (R_ARM_COPY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_COPY", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_GLOB_DAT", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_JUMP_SLOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_JUMP_SLOT", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RELATIVE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RELATIVE", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_GOTOFF", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOTPC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_GOTPC", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOT32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_GOT32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_PLT32, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PLT32", /* name */
+ true, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* End of relocs used in ARM Linux */
+
+ HOWTO (R_ARM_RREL32, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RREL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RABS32, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RABS32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RPC24, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RPC24", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RBASE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RBASE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+ /* GNU extension to record C++ vtable hierarchy */
+static reloc_howto_type elf32_arm_vtinherit_howto =
+ HOWTO (R_ARM_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_ARM_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+static reloc_howto_type elf32_arm_vtentry_howto =
+ HOWTO (R_ARM_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_ARM_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+ /* 12 bit pc relative */
+static reloc_howto_type elf32_arm_thm_pc11_howto =
+ HOWTO (R_ARM_THM_PC11, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC11", /* name */
+ false, /* partial_inplace */
+ 0x000007ff, /* src_mask */
+ 0x000007ff, /* dst_mask */
+ true); /* pcrel_offset */
+
+ /* 12 bit pc relative */
+static reloc_howto_type elf32_arm_thm_pc9_howto =
+ HOWTO (R_ARM_THM_PC9, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC9", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ true); /* pcrel_offset */
+
+
+static void
+elf32_arm_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
+ bfd * abfd;
+ arelent * bfd_reloc;
+ Elf32_Internal_Rel * elf_reloc;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+
+ switch (r_type)
+ {
+ case R_ARM_GNU_VTINHERIT:
+ bfd_reloc->howto = & elf32_arm_vtinherit_howto;
+ break;
+
+ case R_ARM_GNU_VTENTRY:
+ bfd_reloc->howto = & elf32_arm_vtentry_howto;
+ break;
+
+ case R_ARM_THM_PC11:
+ bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
+ break;
+
+ case R_ARM_THM_PC9:
+ bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
+ break;
+
+ default:
+ if (r_type >= NUM_ELEM (elf32_arm_howto_table))
+ bfd_reloc->howto = NULL;
+ else
+ bfd_reloc->howto = & elf32_arm_howto_table[r_type];
+ break;
+ }
+}
+
+struct elf32_arm_reloc_map
+ {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+ };
+
+static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_ARM_NONE},
+ {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24},
+ {BFD_RELOC_32, R_ARM_ABS32},
+ {BFD_RELOC_32_PCREL, R_ARM_REL32},
+ {BFD_RELOC_8, R_ARM_ABS8},
+ {BFD_RELOC_16, R_ARM_ABS16},
+ {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12},
+ {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5},
+ {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
+ {BFD_RELOC_ARM_COPY, R_ARM_COPY},
+ {BFD_RELOC_ARM_GLOB_DAT, R_ARM_GLOB_DAT},
+ {BFD_RELOC_ARM_JUMP_SLOT, R_ARM_JUMP_SLOT},
+ {BFD_RELOC_ARM_RELATIVE, R_ARM_RELATIVE},
+ {BFD_RELOC_ARM_GOTOFF, R_ARM_GOTOFF},
+ {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC},
+ {BFD_RELOC_ARM_GOT32, R_ARM_GOT32},
+ {BFD_RELOC_ARM_PLT32, R_ARM_PLT32}
+};
+
+static reloc_howto_type *
+elf32_arm_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ switch (code)
+ {
+ case BFD_RELOC_VTABLE_INHERIT:
+ return & elf32_arm_vtinherit_howto;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ return & elf32_arm_vtentry_howto;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH12:
+ return & elf32_arm_thm_pc11_howto;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH9:
+ return & elf32_arm_thm_pc9_howto;
+
+ default:
+ for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
+ if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
+ return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
+
+ return NULL;
+ }
+}
+
+#include "elf32-arm.h"
diff --git a/bfd/elfarm-oabi.c b/bfd/elfarm-oabi.c
new file mode 100644
index 00000000000..f219b92ea7b
--- /dev/null
+++ b/bfd/elfarm-oabi.c
@@ -0,0 +1,381 @@
+/* 32-bit ELF support for ARM old abi option.
+ Copyright 1999 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "elf/arm-oabi.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+#define USE_RELA
+
+#define TARGET_LITTLE_SYM bfd_elf32_littlearm_oabi_vec
+#define TARGET_LITTLE_NAME "elf32-littlearm-oabi"
+#define TARGET_BIG_SYM bfd_elf32_bigarm_oabi_vec
+#define TARGET_BIG_NAME "elf32-bigarm-oabi"
+
+#define elf_info_to_howto elf32_arm_info_to_howto
+#define elf_info_to_howto_rel 0
+
+static reloc_howto_type elf32_arm_howto_table[] =
+{
+ /* No relocation */
+ HOWTO (R_ARM_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_NONE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_PC24, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PC24", /* name */
+ false, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 32 bit absolute */
+ HOWTO (R_ARM_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* standard 32bit pc-relative reloc */
+ HOWTO (R_ARM_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_REL32", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 8 bit absolute */
+ HOWTO (R_ARM_ABS8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS8", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit absolute */
+ HOWTO (R_ARM_ABS16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS16", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 12 bit absolute */
+ HOWTO (R_ARM_ABS12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS12", /* name */
+ false, /* partial_inplace */
+ 0x000008ff, /* src_mask */
+ 0x000008ff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_ABS5, /* type */
+ 6, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_ABS5", /* name */
+ false, /* partial_inplace */
+ 0x000007e0, /* src_mask */
+ 0x000007e0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_PC22, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 23, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC22", /* name */
+ false, /* partial_inplace */
+ 0x07ff07ff, /* src_mask */
+ 0x07ff07ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ HOWTO (R_ARM_SBREL32, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_SBREL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_AMP_VCALL9, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_AMP_VCALL9", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 12 bit pc relative */
+ HOWTO (R_ARM_THM_PC11, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC11", /* name */
+ false, /* partial_inplace */
+ 0x000007ff, /* src_mask */
+ 0x000007ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* 12 bit pc relative */
+ HOWTO (R_ARM_THM_PC9, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC9", /* name */
+ false, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_ARM_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_ARM_GNU_VTINHERIT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage */
+ HOWTO (R_ARM_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_ARM_GNU_VTENTRY", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+
+ HOWTO (R_ARM_RREL32, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RREL32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RABS32, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RABS32", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RPC24, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RPC24", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ HOWTO (R_ARM_RBASE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_RBASE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+static void
+elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
+ bfd *abfd;
+ arelent *bfd_reloc;
+ Elf32_Internal_Rela *elf_reloc;
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+ /* fixme: need range test */
+ /* BFD_ASSERT (r_type < (unsigned int) R_ELF32_ARM_MAX); */
+ bfd_reloc->howto = &elf32_arm_howto_table[r_type];
+}
+
+struct elf32_arm_reloc_map
+ {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+ };
+
+static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_ARM_NONE,},
+ {BFD_RELOC_ARM_PCREL_BRANCH, R_ARM_PC24,},
+ {BFD_RELOC_32, R_ARM_ABS32,},
+ {BFD_RELOC_32_PCREL, R_ARM_REL32,},
+ {BFD_RELOC_8, R_ARM_ABS8,},
+ {BFD_RELOC_16, R_ARM_ABS16,},
+ {BFD_RELOC_ARM_OFFSET_IMM, R_ARM_ABS12,},
+ {BFD_RELOC_ARM_THUMB_OFFSET, R_ARM_THM_ABS5,},
+ {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22,},
+ {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT },
+ {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY },
+ {BFD_RELOC_NONE, R_ARM_SBREL32,},
+ {BFD_RELOC_NONE, R_ARM_AMP_VCALL9,},
+ {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_PC11,},
+ {BFD_RELOC_THUMB_PCREL_BRANCH9, R_ARM_THM_PC9,}
+};
+
+static reloc_howto_type *
+elf32_arm_reloc_type_lookup (abfd, code)
+ bfd * abfd;
+ bfd_reloc_code_real_type code;
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf32_arm_reloc_map) / sizeof (struct elf32_arm_reloc_map);
+ i++)
+ {
+ if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
+ return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+#define bfd_elf32_arm_allocate_interworking_sections \
+ bfd_elf32_arm_oabi_allocate_interworking_sections
+#define bfd_elf32_arm_get_bfd_for_interworking \
+ bfd_elf32_arm_oabi_get_bfd_for_interworking
+#define bfd_elf32_arm_process_before_allocation \
+ bfd_elf32_arm_oabi_process_before_allocation
+
+#include "elf32-arm.h"
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
new file mode 100644
index 00000000000..22f64886287
--- /dev/null
+++ b/bfd/elfcode.h
@@ -0,0 +1,1452 @@
+/* ELF executable support for BFD.
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support, from information published
+ in "UNIX System V Release 4, Programmers Guide: ANSI C and
+ Programming Support Tools". Sufficient support for gdb.
+
+ Rewritten by Mark Eichin @ Cygnus Support, from information
+ published in "System V Application Binary Interface", chapters 4
+ and 5, as well as the various "Processor Supplement" documents
+ derived from it. Added support for assembler and other object file
+ utilities. Further work done by Ken Raeburn (Cygnus Support), Michael
+ Meissner (Open Software Foundation), and Peter Hoogenboom (University
+ of Utah) to finish and extend this.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Problems and other issues to resolve.
+
+ (1) BFD expects there to be some fixed number of "sections" in
+ the object file. I.E. there is a "section_count" variable in the
+ bfd structure which contains the number of sections. However, ELF
+ supports multiple "views" of a file. In particular, with current
+ implementations, executable files typically have two tables, a
+ program header table and a section header table, both of which
+ partition the executable.
+
+ In ELF-speak, the "linking view" of the file uses the section header
+ table to access "sections" within the file, and the "execution view"
+ uses the program header table to access "segments" within the file.
+ "Segments" typically may contain all the data from one or more
+ "sections".
+
+ Note that the section header table is optional in ELF executables,
+ but it is this information that is most useful to gdb. If the
+ section header table is missing, then gdb should probably try
+ to make do with the program header table. (FIXME)
+
+ (2) The code in this file is compiled twice, once in 32-bit mode and
+ once in 64-bit mode. More of it should be made size-independent
+ and moved into elf.c.
+
+ (3) ELF section symbols are handled rather sloppily now. This should
+ be cleaned up, and ELF section symbols reconciled with BFD section
+ symbols.
+
+ (4) We need a published spec for 64-bit ELF. We've got some stuff here
+ that we're using for SPARC V9 64-bit chips, but don't assume that
+ it's cast in stone.
+ */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* Renaming structures, typedefs, macros and functions to be size-specific. */
+#define Elf_External_Ehdr NAME(Elf,External_Ehdr)
+#define Elf_External_Sym NAME(Elf,External_Sym)
+#define Elf_External_Shdr NAME(Elf,External_Shdr)
+#define Elf_External_Phdr NAME(Elf,External_Phdr)
+#define Elf_External_Rel NAME(Elf,External_Rel)
+#define Elf_External_Rela NAME(Elf,External_Rela)
+#define Elf_External_Dyn NAME(Elf,External_Dyn)
+
+#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command)
+#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal)
+#define elf_core_file_matches_executable_p \
+ NAME(bfd_elf,core_file_matches_executable_p)
+#define elf_object_p NAME(bfd_elf,object_p)
+#define elf_core_file_p NAME(bfd_elf,core_file_p)
+#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound)
+#define elf_get_dynamic_symtab_upper_bound \
+ NAME(bfd_elf,get_dynamic_symtab_upper_bound)
+#define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in)
+#define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in)
+#define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out)
+#define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out)
+#define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in)
+#define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out)
+#define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in)
+#define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out)
+#define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in)
+#define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out)
+#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound)
+#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc)
+#define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table)
+#define elf_get_symtab NAME(bfd_elf,get_symtab)
+#define elf_canonicalize_dynamic_symtab \
+ NAME(bfd_elf,canonicalize_dynamic_symtab)
+#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol)
+#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info)
+#define elf_get_lineno NAME(bfd_elf,get_lineno)
+#define elf_set_arch_mach NAME(bfd_elf,set_arch_mach)
+#define elf_find_nearest_line NAME(bfd_elf,find_nearest_line)
+#define elf_sizeof_headers NAME(bfd_elf,sizeof_headers)
+#define elf_set_section_contents NAME(bfd_elf,set_section_contents)
+#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto)
+#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel)
+#define elf_find_section NAME(bfd_elf,find_section)
+#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols)
+#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry)
+#define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr)
+#define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs)
+#define elf_link_create_dynamic_sections \
+ NAME(bfd_elf,link_create_dynamic_sections)
+#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
+#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link)
+#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section)
+#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section)
+#define elf_gc_sections NAME(_bfd_elf,gc_sections)
+#define elf_gc_common_finalize_got_offsets \
+ NAME(_bfd_elf,gc_common_finalize_got_offsets)
+#define elf_gc_common_final_link NAME(_bfd_elf,gc_common_final_link)
+#define elf_gc_record_vtinherit NAME(_bfd_elf,gc_record_vtinherit)
+#define elf_gc_record_vtentry NAME(_bfd_elf,gc_record_vtentry)
+
+#if ARCH_SIZE == 64
+#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELFCLASS ELFCLASS64
+#define FILE_ALIGN 8
+#define LOG_FILE_ALIGN 3
+#endif
+#if ARCH_SIZE == 32
+#define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELFCLASS ELFCLASS32
+#define FILE_ALIGN 4
+#define LOG_FILE_ALIGN 2
+#endif
+
+/* Static functions */
+
+static void elf_swap_ehdr_in
+ PARAMS ((bfd *, const Elf_External_Ehdr *, Elf_Internal_Ehdr *));
+static void elf_swap_ehdr_out
+ PARAMS ((bfd *, const Elf_Internal_Ehdr *, Elf_External_Ehdr *));
+static void elf_swap_shdr_in
+ PARAMS ((bfd *, const Elf_External_Shdr *, Elf_Internal_Shdr *));
+static void elf_swap_shdr_out
+ PARAMS ((bfd *, const Elf_Internal_Shdr *, Elf_External_Shdr *));
+
+#define elf_stringtab_init _bfd_elf_stringtab_init
+
+#define section_from_elf_index bfd_section_from_elf_index
+
+static boolean elf_slurp_reloc_table
+ PARAMS ((bfd *, asection *, asymbol **, boolean));
+
+static void write_relocs PARAMS ((bfd *, asection *, PTR));
+
+static boolean elf_file_p PARAMS ((Elf_External_Ehdr *));
+
+#ifdef DEBUG
+static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *));
+static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *));
+static char *elf_symbol_flags PARAMS ((flagword));
+#endif
+
+/* Structure swapping routines */
+
+/* Should perhaps use put_offset, put_word, etc. For now, the two versions
+ can be handled by explicitly specifying 32 bits or "the long type". */
+#if ARCH_SIZE == 64
+#define put_word bfd_h_put_64
+#define put_signed_word bfd_h_put_signed_64
+#define get_word bfd_h_get_64
+#define get_signed_word bfd_h_get_signed_64
+#endif
+#if ARCH_SIZE == 32
+#define put_word bfd_h_put_32
+#define put_signed_word bfd_h_put_signed_32
+#define get_word bfd_h_get_32
+#define get_signed_word bfd_h_get_signed_32
+#endif
+
+/* Translate an ELF symbol in external format into an ELF symbol in internal
+ format. */
+
+void
+elf_swap_symbol_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Sym *src;
+ Elf_Internal_Sym *dst;
+{
+ dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name);
+ dst->st_value = get_word (abfd, (bfd_byte *) src->st_value);
+ dst->st_size = get_word (abfd, (bfd_byte *) src->st_size);
+ dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info);
+ dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other);
+ dst->st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src->st_shndx);
+}
+
+/* Translate an ELF symbol in internal format into an ELF symbol in external
+ format. */
+
+void
+elf_swap_symbol_out (abfd, src, cdst)
+ bfd *abfd;
+ const Elf_Internal_Sym *src;
+ PTR cdst;
+{
+ Elf_External_Sym *dst = (Elf_External_Sym *) cdst;
+ bfd_h_put_32 (abfd, src->st_name, dst->st_name);
+ put_word (abfd, src->st_value, dst->st_value);
+ put_word (abfd, src->st_size, dst->st_size);
+ bfd_h_put_8 (abfd, src->st_info, dst->st_info);
+ bfd_h_put_8 (abfd, src->st_other, dst->st_other);
+ bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx);
+}
+
+
+/* Translate an ELF file header in external format into an ELF file header in
+ internal format. */
+
+static void
+elf_swap_ehdr_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Ehdr *src;
+ Elf_Internal_Ehdr *dst;
+{
+ memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
+ dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type);
+ dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine);
+ dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version);
+ dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry);
+ dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff);
+ dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff);
+ dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags);
+ dst->e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_ehsize);
+ dst->e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phentsize);
+ dst->e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phnum);
+ dst->e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shentsize);
+ dst->e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shnum);
+ dst->e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shstrndx);
+}
+
+/* Translate an ELF file header in internal format into an ELF file header in
+ external format. */
+
+static void
+elf_swap_ehdr_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Ehdr *src;
+ Elf_External_Ehdr *dst;
+{
+ memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
+ /* note that all elements of dst are *arrays of unsigned char* already... */
+ bfd_h_put_16 (abfd, src->e_type, dst->e_type);
+ bfd_h_put_16 (abfd, src->e_machine, dst->e_machine);
+ bfd_h_put_32 (abfd, src->e_version, dst->e_version);
+ put_word (abfd, src->e_entry, dst->e_entry);
+ put_word (abfd, src->e_phoff, dst->e_phoff);
+ put_word (abfd, src->e_shoff, dst->e_shoff);
+ bfd_h_put_32 (abfd, src->e_flags, dst->e_flags);
+ bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize);
+ bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize);
+ bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum);
+ bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize);
+ bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum);
+ bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx);
+}
+
+
+/* Translate an ELF section header table entry in external format into an
+ ELF section header table entry in internal format. */
+
+static void
+elf_swap_shdr_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Shdr *src;
+ Elf_Internal_Shdr *dst;
+{
+ dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name);
+ dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type);
+ dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags);
+ dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr);
+ dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset);
+ dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size);
+ dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link);
+ dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info);
+ dst->sh_addralign = get_word (abfd, (bfd_byte *) src->sh_addralign);
+ dst->sh_entsize = get_word (abfd, (bfd_byte *) src->sh_entsize);
+ dst->bfd_section = NULL;
+ dst->contents = NULL;
+}
+
+/* Translate an ELF section header table entry in internal format into an
+ ELF section header table entry in external format. */
+
+static void
+elf_swap_shdr_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Shdr *src;
+ Elf_External_Shdr *dst;
+{
+ /* note that all elements of dst are *arrays of unsigned char* already... */
+ bfd_h_put_32 (abfd, src->sh_name, dst->sh_name);
+ bfd_h_put_32 (abfd, src->sh_type, dst->sh_type);
+ put_word (abfd, src->sh_flags, dst->sh_flags);
+ put_word (abfd, src->sh_addr, dst->sh_addr);
+ put_word (abfd, src->sh_offset, dst->sh_offset);
+ put_word (abfd, src->sh_size, dst->sh_size);
+ bfd_h_put_32 (abfd, src->sh_link, dst->sh_link);
+ bfd_h_put_32 (abfd, src->sh_info, dst->sh_info);
+ put_word (abfd, src->sh_addralign, dst->sh_addralign);
+ put_word (abfd, src->sh_entsize, dst->sh_entsize);
+}
+
+
+/* Translate an ELF program header table entry in external format into an
+ ELF program header table entry in internal format. */
+
+void
+elf_swap_phdr_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Phdr *src;
+ Elf_Internal_Phdr *dst;
+{
+ dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type);
+ dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags);
+ dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset);
+ dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr);
+ dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr);
+ dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz);
+ dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz);
+ dst->p_align = get_word (abfd, (bfd_byte *) src->p_align);
+}
+
+void
+elf_swap_phdr_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Phdr *src;
+ Elf_External_Phdr *dst;
+{
+ /* note that all elements of dst are *arrays of unsigned char* already... */
+ bfd_h_put_32 (abfd, src->p_type, dst->p_type);
+ put_word (abfd, src->p_offset, dst->p_offset);
+ put_word (abfd, src->p_vaddr, dst->p_vaddr);
+ put_word (abfd, src->p_paddr, dst->p_paddr);
+ put_word (abfd, src->p_filesz, dst->p_filesz);
+ put_word (abfd, src->p_memsz, dst->p_memsz);
+ bfd_h_put_32 (abfd, src->p_flags, dst->p_flags);
+ put_word (abfd, src->p_align, dst->p_align);
+}
+
+/* Translate an ELF reloc from external format to internal format. */
+INLINE void
+elf_swap_reloc_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Rel *src;
+ Elf_Internal_Rel *dst;
+{
+ dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset);
+ dst->r_info = get_word (abfd, (bfd_byte *) src->r_info);
+}
+
+INLINE void
+elf_swap_reloca_in (abfd, src, dst)
+ bfd *abfd;
+ const Elf_External_Rela *src;
+ Elf_Internal_Rela *dst;
+{
+ dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset);
+ dst->r_info = get_word (abfd, (bfd_byte *) src->r_info);
+ dst->r_addend = get_signed_word (abfd, (bfd_byte *) src->r_addend);
+}
+
+/* Translate an ELF reloc from internal format to external format. */
+INLINE void
+elf_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Rel *src;
+ Elf_External_Rel *dst;
+{
+ put_word (abfd, src->r_offset, dst->r_offset);
+ put_word (abfd, src->r_info, dst->r_info);
+}
+
+INLINE void
+elf_swap_reloca_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Rela *src;
+ Elf_External_Rela *dst;
+{
+ put_word (abfd, src->r_offset, dst->r_offset);
+ put_word (abfd, src->r_info, dst->r_info);
+ put_signed_word (abfd, src->r_addend, dst->r_addend);
+}
+
+INLINE void
+elf_swap_dyn_in (abfd, p, dst)
+ bfd *abfd;
+ const PTR p;
+ Elf_Internal_Dyn *dst;
+{
+ const Elf_External_Dyn *src = (const Elf_External_Dyn *) p;
+
+ dst->d_tag = get_word (abfd, src->d_tag);
+ dst->d_un.d_val = get_word (abfd, src->d_un.d_val);
+}
+
+INLINE void
+elf_swap_dyn_out (abfd, src, dst)
+ bfd *abfd;
+ const Elf_Internal_Dyn *src;
+ Elf_External_Dyn *dst;
+{
+ put_word (abfd, src->d_tag, dst->d_tag);
+ put_word (abfd, src->d_un.d_val, dst->d_un.d_val);
+}
+
+/* ELF .o/exec file reading */
+
+
+/* Begin processing a given object.
+
+ First we validate the file by reading in the ELF header and checking
+ the magic number. */
+
+static INLINE boolean
+elf_file_p (x_ehdrp)
+ Elf_External_Ehdr *x_ehdrp;
+{
+ return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0)
+ && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1)
+ && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2)
+ && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));
+}
+
+/* Check to see if the file associated with ABFD matches the target vector
+ that ABFD points to.
+
+ Note that we may be called several times with the same ABFD, but different
+ target vectors, most of which will not match. We have to avoid leaving
+ any side effects in ABFD, or any data it points to (like tdata), if the
+ file does not match the target vector. */
+
+const bfd_target *
+elf_object_p (abfd)
+ bfd *abfd;
+{
+ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
+ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
+ Elf_External_Shdr x_shdr; /* Section header table entry, external form */
+ Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */
+ unsigned int shindex;
+ char *shstrtab; /* Internal copy of section header stringtab */
+ struct elf_backend_data *ebd;
+ struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
+ struct elf_obj_tdata *new_tdata = NULL;
+ asection *s;
+
+ /* Read in the ELF header in external format. */
+
+ if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ goto got_wrong_format_error;
+ else
+ goto got_no_match;
+ }
+
+ /* Now check to see if we have a valid ELF file, and one that BFD can
+ make use of. The magic number must match, the address size ('class')
+ and byte-swapping must match our XVEC entry, and it must have a
+ section header table (FIXME: See comments re sections at top of this
+ file). */
+
+ if ((elf_file_p (&x_ehdr) == false) ||
+ (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) ||
+ (x_ehdr.e_ident[EI_CLASS] != ELFCLASS))
+ goto got_wrong_format_error;
+
+ /* Check that file's byte order matches xvec's */
+ switch (x_ehdr.e_ident[EI_DATA])
+ {
+ case ELFDATA2MSB: /* Big-endian */
+ if (! bfd_header_big_endian (abfd))
+ goto got_wrong_format_error;
+ break;
+ case ELFDATA2LSB: /* Little-endian */
+ if (! bfd_header_little_endian (abfd))
+ goto got_wrong_format_error;
+ break;
+ case ELFDATANONE: /* No data encoding specified */
+ default: /* Unknown data encoding specified */
+ goto got_wrong_format_error;
+ }
+
+ /* Allocate an instance of the elf_obj_tdata structure and hook it up to
+ the tdata pointer in the bfd. */
+
+ new_tdata = ((struct elf_obj_tdata *)
+ bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)));
+ if (new_tdata == NULL)
+ goto got_no_match;
+ elf_tdata (abfd) = new_tdata;
+
+ /* Now that we know the byte order, swap in the rest of the header */
+ i_ehdrp = elf_elfheader (abfd);
+ elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
+#if DEBUG & 1
+ elf_debug_file (i_ehdrp);
+#endif
+
+ /* Reject ET_CORE (header indicates core file, not object file) */
+ if (i_ehdrp->e_type == ET_CORE)
+ goto got_wrong_format_error;
+
+ /* If there is no section header table, we're hosed. */
+ if (i_ehdrp->e_shoff == 0)
+ goto got_wrong_format_error;
+
+ /* As a simple sanity check, verify that the what BFD thinks is the
+ size of each section header table entry actually matches the size
+ recorded in the file. */
+ if (i_ehdrp->e_shentsize != sizeof (x_shdr))
+ goto got_wrong_format_error;
+
+ ebd = get_elf_backend_data (abfd);
+
+ /* Check that the ELF e_machine field matches what this particular
+ BFD format expects. */
+ if (ebd->elf_machine_code != i_ehdrp->e_machine
+ && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1)
+ && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2))
+ {
+ const bfd_target * const *target_ptr;
+
+ if (ebd->elf_machine_code != EM_NONE)
+ goto got_wrong_format_error;
+
+ /* This is the generic ELF target. Let it match any ELF target
+ for which we do not have a specific backend. */
+ for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
+ {
+ struct elf_backend_data *back;
+
+ if ((*target_ptr)->flavour != bfd_target_elf_flavour)
+ continue;
+ back = (struct elf_backend_data *) (*target_ptr)->backend_data;
+ if (back->elf_machine_code == i_ehdrp->e_machine
+ || (back->elf_machine_alt1 != 0
+ && back->elf_machine_alt1 == i_ehdrp->e_machine)
+ || (back->elf_machine_alt2 != 0
+ && back->elf_machine_alt2 == i_ehdrp->e_machine))
+ {
+ /* target_ptr is an ELF backend which matches this
+ object file, so reject the generic ELF target. */
+ goto got_wrong_format_error;
+ }
+ }
+ }
+
+ if (i_ehdrp->e_type == ET_EXEC)
+ abfd->flags |= EXEC_P;
+ else if (i_ehdrp->e_type == ET_DYN)
+ abfd->flags |= DYNAMIC;
+
+ if (i_ehdrp->e_phnum > 0)
+ abfd->flags |= D_PAGED;
+
+ if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
+ {
+ /* It's OK if this fails for the generic target. */
+ if (ebd->elf_machine_code != EM_NONE)
+ goto got_no_match;
+ }
+
+ /* Remember the entry point specified in the ELF file header. */
+ bfd_get_start_address (abfd) = i_ehdrp->e_entry;
+
+ /* Allocate space for a copy of the section header table in
+ internal form, seek to the section header table in the file,
+ read it in, and convert it to internal form. */
+ i_shdrp = ((Elf_Internal_Shdr *)
+ bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum));
+ elf_elfsections (abfd) = ((Elf_Internal_Shdr **)
+ bfd_alloc (abfd,
+ sizeof (i_shdrp) * i_ehdrp->e_shnum));
+ if (!i_shdrp || !elf_elfsections (abfd))
+ goto got_no_match;
+ if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) != 0)
+ goto got_no_match;
+ for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++)
+ {
+ if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr))
+ goto got_no_match;
+ elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
+ elf_elfsections (abfd)[shindex] = i_shdrp + shindex;
+
+ /* If the section is loaded, but not page aligned, clear
+ D_PAGED. */
+ if ((i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0
+ && i_shdrp[shindex].sh_type != SHT_NOBITS
+ && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)
+ % ebd->maxpagesize)
+ != 0))
+ abfd->flags &= ~D_PAGED;
+ }
+ if (i_ehdrp->e_shstrndx)
+ {
+ if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx))
+ goto got_no_match;
+ }
+
+ /* Read in the program headers. */
+ if (i_ehdrp->e_phnum == 0)
+ elf_tdata (abfd)->phdr = NULL;
+ else
+ {
+ Elf_Internal_Phdr *i_phdr;
+ unsigned int i;
+
+ elf_tdata (abfd)->phdr = ((Elf_Internal_Phdr *)
+ bfd_alloc (abfd,
+ (i_ehdrp->e_phnum
+ * sizeof (Elf_Internal_Phdr))));
+ if (elf_tdata (abfd)->phdr == NULL)
+ goto got_no_match;
+ if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0)
+ goto got_no_match;
+ i_phdr = elf_tdata (abfd)->phdr;
+ for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
+ {
+ Elf_External_Phdr x_phdr;
+
+ if (bfd_read ((PTR) &x_phdr, sizeof x_phdr, 1, abfd)
+ != sizeof x_phdr)
+ goto got_no_match;
+ elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
+ }
+ }
+
+ /* Read in the string table containing the names of the sections. We
+ will need the base pointer to this table later. */
+ /* We read this inline now, so that we don't have to go through
+ bfd_section_from_shdr with it (since this particular strtab is
+ used to find all of the ELF section names.) */
+
+ shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx);
+ if (!shstrtab)
+ goto got_no_match;
+
+ /* Once all of the section headers have been read and converted, we
+ can start processing them. Note that the first section header is
+ a dummy placeholder entry, so we ignore it. */
+
+ for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
+ {
+ if (! bfd_section_from_shdr (abfd, shindex))
+ goto got_no_match;
+ }
+
+ /* Let the backend double check the format and override global
+ information. */
+ if (ebd->elf_backend_object_p)
+ {
+ if ((*ebd->elf_backend_object_p) (abfd) == false)
+ goto got_wrong_format_error;
+ }
+
+ /* If we have created any reloc sections that are associated with
+ debugging sections, mark the reloc sections as debugging as well. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL
+ || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
+ && elf_section_data (s)->this_hdr.sh_info > 0)
+ {
+ unsigned long targ_index;
+ asection *targ_sec;
+
+ targ_index = elf_section_data (s)->this_hdr.sh_info;
+ targ_sec = bfd_section_from_elf_index (abfd, targ_index);
+ if (targ_sec != NULL
+ && (targ_sec->flags & SEC_DEBUGGING) != 0)
+ s->flags |= SEC_DEBUGGING;
+ }
+ }
+
+ return (abfd->xvec);
+
+ got_wrong_format_error:
+ bfd_set_error (bfd_error_wrong_format);
+ got_no_match:
+ if (new_tdata != NULL
+ && new_tdata->elf_sect_ptr != NULL)
+ bfd_release (abfd, new_tdata->elf_sect_ptr);
+ if (i_shdrp != NULL)
+ bfd_release (abfd, i_shdrp);
+ if (new_tdata != NULL)
+ bfd_release (abfd, new_tdata);
+ elf_tdata (abfd) = preserved_tdata;
+ return (NULL);
+}
+
+/* ELF .o/exec file writing */
+
+/* Write out the relocs. */
+
+static void
+write_relocs (abfd, sec, data)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+{
+ boolean *failedp = (boolean *) data;
+ Elf_Internal_Shdr *rela_hdr;
+ Elf_External_Rela *outbound_relocas;
+ Elf_External_Rel *outbound_relocs;
+ unsigned int idx;
+ int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
+ asymbol *last_sym = 0;
+ int last_sym_idx = 0;
+
+ /* If we have already failed, don't do anything. */
+ if (*failedp)
+ return;
+
+ if ((sec->flags & SEC_RELOC) == 0)
+ return;
+
+ /* The linker backend writes the relocs out itself, and sets the
+ reloc_count field to zero to inhibit writing them here. Also,
+ sometimes the SEC_RELOC flag gets set even when there aren't any
+ relocs. */
+ if (sec->reloc_count == 0)
+ return;
+
+ rela_hdr = &elf_section_data (sec)->rel_hdr;
+
+ rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
+ rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
+ if (rela_hdr->contents == NULL)
+ {
+ *failedp = true;
+ return;
+ }
+
+ /* orelocation has the data, reloc_count has the count... */
+ if (use_rela_p)
+ {
+ outbound_relocas = (Elf_External_Rela *) rela_hdr->contents;
+
+ for (idx = 0; idx < sec->reloc_count; idx++)
+ {
+ Elf_Internal_Rela dst_rela;
+ Elf_External_Rela *src_rela;
+ arelent *ptr;
+ asymbol *sym;
+ int n;
+
+ ptr = sec->orelocation[idx];
+ src_rela = outbound_relocas + idx;
+
+ /* The address of an ELF reloc is section relative for an object
+ file, and absolute for an executable file or shared library.
+ The address of a BFD reloc is always section relative. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ dst_rela.r_offset = ptr->address;
+ else
+ dst_rela.r_offset = ptr->address + sec->vma;
+
+ sym = *ptr->sym_ptr_ptr;
+ if (sym == last_sym)
+ n = last_sym_idx;
+ else if (bfd_is_abs_section (sym->section) && sym->value == 0)
+ n = STN_UNDEF;
+ else
+ {
+ last_sym = sym;
+ n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
+ if (n < 0)
+ {
+ *failedp = true;
+ return;
+ }
+ last_sym_idx = n;
+ }
+
+ if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
+ && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
+ {
+ *failedp = true;
+ return;
+ }
+
+ dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
+
+ dst_rela.r_addend = ptr->addend;
+ elf_swap_reloca_out (abfd, &dst_rela, src_rela);
+ }
+ }
+ else
+ /* REL relocations */
+ {
+ outbound_relocs = (Elf_External_Rel *) rela_hdr->contents;
+
+ for (idx = 0; idx < sec->reloc_count; idx++)
+ {
+ Elf_Internal_Rel dst_rel;
+ Elf_External_Rel *src_rel;
+ arelent *ptr;
+ int n;
+ asymbol *sym;
+
+ ptr = sec->orelocation[idx];
+ sym = *ptr->sym_ptr_ptr;
+ src_rel = outbound_relocs + idx;
+
+ /* The address of an ELF reloc is section relative for an object
+ file, and absolute for an executable file or shared library.
+ The address of a BFD reloc is always section relative. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ dst_rel.r_offset = ptr->address;
+ else
+ dst_rel.r_offset = ptr->address + sec->vma;
+
+ if (sym == last_sym)
+ n = last_sym_idx;
+ else
+ {
+ last_sym = sym;
+ n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
+ if (n < 0)
+ {
+ *failedp = true;
+ return;
+ }
+ last_sym_idx = n;
+ }
+
+ if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
+ {
+ *failedp = true;
+ return;
+ }
+
+ dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type);
+
+ elf_swap_reloc_out (abfd, &dst_rel, src_rel);
+ }
+ }
+}
+
+/* Write out the program headers. */
+
+int
+elf_write_out_phdrs (abfd, phdr, count)
+ bfd *abfd;
+ const Elf_Internal_Phdr *phdr;
+ int count;
+{
+ while (count--)
+ {
+ Elf_External_Phdr extphdr;
+ elf_swap_phdr_out (abfd, phdr, &extphdr);
+ if (bfd_write (&extphdr, sizeof (Elf_External_Phdr), 1, abfd)
+ != sizeof (Elf_External_Phdr))
+ return -1;
+ phdr++;
+ }
+ return 0;
+}
+
+/* Write out the section headers and the ELF file header. */
+
+boolean
+elf_write_shdrs_and_ehdr (abfd)
+ bfd *abfd;
+{
+ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
+ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
+ Elf_External_Shdr *x_shdrp; /* Section header table, external form */
+ Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
+ unsigned int count;
+
+ i_ehdrp = elf_elfheader (abfd);
+ i_shdrp = elf_elfsections (abfd);
+
+ /* swap the header before spitting it out... */
+
+#if DEBUG & 1
+ elf_debug_file (i_ehdrp);
+#endif
+ elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd)
+ != sizeof (x_ehdr)))
+ return false;
+
+ /* at this point we've concocted all the ELF sections... */
+ x_shdrp = (Elf_External_Shdr *)
+ bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum));
+ if (!x_shdrp)
+ return false;
+
+ for (count = 0; count < i_ehdrp->e_shnum; count++)
+ {
+#if DEBUG & 2
+ elf_debug_section (count, i_shdrp[count]);
+#endif
+ elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count);
+ }
+ if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
+ || (bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd)
+ != sizeof (*x_shdrp) * i_ehdrp->e_shnum))
+ return false;
+
+ /* need to dump the string table too... */
+
+ return true;
+}
+
+long
+elf_slurp_symbol_table (abfd, symptrs, dynamic)
+ bfd *abfd;
+ asymbol **symptrs; /* Buffer for generated bfd symbols */
+ boolean dynamic;
+{
+ Elf_Internal_Shdr *hdr;
+ Elf_Internal_Shdr *verhdr;
+ unsigned long symcount; /* Number of external ELF symbols */
+ elf_symbol_type *sym; /* Pointer to current bfd symbol */
+ elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
+ Elf_Internal_Sym i_sym;
+ Elf_External_Sym *x_symp = NULL;
+ Elf_External_Versym *x_versymp = NULL;
+
+ /* Read each raw ELF symbol, converting from external ELF form to
+ internal ELF form, and then using the information to create a
+ canonical bfd symbol table entry.
+
+ Note that we allocate the initial bfd canonical symbol buffer
+ based on a one-to-one mapping of the ELF symbols to canonical
+ symbols. We actually use all the ELF symbols, so there will be no
+ space left over at the end. When we have all the symbols, we
+ build the caller's pointer vector. */
+
+ if (! dynamic)
+ {
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ verhdr = NULL;
+ }
+ else
+ {
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ if (elf_dynversym (abfd) == 0)
+ verhdr = NULL;
+ else
+ verhdr = &elf_tdata (abfd)->dynversym_hdr;
+ if ((elf_tdata (abfd)->dynverdef_section != 0
+ && elf_tdata (abfd)->verdef == NULL)
+ || (elf_tdata (abfd)->dynverref_section != 0
+ && elf_tdata (abfd)->verref == NULL))
+ {
+ if (! _bfd_elf_slurp_version_tables (abfd))
+ return -1;
+ }
+ }
+
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
+ return -1;
+
+ symcount = hdr->sh_size / sizeof (Elf_External_Sym);
+
+ if (symcount == 0)
+ sym = symbase = NULL;
+ else
+ {
+ unsigned long i;
+
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
+ return -1;
+
+ symbase = ((elf_symbol_type *)
+ bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type)));
+ if (symbase == (elf_symbol_type *) NULL)
+ return -1;
+ sym = symbase;
+
+ /* Temporarily allocate room for the raw ELF symbols. */
+ x_symp = ((Elf_External_Sym *)
+ bfd_malloc (symcount * sizeof (Elf_External_Sym)));
+ if (x_symp == NULL && symcount != 0)
+ goto error_return;
+
+ if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd)
+ != symcount * sizeof (Elf_External_Sym))
+ goto error_return;
+
+ /* Read the raw ELF version symbol information. */
+
+ if (verhdr != NULL
+ && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
+ {
+ (*_bfd_error_handler)
+ (_("%s: version count (%ld) does not match symbol count (%ld)"),
+ abfd->filename,
+ (long) (verhdr->sh_size / sizeof (Elf_External_Versym)),
+ symcount);
+
+ /* Slurp in the symbols without the version information,
+ since that is more helpful than just quitting. */
+ verhdr = NULL;
+ }
+
+ if (verhdr != NULL)
+ {
+ if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
+ goto error_return;
+
+ x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
+ if (x_versymp == NULL && verhdr->sh_size != 0)
+ goto error_return;
+
+ if (bfd_read ((PTR) x_versymp, 1, verhdr->sh_size, abfd)
+ != verhdr->sh_size)
+ goto error_return;
+ }
+
+ /* Skip first symbol, which is a null dummy. */
+ for (i = 1; i < symcount; i++)
+ {
+ elf_swap_symbol_in (abfd, x_symp + i, &i_sym);
+ memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym));
+#ifdef ELF_KEEP_EXTSYM
+ memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym));
+#endif
+ sym->symbol.the_bfd = abfd;
+
+ sym->symbol.name = bfd_elf_string_from_elf_section (abfd,
+ hdr->sh_link,
+ i_sym.st_name);
+
+ sym->symbol.value = i_sym.st_value;
+
+ if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERVE)
+ {
+ sym->symbol.section = section_from_elf_index (abfd,
+ i_sym.st_shndx);
+ if (sym->symbol.section == NULL)
+ {
+ /* This symbol is in a section for which we did not
+ create a BFD section. Just use bfd_abs_section,
+ although it is wrong. FIXME. */
+ sym->symbol.section = bfd_abs_section_ptr;
+ }
+ }
+ else if (i_sym.st_shndx == SHN_ABS)
+ {
+ sym->symbol.section = bfd_abs_section_ptr;
+ }
+ else if (i_sym.st_shndx == SHN_COMMON)
+ {
+ sym->symbol.section = bfd_com_section_ptr;
+ /* Elf puts the alignment into the `value' field, and
+ the size into the `size' field. BFD wants to see the
+ size in the value field, and doesn't care (at the
+ moment) about the alignment. */
+ sym->symbol.value = i_sym.st_size;
+ }
+ else if (i_sym.st_shndx == SHN_UNDEF)
+ {
+ sym->symbol.section = bfd_und_section_ptr;
+ }
+ else
+ sym->symbol.section = bfd_abs_section_ptr;
+
+ /* If this is a relocateable file, then the symbol value is
+ already section relative. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ sym->symbol.value -= sym->symbol.section->vma;
+
+ switch (ELF_ST_BIND (i_sym.st_info))
+ {
+ case STB_LOCAL:
+ sym->symbol.flags |= BSF_LOCAL;
+ break;
+ case STB_GLOBAL:
+ if (i_sym.st_shndx != SHN_UNDEF
+ && i_sym.st_shndx != SHN_COMMON)
+ sym->symbol.flags |= BSF_GLOBAL;
+ break;
+ case STB_WEAK:
+ sym->symbol.flags |= BSF_WEAK;
+ break;
+ }
+
+ switch (ELF_ST_TYPE (i_sym.st_info))
+ {
+ case STT_SECTION:
+ sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
+ break;
+ case STT_FILE:
+ sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING;
+ break;
+ case STT_FUNC:
+ sym->symbol.flags |= BSF_FUNCTION;
+ break;
+ case STT_OBJECT:
+ sym->symbol.flags |= BSF_OBJECT;
+ break;
+ }
+
+ if (dynamic)
+ sym->symbol.flags |= BSF_DYNAMIC;
+
+ if (x_versymp != NULL)
+ {
+ Elf_Internal_Versym iversym;
+
+ _bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym);
+ sym->version = iversym.vs_vers;
+ }
+
+ /* Do some backend-specific processing on this symbol. */
+ {
+ struct elf_backend_data *ebd = get_elf_backend_data (abfd);
+ if (ebd->elf_backend_symbol_processing)
+ (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
+ }
+
+ sym++;
+ }
+ }
+
+ /* Do some backend-specific processing on this symbol table. */
+ {
+ struct elf_backend_data *ebd = get_elf_backend_data (abfd);
+ if (ebd->elf_backend_symbol_table_processing)
+ (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
+ }
+
+ /* We rely on the zalloc to clear out the final symbol entry. */
+
+ symcount = sym - symbase;
+
+ /* Fill in the user's symbol pointer vector if needed. */
+ if (symptrs)
+ {
+ long l = symcount;
+
+ sym = symbase;
+ while (l-- > 0)
+ {
+ *symptrs++ = &sym->symbol;
+ sym++;
+ }
+ *symptrs = 0; /* Final null pointer */
+ }
+
+ if (x_versymp != NULL)
+ free (x_versymp);
+ if (x_symp != NULL)
+ free (x_symp);
+ return symcount;
+error_return:
+ if (x_versymp != NULL)
+ free (x_versymp);
+ if (x_symp != NULL)
+ free (x_symp);
+ return -1;
+}
+
+/* Read in and swap the external relocs. */
+
+static boolean
+elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
+ bfd *abfd;
+ asection *asect;
+ asymbol **symbols;
+ boolean dynamic;
+{
+ struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
+ struct bfd_elf_section_data * const d = elf_section_data (asect);
+ Elf_Internal_Shdr *rel_hdr;
+ bfd_size_type reloc_count;
+ PTR allocated = NULL;
+ bfd_byte *native_relocs;
+ arelent *relents;
+ arelent *relent;
+ unsigned int i;
+ int entsize;
+
+ if (asect->relocation != NULL)
+ return true;
+
+ if (! dynamic)
+ {
+ if ((asect->flags & SEC_RELOC) == 0
+ || asect->reloc_count == 0)
+ return true;
+
+ rel_hdr = &d->rel_hdr;
+ reloc_count = asect->reloc_count;
+
+ BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+ && reloc_count == rel_hdr->sh_size / rel_hdr->sh_entsize);
+ }
+ else
+ {
+ if (asect->_raw_size == 0)
+ return true;
+
+ rel_hdr = &d->this_hdr;
+ reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
+ }
+
+ allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
+ if (allocated == NULL)
+ goto error_return;
+
+ if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd)
+ != rel_hdr->sh_size))
+ goto error_return;
+
+ native_relocs = (bfd_byte *) allocated;
+
+ relents = (arelent *) bfd_alloc (abfd, reloc_count * sizeof (arelent));
+ if (relents == NULL)
+ goto error_return;
+
+ entsize = rel_hdr->sh_entsize;
+ BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
+ || entsize == sizeof (Elf_External_Rela));
+
+ for (i = 0, relent = relents;
+ i < reloc_count;
+ i++, relent++, native_relocs += entsize)
+ {
+ Elf_Internal_Rela rela;
+ Elf_Internal_Rel rel;
+
+ if (entsize == sizeof (Elf_External_Rela))
+ elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela);
+ else
+ {
+ elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel);
+ rela.r_offset = rel.r_offset;
+ rela.r_info = rel.r_info;
+ rela.r_addend = 0;
+ }
+
+ /* The address of an ELF reloc is section relative for an object
+ file, and absolute for an executable file or shared library.
+ The address of a normal BFD reloc is always section relative,
+ and the address of a dynamic reloc is absolute.. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
+ relent->address = rela.r_offset;
+ else
+ relent->address = rela.r_offset - asect->vma;
+
+ if (ELF_R_SYM (rela.r_info) == 0)
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ else
+ {
+ asymbol **ps, *s;
+
+ ps = symbols + ELF_R_SYM (rela.r_info) - 1;
+ s = *ps;
+
+ /* Canonicalize ELF section symbols. FIXME: Why? */
+ if ((s->flags & BSF_SECTION_SYM) == 0)
+ relent->sym_ptr_ptr = ps;
+ else
+ relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
+ }
+
+ relent->addend = rela.r_addend;
+
+ if (entsize == sizeof (Elf_External_Rela))
+ (*ebd->elf_info_to_howto) (abfd, relent, &rela);
+ else
+ (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel);
+ }
+
+ asect->relocation = relents;
+
+ if (allocated != NULL)
+ free (allocated);
+
+ return true;
+
+ error_return:
+ if (allocated != NULL)
+ free (allocated);
+ return false;
+}
+
+#ifdef DEBUG
+static void
+elf_debug_section (num, hdr)
+ int num;
+ Elf_Internal_Shdr *hdr;
+{
+ fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num,
+ hdr->bfd_section != NULL ? hdr->bfd_section->name : "",
+ (long) hdr);
+ fprintf (stderr,
+ "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n",
+ (long) hdr->sh_name,
+ (long) hdr->sh_type,
+ (long) hdr->sh_flags);
+ fprintf (stderr,
+ "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n",
+ (long) hdr->sh_addr,
+ (long) hdr->sh_offset,
+ (long) hdr->sh_size);
+ fprintf (stderr,
+ "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n",
+ (long) hdr->sh_link,
+ (long) hdr->sh_info,
+ (long) hdr->sh_addralign);
+ fprintf (stderr, "sh_entsize = %ld\n",
+ (long) hdr->sh_entsize);
+ fflush (stderr);
+}
+
+static void
+elf_debug_file (ehdrp)
+ Elf_Internal_Ehdr *ehdrp;
+{
+ fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry);
+ fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff);
+ fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum);
+ fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize);
+ fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff);
+ fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum);
+ fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize);
+}
+
+static char *
+elf_symbol_flags (flags)
+ flagword flags;
+{
+ static char buffer[1024];
+
+ buffer[0] = '\0';
+ if (flags & BSF_LOCAL)
+ strcat (buffer, " local");
+
+ if (flags & BSF_GLOBAL)
+ strcat (buffer, " global");
+
+ if (flags & BSF_DEBUGGING)
+ strcat (buffer, " debug");
+
+ if (flags & BSF_FUNCTION)
+ strcat (buffer, " function");
+
+ if (flags & BSF_KEEP)
+ strcat (buffer, " keep");
+
+ if (flags & BSF_KEEP_G)
+ strcat (buffer, " keep_g");
+
+ if (flags & BSF_WEAK)
+ strcat (buffer, " weak");
+
+ if (flags & BSF_SECTION_SYM)
+ strcat (buffer, " section-sym");
+
+ if (flags & BSF_OLD_COMMON)
+ strcat (buffer, " old-common");
+
+ if (flags & BSF_NOT_AT_END)
+ strcat (buffer, " not-at-end");
+
+ if (flags & BSF_CONSTRUCTOR)
+ strcat (buffer, " constructor");
+
+ if (flags & BSF_WARNING)
+ strcat (buffer, " warning");
+
+ if (flags & BSF_INDIRECT)
+ strcat (buffer, " indirect");
+
+ if (flags & BSF_FILE)
+ strcat (buffer, " file");
+
+ if (flags & DYNAMIC)
+ strcat (buffer, " dynamic");
+
+ if (flags & ~(BSF_LOCAL
+ | BSF_GLOBAL
+ | BSF_DEBUGGING
+ | BSF_FUNCTION
+ | BSF_KEEP
+ | BSF_KEEP_G
+ | BSF_WEAK
+ | BSF_SECTION_SYM
+ | BSF_OLD_COMMON
+ | BSF_NOT_AT_END
+ | BSF_CONSTRUCTOR
+ | BSF_WARNING
+ | BSF_INDIRECT
+ | BSF_FILE
+ | BSF_DYNAMIC))
+ strcat (buffer, " unknown-bits");
+
+ return buffer;
+}
+#endif
+
+#include "elfcore.h"
+#include "elflink.h"
+
+/* Size-dependent data and functions. */
+const struct elf_size_info NAME(_bfd_elf,size_info) = {
+ sizeof (Elf_External_Ehdr),
+ sizeof (Elf_External_Phdr),
+ sizeof (Elf_External_Shdr),
+ sizeof (Elf_External_Rel),
+ sizeof (Elf_External_Rela),
+ sizeof (Elf_External_Sym),
+ sizeof (Elf_External_Dyn),
+ sizeof (Elf_External_Note),
+
+ ARCH_SIZE, FILE_ALIGN,
+ ELFCLASS, EV_CURRENT,
+ elf_write_out_phdrs,
+ elf_write_shdrs_and_ehdr,
+ write_relocs,
+ elf_swap_symbol_out,
+ elf_slurp_reloc_table,
+ elf_slurp_symbol_table,
+ elf_swap_dyn_in
+};
diff --git a/bfd/elfcore.h b/bfd/elfcore.h
new file mode 100644
index 00000000000..e4454aac9d0
--- /dev/null
+++ b/bfd/elfcore.h
@@ -0,0 +1,226 @@
+/* ELF core file support for BFD.
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+char*
+elf_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return elf_tdata (abfd)->core_command;
+}
+
+int
+elf_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return elf_tdata (abfd)->core_signal;
+}
+
+
+boolean
+elf_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd;
+ bfd *exec_bfd;
+{
+ char* corename;
+
+ /* xvecs must match if both are ELF files for the same target. */
+
+ if (core_bfd->xvec != exec_bfd->xvec)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return false;
+ }
+
+ /* See if the name in the corefile matches the executable name. */
+
+ corename = elf_tdata (core_bfd)->core_program;
+ if (corename != NULL)
+ {
+ const char* execname = strrchr (exec_bfd->filename, '/');
+ execname = execname ? execname + 1 : exec_bfd->filename;
+
+ if (strcmp(execname, corename) != 0)
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Core files are simply standard ELF formatted files that partition
+ the file using the execution view of the file (program header table)
+ rather than the linking view. In fact, there is no section header
+ table in a core file.
+
+ The process status information (including the contents of the general
+ register set) and the floating point register set are stored in a
+ segment of type PT_NOTE. We handcraft a couple of extra bfd sections
+ that allow standard bfd access to the general registers (.reg) and the
+ floating point registers (.reg2).
+
+ */
+
+const bfd_target *
+elf_core_file_p (abfd)
+ bfd *abfd;
+{
+ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
+ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
+ Elf_Internal_Phdr *i_phdrp; /* Elf program header, internal form */
+ unsigned int phindex;
+ struct elf_backend_data *ebd;
+
+ /* Read in the ELF header in external format. */
+ if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Check the magic number. */
+ if (elf_file_p (&x_ehdr) == false)
+ {
+ wrong:
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* FIXME: Check EI_VERSION here ! */
+
+ /* Check the address size ("class"). */
+ if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
+ goto wrong;
+
+ /* Check the byteorder. */
+ switch (x_ehdr.e_ident[EI_DATA])
+ {
+ case ELFDATA2MSB: /* Big-endian */
+ if (! bfd_big_endian (abfd))
+ goto wrong;
+ break;
+ case ELFDATA2LSB: /* Little-endian */
+ if (! bfd_little_endian (abfd))
+ goto wrong;
+ break;
+ default:
+ goto wrong;
+ }
+
+ /* Give abfd an elf_obj_tdata. */
+ elf_tdata (abfd) =
+ (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
+ if (elf_tdata (abfd) == NULL)
+ return NULL;
+
+ /* FIXME: from here on down, "goto wrong" will leak memory. */
+
+ /* Swap in the rest of the header, now that we have the byte order. */
+ i_ehdrp = elf_elfheader (abfd);
+ elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
+
+#if DEBUG & 1
+ elf_debug_file (i_ehdrp);
+#endif
+
+ ebd = get_elf_backend_data (abfd);
+
+ /* Check that the ELF e_machine field matches what this particular
+ BFD format expects. */
+
+ if (ebd->elf_machine_code != i_ehdrp->e_machine
+ && (ebd->elf_machine_alt1 == 0
+ || i_ehdrp->e_machine != ebd->elf_machine_alt1)
+ && (ebd->elf_machine_alt2 == 0
+ || i_ehdrp->e_machine != ebd->elf_machine_alt2))
+ {
+ const bfd_target * const *target_ptr;
+
+ if (ebd->elf_machine_code != EM_NONE)
+ goto wrong;
+
+ /* This is the generic ELF target. Let it match any ELF target
+ for which we do not have a specific backend. */
+
+ for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
+ {
+ struct elf_backend_data *back;
+
+ if ((*target_ptr)->flavour != bfd_target_elf_flavour)
+ continue;
+ back = (struct elf_backend_data *) (*target_ptr)->backend_data;
+ if (back->elf_machine_code == i_ehdrp->e_machine)
+ {
+ /* target_ptr is an ELF backend which matches this
+ object file, so reject the generic ELF target. */
+ goto wrong;
+ }
+ }
+ }
+
+ /* If there is no program header, or the type is not a core file, then
+ we are hosed. */
+ if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
+ goto wrong;
+
+ /* Does BFD's idea of the phdr size match the size
+ recorded in the file? */
+ if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
+ goto wrong;
+
+ /* Allocate space for the program headers. */
+ i_phdrp = (Elf_Internal_Phdr *)
+ bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
+ if (!i_phdrp)
+ return NULL;
+
+ elf_tdata (abfd)->phdr = i_phdrp;
+
+ /* Read and convert to internal form. */
+ for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
+ {
+ Elf_External_Phdr x_phdr;
+ if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd)
+ != sizeof (x_phdr))
+ return NULL;
+
+ elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
+ }
+
+ /* Process each program header. */
+ for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
+ {
+ if (!_bfd_elfcore_section_from_phdr (abfd, i_phdrp + phindex, phindex))
+ return NULL;
+ }
+
+ /* Set the machine architecture. */
+ if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
+ {
+ /* It's OK if this fails for the generic target. */
+ if (ebd->elf_machine_code != EM_NONE)
+ return NULL;
+ }
+
+ /* Save the entry point from the ELF header. */
+ bfd_get_start_address (abfd) = i_ehdrp->e_entry;
+
+ return abfd->xvec;
+}
diff --git a/bfd/elflink.c b/bfd/elflink.c
new file mode 100644
index 00000000000..dc0b0428c60
--- /dev/null
+++ b/bfd/elflink.c
@@ -0,0 +1,433 @@
+/* ELF linking support for BFD.
+ Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#define ARCH_SIZE 0
+#include "elf-bfd.h"
+
+boolean
+_bfd_elf_create_got_section (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+ struct elf_link_hash_entry *h;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign;
+
+ /* This function may be called more than once. */
+ if (bfd_get_section_by_name (abfd, ".got") != NULL)
+ return true;
+
+ switch (bed->s->arch_size)
+ {
+ case 32: ptralign = 2; break;
+ case 64: ptralign = 3; break;
+ default: abort();
+ }
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ s = bfd_make_section (abfd, ".got");
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, flags)
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return false;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section (abfd, ".got.plt");
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, flags)
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return false;
+ }
+
+ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
+ (or .got.plt) section. We don't do this in the linker script
+ because we don't want to define the symbol if we are not creating
+ a global offset table. */
+ h = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
+ bed->got_symbol_offset, (const char *) NULL, false,
+ bed->collect, (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (info->shared
+ && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ elf_hash_table (info)->hgot = h;
+
+ /* The first bit of the global offset table is the header. */
+ s->_raw_size += bed->got_header_size + bed->got_symbol_offset;
+
+ return true;
+}
+
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+boolean
+_bfd_elf_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags, pltflags;
+ register asection *s;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign;
+
+ switch (bed->s->arch_size)
+ {
+ case 32: ptralign = 2; break;
+ case 64: ptralign = 3; break;
+ default: abort();
+ }
+
+ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
+ .rel[a].bss sections. */
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ pltflags = flags;
+ pltflags |= SEC_CODE;
+ if (bed->plt_not_loaded)
+ pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
+ if (bed->plt_readonly)
+ pltflags |= SEC_READONLY;
+
+ s = bfd_make_section (abfd, ".plt");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, pltflags)
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return false;
+
+ if (bed->want_plt_sym)
+ {
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ struct elf_link_hash_entry *h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (info->shared
+ && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.plt" : ".rel.plt");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return false;
+
+ if (! _bfd_elf_create_got_section (abfd, info))
+ return false;
+
+ /* The .dynbss section is a place to put symbols which are defined
+ by dynamic objects, are referenced by regular objects, and are
+ not functions. We must allocate space for them in the process
+ image and use a R_*_COPY reloc to tell the dynamic linker to
+ initialize them at run time. The linker script puts the .dynbss
+ section into the .bss section of the final image. */
+ s = bfd_make_section (abfd, ".dynbss");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
+ return false;
+
+ /* The .rel[a].bss section holds copy relocs. This section is not
+ normally needed. We need to create it here, though, so that the
+ linker will map it to an output section. We can't just create it
+ only if we need it, because we will not know whether we need it
+ until we have seen all the input files, and the first time the
+ main linker code calls BFD after examining all the input files
+ (size_dynamic_sections) the input sections have already been
+ mapped to the output sections. If the section turns out not to
+ be needed, we can discard it later. We will never need this
+ section when generating a shared object, since they do not use
+ copy relocs. */
+ if (! info->shared)
+ {
+ s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.bss" : ".rel.bss");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Record a new dynamic symbol. We record the dynamic symbols as we
+ read the input files, since we need to have a list of all of them
+ before we can determine the final sizes of the output sections.
+ Note that we may actually call this function even though we are not
+ going to output any dynamic symbols; in some cases we know that a
+ symbol should be in the dynamic symbol table, but only if there is
+ one. */
+
+boolean
+_bfd_elf_link_record_dynamic_symbol (info, h)
+ struct bfd_link_info *info;
+ struct elf_link_hash_entry *h;
+{
+ if (h->dynindx == -1)
+ {
+ struct bfd_strtab_hash *dynstr;
+ char *p, *alc;
+ const char *name;
+ boolean copy;
+ bfd_size_type indx;
+
+ h->dynindx = elf_hash_table (info)->dynsymcount;
+ ++elf_hash_table (info)->dynsymcount;
+
+ dynstr = elf_hash_table (info)->dynstr;
+ if (dynstr == NULL)
+ {
+ /* Create a strtab to hold the dynamic symbol names. */
+ elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
+ if (dynstr == NULL)
+ return false;
+ }
+
+ /* We don't put any version information in the dynamic string
+ table. */
+ name = h->root.root.string;
+ p = strchr (name, ELF_VER_CHR);
+ if (p == NULL)
+ {
+ alc = NULL;
+ copy = false;
+ }
+ else
+ {
+ alc = bfd_malloc (p - name + 1);
+ if (alc == NULL)
+ return false;
+ strncpy (alc, name, p - name);
+ alc[p - name] = '\0';
+ name = alc;
+ copy = true;
+ }
+
+ indx = _bfd_stringtab_add (dynstr, name, true, copy);
+
+ if (alc != NULL)
+ free (alc);
+
+ if (indx == (bfd_size_type) -1)
+ return false;
+ h->dynstr_index = indx;
+ }
+
+ return true;
+}
+
+/* Create a special linker section, or return a pointer to a linker section already created */
+
+elf_linker_section_t *
+_bfd_elf_create_linker_section (abfd, info, which, defaults)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ enum elf_linker_section_enum which;
+ elf_linker_section_t *defaults;
+{
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ elf_linker_section_t *lsect;
+
+ /* Record the first bfd section that needs the special section */
+ if (!dynobj)
+ dynobj = elf_hash_table (info)->dynobj = abfd;
+
+ /* If this is the first time, create the section */
+ lsect = elf_linker_section (dynobj, which);
+ if (!lsect)
+ {
+ asection *s;
+
+ lsect = (elf_linker_section_t *)
+ bfd_alloc (dynobj, sizeof (elf_linker_section_t));
+
+ *lsect = *defaults;
+ elf_linker_section (dynobj, which) = lsect;
+ lsect->which = which;
+ lsect->hole_written_p = false;
+
+ /* See if the sections already exist */
+ lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name);
+ if (!s || (s->flags & defaults->flags) != defaults->flags)
+ {
+ lsect->section = s = bfd_make_section_anyway (dynobj, lsect->name);
+
+ if (s == NULL)
+ return (elf_linker_section_t *)0;
+
+ bfd_set_section_flags (dynobj, s, defaults->flags);
+ bfd_set_section_alignment (dynobj, s, lsect->alignment);
+ }
+ else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment)
+ bfd_set_section_alignment (dynobj, s, lsect->alignment);
+
+ s->_raw_size = align_power (s->_raw_size, lsect->alignment);
+
+ /* Is there a hole we have to provide? If so check whether the segment is
+ too big already */
+ if (lsect->hole_size)
+ {
+ lsect->hole_offset = s->_raw_size;
+ s->_raw_size += lsect->hole_size;
+ if (lsect->hole_offset > lsect->max_hole_offset)
+ {
+ (*_bfd_error_handler) (_("%s: Section %s is already to large to put hole of %ld bytes in"),
+ bfd_get_filename (abfd),
+ lsect->name,
+ (long)lsect->hole_size);
+
+ bfd_set_error (bfd_error_bad_value);
+ return (elf_linker_section_t *)0;
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "Creating section %s, current size = %ld\n",
+ lsect->name, (long)s->_raw_size);
+#endif
+
+ if (lsect->sym_name)
+ {
+ struct elf_link_hash_entry *h = NULL;
+#ifdef DEBUG
+ fprintf (stderr, "Adding %s to section %s\n",
+ lsect->sym_name,
+ lsect->name);
+#endif
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false);
+
+ if ((h == NULL || h->root.type == bfd_link_hash_undefined)
+ && !(_bfd_generic_link_add_one_symbol (info,
+ abfd,
+ lsect->sym_name,
+ BSF_GLOBAL,
+ s,
+ ((lsect->hole_size)
+ ? s->_raw_size - lsect->hole_size + lsect->sym_offset
+ : lsect->sym_offset),
+ (const char *) NULL,
+ false,
+ get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return (elf_linker_section_t *)0;
+
+ if ((defaults->which != LINKER_SECTION_SDATA)
+ && (defaults->which != LINKER_SECTION_SDATA2))
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC;
+
+ h->type = STT_OBJECT;
+ lsect->sym_hash = h;
+
+ if (info->shared
+ && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return (elf_linker_section_t *)0;
+ }
+ }
+
+#if 0
+ /* This does not make sense. The sections which may exist in the
+ object file have nothing to do with the sections we want to
+ create. */
+
+ /* Find the related sections if they have been created */
+ if (lsect->bss_name && !lsect->bss_section)
+ lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name);
+
+ if (lsect->rel_name && !lsect->rel_section)
+ lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
+#endif
+
+ return lsect;
+}
+
+
+/* Find a linker generated pointer with a given addend and type. */
+
+elf_linker_section_pointers_t *
+_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which)
+ elf_linker_section_pointers_t *linker_pointers;
+ bfd_signed_vma addend;
+ elf_linker_section_enum_t which;
+{
+ for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
+ {
+ if (which == linker_pointers->which && addend == linker_pointers->addend)
+ return linker_pointers;
+ }
+
+ return (elf_linker_section_pointers_t *)0;
+}
+
+
+/* Make the .rela section corresponding to the generated linker section. */
+
+boolean
+_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment)
+ bfd *dynobj;
+ elf_linker_section_t *lsect;
+ int alignment;
+{
+ if (lsect->rel_section)
+ return true;
+
+ lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name);
+ if (lsect->rel_section == NULL)
+ {
+ lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name);
+ if (lsect->rel_section == NULL
+ || ! bfd_set_section_flags (dynobj,
+ lsect->rel_section,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment))
+ return false;
+ }
+
+ return true;
+}
diff --git a/bfd/elflink.h b/bfd/elflink.h
new file mode 100644
index 00000000000..32bfab0e802
--- /dev/null
+++ b/bfd/elflink.h
@@ -0,0 +1,6150 @@
+/* ELF linker support.
+ Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ELF linker code. */
+
+/* This struct is used to pass information to routines called via
+ elf_link_hash_traverse which must return failure. */
+
+struct elf_info_failed
+{
+ boolean failed;
+ struct bfd_link_info *info;
+};
+
+static boolean elf_link_add_object_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf_link_add_archive_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf_merge_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+ asection **, bfd_vma *, struct elf_link_hash_entry **,
+ boolean *, boolean *, boolean *));
+static boolean elf_export_symbol
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_fix_symbol_flags
+ PARAMS ((struct elf_link_hash_entry *, struct elf_info_failed *));
+static boolean elf_adjust_dynamic_symbol
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_link_find_version_dependencies
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_link_find_version_dependencies
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_link_assign_sym_version
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_link_renumber_dynsyms
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_collect_hash_codes
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+
+/* Given an ELF BFD, add symbols to the global hash table as
+ appropriate. */
+
+boolean
+elf_bfd_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return elf_link_add_object_symbols (abfd, info);
+ case bfd_archive:
+ return elf_link_add_archive_symbols (abfd, info);
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+}
+
+
+/* Add symbols from an ELF archive file to the linker hash table. We
+ don't use _bfd_generic_link_add_archive_symbols because of a
+ problem which arises on UnixWare. The UnixWare libc.so is an
+ archive which includes an entry libc.so.1 which defines a bunch of
+ symbols. The libc.so archive also includes a number of other
+ object files, which also define symbols, some of which are the same
+ as those defined in libc.so.1. Correct linking requires that we
+ consider each object file in turn, and include it if it defines any
+ symbols we need. _bfd_generic_link_add_archive_symbols does not do
+ this; it looks through the list of undefined symbols, and includes
+ any object file which defines them. When this algorithm is used on
+ UnixWare, it winds up pulling in libc.so.1 early and defining a
+ bunch of symbols. This means that some of the other objects in the
+ archive are not included in the link, which is incorrect since they
+ precede libc.so.1 in the archive.
+
+ Fortunately, ELF archive handling is simpler than that done by
+ _bfd_generic_link_add_archive_symbols, which has to allow for a.out
+ oddities. In ELF, if we find a symbol in the archive map, and the
+ symbol is currently undefined, we know that we must pull in that
+ object file.
+
+ Unfortunately, we do have to make multiple passes over the symbol
+ table until nothing further is resolved. */
+
+static boolean
+elf_link_add_archive_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ symindex c;
+ boolean *defined = NULL;
+ boolean *included = NULL;
+ carsym *symdefs;
+ boolean loop;
+
+ if (! bfd_has_map (abfd))
+ {
+ /* An empty archive is a special case. */
+ if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL)
+ return true;
+ bfd_set_error (bfd_error_no_armap);
+ return false;
+ }
+
+ /* Keep track of all symbols we know to be already defined, and all
+ files we know to be already included. This is to speed up the
+ second and subsequent passes. */
+ c = bfd_ardata (abfd)->symdef_count;
+ if (c == 0)
+ return true;
+ defined = (boolean *) bfd_malloc (c * sizeof (boolean));
+ included = (boolean *) bfd_malloc (c * sizeof (boolean));
+ if (defined == (boolean *) NULL || included == (boolean *) NULL)
+ goto error_return;
+ memset (defined, 0, c * sizeof (boolean));
+ memset (included, 0, c * sizeof (boolean));
+
+ symdefs = bfd_ardata (abfd)->symdefs;
+
+ do
+ {
+ file_ptr last;
+ symindex i;
+ carsym *symdef;
+ carsym *symdefend;
+
+ loop = false;
+ last = -1;
+
+ symdef = symdefs;
+ symdefend = symdef + c;
+ for (i = 0; symdef < symdefend; symdef++, i++)
+ {
+ struct elf_link_hash_entry *h;
+ bfd *element;
+ struct bfd_link_hash_entry *undefs_tail;
+ symindex mark;
+
+ if (defined[i] || included[i])
+ continue;
+ if (symdef->file_offset == last)
+ {
+ included[i] = true;
+ continue;
+ }
+
+ h = elf_link_hash_lookup (elf_hash_table (info), symdef->name,
+ false, false, false);
+
+ if (h == NULL)
+ {
+ char *p, *copy;
+
+ /* If this is a default version (the name contains @@),
+ look up the symbol again without the version. The
+ effect is that references to the symbol without the
+ version will be matched by the default symbol in the
+ archive. */
+
+ p = strchr (symdef->name, ELF_VER_CHR);
+ if (p == NULL || p[1] != ELF_VER_CHR)
+ continue;
+
+ copy = bfd_alloc (abfd, p - symdef->name + 1);
+ if (copy == NULL)
+ goto error_return;
+ memcpy (copy, symdef->name, p - symdef->name);
+ copy[p - symdef->name] = '\0';
+
+ h = elf_link_hash_lookup (elf_hash_table (info), copy,
+ false, false, false);
+
+ bfd_release (abfd, copy);
+ }
+
+ if (h == NULL)
+ continue;
+
+ if (h->root.type != bfd_link_hash_undefined)
+ {
+ if (h->root.type != bfd_link_hash_undefweak)
+ defined[i] = true;
+ continue;
+ }
+
+ /* We need to include this archive member. */
+
+ element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
+ if (element == (bfd *) NULL)
+ goto error_return;
+
+ if (! bfd_check_format (element, bfd_object))
+ goto error_return;
+
+ /* Doublecheck that we have not included this object
+ already--it should be impossible, but there may be
+ something wrong with the archive. */
+ if (element->archive_pass != 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ element->archive_pass = 1;
+
+ undefs_tail = info->hash->undefs_tail;
+
+ if (! (*info->callbacks->add_archive_element) (info, element,
+ symdef->name))
+ goto error_return;
+ if (! elf_link_add_object_symbols (element, info))
+ goto error_return;
+
+ /* If there are any new undefined symbols, we need to make
+ another pass through the archive in order to see whether
+ they can be defined. FIXME: This isn't perfect, because
+ common symbols wind up on undefs_tail and because an
+ undefined symbol which is defined later on in this pass
+ does not require another pass. This isn't a bug, but it
+ does make the code less efficient than it could be. */
+ if (undefs_tail != info->hash->undefs_tail)
+ loop = true;
+
+ /* Look backward to mark all symbols from this object file
+ which we have already seen in this pass. */
+ mark = i;
+ do
+ {
+ included[mark] = true;
+ if (mark == 0)
+ break;
+ --mark;
+ }
+ while (symdefs[mark].file_offset == symdef->file_offset);
+
+ /* We mark subsequent symbols from this object file as we go
+ on through the loop. */
+ last = symdef->file_offset;
+ }
+ }
+ while (loop);
+
+ free (defined);
+ free (included);
+
+ return true;
+
+ error_return:
+ if (defined != (boolean *) NULL)
+ free (defined);
+ if (included != (boolean *) NULL)
+ free (included);
+ return false;
+}
+
+/* This function is called when we want to define a new symbol. It
+ handles the various cases which arise when we find a definition in
+ a dynamic object, or when there is already a definition in a
+ dynamic object. The new symbol is described by NAME, SYM, PSEC,
+ and PVALUE. We set SYM_HASH to the hash table entry. We set
+ OVERRIDE if the old symbol is overriding a new definition. We set
+ TYPE_CHANGE_OK if it is OK for the type to change. We set
+ SIZE_CHANGE_OK if it is OK for the size to change. By OK to
+ change, we mean that we shouldn't warn if the type or size does
+ change. */
+
+static boolean
+elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
+ override, type_change_ok, size_change_ok)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const char *name;
+ Elf_Internal_Sym *sym;
+ asection **psec;
+ bfd_vma *pvalue;
+ struct elf_link_hash_entry **sym_hash;
+ boolean *override;
+ boolean *type_change_ok;
+ boolean *size_change_ok;
+{
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ int bind;
+ bfd *oldbfd;
+ boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
+
+ *override = false;
+
+ sec = *psec;
+ bind = ELF_ST_BIND (sym->st_info);
+
+ if (! bfd_is_und_section (sec))
+ h = elf_link_hash_lookup (elf_hash_table (info), name, true, false, false);
+ else
+ h = ((struct elf_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (abfd, info, name, true, false, false));
+ if (h == NULL)
+ return false;
+ *sym_hash = h;
+
+ /* This code is for coping with dynamic objects, and is only useful
+ if we are doing an ELF link. */
+ if (info->hash->creator != abfd->xvec)
+ return true;
+
+ /* For merging, we only care about real symbols. */
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* If we just created the symbol, mark it as being an ELF symbol.
+ Other than that, there is nothing to do--there is no merge issue
+ with a newly defined symbol--so we just return. */
+
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+ return true;
+ }
+
+ /* OLDBFD is a BFD associated with the existing symbol. */
+
+ switch (h->root.type)
+ {
+ default:
+ oldbfd = NULL;
+ break;
+
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ oldbfd = h->root.u.undef.abfd;
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ oldbfd = h->root.u.def.section->owner;
+ break;
+
+ case bfd_link_hash_common:
+ oldbfd = h->root.u.c.p->section->owner;
+ break;
+ }
+
+ /* NEWDYN and OLDDYN indicate whether the new or old symbol,
+ respectively, is from a dynamic object. */
+
+ if ((abfd->flags & DYNAMIC) != 0)
+ newdyn = true;
+ else
+ newdyn = false;
+
+ if (oldbfd == NULL || (oldbfd->flags & DYNAMIC) == 0)
+ olddyn = false;
+ else
+ olddyn = true;
+
+ /* NEWDEF and OLDDEF indicate whether the new or old symbol,
+ respectively, appear to be a definition rather than reference. */
+
+ if (bfd_is_und_section (sec) || bfd_is_com_section (sec))
+ newdef = false;
+ else
+ newdef = true;
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_common)
+ olddef = false;
+ else
+ olddef = true;
+
+ /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
+ symbol, respectively, appears to be a common symbol in a dynamic
+ object. If a symbol appears in an uninitialized section, and is
+ not weak, and is not a function, then it may be a common symbol
+ which was resolved when the dynamic object was created. We want
+ to treat such symbols specially, because they raise special
+ considerations when setting the symbol size: if the symbol
+ appears as a common symbol in a regular object, and the size in
+ the regular object is larger, we must make sure that we use the
+ larger size. This problematic case can always be avoided in C,
+ but it must be handled correctly when using Fortran shared
+ libraries.
+
+ Note that if NEWDYNCOMMON is set, NEWDEF will be set, and
+ likewise for OLDDYNCOMMON and OLDDEF.
+
+ Note that this test is just a heuristic, and that it is quite
+ possible to have an uninitialized symbol in a shared object which
+ is really a definition, rather than a common symbol. This could
+ lead to some minor confusion when the symbol really is a common
+ symbol in some regular object. However, I think it will be
+ harmless. */
+
+ if (newdyn
+ && newdef
+ && (sec->flags & SEC_ALLOC) != 0
+ && (sec->flags & SEC_LOAD) == 0
+ && sym->st_size > 0
+ && bind != STB_WEAK
+ && ELF_ST_TYPE (sym->st_info) != STT_FUNC)
+ newdyncommon = true;
+ else
+ newdyncommon = false;
+
+ if (olddyn
+ && olddef
+ && h->root.type == bfd_link_hash_defined
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->root.u.def.section->flags & SEC_ALLOC) != 0
+ && (h->root.u.def.section->flags & SEC_LOAD) == 0
+ && h->size > 0
+ && h->type != STT_FUNC)
+ olddyncommon = true;
+ else
+ olddyncommon = false;
+
+ /* It's OK to change the type if either the existing symbol or the
+ new symbol is weak. */
+
+ if (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak
+ || bind == STB_WEAK)
+ *type_change_ok = true;
+
+ /* It's OK to change the size if either the existing symbol or the
+ new symbol is weak, or if the old symbol is undefined. */
+
+ if (*type_change_ok
+ || h->root.type == bfd_link_hash_undefined)
+ *size_change_ok = true;
+
+ /* If both the old and the new symbols look like common symbols in a
+ dynamic object, set the size of the symbol to the larger of the
+ two. */
+
+ if (olddyncommon
+ && newdyncommon
+ && sym->st_size != h->size)
+ {
+ /* Since we think we have two common symbols, issue a multiple
+ common warning if desired. Note that we only warn if the
+ size is different. If the size is the same, we simply let
+ the old symbol override the new one as normally happens with
+ symbols defined in dynamic objects. */
+
+ if (! ((*info->callbacks->multiple_common)
+ (info, h->root.root.string, oldbfd, bfd_link_hash_common,
+ h->size, abfd, bfd_link_hash_common, sym->st_size)))
+ return false;
+
+ if (sym->st_size > h->size)
+ h->size = sym->st_size;
+
+ *size_change_ok = true;
+ }
+
+ /* If we are looking at a dynamic object, and we have found a
+ definition, we need to see if the symbol was already defined by
+ some other object. If so, we want to use the existing
+ definition, and we do not want to report a multiple symbol
+ definition error; we do this by clobbering *PSEC to be
+ bfd_und_section_ptr.
+
+ We treat a common symbol as a definition if the symbol in the
+ shared library is a function, since common symbols always
+ represent variables; this can cause confusion in principle, but
+ any such confusion would seem to indicate an erroneous program or
+ shared library. We also permit a common symbol in a regular
+ object to override a weak symbol in a shared object. */
+
+ if (newdyn
+ && newdef
+ && (olddef
+ || (h->root.type == bfd_link_hash_common
+ && (bind == STB_WEAK
+ || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
+ {
+ *override = true;
+ newdef = false;
+ newdyncommon = false;
+
+ *psec = sec = bfd_und_section_ptr;
+ *size_change_ok = true;
+
+ /* If we get here when the old symbol is a common symbol, then
+ we are explicitly letting it override a weak symbol or
+ function in a dynamic object, and we don't want to warn about
+ a type change. If the old symbol is a defined symbol, a type
+ change warning may still be appropriate. */
+
+ if (h->root.type == bfd_link_hash_common)
+ *type_change_ok = true;
+ }
+
+ /* Handle the special case of an old common symbol merging with a
+ new symbol which looks like a common symbol in a shared object.
+ We change *PSEC and *PVALUE to make the new symbol look like a
+ common symbol, and let _bfd_generic_link_add_one_symbol will do
+ the right thing. */
+
+ if (newdyncommon
+ && h->root.type == bfd_link_hash_common)
+ {
+ *override = true;
+ newdef = false;
+ newdyncommon = false;
+ *pvalue = sym->st_size;
+ *psec = sec = bfd_com_section_ptr;
+ *size_change_ok = true;
+ }
+
+ /* If the old symbol is from a dynamic object, and the new symbol is
+ a definition which is not from a dynamic object, then the new
+ symbol overrides the old symbol. Symbols from regular files
+ always take precedence over symbols from dynamic objects, even if
+ they are defined after the dynamic object in the link.
+
+ As above, we again permit a common symbol in a regular object to
+ override a definition in a shared object if the shared object
+ symbol is a function or is weak. */
+
+ if (! newdyn
+ && (newdef
+ || (bfd_is_com_section (sec)
+ && (h->root.type == bfd_link_hash_defweak
+ || h->type == STT_FUNC)))
+ && olddyn
+ && olddef
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
+ {
+ /* Change the hash table entry to undefined, and let
+ _bfd_generic_link_add_one_symbol do the right thing with the
+ new definition. */
+
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = h->root.u.def.section->owner;
+ *size_change_ok = true;
+
+ olddef = false;
+ olddyncommon = false;
+
+ /* We again permit a type change when a common symbol may be
+ overriding a function. */
+
+ if (bfd_is_com_section (sec))
+ *type_change_ok = true;
+
+ /* This union may have been set to be non-NULL when this symbol
+ was seen in a dynamic object. We must force the union to be
+ NULL, so that it is correct for a regular symbol. */
+
+ h->verinfo.vertree = NULL;
+
+ /* In this special case, if H is the target of an indirection,
+ we want the caller to frob with H rather than with the
+ indirect symbol. That will permit the caller to redefine the
+ target of the indirection, rather than the indirect symbol
+ itself. FIXME: This will break the -y option if we store a
+ symbol with a different name. */
+ *sym_hash = h;
+ }
+
+ /* Handle the special case of a new common symbol merging with an
+ old symbol that looks like it might be a common symbol defined in
+ a shared object. Note that we have already handled the case in
+ which a new common symbol should simply override the definition
+ in the shared library. */
+
+ if (! newdyn
+ && bfd_is_com_section (sec)
+ && olddyncommon)
+ {
+ /* It would be best if we could set the hash table entry to a
+ common symbol, but we don't know what to use for the section
+ or the alignment. */
+ if (! ((*info->callbacks->multiple_common)
+ (info, h->root.root.string, oldbfd, bfd_link_hash_common,
+ h->size, abfd, bfd_link_hash_common, sym->st_size)))
+ return false;
+
+ /* If the predumed common symbol in the dynamic object is
+ larger, pretend that the new symbol has its size. */
+
+ if (h->size > *pvalue)
+ *pvalue = h->size;
+
+ /* FIXME: We no longer know the alignment required by the symbol
+ in the dynamic object, so we just wind up using the one from
+ the regular object. */
+
+ olddef = false;
+ olddyncommon = false;
+
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = h->root.u.def.section->owner;
+
+ *size_change_ok = true;
+ *type_change_ok = true;
+
+ h->verinfo.vertree = NULL;
+ }
+
+ return true;
+}
+
+/* Add symbols from an ELF object file to the linker hash table. */
+
+static boolean
+elf_link_add_object_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ boolean (*add_symbol_hook) PARAMS ((bfd *, struct bfd_link_info *,
+ const Elf_Internal_Sym *,
+ const char **, flagword *,
+ asection **, bfd_vma *));
+ boolean (*check_relocs) PARAMS ((bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *));
+ boolean collect;
+ Elf_Internal_Shdr *hdr;
+ size_t symcount;
+ size_t extsymcount;
+ size_t extsymoff;
+ Elf_External_Sym *buf = NULL;
+ struct elf_link_hash_entry **sym_hash;
+ boolean dynamic;
+ bfd_byte *dynver = NULL;
+ Elf_External_Versym *extversym = NULL;
+ Elf_External_Versym *ever;
+ Elf_External_Dyn *dynbuf = NULL;
+ struct elf_link_hash_entry *weaks;
+ Elf_External_Sym *esym;
+ Elf_External_Sym *esymend;
+
+ add_symbol_hook = get_elf_backend_data (abfd)->elf_add_symbol_hook;
+ collect = get_elf_backend_data (abfd)->collect;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ dynamic = false;
+ else
+ {
+ dynamic = true;
+
+ /* You can't use -r against a dynamic object. Also, there's no
+ hope of using a dynamic object which does not exactly match
+ the format of the output file. */
+ if (info->relocateable || info->hash->creator != abfd->xvec)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+ }
+
+ /* As a GNU extension, any input sections which are named
+ .gnu.warning.SYMBOL are treated as warning symbols for the given
+ symbol. This differs from .gnu.warning sections, which generate
+ warnings when they are included in an output file. */
+ if (! info->shared)
+ {
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ name = bfd_get_section_name (abfd, s);
+ if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0)
+ {
+ char *msg;
+ bfd_size_type sz;
+
+ name += sizeof ".gnu.warning." - 1;
+
+ /* If this is a shared object, then look up the symbol
+ in the hash table. If it is there, and it is already
+ been defined, then we will not be using the entry
+ from this shared object, so we don't need to warn.
+ FIXME: If we see the definition in a regular object
+ later on, we will warn, but we shouldn't. The only
+ fix is to keep track of what warnings we are supposed
+ to emit, and then handle them all at the end of the
+ link. */
+ if (dynamic && abfd->xvec == info->hash->creator)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name,
+ false, false, true);
+
+ /* FIXME: What about bfd_link_hash_common? */
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ /* We don't want to issue this warning. Clobber
+ the section size so that the warning does not
+ get copied into the output file. */
+ s->_raw_size = 0;
+ continue;
+ }
+ }
+
+ sz = bfd_section_size (abfd, s);
+ msg = (char *) bfd_alloc (abfd, sz + 1);
+ if (msg == NULL)
+ goto error_return;
+
+ if (! bfd_get_section_contents (abfd, s, msg, (file_ptr) 0, sz))
+ goto error_return;
+
+ msg[sz] = '\0';
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_WARNING, s, (bfd_vma) 0, msg,
+ false, collect, (struct bfd_link_hash_entry **) NULL)))
+ goto error_return;
+
+ if (! info->relocateable)
+ {
+ /* Clobber the section size so that the warning does
+ not get copied into the output file. */
+ s->_raw_size = 0;
+ }
+ }
+ }
+ }
+
+ /* If this is a dynamic object, we always link against the .dynsym
+ symbol table, not the .symtab symbol table. The dynamic linker
+ will only see the .dynsym symbol table, so there is no reason to
+ look at .symtab for a dynamic object. */
+
+ if (! dynamic || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ if (dynamic)
+ {
+ /* Read in any version definitions. */
+
+ if (! _bfd_elf_slurp_version_tables (abfd))
+ goto error_return;
+
+ /* Read in the symbol versions, but don't bother to convert them
+ to internal format. */
+ if (elf_dynversym (abfd) != 0)
+ {
+ Elf_Internal_Shdr *versymhdr;
+
+ versymhdr = &elf_tdata (abfd)->dynversym_hdr;
+ extversym = (Elf_External_Versym *) bfd_malloc (hdr->sh_size);
+ if (extversym == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read ((PTR) extversym, 1, versymhdr->sh_size, abfd)
+ != versymhdr->sh_size))
+ goto error_return;
+ }
+ }
+
+ symcount = hdr->sh_size / sizeof (Elf_External_Sym);
+
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local symbols at
+ this point. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
+
+ buf = ((Elf_External_Sym *)
+ bfd_malloc (extsymcount * sizeof (Elf_External_Sym)));
+ if (buf == NULL && extsymcount != 0)
+ goto error_return;
+
+ /* We store a pointer to the hash table entry for each external
+ symbol. */
+ sym_hash = ((struct elf_link_hash_entry **)
+ bfd_alloc (abfd,
+ extsymcount * sizeof (struct elf_link_hash_entry *)));
+ if (sym_hash == NULL)
+ goto error_return;
+ elf_sym_hashes (abfd) = sym_hash;
+
+ if (! dynamic)
+ {
+ /* If we are creating a shared library, create all the dynamic
+ sections immediately. We need to attach them to something,
+ so we attach them to this BFD, provided it is the right
+ format. FIXME: If there are no input BFD's of the same
+ format as the output, we can't make a shared library. */
+ if (info->shared
+ && ! elf_hash_table (info)->dynamic_sections_created
+ && abfd->xvec == info->hash->creator)
+ {
+ if (! elf_link_create_dynamic_sections (abfd, info))
+ goto error_return;
+ }
+ }
+ else
+ {
+ asection *s;
+ boolean add_needed;
+ const char *name;
+ bfd_size_type oldsize;
+ bfd_size_type strindex;
+
+ /* Find the name to use in a DT_NEEDED entry that refers to this
+ object. If the object has a DT_SONAME entry, we use it.
+ Otherwise, if the generic linker stuck something in
+ elf_dt_name, we use that. Otherwise, we just use the file
+ name. If the generic linker put a null string into
+ elf_dt_name, we don't make a DT_NEEDED entry at all, even if
+ there is a DT_SONAME entry. */
+ add_needed = true;
+ name = bfd_get_filename (abfd);
+ if (elf_dt_name (abfd) != NULL)
+ {
+ name = elf_dt_name (abfd);
+ if (*name == '\0')
+ add_needed = false;
+ }
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ Elf_External_Dyn *extdyn;
+ Elf_External_Dyn *extdynend;
+ int elfsec;
+ unsigned long link;
+
+ dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size);
+ if (dynbuf == NULL)
+ goto error_return;
+
+ if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf,
+ (file_ptr) 0, s->_raw_size))
+ goto error_return;
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == -1)
+ goto error_return;
+ link = elf_elfsections (abfd)[elfsec]->sh_link;
+
+ extdyn = dynbuf;
+ extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn);
+ for (; extdyn < extdynend; extdyn++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ elf_swap_dyn_in (abfd, extdyn, &dyn);
+ if (dyn.d_tag == DT_SONAME)
+ {
+ name = bfd_elf_string_from_elf_section (abfd, link,
+ dyn.d_un.d_val);
+ if (name == NULL)
+ goto error_return;
+ }
+ if (dyn.d_tag == DT_NEEDED)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+
+ n = ((struct bfd_link_needed_list *)
+ bfd_alloc (abfd, sizeof (struct bfd_link_needed_list)));
+ fnm = bfd_elf_string_from_elf_section (abfd, link,
+ dyn.d_un.d_val);
+ if (n == NULL || fnm == NULL)
+ goto error_return;
+ anm = bfd_alloc (abfd, strlen (fnm) + 1);
+ if (anm == NULL)
+ goto error_return;
+ strcpy (anm, fnm);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = &elf_hash_table (info)->needed;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ }
+
+ free (dynbuf);
+ dynbuf = NULL;
+ }
+
+ /* We do not want to include any of the sections in a dynamic
+ object in the output file. We hack by simply clobbering the
+ list of sections in the BFD. This could be handled more
+ cleanly by, say, a new section flag; the existing
+ SEC_NEVER_LOAD flag is not the one we want, because that one
+ still implies that the section takes up space in the output
+ file. */
+ abfd->sections = NULL;
+ abfd->section_count = 0;
+
+ /* If this is the first dynamic object found in the link, create
+ the special sections required for dynamic linking. */
+ if (! elf_hash_table (info)->dynamic_sections_created)
+ {
+ if (! elf_link_create_dynamic_sections (abfd, info))
+ goto error_return;
+ }
+
+ if (add_needed)
+ {
+ /* Add a DT_NEEDED entry for this dynamic object. */
+ oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+ strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, name,
+ true, false);
+ if (strindex == (bfd_size_type) -1)
+ goto error_return;
+
+ if (oldsize == _bfd_stringtab_size (elf_hash_table (info)->dynstr))
+ {
+ asection *sdyn;
+ Elf_External_Dyn *dyncon, *dynconend;
+
+ /* The hash table size did not change, which means that
+ the dynamic object name was already entered. If we
+ have already included this dynamic object in the
+ link, just ignore it. There is no reason to include
+ a particular dynamic object more than once. */
+ sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
+ ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf_External_Dyn *) sdyn->contents;
+ dynconend = (Elf_External_Dyn *) (sdyn->contents +
+ sdyn->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ elf_swap_dyn_in (elf_hash_table (info)->dynobj, dyncon,
+ &dyn);
+ if (dyn.d_tag == DT_NEEDED
+ && dyn.d_un.d_val == strindex)
+ {
+ if (buf != NULL)
+ free (buf);
+ if (extversym != NULL)
+ free (extversym);
+ return true;
+ }
+ }
+ }
+
+ if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+ goto error_return;
+ }
+
+ /* Save the SONAME, if there is one, because sometimes the
+ linker emulation code will need to know it. */
+ if (*name == '\0')
+ name = bfd_get_filename (abfd);
+ elf_dt_name (abfd) = name;
+ }
+
+ if (bfd_seek (abfd,
+ hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym),
+ SEEK_SET) != 0
+ || (bfd_read ((PTR) buf, sizeof (Elf_External_Sym), extsymcount, abfd)
+ != extsymcount * sizeof (Elf_External_Sym)))
+ goto error_return;
+
+ weaks = NULL;
+
+ ever = extversym != NULL ? extversym + extsymoff : NULL;
+ esymend = buf + extsymcount;
+ for (esym = buf;
+ esym < esymend;
+ esym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
+ {
+ Elf_Internal_Sym sym;
+ int bind;
+ bfd_vma value;
+ asection *sec;
+ flagword flags;
+ const char *name;
+ struct elf_link_hash_entry *h;
+ boolean definition;
+ boolean size_change_ok, type_change_ok;
+ boolean new_weakdef;
+ unsigned int old_alignment;
+
+ elf_swap_symbol_in (abfd, esym, &sym);
+
+ flags = BSF_NO_FLAGS;
+ sec = NULL;
+ value = sym.st_value;
+ *sym_hash = NULL;
+
+ bind = ELF_ST_BIND (sym.st_info);
+ if (bind == STB_LOCAL)
+ {
+ /* This should be impossible, since ELF requires that all
+ global symbols follow all local symbols, and that sh_info
+ point to the first global symbol. Unfortunatealy, Irix 5
+ screws this up. */
+ continue;
+ }
+ else if (bind == STB_GLOBAL)
+ {
+ if (sym.st_shndx != SHN_UNDEF
+ && sym.st_shndx != SHN_COMMON)
+ flags = BSF_GLOBAL;
+ else
+ flags = 0;
+ }
+ else if (bind == STB_WEAK)
+ flags = BSF_WEAK;
+ else
+ {
+ /* Leave it up to the processor backend. */
+ }
+
+ if (sym.st_shndx == SHN_UNDEF)
+ sec = bfd_und_section_ptr;
+ else if (sym.st_shndx > 0 && sym.st_shndx < SHN_LORESERVE)
+ {
+ sec = section_from_elf_index (abfd, sym.st_shndx);
+ if (sec == NULL)
+ sec = bfd_abs_section_ptr;
+ else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ value -= sec->vma;
+ }
+ else if (sym.st_shndx == SHN_ABS)
+ sec = bfd_abs_section_ptr;
+ else if (sym.st_shndx == SHN_COMMON)
+ {
+ sec = bfd_com_section_ptr;
+ /* What ELF calls the size we call the value. What ELF
+ calls the value we call the alignment. */
+ value = sym.st_size;
+ }
+ else
+ {
+ /* Leave it up to the processor backend. */
+ }
+
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, sym.st_name);
+ if (name == (const char *) NULL)
+ goto error_return;
+
+ if (add_symbol_hook)
+ {
+ if (! (*add_symbol_hook) (abfd, info, &sym, &name, &flags, &sec,
+ &value))
+ goto error_return;
+
+ /* The hook function sets the name to NULL if this symbol
+ should be skipped for some reason. */
+ if (name == (const char *) NULL)
+ continue;
+ }
+
+ /* Sanity check that all possibilities were handled. */
+ if (sec == (asection *) NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (bfd_is_und_section (sec)
+ || bfd_is_com_section (sec))
+ definition = false;
+ else
+ definition = true;
+
+ size_change_ok = false;
+ type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
+ old_alignment = 0;
+ if (info->hash->creator->flavour == bfd_target_elf_flavour)
+ {
+ Elf_Internal_Versym iver;
+ unsigned int vernum = 0;
+ boolean override;
+
+ if (ever != NULL)
+ {
+ _bfd_elf_swap_versym_in (abfd, ever, &iver);
+ vernum = iver.vs_vers & VERSYM_VERSION;
+
+ /* If this is a hidden symbol, or if it is not version
+ 1, we append the version name to the symbol name.
+ However, we do not modify a non-hidden absolute
+ symbol, because it might be the version symbol
+ itself. FIXME: What if it isn't? */
+ if ((iver.vs_vers & VERSYM_HIDDEN) != 0
+ || (vernum > 1 && ! bfd_is_abs_section (sec)))
+ {
+ const char *verstr;
+ int namelen, newlen;
+ char *newname, *p;
+
+ if (sym.st_shndx != SHN_UNDEF)
+ {
+ if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s: invalid version %u (max %d)"),
+ bfd_get_filename (abfd), name, vernum,
+ elf_tdata (abfd)->dynverdef_hdr.sh_info);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ else if (vernum > 1)
+ verstr =
+ elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+ else
+ verstr = "";
+ }
+ else
+ {
+ /* We cannot simply test for the number of
+ entries in the VERNEED section since the
+ numbers for the needed versions do not start
+ at 0. */
+ Elf_Internal_Verneed *t;
+
+ verstr = NULL;
+ for (t = elf_tdata (abfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ Elf_Internal_Vernaux *a;
+
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ {
+ if (a->vna_other == vernum)
+ {
+ verstr = a->vna_nodename;
+ break;
+ }
+ }
+ if (a != NULL)
+ break;
+ }
+ if (verstr == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s: invalid needed version %d"),
+ bfd_get_filename (abfd), name, vernum);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ }
+
+ namelen = strlen (name);
+ newlen = namelen + strlen (verstr) + 2;
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0)
+ ++newlen;
+
+ newname = (char *) bfd_alloc (abfd, newlen);
+ if (newname == NULL)
+ goto error_return;
+ strcpy (newname, name);
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0)
+ *p++ = ELF_VER_CHR;
+ strcpy (p, verstr);
+
+ name = newname;
+ }
+ }
+
+ if (! elf_merge_symbol (abfd, info, name, &sym, &sec, &value,
+ sym_hash, &override, &type_change_ok,
+ &size_change_ok))
+ goto error_return;
+
+ if (override)
+ definition = false;
+
+ h = *sym_hash;
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* Remember the old alignment if this is a common symbol, so
+ that we don't reduce the alignment later on. We can't
+ check later, because _bfd_generic_link_add_one_symbol
+ will set a default for the alignment which we want to
+ override. */
+ if (h->root.type == bfd_link_hash_common)
+ old_alignment = h->root.u.c.p->alignment_power;
+
+ if (elf_tdata (abfd)->verdef != NULL
+ && ! override
+ && vernum > 1
+ && definition)
+ h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1];
+ }
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, flags, sec, value, (const char *) NULL,
+ false, collect, (struct bfd_link_hash_entry **) sym_hash)))
+ goto error_return;
+
+ h = *sym_hash;
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ *sym_hash = h;
+
+ new_weakdef = false;
+ if (dynamic
+ && definition
+ && (flags & BSF_WEAK) != 0
+ && ELF_ST_TYPE (sym.st_info) != STT_FUNC
+ && info->hash->creator->flavour == bfd_target_elf_flavour
+ && h->weakdef == NULL)
+ {
+ /* Keep a list of all weak defined non function symbols from
+ a dynamic object, using the weakdef field. Later in this
+ function we will set the weakdef field to the correct
+ value. We only put non-function symbols from dynamic
+ objects on this list, because that happens to be the only
+ time we need to know the normal symbol corresponding to a
+ weak symbol, and the information is time consuming to
+ figure out. If the weakdef field is not already NULL,
+ then this symbol was already defined by some previous
+ dynamic object, and we will be using that previous
+ definition anyhow. */
+
+ h->weakdef = weaks;
+ weaks = h;
+ new_weakdef = true;
+ }
+
+ /* Set the alignment of a common symbol. */
+ if (sym.st_shndx == SHN_COMMON
+ && h->root.type == bfd_link_hash_common)
+ {
+ unsigned int align;
+
+ align = bfd_log2 (sym.st_value);
+ if (align > old_alignment)
+ h->root.u.c.p->alignment_power = align;
+ }
+
+ if (info->hash->creator->flavour == bfd_target_elf_flavour)
+ {
+ int old_flags;
+ boolean dynsym;
+ int new_flag;
+
+ /* Remember the symbol size and type. */
+ if (sym.st_size != 0
+ && (definition || h->size == 0))
+ {
+ if (h->size != 0 && h->size != sym.st_size && ! size_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: size of symbol `%s' changed from %lu to %lu in %s"),
+ name, (unsigned long) h->size, (unsigned long) sym.st_size,
+ bfd_get_filename (abfd));
+
+ h->size = sym.st_size;
+ }
+
+ /* If this is a common symbol, then we always want H->SIZE
+ to be the size of the common symbol. The code just above
+ won't fix the size if a common symbol becomes larger. We
+ don't warn about a size change here, because that is
+ covered by --warn-common. */
+ if (h->root.type == bfd_link_hash_common)
+ h->size = h->root.u.c.size;
+
+ if (ELF_ST_TYPE (sym.st_info) != STT_NOTYPE
+ && (definition || h->type == STT_NOTYPE))
+ {
+ if (h->type != STT_NOTYPE
+ && h->type != ELF_ST_TYPE (sym.st_info)
+ && ! type_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
+ name, h->type, ELF_ST_TYPE (sym.st_info),
+ bfd_get_filename (abfd));
+
+ h->type = ELF_ST_TYPE (sym.st_info);
+ }
+
+ if (sym.st_other != 0
+ && (definition || h->other == 0))
+ h->other = sym.st_other;
+
+ /* Set a flag in the hash table entry indicating the type of
+ reference or definition we just found. Keep a count of
+ the number of dynamic symbols we find. A dynamic symbol
+ is one which is referenced or defined by both a regular
+ object and a shared object. */
+ old_flags = h->elf_link_hash_flags;
+ dynsym = false;
+ if (! dynamic)
+ {
+ if (! definition)
+ {
+ new_flag = ELF_LINK_HASH_REF_REGULAR;
+ if (bind != STB_WEAK)
+ new_flag |= ELF_LINK_HASH_REF_REGULAR_NONWEAK;
+ }
+ else
+ new_flag = ELF_LINK_HASH_DEF_REGULAR;
+ if (info->shared
+ || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_REF_DYNAMIC)) != 0)
+ dynsym = true;
+ }
+ else
+ {
+ if (! definition)
+ new_flag = ELF_LINK_HASH_REF_DYNAMIC;
+ else
+ new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
+ if ((old_flags & (ELF_LINK_HASH_DEF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR)) != 0
+ || (h->weakdef != NULL
+ && ! new_weakdef
+ && h->weakdef->dynindx != -1))
+ dynsym = true;
+ }
+
+ h->elf_link_hash_flags |= new_flag;
+
+ /* If this symbol has a version, and it is the default
+ version, we create an indirect symbol from the default
+ name to the fully decorated name. This will cause
+ external references which do not specify a version to be
+ bound to this version of the symbol. */
+ if (definition)
+ {
+ char *p;
+
+ p = strchr (name, ELF_VER_CHR);
+ if (p != NULL && p[1] == ELF_VER_CHR)
+ {
+ char *shortname;
+ struct elf_link_hash_entry *hi;
+ boolean override;
+
+ shortname = bfd_hash_allocate (&info->hash->table,
+ p - name + 1);
+ if (shortname == NULL)
+ goto error_return;
+ strncpy (shortname, name, p - name);
+ shortname[p - name] = '\0';
+
+ /* We are going to create a new symbol. Merge it
+ with any existing symbol with this name. For the
+ purposes of the merge, act as though we were
+ defining the symbol we just defined, although we
+ actually going to define an indirect symbol. */
+ type_change_ok = false;
+ size_change_ok = false;
+ if (! elf_merge_symbol (abfd, info, shortname, &sym, &sec,
+ &value, &hi, &override,
+ &type_change_ok, &size_change_ok))
+ goto error_return;
+
+ if (! override)
+ {
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, shortname, BSF_INDIRECT,
+ bfd_ind_section_ptr, (bfd_vma) 0, name, false,
+ collect, (struct bfd_link_hash_entry **) &hi)))
+ goto error_return;
+ }
+ else
+ {
+ /* In this case the symbol named SHORTNAME is
+ overriding the indirect symbol we want to
+ add. We were planning on making SHORTNAME an
+ indirect symbol referring to NAME. SHORTNAME
+ is the name without a version. NAME is the
+ fully versioned name, and it is the default
+ version.
+
+ Overriding means that we already saw a
+ definition for the symbol SHORTNAME in a
+ regular object, and it is overriding the
+ symbol defined in the dynamic object.
+
+ When this happens, we actually want to change
+ NAME, the symbol we just added, to refer to
+ SHORTNAME. This will cause references to
+ NAME in the shared object to become
+ references to SHORTNAME in the regular
+ object. This is what we expect when we
+ override a function in a shared object: that
+ the references in the shared object will be
+ mapped to the definition in the regular
+ object. */
+
+ while (hi->root.type == bfd_link_hash_indirect
+ || hi->root.type == bfd_link_hash_warning)
+ hi = (struct elf_link_hash_entry *) hi->root.u.i.link;
+
+ h->root.type = bfd_link_hash_indirect;
+ h->root.u.i.link = (struct bfd_link_hash_entry *) hi;
+ if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
+ {
+ h->elf_link_hash_flags &=~ ELF_LINK_HASH_DEF_DYNAMIC;
+ hi->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ if (hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_DEF_REGULAR))
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info,
+ hi))
+ goto error_return;
+ }
+ }
+
+ /* Now set HI to H, so that the following code
+ will set the other fields correctly. */
+ hi = h;
+ }
+
+ /* If there is a duplicate definition somewhere,
+ then HI may not point to an indirect symbol. We
+ will have reported an error to the user in that
+ case. */
+
+ if (hi->root.type == bfd_link_hash_indirect)
+ {
+ struct elf_link_hash_entry *ht;
+
+ /* If the symbol became indirect, then we assume
+ that we have not seen a definition before. */
+ BFD_ASSERT ((hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_DEF_REGULAR))
+ == 0);
+
+ ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
+
+ /* Copy down any references that we may have
+ already seen to the symbol which just became
+ indirect. */
+ ht->elf_link_hash_flags |=
+ (hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+
+ /* Copy over the global and procedure linkage table
+ offset entries. These may have been already set
+ up by a check_relocs routine. */
+ if (ht->got.offset == (bfd_vma) -1)
+ {
+ ht->got.offset = hi->got.offset;
+ hi->got.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+
+ if (ht->plt.offset == (bfd_vma) -1)
+ {
+ ht->plt.offset = hi->plt.offset;
+ hi->plt.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->plt.offset == (bfd_vma) -1);
+
+ if (ht->dynindx == -1)
+ {
+ ht->dynindx = hi->dynindx;
+ ht->dynstr_index = hi->dynstr_index;
+ hi->dynindx = -1;
+ hi->dynstr_index = 0;
+ }
+ BFD_ASSERT (hi->dynindx == -1);
+
+ /* FIXME: There may be other information to copy
+ over for particular targets. */
+
+ /* See if the new flags lead us to realize that
+ the symbol must be dynamic. */
+ if (! dynsym)
+ {
+ if (! dynamic)
+ {
+ if (info->shared
+ || ((hi->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_DYNAMIC)
+ != 0))
+ dynsym = true;
+ }
+ else
+ {
+ if ((hi->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0)
+ dynsym = true;
+ }
+ }
+ }
+
+ /* We also need to define an indirection from the
+ nondefault version of the symbol. */
+
+ shortname = bfd_hash_allocate (&info->hash->table,
+ strlen (name));
+ if (shortname == NULL)
+ goto error_return;
+ strncpy (shortname, name, p - name);
+ strcpy (shortname + (p - name), p + 1);
+
+ /* Once again, merge with any existing symbol. */
+ type_change_ok = false;
+ size_change_ok = false;
+ if (! elf_merge_symbol (abfd, info, shortname, &sym, &sec,
+ &value, &hi, &override,
+ &type_change_ok, &size_change_ok))
+ goto error_return;
+
+ if (override)
+ {
+ /* Here SHORTNAME is a versioned name, so we
+ don't expect to see the type of override we
+ do in the case above. */
+ (*_bfd_error_handler)
+ (_("%s: warning: unexpected redefinition of `%s'"),
+ bfd_get_filename (abfd), shortname);
+ }
+ else
+ {
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, shortname, BSF_INDIRECT,
+ bfd_ind_section_ptr, (bfd_vma) 0, name, false,
+ collect, (struct bfd_link_hash_entry **) &hi)))
+ goto error_return;
+
+ /* If there is a duplicate definition somewhere,
+ then HI may not point to an indirect symbol.
+ We will have reported an error to the user in
+ that case. */
+
+ if (hi->root.type == bfd_link_hash_indirect)
+ {
+ /* If the symbol became indirect, then we
+ assume that we have not seen a definition
+ before. */
+ BFD_ASSERT ((hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_DEF_REGULAR))
+ == 0);
+
+ /* Copy down any references that we may have
+ already seen to the symbol which just
+ became indirect. */
+ h->elf_link_hash_flags |=
+ (hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+
+ /* Copy over the global and procedure linkage
+ table offset entries. These may have been
+ already set up by a check_relocs routine. */
+ if (h->got.offset == (bfd_vma) -1)
+ {
+ h->got.offset = hi->got.offset;
+ hi->got.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+
+ if (h->plt.offset == (bfd_vma) -1)
+ {
+ h->plt.offset = hi->plt.offset;
+ hi->plt.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+
+ if (h->dynindx == -1)
+ {
+ h->dynindx = hi->dynindx;
+ h->dynstr_index = hi->dynstr_index;
+ hi->dynindx = -1;
+ hi->dynstr_index = 0;
+ }
+ BFD_ASSERT (hi->dynindx == -1);
+
+ /* FIXME: There may be other information to
+ copy over for particular targets. */
+
+ /* See if the new flags lead us to realize
+ that the symbol must be dynamic. */
+ if (! dynsym)
+ {
+ if (! dynamic)
+ {
+ if (info->shared
+ || ((hi->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_DYNAMIC)
+ != 0))
+ dynsym = true;
+ }
+ else
+ {
+ if ((hi->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0)
+ dynsym = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (dynsym && h->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+ goto error_return;
+ if (h->weakdef != NULL
+ && ! new_weakdef
+ && h->weakdef->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info,
+ h->weakdef))
+ goto error_return;
+ }
+ }
+ }
+ }
+
+ /* Now set the weakdefs field correctly for all the weak defined
+ symbols we found. The only way to do this is to search all the
+ symbols. Since we only need the information for non functions in
+ dynamic objects, that's the only time we actually put anything on
+ the list WEAKS. We need this information so that if a regular
+ object refers to a symbol defined weakly in a dynamic object, the
+ real symbol in the dynamic object is also put in the dynamic
+ symbols; we also must arrange for both symbols to point to the
+ same memory location. We could handle the general case of symbol
+ aliasing, but a general symbol alias can only be generated in
+ assembler code, handling it correctly would be very time
+ consuming, and other ELF linkers don't handle general aliasing
+ either. */
+ while (weaks != NULL)
+ {
+ struct elf_link_hash_entry *hlook;
+ asection *slook;
+ bfd_vma vlook;
+ struct elf_link_hash_entry **hpp;
+ struct elf_link_hash_entry **hppend;
+
+ hlook = weaks;
+ weaks = hlook->weakdef;
+ hlook->weakdef = NULL;
+
+ BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
+ || hlook->root.type == bfd_link_hash_defweak
+ || hlook->root.type == bfd_link_hash_common
+ || hlook->root.type == bfd_link_hash_indirect);
+ slook = hlook->root.u.def.section;
+ vlook = hlook->root.u.def.value;
+
+ hpp = elf_sym_hashes (abfd);
+ hppend = hpp + extsymcount;
+ for (; hpp < hppend; hpp++)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = *hpp;
+ if (h != NULL && h != hlook
+ && h->root.type == bfd_link_hash_defined
+ && h->root.u.def.section == slook
+ && h->root.u.def.value == vlook)
+ {
+ hlook->weakdef = h;
+
+ /* If the weak definition is in the list of dynamic
+ symbols, make sure the real definition is put there
+ as well. */
+ if (hlook->dynindx != -1
+ && h->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+ goto error_return;
+ }
+
+ /* If the real definition is in the list of dynamic
+ symbols, make sure the weak definition is put there
+ as well. If we don't do this, then the dynamic
+ loader might not merge the entries for the real
+ definition and the weak definition. */
+ if (h->dynindx != -1
+ && hlook->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info, hlook))
+ goto error_return;
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (buf != NULL)
+ {
+ free (buf);
+ buf = NULL;
+ }
+
+ if (extversym != NULL)
+ {
+ free (extversym);
+ extversym = NULL;
+ }
+
+ /* If this object is the same format as the output object, and it is
+ not a shared library, then let the backend look through the
+ relocs.
+
+ This is required to build global offset table entries and to
+ arrange for dynamic relocs. It is not required for the
+ particular common case of linking non PIC code, even when linking
+ against shared libraries, but unfortunately there is no way of
+ knowing whether an object file has been compiled PIC or not.
+ Looking through the relocs is not particularly time consuming.
+ The problem is that we must either (1) keep the relocs in memory,
+ which causes the linker to require additional runtime memory or
+ (2) read the relocs twice from the input file, which wastes time.
+ This would be a good case for using mmap.
+
+ I have no idea how to handle linking PIC code into a file of a
+ different format. It probably can't be done. */
+ check_relocs = get_elf_backend_data (abfd)->check_relocs;
+ if (! dynamic
+ && abfd->xvec == info->hash->creator
+ && check_relocs != NULL)
+ {
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ boolean ok;
+
+ if ((o->flags & SEC_RELOC) == 0
+ || o->reloc_count == 0
+ || ((info->strip == strip_all || info->strip == strip_debugger)
+ && (o->flags & SEC_DEBUGGING) != 0)
+ || bfd_is_abs_section (o->output_section))
+ continue;
+
+ internal_relocs = (NAME(_bfd_elf,link_read_relocs)
+ (abfd, o, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ ok = (*check_relocs) (abfd, info, o, internal_relocs);
+
+ if (! info->keep_memory)
+ free (internal_relocs);
+
+ if (! ok)
+ goto error_return;
+ }
+ }
+
+ /* If this is a non-traditional, non-relocateable link, try to
+ optimize the handling of the .stab/.stabstr sections. */
+ if (! dynamic
+ && ! info->relocateable
+ && ! info->traditional_format
+ && info->hash->creator->flavour == bfd_target_elf_flavour
+ && (info->strip != strip_all && info->strip != strip_debugger))
+ {
+ asection *stab, *stabstr;
+
+ stab = bfd_get_section_by_name (abfd, ".stab");
+ if (stab != NULL)
+ {
+ stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+
+ if (stabstr != NULL)
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (stab);
+ if (! _bfd_link_section_stabs (abfd,
+ &elf_hash_table (info)->stab_info,
+ stab, stabstr,
+ &secdata->stab_info))
+ goto error_return;
+ }
+ }
+ }
+
+ return true;
+
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ if (dynbuf != NULL)
+ free (dynbuf);
+ if (dynver != NULL)
+ free (dynver);
+ if (extversym != NULL)
+ free (extversym);
+ return false;
+}
+
+/* Create some sections which will be filled in with dynamic linking
+ information. ABFD is an input file which requires dynamic sections
+ to be created. The dynamic sections take up virtual memory space
+ when the final executable is run, so we need to create them before
+ addresses are assigned to the output sections. We work out the
+ actual contents and size of these sections later. */
+
+boolean
+elf_link_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+ struct elf_link_hash_entry *h;
+ struct elf_backend_data *bed;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ return true;
+
+ /* Make sure that all dynamic sections use the same input BFD. */
+ if (elf_hash_table (info)->dynobj == NULL)
+ elf_hash_table (info)->dynobj = abfd;
+ else
+ abfd = elf_hash_table (info)->dynobj;
+
+ /* Note that we set the SEC_IN_MEMORY flag for all of these
+ sections. */
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+
+ /* A dynamically linked executable has a .interp section, but a
+ shared library does not. */
+ if (! info->shared)
+ {
+ s = bfd_make_section (abfd, ".interp");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
+ return false;
+ }
+
+ /* Create sections to hold version informations. These are removed
+ if they are not needed. */
+ s = bfd_make_section (abfd, ".gnu.version_d");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
+ return false;
+
+ s = bfd_make_section (abfd, ".gnu.version");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 1))
+ return false;
+
+ s = bfd_make_section (abfd, ".gnu.version_r");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
+ return false;
+
+ s = bfd_make_section (abfd, ".dynsym");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
+ return false;
+
+ s = bfd_make_section (abfd, ".dynstr");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
+ return false;
+
+ /* Create a strtab to hold the dynamic symbol names. */
+ if (elf_hash_table (info)->dynstr == NULL)
+ {
+ elf_hash_table (info)->dynstr = elf_stringtab_init ();
+ if (elf_hash_table (info)->dynstr == NULL)
+ return false;
+ }
+
+ s = bfd_make_section (abfd, ".dynamic");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
+ return false;
+
+ /* The special symbol _DYNAMIC is always set to the start of the
+ .dynamic section. This call occurs before we have processed the
+ symbols for any dynamic object, so we don't have to worry about
+ overriding a dynamic definition. We could set _DYNAMIC in a
+ linker script, but we only want to define it if we are, in fact,
+ creating a .dynamic section. We don't want to define it if there
+ is no .dynamic section, since on some ELF platforms the start up
+ code examines it to decide how to initialize the process. */
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, (bfd_vma) 0,
+ (const char *) NULL, false, get_elf_backend_data (abfd)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (info->shared
+ && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ s = bfd_make_section (abfd, ".hash");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
+ return false;
+
+ /* Let the backend create the rest of the sections. This lets the
+ backend set the right flags. The backend will normally create
+ the .got and .plt sections. */
+ bed = get_elf_backend_data (abfd);
+ if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
+ return false;
+
+ elf_hash_table (info)->dynamic_sections_created = true;
+
+ return true;
+}
+
+/* Add an entry to the .dynamic table. */
+
+boolean
+elf_add_dynamic_entry (info, tag, val)
+ struct bfd_link_info *info;
+ bfd_vma tag;
+ bfd_vma val;
+{
+ Elf_Internal_Dyn dyn;
+ bfd *dynobj;
+ asection *s;
+ size_t newsize;
+ bfd_byte *newcontents;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ s = bfd_get_section_by_name (dynobj, ".dynamic");
+ BFD_ASSERT (s != NULL);
+
+ newsize = s->_raw_size + sizeof (Elf_External_Dyn);
+ newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize);
+ if (newcontents == NULL)
+ return false;
+
+ dyn.d_tag = tag;
+ dyn.d_un.d_val = val;
+ elf_swap_dyn_out (dynobj, &dyn,
+ (Elf_External_Dyn *) (newcontents + s->_raw_size));
+
+ s->_raw_size = newsize;
+ s->contents = newcontents;
+
+ return true;
+}
+
+
+/* Read and swap the relocs for a section. They may have been cached.
+ If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are not NULL,
+ they are used as buffers to read into. They are known to be large
+ enough. If the INTERNAL_RELOCS relocs argument is NULL, the return
+ value is allocated using either malloc or bfd_alloc, according to
+ the KEEP_MEMORY argument. */
+
+Elf_Internal_Rela *
+NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs,
+ keep_memory)
+ bfd *abfd;
+ asection *o;
+ PTR external_relocs;
+ Elf_Internal_Rela *internal_relocs;
+ boolean keep_memory;
+{
+ Elf_Internal_Shdr *rel_hdr;
+ PTR alloc1 = NULL;
+ Elf_Internal_Rela *alloc2 = NULL;
+
+ if (elf_section_data (o)->relocs != NULL)
+ return elf_section_data (o)->relocs;
+
+ if (o->reloc_count == 0)
+ return NULL;
+
+ rel_hdr = &elf_section_data (o)->rel_hdr;
+
+ if (internal_relocs == NULL)
+ {
+ size_t size;
+
+ size = o->reloc_count * sizeof (Elf_Internal_Rela);
+ if (keep_memory)
+ internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
+ else
+ internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size);
+ if (internal_relocs == NULL)
+ goto error_return;
+ }
+
+ if (external_relocs == NULL)
+ {
+ alloc1 = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
+ if (alloc1 == NULL)
+ goto error_return;
+ external_relocs = alloc1;
+ }
+
+ if ((bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0)
+ || (bfd_read (external_relocs, 1, rel_hdr->sh_size, abfd)
+ != rel_hdr->sh_size))
+ goto error_return;
+
+ /* Swap in the relocs. For convenience, we always produce an
+ Elf_Internal_Rela array; if the relocs are Rel, we set the addend
+ to 0. */
+ if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
+ {
+ Elf_External_Rel *erel;
+ Elf_External_Rel *erelend;
+ Elf_Internal_Rela *irela;
+
+ erel = (Elf_External_Rel *) external_relocs;
+ erelend = erel + o->reloc_count;
+ irela = internal_relocs;
+ for (; erel < erelend; erel++, irela++)
+ {
+ Elf_Internal_Rel irel;
+
+ elf_swap_reloc_in (abfd, erel, &irel);
+ irela->r_offset = irel.r_offset;
+ irela->r_info = irel.r_info;
+ irela->r_addend = 0;
+ }
+ }
+ else
+ {
+ Elf_External_Rela *erela;
+ Elf_External_Rela *erelaend;
+ Elf_Internal_Rela *irela;
+
+ BFD_ASSERT (rel_hdr->sh_entsize == sizeof (Elf_External_Rela));
+
+ erela = (Elf_External_Rela *) external_relocs;
+ erelaend = erela + o->reloc_count;
+ irela = internal_relocs;
+ for (; erela < erelaend; erela++, irela++)
+ elf_swap_reloca_in (abfd, erela, irela);
+ }
+
+ /* Cache the results for next time, if we can. */
+ if (keep_memory)
+ elf_section_data (o)->relocs = internal_relocs;
+
+ if (alloc1 != NULL)
+ free (alloc1);
+
+ /* Don't free alloc2, since if it was allocated we are passing it
+ back (under the name of internal_relocs). */
+
+ return internal_relocs;
+
+ error_return:
+ if (alloc1 != NULL)
+ free (alloc1);
+ if (alloc2 != NULL)
+ free (alloc2);
+ return NULL;
+}
+
+
+/* Record an assignment to a symbol made by a linker script. We need
+ this in case some dynamic object refers to this symbol. */
+
+/*ARGSUSED*/
+boolean
+NAME(bfd_elf,record_link_assignment) (output_bfd, info, name, provide)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ const char *name;
+ boolean provide;
+{
+ struct elf_link_hash_entry *h;
+
+ if (info->hash->creator->flavour != bfd_target_elf_flavour)
+ return true;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name, true, true, false);
+ if (h == NULL)
+ return false;
+
+ if (h->root.type == bfd_link_hash_new)
+ h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+
+ /* If this symbol is being provided by the linker script, and it is
+ currently defined by a dynamic object, but not by a regular
+ object, then mark it as undefined so that the generic linker will
+ force the correct value. */
+ if (provide
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ h->root.type = bfd_link_hash_undefined;
+
+ /* If this symbol is not being provided by the linker script, and it is
+ currently defined by a dynamic object, but not by a regular object,
+ then clear out any version information because the symbol will not be
+ associated with the dynamic object any more. */
+ if (!provide
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ h->verinfo.verdef = NULL;
+
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+
+ if (((h->elf_link_hash_flags & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_REF_DYNAMIC)) != 0
+ || info->shared)
+ && h->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ /* If this is a weak defined symbol, and we know a corresponding
+ real symbol from the same dynamic object, make sure the real
+ symbol is also made into a dynamic symbol. */
+ if (h->weakdef != NULL
+ && h->weakdef->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* This structure is used to pass information to
+ elf_link_assign_sym_version. */
+
+struct elf_assign_sym_version_info
+{
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Version tree. */
+ struct bfd_elf_version_tree *verdefs;
+ /* Whether we are exporting all dynamic symbols. */
+ boolean export_dynamic;
+ /* Whether we removed any symbols from the dynamic symbol table. */
+ boolean removed_dynamic;
+ /* Whether we had a failure. */
+ boolean failed;
+};
+
+/* This structure is used to pass information to
+ elf_link_find_version_dependencies. */
+
+struct elf_find_verdep_info
+{
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* The number of dependencies. */
+ unsigned int vers;
+ /* Whether we had a failure. */
+ boolean failed;
+};
+
+/* Array used to determine the number of hash table buckets to use
+ based on the number of symbols there are. If there are fewer than
+ 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets,
+ fewer than 37 we use 17 buckets, and so forth. We never use more
+ than 32771 buckets. */
+
+static const size_t elf_buckets[] =
+{
+ 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
+ 16411, 32771, 0
+};
+
+/* Compute bucket count for hashing table. We do not use a static set
+ of possible tables sizes anymore. Instead we determine for all
+ possible reasonable sizes of the table the outcome (i.e., the
+ number of collisions etc) and choose the best solution. The
+ weighting functions are not too simple to allow the table to grow
+ without bounds. Instead one of the weighting factors is the size.
+ Therefore the result is always a good payoff between few collisions
+ (= short chain lengths) and table size. */
+static size_t
+compute_bucket_count (info)
+ struct bfd_link_info *info;
+{
+ size_t dynsymcount = elf_hash_table (info)->dynsymcount;
+ size_t best_size;
+ unsigned long int *hashcodes;
+ unsigned long int *hashcodesp;
+ unsigned long int i;
+
+ /* Compute the hash values for all exported symbols. At the same
+ time store the values in an array so that we could use them for
+ optimizations. */
+ hashcodes = (unsigned long int *) bfd_malloc (dynsymcount
+ * sizeof (unsigned long int));
+ if (hashcodes == NULL)
+ return 0;
+ hashcodesp = hashcodes;
+
+ /* Put all hash values in HASHCODES. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_collect_hash_codes, &hashcodesp);
+
+/* We have a problem here. The following code to optimize the table
+ size requires an integer type with more the 32 bits. If
+ BFD_HOST_U_64_BIT is set we know about such a type. */
+#ifdef BFD_HOST_U_64_BIT
+ if (info->optimize == true)
+ {
+ unsigned long int nsyms = hashcodesp - hashcodes;
+ size_t minsize;
+ size_t maxsize;
+ BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
+ unsigned long int *counts ;
+
+ /* Possible optimization parameters: if we have NSYMS symbols we say
+ that the hashing table must at least have NSYMS/4 and at most
+ 2*NSYMS buckets. */
+ minsize = nsyms / 4;
+ if (minsize == 0)
+ minsize = 1;
+ best_size = maxsize = nsyms * 2;
+
+ /* Create array where we count the collisions in. We must use bfd_malloc
+ since the size could be large. */
+ counts = (unsigned long int *) bfd_malloc (maxsize
+ * sizeof (unsigned long int));
+ if (counts == NULL)
+ {
+ free (hashcodes);
+ return 0;
+ }
+
+ /* Compute the "optimal" size for the hash table. The criteria is a
+ minimal chain length. The minor criteria is (of course) the size
+ of the table. */
+ for (i = minsize; i < maxsize; ++i)
+ {
+ /* Walk through the array of hashcodes and count the collisions. */
+ BFD_HOST_U_64_BIT max;
+ unsigned long int j;
+ unsigned long int fact;
+
+ memset (counts, '\0', i * sizeof (unsigned long int));
+
+ /* Determine how often each hash bucket is used. */
+ for (j = 0; j < nsyms; ++j)
+ ++counts[hashcodes[j] % i];
+
+ /* For the weight function we need some information about the
+ pagesize on the target. This is information need not be 100%
+ accurate. Since this information is not available (so far) we
+ define it here to a reasonable default value. If it is crucial
+ to have a better value some day simply define this value. */
+# ifndef BFD_TARGET_PAGESIZE
+# define BFD_TARGET_PAGESIZE (4096)
+# endif
+
+ /* We in any case need 2 + NSYMS entries for the size values and
+ the chains. */
+ max = (2 + nsyms) * (ARCH_SIZE / 8);
+
+# if 1
+ /* Variant 1: optimize for short chains. We add the squares
+ of all the chain lengths (which favous many small chain
+ over a few long chains). */
+ for (j = 0; j < i; ++j)
+ max += counts[j] * counts[j];
+
+ /* This adds penalties for the overall size of the table. */
+ fact = i / (BFD_TARGET_PAGESIZE / (ARCH_SIZE / 8)) + 1;
+ max *= fact * fact;
+# else
+ /* Variant 2: Optimize a lot more for small table. Here we
+ also add squares of the size but we also add penalties for
+ empty slots (the +1 term). */
+ for (j = 0; j < i; ++j)
+ max += (1 + counts[j]) * (1 + counts[j]);
+
+ /* The overall size of the table is considered, but not as
+ strong as in variant 1, where it is squared. */
+ fact = i / (BFD_TARGET_PAGESIZE / (ARCH_SIZE / 8)) + 1;
+ max *= fact;
+# endif
+
+ /* Compare with current best results. */
+ if (max < best_chlen)
+ {
+ best_chlen = max;
+ best_size = i;
+ }
+ }
+
+ free (counts);
+ }
+ else
+#endif /* defined (BFD_HOST_U_64_BIT) */
+ {
+ /* This is the fallback solution if no 64bit type is available or if we
+ are not supposed to spend much time on optimizations. We select the
+ bucket count using a fixed set of numbers. */
+ for (i = 0; elf_buckets[i] != 0; i++)
+ {
+ best_size = elf_buckets[i];
+ if (dynsymcount < elf_buckets[i + 1])
+ break;
+ }
+ }
+
+ /* Free the arrays we needed. */
+ free (hashcodes);
+
+ return best_size;
+}
+
+/* Set up the sizes and contents of the ELF dynamic sections. This is
+ called by the ELF linker emulation before_allocation routine. We
+ must set the sizes of the sections before the linker sets the
+ addresses of the various sections. */
+
+boolean
+NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
+ export_dynamic, filter_shlib,
+ auxiliary_filters, info, sinterpptr,
+ verdefs)
+ bfd *output_bfd;
+ const char *soname;
+ const char *rpath;
+ boolean export_dynamic;
+ const char *filter_shlib;
+ const char * const *auxiliary_filters;
+ struct bfd_link_info *info;
+ asection **sinterpptr;
+ struct bfd_elf_version_tree *verdefs;
+{
+ bfd_size_type soname_indx;
+ bfd *dynobj;
+ struct elf_backend_data *bed;
+ bfd_size_type old_dynsymcount;
+ struct elf_assign_sym_version_info asvinfo;
+
+ *sinterpptr = NULL;
+
+ soname_indx = (bfd_size_type) -1;
+
+ if (info->hash->creator->flavour != bfd_target_elf_flavour)
+ return true;
+
+ /* The backend may have to create some sections regardless of whether
+ we're dynamic or not. */
+ bed = get_elf_backend_data (output_bfd);
+ if (bed->elf_backend_always_size_sections
+ && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
+ return false;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* If there were no dynamic objects in the link, there is nothing to
+ do here. */
+ if (dynobj == NULL)
+ return true;
+
+ /* If we are supposed to export all symbols into the dynamic symbol
+ table (this is not the normal case), then do so. */
+ if (export_dynamic)
+ {
+ struct elf_info_failed eif;
+
+ eif.failed = false;
+ eif.info = info;
+ elf_link_hash_traverse (elf_hash_table (info), elf_export_symbol,
+ (PTR) &eif);
+ if (eif.failed)
+ return false;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ struct elf_info_failed eif;
+ struct elf_link_hash_entry *h;
+ bfd_size_type strsize;
+
+ *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (*sinterpptr != NULL || info->shared);
+
+ if (soname != NULL)
+ {
+ soname_indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ soname, true, true);
+ if (soname_indx == (bfd_size_type) -1
+ || ! elf_add_dynamic_entry (info, DT_SONAME, soname_indx))
+ return false;
+ }
+
+ if (info->symbolic)
+ {
+ if (! elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
+ return false;
+ }
+
+ if (rpath != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr, rpath,
+ true, true);
+ if (indx == (bfd_size_type) -1
+ || ! elf_add_dynamic_entry (info, DT_RPATH, indx))
+ return false;
+ }
+
+ if (filter_shlib != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ filter_shlib, true, true);
+ if (indx == (bfd_size_type) -1
+ || ! elf_add_dynamic_entry (info, DT_FILTER, indx))
+ return false;
+ }
+
+ if (auxiliary_filters != NULL)
+ {
+ const char * const *p;
+
+ for (p = auxiliary_filters; *p != NULL; p++)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ *p, true, true);
+ if (indx == (bfd_size_type) -1
+ || ! elf_add_dynamic_entry (info, DT_AUXILIARY, indx))
+ return false;
+ }
+ }
+
+ /* Attach all the symbols to their version information. */
+ asvinfo.output_bfd = output_bfd;
+ asvinfo.info = info;
+ asvinfo.verdefs = verdefs;
+ asvinfo.export_dynamic = export_dynamic;
+ asvinfo.removed_dynamic = false;
+ asvinfo.failed = false;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_assign_sym_version,
+ (PTR) &asvinfo);
+ if (asvinfo.failed)
+ return false;
+
+ /* Find all symbols which were defined in a dynamic object and make
+ the backend pick a reasonable value for them. */
+ eif.failed = false;
+ eif.info = info;
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_adjust_dynamic_symbol,
+ (PTR) &eif);
+ if (eif.failed)
+ return false;
+
+ /* Add some entries to the .dynamic section. We fill in some of the
+ values later, in elf_bfd_final_link, but we must add the entries
+ now so that we know the final size of the .dynamic section. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "_init", false,
+ false, false);
+ if (h != NULL
+ && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_DEF_REGULAR)) != 0)
+ {
+ if (! elf_add_dynamic_entry (info, DT_INIT, 0))
+ return false;
+ }
+ h = elf_link_hash_lookup (elf_hash_table (info), "_fini", false,
+ false, false);
+ if (h != NULL
+ && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_DEF_REGULAR)) != 0)
+ {
+ if (! elf_add_dynamic_entry (info, DT_FINI, 0))
+ return false;
+ }
+ strsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+ if (! elf_add_dynamic_entry (info, DT_HASH, 0)
+ || ! elf_add_dynamic_entry (info, DT_STRTAB, 0)
+ || ! elf_add_dynamic_entry (info, DT_SYMTAB, 0)
+ || ! elf_add_dynamic_entry (info, DT_STRSZ, strsize)
+ || ! elf_add_dynamic_entry (info, DT_SYMENT,
+ sizeof (Elf_External_Sym)))
+ return false;
+ }
+
+ /* The backend must work out the sizes of all the other dynamic
+ sections. */
+ old_dynsymcount = elf_hash_table (info)->dynsymcount;
+ if (bed->elf_backend_size_dynamic_sections
+ && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
+ return false;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ size_t dynsymcount;
+ asection *s;
+ size_t bucketcount = 0;
+ Elf_Internal_Sym isym;
+
+ /* Set up the version definition section. */
+ s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
+ BFD_ASSERT (s != NULL);
+
+ /* We may have created additional version definitions if we are
+ just linking a regular application. */
+ verdefs = asvinfo.verdefs;
+
+ if (verdefs == NULL)
+ {
+ asection **spp;
+
+ /* Don't include this section in the output file. */
+ for (spp = &output_bfd->sections;
+ *spp != s->output_section;
+ spp = &(*spp)->next)
+ ;
+ *spp = s->output_section->next;
+ --output_bfd->section_count;
+ }
+ else
+ {
+ unsigned int cdefs;
+ bfd_size_type size;
+ struct bfd_elf_version_tree *t;
+ bfd_byte *p;
+ Elf_Internal_Verdef def;
+ Elf_Internal_Verdaux defaux;
+
+ if (asvinfo.removed_dynamic)
+ {
+ /* Some dynamic symbols were changed to be local
+ symbols. In this case, we renumber all of the
+ dynamic symbols, so that we don't have a hole. If
+ the backend changed dynsymcount, then assume that the
+ new symbols are at the start. This is the case on
+ the MIPS. FIXME: The names of the removed symbols
+ will still be in the dynamic string table, wasting
+ space. */
+ elf_hash_table (info)->dynsymcount =
+ 1 + (elf_hash_table (info)->dynsymcount - old_dynsymcount);
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_renumber_dynsyms,
+ (PTR) info);
+ }
+
+ cdefs = 0;
+ size = 0;
+
+ /* Make space for the base version. */
+ size += sizeof (Elf_External_Verdef);
+ size += sizeof (Elf_External_Verdaux);
+ ++cdefs;
+
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ struct bfd_elf_version_deps *n;
+
+ size += sizeof (Elf_External_Verdef);
+ size += sizeof (Elf_External_Verdaux);
+ ++cdefs;
+
+ for (n = t->deps; n != NULL; n = n->next)
+ size += sizeof (Elf_External_Verdaux);
+ }
+
+ s->_raw_size = size;
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+
+ /* Fill in the version definition section. */
+
+ p = s->contents;
+
+ def.vd_version = VER_DEF_CURRENT;
+ def.vd_flags = VER_FLG_BASE;
+ def.vd_ndx = 1;
+ def.vd_cnt = 1;
+ def.vd_aux = sizeof (Elf_External_Verdef);
+ def.vd_next = (sizeof (Elf_External_Verdef)
+ + sizeof (Elf_External_Verdaux));
+
+ if (soname_indx != (bfd_size_type) -1)
+ {
+ def.vd_hash = bfd_elf_hash ((const unsigned char *) soname);
+ defaux.vda_name = soname_indx;
+ }
+ else
+ {
+ const char *name;
+ bfd_size_type indx;
+
+ name = output_bfd->filename;
+ def.vd_hash = bfd_elf_hash ((const unsigned char *) name);
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ name, true, false);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ defaux.vda_name = indx;
+ }
+ defaux.vda_next = 0;
+
+ _bfd_elf_swap_verdef_out (output_bfd, &def,
+ (Elf_External_Verdef *)p);
+ p += sizeof (Elf_External_Verdef);
+ _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
+ (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ unsigned int cdeps;
+ struct bfd_elf_version_deps *n;
+ struct elf_link_hash_entry *h;
+
+ cdeps = 0;
+ for (n = t->deps; n != NULL; n = n->next)
+ ++cdeps;
+
+ /* Add a symbol representing this version. */
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
+ (bfd_vma) 0, (const char *) NULL, false,
+ get_elf_backend_data (dynobj)->collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+ h->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+ h->verinfo.vertree = t;
+
+ if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+ return false;
+
+ def.vd_version = VER_DEF_CURRENT;
+ def.vd_flags = 0;
+ if (t->globals == NULL && t->locals == NULL && ! t->used)
+ def.vd_flags |= VER_FLG_WEAK;
+ def.vd_ndx = t->vernum + 1;
+ def.vd_cnt = cdeps + 1;
+ def.vd_hash = bfd_elf_hash ((const unsigned char *) t->name);
+ def.vd_aux = sizeof (Elf_External_Verdef);
+ if (t->next != NULL)
+ def.vd_next = (sizeof (Elf_External_Verdef)
+ + (cdeps + 1) * sizeof (Elf_External_Verdaux));
+ else
+ def.vd_next = 0;
+
+ _bfd_elf_swap_verdef_out (output_bfd, &def,
+ (Elf_External_Verdef *) p);
+ p += sizeof (Elf_External_Verdef);
+
+ defaux.vda_name = h->dynstr_index;
+ if (t->deps == NULL)
+ defaux.vda_next = 0;
+ else
+ defaux.vda_next = sizeof (Elf_External_Verdaux);
+ t->name_indx = defaux.vda_name;
+
+ _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
+ (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+
+ for (n = t->deps; n != NULL; n = n->next)
+ {
+ if (n->version_needed == NULL)
+ {
+ /* This can happen if there was an error in the
+ version script. */
+ defaux.vda_name = 0;
+ }
+ else
+ defaux.vda_name = n->version_needed->name_indx;
+ if (n->next == NULL)
+ defaux.vda_next = 0;
+ else
+ defaux.vda_next = sizeof (Elf_External_Verdaux);
+
+ _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
+ (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+ }
+ }
+
+ if (! elf_add_dynamic_entry (info, DT_VERDEF, 0)
+ || ! elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs))
+ return false;
+
+ elf_tdata (output_bfd)->cverdefs = cdefs;
+ }
+
+ /* Work out the size of the version reference section. */
+
+ s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
+ BFD_ASSERT (s != NULL);
+ {
+ struct elf_find_verdep_info sinfo;
+
+ sinfo.output_bfd = output_bfd;
+ sinfo.info = info;
+ sinfo.vers = elf_tdata (output_bfd)->cverdefs;
+ if (sinfo.vers == 0)
+ sinfo.vers = 1;
+ sinfo.failed = false;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_find_version_dependencies,
+ (PTR) &sinfo);
+
+ if (elf_tdata (output_bfd)->verref == NULL)
+ {
+ asection **spp;
+
+ /* We don't have any version definitions, so we can just
+ remove the section. */
+
+ for (spp = &output_bfd->sections;
+ *spp != s->output_section;
+ spp = &(*spp)->next)
+ ;
+ *spp = s->output_section->next;
+ --output_bfd->section_count;
+ }
+ else
+ {
+ Elf_Internal_Verneed *t;
+ unsigned int size;
+ unsigned int crefs;
+ bfd_byte *p;
+
+ /* Build the version definition section. */
+ size = 0;
+ crefs = 0;
+ for (t = elf_tdata (output_bfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ Elf_Internal_Vernaux *a;
+
+ size += sizeof (Elf_External_Verneed);
+ ++crefs;
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ size += sizeof (Elf_External_Vernaux);
+ }
+
+ s->_raw_size = size;
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, size);
+ if (s->contents == NULL)
+ return false;
+
+ p = s->contents;
+ for (t = elf_tdata (output_bfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ unsigned int caux;
+ Elf_Internal_Vernaux *a;
+ bfd_size_type indx;
+
+ caux = 0;
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ ++caux;
+
+ t->vn_version = VER_NEED_CURRENT;
+ t->vn_cnt = caux;
+ if (elf_dt_name (t->vn_bfd) != NULL)
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ elf_dt_name (t->vn_bfd),
+ true, false);
+ else
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ t->vn_bfd->filename, true, false);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ t->vn_file = indx;
+ t->vn_aux = sizeof (Elf_External_Verneed);
+ if (t->vn_nextref == NULL)
+ t->vn_next = 0;
+ else
+ t->vn_next = (sizeof (Elf_External_Verneed)
+ + caux * sizeof (Elf_External_Vernaux));
+
+ _bfd_elf_swap_verneed_out (output_bfd, t,
+ (Elf_External_Verneed *) p);
+ p += sizeof (Elf_External_Verneed);
+
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ {
+ a->vna_hash = bfd_elf_hash ((const unsigned char *)
+ a->vna_nodename);
+ indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+ a->vna_nodename, true, false);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ a->vna_name = indx;
+ if (a->vna_nextptr == NULL)
+ a->vna_next = 0;
+ else
+ a->vna_next = sizeof (Elf_External_Vernaux);
+
+ _bfd_elf_swap_vernaux_out (output_bfd, a,
+ (Elf_External_Vernaux *) p);
+ p += sizeof (Elf_External_Vernaux);
+ }
+ }
+
+ if (! elf_add_dynamic_entry (info, DT_VERNEED, 0)
+ || ! elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs))
+ return false;
+
+ elf_tdata (output_bfd)->cverrefs = crefs;
+ }
+ }
+
+ dynsymcount = elf_hash_table (info)->dynsymcount;
+
+ /* Work out the size of the symbol version section. */
+ s = bfd_get_section_by_name (dynobj, ".gnu.version");
+ BFD_ASSERT (s != NULL);
+ if (dynsymcount == 0
+ || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
+ {
+ asection **spp;
+
+ /* We don't need any symbol versions; just discard the
+ section. */
+ for (spp = &output_bfd->sections;
+ *spp != s->output_section;
+ spp = &(*spp)->next)
+ ;
+ *spp = s->output_section->next;
+ --output_bfd->section_count;
+ }
+ else
+ {
+ s->_raw_size = dynsymcount * sizeof (Elf_External_Versym);
+ s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+
+ if (! elf_add_dynamic_entry (info, DT_VERSYM, 0))
+ return false;
+ }
+
+ /* Set the size of the .dynsym and .hash sections. We counted
+ the number of dynamic symbols in elf_link_add_object_symbols.
+ We will build the contents of .dynsym and .hash when we build
+ the final symbol table, because until then we do not know the
+ correct value to give the symbols. We built the .dynstr
+ section as we went along in elf_link_add_object_symbols. */
+ s = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = dynsymcount * sizeof (Elf_External_Sym);
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+
+ /* The first entry in .dynsym is a dummy symbol. */
+ isym.st_value = 0;
+ isym.st_size = 0;
+ isym.st_name = 0;
+ isym.st_info = 0;
+ isym.st_other = 0;
+ isym.st_shndx = 0;
+ elf_swap_symbol_out (output_bfd, &isym,
+ (PTR) (Elf_External_Sym *) s->contents);
+
+ /* Compute the size of the hashing table. As a side effect this
+ computes the hash values for all the names we export. */
+ bucketcount = compute_bucket_count (info);
+
+ s = bfd_get_section_by_name (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = (2 + bucketcount + dynsymcount) * (ARCH_SIZE / 8);
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+ memset (s->contents, 0, (size_t) s->_raw_size);
+
+ put_word (output_bfd, bucketcount, s->contents);
+ put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8));
+
+ elf_hash_table (info)->bucketcount = bucketcount;
+
+ s = bfd_get_section_by_name (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+
+ if (! elf_add_dynamic_entry (info, DT_NULL, 0))
+ return false;
+ }
+
+ return true;
+}
+
+/* Fix up the flags for a symbol. This handles various cases which
+ can only be fixed after all the input files are seen. This is
+ currently called by both adjust_dynamic_symbol and
+ assign_sym_version, which is unnecessary but perhaps more robust in
+ the face of future changes. */
+
+static boolean
+elf_fix_symbol_flags (h, eif)
+ struct elf_link_hash_entry *h;
+ struct elf_info_failed *eif;
+{
+ /* If this symbol was mentioned in a non-ELF file, try to set
+ DEF_REGULAR and REF_REGULAR correctly. This is the only way to
+ permit a non-ELF file to correctly refer to a symbol defined in
+ an ELF dynamic object. */
+ if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
+ {
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ h->elf_link_hash_flags |= (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK);
+ else
+ {
+ if (h->root.u.def.section->owner != NULL
+ && (bfd_get_flavour (h->root.u.def.section->owner)
+ == bfd_target_elf_flavour))
+ h->elf_link_hash_flags |= (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK);
+ else
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ }
+
+ if (h->dynindx == -1
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0))
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h))
+ {
+ eif->failed = true;
+ return false;
+ }
+ }
+ }
+ else
+ {
+ /* Unfortunately, ELF_LINK_NON_ELF is only correct if the symbol
+ was first seen in a non-ELF file. Fortunately, if the symbol
+ was first seen in an ELF file, we're probably OK unless the
+ symbol was defined in a non-ELF file. Catch that case here.
+ FIXME: We're still in trouble if the symbol was first seen in
+ a dynamic object, and then later in a non-ELF regular object. */
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+ && (h->root.u.def.section->owner != NULL
+ ? (bfd_get_flavour (h->root.u.def.section->owner)
+ != bfd_target_elf_flavour)
+ : (bfd_is_abs_section (h->root.u.def.section)
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) == 0)))
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ }
+
+ /* If this is a final link, and the symbol was defined as a common
+ symbol in a regular object file, and there was no definition in
+ any dynamic object, then the linker will have allocated space for
+ the symbol in a common section but the ELF_LINK_HASH_DEF_REGULAR
+ flag will not have been set. */
+ if (h->root.type == bfd_link_hash_defined
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+
+ /* If -Bsymbolic was used (which means to bind references to global
+ symbols to the definition within the shared object), and this
+ symbol was defined in a regular object, then it actually doesn't
+ need a PLT entry. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
+ && eif->info->shared
+ && eif->info->symbolic
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
+ {
+ h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
+ h->plt.offset = (bfd_vma) -1;
+ }
+
+ return true;
+}
+
+/* Make the backend pick a good value for a dynamic symbol. This is
+ called via elf_link_hash_traverse, and also calls itself
+ recursively. */
+
+static boolean
+elf_adjust_dynamic_symbol (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ struct elf_info_failed *eif = (struct elf_info_failed *) data;
+ bfd *dynobj;
+ struct elf_backend_data *bed;
+
+ /* Ignore indirect symbols. These are added by the versioning code. */
+ if (h->root.type == bfd_link_hash_indirect)
+ return true;
+
+ /* Fix the symbol flags. */
+ if (! elf_fix_symbol_flags (h, eif))
+ return false;
+
+ /* If this symbol does not require a PLT entry, and it is not
+ defined by a dynamic object, or is not referenced by a regular
+ object, ignore it. We do have to handle a weak defined symbol,
+ even if no regular object refers to it, if we decided to add it
+ to the dynamic symbol table. FIXME: Do we normally need to worry
+ about symbols which are defined by one dynamic object and
+ referenced by another one? */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ || ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
+ && (h->weakdef == NULL || h->weakdef->dynindx == -1))))
+ {
+ h->plt.offset = (bfd_vma) -1;
+ return true;
+ }
+
+ /* If we've already adjusted this symbol, don't do it again. This
+ can happen via a recursive call. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
+ return true;
+
+ /* Don't look at this symbol again. Note that we must set this
+ after checking the above conditions, because we may look at a
+ symbol once, decide not to do anything, and then get called
+ recursively later after REF_REGULAR is set below. */
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DYNAMIC_ADJUSTED;
+
+ /* If this is a weak definition, and we know a real definition, and
+ the real symbol is not itself defined by a regular object file,
+ then get a good value for the real definition. We handle the
+ real symbol first, for the convenience of the backend routine.
+
+ Note that there is a confusing case here. If the real definition
+ is defined by a regular object file, we don't get the real symbol
+ from the dynamic object, but we do get the weak symbol. If the
+ processor backend uses a COPY reloc, then if some routine in the
+ dynamic object changes the real symbol, we will not see that
+ change in the corresponding weak symbol. This is the way other
+ ELF linkers work as well, and seems to be a result of the shared
+ library model.
+
+ I will clarify this issue. Most SVR4 shared libraries define the
+ variable _timezone and define timezone as a weak synonym. The
+ tzset call changes _timezone. If you write
+ extern int timezone;
+ int _timezone = 5;
+ int main () { tzset (); printf ("%d %d\n", timezone, _timezone); }
+ you might expect that, since timezone is a synonym for _timezone,
+ the same number will print both times. However, if the processor
+ backend uses a COPY reloc, then actually timezone will be copied
+ into your process image, and, since you define _timezone
+ yourself, _timezone will not. Thus timezone and _timezone will
+ wind up at different memory locations. The tzset call will set
+ _timezone, leaving timezone unchanged. */
+
+ if (h->weakdef != NULL)
+ {
+ struct elf_link_hash_entry *weakdef;
+
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak);
+ weakdef = h->weakdef;
+ BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
+ || weakdef->root.type == bfd_link_hash_defweak);
+ BFD_ASSERT (weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC);
+ if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
+ {
+ /* This symbol is defined by a regular object file, so we
+ will not do anything special. Clear weakdef for the
+ convenience of the processor backend. */
+ h->weakdef = NULL;
+ }
+ else
+ {
+ /* There is an implicit reference by a regular object file
+ via the weak symbol. */
+ weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
+ if (h->weakdef->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR_NONWEAK)
+ weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR_NONWEAK;
+ if (! elf_adjust_dynamic_symbol (weakdef, (PTR) eif))
+ return false;
+ }
+ }
+
+ /* If a symbol has no type and no size and does not require a PLT
+ entry, then we are probably about to do the wrong thing here: we
+ are probably going to create a COPY reloc for an empty object.
+ This case can arise when a shared object is built with assembly
+ code, and the assembly code fails to set the symbol type. */
+ if (h->size == 0
+ && h->type == STT_NOTYPE
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0)
+ (*_bfd_error_handler)
+ (_("warning: type and size of dynamic symbol `%s' are not defined"),
+ h->root.root.string);
+
+ dynobj = elf_hash_table (eif->info)->dynobj;
+ bed = get_elf_backend_data (dynobj);
+ if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
+ {
+ eif->failed = true;
+ return false;
+ }
+
+ return true;
+}
+
+/* This routine is used to export all defined symbols into the dynamic
+ symbol table. It is called via elf_link_hash_traverse. */
+
+static boolean
+elf_export_symbol (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ struct elf_info_failed *eif = (struct elf_info_failed *) data;
+
+ /* Ignore indirect symbols. These are added by the versioning code. */
+ if (h->root.type == bfd_link_hash_indirect)
+ return true;
+
+ if (h->dynindx == -1
+ && (h->elf_link_hash_flags
+ & (ELF_LINK_HASH_DEF_REGULAR | ELF_LINK_HASH_REF_REGULAR)) != 0)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h))
+ {
+ eif->failed = true;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Look through the symbols which are defined in other shared
+ libraries and referenced here. Update the list of version
+ dependencies. This will be put into the .gnu.version_r section.
+ This function is called via elf_link_hash_traverse. */
+
+static boolean
+elf_link_find_version_dependencies (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data;
+ Elf_Internal_Verneed *t;
+ Elf_Internal_Vernaux *a;
+
+ /* We only care about symbols defined in shared objects with version
+ information. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
+ || h->dynindx == -1
+ || h->verinfo.verdef == NULL)
+ return true;
+
+ /* See if we already know about this version. */
+ for (t = elf_tdata (rinfo->output_bfd)->verref; t != NULL; t = t->vn_nextref)
+ {
+ if (t->vn_bfd != h->verinfo.verdef->vd_bfd)
+ continue;
+
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ if (a->vna_nodename == h->verinfo.verdef->vd_nodename)
+ return true;
+
+ break;
+ }
+
+ /* This is a new version. Add it to tree we are building. */
+
+ if (t == NULL)
+ {
+ t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->output_bfd, sizeof *t);
+ if (t == NULL)
+ {
+ rinfo->failed = true;
+ return false;
+ }
+
+ t->vn_bfd = h->verinfo.verdef->vd_bfd;
+ t->vn_nextref = elf_tdata (rinfo->output_bfd)->verref;
+ elf_tdata (rinfo->output_bfd)->verref = t;
+ }
+
+ a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->output_bfd, sizeof *a);
+
+ /* Note that we are copying a string pointer here, and testing it
+ above. If bfd_elf_string_from_elf_section is ever changed to
+ discard the string data when low in memory, this will have to be
+ fixed. */
+ a->vna_nodename = h->verinfo.verdef->vd_nodename;
+
+ a->vna_flags = h->verinfo.verdef->vd_flags;
+ a->vna_nextptr = t->vn_auxptr;
+
+ h->verinfo.verdef->vd_exp_refno = rinfo->vers;
+ ++rinfo->vers;
+
+ a->vna_other = h->verinfo.verdef->vd_exp_refno + 1;
+
+ t->vn_auxptr = a;
+
+ return true;
+}
+
+/* Figure out appropriate versions for all the symbols. We may not
+ have the version number script until we have read all of the input
+ files, so until that point we don't know which symbols should be
+ local. This function is called via elf_link_hash_traverse. */
+
+static boolean
+elf_link_assign_sym_version (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ struct elf_assign_sym_version_info *sinfo =
+ (struct elf_assign_sym_version_info *) data;
+ struct bfd_link_info *info = sinfo->info;
+ struct elf_info_failed eif;
+ char *p;
+
+ /* Fix the symbol flags. */
+ eif.failed = false;
+ eif.info = info;
+ if (! elf_fix_symbol_flags (h, &eif))
+ {
+ if (eif.failed)
+ sinfo->failed = true;
+ return false;
+ }
+
+ /* We only need version numbers for symbols defined in regular
+ objects. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ return true;
+
+ p = strchr (h->root.root.string, ELF_VER_CHR);
+ if (p != NULL && h->verinfo.vertree == NULL)
+ {
+ struct bfd_elf_version_tree *t;
+ boolean hidden;
+
+ hidden = true;
+
+ /* There are two consecutive ELF_VER_CHR characters if this is
+ not a hidden symbol. */
+ ++p;
+ if (*p == ELF_VER_CHR)
+ {
+ hidden = false;
+ ++p;
+ }
+
+ /* If there is no version string, we can just return out. */
+ if (*p == '\0')
+ {
+ if (hidden)
+ h->elf_link_hash_flags |= ELF_LINK_HIDDEN;
+ return true;
+ }
+
+ /* Look for the version. If we find it, it is no longer weak. */
+ for (t = sinfo->verdefs; t != NULL; t = t->next)
+ {
+ if (strcmp (t->name, p) == 0)
+ {
+ int len;
+ char *alc;
+ struct bfd_elf_version_expr *d;
+
+ len = p - h->root.root.string;
+ alc = bfd_alloc (sinfo->output_bfd, len);
+ if (alc == NULL)
+ return false;
+ strncpy (alc, h->root.root.string, len - 1);
+ alc[len - 1] = '\0';
+ if (alc[len - 2] == ELF_VER_CHR)
+ alc[len - 2] = '\0';
+
+ h->verinfo.vertree = t;
+ t->used = true;
+ d = NULL;
+
+ if (t->globals != NULL)
+ {
+ for (d = t->globals; d != NULL; d = d->next)
+ if ((*d->match) (d, alc))
+ break;
+ }
+
+ /* See if there is anything to force this symbol to
+ local scope. */
+ if (d == NULL && t->locals != NULL)
+ {
+ for (d = t->locals; d != NULL; d = d->next)
+ {
+ if ((*d->match) (d, alc))
+ {
+ if (h->dynindx != -1
+ && info->shared
+ && ! sinfo->export_dynamic)
+ {
+ sinfo->removed_dynamic = true;
+ h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+ h->elf_link_hash_flags &=~
+ ELF_LINK_HASH_NEEDS_PLT;
+ h->dynindx = -1;
+ h->plt.offset = (bfd_vma) -1;
+ /* FIXME: The name of the symbol has
+ already been recorded in the dynamic
+ string table section. */
+ }
+
+ break;
+ }
+ }
+ }
+
+ bfd_release (sinfo->output_bfd, alc);
+ break;
+ }
+ }
+
+ /* If we are building an application, we need to create a
+ version node for this version. */
+ if (t == NULL && ! info->shared)
+ {
+ struct bfd_elf_version_tree **pp;
+ int version_index;
+
+ /* If we aren't going to export this symbol, we don't need
+ to worry about it. */
+ if (h->dynindx == -1)
+ return true;
+
+ t = ((struct bfd_elf_version_tree *)
+ bfd_alloc (sinfo->output_bfd, sizeof *t));
+ if (t == NULL)
+ {
+ sinfo->failed = true;
+ return false;
+ }
+
+ t->next = NULL;
+ t->name = p;
+ t->globals = NULL;
+ t->locals = NULL;
+ t->deps = NULL;
+ t->name_indx = (unsigned int) -1;
+ t->used = true;
+
+ version_index = 1;
+ for (pp = &sinfo->verdefs; *pp != NULL; pp = &(*pp)->next)
+ ++version_index;
+ t->vernum = version_index;
+
+ *pp = t;
+
+ h->verinfo.vertree = t;
+ }
+ else if (t == NULL)
+ {
+ /* We could not find the version for a symbol when
+ generating a shared archive. Return an error. */
+ (*_bfd_error_handler)
+ (_("%s: undefined versioned symbol name %s"),
+ bfd_get_filename (sinfo->output_bfd), h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ sinfo->failed = true;
+ return false;
+ }
+
+ if (hidden)
+ h->elf_link_hash_flags |= ELF_LINK_HIDDEN;
+ }
+
+ /* If we don't have a version for this symbol, see if we can find
+ something. */
+ if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL)
+ {
+ struct bfd_elf_version_tree *t;
+ struct bfd_elf_version_tree *deflt;
+ struct bfd_elf_version_expr *d;
+
+ /* See if can find what version this symbol is in. If the
+ symbol is supposed to be local, then don't actually register
+ it. */
+ deflt = NULL;
+ for (t = sinfo->verdefs; t != NULL; t = t->next)
+ {
+ if (t->globals != NULL)
+ {
+ for (d = t->globals; d != NULL; d = d->next)
+ {
+ if ((*d->match) (d, h->root.root.string))
+ {
+ h->verinfo.vertree = t;
+ break;
+ }
+ }
+
+ if (d != NULL)
+ break;
+ }
+
+ if (t->locals != NULL)
+ {
+ for (d = t->locals; d != NULL; d = d->next)
+ {
+ if (d->pattern[0] == '*' && d->pattern[1] == '\0')
+ deflt = t;
+ else if ((*d->match) (d, h->root.root.string))
+ {
+ h->verinfo.vertree = t;
+ if (h->dynindx != -1
+ && info->shared
+ && ! sinfo->export_dynamic)
+ {
+ sinfo->removed_dynamic = true;
+ h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+ h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
+ h->dynindx = -1;
+ h->plt.offset = (bfd_vma) -1;
+ /* FIXME: The name of the symbol has already
+ been recorded in the dynamic string table
+ section. */
+ }
+ break;
+ }
+ }
+
+ if (d != NULL)
+ break;
+ }
+ }
+
+ if (deflt != NULL && h->verinfo.vertree == NULL)
+ {
+ h->verinfo.vertree = deflt;
+ if (h->dynindx != -1
+ && info->shared
+ && ! sinfo->export_dynamic)
+ {
+ sinfo->removed_dynamic = true;
+ h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+ h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
+ h->dynindx = -1;
+ h->plt.offset = (bfd_vma) -1;
+ /* FIXME: The name of the symbol has already been
+ recorded in the dynamic string table section. */
+ }
+ }
+ }
+
+ return true;
+}
+
+/* This function is used to renumber the dynamic symbols, if some of
+ them are removed because they are marked as local. This is called
+ via elf_link_hash_traverse. */
+
+static boolean
+elf_link_renumber_dynsyms (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
+
+ if (h->dynindx != -1)
+ {
+ h->dynindx = elf_hash_table (info)->dynsymcount;
+ ++elf_hash_table (info)->dynsymcount;
+ }
+
+ return true;
+}
+
+/* Final phase of ELF linker. */
+
+/* A structure we use to avoid passing large numbers of arguments. */
+
+struct elf_final_link_info
+{
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* Symbol string table. */
+ struct bfd_strtab_hash *symstrtab;
+ /* .dynsym section. */
+ asection *dynsym_sec;
+ /* .hash section. */
+ asection *hash_sec;
+ /* symbol version section (.gnu.version). */
+ asection *symver_sec;
+ /* Buffer large enough to hold contents of any section. */
+ bfd_byte *contents;
+ /* Buffer large enough to hold external relocs of any section. */
+ PTR external_relocs;
+ /* Buffer large enough to hold internal relocs of any section. */
+ Elf_Internal_Rela *internal_relocs;
+ /* Buffer large enough to hold external local symbols of any input
+ BFD. */
+ Elf_External_Sym *external_syms;
+ /* Buffer large enough to hold internal local symbols of any input
+ BFD. */
+ Elf_Internal_Sym *internal_syms;
+ /* Array large enough to hold a symbol index for each local symbol
+ of any input BFD. */
+ long *indices;
+ /* Array large enough to hold a section pointer for each local
+ symbol of any input BFD. */
+ asection **sections;
+ /* Buffer to hold swapped out symbols. */
+ Elf_External_Sym *symbuf;
+ /* Number of swapped out symbols in buffer. */
+ size_t symbuf_count;
+ /* Number of symbols which fit in symbuf. */
+ size_t symbuf_size;
+};
+
+static boolean elf_link_output_sym
+ PARAMS ((struct elf_final_link_info *, const char *,
+ Elf_Internal_Sym *, asection *));
+static boolean elf_link_flush_output_syms
+ PARAMS ((struct elf_final_link_info *));
+static boolean elf_link_output_extsym
+ PARAMS ((struct elf_link_hash_entry *, PTR));
+static boolean elf_link_input_bfd
+ PARAMS ((struct elf_final_link_info *, bfd *));
+static boolean elf_reloc_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* This struct is used to pass information to elf_link_output_extsym. */
+
+struct elf_outext_info
+{
+ boolean failed;
+ boolean localsyms;
+ struct elf_final_link_info *finfo;
+};
+
+/* Do the final step of an ELF link. */
+
+boolean
+elf_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ boolean dynamic;
+ bfd *dynobj;
+ struct elf_final_link_info finfo;
+ register asection *o;
+ register struct bfd_link_order *p;
+ register bfd *sub;
+ size_t max_contents_size;
+ size_t max_external_reloc_size;
+ size_t max_internal_reloc_count;
+ size_t max_sym_count;
+ file_ptr off;
+ Elf_Internal_Sym elfsym;
+ unsigned int i;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *symstrtab_hdr;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_outext_info eoinfo;
+
+ if (info->shared)
+ abfd->flags |= DYNAMIC;
+
+ dynamic = elf_hash_table (info)->dynamic_sections_created;
+ dynobj = elf_hash_table (info)->dynobj;
+
+ finfo.info = info;
+ finfo.output_bfd = abfd;
+ finfo.symstrtab = elf_stringtab_init ();
+ if (finfo.symstrtab == NULL)
+ return false;
+
+ if (! dynamic)
+ {
+ finfo.dynsym_sec = NULL;
+ finfo.hash_sec = NULL;
+ finfo.symver_sec = NULL;
+ }
+ else
+ {
+ finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym");
+ finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
+ BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL);
+ finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version");
+ /* Note that it is OK if symver_sec is NULL. */
+ }
+
+ finfo.contents = NULL;
+ finfo.external_relocs = NULL;
+ finfo.internal_relocs = NULL;
+ finfo.external_syms = NULL;
+ finfo.internal_syms = NULL;
+ finfo.indices = NULL;
+ finfo.sections = NULL;
+ finfo.symbuf = NULL;
+ finfo.symbuf_count = 0;
+
+ /* Count up the number of relocations we will output for each output
+ section, so that we know the sizes of the reloc sections. We
+ also figure out some maximum sizes. */
+ max_contents_size = 0;
+ max_external_reloc_size = 0;
+ max_internal_reloc_count = 0;
+ max_sym_count = 0;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ ++o->reloc_count;
+ else if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+
+ /* Mark all sections which are to be included in the
+ link. This will normally be every section. We need
+ to do this so that we can identify any sections which
+ the linker has decided to not include. */
+ sec->linker_mark = true;
+
+ if (info->relocateable)
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->_raw_size > max_contents_size)
+ max_contents_size = sec->_raw_size;
+ if (sec->_cooked_size > max_contents_size)
+ max_contents_size = sec->_cooked_size;
+
+ /* We are interested in just local symbols, not all
+ symbols. */
+ if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
+ && (sec->owner->flags & DYNAMIC) == 0)
+ {
+ size_t sym_count;
+
+ if (elf_bad_symtab (sec->owner))
+ sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size
+ / sizeof (Elf_External_Sym));
+ else
+ sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info;
+
+ if (sym_count > max_sym_count)
+ max_sym_count = sym_count;
+
+ if ((sec->flags & SEC_RELOC) != 0)
+ {
+ size_t ext_size;
+
+ ext_size = elf_section_data (sec)->rel_hdr.sh_size;
+ if (ext_size > max_external_reloc_size)
+ max_external_reloc_size = ext_size;
+ if (sec->reloc_count > max_internal_reloc_count)
+ max_internal_reloc_count = sec->reloc_count;
+ }
+ }
+ }
+ }
+
+ if (o->reloc_count > 0)
+ o->flags |= SEC_RELOC;
+ else
+ {
+ /* Explicitly clear the SEC_RELOC flag. The linker tends to
+ set it (this is probably a bug) and if it is set
+ assign_section_numbers will create a reloc section. */
+ o->flags &=~ SEC_RELOC;
+ }
+
+ /* If the SEC_ALLOC flag is not set, force the section VMA to
+ zero. This is done in elf_fake_sections as well, but forcing
+ the VMA to 0 here will ensure that relocs against these
+ sections are handled correctly. */
+ if ((o->flags & SEC_ALLOC) == 0
+ && ! o->user_set_vma)
+ o->vma = 0;
+ }
+
+ /* Figure out the file positions for everything but the symbol table
+ and the relocs. We set symcount to force assign_section_numbers
+ to create a symbol table. */
+ bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1;
+ BFD_ASSERT (! abfd->output_has_begun);
+ if (! _bfd_elf_compute_section_file_positions (abfd, info))
+ goto error_return;
+
+ /* That created the reloc sections. Set their sizes, and assign
+ them file positions, and allocate some buffers. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ Elf_Internal_Shdr *rel_hdr;
+ register struct elf_link_hash_entry **p, **pend;
+
+ rel_hdr = &elf_section_data (o)->rel_hdr;
+
+ rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count;
+
+ /* The contents field must last into write_object_contents,
+ so we allocate it with bfd_alloc rather than malloc. */
+ rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
+ if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
+ goto error_return;
+
+ p = ((struct elf_link_hash_entry **)
+ bfd_malloc (o->reloc_count
+ * sizeof (struct elf_link_hash_entry *)));
+ if (p == NULL && o->reloc_count != 0)
+ goto error_return;
+ elf_section_data (o)->rel_hashes = p;
+ pend = p + o->reloc_count;
+ for (; p < pend; p++)
+ *p = NULL;
+
+ /* Use the reloc_count field as an index when outputting the
+ relocs. */
+ o->reloc_count = 0;
+ }
+ }
+
+ _bfd_elf_assign_file_positions_for_relocs (abfd);
+
+ /* We have now assigned file positions for all the sections except
+ .symtab and .strtab. We start the .symtab section at the current
+ file position, and write directly to it. We build the .strtab
+ section in memory. */
+ bfd_get_symcount (abfd) = 0;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ /* sh_name is set in prep_headers. */
+ symtab_hdr->sh_type = SHT_SYMTAB;
+ symtab_hdr->sh_flags = 0;
+ symtab_hdr->sh_addr = 0;
+ symtab_hdr->sh_size = 0;
+ symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);
+ /* sh_link is set in assign_section_numbers. */
+ /* sh_info is set below. */
+ /* sh_offset is set just below. */
+ symtab_hdr->sh_addralign = 4; /* FIXME: system dependent? */
+
+ off = elf_tdata (abfd)->next_file_pos;
+ off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, true);
+
+ /* Note that at this point elf_tdata (abfd)->next_file_pos is
+ incorrect. We do not yet know the size of the .symtab section.
+ We correct next_file_pos below, after we do know the size. */
+
+ /* Allocate a buffer to hold swapped out symbols. This is to avoid
+ continuously seeking to the right position in the file. */
+ if (! info->keep_memory || max_sym_count < 20)
+ finfo.symbuf_size = 20;
+ else
+ finfo.symbuf_size = max_sym_count;
+ finfo.symbuf = ((Elf_External_Sym *)
+ bfd_malloc (finfo.symbuf_size * sizeof (Elf_External_Sym)));
+ if (finfo.symbuf == NULL)
+ goto error_return;
+
+ /* Start writing out the symbol table. The first symbol is always a
+ dummy symbol. */
+ if (info->strip != strip_all || info->relocateable)
+ {
+ elfsym.st_value = 0;
+ elfsym.st_size = 0;
+ elfsym.st_info = 0;
+ elfsym.st_other = 0;
+ elfsym.st_shndx = SHN_UNDEF;
+ if (! elf_link_output_sym (&finfo, (const char *) NULL,
+ &elfsym, bfd_und_section_ptr))
+ goto error_return;
+ }
+
+#if 0
+ /* Some standard ELF linkers do this, but we don't because it causes
+ bootstrap comparison failures. */
+ /* Output a file symbol for the output file as the second symbol.
+ We output this even if we are discarding local symbols, although
+ I'm not sure if this is correct. */
+ elfsym.st_value = 0;
+ elfsym.st_size = 0;
+ elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
+ elfsym.st_other = 0;
+ elfsym.st_shndx = SHN_ABS;
+ if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd),
+ &elfsym, bfd_abs_section_ptr))
+ goto error_return;
+#endif
+
+ /* Output a symbol for each section. We output these even if we are
+ discarding local symbols, since they are used for relocs. These
+ symbols have no names. We store the index of each one in the
+ index field of the section, so that we can find it again when
+ outputting relocs. */
+ if (info->strip != strip_all || info->relocateable)
+ {
+ elfsym.st_size = 0;
+ elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ elfsym.st_other = 0;
+ for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++)
+ {
+ o = section_from_elf_index (abfd, i);
+ if (o != NULL)
+ o->target_index = bfd_get_symcount (abfd);
+ elfsym.st_shndx = i;
+ if (info->relocateable || o == NULL)
+ elfsym.st_value = 0;
+ else
+ elfsym.st_value = o->vma;
+ if (! elf_link_output_sym (&finfo, (const char *) NULL,
+ &elfsym, o))
+ goto error_return;
+ }
+ }
+
+ /* Allocate some memory to hold information read in from the input
+ files. */
+ finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ finfo.external_relocs = (PTR) bfd_malloc (max_external_reloc_size);
+ finfo.internal_relocs = ((Elf_Internal_Rela *)
+ bfd_malloc (max_internal_reloc_count
+ * sizeof (Elf_Internal_Rela)));
+ finfo.external_syms = ((Elf_External_Sym *)
+ bfd_malloc (max_sym_count
+ * sizeof (Elf_External_Sym)));
+ finfo.internal_syms = ((Elf_Internal_Sym *)
+ bfd_malloc (max_sym_count
+ * sizeof (Elf_Internal_Sym)));
+ finfo.indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
+ finfo.sections = ((asection **)
+ bfd_malloc (max_sym_count * sizeof (asection *)));
+ if ((finfo.contents == NULL && max_contents_size != 0)
+ || (finfo.external_relocs == NULL && max_external_reloc_size != 0)
+ || (finfo.internal_relocs == NULL && max_internal_reloc_count != 0)
+ || (finfo.external_syms == NULL && max_sym_count != 0)
+ || (finfo.internal_syms == NULL && max_sym_count != 0)
+ || (finfo.indices == NULL && max_sym_count != 0)
+ || (finfo.sections == NULL && max_sym_count != 0))
+ goto error_return;
+
+ /* Since ELF permits relocations to be against local symbols, we
+ must have the local symbols available when we do the relocations.
+ Since we would rather only read the local symbols once, and we
+ would rather not keep them in memory, we handle all the
+ relocations for a single input file at the same time.
+
+ Unfortunately, there is no way to know the total number of local
+ symbols until we have seen all of them, and the local symbol
+ indices precede the global symbol indices. This means that when
+ we are generating relocateable output, and we see a reloc against
+ a global symbol, we can not know the symbol index until we have
+ finished examining all the local symbols to see which ones we are
+ going to output. To deal with this, we keep the relocations in
+ memory, and don't output them until the end of the link. This is
+ an unfortunate waste of memory, but I don't see a good way around
+ it. Fortunately, it only happens when performing a relocateable
+ link, which is not the common case. FIXME: If keep_memory is set
+ we could write the relocs out and then read them again; I don't
+ know how bad the memory loss will be. */
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ sub->output_has_begun = false;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour (p->u.indirect.section->owner)
+ == bfd_target_elf_flavour))
+ {
+ sub = p->u.indirect.section->owner;
+ if (! sub->output_has_begun)
+ {
+ if (! elf_link_input_bfd (&finfo, sub))
+ goto error_return;
+ sub->output_has_begun = true;
+ }
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ if (! elf_reloc_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ }
+ }
+
+ /* That wrote out all the local symbols. Finish up the symbol table
+ with the global symbols. */
+
+ if (info->strip != strip_all && info->shared)
+ {
+ /* Output any global symbols that got converted to local in a
+ version script. We do this in a separate step since ELF
+ requires all local symbols to appear prior to any global
+ symbols. FIXME: We should only do this if some global
+ symbols were, in fact, converted to become local. FIXME:
+ Will this work correctly with the Irix 5 linker? */
+ eoinfo.failed = false;
+ eoinfo.finfo = &finfo;
+ eoinfo.localsyms = true;
+ elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
+ (PTR) &eoinfo);
+ if (eoinfo.failed)
+ return false;
+ }
+
+ /* The sh_info field records the index of the first non local
+ symbol. */
+ symtab_hdr->sh_info = bfd_get_symcount (abfd);
+ if (dynamic)
+ elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1;
+
+ /* We get the global symbols from the hash table. */
+ eoinfo.failed = false;
+ eoinfo.localsyms = false;
+ eoinfo.finfo = &finfo;
+ elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
+ (PTR) &eoinfo);
+ if (eoinfo.failed)
+ return false;
+
+ /* Flush all symbols to the file. */
+ if (! elf_link_flush_output_syms (&finfo))
+ return false;
+
+ /* Now we know the size of the symtab section. */
+ off += symtab_hdr->sh_size;
+
+ /* Finish up and write out the symbol string table (.strtab)
+ section. */
+ symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
+ /* sh_name was set in prep_headers. */
+ symstrtab_hdr->sh_type = SHT_STRTAB;
+ symstrtab_hdr->sh_flags = 0;
+ symstrtab_hdr->sh_addr = 0;
+ symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab);
+ symstrtab_hdr->sh_entsize = 0;
+ symstrtab_hdr->sh_link = 0;
+ symstrtab_hdr->sh_info = 0;
+ /* sh_offset is set just below. */
+ symstrtab_hdr->sh_addralign = 1;
+
+ off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, true);
+ elf_tdata (abfd)->next_file_pos = off;
+
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
+ || ! _bfd_stringtab_emit (abfd, finfo.symstrtab))
+ return false;
+ }
+
+ /* Adjust the relocs to have the correct symbol indices. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct elf_link_hash_entry **rel_hash;
+ Elf_Internal_Shdr *rel_hdr;
+
+ if ((o->flags & SEC_RELOC) == 0)
+ continue;
+
+ rel_hash = elf_section_data (o)->rel_hashes;
+ rel_hdr = &elf_section_data (o)->rel_hdr;
+ for (i = 0; i < o->reloc_count; i++, rel_hash++)
+ {
+ if (*rel_hash == NULL)
+ continue;
+
+ BFD_ASSERT ((*rel_hash)->indx >= 0);
+
+ if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
+ {
+ Elf_External_Rel *erel;
+ Elf_Internal_Rel irel;
+
+ erel = (Elf_External_Rel *) rel_hdr->contents + i;
+ elf_swap_reloc_in (abfd, erel, &irel);
+ irel.r_info = ELF_R_INFO ((*rel_hash)->indx,
+ ELF_R_TYPE (irel.r_info));
+ elf_swap_reloc_out (abfd, &irel, erel);
+ }
+ else
+ {
+ Elf_External_Rela *erela;
+ Elf_Internal_Rela irela;
+
+ BFD_ASSERT (rel_hdr->sh_entsize
+ == sizeof (Elf_External_Rela));
+
+ erela = (Elf_External_Rela *) rel_hdr->contents + i;
+ elf_swap_reloca_in (abfd, erela, &irela);
+ irela.r_info = ELF_R_INFO ((*rel_hash)->indx,
+ ELF_R_TYPE (irela.r_info));
+ elf_swap_reloca_out (abfd, &irela, erela);
+ }
+ }
+
+ /* Set the reloc_count field to 0 to prevent write_relocs from
+ trying to swap the relocs out itself. */
+ o->reloc_count = 0;
+ }
+
+ /* If we are linking against a dynamic object, or generating a
+ shared library, finish up the dynamic linking information. */
+ if (dynamic)
+ {
+ Elf_External_Dyn *dyncon, *dynconend;
+
+ /* Fix up .dynamic entries. */
+ o = bfd_get_section_by_name (dynobj, ".dynamic");
+ BFD_ASSERT (o != NULL);
+
+ dyncon = (Elf_External_Dyn *) o->contents;
+ dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ unsigned int type;
+
+ elf_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ /* SVR4 linkers seem to set DT_INIT and DT_FINI based on
+ magic _init and _fini symbols. This is pretty ugly,
+ but we are compatible. */
+ case DT_INIT:
+ name = "_init";
+ goto get_sym;
+ case DT_FINI:
+ name = "_fini";
+ get_sym:
+ {
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name,
+ false, false, true);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ dyn.d_un.d_val = h->root.u.def.value;
+ o = h->root.u.def.section;
+ if (o->output_section != NULL)
+ dyn.d_un.d_val += (o->output_section->vma
+ + o->output_offset);
+ else
+ {
+ /* The symbol is imported from another shared
+ library and does not apply to this one. */
+ dyn.d_un.d_val = 0;
+ }
+
+ elf_swap_dyn_out (dynobj, &dyn, dyncon);
+ }
+ }
+ break;
+
+ case DT_HASH:
+ name = ".hash";
+ goto get_vma;
+ case DT_STRTAB:
+ name = ".dynstr";
+ goto get_vma;
+ case DT_SYMTAB:
+ name = ".dynsym";
+ goto get_vma;
+ case DT_VERDEF:
+ name = ".gnu.version_d";
+ goto get_vma;
+ case DT_VERNEED:
+ name = ".gnu.version_r";
+ goto get_vma;
+ case DT_VERSYM:
+ name = ".gnu.version";
+ get_vma:
+ o = bfd_get_section_by_name (abfd, name);
+ BFD_ASSERT (o != NULL);
+ dyn.d_un.d_ptr = o->vma;
+ elf_swap_dyn_out (dynobj, &dyn, dyncon);
+ break;
+
+ case DT_REL:
+ case DT_RELA:
+ case DT_RELSZ:
+ case DT_RELASZ:
+ if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
+ type = SHT_REL;
+ else
+ type = SHT_RELA;
+ dyn.d_un.d_val = 0;
+ for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = elf_elfsections (abfd)[i];
+ if (hdr->sh_type == type
+ && (hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
+ dyn.d_un.d_val += hdr->sh_size;
+ else
+ {
+ if (dyn.d_un.d_val == 0
+ || hdr->sh_addr < dyn.d_un.d_val)
+ dyn.d_un.d_val = hdr->sh_addr;
+ }
+ }
+ }
+ elf_swap_dyn_out (dynobj, &dyn, dyncon);
+ break;
+ }
+ }
+ }
+
+ /* If we have created any dynamic sections, then output them. */
+ if (dynobj != NULL)
+ {
+ if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info))
+ goto error_return;
+
+ for (o = dynobj->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || o->_raw_size == 0)
+ continue;
+ if ((o->flags & SEC_LINKER_CREATED) == 0)
+ {
+ /* At this point, we are only interested in sections
+ created by elf_link_create_dynamic_sections. */
+ continue;
+ }
+ if ((elf_section_data (o->output_section)->this_hdr.sh_type
+ != SHT_STRTAB)
+ || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
+ {
+ if (! bfd_set_section_contents (abfd, o->output_section,
+ o->contents, o->output_offset,
+ o->_raw_size))
+ goto error_return;
+ }
+ else
+ {
+ file_ptr off;
+
+ /* The contents of the .dynstr section are actually in a
+ stringtab. */
+ off = elf_section_data (o->output_section)->this_hdr.sh_offset;
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || ! _bfd_stringtab_emit (abfd,
+ elf_hash_table (info)->dynstr))
+ goto error_return;
+ }
+ }
+ }
+
+ /* If we have optimized stabs strings, output them. */
+ if (elf_hash_table (info)->stab_info != NULL)
+ {
+ if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info))
+ goto error_return;
+ }
+
+ if (finfo.symstrtab != NULL)
+ _bfd_stringtab_free (finfo.symstrtab);
+ if (finfo.contents != NULL)
+ free (finfo.contents);
+ if (finfo.external_relocs != NULL)
+ free (finfo.external_relocs);
+ if (finfo.internal_relocs != NULL)
+ free (finfo.internal_relocs);
+ if (finfo.external_syms != NULL)
+ free (finfo.external_syms);
+ if (finfo.internal_syms != NULL)
+ free (finfo.internal_syms);
+ if (finfo.indices != NULL)
+ free (finfo.indices);
+ if (finfo.sections != NULL)
+ free (finfo.sections);
+ if (finfo.symbuf != NULL)
+ free (finfo.symbuf);
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_RELOC) != 0
+ && elf_section_data (o)->rel_hashes != NULL)
+ free (elf_section_data (o)->rel_hashes);
+ }
+
+ elf_tdata (abfd)->linker = true;
+
+ return true;
+
+ error_return:
+ if (finfo.symstrtab != NULL)
+ _bfd_stringtab_free (finfo.symstrtab);
+ if (finfo.contents != NULL)
+ free (finfo.contents);
+ if (finfo.external_relocs != NULL)
+ free (finfo.external_relocs);
+ if (finfo.internal_relocs != NULL)
+ free (finfo.internal_relocs);
+ if (finfo.external_syms != NULL)
+ free (finfo.external_syms);
+ if (finfo.internal_syms != NULL)
+ free (finfo.internal_syms);
+ if (finfo.indices != NULL)
+ free (finfo.indices);
+ if (finfo.sections != NULL)
+ free (finfo.sections);
+ if (finfo.symbuf != NULL)
+ free (finfo.symbuf);
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_RELOC) != 0
+ && elf_section_data (o)->rel_hashes != NULL)
+ free (elf_section_data (o)->rel_hashes);
+ }
+
+ return false;
+}
+
+/* Add a symbol to the output symbol table. */
+
+static boolean
+elf_link_output_sym (finfo, name, elfsym, input_sec)
+ struct elf_final_link_info *finfo;
+ const char *name;
+ Elf_Internal_Sym *elfsym;
+ asection *input_sec;
+{
+ boolean (*output_symbol_hook) PARAMS ((bfd *,
+ struct bfd_link_info *info,
+ const char *,
+ Elf_Internal_Sym *,
+ asection *));
+
+ output_symbol_hook = get_elf_backend_data (finfo->output_bfd)->
+ elf_backend_link_output_symbol_hook;
+ if (output_symbol_hook != NULL)
+ {
+ if (! ((*output_symbol_hook)
+ (finfo->output_bfd, finfo->info, name, elfsym, input_sec)))
+ return false;
+ }
+
+ if (name == (const char *) NULL || *name == '\0')
+ elfsym->st_name = 0;
+ else if (input_sec->flags & SEC_EXCLUDE)
+ elfsym->st_name = 0;
+ else
+ {
+ elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab,
+ name, true,
+ false);
+ if (elfsym->st_name == (unsigned long) -1)
+ return false;
+ }
+
+ if (finfo->symbuf_count >= finfo->symbuf_size)
+ {
+ if (! elf_link_flush_output_syms (finfo))
+ return false;
+ }
+
+ elf_swap_symbol_out (finfo->output_bfd, elfsym,
+ (PTR) (finfo->symbuf + finfo->symbuf_count));
+ ++finfo->symbuf_count;
+
+ ++ bfd_get_symcount (finfo->output_bfd);
+
+ return true;
+}
+
+/* Flush the output symbols to the file. */
+
+static boolean
+elf_link_flush_output_syms (finfo)
+ struct elf_final_link_info *finfo;
+{
+ if (finfo->symbuf_count > 0)
+ {
+ Elf_Internal_Shdr *symtab;
+
+ symtab = &elf_tdata (finfo->output_bfd)->symtab_hdr;
+
+ if (bfd_seek (finfo->output_bfd, symtab->sh_offset + symtab->sh_size,
+ SEEK_SET) != 0
+ || (bfd_write ((PTR) finfo->symbuf, finfo->symbuf_count,
+ sizeof (Elf_External_Sym), finfo->output_bfd)
+ != finfo->symbuf_count * sizeof (Elf_External_Sym)))
+ return false;
+
+ symtab->sh_size += finfo->symbuf_count * sizeof (Elf_External_Sym);
+
+ finfo->symbuf_count = 0;
+ }
+
+ return true;
+}
+
+/* Add an external symbol to the symbol table. This is called from
+ the hash table traversal routine. When generating a shared object,
+ we go through the symbol table twice. The first time we output
+ anything that might have been forced to local scope in a version
+ script. The second time we output the symbols that are still
+ global symbols. */
+
+static boolean
+elf_link_output_extsym (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ struct elf_outext_info *eoinfo = (struct elf_outext_info *) data;
+ struct elf_final_link_info *finfo = eoinfo->finfo;
+ boolean strip;
+ Elf_Internal_Sym sym;
+ asection *input_sec;
+
+ /* Decide whether to output this symbol in this pass. */
+ if (eoinfo->localsyms)
+ {
+ if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
+ return true;
+ }
+ else
+ {
+ if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+ return true;
+ }
+
+ /* If we are not creating a shared library, and this symbol is
+ referenced by a shared library but is not defined anywhere, then
+ warn that it is undefined. If we do not do this, the runtime
+ linker will complain that the symbol is undefined when the
+ program is run. We don't have to worry about symbols that are
+ referenced by regular files, because we will already have issued
+ warnings for them. */
+ if (! finfo->info->relocateable
+ && ! (finfo->info->shared
+ && !finfo->info->symbolic
+ && !finfo->info->no_undefined)
+ && h->root.type == bfd_link_hash_undefined
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
+ {
+ if (! ((*finfo->info->callbacks->undefined_symbol)
+ (finfo->info, h->root.root.string, h->root.u.undef.abfd,
+ (asection *) NULL, 0)))
+ {
+ eoinfo->failed = true;
+ return false;
+ }
+ }
+
+ /* We don't want to output symbols that have never been mentioned by
+ a regular file, or that we have been told to strip. However, if
+ h->indx is set to -2, the symbol is used by a reloc and we must
+ output it. */
+ if (h->indx == -2)
+ strip = false;
+ else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+ || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
+ strip = true;
+ else if (finfo->info->strip == strip_all
+ || (finfo->info->strip == strip_some
+ && bfd_hash_lookup (finfo->info->keep_hash,
+ h->root.root.string,
+ false, false) == NULL))
+ strip = true;
+ else
+ strip = false;
+
+ /* If we're stripping it, and it's not a dynamic symbol, there's
+ nothing else to do. */
+ if (strip && h->dynindx == -1)
+ return true;
+
+ sym.st_value = 0;
+ sym.st_size = h->size;
+ sym.st_other = h->other;
+ if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
+ else if (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_defweak)
+ sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
+ else
+ sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type);
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ abort ();
+ return false;
+
+ case bfd_link_hash_undefined:
+ input_sec = bfd_und_section_ptr;
+ sym.st_shndx = SHN_UNDEF;
+ break;
+
+ case bfd_link_hash_undefweak:
+ input_sec = bfd_und_section_ptr;
+ sym.st_shndx = SHN_UNDEF;
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ {
+ input_sec = h->root.u.def.section;
+ if (input_sec->output_section != NULL)
+ {
+ sym.st_shndx =
+ _bfd_elf_section_from_bfd_section (finfo->output_bfd,
+ input_sec->output_section);
+ if (sym.st_shndx == (unsigned short) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%s: could not find output section %s for input section %s"),
+ bfd_get_filename (finfo->output_bfd),
+ input_sec->output_section->name,
+ input_sec->name);
+ eoinfo->failed = true;
+ return false;
+ }
+
+ /* ELF symbols in relocateable files are section relative,
+ but in nonrelocateable files they are virtual
+ addresses. */
+ sym.st_value = h->root.u.def.value + input_sec->output_offset;
+ if (! finfo->info->relocateable)
+ sym.st_value += input_sec->output_section->vma;
+ }
+ else
+ {
+ BFD_ASSERT (input_sec->owner == NULL
+ || (input_sec->owner->flags & DYNAMIC) != 0);
+ sym.st_shndx = SHN_UNDEF;
+ input_sec = bfd_und_section_ptr;
+ }
+ }
+ break;
+
+ case bfd_link_hash_common:
+ input_sec = h->root.u.c.p->section;
+ sym.st_shndx = SHN_COMMON;
+ sym.st_value = 1 << h->root.u.c.p->alignment_power;
+ break;
+
+ case bfd_link_hash_indirect:
+ /* These symbols are created by symbol versioning. They point
+ to the decorated version of the name. For example, if the
+ symbol foo@@GNU_1.2 is the default, which should be used when
+ foo is used with no version, then we add an indirect symbol
+ foo which points to foo@@GNU_1.2. We ignore these symbols,
+ since the indirected symbol is already in the hash table. If
+ the indirect symbol is non-ELF, fall through and output it. */
+ if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) == 0)
+ return true;
+
+ /* Fall through. */
+ case bfd_link_hash_warning:
+ /* We can't represent these symbols in ELF, although a warning
+ symbol may have come from a .gnu.warning.SYMBOL section. We
+ just put the target symbol in the hash table. If the target
+ symbol does not really exist, don't do anything. */
+ if (h->root.u.i.link->type == bfd_link_hash_new)
+ return true;
+ return (elf_link_output_extsym
+ ((struct elf_link_hash_entry *) h->root.u.i.link, data));
+ }
+
+ /* Give the processor backend a chance to tweak the symbol value,
+ and also to finish up anything that needs to be done for this
+ symbol. */
+ if ((h->dynindx != -1
+ || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+ && elf_hash_table (finfo->info)->dynamic_sections_created)
+ {
+ struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (finfo->output_bfd);
+ if (! ((*bed->elf_backend_finish_dynamic_symbol)
+ (finfo->output_bfd, finfo->info, h, &sym)))
+ {
+ eoinfo->failed = true;
+ return false;
+ }
+ }
+
+ /* If we are marking the symbol as undefined, and there are no
+ non-weak references to this symbol from a regular object, then
+ mark the symbol as weak undefined. We can't do this earlier,
+ because it might not be marked as undefined until the
+ finish_dynamic_symbol routine gets through with it. */
+ if (sym.st_shndx == SHN_UNDEF
+ && sym.st_info == ELF_ST_INFO (STB_GLOBAL, h->type)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) == 0)
+ sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
+
+ /* If this symbol should be put in the .dynsym section, then put it
+ there now. We have already know the symbol index. We also fill
+ in the entry in the .hash section. */
+ if (h->dynindx != -1
+ && elf_hash_table (finfo->info)->dynamic_sections_created)
+ {
+ size_t bucketcount;
+ size_t bucket;
+ bfd_byte *bucketpos;
+ bfd_vma chain;
+
+ sym.st_name = h->dynstr_index;
+
+ elf_swap_symbol_out (finfo->output_bfd, &sym,
+ (PTR) (((Elf_External_Sym *)
+ finfo->dynsym_sec->contents)
+ + h->dynindx));
+
+ bucketcount = elf_hash_table (finfo->info)->bucketcount;
+ bucket = h->elf_hash_value % bucketcount;
+ bucketpos = ((bfd_byte *) finfo->hash_sec->contents
+ + (bucket + 2) * (ARCH_SIZE / 8));
+ chain = get_word (finfo->output_bfd, bucketpos);
+ put_word (finfo->output_bfd, h->dynindx, bucketpos);
+ put_word (finfo->output_bfd, chain,
+ ((bfd_byte *) finfo->hash_sec->contents
+ + (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8)));
+
+ if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL)
+ {
+ Elf_Internal_Versym iversym;
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ if (h->verinfo.verdef == NULL)
+ iversym.vs_vers = 0;
+ else
+ iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1;
+ }
+ else
+ {
+ if (h->verinfo.vertree == NULL)
+ iversym.vs_vers = 1;
+ else
+ iversym.vs_vers = h->verinfo.vertree->vernum + 1;
+ }
+
+ if ((h->elf_link_hash_flags & ELF_LINK_HIDDEN) != 0)
+ iversym.vs_vers |= VERSYM_HIDDEN;
+
+ _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym,
+ (((Elf_External_Versym *)
+ finfo->symver_sec->contents)
+ + h->dynindx));
+ }
+ }
+
+ /* If we're stripping it, then it was just a dynamic symbol, and
+ there's nothing else to do. */
+ if (strip)
+ return true;
+
+ h->indx = bfd_get_symcount (finfo->output_bfd);
+
+ if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec))
+ {
+ eoinfo->failed = true;
+ return false;
+ }
+
+ return true;
+}
+
+/* Link an input file into the linker output file. This function
+ handles all the sections and relocations of the input file at once.
+ This is so that we only have to read the local symbols once, and
+ don't have to keep them in memory. */
+
+static boolean
+elf_link_input_bfd (finfo, input_bfd)
+ struct elf_final_link_info *finfo;
+ bfd *input_bfd;
+{
+ boolean (*relocate_section) PARAMS ((bfd *, struct bfd_link_info *,
+ bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *,
+ Elf_Internal_Sym *, asection **));
+ bfd *output_bfd;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t locsymcount;
+ size_t extsymoff;
+ Elf_External_Sym *external_syms;
+ Elf_External_Sym *esym;
+ Elf_External_Sym *esymend;
+ Elf_Internal_Sym *isym;
+ long *pindex;
+ asection **ppsection;
+ asection *o;
+
+ output_bfd = finfo->output_bfd;
+ relocate_section =
+ get_elf_backend_data (output_bfd)->elf_backend_relocate_section;
+
+ /* If this is a dynamic object, we don't want to do anything here:
+ we don't want the local symbols, and we don't want the section
+ contents. */
+ if ((input_bfd->flags & DYNAMIC) != 0)
+ return true;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (elf_bad_symtab (input_bfd))
+ {
+ locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
+ extsymoff = 0;
+ }
+ else
+ {
+ locsymcount = symtab_hdr->sh_info;
+ extsymoff = symtab_hdr->sh_info;
+ }
+
+ /* Read the local symbols. */
+ if (symtab_hdr->contents != NULL)
+ external_syms = (Elf_External_Sym *) symtab_hdr->contents;
+ else if (locsymcount == 0)
+ external_syms = NULL;
+ else
+ {
+ external_syms = finfo->external_syms;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (external_syms, sizeof (Elf_External_Sym),
+ locsymcount, input_bfd)
+ != locsymcount * sizeof (Elf_External_Sym)))
+ return false;
+ }
+
+ /* Swap in the local symbols and write out the ones which we know
+ are going into the output file. */
+ esym = external_syms;
+ esymend = esym + locsymcount;
+ isym = finfo->internal_syms;
+ pindex = finfo->indices;
+ ppsection = finfo->sections;
+ for (; esym < esymend; esym++, isym++, pindex++, ppsection++)
+ {
+ asection *isec;
+ const char *name;
+ Elf_Internal_Sym osym;
+
+ elf_swap_symbol_in (input_bfd, esym, isym);
+ *pindex = -1;
+
+ if (elf_bad_symtab (input_bfd))
+ {
+ if (ELF_ST_BIND (isym->st_info) != STB_LOCAL)
+ {
+ *ppsection = NULL;
+ continue;
+ }
+ }
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ else if (isym->st_shndx > 0 && isym->st_shndx < SHN_LORESERVE)
+ isec = section_from_elf_index (input_bfd, isym->st_shndx);
+ else if (isym->st_shndx == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else
+ {
+ /* Who knows? */
+ isec = NULL;
+ }
+
+ *ppsection = isec;
+
+ /* Don't output the first, undefined, symbol. */
+ if (esym == external_syms)
+ continue;
+
+ /* If we are stripping all symbols, we don't want to output this
+ one. */
+ if (finfo->info->strip == strip_all)
+ continue;
+
+ /* We never output section symbols. Instead, we use the section
+ symbol of the corresponding section in the output file. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ continue;
+
+ /* If we are discarding all local symbols, we don't want to
+ output this one. If we are generating a relocateable output
+ file, then some of the local symbols may be required by
+ relocs; we output them below as we discover that they are
+ needed. */
+ if (finfo->info->discard == discard_all)
+ continue;
+
+ /* If this symbol is defined in a section which we are
+ discarding, we don't need to keep it, but note that
+ linker_mark is only reliable for sections that have contents.
+ For the benefit of the MIPS ELF linker, we check SEC_EXCLUDE
+ as well as linker_mark. */
+ if (isym->st_shndx > 0
+ && isym->st_shndx < SHN_LORESERVE
+ && isec != NULL
+ && ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
+ || (! finfo->info->relocateable
+ && (isec->flags & SEC_EXCLUDE) != 0)))
+ continue;
+
+ /* Get the name of the symbol. */
+ name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link,
+ isym->st_name);
+ if (name == NULL)
+ return false;
+
+ /* See if we are discarding symbols with this name. */
+ if ((finfo->info->strip == strip_some
+ && (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
+ == NULL))
+ || (finfo->info->discard == discard_l
+ && bfd_is_local_label_name (input_bfd, name)))
+ continue;
+
+ /* If we get here, we are going to output this symbol. */
+
+ osym = *isym;
+
+ /* Adjust the section index for the output file. */
+ osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
+ isec->output_section);
+ if (osym.st_shndx == (unsigned short) -1)
+ return false;
+
+ *pindex = bfd_get_symcount (output_bfd);
+
+ /* ELF symbols in relocateable files are section relative, but
+ in executable files they are virtual addresses. Note that
+ this code assumes that all ELF sections have an associated
+ BFD section with a reasonable value for output_offset; below
+ we assume that they also have a reasonable value for
+ output_section. Any special sections must be set up to meet
+ these requirements. */
+ osym.st_value += isec->output_offset;
+ if (! finfo->info->relocateable)
+ osym.st_value += isec->output_section->vma;
+
+ if (! elf_link_output_sym (finfo, name, &osym, isec))
+ return false;
+ }
+
+ /* Relocate the contents of each section. */
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ bfd_byte *contents;
+
+ if (! o->linker_mark)
+ {
+ /* This section was omitted from the link. */
+ continue;
+ }
+
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0))
+ continue;
+
+ if ((o->flags & SEC_LINKER_CREATED) != 0)
+ {
+ /* Section was created by elf_link_create_dynamic_sections
+ or somesuch. */
+ continue;
+ }
+
+ /* Get the contents of the section. They have been cached by a
+ relaxation routine. Note that o is a section in an input
+ file, so the contents field will not have been set by any of
+ the routines which work on output files. */
+ if (elf_section_data (o)->this_hdr.contents != NULL)
+ contents = elf_section_data (o)->this_hdr.contents;
+ else
+ {
+ contents = finfo->contents;
+ if (! bfd_get_section_contents (input_bfd, o, contents,
+ (file_ptr) 0, o->_raw_size))
+ return false;
+ }
+
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ Elf_Internal_Rela *internal_relocs;
+
+ /* Get the swapped relocs. */
+ internal_relocs = (NAME(_bfd_elf,link_read_relocs)
+ (input_bfd, o, finfo->external_relocs,
+ finfo->internal_relocs, false));
+ if (internal_relocs == NULL
+ && o->reloc_count > 0)
+ return false;
+
+ /* Relocate the section by invoking a back end routine.
+
+ The back end routine is responsible for adjusting the
+ section contents as necessary, and (if using Rela relocs
+ and generating a relocateable output file) adjusting the
+ reloc addend as necessary.
+
+ The back end routine does not have to worry about setting
+ the reloc address or the reloc symbol index.
+
+ The back end routine is given a pointer to the swapped in
+ internal symbols, and can access the hash table entries
+ for the external symbols via elf_sym_hashes (input_bfd).
+
+ When generating relocateable output, the back end routine
+ must handle STB_LOCAL/STT_SECTION symbols specially. The
+ output symbol is going to be a section symbol
+ corresponding to the output section, which will require
+ the addend to be adjusted. */
+
+ if (! (*relocate_section) (output_bfd, finfo->info,
+ input_bfd, o, contents,
+ internal_relocs,
+ finfo->internal_syms,
+ finfo->sections))
+ return false;
+
+ if (finfo->info->relocateable)
+ {
+ Elf_Internal_Rela *irela;
+ Elf_Internal_Rela *irelaend;
+ struct elf_link_hash_entry **rel_hash;
+ Elf_Internal_Shdr *input_rel_hdr;
+ Elf_Internal_Shdr *output_rel_hdr;
+
+ /* Adjust the reloc addresses and symbol indices. */
+
+ irela = internal_relocs;
+ irelaend = irela + o->reloc_count;
+ rel_hash = (elf_section_data (o->output_section)->rel_hashes
+ + o->output_section->reloc_count);
+ for (; irela < irelaend; irela++, rel_hash++)
+ {
+ unsigned long r_symndx;
+ Elf_Internal_Sym *isym;
+ asection *sec;
+
+ irela->r_offset += o->output_offset;
+
+ r_symndx = ELF_R_SYM (irela->r_info);
+
+ if (r_symndx == 0)
+ continue;
+
+ if (r_symndx >= locsymcount
+ || (elf_bad_symtab (input_bfd)
+ && finfo->sections[r_symndx] == NULL))
+ {
+ struct elf_link_hash_entry *rh;
+ long indx;
+
+ /* This is a reloc against a global symbol. We
+ have not yet output all the local symbols, so
+ we do not know the symbol index of any global
+ symbol. We set the rel_hash entry for this
+ reloc to point to the global hash table entry
+ for this symbol. The symbol index is then
+ set at the end of elf_bfd_final_link. */
+ indx = r_symndx - extsymoff;
+ rh = elf_sym_hashes (input_bfd)[indx];
+ while (rh->root.type == bfd_link_hash_indirect
+ || rh->root.type == bfd_link_hash_warning)
+ rh = (struct elf_link_hash_entry *) rh->root.u.i.link;
+
+ /* Setting the index to -2 tells
+ elf_link_output_extsym that this symbol is
+ used by a reloc. */
+ BFD_ASSERT (rh->indx < 0);
+ rh->indx = -2;
+
+ *rel_hash = rh;
+
+ continue;
+ }
+
+ /* This is a reloc against a local symbol. */
+
+ *rel_hash = NULL;
+ isym = finfo->internal_syms + r_symndx;
+ sec = finfo->sections[r_symndx];
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ {
+ /* I suppose the backend ought to fill in the
+ section of any STT_SECTION symbol against a
+ processor specific section. If we have
+ discarded a section, the output_section will
+ be the absolute section. */
+ if (sec != NULL
+ && (bfd_is_abs_section (sec)
+ || (sec->output_section != NULL
+ && bfd_is_abs_section (sec->output_section))))
+ r_symndx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ else
+ {
+ r_symndx = sec->output_section->target_index;
+ BFD_ASSERT (r_symndx != 0);
+ }
+ }
+ else
+ {
+ if (finfo->indices[r_symndx] == -1)
+ {
+ unsigned long link;
+ const char *name;
+ asection *osec;
+
+ if (finfo->info->strip == strip_all)
+ {
+ /* You can't do ld -r -s. */
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ /* This symbol was skipped earlier, but
+ since it is needed by a reloc, we
+ must output it now. */
+ link = symtab_hdr->sh_link;
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ link,
+ isym->st_name);
+ if (name == NULL)
+ return false;
+
+ osec = sec->output_section;
+ isym->st_shndx =
+ _bfd_elf_section_from_bfd_section (output_bfd,
+ osec);
+ if (isym->st_shndx == (unsigned short) -1)
+ return false;
+
+ isym->st_value += sec->output_offset;
+ if (! finfo->info->relocateable)
+ isym->st_value += osec->vma;
+
+ finfo->indices[r_symndx] = bfd_get_symcount (output_bfd);
+
+ if (! elf_link_output_sym (finfo, name, isym, sec))
+ return false;
+ }
+
+ r_symndx = finfo->indices[r_symndx];
+ }
+
+ irela->r_info = ELF_R_INFO (r_symndx,
+ ELF_R_TYPE (irela->r_info));
+ }
+
+ /* Swap out the relocs. */
+ input_rel_hdr = &elf_section_data (o)->rel_hdr;
+ output_rel_hdr = &elf_section_data (o->output_section)->rel_hdr;
+ BFD_ASSERT (output_rel_hdr->sh_entsize
+ == input_rel_hdr->sh_entsize);
+ irela = internal_relocs;
+ irelaend = irela + o->reloc_count;
+ if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
+ {
+ Elf_External_Rel *erel;
+
+ erel = ((Elf_External_Rel *) output_rel_hdr->contents
+ + o->output_section->reloc_count);
+ for (; irela < irelaend; irela++, erel++)
+ {
+ Elf_Internal_Rel irel;
+
+ irel.r_offset = irela->r_offset;
+ irel.r_info = irela->r_info;
+ BFD_ASSERT (irela->r_addend == 0);
+ elf_swap_reloc_out (output_bfd, &irel, erel);
+ }
+ }
+ else
+ {
+ Elf_External_Rela *erela;
+
+ BFD_ASSERT (input_rel_hdr->sh_entsize
+ == sizeof (Elf_External_Rela));
+ erela = ((Elf_External_Rela *) output_rel_hdr->contents
+ + o->output_section->reloc_count);
+ for (; irela < irelaend; irela++, erela++)
+ elf_swap_reloca_out (output_bfd, irela, erela);
+ }
+
+ o->output_section->reloc_count += o->reloc_count;
+ }
+ }
+
+ /* Write out the modified section contents. */
+ if (elf_section_data (o)->stab_info == NULL)
+ {
+ if (! (o->flags & SEC_EXCLUDE) &&
+ ! bfd_set_section_contents (output_bfd, o->output_section,
+ contents, o->output_offset,
+ (o->_cooked_size != 0
+ ? o->_cooked_size
+ : o->_raw_size)))
+ return false;
+ }
+ else
+ {
+ if (! (_bfd_write_section_stabs
+ (output_bfd, &elf_hash_table (finfo->info)->stab_info,
+ o, &elf_section_data (o)->stab_info, contents)))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Generate a reloc when linking an ELF file. This is a reloc
+ requested by the linker, and does come from any input file. This
+ is used to build constructor and destructor tables when linking
+ with -Ur. */
+
+static boolean
+elf_reloc_link_order (output_bfd, info, output_section, link_order)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+{
+ reloc_howto_type *howto;
+ long indx;
+ bfd_vma offset;
+ bfd_vma addend;
+ struct elf_link_hash_entry **rel_hash_ptr;
+ Elf_Internal_Shdr *rel_hdr;
+
+ howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ addend = link_order->u.reloc.p->addend;
+
+ /* Figure out the symbol index. */
+ rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
+ + output_section->reloc_count);
+ if (link_order->type == bfd_section_reloc_link_order)
+ {
+ indx = link_order->u.reloc.p->u.section->target_index;
+ BFD_ASSERT (indx != 0);
+ *rel_hash_ptr = NULL;
+ }
+ else
+ {
+ struct elf_link_hash_entry *h;
+
+ /* Treat a reloc against a defined symbol as though it were
+ actually against the section. */
+ h = ((struct elf_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (output_bfd, info,
+ link_order->u.reloc.p->u.name,
+ false, false, true));
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection *section;
+
+ section = h->root.u.def.section;
+ indx = section->output_section->target_index;
+ *rel_hash_ptr = NULL;
+ /* It seems that we ought to add the symbol value to the
+ addend here, but in practice it has already been added
+ because it was passed to constructor_callback. */
+ addend += section->output_section->vma + section->output_offset;
+ }
+ else if (h != NULL)
+ {
+ /* Setting the index to -2 tells elf_link_output_extsym that
+ this symbol is used by a reloc. */
+ h->indx = -2;
+ *rel_hash_ptr = h;
+ indx = 0;
+ }
+ else
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ indx = 0;
+ }
+ }
+
+ /* If this is an inplace reloc, we must write the addend into the
+ object file. */
+ if (howto->partial_inplace && addend != 0)
+ {
+ bfd_size_type size;
+ bfd_reloc_status_type rstat;
+ bfd_byte *buf;
+ boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == (bfd_byte *) NULL)
+ return false;
+ rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
+ switch (rstat)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info,
+ (link_order->type == bfd_section_reloc_link_order
+ ? bfd_section_name (output_bfd,
+ link_order->u.reloc.p->u.section)
+ : link_order->u.reloc.p->u.name),
+ howto->name, addend, (bfd *) NULL, (asection *) NULL,
+ (bfd_vma) 0)))
+ {
+ free (buf);
+ return false;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
+ (file_ptr) link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return false;
+ }
+
+ /* The address of a reloc is relative to the section in a
+ relocateable file, and is a virtual address in an executable
+ file. */
+ offset = link_order->offset;
+ if (! info->relocateable)
+ offset += output_section->vma;
+
+ rel_hdr = &elf_section_data (output_section)->rel_hdr;
+
+ if (rel_hdr->sh_type == SHT_REL)
+ {
+ Elf_Internal_Rel irel;
+ Elf_External_Rel *erel;
+
+ irel.r_offset = offset;
+ irel.r_info = ELF_R_INFO (indx, howto->type);
+ erel = ((Elf_External_Rel *) rel_hdr->contents
+ + output_section->reloc_count);
+ elf_swap_reloc_out (output_bfd, &irel, erel);
+ }
+ else
+ {
+ Elf_Internal_Rela irela;
+ Elf_External_Rela *erela;
+
+ irela.r_offset = offset;
+ irela.r_info = ELF_R_INFO (indx, howto->type);
+ irela.r_addend = addend;
+ erela = ((Elf_External_Rela *) rel_hdr->contents
+ + output_section->reloc_count);
+ elf_swap_reloca_out (output_bfd, &irela, erela);
+ }
+
+ ++output_section->reloc_count;
+
+ return true;
+}
+
+
+/* Allocate a pointer to live in a linker created section. */
+
+boolean
+elf_create_pointer_linker_section (abfd, info, lsect, h, rel)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ elf_linker_section_t *lsect;
+ struct elf_link_hash_entry *h;
+ const Elf_Internal_Rela *rel;
+{
+ elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
+ elf_linker_section_pointers_t *linker_section_ptr;
+ unsigned long r_symndx = ELF_R_SYM (rel->r_info);;
+
+ BFD_ASSERT (lsect != NULL);
+
+ /* Is this a global symbol? */
+ if (h != NULL)
+ {
+ /* Has this symbol already been allocated, if so, our work is done */
+ if (_bfd_elf_find_pointer_linker_section (h->linker_section_pointer,
+ rel->r_addend,
+ lsect->which))
+ return true;
+
+ ptr_linker_section_ptr = &h->linker_section_pointer;
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! elf_link_record_dynamic_symbol (info, h))
+ return false;
+ }
+
+ if (lsect->rel_section)
+ lsect->rel_section->_raw_size += sizeof (Elf_External_Rela);
+ }
+
+ else /* Allocation of a pointer to a local symbol */
+ {
+ elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
+
+ /* Allocate a table to hold the local symbols if first time */
+ if (!ptr)
+ {
+ unsigned int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info;
+ register unsigned int i;
+
+ ptr = (elf_linker_section_pointers_t **)
+ bfd_alloc (abfd, num_symbols * sizeof (elf_linker_section_pointers_t *));
+
+ if (!ptr)
+ return false;
+
+ elf_local_ptr_offsets (abfd) = ptr;
+ for (i = 0; i < num_symbols; i++)
+ ptr[i] = (elf_linker_section_pointers_t *)0;
+ }
+
+ /* Has this symbol already been allocated, if so, our work is done */
+ if (_bfd_elf_find_pointer_linker_section (ptr[r_symndx],
+ rel->r_addend,
+ lsect->which))
+ return true;
+
+ ptr_linker_section_ptr = &ptr[r_symndx];
+
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_<xxx>_RELATIVE reloc so that the
+ dynamic linker can adjust this GOT entry. */
+ BFD_ASSERT (lsect->rel_section != NULL);
+ lsect->rel_section->_raw_size += sizeof (Elf_External_Rela);
+ }
+ }
+
+ /* Allocate space for a pointer in the linker section, and allocate a new pointer record
+ from internal memory. */
+ BFD_ASSERT (ptr_linker_section_ptr != NULL);
+ linker_section_ptr = (elf_linker_section_pointers_t *)
+ bfd_alloc (abfd, sizeof (elf_linker_section_pointers_t));
+
+ if (!linker_section_ptr)
+ return false;
+
+ linker_section_ptr->next = *ptr_linker_section_ptr;
+ linker_section_ptr->addend = rel->r_addend;
+ linker_section_ptr->which = lsect->which;
+ linker_section_ptr->written_address_p = false;
+ *ptr_linker_section_ptr = linker_section_ptr;
+
+#if 0
+ if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset)
+ {
+ linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size + (ARCH_SIZE / 8);
+ lsect->hole_offset += ARCH_SIZE / 8;
+ lsect->sym_offset += ARCH_SIZE / 8;
+ if (lsect->sym_hash) /* Bump up symbol value if needed */
+ {
+ lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8;
+#ifdef DEBUG
+ fprintf (stderr, "Bump up %s by %ld, current value = %ld\n",
+ lsect->sym_hash->root.root.string,
+ (long)ARCH_SIZE / 8,
+ (long)lsect->sym_hash->root.u.def.value);
+#endif
+ }
+ }
+ else
+#endif
+ linker_section_ptr->offset = lsect->section->_raw_size;
+
+ lsect->section->_raw_size += ARCH_SIZE / 8;
+
+#ifdef DEBUG
+ fprintf (stderr, "Create pointer in linker section %s, offset = %ld, section size = %ld\n",
+ lsect->name, (long)linker_section_ptr->offset, (long)lsect->section->_raw_size);
+#endif
+
+ return true;
+}
+
+
+#if ARCH_SIZE==64
+#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_64 (BFD, VAL, ADDR)
+#endif
+#if ARCH_SIZE==32
+#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_32 (BFD, VAL, ADDR)
+#endif
+
+/* Fill in the address for a pointer generated in alinker section. */
+
+bfd_vma
+elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, relocation, rel, relative_reloc)
+ bfd *output_bfd;
+ bfd *input_bfd;
+ struct bfd_link_info *info;
+ elf_linker_section_t *lsect;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ const Elf_Internal_Rela *rel;
+ int relative_reloc;
+{
+ elf_linker_section_pointers_t *linker_section_ptr;
+
+ BFD_ASSERT (lsect != NULL);
+
+ if (h != NULL) /* global symbol */
+ {
+ linker_section_ptr = _bfd_elf_find_pointer_linker_section (h->linker_section_pointer,
+ rel->r_addend,
+ lsect->which);
+
+ BFD_ASSERT (linker_section_ptr != NULL);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && info->symbolic
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+ {
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined
+ locally. We must initialize this entry in the
+ global section.
+
+ When doing a dynamic link, we create a .rela.<xxx>
+ relocation entry to initialize the value. This
+ is done in the finish_dynamic_symbol routine. */
+ if (!linker_section_ptr->written_address_p)
+ {
+ linker_section_ptr->written_address_p = true;
+ bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
+ lsect->section->contents + linker_section_ptr->offset);
+ }
+ }
+ }
+ else /* local symbol */
+ {
+ unsigned long r_symndx = ELF_R_SYM (rel->r_info);
+ BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
+ BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL);
+ linker_section_ptr = _bfd_elf_find_pointer_linker_section (elf_local_ptr_offsets (input_bfd)[r_symndx],
+ rel->r_addend,
+ lsect->which);
+
+ BFD_ASSERT (linker_section_ptr != NULL);
+
+ /* Write out pointer if it hasn't been rewritten out before */
+ if (!linker_section_ptr->written_address_p)
+ {
+ linker_section_ptr->written_address_p = true;
+ bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend,
+ lsect->section->contents + linker_section_ptr->offset);
+
+ if (info->shared)
+ {
+ asection *srel = lsect->rel_section;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a relative reloc for the dynamic linker. */
+ if (!srel)
+ lsect->rel_section = srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
+ lsect->rel_name);
+
+ BFD_ASSERT (srel != NULL);
+
+ outrel.r_offset = (lsect->section->output_section->vma
+ + lsect->section->output_offset
+ + linker_section_ptr->offset);
+ outrel.r_info = ELF_R_INFO (0, relative_reloc);
+ outrel.r_addend = 0;
+ elf_swap_reloca_out (output_bfd, &outrel,
+ (((Elf_External_Rela *)
+ lsect->section->contents)
+ + lsect->section->reloc_count));
+ ++lsect->section->reloc_count;
+ }
+ }
+ }
+
+ relocation = (lsect->section->output_offset
+ + linker_section_ptr->offset
+ - lsect->hole_offset
+ - lsect->sym_offset);
+
+#ifdef DEBUG
+ fprintf (stderr, "Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
+ lsect->name, (long)relocation, (long)relocation);
+#endif
+
+ /* Subtract out the addend, because it will get added back in by the normal
+ processing. */
+ return relocation - linker_section_ptr->addend;
+}
+
+/* Garbage collect unused sections. */
+
+static boolean elf_gc_mark
+ PARAMS ((struct bfd_link_info *info, asection *sec,
+ asection * (*gc_mark_hook)
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *))));
+
+static boolean elf_gc_sweep
+ PARAMS ((struct bfd_link_info *info,
+ boolean (*gc_sweep_hook)
+ PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *o,
+ const Elf_Internal_Rela *relocs))));
+
+static boolean elf_gc_sweep_symbol
+ PARAMS ((struct elf_link_hash_entry *h, PTR idxptr));
+
+static boolean elf_gc_allocate_got_offsets
+ PARAMS ((struct elf_link_hash_entry *h, PTR offarg));
+
+static boolean elf_gc_propagate_vtable_entries_used
+ PARAMS ((struct elf_link_hash_entry *h, PTR dummy));
+
+static boolean elf_gc_smash_unused_vtentry_relocs
+ PARAMS ((struct elf_link_hash_entry *h, PTR dummy));
+
+/* The mark phase of garbage collection. For a given section, mark
+ it, and all the sections which define symbols to which it refers. */
+
+static boolean
+elf_gc_mark (info, sec, gc_mark_hook)
+ struct bfd_link_info *info;
+ asection *sec;
+ asection * (*gc_mark_hook)
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *));
+{
+ boolean ret = true;
+
+ sec->gc_mark = 1;
+
+ /* Look through the section relocs. */
+
+ if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
+ {
+ Elf_Internal_Rela *relstart, *rel, *relend;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ size_t nlocsyms;
+ size_t extsymoff;
+ Elf_External_Sym *locsyms, *freesyms = NULL;
+ bfd *input_bfd = sec->owner;
+
+ /* GCFIXME: how to arrange so that relocs and symbols are not
+ reread continually? */
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ /* Read the local symbols. */
+ if (elf_bad_symtab (input_bfd))
+ {
+ nlocsyms = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
+ extsymoff = 0;
+ }
+ else
+ extsymoff = nlocsyms = symtab_hdr->sh_info;
+ if (symtab_hdr->contents)
+ locsyms = (Elf_External_Sym *) symtab_hdr->contents;
+ else if (nlocsyms == 0)
+ locsyms = NULL;
+ else
+ {
+ locsyms = freesyms =
+ bfd_malloc (nlocsyms * sizeof (Elf_External_Sym));
+ if (freesyms == NULL
+ || bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (locsyms, sizeof (Elf_External_Sym),
+ nlocsyms, input_bfd)
+ != nlocsyms * sizeof (Elf_External_Sym)))
+ {
+ ret = false;
+ goto out1;
+ }
+ }
+
+ /* Read the relocations. */
+ relstart = (NAME(_bfd_elf,link_read_relocs)
+ (sec->owner, sec, NULL, (Elf_Internal_Rela *) NULL,
+ info->keep_memory));
+ if (relstart == NULL)
+ {
+ ret = false;
+ goto out1;
+ }
+ relend = relstart + sec->reloc_count;
+
+ for (rel = relstart; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ asection *rsec;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym s;
+
+ r_symndx = ELF_R_SYM (rel->r_info);
+ if (r_symndx == 0)
+ continue;
+
+ if (elf_bad_symtab (sec->owner))
+ {
+ elf_swap_symbol_in (input_bfd, &locsyms[r_symndx], &s);
+ if (ELF_ST_BIND (s.st_info) == STB_LOCAL)
+ rsec = (*gc_mark_hook)(sec->owner, info, rel, NULL, &s);
+ else
+ {
+ h = sym_hashes[r_symndx - extsymoff];
+ rsec = (*gc_mark_hook)(sec->owner, info, rel, h, NULL);
+ }
+ }
+ else if (r_symndx >= nlocsyms)
+ {
+ h = sym_hashes[r_symndx - extsymoff];
+ rsec = (*gc_mark_hook)(sec->owner, info, rel, h, NULL);
+ }
+ else
+ {
+ elf_swap_symbol_in (input_bfd, &locsyms[r_symndx], &s);
+ rsec = (*gc_mark_hook)(sec->owner, info, rel, NULL, &s);
+ }
+
+ if (rsec && !rsec->gc_mark)
+ if (!elf_gc_mark (info, rsec, gc_mark_hook))
+ {
+ ret = false;
+ goto out2;
+ }
+ }
+
+ out2:
+ if (!info->keep_memory)
+ free (relstart);
+ out1:
+ if (freesyms)
+ free (freesyms);
+ }
+
+ return ret;
+}
+
+/* The sweep phase of garbage collection. Remove all garbage sections. */
+
+static boolean
+elf_gc_sweep (info, gc_sweep_hook)
+ struct bfd_link_info *info;
+ boolean (*gc_sweep_hook)
+ PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *o,
+ const Elf_Internal_Rela *relocs));
+{
+ bfd *sub;
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ asection *o;
+
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ /* Keep special sections. Keep .debug sections. */
+ if ((o->flags & SEC_LINKER_CREATED)
+ || (o->flags & SEC_DEBUGGING))
+ o->gc_mark = 1;
+
+ if (o->gc_mark)
+ continue;
+
+ /* Skip sweeping sections already excluded. */
+ if (o->flags & SEC_EXCLUDE)
+ continue;
+
+ /* Since this is early in the link process, it is simple
+ to remove a section from the output. */
+ o->flags |= SEC_EXCLUDE;
+
+ /* But we also have to update some of the relocation
+ info we collected before. */
+ if (gc_sweep_hook
+ && (o->flags & SEC_RELOC) && o->reloc_count > 0)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ boolean r;
+
+ internal_relocs = (NAME(_bfd_elf,link_read_relocs)
+ (o->owner, o, NULL, NULL, info->keep_memory));
+ if (internal_relocs == NULL)
+ return false;
+
+ r = (*gc_sweep_hook)(o->owner, info, o, internal_relocs);
+
+ if (!info->keep_memory)
+ free (internal_relocs);
+
+ if (!r)
+ return false;
+ }
+ }
+ }
+
+ /* Remove the symbols that were in the swept sections from the dynamic
+ symbol table. GCFIXME: Anyone know how to get them out of the
+ static symbol table as well? */
+ {
+ int i = 0;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_sweep_symbol,
+ (PTR) &i);
+
+ elf_hash_table (info)->dynsymcount = i;
+ }
+
+ return true;
+}
+
+/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */
+
+static boolean
+elf_gc_sweep_symbol (h, idxptr)
+ struct elf_link_hash_entry *h;
+ PTR idxptr;
+{
+ int *idx = (int *) idxptr;
+
+ if (h->dynindx != -1
+ && ((h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || h->root.u.def.section->gc_mark))
+ h->dynindx = (*idx)++;
+
+ return true;
+}
+
+/* Propogate collected vtable information. This is called through
+ elf_link_hash_traverse. */
+
+static boolean
+elf_gc_propagate_vtable_entries_used (h, okp)
+ struct elf_link_hash_entry *h;
+ PTR okp;
+{
+ /* Those that are not vtables. */
+ if (h->vtable_parent == NULL)
+ return true;
+
+ /* Those vtables that do not have parents, we cannot merge. */
+ if (h->vtable_parent == (struct elf_link_hash_entry *) -1)
+ return true;
+
+ /* If we've already been done, exit. */
+ if (h->vtable_entries_used && h->vtable_entries_used[-1])
+ return true;
+
+ /* Make sure the parent's table is up to date. */
+ elf_gc_propagate_vtable_entries_used (h->vtable_parent, okp);
+
+ if (h->vtable_entries_used == NULL)
+ {
+ /* None of this table's entries were referenced. Re-use the
+ parent's table. */
+ h->vtable_entries_used = h->vtable_parent->vtable_entries_used;
+ h->vtable_entries_size = h->vtable_parent->vtable_entries_size;
+ }
+ else
+ {
+ size_t n;
+ boolean *cu, *pu;
+
+ /* Or the parent's entries into ours. */
+ cu = h->vtable_entries_used;
+ cu[-1] = true;
+ pu = h->vtable_parent->vtable_entries_used;
+ if (pu != NULL)
+ {
+ n = h->vtable_parent->vtable_entries_size / FILE_ALIGN;
+ while (--n != 0)
+ {
+ if (*pu) *cu = true;
+ pu++, cu++;
+ }
+ }
+ }
+
+ return true;
+}
+
+static boolean
+elf_gc_smash_unused_vtentry_relocs (h, okp)
+ struct elf_link_hash_entry *h;
+ PTR okp;
+{
+ asection *sec;
+ bfd_vma hstart, hend;
+ Elf_Internal_Rela *relstart, *relend, *rel;
+
+ /* Take care of both those symbols that do not describe vtables as
+ well as those that are not loaded. */
+ if (h->vtable_parent == NULL)
+ return true;
+
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak);
+
+ sec = h->root.u.def.section;
+ hstart = h->root.u.def.value;
+ hend = hstart + h->size;
+
+ relstart = (NAME(_bfd_elf,link_read_relocs)
+ (sec->owner, sec, NULL, (Elf_Internal_Rela *) NULL, true));
+ if (!relstart)
+ return *(boolean *)okp = false;
+ relend = relstart + sec->reloc_count;
+
+ for (rel = relstart; rel < relend; ++rel)
+ if (rel->r_offset >= hstart && rel->r_offset < hend)
+ {
+ /* If the entry is in use, do nothing. */
+ if (h->vtable_entries_used
+ && (rel->r_offset - hstart) < h->vtable_entries_size)
+ {
+ bfd_vma entry = (rel->r_offset - hstart) / FILE_ALIGN;
+ if (h->vtable_entries_used[entry])
+ continue;
+ }
+ /* Otherwise, kill it. */
+ rel->r_offset = rel->r_info = rel->r_addend = 0;
+ }
+
+ return true;
+}
+
+/* Do mark and sweep of unused sections. */
+
+boolean
+elf_gc_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ boolean ok = true;
+ bfd *sub;
+ asection * (*gc_mark_hook)
+ PARAMS ((bfd *abfd, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *h, Elf_Internal_Sym *));
+
+ if (!get_elf_backend_data (abfd)->can_gc_sections
+ || info->relocateable
+ || elf_hash_table (info)->dynamic_sections_created)
+ return true;
+
+ /* Apply transitive closure to the vtable entry usage info. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_propagate_vtable_entries_used,
+ (PTR) &ok);
+ if (!ok)
+ return false;
+
+ /* Kill the vtable relocations that were not used. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_smash_unused_vtentry_relocs,
+ (PTR) &ok);
+ if (!ok)
+ return false;
+
+ /* Grovel through relocs to find out who stays ... */
+
+ gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ asection *o;
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ if (o->flags & SEC_KEEP)
+ if (!elf_gc_mark (info, o, gc_mark_hook))
+ return false;
+ }
+ }
+
+ /* ... and mark SEC_EXCLUDE for those that go. */
+ if (!elf_gc_sweep(info, get_elf_backend_data (abfd)->gc_sweep_hook))
+ return false;
+
+ return true;
+}
+
+/* Called from check_relocs to record the existance of a VTINHERIT reloc. */
+
+boolean
+elf_gc_record_vtinherit (abfd, sec, h, offset)
+ bfd *abfd;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma offset;
+{
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ struct elf_link_hash_entry **search, *child;
+ bfd_size_type extsymcount;
+
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local symbols at
+ this point. */
+ extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size/sizeof (Elf_External_Sym);
+ if (!elf_bad_symtab (abfd))
+ extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info;
+
+ sym_hashes = elf_sym_hashes (abfd);
+ sym_hashes_end = sym_hashes + extsymcount;
+
+ /* Hunt down the child symbol, which is in this section at the same
+ offset as the relocation. */
+ for (search = sym_hashes; search != sym_hashes_end; ++search)
+ {
+ if ((child = *search) != NULL
+ && (child->root.type == bfd_link_hash_defined
+ || child->root.type == bfd_link_hash_defweak)
+ && child->root.u.def.section == sec
+ && child->root.u.def.value == offset)
+ goto win;
+ }
+
+ (*_bfd_error_handler) ("%s: %s+%lu: No symbol found for INHERIT",
+ bfd_get_filename (abfd), sec->name,
+ (unsigned long)offset);
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+
+win:
+ if (!h)
+ {
+ /* This *should* only be the absolute section. It could potentially
+ be that someone has defined a non-global vtable though, which
+ would be bad. It isn't worth paging in the local symbols to be
+ sure though; that case should simply be handled by the assembler. */
+
+ child->vtable_parent = (struct elf_link_hash_entry *) -1;
+ }
+ else
+ child->vtable_parent = h;
+
+ return true;
+}
+
+/* Called from check_relocs to record the existance of a VTENTRY reloc. */
+
+boolean
+elf_gc_record_vtentry (abfd, sec, h, addend)
+ bfd *abfd;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma addend;
+{
+ if (addend >= h->vtable_entries_size)
+ {
+ size_t size, bytes;
+ boolean *ptr = h->vtable_entries_used;
+
+ /* While the symbol is undefined, we have to be prepared to handle
+ a zero size. */
+ if (h->root.type == bfd_link_hash_undefined)
+ size = addend;
+ else
+ {
+ size = h->size;
+ if (size < addend)
+ {
+ /* Oops! We've got a reference past the defined end of
+ the table. This is probably a bug -- shall we warn? */
+ size = addend;
+ }
+ }
+
+ /* Allocate one extra entry for use as a "done" flag for the
+ consolidation pass. */
+ bytes = (size / FILE_ALIGN + 1) * sizeof(boolean);
+
+ if (ptr)
+ {
+ size_t oldbytes;
+
+ ptr = realloc (ptr-1, bytes);
+ if (ptr == NULL)
+ return false;
+
+ oldbytes = (h->vtable_entries_size/FILE_ALIGN + 1) * sizeof(boolean);
+ memset (ptr + oldbytes, 0, bytes - oldbytes);
+ }
+ else
+ {
+ ptr = calloc (1, bytes);
+ if (ptr == NULL)
+ return false;
+ }
+
+ /* And arrange for that done flag to be at index -1. */
+ h->vtable_entries_used = ptr+1;
+ h->vtable_entries_size = size;
+ }
+ h->vtable_entries_used[addend / FILE_ALIGN] = true;
+
+ return true;
+}
+
+/* And an accompanying bit to work out final got entry offsets once
+ we're done. Should be called from final_link. */
+
+boolean
+elf_gc_common_finalize_got_offsets (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd *i;
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_vma gotoff;
+
+ /* The GOT offset is relative to the .got section, but the GOT header is
+ put into the .got.plt section, if the backend uses it. */
+ if (bed->want_got_plt)
+ gotoff = 0;
+ else
+ gotoff = bed->got_header_size;
+
+ /* Do the local .got entries first. */
+ for (i = info->input_bfds; i; i = i->link_next)
+ {
+ bfd_signed_vma *local_got = elf_local_got_refcounts (i);
+ bfd_size_type j, locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (i)->symtab_hdr;
+ if (elf_bad_symtab (i))
+ locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
+ else
+ locsymcount = symtab_hdr->sh_info;
+
+ for (j = 0; j < locsymcount; ++j)
+ {
+ if (local_got[j] > 0)
+ {
+ local_got[j] = gotoff;
+ gotoff += ARCH_SIZE / 8;
+ }
+ else
+ local_got[j] = (bfd_vma) -1;
+ }
+ }
+
+ /* Then the global .got and .plt entries. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_allocate_got_offsets,
+ (PTR) &gotoff);
+ return true;
+}
+
+/* We need a special top-level link routine to convert got reference counts
+ to real got offsets. */
+
+static boolean
+elf_gc_allocate_got_offsets (h, offarg)
+ struct elf_link_hash_entry *h;
+ PTR offarg;
+{
+ bfd_vma *off = (bfd_vma *) offarg;
+
+ if (h->got.refcount > 0)
+ {
+ h->got.offset = off[0];
+ off[0] += ARCH_SIZE / 8;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ return true;
+}
+
+/* Many folk need no more in the way of final link than this, once
+ got entry reference counting is enabled. */
+
+boolean
+elf_gc_common_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ if (!elf_gc_common_finalize_got_offsets (abfd, info))
+ return false;
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ return elf_bfd_final_link (abfd, info);
+}
+
+/* This function will be called though elf_link_hash_traverse to store
+ all hash value of the exported symbols in an array. */
+
+static boolean
+elf_collect_hash_codes (h, data)
+ struct elf_link_hash_entry *h;
+ PTR data;
+{
+ unsigned long **valuep = (unsigned long **) data;
+ const char *name;
+ char *p;
+ unsigned long ha;
+ char *alc = NULL;
+
+ /* Ignore indirect symbols. These are added by the versioning code. */
+ if (h->dynindx == -1)
+ return true;
+
+ name = h->root.root.string;
+ p = strchr (name, ELF_VER_CHR);
+ if (p != NULL)
+ {
+ alc = bfd_malloc (p - name + 1);
+ memcpy (alc, name, p - name);
+ alc[p - name] = '\0';
+ name = alc;
+ }
+
+ /* Compute the hash value. */
+ ha = bfd_elf_hash (name);
+
+ /* Store the found hash value in the array given as the argument. */
+ *(*valuep)++ = ha;
+
+ /* And store it in the struct so that we can put it in the hash table
+ later. */
+ h->elf_hash_value = ha;
+
+ if (alc != NULL)
+ free (alc);
+
+ return true;
+}
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
new file mode 100644
index 00000000000..9acabd1e607
--- /dev/null
+++ b/bfd/elfxx-target.h
@@ -0,0 +1,536 @@
+/* Target definitions for NN-bit ELF
+ Copyright 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This structure contains everything that BFD knows about a target.
+ It includes things like its byte order, name, what routines to call
+ to do various operations, etc. Every BFD points to a target structure
+ with its "xvec" member.
+
+ There are two such structures here: one for big-endian machines and
+ one for little-endian machines. */
+
+#define bfd_elfNN_close_and_cleanup _bfd_elf_close_and_cleanup
+#define bfd_elfNN_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#ifndef bfd_elfNN_get_section_contents
+#define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents
+#endif
+
+#define bfd_elfNN_canonicalize_dynamic_symtab _bfd_elf_canonicalize_dynamic_symtab
+#define bfd_elfNN_canonicalize_reloc _bfd_elf_canonicalize_reloc
+#ifndef bfd_elfNN_find_nearest_line
+#define bfd_elfNN_find_nearest_line _bfd_elf_find_nearest_line
+#endif
+#define bfd_elfNN_read_minisymbols _bfd_elf_read_minisymbols
+#define bfd_elfNN_minisymbol_to_symbol _bfd_elf_minisymbol_to_symbol
+#define bfd_elfNN_get_dynamic_symtab_upper_bound _bfd_elf_get_dynamic_symtab_upper_bound
+#define bfd_elfNN_get_lineno _bfd_elf_get_lineno
+#ifndef bfd_elfNN_get_reloc_upper_bound
+#define bfd_elfNN_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound
+#endif
+#define bfd_elfNN_get_symbol_info _bfd_elf_get_symbol_info
+#define bfd_elfNN_get_symtab _bfd_elf_get_symtab
+#define bfd_elfNN_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound
+#if 0 /* done in elf-bfd.h */
+#define bfd_elfNN_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
+#endif
+#define bfd_elfNN_make_empty_symbol _bfd_elf_make_empty_symbol
+#define bfd_elfNN_new_section_hook _bfd_elf_new_section_hook
+#define bfd_elfNN_set_arch_mach _bfd_elf_set_arch_mach
+#ifndef bfd_elfNN_set_section_contents
+#define bfd_elfNN_set_section_contents _bfd_elf_set_section_contents
+#endif
+#define bfd_elfNN_sizeof_headers _bfd_elf_sizeof_headers
+#define bfd_elfNN_write_object_contents _bfd_elf_write_object_contents
+#define bfd_elfNN_write_corefile_contents _bfd_elf_write_corefile_contents
+
+#define bfd_elfNN_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#ifndef elf_backend_got_symbol_offset
+#define elf_backend_got_symbol_offset (bfd_vma) 0
+#endif
+#ifndef elf_backend_want_got_plt
+#define elf_backend_want_got_plt 0
+#endif
+#ifndef elf_backend_plt_readonly
+#define elf_backend_plt_readonly 0
+#endif
+#ifndef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 0
+#endif
+#ifndef elf_backend_plt_not_loaded
+#define elf_backend_plt_not_loaded 0
+#endif
+#ifndef elf_backend_plt_alignment
+#define elf_backend_plt_alignment 2
+#endif
+
+#define bfd_elfNN_bfd_debug_info_start bfd_void
+#define bfd_elfNN_bfd_debug_info_end bfd_void
+#define bfd_elfNN_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
+
+#ifndef bfd_elfNN_bfd_get_relocated_section_contents
+#define bfd_elfNN_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#endif
+
+#ifndef bfd_elfNN_bfd_relax_section
+#define bfd_elfNN_bfd_relax_section bfd_generic_relax_section
+#endif
+
+#ifndef elf_backend_can_gc_sections
+#define elf_backend_can_gc_sections 0
+#endif
+#ifndef elf_backend_gc_mark_hook
+#define elf_backend_gc_mark_hook NULL
+#endif
+#ifndef elf_backend_gc_sweep_hook
+#define elf_backend_gc_sweep_hook NULL
+#endif
+#ifndef bfd_elfNN_bfd_gc_sections
+#define bfd_elfNN_bfd_gc_sections _bfd_elfNN_gc_sections
+#endif
+
+#define bfd_elfNN_bfd_make_debug_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+
+#ifndef bfd_elfNN_bfd_copy_private_symbol_data
+#define bfd_elfNN_bfd_copy_private_symbol_data \
+ _bfd_elf_copy_private_symbol_data
+#endif
+
+#ifndef bfd_elfNN_bfd_copy_private_section_data
+#define bfd_elfNN_bfd_copy_private_section_data \
+ _bfd_elf_copy_private_section_data
+#endif
+#ifndef bfd_elfNN_bfd_copy_private_bfd_data
+#define bfd_elfNN_bfd_copy_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
+#endif
+#ifndef bfd_elfNN_bfd_print_private_bfd_data
+#define bfd_elfNN_bfd_print_private_bfd_data \
+ _bfd_elf_print_private_bfd_data
+#endif
+#ifndef bfd_elfNN_bfd_merge_private_bfd_data
+#define bfd_elfNN_bfd_merge_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
+#endif
+#ifndef bfd_elfNN_bfd_set_private_flags
+#define bfd_elfNN_bfd_set_private_flags \
+ ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true)
+#endif
+#ifndef bfd_elfNN_bfd_is_local_label_name
+#define bfd_elfNN_bfd_is_local_label_name _bfd_elf_is_local_label_name
+#endif
+
+#ifndef bfd_elfNN_get_dynamic_reloc_upper_bound
+#define bfd_elfNN_get_dynamic_reloc_upper_bound \
+ _bfd_elf_get_dynamic_reloc_upper_bound
+#endif
+#ifndef bfd_elfNN_canonicalize_dynamic_reloc
+#define bfd_elfNN_canonicalize_dynamic_reloc \
+ _bfd_elf_canonicalize_dynamic_reloc
+#endif
+
+#ifdef elf_backend_relocate_section
+#ifndef bfd_elfNN_bfd_link_hash_table_create
+#define bfd_elfNN_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
+#endif
+#else /* ! defined (elf_backend_relocate_section) */
+/* If no backend relocate_section routine, use the generic linker. */
+#ifndef bfd_elfNN_bfd_link_hash_table_create
+#define bfd_elfNN_bfd_link_hash_table_create \
+ _bfd_generic_link_hash_table_create
+#endif
+#ifndef bfd_elfNN_bfd_link_add_symbols
+#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#endif
+#ifndef bfd_elfNN_bfd_final_link
+#define bfd_elfNN_bfd_final_link _bfd_generic_final_link
+#endif
+#endif /* ! defined (elf_backend_relocate_section) */
+#ifndef bfd_elfNN_bfd_link_split_section
+#define bfd_elfNN_bfd_link_split_section _bfd_generic_link_split_section
+#endif
+
+#ifndef bfd_elfNN_archive_p
+#define bfd_elfNN_archive_p bfd_generic_archive_p
+#endif
+
+#ifndef bfd_elfNN_write_archive_contents
+#define bfd_elfNN_write_archive_contents _bfd_write_archive_contents
+#endif
+
+#ifndef bfd_elfNN_mkobject
+#define bfd_elfNN_mkobject bfd_elf_mkobject
+#endif
+
+#ifndef bfd_elfNN_mkcorefile
+#define bfd_elfNN_mkcorefile bfd_elf_mkcorefile
+#endif
+
+#ifndef bfd_elfNN_mkarchive
+#define bfd_elfNN_mkarchive _bfd_generic_mkarchive
+#endif
+
+#ifndef elf_symbol_leading_char
+#define elf_symbol_leading_char 0
+#endif
+
+#ifndef elf_info_to_howto
+#define elf_info_to_howto 0
+#endif
+
+#ifndef elf_info_to_howto_rel
+#define elf_info_to_howto_rel 0
+#endif
+
+#ifndef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 1
+#endif
+
+#ifndef elf_backend_collect
+#define elf_backend_collect false
+#endif
+#ifndef elf_backend_type_change_ok
+#define elf_backend_type_change_ok false
+#endif
+
+#ifndef elf_backend_sym_is_global
+#define elf_backend_sym_is_global 0
+#endif
+#ifndef elf_backend_object_p
+#define elf_backend_object_p 0
+#endif
+#ifndef elf_backend_symbol_processing
+#define elf_backend_symbol_processing 0
+#endif
+#ifndef elf_backend_symbol_table_processing
+#define elf_backend_symbol_table_processing 0
+#endif
+#ifndef elf_backend_get_symbol_type
+#define elf_backend_get_symbol_type 0
+#endif
+#ifndef elf_backend_section_processing
+#define elf_backend_section_processing 0
+#endif
+#ifndef elf_backend_section_from_shdr
+#define elf_backend_section_from_shdr 0
+#endif
+#ifndef elf_backend_fake_sections
+#define elf_backend_fake_sections 0
+#endif
+#ifndef elf_backend_section_from_bfd_section
+#define elf_backend_section_from_bfd_section 0
+#endif
+#ifndef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook 0
+#endif
+#ifndef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook 0
+#endif
+#ifndef elf_backend_create_dynamic_sections
+#define elf_backend_create_dynamic_sections 0
+#endif
+#ifndef elf_backend_check_relocs
+#define elf_backend_check_relocs 0
+#endif
+#ifndef elf_backend_adjust_dynamic_symbol
+#define elf_backend_adjust_dynamic_symbol 0
+#endif
+#ifndef elf_backend_always_size_sections
+#define elf_backend_always_size_sections 0
+#endif
+#ifndef elf_backend_size_dynamic_sections
+#define elf_backend_size_dynamic_sections 0
+#endif
+#ifndef elf_backend_relocate_section
+#define elf_backend_relocate_section 0
+#endif
+#ifndef elf_backend_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol 0
+#endif
+#ifndef elf_backend_finish_dynamic_sections
+#define elf_backend_finish_dynamic_sections 0
+#endif
+#ifndef elf_backend_begin_write_processing
+#define elf_backend_begin_write_processing 0
+#endif
+#ifndef elf_backend_final_write_processing
+#define elf_backend_final_write_processing 0
+#endif
+#ifndef elf_backend_additional_program_headers
+#define elf_backend_additional_program_headers 0
+#endif
+#ifndef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map 0
+#endif
+#ifndef elf_backend_ecoff_debug_swap
+#define elf_backend_ecoff_debug_swap 0
+#endif
+#ifndef elf_backend_got_header_size
+#define elf_backend_got_header_size 0
+#endif
+#ifndef elf_backend_plt_header_size
+#define elf_backend_plt_header_size 0
+#endif
+
+#ifndef ELF_MACHINE_ALT1
+#define ELF_MACHINE_ALT1 0
+#endif
+
+#ifndef ELF_MACHINE_ALT2
+#define ELF_MACHINE_ALT2 0
+#endif
+
+#ifndef elf_backend_size_info
+#define elf_backend_size_info _bfd_elfNN_size_info
+#endif
+
+extern const struct elf_size_info _bfd_elfNN_size_info;
+
+static CONST struct elf_backend_data elfNN_bed =
+{
+#ifdef USE_REL
+ 0, /* use_rela_p */
+#else
+ 1, /* use_rela_p */
+#endif
+ ELF_ARCH, /* arch */
+ ELF_MACHINE_CODE, /* elf_machine_code */
+ ELF_MAXPAGESIZE, /* maxpagesize */
+ elf_backend_collect,
+ elf_backend_type_change_ok,
+ elf_info_to_howto,
+ elf_info_to_howto_rel,
+ elf_backend_sym_is_global,
+ elf_backend_object_p,
+ elf_backend_symbol_processing,
+ elf_backend_symbol_table_processing,
+ elf_backend_get_symbol_type,
+ elf_backend_section_processing,
+ elf_backend_section_from_shdr,
+ elf_backend_fake_sections,
+ elf_backend_section_from_bfd_section,
+ elf_backend_add_symbol_hook,
+ elf_backend_link_output_symbol_hook,
+ elf_backend_create_dynamic_sections,
+ elf_backend_check_relocs,
+ elf_backend_adjust_dynamic_symbol,
+ elf_backend_always_size_sections,
+ elf_backend_size_dynamic_sections,
+ elf_backend_relocate_section,
+ elf_backend_finish_dynamic_symbol,
+ elf_backend_finish_dynamic_sections,
+ elf_backend_begin_write_processing,
+ elf_backend_final_write_processing,
+ elf_backend_additional_program_headers,
+ elf_backend_modify_segment_map,
+ elf_backend_gc_mark_hook,
+ elf_backend_gc_sweep_hook,
+ elf_backend_ecoff_debug_swap,
+ ELF_MACHINE_ALT1,
+ ELF_MACHINE_ALT2,
+ &elf_backend_size_info,
+ elf_backend_got_symbol_offset,
+ elf_backend_got_header_size,
+ elf_backend_plt_header_size,
+ elf_backend_want_got_plt,
+ elf_backend_plt_readonly,
+ elf_backend_want_plt_sym,
+ elf_backend_plt_not_loaded,
+ elf_backend_plt_alignment,
+ elf_backend_can_gc_sections
+};
+
+#ifdef TARGET_BIG_SYM
+const bfd_target TARGET_BIG_SYM =
+{
+ /* name: identify kind of target */
+ TARGET_BIG_NAME,
+
+ /* flavour: general indication about file */
+ bfd_target_elf_flavour,
+
+ /* byteorder: data is big endian */
+ BFD_ENDIAN_BIG,
+
+ /* header_byteorder: header is also big endian */
+ BFD_ENDIAN_BIG,
+
+ /* object_flags: mask of all file flags */
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
+ DYNAMIC | WP_TEXT | D_PAGED),
+
+ /* section_flags: mask of all section flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
+ SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES),
+
+ /* leading_symbol_char: is the first char of a user symbol
+ predictable, and if so what is it */
+ elf_symbol_leading_char,
+
+ /* ar_pad_char: pad character for filenames within an archive header
+ FIXME: this really has nothing to do with ELF, this is a characteristic
+ of the archiver and/or os and should be independently tunable */
+ '/',
+
+ /* ar_max_namelen: maximum number of characters in an archive header
+ FIXME: this really has nothing to do with ELF, this is a characteristic
+ of the archiver and should be independently tunable. This value is
+ a WAG (wild a** guess) */
+ 14,
+
+ /* Routines to byte-swap various sized integers from the data sections */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+ /* Routines to byte-swap various sized integers from the file headers */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+ /* bfd_check_format: check the format of a file being read */
+ { _bfd_dummy_target, /* unknown format */
+ bfd_elfNN_object_p, /* assembler/linker output (object file) */
+ bfd_elfNN_archive_p, /* an archive */
+ bfd_elfNN_core_file_p /* a core file */
+ },
+
+ /* bfd_set_format: set the format of a file being written */
+ { bfd_false,
+ bfd_elfNN_mkobject,
+ bfd_elfNN_mkarchive,
+ bfd_elfNN_mkcorefile
+ },
+
+ /* bfd_write_contents: write cached information into a file being written */
+ { bfd_false,
+ bfd_elfNN_write_object_contents,
+ bfd_elfNN_write_archive_contents,
+ bfd_elfNN_write_corefile_contents,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_elfNN),
+ BFD_JUMP_TABLE_COPY (bfd_elfNN),
+ BFD_JUMP_TABLE_CORE (bfd_elfNN),
+#ifdef bfd_elfNN_archive_functions
+ BFD_JUMP_TABLE_ARCHIVE (bfd_elfNN_archive),
+#else
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+#endif
+ BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN),
+ BFD_JUMP_TABLE_RELOCS (bfd_elfNN),
+ BFD_JUMP_TABLE_WRITE (bfd_elfNN),
+ BFD_JUMP_TABLE_LINK (bfd_elfNN),
+ BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN),
+
+ /* backend_data: */
+ (PTR) &elfNN_bed,
+};
+#endif
+
+#ifdef TARGET_LITTLE_SYM
+const bfd_target TARGET_LITTLE_SYM =
+{
+ /* name: identify kind of target */
+ TARGET_LITTLE_NAME,
+
+ /* flavour: general indication about file */
+ bfd_target_elf_flavour,
+
+ /* byteorder: data is little endian */
+ BFD_ENDIAN_LITTLE,
+
+ /* header_byteorder: header is also little endian */
+ BFD_ENDIAN_LITTLE,
+
+ /* object_flags: mask of all file flags */
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
+ DYNAMIC | WP_TEXT | D_PAGED),
+
+ /* section_flags: mask of all section flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
+ SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES),
+
+ /* leading_symbol_char: is the first char of a user symbol
+ predictable, and if so what is it */
+ elf_symbol_leading_char,
+
+ /* ar_pad_char: pad character for filenames within an archive header
+ FIXME: this really has nothing to do with ELF, this is a characteristic
+ of the archiver and/or os and should be independently tunable */
+ '/',
+
+ /* ar_max_namelen: maximum number of characters in an archive header
+ FIXME: this really has nothing to do with ELF, this is a characteristic
+ of the archiver and should be independently tunable. This value is
+ a WAG (wild a** guess) */
+ 14,
+
+ /* Routines to byte-swap various sized integers from the data sections */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+
+ /* Routines to byte-swap various sized integers from the file headers */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+
+ /* bfd_check_format: check the format of a file being read */
+ { _bfd_dummy_target, /* unknown format */
+ bfd_elfNN_object_p, /* assembler/linker output (object file) */
+ bfd_elfNN_archive_p, /* an archive */
+ bfd_elfNN_core_file_p /* a core file */
+ },
+
+ /* bfd_set_format: set the format of a file being written */
+ { bfd_false,
+ bfd_elfNN_mkobject,
+ bfd_elfNN_mkarchive,
+ bfd_elfNN_mkcorefile
+ },
+
+ /* bfd_write_contents: write cached information into a file being written */
+ { bfd_false,
+ bfd_elfNN_write_object_contents,
+ bfd_elfNN_write_archive_contents,
+ bfd_elfNN_write_corefile_contents,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_elfNN),
+ BFD_JUMP_TABLE_COPY (bfd_elfNN),
+ BFD_JUMP_TABLE_CORE (bfd_elfNN),
+#ifdef bfd_elfNN_archive_functions
+ BFD_JUMP_TABLE_ARCHIVE (bfd_elfNN_archive),
+#else
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+#endif
+ BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN),
+ BFD_JUMP_TABLE_RELOCS (bfd_elfNN),
+ BFD_JUMP_TABLE_WRITE (bfd_elfNN),
+ BFD_JUMP_TABLE_LINK (bfd_elfNN),
+ BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN),
+
+ /* backend_data: */
+ (PTR) &elfNN_bed,
+};
+#endif
diff --git a/bfd/epoc-pe-arm.c b/bfd/epoc-pe-arm.c
new file mode 100644
index 00000000000..ea89a0b1257
--- /dev/null
+++ b/bfd/epoc-pe-arm.c
@@ -0,0 +1,30 @@
+/* BFD back-end for ARM EPOC PE files.
+ Copyright 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_UNDERSCORE 0
+#define USER_LABEL_PREFIX ""
+
+#define TARGET_LITTLE_SYM arm_epoc_pe_little_vec
+#define TARGET_LITTLE_NAME "epoc-pe-arm-little"
+#define TARGET_BIG_SYM arm_epoc_pe_big_vec
+#define TARGET_BIG_NAME "epoc-pe-arm-big"
+
+
+#include "pe-arm.c"
+
diff --git a/bfd/epoc-pei-arm.c b/bfd/epoc-pei-arm.c
new file mode 100644
index 00000000000..0f2548d3809
--- /dev/null
+++ b/bfd/epoc-pei-arm.c
@@ -0,0 +1,29 @@
+/* BFD back-end for ARM EPOC PE IMAGE COFF files.
+ Copyright 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_UNDERSCORE 0
+#define USER_LABEL_PREFIX ""
+
+#define TARGET_LITTLE_SYM arm_epoc_pei_little_vec
+#define TARGET_LITTLE_NAME "epoc-pei-arm-little"
+#define TARGET_BIG_SYM arm_epoc_pei_big_vec
+#define TARGET_BIG_NAME "epoc-pei-arm-big"
+
+#include "pei-arm.c"
+
diff --git a/bfd/format.c b/bfd/format.c
new file mode 100644
index 00000000000..c9f1f9cd4be
--- /dev/null
+++ b/bfd/format.c
@@ -0,0 +1,342 @@
+/* Generic BFD support for file formats.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1999 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ File formats
+
+ A format is a BFD concept of high level file contents type. The
+ formats supported by BFD are:
+
+ o <<bfd_object>>
+
+ The BFD may contain data, symbols, relocations and debug info.
+
+ o <<bfd_archive>>
+
+ The BFD contains other BFDs and an optional index.
+
+ o <<bfd_core>>
+
+ The BFD contains the result of an executable core dump.
+
+
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* IMPORT from targets.c. */
+extern const size_t _bfd_target_vector_entries;
+
+/*
+FUNCTION
+ bfd_check_format
+
+SYNOPSIS
+ boolean bfd_check_format(bfd *abfd, bfd_format format);
+
+DESCRIPTION
+ Verify if the file attached to the BFD @var{abfd} is compatible
+ with the format @var{format} (i.e., one of <<bfd_object>>,
+ <<bfd_archive>> or <<bfd_core>>).
+
+ If the BFD has been set to a specific target before the
+ call, only the named target and format combination is
+ checked. If the target has not been set, or has been set to
+ <<default>>, then all the known target backends is
+ interrogated to determine a match. If the default target
+ matches, it is used. If not, exactly one target must recognize
+ the file, or an error results.
+
+ The function returns <<true>> on success, otherwise <<false>>
+ with one of the following error codes:
+
+ o <<bfd_error_invalid_operation>> -
+ if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
+ <<bfd_core>>.
+
+ o <<bfd_error_system_call>> -
+ if an error occured during a read - even some file mismatches
+ can cause bfd_error_system_calls.
+
+ o <<file_not_recognised>> -
+ none of the backends recognised the file format.
+
+ o <<bfd_error_file_ambiguously_recognized>> -
+ more than one backend recognised the file format.
+*/
+
+boolean
+bfd_check_format (abfd, format)
+ bfd *abfd;
+ bfd_format format;
+{
+ return bfd_check_format_matches (abfd, format, NULL);
+}
+
+/*
+FUNCTION
+ bfd_check_format_matches
+
+SYNOPSIS
+ boolean bfd_check_format_matches(bfd *abfd, bfd_format format, char ***matching);
+
+DESCRIPTION
+ Like <<bfd_check_format>>, except when it returns false with
+ <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that
+ case, if @var{matching} is not NULL, it will be filled in with
+ a NULL-terminated list of the names of the formats that matched,
+ allocated with <<malloc>>.
+ Then the user may choose a format and try again.
+
+ When done with the list that @var{matching} points to, the caller
+ should free it.
+*/
+
+boolean
+bfd_check_format_matches (abfd, format, matching)
+ bfd *abfd;
+ bfd_format format;
+ char ***matching;
+{
+ extern const bfd_target binary_vec;
+ const bfd_target * const *target, *save_targ, *right_targ;
+ char **matching_vector = NULL;
+ int match_count;
+
+ if (!bfd_read_p (abfd) ||
+ ((int)(abfd->format) < (int)bfd_unknown) ||
+ ((int)(abfd->format) >= (int)bfd_type_end)) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ if (abfd->format != bfd_unknown)
+ return (abfd->format == format)? true: false;
+
+
+ /* Since the target type was defaulted, check them
+ all in the hope that one will be uniquely recognized. */
+
+ save_targ = abfd->xvec;
+ match_count = 0;
+ if (matching)
+ {
+ matching_vector =
+ (char **) bfd_malloc (sizeof (char *) *
+ (_bfd_target_vector_entries + 1));
+ if (!matching_vector)
+ return false;
+ matching_vector[0] = NULL;
+ *matching = matching_vector;
+ }
+ right_targ = 0;
+
+
+ /* presume the answer is yes */
+ abfd->format = format;
+
+ /* If the target type was explicitly specified, just check that target. */
+
+ if (!abfd->target_defaulted) {
+ if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0) /* rewind! */
+ return false;
+ right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
+ if (right_targ) {
+ abfd->xvec = right_targ; /* Set the target as returned */
+ if (matching)
+ free (matching_vector);
+ return true; /* File position has moved, BTW */
+ }
+
+ /* For a long time the code has dropped through to check all
+ targets if the specified target was wrong. I don't know why,
+ and I'm reluctant to change it. However, in the case of an
+ archive, it can cause problems. If the specified target does
+ not permit archives (e.g., the binary target), then we should
+ not allow some other target to recognize it as an archive, but
+ should instead allow the specified target to recognize it as an
+ object. When I first made this change, it broke the PE target,
+ because the specified pei-i386 target did not recognize the
+ actual pe-i386 archive. Since there may be other problems of
+ this sort, I changed this test to check only for the binary
+ target. */
+
+ if (format == bfd_archive && save_targ == &binary_vec)
+ {
+ abfd->xvec = save_targ;
+ abfd->format = bfd_unknown;
+ if (matching)
+ free (matching_vector);
+ bfd_set_error (bfd_error_file_not_recognized);
+ return false;
+ }
+ }
+
+ for (target = bfd_target_vector; *target != NULL; target++) {
+ const bfd_target *temp;
+
+ if (*target == &binary_vec)
+ continue;
+
+ abfd->xvec = *target; /* Change BFD's target temporarily */
+ if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)
+ return false;
+ /* If _bfd_check_format neglects to set bfd_error, assume bfd_error_wrong_format.
+ We didn't used to even pay any attention to bfd_error, so I suspect
+ that some _bfd_check_format might have this problem. */
+ bfd_set_error (bfd_error_wrong_format);
+ temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
+ if (temp) { /* This format checks out as ok! */
+ right_targ = temp;
+ if (matching)
+ {
+ matching_vector[match_count] = temp->name;
+ matching_vector[match_count + 1] = NULL;
+ }
+ match_count++;
+ /* If this is the default target, accept it, even if other targets
+ might match. People who want those other targets have to set
+ the GNUTARGET variable. */
+ if (temp == bfd_default_vector[0])
+ {
+ if (matching)
+ {
+ matching_vector[0] = temp->name;
+ matching_vector[1] = NULL;
+ }
+ match_count = 1;
+ break;
+ }
+#ifdef GNU960
+ /* Big- and little-endian b.out archives look the same, but it doesn't
+ * matter: there is no difference in their headers, and member file byte
+ * orders will (I hope) be handled appropriately by bfd. Ditto for big
+ * and little coff archives. And the 4 coff/b.out object formats are
+ * unambiguous. So accept the first match we find.
+ */
+ break;
+#endif
+ } else if (bfd_get_error () != bfd_error_wrong_format) {
+ abfd->xvec = save_targ;
+ abfd->format = bfd_unknown;
+ if (matching && bfd_get_error () != bfd_error_file_ambiguously_recognized)
+ free (matching_vector);
+ return false;
+ }
+ }
+
+ if (match_count == 1) {
+ abfd->xvec = right_targ; /* Change BFD's target permanently */
+ if (matching)
+ free (matching_vector);
+ return true; /* File position has moved, BTW */
+ }
+
+ abfd->xvec = save_targ; /* Restore original target type */
+ abfd->format = bfd_unknown; /* Restore original format */
+ if (match_count == 0)
+ {
+ bfd_set_error (bfd_error_file_not_recognized);
+ if (matching)
+ free (matching_vector);
+ }
+ else
+ bfd_set_error (bfd_error_file_ambiguously_recognized);
+ return false;
+}
+
+/*
+FUNCTION
+ bfd_set_format
+
+SYNOPSIS
+ boolean bfd_set_format(bfd *abfd, bfd_format format);
+
+DESCRIPTION
+ This function sets the file format of the BFD @var{abfd} to the
+ format @var{format}. If the target set in the BFD does not
+ support the format requested, the format is invalid, or the BFD
+ is not open for writing, then an error occurs.
+
+*/
+
+boolean
+bfd_set_format (abfd, format)
+ bfd *abfd;
+ bfd_format format;
+{
+
+ if (bfd_read_p (abfd) ||
+ ((int)abfd->format < (int)bfd_unknown) ||
+ ((int)abfd->format >= (int)bfd_type_end)) {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ if (abfd->format != bfd_unknown)
+ return (abfd->format == format) ? true:false;
+
+ /* presume the answer is yes */
+ abfd->format = format;
+
+ if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
+ abfd->format = bfd_unknown;
+ return false;
+ }
+
+ return true;
+}
+
+
+/*
+FUNCTION
+ bfd_format_string
+
+SYNOPSIS
+ CONST char *bfd_format_string(bfd_format format);
+
+DESCRIPTION
+ Return a pointer to a const string
+ <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
+ depending upon the value of @var{format}.
+*/
+
+CONST char *
+bfd_format_string (format)
+ bfd_format format;
+{
+ if (((int)format <(int) bfd_unknown)
+ || ((int)format >=(int) bfd_type_end))
+ return "invalid";
+
+ switch (format) {
+ case bfd_object:
+ return "object"; /* linker/assember/compiler output */
+ case bfd_archive:
+ return "archive"; /* object archive file */
+ case bfd_core:
+ return "core"; /* core dump */
+ default:
+ return "unknown";
+ }
+}
diff --git a/bfd/freebsd.h b/bfd/freebsd.h
new file mode 100644
index 00000000000..8bb19acd7d3
--- /dev/null
+++ b/bfd/freebsd.h
@@ -0,0 +1,110 @@
+/* BFD back-end definitions used by all FreeBSD targets.
+ Copyright (C) 1990, 1991, 1992, 1996 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* FreeBSD ZMAGIC files never have the header in the text. */
+#define N_HEADER_IN_TEXT(x) 0
+
+/* ZMAGIC files start at offset 0. Does not apply to QMAGIC files. */
+#define TEXT_START_ADDR 0
+
+#define N_GETMAGIC_NET(exec) \
+ ((exec).a_info & 0xffff)
+#define N_GETMID_NET(exec) \
+ (((exec).a_info >> 16) & 0x3ff)
+#define N_GETFLAG_NET(ex) \
+ (((exec).a_info >> 26) & 0x3f)
+
+#define N_MACHTYPE(exec) \
+ ((enum machine_type) \
+ ((N_GETMAGIC_NET (exec) == ZMAGIC) ? N_GETMID_NET (exec) : \
+ ((exec).a_info >> 16) & 0x3ff))
+#define N_FLAGS(exec) \
+ ((N_GETMAGIC_NET (exec) == ZMAGIC) ? N_GETFLAG_NET (exec) : \
+ ((exec).a_info >> 26) & 0x3f)
+
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0x3ff) << 16) \
+ | (((flags) & 0x3f) << 26))
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info & 0xfb00ffff) | ((((int)(machtype))&0x3ff) << 16))
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info & 0x03ffffff) | ((flags & 0x03f) << 26))
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+/* On FreeBSD, the magic number is always in i386 (little-endian)
+ format. I think. */
+#define SWAP_MAGIC(ext) bfd_getl32 (ext)
+
+
+#define MY_write_object_contents MY(write_object_contents)
+static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
+
+#include "aout-target.h"
+
+/* Write an object file.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static boolean
+MY(write_object_contents) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+#if CHOOSE_RELOC_SIZE
+ CHOOSE_RELOC_SIZE(abfd);
+#else
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+#endif
+
+ /* Magic number, maestro, please! */
+ switch (bfd_get_arch(abfd)) {
+ case bfd_arch_m68k:
+ if (strcmp (abfd->xvec->name, "a.out-m68k4k-netbsd") == 0)
+ N_SET_MACHTYPE(*execp, M_68K4K_NETBSD);
+ else
+ N_SET_MACHTYPE(*execp, M_68K_NETBSD);
+ break;
+ case bfd_arch_sparc:
+ N_SET_MACHTYPE(*execp, M_SPARC_NETBSD);
+ break;
+ case bfd_arch_i386:
+ N_SET_MACHTYPE(*execp, M_386_NETBSD);
+ break;
+ case bfd_arch_ns32k:
+ N_SET_MACHTYPE(*execp, M_532_NETBSD);
+ break;
+ default:
+ N_SET_MACHTYPE(*execp, M_UNKNOWN);
+ break;
+ }
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
diff --git a/bfd/gen-aout.c b/bfd/gen-aout.c
new file mode 100644
index 00000000000..b5ed91a096b
--- /dev/null
+++ b/bfd/gen-aout.c
@@ -0,0 +1,101 @@
+/* Generate parameters for an a.out system.
+ Copyright (C) 1990, 91, 92, 93, 94, 98 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "/usr/include/a.out.h"
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc; char** argv;
+{
+ struct exec my_exec;
+ int page_size;
+ char *target = "unknown", *arch = "unknown";
+ FILE *file = fopen("gen-aout", "r");
+
+ if (file == NULL) {
+ fprintf(stderr, "Cannot open gen-aout!\n");
+ return -1;
+ }
+ if (fread(&my_exec, sizeof(struct exec), 1, file) != 1) {
+ fprintf(stderr, "Cannot read gen-aout!\n");
+ return -1;
+ }
+
+ target = argv[1];
+ if (target == NULL) {
+ fprintf(stderr, "Usage: gen-aout target_name\n");
+ exit (1);
+ }
+
+#ifdef N_TXTOFF
+ page_size = N_TXTOFF(my_exec);
+ if (page_size == 0)
+ printf("#define N_HEADER_IN_TEXT(x) 1\n");
+ else
+ printf("#define N_HEADER_IN_TEXT(x) 0\n");
+#endif
+
+ printf("#define BYTES_IN_WORD %d\n", sizeof (int));
+ if (my_exec.a_entry == 0) {
+ printf("#define ENTRY_CAN_BE_ZERO\n");
+ printf("#define N_SHARED_LIB(x) 0 /* Avoids warning */\n");
+ }
+ else {
+ printf("/*#define ENTRY_CAN_BE_ZERO*/\n");
+ printf("/*#define N_SHARED_LIB(x) 0*/\n");
+ }
+
+ printf("#define TEXT_START_ADDR %d\n", my_exec.a_entry);
+
+#ifdef PAGSIZ
+ if (page_size == 0)
+ page_size = PAGSIZ;
+#endif
+ if (page_size != 0)
+ printf("#define TARGET_PAGE_SIZE %d\n", page_size);
+ else
+ printf("/* #define TARGET_PAGE_SIZE ??? */\n");
+ printf("#define SEGMENT_SIZE TARGET_PAGE_SIZE\n");
+
+#ifdef vax
+ arch = "vax";
+#endif
+#ifdef m68k
+ arch = "m68k";
+#endif
+ if (arch[0] == '1')
+ {
+ fprintf (stderr, _("warning: preprocessor substituted architecture name inside string;"));
+ fprintf (stderr, _(" fix DEFAULT_ARCH in the output file yourself\n"));
+ arch = "unknown";
+ }
+ printf("#define DEFAULT_ARCH bfd_arch_%s\n", arch);
+
+ printf("\n#define MY(OP) CAT(%s_,OP)\n", target);
+ printf("#define TARGETNAME \"a.out-%s\"\n\n", target);
+
+ printf("#include \"bfd.h\"\n");
+ printf("#include \"sysdep.h\"\n");
+ printf("#include \"libbfd.h\"\n");
+ printf("#include \"libaout.h\"\n");
+ printf("\n#include \"aout-target.h\"\n");
+
+ return 0;
+}
diff --git a/bfd/genlink.h b/bfd/genlink.h
new file mode 100644
index 00000000000..0e0a8de300e
--- /dev/null
+++ b/bfd/genlink.h
@@ -0,0 +1,111 @@
+/* genlink.h -- interface to the BFD generic linker
+ Copyright 1993, 1994 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GENLINK_H
+#define GENLINK_H
+
+/* This header file is internal to BFD. It describes the internal
+ structures and functions used by the BFD generic linker, in case
+ any of the more specific linkers want to use or call them. Note
+ that some functions, such as _bfd_generic_link_hash_table_create,
+ are declared in libbfd.h, because they are expected to be widely
+ used. The functions and structures in this file will probably only
+ be used by a few files besides linker.c itself. In fact, this file
+ is not particularly complete; I have only put in the interfaces I
+ actually needed. */
+
+/* The generic linker uses a hash table which is a derived class of
+ the standard linker hash table, just as the other backend specific
+ linkers do. Do not confuse the generic linker hash table with the
+ standard BFD linker hash table it is built upon. */
+
+/* Generic linker hash table entries. */
+
+struct generic_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+ /* Whether this symbol has been written out. */
+ boolean written;
+ /* Symbol from input BFD. */
+ asymbol *sym;
+};
+
+/* Generic linker hash table. */
+
+struct generic_link_hash_table
+{
+ struct bfd_link_hash_table root;
+};
+
+/* Look up an entry in an generic link hash table. */
+
+#define _bfd_generic_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct generic_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
+
+/* Traverse an generic link hash table. */
+
+#define _bfd_generic_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the generic link hash table from the info structure. This is
+ just a cast. */
+
+#define _bfd_generic_hash_table(p) \
+ ((struct generic_link_hash_table *) ((p)->hash))
+
+/* The generic linker reads in the asymbol structures for an input BFD
+ and keeps them in the outsymbol and symcount fields. */
+
+#define _bfd_generic_link_get_symbols(abfd) ((abfd)->outsymbols)
+#define _bfd_generic_link_get_symcount(abfd) ((abfd)->symcount)
+
+/* Add the symbols of input_bfd to the symbols being built for
+ output_bfd. */
+extern boolean _bfd_generic_link_output_symbols
+ PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *,
+ size_t *psymalloc));
+
+/* This structure is used to pass information to
+ _bfd_generic_link_write_global_symbol, which may be called via
+ _bfd_generic_link_hash_traverse. */
+
+struct generic_write_global_symbol_info
+{
+ struct bfd_link_info *info;
+ bfd *output_bfd;
+ size_t *psymalloc;
+};
+
+/* Write out a single global symbol. This is expected to be called
+ via _bfd_generic_link_hash_traverse. The second argument must
+ actually be a struct generic_write_global_symbol_info *. */
+extern boolean _bfd_generic_link_write_global_symbol
+ PARAMS ((struct generic_link_hash_entry *, PTR));
+
+/* Generic link hash table entry creation routine. */
+struct bfd_hash_entry *_bfd_generic_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *));
+
+#endif
diff --git a/bfd/go32stub.h b/bfd/go32stub.h
new file mode 100644
index 00000000000..3e4388c087b
--- /dev/null
+++ b/bfd/go32stub.h
@@ -0,0 +1,128 @@
+0x4d,0x5a,0x00,0x00,0x04,0x00,0x00,0x00,0x20,0x00,0x27,0x00,0xff,0xff,0x00,0x00,
+0x60,0x07,0x00,0x00,0x54,0x00,0x00,0x00,0x0d,0x0a,0x73,0x74,0x75,0x62,0x2e,0x68,
+0x20,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x66,0x72,0x6f,0x6d,0x20,
+0x73,0x74,0x75,0x62,0x2e,0x61,0x73,0x6d,0x20,0x62,0x79,0x20,0x64,0x6a,0x61,0x73,
+0x6d,0x2c,0x20,0x6f,0x6e,0x20,0x57,0x65,0x64,0x20,0x4a,0x75,0x6e,0x20,0x31,0x31,
+0x20,0x31,0x36,0x3a,0x30,0x39,0x3a,0x31,0x35,0x20,0x31,0x39,0x39,0x37,0x0d,0x0a,
+0x54,0x68,0x65,0x20,0x53,0x54,0x55,0x42,0x2e,0x45,0x58,0x45,0x20,0x73,0x74,0x75,
+0x62,0x20,0x6c,0x6f,0x61,0x64,0x65,0x72,0x20,0x69,0x73,0x20,0x43,0x6f,0x70,0x79,
+0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x43,0x29,0x20,0x31,0x39,0x39,0x33,0x2d,0x31,
+0x39,0x39,0x35,0x20,0x44,0x4a,0x20,0x44,0x65,0x6c,0x6f,0x72,0x69,0x65,0x2e,0x20,
+0x0d,0x0a,0x50,0x65,0x72,0x6d,0x69,0x73,0x73,0x69,0x6f,0x6e,0x20,0x67,0x72,0x61,
+0x6e,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x75,0x73,0x65,0x20,0x66,0x6f,0x72,0x20,
+0x61,0x6e,0x79,0x20,0x70,0x75,0x72,0x70,0x6f,0x73,0x65,0x20,0x70,0x72,0x6f,0x76,
+0x69,0x64,0x65,0x64,0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x6f,0x70,0x79,0x72,0x69,
+0x67,0x68,0x74,0x20,0x0d,0x0a,0x72,0x65,0x6d,0x61,0x69,0x6e,0x73,0x20,0x70,0x72,
+0x65,0x73,0x65,0x6e,0x74,0x20,0x61,0x6e,0x64,0x20,0x75,0x6e,0x6d,0x6f,0x64,0x69,
+0x66,0x69,0x65,0x64,0x2e,0x20,0x0d,0x0a,0x54,0x68,0x69,0x73,0x20,0x6f,0x6e,0x6c,
+0x79,0x20,0x61,0x70,0x70,0x6c,0x69,0x65,0x73,0x20,0x74,0x6f,0x20,0x74,0x68,0x65,
+0x20,0x73,0x74,0x75,0x62,0x2c,0x20,0x61,0x6e,0x64,0x20,0x6e,0x6f,0x74,0x20,0x6e,
+0x65,0x63,0x63,0x65,0x73,0x73,0x61,0x72,0x69,0x6c,0x79,0x20,0x74,0x68,0x65,0x20,
+0x77,0x68,0x6f,0x6c,0x65,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x2e,0x0a,0x0d,
+0x0a,0x24,0x49,0x64,0x3a,0x20,0x73,0x74,0x75,0x62,0x2e,0x61,0x73,0x6d,0x20,0x62,
+0x75,0x69,0x6c,0x74,0x20,0x30,0x36,0x2f,0x31,0x31,0x2f,0x39,0x37,0x20,0x31,0x36,
+0x3a,0x30,0x39,0x3a,0x31,0x35,0x20,0x62,0x79,0x20,0x64,0x6a,0x61,0x73,0x6d,0x20,
+0x24,0x0a,0x0d,0x0a,0x40,0x28,0x23,0x29,0x20,0x73,0x74,0x75,0x62,0x2e,0x61,0x73,
+0x6d,0x20,0x62,0x75,0x69,0x6c,0x74,0x20,0x30,0x36,0x2f,0x31,0x31,0x2f,0x39,0x37,
+0x20,0x31,0x36,0x3a,0x30,0x39,0x3a,0x31,0x35,0x20,0x62,0x79,0x20,0x64,0x6a,0x61,
+0x73,0x6d,0x0a,0x0d,0x0a,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x67,0x6f,0x33,0x32,0x73,0x74,0x75,0x62,0x2c,0x20,0x76,0x20,0x32,0x2e,0x30,0x30,
+0x54,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x43,0x57,0x53,0x44,0x50,0x4d,0x49,0x2e,0x45,0x58,0x45,0x00,
+0x00,0x00,0x00,0x00,0x0e,0x1f,0x8c,0x1e,0x24,0x00,0x8c,0x06,0x60,0x07,0xfc,0xb4,
+0x30,0xcd,0x21,0x3c,0x03,0x73,0x06,0xba,0x86,0x05,0xe9,0xb2,0x03,0xa2,0x69,0x08,
+0xbb,0x70,0x08,0xa1,0x20,0x00,0x39,0xc3,0x73,0x02,0x89,0xc3,0x89,0x1e,0x20,0x00,
+0xfe,0xc7,0xb9,0x04,0xff,0xd3,0xeb,0xb4,0x4a,0xcd,0x21,0x73,0x0a,0xd3,0xe3,0xfe,
+0xcf,0x89,0x1e,0x20,0x00,0xeb,0xd9,0x26,0x8e,0x06,0x2c,0x00,0x31,0xff,0x30,0xc0,
+0xa9,0xf2,0xae,0x26,0x81,0x3d,0x50,0x41,0x75,0x15,0xaf,0x26,0x81,0x3d,0x54,0x48,
+0x75,0x0d,0xaf,0x26,0x80,0x3d,0x3d,0x75,0x06,0x47,0x89,0x3e,0x67,0x04,0x4f,0xae,
+0x75,0xdf,0xaf,0x06,0x57,0x31,0xc9,0x74,0x10,0xba,0x5d,0x05,0xe9,0x50,0x03,0x09,
+0xc9,0x75,0xf6,0x41,0xe8,0x92,0x03,0x72,0xf0,0xb8,0x87,0x16,0xcd,0x2f,0x09,0xc0,
+0x75,0xed,0x80,0xe3,0x01,0x74,0xe8,0x89,0x3e,0x00,0x06,0x8c,0x06,0x02,0x06,0x89,
+0x36,0x04,0x06,0x5f,0x07,0xe8,0xd5,0x02,0x89,0x3e,0x2a,0x00,0x89,0x36,0x62,0x07,
+0x80,0x3e,0x2c,0x00,0x00,0x74,0x24,0xb9,0x08,0x00,0xbf,0x2c,0x00,0x8a,0x05,0x47,
+0x08,0xc0,0x74,0x05,0x88,0x07,0x43,0xe2,0xf4,0x66,0xc7,0x07,0x2e,0x45,0x58,0x45,
+0x81,0xc3,0x04,0x00,0xc6,0x07,0x00,0x89,0x1e,0x62,0x07,0xb8,0x00,0x3d,0xba,0x64,
+0x07,0xcd,0x21,0x0f,0x82,0xb4,0x02,0xa3,0x06,0x06,0x89,0xc3,0xb9,0x06,0x00,0xba,
+0xb5,0x07,0xb4,0x3f,0xcd,0x21,0x31,0xd2,0x31,0xc9,0xa1,0xb5,0x07,0x3d,0x4c,0x01,
+0x74,0x1b,0x3d,0x4d,0x5a,0x0f,0x85,0x97,0x02,0x8b,0x16,0xb9,0x07,0xc1,0xe2,0x09,
+0x8b,0x1e,0xb7,0x07,0x09,0xdb,0x74,0x05,0x80,0xee,0x02,0x01,0xda,0x89,0x16,0xbb,
+0x07,0x89,0x0e,0xbd,0x07,0xb8,0x00,0x42,0x8b,0x1e,0x06,0x06,0xcd,0x21,0xb9,0xa8,
+0x00,0xba,0xbf,0x07,0xb4,0x3f,0xcd,0x21,0x3d,0xa8,0x00,0x75,0x06,0x81,0x3e,0xbf,
+0x07,0x4c,0x01,0x0f,0x85,0x5e,0x02,0x66,0xa1,0xe3,0x07,0x66,0xa3,0x10,0x06,0x66,
+0x8b,0x0e,0xbb,0x07,0x66,0xa1,0x03,0x08,0x66,0x01,0xc8,0x66,0xa3,0x08,0x06,0x66,
+0xa1,0x2b,0x08,0x66,0x01,0xc8,0x66,0xa3,0x0c,0x06,0x66,0x8b,0x1e,0x4b,0x08,0x66,
+0xa1,0x4f,0x08,0x66,0x01,0xc3,0x66,0xb8,0x01,0x00,0x01,0x00,0x66,0x39,0xc3,0x73,
+0x03,0x66,0x89,0xc3,0x66,0x81,0xc3,0xff,0xff,0x00,0x00,0x31,0xdb,0x66,0x89,0x1e,
+0x1c,0x00,0xe8,0xe8,0x02,0x8b,0x1e,0x04,0x06,0x09,0xdb,0x74,0x0a,0xb4,0x48,0xcd,
+0x21,0x0f,0x82,0x10,0x02,0x8e,0xc0,0xe8,0xfb,0x02,0xb8,0x01,0x00,0xff,0x1e,0x00,
+0x06,0x0f,0x82,0x08,0x02,0x8c,0x06,0x26,0x00,0x8c,0x0e,0x28,0x00,0x8c,0xd8,0xa3,
+0x22,0x00,0x8e,0xc0,0x31,0xc0,0xb9,0x01,0x00,0xcd,0x31,0x72,0x07,0xa3,0x14,0x06,
+0x31,0xc0,0xcd,0x31,0x0f,0x82,0xea,0x01,0xa3,0x16,0x06,0x66,0x8b,0x0e,0x1c,0x00,
+0xb8,0x01,0x05,0x8b,0x1e,0x1e,0x00,0xcd,0x31,0x0f,0x82,0xda,0x01,0x89,0x1e,0x1a,
+0x06,0x89,0x0e,0x18,0x06,0x89,0x36,0x1a,0x00,0x89,0x3e,0x18,0x00,0xb8,0x07,0x00,
+0x8b,0x1e,0x14,0x06,0x8b,0x0e,0x1a,0x06,0x8b,0x16,0x18,0x06,0xcd,0x31,0xb8,0x09,
+0x00,0x8c,0xc9,0x81,0xe1,0x03,0x00,0xc1,0xe1,0x05,0x51,0x81,0xc9,0x9b,0xc0,0xcd,
+0x31,0xb8,0x08,0x00,0x8b,0x0e,0x1e,0x00,0x49,0xba,0xff,0xff,0xcd,0x31,0xb8,0x07,
+0x00,0x8b,0x1e,0x16,0x06,0x8b,0x0e,0x1a,0x06,0x8b,0x16,0x18,0x06,0xcd,0x31,0xb8,
+0x09,0x00,0x59,0x81,0xc9,0x93,0xc0,0xcd,0x31,0xb8,0x08,0x00,0x8b,0x0e,0x1e,0x00,
+0x49,0xba,0xff,0xff,0xcd,0x31,0xb8,0x00,0x01,0xbb,0x00,0x0f,0xcd,0x31,0x73,0x10,
+0x3d,0x08,0x00,0x0f,0x85,0x65,0x01,0xb8,0x00,0x01,0xcd,0x31,0x0f,0x82,0x5c,0x01,
+0xa3,0x1c,0x06,0x89,0x16,0x1e,0x06,0xc1,0xe3,0x04,0x89,0x1e,0x20,0x06,0x66,0x8b,
+0x36,0x08,0x06,0x66,0x8b,0x3e,0xfb,0x07,0x66,0x8b,0x0e,0xff,0x07,0xe8,0x49,0x00,
+0x66,0x8b,0x36,0x0c,0x06,0x66,0x8b,0x3e,0x23,0x08,0x66,0x8b,0x0e,0x27,0x08,0xe8,
+0x37,0x00,0x8e,0x06,0x16,0x06,0x66,0x8b,0x3e,0x4b,0x08,0x66,0x8b,0x0e,0x4f,0x08,
+0x66,0x31,0xc0,0x66,0xc1,0xe9,0x02,0x67,0xf3,0x66,0xab,0xb4,0x3e,0x8b,0x1e,0x06,
+0x06,0xcd,0x21,0xb8,0x01,0x01,0x8b,0x16,0x1e,0x06,0xcd,0x31,0x1e,0x0f,0xa1,0x8e,
+0x1e,0x16,0x06,0x66,0x64,0xff,0x2e,0x10,0x06,0x66,0x89,0xf0,0x66,0x25,0xff,0x01,
+0x00,0x00,0x66,0x01,0xc1,0x29,0xc6,0x66,0x29,0xc7,0x66,0x89,0x0e,0x26,0x06,0x66,
+0x89,0x3e,0x22,0x06,0xe8,0xfe,0x00,0x89,0x36,0x3e,0x06,0x66,0xc1,0xee,0x10,0x89,
+0x36,0x42,0x06,0x8b,0x1e,0x06,0x06,0x89,0x1e,0x3a,0x06,0xc7,0x06,0x46,0x06,0x00,
+0x42,0xe8,0xf2,0x00,0xa1,0x1c,0x06,0xa3,0x4e,0x06,0xc7,0x06,0x3e,0x06,0x00,0x00,
+0xc6,0x06,0x47,0x06,0x3f,0xa1,0x28,0x06,0x09,0xc0,0x75,0x09,0xa1,0x26,0x06,0x3b,
+0x06,0x20,0x06,0x76,0x03,0xa1,0x20,0x06,0xa3,0x42,0x06,0xe8,0xc8,0x00,0x66,0x31,
+0xc9,0x8b,0x0e,0x46,0x06,0x66,0x8b,0x3e,0x22,0x06,0x66,0x01,0x0e,0x22,0x06,0x66,
+0x29,0x0e,0x26,0x06,0x66,0x31,0xf6,0xc1,0xe9,0x02,0x1e,0x06,0x8e,0x06,0x16,0x06,
+0x8e,0x1e,0x1e,0x06,0x67,0xf3,0x66,0xa5,0x07,0x1f,0x66,0x03,0x0e,0x26,0x06,0x75,
+0xaf,0xc3,0x3c,0x3a,0x74,0x06,0x3c,0x2f,0x74,0x02,0x3c,0x5c,0xc3,0xbe,0x64,0x07,
+0x89,0xf3,0x26,0x8a,0x05,0x47,0x88,0x04,0x38,0xe0,0x74,0x0e,0x08,0xc0,0x74,0x0a,
+0x46,0xe8,0xde,0xff,0x75,0xec,0x89,0xf3,0x74,0xe8,0xc3,0xba,0x26,0x05,0xeb,0x08,
+0xba,0x34,0x05,0xeb,0x03,0xba,0x3e,0x05,0x52,0x8b,0x1e,0x62,0x07,0xc6,0x07,0x24,
+0xbb,0x64,0x07,0xeb,0x1e,0xe8,0xed,0x00,0xba,0x78,0x05,0xeb,0x12,0xba,0x91,0x05,
+0xeb,0x0d,0xba,0xa3,0x05,0xeb,0x08,0xba,0xb5,0x05,0xeb,0x03,0xba,0x78,0x05,0x52,
+0xbb,0x19,0x05,0xe8,0x14,0x00,0x5b,0xe8,0x10,0x00,0xbb,0x42,0x04,0xe8,0x0a,0x00,
+0xb8,0xff,0x4c,0xcd,0x21,0x43,0xb4,0x02,0xcd,0x21,0x8a,0x17,0x80,0xfa,0x24,0x75,
+0xf4,0xc3,0x0d,0x0a,0x24,0x50,0x51,0x57,0x31,0xc0,0xbf,0x2a,0x06,0xb9,0x19,0x00,
+0xf3,0xab,0x5f,0x59,0x58,0xc3,0xb8,0x00,0x03,0xbb,0x21,0x00,0x31,0xc9,0x66,0xbf,
+0x2a,0x06,0x00,0x00,0xcd,0x31,0xc3,0x00,0x00,0x30,0xe4,0xe8,0x5f,0xff,0x89,0xde,
+0x8b,0x3e,0x67,0x04,0xeb,0x18,0xb4,0x3b,0xe8,0x52,0xff,0x81,0xfe,0x64,0x07,0x74,
+0x13,0x8a,0x84,0xff,0xff,0xe8,0x3a,0xff,0x74,0x04,0xc6,0x04,0x5c,0x46,0xe8,0x03,
+0x00,0x72,0xe3,0xc3,0xe8,0x36,0x00,0xbb,0x44,0x00,0x8a,0x07,0x88,0x04,0x43,0x46,
+0x08,0xc0,0x75,0xf6,0x06,0x57,0x1e,0x07,0xe8,0x9a,0xff,0xbb,0x2a,0x06,0x8c,0x9f,
+0x04,0x00,0x89,0x9f,0x02,0x00,0xba,0x64,0x07,0xb8,0x00,0x4b,0xcd,0x21,0x5f,0x07,
+0x72,0x09,0xb4,0x4d,0xcd,0x21,0x2d,0x00,0x03,0xf7,0xd8,0xeb,0x28,0x80,0x3e,0x69,
+0x08,0x05,0x72,0x20,0xb8,0x00,0x58,0xcd,0x21,0xa2,0x67,0x08,0xb8,0x02,0x58,0xcd,
+0x21,0xa2,0x68,0x08,0xb8,0x01,0x58,0xbb,0x80,0x00,0xcd,0x21,0xb8,0x03,0x58,0xbb,
+0x01,0x00,0xcd,0x21,0xc3,0x9c,0x80,0x3e,0x69,0x08,0x05,0x72,0x1a,0x50,0x53,0xb8,
+0x03,0x58,0x8a,0x1e,0x68,0x08,0x30,0xff,0xcd,0x21,0xb8,0x01,0x58,0x8a,0x1e,0x67,
+0x08,0x30,0xff,0xcd,0x21,0x5b,0x58,0x9d,0xc3,0x4c,0x6f,0x61,0x64,0x20,0x65,0x72,
+0x72,0x6f,0x72,0x3a,0x20,0x24,0x3a,0x20,0x63,0x61,0x6e,0x6e,0x6f,0x74,0x20,0x6f,
+0x70,0x65,0x6e,0x24,0x3a,0x20,0x6e,0x6f,0x74,0x20,0x45,0x58,0x45,0x24,0x3a,0x20,
+0x6e,0x6f,0x74,0x20,0x43,0x4f,0x46,0x46,0x20,0x28,0x43,0x68,0x65,0x63,0x6b,0x20,
+0x66,0x6f,0x72,0x20,0x76,0x69,0x72,0x75,0x73,0x65,0x73,0x29,0x24,0x6e,0x6f,0x20,
+0x44,0x50,0x4d,0x49,0x20,0x2d,0x20,0x47,0x65,0x74,0x20,0x63,0x73,0x64,0x70,0x6d,
+0x69,0x2a,0x62,0x2e,0x7a,0x69,0x70,0x24,0x6e,0x6f,0x20,0x44,0x4f,0x53,0x20,0x6d,
+0x65,0x6d,0x6f,0x72,0x79,0x24,0x6e,0x65,0x65,0x64,0x20,0x44,0x4f,0x53,0x20,0x33,
+0x24,0x63,0x61,0x6e,0x27,0x74,0x20,0x73,0x77,0x69,0x74,0x63,0x68,0x20,0x6d,0x6f,
+0x64,0x65,0x24,0x6e,0x6f,0x20,0x44,0x50,0x4d,0x49,0x20,0x73,0x65,0x6c,0x65,0x63,
+0x74,0x6f,0x72,0x73,0x24,0x6e,0x6f,0x20,0x44,0x50,0x4d,0x49,0x20,0x6d,0x65,0x6d,
+0x6f,0x72,0x79,0x24,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
+0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90
diff --git a/bfd/hash.c b/bfd/hash.c
new file mode 100644
index 00000000000..4c6e9877ce4
--- /dev/null
+++ b/bfd/hash.c
@@ -0,0 +1,734 @@
+/* hash.c -- hash table routines for BFD
+ Copyright (C) 1993, 94, 95, 1997 Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "objalloc.h"
+
+/*
+SECTION
+ Hash Tables
+
+@cindex Hash tables
+ BFD provides a simple set of hash table functions. Routines
+ are provided to initialize a hash table, to free a hash table,
+ to look up a string in a hash table and optionally create an
+ entry for it, and to traverse a hash table. There is
+ currently no routine to delete an string from a hash table.
+
+ The basic hash table does not permit any data to be stored
+ with a string. However, a hash table is designed to present a
+ base class from which other types of hash tables may be
+ derived. These derived types may store additional information
+ with the string. Hash tables were implemented in this way,
+ rather than simply providing a data pointer in a hash table
+ entry, because they were designed for use by the linker back
+ ends. The linker may create thousands of hash table entries,
+ and the overhead of allocating private data and storing and
+ following pointers becomes noticeable.
+
+ The basic hash table code is in <<hash.c>>.
+
+@menu
+@* Creating and Freeing a Hash Table::
+@* Looking Up or Entering a String::
+@* Traversing a Hash Table::
+@* Deriving a New Hash Table Type::
+@end menu
+
+INODE
+Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables
+SUBSECTION
+ Creating and freeing a hash table
+
+@findex bfd_hash_table_init
+@findex bfd_hash_table_init_n
+ To create a hash table, create an instance of a <<struct
+ bfd_hash_table>> (defined in <<bfd.h>>) and call
+ <<bfd_hash_table_init>> (if you know approximately how many
+ entries you will need, the function <<bfd_hash_table_init_n>>,
+ which takes a @var{size} argument, may be used).
+ <<bfd_hash_table_init>> returns <<false>> if some sort of
+ error occurs.
+
+@findex bfd_hash_newfunc
+ The function <<bfd_hash_table_init>> take as an argument a
+ function to use to create new entries. For a basic hash
+ table, use the function <<bfd_hash_newfunc>>. @xref{Deriving
+ a New Hash Table Type} for why you would want to use a
+ different value for this argument.
+
+@findex bfd_hash_allocate
+ <<bfd_hash_table_init>> will create an objalloc which will be
+ used to allocate new entries. You may allocate memory on this
+ objalloc using <<bfd_hash_allocate>>.
+
+@findex bfd_hash_table_free
+ Use <<bfd_hash_table_free>> to free up all the memory that has
+ been allocated for a hash table. This will not free up the
+ <<struct bfd_hash_table>> itself, which you must provide.
+
+INODE
+Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables
+SUBSECTION
+ Looking up or entering a string
+
+@findex bfd_hash_lookup
+ The function <<bfd_hash_lookup>> is used both to look up a
+ string in the hash table and to create a new entry.
+
+ If the @var{create} argument is <<false>>, <<bfd_hash_lookup>>
+ will look up a string. If the string is found, it will
+ returns a pointer to a <<struct bfd_hash_entry>>. If the
+ string is not found in the table <<bfd_hash_lookup>> will
+ return <<NULL>>. You should not modify any of the fields in
+ the returns <<struct bfd_hash_entry>>.
+
+ If the @var{create} argument is <<true>>, the string will be
+ entered into the hash table if it is not already there.
+ Either way a pointer to a <<struct bfd_hash_entry>> will be
+ returned, either to the existing structure or to a newly
+ created one. In this case, a <<NULL>> return means that an
+ error occurred.
+
+ If the @var{create} argument is <<true>>, and a new entry is
+ created, the @var{copy} argument is used to decide whether to
+ copy the string onto the hash table objalloc or not. If
+ @var{copy} is passed as <<false>>, you must be careful not to
+ deallocate or modify the string as long as the hash table
+ exists.
+
+INODE
+Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables
+SUBSECTION
+ Traversing a hash table
+
+@findex bfd_hash_traverse
+ The function <<bfd_hash_traverse>> may be used to traverse a
+ hash table, calling a function on each element. The traversal
+ is done in a random order.
+
+ <<bfd_hash_traverse>> takes as arguments a function and a
+ generic <<void *>> pointer. The function is called with a
+ hash table entry (a <<struct bfd_hash_entry *>>) and the
+ generic pointer passed to <<bfd_hash_traverse>>. The function
+ must return a <<boolean>> value, which indicates whether to
+ continue traversing the hash table. If the function returns
+ <<false>>, <<bfd_hash_traverse>> will stop the traversal and
+ return immediately.
+
+INODE
+Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables
+SUBSECTION
+ Deriving a new hash table type
+
+ Many uses of hash tables want to store additional information
+ which each entry in the hash table. Some also find it
+ convenient to store additional information with the hash table
+ itself. This may be done using a derived hash table.
+
+ Since C is not an object oriented language, creating a derived
+ hash table requires sticking together some boilerplate
+ routines with a few differences specific to the type of hash
+ table you want to create.
+
+ An example of a derived hash table is the linker hash table.
+ The structures for this are defined in <<bfdlink.h>>. The
+ functions are in <<linker.c>>.
+
+ You may also derive a hash table from an already derived hash
+ table. For example, the a.out linker backend code uses a hash
+ table derived from the linker hash table.
+
+@menu
+@* Define the Derived Structures::
+@* Write the Derived Creation Routine::
+@* Write Other Derived Routines::
+@end menu
+
+INODE
+Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type
+SUBSUBSECTION
+ Define the derived structures
+
+ You must define a structure for an entry in the hash table,
+ and a structure for the hash table itself.
+
+ The first field in the structure for an entry in the hash
+ table must be of the type used for an entry in the hash table
+ you are deriving from. If you are deriving from a basic hash
+ table this is <<struct bfd_hash_entry>>, which is defined in
+ <<bfd.h>>. The first field in the structure for the hash
+ table itself must be of the type of the hash table you are
+ deriving from itself. If you are deriving from a basic hash
+ table, this is <<struct bfd_hash_table>>.
+
+ For example, the linker hash table defines <<struct
+ bfd_link_hash_entry>> (in <<bfdlink.h>>). The first field,
+ <<root>>, is of type <<struct bfd_hash_entry>>. Similarly,
+ the first field in <<struct bfd_link_hash_table>>, <<table>>,
+ is of type <<struct bfd_hash_table>>.
+
+INODE
+Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type
+SUBSUBSECTION
+ Write the derived creation routine
+
+ You must write a routine which will create and initialize an
+ entry in the hash table. This routine is passed as the
+ function argument to <<bfd_hash_table_init>>.
+
+ In order to permit other hash tables to be derived from the
+ hash table you are creating, this routine must be written in a
+ standard way.
+
+ The first argument to the creation routine is a pointer to a
+ hash table entry. This may be <<NULL>>, in which case the
+ routine should allocate the right amount of space. Otherwise
+ the space has already been allocated by a hash table type
+ derived from this one.
+
+ After allocating space, the creation routine must call the
+ creation routine of the hash table type it is derived from,
+ passing in a pointer to the space it just allocated. This
+ will initialize any fields used by the base hash table.
+
+ Finally the creation routine must initialize any local fields
+ for the new hash table type.
+
+ Here is a boilerplate example of a creation routine.
+ @var{function_name} is the name of the routine.
+ @var{entry_type} is the type of an entry in the hash table you
+ are creating. @var{base_newfunc} is the name of the creation
+ routine of the hash table type your hash table is derived
+ from.
+
+EXAMPLE
+
+.struct bfd_hash_entry *
+.@var{function_name} (entry, table, string)
+. struct bfd_hash_entry *entry;
+. struct bfd_hash_table *table;
+. const char *string;
+.{
+. struct @var{entry_type} *ret = (@var{entry_type} *) entry;
+.
+. {* Allocate the structure if it has not already been allocated by a
+. derived class. *}
+. if (ret == (@var{entry_type} *) NULL)
+. {
+. ret = ((@var{entry_type} *)
+. bfd_hash_allocate (table, sizeof (@var{entry_type})));
+. if (ret == (@var{entry_type} *) NULL)
+. return NULL;
+. }
+.
+. {* Call the allocation method of the base class. *}
+. ret = ((@var{entry_type} *)
+. @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string));
+.
+. {* Initialize the local fields here. *}
+.
+. return (struct bfd_hash_entry *) ret;
+.}
+
+DESCRIPTION
+ The creation routine for the linker hash table, which is in
+ <<linker.c>>, looks just like this example.
+ @var{function_name} is <<_bfd_link_hash_newfunc>>.
+ @var{entry_type} is <<struct bfd_link_hash_entry>>.
+ @var{base_newfunc} is <<bfd_hash_newfunc>>, the creation
+ routine for a basic hash table.
+
+ <<_bfd_link_hash_newfunc>> also initializes the local fields
+ in a linker hash table entry: <<type>>, <<written>> and
+ <<next>>.
+
+INODE
+Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type
+SUBSUBSECTION
+ Write other derived routines
+
+ You will want to write other routines for your new hash table,
+ as well.
+
+ You will want an initialization routine which calls the
+ initialization routine of the hash table you are deriving from
+ and initializes any other local fields. For the linker hash
+ table, this is <<_bfd_link_hash_table_init>> in <<linker.c>>.
+
+ You will want a lookup routine which calls the lookup routine
+ of the hash table you are deriving from and casts the result.
+ The linker hash table uses <<bfd_link_hash_lookup>> in
+ <<linker.c>> (this actually takes an additional argument which
+ it uses to decide how to return the looked up value).
+
+ You may want a traversal routine. This should just call the
+ traversal routine of the hash table you are deriving from with
+ appropriate casts. The linker hash table uses
+ <<bfd_link_hash_traverse>> in <<linker.c>>.
+
+ These routines may simply be defined as macros. For example,
+ the a.out backend linker hash table, which is derived from the
+ linker hash table, uses macros for the lookup and traversal
+ routines. These are <<aout_link_hash_lookup>> and
+ <<aout_link_hash_traverse>> in aoutx.h.
+*/
+
+/* The default number of entries to use when creating a hash table. */
+#define DEFAULT_SIZE (4051)
+
+/* Create a new hash table, given a number of entries. */
+
+boolean
+bfd_hash_table_init_n (table, newfunc, size)
+ struct bfd_hash_table *table;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+ unsigned int size;
+{
+ unsigned int alloc;
+
+ alloc = size * sizeof (struct bfd_hash_entry *);
+
+ table->memory = (PTR) objalloc_create ();
+ if (table->memory == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ table->table = ((struct bfd_hash_entry **)
+ objalloc_alloc ((struct objalloc *) table->memory, alloc));
+ if (table->table == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ memset ((PTR) table->table, 0, alloc);
+ table->size = size;
+ table->newfunc = newfunc;
+ return true;
+}
+
+/* Create a new hash table with the default number of entries. */
+
+boolean
+bfd_hash_table_init (table, newfunc)
+ struct bfd_hash_table *table;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ return bfd_hash_table_init_n (table, newfunc, DEFAULT_SIZE);
+}
+
+/* Free a hash table. */
+
+void
+bfd_hash_table_free (table)
+ struct bfd_hash_table *table;
+{
+ objalloc_free ((struct objalloc *) table->memory);
+ table->memory = NULL;
+}
+
+/* Look up a string in a hash table. */
+
+struct bfd_hash_entry *
+bfd_hash_lookup (table, string, create, copy)
+ struct bfd_hash_table *table;
+ const char *string;
+ boolean create;
+ boolean copy;
+{
+ register const unsigned char *s;
+ register unsigned long hash;
+ register unsigned int c;
+ struct bfd_hash_entry *hashp;
+ unsigned int len;
+ unsigned int index;
+
+ hash = 0;
+ len = 0;
+ s = (const unsigned char *) string;
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ ++len;
+ }
+ hash += len + (len << 17);
+ hash ^= hash >> 2;
+
+ index = hash % table->size;
+ for (hashp = table->table[index];
+ hashp != (struct bfd_hash_entry *) NULL;
+ hashp = hashp->next)
+ {
+ if (hashp->hash == hash
+ && strcmp (hashp->string, string) == 0)
+ return hashp;
+ }
+
+ if (! create)
+ return (struct bfd_hash_entry *) NULL;
+
+ hashp = (*table->newfunc) ((struct bfd_hash_entry *) NULL, table, string);
+ if (hashp == (struct bfd_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) NULL;
+ if (copy)
+ {
+ char *new;
+
+ new = (char *) objalloc_alloc ((struct objalloc *) table->memory,
+ len + 1);
+ if (!new)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return (struct bfd_hash_entry *) NULL;
+ }
+ strcpy (new, string);
+ string = new;
+ }
+ hashp->string = string;
+ hashp->hash = hash;
+ hashp->next = table->table[index];
+ table->table[index] = hashp;
+
+ return hashp;
+}
+
+/* Replace an entry in a hash table. */
+
+void
+bfd_hash_replace (table, old, nw)
+ struct bfd_hash_table *table;
+ struct bfd_hash_entry *old;
+ struct bfd_hash_entry *nw;
+{
+ unsigned int index;
+ struct bfd_hash_entry **pph;
+
+ index = old->hash % table->size;
+ for (pph = &table->table[index];
+ (*pph) != (struct bfd_hash_entry *) NULL;
+ pph = &(*pph)->next)
+ {
+ if (*pph == old)
+ {
+ *pph = nw;
+ return;
+ }
+ }
+
+ abort ();
+}
+
+/* Base method for creating a new hash table entry. */
+
+/*ARGSUSED*/
+struct bfd_hash_entry *
+bfd_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ if (entry == (struct bfd_hash_entry *) NULL)
+ entry = ((struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct bfd_hash_entry)));
+ return entry;
+}
+
+/* Allocate space in a hash table. */
+
+PTR
+bfd_hash_allocate (table, size)
+ struct bfd_hash_table *table;
+ unsigned int size;
+{
+ PTR ret;
+
+ ret = objalloc_alloc ((struct objalloc *) table->memory, size);
+ if (ret == NULL && size != 0)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
+}
+
+/* Traverse a hash table. */
+
+void
+bfd_hash_traverse (table, func, info)
+ struct bfd_hash_table *table;
+ boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR));
+ PTR info;
+{
+ unsigned int i;
+
+ for (i = 0; i < table->size; i++)
+ {
+ struct bfd_hash_entry *p;
+
+ for (p = table->table[i]; p != NULL; p = p->next)
+ {
+ if (! (*func) (p, info))
+ return;
+ }
+ }
+}
+
+/* A few different object file formats (a.out, COFF, ELF) use a string
+ table. These functions support adding strings to a string table,
+ returning the byte offset, and writing out the table.
+
+ Possible improvements:
+ + look for strings matching trailing substrings of other strings
+ + better data structures? balanced trees?
+ + look at reducing memory use elsewhere -- maybe if we didn't have
+ to construct the entire symbol table at once, we could get by
+ with smaller amounts of VM? (What effect does that have on the
+ string table reductions?) */
+
+/* An entry in the strtab hash table. */
+
+struct strtab_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Index in string table. */
+ bfd_size_type index;
+ /* Next string in strtab. */
+ struct strtab_hash_entry *next;
+};
+
+/* The strtab hash table. */
+
+struct bfd_strtab_hash
+{
+ struct bfd_hash_table table;
+ /* Size of strtab--also next available index. */
+ bfd_size_type size;
+ /* First string in strtab. */
+ struct strtab_hash_entry *first;
+ /* Last string in strtab. */
+ struct strtab_hash_entry *last;
+ /* Whether to precede strings with a two byte length, as in the
+ XCOFF .debug section. */
+ boolean xcoff;
+};
+
+static struct bfd_hash_entry *strtab_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+/* Routine to create an entry in a strtab. */
+
+static struct bfd_hash_entry *
+strtab_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct strtab_hash_entry *) NULL)
+ ret = ((struct strtab_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct strtab_hash_entry)));
+ if (ret == (struct strtab_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct strtab_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->index = (bfd_size_type) -1;
+ ret->next = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in an strtab. */
+
+#define strtab_hash_lookup(t, string, create, copy) \
+ ((struct strtab_hash_entry *) \
+ bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
+
+/* Create a new strtab. */
+
+struct bfd_strtab_hash *
+_bfd_stringtab_init ()
+{
+ struct bfd_strtab_hash *table;
+
+ table = ((struct bfd_strtab_hash *)
+ bfd_malloc (sizeof (struct bfd_strtab_hash)));
+ if (table == NULL)
+ return NULL;
+
+ if (! bfd_hash_table_init (&table->table, strtab_hash_newfunc))
+ {
+ free (table);
+ return NULL;
+ }
+
+ table->size = 0;
+ table->first = NULL;
+ table->last = NULL;
+ table->xcoff = false;
+
+ return table;
+}
+
+/* Create a new strtab in which the strings are output in the format
+ used in the XCOFF .debug section: a two byte length precedes each
+ string. */
+
+struct bfd_strtab_hash *
+_bfd_xcoff_stringtab_init ()
+{
+ struct bfd_strtab_hash *ret;
+
+ ret = _bfd_stringtab_init ();
+ if (ret != NULL)
+ ret->xcoff = true;
+ return ret;
+}
+
+/* Free a strtab. */
+
+void
+_bfd_stringtab_free (table)
+ struct bfd_strtab_hash *table;
+{
+ bfd_hash_table_free (&table->table);
+ free (table);
+}
+
+/* Get the index of a string in a strtab, adding it if it is not
+ already present. If HASH is false, we don't really use the hash
+ table, and we don't eliminate duplicate strings. */
+
+bfd_size_type
+_bfd_stringtab_add (tab, str, hash, copy)
+ struct bfd_strtab_hash *tab;
+ const char *str;
+ boolean hash;
+ boolean copy;
+{
+ register struct strtab_hash_entry *entry;
+
+ if (hash)
+ {
+ entry = strtab_hash_lookup (tab, str, true, copy);
+ if (entry == NULL)
+ return (bfd_size_type) -1;
+ }
+ else
+ {
+ entry = ((struct strtab_hash_entry *)
+ bfd_hash_allocate (&tab->table,
+ sizeof (struct strtab_hash_entry)));
+ if (entry == NULL)
+ return (bfd_size_type) -1;
+ if (! copy)
+ entry->root.string = str;
+ else
+ {
+ char *n;
+
+ n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1);
+ if (n == NULL)
+ return (bfd_size_type) -1;
+ entry->root.string = n;
+ }
+ entry->index = (bfd_size_type) -1;
+ entry->next = NULL;
+ }
+
+ if (entry->index == (bfd_size_type) -1)
+ {
+ entry->index = tab->size;
+ tab->size += strlen (str) + 1;
+ if (tab->xcoff)
+ {
+ entry->index += 2;
+ tab->size += 2;
+ }
+ if (tab->first == NULL)
+ tab->first = entry;
+ else
+ tab->last->next = entry;
+ tab->last = entry;
+ }
+
+ return entry->index;
+}
+
+/* Get the number of bytes in a strtab. */
+
+bfd_size_type
+_bfd_stringtab_size (tab)
+ struct bfd_strtab_hash *tab;
+{
+ return tab->size;
+}
+
+/* Write out a strtab. ABFD must already be at the right location in
+ the file. */
+
+boolean
+_bfd_stringtab_emit (abfd, tab)
+ register bfd *abfd;
+ struct bfd_strtab_hash *tab;
+{
+ register boolean xcoff;
+ register struct strtab_hash_entry *entry;
+
+ xcoff = tab->xcoff;
+
+ for (entry = tab->first; entry != NULL; entry = entry->next)
+ {
+ register const char *str;
+ register size_t len;
+
+ str = entry->root.string;
+ len = strlen (str) + 1;
+
+ if (xcoff)
+ {
+ bfd_byte buf[2];
+
+ /* The output length includes the null byte. */
+ bfd_put_16 (abfd, len, buf);
+ if (bfd_write ((PTR) buf, 1, 2, abfd) != 2)
+ return false;
+ }
+
+ if (bfd_write ((PTR) str, 1, len, abfd) != len)
+ return false;
+ }
+
+ return true;
+}
diff --git a/bfd/host-aout.c b/bfd/host-aout.c
new file mode 100644
index 00000000000..99643dcc24e
--- /dev/null
+++ b/bfd/host-aout.c
@@ -0,0 +1,83 @@
+/* BFD backend for local host's a.out binaries
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+ Written by Cygnus Support. Probably John Gilmore's fault.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define ARCH_SIZE 32
+
+/* When porting to a new system, you must supply:
+
+ HOST_PAGE_SIZE (optional)
+ HOST_SEGMENT_SIZE (optional -- defaults to page size)
+ HOST_MACHINE_ARCH (optional)
+ HOST_MACHINE_MACHINE (optional)
+ HOST_TEXT_START_ADDR (optional)
+ HOST_STACK_END_ADDR (not used, except by trad-core ???)
+ HOST_BIG_ENDIAN_P (required -- define if big-endian)
+
+ in the ./hosts/h-systemname.h file. */
+
+#ifdef TRAD_HEADER
+#include TRAD_HEADER
+#endif
+
+#ifdef HOST_PAGE_SIZE
+#define TARGET_PAGE_SIZE HOST_PAGE_SIZE
+#endif
+
+#ifdef HOST_SEGMENT_SIZE
+#define SEGMENT_SIZE HOST_SEGMENT_SIZE
+#else
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#endif
+
+#ifdef HOST_TEXT_START_ADDR
+#define TEXT_START_ADDR HOST_TEXT_START_ADDR
+#endif
+
+#ifdef HOST_STACK_END_ADDR
+#define STACK_END_ADDR HOST_STACK_END_ADDR
+#endif
+
+#ifdef HOST_BIG_ENDIAN_P
+#define TARGET_IS_BIG_ENDIAN_P
+#else
+#undef TARGET_IS_BIG_ENDIAN_P
+#endif
+
+#include "libaout.h" /* BFD a.out internal data structures */
+#include "aout/aout64.h"
+
+#ifdef HOST_MACHINE_ARCH
+#ifdef HOST_MACHINE_MACHINE
+#define SET_ARCH_MACH(abfd, execp) \
+ bfd_default_set_arch_mach(abfd, HOST_MACHINE_ARCH, HOST_MACHINE_MACHINE)
+#else
+#define SET_ARCH_MACH(abfd, execp) \
+ bfd_default_set_arch_mach(abfd, HOST_MACHINE_ARCH, 0)
+#endif
+#endif /* HOST_MACHINE_ARCH */
+
+#define MY(OP) CAT(host_aout_,OP)
+#define TARGETNAME "a.out"
+
+#include "aout-target.h"
diff --git a/bfd/hosts/alphalinux.h b/bfd/hosts/alphalinux.h
new file mode 100644
index 00000000000..d9ba1b7ec6b
--- /dev/null
+++ b/bfd/hosts/alphalinux.h
@@ -0,0 +1,6 @@
+/* Linux dumps "struct task_struct" at the end of the core-file. This
+ structure is currently 920 bytes long, but we allow up to 1024
+ bytes to allow for some future growth. */
+#define TRAD_CORE_EXTRA_SIZE_ALLOWED 1024
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \
+ ((abfd)->tdata.trad_core_data->u.signal)
diff --git a/bfd/hosts/alphavms.h b/bfd/hosts/alphavms.h
new file mode 100644
index 00000000000..eee391a97fb
--- /dev/null
+++ b/bfd/hosts/alphavms.h
@@ -0,0 +1,69 @@
+/* alphavms.h -- BFD definitions for an openVMS host
+ Copyright 1996 Free Software Foundation, Inc.
+ Written by Klaus Kämpf (kkaempf@progis.de)
+ of proGIS Softwareentwicklung, Aachen, Germany
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stddef.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/file.h>
+#include <stdlib.h>
+#include <unixlib.h>
+#include <unixio.h>
+#include <time.h>
+
+#include "bfd.h"
+
+#ifndef BFD_HOST_64_BIT
+/* Make the basic types 64-bit quantities on the host.
+ Also provide the support macros BFD needs. */
+# ifdef __GNUC__
+# define BFD_HOST_64_BIT long long
+# else
+# define BFD_HOST_64_BIT long
+# endif
+typedef unsigned BFD_HOST_64_BIT uint64_type;
+typedef BFD_HOST_64_BIT int64_type;
+
+# define sprintf_vma(s,x) sprintf (s, "%016lx", x) /* BFD_HOST_64_BIT */
+# define fprintf_vma(f,x) fprintf (f, "%016lx", x) /* BFD_HOST_64_BIT */
+
+# define BYTES_IN_PRINTF_INT 4
+
+/* These must have type unsigned long because they are used as
+ arguments in printf functions. */
+# define uint64_typeLOW(x) ((unsigned long) (((x) & 0xffffffff))) /* BFD_HOST_64_BIT */
+# define uint64_typeHIGH(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) /* BFD_HOST_64_BIT */
+
+#endif /* BFD_HOST_64_BIT */
+
+#include "fopen-vms.h"
+
+#define NO_FCNTL 1
+
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
+#endif
+
+extern int getpagesize PARAMS ((void));
diff --git a/bfd/hosts/decstation.h b/bfd/hosts/decstation.h
new file mode 100644
index 00000000000..a80c143d525
--- /dev/null
+++ b/bfd/hosts/decstation.h
@@ -0,0 +1,17 @@
+/* Hopefully this should include either machine/param.h (Ultrix) or
+ machine/machparam.h (Mach), whichever is its name on this system. */
+#include <sys/param.h>
+
+#include <machine/vmparam.h>
+
+#define HOST_PAGE_SIZE NBPG
+/* #define HOST_SEGMENT_SIZE NBPG -- we use HOST_DATA_START_ADDR */
+#define HOST_MACHINE_ARCH bfd_arch_mips
+/* #define HOST_MACHINE_MACHINE */
+
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_DATA_START_ADDR USRDATA
+#define HOST_STACK_END_ADDR USRSTACK
+
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
+ ((core_bfd)->tdata.trad_core_data->u.u_arg[0])
diff --git a/bfd/hosts/delta68.h b/bfd/hosts/delta68.h
new file mode 100644
index 00000000000..1a6a6e6f197
--- /dev/null
+++ b/bfd/hosts/delta68.h
@@ -0,0 +1,18 @@
+/* Definitions for a Motorola Delta 3300 box running System V R3.0.
+ Contributed by manfred@lts.sel.alcatel.de. */
+
+#include <sys/param.h>
+
+/* Definitions used by trad-core.c. */
+#define NBPG NBPC
+#define HOST_DATA_START_ADDR u.u_exdata.ux_datorg
+#define HOST_TEXT_START_ADDR u.u_exdata.ux_txtorg
+#if 0
+#define HOST_STACK_END_ADDR 0x40000000
+#else
+/* User's stack, copied from sys/param.h */
+#define HOST_STACK_END_ADDR USRSTACK
+#endif
+#define UPAGES USIZE
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \
+ abfd->tdata.trad_core_data->u.u_abort
diff --git a/bfd/hosts/dpx2.h b/bfd/hosts/dpx2.h
new file mode 100644
index 00000000000..ea6395f2e5d
--- /dev/null
+++ b/bfd/hosts/dpx2.h
@@ -0,0 +1,8 @@
+/* Definitions that are needed for core files. Core section sizes for
+ the DPX2 are in bytes. */
+
+#include <sys/param.h>
+#define NBPG 1
+#define UPAGES (USIZE * NBPP)
+#define HOST_DATA_START_ADDR (u.u_exdata.ux_datorg)
+#define HOST_STACK_END_ADDR (USERSTACK)
diff --git a/bfd/hosts/hp300bsd.h b/bfd/hosts/hp300bsd.h
new file mode 100644
index 00000000000..98287178207
--- /dev/null
+++ b/bfd/hosts/hp300bsd.h
@@ -0,0 +1,13 @@
+#include <sys/param.h>
+#ifdef BSD4_4
+#define NO_CORE_COMMAND
+#endif
+
+#define HOST_PAGE_SIZE NBPG
+#define HOST_SEGMENT_SIZE NBPG /* Data seg start addr rounds to NBPG */
+#define HOST_MACHINE_ARCH bfd_arch_m68k
+/* #define HOST_MACHINE_MACHINE */
+
+#define HOST_TEXT_START_ADDR 0
+#define HOST_STACK_END_ADDR 0xfff00000
+#define HOST_BIG_ENDIAN_P
diff --git a/bfd/hosts/i386bsd.h b/bfd/hosts/i386bsd.h
new file mode 100644
index 00000000000..8eee3d82fb7
--- /dev/null
+++ b/bfd/hosts/i386bsd.h
@@ -0,0 +1,32 @@
+/* Intel 386 running any BSD Unix */
+
+#include <machine/param.h>
+#include <machine/vmparam.h>
+
+/* Recent versions of FreeBSD don't define NBPG. */
+#ifndef NBPG
+#ifdef PAGE_SIZE
+#define NBPG PAGE_SIZE
+#endif
+#endif
+
+#define HOST_PAGE_SIZE NBPG
+#define HOST_MACHINE_ARCH bfd_arch_i386
+#define HOST_TEXT_START_ADDR USRTEXT
+
+/* Jolitz suggested defining HOST_STACK_END_ADDR to
+ (u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on
+ both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */
+
+#ifdef __bsdi__
+/* This seems to be the right thing for BSDI. */
+#define HOST_STACK_END_ADDR USRSTACK
+#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr)
+#else
+/* This seems to be the right thing for 386BSD release 0.1. */
+#define HOST_STACK_END_ADDR (USRSTACK - MAXSSIZ)
+#endif
+
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
+ ((core_bfd)->tdata.trad_core_data->u.u_sig)
+#define u_comm u_kproc.kp_proc.p_comm
diff --git a/bfd/hosts/i386linux.h b/bfd/hosts/i386linux.h
new file mode 100644
index 00000000000..13a51f1bd14
--- /dev/null
+++ b/bfd/hosts/i386linux.h
@@ -0,0 +1,8 @@
+/* Linux writes the task structure at the end of the core file. Currently it
+ is 2912 bytes. It is possible that this should be a pickier check, but
+ we should probably not be too picky (the size of the task structure might
+ vary, and if it's not the length we expect it to be, it doesn't affect
+ our ability to process the core file). So allow 0-4096 extra bytes at
+ the end. */
+
+#define TRAD_CORE_EXTRA_SIZE_ALLOWED 4096
diff --git a/bfd/hosts/i386mach3.h b/bfd/hosts/i386mach3.h
new file mode 100644
index 00000000000..dcc61e3c8e8
--- /dev/null
+++ b/bfd/hosts/i386mach3.h
@@ -0,0 +1,25 @@
+#include <machine/vmparam.h>
+#include <sys/param.h>
+
+/* This is an ugly way to hack around the incorrect
+ * definition of UPAGES in i386/machparam.h.
+ *
+ * The definition should specify the size reserved
+ * for "struct user" in core files in PAGES,
+ * but instead it gives it in 512-byte core-clicks
+ * for i386 and i860. UPAGES is used only in trad-core.c.
+ */
+#if UPAGES == 16
+#undef UPAGES
+#define UPAGES 2
+#endif
+
+#if UPAGES != 2
+FIXME!! UPAGES is neither 2 nor 16
+#endif
+
+#define HOST_PAGE_SIZE 1
+#define HOST_SEGMENT_SIZE NBPG
+#define HOST_MACHINE_ARCH bfd_arch_i386
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
diff --git a/bfd/hosts/i386sco.h b/bfd/hosts/i386sco.h
new file mode 100644
index 00000000000..ec8608c61dd
--- /dev/null
+++ b/bfd/hosts/i386sco.h
@@ -0,0 +1,19 @@
+/* Core file stuff. At least some, perhaps all, of the following
+ defines work on many more systems than just SCO. */
+
+#define NBPG NBPC
+#define UPAGES USIZE
+#define HOST_DATA_START_ADDR u.u_exdata.ux_datorg
+#define HOST_STACK_START_ADDR u.u_sub
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \
+ ((core_upage(abfd)->u_sysabort != 0) \
+ ? core_upage(abfd)->u_sysabort \
+ : -1)
+
+/* According to the manpage, a version 2 SCO corefile can contain
+ various additional sections (it is cleverly arranged so the u area,
+ data, and stack are first where we can find them). So without
+ writing lots of code to parse all their headers and stuff, we can't
+ know whether a corefile is bigger than it should be. */
+
+#define TRAD_CORE_ALLOW_ANY_EXTRA_SIZE 1
diff --git a/bfd/hosts/i860mach3.h b/bfd/hosts/i860mach3.h
new file mode 100644
index 00000000000..edd2aa10a7b
--- /dev/null
+++ b/bfd/hosts/i860mach3.h
@@ -0,0 +1,27 @@
+/* This file was hacked from i386mach3.h [dolan@ssd.intel.com] */
+
+#include <machine/vmparam.h>
+#include <sys/param.h>
+
+/* This is an ugly way to hack around the incorrect
+ * definition of UPAGES in i386/machparam.h.
+ *
+ * The definition should specify the size reserved
+ * for "struct user" in core files in PAGES,
+ * but instead it gives it in 512-byte core-clicks
+ * for i386 and i860. UPAGES is used only in trad-core.c.
+ */
+#if UPAGES == 16
+#undef UPAGES
+#define UPAGES 2
+#endif
+
+#if UPAGES != 2
+FIXME!! UPAGES is neither 2 nor 16
+#endif
+
+#define HOST_PAGE_SIZE 1
+#define HOST_SEGMENT_SIZE NBPG
+#define HOST_MACHINE_ARCH bfd_arch_i860
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
diff --git a/bfd/hosts/m68kaux.h b/bfd/hosts/m68kaux.h
new file mode 100644
index 00000000000..6237755dba5
--- /dev/null
+++ b/bfd/hosts/m68kaux.h
@@ -0,0 +1,16 @@
+/* Definitions for an Apple Macintosh running A/UX 3.x. */
+
+#include <sys/param.h>
+#include <sys/page.h>
+
+/* Definitions used by trad-core.c. */
+#define NBPG NBPP
+
+#define HOST_DATA_START_ADDR u.u_exdata.ux_datorg
+#define HOST_TEXT_START_ADDR u.u_exdata.ux_txtorg
+#define HOST_STACK_END_ADDR 0x100000000
+
+#define UPAGES USIZE
+
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \
+ (abfd->tdata.trad_core_data->u.u_arg[0])
diff --git a/bfd/hosts/m68klinux.h b/bfd/hosts/m68klinux.h
new file mode 100644
index 00000000000..0067dfa6fda
--- /dev/null
+++ b/bfd/hosts/m68klinux.h
@@ -0,0 +1,6 @@
+/* Linux dumps "struct task_struct" at the end of the core-file. This
+ structure is currently 2512 bytes long, but we allow up to 4096
+ bytes to allow for some future growth. */
+#define TRAD_CORE_EXTRA_SIZE_ALLOWED 4096
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(abfd) \
+ ((abfd)->tdata.trad_core_data->u.signal)
diff --git a/bfd/hosts/m88kmach3.h b/bfd/hosts/m88kmach3.h
new file mode 100644
index 00000000000..421553893ec
--- /dev/null
+++ b/bfd/hosts/m88kmach3.h
@@ -0,0 +1,11 @@
+#include <machine/vmparam.h>
+#include <sys/param.h>
+
+#undef UPAGES
+#define UPAGES 3
+
+#define HOST_PAGE_SIZE NBPG
+#define HOST_SEGMENT_SIZE NBPG
+#define HOST_MACHINE_ARCH bfd_arch_m88k
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
diff --git a/bfd/hosts/mipsbsd.h b/bfd/hosts/mipsbsd.h
new file mode 100644
index 00000000000..a2fad21fcf7
--- /dev/null
+++ b/bfd/hosts/mipsbsd.h
@@ -0,0 +1,12 @@
+#include <machine/param.h>
+#include <machine/vmparam.h>
+#undef ALIGN
+
+#define HOST_PAGE_SIZE NBPG
+/* #define HOST_SEGMENT_SIZE NBPG -- we use HOST_DATA_START_ADDR */
+#define HOST_MACHINE_ARCH bfd_arch_mips
+/* #define HOST_MACHINE_MACHINE */
+
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
+#define NO_CORE_COMMAND
diff --git a/bfd/hosts/mipsmach3.h b/bfd/hosts/mipsmach3.h
new file mode 100644
index 00000000000..c5c468d3742
--- /dev/null
+++ b/bfd/hosts/mipsmach3.h
@@ -0,0 +1,10 @@
+#include <machine/vmparam.h>
+#include <machine/machparam.h>
+#include <sys/param.h>
+
+#define HOST_PAGE_SIZE NBPG
+/* #define HOST_SEGMENT_SIZE NBPG */
+#define HOST_MACHINE_ARCH bfd_arch_mips
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_DATA_START_ADDR USRDATA
+#define HOST_STACK_END_ADDR USRSTACK
diff --git a/bfd/hosts/news-mips.h b/bfd/hosts/news-mips.h
new file mode 100644
index 00000000000..9e799bed904
--- /dev/null
+++ b/bfd/hosts/news-mips.h
@@ -0,0 +1,12 @@
+/* Sony News running NewsOS 3.2. */
+
+#include <sys/param.h>
+#include <machine/vmparam.h>
+
+#define HOST_PAGE_SIZE NBPG
+
+#define HOST_MACHINE_ARCH bfd_arch_mips
+
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_DATA_START_ADDR USRDATA
+#define HOST_STACK_END_ADDR USRSTACK
diff --git a/bfd/hosts/news.h b/bfd/hosts/news.h
new file mode 100644
index 00000000000..bf7946cdb99
--- /dev/null
+++ b/bfd/hosts/news.h
@@ -0,0 +1,9 @@
+/* Sony News running NewsOS 3.2. */
+
+#include <machine/vmparam.h>
+
+#define HOST_PAGE_SIZE NBPG
+#define HOST_SEGMENT_SIZE NBPG
+#define HOST_MACHINE_ARCH bfd_arch_m68k
+#define HOST_TEXT_START_ADDR 0
+#define HOST_STACK_END_ADDR (KERNBASE - (UPAGES * NBPG))
diff --git a/bfd/hosts/pc532mach.h b/bfd/hosts/pc532mach.h
new file mode 100644
index 00000000000..ab96f597edd
--- /dev/null
+++ b/bfd/hosts/pc532mach.h
@@ -0,0 +1,24 @@
+#include <machine/vmparam.h>
+#include <sys/param.h>
+
+/* This is an ugly way to hack around the incorrect
+ * definition of UPAGES in ns532/machparam.h.
+ *
+ * The definition should specify the size reserved
+ * for "struct user" in core files in PAGES,
+ * but instead it gives it in 512-byte core-clicks
+ * for ns532, i386 and i860. UPAGES is used only in trad-core.c.
+ */
+#if UPAGES == 16
+#undef UPAGES
+#define UPAGES 2
+#endif
+
+#if UPAGES != 2
+#error UPAGES is neither 2 nor 16
+#endif
+
+#define HOST_PAGE_SIZE 1
+#define HOST_SEGMENT_SIZE NBPG
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
diff --git a/bfd/hosts/riscos.h b/bfd/hosts/riscos.h
new file mode 100644
index 00000000000..8ffa826bdcf
--- /dev/null
+++ b/bfd/hosts/riscos.h
@@ -0,0 +1,10 @@
+/* RISC/os 4.52C, and presumably other versions. */
+
+#include <bsd43/machine/machparam.h>
+#include <bsd43/machine/vmparam.h>
+
+#define NBPG BSD43_NBPG
+#define UPAGES BSD43_UPAGES
+#define HOST_TEXT_START_ADDR BSD43_USRTEXT
+#define HOST_DATA_START_ADDR BSD43_USRDATA
+#define HOST_STACK_END_ADDR BSD43_USRSTACK
diff --git a/bfd/hosts/symmetry.h b/bfd/hosts/symmetry.h
new file mode 100644
index 00000000000..75717b31eb2
--- /dev/null
+++ b/bfd/hosts/symmetry.h
@@ -0,0 +1,20 @@
+/* Symmetry running either dynix 3.1 (bsd) or ptx (sysv). */
+
+#define NBPG 4096
+#define UPAGES 1
+
+#ifdef _SEQUENT_
+/* ptx */
+#define HOST_TEXT_START_ADDR 0
+#define HOST_STACK_END_ADDR 0x3fffe000
+#define TRAD_CORE_USER_OFFSET ((UPAGES * NBPG) - sizeof (struct user))
+#else
+/* dynix */
+#define HOST_TEXT_START_ADDR 0x1000
+#define HOST_DATA_START_ADDR (NBPG * u.u_tsize)
+#define HOST_STACK_END_ADDR 0x3ffff000
+#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
+ ((core_bfd)->tdata.trad_core_data->u.u_arg[0])
+#endif
+
+#define TRAD_CORE_DSIZE_INCLUDES_TSIZE
diff --git a/bfd/hosts/tahoe.h b/bfd/hosts/tahoe.h
new file mode 100644
index 00000000000..716cee2a171
--- /dev/null
+++ b/bfd/hosts/tahoe.h
@@ -0,0 +1,12 @@
+#define NO_CORE_COMMAND
+
+#undef ALIGN /* They use it, we use it too */
+#include <machine/param.h>
+#undef ALIGN /* They use it, we use it too */
+
+#define HOST_PAGE_SIZE NBPG
+#define HOST_MACHINE_ARCH bfd_arch_tahoe
+
+#define HOST_TEXT_START_ADDR 0
+#define HOST_STACK_END_ADDR (KERNBASE - (UPAGES * NBPG))
+#define HOST_BIG_ENDIAN_P
diff --git a/bfd/hosts/vaxbsd.h b/bfd/hosts/vaxbsd.h
new file mode 100644
index 00000000000..ceb9ccedfaf
--- /dev/null
+++ b/bfd/hosts/vaxbsd.h
@@ -0,0 +1,19 @@
+#define NO_CORE_COMMAND /* No command name in core file */
+
+#if 0
+#undef ALIGN /* They use it, we use it too */
+/* Does not exist on BSD 4.3, it uses machine/machparam.h.
+ Whatever it is, it's included by <sys/param.h>, which trad-core.c,
+ the only place that uses this (I think), already includes. */
+#include <machine/param.h>
+#endif
+#undef ALIGN /* They use it, we use it too */
+
+/* Note that HOST_PAGE_SIZE -- the page size as far as executable files
+ are concerned -- is not the same as NBPG, because of page clustering. */
+#define HOST_PAGE_SIZE 1024
+#define HOST_MACHINE_ARCH bfd_arch_vax
+
+#define HOST_TEXT_START_ADDR 0
+#define HOST_STACK_END_ADDR (0x80000000 - (UPAGES * NBPG))
+#undef HOST_BIG_ENDIAN_P
diff --git a/bfd/hosts/vaxult.h b/bfd/hosts/vaxult.h
new file mode 100644
index 00000000000..13731b7479f
--- /dev/null
+++ b/bfd/hosts/vaxult.h
@@ -0,0 +1,8 @@
+#include <machine/param.h>
+#include <machine/vmparam.h>
+#define HOST_PAGE_SIZE (NBPG*CLSIZE)
+#define HOST_MACHINE_ARCH bfd_arch_vax
+
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
+#undef HOST_BIG_ENDIAN_P
diff --git a/bfd/hosts/vaxult2.h b/bfd/hosts/vaxult2.h
new file mode 100644
index 00000000000..13731b7479f
--- /dev/null
+++ b/bfd/hosts/vaxult2.h
@@ -0,0 +1,8 @@
+#include <machine/param.h>
+#include <machine/vmparam.h>
+#define HOST_PAGE_SIZE (NBPG*CLSIZE)
+#define HOST_MACHINE_ARCH bfd_arch_vax
+
+#define HOST_TEXT_START_ADDR USRTEXT
+#define HOST_STACK_END_ADDR USRSTACK
+#undef HOST_BIG_ENDIAN_P
diff --git a/bfd/hp300bsd.c b/bfd/hp300bsd.c
new file mode 100644
index 00000000000..5767b18c179
--- /dev/null
+++ b/bfd/hp300bsd.c
@@ -0,0 +1,38 @@
+/* BFD back-end for HP 9000/300 (68000-based) machines running BSD Unix.
+ Copyright 1992 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+#define N_HEADER_IN_TEXT(x) 0
+#define BYTES_IN_WORD 4
+#define ENTRY_CAN_BE_ZERO
+#define N_SHARED_LIB(x) 0 /* Avoids warning */
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_m68k
+
+#define MY(OP) CAT(hp300bsd_,OP)
+#define TARGETNAME "a.out-hp300bsd"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#include "aout-target.h"
diff --git a/bfd/hp300hpux.c b/bfd/hp300hpux.c
new file mode 100644
index 00000000000..9552318baa8
--- /dev/null
+++ b/bfd/hp300hpux.c
@@ -0,0 +1,870 @@
+/* BFD backend for hp-ux 9000/300
+ Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc.
+ Written by Glenn Engel.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+
+ hpux native ------------> | |
+ | hp300hpux bfd | ----------> hpux w/gnu ext
+ hpux w/gnu extension ----> | |
+
+
+ Support for the 9000/[34]00 has several limitations.
+ 1. Shared libraries are not supported.
+ 2. The output format from this bfd is not usable by native tools.
+
+ The primary motivation for writing this bfd was to allow use of
+ gdb and gcc for host based debugging and not to mimic the hp-ux tools
+ in every detail. This leads to a significant simplification of the
+ code and a leap in performance. The decision to not output hp native
+ compatible objects was further strengthened by the fact that the richness
+ of the gcc compiled objects could not be represented without loss of
+ information. For example, while the hp format supports the concept of
+ secondary symbols, it does not support indirect symbols. Another
+ reason is to maintain backwards compatibility with older implementations
+ of gcc on hpux which used 'hpxt' to translate .a and .o files into a
+ format which could be readily understood by the gnu linker and gdb.
+ This allows reading hp secondary symbols and converting them into
+ indirect symbols but the reverse it not always possible.
+
+ Another example of differences is that the hp format stores symbol offsets
+ in the object code while the gnu utilities use a field in the
+ relocation record for this. To support the hp native format, the object
+ code would need to be patched with the offsets when producing .o files.
+
+ The basic technique taken in this implementation is to #include the code
+ from aoutx.h and aout-target.h with appropriate #defines to override
+ code where a unique implementation is needed:
+
+ {
+ #define a bunch of stuff
+ #include <aoutx.h>
+
+ implement a bunch of functions
+
+ #include "aout-target.h"
+ }
+
+ The hp symbol table is a bit different than other a.out targets. Instead
+ of having an array of nlist items and an array of strings, hp's format
+ has them mixed together in one structure. In addition, the strings are
+ not null terminated. It looks something like this:
+
+ nlist element 1
+ string1
+ nlist element 2
+ string2
+ ...
+
+ The whole symbol table is read as one chunk and then we march thru it
+ and convert it to canonical form. As we march thru the table, we copy
+ the nlist data into the internal form and we compact the strings and null
+ terminate them, using storage from the already allocated symbol table:
+
+ string1
+ null
+ string2
+ null
+ */
+
+/* @@ Is this really so different from normal a.out that it needs to include
+ aoutx.h? We should go through this file sometime and see what can be made
+ more dependent on aout32.o and what might need to be broken off and accessed
+ through the backend_data field. Or, maybe we really do need such a
+ completely separate implementation. I don't have time to investigate this
+ much further right now. [raeburn:19930428.2124EST] */
+/* @@ Also, note that there wind up being two versions of some routines, with
+ different names, only one of which actually gets used. For example:
+ slurp_symbol_table
+ swap_std_reloc_in
+ slurp_reloc_table
+ get_symtab
+ get_symtab_upper_bound
+ canonicalize_reloc
+ mkobject
+ This should also be fixed. */
+
+#define TARGETNAME "a.out-hp300hpux"
+#define MY(OP) CAT(hp300hpux_,OP)
+
+#define external_exec hp300hpux_exec_bytes
+#define external_nlist hp300hpux_nlist_bytes
+
+#include "aout/hp300hpux.h"
+
+/* define these so we can compile unused routines in aoutx.h */
+#define e_strx e_shlib
+#define e_other e_length
+#define e_desc e_almod
+
+#define AR_PAD_CHAR '/'
+#define TARGET_IS_BIG_ENDIAN_P
+#define DEFAULT_ARCH bfd_arch_m68k
+
+#define MY_get_section_contents aout_32_get_section_contents
+#define MY_slurp_armap bfd_slurp_bsd_armap_f2
+
+/***********************************************/
+/* provide overrides for routines in this file */
+/***********************************************/
+/* these don't use MY because that causes problems within JUMP_TABLE
+ (CAT winds up being expanded recursively, which ANSI C compilers
+ will not do). */
+#define MY_get_symtab hp300hpux_get_symtab
+#define MY_get_symtab_upper_bound hp300hpux_get_symtab_upper_bound
+#define MY_canonicalize_reloc hp300hpux_canonicalize_reloc
+#define MY_write_object_contents hp300hpux_write_object_contents
+
+#define MY_read_minisymbols _bfd_generic_read_minisymbols
+#define MY_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define MY_final_link_callback unused
+#define MY_bfd_final_link _bfd_generic_final_link
+
+/* Until and unless we convert the slurp_reloc and slurp_symtab
+ routines in this file, we can not use the default aout
+ free_cached_info routine which assumes that the relocs and symtabs
+ were allocated using malloc. */
+#define MY_bfd_free_cached_info bfd_true
+
+#define hp300hpux_write_syms aout_32_write_syms
+
+#define MY_callback MY(callback)
+
+#define MY_exec_hdr_flags 0x2
+
+#define NAME_swap_exec_header_in NAME(hp300hpux_32_,swap_exec_header_in)
+
+#define HP_SYMTYPE_UNDEFINED 0x00
+#define HP_SYMTYPE_ABSOLUTE 0x01
+#define HP_SYMTYPE_TEXT 0x02
+#define HP_SYMTYPE_DATA 0x03
+#define HP_SYMTYPE_BSS 0x04
+#define HP_SYMTYPE_COMMON 0x05
+
+#define HP_SYMTYPE_TYPE 0x0F
+#define HP_SYMTYPE_FILENAME 0x1F
+
+#define HP_SYMTYPE_ALIGN 0x10
+#define HP_SYMTYPE_EXTERNAL 0x20
+#define HP_SECONDARY_SYMBOL 0x40
+
+/* RELOCATION DEFINITIONS */
+#define HP_RSEGMENT_TEXT 0x00
+#define HP_RSEGMENT_DATA 0x01
+#define HP_RSEGMENT_BSS 0x02
+#define HP_RSEGMENT_EXTERNAL 0x03
+#define HP_RSEGMENT_PCREL 0x04
+#define HP_RSEGMENT_RDLT 0x05
+#define HP_RSEGMENT_RPLT 0x06
+#define HP_RSEGMENT_NOOP 0x3F
+
+#define HP_RLENGTH_BYTE 0x00
+#define HP_RLENGTH_WORD 0x01
+#define HP_RLENGTH_LONG 0x02
+#define HP_RLENGTH_ALIGN 0x03
+
+#define NAME(x,y) CAT3(hp300hpux,_32_,y)
+#define ARCH_SIZE 32
+
+/* aoutx.h requires definitions for BMAGIC and QMAGIC. */
+#define BMAGIC HPUX_DOT_O_MAGIC
+#define QMAGIC 0314
+
+#include "aoutx.h"
+
+/* Since the hpux symbol table has nlist elements interspersed with
+ strings and we need to insert som strings for secondary symbols, we
+ give ourselves a little extra padding up front to account for
+ this. Note that for each non-secondary symbol we process, we gain
+ 9 bytes of space for the discarded nlist element (one byte used for
+ null). SYM_EXTRA_BYTES is the extra space. */
+#define SYM_EXTRA_BYTES 1024
+
+/* 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) (abfd)
+ 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)->_raw_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;
+}
+
+extern boolean aout_32_write_syms PARAMS ((bfd * abfd));
+
+static boolean
+MY (write_object_contents) (abfd)
+ 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));
+#if CHOOSE_RELOC_SIZE
+ CHOOSE_RELOC_SIZE (abfd);
+#else
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+#endif
+
+ 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 */
+ bfd_h_put_32 (abfd, bfd_get_symcount (abfd) * 12, exec_bytes.e_drelocs);
+
+ if (bfd_seek (abfd, 0L, false) != 0
+ || (bfd_write ((PTR) & exec_bytes, 1, 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, (long) (N_TRELOFF (*execp)), false) != 0)
+ return false;
+ if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
+ return false;
+ if (bfd_seek (abfd, (long) (N_DRELOFF (*execp)), false) != 0)
+ return false;
+ if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
+ return false;
+ }
+
+ return true;
+}
+
+/* convert the hp symbol type to be the same as aout64.h usage so we */
+/* can piggyback routines in aoutx.h. */
+
+static void
+convert_sym_type (sym_pointer, cache_ptr, abfd)
+ struct external_nlist *sym_pointer;
+ aout_symbol_type *cache_ptr;
+ bfd *abfd;
+{
+ int name_type;
+ int new_type;
+
+ name_type = (cache_ptr->type);
+ new_type = 0;
+
+ if ((name_type & HP_SYMTYPE_ALIGN) != 0)
+ {
+ /* iou_error ("aligned symbol encountered: %s", name);*/
+ name_type = 0;
+ }
+
+ if (name_type == HP_SYMTYPE_FILENAME)
+ new_type = N_FN;
+ else
+ {
+ switch (name_type & HP_SYMTYPE_TYPE)
+ {
+ case HP_SYMTYPE_UNDEFINED:
+ new_type = N_UNDF;
+ break;
+
+ case HP_SYMTYPE_ABSOLUTE:
+ new_type = N_ABS;
+ break;
+
+ case HP_SYMTYPE_TEXT:
+ new_type = N_TEXT;
+ break;
+
+ case HP_SYMTYPE_DATA:
+ new_type = N_DATA;
+ break;
+
+ case HP_SYMTYPE_BSS:
+ new_type = N_BSS;
+ break;
+
+ case HP_SYMTYPE_COMMON:
+ new_type = N_COMM;
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+ if (name_type & HP_SYMTYPE_EXTERNAL)
+ new_type |= N_EXT;
+
+ if (name_type & HP_SECONDARY_SYMBOL)
+ {
+ switch (new_type)
+ {
+ default:
+ abort ();
+ case N_UNDF | N_EXT:
+ /* If the value is nonzero, then just treat this as a
+ common symbol. I don't know if this is correct in
+ all cases, but it is more correct than treating it as
+ a weak undefined symbol. */
+ if (cache_ptr->symbol.value == 0)
+ new_type = N_WEAKU;
+ break;
+ case N_ABS | N_EXT:
+ new_type = N_WEAKA;
+ break;
+ case N_TEXT | N_EXT:
+ new_type = N_WEAKT;
+ break;
+ case N_DATA | N_EXT:
+ new_type = N_WEAKD;
+ break;
+ case N_BSS | N_EXT:
+ new_type = N_WEAKB;
+ break;
+ }
+ }
+ }
+ cache_ptr->type = new_type;
+
+}
+
+
+/*
+DESCRIPTION
+ Swaps the information in an executable header taken from a raw
+ byte stream memory image, into the internal exec_header
+ structure.
+*/
+
+void
+NAME (aout,swap_exec_header_in) (abfd, raw_bytes, execp)
+ bfd *abfd;
+ struct external_exec *raw_bytes;
+ struct internal_exec *execp;
+{
+ struct external_exec *bytes = (struct external_exec *) raw_bytes;
+
+ /* The internal_exec structure has some fields that are unused in this
+ configuration (IE for i960), so ensure that all such uninitialized
+ fields are zero'd out. There are places where two of these structs
+ are memcmp'd, and thus the contents do matter. */
+ memset (execp, 0, sizeof (struct internal_exec));
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
+ execp->a_text = GET_WORD (abfd, bytes->e_text);
+ execp->a_data = GET_WORD (abfd, bytes->e_data);
+ execp->a_bss = GET_WORD (abfd, bytes->e_bss);
+ execp->a_syms = GET_WORD (abfd, bytes->e_syms);
+ execp->a_entry = GET_WORD (abfd, bytes->e_entry);
+ execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
+ execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
+
+ /***************************************************************/
+ /* check the header to see if it was generated by a bfd output */
+ /* this is detected rather bizarely by requiring a bunch of */
+ /* header fields to be zero and an old unused field (now used) */
+ /* to be set. */
+ /***************************************************************/
+ do
+ {
+ long syms;
+ struct aout_data_struct *rawptr;
+ if (bfd_h_get_32 (abfd, bytes->e_passize) != 0)
+ break;
+ if (bfd_h_get_32 (abfd, bytes->e_syms) != 0)
+ break;
+ if (bfd_h_get_32 (abfd, bytes->e_supsize) != 0)
+ break;
+
+ syms = bfd_h_get_32 (abfd, bytes->e_drelocs);
+ if (syms == 0)
+ break;
+
+ /* OK, we've passed the test as best as we can determine */
+ execp->a_syms = syms;
+
+ /* allocate storage for where we will store this result */
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (*rawptr));
+
+ if (rawptr == NULL)
+ return;
+ abfd->tdata.aout_data = rawptr;
+ obj_aout_subformat (abfd) = gnu_encap_format;
+ }
+ while (0);
+}
+
+
+/* The hp symbol table is a bit different than other a.out targets. Instead
+ of having an array of nlist items and an array of strings, hp's format
+ has them mixed together in one structure. In addition, the strings are
+ not null terminated. It looks something like this:
+
+ nlist element 1
+ string1
+ nlist element 2
+ string2
+ ...
+
+ The whole symbol table is read as one chunk and then we march thru it
+ and convert it to canonical form. As we march thru the table, we copy
+ the nlist data into the internal form and we compact the strings and null
+ terminate them, using storage from the already allocated symbol table:
+
+ string1
+ null
+ string2
+ null
+ ...
+*/
+
+boolean
+MY (slurp_symbol_table) (abfd)
+ bfd *abfd;
+{
+ bfd_size_type symbol_bytes;
+ struct external_nlist *syms;
+ struct external_nlist *sym_pointer;
+ struct external_nlist *sym_end;
+ char *strings;
+ aout_symbol_type *cached;
+ unsigned num_syms = 0;
+
+ /* If there's no work to be done, don't do any */
+ if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
+ return true;
+ symbol_bytes = exec_hdr (abfd)->a_syms;
+
+ strings = (char *) bfd_alloc (abfd,
+ symbol_bytes + SYM_EXTRA_BYTES);
+ if (!strings)
+ return false;
+ syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES);
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_read ((PTR) syms, symbol_bytes, 1, abfd) != symbol_bytes)
+ {
+ bfd_release (abfd, syms);
+ return false;
+ }
+
+
+ sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes);
+
+ /* first, march thru the table and figure out how many symbols there are */
+ for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++)
+ {
+ /* skip over the embedded symbol. */
+ sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
+ sym_pointer->e_length[0]);
+ }
+
+ /* now that we know the symbol count, update the bfd header */
+ bfd_get_symcount (abfd) = num_syms;
+
+ cached = ((aout_symbol_type *)
+ bfd_zalloc (abfd,
+ bfd_get_symcount (abfd) * sizeof (aout_symbol_type)));
+ if (cached == NULL && bfd_get_symcount (abfd) != 0)
+ return false;
+
+ /* as we march thru the hp symbol table, convert it into a list of
+ null terminated strings to hold the symbol names. Make sure any
+ assignment to the strings pointer is done after we're thru using
+ the nlist so we don't overwrite anything important. */
+
+ /* OK, now walk the new symtable, cacheing symbol properties */
+ {
+ aout_symbol_type *cache_ptr = cached;
+ aout_symbol_type cache_save;
+ /* Run through table and copy values */
+ for (sym_pointer = syms, cache_ptr = cached;
+ sym_pointer < sym_end; sym_pointer++, cache_ptr++)
+ {
+ unsigned int length;
+ cache_ptr->symbol.the_bfd = abfd;
+ cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value);
+ cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod);
+ cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type);
+ cache_ptr->symbol.udata.p = NULL;
+ length = bfd_get_8 (abfd, sym_pointer->e_length);
+ cache_ptr->other = length; /* other not used, save length here */
+
+ cache_save = *cache_ptr;
+ convert_sym_type (sym_pointer, cache_ptr, abfd);
+ if (!translate_from_native_sym_flags (abfd, cache_ptr))
+ return false;
+
+ /********************************************************/
+ /* for hpux, the 'lenght' value indicates the length of */
+ /* the symbol name which follows the nlist entry. */
+ /********************************************************/
+ if (length)
+ {
+ /**************************************************************/
+ /* the hp string is not null terminated so we create a new one*/
+ /* by copying the string to overlap the just vacated nlist */
+ /* structure before it in memory. */
+ /**************************************************************/
+ cache_ptr->symbol.name = strings;
+ memcpy (strings, sym_pointer + 1, length);
+ strings[length] = '\0';
+ strings += length + 1;
+ }
+ else
+ cache_ptr->symbol.name = (char *) NULL;
+
+ /* skip over the embedded symbol. */
+ sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +
+ length);
+ }
+ }
+
+ obj_aout_symbols (abfd) = cached;
+
+ return true;
+}
+
+
+
+void
+MY (swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct hp300hpux_reloc *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ int r_index;
+ int r_extern = 0;
+ unsigned int r_length;
+ int r_pcrel = 0;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
+ r_index = bfd_h_get_16 (abfd, bytes->r_index);
+
+ switch (bytes->r_type[0])
+ {
+ case HP_RSEGMENT_TEXT:
+ r_index = N_TEXT;
+ break;
+ case HP_RSEGMENT_DATA:
+ r_index = N_DATA;
+ break;
+ case HP_RSEGMENT_BSS:
+ r_index = N_BSS;
+ break;
+ case HP_RSEGMENT_EXTERNAL:
+ r_extern = 1;
+ break;
+ case HP_RSEGMENT_PCREL:
+ r_extern = 1;
+ r_pcrel = 1;
+ break;
+ case HP_RSEGMENT_RDLT:
+ break;
+ case HP_RSEGMENT_RPLT:
+ break;
+ case HP_RSEGMENT_NOOP:
+ break;
+ default:
+ abort ();
+ break;
+ }
+
+ switch (bytes->r_length[0])
+ {
+ case HP_RLENGTH_BYTE:
+ r_length = 0;
+ break;
+ case HP_RLENGTH_WORD:
+ r_length = 1;
+ break;
+ case HP_RLENGTH_LONG:
+ r_length = 2;
+ break;
+ default:
+ abort ();
+ break;
+ }
+
+ cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
+ /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
+
+ /* This macro uses the r_index value computed above */
+ if (r_pcrel && r_extern)
+ {
+ /* The GNU linker assumes any offset from beginning of section */
+ /* is already incorporated into the image while the HP linker */
+ /* adds this in later. Add it in now... */
+ MOVE_ADDRESS (-cache_ptr->address);
+ }
+ else
+ {
+ MOVE_ADDRESS (0);
+ }
+}
+
+boolean
+MY (slurp_reloc_table) (abfd, asect, symbols)
+ bfd *abfd;
+ sec_ptr asect;
+ asymbol **symbols;
+{
+ unsigned int count;
+ bfd_size_type reloc_size;
+ PTR relocs;
+ arelent *reloc_cache;
+ size_t each_size;
+ struct hp300hpux_reloc *rptr;
+ unsigned int counter;
+ arelent *cache_ptr;
+
+ if (asect->relocation)
+ return true;
+
+ if (asect->flags & SEC_CONSTRUCTOR)
+ return true;
+
+ if (asect == obj_datasec (abfd))
+ {
+ reloc_size = exec_hdr (abfd)->a_drsize;
+ goto doit;
+ }
+
+ if (asect == obj_textsec (abfd))
+ {
+ reloc_size = exec_hdr (abfd)->a_trsize;
+ goto doit;
+ }
+
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+
+doit:
+ if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+ return false;
+ each_size = obj_reloc_entry_size (abfd);
+
+ count = reloc_size / each_size;
+
+
+ reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t) (count * sizeof
+ (arelent)));
+ if (!reloc_cache && count != 0)
+ return false;
+
+ relocs = (PTR) bfd_alloc (abfd, reloc_size);
+ if (!relocs && reloc_size != 0)
+ {
+ bfd_release (abfd, reloc_cache);
+ return false;
+ }
+
+ if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
+ {
+ bfd_release (abfd, relocs);
+ bfd_release (abfd, reloc_cache);
+ return false;
+ }
+
+ rptr = (struct hp300hpux_reloc *) relocs;
+ counter = 0;
+ cache_ptr = reloc_cache;
+
+ for (; counter < count; counter++, rptr++, cache_ptr++)
+ {
+ MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
+ bfd_get_symcount (abfd));
+ }
+
+
+ bfd_release (abfd, relocs);
+ asect->relocation = reloc_cache;
+ asect->reloc_count = count;
+ return true;
+}
+
+
+/************************************************************************/
+/* The following functions are identical to functions in aoutx.h except */
+/* they refer to MY(func) rather than NAME(aout,func) and they also */
+/* call aout_32 versions if the input file was generated by gcc */
+/************************************************************************/
+
+long aout_32_get_symtab PARAMS ((bfd * abfd, asymbol ** location));
+long aout_32_get_symtab_upper_bound PARAMS ((bfd * abfd));
+
+long aout_32_canonicalize_reloc PARAMS ((bfd * abfd, sec_ptr section,
+ arelent ** relptr,
+ asymbol ** symbols));
+
+long
+MY (get_symtab) (abfd, location)
+ bfd *abfd;
+ asymbol **location;
+{
+ unsigned int counter = 0;
+ aout_symbol_type *symbase;
+
+ if (obj_aout_subformat (abfd) == gnu_encap_format)
+ return aout_32_get_symtab (abfd, location);
+
+ if (!MY (slurp_symbol_table) (abfd))
+ return -1;
+
+ for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
+ *(location++) = (asymbol *) (symbase++);
+ *location++ = 0;
+ return bfd_get_symcount (abfd);
+}
+
+long
+MY (get_symtab_upper_bound) (abfd)
+ bfd *abfd;
+{
+ if (obj_aout_subformat (abfd) == gnu_encap_format)
+ return aout_32_get_symtab_upper_bound (abfd);
+ if (!MY (slurp_symbol_table) (abfd))
+ return -1;
+
+ return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
+}
+
+
+
+
+long
+MY (canonicalize_reloc) (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr = section->relocation;
+ unsigned int count;
+ if (obj_aout_subformat (abfd) == gnu_encap_format)
+ return aout_32_canonicalize_reloc (abfd, section, relptr, symbols);
+
+ if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols)))
+ return -1;
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ arelent_chain *chain = section->constructor_chain;
+ for (count = 0; count < section->reloc_count; count++)
+ {
+ *relptr++ = &chain->relent;
+ chain = chain->next;
+ }
+ }
+ else
+ {
+ tblptr = section->relocation;
+
+ for (count = 0; count++ < section->reloc_count;)
+ {
+ *relptr++ = tblptr++;
+ }
+ }
+ *relptr = 0;
+
+ return section->reloc_count;
+}
+
+
+#include "aout-target.h"
diff --git a/bfd/hppa_stubs.h b/bfd/hppa_stubs.h
new file mode 100644
index 00000000000..ee893e8a57b
--- /dev/null
+++ b/bfd/hppa_stubs.h
@@ -0,0 +1,23 @@
+/* HPPA linker stub instructions */
+
+/* These are the instructions which the linker may insert into the
+ code stream when building final executables to handle out-of-range
+ calls and argument relocations. */
+
+#define LDO_M4_R31_R31 0x37ff3ff9 /* ldo -4(%r31),%r31 */
+#define LDIL_R1 0x20200000 /* ldil XXX,%r1 */
+#define BE_SR4_R1 0xe0202000 /* be XXX(%sr4,%r1) */
+#define COPY_R31_R2 0x081f0242 /* copy %r31,%r2 */
+#define BLE_SR4_R0 0xe4002000 /* ble XXX(%sr4,%r0) */
+#define BLE_SR4_R1 0xe4202000 /* ble XXX(%sr4,%r1) */
+#define BV_N_0_R31 0xebe0c002 /* bv,n 0(%r31) */
+#define STW_R31_M8R30 0x6bdf3ff1 /* stw %r31,-8(%r30) */
+#define LDW_M8R30_R31 0x4bdf3ff1 /* ldw -8(%r30),%r31 */
+#define STW_ARG_M16R30 0x6bc03fe1 /* stw %argX,-16(%r30) */
+#define LDW_M16R30_ARG 0x4bc03fe1 /* ldw -12(%r30),%argX */
+#define STW_ARG_M12R30 0x6bc03fe9 /* stw %argX,-16(%r30) */
+#define LDW_M12R30_ARG 0x4bc03fe9 /* ldw -12(%r30),%argX */
+#define FSTW_FARG_M16R30 0x27c11200 /* fstws %fargX,-16(%r30) */
+#define FLDW_M16R30_FARG 0x27c11000 /* fldws -16(%r30),%fargX */
+#define FSTD_FARG_M16R30 0x2fc11200 /* fstds %fargX,-16(%r30) */
+#define FLDD_M16R30_FARG 0x2fc11000 /* fldds -16(%r30),%fargX */
diff --git a/bfd/hppabsd-core.c b/bfd/hppabsd-core.c
new file mode 100644
index 00000000000..a7c22f519eb
--- /dev/null
+++ b/bfd/hppabsd-core.c
@@ -0,0 +1,303 @@
+/* BFD back-end for HPPA BSD core files.
+ Copyright 1993, 94, 95, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support.
+
+ The core file structure for the Utah 4.3BSD and OSF1 ports on the
+ PA is a mix between traditional cores and hpux cores -- just
+ different enough that supporting this format would tend to add
+ gross hacks to trad-core.c or hpux-core.c. So instead we keep any
+ gross hacks isolated to this file. */
+
+
+/* This file can only be compiled on systems which use HPPA-BSD style
+ core files.
+
+ I would not expect this to be of use to any other host/target, but
+ you never know. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#if defined (HOST_HPPABSD)
+
+#include "machine/vmparam.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <machine/reg.h>
+#include <sys/user.h> /* After a.out.h */
+#include <sys/file.h>
+
+static asection *make_bfd_asection PARAMS ((bfd *, CONST char *,
+ flagword, bfd_size_type,
+ file_ptr, unsigned int));
+static asymbol *hppabsd_core_make_empty_symbol PARAMS ((bfd *));
+static const bfd_target *hppabsd_core_core_file_p PARAMS ((bfd *));
+static char *hppabsd_core_core_file_failing_command PARAMS ((bfd *));
+static int hppabsd_core_core_file_failing_signal PARAMS ((bfd *));
+static boolean hppabsd_core_core_file_matches_executable_p
+ PARAMS ((bfd *, bfd *));
+static void swap_abort PARAMS ((void));
+
+/* These are stored in the bfd's tdata. */
+
+struct hppabsd_core_struct
+ {
+ int sig;
+ char cmd[MAXCOMLEN + 1];
+ asection *data_section;
+ asection *stack_section;
+ asection *reg_section;
+ };
+
+#define core_hdr(bfd) ((bfd)->tdata.hppabsd_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+#define core_datasec(bfd) (core_hdr(bfd)->data_section)
+#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
+#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, offset, alignment_power)
+ bfd *abfd;
+ CONST char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ file_ptr offset;
+ unsigned int alignment_power;
+{
+ asection *asect;
+
+ asect = bfd_make_section (abfd, name);
+ if (!asect)
+ return NULL;
+
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->filepos = offset;
+ asect->alignment_power = alignment_power;
+
+ return asect;
+}
+
+static asymbol *
+hppabsd_core_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+static const bfd_target *
+hppabsd_core_core_file_p (abfd)
+ bfd *abfd;
+{
+ int val;
+ struct user u;
+ struct hppabsd_core_struct *coredata;
+ int clicksz;
+
+ /* Try to read in the u-area. We will need information from this
+ to know how to grok the rest of the core structures. */
+ val = bfd_read ((void *) &u, 1, sizeof u, abfd);
+ if (val != sizeof u)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Get the page size out of the u structure. This will be different
+ for PA 1.0 machines and PA 1.1 machines. Yuk! */
+ clicksz = u.u_pcb.pcb_pgsz;
+
+ /* clicksz must be a power of two >= 2k. */
+ if (clicksz < 0x800
+ || clicksz != (clicksz & -clicksz))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+
+ /* Sanity checks. Make sure the size of the core file matches the
+ the size computed from information within the core itself. */
+ {
+ FILE *stream = bfd_cache_lookup (abfd);
+ struct stat statbuf;
+ if (stream == NULL || fstat (fileno (stream), &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+ if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return NULL;
+ }
+ if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size)
+ {
+ /* The file is too big. Maybe it's not a core file
+ or we otherwise have bad values for u_dsize and u_ssize). */
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ coredata = (struct hppabsd_core_struct *)
+ bfd_zalloc (abfd, sizeof (struct hppabsd_core_struct));
+ if (!coredata)
+ return NULL;
+
+ /* Make the core data and available via the tdata part of the BFD. */
+ abfd->tdata.hppabsd_core_data = coredata;
+
+ /* Create the sections. */
+ core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
+ SEC_ALLOC + SEC_HAS_CONTENTS,
+ clicksz * u.u_ssize,
+ NBPG * (USIZE + KSTAKSIZE)
+ + clicksz * u.u_dsize, 2);
+ core_stacksec (abfd)->vma = USRSTACK;
+
+ core_datasec (abfd) = make_bfd_asection (abfd, ".data",
+ SEC_ALLOC + SEC_LOAD
+ + SEC_HAS_CONTENTS,
+ clicksz * u.u_dsize,
+ NBPG * (USIZE + KSTAKSIZE), 2);
+ core_datasec (abfd)->vma = UDATASEG;
+
+ core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ KSTAKSIZE * NBPG,
+ NBPG * USIZE, 2);
+ core_regsec (abfd)->vma = 0;
+
+ strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
+ core_signal (abfd) = u.u_code;
+ return abfd->xvec;
+}
+
+static char *
+hppabsd_core_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_command (abfd);
+}
+
+/* ARGSUSED */
+static int
+hppabsd_core_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_signal (abfd);
+}
+
+/* ARGSUSED */
+static boolean
+hppabsd_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ /* There's no way to know this... */
+ return true;
+}
+
+
+#define hppabsd_core_get_symtab_upper_bound \
+ _bfd_nosymbols_get_symtab_upper_bound
+#define hppabsd_core_get_symtab _bfd_nosymbols_get_symtab
+#define hppabsd_core_print_symbol _bfd_nosymbols_print_symbol
+#define hppabsd_core_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define hppabsd_core_bfd_is_local_label_name \
+ _bfd_nosymbols_bfd_is_local_label_name
+#define hppabsd_core_get_lineno _bfd_nosymbols_get_lineno
+#define hppabsd_core_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define hppabsd_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define hppabsd_core_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define hppabsd_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort ()
+{
+ /* This way doesn't require any declaration for ANSI to fuck up. */
+ abort ();
+}
+
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target hppabsd_core_vec =
+ {
+ "hppabsd-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ hppabsd_core_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (hppabsd_core),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (hppabsd_core),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
+#endif
diff --git a/bfd/hpux-core.c b/bfd/hpux-core.c
new file mode 100644
index 00000000000..6be709f4999
--- /dev/null
+++ b/bfd/hpux-core.c
@@ -0,0 +1,404 @@
+/* BFD back-end for HP/UX core files.
+ Copyright 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Stu Grossman, Cygnus Support.
+ Converted to back-end form by Ian Lance Taylor, Cygnus SUpport
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file can only be compiled on systems which use HP/UX style
+ core files. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) || defined (HOST_HPPAMPEIX)
+
+/* FIXME: sys/core.h doesn't exist for HPUX version 7. HPUX version
+ 5, 6, and 7 core files seem to be standard trad-core.c type core
+ files; can we just use trad-core.c in addition to this file? */
+
+#include <sys/core.h>
+#include <sys/utsname.h>
+
+#endif /* HOST_HPPAHPUX */
+
+#ifdef HOST_HPPABSD
+
+/* Not a very swift place to put it, but that's where the BSD port
+ puts them. */
+#include "/hpux/usr/include/sys/core.h"
+
+#endif /* HOST_HPPABSD */
+
+#include <sys/param.h>
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# ifdef HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+#include <signal.h>
+#include <machine/reg.h>
+#include <sys/user.h> /* After a.out.h */
+#include <sys/file.h>
+
+/* Kludge: There's no explicit mechanism provided by sys/core.h to
+ conditionally know whether a proc_info has thread id fields.
+ However, CORE_ANON_SHMEM shows up first at 10.30, which is
+ happily also when meaningful thread id's show up in proc_info. */
+#if defined(CORE_ANON_SHMEM)
+#define PROC_INFO_HAS_THREAD_ID (1)
+#endif
+
+/* This type appears at HP-UX 10.30. Defining it if not defined
+ by sys/core.h allows us to build for older HP-UX's, and (since
+ it won't be encountered in core-dumps from older HP-UX's) is
+ harmless. */
+#if !defined(CORE_ANON_SHMEM)
+#define CORE_ANON_SHMEM 0x00000200 /* anonymous shared memory */
+#endif
+
+/* These are stored in the bfd's tdata */
+
+/* .lwpid and .user_tid are only valid if PROC_INFO_HAS_THREAD_ID, else they
+ are set to 0. Also, until HP-UX implements MxN threads, .user_tid and
+ .lwpid are synonymous. */
+struct hpux_core_struct
+{
+ int sig;
+ int lwpid; /* Kernel thread ID. */
+ unsigned long user_tid; /* User thread ID. */
+ char cmd[MAXCOMLEN + 1];
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+#define core_kernel_thread_id(bfd) (core_hdr(bfd)->lwpid)
+#define core_user_thread_id(bfd) (core_hdr(bfd)->user_tid)
+
+static void swap_abort PARAMS ((void));
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
+ bfd *abfd;
+ CONST char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ bfd_vma vma;
+ unsigned int alignment_power;
+{
+ asection *asect;
+ char *newname;
+
+ newname = bfd_alloc (abfd, strlen (name) + 1);
+ if (!newname)
+ return NULL;
+
+ strcpy (newname, name);
+
+ asect = bfd_make_section_anyway (abfd, newname);
+ if (!asect)
+ return NULL;
+
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->vma = vma;
+ asect->filepos = bfd_tell (abfd);
+ asect->alignment_power = alignment_power;
+
+ return asect;
+}
+
+static asymbol *
+hpux_core_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+
+/* this function builds a bfd target if the file is a corefile.
+ It returns null or 0 if it finds out thaat it is not a core file.
+ The way it checks this is by looking for allowed 'type' field values.
+ These are declared in sys/core.h
+ There are some values which are 'reserved for future use'. In particular
+ CORE_NONE is actually defined as 0. This may be a catch-all for cases
+ in which the core file is generated by some non-hpux application.
+ (I am just guessing here!)
+*/
+static const bfd_target *
+hpux_core_core_file_p (abfd)
+ bfd *abfd;
+{
+ int good_sections = 0;
+ int unknown_sections = 0;
+
+ core_hdr (abfd) = (struct hpux_core_struct *)
+ bfd_zalloc (abfd, sizeof (struct hpux_core_struct));
+ if (!core_hdr (abfd))
+ return NULL;
+
+ while (1)
+ {
+ int val;
+ struct corehead core_header;
+
+ val = bfd_read ((void *) &core_header, 1, sizeof core_header, abfd);
+ if (val <= 0)
+ break;
+ switch (core_header.type)
+ {
+ case CORE_KERNEL:
+ case CORE_FORMAT:
+ bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */
+ good_sections++;
+ break;
+ case CORE_EXEC:
+ {
+ struct proc_exec proc_exec;
+ if (bfd_read ((void *) &proc_exec, 1, core_header.len, abfd)
+ != core_header.len)
+ break;
+ strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
+ good_sections++;
+ }
+ break;
+ case CORE_PROC:
+ {
+ struct proc_info proc_info;
+ char secname[100]; /* Of arbitrary size, but plenty large. */
+
+ /* We need to read this section, 'cause we need to determine
+ whether the core-dumped app was threaded before we create
+ any .reg sections. */
+ if (bfd_read (&proc_info, 1, core_header.len, abfd)
+ != core_header.len)
+ break;
+
+ /* However, we also want to create those sections with the
+ file positioned at the start of the record, it seems. */
+ if (bfd_seek (abfd, -core_header.len, SEEK_CUR) != 0)
+ break;
+
+#if defined(PROC_INFO_HAS_THREAD_ID)
+ core_kernel_thread_id (abfd) = proc_info.lwpid;
+ core_user_thread_id (abfd) = proc_info.user_tid;
+#else
+ core_kernel_thread_id (abfd) = 0;
+ core_user_thread_id (abfd) = 0;
+#endif
+ /* If the program was unthreaded, then we'll just create a
+ .reg section.
+
+ If the program was threaded, then we'll create .reg/XXXXX
+ section for each thread, where XXXXX is a printable
+ representation of the kernel thread id. We'll also
+ create a .reg section for the thread that was running
+ and signalled at the time of the core-dump (i.e., this
+ is effectively an alias, needed to keep GDB happy.)
+
+ Note that we use `.reg/XXXXX' as opposed to '.regXXXXX'
+ because GDB expects that .reg2 will be the floating-
+ point registers. */
+ if (core_kernel_thread_id (abfd) == 0)
+ {
+ if (!make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ core_header.len,
+ (int) &proc_info - (int) & proc_info.hw_regs,
+ 2))
+ return NULL;
+ }
+ else
+ {
+ /* There are threads. Is this the one that caused the
+ core-dump? We'll claim it was the running thread. */
+ if (proc_info.sig != -1)
+ {
+ if (!make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ core_header.len,
+ (int) &proc_info - (int) & proc_info.hw_regs,
+ 2))
+ return NULL;
+ }
+ /* We always make one of these sections, for every thread. */
+ sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
+ if (!make_bfd_asection (abfd, secname,
+ SEC_HAS_CONTENTS,
+ core_header.len,
+ (int) &proc_info - (int) & proc_info.hw_regs,
+ 2))
+ return NULL;
+ }
+ core_signal (abfd) = proc_info.sig;
+ if (bfd_seek (abfd, core_header.len, SEEK_CUR) != 0)
+ break;
+ good_sections++;
+ }
+ break;
+
+ case CORE_DATA:
+ case CORE_STACK:
+ case CORE_TEXT:
+ case CORE_MMF:
+ case CORE_SHM:
+ case CORE_ANON_SHMEM:
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ core_header.len, core_header.addr, 2))
+ return NULL;
+
+ bfd_seek (abfd, core_header.len, SEEK_CUR);
+ good_sections++;
+ break;
+
+ case CORE_NONE:
+ /* Let's not punt if we encounter a section of unknown
+ type. Rather, let's make a note of it. If we later
+ see that there were also "good" sections, then we'll
+ declare that this a core file, but we'll also warn that
+ it may be incompatible with this gdb.
+ */
+ unknown_sections++;
+ break;
+
+ default: return 0; /*unrecognized core file type */
+ }
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ /* Were there sections of unknown type? If so, yet there were
+ at least some complete sections of known type, then, issue
+ a warning. Possibly the core file was generated on a version
+ of HP-UX that is incompatible with that for which this gdb was
+ built.
+ */
+ if ((unknown_sections > 0) && (good_sections > 0))
+ (*_bfd_error_handler)
+ ("%s appears to be a core file,\nbut contains unknown sections. It may have been created on an incompatible\nversion of HP-UX. As a result, some information may be unavailable.\n",
+ abfd->filename);
+
+ return abfd->xvec;
+}
+
+static char *
+hpux_core_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_command (abfd);
+}
+
+/* ARGSUSED */
+static int
+hpux_core_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_signal (abfd);
+}
+
+/* ARGSUSED */
+static boolean
+hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this point */
+}
+
+#define hpux_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
+#define hpux_core_get_symtab _bfd_nosymbols_get_symtab
+#define hpux_core_print_symbol _bfd_nosymbols_print_symbol
+#define hpux_core_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define hpux_core_bfd_is_local_label_name \
+ _bfd_nosymbols_bfd_is_local_label_name
+#define hpux_core_get_lineno _bfd_nosymbols_get_lineno
+#define hpux_core_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define hpux_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define hpux_core_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define hpux_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target hpux_core_vec =
+ {
+ "hpux-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ hpux_core_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (hpux_core),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (hpux_core),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
diff --git a/bfd/i386aout.c b/bfd/i386aout.c
new file mode 100644
index 00000000000..d0b2cffef23
--- /dev/null
+++ b/bfd/i386aout.c
@@ -0,0 +1,91 @@
+/* BFD back-end for i386 a.out binaries.
+ Copyright 1990, 91, 92, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* The only 386 aout system we have here is GO32 from DJ.
+ These numbers make BFD work with that. If your aout 386 system
+ doesn't work with these, we'll have to split them into different
+ files. Send me (sac@cygnus.com) the runes to make it work on your
+ system, and I'll stick it in for the next release. */
+
+#define N_HEADER_IN_TEXT(x) 0
+#define BYTES_IN_WORD 4
+
+#define N_TXTOFF(x) 0x20
+#define N_TXTADDR(x) (N_MAGIC(x)==ZMAGIC ? 0x1020 : 0)
+
+#define N_TXTSIZE(x) ((x).a_text)
+#if 0
+#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) : (SEGMENT_SIZE + ((0x1020+(x).a_text-1) & ~(SEGMENT_SIZE-1))))
+#define NOSUBEXECB
+
+#endif
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE 0x400000
+#define DEFAULT_ARCH bfd_arch_i386
+
+#define MY(OP) CAT(i386aout_,OP)
+#define TARGETNAME "a.out-i386"
+#define NO_WRITE_HEADER_KLUDGE 1
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "libaout.h"
+
+/* Set the machine type correctly. */
+
+static boolean
+i386aout_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ N_SET_MACHTYPE (*execp, M_386);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ WRITE_HEADERS (abfd, execp);
+
+ return true;
+}
+
+#define MY_write_object_contents i386aout_write_object_contents
+
+static boolean MY(set_sizes)();
+#define MY_backend_data &MY(backend_data)
+static CONST struct aout_backend_data MY(backend_data) = {
+ 0, /* zmagic contiguous */
+ 1, /* text incl header */
+ 0, /* entry is text address */
+ 0, /* exec_hdr_flags */
+ 0, /* text vma? */
+ MY(set_sizes),
+ 1, /* exec header not counted */
+ 0, /* add_dynamic_symbols */
+ 0, /* add_one_symbol */
+ 0, /* link_dynamic_object */
+ 0, /* write_dynamic_symbol */
+ 0, /* check_dynamic_reloc */
+ 0 /* finish_dynamic_link */
+};
+
+#include "aout-target.h"
diff --git a/bfd/i386bsd.c b/bfd/i386bsd.c
new file mode 100644
index 00000000000..2328fe3e9e8
--- /dev/null
+++ b/bfd/i386bsd.c
@@ -0,0 +1,46 @@
+/* BFD back-end for i386 a.out binaries under BSD.
+ Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This data should be correct for the format used under all the various
+ BSD ports for 386 machines. */
+
+#define BYTES_IN_WORD 4
+
+/* ZMAGIC files never have the header in the text. */
+#define N_HEADER_IN_TEXT(x) 0
+
+/* ZMAGIC files start at address 0. This does not apply to QMAGIC. */
+#define TEXT_START_ADDR 0
+#define N_SHARED_LIB(x) 0
+
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#define DEFAULT_ARCH bfd_arch_i386
+#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN)
+
+#define MY(OP) CAT(i386bsd_,OP)
+#define TARGETNAME "a.out-i386-bsd"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#include "aout-target.h"
diff --git a/bfd/i386dynix.c b/bfd/i386dynix.c
new file mode 100644
index 00000000000..ff50a1450a1
--- /dev/null
+++ b/bfd/i386dynix.c
@@ -0,0 +1,80 @@
+/* BFD back-end for i386 a.out binaries under dynix.
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This BFD is currently only tested with gdb, writing object files
+ may not work. */
+
+#define BYTES_IN_WORD 4
+
+#define TEXT_START_ADDR 4096
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#include "aout/dynix3.h"
+
+#define DEFAULT_ARCH bfd_arch_i386
+#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN)
+
+#define MY(OP) CAT(i386dynix_,OP)
+#define TARGETNAME "a.out-i386-dynix"
+#define NAME(x,y) CAT3(i386dynix,_32_,y)
+#define ARCH_SIZE 32
+#define NAME_swap_exec_header_in NAME(i386dynix_32_,swap_exec_header_in)
+#define MY_get_section_contents aout_32_get_section_contents
+
+/* aoutx.h requires definitions for NMAGIC, BMAGIC and QMAGIC. */
+#define NMAGIC 0
+#define BMAGIC OMAGIC
+#define QMAGIC XMAGIC
+
+#include "aoutx.h"
+
+/* (Ab)use some fields in the internal exec header to be able to read
+ executables that contain shared data. */
+
+#define a_shdata a_tload
+#define a_shdrsize a_dload
+
+void
+i386dynix_32_swap_exec_header_in (abfd, raw_bytes, execp)
+ bfd *abfd;
+ struct external_exec *raw_bytes;
+ struct internal_exec *execp;
+{
+ struct external_exec *bytes = (struct external_exec *)raw_bytes;
+
+ /* The internal_exec structure has some fields that are unused in this
+ configuration (IE for i960), so ensure that all such uninitialized
+ fields are zero'd out. There are places where two of these structs
+ are memcmp'd, and thus the contents do matter. */
+ memset ((PTR) execp, 0, sizeof (struct internal_exec));
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
+ execp->a_text = GET_WORD (abfd, bytes->e_text);
+ execp->a_data = GET_WORD (abfd, bytes->e_data);
+ execp->a_bss = GET_WORD (abfd, bytes->e_bss);
+ execp->a_syms = GET_WORD (abfd, bytes->e_syms);
+ execp->a_entry = GET_WORD (abfd, bytes->e_entry);
+ execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
+ execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
+ execp->a_shdata = GET_WORD (abfd, bytes->e_shdata);
+ execp->a_shdrsize = GET_WORD (abfd, bytes->e_shdrsize);
+}
+
+#include "aout-target.h"
diff --git a/bfd/i386freebsd.c b/bfd/i386freebsd.c
new file mode 100644
index 00000000000..7a6371b5df6
--- /dev/null
+++ b/bfd/i386freebsd.c
@@ -0,0 +1,33 @@
+/* BFD back-end for FreeBSD/386 a.out-ish binaries.
+ Copyright (C) 1990, 1991, 1992, 1996 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#undef TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#define DEFAULT_ARCH bfd_arch_i386
+#define MACHTYPE_OK(mtype) ((mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN)
+
+#define MY(OP) CAT(i386freebsd_,OP)
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-i386-freebsd"
+
+#include "freebsd.h"
diff --git a/bfd/i386linux.c b/bfd/i386linux.c
new file mode 100644
index 00000000000..804bdcd1c1a
--- /dev/null
+++ b/bfd/i386linux.c
@@ -0,0 +1,767 @@
+/* BFD back-end for linux flavored i386 a.out binaries.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define ZMAGIC_DISK_BLOCK_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0x0
+#define N_SHARED_LIB(x) 0
+#define BYTES_IN_WORD 4
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#define DEFAULT_ARCH bfd_arch_i386
+#define MY(OP) CAT(i386linux_,OP)
+#define TARGETNAME "a.out-i386-linux"
+
+extern const bfd_target MY(vec);
+
+/* We always generate QMAGIC files in preference to ZMAGIC files. It
+ would be possible to make this a linker option, if that ever
+ becomes important. */
+
+static void MY_final_link_callback
+ PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+static boolean i386linux_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean i386linux_write_object_contents PARAMS ((bfd *));
+
+static boolean
+i386linux_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ obj_aout_subformat (abfd) = q_magic_format;
+ return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
+}
+
+#define MY_bfd_final_link i386linux_bfd_final_link
+
+/* Set the machine type correctly. */
+
+static boolean
+i386linux_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ N_SET_MACHTYPE (*execp, M_386);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
+
+#define MY_write_object_contents i386linux_write_object_contents
+
+/* Code to link against Linux a.out shared libraries. */
+
+/* See if a symbol name is a reference to the global offset table. */
+
+#ifndef GOT_REF_PREFIX
+#define GOT_REF_PREFIX "__GOT_"
+#endif
+
+#define IS_GOT_SYM(name) \
+ (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
+
+/* See if a symbol name is a reference to the procedure linkage table. */
+
+#ifndef PLT_REF_PREFIX
+#define PLT_REF_PREFIX "__PLT_"
+#endif
+
+#define IS_PLT_SYM(name) \
+ (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
+
+/* This string is used to generate specialized error messages. */
+
+#ifndef NEEDS_SHRLIB
+#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
+#endif
+
+/* This special symbol is a set vector that contains a list of
+ pointers to fixup tables. It will be present in any dynamicly
+ linked file. The linker generated fixup table should also be added
+ to the list, and it should always appear in the second slot (the
+ first one is a dummy with a magic number that is defined in
+ crt0.o). */
+
+#ifndef SHARABLE_CONFLICTS
+#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
+#endif
+
+/* We keep a list of fixups. The terminology is a bit strange, but
+ each fixup contains two 32 bit numbers. A regular fixup contains
+ an address and a pointer, and at runtime we should store the
+ address at the location pointed to by the pointer. A builtin fixup
+ contains two pointers, and we should read the address using one
+ pointer and store it at the location pointed to by the other
+ pointer. Builtin fixups come into play when we have duplicate
+ __GOT__ symbols for the same variable. The builtin fixup will copy
+ the GOT pointer from one over into the other. */
+
+struct fixup
+{
+ struct fixup *next;
+ struct linux_link_hash_entry *h;
+ bfd_vma value;
+
+ /* Nonzero if this is a jump instruction that needs to be fixed,
+ zero if this is just a pointer */
+ char jump;
+
+ char builtin;
+};
+
+/* We don't need a special hash table entry structure, but we do need
+ to keep some information between linker passes, so we use a special
+ hash table. */
+
+struct linux_link_hash_entry
+{
+ struct aout_link_hash_entry root;
+};
+
+struct linux_link_hash_table
+{
+ struct aout_link_hash_table root;
+
+ /* First dynamic object found in link. */
+ bfd *dynobj;
+
+ /* Number of fixups. */
+ size_t fixup_count;
+
+ /* Number of builtin fixups. */
+ size_t local_builtins;
+
+ /* List of fixups. */
+ struct fixup *fixup_list;
+};
+
+static struct bfd_hash_entry *linux_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *linux_link_hash_table_create
+ PARAMS ((bfd *));
+static struct fixup *new_fixup
+ PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
+ bfd_vma, int));
+static boolean linux_link_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean linux_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, boolean, boolean,
+ struct bfd_link_hash_entry **));
+static boolean linux_tally_symbols
+ PARAMS ((struct linux_link_hash_entry *, PTR));
+static boolean linux_finish_dynamic_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Routine to create an entry in an Linux link hash table. */
+
+static struct bfd_hash_entry *
+linux_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct linux_link_hash_entry *) NULL)
+ ret = ((struct linux_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct linux_link_hash_entry *)
+ NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ /* Set local fields; there aren't any. */
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a Linux link hash table. */
+
+static struct bfd_link_hash_table *
+linux_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct linux_link_hash_table *ret;
+
+ ret = ((struct linux_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));
+ if (ret == (struct linux_link_hash_table *) NULL)
+ return (struct bfd_link_hash_table *) NULL;
+ if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
+ linux_link_hash_newfunc))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->dynobj = NULL;
+ ret->fixup_count = 0;
+ ret->local_builtins = 0;
+ ret->fixup_list = NULL;
+
+ return &ret->root.root;
+}
+
+/* Look up an entry in a Linux link hash table. */
+
+#define linux_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct linux_link_hash_entry *) \
+ aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
+ (follow)))
+
+/* Traverse a Linux link hash table. */
+
+#define linux_link_hash_traverse(table, func, info) \
+ (aout_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the Linux link hash table from the info structure. This is
+ just a cast. */
+
+#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
+
+/* Store the information for a new fixup. */
+
+static struct fixup *
+new_fixup (info, h, value, builtin)
+ struct bfd_link_info *info;
+ struct linux_link_hash_entry *h;
+ bfd_vma value;
+ int builtin;
+{
+ struct fixup *f;
+
+ f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
+ sizeof (struct fixup));
+ if (f == NULL)
+ return f;
+ f->next = linux_hash_table (info)->fixup_list;
+ linux_hash_table (info)->fixup_list = f;
+ f->h = h;
+ f->value = value;
+ f->builtin = builtin;
+ f->jump = 0;
+ ++linux_hash_table (info)->fixup_count;
+ return f;
+}
+
+/* We come here once we realize that we are going to link to a shared
+ library. We need to create a special section that contains the
+ fixup table, and we ultimately need to add a pointer to this into
+ the set vector for SHARABLE_CONFLICTS. At this point we do not
+ know the size of the section, but that's OK - we just need to
+ create it for now. */
+
+static boolean
+linux_link_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+
+ /* Note that we set the SEC_IN_MEMORY flag. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ /* We choose to use the name ".linux-dynamic" for the fixup table.
+ Why not? */
+ s = bfd_make_section (abfd, ".linux-dynamic");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+ s->_raw_size = 0;
+ s->contents = 0;
+
+ return true;
+}
+
+/* Function to add a single symbol to the linker hash table. This is
+ a wrapper around _bfd_generic_link_add_one_symbol which handles the
+ tweaking needed for dynamic linking support. */
+
+static boolean
+linux_add_one_symbol (info, abfd, name, flags, section, value, string,
+ copy, collect, hashp)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ const char *string;
+ boolean copy;
+ boolean collect;
+ struct bfd_link_hash_entry **hashp;
+{
+ struct linux_link_hash_entry *h;
+ boolean insert;
+
+ /* Look up and see if we already have this symbol in the hash table.
+ If we do, and the defining entry is from a shared library, we
+ need to create the dynamic sections.
+
+ FIXME: What if abfd->xvec != info->hash->creator? We may want to
+ be able to link Linux a.out and ELF objects together, but serious
+ confusion is possible. */
+
+ insert = false;
+
+ if (! info->relocateable
+ && linux_hash_table (info)->dynobj == NULL
+ && strcmp (name, SHARABLE_CONFLICTS) == 0
+ && (flags & BSF_CONSTRUCTOR) != 0
+ && abfd->xvec == info->hash->creator)
+ {
+ if (! linux_link_create_dynamic_sections (abfd, info))
+ return false;
+ linux_hash_table (info)->dynobj = abfd;
+ insert = true;
+ }
+
+ if (bfd_is_abs_section (section)
+ && abfd->xvec == info->hash->creator)
+ {
+ h = linux_link_hash_lookup (linux_hash_table (info), name, false,
+ false, false);
+ if (h != NULL
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak))
+ {
+ struct fixup *f;
+
+ if (hashp != NULL)
+ *hashp = (struct bfd_link_hash_entry *) h;
+
+ f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
+ if (f == NULL)
+ return false;
+ f->jump = IS_PLT_SYM (name);
+
+ return true;
+ }
+ }
+
+ /* Do the usual procedure for adding a symbol. */
+ if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
+ value, string, copy, collect,
+ hashp))
+ return false;
+
+ /* Insert a pointer to our table in the set vector. The dynamic
+ linker requires this information */
+ if (insert)
+ {
+ asection *s;
+
+ /* Here we do our special thing to add the pointer to the
+ dynamic section in the SHARABLE_CONFLICTS set vector. */
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ BFD_ASSERT (s != NULL);
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
+ BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL)))
+ return false;
+ }
+
+ return true;
+}
+
+/* We will crawl the hash table and come here for every global symbol.
+ We will examine each entry and see if there are indications that we
+ need to add a fixup. There are two possible cases - one is where
+ you have duplicate definitions of PLT or GOT symbols - these will
+ have already been caught and added as "builtin" fixups. If we find
+ that the corresponding non PLT/GOT symbol is also present, we
+ convert it to a regular fixup instead.
+
+ This function is called via linux_link_hash_traverse. */
+
+static boolean
+linux_tally_symbols (h, data)
+ struct linux_link_hash_entry *h;
+ PTR data;
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
+ struct fixup *f, *f1;
+ int is_plt;
+ struct linux_link_hash_entry *h1, *h2;
+ boolean exists;
+
+ if (h->root.root.type == bfd_link_hash_undefined
+ && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
+ sizeof NEEDS_SHRLIB - 1) == 0)
+ {
+ const char *name;
+ char *p;
+ char *alloc = NULL;
+
+ name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
+ p = strrchr (name, '_');
+ if (p != NULL)
+ alloc = (char *) bfd_malloc (strlen (name) + 1);
+
+ if (p == NULL || alloc == NULL)
+ (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
+ name);
+ else
+ {
+ strcpy (alloc, name);
+ p = strrchr (alloc, '_');
+ *p++ = '\0';
+ (*_bfd_error_handler)
+ (_("Output file requires shared library `%s.so.%s'\n"),
+ alloc, p);
+ free (alloc);
+ }
+
+ abort ();
+ }
+
+ /* If this symbol is not a PLT/GOT, we do not even need to look at it */
+ is_plt = IS_PLT_SYM (h->root.root.root.string);
+
+ if (is_plt || IS_GOT_SYM (h->root.root.root.string))
+ {
+ /* Look up this symbol twice. Once just as a regular lookup,
+ and then again following all of the indirect links until we
+ reach a real symbol. */
+ h1 = linux_link_hash_lookup (linux_hash_table (info),
+ (h->root.root.root.string
+ + sizeof PLT_REF_PREFIX - 1),
+ false, false, true);
+ /* h2 does not follow indirect symbols. */
+ h2 = linux_link_hash_lookup (linux_hash_table (info),
+ (h->root.root.root.string
+ + sizeof PLT_REF_PREFIX - 1),
+ false, false, false);
+
+ /* The real symbol must exist but if it is also an ABS symbol,
+ there is no need to have a fixup. This is because they both
+ came from the same library. If on the other hand, we had to
+ use an indirect symbol to get to the real symbol, we add the
+ fixup anyway, since there are cases where these symbols come
+ from different shared libraries */
+ if (h1 != NULL
+ && (((h1->root.root.type == bfd_link_hash_defined
+ || h1->root.root.type == bfd_link_hash_defweak)
+ && ! bfd_is_abs_section (h1->root.root.u.def.section))
+ || h2->root.root.type == bfd_link_hash_indirect))
+ {
+ /* See if there is a "builtin" fixup already present
+ involving this symbol. If so, convert it to a regular
+ fixup. In the end, this relaxes some of the requirements
+ about the order of performing fixups. */
+ exists = false;
+ for (f1 = linux_hash_table (info)->fixup_list;
+ f1 != NULL;
+ f1 = f1->next)
+ {
+ if ((f1->h != h && f1->h != h1)
+ || (! f1->builtin && ! f1->jump))
+ continue;
+ if (f1->h == h1)
+ exists = true;
+ if (! exists
+ && bfd_is_abs_section (h->root.root.u.def.section))
+ {
+ f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
+ f->jump = is_plt;
+ }
+ f1->h = h1;
+ f1->jump = is_plt;
+ f1->builtin = 0;
+ exists = true;
+ }
+ if (! exists
+ && bfd_is_abs_section (h->root.root.u.def.section))
+ {
+ f = new_fixup (info, h1, h->root.root.u.def.value, 0);
+ if (f == NULL)
+ {
+ /* FIXME: No way to return error. */
+ abort ();
+ }
+ f->jump = is_plt;
+ }
+ }
+
+ /* Quick and dirty way of stripping these symbols from the
+ symtab. */
+ if (bfd_is_abs_section (h->root.root.u.def.section))
+ h->root.written = true;
+ }
+
+ return true;
+}
+
+/* This is called to set the size of the .linux-dynamic section is.
+ It is called by the Linux linker emulation before_allocation
+ routine. We have finished reading all of the input files, and now
+ we just scan the hash tables to find out how many additional fixups
+ are required. */
+
+boolean
+bfd_i386linux_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ struct fixup *f;
+ asection *s;
+
+ if (output_bfd->xvec != &MY(vec))
+ return true;
+
+ /* First find the fixups... */
+ linux_link_hash_traverse (linux_hash_table (info),
+ linux_tally_symbols,
+ (PTR) info);
+
+ /* If there are builtin fixups, leave room for a marker. This is
+ used by the dynamic linker so that it knows that all that follow
+ are builtin fixups instead of regular fixups. */
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (f->builtin)
+ {
+ ++linux_hash_table (info)->fixup_count;
+ ++linux_hash_table (info)->local_builtins;
+ break;
+ }
+ }
+
+ if (linux_hash_table (info)->dynobj == NULL)
+ {
+ if (linux_hash_table (info)->fixup_count > 0)
+ abort ();
+ return true;
+ }
+
+ /* Allocate memory for our fixup table. We will fill it in later. */
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ if (s != NULL)
+ {
+ s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+ memset (s->contents, 0, (size_t) s->_raw_size);
+ }
+
+ return true;
+}
+
+/* We come here once we are ready to actually write the fixup table to
+ the output file. Scan the fixup tables and so forth and generate
+ the stuff we need. */
+
+static boolean
+linux_finish_dynamic_link (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ asection *s, *os, *is;
+ bfd_byte *fixup_table;
+ struct linux_link_hash_entry *h;
+ struct fixup *f;
+ unsigned int new_addr;
+ int section_offset;
+ unsigned int fixups_written;
+
+ if (linux_hash_table (info)->dynobj == NULL)
+ return true;
+
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ BFD_ASSERT (s != NULL);
+ os = s->output_section;
+ fixups_written = 0;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup table file offset: %x VMA: %x\n",
+ os->filepos + s->output_offset,
+ os->vma + s->output_offset);
+#endif
+
+ fixup_table = s->contents;
+ bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table);
+ fixup_table += 4;
+
+ /* Fill in fixup table. */
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (f->builtin)
+ continue;
+
+ if (f->h->root.root.type != bfd_link_hash_defined
+ && f->h->root.root.type != bfd_link_hash_defweak)
+ {
+ (*_bfd_error_handler)
+ (_("Symbol %s not defined for fixups\n"),
+ f->h->root.root.root.string);
+ continue;
+ }
+
+ is = f->h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = f->h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
+ new_addr, f->value);
+#endif
+
+ if (f->jump)
+ {
+ /* Relative address */
+ new_addr = new_addr - (f->value + 5);
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value + 1, fixup_table);
+ fixup_table += 4;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value, fixup_table);
+ fixup_table += 4;
+ }
+ ++fixups_written;
+ }
+
+ if (linux_hash_table (info)->local_builtins != 0)
+ {
+ /* Special marker so we know to switch to the other type of fixup */
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (! f->builtin)
+ continue;
+
+ if (f->h->root.root.type != bfd_link_hash_defined
+ && f->h->root.root.type != bfd_link_hash_defweak)
+ {
+ (*_bfd_error_handler)
+ (_("Symbol %s not defined for fixups\n"),
+ f->h->root.root.root.string);
+ continue;
+ }
+
+ is = f->h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = f->h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
+ new_addr, f->value);
+#endif
+
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ }
+ }
+
+ if (linux_hash_table (info)->fixup_count != fixups_written)
+ {
+ (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
+ while (linux_hash_table (info)->fixup_count > fixups_written)
+ {
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ }
+ }
+
+ h = linux_link_hash_lookup (linux_hash_table (info),
+ "__BUILTIN_FIXUPS__",
+ false, false, false);
+
+ if (h != NULL
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak))
+ {
+ is = h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Builtin fixup table at %x\n", new_addr);
+#endif
+
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ }
+ else
+ bfd_put_32 (output_bfd, 0, fixup_table);
+
+ if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0)
+ return false;
+
+ if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd)
+ != s->_raw_size)
+ return false;
+
+ return true;
+}
+
+#define MY_bfd_link_hash_table_create linux_link_hash_table_create
+#define MY_add_one_symbol linux_add_one_symbol
+#define MY_finish_dynamic_link linux_finish_dynamic_link
+
+#define MY_zmagic_contiguous 1
+
+#include "aout-target.h"
diff --git a/bfd/i386lynx.c b/bfd/i386lynx.c
new file mode 100644
index 00000000000..1f0344ec000
--- /dev/null
+++ b/bfd/i386lynx.c
@@ -0,0 +1,562 @@
+/* BFD back-end for i386 a.out binaries under LynxOS.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#define N_SHARED_LIB(x) 0
+
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_i386
+
+#define MY(OP) CAT(i386lynx_aout_,OP)
+#define TARGETNAME "a.out-i386-lynx"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifndef WRITE_HEADERS
+#define WRITE_HEADERS(abfd, execp) \
+ { \
+ bfd_size_type text_size; /* dummy vars */ \
+ file_ptr text_end; \
+ if (adata(abfd).magic == undecided_magic) \
+ NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
+ \
+ execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
+ 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)); \
+ NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
+ \
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
+ if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
+ != EXEC_BYTES_SIZE) \
+ 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(*execp)), SEEK_SET) \
+ != 0) \
+ return false; \
+ \
+ if (! NAME(aout,write_syms)(abfd)) return false; \
+ \
+ if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \
+ != 0) \
+ return false; \
+ \
+ if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
+ return false; \
+ if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \
+ != 0) \
+ return 0; \
+ \
+ if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
+ return false; \
+ } \
+ }
+#endif
+
+#include "libaout.h"
+#include "aout/aout64.h"
+
+#ifdef LYNX_CORE
+
+char *lynx_core_file_failing_command ();
+int lynx_core_file_failing_signal ();
+boolean lynx_core_file_matches_executable_p ();
+const bfd_target *lynx_core_file_p ();
+
+#define MY_core_file_failing_command lynx_core_file_failing_command
+#define MY_core_file_failing_signal lynx_core_file_failing_signal
+#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
+#define MY_core_file_p lynx_core_file_p
+
+#endif /* LYNX_CORE */
+
+
+#define KEEPIT udata.i
+
+extern reloc_howto_type aout_32_ext_howto_table[];
+extern reloc_howto_type aout_32_std_howto_table[];
+
+/* Standard reloc stuff */
+/* Output standard relocation information to a file in target byte order. */
+
+void
+NAME(lynx,swap_std_reloc_out) (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ struct reloc_std_external *natptr;
+{
+ int r_index;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ int r_extern;
+ unsigned int r_length;
+ int r_pcrel;
+ int r_baserel, r_jmptable, r_relative;
+ unsigned int r_addend;
+ asection *output_section = sym->section->output_section;
+
+ PUT_WORD (abfd, g->address, natptr->r_address);
+
+ r_length = g->howto->size; /* Size as a power of two */
+ r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
+ /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
+ r_baserel = 0;
+ r_jmptable = 0;
+ r_relative = 0;
+
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+
+ /* name was clobbered by aout_write_syms to be symbol index */
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ check for that here
+ */
+
+
+ if (bfd_is_com_section (output_section)
+ || bfd_is_abs_section (output_section)
+ || bfd_is_und_section (output_section))
+ {
+ if (bfd_abs_section_ptr->symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_index = 0;
+ r_extern = 0;
+ }
+ else
+ {
+ /* Fill in symbol */
+ r_extern = 1;
+ r_index = (*g->sym_ptr_ptr)->KEEPIT;
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd))
+ {
+ natptr->r_index[0] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[2] = r_index;
+ natptr->r_type[0] =
+ (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
+ | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
+ | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
+ | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
+ }
+ else
+ {
+ natptr->r_index[2] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[0] = r_index;
+ natptr->r_type[0] =
+ (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
+ | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
+ | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
+ | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
+ }
+}
+
+
+/* Extended stuff */
+/* Output extended relocation information to a file in target byte order. */
+
+void
+NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ register struct reloc_ext_external *natptr;
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_type;
+ unsigned int r_addend;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ asection *output_section = sym->section->output_section;
+
+ PUT_WORD (abfd, g->address, natptr->r_address);
+
+ r_type = (unsigned int) g->howto->type;
+
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ check for that here
+ */
+
+ if (bfd_is_com_section (output_section)
+ || bfd_is_abs_section (output_section)
+ || bfd_is_und_section (output_section))
+ {
+ if (bfd_abs_section_ptr->symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_index = 0;
+ r_extern = 0;
+ }
+ else
+ {
+ r_extern = 1;
+ r_index = (*g->sym_ptr_ptr)->KEEPIT;
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd))
+ {
+ natptr->r_index[0] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[2] = r_index;
+ natptr->r_type[0] =
+ (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
+ | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
+ }
+ else
+ {
+ natptr->r_index[2] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[0] = r_index;
+ natptr->r_type[0] =
+ (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
+ | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
+ }
+
+ PUT_WORD (abfd, r_addend, natptr->r_addend);
+}
+
+/* BFD deals internally with all things based from the section they're
+ in. so, something in 10 bytes into a text section with a base of
+ 50 would have a symbol (.text+10) and know .text vma was 50.
+
+ Aout keeps all it's symbols based from zero, so the symbol would
+ contain 60. This macro subs the base of each section from the value
+ to give the true offset from the section */
+
+
+#define MOVE_ADDRESS(ad) \
+ if (r_extern) { \
+ /* undefined symbol */ \
+ cache_ptr->sym_ptr_ptr = symbols + r_index; \
+ cache_ptr->addend = ad; \
+ } else { \
+ /* defined, section relative. replace symbol with pointer to \
+ symbol which points to section */ \
+ switch (r_index) { \
+ case N_TEXT: \
+ case N_TEXT | N_EXT: \
+ cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \
+ cache_ptr->addend = ad - su->textsec->vma; \
+ break; \
+ case N_DATA: \
+ case N_DATA | N_EXT: \
+ cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \
+ cache_ptr->addend = ad - su->datasec->vma; \
+ break; \
+ case N_BSS: \
+ case N_BSS | N_EXT: \
+ cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \
+ cache_ptr->addend = ad - su->bsssec->vma; \
+ break; \
+ default: \
+ case N_ABS: \
+ case N_ABS | N_EXT: \
+ cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
+ cache_ptr->addend = ad; \
+ break; \
+ } \
+ } \
+
+void
+NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct reloc_ext_external *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_type;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
+
+ r_index = bytes->r_index[1];
+ r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG));
+ r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG)
+ >> RELOC_EXT_BITS_TYPE_SH_BIG;
+
+ cache_ptr->howto = aout_32_ext_howto_table + r_type;
+ MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
+}
+
+void
+NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
+ bfd *abfd;
+ struct reloc_std_external *bytes;
+ arelent *cache_ptr;
+ asymbol **symbols;
+ bfd_size_type symcount;
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_length;
+ int r_pcrel;
+ int r_baserel, r_jmptable, r_relative;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
+
+ r_index = bytes->r_index[1];
+ r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG));
+ r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG));
+ r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG));
+ r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+ r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG));
+ r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG)
+ >> RELOC_STD_BITS_LENGTH_SH_BIG;
+
+ cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel;
+ /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
+
+ MOVE_ADDRESS (0);
+}
+
+/* Reloc hackery */
+
+boolean
+NAME(lynx,slurp_reloc_table) (abfd, asect, symbols)
+ bfd *abfd;
+ sec_ptr asect;
+ asymbol **symbols;
+{
+ unsigned int count;
+ bfd_size_type reloc_size;
+ PTR relocs;
+ arelent *reloc_cache;
+ size_t each_size;
+
+ if (asect->relocation)
+ return true;
+
+ if (asect->flags & SEC_CONSTRUCTOR)
+ return true;
+
+ if (asect == obj_datasec (abfd))
+ {
+ reloc_size = exec_hdr (abfd)->a_drsize;
+ goto doit;
+ }
+
+ if (asect == obj_textsec (abfd))
+ {
+ reloc_size = exec_hdr (abfd)->a_trsize;
+ goto doit;
+ }
+
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+
+doit:
+ if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+ return false;
+ each_size = obj_reloc_entry_size (abfd);
+
+ count = reloc_size / each_size;
+
+
+ reloc_cache = (arelent *) bfd_malloc (count * sizeof (arelent));
+ if (!reloc_cache && count != 0)
+ return false;
+ memset (reloc_cache, 0, count * sizeof (arelent));
+
+ relocs = (PTR) bfd_alloc (abfd, reloc_size);
+ if (!relocs && reloc_size != 0)
+ {
+ free (reloc_cache);
+ return false;
+ }
+
+ if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
+ {
+ bfd_release (abfd, relocs);
+ free (reloc_cache);
+ return false;
+ }
+
+ if (each_size == RELOC_EXT_SIZE)
+ {
+ register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
+ unsigned int counter = 0;
+ arelent *cache_ptr = reloc_cache;
+
+ for (; counter < count; counter++, rptr++, cache_ptr++)
+ {
+ NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
+ bfd_get_symcount (abfd));
+ }
+ }
+ else
+ {
+ register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
+ unsigned int counter = 0;
+ arelent *cache_ptr = reloc_cache;
+
+ for (; counter < count; counter++, rptr++, cache_ptr++)
+ {
+ NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,
+ bfd_get_symcount (abfd));
+ }
+
+ }
+
+ bfd_release (abfd, relocs);
+ asect->relocation = reloc_cache;
+ asect->reloc_count = count;
+ return true;
+}
+
+
+
+/* Write out a relocation section into an object file. */
+
+boolean
+NAME(lynx,squirt_out_relocs) (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ arelent **generic;
+ unsigned char *native, *natptr;
+ size_t each_size;
+
+ unsigned int count = section->reloc_count;
+ size_t natsize;
+
+ if (count == 0)
+ return true;
+
+ each_size = obj_reloc_entry_size (abfd);
+ natsize = each_size * count;
+ native = (unsigned char *) bfd_zalloc (abfd, natsize);
+ if (!native)
+ return false;
+
+ generic = section->orelocation;
+
+ if (each_size == RELOC_EXT_SIZE)
+ {
+ for (natptr = native;
+ count != 0;
+ --count, natptr += each_size, ++generic)
+ NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr);
+ }
+ else
+ {
+ for (natptr = native;
+ count != 0;
+ --count, natptr += each_size, ++generic)
+ NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr);
+ }
+
+ if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
+ {
+ bfd_release (abfd, native);
+ return false;
+ }
+ bfd_release (abfd, native);
+
+ return true;
+}
+
+/* This is stupid. This function should be a boolean predicate */
+long
+NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr = section->relocation;
+ unsigned int count;
+
+ if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols)))
+ return -1;
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ arelent_chain *chain = section->constructor_chain;
+ for (count = 0; count < section->reloc_count; count++)
+ {
+ *relptr++ = &chain->relent;
+ chain = chain->next;
+ }
+ }
+ else
+ {
+ tblptr = section->relocation;
+
+ for (count = 0; count++ < section->reloc_count;)
+ {
+ *relptr++ = tblptr++;
+ }
+ }
+ *relptr = 0;
+
+ return section->reloc_count;
+}
+
+#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc)
+
+#include "aout-target.h"
diff --git a/bfd/i386mach3.c b/bfd/i386mach3.c
new file mode 100644
index 00000000000..eff75824658
--- /dev/null
+++ b/bfd/i386mach3.c
@@ -0,0 +1,66 @@
+/* BFD back-end for i386 a.out binaries.
+ Copyright (C) 1990, 91, 93, 94, 95, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This is for Mach 3, which uses a.out, not Mach-O. */
+
+/* There is no magic number or anything which lets us distinguish this target
+ from i386aout or i386bsd. So this target is only useful if it is the
+ default target. */
+
+#define TARGET_PAGE_SIZE 1
+#define SEGMENT_SIZE 0x1000
+#define TEXT_START_ADDR 0x10000
+#define ARCH 32
+#define BYTES_IN_WORD 4
+/* This macro is only relevant when N_MAGIC(x) == ZMAGIC. */
+#define N_HEADER_IN_TEXT(x) 1
+
+#define N_TXTSIZE(x) ((x).a_text)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#define DEFAULT_ARCH bfd_arch_i386
+#define MY(OP) CAT(i386mach3_,OP)
+#define TARGETNAME "a.out-mach3"
+
+static boolean MY(set_sizes)();
+#define MY_backend_data &MY(backend_data)
+static CONST struct aout_backend_data MY(backend_data) = {
+ 0, /* zmagic contiguous */
+ 1, /* text incl header */
+ 0, /* entry is text address */
+ 0, /* exec_hdr_flags */
+ 0, /* text vma? */
+ MY(set_sizes),
+ 1, /* exec header not counted */
+ 0, /* add_dynamic_symbols */
+ 0, /* add_one_symbol */
+ 0, /* link_dynamic_object */
+ 0, /* write_dynamic_symbol */
+ 0, /* check_dynamic_reloc */
+ 0 /* finish_dynamic_link */
+};
+
+#include "aout-target.h"
diff --git a/bfd/i386msdos.c b/bfd/i386msdos.c
new file mode 100644
index 00000000000..c6f24b2ac33
--- /dev/null
+++ b/bfd/i386msdos.c
@@ -0,0 +1,244 @@
+/* BFD back-end for MS-DOS executables.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Bryan Ford of the University of Utah.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#if 0
+struct exe_header
+{
+ unsigned short magic;
+ unsigned short bytes_in_last_page;
+ unsigned short npages; /* number of 512-byte "pages" including this header */
+ unsigned short nrelocs;
+ unsigned short header_paras; /* number of 16-byte paragraphs in header */
+ unsigned short reserved;
+ unsigned short load_switch;
+ unsigned short ss_ofs;
+ unsigned short sp;
+ unsigned short checksum;
+ unsigned short ip;
+ unsigned short cs_ofs;
+ unsigned short reloc_ofs;
+ unsigned short reserved2;
+ unsigned short something1;
+ unsigned short something2;
+ unsigned short something3;
+};
+#endif
+
+#define EXE_MAGIC 0x5a4d
+#define EXE_LOAD_HIGH 0x0000
+#define EXE_LOAD_LOW 0xffff
+#define EXE_PAGE_SIZE 512
+
+
+static int
+msdos_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return 0;
+}
+
+static boolean
+msdos_write_object_contents (abfd)
+ bfd *abfd;
+{
+ static char hdr[EXE_PAGE_SIZE];
+ file_ptr outfile_size = sizeof(hdr);
+ bfd_vma high_vma = 0;
+ asection *sec;
+
+ /* Find the total size of the program on disk and in memory. */
+ for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
+ {
+ if (bfd_get_section_size_before_reloc (sec) == 0)
+ continue;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ {
+ bfd_vma sec_vma = bfd_get_section_vma (abfd, sec)
+ + bfd_get_section_size_before_reloc (sec);
+ if (sec_vma > high_vma)
+ high_vma = sec_vma;
+ }
+ if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
+ {
+ file_ptr sec_end = sizeof(hdr)
+ + bfd_get_section_vma (abfd, sec)
+ + bfd_get_section_size_before_reloc (sec);
+ if (sec_end > outfile_size)
+ outfile_size = sec_end;
+ }
+ }
+
+ /* Make sure the program isn't too big. */
+ if (high_vma > (bfd_vma)0xffff)
+ {
+ bfd_set_error(bfd_error_file_too_big);
+ return false;
+ }
+
+ /* constants */
+ bfd_h_put_16(abfd, EXE_MAGIC, &hdr[0]);
+ bfd_h_put_16(abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
+ bfd_h_put_16(abfd, EXE_LOAD_LOW, &hdr[12]);
+ bfd_h_put_16(abfd, 0x3e, &hdr[24]);
+ bfd_h_put_16(abfd, 0x0001, &hdr[28]); /* XXX??? */
+ bfd_h_put_16(abfd, 0x30fb, &hdr[30]); /* XXX??? */
+ bfd_h_put_16(abfd, 0x726a, &hdr[32]); /* XXX??? */
+
+ /* bytes in last page (0 = full page) */
+ bfd_h_put_16(abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]);
+
+ /* number of pages */
+ bfd_h_put_16(abfd, (outfile_size + EXE_PAGE_SIZE - 1) / EXE_PAGE_SIZE,
+ &hdr[4]);
+
+ /* Set the initial stack pointer to the end of the bss.
+ The program's crt0 code must relocate it to a real stack. */
+ bfd_h_put_16(abfd, high_vma, &hdr[16]);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_write (hdr, 1, sizeof(hdr), abfd) != sizeof(hdr))
+ return false;
+
+ return true;
+}
+
+static boolean
+msdos_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+
+ if (count == 0)
+ return true;
+
+ section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section);
+
+ if (bfd_get_section_flags (abfd, section) & SEC_LOAD)
+ {
+ if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
+ || bfd_write (location, 1, count, abfd) != count)
+ return false;
+ }
+
+ return true;
+}
+
+
+
+#define msdos_mkobject aout_32_mkobject
+#define msdos_make_empty_symbol aout_32_make_empty_symbol
+#define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup
+
+#define msdos_close_and_cleanup _bfd_generic_close_and_cleanup
+#define msdos_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define msdos_new_section_hook _bfd_generic_new_section_hook
+#define msdos_get_section_contents _bfd_generic_get_section_contents
+#define msdos_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+#define msdos_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define msdos_bfd_relax_section bfd_generic_relax_section
+#define msdos_bfd_gc_sections bfd_generic_gc_sections
+#define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define msdos_bfd_final_link _bfd_generic_final_link
+#define msdos_bfd_link_split_section _bfd_generic_link_split_section
+#define msdos_set_arch_mach _bfd_generic_set_arch_mach
+
+#define msdos_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
+#define msdos_get_symtab _bfd_nosymbols_get_symtab
+#define msdos_print_symbol _bfd_nosymbols_print_symbol
+#define msdos_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define msdos_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define msdos_get_lineno _bfd_nosymbols_get_lineno
+#define msdos_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
+#define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define msdos_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+#define msdos_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
+#define msdos_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
+#define msdos_32_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target i386msdos_vec =
+{
+ "msdos", /* name */
+ bfd_target_msdos_flavour,
+ BFD_ENDIAN_LITTLE, /* target byte order */
+ BFD_ENDIAN_LITTLE, /* target headers byte order */
+ (EXEC_P), /* object flags */
+ (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {
+ _bfd_dummy_target,
+ _bfd_dummy_target, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ msdos_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ msdos_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (msdos),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (msdos),
+ BFD_JUMP_TABLE_RELOCS (msdos),
+ BFD_JUMP_TABLE_WRITE (msdos),
+ BFD_JUMP_TABLE_LINK (msdos),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
+
+
diff --git a/bfd/i386netbsd.c b/bfd/i386netbsd.c
new file mode 100644
index 00000000000..327b6f94bbf
--- /dev/null
+++ b/bfd/i386netbsd.c
@@ -0,0 +1,33 @@
+/* BFD back-end for NetBSD/386 a.out-ish binaries.
+ Copyright (C) 1990, 91, 92, 94, 95, 96, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#undef TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#define DEFAULT_ARCH bfd_arch_i386
+#define DEFAULT_MID M_386_NETBSD
+
+#define MY(OP) CAT(i386netbsd_,OP)
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-i386-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/i386os9k.c b/bfd/i386os9k.c
new file mode 100644
index 00000000000..2a01f5b2f83
--- /dev/null
+++ b/bfd/i386os9k.c
@@ -0,0 +1,371 @@
+/* BFD back-end for os9000 i386 binaries.
+ Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+#include "os9k.h"
+
+static const bfd_target *os9k_callback PARAMS ((bfd *));
+
+/* Swaps the information in an executable header taken from a raw byte
+ stream memory image, into the internal exec_header structure. */
+boolean
+os9k_swap_exec_header_in (abfd, raw_bytes, execp)
+ bfd *abfd;
+ mh_com *raw_bytes;
+ struct internal_exec *execp;
+{
+ mh_com *bytes = (mh_com *) raw_bytes;
+ unsigned int dload, dmemsize, dmemstart;
+
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = bfd_h_get_16 (abfd, bytes->m_sync);
+ execp->a_syms = 0;
+ execp->a_entry = bfd_h_get_32 (abfd, bytes->m_exec);
+ execp->a_talign = 2;
+ execp->a_dalign = 2;
+ execp->a_balign = 2;
+
+ dload = bfd_h_get_32 (abfd, bytes->m_idata);
+ execp->a_data = dload + 8;
+
+ if (bfd_seek (abfd, (file_ptr) dload, SEEK_SET) != 0
+ || (bfd_read (&dmemstart, sizeof (dmemstart), 1, abfd)
+ != sizeof (dmemstart))
+ || (bfd_read (&dmemsize, sizeof (dmemsize), 1, abfd)
+ != sizeof (dmemsize)))
+ return false;
+
+ execp->a_tload = 0;
+ execp->a_dload = bfd_h_get_32 (abfd, (unsigned char *) &dmemstart);
+ execp->a_text = dload - execp->a_tload;
+ execp->a_data = bfd_h_get_32 (abfd, (unsigned char *) &dmemsize);
+ execp->a_bss = bfd_h_get_32 (abfd, bytes->m_data) - execp->a_data;
+
+ execp->a_trsize = 0;
+ execp->a_drsize = 0;
+
+ return true;
+}
+
+#if 0
+/* Swaps the information in an internal exec header structure into the
+ supplied buffer ready for writing to disk. */
+
+PROTO (void, os9k_swap_exec_header_out,
+ (bfd * abfd,
+ struct internal_exec * execp,
+ struct mh_com * raw_bytes));
+void
+os9k_swap_exec_header_out (abfd, execp, raw_bytes)
+ bfd *abfd;
+ struct internal_exec *execp;
+ mh_com *raw_bytes;
+{
+ mh_com *bytes = (mh_com *) raw_bytes;
+
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ bfd_h_put_32 (abfd, execp->a_info, bytes->e_info);
+ bfd_h_put_32 (abfd, execp->a_text, bytes->e_text);
+ bfd_h_put_32 (abfd, execp->a_data, bytes->e_data);
+ bfd_h_put_32 (abfd, execp->a_bss, bytes->e_bss);
+ bfd_h_put_32 (abfd, execp->a_syms, bytes->e_syms);
+ bfd_h_put_32 (abfd, execp->a_entry, bytes->e_entry);
+ bfd_h_put_32 (abfd, execp->a_trsize, bytes->e_trsize);
+ bfd_h_put_32 (abfd, execp->a_drsize, bytes->e_drsize);
+ bfd_h_put_32 (abfd, execp->a_tload, bytes->e_tload);
+ bfd_h_put_32 (abfd, execp->a_dload, bytes->e_dload);
+ bytes->e_talign[0] = execp->a_talign;
+ bytes->e_dalign[0] = execp->a_dalign;
+ bytes->e_balign[0] = execp->a_balign;
+ bytes->e_relaxable[0] = execp->a_relaxable;
+}
+
+#endif /* 0 */
+
+static const bfd_target *
+os9k_object_p (abfd)
+ bfd *abfd;
+{
+ struct internal_exec anexec;
+ mh_com exec_bytes;
+
+ if (bfd_read ((PTR) & exec_bytes, MHCOM_BYTES_SIZE, 1, abfd)
+ != MHCOM_BYTES_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ anexec.a_info = bfd_h_get_16 (abfd, exec_bytes.m_sync);
+ if (N_BADMAG (anexec))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (! os9k_swap_exec_header_in (abfd, &exec_bytes, &anexec))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ return aout_32_some_aout_object_p (abfd, &anexec, os9k_callback);
+}
+
+
+/* Finish up the opening of a b.out file for reading. Fill in all the
+ fields that are not handled by common code. */
+
+static const bfd_target *
+os9k_callback (abfd)
+ bfd *abfd;
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+ unsigned long bss_start;
+
+ /* Architecture and machine type */
+ bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
+
+ /* The positions of the string table and symbol table. */
+ obj_str_filepos (abfd) = 0;
+ obj_sym_filepos (abfd) = 0;
+
+ /* The alignments of the sections */
+ obj_textsec (abfd)->alignment_power = execp->a_talign;
+ obj_datasec (abfd)->alignment_power = execp->a_dalign;
+ obj_bsssec (abfd)->alignment_power = execp->a_balign;
+
+ /* The starting addresses of the sections. */
+ obj_textsec (abfd)->vma = execp->a_tload;
+ obj_datasec (abfd)->vma = execp->a_dload;
+
+ /* And reload the sizes, since the aout module zaps them */
+ obj_textsec (abfd)->_raw_size = execp->a_text;
+
+ bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
+ obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign);
+
+ /* The file positions of the sections */
+ obj_textsec (abfd)->filepos = execp->a_entry;
+ obj_datasec (abfd)->filepos = execp->a_dload;
+
+ /* The file positions of the relocation info ***
+ obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
+ obj_datasec (abfd)->rel_filepos = N_DROFF(*execp);
+ */
+
+ adata (abfd).page_size = 1; /* Not applicable. */
+ adata (abfd).segment_size = 1;/* Not applicable. */
+ adata (abfd).exec_bytes_size = MHCOM_BYTES_SIZE;
+
+ return abfd->xvec;
+}
+
+#if 0
+struct bout_data_struct
+{
+ struct aoutdata a;
+ struct internal_exec e;
+};
+
+static boolean
+os9k_mkobject (abfd)
+ bfd *abfd;
+{
+ struct bout_data_struct *rawptr;
+
+ rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
+ if (rawptr == NULL)
+ return false;
+
+ abfd->tdata.bout_data = rawptr;
+ exec_hdr (abfd) = &rawptr->e;
+
+ obj_textsec (abfd) = (asection *) NULL;
+ obj_datasec (abfd) = (asection *) NULL;
+ obj_bsssec (abfd) = (asection *) NULL;
+
+ return true;
+}
+
+static boolean
+os9k_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec swapped_hdr;
+
+ if (! aout_32_make_sections (abfd))
+ return false;
+
+ exec_hdr (abfd)->a_info = BMAGIC;
+
+ exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size;
+ exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size;
+ exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size;
+ exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
+ exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
+ exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
+ sizeof (struct relocation_info));
+ exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
+ sizeof (struct relocation_info));
+
+ exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
+ exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
+ exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
+
+ exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
+ exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
+
+ bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_write ((PTR) & swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE))
+ 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_TROFF (*exec_hdr (abfd))), SEEK_SET)
+ != 0)
+ return false;
+
+ if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd)))
+ return false;
+ if (bfd_seek (abfd, (file_ptr) (N_DROFF (*exec_hdr (abfd))), SEEK_SET)
+ != 0)
+ return false;
+
+ if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd)))
+ return false;
+ }
+ return true;
+}
+
+static boolean
+os9k_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ unsigned char *location;
+ file_ptr offset;
+ int count;
+{
+
+ if (abfd->output_has_begun == false)
+ { /* set by bfd.c handler */
+ if (! aout_32_make_sections (abfd))
+ return false;
+
+ obj_textsec (abfd)->filepos = sizeof (struct internal_exec);
+ obj_datasec (abfd)->filepos = obj_textsec (abfd)->filepos
+ + obj_textsec (abfd)->_raw_size;
+
+ }
+ /* regardless, once we know what we're doing, we might as well get going */
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
+ return false;
+
+ if (count != 0)
+ {
+ return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false;
+ }
+ return true;
+}
+#endif /* 0 */
+
+static int
+os9k_sizeof_headers (ignore_abfd, ignore)
+ bfd *ignore_abfd;
+ boolean ignore;
+{
+ return sizeof (struct internal_exec);
+}
+
+
+/***********************************************************************/
+
+#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
+
+#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+
+#define aout_32_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define aout_32_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#define os9k_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define os9k_bfd_relax_section bfd_generic_relax_section
+#define os9k_bfd_gc_sections bfd_generic_gc_sections
+#define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define os9k_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define os9k_bfd_final_link _bfd_generic_final_link
+#define os9k_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target i386os9k_vec =
+{
+ "i386os9k", /* name */
+ bfd_target_os9k_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* hdr byte order is little */
+ (HAS_RELOC | EXEC_P | WP_TEXT), /* object flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* section flags */
+ 0, /* symbol leading char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+ {_bfd_dummy_target, os9k_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, _bfd_dummy_target},
+ {bfd_false, bfd_false, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, bfd_false, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (aout_32),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
+ BFD_JUMP_TABLE_SYMBOLS (aout_32),
+ BFD_JUMP_TABLE_RELOCS (aout_32),
+ BFD_JUMP_TABLE_WRITE (aout_32),
+ BFD_JUMP_TABLE_LINK (os9k),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0,
+};
diff --git a/bfd/ieee.c b/bfd/ieee.c
new file mode 100644
index 00000000000..126b136d337
--- /dev/null
+++ b/bfd/ieee.c
@@ -0,0 +1,3970 @@
+/* BFD back-end for ieee-695 objects.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ Written by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define KEEPMINUSPCININST 0
+
+/* IEEE 695 format is a stream of records, which we parse using a simple one-
+ token (which is one byte in this lexicon) lookahead recursive decent
+ parser. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "ieee.h"
+#include "libieee.h"
+
+#include <ctype.h>
+
+static boolean ieee_write_byte PARAMS ((bfd *, int));
+static boolean ieee_write_2bytes PARAMS ((bfd *, int));
+static boolean ieee_write_int PARAMS ((bfd *, bfd_vma));
+static boolean ieee_write_id PARAMS ((bfd *, const char *));
+static boolean ieee_write_expression
+ PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int));
+static void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma));
+static boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma));
+static boolean ieee_write_section_part PARAMS ((bfd *));
+static boolean do_with_relocs PARAMS ((bfd *, asection *));
+static boolean do_as_repeat PARAMS ((bfd *, asection *));
+static boolean do_without_relocs PARAMS ((bfd *, asection *));
+static boolean ieee_write_external_part PARAMS ((bfd *));
+static boolean ieee_write_data_part PARAMS ((bfd *));
+static boolean ieee_write_debug_part PARAMS ((bfd *));
+static boolean ieee_write_me_part PARAMS ((bfd *));
+static boolean ieee_write_processor PARAMS ((bfd *));
+
+static boolean ieee_slurp_debug PARAMS ((bfd *));
+static boolean ieee_slurp_section_data PARAMS ((bfd *));
+
+/* Functions for writing to ieee files in the strange way that the
+ standard requires. */
+
+static boolean
+ieee_write_byte (abfd, barg)
+ bfd *abfd;
+ int barg;
+{
+ bfd_byte byte;
+
+ byte = barg;
+ if (bfd_write ((PTR) &byte, 1, 1, abfd) != 1)
+ return false;
+ return true;
+}
+
+static boolean
+ieee_write_2bytes (abfd, bytes)
+ bfd *abfd;
+ int bytes;
+{
+ bfd_byte buffer[2];
+
+ buffer[0] = bytes >> 8;
+ buffer[1] = bytes & 0xff;
+ if (bfd_write ((PTR) buffer, 1, 2, abfd) != 2)
+ return false;
+ return true;
+}
+
+static boolean
+ieee_write_int (abfd, value)
+ bfd *abfd;
+ bfd_vma value;
+{
+ if (value <= 127)
+ {
+ if (! ieee_write_byte (abfd, (bfd_byte) value))
+ return false;
+ }
+ else
+ {
+ unsigned int length;
+
+ /* How many significant bytes ? */
+ /* FIXME FOR LONGER INTS */
+ if (value & 0xff000000)
+ length = 4;
+ else if (value & 0x00ff0000)
+ length = 3;
+ else if (value & 0x0000ff00)
+ length = 2;
+ else
+ length = 1;
+
+ if (! ieee_write_byte (abfd,
+ (bfd_byte) ((int) ieee_number_repeat_start_enum
+ + length)))
+ return false;
+ switch (length)
+ {
+ case 4:
+ if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24)))
+ return false;
+ /* Fall through. */
+ case 3:
+ if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16)))
+ return false;
+ /* Fall through. */
+ case 2:
+ if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8)))
+ return false;
+ /* Fall through. */
+ case 1:
+ if (! ieee_write_byte (abfd, (bfd_byte) (value)))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static boolean
+ieee_write_id (abfd, id)
+ bfd *abfd;
+ const char *id;
+{
+ size_t length = strlen (id);
+
+ if (length <= 127)
+ {
+ if (! ieee_write_byte (abfd, (bfd_byte) length))
+ return false;
+ }
+ else if (length < 255)
+ {
+ if (! ieee_write_byte (abfd, ieee_extension_length_1_enum)
+ || ! ieee_write_byte (abfd, (bfd_byte) length))
+ return false;
+ }
+ else if (length < 65535)
+ {
+ if (! ieee_write_byte (abfd, ieee_extension_length_2_enum)
+ || ! ieee_write_2bytes (abfd, (int) length))
+ return false;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: string too long (%d chars, max 65535)"),
+ bfd_get_filename (abfd), length);
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ if (bfd_write ((PTR) id, 1, length, abfd) != length)
+ return false;
+ return true;
+}
+
+/***************************************************************************
+Functions for reading from ieee files in the strange way that the
+standard requires:
+*/
+
+#define this_byte(ieee) *((ieee)->input_p)
+#define next_byte(ieee) ((ieee)->input_p++)
+#define this_byte_and_next(ieee) (*((ieee)->input_p++))
+
+static unsigned short
+read_2bytes (ieee)
+ common_header_type *ieee;
+{
+ unsigned char c1 = this_byte_and_next (ieee);
+ unsigned char c2 = this_byte_and_next (ieee);
+ return (c1 << 8) | c2;
+}
+
+static void
+bfd_get_string (ieee, string, length)
+ common_header_type *ieee;
+ char *string;
+ size_t length;
+{
+ size_t i;
+ for (i = 0; i < length; i++)
+ {
+ string[i] = this_byte_and_next (ieee);
+ }
+}
+
+static char *
+read_id (ieee)
+ common_header_type *ieee;
+{
+ size_t length;
+ char *string;
+ length = this_byte_and_next (ieee);
+ if (length <= 0x7f)
+ {
+ /* Simple string of length 0 to 127 */
+ }
+ else if (length == 0xde)
+ {
+ /* Length is next byte, allowing 0..255 */
+ length = this_byte_and_next (ieee);
+ }
+ else if (length == 0xdf)
+ {
+ /* Length is next two bytes, allowing 0..65535 */
+ length = this_byte_and_next (ieee);
+ length = (length * 256) + this_byte_and_next (ieee);
+ }
+ /* Buy memory and read string */
+ string = bfd_alloc (ieee->abfd, length + 1);
+ if (!string)
+ return NULL;
+ bfd_get_string (ieee, string, length);
+ string[length] = 0;
+ return string;
+}
+
+static boolean
+ieee_write_expression (abfd, value, symbol, pcrel, index)
+ bfd *abfd;
+ bfd_vma value;
+ asymbol *symbol;
+ boolean pcrel;
+ unsigned int index;
+{
+ unsigned int term_count = 0;
+
+ if (value != 0)
+ {
+ if (! ieee_write_int (abfd, value))
+ return false;
+ term_count++;
+ }
+
+ if (bfd_is_com_section (symbol->section)
+ || bfd_is_und_section (symbol->section))
+ {
+ /* Def of a common symbol */
+ if (! ieee_write_byte (abfd, ieee_variable_X_enum)
+ || ! ieee_write_int (abfd, symbol->value))
+ return false;
+ term_count++;
+ }
+ else if (! bfd_is_abs_section (symbol->section))
+ {
+ /* Ref to defined symbol - */
+
+ if (symbol->flags & BSF_GLOBAL)
+ {
+ if (! ieee_write_byte (abfd, ieee_variable_I_enum)
+ || ! ieee_write_int (abfd, symbol->value))
+ return false;
+ term_count++;
+ }
+ else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM))
+ {
+ /* This is a reference to a defined local symbol. We can
+ easily do a local as a section+offset. */
+ if (! ieee_write_byte (abfd, ieee_variable_R_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (symbol->section->index
+ + IEEE_SECTION_NUMBER_BASE)))
+ return false;
+ term_count++;
+ if (symbol->value != 0)
+ {
+ if (! ieee_write_int (abfd, symbol->value))
+ return false;
+ term_count++;
+ }
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: unrecognized symbol `%s' flags 0x%x"),
+ bfd_get_filename (abfd), bfd_asymbol_name (symbol),
+ symbol->flags);
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+ }
+
+ if (pcrel)
+ {
+ /* subtract the pc from here by asking for PC of this section*/
+ if (! ieee_write_byte (abfd, ieee_variable_P_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE))
+ || ! ieee_write_byte (abfd, ieee_function_minus_enum))
+ return false;
+ }
+
+ /* Handle the degenerate case of a 0 address. */
+ if (term_count == 0)
+ {
+ if (! ieee_write_int (abfd, 0))
+ return false;
+ }
+
+ while (term_count > 1)
+ {
+ if (! ieee_write_byte (abfd, ieee_function_plus_enum))
+ return false;
+ term_count--;
+ }
+
+ return true;
+}
+
+/*****************************************************************************/
+
+/*
+writes any integer into the buffer supplied and always takes 5 bytes
+*/
+static void
+ieee_write_int5 (buffer, value)
+ bfd_byte *buffer;
+ bfd_vma value;
+{
+ buffer[0] = (bfd_byte) ieee_number_repeat_4_enum;
+ buffer[1] = (value >> 24) & 0xff;
+ buffer[2] = (value >> 16) & 0xff;
+ buffer[3] = (value >> 8) & 0xff;
+ buffer[4] = (value >> 0) & 0xff;
+}
+
+static boolean
+ieee_write_int5_out (abfd, value)
+ bfd *abfd;
+ bfd_vma value;
+{
+ bfd_byte b[5];
+
+ ieee_write_int5 (b, value);
+ if (bfd_write ((PTR) b, 1, 5, abfd) != 5)
+ return false;
+ return true;
+}
+
+static boolean
+parse_int (ieee, value_ptr)
+ common_header_type *ieee;
+ bfd_vma *value_ptr;
+{
+ int value = this_byte (ieee);
+ int result;
+ if (value >= 0 && value <= 127)
+ {
+ *value_ptr = value;
+ next_byte (ieee);
+ return true;
+ }
+ else if (value >= 0x80 && value <= 0x88)
+ {
+ unsigned int count = value & 0xf;
+ result = 0;
+ next_byte (ieee);
+ while (count)
+ {
+ result = (result << 8) | this_byte_and_next (ieee);
+ count--;
+ }
+ *value_ptr = result;
+ return true;
+ }
+ return false;
+}
+
+static int
+parse_i (ieee, ok)
+ common_header_type *ieee;
+ boolean *ok;
+{
+ bfd_vma x;
+ *ok = parse_int (ieee, &x);
+ return x;
+}
+
+static bfd_vma
+must_parse_int (ieee)
+ common_header_type *ieee;
+{
+ bfd_vma result;
+ BFD_ASSERT (parse_int (ieee, &result) == true);
+ return result;
+}
+
+typedef struct
+{
+ bfd_vma value;
+ asection *section;
+ ieee_symbol_index_type symbol;
+} ieee_value_type;
+
+
+#if KEEPMINUSPCININST
+
+#define SRC_MASK(arg) arg
+#define PCREL_OFFSET false
+
+#else
+
+#define SRC_MASK(arg) 0
+#define PCREL_OFFSET true
+
+#endif
+
+static reloc_howto_type abs32_howto =
+ HOWTO (1,
+ 0,
+ 2,
+ 32,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ 0,
+ "abs32",
+ true,
+ 0xffffffff,
+ 0xffffffff,
+ false);
+
+static reloc_howto_type abs16_howto =
+ HOWTO (1,
+ 0,
+ 1,
+ 16,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ 0,
+ "abs16",
+ true,
+ 0x0000ffff,
+ 0x0000ffff,
+ false);
+
+static reloc_howto_type abs8_howto =
+ HOWTO (1,
+ 0,
+ 0,
+ 8,
+ false,
+ 0,
+ complain_overflow_bitfield,
+ 0,
+ "abs8",
+ true,
+ 0x000000ff,
+ 0x000000ff,
+ false);
+
+static reloc_howto_type rel32_howto =
+ HOWTO (1,
+ 0,
+ 2,
+ 32,
+ true,
+ 0,
+ complain_overflow_signed,
+ 0,
+ "rel32",
+ true,
+ SRC_MASK (0xffffffff),
+ 0xffffffff,
+ PCREL_OFFSET);
+
+static reloc_howto_type rel16_howto =
+ HOWTO (1,
+ 0,
+ 1,
+ 16,
+ true,
+ 0,
+ complain_overflow_signed,
+ 0,
+ "rel16",
+ true,
+ SRC_MASK (0x0000ffff),
+ 0x0000ffff,
+ PCREL_OFFSET);
+
+static reloc_howto_type rel8_howto =
+ HOWTO (1,
+ 0,
+ 0,
+ 8,
+ true,
+ 0,
+ complain_overflow_signed,
+ 0,
+ "rel8",
+ true,
+ SRC_MASK (0x000000ff),
+ 0x000000ff,
+ PCREL_OFFSET);
+
+static ieee_symbol_index_type NOSYMBOL = {0, 0};
+
+static void
+parse_expression (ieee, value, symbol, pcrel, extra, section)
+ ieee_data_type *ieee;
+ bfd_vma *value;
+ ieee_symbol_index_type *symbol;
+ boolean *pcrel;
+ unsigned int *extra;
+ asection **section;
+
+{
+#define POS sp[1]
+#define TOS sp[0]
+#define NOS sp[-1]
+#define INC sp++;
+#define DEC sp--;
+
+ boolean loop = true;
+ ieee_value_type stack[10];
+
+ /* The stack pointer always points to the next unused location */
+#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC;
+#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value;
+ ieee_value_type *sp = stack;
+
+ while (loop)
+ {
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_variable_P_enum:
+ /* P variable, current program counter for section n */
+ {
+ int section_n;
+ next_byte (&(ieee->h));
+ *pcrel = true;
+ section_n = must_parse_int (&(ieee->h));
+ PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
+ break;
+ }
+ case ieee_variable_L_enum:
+ /* L variable address of section N */
+ next_byte (&(ieee->h));
+ PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
+ break;
+ case ieee_variable_R_enum:
+ /* R variable, logical address of section module */
+ /* FIXME, this should be different to L */
+ next_byte (&(ieee->h));
+ PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0);
+ break;
+ case ieee_variable_S_enum:
+ /* S variable, size in MAUS of section module */
+ next_byte (&(ieee->h));
+ PUSH (NOSYMBOL,
+ 0,
+ ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size);
+ break;
+ case ieee_variable_I_enum:
+ /* Push the address of variable n */
+ {
+ ieee_symbol_index_type sy;
+ next_byte (&(ieee->h));
+ sy.index = (int) must_parse_int (&(ieee->h));
+ sy.letter = 'I';
+
+ PUSH (sy, bfd_abs_section_ptr, 0);
+ }
+ break;
+ case ieee_variable_X_enum:
+ /* Push the address of external variable n */
+ {
+ ieee_symbol_index_type sy;
+ next_byte (&(ieee->h));
+ sy.index = (int) (must_parse_int (&(ieee->h)));
+ sy.letter = 'X';
+
+ PUSH (sy, bfd_und_section_ptr, 0);
+ }
+ break;
+ case ieee_function_minus_enum:
+ {
+ bfd_vma value1, value2;
+ asection *section1, *section_dummy;
+ ieee_symbol_index_type sy;
+ next_byte (&(ieee->h));
+
+ POP (sy, section1, value1);
+ POP (sy, section_dummy, value2);
+ PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
+ }
+ break;
+ case ieee_function_plus_enum:
+ {
+ bfd_vma value1, value2;
+ asection *section1;
+ asection *section2;
+ ieee_symbol_index_type sy1;
+ ieee_symbol_index_type sy2;
+ next_byte (&(ieee->h));
+
+ POP (sy1, section1, value1);
+ POP (sy2, section2, value2);
+ PUSH (sy1.letter ? sy1 : sy2,
+ bfd_is_abs_section (section1) ? section2 : section1,
+ value1 + value2);
+ }
+ break;
+ default:
+ {
+ bfd_vma va;
+ BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum
+ || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum);
+ if (parse_int (&(ieee->h), &va))
+ {
+ PUSH (NOSYMBOL, bfd_abs_section_ptr, va);
+ }
+ else
+ {
+ /*
+ Thats all that we can understand. As far as I can see
+ there is a bug in the Microtec IEEE output which I'm
+ using to scan, whereby the comma operator is omitted
+ sometimes in an expression, giving expressions with too
+ many terms. We can tell if that's the case by ensuring
+ that sp == stack here. If not, then we've pushed
+ something too far, so we keep adding. */
+
+ while (sp != stack + 1)
+ {
+ asection *section1;
+ ieee_symbol_index_type sy1;
+ POP (sy1, section1, *extra);
+ }
+ {
+ asection *dummy;
+
+ POP (*symbol, dummy, *value);
+ if (section)
+ *section = dummy;
+ }
+
+ loop = false;
+ }
+ }
+ }
+ }
+}
+
+
+#define ieee_seek(abfd, offset) \
+ IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset
+
+#define ieee_pos(abfd) \
+ (IEEE_DATA(abfd)->h.input_p - IEEE_DATA(abfd)->h.first_byte)
+
+static unsigned int last_index;
+static char last_type; /* is the index for an X or a D */
+
+static ieee_symbol_type *
+get_symbol (abfd,
+ ieee,
+ last_symbol,
+ symbol_count,
+ pptr,
+ max_index,
+ this_type
+)
+ bfd *abfd;
+ ieee_data_type *ieee;
+ ieee_symbol_type *last_symbol;
+ unsigned int *symbol_count;
+ ieee_symbol_type ***pptr;
+ unsigned int *max_index;
+ char this_type
+ ;
+{
+ /* Need a new symbol */
+ unsigned int new_index = must_parse_int (&(ieee->h));
+ if (new_index != last_index || this_type != last_type)
+ {
+ ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd,
+ sizeof (ieee_symbol_type));
+ if (!new_symbol)
+ return NULL;
+
+ new_symbol->index = new_index;
+ last_index = new_index;
+ (*symbol_count)++;
+ **pptr = new_symbol;
+ *pptr = &new_symbol->next;
+ if (new_index > *max_index)
+ {
+ *max_index = new_index;
+ }
+ last_type = this_type;
+ new_symbol->symbol.section = bfd_abs_section_ptr;
+ return new_symbol;
+ }
+ return last_symbol;
+}
+
+static boolean
+ieee_slurp_external_symbols (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ file_ptr offset = ieee->w.r.external_part;
+
+ ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols;
+ ieee_symbol_type **prev_reference_ptr = &ieee->external_reference;
+ ieee_symbol_type *symbol = (ieee_symbol_type *) NULL;
+ unsigned int symbol_count = 0;
+ boolean loop = true;
+ last_index = 0xffffff;
+ ieee->symbol_table_full = true;
+
+ ieee_seek (abfd, offset);
+
+ while (loop)
+ {
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_nn_record:
+ next_byte (&(ieee->h));
+
+ symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
+ &prev_symbols_ptr,
+ &ieee->external_symbol_max_index, 'I');
+ if (symbol == NULL)
+ return false;
+
+ symbol->symbol.the_bfd = abfd;
+ symbol->symbol.name = read_id (&(ieee->h));
+ symbol->symbol.udata.p = (PTR) NULL;
+ symbol->symbol.flags = BSF_NO_FLAGS;
+ break;
+ case ieee_external_symbol_enum:
+ next_byte (&(ieee->h));
+
+ symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
+ &prev_symbols_ptr,
+ &ieee->external_symbol_max_index, 'D');
+ if (symbol == NULL)
+ return false;
+
+ BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index);
+
+ symbol->symbol.the_bfd = abfd;
+ symbol->symbol.name = read_id (&(ieee->h));
+ symbol->symbol.udata.p = (PTR) NULL;
+ symbol->symbol.flags = BSF_NO_FLAGS;
+ break;
+ case ieee_attribute_record_enum >> 8:
+ {
+ unsigned int symbol_name_index;
+ unsigned int symbol_type_index;
+ unsigned int symbol_attribute_def;
+ bfd_vma value;
+ switch (read_2bytes (ieee))
+ {
+ case ieee_attribute_record_enum:
+ symbol_name_index = must_parse_int (&(ieee->h));
+ symbol_type_index = must_parse_int (&(ieee->h));
+ symbol_attribute_def = must_parse_int (&(ieee->h));
+ switch (symbol_attribute_def)
+ {
+ case 8:
+ case 19:
+ parse_int (&ieee->h, &value);
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("%s: unimplemented ATI record %u for symbol %u"),
+ bfd_get_filename (abfd), symbol_attribute_def,
+ symbol_name_index);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ break;
+ }
+ break;
+ case ieee_external_reference_info_record_enum:
+ /* Skip over ATX record. */
+ parse_int (&(ieee->h), &value);
+ parse_int (&(ieee->h), &value);
+ parse_int (&(ieee->h), &value);
+ parse_int (&(ieee->h), &value);
+ break;
+ case ieee_atn_record_enum:
+ /* We may get call optimization information here,
+ which we just ignore. The format is
+ {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs} */
+ parse_int (&ieee->h, &value);
+ parse_int (&ieee->h, &value);
+ parse_int (&ieee->h, &value);
+ if (value != 0x3f)
+ {
+ (*_bfd_error_handler)
+ (_("%s: unexpected ATN type %d in external part"),
+ bfd_get_filename (abfd), (int) value);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ parse_int (&ieee->h, &value);
+ parse_int (&ieee->h, &value);
+ while (value > 0)
+ {
+ bfd_vma val1;
+
+ --value;
+
+ switch (read_2bytes (ieee))
+ {
+ case ieee_asn_record_enum:
+ parse_int (&ieee->h, &val1);
+ parse_int (&ieee->h, &val1);
+ break;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%s: unexpected type after ATN"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+ }
+ }
+ break;
+ case ieee_value_record_enum >> 8:
+ {
+ unsigned int symbol_name_index;
+ ieee_symbol_index_type symbol_ignore;
+ boolean pcrel_ignore;
+ unsigned int extra;
+ next_byte (&(ieee->h));
+ next_byte (&(ieee->h));
+
+ symbol_name_index = must_parse_int (&(ieee->h));
+ parse_expression (ieee,
+ &symbol->symbol.value,
+ &symbol_ignore,
+ &pcrel_ignore,
+ &extra,
+ &symbol->symbol.section);
+
+ /* Fully linked IEEE-695 files tend to give every symbol
+ an absolute value. Try to convert that back into a
+ section relative value. FIXME: This won't always to
+ the right thing. */
+ if (bfd_is_abs_section (symbol->symbol.section)
+ && (abfd->flags & HAS_RELOC) == 0)
+ {
+ bfd_vma val;
+ asection *s;
+
+ val = symbol->symbol.value;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if (val >= s->vma && val < s->vma + s->_raw_size)
+ {
+ symbol->symbol.section = s;
+ symbol->symbol.value -= s->vma;
+ break;
+ }
+ }
+ }
+
+ symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
+
+ }
+ break;
+ case ieee_weak_external_reference_enum:
+ {
+ bfd_vma size;
+ bfd_vma value;
+ next_byte (&(ieee->h));
+ /* Throw away the external reference index */
+ (void) must_parse_int (&(ieee->h));
+ /* Fetch the default size if not resolved */
+ size = must_parse_int (&(ieee->h));
+ /* Fetch the defautlt value if available */
+ if (parse_int (&(ieee->h), &value) == false)
+ {
+ value = 0;
+ }
+ /* This turns into a common */
+ symbol->symbol.section = bfd_com_section_ptr;
+ symbol->symbol.value = size;
+ }
+ break;
+
+ case ieee_external_reference_enum:
+ next_byte (&(ieee->h));
+
+ symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
+ &prev_reference_ptr,
+ &ieee->external_reference_max_index, 'X');
+ if (symbol == NULL)
+ return false;
+
+ symbol->symbol.the_bfd = abfd;
+ symbol->symbol.name = read_id (&(ieee->h));
+ symbol->symbol.udata.p = (PTR) NULL;
+ symbol->symbol.section = bfd_und_section_ptr;
+ symbol->symbol.value = (bfd_vma) 0;
+ symbol->symbol.flags = 0;
+
+ BFD_ASSERT (symbol->index >= ieee->external_reference_min_index);
+ break;
+
+ default:
+ loop = false;
+ }
+ }
+
+ if (ieee->external_symbol_max_index != 0)
+ {
+ ieee->external_symbol_count =
+ ieee->external_symbol_max_index -
+ ieee->external_symbol_min_index + 1;
+ }
+ else
+ {
+ ieee->external_symbol_count = 0;
+ }
+
+ if (ieee->external_reference_max_index != 0)
+ {
+ ieee->external_reference_count =
+ ieee->external_reference_max_index -
+ ieee->external_reference_min_index + 1;
+ }
+ else
+ {
+ ieee->external_reference_count = 0;
+ }
+
+ abfd->symcount =
+ ieee->external_reference_count + ieee->external_symbol_count;
+
+ if (symbol_count != abfd->symcount)
+ {
+ /* There are gaps in the table -- */
+ ieee->symbol_table_full = false;
+ }
+
+ *prev_symbols_ptr = (ieee_symbol_type *) NULL;
+ *prev_reference_ptr = (ieee_symbol_type *) NULL;
+
+ return true;
+}
+
+static boolean
+ieee_slurp_symbol_table (abfd)
+ bfd *abfd;
+{
+ if (IEEE_DATA (abfd)->read_symbols == false)
+ {
+ if (! ieee_slurp_external_symbols (abfd))
+ return false;
+ IEEE_DATA (abfd)->read_symbols = true;
+ }
+ return true;
+}
+
+long
+ieee_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ if (! ieee_slurp_symbol_table (abfd))
+ return -1;
+
+ return (abfd->symcount != 0) ?
+ (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0;
+}
+
+/*
+Move from our internal lists to the canon table, and insert in
+symbol index order
+*/
+
+extern const bfd_target ieee_vec;
+
+long
+ieee_get_symtab (abfd, location)
+ bfd *abfd;
+ asymbol **location;
+{
+ ieee_symbol_type *symp;
+ static bfd dummy_bfd;
+ static asymbol empty_symbol =
+ /* the_bfd, name, value, attr, section */
+ {&dummy_bfd, " ieee empty", (symvalue) 0, BSF_DEBUGGING, bfd_abs_section_ptr};
+
+ if (abfd->symcount)
+ {
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ dummy_bfd.xvec = &ieee_vec;
+ if (! ieee_slurp_symbol_table (abfd))
+ return -1;
+
+ if (ieee->symbol_table_full == false)
+ {
+ /* Arrgh - there are gaps in the table, run through and fill them */
+ /* up with pointers to a null place */
+ unsigned int i;
+ for (i = 0; i < abfd->symcount; i++)
+ {
+ location[i] = &empty_symbol;
+ }
+ }
+
+ ieee->external_symbol_base_offset = -ieee->external_symbol_min_index;
+ for (symp = IEEE_DATA (abfd)->external_symbols;
+ symp != (ieee_symbol_type *) NULL;
+ symp = symp->next)
+ {
+ /* Place into table at correct index locations */
+ location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol;
+ }
+
+ /* The external refs are indexed in a bit */
+ ieee->external_reference_base_offset =
+ -ieee->external_reference_min_index + ieee->external_symbol_count;
+
+ for (symp = IEEE_DATA (abfd)->external_reference;
+ symp != (ieee_symbol_type *) NULL;
+ symp = symp->next)
+ {
+ location[symp->index + ieee->external_reference_base_offset] =
+ &symp->symbol;
+
+ }
+ }
+ if (abfd->symcount)
+ {
+ location[abfd->symcount] = (asymbol *) NULL;
+ }
+ return abfd->symcount;
+}
+
+static asection *
+get_section_entry (abfd, ieee, index)
+ bfd *abfd;
+ ieee_data_type *ieee;
+ unsigned int index;
+{
+ if (index >= ieee->section_table_size)
+ {
+ unsigned int c, i;
+ asection **n;
+
+ c = ieee->section_table_size;
+ if (c == 0)
+ c = 20;
+ while (c <= index)
+ c *= 2;
+
+ n = ((asection **)
+ bfd_realloc (ieee->section_table, c * sizeof (asection *)));
+ if (n == NULL)
+ return NULL;
+
+ for (i = ieee->section_table_size; i < c; i++)
+ n[i] = NULL;
+
+ ieee->section_table = n;
+ ieee->section_table_size = c;
+ }
+
+ if (ieee->section_table[index] == (asection *) NULL)
+ {
+ char *tmp = bfd_alloc (abfd, 11);
+ asection *section;
+
+ if (!tmp)
+ return NULL;
+ sprintf (tmp, " fsec%4d", index);
+ section = bfd_make_section (abfd, tmp);
+ ieee->section_table[index] = section;
+ section->flags = SEC_NO_FLAGS;
+ section->target_index = index;
+ ieee->section_table[index] = section;
+ }
+ return ieee->section_table[index];
+}
+
+static void
+ieee_slurp_sections (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ file_ptr offset = ieee->w.r.section_part;
+ asection *section = (asection *) NULL;
+ char *name;
+
+ if (offset != 0)
+ {
+ bfd_byte section_type[3];
+ ieee_seek (abfd, offset);
+ while (true)
+ {
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_section_type_enum:
+ {
+ unsigned int section_index;
+ next_byte (&(ieee->h));
+ section_index = must_parse_int (&(ieee->h));
+
+ section = get_section_entry (abfd, ieee, section_index);
+
+ section_type[0] = this_byte_and_next (&(ieee->h));
+
+ /* Set minimal section attributes. Attributes are
+ extended later, based on section contents. */
+
+ switch (section_type[0])
+ {
+ case 0xC1:
+ /* Normal attributes for absolute sections */
+ section_type[1] = this_byte (&(ieee->h));
+ section->flags = SEC_ALLOC;
+ switch (section_type[1])
+ {
+ case 0xD3: /* AS Absolute section attributes */
+ next_byte (&(ieee->h));
+ section_type[2] = this_byte (&(ieee->h));
+ switch (section_type[2])
+ {
+ case 0xD0:
+ /* Normal code */
+ next_byte (&(ieee->h));
+ section->flags |= SEC_CODE;
+ break;
+ case 0xC4:
+ /* Normal data */
+ next_byte (&(ieee->h));
+ section->flags |= SEC_DATA;
+ break;
+ case 0xD2:
+ next_byte (&(ieee->h));
+ /* Normal rom data */
+ section->flags |= SEC_ROM | SEC_DATA;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case 0xC3: /* Named relocatable sections (type C) */
+ section_type[1] = this_byte (&(ieee->h));
+ section->flags = SEC_ALLOC;
+ switch (section_type[1])
+ {
+ case 0xD0: /* Normal code (CP) */
+ next_byte (&(ieee->h));
+ section->flags |= SEC_CODE;
+ break;
+ case 0xC4: /* Normal data (CD) */
+ next_byte (&(ieee->h));
+ section->flags |= SEC_DATA;
+ break;
+ case 0xD2: /* Normal rom data (CR) */
+ next_byte (&(ieee->h));
+ section->flags |= SEC_ROM | SEC_DATA;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Read section name, use it if non empty. */
+ name = read_id (&ieee->h);
+ if (name[0])
+ section->name = name;
+
+ /* Skip these fields, which we don't care about */
+ {
+ bfd_vma parent, brother, context;
+ parse_int (&(ieee->h), &parent);
+ parse_int (&(ieee->h), &brother);
+ parse_int (&(ieee->h), &context);
+ }
+ }
+ break;
+ case ieee_section_alignment_enum:
+ {
+ unsigned int section_index;
+ bfd_vma value;
+ asection *section;
+ next_byte (&(ieee->h));
+ section_index = must_parse_int (&ieee->h);
+ section = get_section_entry (abfd, ieee, section_index);
+ if (section_index > ieee->section_count)
+ {
+ ieee->section_count = section_index;
+ }
+ section->alignment_power =
+ bfd_log2 (must_parse_int (&ieee->h));
+ (void) parse_int (&(ieee->h), &value);
+ }
+ break;
+ case ieee_e2_first_byte_enum:
+ {
+ ieee_record_enum_type t = (ieee_record_enum_type) (read_2bytes (&(ieee->h)));
+
+ switch (t)
+ {
+ case ieee_section_size_enum:
+ section = ieee->section_table[must_parse_int (&(ieee->h))];
+ section->_raw_size = must_parse_int (&(ieee->h));
+ break;
+ case ieee_physical_region_size_enum:
+ section = ieee->section_table[must_parse_int (&(ieee->h))];
+ section->_raw_size = must_parse_int (&(ieee->h));
+ break;
+ case ieee_region_base_address_enum:
+ section = ieee->section_table[must_parse_int (&(ieee->h))];
+ section->vma = must_parse_int (&(ieee->h));
+ section->lma = section->vma;
+ break;
+ case ieee_mau_size_enum:
+ must_parse_int (&(ieee->h));
+ must_parse_int (&(ieee->h));
+ break;
+ case ieee_m_value_enum:
+ must_parse_int (&(ieee->h));
+ must_parse_int (&(ieee->h));
+ break;
+ case ieee_section_base_address_enum:
+ section = ieee->section_table[must_parse_int (&(ieee->h))];
+ section->vma = must_parse_int (&(ieee->h));
+ section->lma = section->vma;
+ break;
+ case ieee_section_offset_enum:
+ (void) must_parse_int (&(ieee->h));
+ (void) must_parse_int (&(ieee->h));
+ break;
+ default:
+ return;
+ }
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ }
+}
+
+/* Make a section for the debugging information, if any. We don't try
+ to interpret the debugging information; we just point the section
+ at the area in the file so that program which understand can dig it
+ out. */
+
+static boolean
+ieee_slurp_debug (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ asection *sec;
+
+ if (ieee->w.r.debug_information_part == 0)
+ return true;
+
+ sec = bfd_make_section (abfd, ".debug");
+ if (sec == NULL)
+ return false;
+ sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS;
+ sec->filepos = ieee->w.r.debug_information_part;
+ sec->_raw_size = ieee->w.r.data_part - ieee->w.r.debug_information_part;
+
+ return true;
+}
+
+/***********************************************************************
+* archive stuff
+*/
+
+const bfd_target *
+ieee_archive_p (abfd)
+ bfd *abfd;
+{
+ char *library;
+ unsigned int i;
+ unsigned char buffer[512];
+ file_ptr buffer_offset = 0;
+ ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
+ ieee_ar_data_type *ieee;
+ unsigned int alc_elts;
+ ieee_ar_obstack_type *elts = NULL;
+
+ abfd->tdata.ieee_ar_data =
+ (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type));
+ if (!abfd->tdata.ieee_ar_data)
+ goto error_return;
+ ieee = IEEE_AR_DATA (abfd);
+
+ /* FIXME: Check return value. I'm not sure whether it needs to read
+ the entire buffer or not. */
+ bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
+
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+
+ ieee->h.abfd = abfd;
+
+ if (this_byte (&(ieee->h)) != Module_Beginning)
+ {
+ abfd->tdata.ieee_ar_data = save;
+ goto error_return;
+ }
+
+ next_byte (&(ieee->h));
+ library = read_id (&(ieee->h));
+ if (strcmp (library, "LIBRARY") != 0)
+ {
+ bfd_release (abfd, ieee);
+ abfd->tdata.ieee_ar_data = save;
+ goto error_return;
+ }
+ /* Throw away the filename */
+ read_id (&(ieee->h));
+
+ ieee->element_count = 0;
+ ieee->element_index = 0;
+
+ next_byte (&(ieee->h)); /* Drop the ad part */
+ must_parse_int (&(ieee->h)); /* And the two dummy numbers */
+ must_parse_int (&(ieee->h));
+
+ alc_elts = 10;
+ elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts);
+ if (elts == NULL)
+ goto error_return;
+
+ /* Read the index of the BB table */
+ while (1)
+ {
+ int rec;
+ ieee_ar_obstack_type *t;
+
+ rec = read_2bytes (&(ieee->h));
+ if (rec != (int) ieee_assign_value_to_variable_enum)
+ break;
+
+ if (ieee->element_count >= alc_elts)
+ {
+ ieee_ar_obstack_type *n;
+
+ alc_elts *= 2;
+ n = ((ieee_ar_obstack_type *)
+ bfd_realloc (elts, alc_elts * sizeof *elts));
+ if (n == NULL)
+ goto error_return;
+ elts = n;
+ }
+
+ t = &elts[ieee->element_count];
+ ieee->element_count++;
+
+ must_parse_int (&(ieee->h));
+ t->file_offset = must_parse_int (&(ieee->h));
+ t->abfd = (bfd *) NULL;
+
+ /* Make sure that we don't go over the end of the buffer */
+
+ if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2)
+ {
+ /* Past half way, reseek and reprime */
+ buffer_offset += ieee_pos (abfd);
+ if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
+ goto error_return;
+ /* FIXME: Check return value. I'm not sure whether it needs
+ to read the entire buffer or not. */
+ bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+ }
+ }
+
+ ieee->elements = ((ieee_ar_obstack_type *)
+ bfd_alloc (abfd,
+ ieee->element_count * sizeof *ieee->elements));
+ if (ieee->elements == NULL)
+ goto error_return;
+ memcpy (ieee->elements, elts,
+ ieee->element_count * sizeof *ieee->elements);
+ free (elts);
+ elts = NULL;
+
+ /* Now scan the area again, and replace BB offsets with file */
+ /* offsets */
+
+ for (i = 2; i < ieee->element_count; i++)
+ {
+ if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
+ goto error_return;
+ /* FIXME: Check return value. I'm not sure whether it needs to
+ read the entire buffer or not. */
+ bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+
+ next_byte (&(ieee->h)); /* Drop F8 */
+ next_byte (&(ieee->h)); /* Drop 14 */
+ must_parse_int (&(ieee->h)); /* Drop size of block */
+ if (must_parse_int (&(ieee->h)) != 0)
+ {
+ /* This object has been deleted */
+ ieee->elements[i].file_offset = 0;
+ }
+ else
+ {
+ ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
+ }
+ }
+
+ /* abfd->has_armap = ;*/
+
+ return abfd->xvec;
+
+ error_return:
+ if (elts != NULL)
+ free (elts);
+ return NULL;
+}
+
+static boolean
+ieee_mkobject (abfd)
+ bfd *abfd;
+{
+ abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, sizeof (ieee_data_type));
+ return abfd->tdata.ieee_data ? true : false;
+}
+
+const bfd_target *
+ieee_object_p (abfd)
+ bfd *abfd;
+{
+ char *processor;
+ unsigned int part;
+ ieee_data_type *ieee;
+ unsigned char buffer[300];
+ ieee_data_type *save = IEEE_DATA (abfd);
+
+ abfd->tdata.ieee_data = 0;
+ ieee_mkobject (abfd);
+
+ ieee = IEEE_DATA (abfd);
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto fail;
+ /* Read the first few bytes in to see if it makes sense */
+ /* FIXME: Check return value. I'm not sure whether it needs to read
+ the entire buffer or not. */
+ bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
+
+ ieee->h.input_p = buffer;
+ if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
+ goto got_wrong_format;
+
+ ieee->read_symbols = false;
+ ieee->read_data = false;
+ ieee->section_count = 0;
+ ieee->external_symbol_max_index = 0;
+ ieee->external_symbol_min_index = IEEE_PUBLIC_BASE;
+ ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
+ ieee->external_reference_max_index = 0;
+ ieee->h.abfd = abfd;
+ ieee->section_table = NULL;
+ ieee->section_table_size = 0;
+
+ processor = ieee->mb.processor = read_id (&(ieee->h));
+ if (strcmp (processor, "LIBRARY") == 0)
+ goto got_wrong_format;
+ ieee->mb.module_name = read_id (&(ieee->h));
+ if (abfd->filename == (CONST char *) NULL)
+ {
+ abfd->filename = ieee->mb.module_name;
+ }
+ /* Determine the architecture and machine type of the object file.
+ */
+ {
+ const bfd_arch_info_type *arch;
+ char family[10];
+
+ /* IEEE does not specify the format of the processor identificaton
+ string, so the compiler is free to put in it whatever it wants.
+ We try here to recognize different processors belonging to the
+ m68k family. Code for other processors can be added here. */
+ if ((processor[0] == '6') && (processor[1] == '8'))
+ {
+ if (processor[2] == '3') /* 683xx integrated processors */
+ {
+ switch (processor[3])
+ {
+ case '0': /* 68302, 68306, 68307 */
+ case '2': /* 68322, 68328 */
+ case '5': /* 68356 */
+ strcpy (family, "68000"); /* MC68000-based controllers */
+ break;
+
+ case '3': /* 68330, 68331, 68332, 68333,
+ 68334, 68335, 68336, 68338 */
+ case '6': /* 68360 */
+ case '7': /* 68376 */
+ strcpy (family, "68332"); /* CPU32 and CPU32+ */
+ break;
+
+ case '4':
+ if (processor[4] == '9') /* 68349 */
+ strcpy (family, "68030"); /* CPU030 */
+ else /* 68340, 68341 */
+ strcpy (family, "68332"); /* CPU32 and CPU32+ */
+ break;
+
+ default: /* Does not exist yet */
+ strcpy (family, "68332"); /* Guess it will be CPU32 */
+ }
+ }
+ else if (toupper (processor[3]) == 'F') /* 68F333 */
+ strcpy (family, "68332"); /* CPU32 */
+ else if ((toupper (processor[3]) == 'C') /* Embedded controllers */
+ && ((toupper (processor[2]) == 'E')
+ || (toupper (processor[2]) == 'H')
+ || (toupper (processor[2]) == 'L')))
+ {
+ strcpy (family, "68");
+ strncat (family, processor + 4, 7);
+ family[9] = '\0';
+ }
+ else /* "Regular" processors */
+ {
+ strncpy (family, processor, 9);
+ family[9] = '\0';
+ }
+ }
+ else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */
+ || (strncmp (processor, "CPU32", 5) == 0))
+ strcpy (family, "68332");
+ else
+ {
+ strncpy (family, processor, 9);
+ family[9] = '\0';
+ }
+
+ arch = bfd_scan_arch (family);
+ if (arch == 0)
+ goto got_wrong_format;
+ abfd->arch_info = arch;
+ }
+
+ if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum)
+ {
+ goto fail;
+ }
+ next_byte (&(ieee->h));
+
+ if (parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau) == false)
+ {
+ goto fail;
+ }
+ if (parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address) == false)
+ {
+ goto fail;
+ }
+
+ /* If there is a byte order info, take it */
+ if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum ||
+ this_byte (&(ieee->h)) == (int) ieee_variable_M_enum)
+ next_byte (&(ieee->h));
+
+ for (part = 0; part < N_W_VARIABLES; part++)
+ {
+ boolean ok;
+ if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum)
+ {
+ goto fail;
+ }
+ if (this_byte_and_next (&(ieee->h)) != part)
+ {
+ goto fail;
+ }
+
+ ieee->w.offset[part] = parse_i (&(ieee->h), &ok);
+ if (ok == false)
+ {
+ goto fail;
+ }
+
+ }
+
+ if (ieee->w.r.external_part != 0)
+ abfd->flags = HAS_SYMS;
+
+ /* By now we know that this is a real IEEE file, we're going to read
+ the whole thing into memory so that we can run up and down it
+ quickly. We can work out how big the file is from the trailer
+ record */
+
+ IEEE_DATA (abfd)->h.first_byte =
+ (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1);
+ if (!IEEE_DATA (abfd)->h.first_byte)
+ goto fail;
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto fail;
+ /* FIXME: Check return value. I'm not sure whether it needs to read
+ the entire buffer or not. */
+ bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1,
+ ieee->w.r.me_record + 1, abfd);
+
+ ieee_slurp_sections (abfd);
+
+ if (! ieee_slurp_debug (abfd))
+ goto fail;
+
+ /* Parse section data to activate file and section flags implied by
+ section contents. */
+
+ if (! ieee_slurp_section_data (abfd))
+ goto fail;
+
+ return abfd->xvec;
+got_wrong_format:
+ bfd_set_error (bfd_error_wrong_format);
+fail:
+ (void) bfd_release (abfd, ieee);
+ abfd->tdata.ieee_data = save;
+ return (const bfd_target *) NULL;
+}
+
+void
+ieee_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+ if (symbol->name[0] == ' ')
+ ret->name = "* empty table entry ";
+ if (!symbol->section)
+ ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
+}
+
+void
+ieee_print_symbol (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+#if 0
+ fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff,
+ aout_symbol (symbol)->other & 0xff);
+#endif
+ BFD_FAIL ();
+ break;
+ case bfd_print_symbol_all:
+ {
+ const char *section_name =
+ (symbol->section == (asection *) NULL
+ ? "*abs"
+ : symbol->section->name);
+ if (symbol->name[0] == ' ')
+ {
+ fprintf (file, "* empty table entry ");
+ }
+ else
+ {
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+
+ fprintf (file, " %-5s %04x %02x %s",
+ section_name,
+ (unsigned) ieee_symbol (symbol)->index,
+ (unsigned) 0,
+ symbol->name);
+ }
+ }
+ break;
+ }
+}
+
+static boolean
+do_one (ieee, current_map, location_ptr, s, iterations)
+ ieee_data_type *ieee;
+ ieee_per_section_type *current_map;
+ unsigned char *location_ptr;
+ asection *s;
+ int iterations;
+{
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_load_constant_bytes_enum:
+ {
+ unsigned int number_of_maus;
+ unsigned int i;
+ next_byte (&(ieee->h));
+ number_of_maus = must_parse_int (&(ieee->h));
+
+ for (i = 0; i < number_of_maus; i++)
+ {
+ location_ptr[current_map->pc++] = this_byte (&(ieee->h));
+ next_byte (&(ieee->h));
+ }
+ }
+ break;
+
+ case ieee_load_with_relocation_enum:
+ {
+ boolean loop = true;
+ next_byte (&(ieee->h));
+ while (loop)
+ {
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_variable_R_enum:
+
+ case ieee_function_signed_open_b_enum:
+ case ieee_function_unsigned_open_b_enum:
+ case ieee_function_either_open_b_enum:
+ {
+ unsigned int extra = 4;
+ boolean pcrel = false;
+ asection *section;
+ ieee_reloc_type *r =
+ (ieee_reloc_type *) bfd_alloc (ieee->h.abfd,
+ sizeof (ieee_reloc_type));
+ if (!r)
+ return false;
+
+ *(current_map->reloc_tail_ptr) = r;
+ current_map->reloc_tail_ptr = &r->next;
+ r->next = (ieee_reloc_type *) NULL;
+ next_byte (&(ieee->h));
+/* abort();*/
+ r->relent.sym_ptr_ptr = 0;
+ parse_expression (ieee,
+ &r->relent.addend,
+ &r->symbol,
+ &pcrel, &extra, &section);
+ r->relent.address = current_map->pc;
+ s->flags |= SEC_RELOC;
+ s->owner->flags |= HAS_RELOC;
+ s->reloc_count++;
+ if (r->relent.sym_ptr_ptr == NULL && section != NULL)
+ r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
+
+ if (this_byte (&(ieee->h)) == (int) ieee_comma)
+ {
+ next_byte (&(ieee->h));
+ /* Fetch number of bytes to pad */
+ extra = must_parse_int (&(ieee->h));
+ };
+
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_function_signed_close_b_enum:
+ next_byte (&(ieee->h));
+ break;
+ case ieee_function_unsigned_close_b_enum:
+ next_byte (&(ieee->h));
+ break;
+ case ieee_function_either_close_b_enum:
+ next_byte (&(ieee->h));
+ break;
+ default:
+ break;
+ }
+ /* Build a relocation entry for this type */
+ /* If pc rel then stick -ve pc into instruction
+ and take out of reloc ..
+
+ I've changed this. It's all too complicated. I
+ keep 0 in the instruction now. */
+
+ switch (extra)
+ {
+ case 0:
+ case 4:
+
+ if (pcrel == true)
+ {
+#if KEEPMINUSPCININST
+ bfd_put_32 (ieee->h.abfd, -current_map->pc, location_ptr +
+ current_map->pc);
+ r->relent.howto = &rel32_howto;
+ r->relent.addend -=
+ current_map->pc;
+#else
+ bfd_put_32 (ieee->h.abfd, 0, location_ptr +
+ current_map->pc);
+ r->relent.howto = &rel32_howto;
+#endif
+ }
+ else
+ {
+ bfd_put_32 (ieee->h.abfd, 0, location_ptr +
+ current_map->pc);
+ r->relent.howto = &abs32_howto;
+ }
+ current_map->pc += 4;
+ break;
+ case 2:
+ if (pcrel == true)
+ {
+#if KEEPMINUSPCININST
+ bfd_put_16 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
+ r->relent.addend -= current_map->pc;
+ r->relent.howto = &rel16_howto;
+#else
+
+ bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc);
+ r->relent.howto = &rel16_howto;
+#endif
+ }
+
+ else
+ {
+ bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc);
+ r->relent.howto = &abs16_howto;
+ }
+ current_map->pc += 2;
+ break;
+ case 1:
+ if (pcrel == true)
+ {
+#if KEEPMINUSPCININST
+ bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc);
+ r->relent.addend -= current_map->pc;
+ r->relent.howto = &rel8_howto;
+#else
+ bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
+ r->relent.howto = &rel8_howto;
+#endif
+ }
+ else
+ {
+ bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc);
+ r->relent.howto = &abs8_howto;
+ }
+ current_map->pc += 1;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return false;
+ }
+ }
+ break;
+ default:
+ {
+ bfd_vma this_size;
+ if (parse_int (&(ieee->h), &this_size) == true)
+ {
+ unsigned int i;
+ for (i = 0; i < this_size; i++)
+ {
+ location_ptr[current_map->pc++] = this_byte (&(ieee->h));
+ next_byte (&(ieee->h));
+ }
+ }
+ else
+ {
+ loop = false;
+ }
+ }
+ }
+
+ /* Prevent more than the first load-item of an LR record
+ from being repeated (MRI convention). */
+ if (iterations != 1)
+ loop = false;
+ }
+ }
+ }
+ return true;
+}
+
+/* Read in all the section data and relocation stuff too */
+static boolean
+ieee_slurp_section_data (abfd)
+ bfd *abfd;
+{
+ bfd_byte *location_ptr = (bfd_byte *) NULL;
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ unsigned int section_number;
+
+ ieee_per_section_type *current_map = (ieee_per_section_type *) NULL;
+ asection *s;
+ /* Seek to the start of the data area */
+ if (ieee->read_data == true)
+ return true;
+ ieee->read_data = true;
+ ieee_seek (abfd, ieee->w.r.data_part);
+
+ /* Allocate enough space for all the section contents */
+
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd;
+ if ((s->flags & SEC_DEBUGGING) != 0)
+ continue;
+ per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size);
+ if (!per->data)
+ return false;
+ /*SUPPRESS 68*/
+ per->reloc_tail_ptr =
+ (ieee_reloc_type **) & (s->relocation);
+ }
+
+ while (true)
+ {
+ switch (this_byte (&(ieee->h)))
+ {
+ /* IF we see anything strange then quit */
+ default:
+ return true;
+
+ case ieee_set_current_section_enum:
+ next_byte (&(ieee->h));
+ section_number = must_parse_int (&(ieee->h));
+ s = ieee->section_table[section_number];
+ s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
+ current_map = (ieee_per_section_type *) s->used_by_bfd;
+ location_ptr = current_map->data - s->vma;
+ /* The document I have says that Microtec's compilers reset */
+ /* this after a sec section, even though the standard says not */
+ /* to. SO .. */
+ current_map->pc = s->vma;
+ break;
+
+ case ieee_e2_first_byte_enum:
+ next_byte (&(ieee->h));
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_set_current_pc_enum & 0xff:
+ {
+ bfd_vma value;
+ ieee_symbol_index_type symbol;
+ unsigned int extra;
+ boolean pcrel;
+ next_byte (&(ieee->h));
+ must_parse_int (&(ieee->h)); /* Thow away section #*/
+ parse_expression (ieee, &value,
+ &symbol,
+ &pcrel, &extra,
+ 0);
+ current_map->pc = value;
+ BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size);
+ }
+ break;
+
+ case ieee_value_starting_address_enum & 0xff:
+ next_byte (&(ieee->h));
+ if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
+ next_byte (&(ieee->h));
+ abfd->start_address = must_parse_int (&(ieee->h));
+ /* We've got to the end of the data now - */
+ return true;
+ default:
+ BFD_FAIL ();
+ return false;
+ }
+ break;
+ case ieee_repeat_data_enum:
+ {
+ /* Repeat the following LD or LR n times - we do this by
+ remembering the stream pointer before running it and
+ resetting it and running it n times. We special case
+ the repetition of a repeat_data/load_constant
+ */
+
+ unsigned int iterations;
+ unsigned char *start;
+ next_byte (&(ieee->h));
+ iterations = must_parse_int (&(ieee->h));
+ start = ieee->h.input_p;
+ if (start[0] == (int) ieee_load_constant_bytes_enum &&
+ start[1] == 1)
+ {
+ while (iterations != 0)
+ {
+ location_ptr[current_map->pc++] = start[2];
+ iterations--;
+ }
+ next_byte (&(ieee->h));
+ next_byte (&(ieee->h));
+ next_byte (&(ieee->h));
+ }
+ else
+ {
+ while (iterations != 0)
+ {
+ ieee->h.input_p = start;
+ if (!do_one (ieee, current_map, location_ptr, s,
+ iterations))
+ return false;
+ iterations--;
+ }
+ }
+ }
+ break;
+ case ieee_load_constant_bytes_enum:
+ case ieee_load_with_relocation_enum:
+ {
+ if (!do_one (ieee, current_map, location_ptr, s, 1))
+ return false;
+ }
+ }
+ }
+}
+
+boolean
+ieee_new_section_hook (abfd, newsect)
+ bfd *abfd;
+ asection *newsect;
+{
+ newsect->used_by_bfd = (PTR)
+ bfd_alloc (abfd, sizeof (ieee_per_section_type));
+ if (!newsect->used_by_bfd)
+ return false;
+ ieee_per_section (newsect)->data = (bfd_byte *) NULL;
+ ieee_per_section (newsect)->section = newsect;
+ return true;
+}
+
+long
+ieee_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ if ((asect->flags & SEC_DEBUGGING) != 0)
+ return 0;
+ if (! ieee_slurp_section_data (abfd))
+ return -1;
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+static boolean
+ieee_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;
+ if ((section->flags & SEC_DEBUGGING) != 0)
+ return _bfd_generic_get_section_contents (abfd, section, location,
+ offset, count);
+ ieee_slurp_section_data (abfd);
+ (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count);
+ return true;
+}
+
+long
+ieee_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/
+ ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation);
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+
+ if ((section->flags & SEC_DEBUGGING) != 0)
+ return 0;
+
+ while (src != (ieee_reloc_type *) NULL)
+ {
+ /* Work out which symbol to attach it this reloc to */
+ switch (src->symbol.letter)
+ {
+ case 'I':
+ src->relent.sym_ptr_ptr =
+ symbols + src->symbol.index + ieee->external_symbol_base_offset;
+ break;
+ case 'X':
+ src->relent.sym_ptr_ptr =
+ symbols + src->symbol.index + ieee->external_reference_base_offset;
+ break;
+ case 0:
+ if (src->relent.sym_ptr_ptr != NULL)
+ src->relent.sym_ptr_ptr =
+ src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
+ break;
+ default:
+
+ BFD_FAIL ();
+ }
+ *relptr++ = &src->relent;
+ src = src->next;
+ }
+ *relptr = (arelent *) NULL;
+ return section->reloc_count;
+}
+
+static int
+comp (ap, bp)
+ CONST PTR ap;
+ CONST PTR bp;
+{
+ arelent *a = *((arelent **) ap);
+ arelent *b = *((arelent **) bp);
+ return a->address - b->address;
+}
+
+/* Write the section headers. */
+
+static boolean
+ieee_write_section_part (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ asection *s;
+ ieee->w.r.section_part = bfd_tell (abfd);
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ if (! bfd_is_abs_section (s)
+ && (s->flags & SEC_DEBUGGING) == 0)
+ {
+ if (! ieee_write_byte (abfd, ieee_section_type_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index
+ + IEEE_SECTION_NUMBER_BASE)))
+ return false;
+
+ if (abfd->flags & EXEC_P)
+ {
+ /* This image is executable, so output absolute sections */
+ if (! ieee_write_byte (abfd, ieee_variable_A_enum)
+ || ! ieee_write_byte (abfd, ieee_variable_S_enum))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_byte (abfd, ieee_variable_C_enum))
+ return false;
+ }
+
+ switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM))
+ {
+ case SEC_CODE | SEC_LOAD:
+ case SEC_CODE:
+ if (! ieee_write_byte (abfd, ieee_variable_P_enum))
+ return false;
+ break;
+ case SEC_DATA:
+ default:
+ if (! ieee_write_byte (abfd, ieee_variable_D_enum))
+ return false;
+ break;
+ case SEC_ROM:
+ case SEC_ROM | SEC_DATA:
+ case SEC_ROM | SEC_LOAD:
+ case SEC_ROM | SEC_DATA | SEC_LOAD:
+ if (! ieee_write_byte (abfd, ieee_variable_R_enum))
+ return false;
+ }
+
+
+ if (! ieee_write_id (abfd, s->name))
+ return false;
+#if 0
+ ieee_write_int (abfd, 0); /* Parent */
+ ieee_write_int (abfd, 0); /* Brother */
+ ieee_write_int (abfd, 0); /* Context */
+#endif
+ /* Alignment */
+ if (! ieee_write_byte (abfd, ieee_section_alignment_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index
+ + IEEE_SECTION_NUMBER_BASE))
+ || ! ieee_write_int (abfd, 1 << s->alignment_power))
+ return false;
+
+ /* Size */
+ if (! ieee_write_2bytes (abfd, ieee_section_size_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index
+ + IEEE_SECTION_NUMBER_BASE))
+ || ! ieee_write_int (abfd, s->_raw_size))
+ return false;
+ if (abfd->flags & EXEC_P)
+ {
+ /* Relocateable sections don't have asl records */
+ /* Vma */
+ if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum)
+ || ! ieee_write_byte (abfd,
+ ((bfd_byte)
+ (s->index
+ + IEEE_SECTION_NUMBER_BASE)))
+ || ! ieee_write_int (abfd, s->lma))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+static boolean
+do_with_relocs (abfd, s)
+ bfd *abfd;
+ asection *s;
+{
+ unsigned int number_of_maus_in_address =
+ bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
+ unsigned int relocs_to_go = s->reloc_count;
+ bfd_byte *stream = ieee_per_section (s)->data;
+ arelent **p = s->orelocation;
+ bfd_size_type current_byte_index = 0;
+
+ qsort (s->orelocation,
+ relocs_to_go,
+ sizeof (arelent **),
+ comp);
+
+ /* Output the section preheader */
+ if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
+ || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
+ return false;
+ if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
+ {
+ if (! ieee_write_int (abfd, s->lma))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0))
+ return false;
+ }
+
+ if (relocs_to_go == 0)
+ {
+ /* If there aren't any relocations then output the load constant
+ byte opcode rather than the load with relocation opcode */
+
+ while (current_byte_index < s->_raw_size)
+ {
+ bfd_size_type run;
+ unsigned int MAXRUN = 127;
+ run = MAXRUN;
+ if (run > s->_raw_size - current_byte_index)
+ {
+ run = s->_raw_size - current_byte_index;
+ }
+
+ if (run != 0)
+ {
+ if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum))
+ return false;
+ /* Output a stream of bytes */
+ if (! ieee_write_int (abfd, run))
+ return false;
+ if (bfd_write ((PTR) (stream + current_byte_index),
+ 1,
+ run,
+ abfd)
+ != run)
+ return false;
+ current_byte_index += run;
+ }
+ }
+ }
+ else
+ {
+ if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum))
+ return false;
+
+ /* Output the data stream as the longest sequence of bytes
+ possible, allowing for the a reasonable packet size and
+ relocation stuffs. */
+
+ if ((PTR) stream == (PTR) NULL)
+ {
+ /* Outputting a section without data, fill it up */
+ stream = (unsigned char *) (bfd_alloc (abfd, s->_raw_size));
+ if (!stream)
+ return false;
+ memset ((PTR) stream, 0, (size_t) s->_raw_size);
+ }
+ while (current_byte_index < s->_raw_size)
+ {
+ bfd_size_type run;
+ unsigned int MAXRUN = 127;
+ if (relocs_to_go)
+ {
+ run = (*p)->address - current_byte_index;
+ if (run > MAXRUN)
+ run = MAXRUN;
+ }
+ else
+ {
+ run = MAXRUN;
+ }
+ if (run > s->_raw_size - current_byte_index)
+ {
+ run = s->_raw_size - current_byte_index;
+ }
+
+ if (run != 0)
+ {
+ /* Output a stream of bytes */
+ if (! ieee_write_int (abfd, run))
+ return false;
+ if (bfd_write ((PTR) (stream + current_byte_index),
+ 1,
+ run,
+ abfd)
+ != run)
+ return false;
+ current_byte_index += run;
+ }
+ /* Output any relocations here */
+ if (relocs_to_go && (*p) && (*p)->address == current_byte_index)
+ {
+ while (relocs_to_go
+ && (*p) && (*p)->address == current_byte_index)
+ {
+ arelent *r = *p;
+ bfd_signed_vma ov;
+
+#if 0
+ if (r->howto->pc_relative)
+ {
+ r->addend += current_byte_index;
+ }
+#endif
+
+ switch (r->howto->size)
+ {
+ case 2:
+
+ ov = bfd_get_signed_32 (abfd,
+ stream + current_byte_index);
+ current_byte_index += 4;
+ break;
+ case 1:
+ ov = bfd_get_signed_16 (abfd,
+ stream + current_byte_index);
+ current_byte_index += 2;
+ break;
+ case 0:
+ ov = bfd_get_signed_8 (abfd,
+ stream + current_byte_index);
+ current_byte_index++;
+ break;
+ default:
+ ov = 0;
+ BFD_FAIL ();
+ return false;
+ }
+
+ ov &= r->howto->src_mask;
+
+ if (r->howto->pc_relative
+ && ! r->howto->pcrel_offset)
+ ov += r->address;
+
+ if (! ieee_write_byte (abfd,
+ ieee_function_either_open_b_enum))
+ return false;
+
+/* abort();*/
+
+ if (r->sym_ptr_ptr != (asymbol **) NULL)
+ {
+ if (! ieee_write_expression (abfd, r->addend + ov,
+ *(r->sym_ptr_ptr),
+ r->howto->pc_relative,
+ s->index))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_expression (abfd, r->addend + ov,
+ (asymbol *) NULL,
+ r->howto->pc_relative,
+ s->index))
+ return false;
+ }
+
+ if (number_of_maus_in_address
+ != bfd_get_reloc_size (r->howto))
+ {
+ if (! ieee_write_int (abfd,
+ bfd_get_reloc_size (r->howto)))
+ return false;
+ }
+ if (! ieee_write_byte (abfd,
+ ieee_function_either_close_b_enum))
+ return false;
+
+ relocs_to_go--;
+ p++;
+ }
+
+ }
+ }
+ }
+
+ return true;
+}
+
+/* If there are no relocations in the output section then we can be
+ clever about how we write. We block items up into a max of 127
+ bytes. */
+
+static boolean
+do_as_repeat (abfd, s)
+ bfd *abfd;
+ asection *s;
+{
+ if (s->_raw_size)
+ {
+ if (! ieee_write_byte (abfd, ieee_set_current_section_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index
+ + IEEE_SECTION_NUMBER_BASE))
+ || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8)
+ || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (s->index
+ + IEEE_SECTION_NUMBER_BASE))
+ || ! ieee_write_int (abfd, s->lma)
+ || ! ieee_write_byte (abfd, ieee_repeat_data_enum)
+ || ! ieee_write_int (abfd, s->_raw_size)
+ || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
+ || ! ieee_write_byte (abfd, 1)
+ || ! ieee_write_byte (abfd, 0))
+ return false;
+ }
+
+ return true;
+}
+
+static boolean
+do_without_relocs (abfd, s)
+ bfd *abfd;
+ asection *s;
+{
+ bfd_byte *stream = ieee_per_section (s)->data;
+
+ if (stream == 0 || ((s->flags & SEC_LOAD) == 0))
+ {
+ if (! do_as_repeat (abfd, s))
+ return false;
+ }
+ else
+ {
+ unsigned int i;
+ for (i = 0; i < s->_raw_size; i++)
+ {
+ if (stream[i] != 0)
+ {
+ if (! do_with_relocs (abfd, s))
+ return false;
+ return true;
+ }
+ }
+ if (! do_as_repeat (abfd, s))
+ return false;
+ }
+
+ return true;
+}
+
+
+static unsigned char *output_ptr_start;
+static unsigned char *output_ptr;
+static unsigned char *output_ptr_end;
+static unsigned char *input_ptr_start;
+static unsigned char *input_ptr;
+static unsigned char *input_ptr_end;
+static bfd *input_bfd;
+static bfd *output_bfd;
+static int output_buffer;
+
+static void
+fill ()
+{
+ /* FIXME: Check return value. I'm not sure whether it needs to read
+ the entire buffer or not. */
+ bfd_read ((PTR) input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd);
+ input_ptr = input_ptr_start;
+}
+static void
+flush ()
+{
+ if (bfd_write ((PTR) (output_ptr_start), 1, output_ptr - output_ptr_start,
+ output_bfd)
+ != (bfd_size_type) (output_ptr - output_ptr_start))
+ abort ();
+ output_ptr = output_ptr_start;
+ output_buffer++;
+}
+
+#define THIS() ( *input_ptr )
+#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); }
+#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); }
+
+static void
+write_int (value)
+ int value;
+{
+ if (value >= 0 && value <= 127)
+ {
+ OUT (value);
+ }
+ else
+ {
+ unsigned int length;
+ /* How many significant bytes ? */
+ /* FIXME FOR LONGER INTS */
+ if (value & 0xff000000)
+ {
+ length = 4;
+ }
+ else if (value & 0x00ff0000)
+ {
+ length = 3;
+ }
+ else if (value & 0x0000ff00)
+ {
+ length = 2;
+ }
+ else
+ length = 1;
+
+ OUT ((int) ieee_number_repeat_start_enum + length);
+ switch (length)
+ {
+ case 4:
+ OUT (value >> 24);
+ case 3:
+ OUT (value >> 16);
+ case 2:
+ OUT (value >> 8);
+ case 1:
+ OUT (value);
+ }
+
+ }
+}
+
+static void
+copy_id ()
+{
+ int length = THIS ();
+ char ch;
+ OUT (length);
+ NEXT ();
+ while (length--)
+ {
+ ch = THIS ();
+ OUT (ch);
+ NEXT ();
+ }
+}
+
+#define VAR(x) ((x | 0x80))
+static void
+copy_expression ()
+{
+ int stack[10];
+ int *tos = stack;
+ int value = 0;
+ while (1)
+ {
+ switch (THIS ())
+ {
+ case 0x84:
+ NEXT ();
+ value = THIS ();
+ NEXT ();
+ value = (value << 8) | THIS ();
+ NEXT ();
+ value = (value << 8) | THIS ();
+ NEXT ();
+ value = (value << 8) | THIS ();
+ NEXT ();
+ *tos++ = value;
+ break;
+ case 0x83:
+ NEXT ();
+ value = THIS ();
+ NEXT ();
+ value = (value << 8) | THIS ();
+ NEXT ();
+ value = (value << 8) | THIS ();
+ NEXT ();
+ *tos++ = value;
+ break;
+ case 0x82:
+ NEXT ();
+ value = THIS ();
+ NEXT ();
+ value = (value << 8) | THIS ();
+ NEXT ();
+ *tos++ = value;
+ break;
+ case 0x81:
+ NEXT ();
+ value = THIS ();
+ NEXT ();
+ *tos++ = value;
+ break;
+ case 0x80:
+ NEXT ();
+ *tos++ = 0;
+ break;
+ default:
+ if (THIS () > 0x84)
+ {
+ /* Not a number, just bug out with the answer */
+ write_int (*(--tos));
+ return;
+ }
+ *tos++ = THIS ();
+ NEXT ();
+ value = 0;
+ break;
+ case 0xa5:
+ /* PLUS anything */
+ {
+ int value = *(--tos);
+ value += *(--tos);
+ *tos++ = value;
+ NEXT ();
+ }
+ break;
+ case VAR ('R'):
+ {
+ int section_number;
+ ieee_data_type *ieee;
+ asection *s;
+ NEXT ();
+ section_number = THIS ();
+
+ NEXT ();
+ ieee = IEEE_DATA (input_bfd);
+ s = ieee->section_table[section_number];
+ if (s->output_section)
+ {
+ value = s->output_section->lma;
+ }
+ else
+ {
+ value = 0;
+ }
+ value += s->output_offset;
+ *tos++ = value;
+ value = 0;
+ }
+ break;
+ case 0x90:
+ {
+ NEXT ();
+ write_int (*(--tos));
+ OUT (0x90);
+ return;
+
+ }
+ }
+ }
+
+}
+
+/* Drop the int in the buffer, and copy a null into the gap, which we
+ will overwrite later */
+
+struct output_buffer_struct
+{
+ unsigned char *ptrp;
+ int buffer;
+};
+
+static void
+fill_int (buf)
+ struct output_buffer_struct *buf;
+{
+ if (buf->buffer == output_buffer)
+ {
+ /* Still a chance to output the size */
+ int value = output_ptr - buf->ptrp + 3;
+ buf->ptrp[0] = value >> 24;
+ buf->ptrp[1] = value >> 16;
+ buf->ptrp[2] = value >> 8;
+ buf->ptrp[3] = value >> 0;
+ }
+}
+
+static void
+drop_int (buf)
+ struct output_buffer_struct *buf;
+{
+ int type = THIS ();
+ int ch;
+ if (type <= 0x84)
+ {
+ NEXT ();
+ switch (type)
+ {
+ case 0x84:
+ ch = THIS ();
+ NEXT ();
+ case 0x83:
+ ch = THIS ();
+ NEXT ();
+ case 0x82:
+ ch = THIS ();
+ NEXT ();
+ case 0x81:
+ ch = THIS ();
+ NEXT ();
+ case 0x80:
+ break;
+ }
+ }
+ OUT (0x84);
+ buf->ptrp = output_ptr;
+ buf->buffer = output_buffer;
+ OUT (0);
+ OUT (0);
+ OUT (0);
+ OUT (0);
+}
+
+static void
+copy_int ()
+{
+ int type = THIS ();
+ int ch;
+ if (type <= 0x84)
+ {
+ OUT (type);
+ NEXT ();
+ switch (type)
+ {
+ case 0x84:
+ ch = THIS ();
+ NEXT ();
+ OUT (ch);
+ case 0x83:
+ ch = THIS ();
+ NEXT ();
+ OUT (ch);
+ case 0x82:
+ ch = THIS ();
+ NEXT ();
+ OUT (ch);
+ case 0x81:
+ ch = THIS ();
+ NEXT ();
+ OUT (ch);
+ case 0x80:
+ break;
+ }
+ }
+}
+
+#define ID copy_id()
+#define INT copy_int()
+#define EXP copy_expression()
+static void copy_till_end ();
+#define INTn(q) copy_int()
+#define EXPn(q) copy_expression()
+
+static void
+f1_record ()
+{
+ int ch;
+ /* ATN record */
+ NEXT ();
+ ch = THIS ();
+ switch (ch)
+ {
+ default:
+ OUT (0xf1);
+ OUT (ch);
+ break;
+ case 0xc9:
+ NEXT ();
+ OUT (0xf1);
+ OUT (0xc9);
+ INT;
+ INT;
+ ch = THIS ();
+ switch (ch)
+ {
+ case 0x16:
+ NEXT ();
+ break;
+ case 0x01:
+ NEXT ();
+ break;
+ case 0x00:
+ NEXT ();
+ INT;
+ break;
+ case 0x03:
+ NEXT ();
+ INT;
+ break;
+ case 0x13:
+ EXPn (instruction address);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 0xd8:
+ /* EXternal ref */
+ NEXT ();
+ OUT (0xf1);
+ OUT (0xd8);
+ EXP;
+ EXP;
+ EXP;
+ EXP;
+ break;
+ case 0xce:
+ NEXT ();
+ OUT (0xf1);
+ OUT (0xce);
+ INT;
+ INT;
+ ch = THIS ();
+ INT;
+ switch (ch)
+ {
+ case 0x01:
+ INT;
+ INT;
+ break;
+ case 0x02:
+ INT;
+ break;
+ case 0x04:
+ EXPn (external function);
+ break;
+ case 0x05:
+ break;
+ case 0x07:
+ INTn (line number);
+ INT;
+ case 0x08:
+ break;
+ case 0x0a:
+ INTn (locked register);
+ INT;
+ break;
+ case 0x3f:
+ copy_till_end ();
+ break;
+ case 0x3e:
+ copy_till_end ();
+ break;
+ case 0x40:
+ copy_till_end ();
+ break;
+ case 0x41:
+ ID;
+ break;
+ }
+ }
+
+}
+
+static void
+f0_record ()
+{
+ /* Attribute record */
+ NEXT ();
+ OUT (0xf0);
+ INTn (Symbol name);
+ ID;
+}
+
+static void
+copy_till_end ()
+{
+ int ch = THIS ();
+ while (1)
+ {
+ while (ch <= 0x80)
+ {
+ OUT (ch);
+ NEXT ();
+ ch = THIS ();
+ }
+ switch (ch)
+ {
+ case 0x84:
+ OUT (THIS ());
+ NEXT ();
+ case 0x83:
+ OUT (THIS ());
+ NEXT ();
+ case 0x82:
+ OUT (THIS ());
+ NEXT ();
+ case 0x81:
+ OUT (THIS ());
+ NEXT ();
+ OUT (THIS ());
+ NEXT ();
+
+ ch = THIS ();
+ break;
+ default:
+ return;
+ }
+ }
+
+}
+
+static void
+f2_record ()
+{
+ NEXT ();
+ OUT (0xf2);
+ INT;
+ NEXT ();
+ OUT (0xce);
+ INT;
+ copy_till_end ();
+}
+
+
+static void block ();
+static void
+f8_record ()
+{
+ int ch;
+ NEXT ();
+ ch = THIS ();
+ switch (ch)
+ {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ /* Unique typedefs for module */
+ /* GLobal typedefs */
+ /* High level module scope beginning */
+ {
+ struct output_buffer_struct ob;
+ NEXT ();
+ OUT (0xf8);
+ OUT (ch);
+ drop_int (&ob);
+ ID;
+
+ block ();
+
+ NEXT ();
+ fill_int (&ob);
+ OUT (0xf9);
+ }
+ break;
+ case 0x04:
+ /* Global function */
+ {
+ struct output_buffer_struct ob;
+ NEXT ();
+ OUT (0xf8);
+ OUT (0x04);
+ drop_int (&ob);
+ ID;
+ INTn (stack size);
+ INTn (ret val);
+ EXPn (offset);
+
+ block ();
+
+ NEXT ();
+ OUT (0xf9);
+ EXPn (size of block);
+ fill_int (&ob);
+ }
+ break;
+
+ case 0x05:
+ /* File name for source line numbers */
+ {
+ struct output_buffer_struct ob;
+ NEXT ();
+ OUT (0xf8);
+ OUT (0x05);
+ drop_int (&ob);
+ ID;
+ INTn (year);
+ INTn (month);
+ INTn (day);
+ INTn (hour);
+ INTn (monute);
+ INTn (second);
+ block ();
+ NEXT ();
+ OUT (0xf9);
+ fill_int (&ob);
+ }
+ break;
+
+ case 0x06:
+ /* Local function */
+ {
+ struct output_buffer_struct ob;
+ NEXT ();
+ OUT (0xf8);
+ OUT (0x06);
+ drop_int (&ob);
+ ID;
+ INTn (stack size);
+ INTn (type return);
+ EXPn (offset);
+ block ();
+ NEXT ();
+ OUT (0xf9);
+ EXPn (size);
+ fill_int (&ob);
+ }
+ break;
+
+ case 0x0a:
+ /* Assembler module scope beginning -*/
+ {
+ struct output_buffer_struct ob;
+
+ NEXT ();
+ OUT (0xf8);
+ OUT (0x0a);
+ drop_int (&ob);
+ ID;
+ ID;
+ INT;
+ ID;
+ INT;
+ INT;
+ INT;
+ INT;
+ INT;
+ INT;
+
+ block ();
+
+ NEXT ();
+ OUT (0xf9);
+ fill_int (&ob);
+ }
+ break;
+ case 0x0b:
+ {
+ struct output_buffer_struct ob;
+ NEXT ();
+ OUT (0xf8);
+ OUT (0x0b);
+ drop_int (&ob);
+ ID;
+ INT;
+ INTn (section index);
+ EXPn (offset);
+ INTn (stuff);
+
+ block ();
+
+ OUT (0xf9);
+ NEXT ();
+ EXPn (Size in Maus);
+ fill_int (&ob);
+ }
+ break;
+ }
+}
+
+static void
+e2_record ()
+{
+ OUT (0xe2);
+ NEXT ();
+ OUT (0xce);
+ NEXT ();
+ INT;
+ EXP;
+}
+
+static void
+block ()
+{
+ int ch;
+ while (1)
+ {
+ ch = THIS ();
+ switch (ch)
+ {
+ case 0xe1:
+ case 0xe5:
+ return;
+ case 0xf9:
+ return;
+ case 0xf0:
+ f0_record ();
+ break;
+ case 0xf1:
+ f1_record ();
+ break;
+ case 0xf2:
+ f2_record ();
+ break;
+ case 0xf8:
+ f8_record ();
+ break;
+ case 0xe2:
+ e2_record ();
+ break;
+
+ }
+ }
+}
+
+
+
+/* relocate_debug,
+ moves all the debug information from the source bfd to the output
+ bfd, and relocates any expressions it finds
+*/
+
+static void
+relocate_debug (output, input)
+ bfd *output;
+ bfd *input;
+{
+#define IBS 400
+#define OBS 400
+ unsigned char input_buffer[IBS];
+
+ input_ptr_start = input_ptr = input_buffer;
+ input_ptr_end = input_buffer + IBS;
+ input_bfd = input;
+ /* FIXME: Check return value. I'm not sure whether it needs to read
+ the entire buffer or not. */
+ bfd_read ((PTR) input_ptr_start, 1, IBS, input);
+ block ();
+}
+
+/*
+ During linking, we we told about the bfds which made up our
+ contents, we have a list of them. They will still be open, so go to
+ the debug info in each, and copy it out, relocating it as we go.
+*/
+
+static boolean
+ieee_write_debug_part (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ bfd_chain_type *chain = ieee->chain_root;
+ unsigned char output_buffer[OBS];
+ boolean some_debug = false;
+ file_ptr here = bfd_tell (abfd);
+
+ output_ptr_start = output_ptr = output_buffer;
+ output_ptr_end = output_buffer + OBS;
+ output_ptr = output_buffer;
+ output_bfd = abfd;
+
+ if (chain == (bfd_chain_type *) NULL)
+ {
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if ((s->flags & SEC_DEBUGGING) != 0)
+ break;
+ if (s == NULL)
+ {
+ ieee->w.r.debug_information_part = 0;
+ return true;
+ }
+
+ ieee->w.r.debug_information_part = here;
+ if (bfd_write (s->contents, 1, s->_raw_size, abfd) != s->_raw_size)
+ return false;
+ }
+ else
+ {
+ while (chain != (bfd_chain_type *) NULL)
+ {
+ bfd *entry = chain->this;
+ ieee_data_type *entry_ieee = IEEE_DATA (entry);
+ if (entry_ieee->w.r.debug_information_part)
+ {
+ if (bfd_seek (entry, entry_ieee->w.r.debug_information_part,
+ SEEK_SET)
+ != 0)
+ return false;
+ relocate_debug (abfd, entry);
+ }
+
+ chain = chain->next;
+ }
+ if (some_debug)
+ {
+ ieee->w.r.debug_information_part = here;
+ }
+ else
+ {
+ ieee->w.r.debug_information_part = 0;
+ }
+
+ flush ();
+ }
+
+ return true;
+}
+
+/* Write the data in an ieee way. */
+
+static boolean
+ieee_write_data_part (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ ieee->w.r.data_part = bfd_tell (abfd);
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ /* Skip sections that have no loadable contents (.bss,
+ debugging, etc.) */
+ if ((s->flags & SEC_LOAD) == 0)
+ continue;
+
+ /* Sort the reloc records so we can insert them in the correct
+ places */
+ if (s->reloc_count != 0)
+ {
+ if (! do_with_relocs (abfd, s))
+ return false;
+ }
+ else
+ {
+ if (! do_without_relocs (abfd, s))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+static boolean
+init_for_output (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ if ((s->flags & SEC_DEBUGGING) != 0)
+ continue;
+ if (s->_raw_size != 0)
+ {
+ ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, s->_raw_size));
+ if (!ieee_per_section (s)->data)
+ return false;
+ }
+ }
+ return true;
+}
+
+/** exec and core file sections */
+
+/* set section contents is complicated with IEEE since the format is
+* not a byte image, but a record stream.
+*/
+boolean
+ieee_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if ((section->flags & SEC_DEBUGGING) != 0)
+ {
+ if (section->contents == NULL)
+ {
+ section->contents = ((unsigned char *)
+ bfd_alloc (abfd, section->_raw_size));
+ if (section->contents == NULL)
+ return false;
+ }
+ /* bfd_set_section_contents has already checked that everything
+ is within range. */
+ memcpy (section->contents + offset, location, count);
+ return true;
+ }
+
+ if (ieee_per_section (section)->data == (bfd_byte *) NULL)
+ {
+ if (!init_for_output (abfd))
+ return false;
+ }
+ memcpy ((PTR) (ieee_per_section (section)->data + offset),
+ (PTR) location,
+ (unsigned int) count);
+ return true;
+}
+
+/* Write the external symbols of a file. IEEE considers two sorts of
+ external symbols, public, and referenced. It uses to internal
+ forms to index them as well. When we write them out we turn their
+ symbol values into indexes from the right base. */
+
+static boolean
+ieee_write_external_part (abfd)
+ bfd *abfd;
+{
+ asymbol **q;
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+
+ unsigned int reference_index = IEEE_REFERENCE_BASE;
+ unsigned int public_index = IEEE_PUBLIC_BASE + 2;
+ file_ptr here = bfd_tell (abfd);
+ boolean hadone = false;
+ if (abfd->outsymbols != (asymbol **) NULL)
+ {
+
+ for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
+ {
+ asymbol *p = *q;
+ if (bfd_is_und_section (p->section))
+ {
+ /* This must be a symbol reference .. */
+ if (! ieee_write_byte (abfd, ieee_external_reference_enum)
+ || ! ieee_write_int (abfd, reference_index)
+ || ! ieee_write_id (abfd, p->name))
+ return false;
+ p->value = reference_index;
+ reference_index++;
+ hadone = true;
+ }
+ else if (bfd_is_com_section (p->section))
+ {
+ /* This is a weak reference */
+ if (! ieee_write_byte (abfd, ieee_external_reference_enum)
+ || ! ieee_write_int (abfd, reference_index)
+ || ! ieee_write_id (abfd, p->name)
+ || ! ieee_write_byte (abfd,
+ ieee_weak_external_reference_enum)
+ || ! ieee_write_int (abfd, reference_index)
+ || ! ieee_write_int (abfd, p->value))
+ return false;
+ p->value = reference_index;
+ reference_index++;
+ hadone = true;
+ }
+ else if (p->flags & BSF_GLOBAL)
+ {
+ /* This must be a symbol definition */
+
+ if (! ieee_write_byte (abfd, ieee_external_symbol_enum)
+ || ! ieee_write_int (abfd, public_index)
+ || ! ieee_write_id (abfd, p->name)
+ || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
+ || ! ieee_write_int (abfd, public_index)
+ || ! ieee_write_byte (abfd, 15) /* instruction address */
+ || ! ieee_write_byte (abfd, 19) /* static symbol */
+ || ! ieee_write_byte (abfd, 1)) /* one of them */
+ return false;
+
+ /* Write out the value */
+ if (! ieee_write_2bytes (abfd, ieee_value_record_enum)
+ || ! ieee_write_int (abfd, public_index))
+ return false;
+ if (! bfd_is_abs_section (p->section))
+ {
+ if (abfd->flags & EXEC_P)
+ {
+ /* If fully linked, then output all symbols
+ relocated */
+ if (! (ieee_write_int
+ (abfd,
+ (p->value
+ + p->section->output_offset
+ + p->section->output_section->vma))))
+ return false;
+ }
+ else
+ {
+ if (! (ieee_write_expression
+ (abfd,
+ p->value + p->section->output_offset,
+ p->section->output_section->symbol,
+ false, 0)))
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_write_expression (abfd,
+ p->value,
+ bfd_abs_section_ptr->symbol,
+ false, 0))
+ return false;
+ }
+ p->value = public_index;
+ public_index++;
+ hadone = true;
+ }
+ else
+ {
+ /* This can happen - when there are gaps in the symbols read */
+ /* from an input ieee file */
+ }
+ }
+ }
+ if (hadone)
+ ieee->w.r.external_part = here;
+
+ return true;
+}
+
+
+static CONST unsigned char exten[] =
+{
+ 0xf0, 0x20, 0x00,
+ 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3 */
+ 0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in original case */
+ 0xf1, 0xce, 0x20, 0x00, 38 /* set object type relocateable to x */
+};
+
+static CONST unsigned char envi[] =
+{
+ 0xf0, 0x21, 0x00,
+
+/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11,
+ 0x19, 0x2c,
+*/
+ 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok */
+
+ 0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */
+/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */
+};
+
+static boolean
+ieee_write_me_part (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ ieee->w.r.trailer_part = bfd_tell (abfd);
+ if (abfd->start_address)
+ {
+ if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
+ || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
+ || ! ieee_write_int (abfd, abfd->start_address)
+ || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
+ return false;
+ }
+ ieee->w.r.me_record = bfd_tell (abfd);
+ if (! ieee_write_byte (abfd, ieee_module_end_enum))
+ return false;
+ return true;
+}
+
+/* Write out the IEEE processor ID. */
+
+static boolean
+ieee_write_processor (abfd)
+ bfd *abfd;
+{
+ const bfd_arch_info_type *arch;
+
+ arch = bfd_get_arch_info (abfd);
+ switch (arch->arch)
+ {
+ default:
+ if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
+ return false;
+ break;
+
+ case bfd_arch_a29k:
+ if (! ieee_write_id (abfd, "29000"))
+ return false;
+ break;
+
+ case bfd_arch_h8300:
+ if (! ieee_write_id (abfd, "H8/300"))
+ return false;
+ break;
+
+ case bfd_arch_h8500:
+ if (! ieee_write_id (abfd, "H8/500"))
+ return false;
+ break;
+
+ case bfd_arch_i960:
+ switch (arch->mach)
+ {
+ default:
+ case bfd_mach_i960_core:
+ case bfd_mach_i960_ka_sa:
+ if (! ieee_write_id (abfd, "80960KA"))
+ return false;
+ break;
+
+ case bfd_mach_i960_kb_sb:
+ if (! ieee_write_id (abfd, "80960KB"))
+ return false;
+ break;
+
+ case bfd_mach_i960_ca:
+ if (! ieee_write_id (abfd, "80960CA"))
+ return false;
+ break;
+
+ case bfd_mach_i960_mc:
+ case bfd_mach_i960_xa:
+ if (! ieee_write_id (abfd, "80960MC"))
+ return false;
+ break;
+ }
+ break;
+
+ case bfd_arch_m68k:
+ {
+ const char *id;
+
+ switch (arch->mach)
+ {
+ default: id = "68020"; break;
+ case bfd_mach_m68000: id = "68000"; break;
+ case bfd_mach_m68008: id = "68008"; break;
+ case bfd_mach_m68010: id = "68010"; break;
+ case bfd_mach_m68020: id = "68020"; break;
+ case bfd_mach_m68030: id = "68030"; break;
+ case bfd_mach_m68040: id = "68040"; break;
+ case bfd_mach_m68060: id = "68060"; break;
+ case bfd_mach_cpu32: id = "cpu32"; break;
+ }
+
+ if (! ieee_write_id (abfd, id))
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+boolean
+ieee_write_object_contents (abfd)
+ bfd *abfd;
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ unsigned int i;
+ file_ptr old;
+
+ /* Fast forward over the header area */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+
+ if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
+ || ! ieee_write_processor (abfd)
+ || ! ieee_write_id (abfd, abfd->filename))
+ return false;
+
+ /* Fast forward over the variable bits */
+ if (! ieee_write_byte (abfd, ieee_address_descriptor_enum))
+ return false;
+
+ /* Bits per MAU */
+ if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd))))
+ return false;
+ /* MAU's per address */
+ if (! ieee_write_byte (abfd,
+ (bfd_byte) (bfd_arch_bits_per_address (abfd)
+ / bfd_arch_bits_per_byte (abfd))))
+ return false;
+
+ old = bfd_tell (abfd);
+ if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0)
+ return false;
+
+ ieee->w.r.extension_record = bfd_tell (abfd);
+ if (bfd_write ((char *) exten, 1, sizeof (exten), abfd) != sizeof (exten))
+ return false;
+ if (abfd->flags & EXEC_P)
+ {
+ if (! ieee_write_byte (abfd, 0x1)) /* Absolute */
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */
+ return false;
+ }
+
+ ieee->w.r.environmental_record = bfd_tell (abfd);
+ if (bfd_write ((char *) envi, 1, sizeof (envi), abfd) != sizeof (envi))
+ return false;
+
+ /* The HP emulator database requires a timestamp in the file. */
+ {
+ time_t now;
+ const struct tm *t;
+
+ time (&now);
+ t = (struct tm *) localtime (&now);
+ if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
+ || ! ieee_write_byte (abfd, 0x21)
+ || ! ieee_write_byte (abfd, 0)
+ || ! ieee_write_byte (abfd, 50)
+ || ! ieee_write_int (abfd, t->tm_year + 1900)
+ || ! ieee_write_int (abfd, t->tm_mon + 1)
+ || ! ieee_write_int (abfd, t->tm_mday)
+ || ! ieee_write_int (abfd, t->tm_hour)
+ || ! ieee_write_int (abfd, t->tm_min)
+ || ! ieee_write_int (abfd, t->tm_sec))
+ return false;
+ }
+
+ output_bfd = abfd;
+
+ flush ();
+
+ if (! ieee_write_section_part (abfd))
+ return false;
+ /* First write the symbols. This changes their values into table
+ indeces so we cant use it after this point. */
+ if (! ieee_write_external_part (abfd))
+ return false;
+
+ /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/
+
+ /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/
+
+
+ /* Write any debugs we have been told about. */
+ if (! ieee_write_debug_part (abfd))
+ return false;
+
+ /* Can only write the data once the symbols have been written, since
+ the data contains relocation information which points to the
+ symbols. */
+ if (! ieee_write_data_part (abfd))
+ return false;
+
+ /* At the end we put the end! */
+ if (! ieee_write_me_part (abfd))
+ return false;
+
+ /* Generate the header */
+ if (bfd_seek (abfd, old, SEEK_SET) != 0)
+ return false;
+
+ for (i = 0; i < N_W_VARIABLES; i++)
+ {
+ if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum)
+ || ! ieee_write_byte (abfd, (bfd_byte) i)
+ || ! ieee_write_int5_out (abfd, ieee->w.offset[i]))
+ return false;
+ }
+
+ return true;
+}
+
+/* Native-level interface to symbols. */
+
+/* We read the symbols into a buffer, which is discarded when this
+ function exits. We read the strings into a buffer large enough to
+ hold them all plus all the cached symbol entries. */
+
+asymbol *
+ieee_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ ieee_symbol_type *new =
+ (ieee_symbol_type *) bfd_zmalloc (sizeof (ieee_symbol_type));
+ if (!new)
+ return NULL;
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
+
+static bfd *
+ieee_openr_next_archived_file (arch, prev)
+ bfd *arch;
+ bfd *prev;
+{
+ ieee_ar_data_type *ar = IEEE_AR_DATA (arch);
+ /* take the next one from the arch state, or reset */
+ if (prev == (bfd *) NULL)
+ {
+ /* Reset the index - the first two entries are bogus*/
+ ar->element_index = 2;
+ }
+ while (true)
+ {
+ ieee_ar_obstack_type *p = ar->elements + ar->element_index;
+ ar->element_index++;
+ if (ar->element_index <= ar->element_count)
+ {
+ if (p->file_offset != (file_ptr) 0)
+ {
+ if (p->abfd == (bfd *) NULL)
+ {
+ p->abfd = _bfd_create_empty_archive_element_shell (arch);
+ p->abfd->origin = p->file_offset;
+ }
+ return p->abfd;
+ }
+ }
+ else
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return (bfd *) NULL;
+ }
+
+ }
+}
+
+static boolean
+ieee_find_nearest_line (abfd,
+ section,
+ symbols,
+ offset,
+ filename_ptr,
+ functionname_ptr,
+ line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ const char **filename_ptr;
+ const char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ return false;
+}
+
+static int
+ieee_generic_stat_arch_elt (abfd, buf)
+ bfd *abfd;
+ struct stat *buf;
+{
+ ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
+ ieee_data_type *ieee;
+
+ if (abfd->my_archive != NULL)
+ ar = abfd->my_archive->tdata.ieee_ar_data;
+ if (ar == (ieee_ar_data_type *) NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ if (IEEE_DATA (abfd) == NULL)
+ {
+ if (ieee_object_p (abfd) == NULL)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+ }
+ }
+
+ ieee = IEEE_DATA (abfd);
+
+ buf->st_size = ieee->w.r.me_record + 1;
+ buf->st_mode = 0644;
+ return 0;
+}
+
+static int
+ieee_sizeof_headers (abfd, x)
+ bfd *abfd;
+ boolean x;
+{
+ return 0;
+}
+
+
+/* The debug info routines are never used. */
+#if 0
+
+static void
+ieee_bfd_debug_info_start (abfd)
+ bfd *abfd;
+{
+
+}
+
+static void
+ieee_bfd_debug_info_end (abfd)
+ bfd *abfd;
+{
+
+}
+
+
+/* Add this section to the list of sections we have debug info for, to
+ be ready to output it at close time
+ */
+static void
+ieee_bfd_debug_info_accumulate (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ ieee_data_type *ieee = IEEE_DATA (section->owner);
+ ieee_data_type *output_ieee = IEEE_DATA (abfd);
+ /* can only accumulate data from other ieee bfds */
+ if (section->owner->xvec != abfd->xvec)
+ return;
+ /* Only bother once per bfd */
+ if (ieee->done_debug == true)
+ return;
+ ieee->done_debug = true;
+
+ /* Don't bother if there is no debug info */
+ if (ieee->w.r.debug_information_part == 0)
+ return;
+
+
+ /* Add to chain */
+ {
+ bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, sizeof (bfd_chain_type));
+ if (!n)
+ abort (); /* FIXME */
+ n->this = section->owner;
+ n->next = (bfd_chain_type *) NULL;
+
+ if (output_ieee->chain_head)
+ {
+ output_ieee->chain_head->next = n;
+ }
+ else
+ {
+ output_ieee->chain_root = n;
+
+ }
+ output_ieee->chain_head = n;
+ }
+}
+
+#endif
+
+#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup
+#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+
+#define ieee_slurp_armap bfd_true
+#define ieee_slurp_extended_name_table bfd_true
+#define ieee_construct_extended_name_table \
+ ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
+ bfd_true)
+#define ieee_truncate_arname bfd_dont_truncate_arname
+#define ieee_write_armap \
+ ((boolean (*) \
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
+ bfd_true)
+#define ieee_read_ar_hdr bfd_nullvoidptr
+#define ieee_update_armap_timestamp bfd_true
+#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
+
+#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define ieee_get_lineno _bfd_nosymbols_get_lineno
+#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define ieee_read_minisymbols _bfd_generic_read_minisymbols
+#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define ieee_set_arch_mach _bfd_generic_set_arch_mach
+
+#define ieee_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+#define ieee_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define ieee_bfd_relax_section bfd_generic_relax_section
+#define ieee_bfd_gc_sections bfd_generic_gc_sections
+#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define ieee_bfd_final_link _bfd_generic_final_link
+#define ieee_bfd_link_split_section _bfd_generic_link_split_section
+
+/*SUPPRESS 460 */
+const bfd_target ieee_vec =
+{
+ "ieee", /* name */
+ bfd_target_ieee_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ '_', /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target,
+ ieee_object_p, /* bfd_check_format */
+ ieee_archive_p,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ ieee_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+ {
+ bfd_false,
+ ieee_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (ieee),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (ieee),
+ BFD_JUMP_TABLE_SYMBOLS (ieee),
+ BFD_JUMP_TABLE_RELOCS (ieee),
+ BFD_JUMP_TABLE_WRITE (ieee),
+ BFD_JUMP_TABLE_LINK (ieee),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/ihex.c b/bfd/ihex.c
new file mode 100644
index 00000000000..b9953d329f5
--- /dev/null
+++ b/bfd/ihex.c
@@ -0,0 +1,1041 @@
+/* BFD back-end for Intel Hex objects.
+ Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor of Cygnus Support <ian@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This is what Intel Hex files look like:
+
+1. INTEL FORMATS
+
+A. Intel 1
+
+ 16-bit address-field format, for files 64k bytes in length or less.
+
+ DATA RECORD
+ Byte 1 Header = colon(:)
+ 2..3 The number of data bytes in hex notation
+ 4..5 High byte of the record load address
+ 6..7 Low byte of the record load address
+ 8..9 Record type, must be "00"
+ 10..x Data bytes in hex notation:
+ x = (number of bytes - 1) * 2 + 11
+ x+1..x+2 Checksum in hex notation
+ x+3..x+4 Carriage return, line feed
+
+ END RECORD
+ Byte 1 Header = colon (:)
+ 2..3 The byte count, must be "00"
+ 4..7 Transfer-address (usually "0000")
+ the jump-to address, execution start address
+ 8..9 Record type, must be "01"
+ 10..11 Checksum, in hex notation
+ 12..13 Carriage return, line feed
+
+B. INTEL 2
+
+ MCS-86 format, using a 20-bit address for files larger than 64K bytes.
+
+ DATA RECORD
+ Byte 1 Header = colon (:)
+ 2..3 The byte count of this record, hex notation
+ 4..5 High byte of the record load address
+ 6..7 Low byte of the record load address
+ 8..9 Record type, must be "00"
+ 10..x The data bytes in hex notation:
+ x = (number of data bytes - 1) * 2 + 11
+ x+1..x+2 Checksum in hex notation
+ x+3..x+4 Carriage return, line feed
+
+ EXTENDED ADDRESS RECORD
+ Byte 1 Header = colon(:)
+ 2..3 The byte count, must be "02"
+ 4..7 Load address, must be "0000"
+ 8..9 Record type, must be "02"
+ 10..11 High byte of the offset address
+ 12..13 Low byte of the offset address
+ 14..15 Checksum in hex notation
+ 16..17 Carriage return, line feed
+
+ The checksums are the two's complement of the 8-bit sum
+ without carry of the byte count, offset address, and the
+ record type.
+
+ START ADDRESS RECORD
+ Byte 1 Header = colon (:)
+ 2..3 The byte count, must be "04"
+ 4..7 Load address, must be "0000"
+ 8..9 Record type, must be "03"
+ 10..13 8086 CS value
+ 14..17 8086 IP value
+ 18..19 Checksum in hex notation
+ 20..21 Carriage return, line feed
+
+Another document reports these additional types:
+
+ EXTENDED LINEAR ADDRESS RECORD
+ Byte 1 Header = colon (:)
+ 2..3 The byte count, must be "02"
+ 4..7 Load address, must be "0000"
+ 8..9 Record type, must be "04"
+ 10..13 Upper 16 bits of address of subsequent records
+ 14..15 Checksum in hex notation
+ 16..17 Carriage return, line feed
+
+ START LINEAR ADDRESS RECORD
+ Byte 1 Header = colon (:)
+ 2..3 The byte count, must be "02"
+ 4..7 Load address, must be "0000"
+ 8..9 Record type, must be "05"
+ 10..13 Upper 16 bits of start address
+ 14..15 Checksum in hex notation
+ 16..17 Carriage return, line feed
+
+The MRI compiler uses this, which is a repeat of type 5:
+
+ EXTENDED START RECORD
+ Byte 1 Header = colon (:)
+ 2..3 The byte count, must be "04"
+ 4..7 Load address, must be "0000"
+ 8..9 Record type, must be "05"
+ 10..13 Upper 16 bits of start address
+ 14..17 Lower 16 bits of start address
+ 18..19 Checksum in hex notation
+ 20..21 Carriage return, line feed
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+#include <ctype.h>
+
+static void ihex_init PARAMS ((void));
+static boolean ihex_mkobject PARAMS ((bfd *));
+static INLINE int ihex_get_byte PARAMS ((bfd *, boolean *));
+static void ihex_bad_byte PARAMS ((bfd *, unsigned int, int, boolean));
+static boolean ihex_scan PARAMS ((bfd *));
+static const bfd_target *ihex_object_p PARAMS ((bfd *));
+static boolean ihex_read_section PARAMS ((bfd *, asection *, bfd_byte *));
+static boolean ihex_get_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static boolean ihex_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static boolean ihex_write_record
+ PARAMS ((bfd *, bfd_size_type, bfd_vma, unsigned int, bfd_byte *));
+static boolean ihex_write_object_contents PARAMS ((bfd *));
+static asymbol *ihex_make_empty_symbol PARAMS ((bfd *));
+static boolean ihex_set_arch_mach
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+static int ihex_sizeof_headers PARAMS ((bfd *, boolean));
+
+/* The number of bytes we put on one line during output. */
+
+#define CHUNK (21)
+
+/* Macros for converting between hex and binary. */
+
+#define NIBBLE(x) (hex_value (x))
+#define HEX2(buffer) ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
+#define HEX4(buffer) ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
+#define ISHEX(x) (hex_p (x))
+
+/* When we write out an ihex value, the values can not be output as
+ they are seen. Instead, we hold them in memory in this structure. */
+
+struct ihex_data_list
+{
+ struct ihex_data_list *next;
+ bfd_byte *data;
+ bfd_vma where;
+ bfd_size_type size;
+};
+
+/* The ihex tdata information. */
+
+struct ihex_data_struct
+{
+ struct ihex_data_list *head;
+ struct ihex_data_list *tail;
+};
+
+/* Initialize by filling in the hex conversion array. */
+
+static void
+ihex_init ()
+{
+ static boolean inited;
+
+ if (! inited)
+ {
+ inited = true;
+ hex_init ();
+ }
+}
+
+/* Create an ihex object. */
+
+static boolean
+ihex_mkobject (abfd)
+ bfd *abfd;
+{
+ if (abfd->tdata.ihex_data == NULL)
+ {
+ struct ihex_data_struct *tdata;
+
+ tdata = ((struct ihex_data_struct *)
+ bfd_alloc (abfd, sizeof (struct ihex_data_struct)));
+ if (tdata == NULL)
+ return false;
+ abfd->tdata.ihex_data = tdata;
+ tdata->head = NULL;
+ tdata->tail = NULL;
+ }
+
+ return true;
+}
+
+/* Read a byte from a BFD. Set *ERRORPTR if an error occurred.
+ Return EOF on error or end of file. */
+
+static INLINE int
+ihex_get_byte (abfd, errorptr)
+ bfd *abfd;
+ boolean *errorptr;
+{
+ bfd_byte c;
+
+ if (bfd_read (&c, 1, 1, abfd) != 1)
+ {
+ if (bfd_get_error () != bfd_error_file_truncated)
+ *errorptr = true;
+ return EOF;
+ }
+
+ return (int) (c & 0xff);
+}
+
+/* Report a problem in an Intel Hex file. */
+
+static void
+ihex_bad_byte (abfd, lineno, c, error)
+ bfd *abfd;
+ unsigned int lineno;
+ int c;
+ boolean error;
+{
+ if (c == EOF)
+ {
+ if (! error)
+ bfd_set_error (bfd_error_file_truncated);
+ }
+ else
+ {
+ char buf[10];
+
+ if (! isprint (c))
+ sprintf (buf, "\\%03o", (unsigned int) c);
+ else
+ {
+ buf[0] = c;
+ buf[1] = '\0';
+ }
+ (*_bfd_error_handler)
+ (_("%s:%d: unexpected character `%s' in Intel Hex file\n"),
+ bfd_get_filename (abfd), lineno, buf);
+ bfd_set_error (bfd_error_bad_value);
+ }
+}
+
+/* Read an Intel hex file and turn it into sections. We create a new
+ section for each contiguous set of bytes. */
+
+static boolean
+ihex_scan (abfd)
+ bfd *abfd;
+{
+ bfd_vma segbase;
+ bfd_vma extbase;
+ asection *sec;
+ int lineno;
+ boolean error;
+ bfd_byte *buf = NULL;
+ size_t bufsize;
+ int c;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto error_return;
+
+ abfd->start_address = 0;
+
+ segbase = 0;
+ extbase = 0;
+ sec = NULL;
+ lineno = 1;
+ error = false;
+ bufsize = 0;
+ while ((c = ihex_get_byte (abfd, &error)) != EOF)
+ {
+ if (c == '\r')
+ continue;
+ else if (c == '\n')
+ {
+ ++lineno;
+ continue;
+ }
+ else if (c != ':')
+ {
+ ihex_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+ else
+ {
+ file_ptr pos;
+ char hdr[8];
+ unsigned int i;
+ unsigned int len;
+ bfd_vma addr;
+ unsigned int type;
+ unsigned int chars;
+ unsigned int chksum;
+
+ /* This is a data record. */
+
+ pos = bfd_tell (abfd) - 1;
+
+ /* Read the header bytes. */
+
+ if (bfd_read (hdr, 1, 8, abfd) != 8)
+ goto error_return;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (! ISHEX (hdr[i]))
+ {
+ ihex_bad_byte (abfd, lineno, hdr[i], error);
+ goto error_return;
+ }
+ }
+
+ len = HEX2 (hdr);
+ addr = HEX4 (hdr + 2);
+ type = HEX2 (hdr + 6);
+
+ /* Read the data bytes. */
+
+ chars = len * 2 + 2;
+ if (chars >= bufsize)
+ {
+ buf = (bfd_byte *) bfd_realloc (buf, chars);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = chars;
+ }
+
+ if (bfd_read (buf, 1, chars, abfd) != chars)
+ goto error_return;
+
+ for (i = 0; i < chars; i++)
+ {
+ if (! ISHEX (buf[i]))
+ {
+ ihex_bad_byte (abfd, lineno, hdr[i], error);
+ goto error_return;
+ }
+ }
+
+ /* Check the checksum. */
+ chksum = len + addr + (addr >> 8) + type;
+ for (i = 0; i < len; i++)
+ chksum += HEX2 (buf + 2 * i);
+ if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
+ {
+ (*_bfd_error_handler)
+ (_("%s:%d: bad checksum in Intel Hex file (expected %u, found %u)"),
+ bfd_get_filename (abfd), lineno,
+ (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ switch (type)
+ {
+ case 0:
+ /* This is a data record. */
+ if (sec != NULL
+ && sec->vma + sec->_raw_size == extbase + segbase + addr)
+ {
+ /* This data goes at the end of the section we are
+ currently building. */
+ sec->_raw_size += len;
+ }
+ else if (len > 0)
+ {
+ char secbuf[20];
+ char *secname;
+
+ sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
+ secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1);
+ if (secname == NULL)
+ goto error_return;
+ strcpy (secname, secbuf);
+ sec = bfd_make_section (abfd, secname);
+ if (sec == NULL)
+ goto error_return;
+ sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ sec->vma = extbase + segbase + addr;
+ sec->lma = extbase + segbase + addr;
+ sec->_raw_size = len;
+ sec->filepos = pos;
+ }
+ break;
+
+ case 1:
+ /* An end record. */
+ if (abfd->start_address == 0)
+ abfd->start_address = addr;
+ if (buf != NULL)
+ free (buf);
+ return true;
+
+ case 2:
+ /* An extended address record. */
+ if (len != 2)
+ {
+ (*_bfd_error_handler)
+ (_("%s:%d: bad extended address record length in Intel Hex file"),
+ bfd_get_filename (abfd), lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ segbase = HEX4 (buf) << 4;
+
+ sec = NULL;
+
+ break;
+
+ case 3:
+ /* An extended start address record. */
+ if (len != 4)
+ {
+ (*_bfd_error_handler)
+ (_("%s:%d: bad extended start address length in Intel Hex file"),
+ bfd_get_filename (abfd), lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);
+
+ sec = NULL;
+
+ break;
+
+ case 4:
+ /* An extended linear address record. */
+ if (len != 2)
+ {
+ (*_bfd_error_handler)
+ (_("%s:%d: bad extended linear address record length in Intel Hex file"),
+ bfd_get_filename (abfd), lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ extbase = HEX4 (buf) << 16;
+
+ sec = NULL;
+
+ break;
+
+ case 5:
+ /* An extended linear start address record. */
+ if (len != 2 && len != 4)
+ {
+ (*_bfd_error_handler)
+ (_("%s:%d: bad extended linear start address length in Intel Hex file"),
+ bfd_get_filename (abfd), lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (len == 2)
+ abfd->start_address += HEX4 (buf) << 16;
+ else
+ abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);
+
+ sec = NULL;
+
+ break;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%s:%d: unrecognized ihex type %u in Intel Hex file\n"),
+ bfd_get_filename (abfd), lineno, type);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ }
+ }
+
+ if (error)
+ goto error_return;
+
+ if (buf != NULL)
+ free (buf);
+
+ return true;
+
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ return false;
+}
+
+/* Try to recognize an Intel Hex file. */
+
+static const bfd_target *
+ihex_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_byte b[9];
+ unsigned int i;
+ unsigned int type;
+
+ ihex_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return NULL;
+ if (bfd_read (b, 1, 9, abfd) != 9)
+ {
+ if (bfd_get_error () == bfd_error_file_truncated)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (b[0] != ':')
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ for (i = 1; i < 9; i++)
+ {
+ if (! ISHEX (b[i]))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ }
+
+ type = HEX2 (b + 7);
+ if (type > 5)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* OK, it looks like it really is an Intel Hex file. */
+
+ if (! ihex_mkobject (abfd)
+ || ! ihex_scan (abfd))
+ return NULL;
+
+ return abfd->xvec;
+}
+
+/* Read the contents of a section in an Intel Hex file. */
+
+static boolean
+ihex_read_section (abfd, section, contents)
+ bfd *abfd;
+ asection *section;
+ bfd_byte *contents;
+{
+ int c;
+ bfd_byte *p;
+ bfd_byte *buf = NULL;
+ size_t bufsize;
+ boolean error;
+
+ if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ p = contents;
+ bufsize = 0;
+ error = false;
+ while ((c = ihex_get_byte (abfd, &error)) != EOF)
+ {
+ char hdr[8];
+ unsigned int len;
+ bfd_vma addr;
+ unsigned int type;
+ unsigned int i;
+
+ if (c == '\r' || c == '\n')
+ continue;
+
+ /* This is called after ihex_scan has succeeded, so we ought to
+ know the exact format. */
+ BFD_ASSERT (c == ':');
+
+ if (bfd_read (hdr, 1, 8, abfd) != 8)
+ goto error_return;
+
+ len = HEX2 (hdr);
+ addr = HEX4 (hdr + 2);
+ type = HEX2 (hdr + 6);
+
+ /* We should only see type 0 records here. */
+ if (type != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: internal error in ihex_read_section"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (len * 2 > bufsize)
+ {
+ buf = (bfd_byte *) bfd_realloc (buf, len * 2);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = len * 2;
+ }
+
+ if (bfd_read (buf, 1, len * 2, abfd) != len * 2)
+ goto error_return;
+
+ for (i = 0; i < len; i++)
+ *p++ = HEX2 (buf + 2 * i);
+ if ((bfd_size_type) (p - contents) >= section->_raw_size)
+ {
+ /* We've read everything in the section. */
+ if (buf != NULL)
+ free (buf);
+ return true;
+ }
+
+ /* Skip the checksum. */
+ if (bfd_read (buf, 1, 2, abfd) != 2)
+ goto error_return;
+ }
+
+ if ((bfd_size_type) (p - contents) < section->_raw_size)
+ {
+ (*_bfd_error_handler)
+ (_("%s: bad section length in ihex_read_section"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (buf != NULL)
+ free (buf);
+
+ return true;
+
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ return false;
+}
+
+/* Get the contents of a section in an Intel Hex file. */
+
+static boolean
+ihex_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (section->used_by_bfd == NULL)
+ {
+ section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);
+ if (section->used_by_bfd == NULL)
+ return false;
+ if (! ihex_read_section (abfd, section, section->used_by_bfd))
+ return false;
+ }
+
+ memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
+ (size_t) count);
+
+ return true;
+}
+
+/* Set the contents of a section in an Intel Hex file. */
+
+static boolean
+ihex_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ struct ihex_data_list *n;
+ bfd_byte *data;
+ struct ihex_data_struct *tdata;
+
+ if (count == 0
+ || (section->flags & SEC_ALLOC) == 0
+ || (section->flags & SEC_LOAD) == 0)
+ return true;
+
+ n = ((struct ihex_data_list *)
+ bfd_alloc (abfd, sizeof (struct ihex_data_list)));
+ if (n == NULL)
+ return false;
+
+ data = (bfd_byte *) bfd_alloc (abfd, count);
+ if (data == NULL)
+ return false;
+ memcpy (data, location, (size_t) count);
+
+ n->data = data;
+ n->where = section->lma + offset;
+ n->size = count;
+
+ /* Sort the records by address. Optimize for the common case of
+ adding a record to the end of the list. */
+ tdata = abfd->tdata.ihex_data;
+ if (tdata->tail != NULL
+ && n->where >= tdata->tail->where)
+ {
+ tdata->tail->next = n;
+ n->next = NULL;
+ tdata->tail = n;
+ }
+ else
+ {
+ register struct ihex_data_list **pp;
+
+ for (pp = &tdata->head;
+ *pp != NULL && (*pp)->where < n->where;
+ pp = &(*pp)->next)
+ ;
+ n->next = *pp;
+ *pp = n;
+ if (n->next == NULL)
+ tdata->tail = n;
+ }
+
+ return true;
+}
+
+/* Write a record out to an Intel Hex file. */
+
+static boolean
+ihex_write_record (abfd, count, addr, type, data)
+ bfd *abfd;
+ bfd_size_type count;
+ bfd_vma addr;
+ unsigned int type;
+ bfd_byte *data;
+{
+ static const char digs[] = "0123456789ABCDEF";
+ char buf[9 + CHUNK * 2 + 4];
+ char *p;
+ unsigned int chksum;
+ unsigned int i;
+
+#define TOHEX(buf, v) \
+ ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
+
+ buf[0] = ':';
+ TOHEX (buf + 1, count);
+ TOHEX (buf + 3, (addr >> 8) & 0xff);
+ TOHEX (buf + 5, addr & 0xff);
+ TOHEX (buf + 7, type);
+
+ chksum = count + addr + (addr >> 8) + type;
+
+ for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
+ {
+ TOHEX (p, *data);
+ chksum += *data;
+ }
+
+ TOHEX (p, (- chksum) & 0xff);
+ p[2] = '\r';
+ p[3] = '\n';
+
+ if (bfd_write (buf, 1, 9 + count * 2 + 4, abfd) != 9 + count * 2 + 4)
+ return false;
+
+ return true;
+}
+
+/* Write out an Intel Hex file. */
+
+static boolean
+ihex_write_object_contents (abfd)
+ bfd *abfd;
+{
+ bfd_vma segbase;
+ bfd_vma extbase;
+ struct ihex_data_list *l;
+
+ segbase = 0;
+ extbase = 0;
+ for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
+ {
+ bfd_vma where;
+ bfd_byte *p;
+ bfd_size_type count;
+
+ where = l->where;
+ p = l->data;
+ count = l->size;
+ while (count > 0)
+ {
+ bfd_size_type now;
+
+ now = count;
+ if (now > CHUNK)
+ now = CHUNK;
+
+ if (where > segbase + extbase + 0xffff)
+ {
+ bfd_byte addr[2];
+
+ /* We need a new base address. */
+ if (where <= 0xfffff)
+ {
+ /* The addresses should be sorted. */
+ BFD_ASSERT (extbase == 0);
+
+ segbase = where & 0xf0000;
+ addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
+ addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
+ if (! ihex_write_record (abfd, 2, 0, 2, addr))
+ return false;
+ }
+ else
+ {
+ /* The extended address record and the extended
+ linear address record are combined, at least by
+ some readers. We need an extended linear address
+ record here, so if we've already written out an
+ extended address record, zero it out to avoid
+ confusion. */
+ if (segbase != 0)
+ {
+ addr[0] = 0;
+ addr[1] = 0;
+ if (! ihex_write_record (abfd, 2, 0, 2, addr))
+ return false;
+ segbase = 0;
+ }
+
+ extbase = where & 0xffff0000;
+ if (where > extbase + 0xffff)
+ {
+ char buf[20];
+
+ sprintf_vma (buf, where);
+ (*_bfd_error_handler)
+ (_("%s: address 0x%s out of range for Intex Hex file"),
+ bfd_get_filename (abfd), buf);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
+ addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
+ if (! ihex_write_record (abfd, 2, 0, 4, addr))
+ return false;
+ }
+ }
+
+ if (! ihex_write_record (abfd, now, where - (extbase + segbase),
+ 0, p))
+ return false;
+
+ where += now;
+ p += now;
+ count -= now;
+ }
+ }
+
+ if (abfd->start_address != 0)
+ {
+ bfd_vma start;
+ bfd_byte startbuf[4];
+
+ start = abfd->start_address;
+
+ if (start <= 0xfffff)
+ {
+ startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
+ startbuf[1] = 0;
+ startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
+ startbuf[3] = (bfd_byte)start & 0xff;
+ if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
+ return false;
+ }
+ else
+ {
+ startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
+ startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
+ startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
+ startbuf[3] = (bfd_byte)start & 0xff;
+ if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
+ return false;
+ }
+ }
+
+ if (! ihex_write_record (abfd, 0, 0, 1, NULL))
+ return false;
+
+ return true;
+}
+
+/* Make an empty symbol. This is required only because
+ bfd_make_section_anyway wants to create a symbol for the section. */
+
+static asymbol *
+ihex_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new;
+
+ new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new != NULL)
+ new->the_bfd = abfd;
+ return new;
+}
+
+/* Set the architecture for the output file. The architecture is
+ irrelevant, so we ignore errors about unknown architectures. */
+
+static boolean
+ihex_set_arch_mach (abfd, arch, mach)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long mach;
+{
+ if (! bfd_default_set_arch_mach (abfd, arch, mach))
+ {
+ if (arch != bfd_arch_unknown)
+ return false;
+ }
+ return true;
+}
+
+/* Get the size of the headers, for the linker. */
+
+/*ARGSUSED*/
+static int
+ihex_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return 0;
+}
+
+/* Some random definitions for the target vector. */
+
+#define ihex_close_and_cleanup _bfd_generic_close_and_cleanup
+#define ihex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define ihex_new_section_hook _bfd_generic_new_section_hook
+#define ihex_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#define ihex_get_symtab_upper_bound bfd_0l
+#define ihex_get_symtab \
+ ((long (*) PARAMS ((bfd *, asymbol **))) bfd_0l)
+#define ihex_print_symbol _bfd_nosymbols_print_symbol
+#define ihex_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define ihex_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
+#define ihex_get_lineno _bfd_nosymbols_get_lineno
+#define ihex_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define ihex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define ihex_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define ihex_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+#define ihex_get_reloc_upper_bound \
+ ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
+#define ihex_canonicalize_reloc \
+ ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
+#define ihex_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define ihex_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define ihex_bfd_relax_section bfd_generic_relax_section
+#define ihex_bfd_gc_sections bfd_generic_gc_sections
+#define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define ihex_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define ihex_bfd_final_link _bfd_generic_final_link
+#define ihex_bfd_link_split_section _bfd_generic_link_split_section
+
+/* The Intel Hex target vector. */
+
+const bfd_target ihex_vec =
+{
+ "ihex", /* name */
+ bfd_target_ihex_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ 0, /* object flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {
+ _bfd_dummy_target,
+ ihex_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ ihex_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ ihex_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (ihex),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (ihex),
+ BFD_JUMP_TABLE_RELOCS (ihex),
+ BFD_JUMP_TABLE_WRITE (ihex),
+ BFD_JUMP_TABLE_LINK (ihex),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/init.c b/bfd/init.c
new file mode 100644
index 00000000000..1fa1d505bee
--- /dev/null
+++ b/bfd/init.c
@@ -0,0 +1,50 @@
+/* bfd initialization stuff
+ Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/*
+SECTION
+ Initialization
+
+ These are the functions that handle initializing a BFD.
+*/
+
+/*
+FUNCTION
+ bfd_init
+
+SYNOPSIS
+ void bfd_init(void);
+
+DESCRIPTION
+ This routine must be called before any other BFD function to
+ initialize magical internal data structures.
+*/
+
+/* Actually, there is currently nothing for this function to do.
+ However, someday it may be needed, so keep it around. */
+
+void
+bfd_init ()
+{
+}
diff --git a/bfd/irix-core.c b/bfd/irix-core.c
new file mode 100644
index 00000000000..964ca20eac5
--- /dev/null
+++ b/bfd/irix-core.c
@@ -0,0 +1,276 @@
+/* BFD back-end for Irix core files.
+ Copyright 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Stu Grossman, Cygnus Support.
+ Converted to back-end form by Ian Lance Taylor, Cygnus Support
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file can only be compiled on systems which use Irix style core
+ files (namely, Irix 4 and Irix 5, so far). */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifdef IRIX_CORE
+
+#include <core.out.h>
+
+struct sgi_core_struct
+{
+ int sig;
+ char cmd[CORE_NAMESIZE];
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+
+static asection *make_bfd_asection
+ PARAMS ((bfd *, CONST char *, flagword, bfd_size_type, bfd_vma, file_ptr));
+static const bfd_target *irix_core_core_file_p PARAMS ((bfd *));
+static char *irix_core_core_file_failing_command PARAMS ((bfd *));
+static int irix_core_core_file_failing_signal PARAMS ((bfd *));
+static boolean irix_core_core_file_matches_executable_p
+ PARAMS ((bfd *, bfd *));
+static asymbol *irix_core_make_empty_symbol PARAMS ((bfd *));
+static void swap_abort PARAMS ((void));
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+ bfd *abfd;
+ CONST char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ bfd_vma vma;
+ file_ptr filepos;
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway (abfd, name);
+ if (!asect)
+ return NULL;
+
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 4;
+
+ return asect;
+}
+
+static const bfd_target *
+irix_core_core_file_p (abfd)
+ bfd *abfd;
+{
+ int val;
+ int i;
+ char *secname;
+ struct coreout coreout;
+ struct idesc *idg, *idf, *ids;
+
+ val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
+ if (val != sizeof coreout)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+#ifndef CORE_MAGICN32
+#define CORE_MAGICN32 CORE_MAGIC
+#endif
+ if ((coreout.c_magic != CORE_MAGIC && coreout.c_magic != CORE_MAGICN32)
+ || coreout.c_version != CORE_VERSION1)
+ return 0;
+
+ core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
+ if (!core_hdr (abfd))
+ return NULL;
+
+ strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
+ core_signal (abfd) = coreout.c_sigcause;
+
+ if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0)
+ return NULL;
+
+ for (i = 0; i < coreout.c_nvmap; i++)
+ {
+ struct vmap vmap;
+
+ val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
+ if (val != sizeof vmap)
+ break;
+
+ switch (vmap.v_type)
+ {
+ case VDATA:
+ secname = ".data";
+ break;
+ case VSTACK:
+ secname = ".stack";
+ break;
+#ifdef VMAPFILE
+ case VMAPFILE:
+ secname = ".mapfile";
+ break;
+#endif
+ default:
+ continue;
+ }
+
+ /* A file offset of zero means that the section is not contained
+ in the corefile. */
+ if (vmap.v_offset == 0)
+ continue;
+
+ if (!make_bfd_asection (abfd, secname,
+ SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
+ vmap.v_len,
+ vmap.v_vaddr,
+ vmap.v_offset))
+ return NULL;
+ }
+
+ /* Make sure that the regs are contiguous within the core file. */
+
+ idg = &coreout.c_idesc[I_GPREGS];
+ idf = &coreout.c_idesc[I_FPREGS];
+ ids = &coreout.c_idesc[I_SPECREGS];
+
+ if (idg->i_offset + idg->i_len != idf->i_offset
+ || idf->i_offset + idf->i_len != ids->i_offset)
+ return 0; /* Can't deal with non-contig regs */
+
+ if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0)
+ return NULL;
+
+ make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ idg->i_len + idf->i_len + ids->i_len,
+ 0,
+ idg->i_offset);
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ return abfd->xvec;
+}
+
+static char *
+irix_core_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_command (abfd);
+}
+
+static int
+irix_core_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_signal (abfd);
+}
+
+static boolean
+irix_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* XXX - FIXME */
+}
+
+static asymbol *
+irix_core_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+#define irix_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
+#define irix_core_get_symtab _bfd_nosymbols_get_symtab
+#define irix_core_print_symbol _bfd_nosymbols_print_symbol
+#define irix_core_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define irix_core_bfd_is_local_label_name \
+ _bfd_nosymbols_bfd_is_local_label_name
+#define irix_core_get_lineno _bfd_nosymbols_get_lineno
+#define irix_core_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define irix_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define irix_core_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define irix_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target irix_core_vec =
+ {
+ "irix-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ irix_core_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (irix_core),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (irix_core),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
+
+#endif /* IRIX_CORE */
diff --git a/bfd/libaout.h b/bfd/libaout.h
new file mode 100644
index 00000000000..7001d3dc6d4
--- /dev/null
+++ b/bfd/libaout.h
@@ -0,0 +1,624 @@
+/* BFD back-end data structures for a.out (and similar) files.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef LIBAOUT_H
+#define LIBAOUT_H
+
+/* We try to encapsulate the differences in the various a.out file
+ variants in a few routines, and otherwise share large masses of code.
+ This means we only have to fix bugs in one place, most of the time. */
+
+#include "bfdlink.h"
+
+/* Parameterize the a.out code based on whether it is being built
+ for a 32-bit architecture or a 64-bit architecture. */
+#if ARCH_SIZE==64
+#define GET_WORD bfd_h_get_64
+#define GET_SWORD bfd_h_get_signed_64
+#define PUT_WORD bfd_h_put_64
+#ifndef NAME
+#define NAME(x,y) CAT3(x,_64_,y)
+#endif
+#define JNAME(x) CAT(x,_64)
+#define BYTES_IN_WORD 8
+#else /* ARCH_SIZE == 32 */
+#define GET_WORD bfd_h_get_32
+#define GET_SWORD bfd_h_get_signed_32
+#define PUT_WORD bfd_h_put_32
+#ifndef NAME
+#define NAME(x,y) CAT3(x,_32_,y)
+#endif
+#define JNAME(x) CAT(x,_32)
+#define BYTES_IN_WORD 4
+#endif /* ARCH_SIZE==32 */
+
+/* Declare at file level, since used in parameter lists, which have
+ weird scope. */
+struct external_exec;
+struct external_nlist;
+struct reloc_ext_external;
+struct reloc_std_external;
+
+/* a.out backend linker hash table entries. */
+
+struct aout_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+ /* Whether this symbol has been written out. */
+ boolean written;
+ /* Symbol index in output file. */
+ int indx;
+};
+
+/* a.out backend linker hash table. */
+
+struct aout_link_hash_table
+{
+ struct bfd_link_hash_table root;
+};
+
+/* Look up an entry in an a.out link hash table. */
+
+#define aout_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct aout_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
+
+/* Traverse an a.out link hash table. */
+
+#define aout_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the a.out link hash table from the info structure. This is
+ just a cast. */
+
+#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
+
+/* Back-end information for various a.out targets. */
+struct aout_backend_data
+{
+ /* Are ZMAGIC files mapped contiguously? If so, the text section may
+ need more padding, if the segment size (granularity for memory access
+ control) is larger than the page size. */
+ unsigned char zmagic_mapped_contiguous;
+ /* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the
+ text section, which starts immediately after the file header.
+ If not, the text section starts on the next page. */
+ unsigned char text_includes_header;
+
+ /* If this flag is set, then if the entry address is not in the
+ first SEGMENT_SIZE bytes of the text section, it is taken to be
+ the address of the start of the text section. This can be useful
+ for kernels. */
+ unsigned char entry_is_text_address;
+
+ /* The value to pass to N_SET_FLAGS. */
+ unsigned char exec_hdr_flags;
+
+ /* If the text section VMA isn't specified, and we need an absolute
+ address, use this as the default. If we're producing a relocatable
+ file, zero is always used. */
+ /* ?? Perhaps a callback would be a better choice? Will this do anything
+ reasonable for a format that handles multiple CPUs with different
+ load addresses for each? */
+ bfd_vma default_text_vma;
+
+ /* Callback for setting the page and segment sizes, if they can't be
+ trivially determined from the architecture. */
+ boolean (*set_sizes) PARAMS ((bfd *));
+
+ /* zmagic files only. For go32, the length of the exec header contributes
+ to the size of the text section in the file for alignment purposes but
+ does *not* get counted in the length of the text section. */
+ unsigned char exec_header_not_counted;
+
+ /* Callback from the add symbols phase of the linker code to handle
+ a dynamic object. */
+ boolean (*add_dynamic_symbols) PARAMS ((bfd *, struct bfd_link_info *,
+ struct external_nlist **,
+ bfd_size_type *, char **));
+
+ /* Callback from the add symbols phase of the linker code to handle
+ adding a single symbol to the global linker hash table. */
+ boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
+ const char *, flagword, asection *,
+ bfd_vma, const char *, boolean,
+ boolean,
+ struct bfd_link_hash_entry **));
+
+ /* Called to handle linking a dynamic object. */
+ boolean (*link_dynamic_object) PARAMS ((struct bfd_link_info *, bfd *));
+
+ /* Called for each global symbol being written out by the linker.
+ This should write out the dynamic symbol information. */
+ boolean (*write_dynamic_symbol) PARAMS ((bfd *, struct bfd_link_info *,
+ struct aout_link_hash_entry *));
+
+ /* If this callback is not NULL, the linker calls it for each reloc.
+ RELOC is a pointer to the unswapped reloc. If *SKIP is set to
+ true, the reloc will be skipped. *RELOCATION may be changed to
+ change the effects of the relocation. */
+ boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ struct aout_link_hash_entry *h,
+ PTR reloc, bfd_byte *contents,
+ boolean *skip,
+ bfd_vma *relocation));
+
+ /* Called at the end of a link to finish up any dynamic linking
+ information. */
+ boolean (*finish_dynamic_link) PARAMS ((bfd *, struct bfd_link_info *));
+};
+#define aout_backend_info(abfd) \
+ ((CONST struct aout_backend_data *)((abfd)->xvec->backend_data))
+
+/* This is the layout in memory of a "struct exec" while we process it.
+ All 'lengths' are given as a number of bytes.
+ All 'alignments' are for relinkable files only; an alignment of
+ 'n' indicates the corresponding segment must begin at an
+ address that is a multiple of (2**n). */
+
+struct internal_exec
+{
+ long a_info; /* Magic number and flags, packed */
+ bfd_vma a_text; /* length of text, in bytes */
+ bfd_vma a_data; /* length of data, in bytes */
+ bfd_vma a_bss; /* length of uninitialized data area in mem */
+ bfd_vma a_syms; /* length of symbol table data in file */
+ bfd_vma a_entry; /* start address */
+ bfd_vma a_trsize; /* length of text's relocation info, in bytes */
+ bfd_vma a_drsize; /* length of data's relocation info, in bytes */
+ /* Added for i960 */
+ bfd_vma a_tload; /* Text runtime load address */
+ bfd_vma a_dload; /* Data runtime load address */
+ unsigned char a_talign; /* Alignment of text segment */
+ unsigned char a_dalign; /* Alignment of data segment */
+ unsigned char a_balign; /* Alignment of bss segment */
+ char a_relaxable; /* Enough info for linker relax */
+};
+
+/* Magic number is written
+< MSB >
+3130292827262524232221201918171615141312111009080706050403020100
+< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
+*/
+/* Magic number for NetBSD is
+<MSB >
+3130292827262524232221201918171615141312111009080706050403020100
+< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
+*/
+
+enum machine_type {
+ M_UNKNOWN = 0,
+ M_68010 = 1,
+ M_68020 = 2,
+ M_SPARC = 3,
+ /* skip a bunch so we don't run into any of suns numbers */
+ /* make these up for the ns32k*/
+ M_NS32032 = (64), /* ns32032 running ? */
+ M_NS32532 = (64 + 5), /* ns32532 running mach */
+
+ M_386 = 100,
+ M_29K = 101, /* AMD 29000 */
+ M_386_DYNIX = 102, /* Sequent running dynix */
+ M_ARM = 103, /* Advanced Risc Machines ARM */
+ M_SPARCLET = 131, /* SPARClet = M_SPARC + 128 */
+ M_386_NETBSD = 134, /* NetBSD/i386 binary */
+ M_68K_NETBSD = 135, /* NetBSD/m68k binary */
+ M_68K4K_NETBSD = 136, /* NetBSD/m68k4k binary */
+ M_532_NETBSD = 137, /* NetBSD/ns32k binary */
+ M_SPARC_NETBSD = 138, /* NetBSD/sparc binary */
+ M_PMAX_NETBSD = 139, /* NetBSD/pmax (MIPS little-endian) binary */
+ M_VAX_NETBSD = 140, /* NetBSD/vax binary */
+ M_ALPHA_NETBSD = 141, /* NetBSD/alpha binary */
+ M_ARM6_NETBSD = 143, /* NetBSD/arm32 binary */
+ M_SPARCLET_1 = 147, /* 0x93, reserved */
+ M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
+ M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
+ M_SPARCLET_2 = 163, /* 0xa3, reserved */
+ M_SPARCLET_3 = 179, /* 0xb3, reserved */
+ M_SPARCLET_4 = 195, /* 0xc3, reserved */
+ M_HP200 = 200, /* HP 200 (68010) BSD binary */
+ M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */
+ M_HPUX = (0x20c % 256), /* HP 200/300 HPUX binary */
+ M_SPARCLET_5 = 211, /* 0xd3, reserved */
+ M_SPARCLET_6 = 227, /* 0xe3, reserved */
+ /* M_SPARCLET_7 = 243 / * 0xf3, reserved */
+ M_SPARCLITE_LE = 243
+};
+
+#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000)
+
+#ifndef N_MAGIC
+# define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#endif
+
+#ifndef N_MACHTYPE
+# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#endif
+
+#ifndef N_FLAGS
+# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#endif
+
+#ifndef N_SET_INFO
+# define N_SET_INFO(exec, magic, type, flags) \
+((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#endif
+
+#ifndef N_SET_DYNAMIC
+# define N_SET_DYNAMIC(exec, dynamic) \
+((exec).a_info = (dynamic) ? ((exec).a_info | 0x80000000) : \
+((exec).a_info & 0x7fffffff))
+#endif
+
+#ifndef N_SET_MAGIC
+# define N_SET_MAGIC(exec, magic) \
+((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+#endif
+
+#ifndef N_SET_MACHTYPE
+# define N_SET_MACHTYPE(exec, machtype) \
+((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+#endif
+
+#ifndef N_SET_FLAGS
+# define N_SET_FLAGS(exec, flags) \
+((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+#endif
+
+typedef struct aout_symbol {
+ asymbol symbol;
+ short desc;
+ char other;
+ unsigned char type;
+} aout_symbol_type;
+
+/* The `tdata' struct for all a.out-like object file formats.
+ Various things depend on this struct being around any time an a.out
+ file is being handled. An example is dbxread.c in GDB. */
+
+struct aoutdata {
+ struct internal_exec *hdr; /* exec file header */
+ aout_symbol_type *symbols; /* symtab for input bfd */
+
+ /* For ease, we do this */
+ asection *textsec;
+ asection *datasec;
+ asection *bsssec;
+
+ /* We remember these offsets so that after check_file_format, we have
+ no dependencies on the particular format of the exec_hdr. */
+ file_ptr sym_filepos;
+ file_ptr str_filepos;
+
+ /* Size of a relocation entry in external form */
+ unsigned reloc_entry_size;
+
+ /* Size of a symbol table entry in external form */
+ unsigned symbol_entry_size;
+
+ /* Page size - needed for alignment of demand paged files. */
+ unsigned long page_size;
+
+ /* Segment size - needed for alignment of demand paged files. */
+ unsigned long segment_size;
+
+ /* Zmagic disk block size - need to align the start of the text
+ section in ZMAGIC binaries. Normally the same as page_size. */
+ unsigned long zmagic_disk_block_size;
+
+ unsigned exec_bytes_size;
+ unsigned vma_adjusted : 1;
+
+ /* used when a bfd supports several highly similar formats */
+ enum
+ {
+ default_format = 0,
+ /* Used on HP 9000/300 running HP/UX. See hp300hpux.c. */
+ gnu_encap_format,
+ /* Used on Linux, 386BSD, etc. See include/aout/aout64.h. */
+ q_magic_format
+ } subformat;
+
+ enum
+ {
+ undecided_magic = 0,
+ z_magic,
+ o_magic,
+ n_magic
+ } magic;
+
+ /* A buffer for find_nearest_line. */
+ char *line_buf;
+
+ /* The external symbol information. */
+ struct external_nlist *external_syms;
+ bfd_size_type external_sym_count;
+ bfd_window sym_window;
+ char *external_strings;
+ bfd_size_type external_string_size;
+ bfd_window string_window;
+ struct aout_link_hash_entry **sym_hashes;
+
+ /* A pointer for shared library information. */
+ PTR dynamic_info;
+
+ /* A mapping from local symbols to offsets into the global offset
+ table, used when linking on SunOS. This is indexed by the symbol
+ index. */
+ bfd_vma *local_got_offsets;
+};
+
+struct aout_data_struct {
+ struct aoutdata a;
+ struct internal_exec e;
+};
+
+#define adata(bfd) ((bfd)->tdata.aout_data->a)
+#define exec_hdr(bfd) (adata(bfd).hdr)
+#define obj_aout_symbols(bfd) (adata(bfd).symbols)
+#define obj_textsec(bfd) (adata(bfd).textsec)
+#define obj_datasec(bfd) (adata(bfd).datasec)
+#define obj_bsssec(bfd) (adata(bfd).bsssec)
+#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos)
+#define obj_str_filepos(bfd) (adata(bfd).str_filepos)
+#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
+#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
+#define obj_aout_subformat(bfd) (adata(bfd).subformat)
+#define obj_aout_external_syms(bfd) (adata(bfd).external_syms)
+#define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count)
+#define obj_aout_sym_window(bfd) (adata(bfd).sym_window)
+#define obj_aout_external_strings(bfd) (adata(bfd).external_strings)
+#define obj_aout_external_string_size(bfd) (adata(bfd).external_string_size)
+#define obj_aout_string_window(bfd) (adata(bfd).string_window)
+#define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes)
+#define obj_aout_dynamic_info(bfd) (adata(bfd).dynamic_info)
+
+/* We take the address of the first element of an asymbol to ensure that the
+ macro is only ever applied to an asymbol */
+#define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd))
+
+/* Information we keep for each a.out section. This is currently only
+ used by the a.out backend linker. */
+
+struct aout_section_data_struct
+{
+ /* The unswapped relocation entries for this section. */
+ PTR relocs;
+};
+
+#define aout_section_data(s) \
+ ((struct aout_section_data_struct *) (s)->used_by_bfd)
+
+#define set_aout_section_data(s,v) \
+ ((s)->used_by_bfd = (PTR)&(v)->relocs)
+
+/* Prototype declarations for functions defined in aoutx.h */
+
+boolean
+NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section));
+
+boolean
+NAME(aout,make_sections) PARAMS ((bfd *));
+
+const bfd_target *
+NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd,
+ struct internal_exec *execp,
+ const bfd_target *(*callback)(bfd *)));
+
+boolean
+NAME(aout,mkobject) PARAMS ((bfd *abfd));
+
+enum machine_type
+NAME(aout,machine_type) PARAMS ((enum bfd_architecture arch,
+ unsigned long machine,
+ boolean *unknown));
+
+boolean
+NAME(aout,set_arch_mach) PARAMS ((bfd *abfd, enum bfd_architecture arch,
+ unsigned long machine));
+
+boolean
+NAME(aout,new_section_hook) PARAMS ((bfd *abfd, asection *newsect));
+
+boolean
+NAME(aout,set_section_contents) PARAMS ((bfd *abfd, sec_ptr section,
+ PTR location, file_ptr offset, bfd_size_type count));
+
+asymbol *
+NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd));
+
+boolean
+NAME(aout,translate_symbol_table) PARAMS ((bfd *, aout_symbol_type *,
+ struct external_nlist *,
+ bfd_size_type, char *,
+ bfd_size_type,
+ boolean dynamic));
+
+boolean
+NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd));
+
+boolean
+NAME(aout,write_syms) PARAMS ((bfd *abfd));
+
+void
+NAME(aout,reclaim_symbol_table) PARAMS ((bfd *abfd));
+
+long
+NAME(aout,get_symtab_upper_bound) PARAMS ((bfd *abfd));
+
+long
+NAME(aout,get_symtab) PARAMS ((bfd *abfd, asymbol **location));
+
+void
+NAME(aout,swap_ext_reloc_in) PARAMS ((bfd *, struct reloc_ext_external *,
+ arelent *, asymbol **, bfd_size_type));
+void
+NAME(aout,swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *,
+ arelent *, asymbol **, bfd_size_type));
+
+reloc_howto_type *
+NAME(aout,reloc_type_lookup) PARAMS ((bfd *abfd,
+ bfd_reloc_code_real_type code));
+
+boolean
+NAME(aout,slurp_reloc_table) PARAMS ((bfd *abfd, sec_ptr asect,
+ asymbol **symbols));
+
+long
+NAME(aout,canonicalize_reloc) PARAMS ((bfd *abfd, sec_ptr section,
+ arelent **relptr, asymbol **symbols));
+
+long
+NAME(aout,get_reloc_upper_bound) PARAMS ((bfd *abfd, sec_ptr asect));
+
+void
+NAME(aout,reclaim_reloc) PARAMS ((bfd *ignore_abfd, sec_ptr ignore));
+
+alent *
+NAME(aout,get_lineno) PARAMS ((bfd *ignore_abfd, asymbol *ignore_symbol));
+
+void
+NAME(aout,print_symbol) PARAMS ((bfd *ignore_abfd, PTR file,
+ asymbol *symbol, bfd_print_symbol_type how));
+
+void
+NAME(aout,get_symbol_info) PARAMS ((bfd *ignore_abfd,
+ asymbol *symbol, symbol_info *ret));
+
+boolean
+NAME(aout,find_nearest_line) PARAMS ((bfd *abfd, asection *section,
+ asymbol **symbols, bfd_vma offset, CONST char **filename_ptr,
+ CONST char **functionname_ptr, unsigned int *line_ptr));
+
+long
+NAME(aout,read_minisymbols) PARAMS ((bfd *, boolean, PTR *, unsigned int *));
+
+asymbol *
+NAME(aout,minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR,
+ asymbol *));
+
+int
+NAME(aout,sizeof_headers) PARAMS ((bfd *abfd, boolean exec));
+
+boolean
+NAME(aout,adjust_sizes_and_vmas) PARAMS ((bfd *abfd,
+ bfd_size_type *text_size, file_ptr *text_end));
+
+void
+NAME(aout,swap_exec_header_in) PARAMS ((bfd *abfd,
+ struct external_exec *raw_bytes, struct internal_exec *execp));
+
+void
+NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
+ struct internal_exec *execp, struct external_exec *raw_bytes));
+
+struct bfd_hash_entry *
+NAME(aout,link_hash_newfunc)
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+boolean
+NAME(aout,link_hash_table_init)
+ PARAMS ((struct aout_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+
+struct bfd_link_hash_table *
+NAME(aout,link_hash_table_create) PARAMS ((bfd *));
+
+boolean
+NAME(aout,link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+
+boolean
+NAME(aout,final_link) PARAMS ((bfd *, struct bfd_link_info *,
+ void (*) (bfd *, file_ptr *, file_ptr *,
+ file_ptr *)));
+
+boolean
+NAME(aout,bfd_free_cached_info) PARAMS ((bfd *));
+
+/* A.out uses the generic versions of these routines... */
+
+#define aout_32_get_section_contents _bfd_generic_get_section_contents
+
+#define aout_64_get_section_contents _bfd_generic_get_section_contents
+#ifndef NO_WRITE_HEADER_KLUDGE
+#define NO_WRITE_HEADER_KLUDGE 0
+#endif
+
+#ifndef aout_32_bfd_is_local_label_name
+#define aout_32_bfd_is_local_label_name bfd_generic_is_local_label_name
+#endif
+
+#ifndef WRITE_HEADERS
+#define WRITE_HEADERS(abfd, execp) \
+ { \
+ bfd_size_type text_size; /* dummy vars */ \
+ file_ptr text_end; \
+ if (adata(abfd).magic == undecided_magic) \
+ NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
+ \
+ execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
+ 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)); \
+ NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
+ \
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
+ if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
+ != EXEC_BYTES_SIZE) \
+ return false; \
+ /* Now write out reloc info, followed by syms and strings */ \
+ \
+ if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \
+ && bfd_get_symcount (abfd) != 0) \
+ { \
+ if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) != 0) \
+ return false; \
+ \
+ if (! NAME(aout,write_syms)(abfd)) return false; \
+ } \
+ \
+ if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) != 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_SET) != 0) \
+ return false; \
+ if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
+ return false; \
+ }
+#endif
+
+#endif /* ! defined (LIBAOUT_H) */
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
new file mode 100644
index 00000000000..cb4a4df1ac2
--- /dev/null
+++ b/bfd/libbfd-in.h
@@ -0,0 +1,538 @@
+/* libbfd.h -- Declarations used by bfd library *implementation*.
+ (This include file is not for users of the library.)
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+** NOTE: libbfd.h is a GENERATED file. Don't change it; instead,
+** change libbfd-in.h or the other BFD source files processed to
+** generate this file.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Align an address upward to a boundary, expressed as a number of bytes.
+ E.g. align to an 8-byte boundary with argument of 8. Take care never
+ to wrap around if the address is within boundary-1 of the end of the
+ address space. */
+#define BFD_ALIGN(this, boundary) \
+ ((((bfd_vma) (this) + (boundary) - 1) >= (bfd_vma) (this)) \
+ ? (((bfd_vma) (this) + ((boundary) - 1)) & (~((boundary)-1))) \
+ : ~ (bfd_vma) 0)
+
+/* If you want to read and write large blocks, you might want to do it
+ in quanta of this amount */
+#define DEFAULT_BUFFERSIZE 8192
+
+/* Set a tdata field. Can't use the other macros for this, since they
+ do casts, and casting to the left of assignment isn't portable. */
+#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v))
+
+/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points
+ to an instance of this structure. */
+
+struct bfd_in_memory
+{
+ /* Size of buffer. */
+ bfd_size_type size;
+ /* Buffer holding contents of BFD. */
+ bfd_byte *buffer;
+};
+
+/* tdata for an archive. For an input archive, cache
+ needs to be free()'d. For an output archive, symdefs do. */
+
+struct artdata {
+ file_ptr first_file_filepos;
+ /* Speed up searching the armap */
+ struct ar_cache *cache;
+ bfd *archive_head; /* Only interesting in output routines */
+ carsym *symdefs; /* the symdef entries */
+ symindex symdef_count; /* how many there are */
+ char *extended_names; /* clever intel extension */
+ /* when more compilers are standard C, this can be a time_t */
+ long armap_timestamp; /* Timestamp value written into armap.
+ This is used for BSD archives to check
+ that the timestamp is recent enough
+ for the BSD linker to not complain,
+ just before we finish writing an
+ archive. */
+ file_ptr armap_datepos; /* Position within archive to seek to
+ rewrite the date field. */
+ PTR tdata; /* Backend specific information. */
+};
+
+#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data)
+
+/* Goes in bfd's arelt_data slot */
+struct areltdata {
+ char * arch_header; /* it's actually a string */
+ unsigned int parsed_size; /* octets of filesize not including ar_hdr */
+ char *filename; /* null-terminated */
+};
+
+#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
+
+extern PTR bfd_malloc PARAMS ((size_t));
+extern PTR bfd_realloc PARAMS ((PTR, size_t));
+extern PTR bfd_zmalloc PARAMS ((size_t));
+
+extern bfd_error_handler_type _bfd_error_handler;
+
+/* These routines allocate and free things on the BFD's objalloc. */
+
+extern PTR bfd_alloc PARAMS ((bfd *, size_t));
+extern PTR bfd_zalloc PARAMS ((bfd *, size_t));
+extern void bfd_release PARAMS ((bfd *, PTR));
+
+bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
+bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
+boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *));
+boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
+const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd));
+boolean bfd_slurp_armap PARAMS ((bfd *abfd));
+boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
+#define bfd_slurp_bsd_armap bfd_slurp_armap
+#define bfd_slurp_coff_armap bfd_slurp_armap
+boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
+extern boolean _bfd_construct_extended_name_table
+ PARAMS ((bfd *, boolean, char **, bfd_size_type *));
+boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
+boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength));
+bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos));
+extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex));
+bfd * _bfd_new_bfd PARAMS ((void));
+
+boolean bfd_false PARAMS ((bfd *ignore));
+boolean bfd_true PARAMS ((bfd *ignore));
+PTR bfd_nullvoidptr PARAMS ((bfd *ignore));
+int bfd_0 PARAMS ((bfd *ignore));
+unsigned int bfd_0u PARAMS ((bfd *ignore));
+long bfd_0l PARAMS ((bfd *ignore));
+long _bfd_n1 PARAMS ((bfd *ignore));
+void bfd_void PARAMS ((bfd *ignore));
+
+bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *));
+const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd));
+
+void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
+ char *hdr));
+void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
+ char *hdr));
+void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
+ char *hdr));
+
+boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength,
+ struct orl *map, unsigned int orl_count, int stridx));
+
+boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength,
+ struct orl *map, unsigned int orl_count, int stridx));
+
+extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *));
+
+extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *));
+
+bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
+ bfd *last_file));
+
+int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
+
+#define _bfd_read_ar_hdr(abfd) \
+ BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd))
+
+/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
+
+#define _bfd_generic_close_and_cleanup bfd_true
+#define _bfd_generic_bfd_free_cached_info bfd_true
+#define _bfd_generic_new_section_hook \
+ ((boolean (*) PARAMS ((bfd *, asection *))) bfd_true)
+extern boolean _bfd_generic_get_section_contents
+ PARAMS ((bfd *, asection *, PTR location, file_ptr offset,
+ bfd_size_type count));
+extern boolean _bfd_generic_get_section_contents_in_window
+ PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type));
+
+/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use
+ BFD_JUMP_TABLE_COPY (_bfd_generic). */
+
+#define _bfd_generic_bfd_copy_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
+#define _bfd_generic_bfd_merge_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
+#define _bfd_generic_bfd_set_private_flags \
+ ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true)
+#define _bfd_generic_bfd_copy_private_section_data \
+ ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true)
+#define _bfd_generic_bfd_copy_private_symbol_data \
+ ((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true)
+#define _bfd_generic_bfd_print_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, PTR))) bfd_true)
+
+/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
+ support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */
+
+extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *));
+extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *));
+extern boolean _bfd_nocore_core_file_matches_executable_p
+ PARAMS ((bfd *, bfd *));
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive
+ file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */
+
+#define _bfd_noarchive_slurp_armap bfd_false
+#define _bfd_noarchive_slurp_extended_name_table bfd_false
+#define _bfd_noarchive_construct_extended_name_table \
+ ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
+ bfd_false)
+#define _bfd_noarchive_truncate_arname \
+ ((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void)
+#define _bfd_noarchive_write_armap \
+ ((boolean (*) \
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
+ bfd_false)
+#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr
+#define _bfd_noarchive_openr_next_archived_file \
+ ((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr)
+#define _bfd_noarchive_get_elt_at_index \
+ ((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr)
+#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define _bfd_noarchive_update_armap_timestamp bfd_false
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */
+
+#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap
+#define _bfd_archive_bsd_slurp_extended_name_table \
+ _bfd_slurp_extended_name_table
+extern boolean _bfd_archive_bsd_construct_extended_name_table
+ PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname
+#define _bfd_archive_bsd_write_armap bsd_write_armap
+#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_archive_bsd_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_archive_bsd_generic_stat_arch_elt \
+ bfd_generic_stat_arch_elt
+extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *));
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */
+
+#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap
+#define _bfd_archive_coff_slurp_extended_name_table \
+ _bfd_slurp_extended_name_table
+extern boolean _bfd_archive_coff_construct_extended_name_table
+ PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname
+#define _bfd_archive_coff_write_armap coff_write_armap
+#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_archive_coff_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_archive_coff_generic_stat_arch_elt \
+ bfd_generic_stat_arch_elt
+#define _bfd_archive_coff_update_armap_timestamp bfd_true
+
+/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol
+ support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */
+
+#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1
+#define _bfd_nosymbols_get_symtab \
+ ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1)
+#define _bfd_nosymbols_make_empty_symbol \
+ ((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define _bfd_nosymbols_print_symbol \
+ ((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void)
+#define _bfd_nosymbols_get_symbol_info \
+ ((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void)
+#define _bfd_nosymbols_bfd_is_local_label_name \
+ ((boolean (*) PARAMS ((bfd *, const char *))) bfd_false)
+#define _bfd_nosymbols_get_lineno \
+ ((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr)
+#define _bfd_nosymbols_find_nearest_line \
+ ((boolean (*) \
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \
+ const char **, unsigned int *))) \
+ bfd_false)
+#define _bfd_nosymbols_bfd_make_debug_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr)
+#define _bfd_nosymbols_read_minisymbols \
+ ((long (*) PARAMS ((bfd *, boolean, PTR *, unsigned int *))) _bfd_n1)
+#define _bfd_nosymbols_minisymbol_to_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, boolean, const PTR, asymbol *))) \
+ bfd_nullvoidptr)
+
+/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc
+ support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */
+
+#define _bfd_norelocs_get_reloc_upper_bound \
+ ((long (*) PARAMS ((bfd *, asection *))) _bfd_n1)
+#define _bfd_norelocs_canonicalize_reloc \
+ ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1)
+#define _bfd_norelocs_bfd_reloc_type_lookup \
+ ((reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \
+ bfd_nullvoidptr)
+
+/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not
+ be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */
+
+#define _bfd_nowrite_set_arch_mach \
+ ((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \
+ bfd_false)
+#define _bfd_nowrite_set_section_contents \
+ ((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \
+ bfd_false)
+
+/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use
+ BFD_JUMP_TABLE_WRITE (_bfd_generic). */
+
+#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach
+extern boolean _bfd_generic_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+
+/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not
+ support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */
+
+#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0)
+#define _bfd_nolink_bfd_get_relocated_section_contents \
+ ((bfd_byte *(*) \
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \
+ bfd_byte *, boolean, asymbol **))) \
+ bfd_nullvoidptr)
+#define _bfd_nolink_bfd_relax_section \
+ ((boolean (*) \
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \
+ bfd_false)
+#define _bfd_nolink_bfd_gc_sections \
+ ((boolean (*) \
+ PARAMS ((bfd *, struct bfd_link_info *))) \
+ bfd_false)
+#define _bfd_nolink_bfd_link_hash_table_create \
+ ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define _bfd_nolink_bfd_link_add_symbols \
+ ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define _bfd_nolink_bfd_final_link \
+ ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define _bfd_nolink_bfd_link_split_section \
+ ((boolean (*) PARAMS ((bfd *, struct sec *))) bfd_false)
+
+/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
+ have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC
+ (_bfd_nodynamic). */
+
+#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1
+#define _bfd_nodynamic_canonicalize_dynamic_symtab \
+ ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1)
+#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
+#define _bfd_nodynamic_canonicalize_dynamic_reloc \
+ ((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1)
+
+/* Generic routine to determine of the given symbol is a local
+ label. */
+extern boolean bfd_generic_is_local_label_name PARAMS ((bfd *, const char *));
+
+/* Generic minisymbol routines. */
+extern long _bfd_generic_read_minisymbols
+ PARAMS ((bfd *, boolean, PTR *, unsigned int *));
+extern asymbol *_bfd_generic_minisymbol_to_symbol
+ PARAMS ((bfd *, boolean, const PTR, asymbol *));
+
+/* Find the nearest line using .stab/.stabstr sections. */
+extern boolean _bfd_stab_section_find_nearest_line
+ PARAMS ((bfd *, asymbol **, asection *, bfd_vma, boolean *, const char **,
+ const char **, unsigned int *, PTR *));
+
+/* Find the neaderst line using DWARF 1 debugging information. */
+extern boolean _bfd_dwarf1_find_nearest_line
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
+ const char **, unsigned int *));
+
+/* Find the nearest line using DWARF 2 debugging information. */
+extern boolean _bfd_dwarf2_find_nearest_line
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
+ const char **, unsigned int *));
+
+/* A routine to create entries for a bfd_link_hash_table. */
+extern struct bfd_hash_entry *_bfd_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string));
+
+/* Initialize a bfd_link_hash_table. */
+extern boolean _bfd_link_hash_table_init
+ PARAMS ((struct bfd_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+
+/* Generic link hash table creation routine. */
+extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
+ PARAMS ((bfd *));
+
+/* Generic add symbol routine. */
+extern boolean _bfd_generic_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Generic add symbol routine. This version is used by targets for
+ which the linker must collect constructors and destructors by name,
+ as the collect2 program does. */
+extern boolean _bfd_generic_link_add_symbols_collect
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Generic archive add symbol routine. */
+extern boolean _bfd_generic_link_add_archive_symbols
+ PARAMS ((bfd *, struct bfd_link_info *,
+ boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *)));
+
+
+
+/* Forward declaration to avoid prototype errors. */
+typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
+
+/* Generic routine to add a single symbol. */
+extern boolean _bfd_generic_link_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword,
+ asection *, bfd_vma, const char *, boolean copy,
+ boolean constructor, struct bfd_link_hash_entry **));
+
+/* Generic link routine. */
+extern boolean _bfd_generic_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+extern boolean _bfd_generic_link_split_section
+ PARAMS ((bfd *, struct sec *));
+
+/* Generic reloc_link_order processing routine. */
+extern boolean _bfd_generic_reloc_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* Default link order processing routine. */
+extern boolean _bfd_default_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* Count the number of reloc entries in a link order list. */
+extern unsigned int _bfd_count_link_order_relocs
+ PARAMS ((struct bfd_link_order *));
+
+/* Final link relocation routine. */
+extern bfd_reloc_status_type _bfd_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
+ bfd_vma address, bfd_vma value, bfd_vma addend));
+
+/* Relocate a particular location by a howto and a value. */
+extern bfd_reloc_status_type _bfd_relocate_contents
+ PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
+
+/* Link stabs in sections in the first pass. */
+
+extern boolean _bfd_link_section_stabs
+ PARAMS ((bfd *, PTR *, asection *, asection *, PTR *));
+
+/* Write out the .stab section when linking stabs in sections. */
+
+extern boolean _bfd_write_section_stabs
+ PARAMS ((bfd *, PTR *, asection *, PTR *, bfd_byte *));
+
+/* Write out the .stabstr string table when linking stabs in sections. */
+
+extern boolean _bfd_write_stab_strings PARAMS ((bfd *, PTR *));
+
+/* Find an offset within a .stab section when linking stabs in
+ sections. */
+
+extern bfd_vma _bfd_stab_section_offset
+ PARAMS ((bfd *, PTR *, asection *, PTR *, bfd_vma));
+
+/* Create a string table. */
+extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void));
+
+/* Create an XCOFF .debug section style string table. */
+extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void));
+
+/* Free a string table. */
+extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *));
+
+/* Get the size of a string table. */
+extern bfd_size_type _bfd_stringtab_size PARAMS ((struct bfd_strtab_hash *));
+
+/* Add a string to a string table. */
+extern bfd_size_type _bfd_stringtab_add
+ PARAMS ((struct bfd_strtab_hash *, const char *, boolean hash,
+ boolean copy));
+
+/* Write out a string table. */
+extern boolean _bfd_stringtab_emit PARAMS ((bfd *, struct bfd_strtab_hash *));
+
+/* Macros to tell if bfds are read or write enabled.
+
+ Note that bfds open for read may be scribbled into if the fd passed
+ to bfd_fdopenr is actually open both for read and write
+ simultaneously. However an output bfd will never be open for
+ read. Therefore sometimes you want to check bfd_read_p or
+ !bfd_read_p, and only sometimes bfd_write_p.
+*/
+
+#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction)
+#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction)
+
+void bfd_assert PARAMS ((const char*,int));
+
+#define BFD_ASSERT(x) \
+{ if (!(x)) bfd_assert(__FILE__,__LINE__); }
+
+#define BFD_FAIL() \
+{ bfd_assert(__FILE__,__LINE__); }
+
+FILE * bfd_cache_lookup_worker PARAMS ((bfd *));
+
+extern bfd *bfd_last_cache;
+
+/* List of supported target vectors, and the default vector (if
+ bfd_default_vector[0] is NULL, there is no default). */
+extern const bfd_target * const bfd_target_vector[];
+extern const bfd_target *bfd_default_vector[];
+
+/* Functions shared by the ECOFF and MIPS ELF backends, which have no
+ other common header files. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_find_line;
+#endif
+
+extern boolean _bfd_ecoff_locate_line
+ PARAMS ((bfd *, asection *, bfd_vma, struct ecoff_debug_info * const,
+ const struct ecoff_debug_swap * const, struct ecoff_find_line *,
+ const char **, const char **, unsigned int *));
+extern boolean _bfd_ecoff_get_accumulated_pdr PARAMS ((PTR, bfd_byte *));
+extern boolean _bfd_ecoff_get_accumulated_sym PARAMS ((PTR, bfd_byte *));
+extern boolean _bfd_ecoff_get_accumulated_ss PARAMS ((PTR, bfd_byte *));
+
+extern bfd_vma _bfd_get_gp_value PARAMS ((bfd *));
+extern void _bfd_set_gp_value PARAMS ((bfd *, bfd_vma));
+
+/* Function shared by the COFF and ELF SH backends, which have no
+ other common header files. */
+
+extern boolean _bfd_sh_align_load_span
+ PARAMS ((bfd *, asection *, bfd_byte *,
+ boolean (*) (bfd *, asection *, PTR, bfd_byte *, bfd_vma),
+ PTR, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, boolean *));
+
+/* And more follows */
+
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
new file mode 100644
index 00000000000..8abd1f58f1c
--- /dev/null
+++ b/bfd/libbfd.c
@@ -0,0 +1,1263 @@
+/* Assorted BFD support routines, only used internally.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifndef HAVE_GETPAGESIZE
+#define getpagesize() 2048
+#endif
+
+static int real_read PARAMS ((PTR, size_t, size_t, FILE *));
+
+/*
+SECTION
+ Internal functions
+
+DESCRIPTION
+ These routines are used within BFD.
+ They are not intended for export, but are documented here for
+ completeness.
+*/
+
+/* A routine which is used in target vectors for unsupported
+ operations. */
+
+/*ARGSUSED*/
+boolean
+bfd_false (ignore)
+ bfd *ignore;
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+}
+
+/* A routine which is used in target vectors for supported operations
+ which do not actually do anything. */
+
+/*ARGSUSED*/
+boolean
+bfd_true (ignore)
+ bfd *ignore;
+{
+ return true;
+}
+
+/* A routine which is used in target vectors for unsupported
+ operations which return a pointer value. */
+
+/*ARGSUSED*/
+PTR
+bfd_nullvoidptr (ignore)
+ bfd *ignore;
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+}
+
+/*ARGSUSED*/
+int
+bfd_0 (ignore)
+ bfd *ignore;
+{
+ return 0;
+}
+
+/*ARGSUSED*/
+unsigned int
+bfd_0u (ignore)
+ bfd *ignore;
+{
+ return 0;
+}
+
+/*ARGUSED*/
+long
+bfd_0l (ignore)
+ bfd *ignore;
+{
+ return 0;
+}
+
+/* A routine which is used in target vectors for unsupported
+ operations which return -1 on error. */
+
+/*ARGSUSED*/
+long
+_bfd_n1 (ignore_abfd)
+ bfd *ignore_abfd;
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+}
+
+/*ARGSUSED*/
+void
+bfd_void (ignore)
+ bfd *ignore;
+{
+}
+
+/*ARGSUSED*/
+boolean
+_bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd)
+ bfd *ignore_core_bfd;
+ bfd *ignore_exec_bfd;
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+}
+
+/* Routine to handle core_file_failing_command entry point for targets
+ without core file support. */
+
+/*ARGSUSED*/
+char *
+_bfd_nocore_core_file_failing_command (ignore_abfd)
+ bfd *ignore_abfd;
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return (char *)NULL;
+}
+
+/* Routine to handle core_file_failing_signal entry point for targets
+ without core file support. */
+
+/*ARGSUSED*/
+int
+_bfd_nocore_core_file_failing_signal (ignore_abfd)
+ bfd *ignore_abfd;
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+}
+
+/*ARGSUSED*/
+const bfd_target *
+_bfd_dummy_target (ignore_abfd)
+ bfd *ignore_abfd;
+{
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+}
+
+/* Allocate memory using malloc. */
+
+PTR
+bfd_malloc (size)
+ size_t size;
+{
+ PTR ptr;
+
+ ptr = (PTR) malloc (size);
+ if (ptr == NULL && size != 0)
+ bfd_set_error (bfd_error_no_memory);
+ return ptr;
+}
+
+/* Reallocate memory using realloc. */
+
+PTR
+bfd_realloc (ptr, size)
+ PTR ptr;
+ size_t size;
+{
+ PTR ret;
+
+ if (ptr == NULL)
+ ret = malloc (size);
+ else
+ ret = realloc (ptr, size);
+
+ if (ret == NULL)
+ bfd_set_error (bfd_error_no_memory);
+
+ return ret;
+}
+
+/* Allocate memory using malloc and clear it. */
+
+PTR
+bfd_zmalloc (size)
+ size_t size;
+{
+ PTR ptr;
+
+ ptr = (PTR) malloc (size);
+
+ if (size != 0)
+ {
+ if (ptr == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ else
+ memset (ptr, 0, size);
+ }
+
+ return ptr;
+}
+
+/* Some IO code */
+
+
+/* Note that archive entries don't have streams; they share their parent's.
+ This allows someone to play with the iostream behind BFD's back.
+
+ Also, note that the origin pointer points to the beginning of a file's
+ contents (0 for non-archive elements). For archive entries this is the
+ first octet in the file, NOT the beginning of the archive header. */
+
+static int
+real_read (where, a,b, file)
+ PTR where;
+ size_t a;
+ size_t b;
+ FILE *file;
+{
+ /* FIXME - this looks like an optimization, but it's really to cover
+ up for a feature of some OSs (not solaris - sigh) that
+ ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
+ internally and tries to link against them. BFD seems to be smart
+ enough to realize there are no symbol records in the "file" that
+ doesn't exist but attempts to read them anyway. On Solaris,
+ attempting to read zero bytes from a NULL file results in a core
+ dump, but on other platforms it just returns zero bytes read.
+ This makes it to something reasonable. - DJ */
+ if (a == 0 || b == 0)
+ return 0;
+
+#if defined (__VAX) && defined (VMS)
+ /* Apparently fread on Vax VMS does not keep the record length
+ information. */
+ return read (fileno (file), where, a * b);
+#else
+ return fread (where, a, b, file);
+#endif
+}
+
+/* Return value is amount read (FIXME: how are errors and end of file dealt
+ with? We never call bfd_set_error, which is probably a mistake). */
+
+bfd_size_type
+bfd_read (ptr, size, nitems, abfd)
+ PTR ptr;
+ bfd_size_type size;
+ bfd_size_type nitems;
+ bfd *abfd;
+{
+ int nread;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ {
+ struct bfd_in_memory *bim;
+ bfd_size_type get;
+
+ bim = (struct bfd_in_memory *) abfd->iostream;
+ get = size * nitems;
+ if (abfd->where + get > bim->size)
+ {
+ get = bim->size - abfd->where;
+ bfd_set_error (bfd_error_file_truncated);
+ }
+ memcpy (ptr, bim->buffer + abfd->where, get);
+ abfd->where += get;
+ return get;
+ }
+
+ nread = real_read (ptr, 1, (size_t)(size*nitems), bfd_cache_lookup(abfd));
+ if (nread > 0)
+ abfd->where += nread;
+
+ /* Set bfd_error if we did not read as much data as we expected.
+
+ If the read failed due to an error set the bfd_error_system_call,
+ else set bfd_error_file_truncated.
+
+ A BFD backend may wish to override bfd_error_file_truncated to
+ provide something more useful (eg. no_symbols or wrong_format). */
+ if (nread < (int)(size * nitems))
+ {
+ if (ferror (bfd_cache_lookup (abfd)))
+ bfd_set_error (bfd_error_system_call);
+ else
+ bfd_set_error (bfd_error_file_truncated);
+ }
+
+ return nread;
+}
+
+/* The window support stuff should probably be broken out into
+ another file.... */
+/* The idea behind the next and refcount fields is that one mapped
+ region can suffice for multiple read-only windows or multiple
+ non-overlapping read-write windows. It's not implemented yet
+ though. */
+struct _bfd_window_internal {
+ struct _bfd_window_internal *next;
+ PTR data;
+ bfd_size_type size;
+ int refcount : 31; /* should be enough... */
+ unsigned mapped : 1; /* 1 = mmap, 0 = malloc */
+};
+
+void
+bfd_init_window (windowp)
+ bfd_window *windowp;
+{
+ windowp->data = 0;
+ windowp->i = 0;
+ windowp->size = 0;
+}
+
+/* Currently, if USE_MMAP is undefined, none if the window stuff is
+ used. Okay, so it's mis-named. At least the command-line option
+ "--without-mmap" is more obvious than "--without-windows" or some
+ such. */
+#ifdef USE_MMAP
+
+#undef HAVE_MPROTECT /* code's not tested yet */
+
+#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE
+#include <sys/mman.h>
+#endif
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+static int debug_windows;
+
+void
+bfd_free_window (windowp)
+ bfd_window *windowp;
+{
+ bfd_window_internal *i = windowp->i;
+ windowp->i = 0;
+ windowp->data = 0;
+ if (i == 0)
+ return;
+ i->refcount--;
+ if (debug_windows)
+ fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n",
+ windowp, windowp->data, windowp->size, windowp->i);
+ if (i->refcount != 0)
+ return;
+
+ if (i->mapped)
+ {
+#ifdef HAVE_MMAP
+ munmap (i->data, i->size);
+ goto no_free;
+#else
+ abort ();
+#endif
+ }
+#ifdef HAVE_MPROTECT
+ mprotect (i->data, i->size, PROT_READ | PROT_WRITE);
+#endif
+ free (i->data);
+#ifdef HAVE_MMAP
+ no_free:
+#endif
+ i->data = 0;
+ /* There should be no more references to i at this point. */
+ free (i);
+}
+
+static int ok_to_map = 1;
+
+boolean
+bfd_get_file_window (abfd, offset, size, windowp, writable)
+ bfd *abfd;
+ file_ptr offset;
+ bfd_size_type size;
+ bfd_window *windowp;
+ boolean writable;
+{
+ static size_t pagesize;
+ bfd_window_internal *i = windowp->i;
+ size_t size_to_alloc = size;
+
+ if (debug_windows)
+ fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)",
+ abfd, (long) offset, (long) size,
+ windowp, windowp->data, (unsigned long) windowp->size,
+ windowp->i, writable);
+
+ /* Make sure we know the page size, so we can be friendly to mmap. */
+ if (pagesize == 0)
+ pagesize = getpagesize ();
+ if (pagesize == 0)
+ abort ();
+
+ if (i == 0)
+ {
+ windowp->i = i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
+ if (i == 0)
+ return false;
+ i->data = 0;
+ }
+#ifdef HAVE_MMAP
+ if (ok_to_map
+ && (i->data == 0 || i->mapped == 1)
+ && (abfd->flags & BFD_IN_MEMORY) == 0)
+ {
+ file_ptr file_offset, offset2;
+ size_t real_size;
+ int fd;
+ FILE *f;
+
+ /* Find the real file and the real offset into it. */
+ while (abfd->my_archive != NULL)
+ {
+ offset += abfd->origin;
+ abfd = abfd->my_archive;
+ }
+ f = bfd_cache_lookup (abfd);
+ fd = fileno (f);
+
+ /* Compute offsets and size for mmap and for the user's data. */
+ offset2 = offset % pagesize;
+ if (offset2 < 0)
+ abort ();
+ file_offset = offset - offset2;
+ real_size = offset + size - file_offset;
+ real_size = real_size + pagesize - 1;
+ real_size -= real_size % pagesize;
+
+ /* If we're re-using a memory region, make sure it's big enough. */
+ if (i->data && i->size < size)
+ {
+ munmap (i->data, i->size);
+ i->data = 0;
+ }
+ i->data = mmap (i->data, real_size,
+ writable ? PROT_WRITE | PROT_READ : PROT_READ,
+ (writable
+ ? MAP_FILE | MAP_PRIVATE
+ : MAP_FILE | MAP_SHARED),
+ fd, file_offset);
+ if (i->data == (PTR) -1)
+ {
+ /* An error happened. Report it, or try using malloc, or
+ something. */
+ bfd_set_error (bfd_error_system_call);
+ i->data = 0;
+ windowp->data = 0;
+ if (debug_windows)
+ fprintf (stderr, "\t\tmmap failed!\n");
+ return false;
+ }
+ if (debug_windows)
+ fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n",
+ (long) real_size, i->data, (long) offset2);
+ i->size = real_size;
+ windowp->data = (PTR) ((bfd_byte *) i->data + offset2);
+ windowp->size = size;
+ i->mapped = 1;
+ return true;
+ }
+ else if (debug_windows)
+ {
+ if (ok_to_map)
+ fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"),
+ (unsigned long) i->data, (int) i->mapped);
+ else
+ fprintf (stderr, _("not mapping: env var not set\n"));
+ }
+#else
+ ok_to_map = 0;
+#endif
+
+#ifdef HAVE_MPROTECT
+ if (!writable)
+ {
+ size_to_alloc += pagesize - 1;
+ size_to_alloc -= size_to_alloc % pagesize;
+ }
+#endif
+ if (debug_windows)
+ fprintf (stderr, "\n\t%s(%6ld)",
+ i->data ? "realloc" : " malloc", (long) size_to_alloc);
+ i->data = (PTR) bfd_realloc (i->data, size_to_alloc);
+ if (debug_windows)
+ fprintf (stderr, "\t-> %p\n", i->data);
+ i->refcount = 1;
+ if (i->data == NULL)
+ {
+ if (size_to_alloc == 0)
+ return true;
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+ return false;
+ i->size = bfd_read (i->data, size, 1, abfd);
+ if (i->size != size)
+ return false;
+ i->mapped = 0;
+#ifdef HAVE_MPROTECT
+ if (!writable)
+ {
+ if (debug_windows)
+ fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data,
+ (long) i->size);
+ mprotect (i->data, i->size, PROT_READ);
+ }
+#endif
+ windowp->data = i->data;
+ windowp->size = i->size;
+ return true;
+}
+
+#endif /* USE_MMAP */
+
+bfd_size_type
+bfd_write (ptr, size, nitems, abfd)
+ CONST PTR ptr;
+ bfd_size_type size;
+ bfd_size_type nitems;
+ bfd *abfd;
+{
+ long nwrote;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ {
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) (abfd->iostream);
+ size *= nitems;
+ if (abfd->where + size > bim->size)
+ {
+ long newsize, oldsize = (bim->size + 127) & ~127;
+ bim->size = abfd->where + size;
+ /* Round up to cut down on memory fragmentation */
+ newsize = (bim->size + 127) & ~127;
+ if (newsize > oldsize)
+ {
+ bim->buffer = bfd_realloc (bim->buffer, newsize);
+ if (bim->buffer == 0)
+ {
+ bim->size = 0;
+ return 0;
+ }
+ }
+ }
+ memcpy (bim->buffer + abfd->where, ptr, size);
+ abfd->where += size;
+ return size;
+ }
+
+ nwrote = fwrite (ptr, 1, (size_t) (size * nitems),
+ bfd_cache_lookup (abfd));
+ if (nwrote > 0)
+ abfd->where += nwrote;
+ if ((bfd_size_type) nwrote != size * nitems)
+ {
+#ifdef ENOSPC
+ if (nwrote >= 0)
+ errno = ENOSPC;
+#endif
+ bfd_set_error (bfd_error_system_call);
+ }
+ return nwrote;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_write_bigendian_4byte_int
+
+SYNOPSIS
+ void bfd_write_bigendian_4byte_int(bfd *abfd, int i);
+
+DESCRIPTION
+ Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
+ endian order regardless of what else is going on. This is useful in
+ archives.
+
+*/
+void
+bfd_write_bigendian_4byte_int (abfd, i)
+ bfd *abfd;
+ int i;
+{
+ bfd_byte buffer[4];
+ bfd_putb32(i, buffer);
+ if (bfd_write((PTR)buffer, 4, 1, abfd) != 4)
+ abort ();
+}
+
+long
+bfd_tell (abfd)
+ bfd *abfd;
+{
+ file_ptr ptr;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ return abfd->where;
+
+ ptr = ftell (bfd_cache_lookup(abfd));
+
+ if (abfd->my_archive)
+ ptr -= abfd->origin;
+ abfd->where = ptr;
+ return ptr;
+}
+
+int
+bfd_flush (abfd)
+ bfd *abfd;
+{
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ return 0;
+ return fflush (bfd_cache_lookup(abfd));
+}
+
+/* Returns 0 for success, negative value for failure (in which case
+ bfd_get_error can retrieve the error code). */
+int
+bfd_stat (abfd, statbuf)
+ bfd *abfd;
+ struct stat *statbuf;
+{
+ FILE *f;
+ int result;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ abort ();
+
+ f = bfd_cache_lookup (abfd);
+ if (f == NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return -1;
+ }
+ result = fstat (fileno (f), statbuf);
+ if (result < 0)
+ bfd_set_error (bfd_error_system_call);
+ return result;
+}
+
+/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
+ can retrieve the error code). */
+
+int
+bfd_seek (abfd, position, direction)
+ bfd *abfd;
+ file_ptr position;
+ int direction;
+{
+ int result;
+ FILE *f;
+ file_ptr file_position;
+ /* For the time being, a BFD may not seek to it's end. The problem
+ is that we don't easily have a way to recognize the end of an
+ element in an archive. */
+
+ BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
+
+ if (direction == SEEK_CUR && position == 0)
+ return 0;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ {
+ if (direction == SEEK_SET)
+ abfd->where = position;
+ else
+ abfd->where += position;
+ return 0;
+ }
+
+ if (abfd->format != bfd_archive && abfd->my_archive == 0)
+ {
+#if 0
+ /* Explanation for this code: I'm only about 95+% sure that the above
+ conditions are sufficient and that all i/o calls are properly
+ adjusting the `where' field. So this is sort of an `assert'
+ that the `where' field is correct. If we can go a while without
+ tripping the abort, we can probably safely disable this code,
+ so that the real optimizations happen. */
+ file_ptr where_am_i_now;
+ where_am_i_now = ftell (bfd_cache_lookup (abfd));
+ if (abfd->my_archive)
+ where_am_i_now -= abfd->origin;
+ if (where_am_i_now != abfd->where)
+ abort ();
+#endif
+ if (direction == SEEK_SET && position == abfd->where)
+ return 0;
+ }
+ else
+ {
+ /* We need something smarter to optimize access to archives.
+ Currently, anything inside an archive is read via the file
+ handle for the archive. Which means that a bfd_seek on one
+ component affects the `current position' in the archive, as
+ well as in any other component.
+
+ It might be sufficient to put a spike through the cache
+ abstraction, and look to the archive for the file position,
+ but I think we should try for something cleaner.
+
+ In the meantime, no optimization for archives. */
+ }
+
+ f = bfd_cache_lookup (abfd);
+ file_position = position;
+ if (direction == SEEK_SET && abfd->my_archive != NULL)
+ file_position += abfd->origin;
+
+ result = fseek (f, file_position, direction);
+
+ if (result != 0)
+ {
+ int hold_errno = errno;
+
+ /* Force redetermination of `where' field. */
+ bfd_tell (abfd);
+
+ /* An EINVAL error probably means that the file offset was
+ absurd. */
+ if (hold_errno == EINVAL)
+ bfd_set_error (bfd_error_file_truncated);
+ else
+ {
+ bfd_set_error (bfd_error_system_call);
+ errno = hold_errno;
+ }
+ }
+ else
+ {
+ /* Adjust `where' field. */
+ if (direction == SEEK_SET)
+ abfd->where = position;
+ else
+ abfd->where += position;
+ }
+ return result;
+}
+
+/** The do-it-yourself (byte) sex-change kit */
+
+/* The middle letter e.g. get<b>short indicates Big or Little endian
+ target machine. It doesn't matter what the byte order of the host
+ machine is; these routines work for either. */
+
+/* FIXME: Should these take a count argument?
+ Answer (gnu@cygnus.com): No, but perhaps they should be inline
+ functions in swap.h #ifdef __GNUC__.
+ Gprof them later and find out. */
+
+/*
+FUNCTION
+ bfd_put_size
+FUNCTION
+ bfd_get_size
+
+DESCRIPTION
+ These macros as used for reading and writing raw data in
+ sections; each access (except for bytes) is vectored through
+ the target format of the BFD and mangled accordingly. The
+ mangling performs any necessary endian translations and
+ removes alignment restrictions. Note that types accepted and
+ returned by these macros are identical so they can be swapped
+ around in macros---for example, @file{libaout.h} defines <<GET_WORD>>
+ to either <<bfd_get_32>> or <<bfd_get_64>>.
+
+ In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a
+ system without prototypes, the caller is responsible for making
+ sure that is true, with a cast if necessary. We don't cast
+ them in the macro definitions because that would prevent <<lint>>
+ or <<gcc -Wall>> from detecting sins such as passing a pointer.
+ To detect calling these with less than a <<bfd_vma>>, use
+ <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s.
+
+.
+.{* Byte swapping macros for user section data. *}
+.
+.#define bfd_put_8(abfd, val, ptr) \
+. (*((unsigned char *)(ptr)) = (unsigned char)(val))
+.#define bfd_put_signed_8 \
+. bfd_put_8
+.#define bfd_get_8(abfd, ptr) \
+. (*(unsigned char *)(ptr))
+.#define bfd_get_signed_8(abfd, ptr) \
+. ((*(unsigned char *)(ptr) ^ 0x80) - 0x80)
+.
+.#define bfd_put_16(abfd, val, ptr) \
+. BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
+.#define bfd_put_signed_16 \
+. bfd_put_16
+.#define bfd_get_16(abfd, ptr) \
+. BFD_SEND(abfd, bfd_getx16, (ptr))
+.#define bfd_get_signed_16(abfd, ptr) \
+. BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
+.
+.#define bfd_put_32(abfd, val, ptr) \
+. BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
+.#define bfd_put_signed_32 \
+. bfd_put_32
+.#define bfd_get_32(abfd, ptr) \
+. BFD_SEND(abfd, bfd_getx32, (ptr))
+.#define bfd_get_signed_32(abfd, ptr) \
+. BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
+.
+.#define bfd_put_64(abfd, val, ptr) \
+. BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
+.#define bfd_put_signed_64 \
+. bfd_put_64
+.#define bfd_get_64(abfd, ptr) \
+. BFD_SEND(abfd, bfd_getx64, (ptr))
+.#define bfd_get_signed_64(abfd, ptr) \
+. BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
+.
+*/
+
+/*
+FUNCTION
+ bfd_h_put_size
+ bfd_h_get_size
+
+DESCRIPTION
+ These macros have the same function as their <<bfd_get_x>>
+ bretheren, except that they are used for removing information
+ for the header records of object files. Believe it or not,
+ some object files keep their header records in big endian
+ order and their data in little endian order.
+.
+.{* Byte swapping macros for file header data. *}
+.
+.#define bfd_h_put_8(abfd, val, ptr) \
+. bfd_put_8 (abfd, val, ptr)
+.#define bfd_h_put_signed_8(abfd, val, ptr) \
+. bfd_put_8 (abfd, val, ptr)
+.#define bfd_h_get_8(abfd, ptr) \
+. bfd_get_8 (abfd, ptr)
+.#define bfd_h_get_signed_8(abfd, ptr) \
+. bfd_get_signed_8 (abfd, ptr)
+.
+.#define bfd_h_put_16(abfd, val, ptr) \
+. BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
+.#define bfd_h_put_signed_16 \
+. bfd_h_put_16
+.#define bfd_h_get_16(abfd, ptr) \
+. BFD_SEND(abfd, bfd_h_getx16,(ptr))
+.#define bfd_h_get_signed_16(abfd, ptr) \
+. BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
+.
+.#define bfd_h_put_32(abfd, val, ptr) \
+. BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
+.#define bfd_h_put_signed_32 \
+. bfd_h_put_32
+.#define bfd_h_get_32(abfd, ptr) \
+. BFD_SEND(abfd, bfd_h_getx32,(ptr))
+.#define bfd_h_get_signed_32(abfd, ptr) \
+. BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
+.
+.#define bfd_h_put_64(abfd, val, ptr) \
+. BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
+.#define bfd_h_put_signed_64 \
+. bfd_h_put_64
+.#define bfd_h_get_64(abfd, ptr) \
+. BFD_SEND(abfd, bfd_h_getx64,(ptr))
+.#define bfd_h_get_signed_64(abfd, ptr) \
+. BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
+.
+*/
+
+/* Sign extension to bfd_signed_vma. */
+#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
+#define COERCE32(x) \
+ ((bfd_signed_vma) (long) (((unsigned long) (x) ^ 0x80000000) - 0x80000000))
+#define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32)
+#define COERCE64(x) \
+ (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
+
+bfd_vma
+bfd_getb16 (addr)
+ register const bfd_byte *addr;
+{
+ return (addr[0] << 8) | addr[1];
+}
+
+bfd_vma
+bfd_getl16 (addr)
+ register const bfd_byte *addr;
+{
+ return (addr[1] << 8) | addr[0];
+}
+
+bfd_signed_vma
+bfd_getb_signed_16 (addr)
+ register const bfd_byte *addr;
+{
+ return COERCE16((addr[0] << 8) | addr[1]);
+}
+
+bfd_signed_vma
+bfd_getl_signed_16 (addr)
+ register const bfd_byte *addr;
+{
+ return COERCE16((addr[1] << 8) | addr[0]);
+}
+
+void
+bfd_putb16 (data, addr)
+ bfd_vma data;
+ register bfd_byte *addr;
+{
+ addr[0] = (bfd_byte)(data >> 8);
+ addr[1] = (bfd_byte )data;
+}
+
+void
+bfd_putl16 (data, addr)
+ bfd_vma data;
+ register bfd_byte *addr;
+{
+ addr[0] = (bfd_byte )data;
+ addr[1] = (bfd_byte)(data >> 8);
+}
+
+bfd_vma
+bfd_getb32 (addr)
+ register const bfd_byte *addr;
+{
+ unsigned long v;
+
+ v = (unsigned long) addr[0] << 24;
+ v |= (unsigned long) addr[1] << 16;
+ v |= (unsigned long) addr[2] << 8;
+ v |= (unsigned long) addr[3];
+ return (bfd_vma) v;
+}
+
+bfd_vma
+bfd_getl32 (addr)
+ register const bfd_byte *addr;
+{
+ unsigned long v;
+
+ v = (unsigned long) addr[0];
+ v |= (unsigned long) addr[1] << 8;
+ v |= (unsigned long) addr[2] << 16;
+ v |= (unsigned long) addr[3] << 24;
+ return (bfd_vma) v;
+}
+
+bfd_signed_vma
+bfd_getb_signed_32 (addr)
+ register const bfd_byte *addr;
+{
+ unsigned long v;
+
+ v = (unsigned long) addr[0] << 24;
+ v |= (unsigned long) addr[1] << 16;
+ v |= (unsigned long) addr[2] << 8;
+ v |= (unsigned long) addr[3];
+ return COERCE32 (v);
+}
+
+bfd_signed_vma
+bfd_getl_signed_32 (addr)
+ register const bfd_byte *addr;
+{
+ unsigned long v;
+
+ v = (unsigned long) addr[0];
+ v |= (unsigned long) addr[1] << 8;
+ v |= (unsigned long) addr[2] << 16;
+ v |= (unsigned long) addr[3] << 24;
+ return COERCE32 (v);
+}
+
+bfd_vma
+bfd_getb64 (addr)
+ register const bfd_byte *addr;
+{
+#ifdef BFD64
+ bfd_vma low, high;
+
+ high= ((((((((addr[0]) << 8) |
+ addr[1]) << 8) |
+ addr[2]) << 8) |
+ addr[3]) );
+
+ low = (((((((((bfd_vma)addr[4]) << 8) |
+ addr[5]) << 8) |
+ addr[6]) << 8) |
+ addr[7]));
+
+ return high << 32 | low;
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+}
+
+bfd_vma
+bfd_getl64 (addr)
+ register const bfd_byte *addr;
+{
+#ifdef BFD64
+ bfd_vma low, high;
+ high= (((((((addr[7] << 8) |
+ addr[6]) << 8) |
+ addr[5]) << 8) |
+ addr[4]));
+
+ low = ((((((((bfd_vma)addr[3] << 8) |
+ addr[2]) << 8) |
+ addr[1]) << 8) |
+ addr[0]) );
+
+ return high << 32 | low;
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+
+}
+
+bfd_signed_vma
+bfd_getb_signed_64 (addr)
+ register const bfd_byte *addr;
+{
+#ifdef BFD64
+ bfd_vma low, high;
+
+ high= ((((((((addr[0]) << 8) |
+ addr[1]) << 8) |
+ addr[2]) << 8) |
+ addr[3]) );
+
+ low = (((((((((bfd_vma)addr[4]) << 8) |
+ addr[5]) << 8) |
+ addr[6]) << 8) |
+ addr[7]));
+
+ return COERCE64(high << 32 | low);
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+}
+
+bfd_signed_vma
+bfd_getl_signed_64 (addr)
+ register const bfd_byte *addr;
+{
+#ifdef BFD64
+ bfd_vma low, high;
+ high= (((((((addr[7] << 8) |
+ addr[6]) << 8) |
+ addr[5]) << 8) |
+ addr[4]));
+
+ low = ((((((((bfd_vma)addr[3] << 8) |
+ addr[2]) << 8) |
+ addr[1]) << 8) |
+ addr[0]) );
+
+ return COERCE64(high << 32 | low);
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+}
+
+void
+bfd_putb32 (data, addr)
+ bfd_vma data;
+ register bfd_byte *addr;
+{
+ addr[0] = (bfd_byte)(data >> 24);
+ addr[1] = (bfd_byte)(data >> 16);
+ addr[2] = (bfd_byte)(data >> 8);
+ addr[3] = (bfd_byte)data;
+}
+
+void
+bfd_putl32 (data, addr)
+ bfd_vma data;
+ register bfd_byte *addr;
+{
+ addr[0] = (bfd_byte)data;
+ addr[1] = (bfd_byte)(data >> 8);
+ addr[2] = (bfd_byte)(data >> 16);
+ addr[3] = (bfd_byte)(data >> 24);
+}
+
+void
+bfd_putb64 (data, addr)
+ bfd_vma data;
+ register bfd_byte *addr;
+{
+#ifdef BFD64
+ addr[0] = (bfd_byte)(data >> (7*8));
+ addr[1] = (bfd_byte)(data >> (6*8));
+ addr[2] = (bfd_byte)(data >> (5*8));
+ addr[3] = (bfd_byte)(data >> (4*8));
+ addr[4] = (bfd_byte)(data >> (3*8));
+ addr[5] = (bfd_byte)(data >> (2*8));
+ addr[6] = (bfd_byte)(data >> (1*8));
+ addr[7] = (bfd_byte)(data >> (0*8));
+#else
+ BFD_FAIL();
+#endif
+}
+
+void
+bfd_putl64 (data, addr)
+ bfd_vma data;
+ register bfd_byte *addr;
+{
+#ifdef BFD64
+ addr[7] = (bfd_byte)(data >> (7*8));
+ addr[6] = (bfd_byte)(data >> (6*8));
+ addr[5] = (bfd_byte)(data >> (5*8));
+ addr[4] = (bfd_byte)(data >> (4*8));
+ addr[3] = (bfd_byte)(data >> (3*8));
+ addr[2] = (bfd_byte)(data >> (2*8));
+ addr[1] = (bfd_byte)(data >> (1*8));
+ addr[0] = (bfd_byte)(data >> (0*8));
+#else
+ BFD_FAIL();
+#endif
+}
+
+/* Default implementation */
+
+boolean
+_bfd_generic_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (count == 0)
+ return true;
+ if ((bfd_size_type)(offset+count) > section->_raw_size
+ || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
+ || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
+ return (false); /* on error */
+ return (true);
+}
+
+boolean
+_bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ bfd_window *w;
+ file_ptr offset;
+ bfd_size_type count;
+{
+#ifdef USE_MMAP
+ if (count == 0)
+ return true;
+ if (abfd->xvec->_bfd_get_section_contents != _bfd_generic_get_section_contents)
+ {
+ /* We don't know what changes the bfd's get_section_contents
+ method may have to make. So punt trying to map the file
+ window, and let get_section_contents do its thing. */
+ /* @@ FIXME : If the internal window has a refcount of 1 and was
+ allocated with malloc instead of mmap, just reuse it. */
+ bfd_free_window (w);
+ w->i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
+ if (w->i == NULL)
+ return false;
+ w->i->data = (PTR) bfd_malloc ((size_t) count);
+ if (w->i->data == NULL)
+ {
+ free (w->i);
+ w->i = NULL;
+ return false;
+ }
+ w->i->mapped = 0;
+ w->i->refcount = 1;
+ w->size = w->i->size = count;
+ w->data = w->i->data;
+ return bfd_get_section_contents (abfd, section, w->data, offset, count);
+ }
+ if ((bfd_size_type) (offset+count) > section->_raw_size
+ || (bfd_get_file_window (abfd, section->filepos + offset, count, w, true)
+ == false))
+ return false;
+ return true;
+#else
+ abort ();
+#endif
+}
+
+/* This generic function can only be used in implementations where creating
+ NEW sections is disallowed. It is useful in patching existing sections
+ in read-write files, though. See other set_section_contents functions
+ to see why it doesn't work for new sections. */
+boolean
+_bfd_generic_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (count == 0)
+ return true;
+
+ if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) == -1
+ || bfd_write (location, (bfd_size_type) 1, count, abfd) != count)
+ return false;
+
+ return true;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_log2
+
+SYNOPSIS
+ unsigned int bfd_log2(bfd_vma x);
+
+DESCRIPTION
+ Return the log base 2 of the value supplied, rounded up. E.g., an
+ @var{x} of 1025 returns 11.
+*/
+
+unsigned int
+bfd_log2 (x)
+ bfd_vma x;
+{
+ unsigned int result = 0;
+
+ while ((((bfd_vma) 1) << result) < x)
+ ++result;
+ return result;
+}
+
+boolean
+bfd_generic_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
+
+ return (name[0] == locals_prefix);
+}
+
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
new file mode 100644
index 00000000000..f804bde593c
--- /dev/null
+++ b/bfd/libbfd.h
@@ -0,0 +1,885 @@
+/* libbfd.h -- Declarations used by bfd library *implementation*.
+ (This include file is not for users of the library.)
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+** NOTE: libbfd.h is a GENERATED file. Don't change it; instead,
+** change libbfd-in.h or the other BFD source files processed to
+** generate this file.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Align an address upward to a boundary, expressed as a number of bytes.
+ E.g. align to an 8-byte boundary with argument of 8. Take care never
+ to wrap around if the address is within boundary-1 of the end of the
+ address space. */
+#define BFD_ALIGN(this, boundary) \
+ ((((bfd_vma) (this) + (boundary) - 1) >= (bfd_vma) (this)) \
+ ? (((bfd_vma) (this) + ((boundary) - 1)) & (~((boundary)-1))) \
+ : ~ (bfd_vma) 0)
+
+/* If you want to read and write large blocks, you might want to do it
+ in quanta of this amount */
+#define DEFAULT_BUFFERSIZE 8192
+
+/* Set a tdata field. Can't use the other macros for this, since they
+ do casts, and casting to the left of assignment isn't portable. */
+#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v))
+
+/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points
+ to an instance of this structure. */
+
+struct bfd_in_memory
+{
+ /* Size of buffer. */
+ bfd_size_type size;
+ /* Buffer holding contents of BFD. */
+ bfd_byte *buffer;
+};
+
+/* tdata for an archive. For an input archive, cache
+ needs to be free()'d. For an output archive, symdefs do. */
+
+struct artdata {
+ file_ptr first_file_filepos;
+ /* Speed up searching the armap */
+ struct ar_cache *cache;
+ bfd *archive_head; /* Only interesting in output routines */
+ carsym *symdefs; /* the symdef entries */
+ symindex symdef_count; /* how many there are */
+ char *extended_names; /* clever intel extension */
+ /* when more compilers are standard C, this can be a time_t */
+ long armap_timestamp; /* Timestamp value written into armap.
+ This is used for BSD archives to check
+ that the timestamp is recent enough
+ for the BSD linker to not complain,
+ just before we finish writing an
+ archive. */
+ file_ptr armap_datepos; /* Position within archive to seek to
+ rewrite the date field. */
+ PTR tdata; /* Backend specific information. */
+};
+
+#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data)
+
+/* Goes in bfd's arelt_data slot */
+struct areltdata {
+ char * arch_header; /* it's actually a string */
+ unsigned int parsed_size; /* octets of filesize not including ar_hdr */
+ char *filename; /* null-terminated */
+};
+
+#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
+
+extern PTR bfd_malloc PARAMS ((size_t));
+extern PTR bfd_realloc PARAMS ((PTR, size_t));
+extern PTR bfd_zmalloc PARAMS ((size_t));
+
+extern bfd_error_handler_type _bfd_error_handler;
+
+/* These routines allocate and free things on the BFD's objalloc. */
+
+extern PTR bfd_alloc PARAMS ((bfd *, size_t));
+extern PTR bfd_zalloc PARAMS ((bfd *, size_t));
+extern void bfd_release PARAMS ((bfd *, PTR));
+
+bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
+bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
+boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *));
+boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
+const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd));
+boolean bfd_slurp_armap PARAMS ((bfd *abfd));
+boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
+#define bfd_slurp_bsd_armap bfd_slurp_armap
+#define bfd_slurp_coff_armap bfd_slurp_armap
+boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
+extern boolean _bfd_construct_extended_name_table
+ PARAMS ((bfd *, boolean, char **, bfd_size_type *));
+boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
+boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength));
+bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos));
+extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex));
+bfd * _bfd_new_bfd PARAMS ((void));
+
+boolean bfd_false PARAMS ((bfd *ignore));
+boolean bfd_true PARAMS ((bfd *ignore));
+PTR bfd_nullvoidptr PARAMS ((bfd *ignore));
+int bfd_0 PARAMS ((bfd *ignore));
+unsigned int bfd_0u PARAMS ((bfd *ignore));
+long bfd_0l PARAMS ((bfd *ignore));
+long _bfd_n1 PARAMS ((bfd *ignore));
+void bfd_void PARAMS ((bfd *ignore));
+
+bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *));
+const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd));
+
+void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
+ char *hdr));
+void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
+ char *hdr));
+void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
+ char *hdr));
+
+boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength,
+ struct orl *map, unsigned int orl_count, int stridx));
+
+boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength,
+ struct orl *map, unsigned int orl_count, int stridx));
+
+extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *));
+
+extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *));
+
+bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
+ bfd *last_file));
+
+int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
+
+#define _bfd_read_ar_hdr(abfd) \
+ BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd))
+
+/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
+
+#define _bfd_generic_close_and_cleanup bfd_true
+#define _bfd_generic_bfd_free_cached_info bfd_true
+#define _bfd_generic_new_section_hook \
+ ((boolean (*) PARAMS ((bfd *, asection *))) bfd_true)
+extern boolean _bfd_generic_get_section_contents
+ PARAMS ((bfd *, asection *, PTR location, file_ptr offset,
+ bfd_size_type count));
+extern boolean _bfd_generic_get_section_contents_in_window
+ PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type));
+
+/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use
+ BFD_JUMP_TABLE_COPY (_bfd_generic). */
+
+#define _bfd_generic_bfd_copy_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
+#define _bfd_generic_bfd_merge_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
+#define _bfd_generic_bfd_set_private_flags \
+ ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true)
+#define _bfd_generic_bfd_copy_private_section_data \
+ ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true)
+#define _bfd_generic_bfd_copy_private_symbol_data \
+ ((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true)
+#define _bfd_generic_bfd_print_private_bfd_data \
+ ((boolean (*) PARAMS ((bfd *, PTR))) bfd_true)
+
+/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
+ support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */
+
+extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *));
+extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *));
+extern boolean _bfd_nocore_core_file_matches_executable_p
+ PARAMS ((bfd *, bfd *));
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive
+ file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */
+
+#define _bfd_noarchive_slurp_armap bfd_false
+#define _bfd_noarchive_slurp_extended_name_table bfd_false
+#define _bfd_noarchive_construct_extended_name_table \
+ ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
+ bfd_false)
+#define _bfd_noarchive_truncate_arname \
+ ((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void)
+#define _bfd_noarchive_write_armap \
+ ((boolean (*) \
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
+ bfd_false)
+#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr
+#define _bfd_noarchive_openr_next_archived_file \
+ ((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr)
+#define _bfd_noarchive_get_elt_at_index \
+ ((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr)
+#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define _bfd_noarchive_update_armap_timestamp bfd_false
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */
+
+#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap
+#define _bfd_archive_bsd_slurp_extended_name_table \
+ _bfd_slurp_extended_name_table
+extern boolean _bfd_archive_bsd_construct_extended_name_table
+ PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname
+#define _bfd_archive_bsd_write_armap bsd_write_armap
+#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_archive_bsd_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_archive_bsd_generic_stat_arch_elt \
+ bfd_generic_stat_arch_elt
+extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *));
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */
+
+#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap
+#define _bfd_archive_coff_slurp_extended_name_table \
+ _bfd_slurp_extended_name_table
+extern boolean _bfd_archive_coff_construct_extended_name_table
+ PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname
+#define _bfd_archive_coff_write_armap coff_write_armap
+#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_archive_coff_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_archive_coff_generic_stat_arch_elt \
+ bfd_generic_stat_arch_elt
+#define _bfd_archive_coff_update_armap_timestamp bfd_true
+
+/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol
+ support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */
+
+#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1
+#define _bfd_nosymbols_get_symtab \
+ ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1)
+#define _bfd_nosymbols_make_empty_symbol \
+ ((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define _bfd_nosymbols_print_symbol \
+ ((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void)
+#define _bfd_nosymbols_get_symbol_info \
+ ((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void)
+#define _bfd_nosymbols_bfd_is_local_label_name \
+ ((boolean (*) PARAMS ((bfd *, const char *))) bfd_false)
+#define _bfd_nosymbols_get_lineno \
+ ((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr)
+#define _bfd_nosymbols_find_nearest_line \
+ ((boolean (*) \
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \
+ const char **, unsigned int *))) \
+ bfd_false)
+#define _bfd_nosymbols_bfd_make_debug_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr)
+#define _bfd_nosymbols_read_minisymbols \
+ ((long (*) PARAMS ((bfd *, boolean, PTR *, unsigned int *))) _bfd_n1)
+#define _bfd_nosymbols_minisymbol_to_symbol \
+ ((asymbol *(*) PARAMS ((bfd *, boolean, const PTR, asymbol *))) \
+ bfd_nullvoidptr)
+
+/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc
+ support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */
+
+#define _bfd_norelocs_get_reloc_upper_bound \
+ ((long (*) PARAMS ((bfd *, asection *))) _bfd_n1)
+#define _bfd_norelocs_canonicalize_reloc \
+ ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1)
+#define _bfd_norelocs_bfd_reloc_type_lookup \
+ ((reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \
+ bfd_nullvoidptr)
+
+/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not
+ be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */
+
+#define _bfd_nowrite_set_arch_mach \
+ ((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \
+ bfd_false)
+#define _bfd_nowrite_set_section_contents \
+ ((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \
+ bfd_false)
+
+/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use
+ BFD_JUMP_TABLE_WRITE (_bfd_generic). */
+
+#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach
+extern boolean _bfd_generic_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+
+/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not
+ support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */
+
+#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0)
+#define _bfd_nolink_bfd_get_relocated_section_contents \
+ ((bfd_byte *(*) \
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \
+ bfd_byte *, boolean, asymbol **))) \
+ bfd_nullvoidptr)
+#define _bfd_nolink_bfd_relax_section \
+ ((boolean (*) \
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \
+ bfd_false)
+#define _bfd_nolink_bfd_gc_sections \
+ ((boolean (*) \
+ PARAMS ((bfd *, struct bfd_link_info *))) \
+ bfd_false)
+#define _bfd_nolink_bfd_link_hash_table_create \
+ ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define _bfd_nolink_bfd_link_add_symbols \
+ ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define _bfd_nolink_bfd_final_link \
+ ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define _bfd_nolink_bfd_link_split_section \
+ ((boolean (*) PARAMS ((bfd *, struct sec *))) bfd_false)
+
+/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
+ have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC
+ (_bfd_nodynamic). */
+
+#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1
+#define _bfd_nodynamic_canonicalize_dynamic_symtab \
+ ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1)
+#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
+#define _bfd_nodynamic_canonicalize_dynamic_reloc \
+ ((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1)
+
+/* Generic routine to determine of the given symbol is a local
+ label. */
+extern boolean bfd_generic_is_local_label_name PARAMS ((bfd *, const char *));
+
+/* Generic minisymbol routines. */
+extern long _bfd_generic_read_minisymbols
+ PARAMS ((bfd *, boolean, PTR *, unsigned int *));
+extern asymbol *_bfd_generic_minisymbol_to_symbol
+ PARAMS ((bfd *, boolean, const PTR, asymbol *));
+
+/* Find the nearest line using .stab/.stabstr sections. */
+extern boolean _bfd_stab_section_find_nearest_line
+ PARAMS ((bfd *, asymbol **, asection *, bfd_vma, boolean *, const char **,
+ const char **, unsigned int *, PTR *));
+
+/* Find the neaderst line using DWARF 1 debugging information. */
+extern boolean _bfd_dwarf1_find_nearest_line
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
+ const char **, unsigned int *));
+
+/* Find the nearest line using DWARF 2 debugging information. */
+extern boolean _bfd_dwarf2_find_nearest_line
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
+ const char **, unsigned int *));
+
+/* A routine to create entries for a bfd_link_hash_table. */
+extern struct bfd_hash_entry *_bfd_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string));
+
+/* Initialize a bfd_link_hash_table. */
+extern boolean _bfd_link_hash_table_init
+ PARAMS ((struct bfd_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+
+/* Generic link hash table creation routine. */
+extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
+ PARAMS ((bfd *));
+
+/* Generic add symbol routine. */
+extern boolean _bfd_generic_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Generic add symbol routine. This version is used by targets for
+ which the linker must collect constructors and destructors by name,
+ as the collect2 program does. */
+extern boolean _bfd_generic_link_add_symbols_collect
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Generic archive add symbol routine. */
+extern boolean _bfd_generic_link_add_archive_symbols
+ PARAMS ((bfd *, struct bfd_link_info *,
+ boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *)));
+
+
+
+/* Forward declaration to avoid prototype errors. */
+typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
+
+/* Generic routine to add a single symbol. */
+extern boolean _bfd_generic_link_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword,
+ asection *, bfd_vma, const char *, boolean copy,
+ boolean constructor, struct bfd_link_hash_entry **));
+
+/* Generic link routine. */
+extern boolean _bfd_generic_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+extern boolean _bfd_generic_link_split_section
+ PARAMS ((bfd *, struct sec *));
+
+/* Generic reloc_link_order processing routine. */
+extern boolean _bfd_generic_reloc_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* Default link order processing routine. */
+extern boolean _bfd_default_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+
+/* Count the number of reloc entries in a link order list. */
+extern unsigned int _bfd_count_link_order_relocs
+ PARAMS ((struct bfd_link_order *));
+
+/* Final link relocation routine. */
+extern bfd_reloc_status_type _bfd_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
+ bfd_vma address, bfd_vma value, bfd_vma addend));
+
+/* Relocate a particular location by a howto and a value. */
+extern bfd_reloc_status_type _bfd_relocate_contents
+ PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
+
+/* Link stabs in sections in the first pass. */
+
+extern boolean _bfd_link_section_stabs
+ PARAMS ((bfd *, PTR *, asection *, asection *, PTR *));
+
+/* Write out the .stab section when linking stabs in sections. */
+
+extern boolean _bfd_write_section_stabs
+ PARAMS ((bfd *, PTR *, asection *, PTR *, bfd_byte *));
+
+/* Write out the .stabstr string table when linking stabs in sections. */
+
+extern boolean _bfd_write_stab_strings PARAMS ((bfd *, PTR *));
+
+/* Find an offset within a .stab section when linking stabs in
+ sections. */
+
+extern bfd_vma _bfd_stab_section_offset
+ PARAMS ((bfd *, PTR *, asection *, PTR *, bfd_vma));
+
+/* Create a string table. */
+extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void));
+
+/* Create an XCOFF .debug section style string table. */
+extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void));
+
+/* Free a string table. */
+extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *));
+
+/* Get the size of a string table. */
+extern bfd_size_type _bfd_stringtab_size PARAMS ((struct bfd_strtab_hash *));
+
+/* Add a string to a string table. */
+extern bfd_size_type _bfd_stringtab_add
+ PARAMS ((struct bfd_strtab_hash *, const char *, boolean hash,
+ boolean copy));
+
+/* Write out a string table. */
+extern boolean _bfd_stringtab_emit PARAMS ((bfd *, struct bfd_strtab_hash *));
+
+/* Macros to tell if bfds are read or write enabled.
+
+ Note that bfds open for read may be scribbled into if the fd passed
+ to bfd_fdopenr is actually open both for read and write
+ simultaneously. However an output bfd will never be open for
+ read. Therefore sometimes you want to check bfd_read_p or
+ !bfd_read_p, and only sometimes bfd_write_p.
+*/
+
+#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction)
+#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction)
+
+void bfd_assert PARAMS ((const char*,int));
+
+#define BFD_ASSERT(x) \
+{ if (!(x)) bfd_assert(__FILE__,__LINE__); }
+
+#define BFD_FAIL() \
+{ bfd_assert(__FILE__,__LINE__); }
+
+FILE * bfd_cache_lookup_worker PARAMS ((bfd *));
+
+extern bfd *bfd_last_cache;
+
+/* List of supported target vectors, and the default vector (if
+ bfd_default_vector[0] is NULL, there is no default). */
+extern const bfd_target * const bfd_target_vector[];
+extern const bfd_target *bfd_default_vector[];
+
+/* Functions shared by the ECOFF and MIPS ELF backends, which have no
+ other common header files. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_find_line;
+#endif
+
+extern boolean _bfd_ecoff_locate_line
+ PARAMS ((bfd *, asection *, bfd_vma, struct ecoff_debug_info * const,
+ const struct ecoff_debug_swap * const, struct ecoff_find_line *,
+ const char **, const char **, unsigned int *));
+extern boolean _bfd_ecoff_get_accumulated_pdr PARAMS ((PTR, bfd_byte *));
+extern boolean _bfd_ecoff_get_accumulated_sym PARAMS ((PTR, bfd_byte *));
+extern boolean _bfd_ecoff_get_accumulated_ss PARAMS ((PTR, bfd_byte *));
+
+extern bfd_vma _bfd_get_gp_value PARAMS ((bfd *));
+extern void _bfd_set_gp_value PARAMS ((bfd *, bfd_vma));
+
+/* Function shared by the COFF and ELF SH backends, which have no
+ other common header files. */
+
+extern boolean _bfd_sh_align_load_span
+ PARAMS ((bfd *, asection *, bfd_byte *,
+ boolean (*) (bfd *, asection *, PTR, bfd_byte *, bfd_vma),
+ PTR, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, boolean *));
+
+/* And more follows */
+
+void
+bfd_write_bigendian_4byte_int PARAMS ((bfd *abfd, int i));
+
+unsigned int
+bfd_log2 PARAMS ((bfd_vma x));
+
+#define BFD_CACHE_MAX_OPEN 10
+extern bfd *bfd_last_cache;
+
+#define bfd_cache_lookup(x) \
+ ((x)==bfd_last_cache? \
+ (FILE*)(bfd_last_cache->iostream): \
+ bfd_cache_lookup_worker(x))
+boolean
+bfd_cache_init PARAMS ((bfd *abfd));
+
+boolean
+bfd_cache_close PARAMS ((bfd *abfd));
+
+FILE*
+bfd_open_file PARAMS ((bfd *abfd));
+
+FILE *
+bfd_cache_lookup_worker PARAMS ((bfd *abfd));
+
+#ifdef _BFD_MAKE_TABLE_bfd_reloc_code_real
+
+static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
+
+ "BFD_RELOC_64",
+ "BFD_RELOC_32",
+ "BFD_RELOC_26",
+ "BFD_RELOC_24",
+ "BFD_RELOC_16",
+ "BFD_RELOC_14",
+ "BFD_RELOC_8",
+ "BFD_RELOC_64_PCREL",
+ "BFD_RELOC_32_PCREL",
+ "BFD_RELOC_24_PCREL",
+ "BFD_RELOC_16_PCREL",
+ "BFD_RELOC_12_PCREL",
+ "BFD_RELOC_8_PCREL",
+ "BFD_RELOC_32_GOT_PCREL",
+ "BFD_RELOC_16_GOT_PCREL",
+ "BFD_RELOC_8_GOT_PCREL",
+ "BFD_RELOC_32_GOTOFF",
+ "BFD_RELOC_16_GOTOFF",
+ "BFD_RELOC_LO16_GOTOFF",
+ "BFD_RELOC_HI16_GOTOFF",
+ "BFD_RELOC_HI16_S_GOTOFF",
+ "BFD_RELOC_8_GOTOFF",
+ "BFD_RELOC_32_PLT_PCREL",
+ "BFD_RELOC_24_PLT_PCREL",
+ "BFD_RELOC_16_PLT_PCREL",
+ "BFD_RELOC_8_PLT_PCREL",
+ "BFD_RELOC_32_PLTOFF",
+ "BFD_RELOC_16_PLTOFF",
+ "BFD_RELOC_LO16_PLTOFF",
+ "BFD_RELOC_HI16_PLTOFF",
+ "BFD_RELOC_HI16_S_PLTOFF",
+ "BFD_RELOC_8_PLTOFF",
+ "BFD_RELOC_68K_GLOB_DAT",
+ "BFD_RELOC_68K_JMP_SLOT",
+ "BFD_RELOC_68K_RELATIVE",
+ "BFD_RELOC_32_BASEREL",
+ "BFD_RELOC_16_BASEREL",
+ "BFD_RELOC_LO16_BASEREL",
+ "BFD_RELOC_HI16_BASEREL",
+ "BFD_RELOC_HI16_S_BASEREL",
+ "BFD_RELOC_8_BASEREL",
+ "BFD_RELOC_RVA",
+ "BFD_RELOC_8_FFnn",
+ "BFD_RELOC_32_PCREL_S2",
+ "BFD_RELOC_16_PCREL_S2",
+ "BFD_RELOC_23_PCREL_S2",
+ "BFD_RELOC_HI22",
+ "BFD_RELOC_LO10",
+ "BFD_RELOC_GPREL16",
+ "BFD_RELOC_GPREL32",
+ "BFD_RELOC_I960_CALLJ",
+ "BFD_RELOC_NONE",
+ "BFD_RELOC_SPARC_WDISP22",
+ "BFD_RELOC_SPARC22",
+ "BFD_RELOC_SPARC13",
+ "BFD_RELOC_SPARC_GOT10",
+ "BFD_RELOC_SPARC_GOT13",
+ "BFD_RELOC_SPARC_GOT22",
+ "BFD_RELOC_SPARC_PC10",
+ "BFD_RELOC_SPARC_PC22",
+ "BFD_RELOC_SPARC_WPLT30",
+ "BFD_RELOC_SPARC_COPY",
+ "BFD_RELOC_SPARC_GLOB_DAT",
+ "BFD_RELOC_SPARC_JMP_SLOT",
+ "BFD_RELOC_SPARC_RELATIVE",
+ "BFD_RELOC_SPARC_UA32",
+ "BFD_RELOC_SPARC_BASE13",
+ "BFD_RELOC_SPARC_BASE22",
+ "BFD_RELOC_SPARC_10",
+ "BFD_RELOC_SPARC_11",
+ "BFD_RELOC_SPARC_OLO10",
+ "BFD_RELOC_SPARC_HH22",
+ "BFD_RELOC_SPARC_HM10",
+ "BFD_RELOC_SPARC_LM22",
+ "BFD_RELOC_SPARC_PC_HH22",
+ "BFD_RELOC_SPARC_PC_HM10",
+ "BFD_RELOC_SPARC_PC_LM22",
+ "BFD_RELOC_SPARC_WDISP16",
+ "BFD_RELOC_SPARC_WDISP19",
+ "BFD_RELOC_SPARC_7",
+ "BFD_RELOC_SPARC_6",
+ "BFD_RELOC_SPARC_5",
+ "BFD_RELOC_SPARC_PLT64",
+ "BFD_RELOC_SPARC_HIX22",
+ "BFD_RELOC_SPARC_LOX10",
+ "BFD_RELOC_SPARC_H44",
+ "BFD_RELOC_SPARC_M44",
+ "BFD_RELOC_SPARC_L44",
+ "BFD_RELOC_SPARC_REGISTER",
+ "BFD_RELOC_SPARC_REV32",
+ "BFD_RELOC_ALPHA_GPDISP_HI16",
+ "BFD_RELOC_ALPHA_GPDISP_LO16",
+ "BFD_RELOC_ALPHA_GPDISP",
+ "BFD_RELOC_ALPHA_LITERAL",
+ "BFD_RELOC_ALPHA_ELF_LITERAL",
+ "BFD_RELOC_ALPHA_LITUSE",
+ "BFD_RELOC_ALPHA_HINT",
+ "BFD_RELOC_ALPHA_LINKAGE",
+ "BFD_RELOC_ALPHA_CODEADDR",
+ "BFD_RELOC_MIPS_JMP",
+ "BFD_RELOC_MIPS16_JMP",
+ "BFD_RELOC_MIPS16_GPREL",
+ "BFD_RELOC_HI16",
+ "BFD_RELOC_HI16_S",
+ "BFD_RELOC_LO16",
+ "BFD_RELOC_PCREL_HI16_S",
+ "BFD_RELOC_PCREL_LO16",
+ "BFD_RELOC_MIPS_LITERAL",
+ "BFD_RELOC_MIPS_GOT16",
+ "BFD_RELOC_MIPS_CALL16",
+ "BFD_RELOC_MIPS_GOT_HI16",
+ "BFD_RELOC_MIPS_GOT_LO16",
+ "BFD_RELOC_MIPS_CALL_HI16",
+ "BFD_RELOC_MIPS_CALL_LO16",
+
+ "BFD_RELOC_386_GOT32",
+ "BFD_RELOC_386_PLT32",
+ "BFD_RELOC_386_COPY",
+ "BFD_RELOC_386_GLOB_DAT",
+ "BFD_RELOC_386_JUMP_SLOT",
+ "BFD_RELOC_386_RELATIVE",
+ "BFD_RELOC_386_GOTOFF",
+ "BFD_RELOC_386_GOTPC",
+ "BFD_RELOC_NS32K_IMM_8",
+ "BFD_RELOC_NS32K_IMM_16",
+ "BFD_RELOC_NS32K_IMM_32",
+ "BFD_RELOC_NS32K_IMM_8_PCREL",
+ "BFD_RELOC_NS32K_IMM_16_PCREL",
+ "BFD_RELOC_NS32K_IMM_32_PCREL",
+ "BFD_RELOC_NS32K_DISP_8",
+ "BFD_RELOC_NS32K_DISP_16",
+ "BFD_RELOC_NS32K_DISP_32",
+ "BFD_RELOC_NS32K_DISP_8_PCREL",
+ "BFD_RELOC_NS32K_DISP_16_PCREL",
+ "BFD_RELOC_NS32K_DISP_32_PCREL",
+ "BFD_RELOC_PPC_B26",
+ "BFD_RELOC_PPC_BA26",
+ "BFD_RELOC_PPC_TOC16",
+ "BFD_RELOC_PPC_B16",
+ "BFD_RELOC_PPC_B16_BRTAKEN",
+ "BFD_RELOC_PPC_B16_BRNTAKEN",
+ "BFD_RELOC_PPC_BA16",
+ "BFD_RELOC_PPC_BA16_BRTAKEN",
+ "BFD_RELOC_PPC_BA16_BRNTAKEN",
+ "BFD_RELOC_PPC_COPY",
+ "BFD_RELOC_PPC_GLOB_DAT",
+ "BFD_RELOC_PPC_JMP_SLOT",
+ "BFD_RELOC_PPC_RELATIVE",
+ "BFD_RELOC_PPC_LOCAL24PC",
+ "BFD_RELOC_PPC_EMB_NADDR32",
+ "BFD_RELOC_PPC_EMB_NADDR16",
+ "BFD_RELOC_PPC_EMB_NADDR16_LO",
+ "BFD_RELOC_PPC_EMB_NADDR16_HI",
+ "BFD_RELOC_PPC_EMB_NADDR16_HA",
+ "BFD_RELOC_PPC_EMB_SDAI16",
+ "BFD_RELOC_PPC_EMB_SDA2I16",
+ "BFD_RELOC_PPC_EMB_SDA2REL",
+ "BFD_RELOC_PPC_EMB_SDA21",
+ "BFD_RELOC_PPC_EMB_MRKREF",
+ "BFD_RELOC_PPC_EMB_RELSEC16",
+ "BFD_RELOC_PPC_EMB_RELST_LO",
+ "BFD_RELOC_PPC_EMB_RELST_HI",
+ "BFD_RELOC_PPC_EMB_RELST_HA",
+ "BFD_RELOC_PPC_EMB_BIT_FLD",
+ "BFD_RELOC_PPC_EMB_RELSDA",
+ "BFD_RELOC_CTOR",
+ "BFD_RELOC_ARM_PCREL_BRANCH",
+ "BFD_RELOC_ARM_IMMEDIATE",
+ "BFD_RELOC_ARM_OFFSET_IMM",
+ "BFD_RELOC_ARM_SHIFT_IMM",
+ "BFD_RELOC_ARM_SWI",
+ "BFD_RELOC_ARM_MULTI",
+ "BFD_RELOC_ARM_CP_OFF_IMM",
+ "BFD_RELOC_ARM_ADR_IMM",
+ "BFD_RELOC_ARM_LDR_IMM",
+ "BFD_RELOC_ARM_LITERAL",
+ "BFD_RELOC_ARM_IN_POOL",
+ "BFD_RELOC_ARM_OFFSET_IMM8",
+ "BFD_RELOC_ARM_HWLITERAL",
+ "BFD_RELOC_ARM_THUMB_ADD",
+ "BFD_RELOC_ARM_THUMB_IMM",
+ "BFD_RELOC_ARM_THUMB_SHIFT",
+ "BFD_RELOC_ARM_THUMB_OFFSET",
+ "BFD_RELOC_ARM_GOT12",
+ "BFD_RELOC_ARM_GOT32",
+ "BFD_RELOC_ARM_JUMP_SLOT",
+ "BFD_RELOC_ARM_COPY",
+ "BFD_RELOC_ARM_GLOB_DAT",
+ "BFD_RELOC_ARM_PLT32",
+ "BFD_RELOC_ARM_RELATIVE",
+ "BFD_RELOC_ARM_GOTOFF",
+ "BFD_RELOC_ARM_GOTPC",
+ "BFD_RELOC_SH_PCDISP8BY2",
+ "BFD_RELOC_SH_PCDISP12BY2",
+ "BFD_RELOC_SH_IMM4",
+ "BFD_RELOC_SH_IMM4BY2",
+ "BFD_RELOC_SH_IMM4BY4",
+ "BFD_RELOC_SH_IMM8",
+ "BFD_RELOC_SH_IMM8BY2",
+ "BFD_RELOC_SH_IMM8BY4",
+ "BFD_RELOC_SH_PCRELIMM8BY2",
+ "BFD_RELOC_SH_PCRELIMM8BY4",
+ "BFD_RELOC_SH_SWITCH16",
+ "BFD_RELOC_SH_SWITCH32",
+ "BFD_RELOC_SH_USES",
+ "BFD_RELOC_SH_COUNT",
+ "BFD_RELOC_SH_ALIGN",
+ "BFD_RELOC_SH_CODE",
+ "BFD_RELOC_SH_DATA",
+ "BFD_RELOC_SH_LABEL",
+ "BFD_RELOC_THUMB_PCREL_BRANCH9",
+ "BFD_RELOC_THUMB_PCREL_BRANCH12",
+ "BFD_RELOC_THUMB_PCREL_BRANCH23",
+ "BFD_RELOC_ARC_B22_PCREL",
+ "BFD_RELOC_ARC_B26",
+ "BFD_RELOC_D10V_10_PCREL_R",
+ "BFD_RELOC_D10V_10_PCREL_L",
+ "BFD_RELOC_D10V_18",
+ "BFD_RELOC_D10V_18_PCREL",
+ "BFD_RELOC_D30V_6",
+ "BFD_RELOC_D30V_9_PCREL",
+ "BFD_RELOC_D30V_9_PCREL_R",
+ "BFD_RELOC_D30V_15",
+ "BFD_RELOC_D30V_15_PCREL",
+ "BFD_RELOC_D30V_15_PCREL_R",
+ "BFD_RELOC_D30V_21",
+ "BFD_RELOC_D30V_21_PCREL",
+ "BFD_RELOC_D30V_21_PCREL_R",
+ "BFD_RELOC_D30V_32",
+ "BFD_RELOC_D30V_32_PCREL",
+ "BFD_RELOC_M32R_24",
+ "BFD_RELOC_M32R_10_PCREL",
+ "BFD_RELOC_M32R_18_PCREL",
+ "BFD_RELOC_M32R_26_PCREL",
+ "BFD_RELOC_M32R_HI16_ULO",
+ "BFD_RELOC_M32R_HI16_SLO",
+ "BFD_RELOC_M32R_LO16",
+ "BFD_RELOC_M32R_SDA16",
+ "BFD_RELOC_V850_9_PCREL",
+ "BFD_RELOC_V850_22_PCREL",
+ "BFD_RELOC_V850_SDA_16_16_OFFSET",
+ "BFD_RELOC_V850_SDA_15_16_OFFSET",
+ "BFD_RELOC_V850_ZDA_16_16_OFFSET",
+ "BFD_RELOC_V850_ZDA_15_16_OFFSET",
+ "BFD_RELOC_V850_TDA_6_8_OFFSET",
+ "BFD_RELOC_V850_TDA_7_8_OFFSET",
+ "BFD_RELOC_V850_TDA_7_7_OFFSET",
+ "BFD_RELOC_V850_TDA_16_16_OFFSET",
+ "BFD_RELOC_V850_TDA_4_5_OFFSET",
+ "BFD_RELOC_V850_TDA_4_4_OFFSET",
+ "BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET",
+ "BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET",
+ "BFD_RELOC_V850_CALLT_6_7_OFFSET",
+ "BFD_RELOC_V850_CALLT_16_16_OFFSET",
+
+ "BFD_RELOC_MN10300_32_PCREL",
+ "BFD_RELOC_MN10300_16_PCREL",
+ "BFD_RELOC_TIC30_LDP",
+ "BFD_RELOC_FR30_48",
+ "BFD_RELOC_FR30_20",
+ "BFD_RELOC_FR30_6_IN_4",
+ "BFD_RELOC_FR30_8_IN_8",
+ "BFD_RELOC_FR30_9_IN_8",
+ "BFD_RELOC_FR30_10_IN_8",
+ "BFD_RELOC_FR30_9_PCREL",
+ "BFD_RELOC_FR30_12_PCREL",
+ "BFD_RELOC_MCORE_PCREL_IMM8BY4",
+ "BFD_RELOC_MCORE_PCREL_IMM11BY2",
+ "BFD_RELOC_MCORE_PCREL_IMM4BY2",
+ "BFD_RELOC_MCORE_PCREL_32",
+ "BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2",
+ "BFD_RELOC_VTABLE_INHERIT",
+ "BFD_RELOC_VTABLE_ENTRY",
+ "@@overflow: BFD_RELOC_UNUSED@@",
+};
+#endif
+
+reloc_howto_type *
+bfd_default_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+
+boolean
+bfd_generic_relax_section
+ PARAMS ((bfd *abfd,
+ asection *section,
+ struct bfd_link_info *,
+ boolean *));
+
+boolean
+bfd_generic_gc_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+bfd_byte *
+
+bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ boolean relocateable,
+ asymbol **symbols));
+
+extern const bfd_arch_info_type bfd_default_arch_struct;
+boolean
+bfd_default_set_arch_mach PARAMS ((bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long mach));
+
+const bfd_arch_info_type *
+bfd_default_compatible
+ PARAMS ((const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b));
+
+boolean
+bfd_default_scan PARAMS ((const struct bfd_arch_info *info, const char *string));
+
+struct elf_internal_shdr *
+bfd_elf_find_section PARAMS ((bfd *abfd, char *name));
+
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
new file mode 100644
index 00000000000..0dc2121c981
--- /dev/null
+++ b/bfd/libcoff-in.h
@@ -0,0 +1,529 @@
+/* BFD COFF object file private structure.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+** NOTE: libcoff.h is a GENERATED file. Don't change it; instead,
+** change libcoff-in.h or coffcode.h.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfdlink.h"
+
+/* Object file tdata; access macros */
+
+#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
+#define exec_hdr(bfd) (coff_data(bfd)->hdr)
+#define obj_pe(bfd) (coff_data(bfd)->pe)
+#define obj_symbols(bfd) (coff_data(bfd)->symbols)
+#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos)
+
+#define obj_relocbase(bfd) (coff_data(bfd)->relocbase)
+#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments)
+#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count)
+#define obj_convert(bfd) (coff_data(bfd)->conversion_table)
+#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size)
+
+#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms)
+#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms)
+#define obj_coff_strings(bfd) (coff_data (bfd)->strings)
+#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings)
+#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes)
+
+#define obj_coff_local_toc_table(bfd) (coff_data(bfd)->local_toc_sym_map)
+
+/* `Tdata' information kept for COFF files. */
+
+typedef struct coff_tdata
+{
+ struct coff_symbol_struct *symbols; /* symtab for input bfd */
+ unsigned int *conversion_table;
+ int conv_table_size;
+ file_ptr sym_filepos;
+
+ struct coff_ptr_struct *raw_syments;
+ unsigned int raw_syment_count;
+
+ /* These are only valid once writing has begun */
+ long int relocbase;
+
+ /* These members communicate important constants about the symbol table
+ to GDB's symbol-reading code. These `constants' unfortunately vary
+ from coff implementation to implementation... */
+ unsigned local_n_btmask;
+ unsigned local_n_btshft;
+ unsigned local_n_tmask;
+ unsigned local_n_tshift;
+ unsigned local_symesz;
+ unsigned local_auxesz;
+ unsigned local_linesz;
+
+ /* The unswapped external symbols. May be NULL. Read by
+ _bfd_coff_get_external_symbols. */
+ PTR external_syms;
+ /* If this is true, the external_syms may not be freed. */
+ boolean keep_syms;
+
+ /* The string table. May be NULL. Read by
+ _bfd_coff_read_string_table. */
+ char *strings;
+ /* If this is true, the strings may not be freed. */
+ boolean keep_strings;
+
+ /* is this a PE format coff file */
+ int pe;
+ /* Used by the COFF backend linker. */
+ struct coff_link_hash_entry **sym_hashes;
+
+ /* used by the pe linker for PowerPC */
+ int *local_toc_sym_map;
+
+ struct bfd_link_info *link_info;
+
+ /* Used by coff_find_nearest_line. */
+ PTR line_info;
+
+ /* Copy of some of the f_flags bits in the COFF filehdr structure,
+ used by ARM code. */
+ flagword flags;
+
+} coff_data_type;
+
+/* Tdata for pe image files. */
+typedef struct pe_tdata
+{
+ coff_data_type coff;
+ struct internal_extra_pe_aouthdr pe_opthdr;
+ int dll;
+ int has_reloc_section;
+ boolean (*in_reloc_p) PARAMS((bfd *, reloc_howto_type *));
+ flagword real_flags;
+} pe_data_type;
+
+#define pe_data(bfd) ((bfd)->tdata.pe_obj_data)
+
+/* Tdata for XCOFF files. */
+
+struct xcoff_tdata
+{
+ /* Basic COFF information. */
+ coff_data_type coff;
+
+ /* True if a large a.out header should be generated. */
+ boolean full_aouthdr;
+
+ /* TOC value. */
+ bfd_vma toc;
+
+ /* Index of section holding TOC. */
+ int sntoc;
+
+ /* Index of section holding entry point. */
+ int snentry;
+
+ /* .text alignment from optional header. */
+ int text_align_power;
+
+ /* .data alignment from optional header. */
+ int data_align_power;
+
+ /* modtype from optional header. */
+ short modtype;
+
+ /* cputype from optional header. */
+ short cputype;
+
+ /* maxdata from optional header. */
+ bfd_size_type maxdata;
+
+ /* maxstack from optional header. */
+ bfd_size_type maxstack;
+
+ /* Used by the XCOFF backend linker. */
+ asection **csects;
+ unsigned long *debug_indices;
+ unsigned int import_file_id;
+};
+
+#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data)
+
+/* We take the address of the first element of a asymbol to ensure that the
+ * macro is only ever applied to an asymbol. */
+#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd)))
+
+/* The used_by_bfd field of a section may be set to a pointer to this
+ structure. */
+
+struct coff_section_tdata
+{
+ /* The relocs, swapped into COFF internal form. This may be NULL. */
+ struct internal_reloc *relocs;
+ /* If this is true, the relocs entry may not be freed. */
+ boolean keep_relocs;
+ /* The section contents. This may be NULL. */
+ bfd_byte *contents;
+ /* If this is true, the contents entry may not be freed. */
+ boolean keep_contents;
+ /* Information cached by coff_find_nearest_line. */
+ bfd_vma offset;
+ unsigned int i;
+ const char *function;
+ int line_base;
+ /* A pointer used for .stab linking optimizations. */
+ PTR stab_info;
+ /* Available for individual backends. */
+ PTR tdata;
+};
+
+/* An accessor macro for the coff_section_tdata structure. */
+#define coff_section_data(abfd, sec) \
+ ((struct coff_section_tdata *) (sec)->used_by_bfd)
+
+/* Tdata for sections in XCOFF files. This is used by the linker. */
+
+struct xcoff_section_tdata
+{
+ /* Used for XCOFF csects created by the linker; points to the real
+ XCOFF section which contains this csect. */
+ asection *enclosing;
+ /* The lineno_count field for the enclosing section, because we are
+ going to clobber it there. */
+ unsigned int lineno_count;
+ /* The first and one past the last symbol indices for symbols used
+ by this csect. */
+ unsigned long first_symndx;
+ unsigned long last_symndx;
+};
+
+/* An accessor macro the xcoff_section_tdata structure. */
+#define xcoff_section_data(abfd, sec) \
+ ((struct xcoff_section_tdata *) coff_section_data ((abfd), (sec))->tdata)
+
+/* Tdata for sections in PEI image files. */
+
+struct pei_section_tdata
+{
+ /* The virtual size of the section. */
+ bfd_size_type virt_size;
+};
+
+/* An accessor macro for the pei_section_tdata structure. */
+#define pei_section_data(abfd, sec) \
+ ((struct pei_section_tdata *) coff_section_data ((abfd), (sec))->tdata)
+
+/* COFF linker hash table entries. */
+
+struct coff_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+
+ /* Symbol index in output file. Set to -1 initially. Set to -2 if
+ there is a reloc against this symbol. */
+ long indx;
+
+ /* Symbol type. */
+ unsigned short type;
+
+ /* Symbol class. */
+ unsigned char class;
+
+ /* Number of auxiliary entries. */
+ char numaux;
+
+ /* BFD to take auxiliary entries from. */
+ bfd *auxbfd;
+
+ /* Pointer to array of auxiliary entries, if any. */
+ union internal_auxent *aux;
+};
+
+/* COFF linker hash table. */
+
+struct coff_link_hash_table
+{
+ struct bfd_link_hash_table root;
+ /* A pointer to information used to link stabs in sections. */
+ PTR stab_info;
+};
+
+/* Look up an entry in a COFF linker hash table. */
+
+#define coff_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct coff_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), \
+ (copy), (follow)))
+
+/* Traverse a COFF linker hash table. */
+
+#define coff_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the COFF linker hash table from a link_info structure. */
+
+#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash))
+
+/* Functions in coffgen.c. */
+extern const bfd_target *coff_object_p PARAMS ((bfd *));
+extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int));
+extern long coff_get_symtab_upper_bound PARAMS ((bfd *));
+extern long coff_get_symtab PARAMS ((bfd *, asymbol **));
+extern int coff_count_linenumbers PARAMS ((bfd *));
+extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *));
+extern boolean coff_renumber_symbols PARAMS ((bfd *, int *));
+extern void coff_mangle_symbols PARAMS ((bfd *));
+extern boolean coff_write_symbols PARAMS ((bfd *));
+extern boolean coff_write_linenumbers PARAMS ((bfd *));
+extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *));
+extern asymbol *coff_section_symbol PARAMS ((bfd *, char *));
+extern boolean _bfd_coff_get_external_symbols PARAMS ((bfd *));
+extern const char *_bfd_coff_read_string_table PARAMS ((bfd *));
+extern boolean _bfd_coff_free_symbols PARAMS ((bfd *));
+extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *));
+extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
+extern asymbol *coff_make_empty_symbol PARAMS ((bfd *));
+extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *,
+ bfd_print_symbol_type how));
+extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *,
+ symbol_info *ret));
+extern boolean _bfd_coff_is_local_label_name PARAMS ((bfd *, const char *));
+extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR,
+ unsigned long));
+extern boolean coff_find_nearest_line PARAMS ((bfd *,
+ asection *,
+ asymbol **,
+ bfd_vma offset,
+ CONST char **filename_ptr,
+ CONST char **functionname_ptr,
+ unsigned int *line_ptr));
+extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc));
+extern boolean bfd_coff_reloc16_relax_section
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, boolean relocateable, asymbol **));
+extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
+ struct bfd_link_info *,
+ asection *));
+extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip,
+ asection *input_section,
+ bfd_vma val));
+
+/* Functions and types in cofflink.c. */
+
+#define STRING_SIZE_SIZE (4)
+
+/* We use a hash table to merge identical enum, struct, and union
+ definitions in the linker. */
+
+/* Information we keep for a single element (an enum value, a
+ structure or union field) in the debug merge hash table. */
+
+struct coff_debug_merge_element
+{
+ /* Next element. */
+ struct coff_debug_merge_element *next;
+
+ /* Name. */
+ const char *name;
+
+ /* Type. */
+ unsigned int type;
+
+ /* Symbol index for complex type. */
+ long tagndx;
+};
+
+/* A linked list of debug merge entries for a given name. */
+
+struct coff_debug_merge_type
+{
+ /* Next type with the same name. */
+ struct coff_debug_merge_type *next;
+
+ /* Class of type. */
+ int class;
+
+ /* Symbol index where this type is defined. */
+ long indx;
+
+ /* List of elements. */
+ struct coff_debug_merge_element *elements;
+};
+
+/* Information we store in the debug merge hash table. */
+
+struct coff_debug_merge_hash_entry
+{
+ struct bfd_hash_entry root;
+
+ /* A list of types with this name. */
+ struct coff_debug_merge_type *types;
+};
+
+/* The debug merge hash table. */
+
+struct coff_debug_merge_hash_table
+{
+ struct bfd_hash_table root;
+};
+
+/* Initialize a COFF debug merge hash table. */
+
+#define coff_debug_merge_hash_table_init(table) \
+ (bfd_hash_table_init (&(table)->root, _bfd_coff_debug_merge_hash_newfunc))
+
+/* Free a COFF debug merge hash table. */
+
+#define coff_debug_merge_hash_table_free(table) \
+ (bfd_hash_table_free (&(table)->root))
+
+/* Look up an entry in a COFF debug merge hash table. */
+
+#define coff_debug_merge_hash_lookup(table, string, create, copy) \
+ ((struct coff_debug_merge_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* Information we keep for each section in the output file when doing
+ a relocateable link. */
+
+struct coff_link_section_info
+{
+ /* The relocs to be output. */
+ struct internal_reloc *relocs;
+ /* For each reloc against a global symbol whose index was not known
+ when the reloc was handled, the global hash table entry. */
+ struct coff_link_hash_entry **rel_hashes;
+};
+
+/* Information that we pass around while doing the final link step. */
+
+struct coff_final_link_info
+{
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* Used to indicate failure in traversal routine. */
+ boolean failed;
+ /* If doing "task linking" set only during the time when we want the
+ global symbol writer to convert the storage class of defined global
+ symbols from global to static. */
+ boolean global_to_static;
+ /* Hash table for long symbol names. */
+ struct bfd_strtab_hash *strtab;
+ /* When doing a relocateable link, an array of information kept for
+ each output section, indexed by the target_index field. */
+ struct coff_link_section_info *section_info;
+ /* Symbol index of last C_FILE symbol (-1 if none). */
+ long last_file_index;
+ /* Contents of last C_FILE symbol. */
+ struct internal_syment last_file;
+ /* Symbol index of first aux entry of last .bf symbol with an empty
+ endndx field (-1 if none). */
+ long last_bf_index;
+ /* Contents of last_bf_index aux entry. */
+ union internal_auxent last_bf;
+ /* Hash table used to merge debug information. */
+ struct coff_debug_merge_hash_table debug_merge;
+ /* Buffer large enough to hold swapped symbols of any input file. */
+ struct internal_syment *internal_syms;
+ /* Buffer large enough to hold sections of symbols of any input file. */
+ asection **sec_ptrs;
+ /* Buffer large enough to hold output indices of symbols of any
+ input file. */
+ long *sym_indices;
+ /* Buffer large enough to hold output symbols for any input file. */
+ bfd_byte *outsyms;
+ /* Buffer large enough to hold external line numbers for any input
+ section. */
+ bfd_byte *linenos;
+ /* Buffer large enough to hold any input section. */
+ bfd_byte *contents;
+ /* Buffer large enough to hold external relocs of any input section. */
+ bfd_byte *external_relocs;
+ /* Buffer large enough to hold swapped relocs of any input section. */
+ struct internal_reloc *internal_relocs;
+};
+
+extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+extern boolean _bfd_coff_link_hash_table_init
+ PARAMS ((struct coff_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create
+ PARAMS ((bfd *));
+extern const char *_bfd_coff_internal_syment_name
+ PARAMS ((bfd *, const struct internal_syment *, char *));
+extern boolean _bfd_coff_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_coff_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern struct internal_reloc *_bfd_coff_read_internal_relocs
+ PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean,
+ struct internal_reloc *));
+extern boolean _bfd_coff_generic_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+extern struct bfd_hash_entry *_bfd_coff_debug_merge_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+extern boolean _bfd_coff_write_global_sym
+ PARAMS ((struct coff_link_hash_entry *, PTR));
+extern boolean _bfd_coff_write_task_globals
+ PARAMS ((struct coff_link_hash_entry *, PTR));
+extern boolean _bfd_coff_link_input_bfd
+ PARAMS ((struct coff_final_link_info *, bfd *));
+extern boolean _bfd_coff_reloc_link_order
+ PARAMS ((bfd *, struct coff_final_link_info *, asection *,
+ struct bfd_link_order *));
+
+
+#define coff_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+/* Functions in xcofflink.c. */
+
+extern long _bfd_xcoff_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
+extern long _bfd_xcoff_canonicalize_dynamic_symtab
+ PARAMS ((bfd *, asymbol **));
+extern long _bfd_xcoff_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
+extern long _bfd_xcoff_canonicalize_dynamic_reloc
+ PARAMS ((bfd *, arelent **, asymbol **));
+extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
+ PARAMS ((bfd *));
+extern boolean _bfd_xcoff_bfd_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_xcoff_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_ppc_xcoff_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+/* Functions in coff-ppc.c. FIXME: These are called be pe.em in the
+ linker, and so should start with bfd and be declared in bfd.h. */
+
+extern boolean ppc_allocate_toc_section PARAMS ((struct bfd_link_info *));
+extern boolean ppc_process_before_allocation
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* And more taken from the source .. */
+
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
new file mode 100644
index 00000000000..c418a4d4667
--- /dev/null
+++ b/bfd/libcoff.h
@@ -0,0 +1,888 @@
+/* BFD COFF object file private structure.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+** NOTE: libcoff.h is a GENERATED file. Don't change it; instead,
+** change libcoff-in.h or coffcode.h.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfdlink.h"
+
+/* Object file tdata; access macros */
+
+#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
+#define exec_hdr(bfd) (coff_data(bfd)->hdr)
+#define obj_pe(bfd) (coff_data(bfd)->pe)
+#define obj_symbols(bfd) (coff_data(bfd)->symbols)
+#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos)
+
+#define obj_relocbase(bfd) (coff_data(bfd)->relocbase)
+#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments)
+#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count)
+#define obj_convert(bfd) (coff_data(bfd)->conversion_table)
+#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size)
+
+#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms)
+#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms)
+#define obj_coff_strings(bfd) (coff_data (bfd)->strings)
+#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings)
+#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes)
+
+#define obj_coff_local_toc_table(bfd) (coff_data(bfd)->local_toc_sym_map)
+
+/* `Tdata' information kept for COFF files. */
+
+typedef struct coff_tdata
+{
+ struct coff_symbol_struct *symbols; /* symtab for input bfd */
+ unsigned int *conversion_table;
+ int conv_table_size;
+ file_ptr sym_filepos;
+
+ struct coff_ptr_struct *raw_syments;
+ unsigned int raw_syment_count;
+
+ /* These are only valid once writing has begun */
+ long int relocbase;
+
+ /* These members communicate important constants about the symbol table
+ to GDB's symbol-reading code. These `constants' unfortunately vary
+ from coff implementation to implementation... */
+ unsigned local_n_btmask;
+ unsigned local_n_btshft;
+ unsigned local_n_tmask;
+ unsigned local_n_tshift;
+ unsigned local_symesz;
+ unsigned local_auxesz;
+ unsigned local_linesz;
+
+ /* The unswapped external symbols. May be NULL. Read by
+ _bfd_coff_get_external_symbols. */
+ PTR external_syms;
+ /* If this is true, the external_syms may not be freed. */
+ boolean keep_syms;
+
+ /* The string table. May be NULL. Read by
+ _bfd_coff_read_string_table. */
+ char *strings;
+ /* If this is true, the strings may not be freed. */
+ boolean keep_strings;
+
+ /* is this a PE format coff file */
+ int pe;
+ /* Used by the COFF backend linker. */
+ struct coff_link_hash_entry **sym_hashes;
+
+ /* used by the pe linker for PowerPC */
+ int *local_toc_sym_map;
+
+ struct bfd_link_info *link_info;
+
+ /* Used by coff_find_nearest_line. */
+ PTR line_info;
+
+ /* Copy of some of the f_flags bits in the COFF filehdr structure,
+ used by ARM code. */
+ flagword flags;
+
+} coff_data_type;
+
+/* Tdata for pe image files. */
+typedef struct pe_tdata
+{
+ coff_data_type coff;
+ struct internal_extra_pe_aouthdr pe_opthdr;
+ int dll;
+ int has_reloc_section;
+ boolean (*in_reloc_p) PARAMS((bfd *, reloc_howto_type *));
+ flagword real_flags;
+} pe_data_type;
+
+#define pe_data(bfd) ((bfd)->tdata.pe_obj_data)
+
+/* Tdata for XCOFF files. */
+
+struct xcoff_tdata
+{
+ /* Basic COFF information. */
+ coff_data_type coff;
+
+ /* True if a large a.out header should be generated. */
+ boolean full_aouthdr;
+
+ /* TOC value. */
+ bfd_vma toc;
+
+ /* Index of section holding TOC. */
+ int sntoc;
+
+ /* Index of section holding entry point. */
+ int snentry;
+
+ /* .text alignment from optional header. */
+ int text_align_power;
+
+ /* .data alignment from optional header. */
+ int data_align_power;
+
+ /* modtype from optional header. */
+ short modtype;
+
+ /* cputype from optional header. */
+ short cputype;
+
+ /* maxdata from optional header. */
+ bfd_size_type maxdata;
+
+ /* maxstack from optional header. */
+ bfd_size_type maxstack;
+
+ /* Used by the XCOFF backend linker. */
+ asection **csects;
+ unsigned long *debug_indices;
+ unsigned int import_file_id;
+};
+
+#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data)
+
+/* We take the address of the first element of a asymbol to ensure that the
+ * macro is only ever applied to an asymbol. */
+#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd)))
+
+/* The used_by_bfd field of a section may be set to a pointer to this
+ structure. */
+
+struct coff_section_tdata
+{
+ /* The relocs, swapped into COFF internal form. This may be NULL. */
+ struct internal_reloc *relocs;
+ /* If this is true, the relocs entry may not be freed. */
+ boolean keep_relocs;
+ /* The section contents. This may be NULL. */
+ bfd_byte *contents;
+ /* If this is true, the contents entry may not be freed. */
+ boolean keep_contents;
+ /* Information cached by coff_find_nearest_line. */
+ bfd_vma offset;
+ unsigned int i;
+ const char *function;
+ int line_base;
+ /* A pointer used for .stab linking optimizations. */
+ PTR stab_info;
+ /* Available for individual backends. */
+ PTR tdata;
+};
+
+/* An accessor macro for the coff_section_tdata structure. */
+#define coff_section_data(abfd, sec) \
+ ((struct coff_section_tdata *) (sec)->used_by_bfd)
+
+/* Tdata for sections in XCOFF files. This is used by the linker. */
+
+struct xcoff_section_tdata
+{
+ /* Used for XCOFF csects created by the linker; points to the real
+ XCOFF section which contains this csect. */
+ asection *enclosing;
+ /* The lineno_count field for the enclosing section, because we are
+ going to clobber it there. */
+ unsigned int lineno_count;
+ /* The first and one past the last symbol indices for symbols used
+ by this csect. */
+ unsigned long first_symndx;
+ unsigned long last_symndx;
+};
+
+/* An accessor macro the xcoff_section_tdata structure. */
+#define xcoff_section_data(abfd, sec) \
+ ((struct xcoff_section_tdata *) coff_section_data ((abfd), (sec))->tdata)
+
+/* Tdata for sections in PEI image files. */
+
+struct pei_section_tdata
+{
+ /* The virtual size of the section. */
+ bfd_size_type virt_size;
+};
+
+/* An accessor macro for the pei_section_tdata structure. */
+#define pei_section_data(abfd, sec) \
+ ((struct pei_section_tdata *) coff_section_data ((abfd), (sec))->tdata)
+
+/* COFF linker hash table entries. */
+
+struct coff_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+
+ /* Symbol index in output file. Set to -1 initially. Set to -2 if
+ there is a reloc against this symbol. */
+ long indx;
+
+ /* Symbol type. */
+ unsigned short type;
+
+ /* Symbol class. */
+ unsigned char class;
+
+ /* Number of auxiliary entries. */
+ char numaux;
+
+ /* BFD to take auxiliary entries from. */
+ bfd *auxbfd;
+
+ /* Pointer to array of auxiliary entries, if any. */
+ union internal_auxent *aux;
+};
+
+/* COFF linker hash table. */
+
+struct coff_link_hash_table
+{
+ struct bfd_link_hash_table root;
+ /* A pointer to information used to link stabs in sections. */
+ PTR stab_info;
+};
+
+/* Look up an entry in a COFF linker hash table. */
+
+#define coff_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct coff_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), \
+ (copy), (follow)))
+
+/* Traverse a COFF linker hash table. */
+
+#define coff_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the COFF linker hash table from a link_info structure. */
+
+#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash))
+
+/* Functions in coffgen.c. */
+extern const bfd_target *coff_object_p PARAMS ((bfd *));
+extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int));
+extern long coff_get_symtab_upper_bound PARAMS ((bfd *));
+extern long coff_get_symtab PARAMS ((bfd *, asymbol **));
+extern int coff_count_linenumbers PARAMS ((bfd *));
+extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *));
+extern boolean coff_renumber_symbols PARAMS ((bfd *, int *));
+extern void coff_mangle_symbols PARAMS ((bfd *));
+extern boolean coff_write_symbols PARAMS ((bfd *));
+extern boolean coff_write_linenumbers PARAMS ((bfd *));
+extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *));
+extern asymbol *coff_section_symbol PARAMS ((bfd *, char *));
+extern boolean _bfd_coff_get_external_symbols PARAMS ((bfd *));
+extern const char *_bfd_coff_read_string_table PARAMS ((bfd *));
+extern boolean _bfd_coff_free_symbols PARAMS ((bfd *));
+extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *));
+extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
+extern asymbol *coff_make_empty_symbol PARAMS ((bfd *));
+extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *,
+ bfd_print_symbol_type how));
+extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *,
+ symbol_info *ret));
+extern boolean _bfd_coff_is_local_label_name PARAMS ((bfd *, const char *));
+extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR,
+ unsigned long));
+extern boolean coff_find_nearest_line PARAMS ((bfd *,
+ asection *,
+ asymbol **,
+ bfd_vma offset,
+ CONST char **filename_ptr,
+ CONST char **functionname_ptr,
+ unsigned int *line_ptr));
+extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc));
+extern boolean bfd_coff_reloc16_relax_section
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
+extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
+ PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, boolean relocateable, asymbol **));
+extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
+ struct bfd_link_info *,
+ asection *));
+extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip,
+ asection *input_section,
+ bfd_vma val));
+
+/* Functions and types in cofflink.c. */
+
+#define STRING_SIZE_SIZE (4)
+
+/* We use a hash table to merge identical enum, struct, and union
+ definitions in the linker. */
+
+/* Information we keep for a single element (an enum value, a
+ structure or union field) in the debug merge hash table. */
+
+struct coff_debug_merge_element
+{
+ /* Next element. */
+ struct coff_debug_merge_element *next;
+
+ /* Name. */
+ const char *name;
+
+ /* Type. */
+ unsigned int type;
+
+ /* Symbol index for complex type. */
+ long tagndx;
+};
+
+/* A linked list of debug merge entries for a given name. */
+
+struct coff_debug_merge_type
+{
+ /* Next type with the same name. */
+ struct coff_debug_merge_type *next;
+
+ /* Class of type. */
+ int class;
+
+ /* Symbol index where this type is defined. */
+ long indx;
+
+ /* List of elements. */
+ struct coff_debug_merge_element *elements;
+};
+
+/* Information we store in the debug merge hash table. */
+
+struct coff_debug_merge_hash_entry
+{
+ struct bfd_hash_entry root;
+
+ /* A list of types with this name. */
+ struct coff_debug_merge_type *types;
+};
+
+/* The debug merge hash table. */
+
+struct coff_debug_merge_hash_table
+{
+ struct bfd_hash_table root;
+};
+
+/* Initialize a COFF debug merge hash table. */
+
+#define coff_debug_merge_hash_table_init(table) \
+ (bfd_hash_table_init (&(table)->root, _bfd_coff_debug_merge_hash_newfunc))
+
+/* Free a COFF debug merge hash table. */
+
+#define coff_debug_merge_hash_table_free(table) \
+ (bfd_hash_table_free (&(table)->root))
+
+/* Look up an entry in a COFF debug merge hash table. */
+
+#define coff_debug_merge_hash_lookup(table, string, create, copy) \
+ ((struct coff_debug_merge_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* Information we keep for each section in the output file when doing
+ a relocateable link. */
+
+struct coff_link_section_info
+{
+ /* The relocs to be output. */
+ struct internal_reloc *relocs;
+ /* For each reloc against a global symbol whose index was not known
+ when the reloc was handled, the global hash table entry. */
+ struct coff_link_hash_entry **rel_hashes;
+};
+
+/* Information that we pass around while doing the final link step. */
+
+struct coff_final_link_info
+{
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* Used to indicate failure in traversal routine. */
+ boolean failed;
+ /* If doing "task linking" set only during the time when we want the
+ global symbol writer to convert the storage class of defined global
+ symbols from global to static. */
+ boolean global_to_static;
+ /* Hash table for long symbol names. */
+ struct bfd_strtab_hash *strtab;
+ /* When doing a relocateable link, an array of information kept for
+ each output section, indexed by the target_index field. */
+ struct coff_link_section_info *section_info;
+ /* Symbol index of last C_FILE symbol (-1 if none). */
+ long last_file_index;
+ /* Contents of last C_FILE symbol. */
+ struct internal_syment last_file;
+ /* Symbol index of first aux entry of last .bf symbol with an empty
+ endndx field (-1 if none). */
+ long last_bf_index;
+ /* Contents of last_bf_index aux entry. */
+ union internal_auxent last_bf;
+ /* Hash table used to merge debug information. */
+ struct coff_debug_merge_hash_table debug_merge;
+ /* Buffer large enough to hold swapped symbols of any input file. */
+ struct internal_syment *internal_syms;
+ /* Buffer large enough to hold sections of symbols of any input file. */
+ asection **sec_ptrs;
+ /* Buffer large enough to hold output indices of symbols of any
+ input file. */
+ long *sym_indices;
+ /* Buffer large enough to hold output symbols for any input file. */
+ bfd_byte *outsyms;
+ /* Buffer large enough to hold external line numbers for any input
+ section. */
+ bfd_byte *linenos;
+ /* Buffer large enough to hold any input section. */
+ bfd_byte *contents;
+ /* Buffer large enough to hold external relocs of any input section. */
+ bfd_byte *external_relocs;
+ /* Buffer large enough to hold swapped relocs of any input section. */
+ struct internal_reloc *internal_relocs;
+};
+
+extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+extern boolean _bfd_coff_link_hash_table_init
+ PARAMS ((struct coff_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create
+ PARAMS ((bfd *));
+extern const char *_bfd_coff_internal_syment_name
+ PARAMS ((bfd *, const struct internal_syment *, char *));
+extern boolean _bfd_coff_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_coff_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern struct internal_reloc *_bfd_coff_read_internal_relocs
+ PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean,
+ struct internal_reloc *));
+extern boolean _bfd_coff_generic_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+extern struct bfd_hash_entry *_bfd_coff_debug_merge_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+extern boolean _bfd_coff_write_global_sym
+ PARAMS ((struct coff_link_hash_entry *, PTR));
+extern boolean _bfd_coff_write_task_globals
+ PARAMS ((struct coff_link_hash_entry *, PTR));
+extern boolean _bfd_coff_link_input_bfd
+ PARAMS ((struct coff_final_link_info *, bfd *));
+extern boolean _bfd_coff_reloc_link_order
+ PARAMS ((bfd *, struct coff_final_link_info *, asection *,
+ struct bfd_link_order *));
+
+
+#define coff_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+/* Functions in xcofflink.c. */
+
+extern long _bfd_xcoff_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
+extern long _bfd_xcoff_canonicalize_dynamic_symtab
+ PARAMS ((bfd *, asymbol **));
+extern long _bfd_xcoff_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
+extern long _bfd_xcoff_canonicalize_dynamic_reloc
+ PARAMS ((bfd *, arelent **, asymbol **));
+extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
+ PARAMS ((bfd *));
+extern boolean _bfd_xcoff_bfd_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_xcoff_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_ppc_xcoff_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+/* Functions in coff-ppc.c. FIXME: These are called be pe.em in the
+ linker, and so should start with bfd and be declared in bfd.h. */
+
+extern boolean ppc_allocate_toc_section PARAMS ((struct bfd_link_info *));
+extern boolean ppc_process_before_allocation
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* And more taken from the source .. */
+
+typedef struct coff_ptr_struct
+{
+
+ /* Remembers the offset from the first symbol in the file for
+ this symbol. Generated by coff_renumber_symbols. */
+unsigned int offset;
+
+ /* Should the value of this symbol be renumbered. Used for
+ XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */
+unsigned int fix_value : 1;
+
+ /* Should the tag field of this symbol be renumbered.
+ Created by coff_pointerize_aux. */
+unsigned int fix_tag : 1;
+
+ /* Should the endidx field of this symbol be renumbered.
+ Created by coff_pointerize_aux. */
+unsigned int fix_end : 1;
+
+ /* Should the x_csect.x_scnlen field be renumbered.
+ Created by coff_pointerize_aux. */
+unsigned int fix_scnlen : 1;
+
+ /* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the
+ index into the line number entries. Set by
+ coff_slurp_symbol_table. */
+unsigned int fix_line : 1;
+
+ /* The container for the symbol structure as read and translated
+ from the file. */
+
+union {
+ union internal_auxent auxent;
+ struct internal_syment syment;
+ } u;
+} combined_entry_type;
+
+
+ /* Each canonical asymbol really looks like this: */
+
+typedef struct coff_symbol_struct
+{
+ /* The actual symbol which the rest of BFD works with */
+asymbol symbol;
+
+ /* A pointer to the hidden information for this symbol */
+combined_entry_type *native;
+
+ /* A pointer to the linenumber information for this symbol */
+struct lineno_cache_entry *lineno;
+
+ /* Have the line numbers been relocated yet ? */
+boolean done_lineno;
+} coff_symbol_type;
+typedef struct
+{
+ void (*_bfd_coff_swap_aux_in) PARAMS ((
+ bfd *abfd,
+ PTR ext,
+ int type,
+ int class,
+ int indaux,
+ int numaux,
+ PTR in));
+
+ void (*_bfd_coff_swap_sym_in) PARAMS ((
+ bfd *abfd ,
+ PTR ext,
+ PTR in));
+
+ void (*_bfd_coff_swap_lineno_in) PARAMS ((
+ bfd *abfd,
+ PTR ext,
+ PTR in));
+
+ unsigned int (*_bfd_coff_swap_aux_out) PARAMS ((
+ bfd *abfd,
+ PTR in,
+ int type,
+ int class,
+ int indaux,
+ int numaux,
+ PTR ext));
+
+ unsigned int (*_bfd_coff_swap_sym_out) PARAMS ((
+ bfd *abfd,
+ PTR in,
+ PTR ext));
+
+ unsigned int (*_bfd_coff_swap_lineno_out) PARAMS ((
+ bfd *abfd,
+ PTR in,
+ PTR ext));
+
+ unsigned int (*_bfd_coff_swap_reloc_out) PARAMS ((
+ bfd *abfd,
+ PTR src,
+ PTR dst));
+
+ unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS ((
+ bfd *abfd,
+ PTR in,
+ PTR out));
+
+ unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS ((
+ bfd *abfd,
+ PTR in,
+ PTR out));
+
+ unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS ((
+ bfd *abfd,
+ PTR in,
+ PTR out));
+
+ unsigned int _bfd_filhsz;
+ unsigned int _bfd_aoutsz;
+ unsigned int _bfd_scnhsz;
+ unsigned int _bfd_symesz;
+ unsigned int _bfd_auxesz;
+ unsigned int _bfd_relsz;
+ unsigned int _bfd_linesz;
+ boolean _bfd_coff_long_filenames;
+ boolean _bfd_coff_long_section_names;
+ unsigned int _bfd_coff_default_section_alignment_power;
+ void (*_bfd_coff_swap_filehdr_in) PARAMS ((
+ bfd *abfd,
+ PTR ext,
+ PTR in));
+ void (*_bfd_coff_swap_aouthdr_in) PARAMS ((
+ bfd *abfd,
+ PTR ext,
+ PTR in));
+ void (*_bfd_coff_swap_scnhdr_in) PARAMS ((
+ bfd *abfd,
+ PTR ext,
+ PTR in));
+ void (*_bfd_coff_swap_reloc_in) PARAMS ((
+ bfd *abfd,
+ PTR ext,
+ PTR in));
+ boolean (*_bfd_coff_bad_format_hook) PARAMS ((
+ bfd *abfd,
+ PTR internal_filehdr));
+ boolean (*_bfd_coff_set_arch_mach_hook) PARAMS ((
+ bfd *abfd,
+ PTR internal_filehdr));
+ PTR (*_bfd_coff_mkobject_hook) PARAMS ((
+ bfd *abfd,
+ PTR internal_filehdr,
+ PTR internal_aouthdr));
+ flagword (*_bfd_styp_to_sec_flags_hook) PARAMS ((
+ bfd *abfd,
+ PTR internal_scnhdr,
+ const char *name));
+ void (*_bfd_set_alignment_hook) PARAMS ((
+ bfd *abfd,
+ asection *sec,
+ PTR internal_scnhdr));
+ boolean (*_bfd_coff_slurp_symbol_table) PARAMS ((
+ bfd *abfd));
+ boolean (*_bfd_coff_symname_in_debug) PARAMS ((
+ bfd *abfd,
+ struct internal_syment *sym));
+ boolean (*_bfd_coff_pointerize_aux_hook) PARAMS ((
+ bfd *abfd,
+ combined_entry_type *table_base,
+ combined_entry_type *symbol,
+ unsigned int indaux,
+ combined_entry_type *aux));
+ boolean (*_bfd_coff_print_aux) PARAMS ((
+ bfd *abfd,
+ FILE *file,
+ combined_entry_type *table_base,
+ combined_entry_type *symbol,
+ combined_entry_type *aux,
+ unsigned int indaux));
+ void (*_bfd_coff_reloc16_extra_cases) PARAMS ((
+ bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ arelent *reloc,
+ bfd_byte *data,
+ unsigned int *src_ptr,
+ unsigned int *dst_ptr));
+ int (*_bfd_coff_reloc16_estimate) PARAMS ((
+ bfd *abfd,
+ asection *input_section,
+ arelent *r,
+ unsigned int shrink,
+ struct bfd_link_info *link_info));
+ boolean (*_bfd_coff_sym_is_global) PARAMS ((
+ bfd *abfd,
+ struct internal_syment *));
+ boolean (*_bfd_coff_compute_section_file_positions) PARAMS ((
+ bfd *abfd));
+ boolean (*_bfd_coff_start_final_link) PARAMS ((
+ bfd *output_bfd,
+ struct bfd_link_info *info));
+ boolean (*_bfd_coff_relocate_section) PARAMS ((
+ bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ struct internal_reloc *relocs,
+ struct internal_syment *syms,
+ asection **sections));
+ reloc_howto_type *(*_bfd_coff_rtype_to_howto) PARAMS ((
+ bfd *abfd,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h,
+ struct internal_syment *sym,
+ bfd_vma *addendp));
+ boolean (*_bfd_coff_adjust_symndx) PARAMS ((
+ bfd *obfd,
+ struct bfd_link_info *info,
+ bfd *ibfd,
+ asection *sec,
+ struct internal_reloc *reloc,
+ boolean *adjustedp));
+ boolean (*_bfd_coff_link_add_one_symbol) PARAMS ((
+ struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ boolean copy,
+ boolean collect,
+ struct bfd_link_hash_entry **hashp));
+
+ boolean (*_bfd_coff_link_output_has_begun) PARAMS ((
+ bfd * abfd,
+ struct coff_final_link_info * pfinfo));
+ boolean (*_bfd_coff_final_link_postscript) PARAMS ((
+ bfd * abfd,
+ struct coff_final_link_info * pfinfo));
+
+} bfd_coff_backend_data;
+
+#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data)
+
+#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \
+ ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i))
+
+#define bfd_coff_swap_sym_in(a,e,i) \
+ ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))
+
+#define bfd_coff_swap_lineno_in(a,e,i) \
+ ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i))
+
+#define bfd_coff_swap_reloc_out(abfd, i, o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o))
+
+#define bfd_coff_swap_lineno_out(abfd, i, o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o))
+
+#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \
+ ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o))
+
+#define bfd_coff_swap_sym_out(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))
+
+#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o))
+
+#define bfd_coff_swap_filehdr_out(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o))
+
+#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o))
+
+#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz)
+#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz)
+#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz)
+#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz)
+#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz)
+#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz)
+#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz)
+#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames)
+#define bfd_coff_long_section_names(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_long_section_names)
+#define bfd_coff_default_section_alignment_power(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
+#define bfd_coff_swap_filehdr_in(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o))
+
+#define bfd_coff_swap_aouthdr_in(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o))
+
+#define bfd_coff_swap_scnhdr_in(abfd, i,o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o))
+
+#define bfd_coff_swap_reloc_in(abfd, i, o) \
+ ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o))
+
+#define bfd_coff_bad_format_hook(abfd, filehdr) \
+ ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr))
+
+#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\
+ ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr))
+#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\
+ ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr))
+
+#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name)\
+ ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr, name))
+
+#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\
+ ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr))
+
+#define bfd_coff_slurp_symbol_table(abfd)\
+ ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd))
+
+#define bfd_coff_symname_in_debug(abfd, sym)\
+ ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym))
+
+#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\
+ ((coff_backend_info (abfd)->_bfd_coff_print_aux)\
+ (abfd, file, base, symbol, aux, indaux))
+
+#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)\
+ ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
+ (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr))
+
+#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\
+ ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
+ (abfd, section, reloc, shrink, link_info))
+
+#define bfd_coff_sym_is_global(abfd, sym)\
+ ((coff_backend_info (abfd)->_bfd_coff_sym_is_global)\
+ (abfd, sym))
+
+#define bfd_coff_compute_section_file_positions(abfd)\
+ ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\
+ (abfd))
+
+#define bfd_coff_start_final_link(obfd, info)\
+ ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\
+ (obfd, info))
+#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\
+ ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\
+ (obfd, info, ibfd, o, con, rel, isyms, secs))
+#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\
+ ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\
+ (abfd, sec, rel, h, sym, addendp))
+#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
+ ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
+ (obfd, info, ibfd, sec, rel, adjustedp))
+#define bfd_coff_link_add_one_symbol(info,abfd,name,flags,section,value,string,cp,coll,hashp)\
+ ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
+ (info, abfd, name, flags, section, value, string, cp, coll, hashp))
+
+#define bfd_coff_link_output_has_begun(a,p) \
+ ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a,p))
+#define bfd_coff_final_link_postscript(a,p) \
+ ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a,p))
+
diff --git a/bfd/libecoff.h b/bfd/libecoff.h
new file mode 100644
index 00000000000..ad269a52f5d
--- /dev/null
+++ b/bfd/libecoff.h
@@ -0,0 +1,357 @@
+/* BFD ECOFF object file private structure.
+ Copyright (C) 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfdlink.h"
+
+#ifndef ECOFF_H
+#include "coff/ecoff.h"
+#endif
+
+/* This is the backend information kept for ECOFF files. This
+ structure is constant for a particular backend. The first element
+ is the COFF backend data structure, so that ECOFF targets can use
+ the generic COFF code. */
+
+#define ecoff_backend(abfd) \
+ ((struct ecoff_backend_data *) (abfd)->xvec->backend_data)
+
+struct ecoff_backend_data
+{
+ /* COFF backend information. This must be the first field. */
+ bfd_coff_backend_data coff;
+ /* Supported architecture. */
+ enum bfd_architecture arch;
+ /* Initial portion of armap string. */
+ const char *armap_start;
+ /* The page boundary used to align sections in a demand-paged
+ executable file. E.g., 0x1000. */
+ bfd_vma round;
+ /* True if the .rdata section is part of the text segment, as on the
+ Alpha. False if .rdata is part of the data segment, as on the
+ MIPS. */
+ boolean rdata_in_text;
+ /* Bitsize of constructor entries. */
+ unsigned int constructor_bitsize;
+ /* Reloc to use for constructor entries. */
+ reloc_howto_type *constructor_reloc;
+ /* How to swap debugging information. */
+ struct ecoff_debug_swap debug_swap;
+ /* External reloc size. */
+ bfd_size_type external_reloc_size;
+ /* Reloc swapping functions. */
+ void (*swap_reloc_in) PARAMS ((bfd *, PTR, struct internal_reloc *));
+ void (*swap_reloc_out) PARAMS ((bfd *, const struct internal_reloc *, PTR));
+ /* Backend reloc tweaking. */
+ void (*adjust_reloc_in) PARAMS ((bfd *, const struct internal_reloc *,
+ arelent *));
+ void (*adjust_reloc_out) PARAMS ((bfd *, const arelent *,
+ struct internal_reloc *));
+ /* Relocate section contents while linking. */
+ boolean (*relocate_section) PARAMS ((bfd *output_bfd, struct bfd_link_info *,
+ bfd *input_bfd, asection *input_section,
+ bfd_byte *contents,
+ PTR external_relocs));
+ /* Do final adjustments to filehdr and aouthdr. */
+ boolean (*adjust_headers) PARAMS ((bfd *, struct internal_filehdr *,
+ struct internal_aouthdr *));
+ /* Read an element from an archive at a given file position. This
+ is needed because OSF/1 3.2 uses a weird archive format. */
+ bfd *(*get_elt_at_filepos) PARAMS ((bfd *, file_ptr));
+};
+
+/* This is the target specific information kept for ECOFF files. */
+
+#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data)
+
+typedef struct ecoff_tdata
+{
+ /* The reloc file position, set by
+ ecoff_compute_section_file_positions. */
+ file_ptr reloc_filepos;
+
+ /* The symbol table file position, set by _bfd_ecoff_mkobject_hook. */
+ file_ptr sym_filepos;
+
+ /* The start and end of the text segment. Only valid for an
+ existing file, not for one we are creating. */
+ unsigned long text_start;
+ unsigned long text_end;
+
+ /* The cached gp value. This is used when relocating. */
+ bfd_vma gp;
+
+ /* The maximum size of objects to optimize using gp. This is
+ typically set by the -G option to the compiler, assembler or
+ linker. */
+ unsigned int gp_size;
+
+ /* The register masks. When linking, all the masks found in the
+ input files are combined into the masks of the output file.
+ These are not all used for all targets, but that's OK, because
+ the relevant ones are the only ones swapped in and out. */
+ unsigned long gprmask;
+ unsigned long fprmask;
+ unsigned long cprmask[4];
+
+ /* The ECOFF symbolic debugging information. */
+ struct ecoff_debug_info debug_info;
+
+ /* The unswapped ECOFF symbolic information. */
+ PTR raw_syments;
+
+ /* The canonical BFD symbols. */
+ struct ecoff_symbol_struct *canonical_symbols;
+
+ /* A mapping from external symbol numbers to entries in the linker
+ hash table, used when linking. */
+ struct ecoff_link_hash_entry **sym_hashes;
+
+ /* A mapping from reloc symbol indices to sections, used when
+ linking. */
+ asection **symndx_to_section;
+
+ /* True if this BFD was written by the backend linker. */
+ boolean linker;
+
+ /* True if a warning that multiple global pointer values are
+ needed in the output binary was issued already. */
+ boolean issued_multiple_gp_warning;
+
+ /* Used by find_nearest_line entry point. The structure could be
+ included directly in this one, but there's no point to wasting
+ the memory just for the infrequently called find_nearest_line. */
+ struct ecoff_find_line *find_line_info;
+
+ /* Whether the .rdata section is in the text segment for this
+ particular ECOFF file. This is not valid until
+ ecoff_compute_section_file_positions is called. */
+ boolean rdata_in_text;
+
+} ecoff_data_type;
+
+/* Each canonical asymbol really looks like this. */
+
+typedef struct ecoff_symbol_struct
+{
+ /* The actual symbol which the rest of BFD works with */
+ asymbol symbol;
+
+ /* The fdr for this symbol. */
+ FDR *fdr;
+
+ /* true if this is a local symbol rather than an external one. */
+ boolean local;
+
+ /* A pointer to the unswapped hidden information for this symbol.
+ This is either a struct sym_ext or a struct ext_ext, depending on
+ the value of the local field above. */
+ PTR native;
+} ecoff_symbol_type;
+
+/* We take the address of the first element of a asymbol to ensure that the
+ macro is only ever applied to an asymbol. */
+#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd)))
+
+/* We need to save the index of an external symbol when we write it
+ out so that can set the symbol index correctly when we write out
+ the relocs. */
+#define ecoff_get_sym_index(symbol) ((symbol)->udata.i)
+#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata.i = (idx))
+
+/* When generating MIPS embedded PIC code, the linker relaxes the code
+ to turn PC relative branches into longer code sequences when the PC
+ relative branch is out of range. This involves reading the relocs
+ in bfd_relax_section as well as in bfd_final_link, and requires the
+ code to keep track of which relocs have been expanded. A pointer
+ to this structure is put in the used_by_bfd pointer of a section to
+ keep track of this information. The user_by_bfd pointer will be
+ NULL if the information was not needed. */
+
+struct ecoff_section_tdata
+{
+ /* The unswapped relocs for this section. These are stored in
+ memory so the input file does not have to be read twice. */
+ PTR external_relocs;
+
+ /* The contents of the section. These bytes may or may not be saved
+ in memory, but if it is this is a pointer to them. */
+ bfd_byte *contents;
+
+ /* Offset adjustments for PC relative branches. A number other than
+ 1 is an addend for a PC relative branch, or a switch table entry
+ which is the difference of two .text locations; this addend
+ arises because the branch or difference crosses one or more
+ branches which were expanded into a larger code sequence. A 1
+ means that this branch was itself expanded into a larger code
+ sequence. 1 is not a possible offset, since all offsets must be
+ multiples of the instruction size, which is 4; also, the only
+ relocs with non-zero offsets will be PC relative branches or
+ switch table entries within the same object file. If this field
+ is NULL, no branches were expanded and no offsets are required.
+ Otherwise there are as many entries as there are relocs in the
+ section, and the entry for any reloc that is not PC relative is
+ zero. */
+ long *offsets;
+
+ /* When producing an executable (i.e., final, non-relocatable link)
+ on the Alpha, we may need to use multiple global pointer values
+ to span the entire .lita section. In essence, we allow each
+ input .lita section to have its own gp value. To support this,
+ we need to keep track of the gp values that we picked for each
+ input .lita section . */
+ bfd_vma gp;
+};
+
+/* An accessor macro for the ecoff_section_tdata structure. */
+#define ecoff_section_data(abfd, sec) \
+ ((struct ecoff_section_tdata *) (sec)->used_by_bfd)
+
+/* ECOFF linker hash table entries. */
+
+struct ecoff_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+ /* Symbol index in output file. */
+ long indx;
+ /* BFD that ext field value came from. */
+ bfd *abfd;
+ /* ECOFF external symbol information. */
+ EXTR esym;
+ /* Nonzero if this symbol has been written out. */
+ char written;
+ /* Nonzero if this symbol was referred to as small undefined. */
+ char small;
+};
+
+/* ECOFF linker hash table. */
+
+struct ecoff_link_hash_table
+{
+ struct bfd_link_hash_table root;
+};
+
+/* Make an ECOFF object. */
+extern boolean _bfd_ecoff_mkobject PARAMS ((bfd *));
+
+/* Read in the ECOFF symbolic debugging information. */
+extern boolean _bfd_ecoff_slurp_symbolic_info
+ PARAMS ((bfd *, asection *, struct ecoff_debug_info *));
+
+/* Generic ECOFF BFD backend vectors. */
+
+extern boolean _bfd_ecoff_write_object_contents PARAMS ((bfd *abfd));
+extern const bfd_target *_bfd_ecoff_archive_p PARAMS ((bfd *abfd));
+
+#define _bfd_ecoff_close_and_cleanup _bfd_generic_close_and_cleanup
+#define _bfd_ecoff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+extern boolean _bfd_ecoff_new_section_hook
+ PARAMS ((bfd *, asection *));
+extern boolean _bfd_ecoff_get_section_contents
+ PARAMS ((bfd *, asection *, PTR location, file_ptr, bfd_size_type));
+
+#define _bfd_ecoff_bfd_link_split_section _bfd_generic_link_split_section
+
+extern boolean _bfd_ecoff_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+#define _bfd_ecoff_bfd_copy_private_section_data \
+ _bfd_generic_bfd_copy_private_section_data
+
+#define _bfd_ecoff_bfd_copy_private_symbol_data \
+ _bfd_generic_bfd_copy_private_symbol_data
+
+#define _bfd_ecoff_bfd_print_private_bfd_data \
+ _bfd_generic_bfd_print_private_bfd_data
+
+#define _bfd_ecoff_bfd_merge_private_bfd_data \
+ _bfd_generic_bfd_merge_private_bfd_data
+
+#define _bfd_ecoff_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+extern boolean _bfd_ecoff_slurp_armap PARAMS ((bfd *abfd));
+#define _bfd_ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table
+#define _bfd_ecoff_construct_extended_name_table \
+ _bfd_archive_bsd_construct_extended_name_table
+#define _bfd_ecoff_truncate_arname bfd_dont_truncate_arname
+extern boolean _bfd_ecoff_write_armap
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
+#define _bfd_ecoff_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_ecoff_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_ecoff_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define _bfd_ecoff_update_armap_timestamp bfd_true
+
+extern long _bfd_ecoff_get_symtab_upper_bound PARAMS ((bfd *abfd));
+extern long _bfd_ecoff_get_symtab PARAMS ((bfd *abfd, asymbol **alocation));
+extern asymbol *_bfd_ecoff_make_empty_symbol PARAMS ((bfd *abfd));
+extern void _bfd_ecoff_print_symbol
+ PARAMS ((bfd *, PTR filep, asymbol *, bfd_print_symbol_type));
+extern void _bfd_ecoff_get_symbol_info
+ PARAMS ((bfd *, asymbol *, symbol_info *));
+extern boolean _bfd_ecoff_bfd_is_local_label_name
+ PARAMS ((bfd *, const char *));
+#define _bfd_ecoff_get_lineno _bfd_nosymbols_get_lineno
+extern boolean _bfd_ecoff_find_nearest_line
+ PARAMS ((bfd *, asection *, asymbol **, bfd_vma offset,
+ const char **filename_ptr, const char **fnname_ptr,
+ unsigned int *retline_ptr));
+#define _bfd_ecoff_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define _bfd_ecoff_read_minisymbols _bfd_generic_read_minisymbols
+#define _bfd_ecoff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define _bfd_ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound
+extern long _bfd_ecoff_canonicalize_reloc
+ PARAMS ((bfd *, asection *, arelent **, asymbol **symbols));
+/* ecoff_bfd_reloc_type_lookup defined by backend. */
+
+extern boolean _bfd_ecoff_set_arch_mach
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long machine));
+extern boolean _bfd_ecoff_set_section_contents
+ PARAMS ((bfd *, asection *, PTR location, file_ptr, bfd_size_type));
+
+extern int _bfd_ecoff_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
+/* ecoff_bfd_get_relocated_section_contents defined by backend. */
+/* ecoff_bfd_relax_section defined by backend. */
+extern struct bfd_link_hash_table *_bfd_ecoff_bfd_link_hash_table_create
+ PARAMS ((bfd *));
+extern boolean _bfd_ecoff_bfd_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+extern boolean _bfd_ecoff_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Hook functions for the generic COFF section reading code. */
+
+extern PTR _bfd_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
+#define _bfd_ecoff_set_alignment_hook \
+ ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
+extern boolean _bfd_ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr));
+extern flagword _bfd_ecoff_styp_to_sec_flags
+ PARAMS ((bfd *abfd, PTR hdr, const char *name));
+extern boolean _bfd_ecoff_slurp_symbol_table PARAMS ((bfd *abfd));
+
+/* ECOFF auxiliary information swapping routines. These are the same
+ for all ECOFF targets, so they are defined in ecofflink.c. */
+
+extern void _bfd_ecoff_swap_tir_in
+ PARAMS ((int, const struct tir_ext *, TIR *));
+extern void _bfd_ecoff_swap_tir_out
+ PARAMS ((int, const TIR *, struct tir_ext *));
+extern void _bfd_ecoff_swap_rndx_in
+ PARAMS ((int, const struct rndx_ext *, RNDXR *));
+extern void _bfd_ecoff_swap_rndx_out
+ PARAMS ((int, const RNDXR *, struct rndx_ext *));
diff --git a/bfd/libhppa.h b/bfd/libhppa.h
new file mode 100644
index 00000000000..35b40efe86e
--- /dev/null
+++ b/bfd/libhppa.h
@@ -0,0 +1,700 @@
+/* HP PA-RISC SOM object file format: definitions internal to BFD.
+ Copyright (C) 1990, 91, 92, 93, 94 , 95, 1996 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _HPPA_H
+#define _HPPA_H
+
+#define BYTES_IN_WORD 4
+#define PA_PAGESIZE 0x1000
+
+#ifndef INLINE
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif /* GNU C? */
+#endif /* INLINE */
+
+#if __GNUC__ >= 2 && __GNUC_MINOR__ >= 7
+/* Declare the functions with the unused attribute to avoid warnings. */
+static INLINE unsigned int assemble_3 (unsigned int)
+ __attribute__ ((__unused__));
+static INLINE void dis_assemble_3 (unsigned int, unsigned int *)
+ __attribute__ ((__unused__));
+static INLINE unsigned int assemble_12 (unsigned int, unsigned int)
+ __attribute__ ((__unused__));
+static INLINE void dis_assemble_12 (unsigned int, unsigned int *,
+ unsigned int *)
+ __attribute__ ((__unused__));
+static INLINE unsigned long assemble_17 (unsigned int, unsigned int,
+ unsigned int)
+ __attribute__ ((__unused__));
+static INLINE void dis_assemble_17 (unsigned int, unsigned int *,
+ unsigned int *, unsigned int *)
+ __attribute__ ((__unused__));
+static INLINE unsigned long assemble_21 (unsigned int)
+ __attribute ((__unused__));
+static INLINE void dis_assemble_21 (unsigned int, unsigned int *)
+ __attribute__ ((__unused__));
+static INLINE unsigned long sign_extend (unsigned int, unsigned int)
+ __attribute__ ((__unused__));
+static INLINE unsigned int ones (int) __attribute ((__unused__));
+static INLINE void sign_unext (unsigned int, unsigned int, unsigned int *)
+ __attribute__ ((__unused__));
+static INLINE unsigned long low_sign_extend (unsigned int, unsigned int)
+ __attribute__ ((__unused__));
+static INLINE void low_sign_unext (unsigned int, unsigned int, unsigned int *)
+ __attribute__ ((__unused__));
+static INLINE unsigned long hppa_field_adjust (unsigned long, unsigned long,
+ unsigned short)
+ __attribute__ ((__unused__));
+static INLINE char bfd_hppa_insn2fmt (unsigned long)
+ __attribute__ ((__unused__));
+static INLINE unsigned long hppa_rebuild_insn (bfd *, unsigned long,
+ unsigned long, unsigned long)
+ __attribute__ ((__unused__));
+#endif /* gcc 2.7 or higher */
+
+
+/* The PA instruction set variants. */
+enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20};
+
+/* HP PA-RISC relocation types */
+
+enum hppa_reloc_field_selector_type
+ {
+ R_HPPA_FSEL = 0x0,
+ R_HPPA_LSSEL = 0x1,
+ R_HPPA_RSSEL = 0x2,
+ R_HPPA_LSEL = 0x3,
+ R_HPPA_RSEL = 0x4,
+ R_HPPA_LDSEL = 0x5,
+ R_HPPA_RDSEL = 0x6,
+ R_HPPA_LRSEL = 0x7,
+ R_HPPA_RRSEL = 0x8,
+ R_HPPA_NSEL = 0x9,
+ R_HPPA_NLSEL = 0xa,
+ R_HPPA_NLRSEL = 0xb,
+ R_HPPA_PSEL = 0xc,
+ R_HPPA_LPSEL = 0xd,
+ R_HPPA_RPSEL = 0xe,
+ R_HPPA_TSEL = 0xf,
+ R_HPPA_LTSEL = 0x10,
+ R_HPPA_RTSEL = 0x11
+ };
+
+/* /usr/include/reloc.h defines these to constants. We want to use
+ them in enums, so #undef them before we start using them. We might
+ be able to fix this another way by simply managing not to include
+ /usr/include/reloc.h, but currently GDB picks up these defines
+ somewhere. */
+#undef e_fsel
+#undef e_lssel
+#undef e_rssel
+#undef e_lsel
+#undef e_rsel
+#undef e_ldsel
+#undef e_rdsel
+#undef e_lrsel
+#undef e_rrsel
+#undef e_nsel
+#undef e_nlsel
+#undef e_nlrsel
+#undef e_psel
+#undef e_lpsel
+#undef e_rpsel
+#undef e_tsel
+#undef e_ltsel
+#undef e_rtsel
+#undef e_one
+#undef e_two
+#undef e_pcrel
+#undef e_con
+#undef e_plabel
+#undef e_abs
+
+/* for compatibility */
+enum hppa_reloc_field_selector_type_alt
+ {
+ e_fsel = R_HPPA_FSEL,
+ e_lssel = R_HPPA_LSSEL,
+ e_rssel = R_HPPA_RSSEL,
+ e_lsel = R_HPPA_LSEL,
+ e_rsel = R_HPPA_RSEL,
+ e_ldsel = R_HPPA_LDSEL,
+ e_rdsel = R_HPPA_RDSEL,
+ e_lrsel = R_HPPA_LRSEL,
+ e_rrsel = R_HPPA_RRSEL,
+ e_nsel = R_HPPA_NSEL,
+ e_nlsel = R_HPPA_NLSEL,
+ e_nlrsel = R_HPPA_NLRSEL,
+ e_psel = R_HPPA_PSEL,
+ e_lpsel = R_HPPA_LPSEL,
+ e_rpsel = R_HPPA_RPSEL,
+ e_tsel = R_HPPA_TSEL,
+ e_ltsel = R_HPPA_LTSEL,
+ e_rtsel = R_HPPA_RTSEL
+ };
+
+enum hppa_reloc_expr_type
+ {
+ R_HPPA_E_ONE = 0,
+ R_HPPA_E_TWO = 1,
+ R_HPPA_E_PCREL = 2,
+ R_HPPA_E_CON = 3,
+ R_HPPA_E_PLABEL = 7,
+ R_HPPA_E_ABS = 18
+ };
+
+/* for compatibility */
+enum hppa_reloc_expr_type_alt
+ {
+ e_one = R_HPPA_E_ONE,
+ e_two = R_HPPA_E_TWO,
+ e_pcrel = R_HPPA_E_PCREL,
+ e_con = R_HPPA_E_CON,
+ e_plabel = R_HPPA_E_PLABEL,
+ e_abs = R_HPPA_E_ABS
+ };
+
+
+/* Relocations for function calls must be accompanied by parameter
+ relocation bits. These bits describe exactly where the caller has
+ placed the function's arguments and where it expects to find a return
+ value.
+
+ Both ELF and SOM encode this information within the addend field
+ of the call relocation. (Note this could break very badly if one
+ was to make a call like bl foo + 0x12345678).
+
+ The high order 10 bits contain parameter relocation information,
+ the low order 22 bits contain the constant offset. */
+
+#define HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF)
+#define HPPA_R_CONSTANT(a) ((((int)(a)) << 10) >> 10)
+#define HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF))
+#define HPPA_WIDE (0) /* PSW W-bit, need to check! FIXME */
+
+/* These macros get bit fields using HP's numbering (MSB = 0),
+ * but note that "MASK" assumes that the LSB bits are what's
+ * wanted.
+ */
+#ifndef GET_FIELD
+#define GET_FIELD(X, FROM, TO) \
+ ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
+#endif
+#define GET_BIT( X, WHICH ) \
+ GET_FIELD( X, WHICH, WHICH )
+
+#define MASK( SIZE ) \
+ (~((-1) << SIZE))
+
+#define CATENATE( X, XSIZE, Y, YSIZE ) \
+ (((X & MASK( XSIZE )) << YSIZE) | (Y & MASK( YSIZE )))
+
+#define ELEVEN( X ) \
+ CATENATE( GET_BIT( X, 10 ), 1, GET_FIELD( X, 0, 9 ), 10)
+
+/* Some functions to manipulate PA instructions. */
+
+/* NOTE: these use the HP convention that f{1} is the _left_ most
+ * bit (MSB) of f; they sometimes have to impose an assumption
+ * about the size of a field; and as far as I can tell, most
+ * aren't used.
+ */
+
+static INLINE unsigned long
+sign_extend (x, len)
+ unsigned int x, len;
+{
+ return (int)(x >> (len - 1) ? (-1 << len) | x : x);
+}
+
+static INLINE unsigned int
+assemble_3 (x)
+ unsigned int x;
+{
+ return (((x & 1) << 2) | ((x & 6) >> 1)) & 7;
+}
+
+static INLINE void
+dis_assemble_3 (x, r)
+ unsigned int x;
+ unsigned int *r;
+{
+ *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7;
+}
+
+static INLINE unsigned int /* PA 2.0 */
+assemble_6 (x, y)
+ unsigned int x, y;
+{
+ return (((x & 0x1) << 5) + (32 - (y & 0x1f)));
+}
+
+static INLINE unsigned int
+assemble_12 (x, y)
+ unsigned int x, y;
+{
+ return CATENATE( CATENATE( y, 1,
+ GET_BIT( x, 10 ), 1), 2,
+ GET_FIELD( x, 0, 9 ), 9);
+}
+
+static INLINE void
+dis_assemble_12 (as12, x, y)
+ unsigned int as12;
+ unsigned int *x, *y;
+{
+ *y = (as12 & 0x800) >> 11;
+ *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10);
+}
+
+static INLINE unsigned long /* PA 2.0 */
+assemble_16 (x, y)
+ unsigned int x, y;
+{
+ /* Depends on PSW W-bit !*/
+ unsigned int temp;
+
+ if( HPPA_WIDE ) {
+ temp = CATENATE( CATENATE( GET_BIT( y, 13 ), 1,
+ (GET_BIT( y, 13 )^GET_BIT( x, 0)), 1 ), 2,
+ CATENATE( (GET_BIT( y, 13 )^GET_BIT( x, 1)), 1,
+ GET_FIELD( y, 0, 12 ), 13 ), 14 );
+ }
+ else {
+ temp = CATENATE( CATENATE( GET_BIT( y, 13 ), 1,
+ GET_BIT( y, 13 ), 1 ), 2,
+ CATENATE( GET_BIT( y, 13 ), 1,
+ GET_FIELD( y, 0, 12 ), 13 ), 14 );
+ }
+
+ return sign_extend( temp, 16 );
+}
+
+
+static INLINE unsigned long /* PA 2.0 */
+assemble_16a (x, y, z)
+ unsigned int x, y, z;
+{
+ /* Depends on PSW W-bit !*/
+ unsigned int temp;
+
+ if( HPPA_WIDE ) {
+ temp = CATENATE( CATENATE( z, 1,
+ (z^GET_BIT( x, 0 )), 1), 2,
+
+ CATENATE( (z^GET_BIT( x, 1 )), 1,
+ y, 11), 12);
+ }
+ else {
+ temp = CATENATE( CATENATE( z, 1,
+ z, 1), 2,
+ CATENATE( z, 1,
+ y, 11), 12);
+
+ }
+
+ return sign_extend( (temp << 2), 16 );
+}
+
+static INLINE unsigned long
+assemble_17 (x, y, z)
+ unsigned int x, y, z;
+{
+ unsigned long temp;
+ int q;
+
+ temp = CATENATE( CATENATE( z, q,
+ x, q), q,
+ CATENATE( GET_BIT( y, 1 ), 1,
+ GET_FIELD( y, 0, 9 ), 10), 11);
+
+ return temp;
+}
+
+static INLINE void
+dis_assemble_17 (as17, x, y, z)
+ unsigned int as17;
+ unsigned int *x, *y, *z;
+{
+
+ *z = (as17 & 0x10000) >> 16;
+ *x = (as17 & 0x0f800) >> 11;
+ *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff;
+}
+
+static INLINE unsigned long
+assemble_21 (x)
+ unsigned int x;
+{
+ unsigned long temp;
+
+ temp = ((x & 1) << 20) |
+ ((x & 0xffe) << 8) |
+ ((x & 0xc000) >> 7) |
+ ((x & 0x1f0000) >> 14) |
+ ((x & 0x003000) >> 12);
+ return temp & 0x1fffff;
+}
+
+static INLINE unsigned long /* PA 2.0 */
+assemble_22 (a,b,c,d)
+ unsigned int a,b,c,d;
+{
+ unsigned long temp;
+
+ temp = CATENATE( CATENATE( d, 1,
+ a, 5 ), 6,
+ CATENATE( b, 5,
+ ELEVEN( c ), 11 ), 16 );
+
+ return sign_extend( temp, 22 );
+}
+
+static INLINE void
+dis_assemble_21 (as21, x)
+ unsigned int as21, *x;
+{
+ unsigned long temp;
+
+
+ temp = (as21 & 0x100000) >> 20;
+ temp |= (as21 & 0x0ffe00) >> 8;
+ temp |= (as21 & 0x000180) << 7;
+ temp |= (as21 & 0x00007c) << 14;
+ temp |= (as21 & 0x000003) << 12;
+ *x = temp;
+}
+
+static INLINE unsigned int
+ones (n)
+ int n;
+{
+ unsigned int len_ones;
+ int i;
+
+ i = 0;
+ len_ones = 0;
+ while (i < n)
+ {
+ len_ones = (len_ones << 1) | 1;
+ i++;
+ }
+
+ return len_ones;
+}
+
+static INLINE void
+sign_unext (x, len, result)
+ unsigned int x, len;
+ unsigned int *result;
+{
+ unsigned int len_ones;
+
+ len_ones = ones (len);
+
+ *result = x & len_ones;
+}
+
+static INLINE unsigned long
+low_sign_extend (x, len)
+ unsigned int x, len;
+{
+ return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1);
+}
+
+static INLINE void
+low_sign_unext (x, len, result)
+ unsigned int x, len;
+ unsigned int *result;
+{
+ unsigned int temp;
+ unsigned int sign;
+ unsigned int rest;
+ unsigned int one_bit_at_len;
+ unsigned int len_ones;
+
+ len_ones = ones (len);
+ one_bit_at_len = 1 << (len - 1);
+
+ sign_unext (x, len, &temp);
+ sign = temp & one_bit_at_len;
+ sign >>= (len - 1);
+
+ rest = temp & (len_ones ^ one_bit_at_len);
+ rest <<= 1;
+
+ *result = rest | sign;
+}
+
+/* Handle field selectors for PA instructions. */
+
+static INLINE unsigned long
+hppa_field_adjust (value, constant_value, r_field)
+ unsigned long value;
+ unsigned long constant_value;
+ unsigned short r_field;
+{
+ switch (r_field)
+ {
+ case e_fsel: /* F : no change */
+ case e_nsel: /* N : no change */
+ value += constant_value;
+ break;
+
+ case e_lssel: /* LS : if (bit 21) then add 0x800
+ arithmetic shift right 11 bits */
+ value += constant_value;
+ if (value & 0x00000400)
+ value += 0x800;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rssel: /* RS : Sign extend from bit 21 */
+ value += constant_value;
+ if (value & 0x00000400)
+ value |= 0xfffff800;
+ else
+ value &= 0x7ff;
+ break;
+
+ case e_lsel: /* L : Arithmetic shift right 11 bits */
+ case e_nlsel: /* NL : Arithmetic shift right 11 bits */
+ value += constant_value;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rsel: /* R : Set bits 0-20 to zero */
+ value += constant_value;
+ value = value & 0x7ff;
+ break;
+
+ case e_ldsel: /* LD : Add 0x800, arithmetic shift
+ right 11 bits */
+ value += constant_value;
+ value += 0x800;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rdsel: /* RD : Set bits 0-20 to one */
+ value += constant_value;
+ value |= 0xfffff800;
+ break;
+
+ case e_lrsel: /* LR : L with "rounded" constant */
+ case e_nlrsel: /* NLR : NL with "rounded" constant */
+ value = value + ((constant_value + 0x1000) & 0xffffe000);
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ case e_rrsel: /* RR : R with "rounded" constant */
+ value = value + ((constant_value + 0x1000) & 0xffffe000);
+ value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000);
+ break;
+
+ default:
+ abort ();
+ }
+ return value;
+
+}
+
+/* PA-RISC OPCODES */
+#define get_opcode(insn) ((insn) & 0xfc000000) >> 26
+
+/* FIXME: this list is incomplete. It should also be an enumerated
+ type rather than #defines. */
+
+#define LDO 0x0d
+#define LDB 0x10
+#define LDH 0x11
+#define LDW 0x12
+#define LDWM 0x13
+#define STB 0x18
+#define STH 0x19
+#define STW 0x1a
+#define STWM 0x1b
+#define COMICLR 0x24
+#define SUBI 0x25
+#define SUBIO 0x25
+#define ADDIT 0x2c
+#define ADDITO 0x2c
+#define ADDI 0x2d
+#define ADDIO 0x2d
+#define LDIL 0x08
+#define ADDIL 0x0a
+
+#define MOVB 0x32
+#define MOVIB 0x33
+#define COMBT 0x20
+#define COMBF 0x22
+#define COMIBT 0x21
+#define COMIBF 0x23
+#define ADDBT 0x28
+#define ADDBF 0x2a
+#define ADDIBT 0x29
+#define ADDIBF 0x2b
+#define BVB 0x30
+#define BB 0x31
+
+#define BL 0x3a
+#define BLE 0x39
+#define BE 0x38
+
+
+/* Given a machine instruction, return its format.
+
+ FIXME: opcodes which do not map to a known format
+ should return an error of some sort. */
+
+static INLINE char
+bfd_hppa_insn2fmt (insn)
+ unsigned long insn;
+{
+ char fmt = -1;
+ unsigned char op = get_opcode (insn);
+
+ switch (op)
+ {
+ case ADDI:
+ case ADDIT:
+ case SUBI:
+ fmt = 11;
+ break;
+ case MOVB:
+ case MOVIB:
+ case COMBT:
+ case COMBF:
+ case COMIBT:
+ case COMIBF:
+ case ADDBT:
+ case ADDBF:
+ case ADDIBT:
+ case ADDIBF:
+ case BVB:
+ case BB:
+ fmt = 12;
+ break;
+ case LDO:
+ case LDB:
+ case LDH:
+ case LDW:
+ case LDWM:
+ case STB:
+ case STH:
+ case STW:
+ case STWM:
+ fmt = 14;
+ break;
+ case BL:
+ case BE:
+ case BLE:
+ fmt = 17;
+ break;
+ case LDIL:
+ case ADDIL:
+ fmt = 21;
+ break;
+ default:
+ fmt = 32;
+ break;
+ }
+ return fmt;
+}
+
+
+/* Insert VALUE into INSN using R_FORMAT to determine exactly what
+ bits to change. */
+
+static INLINE unsigned long
+hppa_rebuild_insn (abfd, insn, value, r_format)
+ bfd *abfd;
+ unsigned long insn;
+ unsigned long value;
+ unsigned long r_format;
+{
+ unsigned long const_part;
+ unsigned long rebuilt_part;
+
+ switch (r_format)
+ {
+ case 11:
+ {
+ unsigned w1, w;
+
+ const_part = insn & 0xffffe002;
+ dis_assemble_12 (value, &w1, &w);
+ rebuilt_part = (w1 << 2) | w;
+ return const_part | rebuilt_part;
+ }
+
+ case 12:
+ {
+ unsigned w1, w;
+
+ const_part = insn & 0xffffe002;
+ dis_assemble_12 (value, &w1, &w);
+ rebuilt_part = (w1 << 2) | w;
+ return const_part | rebuilt_part;
+ }
+
+ case 14:
+ {
+ unsigned int ext;
+
+ const_part = insn & 0xffffc000;
+ low_sign_unext (value, 14, &ext);
+ return const_part | ext;
+ }
+
+ case 17:
+ {
+ unsigned w1, w2, w;
+
+ const_part = insn & 0xffe0e002;
+ dis_assemble_17 (value, &w1, &w2, &w);
+ rebuilt_part = (w2 << 2) | (w1 << 16) | w;
+ return const_part | rebuilt_part;
+ }
+
+ case 21:
+ {
+ unsigned int w;
+
+ const_part = insn & 0xffe00000;
+ dis_assemble_21 (value, &w);
+ return const_part | w;
+ }
+
+ case 32:
+ const_part = 0;
+ return value;
+
+ default:
+ abort ();
+ }
+ return insn;
+}
+
+#endif /* _HPPA_H */
diff --git a/bfd/libieee.h b/bfd/libieee.h
new file mode 100644
index 00000000000..30e806eaa70
--- /dev/null
+++ b/bfd/libieee.h
@@ -0,0 +1,133 @@
+/* IEEE-695 object file formats: definitions internal to BFD.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Written by Cygnus Support. Mostly Steve Chamberlain's fault.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+typedef struct {
+ unsigned int index:24;
+ char letter;
+} ieee_symbol_index_type;
+
+typedef struct ct {
+ bfd *this;
+ struct ct *next;
+} bfd_chain_type;
+
+typedef struct ieee_symbol
+{
+ asymbol symbol;
+ struct ieee_symbol *next;
+
+ unsigned int index;
+} ieee_symbol_type;
+
+
+typedef struct ieee_reloc {
+ arelent relent;
+ struct ieee_reloc *next;
+ ieee_symbol_index_type symbol;
+
+} ieee_reloc_type;
+
+#define ieee_symbol(x) ((ieee_symbol_type *)(x))
+
+typedef struct ieee_per_section
+{
+ asection *section;
+ bfd_byte *data;
+ bfd_vma offset;
+ bfd_vma pc;
+ /* For output */
+ file_ptr current_pos;
+ unsigned int current_byte;
+ boolean initialized;
+ ieee_reloc_type **reloc_tail_ptr;
+} ieee_per_section_type;
+
+#define ieee_per_section(x) ((ieee_per_section_type *)((x)->used_by_bfd))
+
+typedef struct {
+ unsigned char *input_p;
+ unsigned char *first_byte;
+ bfd *abfd;
+} common_header_type ;
+
+typedef struct ieee_data_struct
+{
+ common_header_type h;
+ boolean read_symbols;
+ boolean read_data;
+ file_ptr output_cursor;
+ /* Map of section indexes to section ptrs */
+ asection **section_table;
+ unsigned int section_table_size;
+ ieee_address_descriptor_type ad;
+ ieee_module_begin_type mb;
+ ieee_w_variable_type w;
+
+ unsigned int section_count;
+
+ unsigned int map_idx;
+ /* List of GLOBAL EXPORT symbols */
+ ieee_symbol_type *external_symbols;
+ /* List of UNDEFINED symbols */
+ ieee_symbol_type *external_reference;
+
+ /* When the symbols have been canonicalized, they are in a
+ * special order, we remember various bases here.. */
+ unsigned int external_symbol_max_index;
+ unsigned int external_symbol_min_index;
+ unsigned int external_symbol_count;
+ int external_symbol_base_offset;
+
+ unsigned int external_reference_max_index;
+ unsigned int external_reference_min_index;
+ unsigned int external_reference_count;
+ int external_reference_base_offset;
+
+
+ boolean symbol_table_full;
+
+
+boolean done_debug;
+
+
+bfd_chain_type *chain_head;
+bfd_chain_type *chain_root;
+
+} ieee_data_type;
+
+typedef struct {
+ file_ptr file_offset;
+ bfd *abfd;
+} ieee_ar_obstack_type;
+
+typedef struct ieee_ar_data_struct
+{
+ common_header_type h;
+ ieee_ar_obstack_type *elements;
+
+ unsigned int element_index ;
+ unsigned int element_count;
+
+} ieee_ar_data_type;
+
+#define IEEE_DATA(abfd) ((abfd)->tdata.ieee_data)
+#define IEEE_AR_DATA(abfd) ((abfd)->tdata.ieee_ar_data)
+
+#define ptr(abfd) (ieee_data(abfd)->input_p)
diff --git a/bfd/libnlm.h b/bfd/libnlm.h
new file mode 100644
index 00000000000..12d2e4e0cf8
--- /dev/null
+++ b/bfd/libnlm.h
@@ -0,0 +1,264 @@
+/* BFD back-end data structures for NLM (NetWare Loadable Modules) files.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _LIBNLM_H_
+#define _LIBNLM_H_ 1
+
+#ifdef ARCH_SIZE
+# define NLM_ARCH_SIZE ARCH_SIZE
+#endif
+#include "nlm/common.h"
+#include "nlm/internal.h"
+#include "nlm/external.h"
+
+/* A reloc for an imported NLM symbol. Normal relocs are associated
+ with sections, and include a symbol. These relocs are associated
+ with (undefined) symbols, and include a section. */
+
+struct nlm_relent
+{
+ /* Section of reloc. */
+ asection *section;
+ /* Reloc info (sym_ptr_ptr field set only when canonicalized). */
+ arelent reloc;
+};
+
+/* Information we keep for an NLM symbol. */
+
+typedef struct
+{
+ /* BFD symbol. */
+ asymbol symbol;
+ /* Number of reloc entries for imported symbol. */
+ bfd_size_type rcnt;
+ /* Array of reloc information for imported symbol. */
+ struct nlm_relent *relocs;
+} nlmNAME(symbol_type);
+
+extern boolean nlm_mkobject PARAMS ((bfd *));
+extern boolean nlm_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
+ unsigned long));
+
+extern void nlmNAME(get_symbol_info)
+ PARAMS ((bfd *, asymbol *, symbol_info *));
+extern long nlmNAME(get_symtab_upper_bound)
+ PARAMS ((bfd *));
+extern long nlmNAME(get_symtab)
+ PARAMS ((bfd *, asymbol **));
+extern asymbol *nlmNAME(make_empty_symbol)
+ PARAMS ((bfd *));
+extern void nlmNAME(print_symbol)
+ PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+extern long nlmNAME(get_reloc_upper_bound)
+ PARAMS ((bfd *, asection *));
+extern long nlmNAME(canonicalize_reloc)
+ PARAMS ((bfd *, asection *, arelent **, asymbol **));
+extern const bfd_target *nlmNAME(object_p)
+ PARAMS ((bfd *));
+extern boolean nlmNAME(set_arch_mach)
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+extern boolean nlmNAME(set_section_contents)
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+extern boolean nlmNAME(write_object_contents)
+ PARAMS ((bfd *));
+
+/* Some private data is stashed away for future use using the tdata pointer
+ in the bfd structure. */
+
+struct nlm_obj_tdata
+{
+ /* Actual data, but ref like ptr */
+ Nlm_Internal_Fixed_Header nlm_fixed_hdr[1];
+ Nlm_Internal_Variable_Header nlm_variable_hdr[1];
+ Nlm_Internal_Version_Header nlm_version_hdr[1];
+ Nlm_Internal_Copyright_Header nlm_copyright_hdr[1];
+ Nlm_Internal_Extended_Header nlm_extended_hdr[1];
+ Nlm_Internal_Custom_Header nlm_custom_hdr[1];
+ Nlm_Internal_Cygnus_Ext_Header nlm_cygnus_ext_hdr[1];
+ /* BFD NLM symbols. */
+ nlmNAME(symbol_type) *nlm_symbols;
+ /* Lowest text and data VMA values. */
+ bfd_vma nlm_text_low;
+ bfd_vma nlm_data_low;
+ /* Caches for data read from object file. */
+ arelent * nlm_reloc_fixups;
+ asection ** nlm_reloc_fixup_secs;
+ /* Backend specific information. This should probably be a pointer,
+ but that would require yet another entry point to initialize the
+ structure. */
+ union
+ {
+ struct /* Alpha backend information. */
+ {
+ bfd_vma gp; /* GP value. */
+ bfd_vma lita_address; /* .lita section address. */
+ bfd_size_type lita_size; /* .lita section size. */
+ }
+ alpha_backend_data;
+ }
+ backend_data;
+};
+
+#define nlm_tdata(bfd) ((bfd) -> tdata.nlm_obj_data)
+#define nlm_fixed_header(bfd) (nlm_tdata(bfd) -> nlm_fixed_hdr)
+#define nlm_variable_header(bfd) (nlm_tdata(bfd) -> nlm_variable_hdr)
+#define nlm_version_header(bfd) (nlm_tdata(bfd) -> nlm_version_hdr)
+#define nlm_copyright_header(bfd) (nlm_tdata(bfd) -> nlm_copyright_hdr)
+#define nlm_extended_header(bfd) (nlm_tdata(bfd) -> nlm_extended_hdr)
+#define nlm_custom_header(bfd) (nlm_tdata(bfd) -> nlm_custom_hdr)
+#define nlm_cygnus_ext_header(bfd) (nlm_tdata(bfd) -> nlm_cygnus_ext_hdr)
+#define nlm_get_symbols(bfd) (nlm_tdata(bfd) -> nlm_symbols)
+#define nlm_set_symbols(bfd, p) (nlm_tdata(bfd) -> nlm_symbols = (p))
+#define nlm_set_text_low(bfd, i) (nlm_tdata(bfd) -> nlm_text_low = (i))
+#define nlm_get_text_low(bfd) (nlm_tdata(bfd) -> nlm_text_low)
+#define nlm_set_data_low(bfd, i) (nlm_tdata(bfd) -> nlm_data_low = (i))
+#define nlm_get_data_low(bfd) (nlm_tdata(bfd) -> nlm_data_low)
+#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups)
+#define nlm_relocation_fixup_secs(bfd) (nlm_tdata(bfd)->nlm_reloc_fixup_secs)
+
+#define nlm_alpha_backend_data(bfd) \
+ (&nlm_tdata (bfd)->backend_data.alpha_backend_data)
+
+/* This is used when writing out the external relocs. */
+
+struct reloc_and_sec
+{
+ arelent *rel;
+ asection *sec;
+};
+
+/* We store some function pointer in the backend structure. This lets
+ different NLM targets share most of the same code, while providing
+ slightly different code where necessary. */
+
+struct nlm_backend_data
+{
+ /* Signature for this backend. */
+ char signature[NLM_SIGNATURE_SIZE];
+ /* Size of the fixed header. */
+ bfd_size_type fixed_header_size;
+ /* Size of optional prefix for this backend. Some backend may
+ require this to be a function, but so far a constant is OK. This
+ is for a prefix which precedes the standard NLM fixed header. */
+ bfd_size_type optional_prefix_size;
+ /* Architecture. */
+ enum bfd_architecture arch;
+ /* Machine. */
+ long mach;
+ /* Some NLM formats do not use the uninitialized data section, so
+ all uninitialized data must be put into the regular data section
+ instead. */
+ boolean no_uninitialized_data;
+ /* Some NLM formats have a prefix on the file. If this function is
+ not NULL, it will be called by nlm_object_p. It should return
+ true if this file could match this format, and it should leave
+ the BFD such that a bfd_read will pick up the fixed header. */
+ boolean (*nlm_backend_object_p) PARAMS ((bfd *));
+ /* Write out the prefix. This function may be NULL. This must
+ write out the same number of bytes as is in the field
+ optional_prefix_size. */
+ boolean (*nlm_write_prefix) PARAMS ((bfd *));
+ /* Read a relocation fixup from abfd. The reloc information is
+ machine specific. The second argument is the symbol if this is
+ an import, or NULL if this is a reloc fixup. This function
+ should set the third argument to the section which the reloc
+ belongs in, and the fourth argument to the reloc itself; it does
+ not need to fill in the sym_ptr_ptr field for a reloc against an
+ import symbol. */
+ boolean (*nlm_read_reloc) PARAMS ((bfd *, nlmNAME(symbol_type) *,
+ asection **, arelent *));
+ /* To make objcopy to an i386 NLM work, the i386 backend needs a
+ chance to work over the relocs. This is a bit icky. */
+ boolean (*nlm_mangle_relocs) PARAMS ((bfd *, asection *, PTR data,
+ bfd_vma offset,
+ bfd_size_type count));
+ /* Read an import record from abfd. It would be nice if this
+ were in a machine-dependent format, but it doesn't seem to be. */
+ boolean (*nlm_read_import) PARAMS ((bfd *, nlmNAME(symbol_type) *));
+ /* Write an import record to abfd. */
+ boolean (*nlm_write_import) PARAMS ((bfd *, asection *, arelent *));
+ /* Set the section for a public symbol. This may be NULL, in which
+ case a default method will be used. */
+ boolean (*nlm_set_public_section) PARAMS ((bfd *, nlmNAME(symbol_type) *));
+ /* Get the offset to write out for a public symbol. This may be
+ NULL, in which case a default method will be used. */
+ bfd_vma (*nlm_get_public_offset) PARAMS ((bfd *, asymbol *));
+ /* Swap the fixed header in and out */
+ void (*nlm_swap_fhdr_in) PARAMS ((bfd *,
+ PTR,
+ Nlm_Internal_Fixed_Header *));
+ void (*nlm_swap_fhdr_out) PARAMS ((bfd *,
+ struct nlm_internal_fixed_header *,
+ PTR));
+ /* Write out an external reference. */
+ boolean (*nlm_write_external) PARAMS ((bfd *, bfd_size_type,
+ asymbol *,
+ struct reloc_and_sec *));
+ boolean (*nlm_write_export) PARAMS ((bfd *, asymbol *, bfd_vma));
+};
+
+#define nlm_backend(bfd) \
+ ((struct nlm_backend_data *)((bfd) -> xvec -> backend_data))
+#define nlm_signature(bfd) \
+ (nlm_backend(bfd) -> signature)
+#define nlm_fixed_header_size(bfd) \
+ (nlm_backend(bfd) -> fixed_header_size)
+#define nlm_optional_prefix_size(bfd) \
+ (nlm_backend(bfd) -> optional_prefix_size)
+#define nlm_architecture(bfd) \
+ (nlm_backend(bfd) -> arch)
+#define nlm_machine(bfd) \
+ (nlm_backend(bfd) -> mach)
+#define nlm_no_uninitialized_data(bfd) \
+ (nlm_backend(bfd) -> no_uninitialized_data)
+#define nlm_backend_object_p_func(bfd) \
+ (nlm_backend(bfd) -> nlm_backend_object_p)
+#define nlm_write_prefix_func(bfd) \
+ (nlm_backend(bfd) -> nlm_write_prefix)
+#define nlm_read_reloc_func(bfd) \
+ (nlm_backend(bfd) -> nlm_read_reloc)
+#define nlm_mangle_relocs_func(bfd) \
+ (nlm_backend(bfd) -> nlm_mangle_relocs)
+#define nlm_read_import_func(bfd) \
+ (nlm_backend(bfd) -> nlm_read_import)
+#define nlm_write_import_func(bfd) \
+ (nlm_backend(bfd) -> nlm_write_import)
+#define nlm_set_public_section_func(bfd) \
+ (nlm_backend(bfd) -> nlm_set_public_section)
+#define nlm_get_public_offset_func(bfd) \
+ (nlm_backend(bfd) -> nlm_get_public_offset)
+#define nlm_swap_fixed_header_in_func(bfd) \
+ (nlm_backend(bfd) -> nlm_swap_fhdr_in)
+#define nlm_swap_fixed_header_out_func(bfd) \
+ (nlm_backend(bfd) -> nlm_swap_fhdr_out)
+#define nlm_write_external_func(bfd) \
+ (nlm_backend(bfd) -> nlm_write_external)
+#define nlm_write_export_func(bfd) \
+ (nlm_backend(bfd) -> nlm_write_export)
+
+/* The NLM code, data, and uninitialized sections have no names defined
+ in the NLM, but bfd wants to give them names, so use the traditional
+ UNIX names. */
+
+#define NLM_CODE_NAME ".text"
+#define NLM_INITIALIZED_DATA_NAME ".data"
+#define NLM_UNINITIALIZED_DATA_NAME ".bss"
+
+#endif /* _LIBNLM_H_ */
diff --git a/bfd/liboasys.h b/bfd/liboasys.h
new file mode 100644
index 00000000000..7f7ea59b5a7
--- /dev/null
+++ b/bfd/liboasys.h
@@ -0,0 +1,82 @@
+/* BFD internal declarations for Oasys file format handling.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Scrawled by Steve Chamberlain of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+typedef struct _oasys_symbol
+{
+ asymbol symbol;
+} oasys_symbol_type;
+
+typedef struct _oasys_reloc {
+ arelent relent;
+ struct _oasys_reloc *next;
+ unsigned int symbol;
+} oasys_reloc_type;
+
+
+#define oasys_symbol(x) ((oasys_symbol_type *)(x))
+#define oasys_per_section(x) ((oasys_per_section_type *)(x->used_by_bfd))
+
+typedef struct _oasys_per_section
+{
+ asection *section;
+ bfd_byte *data;
+ bfd_vma offset;
+ boolean had_vma;
+ oasys_reloc_type **reloc_tail_ptr;
+ bfd_vma pc;
+
+
+ file_ptr current_pos;
+ unsigned int current_byte;
+ boolean initialized;
+} oasys_per_section_type;
+
+#define NSECTIONS 10
+
+typedef struct _oasys_ar_obstack {
+ file_ptr file_offset;
+ bfd *abfd;
+} oasys_ar_obstack_type;
+
+
+typedef struct _oasys_module_info {
+ file_ptr pos;
+ unsigned int size;
+ bfd *abfd;
+ char *name;
+} oasys_module_info_type;
+
+typedef struct _oasys_ar_data {
+ oasys_module_info_type *module;
+ unsigned int module_count;
+ unsigned int module_index;
+} oasys_ar_data_type;
+
+typedef struct _oasys_data {
+ char *strings;
+ asymbol *symbols;
+ unsigned int symbol_string_length;
+ asection *sections[OASYS_MAX_SEC_COUNT];
+ file_ptr first_data_record;
+} oasys_data_type;
+
+#define OASYS_DATA(abfd) ((abfd)->tdata.oasys_obj_data)
+#define OASYS_AR_DATA(abfd) ((abfd)->tdata.oasys_ar_data)
+
diff --git a/bfd/linker.c b/bfd/linker.c
new file mode 100644
index 00000000000..947514c3fbd
--- /dev/null
+++ b/bfd/linker.c
@@ -0,0 +1,2804 @@
+/* linker.c -- BFD linker routines
+ Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+
+/*
+SECTION
+ Linker Functions
+
+@cindex Linker
+ The linker uses three special entry points in the BFD target
+ vector. It is not necessary to write special routines for
+ these entry points when creating a new BFD back end, since
+ generic versions are provided. However, writing them can
+ speed up linking and make it use significantly less runtime
+ memory.
+
+ The first routine creates a hash table used by the other
+ routines. The second routine adds the symbols from an object
+ file to the hash table. The third routine takes all the
+ object files and links them together to create the output
+ file. These routines are designed so that the linker proper
+ does not need to know anything about the symbols in the object
+ files that it is linking. The linker merely arranges the
+ sections as directed by the linker script and lets BFD handle
+ the details of symbols and relocs.
+
+ The second routine and third routines are passed a pointer to
+ a <<struct bfd_link_info>> structure (defined in
+ <<bfdlink.h>>) which holds information relevant to the link,
+ including the linker hash table (which was created by the
+ first routine) and a set of callback functions to the linker
+ proper.
+
+ The generic linker routines are in <<linker.c>>, and use the
+ header file <<genlink.h>>. As of this writing, the only back
+ ends which have implemented versions of these routines are
+ a.out (in <<aoutx.h>>) and ECOFF (in <<ecoff.c>>). The a.out
+ routines are used as examples throughout this section.
+
+@menu
+@* Creating a Linker Hash Table::
+@* Adding Symbols to the Hash Table::
+@* Performing the Final Link::
+@end menu
+
+INODE
+Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions
+SUBSECTION
+ Creating a linker hash table
+
+@cindex _bfd_link_hash_table_create in target vector
+@cindex target vector (_bfd_link_hash_table_create)
+ The linker routines must create a hash table, which must be
+ derived from <<struct bfd_link_hash_table>> described in
+ <<bfdlink.c>>. @xref{Hash Tables} for information on how to
+ create a derived hash table. This entry point is called using
+ the target vector of the linker output file.
+
+ The <<_bfd_link_hash_table_create>> entry point must allocate
+ and initialize an instance of the desired hash table. If the
+ back end does not require any additional information to be
+ stored with the entries in the hash table, the entry point may
+ simply create a <<struct bfd_link_hash_table>>. Most likely,
+ however, some additional information will be needed.
+
+ For example, with each entry in the hash table the a.out
+ linker keeps the index the symbol has in the final output file
+ (this index number is used so that when doing a relocateable
+ link the symbol index used in the output file can be quickly
+ filled in when copying over a reloc). The a.out linker code
+ defines the required structures and functions for a hash table
+ derived from <<struct bfd_link_hash_table>>. The a.out linker
+ hash table is created by the function
+ <<NAME(aout,link_hash_table_create)>>; it simply allocates
+ space for the hash table, initializes it, and returns a
+ pointer to it.
+
+ When writing the linker routines for a new back end, you will
+ generally not know exactly which fields will be required until
+ you have finished. You should simply create a new hash table
+ which defines no additional fields, and then simply add fields
+ as they become necessary.
+
+INODE
+Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions
+SUBSECTION
+ Adding symbols to the hash table
+
+@cindex _bfd_link_add_symbols in target vector
+@cindex target vector (_bfd_link_add_symbols)
+ The linker proper will call the <<_bfd_link_add_symbols>>
+ entry point for each object file or archive which is to be
+ linked (typically these are the files named on the command
+ line, but some may also come from the linker script). The
+ entry point is responsible for examining the file. For an
+ object file, BFD must add any relevant symbol information to
+ the hash table. For an archive, BFD must determine which
+ elements of the archive should be used and adding them to the
+ link.
+
+ The a.out version of this entry point is
+ <<NAME(aout,link_add_symbols)>>.
+
+@menu
+@* Differing file formats::
+@* Adding symbols from an object file::
+@* Adding symbols from an archive::
+@end menu
+
+INODE
+Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table
+SUBSUBSECTION
+ Differing file formats
+
+ Normally all the files involved in a link will be of the same
+ format, but it is also possible to link together different
+ format object files, and the back end must support that. The
+ <<_bfd_link_add_symbols>> entry point is called via the target
+ vector of the file to be added. This has an important
+ consequence: the function may not assume that the hash table
+ is the type created by the corresponding
+ <<_bfd_link_hash_table_create>> vector. All the
+ <<_bfd_link_add_symbols>> function can assume about the hash
+ table is that it is derived from <<struct
+ bfd_link_hash_table>>.
+
+ Sometimes the <<_bfd_link_add_symbols>> function must store
+ some information in the hash table entry to be used by the
+ <<_bfd_final_link>> function. In such a case the <<creator>>
+ field of the hash table must be checked to make sure that the
+ hash table was created by an object file of the same format.
+
+ The <<_bfd_final_link>> routine must be prepared to handle a
+ hash entry without any extra information added by the
+ <<_bfd_link_add_symbols>> function. A hash entry without
+ extra information will also occur when the linker script
+ directs the linker to create a symbol. Note that, regardless
+ of how a hash table entry is added, all the fields will be
+ initialized to some sort of null value by the hash table entry
+ initialization function.
+
+ See <<ecoff_link_add_externals>> for an example of how to
+ check the <<creator>> field before saving information (in this
+ case, the ECOFF external symbol debugging information) in a
+ hash table entry.
+
+INODE
+Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table
+SUBSUBSECTION
+ Adding symbols from an object file
+
+ When the <<_bfd_link_add_symbols>> routine is passed an object
+ file, it must add all externally visible symbols in that
+ object file to the hash table. The actual work of adding the
+ symbol to the hash table is normally handled by the function
+ <<_bfd_generic_link_add_one_symbol>>. The
+ <<_bfd_link_add_symbols>> routine is responsible for reading
+ all the symbols from the object file and passing the correct
+ information to <<_bfd_generic_link_add_one_symbol>>.
+
+ The <<_bfd_link_add_symbols>> routine should not use
+ <<bfd_canonicalize_symtab>> to read the symbols. The point of
+ providing this routine is to avoid the overhead of converting
+ the symbols into generic <<asymbol>> structures.
+
+@findex _bfd_generic_link_add_one_symbol
+ <<_bfd_generic_link_add_one_symbol>> handles the details of
+ combining common symbols, warning about multiple definitions,
+ and so forth. It takes arguments which describe the symbol to
+ add, notably symbol flags, a section, and an offset. The
+ symbol flags include such things as <<BSF_WEAK>> or
+ <<BSF_INDIRECT>>. The section is a section in the object
+ file, or something like <<bfd_und_section_ptr>> for an undefined
+ symbol or <<bfd_com_section_ptr>> for a common symbol.
+
+ If the <<_bfd_final_link>> routine is also going to need to
+ read the symbol information, the <<_bfd_link_add_symbols>>
+ routine should save it somewhere attached to the object file
+ BFD. However, the information should only be saved if the
+ <<keep_memory>> field of the <<info>> argument is true, so
+ that the <<-no-keep-memory>> linker switch is effective.
+
+ The a.out function which adds symbols from an object file is
+ <<aout_link_add_object_symbols>>, and most of the interesting
+ work is in <<aout_link_add_symbols>>. The latter saves
+ pointers to the hash tables entries created by
+ <<_bfd_generic_link_add_one_symbol>> indexed by symbol number,
+ so that the <<_bfd_final_link>> routine does not have to call
+ the hash table lookup routine to locate the entry.
+
+INODE
+Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table
+SUBSUBSECTION
+ Adding symbols from an archive
+
+ When the <<_bfd_link_add_symbols>> routine is passed an
+ archive, it must look through the symbols defined by the
+ archive and decide which elements of the archive should be
+ included in the link. For each such element it must call the
+ <<add_archive_element>> linker callback, and it must add the
+ symbols from the object file to the linker hash table.
+
+@findex _bfd_generic_link_add_archive_symbols
+ In most cases the work of looking through the symbols in the
+ archive should be done by the
+ <<_bfd_generic_link_add_archive_symbols>> function. This
+ function builds a hash table from the archive symbol table and
+ looks through the list of undefined symbols to see which
+ elements should be included.
+ <<_bfd_generic_link_add_archive_symbols>> is passed a function
+ to call to make the final decision about adding an archive
+ element to the link and to do the actual work of adding the
+ symbols to the linker hash table.
+
+ The function passed to
+ <<_bfd_generic_link_add_archive_symbols>> must read the
+ symbols of the archive element and decide whether the archive
+ element should be included in the link. If the element is to
+ be included, the <<add_archive_element>> linker callback
+ routine must be called with the element as an argument, and
+ the elements symbols must be added to the linker hash table
+ just as though the element had itself been passed to the
+ <<_bfd_link_add_symbols>> function.
+
+ When the a.out <<_bfd_link_add_symbols>> function receives an
+ archive, it calls <<_bfd_generic_link_add_archive_symbols>>
+ passing <<aout_link_check_archive_element>> as the function
+ argument. <<aout_link_check_archive_element>> calls
+ <<aout_link_check_ar_symbols>>. If the latter decides to add
+ the element (an element is only added if it provides a real,
+ non-common, definition for a previously undefined or common
+ symbol) it calls the <<add_archive_element>> callback and then
+ <<aout_link_check_archive_element>> calls
+ <<aout_link_add_symbols>> to actually add the symbols to the
+ linker hash table.
+
+ The ECOFF back end is unusual in that it does not normally
+ call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF
+ archives already contain a hash table of symbols. The ECOFF
+ back end searches the archive itself to avoid the overhead of
+ creating a new hash table.
+
+INODE
+Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions
+SUBSECTION
+ Performing the final link
+
+@cindex _bfd_link_final_link in target vector
+@cindex target vector (_bfd_final_link)
+ When all the input files have been processed, the linker calls
+ the <<_bfd_final_link>> entry point of the output BFD. This
+ routine is responsible for producing the final output file,
+ which has several aspects. It must relocate the contents of
+ the input sections and copy the data into the output sections.
+ It must build an output symbol table including any local
+ symbols from the input files and the global symbols from the
+ hash table. When producing relocateable output, it must
+ modify the input relocs and write them into the output file.
+ There may also be object format dependent work to be done.
+
+ The linker will also call the <<write_object_contents>> entry
+ point when the BFD is closed. The two entry points must work
+ together in order to produce the correct output file.
+
+ The details of how this works are inevitably dependent upon
+ the specific object file format. The a.out
+ <<_bfd_final_link>> routine is <<NAME(aout,final_link)>>.
+
+@menu
+@* Information provided by the linker::
+@* Relocating the section contents::
+@* Writing the symbol table::
+@end menu
+
+INODE
+Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link
+SUBSUBSECTION
+ Information provided by the linker
+
+ Before the linker calls the <<_bfd_final_link>> entry point,
+ it sets up some data structures for the function to use.
+
+ The <<input_bfds>> field of the <<bfd_link_info>> structure
+ will point to a list of all the input files included in the
+ link. These files are linked through the <<link_next>> field
+ of the <<bfd>> structure.
+
+ Each section in the output file will have a list of
+ <<link_order>> structures attached to the <<link_order_head>>
+ field (the <<link_order>> structure is defined in
+ <<bfdlink.h>>). These structures describe how to create the
+ contents of the output section in terms of the contents of
+ various input sections, fill constants, and, eventually, other
+ types of information. They also describe relocs that must be
+ created by the BFD backend, but do not correspond to any input
+ file; this is used to support -Ur, which builds constructors
+ while generating a relocateable object file.
+
+INODE
+Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link
+SUBSUBSECTION
+ Relocating the section contents
+
+ The <<_bfd_final_link>> function should look through the
+ <<link_order>> structures attached to each section of the
+ output file. Each <<link_order>> structure should either be
+ handled specially, or it should be passed to the function
+ <<_bfd_default_link_order>> which will do the right thing
+ (<<_bfd_default_link_order>> is defined in <<linker.c>>).
+
+ For efficiency, a <<link_order>> of type
+ <<bfd_indirect_link_order>> whose associated section belongs
+ to a BFD of the same format as the output BFD must be handled
+ specially. This type of <<link_order>> describes part of an
+ output section in terms of a section belonging to one of the
+ input files. The <<_bfd_final_link>> function should read the
+ contents of the section and any associated relocs, apply the
+ relocs to the section contents, and write out the modified
+ section contents. If performing a relocateable link, the
+ relocs themselves must also be modified and written out.
+
+@findex _bfd_relocate_contents
+@findex _bfd_final_link_relocate
+ The functions <<_bfd_relocate_contents>> and
+ <<_bfd_final_link_relocate>> provide some general support for
+ performing the actual relocations, notably overflow checking.
+ Their arguments include information about the symbol the
+ relocation is against and a <<reloc_howto_type>> argument
+ which describes the relocation to perform. These functions
+ are defined in <<reloc.c>>.
+
+ The a.out function which handles reading, relocating, and
+ writing section contents is <<aout_link_input_section>>. The
+ actual relocation is done in <<aout_link_input_section_std>>
+ and <<aout_link_input_section_ext>>.
+
+INODE
+Writing the symbol table, , Relocating the section contents, Performing the Final Link
+SUBSUBSECTION
+ Writing the symbol table
+
+ The <<_bfd_final_link>> function must gather all the symbols
+ in the input files and write them out. It must also write out
+ all the symbols in the global hash table. This must be
+ controlled by the <<strip>> and <<discard>> fields of the
+ <<bfd_link_info>> structure.
+
+ The local symbols of the input files will not have been
+ entered into the linker hash table. The <<_bfd_final_link>>
+ routine must consider each input file and include the symbols
+ in the output file. It may be convenient to do this when
+ looking through the <<link_order>> structures, or it may be
+ done by stepping through the <<input_bfds>> list.
+
+ The <<_bfd_final_link>> routine must also traverse the global
+ hash table to gather all the externally visible symbols. It
+ is possible that most of the externally visible symbols may be
+ written out when considering the symbols of each input file,
+ but it is still necessary to traverse the hash table since the
+ linker script may have defined some symbols that are not in
+ any of the input files.
+
+ The <<strip>> field of the <<bfd_link_info>> structure
+ controls which symbols are written out. The possible values
+ are listed in <<bfdlink.h>>. If the value is <<strip_some>>,
+ then the <<keep_hash>> field of the <<bfd_link_info>>
+ structure is a hash table of symbols to keep; each symbol
+ should be looked up in this hash table, and only symbols which
+ are present should be included in the output file.
+
+ If the <<strip>> field of the <<bfd_link_info>> structure
+ permits local symbols to be written out, the <<discard>> field
+ is used to further controls which local symbols are included
+ in the output file. If the value is <<discard_l>>, then all
+ local symbols which begin with a certain prefix are discarded;
+ this is controlled by the <<bfd_is_local_label_name>> entry point.
+
+ The a.out backend handles symbols by calling
+ <<aout_link_write_symbols>> on each input BFD and then
+ traversing the global hash table with the function
+ <<aout_link_write_other_symbol>>. It builds a string table
+ while writing out the symbols, which is written to the output
+ file at the end of <<NAME(aout,final_link)>>.
+*/
+
+static boolean generic_link_read_symbols
+ PARAMS ((bfd *));
+static boolean generic_link_add_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, boolean collect));
+static boolean generic_link_add_object_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, boolean collect));
+static boolean generic_link_check_archive_element_no_collect
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
+static boolean generic_link_check_archive_element_collect
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
+static boolean generic_link_check_archive_element
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded, boolean collect));
+static boolean generic_link_add_symbol_list
+ PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **,
+ boolean collect));
+static bfd *hash_entry_bfd PARAMS ((struct bfd_link_hash_entry *));
+static void set_symbol_from_hash
+ PARAMS ((asymbol *, struct bfd_link_hash_entry *));
+static boolean generic_add_output_symbol
+ PARAMS ((bfd *, size_t *psymalloc, asymbol *));
+static boolean default_fill_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *));
+static boolean default_indirect_link_order
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ struct bfd_link_order *, boolean));
+
+/* The link hash table structure is defined in bfdlink.h. It provides
+ a base hash table which the backend specific hash tables are built
+ upon. */
+
+/* Routine to create an entry in the link hash table. */
+
+struct bfd_hash_entry *
+_bfd_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct bfd_link_hash_entry *ret = (struct bfd_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct bfd_link_hash_entry *) NULL)
+ ret = ((struct bfd_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry)));
+ if (ret == (struct bfd_link_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct bfd_link_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->type = bfd_link_hash_new;
+ ret->next = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize a link hash table. The BFD argument is the one
+ responsible for creating this table. */
+
+boolean
+_bfd_link_hash_table_init (table, abfd, newfunc)
+ struct bfd_link_hash_table *table;
+ bfd *abfd;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ table->creator = abfd->xvec;
+ table->undefs = NULL;
+ table->undefs_tail = NULL;
+ return bfd_hash_table_init (&table->table, newfunc);
+}
+
+/* Look up a symbol in a link hash table. If follow is true, we
+ follow bfd_link_hash_indirect and bfd_link_hash_warning links to
+ the real symbol. */
+
+struct bfd_link_hash_entry *
+bfd_link_hash_lookup (table, string, create, copy, follow)
+ struct bfd_link_hash_table *table;
+ const char *string;
+ boolean create;
+ boolean copy;
+ boolean follow;
+{
+ struct bfd_link_hash_entry *ret;
+
+ ret = ((struct bfd_link_hash_entry *)
+ bfd_hash_lookup (&table->table, string, create, copy));
+
+ if (follow && ret != (struct bfd_link_hash_entry *) NULL)
+ {
+ while (ret->type == bfd_link_hash_indirect
+ || ret->type == bfd_link_hash_warning)
+ ret = ret->u.i.link;
+ }
+
+ return ret;
+}
+
+/* Look up a symbol in the main linker hash table if the symbol might
+ be wrapped. This should only be used for references to an
+ undefined symbol, not for definitions of a symbol. */
+
+struct bfd_link_hash_entry *
+bfd_wrapped_link_hash_lookup (abfd, info, string, create, copy, follow)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ const char *string;
+ boolean create;
+ boolean copy;
+ boolean follow;
+{
+ if (info->wrap_hash != NULL)
+ {
+ const char *l;
+
+ l = string;
+ if (*l == bfd_get_symbol_leading_char (abfd))
+ ++l;
+
+#undef WRAP
+#define WRAP "__wrap_"
+
+ if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL)
+ {
+ char *n;
+ struct bfd_link_hash_entry *h;
+
+ /* This symbol is being wrapped. We want to replace all
+ references to SYM with references to __wrap_SYM. */
+
+ n = (char *) bfd_malloc (strlen (l) + sizeof WRAP + 1);
+ if (n == NULL)
+ return NULL;
+
+ /* Note that symbol_leading_char may be '\0'. */
+ n[0] = bfd_get_symbol_leading_char (abfd);
+ n[1] = '\0';
+ strcat (n, WRAP);
+ strcat (n, l);
+ h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
+ free (n);
+ return h;
+ }
+
+#undef WRAP
+
+#undef REAL
+#define REAL "__real_"
+
+ if (*l == '_'
+ && strncmp (l, REAL, sizeof REAL - 1) == 0
+ && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1,
+ false, false) != NULL)
+ {
+ char *n;
+ struct bfd_link_hash_entry *h;
+
+ /* This is a reference to __real_SYM, where SYM is being
+ wrapped. We want to replace all references to __real_SYM
+ with references to SYM. */
+
+ n = (char *) bfd_malloc (strlen (l + sizeof REAL - 1) + 2);
+ if (n == NULL)
+ return NULL;
+
+ /* Note that symbol_leading_char may be '\0'. */
+ n[0] = bfd_get_symbol_leading_char (abfd);
+ n[1] = '\0';
+ strcat (n, l + sizeof REAL - 1);
+ h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
+ free (n);
+ return h;
+ }
+
+#undef REAL
+ }
+
+ return bfd_link_hash_lookup (info->hash, string, create, copy, follow);
+}
+
+/* Traverse a generic link hash table. The only reason this is not a
+ macro is to do better type checking. This code presumes that an
+ argument passed as a struct bfd_hash_entry * may be caught as a
+ struct bfd_link_hash_entry * with no explicit cast required on the
+ call. */
+
+void
+bfd_link_hash_traverse (table, func, info)
+ struct bfd_link_hash_table *table;
+ boolean (*func) PARAMS ((struct bfd_link_hash_entry *, PTR));
+ PTR info;
+{
+ bfd_hash_traverse (&table->table,
+ ((boolean (*) PARAMS ((struct bfd_hash_entry *, PTR)))
+ func),
+ info);
+}
+
+/* Add a symbol to the linker hash table undefs list. */
+
+INLINE void
+bfd_link_add_undef (table, h)
+ struct bfd_link_hash_table *table;
+ struct bfd_link_hash_entry *h;
+{
+ BFD_ASSERT (h->next == NULL);
+ if (table->undefs_tail != (struct bfd_link_hash_entry *) NULL)
+ table->undefs_tail->next = h;
+ if (table->undefs == (struct bfd_link_hash_entry *) NULL)
+ table->undefs = h;
+ table->undefs_tail = h;
+}
+
+/* Routine to create an entry in an generic link hash table. */
+
+struct bfd_hash_entry *
+_bfd_generic_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct generic_link_hash_entry *ret =
+ (struct generic_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct generic_link_hash_entry *) NULL)
+ ret = ((struct generic_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)));
+ if (ret == (struct generic_link_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct generic_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->written = false;
+ ret->sym = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an generic link hash table. */
+
+struct bfd_link_hash_table *
+_bfd_generic_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct generic_link_hash_table *ret;
+
+ ret = ((struct generic_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct generic_link_hash_table)));
+ if (ret == NULL)
+ return (struct bfd_link_hash_table *) NULL;
+ if (! _bfd_link_hash_table_init (&ret->root, abfd,
+ _bfd_generic_link_hash_newfunc))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+ return &ret->root;
+}
+
+/* Grab the symbols for an object file when doing a generic link. We
+ store the symbols in the outsymbols field. We need to keep them
+ around for the entire link to ensure that we only read them once.
+ If we read them multiple times, we might wind up with relocs and
+ the hash table pointing to different instances of the symbol
+ structure. */
+
+static boolean
+generic_link_read_symbols (abfd)
+ bfd *abfd;
+{
+ if (bfd_get_outsymbols (abfd) == (asymbol **) NULL)
+ {
+ long symsize;
+ long symcount;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ return false;
+ bfd_get_outsymbols (abfd) = (asymbol **) bfd_alloc (abfd, symsize);
+ if (bfd_get_outsymbols (abfd) == NULL && symsize != 0)
+ return false;
+ symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd));
+ if (symcount < 0)
+ return false;
+ bfd_get_symcount (abfd) = symcount;
+ }
+
+ return true;
+}
+
+/* Generic function to add symbols to from an object file to the
+ global hash table. This version does not automatically collect
+ constructors by name. */
+
+boolean
+_bfd_generic_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ return generic_link_add_symbols (abfd, info, false);
+}
+
+/* Generic function to add symbols from an object file to the global
+ hash table. This version automatically collects constructors by
+ name, as the collect2 program does. It should be used for any
+ target which does not provide some other mechanism for setting up
+ constructors and destructors; these are approximately those targets
+ for which gcc uses collect2 and do not support stabs. */
+
+boolean
+_bfd_generic_link_add_symbols_collect (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ return generic_link_add_symbols (abfd, info, true);
+}
+
+/* Add symbols from an object file to the global hash table. */
+
+static boolean
+generic_link_add_symbols (abfd, info, collect)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean collect;
+{
+ boolean ret;
+
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ ret = generic_link_add_object_symbols (abfd, info, collect);
+ break;
+ case bfd_archive:
+ ret = (_bfd_generic_link_add_archive_symbols
+ (abfd, info,
+ (collect
+ ? generic_link_check_archive_element_collect
+ : generic_link_check_archive_element_no_collect)));
+ break;
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ ret = false;
+ }
+
+ return ret;
+}
+
+/* Add symbols from an object file to the global hash table. */
+
+static boolean
+generic_link_add_object_symbols (abfd, info, collect)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean collect;
+{
+ if (! generic_link_read_symbols (abfd))
+ return false;
+ return generic_link_add_symbol_list (abfd, info,
+ _bfd_generic_link_get_symcount (abfd),
+ _bfd_generic_link_get_symbols (abfd),
+ collect);
+}
+
+/* We build a hash table of all symbols defined in an archive. */
+
+/* An archive symbol may be defined by multiple archive elements.
+ This linked list is used to hold the elements. */
+
+struct archive_list
+{
+ struct archive_list *next;
+ int indx;
+};
+
+/* An entry in an archive hash table. */
+
+struct archive_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Where the symbol is defined. */
+ struct archive_list *defs;
+};
+
+/* An archive hash table itself. */
+
+struct archive_hash_table
+{
+ struct bfd_hash_table table;
+};
+
+static struct bfd_hash_entry *archive_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean archive_hash_table_init
+ PARAMS ((struct archive_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *)));
+
+/* Create a new entry for an archive hash table. */
+
+static struct bfd_hash_entry *
+archive_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct archive_hash_entry *ret = (struct archive_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct archive_hash_entry *) NULL)
+ ret = ((struct archive_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct archive_hash_entry)));
+ if (ret == (struct archive_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct archive_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->defs = (struct archive_list *) NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize an archive hash table. */
+
+static boolean
+archive_hash_table_init (table, newfunc)
+ struct archive_hash_table *table;
+ struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+{
+ return bfd_hash_table_init (&table->table, newfunc);
+}
+
+/* Look up an entry in an archive hash table. */
+
+#define archive_hash_lookup(t, string, create, copy) \
+ ((struct archive_hash_entry *) \
+ bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
+
+/* Allocate space in an archive hash table. */
+
+#define archive_hash_allocate(t, size) bfd_hash_allocate (&(t)->table, (size))
+
+/* Free an archive hash table. */
+
+#define archive_hash_table_free(t) bfd_hash_table_free (&(t)->table)
+
+/* Generic function to add symbols from an archive file to the global
+ hash file. This function presumes that the archive symbol table
+ has already been read in (this is normally done by the
+ bfd_check_format entry point). It looks through the undefined and
+ common symbols and searches the archive symbol table for them. If
+ it finds an entry, it includes the associated object file in the
+ link.
+
+ The old linker looked through the archive symbol table for
+ undefined symbols. We do it the other way around, looking through
+ undefined symbols for symbols defined in the archive. The
+ advantage of the newer scheme is that we only have to look through
+ the list of undefined symbols once, whereas the old method had to
+ re-search the symbol table each time a new object file was added.
+
+ The CHECKFN argument is used to see if an object file should be
+ included. CHECKFN should set *PNEEDED to true if the object file
+ should be included, and must also call the bfd_link_info
+ add_archive_element callback function and handle adding the symbols
+ to the global hash table. CHECKFN should only return false if some
+ sort of error occurs.
+
+ For some formats, such as a.out, it is possible to look through an
+ object file but not actually include it in the link. The
+ archive_pass field in a BFD is used to avoid checking the symbols
+ of an object files too many times. When an object is included in
+ the link, archive_pass is set to -1. If an object is scanned but
+ not included, archive_pass is set to the pass number. The pass
+ number is incremented each time a new object file is included. The
+ pass number is used because when a new object file is included it
+ may create new undefined symbols which cause a previously examined
+ object file to be included. */
+
+boolean
+_bfd_generic_link_add_archive_symbols (abfd, info, checkfn)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean (*checkfn) PARAMS ((bfd *, struct bfd_link_info *,
+ boolean *pneeded));
+{
+ carsym *arsyms;
+ carsym *arsym_end;
+ register carsym *arsym;
+ int pass;
+ struct archive_hash_table arsym_hash;
+ int indx;
+ struct bfd_link_hash_entry **pundef;
+
+ if (! bfd_has_map (abfd))
+ {
+ /* An empty archive is a special case. */
+ if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL)
+ return true;
+ bfd_set_error (bfd_error_no_armap);
+ return false;
+ }
+
+ arsyms = bfd_ardata (abfd)->symdefs;
+ arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
+
+ /* In order to quickly determine whether an symbol is defined in
+ this archive, we build a hash table of the symbols. */
+ if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc))
+ return false;
+ for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
+ {
+ struct archive_hash_entry *arh;
+ struct archive_list *l, **pp;
+
+ arh = archive_hash_lookup (&arsym_hash, arsym->name, true, false);
+ if (arh == (struct archive_hash_entry *) NULL)
+ goto error_return;
+ l = ((struct archive_list *)
+ archive_hash_allocate (&arsym_hash, sizeof (struct archive_list)));
+ if (l == NULL)
+ goto error_return;
+ l->indx = indx;
+ for (pp = &arh->defs;
+ *pp != (struct archive_list *) NULL;
+ pp = &(*pp)->next)
+ ;
+ *pp = l;
+ l->next = NULL;
+ }
+
+ /* The archive_pass field in the archive itself is used to
+ initialize PASS, sine we may search the same archive multiple
+ times. */
+ pass = abfd->archive_pass + 1;
+
+ /* New undefined symbols are added to the end of the list, so we
+ only need to look through it once. */
+ pundef = &info->hash->undefs;
+ while (*pundef != (struct bfd_link_hash_entry *) NULL)
+ {
+ struct bfd_link_hash_entry *h;
+ struct archive_hash_entry *arh;
+ struct archive_list *l;
+
+ h = *pundef;
+
+ /* When a symbol is defined, it is not necessarily removed from
+ the list. */
+ if (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common)
+ {
+ /* Remove this entry from the list, for general cleanliness
+ and because we are going to look through the list again
+ if we search any more libraries. We can't remove the
+ entry if it is the tail, because that would lose any
+ entries we add to the list later on (it would also cause
+ us to lose track of whether the symbol has been
+ referenced). */
+ if (*pundef != info->hash->undefs_tail)
+ *pundef = (*pundef)->next;
+ else
+ pundef = &(*pundef)->next;
+ continue;
+ }
+
+ /* Look for this symbol in the archive symbol map. */
+ arh = archive_hash_lookup (&arsym_hash, h->root.string, false, false);
+ if (arh == (struct archive_hash_entry *) NULL)
+ {
+ pundef = &(*pundef)->next;
+ continue;
+ }
+
+ /* Look at all the objects which define this symbol. */
+ for (l = arh->defs; l != (struct archive_list *) NULL; l = l->next)
+ {
+ bfd *element;
+ boolean needed;
+
+ /* If the symbol has gotten defined along the way, quit. */
+ if (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common)
+ break;
+
+ element = bfd_get_elt_at_index (abfd, l->indx);
+ if (element == (bfd *) NULL)
+ goto error_return;
+
+ /* If we've already included this element, or if we've
+ already checked it on this pass, continue. */
+ if (element->archive_pass == -1
+ || element->archive_pass == pass)
+ continue;
+
+ /* If we can't figure this element out, just ignore it. */
+ if (! bfd_check_format (element, bfd_object))
+ {
+ element->archive_pass = -1;
+ continue;
+ }
+
+ /* CHECKFN will see if this element should be included, and
+ go ahead and include it if appropriate. */
+ if (! (*checkfn) (element, info, &needed))
+ goto error_return;
+
+ if (! needed)
+ element->archive_pass = pass;
+ else
+ {
+ element->archive_pass = -1;
+
+ /* Increment the pass count to show that we may need to
+ recheck object files which were already checked. */
+ ++pass;
+ }
+ }
+
+ pundef = &(*pundef)->next;
+ }
+
+ archive_hash_table_free (&arsym_hash);
+
+ /* Save PASS in case we are called again. */
+ abfd->archive_pass = pass;
+
+ return true;
+
+ error_return:
+ archive_hash_table_free (&arsym_hash);
+ return false;
+}
+
+/* See if we should include an archive element. This version is used
+ when we do not want to automatically collect constructors based on
+ the symbol name, presumably because we have some other mechanism
+ for finding them. */
+
+static boolean
+generic_link_check_archive_element_no_collect (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ return generic_link_check_archive_element (abfd, info, pneeded, false);
+}
+
+/* See if we should include an archive element. This version is used
+ when we want to automatically collect constructors based on the
+ symbol name, as collect2 does. */
+
+static boolean
+generic_link_check_archive_element_collect (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ return generic_link_check_archive_element (abfd, info, pneeded, true);
+}
+
+/* See if we should include an archive element. Optionally collect
+ constructors. */
+
+static boolean
+generic_link_check_archive_element (abfd, info, pneeded, collect)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+ boolean collect;
+{
+ asymbol **pp, **ppend;
+
+ *pneeded = false;
+
+ if (! generic_link_read_symbols (abfd))
+ return false;
+
+ pp = _bfd_generic_link_get_symbols (abfd);
+ ppend = pp + _bfd_generic_link_get_symcount (abfd);
+ for (; pp < ppend; pp++)
+ {
+ asymbol *p;
+ struct bfd_link_hash_entry *h;
+
+ p = *pp;
+
+ /* We are only interested in globally visible symbols. */
+ if (! bfd_is_com_section (p->section)
+ && (p->flags & (BSF_GLOBAL | BSF_INDIRECT | BSF_WEAK)) == 0)
+ continue;
+
+ /* We are only interested if we know something about this
+ symbol, and it is undefined or common. An undefined weak
+ symbol (type bfd_link_hash_undefweak) is not considered to be
+ a reference when pulling files out of an archive. See the
+ SVR4 ABI, p. 4-27. */
+ h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false,
+ false, true);
+ if (h == (struct bfd_link_hash_entry *) NULL
+ || (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common))
+ continue;
+
+ /* P is a symbol we are looking for. */
+
+ if (! bfd_is_com_section (p->section))
+ {
+ bfd_size_type symcount;
+ asymbol **symbols;
+
+ /* This object file defines this symbol, so pull it in. */
+ if (! (*info->callbacks->add_archive_element) (info, abfd,
+ bfd_asymbol_name (p)))
+ return false;
+ symcount = _bfd_generic_link_get_symcount (abfd);
+ symbols = _bfd_generic_link_get_symbols (abfd);
+ if (! generic_link_add_symbol_list (abfd, info, symcount,
+ symbols, collect))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+
+ /* P is a common symbol. */
+
+ if (h->type == bfd_link_hash_undefined)
+ {
+ bfd *symbfd;
+ bfd_vma size;
+ unsigned int power;
+
+ symbfd = h->u.undef.abfd;
+ if (symbfd == (bfd *) NULL)
+ {
+ /* This symbol was created as undefined from outside
+ BFD. We assume that we should link in the object
+ file. This is for the -u option in the linker. */
+ if (! (*info->callbacks->add_archive_element)
+ (info, abfd, bfd_asymbol_name (p)))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+
+ /* Turn the symbol into a common symbol but do not link in
+ the object file. This is how a.out works. Object
+ formats that require different semantics must implement
+ this function differently. This symbol is already on the
+ undefs list. We add the section to a common section
+ attached to symbfd to ensure that it is in a BFD which
+ will be linked in. */
+ h->type = bfd_link_hash_common;
+ h->u.c.p =
+ ((struct bfd_link_hash_common_entry *)
+ bfd_hash_allocate (&info->hash->table,
+ sizeof (struct bfd_link_hash_common_entry)));
+ if (h->u.c.p == NULL)
+ return false;
+
+ size = bfd_asymbol_value (p);
+ h->u.c.size = size;
+
+ power = bfd_log2 (size);
+ if (power > 4)
+ power = 4;
+ h->u.c.p->alignment_power = power;
+
+ if (p->section == bfd_com_section_ptr)
+ h->u.c.p->section = bfd_make_section_old_way (symbfd, "COMMON");
+ else
+ h->u.c.p->section = bfd_make_section_old_way (symbfd,
+ p->section->name);
+ h->u.c.p->section->flags = SEC_ALLOC;
+ }
+ else
+ {
+ /* Adjust the size of the common symbol if necessary. This
+ is how a.out works. Object formats that require
+ different semantics must implement this function
+ differently. */
+ if (bfd_asymbol_value (p) > h->u.c.size)
+ h->u.c.size = bfd_asymbol_value (p);
+ }
+ }
+
+ /* This archive element is not needed. */
+ return true;
+}
+
+/* Add the symbols from an object file to the global hash table. ABFD
+ is the object file. INFO is the linker information. SYMBOL_COUNT
+ is the number of symbols. SYMBOLS is the list of symbols. COLLECT
+ is true if constructors should be automatically collected by name
+ as is done by collect2. */
+
+static boolean
+generic_link_add_symbol_list (abfd, info, symbol_count, symbols, collect)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ bfd_size_type symbol_count;
+ asymbol **symbols;
+ boolean collect;
+{
+ asymbol **pp, **ppend;
+
+ pp = symbols;
+ ppend = symbols + symbol_count;
+ for (; pp < ppend; pp++)
+ {
+ asymbol *p;
+
+ p = *pp;
+
+ if ((p->flags & (BSF_INDIRECT
+ | BSF_WARNING
+ | BSF_GLOBAL
+ | BSF_CONSTRUCTOR
+ | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (p))
+ || bfd_is_com_section (bfd_get_section (p))
+ || bfd_is_ind_section (bfd_get_section (p)))
+ {
+ const char *name;
+ const char *string;
+ struct generic_link_hash_entry *h;
+
+ name = bfd_asymbol_name (p);
+ if (((p->flags & BSF_INDIRECT) != 0
+ || bfd_is_ind_section (p->section))
+ && pp + 1 < ppend)
+ {
+ pp++;
+ string = bfd_asymbol_name (*pp);
+ }
+ else if ((p->flags & BSF_WARNING) != 0
+ && pp + 1 < ppend)
+ {
+ /* The name of P is actually the warning string, and the
+ next symbol is the one to warn about. */
+ string = name;
+ pp++;
+ name = bfd_asymbol_name (*pp);
+ }
+ else
+ string = NULL;
+
+ h = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, p->flags, bfd_get_section (p),
+ p->value, string, false, collect,
+ (struct bfd_link_hash_entry **) &h)))
+ return false;
+
+ /* If this is a constructor symbol, and the linker didn't do
+ anything with it, then we want to just pass the symbol
+ through to the output file. This will happen when
+ linking with -r. */
+ if ((p->flags & BSF_CONSTRUCTOR) != 0
+ && (h == NULL || h->root.type == bfd_link_hash_new))
+ {
+ p->udata.p = NULL;
+ continue;
+ }
+
+ /* Save the BFD symbol so that we don't lose any backend
+ specific information that may be attached to it. We only
+ want this one if it gives more information than the
+ existing one; we don't want to replace a defined symbol
+ with an undefined one. This routine may be called with a
+ hash table other than the generic hash table, so we only
+ do this if we are certain that the hash table is a
+ generic one. */
+ if (info->hash->creator == abfd->xvec)
+ {
+ if (h->sym == (asymbol *) NULL
+ || (! bfd_is_und_section (bfd_get_section (p))
+ && (! bfd_is_com_section (bfd_get_section (p))
+ || bfd_is_und_section (bfd_get_section (h->sym)))))
+ {
+ h->sym = p;
+ /* BSF_OLD_COMMON is a hack to support COFF reloc
+ reading, and it should go away when the COFF
+ linker is switched to the new version. */
+ if (bfd_is_com_section (bfd_get_section (p)))
+ p->flags |= BSF_OLD_COMMON;
+ }
+ }
+
+ /* Store a back pointer from the symbol to the hash
+ table entry for the benefit of relaxation code until
+ it gets rewritten to not use asymbol structures.
+ Setting this is also used to check whether these
+ symbols were set up by the generic linker. */
+ p->udata.p = (PTR) h;
+ }
+ }
+
+ return true;
+}
+
+/* We use a state table to deal with adding symbols from an object
+ file. The first index into the state table describes the symbol
+ from the object file. The second index into the state table is the
+ type of the symbol in the hash table. */
+
+/* The symbol from the object file is turned into one of these row
+ values. */
+
+enum link_row
+{
+ UNDEF_ROW, /* Undefined. */
+ UNDEFW_ROW, /* Weak undefined. */
+ DEF_ROW, /* Defined. */
+ DEFW_ROW, /* Weak defined. */
+ COMMON_ROW, /* Common. */
+ INDR_ROW, /* Indirect. */
+ WARN_ROW, /* Warning. */
+ SET_ROW /* Member of set. */
+};
+
+/* apparently needed for Hitachi 3050R(HI-UX/WE2)? */
+#undef FAIL
+
+/* The actions to take in the state table. */
+
+enum link_action
+{
+ FAIL, /* Abort. */
+ UND, /* Mark symbol undefined. */
+ WEAK, /* Mark symbol weak undefined. */
+ DEF, /* Mark symbol defined. */
+ DEFW, /* Mark symbol weak defined. */
+ COM, /* Mark symbol common. */
+ REF, /* Mark defined symbol referenced. */
+ CREF, /* Possibly warn about common reference to defined symbol. */
+ CDEF, /* Define existing common symbol. */
+ NOACT, /* No action. */
+ BIG, /* Mark symbol common using largest size. */
+ MDEF, /* Multiple definition error. */
+ MIND, /* Multiple indirect symbols. */
+ IND, /* Make indirect symbol. */
+ CIND, /* Make indirect symbol from existing common symbol. */
+ SET, /* Add value to set. */
+ MWARN, /* Make warning symbol. */
+ WARN, /* Issue warning. */
+ CWARN, /* Warn if referenced, else MWARN. */
+ CYCLE, /* Repeat with symbol pointed to. */
+ REFC, /* Mark indirect symbol referenced and then CYCLE. */
+ WARNC /* Issue warning and then CYCLE. */
+};
+
+/* The state table itself. The first index is a link_row and the
+ second index is a bfd_link_hash_type. */
+
+static const enum link_action link_action[8][8] =
+{
+ /* current\prev new undef undefw def defw com indr warn */
+ /* UNDEF_ROW */ {UND, NOACT, UND, REF, REF, NOACT, REFC, WARNC },
+ /* UNDEFW_ROW */ {WEAK, NOACT, NOACT, REF, REF, NOACT, REFC, WARNC },
+ /* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MDEF, CYCLE },
+ /* DEFW_ROW */ {DEFW, DEFW, DEFW, NOACT, NOACT, NOACT, NOACT, CYCLE },
+ /* COMMON_ROW */ {COM, COM, COM, CREF, CREF, BIG, REFC, WARNC },
+ /* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE },
+ /* WARN_ROW */ {MWARN, WARN, WARN, CWARN, CWARN, WARN, CWARN, MWARN },
+ /* SET_ROW */ {SET, SET, SET, SET, SET, SET, CYCLE, CYCLE }
+};
+
+/* Most of the entries in the LINK_ACTION table are straightforward,
+ but a few are somewhat subtle.
+
+ A reference to an indirect symbol (UNDEF_ROW/indr or
+ UNDEFW_ROW/indr) is counted as a reference both to the indirect
+ symbol and to the symbol the indirect symbol points to.
+
+ A reference to a warning symbol (UNDEF_ROW/warn or UNDEFW_ROW/warn)
+ causes the warning to be issued.
+
+ A common definition of an indirect symbol (COMMON_ROW/indr) is
+ treated as a multiple definition error. Likewise for an indirect
+ definition of a common symbol (INDR_ROW/com).
+
+ An indirect definition of a warning (INDR_ROW/warn) does not cause
+ the warning to be issued.
+
+ If a warning is created for an indirect symbol (WARN_ROW/indr) no
+ warning is created for the symbol the indirect symbol points to.
+
+ Adding an entry to a set does not count as a reference to a set,
+ and no warning is issued (SET_ROW/warn). */
+
+/* Return the BFD in which a hash entry has been defined, if known. */
+
+static bfd *
+hash_entry_bfd (h)
+ struct bfd_link_hash_entry *h;
+{
+ while (h->type == bfd_link_hash_warning)
+ h = h->u.i.link;
+ switch (h->type)
+ {
+ default:
+ return NULL;
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ return h->u.undef.abfd;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->u.def.section->owner;
+ case bfd_link_hash_common:
+ return h->u.c.p->section->owner;
+ }
+ /*NOTREACHED*/
+}
+
+/* Add a symbol to the global hash table.
+ ABFD is the BFD the symbol comes from.
+ NAME is the name of the symbol.
+ FLAGS is the BSF_* bits associated with the symbol.
+ SECTION is the section in which the symbol is defined; this may be
+ bfd_und_section_ptr or bfd_com_section_ptr.
+ VALUE is the value of the symbol, relative to the section.
+ STRING is used for either an indirect symbol, in which case it is
+ the name of the symbol to indirect to, or a warning symbol, in
+ which case it is the warning string.
+ COPY is true if NAME or STRING must be copied into locally
+ allocated memory if they need to be saved.
+ COLLECT is true if we should automatically collect gcc constructor
+ or destructor names as collect2 does.
+ HASHP, if not NULL, is a place to store the created hash table
+ entry; if *HASHP is not NULL, the caller has already looked up
+ the hash table entry, and stored it in *HASHP. */
+
+boolean
+_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
+ string, copy, collect, hashp)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ const char *string;
+ boolean copy;
+ boolean collect;
+ struct bfd_link_hash_entry **hashp;
+{
+ enum link_row row;
+ struct bfd_link_hash_entry *h;
+ boolean cycle;
+
+ if (bfd_is_ind_section (section)
+ || (flags & BSF_INDIRECT) != 0)
+ row = INDR_ROW;
+ else if ((flags & BSF_WARNING) != 0)
+ row = WARN_ROW;
+ else if ((flags & BSF_CONSTRUCTOR) != 0)
+ row = SET_ROW;
+ else if (bfd_is_und_section (section))
+ {
+ if ((flags & BSF_WEAK) != 0)
+ row = UNDEFW_ROW;
+ else
+ row = UNDEF_ROW;
+ }
+ else if ((flags & BSF_WEAK) != 0)
+ row = DEFW_ROW;
+ else if (bfd_is_com_section (section))
+ row = COMMON_ROW;
+ else
+ row = DEF_ROW;
+
+ if (hashp != NULL && *hashp != NULL)
+ h = *hashp;
+ else
+ {
+ if (row == UNDEF_ROW || row == UNDEFW_ROW)
+ h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false);
+ else
+ h = bfd_link_hash_lookup (info->hash, name, true, copy, false);
+ if (h == NULL)
+ {
+ if (hashp != NULL)
+ *hashp = NULL;
+ return false;
+ }
+ }
+
+ if (info->notice_all
+ || (info->notice_hash != (struct bfd_hash_table *) NULL
+ && (bfd_hash_lookup (info->notice_hash, name, false, false)
+ != (struct bfd_hash_entry *) NULL)))
+ {
+ if (! (*info->callbacks->notice) (info, h->root.string, abfd, section,
+ value))
+ return false;
+ }
+
+ if (hashp != (struct bfd_link_hash_entry **) NULL)
+ *hashp = h;
+
+ do
+ {
+ enum link_action action;
+
+ cycle = false;
+ action = link_action[(int) row][(int) h->type];
+ switch (action)
+ {
+ case FAIL:
+ abort ();
+
+ case NOACT:
+ /* Do nothing. */
+ break;
+
+ case UND:
+ /* Make a new undefined symbol. */
+ h->type = bfd_link_hash_undefined;
+ h->u.undef.abfd = abfd;
+ bfd_link_add_undef (info->hash, h);
+ break;
+
+ case WEAK:
+ /* Make a new weak undefined symbol. */
+ h->type = bfd_link_hash_undefweak;
+ h->u.undef.abfd = abfd;
+ break;
+
+ case CDEF:
+ /* We have found a definition for a symbol which was
+ previously common. */
+ BFD_ASSERT (h->type == bfd_link_hash_common);
+ if (! ((*info->callbacks->multiple_common)
+ (info, h->root.string,
+ h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
+ abfd, bfd_link_hash_defined, (bfd_vma) 0)))
+ return false;
+ /* Fall through. */
+ case DEF:
+ case DEFW:
+ {
+ enum bfd_link_hash_type oldtype;
+
+ /* Define a symbol. */
+ oldtype = h->type;
+ if (action == DEFW)
+ h->type = bfd_link_hash_defweak;
+ else
+ h->type = bfd_link_hash_defined;
+ h->u.def.section = section;
+ h->u.def.value = value;
+
+ /* If we have been asked to, we act like collect2 and
+ identify all functions that might be global
+ constructors and destructors and pass them up in a
+ callback. We only do this for certain object file
+ types, since many object file types can handle this
+ automatically. */
+ if (collect && name[0] == '_')
+ {
+ const char *s;
+
+ /* A constructor or destructor name starts like this:
+ _+GLOBAL_[_.$][ID][_.$] where the first [_.$] and
+ the second are the same character (we accept any
+ character there, in case a new object file format
+ comes along with even worse naming restrictions). */
+
+#define CONS_PREFIX "GLOBAL_"
+#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1)
+
+ s = name + 1;
+ while (*s == '_')
+ ++s;
+ if (s[0] == 'G'
+ && strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0)
+ {
+ char c;
+
+ c = s[CONS_PREFIX_LEN + 1];
+ if ((c == 'I' || c == 'D')
+ && s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2])
+ {
+ /* If this is a definition of a symbol which
+ was previously weakly defined, we are in
+ trouble. We have already added a
+ constructor entry for the weak defined
+ symbol, and now we are trying to add one
+ for the new symbol. Fortunately, this case
+ should never arise in practice. */
+ if (oldtype == bfd_link_hash_defweak)
+ abort ();
+
+ if (! ((*info->callbacks->constructor)
+ (info,
+ c == 'I' ? true : false,
+ h->root.string, abfd, section, value)))
+ return false;
+ }
+ }
+ }
+ }
+
+ break;
+
+ case COM:
+ /* We have found a common definition for a symbol. */
+ if (h->type == bfd_link_hash_new)
+ bfd_link_add_undef (info->hash, h);
+ h->type = bfd_link_hash_common;
+ h->u.c.p =
+ ((struct bfd_link_hash_common_entry *)
+ bfd_hash_allocate (&info->hash->table,
+ sizeof (struct bfd_link_hash_common_entry)));
+ if (h->u.c.p == NULL)
+ return false;
+
+ h->u.c.size = value;
+
+ /* Select a default alignment based on the size. This may
+ be overridden by the caller. */
+ {
+ unsigned int power;
+
+ power = bfd_log2 (value);
+ if (power > 4)
+ power = 4;
+ h->u.c.p->alignment_power = power;
+ }
+
+ /* The section of a common symbol is only used if the common
+ symbol is actually allocated. It basically provides a
+ hook for the linker script to decide which output section
+ the common symbols should be put in. In most cases, the
+ section of a common symbol will be bfd_com_section_ptr,
+ the code here will choose a common symbol section named
+ "COMMON", and the linker script will contain *(COMMON) in
+ the appropriate place. A few targets use separate common
+ sections for small symbols, and they require special
+ handling. */
+ if (section == bfd_com_section_ptr)
+ {
+ h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON");
+ h->u.c.p->section->flags = SEC_ALLOC;
+ }
+ else if (section->owner != abfd)
+ {
+ h->u.c.p->section = bfd_make_section_old_way (abfd,
+ section->name);
+ h->u.c.p->section->flags = SEC_ALLOC;
+ }
+ else
+ h->u.c.p->section = section;
+ break;
+
+ case REF:
+ /* A reference to a defined symbol. */
+ if (h->next == NULL && info->hash->undefs_tail != h)
+ h->next = h;
+ break;
+
+ case BIG:
+ /* We have found a common definition for a symbol which
+ already had a common definition. Use the maximum of the
+ two sizes. */
+ BFD_ASSERT (h->type == bfd_link_hash_common);
+ if (! ((*info->callbacks->multiple_common)
+ (info, h->root.string,
+ h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
+ abfd, bfd_link_hash_common, value)))
+ return false;
+ if (value > h->u.c.size)
+ {
+ unsigned int power;
+
+ h->u.c.size = value;
+
+ /* Select a default alignment based on the size. This may
+ be overridden by the caller. */
+ power = bfd_log2 (value);
+ if (power > 4)
+ power = 4;
+ h->u.c.p->alignment_power = power;
+ }
+ break;
+
+ case CREF:
+ {
+ bfd *obfd;
+
+ /* We have found a common definition for a symbol which
+ was already defined. FIXME: It would nice if we could
+ report the BFD which defined an indirect symbol, but we
+ don't have anywhere to store the information. */
+ if (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
+ obfd = h->u.def.section->owner;
+ else
+ obfd = NULL;
+ if (! ((*info->callbacks->multiple_common)
+ (info, h->root.string, obfd, h->type, (bfd_vma) 0,
+ abfd, bfd_link_hash_common, value)))
+ return false;
+ }
+ break;
+
+ case MIND:
+ /* Multiple indirect symbols. This is OK if they both point
+ to the same symbol. */
+ if (strcmp (h->u.i.link->root.string, string) == 0)
+ break;
+ /* Fall through. */
+ case MDEF:
+ /* Handle a multiple definition. */
+ {
+ asection *msec;
+ bfd_vma mval;
+
+ switch (h->type)
+ {
+ case bfd_link_hash_defined:
+ msec = h->u.def.section;
+ mval = h->u.def.value;
+ break;
+ case bfd_link_hash_indirect:
+ msec = bfd_ind_section_ptr;
+ mval = 0;
+ break;
+ default:
+ abort ();
+ }
+
+ /* Ignore a redefinition of an absolute symbol to the same
+ value; it's harmless. */
+ if (h->type == bfd_link_hash_defined
+ && bfd_is_abs_section (msec)
+ && bfd_is_abs_section (section)
+ && value == mval)
+ break;
+
+ if (! ((*info->callbacks->multiple_definition)
+ (info, h->root.string, msec->owner, msec, mval, abfd,
+ section, value)))
+ return false;
+ }
+ break;
+
+ case CIND:
+ /* Create an indirect symbol from an existing common symbol. */
+ BFD_ASSERT (h->type == bfd_link_hash_common);
+ if (! ((*info->callbacks->multiple_common)
+ (info, h->root.string,
+ h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
+ abfd, bfd_link_hash_indirect, (bfd_vma) 0)))
+ return false;
+ /* Fall through. */
+ case IND:
+ /* Create an indirect symbol. */
+ {
+ struct bfd_link_hash_entry *inh;
+
+ /* STRING is the name of the symbol we want to indirect
+ to. */
+ inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true,
+ copy, false);
+ if (inh == (struct bfd_link_hash_entry *) NULL)
+ return false;
+ if (inh->type == bfd_link_hash_new)
+ {
+ inh->type = bfd_link_hash_undefined;
+ inh->u.undef.abfd = abfd;
+ bfd_link_add_undef (info->hash, inh);
+ }
+
+ /* If the indirect symbol has been referenced, we need to
+ push the reference down to the symbol we are
+ referencing. */
+ if (h->type != bfd_link_hash_new)
+ {
+ row = UNDEF_ROW;
+ cycle = true;
+ }
+
+ h->type = bfd_link_hash_indirect;
+ h->u.i.link = inh;
+ }
+ break;
+
+ case SET:
+ /* Add an entry to a set. */
+ if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR,
+ abfd, section, value))
+ return false;
+ break;
+
+ case WARNC:
+ /* Issue a warning and cycle. */
+ if (h->u.i.warning != NULL)
+ {
+ if (! (*info->callbacks->warning) (info, h->u.i.warning,
+ h->root.string, abfd,
+ (asection *) NULL,
+ (bfd_vma) 0))
+ return false;
+ /* Only issue a warning once. */
+ h->u.i.warning = NULL;
+ }
+ /* Fall through. */
+ case CYCLE:
+ /* Try again with the referenced symbol. */
+ h = h->u.i.link;
+ cycle = true;
+ break;
+
+ case REFC:
+ /* A reference to an indirect symbol. */
+ if (h->next == NULL && info->hash->undefs_tail != h)
+ h->next = h;
+ h = h->u.i.link;
+ cycle = true;
+ break;
+
+ case WARN:
+ /* Issue a warning. */
+ if (! (*info->callbacks->warning) (info, string, h->root.string,
+ hash_entry_bfd (h),
+ (asection *) NULL, (bfd_vma) 0))
+ return false;
+ break;
+
+ case CWARN:
+ /* Warn if this symbol has been referenced already,
+ otherwise add a warning. A symbol has been referenced if
+ the next field is not NULL, or it is the tail of the
+ undefined symbol list. The REF case above helps to
+ ensure this. */
+ if (h->next != NULL || info->hash->undefs_tail == h)
+ {
+ if (! (*info->callbacks->warning) (info, string, h->root.string,
+ hash_entry_bfd (h),
+ (asection *) NULL,
+ (bfd_vma) 0))
+ return false;
+ break;
+ }
+ /* Fall through. */
+ case MWARN:
+ /* Make a warning symbol. */
+ {
+ struct bfd_link_hash_entry *sub;
+
+ /* STRING is the warning to give. */
+ sub = ((struct bfd_link_hash_entry *)
+ ((*info->hash->table.newfunc)
+ ((struct bfd_hash_entry *) NULL, &info->hash->table,
+ h->root.string)));
+ if (sub == NULL)
+ return false;
+ *sub = *h;
+ sub->type = bfd_link_hash_warning;
+ sub->u.i.link = h;
+ if (! copy)
+ sub->u.i.warning = string;
+ else
+ {
+ char *w;
+
+ w = bfd_hash_allocate (&info->hash->table,
+ strlen (string) + 1);
+ if (w == NULL)
+ return false;
+ strcpy (w, string);
+ sub->u.i.warning = w;
+ }
+
+ bfd_hash_replace (&info->hash->table,
+ (struct bfd_hash_entry *) h,
+ (struct bfd_hash_entry *) sub);
+ if (hashp != NULL)
+ *hashp = sub;
+ }
+ break;
+ }
+ }
+ while (cycle);
+
+ return true;
+}
+
+/* Generic final link routine. */
+
+boolean
+_bfd_generic_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd *sub;
+ asection *o;
+ struct bfd_link_order *p;
+ size_t outsymalloc;
+ struct generic_write_global_symbol_info wginfo;
+
+ bfd_get_outsymbols (abfd) = (asymbol **) NULL;
+ bfd_get_symcount (abfd) = 0;
+ outsymalloc = 0;
+
+ /* Mark all sections which will be included in the output file. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ if (p->type == bfd_indirect_link_order)
+ p->u.indirect.section->linker_mark = true;
+
+ /* Build the output symbol table. */
+ for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
+ if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc))
+ return false;
+
+ /* Accumulate the global symbols. */
+ wginfo.info = info;
+ wginfo.output_bfd = abfd;
+ wginfo.psymalloc = &outsymalloc;
+ _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info),
+ _bfd_generic_link_write_global_symbol,
+ (PTR) &wginfo);
+
+ /* Make sure we have a trailing NULL pointer on OUTSYMBOLS. We
+ shouldn't really need one, since we have SYMCOUNT, but some old
+ code still expects one. */
+ if (! generic_add_output_symbol (abfd, &outsymalloc, NULL))
+ return false;
+
+ if (info->relocateable)
+ {
+ /* Allocate space for the output relocs for each section. */
+ for (o = abfd->sections;
+ o != (asection *) NULL;
+ o = o->next)
+ {
+ o->reloc_count = 0;
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ ++o->reloc_count;
+ else if (p->type == bfd_indirect_link_order)
+ {
+ asection *input_section;
+ bfd *input_bfd;
+ long relsize;
+ arelent **relocs;
+ asymbol **symbols;
+ long reloc_count;
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+ relsize = bfd_get_reloc_upper_bound (input_bfd,
+ input_section);
+ if (relsize < 0)
+ return false;
+ relocs = (arelent **) bfd_malloc ((size_t) relsize);
+ if (!relocs && relsize != 0)
+ return false;
+ symbols = _bfd_generic_link_get_symbols (input_bfd);
+ reloc_count = bfd_canonicalize_reloc (input_bfd,
+ input_section,
+ relocs,
+ symbols);
+ if (reloc_count < 0)
+ return false;
+ BFD_ASSERT ((unsigned long) reloc_count
+ == input_section->reloc_count);
+ o->reloc_count += reloc_count;
+ free (relocs);
+ }
+ }
+ if (o->reloc_count > 0)
+ {
+ o->orelocation = ((arelent **)
+ bfd_alloc (abfd,
+ (o->reloc_count
+ * sizeof (arelent *))));
+ if (!o->orelocation)
+ return false;
+ o->flags |= SEC_RELOC;
+ /* Reset the count so that it can be used as an index
+ when putting in the output relocs. */
+ o->reloc_count = 0;
+ }
+ }
+ }
+
+ /* Handle all the link order information for the sections. */
+ for (o = abfd->sections;
+ o != (asection *) NULL;
+ o = o->next)
+ {
+ for (p = o->link_order_head;
+ p != (struct bfd_link_order *) NULL;
+ p = p->next)
+ {
+ switch (p->type)
+ {
+ case bfd_section_reloc_link_order:
+ case bfd_symbol_reloc_link_order:
+ if (! _bfd_generic_reloc_link_order (abfd, info, o, p))
+ return false;
+ break;
+ case bfd_indirect_link_order:
+ if (! default_indirect_link_order (abfd, info, o, p, true))
+ return false;
+ break;
+ default:
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Add an output symbol to the output BFD. */
+
+static boolean
+generic_add_output_symbol (output_bfd, psymalloc, sym)
+ bfd *output_bfd;
+ size_t *psymalloc;
+ asymbol *sym;
+{
+ if (bfd_get_symcount (output_bfd) >= *psymalloc)
+ {
+ asymbol **newsyms;
+
+ if (*psymalloc == 0)
+ *psymalloc = 124;
+ else
+ *psymalloc *= 2;
+ newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd),
+ *psymalloc * sizeof (asymbol *));
+ if (newsyms == (asymbol **) NULL)
+ return false;
+ bfd_get_outsymbols (output_bfd) = newsyms;
+ }
+
+ bfd_get_outsymbols (output_bfd) [bfd_get_symcount (output_bfd)] = sym;
+ if (sym != NULL)
+ ++ bfd_get_symcount (output_bfd);
+
+ return true;
+}
+
+/* Handle the symbols for an input BFD. */
+
+boolean
+_bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc)
+ bfd *output_bfd;
+ bfd *input_bfd;
+ struct bfd_link_info *info;
+ size_t *psymalloc;
+{
+ asymbol **sym_ptr;
+ asymbol **sym_end;
+
+ if (! generic_link_read_symbols (input_bfd))
+ return false;
+
+ /* Create a filename symbol if we are supposed to. */
+ if (info->create_object_symbols_section != (asection *) NULL)
+ {
+ asection *sec;
+
+ for (sec = input_bfd->sections;
+ sec != (asection *) NULL;
+ sec = sec->next)
+ {
+ if (sec->output_section == info->create_object_symbols_section)
+ {
+ asymbol *newsym;
+
+ newsym = bfd_make_empty_symbol (input_bfd);
+ if (!newsym)
+ return false;
+ newsym->name = input_bfd->filename;
+ newsym->value = 0;
+ newsym->flags = BSF_LOCAL | BSF_FILE;
+ newsym->section = sec;
+
+ if (! generic_add_output_symbol (output_bfd, psymalloc,
+ newsym))
+ return false;
+
+ break;
+ }
+ }
+ }
+
+ /* Adjust the values of the globally visible symbols, and write out
+ local symbols. */
+ sym_ptr = _bfd_generic_link_get_symbols (input_bfd);
+ sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd);
+ for (; sym_ptr < sym_end; sym_ptr++)
+ {
+ asymbol *sym;
+ struct generic_link_hash_entry *h;
+ boolean output;
+
+ h = (struct generic_link_hash_entry *) NULL;
+ sym = *sym_ptr;
+ if ((sym->flags & (BSF_INDIRECT
+ | BSF_WARNING
+ | BSF_GLOBAL
+ | BSF_CONSTRUCTOR
+ | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym))
+ || bfd_is_ind_section (bfd_get_section (sym)))
+ {
+ if (sym->udata.p != NULL)
+ h = (struct generic_link_hash_entry *) sym->udata.p;
+ else if ((sym->flags & BSF_CONSTRUCTOR) != 0)
+ {
+ /* This case normally means that the main linker code
+ deliberately ignored this constructor symbol. We
+ should just pass it through. This will screw up if
+ the constructor symbol is from a different,
+ non-generic, object file format, but the case will
+ only arise when linking with -r, which will probably
+ fail anyhow, since there will be no way to represent
+ the relocs in the output format being used. */
+ h = NULL;
+ }
+ else if (bfd_is_und_section (bfd_get_section (sym)))
+ h = ((struct generic_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (output_bfd, info,
+ bfd_asymbol_name (sym),
+ false, false, true));
+ else
+ h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info),
+ bfd_asymbol_name (sym),
+ false, false, true);
+
+ if (h != (struct generic_link_hash_entry *) NULL)
+ {
+ /* Force all references to this symbol to point to
+ the same area in memory. It is possible that
+ this routine will be called with a hash table
+ other than a generic hash table, so we double
+ check that. */
+ if (info->hash->creator == input_bfd->xvec)
+ {
+ if (h->sym != (asymbol *) NULL)
+ *sym_ptr = sym = h->sym;
+ }
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ abort ();
+ case bfd_link_hash_undefined:
+ break;
+ case bfd_link_hash_undefweak:
+ sym->flags |= BSF_WEAK;
+ break;
+ case bfd_link_hash_indirect:
+ h = (struct generic_link_hash_entry *) h->root.u.i.link;
+ /* fall through */
+ case bfd_link_hash_defined:
+ sym->flags |= BSF_GLOBAL;
+ sym->flags &=~ BSF_CONSTRUCTOR;
+ sym->value = h->root.u.def.value;
+ sym->section = h->root.u.def.section;
+ break;
+ case bfd_link_hash_defweak:
+ sym->flags |= BSF_WEAK;
+ sym->flags &=~ BSF_CONSTRUCTOR;
+ sym->value = h->root.u.def.value;
+ sym->section = h->root.u.def.section;
+ break;
+ case bfd_link_hash_common:
+ sym->value = h->root.u.c.size;
+ sym->flags |= BSF_GLOBAL;
+ if (! bfd_is_com_section (sym->section))
+ {
+ BFD_ASSERT (bfd_is_und_section (sym->section));
+ sym->section = bfd_com_section_ptr;
+ }
+ /* We do not set the section of the symbol to
+ h->root.u.c.p->section. That value was saved so
+ that we would know where to allocate the symbol
+ if it was defined. In this case the type is
+ still bfd_link_hash_common, so we did not define
+ it, so we do not want to use that section. */
+ break;
+ }
+ }
+ }
+
+ /* This switch is straight from the old code in
+ write_file_locals in ldsym.c. */
+ if (info->strip == strip_all
+ || (info->strip == strip_some
+ && (bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
+ false, false)
+ == (struct bfd_hash_entry *) NULL)))
+ output = false;
+ else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
+ {
+ /* If this symbol is marked as occurring now, rather
+ than at the end, output it now. This is used for
+ COFF C_EXT FCN symbols. FIXME: There must be a
+ better way. */
+ if (bfd_asymbol_bfd (sym) == input_bfd
+ && (sym->flags & BSF_NOT_AT_END) != 0)
+ output = true;
+ else
+ output = false;
+ }
+ else if (bfd_is_ind_section (sym->section))
+ output = false;
+ else if ((sym->flags & BSF_DEBUGGING) != 0)
+ {
+ if (info->strip == strip_none)
+ output = true;
+ else
+ output = false;
+ }
+ else if (bfd_is_und_section (sym->section)
+ || bfd_is_com_section (sym->section))
+ output = false;
+ else if ((sym->flags & BSF_LOCAL) != 0)
+ {
+ if ((sym->flags & BSF_WARNING) != 0)
+ output = false;
+ else
+ {
+ switch (info->discard)
+ {
+ default:
+ case discard_all:
+ output = false;
+ break;
+ case discard_l:
+ if (bfd_is_local_label (input_bfd, sym))
+ output = false;
+ else
+ output = true;
+ break;
+ case discard_none:
+ output = true;
+ break;
+ }
+ }
+ }
+ else if ((sym->flags & BSF_CONSTRUCTOR))
+ {
+ if (info->strip != strip_all)
+ output = true;
+ else
+ output = false;
+ }
+ else
+ abort ();
+
+ /* If this symbol is in a section which is not being included
+ in the output file, then we don't want to output the symbol.
+
+ Gross. .bss and similar sections won't have the linker_mark
+ field set. */
+ if ((sym->section->flags & SEC_HAS_CONTENTS) != 0
+ && sym->section->linker_mark == false)
+ output = false;
+
+ if (output)
+ {
+ if (! generic_add_output_symbol (output_bfd, psymalloc, sym))
+ return false;
+ if (h != (struct generic_link_hash_entry *) NULL)
+ h->written = true;
+ }
+ }
+
+ return true;
+}
+
+/* Set the section and value of a generic BFD symbol based on a linker
+ hash table entry. */
+
+static void
+set_symbol_from_hash (sym, h)
+ asymbol *sym;
+ struct bfd_link_hash_entry *h;
+{
+ switch (h->type)
+ {
+ default:
+ abort ();
+ break;
+ case bfd_link_hash_new:
+ /* This can happen when a constructor symbol is seen but we are
+ not building constructors. */
+ if (sym->section != NULL)
+ {
+ BFD_ASSERT ((sym->flags & BSF_CONSTRUCTOR) != 0);
+ }
+ else
+ {
+ sym->flags |= BSF_CONSTRUCTOR;
+ sym->section = bfd_abs_section_ptr;
+ sym->value = 0;
+ }
+ break;
+ case bfd_link_hash_undefined:
+ sym->section = bfd_und_section_ptr;
+ sym->value = 0;
+ break;
+ case bfd_link_hash_undefweak:
+ sym->section = bfd_und_section_ptr;
+ sym->value = 0;
+ sym->flags |= BSF_WEAK;
+ break;
+ case bfd_link_hash_defined:
+ sym->section = h->u.def.section;
+ sym->value = h->u.def.value;
+ break;
+ case bfd_link_hash_defweak:
+ sym->flags |= BSF_WEAK;
+ sym->section = h->u.def.section;
+ sym->value = h->u.def.value;
+ break;
+ case bfd_link_hash_common:
+ sym->value = h->u.c.size;
+ if (sym->section == NULL)
+ sym->section = bfd_com_section_ptr;
+ else if (! bfd_is_com_section (sym->section))
+ {
+ BFD_ASSERT (bfd_is_und_section (sym->section));
+ sym->section = bfd_com_section_ptr;
+ }
+ /* Do not set the section; see _bfd_generic_link_output_symbols. */
+ break;
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ /* FIXME: What should we do here? */
+ break;
+ }
+}
+
+/* Write out a global symbol, if it hasn't already been written out.
+ This is called for each symbol in the hash table. */
+
+boolean
+_bfd_generic_link_write_global_symbol (h, data)
+ struct generic_link_hash_entry *h;
+ PTR data;
+{
+ struct generic_write_global_symbol_info *wginfo =
+ (struct generic_write_global_symbol_info *) data;
+ asymbol *sym;
+
+ if (h->written)
+ return true;
+
+ h->written = true;
+
+ if (wginfo->info->strip == strip_all
+ || (wginfo->info->strip == strip_some
+ && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string,
+ false, false) == NULL))
+ return true;
+
+ if (h->sym != (asymbol *) NULL)
+ sym = h->sym;
+ else
+ {
+ sym = bfd_make_empty_symbol (wginfo->output_bfd);
+ if (!sym)
+ return false;
+ sym->name = h->root.root.string;
+ sym->flags = 0;
+ }
+
+ set_symbol_from_hash (sym, &h->root);
+
+ sym->flags |= BSF_GLOBAL;
+
+ if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc,
+ sym))
+ {
+ /* FIXME: No way to return failure. */
+ abort ();
+ }
+
+ return true;
+}
+
+/* Create a relocation. */
+
+boolean
+_bfd_generic_reloc_link_order (abfd, info, sec, link_order)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ struct bfd_link_order *link_order;
+{
+ arelent *r;
+
+ if (! info->relocateable)
+ abort ();
+ if (sec->orelocation == (arelent **) NULL)
+ abort ();
+
+ r = (arelent *) bfd_alloc (abfd, sizeof (arelent));
+ if (r == (arelent *) NULL)
+ return false;
+
+ r->address = link_order->offset;
+ r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
+ if (r->howto == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ /* Get the symbol to use for the relocation. */
+ if (link_order->type == bfd_section_reloc_link_order)
+ r->sym_ptr_ptr = link_order->u.reloc.p->u.section->symbol_ptr_ptr;
+ else
+ {
+ struct generic_link_hash_entry *h;
+
+ h = ((struct generic_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (abfd, info,
+ link_order->u.reloc.p->u.name,
+ false, false, true));
+ if (h == (struct generic_link_hash_entry *) NULL
+ || ! h->written)
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name,
+ (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ r->sym_ptr_ptr = &h->sym;
+ }
+
+ /* If this is an inplace reloc, write the addend to the object file.
+ Otherwise, store it in the reloc addend. */
+ if (! r->howto->partial_inplace)
+ r->addend = link_order->u.reloc.p->addend;
+ else
+ {
+ bfd_size_type size;
+ bfd_reloc_status_type rstat;
+ bfd_byte *buf;
+ boolean ok;
+
+ size = bfd_get_reloc_size (r->howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == (bfd_byte *) NULL)
+ return false;
+ rstat = _bfd_relocate_contents (r->howto, abfd,
+ link_order->u.reloc.p->addend, buf);
+ switch (rstat)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info,
+ (link_order->type == bfd_section_reloc_link_order
+ ? bfd_section_name (abfd, link_order->u.reloc.p->u.section)
+ : link_order->u.reloc.p->u.name),
+ r->howto->name, link_order->u.reloc.p->addend,
+ (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return false;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (abfd, sec, (PTR) buf,
+ (file_ptr) link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return false;
+
+ r->addend = 0;
+ }
+
+ sec->orelocation[sec->reloc_count] = r;
+ ++sec->reloc_count;
+
+ return true;
+}
+
+/* Allocate a new link_order for a section. */
+
+struct bfd_link_order *
+bfd_new_link_order (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ struct bfd_link_order *new;
+
+ new = ((struct bfd_link_order *)
+ bfd_alloc (abfd, sizeof (struct bfd_link_order)));
+ if (!new)
+ return NULL;
+
+ new->type = bfd_undefined_link_order;
+ new->offset = 0;
+ new->size = 0;
+ new->next = (struct bfd_link_order *) NULL;
+
+ if (section->link_order_tail != (struct bfd_link_order *) NULL)
+ section->link_order_tail->next = new;
+ else
+ section->link_order_head = new;
+ section->link_order_tail = new;
+
+ return new;
+}
+
+/* Default link order processing routine. Note that we can not handle
+ the reloc_link_order types here, since they depend upon the details
+ of how the particular backends generates relocs. */
+
+boolean
+_bfd_default_link_order (abfd, info, sec, link_order)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ struct bfd_link_order *link_order;
+{
+ switch (link_order->type)
+ {
+ case bfd_undefined_link_order:
+ case bfd_section_reloc_link_order:
+ case bfd_symbol_reloc_link_order:
+ default:
+ abort ();
+ case bfd_indirect_link_order:
+ return default_indirect_link_order (abfd, info, sec, link_order,
+ false);
+ case bfd_fill_link_order:
+ return default_fill_link_order (abfd, info, sec, link_order);
+ case bfd_data_link_order:
+ return bfd_set_section_contents (abfd, sec,
+ (PTR) link_order->u.data.contents,
+ (file_ptr) link_order->offset,
+ link_order->size);
+ }
+}
+
+/* Default routine to handle a bfd_fill_link_order. */
+
+/*ARGSUSED*/
+static boolean
+default_fill_link_order (abfd, info, sec, link_order)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *sec;
+ struct bfd_link_order *link_order;
+{
+ size_t size;
+ char *space;
+ size_t i;
+ int fill;
+ boolean result;
+
+ BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0);
+
+ size = (size_t) link_order->size;
+ space = (char *) bfd_malloc (size);
+ if (space == NULL && size != 0)
+ return false;
+
+ fill = link_order->u.fill.value;
+ for (i = 0; i < size; i += 2)
+ space[i] = fill >> 8;
+ for (i = 1; i < size; i += 2)
+ space[i] = fill;
+ result = bfd_set_section_contents (abfd, sec, space,
+ (file_ptr) link_order->offset,
+ link_order->size);
+ free (space);
+ return result;
+}
+
+/* Default routine to handle a bfd_indirect_link_order. */
+
+static boolean
+default_indirect_link_order (output_bfd, info, output_section, link_order,
+ generic_linker)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+ boolean generic_linker;
+{
+ asection *input_section;
+ bfd *input_bfd;
+ bfd_byte *contents = NULL;
+ bfd_byte *new_contents;
+
+ BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);
+
+ if (link_order->size == 0)
+ return true;
+
+ input_section = link_order->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ BFD_ASSERT (input_section->output_section == output_section);
+ BFD_ASSERT (input_section->output_offset == link_order->offset);
+ BFD_ASSERT (input_section->_cooked_size == link_order->size);
+
+ if (info->relocateable
+ && input_section->reloc_count > 0
+ && output_section->orelocation == (arelent **) NULL)
+ {
+ /* Space has not been allocated for the output relocations.
+ This can happen when we are called by a specific backend
+ because somebody is attempting to link together different
+ types of object files. Handling this case correctly is
+ difficult, and sometimes impossible. */
+ (*_bfd_error_handler)
+ (_("Attempt to do relocateable link with %s input and %s output"),
+ bfd_get_target (input_bfd), bfd_get_target (output_bfd));
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ if (! generic_linker)
+ {
+ asymbol **sympp;
+ asymbol **symppend;
+
+ /* Get the canonical symbols. The generic linker will always
+ have retrieved them by this point, but we are being called by
+ a specific linker, presumably because we are linking
+ different types of object files together. */
+ if (! generic_link_read_symbols (input_bfd))
+ return false;
+
+ /* Since we have been called by a specific linker, rather than
+ the generic linker, the values of the symbols will not be
+ right. They will be the values as seen in the input file,
+ not the values of the final link. We need to fix them up
+ before we can relocate the section. */
+ sympp = _bfd_generic_link_get_symbols (input_bfd);
+ symppend = sympp + _bfd_generic_link_get_symcount (input_bfd);
+ for (; sympp < symppend; sympp++)
+ {
+ asymbol *sym;
+ struct bfd_link_hash_entry *h;
+
+ sym = *sympp;
+
+ if ((sym->flags & (BSF_INDIRECT
+ | BSF_WARNING
+ | BSF_GLOBAL
+ | BSF_CONSTRUCTOR
+ | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym))
+ || bfd_is_ind_section (bfd_get_section (sym)))
+ {
+ /* sym->udata may have been set by
+ generic_link_add_symbol_list. */
+ if (sym->udata.p != NULL)
+ h = (struct bfd_link_hash_entry *) sym->udata.p;
+ else if (bfd_is_und_section (bfd_get_section (sym)))
+ h = bfd_wrapped_link_hash_lookup (output_bfd, info,
+ bfd_asymbol_name (sym),
+ false, false, true);
+ else
+ h = bfd_link_hash_lookup (info->hash,
+ bfd_asymbol_name (sym),
+ false, false, true);
+ if (h != NULL)
+ set_symbol_from_hash (sym, h);
+ }
+ }
+ }
+
+ /* Get and relocate the section contents. */
+ contents = ((bfd_byte *)
+ bfd_malloc (bfd_section_size (input_bfd, input_section)));
+ if (contents == NULL && bfd_section_size (input_bfd, input_section) != 0)
+ goto error_return;
+ new_contents = (bfd_get_relocated_section_contents
+ (output_bfd, info, link_order, contents, info->relocateable,
+ _bfd_generic_link_get_symbols (input_bfd)));
+ if (!new_contents)
+ goto error_return;
+
+ /* Output the section contents. */
+ if (! bfd_set_section_contents (output_bfd, output_section,
+ (PTR) new_contents,
+ link_order->offset, link_order->size))
+ goto error_return;
+
+ if (contents != NULL)
+ free (contents);
+ return true;
+
+ error_return:
+ if (contents != NULL)
+ free (contents);
+ return false;
+}
+
+/* A little routine to count the number of relocs in a link_order
+ list. */
+
+unsigned int
+_bfd_count_link_order_relocs (link_order)
+ struct bfd_link_order *link_order;
+{
+ register unsigned int c;
+ register struct bfd_link_order *l;
+
+ c = 0;
+ for (l = link_order; l != (struct bfd_link_order *) NULL; l = l->next)
+ {
+ if (l->type == bfd_section_reloc_link_order
+ || l->type == bfd_symbol_reloc_link_order)
+ ++c;
+ }
+
+ return c;
+}
+
+/*
+FUNCTION
+ bfd_link_split_section
+
+SYNOPSIS
+ boolean bfd_link_split_section(bfd *abfd, asection *sec);
+
+DESCRIPTION
+ Return nonzero if @var{sec} should be split during a
+ reloceatable or final link.
+
+.#define bfd_link_split_section(abfd, sec) \
+. BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
+.
+
+*/
+
+
+
+boolean
+_bfd_generic_link_split_section (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ return false;
+}
diff --git a/bfd/lynx-core.c b/bfd/lynx-core.c
new file mode 100644
index 00000000000..2358177dbc6
--- /dev/null
+++ b/bfd/lynx-core.c
@@ -0,0 +1,233 @@
+/* BFD back end for Lynx core files
+ Copyright 1993 Free Software Foundation, Inc.
+ Written by Stu Grossman of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifdef LYNX_CORE
+
+#include <sys/conf.h>
+#include <sys/kernel.h>
+/* sys/kernel.h should define this, but doesn't always, sigh. */
+#ifndef __LYNXOS
+#define __LYNXOS
+#endif
+#include <sys/mem.h>
+#include <sys/signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/itimer.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+
+/* These are stored in the bfd's tdata */
+
+struct lynx_core_struct
+{
+ int sig;
+ char cmd[PNMLEN + 1];
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.lynx_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+
+/* Handle Lynx core dump file. */
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+ bfd *abfd;
+ CONST char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ bfd_vma vma;
+ file_ptr filepos;
+{
+ asection *asect;
+ char *newname;
+
+ newname = bfd_alloc (abfd, strlen (name) + 1);
+ if (!newname)
+ return NULL;
+
+ strcpy (newname, name);
+
+ asect = bfd_make_section (abfd, newname);
+ if (!asect)
+ return NULL;
+
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 2;
+
+ return asect;
+}
+
+/* ARGSUSED */
+const bfd_target *
+lynx_core_file_p (abfd)
+ bfd *abfd;
+{
+ int val;
+ int secnum;
+ struct pssentry pss;
+ size_t tcontext_size;
+ core_st_t *threadp;
+ int pagesize;
+ asection *newsect;
+
+ pagesize = getpagesize (); /* Serious cross-target issue here... This
+ really needs to come from a system-specific
+ header file. */
+
+ /* Get the pss entry from the core file */
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return NULL;
+
+ val = bfd_read ((void *)&pss, 1, sizeof pss, abfd);
+ if (val != sizeof pss)
+ {
+ /* Too small to be a core file */
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ core_hdr (abfd) = (struct lynx_core_struct *)
+ bfd_zalloc (abfd, sizeof (struct lynx_core_struct));
+
+ if (!core_hdr (abfd))
+ return NULL;
+
+ strncpy (core_command (abfd), pss.pname, PNMLEN + 1);
+
+ /* Compute the size of the thread contexts */
+
+ tcontext_size = pss.threadcnt * sizeof (core_st_t);
+
+ /* Allocate space for the thread contexts */
+
+ threadp = (core_st_t *)bfd_alloc (abfd, tcontext_size);
+ if (!threadp)
+ return NULL;
+
+ /* Save thread contexts */
+
+ if (bfd_seek (abfd, pagesize, SEEK_SET) != 0)
+ return NULL;
+
+ val = bfd_read ((void *)threadp, pss.threadcnt, sizeof (core_st_t), abfd);
+
+ if (val != tcontext_size)
+ {
+ /* Probably too small to be a core file */
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ core_signal (abfd) = threadp->currsig;
+
+ newsect = make_bfd_asection (abfd, ".stack",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ pss.ssize,
+ pss.slimit,
+ pagesize + tcontext_size);
+ if (!newsect)
+ return NULL;
+
+ newsect = make_bfd_asection (abfd, ".data",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ pss.data_len + pss.bss_len,
+ pss.data_start,
+ pagesize + tcontext_size + pss.ssize
+#if defined (SPARC) || defined (__SPARC__)
+ /* SPARC Lynx seems to start dumping
+ the .data section at a page
+ boundary. It's OK to check a
+ #define like SPARC here because this
+ file can only be compiled on a Lynx
+ host. */
+ + pss.data_start % pagesize
+#endif
+ );
+ if (!newsect)
+ return NULL;
+
+/* And, now for the .reg/XXX pseudo sections. Each thread has it's own
+ .reg/XXX section, where XXX is the thread id (without leading zeros). The
+ currently running thread (at the time of the core dump) also has an alias
+ called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as
+ opposed to `.regXXX' because GDB expects that .reg2 will be the floating-
+ point registers. */
+
+ newsect = make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ sizeof (core_st_t),
+ 0,
+ pagesize);
+ if (!newsect)
+ return NULL;
+
+ for (secnum = 0; secnum < pss.threadcnt; secnum++)
+ {
+ char secname[100];
+
+ sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid));
+ newsect = make_bfd_asection (abfd, secname,
+ SEC_HAS_CONTENTS,
+ sizeof (core_st_t),
+ 0,
+ pagesize + secnum * sizeof (core_st_t));
+ if (!newsect)
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+char *
+lynx_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_command (abfd);
+}
+
+/* ARGSUSED */
+int
+lynx_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_signal (abfd);
+}
+
+/* ARGSUSED */
+boolean
+lynx_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this point */
+}
+
+#endif /* LYNX_CORE */
diff --git a/bfd/m68k4knetbsd.c b/bfd/m68k4knetbsd.c
new file mode 100644
index 00000000000..943438d2dda
--- /dev/null
+++ b/bfd/m68k4knetbsd.c
@@ -0,0 +1,32 @@
+/* BFD back-end for NetBSD/m68k a.out-ish binaries.
+ Copyright (C) 1990, 91, 92, 95, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#define TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 0x1000
+
+#define DEFAULT_ARCH bfd_arch_m68k
+#define DEFAULT_MID M_68K4K_NETBSD
+
+#define MY(OP) CAT(m68k4knetbsd_,OP)
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-m68k4k-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/m68klinux.c b/bfd/m68klinux.c
new file mode 100644
index 00000000000..c8f47a89fb0
--- /dev/null
+++ b/bfd/m68klinux.c
@@ -0,0 +1,772 @@
+/* BFD back-end for linux flavored m68k a.out binaries.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define ZMAGIC_DISK_BLOCK_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0x0
+#define N_SHARED_LIB(x) 0
+#define BYTES_IN_WORD 4
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_68020 || (mtype) == M_UNKNOWN)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#define TARGET_IS_BIG_ENDIAN_P
+#define DEFAULT_ARCH bfd_arch_m68k
+#define MY(OP) CAT(m68klinux_,OP)
+#define TARGETNAME "a.out-m68k-linux"
+
+extern const bfd_target MY(vec);
+
+/* We always generate QMAGIC files in preference to ZMAGIC files. It
+ would be possible to make this a linker option, if that ever
+ becomes important. */
+
+static void MY_final_link_callback
+ PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+static boolean m68klinux_bfd_final_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean m68klinux_write_object_contents PARAMS ((bfd *));
+
+static boolean
+m68klinux_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ obj_aout_subformat (abfd) = q_magic_format;
+ return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
+}
+
+#define MY_bfd_final_link m68klinux_bfd_final_link
+
+/* Set the machine type correctly. */
+
+static boolean
+m68klinux_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ N_SET_MACHTYPE (*execp, M_68020);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
+
+#define MY_write_object_contents m68klinux_write_object_contents
+
+/* Code to link against Linux a.out shared libraries. */
+
+/* See if a symbol name is a reference to the global offset table. */
+
+#ifndef GOT_REF_PREFIX
+#define GOT_REF_PREFIX "__GOT_"
+#endif
+
+#define IS_GOT_SYM(name) \
+ (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
+
+/* See if a symbol name is a reference to the procedure linkage table. */
+
+#ifndef PLT_REF_PREFIX
+#define PLT_REF_PREFIX "__PLT_"
+#endif
+
+#define IS_PLT_SYM(name) \
+ (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
+
+/* This string is used to generate specialized error messages. */
+
+#ifndef NEEDS_SHRLIB
+#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
+#endif
+
+/* This special symbol is a set vector that contains a list of
+ pointers to fixup tables. It will be present in any dynamicly
+ linked file. The linker generated fixup table should also be added
+ to the list, and it should always appear in the second slot (the
+ first one is a dummy with a magic number that is defined in
+ crt0.o). */
+
+#ifndef SHARABLE_CONFLICTS
+#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
+#endif
+
+/* We keep a list of fixups. The terminology is a bit strange, but
+ each fixup contains two 32 bit numbers. A regular fixup contains
+ an address and a pointer, and at runtime we should store the
+ address at the location pointed to by the pointer. A builtin fixup
+ contains two pointers, and we should read the address using one
+ pointer and store it at the location pointed to by the other
+ pointer. Builtin fixups come into play when we have duplicate
+ __GOT__ symbols for the same variable. The builtin fixup will copy
+ the GOT pointer from one over into the other. */
+
+struct fixup
+{
+ struct fixup *next;
+ struct linux_link_hash_entry *h;
+ bfd_vma value;
+
+ /* Nonzero if this is a jump instruction that needs to be fixed,
+ zero if this is just a pointer */
+ char jump;
+
+ char builtin;
+};
+
+/* We don't need a special hash table entry structure, but we do need
+ to keep some information between linker passes, so we use a special
+ hash table. */
+
+struct linux_link_hash_entry
+{
+ struct aout_link_hash_entry root;
+};
+
+struct linux_link_hash_table
+{
+ struct aout_link_hash_table root;
+
+ /* First dynamic object found in link. */
+ bfd *dynobj;
+
+ /* Number of fixups. */
+ size_t fixup_count;
+
+ /* Number of builtin fixups. */
+ size_t local_builtins;
+
+ /* List of fixups. */
+ struct fixup *fixup_list;
+};
+
+static struct bfd_hash_entry *linux_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *linux_link_hash_table_create
+ PARAMS ((bfd *));
+static struct fixup *new_fixup
+ PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
+ bfd_vma, int));
+static boolean linux_link_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean linux_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, boolean, boolean,
+ struct bfd_link_hash_entry **));
+static boolean linux_tally_symbols
+ PARAMS ((struct linux_link_hash_entry *, PTR));
+static boolean linux_finish_dynamic_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Routine to create an entry in an Linux link hash table. */
+
+static struct bfd_hash_entry *
+linux_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct linux_link_hash_entry *) NULL)
+ ret = ((struct linux_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct linux_link_hash_entry *)
+ NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ /* Set local fields; there aren't any. */
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a Linux link hash table. */
+
+static struct bfd_link_hash_table *
+linux_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct linux_link_hash_table *ret;
+
+ ret = ((struct linux_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));
+ if (ret == (struct linux_link_hash_table *) NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+ if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
+ linux_link_hash_newfunc))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->dynobj = NULL;
+ ret->fixup_count = 0;
+ ret->local_builtins = 0;
+ ret->fixup_list = NULL;
+
+ return &ret->root.root;
+}
+
+/* Look up an entry in a Linux link hash table. */
+
+#define linux_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct linux_link_hash_entry *) \
+ aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
+ (follow)))
+
+/* Traverse a Linux link hash table. */
+
+#define linux_link_hash_traverse(table, func, info) \
+ (aout_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the Linux link hash table from the info structure. This is
+ just a cast. */
+
+#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
+
+/* Store the information for a new fixup. */
+
+static struct fixup *
+new_fixup (info, h, value, builtin)
+ struct bfd_link_info *info;
+ struct linux_link_hash_entry *h;
+ bfd_vma value;
+ int builtin;
+{
+ struct fixup *f;
+
+ f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
+ sizeof (struct fixup));
+ if (f == NULL)
+ return f;
+ f->next = linux_hash_table (info)->fixup_list;
+ linux_hash_table (info)->fixup_list = f;
+ f->h = h;
+ f->value = value;
+ f->builtin = builtin;
+ f->jump = 0;
+ ++linux_hash_table (info)->fixup_count;
+ return f;
+}
+
+/* We come here once we realize that we are going to link to a shared
+ library. We need to create a special section that contains the
+ fixup table, and we ultimately need to add a pointer to this into
+ the set vector for SHARABLE_CONFLICTS. At this point we do not
+ know the size of the section, but that's OK - we just need to
+ create it for now. */
+
+static boolean
+linux_link_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+
+ /* Note that we set the SEC_IN_MEMORY flag. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ /* We choose to use the name ".linux-dynamic" for the fixup table.
+ Why not? */
+ s = bfd_make_section (abfd, ".linux-dynamic");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+ s->_raw_size = 0;
+ s->contents = 0;
+
+ return true;
+}
+
+/* Function to add a single symbol to the linker hash table. This is
+ a wrapper around _bfd_generic_link_add_one_symbol which handles the
+ tweaking needed for dynamic linking support. */
+
+static boolean
+linux_add_one_symbol (info, abfd, name, flags, section, value, string,
+ copy, collect, hashp)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ const char *string;
+ boolean copy;
+ boolean collect;
+ struct bfd_link_hash_entry **hashp;
+{
+ struct linux_link_hash_entry *h;
+ boolean insert;
+
+ /* Look up and see if we already have this symbol in the hash table.
+ If we do, and the defining entry is from a shared library, we
+ need to create the dynamic sections.
+
+ FIXME: What if abfd->xvec != info->hash->creator? We may want to
+ be able to link Linux a.out and ELF objects together, but serious
+ confusion is possible. */
+
+ insert = false;
+
+ if (! info->relocateable
+ && linux_hash_table (info)->dynobj == NULL
+ && strcmp (name, SHARABLE_CONFLICTS) == 0
+ && (flags & BSF_CONSTRUCTOR) != 0
+ && abfd->xvec == info->hash->creator)
+ {
+ if (! linux_link_create_dynamic_sections (abfd, info))
+ return false;
+ linux_hash_table (info)->dynobj = abfd;
+ insert = true;
+ }
+
+ if (bfd_is_abs_section (section)
+ && abfd->xvec == info->hash->creator)
+ {
+ h = linux_link_hash_lookup (linux_hash_table (info), name, false,
+ false, false);
+ if (h != NULL
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak))
+ {
+ struct fixup *f;
+
+ if (hashp != NULL)
+ *hashp = (struct bfd_link_hash_entry *) h;
+
+ f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
+ if (f == NULL)
+ return false;
+ f->jump = IS_PLT_SYM (name);
+
+ return true;
+ }
+ }
+
+ /* Do the usual procedure for adding a symbol. */
+ if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
+ value, string, copy, collect,
+ hashp))
+ return false;
+
+ /* Insert a pointer to our table in the set vector. The dynamic
+ linker requires this information */
+ if (insert)
+ {
+ asection *s;
+
+ /* Here we do our special thing to add the pointer to the
+ dynamic section in the SHARABLE_CONFLICTS set vector. */
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ BFD_ASSERT (s != NULL);
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
+ BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL)))
+ return false;
+ }
+
+ return true;
+}
+
+/* We will crawl the hash table and come here for every global symbol.
+ We will examine each entry and see if there are indications that we
+ need to add a fixup. There are two possible cases - one is where
+ you have duplicate definitions of PLT or GOT symbols - these will
+ have already been caught and added as "builtin" fixups. If we find
+ that the corresponding non PLT/GOT symbol is also present, we
+ convert it to a regular fixup instead.
+
+ This function is called via linux_link_hash_traverse. */
+
+static boolean
+linux_tally_symbols (h, data)
+ struct linux_link_hash_entry *h;
+ PTR data;
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
+ struct fixup *f, *f1;
+ int is_plt;
+ struct linux_link_hash_entry *h1, *h2;
+ boolean exists;
+
+ if (h->root.root.type == bfd_link_hash_undefined
+ && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
+ sizeof NEEDS_SHRLIB - 1) == 0)
+ {
+ const char *name;
+ char *p;
+ char *alloc = NULL;
+
+ name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
+ p = strrchr (name, '_');
+ if (p != NULL)
+ alloc = (char *) bfd_malloc (strlen (name) + 1);
+
+ if (p == NULL || alloc == NULL)
+ (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
+ name);
+ else
+ {
+ strcpy (alloc, name);
+ p = strrchr (alloc, '_');
+ *p++ = '\0';
+ (*_bfd_error_handler)
+ (_("Output file requires shared library `%s.so.%s'\n"),
+ alloc, p);
+ free (alloc);
+ }
+
+ abort ();
+ }
+
+ /* If this symbol is not a PLT/GOT, we do not even need to look at it */
+ is_plt = IS_PLT_SYM (h->root.root.root.string);
+
+ if (is_plt || IS_GOT_SYM (h->root.root.root.string))
+ {
+ /* Look up this symbol twice. Once just as a regular lookup,
+ and then again following all of the indirect links until we
+ reach a real symbol. */
+ h1 = linux_link_hash_lookup (linux_hash_table (info),
+ (h->root.root.root.string
+ + sizeof PLT_REF_PREFIX - 1),
+ false, false, true);
+ /* h2 does not follow indirect symbols. */
+ h2 = linux_link_hash_lookup (linux_hash_table (info),
+ (h->root.root.root.string
+ + sizeof PLT_REF_PREFIX - 1),
+ false, false, false);
+
+ /* The real symbol must exist but if it is also an ABS symbol,
+ there is no need to have a fixup. This is because they both
+ came from the same library. If on the other hand, we had to
+ use an indirect symbol to get to the real symbol, we add the
+ fixup anyway, since there are cases where these symbols come
+ from different shared libraries */
+ if (h1 != NULL
+ && (((h1->root.root.type == bfd_link_hash_defined
+ || h1->root.root.type == bfd_link_hash_defweak)
+ && ! bfd_is_abs_section (h1->root.root.u.def.section))
+ || h2->root.root.type == bfd_link_hash_indirect))
+ {
+ /* See if there is a "builtin" fixup already present
+ involving this symbol. If so, convert it to a regular
+ fixup. In the end, this relaxes some of the requirements
+ about the order of performing fixups. */
+ exists = false;
+ for (f1 = linux_hash_table (info)->fixup_list;
+ f1 != NULL;
+ f1 = f1->next)
+ {
+ if ((f1->h != h && f1->h != h1)
+ || (! f1->builtin && ! f1->jump))
+ continue;
+ if (f1->h == h1)
+ exists = true;
+ if (! exists
+ && bfd_is_abs_section (h->root.root.u.def.section))
+ {
+ f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
+ f->jump = is_plt;
+ }
+ f1->h = h1;
+ f1->jump = is_plt;
+ f1->builtin = 0;
+ exists = true;
+ }
+ if (! exists
+ && bfd_is_abs_section (h->root.root.u.def.section))
+ {
+ f = new_fixup (info, h1, h->root.root.u.def.value, 0);
+ if (f == NULL)
+ {
+ /* FIXME: No way to return error. */
+ abort ();
+ }
+ f->jump = is_plt;
+ }
+ }
+
+ /* Quick and dirty way of stripping these symbols from the
+ symtab. */
+ if (bfd_is_abs_section (h->root.root.u.def.section))
+ h->root.written = true;
+ }
+
+ return true;
+}
+
+/* This is called to set the size of the .linux-dynamic section is.
+ It is called by the Linux linker emulation before_allocation
+ routine. We have finished reading all of the input files, and now
+ we just scan the hash tables to find out how many additional fixups
+ are required. */
+
+boolean
+bfd_m68klinux_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ struct fixup *f;
+ asection *s;
+
+ if (output_bfd->xvec != &MY(vec))
+ return true;
+
+ /* First find the fixups... */
+ linux_link_hash_traverse (linux_hash_table (info),
+ linux_tally_symbols,
+ (PTR) info);
+
+ /* If there are builtin fixups, leave room for a marker. This is
+ used by the dynamic linker so that it knows that all that follow
+ are builtin fixups instead of regular fixups. */
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (f->builtin)
+ {
+ ++linux_hash_table (info)->fixup_count;
+ ++linux_hash_table (info)->local_builtins;
+ break;
+ }
+ }
+
+ if (linux_hash_table (info)->dynobj == NULL)
+ {
+ if (linux_hash_table (info)->fixup_count > 0)
+ abort ();
+ return true;
+ }
+
+ /* Allocate memory for our fixup table. We will fill it in later. */
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ if (s != NULL)
+ {
+ s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return false;
+ }
+ memset (s->contents, 0, (size_t) s->_raw_size);
+ }
+
+ return true;
+}
+
+/* We come here once we are ready to actually write the fixup table to
+ the output file. Scan the fixup tables and so forth and generate
+ the stuff we need. */
+
+static boolean
+linux_finish_dynamic_link (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ asection *s, *os, *is;
+ bfd_byte *fixup_table;
+ struct linux_link_hash_entry *h;
+ struct fixup *f;
+ unsigned int new_addr;
+ int section_offset;
+ unsigned int fixups_written;
+
+ if (linux_hash_table (info)->dynobj == NULL)
+ return true;
+
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ BFD_ASSERT (s != NULL);
+ os = s->output_section;
+ fixups_written = 0;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup table file offset: %x VMA: %x\n",
+ os->filepos + s->output_offset,
+ os->vma + s->output_offset);
+#endif
+
+ fixup_table = s->contents;
+ bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table);
+ fixup_table += 4;
+
+ /* Fill in fixup table. */
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (f->builtin)
+ continue;
+
+ if (f->h->root.root.type != bfd_link_hash_defined
+ && f->h->root.root.type != bfd_link_hash_defweak)
+ {
+ (*_bfd_error_handler)
+ (_("Symbol %s not defined for fixups\n"),
+ f->h->root.root.root.string);
+ continue;
+ }
+
+ is = f->h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = f->h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
+ new_addr, f->value);
+#endif
+
+ if (f->jump)
+ {
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value + 2, fixup_table);
+ fixup_table += 4;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value, fixup_table);
+ fixup_table += 4;
+ }
+ ++fixups_written;
+ }
+
+ if (linux_hash_table (info)->local_builtins != 0)
+ {
+ /* Special marker so we know to switch to the other type of fixup */
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (! f->builtin)
+ continue;
+
+ if (f->h->root.root.type != bfd_link_hash_defined
+ && f->h->root.root.type != bfd_link_hash_defweak)
+ {
+ (*_bfd_error_handler)
+ (_("Symbol %s not defined for fixups\n"),
+ f->h->root.root.root.string);
+ continue;
+ }
+
+ is = f->h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = f->h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
+ new_addr, f->value);
+#endif
+
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ }
+ }
+
+ if (linux_hash_table (info)->fixup_count != fixups_written)
+ {
+ (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
+ while (linux_hash_table (info)->fixup_count > fixups_written)
+ {
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ }
+ }
+
+ h = linux_link_hash_lookup (linux_hash_table (info),
+ "__BUILTIN_FIXUPS__",
+ false, false, false);
+
+ if (h != NULL
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak))
+ {
+ is = h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Builtin fixup table at %x\n", new_addr);
+#endif
+
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ }
+ else
+ bfd_put_32 (output_bfd, 0, fixup_table);
+
+ if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0)
+ return false;
+
+ if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd)
+ != s->_raw_size)
+ return false;
+
+ return true;
+}
+
+#define MY_bfd_link_hash_table_create linux_link_hash_table_create
+#define MY_add_one_symbol linux_add_one_symbol
+#define MY_finish_dynamic_link linux_finish_dynamic_link
+
+#define MY_zmagic_contiguous 1
+
+#include "aout-target.h"
diff --git a/bfd/m68klynx.c b/bfd/m68klynx.c
new file mode 100644
index 00000000000..7acdfbcad21
--- /dev/null
+++ b/bfd/m68klynx.c
@@ -0,0 +1,54 @@
+/* BFD back-end for m68k binaries under LynxOS.
+ Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#define N_SHARED_LIB(x) 0
+
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_m68k
+
+#define MY(OP) CAT(m68klynx_aout_,OP)
+#define TARGETNAME "a.out-m68k-lynx"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "libaout.h"
+#include "aout/aout64.h"
+
+#define TARGET_IS_BIG_ENDIAN_P
+
+#ifdef LYNX_CORE
+
+char *lynx_core_file_failing_command();
+int lynx_core_file_failing_signal();
+boolean lynx_core_file_matches_executable_p();
+const bfd_target *lynx_core_file_p();
+
+#define MY_core_file_failing_command lynx_core_file_failing_command
+#define MY_core_file_failing_signal lynx_core_file_failing_signal
+#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
+#define MY_core_file_p lynx_core_file_p
+
+#endif /* LYNX_CORE */
+
+#include "aout-target.h"
diff --git a/bfd/m68knetbsd.c b/bfd/m68knetbsd.c
new file mode 100644
index 00000000000..24d16656539
--- /dev/null
+++ b/bfd/m68knetbsd.c
@@ -0,0 +1,34 @@
+/* BFD back-end for NetBSD/m68k a.out-ish binaries.
+ Copyright (C) 1990, 91, 92, 94, 95, 97, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#define TARGET_IS_BIG_ENDIAN_P
+
+/* Our m68k ports use either 4K or 8K pages, but object files always
+ assume 8K page alignment so they will work on all m68k machines. */
+#define TARGET_PAGE_SIZE 0x2000
+
+#define DEFAULT_ARCH bfd_arch_m68k
+#define DEFAULT_MID M_68K_NETBSD
+
+#define MY(OP) CAT(m68knetbsd_,OP)
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-m68k-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/m88kmach3.c b/bfd/m88kmach3.c
new file mode 100644
index 00000000000..7a564087300
--- /dev/null
+++ b/bfd/m88kmach3.c
@@ -0,0 +1,38 @@
+/* BFD back-end for Motorola m88k a.out (Mach 3) binaries.
+ Copyright (C) 1990, 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_PAGE_SIZE (4096*2)
+#define SEGMENT_SIZE 0x20000
+#define TEXT_START_ADDR 0
+#define BYTES_IN_WORD 4
+#define N_HEADER_IN_TEXT(x) 1 /* (N_MAGIG(x) == ZMAGIC) */
+#define N_SHARED_LIB(x) 0
+
+#define N_TXTSIZE(x) ((x).a_text)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#define DEFAULT_ARCH bfd_arch_m88k
+#define MY(OP) CAT(m88kmach3_,OP)
+#define TARGETNAME "a.out-m88k-mach3"
+
+#include "aout-target.h"
diff --git a/bfd/makefile.dos b/bfd/makefile.dos
new file mode 100644
index 00000000000..8a22c6af201
--- /dev/null
+++ b/bfd/makefile.dos
@@ -0,0 +1,49 @@
+CFLAGS=-O2
+
+.c.o :
+ gcc $(CFLAGS) -I. -I../include -c $<
+
+all : libbfd.a
+
+targets.o : targets.c
+ gcc $(CFLAGS) -I. -I../include -DSELECT_VECS=&go32coff_vec,&i386aout_vec -DDEFAULT_VECTOR=go32coff_vec -c $*.c
+
+archures.o : archures.c
+ gcc $(CFLAGS) -I. -I../include -DSELECT_ARCHITECTURES=bfd_i386_arch -c $*.c
+
+OBJS = \
+ libbfd.o \
+ opncls.o \
+ bfd.o \
+ archive.o \
+ targets.o \
+ cache.o \
+ archures.o \
+ corefile.o \
+ section.o \
+ format.o \
+ syms.o \
+ reloc.o \
+ init.o \
+ coffgen.o \
+ srec.o \
+ hash.o \
+ linker.o \
+ ecoff.o \
+ ecofflink.o \
+ elf.o \
+ aout32.o \
+ stab-sym.o \
+ i386aout.o \
+ cpu-i386.o \
+ coff-go32.o \
+ cofflink.o \
+ elf32.o \
+ binary.o \
+ tekhex.o \
+ $E
+
+libbfd.a : $(OBJS)
+ -rm libbfd.a
+ ar rvs libbfd.a $(OBJS)
+ ranlib libbfd.a
diff --git a/bfd/makefile.vms b/bfd/makefile.vms
new file mode 100644
index 00000000000..ad6b1fff92a
--- /dev/null
+++ b/bfd/makefile.vms
@@ -0,0 +1,75 @@
+#
+# Makefile for bfd library under openVMS (Alpha and Vax)
+#
+# For use with gnu-make for vms
+#
+# Created by Klaus K"ampf, kkaempf@rmi.de
+#
+#
+
+CC=cc
+
+ifeq ($(ARCH),ALPHA)
+HOSTFILE=alphavms.h
+TARGETOBJS = cpu-alpha.obj
+else
+HOSTFILE=vaxvms.h
+TARGETOBJS = cpu-vax.obj
+endif
+
+
+OBJS=archive.obj,archures.obj,bfd.obj,cache.obj,coffgen.obj,corefile.obj,\
+ format.obj,init.obj,libbfd.obj,opncls.obj,reloc.obj,section.obj,syms.obj,\
+ targets.obj,hash.obj,linker.obj,elf.obj,srec.obj,binary.obj,tekhex.obj,\
+ ihex.obj,stab-syms.obj,vms.obj,vms-hdr.obj,vms-gsd.obj,vms-tir.obj,\
+ vms-misc.obj,$(TARGETOBJS)
+
+ifeq ($(CC),gcc)
+ifeq ($(ARCH),ALPHA)
+DEFS=/define=(SELECT_VECS="&vms_alpha_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch",\
+"HAVE_vms_alpha_vec=1")
+else
+DEFS=/define=(SELECT_VECS="&vms_vax_vec",SELECT_ARCHITECTURES="&bfd_vax_arch",\
+"HAVE_vms_vax_vec=1","VMS_DEBUG")
+endif
+CFLAGS=/include=([],[-.include])$(DEFS)
+else
+ifeq ($(ARCH),ALPHA)
+DEFS=/define=(SELECT_VECS="&vms_alpha_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch",\
+"HAVE_vms_alpha_vec=1","unlink=remove","const=","VMS_DEBUG",)
+else
+DEFS=/define=(SELECT_VECS="&vms_vax_vec",SELECT_ARCHITECTURES="&bfd_vax_arch",\
+"HAVE_vms_vax_vec=1","unlink=remove","const=","VMS_DEBUG")
+endif
+CFLAGS=/noopt/debug/include=([],[-.include])$(DEFS)/warnings=disable=(missingreturn,implicitfunc,longextern)
+endif
+
+
+libbfd.olb: sysdep.h bfd.h $(OBJS)
+ purge
+ lib/create libbfd $(OBJS)
+
+sysdep.h: [.hosts]$(HOSTFILE) config.h
+ $(CP) $< $@
+
+bfd.h: bfd-in2.h
+ $$ @configure
+
+targmatch.h: bfd.h
+config.h: bfd.h
+
+vms.c: vms.h
+vms-mhd.c: vms.h
+vms-gsd.c: vms.h
+vms-tir.c: vms.h
+vms-misc.c: vms.h
+targets.c: targmatch.h
+
+clean:
+ $$ purge
+ $(RM) libbfd.olb;
+ $(RM) sysdep.h;
+ $(RM) bfd.h;
+ $(RM) targmatch.h;
+ $(RM) config.h;
+ $(RM) *.obj;
diff --git a/bfd/mipsbsd.c b/bfd/mipsbsd.c
new file mode 100644
index 00000000000..e7ba68dde61
--- /dev/null
+++ b/bfd/mipsbsd.c
@@ -0,0 +1,468 @@
+/* BFD backend for MIPS BSD (a.out) binaries.
+ Copyright (C) 1993, 94, 95, 97, 1998 Free Software Foundation, Inc.
+ Written by Ralph Campbell.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+/* #define ENTRY_CAN_BE_ZERO */
+#define N_HEADER_IN_TEXT(x) 1
+#define N_SHARED_LIB(x) 0
+#define N_TXTADDR(x) \
+ (N_MAGIC(x) != ZMAGIC ? (x).a_entry : /* object file or NMAGIC */\
+ TEXT_START_ADDR + EXEC_BYTES_SIZE /* no padding */\
+ )
+#define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
+#define TEXT_START_ADDR 4096
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_mips
+#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
+ || (mtype) == M_MIPS1 || (mtype) == M_MIPS2)
+#define MY_symbol_leading_char '\0'
+
+#define MY(OP) CAT(mipsbsd_,OP)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#define SET_ARCH_MACH(ABFD, EXEC) \
+ MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
+ MY(choose_reloc_size)(ABFD);
+static void MY(set_arch_mach) PARAMS ((bfd *abfd, int machtype));
+static void MY(choose_reloc_size) PARAMS ((bfd *abfd));
+
+#define MY_write_object_contents MY(write_object_contents)
+static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
+
+/* We can't use MY(x) here because it leads to a recursive call to CAT
+ when expanded inside JUMP_TABLE. */
+#define MY_bfd_reloc_type_lookup mipsbsd_reloc_howto_type_lookup
+#define MY_canonicalize_reloc mipsbsd_canonicalize_reloc
+
+#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define MY_final_link_callback unused
+#define MY_bfd_final_link _bfd_generic_final_link
+
+#define MY_backend_data &MY(backend_data)
+#define MY_BFD_TARGET
+
+#include "aout-target.h"
+
+static void
+MY(set_arch_mach) (abfd, machtype)
+ bfd *abfd;
+ int machtype;
+{
+ enum bfd_architecture arch;
+ long machine;
+
+ /* Determine the architecture and machine type of the object file. */
+ switch (machtype) {
+
+ case M_MIPS1:
+ arch = bfd_arch_mips;
+ machine = 3000;
+ break;
+
+ case M_MIPS2:
+ arch = bfd_arch_mips;
+ machine = 4000;
+ break;
+
+ default:
+ arch = bfd_arch_obscure;
+ machine = 0;
+ break;
+ }
+ bfd_set_arch_mach(abfd, arch, machine);
+}
+
+/* Determine the size of a relocation entry, based on the architecture */
+static void
+MY(choose_reloc_size) (abfd)
+ bfd *abfd;
+{
+ switch (bfd_get_arch(abfd)) {
+ case bfd_arch_sparc:
+ case bfd_arch_a29k:
+ case bfd_arch_mips:
+ obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+ break;
+ default:
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+ break;
+ }
+}
+
+/* Write an object file in BSD a.out format.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static boolean
+MY(write_object_contents) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ /* Magic number, maestro, please! */
+ switch (bfd_get_arch(abfd)) {
+ case bfd_arch_m68k:
+ switch (bfd_get_mach(abfd)) {
+ case bfd_mach_m68010:
+ N_SET_MACHTYPE(*execp, M_68010);
+ break;
+ default:
+ case bfd_mach_m68020:
+ N_SET_MACHTYPE(*execp, M_68020);
+ break;
+ }
+ break;
+ case bfd_arch_sparc:
+ N_SET_MACHTYPE(*execp, M_SPARC);
+ break;
+ case bfd_arch_i386:
+ N_SET_MACHTYPE(*execp, M_386);
+ break;
+ case bfd_arch_a29k:
+ N_SET_MACHTYPE(*execp, M_29K);
+ break;
+ case bfd_arch_mips:
+ switch (bfd_get_mach(abfd)) {
+ case 4000:
+ case 6000:
+ N_SET_MACHTYPE(*execp, M_MIPS2);
+ break;
+ default:
+ N_SET_MACHTYPE(*execp, M_MIPS1);
+ break;
+ }
+ break;
+ default:
+ N_SET_MACHTYPE(*execp, M_UNKNOWN);
+ }
+
+ MY(choose_reloc_size)(abfd);
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
+
+/*
+ * MIPS relocation types.
+ */
+#define MIPS_RELOC_32 0
+#define MIPS_RELOC_JMP 1
+#define MIPS_RELOC_WDISP16 2
+#define MIPS_RELOC_HI16 3
+#define MIPS_RELOC_HI16_S 4
+#define MIPS_RELOC_LO16 5
+
+/*
+ * This is only called when performing a BFD_RELOC_MIPS_JMP relocation.
+ * The jump destination address is formed from the upper 4 bits of the
+ * "current" program counter concatenated with the jump instruction's
+ * 26 bit field and two trailing zeros.
+ * If the destination address is not in the same segment as the "current"
+ * program counter, then we need to signal an error.
+ */
+static bfd_reloc_status_type
+mips_fix_jmp_addr (abfd,reloc_entry,symbol,data,input_section,output_bfd)
+ bfd *abfd;
+ arelent *reloc_entry;
+ struct symbol_cache_entry *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+{
+ bfd_vma relocation, pc;
+
+ /* If this is a partial relocation, just continue. */
+ if (output_bfd != (bfd *)NULL)
+ return bfd_reloc_continue;
+
+ /* If this is an undefined symbol, return error */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0)
+ return bfd_reloc_undefined;
+
+ /*
+ * Work out which section the relocation is targetted at and the
+ * initial relocation command value.
+ */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ pc = input_section->output_section->vma + input_section->output_offset +
+ reloc_entry->address + 4;
+
+ if ((relocation & 0xF0000000) != (pc & 0xF0000000))
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_continue;
+}
+
+/*
+ * This is only called when performing a BFD_RELOC_HI16_S relocation.
+ * We need to see if bit 15 is set in the result. If it is, we add
+ * 0x10000 and continue normally. This will compensate for the sign extension
+ * when the low bits are added at run time.
+ */
+static bfd_reloc_status_type
+mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+
+static bfd_reloc_status_type
+mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+
+ /* If this is a partial relocation, just continue. */
+ if (output_bfd != (bfd *)NULL)
+ return bfd_reloc_continue;
+
+ /* If this is an undefined symbol, return error */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0)
+ return bfd_reloc_undefined;
+
+ /*
+ * Work out which section the relocation is targetted at and the
+ * initial relocation command value.
+ */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+
+ if (relocation & 0x8000)
+ reloc_entry->addend += 0x10000;
+
+ return bfd_reloc_continue;
+}
+
+static reloc_howto_type mips_howto_table_ext[] = {
+ {MIPS_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield, 0,
+ "32", false, 0, 0xffffffff, false},
+ {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_dont,
+ mips_fix_jmp_addr,
+ "MIPS_JMP", false, 0, 0x03ffffff, false},
+ {MIPS_RELOC_WDISP16, 2, 2, 16, true, 0, complain_overflow_signed, 0,
+ "WDISP16", false, 0, 0x0000ffff, false},
+ {MIPS_RELOC_HI16, 16, 2, 16, false, 0, complain_overflow_bitfield, 0,
+ "HI16", false, 0, 0x0000ffff, false},
+ {MIPS_RELOC_HI16_S, 16, 2, 16, false, 0, complain_overflow_bitfield,
+ mips_fix_hi16_s,
+ "HI16_S", false, 0, 0x0000ffff, false},
+ {MIPS_RELOC_LO16, 0, 2, 16, false, 0, complain_overflow_dont, 0,
+ "LO16", false, 0, 0x0000ffff, false},
+};
+
+static reloc_howto_type *
+MY(reloc_howto_type_lookup) (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+
+ if (bfd_get_arch (abfd) != bfd_arch_mips)
+ return 0;
+
+ switch (code)
+ {
+ case BFD_RELOC_CTOR:
+ case BFD_RELOC_32:
+ return (&mips_howto_table_ext[MIPS_RELOC_32]);
+ case BFD_RELOC_MIPS_JMP:
+ return (&mips_howto_table_ext[MIPS_RELOC_JMP]);
+ case BFD_RELOC_16_PCREL_S2:
+ return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]);
+ case BFD_RELOC_HI16:
+ return (&mips_howto_table_ext[MIPS_RELOC_HI16]);
+ case BFD_RELOC_HI16_S:
+ return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]);
+ case BFD_RELOC_LO16:
+ return (&mips_howto_table_ext[MIPS_RELOC_LO16]);
+ default:
+ return 0;
+ }
+}
+
+/*
+ * This is just like the standard aoutx.h version but we need to do our
+ * own mapping of external reloc type values to howto entries.
+ */
+long
+MY(canonicalize_reloc)(abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr = section->relocation;
+ unsigned int count, c;
+ extern reloc_howto_type NAME(aout,ext_howto_table)[];
+
+ /* If we have already read in the relocation table, return the values. */
+ if (section->flags & SEC_CONSTRUCTOR) {
+ arelent_chain *chain = section->constructor_chain;
+
+ for (count = 0; count < section->reloc_count; count++) {
+ *relptr++ = &chain->relent;
+ chain = chain->next;
+ }
+ *relptr = 0;
+ return section->reloc_count;
+ }
+ if (tblptr && section->reloc_count) {
+ for (count = 0; count++ < section->reloc_count;)
+ *relptr++ = tblptr++;
+ *relptr = 0;
+ return section->reloc_count;
+ }
+
+ if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols))
+ return -1;
+ tblptr = section->relocation;
+
+ /* fix up howto entries */
+ for (count = 0; count++ < section->reloc_count;)
+ {
+ c = tblptr->howto - NAME(aout,ext_howto_table);
+ tblptr->howto = &mips_howto_table_ext[c];
+
+ *relptr++ = tblptr++;
+ }
+ *relptr = 0;
+ return section->reloc_count;
+}
+
+static CONST struct aout_backend_data MY(backend_data) = {
+ 0, /* zmagic contiguous */
+ 1, /* text incl header */
+ 0, /* entry is text address */
+ 0, /* exec_hdr_flags */
+ TARGET_PAGE_SIZE, /* text vma */
+ MY_set_sizes,
+ 0, /* text size includes exec header */
+ 0, /* add_dynamic_symbols */
+ 0, /* add_one_symbol */
+ 0, /* link_dynamic_object */
+ 0, /* write_dynamic_symbol */
+ 0, /* check_dynamic_reloc */
+ 0 /* finish_dynamic_link */
+};
+
+const bfd_target aout_mips_little_vec =
+{
+ "a.out-mips-little", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_LITTLE, /* target byte order (little) */
+ BFD_ENDIAN_LITTLE, /* target headers byte order (little) */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ MY_symbol_leading_char,
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+ {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, MY_core_file_p},
+ {bfd_false, MY_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, MY_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (MY),
+ BFD_JUMP_TABLE_COPY (MY),
+ BFD_JUMP_TABLE_CORE (MY),
+ BFD_JUMP_TABLE_ARCHIVE (MY),
+ BFD_JUMP_TABLE_SYMBOLS (MY),
+ BFD_JUMP_TABLE_RELOCS (MY),
+ BFD_JUMP_TABLE_WRITE (MY),
+ BFD_JUMP_TABLE_LINK (MY),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) MY_backend_data,
+};
+
+const bfd_target aout_mips_big_vec =
+{
+ "a.out-mips-big", /* name */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_BIG, /* target byte order (big) */
+ BFD_ENDIAN_BIG, /* target headers byte order (big) */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
+ MY_symbol_leading_char,
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, MY_core_file_p},
+ {bfd_false, MY_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, MY_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (MY),
+ BFD_JUMP_TABLE_COPY (MY),
+ BFD_JUMP_TABLE_CORE (MY),
+ BFD_JUMP_TABLE_ARCHIVE (MY),
+ BFD_JUMP_TABLE_SYMBOLS (MY),
+ BFD_JUMP_TABLE_RELOCS (MY),
+ BFD_JUMP_TABLE_WRITE (MY),
+ BFD_JUMP_TABLE_LINK (MY),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) MY_backend_data,
+};
diff --git a/bfd/mpw-config.in b/bfd/mpw-config.in
new file mode 100644
index 00000000000..31addeebdcf
--- /dev/null
+++ b/bfd/mpw-config.in
@@ -0,0 +1,86 @@
+# Configuration fragment for BFD.
+
+# This is almost always correct.
+
+Set selarchs "&bfd_{target_cpu}_arch"
+Set defvec ""
+Set selvecs ""
+Set havevecs ""
+
+If "{target_canonical}" =~ /m68k-apple-macos/
+ Set BFD_BACKENDS '"{o}"coff-m68k.c.o "{o}"cofflink.c.o'
+ Set defvec m68kcoff_vec
+ Set selvecs '&m68kcoff_vec'
+ Set havevecs '-d HAVE_m68kcoff_vec'
+
+Else If "{target_canonical}" =~ /powerpc-apple-macos/
+ Set BFD_BACKENDS '"{o}"coff-pmac.c.o "{o}"xcofflink.c.o'
+ Set defvec pmac_xcoff_vec
+ Set selvecs '&pmac_xcoff_vec'
+ Set havevecs '-d HAVE_pmac_xcoff_vec'
+ Set selarchs "&bfd_powerpc_arch"
+
+Else If "{target_canonical}" =~ /i386-\Option-x-go32/
+ Set BFD_BACKENDS '"{o}"coff-i386.c.o'
+ Set defvec i386coff_vec
+ Set selvecs '&i386coff_vec'
+ Set havevecs '-d HAVE_i386coff_vec'
+
+Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/
+ Set BFD_BACKENDS '"{o}"coff-mips.c.o "{o}"ecoff.c.o "{o}"ecofflink.c.o "{o}"elf32.c.o "{o}"elf32-mips.c.o "{o}"elflink.c.o'
+ Set defvec ecoff_big_vec
+ Set selvecs '&ecoff_big_vec,&ecoff_little_vec,&bfd_elf32_bigmips_vec'
+ Set havevecs '-d HAVE_ecoff_big_vec -d HAVE_ecoff_little_vec -d HAVE_bfd_elf32_bigmips_vec'
+
+Else If "{target_canonical}" =~ /sh-\Option-x-hms/
+ Set BFD_BACKENDS '"{o}"coff-sh.c.o "{o}"cofflink.c.o'
+ Set defvec shcoff_vec
+ Set selvecs '&shcoff_vec,&shlcoff_vec'
+ Set havevecs '-d HAVE_shcoff_vec -d HAVE_shlcoff_vec'
+End If
+
+Set ta `echo {selarchs} | sed -e 's/&bfd_/{o}cpu-/g' -e 's/_arch/.c.o/g'`
+
+Set tdefaults "-d DEFAULT_VECTOR={defvec} -d SELECT_VECS={selvecs} -d SELECT_ARCHITECTURES={selarchs} {havevecs}"
+
+Echo '# From mpw-config.in' > "{o}"mk.tmp
+Echo 'WORDSIZE = 32' >> "{o}"mk.tmp
+Echo 'BFD_MACHINES = ' {ta} >> "{o}"mk.tmp
+Echo 'BFD_BACKENDS = ' {BFD_BACKENDS} >> "{o}"mk.tmp
+Echo 'TDEFAULTS = ' {tdefaults} >> "{o}"mk.tmp
+Echo 'HDEPFILES = ' >> "{o}"mk.tmp
+Echo 'TDEPFILES = ' >> "{o}"mk.tmp
+Echo '# End from mpw-config.in' >> "{o}"mk.tmp
+
+Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new
+Echo '#include "mpw.h"' >> "{o}"config.new
+
+MoveIfChange "{o}"config.new "{o}"config.h
+
+# We can only handle 32-bit targets right now.
+
+sed -e 's/@WORDSIZE@/32/' \Option-d
+ -e 's/@wordsize@/32/' \Option-d
+ -e "s/@VERSION@/`Catenate {srcdir}VERSION`/" \Option-d
+ -e 's/@BFD_HOST_64_BIT_DEFINED@/0/' \Option-d
+ -e 's/@BFD_HOST_64_BIT@//' \Option-d
+ -e 's/@BFD_HOST_U_64_BIT@//' \Option-d
+ -e 's/@BFD_HOST_64BIT_LONG@/0/' \Option-d
+ "{srcdir}"bfd-in2.h >"{o}"bfd.h-new
+
+MoveIfChange "{o}"bfd.h-new "{o}"bfd.h
+
+sed -e 's/NN/32/g' "{srcdir}"elfxx-target.h >"{o}"elf32-target.h-new
+MoveIfChange "{o}"elf32-target.h-new "{o}"elf32-target.h
+
+# Pre-expand some macros in coffswap.h, so MPW C doesn't choke.
+
+sed -e 's/^ PUT_AOUTHDR_TSIZE (/ bfd_h_put_32 (/' \Option-d
+ -e 's/^ PUT_AOUTHDR_DSIZE (/ bfd_h_put_32 (/' \Option-d
+ -e 's/^ PUT_AOUTHDR_BSIZE (/ bfd_h_put_32 (/' \Option-d
+ -e 's/^ PUT_AOUTHDR_ENTRY (/ bfd_h_put_32 (/' \Option-d
+ -e 's/^ PUT_AOUTHDR_TEXT_START (/ bfd_h_put_32 (/' \Option-d
+ -e 's/^ PUT_AOUTHDR_DATA_START (/ bfd_h_put_32 (/' \Option-d
+ "{srcdir}"coffswap.h >"{o}"coffswap.h-new
+
+MoveIfChange "{o}"coffswap.h-new "{o}"coffswap.h
diff --git a/bfd/mpw-make.sed b/bfd/mpw-make.sed
new file mode 100644
index 00000000000..b2463c72b7f
--- /dev/null
+++ b/bfd/mpw-make.sed
@@ -0,0 +1,81 @@
+# Sed commands to finish translating the Unix BFD Makefile into MPW syntax.
+
+# Whack out unused host and target define bits.
+/HDEFINES/s/@HDEFINES@//
+/TDEFINES/s/@TDEFINES@//
+
+# Fix pathnames to include directories.
+/^INCDIR = /s/^INCDIR = .*$/INCDIR = "{topsrcdir}"include/
+/^CSEARCH = /s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/
+
+# Comment out setting of vars, configure script will add these itself.
+/^WORDSIZE =/s/^/#/
+# /^ALL_BACKENDS/s/^/#/
+/^BFD_BACKENDS/s/^/#/
+/^BFD_MACHINES/s/^/#/
+/^TDEFAULTS/s/^/#/
+
+# Remove extra, useless, "all".
+/^all \\Option-f _oldest/,/^$/d
+
+# Remove the Makefile rebuild rule.
+/^Makefile /,/--recheck/d
+
+# Don't do any recursive subdir stuff.
+/ subdir_do/s/{MAKE}/null-command/
+
+/BFD_H/s/^{BFD_H}/#{BFD_H}/
+
+# Add explicit srcdir paths to special files.
+/config.bfd/s/ config.bfd/ "{s}"config.bfd/g
+/targmatch.sed/s/ targmatch.sed/ "{s}"targmatch.sed/g
+
+# Point at include files that are always in the objdir.
+/bfd/s/"{s}"bfd\.h/"{o}"bfd.h/g
+/config/s/"{s}"config\.h/"{o}"config.h/g
+/targmatch/s/"{s}"targmatch\.h/"{o}"targmatch.h/g
+/targmatch/s/^targmatch\.h/"{o}"targmatch.h/
+/elf32-target/s/"{s}"elf32-target\.h/"{o}"elf32-target.h/g
+/elf32-target/s/^elf32-target\.h/"{o}"elf32-target.h/
+/elf64-target/s/"{s}"elf64-target\.h/"{o}"elf64-target.h/g
+/elf64-target/s/^elf64-target\.h/"{o}"elf64-target.h/
+
+/"{s}"{INCDIR}/s/"{s}"{INCDIR}/"{INCDIR}"/g
+
+/dep/s/\.dep/__dep/g
+
+# Removing duplicates is cool but presently unnecessary,
+# so whack this out.
+/^ofiles \\Option-f/,/^$/d
+/ofiles/s/{OFILES} ofiles/{OFILES}/
+/echo ofiles = /d
+/cat ofiles/s/`cat ofiles`/{OFILES}/
+
+# No corefile support.
+/COREFILE/s/@COREFILE@//
+/COREFLAG/s/@COREFLAG@//
+
+# No PIC foolery in this environment.
+/@ALLLIBS@/s/@ALLLIBS@/{TARGETLIB}/
+/@PICLIST@/s/@PICLIST@//
+/@PICFLAG@/s/@PICFLAG@//
+/^{OFILES} \\Option-f stamp-picdir/,/^$/d
+
+# Remove the pic trickery from the default build rule.
+/^\.c\.o \\Option-f /,/End If/c\
+.c.o \\Option-f .c
+
+# MPW Make doesn't know about $<.
+/"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile/,/^$/c\
+"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile\
+ {CC} @DASH_C_FLAG@ {ALL_CFLAGS} {TDEFAULTS} "{s}"targets.c -o "{o}"targets.c.o
+
+/"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile/,/^$/c\
+"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile\
+ {CC} @DASH_C_FLAG@ {ALL_CFLAGS} {TDEFAULTS} "{s}"archures.c -o "{o}"archures.c.o
+
+# Remove the .h rebuilding rules, we don't currently have a doc subdir,
+# or a way to build the prototype-hacking tool that's in it.
+/^"{srcdir}"bfd-in2.h \\Option-f /,/^$/d
+/^"{srcdir}"libbfd.h \\Option-f /,/^$/d
+/^"{srcdir}"libcoff.h \\Option-f /,/^$/d
diff --git a/bfd/netbsd-core.c b/bfd/netbsd-core.c
new file mode 100644
index 00000000000..21b184dce3b
--- /dev/null
+++ b/bfd/netbsd-core.c
@@ -0,0 +1,251 @@
+/* BFD back end for NetBSD style core files
+ Copyright 1988, 89, 91, 92, 93, 96, 1998 Free Software Foundation, Inc.
+ Written by Paul Kranenburg, EUR
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/core.h>
+
+/*
+ * FIXME: On NetBSD/sparc CORE_FPU_OFFSET should be (sizeof(struct trapframe))
+ */
+
+struct netbsd_core_struct {
+ struct core core;
+} *rawptr;
+
+/* forward declarations */
+
+static const bfd_target * netbsd_core_file_p PARAMS ((bfd *abfd));
+static char * netbsd_core_file_failing_command PARAMS ((bfd *abfd));
+static int netbsd_core_file_failing_signal PARAMS ((bfd *abfd));
+static boolean netbsd_core_file_matches_executable_p
+ PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+static void swap_abort PARAMS ((void));
+
+/* Handle NetBSD-style core dump file. */
+
+/* ARGSUSED */
+static const bfd_target *
+netbsd_core_file_p (abfd)
+ bfd *abfd;
+
+{
+ int i, val, offset;
+ asection *asect, *asect2;
+ struct core core;
+ struct coreseg coreseg;
+
+ val = bfd_read ((void *)&core, 1, sizeof core, abfd);
+ if (val != sizeof core) {
+ /* Too small to be a core file */
+ bfd_set_error(bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (CORE_GETMAGIC(core) != COREMAGIC) {
+ bfd_set_error(bfd_error_wrong_format);
+ return 0;
+ }
+
+ rawptr = (struct netbsd_core_struct *)
+ bfd_zalloc (abfd, sizeof (struct netbsd_core_struct));
+ if (rawptr == NULL) {
+ bfd_set_error(bfd_error_no_memory);
+ return 0;
+ }
+
+ rawptr->core = core;
+ abfd->tdata.netbsd_core_data = rawptr;
+
+ offset = core.c_hdrsize;
+ for (i = 0; i < core.c_nseg; i++) {
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+ goto punt;
+
+ val = bfd_read ((void *)&coreseg, 1, sizeof coreseg, abfd);
+ if (val != sizeof coreseg) {
+ bfd_set_error(bfd_error_file_truncated);
+ goto punt;
+ }
+ if (CORE_GETMAGIC(coreseg) != CORESEGMAGIC) {
+ bfd_set_error(bfd_error_wrong_format);
+ goto punt;
+ }
+
+ offset += core.c_seghdrsize;
+
+ asect = (asection *) bfd_zalloc (abfd, sizeof(asection));
+ if (asect == NULL) {
+ bfd_set_error(bfd_error_no_memory);
+ goto punt;
+ }
+
+ asect->_raw_size = coreseg.c_size;
+ asect->vma = coreseg.c_addr;
+ asect->filepos = offset;
+ asect->alignment_power = 2;
+ asect->next = abfd->sections;
+ abfd->sections = asect;
+ abfd->section_count++;
+ offset += coreseg.c_size;
+
+ switch (CORE_GETFLAG(coreseg)) {
+ case CORE_CPU:
+ asect->name = ".reg";
+ asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+#ifdef CORE_FPU_OFFSET
+ /* Hackish... */
+ asect->_raw_size = CORE_FPU_OFFSET;
+ asect2 = (asection *)bfd_zalloc (abfd,
+ sizeof (asection));
+ if (asect2 == NULL) {
+ bfd_set_error(bfd_error_no_memory);
+ goto punt;
+ }
+ asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET;
+ asect2->vma = 0;
+ asect2->filepos = asect->filepos + CORE_FPU_OFFSET;
+ asect2->alignment_power = 2;
+ asect2->next = abfd->sections;
+ asect2->name = ".reg2";
+ asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ abfd->sections = asect2;
+ abfd->section_count++;
+#endif
+
+ break;
+ case CORE_DATA:
+ asect->name = ".data";
+ asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
+ break;
+ case CORE_STACK:
+ asect->name = ".stack";
+ asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
+ break;
+ }
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+ return abfd->xvec;
+
+punt: {
+ asection *anext;
+ for (asect = abfd->sections; asect; asect = anext) {
+ anext = asect->next;
+ free((void *)asect);
+ }
+ }
+ free ((void *)rawptr);
+ abfd->tdata.netbsd_core_data = NULL;
+ abfd->sections = NULL;
+ abfd->section_count = 0;
+ return 0;
+}
+
+static char*
+netbsd_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ /*return core_command (abfd);*/
+ return abfd->tdata.netbsd_core_data->core.c_name;
+}
+
+/* ARGSUSED */
+static int
+netbsd_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ /*return core_signal (abfd);*/
+ return abfd->tdata.netbsd_core_data->core.c_signo;
+}
+
+/* ARGSUSED */
+static boolean
+netbsd_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this point */
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target netbsd_core_vec =
+ {
+ "netbsd-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ netbsd_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (netbsd),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
diff --git a/bfd/netbsd.h b/bfd/netbsd.h
new file mode 100644
index 00000000000..a5482f04312
--- /dev/null
+++ b/bfd/netbsd.h
@@ -0,0 +1,122 @@
+/* BFD back-end definitions used by all NetBSD targets.
+ Copyright (C) 1990, 91, 92, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA. */
+
+/* Check for our machine type (part of magic number). */
+#ifndef MACHTYPE_OK
+#define MACHTYPE_OK(m) ((m) == DEFAULT_MID || (m) == M_UNKNOWN)
+#endif
+
+/* This is the normal load address for executables. */
+#define TEXT_START_ADDR TARGET_PAGE_SIZE
+
+/* NetBSD ZMAGIC has its header in the text segment. */
+#define N_HEADER_IN_TEXT(x) 1
+
+/* Determine if this is a shared library using the flags. */
+#define N_SHARED_LIB(x) (N_DYNAMIC(x))
+
+/* We have 6 bits of flags and 10 bits of machine ID. */
+#define N_MACHTYPE(exec) \
+ ((enum machine_type)(((exec).a_info >> 16) & 0x03ff))
+#define N_FLAGS(exec) \
+ (((exec).a_info >> 26) & 0x3f)
+
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0x3ff) << 16) \
+ | (((flags) & 0x3f) << 24))
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info & 0xfb00ffff) | ((((int)(machtype))&0x3ff) << 16))
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info & 0x03ffffff) | ((flags & 0x03f) << 26))
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+/* On NetBSD, the magic number is always in ntohl's "network" (big-endian)
+ format. */
+#define SWAP_MAGIC(ext) bfd_getb32 (ext)
+
+/* On NetBSD, the entry point may be taken to be the start of the text
+ section. */
+#define MY_entry_is_text_address 1
+
+#define MY_write_object_contents MY(write_object_contents)
+static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
+#define MY_text_includes_header 1
+
+#include "aout-target.h"
+
+/* Write an object file.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static boolean
+MY(write_object_contents) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ /* We must make certain that the magic number has been set. This
+ will normally have been done by set_section_contents, but only if
+ there actually are some section contents. */
+ if (! abfd->output_has_begun)
+ {
+ bfd_size_type text_size;
+ file_ptr text_end;
+
+ NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
+ }
+
+#if CHOOSE_RELOC_SIZE
+ CHOOSE_RELOC_SIZE(abfd);
+#else
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+#endif
+
+ /* Magic number, maestro, please! */
+ switch (bfd_get_arch(abfd)) {
+ case DEFAULT_ARCH:
+ N_SET_MACHTYPE(*execp, DEFAULT_MID);
+ break;
+ default:
+ N_SET_MACHTYPE(*execp, M_UNKNOWN);
+ break;
+ }
+
+ /* The NetBSD magic number is always big-endian */
+#ifndef TARGET_IS_BIG_ENDIAN_P
+ /* XXX aren't there any macro to change byteorder of a word independent of
+ the host's or target's endianesses? */
+ execp->a_info
+ = (execp->a_info & 0xff) << 24 | (execp->a_info & 0xff00) << 8
+ | (execp->a_info & 0xff0000) >> 8 | (execp->a_info & 0xff000000) >> 24;
+#endif
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
diff --git a/bfd/newsos3.c b/bfd/newsos3.c
new file mode 100644
index 00000000000..7ec7a75a87c
--- /dev/null
+++ b/bfd/newsos3.c
@@ -0,0 +1,40 @@
+/* BFD back-end for NewsOS3 (Sony, 68k) binaries.
+ Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0
+#define BYTES_IN_WORD 4
+#define MY(OP) CAT(newsos3_,OP)
+#define TARGETNAME "a.out-newsos3"
+#define ENTRY_CAN_BE_ZERO
+#define N_SHARED_LIB(x) 0 /* Avoids warning when compiled with -Wall. */
+#define DEFAULT_ARCH bfd_arch_m68k
+#define TARGET_IS_BIG_ENDIAN_P
+#define N_HEADER_IN_TEXT(x) 0
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#include "aout-target.h"
diff --git a/bfd/nlm-target.h b/bfd/nlm-target.h
new file mode 100644
index 00000000000..6f1d47d8c45
--- /dev/null
+++ b/bfd/nlm-target.h
@@ -0,0 +1,229 @@
+/* Target definitions for 32/64-bit NLM (NetWare Loadable Module)
+ Copyright (C) 1993, 94, 95, 1997 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define nlm_core_file_p _bfd_dummy_target
+
+#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
+#define nlm_get_symtab nlmNAME(get_symtab)
+#define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
+#define nlm_print_symbol nlmNAME(print_symbol)
+#define nlm_get_symbol_info nlmNAME(get_symbol_info)
+#define nlm_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define nlm_get_lineno _bfd_nosymbols_get_lineno
+#define nlm_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define nlm_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define nlm_read_minisymbols _bfd_generic_read_minisymbols
+#define nlm_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
+#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
+#define nlm_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+
+#define nlm_set_section_contents nlmNAME(set_section_contents)
+
+#define nlm_sizeof_headers _bfd_nolink_sizeof_headers
+#define nlm_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define nlm_bfd_relax_section bfd_generic_relax_section
+#define nlm_bfd_gc_sections bfd_generic_gc_sections
+#define nlm_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define nlm_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define nlm_bfd_final_link _bfd_generic_final_link
+#define nlm_bfd_link_split_section _bfd_generic_link_split_section
+
+/* This structure contains everything that BFD knows about a target.
+ It includes things like its byte order, name, what routines to call
+ to do various operations, etc. Every BFD points to a target structure
+ with its "xvec" member.
+
+ There are two such structures here: one for big-endian machines and
+ one for little-endian machines. */
+
+
+#ifdef TARGET_BIG_SYM
+const bfd_target TARGET_BIG_SYM =
+{
+ /* name: identify kind of target */
+ TARGET_BIG_NAME,
+
+ /* flavour: general indication about file */
+ bfd_target_nlm_flavour,
+
+ /* byteorder: data is big endian */
+ BFD_ENDIAN_BIG,
+
+ /* header_byteorder: header is also big endian */
+ BFD_ENDIAN_BIG,
+
+ /* object_flags: mask of all file flags */
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+ | WP_TEXT),
+
+ /* section_flags: mask of all section flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
+ SEC_CODE | SEC_DATA),
+
+ /* leading_symbol_char: is the first char of a user symbol
+ predictable, and if so what is it */
+ 0,
+
+ /* ar_pad_char: pad character for filenames within an archive header
+ FIXME: this really has nothing to do with NLM, this is a characteristic
+ of the archiver and/or os and should be independently tunable */
+ '/',
+
+ /* ar_max_namelen: maximum number of characters in an archive header
+ FIXME: this really has nothing to do with NLM, this is a characteristic
+ of the archiver and should be independently tunable. This value is
+ a WAG (wild a** guess) */
+ 15,
+
+ /* Routines to byte-swap various sized integers from the data sections */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+ /* Routines to byte-swap various sized integers from the file headers */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16,
+
+ /* bfd_check_format: check the format of a file being read */
+ { _bfd_dummy_target, /* unknown format */
+ nlmNAME(object_p), /* assembler/linker output (object file) */
+ bfd_generic_archive_p, /* an archive */
+ nlm_core_file_p /* a core file */
+ },
+
+ /* bfd_set_format: set the format of a file being written */
+ { bfd_false,
+ nlm_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+
+ /* bfd_write_contents: write cached information into a file being written */
+ { bfd_false,
+ nlmNAME(write_object_contents),
+ _bfd_write_archive_contents,
+ bfd_false
+ },
+
+ /* Initialize a jump table with the standard macro. All names start with
+ "nlm" */
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (nlm),
+ BFD_JUMP_TABLE_RELOCS (nlm),
+ BFD_JUMP_TABLE_WRITE (nlm),
+ BFD_JUMP_TABLE_LINK (nlm),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ /* backend_data: */
+ (PTR) TARGET_BACKEND_DATA
+};
+#endif
+
+#ifdef TARGET_LITTLE_SYM
+const bfd_target TARGET_LITTLE_SYM =
+{
+ /* name: identify kind of target */
+ TARGET_LITTLE_NAME,
+
+ /* flavour: general indication about file */
+ bfd_target_nlm_flavour,
+
+ /* byteorder: data is little endian */
+ BFD_ENDIAN_LITTLE,
+
+ /* header_byteorder: header is also little endian */
+ BFD_ENDIAN_LITTLE,
+
+ /* object_flags: mask of all file flags */
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+ | WP_TEXT),
+
+ /* section_flags: mask of all section flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
+ SEC_DATA),
+
+ /* leading_symbol_char: is the first char of a user symbol
+ predictable, and if so what is it */
+ 0,
+
+ /* ar_pad_char: pad character for filenames within an archive header
+ FIXME: this really has nothing to do with NLM, this is a characteristic
+ of the archiver and/or os and should be independently tunable */
+ '/',
+
+ /* ar_max_namelen: maximum number of characters in an archive header
+ FIXME: this really has nothing to do with NLM, this is a characteristic
+ of the archiver and should be independently tunable. This value is
+ a WAG (wild a** guess) */
+ 15,
+
+ /* Routines to byte-swap various sized integers from the data sections */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+
+ /* Routines to byte-swap various sized integers from the file headers */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+
+ /* bfd_check_format: check the format of a file being read */
+ { _bfd_dummy_target, /* unknown format */
+ nlmNAME(object_p), /* assembler/linker output (object file) */
+ bfd_generic_archive_p, /* an archive */
+ nlm_core_file_p /* a core file */
+ },
+
+ /* bfd_set_format: set the format of a file being written */
+ { bfd_false,
+ nlm_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+
+ /* bfd_write_contents: write cached information into a file being written */
+ { bfd_false,
+ nlmNAME(write_object_contents),
+ _bfd_write_archive_contents,
+ bfd_false
+ },
+
+ /* Initialize a jump table with the standard macro. All names start with
+ "nlm" */
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (nlm),
+ BFD_JUMP_TABLE_RELOCS (nlm),
+ BFD_JUMP_TABLE_WRITE (nlm),
+ BFD_JUMP_TABLE_LINK (nlm),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ /* backend_data: */
+ (PTR) TARGET_BACKEND_DATA
+};
+#endif
diff --git a/bfd/nlm.c b/bfd/nlm.c
new file mode 100644
index 00000000000..89c6baa64ef
--- /dev/null
+++ b/bfd/nlm.c
@@ -0,0 +1,55 @@
+/* NLM (NetWare Loadable Module) executable support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libnlm.h"
+
+/* Make an NLM object. We just need to allocate the backend
+ information. */
+
+boolean
+nlm_mkobject (abfd)
+ bfd * abfd;
+{
+ nlm_tdata (abfd) =
+ (struct nlm_obj_tdata *) bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
+ if (nlm_tdata (abfd) == NULL)
+ return (false);
+
+ if (nlm_architecture (abfd) != bfd_arch_unknown)
+ bfd_default_set_arch_mach (abfd, nlm_architecture (abfd),
+ nlm_machine (abfd));
+
+ /* since everything is done at close time, do we need any initialization? */
+ return (true);
+}
+
+/* Set the architecture and machine for an NLM object. */
+
+boolean
+nlm_set_arch_mach (abfd, arch, machine)
+ bfd * abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ bfd_default_set_arch_mach (abfd, arch, machine);
+ return arch == nlm_architecture (abfd);
+}
diff --git a/bfd/nlm32-alpha.c b/bfd/nlm32-alpha.c
new file mode 100644
index 00000000000..24c8e516762
--- /dev/null
+++ b/bfd/nlm32-alpha.c
@@ -0,0 +1,892 @@
+/* Support for 32-bit Alpha NLM (NetWare Loadable Module)
+ Copyright (C) 1993 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file describes the 32 bit Alpha NLM format. You might think
+ that an Alpha chip would use a 64 bit format, but, for some reason,
+ it doesn't. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define ARCH_SIZE 32
+
+#include "nlm/alpha-ext.h"
+#define Nlm_External_Fixed_Header Nlm32_alpha_External_Fixed_Header
+
+#include "libnlm.h"
+
+static boolean nlm_alpha_backend_object_p
+ PARAMS ((bfd *));
+static boolean nlm_alpha_write_prefix
+ PARAMS ((bfd *));
+static boolean nlm_alpha_read_reloc
+ PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
+static boolean nlm_alpha_mangle_relocs
+ PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
+static boolean nlm_alpha_read_import
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static boolean nlm_alpha_write_import
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_alpha_set_public_section
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static bfd_vma nlm_alpha_get_public_offset
+ PARAMS ((bfd *, asymbol *));
+static boolean nlm_alpha_write_external
+ PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
+
+/* Alpha NLM's have a prefix header before the standard NLM. This
+ function reads it in, verifies the version, and seeks the bfd to
+ the location before the regular NLM header. */
+
+static boolean
+nlm_alpha_backend_object_p (abfd)
+ bfd *abfd;
+{
+ struct nlm32_alpha_external_prefix_header s;
+ bfd_size_type size;
+
+ if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
+ return false;
+
+ if (bfd_h_get_32 (abfd, s.magic) != NLM32_ALPHA_MAGIC)
+ return false;
+
+ /* FIXME: Should we check the format number? */
+
+ /* Skip to the end of the header. */
+ size = bfd_h_get_32 (abfd, s.size);
+ if (bfd_seek (abfd, size, SEEK_SET) != 0)
+ return false;
+
+ return true;
+}
+
+/* Write out the prefix. */
+
+static boolean
+nlm_alpha_write_prefix (abfd)
+ bfd *abfd;
+{
+ struct nlm32_alpha_external_prefix_header s;
+
+ memset (&s, 0, sizeof s);
+ bfd_h_put_32 (abfd, (bfd_vma) NLM32_ALPHA_MAGIC, s.magic);
+ bfd_h_put_32 (abfd, (bfd_vma) 2, s.format);
+ bfd_h_put_32 (abfd, (bfd_vma) sizeof s, s.size);
+ if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
+ return false;
+ return true;
+}
+
+/* How to process the various reloc types. */
+
+static reloc_howto_type nlm32_alpha_howto_table[] =
+{
+ /* Reloc type 0 is ignored by itself. However, it appears after a
+ GPDISP reloc to identify the location where the low order 16 bits
+ of the gp register are loaded. */
+ HOWTO (ALPHA_R_IGNORE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "IGNORE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit reference to a symbol. */
+ HOWTO (ALPHA_R_REFLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "REFLONG", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit reference to a symbol. */
+ HOWTO (ALPHA_R_REFQUAD, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "REFQUAD", /* name */
+ true, /* partial_inplace */
+ 0xffffffffffffffff, /* src_mask */
+ 0xffffffffffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit GP relative offset. This is just like REFLONG except
+ that when the value is used the value of the gp register will be
+ added in. */
+ HOWTO (ALPHA_R_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "GPREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Used for an instruction that refers to memory off the GP
+ register. The offset is 16 bits of the 32 bit instruction. This
+ reloc always seems to be against the .lita section. */
+ HOWTO (ALPHA_R_LITERAL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "LITERAL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* This reloc only appears immediately following a LITERAL reloc.
+ It identifies a use of the literal. It seems that the linker can
+ use this to eliminate a portion of the .lita section. The symbol
+ index is special: 1 means the literal address is in the base
+ register of a memory format instruction; 2 means the literal
+ address is in the byte offset register of a byte-manipulation
+ instruction; 3 means the literal address is in the target
+ register of a jsr instruction. This does not actually do any
+ relocation. */
+ HOWTO (ALPHA_R_LITUSE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "LITUSE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Load the gp register. This is always used for a ldah instruction
+ which loads the upper 16 bits of the gp register. The next reloc
+ will be an IGNORE reloc which identifies the location of the lda
+ instruction which loads the lower 16 bits. The symbol index of
+ the GPDISP instruction appears to actually be the number of bytes
+ between the ldah and lda instructions. This gives two different
+ ways to determine where the lda instruction is; I don't know why
+ both are used. The value to use for the relocation is the
+ difference between the GP value and the current location; the
+ load will always be done against a register holding the current
+ address. */
+ HOWTO (ALPHA_R_GPDISP, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "GPDISP", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 21 bit branch. The native assembler generates these for
+ branches within the text segment, and also fills in the PC
+ relative offset in the instruction. It seems to me that this
+ reloc, unlike the others, is not partial_inplace. */
+ HOWTO (ALPHA_R_BRADDR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "BRADDR", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A hint for a jump to a register. */
+ HOWTO (ALPHA_R_HINT, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "HINT", /* name */
+ true, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "SREL64", /* name */
+ true, /* partial_inplace */
+ 0xffffffffffffffff, /* src_mask */
+ 0xffffffffffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Push a value on the reloc evaluation stack. */
+ HOWTO (ALPHA_R_OP_PUSH, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_PUSH", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Store the value from the stack at the given address. Store it in
+ a bitfield of size r_size starting at bit position r_offset. */
+ HOWTO (ALPHA_R_OP_STORE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_STORE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffffffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Subtract the reloc address from the value on the top of the
+ relocation stack. */
+ HOWTO (ALPHA_R_OP_PSUB, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_PSUB", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Shift the value on the top of the relocation stack right by the
+ given value. */
+ HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "OP_PRSHIFT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Adjust the GP value for a new range in the object file. */
+ HOWTO (ALPHA_R_GPVALUE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "GPVALUE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+static reloc_howto_type nlm32_alpha_nw_howto =
+ HOWTO (ALPHA_R_NW_RELOC, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "NW_RELOC", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* Read an Alpha NLM reloc. This routine keeps some static data which
+ it uses when handling local relocs. This only works correctly
+ because all the local relocs are read at once. */
+
+static boolean
+nlm_alpha_read_reloc (abfd, sym, secp, rel)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+ asection **secp;
+ arelent *rel;
+{
+ static bfd_vma gp_value;
+ static bfd_vma lita_address;
+ struct nlm32_alpha_external_reloc ext;
+ bfd_vma r_vaddr;
+ long r_symndx;
+ int r_type, r_extern, r_offset, r_size;
+ asection *code_sec, *data_sec;
+
+ /* Read the reloc from the file. */
+ if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext)
+ return false;
+
+ /* Swap in the reloc information. */
+ r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext.r_vaddr);
+ r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext.r_symndx);
+
+ BFD_ASSERT (bfd_little_endian (abfd));
+
+ r_type = ((ext.r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
+ >> RELOC_BITS0_TYPE_SH_LITTLE);
+ r_extern = (ext.r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
+ r_offset = ((ext.r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
+ >> RELOC_BITS1_OFFSET_SH_LITTLE);
+ /* Ignore the reserved bits. */
+ r_size = ((ext.r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
+ >> RELOC_BITS3_SIZE_SH_LITTLE);
+
+ /* Fill in the BFD arelent structure. */
+ code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ if (r_extern)
+ {
+ /* External relocations are only used for imports. */
+ BFD_ASSERT (sym != NULL);
+ /* We don't need to set sym_ptr_ptr for this case. It is set in
+ nlm_canonicalize_reloc. */
+ rel->sym_ptr_ptr = NULL;
+ rel->addend = 0;
+ }
+ else
+ {
+ /* Internal relocations are only used for local relocation
+ fixups. If they are not NW_RELOC or GPDISP or IGNORE, they
+ must be against .text or .data. */
+ BFD_ASSERT (r_type == ALPHA_R_NW_RELOC || sym == NULL);
+ if (r_type == ALPHA_R_NW_RELOC
+ || r_type == ALPHA_R_GPDISP
+ || r_type == ALPHA_R_IGNORE)
+ {
+ rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ rel->addend = 0;
+ }
+ else if (r_symndx == ALPHA_RELOC_SECTION_TEXT)
+ {
+ rel->sym_ptr_ptr = code_sec->symbol_ptr_ptr;
+ BFD_ASSERT (bfd_get_section_vma (abfd, code_sec) == 0);
+ rel->addend = 0;
+ }
+ else if (r_symndx == ALPHA_RELOC_SECTION_DATA)
+ {
+ rel->sym_ptr_ptr = data_sec->symbol_ptr_ptr;
+ rel->addend = - bfd_get_section_vma (abfd, data_sec);
+ }
+ else
+ {
+ BFD_ASSERT (0);
+ rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ rel->addend = 0;
+ }
+ }
+
+ /* We use the address to determine whether the reloc is in the .text
+ or .data section. R_NW_RELOC relocs don't really have a section,
+ so we put them in .text. */
+ if (r_type == ALPHA_R_NW_RELOC
+ || r_vaddr < bfd_section_size (abfd, code_sec))
+ {
+ *secp = code_sec;
+ rel->address = r_vaddr;
+ }
+ else
+ {
+ *secp = data_sec;
+ rel->address = r_vaddr - bfd_section_size (abfd, code_sec);
+ }
+
+ /* We must adjust the addend based on the type. */
+ BFD_ASSERT ((r_type >= 0 && r_type <= ALPHA_R_GPVALUE)
+ || r_type == ALPHA_R_NW_RELOC);
+
+ switch (r_type)
+ {
+ case ALPHA_R_BRADDR:
+ case ALPHA_R_SREL16:
+ case ALPHA_R_SREL32:
+ case ALPHA_R_SREL64:
+ /* The PC relative relocs do not seem to use the section VMA as
+ a negative addend. */
+ rel->addend = 0;
+ break;
+
+ case ALPHA_R_GPREL32:
+ /* Copy the gp value for this object file into the addend, to
+ ensure that we are not confused by the linker. */
+ if (! r_extern)
+ rel->addend += gp_value;
+ break;
+
+ case ALPHA_R_LITERAL:
+ BFD_ASSERT (! r_extern);
+ rel->addend += lita_address;
+ break;
+
+ case ALPHA_R_LITUSE:
+ case ALPHA_R_GPDISP:
+ /* The LITUSE and GPDISP relocs do not use a symbol, or an
+ addend, but they do use a special code. Put this code in the
+ addend field. */
+ rel->addend = r_symndx;
+ rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ break;
+
+ case ALPHA_R_OP_STORE:
+ /* The STORE reloc needs the size and offset fields. We store
+ them in the addend. */
+ BFD_ASSERT (r_offset < 256 && r_size < 256);
+ rel->addend = (r_offset << 8) + r_size;
+ break;
+
+ case ALPHA_R_OP_PUSH:
+ case ALPHA_R_OP_PSUB:
+ case ALPHA_R_OP_PRSHIFT:
+ /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
+ address. I believe that the address supplied is really an
+ addend. */
+ rel->addend = r_vaddr;
+ break;
+
+ case ALPHA_R_GPVALUE:
+ /* Record the new gp value. */
+ gp_value += r_symndx;
+ rel->addend = gp_value;
+ break;
+
+ case ALPHA_R_IGNORE:
+ /* If the type is ALPHA_R_IGNORE, make sure this is a reference
+ to the absolute section so that the reloc is ignored. For
+ some reason the address of this reloc type is not adjusted by
+ the section vma. We record the gp value for this object file
+ here, for convenience when doing the GPDISP relocation. */
+ rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ rel->address = r_vaddr;
+ rel->addend = gp_value;
+ break;
+
+ case ALPHA_R_NW_RELOC:
+ /* If this is SETGP, we set the addend to 0. Otherwise we set
+ the addend to the size of the .lita section (this is
+ r_symndx) plus 1. We have already set the address of the
+ reloc to r_vaddr. */
+ if (r_size == ALPHA_R_NW_RELOC_SETGP)
+ {
+ gp_value = r_vaddr;
+ rel->addend = 0;
+ }
+ else if (r_size == ALPHA_R_NW_RELOC_LITA)
+ {
+ lita_address = r_vaddr;
+ rel->addend = r_symndx + 1;
+ }
+ else
+ BFD_ASSERT (0);
+ rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ break;
+
+ default:
+ break;
+ }
+
+ if (r_type == ALPHA_R_NW_RELOC)
+ rel->howto = &nlm32_alpha_nw_howto;
+ else
+ rel->howto = &nlm32_alpha_howto_table[r_type];
+
+ return true;
+}
+
+/* Mangle Alpha NLM relocs for output. */
+
+static boolean
+nlm_alpha_mangle_relocs (abfd, sec, data, offset, count)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ bfd_vma offset;
+ bfd_size_type count;
+{
+ return true;
+}
+
+/* Read an ALPHA NLM import record */
+
+static boolean
+nlm_alpha_read_import (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ struct nlm_relent *nlm_relocs; /* relocation records for symbol */
+ bfd_size_type rcount; /* number of relocs */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
+ unsigned char symlength; /* length of symbol name */
+ char *name;
+
+ if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ return false;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, symlength + 1);
+ if (name == NULL)
+ return false;
+ if (bfd_read (name, symlength, 1, abfd) != symlength)
+ return false;
+ name[symlength] = '\0';
+ sym -> symbol.name = name;
+ sym -> symbol.flags = 0;
+ sym -> symbol.value = 0;
+ sym -> symbol.section = bfd_und_section_ptr;
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+ rcount = bfd_h_get_32 (abfd, temp);
+ nlm_relocs = ((struct nlm_relent *)
+ bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+ if (!nlm_relocs)
+ return false;
+ sym -> relocs = nlm_relocs;
+ sym -> rcnt = 0;
+ while (sym -> rcnt < rcount)
+ {
+ asection *section;
+
+ if (nlm_alpha_read_reloc (abfd, sym, &section,
+ &nlm_relocs -> reloc)
+ == false)
+ return false;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+
+ return true;
+}
+
+/* Write an Alpha NLM reloc. */
+
+static boolean
+nlm_alpha_write_import (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ asymbol *sym;
+ bfd_vma r_vaddr;
+ long r_symndx;
+ int r_type, r_extern, r_offset, r_size;
+ struct nlm32_alpha_external_reloc ext;
+
+ sym = *rel->sym_ptr_ptr;
+
+ /* Get values for the relocation fields. */
+ r_type = rel->howto->type;
+ if (r_type != ALPHA_R_NW_RELOC)
+ {
+ r_vaddr = bfd_get_section_vma (abfd, sec) + rel->address;
+ if ((sec->flags & SEC_CODE) == 0)
+ r_vaddr += bfd_section_size (abfd,
+ bfd_get_section_by_name (abfd,
+ NLM_CODE_NAME));
+ if (bfd_is_und_section (bfd_get_section (sym)))
+ {
+ r_extern = 1;
+ r_symndx = 0;
+ }
+ else
+ {
+ r_extern = 0;
+ if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
+ r_symndx = ALPHA_RELOC_SECTION_TEXT;
+ else
+ r_symndx = ALPHA_RELOC_SECTION_DATA;
+ }
+ r_offset = 0;
+ r_size = 0;
+
+ switch (r_type)
+ {
+ case ALPHA_R_LITUSE:
+ case ALPHA_R_GPDISP:
+ r_symndx = rel->addend;
+ break;
+
+ case ALPHA_R_OP_STORE:
+ r_size = rel->addend & 0xff;
+ r_offset = (rel->addend >> 8) & 0xff;
+ break;
+
+ case ALPHA_R_OP_PUSH:
+ case ALPHA_R_OP_PSUB:
+ case ALPHA_R_OP_PRSHIFT:
+ r_vaddr = rel->addend;
+ break;
+
+ case ALPHA_R_IGNORE:
+ r_vaddr = rel->address;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ /* r_type == ALPHA_R_NW_RELOC */
+ r_vaddr = rel->address;
+ if (rel->addend == 0)
+ {
+ r_symndx = 0;
+ r_size = ALPHA_R_NW_RELOC_SETGP;
+ }
+ else
+ {
+ r_symndx = rel->addend - 1;
+ r_size = ALPHA_R_NW_RELOC_LITA;
+ }
+ r_extern = 0;
+ r_offset = 0;
+ }
+
+ /* Swap out the relocation fields. */
+ bfd_h_put_64 (abfd, r_vaddr, (bfd_byte *) ext.r_vaddr);
+ bfd_h_put_32 (abfd, r_symndx, (bfd_byte *) ext.r_symndx);
+
+ BFD_ASSERT (bfd_little_endian (abfd));
+
+ ext.r_bits[0] = ((r_type << RELOC_BITS0_TYPE_SH_LITTLE)
+ & RELOC_BITS0_TYPE_LITTLE);
+ ext.r_bits[1] = ((r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
+ | ((r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
+ & RELOC_BITS1_OFFSET_LITTLE));
+ ext.r_bits[2] = 0;
+ ext.r_bits[3] = ((r_size << RELOC_BITS3_SIZE_SH_LITTLE)
+ & RELOC_BITS3_SIZE_LITTLE);
+
+ /* Write out the relocation. */
+ if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext)
+ return false;
+
+ return true;
+}
+
+/* Alpha NetWare does not use the high bit to determine whether a
+ public symbol is in the code segment or the data segment. Instead,
+ it just uses the address. The set_public_section and
+ get_public_offset routines override the default code which uses the
+ high bit. */
+
+/* Set the section for a public symbol. */
+
+static boolean
+nlm_alpha_set_public_section (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ asection *code_sec, *data_sec;
+
+ code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ if (sym->symbol.value < bfd_section_size (abfd, code_sec))
+ {
+ sym->symbol.section = code_sec;
+ sym->symbol.flags |= BSF_FUNCTION;
+ }
+ else
+ {
+ sym->symbol.section = data_sec;
+ sym->symbol.value -= bfd_section_size (abfd, code_sec);
+ /* The data segment had better be aligned. */
+ BFD_ASSERT ((bfd_section_size (abfd, code_sec) & 0xf) == 0);
+ }
+ return true;
+}
+
+/* Get the offset to write out for a public symbol. */
+
+static bfd_vma
+nlm_alpha_get_public_offset (abfd, sym)
+ bfd *abfd;
+ asymbol *sym;
+{
+ return bfd_asymbol_value (sym);
+}
+
+/* Write an Alpha NLM external symbol. */
+
+static boolean
+nlm_alpha_write_external (abfd, count, sym, relocs)
+ bfd *abfd;
+ bfd_size_type count;
+ asymbol *sym;
+ struct reloc_and_sec *relocs;
+{
+ int i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+ arelent r;
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ return false;
+
+ bfd_put_32 (abfd, count + 2, temp);
+ if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ /* The first two relocs for each external symbol are the .lita
+ address and the GP value. */
+ r.sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ r.howto = &nlm32_alpha_nw_howto;
+
+ r.address = nlm_alpha_backend_data (abfd)->lita_address;
+ r.addend = nlm_alpha_backend_data (abfd)->lita_size + 1;
+ if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false)
+ return false;
+
+ r.address = nlm_alpha_backend_data (abfd)->gp;
+ r.addend = 0;
+ if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false)
+ return false;
+
+ for (i = 0; i < count; i++)
+ {
+ if (nlm_alpha_write_import (abfd, relocs[i].sec,
+ relocs[i].rel) == false)
+ return false;
+ }
+
+ return true;
+}
+
+#include "nlmswap.h"
+
+static const struct nlm_backend_data nlm32_alpha_backend =
+{
+ "NetWare Alpha Module \032",
+ sizeof (Nlm32_alpha_External_Fixed_Header),
+ sizeof (struct nlm32_alpha_external_prefix_header),
+ bfd_arch_alpha,
+ 0,
+ true, /* no uninitialized data permitted by Alpha NetWare. */
+ nlm_alpha_backend_object_p,
+ nlm_alpha_write_prefix,
+ nlm_alpha_read_reloc,
+ nlm_alpha_mangle_relocs,
+ nlm_alpha_read_import,
+ nlm_alpha_write_import,
+ nlm_alpha_set_public_section,
+ nlm_alpha_get_public_offset,
+ nlm_swap_fixed_header_in,
+ nlm_swap_fixed_header_out,
+ nlm_alpha_write_external,
+ 0, /* write_export */
+};
+
+#define TARGET_LITTLE_NAME "nlm32-alpha"
+#define TARGET_LITTLE_SYM nlmNAME(alpha_vec)
+#define TARGET_BACKEND_DATA &nlm32_alpha_backend
+
+#include "nlm-target.h"
diff --git a/bfd/nlm32-i386.c b/bfd/nlm32-i386.c
new file mode 100644
index 00000000000..f16c74d985e
--- /dev/null
+++ b/bfd/nlm32-i386.c
@@ -0,0 +1,451 @@
+/* Support for 32-bit i386 NLM (NetWare Loadable Module)
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define ARCH_SIZE 32
+
+#include "nlm/i386-ext.h"
+#define Nlm_External_Fixed_Header Nlm32_i386_External_Fixed_Header
+
+#include "libnlm.h"
+
+static boolean nlm_i386_read_reloc
+ PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
+static boolean nlm_i386_write_import
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_i386_mangle_relocs
+ PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
+static boolean nlm_i386_read_import
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static boolean nlm_i386_write_external
+ PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
+
+/* Adjust the reloc location by an absolute value. */
+
+static reloc_howto_type nlm_i386_abs_howto =
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* Adjust the reloc location by a PC relative displacement. */
+
+static reloc_howto_type nlm_i386_pcrel_howto =
+ HOWTO (1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "DISP32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true); /* pcrel_offset */
+
+/* Read a NetWare i386 reloc. */
+
+static boolean
+nlm_i386_read_reloc (abfd, sym, secp, rel)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+ asection **secp;
+ arelent *rel;
+{
+ bfd_byte temp[4];
+ bfd_vma val;
+ const char *name;
+
+ if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ val = bfd_get_32 (abfd, temp);
+
+ /* The value is an offset into either the code or data segment.
+ This is the location which needs to be adjusted.
+
+ If this is a relocation fixup rather than an imported symbol (the
+ sym argument is NULL) then the high bit is 0 if the location
+ needs to be adjusted by the address of the data segment, or 1 if
+ the location needs to be adjusted by the address of the code
+ segment. If this is an imported symbol, then the high bit is 0
+ if the location is 0 if the location should be adjusted by the
+ offset to the symbol, or 1 if the location should adjusted by the
+ absolute value of the symbol.
+
+ The second most significant bit is 0 if the value is an offset
+ into the data segment, or 1 if the value is an offset into the
+ code segment.
+
+ All this translates fairly easily into a BFD reloc. */
+
+ if (sym == NULL)
+ {
+ if ((val & NLM_HIBIT) == 0)
+ name = NLM_INITIALIZED_DATA_NAME;
+ else
+ {
+ name = NLM_CODE_NAME;
+ val &=~ NLM_HIBIT;
+ }
+ rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
+ rel->howto = &nlm_i386_abs_howto;
+ }
+ else
+ {
+ /* In this case we do not need to set the sym_ptr_ptr field. */
+ rel->sym_ptr_ptr = NULL;
+ if ((val & NLM_HIBIT) == 0)
+ rel->howto = &nlm_i386_pcrel_howto;
+ else
+ {
+ rel->howto = &nlm_i386_abs_howto;
+ val &=~ NLM_HIBIT;
+ }
+ }
+
+ if ((val & (NLM_HIBIT >> 1)) == 0)
+ *secp = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ else
+ {
+ *secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ val &=~ (NLM_HIBIT >> 1);
+ }
+
+ rel->address = val;
+ rel->addend = 0;
+
+ return true;
+}
+
+/* Write a NetWare i386 reloc. */
+
+static boolean
+nlm_i386_write_import (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ asymbol *sym;
+ bfd_vma val;
+ bfd_byte temp[4];
+
+ /* NetWare only supports two kinds of relocs. We should check
+ special_function here, as well, but at the moment coff-i386
+ relocs uses a special_function which does not affect what we do
+ here. */
+ if (rel->addend != 0
+ || rel->howto == NULL
+ || rel->howto->rightshift != 0
+ || rel->howto->size != 2
+ || rel->howto->bitsize != 32
+ || rel->howto->bitpos != 0
+ || rel->howto->src_mask != 0xffffffff
+ || rel->howto->dst_mask != 0xffffffff)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ sym = *rel->sym_ptr_ptr;
+
+ /* The value we write out is the offset into the appropriate
+ segment. This offset is the section vma, adjusted by the vma of
+ the lowest section in that segment, plus the address of the
+ relocation. */
+ val = bfd_get_section_vma (abfd, sec) + rel->address;
+
+ /* The second most significant bit is 0 if the value is an offset
+ into the data segment, or 1 if the value is an offset into the
+ code segment. */
+ if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
+ {
+ val -= nlm_get_text_low (abfd);
+ val |= NLM_HIBIT >> 1;
+ }
+ else
+ val -= nlm_get_data_low (abfd);
+
+ if (! bfd_is_und_section (bfd_get_section (sym)))
+ {
+ /* NetWare only supports absolute internal relocs. */
+ if (rel->howto->pc_relative)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ /* The high bit is 1 if the reloc is against the code section, 0
+ if against the data section. */
+ if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
+ val |= NLM_HIBIT;
+ }
+ else
+ {
+ /* The high bit is 1 if this is an absolute reloc, 0 if it is PC
+ relative. */
+ if (! rel->howto->pc_relative)
+ val |= NLM_HIBIT;
+ else
+ {
+ /* PC relative relocs on NetWare must be pcrel_offset. */
+ if (! rel->howto->pcrel_offset)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+ }
+ }
+
+ bfd_put_32 (abfd, val, temp);
+ if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ return true;
+}
+
+/* I want to be able to use objcopy to turn a i386 a.out or COFF file
+ into a NetWare i386 module. That means that the relocs from the
+ source file have to be mapped into relocs that apply to the target
+ file. This function is called by nlm_set_section_contents to give
+ it a chance to rework the relocs.
+
+ This is actually a fairly general concept. However, this is not a
+ general implementation. */
+
+static boolean
+nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ bfd_vma offset;
+ bfd_size_type count;
+{
+ arelent **rel_ptr_ptr, **rel_end;
+
+ rel_ptr_ptr = sec->orelocation;
+ rel_end = rel_ptr_ptr + sec->reloc_count;
+ for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
+ {
+ arelent *rel;
+ asymbol *sym;
+ bfd_vma addend;
+
+ rel = *rel_ptr_ptr;
+ sym = *rel->sym_ptr_ptr;
+
+ /* Note that no serious harm will ensue if we fail to change a
+ reloc. We will wind up failing in nlm_i386_write_import. */
+
+ /* Make sure this reloc is within the data we have. We only 4
+ byte relocs here, so we insist on having 4 bytes. */
+ if (rel->address < offset
+ || rel->address + 4 > offset + count)
+ continue;
+
+ /* NetWare doesn't support reloc addends, so we get rid of them
+ here by simply adding them into the object data. We handle
+ the symbol value, if any, the same way. */
+ addend = rel->addend + sym->value;
+
+ /* The value of a symbol is the offset into the section. If the
+ symbol is in the .bss segment, we need to include the size of
+ the data segment in the offset as well. Fortunately, we know
+ that at this point the size of the data section is in the NLM
+ header. */
+ if (((bfd_get_section_flags (abfd, bfd_get_section (sym))
+ & SEC_LOAD) == 0)
+ && ((bfd_get_section_flags (abfd, bfd_get_section (sym))
+ & SEC_ALLOC) != 0))
+ addend += nlm_fixed_header (abfd)->dataImageSize;
+
+ if (addend != 0
+ && rel->howto != NULL
+ && rel->howto->rightshift == 0
+ && rel->howto->size == 2
+ && rel->howto->bitsize == 32
+ && rel->howto->bitpos == 0
+ && rel->howto->src_mask == 0xffffffff
+ && rel->howto->dst_mask == 0xffffffff)
+ {
+ bfd_vma val;
+
+ val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
+ val += addend;
+ bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
+ rel->addend = 0;
+ }
+
+ /* NetWare uses a reloc with pcrel_offset set. We adjust
+ pc_relative relocs accordingly. We are going to change the
+ howto field, so we can only do this if the current one is
+ compatible. We should check special_function here, but at
+ the moment coff-i386 uses a special_function which does not
+ affect what we are doing here. */
+ if (rel->howto != NULL
+ && rel->howto->pc_relative
+ && ! rel->howto->pcrel_offset
+ && rel->howto->rightshift == 0
+ && rel->howto->size == 2
+ && rel->howto->bitsize == 32
+ && rel->howto->bitpos == 0
+ && rel->howto->src_mask == 0xffffffff
+ && rel->howto->dst_mask == 0xffffffff)
+ {
+ bfd_vma val;
+
+ /* When pcrel_offset is not set, it means that the negative
+ of the address of the memory location is stored in the
+ memory location. We must add it back in. */
+ val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
+ val += rel->address;
+ bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
+
+ rel->howto = &nlm_i386_pcrel_howto;
+ }
+ }
+
+ return true;
+}
+
+/* Read a NetWare i386 import record */
+static boolean
+nlm_i386_read_import (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ struct nlm_relent *nlm_relocs; /* relocation records for symbol */
+ bfd_size_type rcount; /* number of relocs */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
+ unsigned char symlength; /* length of symbol name */
+ char *name;
+
+ if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ return false;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, symlength + 1);
+ if (name == NULL)
+ return false;
+ if (bfd_read (name, symlength, 1, abfd) != symlength)
+ return false;
+ name[symlength] = '\0';
+ sym -> symbol.name = name;
+ sym -> symbol.flags = 0;
+ sym -> symbol.value = 0;
+ sym -> symbol.section = bfd_und_section_ptr;
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+ rcount = bfd_h_get_32 (abfd, temp);
+ nlm_relocs = ((struct nlm_relent *)
+ bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+ if (!nlm_relocs)
+ return false;
+ sym -> relocs = nlm_relocs;
+ sym -> rcnt = 0;
+ while (sym -> rcnt < rcount)
+ {
+ asection *section;
+
+ if (nlm_i386_read_reloc (abfd, sym, &section,
+ &nlm_relocs -> reloc)
+ == false)
+ return false;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return true;
+}
+
+/* Write out an external reference. */
+
+static boolean
+nlm_i386_write_external (abfd, count, sym, relocs)
+ bfd *abfd;
+ bfd_size_type count;
+ asymbol *sym;
+ struct reloc_and_sec *relocs;
+{
+ unsigned int i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ return false;
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ for (i = 0; i < count; i++)
+ {
+ if (nlm_i386_write_import (abfd, relocs[i].sec,
+ relocs[i].rel) == false)
+ return false;
+ }
+
+ return true;
+}
+
+#include "nlmswap.h"
+
+static const struct nlm_backend_data nlm32_i386_backend =
+{
+ "NetWare Loadable Module\032",
+ sizeof (Nlm32_i386_External_Fixed_Header),
+ 0, /* optional_prefix_size */
+ bfd_arch_i386,
+ 0,
+ false,
+ 0, /* backend_object_p */
+ 0, /* write_prefix_func */
+ nlm_i386_read_reloc,
+ nlm_i386_mangle_relocs,
+ nlm_i386_read_import,
+ nlm_i386_write_import,
+ 0, /* set_public_section */
+ 0, /* get_public_offset */
+ nlm_swap_fixed_header_in,
+ nlm_swap_fixed_header_out,
+ nlm_i386_write_external,
+ 0, /* write_export */
+};
+
+#define TARGET_LITTLE_NAME "nlm32-i386"
+#define TARGET_LITTLE_SYM nlmNAME(i386_vec)
+#define TARGET_BACKEND_DATA &nlm32_i386_backend
+
+#include "nlm-target.h"
diff --git a/bfd/nlm32-ppc.c b/bfd/nlm32-ppc.c
new file mode 100644
index 00000000000..ecf2de8f10b
--- /dev/null
+++ b/bfd/nlm32-ppc.c
@@ -0,0 +1,1045 @@
+/* Support for 32-bit PowerPC NLM (NetWare Loadable Module)
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* The format of a PowerPC NLM changed. Define OLDFORMAT to get the
+ old format. */
+
+#define ARCH_SIZE 32
+
+#include "nlm/ppc-ext.h"
+#define Nlm_External_Fixed_Header Nlm32_powerpc_External_Fixed_Header
+
+#include "libnlm.h"
+
+#ifdef OLDFORMAT
+static boolean nlm_powerpc_backend_object_p
+ PARAMS ((bfd *));
+static boolean nlm_powerpc_write_prefix
+ PARAMS ((bfd *));
+#endif
+
+static boolean nlm_powerpc_read_reloc
+ PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
+static boolean nlm_powerpc_mangle_relocs
+ PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
+static boolean nlm_powerpc_read_import
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+
+#ifdef OLDFORMAT
+static boolean nlm_powerpc_write_reloc
+ PARAMS ((bfd *, asection *, arelent *, int));
+#endif
+
+static boolean nlm_powerpc_write_import
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_powerpc_write_external
+ PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
+
+#ifndef OLDFORMAT
+static boolean nlm_powerpc_set_public_section
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static bfd_vma nlm_powerpc_get_public_offset
+ PARAMS ((bfd *, asymbol *));
+#endif
+
+#ifdef OLDFORMAT
+
+/* The prefix header is only used in the old format. */
+
+/* PowerPC NLM's have a prefix header before the standard NLM. This
+ function reads it in, verifies the version, and seeks the bfd to
+ the location before the regular NLM header. */
+
+static boolean
+nlm_powerpc_backend_object_p (abfd)
+ bfd *abfd;
+{
+ struct nlm32_powerpc_external_prefix_header s;
+
+ if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
+ return false;
+
+ if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
+ || bfd_h_get_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
+ return false;
+
+ return true;
+}
+
+/* Write out the prefix. */
+
+static boolean
+nlm_powerpc_write_prefix (abfd)
+ bfd *abfd;
+{
+ struct nlm32_powerpc_external_prefix_header s;
+
+ memset (&s, 0, sizeof s);
+ memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
+ bfd_h_put_32 (abfd, (bfd_vma) NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
+ bfd_h_put_32 (abfd, (bfd_vma) 0, s.origins);
+
+ /* FIXME: What should we do about the date? */
+
+ if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s)
+ return false;
+
+ return true;
+}
+
+#endif /* OLDFORMAT */
+
+#ifndef OLDFORMAT
+
+/* There is only one type of reloc in a PowerPC NLM. */
+
+static reloc_howto_type nlm_powerpc_howto =
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* Read a PowerPC NLM reloc. */
+
+static boolean
+nlm_powerpc_read_reloc (abfd, sym, secp, rel)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+ asection **secp;
+ arelent *rel;
+{
+ bfd_byte temp[4];
+ bfd_vma val;
+ const char *name;
+
+ if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ val = bfd_get_32 (abfd, temp);
+
+ /* The value is a word offset into either the code or data segment.
+ This is the location which needs to be adjusted.
+
+ The high bit is 0 if the value is an offset into the data
+ segment, or 1 if the value is an offset into the text segment.
+
+ If this is a relocation fixup rather than an imported symbol (the
+ sym argument is NULL), then the second most significant bit is 0
+ if the address of the data segment should be added to the
+ location addressed by the value, or 1 if the address of the text
+ segment should be added.
+
+ If this is an imported symbol, the second most significant bit is
+ not used and must be 0. */
+
+ if ((val & NLM_HIBIT) == 0)
+ name = NLM_INITIALIZED_DATA_NAME;
+ else
+ {
+ name = NLM_CODE_NAME;
+ val &=~ NLM_HIBIT;
+ }
+ *secp = bfd_get_section_by_name (abfd, name);
+
+ if (sym == NULL)
+ {
+ if ((val & (NLM_HIBIT >> 1)) == 0)
+ name = NLM_INITIALIZED_DATA_NAME;
+ else
+ {
+ name = NLM_CODE_NAME;
+ val &=~ (NLM_HIBIT >> 1);
+ }
+ rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
+ }
+
+ rel->howto = &nlm_powerpc_howto;
+
+ rel->address = val << 2;
+ rel->addend = 0;
+
+ return true;
+}
+
+#else /* OLDFORMAT */
+
+/* This reloc handling is only applicable to the old format. */
+
+/* How to process the various reloc types. PowerPC NLMs use XCOFF
+ reloc types, and I have just copied the XCOFF reloc table here. */
+
+static reloc_howto_type nlm_powerpc_howto_table[] =
+{
+ /* Standard 32 bit relocation. */
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_POS", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit relocation, but store negative value. */
+ HOWTO (1, /* type */
+ 0, /* rightshift */
+ -2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_NEG", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative relocation. */
+ HOWTO (2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REL", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit TOC relative relocation. */
+ HOWTO (3, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TOC", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* I don't really know what this is. */
+ HOWTO (4, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RTB", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* External TOC relative symbol. */
+ HOWTO (5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_GL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Local TOC relative symbol. */
+ HOWTO (6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TCL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 7 },
+
+ /* Non modifiable absolute branch. */
+ HOWTO (8, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_BA", /* name */
+ true, /* partial_inplace */
+ 0x3fffffc, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 9 },
+
+ /* Non modifiable relative branch. */
+ HOWTO (0xa, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_BR", /* name */
+ true, /* partial_inplace */
+ 0x3fffffc, /* src_mask */
+ 0x3fffffc, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 0xb },
+
+ /* Indirect load. */
+ HOWTO (0xc, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Load address. */
+ HOWTO (0xd, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RLA", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 0xe },
+
+ /* Non-relocating reference. */
+ HOWTO (0xf, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REF", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ { 0x10 },
+ { 0x11 },
+
+ /* TOC relative indirect load. */
+ HOWTO (0x12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TRL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* TOC relative load address. */
+ HOWTO (0x13, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_TRLA", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable relative branch. */
+ HOWTO (0x14, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RRTBI", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable absolute branch. */
+ HOWTO (0x15, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RRTBA", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable call absolute indirect. */
+ HOWTO (0x16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_CAI", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable call relative. */
+ HOWTO (0x17, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch absolute. */
+ HOWTO (0x18, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RBA", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch absolute. */
+ HOWTO (0x19, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_RBAC", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch relative. */
+ HOWTO (0x1a, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Modifiable branch absolute. */
+ HOWTO (0x1b, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REL", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false) /* pcrel_offset */
+};
+
+#define HOWTO_COUNT (sizeof nlm_powerpc_howto_table \
+ / sizeof nlm_powerpc_howto_table[0])
+
+/* Read a PowerPC NLM reloc. */
+
+static boolean
+nlm_powerpc_read_reloc (abfd, sym, secp, rel)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+ asection **secp;
+ arelent *rel;
+{
+ struct nlm32_powerpc_external_reloc ext;
+ bfd_vma l_vaddr;
+ unsigned long l_symndx;
+ int l_rtype;
+ int l_rsecnm;
+ asection *code_sec, *data_sec, *bss_sec;
+
+ /* Read the reloc from the file. */
+ if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext)
+ return false;
+
+ /* Swap in the fields. */
+ l_vaddr = bfd_h_get_32 (abfd, ext.l_vaddr);
+ l_symndx = bfd_h_get_32 (abfd, ext.l_symndx);
+ l_rtype = bfd_h_get_16 (abfd, ext.l_rtype);
+ l_rsecnm = bfd_h_get_16 (abfd, ext.l_rsecnm);
+
+ /* Get the sections now, for convenience. */
+ code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
+
+ /* Work out the arelent fields. */
+ if (sym != NULL)
+ {
+ /* This is an import. sym_ptr_ptr is filled in by
+ nlm_canonicalize_reloc. */
+ rel->sym_ptr_ptr = NULL;
+ }
+ else
+ {
+ asection *sec;
+
+ if (l_symndx == 0)
+ sec = code_sec;
+ else if (l_symndx == 1)
+ sec = data_sec;
+ else if (l_symndx == 2)
+ sec = bss_sec;
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ rel->sym_ptr_ptr = sec->symbol_ptr_ptr;
+ }
+
+ rel->addend = 0;
+
+ BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT);
+
+ rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff);
+
+ BFD_ASSERT (rel->howto->name != NULL
+ && ((l_rtype & 0x8000) != 0
+ ? (rel->howto->complain_on_overflow
+ == complain_overflow_signed)
+ : (rel->howto->complain_on_overflow
+ == complain_overflow_bitfield))
+ && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1);
+
+ if (l_rsecnm == 0)
+ *secp = code_sec;
+ else if (l_rsecnm == 1)
+ {
+ *secp = data_sec;
+ l_vaddr -= bfd_section_size (abfd, code_sec);
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ rel->address = l_vaddr;
+
+ return true;
+}
+
+#endif /* OLDFORMAT */
+
+/* Mangle PowerPC NLM relocs for output. */
+
+static boolean
+nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ bfd_vma offset;
+ bfd_size_type count;
+{
+ return true;
+}
+
+/* Read a PowerPC NLM import record */
+
+static boolean
+nlm_powerpc_read_import (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ struct nlm_relent *nlm_relocs; /* relocation records for symbol */
+ bfd_size_type rcount; /* number of relocs */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
+ unsigned char symlength; /* length of symbol name */
+ char *name;
+
+ if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ return (false);
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, symlength + 1);
+ if (name == NULL)
+ return false;
+ if (bfd_read (name, symlength, 1, abfd) != symlength)
+ return (false);
+ name[symlength] = '\0';
+ sym -> symbol.name = name;
+ sym -> symbol.flags = 0;
+ sym -> symbol.value = 0;
+ sym -> symbol.section = bfd_und_section_ptr;
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return (false);
+ rcount = bfd_h_get_32 (abfd, temp);
+ nlm_relocs = ((struct nlm_relent *)
+ bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+ if (nlm_relocs == (struct nlm_relent *) NULL)
+ return false;
+ sym -> relocs = nlm_relocs;
+ sym -> rcnt = 0;
+ while (sym -> rcnt < rcount)
+ {
+ asection *section;
+
+ if (nlm_powerpc_read_reloc (abfd, sym, &section,
+ &nlm_relocs -> reloc)
+ == false)
+ return false;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return true;
+}
+
+#ifndef OLDFORMAT
+
+/* Write a PowerPC NLM reloc. */
+
+static boolean
+nlm_powerpc_write_import (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ asymbol *sym;
+ bfd_vma val;
+ bfd_byte temp[4];
+
+ /* PowerPC NetWare only supports one kind of reloc. */
+ if (rel->addend != 0
+ || rel->howto == NULL
+ || rel->howto->rightshift != 0
+ || rel->howto->size != 2
+ || rel->howto->bitsize != 32
+ || rel->howto->bitpos != 0
+ || rel->howto->pc_relative
+ || (rel->howto->src_mask != 0xffffffff && rel->addend != 0)
+ || rel->howto->dst_mask != 0xffffffff)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ sym = *rel->sym_ptr_ptr;
+
+ /* The value we write out is the offset into the appropriate
+ segment, rightshifted by two. This offset is the section vma,
+ adjusted by the vma of the lowest section in that segment, plus
+ the address of the relocation. */
+ val = bfd_get_section_vma (abfd, sec) + rel->address;
+ if ((val & 3) != 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ val >>= 2;
+
+ /* The high bit is 0 if the reloc is in the data section, or 1 if
+ the reloc is in the code section. */
+ if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+ val -= nlm_get_data_low (abfd);
+ else
+ {
+ val -= nlm_get_text_low (abfd);
+ val |= NLM_HIBIT;
+ }
+
+ if (! bfd_is_und_section (bfd_get_section (sym)))
+ {
+ /* This is an internal relocation fixup. The second most
+ significant bit is 0 if this is a reloc against the data
+ segment, or 1 if it is a reloc against the text segment. */
+ if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
+ val |= NLM_HIBIT >> 1;
+ }
+
+ bfd_put_32 (abfd, val, temp);
+ if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ return true;
+}
+
+#else /* OLDFORMAT */
+
+/* This is used for the reloc handling in the old format. */
+
+/* Write a PowerPC NLM reloc. */
+
+static boolean
+nlm_powerpc_write_reloc (abfd, sec, rel, indx)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+ int indx;
+{
+ struct nlm32_powerpc_external_reloc ext;
+ asection *code_sec, *data_sec, *bss_sec;
+ asymbol *sym;
+ asection *symsec;
+ unsigned long l_symndx;
+ int l_rtype;
+ int l_rsecnm;
+ reloc_howto_type *howto;
+ bfd_size_type address;
+
+ /* Get the sections now, for convenience. */
+ code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
+
+ sym = *rel->sym_ptr_ptr;
+ symsec = bfd_get_section (sym);
+ if (indx != -1)
+ {
+ BFD_ASSERT (bfd_is_und_section (symsec));
+ l_symndx = indx + 3;
+ }
+ else
+ {
+ if (symsec == code_sec)
+ l_symndx = 0;
+ else if (symsec == data_sec)
+ l_symndx = 1;
+ else if (symsec == bss_sec)
+ l_symndx = 2;
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ bfd_h_put_32 (abfd, (bfd_vma) l_symndx, ext.l_symndx);
+
+ for (howto = nlm_powerpc_howto_table;
+ howto < nlm_powerpc_howto_table + HOWTO_COUNT;
+ howto++)
+ {
+ if (howto->rightshift == rel->howto->rightshift
+ && howto->size == rel->howto->size
+ && howto->bitsize == rel->howto->bitsize
+ && howto->pc_relative == rel->howto->pc_relative
+ && howto->bitpos == rel->howto->bitpos
+ && (howto->partial_inplace == rel->howto->partial_inplace
+ || (! rel->howto->partial_inplace
+ && rel->addend == 0))
+ && (howto->src_mask == rel->howto->src_mask
+ || (rel->howto->src_mask == 0
+ && rel->addend == 0))
+ && howto->dst_mask == rel->howto->dst_mask
+ && howto->pcrel_offset == rel->howto->pcrel_offset)
+ break;
+ }
+ if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ l_rtype = howto->type;
+ if (howto->complain_on_overflow == complain_overflow_signed)
+ l_rtype |= 0x8000;
+ l_rtype |= (howto->bitsize - 1) << 8;
+ bfd_h_put_16 (abfd, (bfd_vma) l_rtype, ext.l_rtype);
+
+ address = rel->address;
+
+ if (sec == code_sec)
+ l_rsecnm = 0;
+ else if (sec == data_sec)
+ {
+ l_rsecnm = 1;
+ address += bfd_section_size (abfd, code_sec);
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ bfd_h_put_16 (abfd, (bfd_vma) l_rsecnm, ext.l_rsecnm);
+ bfd_h_put_32 (abfd, (bfd_vma) address, ext.l_vaddr);
+
+ if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext)
+ return false;
+
+ return true;
+}
+
+/* Write a PowerPC NLM import. */
+
+static boolean
+nlm_powerpc_write_import (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
+}
+
+#endif /* OLDFORMAT */
+
+/* Write a PowerPC NLM external symbol. This routine keeps a static
+ count of the symbol index. FIXME: I don't know if this is
+ necessary, and the index never gets reset. */
+
+static boolean
+nlm_powerpc_write_external (abfd, count, sym, relocs)
+ bfd *abfd;
+ bfd_size_type count;
+ asymbol *sym;
+ struct reloc_and_sec *relocs;
+{
+ unsigned int i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+#ifdef OLDFORMAT
+ static int indx;
+#endif
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ return false;
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ for (i = 0; i < count; i++)
+ {
+#ifndef OLDFORMAT
+ if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel))
+ return false;
+#else
+ if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec,
+ relocs[i].rel, indx))
+ return false;
+#endif
+ }
+
+#ifdef OLDFORMAT
+ ++indx;
+#endif
+
+ return true;
+}
+
+#ifndef OLDFORMAT
+
+/* PowerPC Netware uses a word offset, not a byte offset, for public
+ symbols. */
+
+/* Set the section for a public symbol. */
+
+static boolean
+nlm_powerpc_set_public_section (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ if (sym->symbol.value & NLM_HIBIT)
+ {
+ sym->symbol.value &= ~NLM_HIBIT;
+ sym->symbol.flags |= BSF_FUNCTION;
+ sym->symbol.section =
+ bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ }
+ else
+ {
+ sym->symbol.section =
+ bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ }
+
+ sym->symbol.value <<= 2;
+
+ return true;
+}
+
+/* Get the offset to write out for a public symbol. */
+
+static bfd_vma
+nlm_powerpc_get_public_offset (abfd, sym)
+ bfd *abfd;
+ asymbol *sym;
+{
+ bfd_vma offset;
+ asection *sec;
+
+ offset = bfd_asymbol_value (sym);
+ sec = bfd_get_section (sym);
+ if (sec->flags & SEC_CODE)
+ {
+ offset -= nlm_get_text_low (abfd);
+ offset |= NLM_HIBIT;
+ }
+ else if (sec->flags & (SEC_DATA | SEC_ALLOC))
+ {
+ /* SEC_ALLOC is for the .bss section. */
+ offset -= nlm_get_data_low (abfd);
+ }
+ else
+ {
+ /* We can't handle an exported symbol that is not in the code or
+ data segment. */
+ bfd_set_error (bfd_error_invalid_operation);
+ /* FIXME: No way to return error. */
+ abort ();
+ }
+
+ return offset;
+}
+
+#endif /* ! defined (OLDFORMAT) */
+
+#include "nlmswap.h"
+
+static const struct nlm_backend_data nlm32_powerpc_backend =
+{
+ "NetWare PowerPC Module \032",
+ sizeof (Nlm32_powerpc_External_Fixed_Header),
+#ifndef OLDFORMAT
+ 0, /* optional_prefix_size */
+#else
+ sizeof (struct nlm32_powerpc_external_prefix_header),
+#endif
+ bfd_arch_powerpc,
+ 0,
+ false,
+#ifndef OLDFORMAT
+ 0, /* backend_object_p */
+ 0, /* write_prefix */
+#else
+ nlm_powerpc_backend_object_p,
+ nlm_powerpc_write_prefix,
+#endif
+ nlm_powerpc_read_reloc,
+ nlm_powerpc_mangle_relocs,
+ nlm_powerpc_read_import,
+ nlm_powerpc_write_import,
+#ifndef OLDFORMAT
+ nlm_powerpc_set_public_section,
+ nlm_powerpc_get_public_offset,
+#else
+ 0, /* set_public_section */
+ 0, /* get_public_offset */
+#endif
+ nlm_swap_fixed_header_in,
+ nlm_swap_fixed_header_out,
+ nlm_powerpc_write_external,
+ 0, /* write_export */
+};
+
+#define TARGET_BIG_NAME "nlm32-powerpc"
+#define TARGET_BIG_SYM nlmNAME(powerpc_vec)
+#define TARGET_BACKEND_DATA &nlm32_powerpc_backend
+
+#include "nlm-target.h"
diff --git a/bfd/nlm32-sparc.c b/bfd/nlm32-sparc.c
new file mode 100644
index 00000000000..5963adbc70b
--- /dev/null
+++ b/bfd/nlm32-sparc.c
@@ -0,0 +1,440 @@
+/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define ARCH_SIZE 32
+
+#include "nlm/sparc32-ext.h"
+#define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
+
+#include "libnlm.h"
+
+static boolean nlm_sparc_read_reloc
+ PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
+static boolean nlm_sparc_write_reloc
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_sparc_mangle_relocs
+ PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
+static boolean nlm_sparc_read_import
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static boolean nlm_sparc_write_import
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_sparc_write_external
+ PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
+
+enum reloc_type
+ {
+ R_SPARC_NONE = 0,
+ R_SPARC_8, R_SPARC_16, R_SPARC_32,
+ R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
+ R_SPARC_WDISP30, R_SPARC_WDISP22,
+ R_SPARC_HI22, R_SPARC_22,
+ R_SPARC_13, R_SPARC_LO10,
+ R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
+ R_SPARC_PC10, R_SPARC_PC22,
+ R_SPARC_WPLT30,
+ R_SPARC_COPY,
+ R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
+ R_SPARC_RELATIVE,
+ R_SPARC_UA32,
+ R_SPARC_max
+ };
+
+#if 0
+static CONST char *CONST reloc_type_names[] =
+{
+ "R_SPARC_NONE",
+ "R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
+ "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
+ "R_SPARC_WDISP30", "R_SPARC_WDISP22",
+ "R_SPARC_HI22", "R_SPARC_22",
+ "R_SPARC_13", "R_SPARC_LO10",
+ "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
+ "R_SPARC_PC10", "R_SPARC_PC22",
+ "R_SPARC_WPLT30",
+ "R_SPARC_COPY",
+ "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
+ "R_SPARC_RELATIVE",
+ "R_SPARC_UA32",
+};
+#endif
+
+static reloc_howto_type nlm32_sparc_howto_table[] =
+{
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, 0,"R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32", false,0,0xffffffff,true),
+ HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP32", false,0,0x00ffffff,true),
+ HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, 0,"R_SPARC_HI22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, 0,"R_SPARC_LO10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_WPLT30", false,0,0x00000000,true),
+ HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_COPY", false,0,0x00000000,true),
+ HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_RELATIVE",false,0,0x00000000,true),
+ HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_UA32", false,0,0x00000000,true),
+};
+
+/* Read a NetWare sparc reloc. */
+
+struct nlm32_sparc_reloc_ext {
+ unsigned char offset[4];
+ unsigned char addend[4];
+ unsigned char type[1];
+ unsigned char pad1[3];
+};
+
+static boolean
+nlm_sparc_read_reloc (abfd, sym, secp, rel)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+ asection **secp;
+ arelent *rel;
+{
+ bfd_vma val, addend;
+ unsigned int index;
+ unsigned int type;
+ struct nlm32_sparc_reloc_ext tmp_reloc;
+ asection *code_sec, *data_sec;
+
+ if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12)
+ return false;
+
+ code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+
+ *secp = code_sec;
+
+ val = bfd_get_32 (abfd, tmp_reloc.offset);
+ addend = bfd_get_32 (abfd, tmp_reloc.addend);
+ type = bfd_get_8 (abfd, tmp_reloc.type);
+
+ rel->address = val;
+ rel->addend = addend;
+ rel->howto = NULL;
+
+ for (index = 0;
+ index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
+ index++)
+ if (nlm32_sparc_howto_table[index].type == type) {
+ rel->howto = &nlm32_sparc_howto_table[index];
+ break;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
+ __FUNCTION__, rel->address, rel->addend, type, rel->howto);
+#endif
+ return true;
+
+}
+
+/* Write a NetWare sparc reloc. */
+
+static boolean
+nlm_sparc_write_reloc (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ bfd_vma val;
+ struct nlm32_sparc_reloc_ext tmp_reloc;
+ unsigned int index;
+ int type = -1;
+ reloc_howto_type *tmp;
+
+
+ for (index = 0;
+ index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
+ index++) {
+ tmp = &nlm32_sparc_howto_table[index];
+
+ if (tmp->rightshift == rel->howto->rightshift
+ && tmp->size == rel->howto->size
+ && tmp->bitsize == rel->howto->bitsize
+ && tmp->pc_relative == rel->howto->pc_relative
+ && tmp->bitpos == rel->howto->bitpos
+ && tmp->src_mask == rel->howto->src_mask
+ && tmp->dst_mask == rel->howto->dst_mask) {
+ type = tmp->type;
+ break;
+ }
+ }
+ if (type == -1)
+ abort();
+
+ /*
+ * Netware wants a list of relocs for each address.
+ * Format is:
+ * long offset
+ * long addend
+ * char type
+ * That should be it.
+ */
+
+ /* The value we write out is the offset into the appropriate
+ segment. This offset is the section vma, adjusted by the vma of
+ the lowest section in that segment, plus the address of the
+ relocation. */
+#if 0
+ val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address;
+#else
+ val = bfd_get_section_vma (abfd, sec) + rel->address;
+#endif
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
+ __FUNCTION__, val, rel->addend, rel->howto->type);
+#endif
+ bfd_put_32 (abfd, val, tmp_reloc.offset);
+ bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
+ bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type);
+
+ if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
+ return false;
+
+ return true;
+}
+
+/* Mangle relocs for SPARC NetWare. We can just use the standard
+ SPARC relocs. */
+
+static boolean
+nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ bfd_vma offset;
+ bfd_size_type count;
+{
+ return true;
+}
+
+/* Read a NetWare sparc import record */
+static boolean
+nlm_sparc_read_import (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ struct nlm_relent *nlm_relocs; /* relocation records for symbol */
+ bfd_size_type rcount; /* number of relocs */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
+ unsigned char symlength; /* length of symbol name */
+ char *name;
+
+ /*
+ * First, read in the number of relocation
+ * entries for this symbol
+ */
+ if (bfd_read ((PTR) temp, 4, 1, abfd) != 4)
+ return false;
+
+ rcount = bfd_get_32 (abfd, temp);
+
+ /*
+ * Next, read in the length of the symbol
+ */
+
+ if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ return false;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, symlength + 1);
+ if (name == NULL)
+ return false;
+
+ /*
+ * Then read in the symbol
+ */
+
+ if (bfd_read (name, symlength, 1, abfd) != symlength)
+ return false;
+ name[symlength] = '\0';
+ sym -> symbol.name = name;
+ sym -> symbol.flags = 0;
+ sym -> symbol.value = 0;
+ sym -> symbol.section = bfd_und_section_ptr;
+
+ /*
+ * Next, start reading in the relocs.
+ */
+
+ nlm_relocs = ((struct nlm_relent *)
+ bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+ if (!nlm_relocs)
+ return false;
+ sym -> relocs = nlm_relocs;
+ sym -> rcnt = 0;
+ while (sym -> rcnt < rcount)
+ {
+ asection *section;
+
+ if (nlm_sparc_read_reloc (abfd, sym, &section,
+ &nlm_relocs -> reloc)
+ == false)
+ return false;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return true;
+}
+
+static boolean
+nlm_sparc_write_import (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ char temp[4];
+ asection *code, *data, *bss, *symsec;
+ bfd_vma base;
+
+ code = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
+ symsec = (*rel->sym_ptr_ptr)->section;
+
+ if (symsec == code) {
+ base = 0;
+ } else if (symsec == data) {
+ base = bfd_section_size (abfd, code);
+ } else if (symsec == bss) {
+ base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data);
+ } else
+ base = 0;
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: <%x, 1>\n\t",
+ __FUNCTION__, base + (*rel->sym_ptr_ptr)->value);
+#endif
+ bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
+ if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
+ return false;
+ bfd_put_32 (abfd, 1, temp);
+ if (bfd_write ((PTR)temp, 4, 1, abfd) != 4)
+ return false;
+ if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
+ return false;
+ return true;
+}
+
+/* Write out an external reference. */
+
+static boolean
+nlm_sparc_write_external (abfd, count, sym, relocs)
+ bfd *abfd;
+ bfd_size_type count;
+ asymbol *sym;
+ struct reloc_and_sec *relocs;
+{
+ unsigned int i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
+ return false;
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ return false;
+
+ for (i = 0; i < count; i++)
+ {
+ if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
+ relocs[i].rel) == false)
+ return false;
+ }
+
+ return true;
+}
+
+static boolean
+nlm_sparc_write_export (abfd, sym, value)
+ bfd *abfd;
+ asymbol *sym;
+ bfd_vma value;
+{
+ bfd_byte len;
+ bfd_byte temp[4];
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: <%x, %d, %s>\n",
+ __FUNCTION__, value, strlen (sym->name), sym->name);
+#endif
+ bfd_put_32 (abfd, value, temp);
+ len = strlen (sym->name);
+
+ if (bfd_write (temp, 4, 1, abfd) != 4
+ || bfd_write (&len, 1, 1, abfd) != 1
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ return false;
+
+ return true;
+}
+
+#undef nlm_swap_fixed_header_in
+#undef nlm_swap_fixed_header_out
+
+#include "nlmswap.h"
+
+static const struct nlm_backend_data nlm32_sparc_backend =
+{
+ "NetWare SPARC Module \032",
+ sizeof (Nlm32_sparc_External_Fixed_Header),
+ 0, /* optional_prefix_size */
+ bfd_arch_sparc,
+ 0,
+ false,
+ 0, /* backend_object_p */
+ 0, /* write_prefix_func */
+ nlm_sparc_read_reloc,
+ nlm_sparc_mangle_relocs,
+ nlm_sparc_read_import,
+ nlm_sparc_write_import,
+ 0, /* set_public_section */
+ 0, /* get_public_offset */
+ nlm_swap_fixed_header_in,
+ nlm_swap_fixed_header_out,
+ nlm_sparc_write_external,
+ nlm_sparc_write_export
+};
+
+#define TARGET_BIG_NAME "nlm32-sparc"
+#define TARGET_BIG_SYM nlmNAME(sparc_vec)
+#define TARGET_BACKEND_DATA &nlm32_sparc_backend
+
+#include "nlm-target.h"
diff --git a/bfd/nlm32.c b/bfd/nlm32.c
new file mode 100644
index 00000000000..4730e4fd349
--- /dev/null
+++ b/bfd/nlm32.c
@@ -0,0 +1,21 @@
+/* NLM (NetWare Loadable Module) 32-bit executable support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 32
+#include "nlmcode.h"
diff --git a/bfd/nlm64.c b/bfd/nlm64.c
new file mode 100644
index 00000000000..5dcd96a2b3c
--- /dev/null
+++ b/bfd/nlm64.c
@@ -0,0 +1,21 @@
+/* NLM (NetWare Loadable Module) 64-bit executable support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define ARCH_SIZE 64
+#include "nlmcode.h"
diff --git a/bfd/nlmcode.h b/bfd/nlmcode.h
new file mode 100644
index 00000000000..63ac0c300f7
--- /dev/null
+++ b/bfd/nlmcode.h
@@ -0,0 +1,2056 @@
+/* NLM (NetWare Loadable Module) executable support for BFD.
+ Copyright (C) 1993, 94, 95, 1998 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support, using ELF support as the
+ template.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libnlm.h"
+
+/* The functions in this file do not use the names they appear to use.
+ This file is actually compiled multiple times, once for each size
+ of NLM target we are using. At each size we use a different name,
+ constructed by the macro nlmNAME. For example, the function which
+ is named nlm_symbol_type below is actually named nlm32_symbol_type
+ in the final executable. */
+
+#define Nlm_External_Fixed_Header NlmNAME(External_Fixed_Header)
+#define Nlm_External_Version_Header NlmNAME(External_Version_Header)
+#define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header)
+#define Nlm_External_Extended_Header NlmNAME(External_Extended_Header)
+#define Nlm_External_Custom_Header NlmNAME(External_Custom_Header)
+#define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header)
+
+#define nlm_symbol_type nlmNAME(symbol_type)
+#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound)
+#define nlm_get_symtab nlmNAME(get_symtab)
+#define nlm_make_empty_symbol nlmNAME(make_empty_symbol)
+#define nlm_print_symbol nlmNAME(print_symbol)
+#define nlm_get_symbol_info nlmNAME(get_symbol_info)
+#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound)
+#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc)
+#define nlm_object_p nlmNAME(object_p)
+#define nlm_set_section_contents nlmNAME(set_section_contents)
+#define nlm_write_object_contents nlmNAME(write_object_contents)
+
+#define nlm_swap_fixed_header_in(abfd,src,dst) \
+ (nlm_swap_fixed_header_in_func(abfd))(abfd,src,dst)
+#define nlm_swap_fixed_header_out(abfd,src,dst) \
+ (nlm_swap_fixed_header_out_func(abfd))(abfd,src,dst)
+
+/* Forward declarations of static functions */
+
+static boolean add_bfd_section
+ PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
+static boolean nlm_swap_variable_header_in
+ PARAMS ((bfd *));
+static boolean nlm_swap_variable_header_out
+ PARAMS ((bfd *));
+static boolean find_nonzero
+ PARAMS ((PTR, size_t));
+static boolean nlm_swap_auxiliary_headers_in
+ PARAMS ((bfd *));
+static boolean nlm_swap_auxiliary_headers_out
+ PARAMS ((bfd *));
+static boolean nlm_slurp_symbol_table
+ PARAMS ((bfd *));
+static boolean nlm_slurp_reloc_fixups
+ PARAMS ((bfd *));
+static boolean nlm_compute_section_file_positions
+ PARAMS ((bfd *));
+static int nlm_external_reloc_compare
+ PARAMS ((const void *, const void *));
+
+/* Should perhaps use put_offset, put_word, etc. For now, the two versions
+ can be handled by explicitly specifying 32 bits or "the long type". */
+#if ARCH_SIZE == 64
+#define put_word bfd_h_put_64
+#define get_word bfd_h_get_64
+#endif
+#if ARCH_SIZE == 32
+#define put_word bfd_h_put_32
+#define get_word bfd_h_get_32
+#endif
+
+const bfd_target *
+nlm_object_p (abfd)
+ bfd *abfd;
+{
+ struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
+ boolean (*backend_object_p) PARAMS ((bfd *));
+ PTR x_fxdhdr = NULL;
+ Nlm_Internal_Fixed_Header *i_fxdhdrp;
+ struct nlm_obj_tdata *new_tdata = NULL;
+ const char *signature;
+ enum bfd_architecture arch;
+
+ /* Some NLM formats have a prefix before the standard NLM fixed
+ header. */
+ backend_object_p = nlm_backend_object_p_func (abfd);
+ if (backend_object_p)
+ {
+ if (!(*backend_object_p) (abfd))
+ goto got_wrong_format_error;
+ }
+
+ /* Read in the fixed length portion of the NLM header in external format. */
+
+ x_fxdhdr = (PTR) bfd_malloc ((size_t) nlm_fixed_header_size (abfd));
+ if (x_fxdhdr == NULL)
+ goto got_no_match;
+
+ if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=
+ nlm_fixed_header_size (abfd))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ goto got_wrong_format_error;
+ else
+ goto got_no_match;
+ }
+
+ /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
+ the tdata pointer in the bfd. */
+
+ new_tdata = ((struct nlm_obj_tdata *)
+ bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)));
+ if (new_tdata == NULL)
+ goto got_no_match;
+
+ nlm_tdata (abfd) = new_tdata;
+
+ i_fxdhdrp = nlm_fixed_header (abfd);
+ nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
+ free (x_fxdhdr);
+ x_fxdhdr = NULL;
+
+ /* Check to see if we have an NLM file for this backend by matching
+ the NLM signature. */
+
+ signature = nlm_signature (abfd);
+ if (signature != NULL
+ && *signature != '\0'
+ && strncmp ((char *) i_fxdhdrp->signature, signature,
+ NLM_SIGNATURE_SIZE) != 0)
+ goto got_wrong_format_error;
+
+ /* There's no supported way to discover the endianess of an NLM, so test for
+ a sane version number after doing byte swapping appropriate for this
+ XVEC. (Hack alert!) */
+
+ if (i_fxdhdrp->version > 0xFFFF)
+ goto got_wrong_format_error;
+
+ /* There's no supported way to check for 32 bit versus 64 bit addresses,
+ so ignore this distinction for now. (FIXME) */
+
+ /* Swap in the rest of the required header. */
+ if (!nlm_swap_variable_header_in (abfd))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ goto got_wrong_format_error;
+ else
+ goto got_no_match;
+ }
+
+ /* Add the sections supplied by all NLM's, and then read in the
+ auxiliary headers. Reading the auxiliary headers may create
+ additional sections described in the cygnus_ext header.
+ From this point on we assume that we have an NLM, and do not
+ treat errors as indicating the wrong format. */
+
+ if (!add_bfd_section (abfd, NLM_CODE_NAME,
+ i_fxdhdrp->codeImageOffset,
+ i_fxdhdrp->codeImageSize,
+ (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_RELOC))
+ || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME,
+ i_fxdhdrp->dataImageOffset,
+ i_fxdhdrp->dataImageSize,
+ (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_RELOC))
+ || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
+ (file_ptr) 0,
+ i_fxdhdrp->uninitializedDataSize,
+ SEC_ALLOC))
+ goto got_no_match;
+
+ if (!nlm_swap_auxiliary_headers_in (abfd))
+ goto got_no_match;
+
+ if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
+ || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
+ abfd->flags |= HAS_RELOC;
+ if (nlm_fixed_header (abfd)->numberOfPublics != 0
+ || nlm_fixed_header (abfd)->numberOfDebugRecords != 0
+ || nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
+ abfd->flags |= HAS_SYMS;
+
+ arch = nlm_architecture (abfd);
+ if (arch != bfd_arch_unknown)
+ bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
+
+ abfd->flags |= EXEC_P;
+ bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset;
+
+ return (abfd->xvec);
+
+got_wrong_format_error:
+ bfd_set_error (bfd_error_wrong_format);
+got_no_match:
+ nlm_tdata (abfd) = preserved_tdata;
+ if (new_tdata != NULL)
+ bfd_release (abfd, new_tdata);
+ if (x_fxdhdr != NULL)
+ free (x_fxdhdr);
+ return (NULL);
+}
+
+/* Add a section to the bfd. */
+
+static boolean
+add_bfd_section (abfd, name, offset, size, flags)
+ bfd *abfd;
+ char *name;
+ file_ptr offset;
+ bfd_size_type size;
+ flagword flags;
+{
+ asection *newsect;
+
+ newsect = bfd_make_section (abfd, name);
+ if (newsect == NULL)
+ {
+ return (false);
+ }
+ newsect->vma = 0; /* NLM's are relocatable. */
+ newsect->_raw_size = size;
+ newsect->filepos = offset;
+ newsect->flags = flags;
+ newsect->alignment_power = bfd_log2 (0); /* FIXME */
+ return (true);
+}
+
+/* Read and swap in the variable length header. All the fields must
+ exist in the NLM, and must exist in the order they are read here. */
+
+static boolean
+nlm_swap_variable_header_in (abfd)
+ bfd *abfd;
+{
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+
+ /* Read the description length and text members. */
+
+ if (bfd_read ((PTR) & nlm_variable_header (abfd)->descriptionLength,
+ sizeof (nlm_variable_header (abfd)->descriptionLength),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->descriptionLength))
+ return (false);
+ if (bfd_read ((PTR) nlm_variable_header (abfd)->descriptionText,
+ nlm_variable_header (abfd)->descriptionLength + 1,
+ 1, abfd) !=
+ (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1)
+ return (false);
+
+ /* Read and convert the stackSize field. */
+
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return (false);
+ nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
+
+ /* Read and convert the reserved field. */
+
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return (false);
+ nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
+
+ /* Read the oldThreadName field. This field is a fixed length string. */
+
+ if (bfd_read ((PTR) nlm_variable_header (abfd)->oldThreadName,
+ sizeof (nlm_variable_header (abfd)->oldThreadName),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->oldThreadName))
+ return (false);
+
+ /* Read the screen name length and text members. */
+
+ if (bfd_read ((PTR) & nlm_variable_header (abfd)->screenNameLength,
+ sizeof (nlm_variable_header (abfd)->screenNameLength),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->screenNameLength))
+ return (false);
+ if (bfd_read ((PTR) nlm_variable_header (abfd)->screenName,
+ nlm_variable_header (abfd)->screenNameLength + 1,
+ 1, abfd) !=
+ (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1)
+ return (false);
+
+ /* Read the thread name length and text members. */
+
+ if (bfd_read ((PTR) & nlm_variable_header (abfd)->threadNameLength,
+ sizeof (nlm_variable_header (abfd)->threadNameLength),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->threadNameLength))
+ return (false);
+ if (bfd_read ((PTR) nlm_variable_header (abfd)->threadName,
+ nlm_variable_header (abfd)->threadNameLength + 1,
+ 1, abfd) !=
+ (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1)
+ return (false);
+ return (true);
+}
+
+/* Swap and write out the variable length header. All the fields must
+ exist in the NLM, and must exist in this order. */
+
+static boolean
+nlm_swap_variable_header_out (abfd)
+ bfd *abfd;
+{
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+
+ /* Write the description length and text members. */
+
+ if (bfd_write ((PTR) & nlm_variable_header (abfd)->descriptionLength,
+ sizeof (nlm_variable_header (abfd)->descriptionLength),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->descriptionLength))
+ return (false);
+ if (bfd_write ((PTR) nlm_variable_header (abfd)->descriptionText,
+ nlm_variable_header (abfd)->descriptionLength + 1,
+ 1, abfd) !=
+ (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1)
+ return (false);
+
+ /* Convert and write the stackSize field. */
+
+ put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize,
+ (bfd_byte *) temp);
+ if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return (false);
+
+ /* Convert and write the reserved field. */
+
+ put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved,
+ (bfd_byte *) temp);
+ if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return (false);
+
+ /* Write the oldThreadName field. This field is a fixed length string. */
+
+ if (bfd_write ((PTR) nlm_variable_header (abfd)->oldThreadName,
+ sizeof (nlm_variable_header (abfd)->oldThreadName),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->oldThreadName))
+ return (false);
+
+ /* Write the screen name length and text members. */
+
+ if (bfd_write ((PTR) & nlm_variable_header (abfd)->screenNameLength,
+ sizeof (nlm_variable_header (abfd)->screenNameLength),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->screenNameLength))
+ return (false);
+ if (bfd_write ((PTR) nlm_variable_header (abfd)->screenName,
+ nlm_variable_header (abfd)->screenNameLength + 1,
+ 1, abfd) !=
+ (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1)
+ return (false);
+
+ /* Write the thread name length and text members. */
+
+ if (bfd_write ((PTR) & nlm_variable_header (abfd)->threadNameLength,
+ sizeof (nlm_variable_header (abfd)->threadNameLength),
+ 1, abfd) !=
+ sizeof (nlm_variable_header (abfd)->threadNameLength))
+ return (false);
+ if (bfd_write ((PTR) nlm_variable_header (abfd)->threadName,
+ nlm_variable_header (abfd)->threadNameLength + 1,
+ 1, abfd) !=
+ (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1)
+ return (false);
+ return (true);
+}
+
+/* Read and swap in the contents of all the auxiliary headers. Because of
+ the braindead design, we have to do strcmps on strings of indeterminate
+ length to figure out what each auxiliary header is. Even worse, we have
+ no way of knowing how many auxiliary headers there are or where the end
+ of the auxiliary headers are, except by finding something that doesn't
+ look like a known auxiliary header. This means that the first new type
+ of auxiliary header added will break all existing tools that don't
+ recognize it. */
+
+static boolean
+nlm_swap_auxiliary_headers_in (abfd)
+ bfd *abfd;
+{
+ char tempstr[16];
+ long position;
+
+ for (;;)
+ {
+ position = bfd_tell (abfd);
+ if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) !=
+ sizeof (tempstr))
+ return (false);
+ if (bfd_seek (abfd, position, SEEK_SET) == -1)
+ return (false);
+ if (strncmp (tempstr, "VeRsIoN#", 8) == 0)
+ {
+ Nlm_External_Version_Header thdr;
+ if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
+ return (false);
+ memcpy (nlm_version_header (abfd)->stamp, thdr.stamp,
+ sizeof (thdr.stamp));
+ nlm_version_header (abfd)->majorVersion =
+ get_word (abfd, (bfd_byte *) thdr.majorVersion);
+ nlm_version_header (abfd)->minorVersion =
+ get_word (abfd, (bfd_byte *) thdr.minorVersion);
+ nlm_version_header (abfd)->revision =
+ get_word (abfd, (bfd_byte *) thdr.revision);
+ nlm_version_header (abfd)->year =
+ get_word (abfd, (bfd_byte *) thdr.year);
+ nlm_version_header (abfd)->month =
+ get_word (abfd, (bfd_byte *) thdr.month);
+ nlm_version_header (abfd)->day =
+ get_word (abfd, (bfd_byte *) thdr.day);
+ }
+ else if (strncmp (tempstr, "MeSsAgEs", 8) == 0)
+ {
+ Nlm_External_Extended_Header thdr;
+ if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
+ return (false);
+ memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp,
+ sizeof (thdr.stamp));
+ nlm_extended_header (abfd)->languageID =
+ get_word (abfd, (bfd_byte *) thdr.languageID);
+ nlm_extended_header (abfd)->messageFileOffset =
+ get_word (abfd, (bfd_byte *) thdr.messageFileOffset);
+ nlm_extended_header (abfd)->messageFileLength =
+ get_word (abfd, (bfd_byte *) thdr.messageFileLength);
+ nlm_extended_header (abfd)->messageCount =
+ get_word (abfd, (bfd_byte *) thdr.messageCount);
+ nlm_extended_header (abfd)->helpFileOffset =
+ get_word (abfd, (bfd_byte *) thdr.helpFileOffset);
+ nlm_extended_header (abfd)->helpFileLength =
+ get_word (abfd, (bfd_byte *) thdr.helpFileLength);
+ nlm_extended_header (abfd)->RPCDataOffset =
+ get_word (abfd, (bfd_byte *) thdr.RPCDataOffset);
+ nlm_extended_header (abfd)->RPCDataLength =
+ get_word (abfd, (bfd_byte *) thdr.RPCDataLength);
+ nlm_extended_header (abfd)->sharedCodeOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset);
+ nlm_extended_header (abfd)->sharedCodeLength =
+ get_word (abfd, (bfd_byte *) thdr.sharedCodeLength);
+ nlm_extended_header (abfd)->sharedDataOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedDataOffset);
+ nlm_extended_header (abfd)->sharedDataLength =
+ get_word (abfd, (bfd_byte *) thdr.sharedDataLength);
+ nlm_extended_header (abfd)->sharedRelocationFixupOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset);
+ nlm_extended_header (abfd)->sharedRelocationFixupCount =
+ get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount);
+ nlm_extended_header (abfd)->sharedExternalReferenceOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset);
+ nlm_extended_header (abfd)->sharedExternalReferenceCount =
+ get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount);
+ nlm_extended_header (abfd)->sharedPublicsOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
+ nlm_extended_header (abfd)->sharedPublicsCount =
+ get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
+ nlm_extended_header (abfd)->sharedDebugRecordOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
+ nlm_extended_header (abfd)->sharedDebugRecordCount =
+ get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
+ nlm_extended_header (abfd)->SharedInitializationOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
+ nlm_extended_header (abfd)->SharedExitProcedureOffset =
+ get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset);
+ nlm_extended_header (abfd)->productID =
+ get_word (abfd, (bfd_byte *) thdr.productID);
+ nlm_extended_header (abfd)->reserved0 =
+ get_word (abfd, (bfd_byte *) thdr.reserved0);
+ nlm_extended_header (abfd)->reserved1 =
+ get_word (abfd, (bfd_byte *) thdr.reserved1);
+ nlm_extended_header (abfd)->reserved2 =
+ get_word (abfd, (bfd_byte *) thdr.reserved2);
+ nlm_extended_header (abfd)->reserved3 =
+ get_word (abfd, (bfd_byte *) thdr.reserved3);
+ nlm_extended_header (abfd)->reserved4 =
+ get_word (abfd, (bfd_byte *) thdr.reserved4);
+ nlm_extended_header (abfd)->reserved5 =
+ get_word (abfd, (bfd_byte *) thdr.reserved5);
+ }
+ else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
+ {
+ if (bfd_read ((PTR) nlm_copyright_header (abfd)->stamp,
+ sizeof (nlm_copyright_header (abfd)->stamp),
+ 1, abfd)
+ != sizeof (nlm_copyright_header (abfd)->stamp))
+ return (false);
+ if (bfd_read ((PTR) & (nlm_copyright_header (abfd)
+ ->copyrightMessageLength),
+ 1, 1, abfd) != 1)
+ return (false);
+ /* The copyright message is a variable length string. */
+ if (bfd_read ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1,
+ 1, abfd) !=
+ ((bfd_size_type)
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1))
+ return (false);
+ }
+ else if (strncmp (tempstr, "CuStHeAd", 8) == 0)
+ {
+ Nlm_External_Custom_Header thdr;
+ bfd_size_type hdrLength;
+ file_ptr dataOffset;
+ bfd_size_type dataLength;
+ char dataStamp[8];
+ PTR hdr;
+
+ /* Read the stamp ("CuStHeAd"). */
+ if (bfd_read ((PTR) thdr.stamp, 1, sizeof (thdr.stamp), abfd)
+ != sizeof (thdr.stamp))
+ return false;
+ /* Read the length of this custom header. */
+ if (bfd_read ((PTR) thdr.length, 1, sizeof (thdr.length), abfd)
+ != sizeof (thdr.length))
+ return false;
+ hdrLength = get_word (abfd, (bfd_byte *) thdr.length);
+ /* Read further fields if we have them. */
+ if (hdrLength < NLM_TARGET_LONG_SIZE)
+ dataOffset = 0;
+ else
+ {
+ if (bfd_read ((PTR) thdr.dataOffset, 1,
+ sizeof (thdr.dataOffset), abfd)
+ != sizeof (thdr.dataOffset))
+ return false;
+ dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
+ }
+ if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
+ dataLength = 0;
+ else
+ {
+ if (bfd_read ((PTR) thdr.dataLength, 1,
+ sizeof (thdr.dataLength), abfd)
+ != sizeof (thdr.dataLength))
+ return false;
+ dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
+ }
+ if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
+ memset (dataStamp, 0, sizeof (dataStamp));
+ else
+ {
+ if (bfd_read ((PTR) dataStamp, 1, sizeof (dataStamp), abfd)
+ != sizeof (dataStamp))
+ return false;
+ }
+
+ /* Read the rest of the header, if any. */
+ if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8)
+ {
+ hdr = NULL;
+ hdrLength = 0;
+ }
+ else
+ {
+ hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8;
+ hdr = bfd_alloc (abfd, hdrLength);
+ if (hdr == NULL)
+ return false;
+ if (bfd_read (hdr, 1, hdrLength, abfd) != hdrLength)
+ return false;
+ }
+
+ /* If we have found a Cygnus header, process it. Otherwise,
+ just save the associated data without trying to interpret
+ it. */
+ if (strncmp (dataStamp, "CyGnUsEx", 8) == 0)
+ {
+ file_ptr pos;
+ bfd_byte *contents;
+ bfd_byte *p, *pend;
+
+ BFD_ASSERT (hdrLength == 0 && hdr == NULL);
+
+ pos = bfd_tell (abfd);
+ if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0)
+ return false;
+ contents = (bfd_byte *) bfd_alloc (abfd, dataLength);
+ if (contents == NULL)
+ return false;
+ if (bfd_read (contents, 1, dataLength, abfd) != dataLength)
+ return false;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return false;
+
+ memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8);
+ nlm_cygnus_ext_header (abfd)->offset = dataOffset;
+ nlm_cygnus_ext_header (abfd)->length = dataLength;
+
+ /* This data this header points to provides a list of
+ the sections which were in the original object file
+ which was converted to become an NLM. We locate
+ those sections and add them to the BFD. Note that
+ this is likely to create a second .text, .data and
+ .bss section; retrieving the sections by name will
+ get the actual NLM sections, which is what we want to
+ happen. The sections from the original file, which
+ may be subsets of the NLM section, can only be found
+ using bfd_map_over_sections. */
+ p = contents;
+ pend = p + dataLength;
+ while (p < pend)
+ {
+ char *name;
+ size_t l;
+ file_ptr filepos;
+ bfd_size_type size;
+ asection *newsec;
+
+ /* The format of this information is
+ null terminated section name
+ zeroes to adjust to 4 byte boundary
+ 4 byte section data file pointer
+ 4 byte section size
+ */
+
+ name = (char *) p;
+ l = strlen (name) + 1;
+ l = (l + 3) &~ 3;
+ p += l;
+ filepos = bfd_h_get_32 (abfd, p);
+ p += 4;
+ size = bfd_h_get_32 (abfd, p);
+ p += 4;
+
+ newsec = bfd_make_section_anyway (abfd, name);
+ if (newsec == (asection *) NULL)
+ return false;
+ newsec->_raw_size = size;
+ if (filepos != 0)
+ {
+ newsec->filepos = filepos;
+ newsec->flags |= SEC_HAS_CONTENTS;
+ }
+ }
+ }
+ else
+ {
+ memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp,
+ sizeof (thdr.stamp));
+ nlm_custom_header (abfd)->hdrLength = hdrLength;
+ nlm_custom_header (abfd)->dataOffset = dataOffset;
+ nlm_custom_header (abfd)->dataLength = dataLength;
+ memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp,
+ sizeof (dataStamp));
+ nlm_custom_header (abfd)->hdr = hdr;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ return (true);
+}
+
+/* Return whether there is a non-zero byte in a memory block. */
+
+static boolean
+find_nonzero (buf, size)
+ PTR buf;
+ size_t size;
+{
+ char *p = (char *) buf;
+
+ while (size-- != 0)
+ if (*p++ != 0)
+ return true;
+ return false;
+}
+
+/* Swap out the contents of the auxiliary headers. We create those
+ auxiliary headers which have been set non-zero. We do not require
+ the caller to set up the stamp fields. */
+
+static boolean
+nlm_swap_auxiliary_headers_out (abfd)
+ bfd *abfd;
+{
+ /* Write out the version header if there is one. */
+ if (find_nonzero ((PTR) nlm_version_header (abfd),
+ sizeof (Nlm_Internal_Version_Header)))
+ {
+ Nlm_External_Version_Header thdr;
+
+ memcpy (thdr.stamp, "VeRsIoN#", 8);
+ put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion,
+ (bfd_byte *) thdr.majorVersion);
+ put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion,
+ (bfd_byte *) thdr.minorVersion);
+ put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision,
+ (bfd_byte *) thdr.revision);
+ put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year,
+ (bfd_byte *) thdr.year);
+ put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month,
+ (bfd_byte *) thdr.month);
+ put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day,
+ (bfd_byte *) thdr.day);
+ if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
+ return false;
+ }
+
+ /* Write out the extended header if there is one. */
+ if (find_nonzero ((PTR) nlm_extended_header (abfd),
+ sizeof (Nlm_Internal_Extended_Header)))
+ {
+ Nlm_External_Extended_Header thdr;
+
+ memcpy (thdr.stamp, "MeSsAgEs", 8);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->languageID,
+ (bfd_byte *) thdr.languageID);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->messageFileOffset,
+ (bfd_byte *) thdr.messageFileOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->messageFileLength,
+ (bfd_byte *) thdr.messageFileLength);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->messageCount,
+ (bfd_byte *) thdr.messageCount);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->helpFileOffset,
+ (bfd_byte *) thdr.helpFileOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->helpFileLength,
+ (bfd_byte *) thdr.helpFileLength);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset,
+ (bfd_byte *) thdr.RPCDataOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->RPCDataLength,
+ (bfd_byte *) thdr.RPCDataLength);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset,
+ (bfd_byte *) thdr.sharedCodeOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength,
+ (bfd_byte *) thdr.sharedCodeLength);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset,
+ (bfd_byte *) thdr.sharedDataOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedDataLength,
+ (bfd_byte *) thdr.sharedDataLength);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset,
+ (bfd_byte *) thdr.sharedRelocationFixupOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount,
+ (bfd_byte *) thdr.sharedRelocationFixupCount);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset,
+ (bfd_byte *) thdr.sharedExternalReferenceOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount,
+ (bfd_byte *) thdr.sharedExternalReferenceCount);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset,
+ (bfd_byte *) thdr.sharedPublicsOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount,
+ (bfd_byte *) thdr.sharedPublicsCount);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset,
+ (bfd_byte *) thdr.sharedDebugRecordOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount,
+ (bfd_byte *) thdr.sharedDebugRecordCount);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset,
+ (bfd_byte *) thdr.sharedInitializationOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset,
+ (bfd_byte *) thdr.SharedExitProcedureOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->productID,
+ (bfd_byte *) thdr.productID);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->reserved0,
+ (bfd_byte *) thdr.reserved0);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->reserved1,
+ (bfd_byte *) thdr.reserved1);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->reserved2,
+ (bfd_byte *) thdr.reserved2);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->reserved3,
+ (bfd_byte *) thdr.reserved3);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->reserved4,
+ (bfd_byte *) thdr.reserved4);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd)->reserved5,
+ (bfd_byte *) thdr.reserved5);
+ if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
+ return false;
+ }
+
+
+ /* Write out the copyright header if there is one. */
+ if (find_nonzero ((PTR) nlm_copyright_header (abfd),
+ sizeof (Nlm_Internal_Copyright_Header)))
+ {
+ Nlm_External_Copyright_Header thdr;
+
+ memcpy (thdr.stamp, "CoPyRiGhT=", 10);
+ if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd)
+ != sizeof (thdr.stamp))
+ return false;
+ thdr.copyrightMessageLength[0] =
+ nlm_copyright_header (abfd)->copyrightMessageLength;
+ if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1)
+ return false;
+ /* The copyright message is a variable length string. */
+ if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage,
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1,
+ 1, abfd) !=
+ ((bfd_size_type)
+ nlm_copyright_header (abfd)->copyrightMessageLength + 1))
+ return false;
+ }
+
+ /* Write out the custom header if there is one. */
+ if (find_nonzero ((PTR) nlm_custom_header (abfd),
+ sizeof (Nlm_Internal_Custom_Header)))
+ {
+ Nlm_External_Custom_Header thdr;
+ boolean ds;
+ bfd_size_type hdrLength;
+
+ ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp,
+ sizeof (nlm_custom_header (abfd)->dataStamp));
+ memcpy (thdr.stamp, "CuStHeAd", 8);
+ hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0)
+ + nlm_custom_header (abfd)->hdrLength);
+ put_word (abfd, hdrLength, thdr.length);
+ put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset,
+ thdr.dataOffset);
+ put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength,
+ thdr.dataLength);
+ if (! ds)
+ {
+ BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0);
+ if (bfd_write ((PTR) &thdr, 1,
+ sizeof (thdr) - sizeof (thdr.dataStamp), abfd)
+ != sizeof (thdr) - sizeof (thdr.dataStamp))
+ return false;
+ }
+ else
+ {
+ memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
+ sizeof (thdr.dataStamp));
+ if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
+ return false;
+ if (bfd_write (nlm_custom_header (abfd)->hdr, 1,
+ nlm_custom_header (abfd)->hdrLength, abfd)
+ != nlm_custom_header (abfd)->hdrLength)
+ return false;
+ }
+ }
+
+ /* Write out the Cygnus debugging header if there is one. */
+ if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
+ sizeof (Nlm_Internal_Cygnus_Ext_Header)))
+ {
+ Nlm_External_Custom_Header thdr;
+
+ memcpy (thdr.stamp, "CuStHeAd", 8);
+ put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8,
+ (bfd_byte *) thdr.length);
+ put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset,
+ (bfd_byte *) thdr.dataOffset);
+ put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length,
+ (bfd_byte *) thdr.dataLength);
+ memcpy (thdr.dataStamp, "CyGnUsEx", 8);
+ if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr))
+ return false;
+ }
+
+ return true;
+}
+
+/* We read the NLM's public symbols and use it to generate a bfd symbol
+ table (hey, it's better than nothing) on a one-for-one basis. Thus
+ use the number of public symbols as the number of bfd symbols we will
+ have once we actually get around to reading them in.
+
+ Return the number of bytes required to hold the symtab vector, based on
+ the count plus 1, since we will NULL terminate the vector allocated based
+ on this size. */
+
+long
+nlm_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
+ long symcount;
+ long symtab_size = 0;
+
+ i_fxdhdrp = nlm_fixed_header (abfd);
+ symcount = (i_fxdhdrp->numberOfPublics
+ + i_fxdhdrp->numberOfDebugRecords
+ + i_fxdhdrp->numberOfExternalReferences);
+ symtab_size = (symcount + 1) * (sizeof (asymbol));
+ return (symtab_size);
+}
+
+/* Note that bfd_get_symcount is guaranteed to be zero if slurping the
+ symbol table fails. */
+
+long
+nlm_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ nlm_symbol_type *symbase;
+ bfd_size_type counter = 0;
+
+ if (nlm_slurp_symbol_table (abfd) == false)
+ return -1;
+ symbase = nlm_get_symbols (abfd);
+ while (counter < bfd_get_symcount (abfd))
+ {
+ *alocation++ = &symbase->symbol;
+ symbase++;
+ counter++;
+ }
+ *alocation = (asymbol *) NULL;
+ return bfd_get_symcount (abfd);
+}
+
+/* Make an NLM symbol. There is nothing special to do here. */
+
+asymbol *
+nlm_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ nlm_symbol_type *new;
+
+ new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type));
+ if (new)
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
+
+/* Get symbol information. */
+
+void
+nlm_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* Print symbol information. */
+
+void
+nlm_print_symbol (abfd, afile, symbol, how)
+ bfd *abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ case bfd_print_symbol_more:
+ if (symbol->name)
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_all:
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %-5s", symbol->section->name);
+ if (symbol->name)
+ fprintf (file, " %s", symbol->name);
+ break;
+ }
+}
+
+/* Slurp in nlm symbol table.
+
+ In the external (in-file) form, NLM export records are variable length,
+ with the following form:
+
+ 1 byte length of the symbol name (N)
+ N bytes the symbol name
+ 4 bytes the symbol offset from start of it's section
+
+ We also read in the debugging symbols and import records. Import
+ records are treated as undefined symbols. As we read the import
+ records we also read in the associated reloc information, which is
+ attached to the symbol.
+
+ The bfd symbols are copied to SYMPTRS.
+
+ When we return, the bfd symcount is either zero or contains the correct
+ number of symbols.
+*/
+
+static boolean
+nlm_slurp_symbol_table (abfd)
+ bfd *abfd;
+{
+ Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
+ bfd_size_type totsymcount; /* Number of NLM symbols */
+ bfd_size_type symcount; /* Counter of NLM symbols */
+ nlm_symbol_type *sym; /* Pointer to current bfd symbol */
+ unsigned char symlength; /* Symbol length read into here */
+ unsigned char symtype; /* Type of debugging symbol */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
+ boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
+ boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
+
+ if (nlm_get_symbols (abfd) != NULL)
+ return (true);
+
+ /* Read each raw NLM symbol, using the information to create a canonical bfd
+ symbol table entry.
+
+ Note that we allocate the initial bfd canonical symbol buffer based on a
+ one-to-one mapping of the NLM symbols to canonical symbols. We actually
+ use all the NLM symbols, so there will be no space left over at the end.
+ When we have all the symbols, we build the caller's pointer vector. */
+
+ abfd->symcount = 0;
+ i_fxdhdrp = nlm_fixed_header (abfd);
+ totsymcount = (i_fxdhdrp->numberOfPublics
+ + i_fxdhdrp->numberOfDebugRecords
+ + i_fxdhdrp->numberOfExternalReferences);
+ if (totsymcount == 0)
+ {
+ return (true);
+ }
+
+ if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1)
+ return (false);
+
+ sym = ((nlm_symbol_type *)
+ bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type)));
+ if (!sym)
+ return false;
+ nlm_set_symbols (abfd, sym);
+
+ /* We use the bfd's symcount directly as the control count, so that early
+ termination of the loop leaves the symcount correct for the symbols that
+ were read. */
+
+ set_public_section_func = nlm_set_public_section_func (abfd);
+ symcount = i_fxdhdrp->numberOfPublics;
+ while (abfd->symcount < symcount)
+ {
+ if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ return (false);
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bfd_alloc (abfd, symlength + 1);
+ if (!sym->symbol.name)
+ return false;
+ if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
+ != symlength)
+ return (false);
+ /* Cast away const. */
+ ((char *) (sym->symbol.name))[symlength] = '\0';
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ return (false);
+ sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
+ sym->symbol.value = get_word (abfd, temp);
+ if (set_public_section_func)
+ {
+ /* Most backends can use the code below, but unfortunately
+ some use a different scheme. */
+ if ((*set_public_section_func) (abfd, sym) == false)
+ return false;
+ }
+ else
+ {
+ if (sym->symbol.value & NLM_HIBIT)
+ {
+ sym->symbol.value &= ~NLM_HIBIT;
+ sym->symbol.flags |= BSF_FUNCTION;
+ sym->symbol.section =
+ bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ }
+ else
+ {
+ sym->symbol.section =
+ bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ }
+ }
+ sym->rcnt = 0;
+ abfd->symcount++;
+ sym++;
+ }
+
+ /* Read the debugging records. */
+
+ if (i_fxdhdrp->numberOfDebugRecords > 0)
+ {
+ if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1)
+ return (false);
+
+ symcount += i_fxdhdrp->numberOfDebugRecords;
+ while (abfd->symcount < symcount)
+ {
+ if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd)
+ != sizeof (symtype))
+ || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)
+ || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength)))
+ return false;
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bfd_alloc (abfd, symlength + 1);
+ if (!sym->symbol.name)
+ return false;
+ if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd)
+ != symlength)
+ return (false);
+ /* Cast away const. */
+ ((char *) (sym->symbol.name))[symlength] = '\0';
+ sym->symbol.flags = BSF_LOCAL;
+ sym->symbol.value = get_word (abfd, temp);
+ if (symtype == 0)
+ {
+ sym->symbol.section =
+ bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ }
+ else if (symtype == 1)
+ {
+ sym->symbol.flags |= BSF_FUNCTION;
+ sym->symbol.section =
+ bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ }
+ else
+ {
+ sym->symbol.section = bfd_abs_section_ptr;
+ }
+ sym->rcnt = 0;
+ abfd->symcount++;
+ sym++;
+ }
+ }
+
+ /* Read in the import records. We can only do this if we know how
+ to read relocs for this target. */
+
+ read_import_func = nlm_read_import_func (abfd);
+ if (read_import_func != NULL)
+ {
+ if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET)
+ == -1)
+ return (false);
+
+ symcount += i_fxdhdrp->numberOfExternalReferences;
+ while (abfd->symcount < symcount)
+ {
+ if ((*read_import_func) (abfd, sym) == false)
+ return false;
+ sym++;
+ abfd->symcount++;
+ }
+ }
+
+ return (true);
+}
+
+/* Get the relocs for an NLM file. There are two types of relocs.
+ Imports are relocs against symbols defined in other NLM files. We
+ treat these as relocs against global symbols. Relocation fixups
+ are internal relocs.
+
+ The actual format used to store the relocs is machine specific. */
+
+/* Read in the relocation fixup information. This is stored in
+ nlm_relocation_fixups, an array of arelent structures, and
+ nlm_relocation_fixup_secs, an array of section pointers. The
+ section pointers are needed because the relocs are not sorted by
+ section. */
+
+static boolean
+nlm_slurp_reloc_fixups (abfd)
+ bfd *abfd;
+{
+ boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
+ arelent *));
+ bfd_size_type count;
+ arelent *rels;
+ asection **secs;
+
+ if (nlm_relocation_fixups (abfd) != NULL)
+ return true;
+ read_func = nlm_read_reloc_func (abfd);
+ if (read_func == NULL)
+ return true;
+
+ if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
+ SEEK_SET) != 0)
+ return false;
+
+ count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
+ rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent));
+ secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *));
+ if ((rels == NULL || secs == NULL) && count != 0)
+ return false;
+ nlm_relocation_fixups (abfd) = rels;
+ nlm_relocation_fixup_secs (abfd) = secs;
+
+ /* We have to read piece by piece, because we don't know how large
+ the machine specific reloc information is. */
+ while (count-- != 0)
+ {
+ if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false)
+ {
+ nlm_relocation_fixups (abfd) = NULL;
+ nlm_relocation_fixup_secs (abfd) = NULL;
+ return false;
+ }
+ ++secs;
+ ++rels;
+ }
+
+ return true;
+}
+
+/* Get the number of relocs. This really just returns an upper bound,
+ since it does not attempt to distinguish them based on the section.
+ That will be handled when they are actually read. */
+
+long
+nlm_get_reloc_upper_bound (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ nlm_symbol_type *syms;
+ bfd_size_type count;
+ unsigned int ret;
+
+ /* If we don't know how to read relocs, just return 0. */
+ if (nlm_read_reloc_func (abfd) == NULL)
+ return -1;
+ /* Make sure we have either the code or the data section. */
+ if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
+ return 0;
+
+ syms = nlm_get_symbols (abfd);
+ if (syms == NULL)
+ {
+ if (nlm_slurp_symbol_table (abfd) == false)
+ return -1;
+ syms = nlm_get_symbols (abfd);
+ }
+
+ ret = nlm_fixed_header (abfd)->numberOfRelocationFixups;
+
+ count = bfd_get_symcount (abfd);
+ while (count-- != 0)
+ {
+ ret += syms->rcnt;
+ ++syms;
+ }
+
+ return (ret + 1) * sizeof (arelent *);
+}
+
+/* Get the relocs themselves. */
+
+long
+nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
+ bfd *abfd;
+ asection *sec;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *rels;
+ asection **secs;
+ bfd_size_type count, i;
+ unsigned int ret;
+
+ /* Get the relocation fixups. */
+ rels = nlm_relocation_fixups (abfd);
+ if (rels == NULL)
+ {
+ if (nlm_slurp_reloc_fixups (abfd) == false)
+ return -1;
+ rels = nlm_relocation_fixups (abfd);
+ }
+ secs = nlm_relocation_fixup_secs (abfd);
+
+ ret = 0;
+ count = nlm_fixed_header (abfd)->numberOfRelocationFixups;
+ for (i = 0; i < count; i++, rels++, secs++)
+ {
+ if (*secs == sec)
+ {
+ *relptr++ = rels;
+ ++ret;
+ }
+ }
+
+ /* Get the import symbols. */
+ count = bfd_get_symcount (abfd);
+ for (i = 0; i < count; i++, symbols++)
+ {
+ asymbol *sym;
+
+ sym = *symbols;
+ if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour)
+ {
+ nlm_symbol_type *nlm_sym;
+ bfd_size_type j;
+
+ nlm_sym = (nlm_symbol_type *) sym;
+ for (j = 0; j < nlm_sym->rcnt; j++)
+ {
+ if (nlm_sym->relocs[j].section == sec)
+ {
+ *relptr = &nlm_sym->relocs[j].reloc;
+ (*relptr)->sym_ptr_ptr = symbols;
+ ++relptr;
+ ++ret;
+ }
+ }
+ }
+ }
+
+ *relptr = NULL;
+
+ return ret;
+}
+
+/* Compute the section file positions for an NLM file. All variable
+ length data in the file headers must be set before this function is
+ called. If the variable length data is changed later, the
+ resulting object file will be incorrect. Unfortunately, there is
+ no way to check this.
+
+ This routine also sets the Size and Offset fields in the fixed
+ header.
+
+ It also looks over the symbols and moves any common symbols into
+ the .bss section; NLM has no way to represent a common symbol.
+ This approach means that either the symbols must already have been
+ set at this point, or there must be no common symbols. We need to
+ move the symbols at this point so that mangle_relocs can see the
+ final values. */
+
+static boolean
+nlm_compute_section_file_positions (abfd)
+ bfd *abfd;
+{
+ file_ptr sofar;
+ asection *sec;
+ bfd_vma text, data, bss;
+ bfd_vma text_low, data_low;
+ unsigned int text_align, data_align, other_align;
+ file_ptr text_ptr, data_ptr, other_ptr;
+ asection *bss_sec;
+ asymbol **sym_ptr_ptr;
+
+ if (abfd->output_has_begun == true)
+ return true;
+
+ /* Make sure we have a section to hold uninitialized data. */
+ bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
+ if (bss_sec == NULL)
+ {
+ if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
+ (file_ptr) 0, (bfd_size_type) 0,
+ SEC_ALLOC))
+ return false;
+ bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
+ }
+
+ abfd->output_has_begun = true;
+
+ /* The fixed header. */
+ sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
+
+ /* The variable header. */
+ sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
+ + nlm_variable_header (abfd)->descriptionLength + 1
+ + NLM_TARGET_LONG_SIZE /* stackSize */
+ + NLM_TARGET_LONG_SIZE /* reserved */
+ + sizeof (nlm_variable_header (abfd)->oldThreadName)
+ + sizeof (nlm_variable_header (abfd)->screenNameLength)
+ + nlm_variable_header (abfd)->screenNameLength + 1
+ + sizeof (nlm_variable_header (abfd)->threadNameLength)
+ + nlm_variable_header (abfd)->threadNameLength + 1);
+
+ /* The auxiliary headers. */
+ if (find_nonzero ((PTR) nlm_version_header (abfd),
+ sizeof (Nlm_Internal_Version_Header)))
+ sofar += sizeof (Nlm_External_Version_Header);
+ if (find_nonzero ((PTR) nlm_extended_header (abfd),
+ sizeof (Nlm_Internal_Extended_Header)))
+ sofar += sizeof (Nlm_External_Extended_Header);
+ if (find_nonzero ((PTR) nlm_copyright_header (abfd),
+ sizeof (Nlm_Internal_Copyright_Header)))
+ sofar += (sizeof (Nlm_External_Copyright_Header)
+ + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
+ if (find_nonzero ((PTR) nlm_custom_header (abfd),
+ sizeof (Nlm_Internal_Custom_Header)))
+ sofar += (sizeof (Nlm_External_Custom_Header)
+ + nlm_custom_header (abfd)->hdrLength);
+ if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd),
+ sizeof (Nlm_Internal_Cygnus_Ext_Header)))
+ sofar += sizeof (Nlm_External_Custom_Header);
+
+ /* Compute the section file positions in two passes. First get the
+ sizes of the text and data sections, and then set the file
+ positions. This code aligns the sections in the file using the
+ same alignment restrictions that apply to the sections in memory;
+ this may not be necessary. */
+ text = 0;
+ text_low = (bfd_vma) - 1;
+ text_align = 0;
+ data = 0;
+ data_low = (bfd_vma) - 1;
+ data_align = 0;
+ bss = 0;
+ other_align = 0;
+ for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
+ {
+ flagword f;
+
+ sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power);
+
+ f = bfd_get_section_flags (abfd, sec);
+ if (f & SEC_CODE)
+ {
+ text += sec->_raw_size;
+ if (bfd_get_section_vma (abfd, sec) < text_low)
+ text_low = bfd_get_section_vma (abfd, sec);
+ if (sec->alignment_power > text_align)
+ text_align = sec->alignment_power;
+ }
+ else if (f & SEC_DATA)
+ {
+ data += sec->_raw_size;
+ if (bfd_get_section_vma (abfd, sec) < data_low)
+ data_low = bfd_get_section_vma (abfd, sec);
+ if (sec->alignment_power > data_align)
+ data_align = sec->alignment_power;
+ }
+ else if (f & SEC_HAS_CONTENTS)
+ {
+ if (sec->alignment_power > other_align)
+ other_align = sec->alignment_power;
+ }
+ else if (f & SEC_ALLOC)
+ bss += sec->_raw_size;
+ }
+
+ nlm_set_text_low (abfd, text_low);
+ nlm_set_data_low (abfd, data_low);
+
+ if (nlm_no_uninitialized_data (abfd))
+ {
+ /* This NetWare format does not use uninitialized data. We must
+ increase the size of the data section. We will never wind up
+ writing those file locations, so they will remain zero. */
+ data += bss;
+ bss = 0;
+ }
+
+ text_ptr = BFD_ALIGN (sofar, 1 << text_align);
+ data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align);
+ other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align);
+
+ /* Fill in some fields in the header for which we now have the
+ information. */
+ nlm_fixed_header (abfd)->codeImageOffset = text_ptr;
+ nlm_fixed_header (abfd)->codeImageSize = text;
+ nlm_fixed_header (abfd)->dataImageOffset = data_ptr;
+ nlm_fixed_header (abfd)->dataImageSize = data;
+ nlm_fixed_header (abfd)->uninitializedDataSize = bss;
+
+ for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
+ {
+ flagword f;
+
+ f = bfd_get_section_flags (abfd, sec);
+
+ if (f & SEC_CODE)
+ {
+ sec->filepos = text_ptr;
+ text_ptr += sec->_raw_size;
+ }
+ else if (f & SEC_DATA)
+ {
+ sec->filepos = data_ptr;
+ data_ptr += sec->_raw_size;
+ }
+ else if (f & SEC_HAS_CONTENTS)
+ {
+ sec->filepos = other_ptr;
+ other_ptr += sec->_raw_size;
+ }
+ }
+
+ nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
+
+ /* Move all common symbols into the .bss section. */
+
+ sym_ptr_ptr = bfd_get_outsymbols (abfd);
+ if (sym_ptr_ptr != NULL)
+ {
+ asymbol **sym_end;
+ bfd_vma add;
+
+ sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
+ add = 0;
+ for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
+ {
+ asymbol *sym;
+ bfd_vma size;
+
+ sym = *sym_ptr_ptr;
+
+ if (!bfd_is_com_section (bfd_get_section (sym)))
+ continue;
+
+ /* Put the common symbol in the .bss section, and increase
+ the size of the .bss section by the size of the common
+ symbol (which is the old value of the symbol). */
+ sym->section = bss_sec;
+ size = sym->value;
+ sym->value = bss_sec->_raw_size + add;
+ add += size;
+ add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
+ }
+ if (add != 0)
+ {
+ if (nlm_no_uninitialized_data (abfd))
+ {
+ /* We could handle this case, but so far it hasn't been
+ necessary. */
+ abort ();
+ }
+ nlm_fixed_header (abfd)->uninitializedDataSize += add;
+ bss_sec->_raw_size += add;
+ }
+ }
+
+ return true;
+}
+
+/* Set the contents of a section. To do this we need to know where
+ the section is going to be located in the output file. That means
+ that the sizes of all the sections must be set, and all the
+ variable size header information must be known. */
+
+boolean
+nlm_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (abfd->output_has_begun == false
+ && nlm_compute_section_file_positions (abfd) == false)
+ return false;
+
+ if (count == 0)
+ return true;
+
+ /* i386 NetWare has a very restricted set of relocs. In order for
+ objcopy to work, the NLM i386 backend needs a chance to rework
+ the section contents so that its set of relocs will work. If all
+ the relocs are already acceptable, this will not do anything. */
+ if (section->reloc_count != 0)
+ {
+ boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR,
+ bfd_vma, bfd_size_type));
+
+ mangle_relocs_func = nlm_mangle_relocs_func (abfd);
+ if (mangle_relocs_func != NULL)
+ {
+ if (!(*mangle_relocs_func) (abfd, section, location,
+ (bfd_vma) offset, count))
+ return false;
+ }
+ }
+
+ if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
+ || bfd_write (location, 1, count, abfd) != count)
+ return false;
+
+ return true;
+}
+
+/* We need to sort a list of relocs associated with sections when we
+ write out the external relocs. */
+
+static int
+nlm_external_reloc_compare (p1, p2)
+ const void *p1;
+ const void *p2;
+{
+ const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1;
+ const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2;
+ int cmp;
+
+ cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name,
+ (*r2->rel->sym_ptr_ptr)->name);
+ if (cmp != 0)
+ return cmp;
+
+ /* We sort by address within symbol to make the sort more stable and
+ increase the chances that different hosts will generate bit for
+ bit equivalent results. */
+ return (int) (r1->rel->address - r2->rel->address);
+}
+
+/* Write out an NLM file. We write out the information in this order:
+ fixed header
+ variable header
+ auxiliary headers
+ code sections
+ data sections
+ other sections (custom data, messages, help, shared NLM, RPC,
+ module dependencies)
+ relocation fixups
+ external references (imports)
+ public symbols (exports)
+ debugging records
+ This is similar to the order used by the NetWare tools; the
+ difference is that NetWare puts the sections other than code, data
+ and custom data at the end of the NLM. It is convenient for us to
+ know where the sections are going to be before worrying about the
+ size of the other information.
+
+ By the time this function is called, all the section data should
+ have been output using set_section_contents. Note that custom
+ data, the message file, the help file, the shared NLM file, the RPC
+ data, and the module dependencies are all considered to be
+ sections; the caller is responsible for filling in the offset and
+ length fields in the NLM headers. The relocation fixups and
+ imports are both obtained from the list of relocs attached to each
+ section. The exports and debugging records are obtained from the
+ list of outsymbols. */
+
+boolean
+nlm_write_object_contents (abfd)
+ bfd *abfd;
+{
+ asection *sec;
+ boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
+ bfd_size_type external_reloc_count, internal_reloc_count, i, c;
+ struct reloc_and_sec *external_relocs;
+ asymbol **sym_ptr_ptr;
+ file_ptr last;
+ boolean (*write_prefix_func) PARAMS ((bfd *));
+ unsigned char *fixed_header = NULL;
+
+ fixed_header = ((unsigned char *)
+ bfd_malloc ((size_t) nlm_fixed_header_size (abfd)));
+ if (fixed_header == NULL)
+ goto error_return;
+
+ if (abfd->output_has_begun == false
+ && nlm_compute_section_file_positions (abfd) == false)
+ goto error_return;
+
+ /* Write out the variable length headers. */
+ if (bfd_seek (abfd,
+ nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
+ SEEK_SET) != 0)
+ goto error_return;
+ if (nlm_swap_variable_header_out (abfd) == false
+ || nlm_swap_auxiliary_headers_out (abfd) == false)
+ {
+ bfd_set_error (bfd_error_system_call);
+ goto error_return;
+ }
+
+ /* A weak check on whether the section file positions were
+ reasonable. */
+ if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+
+ /* Advance to the relocs. */
+ if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset,
+ SEEK_SET) != 0)
+ goto error_return;
+
+ /* The format of the relocation entries is dependent upon the
+ particular target. We use an external routine to write the reloc
+ out. */
+ write_import_func = nlm_write_import_func (abfd);
+
+ /* Write out the internal relocation fixups. While we're looping
+ over the relocs, we also count the external relocs, which is
+ needed when they are written out below. */
+ internal_reloc_count = 0;
+ external_reloc_count = 0;
+ for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
+ {
+ arelent **rel_ptr_ptr, **rel_end;
+
+ if (sec->reloc_count == 0)
+ continue;
+
+ /* We can only represent relocs within a code or data
+ section. We ignore them for a debugging section. */
+ if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
+ continue;
+
+ /* We need to know how to write out imports */
+ if (write_import_func == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+
+ rel_ptr_ptr = sec->orelocation;
+ rel_end = rel_ptr_ptr + sec->reloc_count;
+ for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
+ {
+ arelent *rel;
+ asymbol *sym;
+
+ rel = *rel_ptr_ptr;
+ sym = *rel->sym_ptr_ptr;
+
+ if (! bfd_is_und_section (bfd_get_section (sym)))
+ {
+ ++internal_reloc_count;
+ if ((*write_import_func) (abfd, sec, rel) == false)
+ goto error_return;
+ }
+ else
+ ++external_reloc_count;
+ }
+ }
+ nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count;
+
+ /* Write out the imports (relocs against external symbols). These
+ are output as a symbol name followed by all the relocs for that
+ symbol, so we must first gather together all the relocs against
+ external symbols and sort them. */
+ external_relocs =
+ (struct reloc_and_sec *) bfd_alloc (abfd,
+ (external_reloc_count
+ * sizeof (struct reloc_and_sec)));
+ if (external_relocs == (struct reloc_and_sec *) NULL)
+ goto error_return;
+ i = 0;
+ for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
+ {
+ arelent **rel_ptr_ptr, **rel_end;
+
+ if (sec->reloc_count == 0)
+ continue;
+
+ rel_ptr_ptr = sec->orelocation;
+ rel_end = rel_ptr_ptr + sec->reloc_count;
+ for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
+ {
+ arelent *rel;
+ asymbol *sym;
+
+ rel = *rel_ptr_ptr;
+ sym = *rel->sym_ptr_ptr;
+
+ if (! bfd_is_und_section (bfd_get_section (sym)))
+ continue;
+
+ external_relocs[i].rel = rel;
+ external_relocs[i].sec = sec;
+ ++i;
+ }
+ }
+
+ BFD_ASSERT (i == external_reloc_count);
+
+ /* Sort the external relocs by name. */
+ qsort ((PTR) external_relocs, (size_t) external_reloc_count,
+ sizeof (struct reloc_and_sec), nlm_external_reloc_compare);
+
+ /* Write out the external relocs. */
+ nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd);
+ c = 0;
+ i = 0;
+ while (i < external_reloc_count)
+ {
+ arelent *rel;
+ asymbol *sym;
+ bfd_size_type j, cnt;
+
+ ++c;
+
+ rel = external_relocs[i].rel;
+ sym = *rel->sym_ptr_ptr;
+
+ cnt = 0;
+ for (j = i;
+ (j < external_reloc_count
+ && *external_relocs[j].rel->sym_ptr_ptr == sym);
+ j++)
+ ++cnt;
+
+ if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
+ &external_relocs[i])
+ == false)
+ goto error_return;
+
+ i += cnt;
+ }
+
+ nlm_fixed_header (abfd)->numberOfExternalReferences = c;
+
+ /* Write out the public symbols (exports). */
+ sym_ptr_ptr = bfd_get_outsymbols (abfd);
+ if (sym_ptr_ptr != (asymbol **) NULL)
+ {
+ bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
+ boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma));
+
+ asymbol **sym_end;
+
+ nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
+ get_public_offset_func = nlm_get_public_offset_func (abfd);
+ write_export_func = nlm_write_export_func (abfd);
+ c = 0;
+ sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
+ for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
+ {
+ asymbol *sym;
+ bfd_byte len;
+ bfd_vma offset;
+ bfd_byte temp[NLM_TARGET_LONG_SIZE];
+
+ sym = *sym_ptr_ptr;
+
+ if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
+ || bfd_is_und_section (bfd_get_section (sym)))
+ continue;
+
+ ++c;
+
+ if (get_public_offset_func)
+ {
+ /* Most backends can use the code below, but
+ unfortunately some use a different scheme. */
+ offset = (*get_public_offset_func) (abfd, sym);
+ }
+ else
+ {
+ offset = bfd_asymbol_value (sym);
+ sec = sym->section;
+ if (sec->flags & SEC_CODE)
+ {
+ offset -= nlm_get_text_low (abfd);
+ offset |= NLM_HIBIT;
+ }
+ else if (sec->flags & (SEC_DATA | SEC_ALLOC))
+ {
+ /* SEC_ALLOC is for the .bss section. */
+ offset -= nlm_get_data_low (abfd);
+ }
+ else
+ {
+ /* We can't handle an exported symbol that is not in
+ the code or data segment. */
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+ }
+
+ if (write_export_func)
+ {
+ if ((*write_export_func) (abfd, sym, offset) == false)
+ goto error_return;
+ }
+ else
+ {
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
+ != sizeof (bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ goto error_return;
+
+ put_word (abfd, offset, temp);
+ if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ goto error_return;
+ }
+ }
+ nlm_fixed_header (abfd)->numberOfPublics = c;
+
+ /* Write out the debugging records. The NLM conversion program
+ wants to be able to inhibit this, so as a special hack if
+ debugInfoOffset is set to -1 we don't write any debugging
+ information. This can not be handled by fiddling with the
+ symbol table, because exported symbols appear in both the
+ exported symbol list and the debugging information. */
+ if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1)
+ {
+ nlm_fixed_header (abfd)->debugInfoOffset = 0;
+ nlm_fixed_header (abfd)->numberOfDebugRecords = 0;
+ }
+ else
+ {
+ nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
+ c = 0;
+ sym_ptr_ptr = bfd_get_outsymbols (abfd);
+ sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
+ for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
+ {
+ asymbol *sym;
+ bfd_byte type, len;
+ bfd_vma offset;
+ bfd_byte temp[NLM_TARGET_LONG_SIZE];
+
+ sym = *sym_ptr_ptr;
+
+ /* The NLM notion of a debugging symbol is actually what
+ BFD calls a local or global symbol. What BFD calls a
+ debugging symbol NLM does not understand at all. */
+ if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
+ || (sym->flags & BSF_DEBUGGING) != 0
+ || bfd_is_und_section (bfd_get_section (sym)))
+ continue;
+
+ ++c;
+
+ offset = bfd_asymbol_value (sym);
+ sec = sym->section;
+ if (sec->flags & SEC_CODE)
+ {
+ offset -= nlm_get_text_low (abfd);
+ type = 1;
+ }
+ else if (sec->flags & (SEC_DATA | SEC_ALLOC))
+ {
+ /* SEC_ALLOC is for the .bss section. */
+ offset -= nlm_get_data_low (abfd);
+ type = 0;
+ }
+ else
+ type = 2;
+
+ /* The type is 0 for data, 1 for code, 2 for absolute. */
+ if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
+ != sizeof (bfd_byte))
+ goto error_return;
+
+ put_word (abfd, offset, temp);
+ if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ goto error_return;
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
+ != sizeof (bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ goto error_return;
+ }
+ nlm_fixed_header (abfd)->numberOfDebugRecords = c;
+ }
+ }
+
+ /* NLMLINK fills in offset values even if there is no data, so we do
+ the same. */
+ last = bfd_tell (abfd);
+ if (nlm_fixed_header (abfd)->codeImageOffset == 0)
+ nlm_fixed_header (abfd)->codeImageOffset = last;
+ if (nlm_fixed_header (abfd)->dataImageOffset == 0)
+ nlm_fixed_header (abfd)->dataImageOffset = last;
+ if (nlm_fixed_header (abfd)->customDataOffset == 0)
+ nlm_fixed_header (abfd)->customDataOffset = last;
+ if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0)
+ nlm_fixed_header (abfd)->moduleDependencyOffset = last;
+ if (nlm_fixed_header (abfd)->relocationFixupOffset == 0)
+ nlm_fixed_header (abfd)->relocationFixupOffset = last;
+ if (nlm_fixed_header (abfd)->externalReferencesOffset == 0)
+ nlm_fixed_header (abfd)->externalReferencesOffset = last;
+ if (nlm_fixed_header (abfd)->publicsOffset == 0)
+ nlm_fixed_header (abfd)->publicsOffset = last;
+ if (nlm_fixed_header (abfd)->debugInfoOffset == 0)
+ nlm_fixed_header (abfd)->debugInfoOffset = last;
+
+ /* At this point everything has been written out except the fixed
+ header. */
+ memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
+ NLM_SIGNATURE_SIZE);
+ nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
+ nlm_fixed_header (abfd)->codeStartOffset =
+ (bfd_get_start_address (abfd)
+ - nlm_get_text_low (abfd));
+
+ /* We have no convenient way for the caller to pass in the exit
+ procedure or the check unload procedure, so the caller must set
+ the values in the header to the values of the symbols. */
+ nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
+ if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
+ nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
+ nlm_get_text_low (abfd);
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ goto error_return;
+
+ write_prefix_func = nlm_write_prefix_func (abfd);
+ if (write_prefix_func)
+ {
+ if ((*write_prefix_func) (abfd) == false)
+ goto error_return;
+ }
+
+ BFD_ASSERT ((bfd_size_type) bfd_tell (abfd)
+ == nlm_optional_prefix_size (abfd));
+
+ nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
+ if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
+ != nlm_fixed_header_size (abfd))
+ goto error_return;
+
+ if (fixed_header != NULL)
+ free (fixed_header);
+ return true;
+
+error_return:
+ if (fixed_header != NULL)
+ free (fixed_header);
+ return false;
+}
diff --git a/bfd/nlmswap.h b/bfd/nlmswap.h
new file mode 100644
index 00000000000..5a9ce7268d0
--- /dev/null
+++ b/bfd/nlmswap.h
@@ -0,0 +1,157 @@
+/* NLM (NetWare Loadable Module) swapping routines for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support, using ELF support as the
+ template.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Although this is a header file, it defines functions. It is
+ included by NLM backends to define swapping functions that vary
+ from one NLM to another. The backend code must arrange for
+ Nlm_External_xxxx to be defined appropriately, and can then include
+ this file to get the swapping routines.
+
+ At the moment this is only needed for one structure, the fixed NLM
+ file header. */
+
+static void nlm_swap_fixed_header_in PARAMS ((bfd *, PTR,
+ Nlm_Internal_Fixed_Header *));
+static void nlm_swap_fixed_header_out PARAMS ((bfd *,
+ Nlm_Internal_Fixed_Header *,
+ PTR));
+
+/* Translate an NLM fixed length file header in external format into an NLM
+ file header in internal format. */
+
+static void
+nlm_swap_fixed_header_in (abfd, realsrc, dst)
+ bfd *abfd;
+ PTR realsrc;
+ Nlm_Internal_Fixed_Header *dst;
+{
+ Nlm_External_Fixed_Header *src = (Nlm_External_Fixed_Header *) realsrc;
+ memcpy (dst->signature, src->signature, NLM_SIGNATURE_SIZE);
+ memcpy (dst->moduleName, src->moduleName, NLM_MODULE_NAME_SIZE);
+ dst->version =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->version);
+ dst->codeImageOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->codeImageOffset);
+ dst->codeImageSize =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->codeImageSize);
+ dst->dataImageOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->dataImageOffset);
+ dst->dataImageSize =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->dataImageSize);
+ dst->uninitializedDataSize =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->uninitializedDataSize);
+ dst->customDataOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->customDataOffset);
+ dst->customDataSize =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->customDataSize);
+ dst->moduleDependencyOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->moduleDependencyOffset);
+ dst->numberOfModuleDependencies =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfModuleDependencies);
+ dst->relocationFixupOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->relocationFixupOffset);
+ dst->numberOfRelocationFixups =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfRelocationFixups);
+ dst->externalReferencesOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->externalReferencesOffset);
+ dst->numberOfExternalReferences =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfExternalReferences);
+ dst->publicsOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->publicsOffset);
+ dst->numberOfPublics =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfPublics);
+ dst->debugInfoOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->debugInfoOffset);
+ dst->numberOfDebugRecords =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfDebugRecords);
+ dst->codeStartOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->codeStartOffset);
+ dst->exitProcedureOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->exitProcedureOffset);
+ dst->checkUnloadProcedureOffset =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->checkUnloadProcedureOffset);
+ dst->moduleType =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->moduleType);
+ dst->flags =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->flags);
+}
+
+/* Translate an NLM fixed length file header in internal format into
+ an NLM file header in external format. */
+
+static void
+nlm_swap_fixed_header_out (abfd, src, realdst)
+ bfd *abfd;
+ Nlm_Internal_Fixed_Header *src;
+ PTR realdst;
+{
+ Nlm_External_Fixed_Header *dst = (Nlm_External_Fixed_Header *) realdst;
+ memset (dst, 0, sizeof *dst);
+ memcpy (dst->signature, src->signature, NLM_SIGNATURE_SIZE);
+ memcpy (dst->moduleName, src->moduleName, NLM_MODULE_NAME_SIZE);
+ bfd_h_put_32 (abfd, (bfd_vma) src->version,
+ (bfd_byte *) dst->version);
+ bfd_h_put_32 (abfd, (bfd_vma) src->codeImageOffset,
+ (bfd_byte *) dst->codeImageOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->codeImageSize,
+ (bfd_byte *) dst->codeImageSize);
+ bfd_h_put_32 (abfd, (bfd_vma) src->dataImageOffset,
+ (bfd_byte *) dst->dataImageOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->dataImageSize,
+ (bfd_byte *) dst->dataImageSize);
+ bfd_h_put_32 (abfd, (bfd_vma) src->uninitializedDataSize,
+ (bfd_byte *) dst->uninitializedDataSize);
+ bfd_h_put_32 (abfd, (bfd_vma) src->customDataOffset,
+ (bfd_byte *) dst->customDataOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->customDataSize,
+ (bfd_byte *) dst->customDataSize);
+ bfd_h_put_32 (abfd, (bfd_vma) src->moduleDependencyOffset,
+ (bfd_byte *) dst->moduleDependencyOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->numberOfModuleDependencies,
+ (bfd_byte *) dst->numberOfModuleDependencies);
+ bfd_h_put_32 (abfd, (bfd_vma) src->relocationFixupOffset,
+ (bfd_byte *) dst->relocationFixupOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->numberOfRelocationFixups,
+ (bfd_byte *) dst->numberOfRelocationFixups);
+ bfd_h_put_32 (abfd, (bfd_vma) src->externalReferencesOffset,
+ (bfd_byte *) dst->externalReferencesOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->numberOfExternalReferences,
+ (bfd_byte *) dst->numberOfExternalReferences);
+ bfd_h_put_32 (abfd, (bfd_vma) src->publicsOffset,
+ (bfd_byte *) dst->publicsOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->numberOfPublics,
+ (bfd_byte *) dst->numberOfPublics);
+ bfd_h_put_32 (abfd, (bfd_vma) src->debugInfoOffset,
+ (bfd_byte *) dst->debugInfoOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->numberOfDebugRecords,
+ (bfd_byte *) dst->numberOfDebugRecords);
+ bfd_h_put_32 (abfd, (bfd_vma) src->codeStartOffset,
+ (bfd_byte *) dst->codeStartOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->exitProcedureOffset,
+ (bfd_byte *) dst->exitProcedureOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->checkUnloadProcedureOffset,
+ (bfd_byte *) dst->checkUnloadProcedureOffset);
+ bfd_h_put_32 (abfd, (bfd_vma) src->moduleType,
+ (bfd_byte *) dst->moduleType);
+ bfd_h_put_32 (abfd, (bfd_vma) src->flags,
+ (bfd_byte *) dst->flags);
+}
diff --git a/bfd/ns32k.h b/bfd/ns32k.h
new file mode 100644
index 00000000000..d63ba096219
--- /dev/null
+++ b/bfd/ns32k.h
@@ -0,0 +1,41 @@
+/* Header file for ns32k routines.
+ Copyright 1996 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern bfd_reloc_status_type _bfd_ns32k_relocate_contents
+ PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
+
+extern bfd_reloc_status_type _bfd_do_ns32k_reloc_contents
+ PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *,
+ long (*) PARAMS ((bfd_byte *, long, long)),
+ int (*) PARAMS ((long, bfd_byte *, long, long))));
+
+extern bfd_reloc_status_type _bfd_ns32k_final_link_relocate
+ PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma,
+ bfd_vma, bfd_vma));
+
+extern long _bfd_ns32k_get_displacement PARAMS ((bfd_byte *, long, long));
+extern long _bfd_ns32k_get_immediate PARAMS ((bfd_byte *, long, long));
+extern int _bfd_ns32k_put_displacement PARAMS ((long, bfd_byte *, long, long));
+extern int _bfd_ns32k_put_immediate PARAMS ((long, bfd_byte *, long, long));
+
+extern bfd_reloc_status_type _bfd_ns32k_reloc_disp
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+extern bfd_reloc_status_type _bfd_ns32k_reloc_imm
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
diff --git a/bfd/ns32knetbsd.c b/bfd/ns32knetbsd.c
new file mode 100644
index 00000000000..a22356df6e1
--- /dev/null
+++ b/bfd/ns32knetbsd.c
@@ -0,0 +1,53 @@
+/* BFD back-end for NetBSD/ns32k a.out-ish binaries.
+ Copyright (C) 1990, 91, 92, 94, 95, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#undef TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE 4096
+
+#define DEFAULT_ARCH bfd_arch_ns32k
+#define DEFAULT_MID M_532_NETBSD
+
+#define MY(OP) CAT(pc532netbsd_,OP)
+
+#define NAME(x,y) CAT3(ns32kaout,_32_,y)
+
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-ns32k-netbsd"
+
+#define ns32kaout_32_get_section_contents aout_32_get_section_contents
+
+#define MY_text_includes_header 1
+
+/* We can`t use the MYNS macro here for cpp reasons too subtle
+ * for me -- IWD
+ */
+#define MY_bfd_reloc_type_lookup ns32kaout_bfd_reloc_type_lookup
+
+#include "bfd.h" /* To ensure following declaration is OK */
+
+CONST struct reloc_howto_struct *
+MY_bfd_reloc_type_lookup
+ PARAMS((bfd *abfd AND
+ bfd_reloc_code_real_type code));
+
+
+#include "netbsd.h"
diff --git a/bfd/oasys.c b/bfd/oasys.c
new file mode 100644
index 00000000000..b51560e47fa
--- /dev/null
+++ b/bfd/oasys.c
@@ -0,0 +1,1535 @@
+/* BFD back-end for oasys objects.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define UNDERSCORE_HACK 1
+#include "bfd.h"
+#include "sysdep.h"
+#include <ctype.h>
+#include "libbfd.h"
+#include "oasys.h"
+#include "liboasys.h"
+
+/* XXX - FIXME. offsetof belongs in the system-specific files in
+ ../include/sys. */
+/* Define offsetof for those systems which lack it */
+
+#ifndef offsetof
+#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
+#endif
+
+static boolean oasys_read_record PARAMS ((bfd *,
+ oasys_record_union_type *));
+static boolean oasys_write_sections PARAMS ((bfd *));
+static boolean oasys_write_record PARAMS ((bfd *,
+ oasys_record_enum_type,
+ oasys_record_union_type *,
+ size_t));
+static boolean oasys_write_syms PARAMS ((bfd *));
+static boolean oasys_write_header PARAMS ((bfd *));
+static boolean oasys_write_end PARAMS ((bfd *));
+static boolean oasys_write_data PARAMS ((bfd *));
+
+/* Read in all the section data and relocation stuff too */
+PROTO (static boolean, oasys_slurp_section_data, (bfd * CONST abfd));
+
+static boolean
+oasys_read_record (abfd, record)
+ bfd *abfd;
+ oasys_record_union_type *record;
+{
+ if (bfd_read ((PTR) record, 1, sizeof (record->header), abfd)
+ != sizeof (record->header))
+ return false;
+
+ if ((size_t) record->header.length <= (size_t) sizeof (record->header))
+ return true;
+ if (bfd_read ((PTR) (((char *) record) + sizeof (record->header)),
+ 1, record->header.length - sizeof (record->header),
+ abfd)
+ != record->header.length - sizeof (record->header))
+ return false;
+ return true;
+}
+static size_t
+oasys_string_length (record)
+ oasys_record_union_type *record;
+{
+ return record->header.length
+ - ((char *) record->symbol.name - (char *) record);
+}
+
+/*****************************************************************************/
+
+/*
+
+Slurp the symbol table by reading in all the records at the start file
+till we get to the first section record.
+
+We'll sort the symbolss into two lists, defined and undefined. The
+undefined symbols will be placed into the table according to their
+refno.
+
+We do this by placing all undefined symbols at the front of the table
+moving in, and the defined symbols at the end of the table moving back.
+
+*/
+
+static boolean
+oasys_slurp_symbol_table (abfd)
+ bfd *CONST abfd;
+{
+ oasys_record_union_type record;
+ oasys_data_type *data = OASYS_DATA (abfd);
+ boolean loop = true;
+ asymbol *dest_defined;
+ asymbol *dest;
+ char *string_ptr;
+
+
+ if (data->symbols != (asymbol *) NULL)
+ {
+ return true;
+ }
+ /* Buy enough memory for all the symbols and all the names */
+ data->symbols =
+ (asymbol *) bfd_alloc (abfd, sizeof (asymbol) * abfd->symcount);
+#ifdef UNDERSCORE_HACK
+ /* buy 1 more char for each symbol to keep the underscore in*/
+ data->strings = bfd_alloc (abfd, data->symbol_string_length +
+ abfd->symcount);
+#else
+ data->strings = bfd_alloc (abfd, data->symbol_string_length);
+#endif
+ if (!data->symbols || !data->strings)
+ return false;
+
+ dest_defined = data->symbols + abfd->symcount - 1;
+
+ string_ptr = data->strings;
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return false;
+ while (loop)
+ {
+
+ if (! oasys_read_record (abfd, &record))
+ return false;
+ switch (record.header.type)
+ {
+ case oasys_record_is_header_enum:
+ break;
+ case oasys_record_is_local_enum:
+ case oasys_record_is_symbol_enum:
+ {
+ int flag = record.header.type == (int) oasys_record_is_local_enum ?
+ (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
+
+
+ size_t length = oasys_string_length (&record);
+ switch (record.symbol.relb & RELOCATION_TYPE_BITS)
+ {
+ case RELOCATION_TYPE_ABS:
+ dest = dest_defined--;
+ dest->section = bfd_abs_section_ptr;
+ dest->flags = 0;
+
+ break;
+ case RELOCATION_TYPE_REL:
+ dest = dest_defined--;
+ dest->section =
+ OASYS_DATA (abfd)->sections[record.symbol.relb &
+ RELOCATION_SECT_BITS];
+ if (record.header.type == (int) oasys_record_is_local_enum)
+ {
+ dest->flags = BSF_LOCAL;
+ if (dest->section == (asection *) (~0))
+ {
+ /* It seems that sometimes internal symbols are tied up, but
+ still get output, even though there is no
+ section */
+ dest->section = 0;
+ }
+ }
+ else
+ {
+
+ dest->flags = flag;
+ }
+ break;
+ case RELOCATION_TYPE_UND:
+ dest = data->symbols + bfd_h_get_16 (abfd, record.symbol.refno);
+ dest->section = bfd_und_section_ptr;
+ break;
+ case RELOCATION_TYPE_COM:
+ dest = dest_defined--;
+ dest->name = string_ptr;
+ dest->the_bfd = abfd;
+
+ dest->section = bfd_com_section_ptr;
+
+ break;
+ default:
+ dest = dest_defined--;
+ BFD_ASSERT (0);
+ break;
+ }
+ dest->name = string_ptr;
+ dest->the_bfd = abfd;
+ dest->udata.p = (PTR) NULL;
+ dest->value = bfd_h_get_32 (abfd, record.symbol.value);
+
+#ifdef UNDERSCORE_HACK
+ if (record.symbol.name[0] != '_')
+ {
+ string_ptr[0] = '_';
+ string_ptr++;
+ }
+#endif
+ memcpy (string_ptr, record.symbol.name, length);
+
+
+ string_ptr[length] = 0;
+ string_ptr += length + 1;
+ }
+ break;
+ default:
+ loop = false;
+ }
+ }
+ return true;
+}
+
+static long
+oasys_get_symtab_upper_bound (abfd)
+ bfd *CONST abfd;
+{
+ if (! oasys_slurp_symbol_table (abfd))
+ return -1;
+
+ return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));
+}
+
+/*
+*/
+
+extern const bfd_target oasys_vec;
+
+long
+oasys_get_symtab (abfd, location)
+ bfd *abfd;
+ asymbol **location;
+{
+ asymbol *symbase;
+ unsigned int counter;
+ if (oasys_slurp_symbol_table (abfd) == false)
+ {
+ return -1;
+ }
+ symbase = OASYS_DATA (abfd)->symbols;
+ for (counter = 0; counter < abfd->symcount; counter++)
+ {
+ *(location++) = symbase++;
+ }
+ *location = 0;
+ return abfd->symcount;
+}
+
+/***********************************************************************
+* archive stuff
+*/
+
+static const bfd_target *
+oasys_archive_p (abfd)
+ bfd *abfd;
+{
+ oasys_archive_header_type header;
+ oasys_extarchive_header_type header_ext;
+ unsigned int i;
+ file_ptr filepos;
+
+ if (bfd_seek (abfd, (file_ptr) 0, false) != 0
+ || (bfd_read ((PTR) & header_ext, 1, sizeof (header_ext), abfd)
+ != sizeof (header_ext)))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ header.version = bfd_h_get_32 (abfd, header_ext.version);
+ header.mod_count = bfd_h_get_32 (abfd, header_ext.mod_count);
+ header.mod_tbl_offset = bfd_h_get_32 (abfd, header_ext.mod_tbl_offset);
+ header.sym_tbl_size = bfd_h_get_32 (abfd, header_ext.sym_tbl_size);
+ header.sym_count = bfd_h_get_32 (abfd, header_ext.sym_count);
+ header.sym_tbl_offset = bfd_h_get_32 (abfd, header_ext.sym_tbl_offset);
+ header.xref_count = bfd_h_get_32 (abfd, header_ext.xref_count);
+ header.xref_lst_offset = bfd_h_get_32 (abfd, header_ext.xref_lst_offset);
+
+ /*
+ There isn't a magic number in an Oasys archive, so the best we
+ can do to verify reasnableness is to make sure that the values in
+ the header are too weird
+ */
+
+ if (header.version > 10000 ||
+ header.mod_count > 10000 ||
+ header.sym_count > 100000 ||
+ header.xref_count > 100000)
+ return (const bfd_target *) NULL;
+
+ /*
+ That all worked, let's buy the space for the header and read in
+ the headers.
+ */
+ {
+ oasys_ar_data_type *ar =
+ (oasys_ar_data_type *) bfd_alloc (abfd, sizeof (oasys_ar_data_type));
+
+ oasys_module_info_type *module =
+ (oasys_module_info_type *)
+ bfd_alloc (abfd, sizeof (oasys_module_info_type) * header.mod_count);
+ oasys_module_table_type record;
+
+ if (!ar || !module)
+ return NULL;
+
+ abfd->tdata.oasys_ar_data = ar;
+ ar->module = module;
+ ar->module_count = header.mod_count;
+
+ filepos = header.mod_tbl_offset;
+ for (i = 0; i < header.mod_count; i++)
+ {
+ if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ return NULL;
+
+ /* There are two ways of specifying the archive header */
+
+ if (0)
+ {
+ oasys_extmodule_table_type_a_type record_ext;
+ if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)
+ != sizeof (record_ext))
+ return NULL;
+
+ record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);
+ record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);
+
+ record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);
+ record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);
+ record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);
+
+ module[i].name = bfd_alloc (abfd, 33);
+ if (!module[i].name)
+ return NULL;
+
+ memcpy (module[i].name, record_ext.mod_name, 33);
+ filepos +=
+ sizeof (record_ext) +
+ record.dep_count * 4 +
+ record.depee_count * 4 +
+ record.sect_count * 8 + 187;
+ }
+ else
+ {
+ oasys_extmodule_table_type_b_type record_ext;
+ if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)
+ != sizeof (record_ext))
+ return NULL;
+
+ record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);
+ record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);
+
+ record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);
+ record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);
+ record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);
+ record.module_name_size = bfd_h_get_32 (abfd, record_ext.mod_name_length);
+
+ module[i].name = bfd_alloc (abfd, record.module_name_size + 1);
+ if (!module[i].name)
+ return NULL;
+ if (bfd_read ((PTR) module[i].name, 1, record.module_name_size,
+ abfd)
+ != record.module_name_size)
+ return NULL;
+ module[i].name[record.module_name_size] = 0;
+ filepos +=
+ sizeof (record_ext) +
+ record.dep_count * 4 +
+ record.module_name_size + 1;
+
+ }
+
+
+ module[i].size = record.mod_size;
+ module[i].pos = record.file_offset;
+ module[i].abfd = 0;
+ }
+
+ }
+ return abfd->xvec;
+}
+
+static boolean
+oasys_mkobject (abfd)
+ bfd *abfd;
+{
+
+ abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, sizeof (oasys_data_type));
+ return abfd->tdata.oasys_obj_data ? true : false;
+}
+
+#define MAX_SECS 16
+static const bfd_target *
+oasys_object_p (abfd)
+ bfd *abfd;
+{
+ oasys_data_type *oasys;
+ oasys_data_type *save = OASYS_DATA (abfd);
+ boolean loop = true;
+ boolean had_usefull = false;
+
+ abfd->tdata.oasys_obj_data = 0;
+ oasys_mkobject (abfd);
+ oasys = OASYS_DATA (abfd);
+ memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections));
+
+ /* Point to the start of the file */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto fail;
+ oasys->symbol_string_length = 0;
+ /* Inspect the records, but only keep the section info -
+ remember the size of the symbols
+ */
+ oasys->first_data_record = 0;
+ while (loop)
+ {
+ oasys_record_union_type record;
+ if (! oasys_read_record (abfd, &record))
+ goto fail;
+ if ((size_t) record.header.length < (size_t) sizeof (record.header))
+ goto fail;
+
+
+ switch ((oasys_record_enum_type) (record.header.type))
+ {
+ case oasys_record_is_header_enum:
+ had_usefull = true;
+ break;
+ case oasys_record_is_symbol_enum:
+ case oasys_record_is_local_enum:
+ /* Count symbols and remember their size for a future malloc */
+ abfd->symcount++;
+ oasys->symbol_string_length += 1 + oasys_string_length (&record);
+ had_usefull = true;
+ break;
+ case oasys_record_is_section_enum:
+ {
+ asection *s;
+ char *buffer;
+ unsigned int section_number;
+ if (record.section.header.length != sizeof (record.section))
+ {
+ goto fail;
+ }
+ buffer = bfd_alloc (abfd, 3);
+ if (!buffer)
+ goto fail;
+ section_number = record.section.relb & RELOCATION_SECT_BITS;
+ sprintf (buffer, "%u", section_number);
+ s = bfd_make_section (abfd, buffer);
+ oasys->sections[section_number] = s;
+ switch (record.section.relb & RELOCATION_TYPE_BITS)
+ {
+ case RELOCATION_TYPE_ABS:
+ case RELOCATION_TYPE_REL:
+ break;
+ case RELOCATION_TYPE_UND:
+ case RELOCATION_TYPE_COM:
+ BFD_FAIL ();
+ }
+
+ s->_raw_size = bfd_h_get_32 (abfd, record.section.value);
+ s->vma = bfd_h_get_32 (abfd, record.section.vma);
+ s->flags = 0;
+ had_usefull = true;
+ }
+ break;
+ case oasys_record_is_data_enum:
+ oasys->first_data_record = bfd_tell (abfd) - record.header.length;
+ case oasys_record_is_debug_enum:
+ case oasys_record_is_module_enum:
+ case oasys_record_is_named_section_enum:
+ case oasys_record_is_end_enum:
+ if (had_usefull == false)
+ goto fail;
+ loop = false;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ oasys->symbols = (asymbol *) NULL;
+ /*
+ Oasys support several architectures, but I can't see a simple way
+ to discover which one is in a particular file - we'll guess
+ */
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
+ if (abfd->symcount != 0)
+ {
+ abfd->flags |= HAS_SYMS;
+ }
+
+ /*
+ We don't know if a section has data until we've read it..
+ */
+
+ oasys_slurp_section_data (abfd);
+
+
+ return abfd->xvec;
+
+fail:
+ (void) bfd_release (abfd, oasys);
+ abfd->tdata.oasys_obj_data = save;
+ return (const bfd_target *) NULL;
+}
+
+
+static void
+oasys_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+ if (!symbol->section)
+ ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
+}
+
+static void
+oasys_print_symbol (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ case bfd_print_symbol_more:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name = symbol->section == (asection *) NULL ?
+ (CONST char *) "*abs" : symbol->section->name;
+
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+
+ fprintf (file, " %-5s %s",
+ section_name,
+ symbol->name);
+ }
+ break;
+ }
+}
+/*
+ The howto table is build using the top two bits of a reloc byte to
+ index into it. The bits are PCREL,WORD/LONG
+*/
+static reloc_howto_type howto_table[] =
+{
+
+ HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false),
+ HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false)
+};
+
+/* Read in all the section data and relocation stuff too */
+static boolean
+oasys_slurp_section_data (abfd)
+ bfd *CONST abfd;
+{
+ oasys_record_union_type record;
+ oasys_data_type *data = OASYS_DATA (abfd);
+ boolean loop = true;
+
+ oasys_per_section_type *per;
+
+ asection *s;
+
+ /* See if the data has been slurped already .. */
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ per = oasys_per_section (s);
+ if (per->initialized == true)
+ return true;
+ }
+
+ if (data->first_data_record == 0)
+ return true;
+
+ if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0)
+ return false;
+ while (loop)
+ {
+ if (! oasys_read_record (abfd, &record))
+ return false;
+ switch (record.header.type)
+ {
+ case oasys_record_is_header_enum:
+ break;
+ case oasys_record_is_data_enum:
+ {
+
+ bfd_byte *src = record.data.data;
+ bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length;
+ bfd_byte *dst_ptr;
+ bfd_byte *dst_base_ptr;
+ unsigned int relbit;
+ unsigned int count;
+ asection *section =
+ data->sections[record.data.relb & RELOCATION_SECT_BITS];
+ bfd_vma dst_offset;
+
+ per = oasys_per_section (section);
+
+ if (per->initialized == false)
+ {
+ per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size);
+ if (!per->data)
+ return false;
+ per->reloc_tail_ptr = (oasys_reloc_type **) & (section->relocation);
+ per->had_vma = false;
+ per->initialized = true;
+ section->reloc_count = 0;
+ section->flags = SEC_ALLOC;
+ }
+
+ dst_offset = bfd_h_get_32 (abfd, record.data.addr);
+ if (per->had_vma == false)
+ {
+ /* Take the first vma we see as the base */
+ section->vma = dst_offset;
+ per->had_vma = true;
+ }
+
+ dst_offset -= section->vma;
+
+ dst_base_ptr = oasys_per_section (section)->data;
+ dst_ptr = oasys_per_section (section)->data +
+ dst_offset;
+
+ if (src < end_src)
+ {
+ section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
+ }
+ while (src < end_src)
+ {
+ unsigned char mod_byte = *src++;
+ size_t gap = end_src - src;
+
+ count = 8;
+ if (mod_byte == 0 && gap >= 8)
+ {
+ dst_ptr[0] = src[0];
+ dst_ptr[1] = src[1];
+ dst_ptr[2] = src[2];
+ dst_ptr[3] = src[3];
+ dst_ptr[4] = src[4];
+ dst_ptr[5] = src[5];
+ dst_ptr[6] = src[6];
+ dst_ptr[7] = src[7];
+ dst_ptr += 8;
+ src += 8;
+ }
+ else
+ {
+ for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1)
+ {
+ if (relbit & mod_byte)
+ {
+ unsigned char reloc = *src;
+ /* This item needs to be relocated */
+ switch (reloc & RELOCATION_TYPE_BITS)
+ {
+ case RELOCATION_TYPE_ABS:
+
+ break;
+
+ case RELOCATION_TYPE_REL:
+ {
+ /* Relocate the item relative to the section */
+ oasys_reloc_type *r =
+ (oasys_reloc_type *)
+ bfd_alloc (abfd,
+ sizeof (oasys_reloc_type));
+ if (!r)
+ return false;
+ *(per->reloc_tail_ptr) = r;
+ per->reloc_tail_ptr = &r->next;
+ r->next = (oasys_reloc_type *) NULL;
+ /* Reference to undefined symbol */
+ src++;
+ /* There is no symbol */
+ r->symbol = 0;
+ /* Work out the howto */
+ abort ();
+#if 0
+ r->relent.section =
+ data->sections[reloc &
+ RELOCATION_SECT_BITS];
+
+ r->relent.addend = -
+ r->relent.section->vma;
+#endif
+ r->relent.address = dst_ptr - dst_base_ptr;
+ r->relent.howto = &howto_table[reloc >> 6];
+ r->relent.sym_ptr_ptr = (asymbol **) NULL;
+ section->reloc_count++;
+
+ /* Fake up the data to look like it's got the -ve pc in it, this makes
+ it much easier to convert into other formats. This is done by
+ hitting the addend.
+ */
+ if (r->relent.howto->pc_relative == true)
+ {
+ r->relent.addend -= dst_ptr - dst_base_ptr;
+ }
+
+
+ }
+ break;
+
+
+ case RELOCATION_TYPE_UND:
+ {
+ oasys_reloc_type *r =
+ (oasys_reloc_type *)
+ bfd_alloc (abfd,
+ sizeof (oasys_reloc_type));
+ if (!r)
+ return false;
+ *(per->reloc_tail_ptr) = r;
+ per->reloc_tail_ptr = &r->next;
+ r->next = (oasys_reloc_type *) NULL;
+ /* Reference to undefined symbol */
+ src++;
+ /* Get symbol number */
+ r->symbol = (src[0] << 8) | src[1];
+ /* Work out the howto */
+ abort ();
+
+#if 0
+ r->relent.section = (asection
+ *) NULL;
+#endif
+ r->relent.addend = 0;
+ r->relent.address = dst_ptr - dst_base_ptr;
+ r->relent.howto = &howto_table[reloc >> 6];
+ r->relent.sym_ptr_ptr = (asymbol **) NULL;
+ section->reloc_count++;
+
+ src += 2;
+ /* Fake up the data to look like it's got the -ve pc in it, this makes
+ it much easier to convert into other formats. This is done by
+ hitting the addend.
+ */
+ if (r->relent.howto->pc_relative == true)
+ {
+ r->relent.addend -= dst_ptr - dst_base_ptr;
+ }
+
+
+
+ }
+ break;
+ case RELOCATION_TYPE_COM:
+ BFD_FAIL ();
+ }
+ }
+ *dst_ptr++ = *src++;
+ }
+ }
+ }
+ }
+ break;
+ case oasys_record_is_local_enum:
+ case oasys_record_is_symbol_enum:
+ case oasys_record_is_section_enum:
+ break;
+ default:
+ loop = false;
+ }
+ }
+
+ return true;
+
+}
+
+static boolean
+oasys_new_section_hook (abfd, newsect)
+ bfd *abfd;
+ asection *newsect;
+{
+ newsect->used_by_bfd = (PTR)
+ bfd_alloc (abfd, sizeof (oasys_per_section_type));
+ if (!newsect->used_by_bfd)
+ return false;
+ oasys_per_section (newsect)->data = (bfd_byte *) NULL;
+ oasys_per_section (newsect)->section = newsect;
+ oasys_per_section (newsect)->offset = 0;
+ oasys_per_section (newsect)->initialized = false;
+ newsect->alignment_power = 1;
+ /* Turn the section string into an index */
+
+ sscanf (newsect->name, "%u", &newsect->target_index);
+
+ return true;
+}
+
+
+static long
+oasys_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ if (! oasys_slurp_section_data (abfd))
+ return -1;
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+static boolean
+oasys_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
+ oasys_slurp_section_data (abfd);
+ if (p->initialized == false)
+ {
+ (void) memset (location, 0, (int) count);
+ }
+ else
+ {
+ (void) memcpy (location, (PTR) (p->data + offset), (int) count);
+ }
+ return true;
+}
+
+
+long
+oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols)
+ bfd *ignore_abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ unsigned int reloc_count = 0;
+ oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
+ while (src != (oasys_reloc_type *) NULL)
+ {
+ abort ();
+
+#if 0
+ if (src->relent.section == (asection *) NULL)
+ {
+ src->relent.sym_ptr_ptr = symbols + src->symbol;
+ }
+#endif
+
+ *relptr++ = &src->relent;
+ src = src->next;
+ reloc_count++;
+ }
+ *relptr = (arelent *) NULL;
+ return section->reloc_count = reloc_count;
+}
+
+
+
+
+/* Writing */
+
+
+/* Calculate the checksum and write one record */
+static boolean
+oasys_write_record (abfd, type, record, size)
+ bfd *abfd;
+ oasys_record_enum_type type;
+ oasys_record_union_type *record;
+ size_t size;
+{
+ int checksum;
+ size_t i;
+ unsigned char *ptr;
+
+ record->header.length = size;
+ record->header.type = (int) type;
+ record->header.check_sum = 0;
+ record->header.fill = 0;
+ ptr = (unsigned char *) &record->pad[0];
+ checksum = 0;
+ for (i = 0; i < size; i++)
+ {
+ checksum += *ptr++;
+ }
+ record->header.check_sum = 0xff & (-checksum);
+ if (bfd_write ((PTR) record, 1, size, abfd) != size)
+ return false;
+ return true;
+}
+
+
+/* Write out all the symbols */
+static boolean
+oasys_write_syms (abfd)
+ bfd *abfd;
+{
+ unsigned int count;
+ asymbol **generic = bfd_get_outsymbols (abfd);
+ unsigned int index = 0;
+ for (count = 0; count < bfd_get_symcount (abfd); count++)
+ {
+
+ oasys_symbol_record_type symbol;
+ asymbol *CONST g = generic[count];
+
+ CONST char *src = g->name;
+ char *dst = symbol.name;
+ unsigned int l = 0;
+
+ if (bfd_is_com_section (g->section))
+ {
+ symbol.relb = RELOCATION_TYPE_COM;
+ bfd_h_put_16 (abfd, index, symbol.refno);
+ index++;
+ }
+ else if (bfd_is_abs_section (g->section))
+ {
+ symbol.relb = RELOCATION_TYPE_ABS;
+ bfd_h_put_16 (abfd, 0, symbol.refno);
+
+ }
+ else if (bfd_is_und_section (g->section))
+ {
+ symbol.relb = RELOCATION_TYPE_UND;
+ bfd_h_put_16 (abfd, index, symbol.refno);
+ /* Overload the value field with the output index number */
+ index++;
+ }
+ else if (g->flags & BSF_DEBUGGING)
+ {
+ /* throw it away */
+ continue;
+ }
+ else
+ {
+ if (g->section == (asection *) NULL)
+ {
+ /* Sometime, the oasys tools give out a symbol with illegal
+ bits in it, we'll output it in the same broken way */
+
+ symbol.relb = RELOCATION_TYPE_REL | 0;
+ }
+ else
+ {
+ symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index;
+ }
+ bfd_h_put_16 (abfd, 0, symbol.refno);
+ }
+#ifdef UNDERSCORE_HACK
+ if (src[l] == '_')
+ dst[l++] = '.';
+#endif
+ while (src[l])
+ {
+ dst[l] = src[l];
+ l++;
+ }
+
+ bfd_h_put_32 (abfd, g->value, symbol.value);
+
+
+ if (g->flags & BSF_LOCAL)
+ {
+ if (! oasys_write_record (abfd,
+ oasys_record_is_local_enum,
+ (oasys_record_union_type *) & symbol,
+ offsetof (oasys_symbol_record_type,
+ name[0]) + l))
+ return false;
+ }
+ else
+ {
+ if (! oasys_write_record (abfd,
+ oasys_record_is_symbol_enum,
+ (oasys_record_union_type *) & symbol,
+ offsetof (oasys_symbol_record_type,
+ name[0]) + l))
+ return false;
+ }
+ g->value = index - 1;
+ }
+
+ return true;
+}
+
+
+ /* Write a section header for each section */
+static boolean
+oasys_write_sections (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ static oasys_section_record_type out;
+
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ if (!isdigit ((unsigned char) s->name[0]))
+ {
+ (*_bfd_error_handler)
+ (_("%s: can not represent section `%s' in oasys"),
+ bfd_get_filename (abfd), s->name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ out.relb = RELOCATION_TYPE_REL | s->target_index;
+ bfd_h_put_32 (abfd, s->_cooked_size, out.value);
+ bfd_h_put_32 (abfd, s->vma, out.vma);
+
+ if (! oasys_write_record (abfd,
+ oasys_record_is_section_enum,
+ (oasys_record_union_type *) & out,
+ sizeof (out)))
+ return false;
+ }
+ return true;
+}
+
+static boolean
+oasys_write_header (abfd)
+ bfd *abfd;
+{
+ /* Create and write the header */
+ oasys_header_record_type r;
+ size_t length = strlen (abfd->filename);
+ if (length > (size_t) sizeof (r.module_name))
+ {
+ length = sizeof (r.module_name);
+ }
+
+ (void) memcpy (r.module_name,
+ abfd->filename,
+ length);
+ (void) memset (r.module_name + length,
+ ' ',
+ sizeof (r.module_name) - length);
+
+ r.version_number = OASYS_VERSION_NUMBER;
+ r.rev_number = OASYS_REV_NUMBER;
+ if (! oasys_write_record (abfd,
+ oasys_record_is_header_enum,
+ (oasys_record_union_type *) & r,
+ offsetof (oasys_header_record_type,
+ description[0])))
+ return false;
+
+ return true;
+}
+
+static boolean
+oasys_write_end (abfd)
+ bfd *abfd;
+{
+ oasys_end_record_type end;
+ unsigned char null = 0;
+ end.relb = RELOCATION_TYPE_ABS;
+ bfd_h_put_32 (abfd, abfd->start_address, end.entry);
+ bfd_h_put_16 (abfd, 0, end.fill);
+ end.zero = 0;
+ if (! oasys_write_record (abfd,
+ oasys_record_is_end_enum,
+ (oasys_record_union_type *) & end,
+ sizeof (end)))
+ return false;
+ if (bfd_write ((PTR) & null, 1, 1, abfd) != 1)
+ return false;
+ return true;
+}
+
+static int
+comp (ap, bp)
+ CONST PTR ap;
+ CONST PTR bp;
+{
+ arelent *a = *((arelent **) ap);
+ arelent *b = *((arelent **) bp);
+ return a->address - b->address;
+}
+
+/*
+ Writing data..
+
+*/
+static boolean
+oasys_write_data (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_byte *raw_data = oasys_per_section (s)->data;
+ oasys_data_record_type processed_data;
+ bfd_size_type current_byte_index = 0;
+ unsigned int relocs_to_go = s->reloc_count;
+ arelent **p = s->orelocation;
+ if (s->reloc_count != 0)
+ {
+/* Sort the reloc records so it's easy to insert the relocs into the
+ data */
+
+ qsort (s->orelocation,
+ s->reloc_count,
+ sizeof (arelent **),
+ comp);
+ }
+ current_byte_index = 0;
+ processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
+
+ while (current_byte_index < s->_cooked_size)
+ {
+ /* Scan forwards by eight bytes or however much is left and see if
+ there are any relocations going on */
+ bfd_byte *mod = &processed_data.data[0];
+ bfd_byte *dst = &processed_data.data[1];
+
+ unsigned int i = 0;
+ *mod = 0;
+
+
+ bfd_h_put_32 (abfd, s->vma + current_byte_index,
+ processed_data.addr);
+
+ /* Don't start a relocation unless you're sure you can finish it
+ within the same data record. The worst case relocation is a
+ 4-byte relocatable value which is split across two modification
+ bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
+ 1 modification byte + 2 data = 8 bytes total). That's where
+ the magic number 8 comes from.
+ */
+ while (current_byte_index < s->_raw_size && dst <=
+ &processed_data.data[sizeof (processed_data.data) - 8])
+ {
+
+
+ if (relocs_to_go != 0)
+ {
+ arelent *r = *p;
+ reloc_howto_type *const how = r->howto;
+ /* There is a relocation, is it for this byte ? */
+ if (r->address == current_byte_index)
+ {
+ unsigned char rel_byte;
+
+ p++;
+ relocs_to_go--;
+
+ *mod |= (1 << i);
+ if (how->pc_relative)
+ {
+ rel_byte = RELOCATION_PCREL_BIT;
+
+ /* Also patch the raw data so that it doesn't have
+ the -ve stuff any more */
+ if (how->size != 2)
+ {
+ bfd_put_16 (abfd,
+ bfd_get_16 (abfd, raw_data) +
+ current_byte_index, raw_data);
+ }
+
+ else
+ {
+ bfd_put_32 (abfd,
+ bfd_get_32 (abfd, raw_data) +
+ current_byte_index, raw_data);
+ }
+ }
+ else
+ {
+ rel_byte = 0;
+ }
+ if (how->size == 2)
+ {
+ rel_byte |= RELOCATION_32BIT_BIT;
+ }
+
+ /* Is this a section relative relocation, or a symbol
+ relative relocation ? */
+ abort ();
+
+#if 0
+ if (r->section != (asection *) NULL)
+ {
+ /* The relent has a section attached, so it must be section
+ relative */
+ rel_byte |= RELOCATION_TYPE_REL;
+ rel_byte |= r->section->output_section->target_index;
+ *dst++ = rel_byte;
+ }
+ else
+#endif
+ {
+ asymbol *p = *(r->sym_ptr_ptr);
+
+ /* If this symbol has a section attached, then it
+ has already been resolved. Change from a symbol
+ ref to a section ref */
+ if (p->section != (asection *) NULL)
+ {
+ rel_byte |= RELOCATION_TYPE_REL;
+ rel_byte |=
+ p->section->output_section->target_index;
+ *dst++ = rel_byte;
+ }
+ else
+ {
+ rel_byte |= RELOCATION_TYPE_UND;
+ *dst++ = rel_byte;
+ /* Next two bytes are a symbol index - we can get
+ this from the symbol value which has been zapped
+ into the symbol index in the table when the
+ symbol table was written
+ */
+ *dst++ = p->value >> 8;
+ *dst++ = p->value;
+ }
+ }
+#define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; }
+ /* relocations never occur from an unloadable section,
+ so we can assume that raw_data is not NULL
+ */
+ *dst++ = *raw_data++;
+ ADVANCE
+ * dst++ = *raw_data++;
+ ADVANCE
+ if (how->size == 2)
+ {
+ *dst++ = *raw_data++;
+ ADVANCE
+ * dst++ = *raw_data++;
+ ADVANCE
+ }
+ continue;
+ }
+ }
+ /* If this is coming from an unloadable section then copy
+ zeros */
+ if (raw_data == NULL)
+ {
+ *dst++ = 0;
+ }
+ else
+ {
+ *dst++ = *raw_data++;
+ }
+ ADVANCE
+ }
+
+ /* Don't write a useless null modification byte */
+ if (dst == mod + 1)
+ {
+ --dst;
+ }
+
+ if (! oasys_write_record (abfd,
+ oasys_record_is_data_enum,
+ ((oasys_record_union_type *)
+ & processed_data),
+ dst - (bfd_byte *) & processed_data))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+static boolean
+oasys_write_object_contents (abfd)
+ bfd *abfd;
+{
+ if (! oasys_write_header (abfd))
+ return false;
+ if (! oasys_write_syms (abfd))
+ return false;
+ if (! oasys_write_sections (abfd))
+ return false;
+ if (! oasys_write_data (abfd))
+ return false;
+ if (! oasys_write_end (abfd))
+ return false;
+ return true;
+}
+
+
+
+
+/** exec and core file sections */
+
+/* set section contents is complicated with OASYS since the format is
+* not a byte image, but a record stream.
+*/
+static boolean
+oasys_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (count != 0)
+ {
+ if (oasys_per_section (section)->data == (bfd_byte *) NULL)
+ {
+ oasys_per_section (section)->data =
+ (bfd_byte *) (bfd_alloc (abfd, section->_cooked_size));
+ if (!oasys_per_section (section)->data)
+ return false;
+ }
+ (void) memcpy ((PTR) (oasys_per_section (section)->data + offset),
+ location,
+ (size_t) count);
+ }
+ return true;
+}
+
+
+
+/* Native-level interface to symbols. */
+
+/* We read the symbols into a buffer, which is discarded when this
+function exits. We read the strings into a buffer large enough to
+hold them all plus all the cached symbol entries. */
+
+static asymbol *
+oasys_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+
+ oasys_symbol_type *new =
+ (oasys_symbol_type *) bfd_zalloc (abfd, sizeof (oasys_symbol_type));
+ if (!new)
+ return NULL;
+ new->symbol.the_bfd = abfd;
+ return &new->symbol;
+}
+
+
+
+
+/* User should have checked the file flags; perhaps we should return
+BFD_NO_MORE_SYMBOLS if there are none? */
+
+static bfd *
+oasys_openr_next_archived_file (arch, prev)
+ bfd *arch;
+ bfd *prev;
+{
+ oasys_ar_data_type *ar = OASYS_AR_DATA (arch);
+ oasys_module_info_type *p;
+ /* take the next one from the arch state, or reset */
+ if (prev == (bfd *) NULL)
+ {
+ /* Reset the index - the first two entries are bogus*/
+ ar->module_index = 0;
+ }
+
+ p = ar->module + ar->module_index;
+ ar->module_index++;
+
+ if (ar->module_index <= ar->module_count)
+ {
+ if (p->abfd == (bfd *) NULL)
+ {
+ p->abfd = _bfd_create_empty_archive_element_shell (arch);
+ p->abfd->origin = p->pos;
+ p->abfd->filename = p->name;
+
+ /* Fixup a pointer to this element for the member */
+ p->abfd->arelt_data = (PTR) p;
+ }
+ return p->abfd;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return (bfd *) NULL;
+ }
+}
+
+static boolean
+oasys_find_nearest_line (abfd,
+ section,
+ symbols,
+ offset,
+ filename_ptr,
+ functionname_ptr,
+ line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ char **filename_ptr;
+ char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ return false;
+
+}
+
+static int
+oasys_generic_stat_arch_elt (abfd, buf)
+ bfd *abfd;
+ struct stat *buf;
+{
+ oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
+ if (mod == (oasys_module_info_type *) NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+ else
+ {
+ buf->st_size = mod->size;
+ buf->st_mode = 0666;
+ return 0;
+ }
+}
+
+static int
+oasys_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return 0;
+}
+
+#define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
+#define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+
+#define oasys_slurp_armap bfd_true
+#define oasys_slurp_extended_name_table bfd_true
+#define oasys_construct_extended_name_table \
+ ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \
+ bfd_true)
+#define oasys_truncate_arname bfd_dont_truncate_arname
+#define oasys_write_armap \
+ ((boolean (*) \
+ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
+ bfd_true)
+#define oasys_read_ar_hdr bfd_nullvoidptr
+#define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
+#define oasys_update_armap_timestamp bfd_true
+
+#define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define oasys_get_lineno _bfd_nosymbols_get_lineno
+#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define oasys_read_minisymbols _bfd_generic_read_minisymbols
+#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define oasys_set_arch_mach bfd_default_set_arch_mach
+
+#define oasys_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#define oasys_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define oasys_bfd_relax_section bfd_generic_relax_section
+#define oasys_bfd_gc_sections bfd_generic_gc_sections
+#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define oasys_bfd_final_link _bfd_generic_final_link
+#define oasys_bfd_link_split_section _bfd_generic_link_split_section
+
+/*SUPPRESS 460 */
+const bfd_target oasys_vec =
+{
+ "oasys", /* name */
+ bfd_target_oasys_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {_bfd_dummy_target,
+ oasys_object_p, /* bfd_check_format */
+ oasys_archive_p,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format */
+ bfd_false,
+ oasys_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ oasys_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (oasys),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (oasys),
+ BFD_JUMP_TABLE_SYMBOLS (oasys),
+ BFD_JUMP_TABLE_RELOCS (oasys),
+ BFD_JUMP_TABLE_WRITE (oasys),
+ BFD_JUMP_TABLE_LINK (oasys),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/opncls.c b/bfd/opncls.c
new file mode 100644
index 00000000000..8f10135d267
--- /dev/null
+++ b/bfd/opncls.c
@@ -0,0 +1,683 @@
+/* opncls.c -- open and close a BFD.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "objalloc.h"
+#include "libbfd.h"
+
+#ifndef S_IXUSR
+#define S_IXUSR 0100 /* Execute by owner. */
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0010 /* Execute by group. */
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001 /* Execute by others. */
+#endif
+
+/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
+ if we do that we can't use fcntl. */
+
+/* FIXME: This is no longer used. */
+long _bfd_chunksize = -1;
+
+/* Return a new BFD. All BFD's are allocated through this routine. */
+
+bfd *
+_bfd_new_bfd ()
+{
+ bfd *nbfd;
+
+ nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
+ if (nbfd == NULL)
+ return NULL;
+
+ nbfd->memory = (PTR) objalloc_create ();
+ if (nbfd->memory == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ nbfd->arch_info = &bfd_default_arch_struct;
+
+ nbfd->direction = no_direction;
+ nbfd->iostream = NULL;
+ nbfd->where = 0;
+ nbfd->sections = (asection *) NULL;
+ nbfd->format = bfd_unknown;
+ nbfd->my_archive = (bfd *) NULL;
+ nbfd->origin = 0;
+ nbfd->opened_once = false;
+ nbfd->output_has_begun = false;
+ nbfd->section_count = 0;
+ nbfd->usrdata = (PTR) NULL;
+ nbfd->cacheable = false;
+ nbfd->flags = BFD_NO_FLAGS;
+ nbfd->mtime_set = false;
+
+ return nbfd;
+}
+
+/* Allocate a new BFD as a member of archive OBFD. */
+
+bfd *
+_bfd_new_bfd_contained_in (obfd)
+ bfd *obfd;
+{
+ bfd *nbfd;
+
+ nbfd = _bfd_new_bfd ();
+ nbfd->xvec = obfd->xvec;
+ nbfd->my_archive = obfd;
+ nbfd->direction = read_direction;
+ nbfd->target_defaulted = obfd->target_defaulted;
+ return nbfd;
+}
+
+/*
+SECTION
+ Opening and closing BFDs
+
+*/
+
+/*
+FUNCTION
+ bfd_openr
+
+SYNOPSIS
+ bfd *bfd_openr(CONST char *filename, CONST char *target);
+
+DESCRIPTION
+ Open the file @var{filename} (using <<fopen>>) with the target
+ @var{target}. Return a pointer to the created BFD.
+
+ Calls <<bfd_find_target>>, so @var{target} is interpreted as by
+ that function.
+
+ If <<NULL>> is returned then an error has occured. Possible errors
+ are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
+*/
+
+bfd *
+bfd_openr (filename, target)
+ CONST char *filename;
+ CONST char *target;
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ bfd_set_error (bfd_error_invalid_target);
+ return NULL;
+ }
+
+ nbfd->filename = filename;
+ nbfd->direction = read_direction;
+
+ if (bfd_open_file (nbfd) == NULL)
+ {
+ /* File didn't exist, or some such */
+ bfd_set_error (bfd_error_system_call);
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ return nbfd;
+}
+
+/* Don't try to `optimize' this function:
+
+ o - We lock using stack space so that interrupting the locking
+ won't cause a storage leak.
+ o - We open the file stream last, since we don't want to have to
+ close it if anything goes wrong. Closing the stream means closing
+ the file descriptor too, even though we didn't open it.
+ */
+/*
+FUNCTION
+ bfd_fdopenr
+
+SYNOPSIS
+ bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
+
+DESCRIPTION
+ <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
+ It opens a BFD on a file already described by the @var{fd}
+ supplied.
+
+ When the file is later <<bfd_close>>d, the file descriptor will be closed.
+
+ If the caller desires that this file descriptor be cached by BFD
+ (opened as needed, closed as needed to free descriptors for
+ other opens), with the supplied @var{fd} used as an initial
+ file descriptor (but subject to closure at any time), call
+ bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to
+ assume no cacheing; the file descriptor will remain open until
+ <<bfd_close>>, and will not be affected by BFD operations on other
+ files.
+
+ Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
+*/
+
+bfd *
+bfd_fdopenr (filename, target, fd)
+ CONST char *filename;
+ CONST char *target;
+ int fd;
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+ int fdflags;
+
+ bfd_set_error (bfd_error_system_call);
+#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
+ fdflags = O_RDWR; /* Assume full access */
+#else
+ fdflags = fcntl (fd, F_GETFL, NULL);
+#endif
+ if (fdflags == -1) return NULL;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_target);
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+#ifndef HAVE_FDOPEN
+ nbfd->iostream = (PTR) fopen (filename, FOPEN_RB);
+#else
+ /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
+ switch (fdflags & (O_ACCMODE))
+ {
+ case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
+ case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
+ case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
+ default: abort ();
+ }
+#endif
+
+ if (nbfd->iostream == NULL)
+ {
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ /* OK, put everything where it belongs */
+
+ nbfd->filename = filename;
+
+ /* As a special case we allow a FD open for read/write to
+ be written through, although doing so requires that we end
+ the previous clause with a preposition. */
+ /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
+ switch (fdflags & O_ACCMODE)
+ {
+ case O_RDONLY: nbfd->direction = read_direction; break;
+ case O_WRONLY: nbfd->direction = write_direction; break;
+ case O_RDWR: nbfd->direction = both_direction; break;
+ default: abort ();
+ }
+
+ if (! bfd_cache_init (nbfd))
+ {
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+ nbfd->opened_once = true;
+
+ return nbfd;
+}
+
+/*
+FUNCTION
+ bfd_openstreamr
+
+SYNOPSIS
+ bfd *bfd_openstreamr(const char *, const char *, PTR);
+
+DESCRIPTION
+
+ Open a BFD for read access on an existing stdio stream. When
+ the BFD is passed to <<bfd_close>>, the stream will be closed.
+*/
+
+bfd *
+bfd_openstreamr (filename, target, streamarg)
+ const char *filename;
+ const char *target;
+ PTR streamarg;
+{
+ FILE *stream = (FILE *) streamarg;
+ bfd *nbfd;
+ const bfd_target *target_vec;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_target);
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ nbfd->iostream = (PTR) stream;
+ nbfd->filename = filename;
+ nbfd->direction = read_direction;
+
+ if (! bfd_cache_init (nbfd))
+ {
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ return nbfd;
+}
+
+/** bfd_openw -- open for writing.
+ Returns a pointer to a freshly-allocated BFD on success, or NULL.
+
+ See comment by bfd_fdopenr before you try to modify this function. */
+
+/*
+FUNCTION
+ bfd_openw
+
+SYNOPSIS
+ bfd *bfd_openw(CONST char *filename, CONST char *target);
+
+DESCRIPTION
+ Create a BFD, associated with file @var{filename}, using the
+ file format @var{target}, and return a pointer to it.
+
+ Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
+ <<bfd_error_invalid_target>>.
+*/
+
+bfd *
+bfd_openw (filename, target)
+ CONST char *filename;
+ CONST char *target;
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+
+ bfd_set_error (bfd_error_system_call);
+
+ /* nbfd has to point to head of malloc'ed block so that bfd_close may
+ reclaim it correctly. */
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ nbfd->filename = filename;
+ nbfd->direction = write_direction;
+
+ if (bfd_open_file (nbfd) == NULL)
+ {
+ bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
+ objalloc_free ((struct objalloc *) nbfd->memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ return nbfd;
+}
+
+/*
+
+FUNCTION
+ bfd_close
+
+SYNOPSIS
+ boolean bfd_close(bfd *abfd);
+
+DESCRIPTION
+
+ Close a BFD. If the BFD was open for writing,
+ then pending operations are completed and the file written out
+ and closed. If the created file is executable, then
+ <<chmod>> is called to mark it as such.
+
+ All memory attached to the BFD is released.
+
+ The file descriptor associated with the BFD is closed (even
+ if it was passed in to BFD by <<bfd_fdopenr>>).
+
+RETURNS
+ <<true>> is returned if all is ok, otherwise <<false>>.
+*/
+
+
+boolean
+bfd_close (abfd)
+ bfd *abfd;
+{
+ boolean ret;
+
+ if (!bfd_read_p (abfd))
+ {
+ if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
+ return false;
+ }
+
+ if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
+ return false;
+
+ ret = bfd_cache_close (abfd);
+
+ /* If the file was open for writing and is now executable,
+ make it so */
+ if (ret
+ && abfd->direction == write_direction
+ && abfd->flags & EXEC_P)
+ {
+ struct stat buf;
+
+ if (stat (abfd->filename, &buf) == 0)
+ {
+ int mask = umask (0);
+ umask (mask);
+ chmod (abfd->filename,
+ (0777
+ & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
+ }
+ }
+
+ objalloc_free ((struct objalloc *) abfd->memory);
+ free (abfd);
+
+ return ret;
+}
+
+/*
+FUNCTION
+ bfd_close_all_done
+
+SYNOPSIS
+ boolean bfd_close_all_done(bfd *);
+
+DESCRIPTION
+ Close a BFD. Differs from <<bfd_close>>
+ since it does not complete any pending operations. This
+ routine would be used if the application had just used BFD for
+ swapping and didn't want to use any of the writing code.
+
+ If the created file is executable, then <<chmod>> is called
+ to mark it as such.
+
+ All memory attached to the BFD is released.
+
+RETURNS
+ <<true>> is returned if all is ok, otherwise <<false>>.
+
+*/
+
+boolean
+bfd_close_all_done (abfd)
+ bfd *abfd;
+{
+ boolean ret;
+
+ ret = bfd_cache_close (abfd);
+
+ /* If the file was open for writing and is now executable,
+ make it so */
+ if (ret
+ && abfd->direction == write_direction
+ && abfd->flags & EXEC_P)
+ {
+ struct stat buf;
+
+ if (stat (abfd->filename, &buf) == 0)
+ {
+ int mask = umask (0);
+ umask (mask);
+ chmod (abfd->filename,
+ (0x777
+ & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
+ }
+ }
+
+ objalloc_free ((struct objalloc *) abfd->memory);
+ free (abfd);
+
+ return ret;
+}
+
+/*
+FUNCTION
+ bfd_create
+
+SYNOPSIS
+ bfd *bfd_create(CONST char *filename, bfd *templ);
+
+DESCRIPTION
+ Create a new BFD in the manner of
+ <<bfd_openw>>, but without opening a file. The new BFD
+ takes the target from the target used by @var{template}. The
+ format is always set to <<bfd_object>>.
+
+*/
+
+bfd *
+bfd_create (filename, templ)
+ CONST char *filename;
+ bfd *templ;
+{
+ bfd *nbfd;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+ nbfd->filename = filename;
+ if (templ)
+ nbfd->xvec = templ->xvec;
+ nbfd->direction = no_direction;
+ bfd_set_format (nbfd, bfd_object);
+ return nbfd;
+}
+
+/*
+FUNCTION
+ bfd_make_writable
+
+SYNOPSIS
+ boolean bfd_make_writable(bfd *abfd);
+
+DESCRIPTION
+ Takes a BFD as created by <<bfd_create>> and converts it
+ into one like as returned by <<bfd_openw>>. It does this
+ by converting the BFD to BFD_IN_MEMORY. It's assumed that
+ you will call <<bfd_make_readable>> on this bfd later.
+
+RETURNS
+ <<true>> is returned if all is ok, otherwise <<false>>.
+*/
+
+boolean
+bfd_make_writable(abfd)
+ bfd *abfd;
+{
+ struct bfd_in_memory *bim;
+
+ if (abfd->direction != no_direction)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory));
+ abfd->iostream = (PTR) bim;
+ /* bfd_write will grow these as needed */
+ bim->size = 0;
+ bim->buffer = 0;
+
+ abfd->flags |= BFD_IN_MEMORY;
+ abfd->direction = write_direction;
+ abfd->where = 0;
+
+ return true;
+}
+
+/*
+FUNCTION
+ bfd_make_readable
+
+SYNOPSIS
+ boolean bfd_make_readable(bfd *abfd);
+
+DESCRIPTION
+ Takes a BFD as created by <<bfd_create>> and
+ <<bfd_make_writable>> and converts it into one like as
+ returned by <<bfd_openr>>. It does this by writing the
+ contents out to the memory buffer, then reversing the
+ direction.
+
+RETURNS
+ <<true>> is returned if all is ok, otherwise <<false>>. */
+
+boolean
+bfd_make_readable(abfd)
+ bfd *abfd;
+{
+ if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
+ return false;
+
+ if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
+ return false;
+
+
+ abfd->arch_info = &bfd_default_arch_struct;
+
+ abfd->where = 0;
+ abfd->sections = (asection *) NULL;
+ abfd->format = bfd_unknown;
+ abfd->my_archive = (bfd *) NULL;
+ abfd->origin = 0;
+ abfd->opened_once = false;
+ abfd->output_has_begun = false;
+ abfd->section_count = 0;
+ abfd->usrdata = (PTR) NULL;
+ abfd->cacheable = false;
+ abfd->flags = BFD_IN_MEMORY;
+ abfd->mtime_set = false;
+
+ abfd->target_defaulted = true;
+ abfd->direction = read_direction;
+ abfd->sections = 0;
+ abfd->symcount = 0;
+ abfd->outsymbols = 0;
+ abfd->tdata.any = 0;
+
+ bfd_check_format(abfd, bfd_object);
+
+ return true;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_alloc
+
+SYNOPSIS
+ PTR bfd_alloc (bfd *abfd, size_t wanted);
+
+DESCRIPTION
+ Allocate a block of @var{wanted} bytes of memory attached to
+ <<abfd>> and return a pointer to it.
+*/
+
+
+PTR
+bfd_alloc (abfd, size)
+ bfd *abfd;
+ size_t size;
+{
+ PTR ret;
+
+ ret = objalloc_alloc (abfd->memory, (unsigned long) size);
+ if (ret == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
+}
+
+PTR
+bfd_zalloc (abfd, size)
+ bfd *abfd;
+ size_t size;
+{
+ PTR res;
+
+ res = bfd_alloc (abfd, size);
+ if (res)
+ memset (res, 0, size);
+ return res;
+}
+
+/* Free a block allocated for a BFD. */
+
+void
+bfd_release (abfd, block)
+ bfd *abfd;
+ PTR block;
+{
+ objalloc_free_block ((struct objalloc *) abfd->memory, block);
+}
diff --git a/bfd/osf-core.c b/bfd/osf-core.c
new file mode 100644
index 00000000000..671f4af495c
--- /dev/null
+++ b/bfd/osf-core.c
@@ -0,0 +1,254 @@
+/* BFD back-end for OSF/1 core files.
+ Copyright 1993, 94, 95, 97, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file can only be compiled on systems which use OSF/1 style
+ core files. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include <sys/user.h>
+#include <sys/core.h>
+
+/* forward declarations */
+
+static asection *
+make_bfd_asection PARAMS ((bfd *, CONST char *, flagword, bfd_size_type,
+ bfd_vma, file_ptr));
+static asymbol *
+osf_core_make_empty_symbol PARAMS ((bfd *));
+static const bfd_target *
+osf_core_core_file_p PARAMS ((bfd *));
+static char *
+osf_core_core_file_failing_command PARAMS ((bfd *));
+static int
+osf_core_core_file_failing_signal PARAMS ((bfd *));
+static boolean
+osf_core_core_file_matches_executable_p PARAMS ((bfd *, bfd *));
+static void
+swap_abort PARAMS ((void));
+
+/* These are stored in the bfd's tdata */
+
+struct osf_core_struct
+{
+ int sig;
+ char cmd[MAXCOMLEN + 1];
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.osf_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+ bfd *abfd;
+ CONST char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ bfd_vma vma;
+ file_ptr filepos;
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway (abfd, name);
+ if (!asect)
+ return NULL;
+
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 8;
+
+ return asect;
+}
+
+static asymbol *
+osf_core_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+static const bfd_target *
+osf_core_core_file_p (abfd)
+ bfd *abfd;
+{
+ int val;
+ int i;
+ char *secname;
+ struct core_filehdr core_header;
+
+ val = bfd_read ((PTR)&core_header, 1, sizeof core_header, abfd);
+ if (val != sizeof core_header)
+ return NULL;
+
+ if (strncmp (core_header.magic, "Core", 4) != 0)
+ return NULL;
+
+ core_hdr (abfd) = (struct osf_core_struct *)
+ bfd_zalloc (abfd, sizeof (struct osf_core_struct));
+ if (!core_hdr (abfd))
+ return NULL;
+
+ strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1);
+ core_signal (abfd) = core_header.signo;
+
+ for (i = 0; i < core_header.nscns; i++)
+ {
+ struct core_scnhdr core_scnhdr;
+ flagword flags;
+
+ val = bfd_read ((PTR)&core_scnhdr, 1, sizeof core_scnhdr, abfd);
+ if (val != sizeof core_scnhdr)
+ break;
+
+ /* Skip empty sections. */
+ if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0)
+ continue;
+
+ switch (core_scnhdr.scntype)
+ {
+ case SCNRGN:
+ secname = ".data";
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ case SCNSTACK:
+ secname = ".stack";
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ case SCNREGS:
+ secname = ".reg";
+ flags = SEC_HAS_CONTENTS;
+ break;
+ default:
+ (*_bfd_error_handler) (_("Unhandled OSF/1 core file section type %d\n"),
+ core_scnhdr.scntype);
+ continue;
+ }
+
+ if (!make_bfd_asection (abfd, secname, flags,
+ (bfd_size_type) core_scnhdr.size,
+ (bfd_vma) core_scnhdr.vaddr,
+ (file_ptr) core_scnhdr.scnptr))
+ return NULL;
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ return abfd->xvec;
+}
+
+static char *
+osf_core_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ return core_command (abfd);
+}
+
+/* ARGSUSED */
+static int
+osf_core_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_signal (abfd);
+}
+
+/* ARGSUSED */
+static boolean
+osf_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this point */
+}
+
+#define osf_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
+#define osf_core_get_symtab _bfd_nosymbols_get_symtab
+#define osf_core_print_symbol _bfd_nosymbols_print_symbol
+#define osf_core_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define osf_core_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
+#define osf_core_get_lineno _bfd_nosymbols_get_lineno
+#define osf_core_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define osf_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define osf_core_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define osf_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target osf_core_vec =
+ {
+ "osf-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ osf_core_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (osf_core),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (osf_core),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
diff --git a/bfd/pc532-mach.c b/bfd/pc532-mach.c
new file mode 100644
index 00000000000..73f4ac49e82
--- /dev/null
+++ b/bfd/pc532-mach.c
@@ -0,0 +1,121 @@
+/* BFD back-end for Mach3/532 a.out-ish binaries.
+ Copyright (C) 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Ian Dall
+ * 19-Apr-94
+ *
+ * Formerly part of aout-pc532-mach.c. Split out to allow more
+ * flexibility with multiple formats.
+ *
+ */
+/* This architecture has N_TXTOFF and N_TXTADDR defined as if
+ * N_HEADER_IN_TEXT, but the a_text entry (text size) does not include the
+ * space for the header. So we have N_HEADER_IN_TEXT defined to
+ * 1 and specially define our own N_TXTSIZE
+ */
+
+#define N_HEADER_IN_TEXT(x) 1
+#define N_TXTSIZE(x) ((x).a_text)
+
+
+#define TEXT_START_ADDR 0x10000 /* from old ld */
+#define TARGET_PAGE_SIZE 0x1000 /* from old ld, 032 & 532 are really 512/4k */
+
+/* Use a_entry of 0 to distinguish object files from OMAGIC executables */
+#define N_TXTADDR(x) \
+ (N_MAGIC(x) == OMAGIC ? \
+ ((x).a_entry < TEXT_START_ADDR? 0: TEXT_START_ADDR): \
+ (N_MAGIC(x) == NMAGIC? TEXT_START_ADDR: \
+ TEXT_START_ADDR + EXEC_BYTES_SIZE))
+
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#define N_SHARED_LIB(x) 0
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_ns32k
+
+#define MY(OP) CAT(pc532machaout_,OP)
+
+/* Must be the same as aout-ns32k.c */
+#define NAME(x,y) CAT3(ns32kaout,_32_,y)
+
+#define TARGETNAME "a.out-pc532-mach"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libaout.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+
+/* We can`t use the MYNS macro here for cpp reasons too subtle for me -- IWD */
+
+#define MY_bfd_reloc_type_lookup ns32kaout_bfd_reloc_type_lookup
+
+/* libaout doesn't use NAME for these ... */
+
+#define MY_get_section_contents aout_32_get_section_contents
+
+#define MY_text_includes_header 1
+
+#define MY_exec_header_not_counted 1
+
+#define MYNSX(OP) CAT(ns32kaout_,OP)
+reloc_howto_type *
+MYNSX(bfd_reloc_type_lookup)
+ PARAMS((bfd *abfd AND
+ bfd_reloc_code_real_type code));
+
+boolean
+MYNSX(write_object_contents)
+ PARAMS((bfd *abfd));
+
+static boolean
+MY(write_object_contents) (abfd)
+bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+#if CHOOSE_RELOC_SIZE
+ CHOOSE_RELOC_SIZE(abfd);
+#else
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+#endif
+
+ BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_ns32k);
+ switch (bfd_get_mach (abfd))
+ {
+ case 32032:
+ N_SET_MACHTYPE (*execp, M_NS32032);
+ break;
+ case 32532:
+ default:
+ N_SET_MACHTYPE (*execp, M_NS32532);
+ break;
+ }
+ N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
+
+#define MY_write_object_contents MY(write_object_contents)
+
+#include "aout-target.h"
diff --git a/bfd/pe-arm.c b/bfd/pe-arm.c
new file mode 100644
index 00000000000..d315888f1da
--- /dev/null
+++ b/bfd/pe-arm.c
@@ -0,0 +1,34 @@
+/* BFD back-end for ARM PECOFF files.
+ Copyright 1995, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#ifndef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM armpe_little_vec
+#define TARGET_LITTLE_NAME "pe-arm-little"
+#define TARGET_BIG_SYM armpe_big_vec
+#define TARGET_BIG_NAME "pe-arm-big"
+#endif
+
+#define COFF_WITH_PE
+#define PCRELOFFSET true
+#define COFF_LONG_SECTION_NAMES
+
+#include "coff-arm.c"
diff --git a/bfd/pe-i386.c b/bfd/pe-i386.c
new file mode 100644
index 00000000000..bcdbe444994
--- /dev/null
+++ b/bfd/pe-i386.c
@@ -0,0 +1,31 @@
+/* BFD back-end for Intel 386 PECOFF files.
+ Copyright 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+
+#define TARGET_SYM i386pe_vec
+#define TARGET_NAME "pe-i386"
+#define COFF_WITH_PE
+#define PCRELOFFSET true
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+
+#include "coff-i386.c"
diff --git a/bfd/pe-mcore.c b/bfd/pe-mcore.c
new file mode 100644
index 00000000000..8119f815895
--- /dev/null
+++ b/bfd/pe-mcore.c
@@ -0,0 +1,36 @@
+/* BFD back-end for MCore PECOFF files.
+ Copyright 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#ifndef TARGET_BIG_SYM
+#define TARGET_BIG_SYM mcore_pe_big_vec
+#define TARGET_BIG_NAME "pe-mcore-big"
+#define TARGET_LITTLE_SYM mcore_pe_little_vec
+#define TARGET_LITTLE_NAME "pe-mcore-little"
+#endif
+
+#define COFF_WITH_PE
+#define PCRELOFFSET true
+#define COFF_LONG_SECTION_NAMES
+
+#define MCORE_PE
+
+#include "coff-mcore.c"
diff --git a/bfd/pe-ppc.c b/bfd/pe-ppc.c
new file mode 100644
index 00000000000..a2bac04ac6f
--- /dev/null
+++ b/bfd/pe-ppc.c
@@ -0,0 +1,41 @@
+/* BFD back-end for PowerPC PECOFF files.
+ Copyright 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+
+#define E_FILENMLEN 18
+
+#define PPC_PE
+
+#define TARGET_LITTLE_SYM bfd_powerpcle_pe_vec
+#define TARGET_LITTLE_NAME "pe-powerpcle"
+
+#define TARGET_BIG_SYM bfd_powerpc_pe_vec
+#define TARGET_BIG_NAME "pe-powerpc"
+
+#define COFF_WITH_PE
+
+#define COFF_LONG_SECTION_NAMES
+
+/* FIXME: verify PCRELOFFSET is always false */
+
+#include "coff-ppc.c"
diff --git a/bfd/pei-arm.c b/bfd/pei-arm.c
new file mode 100644
index 00000000000..4ba5b3a5cd0
--- /dev/null
+++ b/bfd/pei-arm.c
@@ -0,0 +1,36 @@
+/* BFD back-end for arm PE IMAGE COFF files.
+ Copyright 1995, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#ifndef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM armpei_little_vec
+#define TARGET_LITTLE_NAME "pei-arm-little"
+#define TARGET_BIG_SYM armpei_big_vec
+#define TARGET_BIG_NAME "pei-arm-big"
+#endif
+
+#define IMAGE_BASE NT_IMAGE_BASE
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET true
+#define COFF_LONG_SECTION_NAMES
+
+#include "coff-arm.c"
diff --git a/bfd/pei-i386.c b/bfd/pei-i386.c
new file mode 100644
index 00000000000..8b52968370e
--- /dev/null
+++ b/bfd/pei-i386.c
@@ -0,0 +1,35 @@
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+ Copyright 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define TARGET_SYM i386pei_vec
+#define TARGET_NAME "pei-i386"
+#define IMAGE_BASE NT_IMAGE_BASE
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET true
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+
+#include "coff-i386.c"
+
+
+
diff --git a/bfd/pei-mcore.c b/bfd/pei-mcore.c
new file mode 100644
index 00000000000..d4a872cdfcb
--- /dev/null
+++ b/bfd/pei-mcore.c
@@ -0,0 +1,38 @@
+/* BFD back-end for MCore PECOFF files.
+ Copyright 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#ifndef TARGET_BIG_SYM
+#define TARGET_BIG_SYM mcore_pei_big_vec
+#define TARGET_BIG_NAME "pei-mcore-big"
+#define TARGET_LITTLE_SYM mcore_pei_little_vec
+#define TARGET_LITTLE_NAME "pei-mcore-little"
+#endif
+
+#define IMAGE_BASE NT_IMAGE_BASE
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET true
+#define COFF_LONG_SECTION_NAMES
+
+#define MCORE_PE
+
+#include "coff-mcore.c"
diff --git a/bfd/pei-ppc.c b/bfd/pei-ppc.c
new file mode 100644
index 00000000000..839bc0f64af
--- /dev/null
+++ b/bfd/pei-ppc.c
@@ -0,0 +1,47 @@
+/* BFD back-end for PowerPC PE IMAGE COFF files.
+ Copyright 1995 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+/* setting up for a PE environment stolen directly from the i386 structure */
+#define E_FILNMLEN 18 /* # characters in a file name */
+
+#define PPC_PE
+
+#define TARGET_LITTLE_SYM bfd_powerpcle_pei_vec
+#define TARGET_LITTLE_NAME "pei-powerpcle"
+
+#define TARGET_BIG_SYM bfd_powerpc_pei_vec
+#define TARGET_BIG_NAME "pei-powerpc"
+
+#define IMAGE_BASE NT_IMAGE_BASE
+
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+
+#define COFF_LONG_SECTION_NAMES
+
+/* FIXME: Verify PCRELOFFSET is always false */
+
+#include "coff-ppc.c"
+
+
+
diff --git a/bfd/peicode.h b/bfd/peicode.h
new file mode 100644
index 00000000000..79d16e5abe9
--- /dev/null
+++ b/bfd/peicode.h
@@ -0,0 +1,2144 @@
+/* Support for the generic parts of most COFF variants, for BFD.
+ Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+Most of this hacked by Steve Chamberlain,
+ sac@cygnus.com
+*/
+
+/* Hey look, some documentation [and in a place you expect to find it]!
+
+ The main reference for the pei format is "Microsoft Portable Executable
+ and Common Object File Format Specification 4.1". Get it if you need to
+ do some serious hacking on this code.
+
+ Another reference:
+ "Peering Inside the PE: A Tour of the Win32 Portable Executable
+ File Format", MSJ 1994, Volume 9.
+
+ The *sole* difference between the pe format and the pei format is that the
+ latter has an MSDOS 2.0 .exe header on the front that prints the message
+ "This app must be run under Windows." (or some such).
+ (FIXME: Whether that statement is *really* true or not is unknown.
+ Are there more subtle differences between pe and pei formats?
+ For now assume there aren't. If you find one, then for God sakes
+ document it here!)
+
+ The Microsoft docs use the word "image" instead of "executable" because
+ the former can also refer to a DLL (shared library). Confusion can arise
+ because the `i' in `pei' also refers to "image". The `pe' format can
+ also create images (i.e. executables), it's just that to run on a win32
+ system you need to use the pei format.
+
+ FIXME: Please add more docs here so the next poor fool that has to hack
+ on this code has a chance of getting something accomplished without
+ wasting too much time.
+*/
+
+#ifdef coff_bfd_print_private_bfd_data
+static boolean (*pe_saved_coff_bfd_print_private_bfd_data)
+ PARAMS ((bfd *, PTR))
+ = coff_bfd_print_private_bfd_data;
+#undef coff_bfd_print_private_bfd_data
+#else
+static boolean (*pe_saved_coff_bfd_print_private_bfd_data)
+ PARAMS ((bfd *, PTR))
+ = NULL;
+#endif
+#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
+
+#define coff_mkobject pe_mkobject
+#define coff_mkobject_hook pe_mkobject_hook
+
+#ifndef GET_FCN_LNNOPTR
+#define GET_FCN_LNNOPTR(abfd, ext) \
+ bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+
+#ifndef GET_FCN_ENDNDX
+#define GET_FCN_ENDNDX(abfd, ext) \
+ bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+
+#ifndef PUT_FCN_LNNOPTR
+#define PUT_FCN_LNNOPTR(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+#ifndef PUT_FCN_ENDNDX
+#define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#ifndef GET_LNSZ_LNNO
+#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef GET_LNSZ_SIZE
+#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef PUT_LNSZ_LNNO
+#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef PUT_LNSZ_SIZE
+#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef GET_SCN_SCNLEN
+#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
+#endif
+#ifndef GET_SCN_NRELOC
+#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
+#endif
+#ifndef GET_SCN_NLINNO
+#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
+#endif
+#ifndef PUT_SCN_SCNLEN
+#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
+#endif
+#ifndef PUT_SCN_NRELOC
+#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
+#endif
+#ifndef PUT_SCN_NLINNO
+#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
+#endif
+#ifndef GET_LINENO_LNNO
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
+#endif
+#ifndef PUT_LINENO_LNNO
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
+#endif
+
+/* The f_symptr field in the filehdr is sometimes 64 bits. */
+#ifndef GET_FILEHDR_SYMPTR
+#define GET_FILEHDR_SYMPTR bfd_h_get_32
+#endif
+#ifndef PUT_FILEHDR_SYMPTR
+#define PUT_FILEHDR_SYMPTR bfd_h_put_32
+#endif
+
+/* Some fields in the aouthdr are sometimes 64 bits. */
+#ifndef GET_AOUTHDR_TSIZE
+#define GET_AOUTHDR_TSIZE bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_TSIZE
+#define PUT_AOUTHDR_TSIZE bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_DSIZE
+#define GET_AOUTHDR_DSIZE bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_DSIZE
+#define PUT_AOUTHDR_DSIZE bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_BSIZE
+#define GET_AOUTHDR_BSIZE bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_BSIZE
+#define PUT_AOUTHDR_BSIZE bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_ENTRY
+#define GET_AOUTHDR_ENTRY bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_ENTRY
+#define PUT_AOUTHDR_ENTRY bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_TEXT_START
+#define GET_AOUTHDR_TEXT_START bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_TEXT_START
+#define PUT_AOUTHDR_TEXT_START bfd_h_put_32
+#endif
+#ifndef GET_AOUTHDR_DATA_START
+#define GET_AOUTHDR_DATA_START bfd_h_get_32
+#endif
+#ifndef PUT_AOUTHDR_DATA_START
+#define PUT_AOUTHDR_DATA_START bfd_h_put_32
+#endif
+
+/* Some fields in the scnhdr are sometimes 64 bits. */
+#ifndef GET_SCNHDR_PADDR
+#define GET_SCNHDR_PADDR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_PADDR
+#define PUT_SCNHDR_PADDR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_VADDR
+#define GET_SCNHDR_VADDR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_VADDR
+#define PUT_SCNHDR_VADDR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_SIZE
+#define GET_SCNHDR_SIZE bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_SIZE
+#define PUT_SCNHDR_SIZE bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_SCNPTR
+#define GET_SCNHDR_SCNPTR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_SCNPTR
+#define PUT_SCNHDR_SCNPTR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_RELPTR
+#define GET_SCNHDR_RELPTR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_RELPTR
+#define PUT_SCNHDR_RELPTR bfd_h_put_32
+#endif
+#ifndef GET_SCNHDR_LNNOPTR
+#define GET_SCNHDR_LNNOPTR bfd_h_get_32
+#endif
+#ifndef PUT_SCNHDR_LNNOPTR
+#define PUT_SCNHDR_LNNOPTR bfd_h_put_32
+#endif
+
+static void coff_swap_reloc_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_reloc_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_filehdr_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_sym_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_aux_in PARAMS ((bfd *, PTR, int, int, int, int, PTR));
+static unsigned int coff_swap_aux_out
+ PARAMS ((bfd *, PTR, int, int, int, int, PTR));
+static void coff_swap_lineno_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_lineno_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_aouthdr_in PARAMS ((bfd *, PTR, PTR));
+static void add_data_entry
+ PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));
+static unsigned int coff_swap_aouthdr_out PARAMS ((bfd *, PTR, PTR));
+static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR));
+static unsigned int coff_swap_scnhdr_out PARAMS ((bfd *, PTR, PTR));
+static boolean pe_print_idata PARAMS ((bfd *, PTR));
+static boolean pe_print_edata PARAMS ((bfd *, PTR));
+static boolean pe_print_pdata PARAMS ((bfd *, PTR));
+static boolean pe_print_reloc PARAMS ((bfd *, PTR));
+static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR));
+static boolean pe_mkobject PARAMS ((bfd *));
+static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR));
+static boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+
+/**********************************************************************/
+
+static void
+coff_swap_reloc_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
+ reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
+ reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
+
+ reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
+
+#ifdef SWAP_IN_RELOC_OFFSET
+ reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
+ (bfd_byte *) reloc_src->r_offset);
+#endif
+}
+
+
+static unsigned int
+coff_swap_reloc_out (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ struct internal_reloc *reloc_src = (struct internal_reloc *)src;
+ struct external_reloc *reloc_dst = (struct external_reloc *)dst;
+ bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
+ bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
+
+ bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
+ reloc_dst->r_type);
+
+#ifdef SWAP_OUT_RELOC_OFFSET
+ SWAP_OUT_RELOC_OFFSET(abfd,
+ reloc_src->r_offset,
+ (bfd_byte *) reloc_dst->r_offset);
+#endif
+#ifdef SWAP_OUT_RELOC_EXTRA
+ SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
+#endif
+ return RELSZ;
+}
+
+
+static void
+coff_swap_filehdr_in (abfd, src, dst)
+ bfd *abfd;
+ PTR src;
+ PTR dst;
+{
+ FILHDR *filehdr_src = (FILHDR *) src;
+ struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
+ filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic);
+ filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns);
+ filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat);
+
+ filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
+ filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
+ filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr);
+
+ /* Other people's tools sometimes generate headers with an nsyms but
+ a zero symptr. */
+ if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
+ {
+ filehdr_dst->f_nsyms = 0;
+ filehdr_dst->f_flags |= F_LSYMS;
+ }
+
+ filehdr_dst->f_opthdr = bfd_h_get_16(abfd,
+ (bfd_byte *)filehdr_src-> f_opthdr);
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+
+static unsigned int
+coff_swap_filehdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ int idx;
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
+ FILHDR *filehdr_out = (FILHDR *)out;
+
+ if (pe_data (abfd)->has_reloc_section)
+ filehdr_in->f_flags &= ~F_RELFLG;
+
+ if (pe_data (abfd)->dll)
+ filehdr_in->f_flags |= F_DLL;
+
+ filehdr_in->pe.e_magic = DOSMAGIC;
+ filehdr_in->pe.e_cblp = 0x90;
+ filehdr_in->pe.e_cp = 0x3;
+ filehdr_in->pe.e_crlc = 0x0;
+ filehdr_in->pe.e_cparhdr = 0x4;
+ filehdr_in->pe.e_minalloc = 0x0;
+ filehdr_in->pe.e_maxalloc = 0xffff;
+ filehdr_in->pe.e_ss = 0x0;
+ filehdr_in->pe.e_sp = 0xb8;
+ filehdr_in->pe.e_csum = 0x0;
+ filehdr_in->pe.e_ip = 0x0;
+ filehdr_in->pe.e_cs = 0x0;
+ filehdr_in->pe.e_lfarlc = 0x40;
+ filehdr_in->pe.e_ovno = 0x0;
+
+ for (idx=0; idx < 4; idx++)
+ filehdr_in->pe.e_res[idx] = 0x0;
+
+ filehdr_in->pe.e_oemid = 0x0;
+ filehdr_in->pe.e_oeminfo = 0x0;
+
+ for (idx=0; idx < 10; idx++)
+ filehdr_in->pe.e_res2[idx] = 0x0;
+
+ filehdr_in->pe.e_lfanew = 0x80;
+
+ /* this next collection of data are mostly just characters. It appears
+ to be constant within the headers put on NT exes */
+ filehdr_in->pe.dos_message[0] = 0x0eba1f0e;
+ filehdr_in->pe.dos_message[1] = 0xcd09b400;
+ filehdr_in->pe.dos_message[2] = 0x4c01b821;
+ filehdr_in->pe.dos_message[3] = 0x685421cd;
+ filehdr_in->pe.dos_message[4] = 0x70207369;
+ filehdr_in->pe.dos_message[5] = 0x72676f72;
+ filehdr_in->pe.dos_message[6] = 0x63206d61;
+ filehdr_in->pe.dos_message[7] = 0x6f6e6e61;
+ filehdr_in->pe.dos_message[8] = 0x65622074;
+ filehdr_in->pe.dos_message[9] = 0x6e757220;
+ filehdr_in->pe.dos_message[10] = 0x206e6920;
+ filehdr_in->pe.dos_message[11] = 0x20534f44;
+ filehdr_in->pe.dos_message[12] = 0x65646f6d;
+ filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
+ filehdr_in->pe.dos_message[14] = 0x24;
+ filehdr_in->pe.dos_message[15] = 0x0;
+ filehdr_in->pe.nt_signature = NT_SIGNATURE;
+
+
+
+ bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
+ bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
+
+ bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat);
+ PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
+ (bfd_byte *) filehdr_out->f_symptr);
+ bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
+ bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
+ bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
+
+ /* put in extra dos header stuff. This data remains essentially
+ constant, it just has to be tacked on to the beginning of all exes
+ for NT */
+ bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr,
+ (bfd_byte *) filehdr_out->e_cparhdr);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc,
+ (bfd_byte *) filehdr_out->e_minalloc);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc,
+ (bfd_byte *) filehdr_out->e_maxalloc);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno);
+ {
+ int idx;
+ for (idx=0; idx < 4; idx++)
+ bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx],
+ (bfd_byte *) filehdr_out->e_res[idx]);
+ }
+ bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid);
+ bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo,
+ (bfd_byte *) filehdr_out->e_oeminfo);
+ {
+ int idx;
+ for (idx=0; idx < 10; idx++)
+ bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx],
+ (bfd_byte *) filehdr_out->e_res2[idx]);
+ }
+ bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
+
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx],
+ (bfd_byte *) filehdr_out->dos_message[idx]);
+ }
+
+ /* also put in the NT signature */
+ bfd_h_put_32(abfd, filehdr_in->pe.nt_signature,
+ (bfd_byte *) filehdr_out->nt_signature);
+
+
+
+
+ return FILHSZ;
+}
+#else
+
+static unsigned int
+coff_swap_filehdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
+ FILHDR *filehdr_out = (FILHDR *)out;
+
+ bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
+ bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
+ bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
+ PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
+ (bfd_byte *) filehdr_out->f_symptr);
+ bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
+ bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
+ bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
+
+ return FILHSZ;
+}
+
+#endif
+
+
+static void
+coff_swap_sym_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
+{
+ SYMENT *ext = (SYMENT *)ext1;
+ struct internal_syment *in = (struct internal_syment *)in1;
+
+ if( ext->e.e_name[0] == 0) {
+ in->_n._n_n._n_zeroes = 0;
+ in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
+ }
+ else {
+#if SYMNMLEN != E_SYMNMLEN
+ -> Error, we need to cope with truncating or extending SYMNMLEN!;
+#else
+ memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
+#endif
+ }
+
+ in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
+ in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
+ if (sizeof(ext->e_type) == 2){
+ in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
+ }
+ else {
+ in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
+ }
+ in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
+ in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
+
+ /* The section symbols for the .idata$ sections have class 0x68
+ (C_SECTION), which MS documentation indicates is a section
+ symbol. Unfortunately, the value field in the symbol is simply a
+ copy of the .idata section's flags rather than something useful.
+ When these symbols are encountered, change the value to 0 so that
+ they will be handled somewhat correctly in the bfd code. */
+ if (in->n_sclass == C_SECTION)
+ {
+ in->n_value = 0x0;
+
+ /* FIXME: This is clearly wrong. The problem seems to be that
+ undefined C_SECTION symbols appear in the first object of a
+ MS generated .lib file, and the symbols are not defined
+ anywhere. */
+ in->n_scnum = 1;
+
+ /* I have tried setting the class to 3 and using the following
+ to set the section number. This will put the address of the
+ pointer to the string kernel32.dll at addresses 0 and 0x10
+ off start of idata section which is not correct */
+ /* if (strcmp (in->_n._n_name, ".idata$4") == 0) */
+ /* in->n_scnum = 3; */
+ /* else */
+ /* in->n_scnum = 2; */
+ }
+
+#ifdef coff_swap_sym_in_hook
+ coff_swap_sym_in_hook(abfd, ext1, in1);
+#endif
+}
+
+static unsigned int
+coff_swap_sym_out (abfd, inp, extp)
+ bfd *abfd;
+ PTR inp;
+ PTR extp;
+{
+ struct internal_syment *in = (struct internal_syment *)inp;
+ SYMENT *ext =(SYMENT *)extp;
+ if(in->_n._n_name[0] == 0) {
+ bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
+ bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset);
+ }
+ else {
+#if SYMNMLEN != E_SYMNMLEN
+ -> Error, we need to cope with truncating or extending SYMNMLEN!;
+#else
+ memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
+#endif
+ }
+
+ bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value);
+ bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum);
+ if (sizeof(ext->e_type) == 2)
+ {
+ bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
+ }
+ else
+ {
+ bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type);
+ }
+ bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
+ bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
+
+ return SYMESZ;
+}
+
+static void
+coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
+ bfd *abfd;
+ PTR ext1;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR in1;
+{
+ AUXENT *ext = (AUXENT *)ext1;
+ union internal_auxent *in = (union internal_auxent *)in1;
+
+ switch (class) {
+ case C_FILE:
+ if (ext->x_file.x_fname[0] == 0) {
+ in->x_file.x_n.x_zeroes = 0;
+ in->x_file.x_n.x_offset =
+ bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
+ } else {
+#if FILNMLEN != E_FILNMLEN
+ -> Error, we need to cope with truncating or extending FILNMLEN!;
+#else
+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+#endif
+ }
+ return;
+
+
+ case C_STAT:
+#ifdef C_LEAFSTAT
+ case C_LEAFSTAT:
+#endif
+ case C_HIDDEN:
+ if (type == T_NULL) {
+ in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
+ in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
+ in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
+ in->x_scn.x_checksum = bfd_h_get_32 (abfd,
+ (bfd_byte *) ext->x_scn.x_checksum);
+ in->x_scn.x_associated =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);
+ in->x_scn.x_comdat = bfd_h_get_8 (abfd,
+ (bfd_byte *) ext->x_scn.x_comdat);
+ return;
+ }
+ break;
+ }
+
+ in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
+ in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
+#endif
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
+ }
+ else
+ {
+#if DIMNUM != E_DIMNUM
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN(type)) {
+ in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+ }
+ else {
+ in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
+ in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
+ }
+}
+
+static unsigned int
+coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
+ bfd *abfd;
+ PTR inp;
+ int type;
+ int class;
+ int indx;
+ int numaux;
+ PTR extp;
+{
+ union internal_auxent *in = (union internal_auxent *)inp;
+ AUXENT *ext = (AUXENT *)extp;
+
+ memset((PTR)ext, 0, AUXESZ);
+ switch (class) {
+ case C_FILE:
+ if (in->x_file.x_fname[0] == 0) {
+ bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
+ bfd_h_put_32(abfd,
+ in->x_file.x_n.x_offset,
+ (bfd_byte *) ext->x_file.x_n.x_offset);
+ }
+ else {
+#if FILNMLEN != E_FILNMLEN
+ -> Error, we need to cope with truncating or extending FILNMLEN!;
+#else
+ memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
+#endif
+ }
+ return AUXESZ;
+
+
+ case C_STAT:
+#ifdef C_LEAFSTAT
+ case C_LEAFSTAT:
+#endif
+ case C_HIDDEN:
+ if (type == T_NULL) {
+ PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
+ PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
+ PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
+ bfd_h_put_32 (abfd, in->x_scn.x_checksum,
+ (bfd_byte *) ext->x_scn.x_checksum);
+ bfd_h_put_16 (abfd, in->x_scn.x_associated,
+ (bfd_byte *) ext->x_scn.x_associated);
+ bfd_h_put_8 (abfd, in->x_scn.x_comdat,
+ (bfd_byte *) ext->x_scn.x_comdat);
+ return AUXESZ;
+ }
+ break;
+ }
+
+ bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
+ bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
+#endif
+
+ if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
+ {
+ PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
+ PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
+ }
+ else
+ {
+#if DIMNUM != E_DIMNUM
+ #error we need to cope with truncating or extending DIMNUM
+#endif
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
+ (bfd_byte *) ext->x_sym.x_misc.x_fsize);
+ else
+ {
+ PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
+ PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
+ }
+
+ return AUXESZ;
+}
+
+
+static void
+coff_swap_lineno_in (abfd, ext1, in1)
+ bfd *abfd;
+ PTR ext1;
+ PTR in1;
+{
+ LINENO *ext = (LINENO *)ext1;
+ struct internal_lineno *in = (struct internal_lineno *)in1;
+
+ in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
+ in->l_lnno = GET_LINENO_LNNO(abfd, ext);
+}
+
+static unsigned int
+coff_swap_lineno_out (abfd, inp, outp)
+ bfd *abfd;
+ PTR inp;
+ PTR outp;
+{
+ struct internal_lineno *in = (struct internal_lineno *)inp;
+ struct external_lineno *ext = (struct external_lineno *)outp;
+ bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
+ ext->l_addr.l_symndx);
+
+ PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
+ return LINESZ;
+}
+
+
+
+static void
+coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
+ bfd *abfd;
+ PTR aouthdr_ext1;
+ PTR aouthdr_int1;
+{
+ struct internal_extra_pe_aouthdr *a;
+ PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
+ AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+ struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
+
+ aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
+ aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
+ aouthdr_int->tsize =
+ GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
+ aouthdr_int->dsize =
+ GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
+ aouthdr_int->bsize =
+ GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
+ aouthdr_int->entry =
+ GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
+ aouthdr_int->text_start =
+ GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
+ aouthdr_int->data_start =
+ GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
+
+ a = &aouthdr_int->pe;
+ a->ImageBase = bfd_h_get_32 (abfd, (bfd_byte *) src->ImageBase);
+ a->SectionAlignment = bfd_h_get_32 (abfd, (bfd_byte *) src->SectionAlignment);
+ a->FileAlignment = bfd_h_get_32 (abfd, (bfd_byte *) src->FileAlignment);
+ a->MajorOperatingSystemVersion =
+ bfd_h_get_16 (abfd, (bfd_byte *) src->MajorOperatingSystemVersion);
+ a->MinorOperatingSystemVersion =
+ bfd_h_get_16 (abfd, (bfd_byte *) src->MinorOperatingSystemVersion);
+ a->MajorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MajorImageVersion);
+ a->MinorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MinorImageVersion);
+ a->MajorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MajorSubsystemVersion);
+ a->MinorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *) src->MinorSubsystemVersion);
+ a->Reserved1 = bfd_h_get_32 (abfd, (bfd_byte *) src->Reserved1);
+ a->SizeOfImage = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfImage);
+ a->SizeOfHeaders = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeaders);
+ a->CheckSum = bfd_h_get_32 (abfd, (bfd_byte *) src->CheckSum);
+ a->Subsystem = bfd_h_get_16 (abfd, (bfd_byte *) src->Subsystem);
+ a->DllCharacteristics = bfd_h_get_16 (abfd, (bfd_byte *) src->DllCharacteristics);
+ a->SizeOfStackReserve = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfStackReserve);
+ a->SizeOfStackCommit = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfStackCommit);
+ a->SizeOfHeapReserve = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeapReserve);
+ a->SizeOfHeapCommit = bfd_h_get_32 (abfd, (bfd_byte *) src->SizeOfHeapCommit);
+ a->LoaderFlags = bfd_h_get_32 (abfd, (bfd_byte *) src->LoaderFlags);
+ a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, (bfd_byte *) src->NumberOfRvaAndSizes);
+
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ {
+ a->DataDirectory[idx].VirtualAddress =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->DataDirectory[idx][0]);
+ a->DataDirectory[idx].Size =
+ bfd_h_get_32 (abfd, (bfd_byte *) src->DataDirectory[idx][1]);
+ }
+ }
+
+ if (aouthdr_int->entry)
+ {
+ aouthdr_int->entry += a->ImageBase;
+ aouthdr_int->entry &= 0xffffffff;
+ }
+ if (aouthdr_int->tsize)
+ {
+ aouthdr_int->text_start += a->ImageBase;
+ aouthdr_int->text_start &= 0xffffffff;
+ }
+ if (aouthdr_int->dsize)
+ {
+ aouthdr_int->data_start += a->ImageBase;
+ aouthdr_int->data_start &= 0xffffffff;
+ }
+
+#ifdef POWERPC_LE_PE
+ /* These three fields are normally set up by ppc_relocate_section.
+ In the case of reading a file in, we can pick them up from
+ the DataDirectory.
+ */
+ first_thunk_address = a->DataDirectory[12].VirtualAddress ;
+ thunk_size = a->DataDirectory[12].Size;
+ import_table_size = a->DataDirectory[1].Size;
+#endif
+}
+
+
+static void add_data_entry (abfd, aout, idx, name, base)
+ bfd *abfd;
+ struct internal_extra_pe_aouthdr *aout;
+ int idx;
+ char *name;
+ bfd_vma base;
+{
+ asection *sec = bfd_get_section_by_name (abfd, name);
+
+ /* add import directory information if it exists */
+ if ((sec != NULL)
+ && (coff_section_data (abfd, sec) != NULL)
+ && (pei_section_data (abfd, sec) != NULL))
+ {
+ aout->DataDirectory[idx].VirtualAddress = (sec->vma - base) & 0xffffffff;
+ aout->DataDirectory[idx].Size = pei_section_data (abfd, sec)->virt_size;
+ sec->flags |= SEC_DATA;
+ }
+}
+
+static unsigned int
+coff_swap_aouthdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
+ struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
+ PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
+
+ bfd_vma sa = extra->SectionAlignment;
+ bfd_vma fa = extra->FileAlignment;
+ bfd_vma ib = extra->ImageBase ;
+
+ if (aouthdr_in->tsize)
+ {
+ aouthdr_in->text_start -= ib;
+ aouthdr_in->text_start &= 0xffffffff;
+ }
+ if (aouthdr_in->dsize)
+ {
+ aouthdr_in->data_start -= ib;
+ aouthdr_in->data_start &= 0xffffffff;
+ }
+ if (aouthdr_in->entry)
+ {
+ aouthdr_in->entry -= ib;
+ aouthdr_in->entry &= 0xffffffff;
+ }
+
+#define FA(x) (((x) + fa -1 ) & (- fa))
+#define SA(x) (((x) + sa -1 ) & (- sa))
+
+ /* We like to have the sizes aligned */
+
+ aouthdr_in->bsize = FA (aouthdr_in->bsize);
+
+
+ extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+
+ /* first null out all data directory entries .. */
+ memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
+
+ add_data_entry (abfd, extra, 0, ".edata", ib);
+ add_data_entry (abfd, extra, 1, ".idata", ib);
+ add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
+
+#ifdef POWERPC_LE_PE
+ /* FIXME: do other PE platforms use this? */
+ add_data_entry (abfd, extra, 3, ".pdata" ,ib);
+#endif
+
+ add_data_entry (abfd, extra, 5, ".reloc", ib);
+
+#ifdef POWERPC_LE_PE
+ /* On the PPC NT system, this field is set up as follows. It is
+ not an "officially" reserved field, so it currently has no title.
+ first_thunk_address is idata$5, and the thunk_size is the size
+ of the idata$5 chunk of the idata section.
+ */
+ extra->DataDirectory[12].VirtualAddress = first_thunk_address;
+ extra->DataDirectory[12].Size = thunk_size;
+
+ /* On the PPC NT system, the size of the directory entry is not the
+ size of the entire section. It's actually offset to the end of
+ the idata$3 component of the idata section. This is the size of
+ the entire import table. (also known as the start of idata$4)
+ */
+ extra->DataDirectory[1].Size = import_table_size;
+#endif
+
+ {
+ asection *sec;
+ bfd_vma dsize= 0;
+ bfd_vma isize = SA(abfd->sections->filepos);
+ bfd_vma tsize= 0;
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ int rounded = FA(sec->_raw_size);
+
+ if (sec->flags & SEC_DATA)
+ dsize += rounded;
+ if (sec->flags & SEC_CODE)
+ tsize += rounded;
+ isize += SA(rounded);
+ }
+
+ aouthdr_in->dsize = dsize;
+ aouthdr_in->tsize = tsize;
+ extra->SizeOfImage = isize;
+ }
+
+ extra->SizeOfHeaders = abfd->sections->filepos;
+ bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
+
+#ifdef POWERPC_LE_PE
+ /* this little piece of magic sets the "linker version" field to 2.60 */
+ bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
+#else
+ /* this little piece of magic sets the "linker version" field to 2.55 */
+ bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
+#endif
+
+ PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
+ PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
+ PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
+ PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
+ PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
+ (bfd_byte *) aouthdr_out->standard.text_start);
+
+ PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
+ (bfd_byte *) aouthdr_out->standard.data_start);
+
+
+ bfd_h_put_32 (abfd, extra->ImageBase,
+ (bfd_byte *) aouthdr_out->ImageBase);
+ bfd_h_put_32 (abfd, extra->SectionAlignment,
+ (bfd_byte *) aouthdr_out->SectionAlignment);
+ bfd_h_put_32 (abfd, extra->FileAlignment,
+ (bfd_byte *) aouthdr_out->FileAlignment);
+ bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
+ (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
+ bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
+ (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
+ bfd_h_put_16 (abfd, extra->MajorImageVersion,
+ (bfd_byte *) aouthdr_out->MajorImageVersion);
+ bfd_h_put_16 (abfd, extra->MinorImageVersion,
+ (bfd_byte *) aouthdr_out->MinorImageVersion);
+ bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
+ (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
+ bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
+ (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
+ bfd_h_put_32 (abfd, extra->Reserved1,
+ (bfd_byte *) aouthdr_out->Reserved1);
+ bfd_h_put_32 (abfd, extra->SizeOfImage,
+ (bfd_byte *) aouthdr_out->SizeOfImage);
+ bfd_h_put_32 (abfd, extra->SizeOfHeaders,
+ (bfd_byte *) aouthdr_out->SizeOfHeaders);
+ bfd_h_put_32 (abfd, extra->CheckSum,
+ (bfd_byte *) aouthdr_out->CheckSum);
+ bfd_h_put_16 (abfd, extra->Subsystem,
+ (bfd_byte *) aouthdr_out->Subsystem);
+ bfd_h_put_16 (abfd, extra->DllCharacteristics,
+ (bfd_byte *) aouthdr_out->DllCharacteristics);
+ bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
+ (bfd_byte *) aouthdr_out->SizeOfStackReserve);
+ bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
+ (bfd_byte *) aouthdr_out->SizeOfStackCommit);
+ bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
+ (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
+ bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
+ (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
+ bfd_h_put_32 (abfd, extra->LoaderFlags,
+ (bfd_byte *) aouthdr_out->LoaderFlags);
+ bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
+ (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
+ {
+ int idx;
+ for (idx=0; idx < 16; idx++)
+ {
+ bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
+ (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
+ bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
+ (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
+ }
+ }
+
+ return AOUTSZ;
+}
+
+static void
+ coff_swap_scnhdr_in (abfd, ext, in)
+ bfd *abfd;
+ PTR ext;
+ PTR in;
+{
+ SCNHDR *scnhdr_ext = (SCNHDR *) ext;
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
+ scnhdr_int->s_vaddr =
+ GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
+ scnhdr_int->s_paddr =
+ GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
+ scnhdr_int->s_size =
+ GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
+ scnhdr_int->s_scnptr =
+ GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
+ scnhdr_int->s_relptr =
+ GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
+ scnhdr_int->s_lnnoptr =
+ GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
+ scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
+
+ scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
+ scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
+
+ if (scnhdr_int->s_vaddr != 0)
+ {
+ scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
+ scnhdr_int->s_vaddr &= 0xffffffff;
+ }
+ if (strcmp (scnhdr_int->s_name, _BSS) == 0)
+ {
+ scnhdr_int->s_size = scnhdr_int->s_paddr;
+ scnhdr_int->s_paddr = 0;
+ }
+}
+
+static unsigned int
+coff_swap_scnhdr_out (abfd, in, out)
+ bfd *abfd;
+ PTR in;
+ PTR out;
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
+ SCNHDR *scnhdr_ext = (SCNHDR *)out;
+ unsigned int ret = SCNHSZ;
+ bfd_vma ps;
+ bfd_vma ss;
+
+ memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
+
+ PUT_SCNHDR_VADDR (abfd,
+ ((scnhdr_int->s_vaddr
+ - pe_data(abfd)->pe_opthdr.ImageBase)
+ & 0xffffffff),
+ (bfd_byte *) scnhdr_ext->s_vaddr);
+
+ /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
+ value except for the BSS section, its s_size should be 0 */
+
+
+ if (strcmp (scnhdr_int->s_name, _BSS) == 0)
+ {
+ ps = scnhdr_int->s_size;
+ ss = 0;
+ }
+ else
+ {
+ ps = scnhdr_int->s_paddr;
+ ss = scnhdr_int->s_size;
+ }
+
+ PUT_SCNHDR_SIZE (abfd, ss,
+ (bfd_byte *) scnhdr_ext->s_size);
+
+
+ PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
+
+ PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
+ (bfd_byte *) scnhdr_ext->s_scnptr);
+ PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
+ (bfd_byte *) scnhdr_ext->s_relptr);
+ PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
+ (bfd_byte *) scnhdr_ext->s_lnnoptr);
+
+ /* Extra flags must be set when dealing with NT. All sections should also
+ have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
+ .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
+ sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
+ (this is especially important when dealing with the .idata section since
+ the addresses for routines from .dlls must be overwritten). If .reloc
+ section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
+ (0x02000000). Also, the resource data should also be read and
+ writable. */
+
+ /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
+ /* FIXME: even worse, I don't see how to get the original alignment field*/
+ /* back... */
+
+ /* FIXME: Basing this on section names is bogus. Also, this should
+ be in sec_to_styp_flags. */
+
+ {
+ int flags = scnhdr_int->s_flags;
+ if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
+ strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
+ strcmp (scnhdr_int->s_name, ".bss") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
+ else if (strcmp (scnhdr_int->s_name, ".text") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+ else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
+ flags = (SEC_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
+ | IMAGE_SCN_MEM_SHARED);
+ else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
+ flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
+ else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
+ || strcmp (scnhdr_int->s_name, ".edata") == 0)
+ flags = IMAGE_SCN_MEM_READ | SEC_DATA;
+ else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
+ flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
+ IMAGE_SCN_MEM_READ ;
+ /* Remember this field is a max of 8 chars, so the null is _not_ there
+ for an 8 character name like ".reldata". (yep. Stupid bug) */
+ else if (strncmp (scnhdr_int->s_name, ".reldata", 8) == 0)
+ flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
+ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
+ else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
+ flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
+ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
+ else if (strncmp (scnhdr_int->s_name, ".drectve", 8) == 0)
+ flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
+ else if (strncmp (scnhdr_int->s_name, ".stab", 5) == 0)
+ flags |= (IMAGE_SCN_LNK_INFO | IMAGE_SCN_MEM_DISCARDABLE
+ | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ);
+ else if (strcmp (scnhdr_int->s_name, ".rsrc") == 0)
+ flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_SHARED;
+ else
+ flags |= IMAGE_SCN_MEM_READ;
+
+ bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
+ }
+
+ if (scnhdr_int->s_nlnno <= 0xffff)
+ bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
+ else
+ {
+ (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nlnno);
+ bfd_set_error (bfd_error_file_truncated);
+ bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
+ ret = 0;
+ }
+ if (scnhdr_int->s_nreloc <= 0xffff)
+ bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
+ else
+ {
+ (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (abfd),
+ scnhdr_int->s_nreloc);
+ bfd_set_error (bfd_error_file_truncated);
+ bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
+ ret = 0;
+ }
+ return ret;
+}
+
+static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
+{
+ N_ ("Export Directory [.edata (or where ever we found it)]"),
+ N_ ("Import Directory [parts of .idata]"),
+ N_ ("Resource Directory [.rsrc]"),
+ N_ ("Exception Directory [.pdata]"),
+ N_ ("Security Directory"),
+ N_ ("Base Relocation Directory [.reloc]"),
+ N_ ("Debug Directory"),
+ N_ ("Description Directory"),
+ N_ ("Special Directory"),
+ N_ ("Thread Storage Directory [.tls]"),
+ N_ ("Load Configuration Directory"),
+ N_ ("Bound Import Directory"),
+ N_ ("Import Address Table Directory"),
+ N_ ("Reserved"),
+ N_ ("Reserved"),
+ N_ ("Reserved")
+};
+
+/**********************************************************************/
+static boolean
+pe_print_idata(abfd, vfile)
+ bfd *abfd;
+ PTR vfile;
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data = 0;
+ asection *section = bfd_get_section_by_name (abfd, ".idata");
+ unsigned long adj;
+
+#ifdef POWERPC_LE_PE
+ asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
+#endif
+
+ bfd_size_type datasize;
+ bfd_size_type dataoff;
+ bfd_size_type secsize;
+ bfd_size_type i;
+ bfd_size_type start, stop;
+ int onaline = 20;
+
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
+
+ if (section != NULL)
+ {
+ datasize = bfd_section_size (abfd, section);
+ dataoff = 0;
+
+ if (datasize == 0)
+ return true;
+ }
+ else
+ {
+ bfd_vma addr, size;
+
+ addr = extra->DataDirectory[1].VirtualAddress;
+ size = extra->DataDirectory[1].Size;
+
+ if (addr == 0 || size == 0)
+ return true;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ if (section->vma - extra->ImageBase <= addr
+ && ((section->vma - extra->ImageBase
+ + bfd_section_size (abfd, section))
+ >= addr + size))
+ break;
+ }
+ if (section == NULL)
+ return true;
+
+ /* For some reason the import table size is not reliable. The
+ import data will extend past the indicated size, and before
+ the indicated address. */
+ dataoff = addr - (section->vma - extra->ImageBase);
+ datasize = size;
+ }
+
+#ifdef POWERPC_LE_PE
+ if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
+ {
+ /* The toc address can be found by taking the starting address,
+ which on the PPC locates a function descriptor. The descriptor
+ consists of the function code starting address followed by the
+ address of the toc. The starting address we get from the bfd,
+ and the descriptor is supposed to be in the .reldata section.
+ */
+
+ bfd_vma loadable_toc_address;
+ bfd_vma toc_address;
+ bfd_vma start_address;
+ bfd_byte *data = 0;
+ int offset;
+ data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
+ rel_section));
+ if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
+ return false;
+
+ datasize = bfd_section_size (abfd, rel_section);
+
+ bfd_get_section_contents (abfd,
+ rel_section,
+ (PTR) data, 0,
+ bfd_section_size (abfd, rel_section));
+
+ offset = abfd->start_address - rel_section->vma;
+
+ start_address = bfd_get_32(abfd, data+offset);
+ loadable_toc_address = bfd_get_32(abfd, data+offset+4);
+ toc_address = loadable_toc_address - 32768;
+
+ fprintf(file,
+ _("\nFunction descriptor located at the start address: %04lx\n"),
+ (unsigned long int) (abfd->start_address));
+ fprintf (file,
+ _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
+ start_address, loadable_toc_address, toc_address);
+ }
+ else
+ {
+ fprintf(file,
+ _("\nNo reldata section! Function descriptor not decoded.\n"));
+ }
+#endif
+
+ fprintf(file,
+ _("\nThe Import Tables (interpreted .idata section contents)\n"));
+ fprintf(file,
+ _(" vma: Hint Time Forward DLL First\n"));
+ fprintf(file,
+ _(" Table Stamp Chain Name Thunk\n"));
+
+ secsize = bfd_section_size (abfd, section);
+ data = (bfd_byte *) bfd_malloc (secsize);
+ if (data == NULL && secsize != 0)
+ return false;
+
+ if (! bfd_get_section_contents (abfd, section, (PTR) data, 0, secsize))
+ return false;
+
+ adj = (extra->ImageBase - section->vma) & 0xffffffff;
+
+ start = dataoff;
+ stop = dataoff + datasize;
+ for (i = start; i < stop; i += onaline)
+ {
+ bfd_vma hint_addr;
+ bfd_vma time_stamp;
+ bfd_vma forward_chain;
+ bfd_vma dll_name;
+ bfd_vma first_thunk;
+ int idx = 0;
+ bfd_size_type j;
+ char *dll;
+
+ fprintf (file,
+ " %08lx\t",
+ (unsigned long int) (i + section->vma + dataoff));
+
+ if (i+20 > stop)
+ {
+ /* check stuff */
+ ;
+ }
+
+ hint_addr = bfd_get_32(abfd, data+i);
+ time_stamp = bfd_get_32(abfd, data+i+4);
+ forward_chain = bfd_get_32(abfd, data+i+8);
+ dll_name = bfd_get_32(abfd, data+i+12);
+ first_thunk = bfd_get_32(abfd, data+i+16);
+
+ fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
+ hint_addr,
+ time_stamp,
+ forward_chain,
+ dll_name,
+ first_thunk);
+
+ if (hint_addr == 0 && first_thunk == 0)
+ break;
+
+ /* the image base is present in the section->vma */
+ dll = (char *) data + dll_name + adj;
+ fprintf(file, _("\n\tDLL Name: %s\n"), dll);
+
+ if (hint_addr != 0)
+ {
+ fprintf (file, _("\tvma: Hint/Ord Member-Name\n"));
+
+ idx = hint_addr + adj;
+
+ for (j = 0; j < stop; j += 4)
+ {
+ unsigned long member = bfd_get_32 (abfd, data + idx + j);
+
+ if (member == 0)
+ break;
+ if (member & 0x80000000)
+ fprintf (file, "\t%04lx\t %4lu", member,
+ member & 0x7fffffff);
+ else
+ {
+ int ordinal;
+ char *member_name;
+
+ ordinal = bfd_get_16 (abfd, data + member + adj);
+ member_name = (char *) data + member + adj + 2;
+ fprintf (file, "\t%04lx\t %4d %s",
+ member, ordinal, member_name);
+ }
+
+ /* If the time stamp is not zero, the import address
+ table holds actual addresses. */
+ if (time_stamp != 0
+ && first_thunk != 0
+ && first_thunk != hint_addr)
+ fprintf (file, "\t%04lx",
+ bfd_get_32 (abfd, data + first_thunk + adj + j));
+
+ fprintf (file, "\n");
+ }
+ }
+
+ if (hint_addr != first_thunk && time_stamp == 0)
+ {
+ int differ = 0;
+ int idx2;
+
+ idx2 = first_thunk + adj;
+
+ for (j=0;j<stop;j+=4)
+ {
+ int ordinal;
+ char *member_name;
+ bfd_vma hint_member = 0;
+ bfd_vma iat_member;
+
+ if (hint_addr != 0)
+ hint_member = bfd_get_32 (abfd, data + idx + j);
+ iat_member = bfd_get_32 (abfd, data + idx2 + j);
+
+ if (hint_addr == 0 && iat_member == 0)
+ break;
+
+ if (hint_addr == 0 || hint_member != iat_member)
+ {
+ if (differ == 0)
+ {
+ fprintf (file,
+ _("\tThe Import Address Table (difference found)\n"));
+ fprintf(file, _("\tvma: Hint/Ord Member-Name\n"));
+ differ = 1;
+ }
+ if (iat_member == 0)
+ {
+ fprintf(file,
+ _("\t>>> Ran out of IAT members!\n"));
+ }
+ else
+ {
+ ordinal = bfd_get_16(abfd,
+ data + iat_member + adj);
+ member_name = (char *) data + iat_member + adj + 2;
+ fprintf(file, "\t%04lx\t %4d %s\n",
+ iat_member, ordinal, member_name);
+ }
+ }
+
+ if (hint_addr != 0 && hint_member == 0)
+ break;
+ }
+ if (differ == 0)
+ {
+ fprintf(file,
+ _("\tThe Import Address Table is identical\n"));
+ }
+ }
+
+ fprintf(file, "\n");
+
+ }
+
+ free (data);
+
+ return true;
+}
+
+static boolean
+pe_print_edata (abfd, vfile)
+ bfd *abfd;
+ PTR vfile;
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data = 0;
+ asection *section = bfd_get_section_by_name (abfd, ".edata");
+
+ bfd_size_type datasize;
+ bfd_size_type dataoff;
+ bfd_size_type i;
+
+ int adj;
+ struct EDT_type
+ {
+ long export_flags; /* reserved - should be zero */
+ long time_stamp;
+ short major_ver;
+ short minor_ver;
+ bfd_vma name; /* rva - relative to image base */
+ long base; /* ordinal base */
+ unsigned long num_functions; /* Number in the export address table */
+ unsigned long num_names; /* Number in the name pointer table */
+ bfd_vma eat_addr; /* rva to the export address table */
+ bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
+ bfd_vma ot_addr; /* rva to the Ordinal Table */
+ } edt;
+
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
+
+ if (section != NULL)
+ {
+ datasize = bfd_section_size (abfd, section);
+ dataoff = 0;
+ }
+ else
+ {
+ bfd_vma addr, size;
+
+ addr = extra->DataDirectory[0].VirtualAddress;
+ size = extra->DataDirectory[0].Size;
+
+ if (addr == 0 || size == 0)
+ return true;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ if (section->vma - extra->ImageBase <= addr
+ && ((section->vma - extra->ImageBase
+ + bfd_section_size (abfd, section))
+ >= addr + size))
+ break;
+ }
+ if (section == NULL)
+ return true;
+
+ datasize = size;
+ dataoff = addr - (section->vma - extra->ImageBase);
+ }
+
+ data = (bfd_byte *) bfd_malloc (datasize);
+ if (data == NULL && datasize != 0)
+ return false;
+
+ if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff,
+ datasize))
+ return false;
+
+ /* Go get Export Directory Table */
+ edt.export_flags = bfd_get_32(abfd, data+0);
+ edt.time_stamp = bfd_get_32(abfd, data+4);
+ edt.major_ver = bfd_get_16(abfd, data+8);
+ edt.minor_ver = bfd_get_16(abfd, data+10);
+ edt.name = bfd_get_32(abfd, data+12);
+ edt.base = bfd_get_32(abfd, data+16);
+ edt.num_functions = bfd_get_32(abfd, data+20);
+ edt.num_names = bfd_get_32(abfd, data+24);
+ edt.eat_addr = bfd_get_32(abfd, data+28);
+ edt.npt_addr = bfd_get_32(abfd, data+32);
+ edt.ot_addr = bfd_get_32(abfd, data+36);
+
+ adj = (extra->ImageBase - (section->vma + dataoff)) & 0xffffffff;
+
+
+ /* Dump the EDT first first */
+ fprintf(file,
+ _("\nThe Export Tables (interpreted .edata section contents)\n\n"));
+
+ fprintf(file,
+ _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
+
+ fprintf(file,
+ _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
+
+ fprintf(file,
+ _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
+
+ fprintf (file,
+ _("Name \t\t\t\t"));
+ fprintf_vma (file, edt.name);
+ fprintf (file,
+ " %s\n", data + edt.name + adj);
+
+ fprintf(file,
+ _("Ordinal Base \t\t\t%ld\n"), edt.base);
+
+ fprintf(file,
+ _("Number in:\n"));
+
+ fprintf(file,
+ _("\tExport Address Table \t\t%lx\n"),
+ edt.num_functions);
+
+ fprintf(file,
+ _("\t[Name Pointer/Ordinal] Table\t%lu\n"), edt.num_names);
+
+ fprintf(file,
+ _("Table Addresses\n"));
+
+ fprintf (file,
+ _("\tExport Address Table \t\t"));
+ fprintf_vma (file, edt.eat_addr);
+ fprintf (file, "\n");
+
+ fprintf (file,
+ _("\tName Pointer Table \t\t"));
+ fprintf_vma (file, edt.npt_addr);
+ fprintf (file, "\n");
+
+ fprintf (file,
+ _("\tOrdinal Table \t\t\t"));
+ fprintf_vma (file, edt.ot_addr);
+ fprintf (file, "\n");
+
+
+ /* The next table to find si the Export Address Table. It's basically
+ a list of pointers that either locate a function in this dll, or
+ forward the call to another dll. Something like:
+ typedef union
+ {
+ long export_rva;
+ long forwarder_rva;
+ } export_address_table_entry;
+ */
+
+ fprintf(file,
+ _("\nExport Address Table -- Ordinal Base %ld\n"),
+ edt.base);
+
+ for (i = 0; i < edt.num_functions; ++i)
+ {
+ bfd_vma eat_member = bfd_get_32 (abfd,
+ data + edt.eat_addr + (i * 4) + adj);
+ bfd_vma eat_actual = (extra->ImageBase + eat_member) & 0xffffffff;
+ bfd_vma edata_start = bfd_get_section_vma (abfd,section) + dataoff;
+ bfd_vma edata_end = edata_start + datasize;
+
+ if (eat_member == 0)
+ continue;
+
+ if (edata_start < eat_actual && eat_actual < edata_end)
+ {
+ /* this rva is to a name (forwarding function) in our section */
+ /* Should locate a function descriptor */
+ fprintf(file,
+ "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
+ (long) i, (long) (i + edt.base), eat_member,
+ "Forwarder RVA", data + eat_member + adj);
+ }
+ else
+ {
+ /* Should locate a function descriptor in the reldata section */
+ fprintf(file,
+ "\t[%4ld] +base[%4ld] %04lx %s\n",
+ (long) i, (long) (i + edt.base), eat_member, "Export RVA");
+ }
+ }
+
+ /* The Export Name Pointer Table is paired with the Export Ordinal Table */
+ /* Dump them in parallel for clarity */
+ fprintf(file,
+ _("\n[Ordinal/Name Pointer] Table\n"));
+
+ for (i = 0; i < edt.num_names; ++i)
+ {
+ bfd_vma name_ptr = bfd_get_32(abfd,
+ data +
+ edt.npt_addr
+ + (i*4) + adj);
+
+ char *name = (char *) data + name_ptr + adj;
+
+ bfd_vma ord = bfd_get_16(abfd,
+ data +
+ edt.ot_addr
+ + (i*2) + adj);
+ fprintf(file,
+ "\t[%4ld] %s\n", (long) ord, name);
+
+ }
+
+ free (data);
+
+ return true;
+}
+
+static boolean
+pe_print_pdata (abfd, vfile)
+ bfd *abfd;
+ PTR vfile;
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data = 0;
+ asection *section = bfd_get_section_by_name (abfd, ".pdata");
+ bfd_size_type datasize = 0;
+ bfd_size_type i;
+ bfd_size_type start, stop;
+ int onaline = 20;
+
+ if (section == 0)
+ return true;
+
+ stop = bfd_section_size (abfd, section);
+ if ((stop % onaline) != 0)
+ fprintf (file, _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
+ (long)stop, onaline);
+
+ fprintf(file,
+ _("\nThe Function Table (interpreted .pdata section contents)\n"));
+ fprintf(file,
+ _(" vma:\t\tBegin End EH EH PrologEnd\n"));
+ fprintf(file,
+ _(" \t\tAddress Address Handler Data Address\n"));
+
+ if (bfd_section_size (abfd, section) == 0)
+ return true;
+
+ data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
+ datasize = bfd_section_size (abfd, section);
+ if (data == NULL && datasize != 0)
+ return false;
+
+ bfd_get_section_contents (abfd,
+ section,
+ (PTR) data, 0,
+ bfd_section_size (abfd, section));
+
+ start = 0;
+
+ for (i = start; i < stop; i += onaline)
+ {
+ bfd_vma begin_addr;
+ bfd_vma end_addr;
+ bfd_vma eh_handler;
+ bfd_vma eh_data;
+ bfd_vma prolog_end_addr;
+
+ if (i+20 > stop)
+ break;
+
+ begin_addr = bfd_get_32(abfd, data+i);
+ end_addr = bfd_get_32(abfd, data+i+4);
+ eh_handler = bfd_get_32(abfd, data+i+8);
+ eh_data = bfd_get_32(abfd, data+i+12);
+ prolog_end_addr = bfd_get_32(abfd, data+i+16);
+
+ if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
+ && eh_data == 0 && prolog_end_addr == 0)
+ {
+ /* We are probably into the padding of the
+ section now */
+ break;
+ }
+
+ fprintf (file,
+ " %08lx\t",
+ (unsigned long int) (i + section->vma));
+
+ fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
+ begin_addr,
+ end_addr,
+ eh_handler,
+ eh_data,
+ prolog_end_addr);
+
+#ifdef POWERPC_LE_PE
+ if (eh_handler == 0 && eh_data != 0)
+ {
+ /* Special bits here, although the meaning may */
+ /* be a little mysterious. The only one I know */
+ /* for sure is 0x03. */
+ /* Code Significance */
+ /* 0x00 None */
+ /* 0x01 Register Save Millicode */
+ /* 0x02 Register Restore Millicode */
+ /* 0x03 Glue Code Sequence */
+ switch (eh_data)
+ {
+ case 0x01:
+ fprintf(file, _(" Register save millicode"));
+ break;
+ case 0x02:
+ fprintf(file, _(" Register restore millicode"));
+ break;
+ case 0x03:
+ fprintf(file, _(" Glue code sequence"));
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+ fprintf(file, "\n");
+ }
+
+ free (data);
+
+ return true;
+}
+
+static const char *tbl[6] =
+{
+"ABSOLUTE",
+"HIGH",
+"LOW",
+"HIGHLOW",
+"HIGHADJ",
+"MIPS_JMPADDR"
+};
+
+static boolean
+pe_print_reloc (abfd, vfile)
+ bfd *abfd;
+ PTR vfile;
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data = 0;
+ asection *section = bfd_get_section_by_name (abfd, ".reloc");
+ bfd_size_type datasize = 0;
+ bfd_size_type i;
+ bfd_size_type start, stop;
+
+ if (section == 0)
+ return true;
+
+ if (bfd_section_size (abfd, section) == 0)
+ return true;
+
+ fprintf(file,
+ _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
+
+ data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
+ datasize = bfd_section_size (abfd, section);
+ if (data == NULL && datasize != 0)
+ return false;
+
+ bfd_get_section_contents (abfd,
+ section,
+ (PTR) data, 0,
+ bfd_section_size (abfd, section));
+
+ start = 0;
+
+ stop = bfd_section_size (abfd, section);
+
+ for (i = start; i < stop;)
+ {
+ int j;
+ bfd_vma virtual_address;
+ long number, size;
+
+ /* The .reloc section is a sequence of blocks, with a header consisting
+ of two 32 bit quantities, followed by a number of 16 bit entries */
+
+ virtual_address = bfd_get_32(abfd, data+i);
+ size = bfd_get_32(abfd, data+i+4);
+ number = (size - 8) / 2;
+
+ if (size == 0)
+ {
+ break;
+ }
+
+ fprintf (file,
+ _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
+ virtual_address, size, size, number);
+
+ for (j = 0; j < number; ++j)
+ {
+ unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
+ int t = (e & 0xF000) >> 12;
+ int off = e & 0x0FFF;
+
+ if (t > 5)
+ abort();
+
+ fprintf(file,
+ _("\treloc %4d offset %4x [%4lx] %s\n"),
+ j, off, (long) (off + virtual_address), tbl[t]);
+
+ }
+ i += size;
+ }
+
+ free (data);
+
+ return true;
+}
+
+static boolean
+pe_print_private_bfd_data (abfd, vfile)
+ bfd *abfd;
+ PTR vfile;
+{
+ FILE *file = (FILE *) vfile;
+ int j;
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
+
+ /* The MS dumpbin program reportedly ands with 0xff0f before
+ printing the characteristics field. Not sure why. No reason to
+ emulate it here. */
+ fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
+#undef PF
+#define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
+ PF (F_RELFLG, "relocations stripped");
+ PF (F_EXEC, "executable");
+ PF (F_LNNO, "line numbers stripped");
+ PF (F_LSYMS, "symbols stripped");
+ PF (0x80, "little endian");
+ PF (F_AR32WR, "32 bit words");
+ PF (0x200, "debugging information removed");
+ PF (0x1000, "system file");
+ PF (F_DLL, "DLL");
+ PF (0x8000, "big endian");
+#undef PF
+
+ fprintf (file,"\nImageBase\t\t");
+ fprintf_vma (file, i->ImageBase);
+ fprintf (file,"\nSectionAlignment\t");
+ fprintf_vma (file, i->SectionAlignment);
+ fprintf (file,"\nFileAlignment\t\t");
+ fprintf_vma (file, i->FileAlignment);
+ fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
+ fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
+ fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
+ fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
+ fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
+ fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
+ fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
+ fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
+ fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
+ fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
+ fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
+ fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
+ fprintf (file,"SizeOfStackReserve\t");
+ fprintf_vma (file, i->SizeOfStackReserve);
+ fprintf (file,"\nSizeOfStackCommit\t");
+ fprintf_vma (file, i->SizeOfStackCommit);
+ fprintf (file,"\nSizeOfHeapReserve\t");
+ fprintf_vma (file, i->SizeOfHeapReserve);
+ fprintf (file,"\nSizeOfHeapCommit\t");
+ fprintf_vma (file, i->SizeOfHeapCommit);
+ fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
+ fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
+
+ fprintf (file,"\nThe Data Directory\n");
+ for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
+ {
+ fprintf (file, "Entry %1x ", j);
+ fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
+ fprintf (file, " %08lx ", i->DataDirectory[j].Size);
+ fprintf (file, "%s\n", dir_names[j]);
+ }
+
+ pe_print_idata (abfd, vfile);
+ pe_print_edata (abfd, vfile);
+ pe_print_pdata (abfd, vfile);
+ pe_print_reloc (abfd, vfile);
+
+ if (pe_saved_coff_bfd_print_private_bfd_data != NULL)
+ {
+ fputc ('\n', file);
+
+ return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
+ }
+
+ return true;
+}
+
+static boolean
+pe_mkobject (abfd)
+ bfd * abfd;
+{
+ pe_data_type *pe;
+ abfd->tdata.pe_obj_data =
+ (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
+
+ if (abfd->tdata.pe_obj_data == 0)
+ return false;
+
+ pe = pe_data (abfd);
+
+ pe->coff.pe = 1;
+ pe->in_reloc_p = in_reloc_p;
+ return true;
+}
+
+/* Create the COFF backend specific information. */
+static PTR
+pe_mkobject_hook (abfd, filehdr, aouthdr)
+ bfd * abfd;
+ PTR filehdr;
+ PTR aouthdr;
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ pe_data_type *pe;
+
+ if (pe_mkobject (abfd) == false)
+ return NULL;
+
+ pe = pe_data (abfd);
+ pe->coff.sym_filepos = internal_f->f_symptr;
+ /* These members communicate important constants about the symbol
+ table to GDB's symbol-reading code. These `constants'
+ unfortunately vary among coff implementations... */
+ pe->coff.local_n_btmask = N_BTMASK;
+ pe->coff.local_n_btshft = N_BTSHFT;
+ pe->coff.local_n_tmask = N_TMASK;
+ pe->coff.local_n_tshift = N_TSHIFT;
+ pe->coff.local_symesz = SYMESZ;
+ pe->coff.local_auxesz = AUXESZ;
+ pe->coff.local_linesz = LINESZ;
+
+ obj_raw_syment_count (abfd) =
+ obj_conv_table_size (abfd) =
+ internal_f->f_nsyms;
+
+ pe->real_flags = internal_f->f_flags;
+
+ if ((internal_f->f_flags & F_DLL) != 0)
+ pe->dll = 1;
+
+#ifdef COFF_IMAGE_WITH_PE
+ if (aouthdr)
+ pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
+#endif
+
+#ifdef ARM
+ if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
+ coff_data (abfd) ->flags = 0;
+#endif
+
+ return (PTR) pe;
+}
+
+
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+#ifdef coff_bfd_copy_private_bfd_data
+static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
+ PARAMS ((bfd *, bfd *))
+ = coff_bfd_copy_private_bfd_data;
+#undef coff_bfd_copy_private_bfd_data
+#else
+static boolean (*pe_saved_coff_bfd_copy_private_bfd_data)
+ PARAMS ((bfd *, bfd *))
+ = NULL;
+#endif
+#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
+
+static boolean
+pe_bfd_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd, *obfd;
+{
+ /* One day we may try to grok other private data. */
+ if (ibfd->xvec->flavour != bfd_target_coff_flavour
+ || obfd->xvec->flavour != bfd_target_coff_flavour)
+ return true;
+
+ pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
+ pe_data (obfd)->dll = pe_data (ibfd)->dll;
+
+ if (pe_saved_coff_bfd_copy_private_bfd_data)
+ return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
+
+ return true;
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+
+/* Copy private section data. */
+
+#define coff_bfd_copy_private_section_data pe_bfd_copy_private_section_data
+
+static boolean pe_bfd_copy_private_section_data
+ PARAMS ((bfd *, asection *, bfd *, asection *));
+
+static boolean
+pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
+ bfd *ibfd;
+ asection *isec;
+ bfd *obfd;
+ asection *osec;
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
+ || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
+ return true;
+
+ if (coff_section_data (ibfd, isec) != NULL
+ && pei_section_data (ibfd, isec) != NULL)
+ {
+ if (coff_section_data (obfd, osec) == NULL)
+ {
+ osec->used_by_bfd =
+ (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
+ if (osec->used_by_bfd == NULL)
+ return false;
+ }
+ if (pei_section_data (obfd, osec) == NULL)
+ {
+ coff_section_data (obfd, osec)->tdata =
+ (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
+ if (coff_section_data (obfd, osec)->tdata == NULL)
+ return false;
+ }
+ pei_section_data (obfd, osec)->virt_size =
+ pei_section_data (ibfd, isec)->virt_size;
+ }
+
+ return true;
+}
+
+#endif
diff --git a/bfd/po/Make-in b/bfd/po/Make-in
new file mode 100644
index 00000000000..0552db1feef
--- /dev/null
+++ b/bfd/po/Make-in
@@ -0,0 +1,251 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bfd/po/POTFILES.in b/bfd/po/POTFILES.in
new file mode 100644
index 00000000000..ae4996698e6
--- /dev/null
+++ b/bfd/po/POTFILES.in
@@ -0,0 +1,264 @@
+archures.c
+bfd-in2.h
+aix386-core.c
+aout-adobe.c
+aout-arm.c
+aout-encap.c
+aout-ns32k.c
+aout-sparcle.c
+aout-target.h
+aout-tic30.c
+aout0.c
+aout32.c
+aout64.c
+aoutf1.h
+aoutx.h
+archive.c
+bfd-in.h
+bfd.c
+binary.c
+bout.c
+cache.c
+cf-i386lynx.c
+cf-m68klynx.c
+cf-sparclynx.c
+cisco-core.c
+coff-a29k.c
+coff-alpha.c
+coff-apollo.c
+coff-arm.c
+coff-aux.c
+coff-go32.c
+coff-h8300.c
+coff-h8500.c
+coff-i386.c
+coff-i860.c
+coff-i960.c
+coff-m68k.c
+coff-m88k.c
+coff-mcore.c
+coff-mips.c
+coff-pmac.c
+coff-ppc.c
+coff-rs6000.c
+coff-sh.c
+coff-sparc.c
+coff-stgo32.c
+coff-svm68k.c
+coff-tic30.c
+coff-tic80.c
+coff-u68k.c
+coff-w65.c
+coff-we32k.c
+coff-z8k.c
+coffcode.h
+coffgen.c
+cofflink.c
+coffswap.h
+cpu-m10300.c
+cpu-m32r.c
+cpu-mips.c
+corefile.c
+cpu-a29k.c
+cpu-alpha.c
+cpu-arc.c
+cpu-arm.c
+cpu-d10v.c
+cpu-d30v.c
+cpu-fr30.c
+cpu-h8300.c
+cpu-h8500.c
+cpu-hppa.c
+cpu-i386.c
+cpu-i860.c
+cpu-i960.c
+cpu-m10200.c
+cpu-sh.c
+elf-m10300.c
+cpu-m68k.c
+cpu-m88k.c
+cpu-mcore.c
+elf32-m32r.c
+cpu-ns32k.c
+cpu-powerpc.c
+cpu-rs6000.c
+libbfd.h
+cpu-sparc.c
+cpu-tic30.c
+cpu-tic80.c
+cpu-v850.c
+cpu-vax.c
+elf32-mips.c
+cpu-w65.c
+cpu-we32k.c
+cpu-z8k.c
+demo64.c
+dwarf1.c
+dwarf2.c
+ecoff.c
+ecofflink.c
+ecoffswap.h
+elf-bfd.h
+elf-m10200.c
+libhppa.h
+elf.c
+elf32-arc.c
+elf32-arm.h
+elf32-d10v.c
+elf32-d30v.c
+elf32-fr30.c
+elf32-gen.c
+elf32-hppa.c
+elf32-hppa.h
+elf32-i386.c
+elf32-i860.c
+reloc.c
+elf32-m68k.c
+elf32-m88k.c
+elf32-mcore.c
+targets.c
+elf32-ppc.c
+elf32-sh.c
+elf32-sparc.c
+elf32-v850.c
+elf32.c
+elf64-alpha.c
+elf64-gen.c
+elf64-mips.c
+elf64-sparc.c
+elf64.c
+elfarm-nabi.c
+elfarm-oabi.c
+elfcode.h
+elfcore.h
+elflink.c
+elflink.h
+elfxx-target.h
+epoc-pe-arm.c
+epoc-pei-arm.c
+format.c
+freebsd.h
+gen-aout.c
+genlink.h
+go32stub.h
+hash.c
+host-aout.c
+hp300bsd.c
+hp300hpux.c
+hppa_stubs.h
+hppabsd-core.c
+hpux-core.c
+i386aout.c
+i386bsd.c
+i386dynix.c
+i386freebsd.c
+i386linux.c
+i386lynx.c
+i386mach3.c
+i386msdos.c
+i386netbsd.c
+i386os9k.c
+ieee.c
+ihex.c
+init.c
+irix-core.c
+libaout.h
+libbfd-in.h
+libbfd.c
+libcoff-in.h
+libcoff.h
+libecoff.h
+libieee.h
+libnlm.h
+liboasys.h
+linker.c
+lynx-core.c
+m68k4knetbsd.c
+m68klinux.c
+m68klynx.c
+m68knetbsd.c
+doc/chew.c
+m88kmach3.c
+mipsbsd.c
+netbsd-core.c
+netbsd.h
+newsos3.c
+nlm-target.h
+nlm.c
+nlm32-alpha.c
+nlm32-i386.c
+nlm32-ppc.c
+nlm32-sparc.c
+nlm32.c
+nlm64.c
+nlmcode.h
+nlmswap.h
+ns32k.h
+ns32knetbsd.c
+oasys.c
+opncls.c
+osf-core.c
+pc532-mach.c
+pe-arm.c
+pe-i386.c
+pe-mcore.c
+pe-ppc.c
+pei-arm.c
+pei-i386.c
+pei-mcore.c
+pei-ppc.c
+peicode.h
+ppcboot.c
+ptrace-core.c
+reloc16.c
+riscix.c
+rs6000-core.c
+sco5-core.c
+section.c
+som.c
+som.h
+sparclinux.c
+sparclynx.c
+sparcnetbsd.c
+srec.c
+stab-syms.c
+stabs.c
+sunos.c
+syms.c
+sysdep.h
+tekhex.c
+trad-core.c
+vaxnetbsd.c
+versados.c
+vms-gsd.c
+vms-hdr.c
+vms-misc.c
+vms-tir.c
+vms.c
+vms.h
+xcofflink.c
+hosts/alphalinux.h
+hosts/alphavms.h
+hosts/decstation.h
+hosts/delta68.h
+hosts/dpx2.h
+hosts/hp300bsd.h
+hosts/i386bsd.h
+hosts/i386linux.h
+hosts/i386mach3.h
+hosts/i386sco.h
+hosts/i860mach3.h
+hosts/m68kaux.h
+hosts/m68klinux.h
+hosts/m88kmach3.h
+hosts/mipsbsd.h
+hosts/mipsmach3.h
+hosts/news-mips.h
+hosts/news.h
+hosts/pc532mach.h
+hosts/riscos.h
+hosts/symmetry.h
+hosts/tahoe.h
+hosts/vaxbsd.h
+hosts/vaxult.h
+hosts/vaxult2.h
diff --git a/bfd/po/bfd.pot b/bfd/po/bfd.pot
new file mode 100644
index 00000000000..f7ffbb47b01
--- /dev/null
+++ b/bfd/po/bfd.pot
@@ -0,0 +1,632 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1999-04-18 18:26-0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: aout-adobe.c:182
+#, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr ""
+
+#: aoutx.h:1237 aoutx.h:1651
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr ""
+
+#: aoutx.h:1621
+#, c-format
+msgid ""
+"%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr ""
+
+#: aoutx.h:1623
+msgid "*unknown*"
+msgstr ""
+
+#: aoutx.h:3667
+#, c-format
+msgid "%s: relocateable link from %s to %s not supported"
+msgstr ""
+
+#: archive.c:1716
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr ""
+
+#: archive.c:1987
+msgid "Reading archive file mod timestamp"
+msgstr ""
+
+#. FIXME: bfd can't call perror.
+#: archive.c:2011
+msgid "Writing updated armap timestamp"
+msgstr ""
+
+#: bfd.c:274
+msgid "No error"
+msgstr ""
+
+#: bfd.c:275
+msgid "System call error"
+msgstr ""
+
+#: bfd.c:276
+msgid "Invalid bfd target"
+msgstr ""
+
+#: bfd.c:277
+msgid "File in wrong format"
+msgstr ""
+
+#: bfd.c:278
+msgid "Invalid operation"
+msgstr ""
+
+#: bfd.c:279
+msgid "Memory exhausted"
+msgstr ""
+
+#: bfd.c:280
+msgid "No symbols"
+msgstr ""
+
+#: bfd.c:281
+msgid "Archive has no index; run ranlib to add one"
+msgstr ""
+
+#: bfd.c:282
+msgid "No more archived files"
+msgstr ""
+
+#: bfd.c:283
+msgid "Malformed archive"
+msgstr ""
+
+#: bfd.c:284
+msgid "File format not recognized"
+msgstr ""
+
+#: bfd.c:285
+msgid "File format is ambiguous"
+msgstr ""
+
+#: bfd.c:286
+msgid "Section has no contents"
+msgstr ""
+
+#: bfd.c:287
+msgid "Nonrepresentable section on output"
+msgstr ""
+
+#: bfd.c:288
+msgid "Symbol needs debug section which does not exist"
+msgstr ""
+
+#: bfd.c:289
+msgid "Bad value"
+msgstr ""
+
+#: bfd.c:290
+msgid "File truncated"
+msgstr ""
+
+#: bfd.c:291
+msgid "File too big"
+msgstr ""
+
+#: bfd.c:292
+msgid "#<Invalid error code>"
+msgstr ""
+
+#: bfd.c:679
+#, c-format
+msgid "bfd assertion fail %s:%d"
+msgstr ""
+
+#: binary.c:298
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr ""
+
+#: coff-a29k.c:121
+msgid "Missing IHCONST"
+msgstr ""
+
+#: coff-a29k.c:181
+msgid "Missing IHIHALF"
+msgstr ""
+
+#: coff-a29k.c:213
+msgid "Unrecognized reloc"
+msgstr ""
+
+#: coff-a29k.c:406
+msgid "missing IHCONST reloc"
+msgstr ""
+
+#: coff-a29k.c:497
+msgid "missing IHIHALF reloc"
+msgstr ""
+
+#: coff-alpha.c:880 coff-alpha.c:917
+msgid "GP relative relocation used when GP not defined"
+msgstr ""
+
+#: coff-alpha.c:1486 elf64-alpha.c:4051
+msgid "using multiple gp values"
+msgstr ""
+
+#: coff-alpha.c:1992 coff-mips.c:1435 elf32-mips.c:5175
+msgid "GP relative relocation when GP not defined"
+msgstr ""
+
+#: coff-arm.c:884
+#, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr ""
+
+#: coff-arm.c:913
+#, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr ""
+
+#: coff-arm.c:1192 coff-arm.c:1286
+#, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr ""
+
+#: coff-arm.c:1196
+#, c-format
+msgid " first occurrence: %s: arm call to thumb"
+msgstr ""
+
+#: coff-arm.c:1290
+#, c-format
+msgid " first occurrence: %s: thumb call to arm"
+msgstr ""
+
+#: coff-arm.c:1293
+msgid " consider relinking with --support-old-code enabled"
+msgstr ""
+
+#: coff-arm.c:1581 coff-tic80.c:682 cofflink.c:2722
+#, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr ""
+
+#: coff-arm.c:2036
+#, c-format
+msgid "%s: ERROR: compiled for APCS-%d whereas target %s uses APCS-%d"
+msgstr ""
+
+#: coff-arm.c:2051
+#, c-format
+msgid ""
+"%s: ERROR: passes floats in float registers whereas target %s uses integer "
+"registers"
+msgstr ""
+
+#: coff-arm.c:2054
+#, c-format
+msgid ""
+"%s: ERROR: passes floats in integer registers whereas target %s uses float "
+"registers"
+msgstr ""
+
+#: coff-arm.c:2069
+#, c-format
+msgid ""
+"%s: ERROR: compiled as position independent code, whereas target %s is "
+"absolute position"
+msgstr ""
+
+#: coff-arm.c:2072
+#, c-format
+msgid ""
+"%s: ERROR: compiled as absolute position code, whereas target %s is position "
+"independent"
+msgstr ""
+
+#: coff-arm.c:2101
+#, c-format
+msgid "Warning: input file %s supports interworking, whereas %s does not."
+msgstr ""
+
+#: coff-arm.c:2104
+#, c-format
+msgid "Warning: input file %s does not support interworking, whereas %s does."
+msgstr ""
+
+#: coff-arm.c:2132
+#, c-format
+msgid "private flags = %x:"
+msgstr ""
+
+#: coff-arm.c:2140
+msgid " [floats passed in float registers]"
+msgstr ""
+
+#: coff-arm.c:2142
+msgid " [floats passed in integer registers]"
+msgstr ""
+
+#: coff-arm.c:2145
+msgid " [position independent]"
+msgstr ""
+
+#: coff-arm.c:2147
+msgid " [absolute position]"
+msgstr ""
+
+#: coff-arm.c:2151
+msgid " [interworking flag not initialised]"
+msgstr ""
+
+#: coff-arm.c:2153
+msgid " [interworking supported]"
+msgstr ""
+
+#: coff-arm.c:2155
+msgid " [interworking not supported]"
+msgstr ""
+
+#: coff-arm.c:2204
+#, c-format
+msgid ""
+"Warning: Not setting interworking flag of %s, since it has already been "
+"specified as non-interworking"
+msgstr ""
+
+#: coff-arm.c:2208
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr ""
+
+#: coff-i960.c:135 coff-i960.c:484
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr ""
+
+#: coff-mips.c:875 elf32-mips.c:1183
+msgid "GP relative relocation when _gp not defined"
+msgstr ""
+
+#: coff-mips.c:2433
+msgid "unsupported reloc type"
+msgstr ""
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2470
+msgid "reloc against unsupported section"
+msgstr ""
+
+#: coff-mips.c:2478
+msgid "reloc not properly aligned"
+msgstr ""
+
+#: coff-tic80.c:445
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr ""
+
+#: coff-w65.c:383
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr ""
+
+#: coffcode.h:3413
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr ""
+
+#: coffcode.h:3427
+#, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr ""
+
+#: coffcode.h:3748
+#, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr ""
+
+#: coffcode.h:3932
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr ""
+
+#: coffcode.h:3970
+#, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr ""
+
+#: coffgen.c:1607
+#, c-format
+msgid "%s: bad string table size %lu"
+msgstr ""
+
+#: cofflink.c:423
+#, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr ""
+
+#: cofflink.c:2093
+#, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr ""
+
+#: coffswap.h:879
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr ""
+
+#: coffswap.h:892
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr ""
+
+#: dwarf2.c:420
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr ""
+
+#: dwarf2.c:438
+#, c-format
+msgid "Dwarf Error: Abbrev offset (%u) bigger than abbrev size (%u)."
+msgstr ""
+
+#: dwarf2.c:614
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %d."
+msgstr ""
+
+#: dwarf2.c:720
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr ""
+
+#: dwarf2.c:881
+msgid "Dwarf Error: mangled line number section."
+msgstr ""
+
+#: dwarf2.c:1054 dwarf2.c:1201
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %d."
+msgstr ""
+
+#: dwarf2.c:1162
+#, c-format
+msgid ""
+"Dwarf Error: found dwarf version '%hu', this reader only handles version 2 "
+"information."
+msgstr ""
+
+#: dwarf2.c:1169
+#, c-format
+msgid ""
+"Dwarf Error: found address size '%u', this reader can not handle sizes "
+"greater than '%u'."
+msgstr ""
+
+#: dwarf2.c:1192
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %d."
+msgstr ""
+
+#: ecoff.c:1308
+#, c-format
+msgid "Unknown basic type %d"
+msgstr ""
+
+#: ecoff.c:1580
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1587 ecoff.c:1590
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1602
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+
+#: ecoff.c:1609
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1617
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1622
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1627
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1633
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+
+#: elf-m10200.c:455 elf-m10300.c:667 elf32-d10v.c:490 elf32-fr30.c:650
+#: elf32-m32r.c:1157 elf32-v850.c:1674
+msgid "internal error: out of range error"
+msgstr ""
+
+#: elf-m10200.c:459 elf-m10300.c:671 elf32-d10v.c:494 elf32-fr30.c:654
+#: elf32-m32r.c:1161 elf32-v850.c:1678
+msgid "internal error: unsupported relocation error"
+msgstr ""
+
+#: elf-m10200.c:463 elf-m10300.c:675 elf32-d10v.c:498 elf32-m32r.c:1165
+msgid "internal error: dangerous error"
+msgstr ""
+
+#: elf-m10200.c:467 elf-m10300.c:679 elf32-d10v.c:502 elf32-fr30.c:662
+#: elf32-m32r.c:1169 elf32-v850.c:1698
+msgid "internal error: unknown error"
+msgstr ""
+
+#: elf.c:320
+#, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr ""
+
+#: elf.c:543
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+
+#: elf.c:591
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+
+#: elf.c:693
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+
+#: elf.c:716
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+
+#: elf.c:721
+#, c-format
+msgid " required from %s:\n"
+msgstr ""
+
+#: elf.c:1882
+#, c-format
+msgid ""
+"creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = "
+"0x%.8lx\n"
+msgstr ""
+
+#: elf.c:2481
+#, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr ""
+
+#: elf.c:2584
+#, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr ""
+
+#: elf.c:2710
+#, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x"
+msgstr ""
+
+#: elf.c:2713
+#, c-format
+msgid " whereas segment starts at 0x%x"
+msgstr ""
+
+#: elf.c:2983
+#, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr ""
+
+#: elf.c:3350
+#, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr ""
+
+#: elf.c:3359
+#, c-format
+msgid ""
+"elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = "
+"0x%.8lx%s\n"
+msgstr ""
+
+#: elf.c:3501
+#, c-format
+msgid "%s: warning: Empty loadable segment detected\n"
+msgstr ""
+
+#: elf.c:4774
+#, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr ""
+
+#: elf32-fr30.c:658 elf32-v850.c:1682
+msgid "internal error: dangerous relocation"
+msgstr ""
+
+#: elf32-hppa.c:1215
+msgid "Unsupported call to hppa_elf_reloc"
+msgstr ""
+
+#: elf32-i386.c:1293
+#, c-format
+msgid ""
+"%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr ""
+
+#: elf32-m32r.c:808
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr ""
+
+#: elf32-m32r.c:892 elf32-ppc.c:3071
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr ""
+
+#: elf32-m32r.c:1100
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr ""
+
+#: elf32-m32r.c:1906
+#, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr ""
+
+#: elf32-m32r.c:1929
+#, c-format
+msgid "private flags = %lx"
+msgstr ""
+
+#: elf32-m32r.c:1934
+msgid ": m32r instructions"
+msgstr ""
+
diff --git a/bfd/ppcboot.c b/bfd/ppcboot.c
new file mode 100644
index 00000000000..cbda407ea33
--- /dev/null
+++ b/bfd/ppcboot.c
@@ -0,0 +1,535 @@
+/* BFD back-end for PPCbug boot records.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Michael Meissner, Cygnus Support, <meissner@cygnus.com>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This is a BFD backend which may be used to write PowerPCBug boot objects.
+ It may only be used for output, not input. The intention is that this may
+ be used as an output format for objcopy in order to generate raw binary
+ data.
+
+ This is very simple. The only complication is that the real data
+ will start at some address X, and in some cases we will not want to
+ include X zeroes just to get to that point. Since the start
+ address is not meaningful for this object file format, we use it
+ instead to indicate the number of zeroes to skip at the start of
+ the file. objcopy cooperates by specially setting the start
+ address to zero by default. */
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+/* PPCbug location structure */
+typedef struct ppcboot_location {
+ bfd_byte ind;
+ bfd_byte head;
+ bfd_byte sector;
+ bfd_byte cylinder;
+} ppcboot_location_t;
+
+/* PPCbug partition table layout */
+typedef struct ppcboot_partition {
+ ppcboot_location_t partition_begin; /* partition begin */
+ ppcboot_location_t partition_end; /* partition end */
+ bfd_byte sector_begin[4]; /* 32-bit start RBA (zero-based), little endian */
+ bfd_byte sector_length[4]; /* 32-bit RBA count (one-based), little endian */
+} ppcboot_partition_t;
+
+/* PPCbug boot layout. */
+typedef struct ppcboot_hdr {
+ bfd_byte pc_compatibility[446]; /* x86 instruction field */
+ ppcboot_partition_t partition[4]; /* partition information */
+ bfd_byte signature[2]; /* 0x55 and 0xaa */
+ bfd_byte entry_offset[4]; /* entry point offset, little endian */
+ bfd_byte length[4]; /* load image length, little endian */
+ bfd_byte flags; /* flag field */
+ bfd_byte os_id; /* OS_ID */
+ char partition_name[32]; /* partition name */
+ bfd_byte reserved1[470]; /* reserved */
+} ppcboot_hdr_t;
+
+/* Signature bytes for last 2 bytes of the 512 byte record */
+#define SIGNATURE0 0x55
+#define SIGNATURE1 0xaa
+
+/* PowerPC boot type */
+#define PPC_IND 0x41
+
+/* Information needed for ppcboot header */
+typedef struct ppcboot_data {
+ ppcboot_hdr_t header; /* raw header */
+ asection *sec; /* single section */
+} ppcboot_data_t;
+
+/* Any bfd we create by reading a ppcboot file has three symbols:
+ a start symbol, an end symbol, and an absolute length symbol. */
+#define PPCBOOT_SYMS 3
+
+static boolean ppcboot_mkobject PARAMS ((bfd *));
+static const bfd_target *ppcboot_object_p PARAMS ((bfd *));
+static boolean ppcboot_set_arch_mach
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+static boolean ppcboot_get_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static long ppcboot_get_symtab_upper_bound PARAMS ((bfd *));
+static char *mangle_name PARAMS ((bfd *, char *));
+static long ppcboot_get_symtab PARAMS ((bfd *, asymbol **));
+static asymbol *ppcboot_make_empty_symbol PARAMS ((bfd *));
+static void ppcboot_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static boolean ppcboot_set_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static int ppcboot_sizeof_headers PARAMS ((bfd *, boolean));
+static boolean ppcboot_bfd_print_private_bfd_data PARAMS ((bfd *, PTR));
+
+#define ppcboot_set_tdata(abfd, ptr) ((abfd)->tdata.any = (PTR) (ptr))
+#define ppcboot_get_tdata(abfd) ((ppcboot_data_t *) ((abfd)->tdata.any))
+
+/* Create a ppcboot object. Invoked via bfd_set_format. */
+
+static boolean
+ppcboot_mkobject (abfd)
+ bfd *abfd;
+{
+ if (!ppcboot_get_tdata (abfd))
+ ppcboot_set_tdata (abfd, bfd_zalloc (abfd, sizeof (ppcboot_data_t)));
+
+ return true;
+}
+
+
+/* Set the architecture to PowerPC */
+static boolean
+ppcboot_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ if (arch == bfd_arch_unknown)
+ arch = bfd_arch_powerpc;
+
+ else if (arch != bfd_arch_powerpc)
+ return false;
+
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+
+/* Any file may be considered to be a ppcboot file, provided the target
+ was not defaulted. That is, it must be explicitly specified as
+ being ppcboot. */
+
+static const bfd_target *
+ppcboot_object_p (abfd)
+ bfd *abfd;
+{
+ struct stat statbuf;
+ asection *sec;
+ ppcboot_hdr_t hdr;
+ size_t i;
+ ppcboot_data_t *tdata;
+
+ BFD_ASSERT (sizeof (ppcboot_hdr_t) == 1024);
+
+ if (abfd->target_defaulted)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Find the file size. */
+ if (bfd_stat (abfd, &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ if ((size_t) statbuf.st_size < sizeof (ppcboot_hdr_t))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_read ((PTR) &hdr, sizeof (hdr), 1, abfd) != sizeof (hdr))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+
+ return NULL;
+ }
+
+ /* Now do some basic checks. */
+ for (i = 0; i < sizeof (hdr.pc_compatibility); i++)
+ if (hdr.pc_compatibility[i])
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (hdr.signature[0] != SIGNATURE0 || hdr.signature[1] != SIGNATURE1)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (hdr.partition[0].partition_end.ind != PPC_IND)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ abfd->symcount = PPCBOOT_SYMS;
+
+ /* One data section. */
+ sec = bfd_make_section (abfd, ".data");
+ if (sec == NULL)
+ return NULL;
+ sec->flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_CODE | SEC_HAS_CONTENTS;
+ sec->vma = 0;
+ sec->_raw_size = statbuf.st_size - sizeof (ppcboot_hdr_t);
+ sec->filepos = sizeof (ppcboot_hdr_t);
+
+ ppcboot_mkobject (abfd);
+ tdata = ppcboot_get_tdata (abfd);
+ tdata->sec = sec;
+ memcpy ((PTR) &tdata->header, (PTR) &hdr, sizeof (ppcboot_hdr_t));
+
+ ppcboot_set_arch_mach (abfd, bfd_arch_powerpc, 0);
+ return abfd->xvec;
+}
+
+#define ppcboot_close_and_cleanup _bfd_generic_close_and_cleanup
+#define ppcboot_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define ppcboot_new_section_hook _bfd_generic_new_section_hook
+
+
+/* Get contents of the only section. */
+
+static boolean
+ppcboot_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (bfd_seek (abfd, offset + sizeof(ppcboot_hdr_t), SEEK_SET) != 0
+ || bfd_read (location, 1, count, abfd) != count)
+ return false;
+ return true;
+}
+
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+ppcboot_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ return (PPCBOOT_SYMS + 1) * sizeof (asymbol *);
+}
+
+
+/* Create a symbol name based on the bfd's filename. */
+
+static char *
+mangle_name (abfd, suffix)
+ bfd *abfd;
+ char *suffix;
+{
+ int size;
+ char *buf;
+ char *p;
+
+ size = (strlen (bfd_get_filename (abfd))
+ + strlen (suffix)
+ + sizeof "_ppcboot__");
+
+ buf = (char *) bfd_alloc (abfd, size);
+ if (buf == NULL)
+ return "";
+
+ sprintf (buf, "_ppcboot_%s_%s", bfd_get_filename (abfd), suffix);
+
+ /* Change any non-alphanumeric characters to underscores. */
+ for (p = buf; *p; p++)
+ if (! isalnum ((unsigned char) *p))
+ *p = '_';
+
+ return buf;
+}
+
+
+/* Return the symbol table. */
+
+static long
+ppcboot_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ asection *sec = ppcboot_get_tdata (abfd)->sec;
+ asymbol *syms;
+ unsigned int i;
+
+ syms = (asymbol *) bfd_alloc (abfd, PPCBOOT_SYMS * sizeof (asymbol));
+ if (syms == NULL)
+ return false;
+
+ /* Start symbol. */
+ syms[0].the_bfd = abfd;
+ syms[0].name = mangle_name (abfd, "start");
+ syms[0].value = 0;
+ syms[0].flags = BSF_GLOBAL;
+ syms[0].section = sec;
+ syms[0].udata.p = NULL;
+
+ /* End symbol. */
+ syms[1].the_bfd = abfd;
+ syms[1].name = mangle_name (abfd, "end");
+ syms[1].value = sec->_raw_size;
+ syms[1].flags = BSF_GLOBAL;
+ syms[1].section = sec;
+ syms[1].udata.p = NULL;
+
+ /* Size symbol. */
+ syms[2].the_bfd = abfd;
+ syms[2].name = mangle_name (abfd, "size");
+ syms[2].value = sec->_raw_size;
+ syms[2].flags = BSF_GLOBAL;
+ syms[2].section = bfd_abs_section_ptr;
+ syms[2].udata.p = NULL;
+
+ for (i = 0; i < PPCBOOT_SYMS; i++)
+ *alocation++ = syms++;
+ *alocation = NULL;
+
+ return PPCBOOT_SYMS;
+}
+
+
+/* Make an empty symbol. */
+
+static asymbol *
+ppcboot_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ return (asymbol *) bfd_alloc (abfd, sizeof (asymbol));
+}
+
+
+#define ppcboot_print_symbol _bfd_nosymbols_print_symbol
+
+/* Get information about a symbol. */
+
+static void
+ppcboot_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+#define ppcboot_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define ppcboot_get_lineno _bfd_nosymbols_get_lineno
+#define ppcboot_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define ppcboot_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define ppcboot_read_minisymbols _bfd_generic_read_minisymbols
+#define ppcboot_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define ppcboot_get_reloc_upper_bound \
+ ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
+#define ppcboot_canonicalize_reloc \
+ ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
+#define ppcboot_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+/* Write section contents of a ppcboot file. */
+
+static boolean
+ppcboot_set_section_contents (abfd, sec, data, offset, size)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ file_ptr offset;
+ bfd_size_type size;
+{
+ if (! abfd->output_has_begun)
+ {
+ bfd_vma low;
+ asection *s;
+
+ /* The lowest section VMA sets the virtual address of the start
+ of the file. We use the set the file position of all the
+ sections. */
+ low = abfd->sections->vma;
+ for (s = abfd->sections->next; s != NULL; s = s->next)
+ if (s->vma < low)
+ low = s->vma;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ s->filepos = s->vma - low;
+
+ abfd->output_has_begun = true;
+ }
+
+ return _bfd_generic_set_section_contents (abfd, sec, data, offset, size);
+}
+
+
+static int
+ppcboot_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return sizeof (ppcboot_hdr_t);
+}
+
+
+/* Print out the program headers. */
+
+static boolean
+ppcboot_bfd_print_private_bfd_data (abfd, farg)
+ bfd *abfd;
+ PTR farg;
+{
+ FILE *f = (FILE *)farg;
+ ppcboot_data_t *tdata = ppcboot_get_tdata (abfd);
+ long entry_offset = bfd_getl_signed_32 ((PTR) tdata->header.entry_offset);
+ long length = bfd_getl_signed_32 ((PTR) tdata->header.length);
+ int i;
+
+ fprintf (f, _("\nppcboot header:\n"));
+ fprintf (f, _("Entry offset = 0x%.8lx (%ld)\n"), entry_offset, entry_offset);
+ fprintf (f, _("Length = 0x%.8lx (%ld)\n"), length, length);
+
+ if (tdata->header.flags)
+ fprintf (f, _("Flag field = 0x%.2x\n"), tdata->header.flags);
+
+ if (tdata->header.os_id)
+ fprintf (f, "OS_ID = 0x%.2x\n", tdata->header.os_id);
+
+ if (tdata->header.partition_name)
+ fprintf (f, _("Partition name = \"%s\"\n"), tdata->header.partition_name);
+
+ for (i = 0; i < 4; i++)
+ {
+ long sector_begin = bfd_getl_signed_32 ((PTR) tdata->header.partition[i].sector_begin);
+ long sector_length = bfd_getl_signed_32 ((PTR) tdata->header.partition[i].sector_length);
+
+ /* Skip all 0 entries */
+ if (!tdata->header.partition[i].partition_begin.ind
+ && !tdata->header.partition[i].partition_begin.head
+ && !tdata->header.partition[i].partition_begin.sector
+ && !tdata->header.partition[i].partition_begin.cylinder
+ && !tdata->header.partition[i].partition_end.ind
+ && !tdata->header.partition[i].partition_end.head
+ && !tdata->header.partition[i].partition_end.sector
+ && !tdata->header.partition[i].partition_end.cylinder
+ && !sector_begin && !sector_length)
+ continue;
+
+ fprintf (f, _("\nPartition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i,
+ tdata->header.partition[i].partition_begin.ind,
+ tdata->header.partition[i].partition_begin.head,
+ tdata->header.partition[i].partition_begin.sector,
+ tdata->header.partition[i].partition_begin.cylinder);
+
+ fprintf (f, _("Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"), i,
+ tdata->header.partition[i].partition_end.ind,
+ tdata->header.partition[i].partition_end.head,
+ tdata->header.partition[i].partition_end.sector,
+ tdata->header.partition[i].partition_end.cylinder);
+
+ fprintf (f, _("Partition[%d] sector = 0x%.8lx (%ld)\n"), i, sector_begin, sector_begin);
+ fprintf (f, _("Partition[%d] length = 0x%.8lx (%ld)\n"), i, sector_length, sector_length);
+ }
+
+ fprintf (f, "\n");
+ return true;
+}
+
+
+#define ppcboot_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define ppcboot_bfd_relax_section bfd_generic_relax_section
+#define ppcboot_bfd_gc_sections bfd_generic_gc_sections
+#define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define ppcboot_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define ppcboot_bfd_final_link _bfd_generic_final_link
+#define ppcboot_bfd_link_split_section _bfd_generic_link_split_section
+#define ppcboot_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#define ppcboot_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#define ppcboot_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define ppcboot_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
+#define ppcboot_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#define ppcboot_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define ppcboot_bfd_print_private_bfd_dat ppcboot_bfd_print_private_bfd_data
+
+const bfd_target ppcboot_vec =
+{
+ "ppcboot", /* name */
+ bfd_target_unknown_flavour, /* flavour */
+ BFD_ENDIAN_BIG, /* byteorder is big endian for code */
+ BFD_ENDIAN_LITTLE, /* header_byteorder */
+ EXEC_P, /* object_flags */
+ (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+ { /* bfd_check_format */
+ _bfd_dummy_target,
+ ppcboot_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format */
+ bfd_false,
+ ppcboot_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (ppcboot),
+ BFD_JUMP_TABLE_COPY (ppcboot),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (ppcboot),
+ BFD_JUMP_TABLE_RELOCS (ppcboot),
+ BFD_JUMP_TABLE_WRITE (ppcboot),
+ BFD_JUMP_TABLE_LINK (ppcboot),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL
+};
diff --git a/bfd/ptrace-core.c b/bfd/ptrace-core.c
new file mode 100644
index 00000000000..2b4fdbbd01f
--- /dev/null
+++ b/bfd/ptrace-core.c
@@ -0,0 +1,230 @@
+/* BFD backend for core files which use the ptrace_user structure
+ Copyright 1993, 94, 95, 96, 1998 Free Software Foundation, Inc.
+ The structure of this file is based on trad-core.c written by John Gilmore
+ of Cygnus Support.
+ Modified to work with the ptrace_user structure by Kevin A. Buettner.
+ (Longterm it may be better to merge this file with trad-core.c)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef PTRACE_CORE
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <sys/ptrace.h>
+
+
+struct trad_core_struct
+ {
+ asection *data_section;
+ asection *stack_section;
+ asection *reg_section;
+ struct ptrace_user u;
+ };
+
+#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
+#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
+#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
+#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
+
+/* forward declarations */
+
+const bfd_target *ptrace_unix_core_file_p PARAMS ((bfd *abfd));
+char * ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd));
+int ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd));
+boolean ptrace_unix_core_file_matches_executable_p
+ PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+static void swap_abort PARAMS ((void));
+
+/* ARGSUSED */
+const bfd_target *
+ptrace_unix_core_file_p (abfd)
+ bfd *abfd;
+
+{
+ int val;
+ struct ptrace_user u;
+ struct trad_core_struct *rawptr;
+
+ val = bfd_read ((void *)&u, 1, sizeof u, abfd);
+ if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC
+ || u.pt_rev != _BCS_PTRACE_REV)
+ {
+ /* Too small to be a core file */
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ /* Allocate both the upage and the struct core_data at once, so
+ a single free() will free them both. */
+ rawptr = (struct trad_core_struct *)
+ bfd_zalloc (abfd, sizeof (struct trad_core_struct));
+
+ if (rawptr == NULL)
+ return 0;
+
+ abfd->tdata.trad_core_data = rawptr;
+
+ rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
+
+ /* Create the sections. This is raunchy, but bfd_close wants to free
+ them separately. */
+
+ core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_stacksec (abfd) == NULL)
+ return NULL;
+ core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_datasec (abfd) == NULL)
+ return NULL;
+ core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_regsec (abfd) == NULL)
+ return NULL;
+
+ core_stacksec (abfd)->name = ".stack";
+ core_datasec (abfd)->name = ".data";
+ core_regsec (abfd)->name = ".reg";
+
+ /* FIXME: Need to worry about shared memory, library data, and library
+ text. I don't think that any of these things are supported on the
+ system on which I am developing this for though. */
+
+
+ core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
+
+ core_datasec (abfd)->_raw_size = u.pt_dsize;
+ core_stacksec (abfd)->_raw_size = u.pt_ssize;
+ core_regsec (abfd)->_raw_size = sizeof(u);
+
+ core_datasec (abfd)->vma = u.pt_o_data_start;
+ core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize;
+ core_regsec (abfd)->vma = 0 - sizeof(u); /* see trad-core.c */
+
+ core_datasec (abfd)->filepos = (int) u.pt_dataptr;
+ core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize);
+ core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */
+
+ /* Align to word at least */
+ core_stacksec (abfd)->alignment_power = 2;
+ core_datasec (abfd)->alignment_power = 2;
+ core_regsec (abfd)->alignment_power = 2;
+
+ abfd->sections = core_stacksec (abfd);
+ core_stacksec (abfd)->next = core_datasec (abfd);
+ core_datasec (abfd)->next = core_regsec (abfd);
+ abfd->section_count = 3;
+
+ return abfd->xvec;
+}
+
+char *
+ptrace_unix_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ char *com = abfd->tdata.trad_core_data->u.pt_comm;
+ if (*com)
+ return com;
+ else
+ return 0;
+}
+
+/* ARGSUSED */
+int
+ptrace_unix_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num;
+}
+
+/* ARGSUSED */
+boolean
+ptrace_unix_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ /* FIXME: Use pt_timdat field of the ptrace_user structure to match
+ the date of the executable */
+ return true;
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target ptrace_core_vec =
+ {
+ "trad-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ ptrace_unix_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (ptrace_unix),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
+
+#endif /* PTRACE_CORE */
diff --git a/bfd/reloc.c b/bfd/reloc.c
new file mode 100644
index 00000000000..888581493b4
--- /dev/null
+++ b/bfd/reloc.c
@@ -0,0 +1,2842 @@
+/* BFD support for handling relocation entries.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ Relocations
+
+ BFD maintains relocations in much the same way it maintains
+ symbols: they are left alone until required, then read in
+ en-mass and translated into an internal form. A common
+ routine <<bfd_perform_relocation>> acts upon the
+ canonical form to do the fixup.
+
+ Relocations are maintained on a per section basis,
+ while symbols are maintained on a per BFD basis.
+
+ All that a back end has to do to fit the BFD interface is to create
+ a <<struct reloc_cache_entry>> for each relocation
+ in a particular section, and fill in the right bits of the structures.
+
+@menu
+@* typedef arelent::
+@* howto manager::
+@end menu
+
+*/
+
+/* DO compile in the reloc_code name table from libbfd.h. */
+#define _BFD_MAKE_TABLE_bfd_reloc_code_real
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+/*
+DOCDD
+INODE
+ typedef arelent, howto manager, Relocations, Relocations
+
+SUBSECTION
+ typedef arelent
+
+ This is the structure of a relocation entry:
+
+CODE_FRAGMENT
+.
+.typedef enum bfd_reloc_status
+.{
+. {* No errors detected *}
+. bfd_reloc_ok,
+.
+. {* The relocation was performed, but there was an overflow. *}
+. bfd_reloc_overflow,
+.
+. {* The address to relocate was not within the section supplied. *}
+. bfd_reloc_outofrange,
+.
+. {* Used by special functions *}
+. bfd_reloc_continue,
+.
+. {* Unsupported relocation size requested. *}
+. bfd_reloc_notsupported,
+.
+. {* Unused *}
+. bfd_reloc_other,
+.
+. {* The symbol to relocate against was undefined. *}
+. bfd_reloc_undefined,
+.
+. {* The relocation was performed, but may not be ok - presently
+. generated only when linking i960 coff files with i960 b.out
+. symbols. If this type is returned, the error_message argument
+. to bfd_perform_relocation will be set. *}
+. bfd_reloc_dangerous
+. }
+. bfd_reloc_status_type;
+.
+.
+.typedef struct reloc_cache_entry
+.{
+. {* A pointer into the canonical table of pointers *}
+. struct symbol_cache_entry **sym_ptr_ptr;
+.
+. {* offset in section *}
+. bfd_size_type address;
+.
+. {* addend for relocation value *}
+. bfd_vma addend;
+.
+. {* Pointer to how to perform the required relocation *}
+. reloc_howto_type *howto;
+.
+.} arelent;
+
+*/
+
+/*
+DESCRIPTION
+
+ Here is a description of each of the fields within an <<arelent>>:
+
+ o <<sym_ptr_ptr>>
+
+ The symbol table pointer points to a pointer to the symbol
+ associated with the relocation request. It is
+ the pointer into the table returned by the back end's
+ <<get_symtab>> action. @xref{Symbols}. The symbol is referenced
+ through a pointer to a pointer so that tools like the linker
+ can fix up all the symbols of the same name by modifying only
+ one pointer. The relocation routine looks in the symbol and
+ uses the base of the section the symbol is attached to and the
+ value of the symbol as the initial relocation offset. If the
+ symbol pointer is zero, then the section provided is looked up.
+
+ o <<address>>
+
+ The <<address>> field gives the offset in bytes from the base of
+ the section data which owns the relocation record to the first
+ byte of relocatable information. The actual data relocated
+ will be relative to this point; for example, a relocation
+ type which modifies the bottom two bytes of a four byte word
+ would not touch the first byte pointed to in a big endian
+ world.
+
+ o <<addend>>
+
+ The <<addend>> is a value provided by the back end to be added (!)
+ to the relocation offset. Its interpretation is dependent upon
+ the howto. For example, on the 68k the code:
+
+
+| char foo[];
+| main()
+| {
+| return foo[0x12345678];
+| }
+
+ Could be compiled into:
+
+| linkw fp,#-4
+| moveb @@#12345678,d0
+| extbl d0
+| unlk fp
+| rts
+
+
+ This could create a reloc pointing to <<foo>>, but leave the
+ offset in the data, something like:
+
+
+|RELOCATION RECORDS FOR [.text]:
+|offset type value
+|00000006 32 _foo
+|
+|00000000 4e56 fffc ; linkw fp,#-4
+|00000004 1039 1234 5678 ; moveb @@#12345678,d0
+|0000000a 49c0 ; extbl d0
+|0000000c 4e5e ; unlk fp
+|0000000e 4e75 ; rts
+
+
+ Using coff and an 88k, some instructions don't have enough
+ space in them to represent the full address range, and
+ pointers have to be loaded in two parts. So you'd get something like:
+
+
+| or.u r13,r0,hi16(_foo+0x12345678)
+| ld.b r2,r13,lo16(_foo+0x12345678)
+| jmp r1
+
+
+ This should create two relocs, both pointing to <<_foo>>, and with
+ 0x12340000 in their addend field. The data would consist of:
+
+
+|RELOCATION RECORDS FOR [.text]:
+|offset type value
+|00000002 HVRT16 _foo+0x12340000
+|00000006 LVRT16 _foo+0x12340000
+|
+|00000000 5da05678 ; or.u r13,r0,0x5678
+|00000004 1c4d5678 ; ld.b r2,r13,0x5678
+|00000008 f400c001 ; jmp r1
+
+
+ The relocation routine digs out the value from the data, adds
+ it to the addend to get the original offset, and then adds the
+ value of <<_foo>>. Note that all 32 bits have to be kept around
+ somewhere, to cope with carry from bit 15 to bit 16.
+
+ One further example is the sparc and the a.out format. The
+ sparc has a similar problem to the 88k, in that some
+ instructions don't have room for an entire offset, but on the
+ sparc the parts are created in odd sized lumps. The designers of
+ the a.out format chose to not use the data within the section
+ for storing part of the offset; all the offset is kept within
+ the reloc. Anything in the data should be ignored.
+
+| save %sp,-112,%sp
+| sethi %hi(_foo+0x12345678),%g2
+| ldsb [%g2+%lo(_foo+0x12345678)],%i0
+| ret
+| restore
+
+ Both relocs contain a pointer to <<foo>>, and the offsets
+ contain junk.
+
+
+|RELOCATION RECORDS FOR [.text]:
+|offset type value
+|00000004 HI22 _foo+0x12345678
+|00000008 LO10 _foo+0x12345678
+|
+|00000000 9de3bf90 ; save %sp,-112,%sp
+|00000004 05000000 ; sethi %hi(_foo+0),%g2
+|00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0
+|0000000c 81c7e008 ; ret
+|00000010 81e80000 ; restore
+
+
+ o <<howto>>
+
+ The <<howto>> field can be imagined as a
+ relocation instruction. It is a pointer to a structure which
+ contains information on what to do with all of the other
+ information in the reloc record and data section. A back end
+ would normally have a relocation instruction set and turn
+ relocations into pointers to the correct structure on input -
+ but it would be possible to create each howto field on demand.
+
+*/
+
+/*
+SUBSUBSECTION
+ <<enum complain_overflow>>
+
+ Indicates what sort of overflow checking should be done when
+ performing a relocation.
+
+CODE_FRAGMENT
+.
+.enum complain_overflow
+.{
+. {* Do not complain on overflow. *}
+. complain_overflow_dont,
+.
+. {* Complain if the bitfield overflows, whether it is considered
+. as signed or unsigned. *}
+. complain_overflow_bitfield,
+.
+. {* Complain if the value overflows when considered as signed
+. number. *}
+. complain_overflow_signed,
+.
+. {* Complain if the value overflows when considered as an
+. unsigned number. *}
+. complain_overflow_unsigned
+.};
+
+*/
+
+/*
+SUBSUBSECTION
+ <<reloc_howto_type>>
+
+ The <<reloc_howto_type>> is a structure which contains all the
+ information that libbfd needs to know to tie up a back end's data.
+
+CODE_FRAGMENT
+.struct symbol_cache_entry; {* Forward declaration *}
+.
+.struct reloc_howto_struct
+.{
+. {* The type field has mainly a documentary use - the back end can
+. do what it wants with it, though normally the back end's
+. external idea of what a reloc number is stored
+. in this field. For example, a PC relative word relocation
+. in a coff environment has the type 023 - because that's
+. what the outside world calls a R_PCRWORD reloc. *}
+. unsigned int type;
+.
+. {* The value the final relocation is shifted right by. This drops
+. unwanted data from the relocation. *}
+. unsigned int rightshift;
+.
+. {* The size of the item to be relocated. This is *not* a
+. power-of-two measure. To get the number of bytes operated
+. on by a type of relocation, use bfd_get_reloc_size. *}
+. int size;
+.
+. {* The number of bits in the item to be relocated. This is used
+. when doing overflow checking. *}
+. unsigned int bitsize;
+.
+. {* Notes that the relocation is relative to the location in the
+. data section of the addend. The relocation function will
+. subtract from the relocation value the address of the location
+. being relocated. *}
+. boolean pc_relative;
+.
+. {* The bit position of the reloc value in the destination.
+. The relocated value is left shifted by this amount. *}
+. unsigned int bitpos;
+.
+. {* What type of overflow error should be checked for when
+. relocating. *}
+. enum complain_overflow complain_on_overflow;
+.
+. {* If this field is non null, then the supplied function is
+. called rather than the normal function. This allows really
+. strange relocation methods to be accomodated (e.g., i960 callj
+. instructions). *}
+. bfd_reloc_status_type (*special_function)
+. PARAMS ((bfd *abfd,
+. arelent *reloc_entry,
+. struct symbol_cache_entry *symbol,
+. PTR data,
+. asection *input_section,
+. bfd *output_bfd,
+. char **error_message));
+.
+. {* The textual name of the relocation type. *}
+. char *name;
+.
+. {* When performing a partial link, some formats must modify the
+. relocations rather than the data - this flag signals this.*}
+. boolean partial_inplace;
+.
+. {* The src_mask selects which parts of the read in data
+. are to be used in the relocation sum. E.g., if this was an 8 bit
+. bit of data which we read and relocated, this would be
+. 0x000000ff. When we have relocs which have an addend, such as
+. sun4 extended relocs, the value in the offset part of a
+. relocating field is garbage so we never use it. In this case
+. the mask would be 0x00000000. *}
+. bfd_vma src_mask;
+.
+. {* The dst_mask selects which parts of the instruction are replaced
+. into the instruction. In most cases src_mask == dst_mask,
+. except in the above special case, where dst_mask would be
+. 0x000000ff, and src_mask would be 0x00000000. *}
+. bfd_vma dst_mask;
+.
+. {* When some formats create PC relative instructions, they leave
+. the value of the pc of the place being relocated in the offset
+. slot of the instruction, so that a PC relative relocation can
+. be made just by adding in an ordinary offset (e.g., sun3 a.out).
+. Some formats leave the displacement part of an instruction
+. empty (e.g., m88k bcs); this flag signals the fact.*}
+. boolean pcrel_offset;
+.
+.};
+
+*/
+
+/*
+FUNCTION
+ The HOWTO Macro
+
+DESCRIPTION
+ The HOWTO define is horrible and will go away.
+
+
+.#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+. {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+
+DESCRIPTION
+ And will be replaced with the totally magic way. But for the
+ moment, we are compatible, so do it this way.
+
+
+.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN)
+.
+DESCRIPTION
+ Helper routine to turn a symbol into a relocation value.
+
+.#define HOWTO_PREPARE(relocation, symbol) \
+. { \
+. if (symbol != (asymbol *)NULL) { \
+. if (bfd_is_com_section (symbol->section)) { \
+. relocation = 0; \
+. } \
+. else { \
+. relocation = symbol->value; \
+. } \
+. } \
+.}
+
+*/
+
+/*
+FUNCTION
+ bfd_get_reloc_size
+
+SYNOPSIS
+ unsigned int bfd_get_reloc_size (reloc_howto_type *);
+
+DESCRIPTION
+ For a reloc_howto_type that operates on a fixed number of bytes,
+ this returns the number of bytes operated on.
+ */
+
+unsigned int
+bfd_get_reloc_size (howto)
+ reloc_howto_type *howto;
+{
+ switch (howto->size)
+ {
+ case 0: return 1;
+ case 1: return 2;
+ case 2: return 4;
+ case 3: return 0;
+ case 4: return 8;
+ case 8: return 16;
+ case -2: return 4;
+ default: abort ();
+ }
+}
+
+/*
+TYPEDEF
+ arelent_chain
+
+DESCRIPTION
+
+ How relocs are tied together in an <<asection>>:
+
+.typedef struct relent_chain {
+. arelent relent;
+. struct relent_chain *next;
+.} arelent_chain;
+
+*/
+
+/* N_ONES produces N one bits, without overflowing machine arithmetic. */
+#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
+
+/*
+FUNCTION
+ bfd_check_overflow
+
+SYNOPSIS
+ bfd_reloc_status_type
+ bfd_check_overflow
+ (enum complain_overflow how,
+ unsigned int bitsize,
+ unsigned int rightshift,
+ unsigned int addrsize,
+ bfd_vma relocation);
+
+DESCRIPTION
+ Perform overflow checking on @var{relocation} which has
+ @var{bitsize} significant bits and will be shifted right by
+ @var{rightshift} bits, on a machine with addresses containing
+ @var{addrsize} significant bits. The result is either of
+ @code{bfd_reloc_ok} or @code{bfd_reloc_overflow}.
+
+*/
+
+bfd_reloc_status_type
+bfd_check_overflow (how, bitsize, rightshift, addrsize, relocation)
+ enum complain_overflow how;
+ unsigned int bitsize;
+ unsigned int rightshift;
+ unsigned int addrsize;
+ bfd_vma relocation;
+{
+ bfd_vma fieldmask, addrmask, signmask, ss, a;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+
+ a = relocation;
+
+ /* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not,
+ we'll be permissive: extra bits in the field mask will
+ automatically extend the address mask for purposes of the
+ overflow check. */
+ fieldmask = N_ONES (bitsize);
+ addrmask = N_ONES (addrsize) | fieldmask;
+
+ switch (how)
+ {
+ case complain_overflow_dont:
+ break;
+
+ case complain_overflow_signed:
+ /* If any sign bits are set, all sign bits must be set. That
+ is, A must be a valid negative address after shifting. */
+ a = (a & addrmask) >> rightshift;
+ signmask = ~ (fieldmask >> 1);
+ ss = a & signmask;
+ if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
+ flag = bfd_reloc_overflow;
+ break;
+
+ case complain_overflow_unsigned:
+ /* We have an overflow if the address does not fit in the field. */
+ a = (a & addrmask) >> rightshift;
+ if ((a & ~ fieldmask) != 0)
+ flag = bfd_reloc_overflow;
+ break;
+
+ case complain_overflow_bitfield:
+ /* Bitfields are sometimes signed, sometimes unsigned. We
+ overflow if the value has some, but not all, bits set outside
+ the field, or if it has any bits set outside the field but
+ the sign bit is not set. */
+ a >>= rightshift;
+ if ((a & ~ fieldmask) != 0)
+ {
+ signmask = (fieldmask >> 1) + 1;
+ ss = (signmask << rightshift) - 1;
+ if ((ss | relocation) != ~ (bfd_vma) 0)
+ flag = bfd_reloc_overflow;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return flag;
+}
+
+/*
+FUNCTION
+ bfd_perform_relocation
+
+SYNOPSIS
+ bfd_reloc_status_type
+ bfd_perform_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ PTR data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message);
+
+DESCRIPTION
+ If @var{output_bfd} is supplied to this function, the
+ generated image will be relocatable; the relocations are
+ copied to the output file after they have been changed to
+ reflect the new state of the world. There are two ways of
+ reflecting the results of partial linkage in an output file:
+ by modifying the output data in place, and by modifying the
+ relocation record. Some native formats (e.g., basic a.out and
+ basic coff) have no way of specifying an addend in the
+ relocation type, so the addend has to go in the output data.
+ This is no big deal since in these formats the output data
+ slot will always be big enough for the addend. Complex reloc
+ types with addends were invented to solve just this problem.
+ The @var{error_message} argument is set to an error message if
+ this return @code{bfd_reloc_dangerous}.
+
+*/
+
+
+bfd_reloc_status_type
+bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
+ error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *reloc_target_output_section;
+ asymbol *symbol;
+
+ symbol = *(reloc_entry->sym_ptr_ptr);
+ if (bfd_is_abs_section (symbol->section)
+ && output_bfd != (bfd *) NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* If we are not producing relocateable output, return an error if
+ the symbol is not defined. An undefined weak symbol is
+ considered to have a value of zero (SVR4 ABI, p. 4-27). */
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && output_bfd == (bfd *) NULL)
+ flag = bfd_reloc_undefined;
+
+ /* If there is a function supplied to handle this relocation type,
+ call it. It'll return `bfd_reloc_continue' if further processing
+ can be done. */
+ if (howto->special_function)
+ {
+ bfd_reloc_status_type cont;
+ cont = howto->special_function (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+ if (cont != bfd_reloc_continue)
+ return cont;
+ }
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (output_bfd && howto->partial_inplace == false)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ if (howto->pc_relative == true)
+ {
+ /* This is a PC relative relocation. We want to set RELOCATION
+ to the distance between the address of the symbol and the
+ location. RELOCATION is already the address of the symbol.
+
+ We start by subtracting the address of the section containing
+ the location.
+
+ If pcrel_offset is set, we must further subtract the position
+ of the location within the section. Some targets arrange for
+ the addend to be the negative of the position of the location
+ within the section; for example, i386-aout does this. For
+ i386-aout, pcrel_offset is false. Some other targets do not
+ include the position of the location; for example, m88kbcs,
+ or ELF. For those targets, pcrel_offset is true.
+
+ If we are producing relocateable output, then we must ensure
+ that this reloc will be correctly computed when the final
+ relocation is done. If pcrel_offset is false we want to wind
+ up with the negative of the location within the section,
+ which means we must adjust the existing addend by the change
+ in the location within the section. If pcrel_offset is true
+ we do not want to adjust the existing addend at all.
+
+ FIXME: This seems logical to me, but for the case of
+ producing relocateable output it is not what the code
+ actually does. I don't want to change it, because it seems
+ far too likely that something will break. */
+
+ relocation -=
+ input_section->output_section->vma + input_section->output_offset;
+
+ if (howto->pcrel_offset == true)
+ relocation -= reloc_entry->address;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ if (howto->partial_inplace == false)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Modify the reloc
+ inplace to reflect what we now know. */
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return flag;
+ }
+ else
+ {
+ /* This is a partial relocation, but inplace, so modify the
+ reloc record a bit.
+
+ If we've relocated with a symbol with a section, change
+ into a ref to the section belonging to the symbol. */
+
+ reloc_entry->address += input_section->output_offset;
+
+ /* WTF?? */
+ if (abfd->xvec->flavour == bfd_target_coff_flavour
+ && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0
+ && strcmp (abfd->xvec->name, "xcoff-powermac") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
+ {
+#if 1
+ /* For m68k-coff, the addend was being subtracted twice during
+ relocation with -r. Removing the line below this comment
+ fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled: --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers. I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way. There may very well be a reason that the
+code works as it does.
+
+Hmmm. The first obvious point is that bfd_perform_relocation should
+not have any tests that depend upon the flavour. It's seem like
+entirely the wrong place for such a thing. The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF. That's peculiar. In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location). When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol. Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output. When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output. Therefore, your
+patch is correct. In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file. This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line. Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c. The function
+specifically adds the addend field into the object file, knowing that
+bfd_perform_relocation is not going to. If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice. It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code. With BFD it's hard to be sure of anything. The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets. It should be straightforward if time and disk
+space consuming. For each target:
+ 1) build the linker
+ 2) generate some executable, and link it using -r (I would
+ probably use paranoia.o and link against newlib/libc.a, which
+ for all the supported targets would be available in
+ /usr/cygnus/progressive/H-host/target/lib/libc.a).
+ 3) make the change to reloc.c
+ 4) rebuild the linker
+ 5) repeat step 2
+ 6) if the resulting object files are the same, you have at least
+ made it no worse
+ 7) if they are different you have to figure out which version is
+ right
+*/
+ relocation -= reloc_entry->addend;
+#endif
+ reloc_entry->addend = 0;
+ }
+ else
+ {
+ reloc_entry->addend = relocation;
+ }
+ }
+ }
+ else
+ {
+ reloc_entry->addend = 0;
+ }
+
+ /* FIXME: This overflow checking is incomplete, because the value
+ might have overflowed before we get here. For a correct check we
+ need to compute the value in a size larger than bitsize, but we
+ can't reasonably do that for a reloc the same size as a host
+ machine word.
+ FIXME: We should also do overflow checking on the result after
+ adding in the value contained in the object file. */
+ if (howto->complain_on_overflow != complain_overflow_dont
+ && flag == bfd_reloc_ok)
+ flag = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ bfd_arch_bits_per_address (abfd),
+ relocation);
+
+ /*
+ Either we are relocating all the way, or we don't want to apply
+ the relocation to the reloc entry (probably because there isn't
+ any room in the output format to describe addends to relocs)
+ */
+
+ /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+ (OSF version 1.3, compiler version 3.11). It miscompiles the
+ following program:
+
+ struct str
+ {
+ unsigned int i0;
+ } s = { 0 };
+
+ int
+ main ()
+ {
+ unsigned long x;
+
+ x = 0x100000000;
+ x <<= (unsigned long) s.i0;
+ if (x == 0)
+ printf ("failed\n");
+ else
+ printf ("succeeded (%lx)\n", x);
+ }
+ */
+
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ /* Wait for the day when all have the mask in them */
+
+ /* What we do:
+ i instruction to be left alone
+ o offset within instruction
+ r relocation offset to apply
+ S src mask
+ D dst mask
+ N ~dst mask
+ A part 1
+ B part 2
+ R result
+
+ Do this:
+ i i i i i o o o o o from bfd_get<size>
+ and S S S S S to get the size offset we want
+ + r r r r r r r r r r to get the final value to place
+ and D D D D D to chop to right size
+ -----------------------
+ A A A A A
+ And this:
+ ... i i i i i o o o o o from bfd_get<size>
+ and N N N N N get instruction
+ -----------------------
+ ... B B B B B
+
+ And then:
+ B B B B B
+ or A A A A A
+ -----------------------
+ R R R R R R R R R R put into bfd_put<size>
+ */
+
+#define DOIT(x) \
+ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, (char *) data + addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, (unsigned char *) data + addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_16 (abfd, x, (unsigned char *) data + addr);
+ }
+ break;
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
+ }
+ break;
+ case -2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
+ }
+ break;
+
+ case -1:
+ {
+ long x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_16 (abfd, x, (bfd_byte *) data + addr);
+ }
+ break;
+
+ case 3:
+ /* Do nothing */
+ break;
+
+ case 4:
+#ifdef BFD64
+ {
+ bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_64 (abfd, x, (bfd_byte *) data + addr);
+ }
+#else
+ abort ();
+#endif
+ break;
+ default:
+ return bfd_reloc_other;
+ }
+
+ return flag;
+}
+
+/*
+FUNCTION
+ bfd_install_relocation
+
+SYNOPSIS
+ bfd_reloc_status_type
+ bfd_install_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ PTR data, bfd_vma data_start,
+ asection *input_section,
+ char **error_message);
+
+DESCRIPTION
+ This looks remarkably like <<bfd_perform_relocation>>, except it
+ does not expect that the section contents have been filled in.
+ I.e., it's suitable for use when creating, rather than applying
+ a relocation.
+
+ For now, this function should be considered reserved for the
+ assembler.
+
+*/
+
+
+bfd_reloc_status_type
+bfd_install_relocation (abfd, reloc_entry, data_start, data_start_offset,
+ input_section, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ PTR data_start;
+ bfd_vma data_start_offset;
+ asection *input_section;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *reloc_target_output_section;
+ asymbol *symbol;
+ bfd_byte *data;
+
+ symbol = *(reloc_entry->sym_ptr_ptr);
+ if (bfd_is_abs_section (symbol->section))
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* If there is a function supplied to handle this relocation type,
+ call it. It'll return `bfd_reloc_continue' if further processing
+ can be done. */
+ if (howto->special_function)
+ {
+ bfd_reloc_status_type cont;
+
+ /* XXX - The special_function calls haven't been fixed up to deal
+ with creating new relocations and section contents. */
+ cont = howto->special_function (abfd, reloc_entry, symbol,
+ /* XXX - Non-portable! */
+ ((bfd_byte *) data_start
+ - data_start_offset),
+ input_section, abfd, error_message);
+ if (cont != bfd_reloc_continue)
+ return cont;
+ }
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > input_section->_cooked_size)
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targetted at and the
+ initial relocation command value. */
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ reloc_target_output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (howto->partial_inplace == false)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ if (howto->pc_relative == true)
+ {
+ /* This is a PC relative relocation. We want to set RELOCATION
+ to the distance between the address of the symbol and the
+ location. RELOCATION is already the address of the symbol.
+
+ We start by subtracting the address of the section containing
+ the location.
+
+ If pcrel_offset is set, we must further subtract the position
+ of the location within the section. Some targets arrange for
+ the addend to be the negative of the position of the location
+ within the section; for example, i386-aout does this. For
+ i386-aout, pcrel_offset is false. Some other targets do not
+ include the position of the location; for example, m88kbcs,
+ or ELF. For those targets, pcrel_offset is true.
+
+ If we are producing relocateable output, then we must ensure
+ that this reloc will be correctly computed when the final
+ relocation is done. If pcrel_offset is false we want to wind
+ up with the negative of the location within the section,
+ which means we must adjust the existing addend by the change
+ in the location within the section. If pcrel_offset is true
+ we do not want to adjust the existing addend at all.
+
+ FIXME: This seems logical to me, but for the case of
+ producing relocateable output it is not what the code
+ actually does. I don't want to change it, because it seems
+ far too likely that something will break. */
+
+ relocation -=
+ input_section->output_section->vma + input_section->output_offset;
+
+ if (howto->pcrel_offset == true && howto->partial_inplace == true)
+ relocation -= reloc_entry->address;
+ }
+
+ if (howto->partial_inplace == false)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Modify the reloc
+ inplace to reflect what we now know. */
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return flag;
+ }
+ else
+ {
+ /* This is a partial relocation, but inplace, so modify the
+ reloc record a bit.
+
+ If we've relocated with a symbol with a section, change
+ into a ref to the section belonging to the symbol. */
+
+ reloc_entry->address += input_section->output_offset;
+
+ /* WTF?? */
+ if (abfd->xvec->flavour == bfd_target_coff_flavour
+ && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0
+ && strcmp (abfd->xvec->name, "xcoff-powermac") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
+ {
+#if 1
+/* For m68k-coff, the addend was being subtracted twice during
+ relocation with -r. Removing the line below this comment
+ fixes that problem; see PR 2953.
+
+However, Ian wrote the following, regarding removing the line below,
+which explains why it is still enabled: --djm
+
+If you put a patch like that into BFD you need to check all the COFF
+linkers. I am fairly certain that patch will break coff-i386 (e.g.,
+SCO); see coff_i386_reloc in coff-i386.c where I worked around the
+problem in a different way. There may very well be a reason that the
+code works as it does.
+
+Hmmm. The first obvious point is that bfd_install_relocation should
+not have any tests that depend upon the flavour. It's seem like
+entirely the wrong place for such a thing. The second obvious point
+is that the current code ignores the reloc addend when producing
+relocateable output for COFF. That's peculiar. In fact, I really
+have no idea what the point of the line you want to remove is.
+
+A typical COFF reloc subtracts the old value of the symbol and adds in
+the new value to the location in the object file (if it's a pc
+relative reloc it adds the difference between the symbol value and the
+location). When relocating we need to preserve that property.
+
+BFD handles this by setting the addend to the negative of the old
+value of the symbol. Unfortunately it handles common symbols in a
+non-standard way (it doesn't subtract the old value) but that's a
+different story (we can't change it without losing backward
+compatibility with old object files) (coff-i386 does subtract the old
+value, to be compatible with existing coff-i386 targets, like SCO).
+
+So everything works fine when not producing relocateable output. When
+we are producing relocateable output, logically we should do exactly
+what we do when not producing relocateable output. Therefore, your
+patch is correct. In fact, it should probably always just set
+reloc_entry->addend to 0 for all cases, since it is, in fact, going to
+add the value into the object file. This won't hurt the COFF code,
+which doesn't use the addend; I'm not sure what it will do to other
+formats (the thing to check for would be whether any formats both use
+the addend and set partial_inplace).
+
+When I wanted to make coff-i386 produce relocateable output, I ran
+into the problem that you are running into: I wanted to remove that
+line. Rather than risk it, I made the coff-i386 relocs use a special
+function; it's coff_i386_reloc in coff-i386.c. The function
+specifically adds the addend field into the object file, knowing that
+bfd_install_relocation is not going to. If you remove that line, then
+coff-i386.c will wind up adding the addend field in twice. It's
+trivial to fix; it just needs to be done.
+
+The problem with removing the line is just that it may break some
+working code. With BFD it's hard to be sure of anything. The right
+way to deal with this is simply to build and test at least all the
+supported COFF targets. It should be straightforward if time and disk
+space consuming. For each target:
+ 1) build the linker
+ 2) generate some executable, and link it using -r (I would
+ probably use paranoia.o and link against newlib/libc.a, which
+ for all the supported targets would be available in
+ /usr/cygnus/progressive/H-host/target/lib/libc.a).
+ 3) make the change to reloc.c
+ 4) rebuild the linker
+ 5) repeat step 2
+ 6) if the resulting object files are the same, you have at least
+ made it no worse
+ 7) if they are different you have to figure out which version is
+ right
+*/
+ relocation -= reloc_entry->addend;
+#endif
+ reloc_entry->addend = 0;
+ }
+ else
+ {
+ reloc_entry->addend = relocation;
+ }
+ }
+
+ /* FIXME: This overflow checking is incomplete, because the value
+ might have overflowed before we get here. For a correct check we
+ need to compute the value in a size larger than bitsize, but we
+ can't reasonably do that for a reloc the same size as a host
+ machine word.
+ FIXME: We should also do overflow checking on the result after
+ adding in the value contained in the object file. */
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ flag = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ bfd_arch_bits_per_address (abfd),
+ relocation);
+
+ /*
+ Either we are relocating all the way, or we don't want to apply
+ the relocation to the reloc entry (probably because there isn't
+ any room in the output format to describe addends to relocs)
+ */
+
+ /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
+ (OSF version 1.3, compiler version 3.11). It miscompiles the
+ following program:
+
+ struct str
+ {
+ unsigned int i0;
+ } s = { 0 };
+
+ int
+ main ()
+ {
+ unsigned long x;
+
+ x = 0x100000000;
+ x <<= (unsigned long) s.i0;
+ if (x == 0)
+ printf ("failed\n");
+ else
+ printf ("succeeded (%lx)\n", x);
+ }
+ */
+
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ /* Wait for the day when all have the mask in them */
+
+ /* What we do:
+ i instruction to be left alone
+ o offset within instruction
+ r relocation offset to apply
+ S src mask
+ D dst mask
+ N ~dst mask
+ A part 1
+ B part 2
+ R result
+
+ Do this:
+ i i i i i o o o o o from bfd_get<size>
+ and S S S S S to get the size offset we want
+ + r r r r r r r r r r to get the final value to place
+ and D D D D D to chop to right size
+ -----------------------
+ A A A A A
+ And this:
+ ... i i i i i o o o o o from bfd_get<size>
+ and N N N N N get instruction
+ -----------------------
+ ... B B B B B
+
+ And then:
+ B B B B B
+ or A A A A A
+ -----------------------
+ R R R R R R R R R R put into bfd_put<size>
+ */
+
+#define DOIT(x) \
+ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
+
+ data = (bfd_byte *) data_start + (addr - data_start_offset);
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, (char *) data);
+ DOIT (x);
+ bfd_put_8 (abfd, x, (unsigned char *) data);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, (bfd_byte *) data);
+ DOIT (x);
+ bfd_put_16 (abfd, x, (unsigned char *) data);
+ }
+ break;
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data);
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data);
+ }
+ break;
+ case -2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_32 (abfd, x, (bfd_byte *) data);
+ }
+ break;
+
+ case 3:
+ /* Do nothing */
+ break;
+
+ case 4:
+ {
+ bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data);
+ DOIT (x);
+ bfd_put_64 (abfd, x, (bfd_byte *) data);
+ }
+ break;
+ default:
+ return bfd_reloc_other;
+ }
+
+ return flag;
+}
+
+/* This relocation routine is used by some of the backend linkers.
+ They do not construct asymbol or arelent structures, so there is no
+ reason for them to use bfd_perform_relocation. Also,
+ bfd_perform_relocation is so hacked up it is easier to write a new
+ function than to try to deal with it.
+
+ This routine does a final relocation. Whether it is useful for a
+ relocateable link depends upon how the object format defines
+ relocations.
+
+ FIXME: This routine ignores any special_function in the HOWTO,
+ since the existing special_function values have been written for
+ bfd_perform_relocation.
+
+ HOWTO is the reloc howto information.
+ INPUT_BFD is the BFD which the reloc applies to.
+ INPUT_SECTION is the section which the reloc applies to.
+ CONTENTS is the contents of the section.
+ ADDRESS is the address of the reloc within INPUT_SECTION.
+ VALUE is the value of the symbol the reloc refers to.
+ ADDEND is the addend of the reloc. */
+
+bfd_reloc_status_type
+_bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
+ value, addend)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ bfd_vma address;
+ bfd_vma value;
+ bfd_vma addend;
+{
+ bfd_vma relocation;
+
+ /* Sanity check the address. */
+ if (address > input_section->_raw_size)
+ return bfd_reloc_outofrange;
+
+ /* This function assumes that we are dealing with a basic relocation
+ against a symbol. We want to compute the value of the symbol to
+ relocate to. This is just VALUE, the value of the symbol, plus
+ ADDEND, any addend associated with the reloc. */
+ relocation = value + addend;
+
+ /* If the relocation is PC relative, we want to set RELOCATION to
+ the distance between the symbol (currently in RELOCATION) and the
+ location we are relocating. Some targets (e.g., i386-aout)
+ arrange for the contents of the section to be the negative of the
+ offset of the location within the section; for such targets
+ pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
+ simply leave the contents of the section as zero; for such
+ targets pcrel_offset is true. If pcrel_offset is false we do not
+ need to subtract out the offset of the location within the
+ section (which is just ADDRESS). */
+ if (howto->pc_relative)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ if (howto->pcrel_offset)
+ relocation -= address;
+ }
+
+ return _bfd_relocate_contents (howto, input_bfd, relocation,
+ contents + address);
+}
+
+/* Relocate a given location using a given value and howto. */
+
+bfd_reloc_status_type
+_bfd_relocate_contents (howto, input_bfd, relocation, location)
+ reloc_howto_type *howto;
+ bfd *input_bfd;
+ bfd_vma relocation;
+ bfd_byte *location;
+{
+ int size;
+ bfd_vma x;
+ boolean overflow;
+ unsigned int rightshift = howto->rightshift;
+ unsigned int bitpos = howto->bitpos;
+
+ /* If the size is negative, negate RELOCATION. This isn't very
+ general. */
+ if (howto->size < 0)
+ relocation = -relocation;
+
+ /* Get the value we are going to relocate. */
+ size = bfd_get_reloc_size (howto);
+ switch (size)
+ {
+ default:
+ case 0:
+ abort ();
+ case 1:
+ x = bfd_get_8 (input_bfd, location);
+ break;
+ case 2:
+ x = bfd_get_16 (input_bfd, location);
+ break;
+ case 4:
+ x = bfd_get_32 (input_bfd, location);
+ break;
+ case 8:
+#ifdef BFD64
+ x = bfd_get_64 (input_bfd, location);
+#else
+ abort ();
+#endif
+ break;
+ }
+
+ /* Check for overflow. FIXME: We may drop bits during the addition
+ which we don't check for. We must either check at every single
+ operation, which would be tedious, or we must do the computations
+ in a type larger than bfd_vma, which would be inefficient. */
+ overflow = false;
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_vma addrmask, fieldmask, signmask, ss;
+ bfd_vma a, b, sum;
+
+ /* Get the values to be added together. For signed and unsigned
+ relocations, we assume that all values should be truncated to
+ the size of an address. For bitfields, all the bits matter.
+ See also bfd_check_overflow. */
+ fieldmask = N_ONES (howto->bitsize);
+ addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
+ a = relocation;
+ b = x & howto->src_mask;
+
+ switch (howto->complain_on_overflow)
+ {
+ case complain_overflow_signed:
+ a = (a & addrmask) >> rightshift;
+
+ /* If any sign bits are set, all sign bits must be set.
+ That is, A must be a valid negative address after
+ shifting. */
+ signmask = ~ (fieldmask >> 1);
+ ss = a & signmask;
+ if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
+ overflow = true;
+
+ /* We only need this next bit of code if the sign bit of B
+ is below the sign bit of A. This would only happen if
+ SRC_MASK had fewer bits than BITSIZE. Note that if
+ SRC_MASK has more bits than BITSIZE, we can get into
+ trouble; we would need to verify that B is in range, as
+ we do for A above. */
+ signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
+ if ((b & signmask) != 0)
+ {
+ /* Set all the bits above the sign bit. */
+ b -= signmask <<= 1;
+ }
+
+ b = (b & addrmask) >> bitpos;
+
+ /* Now we can do the addition. */
+ sum = a + b;
+
+ /* See if the result has the correct sign. Bits above the
+ sign bit are junk now; ignore them. If the sum is
+ positive, make sure we did not have all negative inputs;
+ if the sum is negative, make sure we did not have all
+ positive inputs. The test below looks only at the sign
+ bits, and it really just
+ SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
+ */
+ signmask = (fieldmask >> 1) + 1;
+ if (((~ (a ^ b)) & (a ^ sum)) & signmask)
+ overflow = true;
+
+ break;
+
+ case complain_overflow_unsigned:
+ /* Checking for an unsigned overflow is relatively easy:
+ trim the addresses and add, and trim the result as well.
+ Overflow is normally indicated when the result does not
+ fit in the field. However, we also need to consider the
+ case when, e.g., fieldmask is 0x7fffffff or smaller, an
+ input is 0x80000000, and bfd_vma is only 32 bits; then we
+ will get sum == 0, but there is an overflow, since the
+ inputs did not fit in the field. Instead of doing a
+ separate test, we can check for this by or-ing in the
+ operands when testing for the sum overflowing its final
+ field. */
+ a = (a & addrmask) >> rightshift;
+ b = (b & addrmask) >> bitpos;
+ sum = (a + b) & addrmask;
+ if ((a | b | sum) & ~ fieldmask)
+ overflow = true;
+
+ break;
+
+ case complain_overflow_bitfield:
+ /* Much like unsigned, except no trimming with addrmask. In
+ addition, the sum overflows if there is a carry out of
+ the bfd_vma, i.e., the sum is less than either input
+ operand. */
+ a >>= rightshift;
+ b >>= bitpos;
+
+ /* Bitfields are sometimes used for signed numbers; for
+ example, a 13-bit field sometimes represents values in
+ 0..8191 and sometimes represents values in -4096..4095.
+ If the field is signed and a is -4095 (0x1001) and b is
+ -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
+ 0x1fff is 0x3000). It's not clear how to handle this
+ everywhere, since there is not way to know how many bits
+ are significant in the relocation, but the original code
+ assumed that it was fully sign extended, and we will keep
+ that assumption. */
+ signmask = (fieldmask >> 1) + 1;
+
+ if ((a & ~ fieldmask) != 0)
+ {
+ /* Some bits out of the field are set. This might not
+ be a problem: if this is a signed bitfield, it is OK
+ iff all the high bits are set, including the sign
+ bit. We'll try setting all but the most significant
+ bit in the original relocation value: if this is all
+ ones, we are OK, assuming a signed bitfield. */
+ ss = (signmask << rightshift) - 1;
+ if ((ss | relocation) != ~ (bfd_vma) 0)
+ overflow = true;
+ a &= fieldmask;
+ }
+
+ /* We just assume (b & ~ fieldmask) == 0. */
+
+ sum = a + b;
+ if (sum < a || (sum & ~ fieldmask) != 0)
+ {
+ /* There was a carry out, or the field overflow. Test
+ for signed operands again. Here is the overflow test
+ is as for complain_overflow_signed. */
+ if (((~ (a ^ b)) & (a ^ sum)) & signmask)
+ overflow = true;
+ }
+
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Put RELOCATION in the right bits. */
+ relocation >>= (bfd_vma) rightshift;
+ relocation <<= (bfd_vma) bitpos;
+
+ /* Add RELOCATION to the right bits of X. */
+ x = ((x & ~howto->dst_mask)
+ | (((x & howto->src_mask) + relocation) & howto->dst_mask));
+
+ /* Put the relocated value back in the object file. */
+ switch (size)
+ {
+ default:
+ case 0:
+ abort ();
+ case 1:
+ bfd_put_8 (input_bfd, x, location);
+ break;
+ case 2:
+ bfd_put_16 (input_bfd, x, location);
+ break;
+ case 4:
+ bfd_put_32 (input_bfd, x, location);
+ break;
+ case 8:
+#ifdef BFD64
+ bfd_put_64 (input_bfd, x, location);
+#else
+ abort ();
+#endif
+ break;
+ }
+
+ return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+}
+
+/*
+DOCDD
+INODE
+ howto manager, , typedef arelent, Relocations
+
+SECTION
+ The howto manager
+
+ When an application wants to create a relocation, but doesn't
+ know what the target machine might call it, it can find out by
+ using this bit of code.
+
+*/
+
+/*
+TYPEDEF
+ bfd_reloc_code_type
+
+DESCRIPTION
+ The insides of a reloc code. The idea is that, eventually, there
+ will be one enumerator for every type of relocation we ever do.
+ Pass one of these values to <<bfd_reloc_type_lookup>>, and it'll
+ return a howto pointer.
+
+ This does mean that the application must determine the correct
+ enumerator value; you can't get a howto pointer from a random set
+ of attributes.
+
+SENUM
+ bfd_reloc_code_real
+
+ENUM
+ BFD_RELOC_64
+ENUMX
+ BFD_RELOC_32
+ENUMX
+ BFD_RELOC_26
+ENUMX
+ BFD_RELOC_24
+ENUMX
+ BFD_RELOC_16
+ENUMX
+ BFD_RELOC_14
+ENUMX
+ BFD_RELOC_8
+ENUMDOC
+ Basic absolute relocations of N bits.
+
+ENUM
+ BFD_RELOC_64_PCREL
+ENUMX
+ BFD_RELOC_32_PCREL
+ENUMX
+ BFD_RELOC_24_PCREL
+ENUMX
+ BFD_RELOC_16_PCREL
+ENUMX
+ BFD_RELOC_12_PCREL
+ENUMX
+ BFD_RELOC_8_PCREL
+ENUMDOC
+ PC-relative relocations. Sometimes these are relative to the address
+of the relocation itself; sometimes they are relative to the start of
+the section containing the relocation. It depends on the specific target.
+
+The 24-bit relocation is used in some Intel 960 configurations.
+
+ENUM
+ BFD_RELOC_32_GOT_PCREL
+ENUMX
+ BFD_RELOC_16_GOT_PCREL
+ENUMX
+ BFD_RELOC_8_GOT_PCREL
+ENUMX
+ BFD_RELOC_32_GOTOFF
+ENUMX
+ BFD_RELOC_16_GOTOFF
+ENUMX
+ BFD_RELOC_LO16_GOTOFF
+ENUMX
+ BFD_RELOC_HI16_GOTOFF
+ENUMX
+ BFD_RELOC_HI16_S_GOTOFF
+ENUMX
+ BFD_RELOC_8_GOTOFF
+ENUMX
+ BFD_RELOC_32_PLT_PCREL
+ENUMX
+ BFD_RELOC_24_PLT_PCREL
+ENUMX
+ BFD_RELOC_16_PLT_PCREL
+ENUMX
+ BFD_RELOC_8_PLT_PCREL
+ENUMX
+ BFD_RELOC_32_PLTOFF
+ENUMX
+ BFD_RELOC_16_PLTOFF
+ENUMX
+ BFD_RELOC_LO16_PLTOFF
+ENUMX
+ BFD_RELOC_HI16_PLTOFF
+ENUMX
+ BFD_RELOC_HI16_S_PLTOFF
+ENUMX
+ BFD_RELOC_8_PLTOFF
+ENUMDOC
+ For ELF.
+
+ENUM
+ BFD_RELOC_68K_GLOB_DAT
+ENUMX
+ BFD_RELOC_68K_JMP_SLOT
+ENUMX
+ BFD_RELOC_68K_RELATIVE
+ENUMDOC
+ Relocations used by 68K ELF.
+
+ENUM
+ BFD_RELOC_32_BASEREL
+ENUMX
+ BFD_RELOC_16_BASEREL
+ENUMX
+ BFD_RELOC_LO16_BASEREL
+ENUMX
+ BFD_RELOC_HI16_BASEREL
+ENUMX
+ BFD_RELOC_HI16_S_BASEREL
+ENUMX
+ BFD_RELOC_8_BASEREL
+ENUMX
+ BFD_RELOC_RVA
+ENUMDOC
+ Linkage-table relative.
+
+ENUM
+ BFD_RELOC_8_FFnn
+ENUMDOC
+ Absolute 8-bit relocation, but used to form an address like 0xFFnn.
+
+ENUM
+ BFD_RELOC_32_PCREL_S2
+ENUMX
+ BFD_RELOC_16_PCREL_S2
+ENUMX
+ BFD_RELOC_23_PCREL_S2
+ENUMDOC
+ These PC-relative relocations are stored as word displacements --
+i.e., byte displacements shifted right two bits. The 30-bit word
+displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the
+SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The
+signed 16-bit displacement is used on the MIPS, and the 23-bit
+displacement is used on the Alpha.
+
+ENUM
+ BFD_RELOC_HI22
+ENUMX
+ BFD_RELOC_LO10
+ENUMDOC
+ High 22 bits and low 10 bits of 32-bit value, placed into lower bits of
+the target word. These are used on the SPARC.
+
+ENUM
+ BFD_RELOC_GPREL16
+ENUMX
+ BFD_RELOC_GPREL32
+ENUMDOC
+ For systems that allocate a Global Pointer register, these are
+displacements off that register. These relocation types are
+handled specially, because the value the register will have is
+decided relatively late.
+
+
+ENUM
+ BFD_RELOC_I960_CALLJ
+ENUMDOC
+ Reloc types used for i960/b.out.
+
+ENUM
+ BFD_RELOC_NONE
+ENUMX
+ BFD_RELOC_SPARC_WDISP22
+ENUMX
+ BFD_RELOC_SPARC22
+ENUMX
+ BFD_RELOC_SPARC13
+ENUMX
+ BFD_RELOC_SPARC_GOT10
+ENUMX
+ BFD_RELOC_SPARC_GOT13
+ENUMX
+ BFD_RELOC_SPARC_GOT22
+ENUMX
+ BFD_RELOC_SPARC_PC10
+ENUMX
+ BFD_RELOC_SPARC_PC22
+ENUMX
+ BFD_RELOC_SPARC_WPLT30
+ENUMX
+ BFD_RELOC_SPARC_COPY
+ENUMX
+ BFD_RELOC_SPARC_GLOB_DAT
+ENUMX
+ BFD_RELOC_SPARC_JMP_SLOT
+ENUMX
+ BFD_RELOC_SPARC_RELATIVE
+ENUMX
+ BFD_RELOC_SPARC_UA32
+ENUMDOC
+ SPARC ELF relocations. There is probably some overlap with other
+ relocation types already defined.
+
+ENUM
+ BFD_RELOC_SPARC_BASE13
+ENUMX
+ BFD_RELOC_SPARC_BASE22
+ENUMDOC
+ I think these are specific to SPARC a.out (e.g., Sun 4).
+
+ENUMEQ
+ BFD_RELOC_SPARC_64
+ BFD_RELOC_64
+ENUMX
+ BFD_RELOC_SPARC_10
+ENUMX
+ BFD_RELOC_SPARC_11
+ENUMX
+ BFD_RELOC_SPARC_OLO10
+ENUMX
+ BFD_RELOC_SPARC_HH22
+ENUMX
+ BFD_RELOC_SPARC_HM10
+ENUMX
+ BFD_RELOC_SPARC_LM22
+ENUMX
+ BFD_RELOC_SPARC_PC_HH22
+ENUMX
+ BFD_RELOC_SPARC_PC_HM10
+ENUMX
+ BFD_RELOC_SPARC_PC_LM22
+ENUMX
+ BFD_RELOC_SPARC_WDISP16
+ENUMX
+ BFD_RELOC_SPARC_WDISP19
+ENUMX
+ BFD_RELOC_SPARC_7
+ENUMX
+ BFD_RELOC_SPARC_6
+ENUMX
+ BFD_RELOC_SPARC_5
+ENUMEQX
+ BFD_RELOC_SPARC_DISP64
+ BFD_RELOC_64_PCREL
+ENUMX
+ BFD_RELOC_SPARC_PLT64
+ENUMX
+ BFD_RELOC_SPARC_HIX22
+ENUMX
+ BFD_RELOC_SPARC_LOX10
+ENUMX
+ BFD_RELOC_SPARC_H44
+ENUMX
+ BFD_RELOC_SPARC_M44
+ENUMX
+ BFD_RELOC_SPARC_L44
+ENUMX
+ BFD_RELOC_SPARC_REGISTER
+ENUMDOC
+ SPARC64 relocations
+
+ENUM
+ BFD_RELOC_SPARC_REV32
+ENUMDOC
+ SPARC little endian relocation
+
+ENUM
+ BFD_RELOC_ALPHA_GPDISP_HI16
+ENUMDOC
+ Alpha ECOFF and ELF relocations. Some of these treat the symbol or
+ "addend" in some special way.
+ For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+ writing; when reading, it will be the absolute section symbol. The
+ addend is the displacement in bytes of the "lda" instruction from
+ the "ldah" instruction (which is at the address of this reloc).
+ENUM
+ BFD_RELOC_ALPHA_GPDISP_LO16
+ENUMDOC
+ For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+ with GPDISP_HI16 relocs. The addend is ignored when writing the
+ relocations out, and is filled in with the file's GP value on
+ reading, for convenience.
+
+ENUM
+ BFD_RELOC_ALPHA_GPDISP
+ENUMDOC
+ The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+ relocation except that there is no accompanying GPDISP_LO16
+ relocation.
+
+ENUM
+ BFD_RELOC_ALPHA_LITERAL
+ENUMX
+ BFD_RELOC_ALPHA_ELF_LITERAL
+ENUMX
+ BFD_RELOC_ALPHA_LITUSE
+ENUMDOC
+ The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+ the assembler turns it into a LDQ instruction to load the address of
+ the symbol, and then fills in a register in the real instruction.
+
+ The LITERAL reloc, at the LDQ instruction, refers to the .lita
+ section symbol. The addend is ignored when writing, but is filled
+ in with the file's GP value on reading, for convenience, as with the
+ GPDISP_LO16 reloc.
+
+ The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16.
+ It should refer to the symbol to be referenced, as with 16_GOTOFF,
+ but it generates output not based on the position within the .got
+ section, but relative to the GP value chosen for the file during the
+ final link stage.
+
+ The LITUSE reloc, on the instruction using the loaded address, gives
+ information to the linker that it might be able to use to optimize
+ away some literal section references. The symbol is ignored (read
+ as the absolute section symbol), and the "addend" indicates the type
+ of instruction using the register:
+ 1 - "memory" fmt insn
+ 2 - byte-manipulation (byte offset reg)
+ 3 - jsr (target of branch)
+
+ The GNU linker currently doesn't do any of this optimizing.
+
+ENUM
+ BFD_RELOC_ALPHA_HINT
+ENUMDOC
+ The HINT relocation indicates a value that should be filled into the
+ "hint" field of a jmp/jsr/ret instruction, for possible branch-
+ prediction logic which may be provided on some processors.
+
+ENUM
+ BFD_RELOC_ALPHA_LINKAGE
+ENUMDOC
+ The LINKAGE relocation outputs a linkage pair in the object file,
+ which is filled by the linker.
+
+ENUM
+ BFD_RELOC_ALPHA_CODEADDR
+ENUMDOC
+ The CODEADDR relocation outputs a STO_CA in the object file,
+ which is filled by the linker.
+
+ENUM
+ BFD_RELOC_MIPS_JMP
+ENUMDOC
+ Bits 27..2 of the relocation address shifted right 2 bits;
+ simple reloc otherwise.
+
+ENUM
+ BFD_RELOC_MIPS16_JMP
+ENUMDOC
+ The MIPS16 jump instruction.
+
+ENUM
+ BFD_RELOC_MIPS16_GPREL
+ENUMDOC
+ MIPS16 GP relative reloc.
+
+ENUM
+ BFD_RELOC_HI16
+ENUMDOC
+ High 16 bits of 32-bit value; simple reloc.
+ENUM
+ BFD_RELOC_HI16_S
+ENUMDOC
+ High 16 bits of 32-bit value but the low 16 bits will be sign
+ extended and added to form the final result. If the low 16
+ bits form a negative number, we need to add one to the high value
+ to compensate for the borrow when the low bits are added.
+ENUM
+ BFD_RELOC_LO16
+ENUMDOC
+ Low 16 bits.
+ENUM
+ BFD_RELOC_PCREL_HI16_S
+ENUMDOC
+ Like BFD_RELOC_HI16_S, but PC relative.
+ENUM
+ BFD_RELOC_PCREL_LO16
+ENUMDOC
+ Like BFD_RELOC_LO16, but PC relative.
+
+ENUMEQ
+ BFD_RELOC_MIPS_GPREL
+ BFD_RELOC_GPREL16
+ENUMDOC
+ Relocation relative to the global pointer.
+
+ENUM
+ BFD_RELOC_MIPS_LITERAL
+ENUMDOC
+ Relocation against a MIPS literal section.
+
+ENUM
+ BFD_RELOC_MIPS_GOT16
+ENUMX
+ BFD_RELOC_MIPS_CALL16
+ENUMEQX
+ BFD_RELOC_MIPS_GPREL32
+ BFD_RELOC_GPREL32
+ENUMX
+ BFD_RELOC_MIPS_GOT_HI16
+ENUMX
+ BFD_RELOC_MIPS_GOT_LO16
+ENUMX
+ BFD_RELOC_MIPS_CALL_HI16
+ENUMX
+ BFD_RELOC_MIPS_CALL_LO16
+COMMENT
+ENUMDOC
+ MIPS ELF relocations.
+
+COMMENT
+
+ENUM
+ BFD_RELOC_386_GOT32
+ENUMX
+ BFD_RELOC_386_PLT32
+ENUMX
+ BFD_RELOC_386_COPY
+ENUMX
+ BFD_RELOC_386_GLOB_DAT
+ENUMX
+ BFD_RELOC_386_JUMP_SLOT
+ENUMX
+ BFD_RELOC_386_RELATIVE
+ENUMX
+ BFD_RELOC_386_GOTOFF
+ENUMX
+ BFD_RELOC_386_GOTPC
+ENUMDOC
+ i386/elf relocations
+
+ENUM
+ BFD_RELOC_NS32K_IMM_8
+ENUMX
+ BFD_RELOC_NS32K_IMM_16
+ENUMX
+ BFD_RELOC_NS32K_IMM_32
+ENUMX
+ BFD_RELOC_NS32K_IMM_8_PCREL
+ENUMX
+ BFD_RELOC_NS32K_IMM_16_PCREL
+ENUMX
+ BFD_RELOC_NS32K_IMM_32_PCREL
+ENUMX
+ BFD_RELOC_NS32K_DISP_8
+ENUMX
+ BFD_RELOC_NS32K_DISP_16
+ENUMX
+ BFD_RELOC_NS32K_DISP_32
+ENUMX
+ BFD_RELOC_NS32K_DISP_8_PCREL
+ENUMX
+ BFD_RELOC_NS32K_DISP_16_PCREL
+ENUMX
+ BFD_RELOC_NS32K_DISP_32_PCREL
+ENUMDOC
+ ns32k relocations
+
+ENUM
+ BFD_RELOC_PPC_B26
+ENUMX
+ BFD_RELOC_PPC_BA26
+ENUMX
+ BFD_RELOC_PPC_TOC16
+ENUMX
+ BFD_RELOC_PPC_B16
+ENUMX
+ BFD_RELOC_PPC_B16_BRTAKEN
+ENUMX
+ BFD_RELOC_PPC_B16_BRNTAKEN
+ENUMX
+ BFD_RELOC_PPC_BA16
+ENUMX
+ BFD_RELOC_PPC_BA16_BRTAKEN
+ENUMX
+ BFD_RELOC_PPC_BA16_BRNTAKEN
+ENUMX
+ BFD_RELOC_PPC_COPY
+ENUMX
+ BFD_RELOC_PPC_GLOB_DAT
+ENUMX
+ BFD_RELOC_PPC_JMP_SLOT
+ENUMX
+ BFD_RELOC_PPC_RELATIVE
+ENUMX
+ BFD_RELOC_PPC_LOCAL24PC
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR32
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16_LO
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16_HI
+ENUMX
+ BFD_RELOC_PPC_EMB_NADDR16_HA
+ENUMX
+ BFD_RELOC_PPC_EMB_SDAI16
+ENUMX
+ BFD_RELOC_PPC_EMB_SDA2I16
+ENUMX
+ BFD_RELOC_PPC_EMB_SDA2REL
+ENUMX
+ BFD_RELOC_PPC_EMB_SDA21
+ENUMX
+ BFD_RELOC_PPC_EMB_MRKREF
+ENUMX
+ BFD_RELOC_PPC_EMB_RELSEC16
+ENUMX
+ BFD_RELOC_PPC_EMB_RELST_LO
+ENUMX
+ BFD_RELOC_PPC_EMB_RELST_HI
+ENUMX
+ BFD_RELOC_PPC_EMB_RELST_HA
+ENUMX
+ BFD_RELOC_PPC_EMB_BIT_FLD
+ENUMX
+ BFD_RELOC_PPC_EMB_RELSDA
+ENUMDOC
+ Power(rs6000) and PowerPC relocations.
+
+ENUM
+ BFD_RELOC_CTOR
+ENUMDOC
+ The type of reloc used to build a contructor table - at the moment
+ probably a 32 bit wide absolute relocation, but the target can choose.
+ It generally does map to one of the other relocation types.
+
+ENUM
+ BFD_RELOC_ARM_PCREL_BRANCH
+ENUMDOC
+ ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
+ not stored in the instruction.
+ENUM
+ BFD_RELOC_ARM_IMMEDIATE
+ENUMX
+ BFD_RELOC_ARM_OFFSET_IMM
+ENUMX
+ BFD_RELOC_ARM_SHIFT_IMM
+ENUMX
+ BFD_RELOC_ARM_SWI
+ENUMX
+ BFD_RELOC_ARM_MULTI
+ENUMX
+ BFD_RELOC_ARM_CP_OFF_IMM
+ENUMX
+ BFD_RELOC_ARM_ADR_IMM
+ENUMX
+ BFD_RELOC_ARM_LDR_IMM
+ENUMX
+ BFD_RELOC_ARM_LITERAL
+ENUMX
+ BFD_RELOC_ARM_IN_POOL
+ENUMX
+ BFD_RELOC_ARM_OFFSET_IMM8
+ENUMX
+ BFD_RELOC_ARM_HWLITERAL
+ENUMX
+ BFD_RELOC_ARM_THUMB_ADD
+ENUMX
+ BFD_RELOC_ARM_THUMB_IMM
+ENUMX
+ BFD_RELOC_ARM_THUMB_SHIFT
+ENUMX
+ BFD_RELOC_ARM_THUMB_OFFSET
+ENUMX
+ BFD_RELOC_ARM_GOT12
+ENUMX
+ BFD_RELOC_ARM_GOT32
+ENUMX
+ BFD_RELOC_ARM_JUMP_SLOT
+ENUMX
+ BFD_RELOC_ARM_COPY
+ENUMX
+ BFD_RELOC_ARM_GLOB_DAT
+ENUMX
+ BFD_RELOC_ARM_PLT32
+ENUMX
+ BFD_RELOC_ARM_RELATIVE
+ENUMX
+ BFD_RELOC_ARM_GOTOFF
+ENUMX
+ BFD_RELOC_ARM_GOTPC
+ENUMDOC
+ These relocs are only used within the ARM assembler. They are not
+ (at present) written to any object files.
+
+ENUM
+ BFD_RELOC_SH_PCDISP8BY2
+ENUMX
+ BFD_RELOC_SH_PCDISP12BY2
+ENUMX
+ BFD_RELOC_SH_IMM4
+ENUMX
+ BFD_RELOC_SH_IMM4BY2
+ENUMX
+ BFD_RELOC_SH_IMM4BY4
+ENUMX
+ BFD_RELOC_SH_IMM8
+ENUMX
+ BFD_RELOC_SH_IMM8BY2
+ENUMX
+ BFD_RELOC_SH_IMM8BY4
+ENUMX
+ BFD_RELOC_SH_PCRELIMM8BY2
+ENUMX
+ BFD_RELOC_SH_PCRELIMM8BY4
+ENUMX
+ BFD_RELOC_SH_SWITCH16
+ENUMX
+ BFD_RELOC_SH_SWITCH32
+ENUMX
+ BFD_RELOC_SH_USES
+ENUMX
+ BFD_RELOC_SH_COUNT
+ENUMX
+ BFD_RELOC_SH_ALIGN
+ENUMX
+ BFD_RELOC_SH_CODE
+ENUMX
+ BFD_RELOC_SH_DATA
+ENUMX
+ BFD_RELOC_SH_LABEL
+ENUMDOC
+ Hitachi SH relocs. Not all of these appear in object files.
+
+ENUM
+ BFD_RELOC_THUMB_PCREL_BRANCH9
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH12
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH23
+ENUMDOC
+ Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must
+ be zero and is not stored in the instruction.
+
+ENUM
+ BFD_RELOC_ARC_B22_PCREL
+ENUMDOC
+ Argonaut RISC Core (ARC) relocs.
+ ARC 22 bit pc-relative branch. The lowest two bits must be zero and are
+ not stored in the instruction. The high 20 bits are installed in bits 26
+ through 7 of the instruction.
+ENUM
+ BFD_RELOC_ARC_B26
+ENUMDOC
+ ARC 26 bit absolute branch. The lowest two bits must be zero and are not
+ stored in the instruction. The high 24 bits are installed in bits 23
+ through 0.
+
+ENUM
+ BFD_RELOC_D10V_10_PCREL_R
+ENUMDOC
+ Mitsubishi D10V relocs.
+ This is a 10-bit reloc with the right 2 bits
+ assumed to be 0.
+ENUM
+ BFD_RELOC_D10V_10_PCREL_L
+ENUMDOC
+ Mitsubishi D10V relocs.
+ This is a 10-bit reloc with the right 2 bits
+ assumed to be 0. This is the same as the previous reloc
+ except it is in the left container, i.e.,
+ shifted left 15 bits.
+ENUM
+ BFD_RELOC_D10V_18
+ENUMDOC
+ This is an 18-bit reloc with the right 2 bits
+ assumed to be 0.
+ENUM
+ BFD_RELOC_D10V_18_PCREL
+ENUMDOC
+ This is an 18-bit reloc with the right 2 bits
+ assumed to be 0.
+
+ENUM
+ BFD_RELOC_D30V_6
+ENUMDOC
+ Mitsubishi D30V relocs.
+ This is a 6-bit absolute reloc.
+ENUM
+ BFD_RELOC_D30V_9_PCREL
+ENUMDOC
+ This is a 6-bit pc-relative reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_9_PCREL_R
+ENUMDOC
+ This is a 6-bit pc-relative reloc with
+ the right 3 bits assumed to be 0. Same
+ as the previous reloc but on the right side
+ of the container.
+ENUM
+ BFD_RELOC_D30V_15
+ENUMDOC
+ This is a 12-bit absolute reloc with the
+ right 3 bitsassumed to be 0.
+ENUM
+ BFD_RELOC_D30V_15_PCREL
+ENUMDOC
+ This is a 12-bit pc-relative reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_15_PCREL_R
+ENUMDOC
+ This is a 12-bit pc-relative reloc with
+ the right 3 bits assumed to be 0. Same
+ as the previous reloc but on the right side
+ of the container.
+ENUM
+ BFD_RELOC_D30V_21
+ENUMDOC
+ This is an 18-bit absolute reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_21_PCREL
+ENUMDOC
+ This is an 18-bit pc-relative reloc with
+ the right 3 bits assumed to be 0.
+ENUM
+ BFD_RELOC_D30V_21_PCREL_R
+ENUMDOC
+ This is an 18-bit pc-relative reloc with
+ the right 3 bits assumed to be 0. Same
+ as the previous reloc but on the right side
+ of the container.
+ENUM
+ BFD_RELOC_D30V_32
+ENUMDOC
+ This is a 32-bit absolute reloc.
+ENUM
+ BFD_RELOC_D30V_32_PCREL
+ENUMDOC
+ This is a 32-bit pc-relative reloc.
+
+ENUM
+ BFD_RELOC_M32R_24
+ENUMDOC
+ Mitsubishi M32R relocs.
+ This is a 24 bit absolute address.
+ENUM
+ BFD_RELOC_M32R_10_PCREL
+ENUMDOC
+ This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0.
+ENUM
+ BFD_RELOC_M32R_18_PCREL
+ENUMDOC
+ This is an 18-bit reloc with the right 2 bits assumed to be 0.
+ENUM
+ BFD_RELOC_M32R_26_PCREL
+ENUMDOC
+ This is a 26-bit reloc with the right 2 bits assumed to be 0.
+ENUM
+ BFD_RELOC_M32R_HI16_ULO
+ENUMDOC
+ This is a 16-bit reloc containing the high 16 bits of an address
+ used when the lower 16 bits are treated as unsigned.
+ENUM
+ BFD_RELOC_M32R_HI16_SLO
+ENUMDOC
+ This is a 16-bit reloc containing the high 16 bits of an address
+ used when the lower 16 bits are treated as signed.
+ENUM
+ BFD_RELOC_M32R_LO16
+ENUMDOC
+ This is a 16-bit reloc containing the lower 16 bits of an address.
+ENUM
+ BFD_RELOC_M32R_SDA16
+ENUMDOC
+ This is a 16-bit reloc containing the small data area offset for use in
+ add3, load, and store instructions.
+
+ENUM
+ BFD_RELOC_V850_9_PCREL
+ENUMDOC
+ This is a 9-bit reloc
+ENUM
+ BFD_RELOC_V850_22_PCREL
+ENUMDOC
+ This is a 22-bit reloc
+
+ENUM
+ BFD_RELOC_V850_SDA_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the short data area pointer.
+ENUM
+ BFD_RELOC_V850_SDA_15_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset (of which only 15 bits are used) from the
+ short data area pointer.
+ENUM
+ BFD_RELOC_V850_ZDA_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the zero data area pointer.
+ENUM
+ BFD_RELOC_V850_ZDA_15_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset (of which only 15 bits are used) from the
+ zero data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_6_8_OFFSET
+ENUMDOC
+ This is an 8 bit offset (of which only 6 bits are used) from the
+ tiny data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_7_8_OFFSET
+ENUMDOC
+ This is an 8bit offset (of which only 7 bits are used) from the tiny
+ data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_7_7_OFFSET
+ENUMDOC
+ This is a 7 bit offset from the tiny data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the tiny data area pointer.
+COMMENT
+ENUM
+ BFD_RELOC_V850_TDA_4_5_OFFSET
+ENUMDOC
+ This is a 5 bit offset (of which only 4 bits are used) from the tiny
+ data area pointer.
+ENUM
+ BFD_RELOC_V850_TDA_4_4_OFFSET
+ENUMDOC
+ This is a 4 bit offset from the tiny data area pointer.
+ENUM
+ BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the short data area pointer, with the
+ bits placed non-contigously in the instruction.
+ENUM
+ BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the zero data area pointer, with the
+ bits placed non-contigously in the instruction.
+ENUM
+ BFD_RELOC_V850_CALLT_6_7_OFFSET
+ENUMDOC
+ This is a 6 bit offset from the call table base pointer.
+ENUM
+ BFD_RELOC_V850_CALLT_16_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the call table base pointer.
+COMMENT
+
+ENUM
+ BFD_RELOC_MN10300_32_PCREL
+ENUMDOC
+ This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+ instruction.
+ENUM
+ BFD_RELOC_MN10300_16_PCREL
+ENUMDOC
+ This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+ instruction.
+
+ENUM
+ BFD_RELOC_TIC30_LDP
+ENUMDOC
+ This is a 8bit DP reloc for the tms320c30, where the most
+ significant 8 bits of a 24 bit word are placed into the least
+ significant 8 bits of the opcode.
+
+ENUM
+ BFD_RELOC_FR30_48
+ENUMDOC
+ This is a 48 bit reloc for the FR30 that stores 32 bits.
+ENUM
+ BFD_RELOC_FR30_20
+ENUMDOC
+ This is a 32 bit reloc for the FR30 that stores 20 bits split up into
+ two sections.
+ENUM
+ BFD_RELOC_FR30_6_IN_4
+ENUMDOC
+ This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in
+ 4 bits.
+ENUM
+ BFD_RELOC_FR30_8_IN_8
+ENUMDOC
+ This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset
+ into 8 bits.
+ENUM
+ BFD_RELOC_FR30_9_IN_8
+ENUMDOC
+ This is a 16 bit reloc for the FR30 that stores a 9 bit short offset
+ into 8 bits.
+ENUM
+ BFD_RELOC_FR30_10_IN_8
+ENUMDOC
+ This is a 16 bit reloc for the FR30 that stores a 10 bit word offset
+ into 8 bits.
+ENUM
+ BFD_RELOC_FR30_9_PCREL
+ENUMDOC
+ This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+ short offset into 8 bits.
+ENUM
+ BFD_RELOC_FR30_12_PCREL
+ENUMDOC
+ This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative
+ short offset into 11 bits.
+
+ENUM
+ BFD_RELOC_MCORE_PCREL_IMM8BY4
+ENUMX
+ BFD_RELOC_MCORE_PCREL_IMM11BY2
+ENUMX
+ BFD_RELOC_MCORE_PCREL_IMM4BY2
+ENUMX
+ BFD_RELOC_MCORE_PCREL_32
+ENUMX
+ BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2
+ENUMDOC
+ Motorola Mcore relocations.
+
+ENUM
+ BFD_RELOC_VTABLE_INHERIT
+ENUMX
+ BFD_RELOC_VTABLE_ENTRY
+ENUMDOC
+ These two relocations are used by the linker to determine which of
+ the entries in a C++ virtual function table are actually used. When
+ the --gc-sections option is given, the linker will zero out the entries
+ that are not used, so that the code for those functions need not be
+ included in the output.
+
+ VTABLE_INHERIT is a zero-space relocation used to describe to the
+ linker the inheritence tree of a C++ virtual function table. The
+ relocation's symbol should be the parent class' vtable, and the
+ relocation should be located at the child vtable.
+
+ VTABLE_ENTRY is a zero-space relocation that describes the use of a
+ virtual function table entry. The reloc's symbol should refer to the
+ table of the class mentioned in the code. Off of that base, an offset
+ describes the entry that is being used. For Rela hosts, this offset
+ is stored in the reloc's addend. For Rel hosts, we are forced to put
+ this offset in the reloc's section offset.
+
+ENDSENUM
+ BFD_RELOC_UNUSED
+CODE_FRAGMENT
+.
+.typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+*/
+
+
+/*
+FUNCTION
+ bfd_reloc_type_lookup
+
+SYNOPSIS
+ reloc_howto_type *
+ bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
+
+DESCRIPTION
+ Return a pointer to a howto structure which, when
+ invoked, will perform the relocation @var{code} on data from the
+ architecture noted.
+
+*/
+
+
+reloc_howto_type *
+bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ return BFD_SEND (abfd, reloc_type_lookup, (abfd, code));
+}
+
+static reloc_howto_type bfd_howto_32 =
+HOWTO (0, 00, 2, 32, false, 0, complain_overflow_bitfield, 0, "VRT32", false, 0xffffffff, 0xffffffff, true);
+
+
+/*
+INTERNAL_FUNCTION
+ bfd_default_reloc_type_lookup
+
+SYNOPSIS
+ reloc_howto_type *bfd_default_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+
+DESCRIPTION
+ Provides a default relocation lookup routine for any architecture.
+
+
+*/
+
+reloc_howto_type *
+bfd_default_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_CTOR:
+ /* The type of reloc used in a ctor, which will be as wide as the
+ address - so either a 64, 32, or 16 bitter. */
+ switch (bfd_get_arch_info (abfd)->bits_per_address)
+ {
+ case 64:
+ BFD_FAIL ();
+ case 32:
+ return &bfd_howto_32;
+ case 16:
+ BFD_FAIL ();
+ default:
+ BFD_FAIL ();
+ }
+ default:
+ BFD_FAIL ();
+ }
+ return (reloc_howto_type *) NULL;
+}
+
+/*
+FUNCTION
+ bfd_get_reloc_code_name
+
+SYNOPSIS
+ const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code);
+
+DESCRIPTION
+ Provides a printable name for the supplied relocation code.
+ Useful mainly for printing error messages.
+*/
+
+const char *
+bfd_get_reloc_code_name (code)
+ bfd_reloc_code_real_type code;
+{
+ if (code > BFD_RELOC_UNUSED)
+ return 0;
+ return bfd_reloc_code_real_names[(int)code];
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_relax_section
+
+SYNOPSIS
+ boolean bfd_generic_relax_section
+ (bfd *abfd,
+ asection *section,
+ struct bfd_link_info *,
+ boolean *);
+
+DESCRIPTION
+ Provides default handling for relaxing for back ends which
+ don't do relaxing -- i.e., does nothing.
+*/
+
+/*ARGSUSED*/
+boolean
+bfd_generic_relax_section (abfd, section, link_info, again)
+ bfd *abfd;
+ asection *section;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ *again = false;
+ return true;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_gc_sections
+
+SYNOPSIS
+ boolean bfd_generic_gc_sections
+ (bfd *, struct bfd_link_info *);
+
+DESCRIPTION
+ Provides default handling for relaxing for back ends which
+ don't do section gc -- i.e., does nothing.
+*/
+
+/*ARGSUSED*/
+boolean
+bfd_generic_gc_sections (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+{
+ return true;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_get_relocated_section_contents
+
+SYNOPSIS
+ bfd_byte *
+ bfd_generic_get_relocated_section_contents (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ boolean relocateable,
+ asymbol **symbols);
+
+DESCRIPTION
+ Provides default handling of relocation effort for back ends
+ which can't be bothered to do it efficiently.
+
+*/
+
+bfd_byte *
+bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data,
+ relocateable, symbols)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ /* Get enough memory to hold the stuff */
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ arelent **reloc_vector = NULL;
+ long reloc_count;
+
+ if (reloc_size < 0)
+ goto error_return;
+
+ reloc_vector = (arelent **) bfd_malloc ((size_t) reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ /* read in the section */
+ if (!bfd_get_section_contents (input_bfd,
+ input_section,
+ (PTR) data,
+ 0,
+ input_section->_raw_size))
+ goto error_return;
+
+ /* We're not relaxing the section, so just copy the size info */
+ input_section->_cooked_size = input_section->_raw_size;
+ input_section->reloc_done = true;
+
+ reloc_count = bfd_canonicalize_reloc (input_bfd,
+ input_section,
+ reloc_vector,
+ symbols);
+ if (reloc_count < 0)
+ goto error_return;
+
+ if (reloc_count > 0)
+ {
+ arelent **parent;
+ for (parent = reloc_vector; *parent != (arelent *) NULL;
+ parent++)
+ {
+ char *error_message = (char *) NULL;
+ bfd_reloc_status_type r =
+ bfd_perform_relocation (input_bfd,
+ *parent,
+ (PTR) data,
+ input_section,
+ relocateable ? abfd : (bfd *) NULL,
+ &error_message);
+
+ if (relocateable)
+ {
+ asection *os = input_section->output_section;
+
+ /* A partial link, so keep the relocs */
+ os->orelocation[os->reloc_count] = *parent;
+ os->reloc_count++;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ case bfd_reloc_undefined:
+ if (!((*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ input_bfd, input_section, (*parent)->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_dangerous:
+ BFD_ASSERT (error_message != (char *) NULL);
+ if (!((*link_info->callbacks->reloc_dangerous)
+ (link_info, error_message, input_bfd, input_section,
+ (*parent)->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_overflow:
+ if (!((*link_info->callbacks->reloc_overflow)
+ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+ (*parent)->howto->name, (*parent)->addend,
+ input_bfd, input_section, (*parent)->address)))
+ goto error_return;
+ break;
+ case bfd_reloc_outofrange:
+ default:
+ abort ();
+ break;
+ }
+
+ }
+ }
+ }
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return data;
+
+error_return:
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return NULL;
+}
diff --git a/bfd/reloc16.c b/bfd/reloc16.c
new file mode 100644
index 00000000000..7e7952ed506
--- /dev/null
+++ b/bfd/reloc16.c
@@ -0,0 +1,334 @@
+/* 8 and 16 bit COFF relocation functions, for BFD.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+Most of this hacked by Steve Chamberlain,
+ sac@cygnus.com
+*/
+
+/* These routines are used by coff-h8300 and coff-z8k to do
+ relocation.
+
+ FIXME: This code should be rewritten to support the new COFF
+ linker. Basically, they need to deal with COFF relocs rather than
+ BFD generic relocs. They should store the relocs in some location
+ where coff_link_input_bfd can find them (and coff_link_input_bfd
+ should be changed to use this location rather than rereading the
+ file) (unless info->keep_memory is false, in which case they should
+ free up the relocs after dealing with them). */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+bfd_vma
+bfd_coff_reloc16_get_value (reloc, link_info, input_section)
+ arelent *reloc;
+ struct bfd_link_info *link_info;
+ asection *input_section;
+{
+ bfd_vma value;
+ asymbol *symbol = *(reloc->sym_ptr_ptr);
+ /* A symbol holds a pointer to a section, and an offset from the
+ base of the section. To relocate, we find where the section will
+ live in the output and add that in */
+
+ if (bfd_is_und_section (symbol->section)
+ || bfd_is_com_section (symbol->section))
+ {
+ struct bfd_link_hash_entry *h;
+
+ /* The symbol is undefined in this BFD. Look it up in the
+ global linker hash table. FIXME: This should be changed when
+ we convert this stuff to use a specific final_link function
+ and change the interface to bfd_relax_section to not require
+ the generic symbols. */
+ h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info,
+ bfd_asymbol_name (symbol),
+ false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ value = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ else if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_common)
+ value = h->u.c.size;
+ else
+ {
+ if (! ((*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (symbol),
+ input_section->owner, input_section, reloc->address)))
+ abort ();
+ value = 0;
+ }
+ }
+ else
+ {
+ value = symbol->value +
+ symbol->section->output_offset +
+ symbol->section->output_section->vma;
+ }
+
+ /* Add the value contained in the relocation */
+ value += reloc->addend;
+
+ return value;
+}
+
+void
+bfd_perform_slip(abfd, slip, input_section, value)
+ bfd *abfd;
+ unsigned int slip;
+ asection *input_section;
+ bfd_vma value;
+{
+ asymbol **s;
+
+ s = _bfd_generic_link_get_symbols (abfd);
+ BFD_ASSERT (s != (asymbol **) NULL);
+
+ /* Find all symbols past this point, and make them know
+ what's happened */
+ while (*s)
+ {
+ asymbol *p = *s;
+ if (p->section == input_section)
+ {
+ /* This was pointing into this section, so mangle it */
+ if (p->value > value)
+ {
+ p->value -= slip;
+ if (p->udata.p != NULL)
+ {
+ struct generic_link_hash_entry *h;
+
+ h = (struct generic_link_hash_entry *) p->udata.p;
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak);
+ h->root.u.def.value -= slip;
+ BFD_ASSERT (h->root.u.def.value == p->value);
+ }
+ }
+ }
+ s++;
+ }
+}
+
+boolean
+bfd_coff_reloc16_relax_section (abfd, i, link_info, again)
+ bfd *abfd;
+ asection *i;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+ /* Get enough memory to hold the stuff */
+ bfd *input_bfd = i->owner;
+ asection *input_section = i;
+ int *shrinks;
+ int shrink = 0;
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ arelent **reloc_vector = NULL;
+ long reloc_count;
+
+ /* We only do global relaxation once. It is not safe to do it multiple
+ times (see discussion of the "shrinks" array below). */
+ *again = false;
+
+ if (reloc_size < 0)
+ return false;
+
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (!reloc_vector && reloc_size > 0)
+ return false;
+
+ /* Get the relocs and think about them */
+ reloc_count =
+ bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector,
+ _bfd_generic_link_get_symbols (input_bfd));
+ if (reloc_count < 0)
+ {
+ free (reloc_vector);
+ return false;
+ }
+
+ /* The reloc16.c and related relaxing code is very simple, the price
+ for that simplicity is we can only call this function once for
+ each section.
+
+ So, to get the best results within that limitation, we do multiple
+ relaxing passes over each section here. That involves keeping track
+ of the "shrink" at each reloc in the section. This allows us to
+ accurately determine the relative location of two relocs within
+ this section.
+
+ In theory, if we kept the "shrinks" array for each section for the
+ entire link, we could use the generic relaxing code in the linker
+ and get better results, particularly for jsr->bsr and 24->16 bit
+ memory reference relaxations. */
+
+ if (reloc_count > 0)
+ {
+ int another_pass = 0;
+
+ /* Allocate and initialize the shrinks array for this section. */
+ shrinks = (int *) bfd_malloc (reloc_count * sizeof (int));
+ memset (shrinks, 0, reloc_count * sizeof (int));
+
+ /* Loop until nothing changes in this section. */
+ do {
+ arelent **parent;
+ unsigned int i;
+ long j;
+
+ another_pass = 0;
+
+ for (i = 0, parent = reloc_vector; *parent; parent++, i++)
+ {
+ /* Let the target/machine dependent code examine each reloc
+ in this section and attempt to shrink it. */
+ shrink = bfd_coff_reloc16_estimate (abfd, input_section, *parent,
+ shrinks[i], link_info);
+
+ /* If it shrunk, note it in the shrinks array and set up for
+ another pass. */
+ if (shrink != shrinks[i])
+ {
+ another_pass = 1;
+ for (j = i + 1; j < reloc_count; j++)
+ shrinks[j] += shrink - shrinks[i];
+ }
+ }
+
+ } while (another_pass);
+
+ free((char *)shrinks);
+ }
+
+ input_section->_cooked_size -= shrink;
+ free((char *)reloc_vector);
+ return true;
+}
+
+bfd_byte *
+bfd_coff_reloc16_get_relocated_section_contents(in_abfd,
+ link_info,
+ link_order,
+ data,
+ relocateable,
+ symbols)
+ bfd *in_abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+ /* Get enough memory to hold the stuff */
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ arelent **reloc_vector;
+ long reloc_count;
+
+ if (reloc_size < 0)
+ return NULL;
+
+ /* If producing relocateable output, don't bother to relax. */
+ if (relocateable)
+ return bfd_generic_get_relocated_section_contents (in_abfd, link_info,
+ link_order,
+ data, relocateable,
+ symbols);
+
+ /* read in the section */
+ if (! bfd_get_section_contents(input_bfd,
+ input_section,
+ data,
+ 0,
+ input_section->_raw_size))
+ return NULL;
+
+
+ reloc_vector = (arelent **) bfd_malloc((size_t) reloc_size);
+ if (!reloc_vector && reloc_size != 0)
+ return NULL;
+
+ reloc_count = bfd_canonicalize_reloc (input_bfd,
+ input_section,
+ reloc_vector,
+ symbols);
+ if (reloc_count < 0)
+ {
+ free (reloc_vector);
+ return NULL;
+ }
+
+ if (reloc_count > 0)
+ {
+ arelent **parent = reloc_vector;
+ arelent *reloc ;
+ unsigned int dst_address = 0;
+ unsigned int src_address = 0;
+ unsigned int run;
+ unsigned int idx;
+
+ /* Find how long a run we can do */
+ while (dst_address < link_order->size)
+ {
+ reloc = *parent;
+ if (reloc)
+ {
+ /* Note that the relaxing didn't tie up the addresses in the
+ relocation, so we use the original address to work out the
+ run of non-relocated data */
+ run = reloc->address - src_address;
+ parent++;
+ }
+ else
+ {
+ run = link_order->size - dst_address;
+ }
+ /* Copy the bytes */
+ for (idx = 0; idx < run; idx++)
+ {
+ data[dst_address++] = data[src_address++];
+ }
+
+ /* Now do the relocation */
+
+ if (reloc)
+ {
+ bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order,
+ reloc, data, &src_address,
+ &dst_address);
+ }
+ }
+ }
+ free((char *)reloc_vector);
+ return data;
+}
+
diff --git a/bfd/riscix.c b/bfd/riscix.c
new file mode 100644
index 00000000000..f5ab49a692c
--- /dev/null
+++ b/bfd/riscix.c
@@ -0,0 +1,644 @@
+/* BFD back-end for RISC iX (Acorn, arm) binaries.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* RISC iX overloads the MAGIC field to indicate more than just the usual
+ [ZNO]MAGIC values. Also included are squeezing information and
+ shared library usage. */
+
+/* The following come from the man page. */
+#define SHLIBLEN 60
+
+#define MF_IMPURE 00200
+#define MF_SQUEEZED 01000
+#define MF_USES_SL 02000
+#define MF_IS_SL 04000
+
+/* Common combinations. */
+#define IMAGIC (MF_IMPURE|ZMAGIC) /* Demand load (impure text) */
+#define SPOMAGIC (MF_USES_SL|OMAGIC) /* OMAGIC with large header */
+ /* -- may contain a ref to a */
+ /* shared lib required by the */
+ /* object. */
+#define SLOMAGIC (MF_IS_SL|OMAGIC) /* A reference to a shared library */
+ /* The text portion of the object */
+ /* contains "overflow text" from */
+ /* the shared library to be linked */
+ /* in with an object */
+#define QMAGIC (MF_SQUEEZED|ZMAGIC) /* Sqeezed demand paged. */
+ /* NOTE: This interpretation of */
+ /* QMAGIC seems to be at variance */
+ /* With that used on other */
+ /* architectures. */
+#define SPZMAGIC (MF_USES_SL|ZMAGIC) /* program which uses sl */
+#define SPQMAGIC (MF_USES_SL|QMAGIC) /* sqeezed ditto */
+#define SLZMAGIC (MF_IS_SL|ZMAGIC) /* shared lib part of prog */
+#define SLPZMAGIC (MF_USES_SL|SLZMAGIC) /* sl which uses another */
+
+#define N_SHARED_LIB(x) ((x).a_info & MF_USES_SL)
+
+/* Only a pure OMAGIC file has the minimal header */
+#define N_TXTOFF(x) \
+ ((x).a_info == OMAGIC ? 32 \
+ : (N_MAGIC(x) == ZMAGIC) ? TARGET_PAGE_SIZE \
+ : 999)
+
+#define N_TXTADDR(x) \
+ (N_MAGIC(x) != ZMAGIC ? 0 /* object file or NMAGIC */ \
+ /* Programs with shared libs are loaded at the first page after all the \
+ text segments of the shared library programs. Without looking this \
+ up we can't know exactly what the address will be. A reasonable guess \
+ is that a_entry will be in the first page of the executable. */ \
+ : N_SHARED_LIB(x) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) \
+ : TEXT_START_ADDR)
+
+#define N_SYMOFF(x) \
+ (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
+
+#define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms)
+
+#define TEXT_START_ADDR 32768
+#define TARGET_PAGE_SIZE 32768
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_arm
+
+#define MY(OP) CAT(riscix_,OP)
+#define TARGETNAME "a.out-riscix"
+#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \
+ (((x).a_info & ~006000) != OMAGIC) && \
+ ((x).a_info != NMAGIC))
+#define N_MAGIC(x) ((x).a_info & ~07200)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define WRITE_HEADERS(abfd, execp) \
+ { \
+ bfd_size_type text_size; /* dummy vars */ \
+ file_ptr text_end; \
+ if (adata(abfd).magic == undecided_magic) \
+ NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
+ \
+ execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \
+ 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)); \
+ NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
+ \
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
+ if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
+ != EXEC_BYTES_SIZE) \
+ return false; \
+ /* Now write out reloc info, followed by syms and strings */ \
+ \
+ if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \
+ && bfd_get_symcount (abfd) != 0) \
+ { \
+ if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) != 0) \
+ return false; \
+ \
+ if (! NAME(aout,write_syms)(abfd)) return false; \
+ \
+ if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) != 0) \
+ return false; \
+ \
+ if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd))) \
+ return false; \
+ if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) != 0) \
+ return false; \
+ \
+ if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
+ return false; \
+ } \
+ }
+
+#include "libaout.h"
+#include "aout/aout64.h"
+
+static bfd_reloc_status_type
+riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+
+static bfd_reloc_status_type
+riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR,
+ asection *, bfd *, char **));
+
+static reloc_howto_type riscix_std_reloc_howto[] = {
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+ HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false),
+ HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false),
+ HOWTO( 3, 2, 3, 26, true, 0, complain_overflow_signed, riscix_fix_pcrel_26 , "ARM26", true, 0x00ffffff,0x00ffffff, false),
+ HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, true),
+ HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, true),
+ HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, true),
+ HOWTO( 7, 2, 3, 26, false, 0, complain_overflow_signed, riscix_fix_pcrel_26_done, "ARM26D",true,0x00ffffff,0x00ffffff, false),
+ {-1},
+ HOWTO( 9, 0, -1, 16, false, 0, complain_overflow_bitfield,0,"NEG16", true, 0x0000ffff,0x0000ffff, false),
+ HOWTO( 10, 0, -2, 32, false, 0, complain_overflow_bitfield,0,"NEG32", true, 0xffffffff,0xffffffff, false)
+};
+
+#define RISCIX_TABLE_SIZE \
+ (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type))
+
+
+static bfd_reloc_status_type
+riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ /* This is dead simple at present. */
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+riscix_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ bfd_vma relocation;
+ bfd_size_type addr = reloc_entry->address;
+ long target = bfd_get_32 (abfd, (bfd_byte *) data + addr);
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+
+ /* If this is an undefined symbol, return error */
+ if (symbol->section == &bfd_und_section
+ && (symbol->flags & BSF_WEAK) == 0)
+ return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
+
+ /* If the sections are different, and we are doing a partial relocation,
+ just ignore it for now. */
+ if (symbol->section->name != input_section->name
+ && output_bfd != (bfd *)NULL)
+ return bfd_reloc_continue;
+
+ relocation = (target & 0x00ffffff) << 2;
+ relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */
+ relocation += symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+ relocation -= input_section->output_section->vma;
+ relocation -= input_section->output_offset;
+ relocation -= addr;
+ if (relocation & 3)
+ return bfd_reloc_overflow;
+
+ /* Check for overflow */
+ if (relocation & 0x02000000)
+ {
+ if ((relocation & ~ (bfd_vma) 0x03ffffff) != ~ (bfd_vma) 0x03ffffff)
+ flag = bfd_reloc_overflow;
+ }
+ else if (relocation & ~0x03ffffff)
+ flag = bfd_reloc_overflow;
+
+ target &= ~0x00ffffff;
+ target |= (relocation >> 2) & 0x00ffffff;
+ bfd_put_32 (abfd, target, (bfd_byte *) data + addr);
+
+ /* Now the ARM magic... Change the reloc type so that it is marked as done.
+ Strictly this is only necessary if we are doing a partial relocation. */
+ reloc_entry->howto = &riscix_std_reloc_howto[7];
+
+ return flag;
+}
+
+reloc_howto_type *
+DEFUN(riscix_reloc_type_lookup,(abfd,code),
+ bfd *abfd AND
+ bfd_reloc_code_real_type code)
+{
+#define ASTD(i,j) case i: return &riscix_std_reloc_howto[j]
+ if (code == BFD_RELOC_CTOR)
+ switch (bfd_get_arch_info (abfd)->bits_per_address)
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default: return (reloc_howto_type *) NULL;
+ }
+
+ switch (code)
+ {
+ ASTD (BFD_RELOC_16, 1);
+ ASTD (BFD_RELOC_32, 2);
+ ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3);
+ ASTD (BFD_RELOC_8_PCREL, 4);
+ ASTD (BFD_RELOC_16_PCREL, 5);
+ ASTD (BFD_RELOC_32_PCREL, 6);
+ default: return (reloc_howto_type *) NULL;
+ }
+}
+
+#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define MY_final_link_callback should_not_be_used
+#define MY_bfd_final_link _bfd_generic_final_link
+
+#define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup
+#define MY_canonicalize_reloc riscix_canonicalize_reloc
+#define MY_object_p riscix_object_p
+
+static const bfd_target *riscix_callback PARAMS ((bfd *));
+
+void
+riscix_swap_std_reloc_out (abfd, g, natptr)
+ bfd *abfd;
+ arelent *g;
+ struct reloc_std_external *natptr;
+{
+ int r_index;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ int r_extern;
+ int r_length;
+ int r_pcrel;
+ int r_neg = 0; /* Negative relocs use the BASEREL bit. */
+ asection *output_section = sym->section->output_section;
+
+ PUT_WORD(abfd, g->address, natptr->r_address);
+
+ r_length = g->howto->size ; /* Size as a power of two */
+ if (r_length < 0)
+ {
+ r_length = -r_length;
+ r_neg = 1;
+ }
+
+ r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
+
+ /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the
+ relocation has been done already (Only for the 26-bit one I think)???!!!
+ */
+
+ if (r_length == 3)
+ r_pcrel = r_pcrel ? 0 : 1;
+
+
+#if 0
+ /* For a standard reloc, the addend is in the object file. */
+ r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+#endif
+
+ /* name was clobbered by aout_write_syms to be symbol index */
+
+ /* If this relocation is relative to a symbol then set the
+ r_index to the symbols index, and the r_extern bit.
+
+ Absolute symbols can come in in two ways, either as an offset
+ from the abs section, or as a symbol which has an abs value.
+ check for that here
+ */
+
+ if (bfd_is_com_section (output_section)
+ || output_section == &bfd_abs_section
+ || output_section == &bfd_und_section)
+ {
+ if (bfd_abs_section.symbol == sym)
+ {
+ /* Whoops, looked like an abs symbol, but is really an offset
+ from the abs section */
+ r_index = 0;
+ r_extern = 0;
+ }
+ else
+ {
+ /* Fill in symbol */
+ r_extern = 1;
+ r_index = (*g->sym_ptr_ptr)->udata.i;
+ }
+ }
+ else
+ {
+ /* Just an ordinary section */
+ r_extern = 0;
+ r_index = output_section->target_index;
+ }
+
+ /* now the fun stuff */
+ if (bfd_header_big_endian (abfd))
+ {
+ natptr->r_index[0] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[2] = r_index;
+ natptr->r_type[0] =
+ ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0)
+ | (r_neg ? RELOC_STD_BITS_BASEREL_BIG: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
+ }
+ else
+ {
+ natptr->r_index[2] = r_index >> 16;
+ natptr->r_index[1] = r_index >> 8;
+ natptr->r_index[0] = r_index;
+ natptr->r_type[0] =
+ ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0)
+ | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0)
+ | (r_neg ? RELOC_STD_BITS_BASEREL_LITTLE: 0)
+ | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
+ }
+}
+
+boolean
+riscix_squirt_out_relocs (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+ arelent **generic;
+ unsigned char *native, *natptr;
+ size_t each_size;
+
+ unsigned int count = section->reloc_count;
+ size_t natsize;
+
+ if (count == 0) return true;
+
+ each_size = obj_reloc_entry_size (abfd);
+ natsize = each_size * count;
+ native = (unsigned char *) bfd_zalloc (abfd, natsize);
+ if (!native)
+ return false;
+
+ generic = section->orelocation;
+
+ for (natptr = native;
+ count != 0;
+ --count, natptr += each_size, ++generic)
+ riscix_swap_std_reloc_out (abfd, *generic,
+ (struct reloc_std_external *) natptr);
+
+ if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize)
+ {
+ bfd_release(abfd, native);
+ return false;
+ }
+
+ bfd_release (abfd, native);
+ return true;
+}
+
+
+/*
+ * This is just like the standard aoutx.h version but we need to do our
+ * own mapping of external reloc type values to howto entries.
+ */
+long
+MY(canonicalize_reloc)(abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr = section->relocation;
+ unsigned int count, c;
+ extern reloc_howto_type NAME(aout,std_howto_table)[];
+
+ /* If we have already read in the relocation table, return the values. */
+ if (section->flags & SEC_CONSTRUCTOR) {
+ arelent_chain *chain = section->constructor_chain;
+
+ for (count = 0; count < section->reloc_count; count++) {
+ *relptr++ = &chain->relent;
+ chain = chain->next;
+ }
+ *relptr = 0;
+ return section->reloc_count;
+ }
+ if (tblptr && section->reloc_count) {
+ for (count = 0; count++ < section->reloc_count;)
+ *relptr++ = tblptr++;
+ *relptr = 0;
+ return section->reloc_count;
+ }
+
+ if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols))
+ return -1;
+ tblptr = section->relocation;
+
+ /* fix up howto entries */
+ for (count = 0; count++ < section->reloc_count;)
+ {
+ c = tblptr->howto - NAME(aout,std_howto_table);
+ BFD_ASSERT (c < RISCIX_TABLE_SIZE);
+ tblptr->howto = &riscix_std_reloc_howto[c];
+
+ *relptr++ = tblptr++;
+ }
+ *relptr = 0;
+ return section->reloc_count;
+}
+
+/* This is the same as NAME(aout,some_aout_object_p), but has different
+ expansions of the macro definitions. */
+
+const bfd_target *
+riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p)
+ bfd *abfd;
+ struct internal_exec *execp;
+ const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
+{
+ struct aout_data_struct *rawptr, *oldrawptr;
+ const bfd_target *result;
+
+ rawptr = ((struct aout_data_struct *)
+ bfd_zalloc (abfd, sizeof (struct aout_data_struct )));
+
+ if (rawptr == NULL)
+ return 0;
+
+ oldrawptr = abfd->tdata.aout_data;
+ abfd->tdata.aout_data = rawptr;
+
+ /* Copy the contents of the old tdata struct.
+ In particular, we want the subformat, since for hpux it was set in
+ hp300hpux.c:swap_exec_header_in and will be used in
+ hp300hpux.c:callback. */
+ if (oldrawptr != NULL)
+ *abfd->tdata.aout_data = *oldrawptr;
+
+ abfd->tdata.aout_data->a.hdr = &rawptr->e;
+ *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec
+ struct */
+ execp = abfd->tdata.aout_data->a.hdr;
+
+ /* Set the file flags */
+ abfd->flags = BFD_NO_FLAGS;
+ if (execp->a_drsize || execp->a_trsize)
+ abfd->flags |= HAS_RELOC;
+ /* Setting of EXEC_P has been deferred to the bottom of this function */
+ if (execp->a_syms)
+ abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
+ if (N_DYNAMIC(*execp))
+ abfd->flags |= DYNAMIC;
+
+
+ if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported
+ (yet)! */
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ else if ((execp->a_info & MF_IS_SL) != 0) /* Nor are shared libraries */
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ else if (N_MAGIC (*execp) == ZMAGIC)
+ {
+ abfd->flags |= D_PAGED | WP_TEXT;
+ adata (abfd).magic = z_magic;
+ }
+ else if (N_MAGIC (*execp) == NMAGIC)
+ {
+ abfd->flags |= WP_TEXT;
+ adata (abfd).magic = n_magic;
+ }
+ else if (N_MAGIC (*execp) == OMAGIC)
+ adata (abfd).magic = o_magic;
+ else
+ {
+ /* Should have been checked with N_BADMAG before this routine
+ was called. */
+ abort ();
+ }
+
+ bfd_get_start_address (abfd) = execp->a_entry;
+
+ obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
+ bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
+
+ /* The default relocation entry size is that of traditional V7 Unix. */
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ /* The default symbol entry size is that of traditional Unix. */
+ obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
+
+ obj_aout_external_syms (abfd) = NULL;
+ obj_aout_external_strings (abfd) = NULL;
+ obj_aout_sym_hashes (abfd) = NULL;
+
+ if (! NAME(aout,make_sections) (abfd))
+ return NULL;
+
+ obj_datasec (abfd)->_raw_size = execp->a_data;
+ obj_bsssec (abfd)->_raw_size = execp->a_bss;
+
+ obj_textsec (abfd)->flags =
+ (execp->a_trsize != 0
+ ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
+ : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
+ obj_datasec (abfd)->flags =
+ (execp->a_drsize != 0
+ ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
+ : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
+ obj_bsssec (abfd)->flags = SEC_ALLOC;
+
+ result = (*callback_to_real_object_p)(abfd);
+
+#if defined(MACH) || defined(STAT_FOR_EXEC)
+ /* The original heuristic doesn't work in some important cases. The
+ * a.out file has no information about the text start address. For
+ * files (like kernels) linked to non-standard addresses (ld -Ttext
+ * nnn) the entry point may not be between the default text start
+ * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
+ * This is not just a mach issue. Many kernels are loaded at non
+ * standard addresses.
+ */
+ {
+ struct stat stat_buf;
+ if (abfd->iostream != NULL
+ && (abfd->flags & BFD_IN_MEMORY) == 0
+ && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
+ && ((stat_buf.st_mode & 0111) != 0))
+ abfd->flags |= EXEC_P;
+ }
+#else /* ! MACH */
+ /* Now that the segment addresses have been worked out, take a better
+ guess at whether the file is executable. If the entry point
+ is within the text segment, assume it is. (This makes files
+ executable even if their entry point address is 0, as long as
+ their text starts at zero.)
+
+ At some point we should probably break down and stat the file and
+ declare it executable if (one of) its 'x' bits are on... */
+ if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
+ (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
+ abfd->flags |= EXEC_P;
+#endif /* MACH */
+ if (result)
+ {
+ }
+ else
+ {
+ free (rawptr);
+ abfd->tdata.aout_data = oldrawptr;
+ }
+ return result;
+}
+
+
+static const bfd_target *
+MY(object_p) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes; /* Raw exec header from file */
+ struct internal_exec exec; /* Cleaned-up exec header */
+ const bfd_target *target;
+
+ if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE) {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
+
+ if (N_BADMAG (exec)) return 0;
+#ifdef MACHTYPE_OK
+ if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
+#endif
+
+ NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
+
+ target = riscix_some_aout_object_p (abfd, &exec, MY(callback));
+
+ return target;
+}
+
+
+#include "aout-target.h"
diff --git a/bfd/rs6000-core.c b/bfd/rs6000-core.c
new file mode 100644
index 00000000000..b20555f5d38
--- /dev/null
+++ b/bfd/rs6000-core.c
@@ -0,0 +1,507 @@
+/* IBM RS/6000 "XCOFF" back-end for BFD.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ FIXME: Can someone provide a transliteration of this name into ASCII?
+ Using the following chars caused a compiler warning on HIUX (so I replaced
+ them with octal escapes), and isn't useful without an understanding of what
+ character set it is.
+ Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
+ and John Gilmore.
+ Archive support from Damon A. Permezel.
+ Contributed by IBM Corporation and Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This port currently only handles reading object files, except when
+ compiled on an RS/6000 host. -- no archive support, no core files.
+ In all cases, it does not support writing.
+
+ FIXMEmgo comments are left from Metin Ozisik's original port.
+
+ This is in a separate file from coff-rs6000.c, because it includes
+ system include files that conflict with coff/rs6000.h.
+ */
+
+/* Internalcoff.h and coffcode.h modify themselves based on this flag. */
+#define RS6000COFF_C 1
+
+/* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
+ we have to define _LONG_LONG for older versions of gcc to get the
+ proper alignments in the user structure. */
+#if defined(_AIX41) && !defined(_LONG_LONG)
+#define _LONG_LONG
+#endif
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifdef AIX_CORE
+
+/* AOUTHDR is defined by the above. We need another defn of it, from the
+ system include files. Punt the old one and get us a new name for the
+ typedef in the system include files. */
+#ifdef AOUTHDR
+#undef AOUTHDR
+#endif
+#define AOUTHDR second_AOUTHDR
+
+#undef SCNHDR
+
+
+/* ------------------------------------------------------------------------ */
+/* Support for core file stuff.. */
+/* ------------------------------------------------------------------------ */
+
+#include <sys/user.h>
+#include <sys/ldr.h>
+#include <sys/core.h>
+
+
+/* Number of special purpose registers supported by gdb. This value
+ should match `tm.h' in gdb directory. Clean this mess up and use
+ the macros in sys/reg.h. FIXMEmgo. */
+
+#define NUM_OF_SPEC_REGS 7
+
+#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
+
+/* AIX 4.1 Changed the names and locations of a few items in the core file,
+ this seems to be the quickest easiet way to deal with it.
+
+ Note however that encoding magic addresses (STACK_END_ADDR) is going
+ to be _very_ fragile. But I don't see any easy way to get that info
+ right now. */
+#ifdef CORE_VERSION_1
+#define CORE_DATA_SIZE_FIELD c_u.U_dsize
+#define CORE_COMM_FIELD c_u.U_comm
+#define SAVE_FIELD c_mst
+#define STACK_END_ADDR 0x2ff23000
+#else
+#define CORE_DATA_SIZE_FIELD c_u.u_dsize
+#define CORE_COMM_FIELD c_u.u_comm
+#define SAVE_FIELD c_u.u_save
+#define STACK_END_ADDR 0x2ff80000
+#endif
+
+/* These are stored in the bfd's tdata */
+typedef struct {
+ struct core_dump hdr; /* core file header */
+} Rs6kCorData;
+
+static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword,
+ bfd_size_type, bfd_vma, file_ptr));
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+ bfd *abfd;
+ CONST char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ bfd_vma vma;
+ file_ptr filepos;
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway (abfd, name);
+ if (!asect)
+ return NULL;
+
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 8;
+
+ return asect;
+}
+
+/* Decide if a given bfd represents a `core' file or not. There really is no
+ magic number or anything like, in rs6000coff. */
+
+const bfd_target *
+rs6000coff_core_p (abfd)
+ bfd *abfd;
+{
+ struct core_dump coredata;
+ struct stat statbuf;
+ bfd_size_type nread;
+ char *tmpptr;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return NULL;
+
+ nread = bfd_read (&coredata, 1, sizeof (struct core_dump), abfd);
+ if (nread != sizeof (struct core_dump))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ /* If the core file ulimit is too small, the system will first
+ omit the data segment, then omit the stack, then decline to
+ dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
+ are always set) (this is based on experimentation on AIX 3.2).
+ Now, the thing is that GDB users will be surprised
+ if segments just silently don't appear (well, maybe they would
+ think to check "info files", I don't know).
+
+ For the data segment, we have no choice but to keep going if it's
+ not there, since the default behavior is not to dump it (regardless
+ of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
+ if it's not there, we refuse to have anything to do with this core
+ file. The usefulness of a core dump without a stack segment is pretty
+ limited anyway. */
+
+ if (!(coredata.c_flag & UBLOCK_VALID)
+ || !(coredata.c_flag & LE_VALID))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (!(coredata.c_flag & USTACK_VALID))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return NULL;
+ }
+
+ /* Don't check the core file size for a full core, AIX 4.1 includes
+ additional shared library sections in a full core. */
+ if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC))
+ && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size)
+ {
+ /* If the size is wrong, it means we're misinterpreting something. */
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Sanity check on the c_tab field. */
+ if ((u_long) coredata.c_tab < sizeof coredata ||
+ (u_long) coredata.c_tab >= statbuf.st_size ||
+ (long) coredata.c_tab >= (long)coredata.c_stack)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Issue warning if the core file was truncated during writing. */
+ if (coredata.c_flag & CORE_TRUNC)
+ (*_bfd_error_handler) (_("%s: warning core file truncated"),
+ bfd_get_filename (abfd));
+
+ /* Allocate core file header. */
+ tmpptr = (char*) bfd_zalloc (abfd, sizeof (Rs6kCorData));
+ if (!tmpptr)
+ return NULL;
+
+ set_tdata (abfd, tmpptr);
+
+ /* Copy core file header. */
+ core_hdr (abfd) = coredata;
+
+ /* .stack section. */
+ if (!make_bfd_asection (abfd, ".stack",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ (bfd_size_type) coredata.c_size,
+ (bfd_vma) (STACK_END_ADDR - coredata.c_size),
+ (file_ptr) coredata.c_stack))
+ return NULL;
+
+ /* .reg section for GPRs and special registers. */
+ if (!make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ (bfd_size_type) ((32 + NUM_OF_SPEC_REGS) * 4),
+ (bfd_vma) 0,
+ (file_ptr) ((char *) &coredata.SAVE_FIELD
+ - (char *) &coredata)))
+ return NULL;
+
+ /* .reg2 section for FPRs (floating point registers). */
+ if (!make_bfd_asection (abfd, ".reg2",
+ SEC_HAS_CONTENTS,
+ (bfd_size_type) 8 * 32, /* 32 FPRs. */
+ (bfd_vma) 0,
+ (file_ptr) ((char *) &coredata.SAVE_FIELD.fpr[0]
+ - (char *) &coredata)))
+ return NULL;
+
+ /* .ldinfo section.
+ To actually find out how long this section is in this particular
+ core dump would require going down the whole list of struct ld_info's.
+ See if we can just fake it. */
+ if (!make_bfd_asection (abfd, ".ldinfo",
+ SEC_HAS_CONTENTS,
+ (bfd_size_type) 0x7fffffff,
+ (bfd_vma) 0,
+ (file_ptr) coredata.c_tab))
+ return NULL;
+
+#ifndef CORE_VERSION_1
+ /* .data section if present.
+ AIX 3 dumps the complete data section and sets FULL_CORE if the
+ ulimit is large enough, otherwise the data section is omitted.
+ AIX 4 sets FULL_CORE even if the core file is truncated, we have
+ to examine coredata.c_datasize below to find out the actual size of
+ the .data section. */
+ if (coredata.c_flag & FULL_CORE)
+ {
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ (bfd_size_type) coredata.CORE_DATA_SIZE_FIELD,
+ (bfd_vma)
+ CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
+ (file_ptr) coredata.c_stack + coredata.c_size))
+ return NULL;
+ }
+#endif
+
+#ifdef CORE_VERSION_1
+ /* AIX 4 adds data sections from loaded objects to the core file,
+ which can be found by examining ldinfo, and anonymously mmapped
+ regions. */
+ {
+ struct ld_info ldinfo;
+ bfd_size_type ldinfo_size;
+ file_ptr ldinfo_offset = (file_ptr) coredata.c_tab;
+
+ /* .data section from executable. */
+ if (coredata.c_datasize)
+ {
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ (bfd_size_type) coredata.c_datasize,
+ (bfd_vma)
+ CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
+ (file_ptr) coredata.c_data))
+ return NULL;
+ }
+
+ /* .data sections from loaded objects. */
+ ldinfo_size = (char *) &ldinfo.ldinfo_filename[0]
+ - (char *) &ldinfo.ldinfo_next;
+ while (1)
+ {
+ if (bfd_seek (abfd, ldinfo_offset, SEEK_SET) != 0)
+ return NULL;
+ if (bfd_read (&ldinfo, ldinfo_size, 1, abfd) != ldinfo_size)
+ return NULL;
+ if (ldinfo.ldinfo_core)
+ {
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ (bfd_size_type) ldinfo.ldinfo_datasize,
+ (bfd_vma) ldinfo.ldinfo_dataorg,
+ (file_ptr) ldinfo.ldinfo_core))
+ return NULL;
+ }
+ if (ldinfo.ldinfo_next == 0)
+ break;
+ ldinfo_offset += ldinfo.ldinfo_next;
+ }
+
+ /* .vmdata sections from anonymously mmapped regions. */
+ if (coredata.c_vmregions)
+ {
+ int i;
+
+ if (bfd_seek (abfd, (file_ptr) coredata.c_vmm, SEEK_SET) != 0)
+ return NULL;
+
+ for (i = 0; i < coredata.c_vmregions; i++)
+ {
+ struct vm_info vminfo;
+
+ if (bfd_read (&vminfo, sizeof (vminfo), 1, abfd) != sizeof (vminfo))
+ return NULL;
+ if (vminfo.vminfo_offset)
+ {
+ if (!make_bfd_asection (abfd, ".vmdata",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ (bfd_size_type) vminfo.vminfo_size,
+ (bfd_vma) vminfo.vminfo_addr,
+ (file_ptr) vminfo.vminfo_offset))
+ return NULL;
+ }
+ }
+ }
+ }
+#endif
+
+ return abfd->xvec; /* this is garbage for now. */
+}
+
+
+
+/* return `true' if given core is from the given executable.. */
+boolean
+rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd;
+ bfd *exec_bfd;
+{
+ struct core_dump coredata;
+ struct ld_info ldinfo;
+ bfd_size_type size;
+ char *path, *s;
+ size_t alloc;
+ const char *str1, *str2;
+ boolean ret;
+
+ if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
+ || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
+ return false;
+
+ if (bfd_seek (core_bfd, (long) coredata.c_tab, SEEK_SET) != 0)
+ return false;
+
+ size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
+ if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
+ return false;
+
+ alloc = 100;
+ path = bfd_malloc (alloc);
+ if (path == NULL)
+ return false;
+ s = path;
+
+ while (1)
+ {
+ if (bfd_read (s, 1, 1, core_bfd) != 1)
+ {
+ free (path);
+ return false;
+ }
+ if (*s == '\0')
+ break;
+ ++s;
+ if (s == path + alloc)
+ {
+ char *n;
+
+ alloc *= 2;
+ n = bfd_realloc (path, alloc);
+ if (n == NULL)
+ {
+ free (path);
+ return false;
+ }
+ s = n + (path - s);
+ path = n;
+ }
+ }
+
+ str1 = strrchr (path, '/');
+ str2 = strrchr (exec_bfd->filename, '/');
+
+ /* step over character '/' */
+ str1 = str1 != NULL ? str1 + 1 : path;
+ str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
+
+ if (strcmp (str1, str2) == 0)
+ ret = true;
+ else
+ ret = false;
+
+ free (path);
+
+ return ret;
+}
+
+char *
+rs6000coff_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ char *com = core_hdr (abfd).CORE_COMM_FIELD;
+ if (*com)
+ return com;
+ else
+ return 0;
+}
+
+int
+rs6000coff_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+ return core_hdr (abfd).c_signo;
+}
+
+
+boolean
+rs6000coff_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (count == 0)
+ return true;
+
+ /* Reading a core file's sections will be slightly different. For the
+ rest of them we can use bfd_generic_get_section_contents () I suppose. */
+ /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
+
+ if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
+
+ struct mstsave mstatus;
+ int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
+
+ /* Assert that the only way this code will be executed is reading the
+ whole section. */
+ if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
+ (*_bfd_error_handler)
+ (_("ERROR! in rs6000coff_get_section_contents()\n"));
+
+ /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
+ in the core file. */
+
+ /* read GPR's into the location. */
+ if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
+ || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
+ return (false); /* on error */
+
+ /* increment location to the beginning of special registers in the section,
+ reset register offset value to the beginning of first special register
+ in mstsave structure, and read special registers. */
+
+ location = (PTR) ((char*)location + sizeof (mstatus.gpr));
+ regoffset = (char*)&mstatus.iar - (char*)&mstatus;
+
+ if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
+ || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
+ 4 * NUM_OF_SPEC_REGS)
+ return (false); /* on error */
+
+ /* increment location address, and read the special registers.. */
+ /* FIXMEmgo */
+ return (true);
+ }
+
+ /* else, use default bfd section content transfer. */
+ else
+ return _bfd_generic_get_section_contents
+ (abfd, section, location, offset, count);
+}
+
+#endif /* AIX_CORE */
diff --git a/bfd/sco5-core.c b/bfd/sco5-core.c
new file mode 100644
index 00000000000..f10c8f139f6
--- /dev/null
+++ b/bfd/sco5-core.c
@@ -0,0 +1,429 @@
+/* BFD back end for SCO5 core files (U-area and raw sections)
+ Copyright 1998 Free Software Foundation, Inc.
+ Written by Jouke Numan <jnuman@hiscom.nl>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+
+#include <sys/user.h> /* After a.out.h */
+#include <sys/paccess.h>
+#include <sys/region.h>
+
+struct sco5_core_struct
+{
+ struct user u;
+};
+
+/* forward declarations */
+
+static asection *
+make_bfd_asection PARAMS ((bfd *, const char *, flagword, bfd_size_type,
+ bfd_vma, file_ptr));
+static asymbol *sco5_core_make_empty_symbol PARAMS ((bfd *));
+static struct user *read_uarea PARAMS ((bfd *, int));
+const bfd_target *sco5_core_file_p PARAMS ((bfd *abfd));
+char *sco5_core_file_failing_command PARAMS ((bfd *abfd));
+int sco5_core_file_failing_signal PARAMS ((bfd *abfd));
+boolean sco5_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
+ bfd *exec_bfd));
+static void swap_abort PARAMS ((void));
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ bfd_size_type _raw_size;
+ bfd_vma vma;
+ file_ptr filepos;
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway (abfd, name);
+ if (!asect)
+ return NULL;
+ asect->flags = flags;
+ asect->_raw_size = _raw_size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 2;
+
+ return asect;
+}
+
+static asymbol *
+sco5_core_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+static struct user *
+read_uarea(abfd, filepos)
+ bfd *abfd;
+ int filepos;
+
+{
+ struct sco5_core_struct *rawptr;
+
+ rawptr = ((struct sco5_core_struct *)
+ bfd_zmalloc (sizeof (struct sco5_core_struct)));
+ if (rawptr == NULL)
+ return NULL;
+
+ abfd->tdata.sco5_core_data = rawptr;
+
+ if ((bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ || (bfd_read ((void *)&rawptr->u, 1, sizeof rawptr->u, abfd)
+ != sizeof rawptr->u))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Sanity check perhaps??? */
+ if (rawptr->u.u_dsize > 0x1000000) /* Remember, it's in pages... */
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ if (rawptr->u.u_ssize > 0x1000000)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ return &rawptr->u;
+}
+
+/* ARGSUSED */
+const bfd_target *
+sco5_core_file_p (abfd)
+ bfd *abfd;
+{
+ int coffset_siz, val, nsecs, cheadoffs;
+ int coresize;
+ struct user *u;
+ struct coreoffsets coffsets;
+ struct coresecthead chead;
+ char *secname;
+ flagword flags;
+
+ /* Read coreoffsets region at end of core (see core(FP)) */
+
+ {
+ FILE *stream = bfd_cache_lookup (abfd);
+ struct stat statbuf;
+ if (stream == NULL)
+ return NULL;
+ if (fstat (fileno (stream), &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+ coresize = statbuf.st_size;
+ }
+ /* Last long in core is sizeof struct coreoffsets, read it */
+ if ((bfd_seek (abfd, coresize-sizeof coffset_siz, SEEK_SET) != 0)
+ || (bfd_read ((void *)&coffset_siz, 1, sizeof coffset_siz, abfd)
+ != sizeof coffset_siz) )
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Use it to seek start of coreoffsets region, read it and determine
+ validity */
+ if ((bfd_seek (abfd, coresize-coffset_siz, SEEK_SET) != 0)
+ || (bfd_read ((void *)&coffsets, 1, sizeof coffsets, abfd)
+ != sizeof coffsets)
+ || ((coffsets.u_info != 1) && (coffsets.u_info != C_VERSION)))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+
+ if (coffsets.u_info == 1)
+ {
+ /* Old version, no section heads, read info from user struct */
+
+ u = read_uarea(abfd, coffsets.u_user);
+ if (! u)
+ return NULL;
+
+ if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS,
+ (bfd_size_type) coffsets.u_usize,
+ 0 - (bfd_vma) u->u_ar0,
+ (file_ptr) coffsets.u_user))
+ return NULL;
+
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ ((bfd_size_type) u->u_exdata.ux_dsize
+ + u->u_exdata.ux_bsize),
+ (bfd_vma) u->u_exdata.ux_datorg,
+ (file_ptr) coffsets.u_data))
+ return NULL;
+
+ if (!make_bfd_asection (abfd, ".stack",
+ SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+ (bfd_size_type) u->u_ssize * NBPC,
+ (bfd_vma) u->u_sub,
+ (file_ptr) coffsets.u_stack))
+ return NULL;
+
+ return abfd->xvec; /* Done for version 1 */
+ }
+
+ /* Immediately before coreoffsets region is a long with offset in core
+ to first coresecthead (CORES_OFFSETS), the long before this is the
+ number of section heads in the list. Read both longs and read the
+ coresecthead and check its validity */
+
+ if ((bfd_seek (abfd,
+ coresize - coffset_siz - 2 * sizeof coffset_siz,
+ SEEK_SET) != 0)
+ || (bfd_read ((void *)&nsecs, 1, sizeof nsecs, abfd) != sizeof nsecs)
+ || (bfd_read ((void *)&cheadoffs, 1, sizeof cheadoffs, abfd)
+ != sizeof cheadoffs)
+ || (bfd_seek (abfd, cheadoffs, SEEK_SET) != 0)
+ || (bfd_read ((void *)&chead, 1, sizeof chead, abfd) != sizeof chead)
+ || (chead.cs_stype != CORES_OFFSETS)
+ || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ /* Now loop over all regions and map them */
+ nsecs--; /* We've seen CORES_OFFSETS already */
+ for (; nsecs; nsecs--)
+ {
+ if ((bfd_seek (abfd, chead.cs_hseek, SEEK_SET) != 0)
+ || bfd_read ((void *)&chead, 1, sizeof chead, abfd) != sizeof chead)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ switch (chead.cs_stype)
+ {
+ case CORES_MAGIC: /* Core header, check magic */
+ if (chead.cs_x.csx_magic != COREMAGIC_NUMBER)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ secname = NULL;
+ nsecs++; /* MAGIC not in section cnt!*/
+ break;
+ case CORES_UAREA: /* U-area, read in tdata */
+ u = read_uarea(abfd, chead.cs_sseek);
+ if (! u)
+ return NULL;
+
+ /* This is tricky. As the "register section", we give them
+ the entire upage and stack. u.u_ar0 points to where
+ "register 0" is stored. There are two tricks with this,
+ though. One is that the rest of the registers might be
+ at positive or negative (or both) displacements from
+ *u_ar0. The other is that u_ar0 is sometimes an absolute
+ address in kernel memory, and on other systems it is an
+ offset from the beginning of the `struct user'.
+
+ As a practical matter, we don't know where the registers
+ actually are, so we have to pass the whole area to GDB.
+ We encode the value of u_ar0 by setting the .regs section
+ up so that its virtual memory address 0 is at the place
+ pointed to by u_ar0 (by setting the vma of the start of
+ the section to -u_ar0). GDB uses this info to locate the
+ regs, using minor trickery to get around the
+ offset-or-absolute-addr problem. */
+
+ chead.cs_vaddr = 0 - (bfd_vma) u->u_ar0;
+
+
+ secname = ".reg";
+ flags = SEC_HAS_CONTENTS;
+
+ break;
+ case CORES_PREGION: /* A program region, map it */
+ switch (chead.cs_x.csx_preg.csxp_rtyp)
+ {
+ case PT_DATA:
+ secname = ".data"; /* Data region. */
+ break;
+ case PT_STACK:
+ secname = ".stack"; /* Stack region. */
+ break;
+ case PT_SHMEM:
+ secname = ".shmem"; /* Shared memory */
+ break;
+ case PT_LIBDAT:
+ secname = ".libdat"; /* Shared library data */
+ break;
+ case PT_V86:
+ secname = ".virt86"; /* Virtual 8086 mode */
+ break;
+ case PT_SHFIL:
+ secname = ".mmfile"; /* Memory mapped file */
+ break;
+ case PT_XDATA0:
+ secname = ".Xdat0"; /* XENIX data region, virtual 0 */
+ break;
+ default:
+ secname = "";
+ }
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ case CORES_PROC: /* struct proc */
+ case CORES_ITIMER: /* interval timers */
+ case CORES_SCOUTSNAME: /* struct scoutsname */
+ secname = NULL; /* Ignore these */
+ break;
+ default:
+ (*_bfd_error_handler) ("Unhandled SCO core file section type %d\n",
+ chead.cs_stype);
+ continue;
+ }
+
+ if (secname
+ && !make_bfd_asection (abfd, secname, flags,
+ (bfd_size_type) chead.cs_vsize,
+ (bfd_vma) chead.cs_vaddr,
+ (file_ptr) chead.cs_sseek))
+ return NULL;
+
+ }
+
+ return abfd->xvec;
+
+}
+
+char *
+sco5_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ char *com = abfd->tdata.sco5_core_data->u.u_comm;
+ if (*com)
+ return com;
+ else
+ return NULL;
+}
+
+/* ARGSUSED */
+int
+sco5_core_file_failing_signal (ignore_abfd)
+ bfd *ignore_abfd;
+{
+ return ((ignore_abfd->tdata.sco5_core_data->u.u_sysabort != 0)
+ ? ignore_abfd->tdata.sco5_core_data->u.u_sysabort
+ : -1);
+}
+
+/* ARGSUSED */
+boolean
+sco5_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this point */
+}
+
+#define sco5_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
+#define sco5_core_get_symtab _bfd_nosymbols_get_symtab
+#define sco5_core_print_symbol _bfd_nosymbols_print_symbol
+#define sco5_core_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define sco5_core_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
+#define sco5_core_get_lineno _bfd_nosymbols_get_lineno
+#define sco5_core_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define sco5_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define sco5_core_read_minisymbols _bfd_nosymbols_read_minisymbols
+#define sco5_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target sco5_core_vec =
+ {
+ "sco5-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_LITTLE, /* target byte order */
+ BFD_ENDIAN_LITTLE, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ sco5_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (sco5),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (sco5_core),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
diff --git a/bfd/section.c b/bfd/section.c
new file mode 100644
index 00000000000..18778b5362f
--- /dev/null
+++ b/bfd/section.c
@@ -0,0 +1,1075 @@
+/* Object file "section" support for the BFD library.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ Sections
+
+ The raw data contained within a BFD is maintained through the
+ section abstraction. A single BFD may have any number of
+ sections. It keeps hold of them by pointing to the first;
+ each one points to the next in the list.
+
+ Sections are supported in BFD in <<section.c>>.
+
+@menu
+@* Section Input::
+@* Section Output::
+@* typedef asection::
+@* section prototypes::
+@end menu
+
+INODE
+Section Input, Section Output, Sections, Sections
+SUBSECTION
+ Section input
+
+ When a BFD is opened for reading, the section structures are
+ created and attached to the BFD.
+
+ Each section has a name which describes the section in the
+ outside world---for example, <<a.out>> would contain at least
+ three sections, called <<.text>>, <<.data>> and <<.bss>>.
+
+ Names need not be unique; for example a COFF file may have several
+ sections named <<.data>>.
+
+ Sometimes a BFD will contain more than the ``natural'' number of
+ sections. A back end may attach other sections containing
+ constructor data, or an application may add a section (using
+ <<bfd_make_section>>) to the sections attached to an already open
+ BFD. For example, the linker creates an extra section
+ <<COMMON>> for each input file's BFD to hold information about
+ common storage.
+
+ The raw data is not necessarily read in when
+ the section descriptor is created. Some targets may leave the
+ data in place until a <<bfd_get_section_contents>> call is
+ made. Other back ends may read in all the data at once. For
+ example, an S-record file has to be read once to determine the
+ size of the data. An IEEE-695 file doesn't contain raw data in
+ sections, but data and relocation expressions intermixed, so
+ the data area has to be parsed to get out the data and
+ relocations.
+
+INODE
+Section Output, typedef asection, Section Input, Sections
+
+SUBSECTION
+ Section output
+
+ To write a new object style BFD, the various sections to be
+ written have to be created. They are attached to the BFD in
+ the same way as input sections; data is written to the
+ sections using <<bfd_set_section_contents>>.
+
+ Any program that creates or combines sections (e.g., the assembler
+ and linker) must use the <<asection>> fields <<output_section>> and
+ <<output_offset>> to indicate the file sections to which each
+ section must be written. (If the section is being created from
+ scratch, <<output_section>> should probably point to the section
+ itself and <<output_offset>> should probably be zero.)
+
+ The data to be written comes from input sections attached
+ (via <<output_section>> pointers) to
+ the output sections. The output section structure can be
+ considered a filter for the input section: the output section
+ determines the vma of the output data and the name, but the
+ input section determines the offset into the output section of
+ the data to be written.
+
+ E.g., to create a section "O", starting at 0x100, 0x123 long,
+ containing two subsections, "A" at offset 0x0 (i.e., at vma
+ 0x100) and "B" at offset 0x20 (i.e., at vma 0x120) the <<asection>>
+ structures would look like:
+
+| section name "A"
+| output_offset 0x00
+| size 0x20
+| output_section -----------> section name "O"
+| | vma 0x100
+| section name "B" | size 0x123
+| output_offset 0x20 |
+| size 0x103 |
+| output_section --------|
+
+
+SUBSECTION
+ Link orders
+
+ The data within a section is stored in a @dfn{link_order}.
+ These are much like the fixups in <<gas>>. The link_order
+ abstraction allows a section to grow and shrink within itself.
+
+ A link_order knows how big it is, and which is the next
+ link_order and where the raw data for it is; it also points to
+ a list of relocations which apply to it.
+
+ The link_order is used by the linker to perform relaxing on
+ final code. The compiler creates code which is as big as
+ necessary to make it work without relaxing, and the user can
+ select whether to relax. Sometimes relaxing takes a lot of
+ time. The linker runs around the relocations to see if any
+ are attached to data which can be shrunk, if so it does it on
+ a link_order by link_order basis.
+
+*/
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+
+/*
+DOCDD
+INODE
+typedef asection, section prototypes, Section Output, Sections
+SUBSECTION
+ typedef asection
+
+ Here is the section structure:
+
+CODE_FRAGMENT
+.
+.typedef struct sec
+.{
+. {* The name of the section; the name isn't a copy, the pointer is
+. the same as that passed to bfd_make_section. *}
+.
+. CONST char *name;
+.
+. {* Which section is it; 0..nth. *}
+.
+. int index;
+.
+. {* The next section in the list belonging to the BFD, or NULL. *}
+.
+. struct sec *next;
+.
+. {* The field flags contains attributes of the section. Some
+. flags are read in from the object file, and some are
+. synthesized from other information. *}
+.
+. flagword flags;
+.
+.#define SEC_NO_FLAGS 0x000
+.
+. {* Tells the OS to allocate space for this section when loading.
+. This is clear for a section containing debug information
+. only. *}
+.#define SEC_ALLOC 0x001
+.
+. {* Tells the OS to load the section from the file when loading.
+. This is clear for a .bss section. *}
+.#define SEC_LOAD 0x002
+.
+. {* The section contains data still to be relocated, so there is
+. some relocation information too. *}
+.#define SEC_RELOC 0x004
+.
+.#if 0 {* Obsolete ? *}
+.#define SEC_BALIGN 0x008
+.#endif
+.
+. {* A signal to the OS that the section contains read only
+. data. *}
+.#define SEC_READONLY 0x010
+.
+. {* The section contains code only. *}
+.#define SEC_CODE 0x020
+.
+. {* The section contains data only. *}
+.#define SEC_DATA 0x040
+.
+. {* The section will reside in ROM. *}
+.#define SEC_ROM 0x080
+.
+. {* The section contains constructor information. This section
+. type is used by the linker to create lists of constructors and
+. destructors used by <<g++>>. When a back end sees a symbol
+. which should be used in a constructor list, it creates a new
+. section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+. the symbol to it, and builds a relocation. To build the lists
+. of constructors, all the linker has to do is catenate all the
+. sections called <<__CTOR_LIST__>> and relocate the data
+. contained within - exactly the operations it would peform on
+. standard data. *}
+.#define SEC_CONSTRUCTOR 0x100
+.
+. {* The section is a constructor, and should be placed at the
+. end of the text, data, or bss section(?). *}
+.#define SEC_CONSTRUCTOR_TEXT 0x1100
+.#define SEC_CONSTRUCTOR_DATA 0x2100
+.#define SEC_CONSTRUCTOR_BSS 0x3100
+.
+. {* The section has contents - a data section could be
+. <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
+. <<SEC_HAS_CONTENTS>> *}
+.#define SEC_HAS_CONTENTS 0x200
+.
+. {* An instruction to the linker to not output the section
+. even if it has information which would normally be written. *}
+.#define SEC_NEVER_LOAD 0x400
+.
+. {* The section is a COFF shared library section. This flag is
+. only for the linker. If this type of section appears in
+. the input file, the linker must copy it to the output file
+. without changing the vma or size. FIXME: Although this
+. was originally intended to be general, it really is COFF
+. specific (and the flag was renamed to indicate this). It
+. might be cleaner to have some more general mechanism to
+. allow the back end to control what the linker does with
+. sections. *}
+.#define SEC_COFF_SHARED_LIBRARY 0x800
+.
+. {* The section contains common symbols (symbols may be defined
+. multiple times, the value of a symbol is the amount of
+. space it requires, and the largest symbol value is the one
+. used). Most targets have exactly one of these (which we
+. translate to bfd_com_section_ptr), but ECOFF has two. *}
+.#define SEC_IS_COMMON 0x8000
+.
+. {* The section contains only debugging information. For
+. example, this is set for ELF .debug and .stab sections.
+. strip tests this flag to see if a section can be
+. discarded. *}
+.#define SEC_DEBUGGING 0x10000
+.
+. {* The contents of this section are held in memory pointed to
+. by the contents field. This is checked by
+. bfd_get_section_contents, and the data is retrieved from
+. memory if appropriate. *}
+.#define SEC_IN_MEMORY 0x20000
+.
+. {* The contents of this section are to be excluded by the
+. linker for executable and shared objects unless those
+. objects are to be further relocated. *}
+.#define SEC_EXCLUDE 0x40000
+.
+. {* The contents of this section are to be sorted by the
+. based on the address specified in the associated symbol
+. table. *}
+.#define SEC_SORT_ENTRIES 0x80000
+.
+. {* When linking, duplicate sections of the same name should be
+. discarded, rather than being combined into a single section as
+. is usually done. This is similar to how common symbols are
+. handled. See SEC_LINK_DUPLICATES below. *}
+.#define SEC_LINK_ONCE 0x100000
+.
+. {* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+. should handle duplicate sections. *}
+.#define SEC_LINK_DUPLICATES 0x600000
+.
+. {* This value for SEC_LINK_DUPLICATES means that duplicate
+. sections with the same name should simply be discarded. *}
+.#define SEC_LINK_DUPLICATES_DISCARD 0x0
+.
+. {* This value for SEC_LINK_DUPLICATES means that the linker
+. should warn if there are any duplicate sections, although
+. it should still only link one copy. *}
+.#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000
+.
+. {* This value for SEC_LINK_DUPLICATES means that the linker
+. should warn if any duplicate sections are a different size. *}
+.#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000
+.
+. {* This value for SEC_LINK_DUPLICATES means that the linker
+. should warn if any duplicate sections contain different
+. contents. *}
+.#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
+.
+. {* This section was created by the linker as part of dynamic
+. relocation or other arcane processing. It is skipped when
+. going through the first-pass output, trusting that someone
+. else up the line will take care of it later. *}
+.#define SEC_LINKER_CREATED 0x800000
+.
+. {* This section should not be subject to garbage collection. *}
+.#define SEC_KEEP 0x1000000
+.
+. {* End of section flags. *}
+.
+. {* Some internal packed boolean fields. *}
+.
+. {* See the vma field. *}
+. unsigned int user_set_vma : 1;
+.
+. {* Whether relocations have been processed. *}
+. unsigned int reloc_done : 1;
+.
+. {* A mark flag used by some of the linker backends. *}
+. unsigned int linker_mark : 1;
+.
+. {* A mark flag used by some linker backends for garbage collection. *}
+. unsigned int gc_mark : 1;
+.
+. {* End of internal packed boolean fields. *}
+.
+. {* The virtual memory address of the section - where it will be
+. at run time. The symbols are relocated against this. The
+. user_set_vma flag is maintained by bfd; if it's not set, the
+. backend can assign addresses (for example, in <<a.out>>, where
+. the default address for <<.data>> is dependent on the specific
+. target and various flags). *}
+.
+. bfd_vma vma;
+.
+. {* The load address of the section - where it would be in a
+. rom image; really only used for writing section header
+. information. *}
+.
+. bfd_vma lma;
+.
+. {* The size of the section in bytes, as it will be output.
+. contains a value even if the section has no contents (e.g., the
+. size of <<.bss>>). This will be filled in after relocation *}
+.
+. bfd_size_type _cooked_size;
+.
+. {* The original size on disk of the section, in bytes. Normally this
+. value is the same as the size, but if some relaxing has
+. been done, then this value will be bigger. *}
+.
+. bfd_size_type _raw_size;
+.
+. {* If this section is going to be output, then this value is the
+. offset into the output section of the first byte in the input
+. section. E.g., if this was going to start at the 100th byte in
+. the output section, this value would be 100. *}
+.
+. bfd_vma output_offset;
+.
+. {* The output section through which to map on output. *}
+.
+. struct sec *output_section;
+.
+. {* The alignment requirement of the section, as an exponent of 2 -
+. e.g., 3 aligns to 2^3 (or 8). *}
+.
+. unsigned int alignment_power;
+.
+. {* If an input section, a pointer to a vector of relocation
+. records for the data in this section. *}
+.
+. struct reloc_cache_entry *relocation;
+.
+. {* If an output section, a pointer to a vector of pointers to
+. relocation records for the data in this section. *}
+.
+. struct reloc_cache_entry **orelocation;
+.
+. {* The number of relocation records in one of the above *}
+.
+. unsigned reloc_count;
+.
+. {* Information below is back end specific - and not always used
+. or updated. *}
+.
+. {* File position of section data *}
+.
+. file_ptr filepos;
+.
+. {* File position of relocation info *}
+.
+. file_ptr rel_filepos;
+.
+. {* File position of line data *}
+.
+. file_ptr line_filepos;
+.
+. {* Pointer to data for applications *}
+.
+. PTR userdata;
+.
+. {* If the SEC_IN_MEMORY flag is set, this points to the actual
+. contents. *}
+. unsigned char *contents;
+.
+. {* Attached line number information *}
+.
+. alent *lineno;
+.
+. {* Number of line number records *}
+.
+. unsigned int lineno_count;
+.
+. {* When a section is being output, this value changes as more
+. linenumbers are written out *}
+.
+. file_ptr moving_line_filepos;
+.
+. {* What the section number is in the target world *}
+.
+. int target_index;
+.
+. PTR used_by_bfd;
+.
+. {* If this is a constructor section then here is a list of the
+. relocations created to relocate items within it. *}
+.
+. struct relent_chain *constructor_chain;
+.
+. {* The BFD which owns the section. *}
+.
+. bfd *owner;
+.
+. {* A symbol which points at this section only *}
+. struct symbol_cache_entry *symbol;
+. struct symbol_cache_entry **symbol_ptr_ptr;
+.
+. struct bfd_link_order *link_order_head;
+. struct bfd_link_order *link_order_tail;
+.} asection ;
+.
+. {* These sections are global, and are managed by BFD. The application
+. and target back end are not permitted to change the values in
+. these sections. New code should use the section_ptr macros rather
+. than referring directly to the const sections. The const sections
+. may eventually vanish. *}
+.#define BFD_ABS_SECTION_NAME "*ABS*"
+.#define BFD_UND_SECTION_NAME "*UND*"
+.#define BFD_COM_SECTION_NAME "*COM*"
+.#define BFD_IND_SECTION_NAME "*IND*"
+.
+. {* the absolute section *}
+.extern const asection bfd_abs_section;
+.#define bfd_abs_section_ptr ((asection *) &bfd_abs_section)
+.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+. {* Pointer to the undefined section *}
+.extern const asection bfd_und_section;
+.#define bfd_und_section_ptr ((asection *) &bfd_und_section)
+.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+. {* Pointer to the common section *}
+.extern const asection bfd_com_section;
+.#define bfd_com_section_ptr ((asection *) &bfd_com_section)
+. {* Pointer to the indirect section *}
+.extern const asection bfd_ind_section;
+.#define bfd_ind_section_ptr ((asection *) &bfd_ind_section)
+.#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+.
+.extern const struct symbol_cache_entry * const bfd_abs_symbol;
+.extern const struct symbol_cache_entry * const bfd_com_symbol;
+.extern const struct symbol_cache_entry * const bfd_und_symbol;
+.extern const struct symbol_cache_entry * const bfd_ind_symbol;
+.#define bfd_get_section_size_before_reloc(section) \
+. (section->reloc_done ? (abort(),1): (section)->_raw_size)
+.#define bfd_get_section_size_after_reloc(section) \
+. ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
+*/
+
+/* These symbols are global, not specific to any BFD. Therefore, anything
+ that tries to change them is broken, and should be repaired. */
+static const asymbol global_syms[] =
+{
+ /* the_bfd, name, value, attr, section [, udata] */
+ {0, BFD_COM_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_com_section},
+ {0, BFD_UND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_und_section},
+ {0, BFD_ABS_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_abs_section},
+ {0, BFD_IND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_ind_section},
+};
+
+#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
+ const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \
+ const asection SEC = \
+ { NAME, 0, 0, FLAGS, 0, 0, 0, 0, 0, 0, 0, 0, 0, (asection *) &SEC, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ (asymbol *) &global_syms[IDX], (asymbol **) &SYM, 0, 0 }
+
+STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
+ BFD_COM_SECTION_NAME, 0);
+STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1);
+STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2);
+STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3);
+#undef STD_SECTION
+
+/*
+DOCDD
+INODE
+section prototypes, , typedef asection, Sections
+SUBSECTION
+ Section prototypes
+
+These are the functions exported by the section handling part of BFD.
+*/
+
+/*
+FUNCTION
+ bfd_get_section_by_name
+
+SYNOPSIS
+ asection *bfd_get_section_by_name(bfd *abfd, CONST char *name);
+
+DESCRIPTION
+ Run through @var{abfd} and return the one of the
+ <<asection>>s whose name matches @var{name}, otherwise <<NULL>>.
+ @xref{Sections}, for more information.
+
+ This should only be used in special cases; the normal way to process
+ all sections of a given name is to use <<bfd_map_over_sections>> and
+ <<strcmp>> on the name (or better yet, base it on the section flags
+ or something else) for each section.
+*/
+
+asection *
+bfd_get_section_by_name (abfd, name)
+ bfd *abfd;
+ CONST char *name;
+{
+ asection *sect;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ if (!strcmp (sect->name, name))
+ return sect;
+ return NULL;
+}
+
+
+/*
+FUNCTION
+ bfd_make_section_old_way
+
+SYNOPSIS
+ asection *bfd_make_section_old_way(bfd *abfd, CONST char *name);
+
+DESCRIPTION
+ Create a new empty section called @var{name}
+ and attach it to the end of the chain of sections for the
+ BFD @var{abfd}. An attempt to create a section with a name which
+ is already in use returns its pointer without changing the
+ section chain.
+
+ It has the funny name since this is the way it used to be
+ before it was rewritten....
+
+ Possible errors are:
+ o <<bfd_error_invalid_operation>> -
+ If output has already started for this BFD.
+ o <<bfd_error_no_memory>> -
+ If memory allocation fails.
+
+*/
+
+
+asection *
+bfd_make_section_old_way (abfd, name)
+ bfd *abfd;
+ CONST char *name;
+{
+ asection *sec = bfd_get_section_by_name (abfd, name);
+ if (sec == (asection *) NULL)
+ {
+ sec = bfd_make_section (abfd, name);
+ }
+ return sec;
+}
+
+/*
+FUNCTION
+ bfd_make_section_anyway
+
+SYNOPSIS
+ asection *bfd_make_section_anyway(bfd *abfd, CONST char *name);
+
+DESCRIPTION
+ Create a new empty section called @var{name} and attach it to the end of
+ the chain of sections for @var{abfd}. Create a new section even if there
+ is already a section with that name.
+
+ Return <<NULL>> and set <<bfd_error>> on error; possible errors are:
+ o <<bfd_error_invalid_operation>> - If output has already started for @var{abfd}.
+ o <<bfd_error_no_memory>> - If memory allocation fails.
+*/
+
+sec_ptr
+bfd_make_section_anyway (abfd, name)
+ bfd *abfd;
+ CONST char *name;
+{
+ asection *newsect;
+ asection **prev = &abfd->sections;
+ asection *sect = abfd->sections;
+
+ if (abfd->output_has_begun)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ while (sect)
+ {
+ prev = &sect->next;
+ sect = sect->next;
+ }
+
+ newsect = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (newsect == NULL)
+ return NULL;
+
+ newsect->name = name;
+ newsect->index = abfd->section_count++;
+ newsect->flags = SEC_NO_FLAGS;
+
+ newsect->userdata = NULL;
+ newsect->contents = NULL;
+ newsect->next = (asection *) NULL;
+ newsect->relocation = (arelent *) NULL;
+ newsect->reloc_count = 0;
+ newsect->line_filepos = 0;
+ newsect->owner = abfd;
+
+ /* Create a symbol whos only job is to point to this section. This is
+ useful for things like relocs which are relative to the base of a
+ section. */
+ newsect->symbol = bfd_make_empty_symbol (abfd);
+ if (newsect->symbol == NULL)
+ return NULL;
+ newsect->symbol->name = name;
+ newsect->symbol->value = 0;
+ newsect->symbol->section = newsect;
+ newsect->symbol->flags = BSF_SECTION_SYM;
+
+ newsect->symbol_ptr_ptr = &newsect->symbol;
+
+ if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true)
+ {
+ free (newsect);
+ return NULL;
+ }
+
+ *prev = newsect;
+ return newsect;
+}
+
+/*
+FUNCTION
+ bfd_make_section
+
+SYNOPSIS
+ asection *bfd_make_section(bfd *, CONST char *name);
+
+DESCRIPTION
+ Like <<bfd_make_section_anyway>>, but return <<NULL>> (without calling
+ bfd_set_error ()) without changing the section chain if there is already a
+ section named @var{name}. If there is an error, return <<NULL>> and set
+ <<bfd_error>>.
+*/
+
+asection *
+bfd_make_section (abfd, name)
+ bfd *abfd;
+ CONST char *name;
+{
+ asection *sect = abfd->sections;
+
+ if (strcmp (name, BFD_ABS_SECTION_NAME) == 0)
+ {
+ return bfd_abs_section_ptr;
+ }
+ if (strcmp (name, BFD_COM_SECTION_NAME) == 0)
+ {
+ return bfd_com_section_ptr;
+ }
+ if (strcmp (name, BFD_UND_SECTION_NAME) == 0)
+ {
+ return bfd_und_section_ptr;
+ }
+
+ if (strcmp (name, BFD_IND_SECTION_NAME) == 0)
+ {
+ return bfd_ind_section_ptr;
+ }
+
+ while (sect)
+ {
+ if (!strcmp (sect->name, name))
+ return NULL;
+ sect = sect->next;
+ }
+
+ /* The name is not already used; go ahead and make a new section. */
+ return bfd_make_section_anyway (abfd, name);
+}
+
+
+/*
+FUNCTION
+ bfd_set_section_flags
+
+SYNOPSIS
+ boolean bfd_set_section_flags(bfd *abfd, asection *sec, flagword flags);
+
+DESCRIPTION
+ Set the attributes of the section @var{sec} in the BFD
+ @var{abfd} to the value @var{flags}. Return <<true>> on success,
+ <<false>> on error. Possible error returns are:
+
+ o <<bfd_error_invalid_operation>> -
+ The section cannot have one or more of the attributes
+ requested. For example, a .bss section in <<a.out>> may not
+ have the <<SEC_HAS_CONTENTS>> field set.
+
+*/
+
+/*ARGSUSED*/
+boolean
+bfd_set_section_flags (abfd, section, flags)
+ bfd *abfd;
+ sec_ptr section;
+ flagword flags;
+{
+#if 0
+ /* If you try to copy a text section from an input file (where it
+ has the SEC_CODE flag set) to an output file, this loses big if
+ the bfd_applicable_section_flags (abfd) doesn't have the SEC_CODE
+ set - which it doesn't, at least not for a.out. FIXME */
+
+ if ((flags & bfd_applicable_section_flags (abfd)) != flags)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+#endif
+
+ section->flags = flags;
+ return true;
+}
+
+
+/*
+FUNCTION
+ bfd_map_over_sections
+
+SYNOPSIS
+ void bfd_map_over_sections(bfd *abfd,
+ void (*func)(bfd *abfd,
+ asection *sect,
+ PTR obj),
+ PTR obj);
+
+DESCRIPTION
+ Call the provided function @var{func} for each section
+ attached to the BFD @var{abfd}, passing @var{obj} as an
+ argument. The function will be called as if by
+
+| func(abfd, the_section, obj);
+
+ This is the prefered method for iterating over sections; an
+ alternative would be to use a loop:
+
+| section *p;
+| for (p = abfd->sections; p != NULL; p = p->next)
+| func(abfd, p, ...)
+
+
+*/
+
+/*VARARGS2*/
+void
+bfd_map_over_sections (abfd, operation, user_storage)
+ bfd *abfd;
+ void (*operation) PARAMS ((bfd * abfd, asection * sect, PTR obj));
+ PTR user_storage;
+{
+ asection *sect;
+ unsigned int i = 0;
+
+ for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ (*operation) (abfd, sect, user_storage);
+
+ if (i != abfd->section_count) /* Debugging */
+ abort ();
+}
+
+
+/*
+FUNCTION
+ bfd_set_section_size
+
+SYNOPSIS
+ boolean bfd_set_section_size(bfd *abfd, asection *sec, bfd_size_type val);
+
+DESCRIPTION
+ Set @var{sec} to the size @var{val}. If the operation is
+ ok, then <<true>> is returned, else <<false>>.
+
+ Possible error returns:
+ o <<bfd_error_invalid_operation>> -
+ Writing has started to the BFD, so setting the size is invalid.
+
+*/
+
+boolean
+bfd_set_section_size (abfd, ptr, val)
+ bfd *abfd;
+ sec_ptr ptr;
+ bfd_size_type val;
+{
+ /* Once you've started writing to any section you cannot create or change
+ the size of any others. */
+
+ if (abfd->output_has_begun)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ ptr->_cooked_size = val;
+ ptr->_raw_size = val;
+
+ return true;
+}
+
+/*
+FUNCTION
+ bfd_set_section_contents
+
+SYNOPSIS
+ boolean bfd_set_section_contents
+ (bfd *abfd,
+ asection *section,
+ PTR data,
+ file_ptr offset,
+ bfd_size_type count);
+
+
+DESCRIPTION
+ Sets the contents of the section @var{section} in BFD
+ @var{abfd} to the data starting in memory at @var{data}. The
+ data is written to the output section starting at offset
+ @var{offset} for @var{count} bytes.
+
+
+
+ Normally <<true>> is returned, else <<false>>. Possible error
+ returns are:
+ o <<bfd_error_no_contents>> -
+ The output section does not have the <<SEC_HAS_CONTENTS>>
+ attribute, so nothing can be written to it.
+ o and some more too
+
+ This routine is front end to the back end function
+ <<_bfd_set_section_contents>>.
+
+
+*/
+
+#define bfd_get_section_size_now(abfd,sec) \
+(sec->reloc_done \
+ ? bfd_get_section_size_after_reloc (sec) \
+ : bfd_get_section_size_before_reloc (sec))
+
+boolean
+bfd_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ bfd_size_type sz;
+
+ if (!(bfd_get_section_flags (abfd, section) & SEC_HAS_CONTENTS))
+ {
+ bfd_set_error (bfd_error_no_contents);
+ return (false);
+ }
+
+ if (offset < 0)
+ {
+ bad_val:
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ sz = bfd_get_section_size_now (abfd, section);
+ if ((bfd_size_type) offset > sz
+ || count > sz
+ || offset + count > sz)
+ goto bad_val;
+
+ switch (abfd->direction)
+ {
+ case read_direction:
+ case no_direction:
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+
+ case write_direction:
+ break;
+
+ case both_direction:
+ /* File is opened for update. `output_has_begun' some time ago when
+ the file was created. Do not recompute sections sizes or alignments
+ in _bfd_set_section_content. */
+ abfd->output_has_begun = true;
+ break;
+ }
+
+ if (BFD_SEND (abfd, _bfd_set_section_contents,
+ (abfd, section, location, offset, count)))
+ {
+ abfd->output_has_begun = true;
+ return true;
+ }
+
+ return false;
+}
+
+/*
+FUNCTION
+ bfd_get_section_contents
+
+SYNOPSIS
+ boolean bfd_get_section_contents
+ (bfd *abfd, asection *section, PTR location,
+ file_ptr offset, bfd_size_type count);
+
+DESCRIPTION
+ Read data from @var{section} in BFD @var{abfd}
+ into memory starting at @var{location}. The data is read at an
+ offset of @var{offset} from the start of the input section,
+ and is read for @var{count} bytes.
+
+ If the contents of a constructor with the <<SEC_CONSTRUCTOR>>
+ flag set are requested or if the section does not have the
+ <<SEC_HAS_CONTENTS>> flag set, then the @var{location} is filled
+ with zeroes. If no errors occur, <<true>> is returned, else
+ <<false>>.
+
+
+
+*/
+boolean
+bfd_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ bfd_size_type sz;
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ memset (location, 0, (unsigned) count);
+ return true;
+ }
+
+ if (offset < 0)
+ {
+ bad_val:
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ /* Even if reloc_done is true, this function reads unrelocated
+ contents, so we want the raw size. */
+ sz = section->_raw_size;
+ if ((bfd_size_type) offset > sz || count > sz || offset + count > sz)
+ goto bad_val;
+
+ if (count == 0)
+ /* Don't bother. */
+ return true;
+
+ if ((section->flags & SEC_HAS_CONTENTS) == 0)
+ {
+ memset (location, 0, (unsigned) count);
+ return true;
+ }
+
+ if ((section->flags & SEC_IN_MEMORY) != 0)
+ {
+ memcpy (location, section->contents + offset, (size_t) count);
+ return true;
+ }
+
+ return BFD_SEND (abfd, _bfd_get_section_contents,
+ (abfd, section, location, offset, count));
+}
+
+/*
+FUNCTION
+ bfd_copy_private_section_data
+
+SYNOPSIS
+ boolean bfd_copy_private_section_data(bfd *ibfd, asection *isec, bfd *obfd, asection *osec);
+
+DESCRIPTION
+ Copy private section information from @var{isec} in the BFD
+ @var{ibfd} to the section @var{osec} in the BFD @var{obfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{osec}.
+
+.#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+. BFD_SEND (obfd, _bfd_copy_private_section_data, \
+. (ibfd, isection, obfd, osection))
+*/
+
+/*
+FUNCTION
+ _bfd_strip_section_from_output
+
+SYNOPSIS
+ void _bfd_strip_section_from_output
+ (asection *section);
+
+DESCRIPTION
+ Remove @var{section} from the output. If the output section becomes
+ empty, remove it from the output bfd.
+*/
+void
+_bfd_strip_section_from_output (s)
+ asection *s;
+{
+ asection **spp, *os;
+ struct bfd_link_order *p, *pp;
+
+ os = s->output_section;
+ for (p = os->link_order_head, pp = NULL; p != NULL; pp = p, p = p->next)
+ if (p->type == bfd_indirect_link_order
+ && p->u.indirect.section == s)
+ {
+ /* Excise the input section. */
+ if (pp)
+ pp->next = p->next;
+ else
+ os->link_order_head = p->next;
+ if (!p->next)
+ os->link_order_tail = pp;
+
+ if (!os->link_order_head)
+ {
+ /* Excise the output section. */
+ for (spp = &os->owner->sections; *spp; spp = &(*spp)->next)
+ if (*spp == os)
+ {
+ *spp = os->next;
+ os->owner->section_count--;
+ break;
+ }
+ }
+ break;
+ }
+}
diff --git a/bfd/som.c b/bfd/som.c
new file mode 100644
index 00000000000..b5786b51ed7
--- /dev/null
+++ b/bfd/som.c
@@ -0,0 +1,6264 @@
+/* bfd back-end for HP PA-RISC SOM objects.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) || defined(HOST_HPPAMPEIX)
+
+#include "libbfd.h"
+#include "som.h"
+
+#include <sys/param.h>
+#include <signal.h>
+#include <machine/reg.h>
+#include <sys/file.h>
+#include <ctype.h>
+
+/* Magic not defined in standard HP-UX header files until 8.0 */
+
+#ifndef CPU_PA_RISC1_0
+#define CPU_PA_RISC1_0 0x20B
+#endif /* CPU_PA_RISC1_0 */
+
+#ifndef CPU_PA_RISC1_1
+#define CPU_PA_RISC1_1 0x210
+#endif /* CPU_PA_RISC1_1 */
+
+#ifndef CPU_PA_RISC2_0
+#define CPU_PA_RISC2_0 0x214
+#endif /* CPU_PA_RISC2_0 */
+
+#ifndef _PA_RISC1_0_ID
+#define _PA_RISC1_0_ID CPU_PA_RISC1_0
+#endif /* _PA_RISC1_0_ID */
+
+#ifndef _PA_RISC1_1_ID
+#define _PA_RISC1_1_ID CPU_PA_RISC1_1
+#endif /* _PA_RISC1_1_ID */
+
+#ifndef _PA_RISC2_0_ID
+#define _PA_RISC2_0_ID CPU_PA_RISC2_0
+#endif /* _PA_RISC2_0_ID */
+
+#ifndef _PA_RISC_MAXID
+#define _PA_RISC_MAXID 0x2FF
+#endif /* _PA_RISC_MAXID */
+
+#ifndef _PA_RISC_ID
+#define _PA_RISC_ID(__m_num) \
+ (((__m_num) == _PA_RISC1_0_ID) || \
+ ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID))
+#endif /* _PA_RISC_ID */
+
+
+/* HIUX in it's infinite stupidity changed the names for several "well
+ known" constants. Work around such braindamage. Try the HPUX version
+ first, then the HIUX version, and finally provide a default. */
+#ifdef HPUX_AUX_ID
+#define EXEC_AUX_ID HPUX_AUX_ID
+#endif
+
+#if !defined (EXEC_AUX_ID) && defined (HIUX_AUX_ID)
+#define EXEC_AUX_ID HIUX_AUX_ID
+#endif
+
+#ifndef EXEC_AUX_ID
+#define EXEC_AUX_ID 0
+#endif
+
+/* Size (in chars) of the temporary buffers used during fixup and string
+ table writes. */
+
+#define SOM_TMP_BUFSIZE 8192
+
+/* Size of the hash table in archives. */
+#define SOM_LST_HASH_SIZE 31
+
+/* Max number of SOMs to be found in an archive. */
+#define SOM_LST_MODULE_LIMIT 1024
+
+/* Generic alignment macro. */
+#define SOM_ALIGN(val, alignment) \
+ (((val) + (alignment) - 1) & ~((alignment) - 1))
+
+/* SOM allows any one of the four previous relocations to be reused
+ with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP
+ relocations are always a single byte, using a R_PREV_FIXUP instead
+ of some multi-byte relocation makes object files smaller.
+
+ Note one side effect of using a R_PREV_FIXUP is the relocation that
+ is being repeated moves to the front of the queue. */
+struct reloc_queue
+ {
+ unsigned char *reloc;
+ unsigned int size;
+ } reloc_queue[4];
+
+/* This fully describes the symbol types which may be attached to
+ an EXPORT or IMPORT directive. Only SOM uses this formation
+ (ELF has no need for it). */
+typedef enum
+{
+ SYMBOL_TYPE_UNKNOWN,
+ SYMBOL_TYPE_ABSOLUTE,
+ SYMBOL_TYPE_CODE,
+ SYMBOL_TYPE_DATA,
+ SYMBOL_TYPE_ENTRY,
+ SYMBOL_TYPE_MILLICODE,
+ SYMBOL_TYPE_PLABEL,
+ SYMBOL_TYPE_PRI_PROG,
+ SYMBOL_TYPE_SEC_PROG,
+} pa_symbol_type;
+
+struct section_to_type
+{
+ char *section;
+ char type;
+};
+
+/* Assorted symbol information that needs to be derived from the BFD symbol
+ and/or the BFD backend private symbol data. */
+struct som_misc_symbol_info
+{
+ unsigned int symbol_type;
+ unsigned int symbol_scope;
+ unsigned int arg_reloc;
+ unsigned int symbol_info;
+ unsigned int symbol_value;
+ unsigned int priv_level;
+};
+
+/* Forward declarations */
+
+static boolean som_mkobject PARAMS ((bfd *));
+static const bfd_target * som_object_setup PARAMS ((bfd *,
+ struct header *,
+ struct som_exec_auxhdr *,
+ unsigned long));
+static boolean setup_sections PARAMS ((bfd *, struct header *, unsigned long));
+static const bfd_target * som_object_p PARAMS ((bfd *));
+static boolean som_write_object_contents PARAMS ((bfd *));
+static boolean som_slurp_string_table PARAMS ((bfd *));
+static unsigned int som_slurp_symbol_table PARAMS ((bfd *));
+static long som_get_symtab_upper_bound PARAMS ((bfd *));
+static long som_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
+ arelent **, asymbol **));
+static long som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
+static unsigned int som_set_reloc_info PARAMS ((unsigned char *, unsigned int,
+ arelent *, asection *,
+ asymbol **, boolean));
+static boolean som_slurp_reloc_table PARAMS ((bfd *, asection *,
+ asymbol **, boolean));
+static long som_get_symtab PARAMS ((bfd *, asymbol **));
+static asymbol * som_make_empty_symbol PARAMS ((bfd *));
+static void som_print_symbol PARAMS ((bfd *, PTR,
+ asymbol *, bfd_print_symbol_type));
+static boolean som_new_section_hook PARAMS ((bfd *, asection *));
+static boolean som_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *,
+ bfd *, asymbol *));
+static boolean som_bfd_copy_private_section_data PARAMS ((bfd *, asection *,
+ bfd *, asection *));
+static boolean som_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+static boolean som_bfd_is_local_label_name PARAMS ((bfd *, const char *));
+static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
+ file_ptr, bfd_size_type));
+static boolean som_get_section_contents PARAMS ((bfd *, sec_ptr, PTR,
+ file_ptr, bfd_size_type));
+static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
+ unsigned long));
+static boolean som_find_nearest_line PARAMS ((bfd *, asection *,
+ asymbol **, bfd_vma,
+ CONST char **,
+ CONST char **,
+ unsigned int *));
+static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static asection * bfd_section_from_som_symbol PARAMS ((bfd *,
+ struct symbol_dictionary_record *));
+static int log2 PARAMS ((unsigned int));
+static bfd_reloc_status_type hppa_som_reloc PARAMS ((bfd *, arelent *,
+ asymbol *, PTR,
+ asection *, bfd *,
+ char **));
+static void som_initialize_reloc_queue PARAMS ((struct reloc_queue *));
+static void som_reloc_queue_insert PARAMS ((unsigned char *, unsigned int,
+ struct reloc_queue *));
+static void som_reloc_queue_fix PARAMS ((struct reloc_queue *, unsigned int));
+static int som_reloc_queue_find PARAMS ((unsigned char *, unsigned int,
+ struct reloc_queue *));
+static unsigned char * try_prev_fixup PARAMS ((bfd *, int *, unsigned char *,
+ unsigned int,
+ struct reloc_queue *));
+
+static unsigned char * som_reloc_skip PARAMS ((bfd *, unsigned int,
+ unsigned char *, unsigned int *,
+ struct reloc_queue *));
+static unsigned char * som_reloc_addend PARAMS ((bfd *, int, unsigned char *,
+ unsigned int *,
+ struct reloc_queue *));
+static unsigned char * som_reloc_call PARAMS ((bfd *, unsigned char *,
+ unsigned int *,
+ arelent *, int,
+ struct reloc_queue *));
+static unsigned long som_count_spaces PARAMS ((bfd *));
+static unsigned long som_count_subspaces PARAMS ((bfd *));
+static int compare_syms PARAMS ((const void *, const void *));
+static int compare_subspaces PARAMS ((const void *, const void *));
+static unsigned long som_compute_checksum PARAMS ((bfd *));
+static boolean som_prep_headers PARAMS ((bfd *));
+static int som_sizeof_headers PARAMS ((bfd *, boolean));
+static boolean som_finish_writing PARAMS ((bfd *));
+static boolean som_build_and_write_symbol_table PARAMS ((bfd *));
+static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long));
+static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *));
+static boolean som_write_space_strings PARAMS ((bfd *, unsigned long,
+ unsigned int *));
+static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long,
+ asymbol **, unsigned int,
+ unsigned *,
+ COMPUNIT *));
+static boolean som_begin_writing PARAMS ((bfd *));
+static reloc_howto_type * som_bfd_reloc_type_lookup
+ PARAMS ((bfd *, bfd_reloc_code_real_type));
+static char som_section_type PARAMS ((const char *));
+static int som_decode_symclass PARAMS ((asymbol *));
+static boolean som_bfd_count_ar_symbols PARAMS ((bfd *, struct lst_header *,
+ symindex *));
+
+static boolean som_bfd_fill_in_ar_symbols PARAMS ((bfd *, struct lst_header *,
+ carsym **syms));
+static boolean som_slurp_armap PARAMS ((bfd *));
+static boolean som_write_armap PARAMS ((bfd *, unsigned int, struct orl *,
+ unsigned int, int));
+static void som_bfd_derive_misc_symbol_info PARAMS ((bfd *, asymbol *,
+ struct som_misc_symbol_info *));
+static boolean som_bfd_prep_for_ar_write PARAMS ((bfd *, unsigned int *,
+ unsigned int *));
+static unsigned int som_bfd_ar_symbol_hash PARAMS ((asymbol *));
+static boolean som_bfd_ar_write_symbol_stuff PARAMS ((bfd *, unsigned int,
+ unsigned int,
+ struct lst_header,
+ unsigned int));
+static boolean som_is_space PARAMS ((asection *));
+static boolean som_is_subspace PARAMS ((asection *));
+static boolean som_is_container PARAMS ((asection *, asection *));
+static boolean som_bfd_free_cached_info PARAMS ((bfd *));
+static boolean som_bfd_link_split_section PARAMS ((bfd *, asection *));
+
+/* Map SOM section names to POSIX/BSD single-character symbol types.
+
+ This table includes all the standard subspaces as defined in the
+ current "PRO ABI for PA-RISC Systems", $UNWIND$ which for
+ some reason was left out, and sections specific to embedded stabs. */
+
+static const struct section_to_type stt[] = {
+ {"$TEXT$", 't'},
+ {"$SHLIB_INFO$", 't'},
+ {"$MILLICODE$", 't'},
+ {"$LIT$", 't'},
+ {"$CODE$", 't'},
+ {"$UNWIND_START$", 't'},
+ {"$UNWIND$", 't'},
+ {"$PRIVATE$", 'd'},
+ {"$PLT$", 'd'},
+ {"$SHLIB_DATA$", 'd'},
+ {"$DATA$", 'd'},
+ {"$SHORTDATA$", 'g'},
+ {"$DLT$", 'd'},
+ {"$GLOBAL$", 'g'},
+ {"$SHORTBSS$", 's'},
+ {"$BSS$", 'b'},
+ {"$GDB_STRINGS$", 'N'},
+ {"$GDB_SYMBOLS$", 'N'},
+ {0, 0}
+};
+
+/* About the relocation formatting table...
+
+ There are 256 entries in the table, one for each possible
+ relocation opcode available in SOM. We index the table by
+ the relocation opcode. The names and operations are those
+ defined by a.out_800 (4).
+
+ Right now this table is only used to count and perform minimal
+ processing on relocation streams so that they can be internalized
+ into BFD and symbolically printed by utilities. To make actual use
+ of them would be much more difficult, BFD's concept of relocations
+ is far too simple to handle SOM relocations. The basic assumption
+ that a relocation can be completely processed independent of other
+ relocations before an object file is written is invalid for SOM.
+
+ The SOM relocations are meant to be processed as a stream, they
+ specify copying of data from the input section to the output section
+ while possibly modifying the data in some manner. They also can
+ specify that a variable number of zeros or uninitialized data be
+ inserted on in the output segment at the current offset. Some
+ relocations specify that some previous relocation be re-applied at
+ the current location in the input/output sections. And finally a number
+ of relocations have effects on other sections (R_ENTRY, R_EXIT,
+ R_UNWIND_AUX and a variety of others). There isn't even enough room
+ in the BFD relocation data structure to store enough information to
+ perform all the relocations.
+
+ Each entry in the table has three fields.
+
+ The first entry is an index into this "class" of relocations. This
+ index can then be used as a variable within the relocation itself.
+
+ The second field is a format string which actually controls processing
+ of the relocation. It uses a simple postfix machine to do calculations
+ based on variables/constants found in the string and the relocation
+ stream.
+
+ The third field specifys whether or not this relocation may use
+ a constant (V) from the previous R_DATA_OVERRIDE rather than a constant
+ stored in the instruction.
+
+ Variables:
+
+ L = input space byte count
+ D = index into class of relocations
+ M = output space byte count
+ N = statement number (unused?)
+ O = stack operation
+ R = parameter relocation bits
+ S = symbol index
+ T = first 32 bits of stack unwind information
+ U = second 32 bits of stack unwind information
+ V = a literal constant (usually used in the next relocation)
+ P = a previous relocation
+
+ Lower case letters (starting with 'b') refer to following
+ bytes in the relocation stream. 'b' is the next 1 byte,
+ c is the next 2 bytes, d is the next 3 bytes, etc...
+ This is the variable part of the relocation entries that
+ makes our life a living hell.
+
+ numerical constants are also used in the format string. Note
+ the constants are represented in decimal.
+
+ '+', "*" and "=" represents the obvious postfix operators.
+ '<' represents a left shift.
+
+ Stack Operations:
+
+ Parameter Relocation Bits:
+
+ Unwind Entries:
+
+ Previous Relocations: The index field represents which in the queue
+ of 4 previous fixups should be re-applied.
+
+ Literal Constants: These are generally used to represent addend
+ parts of relocations when these constants are not stored in the
+ fields of the instructions themselves. For example the instruction
+ addil foo-$global$-0x1234 would use an override for "0x1234" rather
+ than storing it into the addil itself. */
+
+struct fixup_format
+{
+ int D;
+ char *format;
+};
+
+static const struct fixup_format som_fixup_formats[256] =
+{
+ /* R_NO_RELOCATION */
+ 0, "LD1+4*=", /* 0x00 */
+ 1, "LD1+4*=", /* 0x01 */
+ 2, "LD1+4*=", /* 0x02 */
+ 3, "LD1+4*=", /* 0x03 */
+ 4, "LD1+4*=", /* 0x04 */
+ 5, "LD1+4*=", /* 0x05 */
+ 6, "LD1+4*=", /* 0x06 */
+ 7, "LD1+4*=", /* 0x07 */
+ 8, "LD1+4*=", /* 0x08 */
+ 9, "LD1+4*=", /* 0x09 */
+ 10, "LD1+4*=", /* 0x0a */
+ 11, "LD1+4*=", /* 0x0b */
+ 12, "LD1+4*=", /* 0x0c */
+ 13, "LD1+4*=", /* 0x0d */
+ 14, "LD1+4*=", /* 0x0e */
+ 15, "LD1+4*=", /* 0x0f */
+ 16, "LD1+4*=", /* 0x10 */
+ 17, "LD1+4*=", /* 0x11 */
+ 18, "LD1+4*=", /* 0x12 */
+ 19, "LD1+4*=", /* 0x13 */
+ 20, "LD1+4*=", /* 0x14 */
+ 21, "LD1+4*=", /* 0x15 */
+ 22, "LD1+4*=", /* 0x16 */
+ 23, "LD1+4*=", /* 0x17 */
+ 0, "LD8<b+1+4*=", /* 0x18 */
+ 1, "LD8<b+1+4*=", /* 0x19 */
+ 2, "LD8<b+1+4*=", /* 0x1a */
+ 3, "LD8<b+1+4*=", /* 0x1b */
+ 0, "LD16<c+1+4*=", /* 0x1c */
+ 1, "LD16<c+1+4*=", /* 0x1d */
+ 2, "LD16<c+1+4*=", /* 0x1e */
+ 0, "Ld1+=", /* 0x1f */
+ /* R_ZEROES */
+ 0, "Lb1+4*=", /* 0x20 */
+ 1, "Ld1+=", /* 0x21 */
+ /* R_UNINIT */
+ 0, "Lb1+4*=", /* 0x22 */
+ 1, "Ld1+=", /* 0x23 */
+ /* R_RELOCATION */
+ 0, "L4=", /* 0x24 */
+ /* R_DATA_ONE_SYMBOL */
+ 0, "L4=Sb=", /* 0x25 */
+ 1, "L4=Sd=", /* 0x26 */
+ /* R_DATA_PLEBEL */
+ 0, "L4=Sb=", /* 0x27 */
+ 1, "L4=Sd=", /* 0x28 */
+ /* R_SPACE_REF */
+ 0, "L4=", /* 0x29 */
+ /* R_REPEATED_INIT */
+ 0, "L4=Mb1+4*=", /* 0x2a */
+ 1, "Lb4*=Mb1+L*=", /* 0x2b */
+ 2, "Lb4*=Md1+4*=", /* 0x2c */
+ 3, "Ld1+=Me1+=", /* 0x2d */
+ /* R_SHORT_PCREL_MODE */
+ 0, "", /* 0x2e */
+ /* R_LONG_PCREL_MODE */
+ 0, "", /* 0x2f */
+ /* R_PCREL_CALL */
+ 0, "L4=RD=Sb=", /* 0x30 */
+ 1, "L4=RD=Sb=", /* 0x31 */
+ 2, "L4=RD=Sb=", /* 0x32 */
+ 3, "L4=RD=Sb=", /* 0x33 */
+ 4, "L4=RD=Sb=", /* 0x34 */
+ 5, "L4=RD=Sb=", /* 0x35 */
+ 6, "L4=RD=Sb=", /* 0x36 */
+ 7, "L4=RD=Sb=", /* 0x37 */
+ 8, "L4=RD=Sb=", /* 0x38 */
+ 9, "L4=RD=Sb=", /* 0x39 */
+ 0, "L4=RD8<b+=Sb=",/* 0x3a */
+ 1, "L4=RD8<b+=Sb=",/* 0x3b */
+ 0, "L4=RD8<b+=Sd=",/* 0x3c */
+ 1, "L4=RD8<b+=Sd=",/* 0x3d */
+ /* R_RESERVED */
+ 0, "", /* 0x3e */
+ 0, "", /* 0x3f */
+ /* R_ABS_CALL */
+ 0, "L4=RD=Sb=", /* 0x40 */
+ 1, "L4=RD=Sb=", /* 0x41 */
+ 2, "L4=RD=Sb=", /* 0x42 */
+ 3, "L4=RD=Sb=", /* 0x43 */
+ 4, "L4=RD=Sb=", /* 0x44 */
+ 5, "L4=RD=Sb=", /* 0x45 */
+ 6, "L4=RD=Sb=", /* 0x46 */
+ 7, "L4=RD=Sb=", /* 0x47 */
+ 8, "L4=RD=Sb=", /* 0x48 */
+ 9, "L4=RD=Sb=", /* 0x49 */
+ 0, "L4=RD8<b+=Sb=",/* 0x4a */
+ 1, "L4=RD8<b+=Sb=",/* 0x4b */
+ 0, "L4=RD8<b+=Sd=",/* 0x4c */
+ 1, "L4=RD8<b+=Sd=",/* 0x4d */
+ /* R_RESERVED */
+ 0, "", /* 0x4e */
+ 0, "", /* 0x4f */
+ /* R_DP_RELATIVE */
+ 0, "L4=SD=", /* 0x50 */
+ 1, "L4=SD=", /* 0x51 */
+ 2, "L4=SD=", /* 0x52 */
+ 3, "L4=SD=", /* 0x53 */
+ 4, "L4=SD=", /* 0x54 */
+ 5, "L4=SD=", /* 0x55 */
+ 6, "L4=SD=", /* 0x56 */
+ 7, "L4=SD=", /* 0x57 */
+ 8, "L4=SD=", /* 0x58 */
+ 9, "L4=SD=", /* 0x59 */
+ 10, "L4=SD=", /* 0x5a */
+ 11, "L4=SD=", /* 0x5b */
+ 12, "L4=SD=", /* 0x5c */
+ 13, "L4=SD=", /* 0x5d */
+ 14, "L4=SD=", /* 0x5e */
+ 15, "L4=SD=", /* 0x5f */
+ 16, "L4=SD=", /* 0x60 */
+ 17, "L4=SD=", /* 0x61 */
+ 18, "L4=SD=", /* 0x62 */
+ 19, "L4=SD=", /* 0x63 */
+ 20, "L4=SD=", /* 0x64 */
+ 21, "L4=SD=", /* 0x65 */
+ 22, "L4=SD=", /* 0x66 */
+ 23, "L4=SD=", /* 0x67 */
+ 24, "L4=SD=", /* 0x68 */
+ 25, "L4=SD=", /* 0x69 */
+ 26, "L4=SD=", /* 0x6a */
+ 27, "L4=SD=", /* 0x6b */
+ 28, "L4=SD=", /* 0x6c */
+ 29, "L4=SD=", /* 0x6d */
+ 30, "L4=SD=", /* 0x6e */
+ 31, "L4=SD=", /* 0x6f */
+ 32, "L4=Sb=", /* 0x70 */
+ 33, "L4=Sd=", /* 0x71 */
+ /* R_RESERVED */
+ 0, "", /* 0x72 */
+ 0, "", /* 0x73 */
+ 0, "", /* 0x74 */
+ 0, "", /* 0x75 */
+ 0, "", /* 0x76 */
+ 0, "", /* 0x77 */
+ /* R_DLT_REL */
+ 0, "L4=Sb=", /* 0x78 */
+ 1, "L4=Sd=", /* 0x79 */
+ /* R_RESERVED */
+ 0, "", /* 0x7a */
+ 0, "", /* 0x7b */
+ 0, "", /* 0x7c */
+ 0, "", /* 0x7d */
+ 0, "", /* 0x7e */
+ 0, "", /* 0x7f */
+ /* R_CODE_ONE_SYMBOL */
+ 0, "L4=SD=", /* 0x80 */
+ 1, "L4=SD=", /* 0x81 */
+ 2, "L4=SD=", /* 0x82 */
+ 3, "L4=SD=", /* 0x83 */
+ 4, "L4=SD=", /* 0x84 */
+ 5, "L4=SD=", /* 0x85 */
+ 6, "L4=SD=", /* 0x86 */
+ 7, "L4=SD=", /* 0x87 */
+ 8, "L4=SD=", /* 0x88 */
+ 9, "L4=SD=", /* 0x89 */
+ 10, "L4=SD=", /* 0x8q */
+ 11, "L4=SD=", /* 0x8b */
+ 12, "L4=SD=", /* 0x8c */
+ 13, "L4=SD=", /* 0x8d */
+ 14, "L4=SD=", /* 0x8e */
+ 15, "L4=SD=", /* 0x8f */
+ 16, "L4=SD=", /* 0x90 */
+ 17, "L4=SD=", /* 0x91 */
+ 18, "L4=SD=", /* 0x92 */
+ 19, "L4=SD=", /* 0x93 */
+ 20, "L4=SD=", /* 0x94 */
+ 21, "L4=SD=", /* 0x95 */
+ 22, "L4=SD=", /* 0x96 */
+ 23, "L4=SD=", /* 0x97 */
+ 24, "L4=SD=", /* 0x98 */
+ 25, "L4=SD=", /* 0x99 */
+ 26, "L4=SD=", /* 0x9a */
+ 27, "L4=SD=", /* 0x9b */
+ 28, "L4=SD=", /* 0x9c */
+ 29, "L4=SD=", /* 0x9d */
+ 30, "L4=SD=", /* 0x9e */
+ 31, "L4=SD=", /* 0x9f */
+ 32, "L4=Sb=", /* 0xa0 */
+ 33, "L4=Sd=", /* 0xa1 */
+ /* R_RESERVED */
+ 0, "", /* 0xa2 */
+ 0, "", /* 0xa3 */
+ 0, "", /* 0xa4 */
+ 0, "", /* 0xa5 */
+ 0, "", /* 0xa6 */
+ 0, "", /* 0xa7 */
+ 0, "", /* 0xa8 */
+ 0, "", /* 0xa9 */
+ 0, "", /* 0xaa */
+ 0, "", /* 0xab */
+ 0, "", /* 0xac */
+ 0, "", /* 0xad */
+ /* R_MILLI_REL */
+ 0, "L4=Sb=", /* 0xae */
+ 1, "L4=Sd=", /* 0xaf */
+ /* R_CODE_PLABEL */
+ 0, "L4=Sb=", /* 0xb0 */
+ 1, "L4=Sd=", /* 0xb1 */
+ /* R_BREAKPOINT */
+ 0, "L4=", /* 0xb2 */
+ /* R_ENTRY */
+ 0, "Te=Ue=", /* 0xb3 */
+ 1, "Uf=", /* 0xb4 */
+ /* R_ALT_ENTRY */
+ 0, "", /* 0xb5 */
+ /* R_EXIT */
+ 0, "", /* 0xb6 */
+ /* R_BEGIN_TRY */
+ 0, "", /* 0xb7 */
+ /* R_END_TRY */
+ 0, "R0=", /* 0xb8 */
+ 1, "Rb4*=", /* 0xb9 */
+ 2, "Rd4*=", /* 0xba */
+ /* R_BEGIN_BRTAB */
+ 0, "", /* 0xbb */
+ /* R_END_BRTAB */
+ 0, "", /* 0xbc */
+ /* R_STATEMENT */
+ 0, "Nb=", /* 0xbd */
+ 1, "Nc=", /* 0xbe */
+ 2, "Nd=", /* 0xbf */
+ /* R_DATA_EXPR */
+ 0, "L4=", /* 0xc0 */
+ /* R_CODE_EXPR */
+ 0, "L4=", /* 0xc1 */
+ /* R_FSEL */
+ 0, "", /* 0xc2 */
+ /* R_LSEL */
+ 0, "", /* 0xc3 */
+ /* R_RSEL */
+ 0, "", /* 0xc4 */
+ /* R_N_MODE */
+ 0, "", /* 0xc5 */
+ /* R_S_MODE */
+ 0, "", /* 0xc6 */
+ /* R_D_MODE */
+ 0, "", /* 0xc7 */
+ /* R_R_MODE */
+ 0, "", /* 0xc8 */
+ /* R_DATA_OVERRIDE */
+ 0, "V0=", /* 0xc9 */
+ 1, "Vb=", /* 0xca */
+ 2, "Vc=", /* 0xcb */
+ 3, "Vd=", /* 0xcc */
+ 4, "Ve=", /* 0xcd */
+ /* R_TRANSLATED */
+ 0, "", /* 0xce */
+ /* R_RESERVED */
+ 0, "", /* 0xcf */
+ /* R_COMP1 */
+ 0, "Ob=", /* 0xd0 */
+ /* R_COMP2 */
+ 0, "Ob=Sd=", /* 0xd1 */
+ /* R_COMP3 */
+ 0, "Ob=Ve=", /* 0xd2 */
+ /* R_PREV_FIXUP */
+ 0, "P", /* 0xd3 */
+ 1, "P", /* 0xd4 */
+ 2, "P", /* 0xd5 */
+ 3, "P", /* 0xd6 */
+ /* R_SEC_STMT */
+ 0, "", /* 0xd7 */
+ /* R_N0SEL */
+ 0, "", /* 0xd8 */
+ /* R_N1SEL */
+ 0, "", /* 0xd9 */
+ /* R_LINETAB */
+ 0, "", /* 0xda */
+ /* R_LINETAB_ESC */
+ 0, "", /* 0xdb */
+ /* R_LTP_OVERRIDE */
+ 0, "", /* 0xdc */
+ /* R_COMMENT */
+ 0, "", /* 0xdd */
+ /* R_RESERVED */
+ 0, "", /* 0xde */
+ 0, "", /* 0xdf */
+ 0, "", /* 0xe0 */
+ 0, "", /* 0xe1 */
+ 0, "", /* 0xe2 */
+ 0, "", /* 0xe3 */
+ 0, "", /* 0xe4 */
+ 0, "", /* 0xe5 */
+ 0, "", /* 0xe6 */
+ 0, "", /* 0xe7 */
+ 0, "", /* 0xe8 */
+ 0, "", /* 0xe9 */
+ 0, "", /* 0xea */
+ 0, "", /* 0xeb */
+ 0, "", /* 0xec */
+ 0, "", /* 0xed */
+ 0, "", /* 0xee */
+ 0, "", /* 0xef */
+ 0, "", /* 0xf0 */
+ 0, "", /* 0xf1 */
+ 0, "", /* 0xf2 */
+ 0, "", /* 0xf3 */
+ 0, "", /* 0xf4 */
+ 0, "", /* 0xf5 */
+ 0, "", /* 0xf6 */
+ 0, "", /* 0xf7 */
+ 0, "", /* 0xf8 */
+ 0, "", /* 0xf9 */
+ 0, "", /* 0xfa */
+ 0, "", /* 0xfb */
+ 0, "", /* 0xfc */
+ 0, "", /* 0xfd */
+ 0, "", /* 0xfe */
+ 0, "", /* 0xff */
+};
+
+static const int comp1_opcodes[] =
+{
+ 0x00,
+ 0x40,
+ 0x41,
+ 0x42,
+ 0x43,
+ 0x44,
+ 0x45,
+ 0x46,
+ 0x47,
+ 0x48,
+ 0x49,
+ 0x4a,
+ 0x4b,
+ 0x60,
+ 0x80,
+ 0xa0,
+ 0xc0,
+ -1
+};
+
+static const int comp2_opcodes[] =
+{
+ 0x00,
+ 0x80,
+ 0x82,
+ 0xc0,
+ -1
+};
+
+static const int comp3_opcodes[] =
+{
+ 0x00,
+ 0x02,
+ -1
+};
+
+/* These apparently are not in older versions of hpux reloc.h (hpux7). */
+#ifndef R_DLT_REL
+#define R_DLT_REL 0x78
+#endif
+
+#ifndef R_AUX_UNWIND
+#define R_AUX_UNWIND 0xcf
+#endif
+
+#ifndef R_SEC_STMT
+#define R_SEC_STMT 0xd7
+#endif
+
+/* And these first appeared in hpux10. */
+#ifndef R_SHORT_PCREL_MODE
+#define R_SHORT_PCREL_MODE 0x3e
+#endif
+
+#ifndef R_LONG_PCREL_MODE
+#define R_LONG_PCREL_MODE 0x3f
+#endif
+
+#ifndef R_N0SEL
+#define R_N0SEL 0xd8
+#endif
+
+#ifndef R_N1SEL
+#define R_N1SEL 0xd9
+#endif
+
+#ifndef R_LINETAB
+#define R_LINETAB 0xda
+#endif
+
+#ifndef R_LINETAB_ESC
+#define R_LINETAB_ESC 0xdb
+#endif
+
+#ifndef R_LTP_OVERRIDE
+#define R_LTP_OVERRIDE 0xdc
+#endif
+
+#ifndef R_COMMENT
+#define R_COMMENT 0xdd
+#endif
+
+static reloc_howto_type som_hppa_howto_table[] =
+{
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"},
+ {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"},
+ {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"},
+ {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"},
+ {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"},
+ {R_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RELOCATION"},
+ {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"},
+ {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"},
+ {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"},
+ {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"},
+ {R_SPACE_REF, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SPACE_REF"},
+ {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
+ {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
+ {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
+ {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"},
+ {R_SHORT_PCREL_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SHORT_PCREL_MODE"},
+ {R_LONG_PCREL_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LONG_PCREL_MODE"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_DLT_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DLT_REL"},
+ {R_DLT_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DLT_REL"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"},
+ {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"},
+ {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"},
+ {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"},
+ {R_BREAKPOINT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BREAKPOINT"},
+ {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"},
+ {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"},
+ {R_ALT_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ALT_ENTRY"},
+ {R_EXIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_EXIT"},
+ {R_BEGIN_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_TRY"},
+ {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
+ {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
+ {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"},
+ {R_BEGIN_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_BRTAB"},
+ {R_END_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_BRTAB"},
+ {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
+ {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
+ {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"},
+ {R_DATA_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_EXPR"},
+ {R_CODE_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_EXPR"},
+ {R_FSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_FSEL"},
+ {R_LSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LSEL"},
+ {R_RSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RSEL"},
+ {R_N_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N_MODE"},
+ {R_S_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_S_MODE"},
+ {R_D_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_D_MODE"},
+ {R_R_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_R_MODE"},
+ {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
+ {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
+ {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
+ {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
+ {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"},
+ {R_TRANSLATED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_TRANSLATED"},
+ {R_AUX_UNWIND, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_AUX_UNWIND"},
+ {R_COMP1, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP1"},
+ {R_COMP2, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP2"},
+ {R_COMP3, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP3"},
+ {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
+ {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
+ {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
+ {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"},
+ {R_SEC_STMT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SEC_STMT"},
+ {R_N0SEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N0SEL"},
+ {R_N1SEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N1SEL"},
+ {R_LINETAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LINETAB"},
+ {R_LINETAB_ESC, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LINETAB_ESC"},
+ {R_LTP_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LTP_OVERRIDE"},
+ {R_COMMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMMENT"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"},
+ {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}};
+
+/* Initialize the SOM relocation queue. By definition the queue holds
+ the last four multibyte fixups. */
+
+static void
+som_initialize_reloc_queue (queue)
+ struct reloc_queue *queue;
+{
+ queue[0].reloc = NULL;
+ queue[0].size = 0;
+ queue[1].reloc = NULL;
+ queue[1].size = 0;
+ queue[2].reloc = NULL;
+ queue[2].size = 0;
+ queue[3].reloc = NULL;
+ queue[3].size = 0;
+}
+
+/* Insert a new relocation into the relocation queue. */
+
+static void
+som_reloc_queue_insert (p, size, queue)
+ unsigned char *p;
+ unsigned int size;
+ struct reloc_queue *queue;
+{
+ queue[3].reloc = queue[2].reloc;
+ queue[3].size = queue[2].size;
+ queue[2].reloc = queue[1].reloc;
+ queue[2].size = queue[1].size;
+ queue[1].reloc = queue[0].reloc;
+ queue[1].size = queue[0].size;
+ queue[0].reloc = p;
+ queue[0].size = size;
+}
+
+/* When an entry in the relocation queue is reused, the entry moves
+ to the front of the queue. */
+
+static void
+som_reloc_queue_fix (queue, index)
+ struct reloc_queue *queue;
+ unsigned int index;
+{
+ if (index == 0)
+ return;
+
+ if (index == 1)
+ {
+ unsigned char *tmp1 = queue[0].reloc;
+ unsigned int tmp2 = queue[0].size;
+ queue[0].reloc = queue[1].reloc;
+ queue[0].size = queue[1].size;
+ queue[1].reloc = tmp1;
+ queue[1].size = tmp2;
+ return;
+ }
+
+ if (index == 2)
+ {
+ unsigned char *tmp1 = queue[0].reloc;
+ unsigned int tmp2 = queue[0].size;
+ queue[0].reloc = queue[2].reloc;
+ queue[0].size = queue[2].size;
+ queue[2].reloc = queue[1].reloc;
+ queue[2].size = queue[1].size;
+ queue[1].reloc = tmp1;
+ queue[1].size = tmp2;
+ return;
+ }
+
+ if (index == 3)
+ {
+ unsigned char *tmp1 = queue[0].reloc;
+ unsigned int tmp2 = queue[0].size;
+ queue[0].reloc = queue[3].reloc;
+ queue[0].size = queue[3].size;
+ queue[3].reloc = queue[2].reloc;
+ queue[3].size = queue[2].size;
+ queue[2].reloc = queue[1].reloc;
+ queue[2].size = queue[1].size;
+ queue[1].reloc = tmp1;
+ queue[1].size = tmp2;
+ return;
+ }
+ abort();
+}
+
+/* Search for a particular relocation in the relocation queue. */
+
+static int
+som_reloc_queue_find (p, size, queue)
+ unsigned char *p;
+ unsigned int size;
+ struct reloc_queue *queue;
+{
+ if (queue[0].reloc && !memcmp (p, queue[0].reloc, size)
+ && size == queue[0].size)
+ return 0;
+ if (queue[1].reloc && !memcmp (p, queue[1].reloc, size)
+ && size == queue[1].size)
+ return 1;
+ if (queue[2].reloc && !memcmp (p, queue[2].reloc, size)
+ && size == queue[2].size)
+ return 2;
+ if (queue[3].reloc && !memcmp (p, queue[3].reloc, size)
+ && size == queue[3].size)
+ return 3;
+ return -1;
+}
+
+static unsigned char *
+try_prev_fixup (abfd, subspace_reloc_sizep, p, size, queue)
+ bfd *abfd;
+ int *subspace_reloc_sizep;
+ unsigned char *p;
+ unsigned int size;
+ struct reloc_queue *queue;
+{
+ int queue_index = som_reloc_queue_find (p, size, queue);
+
+ if (queue_index != -1)
+ {
+ /* Found this in a previous fixup. Undo the fixup we
+ just built and use R_PREV_FIXUP instead. We saved
+ a total of size - 1 bytes in the fixup stream. */
+ bfd_put_8 (abfd, R_PREV_FIXUP + queue_index, p);
+ p += 1;
+ *subspace_reloc_sizep += 1;
+ som_reloc_queue_fix (queue, queue_index);
+ }
+ else
+ {
+ som_reloc_queue_insert (p, size, queue);
+ *subspace_reloc_sizep += size;
+ p += size;
+ }
+ return p;
+}
+
+/* Emit the proper R_NO_RELOCATION fixups to map the next SKIP
+ bytes without any relocation. Update the size of the subspace
+ relocation stream via SUBSPACE_RELOC_SIZE_P; also return the
+ current pointer into the relocation stream. */
+
+static unsigned char *
+som_reloc_skip (abfd, skip, p, subspace_reloc_sizep, queue)
+ bfd *abfd;
+ unsigned int skip;
+ unsigned char *p;
+ unsigned int *subspace_reloc_sizep;
+ struct reloc_queue *queue;
+{
+ /* Use a 4 byte R_NO_RELOCATION entry with a maximal value
+ then R_PREV_FIXUPs to get the difference down to a
+ reasonable size. */
+ if (skip >= 0x1000000)
+ {
+ skip -= 0x1000000;
+ bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
+ bfd_put_8 (abfd, 0xff, p + 1);
+ bfd_put_16 (abfd, 0xffff, p + 2);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
+ while (skip >= 0x1000000)
+ {
+ skip -= 0x1000000;
+ bfd_put_8 (abfd, R_PREV_FIXUP, p);
+ p++;
+ *subspace_reloc_sizep += 1;
+ /* No need to adjust queue here since we are repeating the
+ most recent fixup. */
+ }
+ }
+
+ /* The difference must be less than 0x1000000. Use one
+ more R_NO_RELOCATION entry to get to the right difference. */
+ if ((skip & 3) == 0 && skip <= 0xc0000 && skip > 0)
+ {
+ /* Difference can be handled in a simple single-byte
+ R_NO_RELOCATION entry. */
+ if (skip <= 0x60)
+ {
+ bfd_put_8 (abfd, R_NO_RELOCATION + (skip >> 2) - 1, p);
+ *subspace_reloc_sizep += 1;
+ p++;
+ }
+ /* Handle it with a two byte R_NO_RELOCATION entry. */
+ else if (skip <= 0x1000)
+ {
+ bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p);
+ bfd_put_8 (abfd, (skip >> 2) - 1, p + 1);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
+ }
+ /* Handle it with a three byte R_NO_RELOCATION entry. */
+ else
+ {
+ bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p);
+ bfd_put_16 (abfd, (skip >> 2) - 1, p + 1);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
+ }
+ }
+ /* Ugh. Punt and use a 4 byte entry. */
+ else if (skip > 0)
+ {
+ bfd_put_8 (abfd, R_NO_RELOCATION + 31, p);
+ bfd_put_8 (abfd, (skip - 1) >> 16, p + 1);
+ bfd_put_16 (abfd, skip - 1, p + 2);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
+ }
+ return p;
+}
+
+/* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend
+ from a BFD relocation. Update the size of the subspace relocation
+ stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer
+ into the relocation stream. */
+
+static unsigned char *
+som_reloc_addend (abfd, addend, p, subspace_reloc_sizep, queue)
+ bfd *abfd;
+ int addend;
+ unsigned char *p;
+ unsigned int *subspace_reloc_sizep;
+ struct reloc_queue *queue;
+{
+ if ((unsigned)(addend) + 0x80 < 0x100)
+ {
+ bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p);
+ bfd_put_8 (abfd, addend, p + 1);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
+ }
+ else if ((unsigned) (addend) + 0x8000 < 0x10000)
+ {
+ bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p);
+ bfd_put_16 (abfd, addend, p + 1);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
+ }
+ else if ((unsigned) (addend) + 0x800000 < 0x1000000)
+ {
+ bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p);
+ bfd_put_8 (abfd, addend >> 16, p + 1);
+ bfd_put_16 (abfd, addend, p + 2);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue);
+ }
+ else
+ {
+ bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p);
+ bfd_put_32 (abfd, addend, p + 1);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
+ }
+ return p;
+}
+
+/* Handle a single function call relocation. */
+
+static unsigned char *
+som_reloc_call (abfd, p, subspace_reloc_sizep, bfd_reloc, sym_num, queue)
+ bfd *abfd;
+ unsigned char *p;
+ unsigned int *subspace_reloc_sizep;
+ arelent *bfd_reloc;
+ int sym_num;
+ struct reloc_queue *queue;
+{
+ int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend);
+ int rtn_bits = arg_bits & 0x3;
+ int type, done = 0;
+
+ /* You'll never believe all this is necessary to handle relocations
+ for function calls. Having to compute and pack the argument
+ relocation bits is the real nightmare.
+
+ If you're interested in how this works, just forget it. You really
+ do not want to know about this braindamage. */
+
+ /* First see if this can be done with a "simple" relocation. Simple
+ relocations have a symbol number < 0x100 and have simple encodings
+ of argument relocations. */
+
+ if (sym_num < 0x100)
+ {
+ switch (arg_bits)
+ {
+ case 0:
+ case 1:
+ type = 0;
+ break;
+ case 1 << 8:
+ case 1 << 8 | 1:
+ type = 1;
+ break;
+ case 1 << 8 | 1 << 6:
+ case 1 << 8 | 1 << 6 | 1:
+ type = 2;
+ break;
+ case 1 << 8 | 1 << 6 | 1 << 4:
+ case 1 << 8 | 1 << 6 | 1 << 4 | 1:
+ type = 3;
+ break;
+ case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2:
+ case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1:
+ type = 4;
+ break;
+ default:
+ /* Not one of the easy encodings. This will have to be
+ handled by the more complex code below. */
+ type = -1;
+ break;
+ }
+ if (type != -1)
+ {
+ /* Account for the return value too. */
+ if (rtn_bits)
+ type += 5;
+
+ /* Emit a 2 byte relocation. Then see if it can be handled
+ with a relocation which is already in the relocation queue. */
+ bfd_put_8 (abfd, bfd_reloc->howto->type + type, p);
+ bfd_put_8 (abfd, sym_num, p + 1);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue);
+ done = 1;
+ }
+ }
+
+ /* If this could not be handled with a simple relocation, then do a hard
+ one. Hard relocations occur if the symbol number was too high or if
+ the encoding of argument relocation bits is too complex. */
+ if (! done)
+ {
+ /* Don't ask about these magic sequences. I took them straight
+ from gas-1.36 which took them from the a.out man page. */
+ type = rtn_bits;
+ if ((arg_bits >> 6 & 0xf) == 0xe)
+ type += 9 * 40;
+ else
+ type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40;
+ if ((arg_bits >> 2 & 0xf) == 0xe)
+ type += 9 * 4;
+ else
+ type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4;
+
+ /* Output the first two bytes of the relocation. These describe
+ the length of the relocation and encoding style. */
+ bfd_put_8 (abfd, bfd_reloc->howto->type + 10
+ + 2 * (sym_num >= 0x100) + (type >= 0x100),
+ p);
+ bfd_put_8 (abfd, type, p + 1);
+
+ /* Now output the symbol index and see if this bizarre relocation
+ just happened to be in the relocation queue. */
+ if (sym_num < 0x100)
+ {
+ bfd_put_8 (abfd, sym_num, p + 2);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue);
+ }
+ else
+ {
+ bfd_put_8 (abfd, sym_num >> 16, p + 2);
+ bfd_put_16 (abfd, sym_num, p + 3);
+ p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue);
+ }
+ }
+ return p;
+}
+
+
+/* Return the logarithm of X, base 2, considering X unsigned.
+ Abort -1 if X is not a power or two or is zero. */
+
+static int
+log2 (x)
+ unsigned int x;
+{
+ int log = 0;
+
+ /* Test for 0 or a power of 2. */
+ if (x == 0 || x != (x & -x))
+ return -1;
+
+ while ((x >>= 1) != 0)
+ log++;
+ return log;
+}
+
+static bfd_reloc_status_type
+hppa_som_reloc (abfd, reloc_entry, symbol_in, data,
+ input_section, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc_entry;
+ asymbol *symbol_in;
+ PTR data;
+ asection *input_section;
+ bfd *output_bfd;
+ char **error_message;
+{
+ if (output_bfd)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+ return bfd_reloc_ok;
+}
+
+/* Given a generic HPPA relocation type, the instruction format,
+ and a field selector, return one or more appropriate SOM relocations. */
+
+int **
+hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff, sym)
+ bfd *abfd;
+ int base_type;
+ int format;
+ enum hppa_reloc_field_selector_type_alt field;
+ int sym_diff;
+ asymbol *sym;
+{
+ int *final_type, **final_types;
+
+ final_types = (int **) bfd_alloc (abfd, sizeof (int *) * 6);
+ final_type = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types || !final_type)
+ return NULL;
+
+ /* The field selector may require additional relocations to be
+ generated. It's impossible to know at this moment if additional
+ relocations will be needed, so we make them. The code to actually
+ write the relocation/fixup stream is responsible for removing
+ any redundant relocations. */
+ switch (field)
+ {
+ case e_fsel:
+ case e_psel:
+ case e_lpsel:
+ case e_rpsel:
+ final_types[0] = final_type;
+ final_types[1] = NULL;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_tsel:
+ case e_ltsel:
+ case e_rtsel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ if (field == e_tsel)
+ *final_types[0] = R_FSEL;
+ else if (field == e_ltsel)
+ *final_types[0] = R_LSEL;
+ else
+ *final_types[0] = R_RSEL;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_lssel:
+ case e_rssel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_S_MODE;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_lsel:
+ case e_rsel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_N_MODE;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_ldsel:
+ case e_rdsel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_D_MODE;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_lrsel:
+ case e_rrsel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_R_MODE;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_nsel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_N1SEL;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
+ case e_nlsel:
+ case e_nlrsel:
+ final_types[0] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_N0SEL;
+ final_types[1] = (int *) bfd_alloc (abfd, sizeof (int));
+ if (!final_types[1])
+ return NULL;
+ if (field == e_nlsel)
+ *final_types[1] = R_N_MODE;
+ else
+ *final_types[1] = R_R_MODE;
+ final_types[2] = final_type;
+ final_types[3] = NULL;
+ *final_type = base_type;
+ break;
+ }
+
+ switch (base_type)
+ {
+ case R_HPPA:
+ /* The difference of two symbols needs *very* special handling. */
+ if (sym_diff)
+ {
+ final_types[0] = (int *)bfd_alloc (abfd, sizeof (int));
+ final_types[1] = (int *)bfd_alloc (abfd, sizeof (int));
+ final_types[2] = (int *)bfd_alloc (abfd, sizeof (int));
+ final_types[3] = (int *)bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0] || !final_types[1] || !final_types[2])
+ return NULL;
+ if (field == e_fsel)
+ *final_types[0] = R_FSEL;
+ else if (field == e_rsel)
+ *final_types[0] = R_RSEL;
+ else if (field == e_lsel)
+ *final_types[0] = R_LSEL;
+ *final_types[1] = R_COMP2;
+ *final_types[2] = R_COMP2;
+ *final_types[3] = R_COMP1;
+ final_types[4] = final_type;
+ if (format == 32)
+ *final_types[4] = R_DATA_EXPR;
+ else
+ *final_types[4] = R_CODE_EXPR;
+ final_types[5] = NULL;
+ break;
+ }
+ /* PLABELs get their own relocation type. */
+ else if (field == e_psel
+ || field == e_lpsel
+ || field == e_rpsel)
+ {
+ /* A PLABEL relocation that has a size of 32 bits must
+ be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */
+ if (format == 32)
+ *final_type = R_DATA_PLABEL;
+ else
+ *final_type = R_CODE_PLABEL;
+ }
+ /* PIC stuff. */
+ else if (field == e_tsel
+ || field == e_ltsel
+ || field == e_rtsel)
+ *final_type = R_DLT_REL;
+ /* A relocation in the data space is always a full 32bits. */
+ else if (format == 32)
+ {
+ *final_type = R_DATA_ONE_SYMBOL;
+
+ /* If there's no SOM symbol type associated with this BFD
+ symbol, then set the symbol type to ST_DATA.
+
+ Only do this if the type is going to default later when
+ we write the object file.
+
+ This is done so that the linker never encounters an
+ R_DATA_ONE_SYMBOL reloc involving an ST_CODE symbol.
+
+ This allows the compiler to generate exception handling
+ tables.
+
+ Note that one day we may need to also emit BEGIN_BRTAB and
+ END_BRTAB to prevent the linker from optimizing away insns
+ in exception handling regions. */
+ if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
+ && (sym->flags & BSF_SECTION_SYM) == 0
+ && (sym->flags & BSF_FUNCTION) == 0
+ && ! bfd_is_com_section (sym->section))
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
+ }
+ break;
+
+
+ case R_HPPA_GOTOFF:
+ /* More PLABEL special cases. */
+ if (field == e_psel
+ || field == e_lpsel
+ || field == e_rpsel)
+ *final_type = R_DATA_PLABEL;
+ break;
+
+ case R_HPPA_COMPLEX:
+ /* The difference of two symbols needs *very* special handling. */
+ if (sym_diff)
+ {
+ final_types[0] = (int *)bfd_alloc (abfd, sizeof (int));
+ final_types[1] = (int *)bfd_alloc (abfd, sizeof (int));
+ final_types[2] = (int *)bfd_alloc (abfd, sizeof (int));
+ final_types[3] = (int *)bfd_alloc (abfd, sizeof (int));
+ if (!final_types[0] || !final_types[1] || !final_types[2])
+ return NULL;
+ if (field == e_fsel)
+ *final_types[0] = R_FSEL;
+ else if (field == e_rsel)
+ *final_types[0] = R_RSEL;
+ else if (field == e_lsel)
+ *final_types[0] = R_LSEL;
+ *final_types[1] = R_COMP2;
+ *final_types[2] = R_COMP2;
+ *final_types[3] = R_COMP1;
+ final_types[4] = final_type;
+ if (format == 32)
+ *final_types[4] = R_DATA_EXPR;
+ else
+ *final_types[4] = R_CODE_EXPR;
+ final_types[5] = NULL;
+ break;
+ }
+ else
+ break;
+
+ case R_HPPA_NONE:
+ case R_HPPA_ABS_CALL:
+ case R_HPPA_PCREL_CALL:
+ /* Right now we can default all these. */
+ break;
+ }
+ return final_types;
+}
+
+/* Return the address of the correct entry in the PA SOM relocation
+ howto table. */
+
+/*ARGSUSED*/
+static reloc_howto_type *
+som_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ if ((int) code < (int) R_NO_RELOCATION + 255)
+ {
+ BFD_ASSERT ((int) som_hppa_howto_table[(int) code].type == (int) code);
+ return &som_hppa_howto_table[(int) code];
+ }
+
+ return (reloc_howto_type *) 0;
+}
+
+/* Perform some initialization for an object. Save results of this
+ initialization in the BFD. */
+
+static const bfd_target *
+som_object_setup (abfd, file_hdrp, aux_hdrp, current_offset)
+ bfd *abfd;
+ struct header *file_hdrp;
+ struct som_exec_auxhdr *aux_hdrp;
+ unsigned long current_offset;
+{
+ asection *section;
+ int found;
+
+ /* som_mkobject will set bfd_error if som_mkobject fails. */
+ if (som_mkobject (abfd) != true)
+ return 0;
+
+ /* Set BFD flags based on what information is available in the SOM. */
+ abfd->flags = BFD_NO_FLAGS;
+ if (file_hdrp->symbol_total)
+ abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
+
+ switch (file_hdrp->a_magic)
+ {
+ case DEMAND_MAGIC:
+ abfd->flags |= (D_PAGED | WP_TEXT | EXEC_P);
+ break;
+ case SHARE_MAGIC:
+ abfd->flags |= (WP_TEXT | EXEC_P);
+ break;
+ case EXEC_MAGIC:
+ abfd->flags |= (EXEC_P);
+ break;
+ case RELOC_MAGIC:
+ abfd->flags |= HAS_RELOC;
+ break;
+#ifdef SHL_MAGIC
+ case SHL_MAGIC:
+#endif
+#ifdef DL_MAGIC
+ case DL_MAGIC:
+#endif
+ abfd->flags |= DYNAMIC;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Allocate space to hold the saved exec header information. */
+ obj_som_exec_data (abfd) = (struct som_exec_data *)
+ bfd_zalloc (abfd, sizeof (struct som_exec_data ));
+ if (obj_som_exec_data (abfd) == NULL)
+ return NULL;
+
+ /* The braindamaged OSF1 linker switched exec_flags and exec_entry!
+
+ We used to identify OSF1 binaries based on NEW_VERSION_ID, but
+ apparently the latest HPUX linker is using NEW_VERSION_ID now.
+
+ It's about time, OSF has used the new id since at least 1992;
+ HPUX didn't start till nearly 1995!.
+
+ The new approach examines the entry field. If it's zero or not 4
+ byte aligned then it's not a proper code address and we guess it's
+ really the executable flags. */
+ found = 0;
+ for (section = abfd->sections; section; section = section->next)
+ {
+ if ((section->flags & SEC_CODE) == 0)
+ continue;
+ if (aux_hdrp->exec_entry >= section->vma
+ && aux_hdrp->exec_entry < section->vma + section->_cooked_size)
+ found = 1;
+ }
+ if (aux_hdrp->exec_entry == 0
+ || (aux_hdrp->exec_entry & 0x3) != 0
+ || ! found)
+ {
+ bfd_get_start_address (abfd) = aux_hdrp->exec_flags;
+ obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry;
+ }
+ else
+ {
+ bfd_get_start_address (abfd) = aux_hdrp->exec_entry + current_offset;
+ obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags;
+ }
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_hppa, pa10);
+ bfd_get_symcount (abfd) = file_hdrp->symbol_total;
+
+ /* Initialize the saved symbol table and string table to NULL.
+ Save important offsets and sizes from the SOM header into
+ the BFD. */
+ obj_som_stringtab (abfd) = (char *) NULL;
+ obj_som_symtab (abfd) = (som_symbol_type *) NULL;
+ obj_som_sorted_syms (abfd) = NULL;
+ obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size;
+ obj_som_sym_filepos (abfd) = file_hdrp->symbol_location + current_offset;
+ obj_som_str_filepos (abfd) = (file_hdrp->symbol_strings_location
+ + current_offset);
+ obj_som_reloc_filepos (abfd) = (file_hdrp->fixup_request_location
+ + current_offset);
+ obj_som_exec_data (abfd)->system_id = file_hdrp->system_id;
+
+ return abfd->xvec;
+}
+
+/* Convert all of the space and subspace info into BFD sections. Each space
+ contains a number of subspaces, which in turn describe the mapping between
+ regions of the exec file, and the address space that the program runs in.
+ BFD sections which correspond to spaces will overlap the sections for the
+ associated subspaces. */
+
+static boolean
+setup_sections (abfd, file_hdr, current_offset)
+ bfd *abfd;
+ struct header *file_hdr;
+ unsigned long current_offset;
+{
+ char *space_strings;
+ unsigned int space_index, i;
+ unsigned int total_subspaces = 0;
+ asection **subspace_sections, *section;
+
+ /* First, read in space names */
+
+ space_strings = bfd_malloc (file_hdr->space_strings_size);
+ if (!space_strings && file_hdr->space_strings_size != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location,
+ SEEK_SET) < 0)
+ goto error_return;
+ if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd)
+ != file_hdr->space_strings_size)
+ goto error_return;
+
+ /* Loop over all of the space dictionaries, building up sections */
+ for (space_index = 0; space_index < file_hdr->space_total; space_index++)
+ {
+ struct space_dictionary_record space;
+ struct subspace_dictionary_record subspace, save_subspace;
+ int subspace_index;
+ asection *space_asect;
+ char *newname;
+
+ /* Read the space dictionary element */
+ if (bfd_seek (abfd,
+ (current_offset + file_hdr->space_location
+ + space_index * sizeof space),
+ SEEK_SET) < 0)
+ goto error_return;
+ if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space)
+ goto error_return;
+
+ /* Setup the space name string */
+ space.name.n_name = space.name.n_strx + space_strings;
+
+ /* Make a section out of it */
+ newname = bfd_alloc (abfd, strlen (space.name.n_name) + 1);
+ if (!newname)
+ goto error_return;
+ strcpy (newname, space.name.n_name);
+
+ space_asect = bfd_make_section_anyway (abfd, newname);
+ if (!space_asect)
+ goto error_return;
+
+ if (space.is_loadable == 0)
+ space_asect->flags |= SEC_DEBUGGING;
+
+ /* Set up all the attributes for the space. */
+ if (bfd_som_set_section_attributes (space_asect, space.is_defined,
+ space.is_private, space.sort_key,
+ space.space_number) == false)
+ goto error_return;
+
+ /* If the space has no subspaces, then we're done. */
+ if (space.subspace_quantity == 0)
+ continue;
+
+ /* Now, read in the first subspace for this space */
+ if (bfd_seek (abfd,
+ (current_offset + file_hdr->subspace_location
+ + space.subspace_index * sizeof subspace),
+ SEEK_SET) < 0)
+ goto error_return;
+ if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace)
+ goto error_return;
+ /* Seek back to the start of the subspaces for loop below */
+ if (bfd_seek (abfd,
+ (current_offset + file_hdr->subspace_location
+ + space.subspace_index * sizeof subspace),
+ SEEK_SET) < 0)
+ goto error_return;
+
+ /* Setup the start address and file loc from the first subspace record */
+ space_asect->vma = subspace.subspace_start;
+ space_asect->filepos = subspace.file_loc_init_value + current_offset;
+ space_asect->alignment_power = log2 (subspace.alignment);
+ if (space_asect->alignment_power == -1)
+ goto error_return;
+
+ /* Initialize save_subspace so we can reliably determine if this
+ loop placed any useful values into it. */
+ memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record));
+
+ /* Loop over the rest of the subspaces, building up more sections */
+ for (subspace_index = 0; subspace_index < space.subspace_quantity;
+ subspace_index++)
+ {
+ asection *subspace_asect;
+
+ /* Read in the next subspace */
+ if (bfd_read (&subspace, 1, sizeof subspace, abfd)
+ != sizeof subspace)
+ goto error_return;
+
+ /* Setup the subspace name string */
+ subspace.name.n_name = subspace.name.n_strx + space_strings;
+
+ newname = bfd_alloc (abfd, strlen (subspace.name.n_name) + 1);
+ if (!newname)
+ goto error_return;
+ strcpy (newname, subspace.name.n_name);
+
+ /* Make a section out of this subspace */
+ subspace_asect = bfd_make_section_anyway (abfd, newname);
+ if (!subspace_asect)
+ goto error_return;
+
+ /* Store private information about the section. */
+ if (bfd_som_set_subsection_attributes (subspace_asect, space_asect,
+ subspace.access_control_bits,
+ subspace.sort_key,
+ subspace.quadrant) == false)
+ goto error_return;
+
+ /* Keep an easy mapping between subspaces and sections.
+ Note we do not necessarily read the subspaces in the
+ same order in which they appear in the object file.
+
+ So to make the target index come out correctly, we
+ store the location of the subspace header in target
+ index, then sort using the location of the subspace
+ header as the key. Then we can assign correct
+ subspace indices. */
+ total_subspaces++;
+ subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace);
+
+ /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified
+ by the access_control_bits in the subspace header. */
+ switch (subspace.access_control_bits >> 4)
+ {
+ /* Readonly data. */
+ case 0x0:
+ subspace_asect->flags |= SEC_DATA | SEC_READONLY;
+ break;
+
+ /* Normal data. */
+ case 0x1:
+ subspace_asect->flags |= SEC_DATA;
+ break;
+
+ /* Readonly code and the gateways.
+ Gateways have other attributes which do not map
+ into anything BFD knows about. */
+ case 0x2:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ subspace_asect->flags |= SEC_CODE | SEC_READONLY;
+ break;
+
+ /* dynamic (writable) code. */
+ case 0x3:
+ subspace_asect->flags |= SEC_CODE;
+ break;
+ }
+
+ if (subspace.dup_common || subspace.is_common)
+ subspace_asect->flags |= SEC_IS_COMMON;
+ else if (subspace.subspace_length > 0)
+ subspace_asect->flags |= SEC_HAS_CONTENTS;
+
+ if (subspace.is_loadable)
+ subspace_asect->flags |= SEC_ALLOC | SEC_LOAD;
+ else
+ subspace_asect->flags |= SEC_DEBUGGING;
+
+ if (subspace.code_only)
+ subspace_asect->flags |= SEC_CODE;
+
+ /* Both file_loc_init_value and initialization_length will
+ be zero for a BSS like subspace. */
+ if (subspace.file_loc_init_value == 0
+ && subspace.initialization_length == 0)
+ subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD | SEC_HAS_CONTENTS);
+
+ /* This subspace has relocations.
+ The fixup_request_quantity is a byte count for the number of
+ entries in the relocation stream; it is not the actual number
+ of relocations in the subspace. */
+ if (subspace.fixup_request_quantity != 0)
+ {
+ subspace_asect->flags |= SEC_RELOC;
+ subspace_asect->rel_filepos = subspace.fixup_request_index;
+ som_section_data (subspace_asect)->reloc_size
+ = subspace.fixup_request_quantity;
+ /* We can not determine this yet. When we read in the
+ relocation table the correct value will be filled in. */
+ subspace_asect->reloc_count = -1;
+ }
+
+ /* Update save_subspace if appropriate. */
+ if (subspace.file_loc_init_value > save_subspace.file_loc_init_value)
+ save_subspace = subspace;
+
+ subspace_asect->vma = subspace.subspace_start;
+ subspace_asect->_cooked_size = subspace.subspace_length;
+ subspace_asect->_raw_size = subspace.subspace_length;
+ subspace_asect->filepos = (subspace.file_loc_init_value
+ + current_offset);
+ subspace_asect->alignment_power = log2 (subspace.alignment);
+ if (subspace_asect->alignment_power == -1)
+ goto error_return;
+ }
+
+ /* This can happen for a .o which defines symbols in otherwise
+ empty subspaces. */
+ if (!save_subspace.file_loc_init_value)
+ {
+ space_asect->_cooked_size = 0;
+ space_asect->_raw_size = 0;
+ }
+ else
+ {
+ /* Setup the sizes for the space section based upon the info in the
+ last subspace of the space. */
+ space_asect->_cooked_size = (save_subspace.subspace_start
+ - space_asect->vma
+ + save_subspace.subspace_length);
+ space_asect->_raw_size = (save_subspace.file_loc_init_value
+ - space_asect->filepos
+ + save_subspace.initialization_length);
+ }
+ }
+ /* Now that we've read in all the subspace records, we need to assign
+ a target index to each subspace. */
+ subspace_sections = (asection **) bfd_malloc (total_subspaces
+ * sizeof (asection *));
+ if (subspace_sections == NULL)
+ goto error_return;
+
+ for (i = 0, section = abfd->sections; section; section = section->next)
+ {
+ if (!som_is_subspace (section))
+ continue;
+
+ subspace_sections[i] = section;
+ i++;
+ }
+ qsort (subspace_sections, total_subspaces,
+ sizeof (asection *), compare_subspaces);
+
+ /* subspace_sections is now sorted in the order in which the subspaces
+ appear in the object file. Assign an index to each one now. */
+ for (i = 0; i < total_subspaces; i++)
+ subspace_sections[i]->target_index = i;
+
+ if (space_strings != NULL)
+ free (space_strings);
+
+ if (subspace_sections != NULL)
+ free (subspace_sections);
+
+ return true;
+
+ error_return:
+ if (space_strings != NULL)
+ free (space_strings);
+
+ if (subspace_sections != NULL)
+ free (subspace_sections);
+ return false;
+}
+
+/* Read in a SOM object and make it into a BFD. */
+
+static const bfd_target *
+som_object_p (abfd)
+ bfd *abfd;
+{
+ struct header file_hdr;
+ struct som_exec_auxhdr aux_hdr;
+ unsigned long current_offset = 0;
+ struct lst_header lst_header;
+ struct som_entry som_entry;
+#define ENTRY_SIZE sizeof(struct som_entry)
+
+ if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (!_PA_RISC_ID (file_hdr.system_id))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ switch (file_hdr.a_magic)
+ {
+ case RELOC_MAGIC:
+ case EXEC_MAGIC:
+ case SHARE_MAGIC:
+ case DEMAND_MAGIC:
+#ifdef DL_MAGIC
+ case DL_MAGIC:
+#endif
+#ifdef SHL_MAGIC
+ case SHL_MAGIC:
+#endif
+#ifdef SHARED_MAGIC_CNX
+ case SHARED_MAGIC_CNX:
+#endif
+ break;
+
+#ifdef EXECLIBMAGIC
+ case EXECLIBMAGIC:
+ /* Read the lst header and determine where the SOM directory begins */
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (bfd_read ((PTR) & lst_header, 1, SLSTHDR, abfd) != SLSTHDR)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* Position to and read the first directory entry */
+
+ if (bfd_seek (abfd, lst_header.dir_loc, SEEK_SET) < 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (bfd_read ((PTR) & som_entry, 1, ENTRY_SIZE, abfd) != ENTRY_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* Now position to the first SOM */
+
+ if (bfd_seek (abfd, som_entry.location, SEEK_SET) < 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ current_offset = som_entry.location;
+
+ /* And finally, re-read the som header */
+
+ if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ break;
+#endif
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (file_hdr.version_id != VERSION_ID
+ && file_hdr.version_id != NEW_VERSION_ID)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* If the aux_header_size field in the file header is zero, then this
+ object is an incomplete executable (a .o file). Do not try to read
+ a non-existant auxiliary header. */
+ memset (&aux_hdr, 0, sizeof (struct som_exec_auxhdr));
+ if (file_hdr.aux_header_size != 0)
+ {
+ if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ }
+
+ if (!setup_sections (abfd, &file_hdr, current_offset))
+ {
+ /* setup_sections does not bubble up a bfd error code. */
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ /* This appears to be a valid SOM object. Do some initialization. */
+ return som_object_setup (abfd, &file_hdr, &aux_hdr, current_offset);
+}
+
+/* Create a SOM object. */
+
+static boolean
+som_mkobject (abfd)
+ bfd *abfd;
+{
+ /* Allocate memory to hold backend information. */
+ abfd->tdata.som_data = (struct som_data_struct *)
+ bfd_zalloc (abfd, sizeof (struct som_data_struct));
+ if (abfd->tdata.som_data == NULL)
+ return false;
+ return true;
+}
+
+/* Initialize some information in the file header. This routine makes
+ not attempt at doing the right thing for a full executable; it
+ is only meant to handle relocatable objects. */
+
+static boolean
+som_prep_headers (abfd)
+ bfd *abfd;
+{
+ struct header *file_hdr;
+ asection *section;
+
+ /* Make and attach a file header to the BFD. */
+ file_hdr = (struct header *) bfd_zalloc (abfd, sizeof (struct header));
+ if (file_hdr == NULL)
+ return false;
+ obj_som_file_hdr (abfd) = file_hdr;
+
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ {
+
+ /* Make and attach an exec header to the BFD. */
+ obj_som_exec_hdr (abfd) = (struct som_exec_auxhdr *)
+ bfd_zalloc (abfd, sizeof (struct som_exec_auxhdr));
+ if (obj_som_exec_hdr (abfd) == NULL)
+ return false;
+
+ if (abfd->flags & D_PAGED)
+ file_hdr->a_magic = DEMAND_MAGIC;
+ else if (abfd->flags & WP_TEXT)
+ file_hdr->a_magic = SHARE_MAGIC;
+#ifdef SHL_MAGIC
+ else if (abfd->flags & DYNAMIC)
+ file_hdr->a_magic = SHL_MAGIC;
+#endif
+ else
+ file_hdr->a_magic = EXEC_MAGIC;
+ }
+ else
+ file_hdr->a_magic = RELOC_MAGIC;
+
+ /* Only new format SOM is supported. */
+ file_hdr->version_id = NEW_VERSION_ID;
+
+ /* These fields are optional, and embedding timestamps is not always
+ a wise thing to do, it makes comparing objects during a multi-stage
+ bootstrap difficult. */
+ file_hdr->file_time.secs = 0;
+ file_hdr->file_time.nanosecs = 0;
+
+ file_hdr->entry_space = 0;
+ file_hdr->entry_subspace = 0;
+ file_hdr->entry_offset = 0;
+ file_hdr->presumed_dp = 0;
+
+ /* Now iterate over the sections translating information from
+ BFD sections to SOM spaces/subspaces. */
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ /* Ignore anything which has not been marked as a space or
+ subspace. */
+ if (!som_is_space (section) && !som_is_subspace (section))
+ continue;
+
+ if (som_is_space (section))
+ {
+ /* Allocate space for the space dictionary. */
+ som_section_data (section)->space_dict
+ = (struct space_dictionary_record *)
+ bfd_zalloc (abfd, sizeof (struct space_dictionary_record));
+ if (som_section_data (section)->space_dict == NULL)
+ return false;
+ /* Set space attributes. Note most attributes of SOM spaces
+ are set based on the subspaces it contains. */
+ som_section_data (section)->space_dict->loader_fix_index = -1;
+ som_section_data (section)->space_dict->init_pointer_index = -1;
+
+ /* Set more attributes that were stuffed away in private data. */
+ som_section_data (section)->space_dict->sort_key =
+ som_section_data (section)->copy_data->sort_key;
+ som_section_data (section)->space_dict->is_defined =
+ som_section_data (section)->copy_data->is_defined;
+ som_section_data (section)->space_dict->is_private =
+ som_section_data (section)->copy_data->is_private;
+ som_section_data (section)->space_dict->space_number =
+ som_section_data (section)->copy_data->space_number;
+ }
+ else
+ {
+ /* Allocate space for the subspace dictionary. */
+ som_section_data (section)->subspace_dict
+ = (struct subspace_dictionary_record *)
+ bfd_zalloc (abfd, sizeof (struct subspace_dictionary_record));
+ if (som_section_data (section)->subspace_dict == NULL)
+ return false;
+
+ /* Set subspace attributes. Basic stuff is done here, additional
+ attributes are filled in later as more information becomes
+ available. */
+ if (section->flags & SEC_IS_COMMON)
+ {
+ som_section_data (section)->subspace_dict->dup_common = 1;
+ som_section_data (section)->subspace_dict->is_common = 1;
+ }
+
+ if (section->flags & SEC_ALLOC)
+ som_section_data (section)->subspace_dict->is_loadable = 1;
+
+ if (section->flags & SEC_CODE)
+ som_section_data (section)->subspace_dict->code_only = 1;
+
+ som_section_data (section)->subspace_dict->subspace_start =
+ section->vma;
+ som_section_data (section)->subspace_dict->subspace_length =
+ bfd_section_size (abfd, section);
+ som_section_data (section)->subspace_dict->initialization_length =
+ bfd_section_size (abfd, section);
+ som_section_data (section)->subspace_dict->alignment =
+ 1 << section->alignment_power;
+
+ /* Set more attributes that were stuffed away in private data. */
+ som_section_data (section)->subspace_dict->sort_key =
+ som_section_data (section)->copy_data->sort_key;
+ som_section_data (section)->subspace_dict->access_control_bits =
+ som_section_data (section)->copy_data->access_control_bits;
+ som_section_data (section)->subspace_dict->quadrant =
+ som_section_data (section)->copy_data->quadrant;
+ }
+ }
+ return true;
+}
+
+/* Return true if the given section is a SOM space, false otherwise. */
+
+static boolean
+som_is_space (section)
+ asection *section;
+{
+ /* If no copy data is available, then it's neither a space nor a
+ subspace. */
+ if (som_section_data (section)->copy_data == NULL)
+ return false;
+
+ /* If the containing space isn't the same as the given section,
+ then this isn't a space. */
+ if (som_section_data (section)->copy_data->container != section
+ && (som_section_data (section)->copy_data->container->output_section
+ != section))
+ return false;
+
+ /* OK. Must be a space. */
+ return true;
+}
+
+/* Return true if the given section is a SOM subspace, false otherwise. */
+
+static boolean
+som_is_subspace (section)
+ asection *section;
+{
+ /* If no copy data is available, then it's neither a space nor a
+ subspace. */
+ if (som_section_data (section)->copy_data == NULL)
+ return false;
+
+ /* If the containing space is the same as the given section,
+ then this isn't a subspace. */
+ if (som_section_data (section)->copy_data->container == section
+ || (som_section_data (section)->copy_data->container->output_section
+ == section))
+ return false;
+
+ /* OK. Must be a subspace. */
+ return true;
+}
+
+/* Return true if the given space containins the given subspace. It
+ is safe to assume space really is a space, and subspace really
+ is a subspace. */
+
+static boolean
+som_is_container (space, subspace)
+ asection *space, *subspace;
+{
+ return (som_section_data (subspace)->copy_data->container == space
+ || (som_section_data (subspace)->copy_data->container->output_section
+ == space));
+}
+
+/* Count and return the number of spaces attached to the given BFD. */
+
+static unsigned long
+som_count_spaces (abfd)
+ bfd *abfd;
+{
+ int count = 0;
+ asection *section;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ count += som_is_space (section);
+
+ return count;
+}
+
+/* Count the number of subspaces attached to the given BFD. */
+
+static unsigned long
+som_count_subspaces (abfd)
+ bfd *abfd;
+{
+ int count = 0;
+ asection *section;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ count += som_is_subspace (section);
+
+ return count;
+}
+
+/* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2.
+
+ We desire symbols to be ordered starting with the symbol with the
+ highest relocation count down to the symbol with the lowest relocation
+ count. Doing so compacts the relocation stream. */
+
+static int
+compare_syms (arg1, arg2)
+ const PTR arg1;
+ const PTR arg2;
+
+{
+ asymbol **sym1 = (asymbol **) arg1;
+ asymbol **sym2 = (asymbol **) arg2;
+ unsigned int count1, count2;
+
+ /* Get relocation count for each symbol. Note that the count
+ is stored in the udata pointer for section symbols! */
+ if ((*sym1)->flags & BSF_SECTION_SYM)
+ count1 = (*sym1)->udata.i;
+ else
+ count1 = som_symbol_data (*sym1)->reloc_count;
+
+ if ((*sym2)->flags & BSF_SECTION_SYM)
+ count2 = (*sym2)->udata.i;
+ else
+ count2 = som_symbol_data (*sym2)->reloc_count;
+
+ /* Return the appropriate value. */
+ if (count1 < count2)
+ return 1;
+ else if (count1 > count2)
+ return -1;
+ return 0;
+}
+
+/* Return -1, 0, 1 indicating the relative ordering of subspace1
+ and subspace. */
+
+static int
+compare_subspaces (arg1, arg2)
+ const PTR arg1;
+ const PTR arg2;
+
+{
+ asection **subspace1 = (asection **) arg1;
+ asection **subspace2 = (asection **) arg2;
+ unsigned int count1, count2;
+
+ if ((*subspace1)->target_index < (*subspace2)->target_index)
+ return -1;
+ else if ((*subspace2)->target_index < (*subspace1)->target_index)
+ return 1;
+ else
+ return 0;
+}
+
+/* Perform various work in preparation for emitting the fixup stream. */
+
+static void
+som_prep_for_fixups (abfd, syms, num_syms)
+ bfd *abfd;
+ asymbol **syms;
+ unsigned long num_syms;
+{
+ int i;
+ asection *section;
+ asymbol **sorted_syms;
+
+ /* Most SOM relocations involving a symbol have a length which is
+ dependent on the index of the symbol. So symbols which are
+ used often in relocations should have a small index. */
+
+ /* First initialize the counters for each symbol. */
+ for (i = 0; i < num_syms; i++)
+ {
+ /* Handle a section symbol; these have no pointers back to the
+ SOM symbol info. So we just use the udata field to hold the
+ relocation count. */
+ if (som_symbol_data (syms[i]) == NULL
+ || syms[i]->flags & BSF_SECTION_SYM)
+ {
+ syms[i]->flags |= BSF_SECTION_SYM;
+ syms[i]->udata.i = 0;
+ }
+ else
+ som_symbol_data (syms[i])->reloc_count = 0;
+ }
+
+ /* Now that the counters are initialized, make a weighted count
+ of how often a given symbol is used in a relocation. */
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ int i;
+
+ /* Does this section have any relocations? */
+ if (section->reloc_count <= 0)
+ continue;
+
+ /* Walk through each relocation for this section. */
+ for (i = 1; i < section->reloc_count; i++)
+ {
+ arelent *reloc = section->orelocation[i];
+ int scale;
+
+ /* A relocation against a symbol in the *ABS* section really
+ does not have a symbol. Likewise if the symbol isn't associated
+ with any section. */
+ if (reloc->sym_ptr_ptr == NULL
+ || bfd_is_abs_section ((*reloc->sym_ptr_ptr)->section))
+ continue;
+
+ /* Scaling to encourage symbols involved in R_DP_RELATIVE
+ and R_CODE_ONE_SYMBOL relocations to come first. These
+ two relocations have single byte versions if the symbol
+ index is very small. */
+ if (reloc->howto->type == R_DP_RELATIVE
+ || reloc->howto->type == R_CODE_ONE_SYMBOL)
+ scale = 2;
+ else
+ scale = 1;
+
+ /* Handle section symbols by storing the count in the udata
+ field. It will not be used and the count is very important
+ for these symbols. */
+ if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
+ {
+ (*reloc->sym_ptr_ptr)->udata.i =
+ (*reloc->sym_ptr_ptr)->udata.i + scale;
+ continue;
+ }
+
+ /* A normal symbol. Increment the count. */
+ som_symbol_data (*reloc->sym_ptr_ptr)->reloc_count += scale;
+ }
+ }
+
+ /* Sort a copy of the symbol table, rather than the canonical
+ output symbol table. */
+ sorted_syms = (asymbol **) bfd_zalloc (abfd, num_syms * sizeof (asymbol *));
+ memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *));
+ qsort (sorted_syms, num_syms, sizeof (asymbol *), compare_syms);
+ obj_som_sorted_syms (abfd) = sorted_syms;
+
+ /* Compute the symbol indexes, they will be needed by the relocation
+ code. */
+ for (i = 0; i < num_syms; i++)
+ {
+ /* A section symbol. Again, there is no pointer to backend symbol
+ information, so we reuse the udata field again. */
+ if (sorted_syms[i]->flags & BSF_SECTION_SYM)
+ sorted_syms[i]->udata.i = i;
+ else
+ som_symbol_data (sorted_syms[i])->index = i;
+ }
+}
+
+static boolean
+som_write_fixups (abfd, current_offset, total_reloc_sizep)
+ bfd *abfd;
+ unsigned long current_offset;
+ unsigned int *total_reloc_sizep;
+{
+ unsigned int i, j;
+ /* Chunk of memory that we can use as buffer space, then throw
+ away. */
+ unsigned char tmp_space[SOM_TMP_BUFSIZE];
+ unsigned char *p;
+ unsigned int total_reloc_size = 0;
+ unsigned int subspace_reloc_size = 0;
+ unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total;
+ asection *section = abfd->sections;
+
+ memset (tmp_space, 0, SOM_TMP_BUFSIZE);
+ p = tmp_space;
+
+ /* All the fixups for a particular subspace are emitted in a single
+ stream. All the subspaces for a particular space are emitted
+ as a single stream.
+
+ So, to get all the locations correct one must iterate through all the
+ spaces, for each space iterate through its subspaces and output a
+ fixups stream. */
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ /* Now iterate through each of its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+ int reloc_offset, current_rounding_mode;
+
+ /* Find a subspace of this space. */
+ if (!som_is_subspace (subsection)
+ || !som_is_container (section, subsection))
+ continue;
+
+ /* If this subspace does not have real data, then we are
+ finised with it. */
+ if ((subsection->flags & SEC_HAS_CONTENTS) == 0)
+ {
+ som_section_data (subsection)->subspace_dict->fixup_request_index
+ = -1;
+ continue;
+ }
+
+ /* This subspace has some relocations. Put the relocation stream
+ index into the subspace record. */
+ som_section_data (subsection)->subspace_dict->fixup_request_index
+ = total_reloc_size;
+
+ /* To make life easier start over with a clean slate for
+ each subspace. Seek to the start of the relocation stream
+ for this subspace in preparation for writing out its fixup
+ stream. */
+ if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) < 0)
+ return false;
+
+ /* Buffer space has already been allocated. Just perform some
+ initialization here. */
+ p = tmp_space;
+ subspace_reloc_size = 0;
+ reloc_offset = 0;
+ som_initialize_reloc_queue (reloc_queue);
+ current_rounding_mode = R_N_MODE;
+
+ /* Translate each BFD relocation into one or more SOM
+ relocations. */
+ for (j = 0; j < subsection->reloc_count; j++)
+ {
+ arelent *bfd_reloc = subsection->orelocation[j];
+ unsigned int skip;
+ int sym_num;
+
+ /* Get the symbol number. Remember it's stored in a
+ special place for section symbols. */
+ if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
+ sym_num = (*bfd_reloc->sym_ptr_ptr)->udata.i;
+ else
+ sym_num = som_symbol_data (*bfd_reloc->sym_ptr_ptr)->index;
+
+ /* If there is not enough room for the next couple relocations,
+ then dump the current buffer contents now. Also reinitialize
+ the relocation queue.
+
+ No single BFD relocation could ever translate into more
+ than 100 bytes of SOM relocations (20bytes is probably the
+ upper limit, but leave lots of space for growth). */
+ if (p - tmp_space + 100 > SOM_TMP_BUFSIZE)
+ {
+ if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
+ != p - tmp_space)
+ return false;
+
+ p = tmp_space;
+ som_initialize_reloc_queue (reloc_queue);
+ }
+
+ /* Emit R_NO_RELOCATION fixups to map any bytes which were
+ skipped. */
+ skip = bfd_reloc->address - reloc_offset;
+ p = som_reloc_skip (abfd, skip, p,
+ &subspace_reloc_size, reloc_queue);
+
+ /* Update reloc_offset for the next iteration.
+
+ Many relocations do not consume input bytes. They
+ are markers, or set state necessary to perform some
+ later relocation. */
+ switch (bfd_reloc->howto->type)
+ {
+ case R_ENTRY:
+ case R_ALT_ENTRY:
+ case R_EXIT:
+ case R_N_MODE:
+ case R_S_MODE:
+ case R_D_MODE:
+ case R_R_MODE:
+ case R_FSEL:
+ case R_LSEL:
+ case R_RSEL:
+ case R_COMP1:
+ case R_COMP2:
+ case R_BEGIN_BRTAB:
+ case R_END_BRTAB:
+ case R_BEGIN_TRY:
+ case R_END_TRY:
+ case R_N0SEL:
+ case R_N1SEL:
+ reloc_offset = bfd_reloc->address;
+ break;
+
+ default:
+ reloc_offset = bfd_reloc->address + 4;
+ break;
+ }
+
+ /* Now the actual relocation we care about. */
+ switch (bfd_reloc->howto->type)
+ {
+ case R_PCREL_CALL:
+ case R_ABS_CALL:
+ p = som_reloc_call (abfd, p, &subspace_reloc_size,
+ bfd_reloc, sym_num, reloc_queue);
+ break;
+
+ case R_CODE_ONE_SYMBOL:
+ case R_DP_RELATIVE:
+ /* Account for any addend. */
+ if (bfd_reloc->addend)
+ p = som_reloc_addend (abfd, bfd_reloc->addend, p,
+ &subspace_reloc_size, reloc_queue);
+
+ if (sym_num < 0x20)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ }
+ else if (sym_num < 0x100)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p);
+ bfd_put_8 (abfd, sym_num, p + 1);
+ p = try_prev_fixup (abfd, &subspace_reloc_size, p,
+ 2, reloc_queue);
+ }
+ else if (sym_num < 0x10000000)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p);
+ bfd_put_8 (abfd, sym_num >> 16, p + 1);
+ bfd_put_16 (abfd, sym_num, p + 2);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 4, reloc_queue);
+ }
+ else
+ abort ();
+ break;
+
+ case R_DATA_ONE_SYMBOL:
+ case R_DATA_PLABEL:
+ case R_CODE_PLABEL:
+ case R_DLT_REL:
+ /* Account for any addend using R_DATA_OVERRIDE. */
+ if (bfd_reloc->howto->type != R_DATA_ONE_SYMBOL
+ && bfd_reloc->addend)
+ p = som_reloc_addend (abfd, bfd_reloc->addend, p,
+ &subspace_reloc_size, reloc_queue);
+
+ if (sym_num < 0x100)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ bfd_put_8 (abfd, sym_num, p + 1);
+ p = try_prev_fixup (abfd, &subspace_reloc_size, p,
+ 2, reloc_queue);
+ }
+ else if (sym_num < 0x10000000)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
+ bfd_put_8 (abfd, sym_num >> 16, p + 1);
+ bfd_put_16 (abfd, sym_num, p + 2);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 4, reloc_queue);
+ }
+ else
+ abort ();
+ break;
+
+ case R_ENTRY:
+ {
+ int tmp;
+ arelent *tmp_reloc = NULL;
+ bfd_put_8 (abfd, R_ENTRY, p);
+
+ /* R_ENTRY relocations have 64 bits of associated
+ data. Unfortunately the addend field of a bfd
+ relocation is only 32 bits. So, we split up
+ the 64bit unwind information and store part in
+ the R_ENTRY relocation, and the rest in the R_EXIT
+ relocation. */
+ bfd_put_32 (abfd, bfd_reloc->addend, p + 1);
+
+ /* Find the next R_EXIT relocation. */
+ for (tmp = j; tmp < subsection->reloc_count; tmp++)
+ {
+ tmp_reloc = subsection->orelocation[tmp];
+ if (tmp_reloc->howto->type == R_EXIT)
+ break;
+ }
+
+ if (tmp == subsection->reloc_count)
+ abort ();
+
+ bfd_put_32 (abfd, tmp_reloc->addend, p + 5);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 9, reloc_queue);
+ break;
+ }
+
+ case R_N_MODE:
+ case R_S_MODE:
+ case R_D_MODE:
+ case R_R_MODE:
+ /* If this relocation requests the current rounding
+ mode, then it is redundant. */
+ if (bfd_reloc->howto->type != current_rounding_mode)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ current_rounding_mode = bfd_reloc->howto->type;
+ }
+ break;
+
+ case R_EXIT:
+ case R_ALT_ENTRY:
+ case R_FSEL:
+ case R_LSEL:
+ case R_RSEL:
+ case R_BEGIN_BRTAB:
+ case R_END_BRTAB:
+ case R_BEGIN_TRY:
+ case R_N0SEL:
+ case R_N1SEL:
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ break;
+
+ case R_END_TRY:
+ /* The end of a exception handling region. The reloc's
+ addend contains the offset of the exception handling
+ code. */
+ if (bfd_reloc->addend == 0)
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ else if (bfd_reloc->addend < 1024)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p);
+ bfd_put_8 (abfd, bfd_reloc->addend / 4, p + 1);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 2, reloc_queue);
+ }
+ else
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type + 2, p);
+ bfd_put_8 (abfd, (bfd_reloc->addend / 4) >> 16, p + 1);
+ bfd_put_16 (abfd, bfd_reloc->addend / 4, p + 2);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 4, reloc_queue);
+ }
+ break;
+
+ case R_COMP1:
+ /* The only time we generate R_COMP1, R_COMP2 and
+ R_CODE_EXPR relocs is for the difference of two
+ symbols. Hence we can cheat here. */
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ bfd_put_8 (abfd, 0x44, p + 1);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 2, reloc_queue);
+ break;
+
+ case R_COMP2:
+ /* The only time we generate R_COMP1, R_COMP2 and
+ R_CODE_EXPR relocs is for the difference of two
+ symbols. Hence we can cheat here. */
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ bfd_put_8 (abfd, 0x80, p + 1);
+ bfd_put_8 (abfd, sym_num >> 16, p + 2);
+ bfd_put_16 (abfd, sym_num, p + 3);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 5, reloc_queue);
+ break;
+
+ case R_CODE_EXPR:
+ case R_DATA_EXPR:
+ /* The only time we generate R_COMP1, R_COMP2 and
+ R_CODE_EXPR relocs is for the difference of two
+ symbols. Hence we can cheat here. */
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ break;
+
+ /* Put a "R_RESERVED" relocation in the stream if
+ we hit something we do not understand. The linker
+ will complain loudly if this ever happens. */
+ default:
+ bfd_put_8 (abfd, 0xff, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ break;
+ }
+ }
+
+ /* Last BFD relocation for a subspace has been processed.
+ Map the rest of the subspace with R_NO_RELOCATION fixups. */
+ p = som_reloc_skip (abfd, bfd_section_size (abfd, subsection)
+ - reloc_offset,
+ p, &subspace_reloc_size, reloc_queue);
+
+ /* Scribble out the relocations. */
+ if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd)
+ != p - tmp_space)
+ return false;
+ p = tmp_space;
+
+ total_reloc_size += subspace_reloc_size;
+ som_section_data (subsection)->subspace_dict->fixup_request_quantity
+ = subspace_reloc_size;
+ }
+ section = section->next;
+ }
+ *total_reloc_sizep = total_reloc_size;
+ return true;
+}
+
+/* Write out the space/subspace string table. */
+
+static boolean
+som_write_space_strings (abfd, current_offset, string_sizep)
+ bfd *abfd;
+ unsigned long current_offset;
+ unsigned int *string_sizep;
+{
+ /* Chunk of memory that we can use as buffer space, then throw
+ away. */
+ unsigned char tmp_space[SOM_TMP_BUFSIZE];
+ unsigned char *p;
+ unsigned int strings_size = 0;
+ asection *section;
+
+ memset (tmp_space, 0, SOM_TMP_BUFSIZE);
+ p = tmp_space;
+
+ /* Seek to the start of the space strings in preparation for writing
+ them out. */
+ if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
+ return false;
+
+ /* Walk through all the spaces and subspaces (order is not important)
+ building up and writing string table entries for their names. */
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ int length;
+
+ /* Only work with space/subspaces; avoid any other sections
+ which might have been made (.text for example). */
+ if (!som_is_space (section) && !som_is_subspace (section))
+ continue;
+
+ /* Get the length of the space/subspace name. */
+ length = strlen (section->name);
+
+ /* If there is not enough room for the next entry, then dump the
+ current buffer contents now. Each entry will take 4 bytes to
+ hold the string length + the string itself + null terminator. */
+ if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
+ {
+ if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd)
+ != p - tmp_space)
+ return false;
+ /* Reset to beginning of the buffer space. */
+ p = tmp_space;
+ }
+
+ /* First element in a string table entry is the length of the
+ string. Alignment issues are already handled. */
+ bfd_put_32 (abfd, length, p);
+ p += 4;
+ strings_size += 4;
+
+ /* Record the index in the space/subspace records. */
+ if (som_is_space (section))
+ som_section_data (section)->space_dict->name.n_strx = strings_size;
+ else
+ som_section_data (section)->subspace_dict->name.n_strx = strings_size;
+
+ /* Next comes the string itself + a null terminator. */
+ strcpy (p, section->name);
+ p += length + 1;
+ strings_size += length + 1;
+
+ /* Always align up to the next word boundary. */
+ while (strings_size % 4)
+ {
+ bfd_put_8 (abfd, 0, p);
+ p++;
+ strings_size++;
+ }
+ }
+
+ /* Done with the space/subspace strings. Write out any information
+ contained in a partial block. */
+ if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space)
+ return false;
+ *string_sizep = strings_size;
+ return true;
+}
+
+/* Write out the symbol string table. */
+
+static boolean
+som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep,
+ compilation_unit)
+ bfd *abfd;
+ unsigned long current_offset;
+ asymbol **syms;
+ unsigned int num_syms;
+ unsigned int *string_sizep;
+ COMPUNIT *compilation_unit;
+{
+ unsigned int i;
+
+ /* Chunk of memory that we can use as buffer space, then throw
+ away. */
+ unsigned char tmp_space[SOM_TMP_BUFSIZE];
+ unsigned char *p;
+ unsigned int strings_size = 0;
+ unsigned char *comp[4];
+
+ /* This gets a bit gruesome because of the compilation unit. The
+ strings within the compilation unit are part of the symbol
+ strings, but don't have symbol_dictionary entries. So, manually
+ write them and update the compliation unit header. On input, the
+ compilation unit header contains local copies of the strings.
+ Move them aside. */
+ if (compilation_unit)
+ {
+ comp[0] = compilation_unit->name.n_name;
+ comp[1] = compilation_unit->language_name.n_name;
+ comp[2] = compilation_unit->product_id.n_name;
+ comp[3] = compilation_unit->version_id.n_name;
+ }
+
+ memset (tmp_space, 0, SOM_TMP_BUFSIZE);
+ p = tmp_space;
+
+ /* Seek to the start of the space strings in preparation for writing
+ them out. */
+ if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
+ return false;
+
+ if (compilation_unit)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ int length = strlen (comp[i]);
+
+ /* If there is not enough room for the next entry, then dump
+ the current buffer contents now. */
+ if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
+ {
+ if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd)
+ != p - tmp_space)
+ return false;
+ /* Reset to beginning of the buffer space. */
+ p = tmp_space;
+ }
+
+ /* First element in a string table entry is the length of
+ the string. This must always be 4 byte aligned. This is
+ also an appropriate time to fill in the string index
+ field in the symbol table entry. */
+ bfd_put_32 (abfd, length, p);
+ strings_size += 4;
+ p += 4;
+
+ /* Next comes the string itself + a null terminator. */
+ strcpy (p, comp[i]);
+
+ switch (i)
+ {
+ case 0:
+ obj_som_compilation_unit (abfd)->name.n_strx = strings_size;
+ break;
+ case 1:
+ obj_som_compilation_unit (abfd)->language_name.n_strx =
+ strings_size;
+ break;
+ case 2:
+ obj_som_compilation_unit (abfd)->product_id.n_strx =
+ strings_size;
+ break;
+ case 3:
+ obj_som_compilation_unit (abfd)->version_id.n_strx =
+ strings_size;
+ break;
+ }
+
+ p += length + 1;
+ strings_size += length + 1;
+
+ /* Always align up to the next word boundary. */
+ while (strings_size % 4)
+ {
+ bfd_put_8 (abfd, 0, p);
+ strings_size++;
+ p++;
+ }
+ }
+ }
+
+ for (i = 0; i < num_syms; i++)
+ {
+ int length = strlen (syms[i]->name);
+
+ /* If there is not enough room for the next entry, then dump the
+ current buffer contents now. */
+ if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE)
+ {
+ if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd)
+ != p - tmp_space)
+ return false;
+ /* Reset to beginning of the buffer space. */
+ p = tmp_space;
+ }
+
+ /* First element in a string table entry is the length of the
+ string. This must always be 4 byte aligned. This is also
+ an appropriate time to fill in the string index field in the
+ symbol table entry. */
+ bfd_put_32 (abfd, length, p);
+ strings_size += 4;
+ p += 4;
+
+ /* Next comes the string itself + a null terminator. */
+ strcpy (p, syms[i]->name);
+
+ som_symbol_data(syms[i])->stringtab_offset = strings_size;
+ p += length + 1;
+ strings_size += length + 1;
+
+ /* Always align up to the next word boundary. */
+ while (strings_size % 4)
+ {
+ bfd_put_8 (abfd, 0, p);
+ strings_size++;
+ p++;
+ }
+ }
+
+ /* Scribble out any partial block. */
+ if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space)
+ return false;
+
+ *string_sizep = strings_size;
+ return true;
+}
+
+/* Compute variable information to be placed in the SOM headers,
+ space/subspace dictionaries, relocation streams, etc. Begin
+ writing parts of the object file. */
+
+static boolean
+som_begin_writing (abfd)
+ bfd *abfd;
+{
+ unsigned long current_offset = 0;
+ int strings_size = 0;
+ unsigned int total_reloc_size = 0;
+ unsigned long num_spaces, num_subspaces, i;
+ asection *section;
+ unsigned int total_subspaces = 0;
+ struct som_exec_auxhdr *exec_header = NULL;
+
+ /* The file header will always be first in an object file,
+ everything else can be in random locations. To keep things
+ "simple" BFD will lay out the object file in the manner suggested
+ by the PRO ABI for PA-RISC Systems. */
+
+ /* Before any output can really begin offsets for all the major
+ portions of the object file must be computed. So, starting
+ with the initial file header compute (and sometimes write)
+ each portion of the object file. */
+
+ /* Make room for the file header, it's contents are not complete
+ yet, so it can not be written at this time. */
+ current_offset += sizeof (struct header);
+
+ /* Any auxiliary headers will follow the file header. Right now
+ we support only the copyright and version headers. */
+ obj_som_file_hdr (abfd)->aux_header_location = current_offset;
+ obj_som_file_hdr (abfd)->aux_header_size = 0;
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ {
+ /* Parts of the exec header will be filled in later, so
+ delay writing the header itself. Fill in the defaults,
+ and write it later. */
+ current_offset += sizeof (struct som_exec_auxhdr);
+ obj_som_file_hdr (abfd)->aux_header_size
+ += sizeof (struct som_exec_auxhdr);
+ exec_header = obj_som_exec_hdr (abfd);
+ exec_header->som_auxhdr.type = EXEC_AUX_ID;
+ exec_header->som_auxhdr.length = 40;
+ }
+ if (obj_som_version_hdr (abfd) != NULL)
+ {
+ unsigned int len;
+
+ if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
+ return false;
+
+ /* Write the aux_id structure and the string length. */
+ len = sizeof (struct aux_id) + sizeof (unsigned int);
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ if (bfd_write ((PTR) obj_som_version_hdr (abfd), len, 1, abfd) != len)
+ return false;
+
+ /* Write the version string. */
+ len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int);
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ if (bfd_write ((PTR) obj_som_version_hdr (abfd)->user_string,
+ len, 1, abfd) != len)
+ return false;
+ }
+
+ if (obj_som_copyright_hdr (abfd) != NULL)
+ {
+ unsigned int len;
+
+ if (bfd_seek (abfd, current_offset, SEEK_SET) < 0)
+ return false;
+
+ /* Write the aux_id structure and the string length. */
+ len = sizeof (struct aux_id) + sizeof (unsigned int);
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ if (bfd_write ((PTR) obj_som_copyright_hdr (abfd), len, 1, abfd) != len)
+ return false;
+
+ /* Write the copyright string. */
+ len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int);
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ if (bfd_write ((PTR) obj_som_copyright_hdr (abfd)->copyright,
+ len, 1, abfd) != len)
+ return false;
+ }
+
+ /* Next comes the initialization pointers; we have no initialization
+ pointers, so current offset does not change. */
+ obj_som_file_hdr (abfd)->init_array_location = current_offset;
+ obj_som_file_hdr (abfd)->init_array_total = 0;
+
+ /* Next are the space records. These are fixed length records.
+
+ Count the number of spaces to determine how much room is needed
+ in the object file for the space records.
+
+ The names of the spaces are stored in a separate string table,
+ and the index for each space into the string table is computed
+ below. Therefore, it is not possible to write the space headers
+ at this time. */
+ num_spaces = som_count_spaces (abfd);
+ obj_som_file_hdr (abfd)->space_location = current_offset;
+ obj_som_file_hdr (abfd)->space_total = num_spaces;
+ current_offset += num_spaces * sizeof (struct space_dictionary_record);
+
+ /* Next are the subspace records. These are fixed length records.
+
+ Count the number of subspaes to determine how much room is needed
+ in the object file for the subspace records.
+
+ A variety if fields in the subspace record are still unknown at
+ this time (index into string table, fixup stream location/size, etc). */
+ num_subspaces = som_count_subspaces (abfd);
+ obj_som_file_hdr (abfd)->subspace_location = current_offset;
+ obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
+ current_offset += num_subspaces * sizeof (struct subspace_dictionary_record);
+
+ /* Next is the string table for the space/subspace names. We will
+ build and write the string table on the fly. At the same time
+ we will fill in the space/subspace name index fields. */
+
+ /* The string table needs to be aligned on a word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+
+ /* Mark the offset of the space/subspace string table in the
+ file header. */
+ obj_som_file_hdr (abfd)->space_strings_location = current_offset;
+
+ /* Scribble out the space strings. */
+ if (som_write_space_strings (abfd, current_offset, &strings_size) == false)
+ return false;
+
+ /* Record total string table size in the header and update the
+ current offset. */
+ obj_som_file_hdr (abfd)->space_strings_size = strings_size;
+ current_offset += strings_size;
+
+ /* Next is the compilation unit. */
+ obj_som_file_hdr (abfd)->compiler_location = current_offset;
+ obj_som_file_hdr (abfd)->compiler_total = 0;
+ if (obj_som_compilation_unit (abfd))
+ {
+ obj_som_file_hdr (abfd)->compiler_total = 1;
+ current_offset += COMPUNITSZ;
+ }
+
+ /* Now compute the file positions for the loadable subspaces, taking
+ care to make sure everything stays properly aligned. */
+
+ section = abfd->sections;
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+ int first_subspace;
+ unsigned int subspace_offset = 0;
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ first_subspace = 1;
+ /* Now look for all its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+
+ if (!som_is_subspace (subsection)
+ || !som_is_container (section, subsection)
+ || (subsection->flags & SEC_ALLOC) == 0)
+ continue;
+
+ /* If this is the first subspace in the space, and we are
+ building an executable, then take care to make sure all
+ the alignments are correct and update the exec header. */
+ if (first_subspace
+ && (abfd->flags & (EXEC_P | DYNAMIC)))
+ {
+ /* Demand paged executables have each space aligned to a
+ page boundary. Sharable executables (write-protected
+ text) have just the private (aka data & bss) space aligned
+ to a page boundary. Ugh. Not true for HPUX.
+
+ The HPUX kernel requires the text to always be page aligned
+ within the file regardless of the executable's type. */
+ if (abfd->flags & (D_PAGED | DYNAMIC)
+ || (subsection->flags & SEC_CODE)
+ || ((abfd->flags & WP_TEXT)
+ && (subsection->flags & SEC_DATA)))
+ current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
+
+ /* Update the exec header. */
+ if (subsection->flags & SEC_CODE && exec_header->exec_tfile == 0)
+ {
+ exec_header->exec_tmem = section->vma;
+ exec_header->exec_tfile = current_offset;
+ }
+ if (subsection->flags & SEC_DATA && exec_header->exec_dfile == 0)
+ {
+ exec_header->exec_dmem = section->vma;
+ exec_header->exec_dfile = current_offset;
+ }
+
+ /* Keep track of exactly where we are within a particular
+ space. This is necessary as the braindamaged HPUX
+ loader will create holes between subspaces *and*
+ subspace alignments are *NOT* preserved. What a crock. */
+ subspace_offset = subsection->vma;
+
+ /* Only do this for the first subspace within each space. */
+ first_subspace = 0;
+ }
+ else if (abfd->flags & (EXEC_P | DYNAMIC))
+ {
+ /* The braindamaged HPUX loader may have created a hole
+ between two subspaces. It is *not* sufficient to use
+ the alignment specifications within the subspaces to
+ account for these holes -- I've run into at least one
+ case where the loader left one code subspace unaligned
+ in a final executable.
+
+ To combat this we keep a current offset within each space,
+ and use the subspace vma fields to detect and preserve
+ holes. What a crock!
+
+ ps. This is not necessary for unloadable space/subspaces. */
+ current_offset += subsection->vma - subspace_offset;
+ if (subsection->flags & SEC_CODE)
+ exec_header->exec_tsize += subsection->vma - subspace_offset;
+ else
+ exec_header->exec_dsize += subsection->vma - subspace_offset;
+ subspace_offset += subsection->vma - subspace_offset;
+ }
+
+
+ subsection->target_index = total_subspaces++;
+ /* This is real data to be loaded from the file. */
+ if (subsection->flags & SEC_LOAD)
+ {
+ /* Update the size of the code & data. */
+ if (abfd->flags & (EXEC_P | DYNAMIC)
+ && subsection->flags & SEC_CODE)
+ exec_header->exec_tsize += subsection->_cooked_size;
+ else if (abfd->flags & (EXEC_P | DYNAMIC)
+ && subsection->flags & SEC_DATA)
+ exec_header->exec_dsize += subsection->_cooked_size;
+ som_section_data (subsection)->subspace_dict->file_loc_init_value
+ = current_offset;
+ subsection->filepos = current_offset;
+ current_offset += bfd_section_size (abfd, subsection);
+ subspace_offset += bfd_section_size (abfd, subsection);
+ }
+ /* Looks like uninitialized data. */
+ else
+ {
+ /* Update the size of the bss section. */
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ exec_header->exec_bsize += subsection->_cooked_size;
+
+ som_section_data (subsection)->subspace_dict->file_loc_init_value
+ = 0;
+ som_section_data (subsection)->subspace_dict->
+ initialization_length = 0;
+ }
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* Finally compute the file positions for unloadable subspaces.
+ If building an executable, start the unloadable stuff on its
+ own page. */
+
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
+
+ obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset;
+ section = abfd->sections;
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
+
+ /* Now look for all its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+
+ if (!som_is_subspace (subsection)
+ || !som_is_container (section, subsection)
+ || (subsection->flags & SEC_ALLOC) != 0)
+ continue;
+
+ subsection->target_index = total_subspaces++;
+ /* This is real data to be loaded from the file. */
+ if ((subsection->flags & SEC_LOAD) == 0)
+ {
+ som_section_data (subsection)->subspace_dict->file_loc_init_value
+ = current_offset;
+ subsection->filepos = current_offset;
+ current_offset += bfd_section_size (abfd, subsection);
+ }
+ /* Looks like uninitialized data. */
+ else
+ {
+ som_section_data (subsection)->subspace_dict->file_loc_init_value
+ = 0;
+ som_section_data (subsection)->subspace_dict->
+ initialization_length = bfd_section_size (abfd, subsection);
+ }
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* If building an executable, then make sure to seek to and write
+ one byte at the end of the file to make sure any necessary
+ zeros are filled in. Ugh. */
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE);
+ if (bfd_seek (abfd, current_offset - 1, SEEK_SET) < 0)
+ return false;
+ if (bfd_write ((PTR) "", 1, 1, abfd) != 1)
+ return false;
+
+ obj_som_file_hdr (abfd)->unloadable_sp_size
+ = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location;
+
+ /* Loader fixups are not supported in any way shape or form. */
+ obj_som_file_hdr (abfd)->loader_fixup_location = 0;
+ obj_som_file_hdr (abfd)->loader_fixup_total = 0;
+
+ /* Done. Store the total size of the SOM so far. */
+ obj_som_file_hdr (abfd)->som_length = current_offset;
+
+ return true;
+}
+
+/* Finally, scribble out the various headers to the disk. */
+
+static boolean
+som_finish_writing (abfd)
+ bfd *abfd;
+{
+ int num_spaces = som_count_spaces (abfd);
+ asymbol **syms = bfd_get_outsymbols (abfd);
+ int i, num_syms, strings_size;
+ int subspace_index = 0;
+ file_ptr location;
+ asection *section;
+ unsigned long current_offset;
+ unsigned int total_reloc_size;
+
+ /* Next is the symbol table. These are fixed length records.
+
+ Count the number of symbols to determine how much room is needed
+ in the object file for the symbol table.
+
+ The names of the symbols are stored in a separate string table,
+ and the index for each symbol name into the string table is computed
+ below. Therefore, it is not possible to write the symbol table
+ at this time.
+
+ These used to be output before the subspace contents, but they
+ were moved here to work around a stupid bug in the hpux linker
+ (fixed in hpux10). */
+ current_offset = obj_som_file_hdr (abfd)->som_length;
+
+ /* Make sure we're on a word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+
+ num_syms = bfd_get_symcount (abfd);
+ obj_som_file_hdr (abfd)->symbol_location = current_offset;
+ obj_som_file_hdr (abfd)->symbol_total = num_syms;
+ current_offset += num_syms * sizeof (struct symbol_dictionary_record);
+
+ /* Next are the symbol strings.
+ Align them to a word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+ obj_som_file_hdr (abfd)->symbol_strings_location = current_offset;
+
+ /* Scribble out the symbol strings. */
+ if (som_write_symbol_strings (abfd, current_offset, syms,
+ num_syms, &strings_size,
+ obj_som_compilation_unit (abfd))
+ == false)
+ return false;
+
+ /* Record total string table size in header and update the
+ current offset. */
+ obj_som_file_hdr (abfd)->symbol_strings_size = strings_size;
+ current_offset += strings_size;
+
+ /* Do prep work before handling fixups. */
+ som_prep_for_fixups (abfd,
+ bfd_get_outsymbols (abfd),
+ bfd_get_symcount (abfd));
+
+ /* At the end of the file is the fixup stream which starts on a
+ word boundary. */
+ if (current_offset % 4)
+ current_offset += (4 - (current_offset % 4));
+ obj_som_file_hdr (abfd)->fixup_request_location = current_offset;
+
+ /* Write the fixups and update fields in subspace headers which
+ relate to the fixup stream. */
+ if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false)
+ return false;
+
+ /* Record the total size of the fixup stream in the file header. */
+ obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size;
+
+ /* Done. Store the total size of the SOM. */
+ obj_som_file_hdr (abfd)->som_length = current_offset + total_reloc_size;
+
+ /* Now that the symbol table information is complete, build and
+ write the symbol table. */
+ if (som_build_and_write_symbol_table (abfd) == false)
+ return false;
+
+ /* Subspaces are written first so that we can set up information
+ about them in their containing spaces as the subspace is written. */
+
+ /* Seek to the start of the subspace dictionary records. */
+ location = obj_som_file_hdr (abfd)->subspace_location;
+ if (bfd_seek (abfd, location, SEEK_SET) < 0)
+ return false;
+
+ section = abfd->sections;
+ /* Now for each loadable space write out records for its subspaces. */
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ /* Now look for all its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+
+ /* Skip any section which does not correspond to a space
+ or subspace. Or does not have SEC_ALLOC set (and therefore
+ has no real bits on the disk). */
+ if (!som_is_subspace (subsection)
+ || !som_is_container (section, subsection)
+ || (subsection->flags & SEC_ALLOC) == 0)
+ continue;
+
+ /* If this is the first subspace for this space, then save
+ the index of the subspace in its containing space. Also
+ set "is_loadable" in the containing space. */
+
+ if (som_section_data (section)->space_dict->subspace_quantity == 0)
+ {
+ som_section_data (section)->space_dict->is_loadable = 1;
+ som_section_data (section)->space_dict->subspace_index
+ = subspace_index;
+ }
+
+ /* Increment the number of subspaces seen and the number of
+ subspaces contained within the current space. */
+ subspace_index++;
+ som_section_data (section)->space_dict->subspace_quantity++;
+
+ /* Mark the index of the current space within the subspace's
+ dictionary record. */
+ som_section_data (subsection)->subspace_dict->space_index = i;
+
+ /* Dump the current subspace header. */
+ if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict,
+ sizeof (struct subspace_dictionary_record), 1, abfd)
+ != sizeof (struct subspace_dictionary_record))
+ return false;
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* Now repeat the process for unloadable subspaces. */
+ section = abfd->sections;
+ /* Now for each space write out records for its subspaces. */
+ for (i = 0; i < num_spaces; i++)
+ {
+ asection *subsection;
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ /* Now look for all its subspaces. */
+ for (subsection = abfd->sections;
+ subsection != NULL;
+ subsection = subsection->next)
+ {
+
+ /* Skip any section which does not correspond to a space or
+ subspace, or which SEC_ALLOC set (and therefore handled
+ in the loadable spaces/subspaces code above). */
+
+ if (!som_is_subspace (subsection)
+ || !som_is_container (section, subsection)
+ || (subsection->flags & SEC_ALLOC) != 0)
+ continue;
+
+ /* If this is the first subspace for this space, then save
+ the index of the subspace in its containing space. Clear
+ "is_loadable". */
+
+ if (som_section_data (section)->space_dict->subspace_quantity == 0)
+ {
+ som_section_data (section)->space_dict->is_loadable = 0;
+ som_section_data (section)->space_dict->subspace_index
+ = subspace_index;
+ }
+
+ /* Increment the number of subspaces seen and the number of
+ subspaces contained within the current space. */
+ som_section_data (section)->space_dict->subspace_quantity++;
+ subspace_index++;
+
+ /* Mark the index of the current space within the subspace's
+ dictionary record. */
+ som_section_data (subsection)->subspace_dict->space_index = i;
+
+ /* Dump this subspace header. */
+ if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict,
+ sizeof (struct subspace_dictionary_record), 1, abfd)
+ != sizeof (struct subspace_dictionary_record))
+ return false;
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* All the subspace dictiondary records are written, and all the
+ fields are set up in the space dictionary records.
+
+ Seek to the right location and start writing the space
+ dictionary records. */
+ location = obj_som_file_hdr (abfd)->space_location;
+ if (bfd_seek (abfd, location, SEEK_SET) < 0)
+ return false;
+
+ section = abfd->sections;
+ for (i = 0; i < num_spaces; i++)
+ {
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ /* Dump its header */
+ if (bfd_write ((PTR) som_section_data (section)->space_dict,
+ sizeof (struct space_dictionary_record), 1, abfd)
+ != sizeof (struct space_dictionary_record))
+ return false;
+
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* Write the compilation unit record if there is one. */
+ if (obj_som_compilation_unit (abfd))
+ {
+ location = obj_som_file_hdr (abfd)->compiler_location;
+ if (bfd_seek (abfd, location, SEEK_SET) < 0)
+ return false;
+
+ if (bfd_write ((PTR) obj_som_compilation_unit (abfd),
+ COMPUNITSZ, 1, abfd) != COMPUNITSZ)
+ return false;
+ }
+
+ /* Setting of the system_id has to happen very late now that copying of
+ BFD private data happens *after* section contents are set. */
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ obj_som_file_hdr(abfd)->system_id = obj_som_exec_data (abfd)->system_id;
+ else if (bfd_get_mach (abfd) == pa20)
+ obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC2_0;
+ else if (bfd_get_mach (abfd) == pa11)
+ obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_1;
+ else
+ obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_0;
+
+ /* Compute the checksum for the file header just before writing
+ the header to disk. */
+ obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd);
+
+ /* Only thing left to do is write out the file header. It is always
+ at location zero. Seek there and write it. */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0)
+ return false;
+ if (bfd_write ((PTR) obj_som_file_hdr (abfd),
+ sizeof (struct header), 1, abfd)
+ != sizeof (struct header))
+ return false;
+
+ /* Now write the exec header. */
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ {
+ long tmp, som_length;
+ struct som_exec_auxhdr *exec_header;
+
+ exec_header = obj_som_exec_hdr (abfd);
+ exec_header->exec_entry = bfd_get_start_address (abfd);
+ exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags;
+
+ /* Oh joys. Ram some of the BSS data into the DATA section
+ to be compatable with how the hp linker makes objects
+ (saves memory space). */
+ tmp = exec_header->exec_dsize;
+ tmp = SOM_ALIGN (tmp, PA_PAGESIZE);
+ exec_header->exec_bsize -= (tmp - exec_header->exec_dsize);
+ if (exec_header->exec_bsize < 0)
+ exec_header->exec_bsize = 0;
+ exec_header->exec_dsize = tmp;
+
+ /* Now perform some sanity checks. The idea is to catch bogons now and
+ inform the user, instead of silently generating a bogus file. */
+ som_length = obj_som_file_hdr (abfd)->som_length;
+ if (exec_header->exec_tfile + exec_header->exec_tsize > som_length
+ || exec_header->exec_dfile + exec_header->exec_dsize > som_length)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location,
+ SEEK_SET) < 0)
+ return false;
+
+ if (bfd_write ((PTR) exec_header, AUX_HDR_SIZE, 1, abfd)
+ != AUX_HDR_SIZE)
+ return false;
+ }
+ return true;
+}
+
+/* Compute and return the checksum for a SOM file header. */
+
+static unsigned long
+som_compute_checksum (abfd)
+ bfd *abfd;
+{
+ unsigned long checksum, count, i;
+ unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd);
+
+ checksum = 0;
+ count = sizeof (struct header) / sizeof (unsigned long);
+ for (i = 0; i < count; i++)
+ checksum ^= *(buffer + i);
+
+ return checksum;
+}
+
+static void
+som_bfd_derive_misc_symbol_info (abfd, sym, info)
+ bfd *abfd;
+ asymbol *sym;
+ struct som_misc_symbol_info *info;
+{
+ /* Initialize. */
+ memset (info, 0, sizeof (struct som_misc_symbol_info));
+
+ /* The HP SOM linker requires detailed type information about
+ all symbols (including undefined symbols!). Unfortunately,
+ the type specified in an import/export statement does not
+ always match what the linker wants. Severe braindamage. */
+
+ /* Section symbols will not have a SOM symbol type assigned to
+ them yet. Assign all section symbols type ST_DATA. */
+ if (sym->flags & BSF_SECTION_SYM)
+ info->symbol_type = ST_DATA;
+ else
+ {
+ /* Common symbols must have scope SS_UNSAT and type
+ ST_STORAGE or the linker will choke. */
+ if (bfd_is_com_section (sym->section))
+ {
+ info->symbol_scope = SS_UNSAT;
+ info->symbol_type = ST_STORAGE;
+ }
+
+ /* It is possible to have a symbol without an associated
+ type. This happens if the user imported the symbol
+ without a type and the symbol was never defined
+ locally. If BSF_FUNCTION is set for this symbol, then
+ assign it type ST_CODE (the HP linker requires undefined
+ external functions to have type ST_CODE rather than ST_ENTRY). */
+ else if ((som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
+ || som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
+ && bfd_is_und_section (sym->section)
+ && sym->flags & BSF_FUNCTION)
+ info->symbol_type = ST_CODE;
+
+ /* Handle function symbols which were defined in this file.
+ They should have type ST_ENTRY. Also retrieve the argument
+ relocation bits from the SOM backend information. */
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY
+ || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE
+ && (sym->flags & BSF_FUNCTION))
+ || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN
+ && (sym->flags & BSF_FUNCTION)))
+ {
+ info->symbol_type = ST_ENTRY;
+ info->arg_reloc = som_symbol_data (sym)->tc_data.ap.hppa_arg_reloc;
+ info->priv_level= som_symbol_data (sym)->tc_data.ap.hppa_priv_level;
+ }
+
+ /* For unknown symbols set the symbol's type based on the symbol's
+ section (ST_DATA for DATA sections, ST_CODE for CODE sections). */
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
+ {
+ if (sym->section->flags & SEC_CODE)
+ info->symbol_type = ST_CODE;
+ else
+ info->symbol_type = ST_DATA;
+ }
+
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
+ info->symbol_type = ST_DATA;
+
+ /* From now on it's a very simple mapping. */
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
+ info->symbol_type = ST_ABSOLUTE;
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE)
+ info->symbol_type = ST_CODE;
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA)
+ info->symbol_type = ST_DATA;
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE)
+ info->symbol_type = ST_MILLICODE;
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL)
+ info->symbol_type = ST_PLABEL;
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG)
+ info->symbol_type = ST_PRI_PROG;
+ else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG)
+ info->symbol_type = ST_SEC_PROG;
+ }
+
+ /* Now handle the symbol's scope. Exported data which is not
+ in the common section has scope SS_UNIVERSAL. Note scope
+ of common symbols was handled earlier! */
+ if (bfd_is_und_section (sym->section))
+ info->symbol_scope = SS_UNSAT;
+ else if (sym->flags & BSF_EXPORT && ! bfd_is_com_section (sym->section))
+ info->symbol_scope = SS_UNIVERSAL;
+ /* Anything else which is not in the common section has scope
+ SS_LOCAL. */
+ else if (! bfd_is_com_section (sym->section))
+ info->symbol_scope = SS_LOCAL;
+
+ /* Now set the symbol_info field. It has no real meaning
+ for undefined or common symbols, but the HP linker will
+ choke if it's not set to some "reasonable" value. We
+ use zero as a reasonable value. */
+ if (bfd_is_com_section (sym->section)
+ || bfd_is_und_section (sym->section)
+ || bfd_is_abs_section (sym->section))
+ info->symbol_info = 0;
+ /* For all other symbols, the symbol_info field contains the
+ subspace index of the space this symbol is contained in. */
+ else
+ info->symbol_info = sym->section->target_index;
+
+ /* Set the symbol's value. */
+ info->symbol_value = sym->value + sym->section->vma;
+}
+
+/* Build and write, in one big chunk, the entire symbol table for
+ this BFD. */
+
+static boolean
+som_build_and_write_symbol_table (abfd)
+ bfd *abfd;
+{
+ unsigned int num_syms = bfd_get_symcount (abfd);
+ file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location;
+ asymbol **bfd_syms = obj_som_sorted_syms (abfd);
+ struct symbol_dictionary_record *som_symtab = NULL;
+ int i, symtab_size;
+
+ /* Compute total symbol table size and allocate a chunk of memory
+ to hold the symbol table as we build it. */
+ symtab_size = num_syms * sizeof (struct symbol_dictionary_record);
+ som_symtab = (struct symbol_dictionary_record *) bfd_malloc (symtab_size);
+ if (som_symtab == NULL && symtab_size != 0)
+ goto error_return;
+ memset (som_symtab, 0, symtab_size);
+
+ /* Walk over each symbol. */
+ for (i = 0; i < num_syms; i++)
+ {
+ struct som_misc_symbol_info info;
+
+ /* This is really an index into the symbol strings table.
+ By the time we get here, the index has already been
+ computed and stored into the name field in the BFD symbol. */
+ som_symtab[i].name.n_strx = som_symbol_data(bfd_syms[i])->stringtab_offset;
+
+ /* Derive SOM information from the BFD symbol. */
+ som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info);
+
+ /* Now use it. */
+ som_symtab[i].symbol_type = info.symbol_type;
+ som_symtab[i].symbol_scope = info.symbol_scope;
+ som_symtab[i].arg_reloc = info.arg_reloc;
+ som_symtab[i].symbol_info = info.symbol_info;
+ som_symtab[i].xleast = 3;
+ som_symtab[i].symbol_value = info.symbol_value | info.priv_level;
+ }
+
+ /* Everything is ready, seek to the right location and
+ scribble out the symbol table. */
+ if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0)
+ return false;
+
+ if (bfd_write ((PTR) som_symtab, symtab_size, 1, abfd) != symtab_size)
+ goto error_return;
+
+ if (som_symtab != NULL)
+ free (som_symtab);
+ return true;
+ error_return:
+ if (som_symtab != NULL)
+ free (som_symtab);
+ return false;
+}
+
+/* Write an object in SOM format. */
+
+static boolean
+som_write_object_contents (abfd)
+ bfd *abfd;
+{
+ if (abfd->output_has_begun == false)
+ {
+ /* Set up fixed parts of the file, space, and subspace headers.
+ Notify the world that output has begun. */
+ som_prep_headers (abfd);
+ abfd->output_has_begun = true;
+ /* Start writing the object file. This include all the string
+ tables, fixup streams, and other portions of the object file. */
+ som_begin_writing (abfd);
+ }
+
+ return (som_finish_writing (abfd));
+}
+
+
+/* Read and save the string table associated with the given BFD. */
+
+static boolean
+som_slurp_string_table (abfd)
+ bfd *abfd;
+{
+ char *stringtab;
+
+ /* Use the saved version if its available. */
+ if (obj_som_stringtab (abfd) != NULL)
+ return true;
+
+ /* I don't think this can currently happen, and I'm not sure it should
+ really be an error, but it's better than getting unpredictable results
+ from the host's malloc when passed a size of zero. */
+ if (obj_som_stringtab_size (abfd) == 0)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return false;
+ }
+
+ /* Allocate and read in the string table. */
+ stringtab = bfd_malloc (obj_som_stringtab_size (abfd));
+ if (stringtab == NULL)
+ return false;
+ memset (stringtab, 0, obj_som_stringtab_size (abfd));
+
+ if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0)
+ return false;
+
+ if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd)
+ != obj_som_stringtab_size (abfd))
+ return false;
+
+ /* Save our results and return success. */
+ obj_som_stringtab (abfd) = stringtab;
+ return true;
+}
+
+/* Return the amount of data (in bytes) required to hold the symbol
+ table for this object. */
+
+static long
+som_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ if (!som_slurp_symbol_table (abfd))
+ return -1;
+
+ return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *));
+}
+
+/* Convert from a SOM subspace index to a BFD section. */
+
+static asection *
+bfd_section_from_som_symbol (abfd, symbol)
+ bfd *abfd;
+ struct symbol_dictionary_record *symbol;
+{
+ asection *section;
+
+ /* The meaning of the symbol_info field changes for functions
+ within executables. So only use the quick symbol_info mapping for
+ incomplete objects and non-function symbols in executables. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
+ || (symbol->symbol_type != ST_ENTRY
+ && symbol->symbol_type != ST_PRI_PROG
+ && symbol->symbol_type != ST_SEC_PROG
+ && symbol->symbol_type != ST_MILLICODE))
+ {
+ unsigned int index = symbol->symbol_info;
+ for (section = abfd->sections; section != NULL; section = section->next)
+ if (section->target_index == index && som_is_subspace (section))
+ return section;
+
+ /* Could be a symbol from an external library (such as an OMOS
+ shared library). Don't abort. */
+ return bfd_abs_section_ptr;
+
+ }
+ else
+ {
+ unsigned int value = symbol->symbol_value;
+
+ /* For executables we will have to use the symbol's address and
+ find out what section would contain that address. Yuk. */
+ for (section = abfd->sections; section; section = section->next)
+ {
+ if (value >= section->vma
+ && value <= section->vma + section->_cooked_size
+ && som_is_subspace (section))
+ return section;
+ }
+
+ /* Could be a symbol from an external library (such as an OMOS
+ shared library). Don't abort. */
+ return bfd_abs_section_ptr;
+
+ }
+}
+
+/* Read and save the symbol table associated with the given BFD. */
+
+static unsigned int
+som_slurp_symbol_table (abfd)
+ bfd *abfd;
+{
+ int symbol_count = bfd_get_symcount (abfd);
+ int symsize = sizeof (struct symbol_dictionary_record);
+ char *stringtab;
+ struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
+ som_symbol_type *sym, *symbase;
+
+ /* Return saved value if it exists. */
+ if (obj_som_symtab (abfd) != NULL)
+ goto successful_return;
+
+ /* Special case. This is *not* an error. */
+ if (symbol_count == 0)
+ goto successful_return;
+
+ if (!som_slurp_string_table (abfd))
+ goto error_return;
+
+ stringtab = obj_som_stringtab (abfd);
+
+ symbase = ((som_symbol_type *)
+ bfd_malloc (symbol_count * sizeof (som_symbol_type)));
+ if (symbase == NULL)
+ goto error_return;
+ memset (symbase, 0, symbol_count * sizeof (som_symbol_type));
+
+ /* Read in the external SOM representation. */
+ buf = bfd_malloc (symbol_count * symsize);
+ if (buf == NULL && symbol_count * symsize != 0)
+ goto error_return;
+ if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0)
+ goto error_return;
+ if (bfd_read (buf, symbol_count * symsize, 1, abfd)
+ != symbol_count * symsize)
+ goto error_return;
+
+ /* Iterate over all the symbols and internalize them. */
+ endbufp = buf + symbol_count;
+ for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
+ {
+
+ /* I don't think we care about these. */
+ if (bufp->symbol_type == ST_SYM_EXT
+ || bufp->symbol_type == ST_ARG_EXT)
+ continue;
+
+ /* Set some private data we care about. */
+ if (bufp->symbol_type == ST_NULL)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
+ else if (bufp->symbol_type == ST_ABSOLUTE)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
+ else if (bufp->symbol_type == ST_DATA)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
+ else if (bufp->symbol_type == ST_CODE)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
+ else if (bufp->symbol_type == ST_PRI_PROG)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
+ else if (bufp->symbol_type == ST_SEC_PROG)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
+ else if (bufp->symbol_type == ST_ENTRY)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
+ else if (bufp->symbol_type == ST_MILLICODE)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
+ else if (bufp->symbol_type == ST_PLABEL)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL;
+ else
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
+ som_symbol_data (sym)->tc_data.ap.hppa_arg_reloc = bufp->arg_reloc;
+
+ /* Some reasonable defaults. */
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bufp->name.n_strx + stringtab;
+ sym->symbol.value = bufp->symbol_value;
+ sym->symbol.section = 0;
+ sym->symbol.flags = 0;
+
+ switch (bufp->symbol_type)
+ {
+ case ST_ENTRY:
+ case ST_MILLICODE:
+ sym->symbol.flags |= BSF_FUNCTION;
+ som_symbol_data (sym)->tc_data.ap.hppa_priv_level =
+ sym->symbol.value & 0x3;
+ sym->symbol.value &= ~0x3;
+ break;
+
+ case ST_STUB:
+ case ST_CODE:
+ case ST_PRI_PROG:
+ case ST_SEC_PROG:
+ som_symbol_data (sym)->tc_data.ap.hppa_priv_level =
+ sym->symbol.value & 0x3;
+ sym->symbol.value &= ~0x3;
+ /* If the symbol's scope is ST_UNSAT, then these are
+ undefined function symbols. */
+ if (bufp->symbol_scope == SS_UNSAT)
+ sym->symbol.flags |= BSF_FUNCTION;
+
+
+ default:
+ break;
+ }
+
+ /* Handle scoping and section information. */
+ switch (bufp->symbol_scope)
+ {
+ /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols,
+ so the section associated with this symbol can't be known. */
+ case SS_EXTERNAL:
+ if (bufp->symbol_type != ST_STORAGE)
+ sym->symbol.section = bfd_und_section_ptr;
+ else
+ sym->symbol.section = bfd_com_section_ptr;
+ sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
+ break;
+
+ case SS_UNSAT:
+ if (bufp->symbol_type != ST_STORAGE)
+ sym->symbol.section = bfd_und_section_ptr;
+ else
+ sym->symbol.section = bfd_com_section_ptr;
+ break;
+
+ case SS_UNIVERSAL:
+ sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL);
+ sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
+ sym->symbol.value -= sym->symbol.section->vma;
+ break;
+
+#if 0
+ /* SS_GLOBAL and SS_LOCAL are two names for the same thing.
+ Sound dumb? It is. */
+ case SS_GLOBAL:
+#endif
+ case SS_LOCAL:
+ sym->symbol.flags |= BSF_LOCAL;
+ sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp);
+ sym->symbol.value -= sym->symbol.section->vma;
+ break;
+ }
+
+ /* Mark section symbols and symbols used by the debugger.
+ Note $START$ is a magic code symbol, NOT a section symbol. */
+ if (sym->symbol.name[0] == '$'
+ && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$'
+ && !strcmp (sym->symbol.name, sym->symbol.section->name))
+ sym->symbol.flags |= BSF_SECTION_SYM;
+ else if (!strncmp (sym->symbol.name, "L$0\002", 4))
+ {
+ sym->symbol.flags |= BSF_SECTION_SYM;
+ sym->symbol.name = sym->symbol.section->name;
+ }
+ else if (!strncmp (sym->symbol.name, "L$0\001", 4))
+ sym->symbol.flags |= BSF_DEBUGGING;
+
+ /* Note increment at bottom of loop, since we skip some symbols
+ we can not include it as part of the for statement. */
+ sym++;
+ }
+
+ /* We modify the symbol count to record the number of BFD symbols we
+ created. */
+ bfd_get_symcount (abfd) = sym - symbase;
+
+ /* Save our results and return success. */
+ obj_som_symtab (abfd) = symbase;
+ successful_return:
+ if (buf != NULL)
+ free (buf);
+ return (true);
+
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ return false;
+}
+
+/* Canonicalize a SOM symbol table. Return the number of entries
+ in the symbol table. */
+
+static long
+som_get_symtab (abfd, location)
+ bfd *abfd;
+ asymbol **location;
+{
+ int i;
+ som_symbol_type *symbase;
+
+ if (!som_slurp_symbol_table (abfd))
+ return -1;
+
+ i = bfd_get_symcount (abfd);
+ symbase = obj_som_symtab (abfd);
+
+ for (; i > 0; i--, location++, symbase++)
+ *location = &symbase->symbol;
+
+ /* Final null pointer. */
+ *location = 0;
+ return (bfd_get_symcount (abfd));
+}
+
+/* Make a SOM symbol. There is nothing special to do here. */
+
+static asymbol *
+som_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ som_symbol_type *new =
+ (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type));
+ if (new == NULL)
+ return 0;
+ new->symbol.the_bfd = abfd;
+
+ return &new->symbol;
+}
+
+/* Print symbol information. */
+
+static void
+som_print_symbol (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ fprintf (file, "som ");
+ fprintf_vma (file, symbol->value);
+ fprintf (file, " %lx", (long) symbol->flags);
+ break;
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name;
+ section_name = symbol->section ? symbol->section->name : "(*none*)";
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %s\t%s", section_name, symbol->name);
+ break;
+ }
+ }
+}
+
+static boolean
+som_bfd_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ return (name[0] == 'L' && name[1] == '$');
+}
+
+/* Count or process variable-length SOM fixup records.
+
+ To avoid code duplication we use this code both to compute the number
+ of relocations requested by a stream, and to internalize the stream.
+
+ When computing the number of relocations requested by a stream the
+ variables rptr, section, and symbols have no meaning.
+
+ Return the number of relocations requested by the fixup stream. When
+ not just counting
+
+ This needs at least two or three more passes to get it cleaned up. */
+
+static unsigned int
+som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count)
+ unsigned char *fixup;
+ unsigned int end;
+ arelent *internal_relocs;
+ asection *section;
+ asymbol **symbols;
+ boolean just_count;
+{
+ unsigned int op, varname, deallocate_contents = 0;
+ unsigned char *end_fixups = &fixup[end];
+ const struct fixup_format *fp;
+ char *cp;
+ unsigned char *save_fixup;
+ int variables[26], stack[20], c, v, count, prev_fixup, *sp, saved_unwind_bits;
+ const int *subop;
+ arelent *rptr= internal_relocs;
+ unsigned int offset = 0;
+
+#define var(c) variables[(c) - 'A']
+#define push(v) (*sp++ = (v))
+#define pop() (*--sp)
+#define emptystack() (sp == stack)
+
+ som_initialize_reloc_queue (reloc_queue);
+ memset (variables, 0, sizeof (variables));
+ memset (stack, 0, sizeof (stack));
+ count = 0;
+ prev_fixup = 0;
+ saved_unwind_bits = 0;
+ sp = stack;
+
+ while (fixup < end_fixups)
+ {
+
+ /* Save pointer to the start of this fixup. We'll use
+ it later to determine if it is necessary to put this fixup
+ on the queue. */
+ save_fixup = fixup;
+
+ /* Get the fixup code and its associated format. */
+ op = *fixup++;
+ fp = &som_fixup_formats[op];
+
+ /* Handle a request for a previous fixup. */
+ if (*fp->format == 'P')
+ {
+ /* Get pointer to the beginning of the prev fixup, move
+ the repeated fixup to the head of the queue. */
+ fixup = reloc_queue[fp->D].reloc;
+ som_reloc_queue_fix (reloc_queue, fp->D);
+ prev_fixup = 1;
+
+ /* Get the fixup code and its associated format. */
+ op = *fixup++;
+ fp = &som_fixup_formats[op];
+ }
+
+ /* If this fixup will be passed to BFD, set some reasonable defaults. */
+ if (! just_count
+ && som_hppa_howto_table[op].type != R_NO_RELOCATION
+ && som_hppa_howto_table[op].type != R_DATA_OVERRIDE)
+ {
+ rptr->address = offset;
+ rptr->howto = &som_hppa_howto_table[op];
+ rptr->addend = 0;
+ rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+
+ /* Set default input length to 0. Get the opcode class index
+ into D. */
+ var ('L') = 0;
+ var ('D') = fp->D;
+ var ('U') = saved_unwind_bits;
+
+ /* Get the opcode format. */
+ cp = fp->format;
+
+ /* Process the format string. Parsing happens in two phases,
+ parse RHS, then assign to LHS. Repeat until no more
+ characters in the format string. */
+ while (*cp)
+ {
+ /* The variable this pass is going to compute a value for. */
+ varname = *cp++;
+
+ /* Start processing RHS. Continue until a NULL or '=' is found. */
+ do
+ {
+ c = *cp++;
+
+ /* If this is a variable, push it on the stack. */
+ if (isupper (c))
+ push (var (c));
+
+ /* If this is a lower case letter, then it represents
+ additional data from the fixup stream to be pushed onto
+ the stack. */
+ else if (islower (c))
+ {
+ int bits = (c - 'a') * 8;
+ for (v = 0; c > 'a'; --c)
+ v = (v << 8) | *fixup++;
+ if (varname == 'V')
+ v = sign_extend (v, bits);
+ push (v);
+ }
+
+ /* A decimal constant. Push it on the stack. */
+ else if (isdigit (c))
+ {
+ v = c - '0';
+ while (isdigit (*cp))
+ v = (v * 10) + (*cp++ - '0');
+ push (v);
+ }
+ else
+
+ /* An operator. Pop two two values from the stack and
+ use them as operands to the given operation. Push
+ the result of the operation back on the stack. */
+ switch (c)
+ {
+ case '+':
+ v = pop ();
+ v += pop ();
+ push (v);
+ break;
+ case '*':
+ v = pop ();
+ v *= pop ();
+ push (v);
+ break;
+ case '<':
+ v = pop ();
+ v = pop () << v;
+ push (v);
+ break;
+ default:
+ abort ();
+ }
+ }
+ while (*cp && *cp != '=');
+
+ /* Move over the equal operator. */
+ cp++;
+
+ /* Pop the RHS off the stack. */
+ c = pop ();
+
+ /* Perform the assignment. */
+ var (varname) = c;
+
+ /* Handle side effects. and special 'O' stack cases. */
+ switch (varname)
+ {
+ /* Consume some bytes from the input space. */
+ case 'L':
+ offset += c;
+ break;
+ /* A symbol to use in the relocation. Make a note
+ of this if we are not just counting. */
+ case 'S':
+ if (! just_count)
+ rptr->sym_ptr_ptr = &symbols[c];
+ break;
+ /* Argument relocation bits for a function call. */
+ case 'R':
+ if (! just_count)
+ {
+ unsigned int tmp = var ('R');
+ rptr->addend = 0;
+
+ if ((som_hppa_howto_table[op].type == R_PCREL_CALL
+ && R_PCREL_CALL + 10 > op)
+ || (som_hppa_howto_table[op].type == R_ABS_CALL
+ && R_ABS_CALL + 10 > op))
+ {
+ /* Simple encoding. */
+ if (tmp > 4)
+ {
+ tmp -= 5;
+ rptr->addend |= 1;
+ }
+ if (tmp == 4)
+ rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2;
+ else if (tmp == 3)
+ rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4;
+ else if (tmp == 2)
+ rptr->addend |= 1 << 8 | 1 << 6;
+ else if (tmp == 1)
+ rptr->addend |= 1 << 8;
+ }
+ else
+ {
+ unsigned int tmp1, tmp2;
+
+ /* First part is easy -- low order two bits are
+ directly copied, then shifted away. */
+ rptr->addend = tmp & 0x3;
+ tmp >>= 2;
+
+ /* Diving the result by 10 gives us the second
+ part. If it is 9, then the first two words
+ are a double precision paramater, else it is
+ 3 * the first arg bits + the 2nd arg bits. */
+ tmp1 = tmp / 10;
+ tmp -= tmp1 * 10;
+ if (tmp1 == 9)
+ rptr->addend += (0xe << 6);
+ else
+ {
+ /* Get the two pieces. */
+ tmp2 = tmp1 / 3;
+ tmp1 -= tmp2 * 3;
+ /* Put them in the addend. */
+ rptr->addend += (tmp2 << 8) + (tmp1 << 6);
+ }
+
+ /* What's left is the third part. It's unpacked
+ just like the second. */
+ if (tmp == 9)
+ rptr->addend += (0xe << 2);
+ else
+ {
+ tmp2 = tmp / 3;
+ tmp -= tmp2 * 3;
+ rptr->addend += (tmp2 << 4) + (tmp << 2);
+ }
+ }
+ rptr->addend = HPPA_R_ADDEND (rptr->addend, 0);
+ }
+ break;
+ /* Handle the linker expression stack. */
+ case 'O':
+ switch (op)
+ {
+ case R_COMP1:
+ subop = comp1_opcodes;
+ break;
+ case R_COMP2:
+ subop = comp2_opcodes;
+ break;
+ case R_COMP3:
+ subop = comp3_opcodes;
+ break;
+ default:
+ abort ();
+ }
+ while (*subop <= (unsigned char) c)
+ ++subop;
+ --subop;
+ break;
+ /* The lower 32unwind bits must be persistent. */
+ case 'U':
+ saved_unwind_bits = var ('U');
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* If we used a previous fixup, clean up after it. */
+ if (prev_fixup)
+ {
+ fixup = save_fixup + 1;
+ prev_fixup = 0;
+ }
+ /* Queue it. */
+ else if (fixup > save_fixup + 1)
+ som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue);
+
+ /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION
+ fixups to BFD. */
+ if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE
+ && som_hppa_howto_table[op].type != R_NO_RELOCATION)
+ {
+ /* Done with a single reloction. Loop back to the top. */
+ if (! just_count)
+ {
+ if (som_hppa_howto_table[op].type == R_ENTRY)
+ rptr->addend = var ('T');
+ else if (som_hppa_howto_table[op].type == R_EXIT)
+ rptr->addend = var ('U');
+ else if (som_hppa_howto_table[op].type == R_PCREL_CALL
+ || som_hppa_howto_table[op].type == R_ABS_CALL)
+ ;
+ else if (som_hppa_howto_table[op].type == R_DATA_ONE_SYMBOL)
+ {
+ unsigned addend = var ('V');
+
+ /* Try what was specified in R_DATA_OVERRIDE first
+ (if anything). Then the hard way using the
+ section contents. */
+ rptr->addend = var ('V');
+
+ if (rptr->addend == 0 && !section->contents)
+ {
+ /* Got to read the damn contents first. We don't
+ bother saving the contents (yet). Add it one
+ day if the need arises. */
+ section->contents = bfd_malloc (section->_raw_size);
+ if (section->contents == NULL)
+ return -1;
+
+ deallocate_contents = 1;
+ bfd_get_section_contents (section->owner,
+ section,
+ section->contents,
+ 0,
+ section->_raw_size);
+ }
+ else if (rptr->addend == 0)
+ rptr->addend = bfd_get_32 (section->owner,
+ (section->contents
+ + offset - var ('L')));
+
+ }
+ else
+ rptr->addend = var ('V');
+ rptr++;
+ }
+ count++;
+ /* Now that we've handled a "full" relocation, reset
+ some state. */
+ memset (variables, 0, sizeof (variables));
+ memset (stack, 0, sizeof (stack));
+ }
+ }
+ if (deallocate_contents)
+ free (section->contents);
+
+ return count;
+
+#undef var
+#undef push
+#undef pop
+#undef emptystack
+}
+
+/* Read in the relocs (aka fixups in SOM terms) for a section.
+
+ som_get_reloc_upper_bound calls this routine with JUST_COUNT
+ set to true to indicate it only needs a count of the number
+ of actual relocations. */
+
+static boolean
+som_slurp_reloc_table (abfd, section, symbols, just_count)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ boolean just_count;
+{
+ char *external_relocs;
+ unsigned int fixup_stream_size;
+ arelent *internal_relocs;
+ unsigned int num_relocs;
+
+ fixup_stream_size = som_section_data (section)->reloc_size;
+ /* If there were no relocations, then there is nothing to do. */
+ if (section->reloc_count == 0)
+ return true;
+
+ /* If reloc_count is -1, then the relocation stream has not been
+ parsed. We must do so now to know how many relocations exist. */
+ if (section->reloc_count == -1)
+ {
+ external_relocs = (char *) bfd_malloc (fixup_stream_size);
+ if (external_relocs == (char *) NULL)
+ return false;
+ /* Read in the external forms. */
+ if (bfd_seek (abfd,
+ obj_som_reloc_filepos (abfd) + section->rel_filepos,
+ SEEK_SET)
+ != 0)
+ return false;
+ if (bfd_read (external_relocs, 1, fixup_stream_size, abfd)
+ != fixup_stream_size)
+ return false;
+
+ /* Let callers know how many relocations found.
+ also save the relocation stream as we will
+ need it again. */
+ section->reloc_count = som_set_reloc_info (external_relocs,
+ fixup_stream_size,
+ NULL, NULL, NULL, true);
+
+ som_section_data (section)->reloc_stream = external_relocs;
+ }
+
+ /* If the caller only wanted a count, then return now. */
+ if (just_count)
+ return true;
+
+ num_relocs = section->reloc_count;
+ external_relocs = som_section_data (section)->reloc_stream;
+ /* Return saved information about the relocations if it is available. */
+ if (section->relocation != (arelent *) NULL)
+ return true;
+
+ internal_relocs = (arelent *)
+ bfd_zalloc (abfd, (num_relocs * sizeof (arelent)));
+ if (internal_relocs == (arelent *) NULL)
+ return false;
+
+ /* Process and internalize the relocations. */
+ som_set_reloc_info (external_relocs, fixup_stream_size,
+ internal_relocs, section, symbols, false);
+
+ /* We're done with the external relocations. Free them. */
+ free (external_relocs);
+ som_section_data (section)->reloc_stream = NULL;
+
+ /* Save our results and return success. */
+ section->relocation = internal_relocs;
+ return (true);
+}
+
+/* Return the number of bytes required to store the relocation
+ information associated with the given section. */
+
+static long
+som_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ /* If section has relocations, then read in the relocation stream
+ and parse it to determine how many relocations exist. */
+ if (asect->flags & SEC_RELOC)
+ {
+ if (! som_slurp_reloc_table (abfd, asect, NULL, true))
+ return -1;
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+ }
+ /* There are no relocations. */
+ return 0;
+}
+
+/* Convert relocations from SOM (external) form into BFD internal
+ form. Return the number of relocations. */
+
+static long
+som_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ arelent *tblptr;
+ int count;
+
+ if (som_slurp_reloc_table (abfd, section, symbols, false) == false)
+ return -1;
+
+ count = section->reloc_count;
+ tblptr = section->relocation;
+
+ while (count--)
+ *relptr++ = tblptr++;
+
+ *relptr = (arelent *) NULL;
+ return section->reloc_count;
+}
+
+extern const bfd_target som_vec;
+
+/* A hook to set up object file dependent section information. */
+
+static boolean
+som_new_section_hook (abfd, newsect)
+ bfd *abfd;
+ asection *newsect;
+{
+ newsect->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct));
+ if (!newsect->used_by_bfd)
+ return false;
+ newsect->alignment_power = 3;
+
+ /* We allow more than three sections internally */
+ return true;
+}
+
+/* Copy any private info we understand from the input symbol
+ to the output symbol. */
+
+static boolean
+som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
+ bfd *ibfd;
+ asymbol *isymbol;
+ bfd *obfd;
+ asymbol *osymbol;
+{
+ struct som_symbol *input_symbol = (struct som_symbol *) isymbol;
+ struct som_symbol *output_symbol = (struct som_symbol *) osymbol;
+
+ /* One day we may try to grok other private data. */
+ if (ibfd->xvec->flavour != bfd_target_som_flavour
+ || obfd->xvec->flavour != bfd_target_som_flavour)
+ return false;
+
+ /* The only private information we need to copy is the argument relocation
+ bits. */
+ output_symbol->tc_data.ap.hppa_arg_reloc =
+ input_symbol->tc_data.ap.hppa_arg_reloc;
+
+ return true;
+}
+
+/* Copy any private info we understand from the input section
+ to the output section. */
+static boolean
+som_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
+ bfd *ibfd;
+ asection *isection;
+ bfd *obfd;
+ asection *osection;
+{
+ /* One day we may try to grok other private data. */
+ if (ibfd->xvec->flavour != bfd_target_som_flavour
+ || obfd->xvec->flavour != bfd_target_som_flavour
+ || (!som_is_space (isection) && !som_is_subspace (isection)))
+ return true;
+
+ som_section_data (osection)->copy_data
+ = (struct som_copyable_section_data_struct *)
+ bfd_zalloc (obfd, sizeof (struct som_copyable_section_data_struct));
+ if (som_section_data (osection)->copy_data == NULL)
+ return false;
+
+ memcpy (som_section_data (osection)->copy_data,
+ som_section_data (isection)->copy_data,
+ sizeof (struct som_copyable_section_data_struct));
+
+ /* Reparent if necessary. */
+ if (som_section_data (osection)->copy_data->container)
+ som_section_data (osection)->copy_data->container =
+ som_section_data (osection)->copy_data->container->output_section;
+
+ return true;
+}
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+static boolean
+som_bfd_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd, *obfd;
+{
+ /* One day we may try to grok other private data. */
+ if (ibfd->xvec->flavour != bfd_target_som_flavour
+ || obfd->xvec->flavour != bfd_target_som_flavour)
+ return true;
+
+ /* Allocate some memory to hold the data we need. */
+ obj_som_exec_data (obfd) = (struct som_exec_data *)
+ bfd_zalloc (obfd, sizeof (struct som_exec_data));
+ if (obj_som_exec_data (obfd) == NULL)
+ return false;
+
+ /* Now copy the data. */
+ memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd),
+ sizeof (struct som_exec_data));
+
+ return true;
+}
+
+/* Set backend info for sections which can not be described
+ in the BFD data structures. */
+
+boolean
+bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
+ asection *section;
+ int defined;
+ int private;
+ unsigned int sort_key;
+ int spnum;
+{
+ /* Allocate memory to hold the magic information. */
+ if (som_section_data (section)->copy_data == NULL)
+ {
+ som_section_data (section)->copy_data
+ = (struct som_copyable_section_data_struct *)
+ bfd_zalloc (section->owner,
+ sizeof (struct som_copyable_section_data_struct));
+ if (som_section_data (section)->copy_data == NULL)
+ return false;
+ }
+ som_section_data (section)->copy_data->sort_key = sort_key;
+ som_section_data (section)->copy_data->is_defined = defined;
+ som_section_data (section)->copy_data->is_private = private;
+ som_section_data (section)->copy_data->container = section;
+ som_section_data (section)->copy_data->space_number = spnum;
+ return true;
+}
+
+/* Set backend info for subsections which can not be described
+ in the BFD data structures. */
+
+boolean
+bfd_som_set_subsection_attributes (section, container, access,
+ sort_key, quadrant)
+ asection *section;
+ asection *container;
+ int access;
+ unsigned int sort_key;
+ int quadrant;
+{
+ /* Allocate memory to hold the magic information. */
+ if (som_section_data (section)->copy_data == NULL)
+ {
+ som_section_data (section)->copy_data
+ = (struct som_copyable_section_data_struct *)
+ bfd_zalloc (section->owner,
+ sizeof (struct som_copyable_section_data_struct));
+ if (som_section_data (section)->copy_data == NULL)
+ return false;
+ }
+ som_section_data (section)->copy_data->sort_key = sort_key;
+ som_section_data (section)->copy_data->access_control_bits = access;
+ som_section_data (section)->copy_data->quadrant = quadrant;
+ som_section_data (section)->copy_data->container = container;
+ return true;
+}
+
+/* Set the full SOM symbol type. SOM needs far more symbol information
+ than any other object file format I'm aware of. It is mandatory
+ to be able to know if a symbol is an entry point, millicode, data,
+ code, absolute, storage request, or procedure label. If you get
+ the symbol type wrong your program will not link. */
+
+void
+bfd_som_set_symbol_type (symbol, type)
+ asymbol *symbol;
+ unsigned int type;
+{
+ som_symbol_data (symbol)->som_type = type;
+}
+
+/* Attach an auxiliary header to the BFD backend so that it may be
+ written into the object file. */
+boolean
+bfd_som_attach_aux_hdr (abfd, type, string)
+ bfd *abfd;
+ int type;
+ char *string;
+{
+ if (type == VERSION_AUX_ID)
+ {
+ int len = strlen (string);
+ int pad = 0;
+
+ if (len % 4)
+ pad = (4 - (len % 4));
+ obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *)
+ bfd_zalloc (abfd, sizeof (struct aux_id)
+ + sizeof (unsigned int) + len + pad);
+ if (!obj_som_version_hdr (abfd))
+ return false;
+ obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID;
+ obj_som_version_hdr (abfd)->header_id.length = len + pad;
+ obj_som_version_hdr (abfd)->header_id.length += sizeof (int);
+ obj_som_version_hdr (abfd)->string_length = len;
+ strncpy (obj_som_version_hdr (abfd)->user_string, string, len);
+ }
+ else if (type == COPYRIGHT_AUX_ID)
+ {
+ int len = strlen (string);
+ int pad = 0;
+
+ if (len % 4)
+ pad = (4 - (len % 4));
+ obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *)
+ bfd_zalloc (abfd, sizeof (struct aux_id)
+ + sizeof (unsigned int) + len + pad);
+ if (!obj_som_copyright_hdr (abfd))
+ return false;
+ obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID;
+ obj_som_copyright_hdr (abfd)->header_id.length = len + pad;
+ obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int);
+ obj_som_copyright_hdr (abfd)->string_length = len;
+ strcpy (obj_som_copyright_hdr (abfd)->copyright, string);
+ }
+ return true;
+}
+
+/* Attach an compilation unit header to the BFD backend so that it may be
+ written into the object file. */
+
+boolean
+bfd_som_attach_compilation_unit (abfd, name, language_name, product_id,
+ version_id)
+ bfd *abfd;
+ const char *name;
+ const char *language_name;
+ const char *product_id;
+ const char *version_id;
+{
+ COMPUNIT *n = (COMPUNIT *) bfd_zalloc (abfd, COMPUNITSZ);
+ if (n == NULL)
+ return false;
+
+#define STRDUP(f) \
+ if (f != NULL) \
+ { \
+ n->f.n_name = bfd_alloc (abfd, strlen (f) + 1); \
+ if (n->f.n_name == NULL) \
+ return false; \
+ strcpy (n->f.n_name, f); \
+ }
+
+ STRDUP (name);
+ STRDUP (language_name);
+ STRDUP (product_id);
+ STRDUP (version_id);
+
+#undef STRDUP
+
+ obj_som_compilation_unit (abfd) = n;
+
+ return true;
+}
+
+static boolean
+som_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0))
+ return true;
+ if ((bfd_size_type)(offset+count) > section->_raw_size
+ || bfd_seek (abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
+ || bfd_read (location, (bfd_size_type)1, count, abfd) != count)
+ return (false); /* on error */
+ return (true);
+}
+
+static boolean
+som_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (abfd->output_has_begun == false)
+ {
+ /* Set up fixed parts of the file, space, and subspace headers.
+ Notify the world that output has begun. */
+ som_prep_headers (abfd);
+ abfd->output_has_begun = true;
+ /* Start writing the object file. This include all the string
+ tables, fixup streams, and other portions of the object file. */
+ som_begin_writing (abfd);
+ }
+
+ /* Only write subspaces which have "real" contents (eg. the contents
+ are not generated at run time by the OS). */
+ if (!som_is_subspace (section)
+ || ((section->flags & SEC_HAS_CONTENTS) == 0))
+ return true;
+
+ /* Seek to the proper offset within the object file and write the
+ data. */
+ offset += som_section_data (section)->subspace_dict->file_loc_init_value;
+ if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+ return false;
+
+ if (bfd_write ((PTR) location, 1, count, abfd) != count)
+ return false;
+ return true;
+}
+
+static boolean
+som_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ /* Allow any architecture to be supported by the SOM backend */
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+static boolean
+som_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
+ functionname_ptr, line_ptr)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ CONST char **filename_ptr;
+ CONST char **functionname_ptr;
+ unsigned int *line_ptr;
+{
+ return (false);
+}
+
+static int
+som_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+ (*_bfd_error_handler) (_("som_sizeof_headers unimplemented"));
+ fflush (stderr);
+ abort ();
+ return (0);
+}
+
+/* Return the single-character symbol type corresponding to
+ SOM section S, or '?' for an unknown SOM section. */
+
+static char
+som_section_type (s)
+ const char *s;
+{
+ const struct section_to_type *t;
+
+ for (t = &stt[0]; t->section; t++)
+ if (!strcmp (s, t->section))
+ return t->type;
+ return '?';
+}
+
+static int
+som_decode_symclass (symbol)
+ asymbol *symbol;
+{
+ char c;
+
+ if (bfd_is_com_section (symbol->section))
+ return 'C';
+ if (bfd_is_und_section (symbol->section))
+ return 'U';
+ if (bfd_is_ind_section (symbol->section))
+ return 'I';
+ if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
+ return '?';
+
+ if (bfd_is_abs_section (symbol->section)
+ || (som_symbol_data (symbol) != NULL
+ && som_symbol_data (symbol)->som_type == SYMBOL_TYPE_ABSOLUTE))
+ c = 'a';
+ else if (symbol->section)
+ c = som_section_type (symbol->section->name);
+ else
+ return '?';
+ if (symbol->flags & BSF_GLOBAL)
+ c = toupper (c);
+ return c;
+}
+
+/* Return information about SOM symbol SYMBOL in RET. */
+
+static void
+som_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ ret->type = som_decode_symclass (symbol);
+ if (ret->type != 'U')
+ ret->value = symbol->value+symbol->section->vma;
+ else
+ ret->value = 0;
+ ret->name = symbol->name;
+}
+
+/* Count the number of symbols in the archive symbol table. Necessary
+ so that we can allocate space for all the carsyms at once. */
+
+static boolean
+som_bfd_count_ar_symbols (abfd, lst_header, count)
+ bfd *abfd;
+ struct lst_header *lst_header;
+ symindex *count;
+{
+ unsigned int i;
+ unsigned int *hash_table = NULL;
+ file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
+
+ hash_table =
+ (unsigned int *) bfd_malloc (lst_header->hash_size
+ * sizeof (unsigned int));
+ if (hash_table == NULL && lst_header->hash_size != 0)
+ goto error_return;
+
+ /* Don't forget to initialize the counter! */
+ *count = 0;
+
+ /* Read in the hash table. The has table is an array of 32bit file offsets
+ which point to the hash chains. */
+ if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
+ != lst_header->hash_size * 4)
+ goto error_return;
+
+ /* Walk each chain counting the number of symbols found on that particular
+ chain. */
+ for (i = 0; i < lst_header->hash_size; i++)
+ {
+ struct lst_symbol_record lst_symbol;
+
+ /* An empty chain has zero as it's file offset. */
+ if (hash_table[i] == 0)
+ continue;
+
+ /* Seek to the first symbol in this hash chain. */
+ if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
+ goto error_return;
+
+ /* Read in this symbol and update the counter. */
+ if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
+ != sizeof (lst_symbol))
+ goto error_return;
+
+ (*count)++;
+
+ /* Now iterate through the rest of the symbols on this chain. */
+ while (lst_symbol.next_entry)
+ {
+
+ /* Seek to the next symbol. */
+ if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET)
+ < 0)
+ goto error_return;
+
+ /* Read the symbol in and update the counter. */
+ if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
+ != sizeof (lst_symbol))
+ goto error_return;
+
+ (*count)++;
+ }
+ }
+ if (hash_table != NULL)
+ free (hash_table);
+ return true;
+
+ error_return:
+ if (hash_table != NULL)
+ free (hash_table);
+ return false;
+}
+
+/* Fill in the canonical archive symbols (SYMS) from the archive described
+ by ABFD and LST_HEADER. */
+
+static boolean
+som_bfd_fill_in_ar_symbols (abfd, lst_header, syms)
+ bfd *abfd;
+ struct lst_header *lst_header;
+ carsym **syms;
+{
+ unsigned int i, len;
+ carsym *set = syms[0];
+ unsigned int *hash_table = NULL;
+ struct som_entry *som_dict = NULL;
+ file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
+
+ hash_table =
+ (unsigned int *) bfd_malloc (lst_header->hash_size
+ * sizeof (unsigned int));
+ if (hash_table == NULL && lst_header->hash_size != 0)
+ goto error_return;
+
+ som_dict =
+ (struct som_entry *) bfd_malloc (lst_header->module_count
+ * sizeof (struct som_entry));
+ if (som_dict == NULL && lst_header->module_count != 0)
+ goto error_return;
+
+ /* Read in the hash table. The has table is an array of 32bit file offsets
+ which point to the hash chains. */
+ if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd)
+ != lst_header->hash_size * 4)
+ goto error_return;
+
+ /* Seek to and read in the SOM dictionary. We will need this to fill
+ in the carsym's filepos field. */
+ if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) < 0)
+ goto error_return;
+
+ if (bfd_read ((PTR) som_dict, lst_header->module_count,
+ sizeof (struct som_entry), abfd)
+ != lst_header->module_count * sizeof (struct som_entry))
+ goto error_return;
+
+ /* Walk each chain filling in the carsyms as we go along. */
+ for (i = 0; i < lst_header->hash_size; i++)
+ {
+ struct lst_symbol_record lst_symbol;
+
+ /* An empty chain has zero as it's file offset. */
+ if (hash_table[i] == 0)
+ continue;
+
+ /* Seek to and read the first symbol on the chain. */
+ if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0)
+ goto error_return;
+
+ if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
+ != sizeof (lst_symbol))
+ goto error_return;
+
+ /* Get the name of the symbol, first get the length which is stored
+ as a 32bit integer just before the symbol.
+
+ One might ask why we don't just read in the entire string table
+ and index into it. Well, according to the SOM ABI the string
+ index can point *anywhere* in the archive to save space, so just
+ using the string table would not be safe. */
+ if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
+ + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
+ goto error_return;
+
+ if (bfd_read (&len, 1, 4, abfd) != 4)
+ goto error_return;
+
+ /* Allocate space for the name and null terminate it too. */
+ set->name = bfd_zalloc (abfd, len + 1);
+ if (!set->name)
+ goto error_return;
+ if (bfd_read (set->name, 1, len, abfd) != len)
+ goto error_return;
+
+ set->name[len] = 0;
+
+ /* Fill in the file offset. Note that the "location" field points
+ to the SOM itself, not the ar_hdr in front of it. */
+ set->file_offset = som_dict[lst_symbol.som_index].location
+ - sizeof (struct ar_hdr);
+
+ /* Go to the next symbol. */
+ set++;
+
+ /* Iterate through the rest of the chain. */
+ while (lst_symbol.next_entry)
+ {
+ /* Seek to the next symbol and read it in. */
+ if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) <0)
+ goto error_return;
+
+ if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd)
+ != sizeof (lst_symbol))
+ goto error_return;
+
+ /* Seek to the name length & string and read them in. */
+ if (bfd_seek (abfd, lst_filepos + lst_header->string_loc
+ + lst_symbol.name.n_strx - 4, SEEK_SET) < 0)
+ goto error_return;
+
+ if (bfd_read (&len, 1, 4, abfd) != 4)
+ goto error_return;
+
+ /* Allocate space for the name and null terminate it too. */
+ set->name = bfd_zalloc (abfd, len + 1);
+ if (!set->name)
+ goto error_return;
+
+ if (bfd_read (set->name, 1, len, abfd) != len)
+ goto error_return;
+ set->name[len] = 0;
+
+ /* Fill in the file offset. Note that the "location" field points
+ to the SOM itself, not the ar_hdr in front of it. */
+ set->file_offset = som_dict[lst_symbol.som_index].location
+ - sizeof (struct ar_hdr);
+
+ /* Go on to the next symbol. */
+ set++;
+ }
+ }
+ /* If we haven't died by now, then we successfully read the entire
+ archive symbol table. */
+ if (hash_table != NULL)
+ free (hash_table);
+ if (som_dict != NULL)
+ free (som_dict);
+ return true;
+
+ error_return:
+ if (hash_table != NULL)
+ free (hash_table);
+ if (som_dict != NULL)
+ free (som_dict);
+ return false;
+}
+
+/* Read in the LST from the archive. */
+static boolean
+som_slurp_armap (abfd)
+ bfd *abfd;
+{
+ struct lst_header lst_header;
+ struct ar_hdr ar_header;
+ unsigned int parsed_size;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char nextname[17];
+ int i = bfd_read ((PTR) nextname, 1, 16, abfd);
+
+ /* Special cases. */
+ if (i == 0)
+ return true;
+ if (i != 16)
+ return false;
+
+ if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) < 0)
+ return false;
+
+ /* For archives without .o files there is no symbol table. */
+ if (strncmp (nextname, "/ ", 16))
+ {
+ bfd_has_map (abfd) = false;
+ return true;
+ }
+
+ /* Read in and sanity check the archive header. */
+ if (bfd_read ((PTR) &ar_header, 1, sizeof (struct ar_hdr), abfd)
+ != sizeof (struct ar_hdr))
+ return false;
+
+ if (strncmp (ar_header.ar_fmag, ARFMAG, 2))
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
+ }
+
+ /* How big is the archive symbol table entry? */
+ errno = 0;
+ parsed_size = strtol (ar_header.ar_size, NULL, 10);
+ if (errno != 0)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
+ }
+
+ /* Save off the file offset of the first real user data. */
+ ardata->first_file_filepos = bfd_tell (abfd) + parsed_size;
+
+ /* Read in the library symbol table. We'll make heavy use of this
+ in just a minute. */
+ if (bfd_read ((PTR) & lst_header, 1, sizeof (struct lst_header), abfd)
+ != sizeof (struct lst_header))
+ return false;
+
+ /* Sanity check. */
+ if (lst_header.a_magic != LIBMAGIC)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
+ }
+
+ /* Count the number of symbols in the library symbol table. */
+ if (som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count)
+ == false)
+ return false;
+
+ /* Get back to the start of the library symbol table. */
+ if (bfd_seek (abfd, ardata->first_file_filepos - parsed_size
+ + sizeof (struct lst_header), SEEK_SET) < 0)
+ return false;
+
+ /* Initializae the cache and allocate space for the library symbols. */
+ ardata->cache = 0;
+ ardata->symdefs = (carsym *) bfd_alloc (abfd,
+ (ardata->symdef_count
+ * sizeof (carsym)));
+ if (!ardata->symdefs)
+ return false;
+
+ /* Now fill in the canonical archive symbols. */
+ if (som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs)
+ == false)
+ return false;
+
+ /* Seek back to the "first" file in the archive. Note the "first"
+ file may be the extended name table. */
+ if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) < 0)
+ return false;
+
+ /* Notify the generic archive code that we have a symbol map. */
+ bfd_has_map (abfd) = true;
+ return true;
+}
+
+/* Begin preparing to write a SOM library symbol table.
+
+ As part of the prep work we need to determine the number of symbols
+ and the size of the associated string section. */
+
+static boolean
+som_bfd_prep_for_ar_write (abfd, num_syms, stringsize)
+ bfd *abfd;
+ unsigned int *num_syms, *stringsize;
+{
+ bfd *curr_bfd = abfd->archive_head;
+
+ /* Some initialization. */
+ *num_syms = 0;
+ *stringsize = 0;
+
+ /* Iterate over each BFD within this archive. */
+ while (curr_bfd != NULL)
+ {
+ unsigned int curr_count, i;
+ som_symbol_type *sym;
+
+ /* Don't bother for non-SOM objects. */
+ if (curr_bfd->format != bfd_object
+ || curr_bfd->xvec->flavour != bfd_target_som_flavour)
+ {
+ curr_bfd = curr_bfd->next;
+ continue;
+ }
+
+ /* Make sure the symbol table has been read, then snag a pointer
+ to it. It's a little slimey to grab the symbols via obj_som_symtab,
+ but doing so avoids allocating lots of extra memory. */
+ if (som_slurp_symbol_table (curr_bfd) == false)
+ return false;
+
+ sym = obj_som_symtab (curr_bfd);
+ curr_count = bfd_get_symcount (curr_bfd);
+
+ /* Examine each symbol to determine if it belongs in the
+ library symbol table. */
+ for (i = 0; i < curr_count; i++, sym++)
+ {
+ struct som_misc_symbol_info info;
+
+ /* Derive SOM information from the BFD symbol. */
+ som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
+
+ /* Should we include this symbol? */
+ if (info.symbol_type == ST_NULL
+ || info.symbol_type == ST_SYM_EXT
+ || info.symbol_type == ST_ARG_EXT)
+ continue;
+
+ /* Only global symbols and unsatisfied commons. */
+ if (info.symbol_scope != SS_UNIVERSAL
+ && info.symbol_type != ST_STORAGE)
+ continue;
+
+ /* Do no include undefined symbols. */
+ if (bfd_is_und_section (sym->symbol.section))
+ continue;
+
+ /* Bump the various counters, being careful to honor
+ alignment considerations in the string table. */
+ (*num_syms)++;
+ *stringsize = *stringsize + strlen (sym->symbol.name) + 5;
+ while (*stringsize % 4)
+ (*stringsize)++;
+ }
+
+ curr_bfd = curr_bfd->next;
+ }
+ return true;
+}
+
+/* Hash a symbol name based on the hashing algorithm presented in the
+ SOM ABI. */
+static unsigned int
+som_bfd_ar_symbol_hash (symbol)
+ asymbol *symbol;
+{
+ unsigned int len = strlen (symbol->name);
+
+ /* Names with length 1 are special. */
+ if (len == 1)
+ return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0];
+
+ return ((len & 0x7f) << 24) | (symbol->name[1] << 16)
+ | (symbol->name[len-2] << 8) | symbol->name[len-1];
+}
+
+/* Do the bulk of the work required to write the SOM library
+ symbol table. */
+
+static boolean
+som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst, elength)
+ bfd *abfd;
+ unsigned int nsyms, string_size;
+ struct lst_header lst;
+ unsigned elength;
+{
+ file_ptr lst_filepos;
+ char *strings = NULL, *p;
+ struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
+ bfd *curr_bfd;
+ unsigned int *hash_table = NULL;
+ struct som_entry *som_dict = NULL;
+ struct lst_symbol_record **last_hash_entry = NULL;
+ unsigned int curr_som_offset, som_index = 0;
+
+ hash_table =
+ (unsigned int *) bfd_malloc (lst.hash_size * sizeof (unsigned int));
+ if (hash_table == NULL && lst.hash_size != 0)
+ goto error_return;
+ som_dict =
+ (struct som_entry *) bfd_malloc (lst.module_count
+ * sizeof (struct som_entry));
+ if (som_dict == NULL && lst.module_count != 0)
+ goto error_return;
+
+ last_hash_entry =
+ ((struct lst_symbol_record **)
+ bfd_malloc (lst.hash_size * sizeof (struct lst_symbol_record *)));
+ if (last_hash_entry == NULL && lst.hash_size != 0)
+ goto error_return;
+
+ /* Lots of fields are file positions relative to the start
+ of the lst record. So save its location. */
+ lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header);
+
+ /* Some initialization. */
+ memset (hash_table, 0, 4 * lst.hash_size);
+ memset (som_dict, 0, lst.module_count * sizeof (struct som_entry));
+ memset (last_hash_entry, 0,
+ lst.hash_size * sizeof (struct lst_symbol_record *));
+
+ /* Symbols have som_index fields, so we have to keep track of the
+ index of each SOM in the archive.
+
+ The SOM dictionary has (among other things) the absolute file
+ position for the SOM which a particular dictionary entry
+ describes. We have to compute that information as we iterate
+ through the SOMs/symbols. */
+ som_index = 0;
+
+ /* We add in the size of the archive header twice as the location
+ in the SOM dictionary is the actual offset of the SOM, not the
+ archive header before the SOM. */
+ curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end;
+
+ /* Make room for the archive header and the contents of the
+ extended string table. Note that elength includes the size
+ of the archive header for the extended name table! */
+ if (elength)
+ curr_som_offset += elength;
+
+ /* Make sure we're properly aligned. */
+ curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
+
+ /* FIXME should be done with buffers just like everything else... */
+ lst_syms = bfd_malloc (nsyms * sizeof (struct lst_symbol_record));
+ if (lst_syms == NULL && nsyms != 0)
+ goto error_return;
+ strings = bfd_malloc (string_size);
+ if (strings == NULL && string_size != 0)
+ goto error_return;
+
+ p = strings;
+ curr_lst_sym = lst_syms;
+
+ curr_bfd = abfd->archive_head;
+ while (curr_bfd != NULL)
+ {
+ unsigned int curr_count, i;
+ som_symbol_type *sym;
+
+ /* Don't bother for non-SOM objects. */
+ if (curr_bfd->format != bfd_object
+ || curr_bfd->xvec->flavour != bfd_target_som_flavour)
+ {
+ curr_bfd = curr_bfd->next;
+ continue;
+ }
+
+ /* Make sure the symbol table has been read, then snag a pointer
+ to it. It's a little slimey to grab the symbols via obj_som_symtab,
+ but doing so avoids allocating lots of extra memory. */
+ if (som_slurp_symbol_table (curr_bfd) == false)
+ goto error_return;
+
+ sym = obj_som_symtab (curr_bfd);
+ curr_count = bfd_get_symcount (curr_bfd);
+
+ for (i = 0; i < curr_count; i++, sym++)
+ {
+ struct som_misc_symbol_info info;
+
+ /* Derive SOM information from the BFD symbol. */
+ som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info);
+
+ /* Should we include this symbol? */
+ if (info.symbol_type == ST_NULL
+ || info.symbol_type == ST_SYM_EXT
+ || info.symbol_type == ST_ARG_EXT)
+ continue;
+
+ /* Only global symbols and unsatisfied commons. */
+ if (info.symbol_scope != SS_UNIVERSAL
+ && info.symbol_type != ST_STORAGE)
+ continue;
+
+ /* Do no include undefined symbols. */
+ if (bfd_is_und_section (sym->symbol.section))
+ continue;
+
+ /* If this is the first symbol from this SOM, then update
+ the SOM dictionary too. */
+ if (som_dict[som_index].location == 0)
+ {
+ som_dict[som_index].location = curr_som_offset;
+ som_dict[som_index].length = arelt_size (curr_bfd);
+ }
+
+ /* Fill in the lst symbol record. */
+ curr_lst_sym->hidden = 0;
+ curr_lst_sym->secondary_def = 0;
+ curr_lst_sym->symbol_type = info.symbol_type;
+ curr_lst_sym->symbol_scope = info.symbol_scope;
+ curr_lst_sym->check_level = 0;
+ curr_lst_sym->must_qualify = 0;
+ curr_lst_sym->initially_frozen = 0;
+ curr_lst_sym->memory_resident = 0;
+ curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
+ curr_lst_sym->dup_common = 0;
+ curr_lst_sym->xleast = 3;
+ curr_lst_sym->arg_reloc = info.arg_reloc;
+ curr_lst_sym->name.n_strx = p - strings + 4;
+ curr_lst_sym->qualifier_name.n_strx = 0;
+ curr_lst_sym->symbol_info = info.symbol_info;
+ curr_lst_sym->symbol_value = info.symbol_value | info.priv_level;
+ curr_lst_sym->symbol_descriptor = 0;
+ curr_lst_sym->reserved = 0;
+ curr_lst_sym->som_index = som_index;
+ curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
+ curr_lst_sym->next_entry = 0;
+
+ /* Insert into the hash table. */
+ if (hash_table[curr_lst_sym->symbol_key % lst.hash_size])
+ {
+ struct lst_symbol_record *tmp;
+
+ /* There is already something at the head of this hash chain,
+ so tack this symbol onto the end of the chain. */
+ tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size];
+ tmp->next_entry
+ = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
+ + lst.hash_size * 4
+ + lst.module_count * sizeof (struct som_entry)
+ + sizeof (struct lst_header);
+ }
+ else
+ {
+ /* First entry in this hash chain. */
+ hash_table[curr_lst_sym->symbol_key % lst.hash_size]
+ = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record)
+ + lst.hash_size * 4
+ + lst.module_count * sizeof (struct som_entry)
+ + sizeof (struct lst_header);
+ }
+
+ /* Keep track of the last symbol we added to this chain so we can
+ easily update its next_entry pointer. */
+ last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]
+ = curr_lst_sym;
+
+
+ /* Update the string table. */
+ bfd_put_32 (abfd, strlen (sym->symbol.name), p);
+ p += 4;
+ strcpy (p, sym->symbol.name);
+ p += strlen (sym->symbol.name) + 1;
+ while ((int)p % 4)
+ {
+ bfd_put_8 (abfd, 0, p);
+ p++;
+ }
+
+ /* Head to the next symbol. */
+ curr_lst_sym++;
+ }
+
+ /* Keep track of where each SOM will finally reside; then look
+ at the next BFD. */
+ curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr);
+
+ /* A particular object in the archive may have an odd length; the
+ linker requires objects begin on an even boundary. So round
+ up the current offset as necessary. */
+ curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
+ curr_bfd = curr_bfd->next;
+ som_index++;
+ }
+
+ /* Now scribble out the hash table. */
+ if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd)
+ != lst.hash_size * 4)
+ goto error_return;
+
+ /* Then the SOM dictionary. */
+ if (bfd_write ((PTR) som_dict, lst.module_count,
+ sizeof (struct som_entry), abfd)
+ != lst.module_count * sizeof (struct som_entry))
+ goto error_return;
+
+ /* The library symbols. */
+ if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd)
+ != nsyms * sizeof (struct lst_symbol_record))
+ goto error_return;
+
+ /* And finally the strings. */
+ if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size)
+ goto error_return;
+
+ if (hash_table != NULL)
+ free (hash_table);
+ if (som_dict != NULL)
+ free (som_dict);
+ if (last_hash_entry != NULL)
+ free (last_hash_entry);
+ if (lst_syms != NULL)
+ free (lst_syms);
+ if (strings != NULL)
+ free (strings);
+ return true;
+
+ error_return:
+ if (hash_table != NULL)
+ free (hash_table);
+ if (som_dict != NULL)
+ free (som_dict);
+ if (last_hash_entry != NULL)
+ free (last_hash_entry);
+ if (lst_syms != NULL)
+ free (lst_syms);
+ if (strings != NULL)
+ free (strings);
+
+ return false;
+}
+
+/* Write out the LST for the archive.
+
+ You'll never believe this is really how armaps are handled in SOM... */
+
+/*ARGSUSED*/
+static boolean
+som_write_armap (abfd, elength, map, orl_count, stridx)
+ bfd *abfd;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int orl_count;
+ int stridx;
+{
+ bfd *curr_bfd;
+ struct stat statbuf;
+ unsigned int i, lst_size, nsyms, stringsize;
+ struct ar_hdr hdr;
+ struct lst_header lst;
+ int *p;
+
+ /* We'll use this for the archive's date and mode later. */
+ if (stat (abfd->filename, &statbuf) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return false;
+ }
+ /* Fudge factor. */
+ bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60;
+
+ /* Account for the lst header first. */
+ lst_size = sizeof (struct lst_header);
+
+ /* Start building the LST header. */
+ /* FIXME: Do we need to examine each element to determine the
+ largest id number? */
+ lst.system_id = CPU_PA_RISC1_0;
+ lst.a_magic = LIBMAGIC;
+ lst.version_id = VERSION_ID;
+ lst.file_time.secs = 0;
+ lst.file_time.nanosecs = 0;
+
+ lst.hash_loc = lst_size;
+ lst.hash_size = SOM_LST_HASH_SIZE;
+
+ /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets. */
+ lst_size += 4 * SOM_LST_HASH_SIZE;
+
+ /* We need to count the number of SOMs in this archive. */
+ curr_bfd = abfd->archive_head;
+ lst.module_count = 0;
+ while (curr_bfd != NULL)
+ {
+ /* Only true SOM objects count. */
+ if (curr_bfd->format == bfd_object
+ && curr_bfd->xvec->flavour == bfd_target_som_flavour)
+ lst.module_count++;
+ curr_bfd = curr_bfd->next;
+ }
+ lst.module_limit = lst.module_count;
+ lst.dir_loc = lst_size;
+ lst_size += sizeof (struct som_entry) * lst.module_count;
+
+ /* We don't support import/export tables, auxiliary headers,
+ or free lists yet. Make the linker work a little harder
+ to make our life easier. */
+
+ lst.export_loc = 0;
+ lst.export_count = 0;
+ lst.import_loc = 0;
+ lst.aux_loc = 0;
+ lst.aux_size = 0;
+
+ /* Count how many symbols we will have on the hash chains and the
+ size of the associated string table. */
+ if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false)
+ return false;
+
+ lst_size += sizeof (struct lst_symbol_record) * nsyms;
+
+ /* For the string table. One day we might actually use this info
+ to avoid small seeks/reads when reading archives. */
+ lst.string_loc = lst_size;
+ lst.string_size = stringsize;
+ lst_size += stringsize;
+
+ /* SOM ABI says this must be zero. */
+ lst.free_list = 0;
+ lst.file_end = lst_size;
+
+ /* Compute the checksum. Must happen after the entire lst header
+ has filled in. */
+ p = (int *)&lst;
+ lst.checksum = 0;
+ for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++)
+ lst.checksum ^= *p++;
+
+ sprintf (hdr.ar_name, "/ ");
+ sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp);
+ sprintf (hdr.ar_uid, "%ld", (long) getuid ());
+ sprintf (hdr.ar_gid, "%ld", (long) getgid ());
+ sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode);
+ sprintf (hdr.ar_size, "%-10d", (int) lst_size);
+ hdr.ar_fmag[0] = '`';
+ hdr.ar_fmag[1] = '\012';
+
+ /* Turn any nulls into spaces. */
+ for (i = 0; i < sizeof (struct ar_hdr); i++)
+ if (((char *) (&hdr))[i] == '\0')
+ (((char *) (&hdr))[i]) = ' ';
+
+ /* Scribble out the ar header. */
+ if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd)
+ != sizeof (struct ar_hdr))
+ return false;
+
+ /* Now scribble out the lst header. */
+ if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd)
+ != sizeof (struct lst_header))
+ return false;
+
+ /* Build and write the armap. */
+ if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst, elength)
+ == false)
+ return false;
+
+ /* Done. */
+ return true;
+}
+
+/* Free all information we have cached for this BFD. We can always
+ read it again later if we need it. */
+
+static boolean
+som_bfd_free_cached_info (abfd)
+ bfd *abfd;
+{
+ asection *o;
+
+ if (bfd_get_format (abfd) != bfd_object)
+ return true;
+
+#define FREE(x) if (x != NULL) { free (x); x = NULL; }
+ /* Free the native string and symbol tables. */
+ FREE (obj_som_symtab (abfd));
+ FREE (obj_som_stringtab (abfd));
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ /* Free the native relocations. */
+ o->reloc_count = -1;
+ FREE (som_section_data (o)->reloc_stream);
+ /* Free the generic relocations. */
+ FREE (o->relocation);
+ }
+#undef FREE
+
+ return true;
+}
+
+/* End of miscellaneous support functions. */
+
+/* Linker support functions. */
+static boolean
+som_bfd_link_split_section (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ return (som_is_subspace (sec) && sec->_raw_size > 240000);
+}
+
+#define som_close_and_cleanup som_bfd_free_cached_info
+
+#define som_read_ar_hdr _bfd_generic_read_ar_hdr
+#define som_openr_next_archived_file bfd_generic_openr_next_archived_file
+#define som_get_elt_at_index _bfd_generic_get_elt_at_index
+#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt
+#define som_truncate_arname bfd_bsd_truncate_arname
+#define som_slurp_extended_name_table _bfd_slurp_extended_name_table
+#define som_construct_extended_name_table \
+ _bfd_archive_coff_construct_extended_name_table
+#define som_update_armap_timestamp bfd_true
+#define som_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+
+#define som_get_lineno _bfd_nosymbols_get_lineno
+#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define som_read_minisymbols _bfd_generic_read_minisymbols
+#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define som_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#define som_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define som_bfd_relax_section bfd_generic_relax_section
+#define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define som_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define som_bfd_final_link _bfd_generic_final_link
+
+#define som_bfd_gc_sections bfd_generic_gc_sections
+
+
+const bfd_target som_vec =
+{
+ "som", /* name */
+ bfd_target_som_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+
+/* leading_symbol_char: is the first char of a user symbol
+ predictable, and if so what is it */
+ 0,
+ '/', /* ar_pad_char */
+ 14, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ {_bfd_dummy_target,
+ som_object_p, /* bfd_check_format */
+ bfd_generic_archive_p,
+ _bfd_dummy_target
+ },
+ {
+ bfd_false,
+ som_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+ {
+ bfd_false,
+ som_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+#undef som
+
+ BFD_JUMP_TABLE_GENERIC (som),
+ BFD_JUMP_TABLE_COPY (som),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (som),
+ BFD_JUMP_TABLE_SYMBOLS (som),
+ BFD_JUMP_TABLE_RELOCS (som),
+ BFD_JUMP_TABLE_WRITE (som),
+ BFD_JUMP_TABLE_LINK (som),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
+
+#endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */
diff --git a/bfd/som.h b/bfd/som.h
new file mode 100644
index 00000000000..af378042189
--- /dev/null
+++ b/bfd/som.h
@@ -0,0 +1,237 @@
+/* HP PA-RISC SOM object file format: definitions internal to BFD.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef _SOM_H
+#define _SOM_H
+
+#include "libhppa.h"
+
+#include <a.out.h>
+#include <lst.h>
+#include <ar.h>
+
+/* The SOM BFD backend doesn't currently use anything from these
+ two include files, but it's likely to need them in the future. */
+#ifdef R_DLT_REL
+#include <shl.h>
+#include <dl.h>
+#endif
+
+#if defined(HOST_HPPABSD) || defined (HOST_HPPAOSF)
+/* BSD uses a completely different scheme for object file identification.
+ so for now, define _PA_RISC_ID to accept any random value for a model
+ number. */
+#undef _PA_RISC_ID
+#define _PA_RISC_ID(__m_num) 1
+#endif /* HOST_HPPABSD */
+
+#define FILE_HDR_SIZE sizeof(struct header)
+#define AUX_HDR_SIZE sizeof(struct som_exec_auxhdr)
+
+typedef struct som_symbol
+ {
+ asymbol symbol;
+ unsigned int som_type;
+
+ /* Structured like the ELF tc_data union. Allows more code sharing
+ in GAS this way. */
+ union
+ {
+ struct
+ {
+ unsigned int hppa_arg_reloc;
+ unsigned int hppa_priv_level;
+ } ap;
+ PTR any;
+ }
+ tc_data;
+
+ /* Index of this symbol in the symbol table. Only used when
+ building relocation streams for incomplete objects. */
+ int index;
+
+ /* How many times this symbol is used in a relocation. By sorting
+ the symbols from most used to least used we can significantly
+ reduce the size of the relocation stream for incomplete objects. */
+ int reloc_count;
+
+ /* During object file writing, the offset of the name of this symbol
+ in the SOM string table. */
+ int stringtab_offset;
+ }
+som_symbol_type;
+
+/* A structure containing all the magic information stored in a BFD's
+ private data which needs to be copied during an objcopy/strip run. */
+struct som_exec_data
+ {
+ /* Sort-of a magic number. BSD uses it to distinguish between
+ native executables and hpux executables. */
+ short system_id;
+
+ /* Magic exec flags. These control things like whether or not
+ null pointer dereferencing is allowed and the like. */
+ long exec_flags;
+
+ /* Add more stuff here as needed. Good examples of information
+ we might want to pass would be presumed_dp, entry_* and maybe
+ others from the file header. */
+ };
+
+struct somdata
+ {
+ /* All the magic information about an executable which lives
+ in the private BFD structure and needs to be copied from
+ the input bfd to the output bfd during a objcopy/strip. */
+ struct som_exec_data *exec_data;
+
+ /* These three fields are only used when writing files and are
+ generated from scratch. They need not be copied for objcopy
+ or strip to work. */
+ struct header *file_hdr;
+ struct copyright_aux_hdr *copyright_aux_hdr;
+ struct user_string_aux_hdr *version_aux_hdr;
+ struct som_exec_auxhdr *exec_hdr;
+ COMPUNIT *comp_unit;
+
+ /* Pointers to a saved copy of the symbol and string tables. These
+ need not be copied for objcopy or strip to work. */
+ som_symbol_type *symtab;
+ char *stringtab;
+ asymbol **sorted_syms;
+
+ /* We remember these offsets so that after check_file_format, we have
+ no dependencies on the particular format of the exec_hdr.
+ These offsets need not be copied for objcopy or strip to work. */
+
+ file_ptr sym_filepos;
+ file_ptr str_filepos;
+ file_ptr reloc_filepos;
+ unsigned stringtab_size;
+ };
+
+struct som_data_struct
+ {
+ struct somdata a;
+ };
+
+/* Substructure of som_section_data_struct used to hold information
+ which can't be represented by the generic BFD section structure,
+ but which must be copied during objcopy or strip. */
+struct som_copyable_section_data_struct
+ {
+ /* Various fields in space and subspace headers that we need
+ to pass around. */
+ unsigned int sort_key : 8;
+ unsigned int access_control_bits : 7;
+ unsigned int is_defined : 1;
+ unsigned int is_private : 1;
+ unsigned int quadrant : 2;
+
+ /* For subspaces, this points to the section which represents the
+ space in which the subspace is contained. For spaces it points
+ back to the section for this space. */
+ asection *container;
+
+ /* The user-specified space number. It is wrong to use this as
+ an index since duplicates and holes are allowed. */
+ int space_number;
+
+ /* Add more stuff here as needed. Good examples of information
+ we might want to pass would be initialization pointers,
+ and the many subspace flags we do not represent yet. */
+ };
+
+/* Used to keep extra SOM specific information for a given section.
+
+ reloc_size holds the size of the relocation stream, note this
+ is very different from the number of relocations as SOM relocations
+ are variable length.
+
+ reloc_stream is the actual stream of relocation entries. */
+
+struct som_section_data_struct
+ {
+ struct som_copyable_section_data_struct *copy_data;
+ unsigned int reloc_size;
+ char *reloc_stream;
+ struct space_dictionary_record *space_dict;
+ struct subspace_dictionary_record *subspace_dict;
+ };
+
+#define somdata(bfd) ((bfd)->tdata.som_data->a)
+#define obj_som_exec_data(bfd) (somdata(bfd).exec_data)
+#define obj_som_file_hdr(bfd) (somdata(bfd).file_hdr)
+#define obj_som_exec_hdr(bfd) (somdata(bfd).exec_hdr)
+#define obj_som_copyright_hdr(bfd) (somdata(bfd).copyright_aux_hdr)
+#define obj_som_version_hdr(bfd) (somdata(bfd).version_aux_hdr)
+#define obj_som_compilation_unit(bfd) (somdata(bfd).comp_unit)
+#define obj_som_symtab(bfd) (somdata(bfd).symtab)
+#define obj_som_stringtab(bfd) (somdata(bfd).stringtab)
+#define obj_som_sym_filepos(bfd) (somdata(bfd).sym_filepos)
+#define obj_som_str_filepos(bfd) (somdata(bfd).str_filepos)
+#define obj_som_stringtab_size(bfd) (somdata(bfd).stringtab_size)
+#define obj_som_reloc_filepos(bfd) (somdata(bfd).reloc_filepos)
+#define obj_som_sorted_syms(bfd) (somdata(bfd).sorted_syms)
+#define som_section_data(sec) \
+ ((struct som_section_data_struct *)sec->used_by_bfd)
+#define som_symbol_data(symbol) ((som_symbol_type *) symbol)
+
+
+/* Defines groups of basic relocations. FIXME: These should
+ be the only basic relocations created by GAS. The rest
+ should be internal to the BFD backend.
+
+ The idea is both SOM and ELF define these basic relocation
+ types so they map into a SOM or ELF specific reloation as
+ appropriate. This allows GAS to share much more code
+ between the two object formats. */
+
+#define R_HPPA_NONE R_NO_RELOCATION
+#define R_HPPA R_CODE_ONE_SYMBOL
+#define R_HPPA_PCREL_CALL R_PCREL_CALL
+#define R_HPPA_ABS_CALL R_ABS_CALL
+#define R_HPPA_GOTOFF R_DP_RELATIVE
+#define R_HPPA_ENTRY R_ENTRY
+#define R_HPPA_EXIT R_EXIT
+#define R_HPPA_COMPLEX R_COMP1
+#define R_HPPA_BEGIN_BRTAB R_BEGIN_BRTAB
+#define R_HPPA_END_BRTAB R_END_BRTAB
+#define R_HPPA_BEGIN_TRY R_BEGIN_TRY
+#define R_HPPA_END_TRY R_END_TRY
+
+/* Exported functions, mostly for use by GAS. */
+boolean bfd_som_set_section_attributes PARAMS ((asection *, int, int,
+ unsigned int, int));
+boolean bfd_som_set_subsection_attributes PARAMS ((asection *, asection *,
+ int, unsigned int, int));
+void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int));
+boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *));
+int ** hppa_som_gen_reloc_type
+ PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt,
+ int, asymbol *));
+boolean bfd_som_attach_compilation_unit
+ PARAMS ((bfd *, const char *, const char *, const char *, const char *));
+
+#endif /* _SOM_H */
diff --git a/bfd/sparclinux.c b/bfd/sparclinux.c
new file mode 100644
index 00000000000..86d4e7e9444
--- /dev/null
+++ b/bfd/sparclinux.c
@@ -0,0 +1,770 @@
+/* BFD back-end for linux flavored sparc a.out binaries.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define ZMAGIC_DISK_BLOCK_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0x0
+#define N_SHARED_LIB(x) 0
+#define BYTES_IN_WORD 4
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN)
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#define DEFAULT_ARCH bfd_arch_sparc
+#define MY(OP) CAT(sparclinux_,OP)
+#define TARGETNAME "a.out-sparc-linux"
+
+extern const bfd_target MY(vec);
+
+/* We always generate QMAGIC files in preference to ZMAGIC files. It
+ would be possible to make this a linker option, if that ever
+ becomes important. */
+
+static void MY_final_link_callback
+ PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+
+static boolean sparclinux_bfd_final_link
+ PARAMS ((bfd *abfd, struct bfd_link_info *info));
+
+static boolean
+sparclinux_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ obj_aout_subformat (abfd) = q_magic_format;
+ return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
+}
+
+#define MY_bfd_final_link sparclinux_bfd_final_link
+
+/* Set the machine type correctly. */
+
+static boolean sparclinux_write_object_contents PARAMS ((bfd *abfd));
+
+static boolean
+sparclinux_write_object_contents (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ N_SET_MACHTYPE (*execp, M_SPARC);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ WRITE_HEADERS(abfd, execp);
+
+ return true;
+}
+
+#define MY_write_object_contents sparclinux_write_object_contents
+/* Code to link against Linux a.out shared libraries. */
+
+/* See if a symbol name is a reference to the global offset table. */
+
+#ifndef GOT_REF_PREFIX
+#define GOT_REF_PREFIX "__GOT_"
+#endif
+
+#define IS_GOT_SYM(name) \
+ (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
+
+/* See if a symbol name is a reference to the procedure linkage table. */
+
+#ifndef PLT_REF_PREFIX
+#define PLT_REF_PREFIX "__PLT_"
+#endif
+
+#define IS_PLT_SYM(name) \
+ (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
+
+/* This string is used to generate specialized error messages. */
+
+#ifndef NEEDS_SHRLIB
+#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
+#endif
+
+/* This special symbol is a set vector that contains a list of
+ pointers to fixup tables. It will be present in any dynamicly
+ linked file. The linker generated fixup table should also be added
+ to the list, and it should always appear in the second slot (the
+ first one is a dummy with a magic number that is defined in
+ crt0.o). */
+
+#ifndef SHARABLE_CONFLICTS
+#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
+#endif
+
+/* We keep a list of fixups. The terminology is a bit strange, but
+ each fixup contains two 32 bit numbers. A regular fixup contains
+ an address and a pointer, and at runtime we should store the
+ address at the location pointed to by the pointer. A builtin fixup
+ contains two pointers, and we should read the address using one
+ pointer and store it at the location pointed to by the other
+ pointer. Builtin fixups come into play when we have duplicate
+ __GOT__ symbols for the same variable. The builtin fixup will copy
+ the GOT pointer from one over into the other. */
+
+struct fixup
+{
+ struct fixup *next;
+ struct linux_link_hash_entry *h;
+ bfd_vma value;
+
+ /* Nonzero if this is a jump instruction that needs to be fixed,
+ zero if this is just a pointer */
+ char jump;
+
+ char builtin;
+};
+
+/* We don't need a special hash table entry structure, but we do need
+ to keep some information between linker passes, so we use a special
+ hash table. */
+
+struct linux_link_hash_entry
+{
+ struct aout_link_hash_entry root;
+};
+
+struct linux_link_hash_table
+{
+ struct aout_link_hash_table root;
+
+ /* First dynamic object found in link. */
+ bfd *dynobj;
+
+ /* Number of fixups. */
+ size_t fixup_count;
+
+ /* Number of builtin fixups. */
+ size_t local_builtins;
+
+ /* List of fixups. */
+ struct fixup *fixup_list;
+};
+
+static struct bfd_hash_entry *linux_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *linux_link_hash_table_create
+ PARAMS ((bfd *));
+static struct fixup *new_fixup
+ PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
+ bfd_vma, int));
+static boolean linux_link_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean linux_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, boolean, boolean,
+ struct bfd_link_hash_entry **));
+static boolean linux_tally_symbols
+ PARAMS ((struct linux_link_hash_entry *, PTR));
+static boolean linux_finish_dynamic_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Routine to create an entry in an Linux link hash table. */
+
+static struct bfd_hash_entry *
+linux_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct linux_link_hash_entry *) NULL)
+ ret = ((struct linux_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct linux_link_hash_entry *)
+ NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ /* Set local fields; there aren't any. */
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a Linux link hash table. */
+
+static struct bfd_link_hash_table *
+linux_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct linux_link_hash_table *ret;
+
+ ret = ((struct linux_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));
+ if (ret == (struct linux_link_hash_table *) NULL)
+ return (struct bfd_link_hash_table *) NULL;
+ if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
+ linux_link_hash_newfunc))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->dynobj = NULL;
+ ret->fixup_count = 0;
+ ret->local_builtins = 0;
+ ret->fixup_list = NULL;
+
+ return &ret->root.root;
+}
+
+/* Look up an entry in a Linux link hash table. */
+
+#define linux_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct linux_link_hash_entry *) \
+ aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
+ (follow)))
+
+/* Traverse a Linux link hash table. */
+
+#define linux_link_hash_traverse(table, func, info) \
+ (aout_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the Linux link hash table from the info structure. This is
+ just a cast. */
+
+#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
+
+/* Store the information for a new fixup. */
+
+static struct fixup *
+new_fixup (info, h, value, builtin)
+ struct bfd_link_info *info;
+ struct linux_link_hash_entry *h;
+ bfd_vma value;
+ int builtin;
+{
+ struct fixup *f;
+
+ f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
+ sizeof (struct fixup));
+ if (f == NULL)
+ return f;
+ f->next = linux_hash_table (info)->fixup_list;
+ linux_hash_table (info)->fixup_list = f;
+ f->h = h;
+ f->value = value;
+ f->builtin = builtin;
+ f->jump = 0;
+ ++linux_hash_table (info)->fixup_count;
+ return f;
+}
+
+/* We come here once we realize that we are going to link to a shared
+ library. We need to create a special section that contains the
+ fixup table, and we ultimately need to add a pointer to this into
+ the set vector for SHARABLE_CONFLICTS. At this point we do not
+ know the size of the section, but that's OK - we just need to
+ create it for now. */
+
+static boolean
+linux_link_create_dynamic_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ flagword flags;
+ register asection *s;
+
+ /* Note that we set the SEC_IN_MEMORY flag. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ /* We choose to use the name ".linux-dynamic" for the fixup table.
+ Why not? */
+ s = bfd_make_section (abfd, ".linux-dynamic");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+ s->_raw_size = 0;
+ s->contents = 0;
+
+ return true;
+}
+
+/* Function to add a single symbol to the linker hash table. This is
+ a wrapper around _bfd_generic_link_add_one_symbol which handles the
+ tweaking needed for dynamic linking support. */
+
+static boolean
+linux_add_one_symbol (info, abfd, name, flags, section, value, string,
+ copy, collect, hashp)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ const char *string;
+ boolean copy;
+ boolean collect;
+ struct bfd_link_hash_entry **hashp;
+{
+ struct linux_link_hash_entry *h;
+ boolean insert;
+
+ /* Look up and see if we already have this symbol in the hash table.
+ If we do, and the defining entry is from a shared library, we
+ need to create the dynamic sections.
+
+ FIXME: What if abfd->xvec != info->hash->creator? We may want to
+ be able to link Linux a.out and ELF objects together, but serious
+ confusion is possible. */
+
+ insert = false;
+
+ if (! info->relocateable
+ && linux_hash_table (info)->dynobj == NULL
+ && strcmp (name, SHARABLE_CONFLICTS) == 0
+ && (flags & BSF_CONSTRUCTOR) != 0
+ && abfd->xvec == info->hash->creator)
+ {
+ if (! linux_link_create_dynamic_sections (abfd, info))
+ return false;
+ linux_hash_table (info)->dynobj = abfd;
+ insert = true;
+ }
+
+ if (bfd_is_abs_section (section)
+ && abfd->xvec == info->hash->creator)
+ {
+ h = linux_link_hash_lookup (linux_hash_table (info), name, false,
+ false, false);
+ if (h != NULL
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak))
+ {
+ struct fixup *f;
+
+ if (hashp != NULL)
+ *hashp = (struct bfd_link_hash_entry *) h;
+
+ f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
+ if (f == NULL)
+ return false;
+ f->jump = IS_PLT_SYM (name);
+
+ return true;
+ }
+ }
+
+ /* Do the usual procedure for adding a symbol. */
+ if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
+ value, string, copy, collect,
+ hashp))
+ return false;
+
+ /* Insert a pointer to our table in the set vector. The dynamic
+ linker requires this information */
+ if (insert)
+ {
+ asection *s;
+
+ /* Here we do our special thing to add the pointer to the
+ dynamic section in the SHARABLE_CONFLICTS set vector. */
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ BFD_ASSERT (s != NULL);
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
+ BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL)))
+ return false;
+ }
+
+ return true;
+}
+
+/* We will crawl the hash table and come here for every global symbol.
+ We will examine each entry and see if there are indications that we
+ need to add a fixup. There are two possible cases - one is where
+ you have duplicate definitions of PLT or GOT symbols - these will
+ have already been caught and added as "builtin" fixups. If we find
+ that the corresponding non PLT/GOT symbol is also present, we
+ convert it to a regular fixup instead.
+
+ This function is called via linux_link_hash_traverse. */
+
+static boolean
+linux_tally_symbols (h, data)
+ struct linux_link_hash_entry *h;
+ PTR data;
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
+ struct fixup *f, *f1;
+ int is_plt;
+ struct linux_link_hash_entry *h1, *h2;
+ boolean exists;
+
+ if (h->root.root.type == bfd_link_hash_undefined
+ && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
+ sizeof NEEDS_SHRLIB - 1) == 0)
+ {
+ const char *name;
+ char *p;
+ char *alloc = NULL;
+
+ name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
+ p = strrchr (name, '_');
+ if (p != NULL)
+ alloc = (char *) bfd_malloc (strlen (name) + 1);
+
+ if (p == NULL || alloc == NULL)
+ (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
+ name);
+ else
+ {
+ strcpy (alloc, name);
+ p = strrchr (alloc, '_');
+ *p++ = '\0';
+ (*_bfd_error_handler)
+ (_("Output file requires shared library `%s.so.%s'\n"),
+ alloc, p);
+ free (alloc);
+ }
+
+ abort ();
+ }
+
+ /* If this symbol is not a PLT/GOT, we do not even need to look at
+ it. */
+ is_plt = IS_PLT_SYM (h->root.root.root.string);
+
+ if (is_plt || IS_GOT_SYM (h->root.root.root.string))
+ {
+ /* Look up this symbol twice. Once just as a regular lookup,
+ and then again following all of the indirect links until we
+ reach a real symbol. */
+ h1 = linux_link_hash_lookup (linux_hash_table (info),
+ (h->root.root.root.string
+ + sizeof PLT_REF_PREFIX - 1),
+ false, false, true);
+ /* h2 does not follow indirect symbols. */
+ h2 = linux_link_hash_lookup (linux_hash_table (info),
+ (h->root.root.root.string
+ + sizeof PLT_REF_PREFIX - 1),
+ false, false, false);
+
+ /* The real symbol must exist but if it is also an ABS symbol,
+ there is no need to have a fixup. This is because they both
+ came from the same library. If on the other hand, we had to
+ use an indirect symbol to get to the real symbol, we add the
+ fixup anyway, since there are cases where these symbols come
+ from different shared libraries */
+ if (h1 != NULL
+ && (((h1->root.root.type == bfd_link_hash_defined
+ || h1->root.root.type == bfd_link_hash_defweak)
+ && ! bfd_is_abs_section (h1->root.root.u.def.section))
+ || h2->root.root.type == bfd_link_hash_indirect))
+ {
+ /* See if there is a "builtin" fixup already present
+ involving this symbol. If so, convert it to a regular
+ fixup. In the end, this relaxes some of the requirements
+ about the order of performing fixups. */
+ exists = false;
+ for (f1 = linux_hash_table (info)->fixup_list;
+ f1 != NULL;
+ f1 = f1->next)
+ {
+ if ((f1->h != h && f1->h != h1)
+ || (! f1->builtin && ! f1->jump))
+ continue;
+ if (f1->h == h1)
+ exists = true;
+ if (! exists
+ && bfd_is_abs_section (h->root.root.u.def.section))
+ {
+ f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
+ f->jump = is_plt;
+ }
+ f1->h = h1;
+ f1->jump = is_plt;
+ f1->builtin = 0;
+ exists = true;
+ }
+ if (! exists
+ && bfd_is_abs_section (h->root.root.u.def.section))
+ {
+ f = new_fixup (info, h1, h->root.root.u.def.value, 0);
+ if (f == NULL)
+ {
+ /* FIXME: No way to return error. */
+ abort ();
+ }
+ f->jump = is_plt;
+ }
+ }
+
+ /* Quick and dirty way of stripping these symbols from the
+ symtab. */
+ if (bfd_is_abs_section (h->root.root.u.def.section))
+ h->root.written = true;
+ }
+
+ return true;
+}
+
+/* This is called to set the size of the .linux-dynamic section is.
+ It is called by the Linux linker emulation before_allocation
+ routine. We have finished reading all of the input files, and now
+ we just scan the hash tables to find out how many additional fixups
+ are required. */
+
+boolean
+bfd_sparclinux_size_dynamic_sections (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ struct fixup *f;
+ asection *s;
+
+ if (output_bfd->xvec != &MY(vec))
+ return true;
+
+ /* First find the fixups... */
+ linux_link_hash_traverse (linux_hash_table (info),
+ linux_tally_symbols,
+ (PTR) info);
+
+ /* If there are builtin fixups, leave room for a marker. This is
+ used by the dynamic linker so that it knows that all that follow
+ are builtin fixups instead of regular fixups. */
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (f->builtin)
+ {
+ ++linux_hash_table (info)->fixup_count;
+ ++linux_hash_table (info)->local_builtins;
+ break;
+ }
+ }
+
+ if (linux_hash_table (info)->dynobj == NULL)
+ {
+ if (linux_hash_table (info)->fixup_count > 0)
+ abort ();
+ return true;
+ }
+
+ /* Allocate memory for our fixup table. We will fill it in later. */
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ if (s != NULL)
+ {
+ s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+ memset (s->contents, 0, (size_t) s->_raw_size);
+ }
+
+ return true;
+}
+
+/* We come here once we are ready to actually write the fixup table to
+ the output file. Scan the fixup tables and so forth and generate
+ the stuff we need. */
+
+static boolean
+linux_finish_dynamic_link (output_bfd, info)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+{
+ asection *s, *os, *is;
+ bfd_byte *fixup_table;
+ struct linux_link_hash_entry *h;
+ struct fixup *f;
+ unsigned int new_addr;
+ int section_offset;
+ unsigned int fixups_written;
+
+ if (linux_hash_table (info)->dynobj == NULL)
+ return true;
+
+ s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
+ ".linux-dynamic");
+ BFD_ASSERT (s != NULL);
+ os = s->output_section;
+ fixups_written = 0;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup table file offset: %x VMA: %x\n",
+ os->filepos + s->output_offset,
+ os->vma + s->output_offset);
+#endif
+
+ fixup_table = s->contents;
+ bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table);
+ fixup_table += 4;
+
+ /* Fill in fixup table. */
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (f->builtin)
+ continue;
+
+ if (f->h->root.root.type != bfd_link_hash_defined
+ && f->h->root.root.type != bfd_link_hash_defweak)
+ {
+ (*_bfd_error_handler)
+ (_("Symbol %s not defined for fixups\n"),
+ f->h->root.root.root.string);
+ continue;
+ }
+
+ is = f->h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = f->h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
+ new_addr, f->value);
+#endif
+
+ if (f->jump)
+ {
+ /* Relative address */
+ new_addr = new_addr - (f->value + 5);
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value + 1, fixup_table);
+ fixup_table += 4;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value, fixup_table);
+ fixup_table += 4;
+ }
+ ++fixups_written;
+ }
+
+ if (linux_hash_table (info)->local_builtins != 0)
+ {
+ /* Special marker so we know to switch to the other type of fixup */
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
+ {
+ if (! f->builtin)
+ continue;
+
+ if (f->h->root.root.type != bfd_link_hash_defined
+ && f->h->root.root.type != bfd_link_hash_defweak)
+ {
+ (*_bfd_error_handler)
+ (_("Symbol %s not defined for fixups\n"),
+ f->h->root.root.root.string);
+ continue;
+ }
+
+ is = f->h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = f->h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
+ new_addr, f->value);
+#endif
+
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, f->value, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ }
+ }
+
+ if (linux_hash_table (info)->fixup_count != fixups_written)
+ {
+ (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
+ while (linux_hash_table (info)->fixup_count > fixups_written)
+ {
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, 0, fixup_table);
+ fixup_table += 4;
+ ++fixups_written;
+ }
+ }
+
+ h = linux_link_hash_lookup (linux_hash_table (info),
+ "__BUILTIN_FIXUPS__",
+ false, false, false);
+
+ if (h != NULL
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak))
+ {
+ is = h->root.root.u.def.section;
+ section_offset = is->output_section->vma + is->output_offset;
+ new_addr = h->root.root.u.def.value + section_offset;
+
+#ifdef LINUX_LINK_DEBUG
+ printf ("Builtin fixup table at %x\n", new_addr);
+#endif
+
+ bfd_put_32 (output_bfd, new_addr, fixup_table);
+ }
+ else
+ bfd_put_32 (output_bfd, 0, fixup_table);
+
+ if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0)
+ return false;
+
+ if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd)
+ != s->_raw_size)
+ return false;
+
+ return true;
+}
+
+#define MY_bfd_link_hash_table_create linux_link_hash_table_create
+#define MY_add_one_symbol linux_add_one_symbol
+#define MY_finish_dynamic_link linux_finish_dynamic_link
+
+#define MY_zmagic_contiguous 1
+
+#include "aout-target.h"
diff --git a/bfd/sparclynx.c b/bfd/sparclynx.c
new file mode 100644
index 00000000000..dbfcae55cbe
--- /dev/null
+++ b/bfd/sparclynx.c
@@ -0,0 +1,266 @@
+/* BFD support for Sparc binaries under LynxOS.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 97, 1998
+ Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if 0
+#define BYTES_IN_WORD 4
+#define N_SHARED_LIB(x) 0
+
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_sparc
+
+#endif
+
+#define MY(OP) CAT(sparclynx_aout_,OP)
+#define TARGETNAME "a.out-sparc-lynx"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "aout/sun4.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+/* This is needed to reject a NewsOS file, e.g. in
+ gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
+ I needed to add M_UNKNOWN to recognize a 68000 object, so this will
+ probably no longer reject a NewsOS object. <ian@cygnus.com>. */
+#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
+ || (mtype) == M_68010 \
+ || (mtype) == M_68020 \
+ || (mtype) == M_SPARC)
+
+/*
+The file @code{aoutf1.h} contains the code for BFD's
+a.out back end. Control over the generated back end is given by these
+two preprocessor names:
+@table @code
+@item ARCH_SIZE
+This value should be either 32 or 64, depending upon the size of an
+int in the target format. It changes the sizes of the structs which
+perform the memory/disk mapping of structures.
+
+The 64 bit backend may only be used if the host compiler supports 64
+ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}.
+With this name defined, @emph{all} bfd operations are performed with 64bit
+arithmetic, not just those to a 64bit target.
+
+@item TARGETNAME
+The name put into the target vector.
+@item
+@end table
+
+*/
+
+/*SUPPRESS558*/
+/*SUPPRESS529*/
+
+void
+NAME(lynx,set_arch_mach) (abfd, machtype)
+ bfd *abfd;
+ int machtype;
+{
+ /* Determine the architecture and machine type of the object file. */
+ enum bfd_architecture arch;
+ long machine;
+ switch (machtype)
+ {
+
+ case M_UNKNOWN:
+ /* Some Sun3s make magic numbers without cpu types in them, so
+ we'll default to the 68000. */
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68000;
+ break;
+
+ case M_68010:
+ case M_HP200:
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68010;
+ break;
+
+ case M_68020:
+ case M_HP300:
+ arch = bfd_arch_m68k;
+ machine = bfd_mach_m68020;
+ break;
+
+ case M_SPARC:
+ arch = bfd_arch_sparc;
+ machine = 0;
+ break;
+
+ case M_386:
+ case M_386_DYNIX:
+ arch = bfd_arch_i386;
+ machine = 0;
+ break;
+
+ case M_29K:
+ arch = bfd_arch_a29k;
+ machine = 0;
+ break;
+
+ case M_HPUX:
+ arch = bfd_arch_m68k;
+ machine = 0;
+ break;
+
+ default:
+ arch = bfd_arch_obscure;
+ machine = 0;
+ break;
+ }
+ bfd_set_arch_mach (abfd, arch, machine);
+}
+
+#define SET_ARCH_MACH(ABFD, EXEC) \
+ NAME(lynx,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
+ choose_reloc_size(ABFD);
+
+/* Determine the size of a relocation entry, based on the architecture */
+static void
+choose_reloc_size (abfd)
+ bfd *abfd;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ case bfd_arch_a29k:
+ obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+ break;
+ default:
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+ break;
+ }
+}
+
+/* Write an object file in LynxOS format.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static boolean
+NAME(aout,sparclynx_write_object_contents) (abfd)
+ bfd *abfd;
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ /* Magic number, maestro, please! */
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_m68010:
+ N_SET_MACHTYPE (*execp, M_68010);
+ break;
+ default:
+ case bfd_mach_m68020:
+ N_SET_MACHTYPE (*execp, M_68020);
+ break;
+ }
+ break;
+ case bfd_arch_sparc:
+ N_SET_MACHTYPE (*execp, M_SPARC);
+ break;
+ case bfd_arch_i386:
+ N_SET_MACHTYPE (*execp, M_386);
+ break;
+ case bfd_arch_a29k:
+ N_SET_MACHTYPE (*execp, M_29K);
+ break;
+ default:
+ N_SET_MACHTYPE (*execp, M_UNKNOWN);
+ }
+
+ choose_reloc_size (abfd);
+
+ N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
+
+ WRITE_HEADERS (abfd, execp);
+
+ return true;
+}
+
+#define MY_set_sizes sparclynx_set_sizes
+static boolean
+sparclynx_set_sizes (abfd)
+ bfd *abfd;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ default:
+ return false;
+ case bfd_arch_sparc:
+ adata (abfd).page_size = 0x2000;
+ adata (abfd).segment_size = 0x2000;
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+ return true;
+ case bfd_arch_m68k:
+ adata (abfd).page_size = 0x2000;
+ adata (abfd).segment_size = 0x20000;
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+ return true;
+ }
+}
+
+static CONST struct aout_backend_data sparclynx_aout_backend =
+{
+ 0, 1, 0, 1, 0, sparclynx_set_sizes, 0,
+ 0, /* add_dynamic_symbols */
+ 0, /* add_one_symbol */
+ 0, /* link_dynamic_object */
+ 0, /* write_dynamic_symbol */
+ 0, /* check_dynamic_reloc */
+ 0 /* finish_dynamic_link */
+};
+
+
+#define MY_bfd_debug_info_start bfd_void
+#define MY_bfd_debug_info_end bfd_void
+#define MY_bfd_debug_info_accumulate \
+ (void (*) PARAMS ((bfd *, struct sec *))) bfd_void
+
+#define MY_write_object_contents NAME(aout,sparclynx_write_object_contents)
+#define MY_backend_data &sparclynx_aout_backend
+
+#define TARGET_IS_BIG_ENDIAN_P
+
+#ifdef LYNX_CORE
+
+char *lynx_core_file_failing_command ();
+int lynx_core_file_failing_signal ();
+boolean lynx_core_file_matches_executable_p ();
+const bfd_target *lynx_core_file_p ();
+
+#define MY_core_file_failing_command lynx_core_file_failing_command
+#define MY_core_file_failing_signal lynx_core_file_failing_signal
+#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p
+#define MY_core_file_p lynx_core_file_p
+
+#endif /* LYNX_CORE */
+
+#include "aout-target.h"
diff --git a/bfd/sparcnetbsd.c b/bfd/sparcnetbsd.c
new file mode 100644
index 00000000000..4277bb8914d
--- /dev/null
+++ b/bfd/sparcnetbsd.c
@@ -0,0 +1,34 @@
+/* BFD back-end for NetBSD/sparc a.out-ish binaries.
+ Copyright (C) 1990, 91, 92, 94, 95, 97, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#define TARGET_IS_BIG_ENDIAN_P
+
+/* SPARC chips use either 4K or 8K pages, but object files always
+ assume 8K page alignment so they will work on either one. */
+#define TARGET_PAGE_SIZE 0x2000
+
+#define DEFAULT_ARCH bfd_arch_sparc
+#define DEFAULT_MID M_SPARC_NETBSD
+
+#define MY(OP) CAT(sparcnetbsd_,OP)
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-sparc-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/srec.c b/bfd/srec.c
new file mode 100644
index 00000000000..70d2f96175e
--- /dev/null
+++ b/bfd/srec.c
@@ -0,0 +1,1377 @@
+/* BFD back-end for s-record objects.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SUBSECTION
+ S-Record handling
+
+DESCRIPTION
+
+ Ordinary S-Records cannot hold anything but addresses and
+ data, so that's all that we implement.
+
+ The only interesting thing is that S-Records may come out of
+ order and there is no header, so an initial scan is required
+ to discover the minimum and maximum addresses used to create
+ the vma and size of the only section we create. We
+ arbitrarily call this section ".text".
+
+ When bfd_get_section_contents is called the file is read
+ again, and this time the data is placed into a bfd_alloc'd
+ area.
+
+ Any number of sections may be created for output, we save them
+ up and output them when it's time to close the bfd.
+
+ An s record looks like:
+
+EXAMPLE
+ S<type><length><address><data><checksum>
+
+DESCRIPTION
+ Where
+ o length
+ is the number of bytes following upto the checksum. Note that
+ this is not the number of chars following, since it takes two
+ chars to represent a byte.
+ o type
+ is one of:
+ 0) header record
+ 1) two byte address data record
+ 2) three byte address data record
+ 3) four byte address data record
+ 7) four byte address termination record
+ 8) three byte address termination record
+ 9) two byte address termination record
+
+ o address
+ is the start address of the data following, or in the case of
+ a termination record, the start address of the image
+ o data
+ is the data.
+ o checksum
+ is the sum of all the raw byte data in the record, from the length
+ upwards, modulo 256 and subtracted from 255.
+
+
+SUBSECTION
+ Symbol S-Record handling
+
+DESCRIPTION
+ Some ICE equipment understands an addition to the standard
+ S-Record format; symbols and their addresses can be sent
+ before the data.
+
+ The format of this is:
+ ($$ <modulename>
+ (<space> <symbol> <address>)*)
+ $$
+
+ so a short symbol table could look like:
+
+EXAMPLE
+ $$ flash.x
+ $$ flash.c
+ _port6 $0
+ _delay $4
+ _start $14
+ _etext $8036
+ _edata $8036
+ _end $8036
+ $$
+
+DESCRIPTION
+ We allow symbols to be anywhere in the data stream - the module names
+ are always ignored.
+
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include <ctype.h>
+
+static void srec_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static void srec_print_symbol
+ PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+static void srec_init PARAMS ((void));
+static boolean srec_mkobject PARAMS ((bfd *));
+static int srec_get_byte PARAMS ((bfd *, boolean *));
+static void srec_bad_byte PARAMS ((bfd *, unsigned int, int, boolean));
+static boolean srec_scan PARAMS ((bfd *));
+static const bfd_target *srec_object_p PARAMS ((bfd *));
+static const bfd_target *symbolsrec_object_p PARAMS ((bfd *));
+static boolean srec_read_section PARAMS ((bfd *, asection *, bfd_byte *));
+
+static boolean srec_write_record PARAMS ((bfd *, int, bfd_vma,
+ const bfd_byte *,
+ const bfd_byte *));
+static boolean srec_write_header PARAMS ((bfd *));
+static boolean srec_write_symbols PARAMS ((bfd *));
+static boolean srec_new_symbol PARAMS ((bfd *, const char *, bfd_vma));
+static boolean srec_get_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static boolean srec_set_arch_mach
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+static boolean srec_set_section_contents
+ PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+static boolean internal_srec_write_object_contents PARAMS ((bfd *, int));
+static boolean srec_write_object_contents PARAMS ((bfd *));
+static boolean symbolsrec_write_object_contents PARAMS ((bfd *));
+static int srec_sizeof_headers PARAMS ((bfd *, boolean));
+static asymbol *srec_make_empty_symbol PARAMS ((bfd *));
+static long srec_get_symtab_upper_bound PARAMS ((bfd *));
+static long srec_get_symtab PARAMS ((bfd *, asymbol **));
+
+/* Macros for converting between hex and binary. */
+
+static CONST char digs[] = "0123456789ABCDEF";
+
+#define NIBBLE(x) hex_value(x)
+#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
+#define TOHEX(d, x, ch) \
+ d[1] = digs[(x) & 0xf]; \
+ d[0] = digs[((x)>>4)&0xf]; \
+ ch += ((x) & 0xff);
+#define ISHEX(x) hex_p(x)
+
+/* Initialize by filling in the hex conversion array. */
+
+static void
+srec_init ()
+{
+ static boolean inited = false;
+
+ if (inited == false)
+ {
+ inited = true;
+ hex_init ();
+ }
+}
+
+/* The maximum number of bytes on a line is FF */
+#define MAXCHUNK 0xff
+/* The number of bytes we fit onto a line on output */
+#define CHUNK 21
+
+/* When writing an S-record file, the S-records can not be output as
+ they are seen. This structure is used to hold them in memory. */
+
+struct srec_data_list_struct
+{
+ struct srec_data_list_struct *next;
+ bfd_byte *data;
+ bfd_vma where;
+ bfd_size_type size;
+};
+
+typedef struct srec_data_list_struct srec_data_list_type;
+
+/* When scanning the S-record file, a linked list of srec_symbol
+ structures is built to represent the symbol table (if there is
+ one). */
+
+struct srec_symbol
+{
+ struct srec_symbol *next;
+ const char *name;
+ bfd_vma val;
+};
+
+/* The S-record tdata information. */
+
+typedef struct srec_data_struct
+ {
+ srec_data_list_type *head;
+ srec_data_list_type *tail;
+ unsigned int type;
+ struct srec_symbol *symbols;
+ struct srec_symbol *symtail;
+ asymbol *csymbols;
+ }
+tdata_type;
+
+static boolean srec_write_section PARAMS ((bfd *, tdata_type *,
+ srec_data_list_type *));
+static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *));
+
+/* Set up the S-record tdata information. */
+
+static boolean
+srec_mkobject (abfd)
+ bfd *abfd;
+{
+ srec_init ();
+
+ if (abfd->tdata.srec_data == NULL)
+ {
+ tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
+ if (tdata == NULL)
+ return false;
+ abfd->tdata.srec_data = tdata;
+ tdata->type = 1;
+ tdata->head = NULL;
+ tdata->tail = NULL;
+ tdata->symbols = NULL;
+ tdata->symtail = NULL;
+ tdata->csymbols = NULL;
+ }
+
+ return true;
+}
+
+/* Read a byte from an S record file. Set *ERRORPTR if an error
+ occurred. Return EOF on error or end of file. */
+
+static int
+srec_get_byte (abfd, errorptr)
+ bfd *abfd;
+ boolean *errorptr;
+{
+ bfd_byte c;
+
+ if (bfd_read (&c, 1, 1, abfd) != 1)
+ {
+ if (bfd_get_error () != bfd_error_file_truncated)
+ *errorptr = true;
+ return EOF;
+ }
+
+ return (int) (c & 0xff);
+}
+
+/* Report a problem in an S record file. FIXME: This probably should
+ not call fprintf, but we really do need some mechanism for printing
+ error messages. */
+
+static void
+srec_bad_byte (abfd, lineno, c, error)
+ bfd *abfd;
+ unsigned int lineno;
+ int c;
+ boolean error;
+{
+ if (c == EOF)
+ {
+ if (! error)
+ bfd_set_error (bfd_error_file_truncated);
+ }
+ else
+ {
+ char buf[10];
+
+ if (! isprint (c))
+ sprintf (buf, "\\%03o", (unsigned int) c);
+ else
+ {
+ buf[0] = c;
+ buf[1] = '\0';
+ }
+ (*_bfd_error_handler)
+ (_("%s:%d: Unexpected character `%s' in S-record file\n"),
+ bfd_get_filename (abfd), lineno, buf);
+ bfd_set_error (bfd_error_bad_value);
+ }
+}
+
+/* Add a new symbol found in an S-record file. */
+
+static boolean
+srec_new_symbol (abfd, name, val)
+ bfd *abfd;
+ const char *name;
+ bfd_vma val;
+{
+ struct srec_symbol *n;
+
+ n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (struct srec_symbol));
+ if (n == NULL)
+ return false;
+
+ n->name = name;
+ n->val = val;
+
+ if (abfd->tdata.srec_data->symbols == NULL)
+ abfd->tdata.srec_data->symbols = n;
+ else
+ abfd->tdata.srec_data->symtail->next = n;
+ abfd->tdata.srec_data->symtail = n;
+ n->next = NULL;
+
+ ++abfd->symcount;
+
+ return true;
+}
+
+/* Read the S record file and turn it into sections. We create a new
+ section for each contiguous set of bytes. */
+
+static boolean
+srec_scan (abfd)
+ bfd *abfd;
+{
+ int c;
+ unsigned int lineno = 1;
+ boolean error = false;
+ bfd_byte *buf = NULL;
+ size_t bufsize = 0;
+ asection *sec = NULL;
+ char *symbuf = NULL;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto error_return;
+
+ while ((c = srec_get_byte (abfd, &error)) != EOF)
+ {
+ /* We only build sections from contiguous S-records, so if this
+ is not an S-record, then stop building a section. */
+ if (c != 'S' && c != '\r' && c != '\n')
+ sec = NULL;
+
+ switch (c)
+ {
+ default:
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+
+ case '\n':
+ ++lineno;
+ break;
+
+ case '\r':
+ break;
+
+ case '$':
+ /* Starting a module name, which we ignore. */
+ while ((c = srec_get_byte (abfd, &error)) != '\n'
+ && c != EOF)
+ ;
+ if (c == EOF)
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+
+ ++lineno;
+
+ break;
+
+ case ' ':
+ do
+ {
+ unsigned int alc;
+ char *p, *symname;
+ bfd_vma symval;
+
+ /* Starting a symbol definition. */
+ while ((c = srec_get_byte (abfd, &error)) != EOF
+ && (c == ' ' || c == '\t'))
+ ;
+
+ if (c == '\n' || c == '\r')
+ break;
+
+ if (c == EOF)
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+
+ alc = 10;
+ symbuf = (char *) bfd_malloc (alc + 1);
+ if (symbuf == NULL)
+ goto error_return;
+
+ p = symbuf;
+
+ *p++ = c;
+ while ((c = srec_get_byte (abfd, &error)) != EOF
+ && ! isspace (c))
+ {
+ if ((unsigned int) (p - symbuf) >= alc)
+ {
+ char *n;
+
+ alc *= 2;
+ n = (char *) bfd_realloc (symbuf, alc + 1);
+ if (n == NULL)
+ goto error_return;
+ p = n + (p - symbuf);
+ symbuf = n;
+ }
+
+ *p++ = c;
+ }
+
+ if (c == EOF)
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+
+ *p++ = '\0';
+ symname = bfd_alloc (abfd, p - symbuf);
+ if (symname == NULL)
+ goto error_return;
+ strcpy (symname, symbuf);
+ free (symbuf);
+ symbuf = NULL;
+
+ while ((c = srec_get_byte (abfd, &error)) != EOF
+ && (c == ' ' || c == '\t'))
+ ;
+ if (c == EOF)
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+
+ /* Skip a dollar sign before the hex value. */
+ if (c == '$')
+ {
+ c = srec_get_byte (abfd, &error);
+ if (c == EOF)
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+ }
+
+ symval = 0;
+ while (ISHEX (c))
+ {
+ symval <<= 4;
+ symval += NIBBLE (c);
+ c = srec_get_byte (abfd, &error);
+ }
+
+ if (! srec_new_symbol (abfd, symname, symval))
+ goto error_return;
+ }
+ while (c == ' ' || c == '\t');
+
+ if (c == '\n')
+ ++lineno;
+ else if (c != '\r')
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+
+ break;
+
+ case 'S':
+ {
+ file_ptr pos;
+ char hdr[3];
+ unsigned int bytes;
+ bfd_vma address;
+ bfd_byte *data;
+
+ /* Starting an S-record. */
+
+ pos = bfd_tell (abfd) - 1;
+
+ if (bfd_read (hdr, 1, 3, abfd) != 3)
+ goto error_return;
+
+ if (! ISHEX (hdr[1]) || ! ISHEX (hdr[2]))
+ {
+ if (! ISHEX (hdr[1]))
+ c = hdr[1];
+ else
+ c = hdr[2];
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+
+ bytes = HEX (hdr + 1);
+ if (bytes * 2 > bufsize)
+ {
+ if (buf != NULL)
+ free (buf);
+ buf = (bfd_byte *) bfd_malloc (bytes * 2);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = bytes * 2;
+ }
+
+ if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
+ goto error_return;
+
+ /* Ignore the checksum byte. */
+ --bytes;
+
+ address = 0;
+ data = buf;
+ switch (hdr[0])
+ {
+ case '0':
+ case '5':
+ /* Prologue--ignore the file name, but stop building a
+ section at this point. */
+ sec = NULL;
+ break;
+
+ case '3':
+ address = HEX (data);
+ data += 2;
+ --bytes;
+ /* Fall through. */
+ case '2':
+ address = (address << 8) | HEX (data);
+ data += 2;
+ --bytes;
+ /* Fall through. */
+ case '1':
+ address = (address << 8) | HEX (data);
+ data += 2;
+ address = (address << 8) | HEX (data);
+ data += 2;
+ bytes -= 2;
+
+ if (sec != NULL
+ && sec->vma + sec->_raw_size == address)
+ {
+ /* This data goes at the end of the section we are
+ currently building. */
+ sec->_raw_size += bytes;
+ }
+ else
+ {
+ char secbuf[20];
+ char *secname;
+
+ sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
+ secname = (char *) bfd_alloc (abfd, strlen (secbuf) + 1);
+ strcpy (secname, secbuf);
+ sec = bfd_make_section (abfd, secname);
+ if (sec == NULL)
+ goto error_return;
+ sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ sec->vma = address;
+ sec->lma = address;
+ sec->_raw_size = bytes;
+ sec->filepos = pos;
+ }
+
+ break;
+
+ case '7':
+ address = HEX (data);
+ data += 2;
+ /* Fall through. */
+ case '8':
+ address = (address << 8) | HEX (data);
+ data += 2;
+ /* Fall through. */
+ case '9':
+ address = (address << 8) | HEX (data);
+ data += 2;
+ address = (address << 8) | HEX (data);
+ data += 2;
+
+ /* This is a termination record. */
+ abfd->start_address = address;
+
+ if (buf != NULL)
+ free (buf);
+
+ return true;
+ }
+ }
+ break;
+ }
+ }
+
+ if (error)
+ goto error_return;
+
+ if (buf != NULL)
+ free (buf);
+
+ return true;
+
+ error_return:
+ if (symbuf != NULL)
+ free (symbuf);
+ if (buf != NULL)
+ free (buf);
+ return false;
+}
+
+/* Check whether an existing file is an S-record file. */
+
+static const bfd_target *
+srec_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_byte b[4];
+
+ srec_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_read (b, 1, 4, abfd) != 4)
+ return NULL;
+
+ if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (! srec_mkobject (abfd)
+ || ! srec_scan (abfd))
+ return NULL;
+
+ if (abfd->symcount > 0)
+ abfd->flags |= HAS_SYMS;
+
+ return abfd->xvec;
+}
+
+/* Check whether an existing file is an S-record file with symbols. */
+
+static const bfd_target *
+symbolsrec_object_p (abfd)
+ bfd *abfd;
+{
+ char b[2];
+
+ srec_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_read (b, 1, 2, abfd) != 2)
+ return NULL;
+
+ if (b[0] != '$' || b[1] != '$')
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (! srec_mkobject (abfd)
+ || ! srec_scan (abfd))
+ return NULL;
+
+ if (abfd->symcount > 0)
+ abfd->flags |= HAS_SYMS;
+
+ return abfd->xvec;
+}
+
+/* Read in the contents of a section in an S-record file. */
+
+static boolean
+srec_read_section (abfd, section, contents)
+ bfd *abfd;
+ asection *section;
+ bfd_byte *contents;
+{
+ int c;
+ bfd_size_type sofar = 0;
+ boolean error = false;
+ bfd_byte *buf = NULL;
+ size_t bufsize = 0;
+
+ if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ while ((c = srec_get_byte (abfd, &error)) != EOF)
+ {
+ bfd_byte hdr[3];
+ unsigned int bytes;
+ bfd_vma address;
+ bfd_byte *data;
+
+ if (c == '\r' || c == '\n')
+ continue;
+
+ /* This is called after srec_scan has already been called, so we
+ ought to know the exact format. */
+ BFD_ASSERT (c == 'S');
+
+ if (bfd_read (hdr, 1, 3, abfd) != 3)
+ goto error_return;
+
+ BFD_ASSERT (ISHEX (hdr[1]) && ISHEX (hdr[2]));
+
+ bytes = HEX (hdr + 1);
+
+ if (bytes * 2 > bufsize)
+ {
+ if (buf != NULL)
+ free (buf);
+ buf = (bfd_byte *) bfd_malloc (bytes * 2);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = bytes * 2;
+ }
+
+ if (bfd_read (buf, 1, bytes * 2, abfd) != bytes * 2)
+ goto error_return;
+
+ address = 0;
+ data = buf;
+ switch (hdr[0])
+ {
+ default:
+ BFD_ASSERT (sofar == section->_raw_size);
+ if (buf != NULL)
+ free (buf);
+ return true;
+
+ case '3':
+ address = HEX (data);
+ data += 2;
+ --bytes;
+ /* Fall through. */
+ case '2':
+ address = (address << 8) | HEX (data);
+ data += 2;
+ --bytes;
+ /* Fall through. */
+ case '1':
+ address = (address << 8) | HEX (data);
+ data += 2;
+ address = (address << 8) | HEX (data);
+ data += 2;
+ bytes -= 2;
+
+ if (address != section->vma + sofar)
+ {
+ /* We've come to the end of this section. */
+ BFD_ASSERT (sofar == section->_raw_size);
+ if (buf != NULL)
+ free (buf);
+ return true;
+ }
+
+ /* Don't consider checksum. */
+ --bytes;
+
+ while (bytes-- != 0)
+ {
+ contents[sofar] = HEX (data);
+ data += 2;
+ ++sofar;
+ }
+
+ break;
+ }
+ }
+
+ if (error)
+ goto error_return;
+
+ BFD_ASSERT (sofar == section->_raw_size);
+
+ if (buf != NULL)
+ free (buf);
+
+ return true;
+
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ return false;
+}
+
+/* Get the contents of a section in an S-record file. */
+
+static boolean
+srec_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (section->used_by_bfd == NULL)
+ {
+ section->used_by_bfd = bfd_alloc (abfd, section->_raw_size);
+ if (section->used_by_bfd == NULL
+ && section->_raw_size != 0)
+ return false;
+
+ if (! srec_read_section (abfd, section, section->used_by_bfd))
+ return false;
+ }
+
+ memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
+ (size_t) count);
+
+ return true;
+}
+
+/* Set the architecture. We accept an unknown architecture here. */
+
+static boolean
+srec_set_arch_mach (abfd, arch, mach)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long mach;
+{
+ if (arch == bfd_arch_unknown)
+ {
+ abfd->arch_info = &bfd_default_arch_struct;
+ return true;
+ }
+ return bfd_default_set_arch_mach (abfd, arch, mach);
+}
+
+/* we have to save up all the Srecords for a splurge before output */
+
+static boolean
+srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type bytes_to_do;
+{
+ tdata_type *tdata = abfd->tdata.srec_data;
+ register srec_data_list_type *entry;
+
+ entry = ((srec_data_list_type *)
+ bfd_alloc (abfd, sizeof (srec_data_list_type)));
+ if (entry == NULL)
+ return false;
+
+ if (bytes_to_do
+ && (section->flags & SEC_ALLOC)
+ && (section->flags & SEC_LOAD))
+ {
+ bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
+ if (data == NULL)
+ return false;
+ memcpy ((PTR) data, location, (size_t) bytes_to_do);
+
+ if ((section->lma + offset + bytes_to_do - 1) <= 0xffff)
+ {
+
+ }
+ else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff
+ && tdata->type <= 2)
+ {
+ tdata->type = 2;
+ }
+ else
+ {
+ tdata->type = 3;
+ }
+
+ entry->data = data;
+ entry->where = section->lma + offset;
+ entry->size = bytes_to_do;
+
+ /* Sort the records by address. Optimize for the common case of
+ adding a record to the end of the list. */
+ if (tdata->tail != NULL
+ && entry->where >= tdata->tail->where)
+ {
+ tdata->tail->next = entry;
+ entry->next = NULL;
+ tdata->tail = entry;
+ }
+ else
+ {
+ register srec_data_list_type **look;
+
+ for (look = &tdata->head;
+ *look != NULL && (*look)->where < entry->where;
+ look = &(*look)->next)
+ ;
+ entry->next = *look;
+ *look = entry;
+ if (entry->next == NULL)
+ tdata->tail = entry;
+ }
+ }
+ return true;
+}
+
+/* Write a record of type, of the supplied number of bytes. The
+ supplied bytes and length don't have a checksum. That's worked out
+ here
+*/
+static boolean
+srec_write_record (abfd, type, address, data, end)
+ bfd *abfd;
+ int type;
+ bfd_vma address;
+ const bfd_byte *data;
+ const bfd_byte *end;
+{
+ char buffer[MAXCHUNK];
+ unsigned int check_sum = 0;
+ CONST bfd_byte *src = data;
+ char *dst = buffer;
+ char *length;
+ bfd_size_type wrlen;
+
+ *dst++ = 'S';
+ *dst++ = '0' + type;
+
+ length = dst;
+ dst += 2; /* leave room for dst*/
+
+ switch (type)
+ {
+ case 3:
+ case 7:
+ TOHEX (dst, (address >> 24), check_sum);
+ dst += 2;
+ case 8:
+ case 2:
+ TOHEX (dst, (address >> 16), check_sum);
+ dst += 2;
+ case 9:
+ case 1:
+ case 0:
+ TOHEX (dst, (address >> 8), check_sum);
+ dst += 2;
+ TOHEX (dst, (address), check_sum);
+ dst += 2;
+ break;
+
+ }
+ for (src = data; src < end; src++)
+ {
+ TOHEX (dst, *src, check_sum);
+ dst += 2;
+ }
+
+ /* Fill in the length */
+ TOHEX (length, (dst - length) / 2, check_sum);
+ check_sum &= 0xff;
+ check_sum = 255 - check_sum;
+ TOHEX (dst, check_sum, check_sum);
+ dst += 2;
+
+ *dst++ = '\r';
+ *dst++ = '\n';
+ wrlen = dst - buffer;
+ if (bfd_write ((PTR) buffer, 1, wrlen, abfd) != wrlen)
+ return false;
+ return true;
+}
+
+
+
+static boolean
+srec_write_header (abfd)
+ bfd *abfd;
+{
+ bfd_byte buffer[MAXCHUNK];
+ bfd_byte *dst = buffer;
+ unsigned int i;
+
+ /* I'll put an arbitary 40 char limit on header size */
+ for (i = 0; i < 40 && abfd->filename[i]; i++)
+ {
+ *dst++ = abfd->filename[i];
+ }
+ return srec_write_record (abfd, 0, 0, buffer, dst);
+}
+
+static boolean
+srec_write_section (abfd, tdata, list)
+ bfd *abfd;
+ tdata_type *tdata;
+ srec_data_list_type *list;
+{
+ unsigned int bytes_written = 0;
+ bfd_byte *location = list->data;
+
+ while (bytes_written < list->size)
+ {
+ bfd_vma address;
+
+ unsigned int bytes_this_chunk = list->size - bytes_written;
+
+ if (bytes_this_chunk > CHUNK)
+ {
+ bytes_this_chunk = CHUNK;
+ }
+
+ address = list->where + bytes_written;
+
+ if (! srec_write_record (abfd,
+ tdata->type,
+ address,
+ location,
+ location + bytes_this_chunk))
+ return false;
+
+ bytes_written += bytes_this_chunk;
+ location += bytes_this_chunk;
+ }
+
+ return true;
+}
+
+static boolean
+srec_write_terminator (abfd, tdata)
+ bfd *abfd;
+ tdata_type *tdata;
+{
+ bfd_byte buffer[2];
+
+ return srec_write_record (abfd, 10 - tdata->type,
+ abfd->start_address, buffer, buffer);
+}
+
+
+
+static boolean
+srec_write_symbols (abfd)
+ bfd *abfd;
+{
+ char buffer[MAXCHUNK];
+ /* Dump out the symbols of a bfd */
+ int i;
+ int count = bfd_get_symcount (abfd);
+
+ if (count)
+ {
+ size_t len;
+ asymbol **table = bfd_get_outsymbols (abfd);
+ sprintf (buffer, "$$ %s\r\n", abfd->filename);
+
+ len = strlen (buffer);
+ if (bfd_write (buffer, len, 1, abfd) != len)
+ return false;
+
+ for (i = 0; i < count; i++)
+ {
+ asymbol *s = table[i];
+ if (! bfd_is_local_label (abfd, s)
+ && (s->flags & BSF_DEBUGGING) == 0)
+ {
+ /* Just dump out non debug symbols */
+ bfd_size_type l;
+ char buf2[40], *p;
+
+ sprintf_vma (buf2,
+ s->value + s->section->output_section->lma
+ + s->section->output_offset);
+ p = buf2;
+ while (p[0] == '0' && p[1] != 0)
+ p++;
+ sprintf (buffer, " %s $%s\r\n", s->name, p);
+ l = strlen (buffer);
+ if (bfd_write (buffer, l, 1, abfd) != l)
+ return false;
+ }
+ }
+ sprintf (buffer, "$$ \r\n");
+ len = strlen (buffer);
+ if (bfd_write (buffer, len, 1, abfd) != len)
+ return false;
+ }
+
+ return true;
+}
+
+static boolean
+internal_srec_write_object_contents (abfd, symbols)
+ bfd *abfd;
+ int symbols;
+{
+ tdata_type *tdata = abfd->tdata.srec_data;
+ srec_data_list_type *list;
+
+ if (symbols)
+ {
+ if (! srec_write_symbols (abfd))
+ return false;
+ }
+
+ if (! srec_write_header (abfd))
+ return false;
+
+ /* Now wander though all the sections provided and output them */
+ list = tdata->head;
+
+ while (list != (srec_data_list_type *) NULL)
+ {
+ if (! srec_write_section (abfd, tdata, list))
+ return false;
+ list = list->next;
+ }
+ return srec_write_terminator (abfd, tdata);
+}
+
+static boolean
+srec_write_object_contents (abfd)
+ bfd *abfd;
+{
+ return internal_srec_write_object_contents (abfd, 0);
+}
+
+static boolean
+symbolsrec_write_object_contents (abfd)
+ bfd *abfd;
+{
+ return internal_srec_write_object_contents (abfd, 1);
+}
+
+/*ARGSUSED*/
+static int
+srec_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return 0;
+}
+
+static asymbol *
+srec_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+srec_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
+}
+
+/* Return the symbol table. */
+
+static long
+srec_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ unsigned int symcount = bfd_get_symcount (abfd);
+ asymbol *csymbols;
+ unsigned int i;
+
+ csymbols = abfd->tdata.srec_data->csymbols;
+ if (csymbols == NULL)
+ {
+ asymbol *c;
+ struct srec_symbol *s;
+
+ csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
+ if (csymbols == NULL && symcount != 0)
+ return false;
+ abfd->tdata.srec_data->csymbols = csymbols;
+
+ for (s = abfd->tdata.srec_data->symbols, c = csymbols;
+ s != NULL;
+ s = s->next, ++c)
+ {
+ c->the_bfd = abfd;
+ c->name = s->name;
+ c->value = s->val;
+ c->flags = BSF_GLOBAL;
+ c->section = bfd_abs_section_ptr;
+ c->udata.p = NULL;
+ }
+ }
+
+ for (i = 0; i < symcount; i++)
+ *alocation++ = csymbols++;
+ *alocation = NULL;
+
+ return symcount;
+}
+
+/*ARGSUSED*/
+static void
+srec_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/*ARGSUSED*/
+static void
+srec_print_symbol (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ default:
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %-5s %s",
+ symbol->section->name,
+ symbol->name);
+
+ }
+}
+
+#define srec_close_and_cleanup _bfd_generic_close_and_cleanup
+#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define srec_new_section_hook _bfd_generic_new_section_hook
+
+#define srec_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define srec_get_lineno _bfd_nosymbols_get_lineno
+#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define srec_read_minisymbols _bfd_generic_read_minisymbols
+#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define srec_get_reloc_upper_bound \
+ ((long (*) PARAMS ((bfd *, asection *))) bfd_0l)
+#define srec_canonicalize_reloc \
+ ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) bfd_0l)
+#define srec_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define srec_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+#define srec_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define srec_bfd_relax_section bfd_generic_relax_section
+#define srec_bfd_gc_sections bfd_generic_gc_sections
+#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define srec_bfd_final_link _bfd_generic_final_link
+#define srec_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target srec_vec =
+{
+ "srec", /* name */
+ bfd_target_srec_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {
+ _bfd_dummy_target,
+ srec_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ srec_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ srec_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (srec),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (srec),
+ BFD_JUMP_TABLE_RELOCS (srec),
+ BFD_JUMP_TABLE_WRITE (srec),
+ BFD_JUMP_TABLE_LINK (srec),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
+
+
+
+const bfd_target symbolsrec_vec =
+{
+ "symbolsrec", /* name */
+ bfd_target_srec_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {
+ _bfd_dummy_target,
+ symbolsrec_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ srec_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ symbolsrec_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (srec),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (srec),
+ BFD_JUMP_TABLE_RELOCS (srec),
+ BFD_JUMP_TABLE_WRITE (srec),
+ BFD_JUMP_TABLE_LINK (srec),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/stab-syms.c b/bfd/stab-syms.c
new file mode 100644
index 00000000000..f4fe6c8ba3c
--- /dev/null
+++ b/bfd/stab-syms.c
@@ -0,0 +1,57 @@
+/* Table of stab names for the BFD library.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+
+#define ARCH_SIZE 32 /* Value doesn't matter. */
+#include "libaout.h"
+#include "aout/aout64.h"
+
+/* Ignore duplicate stab codes; just return the string for the first
+ one. */
+#define __define_stab(NAME, CODE, STRING) __define_name(CODE, STRING)
+#define __define_stab_duplicate(NAME, CODE, STRING)
+
+/* These are not really stab symbols, but it is
+ convenient to have them here for the sake of nm.
+ For completeness, we could also add N_TEXT etc, but those
+ are never needed, since nm treats those specially. */
+#define EXTRA_SYMBOLS \
+ __define_name (N_SETA, "SETA")/* Absolute set element symbol */ \
+ __define_name (N_SETT, "SETT")/* Text set element symbol */ \
+ __define_name (N_SETD, "SETD")/* Data set element symbol */ \
+ __define_name (N_SETB, "SETB")/* Bss set element symbol */ \
+ __define_name (N_SETV, "SETV")/* Pointer to set vector in data area. */ \
+ __define_name (N_INDR, "INDR") \
+ __define_name (N_WARNING, "WARNING")
+
+const char *
+bfd_get_stab_name (code)
+ int code;
+{
+ switch (code)
+ {
+#define __define_name(val, str) case val: return str;
+#include "aout/stab.def"
+ EXTRA_SYMBOLS
+ }
+
+ return (const char *) 0;
+}
diff --git a/bfd/stabs.c b/bfd/stabs.c
new file mode 100644
index 00000000000..ffc000d499e
--- /dev/null
+++ b/bfd/stabs.c
@@ -0,0 +1,651 @@
+/* Stabs in sections linking support.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file contains support for linking stabs in sections, as used
+ on COFF and ELF. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "aout/stab_gnu.h"
+
+#include <ctype.h>
+
+/* Stabs entries use a 12 byte format:
+ 4 byte string table index
+ 1 byte stab type
+ 1 byte stab other field
+ 2 byte stab desc field
+ 4 byte stab value
+ FIXME: This will have to change for a 64 bit object format.
+
+ The stabs symbols are divided into compilation units. For the
+ first entry in each unit, the type of 0, the value is the length of
+ the string table for this unit, and the desc field is the number of
+ stabs symbols for this unit. */
+
+#define STRDXOFF (0)
+#define TYPEOFF (4)
+#define OTHEROFF (5)
+#define DESCOFF (6)
+#define VALOFF (8)
+#define STABSIZE (12)
+
+/* A hash table used for header files with N_BINCL entries. */
+
+struct stab_link_includes_table
+{
+ struct bfd_hash_table root;
+};
+
+/* A linked list of totals that we have found for a particular header
+ file. */
+
+struct stab_link_includes_totals
+{
+ struct stab_link_includes_totals *next;
+ bfd_vma total;
+};
+
+/* An entry in the header file hash table. */
+
+struct stab_link_includes_entry
+{
+ struct bfd_hash_entry root;
+ /* List of totals we have found for this file. */
+ struct stab_link_includes_totals *totals;
+};
+
+/* Look up an entry in an the header file hash table. */
+
+#define stab_link_includes_lookup(table, string, create, copy) \
+ ((struct stab_link_includes_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* This structure is used to hold a list of N_BINCL symbols, some of
+ which might be converted into N_EXCL symbols. */
+
+struct stab_excl_list
+{
+ /* The next symbol to convert. */
+ struct stab_excl_list *next;
+ /* The offset to this symbol in the section contents. */
+ bfd_size_type offset;
+ /* The value to use for the symbol. */
+ bfd_vma val;
+ /* The type of this symbol (N_BINCL or N_EXCL). */
+ int type;
+};
+
+/* This structure is stored with each .stab section. */
+
+struct stab_section_info
+{
+ /* This is a linked list of N_BINCL symbols which should be
+ converted into N_EXCL symbols. */
+ struct stab_excl_list *excls;
+
+ /* This is used to map input stab offsets within their sections
+ to output stab offsets, to take into account stabs that have
+ been deleted. If it is NULL, the output offsets are the same
+ as the input offsets, because no stabs have been deleted from
+ this section. Otherwise the i'th entry is the number of
+ bytes of stabs that have been deleted prior to the i'th
+ stab. */
+ bfd_size_type *cumulative_skips;
+
+ /* This is an array of string indices. For each stab symbol, we
+ store the string index here. If a stab symbol should not be
+ included in the final output, the string index is -1. */
+ bfd_size_type stridxs[1];
+};
+
+/* This structure is used to keep track of stabs in sections
+ information while linking. */
+
+struct stab_info
+{
+ /* A hash table used to hold stabs strings. */
+ struct bfd_strtab_hash *strings;
+ /* The header file hash table. */
+ struct stab_link_includes_table includes;
+ /* The first .stabstr section. */
+ asection *stabstr;
+};
+
+static struct bfd_hash_entry *stab_link_includes_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+/* The function to create a new entry in the header file hash table. */
+
+static struct bfd_hash_entry *
+stab_link_includes_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct stab_link_includes_entry *ret =
+ (struct stab_link_includes_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct stab_link_includes_entry *) NULL)
+ ret = ((struct stab_link_includes_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct stab_link_includes_entry)));
+ if (ret == (struct stab_link_includes_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct stab_link_includes_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->totals = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* This function is called for each input file from the add_symbols
+ pass of the linker. */
+
+boolean
+_bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
+ bfd *abfd;
+ PTR *psinfo;
+ asection *stabsec;
+ asection *stabstrsec;
+ PTR *psecinfo;
+{
+ boolean first;
+ struct stab_info *sinfo;
+ bfd_size_type count;
+ struct stab_section_info *secinfo;
+ bfd_byte *stabbuf = NULL;
+ bfd_byte *stabstrbuf = NULL;
+ bfd_byte *sym, *symend;
+ bfd_size_type stroff, next_stroff, skip;
+ bfd_size_type *pstridx;
+
+ if (stabsec->_raw_size == 0
+ || stabstrsec->_raw_size == 0)
+ {
+ /* This file does not contain stabs debugging information. */
+ return true;
+ }
+
+ if (stabsec->_raw_size % STABSIZE != 0)
+ {
+ /* Something is wrong with the format of these stab symbols.
+ Don't try to optimize them. */
+ return true;
+ }
+
+ if ((stabstrsec->flags & SEC_RELOC) != 0)
+ {
+ /* We shouldn't see relocations in the strings, and we aren't
+ prepared to handle them. */
+ return true;
+ }
+
+ if ((stabsec->output_section != NULL
+ && bfd_is_abs_section (stabsec->output_section))
+ || (stabstrsec->output_section != NULL
+ && bfd_is_abs_section (stabstrsec->output_section)))
+ {
+ /* At least one of the sections is being discarded from the
+ link, so we should just ignore them. */
+ return true;
+ }
+
+ first = false;
+
+ if (*psinfo == NULL)
+ {
+ /* Initialize the stabs information we need to keep track of. */
+ first = true;
+ *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct stab_info));
+ if (*psinfo == NULL)
+ goto error_return;
+ sinfo = (struct stab_info *) *psinfo;
+ sinfo->strings = _bfd_stringtab_init ();
+ if (sinfo->strings == NULL)
+ goto error_return;
+ if (! bfd_hash_table_init_n (&sinfo->includes.root,
+ stab_link_includes_newfunc,
+ 251))
+ goto error_return;
+ sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
+ sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
+ }
+
+ sinfo = (struct stab_info *) *psinfo;
+
+ /* Initialize the information we are going to store for this .stab
+ section. */
+
+ count = stabsec->_raw_size / STABSIZE;
+
+ *psecinfo = bfd_alloc (abfd,
+ (sizeof (struct stab_section_info)
+ + (count - 1) * sizeof (bfd_size_type)));
+ if (*psecinfo == NULL)
+ goto error_return;
+
+ secinfo = (struct stab_section_info *) *psecinfo;
+ secinfo->excls = NULL;
+ secinfo->cumulative_skips = NULL;
+ memset (secinfo->stridxs, 0, count * sizeof (bfd_size_type));
+
+ /* Read the stabs information from abfd. */
+
+ stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
+ stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
+ if (stabbuf == NULL || stabstrbuf == NULL)
+ goto error_return;
+
+ if (! bfd_get_section_contents (abfd, stabsec, stabbuf, 0,
+ stabsec->_raw_size)
+ || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, 0,
+ stabstrsec->_raw_size))
+ goto error_return;
+
+ /* Look through the stabs symbols, work out the new string indices,
+ and identify N_BINCL symbols which can be eliminated. */
+
+ stroff = 0;
+ next_stroff = 0;
+ skip = 0;
+
+ symend = stabbuf + stabsec->_raw_size;
+ for (sym = stabbuf, pstridx = secinfo->stridxs;
+ sym < symend;
+ sym += STABSIZE, ++pstridx)
+ {
+ int type;
+ const char *string;
+
+ if (*pstridx != 0)
+ {
+ /* This symbol has already been handled by an N_BINCL pass. */
+ continue;
+ }
+
+ type = sym[TYPEOFF];
+
+ if (type == 0)
+ {
+ /* Special type 0 stabs indicate the offset to the next
+ string table. We only copy the very first one. */
+ stroff = next_stroff;
+ next_stroff += bfd_get_32 (abfd, sym + 8);
+ if (! first)
+ {
+ *pstridx = (bfd_size_type) -1;
+ ++skip;
+ continue;
+ }
+ first = false;
+ }
+
+ /* Store the string in the hash table, and record the index. */
+ string = ((char *) stabstrbuf
+ + stroff
+ + bfd_get_32 (abfd, sym + STRDXOFF));
+ *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);
+
+ /* An N_BINCL symbol indicates the start of the stabs entries
+ for a header file. We need to scan ahead to the next N_EINCL
+ symbol, ignoring nesting, adding up all the characters in the
+ symbol names, not including the file numbers in types (the
+ first number after an open parenthesis). */
+ if (type == N_BINCL)
+ {
+ bfd_vma val;
+ int nest;
+ bfd_byte *incl_sym;
+ struct stab_link_includes_entry *incl_entry;
+ struct stab_link_includes_totals *t;
+ struct stab_excl_list *ne;
+
+ val = 0;
+ nest = 0;
+ for (incl_sym = sym + STABSIZE;
+ incl_sym < symend;
+ incl_sym += STABSIZE)
+ {
+ int incl_type;
+
+ incl_type = incl_sym[TYPEOFF];
+ if (incl_type == 0)
+ break;
+ else if (incl_type == N_EINCL)
+ {
+ if (nest == 0)
+ break;
+ --nest;
+ }
+ else if (incl_type == N_BINCL)
+ ++nest;
+ else if (nest == 0)
+ {
+ const char *str;
+
+ str = ((char *) stabstrbuf
+ + stroff
+ + bfd_get_32 (abfd, incl_sym + STRDXOFF));
+ for (; *str != '\0'; str++)
+ {
+ val += *str;
+ if (*str == '(')
+ {
+ /* Skip the file number. */
+ ++str;
+ while (isdigit ((unsigned char) *str))
+ ++str;
+ --str;
+ }
+ }
+ }
+ }
+
+ /* If we have already included a header file with the same
+ value, then replaced this one with an N_EXCL symbol. */
+ incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
+ true, true);
+ if (incl_entry == NULL)
+ goto error_return;
+
+ for (t = incl_entry->totals; t != NULL; t = t->next)
+ if (t->total == val)
+ break;
+
+ /* Record this symbol, so that we can set the value
+ correctly. */
+ ne = (struct stab_excl_list *) bfd_alloc (abfd, sizeof *ne);
+ if (ne == NULL)
+ goto error_return;
+ ne->offset = sym - stabbuf;
+ ne->val = val;
+ ne->type = N_BINCL;
+ ne->next = secinfo->excls;
+ secinfo->excls = ne;
+
+ if (t == NULL)
+ {
+ /* This is the first time we have seen this header file
+ with this set of stabs strings. */
+ t = ((struct stab_link_includes_totals *)
+ bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
+ if (t == NULL)
+ goto error_return;
+ t->total = val;
+ t->next = incl_entry->totals;
+ incl_entry->totals = t;
+ }
+ else
+ {
+ bfd_size_type *incl_pstridx;
+
+ /* We have seen this header file before. Tell the final
+ pass to change the type to N_EXCL. */
+ ne->type = N_EXCL;
+
+ /* Mark the skipped symbols. */
+
+ nest = 0;
+ for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
+ incl_sym < symend;
+ incl_sym += STABSIZE, ++incl_pstridx)
+ {
+ int incl_type;
+
+ incl_type = incl_sym[TYPEOFF];
+
+ if (incl_type == N_EINCL)
+ {
+ if (nest == 0)
+ {
+ *incl_pstridx = (bfd_size_type) -1;
+ ++skip;
+ break;
+ }
+ --nest;
+ }
+ else if (incl_type == N_BINCL)
+ ++nest;
+ else if (nest == 0)
+ {
+ *incl_pstridx = (bfd_size_type) -1;
+ ++skip;
+ }
+ }
+ }
+ }
+ }
+
+ free (stabbuf);
+ stabbuf = NULL;
+ free (stabstrbuf);
+ stabstrbuf = NULL;
+
+ /* We need to set the section sizes such that the linker will
+ compute the output section sizes correctly. We set the .stab
+ size to not include the entries we don't want. We set
+ SEC_EXCLUDE for the .stabstr section, so that it will be dropped
+ from the link. We record the size of the strtab in the first
+ .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
+ for that section. */
+ stabsec->_cooked_size = (count - skip) * STABSIZE;
+ if (stabsec->_cooked_size == 0)
+ stabsec->flags |= SEC_EXCLUDE;
+ stabstrsec->flags |= SEC_EXCLUDE;
+ sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
+
+ /* Calculate the `cumulative_skips' array now that stabs have been
+ deleted for this section. */
+
+ if (skip != 0)
+ {
+ bfd_size_type i, offset;
+ bfd_size_type *pskips;
+
+ secinfo->cumulative_skips =
+ (bfd_size_type *) bfd_alloc (abfd, count * sizeof (bfd_size_type));
+ if (secinfo->cumulative_skips == NULL)
+ goto error_return;
+
+ pskips = secinfo->cumulative_skips;
+ pstridx = secinfo->stridxs;
+ offset = 0;
+
+ for (i = 0; i < count; i++, pskips++, pstridx++)
+ {
+ *pskips = offset;
+ if (*pstridx == (bfd_size_type) -1)
+ offset += STABSIZE;
+ }
+
+ BFD_ASSERT (offset != 0);
+ }
+
+ return true;
+
+ error_return:
+ if (stabbuf != NULL)
+ free (stabbuf);
+ if (stabstrbuf != NULL)
+ free (stabstrbuf);
+ return false;
+}
+
+/* Write out the stab section. This is called with the relocated
+ contents. */
+
+boolean
+_bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
+ bfd *output_bfd;
+ PTR *psinfo;
+ asection *stabsec;
+ PTR *psecinfo;
+ bfd_byte *contents;
+{
+ struct stab_info *sinfo;
+ struct stab_section_info *secinfo;
+ struct stab_excl_list *e;
+ bfd_byte *sym, *tosym, *symend;
+ bfd_size_type *pstridx;
+
+ sinfo = (struct stab_info *) *psinfo;
+ secinfo = (struct stab_section_info *) *psecinfo;
+
+ if (secinfo == NULL)
+ return bfd_set_section_contents (output_bfd, stabsec->output_section,
+ contents, stabsec->output_offset,
+ stabsec->_raw_size);
+
+ /* Handle each N_BINCL entry. */
+ for (e = secinfo->excls; e != NULL; e = e->next)
+ {
+ bfd_byte *excl_sym;
+
+ BFD_ASSERT (e->offset < stabsec->_raw_size);
+ 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->_raw_size;
+ 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->_raw_size / STABSIZE - 1,
+ tosym + DESCOFF);
+ }
+
+ tosym += STABSIZE;
+ }
+ }
+
+ BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);
+
+ return bfd_set_section_contents (output_bfd, stabsec->output_section,
+ contents, stabsec->output_offset,
+ stabsec->_cooked_size);
+}
+
+/* Write out the .stabstr section. */
+
+boolean
+_bfd_write_stab_strings (output_bfd, psinfo)
+ bfd *output_bfd;
+ PTR *psinfo;
+{
+ struct stab_info *sinfo;
+
+ sinfo = (struct stab_info *) *psinfo;
+
+ if (sinfo == NULL)
+ return true;
+
+ if (bfd_is_abs_section (sinfo->stabstr->output_section))
+ {
+ /* The section was discarded from the link. */
+ return true;
+ }
+
+ BFD_ASSERT ((sinfo->stabstr->output_offset
+ + _bfd_stringtab_size (sinfo->strings))
+ <= sinfo->stabstr->output_section->_raw_size);
+
+ if (bfd_seek (output_bfd,
+ (sinfo->stabstr->output_section->filepos
+ + sinfo->stabstr->output_offset),
+ SEEK_SET) != 0)
+ return false;
+
+ if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
+ return false;
+
+ /* We no longer need the stabs information. */
+ _bfd_stringtab_free (sinfo->strings);
+ bfd_hash_table_free (&sinfo->includes.root);
+
+ return true;
+}
+
+/* Adjust an address in the .stab section. Given OFFSET within
+ STABSEC, this returns the new offset in the adjusted stab section,
+ or -1 if the address refers to a stab which has been removed. */
+
+bfd_vma
+_bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)
+ bfd *output_bfd;
+ PTR *psinfo;
+ asection *stabsec;
+ PTR *psecinfo;
+ bfd_vma offset;
+{
+ struct stab_section_info *secinfo;
+
+ secinfo = (struct stab_section_info *) *psecinfo;
+
+ if (secinfo == NULL)
+ return offset;
+
+ if (offset >= stabsec->_raw_size)
+ return offset - (stabsec->_cooked_size - stabsec->_raw_size);
+
+ if (secinfo->cumulative_skips)
+ {
+ bfd_vma i;
+
+ i = offset / STABSIZE;
+
+ if (secinfo->stridxs [i] == (bfd_size_type) -1)
+ return (bfd_vma) -1;
+
+ return offset - secinfo->cumulative_skips [i];
+ }
+
+ return offset;
+}
diff --git a/bfd/stamp-h.in b/bfd/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/bfd/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/bfd/sunos.c b/bfd/sunos.c
new file mode 100644
index 00000000000..e34f87803cf
--- /dev/null
+++ b/bfd/sunos.c
@@ -0,0 +1,2948 @@
+/* BFD backend for SunOS binaries.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGETNAME "a.out-sunos-big"
+#define MY(OP) CAT(sunos_big_,OP)
+
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libaout.h"
+
+/* Static routines defined in this file. */
+
+static boolean sunos_read_dynamic_info PARAMS ((bfd *));
+static long sunos_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
+static boolean sunos_slurp_dynamic_symtab PARAMS ((bfd *));
+static long sunos_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **));
+static long sunos_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
+static long sunos_canonicalize_dynamic_reloc
+ PARAMS ((bfd *, arelent **, asymbol **));
+static struct bfd_hash_entry *sunos_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *sunos_link_hash_table_create
+ PARAMS ((bfd *));
+static boolean sunos_create_dynamic_sections
+ PARAMS ((bfd *, struct bfd_link_info *, boolean));
+static boolean sunos_add_dynamic_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, struct external_nlist **,
+ bfd_size_type *, char **));
+static boolean sunos_add_one_symbol
+ PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, boolean, boolean,
+ struct bfd_link_hash_entry **));
+static boolean sunos_scan_relocs
+ PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_size_type));
+static boolean sunos_scan_std_relocs
+ PARAMS ((struct bfd_link_info *, bfd *, asection *,
+ const struct reloc_std_external *, bfd_size_type));
+static boolean sunos_scan_ext_relocs
+ PARAMS ((struct bfd_link_info *, bfd *, asection *,
+ const struct reloc_ext_external *, bfd_size_type));
+static boolean sunos_link_dynamic_object
+ PARAMS ((struct bfd_link_info *, bfd *));
+static boolean sunos_write_dynamic_symbol
+ PARAMS ((bfd *, struct bfd_link_info *, struct aout_link_hash_entry *));
+static boolean sunos_check_dynamic_reloc
+ PARAMS ((struct bfd_link_info *, bfd *, asection *,
+ struct aout_link_hash_entry *, PTR, bfd_byte *, boolean *,
+ bfd_vma *));
+static boolean sunos_finish_dynamic_link
+ PARAMS ((bfd *, struct bfd_link_info *));
+
+#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound
+#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab
+#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound
+#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc
+#define MY_bfd_link_hash_table_create sunos_link_hash_table_create
+#define MY_add_dynamic_symbols sunos_add_dynamic_symbols
+#define MY_add_one_symbol sunos_add_one_symbol
+#define MY_link_dynamic_object sunos_link_dynamic_object
+#define MY_write_dynamic_symbol sunos_write_dynamic_symbol
+#define MY_check_dynamic_reloc sunos_check_dynamic_reloc
+#define MY_finish_dynamic_link sunos_finish_dynamic_link
+
+/* ??? Where should this go? */
+#define MACHTYPE_OK(mtype) \
+ (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
+ || ((mtype) == M_SPARCLET \
+ && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
+ || ((mtype) == M_SPARCLITE_LE \
+ && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
+ || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
+ && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
+
+/* Include the usual a.out support. */
+#include "aoutf1.h"
+
+/* The SunOS 4.1.4 /usr/include/locale.h defines valid as a macro. */
+#undef valid
+
+/* SunOS shared library support. We store a pointer to this structure
+ in obj_aout_dynamic_info (abfd). */
+
+struct sunos_dynamic_info
+{
+ /* Whether we found any dynamic information. */
+ boolean valid;
+ /* Dynamic information. */
+ struct internal_sun4_dynamic_link dyninfo;
+ /* Number of dynamic symbols. */
+ unsigned long dynsym_count;
+ /* Read in nlists for dynamic symbols. */
+ struct external_nlist *dynsym;
+ /* asymbol structures for dynamic symbols. */
+ aout_symbol_type *canonical_dynsym;
+ /* Read in dynamic string table. */
+ char *dynstr;
+ /* Number of dynamic relocs. */
+ unsigned long dynrel_count;
+ /* Read in dynamic relocs. This may be reloc_std_external or
+ reloc_ext_external. */
+ PTR dynrel;
+ /* arelent structures for dynamic relocs. */
+ arelent *canonical_dynrel;
+};
+
+/* The hash table of dynamic symbols is composed of two word entries.
+ See include/aout/sun4.h for details. */
+
+#define HASH_ENTRY_SIZE (2 * BYTES_IN_WORD)
+
+/* Read in the basic dynamic information. This locates the __DYNAMIC
+ structure and uses it to find the dynamic_link structure. It
+ creates and saves a sunos_dynamic_info structure. If it can't find
+ __DYNAMIC, it sets the valid field of the sunos_dynamic_info
+ structure to false to avoid doing this work again. */
+
+static boolean
+sunos_read_dynamic_info (abfd)
+ bfd *abfd;
+{
+ struct sunos_dynamic_info *info;
+ asection *dynsec;
+ bfd_vma dynoff;
+ struct external_sun4_dynamic dyninfo;
+ unsigned long dynver;
+ struct external_sun4_dynamic_link linkinfo;
+
+ if (obj_aout_dynamic_info (abfd) != (PTR) NULL)
+ return true;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ info = ((struct sunos_dynamic_info *)
+ bfd_zalloc (abfd, sizeof (struct sunos_dynamic_info)));
+ if (!info)
+ return false;
+ info->valid = false;
+ info->dynsym = NULL;
+ info->dynstr = NULL;
+ info->canonical_dynsym = NULL;
+ info->dynrel = NULL;
+ info->canonical_dynrel = NULL;
+ obj_aout_dynamic_info (abfd) = (PTR) info;
+
+ /* This code used to look for the __DYNAMIC symbol to locate the dynamic
+ linking information.
+ However this inhibits recovering the dynamic symbols from a
+ stripped object file, so blindly assume that the dynamic linking
+ information is located at the start of the data section.
+ We could verify this assumption later by looking through the dynamic
+ symbols for the __DYNAMIC symbol. */
+ if ((abfd->flags & DYNAMIC) == 0)
+ return true;
+ if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (PTR) &dyninfo,
+ (file_ptr) 0, sizeof dyninfo))
+ return true;
+
+ dynver = GET_WORD (abfd, dyninfo.ld_version);
+ if (dynver != 2 && dynver != 3)
+ return true;
+
+ dynoff = GET_WORD (abfd, dyninfo.ld);
+
+ /* dynoff is a virtual address. It is probably always in the .data
+ section, but this code should work even if it moves. */
+ if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd)))
+ dynsec = obj_textsec (abfd);
+ else
+ dynsec = obj_datasec (abfd);
+ dynoff -= bfd_get_section_vma (abfd, dynsec);
+ if (dynoff > bfd_section_size (abfd, dynsec))
+ return true;
+
+ /* This executable appears to be dynamically linked in a way that we
+ can understand. */
+ if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, dynoff,
+ (bfd_size_type) sizeof linkinfo))
+ return true;
+
+ /* Swap in the dynamic link information. */
+ info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded);
+ info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need);
+ info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules);
+ info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got);
+ info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt);
+ info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel);
+ info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash);
+ info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab);
+ info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash);
+ info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets);
+ info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols);
+ info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size);
+ info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text);
+ info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz);
+
+ /* Reportedly the addresses need to be offset by the size of the
+ exec header in an NMAGIC file. */
+ if (adata (abfd).magic == n_magic)
+ {
+ unsigned long exec_bytes_size = adata (abfd).exec_bytes_size;
+
+ info->dyninfo.ld_need += exec_bytes_size;
+ info->dyninfo.ld_rules += exec_bytes_size;
+ info->dyninfo.ld_rel += exec_bytes_size;
+ info->dyninfo.ld_hash += exec_bytes_size;
+ info->dyninfo.ld_stab += exec_bytes_size;
+ info->dyninfo.ld_symbols += exec_bytes_size;
+ }
+
+ /* The only way to get the size of the symbol information appears to
+ be to determine the distance between it and the string table. */
+ info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab)
+ / EXTERNAL_NLIST_SIZE);
+ BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE
+ == (unsigned long) (info->dyninfo.ld_symbols
+ - info->dyninfo.ld_stab));
+
+ /* Similarly, the relocs end at the hash table. */
+ info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel)
+ / obj_reloc_entry_size (abfd));
+ BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd)
+ == (unsigned long) (info->dyninfo.ld_hash
+ - info->dyninfo.ld_rel));
+
+ info->valid = true;
+
+ return true;
+}
+
+/* Return the amount of memory required for the dynamic symbols. */
+
+static long
+sunos_get_dynamic_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ struct sunos_dynamic_info *info;
+
+ if (! sunos_read_dynamic_info (abfd))
+ return -1;
+
+ info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+ if (! info->valid)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ return (info->dynsym_count + 1) * sizeof (asymbol *);
+}
+
+/* Read the external dynamic symbols. */
+
+static boolean
+sunos_slurp_dynamic_symtab (abfd)
+ bfd *abfd;
+{
+ struct sunos_dynamic_info *info;
+
+ /* Get the general dynamic information. */
+ if (obj_aout_dynamic_info (abfd) == NULL)
+ {
+ if (! sunos_read_dynamic_info (abfd))
+ return false;
+ }
+
+ info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+ if (! info->valid)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return false;
+ }
+
+ /* Get the dynamic nlist structures. */
+ if (info->dynsym == (struct external_nlist *) NULL)
+ {
+ info->dynsym = ((struct external_nlist *)
+ bfd_alloc (abfd,
+ (info->dynsym_count
+ * EXTERNAL_NLIST_SIZE)));
+ if (info->dynsym == NULL && info->dynsym_count != 0)
+ return false;
+ if (bfd_seek (abfd, info->dyninfo.ld_stab, SEEK_SET) != 0
+ || (bfd_read ((PTR) info->dynsym, info->dynsym_count,
+ EXTERNAL_NLIST_SIZE, abfd)
+ != info->dynsym_count * EXTERNAL_NLIST_SIZE))
+ {
+ if (info->dynsym != NULL)
+ {
+ bfd_release (abfd, info->dynsym);
+ info->dynsym = NULL;
+ }
+ return false;
+ }
+ }
+
+ /* Get the dynamic strings. */
+ if (info->dynstr == (char *) NULL)
+ {
+ info->dynstr = (char *) bfd_alloc (abfd, info->dyninfo.ld_symb_size);
+ if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0)
+ return false;
+ if (bfd_seek (abfd, info->dyninfo.ld_symbols, SEEK_SET) != 0
+ || (bfd_read ((PTR) info->dynstr, 1, info->dyninfo.ld_symb_size,
+ abfd)
+ != info->dyninfo.ld_symb_size))
+ {
+ if (info->dynstr != NULL)
+ {
+ bfd_release (abfd, info->dynstr);
+ info->dynstr = NULL;
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read in the dynamic symbols. */
+
+static long
+sunos_canonicalize_dynamic_symtab (abfd, storage)
+ bfd *abfd;
+ asymbol **storage;
+{
+ struct sunos_dynamic_info *info;
+ unsigned long i;
+
+ if (! sunos_slurp_dynamic_symtab (abfd))
+ return -1;
+
+ info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+
+#ifdef CHECK_DYNAMIC_HASH
+ /* Check my understanding of the dynamic hash table by making sure
+ that each symbol can be located in the hash table. */
+ {
+ bfd_size_type table_size;
+ bfd_byte *table;
+ bfd_size_type i;
+
+ if (info->dyninfo.ld_buckets > info->dynsym_count)
+ abort ();
+ table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash;
+ table = (bfd_byte *) bfd_malloc (table_size);
+ if (table == NULL && table_size != 0)
+ abort ();
+ if (bfd_seek (abfd, info->dyninfo.ld_hash, SEEK_SET) != 0
+ || bfd_read ((PTR) table, 1, table_size, abfd) != table_size)
+ abort ();
+ for (i = 0; i < info->dynsym_count; i++)
+ {
+ unsigned char *name;
+ unsigned long hash;
+
+ name = ((unsigned char *) info->dynstr
+ + GET_WORD (abfd, info->dynsym[i].e_strx));
+ hash = 0;
+ while (*name != '\0')
+ hash = (hash << 1) + *name++;
+ hash &= 0x7fffffff;
+ hash %= info->dyninfo.ld_buckets;
+ while (GET_WORD (abfd, table + hash * HASH_ENTRY_SIZE) != i)
+ {
+ hash = GET_WORD (abfd,
+ table + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
+ if (hash == 0 || hash >= table_size / HASH_ENTRY_SIZE)
+ abort ();
+ }
+ }
+ free (table);
+ }
+#endif /* CHECK_DYNAMIC_HASH */
+
+ /* Get the asymbol structures corresponding to the dynamic nlist
+ structures. */
+ if (info->canonical_dynsym == (aout_symbol_type *) NULL)
+ {
+ info->canonical_dynsym = ((aout_symbol_type *)
+ bfd_alloc (abfd,
+ (info->dynsym_count
+ * sizeof (aout_symbol_type))));
+ if (info->canonical_dynsym == NULL && info->dynsym_count != 0)
+ return -1;
+
+ if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym,
+ info->dynsym, info->dynsym_count,
+ info->dynstr,
+ info->dyninfo.ld_symb_size,
+ true))
+ {
+ if (info->canonical_dynsym != NULL)
+ {
+ bfd_release (abfd, info->canonical_dynsym);
+ info->canonical_dynsym = NULL;
+ }
+ return -1;
+ }
+ }
+
+ /* Return pointers to the dynamic asymbol structures. */
+ for (i = 0; i < info->dynsym_count; i++)
+ *storage++ = (asymbol *) (info->canonical_dynsym + i);
+ *storage = NULL;
+
+ return info->dynsym_count;
+}
+
+/* Return the amount of memory required for the dynamic relocs. */
+
+static long
+sunos_get_dynamic_reloc_upper_bound (abfd)
+ bfd *abfd;
+{
+ struct sunos_dynamic_info *info;
+
+ if (! sunos_read_dynamic_info (abfd))
+ return -1;
+
+ info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+ if (! info->valid)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ return (info->dynrel_count + 1) * sizeof (arelent *);
+}
+
+/* Read in the dynamic relocs. */
+
+static long
+sunos_canonicalize_dynamic_reloc (abfd, storage, syms)
+ bfd *abfd;
+ arelent **storage;
+ asymbol **syms;
+{
+ struct sunos_dynamic_info *info;
+ unsigned long i;
+
+ /* Get the general dynamic information. */
+ if (obj_aout_dynamic_info (abfd) == (PTR) NULL)
+ {
+ if (! sunos_read_dynamic_info (abfd))
+ return -1;
+ }
+
+ info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+ if (! info->valid)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ /* Get the dynamic reloc information. */
+ if (info->dynrel == NULL)
+ {
+ info->dynrel = (PTR) bfd_alloc (abfd,
+ (info->dynrel_count
+ * obj_reloc_entry_size (abfd)));
+ if (info->dynrel == NULL && info->dynrel_count != 0)
+ return -1;
+ if (bfd_seek (abfd, info->dyninfo.ld_rel, SEEK_SET) != 0
+ || (bfd_read ((PTR) info->dynrel, info->dynrel_count,
+ obj_reloc_entry_size (abfd), abfd)
+ != info->dynrel_count * obj_reloc_entry_size (abfd)))
+ {
+ if (info->dynrel != NULL)
+ {
+ bfd_release (abfd, info->dynrel);
+ info->dynrel = NULL;
+ }
+ return -1;
+ }
+ }
+
+ /* Get the arelent structures corresponding to the dynamic reloc
+ information. */
+ if (info->canonical_dynrel == (arelent *) NULL)
+ {
+ arelent *to;
+
+ info->canonical_dynrel = ((arelent *)
+ bfd_alloc (abfd,
+ (info->dynrel_count
+ * sizeof (arelent))));
+ if (info->canonical_dynrel == NULL && info->dynrel_count != 0)
+ return -1;
+
+ to = info->canonical_dynrel;
+
+ if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
+ {
+ register struct reloc_ext_external *p;
+ struct reloc_ext_external *pend;
+
+ p = (struct reloc_ext_external *) info->dynrel;
+ pend = p + info->dynrel_count;
+ for (; p < pend; p++, to++)
+ NAME(aout,swap_ext_reloc_in) (abfd, p, to, syms,
+ info->dynsym_count);
+ }
+ else
+ {
+ register struct reloc_std_external *p;
+ struct reloc_std_external *pend;
+
+ p = (struct reloc_std_external *) info->dynrel;
+ pend = p + info->dynrel_count;
+ for (; p < pend; p++, to++)
+ NAME(aout,swap_std_reloc_in) (abfd, p, to, syms,
+ info->dynsym_count);
+ }
+ }
+
+ /* Return pointers to the dynamic arelent structures. */
+ for (i = 0; i < info->dynrel_count; i++)
+ *storage++ = info->canonical_dynrel + i;
+ *storage = NULL;
+
+ return info->dynrel_count;
+}
+
+/* Code to handle linking of SunOS shared libraries. */
+
+/* A SPARC procedure linkage table entry is 12 bytes. The first entry
+ in the table is a jump which is filled in by the runtime linker.
+ The remaining entries are branches back to the first entry,
+ followed by an index into the relocation table encoded to look like
+ a sethi of %g0. */
+
+#define SPARC_PLT_ENTRY_SIZE (12)
+
+static const bfd_byte sparc_plt_first_entry[SPARC_PLT_ENTRY_SIZE] =
+{
+ /* sethi %hi(0),%g1; address filled in by runtime linker. */
+ 0x3, 0, 0, 0,
+ /* jmp %g1; offset filled in by runtime linker. */
+ 0x81, 0xc0, 0x60, 0,
+ /* nop */
+ 0x1, 0, 0, 0
+};
+
+/* save %sp, -96, %sp */
+#define SPARC_PLT_ENTRY_WORD0 0x9de3bfa0
+/* call; address filled in later. */
+#define SPARC_PLT_ENTRY_WORD1 0x40000000
+/* sethi; reloc index filled in later. */
+#define SPARC_PLT_ENTRY_WORD2 0x01000000
+
+/* This sequence is used when for the jump table entry to a defined
+ symbol in a complete executable. It is used when linking PIC
+ compiled code which is not being put into a shared library. */
+/* sethi <address to be filled in later>, %g1 */
+#define SPARC_PLT_PIC_WORD0 0x03000000
+/* jmp %g1 + <address to be filled in later> */
+#define SPARC_PLT_PIC_WORD1 0x81c06000
+/* nop */
+#define SPARC_PLT_PIC_WORD2 0x01000000
+
+/* An m68k procedure linkage table entry is 8 bytes. The first entry
+ in the table is a jump which is filled in the by the runtime
+ linker. The remaining entries are branches back to the first
+ entry, followed by a two byte index into the relocation table. */
+
+#define M68K_PLT_ENTRY_SIZE (8)
+
+static const bfd_byte m68k_plt_first_entry[M68K_PLT_ENTRY_SIZE] =
+{
+ /* jmps @# */
+ 0x4e, 0xf9,
+ /* Filled in by runtime linker with a magic address. */
+ 0, 0, 0, 0,
+ /* Not used? */
+ 0, 0
+};
+
+/* bsrl */
+#define M68K_PLT_ENTRY_WORD0 (0x61ff)
+/* Remaining words filled in later. */
+
+/* An entry in the SunOS linker hash table. */
+
+struct sunos_link_hash_entry
+{
+ struct aout_link_hash_entry root;
+
+ /* If this is a dynamic symbol, this is its index into the dynamic
+ symbol table. This is initialized to -1. As the linker looks at
+ the input files, it changes this to -2 if it will be added to the
+ dynamic symbol table. After all the input files have been seen,
+ the linker will know whether to build a dynamic symbol table; if
+ it does build one, this becomes the index into the table. */
+ long dynindx;
+
+ /* If this is a dynamic symbol, this is the index of the name in the
+ dynamic symbol string table. */
+ long dynstr_index;
+
+ /* The offset into the global offset table used for this symbol. If
+ the symbol does not require a GOT entry, this is 0. */
+ bfd_vma got_offset;
+
+ /* The offset into the procedure linkage table used for this symbol.
+ If the symbol does not require a PLT entry, this is 0. */
+ bfd_vma plt_offset;
+
+ /* Some linker flags. */
+ unsigned char flags;
+ /* Symbol is referenced by a regular object. */
+#define SUNOS_REF_REGULAR 01
+ /* Symbol is defined by a regular object. */
+#define SUNOS_DEF_REGULAR 02
+ /* Symbol is referenced by a dynamic object. */
+#define SUNOS_REF_DYNAMIC 04
+ /* Symbol is defined by a dynamic object. */
+#define SUNOS_DEF_DYNAMIC 010
+ /* Symbol is a constructor symbol in a regular object. */
+#define SUNOS_CONSTRUCTOR 020
+};
+
+/* The SunOS linker hash table. */
+
+struct sunos_link_hash_table
+{
+ struct aout_link_hash_table root;
+
+ /* The object which holds the dynamic sections. */
+ bfd *dynobj;
+
+ /* Whether we have created the dynamic sections. */
+ boolean dynamic_sections_created;
+
+ /* Whether we need the dynamic sections. */
+ boolean dynamic_sections_needed;
+
+ /* Whether we need the .got table. */
+ boolean got_needed;
+
+ /* The number of dynamic symbols. */
+ size_t dynsymcount;
+
+ /* The number of buckets in the hash table. */
+ size_t bucketcount;
+
+ /* The list of dynamic objects needed by dynamic objects included in
+ the link. */
+ struct bfd_link_needed_list *needed;
+
+ /* The offset of __GLOBAL_OFFSET_TABLE_ into the .got section. */
+ bfd_vma got_base;
+};
+
+/* Routine to create an entry in an SunOS link hash table. */
+
+static struct bfd_hash_entry *
+sunos_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct sunos_link_hash_entry *ret = (struct sunos_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct sunos_link_hash_entry *) NULL)
+ ret = ((struct sunos_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct sunos_link_hash_entry)));
+ if (ret == (struct sunos_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct sunos_link_hash_entry *)
+ NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ /* Set local fields. */
+ ret->dynindx = -1;
+ ret->dynstr_index = -1;
+ ret->got_offset = 0;
+ ret->plt_offset = 0;
+ ret->flags = 0;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a SunOS link hash table. */
+
+static struct bfd_link_hash_table *
+sunos_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct sunos_link_hash_table *ret;
+
+ ret = ((struct sunos_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct sunos_link_hash_table)));
+ if (ret == (struct sunos_link_hash_table *) NULL)
+ return (struct bfd_link_hash_table *) NULL;
+ if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
+ sunos_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->dynobj = NULL;
+ ret->dynamic_sections_created = false;
+ ret->dynamic_sections_needed = false;
+ ret->got_needed = false;
+ ret->dynsymcount = 0;
+ ret->bucketcount = 0;
+ ret->needed = NULL;
+ ret->got_base = 0;
+
+ return &ret->root.root;
+}
+
+/* Look up an entry in an SunOS link hash table. */
+
+#define sunos_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct sunos_link_hash_entry *) \
+ aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
+ (follow)))
+
+/* Traverse a SunOS link hash table. */
+
+#define sunos_link_hash_traverse(table, func, info) \
+ (aout_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the SunOS link hash table from the info structure. This is
+ just a cast. */
+
+#define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash))
+
+static boolean sunos_scan_dynamic_symbol
+ PARAMS ((struct sunos_link_hash_entry *, PTR));
+
+/* Create the dynamic sections needed if we are linking against a
+ dynamic object, or if we are linking PIC compiled code. ABFD is a
+ bfd we can attach the dynamic sections to. The linker script will
+ look for these special sections names and put them in the right
+ place in the output file. See include/aout/sun4.h for more details
+ of the dynamic linking information. */
+
+static boolean
+sunos_create_dynamic_sections (abfd, info, needed)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean needed;
+{
+ asection *s;
+
+ if (! sunos_hash_table (info)->dynamic_sections_created)
+ {
+ flagword flags;
+
+ sunos_hash_table (info)->dynobj = abfd;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ /* The .dynamic section holds the basic dynamic information: the
+ sun4_dynamic structure, the dynamic debugger information, and
+ the sun4_dynamic_link structure. */
+ s = bfd_make_section (abfd, ".dynamic");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ /* The .got section holds the global offset table. The address
+ is put in the ld_got field. */
+ s = bfd_make_section (abfd, ".got");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ /* The .plt section holds the procedure linkage table. The
+ address is put in the ld_plt field. */
+ s = bfd_make_section (abfd, ".plt");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_CODE)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ /* The .dynrel section holds the dynamic relocs. The address is
+ put in the ld_rel field. */
+ s = bfd_make_section (abfd, ".dynrel");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ /* The .hash section holds the dynamic hash table. The address
+ is put in the ld_hash field. */
+ s = bfd_make_section (abfd, ".hash");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ /* The .dynsym section holds the dynamic symbols. The address
+ is put in the ld_stab field. */
+ s = bfd_make_section (abfd, ".dynsym");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ /* The .dynstr section holds the dynamic symbol string table.
+ The address is put in the ld_symbols field. */
+ s = bfd_make_section (abfd, ".dynstr");
+ if (s == NULL
+ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return false;
+
+ sunos_hash_table (info)->dynamic_sections_created = true;
+ }
+
+ if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed)
+ || info->shared)
+ {
+ bfd *dynobj;
+
+ dynobj = sunos_hash_table (info)->dynobj;
+
+ s = bfd_get_section_by_name (dynobj, ".got");
+ if (s->_raw_size == 0)
+ s->_raw_size = BYTES_IN_WORD;
+
+ sunos_hash_table (info)->dynamic_sections_needed = true;
+ sunos_hash_table (info)->got_needed = true;
+ }
+
+ return true;
+}
+
+/* Add dynamic symbols during a link. This is called by the a.out
+ backend linker for each object it encounters. */
+
+static boolean
+sunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ struct external_nlist **symsp;
+ bfd_size_type *sym_countp;
+ char **stringsp;
+{
+ asection *s;
+ bfd *dynobj;
+ struct sunos_dynamic_info *dinfo;
+ unsigned long need;
+
+ /* Make sure we have all the required sections. */
+ if (info->hash->creator == abfd->xvec)
+ {
+ if (! sunos_create_dynamic_sections (abfd, info,
+ (((abfd->flags & DYNAMIC) != 0
+ && ! info->relocateable)
+ ? true
+ : false)))
+ return false;
+ }
+
+ /* There is nothing else to do for a normal object. */
+ if ((abfd->flags & DYNAMIC) == 0)
+ return true;
+
+ dynobj = sunos_hash_table (info)->dynobj;
+
+ /* We do not want to include the sections in a dynamic object in the
+ output file. We hack by simply clobbering the list of sections
+ in the BFD. This could be handled more cleanly by, say, a new
+ section flag; the existing SEC_NEVER_LOAD flag is not the one we
+ want, because that one still implies that the section takes up
+ space in the output file. If this is the first object we have
+ seen, we must preserve the dynamic sections we just created. */
+ if (abfd != dynobj)
+ abfd->sections = NULL;
+ else
+ {
+ asection *s;
+
+ for (s = abfd->sections;
+ (s->flags & SEC_LINKER_CREATED) == 0;
+ s = s->next)
+ ;
+ abfd->sections = s;
+ }
+
+ /* The native linker seems to just ignore dynamic objects when -r is
+ used. */
+ if (info->relocateable)
+ return true;
+
+ /* There's no hope of using a dynamic object which does not exactly
+ match the format of the output file. */
+ if (info->hash->creator != abfd->xvec)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ /* Make sure we have a .need and a .rules sections. These are only
+ needed if there really is a dynamic object in the link, so they
+ are not added by sunos_create_dynamic_sections. */
+ if (bfd_get_section_by_name (dynobj, ".need") == NULL)
+ {
+ /* The .need section holds the list of names of shared objets
+ which must be included at runtime. The address of this
+ section is put in the ld_need field. */
+ s = bfd_make_section (dynobj, ".need");
+ if (s == NULL
+ || ! bfd_set_section_flags (dynobj, s,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, s, 2))
+ return false;
+ }
+
+ if (bfd_get_section_by_name (dynobj, ".rules") == NULL)
+ {
+ /* The .rules section holds the path to search for shared
+ objects. The address of this section is put in the ld_rules
+ field. */
+ s = bfd_make_section (dynobj, ".rules");
+ if (s == NULL
+ || ! bfd_set_section_flags (dynobj, s,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY))
+ || ! bfd_set_section_alignment (dynobj, s, 2))
+ return false;
+ }
+
+ /* Pick up the dynamic symbols and return them to the caller. */
+ if (! sunos_slurp_dynamic_symtab (abfd))
+ return false;
+
+ dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
+ *symsp = dinfo->dynsym;
+ *sym_countp = dinfo->dynsym_count;
+ *stringsp = dinfo->dynstr;
+
+ /* Record information about any other objects needed by this one. */
+ need = dinfo->dyninfo.ld_need;
+ while (need != 0)
+ {
+ bfd_byte buf[16];
+ unsigned long name, flags;
+ unsigned short major_vno, minor_vno;
+ struct bfd_link_needed_list *needed, **pp;
+ char *namebuf, *p;
+ size_t alc;
+ bfd_byte b;
+ char *namecopy;
+
+ if (bfd_seek (abfd, need, SEEK_SET) != 0
+ || bfd_read (buf, 1, 16, abfd) != 16)
+ return false;
+
+ /* For the format of an ld_need entry, see aout/sun4.h. We
+ should probably define structs for this manipulation. */
+
+ name = bfd_get_32 (abfd, buf);
+ flags = bfd_get_32 (abfd, buf + 4);
+ major_vno = (unsigned short)bfd_get_16 (abfd, buf + 8);
+ minor_vno = (unsigned short)bfd_get_16 (abfd, buf + 10);
+ need = bfd_get_32 (abfd, buf + 12);
+
+ needed = ((struct bfd_link_needed_list *)
+ bfd_alloc (abfd, sizeof (struct bfd_link_needed_list)));
+ if (needed == NULL)
+ return false;
+ needed->by = abfd;
+
+ /* We return the name as [-l]name[.maj][.min]. */
+ alc = 30;
+ namebuf = (char *) bfd_malloc (alc + 1);
+ if (namebuf == NULL)
+ return false;
+ p = namebuf;
+
+ if ((flags & 0x80000000) != 0)
+ {
+ *p++ = '-';
+ *p++ = 'l';
+ }
+ if (bfd_seek (abfd, name, SEEK_SET) != 0)
+ {
+ free (namebuf);
+ return false;
+ }
+
+ do
+ {
+ if (bfd_read (&b, 1, 1, abfd) != 1)
+ {
+ free (namebuf);
+ return false;
+ }
+
+ if ((size_t) (p - namebuf) >= alc)
+ {
+ char *n;
+
+ alc *= 2;
+ n = (char *) bfd_realloc (namebuf, alc + 1);
+ if (n == NULL)
+ {
+ free (namebuf);
+ return false;
+ }
+ p = n + (p - namebuf);
+ namebuf = n;
+ }
+
+ *p++ = b;
+ }
+ while (b != '\0');
+
+ if (major_vno == 0)
+ *p = '\0';
+ else
+ {
+ char majbuf[30];
+ char minbuf[30];
+
+ sprintf (majbuf, ".%d", major_vno);
+ if (minor_vno == 0)
+ minbuf[0] = '\0';
+ else
+ sprintf (minbuf, ".%d", minor_vno);
+
+ if ((p - namebuf) + strlen (majbuf) + strlen (minbuf) >= alc)
+ {
+ char *n;
+
+ alc = (p - namebuf) + strlen (majbuf) + strlen (minbuf);
+ n = (char *) bfd_realloc (namebuf, alc + 1);
+ if (n == NULL)
+ {
+ free (namebuf);
+ return false;
+ }
+ p = n + (p - namebuf);
+ namebuf = n;
+ }
+
+ strcpy (p, majbuf);
+ strcat (p, minbuf);
+ }
+
+ namecopy = bfd_alloc (abfd, strlen (namebuf) + 1);
+ if (namecopy == NULL)
+ {
+ free (namebuf);
+ return false;
+ }
+ strcpy (namecopy, namebuf);
+ free (namebuf);
+ needed->name = namecopy;
+
+ needed->next = NULL;
+
+ for (pp = &sunos_hash_table (info)->needed;
+ *pp != NULL;
+ pp = &(*pp)->next)
+ ;
+ *pp = needed;
+ }
+
+ return true;
+}
+
+/* Function to add a single symbol to the linker hash table. This is
+ a wrapper around _bfd_generic_link_add_one_symbol which handles the
+ tweaking needed for dynamic linking support. */
+
+static boolean
+sunos_add_one_symbol (info, abfd, name, flags, section, value, string,
+ copy, collect, hashp)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ const char *string;
+ boolean copy;
+ boolean collect;
+ struct bfd_link_hash_entry **hashp;
+{
+ struct sunos_link_hash_entry *h;
+ int new_flag;
+
+ if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0
+ || ! bfd_is_und_section (section))
+ h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy,
+ false);
+ else
+ h = ((struct sunos_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false));
+ if (h == NULL)
+ return false;
+
+ if (hashp != NULL)
+ *hashp = (struct bfd_link_hash_entry *) h;
+
+ /* Treat a common symbol in a dynamic object as defined in the .bss
+ section of the dynamic object. We don't want to allocate space
+ for it in our process image. */
+ if ((abfd->flags & DYNAMIC) != 0
+ && bfd_is_com_section (section))
+ section = obj_bsssec (abfd);
+
+ if (! bfd_is_und_section (section)
+ && h->root.root.type != bfd_link_hash_new
+ && h->root.root.type != bfd_link_hash_undefined
+ && h->root.root.type != bfd_link_hash_defweak)
+ {
+ /* We are defining the symbol, and it is already defined. This
+ is a potential multiple definition error. */
+ if ((abfd->flags & DYNAMIC) != 0)
+ {
+ /* The definition we are adding is from a dynamic object.
+ We do not want this new definition to override the
+ existing definition, so we pretend it is just a
+ reference. */
+ section = bfd_und_section_ptr;
+ }
+ else if (h->root.root.type == bfd_link_hash_defined
+ && h->root.root.u.def.section->owner != NULL
+ && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
+ {
+ /* The existing definition is from a dynamic object. We
+ want to override it with the definition we just found.
+ Clobber the existing definition. */
+ h->root.root.type = bfd_link_hash_undefined;
+ h->root.root.u.undef.abfd = h->root.root.u.def.section->owner;
+ }
+ else if (h->root.root.type == bfd_link_hash_common
+ && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0)
+ {
+ /* The existing definition is from a dynamic object. We
+ want to override it with the definition we just found.
+ Clobber the existing definition. We can't set it to new,
+ because it is on the undefined list. */
+ h->root.root.type = bfd_link_hash_undefined;
+ h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner;
+ }
+ }
+
+ if ((abfd->flags & DYNAMIC) != 0
+ && abfd->xvec == info->hash->creator
+ && (h->flags & SUNOS_CONSTRUCTOR) != 0)
+ {
+ /* The existing symbol is a constructor symbol, and this symbol
+ is from a dynamic object. A constructor symbol is actually a
+ definition, although the type will be bfd_link_hash_undefined
+ at this point. We want to ignore the definition from the
+ dynamic object. */
+ section = bfd_und_section_ptr;
+ }
+ else if ((flags & BSF_CONSTRUCTOR) != 0
+ && (abfd->flags & DYNAMIC) == 0
+ && h->root.root.type == bfd_link_hash_defined
+ && h->root.root.u.def.section->owner != NULL
+ && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
+ {
+ /* The existing symbol is defined by a dynamic object, and this
+ is a constructor symbol. As above, we want to force the use
+ of the constructor symbol from the regular object. */
+ h->root.root.type = bfd_link_hash_new;
+ }
+
+ /* Do the usual procedure for adding a symbol. */
+ if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
+ value, string, copy, collect,
+ hashp))
+ return false;
+
+ if (abfd->xvec == info->hash->creator)
+ {
+ /* Set a flag in the hash table entry indicating the type of
+ reference or definition we just found. Keep a count of the
+ number of dynamic symbols we find. A dynamic symbol is one
+ which is referenced or defined by both a regular object and a
+ shared object. */
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ if (bfd_is_und_section (section))
+ new_flag = SUNOS_REF_REGULAR;
+ else
+ new_flag = SUNOS_DEF_REGULAR;
+ }
+ else
+ {
+ if (bfd_is_und_section (section))
+ new_flag = SUNOS_REF_DYNAMIC;
+ else
+ new_flag = SUNOS_DEF_DYNAMIC;
+ }
+ h->flags |= new_flag;
+
+ if (h->dynindx == -1
+ && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
+ {
+ ++sunos_hash_table (info)->dynsymcount;
+ h->dynindx = -2;
+ }
+
+ if ((flags & BSF_CONSTRUCTOR) != 0
+ && (abfd->flags & DYNAMIC) == 0)
+ h->flags |= SUNOS_CONSTRUCTOR;
+ }
+
+ return true;
+}
+
+/* Return the list of objects needed by BFD. */
+
+/*ARGSUSED*/
+struct bfd_link_needed_list *
+bfd_sunos_get_needed_list (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ if (info->hash->creator != &MY(vec))
+ return NULL;
+ return sunos_hash_table (info)->needed;
+}
+
+/* Record an assignment made to a symbol by a linker script. We need
+ this in case some dynamic object refers to this symbol. */
+
+boolean
+bfd_sunos_record_link_assignment (output_bfd, info, name)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ const char *name;
+{
+ struct sunos_link_hash_entry *h;
+
+ if (output_bfd->xvec != &MY(vec))
+ return true;
+
+ /* This is called after we have examined all the input objects. If
+ the symbol does not exist, it merely means that no object refers
+ to it, and we can just ignore it at this point. */
+ h = sunos_link_hash_lookup (sunos_hash_table (info), name,
+ false, false, false);
+ if (h == NULL)
+ return true;
+
+ /* In a shared library, the __DYNAMIC symbol does not appear in the
+ dynamic symbol table. */
+ if (! info->shared || strcmp (name, "__DYNAMIC") != 0)
+ {
+ h->flags |= SUNOS_DEF_REGULAR;
+
+ if (h->dynindx == -1)
+ {
+ ++sunos_hash_table (info)->dynsymcount;
+ h->dynindx = -2;
+ }
+ }
+
+ return true;
+}
+
+/* Set up the sizes and contents of the dynamic sections created in
+ sunos_add_dynamic_symbols. This is called by the SunOS linker
+ emulation before_allocation routine. We must set the sizes of the
+ sections before the linker sets the addresses of the various
+ sections. This unfortunately requires reading all the relocs so
+ that we can work out which ones need to become dynamic relocs. If
+ info->keep_memory is true, we keep the relocs in memory; otherwise,
+ we discard them, and will read them again later. */
+
+boolean
+bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr,
+ srulesptr)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ asection **sdynptr;
+ asection **sneedptr;
+ asection **srulesptr;
+{
+ bfd *dynobj;
+ size_t dynsymcount;
+ struct sunos_link_hash_entry *h;
+ asection *s;
+ size_t bucketcount;
+ size_t hashalloc;
+ size_t i;
+ bfd *sub;
+
+ *sdynptr = NULL;
+ *sneedptr = NULL;
+ *srulesptr = NULL;
+
+ if (info->relocateable)
+ return true;
+
+ if (output_bfd->xvec != &MY(vec))
+ return true;
+
+ /* Look through all the input BFD's and read their relocs. It would
+ be better if we didn't have to do this, but there is no other way
+ to determine the number of dynamic relocs we need, and, more
+ importantly, there is no other way to know which symbols should
+ get an entry in the procedure linkage table. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ if ((sub->flags & DYNAMIC) == 0
+ && sub->xvec == output_bfd->xvec)
+ {
+ if (! sunos_scan_relocs (info, sub, obj_textsec (sub),
+ exec_hdr (sub)->a_trsize)
+ || ! sunos_scan_relocs (info, sub, obj_datasec (sub),
+ exec_hdr (sub)->a_drsize))
+ return false;
+ }
+ }
+
+ dynobj = sunos_hash_table (info)->dynobj;
+ dynsymcount = sunos_hash_table (info)->dynsymcount;
+
+ /* If there were no dynamic objects in the link, and we don't need
+ to build a global offset table, there is nothing to do here. */
+ if (! sunos_hash_table (info)->dynamic_sections_needed
+ && ! sunos_hash_table (info)->got_needed)
+ return true;
+
+ /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it. */
+ h = sunos_link_hash_lookup (sunos_hash_table (info),
+ "__GLOBAL_OFFSET_TABLE_", false, false, false);
+ if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0)
+ {
+ h->flags |= SUNOS_DEF_REGULAR;
+ if (h->dynindx == -1)
+ {
+ ++sunos_hash_table (info)->dynsymcount;
+ h->dynindx = -2;
+ }
+ h->root.root.type = bfd_link_hash_defined;
+ h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got");
+
+ /* If the .got section is more than 0x1000 bytes, we set
+ __GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section,
+ so that 13 bit relocations have a greater chance of working. */
+ s = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (s != NULL);
+ if (s->_raw_size >= 0x1000)
+ h->root.root.u.def.value = 0x1000;
+ else
+ h->root.root.u.def.value = 0;
+
+ sunos_hash_table (info)->got_base = h->root.root.u.def.value;
+ }
+
+ /* If there are any shared objects in the link, then we need to set
+ up the dynamic linking information. */
+ if (sunos_hash_table (info)->dynamic_sections_needed)
+ {
+ *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ /* The .dynamic section is always the same size. */
+ s = *sdynptr;
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = (sizeof (struct external_sun4_dynamic)
+ + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE
+ + sizeof (struct external_sun4_dynamic_link));
+
+ /* Set the size of the .dynsym and .hash sections. We counted
+ the number of dynamic symbols as we read the input files. We
+ will build the dynamic symbol table (.dynsym) and the hash
+ table (.hash) when we build the final symbol table, because
+ until then we do not know the correct value to give the
+ symbols. We build the dynamic symbol string table (.dynstr)
+ in a traversal of the symbol table using
+ sunos_scan_dynamic_symbol. */
+ s = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = dynsymcount * sizeof (struct external_nlist);
+ s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return false;
+
+ /* The number of buckets is just the number of symbols divided
+ by four. To compute the final size of the hash table, we
+ must actually compute the hash table. Normally we need
+ exactly as many entries in the hash table as there are
+ dynamic symbols, but if some of the buckets are not used we
+ will need additional entries. In the worst case, every
+ symbol will hash to the same bucket, and we will need
+ BUCKETCOUNT - 1 extra entries. */
+ if (dynsymcount >= 4)
+ bucketcount = dynsymcount / 4;
+ else if (dynsymcount > 0)
+ bucketcount = dynsymcount;
+ else
+ bucketcount = 1;
+ s = bfd_get_section_by_name (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, hashalloc);
+ if (s->contents == NULL && dynsymcount > 0)
+ return false;
+ memset (s->contents, 0, hashalloc);
+ for (i = 0; i < bucketcount; i++)
+ PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);
+ s->_raw_size = bucketcount * HASH_ENTRY_SIZE;
+
+ sunos_hash_table (info)->bucketcount = bucketcount;
+
+ /* Scan all the symbols, place them in the dynamic symbol table,
+ and build the dynamic hash table. We reuse dynsymcount as a
+ counter for the number of symbols we have added so far. */
+ sunos_hash_table (info)->dynsymcount = 0;
+ sunos_link_hash_traverse (sunos_hash_table (info),
+ sunos_scan_dynamic_symbol,
+ (PTR) info);
+ BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount);
+
+ /* The SunOS native linker seems to align the total size of the
+ symbol strings to a multiple of 8. I don't know if this is
+ important, but it can't hurt much. */
+ s = bfd_get_section_by_name (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ if ((s->_raw_size & 7) != 0)
+ {
+ bfd_size_type add;
+ bfd_byte *contents;
+
+ add = 8 - (s->_raw_size & 7);
+ contents = (bfd_byte *) bfd_realloc (s->contents,
+ (size_t) (s->_raw_size + add));
+ if (contents == NULL)
+ return false;
+ memset (contents + s->_raw_size, 0, (size_t) add);
+ s->contents = contents;
+ s->_raw_size += add;
+ }
+ }
+
+ /* Now that we have worked out the sizes of the procedure linkage
+ table and the dynamic relocs, allocate storage for them. */
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+ if (s->_raw_size != 0)
+ {
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+
+ /* Fill in the first entry in the table. */
+ switch (bfd_get_arch (dynobj))
+ {
+ case bfd_arch_sparc:
+ memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE);
+ break;
+
+ case bfd_arch_m68k:
+ memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ s = bfd_get_section_by_name (dynobj, ".dynrel");
+ if (s->_raw_size != 0)
+ {
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+ }
+ /* We use the reloc_count field to keep track of how many of the
+ relocs we have output so far. */
+ s->reloc_count = 0;
+
+ /* Make space for the global offset table. */
+ s = bfd_get_section_by_name (dynobj, ".got");
+ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+ if (s->contents == NULL)
+ return false;
+
+ *sneedptr = bfd_get_section_by_name (dynobj, ".need");
+ *srulesptr = bfd_get_section_by_name (dynobj, ".rules");
+
+ return true;
+}
+
+/* Scan the relocs for an input section. */
+
+static boolean
+sunos_scan_relocs (info, abfd, sec, rel_size)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ asection *sec;
+ bfd_size_type rel_size;
+{
+ PTR relocs;
+ PTR free_relocs = NULL;
+
+ if (rel_size == 0)
+ return true;
+
+ if (! info->keep_memory)
+ relocs = free_relocs = bfd_malloc ((size_t) rel_size);
+ else
+ {
+ struct aout_section_data_struct *n;
+
+ n = ((struct aout_section_data_struct *)
+ bfd_alloc (abfd, sizeof (struct aout_section_data_struct)));
+ if (n == NULL)
+ relocs = NULL;
+ else
+ {
+ set_aout_section_data (sec, n);
+ relocs = bfd_malloc ((size_t) rel_size);
+ aout_section_data (sec)->relocs = relocs;
+ }
+ }
+ if (relocs == NULL)
+ return false;
+
+ if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
+ || bfd_read (relocs, 1, rel_size, abfd) != rel_size)
+ goto error_return;
+
+ if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE)
+ {
+ if (! sunos_scan_std_relocs (info, abfd, sec,
+ (struct reloc_std_external *) relocs,
+ rel_size))
+ goto error_return;
+ }
+ else
+ {
+ if (! sunos_scan_ext_relocs (info, abfd, sec,
+ (struct reloc_ext_external *) relocs,
+ rel_size))
+ goto error_return;
+ }
+
+ if (free_relocs != NULL)
+ free (free_relocs);
+
+ return true;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ return false;
+}
+
+/* Scan the relocs for an input section using standard relocs. We
+ need to figure out what to do for each reloc against a dynamic
+ symbol. If the symbol is in the .text section, an entry is made in
+ the procedure linkage table. Note that this will do the wrong
+ thing if the symbol is actually data; I don't think the Sun 3
+ native linker handles this case correctly either. If the symbol is
+ not in the .text section, we must preserve the reloc as a dynamic
+ reloc. FIXME: We should also handle the PIC relocs here by
+ building global offset table entries. */
+
+static boolean
+sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ asection *sec;
+ const struct reloc_std_external *relocs;
+ bfd_size_type rel_size;
+{
+ bfd *dynobj;
+ asection *splt = NULL;
+ asection *srel = NULL;
+ struct sunos_link_hash_entry **sym_hashes;
+ const struct reloc_std_external *rel, *relend;
+
+ /* We only know how to handle m68k plt entries. */
+ if (bfd_get_arch (abfd) != bfd_arch_m68k)
+ {
+ bfd_set_error (bfd_error_invalid_target);
+ return false;
+ }
+
+ dynobj = NULL;
+
+ sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);
+
+ relend = relocs + rel_size / RELOC_STD_SIZE;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ int r_index;
+ struct sunos_link_hash_entry *h;
+
+ /* We only want relocs against external symbols. */
+ if (bfd_header_big_endian (abfd))
+ {
+ if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0)
+ continue;
+ }
+ else
+ {
+ if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0)
+ continue;
+ }
+
+ /* Get the symbol index. */
+ if (bfd_header_big_endian (abfd))
+ r_index = ((rel->r_index[0] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[2]);
+ else
+ r_index = ((rel->r_index[2] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[0]);
+
+ /* Get the hash table entry. */
+ h = sym_hashes[r_index];
+ if (h == NULL)
+ {
+ /* This should not normally happen, but it will in any case
+ be caught in the relocation phase. */
+ continue;
+ }
+
+ /* At this point common symbols have already been allocated, so
+ we don't have to worry about them. We need to consider that
+ we may have already seen this symbol and marked it undefined;
+ if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
+ will be zero. */
+ if (h->root.root.type != bfd_link_hash_defined
+ && h->root.root.type != bfd_link_hash_defweak
+ && h->root.root.type != bfd_link_hash_undefined)
+ continue;
+
+ if ((h->flags & SUNOS_DEF_DYNAMIC) == 0
+ || (h->flags & SUNOS_DEF_REGULAR) != 0)
+ continue;
+
+ if (dynobj == NULL)
+ {
+ asection *sgot;
+
+ if (! sunos_create_dynamic_sections (abfd, info, false))
+ return false;
+ dynobj = sunos_hash_table (info)->dynobj;
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ srel = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && srel != NULL);
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ if (sgot->_raw_size == 0)
+ sgot->_raw_size = BYTES_IN_WORD;
+ sunos_hash_table (info)->got_needed = true;
+ }
+
+ BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
+ BFD_ASSERT (h->plt_offset != 0
+ || ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ ? (h->root.root.u.def.section->owner->flags
+ & DYNAMIC) != 0
+ : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));
+
+ /* This reloc is against a symbol defined only by a dynamic
+ object. */
+
+ if (h->root.root.type == bfd_link_hash_undefined)
+ {
+ /* Presumably this symbol was marked as being undefined by
+ an earlier reloc. */
+ srel->_raw_size += RELOC_STD_SIZE;
+ }
+ else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0)
+ {
+ bfd *sub;
+
+ /* This reloc is not in the .text section. It must be
+ copied into the dynamic relocs. We mark the symbol as
+ being undefined. */
+ srel->_raw_size += RELOC_STD_SIZE;
+ sub = h->root.root.u.def.section->owner;
+ h->root.root.type = bfd_link_hash_undefined;
+ h->root.root.u.undef.abfd = sub;
+ }
+ else
+ {
+ /* This symbol is in the .text section. We must give it an
+ entry in the procedure linkage table, if we have not
+ already done so. We change the definition of the symbol
+ to the .plt section; this will cause relocs against it to
+ be handled correctly. */
+ if (h->plt_offset == 0)
+ {
+ if (splt->_raw_size == 0)
+ splt->_raw_size = M68K_PLT_ENTRY_SIZE;
+ h->plt_offset = splt->_raw_size;
+
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ h->root.root.u.def.section = splt;
+ h->root.root.u.def.value = splt->_raw_size;
+ }
+
+ splt->_raw_size += M68K_PLT_ENTRY_SIZE;
+
+ /* We may also need a dynamic reloc entry. */
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0)
+ srel->_raw_size += RELOC_STD_SIZE;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* Scan the relocs for an input section using extended relocs. We
+ need to figure out what to do for each reloc against a dynamic
+ symbol. If the reloc is a WDISP30, and the symbol is in the .text
+ section, an entry is made in the procedure linkage table.
+ Otherwise, we must preserve the reloc as a dynamic reloc. */
+
+static boolean
+sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ asection *sec;
+ const struct reloc_ext_external *relocs;
+ bfd_size_type rel_size;
+{
+ bfd *dynobj;
+ struct sunos_link_hash_entry **sym_hashes;
+ const struct reloc_ext_external *rel, *relend;
+ asection *splt = NULL;
+ asection *sgot = NULL;
+ asection *srel = NULL;
+
+ /* We only know how to handle SPARC plt entries. */
+ if (bfd_get_arch (abfd) != bfd_arch_sparc)
+ {
+ bfd_set_error (bfd_error_invalid_target);
+ return false;
+ }
+
+ dynobj = NULL;
+
+ sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);
+
+ relend = relocs + rel_size / RELOC_EXT_SIZE;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned int r_index;
+ int r_extern;
+ int r_type;
+ struct sunos_link_hash_entry *h = NULL;
+
+ /* Swap in the reloc information. */
+ if (bfd_header_big_endian (abfd))
+ {
+ r_index = ((rel->r_index[0] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[2]);
+ r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
+ r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+ >> RELOC_EXT_BITS_TYPE_SH_BIG);
+ }
+ else
+ {
+ r_index = ((rel->r_index[2] << 16)
+ | (rel->r_index[1] << 8)
+ | rel->r_index[0]);
+ r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
+ r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+ >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
+ }
+
+ if (r_extern)
+ {
+ h = sym_hashes[r_index];
+ if (h == NULL)
+ {
+ /* This should not normally happen, but it will in any
+ case be caught in the relocation phase. */
+ continue;
+ }
+ }
+
+ /* If this is a base relative reloc, we need to make an entry in
+ the .got section. */
+ if (r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22)
+ {
+ if (dynobj == NULL)
+ {
+ if (! sunos_create_dynamic_sections (abfd, info, false))
+ return false;
+ dynobj = sunos_hash_table (info)->dynobj;
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srel = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+ /* Make sure we have an initial entry in the .got table. */
+ if (sgot->_raw_size == 0)
+ sgot->_raw_size = BYTES_IN_WORD;
+ sunos_hash_table (info)->got_needed = true;
+ }
+
+ if (r_extern)
+ {
+ if (h->got_offset != 0)
+ continue;
+
+ h->got_offset = sgot->_raw_size;
+ }
+ else
+ {
+ if (r_index >= bfd_get_symcount (abfd))
+ {
+ /* This is abnormal, but should be caught in the
+ relocation phase. */
+ continue;
+ }
+
+ if (adata (abfd).local_got_offsets == NULL)
+ {
+ adata (abfd).local_got_offsets =
+ (bfd_vma *) bfd_zalloc (abfd,
+ (bfd_get_symcount (abfd)
+ * sizeof (bfd_vma)));
+ if (adata (abfd).local_got_offsets == NULL)
+ return false;
+ }
+
+ if (adata (abfd).local_got_offsets[r_index] != 0)
+ continue;
+
+ adata (abfd).local_got_offsets[r_index] = sgot->_raw_size;
+ }
+
+ sgot->_raw_size += BYTES_IN_WORD;
+
+ /* If we are making a shared library, or if the symbol is
+ defined by a dynamic object, we will need a dynamic reloc
+ entry. */
+ if (info->shared
+ || (h != NULL
+ && (h->flags & SUNOS_DEF_DYNAMIC) != 0
+ && (h->flags & SUNOS_DEF_REGULAR) == 0))
+ srel->_raw_size += RELOC_EXT_SIZE;
+
+ continue;
+ }
+
+ /* Otherwise, we are only interested in relocs against symbols
+ defined in dynamic objects but not in regular objects. We
+ only need to consider relocs against external symbols. */
+ if (! r_extern)
+ {
+ /* But, if we are creating a shared library, we need to
+ generate an absolute reloc. */
+ if (info->shared)
+ {
+ if (dynobj == NULL)
+ {
+ if (! sunos_create_dynamic_sections (abfd, info, true))
+ return false;
+ dynobj = sunos_hash_table (info)->dynobj;
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srel = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+ }
+
+ srel->_raw_size += RELOC_EXT_SIZE;
+ }
+
+ continue;
+ }
+
+ /* At this point common symbols have already been allocated, so
+ we don't have to worry about them. We need to consider that
+ we may have already seen this symbol and marked it undefined;
+ if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
+ will be zero. */
+ if (h->root.root.type != bfd_link_hash_defined
+ && h->root.root.type != bfd_link_hash_defweak
+ && h->root.root.type != bfd_link_hash_undefined)
+ continue;
+
+ if (r_type != RELOC_JMP_TBL
+ && ! info->shared
+ && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
+ || (h->flags & SUNOS_DEF_REGULAR) != 0))
+ continue;
+
+ if (r_type == RELOC_JMP_TBL
+ && ! info->shared
+ && (h->flags & SUNOS_DEF_DYNAMIC) == 0
+ && (h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ /* This symbol is apparently undefined. Don't do anything
+ here; just let the relocation routine report an undefined
+ symbol. */
+ continue;
+ }
+
+ if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
+ continue;
+
+ if (dynobj == NULL)
+ {
+ if (! sunos_create_dynamic_sections (abfd, info, false))
+ return false;
+ dynobj = sunos_hash_table (info)->dynobj;
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+ srel = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+ /* Make sure we have an initial entry in the .got table. */
+ if (sgot->_raw_size == 0)
+ sgot->_raw_size = BYTES_IN_WORD;
+ sunos_hash_table (info)->got_needed = true;
+ }
+
+ BFD_ASSERT (r_type == RELOC_JMP_TBL
+ || info->shared
+ || (h->flags & SUNOS_REF_REGULAR) != 0);
+ BFD_ASSERT (r_type == RELOC_JMP_TBL
+ || info->shared
+ || h->plt_offset != 0
+ || ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ ? (h->root.root.u.def.section->owner->flags
+ & DYNAMIC) != 0
+ : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));
+
+ /* This reloc is against a symbol defined only by a dynamic
+ object, or it is a jump table reloc from PIC compiled code. */
+
+ if (r_type != RELOC_JMP_TBL
+ && h->root.root.type == bfd_link_hash_undefined)
+ {
+ /* Presumably this symbol was marked as being undefined by
+ an earlier reloc. */
+ srel->_raw_size += RELOC_EXT_SIZE;
+ }
+ else if (r_type != RELOC_JMP_TBL
+ && (h->root.root.u.def.section->flags & SEC_CODE) == 0)
+ {
+ bfd *sub;
+
+ /* This reloc is not in the .text section. It must be
+ copied into the dynamic relocs. We mark the symbol as
+ being undefined. */
+ srel->_raw_size += RELOC_EXT_SIZE;
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ sub = h->root.root.u.def.section->owner;
+ h->root.root.type = bfd_link_hash_undefined;
+ h->root.root.u.undef.abfd = sub;
+ }
+ }
+ else
+ {
+ /* This symbol is in the .text section. We must give it an
+ entry in the procedure linkage table, if we have not
+ already done so. We change the definition of the symbol
+ to the .plt section; this will cause relocs against it to
+ be handled correctly. */
+ if (h->plt_offset == 0)
+ {
+ if (splt->_raw_size == 0)
+ splt->_raw_size = SPARC_PLT_ENTRY_SIZE;
+ h->plt_offset = splt->_raw_size;
+
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ if (h->root.root.type == bfd_link_hash_undefined)
+ h->root.root.type = bfd_link_hash_defined;
+ h->root.root.u.def.section = splt;
+ h->root.root.u.def.value = splt->_raw_size;
+ }
+
+ splt->_raw_size += SPARC_PLT_ENTRY_SIZE;
+
+ /* We will also need a dynamic reloc entry, unless this
+ is a JMP_TBL reloc produced by linking PIC compiled
+ code, and we are not making a shared library. */
+ if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
+ srel->_raw_size += RELOC_EXT_SIZE;
+ }
+
+ /* If we are creating a shared library, we need to copy over
+ any reloc other than a jump table reloc. */
+ if (info->shared && r_type != RELOC_JMP_TBL)
+ srel->_raw_size += RELOC_EXT_SIZE;
+ }
+ }
+
+ return true;
+}
+
+/* Build the hash table of dynamic symbols, and to mark as written all
+ symbols from dynamic objects which we do not plan to write out. */
+
+static boolean
+sunos_scan_dynamic_symbol (h, data)
+ struct sunos_link_hash_entry *h;
+ PTR data;
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
+
+ /* Set the written flag for symbols we do not want to write out as
+ part of the regular symbol table. This is all symbols which are
+ not defined in a regular object file. For some reason symbols
+ which are referenced by a regular object and defined by a dynamic
+ object do not seem to show up in the regular symbol table. It is
+ possible for a symbol to have only SUNOS_REF_REGULAR set here, it
+ is an undefined symbol which was turned into a common symbol
+ because it was found in an archive object which was not included
+ in the link. */
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0
+ && (h->flags & SUNOS_DEF_DYNAMIC) != 0
+ && strcmp (h->root.root.root.string, "__DYNAMIC") != 0)
+ h->root.written = true;
+
+ /* If this symbol is defined by a dynamic object and referenced by a
+ regular object, see whether we gave it a reasonable value while
+ scanning the relocs. */
+
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0
+ && (h->flags & SUNOS_DEF_DYNAMIC) != 0
+ && (h->flags & SUNOS_REF_REGULAR) != 0)
+ {
+ if ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
+ && h->root.root.u.def.section->output_section == NULL)
+ {
+ bfd *sub;
+
+ /* This symbol is currently defined in a dynamic section
+ which is not being put into the output file. This
+ implies that there is no reloc against the symbol. I'm
+ not sure why this case would ever occur. In any case, we
+ change the symbol to be undefined. */
+ sub = h->root.root.u.def.section->owner;
+ h->root.root.type = bfd_link_hash_undefined;
+ h->root.root.u.undef.abfd = sub;
+ }
+ }
+
+ /* If this symbol is defined or referenced by a regular file, add it
+ to the dynamic symbols. */
+ if ((h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
+ {
+ asection *s;
+ size_t len;
+ bfd_byte *contents;
+ unsigned char *name;
+ unsigned long hash;
+ bfd *dynobj;
+
+ BFD_ASSERT (h->dynindx == -2);
+
+ dynobj = sunos_hash_table (info)->dynobj;
+
+ h->dynindx = sunos_hash_table (info)->dynsymcount;
+ ++sunos_hash_table (info)->dynsymcount;
+
+ len = strlen (h->root.root.root.string);
+
+ /* We don't bother to construct a BFD hash table for the strings
+ which are the names of the dynamic symbols. Using a hash
+ table for the regular symbols is beneficial, because the
+ regular symbols includes the debugging symbols, which have
+ long names and are often duplicated in several object files.
+ There are no debugging symbols in the dynamic symbols. */
+ s = bfd_get_section_by_name (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ contents = (bfd_byte *) bfd_realloc (s->contents,
+ s->_raw_size + len + 1);
+ if (contents == NULL)
+ return false;
+ s->contents = contents;
+
+ h->dynstr_index = s->_raw_size;
+ strcpy ((char *) contents + s->_raw_size, h->root.root.root.string);
+ s->_raw_size += len + 1;
+
+ /* Add it to the dynamic hash table. */
+ name = (unsigned char *) h->root.root.root.string;
+ hash = 0;
+ while (*name != '\0')
+ hash = (hash << 1) + *name++;
+ hash &= 0x7fffffff;
+ hash %= sunos_hash_table (info)->bucketcount;
+
+ s = bfd_get_section_by_name (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+
+ if (GET_SWORD (dynobj, s->contents + hash * HASH_ENTRY_SIZE) == -1)
+ PUT_WORD (dynobj, h->dynindx, s->contents + hash * HASH_ENTRY_SIZE);
+ else
+ {
+ bfd_vma next;
+
+ next = GET_WORD (dynobj,
+ (s->contents
+ + hash * HASH_ENTRY_SIZE
+ + BYTES_IN_WORD));
+ PUT_WORD (dynobj, s->_raw_size / HASH_ENTRY_SIZE,
+ s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
+ PUT_WORD (dynobj, h->dynindx, s->contents + s->_raw_size);
+ PUT_WORD (dynobj, next, s->contents + s->_raw_size + BYTES_IN_WORD);
+ s->_raw_size += HASH_ENTRY_SIZE;
+ }
+ }
+
+ return true;
+}
+
+/* Link a dynamic object. We actually don't have anything to do at
+ this point. This entry point exists to prevent the regular linker
+ code from doing anything with the object. */
+
+/*ARGSUSED*/
+static boolean
+sunos_link_dynamic_object (info, abfd)
+ struct bfd_link_info *info;
+ bfd *abfd;
+{
+ return true;
+}
+
+/* Write out a dynamic symbol. This is called by the final traversal
+ over the symbol table. */
+
+static boolean
+sunos_write_dynamic_symbol (output_bfd, info, harg)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct aout_link_hash_entry *harg;
+{
+ struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
+ int type;
+ bfd_vma val;
+ asection *s;
+ struct external_nlist *outsym;
+
+ /* If this symbol is in the procedure linkage table, fill in the
+ table entry. */
+ if (h->plt_offset != 0)
+ {
+ bfd *dynobj;
+ asection *splt;
+ bfd_byte *p;
+ asection *s;
+ bfd_vma r_address;
+
+ dynobj = sunos_hash_table (info)->dynobj;
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ p = splt->contents + h->plt_offset;
+
+ s = bfd_get_section_by_name (dynobj, ".dynrel");
+
+ r_address = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt_offset);
+
+ switch (bfd_get_arch (output_bfd))
+ {
+ case bfd_arch_sparc:
+ if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD0, p);
+ bfd_put_32 (output_bfd,
+ (SPARC_PLT_ENTRY_WORD1
+ + (((- (h->plt_offset + 4) >> 2)
+ & 0x3fffffff))),
+ p + 4);
+ bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD2 + s->reloc_count,
+ p + 8);
+ }
+ else
+ {
+ bfd_vma val;
+
+ val = (h->root.root.u.def.section->output_section->vma
+ + h->root.root.u.def.section->output_offset
+ + h->root.root.u.def.value);
+ bfd_put_32 (output_bfd,
+ SPARC_PLT_PIC_WORD0 + ((val >> 10) & 0x3fffff),
+ p);
+ bfd_put_32 (output_bfd,
+ SPARC_PLT_PIC_WORD1 + (val & 0x3ff),
+ p + 4);
+ bfd_put_32 (output_bfd, SPARC_PLT_PIC_WORD2, p + 8);
+ }
+ break;
+
+ case bfd_arch_m68k:
+ if (! info->shared && (h->flags & SUNOS_DEF_REGULAR) != 0)
+ abort ();
+ bfd_put_16 (output_bfd, M68K_PLT_ENTRY_WORD0, p);
+ bfd_put_32 (output_bfd, (- (h->plt_offset + 2)), p + 2);
+ bfd_put_16 (output_bfd, s->reloc_count, p + 6);
+ r_address += 2;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* We also need to add a jump table reloc, unless this is the
+ result of a JMP_TBL reloc from PIC compiled code. */
+ if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ BFD_ASSERT (h->dynindx >= 0);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
+ < s->_raw_size);
+ p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd);
+ if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE)
+ {
+ struct reloc_std_external *srel;
+
+ srel = (struct reloc_std_external *) p;
+ PUT_WORD (output_bfd, r_address, srel->r_address);
+ if (bfd_header_big_endian (output_bfd))
+ {
+ srel->r_index[0] = (bfd_byte)(h->dynindx >> 16);
+ srel->r_index[1] = (bfd_byte)(h->dynindx >> 8);
+ srel->r_index[2] = (bfd_byte)(h->dynindx);
+ srel->r_type[0] = (RELOC_STD_BITS_EXTERN_BIG
+ | RELOC_STD_BITS_JMPTABLE_BIG);
+ }
+ else
+ {
+ srel->r_index[2] = (bfd_byte)(h->dynindx >> 16);
+ srel->r_index[1] = (bfd_byte)(h->dynindx >> 8);
+ srel->r_index[0] = (bfd_byte)h->dynindx;
+ srel->r_type[0] = (RELOC_STD_BITS_EXTERN_LITTLE
+ | RELOC_STD_BITS_JMPTABLE_LITTLE);
+ }
+ }
+ else
+ {
+ struct reloc_ext_external *erel;
+
+ erel = (struct reloc_ext_external *) p;
+ PUT_WORD (output_bfd, r_address, erel->r_address);
+ if (bfd_header_big_endian (output_bfd))
+ {
+ erel->r_index[0] = (bfd_byte)(h->dynindx >> 16);
+ erel->r_index[1] = (bfd_byte)(h->dynindx >> 8);
+ erel->r_index[2] = (bfd_byte)h->dynindx;
+ erel->r_type[0] =
+ (RELOC_EXT_BITS_EXTERN_BIG
+ | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG));
+ }
+ else
+ {
+ erel->r_index[2] = (bfd_byte)(h->dynindx >> 16);
+ erel->r_index[1] = (bfd_byte)(h->dynindx >> 8);
+ erel->r_index[0] = (bfd_byte)h->dynindx;
+ erel->r_type[0] =
+ (RELOC_EXT_BITS_EXTERN_LITTLE
+ | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE));
+ }
+ PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend);
+ }
+
+ ++s->reloc_count;
+ }
+ }
+
+ /* If this is not a dynamic symbol, we don't have to do anything
+ else. We only check this after handling the PLT entry, because
+ we can have a PLT entry for a nondynamic symbol when linking PIC
+ compiled code from a regular object. */
+ if (h->dynindx < 0)
+ return true;
+
+ switch (h->root.root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ abort ();
+ /* Avoid variable not initialized warnings. */
+ return true;
+ case bfd_link_hash_undefined:
+ type = N_UNDF | N_EXT;
+ val = 0;
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ {
+ asection *sec;
+ asection *output_section;
+
+ sec = h->root.root.u.def.section;
+ output_section = sec->output_section;
+ BFD_ASSERT (bfd_is_abs_section (output_section)
+ || output_section->owner == output_bfd);
+ if (h->plt_offset != 0
+ && (h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ type = N_UNDF | N_EXT;
+ val = 0;
+ }
+ else
+ {
+ if (output_section == obj_textsec (output_bfd))
+ type = (h->root.root.type == bfd_link_hash_defined
+ ? N_TEXT
+ : N_WEAKT);
+ else if (output_section == obj_datasec (output_bfd))
+ type = (h->root.root.type == bfd_link_hash_defined
+ ? N_DATA
+ : N_WEAKD);
+ else if (output_section == obj_bsssec (output_bfd))
+ type = (h->root.root.type == bfd_link_hash_defined
+ ? N_BSS
+ : N_WEAKB);
+ else
+ type = (h->root.root.type == bfd_link_hash_defined
+ ? N_ABS
+ : N_WEAKA);
+ type |= N_EXT;
+ val = (h->root.root.u.def.value
+ + output_section->vma
+ + sec->output_offset);
+ }
+ }
+ break;
+ case bfd_link_hash_common:
+ type = N_UNDF | N_EXT;
+ val = h->root.root.u.c.size;
+ break;
+ case bfd_link_hash_undefweak:
+ type = N_WEAKU;
+ val = 0;
+ break;
+ case bfd_link_hash_indirect:
+ case bfd_link_hash_warning:
+ /* FIXME: Ignore these for now. The circumstances under which
+ they should be written out are not clear to me. */
+ return true;
+ }
+
+ s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ outsym = ((struct external_nlist *)
+ (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE));
+
+ bfd_h_put_8 (output_bfd, type, outsym->e_type);
+ bfd_h_put_8 (output_bfd, 0, outsym->e_other);
+
+ /* FIXME: The native linker doesn't use 0 for desc. It seems to use
+ one less than the desc value in the shared library, although that
+ seems unlikely. */
+ bfd_h_put_16 (output_bfd, 0, outsym->e_desc);
+
+ PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx);
+ PUT_WORD (output_bfd, val, outsym->e_value);
+
+ return true;
+}
+
+/* This is called for each reloc against an external symbol. If this
+ is a reloc which are are going to copy as a dynamic reloc, then
+ copy it over, and tell the caller to not bother processing this
+ reloc. */
+
+/*ARGSUSED*/
+static boolean
+sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
+ contents, skip, relocationp)
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ struct aout_link_hash_entry *harg;
+ PTR reloc;
+ bfd_byte *contents;
+ boolean *skip;
+ bfd_vma *relocationp;
+{
+ struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
+ bfd *dynobj;
+ boolean baserel;
+ boolean jmptbl;
+ boolean pcrel;
+ asection *s;
+ bfd_byte *p;
+ long indx;
+
+ *skip = false;
+
+ dynobj = sunos_hash_table (info)->dynobj;
+
+ if (h != NULL
+ && h->plt_offset != 0
+ && (info->shared
+ || (h->flags & SUNOS_DEF_REGULAR) == 0))
+ {
+ asection *splt;
+
+ /* Redirect the relocation to the PLT entry. */
+ splt = bfd_get_section_by_name (dynobj, ".plt");
+ *relocationp = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt_offset);
+ }
+
+ if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
+ {
+ struct reloc_std_external *srel;
+
+ srel = (struct reloc_std_external *) reloc;
+ if (bfd_header_big_endian (input_bfd))
+ {
+ baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
+ jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+ pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+ }
+ else
+ {
+ baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
+ jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
+ pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+ }
+ }
+ else
+ {
+ struct reloc_ext_external *erel;
+ int r_type;
+
+ erel = (struct reloc_ext_external *) reloc;
+ if (bfd_header_big_endian (input_bfd))
+ r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+ >> RELOC_EXT_BITS_TYPE_SH_BIG);
+ else
+ r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+ >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
+ baserel = (r_type == RELOC_BASE10
+ || r_type == RELOC_BASE13
+ || r_type == RELOC_BASE22);
+ jmptbl = r_type == RELOC_JMP_TBL;
+ pcrel = (r_type == RELOC_DISP8
+ || r_type == RELOC_DISP16
+ || r_type == RELOC_DISP32
+ || r_type == RELOC_WDISP30
+ || r_type == RELOC_WDISP22);
+ /* We don't consider the PC10 and PC22 types to be PC relative,
+ because they are pcrel_offset. */
+ }
+
+ if (baserel)
+ {
+ bfd_vma *got_offsetp;
+ asection *sgot;
+
+ if (h != NULL)
+ got_offsetp = &h->got_offset;
+ else if (adata (input_bfd).local_got_offsets == NULL)
+ got_offsetp = NULL;
+ else
+ {
+ struct reloc_std_external *srel;
+ int r_index;
+
+ srel = (struct reloc_std_external *) reloc;
+ if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
+ {
+ if (bfd_header_big_endian (input_bfd))
+ r_index = ((srel->r_index[0] << 16)
+ | (srel->r_index[1] << 8)
+ | srel->r_index[2]);
+ else
+ r_index = ((srel->r_index[2] << 16)
+ | (srel->r_index[1] << 8)
+ | srel->r_index[0]);
+ }
+ else
+ {
+ struct reloc_ext_external *erel;
+
+ erel = (struct reloc_ext_external *) reloc;
+ if (bfd_header_big_endian (input_bfd))
+ r_index = ((erel->r_index[0] << 16)
+ | (erel->r_index[1] << 8)
+ | erel->r_index[2]);
+ else
+ r_index = ((erel->r_index[2] << 16)
+ | (erel->r_index[1] << 8)
+ | erel->r_index[0]);
+ }
+
+ got_offsetp = adata (input_bfd).local_got_offsets + r_index;
+ }
+
+ BFD_ASSERT (got_offsetp != NULL && *got_offsetp != 0);
+
+ sgot = bfd_get_section_by_name (dynobj, ".got");
+
+ /* We set the least significant bit to indicate whether we have
+ already initialized the GOT entry. */
+ if ((*got_offsetp & 1) == 0)
+ {
+ if (h == NULL
+ || (! info->shared
+ && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
+ || (h->flags & SUNOS_DEF_REGULAR) != 0)))
+ PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp);
+ else
+ PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp);
+
+ if (info->shared
+ || (h != NULL
+ && (h->flags & SUNOS_DEF_DYNAMIC) != 0
+ && (h->flags & SUNOS_DEF_REGULAR) == 0))
+ {
+ /* We need to create a GLOB_DAT or 32 reloc to tell the
+ dynamic linker to fill in this entry in the table. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
+ < s->_raw_size);
+
+ p = (s->contents
+ + s->reloc_count * obj_reloc_entry_size (dynobj));
+
+ if (h != NULL)
+ indx = h->dynindx;
+ else
+ indx = 0;
+
+ if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
+ {
+ struct reloc_std_external *srel;
+
+ srel = (struct reloc_std_external *) p;
+ PUT_WORD (dynobj,
+ (*got_offsetp
+ + sgot->output_section->vma
+ + sgot->output_offset),
+ srel->r_address);
+ if (bfd_header_big_endian (dynobj))
+ {
+ srel->r_index[0] = (bfd_byte)(indx >> 16);
+ srel->r_index[1] = (bfd_byte)(indx >> 8);
+ srel->r_index[2] = (bfd_byte)indx;
+ if (h == NULL)
+ srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG;
+ else
+ srel->r_type[0] =
+ (RELOC_STD_BITS_EXTERN_BIG
+ | RELOC_STD_BITS_BASEREL_BIG
+ | RELOC_STD_BITS_RELATIVE_BIG
+ | (2 << RELOC_STD_BITS_LENGTH_SH_BIG));
+ }
+ else
+ {
+ srel->r_index[2] = (bfd_byte)(indx >> 16);
+ srel->r_index[1] = (bfd_byte)(indx >> 8);
+ srel->r_index[0] = (bfd_byte)indx;
+ if (h == NULL)
+ srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE;
+ else
+ srel->r_type[0] =
+ (RELOC_STD_BITS_EXTERN_LITTLE
+ | RELOC_STD_BITS_BASEREL_LITTLE
+ | RELOC_STD_BITS_RELATIVE_LITTLE
+ | (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE));
+ }
+ }
+ else
+ {
+ struct reloc_ext_external *erel;
+
+ erel = (struct reloc_ext_external *) p;
+ PUT_WORD (dynobj,
+ (*got_offsetp
+ + sgot->output_section->vma
+ + sgot->output_offset),
+ erel->r_address);
+ if (bfd_header_big_endian (dynobj))
+ {
+ erel->r_index[0] = (bfd_byte)(indx >> 16);
+ erel->r_index[1] = (bfd_byte)(indx >> 8);
+ erel->r_index[2] = (bfd_byte)indx;
+ if (h == NULL)
+ erel->r_type[0] =
+ RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG;
+ else
+ erel->r_type[0] =
+ (RELOC_EXT_BITS_EXTERN_BIG
+ | (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG));
+ }
+ else
+ {
+ erel->r_index[2] = (bfd_byte)(indx >> 16);
+ erel->r_index[1] = (bfd_byte)(indx >> 8);
+ erel->r_index[0] = (bfd_byte)indx;
+ if (h == NULL)
+ erel->r_type[0] =
+ RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE;
+ else
+ erel->r_type[0] =
+ (RELOC_EXT_BITS_EXTERN_LITTLE
+ | (RELOC_GLOB_DAT
+ << RELOC_EXT_BITS_TYPE_SH_LITTLE));
+ }
+ PUT_WORD (dynobj, 0, erel->r_addend);
+ }
+
+ ++s->reloc_count;
+ }
+
+ *got_offsetp |= 1;
+ }
+
+ *relocationp = (sgot->vma
+ + (*got_offsetp &~ 1)
+ - sunos_hash_table (info)->got_base);
+
+ /* There is nothing else to do for a base relative reloc. */
+ return true;
+ }
+
+ if (! sunos_hash_table (info)->dynamic_sections_needed)
+ return true;
+ if (! info->shared)
+ {
+ if (h == NULL
+ || h->dynindx == -1
+ || h->root.root.type != bfd_link_hash_undefined
+ || (h->flags & SUNOS_DEF_REGULAR) != 0
+ || (h->flags & SUNOS_DEF_DYNAMIC) == 0
+ || (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0)
+ return true;
+ }
+ else
+ {
+ if (h != NULL
+ && (h->dynindx == -1
+ || jmptbl
+ || strcmp (h->root.root.root.string,
+ "__GLOBAL_OFFSET_TABLE_") == 0))
+ return true;
+ }
+
+ /* It looks like this is a reloc we are supposed to copy. */
+
+ s = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->_raw_size);
+
+ p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj);
+
+ /* Copy the reloc over. */
+ memcpy (p, reloc, obj_reloc_entry_size (dynobj));
+
+ if (h != NULL)
+ indx = h->dynindx;
+ else
+ indx = 0;
+
+ /* Adjust the address and symbol index. */
+ if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
+ {
+ struct reloc_std_external *srel;
+
+ srel = (struct reloc_std_external *) p;
+ PUT_WORD (dynobj,
+ (GET_WORD (dynobj, srel->r_address)
+ + input_section->output_section->vma
+ + input_section->output_offset),
+ srel->r_address);
+ if (bfd_header_big_endian (dynobj))
+ {
+ srel->r_index[0] = (bfd_byte)(indx >> 16);
+ srel->r_index[1] = (bfd_byte)(indx >> 8);
+ srel->r_index[2] = (bfd_byte)indx;
+ }
+ else
+ {
+ srel->r_index[2] = (bfd_byte)(indx >> 16);
+ srel->r_index[1] = (bfd_byte)(indx >> 8);
+ srel->r_index[0] = (bfd_byte)indx;
+ }
+ /* FIXME: We may have to change the addend for a PC relative
+ reloc. */
+ }
+ else
+ {
+ struct reloc_ext_external *erel;
+
+ erel = (struct reloc_ext_external *) p;
+ PUT_WORD (dynobj,
+ (GET_WORD (dynobj, erel->r_address)
+ + input_section->output_section->vma
+ + input_section->output_offset),
+ erel->r_address);
+ if (bfd_header_big_endian (dynobj))
+ {
+ erel->r_index[0] = (bfd_byte)(indx >> 16);
+ erel->r_index[1] = (bfd_byte)(indx >> 8);
+ erel->r_index[2] = (bfd_byte)indx;
+ }
+ else
+ {
+ erel->r_index[2] = (bfd_byte)(indx >> 16);
+ erel->r_index[1] = (bfd_byte)(indx >> 8);
+ erel->r_index[0] = (bfd_byte)indx;
+ }
+ if (pcrel && h != NULL)
+ {
+ /* Adjust the addend for the change in address. */
+ PUT_WORD (dynobj,
+ (GET_WORD (dynobj, erel->r_addend)
+ - (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma)),
+ erel->r_addend);
+ }
+ }
+
+ ++s->reloc_count;
+
+ if (h != NULL)
+ *skip = true;
+
+ return true;
+}
+
+/* Finish up the dynamic linking information. */
+
+static boolean
+sunos_finish_dynamic_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd *dynobj;
+ asection *o;
+ asection *s;
+ asection *sdyn;
+
+ if (! sunos_hash_table (info)->dynamic_sections_needed
+ && ! sunos_hash_table (info)->got_needed)
+ return true;
+
+ dynobj = sunos_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+
+ /* Finish up the .need section. The linker emulation code filled it
+ in, but with offsets from the start of the section instead of
+ real addresses. Now that we know the section location, we can
+ fill in the final values. */
+ s = bfd_get_section_by_name (dynobj, ".need");
+ if (s != NULL && s->_raw_size != 0)
+ {
+ file_ptr filepos;
+ bfd_byte *p;
+
+ filepos = s->output_section->filepos + s->output_offset;
+ p = s->contents;
+ while (1)
+ {
+ bfd_vma val;
+
+ PUT_WORD (dynobj, GET_WORD (dynobj, p) + filepos, p);
+ val = GET_WORD (dynobj, p + 12);
+ if (val == 0)
+ break;
+ PUT_WORD (dynobj, val + filepos, p + 12);
+ p += 16;
+ }
+ }
+
+ /* The first entry in the .got section is the address of the
+ dynamic information, unless this is a shared library. */
+ s = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (s != NULL);
+ if (info->shared || sdyn->_raw_size == 0)
+ PUT_WORD (dynobj, 0, s->contents);
+ else
+ PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset,
+ s->contents);
+
+ for (o = dynobj->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_HAS_CONTENTS) != 0
+ && o->contents != NULL)
+ {
+ BFD_ASSERT (o->output_section != NULL
+ && o->output_section->owner == abfd);
+ if (! bfd_set_section_contents (abfd, o->output_section,
+ o->contents, o->output_offset,
+ o->_raw_size))
+ return false;
+ }
+ }
+
+ if (sdyn->_raw_size > 0)
+ {
+ struct external_sun4_dynamic esd;
+ struct external_sun4_dynamic_link esdl;
+
+ /* Finish up the dynamic link information. */
+ PUT_WORD (dynobj, (bfd_vma) 3, esd.ld_version);
+ PUT_WORD (dynobj,
+ sdyn->output_section->vma + sdyn->output_offset + sizeof esd,
+ esd.ldd);
+ PUT_WORD (dynobj,
+ (sdyn->output_section->vma
+ + sdyn->output_offset
+ + sizeof esd
+ + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE),
+ esd.ld);
+
+ if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd,
+ sdyn->output_offset, sizeof esd))
+ return false;
+
+ PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded);
+
+ s = bfd_get_section_by_name (dynobj, ".need");
+ if (s == NULL || s->_raw_size == 0)
+ PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need);
+ else
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_need);
+
+ s = bfd_get_section_by_name (dynobj, ".rules");
+ if (s == NULL || s->_raw_size == 0)
+ PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules);
+ else
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_rules);
+
+ s = bfd_get_section_by_name (dynobj, ".got");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
+ esdl.ld_got);
+
+ s = bfd_get_section_by_name (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
+ esdl.ld_plt);
+ PUT_WORD (dynobj, s->_raw_size, esdl.ld_plt_sz);
+
+ s = bfd_get_section_by_name (dynobj, ".dynrel");
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
+ == s->_raw_size);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_rel);
+
+ s = bfd_get_section_by_name (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_hash);
+
+ s = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_stab);
+
+ PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_stab_hash);
+
+ PUT_WORD (dynobj, (bfd_vma) sunos_hash_table (info)->bucketcount,
+ esdl.ld_buckets);
+
+ s = bfd_get_section_by_name (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_symbols);
+ PUT_WORD (dynobj, s->_raw_size, esdl.ld_symb_size);
+
+ /* The size of the text area is the size of the .text section
+ rounded up to a page boundary. FIXME: Should the page size be
+ conditional on something? */
+ PUT_WORD (dynobj,
+ BFD_ALIGN (obj_textsec (abfd)->_raw_size, 0x2000),
+ esdl.ld_text);
+
+ if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl,
+ (sdyn->output_offset
+ + sizeof esd
+ + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE),
+ sizeof esdl))
+ return false;
+
+ abfd->flags |= DYNAMIC;
+ }
+
+ return true;
+}
diff --git a/bfd/syms.c b/bfd/syms.c
new file mode 100644
index 00000000000..f69d1f21fa4
--- /dev/null
+++ b/bfd/syms.c
@@ -0,0 +1,1253 @@
+/* Generic symbol-table support for the BFD library.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SECTION
+ Symbols
+
+ BFD tries to maintain as much symbol information as it can when
+ it moves information from file to file. BFD passes information
+ to applications though the <<asymbol>> structure. When the
+ application requests the symbol table, BFD reads the table in
+ the native form and translates parts of it into the internal
+ format. To maintain more than the information passed to
+ applications, some targets keep some information ``behind the
+ scenes'' in a structure only the particular back end knows
+ about. For example, the coff back end keeps the original
+ symbol table structure as well as the canonical structure when
+ a BFD is read in. On output, the coff back end can reconstruct
+ the output symbol table so that no information is lost, even
+ information unique to coff which BFD doesn't know or
+ understand. If a coff symbol table were read, but were written
+ through an a.out back end, all the coff specific information
+ would be lost. The symbol table of a BFD
+ is not necessarily read in until a canonicalize request is
+ made. Then the BFD back end fills in a table provided by the
+ application with pointers to the canonical information. To
+ output symbols, the application provides BFD with a table of
+ pointers to pointers to <<asymbol>>s. This allows applications
+ like the linker to output a symbol as it was read, since the ``behind
+ the scenes'' information will be still available.
+@menu
+@* Reading Symbols::
+@* Writing Symbols::
+@* Mini Symbols::
+@* typedef asymbol::
+@* symbol handling functions::
+@end menu
+
+INODE
+Reading Symbols, Writing Symbols, Symbols, Symbols
+SUBSECTION
+ Reading symbols
+
+ There are two stages to reading a symbol table from a BFD:
+ allocating storage, and the actual reading process. This is an
+ excerpt from an application which reads the symbol table:
+
+| long storage_needed;
+| asymbol **symbol_table;
+| long number_of_symbols;
+| long i;
+|
+| storage_needed = bfd_get_symtab_upper_bound (abfd);
+|
+| if (storage_needed < 0)
+| FAIL
+|
+| if (storage_needed == 0) {
+| return ;
+| }
+| symbol_table = (asymbol **) xmalloc (storage_needed);
+| ...
+| number_of_symbols =
+| bfd_canonicalize_symtab (abfd, symbol_table);
+|
+| if (number_of_symbols < 0)
+| FAIL
+|
+| for (i = 0; i < number_of_symbols; i++) {
+| process_symbol (symbol_table[i]);
+| }
+
+ All storage for the symbols themselves is in an objalloc
+ connected to the BFD; it is freed when the BFD is closed.
+
+
+INODE
+Writing Symbols, Mini Symbols, Reading Symbols, Symbols
+SUBSECTION
+ Writing symbols
+
+ Writing of a symbol table is automatic when a BFD open for
+ writing is closed. The application attaches a vector of
+ pointers to pointers to symbols to the BFD being written, and
+ fills in the symbol count. The close and cleanup code reads
+ through the table provided and performs all the necessary
+ operations. The BFD output code must always be provided with an
+ ``owned'' symbol: one which has come from another BFD, or one
+ which has been created using <<bfd_make_empty_symbol>>. Here is an
+ example showing the creation of a symbol table with only one element:
+
+| #include "bfd.h"
+| main()
+| {
+| bfd *abfd;
+| asymbol *ptrs[2];
+| asymbol *new;
+|
+| abfd = bfd_openw("foo","a.out-sunos-big");
+| bfd_set_format(abfd, bfd_object);
+| new = bfd_make_empty_symbol(abfd);
+| new->name = "dummy_symbol";
+| new->section = bfd_make_section_old_way(abfd, ".text");
+| new->flags = BSF_GLOBAL;
+| new->value = 0x12345;
+|
+| ptrs[0] = new;
+| ptrs[1] = (asymbol *)0;
+|
+| bfd_set_symtab(abfd, ptrs, 1);
+| bfd_close(abfd);
+| }
+|
+| ./makesym
+| nm foo
+| 00012345 A dummy_symbol
+
+ Many formats cannot represent arbitary symbol information; for
+ instance, the <<a.out>> object format does not allow an
+ arbitary number of sections. A symbol pointing to a section
+ which is not one of <<.text>>, <<.data>> or <<.bss>> cannot
+ be described.
+
+INODE
+Mini Symbols, typedef asymbol, Writing Symbols, Symbols
+SUBSECTION
+ Mini Symbols
+
+ Mini symbols provide read-only access to the symbol table.
+ They use less memory space, but require more time to access.
+ They can be useful for tools like nm or objdump, which may
+ have to handle symbol tables of extremely large executables.
+
+ The <<bfd_read_minisymbols>> function will read the symbols
+ into memory in an internal form. It will return a <<void *>>
+ pointer to a block of memory, a symbol count, and the size of
+ each symbol. The pointer is allocated using <<malloc>>, and
+ should be freed by the caller when it is no longer needed.
+
+ The function <<bfd_minisymbol_to_symbol>> will take a pointer
+ to a minisymbol, and a pointer to a structure returned by
+ <<bfd_make_empty_symbol>>, and return a <<asymbol>> structure.
+ The return value may or may not be the same as the value from
+ <<bfd_make_empty_symbol>> which was passed in.
+
+*/
+
+
+
+/*
+DOCDD
+INODE
+typedef asymbol, symbol handling functions, Mini Symbols, Symbols
+
+*/
+/*
+SUBSECTION
+ typedef asymbol
+
+ An <<asymbol>> has the form:
+
+*/
+
+/*
+CODE_FRAGMENT
+
+.
+.typedef struct symbol_cache_entry
+.{
+. {* A pointer to the BFD which owns the symbol. This information
+. is necessary so that a back end can work out what additional
+. information (invisible to the application writer) is carried
+. with the symbol.
+.
+. This field is *almost* redundant, since you can use section->owner
+. instead, except that some symbols point to the global sections
+. bfd_{abs,com,und}_section. This could be fixed by making
+. these globals be per-bfd (or per-target-flavor). FIXME. *}
+.
+. struct _bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *}
+.
+. {* The text of the symbol. The name is left alone, and not copied; the
+. application may not alter it. *}
+. CONST char *name;
+.
+. {* The value of the symbol. This really should be a union of a
+. numeric value with a pointer, since some flags indicate that
+. a pointer to another symbol is stored here. *}
+. symvalue value;
+.
+. {* Attributes of a symbol: *}
+.
+.#define BSF_NO_FLAGS 0x00
+.
+. {* The symbol has local scope; <<static>> in <<C>>. The value
+. is the offset into the section of the data. *}
+.#define BSF_LOCAL 0x01
+.
+. {* The symbol has global scope; initialized data in <<C>>. The
+. value is the offset into the section of the data. *}
+.#define BSF_GLOBAL 0x02
+.
+. {* The symbol has global scope and is exported. The value is
+. the offset into the section of the data. *}
+.#define BSF_EXPORT BSF_GLOBAL {* no real difference *}
+.
+. {* A normal C symbol would be one of:
+. <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or
+. <<BSF_GLOBAL>> *}
+.
+. {* The symbol is a debugging record. The value has an arbitary
+. meaning. *}
+.#define BSF_DEBUGGING 0x08
+.
+. {* The symbol denotes a function entry point. Used in ELF,
+. perhaps others someday. *}
+.#define BSF_FUNCTION 0x10
+.
+. {* Used by the linker. *}
+.#define BSF_KEEP 0x20
+.#define BSF_KEEP_G 0x40
+.
+. {* A weak global symbol, overridable without warnings by
+. a regular global symbol of the same name. *}
+.#define BSF_WEAK 0x80
+.
+. {* This symbol was created to point to a section, e.g. ELF's
+. STT_SECTION symbols. *}
+.#define BSF_SECTION_SYM 0x100
+.
+. {* The symbol used to be a common symbol, but now it is
+. allocated. *}
+.#define BSF_OLD_COMMON 0x200
+.
+. {* The default value for common data. *}
+.#define BFD_FORT_COMM_DEFAULT_VALUE 0
+.
+. {* In some files the type of a symbol sometimes alters its
+. location in an output file - ie in coff a <<ISFCN>> symbol
+. which is also <<C_EXT>> symbol appears where it was
+. declared and not at the end of a section. This bit is set
+. by the target BFD part to convey this information. *}
+.
+.#define BSF_NOT_AT_END 0x400
+.
+. {* Signal that the symbol is the label of constructor section. *}
+.#define BSF_CONSTRUCTOR 0x800
+.
+. {* Signal that the symbol is a warning symbol. The name is a
+. warning. The name of the next symbol is the one to warn about;
+. if a reference is made to a symbol with the same name as the next
+. symbol, a warning is issued by the linker. *}
+.#define BSF_WARNING 0x1000
+.
+. {* Signal that the symbol is indirect. This symbol is an indirect
+. pointer to the symbol with the same name as the next symbol. *}
+.#define BSF_INDIRECT 0x2000
+.
+. {* BSF_FILE marks symbols that contain a file name. This is used
+. for ELF STT_FILE symbols. *}
+.#define BSF_FILE 0x4000
+.
+. {* Symbol is from dynamic linking information. *}
+.#define BSF_DYNAMIC 0x8000
+.
+. {* The symbol denotes a data object. Used in ELF, and perhaps
+. others someday. *}
+.#define BSF_OBJECT 0x10000
+.
+. flagword flags;
+.
+. {* A pointer to the section to which this symbol is
+. relative. This will always be non NULL, there are special
+. sections for undefined and absolute symbols. *}
+. struct sec *section;
+.
+. {* Back end special data. *}
+. union
+. {
+. PTR p;
+. bfd_vma i;
+. } udata;
+.
+.} asymbol;
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "aout/stab_gnu.h"
+
+static char coff_section_type PARAMS ((const char *));
+
+/*
+DOCDD
+INODE
+symbol handling functions, , typedef asymbol, Symbols
+SUBSECTION
+ Symbol handling functions
+*/
+
+/*
+FUNCTION
+ bfd_get_symtab_upper_bound
+
+DESCRIPTION
+ Return the number of bytes required to store a vector of pointers
+ to <<asymbols>> for all the symbols in the BFD @var{abfd},
+ including a terminal NULL pointer. If there are no symbols in
+ the BFD, then return 0. If an error occurs, return -1.
+
+.#define bfd_get_symtab_upper_bound(abfd) \
+. BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+
+*/
+
+/*
+FUNCTION
+ bfd_is_local_label
+
+SYNOPSIS
+ boolean bfd_is_local_label(bfd *abfd, asymbol *sym);
+
+DESCRIPTION
+ Return true if the given symbol @var{sym} in the BFD @var{abfd} is
+ a compiler generated local label, else return false.
+*/
+
+boolean
+bfd_is_local_label (abfd, sym)
+ bfd *abfd;
+ asymbol *sym;
+{
+ if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
+ return false;
+ if (sym->name == NULL)
+ return false;
+ return bfd_is_local_label_name (abfd, sym->name);
+}
+
+/*
+FUNCTION
+ bfd_is_local_label_name
+
+SYNOPSIS
+ boolean bfd_is_local_label_name(bfd *abfd, const char *name);
+
+DESCRIPTION
+ Return true if a symbol with the name @var{name} in the BFD
+ @var{abfd} is a compiler generated local label, else return
+ false. This just checks whether the name has the form of a
+ local label.
+
+.#define bfd_is_local_label_name(abfd, name) \
+. BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
+*/
+
+/*
+FUNCTION
+ bfd_canonicalize_symtab
+
+DESCRIPTION
+ Read the symbols from the BFD @var{abfd}, and fills in
+ the vector @var{location} with pointers to the symbols and
+ a trailing NULL.
+ Return the actual number of symbol pointers, not
+ including the NULL.
+
+
+.#define bfd_canonicalize_symtab(abfd, location) \
+. BFD_SEND (abfd, _bfd_canonicalize_symtab,\
+. (abfd, location))
+
+*/
+
+
+/*
+FUNCTION
+ bfd_set_symtab
+
+SYNOPSIS
+ boolean bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int count);
+
+DESCRIPTION
+ Arrange that when the output BFD @var{abfd} is closed,
+ the table @var{location} of @var{count} pointers to symbols
+ will be written.
+*/
+
+boolean
+bfd_set_symtab (abfd, location, symcount)
+ bfd *abfd;
+ asymbol **location;
+ unsigned int symcount;
+{
+ if ((abfd->format != bfd_object) || (bfd_read_p (abfd)))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ bfd_get_outsymbols (abfd) = location;
+ bfd_get_symcount (abfd) = symcount;
+ return true;
+}
+
+/*
+FUNCTION
+ bfd_print_symbol_vandf
+
+SYNOPSIS
+ void bfd_print_symbol_vandf(PTR file, asymbol *symbol);
+
+DESCRIPTION
+ Print the value and flags of the @var{symbol} supplied to the
+ stream @var{file}.
+*/
+void
+bfd_print_symbol_vandf (arg, symbol)
+ PTR arg;
+ asymbol *symbol;
+{
+ FILE *file = (FILE *) arg;
+ flagword type = symbol->flags;
+ if (symbol->section != (asection *) NULL)
+ {
+ fprintf_vma (file, symbol->value + symbol->section->vma);
+ }
+ else
+ {
+ fprintf_vma (file, symbol->value);
+ }
+
+ /* This presumes that a symbol can not be both BSF_DEBUGGING and
+ BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and
+ BSF_OBJECT. */
+ fprintf (file, " %c%c%c%c%c%c%c",
+ ((type & BSF_LOCAL)
+ ? (type & BSF_GLOBAL) ? '!' : 'l'
+ : (type & BSF_GLOBAL) ? 'g' : ' '),
+ (type & BSF_WEAK) ? 'w' : ' ',
+ (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
+ (type & BSF_WARNING) ? 'W' : ' ',
+ (type & BSF_INDIRECT) ? 'I' : ' ',
+ (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
+ ((type & BSF_FUNCTION)
+ ? 'F'
+ : ((type & BSF_FILE)
+ ? 'f'
+ : ((type & BSF_OBJECT) ? 'O' : ' '))));
+}
+
+
+/*
+FUNCTION
+ bfd_make_empty_symbol
+
+DESCRIPTION
+ Create a new <<asymbol>> structure for the BFD @var{abfd}
+ and return a pointer to it.
+
+ This routine is necessary because each back end has private
+ information surrounding the <<asymbol>>. Building your own
+ <<asymbol>> and pointing to it will not create the private
+ information, and will cause problems later on.
+
+.#define bfd_make_empty_symbol(abfd) \
+. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+*/
+
+/*
+FUNCTION
+ bfd_make_debug_symbol
+
+DESCRIPTION
+ Create a new <<asymbol>> structure for the BFD @var{abfd},
+ to be used as a debugging symbol. Further details of its use have
+ yet to be worked out.
+
+.#define bfd_make_debug_symbol(abfd,ptr,size) \
+. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+*/
+
+struct section_to_type
+{
+ CONST char *section;
+ char type;
+};
+
+/* Map section names to POSIX/BSD single-character symbol types.
+ This table is probably incomplete. It is sorted for convenience of
+ adding entries. Since it is so short, a linear search is used. */
+static CONST struct section_to_type stt[] =
+{
+ {"*DEBUG*", 'N'},
+ {".bss", 'b'},
+ {"zerovars", 'b'}, /* MRI .bss */
+ {".data", 'd'},
+ {"vars", 'd'}, /* MRI .data */
+ {".rdata", 'r'}, /* Read only data. */
+ {".rodata", 'r'}, /* Read only data. */
+ {".sbss", 's'}, /* Small BSS (uninitialized data). */
+ {".scommon", 'c'}, /* Small common. */
+ {".sdata", 'g'}, /* Small initialized data. */
+ {".text", 't'},
+ {"code", 't'}, /* MRI .text */
+ {0, 0}
+};
+
+/* Return the single-character symbol type corresponding to
+ section S, or '?' for an unknown COFF section.
+
+ Check for any leading string which matches, so .text5 returns
+ 't' as well as .text */
+
+static char
+coff_section_type (s)
+ const char *s;
+{
+ CONST struct section_to_type *t;
+
+ for (t = &stt[0]; t->section; t++)
+ if (!strncmp (s, t->section, strlen (t->section)))
+ return t->type;
+
+ return '?';
+}
+
+#ifndef islower
+#define islower(c) ((c) >= 'a' && (c) <= 'z')
+#endif
+#ifndef toupper
+#define toupper(c) (islower(c) ? ((c) & ~0x20) : (c))
+#endif
+
+/*
+FUNCTION
+ bfd_decode_symclass
+
+DESCRIPTION
+ Return a character corresponding to the symbol
+ class of @var{symbol}, or '?' for an unknown class.
+
+SYNOPSIS
+ int bfd_decode_symclass(asymbol *symbol);
+*/
+int
+bfd_decode_symclass (symbol)
+ asymbol *symbol;
+{
+ char c;
+
+ if (bfd_is_com_section (symbol->section))
+ return 'C';
+ if (bfd_is_und_section (symbol->section))
+ return 'U';
+ if (bfd_is_ind_section (symbol->section))
+ return 'I';
+ if (symbol->flags & BSF_WEAK)
+ return 'W';
+ if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
+ return '?';
+
+ if (bfd_is_abs_section (symbol->section))
+ c = 'a';
+ else if (symbol->section)
+ c = coff_section_type (symbol->section->name);
+ else
+ return '?';
+ if (symbol->flags & BSF_GLOBAL)
+ c = toupper (c);
+ return c;
+
+ /* We don't have to handle these cases just yet, but we will soon:
+ N_SETV: 'v';
+ N_SETA: 'l';
+ N_SETT: 'x';
+ N_SETD: 'z';
+ N_SETB: 's';
+ N_INDR: 'i';
+ */
+}
+
+/*
+FUNCTION
+ bfd_symbol_info
+
+DESCRIPTION
+ Fill in the basic info about symbol that nm needs.
+ Additional info may be added by the back-ends after
+ calling this function.
+
+SYNOPSIS
+ void bfd_symbol_info(asymbol *symbol, symbol_info *ret);
+*/
+
+void
+bfd_symbol_info (symbol, ret)
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ ret->type = bfd_decode_symclass (symbol);
+ if (ret->type != 'U')
+ ret->value = symbol->value + symbol->section->vma;
+ else
+ ret->value = 0;
+ ret->name = symbol->name;
+}
+
+/*
+FUNCTION
+ bfd_copy_private_symbol_data
+
+SYNOPSIS
+ boolean bfd_copy_private_symbol_data(bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+
+DESCRIPTION
+ Copy private symbol information from @var{isym} in the BFD
+ @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{osec}.
+
+.#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+. BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
+. (ibfd, isymbol, obfd, osymbol))
+
+*/
+
+/* The generic version of the function which returns mini symbols.
+ This is used when the backend does not provide a more efficient
+ version. It just uses BFD asymbol structures as mini symbols. */
+
+long
+_bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep)
+ bfd *abfd;
+ boolean dynamic;
+ PTR *minisymsp;
+ unsigned int *sizep;
+{
+ long storage;
+ asymbol **syms = NULL;
+ long symcount;
+
+ if (dynamic)
+ storage = bfd_get_dynamic_symtab_upper_bound (abfd);
+ else
+ storage = bfd_get_symtab_upper_bound (abfd);
+ if (storage < 0)
+ goto error_return;
+
+ syms = (asymbol **) bfd_malloc ((size_t) storage);
+ if (syms == NULL)
+ goto error_return;
+
+ if (dynamic)
+ symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
+ else
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+ if (symcount < 0)
+ goto error_return;
+
+ *minisymsp = (PTR) syms;
+ *sizep = sizeof (asymbol *);
+ return symcount;
+
+ error_return:
+ if (syms != NULL)
+ free (syms);
+ return -1;
+}
+
+/* The generic version of the function which converts a minisymbol to
+ an asymbol. We don't worry about the sym argument we are passed;
+ we just return the asymbol the minisymbol points to. */
+
+/*ARGSUSED*/
+asymbol *
+_bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym)
+ bfd *abfd;
+ boolean dynamic;
+ const PTR minisym;
+ asymbol *sym;
+{
+ return *(asymbol **) minisym;
+}
+
+/* Look through stabs debugging information in .stab and .stabstr
+ sections to find the source file and line closest to a desired
+ location. This is used by COFF and ELF targets. It sets *pfound
+ to true if it finds some information. The *pinfo field is used to
+ pass cached information in and out of this routine; this first time
+ the routine is called for a BFD, *pinfo should be NULL. The value
+ placed in *pinfo should be saved with the BFD, and passed back each
+ time this function is called. */
+
+/* We use a cache by default. */
+
+#define ENABLE_CACHING
+
+/* We keep an array of indexentry structures to record where in the
+ stabs section we should look to find line number information for a
+ particular address. */
+
+struct indexentry
+{
+ bfd_vma val;
+ bfd_byte *stab;
+ bfd_byte *str;
+ char *directory_name;
+ char *file_name;
+ char *function_name;
+};
+
+/* Compare two indexentry structures. This is called via qsort. */
+
+static int
+cmpindexentry (a, b)
+ const PTR *a;
+ const PTR *b;
+{
+ const struct indexentry *contestantA = (const struct indexentry *) a;
+ const struct indexentry *contestantB = (const struct indexentry *) b;
+
+ if (contestantA->val < contestantB->val)
+ return -1;
+ else if (contestantA->val > contestantB->val)
+ return 1;
+ else
+ return 0;
+}
+
+/* A pointer to this structure is stored in *pinfo. */
+
+struct stab_find_info
+{
+ /* The .stab section. */
+ asection *stabsec;
+ /* The .stabstr section. */
+ asection *strsec;
+ /* The contents of the .stab section. */
+ bfd_byte *stabs;
+ /* The contents of the .stabstr section. */
+ bfd_byte *strs;
+
+ /* A table that indexes stabs by memory address. */
+ struct indexentry *indextable;
+ /* The number of entries in indextable. */
+ int indextablesize;
+
+#ifdef ENABLE_CACHING
+ /* Cached values to restart quickly. */
+ struct indexentry *cached_indexentry;
+ bfd_vma cached_offset;
+ bfd_byte *cached_stab;
+ char *cached_file_name;
+#endif
+
+ /* Saved ptr to malloc'ed filename. */
+ char *filename;
+};
+
+boolean
+_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound,
+ pfilename, pfnname, pline, pinfo)
+ bfd *abfd;
+ asymbol **symbols;
+ asection *section;
+ bfd_vma offset;
+ boolean *pfound;
+ const char **pfilename;
+ const char **pfnname;
+ unsigned int *pline;
+ PTR *pinfo;
+{
+ struct stab_find_info *info;
+ bfd_size_type stabsize, strsize;
+ bfd_byte *stab, *str, *last_stab;
+ bfd_size_type stroff;
+ struct indexentry *indexentry;
+ char *directory_name, *file_name;
+ int saw_fun;
+
+ *pfound = false;
+ *pfilename = bfd_get_filename (abfd);
+ *pfnname = NULL;
+ *pline = 0;
+
+ /* Stabs entries use a 12 byte format:
+ 4 byte string table index
+ 1 byte stab type
+ 1 byte stab other field
+ 2 byte stab desc field
+ 4 byte stab value
+ FIXME: This will have to change for a 64 bit object format.
+
+ The stabs symbols are divided into compilation units. For the
+ first entry in each unit, the type of 0, the value is the length
+ of the string table for this unit, and the desc field is the
+ number of stabs symbols for this unit. */
+
+#define STRDXOFF (0)
+#define TYPEOFF (4)
+#define OTHEROFF (5)
+#define DESCOFF (6)
+#define VALOFF (8)
+#define STABSIZE (12)
+
+ info = (struct stab_find_info *) *pinfo;
+ if (info != NULL)
+ {
+ if (info->stabsec == NULL || info->strsec == NULL)
+ {
+ /* No stabs debugging information. */
+ return true;
+ }
+
+ stabsize = info->stabsec->_raw_size;
+ strsize = info->strsec->_raw_size;
+ }
+ else
+ {
+ long reloc_size, reloc_count;
+ arelent **reloc_vector;
+ int i;
+ char *name;
+ char *file_name;
+ char *directory_name;
+ char *function_name;
+
+ info = (struct stab_find_info *) bfd_zalloc (abfd, sizeof *info);
+ if (info == NULL)
+ return false;
+
+ /* FIXME: When using the linker --split-by-file or
+ --split-by-reloc options, it is possible for the .stab and
+ .stabstr sections to be split. We should handle that. */
+
+ info->stabsec = bfd_get_section_by_name (abfd, ".stab");
+ info->strsec = bfd_get_section_by_name (abfd, ".stabstr");
+
+ if (info->stabsec == NULL || info->strsec == NULL)
+ {
+ /* No stabs debugging information. Set *pinfo so that we
+ can return quickly in the info != NULL case above. */
+ *pinfo = (PTR) info;
+ return true;
+ }
+
+ stabsize = info->stabsec->_raw_size;
+ strsize = info->strsec->_raw_size;
+
+ info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize);
+ info->strs = (bfd_byte *) bfd_alloc (abfd, strsize);
+ if (info->stabs == NULL || info->strs == NULL)
+ return false;
+
+ if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs, 0,
+ stabsize)
+ || ! bfd_get_section_contents (abfd, info->strsec, info->strs, 0,
+ strsize))
+ return false;
+
+ /* If this is a relocateable object file, we have to relocate
+ the entries in .stab. This should always be simple 32 bit
+ relocations against symbols defined in this object file, so
+ this should be no big deal. */
+ reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
+ if (reloc_size < 0)
+ return false;
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ return false;
+ reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
+ symbols);
+ if (reloc_count < 0)
+ {
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return false;
+ }
+ if (reloc_count > 0)
+ {
+ arelent **pr;
+
+ for (pr = reloc_vector; *pr != NULL; pr++)
+ {
+ arelent *r;
+ unsigned long val;
+ asymbol *sym;
+
+ r = *pr;
+ if (r->howto->rightshift != 0
+ || r->howto->size != 2
+ || r->howto->bitsize != 32
+ || r->howto->pc_relative
+ || r->howto->bitpos != 0
+ || r->howto->dst_mask != 0xffffffff)
+ {
+ (*_bfd_error_handler)
+ (_("Unsupported .stab relocation"));
+ bfd_set_error (bfd_error_invalid_operation);
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+ return false;
+ }
+
+ val = bfd_get_32 (abfd, info->stabs + r->address);
+ val &= r->howto->src_mask;
+ sym = *r->sym_ptr_ptr;
+ val += sym->value + sym->section->vma + r->addend;
+ bfd_put_32 (abfd, val, info->stabs + r->address);
+ }
+ }
+
+ if (reloc_vector != NULL)
+ free (reloc_vector);
+
+ /* First time through this function, build a table matching
+ function VM addresses to stabs, then sort based on starting
+ VM address. Do this in two passes: once to count how many
+ table entries we'll need, and a second to actually build the
+ table. */
+
+ info->indextablesize = 0;
+ saw_fun = 1;
+ for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
+ {
+ if (stab[TYPEOFF] == N_SO)
+ {
+ /* N_SO with null name indicates EOF */
+ if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
+ continue;
+
+ /* if we did not see a function def, leave space for one. */
+ if (saw_fun == 0)
+ ++info->indextablesize;
+
+ saw_fun = 0;
+
+ /* two N_SO's in a row is a filename and directory. Skip */
+ if (stab + STABSIZE < info->stabs + stabsize
+ && *(stab + STABSIZE + TYPEOFF) == N_SO)
+ {
+ stab += STABSIZE;
+ }
+ }
+ else if (stab[TYPEOFF] == N_FUN)
+ {
+ saw_fun = 1;
+ ++info->indextablesize;
+ }
+ }
+
+ if (saw_fun == 0)
+ ++info->indextablesize;
+
+ if (info->indextablesize == 0)
+ return true;
+ ++info->indextablesize;
+
+ info->indextable = ((struct indexentry *)
+ bfd_alloc (abfd,
+ (sizeof (struct indexentry)
+ * info->indextablesize)));
+ if (info->indextable == NULL)
+ return false;
+
+ file_name = NULL;
+ directory_name = NULL;
+ saw_fun = 1;
+
+ for (i = 0, stroff = 0, stab = info->stabs, str = info->strs;
+ i < info->indextablesize && stab < info->stabs + stabsize;
+ stab += STABSIZE)
+ {
+ switch (stab[TYPEOFF])
+ {
+ case 0:
+ /* This is the first entry in a compilation unit. */
+ if ((bfd_size_type) ((info->strs + strsize) - str) < stroff)
+ break;
+ str += stroff;
+ stroff = bfd_get_32 (abfd, stab + VALOFF);
+ break;
+
+ case N_SO:
+ /* The main file name. */
+
+ /* The following code creates a new indextable entry with
+ a NULL function name if there were no N_FUNs in a file.
+ Note that a N_SO without a file name is an EOF and
+ there could be 2 N_SO following it with the new filename
+ and directory. */
+ if (saw_fun == 0)
+ {
+ info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
+ info->indextable[i].stab = last_stab;
+ info->indextable[i].str = str;
+ info->indextable[i].directory_name = directory_name;
+ info->indextable[i].file_name = file_name;
+ info->indextable[i].function_name = NULL;
+ ++i;
+ }
+ saw_fun = 0;
+
+ file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ if (*file_name == '\0')
+ {
+ directory_name = NULL;
+ file_name = NULL;
+ saw_fun = 1;
+ }
+ else {
+ last_stab = stab;
+ if (stab + STABSIZE >= info->stabs + stabsize
+ || *(stab + STABSIZE + TYPEOFF) != N_SO)
+ {
+ directory_name = NULL;
+ }
+ else
+ {
+ /* Two consecutive N_SOs are a directory and a file
+ name. */
+ stab += STABSIZE;
+ directory_name = file_name;
+ file_name = ((char *) str
+ + bfd_get_32 (abfd, stab + STRDXOFF));
+ }
+ }
+ break;
+
+ case N_SOL:
+ /* The name of an include file. */
+ file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ break;
+
+ case N_FUN:
+ /* A function name. */
+ saw_fun = 1;
+ name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+
+ if (*name == '\0')
+ name = NULL;
+
+ function_name = name;
+
+ if (name == NULL)
+ continue;
+
+ info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
+ info->indextable[i].stab = stab;
+ info->indextable[i].str = str;
+ info->indextable[i].directory_name = directory_name;
+ info->indextable[i].file_name = file_name;
+ info->indextable[i].function_name = function_name;
+ ++i;
+ break;
+ }
+ }
+
+ if (saw_fun == 0)
+ {
+ info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
+ info->indextable[i].stab = last_stab;
+ info->indextable[i].str = str;
+ info->indextable[i].directory_name = directory_name;
+ info->indextable[i].file_name = file_name;
+ info->indextable[i].function_name = NULL;
+ ++i;
+ }
+
+ info->indextable[i].val = (bfd_vma) -1;
+ info->indextable[i].stab = info->stabs + stabsize;
+ info->indextable[i].str = str;
+ info->indextable[i].directory_name = NULL;
+ info->indextable[i].file_name = NULL;
+ info->indextable[i].function_name = NULL;
+ ++i;
+
+ info->indextablesize = i;
+ qsort (info->indextable, i, sizeof (struct indexentry), cmpindexentry);
+
+ *pinfo = (PTR) info;
+ }
+
+ /* We are passed a section relative offset. The offsets in the
+ stabs information are absolute. */
+ offset += bfd_get_section_vma (abfd, section);
+
+#ifdef ENABLE_CACHING
+ if (info->cached_indexentry != NULL
+ && offset >= info->cached_offset
+ && offset < (info->cached_indexentry + 1)->val)
+ {
+ stab = info->cached_stab;
+ indexentry = info->cached_indexentry;
+ file_name = info->cached_file_name;
+ }
+ else
+#endif
+ {
+ /* Cache non-existant or invalid. Do binary search on
+ indextable. */
+
+ long low, high;
+ long mid = -1;
+
+ indexentry = NULL;
+
+ low = 0;
+ high = info->indextablesize - 1;
+ while (low != high)
+ {
+ mid = (high + low) / 2;
+ if (offset >= info->indextable[mid].val
+ && offset < info->indextable[mid + 1].val)
+ {
+ indexentry = &info->indextable[mid];
+ break;
+ }
+
+ if (info->indextable[mid].val > offset)
+ high = mid;
+ else
+ low = mid + 1;
+ }
+
+ if (indexentry == NULL)
+ return true;
+
+ stab = indexentry->stab + STABSIZE;
+ file_name = indexentry->file_name;
+ }
+
+ directory_name = indexentry->directory_name;
+ str = indexentry->str;
+
+ for (; stab < (indexentry+1)->stab; stab += STABSIZE)
+ {
+ boolean done;
+ bfd_vma val;
+
+ done = false;
+
+ switch (stab[TYPEOFF])
+ {
+ case N_SOL:
+ /* The name of an include file. */
+ val = bfd_get_32 (abfd, stab + VALOFF);
+ if (val <= offset)
+ {
+ file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ *pline = 0;
+ }
+ break;
+
+ case N_SLINE:
+ case N_DSLINE:
+ case N_BSLINE:
+ /* A line number. The value is relative to the start of the
+ current function. */
+ val = indexentry->val + bfd_get_32 (abfd, stab + VALOFF);
+ if (val <= offset)
+ {
+ *pline = bfd_get_16 (abfd, stab + DESCOFF);
+
+#ifdef ENABLE_CACHING
+ info->cached_stab = stab;
+ info->cached_offset = val;
+ info->cached_file_name = file_name;
+ info->cached_indexentry = indexentry;
+#endif
+ }
+ if (val > offset)
+ done = true;
+ break;
+
+ case N_FUN:
+ case N_SO:
+ done = true;
+ break;
+ }
+
+ if (done)
+ break;
+ }
+
+ *pfound = true;
+
+ if (file_name[0] == '/' || directory_name == NULL)
+ *pfilename = file_name;
+ else
+ {
+ size_t dirlen;
+
+ dirlen = strlen (directory_name);
+ if (info->filename == NULL
+ || strncmp (info->filename, directory_name, dirlen) != 0
+ || strcmp (info->filename + dirlen, file_name) != 0)
+ {
+ if (info->filename != NULL)
+ free (info->filename);
+ info->filename = (char *) bfd_malloc (dirlen +
+ strlen (file_name)
+ + 1);
+ if (info->filename == NULL)
+ return false;
+ strcpy (info->filename, directory_name);
+ strcpy (info->filename + dirlen, file_name);
+ }
+
+ *pfilename = info->filename;
+ }
+
+ if (indexentry->function_name != NULL)
+ {
+ char *s;
+
+ /* This will typically be something like main:F(0,1), so we want
+ to clobber the colon. It's OK to change the name, since the
+ string is in our own local storage anyhow. */
+
+ s = strchr (indexentry->function_name, ':');
+ if (s != NULL)
+ *s = '\0';
+
+ *pfnname = indexentry->function_name;
+ }
+
+ return true;
+}
diff --git a/bfd/sysdep.h b/bfd/sysdep.h
new file mode 100644
index 00000000000..0a58983fa2d
--- /dev/null
+++ b/bfd/sysdep.h
@@ -0,0 +1,144 @@
+/* sysdep.h -- handle host dependencies for the BFD library
+ Copyright 1995, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef BFD_SYSDEP_H
+#define BFD_SYSDEP_H
+
+#include "ansidecl.h"
+
+#include "config.h"
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#if !(defined(errno) || defined(_MSC_VER) && defined(_INC_ERRNO))
+extern int errno;
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#else
+extern char *strchr ();
+extern char *strrchr ();
+#endif
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef USE_BINARY_FOPEN
+#include "fopen-bin.h"
+#else
+#include "fopen-same.h"
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY 1
+#endif
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifdef NEED_DECLARATION_STRSTR
+extern char *strstr ();
+#endif
+
+#ifdef NEED_DECLARATION_MALLOC
+extern PTR malloc ();
+#endif
+
+#ifdef NEED_DECLARATION_REALLOC
+extern PTR realloc ();
+#endif
+
+#ifdef NEED_DECLARATION_FREE
+extern void free ();
+#endif
+
+#ifdef NEED_DECLARATION_GETENV
+extern char *getenv ();
+#endif
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#define _(String) dgettext (PACKAGE, String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop (String)
+#else
+#define N_(String) (String)
+#endif
+#else
+/* Stubs that do something close enough. */
+#define textdomain(String) (String)
+#define gettext(String) (String)
+#define dgettext(Domain,Message) (Message)
+#define dcgettext(Domain,Message,Type) (Message)
+#define bindtextdomain(Domain,Directory) (Domain)
+#define _(String) (String)
+#define N_(String) (String)
+#endif
+
+#endif /* ! defined (BFD_SYSDEP_H) */
diff --git a/bfd/targets.c b/bfd/targets.c
new file mode 100644
index 00000000000..bb6e51d854e
--- /dev/null
+++ b/bfd/targets.c
@@ -0,0 +1,1079 @@
+/* Generic target-file-type support for the BFD library.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "fnmatch.h"
+
+/*
+SECTION
+ Targets
+
+DESCRIPTION
+ Each port of BFD to a different machine requries the creation
+ of a target back end. All the back end provides to the root
+ part of BFD is a structure containing pointers to functions
+ which perform certain low level operations on files. BFD
+ translates the applications's requests through a pointer into
+ calls to the back end routines.
+
+ When a file is opened with <<bfd_openr>>, its format and
+ target are unknown. BFD uses various mechanisms to determine
+ how to interpret the file. The operations performed are:
+
+ o Create a BFD by calling the internal routine
+ <<_bfd_new_bfd>>, then call <<bfd_find_target>> with the
+ target string supplied to <<bfd_openr>> and the new BFD pointer.
+
+ o If a null target string was provided to <<bfd_find_target>>,
+ look up the environment variable <<GNUTARGET>> and use
+ that as the target string.
+
+ o If the target string is still <<NULL>>, or the target string is
+ <<default>>, then use the first item in the target vector
+ as the target type, and set <<target_defaulted>> in the BFD to
+ cause <<bfd_check_format>> to loop through all the targets.
+ @xref{bfd_target}. @xref{Formats}.
+
+ o Otherwise, inspect the elements in the target vector
+ one by one, until a match on target name is found. When found,
+ use it.
+
+ o Otherwise return the error <<bfd_error_invalid_target>> to
+ <<bfd_openr>>.
+
+ o <<bfd_openr>> attempts to open the file using
+ <<bfd_open_file>>, and returns the BFD.
+
+ Once the BFD has been opened and the target selected, the file
+ format may be determined. This is done by calling
+ <<bfd_check_format>> on the BFD with a suggested format.
+ If <<target_defaulted>> has been set, each possible target
+ type is tried to see if it recognizes the specified format.
+ <<bfd_check_format>> returns <<true>> when the caller guesses right.
+@menu
+@* bfd_target::
+@end menu
+*/
+
+
+/*
+
+INODE
+ bfd_target, , Targets, Targets
+DOCDD
+SUBSECTION
+ bfd_target
+
+DESCRIPTION
+ This structure contains everything that BFD knows about a
+ target. It includes things like its byte order, name, and which
+ routines to call to do various operations.
+
+ Every BFD points to a target structure with its <<xvec>>
+ member.
+
+ The macros below are used to dispatch to functions through the
+ <<bfd_target>> vector. They are used in a number of macros further
+ down in @file{bfd.h}, and are also used when calling various
+ routines by hand inside the BFD implementation. The @var{arglist}
+ argument must be parenthesized; it contains all the arguments
+ to the called function.
+
+ They make the documentation (more) unpleasant to read, so if
+ someone wants to fix this and not break the above, please do.
+
+.#define BFD_SEND(bfd, message, arglist) \
+. ((*((bfd)->xvec->message)) arglist)
+.
+.#ifdef DEBUG_BFD_SEND
+.#undef BFD_SEND
+.#define BFD_SEND(bfd, message, arglist) \
+. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+. ((*((bfd)->xvec->message)) arglist) : \
+. (bfd_assert (__FILE__,__LINE__), NULL))
+.#endif
+
+ For operations which index on the BFD format:
+
+.#define BFD_SEND_FMT(bfd, message, arglist) \
+. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+.
+.#ifdef DEBUG_BFD_SEND
+.#undef BFD_SEND_FMT
+.#define BFD_SEND_FMT(bfd, message, arglist) \
+. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \
+. (bfd_assert (__FILE__,__LINE__), NULL))
+.#endif
+
+ This is the structure which defines the type of BFD this is. The
+ <<xvec>> member of the struct <<bfd>> itself points here. Each
+ module that implements access to a different target under BFD,
+ defines one of these.
+
+
+ FIXME, these names should be rationalised with the names of
+ the entry points which call them. Too bad we can't have one
+ macro to define them both!
+
+.enum bfd_flavour {
+. bfd_target_unknown_flavour,
+. bfd_target_aout_flavour,
+. bfd_target_coff_flavour,
+. bfd_target_ecoff_flavour,
+. bfd_target_elf_flavour,
+. bfd_target_ieee_flavour,
+. bfd_target_nlm_flavour,
+. bfd_target_oasys_flavour,
+. bfd_target_tekhex_flavour,
+. bfd_target_srec_flavour,
+. bfd_target_ihex_flavour,
+. bfd_target_som_flavour,
+. bfd_target_os9k_flavour,
+. bfd_target_versados_flavour,
+. bfd_target_msdos_flavour,
+. bfd_target_ovax_flavour,
+. bfd_target_evax_flavour
+.};
+.
+.enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+.
+.{* Forward declaration. *}
+.typedef struct bfd_link_info _bfd_link_info;
+.
+.typedef struct bfd_target
+.{
+
+Identifies the kind of target, e.g., SunOS4, Ultrix, etc.
+
+. char *name;
+
+The "flavour" of a back end is a general indication about the contents
+of a file.
+
+. enum bfd_flavour flavour;
+
+The order of bytes within the data area of a file.
+
+. enum bfd_endian byteorder;
+
+The order of bytes within the header parts of a file.
+
+. enum bfd_endian header_byteorder;
+
+A mask of all the flags which an executable may have set -
+from the set <<BFD_NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>.
+
+. flagword object_flags;
+
+A mask of all the flags which a section may have set - from
+the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>.
+
+. flagword section_flags;
+
+The character normally found at the front of a symbol
+(if any), perhaps `_'.
+
+. char symbol_leading_char;
+
+The pad character for file names within an archive header.
+
+. char ar_pad_char;
+
+The maximum number of characters in an archive header.
+
+. unsigned short ar_max_namelen;
+
+Entries for byte swapping for data. These are different from the other
+entry points, since they don't take a BFD asthe first argument.
+Certain other handlers could do the same.
+
+. bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *));
+. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *));
+. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
+. bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *));
+. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *));
+. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
+. bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *));
+. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *));
+. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
+
+Byte swapping for the headers
+
+. bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *));
+. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *));
+. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
+. bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *));
+. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *));
+. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
+. bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *));
+. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *));
+. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
+
+Format dependent routines: these are vectors of entry points
+within the target vector structure, one for each format to check.
+
+Check the format of a file being read. Return a <<bfd_target *>> or zero.
+
+. const struct bfd_target *(*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
+
+Set the format of a file being written.
+
+. boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
+
+Write cached information into a file being written, at <<bfd_close>>.
+
+. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
+
+The general target vector.
+
+.
+. {* Generic entry points. *}
+.#define BFD_JUMP_TABLE_GENERIC(NAME)\
+.CAT(NAME,_close_and_cleanup),\
+.CAT(NAME,_bfd_free_cached_info),\
+.CAT(NAME,_new_section_hook),\
+.CAT(NAME,_get_section_contents),\
+.CAT(NAME,_get_section_contents_in_window)
+.
+. {* Called when the BFD is being closed to do any necessary cleanup. *}
+. boolean (*_close_and_cleanup) PARAMS ((bfd *));
+. {* Ask the BFD to free all cached information. *}
+. boolean (*_bfd_free_cached_info) PARAMS ((bfd *));
+. {* Called when a new section is created. *}
+. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
+. {* Read the contents of a section. *}
+. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
+. file_ptr, bfd_size_type));
+. boolean (*_bfd_get_section_contents_in_window)
+. PARAMS ((bfd *, sec_ptr, bfd_window *,
+. file_ptr, bfd_size_type));
+.
+. {* Entry points to copy private data. *}
+.#define BFD_JUMP_TABLE_COPY(NAME)\
+.CAT(NAME,_bfd_copy_private_bfd_data),\
+.CAT(NAME,_bfd_merge_private_bfd_data),\
+.CAT(NAME,_bfd_copy_private_section_data),\
+.CAT(NAME,_bfd_copy_private_symbol_data),\
+.CAT(NAME,_bfd_set_private_flags),\
+.CAT(NAME,_bfd_print_private_bfd_data)\
+. {* Called to copy BFD general private data from one object file
+. to another. *}
+. boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *));
+. {* Called to merge BFD general private data from one object file
+. to a common output file when linking. *}
+. boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *));
+. {* Called to copy BFD private section data from one object file
+. to another. *}
+. boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr,
+. bfd *, sec_ptr));
+. {* Called to copy BFD private symbol data from one symbol
+. to another. *}
+. boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *,
+. bfd *, asymbol *));
+. {* Called to set private backend flags *}
+. boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword));
+.
+. {* Called to print private BFD data *}
+. boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR));
+.
+. {* Core file entry points. *}
+.#define BFD_JUMP_TABLE_CORE(NAME)\
+.CAT(NAME,_core_file_failing_command),\
+.CAT(NAME,_core_file_failing_signal),\
+.CAT(NAME,_core_file_matches_executable_p)
+. char * (*_core_file_failing_command) PARAMS ((bfd *));
+. int (*_core_file_failing_signal) PARAMS ((bfd *));
+. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
+.
+. {* Archive entry points. *}
+.#define BFD_JUMP_TABLE_ARCHIVE(NAME)\
+.CAT(NAME,_slurp_armap),\
+.CAT(NAME,_slurp_extended_name_table),\
+.CAT(NAME,_construct_extended_name_table),\
+.CAT(NAME,_truncate_arname),\
+.CAT(NAME,_write_armap),\
+.CAT(NAME,_read_ar_hdr),\
+.CAT(NAME,_openr_next_archived_file),\
+.CAT(NAME,_get_elt_at_index),\
+.CAT(NAME,_generic_stat_arch_elt),\
+.CAT(NAME,_update_armap_timestamp)
+. boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
+. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
+. boolean (*_bfd_construct_extended_name_table)
+. PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+. void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *));
+. boolean (*write_armap) PARAMS ((bfd *arch,
+. unsigned int elength,
+. struct orl *map,
+. unsigned int orl_count,
+. int stridx));
+. PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *));
+. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
+.#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i))
+. bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex));
+. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
+. boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *));
+.
+. {* Entry points used for symbols. *}
+.#define BFD_JUMP_TABLE_SYMBOLS(NAME)\
+.CAT(NAME,_get_symtab_upper_bound),\
+.CAT(NAME,_get_symtab),\
+.CAT(NAME,_make_empty_symbol),\
+.CAT(NAME,_print_symbol),\
+.CAT(NAME,_get_symbol_info),\
+.CAT(NAME,_bfd_is_local_label_name),\
+.CAT(NAME,_get_lineno),\
+.CAT(NAME,_find_nearest_line),\
+.CAT(NAME,_bfd_make_debug_symbol),\
+.CAT(NAME,_read_minisymbols),\
+.CAT(NAME,_minisymbol_to_symbol)
+. long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *));
+. long (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
+. struct symbol_cache_entry **));
+. struct symbol_cache_entry *
+. (*_bfd_make_empty_symbol) PARAMS ((bfd *));
+. void (*_bfd_print_symbol) PARAMS ((bfd *, PTR,
+. struct symbol_cache_entry *,
+. bfd_print_symbol_type));
+.#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+. void (*_bfd_get_symbol_info) PARAMS ((bfd *,
+. struct symbol_cache_entry *,
+. symbol_info *));
+.#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e))
+. boolean (*_bfd_is_local_label_name) PARAMS ((bfd *, const char *));
+.
+. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
+. boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd,
+. struct sec *section, struct symbol_cache_entry **symbols,
+. bfd_vma offset, CONST char **file, CONST char **func,
+. unsigned int *line));
+. {* Back-door to allow format-aware applications to create debug symbols
+. while using BFD for everything else. Currently used by the assembler
+. when creating COFF files. *}
+. asymbol * (*_bfd_make_debug_symbol) PARAMS ((
+. bfd *abfd,
+. void *ptr,
+. unsigned long size));
+.#define bfd_read_minisymbols(b, d, m, s) \
+. BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+. long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *,
+. unsigned int *));
+.#define bfd_minisymbol_to_symbol(b, d, m, f) \
+. BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f))
+. asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR,
+. asymbol *));
+.
+. {* Routines for relocs. *}
+.#define BFD_JUMP_TABLE_RELOCS(NAME)\
+.CAT(NAME,_get_reloc_upper_bound),\
+.CAT(NAME,_canonicalize_reloc),\
+.CAT(NAME,_bfd_reloc_type_lookup)
+. long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
+. long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **,
+. struct symbol_cache_entry **));
+. {* See documentation on reloc types. *}
+. reloc_howto_type *
+. (*reloc_type_lookup) PARAMS ((bfd *abfd,
+. bfd_reloc_code_real_type code));
+.
+. {* Routines used when writing an object file. *}
+.#define BFD_JUMP_TABLE_WRITE(NAME)\
+.CAT(NAME,_set_arch_mach),\
+.CAT(NAME,_set_section_contents)
+. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture,
+. unsigned long));
+. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
+. file_ptr, bfd_size_type));
+.
+. {* Routines used by the linker. *}
+.#define BFD_JUMP_TABLE_LINK(NAME)\
+.CAT(NAME,_sizeof_headers),\
+.CAT(NAME,_bfd_get_relocated_section_contents),\
+.CAT(NAME,_bfd_relax_section),\
+.CAT(NAME,_bfd_link_hash_table_create),\
+.CAT(NAME,_bfd_link_add_symbols),\
+.CAT(NAME,_bfd_final_link),\
+.CAT(NAME,_bfd_link_split_section),\
+.CAT(NAME,_bfd_gc_sections)
+. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
+. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
+. struct bfd_link_info *, struct bfd_link_order *,
+. bfd_byte *data, boolean relocateable,
+. struct symbol_cache_entry **));
+.
+. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
+. struct bfd_link_info *, boolean *again));
+.
+. {* Create a hash table for the linker. Different backends store
+. different information in this table. *}
+. struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *));
+.
+. {* Add symbols from this object file into the hash table. *}
+. boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+.
+. {* Do a link based on the link_order structures attached to each
+. section of the BFD. *}
+. boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
+.
+. {* Should this section be split up into smaller pieces during linking. *}
+. boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *));
+.
+. {* Remove sections that are not referenced from the output. *}
+. boolean (*_bfd_gc_sections) PARAMS ((bfd *, struct bfd_link_info *));
+.
+. {* Routines to handle dynamic symbols and relocs. *}
+.#define BFD_JUMP_TABLE_DYNAMIC(NAME)\
+.CAT(NAME,_get_dynamic_symtab_upper_bound),\
+.CAT(NAME,_canonicalize_dynamic_symtab),\
+.CAT(NAME,_get_dynamic_reloc_upper_bound),\
+.CAT(NAME,_canonicalize_dynamic_reloc)
+. {* Get the amount of memory required to hold the dynamic symbols. *}
+. long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *));
+. {* Read in the dynamic symbols. *}
+. long (*_bfd_canonicalize_dynamic_symtab)
+. PARAMS ((bfd *, struct symbol_cache_entry **));
+. {* Get the amount of memory required to hold the dynamic relocs. *}
+. long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *));
+. {* Read in the dynamic relocs. *}
+. long (*_bfd_canonicalize_dynamic_reloc)
+. PARAMS ((bfd *, arelent **, struct symbol_cache_entry **));
+.
+
+Data for use by back-end routines, which isn't generic enough to belong
+in this structure.
+
+. PTR backend_data;
+.} bfd_target;
+
+*/
+
+/* All known xvecs (even those that don't compile on all systems).
+ Alphabetized for easy reference.
+ They are listed a second time below, since
+ we can't intermix extern's and initializers. */
+extern const bfd_target a29kcoff_big_vec;
+extern const bfd_target a_out_adobe_vec;
+extern const bfd_target aout_arm_big_vec;
+extern const bfd_target aout_arm_little_vec;
+extern const bfd_target aout_mips_big_vec;
+extern const bfd_target aout_mips_little_vec;
+extern const bfd_target aout0_big_vec;
+extern const bfd_target apollocoff_vec;
+extern const bfd_target armcoff_little_vec;
+extern const bfd_target armcoff_big_vec;
+extern const bfd_target armpe_little_vec;
+extern const bfd_target armpe_big_vec;
+extern const bfd_target armpei_little_vec;
+extern const bfd_target armpei_big_vec;
+extern const bfd_target arm_epoc_pe_little_vec;
+extern const bfd_target arm_epoc_pe_big_vec;
+extern const bfd_target arm_epoc_pei_little_vec;
+extern const bfd_target arm_epoc_pei_big_vec;
+extern const bfd_target b_out_vec_big_host;
+extern const bfd_target b_out_vec_little_host;
+extern const bfd_target bfd_elf64_alpha_vec;
+extern const bfd_target bfd_elf32_bigarc_vec;
+extern const bfd_target bfd_elf32_bigarm_vec;
+extern const bfd_target bfd_elf32_bigarm_oabi_vec;
+extern const bfd_target bfd_elf32_littlearc_vec;
+extern const bfd_target bfd_elf32_littlearm_vec;
+extern const bfd_target bfd_elf32_littlearm_oabi_vec;
+extern const bfd_target bfd_elf32_big_generic_vec;
+extern const bfd_target bfd_elf32_bigmips_vec;
+extern const bfd_target bfd_elf64_bigmips_vec;
+extern const bfd_target bfd_elf32_d10v_vec;
+extern const bfd_target bfd_elf32_d30v_vec;
+extern const bfd_target bfd_elf32_hppa_vec;
+extern const bfd_target bfd_elf32_i386_vec;
+extern const bfd_target bfd_elf32_i860_vec;
+extern const bfd_target bfd_elf32_little_generic_vec;
+extern const bfd_target bfd_elf32_littlemips_vec;
+extern const bfd_target bfd_elf64_littlemips_vec;
+extern const bfd_target bfd_elf32_m32r_vec;
+extern const bfd_target bfd_elf32_m68k_vec;
+extern const bfd_target bfd_elf32_m88k_vec;
+extern const bfd_target bfd_elf32_mn10200_vec;
+extern const bfd_target bfd_elf32_mn10300_vec;
+extern const bfd_target bfd_elf32_powerpc_vec;
+extern const bfd_target bfd_elf32_powerpcle_vec;
+extern const bfd_target bfd_elf32_sh_vec;
+extern const bfd_target bfd_elf32_shl_vec;
+extern const bfd_target bfd_elf32_sparc_vec;
+extern const bfd_target bfd_elf32_v850_vec;
+extern const bfd_target bfd_elf32_fr30_vec;
+extern const bfd_target bfd_elf32_mcore_big_vec;
+extern const bfd_target bfd_elf32_mcore_little_vec;
+extern const bfd_target bfd_elf64_big_generic_vec;
+extern const bfd_target bfd_elf64_little_generic_vec;
+extern const bfd_target bfd_elf64_sparc_vec;
+extern const bfd_target demo_64_vec;
+extern const bfd_target ecoff_big_vec;
+extern const bfd_target ecoff_little_vec;
+extern const bfd_target ecoff_biglittle_vec;
+extern const bfd_target ecoffalpha_little_vec;
+extern const bfd_target h8300coff_vec;
+extern const bfd_target h8500coff_vec;
+extern const bfd_target host_aout_vec;
+extern const bfd_target hp300bsd_vec;
+extern const bfd_target hp300hpux_vec;
+extern const bfd_target som_vec;
+extern const bfd_target i386aout_vec;
+extern const bfd_target i386bsd_vec;
+extern const bfd_target i386dynix_vec;
+extern const bfd_target i386freebsd_vec;
+extern const bfd_target i386os9k_vec;
+extern const bfd_target i386coff_vec;
+extern const bfd_target bfd_powerpc_pe_vec;
+extern const bfd_target bfd_powerpcle_pe_vec;
+extern const bfd_target bfd_powerpc_pei_vec;
+extern const bfd_target bfd_powerpcle_pei_vec;
+extern const bfd_target i386pe_vec;
+extern const bfd_target i386pei_vec;
+extern const bfd_target go32coff_vec;
+extern const bfd_target go32stubbedcoff_vec;
+extern const bfd_target i386linux_vec;
+extern const bfd_target i386lynx_aout_vec;
+extern const bfd_target i386lynx_coff_vec;
+extern const bfd_target i386mach3_vec;
+extern const bfd_target i386msdos_vec;
+extern const bfd_target i386netbsd_vec;
+extern const bfd_target i860coff_vec;
+extern const bfd_target icoff_big_vec;
+extern const bfd_target icoff_little_vec;
+extern const bfd_target ieee_vec;
+extern const bfd_target m68kaux_coff_vec;
+extern const bfd_target m68kcoff_vec;
+extern const bfd_target m68kcoffun_vec;
+extern const bfd_target m68klinux_vec;
+extern const bfd_target m68klynx_aout_vec;
+extern const bfd_target m68klynx_coff_vec;
+extern const bfd_target m68knetbsd_vec;
+extern const bfd_target m68ksysvcoff_vec;
+extern const bfd_target m68k4knetbsd_vec;
+extern const bfd_target m88kbcs_vec;
+extern const bfd_target m88kmach3_vec;
+extern const bfd_target mcore_pe_big_vec;
+extern const bfd_target mcore_pe_little_vec;
+extern const bfd_target mcore_pei_big_vec;
+extern const bfd_target mcore_pei_little_vec;
+extern const bfd_target newsos3_vec;
+extern const bfd_target nlm32_i386_vec;
+extern const bfd_target nlm32_sparc_vec;
+extern const bfd_target nlm32_alpha_vec;
+extern const bfd_target nlm32_powerpc_vec;
+extern const bfd_target pc532netbsd_vec;
+extern const bfd_target oasys_vec;
+extern const bfd_target pc532machaout_vec;
+extern const bfd_target ppcboot_vec;
+extern const bfd_target riscix_vec;
+extern const bfd_target pmac_xcoff_vec;
+extern const bfd_target rs6000coff_vec;
+extern const bfd_target shcoff_vec;
+extern const bfd_target shlcoff_vec;
+extern const bfd_target shcoff_small_vec;
+extern const bfd_target shlcoff_small_vec;
+extern const bfd_target sparcle_aout_vec;
+extern const bfd_target sparclinux_vec;
+extern const bfd_target sparclynx_aout_vec;
+extern const bfd_target sparclynx_coff_vec;
+extern const bfd_target sparcnetbsd_vec;
+extern const bfd_target sparccoff_vec;
+extern const bfd_target sunos_big_vec;
+extern const bfd_target tekhex_vec;
+extern const bfd_target tic30_aout_vec;
+extern const bfd_target tic30_coff_vec;
+extern const bfd_target tic80coff_vec;
+extern const bfd_target vaxnetbsd_vec;
+extern const bfd_target versados_vec;
+extern const bfd_target vms_alpha_vec;
+extern const bfd_target vms_vax_vec;
+extern const bfd_target we32kcoff_vec;
+extern const bfd_target w65_vec;
+extern const bfd_target z8kcoff_vec;
+
+/* srec is always included. */
+extern const bfd_target srec_vec;
+extern const bfd_target symbolsrec_vec;
+
+/* binary is always included. */
+extern const bfd_target binary_vec;
+
+/* ihex is always included. */
+extern const bfd_target ihex_vec;
+
+/* All of the xvecs for core files. */
+extern const bfd_target aix386_core_vec;
+extern const bfd_target cisco_core_vec;
+extern const bfd_target hpux_core_vec;
+extern const bfd_target hppabsd_core_vec;
+extern const bfd_target irix_core_vec;
+extern const bfd_target netbsd_core_vec;
+extern const bfd_target osf_core_vec;
+extern const bfd_target sco5_core_vec;
+extern const bfd_target trad_core_vec;
+extern const bfd_target ptrace_core_vec;
+
+const bfd_target * const bfd_target_vector[] = {
+
+#ifdef SELECT_VECS
+
+ SELECT_VECS,
+
+#else /* not SELECT_VECS */
+
+#ifdef DEFAULT_VECTOR
+ &DEFAULT_VECTOR,
+#endif
+ /* This list is alphabetized to make it easy to compare
+ with other vector lists -- the decls above and
+ the case statement in configure.in.
+ Vectors that don't compile on all systems, or aren't finished,
+ should have an entry here with #if 0 around it, to show that
+ it wasn't omitted by mistake. */
+ &a29kcoff_big_vec,
+ &a_out_adobe_vec,
+#if 0 /* No one seems to use this. */
+ &aout_mips_big_vec,
+#endif
+ &aout_mips_little_vec,
+ &b_out_vec_big_host,
+ &b_out_vec_little_host,
+
+ /* This, and other vectors, may not be used in any *.mt configuration.
+ But that does not mean they are unnecessary. If configured with
+ --enable-targets=all, objdump or gdb should be able to examine
+ the file even if we don't recognize the machine type. */
+ &bfd_elf32_big_generic_vec,
+#ifdef BFD64
+ &bfd_elf64_alpha_vec,
+#endif
+ &bfd_elf32_bigarc_vec,
+ &bfd_elf32_bigarm_vec,
+ &bfd_elf32_bigarm_oabi_vec,
+ &bfd_elf32_bigmips_vec,
+#ifdef BFD64
+ &bfd_elf64_bigmips_vec,
+#endif
+ &bfd_elf32_d10v_vec,
+ &bfd_elf32_d30v_vec,
+ &bfd_elf32_hppa_vec,
+ &bfd_elf32_i386_vec,
+ &bfd_elf32_i860_vec,
+ &bfd_elf32_little_generic_vec,
+ &bfd_elf32_littlearc_vec,
+ &bfd_elf32_littlearm_vec,
+ &bfd_elf32_littlearm_oabi_vec,
+ &bfd_elf32_littlemips_vec,
+#ifdef BFD64
+ &bfd_elf64_littlemips_vec,
+#endif
+ &bfd_elf32_m32r_vec,
+ &bfd_elf32_mn10200_vec,
+ &bfd_elf32_mn10300_vec,
+ &bfd_elf32_m68k_vec,
+ &bfd_elf32_m88k_vec,
+ &bfd_elf32_sparc_vec,
+ &bfd_elf32_powerpc_vec,
+ &bfd_elf32_powerpcle_vec,
+ &bfd_elf32_v850_vec,
+ &bfd_elf32_fr30_vec,
+ &bfd_elf32_mcore_big_vec,
+ &bfd_elf32_mcore_little_vec,
+#ifdef BFD64 /* No one seems to use this. */
+ &bfd_elf64_big_generic_vec,
+ &bfd_elf64_little_generic_vec,
+#endif
+#if 0
+ &bfd_elf64_sparc_vec,
+#endif
+ /* We don't include cisco_core_vec. Although it has a magic number,
+ the magic number isn't at the beginning of the file, and thus
+ might spuriously match other kinds of files. */
+#ifdef BFD64
+ &demo_64_vec, /* Only compiled if host has long-long support */
+#endif
+ &ecoff_big_vec,
+ &ecoff_little_vec,
+ &ecoff_biglittle_vec,
+#ifdef BFD64
+ &ecoffalpha_little_vec,
+#endif
+ &h8300coff_vec,
+ &h8500coff_vec,
+#if 0
+ /* Since a.out files lack decent magic numbers, no way to recognize
+ which kind of a.out file it is. */
+ &host_aout_vec,
+#endif
+#if 0 /* Clashes with sunos_big_vec magic no. */
+ &hp300bsd_vec,
+#endif
+ &hp300hpux_vec,
+#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF)
+ &som_vec,
+#endif
+ &i386aout_vec,
+ &i386bsd_vec,
+ &i386coff_vec,
+ &i386freebsd_vec,
+ &i860coff_vec,
+ &bfd_powerpc_pe_vec,
+ &bfd_powerpcle_pe_vec,
+ &bfd_powerpc_pei_vec,
+ &bfd_powerpcle_pei_vec,
+ &go32coff_vec,
+ &go32stubbedcoff_vec,
+#if 0
+ /* Since a.out files lack decent magic numbers, no way to recognize
+ which kind of a.out file it is. */
+ &i386linux_vec,
+#endif
+ &i386lynx_aout_vec,
+ &i386lynx_coff_vec,
+#if 0
+ /* No distinguishing features for Mach 3 executables. */
+ &i386mach3_vec,
+#endif
+ &i386msdos_vec,
+ &i386netbsd_vec,
+ &i386os9k_vec,
+ &i386pe_vec,
+ &i386pei_vec,
+ &armcoff_little_vec,
+ &armcoff_big_vec,
+ &armpe_little_vec,
+ &armpe_big_vec,
+ &armpei_little_vec,
+ &armpei_big_vec,
+ &arm_epoc_pe_little_vec,
+ &arm_epoc_pe_big_vec,
+ &arm_epoc_pei_little_vec,
+ &arm_epoc_pei_big_vec,
+ &icoff_big_vec,
+ &icoff_little_vec,
+ &ieee_vec,
+ &m68kcoff_vec,
+ &m68kcoffun_vec,
+#if 0
+ /* Since a.out files lack decent magic numbers, no way to recognize
+ which kind of a.out file it is. */
+ &m68klinux_vec,
+#endif
+ &m68klynx_aout_vec,
+ &m68klynx_coff_vec,
+ &m68knetbsd_vec,
+ &m68ksysvcoff_vec,
+ &m88kbcs_vec,
+ &m88kmach3_vec,
+ &mcore_pe_big_vec,
+ &mcore_pe_little_vec,
+ &mcore_pei_big_vec,
+ &mcore_pei_little_vec,
+ &newsos3_vec,
+ &nlm32_i386_vec,
+ &nlm32_sparc_vec,
+#ifdef BFD64
+ &nlm32_alpha_vec,
+#endif
+ &pc532netbsd_vec,
+#if 0
+ /* We have no oasys tools anymore, so we can't test any of this
+ anymore. If you want to test the stuff yourself, go ahead...
+ steve@cygnus.com
+ Worse, since there is no magic number for archives, there
+ can be annoying target mis-matches. */
+ &oasys_vec,
+#endif
+ &pc532machaout_vec,
+#if 0
+ /* We have no way of distinguishing these from other a.out variants */
+ &aout_arm_big_vec,
+ &aout_arm_little_vec,
+ &riscix_vec,
+#endif
+#if 0
+ /* This has the same magic number as RS/6000. */
+ &pmac_xcoff_vec,
+#endif
+ &rs6000coff_vec,
+ &ppcboot_vec,
+ &shcoff_vec,
+ &shlcoff_vec,
+ &shcoff_small_vec,
+ &shlcoff_small_vec,
+ &sparcle_aout_vec,
+ &sparclinux_vec,
+ &sparclynx_aout_vec,
+ &sparclynx_coff_vec,
+ &sparcnetbsd_vec,
+ &sunos_big_vec,
+ &aout0_big_vec,
+ &tic30_aout_vec,
+ &tic30_coff_vec,
+ &tic80coff_vec,
+ &vaxnetbsd_vec,
+ &versados_vec,
+#ifdef BFD64
+ &vms_alpha_vec,
+#endif
+ &vms_vax_vec,
+ &we32kcoff_vec,
+ &z8kcoff_vec,
+
+#endif /* not SELECT_VECS */
+
+/* Always support S-records, for convenience. */
+ &srec_vec,
+ &symbolsrec_vec,
+/* And tekhex */
+ &tekhex_vec,
+/* Likewise for binary output. */
+ &binary_vec,
+/* Likewise for ihex. */
+ &ihex_vec,
+
+/* Add any required traditional-core-file-handler. */
+
+#ifdef AIX386_CORE
+ &aix386_core_vec,
+#endif
+#ifdef HPUX_CORE
+ &hpux_core_vec,
+#endif
+#ifdef HPPABSD_CORE
+ &hppabsd_core_vec,
+#endif
+#ifdef IRIX_CORE
+ &irix_core_vec,
+#endif
+#ifdef NETBSD_CORE
+ &netbsd_core_vec,
+#endif
+#ifdef OSF_CORE
+ &osf_core_vec,
+#endif
+#ifdef SCO5_CORE
+ &sco5_core_vec,
+#endif
+#ifdef TRAD_CORE
+ &trad_core_vec,
+#endif
+
+#ifdef PTRACE_CORE
+ &ptrace_core_vec,
+#endif
+
+ NULL /* end of list marker */
+};
+
+/* bfd_default_vector[0] contains either the address of the default vector,
+ if there is one, or zero if there isn't. */
+
+const bfd_target *bfd_default_vector[] = {
+#ifdef DEFAULT_VECTOR
+ &DEFAULT_VECTOR,
+#endif
+ NULL
+};
+
+/* When there is an ambiguous match, bfd_check_format_matches puts the
+ names of the matching targets in an array. This variable is the maximum
+ number of entries that the array could possibly need. */
+const size_t _bfd_target_vector_entries = sizeof(bfd_target_vector)/sizeof(*bfd_target_vector);
+
+/* This array maps configuration triplets onto BFD vectors. */
+
+struct targmatch
+{
+ /* The configuration triplet. */
+ const char *triplet;
+ /* The BFD vector. If this is NULL, then the vector is found by
+ searching forward for the next structure with a non NULL vector
+ field. */
+ const bfd_target *vector;
+};
+
+/* targmatch.h is built by Makefile out of config.bfd. */
+static const struct targmatch bfd_target_match[] = {
+#include "targmatch.h"
+ { NULL, NULL }
+};
+
+static const bfd_target *find_target PARAMS ((const char *));
+
+/* Find a target vector, given a name or configuration triplet. */
+
+static const bfd_target *
+find_target (name)
+ const char *name;
+{
+ const bfd_target * const *target;
+ const struct targmatch *match;
+
+ for (target = &bfd_target_vector[0]; *target != NULL; target++)
+ if (strcmp (name, (*target)->name) == 0)
+ return *target;
+
+ /* If we couldn't match on the exact name, try matching on the
+ configuration triplet. FIXME: We should run the triplet through
+ config.sub first, but that is hard. */
+ for (match = &bfd_target_match[0]; match->triplet != NULL; match++)
+ {
+ if (fnmatch (match->triplet, name, 0) == 0)
+ {
+ while (match->vector == NULL)
+ ++match;
+ return match->vector;
+ break;
+ }
+ }
+
+ bfd_set_error (bfd_error_invalid_target);
+ return NULL;
+}
+
+/*
+FUNCTION
+ bfd_set_default_target
+
+SYNOPSIS
+ boolean bfd_set_default_target (const char *name);
+
+DESCRIPTION
+ Set the default target vector to use when recognizing a BFD.
+ This takes the name of the target, which may be a BFD target
+ name or a configuration triplet.
+*/
+
+boolean
+bfd_set_default_target (name)
+ const char *name;
+{
+ const bfd_target *target;
+
+ if (bfd_default_vector[0] != NULL
+ && strcmp (name, bfd_default_vector[0]->name) == 0)
+ return true;
+
+ target = find_target (name);
+ if (target == NULL)
+ return false;
+
+ bfd_default_vector[0] = target;
+ return true;
+}
+
+/*
+FUNCTION
+ bfd_find_target
+
+SYNOPSIS
+ const bfd_target *bfd_find_target(CONST char *target_name, bfd *abfd);
+
+DESCRIPTION
+ Return a pointer to the transfer vector for the object target
+ named @var{target_name}. If @var{target_name} is <<NULL>>, choose the
+ one in the environment variable <<GNUTARGET>>; if that is null or not
+ defined, then choose the first entry in the target list.
+ Passing in the string "default" or setting the environment
+ variable to "default" will cause the first entry in the target
+ list to be returned, and "target_defaulted" will be set in the
+ BFD. This causes <<bfd_check_format>> to loop over all the
+ targets to find the one that matches the file being read.
+*/
+
+const bfd_target *
+bfd_find_target (target_name, abfd)
+ const char *target_name;
+ bfd *abfd;
+{
+ const char *targname;
+ const bfd_target *target;
+
+ if (target_name != NULL)
+ targname = target_name;
+ else
+ targname = getenv ("GNUTARGET");
+
+ /* This is safe; the vector cannot be null */
+ if (targname == NULL || strcmp (targname, "default") == 0)
+ {
+ abfd->target_defaulted = true;
+ if (bfd_default_vector[0] != NULL)
+ abfd->xvec = bfd_default_vector[0];
+ else
+ abfd->xvec = bfd_target_vector[0];
+ return abfd->xvec;
+ }
+
+ abfd->target_defaulted = false;
+
+ target = find_target (targname);
+ if (target == NULL)
+ return NULL;
+
+ abfd->xvec = target;
+ return target;
+}
+
+/*
+FUNCTION
+ bfd_target_list
+
+SYNOPSIS
+ const char **bfd_target_list(void);
+
+DESCRIPTION
+ Return a freshly malloced NULL-terminated
+ vector of the names of all the valid BFD targets. Do not
+ modify the names.
+
+*/
+
+const char **
+bfd_target_list ()
+{
+ int vec_length= 0;
+#if defined (HOST_HPPAHPUX) && ! defined (__STDC__)
+ /* The native compiler on the HP9000/700 has a bug which causes it
+ to loop endlessly when compiling this file. This avoids it. */
+ volatile
+#endif
+ const bfd_target * const *target;
+ CONST char **name_list, **name_ptr;
+
+ for (target = &bfd_target_vector[0]; *target != NULL; target++)
+ vec_length++;
+
+ name_ptr = name_list = (CONST char **)
+ bfd_zmalloc ((vec_length + 1) * sizeof (char **));
+
+ if (name_list == NULL)
+ return NULL;
+
+ for (target = &bfd_target_vector[0]; *target != NULL; target++)
+ *(name_ptr++) = (*target)->name;
+
+ return name_list;
+}
diff --git a/bfd/targmatch.sed b/bfd/targmatch.sed
new file mode 100644
index 00000000000..2f40e723f2c
--- /dev/null
+++ b/bfd/targmatch.sed
@@ -0,0 +1,32 @@
+1,/START OF targmatch.h/ d
+/END OF targmatch.h/,$ d
+s/^#if/KEEP #if/
+s/^#endif/KEEP #endif/
+s/^[ ]*#.*$//
+s/^KEEP #/#/
+s/[ ]*\\$//
+t lab1
+ :lab1
+s/[| ][| ]*\([^|() ][^|() ]*\)[ ]*|/{ "\1", NULL },/g
+s/[| ][| ]*\([^|() ][^|() ]*\)[ ]*)/{ "\1",/g
+t lab2
+s/^[ ]*targ_defvec=\([^ ]*\)/#if !defined (SELECT_VECS) || defined (HAVE_\1)/
+t lab3
+s/.*=.*//
+s/;;//
+b
+ :lab2
+H
+d
+ :lab3
+G
+s/\n/%EOL%/g
+s/\(defined (HAVE_\)\([^)]*\)\(.*\)/\1\2\3\
+\&\2 },\
+#endif/
+s/%EOL%/\
+/g
+p
+s/.*//g
+s/\n//g
+h
diff --git a/bfd/tekhex.c b/bfd/tekhex.c
new file mode 100644
index 00000000000..c88fe2dbaf2
--- /dev/null
+++ b/bfd/tekhex.c
@@ -0,0 +1,1065 @@
+/* BFD backend for Extended Tektronix Hex Format objects.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+SUBSECTION
+ Tektronix Hex Format handling
+
+DESCRIPTION
+
+ Tek Hex records can hold symbols and data, but not
+ relocations. Their main application is communication with
+ devices like PROM programmers and ICE equipment.
+
+ It seems that the sections are descibed as being really big,
+ the example I have says that the text section is 0..ffffffff.
+ BFD would barf with this, many apps would try to alloc 4GB to
+ read in the file.
+
+ Tex Hex may contain many sections, but the data which comes in
+ has no tag saying which section it belongs to, so we create
+ one section for each block of data, called "blknnnn" which we
+ stick all the data into.
+
+ TekHex may come out of order and there is no header, so an
+ initial scan is required to discover the minimum and maximum
+ addresses used to create the vma and size of the sections we
+ create.
+ We read in the data into pages of CHUNK_MASK+1 size and read
+ them out from that whenever we need to.
+
+ Any number of sections may be created for output, we save them
+ up and output them when it's time to close the bfd.
+
+
+ A TekHex record looks like:
+EXAMPLE
+ %<block length><type><checksum><stuff><cr>
+
+DESCRIPTION
+ Where
+ o length
+ is the number of bytes in the record not including the % sign.
+ o type
+ is one of:
+ 3) symbol record
+ 6) data record
+ 8) termination record
+
+
+The data can come out of order, and may be discontigous. This is a
+serial protocol, so big files are unlikely, so we keep a list of 8k chunks
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+typedef struct
+ {
+ bfd_vma low;
+ bfd_vma high;
+ } addr_range_type;
+
+typedef struct tekhex_symbol_struct
+ {
+
+ asymbol symbol;
+ struct tekhex_symbol_struct *prev;
+
+ } tekhex_symbol_type;
+
+static const char digs[] = "0123456789ABCDEF";
+
+static char sum_block[256];
+
+#define NOT_HEX 20
+#define NIBBLE(x) hex_value(x)
+#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
+#define TOHEX(d,x) \
+(d)[1] = digs[(x) & 0xf]; \
+(d)[0] = digs[((x)>>4)&0xf];
+#define ISHEX(x) hex_p(x)
+
+static void tekhex_init PARAMS ((void));
+static bfd_vma getvalue PARAMS ((char **));
+static void tekhex_print_symbol
+ PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+static void tekhex_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static asymbol *tekhex_make_empty_symbol PARAMS ((bfd *));
+static int tekhex_sizeof_headers PARAMS ((bfd *, boolean));
+static boolean tekhex_write_object_contents PARAMS ((bfd *));
+static void out PARAMS ((bfd *, int, char *, char *));
+static void writesym PARAMS ((char **, CONST char *));
+static void writevalue PARAMS ((char **, bfd_vma));
+static boolean tekhex_set_section_contents
+ PARAMS ((bfd*, sec_ptr, PTR, file_ptr, bfd_size_type));
+static boolean tekhex_set_arch_mach
+ PARAMS ((bfd *, enum bfd_architecture, unsigned long));
+static boolean tekhex_get_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
+static void move_section_contents
+ PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type, boolean));
+static const bfd_target *tekhex_object_p PARAMS ((bfd *));
+static boolean tekhex_mkobject PARAMS ((bfd *));
+static long tekhex_get_symtab_upper_bound PARAMS ((bfd *));
+static long tekhex_get_symtab PARAMS ((bfd *, asymbol **));
+static void pass_over PARAMS ((bfd *, void (*)(bfd*, int, char *)));
+static void first_phase PARAMS ((bfd *, int, char *));
+static void insert_byte PARAMS ((bfd *, int, bfd_vma));
+static struct data_struct *find_chunk PARAMS ((bfd *, bfd_vma));
+static unsigned int getsym PARAMS ((char *, char **));
+
+/*
+Here's an example
+%3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
+%1B3709T_SEGMENT1108FFFFFFFF
+%2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
+%373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
+%373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
+%373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
+%373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
+%373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
+%373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
+%373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
+%2734D9T_SEGMENT8Bvoid$t15$151035_main10
+%2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
+%2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
+%07 8 10 10
+
+explanation:
+%3A6C6480004E56FFFC4E717063B0AEFFFC6D0652AEFFFC60F24E5E4E75
+ ^ ^^ ^ ^-data
+ | || +------ 4 char integer 0x8000
+ | |+-------- checksum
+ | +--------- type 6 (data record)
+ +----------- length 3a chars
+ <---------------------- 3a (58 chars) ------------------->
+
+%1B3709T_SEGMENT1108FFFFFFFF
+ ^ ^^ ^- 8 character integer 0xffffffff
+ | |+- 1 character integer 0
+ | +-- type 1 symbol (section definition)
+ +------------ 9 char symbol T_SEGMENT
+
+%2B3AB9T_SEGMENT7Dgcc_compiled$1087hello$c10
+%373829T_SEGMENT80int$t1$r1$$214741080char$t2$r2$0$12710
+%373769T_SEGMENT80long$int$t3$r1$$1080unsigned$int$t4$10
+%373CA9T_SEGMENT80long$unsigned$in1080short$int$t6$r1$10
+%373049T_SEGMENT80long$long$int$t71080short$unsigned$i10
+%373A29T_SEGMENT80long$long$unsign1080signed$char$t10$10
+%373D69T_SEGMENT80unsigned$char$t11080float$t12$r1$4$010
+%373D19T_SEGMENT80double$t13$r1$8$1080long$double$t14$10
+%2734D9T_SEGMENT8Bvoid$t15$151035_main10
+%2F3CA9T_SEGMENT81$1081$1681$1E81$21487main$F110
+%2832F9T_SEGMENT83i$18FFFFFFFC81$1481$214
+%0781010
+
+Turns into
+sac@thepub$ ./objdump -dx -m m68k f
+
+f: file format tekhex
+-----x--- 9/55728 -134219416 Sep 29 15:13 1995 f
+architecture: UNKNOWN!, flags 0x00000010:
+HAS_SYMS
+start address 0x00000000
+SECTION 0 [D00000000] : size 00020000 vma 00000000 align 2**0
+ ALLOC, LOAD
+SECTION 1 [D00008000] : size 00002001 vma 00008000 align 2**0
+
+SECTION 2 [T_SEGMENT] : size ffffffff vma 00000000 align 2**0
+
+SYMBOL TABLE:
+00000000 g T_SEGMENT gcc_compiled$
+00000000 g T_SEGMENT hello$c
+00000000 g T_SEGMENT int$t1$r1$$21474
+00000000 g T_SEGMENT char$t2$r2$0$127
+00000000 g T_SEGMENT long$int$t3$r1$$
+00000000 g T_SEGMENT unsigned$int$t4$
+00000000 g T_SEGMENT long$unsigned$in
+00000000 g T_SEGMENT short$int$t6$r1$
+00000000 g T_SEGMENT long$long$int$t7
+00000000 g T_SEGMENT short$unsigned$i
+00000000 g T_SEGMENT long$long$unsign
+00000000 g T_SEGMENT signed$char$t10$
+00000000 g T_SEGMENT unsigned$char$t1
+00000000 g T_SEGMENT float$t12$r1$4$0
+00000000 g T_SEGMENT double$t13$r1$8$
+00000000 g T_SEGMENT long$double$t14$
+00000000 g T_SEGMENT void$t15$15
+00000000 g T_SEGMENT _main
+00000000 g T_SEGMENT $
+00000000 g T_SEGMENT $
+00000000 g T_SEGMENT $
+00000010 g T_SEGMENT $
+00000000 g T_SEGMENT main$F1
+fcffffff g T_SEGMENT i$1
+00000000 g T_SEGMENT $
+00000010 g T_SEGMENT $
+
+
+RELOCATION RECORDS FOR [D00000000]: (none)
+
+RELOCATION RECORDS FOR [D00008000]: (none)
+
+RELOCATION RECORDS FOR [T_SEGMENT]: (none)
+
+Disassembly of section D00000000:
+...
+00008000 ($+)7ff0 linkw fp,#-4
+00008004 ($+)7ff4 nop
+00008006 ($+)7ff6 movel #99,d0
+00008008 ($+)7ff8 cmpl fp@(-4),d0
+0000800c ($+)7ffc blts 00008014 ($+)8004
+0000800e ($+)7ffe addql #1,fp@(-4)
+00008012 ($+)8002 bras 00008006 ($+)7ff6
+00008014 ($+)8004 unlk fp
+00008016 ($+)8006 rts
+...
+
+*/
+
+static void
+tekhex_init ()
+{
+ unsigned int i;
+ static boolean inited = false;
+ int val;
+
+ if (inited == false)
+ {
+ inited = true;
+ hex_init ();
+ val = 0;
+ for (i = 0; i < 10; i++)
+ {
+ sum_block[i + '0'] = val++;
+ }
+ for (i = 'A'; i <= 'Z'; i++)
+ {
+ sum_block[i] = val++;
+ }
+ sum_block['$'] = val++;
+ sum_block['%'] = val++;
+ sum_block['.'] = val++;
+ sum_block['_'] = val++;
+ for (i = 'a'; i <= 'z'; i++)
+ {
+ sum_block[i] = val++;
+ }
+ }
+}
+
+/* The maximum number of bytes on a line is FF */
+#define MAXCHUNK 0xff
+/* The number of bytes we fit onto a line on output */
+#define CHUNK 21
+
+/* We cannot output our tekhexords as we see them, we have to glue them
+ together, this is done in this structure : */
+
+struct tekhex_data_list_struct
+{
+ unsigned char *data;
+ bfd_vma where;
+ bfd_size_type size;
+ struct tekhex_data_list_struct *next;
+
+};
+typedef struct tekhex_data_list_struct tekhex_data_list_type;
+
+#define CHUNK_MASK 0x1fff
+
+struct data_struct
+ {
+ char chunk_data[CHUNK_MASK + 1];
+ char chunk_init[CHUNK_MASK + 1];
+ bfd_vma vma;
+ struct data_struct *next;
+ };
+
+typedef struct tekhex_data_struct
+{
+ tekhex_data_list_type *head;
+ unsigned int type;
+ struct tekhex_symbol_struct *symbols;
+ struct data_struct *data;
+} tdata_type;
+
+#define enda(x) (x->vma + x->size)
+
+static bfd_vma
+getvalue (srcp)
+ char **srcp;
+{
+ char *src = *srcp;
+ bfd_vma value = 0;
+ unsigned int len = hex_value(*src++);
+
+ if (len == 0)
+ len = 16;
+ while (len--)
+ {
+ value = value << 4 | hex_value(*src++);
+ }
+ *srcp = src;
+ return value;
+}
+
+static unsigned int
+getsym (dstp, srcp)
+ char *dstp;
+ char **srcp;
+{
+ char *src = *srcp;
+ unsigned int i;
+ unsigned int len = hex_value(*src++);
+
+ if (len == 0)
+ len = 16;
+ for (i = 0; i < len; i++)
+ dstp[i] = src[i];
+ dstp[i] = 0;
+ *srcp = src + i;
+ return len;
+}
+
+static struct data_struct *
+find_chunk (abfd, vma)
+ bfd *abfd;
+ bfd_vma vma;
+{
+ struct data_struct *d = abfd->tdata.tekhex_data->data;
+
+ vma &= ~CHUNK_MASK;
+ while (d && (d->vma) != vma)
+ {
+ d = d->next;
+ }
+ if (!d)
+ {
+ char *sname = bfd_alloc (abfd, 12);
+
+ /* No chunk for this address, so make one up */
+ d = (struct data_struct *)
+ bfd_alloc (abfd, sizeof (struct data_struct));
+
+ if (!sname || !d)
+ return NULL;
+
+ memset (d->chunk_init, 0, CHUNK_MASK + 1);
+ memset (d->chunk_data, 0, CHUNK_MASK + 1);
+ d->next = abfd->tdata.tekhex_data->data;
+ d->vma = vma;
+ abfd->tdata.tekhex_data->data = d;
+ }
+ return d;
+}
+
+static void
+insert_byte (abfd, value, addr)
+ bfd *abfd;
+ int value;
+ bfd_vma addr;
+{
+ /* Find the chunk that this byte needs and put it in */
+ struct data_struct *d = find_chunk (abfd, addr);
+
+ d->chunk_data[addr & CHUNK_MASK] = value;
+ d->chunk_init[addr & CHUNK_MASK] = 1;
+}
+
+/* The first pass is to find the names of all the sections, and see
+ how big the data is */
+static void
+first_phase (abfd, type, src)
+ bfd *abfd;
+ int type;
+ char *src;
+{
+ asection *section = bfd_abs_section_ptr;
+ int len;
+ char sym[17]; /* A symbol can only be 16chars long */
+
+ switch (type)
+ {
+ case '6':
+ /* Data record - read it and store it */
+ {
+ bfd_vma addr = getvalue (&src);
+
+ while (*src)
+ {
+ insert_byte (abfd, HEX (src), addr);
+ src += 2;
+ addr++;
+ }
+ }
+
+ return;
+ case '3':
+ /* Symbol record, read the segment */
+ len = getsym (sym, &src);
+ section = bfd_get_section_by_name (abfd, sym);
+ if (section == (asection *) NULL)
+ {
+ char *n = bfd_alloc (abfd, len + 1);
+
+ if (!n)
+ abort(); /* FIXME */
+ memcpy (n, sym, len + 1);
+ section = bfd_make_section (abfd, n);
+ }
+ while (*src)
+ {
+ switch (*src)
+ {
+ case '1': /* section range */
+ src++;
+ section->vma = getvalue (&src);
+ section->_raw_size = getvalue (&src) - section->vma;
+ section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ break;
+ case '0':
+ case '2':
+ case '3':
+ case '4':
+ case '6':
+ case '7':
+ case '8':
+ /* Symbols, add to section */
+ {
+ tekhex_symbol_type *new =
+ (tekhex_symbol_type *) bfd_alloc (abfd,
+ sizeof (tekhex_symbol_type));
+ char type = (*src);
+
+ if (!new)
+ abort(); /* FIXME */
+ new->symbol.the_bfd = abfd;
+ src++;
+ abfd->symcount++;
+ abfd->flags |= HAS_SYMS;
+ new->prev = abfd->tdata.tekhex_data->symbols;
+ abfd->tdata.tekhex_data->symbols = new;
+ len = getsym (sym, &src);
+ new->symbol.name = bfd_alloc (abfd, len + 1);
+ if (!new->symbol.name)
+ abort(); /* FIXME */
+ memcpy ((char *) (new->symbol.name), sym, len + 1);
+ new->symbol.section = section;
+ if (type <= '4')
+ new->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
+ else
+ new->symbol.flags = BSF_LOCAL;
+ new->symbol.value = getvalue (&src) - section->vma;
+ }
+ }
+ }
+ }
+}
+
+/* Pass over an tekhex, calling one of the above functions on each
+ record. */
+
+static void
+pass_over (abfd, func)
+ bfd *abfd;
+ void (*func) PARAMS ((bfd *, int, char *));
+{
+ unsigned int chars_on_line;
+ boolean eof = false;
+
+ /* To the front of the file */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ abort ();
+ while (eof == false)
+ {
+ char buffer[MAXCHUNK];
+ char *src = buffer;
+ char type;
+
+ /* Find first '%' */
+ eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
+ while (*src != '%' && !eof)
+ {
+ eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1);
+ }
+ if (eof)
+ break;
+ src++;
+
+ /* Fetch the type and the length and the checksum */
+ if (bfd_read (src, 1, 5, abfd) != 5)
+ abort (); /* FIXME */
+
+ type = src[2];
+
+ if (!ISHEX (src[0]) || !ISHEX (src[1]))
+ break;
+
+ chars_on_line = HEX (src) - 5; /* Already read five char */
+
+ if (bfd_read (src, 1, chars_on_line, abfd) != chars_on_line)
+ abort (); /* FIXME */
+ src[chars_on_line] = 0; /* put a null at the end */
+
+ func (abfd, type, src);
+ }
+
+}
+
+static long
+tekhex_get_symtab (abfd, table)
+ bfd *abfd;
+ asymbol **table;
+{
+ tekhex_symbol_type *p = abfd->tdata.tekhex_data->symbols;
+ unsigned int c = bfd_get_symcount (abfd);
+
+ table[c] = 0;
+ while (p)
+ {
+ table[--c] = &(p->symbol);
+ p = p->prev;
+ }
+
+ return bfd_get_symcount (abfd);
+}
+
+static long
+tekhex_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *));
+
+}
+
+static boolean
+tekhex_mkobject (abfd)
+ bfd *abfd;
+{
+ tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
+
+ if (!tdata)
+ return false;
+ abfd->tdata.tekhex_data = tdata;
+ tdata->type = 1;
+ tdata->head = (tekhex_data_list_type *) NULL;
+ tdata->symbols = (struct tekhex_symbol_struct *) NULL;
+ tdata->data = (struct data_struct *) NULL;
+ return true;
+}
+
+/*
+ Return true if the file looks like it's in TekHex format. Just look
+ for a percent sign and some hex digits */
+
+static const bfd_target *
+tekhex_object_p (abfd)
+ bfd *abfd;
+{
+ char b[4];
+
+ tekhex_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_read (b, 1, 4, abfd) != 4)
+ return NULL;
+
+ if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
+ return (const bfd_target *) NULL;
+
+ tekhex_mkobject (abfd);
+
+ pass_over (abfd, first_phase);
+ return abfd->xvec;
+}
+
+static void
+move_section_contents (abfd, section, locationp, offset, count, get)
+ bfd *abfd;
+ asection *section;
+ PTR locationp;
+ file_ptr offset;
+ bfd_size_type count;
+ boolean get;
+{
+ bfd_vma addr;
+ char *location = (char *) locationp;
+ bfd_vma prev_number = 1; /* Nothing can have this as a high bit*/
+ struct data_struct *d = (struct data_struct *) NULL;
+
+ for (addr = section->vma; count != 0; count--, addr++)
+ {
+
+ bfd_vma chunk_number = addr & ~CHUNK_MASK; /* Get high bits of address */
+ bfd_vma low_bits = addr & CHUNK_MASK;
+
+ if (chunk_number != prev_number)
+ {
+ /* Different chunk, so move pointer */
+ d = find_chunk (abfd, chunk_number);
+ }
+
+ if (get)
+ {
+ if (d->chunk_init[low_bits])
+ {
+ *location = d->chunk_data[low_bits];
+ }
+ else
+ {
+ *location = 0;
+ }
+ }
+ else
+ {
+ d->chunk_data[low_bits] = *location;
+ d->chunk_init[low_bits] = (*location != 0);
+ }
+
+ location++;
+
+ }
+
+}
+
+static boolean
+tekhex_get_section_contents (abfd, section, locationp, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR locationp;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (section->flags & (SEC_LOAD | SEC_ALLOC))
+ {
+ move_section_contents (abfd, section, locationp, offset, count, true);
+ return true;
+ }
+ else
+ return false;
+}
+
+static boolean
+tekhex_set_arch_mach (abfd, arch, machine)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long machine;
+{
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+/* we have to save up all the Tekhexords for a splurge before output,
+ */
+
+static boolean
+tekhex_set_section_contents (abfd, section, locationp, offset, bytes_to_do)
+ bfd *abfd;
+ sec_ptr section;
+ PTR locationp;
+ file_ptr offset;
+ bfd_size_type bytes_to_do;
+{
+
+ if (abfd->output_has_begun == false)
+ {
+ /* The first time around, allocate enough sections to hold all the chunks */
+ asection *s = abfd->sections;
+ bfd_vma vma;
+
+ for (s = abfd->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ for (vma = s->vma & ~CHUNK_MASK;
+ vma < s->vma + s->_raw_size;
+ vma += CHUNK_MASK)
+ find_chunk (abfd, vma);
+ }
+ }
+
+ }
+ if (section->flags & (SEC_LOAD | SEC_ALLOC))
+ {
+ move_section_contents (abfd, section, locationp, offset, bytes_to_do, false);
+ return true;
+ }
+ else
+ return false;
+
+}
+
+static void
+writevalue (dst, value)
+ char **dst;
+ bfd_vma value;
+{
+ char *p = *dst;
+ int len;
+ int shift;
+
+ for (len = 8, shift = 28; shift; shift -= 4, len--)
+ {
+ if ((value >> shift) & 0xf)
+ {
+ *p++ = len + '0';
+ while (len)
+ {
+ *p++ = digs[(value >> shift) & 0xf];
+ shift -= 4;
+ len--;
+ }
+ *dst = p;
+ return;
+
+ }
+ }
+ *p++ = '1';
+ *p++ = '0';
+ *dst = p;
+}
+
+static void
+writesym (dst, sym)
+ char **dst;
+ CONST char *sym;
+{
+ char *p = *dst;
+ int len = (sym ? strlen (sym) : 0);
+
+ if (len >= 16)
+ {
+ *p++ = '0';
+ len = 16;
+ }
+
+ else
+ {
+ if (len == 0)
+ {
+ *p++ = '1';
+ sym = "$";
+ len = 1;
+ }
+ else
+ {
+ *p++ = digs[len];
+ }
+ }
+
+ while (len--)
+ {
+ *p++ = *sym++;
+ }
+ *dst = p;
+}
+
+static void
+out (abfd, type, start, end)
+ bfd *abfd;
+ int type;
+ char *start;
+ char *end;
+{
+ int sum = 0;
+ char *s;
+ char front[6];
+ bfd_size_type wrlen;
+
+ front[0] = '%';
+ TOHEX (front + 1, end - start + 5);
+ front[3] = type;
+
+ for (s = start; s < end; s++)
+ {
+ sum += sum_block[(unsigned char) *s];
+ }
+
+ sum += sum_block[(unsigned char) front[1]]; /* length */
+ sum += sum_block[(unsigned char) front[2]];
+ sum += sum_block[(unsigned char) front[3]]; /* type */
+ TOHEX (front + 4, sum);
+ if (bfd_write (front, 1, 6, abfd) != 6)
+ abort ();
+ end[0] = '\n';
+ wrlen = end - start + 1;
+ if (bfd_write (start, 1, wrlen, abfd) != wrlen)
+ abort ();
+}
+
+static boolean
+tekhex_write_object_contents (abfd)
+ bfd *abfd;
+{
+ int bytes_written;
+ char buffer[100];
+ asymbol **p;
+ asection *s;
+ struct data_struct *d;
+
+ tekhex_init ();
+
+ bytes_written = 0;
+
+ /* And the raw data */
+ for (d = abfd->tdata.tekhex_data->data;
+ d != (struct data_struct *) NULL;
+ d = d->next)
+ {
+ int low;
+
+ CONST int span = 32;
+ int addr;
+
+ /* Write it in blocks of 32 bytes */
+
+ for (addr = 0; addr < CHUNK_MASK + 1; addr += span)
+ {
+ int need = 0;
+
+ /* Check to see if necessary */
+ for (low = 0; !need && low < span; low++)
+ {
+ if (d->chunk_init[addr + low])
+ need = 1;
+ }
+ if (need)
+ {
+ char *dst = buffer;
+
+ writevalue (&dst, addr + d->vma);
+ for (low = 0; low < span; low++)
+ {
+ TOHEX (dst, d->chunk_data[addr + low]);
+ dst += 2;
+ }
+ out (abfd, '6', buffer, dst);
+ }
+ }
+ }
+ /* write all the section headers for the sections */
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ char *dst = buffer;
+
+ writesym (&dst, s->name);
+ *dst++ = '1';
+ writevalue (&dst, s->vma);
+ writevalue (&dst, s->vma + s->_raw_size);
+ out (abfd, '3', buffer, dst);
+ }
+
+ /* And the symbols */
+ if (abfd->outsymbols)
+ {
+ for (p = abfd->outsymbols; *p; p++)
+ {
+ int section_code = bfd_decode_symclass (*p);
+
+ if (section_code != '?')
+ { /* do not include debug symbols */
+ asymbol *s = *p;
+ char *dst = buffer;
+
+ writesym (&dst, s->section->name);
+
+ switch (section_code)
+ {
+ case 'A':
+ *dst++ = '2';
+ break;
+ case 'a':
+ *dst++ = '6';
+ break;
+ case 'D':
+ case 'B':
+ case 'O':
+ *dst++ = '4';
+ break;
+ case 'd':
+ case 'b':
+ case 'o':
+ *dst++ = '8';
+ break;
+ case 'T':
+ *dst++ = '3';
+ break;
+ case 't':
+ *dst++ = '7';
+ break;
+ case 'C':
+ case 'U':
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
+ writesym (&dst, s->name);
+ writevalue (&dst, s->value + s->section->vma);
+ out (abfd, '3', buffer, dst);
+ }
+ }
+ }
+
+ /* And the terminator */
+ if (bfd_write ("%0781010\n", 1, 9, abfd) != 9)
+ abort ();
+ return true;
+}
+
+static int
+tekhex_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+
+{
+ return 0;
+}
+
+static asymbol *
+tekhex_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ tekhex_symbol_type *new =
+ (tekhex_symbol_type *) bfd_zalloc (abfd, sizeof (struct tekhex_symbol_struct));
+
+ if (!new)
+ return NULL;
+ new->symbol.the_bfd = abfd;
+ new->prev = (struct tekhex_symbol_struct *) NULL;
+ return &(new->symbol);
+}
+
+static void
+tekhex_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static void
+tekhex_print_symbol (ignore_abfd, filep, symbol, how)
+ bfd *ignore_abfd;
+ PTR filep;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) filep;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ break;
+
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name = symbol->section->name;
+
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+
+ fprintf (file, " %-5s %s",
+ section_name,
+ symbol->name);
+ }
+ }
+}
+
+#define tekhex_close_and_cleanup _bfd_generic_close_and_cleanup
+#define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define tekhex_new_section_hook _bfd_generic_new_section_hook
+
+#define tekhex_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define tekhex_get_lineno _bfd_nosymbols_get_lineno
+#define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define tekhex_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define tekhex_read_minisymbols _bfd_generic_read_minisymbols
+#define tekhex_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define tekhex_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define tekhex_bfd_relax_section bfd_generic_relax_section
+#define tekhex_bfd_gc_sections bfd_generic_gc_sections
+#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define tekhex_bfd_final_link _bfd_generic_final_link
+#define tekhex_bfd_link_split_section _bfd_generic_link_split_section
+
+#define tekhex_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+const bfd_target tekhex_vec =
+{
+ "tekhex", /* name */
+ bfd_target_tekhex_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (EXEC_P | /* object flags */
+ HAS_SYMS | HAS_LINENO | HAS_DEBUG | HAS_RELOC | HAS_LOCALS |
+ WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {
+ _bfd_dummy_target,
+ tekhex_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ tekhex_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ tekhex_write_object_contents,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (tekhex),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (tekhex),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (tekhex),
+ BFD_JUMP_TABLE_LINK (tekhex),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/trad-core.c b/bfd/trad-core.c
new file mode 100644
index 00000000000..21d920b0e87
--- /dev/null
+++ b/bfd/trad-core.c
@@ -0,0 +1,316 @@
+/* BFD back end for traditional Unix core files (U-area and raw sections)
+ Copyright 1988, 89, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+ Written by John Gilmore of Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+
+#include <sys/user.h> /* After a.out.h */
+
+#ifdef TRAD_HEADER
+#include TRAD_HEADER
+#endif
+
+ struct trad_core_struct
+ {
+ asection *data_section;
+ asection *stack_section;
+ asection *reg_section;
+ struct user u;
+ };
+
+#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
+#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
+#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
+#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
+
+/* forward declarations */
+
+const bfd_target *trad_unix_core_file_p PARAMS ((bfd *abfd));
+char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd));
+int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd));
+boolean trad_unix_core_file_matches_executable_p
+ PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+static void swap_abort PARAMS ((void));
+
+/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
+
+/* ARGSUSED */
+const bfd_target *
+trad_unix_core_file_p (abfd)
+ bfd *abfd;
+
+{
+ int val;
+ struct user u;
+ struct trad_core_struct *rawptr;
+
+#ifdef TRAD_CORE_USER_OFFSET
+ /* If defined, this macro is the file position of the user struct. */
+ if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) != 0)
+ return 0;
+#endif
+
+ val = bfd_read ((void *)&u, 1, sizeof u, abfd);
+ if (val != sizeof u)
+ {
+ /* Too small to be a core file */
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* Sanity check perhaps??? */
+ if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ if (u.u_ssize > 0x1000000)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* Check that the size claimed is no greater than the file size. */
+ {
+ FILE *stream = bfd_cache_lookup (abfd);
+ struct stat statbuf;
+ if (stream == NULL)
+ return 0;
+ if (fstat (fileno (stream), &statbuf) < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return 0;
+ }
+ if (NBPG * (UPAGES + u.u_dsize
+#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
+ - u.u_tsize
+#endif
+ + u.u_ssize) > statbuf.st_size)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE
+ if (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
+#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
+ /* Some systems write the file too big. */
+ + TRAD_CORE_EXTRA_SIZE_ALLOWED
+#endif
+ < statbuf.st_size)
+ {
+ /* The file is too big. Maybe it's not a core file
+ or we otherwise have bad values for u_dsize and u_ssize). */
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+#endif
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ /* Allocate both the upage and the struct core_data at once, so
+ a single free() will free them both. */
+ rawptr = (struct trad_core_struct *)
+ bfd_zmalloc (sizeof (struct trad_core_struct));
+ if (rawptr == NULL)
+ return 0;
+
+ abfd->tdata.trad_core_data = rawptr;
+
+ rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
+
+ /* Create the sections. This is raunchy, but bfd_close wants to free
+ them separately. */
+
+ core_stacksec(abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_stacksec (abfd) == NULL)
+ return NULL;
+ core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_datasec (abfd) == NULL)
+ return NULL;
+ core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
+ if (core_regsec (abfd) == NULL)
+ return NULL;
+
+ core_stacksec (abfd)->name = ".stack";
+ core_datasec (abfd)->name = ".data";
+ core_regsec (abfd)->name = ".reg";
+
+ core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
+
+ core_datasec (abfd)->_raw_size = NBPG * u.u_dsize
+#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
+ - NBPG * u.u_tsize
+#endif
+ ;
+ core_stacksec (abfd)->_raw_size = NBPG * u.u_ssize;
+ core_regsec (abfd)->_raw_size = NBPG * UPAGES; /* Larger than sizeof struct u */
+
+ /* What a hack... we'd like to steal it from the exec file,
+ since the upage does not seem to provide it. FIXME. */
+#ifdef HOST_DATA_START_ADDR
+ core_datasec (abfd)->vma = HOST_DATA_START_ADDR;
+#else
+ core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
+#endif
+
+#ifdef HOST_STACK_START_ADDR
+ core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
+#else
+ core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
+#endif
+
+ /* This is tricky. As the "register section", we give them the entire
+ upage and stack. u.u_ar0 points to where "register 0" is stored.
+ There are two tricks with this, though. One is that the rest of the
+ registers might be at positive or negative (or both) displacements
+ from *u_ar0. The other is that u_ar0 is sometimes an absolute address
+ in kernel memory, and on other systems it is an offset from the beginning
+ of the `struct user'.
+
+ As a practical matter, we don't know where the registers actually are,
+ so we have to pass the whole area to GDB. We encode the value of u_ar0
+ by setting the .regs section up so that its virtual memory address
+ 0 is at the place pointed to by u_ar0 (by setting the vma of the start
+ of the section to -u_ar0). GDB uses this info to locate the regs,
+ using minor trickery to get around the offset-or-absolute-addr problem. */
+ core_regsec (abfd)->vma = 0 - (bfd_vma) u.u_ar0;
+
+ core_datasec (abfd)->filepos = NBPG * UPAGES;
+ core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize
+#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
+ - NBPG * u.u_tsize
+#endif
+ ;
+ core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
+
+ /* Align to word at least */
+ core_stacksec (abfd)->alignment_power = 2;
+ core_datasec (abfd)->alignment_power = 2;
+ core_regsec (abfd)->alignment_power = 2;
+
+ abfd->sections = core_stacksec (abfd);
+ core_stacksec (abfd)->next = core_datasec (abfd);
+ core_datasec (abfd)->next = core_regsec (abfd);
+ abfd->section_count = 3;
+
+ return abfd->xvec;
+}
+
+char *
+trad_unix_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+#ifndef NO_CORE_COMMAND
+ char *com = abfd->tdata.trad_core_data->u.u_comm;
+ if (*com)
+ return com;
+ else
+#endif
+ return 0;
+}
+
+/* ARGSUSED */
+int
+trad_unix_core_file_failing_signal (ignore_abfd)
+ bfd *ignore_abfd;
+{
+#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
+ return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd);
+#else
+ return -1; /* FIXME, where is it? */
+#endif
+}
+
+/* ARGSUSED */
+boolean
+trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd, *exec_bfd;
+{
+ return true; /* FIXME, We have no way of telling at this point */
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort()
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
+#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define NO_SIGNED_GET \
+ ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
+
+const bfd_target trad_core_vec =
+ {
+ "trad-core",
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_UNKNOWN, /* target byte order */
+ BFD_ENDIAN_UNKNOWN, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* symbol prefix */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
+
+ { /* bfd_check_format */
+ _bfd_dummy_target, /* unknown format */
+ _bfd_dummy_target, /* object file */
+ _bfd_dummy_target, /* archive */
+ trad_unix_core_file_p /* a core file */
+ },
+ { /* bfd_set_format */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+ { /* bfd_write_contents */
+ bfd_false, bfd_false,
+ bfd_false, bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (trad_unix),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_generic),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0 /* backend_data */
+};
diff --git a/bfd/vaxnetbsd.c b/bfd/vaxnetbsd.c
new file mode 100644
index 00000000000..e137d093c6f
--- /dev/null
+++ b/bfd/vaxnetbsd.c
@@ -0,0 +1,33 @@
+/* BFD back-end for NetBSD/VAX a.out-ish binaries.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BYTES_IN_WORD 4
+#undef TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#define DEFAULT_ARCH bfd_arch_vax
+#define DEFAULT_MID M_VAX_NETBSD
+
+#define MY(OP) CAT(vaxnetbsd_,OP)
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-vax-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/versados.c b/bfd/versados.c
new file mode 100644
index 00000000000..0dcd1080694
--- /dev/null
+++ b/bfd/versados.c
@@ -0,0 +1,923 @@
+/* BFD back-end for VERSAdos-E objects.
+ Copyright 1995, 96, 1997 Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
+
+ Versados is a Motorola trademark.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ SUBSECTION
+ VERSAdos-E relocateable object file format
+
+ DESCRIPTION
+
+ This module supports reading of VERSAdos relocateable
+ object files.
+
+ A VERSAdos file looks like contains
+
+ o Indentification Record
+ o External Symbol Definition Record
+ o Object Text Recrod
+ o End Record
+
+
+ */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+
+static boolean versados_mkobject PARAMS ((bfd *));
+static boolean versados_scan PARAMS ((bfd *));
+static const bfd_target *versados_object_p PARAMS ((bfd *));
+
+
+#define VHEADER '1'
+#define VESTDEF '2'
+#define VOTR '3'
+#define VEND '4'
+
+
+#define ES_BASE 17 /* first symbol has esdid 17 */
+
+/* Per file target dependent information */
+
+/* one for each section */
+struct esdid
+ {
+ asection *section; /* ptr to bfd version */
+ unsigned char *contents; /* used to build image */
+ int pc;
+ int relocs; /* reloc count, valid end of pass 1 */
+ int donerel; /* have relocs been translated */
+ };
+
+typedef struct versados_data_struct
+ {
+ int es_done; /* count of symbol index, starts at ES_BASE */
+ asymbol *symbols; /* pointer to local symbols */
+ char *strings; /* strings of all the above */
+ int stringlen; /* len of string table (valid end of pass1) */
+ int nsecsyms; /* number of sections */
+
+ int ndefs; /* number of exported symbols (they dont get esdids) */
+ int nrefs; /* number of imported symbols (valid end of pass1) */
+
+ int ref_idx; /* current processed value of the above */
+ int def_idx;
+
+ int pass_2_done;
+
+ struct esdid e[16]; /* per section info */
+ int alert; /* to see if we're trampling */
+ asymbol *rest[256 - 16]; /* per symbol info */
+
+ }
+tdata_type;
+
+#define VDATA(abfd) (abfd->tdata.versados_data)
+#define EDATA(abfd, n) (abfd->tdata.versados_data->e[n])
+#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[n])
+
+struct ext_otr
+ {
+ unsigned char size;
+ char type;
+ unsigned char map[4];
+ unsigned char esdid;
+ unsigned char data[200];
+ };
+
+struct ext_vheader
+ {
+ unsigned char size;
+ char type; /* record type */
+ char name[10]; /* module name */
+ char rev; /* module rev number */
+ char lang;
+ char vol[4];
+ char user[2];
+ char cat[8];
+ char fname[8];
+ char ext[2];
+ char time[3];
+ char date[3];
+ char rest[211];
+ };
+
+struct ext_esd
+ {
+ unsigned char size;
+ char type;
+ unsigned char esd_entries[1];
+ };
+#define ESD_ABS 0
+#define ESD_COMMON 1
+#define ESD_STD_REL_SEC 2
+#define ESD_SHRT_REL_SEC 3
+#define ESD_XDEF_IN_SEC 4
+#define ESD_XREF_SYM 7
+#define ESD_XREF_SEC 6
+#define ESD_XDEF_IN_ABS 5
+union ext_any
+ {
+ unsigned char size;
+ struct ext_vheader header;
+ struct ext_esd esd;
+ struct ext_otr otr;
+ };
+
+/* Initialize by filling in the hex conversion array. */
+
+
+
+
+
+/* Set up the tdata information. */
+
+static boolean
+versados_mkobject (abfd)
+ bfd *abfd;
+{
+ if (abfd->tdata.versados_data == NULL)
+ {
+ tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
+ if (tdata == NULL)
+ return false;
+ abfd->tdata.versados_data = tdata;
+ tdata->symbols = NULL;
+ VDATA (abfd)->alert = 0x12345678;
+ }
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
+ return true;
+}
+
+
+/* Report a problem in an S record file. FIXME: This probably should
+ not call fprintf, but we really do need some mechanism for printing
+ error messages. */
+
+
+
+static asymbol *
+versados_new_symbol (abfd, snum, name, val, sec)
+ bfd *abfd;
+ int snum;
+ const char *name;
+ bfd_vma val;
+ asection *sec;
+{
+ asymbol *n = VDATA (abfd)->symbols + snum;
+ n->name = name;
+ n->value = val;
+ n->section = sec;
+ n->the_bfd = abfd;
+ n->flags = 0;
+ return n;
+}
+
+
+static int
+get_record (abfd, ptr)
+ bfd *abfd;
+ union ext_any *ptr;
+{
+ bfd_read (&ptr->size, 1, 1, abfd);
+ if (bfd_read ((char *) ptr + 1, 1, ptr->size, abfd) != ptr->size)
+ return 0;
+ return 1;
+}
+
+int
+get_4 (pp)
+ unsigned char **pp;
+{
+ unsigned char *p = *pp;
+ *pp += 4;
+ return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+}
+
+void
+get_10 (pp, name)
+ unsigned char **pp;
+ char *name;
+{
+ char *p = (char *) *pp;
+ int len = 10;
+ *pp += len;
+ while (*p != ' '
+ && len)
+ {
+ *name++ = *p++;
+ len--;
+ }
+ *name = 0;
+}
+
+static char *
+new_symbol_string (abfd, name)
+ bfd *abfd;
+ char *name;
+{
+ char *n = VDATA (abfd)->strings;
+ strcpy (VDATA (abfd)->strings, name);
+ VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1;
+ return n;
+}
+
+
+static void
+process_esd (abfd, esd, pass)
+ bfd *abfd;
+ struct ext_esd *esd;
+ int pass;
+{
+ /* Read through the ext def for the est entries */
+ int togo = esd->size - 2;
+ bfd_vma size;
+ bfd_vma start;
+ asection *sec;
+ char name[11];
+ unsigned char *ptr = esd->esd_entries;
+ unsigned char *end = ptr + togo;
+ while (ptr < end)
+ {
+ int scn = *ptr & 0xf;
+ int typ = (*ptr >> 4) & 0xf;
+
+ /* Declare this section */
+ sprintf (name, "%d", scn);
+ sec = bfd_make_section_old_way (abfd, strdup (name));
+ sec->target_index = scn;
+ EDATA (abfd, scn).section = sec;
+ ptr++;
+ switch (typ)
+ {
+ default:
+ abort ();
+ case ESD_XREF_SEC:
+ case ESD_XREF_SYM:
+ {
+ int snum = VDATA (abfd)->ref_idx++;
+ get_10 (&ptr, name);
+ if (pass == 1)
+ {
+ VDATA (abfd)->stringlen += strlen (name) + 1;
+ }
+ else
+ {
+ int esidx;
+ asymbol *s;
+ char *n = new_symbol_string (abfd, name);
+ s = versados_new_symbol (abfd, snum, n, 0,
+ &bfd_und_section, scn);
+ esidx = VDATA (abfd)->es_done++;
+ RDATA (abfd, esidx - ES_BASE) = s;
+ }
+ }
+ break;
+
+
+ case ESD_ABS:
+ size = get_4 (&ptr);
+ start = get_4 (&ptr);
+ break;
+ case ESD_STD_REL_SEC:
+ case ESD_SHRT_REL_SEC:
+ {
+ sec->_raw_size = get_4 (&ptr);
+ sec->flags |= SEC_ALLOC;
+ }
+ break;
+ case ESD_XDEF_IN_ABS:
+ sec = (asection *) & bfd_abs_section;
+ case ESD_XDEF_IN_SEC:
+ {
+ int snum = VDATA (abfd)->def_idx++;
+ long val;
+ get_10 (&ptr, name);
+ val = get_4 (&ptr);
+ if (pass == 1)
+ {
+ /* Just remember the symbol */
+ VDATA (abfd)->stringlen += strlen (name) + 1;
+ }
+ else
+ {
+ asymbol *s;
+ char *n = new_symbol_string (abfd, name);
+ s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n, val, sec, scn);
+ s->flags |= BSF_GLOBAL;
+ }
+ }
+ break;
+ }
+ }
+}
+
+#define R_RELWORD 1
+#define R_RELLONG 2
+#define R_RELWORD_NEG 3
+#define R_RELLONG_NEG 4
+
+reloc_howto_type versados_howto_table[] =
+{
+ HOWTO (R_RELWORD, 0, 1, 16, false,
+ 0, complain_overflow_dont, 0,
+ "+v16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_RELLONG, 0, 2, 32, false,
+ 0, complain_overflow_dont, 0,
+ "+v32", true, 0xffffffff, 0xffffffff, false),
+
+ HOWTO (R_RELWORD_NEG, 0, -1, 16, false,
+ 0, complain_overflow_dont, 0,
+ "-v16", true, 0x0000ffff, 0x0000ffff, false),
+ HOWTO (R_RELLONG_NEG, 0, -2, 32, false,
+ 0, complain_overflow_dont, 0,
+ "-v32", true, 0xffffffff, 0xffffffff, false),
+};
+
+
+static int
+get_offset (len, ptr)
+ int len;
+ unsigned char *ptr;
+{
+ int val = 0;
+ if (len)
+ {
+ int i;
+ val = *ptr++;
+ if (val & 0x80)
+ val |= ~0xff;
+ for (i = 1; i < len; i++)
+ val = (val << 8) | *ptr++;
+ }
+
+ return val;
+}
+
+static void
+process_otr (abfd, otr, pass)
+ bfd *abfd;
+ struct ext_otr *otr;
+ int pass;
+{
+ unsigned long shift;
+ unsigned char *srcp = otr->data;
+ unsigned char *endp = (unsigned char *) otr + otr->size;
+ unsigned int bits = (otr->map[0] << 24)
+ | (otr->map[1] << 16)
+ | (otr->map[2] << 8)
+ | (otr->map[3] << 0);
+
+ struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
+ unsigned char *contents = esdid->contents;
+ int need_contents = 0;
+ unsigned int dst_idx = esdid->pc;
+
+ for (shift = (1 << 31); shift && srcp < endp; shift >>= 1)
+ {
+ if (bits & shift)
+ {
+ int flag = *srcp++;
+ int esdids = (flag >> 5) & 0x7;
+ int sizeinwords = ((flag >> 3) & 1) ? 2 : 1;
+ int offsetlen = flag & 0x7;
+ int j;
+
+
+ if (esdids == 0)
+ {
+ /* A zero esdid means the new pc is the offset given */
+ dst_idx += get_offset (offsetlen, srcp);
+ srcp += offsetlen;
+ }
+ else
+ {
+ int val = get_offset (offsetlen, srcp + esdids);
+ if (pass == 1)
+ need_contents = 1;
+ else
+ for (j = 0; j < sizeinwords * 2; j++)
+ {
+ contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
+ val >>= 8;
+ }
+
+ for (j = 0; j < esdids; j++)
+ {
+ int esdid = *srcp++;
+
+ if (esdid)
+ {
+ int rn = EDATA (abfd, otr->esdid - 1).relocs++;
+ if (pass == 1)
+ {
+ /* this is the first pass over the data,
+ just remember that we need a reloc */
+ }
+ else
+ {
+ arelent *n =
+ EDATA (abfd, otr->esdid - 1).section->relocation + rn;
+ n->address = dst_idx;
+
+ n->sym_ptr_ptr = (asymbol **) esdid;
+ n->addend = 0;
+ n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1);
+ }
+ }
+ }
+ srcp += offsetlen;
+ dst_idx += sizeinwords * 2;
+ }
+ }
+ else
+ {
+ need_contents = 1;
+ if (dst_idx < esdid->section->_raw_size)
+ if (pass == 2)
+ {
+ /* absolute code, comes in 16 bit lumps */
+ contents[dst_idx] = srcp[0];
+ contents[dst_idx + 1] = srcp[1];
+ }
+ dst_idx += 2;
+ srcp += 2;
+ }
+ }
+ EDATA (abfd, otr->esdid - 1).pc = dst_idx;
+
+ if (!contents && need_contents)
+ esdid->contents = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size);
+
+
+}
+
+static boolean
+versados_scan (abfd)
+ bfd *abfd;
+{
+ int loop = 1;
+ int i;
+ int j;
+ int nsecs = 0;
+
+ VDATA (abfd)->nrefs = 0;
+ VDATA (abfd)->ndefs = 0;
+ VDATA (abfd)->ref_idx = 0;
+ VDATA (abfd)->def_idx = 0;
+
+ while (loop)
+ {
+ union ext_any any;
+ if (!get_record (abfd, &any))
+ return true;
+ switch (any.header.type)
+ {
+ case VHEADER:
+ break;
+ case VEND:
+ loop = 0;
+ break;
+ case VESTDEF:
+ process_esd (abfd, &any.esd, 1);
+ break;
+ case VOTR:
+ process_otr (abfd, &any.otr, 1);
+ break;
+ }
+ }
+
+ /* Now allocate space for the relocs and sections */
+
+ VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx;
+ VDATA (abfd)->ndefs = VDATA (abfd)->def_idx;
+ VDATA (abfd)->ref_idx = 0;
+ VDATA (abfd)->def_idx = 0;
+
+ abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs;
+
+ for (i = 0; i < 16; i++)
+ {
+ struct esdid *esdid = &EDATA (abfd, i);
+ if (esdid->section)
+ {
+ esdid->section->relocation
+ = (arelent *) bfd_alloc (abfd, sizeof (arelent) * esdid->relocs);
+
+ esdid->pc = 0;
+
+ if (esdid->contents)
+ esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD;
+
+ esdid->section->reloc_count = esdid->relocs;
+ if (esdid->relocs)
+ esdid->section->flags |= SEC_RELOC;
+
+ esdid->relocs = 0;
+
+ /* Add an entry into the symbol table for it */
+ nsecs++;
+ VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1;
+ }
+ }
+
+ abfd->symcount += nsecs;
+
+ VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd,
+ sizeof (asymbol) * (abfd->symcount));
+
+ VDATA (abfd)->strings = bfd_alloc (abfd, VDATA (abfd)->stringlen);
+
+ if ((VDATA (abfd)->symbols == NULL && abfd->symcount > 0)
+ || (VDATA (abfd)->strings == NULL && VDATA (abfd)->stringlen > 0))
+ return false;
+
+ /* Actually fill in the section symbols,
+ we stick them at the end of the table */
+
+ for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++)
+ {
+ struct esdid *esdid = &EDATA (abfd, i);
+ asection *sec = esdid->section;
+ if (sec)
+ {
+ asymbol *s = VDATA (abfd)->symbols + j;
+ s->name = new_symbol_string (abfd, sec->name);
+ s->section = sec;
+ s->flags = BSF_LOCAL;
+ s->value = 0;
+ s->the_bfd = abfd;
+ j++;
+ }
+ }
+ if (abfd->symcount)
+ abfd->flags |= HAS_SYMS;
+
+ /* Set this to nsecs - since we've already planted the section
+ symbols */
+ VDATA (abfd)->nsecsyms = nsecs;
+
+ VDATA (abfd)->ref_idx = 0;
+
+ return 1;
+}
+
+
+
+/* Check whether an existing file is a versados file. */
+
+static const bfd_target *
+versados_object_p (abfd)
+ bfd *abfd;
+{
+ struct ext_vheader ext;
+ unsigned char len;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return NULL;
+
+ if (bfd_read (&len, 1, 1, abfd) != 1)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_read (&ext.type, 1, len, abfd) != len)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* We guess that the language field will never be larger than 10.
+ In sample files, it is always either 0 or 1. Checking for this
+ prevents confusion with Intel Hex files. */
+ if (ext.type != VHEADER
+ || ext.lang > 10)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* OK, looks like a record, build the tdata and read in. */
+
+ if (!versados_mkobject (abfd)
+ || !versados_scan (abfd))
+ return NULL;
+
+ return abfd->xvec;
+}
+
+
+static boolean
+versados_pass_2 (abfd)
+ bfd *abfd;
+{
+ union ext_any any;
+
+ if (VDATA (abfd)->pass_2_done)
+ return 1;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return 0;
+
+ VDATA (abfd)->es_done = ES_BASE;
+
+
+ /* read records till we get to where we want to be */
+
+ while (1)
+ {
+ get_record (abfd, &any);
+ switch (any.header.type)
+ {
+ case VEND:
+ VDATA (abfd)->pass_2_done = 1;
+ return 1;
+ case VESTDEF:
+ process_esd (abfd, &any.esd, 2);
+ break;
+ case VOTR:
+ process_otr (abfd, &any.otr, 2);
+ break;
+ }
+ }
+}
+
+static boolean
+versados_get_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ if (!versados_pass_2 (abfd))
+ return false;
+
+ memcpy (location,
+ EDATA (abfd, section->target_index).contents + offset,
+ (size_t) count);
+
+ return true;
+}
+
+#define versados_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+static boolean
+versados_set_section_contents (abfd, section, location, offset, bytes_to_do)
+ bfd *abfd;
+ sec_ptr section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type bytes_to_do;
+{
+ return false;
+}
+
+
+/*ARGSUSED */
+static int
+versados_sizeof_headers (abfd, exec)
+ bfd *abfd;
+ boolean exec;
+{
+ return 0;
+}
+
+static asymbol *
+versados_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new)
+ new->the_bfd = abfd;
+ return new;
+}
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+versados_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
+}
+
+/* Return the symbol table. */
+
+static long
+versados_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ unsigned int symcount = bfd_get_symcount (abfd);
+ unsigned int i;
+ asymbol *s;
+
+ versados_pass_2 (abfd);
+
+ for (i = 0, s = VDATA (abfd)->symbols;
+ i < symcount;
+ s++, i++)
+ {
+ *alocation++ = s;
+ }
+
+ *alocation = NULL;
+
+ return symcount;
+}
+
+/*ARGSUSED */
+void
+versados_get_symbol_info (ignore_abfd, symbol, ret)
+ bfd *ignore_abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/*ARGSUSED */
+void
+versados_print_symbol (ignore_abfd, afile, symbol, how)
+ bfd *ignore_abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ default:
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %-5s %s",
+ symbol->section->name,
+ symbol->name);
+
+ }
+}
+
+long
+versados_get_reloc_upper_bound (abfd, asect)
+ bfd *abfd;
+ sec_ptr asect;
+{
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+
+long
+versados_canonicalize_reloc (abfd, section, relptr, symbols)
+ bfd *abfd;
+ sec_ptr section;
+ arelent **relptr;
+ asymbol **symbols;
+{
+ unsigned int count;
+ arelent *src;
+
+ versados_pass_2 (abfd);
+ src = section->relocation;
+ if (!EDATA (abfd, section->target_index).donerel)
+ {
+ EDATA (abfd, section->target_index).donerel = 1;
+ /* translate from indexes to symptr ptrs */
+ for (count = 0; count < section->reloc_count; count++)
+ {
+ int esdid = (int) src[count].sym_ptr_ptr;
+
+ if (esdid == 0)
+ {
+ src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+ }
+ else if (esdid < ES_BASE) /* Section relative thing */
+ {
+ struct esdid *e = &EDATA (abfd, esdid - 1);
+ if (!section)
+ {
+ /** relocation relative to section which was
+ never declared ! */
+ }
+ src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
+ }
+ else
+ {
+ src[count].sym_ptr_ptr = symbols + esdid - ES_BASE;
+ }
+
+ }
+ }
+
+ for (count = 0; count < section->reloc_count; count++)
+ {
+ *relptr++ = src++;
+ }
+ *relptr = 0;
+ return section->reloc_count;
+}
+
+#define versados_close_and_cleanup _bfd_generic_close_and_cleanup
+#define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define versados_new_section_hook _bfd_generic_new_section_hook
+
+#define versados_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define versados_get_lineno _bfd_nosymbols_get_lineno
+#define versados_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define versados_read_minisymbols _bfd_generic_read_minisymbols
+#define versados_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define versados_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define versados_set_arch_mach bfd_default_set_arch_mach
+
+#define versados_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define versados_bfd_relax_section bfd_generic_relax_section
+#define versados_bfd_gc_sections bfd_generic_gc_sections
+#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define versados_bfd_final_link _bfd_generic_final_link
+#define versados_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target versados_vec =
+{
+ "versados", /* name */
+ bfd_target_versados_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+
+ {
+ _bfd_dummy_target,
+ versados_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ versados_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ bfd_false,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (versados),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (versados),
+ BFD_JUMP_TABLE_RELOCS (versados),
+ BFD_JUMP_TABLE_WRITE (versados),
+ BFD_JUMP_TABLE_LINK (versados),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ (PTR) 0
+};
diff --git a/bfd/vms-gsd.c b/bfd/vms-gsd.c
new file mode 100644
index 00000000000..6a52462a06d
--- /dev/null
+++ b/bfd/vms-gsd.c
@@ -0,0 +1,920 @@
+/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation Inc.
+
+ go and read the openVMS linker manual (esp. appendix B)
+ if you don't know what's going on here :-)
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+/*-----------------------------------------------------------------------------*/
+
+/* typical sections for vax object files */
+
+#define VAX_CODE_NAME "$CODE"
+#define VAX_DATA_NAME "$DATA"
+#define VAX_ADDRESS_DATA_NAME "$ADDRESS_DATA"
+
+/* typical sections for evax object files */
+
+#define EVAX_ABS_NAME "$ABS$"
+#define EVAX_CODE_NAME "$CODE$"
+#define EVAX_LINK_NAME "$LINK$"
+#define EVAX_DATA_NAME "$DATA$"
+#define EVAX_BSS_NAME "$BSS$"
+#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
+#define EVAX_READONLY_NAME "$READONLY$"
+#define EVAX_LITERAL_NAME "$LITERAL$"
+#define EVAX_COMMON_NAME "$COMMON$"
+#define EVAX_LOCAL_NAME "$LOCAL$"
+
+struct sec_flags_struct {
+ char *name; /* name of section */
+ int vflags_always;
+ flagword flags_always; /* flags we set always */
+ int vflags_hassize;
+ flagword flags_hassize; /* flags we set if the section has a size > 0 */
+};
+
+/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible */
+
+static struct sec_flags_struct vax_section_flags[] = {
+ { VAX_CODE_NAME,
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
+ (SEC_CODE),
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
+ (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { VAX_DATA_NAME,
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_DATA),
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { VAX_ADDRESS_DATA_NAME,
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
+ (SEC_DATA|SEC_READONLY),
+ (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { NULL,
+ (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_DATA),
+ (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
+};
+
+
+/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible */
+
+static struct sec_flags_struct evax_section_flags[] = {
+ { EVAX_ABS_NAME,
+ (EGPS_S_V_SHR),
+ (SEC_DATA),
+ (EGPS_S_V_SHR),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_CODE_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
+ (SEC_CODE),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
+ (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_LITERAL_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_LINK_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_DATA_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
+ (SEC_DATA),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_BSS_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
+ (SEC_NO_FLAGS),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
+ (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { EVAX_READONLYADDR_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_READONLY_NAME,
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
+ (SEC_DATA|SEC_READONLY),
+ (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
+ { EVAX_LOCAL_NAME,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_DATA),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
+ { NULL,
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_DATA),
+ (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
+ (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
+};
+
+/* Retrieve bfd section flags by name and size */
+
+static flagword
+vms_secflag_by_name (abfd, section_flags, name, size)
+ bfd *abfd;
+ struct sec_flags_struct *section_flags;
+ char *name;
+ int size;
+{
+ int i = 0;
+
+ while (section_flags[i].name != NULL)
+ {
+ if ((PRIV(is_vax)?
+ strcasecmp (name, section_flags[i].name):
+ strcmp (name, section_flags[i].name)) == 0)
+ {
+ if (size > 0)
+ return section_flags[i].flags_hassize;
+ else
+ return section_flags[i].flags_always;
+ }
+ i++;
+ }
+ if (size > 0)
+ return section_flags[i].flags_hassize;
+ return section_flags[i].flags_always;
+}
+
+
+/* Retrieve vms section flags by name and size */
+
+static flagword
+vms_esecflag_by_name (section_flags, name, size)
+ struct sec_flags_struct *section_flags;
+ char *name;
+ int size;
+{
+ int i = 0;
+
+ while (section_flags[i].name != NULL)
+ {
+ if (strcmp (name, section_flags[i].name) == 0)
+ {
+ if (size > 0)
+ return section_flags[i].vflags_hassize;
+ else
+ return section_flags[i].vflags_always;
+ }
+ i++;
+ }
+ if (size > 0)
+ return section_flags[i].vflags_hassize;
+ return section_flags[i].vflags_always;
+}
+
+/*-----------------------------------------------------------------------------*/
+#if VMS_DEBUG
+/* debug */
+
+struct flagdescstruct { char *name; flagword value; };
+
+/* Convert flag to printable string */
+
+static char *
+flag2str(flagdesc, flags)
+ struct flagdescstruct *flagdesc;
+ flagword flags;
+{
+
+ static char res[64];
+ int next = 0;
+
+ res[0] = 0;
+ while (flagdesc->name != NULL)
+ {
+ if ((flags & flagdesc->value) != 0)
+ {
+ if (next)
+ strcat(res, ",");
+ else
+ next = 1;
+ strcat (res, flagdesc->name);
+ }
+ flagdesc++;
+ }
+ return res;
+}
+#endif
+
+/*-----------------------------------------------------------------------------*/
+/* input routines */
+
+/* Process GSD/EGSD record
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_gsd (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ static struct flagdescstruct gpsflagdesc[] =
+ {
+ { "PIC", 0x0001 },
+ { "LIB", 0x0002 },
+ { "OVR", 0x0004 },
+ { "REL", 0x0008 },
+ { "GBL", 0x0010 },
+ { "SHR", 0x0020 },
+ { "EXE", 0x0040 },
+ { "RD", 0x0080 },
+ { "WRT", 0x0100 },
+ { "VEC", 0x0200 },
+ { "NOMOD", 0x0400 },
+ { "COM", 0x0800 },
+ { NULL, 0 }
+ };
+
+ static struct flagdescstruct gsyflagdesc[] =
+ {
+ { "WEAK", 0x0001 },
+ { "DEF", 0x0002 },
+ { "UNI", 0x0004 },
+ { "REL", 0x0008 },
+ { "COMM", 0x0010 },
+ { "VECEP", 0x0020 },
+ { "NORM", 0x0040 },
+ { NULL, 0 }
+ };
+#endif
+
+ int gsd_type, gsd_size;
+ asection *section;
+ unsigned char *vms_rec;
+ flagword new_flags, old_flags;
+ char *name;
+ asymbol *symbol;
+ vms_symbol_entry *entry;
+ unsigned long base_addr;
+ unsigned long align_addr;
+ static int psect_idx = 0;
+
+#if VMS_DEBUG
+ vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);
+#endif
+
+ switch (objtype)
+ {
+ case EOBJ_S_C_EGSD:
+ PRIV(vms_rec) += 8; /* skip type, size, l_temp */
+ PRIV(rec_size) -= 8;
+ break;
+ case OBJ_S_C_GSD:
+ PRIV(vms_rec) += 1;
+ PRIV(rec_size) -= 1;
+ break;
+ default:
+ return -1;
+ }
+
+ /* calculate base address for each section */
+ base_addr = 0L;
+
+ abfd->symcount = 0;
+
+ while (PRIV(rec_size) > 0)
+ {
+ vms_rec = PRIV(vms_rec);
+
+ if (objtype == OBJ_S_C_GSD)
+ {
+ gsd_type = *vms_rec;
+ }
+ else
+ {
+ _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
+ gsd_type += EVAX_OFFSET;
+ }
+
+#if VMS_DEBUG
+ vms_debug (3, "gsd_type %d\n", gsd_type);
+#endif
+
+ switch (gsd_type)
+ {
+ case GSD_S_C_PSC:
+ {
+ /*
+ * program section definition
+ */
+
+ asection *old_section = 0;
+
+#if VMS_DEBUG
+ vms_debug (4, "GSD_S_C_PSC\n");
+#endif
+ /* If this section isn't a bfd section. */
+
+ if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1)))
+ {
+ /* check for temporary section from TIR record. */
+
+ if (psect_idx < PRIV(section_count))
+ old_section = PRIV(sections)[psect_idx];
+ else
+ old_section = 0;
+ }
+
+ name = _bfd_vms_save_counted_string (vms_rec + 8);
+ section = bfd_make_section (abfd, name);
+ if (!section)
+ {
+ fprintf (stderr, "bfd_make_section (%s) failed\n", name);
+ return -1;
+ }
+ old_flags = bfd_getl16 (vms_rec + 2);
+ section->_raw_size = bfd_getl32(vms_rec + 4); /* allocation */
+ new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->_raw_size);
+ if (old_flags & EGPS_S_V_REL)
+ new_flags |= SEC_RELOC;
+ if (old_flags & GPS_S_M_OVR)
+ new_flags |= SEC_IS_COMMON;
+ if (!bfd_set_section_flags (abfd, section, new_flags))
+ {
+ fprintf (stderr, "bfd_set_section_flags (%s, %x) failed\n", name, new_flags);
+ return -1;
+ }
+ section->alignment_power = vms_rec[1];
+ align_addr = (1 << section->alignment_power);
+ if ((base_addr % align_addr) != 0)
+ base_addr += (align_addr - (base_addr % align_addr));
+ section->vma = (bfd_vma)base_addr;
+ base_addr += section->_raw_size;
+
+ /* global section is common symbol */
+
+ if (old_flags & GPS_S_M_GBL)
+ {
+ entry = _bfd_vms_enter_symbol (abfd, name);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ symbol = entry->symbol;
+
+ symbol->value = 0;
+ symbol->section = section;
+ symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON);
+ }
+
+ /* copy saved contents if old_section set */
+
+ if (old_section != 0)
+ {
+ section->contents = old_section->contents;
+ if (section->_raw_size < old_section->_raw_size)
+ {
+ fprintf (stderr, "Size mismatch section %s=%d, %s=%d\n", old_section->name, old_section->_raw_size, section->name, section->_raw_size);
+ return -1;
+ }
+ else if (section->_raw_size > old_section->_raw_size)
+ {
+ section->contents = ((unsigned char *)
+ bfd_realloc (old_section->contents, section->_raw_size));
+ if (section->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ section->contents = ((unsigned char *)
+ bfd_malloc (section->_raw_size));
+ if (section->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ memset (section->contents, 0, (size_t)section->_raw_size);
+ }
+ section->_cooked_size = section->_raw_size;
+#if VMS_DEBUG
+ vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
+ section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
+ vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
+ section->_raw_size, section->vma, section->contents);
+#endif
+
+ gsd_size = vms_rec[8] + 9;
+
+ psect_idx++;
+ }
+ break;
+
+ case GSD_S_C_EPM:
+ case GSD_S_C_EPMW:
+#if VMS_DEBUG
+ vms_debug(4, "gsd epm\n");
+#endif
+ /*FALLTHRU*/
+ case GSD_S_C_SYM:
+ case GSD_S_C_SYMW:
+ {
+ int name_offset, value_offset;
+
+ /*
+ * symbol specification (definition or reference)
+ */
+
+#if VMS_DEBUG
+ vms_debug (4, "GSD_S_C_SYM(W)\n");
+#endif
+ old_flags = bfd_getl16 (vms_rec + 2);
+ new_flags = BSF_NO_FLAGS;
+
+ if (old_flags & GSY_S_M_WEAK)
+ new_flags |= BSF_WEAK;
+
+ switch (gsd_type)
+ {
+ case GSD_S_C_EPM:
+ name_offset = 11;
+ value_offset = 5;
+ new_flags |= BSF_FUNCTION;
+ break;
+ case GSD_S_C_EPMW:
+ name_offset = 12;
+ value_offset = 6;
+ new_flags |= BSF_FUNCTION;
+ break;
+ case GSD_S_C_SYM:
+ if (old_flags & GSY_S_M_DEF) /* symbol definition */
+ name_offset = 9;
+ else
+ name_offset = 4;
+ value_offset = 5;
+ break;
+ case GSD_S_C_SYMW:
+ if (old_flags & GSY_S_M_DEF) /* symbol definition */
+ name_offset = 10;
+ else
+ name_offset = 5;
+ value_offset = 6;
+ break;
+ }
+
+ /* save symbol in vms_symbol_table */
+
+ entry = _bfd_vms_enter_symbol (abfd,
+ _bfd_vms_save_counted_string (vms_rec + name_offset));
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ symbol = entry->symbol;
+
+ if (old_flags & GSY_S_M_DEF) /* symbol definition */
+ {
+ int psect;
+
+ symbol->value = bfd_getl32 (vms_rec+value_offset);
+ if ((gsd_type == GSD_S_C_SYMW)
+ || (gsd_type == GSD_S_C_EPMW))
+ psect = bfd_getl16 (vms_rec + value_offset - 2);
+ else
+ psect = vms_rec[value_offset-1];
+
+ symbol->section = (asection *)psect;
+#if VMS_DEBUG
+ vms_debug(4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount,
+ symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
+#endif
+ }
+ else /* symbol reference */
+ {
+ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
+#if VMS_DEBUG
+ vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount,
+ symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
+#endif
+ }
+
+ gsd_size = vms_rec[name_offset] + name_offset + 1;
+ symbol->flags = new_flags;
+ }
+
+ break;
+
+ case GSD_S_C_PRO:
+ case GSD_S_C_PROW:
+#if VMS_DEBUG
+ vms_debug(4, "gsd pro\n");
+#endif
+ break;
+ case GSD_S_C_IDC:
+#if VMS_DEBUG
+ vms_debug(4, "gsd idc\n");
+#endif
+ break;
+ case GSD_S_C_ENV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd env\n");
+#endif
+ break;
+ case GSD_S_C_LSY:
+#if VMS_DEBUG
+ vms_debug(4, "gsd lsy\n");
+#endif
+ break;
+ case GSD_S_C_LEPM:
+#if VMS_DEBUG
+ vms_debug(4, "gsd lepm\n");
+#endif
+ break;
+ case GSD_S_C_LPRO:
+#if VMS_DEBUG
+ vms_debug(4, "gsd lpro\n");
+#endif
+ break;
+ case GSD_S_C_SPSC:
+#if VMS_DEBUG
+ vms_debug(4, "gsd spsc\n");
+#endif
+ break;
+ case GSD_S_C_SYMV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd symv\n");
+#endif
+ break;
+ case GSD_S_C_EPMV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd epmv\n");
+#endif
+ break;
+ case GSD_S_C_PROV:
+#if VMS_DEBUG
+ vms_debug(4, "gsd prov\n");
+#endif
+ break;
+
+ case EGSD_S_C_PSC + EVAX_OFFSET:
+ {
+ /* program section definition */
+
+ name = _bfd_vms_save_counted_string (vms_rec+12);
+ section = bfd_make_section (abfd, name);
+ if (!section)
+ return -1;
+ old_flags = bfd_getl16 (vms_rec + 6);
+ section->_raw_size = bfd_getl32 (vms_rec + 8); /* allocation */
+ new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, (int) section->_raw_size);
+ if (old_flags & EGPS_S_V_REL)
+ new_flags |= SEC_RELOC;
+ if (!bfd_set_section_flags (abfd, section, new_flags))
+ return -1;
+ section->alignment_power = vms_rec[4];
+ align_addr = (1 << section->alignment_power);
+ if ((base_addr % align_addr) != 0)
+ base_addr += (align_addr - (base_addr % align_addr));
+ section->vma = (bfd_vma)base_addr;
+ base_addr += section->_raw_size;
+ section->contents = ((unsigned char *)
+ bfd_malloc (section->_raw_size));
+ if (section->contents == NULL)
+ return -1;
+ memset (section->contents, 0, (size_t) section->_raw_size);
+ section->_cooked_size = section->_raw_size;
+#if VMS_DEBUG
+ vms_debug(4, "egsd psc %d (%s, flags %04x=%s) ",
+ section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
+ vms_debug(4, "%d bytes at 0x%08lx (mem %p)\n",
+ section->_raw_size, section->vma, section->contents);
+#endif
+ }
+ break;
+
+ case EGSD_S_C_SYM + EVAX_OFFSET:
+ {
+ /* symbol specification (definition or reference) */
+
+ symbol = _bfd_vms_make_empty_symbol (abfd);
+ if (symbol == 0)
+ return -1;
+
+ old_flags = bfd_getl16 (vms_rec + 6);
+ new_flags = BSF_NO_FLAGS;
+
+ if (old_flags & EGSY_S_V_WEAK)
+ new_flags |= BSF_WEAK;
+
+ if (vms_rec[6] & EGSY_S_V_DEF) /* symbol definition */
+ {
+ symbol->name =
+ _bfd_vms_save_counted_string (vms_rec+32);
+ if (old_flags & EGSY_S_V_NORM)
+ { /* proc def */
+ new_flags |= BSF_FUNCTION;
+ }
+ symbol->value = bfd_getl64 (vms_rec+8);
+ symbol->section = (asection *)((unsigned long) bfd_getl32 (vms_rec+28));
+#if VMS_DEBUG
+ vms_debug(4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
+ symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
+#endif
+ }
+ else /* symbol reference */
+ {
+ symbol->name =
+ _bfd_vms_save_counted_string (vms_rec+8);
+#if VMS_DEBUG
+ vms_debug(4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
+ symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
+#endif
+ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
+ }
+
+ symbol->flags = new_flags;
+
+ /* save symbol in vms_symbol_table */
+
+ entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), symbol->name, true, false);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ if (entry->symbol != (asymbol *)NULL)
+ { /* FIXME ?, DEC C generates this */
+#if VMS_DEBUG
+ vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
+#endif
+ }
+ else
+ {
+ entry->symbol = symbol;
+ PRIV(gsd_sym_count)++;
+ abfd->symcount++;
+ }
+ }
+ break;
+
+ case EGSD_S_C_IDC + EVAX_OFFSET:
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type);
+ bfd_set_error (bfd_error_bad_value);
+ return -1;
+
+ } /* switch */
+
+ PRIV(rec_size) -= gsd_size;
+ PRIV(vms_rec) += gsd_size;
+
+ } /* while (recsize > 0) */
+
+ if (abfd->symcount > 0)
+ abfd->flags |= HAS_SYMS;
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------*/
+/* output routines */
+
+/* Write section and symbol directory of bfd abfd */
+
+int
+_bfd_vms_write_gsd (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ asection *section;
+ asymbol *symbol;
+ int symnum;
+ int last_index = -1;
+ char dummy_name[10];
+ char *sname;
+ flagword new_flags, old_flags;
+ char *nptr, *uptr;
+
+#if VMS_DEBUG
+ vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
+#endif
+
+ /* output sections */
+
+ section = abfd->sections;
+#if VMS_DEBUG
+ vms_debug (3, "%d sections found\n", abfd->section_count);
+#endif
+
+ /* egsd is quadword aligned */
+
+ _bfd_vms_output_alignment (abfd, 8);
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_push (abfd); /* prepare output for subrecords */
+
+ while (section != 0)
+ {
+#if VMS_DEBUG
+ vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);
+#endif
+
+ /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */
+ if (_bfd_vms_output_check (abfd, 64) < 0)
+ {
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_push (abfd); /* prepare output for subrecords */
+ }
+
+ /* Create dummy sections to keep consecutive indices */
+
+ while (section->index - last_index > 1)
+ {
+#if VMS_DEBUG
+ vms_debug (3, "index %d, last %d\n", section->index, last_index);
+#endif
+ _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
+ _bfd_vms_output_short (abfd, 0);
+ _bfd_vms_output_short (abfd, 0);
+ _bfd_vms_output_long (abfd, 0);
+ sprintf (dummy_name, ".DUMMY%02d", last_index);
+ _bfd_vms_output_counted (abfd, dummy_name);
+ _bfd_vms_output_flush (abfd);
+ last_index++;
+ }
+
+ /* Don't know if this is neccesary for the linker but for now it keeps
+ vms_slurp_gsd happy */
+
+ sname = (char *)section->name;
+ if (*sname == '.')
+ {
+ sname++;
+ if ((*sname == 't') && (strcmp (sname, "text") == 0))
+ sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
+ else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
+ sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
+ else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
+ sname = EVAX_BSS_NAME;
+ else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
+ sname = EVAX_LINK_NAME;
+ else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
+ sname = EVAX_READONLY_NAME;
+ else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
+ sname = EVAX_LITERAL_NAME;
+ else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
+ sname = EVAX_COMMON_NAME;
+ else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
+ sname = EVAX_LOCAL_NAME;
+ }
+ else
+ sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
+
+ _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
+ _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
+ if (bfd_is_com_section (section))
+ {
+ new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM);
+ }
+ else
+ {
+ new_flags = vms_esecflag_by_name (evax_section_flags, sname, section->_raw_size);
+ }
+ _bfd_vms_output_short (abfd, new_flags);
+ _bfd_vms_output_long (abfd, section->_raw_size);
+ _bfd_vms_output_counted (abfd, sname);
+ _bfd_vms_output_flush (abfd);
+
+ last_index = section->index;
+ section = section->next;
+ }
+
+ /* output symbols */
+
+#if VMS_DEBUG
+ vms_debug (3, "%d symbols found\n", abfd->symcount);
+#endif
+
+ bfd_set_start_address (abfd, (bfd_vma)-1);
+
+ for (symnum = 0; symnum < abfd->symcount; symnum++)
+ {
+
+ symbol = abfd->outsymbols[symnum];
+ if (*(symbol->name) == '_')
+ {
+ if (strcmp (symbol->name, "__main") == 0)
+ bfd_set_start_address (abfd, (bfd_vma)symbol->value);
+ }
+ old_flags = symbol->flags;
+
+ if (old_flags & BSF_FILE)
+ continue;
+
+ if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */
+ && (!bfd_is_und_section (symbol->section))) /* and not xref */
+ continue; /* dont output */
+
+ /* 13 bytes egsd, max 64 chars name -> should be 77 bytes */
+
+ if (_bfd_vms_output_check (abfd, 80) < 0)
+ {
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_push (abfd); /* prepare output for subrecords */
+ }
+
+ _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
+
+ _bfd_vms_output_short (abfd, 0); /* data type, alignment */
+
+ new_flags = 0;
+
+ if (old_flags & BSF_WEAK)
+ new_flags |= EGSY_S_V_WEAK;
+ if (bfd_is_com_section (symbol->section)) /* .comm */
+ new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
+
+ if (old_flags & BSF_FUNCTION)
+ {
+ new_flags |= EGSY_S_V_NORM;
+ new_flags |= EGSY_S_V_REL;
+ }
+ if (old_flags & (BSF_GLOBAL|BSF_WEAK))
+ {
+ new_flags |= EGSY_S_V_DEF;
+ if (!bfd_is_abs_section (symbol->section))
+ new_flags |= EGSY_S_V_REL;
+ }
+ _bfd_vms_output_short (abfd, new_flags);
+
+ if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */
+ {
+ if (old_flags & BSF_FUNCTION)
+ {
+ _bfd_vms_output_quad (abfd, symbol->value);
+ _bfd_vms_output_quad (abfd,
+ ((asymbol *)(symbol->udata.p))->value);
+ _bfd_vms_output_long (abfd,
+ (((asymbol *)(symbol->udata.p))
+ ->section->index));
+ _bfd_vms_output_long (abfd, symbol->section->index);
+ }
+ else
+ {
+ _bfd_vms_output_quad (abfd, symbol->value); /* L_VALUE */
+ _bfd_vms_output_quad (abfd, 0); /* L_CODE_ADDRESS */
+ _bfd_vms_output_long (abfd, 0); /* L_CA_PSINDX */
+ _bfd_vms_output_long (abfd, symbol->section->index);/* L_PSINDX */
+ }
+ }
+ _bfd_vms_output_counted (abfd, _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
+
+ _bfd_vms_output_flush (abfd);
+
+ }
+
+ _bfd_vms_output_alignment (abfd, 8);
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+
+ return 0;
+}
diff --git a/bfd/vms-hdr.c b/bfd/vms-hdr.c
new file mode 100644
index 00000000000..01d20aabefa
--- /dev/null
+++ b/bfd/vms-hdr.c
@@ -0,0 +1,461 @@
+/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ HDR record handling functions
+ EMH record handling functions
+ and
+ EOM record handling functions
+ EEOM record handling functions
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+/*---------------------------------------------------------------------------*/
+
+
+/* Read & process emh record
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_hdr (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ unsigned char *ptr;
+ unsigned char *vms_rec;
+ int subtype;
+
+ vms_rec = PRIV(vms_rec);
+
+#if VMS_DEBUG
+ vms_debug(2, "HDR/EMH\n");
+#endif
+
+ switch (objtype)
+ {
+ case OBJ_S_C_HDR:
+ subtype = vms_rec[1];
+ break;
+ case EOBJ_S_C_EMH:
+ subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
+ break;
+ default:
+ subtype = -1;
+ }
+
+#if VMS_DEBUG
+ vms_debug(3, "subtype %d\n", subtype);
+#endif
+
+ switch (subtype)
+ {
+
+ case MHD_S_C_MHD:
+ /*
+ * module header
+ */
+ PRIV(hdr_data).hdr_b_strlvl = vms_rec[2];
+ PRIV(hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
+ PRIV(hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
+ ptr = vms_rec + 5 + vms_rec[5] + 1;
+ PRIV(hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
+ ptr += *ptr + 1;
+ PRIV(hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
+
+ break;
+
+ case MHD_S_C_LNM:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
+ break;
+
+ case MHD_S_C_SRC:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
+ break;
+
+ case MHD_S_C_TTL:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
+ break;
+
+ case MHD_S_C_CPR:
+ /*
+ *
+ */
+ break;
+
+ case MHD_S_C_MTC:
+ /*
+ *
+ */
+ break;
+
+ case MHD_S_C_GTX:
+ /*
+ *
+ */
+ break;
+
+ case EMH_S_C_MHD + EVAX_OFFSET:
+ /*
+ * module header
+ */
+ PRIV(hdr_data).hdr_b_strlvl = vms_rec[6];
+ PRIV(hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
+ PRIV(hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
+ PRIV(hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
+ PRIV(hdr_data).hdr_t_name =
+ _bfd_vms_save_counted_string (vms_rec + 20);
+ ptr = vms_rec + 20 + vms_rec[20] + 1;
+ PRIV(hdr_data).hdr_t_version =
+ _bfd_vms_save_counted_string (ptr);
+ ptr += *ptr + 1;
+ PRIV(hdr_data).hdr_t_date =
+ _bfd_vms_save_sized_string (ptr, 17);
+
+ break;
+
+ case EMH_S_C_LNM + EVAX_OFFSET:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_lnm =
+ _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
+ break;
+
+ case EMH_S_C_SRC + EVAX_OFFSET:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_src =
+ _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
+ break;
+
+ case EMH_S_C_TTL + EVAX_OFFSET:
+ /*
+ *
+ */
+ PRIV(hdr_data).hdr_c_ttl =
+ _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
+ break;
+
+ case EMH_S_C_CPR + EVAX_OFFSET:
+ /*
+ *
+ */
+ break;
+
+ case EMH_S_C_MTC + EVAX_OFFSET:
+ /*
+ *
+ */
+ break;
+
+ case EMH_S_C_GTX + EVAX_OFFSET:
+ /*
+ *
+ */
+ break;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+
+ } /* switch */
+
+ return 0;
+}
+
+
+/*-----------------------------------------------------------------------------*/
+/* Output routines. */
+
+
+/* Manufacure a VMS like time on a unix based system.
+ stolen from obj-vms.c */
+
+static unsigned char *
+get_vms_time_string ()
+{
+ static unsigned char tbuf[18];
+#ifndef VMS
+#include <time.h>
+
+ char *pnt;
+ time_t timeb;
+ time (&timeb);
+ pnt = ctime (&timeb);
+ pnt[3] = 0;
+ pnt[7] = 0;
+ pnt[10] = 0;
+ pnt[16] = 0;
+ pnt[24] = 0;
+ sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
+#else
+#include <starlet.h>
+ struct
+ {
+ int Size;
+ unsigned char *Ptr;
+ } Descriptor;
+ Descriptor.Size = 17;
+ Descriptor.Ptr = tbuf;
+ SYS$ASCTIM (0, &Descriptor, 0, 0);
+#endif /* not VMS */
+
+#if VMS_DEBUG
+ vms_debug (6, "vmstimestring:'%s'\n", tbuf);
+#endif
+
+ return tbuf;
+}
+
+
+/* write object header for bfd abfd */
+
+int
+_bfd_vms_write_hdr (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ asymbol *symbol;
+ int symnum;
+ int had_case = 0;
+ int had_file = 0;
+
+
+#if VMS_DEBUG
+ vms_debug (2, "vms_write_hdr (%p)\n", abfd);
+#endif
+
+ _bfd_vms_output_alignment (abfd, 2);
+
+ /* MHD */
+
+ if (objtype == OBJ_S_C_HDR)
+ {
+ }
+ else
+ {
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
+ _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_long (abfd, 0);
+ _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
+ }
+
+ if (bfd_get_filename (abfd) != 0)
+ {
+ /* strip path and suffix information */
+
+ char *fname, *fout, *fptr;
+
+ fptr = bfd_get_filename (abfd);
+ fname = (char *) alloca (strlen (fptr) + 1);
+ strcpy (fname, fptr);
+ fout = strrchr (fname, ']');
+ if (fout == 0)
+ fout = strchr (fname, ':');
+ if (fout != 0)
+ fout++;
+ else
+ fout = fname;
+
+ /* strip .obj suffix */
+
+ fptr = strrchr (fname, '.');
+ if ((fptr != 0)
+ && (strcasecmp (fptr, ".OBJ") == 0))
+ *fptr = 0;
+
+ fptr = fout;
+ while (*fptr != 0)
+ {
+ if (islower (*fptr))
+ *fptr = toupper (*fptr);
+ fptr++;
+ if ((*fptr == ';')
+ || ((fptr - fout) > 31))
+ *fptr = 0;
+ }
+ _bfd_vms_output_counted (abfd, fout);
+ }
+ else
+ _bfd_vms_output_counted (abfd, "NONAME");
+
+ _bfd_vms_output_counted (abfd, BFD_VERSION);
+ _bfd_vms_output_dump (abfd, get_vms_time_string (), 17);
+ _bfd_vms_output_fill (abfd, 0, 17);
+ _bfd_vms_output_flush (abfd);
+
+ /* LMN */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
+ _bfd_vms_output_dump (abfd, (unsigned char *)"GAS proGIS", 10);
+ _bfd_vms_output_flush (abfd);
+
+ /* SRC */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
+
+ for (symnum = 0; symnum < abfd->symcount; symnum++)
+ {
+ symbol = abfd->outsymbols[symnum];
+
+ if (symbol->flags & BSF_FILE)
+ {
+ char *s;
+
+ if (strncmp ((char *)symbol->name, "<CASE:", 6) == 0)
+ {
+ PRIV(flag_hash_long_names) = symbol->name[6] - '0';
+ PRIV(flag_show_after_trunc) = symbol->name[7] - '0';
+
+ if (had_file)
+ break;
+ had_case = 1;
+ continue;
+ }
+
+ _bfd_vms_output_dump (abfd, (unsigned char *)symbol->name, strlen (symbol->name));
+ if (had_case)
+ break;
+ had_file = 1;
+ }
+ }
+
+ if (symnum == abfd->symcount)
+ _bfd_vms_output_dump (abfd, (unsigned char *)"noname", 6);
+
+ _bfd_vms_output_flush (abfd);
+
+ /* TTL */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
+ _bfd_vms_output_dump (abfd, (unsigned char *)"TTL", 3);
+ _bfd_vms_output_flush (abfd);
+
+ /* CPR */
+
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
+ _bfd_vms_output_dump (abfd,
+ (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
+ 39);
+ _bfd_vms_output_flush (abfd);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------*/
+
+/* Process EOM/EEOM record
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_eom (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ unsigned char *vms_rec;
+
+#if VMS_DEBUG
+ vms_debug(2, "EOM/EEOM\n");
+#endif
+
+ vms_rec = PRIV(vms_rec);
+
+ if ((objtype == OBJ_S_C_EOM)
+ || (objtype == OBJ_S_C_EOMW))
+ {
+ }
+ else
+ {
+ PRIV(eom_data).eom_l_total_lps = bfd_getl32 (vms_rec + 4);
+ PRIV(eom_data).eom_b_comcod = *(vms_rec + 8);
+ if (PRIV(eom_data).eom_b_comcod > 1)
+ {
+ (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
+ bfd_set_error (bfd_error_bad_value);
+ return -1;
+ }
+ PRIV(eom_data).eom_has_transfer = false;
+ if (PRIV(rec_size) > 10)
+ {
+ PRIV(eom_data).eom_has_transfer = true;
+ PRIV(eom_data).eom_b_tfrflg = *(vms_rec + 9);
+ PRIV(eom_data).eom_l_psindx = bfd_getl32 (vms_rec + 12);
+ PRIV(eom_data).eom_l_tfradr = bfd_getl32 (vms_rec + 16);
+
+ abfd->start_address = PRIV(eom_data).eom_l_tfradr;
+ }
+ }
+ return 0;
+}
+
+
+/* Write eom record for bfd abfd */
+
+int
+_bfd_vms_write_eom (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
+#endif
+
+ _bfd_vms_output_begin (abfd, objtype, -1);
+ _bfd_vms_output_long (abfd, (unsigned long)(PRIV(vms_linkage_index) >> 1));
+ _bfd_vms_output_byte (abfd, 0); /* completion code */
+ _bfd_vms_output_byte (abfd, 0); /* fill byte */
+
+ if (bfd_get_start_address (abfd) != (bfd_vma)-1)
+ {
+ asection *section;
+
+ section = bfd_get_section_by_name (abfd, ".link");
+ if (section == 0)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return -1;
+ }
+ _bfd_vms_output_short (abfd, 0);
+ _bfd_vms_output_long (abfd, (unsigned long)(section->index));
+ _bfd_vms_output_long (abfd,
+ (unsigned long) bfd_get_start_address (abfd));
+ _bfd_vms_output_long (abfd, 0);
+ }
+
+ _bfd_vms_output_end (abfd);
+ return 0;
+}
diff --git a/bfd/vms-misc.c b/bfd/vms-misc.c
new file mode 100644
index 00000000000..a5fdae4cc28
--- /dev/null
+++ b/bfd/vms-misc.c
@@ -0,0 +1,1145 @@
+/* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#if __STDC__
+#include <stdarg.h>
+#endif
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+/*-----------------------------------------------------------------------------*/
+#if VMS_DEBUG
+/* debug functions */
+
+/* debug function for all vms extensions
+ evaluates environment variable VMS_DEBUG for a
+ numerical value on the first call
+ all error levels below this value are printed
+
+ levels:
+ 1 toplevel bfd calls (functions from the bfd vector)
+ 2 functions called by bfd calls
+ ...
+ 9 almost everything
+
+ level is also identation level. Indentation is performed
+ if level > 0
+ */
+
+#if __STDC__
+void
+_bfd_vms_debug (int level, char *format, ...)
+{
+ static int min_level = -1;
+ static FILE *output = NULL;
+ char *eptr;
+ va_list args;
+ int abslvl = (level > 0)?level:-level;
+
+ if (min_level == -1)
+ {
+ if ((eptr = getenv("VMS_DEBUG")) != NULL)
+ {
+ min_level = atoi(eptr);
+ output = stderr;
+ }
+ else
+ min_level = 0;
+ }
+ if (output == NULL)
+ return;
+ if (abslvl > min_level)
+ return;
+
+ while(--level>0)
+ fprintf(output, " ");
+ va_start(args, format);
+ vfprintf(output, format, args);
+ fflush(output);
+ va_end(args);
+
+ return;
+}
+
+#else /* not __STDC__ */
+
+void
+_bfd_vms_debug (level, format, a1, a2, a3, a4, a5, a6)
+ int level;
+ char *format;
+ long a1; long a2; long a3;
+ long a4; long a5; long a6;
+{
+ static int min_level = -1;
+ static FILE *output = NULL;
+ char *eptr;
+
+ if (min_level == -1)
+ {
+ if ((eptr = getenv("VMS_DEBUG")) != NULL)
+ {
+ min_level = atoi(eptr);
+ output = stderr;
+ }
+ else
+ min_level = 0;
+ }
+ if (output == NULL)
+ return;
+ if (level > min_level)
+ return;
+
+ while(--level>0)
+ fprintf(output, " ");
+ fprintf(output, format, a1, a2, a3, a4, a5, a6);
+ fflush(output);
+
+ return;
+}
+#endif /* __STDC__ */
+
+
+/* a debug function
+ hex dump 'size' bytes starting at 'ptr' */
+
+void
+_bfd_hexdump (level, ptr, size, offset)
+ int level;
+ unsigned char *ptr;
+ int size;
+ int offset;
+{
+ unsigned char *lptr = ptr;
+ int count = 0;
+ long start = offset;
+
+ while (size-- > 0)
+ {
+ if ((count%16) == 0)
+ vms_debug (level, "%08lx:", start);
+ vms_debug (-level, " %02x", *ptr++);
+ count++;
+ start++;
+ if (size == 0)
+ {
+ while ((count%16) != 0)
+ {
+ vms_debug (-level, " ");
+ count++;
+ }
+ }
+ if ((count%16) == 0)
+ {
+ vms_debug (-level, " ");
+ while (lptr < ptr)
+ {
+ vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
+ lptr++;
+ }
+ vms_debug (-level, "\n");
+ }
+ }
+ if ((count%16) != 0)
+ vms_debug (-level, "\n");
+
+ return;
+}
+#endif
+
+
+/* hash functions
+
+ These are needed when reading an object file. */
+
+/* allocate new vms_hash_entry
+ keep the symbol name and a pointer to the bfd symbol in the table */
+
+struct bfd_hash_entry *
+_bfd_vms_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ vms_symbol_entry *ret;
+
+#if VMS_DEBUG
+ vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry, table, string);
+#endif
+
+ if (entry == (struct bfd_hash_entry *)NULL)
+ {
+ ret = (vms_symbol_entry *)
+ bfd_hash_allocate (table, sizeof (vms_symbol_entry));
+ if (ret == (vms_symbol_entry *) NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return (struct bfd_hash_entry *)NULL;
+ }
+ }
+
+ /* Call the allocation method of the base class. */
+
+ ret = (vms_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
+#endif
+
+ ret->symbol = (asymbol *)NULL;
+
+ return (struct bfd_hash_entry *)ret;
+}
+
+
+/* object file input functions */
+
+/* Return type and length from record header (buf) on Alpha. */
+
+void
+_bfd_vms_get_header_values (abfd, buf, type, length)
+ bfd *abfd;
+ unsigned char *buf;
+ int *type;
+ int *length;
+{
+ if (type != 0)
+ *type = bfd_getl16 (buf);
+ buf += 2;
+ if (length != 0)
+ *length = bfd_getl16 (buf);
+
+#if VMS_DEBUG
+ vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0));
+#endif
+
+
+ return;
+}
+
+
+/* Get next record from object file to vms_buf
+ set PRIV(buf_size) and return it
+
+ this is a little tricky since it should be portable.
+
+ the openVMS object file has 'variable length' which means that
+ read() returns data in chunks of (hopefully) correct and expected
+ size. The linker (and other tools on vms) depend on that. Unix doesn't
+ know about 'formatted' files, so reading and writing such an object
+ file in a unix environment is not trivial.
+
+ With the tool 'file' (available on all vms ftp sites), one
+ can view and change the attributes of a file. Changing from
+ 'variable length' to 'fixed length, 512 bytes' reveals the
+ record length at the first 2 bytes of every record. The same
+ happens during the transfer of object files from vms to unix,
+ at least with ucx, dec's implementation of tcp/ip.
+
+ The vms format repeats the length at bytes 2 & 3 of every record.
+
+ On the first call (file_format == FF_UNKNOWN) we check if
+ the first and the third byte pair (!) of the record match.
+ If they do it's an object file in an unix environment or with
+ wrong attributes (FF_FOREIGN), else we should be in a vms
+ environment where read() returns the record size (FF_NATIVE).
+
+ reading is always done in 2 steps.
+ first just the record header is read and the length extracted
+ by get_header_values
+ then the read buffer is adjusted and the remaining bytes are
+ read in.
+
+ all file i/o is always done on even file positions */
+
+int
+_bfd_vms_get_record (abfd)
+ bfd *abfd;
+{
+ int test_len, test_start, remaining;
+ unsigned char *vms_buf;
+
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_get_record\n");
+#endif
+
+ /* minimum is 6 bytes on Alpha
+ (2 bytes length, 2 bytes record id, 2 bytes length repeated)
+
+ on VAX there's no length information in the record
+ so start with OBJ_S_C_MAXRECSIZ */
+
+ if (PRIV(buf_size) == 0)
+ {
+ if (PRIV(is_vax))
+ {
+ PRIV(vms_buf) = (unsigned char *) malloc (OBJ_S_C_MAXRECSIZ);
+ PRIV(buf_size) = OBJ_S_C_MAXRECSIZ;
+ PRIV(file_format) = FF_VAX;
+ }
+ else
+ PRIV(vms_buf) = (unsigned char *) malloc (6);
+ }
+
+ vms_buf = PRIV(vms_buf);
+
+ if (vms_buf == 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+
+ switch (PRIV(file_format))
+ {
+ case FF_UNKNOWN:
+ case FF_FOREIGN:
+ test_len = 6; /* probe 6 bytes */
+ test_start = 2; /* where the record starts */
+ break;
+
+ case FF_NATIVE:
+ test_len = 4;
+ test_start = 0;
+ break;
+
+ case FF_VAX:
+ test_len = 0;
+ test_start = 0;
+ break;
+ }
+
+ /* skip odd alignment byte */
+
+ if (bfd_tell (abfd) & 1)
+ {
+ if (bfd_read (PRIV(vms_buf), 1, 1, abfd) != 1)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+ }
+
+ /* read the record header on Alpha. */
+
+ if ((test_len != 0)
+ && (bfd_read (PRIV(vms_buf), 1, test_len, abfd) != test_len))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* check file format on first call */
+
+ if (PRIV(file_format) == FF_UNKNOWN)
+ { /* record length repeats ? */
+ if ( (vms_buf[0] == vms_buf[4])
+ && (vms_buf[1] == vms_buf[5]))
+ {
+ PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */
+ test_start = 2;
+ }
+ else
+ {
+ PRIV(file_format) = FF_NATIVE; /* N: native environment */
+ test_start = 0;
+ }
+ }
+
+ if (PRIV(is_vax))
+ {
+ PRIV(rec_length) = bfd_read (vms_buf, 1, PRIV(buf_size), abfd);
+ if (PRIV(rec_length) <= 0)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+ PRIV(vms_rec) = vms_buf;
+ }
+ else /* Alpha */
+ {
+ /* extract vms record length */
+
+ _bfd_vms_get_header_values (abfd, vms_buf+test_start, NULL,
+ &PRIV(rec_length));
+
+ if (PRIV(rec_length) <= 0)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* that's what the linker manual says */
+
+ if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* adjust the buffer */
+
+ if (PRIV(rec_length) > PRIV(buf_size))
+ {
+ PRIV(vms_buf) = (unsigned char *) realloc (vms_buf, PRIV(rec_length));
+ vms_buf = PRIV(vms_buf);
+ if (vms_buf == 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return -1;
+ }
+ PRIV(buf_size) = PRIV(rec_length);
+ }
+
+ /* read the remaining record */
+
+ remaining = PRIV(rec_length) - test_len + test_start;
+
+#if VMS_DEBUG
+ vms_debug (10, "bfd_read remaining %d\n", remaining);
+#endif
+ if (bfd_read (vms_buf + test_len, 1, remaining, abfd) != remaining)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+ PRIV(vms_rec) = vms_buf + test_start;
+ }
+
+#if VMS_DEBUG
+ vms_debug (11, "bfd_read rec_length %d\n", PRIV(rec_length));
+#endif
+
+ return PRIV(rec_length);
+}
+
+
+/* get next vms record from file
+ update vms_rec and rec_length to new (remaining) values */
+
+int
+_bfd_vms_next_record (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
+ PRIV(rec_length), PRIV(rec_size));
+#endif
+
+ if (PRIV(rec_length) > 0)
+ {
+ PRIV(vms_rec) += PRIV(rec_size);
+ }
+ else
+ {
+ if (_bfd_vms_get_record (abfd) <= 0)
+ return -1;
+ }
+
+ if (PRIV(is_vax))
+ {
+ PRIV(rec_type) = *(PRIV(vms_rec));
+ PRIV(rec_size) = PRIV(rec_length);
+ }
+ else
+ {
+ _bfd_vms_get_header_values (abfd, PRIV(vms_rec), &PRIV(rec_type),
+ &PRIV(rec_size));
+ }
+ PRIV(rec_length) -= PRIV(rec_size);
+
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
+ PRIV(vms_rec), PRIV(rec_size), PRIV(rec_length),
+ PRIV(rec_type));
+#endif
+
+ return PRIV(rec_type);
+}
+
+
+
+/* Copy sized string (string with fixed length) to new allocated area
+ size is string length (size of record) */
+
+char *
+_bfd_vms_save_sized_string (str, size)
+ unsigned char *str;
+ int size;
+{
+ char *newstr = bfd_malloc (size + 1);
+
+ if (newstr == NULL)
+ return 0;
+ strncpy (newstr, (char *)str, size);
+ newstr[size] = 0;
+
+ return newstr;
+}
+
+/* Copy counted string (string with length at first byte) to new allocated area
+ ptr points to length byte on entry */
+
+char *
+_bfd_vms_save_counted_string (ptr)
+ unsigned char *ptr;
+{
+ int len = *ptr++;
+
+ return _bfd_vms_save_sized_string (ptr, len);
+}
+
+
+/* stack routines for vms ETIR commands */
+
+/* Push value and section index */
+
+void
+_bfd_vms_push (abfd, val, psect)
+ bfd *abfd;
+ uquad val;
+ int psect;
+{
+ static int last_psect;
+
+#if VMS_DEBUG
+ vms_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
+#endif
+
+ if (psect >= 0)
+ last_psect = psect;
+
+ PRIV(stack[PRIV(stackptr)]).value = val;
+ PRIV(stack[PRIV(stackptr)]).psect = last_psect;
+ PRIV(stackptr)++;
+ if (PRIV(stackptr) >= STACKSIZE)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV(stackptr));
+ exit (1);
+ }
+ return;
+}
+
+
+/* Pop value and section index */
+
+uquad
+_bfd_vms_pop (abfd, psect)
+ bfd *abfd;
+ int *psect;
+{
+ uquad value;
+
+ if (PRIV(stackptr) == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
+ exit (1);
+ }
+ PRIV(stackptr)--;
+ value = PRIV(stack[PRIV(stackptr)]).value;
+ if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
+ *psect = PRIV(stack[PRIV(stackptr)]).psect;
+
+#if VMS_DEBUG
+ vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
+#endif
+
+ return value;
+}
+
+
+/* object file output functions */
+
+/* GAS tends to write sections in little chunks (bfd_set_section_contents)
+ which we can't use directly. So we save the little chunks in linked
+ lists (one per section) and write them later. */
+
+/* Add a new vms_section structure to vms_section_table
+ - forward chaining - */
+
+static vms_section *
+add_new_contents (abfd, section)
+ bfd *abfd;
+ sec_ptr section;
+{
+ vms_section *sptr, *newptr;
+
+ sptr = PRIV(vms_section_table)[section->index];
+ if (sptr != NULL)
+ return sptr;
+
+ newptr = (vms_section *) bfd_malloc (sizeof (vms_section));
+ if (newptr == (vms_section *) NULL)
+ return NULL;
+ newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
+ if (newptr->contents == (unsigned char *)NULL)
+ return NULL;
+ newptr->offset = 0;
+ newptr->size = section->_raw_size;
+ newptr->next = 0;
+ PRIV(vms_section_table)[section->index] = newptr;
+ return newptr;
+}
+
+
+/* Save section data & offset to an vms_section structure
+ vms_section_table[] holds the vms_section chain */
+
+boolean
+_bfd_save_vms_section (abfd, section, data, offset, count)
+ bfd *abfd;
+ sec_ptr section;
+ PTR data;
+ file_ptr offset;
+ bfd_size_type count;
+{
+ vms_section *sptr;
+
+ if (section->index >= VMS_SECTION_COUNT)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ if (count == (bfd_size_type)0)
+ return true;
+ sptr = add_new_contents (abfd, section);
+ if (sptr == NULL)
+ return false;
+ memcpy (sptr->contents + offset, data, (size_t) count);
+
+ return true;
+}
+
+
+/* Get vms_section pointer to saved contents for section # index */
+
+vms_section *
+_bfd_get_vms_section (abfd, index)
+ bfd *abfd;
+ int index;
+{
+ if (index >= VMS_SECTION_COUNT)
+ {
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return NULL;
+ }
+ return PRIV(vms_section_table)[index];
+}
+
+
+/* Object output routines */
+
+/* Begin new record or record header
+ write 2 bytes rectype
+ write 2 bytes record length (filled in at flush)
+ write 2 bytes header type (ommitted if rechead == -1) */
+
+void
+_bfd_vms_output_begin (abfd, rectype, rechead)
+ bfd *abfd;
+ int rectype;
+ int rechead;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype,
+ rechead);
+#endif
+
+ _bfd_vms_output_short (abfd,rectype);
+
+ /* save current output position to fill in lenght later */
+
+ if (PRIV(push_level) > 0)
+ PRIV(length_pos) = PRIV(output_size);
+
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
+ PRIV(length_pos));
+#endif
+
+ _bfd_vms_output_short (abfd,0); /* placeholder for length */
+
+ if (rechead != -1)
+ _bfd_vms_output_short (abfd,rechead);
+
+ return;
+}
+
+
+/* Set record/subrecord alignment */
+
+void
+_bfd_vms_output_alignment (abfd, alignto)
+ bfd *abfd;
+ int alignto;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto);
+#endif
+
+ PRIV(output_alignment) = alignto;
+ return;
+}
+
+
+/* Prepare for subrecord fields */
+
+void
+_bfd_vms_output_push (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV(output_size));
+#endif
+
+ PRIV(push_level)++;
+ PRIV(pushed_size) = PRIV(output_size);
+ return;
+}
+
+
+/* End of subrecord fields */
+
+void
+_bfd_vms_output_pop (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
+#endif
+
+ _bfd_vms_output_flush (abfd);
+ PRIV(length_pos) = 2;
+
+#if VMS_DEBUG
+ vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV(length_pos));
+#endif
+
+ PRIV(pushed_size) = 0;
+ PRIV(push_level)--;
+ return;
+}
+
+
+/* Flush unwritten output, ends current record */
+
+void
+_bfd_vms_output_flush (abfd)
+ bfd *abfd;
+{
+ int real_size = PRIV(output_size);
+ int aligncount;
+ int length;
+
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
+ real_size, PRIV(pushed_size), PRIV(length_pos));
+#endif
+
+ if (PRIV(push_level) > 0)
+ length = real_size - PRIV(pushed_size);
+ else
+ length = real_size;
+
+ if (length == 0)
+ return;
+ aligncount = (PRIV(output_alignment)
+ - (length % PRIV(output_alignment))) % PRIV(output_alignment);
+
+#if VMS_DEBUG
+ vms_debug (6, "align: adding %d bytes\n", aligncount);
+#endif
+
+ while(aligncount-- > 0)
+ {
+ PRIV(output_buf)[real_size++] = 0;
+#if 0
+ /* this is why I *love* vms: inconsistency :-}
+ alignment is added to the subrecord length
+ but not to the record length */
+ if (PRIV(push_level) > 0)
+#endif
+ length++;
+ }
+
+ /* put length to buffer */
+ PRIV(output_size) = PRIV(length_pos);
+ _bfd_vms_output_short (abfd, (unsigned int)length);
+
+ if (PRIV(push_level) == 0)
+ {
+#ifndef VMS
+ /* write length first, see FF_FOREIGN in the input routines */
+ fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
+#endif
+ fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
+
+ PRIV(output_size) = 0;
+ }
+ else
+ {
+ PRIV(output_size) = real_size;
+ PRIV(pushed_size) = PRIV(output_size);
+ }
+
+ return;
+}
+
+
+/* End record output */
+
+void
+_bfd_vms_output_end (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_end\n");
+#endif
+
+ _bfd_vms_output_flush (abfd);
+
+ return;
+}
+
+
+/* check remaining buffer size
+
+ return what's left. */
+
+int
+_bfd_vms_output_check (abfd, size)
+ bfd *abfd;
+ int size;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_check(%d)\n", size);
+#endif
+
+ return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
+}
+
+
+/* Output byte (8 bit) value */
+
+void
+_bfd_vms_output_byte (abfd, value)
+ bfd *abfd;
+ unsigned int value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value);
+#endif
+
+ bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 1;
+ return;
+}
+
+
+/* Output short (16 bit) value */
+
+void
+_bfd_vms_output_short (abfd, value)
+ bfd *abfd;
+ unsigned int value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
+#endif
+
+ bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 2;
+ return;
+}
+
+
+/* Output long (32 bit) value */
+
+void
+_bfd_vms_output_long (abfd, value)
+ bfd *abfd;
+ unsigned long value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
+#endif
+
+ bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 4;
+ return;
+}
+
+
+/* Output quad (64 bit) value */
+
+void
+_bfd_vms_output_quad (abfd, value)
+ bfd *abfd;
+ uquad value;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value);
+#endif
+
+ bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
+ PRIV(output_size) += 8;
+ return;
+}
+
+
+/* Output c-string as counted string */
+
+void
+_bfd_vms_output_counted (abfd, value)
+ bfd *abfd;
+ char *value;
+{
+int len;
+
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_counted(%s)\n", value);
+#endif
+
+ len = strlen (value);
+ if (len == 0)
+ {
+ (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
+ return;
+ }
+ if (len > 255)
+ {
+ (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
+ return;
+ }
+ _bfd_vms_output_byte (abfd, len & 0xff);
+ _bfd_vms_output_dump (abfd, (unsigned char *)value, len);
+}
+
+
+/* Output character area */
+
+void
+_bfd_vms_output_dump (abfd, data, length)
+ bfd *abfd;
+ unsigned char *data;
+ int length;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_dump(%d)\n", length);
+#endif
+
+ if (length == 0)
+ return;
+
+ memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
+ PRIV(output_size) += length;
+
+ return;
+}
+
+
+/* Output count bytes of value */
+
+void
+_bfd_vms_output_fill (abfd, value, count)
+ bfd *abfd;
+ int value;
+ int count;
+{
+#if VMS_DEBUG
+ vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value, count);
+#endif
+
+ if (count == 0)
+ return;
+ memset (PRIV(output_buf) + PRIV(output_size), value, count);
+ PRIV(output_size) += count;
+
+ return;
+}
+
+/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
+
+static int
+hash_string (ptr)
+ const char *ptr;
+{
+ register const unsigned char *p = (unsigned char *) ptr;
+ register const unsigned char *end = p + strlen (ptr);
+ register unsigned char c;
+ register int hash = 0;
+
+ while (p != end)
+ {
+ c = *p++;
+ hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
+ }
+ return hash;
+}
+
+/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
+
+char *
+_bfd_vms_length_hash_symbol (abfd, in, maxlen)
+ bfd *abfd;
+ const char *in;
+ int maxlen;
+{
+ long int init;
+ long int result;
+ int in_len;
+ char *pnt = 0;
+ char *new_name;
+ const char *old_name;
+ int i;
+ static char outbuf[EOBJ_S_C_SYMSIZ+1];
+ char *out = outbuf;
+
+#if VMS_DEBUG
+ vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
+#endif
+
+ if (maxlen > EOBJ_S_C_SYMSIZ)
+ maxlen = EOBJ_S_C_SYMSIZ;
+
+ new_name = out; /* save this for later. */
+
+ /* We may need to truncate the symbol, save the hash for later. */
+
+ in_len = strlen (in);
+
+ result = (in_len > maxlen) ? hash_string (in) : 0;
+
+ old_name = in;
+
+ /* Do the length checking. */
+
+ if (in_len <= maxlen)
+ {
+ i = in_len;
+ }
+ else
+ {
+ if (PRIV(flag_hash_long_names))
+ i = maxlen-9;
+ else
+ i = maxlen;
+ }
+
+ strncpy (out, in, i);
+ in += i;
+ out += i;
+
+ if ((in_len > maxlen)
+ && PRIV(flag_hash_long_names))
+ sprintf (out, "_%08x", result);
+ else
+ *out = 0;
+
+#if VMS_DEBUG
+ vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
+#endif
+
+ if (in_len > maxlen
+ && PRIV(flag_hash_long_names)
+ && PRIV(flag_show_after_trunc))
+ printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
+
+ return outbuf;
+}
+
+
+/* Allocate and initialize a new symbol. */
+
+static asymbol *
+new_symbol (abfd, name)
+ bfd *abfd;
+ char *name;
+{
+ asymbol *symbol;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (7, "new_symbol %s\n", name);
+#endif
+
+ symbol = _bfd_vms_make_empty_symbol (abfd);
+ if (symbol == 0)
+ return symbol;
+ symbol->name = name;
+ symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
+
+ return symbol;
+}
+
+
+/* Allocate and enter a new private symbol. */
+
+vms_symbol_entry *
+_bfd_vms_enter_symbol (abfd, name)
+ bfd *abfd;
+ char *name;
+{
+ vms_symbol_entry *entry;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name);
+#endif
+
+ entry = (vms_symbol_entry *)
+ bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false);
+ if (entry == 0)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "creating hash entry for %s\n", name);
+#endif
+ entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, true, false);
+ if (entry != 0)
+ {
+ asymbol *symbol;
+ symbol = new_symbol (abfd, name);
+ if (symbol != 0)
+ {
+ entry->symbol = symbol;
+ PRIV(gsd_sym_count)++;
+ abfd->symcount++;
+ }
+ else
+ entry = 0;
+ }
+ else
+ (*_bfd_error_handler) (_("failed to enter %s"), name);
+ }
+ else
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "found hash entry for %s\n", name);
+#endif
+ }
+
+#if VMS_DEBUG
+ _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
+#endif
+ return entry;
+}
diff --git a/bfd/vms-tir.c b/bfd/vms-tir.c
new file mode 100644
index 00000000000..782f52bfc04
--- /dev/null
+++ b/bfd/vms-tir.c
@@ -0,0 +1,2489 @@
+/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ TIR record handling functions
+ ETIR record handling functions
+
+ go and read the openVMS linker manual (esp. appendix B)
+ if you don't know what's going on here :-)
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* The following type abbreviations are used:
+
+ cs counted string (ascii string with length byte)
+ by byte (1 byte)
+ sh short (2 byte, 16 bit)
+ lw longword (4 byte, 32 bit)
+ qw quadword (8 byte, 64 bit)
+ da data stream */
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset));
+static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset));
+static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));
+static void image_write_b PARAMS ((bfd *abfd, unsigned int value));
+static void image_write_w PARAMS ((bfd *abfd, unsigned int value));
+static void image_write_l PARAMS ((bfd *abfd, unsigned long value));
+static void image_write_q PARAMS ((bfd *abfd, uquad value));
+
+/*-----------------------------------------------------------------------------*/
+
+static int
+check_section (abfd, size)
+ bfd *abfd;
+ int size;
+{
+ int offset;
+
+ offset = PRIV(image_ptr) - PRIV(image_section)->contents;
+ if ((offset + size) > PRIV(image_section)->_raw_size)
+ {
+ PRIV(image_section)->contents = bfd_realloc (PRIV(image_section)->contents, offset + size);
+ if (PRIV(image_section)->contents == 0)
+ {
+ (*_bfd_error_handler) (_("No Mem !"));
+ return -1;
+ }
+ PRIV(image_section)->_raw_size = offset + size;
+ PRIV(image_ptr) = PRIV(image_section)->contents + offset;
+ }
+
+ return 0;
+}
+
+/* routines to fill sections contents during tir/etir read */
+
+/* Initialize image buffer pointer to be filled */
+
+static void
+image_set_ptr (abfd, psect, offset)
+ bfd *abfd;
+ int psect;
+ uquad offset;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
+ psect, PRIV(sections)[psect]->name, offset);
+#endif
+
+ PRIV(image_ptr) = PRIV(sections)[psect]->contents + offset;
+ PRIV(image_section) = PRIV(sections)[psect];
+ return;
+}
+
+
+/* Increment image buffer pointer by offset */
+
+static void
+image_inc_ptr (abfd, offset)
+ bfd *abfd;
+ uquad offset;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
+#endif
+
+ PRIV(image_ptr) += offset;
+
+ return;
+}
+
+
+/* Dump multiple bytes to section image */
+
+static void
+image_dump (abfd, ptr, size, offset)
+ bfd *abfd;
+ unsigned char *ptr;
+ int size;
+ int offset;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size, PRIV(image_ptr));
+ _bfd_hexdump (9, ptr, size, offset);
+#endif
+
+ if (PRIV(is_vax) && check_section (abfd, size))
+ return;
+
+ while (size-- > 0)
+ *PRIV(image_ptr)++ = *ptr++;
+ return;
+}
+
+
+/* Write byte to section image */
+
+static void
+image_write_b (abfd, value)
+ bfd *abfd;
+ unsigned int value;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "image_write_b(%02x)\n", (int)value);
+#endif
+
+ if (PRIV(is_vax) && check_section (abfd, 1))
+ return;
+
+ *PRIV(image_ptr)++ = (value & 0xff);
+ return;
+}
+
+
+/* Write 2-byte word to image */
+
+static void
+image_write_w (abfd, value)
+ bfd *abfd;
+ unsigned int value;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "image_write_w(%04x)\n", (int)value);
+#endif
+
+ if (PRIV(is_vax) && check_section (abfd, 2))
+ return;
+
+ bfd_putl16 (value, PRIV(image_ptr));
+ PRIV(image_ptr) += 2;
+
+ return;
+}
+
+
+/* Write 4-byte long to image */
+
+static void
+image_write_l (abfd, value)
+ bfd *abfd;
+ unsigned long value;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
+#endif
+
+ if (PRIV(is_vax) && check_section (abfd, 4))
+ return;
+
+ bfd_putl32 (value, PRIV(image_ptr));
+ PRIV(image_ptr) += 4;
+
+ return;
+}
+
+
+/* Write 8-byte quad to image */
+
+static void
+image_write_q (abfd, value)
+ bfd *abfd;
+ uquad value;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
+#endif
+
+ if (PRIV(is_vax) && check_section (abfd, 8))
+ return;
+
+ bfd_putl64 (value, PRIV(image_ptr));
+ PRIV(image_ptr) += 8;
+
+ return;
+}
+
+
+#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
+
+/* etir_sta
+
+ vms stack commands
+
+ handle sta_xxx commands in etir section
+ ptr points to data area in record
+
+ see table B-8 of the openVMS linker manual */
+
+static boolean
+etir_sta (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* stack */
+
+ /* stack global
+ arg: cs symbol name
+
+ stack 32 bit value of symbol (high bits set to 0) */
+
+ case ETIR_S_C_STA_GBL:
+ {
+ char *name;
+ vms_symbol_entry *entry;
+
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = (vms_symbol_entry *)
+ bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "ETIR_S_C_STA_GBL: no symbol \"%s\"\n", name);
+#endif
+ _bfd_vms_push (abfd, (uquad)0, -1);
+ }
+ else
+ {
+ _bfd_vms_push (abfd, (uquad)(entry->symbol->value), -1);
+ }
+ }
+ break;
+
+ /* stack longword
+ arg: lw value
+
+ stack 32 bit value, sign extend to 64 bit */
+
+ case ETIR_S_C_STA_LW:
+ _bfd_vms_push (abfd, (uquad)bfd_getl32 (ptr), -1);
+ break;
+
+ /* stack global
+ arg: qw value
+
+ stack 64 bit value of symbol */
+
+ case ETIR_S_C_STA_QW:
+ _bfd_vms_push (abfd, (uquad)bfd_getl64(ptr), -1);
+ break;
+
+ /* stack psect base plus quadword offset
+ arg: lw section index
+ qw signed quadword offset (low 32 bits)
+
+ stack qw argument and section index
+ (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB) */
+
+ case ETIR_S_C_STA_PQ:
+ {
+ uquad dummy;
+ int psect;
+
+ psect = bfd_getl32 (ptr);
+ if (psect >= PRIV(section_count))
+ {
+ (*_bfd_error_handler) (_("Bad section index in ETIR_S_C_STA_PQ"));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ dummy = bfd_getl64 (ptr+4);
+ _bfd_vms_push (abfd, dummy, psect);
+ }
+ break;
+
+ /* all not supported */
+
+ case ETIR_S_C_STA_LI:
+ case ETIR_S_C_STA_MOD:
+ case ETIR_S_C_STA_CKARG:
+
+ (*_bfd_error_handler) (_("Unsupported STA cmd %d"), cmd);
+ return false;
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STA cmd %d"), cmd);
+ return false;
+ break;
+ }
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_sta true\n");
+#endif
+ return true;
+}
+
+
+/*
+ etir_sto
+
+ vms store commands
+
+ handle sto_xxx commands in etir section
+ ptr points to data area in record
+
+ see table B-9 of the openVMS linker manual */
+
+static boolean
+etir_sto (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ uquad dummy;
+ int psect;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+
+ /* store byte: pop stack, write byte
+ arg: - */
+
+ case ETIR_S_C_STO_B:
+ dummy = _bfd_vms_pop (abfd, &psect);
+#if 0
+ if (is_share) /* FIXME */
+ (*_bfd_error_handler) ("ETIR_S_C_STO_B: byte fixups not supported");
+#endif
+ image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
+ break;
+
+ /* store word: pop stack, write word
+ arg: - */
+
+ case ETIR_S_C_STO_W:
+ dummy = _bfd_vms_pop (abfd, &psect);
+#if 0
+ if (is_share) /* FIXME */
+ (*_bfd_error_handler) ("ETIR_S_C_STO_B: word fixups not supported");
+#endif
+ image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
+ break;
+
+ /* store longword: pop stack, write longword
+ arg: - */
+
+ case ETIR_S_C_STO_LW:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ dummy += (PRIV(sections)[psect])->vma;
+ image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
+ break;
+
+ /* store quadword: pop stack, write quadword
+ arg: - */
+
+ case ETIR_S_C_STO_QW:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ dummy += (PRIV(sections)[psect])->vma;
+ image_write_q (abfd, dummy); /* FIXME: check top bits */
+ break;
+
+ /* store immediate repeated: pop stack for repeat count
+ arg: lw byte count
+ da data */
+
+ case ETIR_S_C_STO_IMMR:
+ {
+ unsigned long size;
+
+ size = bfd_getl32 (ptr);
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ while (dummy-- > 0L)
+ image_dump (abfd, ptr+4, size, 0);
+ }
+ break;
+
+ /* store global: write symbol value
+ arg: cs global symbol name */
+
+ case ETIR_S_C_STO_GBL:
+ {
+ vms_symbol_entry *entry;
+ char *name;
+
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_GBL: no symbol \"%s\""),
+ name);
+ return false;
+ }
+ else
+ image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
+ }
+ break;
+
+ /* store code address: write address of entry point
+ arg: cs global symbol name (procedure) */
+
+ case ETIR_S_C_STO_CA:
+ {
+ vms_symbol_entry *entry;
+ char *name;
+
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_CA: no symbol \"%s\""),
+ name);
+ return false;
+ }
+ else
+ image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
+ }
+ break;
+
+ /* not supported */
+
+ case ETIR_S_C_STO_RB:
+ case ETIR_S_C_STO_AB:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_RB/AB: Not supported"));
+ break;
+
+ /* store offset to psect: pop stack, add low 32 bits to base of psect
+ arg: - */
+
+ case ETIR_S_C_STO_OFF:
+ {
+ uquad q;
+ int psect;
+
+ q = _bfd_vms_pop (abfd, &psect);
+ q += (PRIV(sections)[psect])->vma;
+ image_write_q (abfd, q);
+ }
+ break;
+
+ /* store immediate
+ arg: lw count of bytes
+ da data */
+
+ case ETIR_S_C_STO_IMM:
+ {
+ int size;
+
+ size = bfd_getl32 (ptr);
+ image_dump (abfd, ptr+4, size, 0);
+ }
+ break;
+
+ /* this code is 'reserved to digital' according to the openVMS linker manual,
+ however it is generated by the DEC C compiler and defined in the include file.
+ FIXME, since the following is just a guess
+ store global longword: store 32bit value of symbol
+ arg: cs symbol name */
+
+ case ETIR_S_C_STO_GBL_LW:
+ {
+ vms_symbol_entry *entry;
+ char *name;
+
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false);
+ if (entry == (vms_symbol_entry *)NULL)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "ETIR_S_C_STO_GBL_LW: no symbol \"%s\"\n", name);
+#endif
+ image_write_l (abfd, (unsigned long)0); /* FIXME, reloc */
+ }
+ else
+ image_write_l (abfd, (unsigned long)(entry->symbol->value)); /* FIXME, reloc */
+ }
+ break;
+
+ /* not supported */
+
+ case ETIR_S_C_STO_LP_PSB:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_LP_PSB: Not supported"));
+ break;
+
+ /* */
+
+ case ETIR_S_C_STO_HINT_GBL:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_GBL: not implemented"));
+ break;
+
+ /* */
+
+ case ETIR_S_C_STO_HINT_PS:
+ (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_PS: not implemented"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STO cmd %d"), cmd);
+ break;
+ }
+
+ return true;
+}
+
+/* stack operator commands
+ all 32 bit signed arithmetic
+ all word just like a stack calculator
+ arguments are popped from stack, results are pushed on stack
+
+ see table B-10 of the openVMS linker manual */
+
+static boolean
+etir_opr (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ long op1, op2;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* operation */
+
+ /* no-op */
+
+ case ETIR_S_C_OPR_NOP:
+ break;
+
+ /* add */
+
+ case ETIR_S_C_OPR_ADD:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 + op2), -1);
+ break;
+
+ /* subtract */
+
+ case ETIR_S_C_OPR_SUB:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op2 - op1), -1);
+ break;
+
+ /* multiply */
+
+ case ETIR_S_C_OPR_MUL:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 * op2), -1);
+ break;
+
+ /* divide */
+
+ case ETIR_S_C_OPR_DIV:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (op2 == 0)
+ _bfd_vms_push (abfd, (uquad)0L, -1);
+ else
+ _bfd_vms_push (abfd, (uquad)(op2 / op1), -1);
+ break;
+
+ /* logical and */
+
+ case ETIR_S_C_OPR_AND:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 & op2), -1);
+ break;
+
+ /* logical inclusive or */
+
+ case ETIR_S_C_OPR_IOR:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 | op2), -1);
+ break;
+
+ /* logical exclusive or */
+
+ case ETIR_S_C_OPR_EOR:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 ^ op2), -1);
+ break;
+
+ /* negate */
+
+ case ETIR_S_C_OPR_NEG:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(-op1), -1);
+ break;
+
+ /* complement */
+
+ case ETIR_S_C_OPR_COM:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)(op1 ^ -1L), -1);
+ break;
+
+ /* insert field */
+
+ case ETIR_S_C_OPR_INSV:
+ (void)_bfd_vms_pop (abfd, NULL);
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_INSV: Not supported"));
+ break;
+
+ /* arithmetic shift */
+
+ case ETIR_S_C_OPR_ASH:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (op2 < 0) /* shift right */
+ op1 >>= -op2;
+ else /* shift left */
+ op1 <<= op2;
+ _bfd_vms_push (abfd, (uquad)op1, -1);
+ break;
+
+ /* unsigned shift */
+
+ case ETIR_S_C_OPR_USH:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_USH: Not supported"));
+ break;
+
+ /* rotate */
+
+ case ETIR_S_C_OPR_ROT:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_ROT: Not supported"));
+ break;
+
+ /* select */
+
+ case ETIR_S_C_OPR_SEL:
+ if ((long)_bfd_vms_pop (abfd, NULL) & 0x01L)
+ (void)_bfd_vms_pop (abfd, NULL);
+ else
+ {
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ (void)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (uquad)op1, -1);
+ }
+ break;
+
+ /* redefine symbol to current location */
+
+ case ETIR_S_C_OPR_REDEF:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_REDEF: Not supported"));
+ break;
+
+ /* define a literal */
+
+ case ETIR_S_C_OPR_DFLIT:
+ (*_bfd_error_handler) (_("ETIR_S_C_OPR_DFLIT: Not supported"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved OPR cmd %d"), cmd);
+ break;
+ }
+
+ return true;
+}
+
+
+/* control commands
+
+ see table B-11 of the openVMS linker manual */
+
+static boolean
+etir_ctl (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ uquad dummy;
+ int psect;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* set relocation base: pop stack, set image location counter
+ arg: - */
+
+ case ETIR_S_C_CTL_SETRB:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_set_ptr (abfd, psect, dummy);
+ break;
+
+ /* augment relocation base: increment image location counter by offset
+ arg: lw offset value */
+
+ case ETIR_S_C_CTL_AUGRB:
+ dummy = bfd_getl32 (ptr);
+ image_inc_ptr (abfd, dummy);
+ break;
+
+ /* define location: pop index, save location counter under index
+ arg: - */
+
+ case ETIR_S_C_CTL_DFLOC:
+ dummy = _bfd_vms_pop (abfd, NULL);
+ /* FIXME */
+ break;
+
+ /* set location: pop index, restore location counter from index
+ arg: - */
+
+ case ETIR_S_C_CTL_STLOC:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ /* FIXME */
+ break;
+
+ /* stack defined location: pop index, push location counter from index
+ arg: - */
+
+ case ETIR_S_C_CTL_STKDL:
+ dummy = _bfd_vms_pop (abfd, &psect);
+ /* FIXME */
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved CTL cmd %d"), cmd);
+ break;
+ }
+ return true;
+}
+
+
+/* store conditional commands
+
+ see table B-12 and B-13 of the openVMS linker manual */
+
+static boolean
+etir_stc (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ switch (cmd)
+ {
+ /* 200 Store-conditional Linkage Pair
+ arg: */
+
+ case ETIR_S_C_STC_LP:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_LP: not supported"));
+ break;
+
+ /* 201 Store-conditional Linkage Pair with Procedure Signature
+ arg: lw linkage index
+ cs procedure name
+ by signature length
+ da signature */
+
+ case ETIR_S_C_STC_LP_PSB:
+ image_inc_ptr (abfd, 16); /* skip entry,procval */
+ break;
+
+ /* 202 Store-conditional Address at global address
+ arg: lw linkage index
+ cs global name */
+
+ case ETIR_S_C_STC_GBL:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_GBL: not supported"));
+ break;
+
+ /* 203 Store-conditional Code Address at global address
+ arg: lw linkage index
+ cs procedure name */
+
+ case ETIR_S_C_STC_GCA:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_GCA: not supported"));
+ break;
+
+ /* 204 Store-conditional Address at psect + offset
+ arg: lw linkage index
+ lw psect index
+ qw offset */
+
+ case ETIR_S_C_STC_PS:
+ (*_bfd_error_handler) (_("ETIR_S_C_STC_PS: not supported"));
+ break;
+
+ /* 205 Store-conditional NOP at address of global
+ arg: */
+
+ case ETIR_S_C_STC_NOP_GBL:
+
+ /* 206 Store-conditional NOP at pect + offset
+ arg: */
+
+ case ETIR_S_C_STC_NOP_PS:
+
+ /* 207 Store-conditional BSR at global address
+ arg: */
+
+ case ETIR_S_C_STC_BSR_GBL:
+
+ /* 208 Store-conditional BSR at pect + offset
+ arg: */
+
+ case ETIR_S_C_STC_BSR_PS:
+
+ /* 209 Store-conditional LDA at global address
+ arg: */
+
+ case ETIR_S_C_STC_LDA_GBL:
+
+ /* 210 Store-conditional LDA at psect + offset
+ arg: */
+
+ case ETIR_S_C_STC_LDA_PS:
+
+ /* 211 Store-conditional BSR or Hint at global address
+ arg: */
+
+ case ETIR_S_C_STC_BOH_GBL:
+
+ /* 212 Store-conditional BSR or Hint at pect + offset
+ arg: */
+
+ case ETIR_S_C_STC_BOH_PS:
+
+ /* 213 Store-conditional NOP,BSR or HINT at global address
+ arg: */
+
+ case ETIR_S_C_STC_NBH_GBL:
+
+ /* 214 Store-conditional NOP,BSR or HINT at psect + offset
+ arg: */
+
+ case ETIR_S_C_STC_NBH_PS:
+/* FIXME (*_bfd_error_handler) ("ETIR_S_C_STC_xx: (%d) not supported", cmd); */
+ break;
+
+ default:
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "Reserved STC cmd %d", cmd);
+#endif
+ break;
+ }
+ return true;
+}
+
+
+static asection *
+new_section (abfd, idx)
+ bfd *abfd;
+ int idx;
+{
+ asection *section;
+ char sname[16];
+ char *name;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "new_section %d\n", idx);
+#endif
+ sprintf (sname, SECTION_NAME_TEMPLATE, idx);
+
+ name = bfd_malloc (strlen (sname) + 1);
+ if (name == 0)
+ return 0;
+ strcpy (name, sname);
+
+ section = bfd_malloc (sizeof (asection));
+ if (section == 0)
+ {
+#if VMS_DEBUG
+ _bfd_vms_debug (6, "bfd_make_section (%s) failed", name);
+#endif
+ return 0;
+ }
+
+ section->_raw_size = 0;
+ section->vma = 0;
+ section->contents = 0;
+ section->_cooked_size = 0;
+ section->name = name;
+ section->index = idx;
+
+ return section;
+}
+
+
+static int
+alloc_section (abfd, idx)
+ bfd *abfd;
+ int idx;
+{
+ asection *section;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "alloc_section %d\n", idx);
+#endif
+
+ PRIV(sections) = ((asection **)
+ bfd_realloc (PRIV(sections), (idx+1) * sizeof (asection *)));
+ if (PRIV(sections) == 0)
+ return -1;
+
+ while (PRIV(section_count) <= idx)
+ {
+ PRIV(sections)[PRIV(section_count)] = new_section (abfd, PRIV(section_count));
+ if (PRIV(sections)[PRIV(section_count)] == 0)
+ return -1;
+ PRIV(section_count)++;
+ }
+
+ return 0;
+}
+
+
+/*
+ * tir_sta
+ *
+ * vax stack commands
+ *
+ * handle sta_xxx commands in tir section
+ * ptr points to data area in record
+ *
+ * see table 7-3 of the VAX/VMS linker manual
+ */
+
+static unsigned char *
+tir_sta (bfd *abfd, unsigned char *ptr)
+{
+ int cmd = *ptr++;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "tir_sta %d\n", cmd);
+#endif
+
+ switch (cmd)
+ {
+ /* stack */
+ case TIR_S_C_STA_GBL:
+ /*
+ * stack global
+ * arg: cs symbol name
+ *
+ * stack 32 bit value of symbol (high bits set to 0)
+ */
+ {
+ char *name;
+ vms_symbol_entry *entry;
+
+ name = _bfd_vms_save_counted_string (ptr);
+
+ entry = _bfd_vms_enter_symbol (abfd, name);
+ if (entry == (vms_symbol_entry *)NULL)
+ return 0;
+
+ _bfd_vms_push (abfd, (unsigned long)(entry->symbol->value), -1);
+ ptr += *ptr + 1;
+ }
+ break;
+
+ case TIR_S_C_STA_SB:
+ /*
+ * stack signed byte
+ * arg: by value
+ *
+ * stack byte value, sign extend to 32 bit
+ */
+ _bfd_vms_push (abfd, (long)*ptr++, -1);
+ break;
+
+ case TIR_S_C_STA_SW:
+ /*
+ * stack signed short word
+ * arg: sh value
+ *
+ * stack 16 bit value, sign extend to 32 bit
+ */
+ _bfd_vms_push (abfd, (long)bfd_getl16(ptr), -1);
+ ptr += 2;
+ break;
+
+ case TIR_S_C_STA_LW:
+ /*
+ * stack signed longword
+ * arg: lw value
+ *
+ * stack 32 bit value
+ */
+ _bfd_vms_push (abfd, (long)bfd_getl32 (ptr), -1);
+ ptr += 4;
+ break;
+
+ case TIR_S_C_STA_PB:
+ case TIR_S_C_STA_WPB:
+ /*
+ * stack psect base plus byte offset (word index)
+ * arg: by section index
+ * (sh section index)
+ * by signed byte offset
+ *
+ */
+ {
+ unsigned long dummy;
+ int psect;
+
+ if (cmd == TIR_S_C_STA_PB)
+ psect = *ptr++;
+ else
+ {
+ psect = bfd_getl16(ptr);
+ ptr += 2;
+ }
+
+ if (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+
+ dummy = (long)*ptr++;
+ dummy += (PRIV(sections)[psect])->vma;
+ _bfd_vms_push (abfd, dummy, psect);
+ }
+ break;
+
+ case TIR_S_C_STA_PW:
+ case TIR_S_C_STA_WPW:
+ /*
+ * stack psect base plus word offset (word index)
+ * arg: by section index
+ * (sh section index)
+ * sh signed short offset
+ *
+ */
+ {
+ unsigned long dummy;
+ int psect;
+
+ if (cmd == TIR_S_C_STA_PW)
+ psect = *ptr++;
+ else
+ {
+ psect = bfd_getl16(ptr);
+ ptr += 2;
+ }
+
+ if (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+
+ dummy = bfd_getl16(ptr); ptr+=2;
+ dummy += (PRIV(sections)[psect])->vma;
+ _bfd_vms_push (abfd, dummy, psect);
+ }
+ break;
+
+ case TIR_S_C_STA_PL:
+ case TIR_S_C_STA_WPL:
+ /*
+ * stack psect base plus long offset (word index)
+ * arg: by section index
+ * (sh section index)
+ * lw signed longword offset
+ *
+ */
+ {
+ unsigned long dummy;
+ int psect;
+
+ if (cmd == TIR_S_C_STA_PL)
+ psect = *ptr++;
+ else
+ {
+ psect = bfd_getl16(ptr);
+ ptr += 2;
+ }
+
+ if (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+
+ dummy = bfd_getl32 (ptr); ptr += 4;
+ dummy += (PRIV(sections)[psect])->vma;
+ _bfd_vms_push (abfd, dummy, psect);
+ }
+ break;
+
+ case TIR_S_C_STA_UB:
+ /*
+ * stack unsigned byte
+ * arg: by value
+ *
+ * stack byte value
+ */
+ _bfd_vms_push (abfd, (unsigned long)*ptr++, -1);
+ break;
+
+ case TIR_S_C_STA_UW:
+ /*
+ * stack unsigned short word
+ * arg: sh value
+ *
+ * stack 16 bit value
+ */
+ _bfd_vms_push (abfd, (unsigned long)bfd_getl16(ptr), -1);
+ ptr += 2;
+ break;
+
+ case TIR_S_C_STA_BFI:
+ /*
+ * stack byte from image
+ * arg: -
+ *
+ */
+ /*FALLTHRU*/
+ case TIR_S_C_STA_WFI:
+ /*
+ * stack byte from image
+ * arg: -
+ *
+ */
+ /*FALLTHRU*/
+ case TIR_S_C_STA_LFI:
+ /*
+ * stack byte from image
+ * arg: -
+ *
+ */
+ (*_bfd_error_handler) (_("Stack-from-image not implemented"));
+ return NULL;
+
+ case TIR_S_C_STA_EPM:
+ /*
+ * stack entry point mask
+ * arg: cs symbol name
+ *
+ * stack (unsigned) entry point mask of symbol
+ * err if symbol is no entry point
+ */
+ {
+ char *name;
+ vms_symbol_entry *entry;
+
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = _bfd_vms_enter_symbol (abfd, name);
+ if (entry == (vms_symbol_entry *)NULL)
+ return 0;
+
+ (*_bfd_error_handler) (_("Stack-entry-mask not fully implemented"));
+ _bfd_vms_push (abfd, 0L, -1);
+ ptr += *ptr + 1;
+ }
+ break;
+
+ case TIR_S_C_STA_CKARG:
+ /*
+ * compare procedure argument
+ * arg: cs symbol name
+ * by argument index
+ * da argument descriptor
+ *
+ * compare argument descriptor with symbol argument (ARG$V_PASSMECH)
+ * and stack TRUE (args match) or FALSE (args dont match) value
+ */
+ (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
+ _bfd_vms_push (abfd, 1L, -1);
+ break;
+
+ case TIR_S_C_STA_LSY:
+ /*
+ * stack local symbol value
+ * arg: sh environment index
+ * cs symbol name
+ */
+ {
+ int envidx;
+ char *name;
+ vms_symbol_entry *entry;
+
+ envidx = bfd_getl16(ptr); ptr += 2;
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = _bfd_vms_enter_symbol (abfd, name);
+ if (entry == (vms_symbol_entry *)NULL)
+ return 0;
+ (*_bfd_error_handler) (_("Stack-local-symbol not fully implemented"));
+ _bfd_vms_push (abfd, 0L, -1);
+ ptr += *ptr + 1;
+ }
+ break;
+
+ case TIR_S_C_STA_LIT:
+ /*
+ * stack literal
+ * arg: by literal index
+ *
+ * stack literal
+ */
+ ptr++;
+ _bfd_vms_push (abfd, 0L, -1);
+ (*_bfd_error_handler) (_("Stack-literal not fully implemented"));
+ break;
+
+ case TIR_S_C_STA_LEPM:
+ /*
+ * stack local symbol entry point mask
+ * arg: sh environment index
+ * cs symbol name
+ *
+ * stack (unsigned) entry point mask of symbol
+ * err if symbol is no entry point
+ */
+ {
+ int envidx;
+ char *name;
+ vms_symbol_entry *entry;
+
+ envidx = bfd_getl16(ptr); ptr += 2;
+ name = _bfd_vms_save_counted_string (ptr);
+ entry = _bfd_vms_enter_symbol (abfd, name);
+ if (entry == (vms_symbol_entry *)NULL)
+ return 0;
+ (*_bfd_error_handler) (_("Stack-local-symbol-entry-point-mask not fully implemented"));
+ _bfd_vms_push (abfd, 0L, -1);
+ ptr += *ptr + 1;
+ }
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STA cmd %d"), ptr[-1]);
+ return NULL;
+ break;
+ }
+
+ return ptr;
+}
+
+
+/*
+ * tir_sto
+ *
+ * vax store commands
+ *
+ * handle sto_xxx commands in tir section
+ * ptr points to data area in record
+ *
+ * see table 7-4 of the VAX/VMS linker manual
+ */
+
+static unsigned char *
+tir_sto (bfd *abfd, unsigned char *ptr)
+{
+ unsigned long dummy;
+ int size;
+ int psect;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
+#endif
+
+ switch (*ptr++)
+ {
+ case TIR_S_C_STO_SB:
+ /*
+ * store signed byte: pop stack, write byte
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
+ break;
+
+ case TIR_S_C_STO_SW:
+ /*
+ * store signed word: pop stack, write word
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
+ break;
+
+ case TIR_S_C_STO_LW:
+ /*
+ * store longword: pop stack, write longword
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
+ break;
+
+ case TIR_S_C_STO_BD:
+ /*
+ * store byte displaced: pop stack, sub lc+1, write byte
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ dummy -= ((PRIV(sections)[psect])->vma + 1);
+ image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
+ break;
+
+ case TIR_S_C_STO_WD:
+ /*
+ * store word displaced: pop stack, sub lc+2, write word
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ dummy -= ((PRIV(sections)[psect])->vma + 2);
+ image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
+ break;
+ case TIR_S_C_STO_LD:
+ /*
+ * store long displaced: pop stack, sub lc+4, write long
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ dummy -= ((PRIV(sections)[psect])->vma + 4);
+ image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
+ break;
+ case TIR_S_C_STO_LI:
+ /*
+ * store short literal: pop stack, write byte
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
+ break;
+ case TIR_S_C_STO_PIDR:
+ /*
+ * store position independent data reference: pop stack, write longword
+ * arg: -
+ * FIXME: incomplete !
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_write_l (abfd, dummy & 0xffffffff);
+ break;
+ case TIR_S_C_STO_PICR:
+ /*
+ * store position independent code reference: pop stack, write longword
+ * arg: -
+ * FIXME: incomplete !
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ image_write_b (abfd, 0x9f);
+ image_write_l (abfd, dummy & 0xffffffff);
+ break;
+ case TIR_S_C_STO_RIVB:
+ /*
+ * store repeated immediate variable bytes
+ * 1-byte count n field followed by n bytes of data
+ * pop stack, write n bytes <stack> times
+ */
+ size = *ptr++;
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ while (dummy-- > 0L)
+ image_dump (abfd, ptr, size, 0);
+ ptr += size;
+ break;
+ case TIR_S_C_STO_B:
+ /*
+ * store byte from top longword
+ */
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ image_write_b (abfd, dummy & 0xff);
+ break;
+ case TIR_S_C_STO_W:
+ /*
+ * store word from top longword
+ */
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ image_write_w (abfd, dummy & 0xffff);
+ break;
+ case TIR_S_C_STO_RB:
+ /*
+ * store repeated byte from top longword
+ */
+ size = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ while (size-- > 0)
+ image_write_b (abfd, dummy & 0xff);
+ break;
+ case TIR_S_C_STO_RW:
+ /*
+ * store repeated word from top longword
+ */
+ size = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ dummy = (unsigned long)_bfd_vms_pop (abfd, NULL);
+ while (size-- > 0)
+ image_write_w (abfd, dummy & 0xffff);
+ break;
+
+ case TIR_S_C_STO_RSB:
+ case TIR_S_C_STO_RSW:
+ case TIR_S_C_STO_RL:
+ case TIR_S_C_STO_VPS:
+ case TIR_S_C_STO_USB:
+ case TIR_S_C_STO_USW:
+ case TIR_S_C_STO_RUB:
+ case TIR_S_C_STO_RUW:
+ case TIR_S_C_STO_PIRR:
+ (*_bfd_error_handler) (_("Unimplemented STO cmd %d"), ptr[-1]);
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved STO cmd %d"), ptr[-1]);
+ break;
+ }
+
+ return ptr;
+}
+
+
+/*
+ * stack operator commands
+ * all 32 bit signed arithmetic
+ * all word just like a stack calculator
+ * arguments are popped from stack, results are pushed on stack
+ *
+ * see table 7-5 of the VAX/VMS linker manual
+ */
+
+static unsigned char *
+tir_opr (bfd *abfd, unsigned char *ptr)
+{
+ long op1, op2;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
+#endif
+
+ switch (*ptr++)
+ {
+ /* operation */
+ case TIR_S_C_OPR_NOP:
+ /*
+ * no-op
+ */
+ break;
+
+ case TIR_S_C_OPR_ADD:
+ /*
+ * add
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 + op2), -1);
+ break;
+
+ case TIR_S_C_OPR_SUB:
+ /*
+ * subtract
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op2 - op1), -1);
+ break;
+
+ case TIR_S_C_OPR_MUL:
+ /*
+ * multiply
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 * op2), -1);
+ break;
+
+ case TIR_S_C_OPR_DIV:
+ /*
+ * divide
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (op2 == 0)
+ _bfd_vms_push (abfd, (unsigned long)0L, -1);
+ else
+ _bfd_vms_push (abfd, (unsigned long)(op2 / op1), -1);
+ break;
+
+ case TIR_S_C_OPR_AND:
+ /*
+ * logical and
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 & op2), -1);
+ break;
+
+ case TIR_S_C_OPR_IOR:
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ /*
+ * logical inclusive or
+ */
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 | op2), -1);
+ break;
+
+ case TIR_S_C_OPR_EOR:
+ /*
+ * logical exclusive or
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 ^ op2), -1);
+ break;
+
+ case TIR_S_C_OPR_NEG:
+ /*
+ * negate
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(-op1), -1);
+ break;
+
+ case TIR_S_C_OPR_COM:
+ /*
+ * complement
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)(op1 ^ -1L), -1);
+ break;
+
+ case TIR_S_C_OPR_INSV:
+ /*
+ * insert field
+ */
+ (void)_bfd_vms_pop (abfd, NULL);
+ (*_bfd_error_handler) ("TIR_S_C_OPR_INSV incomplete");
+ break;
+
+ case TIR_S_C_OPR_ASH:
+ /*
+ * arithmetic shift
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (HIGHBIT(op1)) /* shift right */
+ op2 >>= op1;
+ else /* shift left */
+ op2 <<= op1;
+ _bfd_vms_push (abfd, (unsigned long)op2, -1);
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_ASH incomplete"));
+ break;
+
+ case TIR_S_C_OPR_USH:
+ /*
+ * unsigned shift
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (HIGHBIT(op1)) /* shift right */
+ op2 >>= op1;
+ else /* shift left */
+ op2 <<= op1;
+ _bfd_vms_push (abfd, (unsigned long)op2, -1);
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_USH incomplete"));
+ break;
+
+ case TIR_S_C_OPR_ROT:
+ /*
+ * rotate
+ */
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ op2 = (long)_bfd_vms_pop (abfd, NULL);
+ if (HIGHBIT(0)) /* shift right */
+ op2 >>= op1;
+ else /* shift left */
+ op2 <<= op1;
+ _bfd_vms_push (abfd, (unsigned long)op2, -1);
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_ROT incomplete"));
+ break;
+
+ case TIR_S_C_OPR_SEL:
+ /*
+ * select
+ */
+ if ((long)_bfd_vms_pop (abfd, NULL) & 0x01L)
+ (void)_bfd_vms_pop (abfd, NULL);
+ else
+ {
+ op1 = (long)_bfd_vms_pop (abfd, NULL);
+ (void)_bfd_vms_pop (abfd, NULL);
+ _bfd_vms_push (abfd, (unsigned long)op1, -1);
+ }
+ break;
+
+ case TIR_S_C_OPR_REDEF:
+ /*
+ * redefine symbol to current location
+ */
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_REDEF not supported"));
+ break;
+
+ case TIR_S_C_OPR_DFLIT:
+ /*
+ * define a literal
+ */
+ (*_bfd_error_handler) (_("TIR_S_C_OPR_DFLIT not supported"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Reserved OPR cmd %d"), ptr[-1]);
+ break;
+ }
+
+ return ptr;
+}
+
+
+static unsigned char *
+tir_ctl (bfd *abfd, unsigned char *ptr)
+/*
+ * control commands
+ *
+ * see table 7-6 of the VAX/VMS linker manual
+ */
+{
+ unsigned long dummy;
+ int psect;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
+#endif
+
+ switch (*ptr++)
+ {
+ case TIR_S_C_CTL_SETRB:
+ /*
+ * set relocation base: pop stack, set image location counter
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ if (psect >= PRIV(section_count))
+ {
+ alloc_section (abfd, psect);
+ }
+ image_set_ptr (abfd, psect, dummy);
+ break;
+ case TIR_S_C_CTL_AUGRB:
+ /*
+ * augment relocation base: increment image location counter by offset
+ * arg: lw offset value
+ */
+ dummy = bfd_getl32 (ptr);
+ image_inc_ptr (abfd, dummy);
+ break;
+ case TIR_S_C_CTL_DFLOC:
+ /*
+ * define location: pop index, save location counter under index
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, NULL);
+ (*_bfd_error_handler) (_("TIR_S_C_CTL_DFLOC not fully implemented"));
+ break;
+ case TIR_S_C_CTL_STLOC:
+ /*
+ * set location: pop index, restore location counter from index
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ (*_bfd_error_handler) (_("TIR_S_C_CTL_STLOC not fully implemented"));
+ break;
+ case TIR_S_C_CTL_STKDL:
+ /*
+ * stack defined location: pop index, push location counter from index
+ * arg: -
+ */
+ dummy = _bfd_vms_pop (abfd, &psect);
+ (*_bfd_error_handler) (_("TIR_S_C_CTL_STKDL not fully implemented"));
+ break;
+ default:
+ (*_bfd_error_handler) (_("Reserved CTL cmd %d"), ptr[-1]);
+ break;
+ }
+ return ptr;
+}
+
+
+/*
+ * handle command from TIR section
+ */
+
+static unsigned char *
+tir_cmd (bfd *abfd, unsigned char *ptr)
+{
+ struct {
+ int mincod;
+ int maxcod;
+ unsigned char * (*explain)(bfd *, unsigned char *);
+ } tir_table[] = {
+ { 0, TIR_S_C_MAXSTACOD, tir_sta }
+ ,{ TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto }
+ ,{ TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr }
+ ,{ TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl }
+ ,{ -1, -1, NULL }
+ };
+ int i = 0;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ if (*ptr & 0x80) /* store immediate */
+ {
+ i = 128 - (*ptr++ & 0x7f);
+ image_dump (abfd, ptr, i, 0);
+ ptr += i;
+ }
+ else
+ {
+ while (tir_table[i].mincod >= 0)
+ {
+ if ( (tir_table[i].mincod <= *ptr)
+ && (*ptr <= tir_table[i].maxcod))
+ {
+ ptr = tir_table[i].explain (abfd, ptr);
+ break;
+ }
+ i++;
+ }
+ if (tir_table[i].mincod < 0)
+ {
+ (*_bfd_error_handler) (_("Obj code %d not found"), *ptr);
+ ptr = 0;
+ }
+ }
+
+ return ptr;
+}
+
+
+/* handle command from ETIR section */
+
+static int
+etir_cmd (abfd, cmd, ptr)
+ bfd *abfd;
+ int cmd;
+ unsigned char *ptr;
+{
+ static struct {
+ int mincod;
+ int maxcod;
+ boolean (*explain) PARAMS((bfd *, int, unsigned char *));
+ } etir_table[] = {
+ { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
+ { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
+ { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
+ { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
+ { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
+ { -1, -1, NULL }
+ };
+
+ int i = 0;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "etir_cmd %d/%x\n", cmd, cmd);
+ _bfd_hexdump (8, ptr, 16, (int)ptr);
+#endif
+
+ while (etir_table[i].mincod >= 0)
+ {
+ if ( (etir_table[i].mincod <= cmd)
+ && (cmd <= etir_table[i].maxcod))
+ {
+ if (!etir_table[i].explain (abfd, cmd, ptr))
+ return -1;
+ break;
+ }
+ i++;
+ }
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "etir_cmd: = 0\n");
+#endif
+ return 0;
+}
+
+
+/* Text Information and Relocation Records (OBJ$C_TIR)
+ handle tir record */
+
+static int
+analyze_tir (abfd, ptr, length)
+ bfd *abfd;
+ unsigned char *ptr;
+ unsigned int length;
+{
+ unsigned char *maxptr;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
+#endif
+
+ maxptr = ptr + length;
+
+ while (ptr < maxptr)
+ {
+ ptr = tir_cmd (abfd, ptr);
+ if (ptr == 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* Text Information and Relocation Records (EOBJ$C_ETIR)
+ handle etir record */
+
+static int
+analyze_etir (abfd, ptr, length)
+ bfd *abfd;
+ unsigned char *ptr;
+ unsigned int length;
+{
+ int cmd;
+ unsigned char *maxptr;
+ int result = 0;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
+#endif
+
+ maxptr = ptr + length;
+
+ while (ptr < maxptr)
+ {
+ cmd = bfd_getl16 (ptr);
+ length = bfd_getl16 (ptr + 2);
+ result = etir_cmd (abfd, cmd, ptr+4);
+ if (result != 0)
+ break;
+ ptr += length;
+ }
+
+#if VMS_DEBUG
+ _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
+#endif
+
+ return result;
+}
+
+
+/* process ETIR record
+
+ return 0 on success, -1 on error */
+
+int
+_bfd_vms_slurp_tir (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ int result;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "TIR/ETIR\n");
+#endif
+
+ switch (objtype)
+ {
+ case EOBJ_S_C_ETIR:
+ PRIV(vms_rec) += 4; /* skip type, size */
+ PRIV(rec_size) -= 4;
+ result = analyze_etir (abfd, PRIV(vms_rec), PRIV(rec_size));
+ break;
+ case OBJ_S_C_TIR:
+ PRIV(vms_rec) += 1; /* skip type */
+ PRIV(rec_size) -= 1;
+ result = analyze_tir (abfd, PRIV(vms_rec), PRIV(rec_size));
+ break;
+ default:
+ result = -1;
+ break;
+ }
+
+ return result;
+}
+
+
+/* process EDBG record
+ return 0 on success, -1 on error
+
+ not implemented yet */
+
+int
+_bfd_vms_slurp_dbg (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "DBG/EDBG\n");
+#endif
+
+ abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+ return 0;
+}
+
+
+/* process ETBT record
+ return 0 on success, -1 on error
+
+ not implemented yet */
+
+int
+_bfd_vms_slurp_tbt (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "TBT/ETBT\n");
+#endif
+
+ return 0;
+}
+
+
+/* process LNK record
+ return 0 on success, -1 on error
+
+ not implemented yet */
+
+int
+_bfd_vms_slurp_lnk (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "LNK\n");
+#endif
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------*/
+/* */
+/* WRITE ETIR SECTION */
+/* */
+/* this is still under construction and therefore not documented */
+/* */
+/*----------------------------------------------------------------------*/
+
+static void start_etir_record PARAMS ((bfd *abfd, int index, uquad offset, boolean justoffset));
+static void sto_imm PARAMS ((bfd *abfd, vms_section *sptr, bfd_vma vaddr, int index));
+static void end_etir_record PARAMS ((bfd *abfd));
+
+static void
+sto_imm (abfd, sptr, vaddr, index)
+ bfd *abfd;
+ vms_section *sptr;
+ bfd_vma vaddr;
+ int index;
+{
+ int size;
+ int ssize;
+ unsigned char *cptr;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
+ _bfd_hexdump (9, sptr->contents, (int)sptr->size, (int)vaddr);
+#endif
+
+ ssize = sptr->size;
+ cptr = sptr->contents;
+
+ while (ssize > 0)
+ {
+
+ size = ssize; /* try all the rest */
+
+ if (_bfd_vms_output_check (abfd, size) < 0)
+ { /* doesn't fit, split ! */
+ end_etir_record (abfd);
+ start_etir_record (abfd, index, vaddr, false);
+ size = _bfd_vms_output_check (abfd, 0); /* get max size */
+ if (size > ssize) /* more than what's left ? */
+ size = ssize;
+ }
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
+ _bfd_vms_output_long (abfd, (unsigned long)(size));
+ _bfd_vms_output_dump (abfd, cptr, size);
+ _bfd_vms_output_flush (abfd);
+
+#if VMS_DEBUG
+ _bfd_vms_debug (10, "dumped %d bytes\n", size);
+ _bfd_hexdump (10, cptr, (int)size, (int)vaddr);
+#endif
+
+ vaddr += size;
+ ssize -= size;
+ cptr += size;
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------*/
+
+/* start ETIR record for section #index at virtual addr offset. */
+
+static void
+start_etir_record (abfd, index, offset, justoffset)
+ bfd *abfd;
+ int index;
+ uquad offset;
+ boolean justoffset;
+{
+ if (!justoffset)
+ {
+ _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1); /* one ETIR per section */
+ _bfd_vms_output_push (abfd);
+ }
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1); /* push start offset */
+ _bfd_vms_output_long (abfd, (unsigned long)index);
+ _bfd_vms_output_quad (abfd, (uquad)offset);
+ _bfd_vms_output_flush (abfd);
+
+ _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1); /* start = pop () */
+ _bfd_vms_output_flush (abfd);
+
+ return;
+}
+
+
+/* end etir record */
+static void
+end_etir_record (abfd)
+ bfd *abfd;
+{
+ _bfd_vms_output_pop (abfd);
+ _bfd_vms_output_end (abfd);
+}
+
+/* write section contents for bfd abfd */
+
+int
+_bfd_vms_write_tir (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+ asection *section;
+ vms_section *sptr;
+ int nextoffset;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
+#endif
+
+ _bfd_vms_output_alignment (abfd, 4);
+
+ nextoffset = 0;
+ PRIV(vms_linkage_index) = 1;
+
+ /* dump all other sections */
+
+ section = abfd->sections;
+
+ while (section != NULL)
+ {
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n", section->index, section->name, (int)(section->_raw_size));
+#endif
+
+ if (section->flags & SEC_RELOC)
+ {
+ int i;
+
+ if ((i = section->reloc_count) <= 0)
+ {
+ (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
+ section->name);
+ }
+#if VMS_DEBUG
+ else
+ {
+ arelent **rptr;
+ _bfd_vms_debug (4, "%d relocations:\n", i);
+ rptr = section->orelocation;
+ while (i-- > 0)
+ {
+ _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
+ (*(*rptr)->sym_ptr_ptr)->name,
+ (*(*rptr)->sym_ptr_ptr)->section->name,
+ (long)(*(*rptr)->sym_ptr_ptr)->value,
+ (*rptr)->address, (*rptr)->addend,
+ bfd_get_reloc_size((*rptr)->howto),
+ (*rptr)->howto->name);
+ rptr++;
+ }
+ }
+#endif
+ }
+
+ if ((section->flags & SEC_HAS_CONTENTS)
+ && (! bfd_is_com_section (section)))
+ {
+ bfd_vma vaddr; /* virtual addr in section */
+
+ sptr = _bfd_get_vms_section (abfd, section->index);
+ if (sptr == NULL)
+ {
+ bfd_set_error (bfd_error_no_contents);
+ return -1;
+ }
+
+ vaddr = (bfd_vma)(sptr->offset);
+
+ start_etir_record (abfd, section->index, (uquad) sptr->offset,
+ false);
+
+ while (sptr != NULL) /* one STA_PQ, CTL_SETRB per vms_section */
+ {
+
+ if (section->flags & SEC_RELOC) /* check for relocs */
+ {
+ arelent **rptr = section->orelocation;
+ int i = section->reloc_count;
+ for (;;)
+ {
+ bfd_size_type addr = (*rptr)->address;
+ int len = bfd_get_reloc_size ((*rptr)->howto);
+ if (sptr->offset < addr) /* sptr starts before reloc */
+ {
+ int before = addr - sptr->offset;
+ if (sptr->size <= before) /* complete before */
+ {
+ sto_imm (abfd, sptr, vaddr, section->index);
+ vaddr += sptr->size;
+ break;
+ }
+ else /* partly before */
+ {
+ int after = sptr->size - before;
+ sptr->size = before;
+ sto_imm (abfd, sptr, vaddr, section->index);
+ vaddr += sptr->size;
+ sptr->contents += before;
+ sptr->offset += before;
+ sptr->size = after;
+ }
+ }
+ else if (sptr->offset == addr) /* sptr starts at reloc */
+ {
+ asymbol *sym = *(*rptr)->sym_ptr_ptr;
+ asection *sec = sym->section;
+
+ switch ((*rptr)->howto->type)
+ {
+ case ALPHA_R_IGNORE:
+ break;
+
+ case ALPHA_R_REFLONG:
+ {
+ if (bfd_is_und_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd,
+ strlen((char *)sym->name))
+ < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_GBL_LW,
+ -1);
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd, 16) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STA_LW,
+ -1);
+ _bfd_vms_output_quad (abfd,
+ (uquad)sym->value);
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_LW,
+ -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ else
+ {
+ if (_bfd_vms_output_check (abfd, 32) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STA_PQ,
+ -1);
+ _bfd_vms_output_long (abfd,
+ (unsigned long)(sec->index));
+ _bfd_vms_output_quad (abfd,
+ ((uquad)(*rptr)->addend
+ + (uquad)sym->value));
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_LW,
+ -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ }
+ break;
+
+ case ALPHA_R_REFQUAD:
+ {
+ if (bfd_is_und_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd,
+ strlen((char *)sym->name))
+ < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_GBL,
+ -1);
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ if (_bfd_vms_output_check (abfd, 16) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STA_QW,
+ -1);
+ _bfd_vms_output_quad (abfd,
+ (uquad)sym->value);
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_QW,
+ -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ else
+ {
+ if (_bfd_vms_output_check (abfd, 32) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STA_PQ,
+ -1);
+ _bfd_vms_output_long (abfd,
+ (unsigned long)(sec->index));
+ _bfd_vms_output_quad (abfd,
+ ((uquad)(*rptr)->addend
+ + (uquad)sym->value));
+ _bfd_vms_output_flush (abfd);
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_OFF,
+ -1);
+ _bfd_vms_output_flush (abfd);
+ }
+ }
+ break;
+
+ case ALPHA_R_HINT:
+ {
+ int hint_size;
+
+ hint_size = sptr->size;
+ sptr->size = len;
+ sto_imm (abfd, sptr, vaddr, section->index);
+ sptr->size = hint_size;
+#if 0
+ vms_output_begin(abfd, ETIR_S_C_STO_HINT_GBL, -1);
+ vms_output_long(abfd, (unsigned long)(sec->index));
+ vms_output_quad(abfd, (uquad)addr);
+
+ vms_output_counted(abfd, _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ vms_output_flush(abfd);
+#endif
+ }
+ break;
+ case ALPHA_R_LINKAGE:
+ {
+ if (_bfd_vms_output_check (abfd, 64) < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd, section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STC_LP_PSB,
+ -1);
+ _bfd_vms_output_long (abfd,
+ (unsigned long)PRIV(vms_linkage_index));
+ PRIV(vms_linkage_index) += 2;
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_byte (abfd, 0);
+ _bfd_vms_output_flush (abfd);
+ }
+ break;
+
+ case ALPHA_R_CODEADDR:
+ {
+ if (_bfd_vms_output_check (abfd,
+ strlen((char *)sym->name))
+ < 0)
+ {
+ end_etir_record (abfd);
+ start_etir_record (abfd,
+ section->index,
+ vaddr, false);
+ }
+ _bfd_vms_output_begin (abfd,
+ ETIR_S_C_STO_CA,
+ -1);
+ _bfd_vms_output_counted (abfd,
+ _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
+ _bfd_vms_output_flush (abfd);
+ }
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Unhandled relocation %s"),
+ (*rptr)->howto->name);
+ break;
+ }
+
+ vaddr += len;
+
+ if (len == sptr->size)
+ {
+ break;
+ }
+ else
+ {
+ sptr->contents += len;
+ sptr->offset += len;
+ sptr->size -= len;
+ i--;
+ rptr++;
+ }
+ }
+ else /* sptr starts after reloc */
+ {
+ i--; /* check next reloc */
+ rptr++;
+ }
+
+ if (i==0) /* all reloc checked */
+ {
+ if (sptr->size > 0)
+ {
+ sto_imm (abfd, sptr, vaddr, section->index); /* dump rest */
+ vaddr += sptr->size;
+ }
+ break;
+ }
+ } /* for (;;) */
+ } /* if SEC_RELOC */
+ else /* no relocs, just dump */
+ {
+ sto_imm (abfd, sptr, vaddr, section->index);
+ vaddr += sptr->size;
+ }
+
+ sptr = sptr->next;
+
+ } /* while (sptr != 0) */
+
+ end_etir_record (abfd);
+
+ } /* has_contents */
+
+ section = section->next;
+ }
+
+ _bfd_vms_output_alignment(abfd, 2);
+ return 0;
+}
+
+
+/* write traceback data for bfd abfd */
+
+int
+_bfd_vms_write_tbt (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
+#endif
+
+ return 0;
+}
+
+
+/* write debug info for bfd abfd */
+
+int
+_bfd_vms_write_dbg (abfd, objtype)
+ bfd *abfd;
+ int objtype;
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
+#endif
+
+ return 0;
+}
diff --git a/bfd/vms.c b/bfd/vms.c
new file mode 100644
index 00000000000..a5fc13ad942
--- /dev/null
+++ b/bfd/vms.c
@@ -0,0 +1,1947 @@
+/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+
+#include "vms.h"
+
+static boolean vms_initialize PARAMS ((bfd *));
+static int priv_section_count;
+static boolean fill_section_ptr PARAMS ((struct bfd_hash_entry *, PTR));
+static boolean vms_fixup_sections PARAMS ((bfd *));
+static boolean copy_symbols PARAMS ((struct bfd_hash_entry *, PTR));
+static bfd_reloc_status_type reloc_nil
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+static const struct bfd_target *vms_object_p PARAMS ((bfd *abfd));
+static const struct bfd_target *vms_archive_p PARAMS ((bfd *abfd));
+static boolean vms_mkobject PARAMS ((bfd *abfd));
+static boolean vms_write_object_contents PARAMS ((bfd *abfd));
+static boolean vms_close_and_cleanup PARAMS ((bfd *abfd));
+static boolean vms_bfd_free_cached_info PARAMS ((bfd *abfd));
+static boolean vms_new_section_hook PARAMS ((bfd *abfd, asection *section));
+static boolean vms_get_section_contents
+ PARAMS ((bfd *abfd, asection *section, PTR x1, file_ptr x2,
+ bfd_size_type x3));
+static boolean vms_get_section_contents_in_window
+ PARAMS ((bfd *abfd, asection *section, bfd_window *w, file_ptr offset,
+ bfd_size_type count));
+static boolean vms_bfd_copy_private_bfd_data PARAMS ((bfd *src, bfd *dest));
+static boolean vms_bfd_copy_private_section_data
+ PARAMS ((bfd *srcbfd, asection *srcsec, bfd *dstbfd, asection *dstsec));
+static boolean vms_bfd_copy_private_symbol_data
+ PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym));
+static boolean vms_bfd_print_private_bfd_data
+ PARAMS ((bfd *abfd, void *file));
+static char *vms_core_file_failing_command PARAMS ((bfd *abfd));
+static int vms_core_file_failing_signal PARAMS ((bfd *abfd));
+static boolean vms_core_file_matches_executable_p
+ PARAMS ((bfd *abfd, bfd *bbfd));
+static boolean vms_slurp_armap PARAMS ((bfd *abfd));
+static boolean vms_slurp_extended_name_table PARAMS ((bfd *abfd));
+static boolean vms_construct_extended_name_table
+ PARAMS ((bfd *abfd, char **tabloc, bfd_size_type *tablen,
+ const char **name));
+static void vms_truncate_arname
+ PARAMS ((bfd *abfd, CONST char *pathname, char *arhdr));
+static boolean vms_write_armap
+ PARAMS ((bfd *arch, unsigned int elength, struct orl *map,
+ unsigned int orl_count, int stridx));
+static PTR vms_read_ar_hdr PARAMS ((bfd *abfd));
+static bfd *vms_get_elt_at_index PARAMS ((bfd *abfd, symindex index));
+static bfd *vms_openr_next_archived_file PARAMS ((bfd *arch, bfd *prev));
+static boolean vms_update_armap_timestamp PARAMS ((bfd *abfd));
+static int vms_generic_stat_arch_elt PARAMS ((bfd *abfd, struct stat *stat));
+static long vms_get_symtab_upper_bound PARAMS ((bfd *abfd));
+static long vms_get_symtab PARAMS ((bfd *abfd, asymbol **symbols));
+static void vms_print_symbol
+ PARAMS ((bfd *abfd, PTR file, asymbol *symbol, bfd_print_symbol_type how));
+static void vms_get_symbol_info
+ PARAMS ((bfd *abfd, asymbol *symbol, symbol_info *ret));
+static boolean vms_bfd_is_local_label_name PARAMS ((bfd *abfd, const char *));
+static alent *vms_get_lineno PARAMS ((bfd *abfd, asymbol *symbol));
+static boolean vms_find_nearest_line
+ PARAMS ((bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
+ const char **file, const char **func, unsigned int *line));
+static asymbol *vms_bfd_make_debug_symbol
+ PARAMS ((bfd *abfd, void *ptr, unsigned long size));
+static long vms_read_minisymbols
+ PARAMS ((bfd *abfd, boolean dynamic, PTR *minisymsp, unsigned int *sizep));
+static asymbol *vms_minisymbol_to_symbol
+ PARAMS ((bfd *abfd, boolean dynamic, const PTR minisym, asymbol *sym));
+static long vms_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));
+static long vms_canonicalize_reloc
+ PARAMS ((bfd *abfd, asection *srcsec, arelent **location,
+ asymbol **symbols));
+static const struct reloc_howto_struct *vms_bfd_reloc_type_lookup
+ PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
+static boolean vms_set_arch_mach
+ PARAMS ((bfd *abfd, enum bfd_architecture arch, unsigned long mach));
+static boolean vms_set_section_contents
+ PARAMS ((bfd *abfd, asection *section, PTR location, file_ptr offset,
+ bfd_size_type count));
+static int vms_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
+static bfd_byte *vms_bfd_get_relocated_section_contents
+ PARAMS ((bfd *abfd, struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order, bfd_byte *data,
+ boolean relocateable, asymbol **symbols));
+static boolean vms_bfd_relax_section
+ PARAMS ((bfd *abfd, asection *section, struct bfd_link_info *link_info,
+ boolean *again));
+static boolean vms_bfd_gc_sections
+ PARAMS ((bfd *abfd, struct bfd_link_info *link_info));
+static struct bfd_link_hash_table *vms_bfd_link_hash_table_create
+ PARAMS ((bfd *abfd));
+static boolean vms_bfd_link_add_symbols
+ PARAMS ((bfd *abfd, struct bfd_link_info *link_info));
+static boolean vms_bfd_final_link
+ PARAMS ((bfd *abfd, struct bfd_link_info *link_info));
+static boolean vms_bfd_link_split_section
+ PARAMS ((bfd *abfd, asection *section));
+static long vms_get_dynamic_symtab_upper_bound PARAMS ((bfd *abfd));
+static long vms_canonicalize_dynamic_symtab
+ PARAMS ((bfd *abfd, asymbol **symbols));
+static long vms_get_dynamic_reloc_upper_bound PARAMS ((bfd *abfd));
+static long vms_canonicalize_dynamic_reloc
+ PARAMS ((bfd *abfd, arelent **arel, asymbol **symbols));
+static boolean vms_bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));
+static boolean vms_bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags));
+
+#define vms_make_empty_symbol _bfd_vms_make_empty_symbol
+
+/*===========================================================================*/
+
+const bfd_target vms_alpha_vec =
+{
+
+ "vms-alpha", /* name */
+ bfd_target_evax_flavour,
+ false, /* data byte order is little */
+ false, /* header byte order is little */
+
+ (HAS_RELOC | HAS_SYMS
+ | WP_TEXT | D_PAGED), /* object flags */
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16,
+
+ {_bfd_dummy_target, vms_object_p, /* bfd_check_format */
+ vms_archive_p, _bfd_dummy_target},
+ {bfd_false, vms_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, vms_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (vms),
+ BFD_JUMP_TABLE_COPY (vms),
+ BFD_JUMP_TABLE_CORE (vms),
+ BFD_JUMP_TABLE_ARCHIVE (vms),
+ BFD_JUMP_TABLE_SYMBOLS (vms),
+ BFD_JUMP_TABLE_RELOCS (vms),
+ BFD_JUMP_TABLE_WRITE (vms),
+ BFD_JUMP_TABLE_LINK (vms),
+ BFD_JUMP_TABLE_DYNAMIC (vms),
+
+ (PTR) 0
+};
+
+const bfd_target vms_vax_vec =
+{
+
+ "vms-vax", /* name */
+ bfd_target_ovax_flavour,
+ false, /* data byte order is little */
+ false, /* header byte order is little */
+
+ (HAS_RELOC | HAS_SYMS /* object flags */
+ | WP_TEXT | D_PAGED
+ | HAS_LINENO | HAS_DEBUG | HAS_LOCALS),
+
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+
+ {_bfd_dummy_target, vms_object_p, /* bfd_check_format */
+ vms_archive_p, _bfd_dummy_target},
+ {bfd_false, vms_mkobject, /* bfd_set_format */
+ _bfd_generic_mkarchive, bfd_false},
+ {bfd_false, vms_write_object_contents, /* bfd_write_contents */
+ _bfd_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (vms),
+ BFD_JUMP_TABLE_COPY (vms),
+ BFD_JUMP_TABLE_CORE (vms),
+ BFD_JUMP_TABLE_ARCHIVE (vms),
+ BFD_JUMP_TABLE_SYMBOLS (vms),
+ BFD_JUMP_TABLE_RELOCS (vms),
+ BFD_JUMP_TABLE_WRITE (vms),
+ BFD_JUMP_TABLE_LINK (vms),
+ BFD_JUMP_TABLE_DYNAMIC (vms),
+
+ (PTR) 0
+};
+
+/*===========================================================================*/
+
+/* Initialize private data */
+
+static boolean
+vms_initialize (abfd)
+ bfd *abfd;
+{
+ int i;
+
+ if (abfd->tdata.any != 0)
+ return true;
+
+ bfd_set_start_address (abfd, (bfd_vma)-1);
+
+ abfd->tdata.any = ((struct vms_private_data_struct*)
+ bfd_malloc (sizeof (struct vms_private_data_struct)));
+ if (abfd->tdata.any == 0)
+ return false;
+
+#ifdef __ALPHA
+ PRIV(is_vax) = 0;
+#else
+ PRIV(is_vax) = 1;
+#endif
+ PRIV(vms_buf) = 0;
+ PRIV(buf_size) = 0;
+ PRIV(rec_length) = 0;
+ PRIV(file_format) = FF_UNKNOWN;
+ PRIV(fixup_done) = false;
+ PRIV(sections) = NULL;
+
+ PRIV(stack) = ((struct stack_struct *)
+ bfd_malloc (sizeof (struct stack_struct) * STACKSIZE));
+ if (PRIV(stack) == 0)
+ {
+ vms_init_no_mem1:
+ free (abfd->tdata.any);
+ abfd->tdata.any = 0;
+ return false;
+ }
+ PRIV(stackptr) = 0;
+
+ PRIV(vms_symbol_table) = ((struct bfd_hash_table *)
+ bfd_malloc (sizeof (struct bfd_hash_table)));
+ if (PRIV(vms_symbol_table) == 0)
+ {
+ vms_init_no_mem2:
+ free (PRIV(stack));
+ PRIV(stack) = 0;
+ goto vms_init_no_mem1;
+ }
+
+ if (!bfd_hash_table_init (PRIV(vms_symbol_table), _bfd_vms_hash_newfunc))
+ return false;
+
+ PRIV(location_stack) = ((struct location_struct *)
+ bfd_malloc (sizeof (struct location_struct)
+ * LOCATION_SAVE_SIZE));
+ if (PRIV(location_stack) == 0)
+ {
+ vms_init_no_mem3:
+ free (PRIV(vms_symbol_table));
+ PRIV(vms_symbol_table) = 0;
+ goto vms_init_no_mem2;
+ }
+
+ for (i = 0; i < VMS_SECTION_COUNT; i++)
+ PRIV(vms_section_table)[i] = NULL;
+
+ PRIV(output_buf) = (unsigned char *) malloc (MAX_OUTREC_SIZE);
+ if (PRIV(output_buf) == 0)
+ {
+ free (PRIV(location_stack));
+ PRIV(location_stack) = 0;
+ goto vms_init_no_mem3;
+ }
+ PRIV(push_level) = 0;
+ PRIV(pushed_size) = 0;
+ PRIV(length_pos) = 2;
+ PRIV(output_size) = 0;
+ PRIV(output_alignment) = 1;
+
+ return true;
+}
+
+
+/* Fill symbol->section with section ptr
+ symbol->section is filled with the section index for defined symbols
+ during reading the GSD/EGSD section. But we need the pointer to the
+ bfd section later.
+
+ It has the correct value for referenced (undefined section) symbols
+
+ called from bfd_hash_traverse in vms_fixup_sections */
+
+static boolean
+fill_section_ptr (entry, sections)
+ struct bfd_hash_entry *entry;
+ PTR sections;
+{
+ asection *sec;
+ asymbol *sym;
+
+ sym = ((vms_symbol_entry *)entry)->symbol;
+ sec = sym->section;
+
+#if VMS_DEBUG
+ vms_debug (6, "fill_section_ptr: sym %p, sec %p\n", sym, sec);
+#endif
+
+ /* fill forward references (these contain section number, not section ptr). */
+
+ if ((int)sec < priv_section_count)
+ {
+ sec = ((vms_symbol_entry *)entry)->symbol->section =
+ ((asection **)sections)[(int)sec];
+ }
+
+ if (strcmp (sym->name, sec->name) == 0)
+ sym->flags |= BSF_SECTION_SYM;
+
+ return true;
+}
+
+
+/* Fixup sections
+ set up all pointers and arrays, counters and sizes are fixed now
+
+ we build a private sections vector for easy access since sections
+ are always referenced by an index number.
+
+ alloc PRIV(sections) according to abfd->section_count
+ copy abfd->sections to PRIV(sections) */
+
+static boolean
+vms_fixup_sections (abfd)
+ bfd *abfd;
+{
+ asection *s;
+
+ if (PRIV(fixup_done))
+ return true;
+
+ /*
+ * traverse symbol table and fill in all section pointers
+ */
+
+ /* can't provide section count as argument to fill_section_ptr(). */
+ priv_section_count = PRIV(section_count);
+ bfd_hash_traverse (PRIV(vms_symbol_table), fill_section_ptr,
+ (PTR)(PRIV(sections)));
+
+ PRIV(fixup_done) = true;
+
+ return true;
+}
+
+/*===========================================================================*/
+
+/* Check the format for a file being read.
+ Return a (bfd_target *) if it's an object file or zero if not. */
+
+static const struct bfd_target *
+vms_object_p (abfd)
+ bfd *abfd;
+{
+ int err = 0;
+ int prev_type;
+ const struct bfd_target *target_vector = 0;
+ const bfd_arch_info_type *arch = 0;
+
+#if VMS_DEBUG
+ vms_debug (1, "vms_object_p(%p)\n", abfd);
+#endif
+
+ if (!vms_initialize (abfd))
+ {
+ fprintf (stderr, "vms_initialize () failed !!\n");
+ return 0;
+ }
+
+ if (bfd_seek (abfd, 0L, SEEK_SET))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ prev_type = -1;
+
+ do
+ {
+#if VMS_DEBUG
+ vms_debug (7, "reading at %08lx\n", bfd_tell(abfd));
+#endif
+ if (_bfd_vms_next_record (abfd) < 0)
+ {
+#if VMS_DEBUG
+ vms_debug (2, "next_record failed\n");
+#endif
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if ((prev_type == EOBJ_S_C_EGSD)
+ && (PRIV(rec_type) != EOBJ_S_C_EGSD))
+ {
+ if (vms_fixup_sections (abfd) == false)
+ {
+#if VMS_DEBUG
+ vms_debug (2, "vms_fixup_sections failed\n");
+#endif
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ }
+
+ prev_type = PRIV(rec_type);
+
+ if (target_vector == 0)
+ {
+ if (prev_type <= OBJ_S_C_MAXRECTYP)
+ target_vector = &vms_vax_vec;
+ else
+ target_vector = &vms_alpha_vec;
+ }
+
+ switch (prev_type)
+ {
+ case OBJ_S_C_HDR:
+ case EOBJ_S_C_EMH:
+ err = _bfd_vms_slurp_hdr (abfd, prev_type);
+ break;
+ case OBJ_S_C_EOM:
+ case OBJ_S_C_EOMW:
+ case EOBJ_S_C_EEOM:
+ err = _bfd_vms_slurp_eom (abfd, prev_type);
+ break;
+ case OBJ_S_C_GSD:
+ case EOBJ_S_C_EGSD:
+ err = _bfd_vms_slurp_gsd (abfd, prev_type);
+ break;
+ case OBJ_S_C_TIR:
+ case EOBJ_S_C_ETIR:
+ err = _bfd_vms_slurp_tir (abfd, prev_type);
+ break;
+ case OBJ_S_C_DBG:
+ case EOBJ_S_C_EDBG:
+ err = _bfd_vms_slurp_dbg (abfd, prev_type);
+ break;
+ case OBJ_S_C_TBT:
+ case EOBJ_S_C_ETBT:
+ err = _bfd_vms_slurp_tbt (abfd, prev_type);
+ break;
+ case OBJ_S_C_LNK:
+ err = _bfd_vms_slurp_lnk (abfd, prev_type);
+ break;
+ default:
+ err = -1;
+ }
+ if (err != 0)
+ {
+#if VMS_DEBUG
+ vms_debug (2, "slurp type %d failed with %d\n", prev_type, err);
+#endif
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ }
+ while ((prev_type != EOBJ_S_C_EEOM) && (prev_type != OBJ_S_C_EOM) && (prev_type != OBJ_S_C_EOMW));
+
+ if (target_vector == &vms_vax_vec)
+ {
+ if (vms_fixup_sections (abfd) == false)
+ {
+#if VMS_DEBUG
+ vms_debug (2, "vms_fixup_sections failed\n");
+#endif
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ /* set arch_info to vax */
+
+ arch = bfd_scan_arch ("vax");
+ PRIV (is_vax) = 1;
+#if VMS_DEBUG
+ vms_debug (2, "arch is vax\n");
+#endif
+ }
+ else if (target_vector == &vms_alpha_vec)
+ {
+ /* set arch_info to alpha */
+
+ arch = bfd_scan_arch ("alpha");
+ PRIV (is_vax) = 0;
+#if VMS_DEBUG
+ vms_debug (2, "arch is alpha\n");
+#endif
+ }
+
+ if (arch == 0)
+ {
+#if VMS_DEBUG
+ vms_debug (2, "arch not found\n");
+#endif
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+ abfd->arch_info = arch;
+
+ return target_vector;
+}
+
+
+/* Check the format for a file being read.
+ Return a (bfd_target *) if it's an archive file or zero. */
+
+static const struct bfd_target *
+vms_archive_p (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_archive_p(%p)\n", abfd);
+#endif
+
+ return 0;
+}
+
+
+/* Set the format of a file being written. */
+
+static boolean
+vms_mkobject (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_mkobject(%p)\n", abfd);
+#endif
+
+ if (!vms_initialize (abfd))
+ {
+ fprintf (stderr, "vms_initialize () failed !!\n");
+ return 0;
+ }
+
+ {
+#ifdef __VAX
+ const bfd_arch_info_type *arch = bfd_scan_arch ("vax");
+#else
+ const bfd_arch_info_type *arch = bfd_scan_arch ("alpha");
+#endif
+ if (arch == 0)
+ {
+ bfd_set_error(bfd_error_wrong_format);
+ return 0;
+ }
+ abfd->arch_info = arch;
+ }
+
+ return true;
+}
+
+
+/* Write cached information into a file being written, at bfd_close. */
+
+static boolean
+vms_write_object_contents (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_write_object_contents(%p)\n", abfd);
+#endif
+
+ if (abfd->section_count > 0) /* we have sections */
+ {
+ if (PRIV(is_vax))
+ {
+ if (_bfd_vms_write_hdr (abfd, OBJ_S_C_HDR) != 0)
+ return false;
+ if (_bfd_vms_write_gsd (abfd, OBJ_S_C_GSD) != 0)
+ return false;
+ if (_bfd_vms_write_tir (abfd, OBJ_S_C_TIR) != 0)
+ return false;
+ if (_bfd_vms_write_tbt (abfd, OBJ_S_C_TBT) != 0)
+ return false;
+ if (_bfd_vms_write_dbg (abfd, OBJ_S_C_DBG) != 0)
+ return false;
+ if (abfd->section_count > 255)
+ {
+ if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOMW) != 0)
+ return false;
+ }
+ else
+ {
+ if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOM) != 0)
+ return false;
+ }
+ }
+ else
+ {
+ if (_bfd_vms_write_hdr (abfd, EOBJ_S_C_EMH) != 0)
+ return false;
+ if (_bfd_vms_write_gsd (abfd, EOBJ_S_C_EGSD) != 0)
+ return false;
+ if (_bfd_vms_write_tir (abfd, EOBJ_S_C_ETIR) != 0)
+ return false;
+ if (_bfd_vms_write_tbt (abfd, EOBJ_S_C_ETBT) != 0)
+ return false;
+ if (_bfd_vms_write_dbg (abfd, EOBJ_S_C_EDBG) != 0)
+ return false;
+ if (_bfd_vms_write_eom (abfd, EOBJ_S_C_EEOM) != 0)
+ return false;
+ }
+ }
+ return true;
+}
+
+/*-- 4.1, generic -----------------------------------------------------------*/
+
+/* Called when the BFD is being closed to do any necessary cleanup. */
+
+static boolean
+vms_close_and_cleanup (abfd)
+ bfd *abfd;
+{
+ asection *sec;
+ vms_section *es, *es1;
+ vms_reloc *er, *er1;
+ int i;
+
+#if VMS_DEBUG
+ vms_debug (1, "vms_close_and_cleanup(%p)\n", abfd);
+#endif
+ if (abfd == 0)
+ return true;
+
+ if (PRIV(vms_buf) != NULL)
+ {
+ free (PRIV(vms_buf));
+ PRIV(vms_buf) = NULL;
+ }
+ PRIV(buf_size) = 0;
+
+ if (PRIV(output_buf) != 0)
+ {
+ free (PRIV(output_buf));
+ PRIV(output_buf) = 0;
+ }
+
+ sec = abfd->sections;
+ while (sec != NULL)
+ {
+ if (sec->contents)
+ free (sec->contents);
+ sec = sec->next;
+ }
+
+ if (PRIV(sections) != NULL)
+ {
+ free (PRIV(sections));
+ PRIV(sections) = NULL;
+ }
+
+ if (PRIV(vms_symbol_table))
+ {
+ bfd_hash_table_free (PRIV(vms_symbol_table));
+ PRIV(vms_symbol_table) = 0;
+ }
+
+ if (PRIV(stack))
+ {
+ free (PRIV(stack));
+ PRIV(stack) = 0;
+ }
+
+ if (PRIV(location_stack))
+ {
+ free (PRIV(location_stack));
+ PRIV(location_stack) = 0;
+ }
+
+ for (i = 0; i < VMS_SECTION_COUNT; i++)
+ {
+ es = PRIV(vms_section_table)[i];
+ while (es != NULL)
+ {
+ es1 = es->next;
+ free (es);
+ es = es1;
+ }
+ PRIV(vms_section_table)[i] = NULL;
+ }
+
+ free (abfd->tdata.any);
+ abfd->tdata.any = NULL;
+
+ return true;
+}
+
+
+/* Ask the BFD to free all cached information. */
+static boolean
+vms_bfd_free_cached_info (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_free_cached_info(%p)\n", abfd);
+#endif
+ return true;
+}
+
+
+/* Called when a new section is created. */
+
+static boolean
+vms_new_section_hook (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_new_section_hook (%p, [%d]%s), count %d\n", abfd, section->index, section->name, abfd->section_count);
+#endif
+ bfd_set_section_alignment(abfd, section, 4);
+
+ if (abfd->section_count > PRIV(section_count))
+ {
+ PRIV(sections) = ((asection **)
+ bfd_realloc (PRIV(sections), abfd->section_count * sizeof (asection *)));
+ if (PRIV(sections) == 0)
+ return false;
+ PRIV(section_count) = abfd->section_count;
+ }
+#if VMS_DEBUG
+ vms_debug (6, "section_count: %d\n", PRIV(section_count));
+#endif
+ PRIV(sections)[section->index] = section;
+#if VMS_DEBUG
+ vms_debug (7, "%d: %s\n", section->index, section->name);
+#endif
+
+ return true;
+}
+
+
+/* Read the contents of a section.
+ buf points to a buffer of buf_size bytes to be filled with
+ section data (starting at offset into section) */
+
+static boolean
+vms_get_section_contents (abfd, section, buf, offset, buf_size)
+ bfd *abfd;
+ asection *section;
+ PTR buf;
+ file_ptr offset;
+ bfd_size_type buf_size;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_section_contents(%p, %s, %p, off %ld, size %d)\n",
+ abfd, section->name, buf, offset, (int)buf_size);
+#endif
+
+ /* shouldn't be called, since all sections are IN_MEMORY */
+
+ return false;
+}
+
+/* Read the contents of a section.
+ buf points to a buffer of buf_size bytes to be filled with
+ section data (starting at offset into section) */
+
+static boolean
+vms_get_section_contents_in_window (abfd, section, w, offset, count)
+ bfd *abfd;
+ asection *section;
+ bfd_window *w;
+ file_ptr offset;
+ bfd_size_type count;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_section_contents_in_window(%p, %s, %p, off %ld, count %d)\n",
+ abfd, section->name, w, offset, (int)count);
+#endif
+
+ /* shouldn't be called, since all sections are IN_MEMORY */
+
+ return false;
+}
+
+/*-- Part 4.2, copy private data --------------------------------------------*/
+
+/* Called to copy BFD general private data from one object file
+ to another. */
+
+static boolean
+vms_bfd_copy_private_bfd_data (src, dest)
+ bfd *src;
+ bfd *dest;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_copy_private_bfd_data(%p, %p)\n", src, dest);
+#endif
+ return true;
+}
+
+
+/* Merge private BFD information from the BFD @var{ibfd} to the
+ the output file BFD @var{obfd} when linking. Return <<true>>
+ on success, <<false>> on error. Possible error returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}. */
+
+static boolean
+vms_bfd_merge_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+#if VMS_DEBUG
+ vms_debug (1,"vms_bfd_merge_private_bfd_data(%p, %p)\n", ibfd, obfd);
+#endif
+ return true;
+}
+
+
+/* Set private BFD flag information in the BFD @var{abfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{obfd}. */
+
+static boolean
+vms_bfd_set_private_flags (abfd, flags)
+ bfd *abfd;
+ flagword flags;
+{
+#if VMS_DEBUG
+ vms_debug (1,"vms_bfd_set_private_flags(%p, %lx)\n", abfd, (long)flags);
+#endif
+ return true;
+}
+
+
+/* Called to copy BFD private section data from one object file
+ to another. */
+
+static boolean
+vms_bfd_copy_private_section_data (srcbfd, srcsec, dstbfd, dstsec)
+ bfd *srcbfd;
+ asection *srcsec;
+ bfd *dstbfd;
+ asection *dstsec;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_copy_private_section_data(%p, %s, %p, %s)\n",
+ srcbfd, srcsec->name, dstbfd, dstsec->name);
+#endif
+ return true;
+}
+
+/* Called to copy BFD private symbol data from one object file
+ to another. */
+
+static boolean
+vms_bfd_copy_private_symbol_data (ibfd, isym, obfd, osym)
+ bfd *ibfd;
+ asymbol *isym;
+ bfd *obfd;
+ asymbol *osym;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_copy_private_symbol_data(%p, %s, %p, %s)\n",
+ ibfd, isym->name, obfd, osym->name);
+#endif
+ return true;
+}
+
+/*-- Part 4.3, core file ----------------------------------------------------*/
+
+/* Return a read-only string explaining which program was running
+ when it failed and produced the core file abfd. */
+
+static char *
+vms_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_core_file_failing_command(%p)\n", abfd);
+#endif
+ return 0;
+}
+
+
+/* Returns the signal number which caused the core dump which
+ generated the file the BFD abfd is attached to. */
+
+static int
+vms_core_file_failing_signal (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_core_file_failing_signal(%p)\n", abfd);
+#endif
+ return 0;
+}
+
+
+/* Return true if the core file attached to core_bfd was generated
+ by a run of the executable file attached to exec_bfd, false otherwise. */
+
+static boolean
+vms_core_file_matches_executable_p (abfd, bbfd)
+ bfd *abfd;
+ bfd *bbfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_core_file_matches_executable_p(%p, %p)\n", abfd, bbfd);
+#endif
+ return false;
+}
+
+/*-- Part 4.4, archive ------------------------------------------------------*/
+
+/* ??? do something with an archive map.
+ Return false on error, true otherwise. */
+
+static boolean
+vms_slurp_armap (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_slurp_armap(%p)\n", abfd);
+#endif
+ return false;
+}
+
+
+/* ??? do something with an extended name table.
+ Return false on error, true otherwise. */
+
+static boolean
+vms_slurp_extended_name_table (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_slurp_extended_name_table(%p)\n", abfd);
+#endif
+ return false;
+}
+
+
+/* ??? do something with an extended name table.
+ Return false on error, true otherwise. */
+
+static boolean
+vms_construct_extended_name_table (abfd, tabloc, tablen, name)
+ bfd *abfd;
+ char **tabloc;
+ bfd_size_type *tablen;
+ const char **name;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_construct_extended_name_table(%p)\n", abfd);
+#endif
+ return false;
+}
+
+
+/* Truncate the name of an archive to match system-dependent restrictions */
+
+static void
+vms_truncate_arname (abfd, pathname, arhdr)
+ bfd *abfd;
+ CONST char *pathname;
+ char *arhdr;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_truncate_arname(%p, %s, %s)\n", abfd, pathname, arhdr);
+#endif
+ return;
+}
+
+
+/* ??? write archive map */
+
+static boolean
+vms_write_armap (arch, elength, map, orl_count, stridx)
+ bfd *arch;
+ unsigned int elength;
+ struct orl *map;
+ unsigned int orl_count;
+ int stridx;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_write_armap(%p, %d, %p, %d %d)\n",
+ arch, elength, map, orl_count, stridx);
+#endif
+ return true;
+}
+
+/* Read archive header ??? */
+
+static PTR
+vms_read_ar_hdr (abfd)
+ bfd * abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_read_ar_hdr(%p)\n", abfd);
+#endif
+ return (PTR)0;
+}
+
+
+/* Provided a BFD, @var{archive}, containing an archive and NULL, open
+ an input BFD on the first contained element and returns that.
+ Subsequent calls should pass the archive and the previous return value
+ to return a created BFD to the next contained element.
+ NULL is returned when there are no more. */
+
+static bfd *
+vms_openr_next_archived_file (arch, prev)
+ bfd *arch;
+ bfd *prev;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_openr_next_archived_file(%p, %p)\n", arch, prev);
+#endif
+ return false;
+}
+
+
+/* Return the BFD which is referenced by the symbol in ABFD indexed by
+ INDEX. INDEX should have been returned by bfd_get_next_mapent. */
+
+static bfd *
+vms_get_elt_at_index (abfd, index)
+ bfd *abfd;
+ symindex index;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_elt_at_index(%p, %p)\n", abfd, index);
+#endif
+ return _bfd_generic_get_elt_at_index(abfd, index);
+}
+
+
+/* ???
+ -> bfd_generic_stat_arch_elt */
+
+static int
+vms_generic_stat_arch_elt (abfd, stat)
+ bfd *abfd;
+ struct stat *stat;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_generic_stat_arch_elt(%p, %p)\n", abfd, stat);
+#endif
+ return bfd_generic_stat_arch_elt(abfd, stat);
+}
+
+
+/* This is a new function in bfd 2.5 */
+
+static boolean
+vms_update_armap_timestamp (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_update_armap_timestamp(%p)\n", abfd);
+#endif
+ return true;
+}
+
+/*-- Part 4.5, symbols --------------------------------------------------------*/
+
+/* Return the number of bytes required to store a vector of pointers
+ to asymbols for all the symbols in the BFD abfd, including a
+ terminal NULL pointer. If there are no symbols in the BFD,
+ then return 0. If an error occurs, return -1. */
+
+static long
+vms_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_symtab_upper_bound(%p), %d symbols\n", abfd, PRIV(gsd_sym_count));
+#endif
+ return (PRIV(gsd_sym_count)+1) * sizeof(asymbol *);
+}
+
+
+/* Copy symbols from hash table to symbol vector
+
+ called from bfd_hash_traverse in vms_get_symtab
+ init counter to 0 if entry == 0 */
+
+static boolean
+copy_symbols (entry, arg)
+ struct bfd_hash_entry *entry;
+ PTR arg;
+{
+ bfd *abfd = (bfd *) arg;
+
+ if (entry == NULL) /* init counter */
+ PRIV(symnum) = 0;
+ else /* fill vector, inc counter */
+ PRIV(symcache)[PRIV(symnum)++] = ((vms_symbol_entry *)entry)->symbol;
+
+ return true;
+}
+
+
+/* Read the symbols from the BFD abfd, and fills in the vector
+ location with pointers to the symbols and a trailing NULL.
+
+ return # of symbols read */
+
+static long
+vms_get_symtab (abfd, symbols)
+ bfd *abfd;
+ asymbol **symbols;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_symtab(%p, <ret>)\n", abfd);
+#endif
+
+ /* init counter */
+ (void)copy_symbols((struct bfd_hash_entry *)0, abfd);
+
+ /* traverse table and fill symbols vector */
+
+ PRIV(symcache) = symbols;
+ bfd_hash_traverse(PRIV(vms_symbol_table), copy_symbols, (PTR)abfd);
+
+ symbols[PRIV(gsd_sym_count)] = NULL;
+
+ return PRIV(gsd_sym_count);
+}
+
+
+/* Create a new asymbol structure for the BFD abfd and return a pointer
+ to it.
+ This routine is necessary because each back end has private information
+ surrounding the asymbol. Building your own asymbol and pointing to it
+ will not create the private information, and will cause problems later on. */
+
+asymbol *
+_bfd_vms_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *symbol = (asymbol *)bfd_zalloc(abfd, sizeof(asymbol));
+
+#if VMS_DEBUG
+ vms_debug (1, "_bfd_vms_make_empty_symbol(%p)\n", abfd);
+#endif
+
+ if (symbol == 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return 0;
+ }
+ symbol->the_bfd = abfd;
+
+ return symbol;
+}
+
+
+/* Print symbol to file according to how. how is one of
+ bfd_print_symbol_name just print the name
+ bfd_print_symbol_more print more (???)
+ bfd_print_symbol_all print all we know, which is not much right now :-) */
+
+static void
+vms_print_symbol (abfd, file, symbol, how)
+ bfd *abfd;
+ PTR file;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_print_symbol(%p, %p, %p, %d)\n", abfd, file, symbol, how);
+#endif
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ case bfd_print_symbol_more:
+ fprintf((FILE *)file," %s", symbol->name);
+ break;
+
+ break;
+
+ case bfd_print_symbol_all:
+ {
+ CONST char *section_name = symbol->section->name;
+
+ bfd_print_symbol_vandf((PTR)file,symbol);
+
+ fprintf((FILE *)file," %-8s %s", section_name, symbol->name);
+ }
+ break;
+ }
+ return;
+}
+
+
+/* Return information about symbol in ret.
+
+ fill type, value and name
+ type:
+ A absolute
+ B bss segment symbol
+ C common symbol
+ D data segment symbol
+ f filename
+ t a static function symbol
+ T text segment symbol
+ U undefined
+ - debug */
+
+static void
+vms_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ asection *sec;
+
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_symbol_info(%p, %p, %p)\n", abfd, symbol, ret);
+#endif
+
+ sec = symbol->section;
+
+ if (ret == 0)
+ return;
+
+ if (bfd_is_com_section (sec))
+ ret->type = 'C';
+ else if (bfd_is_abs_section (sec))
+ ret->type = 'A';
+ else if (bfd_is_und_section (sec))
+ ret->type = 'U';
+ else if (bfd_is_ind_section (sec))
+ ret->type = 'I';
+ else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
+ ret->type = 'T';
+ else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
+ ret->type = 'D';
+ else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ ret->type = 'B';
+ else
+ ret->type = '-';
+
+ if (ret->type != 'U')
+ ret->value = symbol->value + symbol->section->vma;
+ else
+ ret->value = 0;
+ ret->name = symbol->name;
+
+ return;
+}
+
+
+/* Return true if the given symbol sym in the BFD abfd is
+ a compiler generated local label, else return false. */
+
+static boolean
+vms_bfd_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_is_local_label_name(%p, %s)\n", abfd, name);
+#endif
+ return name[0] == '$';
+}
+
+
+/* Get source line number for symbol */
+
+static alent *
+vms_get_lineno (abfd, symbol)
+ bfd *abfd;
+ asymbol *symbol;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_lineno(%p, %p)\n", abfd, symbol);
+#endif
+ return 0;
+}
+
+
+/* Provided a BFD, a section and an offset into the section, calculate and
+ return the name of the source file and the line nearest to the wanted
+ location. */
+
+static boolean
+vms_find_nearest_line (abfd, section, symbols, offset, file, func, line)
+ bfd *abfd;
+ asection *section;
+ asymbol **symbols;
+ bfd_vma offset;
+ CONST char **file;
+ CONST char **func;
+ unsigned int *line;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_find_nearest_line(%p, %s, %p, %ld, <ret>, <ret>, <ret>)\n",
+ abfd, section->name, symbols, (long int)offset);
+#endif
+ return false;
+}
+
+
+/* Back-door to allow format-aware applications to create debug symbols
+ while using BFD for everything else. Currently used by the assembler
+ when creating COFF files. */
+
+static asymbol *
+vms_bfd_make_debug_symbol (abfd, ptr, size)
+ bfd *abfd;
+ void *ptr;
+ unsigned long size;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_make_debug_symbol(%p, %p, %ld)\n", abfd, ptr, size);
+#endif
+ return 0;
+}
+
+
+/* Read minisymbols. For minisymbols, we use the unmodified a.out
+ symbols. The minisymbol_to_symbol function translates these into
+ BFD asymbol structures. */
+
+static long
+vms_read_minisymbols (abfd, dynamic, minisymsp, sizep)
+ bfd *abfd;
+ boolean dynamic;
+ PTR *minisymsp;
+ unsigned int *sizep;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_read_minisymbols(%p, %d, %p, %d)\n", abfd, dynamic, minisymsp, *sizep);
+#endif
+ return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
+}
+
+/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an
+ unmodified a.out symbol. The SYM argument is a structure returned
+ by bfd_make_empty_symbol, which we fill in here. */
+
+static asymbol *
+vms_minisymbol_to_symbol (abfd, dynamic, minisym, sym)
+ bfd *abfd;
+ boolean dynamic;
+ const PTR minisym;
+ asymbol *sym;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_minisymbol_to_symbol(%p, %d, %p, %p)\n", abfd, dynamic, minisym, sym);
+#endif
+ return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
+}
+
+/*-- Part 4.6, relocations --------------------------------------------------*/
+
+/* Return the number of bytes required to store the relocation information
+ associated with section sect attached to bfd abfd.
+ If an error occurs, return -1. */
+
+static long
+vms_get_reloc_upper_bound (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_reloc_upper_bound(%p, %s)\n", abfd, section->name);
+#endif
+ return -1L;
+}
+
+
+/* Call the back end associated with the open BFD abfd and translate the
+ external form of the relocation information attached to sec into the
+ internal canonical form. Place the table into memory at loc, which has
+ been preallocated, usually by a call to bfd_get_reloc_upper_bound.
+ Returns the number of relocs, or -1 on error. */
+
+static long
+vms_canonicalize_reloc (abfd, section, location, symbols)
+ bfd *abfd;
+ asection *section;
+ arelent **location;
+ asymbol **symbols;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_canonicalize_reloc(%p, %s, <ret>, <ret>)\n", abfd, section->name);
+#endif
+ return false;
+}
+
+/*---------------------------------------------------------------------------*/
+/* this is just copied from ecoff-alpha, needs to be fixed probably */
+
+/* How to process the various reloc types. */
+
+static bfd_reloc_status_type
+reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
+ bfd *abfd;
+ arelent *reloc;
+ asymbol *sym;
+ PTR data;
+ asection *sec;
+ bfd *output_bfd;
+ char **error_message;
+{
+#if VMS_DEBUG
+ vms_debug (1, "reloc_nil(abfd %p, output_bfd %p)\n", abfd, output_bfd);
+ vms_debug (2, "In section %s, symbol %s\n",
+ sec->name, sym->name);
+ vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
+ reloc->sym_ptr_ptr[0]->name,
+ (unsigned long)reloc->address,
+ (unsigned long)reloc->addend, reloc->howto->name);
+ vms_debug (2, "data at %p\n", data);
+/* _bfd_hexdump (2, data, bfd_get_reloc_size(reloc->howto),0); */
+#endif
+
+ return bfd_reloc_ok;
+}
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
+ from smaller values. Start with zero, widen, *then* decrement. */
+#define MINUS_ONE (((bfd_vma)0) - 1)
+
+static reloc_howto_type alpha_howto_table[] =
+{
+ HOWTO (ALPHA_R_IGNORE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "IGNORE", /* name */
+ true, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ true), /* pcrel_offset */
+
+ /* A 64 bit reference to a symbol. */
+ HOWTO (ALPHA_R_REFQUAD, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "REFQUAD", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 21 bit branch. The native assembler generates these for
+ branches within the text segment, and also fills in the PC
+ relative offset in the instruction. */
+ HOWTO (ALPHA_R_BRADDR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "BRADDR", /* name */
+ true, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A hint for a jump to a register. */
+ HOWTO (ALPHA_R_HINT, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "HINT", /* name */
+ true, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 16 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "SREL16", /* name */
+ true, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* 32 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "SREL32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit PC relative offset. */
+ HOWTO (ALPHA_R_SREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "SREL64", /* name */
+ true, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Push a value on the reloc evaluation stack. */
+ HOWTO (ALPHA_R_OP_PUSH, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "OP_PUSH", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Store the value from the stack at the given address. Store it in
+ a bitfield of size r_size starting at bit position r_offset. */
+ HOWTO (ALPHA_R_OP_STORE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "OP_STORE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Subtract the reloc address from the value on the top of the
+ relocation stack. */
+ HOWTO (ALPHA_R_OP_PSUB, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "OP_PSUB", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Shift the value on the top of the relocation stack right by the
+ given value. */
+ HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "OP_PRSHIFT", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* Hack. Linkage is done by linker. */
+ HOWTO (ALPHA_R_LINKAGE, /* type */
+ 0, /* rightshift */
+ 8, /* size (0 = byte, 1 = short, 2 = long) */
+ 256, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "LINKAGE", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 32 bit reference to a symbol. */
+ HOWTO (ALPHA_R_REFLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "REFLONG", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* A 64 bit reference to a procedure, written as 32 bit value. */
+ HOWTO (ALPHA_R_CODEADDR, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ reloc_nil, /* special_function */
+ "CODEADDR", /* name */
+ false, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false), /* pcrel_offset */
+
+};
+
+/* Return a pointer to a howto structure which, when invoked, will perform
+ the relocation code on data from the architecture noted. */
+
+static const struct reloc_howto_struct *
+vms_bfd_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ int alpha_type;
+
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_reloc_type_lookup(%p, %d)\t", abfd, code);
+#endif
+
+ switch (code)
+ {
+ case BFD_RELOC_16: alpha_type = ALPHA_R_SREL16; break;
+ case BFD_RELOC_32: alpha_type = ALPHA_R_REFLONG; break;
+ case BFD_RELOC_64: alpha_type = ALPHA_R_REFQUAD; break;
+ case BFD_RELOC_CTOR: alpha_type = ALPHA_R_REFQUAD; break;
+ case BFD_RELOC_23_PCREL_S2: alpha_type = ALPHA_R_BRADDR; break;
+ case BFD_RELOC_ALPHA_HINT: alpha_type = ALPHA_R_HINT; break;
+ case BFD_RELOC_16_PCREL: alpha_type = ALPHA_R_SREL16; break;
+ case BFD_RELOC_32_PCREL: alpha_type = ALPHA_R_SREL32; break;
+ case BFD_RELOC_64_PCREL: alpha_type = ALPHA_R_SREL64; break;
+ case BFD_RELOC_ALPHA_LINKAGE: alpha_type = ALPHA_R_LINKAGE; break;
+ case BFD_RELOC_ALPHA_CODEADDR: alpha_type = ALPHA_R_CODEADDR; break;
+ default:
+ (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
+ return (const struct reloc_howto_struct *) NULL;
+ }
+#if VMS_DEBUG
+ vms_debug (2, "reloc is %s\n", alpha_howto_table[alpha_type].name);
+#endif
+ return &alpha_howto_table[alpha_type];
+}
+
+
+/*-- Part 4.7, writing an object file ---------------------------------------*/
+
+/* Set the architecture and machine type in BFD abfd to arch and mach.
+ Find the correct pointer to a structure and insert it into the arch_info
+ pointer. */
+
+static boolean
+vms_set_arch_mach (abfd, arch, mach)
+ bfd *abfd;
+ enum bfd_architecture arch;
+ unsigned long mach;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_set_arch_mach(%p, %d, %ld)\n", abfd, arch, mach);
+#endif
+ abfd->arch_info = bfd_scan_arch("alpha");
+
+ return true;
+}
+
+
+/* Sets the contents of the section section in BFD abfd to the data starting
+ in memory at data. The data is written to the output section starting at
+ offset offset for count bytes.
+
+ Normally true is returned, else false. Possible error returns are:
+ o bfd_error_no_contents - The output section does not have the
+ SEC_HAS_CONTENTS attribute, so nothing can be written to it.
+ o and some more too */
+
+static boolean
+vms_set_section_contents (abfd, section, location, offset, count)
+ bfd *abfd;
+ asection *section;
+ PTR location;
+ file_ptr offset;
+ bfd_size_type count;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_set_section_contents(%p, sec %s, loc %p, off %ld, count %d)\n",
+ abfd, section->name, location, (long int)offset, (int)count);
+ vms_debug (2, "secraw %d, seccooked %d\n", (int)section->_raw_size, (int)section->_cooked_size);
+#endif
+ return _bfd_save_vms_section(abfd, section, location, offset, count);
+}
+
+
+/*-- Part 4.8, linker -------------------------------------------------------*/
+
+/* Get the size of the section headers. */
+
+static int
+vms_sizeof_headers (abfd, reloc)
+ bfd *abfd;
+ boolean reloc;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_sizeof_headers(%p, %s)\n", abfd, (reloc)?"True":"False");
+#endif
+ return 0;
+}
+
+
+/* Provides default handling of relocation effort for back ends
+ which can't be bothered to do it efficiently. */
+
+static bfd_byte *
+vms_bfd_get_relocated_section_contents (abfd, link_info, link_order, data,
+ relocateable, symbols)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+ struct bfd_link_order *link_order;
+ bfd_byte *data;
+ boolean relocateable;
+ asymbol **symbols;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_get_relocated_section_contents(%p, %p, %p, %p, %s, %p)\n",
+ abfd, link_info, link_order, data, (relocateable)?"True":"False", symbols);
+#endif
+ return 0;
+}
+
+
+/* ??? */
+
+static boolean
+vms_bfd_relax_section (abfd, section, link_info, again)
+ bfd *abfd;
+ asection *section;
+ struct bfd_link_info *link_info;
+ boolean *again;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_relax_section(%p, %s, %p, <ret>)\n",
+ abfd, section->name, link_info);
+#endif
+ return true;
+}
+
+static boolean
+vms_bfd_gc_sections (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_gc_sections(%p, %p)\n", abfd, link_info);
+#endif
+ return true;
+}
+
+
+/* Create a hash table for the linker. Different backends store
+ different information in this table. */
+
+static struct bfd_link_hash_table *
+vms_bfd_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_link_hash_table_create(%p)\n", abfd);
+#endif
+ return 0;
+}
+
+
+/* Add symbols from this object file into the hash table. */
+
+static boolean
+vms_bfd_link_add_symbols (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_link_add_symbols(%p, %p)\n", abfd, link_info);
+#endif
+ return false;
+}
+
+
+/* Do a link based on the link_order structures attached to each
+ section of the BFD. */
+
+static boolean
+vms_bfd_final_link (abfd, link_info)
+ bfd *abfd;
+ struct bfd_link_info *link_info;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_final_link(%p, %p)\n", abfd, link_info);
+#endif
+ return true;
+}
+
+/* Should this section be split up into smaller pieces during linking. */
+
+static boolean
+vms_bfd_link_split_section (abfd, section)
+ bfd *abfd;
+ asection *section;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_link_split_section(%p, %s)\n", abfd, section->name);
+#endif
+ return false;
+}
+
+/*-- Part 4.9, dynamic symbols and relocations ------------------------------*/
+
+/* Get the amount of memory required to hold the dynamic symbols. */
+
+static long
+vms_get_dynamic_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_dynamic_symtab_upper_bound(%p)\n", abfd);
+#endif
+ return 0;
+}
+
+static boolean
+vms_bfd_print_private_bfd_data (abfd, file)
+ bfd *abfd;
+ void *file;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_bfd_print_private_bfd_data(%p)\n", abfd);
+#endif
+ return 0;
+}
+
+
+/* Read in the dynamic symbols. */
+
+static long
+vms_canonicalize_dynamic_symtab (abfd, symbols)
+ bfd *abfd;
+ asymbol **symbols;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_canonicalize_dynamic_symtab(%p, <ret>)\n", abfd);
+#endif
+ return 0L;
+}
+
+
+/* Get the amount of memory required to hold the dynamic relocs. */
+
+static long
+vms_get_dynamic_reloc_upper_bound (abfd)
+ bfd *abfd;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_get_dynamic_reloc_upper_bound(%p)\n", abfd);
+#endif
+ return 0L;
+}
+
+
+/* Read in the dynamic relocs. */
+
+static long
+vms_canonicalize_dynamic_reloc (abfd, arel, symbols)
+ bfd *abfd;
+ arelent **arel;
+ asymbol **symbols;
+{
+#if VMS_DEBUG
+ vms_debug (1, "vms_canonicalize_dynamic_reloc(%p)\n", abfd);
+#endif
+ return 0L;
+}
diff --git a/bfd/vms.h b/bfd/vms.h
new file mode 100644
index 00000000000..d6bdd02a720
--- /dev/null
+++ b/bfd/vms.h
@@ -0,0 +1,675 @@
+#undef vms
+/* vms.h -- Header file for VMS (Alpha and Vax) support.
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+
+ Written by Klaus K"ampf (kkaempf@rmi.de)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef VMS_H
+#define VMS_H
+
+
+/* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object language) */
+
+/* VMS Text, information and relocation record (TIR/ETIR) definitions. */
+
+#define TIR_S_C_STA_GBL 0
+#define TIR_S_C_STA_SB 1
+#define TIR_S_C_STA_SW 2
+#define TIR_S_C_STA_LW 3
+#define TIR_S_C_STA_PB 4
+#define TIR_S_C_STA_PW 5
+#define TIR_S_C_STA_PL 6
+#define TIR_S_C_STA_UB 7
+#define TIR_S_C_STA_UW 8
+#define TIR_S_C_STA_BFI 9
+#define TIR_S_C_STA_WFI 10
+#define TIR_S_C_STA_LFI 11
+#define TIR_S_C_STA_EPM 12
+#define TIR_S_C_STA_CKARG 13
+#define TIR_S_C_STA_WPB 14
+#define TIR_S_C_STA_WPW 15
+#define TIR_S_C_STA_WPL 16
+#define TIR_S_C_STA_LSY 17
+#define TIR_S_C_STA_LIT 18
+#define TIR_S_C_STA_LEPM 19
+#define TIR_S_C_MAXSTACOD 19
+#define TIR_S_C_MINSTOCOD 20
+#define TIR_S_C_STO_SB 20
+#define TIR_S_C_STO_SW 21
+#define TIR_S_C_STO_L 22
+#define TIR_S_C_STO_LW 22
+#define TIR_S_C_STO_BD 23
+#define TIR_S_C_STO_WD 24
+#define TIR_S_C_STO_LD 25
+#define TIR_S_C_STO_LI 26
+#define TIR_S_C_STO_PIDR 27
+#define TIR_S_C_STO_PICR 28
+#define TIR_S_C_STO_RSB 29
+#define TIR_S_C_STO_RSW 30
+#define TIR_S_C_STO_RL 31
+#define TIR_S_C_STO_VPS 32
+#define TIR_S_C_STO_USB 33
+#define TIR_S_C_STO_USW 34
+#define TIR_S_C_STO_RUB 35
+#define TIR_S_C_STO_RUW 36
+#define TIR_S_C_STO_B 37
+#define TIR_S_C_STO_W 38
+#define TIR_S_C_STO_RB 39
+#define TIR_S_C_STO_RW 40
+#define TIR_S_C_STO_RIVB 41
+#define TIR_S_C_STO_PIRR 42
+#define TIR_S_C_MAXSTOCOD 42
+#define TIR_S_C_MINOPRCOD 50
+#define TIR_S_C_OPR_NOP 50
+#define TIR_S_C_OPR_ADD 51
+#define TIR_S_C_OPR_SUB 52
+#define TIR_S_C_OPR_MUL 53
+#define TIR_S_C_OPR_DIV 54
+#define TIR_S_C_OPR_AND 55
+#define TIR_S_C_OPR_IOR 56
+#define TIR_S_C_OPR_EOR 57
+#define TIR_S_C_OPR_NEG 58
+#define TIR_S_C_OPR_COM 59
+#define TIR_S_C_OPR_INSV 60
+#define TIR_S_C_OPR_ASH 61
+#define TIR_S_C_OPR_USH 62
+#define TIR_S_C_OPR_ROT 63
+#define TIR_S_C_OPR_SEL 64
+#define TIR_S_C_OPR_REDEF 65
+#define TIR_S_C_OPR_DFLIT 66
+#define TIR_S_C_MAXOPRCOD 66
+#define TIR_S_C_MINCTLCOD 80
+#define TIR_S_C_CTL_SETRB 80
+#define TIR_S_C_CTL_AUGRB 81
+#define TIR_S_C_CTL_DFLOC 82
+#define TIR_S_C_CTL_STLOC 83
+#define TIR_S_C_CTL_STKDL 84
+#define TIR_S_C_MAXCTLCOD 84
+
+#define ETIR_S_C_MINSTACOD 0 /* Minimum store code */
+#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value */
+#define ETIR_S_C_STA_LW 1 /* Stack longword */
+#define ETIR_S_C_STA_QW 2 /* Stack quadword */
+#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset */
+#define ETIR_S_C_STA_LI 4 /* Stack literal */
+#define ETIR_S_C_STA_MOD 5 /* Stack module */
+#define ETIR_S_C_STA_CKARG 6 /* Check Arguments */
+#define ETIR_S_C_MAXSTACOD 6 /* Maximum stack code */
+#define ETIR_S_C_MINSTOCOD 50 /* Minimum store code */
+#define ETIR_S_C_STO_B 50 /* Store byte */
+#define ETIR_S_C_STO_W 51 /* Store word */
+#define ETIR_S_C_STO_LW 52 /* Store longword */
+#define ETIR_S_C_STO_QW 53 /* Store quadword */
+#define ETIR_S_C_STO_IMMR 54 /* Store immediate Repeated */
+#define ETIR_S_C_STO_GBL 55 /* Store global */
+#define ETIR_S_C_STO_CA 56 /* Store code address */
+#define ETIR_S_C_STO_RB 57 /* Store relative branch */
+#define ETIR_S_C_STO_AB 58 /* Store absolute branch */
+#define ETIR_S_C_STO_OFF 59 /* Store offset within psect */
+#define ETIR_S_C_STO_IMM 61 /* Store immediate */
+#define ETIR_S_C_STO_GBL_LW 62 /* Store global Longword */
+#define ETIR_S_C_STO_LP_PSB 63 /* STO_LP_PSB not valid in level 2 use STC_LP_PSB */
+#define ETIR_S_C_STO_HINT_GBL 64 /* Store 14 bit HINT at global address */
+#define ETIR_S_C_STO_HINT_PS 65 /* Store 14 bit HINT at psect + offset */
+#define ETIR_S_C_MAXSTOCOD 65 /* Maximum store code */
+#define ETIR_S_C_MINOPRCOD 100 /* Minimum operate code */
+#define ETIR_S_C_OPR_NOP 100 /* No-op */
+#define ETIR_S_C_OPR_ADD 101 /* Add */
+#define ETIR_S_C_OPR_SUB 102 /* Subtract */
+#define ETIR_S_C_OPR_MUL 103 /* Multiply */
+#define ETIR_S_C_OPR_DIV 104 /* Divide */
+#define ETIR_S_C_OPR_AND 105 /* Logical AND */
+#define ETIR_S_C_OPR_IOR 106 /* Logical inclusive OR */
+#define ETIR_S_C_OPR_EOR 107 /* Logical exclusive OR */
+#define ETIR_S_C_OPR_NEG 108 /* Negate */
+#define ETIR_S_C_OPR_COM 109 /* Complement */
+#define ETIR_S_C_OPR_INSV 110 /* Insert bit field */
+#define ETIR_S_C_OPR_ASH 111 /* Arithmetic shift */
+#define ETIR_S_C_OPR_USH 112 /* Unsigned shift */
+#define ETIR_S_C_OPR_ROT 113 /* Rotate */
+#define ETIR_S_C_OPR_SEL 114 /* Select one of three longwords on top of stack */
+#define ETIR_S_C_OPR_REDEF 115 /* Redefine this symbol after pass 2 */
+#define ETIR_S_C_OPR_DFLIT 116 /* Define a literal */
+#define ETIR_S_C_MAXOPRCOD 116 /* Maximum operate code */
+#define ETIR_S_C_MINCTLCOD 150 /* Minimum control code */
+#define ETIR_S_C_CTL_SETRB 150 /* Set relocation base */
+#define ETIR_S_C_CTL_AUGRB 151 /* Augment relocation base */
+#define ETIR_S_C_CTL_DFLOC 152 /* Define debug location */
+#define ETIR_S_C_CTL_STLOC 153 /* Set debug location */
+#define ETIR_S_C_CTL_STKDL 154 /* Stack debug location */
+#define ETIR_S_C_MAXCTLCOD 154 /* Maximum control code */
+#define ETIR_S_C_MINSTCCOD 200 /* Minimum store-conditional code */
+#define ETIR_S_C_STC_LP 200 /* Store-conditional Linkage Pair */
+#define ETIR_S_C_STC_LP_PSB 201 /* Store-conditional Linkage Pair with Procedure Signature */
+#define ETIR_S_C_STC_GBL 202 /* Store-conditional Address at global address */
+#define ETIR_S_C_STC_GCA 203 /* Store-conditional Code Address at global address */
+#define ETIR_S_C_STC_PS 204 /* Store-conditional Address at psect + offset */
+#define ETIR_S_C_STC_NOP_GBL 205 /* Store-conditional NOP at address of global */
+#define ETIR_S_C_STC_NOP_PS 206 /* Store-conditional NOP at pect + offset */
+#define ETIR_S_C_STC_BSR_GBL 207 /* Store-conditional BSR at global address */
+#define ETIR_S_C_STC_BSR_PS 208 /* Store-conditional BSR at pect + offset */
+#define ETIR_S_C_STC_LDA_GBL 209 /* Store-conditional LDA at global address */
+#define ETIR_S_C_STC_LDA_PS 210 /* Store-conditional LDA at psect + offset */
+#define ETIR_S_C_STC_BOH_GBL 211 /* Store-conditional BSR or Hint at global address */
+#define ETIR_S_C_STC_BOH_PS 212 /* Store-conditional BSR or Hint at pect + offset */
+#define ETIR_S_C_STC_NBH_GBL 213 /* Store-conditional NOP,BSR or HINT at global address */
+#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset */
+#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code */
+
+/* VMS Global symbol definition record (GSD/EGSD). */
+
+#define GSD_S_K_ENTRIES 1
+#define GSD_S_C_ENTRIES 1
+#define GSD_S_C_PSC 0
+#define GSD_S_C_SYM 1
+#define GSD_S_C_EPM 2
+#define GSD_S_C_PRO 3
+#define GSD_S_C_SYMW 4
+#define GSD_S_C_EPMW 5
+#define GSD_S_C_PROW 6
+#define GSD_S_C_IDC 7
+#define GSD_S_C_ENV 8
+#define GSD_S_C_LSY 9
+#define GSD_S_C_LEPM 10
+#define GSD_S_C_LPRO 11
+#define GSD_S_C_SPSC 12
+#define GSD_S_C_SYMV 13
+#define GSD_S_C_EPMV 14
+#define GSD_S_C_PROV 15
+#define GSD_S_C_MAXRECTYP 15
+
+#define EGSD_S_K_ENTRIES 2 /* Offset to first entry in record */
+#define EGSD_S_C_ENTRIES 2 /* Offset to first entry in record */
+#define EGSD_S_C_PSC 0 /* Psect definition */
+#define EGSD_S_C_SYM 1 /* Symbol specification */
+#define EGSD_S_C_IDC 2 /* Random entity check */
+#define EGSD_S_C_SPSC 5 /* Shareable image psect definition */
+#define EGSD_S_C_SYMV 6 /* Vectored (dual-valued) versions of SYM, */
+#define EGSD_S_C_SYMM 7 /* Masked versions of SYM, */
+#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM */
+#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined */
+
+#define GPS_S_M_PIC 1
+#define GPS_S_M_LIB 2
+#define GPS_S_M_OVR 4
+#define GPS_S_M_REL 8
+#define GPS_S_M_GBL 16
+#define GPS_S_M_SHR 32
+#define GPS_S_M_EXE 64
+#define GPS_S_M_RD 128
+#define GPS_S_M_WRT 256
+#define GPS_S_M_VEC 512
+#define GPS_S_K_NAME 9
+#define GPS_S_C_NAME 9
+
+#define EGPS_S_V_PIC 0x0001
+#define EGPS_S_V_LIB 0x0002
+#define EGPS_S_V_OVR 0x0004
+#define EGPS_S_V_REL 0x0008
+#define EGPS_S_V_GBL 0x0010
+#define EGPS_S_V_SHR 0x0020
+#define EGPS_S_V_EXE 0x0040
+#define EGPS_S_V_RD 0x0080
+#define EGPS_S_V_WRT 0x0100
+#define EGPS_S_V_VEC 0x0200
+#define EGPS_S_V_NOMOD 0x0400
+#define EGPS_S_V_COM 0x0800
+
+#define GSY_S_M_WEAK 1
+#define GSY_S_M_DEF 2
+#define GSY_S_M_UNI 4
+#define GSY_S_M_REL 8
+
+#define EGSY_S_V_WEAK 0x0001
+#define EGSY_S_V_DEF 0x0002
+#define EGSY_S_V_UNI 0x0004
+#define EGSY_S_V_REL 0x0008
+#define EGSY_S_V_COMM 0x0010
+#define EGSY_S_V_VECEP 0x0020
+#define EGSY_S_V_NORM 0x0040
+
+#define LSY_S_M_DEF 2
+#define LSY_S_M_REL 8
+
+#define ENV_S_M_DEF 1
+#define ENV_S_M_NESTED 2
+
+/*
+ * Debugger symbol definitions: These are done by hand, as no
+ * machine-readable version seems
+ * to be available.
+ */
+#define DST_S_C_C 7 /* Language == "C" */
+#define DST_S_C_CXX 15 /* Language == "C++" */
+#define DST_S_C_VERSION 153
+#define DST_S_C_SOURCE 155 /* Source file */
+#define DST_S_C_PROLOG 162
+#define DST_S_C_BLKBEG 176 /* Beginning of block */
+#define DST_S_C_BLKEND 177 /* End of block */
+#define DST_S_C_ENTRY 181
+#define DST_S_C_PSECT 184
+#define DST_S_C_LINE_NUM 185 /* Line Number */
+#define DST_S_C_LBLORLIT 186
+#define DST_S_C_LABEL 187
+#define DST_S_C_MODBEG 188 /* Beginning of module */
+#define DST_S_C_MODEND 189 /* End of module */
+#define DST_S_C_RTNBEG 190 /* Beginning of routine */
+#define DST_S_C_RTNEND 191 /* End of routine */
+#define DST_S_C_DELTA_PC_W 1 /* Incr PC */
+#define DST_S_C_INCR_LINUM 2 /* Incr Line # */
+#define DST_S_C_INCR_LINUM_W 3 /* Incr Line # */
+#define DST_S_C_SET_LINUM_INCR 4
+#define DST_S_C_SET_LINUM_INCR_W 5
+#define DST_S_C_RESET_LINUM_INCR 6
+#define DST_S_C_BEG_STMT_MODE 7
+#define DST_S_C_END_STMT_MODE 8
+#define DST_S_C_SET_LINE_NUM 9 /* Set Line # */
+#define DST_S_C_SET_PC 10
+#define DST_S_C_SET_PC_W 11
+#define DST_S_C_SET_PC_L 12
+#define DST_S_C_SET_STMTNUM 13
+#define DST_S_C_TERM 14 /* End of lines */
+#define DST_S_C_TERM_W 15 /* End of lines */
+#define DST_S_C_SET_ABS_PC 16 /* Set PC */
+#define DST_S_C_DELTA_PC_L 17 /* Incr PC */
+#define DST_S_C_INCR_LINUM_L 18 /* Incr Line # */
+#define DST_S_C_SET_LINUM_B 19 /* Set Line # */
+#define DST_S_C_SET_LINUM_L 20 /* Set Line # */
+#define DST_S_C_TERM_L 21 /* End of lines */
+/* these are used with DST_S_C_SOURCE */
+#define DST_S_C_SRC_DECLFILE 1 /* Declare source file */
+#define DST_S_C_SRC_SETFILE 2 /* Set source file */
+#define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value */
+#define DST_S_C_SRC_SETREC_W 4 /* Set record, word value */
+#define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter */
+#define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter */
+#define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record */
+/* the following are the codes for the various data types. Anything not on
+ * the list is included under 'advanced_type'
+ */
+#define DBG_S_C_UCHAR 0x02
+#define DBG_S_C_USINT 0x03
+#define DBG_S_C_ULINT 0x04
+#define DBG_S_C_UQUAD 0x05
+#define DBG_S_C_SCHAR 0x06
+#define DBG_S_C_SSINT 0x07
+#define DBG_S_C_SLINT 0x08
+#define DBG_S_C_SQUAD 0x09
+#define DBG_S_C_REAL4 0x0a
+#define DBG_S_C_REAL8 0x0b /* D_float double */
+#define DBG_S_C_COMPLX4 0x0c /* 2xF_float complex float */
+#define DBG_S_C_COMPLX8 0x0d /* 2xD_float complex double */
+#define DBG_S_C_REAL8_G 0x1b /* G_float double */
+#define DBG_S_C_COMPLX8_G 0x1d /* 2xG_float complex double */
+#define DBG_S_C_FUNCTION_ADDR 0x17
+#define DBG_S_C_ADVANCED_TYPE 0xa3
+/* Some of these are just for future reference. [pr]
+ */
+#define DBG_S_C_UBITA 0x01 /* unsigned, aligned bit field */
+#define DBG_S_C_UBITU 0x22 /* unsigned, unaligned bit field */
+#define DBG_S_C_SBITA 0x29 /* signed, aligned bit field */
+#define DBG_S_C_SBITU 0x2a /* signed, unaligned bit field */
+#define DBG_S_C_CSTRING 0x2e /* asciz ('\0' terminated) string */
+#define DBG_S_C_WCHAR 0x38 /* wchar_t */
+/* These are descriptor class codes.
+ */
+#define DSC_K_CLASS_S 0x01 /* static (fixed length) */
+#define DSC_K_CLASS_D 0x02 /* dynamic string (not via malloc!) */
+#define DSC_K_CLASS_A 0x04 /* array */
+#define DSC_K_CLASS_UBS 0x0d /* unaligned bit string */
+/* These are the codes that are used to generate the definitions of struct
+ * union and enum records
+ */
+#define DBG_S_C_ENUM_ITEM 0xa4
+#define DBG_S_C_ENUM_START 0xa5
+#define DBG_S_C_ENUM_END 0xa6
+#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */
+#define DBG_S_C_STRUCT_START 0xab
+#define DBG_S_C_STRUCT_END 0xac
+#define DST_K_TYPSPEC 0xaf /* type specification */
+/* These codes are used in the generation of the symbol definition records
+ */
+#define DST_K_VFLAGS_NOVAL 0x80 /* struct definition only */
+#define DST_K_VFLAGS_DSC 0xfa /* descriptor used */
+#define DST_K_VFLAGS_TVS 0xfb /* trailing value specified */
+#define DST_K_VS_FOLLOWS 0xfd /* value spec follows */
+#define DST_K_VFLAGS_BITOFFS 0xff /* value contains bit offset */
+#define DST_K_VALKIND_LITERAL 0
+#define DST_K_VALKIND_ADDR 1
+#define DST_K_VALKIND_DESC 2
+#define DST_K_VALKIND_REG 3
+#define DST_K_REG_VAX_AP 0x0c /* R12 */
+#define DST_K_REG_VAX_FP 0x0d /* R13 */
+#define DST_K_REG_VAX_SP 0x0e /* R14 */
+#define DST_V_VALKIND 0 /* offset of valkind field */
+#define DST_V_INDIRECT 2 /* offset to indirect bit */
+#define DST_V_DISP 3 /* offset to displacement bit */
+#define DST_V_REGNUM 4 /* offset to register number */
+#define DST_M_INDIRECT (1<<DST_V_INDIRECT)
+#define DST_M_DISP (1<<DST_V_DISP)
+#define DBG_C_FUNCTION_PARAM /* 0xc9 */ \
+ (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_AP<<DST_V_REGNUM))
+#define DBG_C_LOCAL_SYM /* 0xd9 */ \
+ (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_FP<<DST_V_REGNUM))
+/* Kinds of value specifications
+ */
+#define DST_K_VS_ALLOC_SPLIT 3 /* split lifetime */
+/* Kinds of type specifications
+ */
+#define DST_K_TS_ATOM 0x01 /* atomic type specification */
+#define DST_K_TS_DSC 0x02 /* descriptor type spec */
+#define DST_K_TS_IND 0x03 /* indirect type specification */
+#define DST_K_TS_TPTR 0x04 /* typed pointer type spec */
+#define DST_K_TS_PTR 0x05 /* pointer type spec */
+#define DST_K_TS_ARRAY 0x07 /* array type spec */
+#define DST_K_TS_NOV_LENG 0x0e /* novel length type spec */
+/* These are the codes that are used in the suffix records to determine the
+ * actual data type
+ */
+#define DBG_S_C_BASIC DST_K_TS_ATOM
+#define DBG_S_C_BASIC_ARRAY DST_K_TS_DSC
+#define DBG_S_C_STRUCT DST_K_TS_IND
+#define DBG_S_C_POINTER DST_K_TS_TPTR
+#define DBG_S_C_VOID DST_K_TS_PTR
+#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
+
+/* VMS Module header record (EMH) definitions. */
+
+#define MHD_S_C_MHD 0
+#define MHD_S_C_LNM 1
+#define MHD_S_C_SRC 2
+#define MHD_S_C_TTL 3
+#define MHD_S_C_CPR 4
+#define MHD_S_C_MTC 5
+#define MHD_S_C_GTX 6
+#define MHD_S_C_MAXHDRTYP 6
+
+#define EMH_S_C_MHD 0 /* Main header record */
+#define EMH_S_C_LNM 1 /* Language name and version */
+#define EMH_S_C_SRC 2 /* Source file specification */
+#define EMH_S_C_TTL 3 /* Title text of module */
+#define EMH_S_C_CPR 4 /* Copyright notice */
+#define EMH_S_C_MTC 5 /* Maintenance status */
+#define EMH_S_C_GTX 6 /* General text */
+#define EMH_S_C_MAXHDRTYP 6 /* Maximum allowable type */
+
+/* vms.c. */
+
+extern asymbol *_bfd_vms_make_empty_symbol PARAMS ((bfd *abfd));
+
+/* vms-gsd.c. */
+
+extern int _bfd_vms_slurp_gsd PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_gsd PARAMS ((bfd *abfd, int objtype));
+
+/* vms-mhd.c. */
+
+extern int _bfd_vms_slurp_hdr PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_hdr PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_eom PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_eom PARAMS ((bfd *abfd, int objtype));
+
+/* vms-tir.c. */
+
+extern int _bfd_vms_slurp_tir PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_dbg PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_tbt PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_slurp_lnk PARAMS ((bfd *abfd, int objtype));
+
+extern int _bfd_vms_write_tir PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_tbt PARAMS ((bfd *abfd, int objtype));
+extern int _bfd_vms_write_dbg PARAMS ((bfd *abfd, int objtype));
+
+/* The r_type field in a reloc is one of the following values. */
+#define ALPHA_R_IGNORE 0
+#define ALPHA_R_REFQUAD 1
+#define ALPHA_R_BRADDR 2
+#define ALPHA_R_HINT 3
+#define ALPHA_R_SREL16 4
+#define ALPHA_R_SREL32 5
+#define ALPHA_R_SREL64 6
+#define ALPHA_R_OP_PUSH 7
+#define ALPHA_R_OP_STORE 8
+#define ALPHA_R_OP_PSUB 9
+#define ALPHA_R_OP_PRSHIFT 10
+#define ALPHA_R_LINKAGE 11
+#define ALPHA_R_REFLONG 12
+#define ALPHA_R_CODEADDR 13
+
+/* Object language definitions. */
+
+#define OBJ_S_C_HDR 0 /*VAX module header record */
+#define OBJ_S_C_GSD 1 /*VAX global symbol definition record */
+#define OBJ_S_C_TIR 2 /*VAX text information record */
+#define OBJ_S_C_EOM 3 /*VAX end of module record */
+#define OBJ_S_C_DBG 4 /*VAX Debugger information record */
+#define OBJ_S_C_TBT 5 /*VAX Traceback information record */
+#define OBJ_S_C_LNK 6 /*VAX linker options record */
+#define OBJ_S_C_EOMW 7 /*VAX end of module word-psect record */
+#define OBJ_S_C_MAXRECTYP 7 /*VAX Last assigned record type */
+#define EOBJ_S_C_EMH 8 /*EVAX module header record */
+#define EOBJ_S_C_EEOM 9 /*EVAX end of module record */
+#define EOBJ_S_C_EGSD 10 /*EVAX global symbol definition record */
+#define EOBJ_S_C_ETIR 11 /*EVAX text information record */
+#define EOBJ_S_C_EDBG 12 /*EVAX Debugger information record */
+#define EOBJ_S_C_ETBT 13 /*EVAX Traceback information record */
+#define EOBJ_S_C_MAXRECTYP 13 /*EVAX Last assigned record type */
+#define OBJ_S_K_SUBTYP 1
+#define OBJ_S_C_SUBTYP 1
+#define EOBJ_S_K_SUBTYP 4
+#define EOBJ_S_C_SUBTYP 4
+#define OBJ_S_C_MAXRECSIZ 2048 /*Maximum legal record size */
+#define EOBJ_S_C_MAXRECSIZ 8192 /*Maximum legal record size */
+#define OBJ_S_C_STRLVL 0 /*Structure level */
+#define EOBJ_S_C_STRLVL 2 /*Structure level */
+#define OBJ_S_C_SYMSIZ 31 /*Maximum symbol length */
+#define EOBJ_S_C_SYMSIZ 64 /*Maximum symbol length */
+#define EOBJ_S_C_SECSIZ 31 /*Maximum section name length */
+#define OBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
+#define EOBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
+#define OBJ_S_C_PSCALILIM 9 /*Maximum p-sect alignment */
+#define EOBJ_S_C_PSCALILIM 16 /*Maximum p-sect alignment */
+
+#define EVAX_OFFSET 256 /*type offset for EVAX codes in switch */
+/* Miscellaneous definitions. */
+
+#if __GNUC__
+typedef unsigned long long uquad;
+#else
+typedef unsigned long uquad;
+#endif
+
+#define MAX_OUTREC_SIZE 4096
+#define MIN_OUTREC_LUFT 64
+
+typedef struct _vms_section {
+ unsigned char *contents;
+ bfd_vma offset;
+ bfd_size_type size;
+ struct _vms_section *next;
+} vms_section;
+
+extern boolean _bfd_save_vms_section
+ PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
+ bfd_size_type count));
+extern vms_section *_bfd_get_vms_section PARAMS ((bfd *abfd, int index));
+
+typedef struct _vms_reloc {
+ struct _vms_reloc *next;
+ arelent *reloc;
+ asection *section;
+} vms_reloc;
+
+/* vms module header */
+
+struct hdr_struc {
+ int hdr_b_strlvl;
+ long hdr_l_arch1;
+ long hdr_l_arch2;
+ long hdr_l_recsiz;
+ char *hdr_t_name;
+ char *hdr_t_version;
+ char *hdr_t_date;
+ char *hdr_c_lnm;
+ char *hdr_c_src;
+ char *hdr_c_ttl;
+};
+
+
+/* vms end of module */
+
+struct eom_struc {
+ long eom_l_total_lps;
+ unsigned char eom_b_comcod;
+ boolean eom_has_transfer;
+ unsigned char eom_b_tfrflg;
+ long eom_l_psindx;
+ long eom_l_tfradr;
+};
+
+enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE, FF_VAX };
+
+typedef struct vms_symbol_struct {
+ struct bfd_hash_entry bfd_hash;
+ asymbol *symbol;
+} vms_symbol_entry;
+
+/* stack value for push/pop commands */
+
+struct stack_struct {
+ uquad value;
+ int psect;
+};
+#define STACKSIZE 8192
+
+/* location stack definitions for CTL_DFLOC, CTL_STLOC, and CTL_STKDL */
+
+struct location_struct {
+ unsigned long value;
+ int psect;
+};
+#define LOCATION_SAVE_SIZE 32
+
+#define VMS_SECTION_COUNT 1024
+
+struct vms_private_data_struct {
+ int is_vax;
+ boolean fixup_done; /* Flag to indicate if all
+ section pointers and PRIV(sections)
+ are set up correctly */
+ unsigned char *vms_buf; /* buffer to record */
+ int buf_size; /* max size of buffer */
+ unsigned char *vms_rec; /* actual record ptr */
+ int rec_length; /* remaining record length */
+ int rec_size; /* actual record size */
+ int rec_type; /* actual record type */
+ enum file_format_enum file_format;
+
+ struct hdr_struc hdr_data; /* data from HDR/EMH record */
+ struct eom_struc eom_data; /* data from EOM/EEOM record */
+ int section_count; /* # of sections in following array */
+ asection **sections; /* array of GSD/EGSD sections */
+ int gsd_sym_count; /* # of GSD/EGSD symbols */
+ asymbol **symbols; /* vector of GSD/EGSD symbols */
+ struct proc_value *procedure;
+
+ struct stack_struct *stack;
+ int stackptr;
+
+ vms_section *vms_section_table[VMS_SECTION_COUNT];
+
+ struct bfd_hash_table *vms_symbol_table;
+ struct symbol_cache_entry **symcache;
+ int symnum;
+
+ struct location_struct *location_stack;
+
+ asection *image_section; /* section for image_ptr */
+ unsigned char *image_ptr; /* a pointer to section->contents */
+
+ unsigned char pdsc[8]; /* procedure descriptor */
+
+ /* Output routine storage */
+
+ unsigned char *output_buf; /* output data */
+ int push_level;
+ int pushed_size;
+ int length_pos;
+ int output_size;
+ int output_alignment;
+
+ /* linkage index counter
+ used by conditional store commands (ETIR_S_C_STC_) */
+
+ int vms_linkage_index;
+
+ /* see tc-alpha.c of gas for a description. */
+ int flag_hash_long_names; /* -+, hash instead of truncate */
+ int flag_show_after_trunc; /* -H, show hashing/truncation */
+};
+
+#define PRIV(name) ((struct vms_private_data_struct *)abfd->tdata.any)->name
+
+#define SECTION_NAME_TEMPLATE "__SEC__%d"
+
+#if VMS_DEBUG
+extern void _bfd_vms_debug PARAMS((int level, char *format, ...));
+extern void _bfd_hexdump
+ PARAMS ((int level, unsigned char *ptr, int size, int offset));
+
+#define vms_debug _bfd_vms_debug
+#endif
+
+extern struct bfd_hash_entry *_bfd_vms_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string));
+extern void _bfd_vms_get_header_values
+ PARAMS ((bfd *abfd, unsigned char *buf, int *type, int *length));
+extern int _bfd_vms_get_record PARAMS ((bfd *abfd));
+extern int _bfd_vms_next_record PARAMS ((bfd *abfd));
+
+extern char *_bfd_vms_save_sized_string PARAMS ((unsigned char *str, int size));
+extern char *_bfd_vms_save_counted_string PARAMS ((unsigned char *ptr));
+extern void _bfd_vms_push PARAMS ((bfd *abfd, uquad val, int psect));
+extern uquad _bfd_vms_pop PARAMS ((bfd *abfd, int *psect));
+
+extern boolean _bfd_save_vms_section
+ PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
+ bfd_size_type count));
+extern void _bfd_vms_output_begin
+ PARAMS ((bfd *abfd, int rectype, int rechead));
+extern void _bfd_vms_output_alignment PARAMS ((bfd *abfd, int alignto));
+extern void _bfd_vms_output_push PARAMS ((bfd *abfd));
+extern void _bfd_vms_output_pop PARAMS ((bfd *abfd));
+extern void _bfd_vms_output_flush PARAMS ((bfd *abfd));
+extern void _bfd_vms_output_end PARAMS ((bfd *abfd));
+extern int _bfd_vms_output_check PARAMS ((bfd *abfd, int size));
+extern void _bfd_vms_output_byte PARAMS ((bfd *abfd, unsigned int value));
+extern void _bfd_vms_output_short PARAMS ((bfd *abfd, unsigned int value));
+extern void _bfd_vms_output_long PARAMS ((bfd *abfd, unsigned long value));
+extern void _bfd_vms_output_quad PARAMS ((bfd *abfd, uquad value));
+extern void _bfd_vms_output_counted PARAMS ((bfd *abfd, char *value));
+extern void _bfd_vms_output_dump PARAMS ((bfd *abfd, unsigned char *data,
+ int length));
+extern void _bfd_vms_output_fill PARAMS ((bfd *abfd, int value, int length));
+extern char *_bfd_vms_length_hash_symbol PARAMS ((bfd *abfd, const char *in, int maxlen));
+
+extern vms_symbol_entry *_bfd_vms_enter_symbol PARAMS ((bfd *abfd, char *name));
+
+#endif /* VMS_H */
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
new file mode 100644
index 00000000000..c882d237328
--- /dev/null
+++ b/bfd/xcofflink.c
@@ -0,0 +1,6635 @@
+/* POWER/PowerPC XCOFF linker support.
+ Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+/* This file holds the XCOFF linker code. */
+
+#define STRING_SIZE_SIZE (4)
+
+/* In order to support linking different object file formats into an
+ XCOFF format, we need to be able to determine whether a particular
+ bfd_target is an XCOFF vector. FIXME: We need to rethink this
+ whole approach. */
+#define XCOFF_XVECP(xv) \
+ (strcmp ((xv)->name, "aixcoff-rs6000") == 0 \
+ || strcmp ((xv)->name, "xcoff-powermac") == 0)
+
+/* Get the XCOFF hash table entries for a BFD. */
+#define obj_xcoff_sym_hashes(bfd) \
+ ((struct xcoff_link_hash_entry **) obj_coff_sym_hashes (bfd))
+
+/* XCOFF relocation types. These probably belong in a header file
+ somewhere. The relocations are described in the function
+ _bfd_ppc_xcoff_relocate_section in this file. */
+
+#define R_POS (0x00)
+#define R_NEG (0x01)
+#define R_REL (0x02)
+#define R_TOC (0x03)
+#define R_RTB (0x04)
+#define R_GL (0x05)
+#define R_TCL (0x06)
+#define R_BA (0x08)
+#define R_BR (0x0a)
+#define R_RL (0x0c)
+#define R_RLA (0x0d)
+#define R_REF (0x0f)
+#define R_TRL (0x12)
+#define R_TRLA (0x13)
+#define R_RRTBI (0x14)
+#define R_RRTBA (0x15)
+#define R_CAI (0x16)
+#define R_CREL (0x17)
+#define R_RBA (0x18)
+#define R_RBAC (0x19)
+#define R_RBR (0x1a)
+#define R_RBRC (0x1b)
+
+/* The first word of global linkage code. This must be modified by
+ filling in the correct TOC offset. */
+
+#define XCOFF_GLINK_FIRST (0x81820000) /* lwz r12,0(r2) */
+
+/* The remaining words of global linkage code. */
+
+static unsigned long xcoff_glink_code[] =
+{
+ 0x90410014, /* stw r2,20(r1) */
+ 0x800c0000, /* lwz r0,0(r12) */
+ 0x804c0004, /* lwz r2,4(r12) */
+ 0x7c0903a6, /* mtctr r0 */
+ 0x4e800420, /* bctr */
+ 0x0, /* start of traceback table */
+ 0x000c8000, /* traceback table */
+ 0x0 /* traceback table */
+};
+
+#define XCOFF_GLINK_SIZE \
+ (((sizeof xcoff_glink_code / sizeof xcoff_glink_code[0]) * 4) + 4)
+
+/* We reuse the SEC_ROM flag as a mark flag for garbage collection.
+ This flag will only be used on input sections. */
+
+#define SEC_MARK (SEC_ROM)
+
+/* The ldhdr structure. This appears at the start of the .loader
+ section. */
+
+struct internal_ldhdr
+{
+ /* The version number: currently always 1. */
+ unsigned long l_version;
+ /* The number of symbol table entries. */
+ bfd_size_type l_nsyms;
+ /* The number of relocation table entries. */
+ bfd_size_type l_nreloc;
+ /* The length of the import file string table. */
+ bfd_size_type l_istlen;
+ /* The number of import files. */
+ bfd_size_type l_nimpid;
+ /* The offset from the start of the .loader section to the first
+ entry in the import file table. */
+ bfd_size_type l_impoff;
+ /* The length of the string table. */
+ bfd_size_type l_stlen;
+ /* The offset from the start of the .loader section to the first
+ entry in the string table. */
+ bfd_size_type l_stoff;
+};
+
+struct external_ldhdr
+{
+ bfd_byte l_version[4];
+ bfd_byte l_nsyms[4];
+ bfd_byte l_nreloc[4];
+ bfd_byte l_istlen[4];
+ bfd_byte l_nimpid[4];
+ bfd_byte l_impoff[4];
+ bfd_byte l_stlen[4];
+ bfd_byte l_stoff[4];
+};
+
+#define LDHDRSZ (8 * 4)
+
+/* The ldsym structure. This is used to represent a symbol in the
+ .loader section. */
+
+struct internal_ldsym
+{
+ union
+ {
+ /* The symbol name if <= SYMNMLEN characters. */
+ char _l_name[SYMNMLEN];
+ struct
+ {
+ /* Zero if the symbol name is more than SYMNMLEN characters. */
+ long _l_zeroes;
+ /* The offset in the string table if the symbol name is more
+ than SYMNMLEN characters. */
+ long _l_offset;
+ } _l_l;
+ } _l;
+ /* The symbol value. */
+ bfd_vma l_value;
+ /* The symbol section number. */
+ short l_scnum;
+ /* The symbol type and flags. */
+ char l_smtype;
+ /* The symbol storage class. */
+ char l_smclas;
+ /* The import file ID. */
+ bfd_size_type l_ifile;
+ /* Offset to the parameter type check string. */
+ bfd_size_type l_parm;
+};
+
+struct external_ldsym
+{
+ union
+ {
+ bfd_byte _l_name[SYMNMLEN];
+ struct
+ {
+ bfd_byte _l_zeroes[4];
+ bfd_byte _l_offset[4];
+ } _l_l;
+ } _l;
+ bfd_byte l_value[4];
+ bfd_byte l_scnum[2];
+ bfd_byte l_smtype[1];
+ bfd_byte l_smclas[1];
+ bfd_byte l_ifile[4];
+ bfd_byte l_parm[4];
+};
+
+#define LDSYMSZ (8 + 3 * 4 + 2 + 2)
+
+/* These flags are for the l_smtype field (the lower three bits are an
+ XTY_* value). */
+
+/* Imported symbol. */
+#define L_IMPORT (0x40)
+/* Entry point. */
+#define L_ENTRY (0x20)
+/* Exported symbol. */
+#define L_EXPORT (0x10)
+
+/* The ldrel structure. This is used to represent a reloc in the
+ .loader section. */
+
+struct internal_ldrel
+{
+ /* The reloc address. */
+ bfd_vma l_vaddr;
+ /* The symbol table index in the .loader section symbol table. */
+ bfd_size_type l_symndx;
+ /* The relocation type and size. */
+ short l_rtype;
+ /* The section number this relocation applies to. */
+ short l_rsecnm;
+};
+
+struct external_ldrel
+{
+ bfd_byte l_vaddr[4];
+ bfd_byte l_symndx[4];
+ bfd_byte l_rtype[2];
+ bfd_byte l_rsecnm[2];
+};
+
+#define LDRELSZ (2 * 4 + 2 * 2)
+
+/* The list of import files. */
+
+struct xcoff_import_file
+{
+ /* The next entry in the list. */
+ struct xcoff_import_file *next;
+ /* The path. */
+ const char *path;
+ /* The file name. */
+ const char *file;
+ /* The member name. */
+ const char *member;
+};
+
+/* An entry in the XCOFF linker hash table. */
+
+struct xcoff_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+
+ /* Symbol index in output file. Set to -1 initially. Set to -2 if
+ there is a reloc against this symbol. */
+ long indx;
+
+ /* If we have created a TOC entry for this symbol, this is the .tc
+ section which holds it. */
+ asection *toc_section;
+
+ union
+ {
+ /* If we have created a TOC entry (the XCOFF_SET_TOC flag is
+ set), this is the offset in toc_section. */
+ bfd_vma toc_offset;
+ /* If the TOC entry comes from an input file, this is set to the
+ symbol index of the C_HIDEXT XMC_TC or XMC_TD symbol. */
+ long toc_indx;
+ } u;
+
+ /* If this symbol is a function entry point which is called, this
+ field holds a pointer to the function descriptor. If this symbol
+ is a function descriptor, this field holds a pointer to the
+ function entry point. */
+ struct xcoff_link_hash_entry *descriptor;
+
+ /* The .loader symbol table entry, if there is one. */
+ struct internal_ldsym *ldsym;
+
+ /* If XCOFF_BUILT_LDSYM is set, this is the .loader symbol table
+ index. If XCOFF_BUILD_LDSYM is clear, and XCOFF_IMPORT is set,
+ this is the l_ifile value. */
+ long ldindx;
+
+ /* Some linker flags. */
+ unsigned short flags;
+ /* Symbol is referenced by a regular object. */
+#define XCOFF_REF_REGULAR (01)
+ /* Symbol is defined by a regular object. */
+#define XCOFF_DEF_REGULAR (02)
+ /* Symbol is defined by a dynamic object. */
+#define XCOFF_DEF_DYNAMIC (04)
+ /* Symbol is used in a reloc being copied into the .loader section. */
+#define XCOFF_LDREL (010)
+ /* Symbol is the entry point. */
+#define XCOFF_ENTRY (020)
+ /* Symbol is called; this is, it appears in a R_BR reloc. */
+#define XCOFF_CALLED (040)
+ /* Symbol needs the TOC entry filled in. */
+#define XCOFF_SET_TOC (0100)
+ /* Symbol is explicitly imported. */
+#define XCOFF_IMPORT (0200)
+ /* Symbol is explicitly exported. */
+#define XCOFF_EXPORT (0400)
+ /* Symbol has been processed by xcoff_build_ldsyms. */
+#define XCOFF_BUILT_LDSYM (01000)
+ /* Symbol is mentioned by a section which was not garbage collected. */
+#define XCOFF_MARK (02000)
+ /* Symbol size is recorded in size_list list from hash table. */
+#define XCOFF_HAS_SIZE (04000)
+ /* Symbol is a function descriptor. */
+#define XCOFF_DESCRIPTOR (010000)
+ /* Multiple definitions have been for the symbol. */
+#define XCOFF_MULTIPLY_DEFINED (020000)
+
+ /* The storage mapping class. */
+ unsigned char smclas;
+};
+
+/* The XCOFF linker hash table. */
+
+struct xcoff_link_hash_table
+{
+ struct bfd_link_hash_table root;
+
+ /* The .debug string hash table. We need to compute this while
+ reading the input files, so that we know how large the .debug
+ section will be before we assign section positions. */
+ struct bfd_strtab_hash *debug_strtab;
+
+ /* The .debug section we will use for the final output. */
+ asection *debug_section;
+
+ /* The .loader section we will use for the final output. */
+ asection *loader_section;
+
+ /* A count of non TOC relative relocs which will need to be
+ allocated in the .loader section. */
+ size_t ldrel_count;
+
+ /* The .loader section header. */
+ struct internal_ldhdr ldhdr;
+
+ /* The .gl section we use to hold global linkage code. */
+ asection *linkage_section;
+
+ /* The .tc section we use to hold toc entries we build for global
+ linkage code. */
+ asection *toc_section;
+
+ /* The .ds section we use to hold function descriptors which we
+ create for exported symbols. */
+ asection *descriptor_section;
+
+ /* The list of import files. */
+ struct xcoff_import_file *imports;
+
+ /* Required alignment of sections within the output file. */
+ unsigned long file_align;
+
+ /* Whether the .text section must be read-only. */
+ boolean textro;
+
+ /* Whether garbage collection was done. */
+ boolean gc;
+
+ /* A linked list of symbols for which we have size information. */
+ struct xcoff_link_size_list
+ {
+ struct xcoff_link_size_list *next;
+ struct xcoff_link_hash_entry *h;
+ bfd_size_type size;
+ } *size_list;
+
+ /* Magic sections: _text, _etext, _data, _edata, _end, end. */
+ asection *special_sections[6];
+};
+
+/* Information we keep for each section in the output file during the
+ final link phase. */
+
+struct xcoff_link_section_info
+{
+ /* The relocs to be output. */
+ struct internal_reloc *relocs;
+ /* For each reloc against a global symbol whose index was not known
+ when the reloc was handled, the global hash table entry. */
+ struct xcoff_link_hash_entry **rel_hashes;
+ /* If there is a TOC relative reloc against a global symbol, and the
+ index of the TOC symbol is not known when the reloc was handled,
+ an entry is added to this linked list. This is not an array,
+ like rel_hashes, because this case is quite uncommon. */
+ struct xcoff_toc_rel_hash
+ {
+ struct xcoff_toc_rel_hash *next;
+ struct xcoff_link_hash_entry *h;
+ struct internal_reloc *rel;
+ } *toc_rel_hashes;
+};
+
+/* Information that we pass around while doing the final link step. */
+
+struct xcoff_final_link_info
+{
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* Hash table for long symbol names. */
+ struct bfd_strtab_hash *strtab;
+ /* Array of information kept for each output section, indexed by the
+ target_index field. */
+ struct xcoff_link_section_info *section_info;
+ /* Symbol index of last C_FILE symbol (-1 if none). */
+ long last_file_index;
+ /* Contents of last C_FILE symbol. */
+ struct internal_syment last_file;
+ /* Symbol index of TOC symbol. */
+ long toc_symindx;
+ /* Start of .loader symbols. */
+ struct external_ldsym *ldsym;
+ /* Next .loader reloc to swap out. */
+ struct external_ldrel *ldrel;
+ /* File position of start of line numbers. */
+ file_ptr line_filepos;
+ /* Buffer large enough to hold swapped symbols of any input file. */
+ struct internal_syment *internal_syms;
+ /* Buffer large enough to hold output indices of symbols of any
+ input file. */
+ long *sym_indices;
+ /* Buffer large enough to hold output symbols for any input file. */
+ bfd_byte *outsyms;
+ /* Buffer large enough to hold external line numbers for any input
+ section. */
+ bfd_byte *linenos;
+ /* Buffer large enough to hold any input section. */
+ bfd_byte *contents;
+ /* Buffer large enough to hold external relocs of any input section. */
+ bfd_byte *external_relocs;
+};
+
+static void xcoff_swap_ldhdr_in
+ PARAMS ((bfd *, const struct external_ldhdr *, struct internal_ldhdr *));
+static void xcoff_swap_ldhdr_out
+ PARAMS ((bfd *, const struct internal_ldhdr *, struct external_ldhdr *));
+static void xcoff_swap_ldsym_in
+ PARAMS ((bfd *, const struct external_ldsym *, struct internal_ldsym *));
+static void xcoff_swap_ldsym_out
+ PARAMS ((bfd *, const struct internal_ldsym *, struct external_ldsym *));
+static void xcoff_swap_ldrel_in
+ PARAMS ((bfd *, const struct external_ldrel *, struct internal_ldrel *));
+static void xcoff_swap_ldrel_out
+ PARAMS ((bfd *, const struct internal_ldrel *, struct external_ldrel *));
+static struct bfd_hash_entry *xcoff_link_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean xcoff_get_section_contents PARAMS ((bfd *, asection *));
+static struct internal_reloc *xcoff_read_internal_relocs
+ PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean,
+ struct internal_reloc *));
+static boolean xcoff_link_add_object_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean xcoff_link_check_archive_element
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *));
+static boolean xcoff_link_check_ar_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *));
+static boolean xcoff_link_check_dynamic_ar_symbols
+ PARAMS ((bfd *, struct bfd_link_info *, boolean *));
+static bfd_size_type xcoff_find_reloc
+ PARAMS ((struct internal_reloc *, bfd_size_type, bfd_vma));
+static boolean xcoff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *));
+static boolean xcoff_link_add_dynamic_symbols
+ PARAMS ((bfd *, struct bfd_link_info *));
+static boolean xcoff_mark_symbol
+ PARAMS ((struct bfd_link_info *, struct xcoff_link_hash_entry *));
+static boolean xcoff_mark PARAMS ((struct bfd_link_info *, asection *));
+static void xcoff_sweep PARAMS ((struct bfd_link_info *));
+static boolean xcoff_build_ldsyms
+ PARAMS ((struct xcoff_link_hash_entry *, PTR));
+static boolean xcoff_link_input_bfd
+ PARAMS ((struct xcoff_final_link_info *, bfd *));
+static boolean xcoff_write_global_symbol
+ PARAMS ((struct xcoff_link_hash_entry *, PTR));
+static boolean xcoff_reloc_link_order
+ PARAMS ((bfd *, struct xcoff_final_link_info *, asection *,
+ struct bfd_link_order *));
+static int xcoff_sort_relocs PARAMS ((const PTR, const PTR));
+
+/* Routines to swap information in the XCOFF .loader section. If we
+ ever need to write an XCOFF loader, this stuff will need to be
+ moved to another file shared by the linker (which XCOFF calls the
+ ``binder'') and the loader. */
+
+/* Swap in the ldhdr structure. */
+
+static void
+xcoff_swap_ldhdr_in (abfd, src, dst)
+ bfd *abfd;
+ const struct external_ldhdr *src;
+ struct internal_ldhdr *dst;
+{
+ dst->l_version = bfd_get_32 (abfd, src->l_version);
+ dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
+ dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
+ dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
+ dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
+ dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
+ dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
+ dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
+}
+
+/* Swap out the ldhdr structure. */
+
+static void
+xcoff_swap_ldhdr_out (abfd, src, dst)
+ bfd *abfd;
+ const struct internal_ldhdr *src;
+ struct external_ldhdr *dst;
+{
+ bfd_put_32 (abfd, src->l_version, dst->l_version);
+ bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
+ bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
+ bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
+ bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
+ bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
+ bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
+ bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
+}
+
+/* Swap in the ldsym structure. */
+
+static void
+xcoff_swap_ldsym_in (abfd, src, dst)
+ bfd *abfd;
+ const struct external_ldsym *src;
+ struct internal_ldsym *dst;
+{
+ if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0)
+ memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
+ else
+ {
+ dst->_l._l_l._l_zeroes = 0;
+ dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
+ }
+ dst->l_value = bfd_get_32 (abfd, src->l_value);
+ dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
+ dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
+ dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
+ dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
+ dst->l_parm = bfd_get_32 (abfd, src->l_parm);
+}
+
+/* Swap out the ldsym structure. */
+
+static void
+xcoff_swap_ldsym_out (abfd, src, dst)
+ bfd *abfd;
+ const struct internal_ldsym *src;
+ struct external_ldsym *dst;
+{
+ if (src->_l._l_l._l_zeroes != 0)
+ memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
+ else
+ {
+ bfd_put_32 (abfd, 0, dst->_l._l_l._l_zeroes);
+ bfd_put_32 (abfd, src->_l._l_l._l_offset, dst->_l._l_l._l_offset);
+ }
+ bfd_put_32 (abfd, src->l_value, dst->l_value);
+ bfd_put_16 (abfd, src->l_scnum, dst->l_scnum);
+ bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
+ bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
+ bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
+ bfd_put_32 (abfd, src->l_parm, dst->l_parm);
+}
+
+/* Swap in the ldrel structure. */
+
+static void
+xcoff_swap_ldrel_in (abfd, src, dst)
+ bfd *abfd;
+ const struct external_ldrel *src;
+ struct internal_ldrel *dst;
+{
+ dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
+ dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
+ dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
+ dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
+}
+
+/* Swap out the ldrel structure. */
+
+static void
+xcoff_swap_ldrel_out (abfd, src, dst)
+ bfd *abfd;
+ const struct internal_ldrel *src;
+ struct external_ldrel *dst;
+{
+ bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
+ bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
+ bfd_put_16 (abfd, src->l_rtype, dst->l_rtype);
+ bfd_put_16 (abfd, src->l_rsecnm, dst->l_rsecnm);
+}
+
+/* Routines to read XCOFF dynamic information. This don't really
+ belong here, but we already have the ldsym manipulation routines
+ here. */
+
+/* Read the contents of a section. */
+
+static boolean
+xcoff_get_section_contents (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ sec->used_by_bfd = bfd_zalloc (abfd,
+ sizeof (struct coff_section_tdata));
+ if (sec->used_by_bfd == NULL)
+ return false;
+ }
+
+ if (coff_section_data (abfd, sec)->contents == NULL)
+ {
+ coff_section_data (abfd, sec)->contents =
+ (bfd_byte *) bfd_malloc (sec->_raw_size);
+ if (coff_section_data (abfd, sec)->contents == NULL)
+ return false;
+
+ if (! bfd_get_section_contents (abfd, sec,
+ coff_section_data (abfd, sec)->contents,
+ (file_ptr) 0, sec->_raw_size))
+ return false;
+ }
+
+ return true;
+}
+
+/* Get the size required to hold the dynamic symbols. */
+
+long
+_bfd_xcoff_get_dynamic_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ lsec = bfd_get_section_by_name (abfd, ".loader");
+ if (lsec == NULL)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ if (! xcoff_get_section_contents (abfd, lsec))
+ return -1;
+ contents = coff_section_data (abfd, lsec)->contents;
+
+ xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
+
+ return (ldhdr.l_nsyms + 1) * sizeof (asymbol *);
+}
+
+/* Get the dynamic symbols. */
+
+long
+_bfd_xcoff_canonicalize_dynamic_symtab (abfd, psyms)
+ bfd *abfd;
+ asymbol **psyms;
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+ const char *strings;
+ struct external_ldsym *elsym, *elsymend;
+ coff_symbol_type *symbuf;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ lsec = bfd_get_section_by_name (abfd, ".loader");
+ if (lsec == NULL)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ if (! xcoff_get_section_contents (abfd, lsec))
+ return -1;
+ contents = coff_section_data (abfd, lsec)->contents;
+
+ coff_section_data (abfd, lsec)->keep_contents = true;
+
+ xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
+
+ strings = (char *) contents + ldhdr.l_stoff;
+
+ symbuf = ((coff_symbol_type *)
+ bfd_zalloc (abfd, ldhdr.l_nsyms * sizeof (coff_symbol_type)));
+ if (symbuf == NULL)
+ return -1;
+
+ elsym = (struct external_ldsym *) (contents + LDHDRSZ);
+ elsymend = elsym + ldhdr.l_nsyms;
+ for (; elsym < elsymend; elsym++, symbuf++, psyms++)
+ {
+ struct internal_ldsym ldsym;
+
+ xcoff_swap_ldsym_in (abfd, elsym, &ldsym);
+
+ symbuf->symbol.the_bfd = abfd;
+
+ if (ldsym._l._l_l._l_zeroes == 0)
+ symbuf->symbol.name = strings + ldsym._l._l_l._l_offset;
+ else
+ {
+ int i;
+
+ for (i = 0; i < SYMNMLEN; i++)
+ if (ldsym._l._l_name[i] == '\0')
+ break;
+ if (i < SYMNMLEN)
+ symbuf->symbol.name = (char *) elsym->_l._l_name;
+ else
+ {
+ char *c;
+
+ c = bfd_alloc (abfd, SYMNMLEN + 1);
+ if (c == NULL)
+ return -1;
+ memcpy (c, ldsym._l._l_name, SYMNMLEN);
+ c[SYMNMLEN] = '\0';
+ symbuf->symbol.name = c;
+ }
+ }
+
+ if (ldsym.l_smclas == XMC_XO)
+ symbuf->symbol.section = bfd_abs_section_ptr;
+ else
+ symbuf->symbol.section = coff_section_from_bfd_index (abfd,
+ ldsym.l_scnum);
+ symbuf->symbol.value = ldsym.l_value - symbuf->symbol.section->vma;
+
+ symbuf->symbol.flags = BSF_NO_FLAGS;
+ if ((ldsym.l_smtype & L_EXPORT) != 0)
+ symbuf->symbol.flags |= BSF_GLOBAL;
+
+ /* FIXME: We have no way to record the other information stored
+ with the loader symbol. */
+
+ *psyms = (asymbol *) symbuf;
+ }
+
+ *psyms = NULL;
+
+ return ldhdr.l_nsyms;
+}
+
+/* Get the size required to hold the dynamic relocs. */
+
+long
+_bfd_xcoff_get_dynamic_reloc_upper_bound (abfd)
+ bfd *abfd;
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ lsec = bfd_get_section_by_name (abfd, ".loader");
+ if (lsec == NULL)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ if (! xcoff_get_section_contents (abfd, lsec))
+ return -1;
+ contents = coff_section_data (abfd, lsec)->contents;
+
+ xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
+
+ return (ldhdr.l_nreloc + 1) * sizeof (arelent *);
+}
+
+/* The typical dynamic reloc. */
+
+static reloc_howto_type xcoff_dynamic_reloc =
+ HOWTO (0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_POS", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ false); /* pcrel_offset */
+
+/* Get the dynamic relocs. */
+
+long
+_bfd_xcoff_canonicalize_dynamic_reloc (abfd, prelocs, syms)
+ bfd *abfd;
+ arelent **prelocs;
+ asymbol **syms;
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+ arelent *relbuf;
+ struct external_ldrel *elrel, *elrelend;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ lsec = bfd_get_section_by_name (abfd, ".loader");
+ if (lsec == NULL)
+ {
+ bfd_set_error (bfd_error_no_symbols);
+ return -1;
+ }
+
+ if (! xcoff_get_section_contents (abfd, lsec))
+ return -1;
+ contents = coff_section_data (abfd, lsec)->contents;
+
+ xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
+
+ relbuf = (arelent *) bfd_alloc (abfd, ldhdr.l_nreloc * sizeof (arelent));
+ if (relbuf == NULL)
+ return -1;
+
+ elrel = ((struct external_ldrel *)
+ (contents + LDHDRSZ + ldhdr.l_nsyms * LDSYMSZ));
+ elrelend = elrel + ldhdr.l_nreloc;
+ for (; elrel < elrelend; elrel++, relbuf++, prelocs++)
+ {
+ struct internal_ldrel ldrel;
+
+ xcoff_swap_ldrel_in (abfd, elrel, &ldrel);
+
+ if (ldrel.l_symndx >= 3)
+ relbuf->sym_ptr_ptr = syms + (ldrel.l_symndx - 3);
+ else
+ {
+ const char *name;
+ asection *sec;
+
+ switch (ldrel.l_symndx)
+ {
+ case 0:
+ name = ".text";
+ break;
+ case 1:
+ name = ".data";
+ break;
+ case 2:
+ name = ".bss";
+ break;
+ default:
+ abort ();
+ break;
+ }
+
+ sec = bfd_get_section_by_name (abfd, name);
+ if (sec == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return -1;
+ }
+
+ relbuf->sym_ptr_ptr = sec->symbol_ptr_ptr;
+ }
+
+ relbuf->address = ldrel.l_vaddr;
+ relbuf->addend = 0;
+
+ /* Most dynamic relocs have the same type. FIXME: This is only
+ correct if ldrel.l_rtype == 0. In other cases, we should use
+ a different howto. */
+ relbuf->howto = &xcoff_dynamic_reloc;
+
+ /* FIXME: We have no way to record the l_rsecnm field. */
+
+ *prelocs = relbuf;
+ }
+
+ *prelocs = NULL;
+
+ return ldhdr.l_nreloc;
+}
+
+/* Routine to create an entry in an XCOFF link hash table. */
+
+static struct bfd_hash_entry *
+xcoff_link_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct xcoff_link_hash_entry *ret = (struct xcoff_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct xcoff_link_hash_entry *) NULL)
+ ret = ((struct xcoff_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct xcoff_link_hash_entry)));
+ if (ret == (struct xcoff_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct xcoff_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ /* Set local fields. */
+ ret->indx = -1;
+ ret->toc_section = NULL;
+ ret->u.toc_indx = -1;
+ ret->descriptor = NULL;
+ ret->ldsym = NULL;
+ ret->ldindx = -1;
+ ret->flags = 0;
+ ret->smclas = XMC_UA;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a XCOFF link hash table. */
+
+struct bfd_link_hash_table *
+_bfd_xcoff_bfd_link_hash_table_create (abfd)
+ bfd *abfd;
+{
+ struct xcoff_link_hash_table *ret;
+
+ ret = ((struct xcoff_link_hash_table *)
+ bfd_alloc (abfd, sizeof (struct xcoff_link_hash_table)));
+ if (ret == (struct xcoff_link_hash_table *) NULL)
+ return (struct bfd_link_hash_table *) NULL;
+ if (! _bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc))
+ {
+ bfd_release (abfd, ret);
+ return (struct bfd_link_hash_table *) NULL;
+ }
+
+ ret->debug_strtab = _bfd_xcoff_stringtab_init ();
+ ret->debug_section = NULL;
+ ret->loader_section = NULL;
+ ret->ldrel_count = 0;
+ memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr));
+ ret->linkage_section = NULL;
+ ret->toc_section = NULL;
+ ret->descriptor_section = NULL;
+ ret->imports = NULL;
+ ret->file_align = 0;
+ ret->textro = false;
+ ret->gc = false;
+ memset (ret->special_sections, 0, sizeof ret->special_sections);
+
+ /* The linker will always generate a full a.out header. We need to
+ record that fact now, before the sizeof_headers routine could be
+ called. */
+ xcoff_data (abfd)->full_aouthdr = true;
+
+ return &ret->root;
+}
+
+/* Look up an entry in an XCOFF link hash table. */
+
+#define xcoff_link_hash_lookup(table, string, create, copy, follow) \
+ ((struct xcoff_link_hash_entry *) \
+ bfd_link_hash_lookup (&(table)->root, (string), (create), (copy),\
+ (follow)))
+
+/* Traverse an XCOFF link hash table. */
+
+#define xcoff_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* Get the XCOFF link hash table from the info structure. This is
+ just a cast. */
+
+#define xcoff_hash_table(p) ((struct xcoff_link_hash_table *) ((p)->hash))
+
+/* Read internal relocs for an XCOFF csect. This is a wrapper around
+ _bfd_coff_read_internal_relocs which tries to take advantage of any
+ relocs which may have been cached for the enclosing section. */
+
+static struct internal_reloc *
+xcoff_read_internal_relocs (abfd, sec, cache, external_relocs,
+ require_internal, internal_relocs)
+ bfd *abfd;
+ asection *sec;
+ boolean cache;
+ bfd_byte *external_relocs;
+ boolean require_internal;
+ struct internal_reloc *internal_relocs;
+{
+ if (coff_section_data (abfd, sec) != NULL
+ && coff_section_data (abfd, sec)->relocs == NULL
+ && xcoff_section_data (abfd, sec) != NULL)
+ {
+ asection *enclosing;
+
+ enclosing = xcoff_section_data (abfd, sec)->enclosing;
+
+ if (enclosing != NULL
+ && (coff_section_data (abfd, enclosing) == NULL
+ || coff_section_data (abfd, enclosing)->relocs == NULL)
+ && cache
+ && enclosing->reloc_count > 0)
+ {
+ if (_bfd_coff_read_internal_relocs (abfd, enclosing, true,
+ external_relocs, false,
+ (struct internal_reloc *) NULL)
+ == NULL)
+ return NULL;
+ }
+
+ if (enclosing != NULL
+ && coff_section_data (abfd, enclosing) != NULL
+ && coff_section_data (abfd, enclosing)->relocs != NULL)
+ {
+ size_t off;
+
+ off = ((sec->rel_filepos - enclosing->rel_filepos)
+ / bfd_coff_relsz (abfd));
+ if (! require_internal)
+ return coff_section_data (abfd, enclosing)->relocs + off;
+ memcpy (internal_relocs,
+ coff_section_data (abfd, enclosing)->relocs + off,
+ sec->reloc_count * sizeof (struct internal_reloc));
+ return internal_relocs;
+ }
+ }
+
+ return _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs,
+ require_internal, internal_relocs);
+}
+
+/* Given an XCOFF BFD, add symbols to the global hash table as
+ appropriate. */
+
+boolean
+_bfd_xcoff_bfd_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return xcoff_link_add_object_symbols (abfd, info);
+
+ case bfd_archive:
+ /* If the archive has a map, do the usual search. We then need
+ to check the archive for stripped dynamic objects, because
+ they will not appear in the archive map even though they
+ should, perhaps, be included. If the archive has no map, we
+ just consider each object file in turn, since that apparently
+ is what the AIX native linker does. */
+ if (bfd_has_map (abfd))
+ {
+ if (! (_bfd_generic_link_add_archive_symbols
+ (abfd, info, xcoff_link_check_archive_element)))
+ return false;
+ }
+
+ {
+ bfd *member;
+
+ member = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
+ while (member != NULL)
+ {
+ if (bfd_check_format (member, bfd_object)
+ && (! bfd_has_map (abfd)
+ || ((member->flags & DYNAMIC) != 0
+ && (member->flags & HAS_SYMS) == 0)))
+ {
+ boolean needed;
+
+ if (! xcoff_link_check_archive_element (member, info, &needed))
+ return false;
+ if (needed)
+ member->archive_pass = -1;
+ }
+ member = bfd_openr_next_archived_file (abfd, member);
+ }
+ }
+
+ return true;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+}
+
+/* Add symbols from an XCOFF object file. */
+
+static boolean
+xcoff_link_add_object_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return false;
+ if (! xcoff_link_add_symbols (abfd, info))
+ return false;
+ if (! info->keep_memory)
+ {
+ if (! _bfd_coff_free_symbols (abfd))
+ return false;
+ }
+ return true;
+}
+
+/* Check a single archive element to see if we need to include it in
+ the link. *PNEEDED is set according to whether this element is
+ needed in the link or not. This is called via
+ _bfd_generic_link_add_archive_symbols. */
+
+static boolean
+xcoff_link_check_archive_element (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return false;
+
+ if (! xcoff_link_check_ar_symbols (abfd, info, pneeded))
+ return false;
+
+ if (*pneeded)
+ {
+ if (! xcoff_link_add_symbols (abfd, info))
+ return false;
+ }
+
+ if (! info->keep_memory || ! *pneeded)
+ {
+ if (! _bfd_coff_free_symbols (abfd))
+ return false;
+ }
+
+ return true;
+}
+
+/* Look through the symbols to see if this object file should be
+ included in the link. */
+
+static boolean
+xcoff_link_check_ar_symbols (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ bfd_size_type symesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+
+ *pneeded = false;
+
+ if ((abfd->flags & DYNAMIC) != 0
+ && ! info->static_link
+ && info->hash->creator == abfd->xvec)
+ return xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded);
+
+ symesz = bfd_coff_symesz (abfd);
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esym_end = esym + obj_raw_syment_count (abfd) * symesz;
+ while (esym < esym_end)
+ {
+ struct internal_syment sym;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+
+ if (sym.n_sclass == C_EXT && sym.n_scnum != N_UNDEF)
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ struct bfd_link_hash_entry *h;
+
+ /* This symbol is externally visible, and is defined by this
+ object file. */
+
+ name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
+ if (name == NULL)
+ return false;
+ h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+
+ /* We are only interested in symbols that are currently
+ undefined. If a symbol is currently known to be common,
+ XCOFF linkers do not bring in an object file which
+ defines it. We also don't bring in symbols to satisfy
+ undefined references in shared objects. */
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_undefined
+ && (info->hash->creator != abfd->xvec
+ || (((struct xcoff_link_hash_entry *) h)->flags
+ & XCOFF_DEF_DYNAMIC) == 0))
+ {
+ if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ }
+
+ /* We do not need this object file. */
+ return true;
+}
+
+/* Look through the loader symbols to see if this dynamic object
+ should be included in the link. The native linker uses the loader
+ symbols, not the normal symbol table, so we do too. */
+
+static boolean
+xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ boolean *pneeded;
+{
+ asection *lsec;
+ bfd_byte *buf;
+ struct internal_ldhdr ldhdr;
+ const char *strings;
+ struct external_ldsym *elsym, *elsymend;
+
+ *pneeded = false;
+
+ lsec = bfd_get_section_by_name (abfd, ".loader");
+ if (lsec == NULL)
+ {
+ /* There are no symbols, so don't try to include it. */
+ return true;
+ }
+
+ if (! xcoff_get_section_contents (abfd, lsec))
+ return false;
+ buf = coff_section_data (abfd, lsec)->contents;
+
+ xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) buf, &ldhdr);
+
+ strings = (char *) buf + ldhdr.l_stoff;
+
+ elsym = (struct external_ldsym *) (buf + LDHDRSZ);
+ elsymend = elsym + ldhdr.l_nsyms;
+ for (; elsym < elsymend; elsym++)
+ {
+ struct internal_ldsym ldsym;
+ char nambuf[SYMNMLEN + 1];
+ const char *name;
+ struct bfd_link_hash_entry *h;
+
+ xcoff_swap_ldsym_in (abfd, elsym, &ldsym);
+
+ /* We are only interested in exported symbols. */
+ if ((ldsym.l_smtype & L_EXPORT) == 0)
+ continue;
+
+ if (ldsym._l._l_l._l_zeroes == 0)
+ name = strings + ldsym._l._l_l._l_offset;
+ else
+ {
+ memcpy (nambuf, ldsym._l._l_name, SYMNMLEN);
+ nambuf[SYMNMLEN] = '\0';
+ name = nambuf;
+ }
+
+ h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+
+ /* We are only interested in symbols that are currently
+ undefined. At this point we know that we are using an XCOFF
+ hash table. */
+ if (h != NULL
+ && h->type == bfd_link_hash_undefined
+ && (((struct xcoff_link_hash_entry *) h)->flags
+ & XCOFF_DEF_DYNAMIC) == 0)
+ {
+ if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ return false;
+ *pneeded = true;
+ return true;
+ }
+ }
+
+ /* We do not need this shared object. */
+
+ if (buf != NULL && ! coff_section_data (abfd, lsec)->keep_contents)
+ {
+ free (coff_section_data (abfd, lsec)->contents);
+ coff_section_data (abfd, lsec)->contents = NULL;
+ }
+
+ return true;
+}
+
+/* Returns the index of reloc in RELOCS with the least address greater
+ than or equal to ADDRESS. The relocs are sorted by address. */
+
+static bfd_size_type
+xcoff_find_reloc (relocs, count, address)
+ struct internal_reloc *relocs;
+ bfd_size_type count;
+ bfd_vma address;
+{
+ bfd_size_type min, max, this;
+
+ if (count < 2)
+ {
+ if (count == 1 && relocs[0].r_vaddr < address)
+ return 1;
+ else
+ return 0;
+ }
+
+ min = 0;
+ max = count;
+
+ /* Do a binary search over (min,max]. */
+ while (min + 1 < max)
+ {
+ bfd_vma raddr;
+
+ this = (max + min) / 2;
+ raddr = relocs[this].r_vaddr;
+ if (raddr > address)
+ max = this;
+ else if (raddr < address)
+ min = this;
+ else
+ {
+ min = this;
+ break;
+ }
+ }
+
+ if (relocs[min].r_vaddr < address)
+ return min + 1;
+
+ while (min > 0
+ && relocs[min - 1].r_vaddr == address)
+ --min;
+
+ return min;
+}
+
+/* Add all the symbols from an object file to the hash table.
+
+ XCOFF is a weird format. A normal XCOFF .o files will have three
+ COFF sections--.text, .data, and .bss--but each COFF section will
+ contain many csects. These csects are described in the symbol
+ table. From the linker's point of view, each csect must be
+ considered a section in its own right. For example, a TOC entry is
+ handled as a small XMC_TC csect. The linker must be able to merge
+ different TOC entries together, which means that it must be able to
+ extract the XMC_TC csects from the .data section of the input .o
+ file.
+
+ From the point of view of our linker, this is, of course, a hideous
+ nightmare. We cope by actually creating sections for each csect,
+ and discarding the original sections. We then have to handle the
+ relocation entries carefully, since the only way to tell which
+ csect they belong to is to examine the address. */
+
+static boolean
+xcoff_link_add_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ unsigned int n_tmask;
+ unsigned int n_btshft;
+ boolean default_copy;
+ bfd_size_type symcount;
+ struct xcoff_link_hash_entry **sym_hash;
+ asection **csect_cache;
+ bfd_size_type linesz;
+ asection *o;
+ asection *last_real;
+ boolean keep_syms;
+ asection *csect;
+ unsigned int csect_index;
+ asection *first_csect;
+ bfd_size_type symesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+ struct reloc_info_struct
+ {
+ struct internal_reloc *relocs;
+ asection **csects;
+ bfd_byte *linenos;
+ } *reloc_info = NULL;
+
+ keep_syms = obj_coff_keep_syms (abfd);
+
+ if ((abfd->flags & DYNAMIC) != 0
+ && ! info->static_link)
+ {
+ if (! xcoff_link_add_dynamic_symbols (abfd, info))
+ return false;
+ }
+
+ if (info->hash->creator == abfd->xvec)
+ {
+ /* We need to build a .loader section, so we do it here. This
+ won't work if we're producing an XCOFF output file with no
+ XCOFF input files. FIXME. */
+ if (xcoff_hash_table (info)->loader_section == NULL)
+ {
+ asection *lsec;
+
+ lsec = bfd_make_section_anyway (abfd, ".loader");
+ if (lsec == NULL)
+ goto error_return;
+ xcoff_hash_table (info)->loader_section = lsec;
+ lsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ }
+ /* Likewise for the linkage section. */
+ if (xcoff_hash_table (info)->linkage_section == NULL)
+ {
+ asection *lsec;
+
+ lsec = bfd_make_section_anyway (abfd, ".gl");
+ if (lsec == NULL)
+ goto error_return;
+ xcoff_hash_table (info)->linkage_section = lsec;
+ lsec->flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+ lsec->alignment_power = 2;
+ }
+ /* Likewise for the TOC section. */
+ if (xcoff_hash_table (info)->toc_section == NULL)
+ {
+ asection *tsec;
+
+ tsec = bfd_make_section_anyway (abfd, ".tc");
+ if (tsec == NULL)
+ goto error_return;
+ xcoff_hash_table (info)->toc_section = tsec;
+ tsec->flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+ tsec->alignment_power = 2;
+ }
+ /* Likewise for the descriptor section. */
+ if (xcoff_hash_table (info)->descriptor_section == NULL)
+ {
+ asection *dsec;
+
+ dsec = bfd_make_section_anyway (abfd, ".ds");
+ if (dsec == NULL)
+ goto error_return;
+ xcoff_hash_table (info)->descriptor_section = dsec;
+ dsec->flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+ dsec->alignment_power = 2;
+ }
+ /* Likewise for the .debug section. */
+ if (xcoff_hash_table (info)->debug_section == NULL
+ && info->strip != strip_all)
+ {
+ asection *dsec;
+
+ dsec = bfd_make_section_anyway (abfd, ".debug");
+ if (dsec == NULL)
+ goto error_return;
+ xcoff_hash_table (info)->debug_section = dsec;
+ dsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ }
+ }
+
+ if ((abfd->flags & DYNAMIC) != 0
+ && ! info->static_link)
+ return true;
+
+ n_tmask = coff_data (abfd)->local_n_tmask;
+ n_btshft = coff_data (abfd)->local_n_btshft;
+
+ /* Define macros so that ISFCN, et. al., macros work correctly. */
+#define N_TMASK n_tmask
+#define N_BTSHFT n_btshft
+
+ if (info->keep_memory)
+ default_copy = false;
+ else
+ default_copy = true;
+
+ symcount = obj_raw_syment_count (abfd);
+
+ /* We keep a list of the linker hash table entries that correspond
+ to each external symbol. */
+ sym_hash = ((struct xcoff_link_hash_entry **)
+ bfd_alloc (abfd,
+ (symcount
+ * sizeof (struct xcoff_link_hash_entry *))));
+ if (sym_hash == NULL && symcount != 0)
+ goto error_return;
+ coff_data (abfd)->sym_hashes = (struct coff_link_hash_entry **) sym_hash;
+ memset (sym_hash, 0,
+ (size_t) symcount * sizeof (struct xcoff_link_hash_entry *));
+
+ /* Because of the weird stuff we are doing with XCOFF csects, we can
+ not easily determine which section a symbol is in, so we store
+ the information in the tdata for the input file. */
+ csect_cache = ((asection **)
+ bfd_alloc (abfd, symcount * sizeof (asection *)));
+ if (csect_cache == NULL && symcount != 0)
+ goto error_return;
+ xcoff_data (abfd)->csects = csect_cache;
+ memset (csect_cache, 0, (size_t) symcount * sizeof (asection *));
+
+ /* While splitting sections into csects, we need to assign the
+ relocs correctly. The relocs and the csects must both be in
+ order by VMA within a given section, so we handle this by
+ scanning along the relocs as we process the csects. We index
+ into reloc_info using the section target_index. */
+ reloc_info = ((struct reloc_info_struct *)
+ bfd_malloc ((abfd->section_count + 1)
+ * sizeof (struct reloc_info_struct)));
+ if (reloc_info == NULL)
+ goto error_return;
+ memset ((PTR) reloc_info, 0,
+ (abfd->section_count + 1) * sizeof (struct reloc_info_struct));
+
+ /* Read in the relocs and line numbers for each section. */
+ linesz = bfd_coff_linesz (abfd);
+ last_real = NULL;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ last_real = o;
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ reloc_info[o->target_index].relocs =
+ xcoff_read_internal_relocs (abfd, o, true, (bfd_byte *) NULL,
+ false, (struct internal_reloc *) NULL);
+ reloc_info[o->target_index].csects =
+ (asection **) bfd_malloc (o->reloc_count * sizeof (asection *));
+ if (reloc_info[o->target_index].csects == NULL)
+ goto error_return;
+ memset (reloc_info[o->target_index].csects, 0,
+ o->reloc_count * sizeof (asection *));
+ }
+
+ if ((info->strip == strip_none || info->strip == strip_some)
+ && o->lineno_count > 0)
+ {
+ bfd_byte *linenos;
+
+ linenos = (bfd_byte *) bfd_malloc (o->lineno_count * linesz);
+ if (linenos == NULL)
+ goto error_return;
+ reloc_info[o->target_index].linenos = linenos;
+ if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0
+ || (bfd_read (linenos, linesz, o->lineno_count, abfd)
+ != linesz * o->lineno_count))
+ goto error_return;
+ }
+ }
+
+ /* Don't let the linker relocation routines discard the symbols. */
+ obj_coff_keep_syms (abfd) = true;
+
+ csect = NULL;
+ csect_index = 0;
+ first_csect = NULL;
+
+ symesz = bfd_coff_symesz (abfd);
+ BFD_ASSERT (symesz == bfd_coff_auxesz (abfd));
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esym_end = esym + symcount * symesz;
+ while (esym < esym_end)
+ {
+ struct internal_syment sym;
+ union internal_auxent aux;
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ int smtyp;
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ struct xcoff_link_hash_entry *set_toc;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym);
+
+ /* In this pass we are only interested in symbols with csect
+ information. */
+ if (sym.n_sclass != C_EXT && sym.n_sclass != C_HIDEXT)
+ {
+ if (sym.n_sclass == C_FILE && csect != NULL)
+ {
+ xcoff_section_data (abfd, csect)->last_symndx =
+ ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz);
+ csect = NULL;
+ }
+
+ if (csect != NULL)
+ *csect_cache = csect;
+ else if (first_csect == NULL || sym.n_sclass == C_FILE)
+ *csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum);
+ else
+ *csect_cache = NULL;
+ esym += (sym.n_numaux + 1) * symesz;
+ sym_hash += sym.n_numaux + 1;
+ csect_cache += sym.n_numaux + 1;
+ continue;
+ }
+
+ name = _bfd_coff_internal_syment_name (abfd, &sym, buf);
+ if (name == NULL)
+ goto error_return;
+
+ /* If this symbol has line number information attached to it,
+ and we're not stripping it, count the number of entries and
+ add them to the count for this csect. In the final link pass
+ we are going to attach line number information by symbol,
+ rather than by section, in order to more easily handle
+ garbage collection. */
+ if ((info->strip == strip_none || info->strip == strip_some)
+ && sym.n_numaux > 1
+ && csect != NULL
+ && ISFCN (sym.n_type))
+ {
+ union internal_auxent auxlin;
+
+ bfd_coff_swap_aux_in (abfd, (PTR) (esym + symesz),
+ sym.n_type, sym.n_sclass,
+ 0, sym.n_numaux, (PTR) &auxlin);
+ if (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0)
+ {
+ asection *enclosing;
+ bfd_size_type linoff;
+
+ enclosing = xcoff_section_data (abfd, csect)->enclosing;
+ if (enclosing == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: `%s' has line numbers but no enclosing section"),
+ bfd_get_filename (abfd), name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ linoff = (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr
+ - enclosing->line_filepos);
+ if (linoff < enclosing->lineno_count * linesz)
+ {
+ struct internal_lineno lin;
+ bfd_byte *linpstart;
+
+ linpstart = (reloc_info[enclosing->target_index].linenos
+ + linoff);
+ bfd_coff_swap_lineno_in (abfd, (PTR) linpstart, (PTR) &lin);
+ if (lin.l_lnno == 0
+ && ((bfd_size_type) lin.l_addr.l_symndx
+ == ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz)))
+ {
+ bfd_byte *linpend, *linp;
+
+ linpend = (reloc_info[enclosing->target_index].linenos
+ + enclosing->lineno_count * linesz);
+ for (linp = linpstart + linesz;
+ linp < linpend;
+ linp += linesz)
+ {
+ bfd_coff_swap_lineno_in (abfd, (PTR) linp,
+ (PTR) &lin);
+ if (lin.l_lnno == 0)
+ break;
+ }
+ csect->lineno_count += (linp - linpstart) / linesz;
+ /* The setting of line_filepos will only be
+ useful if all the line number entries for a
+ csect are contiguous; this only matters for
+ error reporting. */
+ if (csect->line_filepos == 0)
+ csect->line_filepos =
+ auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ }
+ }
+ }
+ }
+
+ /* Pick up the csect auxiliary information. */
+
+ if (sym.n_numaux == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: class %d symbol `%s' has no aux entries"),
+ bfd_get_filename (abfd), sym.n_sclass, name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ bfd_coff_swap_aux_in (abfd,
+ (PTR) (esym + symesz * sym.n_numaux),
+ sym.n_type, sym.n_sclass,
+ sym.n_numaux - 1, sym.n_numaux,
+ (PTR) &aux);
+
+ smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp);
+
+ flags = BSF_GLOBAL;
+ section = NULL;
+ value = 0;
+ set_toc = NULL;
+
+ switch (smtyp)
+ {
+ default:
+ (*_bfd_error_handler)
+ (_("%s: symbol `%s' has unrecognized csect type %d"),
+ bfd_get_filename (abfd), name, smtyp);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+
+ case XTY_ER:
+ /* This is an external reference. */
+ if (sym.n_sclass == C_HIDEXT
+ || sym.n_scnum != N_UNDEF
+ || aux.x_csect.x_scnlen.l != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"),
+ bfd_get_filename (abfd), name, sym.n_sclass, sym.n_scnum,
+ aux.x_csect.x_scnlen.l);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* An XMC_XO external reference is actually a reference to
+ an absolute location. */
+ if (aux.x_csect.x_smclas != XMC_XO)
+ section = bfd_und_section_ptr;
+ else
+ {
+ section = bfd_abs_section_ptr;
+ value = sym.n_value;
+ }
+ break;
+
+ case XTY_SD:
+ /* This is a csect definition. */
+
+ if (csect != NULL)
+ {
+ xcoff_section_data (abfd, csect)->last_symndx =
+ ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz);
+ }
+
+ csect = NULL;
+ csect_index = -1;
+
+ /* When we see a TOC anchor, we record the TOC value. */
+ if (aux.x_csect.x_smclas == XMC_TC0)
+ {
+ if (sym.n_sclass != C_HIDEXT
+ || aux.x_csect.x_scnlen.l != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: XMC_TC0 symbol `%s' is class %d scnlen %d"),
+ bfd_get_filename (abfd), name, sym.n_sclass,
+ aux.x_csect.x_scnlen.l);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ xcoff_data (abfd)->toc = sym.n_value;
+ }
+
+ /* We must merge TOC entries for the same symbol. We can
+ merge two TOC entries if they are both C_HIDEXT, they
+ both have the same name, they are both 4 bytes long, and
+ they both have a relocation table entry for an external
+ symbol with the same name. Unfortunately, this means
+ that we must look through the relocations. Ick. */
+ if (aux.x_csect.x_smclas == XMC_TC
+ && sym.n_sclass == C_HIDEXT
+ && aux.x_csect.x_scnlen.l == 4
+ && info->hash->creator == abfd->xvec)
+ {
+ asection *enclosing;
+ struct internal_reloc *relocs;
+ bfd_size_type relindx;
+ struct internal_reloc *rel;
+
+ enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum);
+ if (enclosing == NULL)
+ goto error_return;
+
+ relocs = reloc_info[enclosing->target_index].relocs;
+ relindx = xcoff_find_reloc (relocs, enclosing->reloc_count,
+ sym.n_value);
+ rel = relocs + relindx;
+ if (relindx < enclosing->reloc_count
+ && rel->r_vaddr == (bfd_vma) sym.n_value
+ && rel->r_size == 31
+ && rel->r_type == R_POS)
+ {
+ bfd_byte *erelsym;
+ struct internal_syment relsym;
+
+ erelsym = ((bfd_byte *) obj_coff_external_syms (abfd)
+ + rel->r_symndx * symesz);
+ bfd_coff_swap_sym_in (abfd, (PTR) erelsym, (PTR) &relsym);
+ if (relsym.n_sclass == C_EXT)
+ {
+ const char *relname;
+ char relbuf[SYMNMLEN + 1];
+ boolean copy;
+ struct xcoff_link_hash_entry *h;
+
+ /* At this point we know that the TOC entry is
+ for an externally visible symbol. */
+ relname = _bfd_coff_internal_syment_name (abfd, &relsym,
+ relbuf);
+ if (relname == NULL)
+ goto error_return;
+
+ /* We only merge TOC entries if the TC name is
+ the same as the symbol name. This handles
+ the normal case, but not common cases like
+ SYM.P4 which gcc generates to store SYM + 4
+ in the TOC. FIXME. */
+ if (strcmp (name, relname) == 0)
+ {
+ copy = (! info->keep_memory
+ || relsym._n._n_n._n_zeroes != 0
+ || relsym._n._n_n._n_offset == 0);
+ h = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ relname, true, copy,
+ false);
+ if (h == NULL)
+ goto error_return;
+
+ /* At this point h->root.type could be
+ bfd_link_hash_new. That should be OK,
+ since we know for sure that we will come
+ across this symbol as we step through the
+ file. */
+
+ /* We store h in *sym_hash for the
+ convenience of the relocate_section
+ function. */
+ *sym_hash = h;
+
+ if (h->toc_section != NULL)
+ {
+ asection **rel_csects;
+
+ /* We already have a TOC entry for this
+ symbol, so we can just ignore this
+ one. */
+ rel_csects =
+ reloc_info[enclosing->target_index].csects;
+ rel_csects[relindx] = bfd_und_section_ptr;
+ break;
+ }
+
+ /* We are about to create a TOC entry for
+ this symbol. */
+ set_toc = h;
+ }
+ }
+ }
+ }
+
+ /* We need to create a new section. We get the name from
+ the csect storage mapping class, so that the linker can
+ accumulate similar csects together. */
+ {
+ static const char *csect_name_by_class[] =
+ {
+ ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
+ ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
+ ".td"
+ };
+ const char *csect_name;
+ asection *enclosing;
+
+ if ((aux.x_csect.x_smclas >=
+ sizeof csect_name_by_class / sizeof csect_name_by_class[0])
+ || csect_name_by_class[aux.x_csect.x_smclas] == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: symbol `%s' has unrecognized smclas %d"),
+ bfd_get_filename (abfd), name, aux.x_csect.x_smclas);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ csect_name = csect_name_by_class[aux.x_csect.x_smclas];
+ csect = bfd_make_section_anyway (abfd, csect_name);
+ if (csect == NULL)
+ goto error_return;
+ enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum);
+ if (enclosing == NULL)
+ goto error_return;
+ if (! bfd_is_abs_section (enclosing)
+ && ((bfd_vma) sym.n_value < enclosing->vma
+ || ((bfd_vma) sym.n_value + aux.x_csect.x_scnlen.l
+ > enclosing->vma + enclosing->_raw_size)))
+ {
+ (*_bfd_error_handler)
+ (_("%s: csect `%s' not in enclosing section"),
+ bfd_get_filename (abfd), name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ csect->vma = sym.n_value;
+ csect->filepos = (enclosing->filepos
+ + sym.n_value
+ - enclosing->vma);
+ csect->_raw_size = aux.x_csect.x_scnlen.l;
+ csect->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp);
+
+ /* Record the enclosing section in the tdata for this new
+ section. */
+ csect->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata));
+ if (csect->used_by_bfd == NULL)
+ goto error_return;
+ coff_section_data (abfd, csect)->tdata =
+ bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata));
+ if (coff_section_data (abfd, csect)->tdata == NULL)
+ goto error_return;
+ xcoff_section_data (abfd, csect)->enclosing = enclosing;
+ xcoff_section_data (abfd, csect)->lineno_count =
+ enclosing->lineno_count;
+
+ if (enclosing->owner == abfd)
+ {
+ struct internal_reloc *relocs;
+ bfd_size_type relindx;
+ struct internal_reloc *rel;
+ asection **rel_csect;
+
+ relocs = reloc_info[enclosing->target_index].relocs;
+ relindx = xcoff_find_reloc (relocs, enclosing->reloc_count,
+ csect->vma);
+ rel = relocs + relindx;
+ rel_csect = (reloc_info[enclosing->target_index].csects
+ + relindx);
+ csect->rel_filepos = (enclosing->rel_filepos
+ + relindx * bfd_coff_relsz (abfd));
+ while (relindx < enclosing->reloc_count
+ && *rel_csect == NULL
+ && rel->r_vaddr < csect->vma + csect->_raw_size)
+ {
+ *rel_csect = csect;
+ csect->flags |= SEC_RELOC;
+ ++csect->reloc_count;
+ ++relindx;
+ ++rel;
+ ++rel_csect;
+ }
+ }
+
+ /* There are a number of other fields and section flags
+ which we do not bother to set. */
+
+ csect_index = ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz);
+
+ xcoff_section_data (abfd, csect)->first_symndx = csect_index;
+
+ if (first_csect == NULL)
+ first_csect = csect;
+
+ /* If this symbol is C_EXT, we treat it as starting at the
+ beginning of the newly created section. */
+ if (sym.n_sclass == C_EXT)
+ {
+ section = csect;
+ value = 0;
+ }
+
+ /* If this is a TOC section for a symbol, record it. */
+ if (set_toc != NULL)
+ set_toc->toc_section = csect;
+ }
+ break;
+
+ case XTY_LD:
+ /* This is a label definition. The x_scnlen field is the
+ symbol index of the csect. I believe that this must
+ always follow the appropriate XTY_SD symbol, so I will
+ insist on it. */
+ {
+ boolean bad;
+
+ bad = false;
+ if (aux.x_csect.x_scnlen.l < 0
+ || (aux.x_csect.x_scnlen.l
+ >= esym - (bfd_byte *) obj_coff_external_syms (abfd)))
+ bad = true;
+ if (! bad)
+ {
+ section = xcoff_data (abfd)->csects[aux.x_csect.x_scnlen.l];
+ if (section == NULL
+ || (section->flags & SEC_HAS_CONTENTS) == 0)
+ bad = true;
+ }
+ if (bad)
+ {
+ (*_bfd_error_handler)
+ (_("%s: misplaced XTY_LD `%s'"),
+ bfd_get_filename (abfd), name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ value = sym.n_value - csect->vma;
+ }
+ break;
+
+ case XTY_CM:
+ /* This is an unitialized csect. We could base the name on
+ the storage mapping class, but we don't bother except for
+ an XMC_TD symbol. If this csect is externally visible,
+ it is a common symbol. We put XMC_TD symbols in sections
+ named .tocbss, and rely on the linker script to put that
+ in the TOC area. */
+
+ if (csect != NULL)
+ {
+ xcoff_section_data (abfd, csect)->last_symndx =
+ ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz);
+ }
+
+ if (aux.x_csect.x_smclas == XMC_TD)
+ csect = bfd_make_section_anyway (abfd, ".tocbss");
+ else
+ csect = bfd_make_section_anyway (abfd, ".bss");
+ if (csect == NULL)
+ goto error_return;
+ csect->vma = sym.n_value;
+ csect->_raw_size = aux.x_csect.x_scnlen.l;
+ csect->flags |= SEC_ALLOC;
+ csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp);
+ /* There are a number of other fields and section flags
+ which we do not bother to set. */
+
+ csect_index = ((esym
+ - (bfd_byte *) obj_coff_external_syms (abfd))
+ / symesz);
+
+ csect->used_by_bfd =
+ (PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata));
+ if (csect->used_by_bfd == NULL)
+ goto error_return;
+ coff_section_data (abfd, csect)->tdata =
+ bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata));
+ if (coff_section_data (abfd, csect)->tdata == NULL)
+ goto error_return;
+ xcoff_section_data (abfd, csect)->first_symndx = csect_index;
+
+ if (first_csect == NULL)
+ first_csect = csect;
+
+ if (sym.n_sclass == C_EXT)
+ {
+ csect->flags |= SEC_IS_COMMON;
+ csect->_raw_size = 0;
+ section = csect;
+ value = aux.x_csect.x_scnlen.l;
+ }
+
+ break;
+ }
+
+ /* Check for magic symbol names. */
+ if ((smtyp == XTY_SD || smtyp == XTY_CM)
+ && aux.x_csect.x_smclas != XMC_TC
+ && aux.x_csect.x_smclas != XMC_TD)
+ {
+ int i;
+
+ i = -1;
+ if (name[0] == '_')
+ {
+ if (strcmp (name, "_text") == 0)
+ i = 0;
+ else if (strcmp (name, "_etext") == 0)
+ i = 1;
+ else if (strcmp (name, "_data") == 0)
+ i = 2;
+ else if (strcmp (name, "_edata") == 0)
+ i = 3;
+ else if (strcmp (name, "_end") == 0)
+ i = 4;
+ }
+ else if (name[0] == 'e' && strcmp (name, "end") == 0)
+ i = 5;
+
+ if (i != -1)
+ xcoff_hash_table (info)->special_sections[i] = csect;
+ }
+
+ /* Now we have enough information to add the symbol to the
+ linker hash table. */
+
+ if (sym.n_sclass == C_EXT)
+ {
+ boolean copy;
+
+ BFD_ASSERT (section != NULL);
+
+ /* We must copy the name into memory if we got it from the
+ syment itself, rather than the string table. */
+ copy = default_copy;
+ if (sym._n._n_n._n_zeroes != 0
+ || sym._n._n_n._n_offset == 0)
+ copy = true;
+
+ /* The AIX linker appears to only detect multiple symbol
+ definitions when there is a reference to the symbol. If
+ a symbol is defined multiple times, and the only
+ references are from the same object file, the AIX linker
+ appears to permit it. It does not merge the different
+ definitions, but handles them independently. On the
+ other hand, if there is a reference, the linker reports
+ an error.
+
+ This matters because the AIX <net/net_globals.h> header
+ file actually defines an initialized array, so we have to
+ actually permit that to work.
+
+ Just to make matters even more confusing, the AIX linker
+ appears to permit multiple symbol definitions whenever
+ the second definition is in an archive rather than an
+ object file. This may be a consequence of the manner in
+ which it handles archives: I think it may load the entire
+ archive in as separate csects, and then let garbage
+ collection discard symbols.
+
+ We also have to handle the case of statically linking a
+ shared object, which will cause symbol redefinitions,
+ although this is an easier case to detect. */
+
+ if (info->hash->creator == abfd->xvec)
+ {
+ if (! bfd_is_und_section (section))
+ *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ name, true, copy, false);
+ else
+ *sym_hash = ((struct xcoff_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (abfd, info, name,
+ true, copy, false));
+ if (*sym_hash == NULL)
+ goto error_return;
+ if (((*sym_hash)->root.type == bfd_link_hash_defined
+ || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ && ! bfd_is_und_section (section)
+ && ! bfd_is_com_section (section))
+ {
+ /* This is a second definition of a defined symbol. */
+ if ((abfd->flags & DYNAMIC) != 0
+ && ((*sym_hash)->smclas != XMC_GL
+ || aux.x_csect.x_smclas == XMC_GL
+ || ((*sym_hash)->root.u.def.section->owner->flags
+ & DYNAMIC) == 0))
+ {
+ /* The new symbol is from a shared library, and
+ either the existing symbol is not global
+ linkage code or this symbol is global linkage
+ code. If the existing symbol is global
+ linkage code and the new symbol is not, then
+ we want to use the new symbol. */
+ section = bfd_und_section_ptr;
+ value = 0;
+ }
+ else if (((*sym_hash)->root.u.def.section->owner->flags
+ & DYNAMIC) != 0)
+ {
+ /* The existing symbol is from a shared library.
+ Replace it. */
+ (*sym_hash)->root.type = bfd_link_hash_undefined;
+ (*sym_hash)->root.u.undef.abfd =
+ (*sym_hash)->root.u.def.section->owner;
+ }
+ else if (abfd->my_archive != NULL)
+ {
+ /* This is a redefinition in an object contained
+ in an archive. Just ignore it. See the
+ comment above. */
+ section = bfd_und_section_ptr;
+ value = 0;
+ }
+ else if ((*sym_hash)->root.next != NULL
+ || info->hash->undefs_tail == &(*sym_hash)->root)
+ {
+ /* This symbol has been referenced. In this
+ case, we just continue and permit the
+ multiple definition error. See the comment
+ above about the behaviour of the AIX linker. */
+ }
+ else if ((*sym_hash)->smclas == aux.x_csect.x_smclas)
+ {
+ /* The symbols are both csects of the same
+ class. There is at least a chance that this
+ is a semi-legitimate redefinition. */
+ section = bfd_und_section_ptr;
+ value = 0;
+ (*sym_hash)->flags |= XCOFF_MULTIPLY_DEFINED;
+ }
+ }
+ else if (((*sym_hash)->flags & XCOFF_MULTIPLY_DEFINED) != 0
+ && ((*sym_hash)->root.type == bfd_link_hash_defined
+ || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ && (bfd_is_und_section (section)
+ || bfd_is_com_section (section)))
+ {
+ /* This is a reference to a multiply defined symbol.
+ Report the error now. See the comment above
+ about the behaviour of the AIX linker. We could
+ also do this with warning symbols, but I'm not
+ sure the XCOFF linker is wholly prepared to
+ handle them, and that would only be a warning,
+ not an error. */
+ if (! ((*info->callbacks->multiple_definition)
+ (info, (*sym_hash)->root.root.string,
+ (bfd *) NULL, (asection *) NULL, 0,
+ (*sym_hash)->root.u.def.section->owner,
+ (*sym_hash)->root.u.def.section,
+ (*sym_hash)->root.u.def.value)))
+ goto error_return;
+ /* Try not to give this error too many times. */
+ (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
+ }
+ }
+
+ /* _bfd_generic_link_add_one_symbol may call the linker to
+ generate an error message, and the linker may try to read
+ the symbol table to give a good error. Right now, the
+ line numbers are in an inconsistent state, since they are
+ counted both in the real sections and in the new csects.
+ We need to leave the count in the real sections so that
+ the linker can report the line number of the error
+ correctly, so temporarily clobber the link to the csects
+ so that the linker will not try to read the line numbers
+ a second time from the csects. */
+ BFD_ASSERT (last_real->next == first_csect);
+ last_real->next = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, flags, section, value,
+ (const char *) NULL, copy, true,
+ (struct bfd_link_hash_entry **) sym_hash)))
+ goto error_return;
+ last_real->next = first_csect;
+
+ if (smtyp == XTY_CM)
+ {
+ if ((*sym_hash)->root.type != bfd_link_hash_common
+ || (*sym_hash)->root.u.c.p->section != csect)
+ {
+ /* We don't need the common csect we just created. */
+ csect->_raw_size = 0;
+ }
+ else
+ {
+ (*sym_hash)->root.u.c.p->alignment_power
+ = csect->alignment_power;
+ }
+ }
+
+ if (info->hash->creator == abfd->xvec)
+ {
+ int flag;
+
+ if (smtyp == XTY_ER || smtyp == XTY_CM)
+ flag = XCOFF_REF_REGULAR;
+ else
+ flag = XCOFF_DEF_REGULAR;
+ (*sym_hash)->flags |= flag;
+
+ if ((*sym_hash)->smclas == XMC_UA
+ || flag == XCOFF_DEF_REGULAR)
+ (*sym_hash)->smclas = aux.x_csect.x_smclas;
+ }
+ }
+
+ *csect_cache = csect;
+
+ esym += (sym.n_numaux + 1) * symesz;
+ sym_hash += sym.n_numaux + 1;
+ csect_cache += sym.n_numaux + 1;
+ }
+
+ BFD_ASSERT (last_real == NULL || last_real->next == first_csect);
+
+ /* Make sure that we have seen all the relocs. */
+ for (o = abfd->sections; o != first_csect; o = o->next)
+ {
+ /* Reset the section size and the line number count, since the
+ data is now attached to the csects. Don't reset the size of
+ the .debug section, since we need to read it below in
+ bfd_xcoff_size_dynamic_sections. */
+ if (strcmp (bfd_get_section_name (abfd, o), ".debug") != 0)
+ o->_raw_size = 0;
+ o->lineno_count = 0;
+
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ bfd_size_type i;
+ struct internal_reloc *rel;
+ asection **rel_csect;
+
+ rel = reloc_info[o->target_index].relocs;
+ rel_csect = reloc_info[o->target_index].csects;
+ for (i = 0; i < o->reloc_count; i++, rel++, rel_csect++)
+ {
+ if (*rel_csect == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: reloc %s:%d not in csect"),
+ bfd_get_filename (abfd), o->name, i);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* We identify all symbols which are called, so that we
+ can create glue code for calls to functions imported
+ from dynamic objects. */
+ if (info->hash->creator == abfd->xvec
+ && *rel_csect != bfd_und_section_ptr
+ && (rel->r_type == R_BR
+ || rel->r_type == R_RBR)
+ && obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL)
+ {
+ struct xcoff_link_hash_entry *h;
+
+ h = obj_xcoff_sym_hashes (abfd)[rel->r_symndx];
+ h->flags |= XCOFF_CALLED;
+ /* If the symbol name starts with a period, it is
+ the code of a function. If the symbol is
+ currently undefined, then add an undefined symbol
+ for the function descriptor. This should do no
+ harm, because any regular object that defines the
+ function should also define the function
+ descriptor. It helps, because it means that we
+ will identify the function descriptor with a
+ dynamic object if a dynamic object defines it. */
+ if (h->root.root.string[0] == '.'
+ && h->descriptor == NULL)
+ {
+ struct xcoff_link_hash_entry *hds;
+
+ hds = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ h->root.root.string + 1,
+ true, false, true);
+ if (hds == NULL)
+ goto error_return;
+ if (hds->root.type == bfd_link_hash_new)
+ {
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, hds->root.root.string,
+ (flagword) 0, bfd_und_section_ptr,
+ (bfd_vma) 0, (const char *) NULL, false,
+ true,
+ (struct bfd_link_hash_entry **) &hds)))
+ goto error_return;
+ }
+ hds->flags |= XCOFF_DESCRIPTOR;
+ BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0
+ && (h->flags & XCOFF_DESCRIPTOR) == 0);
+ hds->descriptor = h;
+ h->descriptor = hds;
+ }
+ }
+ }
+
+ free (reloc_info[o->target_index].csects);
+ reloc_info[o->target_index].csects = NULL;
+
+ /* Reset SEC_RELOC and the reloc_count, since the reloc
+ information is now attached to the csects. */
+ o->flags &=~ SEC_RELOC;
+ o->reloc_count = 0;
+
+ /* If we are not keeping memory, free the reloc information. */
+ if (! info->keep_memory
+ && coff_section_data (abfd, o) != NULL
+ && coff_section_data (abfd, o)->relocs != NULL
+ && ! coff_section_data (abfd, o)->keep_relocs)
+ {
+ free (coff_section_data (abfd, o)->relocs);
+ coff_section_data (abfd, o)->relocs = NULL;
+ }
+ }
+
+ /* Free up the line numbers. FIXME: We could cache these
+ somewhere for the final link, to avoid reading them again. */
+ if (reloc_info[o->target_index].linenos != NULL)
+ {
+ free (reloc_info[o->target_index].linenos);
+ reloc_info[o->target_index].linenos = NULL;
+ }
+ }
+
+ free (reloc_info);
+
+ obj_coff_keep_syms (abfd) = keep_syms;
+
+ return true;
+
+ error_return:
+ if (reloc_info != NULL)
+ {
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (reloc_info[o->target_index].csects != NULL)
+ free (reloc_info[o->target_index].csects);
+ if (reloc_info[o->target_index].linenos != NULL)
+ free (reloc_info[o->target_index].linenos);
+ }
+ free (reloc_info);
+ }
+ obj_coff_keep_syms (abfd) = keep_syms;
+ return false;
+}
+
+#undef N_TMASK
+#undef N_BTSHFT
+
+/* This function is used to add symbols from a dynamic object to the
+ global symbol table. */
+
+static boolean
+xcoff_link_add_dynamic_symbols (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *lsec;
+ bfd_byte *buf;
+ struct internal_ldhdr ldhdr;
+ const char *strings;
+ struct external_ldsym *elsym, *elsymend;
+ struct xcoff_import_file *n;
+ const char *bname;
+ const char *mname;
+ const char *s;
+ unsigned int c;
+ struct xcoff_import_file **pp;
+
+ /* We can only handle a dynamic object if we are generating an XCOFF
+ output file. */
+ if (info->hash->creator != abfd->xvec)
+ {
+ (*_bfd_error_handler)
+ (_("%s: XCOFF shared object when not producing XCOFF output"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+
+ /* The symbols we use from a dynamic object are not the symbols in
+ the normal symbol table, but, rather, the symbols in the export
+ table. If there is a global symbol in a dynamic object which is
+ not in the export table, the loader will not be able to find it,
+ so we don't want to find it either. Also, on AIX 4.1.3, shr.o in
+ libc.a has symbols in the export table which are not in the
+ symbol table. */
+
+ /* Read in the .loader section. FIXME: We should really use the
+ o_snloader field in the a.out header, rather than grabbing the
+ section by name. */
+ lsec = bfd_get_section_by_name (abfd, ".loader");
+ if (lsec == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: dynamic object with no .loader section"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_no_symbols);
+ return false;
+ }
+
+ if (! xcoff_get_section_contents (abfd, lsec))
+ return false;
+ buf = coff_section_data (abfd, lsec)->contents;
+
+ /* Remove the sections from this object, so that they do not get
+ included in the link. */
+ abfd->sections = NULL;
+
+ xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) buf, &ldhdr);
+
+ strings = (char *) buf + ldhdr.l_stoff;
+
+ elsym = (struct external_ldsym *) (buf + LDHDRSZ);
+ elsymend = elsym + ldhdr.l_nsyms;
+ BFD_ASSERT (sizeof (struct external_ldsym) == LDSYMSZ);
+ for (; elsym < elsymend; elsym++)
+ {
+ struct internal_ldsym ldsym;
+ char nambuf[SYMNMLEN + 1];
+ const char *name;
+ struct xcoff_link_hash_entry *h;
+
+ xcoff_swap_ldsym_in (abfd, elsym, &ldsym);
+
+ /* We are only interested in exported symbols. */
+ if ((ldsym.l_smtype & L_EXPORT) == 0)
+ continue;
+
+ if (ldsym._l._l_l._l_zeroes == 0)
+ name = strings + ldsym._l._l_l._l_offset;
+ else
+ {
+ memcpy (nambuf, ldsym._l._l_name, SYMNMLEN);
+ nambuf[SYMNMLEN] = '\0';
+ name = nambuf;
+ }
+
+ /* Normally we could not call xcoff_link_hash_lookup in an add
+ symbols routine, since we might not be using an XCOFF hash
+ table. However, we verified above that we are using an XCOFF
+ hash table. */
+
+ h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true,
+ true, true);
+ if (h == NULL)
+ return false;
+
+ h->flags |= XCOFF_DEF_DYNAMIC;
+
+ /* If the symbol is undefined, and the BFD it was found in is
+ not a dynamic object, change the BFD to this dynamic object,
+ so that we can get the correct import file ID. */
+ if ((h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ && (h->root.u.undef.abfd == NULL
+ || (h->root.u.undef.abfd->flags & DYNAMIC) == 0))
+ h->root.u.undef.abfd = abfd;
+
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = abfd;
+ /* We do not want to add this to the undefined symbol list. */
+ }
+
+ if (h->smclas == XMC_UA
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ h->smclas = ldsym.l_smclas;
+
+ /* Unless this is an XMC_XO symbol, we don't bother to actually
+ define it, since we don't have a section to put it in anyhow.
+ Instead, the relocation routines handle the DEF_DYNAMIC flag
+ correctly. */
+
+ if (h->smclas == XMC_XO
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This symbol has an absolute value. */
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.value = ldsym.l_value;
+ }
+
+ /* If this symbol defines a function descriptor, then it
+ implicitly defines the function code as well. */
+ if (h->smclas == XMC_DS
+ || (h->smclas == XMC_XO && name[0] != '.'))
+ h->flags |= XCOFF_DESCRIPTOR;
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0)
+ {
+ struct xcoff_link_hash_entry *hds;
+
+ hds = h->descriptor;
+ if (hds == NULL)
+ {
+ char *dsnm;
+
+ dsnm = bfd_malloc (strlen (name) + 2);
+ if (dsnm == NULL)
+ return false;
+ dsnm[0] = '.';
+ strcpy (dsnm + 1, name);
+ hds = xcoff_link_hash_lookup (xcoff_hash_table (info), dsnm,
+ true, true, true);
+ free (dsnm);
+ if (hds == NULL)
+ return false;
+
+ if (hds->root.type == bfd_link_hash_new)
+ {
+ hds->root.type = bfd_link_hash_undefined;
+ hds->root.u.undef.abfd = abfd;
+ /* We do not want to add this to the undefined
+ symbol list. */
+ }
+
+ hds->descriptor = h;
+ h->descriptor = hds;
+ }
+
+ hds->flags |= XCOFF_DEF_DYNAMIC;
+ if (hds->smclas == XMC_UA)
+ hds->smclas = XMC_PR;
+
+ /* An absolute symbol appears to actually define code, not a
+ function descriptor. This is how some math functions are
+ implemented on AIX 4.1. */
+ if (h->smclas == XMC_XO
+ && (hds->root.type == bfd_link_hash_undefined
+ || hds->root.type == bfd_link_hash_undefweak))
+ {
+ hds->smclas = XMC_XO;
+ hds->root.type = bfd_link_hash_defined;
+ hds->root.u.def.section = bfd_abs_section_ptr;
+ hds->root.u.def.value = ldsym.l_value;
+ }
+ }
+ }
+
+ if (buf != NULL && ! coff_section_data (abfd, lsec)->keep_contents)
+ {
+ free (coff_section_data (abfd, lsec)->contents);
+ coff_section_data (abfd, lsec)->contents = NULL;
+ }
+
+ /* Record this file in the import files. */
+
+ n = ((struct xcoff_import_file *)
+ bfd_alloc (abfd, sizeof (struct xcoff_import_file)));
+ if (n == NULL)
+ return false;
+ n->next = NULL;
+
+ /* For some reason, the path entry in the import file list for a
+ shared object appears to always be empty. The file name is the
+ base name. */
+ n->path = "";
+ if (abfd->my_archive == NULL)
+ {
+ bname = bfd_get_filename (abfd);
+ mname = "";
+ }
+ else
+ {
+ bname = bfd_get_filename (abfd->my_archive);
+ mname = bfd_get_filename (abfd);
+ }
+ s = strrchr (bname, '/');
+ if (s != NULL)
+ bname = s + 1;
+ n->file = bname;
+ n->member = mname;
+
+ /* We start c at 1 because the first import file number is reserved
+ for LIBPATH. */
+ for (pp = &xcoff_hash_table (info)->imports, c = 1;
+ *pp != NULL;
+ pp = &(*pp)->next, ++c)
+ ;
+ *pp = n;
+
+ xcoff_data (abfd)->import_file_id = c;
+
+ return true;
+}
+
+/* Routines that are called after all the input files have been
+ handled, but before the sections are laid out in memory. */
+
+/* Mark a symbol as not being garbage, including the section in which
+ it is defined. */
+
+static INLINE boolean
+xcoff_mark_symbol (info, h)
+ struct bfd_link_info *info;
+ struct xcoff_link_hash_entry *h;
+{
+ if ((h->flags & XCOFF_MARK) != 0)
+ return true;
+
+ h->flags |= XCOFF_MARK;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *hsec;
+
+ hsec = h->root.u.def.section;
+ if (! bfd_is_abs_section (hsec)
+ && (hsec->flags & SEC_MARK) == 0)
+ {
+ if (! xcoff_mark (info, hsec))
+ return false;
+ }
+ }
+
+ if (h->toc_section != NULL
+ && (h->toc_section->flags & SEC_MARK) == 0)
+ {
+ if (! xcoff_mark (info, h->toc_section))
+ return false;
+ }
+
+ return true;
+}
+
+/* The mark phase of garbage collection. For a given section, mark
+ it, and all the sections which define symbols to which it refers.
+ Because this function needs to look at the relocs, we also count
+ the number of relocs which need to be copied into the .loader
+ section. */
+
+static boolean
+xcoff_mark (info, sec)
+ struct bfd_link_info *info;
+ asection *sec;
+{
+ if (bfd_is_abs_section (sec)
+ || (sec->flags & SEC_MARK) != 0)
+ return true;
+
+ sec->flags |= SEC_MARK;
+
+ if (sec->owner->xvec == info->hash->creator
+ && coff_section_data (sec->owner, sec) != NULL
+ && xcoff_section_data (sec->owner, sec) != NULL)
+ {
+ register struct xcoff_link_hash_entry **hp, **hpend;
+ struct internal_reloc *rel, *relend;
+
+ /* Mark all the symbols in this section. */
+
+ hp = (obj_xcoff_sym_hashes (sec->owner)
+ + xcoff_section_data (sec->owner, sec)->first_symndx);
+ hpend = (obj_xcoff_sym_hashes (sec->owner)
+ + xcoff_section_data (sec->owner, sec)->last_symndx);
+ for (; hp < hpend; hp++)
+ {
+ register struct xcoff_link_hash_entry *h;
+
+ h = *hp;
+ if (h != NULL
+ && (h->flags & XCOFF_MARK) == 0)
+ {
+ if (! xcoff_mark_symbol (info, h))
+ return false;
+ }
+ }
+
+ /* Look through the section relocs. */
+
+ if ((sec->flags & SEC_RELOC) != 0
+ && sec->reloc_count > 0)
+ {
+ rel = xcoff_read_internal_relocs (sec->owner, sec, true,
+ (bfd_byte *) NULL, false,
+ (struct internal_reloc *) NULL);
+ if (rel == NULL)
+ return false;
+ relend = rel + sec->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ asection *rsec;
+ struct xcoff_link_hash_entry *h;
+
+ if ((unsigned int) rel->r_symndx
+ > obj_raw_syment_count (sec->owner))
+ continue;
+
+ h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx];
+ if (h != NULL
+ && (h->flags & XCOFF_MARK) == 0)
+ {
+ if (! xcoff_mark_symbol (info, h))
+ return false;
+ }
+
+ rsec = xcoff_data (sec->owner)->csects[rel->r_symndx];
+ if (rsec != NULL
+ && (rsec->flags & SEC_MARK) == 0)
+ {
+ if (! xcoff_mark (info, rsec))
+ return false;
+ }
+
+ /* See if this reloc needs to be copied into the .loader
+ section. */
+ switch (rel->r_type)
+ {
+ default:
+ if (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_common
+ || ((h->flags & XCOFF_CALLED) != 0
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ && h->root.root.string[0] == '.'
+ && h->descriptor != NULL
+ && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0
+ || ((h->descriptor->flags & XCOFF_IMPORT) != 0
+ && (h->descriptor->flags
+ & XCOFF_DEF_REGULAR) == 0))))
+ break;
+ /* Fall through. */
+ case R_POS:
+ case R_NEG:
+ case R_RL:
+ case R_RLA:
+ ++xcoff_hash_table (info)->ldrel_count;
+ if (h != NULL)
+ h->flags |= XCOFF_LDREL;
+ break;
+ case R_TOC:
+ case R_GL:
+ case R_TCL:
+ case R_TRL:
+ case R_TRLA:
+ /* We should never need a .loader reloc for a TOC
+ relative reloc. */
+ break;
+ }
+ }
+
+ if (! info->keep_memory
+ && coff_section_data (sec->owner, sec) != NULL
+ && coff_section_data (sec->owner, sec)->relocs != NULL
+ && ! coff_section_data (sec->owner, sec)->keep_relocs)
+ {
+ free (coff_section_data (sec->owner, sec)->relocs);
+ coff_section_data (sec->owner, sec)->relocs = NULL;
+ }
+ }
+ }
+
+ return true;
+}
+
+/* The sweep phase of garbage collection. Remove all garbage
+ sections. */
+
+static void
+xcoff_sweep (info)
+ struct bfd_link_info *info;
+{
+ bfd *sub;
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ asection *o;
+
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_MARK) == 0)
+ {
+ /* Keep all sections from non-XCOFF input files. Keep
+ special sections. Keep .debug sections for the
+ moment. */
+ if (sub->xvec != info->hash->creator
+ || o == xcoff_hash_table (info)->debug_section
+ || o == xcoff_hash_table (info)->loader_section
+ || o == xcoff_hash_table (info)->linkage_section
+ || o == xcoff_hash_table (info)->toc_section
+ || o == xcoff_hash_table (info)->descriptor_section
+ || strcmp (o->name, ".debug") == 0)
+ o->flags |= SEC_MARK;
+ else
+ {
+ o->_raw_size = 0;
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ }
+ }
+ }
+ }
+}
+
+/* Record the number of elements in a set. This is used to output the
+ correct csect length. */
+
+boolean
+bfd_xcoff_link_record_set (output_bfd, info, harg, size)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct bfd_link_hash_entry *harg;
+ bfd_size_type size;
+{
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
+ struct xcoff_link_size_list *n;
+
+ if (! XCOFF_XVECP (output_bfd->xvec))
+ return true;
+
+ /* This will hardly ever be called. I don't want to burn four bytes
+ per global symbol, so instead the size is kept on a linked list
+ attached to the hash table. */
+
+ n = ((struct xcoff_link_size_list *)
+ bfd_alloc (output_bfd, sizeof (struct xcoff_link_size_list)));
+ if (n == NULL)
+ return false;
+ n->next = xcoff_hash_table (info)->size_list;
+ n->h = h;
+ n->size = size;
+ xcoff_hash_table (info)->size_list = n;
+
+ h->flags |= XCOFF_HAS_SIZE;
+
+ return true;
+}
+
+/* Import a symbol. */
+
+boolean
+bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile,
+ impmember)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct bfd_link_hash_entry *harg;
+ bfd_vma val;
+ const char *imppath;
+ const char *impfile;
+ const char *impmember;
+{
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
+
+ if (! XCOFF_XVECP (output_bfd->xvec))
+ return true;
+
+ /* A symbol name which starts with a period is the code for a
+ function. If the symbol is undefined, then add an undefined
+ symbol for the function descriptor, and import that instead. */
+ if (h->root.root.string[0] == '.'
+ && h->root.type == bfd_link_hash_undefined
+ && val == (bfd_vma) -1)
+ {
+ struct xcoff_link_hash_entry *hds;
+
+ hds = h->descriptor;
+ if (hds == NULL)
+ {
+ hds = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ h->root.root.string + 1,
+ true, false, true);
+ if (hds == NULL)
+ return false;
+ if (hds->root.type == bfd_link_hash_new)
+ {
+ hds->root.type = bfd_link_hash_undefined;
+ hds->root.u.undef.abfd = h->root.u.undef.abfd;
+ }
+ hds->flags |= XCOFF_DESCRIPTOR;
+ BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0
+ && (h->flags & XCOFF_DESCRIPTOR) == 0);
+ hds->descriptor = h;
+ h->descriptor = hds;
+ }
+
+ /* Now, if the descriptor is undefined, import the descriptor
+ rather than the symbol we were told to import. FIXME: Is
+ this correct in all cases? */
+ if (hds->root.type == bfd_link_hash_undefined)
+ h = hds;
+ }
+
+ h->flags |= XCOFF_IMPORT;
+
+ if (val != (bfd_vma) -1)
+ {
+ if (h->root.type == bfd_link_hash_defined
+ && (! bfd_is_abs_section (h->root.u.def.section)
+ || h->root.u.def.value != val))
+ {
+ if (! ((*info->callbacks->multiple_definition)
+ (info, h->root.root.string, h->root.u.def.section->owner,
+ h->root.u.def.section, h->root.u.def.value,
+ output_bfd, bfd_abs_section_ptr, val)))
+ return false;
+ }
+
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.value = val;
+ }
+
+ /* We overload the ldindx field to hold the l_ifile value for this
+ symbol. */
+ BFD_ASSERT (h->ldsym == NULL);
+ BFD_ASSERT ((h->flags & XCOFF_BUILT_LDSYM) == 0);
+ if (imppath == NULL)
+ h->ldindx = -1;
+ else
+ {
+ unsigned int c;
+ struct xcoff_import_file **pp;
+
+ /* We start c at 1 because the first entry in the import list is
+ reserved for the library search path. */
+ for (pp = &xcoff_hash_table (info)->imports, c = 1;
+ *pp != NULL;
+ pp = &(*pp)->next, ++c)
+ {
+ if (strcmp ((*pp)->path, imppath) == 0
+ && strcmp ((*pp)->file, impfile) == 0
+ && strcmp ((*pp)->member, impmember) == 0)
+ break;
+ }
+
+ if (*pp == NULL)
+ {
+ struct xcoff_import_file *n;
+
+ n = ((struct xcoff_import_file *)
+ bfd_alloc (output_bfd, sizeof (struct xcoff_import_file)));
+ if (n == NULL)
+ return false;
+ n->next = NULL;
+ n->path = imppath;
+ n->file = impfile;
+ n->member = impmember;
+ *pp = n;
+ }
+
+ h->ldindx = c;
+ }
+
+ return true;
+}
+
+/* Export a symbol. */
+
+boolean
+bfd_xcoff_export_symbol (output_bfd, info, harg, syscall)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ struct bfd_link_hash_entry *harg;
+ boolean syscall;
+{
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
+
+ if (! XCOFF_XVECP (output_bfd->xvec))
+ return true;
+
+ h->flags |= XCOFF_EXPORT;
+
+ /* FIXME: I'm not at all sure what syscall is supposed to mean, so
+ I'm just going to ignore it until somebody explains it. */
+
+ /* See if this is a function descriptor. It may be one even though
+ it is not so marked. */
+ if ((h->flags & XCOFF_DESCRIPTOR) == 0
+ && h->root.root.string[0] != '.')
+ {
+ char *fnname;
+ struct xcoff_link_hash_entry *hfn;
+
+ fnname = (char *) bfd_malloc (strlen (h->root.root.string) + 2);
+ if (fnname == NULL)
+ return false;
+ fnname[0] = '.';
+ strcpy (fnname + 1, h->root.root.string);
+ hfn = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ fnname, false, false, true);
+ free (fnname);
+ if (hfn != NULL
+ && hfn->smclas == XMC_PR
+ && (hfn->root.type == bfd_link_hash_defined
+ || hfn->root.type == bfd_link_hash_defweak))
+ {
+ h->flags |= XCOFF_DESCRIPTOR;
+ h->descriptor = hfn;
+ hfn->descriptor = h;
+ }
+ }
+
+ /* Make sure we don't garbage collect this symbol. */
+ if (! xcoff_mark_symbol (info, h))
+ return false;
+
+ /* If this is a function descriptor, make sure we don't garbage
+ collect the associated function code. We normally don't have to
+ worry about this, because the descriptor will be attached to a
+ section with relocs, but if we are creating the descriptor
+ ourselves those relocs will not be visible to the mark code. */
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0)
+ {
+ if (! xcoff_mark_symbol (info, h->descriptor))
+ return false;
+ }
+
+ return true;
+}
+
+/* Count a reloc against a symbol. This is called for relocs
+ generated by the linker script, typically for global constructors
+ and destructors. */
+
+boolean
+bfd_xcoff_link_count_reloc (output_bfd, info, name)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ const char *name;
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (! XCOFF_XVECP (output_bfd->xvec))
+ return true;
+
+ h = ((struct xcoff_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (output_bfd, info, name, false, false,
+ false));
+ if (h == NULL)
+ {
+ (*_bfd_error_handler) (_("%s: no such symbol"), name);
+ bfd_set_error (bfd_error_no_symbols);
+ return false;
+ }
+
+ h->flags |= XCOFF_REF_REGULAR | XCOFF_LDREL;
+ ++xcoff_hash_table (info)->ldrel_count;
+
+ /* Mark the symbol to avoid garbage collection. */
+ if (! xcoff_mark_symbol (info, h))
+ return false;
+
+ return true;
+}
+
+/* This function is called for each symbol to which the linker script
+ assigns a value. */
+
+boolean
+bfd_xcoff_record_link_assignment (output_bfd, info, name)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ const char *name;
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (! XCOFF_XVECP (output_bfd->xvec))
+ return true;
+
+ h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true, true,
+ false);
+ if (h == NULL)
+ return false;
+
+ h->flags |= XCOFF_DEF_REGULAR;
+
+ return true;
+}
+
+/* This structure is used to pass information through
+ xcoff_link_hash_traverse. */
+
+struct xcoff_loader_info
+{
+ /* Set if a problem occurred. */
+ boolean failed;
+ /* Output BFD. */
+ bfd *output_bfd;
+ /* Link information structure. */
+ struct bfd_link_info *info;
+ /* Whether all defined symbols should be exported. */
+ boolean export_defineds;
+ /* Number of ldsym structures. */
+ size_t ldsym_count;
+ /* Size of string table. */
+ size_t string_size;
+ /* String table. */
+ bfd_byte *strings;
+ /* Allocated size of string table. */
+ size_t string_alc;
+};
+
+/* Build the .loader section. This is called by the XCOFF linker
+ emulation before_allocation routine. We must set the size of the
+ .loader section before the linker lays out the output file.
+ LIBPATH is the library path to search for shared objects; this is
+ normally built from the -L arguments passed to the linker. ENTRY
+ is the name of the entry point symbol (the -e linker option).
+ FILE_ALIGN is the alignment to use for sections within the file
+ (the -H linker option). MAXSTACK is the maximum stack size (the
+ -bmaxstack linker option). MAXDATA is the maximum data size (the
+ -bmaxdata linker option). GC is whether to do garbage collection
+ (the -bgc linker option). MODTYPE is the module type (the
+ -bmodtype linker option). TEXTRO is whether the text section must
+ be read only (the -btextro linker option). EXPORT_DEFINEDS is
+ whether all defined symbols should be exported (the -unix linker
+ option). SPECIAL_SECTIONS is set by this routine to csects with
+ magic names like _end. */
+
+boolean
+bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry,
+ file_align, maxstack, maxdata, gc,
+ modtype, textro, export_defineds,
+ special_sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ const char *libpath;
+ const char *entry;
+ unsigned long file_align;
+ unsigned long maxstack;
+ unsigned long maxdata;
+ boolean gc;
+ int modtype;
+ boolean textro;
+ boolean export_defineds;
+ asection **special_sections;
+{
+ struct xcoff_link_hash_entry *hentry;
+ asection *lsec;
+ struct xcoff_loader_info ldinfo;
+ int i;
+ size_t impsize, impcount;
+ struct xcoff_import_file *fl;
+ struct internal_ldhdr *ldhdr;
+ bfd_size_type stoff;
+ register char *out;
+ asection *sec;
+ bfd *sub;
+ struct bfd_strtab_hash *debug_strtab;
+ bfd_byte *debug_contents = NULL;
+
+ if (! XCOFF_XVECP (output_bfd->xvec))
+ {
+ for (i = 0; i < 6; i++)
+ special_sections[i] = NULL;
+ return true;
+ }
+
+ ldinfo.failed = false;
+ ldinfo.output_bfd = output_bfd;
+ ldinfo.info = info;
+ ldinfo.export_defineds = export_defineds;
+ ldinfo.ldsym_count = 0;
+ ldinfo.string_size = 0;
+ ldinfo.strings = NULL;
+ ldinfo.string_alc = 0;
+
+ xcoff_data (output_bfd)->maxstack = maxstack;
+ xcoff_data (output_bfd)->maxdata = maxdata;
+ xcoff_data (output_bfd)->modtype = modtype;
+
+ xcoff_hash_table (info)->file_align = file_align;
+ xcoff_hash_table (info)->textro = textro;
+
+ hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry,
+ false, false, true);
+ if (hentry != NULL)
+ hentry->flags |= XCOFF_ENTRY;
+
+ /* Garbage collect unused sections. */
+ if (info->relocateable
+ || ! gc
+ || hentry == NULL
+ || (hentry->root.type != bfd_link_hash_defined
+ && hentry->root.type != bfd_link_hash_defweak))
+ {
+ gc = false;
+ xcoff_hash_table (info)->gc = false;
+
+ /* We still need to call xcoff_mark, in order to set ldrel_count
+ correctly. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ asection *o;
+
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_MARK) == 0)
+ {
+ if (! xcoff_mark (info, o))
+ goto error_return;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (! xcoff_mark (info, hentry->root.u.def.section))
+ goto error_return;
+ xcoff_sweep (info);
+ xcoff_hash_table (info)->gc = true;
+ }
+
+ /* Return special sections to the caller. */
+ for (i = 0; i < 6; i++)
+ {
+ asection *sec;
+
+ sec = xcoff_hash_table (info)->special_sections[i];
+ if (sec != NULL
+ && gc
+ && (sec->flags & SEC_MARK) == 0)
+ sec = NULL;
+ special_sections[i] = sec;
+ }
+
+ if (info->input_bfds == NULL)
+ {
+ /* I'm not sure what to do in this bizarre case. */
+ return true;
+ }
+
+ xcoff_link_hash_traverse (xcoff_hash_table (info), xcoff_build_ldsyms,
+ (PTR) &ldinfo);
+ if (ldinfo.failed)
+ goto error_return;
+
+ /* Work out the size of the import file names. Each import file ID
+ consists of three null terminated strings: the path, the file
+ name, and the archive member name. The first entry in the list
+ of names is the path to use to find objects, which the linker has
+ passed in as the libpath argument. For some reason, the path
+ entry in the other import file names appears to always be empty. */
+ impsize = strlen (libpath) + 3;
+ impcount = 1;
+ for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next)
+ {
+ ++impcount;
+ impsize += (strlen (fl->path)
+ + strlen (fl->file)
+ + strlen (fl->member)
+ + 3);
+ }
+
+ /* Set up the .loader section header. */
+ ldhdr = &xcoff_hash_table (info)->ldhdr;
+ ldhdr->l_version = 1;
+ ldhdr->l_nsyms = ldinfo.ldsym_count;
+ ldhdr->l_nreloc = xcoff_hash_table (info)->ldrel_count;
+ ldhdr->l_istlen = impsize;
+ ldhdr->l_nimpid = impcount;
+ ldhdr->l_impoff = (LDHDRSZ
+ + ldhdr->l_nsyms * LDSYMSZ
+ + ldhdr->l_nreloc * LDRELSZ);
+ ldhdr->l_stlen = ldinfo.string_size;
+ stoff = ldhdr->l_impoff + impsize;
+ if (ldinfo.string_size == 0)
+ ldhdr->l_stoff = 0;
+ else
+ ldhdr->l_stoff = stoff;
+
+ /* We now know the final size of the .loader section. Allocate
+ space for it. */
+ lsec = xcoff_hash_table (info)->loader_section;
+ lsec->_raw_size = stoff + ldhdr->l_stlen;
+ lsec->contents = (bfd_byte *) bfd_zalloc (output_bfd, lsec->_raw_size);
+ if (lsec->contents == NULL)
+ goto error_return;
+
+ /* Set up the header. */
+ xcoff_swap_ldhdr_out (output_bfd, ldhdr,
+ (struct external_ldhdr *) lsec->contents);
+
+ /* Set up the import file names. */
+ out = (char *) lsec->contents + ldhdr->l_impoff;
+ strcpy (out, libpath);
+ out += strlen (libpath) + 1;
+ *out++ = '\0';
+ *out++ = '\0';
+ for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next)
+ {
+ register const char *s;
+
+ s = fl->path;
+ while ((*out++ = *s++) != '\0')
+ ;
+ s = fl->file;
+ while ((*out++ = *s++) != '\0')
+ ;
+ s = fl->member;
+ while ((*out++ = *s++) != '\0')
+ ;
+ }
+
+ BFD_ASSERT ((bfd_size_type) ((bfd_byte *) out - lsec->contents) == stoff);
+
+ /* Set up the symbol string table. */
+ if (ldinfo.string_size > 0)
+ {
+ memcpy (out, ldinfo.strings, ldinfo.string_size);
+ free (ldinfo.strings);
+ ldinfo.strings = NULL;
+ }
+
+ /* We can't set up the symbol table or the relocs yet, because we
+ don't yet know the final position of the various sections. The
+ .loader symbols are written out when the corresponding normal
+ symbols are written out in xcoff_link_input_bfd or
+ xcoff_write_global_symbol. The .loader relocs are written out
+ when the corresponding normal relocs are handled in
+ xcoff_link_input_bfd. */
+
+ /* Allocate space for the magic sections. */
+ sec = xcoff_hash_table (info)->linkage_section;
+ if (sec->_raw_size > 0)
+ {
+ sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
+ if (sec->contents == NULL)
+ goto error_return;
+ }
+ sec = xcoff_hash_table (info)->toc_section;
+ if (sec->_raw_size > 0)
+ {
+ sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
+ if (sec->contents == NULL)
+ goto error_return;
+ }
+ sec = xcoff_hash_table (info)->descriptor_section;
+ if (sec->_raw_size > 0)
+ {
+ sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size);
+ if (sec->contents == NULL)
+ goto error_return;
+ }
+
+ /* Now that we've done garbage collection, figure out the contents
+ of the .debug section. */
+ debug_strtab = xcoff_hash_table (info)->debug_strtab;
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ asection *subdeb;
+ bfd_size_type symcount;
+ unsigned long *debug_index;
+ asection **csectpp;
+ bfd_byte *esym, *esymend;
+ bfd_size_type symesz;
+
+ if (sub->xvec != info->hash->creator)
+ continue;
+ subdeb = bfd_get_section_by_name (sub, ".debug");
+ if (subdeb == NULL || subdeb->_raw_size == 0)
+ continue;
+
+ if (info->strip == strip_all
+ || info->strip == strip_debugger
+ || info->discard == discard_all)
+ {
+ subdeb->_raw_size = 0;
+ continue;
+ }
+
+ if (! _bfd_coff_get_external_symbols (sub))
+ goto error_return;
+
+ symcount = obj_raw_syment_count (sub);
+ debug_index = ((unsigned long *)
+ bfd_zalloc (sub, symcount * sizeof (unsigned long)));
+ if (debug_index == NULL)
+ goto error_return;
+ xcoff_data (sub)->debug_indices = debug_index;
+
+ /* Grab the contents of the .debug section. We use malloc and
+ copy the names into the debug stringtab, rather than
+ bfd_alloc, because I expect that, when linking many files
+ together, many of the strings will be the same. Storing the
+ strings in the hash table should save space in this case. */
+ debug_contents = (bfd_byte *) bfd_malloc (subdeb->_raw_size);
+ if (debug_contents == NULL)
+ goto error_return;
+ if (! bfd_get_section_contents (sub, subdeb, (PTR) debug_contents,
+ (file_ptr) 0, subdeb->_raw_size))
+ goto error_return;
+
+ csectpp = xcoff_data (sub)->csects;
+
+ symesz = bfd_coff_symesz (sub);
+ esym = (bfd_byte *) obj_coff_external_syms (sub);
+ esymend = esym + symcount * symesz;
+ while (esym < esymend)
+ {
+ struct internal_syment sym;
+
+ bfd_coff_swap_sym_in (sub, (PTR) esym, (PTR) &sym);
+
+ *debug_index = (unsigned long) -1;
+
+ if (sym._n._n_n._n_zeroes == 0
+ && *csectpp != NULL
+ && (! gc
+ || ((*csectpp)->flags & SEC_MARK) != 0
+ || *csectpp == bfd_abs_section_ptr)
+ && bfd_coff_symname_in_debug (sub, &sym))
+ {
+ char *name;
+ bfd_size_type indx;
+
+ name = (char *) debug_contents + sym._n._n_n._n_offset;
+ indx = _bfd_stringtab_add (debug_strtab, name, true, true);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ *debug_index = indx;
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ csectpp += sym.n_numaux + 1;
+ debug_index += sym.n_numaux + 1;
+ }
+
+ free (debug_contents);
+ debug_contents = NULL;
+
+ /* Clear the size of subdeb, so that it is not included directly
+ in the output file. */
+ subdeb->_raw_size = 0;
+
+ if (! info->keep_memory)
+ {
+ if (! _bfd_coff_free_symbols (sub))
+ goto error_return;
+ }
+ }
+
+ if (info->strip != strip_all)
+ xcoff_hash_table (info)->debug_section->_raw_size =
+ _bfd_stringtab_size (debug_strtab);
+
+ return true;
+
+ error_return:
+ if (ldinfo.strings != NULL)
+ free (ldinfo.strings);
+ if (debug_contents != NULL)
+ free (debug_contents);
+ return false;
+}
+
+/* Add a symbol to the .loader symbols, if necessary. */
+
+static boolean
+xcoff_build_ldsyms (h, p)
+ struct xcoff_link_hash_entry *h;
+ PTR p;
+{
+ struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
+ size_t len;
+
+ /* If this is a final link, and the symbol was defined as a common
+ symbol in a regular object file, and there was no definition in
+ any dynamic object, then the linker will have allocated space for
+ the symbol in a common section but the XCOFF_DEF_REGULAR flag
+ will not have been set. */
+ if (h->root.type == bfd_link_hash_defined
+ && (h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->flags & XCOFF_REF_REGULAR) != 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) == 0
+ && (bfd_is_abs_section (h->root.u.def.section)
+ || (h->root.u.def.section->owner->flags & DYNAMIC) == 0))
+ h->flags |= XCOFF_DEF_REGULAR;
+
+ /* If all defined symbols should be exported, mark them now. We
+ don't want to export the actual functions, just the function
+ descriptors. */
+ if (ldinfo->export_defineds
+ && (h->flags & XCOFF_DEF_REGULAR) != 0
+ && h->root.root.string[0] != '.')
+ {
+ boolean export;
+
+ /* We don't export a symbol which is being defined by an object
+ included from an archive which contains a shared object. The
+ rationale is that if an archive contains both an unshared and
+ a shared object, then there must be some reason that the
+ unshared object is unshared, and we don't want to start
+ providing a shared version of it. In particular, this solves
+ a bug involving the _savefNN set of functions. gcc will call
+ those functions without providing a slot to restore the TOC,
+ so it is essential that these functions be linked in directly
+ and not from a shared object, which means that a shared
+ object which also happens to link them in must not export
+ them. This is confusing, but I haven't been able to think of
+ a different approach. Note that the symbols can, of course,
+ be exported explicitly. */
+ export = true;
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->owner != NULL
+ && h->root.u.def.section->owner->my_archive != NULL)
+ {
+ bfd *arbfd, *member;
+
+ arbfd = h->root.u.def.section->owner->my_archive;
+ member = bfd_openr_next_archived_file (arbfd, (bfd *) NULL);
+ while (member != NULL)
+ {
+ if ((member->flags & DYNAMIC) != 0)
+ {
+ export = false;
+ break;
+ }
+ member = bfd_openr_next_archived_file (arbfd, member);
+ }
+ }
+
+ if (export)
+ h->flags |= XCOFF_EXPORT;
+ }
+
+ /* We don't want to garbage collect symbols which are not defined in
+ XCOFF files. This is a convenient place to mark them. */
+ if (xcoff_hash_table (ldinfo->info)->gc
+ && (h->flags & XCOFF_MARK) == 0
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.section->owner == NULL
+ || (h->root.u.def.section->owner->xvec
+ != ldinfo->info->hash->creator)))
+ h->flags |= XCOFF_MARK;
+
+ /* If this symbol is called and defined in a dynamic object, or it
+ is imported, then we need to set up global linkage code for it.
+ (Unless we did garbage collection and we didn't need this
+ symbol.) */
+ if ((h->flags & XCOFF_CALLED) != 0
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ && h->root.root.string[0] == '.'
+ && h->descriptor != NULL
+ && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0
+ || ((h->descriptor->flags & XCOFF_IMPORT) != 0
+ && (h->descriptor->flags & XCOFF_DEF_REGULAR) == 0))
+ && (! xcoff_hash_table (ldinfo->info)->gc
+ || (h->flags & XCOFF_MARK) != 0))
+ {
+ asection *sec;
+ struct xcoff_link_hash_entry *hds;
+
+ sec = xcoff_hash_table (ldinfo->info)->linkage_section;
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = sec;
+ h->root.u.def.value = sec->_raw_size;
+ h->smclas = XMC_GL;
+ h->flags |= XCOFF_DEF_REGULAR;
+ sec->_raw_size += XCOFF_GLINK_SIZE;
+
+ /* The global linkage code requires a TOC entry for the
+ descriptor. */
+ hds = h->descriptor;
+ BFD_ASSERT ((hds->root.type == bfd_link_hash_undefined
+ || hds->root.type == bfd_link_hash_undefweak)
+ && (hds->flags & XCOFF_DEF_REGULAR) == 0);
+ hds->flags |= XCOFF_MARK;
+ if (hds->toc_section == NULL)
+ {
+ hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
+ hds->u.toc_offset = hds->toc_section->_raw_size;
+ hds->toc_section->_raw_size += 4;
+ ++xcoff_hash_table (ldinfo->info)->ldrel_count;
+ ++hds->toc_section->reloc_count;
+ hds->indx = -2;
+ hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL;
+
+ /* We need to call xcoff_build_ldsyms recursively here,
+ because we may already have passed hds on the traversal. */
+ xcoff_build_ldsyms (hds, p);
+ }
+ }
+
+ /* If this symbol is exported, but not defined, we need to try to
+ define it. */
+ if ((h->flags & XCOFF_EXPORT) != 0
+ && (h->flags & XCOFF_IMPORT) == 0
+ && (h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) == 0
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ {
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0
+ && (h->descriptor->root.type == bfd_link_hash_defined
+ || h->descriptor->root.type == bfd_link_hash_defweak))
+ {
+ asection *sec;
+
+ /* This is an undefined function descriptor associated with
+ a defined entry point. We can build up a function
+ descriptor ourselves. Believe it or not, the AIX linker
+ actually does this, and there are cases where we need to
+ do it as well. */
+ sec = xcoff_hash_table (ldinfo->info)->descriptor_section;
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = sec;
+ h->root.u.def.value = sec->_raw_size;
+ h->smclas = XMC_DS;
+ h->flags |= XCOFF_DEF_REGULAR;
+ sec->_raw_size += 12;
+
+ /* A function descriptor uses two relocs: one for the
+ associated code, and one for the TOC address. */
+ xcoff_hash_table (ldinfo->info)->ldrel_count += 2;
+ sec->reloc_count += 2;
+
+ /* We handle writing out the contents of the descriptor in
+ xcoff_write_global_symbol. */
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("warning: attempt to export undefined symbol `%s'"),
+ h->root.root.string);
+ h->ldsym = NULL;
+ return true;
+ }
+ }
+
+ /* If this is still a common symbol, and it wasn't garbage
+ collected, we need to actually allocate space for it in the .bss
+ section. */
+ if (h->root.type == bfd_link_hash_common
+ && (! xcoff_hash_table (ldinfo->info)->gc
+ || (h->flags & XCOFF_MARK) != 0)
+ && h->root.u.c.p->section->_raw_size == 0)
+ {
+ BFD_ASSERT (bfd_is_com_section (h->root.u.c.p->section));
+ h->root.u.c.p->section->_raw_size = h->root.u.c.size;
+ }
+
+ /* We need to add a symbol to the .loader section if it is mentioned
+ in a reloc which we are copying to the .loader section and it was
+ not defined or common, or if it is the entry point, or if it is
+ being exported. */
+
+ if (((h->flags & XCOFF_LDREL) == 0
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_common)
+ && (h->flags & XCOFF_ENTRY) == 0
+ && (h->flags & XCOFF_EXPORT) == 0)
+ {
+ h->ldsym = NULL;
+ return true;
+ }
+
+ /* We don't need to add this symbol if we did garbage collection and
+ we did not mark this symbol. */
+ if (xcoff_hash_table (ldinfo->info)->gc
+ && (h->flags & XCOFF_MARK) == 0)
+ {
+ h->ldsym = NULL;
+ return true;
+ }
+
+ /* We may have already processed this symbol due to the recursive
+ call above. */
+ if ((h->flags & XCOFF_BUILT_LDSYM) != 0)
+ return true;
+
+ /* We need to add this symbol to the .loader symbols. */
+
+ BFD_ASSERT (h->ldsym == NULL);
+ h->ldsym = ((struct internal_ldsym *)
+ bfd_zalloc (ldinfo->output_bfd,
+ sizeof (struct internal_ldsym)));
+ if (h->ldsym == NULL)
+ {
+ ldinfo->failed = true;
+ return false;
+ }
+
+ if ((h->flags & XCOFF_IMPORT) != 0)
+ h->ldsym->l_ifile = h->ldindx;
+
+ /* The first 3 symbol table indices are reserved to indicate the
+ sections. */
+ h->ldindx = ldinfo->ldsym_count + 3;
+
+ ++ldinfo->ldsym_count;
+
+ len = strlen (h->root.root.string);
+ if (len <= SYMNMLEN)
+ strncpy (h->ldsym->_l._l_name, h->root.root.string, SYMNMLEN);
+ else
+ {
+ if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
+ {
+ size_t newalc;
+ bfd_byte *newstrings;
+
+ newalc = ldinfo->string_alc * 2;
+ if (newalc == 0)
+ newalc = 32;
+ while (ldinfo->string_size + len + 3 > newalc)
+ newalc *= 2;
+
+ newstrings = ((bfd_byte *)
+ bfd_realloc ((PTR) ldinfo->strings, newalc));
+ if (newstrings == NULL)
+ {
+ ldinfo->failed = true;
+ return false;
+ }
+ ldinfo->string_alc = newalc;
+ ldinfo->strings = newstrings;
+ }
+
+ bfd_put_16 (ldinfo->output_bfd, len + 1,
+ ldinfo->strings + ldinfo->string_size);
+ strcpy (ldinfo->strings + ldinfo->string_size + 2, h->root.root.string);
+ h->ldsym->_l._l_l._l_zeroes = 0;
+ h->ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
+ ldinfo->string_size += len + 3;
+ }
+
+ h->flags |= XCOFF_BUILT_LDSYM;
+
+ return true;
+}
+
+/* Do the final link step. */
+
+boolean
+_bfd_xcoff_bfd_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd_size_type symesz;
+ struct xcoff_final_link_info finfo;
+ asection *o;
+ struct bfd_link_order *p;
+ size_t max_contents_size;
+ size_t max_sym_count;
+ size_t max_lineno_count;
+ size_t max_reloc_count;
+ size_t max_output_reloc_count;
+ file_ptr rel_filepos;
+ unsigned int relsz;
+ file_ptr line_filepos;
+ unsigned int linesz;
+ bfd *sub;
+ bfd_byte *external_relocs = NULL;
+ char strbuf[STRING_SIZE_SIZE];
+
+ if (info->shared)
+ abfd->flags |= DYNAMIC;
+
+ symesz = bfd_coff_symesz (abfd);
+
+ finfo.info = info;
+ finfo.output_bfd = abfd;
+ finfo.strtab = NULL;
+ finfo.section_info = NULL;
+ finfo.last_file_index = -1;
+ finfo.toc_symindx = -1;
+ finfo.internal_syms = NULL;
+ finfo.sym_indices = NULL;
+ finfo.outsyms = NULL;
+ finfo.linenos = NULL;
+ finfo.contents = NULL;
+ finfo.external_relocs = NULL;
+
+ finfo.ldsym = ((struct external_ldsym *)
+ (xcoff_hash_table (info)->loader_section->contents
+ + LDHDRSZ));
+ finfo.ldrel = ((struct external_ldrel *)
+ (xcoff_hash_table (info)->loader_section->contents
+ + LDHDRSZ
+ + xcoff_hash_table (info)->ldhdr.l_nsyms * LDSYMSZ));
+
+ xcoff_data (abfd)->coff.link_info = info;
+
+ finfo.strtab = _bfd_stringtab_init ();
+ if (finfo.strtab == NULL)
+ goto error_return;
+
+ /* Count the line number and relocation entries required for the
+ output file. Determine a few maximum sizes. */
+ max_contents_size = 0;
+ max_lineno_count = 0;
+ max_reloc_count = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+
+ /* Mark all sections which are to be included in the
+ link. This will normally be every section. We need
+ to do this so that we can identify any sections which
+ the linker has decided to not include. */
+ sec->linker_mark = true;
+
+ if (info->strip == strip_none
+ || info->strip == strip_some)
+ o->lineno_count += sec->lineno_count;
+
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->_raw_size > max_contents_size)
+ max_contents_size = sec->_raw_size;
+ if (sec->lineno_count > max_lineno_count)
+ max_lineno_count = sec->lineno_count;
+ if (coff_section_data (sec->owner, sec) != NULL
+ && xcoff_section_data (sec->owner, sec) != NULL
+ && (xcoff_section_data (sec->owner, sec)->lineno_count
+ > max_lineno_count))
+ max_lineno_count =
+ xcoff_section_data (sec->owner, sec)->lineno_count;
+ if (sec->reloc_count > max_reloc_count)
+ max_reloc_count = sec->reloc_count;
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ ++o->reloc_count;
+ }
+ }
+
+ /* Compute the file positions for all the sections. */
+ if (abfd->output_has_begun)
+ {
+ if (xcoff_hash_table (info)->file_align != 0)
+ abort ();
+ }
+ else
+ {
+ bfd_vma file_align;
+
+ file_align = xcoff_hash_table (info)->file_align;
+ if (file_align != 0)
+ {
+ boolean saw_contents;
+ int indx;
+ asection **op;
+ file_ptr sofar;
+
+ /* Insert .pad sections before every section which has
+ contents and is loaded, if it is preceded by some other
+ section which has contents and is loaded. */
+ saw_contents = true;
+ for (op = &abfd->sections; *op != NULL; op = &(*op)->next)
+ {
+ if (strcmp ((*op)->name, ".pad") == 0)
+ saw_contents = false;
+ else if (((*op)->flags & SEC_HAS_CONTENTS) != 0
+ && ((*op)->flags & SEC_LOAD) != 0)
+ {
+ if (! saw_contents)
+ saw_contents = true;
+ else
+ {
+ asection *n, *hold;
+
+ hold = *op;
+ *op = NULL;
+ n = bfd_make_section_anyway (abfd, ".pad");
+ BFD_ASSERT (*op == n);
+ n->next = hold;
+ n->flags = SEC_HAS_CONTENTS;
+ n->alignment_power = 0;
+ saw_contents = false;
+ }
+ }
+ }
+
+ /* Reset the section indices after inserting the new
+ sections. */
+ indx = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ ++indx;
+ o->target_index = indx;
+ }
+ BFD_ASSERT ((unsigned int) indx == abfd->section_count);
+
+ /* Work out appropriate sizes for the .pad sections to force
+ each section to land on a page boundary. This bit of
+ code knows what compute_section_file_positions is going
+ to do. */
+ sofar = bfd_coff_filhsz (abfd);
+ sofar += bfd_coff_aoutsz (abfd);
+ sofar += abfd->section_count * bfd_coff_scnhsz (abfd);
+ for (o = abfd->sections; o != NULL; o = o->next)
+ if (o->reloc_count >= 0xffff || o->lineno_count >= 0xffff)
+ sofar += bfd_coff_scnhsz (abfd);
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (strcmp (o->name, ".pad") == 0)
+ {
+ bfd_vma pageoff;
+
+ BFD_ASSERT (o->_raw_size == 0);
+ pageoff = sofar & (file_align - 1);
+ if (pageoff != 0)
+ {
+ o->_raw_size = file_align - pageoff;
+ sofar += file_align - pageoff;
+ o->flags |= SEC_HAS_CONTENTS;
+ }
+ }
+ else
+ {
+ if ((o->flags & SEC_HAS_CONTENTS) != 0)
+ sofar += BFD_ALIGN (o->_raw_size,
+ 1 << o->alignment_power);
+ }
+ }
+ }
+
+ if (! bfd_coff_compute_section_file_positions (abfd))
+ goto error_return;
+ }
+
+ /* Allocate space for the pointers we need to keep for the relocs. */
+ {
+ unsigned int i;
+
+ /* We use section_count + 1, rather than section_count, because
+ the target_index fields are 1 based. */
+ finfo.section_info =
+ ((struct xcoff_link_section_info *)
+ bfd_malloc ((abfd->section_count + 1)
+ * sizeof (struct xcoff_link_section_info)));
+ if (finfo.section_info == NULL)
+ goto error_return;
+ for (i = 0; i <= abfd->section_count; i++)
+ {
+ finfo.section_info[i].relocs = NULL;
+ finfo.section_info[i].rel_hashes = NULL;
+ finfo.section_info[i].toc_rel_hashes = NULL;
+ }
+ }
+
+ /* Set the file positions for the relocs. */
+ rel_filepos = obj_relocbase (abfd);
+ relsz = bfd_coff_relsz (abfd);
+ max_output_reloc_count = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->reloc_count == 0)
+ o->rel_filepos = 0;
+ else
+ {
+ /* A stripped file has no relocs. However, we still
+ allocate the buffers, so that later code doesn't have to
+ worry about whether we are stripping or not. */
+ if (info->strip == strip_all)
+ o->rel_filepos = 0;
+ else
+ {
+ o->flags |= SEC_RELOC;
+ o->rel_filepos = rel_filepos;
+ rel_filepos += o->reloc_count * relsz;
+ }
+
+ /* We don't know the indices of global symbols until we have
+ written out all the local symbols. For each section in
+ the output file, we keep an array of pointers to hash
+ table entries. Each entry in the array corresponds to a
+ reloc. When we find a reloc against a global symbol, we
+ set the corresponding entry in this array so that we can
+ fix up the symbol index after we have written out all the
+ local symbols.
+
+ Because of this problem, we also keep the relocs in
+ memory until the end of the link. This wastes memory.
+ We could backpatch the file later, I suppose, although it
+ would be slow. */
+ finfo.section_info[o->target_index].relocs =
+ ((struct internal_reloc *)
+ bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
+ finfo.section_info[o->target_index].rel_hashes =
+ ((struct xcoff_link_hash_entry **)
+ bfd_malloc (o->reloc_count
+ * sizeof (struct xcoff_link_hash_entry *)));
+ if (finfo.section_info[o->target_index].relocs == NULL
+ || finfo.section_info[o->target_index].rel_hashes == NULL)
+ goto error_return;
+
+ if (o->reloc_count > max_output_reloc_count)
+ max_output_reloc_count = o->reloc_count;
+ }
+ }
+
+ /* We now know the size of the relocs, so we can determine the file
+ positions of the line numbers. */
+ line_filepos = rel_filepos;
+ finfo.line_filepos = line_filepos;
+ linesz = bfd_coff_linesz (abfd);
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->lineno_count == 0)
+ o->line_filepos = 0;
+ else
+ {
+ o->line_filepos = line_filepos;
+ line_filepos += o->lineno_count * linesz;
+ }
+
+ /* Reset the reloc and lineno counts, so that we can use them to
+ count the number of entries we have output so far. */
+ o->reloc_count = 0;
+ o->lineno_count = 0;
+ }
+
+ obj_sym_filepos (abfd) = line_filepos;
+
+ /* Figure out the largest number of symbols in an input BFD. Take
+ the opportunity to clear the output_has_begun fields of all the
+ input BFD's. We want at least 6 symbols, since that is the
+ number which xcoff_write_global_symbol may need. */
+ max_sym_count = 6;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ {
+ size_t sz;
+
+ sub->output_has_begun = false;
+ sz = obj_raw_syment_count (sub);
+ if (sz > max_sym_count)
+ max_sym_count = sz;
+ }
+
+ /* Allocate some buffers used while linking. */
+ finfo.internal_syms = ((struct internal_syment *)
+ bfd_malloc (max_sym_count
+ * sizeof (struct internal_syment)));
+ finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
+ finfo.outsyms = ((bfd_byte *)
+ bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
+ finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
+ * bfd_coff_linesz (abfd));
+ finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
+ if ((finfo.internal_syms == NULL && max_sym_count > 0)
+ || (finfo.sym_indices == NULL && max_sym_count > 0)
+ || finfo.outsyms == NULL
+ || (finfo.linenos == NULL && max_lineno_count > 0)
+ || (finfo.contents == NULL && max_contents_size > 0)
+ || (finfo.external_relocs == NULL && max_reloc_count > 0))
+ goto error_return;
+
+ obj_raw_syment_count (abfd) = 0;
+ xcoff_data (abfd)->toc = (bfd_vma) -1;
+
+ /* We now know the position of everything in the file, except that
+ we don't know the size of the symbol table and therefore we don't
+ know where the string table starts. We just build the string
+ table in memory as we go along. We process all the relocations
+ for a single input file at once. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->link_order_head; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && p->u.indirect.section->owner->xvec == abfd->xvec)
+ {
+ sub = p->u.indirect.section->owner;
+ if (! sub->output_has_begun)
+ {
+ if (! xcoff_link_input_bfd (&finfo, sub))
+ goto error_return;
+ sub->output_has_begun = true;
+ }
+ }
+ else if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ {
+ if (! xcoff_reloc_link_order (abfd, &finfo, o, p))
+ goto error_return;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ }
+ }
+
+ /* Free up the buffers used by xcoff_link_input_bfd. */
+
+ if (finfo.internal_syms != NULL)
+ {
+ free (finfo.internal_syms);
+ finfo.internal_syms = NULL;
+ }
+ if (finfo.sym_indices != NULL)
+ {
+ free (finfo.sym_indices);
+ finfo.sym_indices = NULL;
+ }
+ if (finfo.linenos != NULL)
+ {
+ free (finfo.linenos);
+ finfo.linenos = NULL;
+ }
+ if (finfo.contents != NULL)
+ {
+ free (finfo.contents);
+ finfo.contents = NULL;
+ }
+ if (finfo.external_relocs != NULL)
+ {
+ free (finfo.external_relocs);
+ finfo.external_relocs = NULL;
+ }
+
+ /* The value of the last C_FILE symbol is supposed to be -1. Write
+ it out again. */
+ if (finfo.last_file_index != -1)
+ {
+ finfo.last_file.n_value = -1;
+ bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
+ (PTR) finfo.outsyms);
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + finfo.last_file_index * symesz),
+ SEEK_SET) != 0
+ || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
+ goto error_return;
+ }
+
+ /* Write out all the global symbols which do not come from XCOFF
+ input files. */
+ xcoff_link_hash_traverse (xcoff_hash_table (info),
+ xcoff_write_global_symbol,
+ (PTR) &finfo);
+
+ if (finfo.outsyms != NULL)
+ {
+ free (finfo.outsyms);
+ finfo.outsyms = NULL;
+ }
+
+ /* Now that we have written out all the global symbols, we know the
+ symbol indices to use for relocs against them, and we can finally
+ write out the relocs. */
+ external_relocs = (bfd_byte *) bfd_malloc (max_output_reloc_count * relsz);
+ if (external_relocs == NULL && max_output_reloc_count != 0)
+ goto error_return;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct internal_reloc *irel;
+ struct internal_reloc *irelend;
+ struct xcoff_link_hash_entry **rel_hash;
+ struct xcoff_toc_rel_hash *toc_rel_hash;
+ bfd_byte *erel;
+
+ /* A stripped file has no relocs. */
+ if (info->strip == strip_all)
+ {
+ o->reloc_count = 0;
+ continue;
+ }
+
+ if (o->reloc_count == 0)
+ continue;
+
+ irel = finfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = finfo.section_info[o->target_index].rel_hashes;
+ for (; irel < irelend; irel++, rel_hash++, erel += relsz)
+ {
+ if (*rel_hash != NULL)
+ {
+ if ((*rel_hash)->indx < 0)
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, (*rel_hash)->root.root.string,
+ (bfd *) NULL, o, irel->r_vaddr)))
+ goto error_return;
+ (*rel_hash)->indx = 0;
+ }
+ irel->r_symndx = (*rel_hash)->indx;
+ }
+ }
+
+ for (toc_rel_hash = finfo.section_info[o->target_index].toc_rel_hashes;
+ toc_rel_hash != NULL;
+ toc_rel_hash = toc_rel_hash->next)
+ {
+ if (toc_rel_hash->h->u.toc_indx < 0)
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, toc_rel_hash->h->root.root.string,
+ (bfd *) NULL, o, toc_rel_hash->rel->r_vaddr)))
+ goto error_return;
+ toc_rel_hash->h->u.toc_indx = 0;
+ }
+ toc_rel_hash->rel->r_symndx = toc_rel_hash->h->u.toc_indx;
+ }
+
+ /* XCOFF requires that the relocs be sorted by address. We tend
+ to produce them in the order in which their containing csects
+ appear in the symbol table, which is not necessarily by
+ address. So we sort them here. There may be a better way to
+ do this. */
+ qsort ((PTR) finfo.section_info[o->target_index].relocs,
+ o->reloc_count, sizeof (struct internal_reloc),
+ xcoff_sort_relocs);
+
+ irel = finfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ erel = external_relocs;
+ for (; irel < irelend; irel++, rel_hash++, erel += relsz)
+ bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
+
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
+ || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
+ abfd) != relsz * o->reloc_count)
+ goto error_return;
+ }
+
+ if (external_relocs != NULL)
+ {
+ free (external_relocs);
+ external_relocs = NULL;
+ }
+
+ /* Free up the section information. */
+ if (finfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (finfo.section_info[i].relocs != NULL)
+ free (finfo.section_info[i].relocs);
+ if (finfo.section_info[i].rel_hashes != NULL)
+ free (finfo.section_info[i].rel_hashes);
+ }
+ free (finfo.section_info);
+ finfo.section_info = NULL;
+ }
+
+ /* Write out the loader section contents. */
+ BFD_ASSERT ((bfd_byte *) finfo.ldrel
+ == (xcoff_hash_table (info)->loader_section->contents
+ + xcoff_hash_table (info)->ldhdr.l_impoff));
+ o = xcoff_hash_table (info)->loader_section;
+ if (! bfd_set_section_contents (abfd, o->output_section,
+ o->contents, o->output_offset,
+ o->_raw_size))
+ goto error_return;
+
+ /* Write out the magic sections. */
+ o = xcoff_hash_table (info)->linkage_section;
+ if (o->_raw_size > 0
+ && ! bfd_set_section_contents (abfd, o->output_section, o->contents,
+ o->output_offset, o->_raw_size))
+ goto error_return;
+ o = xcoff_hash_table (info)->toc_section;
+ if (o->_raw_size > 0
+ && ! bfd_set_section_contents (abfd, o->output_section, o->contents,
+ o->output_offset, o->_raw_size))
+ goto error_return;
+ o = xcoff_hash_table (info)->descriptor_section;
+ if (o->_raw_size > 0
+ && ! bfd_set_section_contents (abfd, o->output_section, o->contents,
+ o->output_offset, o->_raw_size))
+ goto error_return;
+
+ /* Write out the string table. */
+ if (bfd_seek (abfd,
+ (obj_sym_filepos (abfd)
+ + obj_raw_syment_count (abfd) * symesz),
+ SEEK_SET) != 0)
+ goto error_return;
+ bfd_h_put_32 (abfd,
+ _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
+ (bfd_byte *) strbuf);
+ if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
+ goto error_return;
+ if (! _bfd_stringtab_emit (abfd, finfo.strtab))
+ goto error_return;
+
+ _bfd_stringtab_free (finfo.strtab);
+
+ /* Write out the debugging string table. */
+ o = xcoff_hash_table (info)->debug_section;
+ if (o != NULL)
+ {
+ struct bfd_strtab_hash *debug_strtab;
+
+ debug_strtab = xcoff_hash_table (info)->debug_strtab;
+ BFD_ASSERT (o->output_section->_raw_size - o->output_offset
+ >= _bfd_stringtab_size (debug_strtab));
+ if (bfd_seek (abfd,
+ o->output_section->filepos + o->output_offset,
+ SEEK_SET) != 0)
+ goto error_return;
+ if (! _bfd_stringtab_emit (abfd, debug_strtab))
+ goto error_return;
+ }
+
+ /* Setting bfd_get_symcount to 0 will cause write_object_contents to
+ not try to write out the symbols. */
+ bfd_get_symcount (abfd) = 0;
+
+ return true;
+
+ error_return:
+ if (finfo.strtab != NULL)
+ _bfd_stringtab_free (finfo.strtab);
+ if (finfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (finfo.section_info[i].relocs != NULL)
+ free (finfo.section_info[i].relocs);
+ if (finfo.section_info[i].rel_hashes != NULL)
+ free (finfo.section_info[i].rel_hashes);
+ }
+ free (finfo.section_info);
+ }
+ if (finfo.internal_syms != NULL)
+ free (finfo.internal_syms);
+ if (finfo.sym_indices != NULL)
+ free (finfo.sym_indices);
+ if (finfo.outsyms != NULL)
+ free (finfo.outsyms);
+ if (finfo.linenos != NULL)
+ free (finfo.linenos);
+ if (finfo.contents != NULL)
+ free (finfo.contents);
+ if (finfo.external_relocs != NULL)
+ free (finfo.external_relocs);
+ if (external_relocs != NULL)
+ free (external_relocs);
+ return false;
+}
+
+/* Link an input file into the linker output file. This function
+ handles all the sections and relocations of the input file at once. */
+
+static boolean
+xcoff_link_input_bfd (finfo, input_bfd)
+ struct xcoff_final_link_info *finfo;
+ bfd *input_bfd;
+{
+ bfd *output_bfd;
+ const char *strings;
+ bfd_size_type syment_base;
+ unsigned int n_tmask;
+ unsigned int n_btshft;
+ boolean copy, hash;
+ bfd_size_type isymesz;
+ bfd_size_type osymesz;
+ bfd_size_type linesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+ struct xcoff_link_hash_entry **sym_hash;
+ struct internal_syment *isymp;
+ asection **csectpp;
+ unsigned long *debug_index;
+ long *indexp;
+ unsigned long output_index;
+ bfd_byte *outsym;
+ unsigned int incls;
+ asection *oline;
+ boolean keep_syms;
+ asection *o;
+
+ /* We can just skip DYNAMIC files, unless this is a static link. */
+ if ((input_bfd->flags & DYNAMIC) != 0
+ && ! finfo->info->static_link)
+ return true;
+
+ /* Move all the symbols to the output file. */
+
+ output_bfd = finfo->output_bfd;
+ strings = NULL;
+ syment_base = obj_raw_syment_count (output_bfd);
+ isymesz = bfd_coff_symesz (input_bfd);
+ osymesz = bfd_coff_symesz (output_bfd);
+ linesz = bfd_coff_linesz (input_bfd);
+ BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd));
+
+ n_tmask = coff_data (input_bfd)->local_n_tmask;
+ n_btshft = coff_data (input_bfd)->local_n_btshft;
+
+ /* Define macros so that ISFCN, et. al., macros work correctly. */
+#define N_TMASK n_tmask
+#define N_BTSHFT n_btshft
+
+ copy = false;
+ if (! finfo->info->keep_memory)
+ copy = true;
+ hash = true;
+ if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = false;
+
+ if (! _bfd_coff_get_external_symbols (input_bfd))
+ return false;
+
+ esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
+ esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
+ sym_hash = obj_xcoff_sym_hashes (input_bfd);
+ csectpp = xcoff_data (input_bfd)->csects;
+ debug_index = xcoff_data (input_bfd)->debug_indices;
+ isymp = finfo->internal_syms;
+ indexp = finfo->sym_indices;
+ output_index = syment_base;
+ outsym = finfo->outsyms;
+ incls = 0;
+ oline = NULL;
+
+ while (esym < esym_end)
+ {
+ struct internal_syment isym;
+ union internal_auxent aux;
+ int smtyp = 0;
+ boolean skip;
+ boolean require;
+ int add;
+
+ bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp);
+
+ /* If this is a C_EXT or C_HIDEXT symbol, we need the csect
+ information. */
+ if (isymp->n_sclass == C_EXT || isymp->n_sclass == C_HIDEXT)
+ {
+ BFD_ASSERT (isymp->n_numaux > 0);
+ bfd_coff_swap_aux_in (input_bfd,
+ (PTR) (esym + isymesz * isymp->n_numaux),
+ isymp->n_type, isymp->n_sclass,
+ isymp->n_numaux - 1, isymp->n_numaux,
+ (PTR) &aux);
+ smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp);
+ }
+
+ /* Make a copy of *isymp so that the relocate_section function
+ always sees the original values. This is more reliable than
+ always recomputing the symbol value even if we are stripping
+ the symbol. */
+ isym = *isymp;
+
+ /* If this symbol is in the .loader section, swap out the
+ .loader symbol information. If this is an external symbol
+ reference to a defined symbol, though, then wait until we get
+ to the definition. */
+ if (isym.n_sclass == C_EXT
+ && *sym_hash != NULL
+ && (*sym_hash)->ldsym != NULL
+ && (smtyp != XTY_ER
+ || (*sym_hash)->root.type == bfd_link_hash_undefined))
+ {
+ struct xcoff_link_hash_entry *h;
+ struct internal_ldsym *ldsym;
+
+ h = *sym_hash;
+ ldsym = h->ldsym;
+ if (isym.n_scnum > 0)
+ {
+ ldsym->l_scnum = (*csectpp)->output_section->target_index;
+ ldsym->l_value = (isym.n_value
+ + (*csectpp)->output_section->vma
+ + (*csectpp)->output_offset
+ - (*csectpp)->vma);
+ }
+ else
+ {
+ ldsym->l_scnum = isym.n_scnum;
+ ldsym->l_value = isym.n_value;
+ }
+
+ ldsym->l_smtype = smtyp;
+ if (((h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0)
+ || (h->flags & XCOFF_IMPORT) != 0)
+ ldsym->l_smtype |= L_IMPORT;
+ if (((h->flags & XCOFF_DEF_REGULAR) != 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0)
+ || (h->flags & XCOFF_EXPORT) != 0)
+ ldsym->l_smtype |= L_EXPORT;
+ if ((h->flags & XCOFF_ENTRY) != 0)
+ ldsym->l_smtype |= L_ENTRY;
+
+ ldsym->l_smclas = aux.x_csect.x_smclas;
+
+ if (ldsym->l_ifile == (bfd_size_type) -1)
+ ldsym->l_ifile = 0;
+ else if (ldsym->l_ifile == 0)
+ {
+ if ((ldsym->l_smtype & L_IMPORT) == 0)
+ ldsym->l_ifile = 0;
+ else
+ {
+ bfd *impbfd;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ impbfd = h->root.u.def.section->owner;
+ else if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ impbfd = h->root.u.undef.abfd;
+ else
+ impbfd = NULL;
+
+ if (impbfd == NULL)
+ ldsym->l_ifile = 0;
+ else
+ {
+ BFD_ASSERT (impbfd->xvec == finfo->output_bfd->xvec);
+ ldsym->l_ifile = xcoff_data (impbfd)->import_file_id;
+ }
+ }
+ }
+
+ ldsym->l_parm = 0;
+
+ BFD_ASSERT (h->ldindx >= 0);
+ BFD_ASSERT (LDSYMSZ == sizeof (struct external_ldsym));
+ xcoff_swap_ldsym_out (finfo->output_bfd, ldsym,
+ finfo->ldsym + h->ldindx - 3);
+ h->ldsym = NULL;
+
+ /* Fill in snentry now that we know the target_index. */
+ if ((h->flags & XCOFF_ENTRY) != 0
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ xcoff_data (output_bfd)->snentry =
+ h->root.u.def.section->output_section->target_index;
+ }
+
+ *indexp = -1;
+
+ skip = false;
+ require = false;
+ add = 1 + isym.n_numaux;
+
+ /* If we are skipping this csect, we want to skip this symbol. */
+ if (*csectpp == NULL)
+ skip = true;
+
+ /* If we garbage collected this csect, we want to skip this
+ symbol. */
+ if (! skip
+ && xcoff_hash_table (finfo->info)->gc
+ && ((*csectpp)->flags & SEC_MARK) == 0
+ && *csectpp != bfd_abs_section_ptr)
+ skip = true;
+
+ /* An XCOFF linker always skips C_STAT symbols. */
+ if (! skip
+ && isymp->n_sclass == C_STAT)
+ skip = true;
+
+ /* We skip all but the first TOC anchor. */
+ if (! skip
+ && isymp->n_sclass == C_HIDEXT
+ && aux.x_csect.x_smclas == XMC_TC0)
+ {
+ if (finfo->toc_symindx != -1)
+ skip = true;
+ else
+ {
+ bfd_vma tocval, tocend;
+
+ tocval = ((*csectpp)->output_section->vma
+ + (*csectpp)->output_offset
+ + isym.n_value
+ - (*csectpp)->vma);
+ /* We want to find out if tocval is a good value to use
+ as the TOC anchor--that is, whether we can access all
+ of the TOC using a 16 bit offset from tocval. This
+ test assumes that the TOC comes at the end of the
+ output section, as it does in the default linker
+ script. FIXME: This doesn't handle .tocbss sections
+ created from XMC_TD common symbols correctly. */
+
+ tocend = ((*csectpp)->output_section->vma
+ + (*csectpp)->output_section->_raw_size);
+
+ if (tocval + 0x10000 < tocend)
+ {
+ (*_bfd_error_handler)
+ (_("TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"),
+ (unsigned long) (tocend - tocval));
+ bfd_set_error (bfd_error_file_too_big);
+ return false;
+ }
+
+ if (tocval + 0x8000 < tocend)
+ {
+ bfd_vma tocadd;
+
+ tocadd = tocend - (tocval + 0x8000);
+ tocval += tocadd;
+ isym.n_value += tocadd;
+ }
+
+ finfo->toc_symindx = output_index;
+ xcoff_data (finfo->output_bfd)->toc = tocval;
+ xcoff_data (finfo->output_bfd)->sntoc =
+ (*csectpp)->output_section->target_index;
+ require = true;
+ }
+ }
+
+ /* If we are stripping all symbols, we want to skip this one. */
+ if (! skip
+ && finfo->info->strip == strip_all)
+ skip = true;
+
+ /* We can skip resolved external references. */
+ if (! skip
+ && isym.n_sclass == C_EXT
+ && smtyp == XTY_ER
+ && (*sym_hash)->root.type != bfd_link_hash_undefined)
+ skip = true;
+
+ /* We can skip common symbols if they got defined somewhere
+ else. */
+ if (! skip
+ && isym.n_sclass == C_EXT
+ && smtyp == XTY_CM
+ && ((*sym_hash)->root.type != bfd_link_hash_common
+ || (*sym_hash)->root.u.c.p->section != *csectpp)
+ && ((*sym_hash)->root.type != bfd_link_hash_defined
+ || (*sym_hash)->root.u.def.section != *csectpp))
+ skip = true;
+
+ /* Skip local symbols if we are discarding them. */
+ if (! skip
+ && finfo->info->discard == discard_all
+ && isym.n_sclass != C_EXT
+ && (isym.n_sclass != C_HIDEXT
+ || smtyp != XTY_SD))
+ skip = true;
+
+ /* If we stripping debugging symbols, and this is a debugging
+ symbol, then skip it. */
+ if (! skip
+ && finfo->info->strip == strip_debugger
+ && isym.n_scnum == N_DEBUG)
+ skip = true;
+
+ /* If some symbols are stripped based on the name, work out the
+ name and decide whether to skip this symbol. We don't handle
+ this correctly for symbols whose names are in the .debug
+ section; to get it right we would need a new bfd_strtab_hash
+ function to return the string given the index. */
+ if (! skip
+ && (finfo->info->strip == strip_some
+ || finfo->info->discard == discard_l)
+ && (debug_index == NULL || *debug_index == (unsigned long) -1))
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf);
+ if (name == NULL)
+ return false;
+
+ if ((finfo->info->strip == strip_some
+ && (bfd_hash_lookup (finfo->info->keep_hash, name, false,
+ false) == NULL))
+ || (finfo->info->discard == discard_l
+ && (isym.n_sclass != C_EXT
+ && (isym.n_sclass != C_HIDEXT
+ || smtyp != XTY_SD))
+ && bfd_is_local_label_name (input_bfd, name)))
+ skip = true;
+ }
+
+ /* We can not skip the first TOC anchor. */
+ if (skip
+ && require
+ && finfo->info->strip != strip_all)
+ skip = false;
+
+ /* We now know whether we are to skip this symbol or not. */
+ if (! skip)
+ {
+ /* Adjust the symbol in order to output it. */
+
+ if (isym._n._n_n._n_zeroes == 0
+ && isym._n._n_n._n_offset != 0)
+ {
+ /* This symbol has a long name. Enter it in the string
+ table we are building. If *debug_index != -1, the
+ name has already been entered in the .debug section. */
+ if (debug_index != NULL && *debug_index != (unsigned long) -1)
+ isym._n._n_n._n_offset = *debug_index;
+ else
+ {
+ const char *name;
+ bfd_size_type indx;
+
+ name = _bfd_coff_internal_syment_name (input_bfd, &isym,
+ (char *) NULL);
+ if (name == NULL)
+ return false;
+ indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+ }
+
+ if (isym.n_sclass != C_BSTAT
+ && isym.n_sclass != C_ESTAT
+ && isym.n_sclass != C_DECL
+ && isym.n_scnum > 0)
+ {
+ isym.n_scnum = (*csectpp)->output_section->target_index;
+ isym.n_value += ((*csectpp)->output_section->vma
+ + (*csectpp)->output_offset
+ - (*csectpp)->vma);
+ }
+
+ /* The value of a C_FILE symbol is the symbol index of the
+ next C_FILE symbol. The value of the last C_FILE symbol
+ is -1. We try to get this right, below, just before we
+ write the symbols out, but in the general case we may
+ have to write the symbol out twice. */
+ if (isym.n_sclass == C_FILE)
+ {
+ if (finfo->last_file_index != -1
+ && finfo->last_file.n_value != (long) output_index)
+ {
+ /* We must correct the value of the last C_FILE entry. */
+ finfo->last_file.n_value = output_index;
+ if ((bfd_size_type) finfo->last_file_index >= syment_base)
+ {
+ /* The last C_FILE symbol is in this input file. */
+ bfd_coff_swap_sym_out (output_bfd,
+ (PTR) &finfo->last_file,
+ (PTR) (finfo->outsyms
+ + ((finfo->last_file_index
+ - syment_base)
+ * osymesz)));
+ }
+ else
+ {
+ /* We have already written out the last C_FILE
+ symbol. We need to write it out again. We
+ borrow *outsym temporarily. */
+ bfd_coff_swap_sym_out (output_bfd,
+ (PTR) &finfo->last_file,
+ (PTR) outsym);
+ if (bfd_seek (output_bfd,
+ (obj_sym_filepos (output_bfd)
+ + finfo->last_file_index * osymesz),
+ SEEK_SET) != 0
+ || (bfd_write (outsym, osymesz, 1, output_bfd)
+ != osymesz))
+ return false;
+ }
+ }
+
+ finfo->last_file_index = output_index;
+ finfo->last_file = isym;
+ }
+
+ /* The value of a C_BINCL or C_EINCL symbol is a file offset
+ into the line numbers. We update the symbol values when
+ we handle the line numbers. */
+ if (isym.n_sclass == C_BINCL
+ || isym.n_sclass == C_EINCL)
+ {
+ isym.n_value = finfo->line_filepos;
+ ++incls;
+ }
+
+ /* Output the symbol. */
+
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
+
+ *indexp = output_index;
+
+ if (isym.n_sclass == C_EXT)
+ {
+ long indx;
+ struct xcoff_link_hash_entry *h;
+
+ indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd))
+ / isymesz);
+ h = obj_xcoff_sym_hashes (input_bfd)[indx];
+ BFD_ASSERT (h != NULL);
+ h->indx = output_index;
+ }
+
+ /* If this is a symbol in the TOC which we may have merged
+ (class XMC_TC), remember the symbol index of the TOC
+ symbol. */
+ if (isym.n_sclass == C_HIDEXT
+ && aux.x_csect.x_smclas == XMC_TC
+ && *sym_hash != NULL)
+ {
+ BFD_ASSERT (((*sym_hash)->flags & XCOFF_SET_TOC) == 0);
+ BFD_ASSERT ((*sym_hash)->toc_section != NULL);
+ (*sym_hash)->u.toc_indx = output_index;
+ }
+
+ output_index += add;
+ outsym += add * osymesz;
+ }
+
+ esym += add * isymesz;
+ isymp += add;
+ csectpp += add;
+ sym_hash += add;
+ if (debug_index != NULL)
+ debug_index += add;
+ ++indexp;
+ for (--add; add > 0; --add)
+ *indexp++ = -1;
+ }
+
+ /* Fix up the aux entries and the C_BSTAT symbols. This must be
+ done in a separate pass, because we don't know the correct symbol
+ indices until we have already decided which symbols we are going
+ to keep. */
+
+ esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
+ esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
+ isymp = finfo->internal_syms;
+ indexp = finfo->sym_indices;
+ csectpp = xcoff_data (input_bfd)->csects;
+ outsym = finfo->outsyms;
+ while (esym < esym_end)
+ {
+ int add;
+
+ add = 1 + isymp->n_numaux;
+
+ if (*indexp < 0)
+ esym += add * isymesz;
+ else
+ {
+ int i;
+
+ if (isymp->n_sclass == C_BSTAT)
+ {
+ struct internal_syment isym;
+ unsigned long indx;
+
+ /* The value of a C_BSTAT symbol is the symbol table
+ index of the containing csect. */
+ bfd_coff_swap_sym_in (output_bfd, (PTR) outsym, (PTR) &isym);
+ indx = isym.n_value;
+ if (indx < obj_raw_syment_count (input_bfd))
+ {
+ long symindx;
+
+ symindx = finfo->sym_indices[indx];
+ if (symindx < 0)
+ isym.n_value = 0;
+ else
+ isym.n_value = symindx;
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &isym,
+ (PTR) outsym);
+ }
+ }
+
+ esym += isymesz;
+ outsym += osymesz;
+
+ for (i = 0; i < isymp->n_numaux && esym < esym_end; i++)
+ {
+ union internal_auxent aux;
+
+ bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ (PTR) &aux);
+
+ if (isymp->n_sclass == C_FILE)
+ {
+ /* This is the file name (or some comment put in by
+ the compiler). If it is long, we must put it in
+ the string table. */
+ if (aux.x_file.x_n.x_zeroes == 0
+ && aux.x_file.x_n.x_offset != 0)
+ {
+ const char *filename;
+ bfd_size_type indx;
+
+ BFD_ASSERT (aux.x_file.x_n.x_offset
+ >= STRING_SIZE_SIZE);
+ if (strings == NULL)
+ {
+ strings = _bfd_coff_read_string_table (input_bfd);
+ if (strings == NULL)
+ return false;
+ }
+ filename = strings + aux.x_file.x_n.x_offset;
+ indx = _bfd_stringtab_add (finfo->strtab, filename,
+ hash, copy);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
+ }
+ }
+ else if ((isymp->n_sclass == C_EXT
+ || isymp->n_sclass == C_HIDEXT)
+ && i + 1 == isymp->n_numaux)
+ {
+ /* We don't support type checking. I don't know if
+ anybody does. */
+ aux.x_csect.x_parmhash = 0;
+ /* I don't think anybody uses these fields, but we'd
+ better clobber them just in case. */
+ aux.x_csect.x_stab = 0;
+ aux.x_csect.x_snstab = 0;
+ if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_LD)
+ {
+ unsigned long indx;
+
+ indx = aux.x_csect.x_scnlen.l;
+ if (indx < obj_raw_syment_count (input_bfd))
+ {
+ long symindx;
+
+ symindx = finfo->sym_indices[indx];
+ if (symindx < 0)
+ aux.x_sym.x_tagndx.l = 0;
+ else
+ aux.x_sym.x_tagndx.l = symindx;
+ }
+ }
+ }
+ else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
+ {
+ unsigned long indx;
+
+ if (ISFCN (isymp->n_type)
+ || ISTAG (isymp->n_sclass)
+ || isymp->n_sclass == C_BLOCK
+ || isymp->n_sclass == C_FCN)
+ {
+ indx = aux.x_sym.x_fcnary.x_fcn.x_endndx.l;
+ if (indx > 0
+ && indx < obj_raw_syment_count (input_bfd))
+ {
+ /* We look forward through the symbol for
+ the index of the next symbol we are going
+ to include. I don't know if this is
+ entirely right. */
+ while (finfo->sym_indices[indx] < 0
+ && indx < obj_raw_syment_count (input_bfd))
+ ++indx;
+ if (indx >= obj_raw_syment_count (input_bfd))
+ indx = output_index;
+ else
+ indx = finfo->sym_indices[indx];
+ aux.x_sym.x_fcnary.x_fcn.x_endndx.l = indx;
+ }
+ }
+
+ indx = aux.x_sym.x_tagndx.l;
+ if (indx > 0 && indx < obj_raw_syment_count (input_bfd))
+ {
+ long symindx;
+
+ symindx = finfo->sym_indices[indx];
+ if (symindx < 0)
+ aux.x_sym.x_tagndx.l = 0;
+ else
+ aux.x_sym.x_tagndx.l = symindx;
+ }
+ }
+
+ /* Copy over the line numbers, unless we are stripping
+ them. We do this on a symbol by symbol basis in
+ order to more easily handle garbage collection. */
+ if ((isymp->n_sclass == C_EXT
+ || isymp->n_sclass == C_HIDEXT)
+ && i == 0
+ && isymp->n_numaux > 1
+ && ISFCN (isymp->n_type)
+ && aux.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0)
+ {
+ if (finfo->info->strip != strip_none
+ && finfo->info->strip != strip_some)
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0;
+ else
+ {
+ asection *enclosing;
+ unsigned int enc_count;
+ bfd_size_type linoff;
+ struct internal_lineno lin;
+
+ o = *csectpp;
+ enclosing = xcoff_section_data (abfd, o)->enclosing;
+ enc_count = xcoff_section_data (abfd, o)->lineno_count;
+ if (oline != enclosing)
+ {
+ if (bfd_seek (input_bfd,
+ enclosing->line_filepos,
+ SEEK_SET) != 0
+ || (bfd_read (finfo->linenos, linesz,
+ enc_count, input_bfd)
+ != linesz * enc_count))
+ return false;
+ oline = enclosing;
+ }
+
+ linoff = (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr
+ - enclosing->line_filepos);
+
+ bfd_coff_swap_lineno_in (input_bfd,
+ (PTR) (finfo->linenos + linoff),
+ (PTR) &lin);
+ if (lin.l_lnno != 0
+ || ((bfd_size_type) lin.l_addr.l_symndx
+ != ((esym
+ - isymesz
+ - ((bfd_byte *)
+ obj_coff_external_syms (input_bfd)))
+ / isymesz)))
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0;
+ else
+ {
+ bfd_byte *linpend, *linp;
+ bfd_vma offset;
+ bfd_size_type count;
+
+ lin.l_addr.l_symndx = *indexp;
+ bfd_coff_swap_lineno_out (output_bfd, (PTR) &lin,
+ (PTR) (finfo->linenos
+ + linoff));
+
+ linpend = (finfo->linenos
+ + enc_count * linesz);
+ offset = (o->output_section->vma
+ + o->output_offset
+ - o->vma);
+ for (linp = finfo->linenos + linoff + linesz;
+ linp < linpend;
+ linp += linesz)
+ {
+ bfd_coff_swap_lineno_in (input_bfd, (PTR) linp,
+ (PTR) &lin);
+ if (lin.l_lnno == 0)
+ break;
+ lin.l_addr.l_paddr += offset;
+ bfd_coff_swap_lineno_out (output_bfd,
+ (PTR) &lin,
+ (PTR) linp);
+ }
+
+ count = (linp - (finfo->linenos + linoff)) / linesz;
+
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr =
+ (o->output_section->line_filepos
+ + o->output_section->lineno_count * linesz);
+
+ if (bfd_seek (output_bfd,
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr,
+ SEEK_SET) != 0
+ || (bfd_write (finfo->linenos + linoff,
+ linesz, count, output_bfd)
+ != linesz * count))
+ return false;
+
+ o->output_section->lineno_count += count;
+
+ if (incls > 0)
+ {
+ struct internal_syment *iisp, *iispend;
+ long *iindp;
+ bfd_byte *oos;
+ int iiadd;
+
+ /* Update any C_BINCL or C_EINCL symbols
+ that refer to a line number in the
+ range we just output. */
+ iisp = finfo->internal_syms;
+ iispend = (iisp
+ + obj_raw_syment_count (input_bfd));
+ iindp = finfo->sym_indices;
+ oos = finfo->outsyms;
+ while (iisp < iispend)
+ {
+ if (*iindp >= 0
+ && (iisp->n_sclass == C_BINCL
+ || iisp->n_sclass == C_EINCL)
+ && ((bfd_size_type) iisp->n_value
+ >= enclosing->line_filepos + linoff)
+ && ((bfd_size_type) iisp->n_value
+ < (enclosing->line_filepos
+ + enc_count * linesz)))
+ {
+ struct internal_syment iis;
+
+ bfd_coff_swap_sym_in (output_bfd,
+ (PTR) oos,
+ (PTR) &iis);
+ iis.n_value =
+ (iisp->n_value
+ - enclosing->line_filepos
+ - linoff
+ + aux.x_sym.x_fcnary.x_fcn.x_lnnoptr);
+ bfd_coff_swap_sym_out (output_bfd,
+ (PTR) &iis,
+ (PTR) oos);
+ --incls;
+ }
+
+ iiadd = 1 + iisp->n_numaux;
+ if (*iindp >= 0)
+ oos += iiadd * osymesz;
+ iisp += iiadd;
+ iindp += iiadd;
+ }
+ }
+ }
+ }
+ }
+
+ bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ (PTR) outsym);
+ outsym += osymesz;
+ esym += isymesz;
+ }
+ }
+
+ indexp += add;
+ isymp += add;
+ csectpp += add;
+ }
+
+ /* If we swapped out a C_FILE symbol, guess that the next C_FILE
+ symbol will be the first symbol in the next input file. In the
+ normal case, this will save us from writing out the C_FILE symbol
+ again. */
+ if (finfo->last_file_index != -1
+ && (bfd_size_type) finfo->last_file_index >= syment_base)
+ {
+ finfo->last_file.n_value = output_index;
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file,
+ (PTR) (finfo->outsyms
+ + ((finfo->last_file_index - syment_base)
+ * osymesz)));
+ }
+
+ /* Write the modified symbols to the output file. */
+ if (outsym > finfo->outsyms)
+ {
+ if (bfd_seek (output_bfd,
+ obj_sym_filepos (output_bfd) + syment_base * osymesz,
+ SEEK_SET) != 0
+ || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1,
+ output_bfd)
+ != (bfd_size_type) (outsym - finfo->outsyms)))
+ return false;
+
+ BFD_ASSERT ((obj_raw_syment_count (output_bfd)
+ + (outsym - finfo->outsyms) / osymesz)
+ == output_index);
+
+ obj_raw_syment_count (output_bfd) = output_index;
+ }
+
+ /* Don't let the linker relocation routines discard the symbols. */
+ keep_syms = obj_coff_keep_syms (input_bfd);
+ obj_coff_keep_syms (input_bfd) = true;
+
+ /* Relocate the contents of each section. */
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ bfd_byte *contents;
+
+ if (! o->linker_mark)
+ {
+ /* This section was omitted from the link. */
+ continue;
+ }
+
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || o->_raw_size == 0
+ || (o->flags & SEC_IN_MEMORY) != 0)
+ continue;
+
+ /* We have set filepos correctly for the sections we created to
+ represent csects, so bfd_get_section_contents should work. */
+ if (coff_section_data (input_bfd, o) != NULL
+ && coff_section_data (input_bfd, o)->contents != NULL)
+ contents = coff_section_data (input_bfd, o)->contents;
+ else
+ {
+ if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
+ (file_ptr) 0, o->_raw_size))
+ return false;
+ contents = finfo->contents;
+ }
+
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ int target_index;
+ struct internal_reloc *internal_relocs;
+ struct internal_reloc *irel;
+ bfd_vma offset;
+ struct internal_reloc *irelend;
+ struct xcoff_link_hash_entry **rel_hash;
+ long r_symndx;
+
+ /* Read in the relocs. */
+ target_index = o->output_section->target_index;
+ internal_relocs = (xcoff_read_internal_relocs
+ (input_bfd, o, false, finfo->external_relocs,
+ true,
+ (finfo->section_info[target_index].relocs
+ + o->output_section->reloc_count)));
+ if (internal_relocs == NULL)
+ return false;
+
+ /* Call processor specific code to relocate the section
+ contents. */
+ if (! bfd_coff_relocate_section (output_bfd, finfo->info,
+ input_bfd, o,
+ contents,
+ internal_relocs,
+ finfo->internal_syms,
+ xcoff_data (input_bfd)->csects))
+ return false;
+
+ offset = o->output_section->vma + o->output_offset - o->vma;
+ irel = internal_relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = (finfo->section_info[target_index].rel_hashes
+ + o->output_section->reloc_count);
+ for (; irel < irelend; irel++, rel_hash++)
+ {
+ struct xcoff_link_hash_entry *h = NULL;
+ struct internal_ldrel ldrel;
+ boolean quiet;
+
+ *rel_hash = NULL;
+
+ /* Adjust the reloc address and symbol index. */
+
+ irel->r_vaddr += offset;
+
+ r_symndx = irel->r_symndx;
+
+ if (r_symndx == -1)
+ h = NULL;
+ else
+ h = obj_xcoff_sym_hashes (input_bfd)[r_symndx];
+
+ if (r_symndx != -1 && finfo->info->strip != strip_all)
+ {
+ if (h != NULL
+ && h->smclas != XMC_TD
+ && (irel->r_type == R_TOC
+ || irel->r_type == R_GL
+ || irel->r_type == R_TCL
+ || irel->r_type == R_TRL
+ || irel->r_type == R_TRLA))
+ {
+ /* This is a TOC relative reloc with a symbol
+ attached. The symbol should be the one which
+ this reloc is for. We want to make this
+ reloc against the TOC address of the symbol,
+ not the symbol itself. */
+ BFD_ASSERT (h->toc_section != NULL);
+ BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
+ if (h->u.toc_indx != -1)
+ irel->r_symndx = h->u.toc_indx;
+ else
+ {
+ struct xcoff_toc_rel_hash *n;
+ struct xcoff_link_section_info *si;
+
+ n = ((struct xcoff_toc_rel_hash *)
+ bfd_alloc (finfo->output_bfd,
+ sizeof (struct xcoff_toc_rel_hash)));
+ if (n == NULL)
+ return false;
+ si = finfo->section_info + target_index;
+ n->next = si->toc_rel_hashes;
+ n->h = h;
+ n->rel = irel;
+ si->toc_rel_hashes = n;
+ }
+ }
+ else if (h != NULL)
+ {
+ /* This is a global symbol. */
+ if (h->indx >= 0)
+ irel->r_symndx = h->indx;
+ else
+ {
+ /* This symbol is being written at the end
+ of the file, and we do not yet know the
+ symbol index. We save the pointer to the
+ hash table entry in the rel_hash list.
+ We set the indx field to -2 to indicate
+ that this symbol must not be stripped. */
+ *rel_hash = h;
+ h->indx = -2;
+ }
+ }
+ else
+ {
+ long indx;
+
+ indx = finfo->sym_indices[r_symndx];
+
+ if (indx == -1)
+ {
+ struct internal_syment *is;
+
+ /* Relocations against a TC0 TOC anchor are
+ automatically transformed to be against
+ the TOC anchor in the output file. */
+ is = finfo->internal_syms + r_symndx;
+ if (is->n_sclass == C_HIDEXT
+ && is->n_numaux > 0)
+ {
+ PTR auxptr;
+ union internal_auxent aux;
+
+ auxptr = ((PTR)
+ (((bfd_byte *)
+ obj_coff_external_syms (input_bfd))
+ + ((r_symndx + is->n_numaux)
+ * isymesz)));
+ bfd_coff_swap_aux_in (input_bfd, auxptr,
+ is->n_type, is->n_sclass,
+ is->n_numaux - 1,
+ is->n_numaux,
+ (PTR) &aux);
+ if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_SD
+ && aux.x_csect.x_smclas == XMC_TC0)
+ indx = finfo->toc_symindx;
+ }
+ }
+
+ if (indx != -1)
+ irel->r_symndx = indx;
+ else
+ {
+ struct internal_syment *is;
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ /* This reloc is against a symbol we are
+ stripping. It would be possible to handle
+ this case, but I don't think it's worth it. */
+ is = finfo->internal_syms + r_symndx;
+
+ name = (_bfd_coff_internal_syment_name
+ (input_bfd, is, buf));
+ if (name == NULL)
+ return false;
+
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, name, input_bfd, o,
+ irel->r_vaddr)))
+ return false;
+ }
+ }
+ }
+
+ quiet = false;
+ switch (irel->r_type)
+ {
+ default:
+ if (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_common)
+ break;
+ /* Fall through. */
+ case R_POS:
+ case R_NEG:
+ case R_RL:
+ case R_RLA:
+ /* This reloc needs to be copied into the .loader
+ section. */
+ ldrel.l_vaddr = irel->r_vaddr;
+ if (r_symndx == -1)
+ ldrel.l_symndx = -1;
+ else if (h == NULL
+ || (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_common))
+ {
+ asection *sec;
+
+ if (h == NULL)
+ sec = xcoff_data (input_bfd)->csects[r_symndx];
+ else if (h->root.type == bfd_link_hash_common)
+ sec = h->root.u.c.p->section;
+ else
+ sec = h->root.u.def.section;
+ sec = sec->output_section;
+
+ if (strcmp (sec->name, ".text") == 0)
+ ldrel.l_symndx = 0;
+ else if (strcmp (sec->name, ".data") == 0)
+ ldrel.l_symndx = 1;
+ else if (strcmp (sec->name, ".bss") == 0)
+ ldrel.l_symndx = 2;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: loader reloc in unrecognized section `%s'"),
+ bfd_get_filename (input_bfd),
+ sec->name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ }
+ else
+ {
+ if (! finfo->info->relocateable
+ && (h->flags & XCOFF_DEF_DYNAMIC) == 0
+ && (h->flags & XCOFF_IMPORT) == 0)
+ {
+ /* We already called the undefined_symbol
+ callback for this relocation, in
+ _bfd_ppc_xcoff_relocate_section. Don't
+ issue any more warnings. */
+ quiet = true;
+ }
+ if (h->ldindx < 0 && ! quiet)
+ {
+ (*_bfd_error_handler)
+ (_("%s: `%s' in loader reloc but not loader sym"),
+ bfd_get_filename (input_bfd),
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ ldrel.l_symndx = h->ldindx;
+ }
+ ldrel.l_rtype = (irel->r_size << 8) | irel->r_type;
+ ldrel.l_rsecnm = o->output_section->target_index;
+ if (xcoff_hash_table (finfo->info)->textro
+ && strcmp (o->output_section->name, ".text") == 0
+ && ! quiet)
+ {
+ (*_bfd_error_handler)
+ (_("%s: loader reloc in read-only section %s"),
+ bfd_get_filename (input_bfd),
+ bfd_get_section_name (finfo->output_bfd,
+ o->output_section));
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
+ xcoff_swap_ldrel_out (output_bfd, &ldrel,
+ finfo->ldrel);
+ BFD_ASSERT (sizeof (struct external_ldrel) == LDRELSZ);
+ ++finfo->ldrel;
+ break;
+
+ case R_TOC:
+ case R_GL:
+ case R_TCL:
+ case R_TRL:
+ case R_TRLA:
+ /* We should never need a .loader reloc for a TOC
+ relative reloc. */
+ break;
+ }
+ }
+
+ o->output_section->reloc_count += o->reloc_count;
+ }
+
+ /* Write out the modified section contents. */
+ if (! bfd_set_section_contents (output_bfd, o->output_section,
+ contents, o->output_offset,
+ (o->_cooked_size != 0
+ ? o->_cooked_size
+ : o->_raw_size)))
+ return false;
+ }
+
+ obj_coff_keep_syms (input_bfd) = keep_syms;
+
+ if (! finfo->info->keep_memory)
+ {
+ if (! _bfd_coff_free_symbols (input_bfd))
+ return false;
+ }
+
+ return true;
+}
+
+#undef N_TMASK
+#undef N_BTSHFT
+
+/* Write out a non-XCOFF global symbol. */
+
+static boolean
+xcoff_write_global_symbol (h, p)
+ struct xcoff_link_hash_entry *h;
+ PTR p;
+{
+ struct xcoff_final_link_info *finfo = (struct xcoff_final_link_info *) p;
+ bfd *output_bfd;
+ bfd_byte *outsym;
+ struct internal_syment isym;
+ union internal_auxent aux;
+
+ output_bfd = finfo->output_bfd;
+ outsym = finfo->outsyms;
+
+ /* If this symbol was garbage collected, just skip it. */
+ if (xcoff_hash_table (finfo->info)->gc
+ && (h->flags & XCOFF_MARK) == 0)
+ return true;
+
+ /* If we need a .loader section entry, write it out. */
+ if (h->ldsym != NULL)
+ {
+ struct internal_ldsym *ldsym;
+ bfd *impbfd;
+
+ ldsym = h->ldsym;
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ {
+ ldsym->l_value = 0;
+ ldsym->l_scnum = N_UNDEF;
+ ldsym->l_smtype = XTY_ER;
+ impbfd = h->root.u.undef.abfd;
+ }
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ ldsym->l_value = (sec->output_section->vma
+ + sec->output_offset
+ + h->root.u.def.value);
+ ldsym->l_scnum = sec->output_section->target_index;
+ ldsym->l_smtype = XTY_SD;
+ impbfd = sec->owner;
+ }
+ else
+ abort ();
+
+ if (((h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0)
+ || (h->flags & XCOFF_IMPORT) != 0)
+ ldsym->l_smtype |= L_IMPORT;
+ if (((h->flags & XCOFF_DEF_REGULAR) != 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0)
+ || (h->flags & XCOFF_EXPORT) != 0)
+ ldsym->l_smtype |= L_EXPORT;
+ if ((h->flags & XCOFF_ENTRY) != 0)
+ ldsym->l_smtype |= L_ENTRY;
+
+ ldsym->l_smclas = h->smclas;
+
+ if (ldsym->l_ifile == (bfd_size_type) -1)
+ ldsym->l_ifile = 0;
+ else if (ldsym->l_ifile == 0)
+ {
+ if ((ldsym->l_smtype & L_IMPORT) == 0)
+ ldsym->l_ifile = 0;
+ else if (impbfd == NULL)
+ ldsym->l_ifile = 0;
+ else
+ {
+ BFD_ASSERT (impbfd->xvec == output_bfd->xvec);
+ ldsym->l_ifile = xcoff_data (impbfd)->import_file_id;
+ }
+ }
+
+ ldsym->l_parm = 0;
+
+ BFD_ASSERT (h->ldindx >= 0);
+ BFD_ASSERT (LDSYMSZ == sizeof (struct external_ldsym));
+ xcoff_swap_ldsym_out (output_bfd, ldsym, finfo->ldsym + h->ldindx - 3);
+ h->ldsym = NULL;
+ }
+
+ /* If this symbol needs global linkage code, write it out. */
+ if (h->root.type == bfd_link_hash_defined
+ && (h->root.u.def.section
+ == xcoff_hash_table (finfo->info)->linkage_section))
+ {
+ bfd_byte *p;
+ bfd_vma tocoff;
+ unsigned int i;
+
+ p = h->root.u.def.section->contents + h->root.u.def.value;
+
+ /* The first instruction in the global linkage code loads a
+ specific TOC element. */
+ tocoff = (h->descriptor->toc_section->output_section->vma
+ + h->descriptor->toc_section->output_offset
+ - xcoff_data (output_bfd)->toc);
+ if ((h->descriptor->flags & XCOFF_SET_TOC) != 0)
+ tocoff += h->descriptor->u.toc_offset;
+ bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | (tocoff & 0xffff), p);
+ for (i = 0, p += 4;
+ i < sizeof xcoff_glink_code / sizeof xcoff_glink_code[0];
+ i++, p += 4)
+ bfd_put_32 (output_bfd, xcoff_glink_code[i], p);
+ }
+
+ /* If we created a TOC entry for this symbol, write out the required
+ relocs. */
+ if ((h->flags & XCOFF_SET_TOC) != 0)
+ {
+ asection *tocsec;
+ asection *osec;
+ int oindx;
+ struct internal_reloc *irel;
+ struct internal_ldrel ldrel;
+ struct internal_syment irsym;
+ union internal_auxent iraux;
+
+ tocsec = h->toc_section;
+ osec = tocsec->output_section;
+ oindx = osec->target_index;
+ irel = finfo->section_info[oindx].relocs + osec->reloc_count;
+ irel->r_vaddr = (osec->vma
+ + tocsec->output_offset
+ + h->u.toc_offset);
+ if (h->indx >= 0)
+ irel->r_symndx = h->indx;
+ else
+ {
+ h->indx = -2;
+ irel->r_symndx = obj_raw_syment_count (output_bfd);
+ }
+ irel->r_type = R_POS;
+ irel->r_size = 31;
+ finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ ++osec->reloc_count;
+
+ BFD_ASSERT (h->ldindx >= 0);
+ ldrel.l_vaddr = irel->r_vaddr;
+ ldrel.l_symndx = h->ldindx;
+ ldrel.l_rtype = (31 << 8) | R_POS;
+ ldrel.l_rsecnm = oindx;
+ xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
+ ++finfo->ldrel;
+
+ /* We need to emit a symbol to define a csect which holds the
+ reloc. */
+ if (finfo->info->strip != strip_all)
+ {
+ if (strlen (h->root.root.string) <= SYMNMLEN)
+ strncpy (irsym._n._n_name, h->root.root.string, SYMNMLEN);
+ else
+ {
+ boolean hash;
+ bfd_size_type indx;
+
+ hash = true;
+ if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = false;
+ indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string,
+ hash, false);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ irsym._n._n_n._n_zeroes = 0;
+ irsym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+
+ irsym.n_value = irel->r_vaddr;
+ irsym.n_scnum = osec->target_index;
+ irsym.n_sclass = C_HIDEXT;
+ irsym.n_type = T_NULL;
+ irsym.n_numaux = 1;
+
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &irsym, (PTR) outsym);
+ outsym += bfd_coff_symesz (output_bfd);
+
+ memset (&iraux, 0, sizeof iraux);
+ iraux.x_csect.x_smtyp = XTY_SD;
+ iraux.x_csect.x_scnlen.l = 4;
+ iraux.x_csect.x_smclas = XMC_TC;
+
+ bfd_coff_swap_aux_out (output_bfd, (PTR) &iraux, T_NULL, C_HIDEXT,
+ 0, 1, (PTR) outsym);
+ outsym += bfd_coff_auxesz (output_bfd);
+
+ if (h->indx >= 0)
+ {
+ /* We aren't going to write out the symbols below, so we
+ need to write them out now. */
+ if (bfd_seek (output_bfd,
+ (obj_sym_filepos (output_bfd)
+ + (obj_raw_syment_count (output_bfd)
+ * bfd_coff_symesz (output_bfd))),
+ SEEK_SET) != 0
+ || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1,
+ output_bfd)
+ != (bfd_size_type) (outsym - finfo->outsyms)))
+ return false;
+ obj_raw_syment_count (output_bfd) +=
+ (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd);
+
+ outsym = finfo->outsyms;
+ }
+ }
+ }
+
+ /* If this symbol is a specially defined function descriptor, write
+ it out. The first word is the address of the function code
+ itself, the second word is the address of the TOC, and the third
+ word is zero. */
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0
+ && h->root.type == bfd_link_hash_defined
+ && (h->root.u.def.section
+ == xcoff_hash_table (finfo->info)->descriptor_section))
+ {
+ asection *sec;
+ asection *osec;
+ int oindx;
+ bfd_byte *p;
+ struct xcoff_link_hash_entry *hentry;
+ asection *esec;
+ struct internal_reloc *irel;
+ struct internal_ldrel ldrel;
+ asection *tsec;
+
+ sec = h->root.u.def.section;
+ osec = sec->output_section;
+ oindx = osec->target_index;
+ p = sec->contents + h->root.u.def.value;
+
+ hentry = h->descriptor;
+ BFD_ASSERT (hentry != NULL
+ && (hentry->root.type == bfd_link_hash_defined
+ || hentry->root.type == bfd_link_hash_defweak));
+ esec = hentry->root.u.def.section;
+ bfd_put_32 (output_bfd,
+ (esec->output_section->vma
+ + esec->output_offset
+ + hentry->root.u.def.value),
+ p);
+
+ irel = finfo->section_info[oindx].relocs + osec->reloc_count;
+ irel->r_vaddr = (osec->vma
+ + sec->output_offset
+ + h->root.u.def.value);
+ irel->r_symndx = esec->output_section->target_index;
+ irel->r_type = R_POS;
+ irel->r_size = 31;
+ finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ ++osec->reloc_count;
+
+ ldrel.l_vaddr = irel->r_vaddr;
+ if (strcmp (esec->output_section->name, ".text") == 0)
+ ldrel.l_symndx = 0;
+ else if (strcmp (esec->output_section->name, ".data") == 0)
+ ldrel.l_symndx = 1;
+ else if (strcmp (esec->output_section->name, ".bss") == 0)
+ ldrel.l_symndx = 2;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: loader reloc in unrecognized section `%s'"),
+ bfd_get_filename (output_bfd),
+ esec->output_section->name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ ldrel.l_rtype = (31 << 8) | R_POS;
+ ldrel.l_rsecnm = oindx;
+ xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
+ ++finfo->ldrel;
+
+ bfd_put_32 (output_bfd, xcoff_data (output_bfd)->toc, p + 4);
+
+ tsec = coff_section_from_bfd_index (output_bfd,
+ xcoff_data (output_bfd)->sntoc);
+
+ ++irel;
+ irel->r_vaddr = (osec->vma
+ + sec->output_offset
+ + h->root.u.def.value
+ + 4);
+ irel->r_symndx = tsec->output_section->target_index;
+ irel->r_type = R_POS;
+ irel->r_size = 31;
+ finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ ++osec->reloc_count;
+
+ ldrel.l_vaddr = irel->r_vaddr;
+ if (strcmp (tsec->output_section->name, ".text") == 0)
+ ldrel.l_symndx = 0;
+ else if (strcmp (tsec->output_section->name, ".data") == 0)
+ ldrel.l_symndx = 1;
+ else if (strcmp (tsec->output_section->name, ".bss") == 0)
+ ldrel.l_symndx = 2;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: loader reloc in unrecognized section `%s'"),
+ bfd_get_filename (output_bfd),
+ tsec->output_section->name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ ldrel.l_rtype = (31 << 8) | R_POS;
+ ldrel.l_rsecnm = oindx;
+ xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
+ ++finfo->ldrel;
+ }
+
+ if (h->indx >= 0 || finfo->info->strip == strip_all)
+ {
+ BFD_ASSERT (outsym == finfo->outsyms);
+ return true;
+ }
+
+ if (h->indx != -2
+ && (finfo->info->strip == strip_all
+ || (finfo->info->strip == strip_some
+ && (bfd_hash_lookup (finfo->info->keep_hash,
+ h->root.root.string, false, false)
+ == NULL))))
+ {
+ BFD_ASSERT (outsym == finfo->outsyms);
+ return true;
+ }
+
+ if (h->indx != -2
+ && (h->flags & (XCOFF_REF_REGULAR | XCOFF_DEF_REGULAR)) == 0)
+ {
+ BFD_ASSERT (outsym == finfo->outsyms);
+ return true;
+ }
+
+ memset (&aux, 0, sizeof aux);
+
+ h->indx = obj_raw_syment_count (output_bfd);
+
+ if (strlen (h->root.root.string) <= SYMNMLEN)
+ strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN);
+ else
+ {
+ boolean hash;
+ bfd_size_type indx;
+
+ hash = true;
+ if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = false;
+ indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash,
+ false);
+ if (indx == (bfd_size_type) -1)
+ return false;
+ isym._n._n_n._n_zeroes = 0;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ {
+ isym.n_value = 0;
+ isym.n_scnum = N_UNDEF;
+ isym.n_sclass = C_EXT;
+ aux.x_csect.x_smtyp = XTY_ER;
+ }
+ else if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->smclas == XMC_XO)
+ {
+ BFD_ASSERT (bfd_is_abs_section (h->root.u.def.section));
+ isym.n_value = h->root.u.def.value;
+ isym.n_scnum = N_UNDEF;
+ isym.n_sclass = C_EXT;
+ aux.x_csect.x_smtyp = XTY_ER;
+ }
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ struct xcoff_link_size_list *l;
+
+ isym.n_value = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+ isym.n_scnum = h->root.u.def.section->output_section->target_index;
+ isym.n_sclass = C_HIDEXT;
+ aux.x_csect.x_smtyp = XTY_SD;
+
+ if ((h->flags & XCOFF_HAS_SIZE) != 0)
+ {
+ for (l = xcoff_hash_table (finfo->info)->size_list;
+ l != NULL;
+ l = l->next)
+ {
+ if (l->h == h)
+ {
+ aux.x_csect.x_scnlen.l = l->size;
+ break;
+ }
+ }
+ }
+ }
+ else if (h->root.type == bfd_link_hash_common)
+ {
+ isym.n_value = (h->root.u.c.p->section->output_section->vma
+ + h->root.u.c.p->section->output_offset);
+ isym.n_scnum = h->root.u.c.p->section->output_section->target_index;
+ isym.n_sclass = C_EXT;
+ aux.x_csect.x_smtyp = XTY_CM;
+ aux.x_csect.x_scnlen.l = h->root.u.c.size;
+ }
+ else
+ abort ();
+
+ isym.n_type = T_NULL;
+ isym.n_numaux = 1;
+
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
+ outsym += bfd_coff_symesz (output_bfd);
+
+ aux.x_csect.x_smclas = h->smclas;
+
+ bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, isym.n_sclass, 0, 1,
+ (PTR) outsym);
+ outsym += bfd_coff_auxesz (output_bfd);
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->smclas != XMC_XO)
+ {
+ /* We just output an SD symbol. Now output an LD symbol. */
+
+ h->indx += 2;
+
+ isym.n_sclass = C_EXT;
+ bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym);
+ outsym += bfd_coff_symesz (output_bfd);
+
+ aux.x_csect.x_smtyp = XTY_LD;
+ aux.x_csect.x_scnlen.l = obj_raw_syment_count (output_bfd);
+
+ bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, C_EXT, 0, 1,
+ (PTR) outsym);
+ outsym += bfd_coff_auxesz (output_bfd);
+ }
+
+ if (bfd_seek (output_bfd,
+ (obj_sym_filepos (output_bfd)
+ + (obj_raw_syment_count (output_bfd)
+ * bfd_coff_symesz (output_bfd))),
+ SEEK_SET) != 0
+ || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, output_bfd)
+ != (bfd_size_type) (outsym - finfo->outsyms)))
+ return false;
+ obj_raw_syment_count (output_bfd) +=
+ (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd);
+
+ return true;
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+static boolean
+xcoff_reloc_link_order (output_bfd, finfo, output_section, link_order)
+ bfd *output_bfd;
+ struct xcoff_final_link_info *finfo;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+{
+ reloc_howto_type *howto;
+ struct xcoff_link_hash_entry *h;
+ asection *hsec;
+ bfd_vma hval;
+ bfd_vma addend;
+ struct internal_reloc *irel;
+ struct xcoff_link_hash_entry **rel_hash_ptr;
+ struct internal_ldrel ldrel;
+
+ if (link_order->type == bfd_section_reloc_link_order)
+ {
+ /* We need to somehow locate a symbol in the right section. The
+ symbol must either have a value of zero, or we must adjust
+ the addend by the value of the symbol. FIXME: Write this
+ when we need it. The old linker couldn't handle this anyhow. */
+ abort ();
+ }
+
+ howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ h = ((struct xcoff_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (output_bfd, finfo->info,
+ link_order->u.reloc.p->u.name,
+ false, false, true));
+ if (h == NULL)
+ {
+ if (! ((*finfo->info->callbacks->unattached_reloc)
+ (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ return true;
+ }
+
+ if (h->root.type == bfd_link_hash_common)
+ {
+ hsec = h->root.u.c.p->section;
+ hval = 0;
+ }
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ hsec = h->root.u.def.section;
+ hval = h->root.u.def.value;
+ }
+ else
+ {
+ hsec = NULL;
+ hval = 0;
+ }
+
+ addend = link_order->u.reloc.p->addend;
+ if (hsec != NULL)
+ addend += (hsec->output_section->vma
+ + hsec->output_offset
+ + hval);
+
+ if (addend != 0)
+ {
+ bfd_size_type size;
+ bfd_byte *buf;
+ bfd_reloc_status_type rstat;
+ boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL)
+ return false;
+
+ rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
+ switch (rstat)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*finfo->info->callbacks->reloc_overflow)
+ (finfo->info, link_order->u.reloc.p->u.name,
+ howto->name, addend, (bfd *) NULL, (asection *) NULL,
+ (bfd_vma) 0)))
+ {
+ free (buf);
+ return false;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
+ (file_ptr) link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return false;
+ }
+
+ /* Store the reloc information in the right place. It will get
+ swapped and written out at the end of the final_link routine. */
+
+ irel = (finfo->section_info[output_section->target_index].relocs
+ + output_section->reloc_count);
+ rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
+ + output_section->reloc_count);
+
+ memset (irel, 0, sizeof (struct internal_reloc));
+ *rel_hash_ptr = NULL;
+
+ irel->r_vaddr = output_section->vma + link_order->offset;
+
+ if (h->indx >= 0)
+ irel->r_symndx = h->indx;
+ else
+ {
+ /* Set the index to -2 to force this symbol to get written out. */
+ h->indx = -2;
+ *rel_hash_ptr = h;
+ irel->r_symndx = 0;
+ }
+
+ irel->r_type = howto->type;
+ irel->r_size = howto->bitsize - 1;
+ if (howto->complain_on_overflow == complain_overflow_signed)
+ irel->r_size |= 0x80;
+
+ ++output_section->reloc_count;
+
+ /* Now output the reloc to the .loader section. */
+
+ ldrel.l_vaddr = irel->r_vaddr;
+
+ if (hsec != NULL)
+ {
+ const char *secname;
+
+ secname = hsec->output_section->name;
+
+ if (strcmp (secname, ".text") == 0)
+ ldrel.l_symndx = 0;
+ else if (strcmp (secname, ".data") == 0)
+ ldrel.l_symndx = 1;
+ else if (strcmp (secname, ".bss") == 0)
+ ldrel.l_symndx = 2;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: loader reloc in unrecognized section `%s'"),
+ bfd_get_filename (output_bfd), secname);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return false;
+ }
+ }
+ else
+ {
+ if (h->ldindx < 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: `%s' in loader reloc but not loader sym"),
+ bfd_get_filename (output_bfd),
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ ldrel.l_symndx = h->ldindx;
+ }
+
+ ldrel.l_rtype = (irel->r_size << 8) | irel->r_type;
+ ldrel.l_rsecnm = output_section->target_index;
+ xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
+ ++finfo->ldrel;
+
+ return true;
+}
+
+/* Sort relocs by VMA. This is called via qsort. */
+
+static int
+xcoff_sort_relocs (p1, p2)
+ const PTR p1;
+ const PTR p2;
+{
+ const struct internal_reloc *r1 = (const struct internal_reloc *) p1;
+ const struct internal_reloc *r2 = (const struct internal_reloc *) p2;
+
+ if (r1->r_vaddr > r2->r_vaddr)
+ return 1;
+ else if (r1->r_vaddr < r2->r_vaddr)
+ return -1;
+ else
+ return 0;
+}
+
+/* This is the relocation function for the RS/6000/POWER/PowerPC.
+ This is currently the only processor which uses XCOFF; I hope that
+ will never change. */
+
+boolean
+_bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents, relocs, syms,
+ sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ struct internal_reloc *rel;
+ struct internal_reloc *relend;
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ long symndx;
+ struct xcoff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma addend;
+ bfd_vma val;
+ struct reloc_howto_struct howto;
+ bfd_reloc_status_type rstat;
+
+ /* Relocation type R_REF is a special relocation type which is
+ merely used to prevent garbage collection from occurring for
+ the csect including the symbol which it references. */
+ if (rel->r_type == R_REF)
+ continue;
+
+ symndx = rel->r_symndx;
+
+ if (symndx == -1)
+ {
+ h = NULL;
+ sym = NULL;
+ addend = 0;
+ }
+ else
+ {
+ h = obj_xcoff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ addend = - sym->n_value;
+ }
+
+ /* We build the howto information on the fly. */
+
+ howto.type = rel->r_type;
+ howto.rightshift = 0;
+ howto.size = 2;
+ howto.bitsize = (rel->r_size & 0x1f) + 1;
+ howto.pc_relative = false;
+ howto.bitpos = 0;
+ if ((rel->r_size & 0x80) != 0)
+ howto.complain_on_overflow = complain_overflow_signed;
+ else
+ howto.complain_on_overflow = complain_overflow_bitfield;
+ howto.special_function = NULL;
+ howto.name = "internal";
+ howto.partial_inplace = true;
+ if (howto.bitsize == 32)
+ howto.src_mask = howto.dst_mask = 0xffffffff;
+ else
+ {
+ howto.src_mask = howto.dst_mask = (1 << howto.bitsize) - 1;
+ if (howto.bitsize == 16)
+ howto.size = 1;
+ }
+ howto.pcrel_offset = false;
+
+ val = 0;
+
+ if (h == NULL)
+ {
+ asection *sec;
+
+ if (symndx == -1)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = sections[symndx];
+ /* Hack to make sure we use the right TOC anchor value
+ if this reloc is against the TOC anchor. */
+ if (sec->name[3] == '0'
+ && strcmp (sec->name, ".tc0") == 0)
+ val = xcoff_data (output_bfd)->toc;
+ else
+ val = (sec->output_section->vma
+ + sec->output_offset
+ + sym->n_value
+ - sec->vma);
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section;
+ val = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_common)
+ {
+ asection *sec;
+
+ sec = h->root.u.c.p->section;
+ val = (sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if ((h->flags & XCOFF_DEF_DYNAMIC) != 0
+ || (h->flags & XCOFF_IMPORT) != 0)
+ {
+ /* Every symbol in a shared object is defined somewhere. */
+ val = 0;
+ }
+ else if (! info->relocateable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return false;
+
+ /* Don't try to process the reloc. It can't help, and
+ it may generate another error. */
+ continue;
+ }
+ }
+
+ /* I took the relocation type definitions from two documents:
+ the PowerPC AIX Version 4 Application Binary Interface, First
+ Edition (April 1992), and the PowerOpen ABI, Big-Endian
+ 32-Bit Hardware Implementation (June 30, 1994). Differences
+ between the documents are noted below. */
+
+ switch (rel->r_type)
+ {
+ case R_RTB:
+ case R_RRTBI:
+ case R_RRTBA:
+ /* These relocs are defined by the PowerPC ABI to be
+ relative branches which use half of the difference
+ between the symbol and the program counter. I can't
+ quite figure out when this is useful. These relocs are
+ not defined by the PowerOpen ABI. */
+ default:
+ (*_bfd_error_handler)
+ (_("%s: unsupported relocation type 0x%02x"),
+ bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ case R_POS:
+ /* Simple positive relocation. */
+ break;
+ case R_NEG:
+ /* Simple negative relocation. */
+ val = - val;
+ break;
+ case R_REL:
+ /* Simple PC relative relocation. */
+ howto.pc_relative = true;
+ break;
+ case R_TOC:
+ /* TOC relative relocation. The value in the instruction in
+ the input file is the offset from the input file TOC to
+ the desired location. We want the offset from the final
+ TOC to the desired location. We have:
+ isym = iTOC + in
+ iinsn = in + o
+ osym = oTOC + on
+ oinsn = on + o
+ so we must change insn by on - in.
+ */
+ case R_GL:
+ /* Global linkage relocation. The value of this relocation
+ is the address of the entry in the TOC section. */
+ case R_TCL:
+ /* Local object TOC address. I can't figure out the
+ difference between this and case R_GL. */
+ case R_TRL:
+ /* TOC relative relocation. A TOC relative load instruction
+ which may be changed to a load address instruction.
+ FIXME: We don't currently implement this optimization. */
+ case R_TRLA:
+ /* TOC relative relocation. This is a TOC relative load
+ address instruction which may be changed to a load
+ instruction. FIXME: I don't know if this is the correct
+ implementation. */
+ if (h != NULL && h->smclas != XMC_TD)
+ {
+ if (h->toc_section == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
+ bfd_get_filename (input_bfd), rel->r_vaddr,
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
+ val = (h->toc_section->output_section->vma
+ + h->toc_section->output_offset);
+ }
+
+ val = ((val - xcoff_data (output_bfd)->toc)
+ - (sym->n_value - xcoff_data (input_bfd)->toc));
+ addend = 0;
+ break;
+ case R_BA:
+ /* Absolute branch. We don't want to mess with the lower
+ two bits of the instruction. */
+ case R_CAI:
+ /* The PowerPC ABI defines this as an absolute call which
+ may be modified to become a relative call. The PowerOpen
+ ABI does not define this relocation type. */
+ case R_RBA:
+ /* Absolute branch which may be modified to become a
+ relative branch. */
+ case R_RBAC:
+ /* The PowerPC ABI defines this as an absolute branch to a
+ fixed address which may be modified to an absolute branch
+ to a symbol. The PowerOpen ABI does not define this
+ relocation type. */
+ case R_RBRC:
+ /* The PowerPC ABI defines this as an absolute branch to a
+ fixed address which may be modified to a relative branch.
+ The PowerOpen ABI does not define this relocation type. */
+ howto.src_mask &= ~3;
+ howto.dst_mask = howto.src_mask;
+ break;
+ case R_BR:
+ /* Relative branch. We don't want to mess with the lower
+ two bits of the instruction. */
+ case R_CREL:
+ /* The PowerPC ABI defines this as a relative call which may
+ be modified to become an absolute call. The PowerOpen
+ ABI does not define this relocation type. */
+ case R_RBR:
+ /* A relative branch which may be modified to become an
+ absolute branch. FIXME: We don't implement this,
+ although we should for symbols of storage mapping class
+ XMC_XO. */
+ howto.pc_relative = true;
+ howto.src_mask &= ~3;
+ howto.dst_mask = howto.src_mask;
+ break;
+ case R_RL:
+ /* The PowerPC AIX ABI describes this as a load which may be
+ changed to a load address. The PowerOpen ABI says this
+ is the same as case R_POS. */
+ break;
+ case R_RLA:
+ /* The PowerPC AIX ABI describes this as a load address
+ which may be changed to a load. The PowerOpen ABI says
+ this is the same as R_POS. */
+ break;
+ }
+
+ /* If we see an R_BR or R_RBR reloc which is jumping to global
+ linkage code, and it is followed by an appropriate cror nop
+ instruction, we replace the cror with lwz r2,20(r1). This
+ restores the TOC after the glink code. Contrariwise, if the
+ call is followed by a lwz r2,20(r1), but the call is not
+ going to global linkage code, we can replace the load with a
+ cror. */
+ if ((rel->r_type == R_BR || rel->r_type == R_RBR)
+ && h != NULL
+ && h->root.type == bfd_link_hash_defined
+ && (rel->r_vaddr - input_section->vma + 8
+ <= input_section->_cooked_size))
+ {
+ bfd_byte *pnext;
+ unsigned long next;
+
+ pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
+ next = bfd_get_32 (input_bfd, pnext);
+
+ /* The _ptrgl function is magic. It is used by the AIX
+ compiler to call a function through a pointer. */
+ if (h->smclas == XMC_GL
+ || strcmp (h->root.root.string, "._ptrgl") == 0)
+ {
+ if (next == 0x4def7b82 /* cror 15,15,15 */
+ || next == 0x4ffffb82) /* cror 31,31,31 */
+ bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */
+ }
+ else
+ {
+ if (next == 0x80410014) /* lwz r1,20(r1) */
+ bfd_put_32 (input_bfd, 0x4ffffb82, pnext); /* cror 31,31,31 */
+ }
+ }
+
+ /* A PC relative reloc includes the section address. */
+ if (howto.pc_relative)
+ addend += input_section->vma;
+
+ rstat = _bfd_final_link_relocate (&howto, input_bfd, input_section,
+ contents,
+ rel->r_vaddr - input_section->vma,
+ val, addend);
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ char howto_name[10];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = h->root.root.string;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return false;
+ }
+ sprintf (howto_name, "0x%02x", rel->r_type);
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, name, howto_name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_vaddr - input_section->vma)))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
new file mode 100644
index 00000000000..b8a3d2725a3
--- /dev/null
+++ b/binutils/ChangeLog
@@ -0,0 +1,6404 @@
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-18 Ian Lance Taylor <ian@zembu.com>
+
+ * stabs.c (parse_stab_range_type): Correct parenthesization in
+ BFD64 case.
+
+ * readelf.c (get_section_type_name): Use correct types in printf
+ formats.
+ (process_relocs): Likewise.
+ (process_dynamic_segment): Likewise.
+ (process_symbol_table): Likewise.
+ (process_mips_specific): Likewise.
+
+Tue Apr 13 21:22:00 1999 Catherine Moore <clm@cygnus.com>
+
+ * dlltool.c (make_one_lib_file): Mark thumb functions as
+ C_THUMBEXTFUNC.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * bucomm.h (environ): Declare it, if needed.
+ (alloca) [C_ALLOCA]: Don't use gcc's builtin or <alloca.h>.
+ * configure.in (environ): Detect declaration.
+ * nm.c (main): Don't declare environ.
+ * configure, config.in: Rebuild.
+
+ * dlltool.c (gen_exp_file): Pad out the .reloc section to a
+ 32-byte boundary with dummy relocations, to make the BeOS loader
+ happy. Patch from Bob Manson <manson@charmed.cygnus.com>.
+
+1999-04-08 Tom Tromey <tromey@cygnus.com>
+
+ * binutils.texi (c++filt): Updated for -j/--java, and hp/edg
+ formats.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Add ability to decode new constants found in April 25
+ 1998 Draft of System V ABI spec.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * bucomm.h (LC_MESSAGES): Never define.
+ * addr2line.c (main): Don't pass LC_MESSAGES to setlocale if the
+ system does not define it.
+ * ar.c (main): Likewise.
+ * coffdump.c (main): Likewise.
+ * dlltool.c (main): Likewise.
+ * nlmconv.c (main): Likewise.
+ * nm.c (main): Likewise.
+ * objcopy.c (main): Likewise.
+ * objdump.c (main): Likewise.
+ * size.c (main): Likewise.
+ * srconv.c (main): Likewise.
+ * strings.c (main): Likewise.
+ * sysdump.c (main): Likewise.
+ * windres.c (main): Likewise.
+ * readelf.c (main): Call locale setting functions.
+
+1999-04-05 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (decode_location_expression): Fix DW_OP_const8{s|u}
+ decodes.
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * rename.c: New file, copied out of objcopy.c with a few changes.
+ * bucomm.h (set_times, smart_rename): Declare.
+ * ar.c: Don't include <utime.h>.
+ (extract_file): Call set_times rather than utime.
+ (write_archive): Call smart_rename rather than unlink and rename.
+ * objcopy.c: Don't include <utime.h>.
+ (simple_copy, smart_rename, set_times): Move to rename.c.
+ (strip_main): Update smart_rename call for new parameter.
+ (copy_main): Likewise.
+ * Makefile.am: Rebuild dependencies.
+ (CFILES): Add rename.c.
+ (objcopy_SOURCES, strip_new_SOURCES): Add rename.c.
+ (ar_SOURCES, ranlib_SOURCES): Add rename.c.
+ * Makefile.in: Rebuild.
+
+ * Makefile.am: Rebuild dependencies.
+ (EXTRA_PROGRAMS): Remove backslash which troubles current version
+ of automake.
+ * Makefile.in: Rebuild.
+
+ * dllwrap.c (main): Expect correct type in format string.
+ * resres.c: Include "bfd.h", "bucomm.h", "libiberty.h", and
+ <time.h>. Don't include <stdio.h> and <errno.h>.
+ (write_res_file): Remove unused locals e and i.
+ (read_resource_entry): Remove unused locals rtype and n.
+ (read_unistring): Remove unused local n.
+
+1999-04-03 Ian Lance Taylor <ian@zembu.com>
+
+ * arparse.y: Declare yylex.
+ * objdump.c (disassemble_bytes): Initialize bytes. Add comment
+ for incorrect use of bytes.
+ * readelf.c: Change many formats to avoid warnings.
+
+1999-04-01 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (reset_state_machine): New function. Resets the
+ registers of the source line number state machine.
+ (process_extended_line_op): Use state machine.
+ (display_debug_lines): Use state machine. Handle multiple line
+ number blocks within the same section.
+
+1999-03-29 Jason Merrill <jason@yorick.cygnus.com>
+
+ * readelf.c (process_extended_line_op): end_sequence also resets
+ the line number.
+ (display_debug_lines): advance_line takes a signed operand.
+ (read_and_display_attr): Print refs as <%x>, addresses as %#x,
+ others as %d. Handle other location expression attributes.
+ (display_debug_info): Handle nesting. Always print the offset.
+
+1999-03-23 Ian Lance Taylor <ian@zembu.com>
+
+ * objcopy.c (filter_symbols): When checking whether to keep a
+ symbol, check the BFD section symbol for a symbol with
+ BSF_SECTION_SYM set.
+
+1999-03-10 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_dynamic_segment): Print new Solaris dynamic
+ section entries. Correct printing of DT_POSFLAG_1 and DT_FLAGS_1.
+
+1999-03-10 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (request_dump): New function.
+ Removed arbitary limit on the number of sections that can be
+ dumped.
+
+Wed Mar 10 15:10:14 1999 Stan Cox <scox@cygnus.com>
+
+ * dlltool.c (make_one_lib_file): Use %05d to output the stub name so
+ order in the import library is preserved.
+
+1999-02-19 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Fix compile time warings.
+
+1999-02-17 DJ Delorie <dj@cygnus.com>
+
+ * resbin.c (res_to_bin_versioninfo): Instead of entering a value
+ length of zero in a version info string, enter the appropriate
+ length.
+
+Tue Feb 16 16:00:33 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Require autoconf 2.13. Change AM_PROG_INSTALL to
+ AC_PROG_INSTALL. Add comments for AC_DEFINE calls.
+ * acconfig.h: Remove.
+ * aclocal.m4: Rebuild.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+ * config.in: Rebuild.
+
+1999-02-02 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (read_and_display_attr): Add display of basic type
+ encodings.
+ (display_debug_aranges): New function: Display the contents of a
+ .debug_aranges section.
+ (display_debug_info): Dump tags found after compunit entry.
+
+ * binutils.texi: Fixed bug in readelf documentation.
+
+Mon Feb 1 12:38:01 1999 Catherine Moore <clm@cygnus.com>
+
+ * readelf.c (dump_relocations): Handle EM_ARM as REL.
+
+1999-01-29 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (process_symbol_table): Do not produce a histogram of
+ bucket chains if none were found.
+
+1999-01-27 Nick Clifton <nickc@cygnus.com>
+
+ * version.c: Add 1999 copyright.
+
+ * binutils.texi (readelf): Document new command line options
+ --debug-dump and --histogram.
+
+ * readelf.c: Add ability to display contents of some or all of the
+ Dwarf2 debug sections. {Work only partially completed}.
+ (display_debug_section): New function.
+ (display_debug_info): New function.
+ (display_debug_not_supported): New function.
+ (display_debug_line): New function.
+ (display_debug_abbrev): New function.
+ (process_abbrev_section): New function.
+ (read_leb128): New function.
+ (process_extended_line_op): New function.
+ (get_TAG_name): New function.
+ (get_AT_name): New function.
+ (get_FORM_name): New function.
+ (free_abbrevs): New function.
+ (add_abbrev): New function.
+ (add_abbrev_attr): New function.
+ (read_and_display_attr): New function.
+ (display_block): New function.
+
+Thu Jan 14 23:36:11 1999 Jeffrey A Law (law@cygnus.com)
+
+ * coffdump.c (xcalloc): Remove, in libiberty now.
+ * srconv.c (xcalloc): Likewise.
+ * sysdump.c (xcalloc): Likewise.
+
+1999-01-14 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (process_section_headers): Omit trailing space at end
+ of section header contents line.
+
+Wed Dec 16 17:20:05 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * aclocal.m4: Regenerate.
+
+Mon Dec 14 12:55:36 1998 Jim Wilson <wilson@cygnus.com>
+
+ * dllwrap.c: Include bfd.h and bucomm.h. Move getopt.h include
+ after libiberty.h include.
+
+Tue Dec 8 16:29:43 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.1: Fix typo (-d to -D). From Nokubi Hirotaka
+ <hnokubi@yyy.or.jp>.
+
+Sun Dec 6 13:28:09 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (SFILE): Add size field.
+ (objdump_sprintf): Merge both versions into one. Increase buffer
+ size as needed to avoid overflow.
+ (disassemble_bytes): Change buf from 1000 bytes to 50. Change
+ initialization and use of sfile to match changes to
+ objdump_sprintf.
+
+ * strip.1: Fix typo (-V to -v). From Issei Hirayama
+ <iss@mail.wbs.or.jp>.
+
+1998-12-03 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_dynamic_segment): Improve output format for
+ various DT_* values.
+
+1998-12-02 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_mips_specific): Print .conflict section
+ content.
+
+ * readelf.c (process_mips_specific): Print l_flags in liblist in
+ textual form.
+
+1998-11-30 Nick Clifton <nickc@cygnus.com>
+
+ * ar.c (extract_file): Add some paranoia checks for negatively
+ sized files.
+
+Tue Nov 24 09:39:24 1998 Nick Clifton <nickc@cygnus.com>
+
+ * stabs.c (DIR_SEPARATOR): Define as '\\' if WIN32 is defined.
+
+Tue Nov 17 10:25:26 1998 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.in: Regenerate.
+
+Mon Nov 16 19:17:23 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/binutils.pot: Regenerate.
+
+Mon Nov 16 10:18:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Regernated dependencies.
+ * aclocal.m4: Regenerated.
+ * configure: Regenerated.
+
+Sat Nov 14 14:50:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * debug.c (debug_name_type): Correct return type from false to
+ DEBUG_TYPE_NULL.
+
+Sat Nov 14 14:48:21 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * objdump.c (disassemble_data): Skip over relocs below start
+ address.
+
+Tue Nov 10 15:31:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Add dependency of readelf.c on elf/fr30.h
+ * Makefile.in: Regenerate.
+
+Wed Nov 4 16:25:55 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Add support for the FR30.
+
+Mon Nov 2 14:59:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Fri Oct 30 15:14:49 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * dllwrap.c: change all references to cygwin32_ to cygwin_,
+ change Cygwin target def to CYGWIN.
+
+Wed Oct 28 10:31:19 1998 Nick Clifton <nickc@cygnus.com>
+
+ * objdump.c (disassemble_data): Replace 'unsigned long' with
+ 'bfd_vma'.
+
+Tue Oct 27 14:39:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * objdump.c (disassemble_bytes): Applied this patch from Philip
+ Blundell <pb@nexus.co.uk>: Make address variables unsigned to
+ avoid problems when disassembling code at high-bit-set addresses.
+
+Mon Oct 26 14:07:59 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dllwrap.c (strhash): New function.
+ (main): Use it to supply image base if not supplied by user.
+ (program_version): Up to 0.2.4.
+
+Mon Oct 26 14:07:59 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dlltool.c (add_stdcall_alias): New global.
+ (long_options): Add --add-stdcall-alias option.
+ (main): Handle it.
+ (scan_drectve_symbols): Add alias if --add-stdcall-alias is
+ specified.
+ (scan_filtered_symbols): Likewise.
+ (gen_def_file): Output alias for stdcall syms if appropriate.
+
+ * binutils.texi (dlltool): Document --add-stdcall-alias option.
+
+ * dllwrap.c (long_options): Add --add-stdcall-alias option.
+ (main): Handle it.
+
+ * defparse.y (opt_name): Allow "." in name.
+ * dlltool.c (def_name): Set dll_name from NAME entry in def file.
+ (def_library): Set dll_name from LIBRARY entry in def file.
+
+Mon Oct 26 14:07:59 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dllwrap.c (long_options): --implib synonym for --output-lib.
+ (main): Pass --export-all to dlltool only if specified.
+ (program_version): Up to 0.2.3.
+
+Mon Oct 26 14:07:59 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dllwrap.c (mybasename): New function.
+ (main): Run dlltool to create export definition file and import
+ library file if necessary.
+ Change exp_file_name so that it's based on the dll name.
+
+Sun Oct 25 10:37:45 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dlltool.c (scan_all_symbols): Fix patch error.
+
+Fri Oct 16 22:56:20 1998 Felix Lee <flee@cygnus.com>
+
+ * nm.c (display_rel_file): fix "no symbols" messages.
+ * objdump.c (slurp_symtab): ditto.
+ * po/POTFILES.in, po/binutils.pot: rebuilt
+
+Mon Oct 12 14:28:03 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (dump_relocations): Rename field from Value to Info to
+ match name of field in ELF structures.
+
+Thu Oct 8 15:33:08 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: call AC_EXEEXT instead of AM_EXEEXT and
+ AM_CYGWIN32.
+ * aclocal.m4: remove local AM_EXEEXT/AM_CYGWIN32 macros.
+ * configure: regenerate
+
+Thu Oct 8 15:33:08 1998 Geoffrey Noer <noer@cygnus.com>
+
+ From Mumit Khan <khan@xraylith.wisc.edu>:
+ * dlltool.c (scan_all_symbols): Don't re-export symbols exported
+ by other DLLs.
+
+Thu Oct 8 15:33:08 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.am (BUILD_DLLWRAP): Add.
+ (BUILD_DLLWRAP, DLLWRAP_PROG): Add.
+ (bin_PROGRAMS): Add dllwrap.
+ * Makefile.in: regenerate with automake
+
+ From Mumit Khan <khan@xraylith.wisc.edu>:
+ * dllwrap.c: New file from dllhelpers v0.2.1.
+ (print_version): New function.
+ (long_options): Add --version.
+ (main): Handle.
+ * dyn-string.h, dyn-string.c: New files from egcs-1.1/gcc.
+ * configure.in (BUILD_DLLWRAP): Add.
+ * configure: Regenerate.
+
+Tue Oct 6 18:20:10 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * Makefile.am (windres_SOURCES): Add resres.c.
+ (windres_OBJECTS): Add resres.o.
+ * Makefile.in: regenerate with automake
+
+ From Anders Norlander <anorland@hem2.passagen.se>.
+ * resres.c: New file. Implementation of read_res_file and
+ write_res_file functions for windres.
+ * rcparse.y: Handle CONTROL's with named classes.
+ * resbin.c: Bug in res_to_bin_dialog and bin_to_res_dialog
+ when dialog is extended: The version and signature fields should
+ be reversed (despite what the docs say). Id is 32 bits long in
+ extended dialogs.
+ * resrc.c (write_rc_dialog): properly print controls with named
+ classes.
+ * windres.c (read_res_file, write_res_file): Remove stubs.
+ * resres.c (write_res): Rename RT_ACCELERATORS to RT_ACCELERATOR.
+
+Sun Oct 4 20:34:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Nokubi Hirotaka <hnokubi@yyy.or.jp>:
+ * objcopy.1: Fix typo in --remove-leading-char docs.
+ * objdump.1: Fix formatting in --stabs docs.
+
+Sat Sep 19 23:33:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * rcparse.y (memflags_move): Correct recursion.
+
+1998-09-10 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_symbol_table): Print in histogram how many
+ symbols are covered by the current chain length.
+
+Sun Sep 6 16:15:47 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (process_section_contents): Do not try to dump empty
+ sections.
+
+Sat Sep 5 19:17:10 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dlltool.c (scan_all_symbols): Don't re-export symbols exported
+ by other DLLs.
+
+1998-09-02 14:50 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_dynamic_segment): Print DT_* value only if
+ do_dynamic.
+ (do_histogram): New variable.
+ (options): New long option histogram. Set do_histogram if this
+ option is used.
+ (usage): Document --histogram.
+ (parse_args): Handle 0 return value from getopt_long. Enable
+ do_histogram for -a.
+ (process_symbol_table): Read hash table also if only do_histogram.
+ Add code to print hash table histogram.
+
+1998-08-25 16:45 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_dynamic_segment): Read syminfo section if
+ available.
+ (process_syminfo): New function. Print syminfo information.
+ (process_file): Call process_syminfo and free syminfo data at the end.
+
+Wed Aug 19 16:19:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (usage): Add file parameter. Change all callers.
+ (main): Don't treat '?' as a special case in getopt return.
+
+ * binutils.texi (dlltool): Document new options. Add some uses of
+ @var.
+
+Wed Aug 19 16:19:07 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dlltool.c (gen_def_file): Plug memory leak. Don't print
+ demangled name if it is NULL.
+
+ Support for exporting all symbols to an output export def file:
+ * dlltool.c ({export_all_symbols, no_default_excludes,
+ no_default_excludes, excludes}): New file static variables.
+ (struct string_list): Type to hold list of symbols to exclude.
+ (scan_drectve_symbols): Renamed from scan_open_obj_file.
+ (scan_filtered_symbols): New static function.
+ (add_excludes): New static function.
+ (match_exclude): New static function.
+ (set_default_excludes): New static function.
+ (filter_symbols): New static function.
+ (scan_all_symbols): New static function.
+ (scan_open_obj_file): New static function.
+ (usage): Document new options.
+ (long_options): Add new options.
+ (main): Handle new options.
+
+1998-07-31 21:24 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_program_headers): Print p_offset value with
+ six hex digits.
+ (dynamic_segment_mips_val): Add support for DT_MIPS_FLAGS,
+ DT_MIPS_IVERSION, and DT_MIPS_TIME_STAMP.
+ (process_mips_specific): Also print seconds of time stamp.
+
+Fri Jul 31 10:04:23 1998 Catherine Moore <clm@cygnus.com>
+
+ * readelf.c (dump_relocations): EM_ARM uses rela relocs.
+
+1998-07-30 16:25 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (get_dynamic_type): Don't used gettext on the names.
+ Add new DT_* values from Solaris. Don't print nuemric value in
+ case of an unknown entry.
+ (process_dynamic_segment): Handle new DT_* entries. Print numeric
+ values in decimal, not hex.
+
+Fri Jul 24 16:28:57 1998 Jeff Holcomb <jeffh@cygnus.com>
+
+ * readelf.c (get_dynamic_type): Remove empty default from switch
+ statement.
+
+Fri Jul 24 16:28:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (install-exec-local): Don't remove the file before
+ checking whether $(bindir) == $(tooldir)/bin. From Maciej
+ W. Rozycki <macro@ds2.pg.gda.pl>.
+ * Makefile.in: Rebuild.
+
+Fri Jul 24 09:38:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * objcopy.c: Removed spurious inclusion of elf/internal.h and
+ elf-bfd.h.
+
+1998-07-22 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c: Consistantly use elf_ prefix for *_reloc_type
+ functions.
+
+Wed Jul 22 16:29:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (dump_relocations): Add dumps of HPPA and ARC
+ relocations.
+
+ (process_relocs): Do not abort if no string table can be found.
+
+1998-07-22 14:58 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c: Remove definition of functions to return relocation
+ symbol strings. They now get implicitly defined when include the
+ system specific ELF header.
+
+1998-07-22 13:51 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c: Before include system specific ELF header define
+ START_RELOC_NUMBERS, RELOC_NUMBER, and END_RELOC_NUMBERS. For now
+ used for ppc, mips, and mn10300.
+
+Wed Jul 22 10:26:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (dump_relocations): Display number of unrecognised
+ relocations.
+
+1998-07-21 13:13 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c: Use symbolic names of relocation entries for the various
+ architectures. Correct more layout details.
+ Print names of MIPS specific section types. Print Alpha, ARM, and
+ MIPS relocation type names.
+
+1998-07-20 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * objcopy.c (filter_symbols): Add code for strip all symbols case.
+ (copy_objects): Strip all case is now processed also through
+ filter_symbols. No marking symbols used in relocations when strip
+ all symbols case.
+ (copy_section): When strip all symbols case, remove relocations
+ which are not in keep strip specific list.
+ (strip_main): Remove guard `strip_specific_list == NULL' for
+ setting up strip all symbols by default.
+
+Mon Jul 20 12:51:16 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * addr2line.c (find_address_in_section): Only consider a section
+ if the pc value is completely contained within it.
+ (translate_addresses): Don't crash if functionname or filename are
+ null.
+
+1998-07-20 07:45 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c (process_symbol_table): Fix little alignment problem
+ in printed table header.
+
+1998-07-20 07:14 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c: Correct reading of .dynamic section.
+ (dynamic_section): Now a global variable.
+ (process_mips_fpe_exception, process_mips_specific,
+ process_arch_specific): New functions.
+ (get_file_header): Call process_arch_specific.
+
+1998-07-19 15:15 Ulrich Drepper <drepper@cygnus.com>
+
+ * readelf.c: Fix several versioning related bugs. Produce nicer
+ output.
+ Add support for processor specific information on MIPS.
+
+Fri Jul 10 15:57:58 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Switch prototypes from unsigned short to unsigned
+ int.
+
+Fri Jul 10 16:17:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Christian Holland <CHolland@de.lucent.com>:
+ * ieee.c (parse_ieee): Initialize info.global_vars and
+ info.global_types.
+ (parse_ieee_atn): Ignore register lifetime information reportedly
+ emitted by MRI compiler.
+
+Thu Jul 9 13:08:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (MAINTAINERCLEANFILES): Define.
+ * Makefile.in: Rebuild.
+
+Tue Jul 7 21:48:54 1998 Jeffrey A Law (law@cygnus.com)
+
+ * readelf.c (byte_get): Use PARAMS in prototype.
+ (error): Make it work with non-ANSI compilers.
+ (warn): Likewise.
+ (get_ver_flags): Don't use an ANSI prototype in the definition.
+
+Tue Jul 7 13:26:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (filter_bytes): Set size correctly if the size of the
+ section is not an even multiple of the interleave. Based on patch
+ from Brion Stone <Brion.Stone@attws.com>.
+
+Thu Jul 2 14:01:34 1998 Klaus Kaempf <kkaempf@rmi.de>
+
+ * configure.com: Add vax/vms support.
+ * makefile.vms-in: Renamed from makefile.vms. Add substitutions
+ now done by configure.com.
+
+Wed Jul 1 20:43:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (parse_stab_range_type): Handle 4 and 8 byte signed
+ integers with real upper bounds. Handle a lower bound one larger
+ than the upper bound as a signed integer. Handle 8 byte signed
+ integers.
+ (stab_demangle_template): Optionally return the demangled name of
+ the template.
+ (stab_demangle_qualified): Treat a template name as a tagged
+ type.
+ (stab_demangle_fund_type): Likewise.
+
+Wed Jul 1 16:29:50 1998 Nick Clifton <nickc@cygnus.com>
+
+ * objcopy.c: Minor formatting improvements.
+ * readelf.c: Minor output formatting improvement.
+
+Wed Jul 1 14:23:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * rclex.l: Add casts and change types to avoid warnings.
+ * rcparse.y: Likewise.
+ * resbin.c: Likewise.
+ * rescoff.c: Likewise.
+ * resrc.c: Likewise.
+
+ * Makefile.am: Rebuild dependencies.
+ (HFILES): Remove readelf.h.
+ * Makefile.in: Rebuild.
+
+ Based on patches from Andrew Kozin
+ <Andrew.Kozin@p14.f960.n5020.z2.fidonet.org>:
+ * winduni.h: New file, from windres.h.
+ * winduni.c: New file, from windres.c.
+ * windres.c: Move Unicode functions into winduni.c.
+ * windres.h: Move Unicode declarations into winduni.h. Include
+ winduni.h.
+ (RT_ACCELERATOR): Rename from RT_ACCELERATORS to match Windows
+ macro. Change all uses.
+ (RT_PLUGPLAY, RT_VXD): Correct values.
+ * Makefile.am (HFILES): Add windres.h.
+ (CFILES): Add winduni.c.
+ (windres_SOURCES): Add winduni.c.
+
+Mon Jun 29 17:01:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Use BFD Internal and External Elf structures.
+ * readelf.h: Removed - no longer needed.
+ * Makefile.in: Remove readelf.c's dependency upon readelf.h.
+
+1998-06-26 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * objcopy.c (strip_main): keep_specific_list == NULL as additional
+ condition to set up strip all symbols by default.
+ (copy_archive): don't change archive when error in object files of
+ the archive.
+
+Wed Jun 24 17:53:47 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (parse_number): Sign extend negative values correctly if
+ bfd_vma is larger than unsigned long.
+
+Tue Jun 23 14:55:05 1998 Mike Stump <mrs@wrs.com>
+
+ * Makefile.am (install-exec-local): Don't let EXEEXT interfere
+ with the program transform name.
+ * Makefile.in: Rebuild.
+
+Tue Jun 23 11:08:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Rewrite to use fopen/fread ratehr than mmap.
+
+ Add --section-headers command line switch, which is an alias for
+ --sections.
+
+ Incorporate improvemnts made by Andreas Schwab
+ <schwab@issan.informatik.uni-dortmund.de> including output
+ formatting and version info display.
+
+ * binutils.texi: Document --section-headers switch to readelf.
+
+Mon Jun 22 18:28:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * readelf.c: Include bfd.h and bucomm.h before system header
+ files.
+ (parse_args): Change type of c from char to int.
+
+Sun Jun 14 14:26:28 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c (usage): Write to stdout, not stderr.
+
+Fri Jun 12 13:33:51 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): Depend on .pot file if maintainer mode
+ enabled.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+Fri Jun 12 16:06:15 1998 Michael Meissner <meissner@cygnus.com>
+
+ * readelf.c (get_ppc_rel_type): New PowerPC support.
+ (dump_relocations): PowerPC uses RELA relocations.
+ (get_machine_name): Spell PowerPC correctly.
+ (get_file_type): Change unsigned short parameter to unsigned.
+ (get_machine_name): Ditto.
+ (get_machine_data): Return whether big endian or little endian.
+ (get_machine_flags): Interpret PowerPC, M32R, and MIPS flags.
+ (process_elf_header): Print endian-ess. Convert all numeric
+ formats to long or unsigned long. Print out machine specific flag
+ bits.
+ (process_section_headers): Increase name by 3 columns and decrease
+ type by the same so that .gcc_except_table fits in the space.
+
+ * readelf.h: Include elf/ppc.h, elf/mips.h, and elf/m32r.h to get
+ machine specific flag bits.
+
+Thu Jun 11 17:54:26 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: Remove extraneous #includes. Fix warnings produced
+ by -Wall when compiling under Linux.
+
+ * Makefile.am (readelf_LDADD): Add $(LIBIBERTY).
+
+Thu Jun 11 18:30:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (struct stab_handle): Add self_crossref field.
+ (parse_stab_string): If a tag is a cross reference to itself,
+ don't define it in the tags list.
+ (parse_stab_type): Set info->self_crossref.
+
+ * debug.c (struct debug_type_real_list): Define.
+ (debug_get_real_type): Add list parameter. Change all callers.
+ Check for circularity to avoid crashing when it occurs.
+
+Thu Jun 11 14:48:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * readelf.c: New file: Display contents of ELF format file.
+ * readelf.h: New file: Header file for readelf.c
+ * Makefile.am: Add rules to build readelf.
+ * Makefile.in: Rebuilt.
+ * binutils.texi: Document readelf.
+ * NEWS: Mention inclusion of readelf into binutils.
+ * po/POTFILES.in; Rebuilt.
+
+Fri Jun 5 18:43:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (setup_section): Adjust the section size if copy_byte
+ is >= 0.
+ (copy_section): Do not call bfd_set_section_size.
+
+Thu Jun 4 09:12:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * objcopy.c (copy_usage): Add missing \n\ from help description.
+
+Wed Jun 3 19:31:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (YACC): Correct bison -L option.
+ * Makefile.in: Rebuild.
+
+ * binutils.texi, objdump.1: Document -p/--private-headers.
+
+Wed Jun 3 12:09:40 1998 Nick Clifton <nickc@cygnus.com>
+
+ * objcopy.c: Add new command line options: --change-section-lma
+ and --change-section-vma. Rename old command line option
+ --adjust-section-vma to --change-section-address. Rename
+ --adjust-vma to --change-addresses and --adjust-start to
+ --change-start. Provide aliases to support the old versions of
+ these command line options.
+
+ Change the names of macros and enum elements to upper case to
+ match the GNU coding standard.
+
+ Replace calls to fprintf (stderr,...) with calls to fatal () or
+ non_fatal () as appropriate.
+
+ * objcopy.1: Document command line option changes.
+ * binutils.texi: Document command line option changes.
+
+ * bucomm.h: New exported funtion from bucomm.c: non_fatal().
+ * bucomm.c (non_fatal): New exported function. Just like fatal()
+ except that it returns rather than calling xexit().
+
+ (bfd_check_format_matches): Call fatal() rather than bfd_fatal().
+
+ (check_matching_formats): Fix C formating.
+
+ (parse_vma): Call fatal().
+
+Mon Jun 1 18:26:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Yuli Barcohen <yuli.barcohen@telrad.co.il>:
+ * debug.c (debug_type_samep): Avoid endless loops comparing
+ function and method parameter types.
+
+Fri May 22 14:02:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (dump_iat): Comment out; not used.
+ (display): Rename from tell. Change all callers.
+
+Thu May 14 14:00:56 1998 Nick Clifton <nickc@cygnus.com>
+
+ * dlltool.c: Add support for Thumb DLLs. Add support for
+ interworking between ARM and Thumb programs and DLLs. Tidy the
+ code.
+
+ * binutils.texi: Document dlltool.
+
+ * configure: Build dlltool for thumb-pe targets.
+
+ * version.c (print_version): Include 1998 in copyright strings.
+
+ * stabs.c (parse_stab): Support Win32 style directory separators.
+
+Sun May 10 22:34:44 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Fri May 8 10:33:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ar.c (usage): Extend information provided about command line
+ options.
+
+Wed May 6 15:28:51 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Run dec c with /nodebug. Pass CC value when
+ calling make.
+
+Tue May 5 15:19:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure: Build dlltool for thumb-pe target.
+ * configure.in: Build dlltool for thumb-pe target.
+
+Sun May 3 22:04:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (EXTRA_PROGRAMS): Change $(SRCONV_PROG) to sysconf
+ sysdump coffdump to avoid extra $(EXEEXT).
+ * Makefile.in: Rebuild.
+
+Wed Apr 29 22:22:55 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: Stop appending EXEEXT to the end of
+ SRCONV_PROG (wrong because that variable may contain multiple
+ programs)
+ * Makefile.am: instead, add EXEEXTs to each SRCONV_PROG
+ program
+ * Makefile.in: regenerate
+ * configure: regenerate
+
+Tue Apr 28 19:14:34 1998 Tom Tromey <tromey@cygnus.com>
+
+ * addr2line.c (main): Conditionally call setlocale.
+ * windres.c (main): Likewise.
+ * sysdump.c (main): Likewise.
+ * strings.c (main): Likewise.
+ * srconv.c (main): Likewise.
+ * size.c (main): Likewise.
+ * objdump.c (main): Likewise.
+ * objcopy.c (main): Likewise.
+ * nm.c (main): Likewise.
+ * nlmconv.c (main): Likewise.
+ * dlltool.c (main): Likewise.
+ * coffdump.c (main): Likewise.
+ * ar.c (main): Likewise.
+ * bucomm.h: Include <locale.h> if HAVE_LOCALE_H.
+ (LC_MESSAGES): Now can be defined even when ENABLE_NLS.
+
+Tue Apr 28 10:33:07 1998 Bill Moyer <ttk@cygnus.com>
+
+ Add support for IMPORTS:
+ * defparse.y (impline): Add IMPORTS syntaxes.
+ * dlltool.c (ifunctype, iheadtype): New typedefs.
+ (import_list): New static variable.
+ (append_import): New static function.
+ (def_import): Add an entry to import_list.
+ (generate_idata_ofile): New static function.
+ (gen_exp_file): Call generate_idata_ofile.
+ * dlltool.h (def_import): Update declaration.
+
+Mon Apr 27 16:39:22 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.9.4
+ * configure: Rebuild.
+
+Wed Apr 22 16:00:35 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir).
+
+Wed Apr 22 00:33:56 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * Makefile.am (INCLUDES): Search intl dirs for headers; define
+ LOCALEDIR.
+ * addr2line.c (main): Call setlocale, bindtextdomain, textdomain.
+ * ar.c (main): Likewise.
+ * coffdump.c (main): Likewise.
+ * dlltool.c (main): Likewise.
+ * nlmconv.c (main): Likewise.
+ * nm.c (main): Likewise.
+ * objcopy.c (main): Likewise.
+ * objdump.c (main): Likewise.
+ * size.c (main): Likewise.
+ * srconv.c (main): Likewise.
+ * strings.c (main): Likewise.
+ * sysdump.c (main): Likewise.
+ * windres.c (main): Likewise.
+
+Tue Apr 21 22:13:08 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * Many files: Added gettext invocations around user-visible
+ strings.
+ * bucomm.h: Added gettext-related includes and defines.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY,
+ HAVE_LC_MESSAGES): Define.
+ * configure.in: Call CY_GNU_GETTEXT. Create po/Makefile.in and
+ po/Makefile. Use AM_PROG_LEX.
+ * Makefile.am (SUBDIRS): New macro.
+ (POTFILES): Likewise.
+ (po/POTFILES.in): New target.
+ (LDADD): Added INTLLIBS.
+ (objdump_LDADD): Likewise.
+ (c__filt_LDADD): Likewise.
+ (ar_LDADD): Likewise.
+ (ranlib_LDADD): Likewise.
+ (dlltool_LDADD): Likewise.
+ (windres_LDADD): Likewise.
+ * po/Make-in, po/POTFILES.in, po/binutils.pot: New files.
+
+Tue Apr 21 16:07:18 1998 Stanislav Brabec <utx@k332.feld.cvut.cz>
+
+ * objcopy.c (preserve_dates): New file static variable.
+ (smart_rename): If preserve_dates, call set_times when copying.
+ (strip_main): Remove preserve_dates local variable.
+ (copy_main): Likewise.
+
+Tue Apr 7 15:41:15 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (DISTSTUFF): Add defparse.h, defparse.c, rclex.c,
+ rcparse.h, and rcparse.c
+ * Makefile.in: Rebuild.
+
+Mon Apr 6 16:24:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (PROGS): Move $(ADDR2LINE_PROG) to end, so that
+ Makefile.in doesn't have an empty continuation line.
+ (bin_PROGRAMS): Likewise.
+ * Makefile.in: Rebuild.
+
+Fri Apr 3 14:48:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (DISTCLEANFILES): Add site.exp and site.bak.
+ (MOSTLYCLEANFILES): Add binutils.log, binutils.sum, and abcdefgh*.
+ (mostlyclean-local): New target.
+ * Makefile.in: Rebuild.
+
+Wed Apr 1 15:54:16 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Zack Weinberg <zack@rabi.phys.columbia.edu> and H.J. Lu
+ <hjl@gnu.org>:
+ * ar.c (usage): Mention S modifier.
+ (main): Add S modifier.
+ * ar.1, binutils.texi: Document S modifier.
+
+Wed Apr 1 13:11:23 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * binutils.texi: Use @itemx for a secondary item in a table.
+
+Tue Mar 31 18:44:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * dep-in.sed: Add rule to remove @OBJDIR@.
+ * Makefile.am (dep.sed): Substitute for @OBJDIR@.
+ * Makefile.in: Rebuild.
+
+Mon Mar 30 12:47:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set version to 2.9.1.
+ * configure: Rebuild.
+
+ * Branched binutils 2.9.
+
+ * Makefile.am (DISTCLEANFILES): Remove defparse.h, arparse.h,
+ rcparse.h, and nlmheader.h.
+ * Makefile.in: Rebuild.
+
+Sat Mar 28 17:39:27 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (MOSTLYCLEANFILES): Define.
+ * Makefile.in: Rebuild.
+
+ Fix some gcc -Wall warnings:
+ * nlmconv.c (main): Add casts to avoid warnings.
+ (alpha_mangle_relocs): Likewise.
+ * objdump.c (dump_section_stabs): Likewise.
+ * size.c (print_sysv_format): Likewise.
+ * srcconv.c (wr_ob): Likewise.
+ * wrstabs.c (stab_modify_type): Likewise.
+ (stab_variable): Likewise.
+ * nlmconv.c (main): Initialize variables to avoid warnings.
+ * nm.c (sort_symbols_by_size): Likewise.
+ * objdump.c (disassemble_bytes): Likewise.
+ * wrstabs.c (stab_end_class_type): Likewise.
+ * coffgrok.c (do_sections_p2): Change j to unsigned int.
+ (do_lines): Change l to unsigned int.
+ * nlmheader.y (yylex): Change i to unsigned int.
+ * nm.c (print_symbol): Change j to long.
+ * size.c (lprint_number): Comment out.
+ * srconv.c (wr_ob): Change i to bfd_size_type.
+ * sysdump.c (unit_info_list): Comment out.
+ (object_body_list, program_structure, debug_list): Likewise.
+ * sysinfo.y (yyerror): Return value.
+
+Thu Mar 26 17:06:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * defparse.y (explist): Allow epsilon.
+ Suggestion from Jonathan-Harris@psion.com.
+
+Thu Mar 26 16:59:09 1998 Richard Henderson <rth@cygnus.com>
+
+ * coffgrok.c (do_sections_p1): Use the section's lma instead of vma
+ for the benefit of prom loaders.
+
+Wed Mar 25 13:05:39 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * Makefile.am (DISTSTUFF): New variable.
+ (diststuff): New target.
+ (DISTCLEANFILES): New variable.
+ * Makefile.in: Rebuild.
+
+Tue Mar 24 19:33:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * rclex.l: Accept { and } as synonyms for BEGIN and END.
+
+Fri Mar 20 19:18:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Tue Feb 24 13:07:50 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * objdump.c (disassemble_data): Delete "++place" after call to
+ find_symbol_for_address. Set disasm_info.symbols to array of
+ symbols at the current address.
+
+Wed Feb 18 23:39:46 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.am (install-exec-local): Install properly when ln
+ fails or tooldir == prefix.
+
+Tue Feb 17 18:40:55 1998 Richard Henderson <rth@cygnus.com>
+
+ * objcopy.c (compare_section_lma): Rename from _vma.
+ (copy_object): Gap fill based on LMA not VMA.
+ * binutils.texi: Update and clarify.
+ * objcopy.1: Likewise.
+
+Tue Feb 17 20:34:11 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (gen_exp_file): Generate _imp__%s as well as __imp_%s,
+ for Microsoft compatibility.
+ (make_one_lib_file): Likewise.
+
+ * dlltool.c (make_one_lib_file): Don't add 1 to hint.
+
+Fri Feb 13 16:37:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e.
+
+Thu Feb 12 14:13:46 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * deflex.l: Accept '?' in symbol names, for VC++ mangled names.
+ From Mikey <jeffdb@netzone.com>.
+
+ * addr2line.c (usage): Update bug-gnu-utils address.
+ * ar.c (usage): Likewise.
+ * nlmconv.c (show_usage): Likewise.
+ * nm.c (usage): Likewise.
+ * objcopy.c (copy_usage): Likewise.
+ (strip_usage): Likewise.
+ * objdump.c (usage): Likewise.
+ * size.c (usage): Likewise.
+ * strings.c (usage): Likewise.
+ * windres.c (usage): Likewise.
+ * binutils.texi (Bug Reporting): Likewise.
+
+Sat Feb 7 15:36:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Thu Feb 5 12:21:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, Makefile.in, aclocal.m4: Rebuild with new libtool.
+
+Fri Jan 30 19:16:28 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.am (CC_FOR_TARGET,nlmcomv.o): Change program_transform_name
+ to transform.
+ * Makefile.in: Regenerate.
+
+Thu Jan 29 16:24:04 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * dlltool.c: Define exit status macros for _WIN32 but not
+ __CYGWIN32__.
+ (gen_lib_file): Check for exit status of unlink.
+ * resrc.c: Define popen and pclose if _WIN32 but not
+ __CYGWIN32__.
+
+Wed Jan 28 17:45:46 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Remove vfork check.
+ * nlmconv.c: Never include vfork.h.
+ * aclocal.m4, configure, Makefile.in, config.in: Rebuild.
+
+Wed Jan 28 17:43:02 1998 J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl>
+
+ * objcopy.c (copy_archive): Only pass one argument to mkdir if
+ _WIN32 but not __CYGWIN32__.
+ (smart_rename): Add code for _WIN32 (not __CYGWIN32__), to cope
+ with different rename behaviour and lack of chown.
+
+ * configure.in: Check for mingw32 when deciding whether to build
+ dlltool.
+ * dlltool.c: Never include vfork.h.
+ (run): Use pexecute rather than vfork.
+ (gen_lib_file): Check for errors from bfd_set_archive_head and
+ bfd_close. Close all the BFDs in the archive before deleting the
+ temporary files.
+
+Thu Jan 22 16:22:55 1998 Fred Fish <fnf@cygnus.com>
+
+ * objdump.c (disassemble_bytes): Add flag INSN_HAS_RELOC to tell
+ disassembly function there is a reloc on this line.
+
+Wed Jan 14 15:29:43 1998 Richard Henderson <rth@cygnus.com>
+
+ * srconv.c (sh, h8300): Delete variables.
+ (addrsize, toolname, rnames): New variables.
+ (writeINT): Use addrsize.
+ (wr_un): Use toolname.
+ (wr_hd): Set up addrsize et al properly for h8300[hs].
+ (walk_tree_symbol): Zero dsy. Use rnames.
+ (wr_un, wr_hd, wr_ob, wr_du): Use proper bfd access macros.
+ * sysdump.c (sh, h8300): Delete variables.
+ (addrsize): New variable.
+ (getINT): Use it.
+ (getone): Initialize it.
+ (getBITS): Range check on MAX.
+
+Mon Dec 29 16:58:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Matthew Bellantoni <matthew@chrysalis.com>:
+ * ar.c (get_pos_bfd): Add default_posname parameter. Change all
+ callers.
+ (replace_members): Default to replacing in the same position.
+
+Mon Dec 22 11:27:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * rclex.l: Don't permit a comma in a STRING.
+ * rcparse.y (acc_entry): Warn if an inappropriate modifier is used
+ with a non VIRTKEY.
+ (acc_event): For a control character, set VIRTKEY, and force the
+ character to uppercase.
+ (acc_options): Don't require a comma separator.
+
+Tue Dec 9 13:25:42 1997 Michael Meissner <meissner@cygnus.com>
+
+ * size.c (size_number): New function to provide size of field.
+ ({l,r}print_number): For octal and hex fields, print field using
+ '0' and '0x' suffixes. Do not include following tab.
+ (sysv_internal_sizer): Size section name, section size, and vma
+ address fields.
+ (sysv_internal_printer): Use calculated sizes for the columns.
+ (print_sysv_format): Size columns before printing.
+ (print_berkeley_format): Print tabs between numbers now that
+ {l,r}print_number doesn't. Print fields right justified.
+
+Mon Dec 8 11:22:04 1997 Nick Clifton <nickc@cygnus.com>
+
+ * objdump.c (objdump_print_addr_with_sym): Remove call to
+ disasm_symaddr() as this function no longer exists.
+
+Tue Dec 2 10:23:50 1997 Nick Clifton <nickc@cygnus.com>
+
+ * objdump.c (objdump_print_addr_with_sym): Call disasm_symaddr()
+ to allow backend to know which symbol has just been displayed.
+
+Tue Dec 2 13:06:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * windres.h (ESCAPE_*): Define standard escape sequences.
+ * rclex.l (handle_quotes): Handle standard escape sequences. Warn
+ about an unrecognized escape character.
+ * windres.c (unicode_print): Print standard escape sequences.
+ * rcparse.y (acc_event): Initialize $$.next.
+ * resbin.c (bin_to_res_menuitems): Don't set MENUITEM_POPUP or
+ MENUITEM_ENDMENU in the menu item flags.
+ (bin_to_res_accelerators): Allocate a structure (the old code
+ never worked).
+ (res_to_bin_accelerator): Correct the test for setting ACC_LAST.
+ (res_to_bin_dialog): Save the extended style rather than saving
+ the style twice. Remove useless shadowing length variable. Set
+ the length of control data correctly.
+ * resrc.c (write_rc_dialog): Don't print the class or menu if the
+ string length is zero.
+
+Mon Nov 24 18:52:43 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * stabs.c (parse_stab_argtypes): Don't try to parse the name of a
+ destructor as mangled argument types.
+
+Mon Nov 10 17:51:41 1997 Gavin Koch <gavin@cygnus.com>
+
+ * addr2line.c (translate_addresses): Use bfd_scan_vma rather
+ than strtol to scan addresses.
+
+Sun Nov 9 11:01:31 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.am (bin_PROGRAMS): Don't use line continuations here.
+
+Tue Nov 4 11:56:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (copy_section): Don't crash if there is no particular
+ information for a section.
+
+Mon Nov 3 12:36:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (parse_flags): Make flag check case insensitive.
+ Check for `contents' flag. Give an error for unrecognized flags.
+ (copy_section): If the contents flag was set for a section that
+ had no contents, zero out the new contents.
+ * binutils.texi (objcopy): Document contents section flag.
+
+Sun Nov 2 14:49:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c: Move new struct and variable definitions to top of
+ file. Remove obsolete add_strip_symbol and is_strip_symbol
+ declarations. Add prototype declarations for add_specific_symbol
+ and is_specified_symbol.
+
+Mon Oct 20 15:31:43 1997 Klaus K"ampf <kkaempf@progis.de>
+
+ * configure.com (HAVE_SBRK): Undefine.
+
+Tue Oct 14 16:14:35 1997 Nick Clifton <nickc@cygnus.com>
+
+ * objdump.c (objdump_symbol_at_address): New function. Returns
+ true if a symbol can be found at the address passed in.
+ (disassemble_data): Set the symbol_at_address_func field to point
+ to objdump_symbol_at_address.
+
+Fri Oct 10 14:13:09 1997 Richard Henderson <rth@cygnus.com>
+
+ * objcopy.c, objcopy.1, binutils.texi: "localize" is a better name
+ than "privatize". Update all references.
+
+Thu Oct 9 15:57:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils.texi (strip): Remove duplicate --target. From Marty
+ Leisner <leisner@sdsp.mc.xerox.com>.
+
+ * nm.c (lineno_cache_bfd): New file static variable.
+ (lineno_cache_rel_bfd): New file static variable.
+ (display_archive): Clear lineno_cache_bfd and lineno_cache_rel_bfd
+ when closing a BFD.
+ (display_file): Likewise.
+ (print_symbol): Use lineno_cache_bfd and lineno_cache_rel_bfd
+ instead of cache_bfd and cache_rel_bfd. Make seccount static, and
+ only set it when setting relocs.
+
+Wed Oct 8 21:19:11 1997 Richard Henderson <rth@cygnus.com>
+
+ * objcopy.c (keep_specific_list, privatize_specific_list,
+ weaken_specific_list): New variables.
+ (keep_symbols): Removed.
+ (add_specific_symbol): New function from the carcas of
+ add_strip_symbol. Takes a list as an argument.
+ (is_specified_symbol): Likewise from is_strip_symbol.
+ (filter_symbols): Honor the new privatize and weaken lists.
+ Optimize bfd_asymbol_name handling.
+ (copy_object, copy_options, copy_usage): Add privatize-symbol &
+ weaken-symbol options.
+
+ * objcopy.1, binutils.texi: Update docs.
+
+Sun Oct 5 09:05:44 1997 Frank Ch. Eigler <fche@cygnus.com>
+
+ * objdump.c (disassemble_data): Make "--prefix-addresses"
+ disassembly adjust to mixed-length instructions.
+ (objdump_print_addr_with_sym): Add "0x" prefix for hexadecimal
+ symbol-offsets in disassembly.
+
+Fri Oct 3 12:04:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (set_times): New static function, replacing
+ make_same_dates.
+ (strip_main): If preserve_dates, stat the input file before
+ copying it, and call set_times afterward.
+ (copy_main): Likewise.
+
+ * wrstabs.c (write_stabs_in_sections_debugging_info): Cast p to
+ char * when calling strcpy and strlen.
+
+Wed Sep 24 11:34:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils.texi (ar cmdline): Document that q now works like r.
+ From Marty Leisner <leisner@sdsp.mc.xerox.com>.
+
+ * binutils.texi (size): The object file argument is optional.
+ From Marty Leisner <leisner@sdsp.mc.xerox.com>.
+
+ * aclocal.m4: Rebuild with new libtool.
+ * configure: Rebuild.
+
+Tue Aug 26 17:48:34 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (EXEEXT_FOR_BUILD): New variable. Use it in all
+ references to the sysinfo program.
+ * configure.in: Rebuild with new bfd/acinclude.m4.
+ * Makefile.in: Rebuild.
+
+Fri Aug 8 15:32:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * windres.c: Include <time.h>.
+ (define_resource): Set a timestamp for the resource.
+
+Wed Aug 6 13:37:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Define TARGET in header file.
+ * acconfig.h (TARGET): Add #undef.
+ * Makefile.am (version.o, bucomm.o): Remove special targets.
+ * bucomm.c (target): Remove.
+ * nm.c (program_name): Don't declare.
+ (target): Make static.
+ * size.c (target): Make static.
+ * configure, config.in, Makefile.in: Rebuild.
+
+Tue Aug 5 00:01:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (check-DEJAGNU): Export r.
+ (.dep1): Use $(INCLUDES) rather than $(ALL_CFLAGS).
+ * Makefile.in: Rebuild.
+
+ * nlmheader.y: Use VERSIONK rather than VERSION.
+
+ * Makefile.am (STRIP_PROG): Change from strip.new to strip-new.
+ (NM_PROG): Change from nm.new to nm-new.
+ (TOOL_PROGS, install-exec-local): Adjust accordingly.
+ * Makefile.in: Rebuild.
+
+Mon Aug 4 11:47:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Remove AC_ARG_PROGRAM; it's invoked by
+ AM_INIT_AUTOMAKE.
+ * configure: Rebuild.
+
+ * Makefile.am (install-exec-local): Create $(tooldir)/bin before
+ trying to install anything into it.
+ * Makefile.in: Rebuild.
+
+ * Makefile.am (TOOL_PROGS): Use an explicit $(EXEEXT).
+ (install-exec-local): When handling $(noinst_PROGRAMS), only use
+ $(EXEEXT) on the installed file. When handling $(TOOL_PROGS),
+ handle $(EXEEXT) correctly.
+ * configure.in: Add an explicit $(EXEEXT) when substituting for
+ the name of a program to build.
+ * Makefile.in, configure: Rebuild.
+
+ * aclocal.m4, configure, Makefile.in: Rebuild with new automake
+ patches.
+
+ * deflex.l, defparse.y: Use VERSIONK rather than VERSION.
+ * rclex.l, rcparse.y: Likewise.
+ * Makefile.am (windres_SOURCES): Add $(BULIBS).
+ * Makefile.in: Rebuild.
+
+Fri Aug 1 13:08:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * acinclude.m4: Include bfd/acinclude.m4, not bfd/acmacros.m4.
+ * aclocal.m4, configure: Rebuild with new libtool.
+
+Thu Jul 31 11:51:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * acinclude.m4: New file, from old aclocal.m4.
+ * configure.in: Call AM_INIT_AUTOMAKE and AM_PROG_LIBTOOL. Remove
+ shared library handling; now handled by libtool. Replace
+ AC_CONFIG_HEADER with AM_CONFIG_HEADER. Call AC_PROG_YACC,
+ AC_PROG_LEX, AC_DECL_YYTEST, AM_MAINTAINER_MODE, AM_CYGWIN32, and
+ AM_EXEEXT. Replace AC_PROG_INSTALL with AM_PROG_INSTALL. Remove
+ stamp-h handling in AC_OUTPUT.
+ * acconfig.h: Mention PACKAGE and VERSION.
+ * stamp-h.in: New file.
+ * Makefile.in: Now built with automake.
+ * aclocal.m4: Now built with aclocal.
+ * config.in, configure: Rebuild.
+
+ From Ton van Overbeek <tvoverbe@wk.estec.esa.nl>:
+ * rcparse.y (dialog): Default menu and class to be named.
+ (styles): If FONT is seen, set DS_SETFONT in dialog style.
+ * resbin.c (res_to_bin_dialog): Correct computation of font
+ information length.
+
+Wed Jul 30 11:21:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Ton van Overbeek <tvoverbe@wk.estec.esa.nl>:
+ * resbin.c (res_to_bin_menu): Correct computation of menu
+ vs. menuex length.
+ * resrc.c (define_stringtable): Add 1 to resource ID.
+
+Tue Jul 29 11:06:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * resbin.c (bin_to_res_string): Correct adjustment of data and
+ length. From Ton van Overbeek <tvoverbe@wk.estec.esa.nl>.
+
+Tue Jul 22 18:01:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * nlmconv.c (link_inputs): Call libiberty pexecute function.
+ (pexecute) [multiple versions]: Remove.
+
+Tue Jul 22 16:19:34 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * bucomm.c (make_tempname): If we might be using a DOS filesystem,
+ check for a backslash as well as a slash.
+
+Thu Jun 26 13:53:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * windres.c (main): Quit if we didn't get any resources.
+ (usage): Fix --yydebug usage message.
+ * rescoff.c (write_coff_file): Don't free the relocation array
+ until after we've closed the BFD.
+ (read_coff_rsrc): Quit rather than try to read standard input.
+ (write_coff_file): Quit rather than try to write to standard
+ output.
+ * rcparse.y: Add a couple of missing semicolons (accepted by bison
+ but not byacc).
+ * binutils.texi: Document windres.
+
+Wed Jun 25 20:57:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * resbin.c: New file.
+ * rclex.l, rcparse.y, rescoff.c, resrc.c, windres.c, windres.h:
+ Numerous fixes and improvements.
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Add resbin.c.
+ (WINDRES_OBJS): Add resbin.o.
+
+Sun Jun 22 17:29:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ First stab at Windows resource compiler:
+ * windres.h: New file.
+ * windres.c: New file.
+ * resrc.c: New file.
+ * rcparse.y: New file.
+ * rclex.l: New file.
+ * rescoff.c: New file.
+ * configure.in: Define and substitute BUILD_WINDRES.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild dependencies.
+ (WINDRES_PROG): New variable.
+ (PROGS): Add @BUILD_WINDRES@.
+ (HFILES): Add dlltool.h and windres.h.
+ (CFILES): Add windres.c and resrc.c.
+ (GENERATED_CFILES): Add rcparse.c and rclex.c.
+ (WINDRES_OBJS): New variable.
+ $(WINDRES_PROG): New target.
+ (rcparse.c, rcparse.h, rclex.c): New targets.
+
+Thu Jun 12 12:27:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (export_type): Add data field.
+ (def_exports): Add data parameter. Change all callers.
+ (dump_def_info): Print data field.
+ (gen_def_file): Likewise.
+ (make_one_lib_file): Handle data field by not emitting simple
+ label and not emitting anything in SEC_TEXT.
+ (dtab): Print data field.
+ (process_duplicates): Merge data field.
+ * dlltool.h (def_exports): Update declaration.
+ * defparse.y (expline): Accept opt_DATA. Pass it to def_exports.
+ (opt_DATA): New non-terminal.
+
+Wed Jun 11 17:15:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.h: New file.
+ * deflex.l: Include dlltool.h and libiberty.h. Don't declare
+ strdup. Use xstrdup rather than strdup.
+ * defparse.y: Include bfd.h, bucomm.h, and dlltool.h.
+ * dlltool.c: Include dlltool.h and time.h. Make a lot of
+ variables and functions static. Make a lot of char * variables
+ and parameters const. Add declarations for static functions. Do
+ some reindenting. Hide more PowerPC stuff inside DLLTOOL_PPC.
+
+Wed Jun 11 12:05:52 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * ar.c (bfd_special_undocumented_glue): Add const.
+
+Mon May 12 22:09:35 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * Makefile.in (check): Pass CC_FOR_TARGET and CFLAGS_FOR_TARGET
+ to runtest.
+
+Mon May 12 13:14:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't clear OPCODES when --enable-commonbfdlib is
+ used on HP/UX.
+ * configure: Rebuild.
+
+Fri Apr 25 14:22:08 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * Makefile.in (maintainer-clean realclean): Change *.info*
+ to binutils.info* to save sysroff.info.
+
+Tue Apr 15 13:42:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL): Set to @INSTALL@.
+ (INSTALL_XFORM, INSTALL_XFORM1): Remove.
+ (install): Depend upon installdirs. Use $(program_transform_name)
+ directly, rather than using $(INSTALL_XFORM) and
+ $(INSTALL_XFORM1).
+ (installdirs): New target.
+ (install-info): Run mkinstalldirs.
+
+Mon Apr 14 11:52:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL): Change install.sh to install-sh.
+
+ From Thomas Graichen <graichen@rzpd.de>:
+ * Makefile.in: Always use $(SHELL) when running move-if-change.
+ * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub.
+ * configure: Rebuild.
+
+Fri Apr 4 13:28:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add AC_FUNC_ALLOCA.
+ * configure, config.in: Rebuild.
+ * bucomm.h: Add alloca handling, copied from gas/as.h.
+ * dlltool.c: Add #pragma alloca for AIX to start of file.
+ * nlmconv.c: Likewise.
+
+ * Makefile.in (distclean): Remove site.exp and site.bak. Remove
+ everything that clean removes.
+
+Thu Apr 3 13:18:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (VERSION): Set to 2.8.1.
+
+ * Branched binutils 2.8.
+
+Tue Apr 1 16:21:44 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * configure.com: New file.
+ * config.h-vms: Remove file.
+ * makefile.vms: Update for new configure scheme.
+
+Mon Mar 31 15:30:43 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * objcopy.c (make_same_dates): Use statbuf, not buf, if not
+ HAVE_GOOD_UTIME_H.
+
+Fri Mar 28 17:57:53 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * Makefile.in ($(OBJDUMP_PROG)): Don't link against BFDLIB twice.
+ * configure.in: Add AC_ARG_ENABLE for commonbfdlib. If it is set,
+ set OPCODES to empty.
+ * configure: Rebuild.
+
+Thu Mar 27 16:03:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from Marty Leisner <leisner@sdsp.mc.xerox.com>:
+ * objcopy.c: Include <utime.h> or <sys/time.h>.
+ (strip_options): Add "preserve-dates".
+ (copy_options): Likewise.
+ (copy_usage): Mention -p and --preserve-dates.
+ (strip_usage): Likewise.
+ (make_same_dates): New static function.
+ (strip_main): Handle -p.
+ (copy_main): Likewise.
+ * binutils.texi, strip.1, objcopy.1: Document new option.
+
+ addr2line.c contributed by Ulrich Lauther
+ <Ulrich.Lauther@zfe.siemens.de>:
+ * addr2line.c: New file.
+ * Makefile.in: Rebuild dependencies.
+ (ADDR2LINE_PROG): New variable.
+ (MANPAGES): Add addr2line.
+ (PROGS): Add $(ADDR2LINE_PROG).
+ (CFILES): Add addr2line.c.
+ ($(ADDR2LINE_PROG)): New target.
+ * binutils.texi: Document addr2line.
+ * addr2line.1: New file.
+
+ * version.c (print_version): Update copyright date.
+
+Mon Mar 24 10:52:45 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * objdump.c (disassemble_data): Don't exit if a file cannot be
+ disassembled, instead just return.
+
+Thu Mar 20 21:16:51 1997 Jeffrey A Law (law@cygnus.com)
+
+ * size.c (usage): Make definition match its prototype.
+ (display_bfd, lprint_number, rprint_number): Likewise.
+ (print_berkeley_format, sysv_internal_printer): Likewise.
+ (print_sysv_format): Likewise.
+ * nm.c (set_print_radix, set_output_format): Likewise.
+ * objcopy.c (filter_bytes): Likewise.
+
+Tue Mar 18 16:39:55 1997 H.J. Lu <hjl@lucon.org>
+
+ * Many files: Add function prototypes.
+ * ar.c (mri_emul, get_pos_bfd): Make static.
+ * arlex.l: Include "libiberty.h". Don't declare strdup. Use
+ xstrdup rather than strdup.
+ * arparse.y (yyerror): Make argument const. Correct typo.
+ * arsup.c (strdup): Don't declare.
+ (ar_save): Use xstrdup rather than strdup.
+ * filemode.c: Include "bucomm.h".
+ * nm.c (usage): Make static.
+ (print_symname): Make format and name const.
+ * objcopy.c (cat): Remove.
+ (copy_archive): Make output_target const. Use concat, not cat.
+ (copy_file, simple_copy, smart_rename): Make arguments const.
+ * objdump.c (read_section_stabs): Likewise.
+ (print_section_stabs): Likewise.
+ (display_target_tables): Don't declare getenv.
+ * strings.c (strings_object_file): Change file to const.
+ (print_strings): Change filename to const.
+ * Makefile.in: Rebuild dependencies.
+
+Tue Mar 18 11:37:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add BFD_NEED_DECLARATION(getenv).
+ * acconfig.h: Add NEED_DECLARATION_GETENV.
+ * bucomm.h (getenv): Declare if NEED_DECLARATION_GETENV.
+ * configure, config.in: Rebuild.
+ * nlmconv.c (getenv): Don't declare.
+
+ * Makefile.in: Rebuild dependencies.
+
+Sat Mar 15 15:35:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Jamie Lokier <jamie@rebellion.co.uk>:
+ * objdump.c: Include "demangle.h".
+ (do_demangle): New static variable.
+ (usage): Mention -C/--demangle.
+ (long_options): Add "demangle".
+ (objdump_print_symname): New static function.
+ (objdump_print_addr_with_sym): Use objdump_print_symname.
+ (disassemble_bytes): Likewise.
+ (dump_reloc_set): Likewise.
+ (dump_symbols): Demangle symbol name.
+ (main): Handle -C.
+ * binutils.texi, objdump.1: Document -C/--demangle.
+
+ * objdump.c (usage): Mention --no-show-raw-insn.
+ (long_options): Add "no-show-raw-insn".
+ (disassemble_bytes): Handle --no-show-raw-insn.
+ * binutils.texi, objdump.1: Document --no-show-raw-insn.
+
+Wed Mar 12 11:42:00 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * rddbg.c (free_saved_stabs): Set the strings to NULL after being
+ freed.
+
+Fri Feb 28 17:18:45 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * bucomm.c (set_default_bfd_target): New function.
+ * bucomm.h (set_default_bfd_target): Declare.
+ * ar.c (main): Call set_default_bfd_target.
+ * nlmconv.c (main): Likewise.
+ * nm.c (main): Likewise.
+ * objcopy.c (main): Likewise.
+ * objdump.c (main): Likewise.
+ * size.c (main): Likewise.
+ * strings.c (main): Likewise.
+ * Makefile.in (bucomm.o): New target, to define TARGET.
+
+Tue Feb 25 21:28:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (adjust_section_vma): New static variable.
+ (usage): Mention --adjust-section-vma.
+ (OPTION_ADJUST_VMA): Define.
+ (long_options): Add "addjust-vma".
+ (display_bfd): If adjust_section_vma is not 0, add it to all the
+ section addresses.
+ (main): Handle OPTION_ADJUST_VMA.
+ * binutils.texi, objdump.1: Document --adjust-vma.
+
+Fri Feb 14 18:46:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * nm.c (print_symbol): Cache the BFD as well as the symbols and
+ relocs, and don't try to use the symbols or relocs with a
+ different BFD.
+
+Thu Feb 13 21:34:43 1997 Klaus Kaempf (kkaempf@progis.de)
+
+ * config.h-vms: sbrk() is provided on openVMS/Alpha.
+ * makefile.vms: allow compiling with current gcc snapshot.
+
+Thu Feb 13 20:14:40 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * arsup.c, coffgrok.c, dlltool.c, nlmconv.c: Use xmalloc rather
+ than malloc.
+
+Wed Feb 12 16:12:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (disassemble_data): Correct VMA argument to
+ find_symbol_for_address. Improve handling of code with no symbol
+ followed by code with a symbol.
+
+Wed Feb 12 12:16:47 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * objdump.c (disassemble_bytes): Make output of raw instructions
+ work better for non-standard values of bytes_per_chunk and
+ bytes_per_line.
+
+Thu Feb 6 14:14:59 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * objdump.c (disassemble_bytes): Added code to allow some control
+ over the way raw instructions are displayed.
+
+Thu Feb 6 12:36:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (struct bincl_file): Add next_stack field.
+ (push_bincl): Put the new file on both bincl_list and
+ bincl_stack. Clear the file_types field.
+ (pop_bincl): Use the next_stack field when popping the stack.
+ Don't put the file on bincl_list.
+ (find_excl): Include the file name when warning about an unfound
+ N_EXCL.
+
+ * debug.c (debug_type_samep): Don't crash if we are passed NULL.
+
+Thu Feb 6 11:54:24 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * objcopy.1: Add missing space after .B.
+
+Fri Jan 31 10:33:07 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * objdump.c (disassemble_data): Initialize `aux.require_sec'.
+
+Wed Jan 29 13:21:21 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (objdump_print_value): Add skip_zeroes parameter.
+ Change all callers.
+ (objdump_print_addr_with_sym): Likewise. Call objdump_print_value
+ to print address.
+ (objdump_print_addr): New static function.
+ (objdump_print_address): Just call objdump_print_addr.
+ (disassemble_bytes): Print real address, not function offset.
+ Skip a certain number of leading zeroes.
+
+ * objdump.c (disassemble_zeroes): New static variable.
+ (usage): Mention --disassemble-zeroes.
+ (long_options): Add "disassemble-zeroes".
+ (disassemble_bytes): Check disassemble_zeroes.
+
+Tue Jan 28 16:47:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (disassemble_bytes): Don't skip zeroes if the
+ disassembler has told us that we are in a branch delay slot.
+
+Mon Jan 20 14:24:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * size.c (berkeley_sum): Rewrite. Skip sections which are not
+ SEC_ALLOC. Count SEC_READONLY sections as text.
+
+Tue Jan 14 15:14:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean realclean): Remove *.info*, not
+ just *.info. From H.J. Lu <hjl@lucon.org>.
+
+Tue Dec 31 15:42:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE.
+
+Fri Dec 27 11:19:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Work around bug in AC_FUNC_VFORK in autoconf 2.12.
+ * configure: Rebuild.
+
+Thu Dec 19 13:11:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from Andrew J Klossner <andrew@pogo.wv.tek.com>:
+ * objcopy.c (OPTION_WEAKEN): Define.
+ (copy_options): Add "weaken".
+ (copy_usage): Mention --weaken.
+ (weaken): New static variable.
+ (filter_symbols): Handle weaken.
+ (copy_object): Call filter_symbols if weaken.
+ (copy_main): Handle OPTION_WEAKEN.
+ * binutils.texi, objcopy.1: Document --weaken.
+
+Wed Dec 18 22:49:13 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Use NewFolderRecursive for installation.
+
+Sat Dec 7 10:17:25 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (install): Add "else true" clause to cater to
+ broken "make" on some systems.
+
+Fri Dec 6 17:21:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (parse_ieee_bb): Always initialize namcopy to avoid gcc
+ warning about uninitialized variable.
+ (ieee_read_cxx_class): Likewise, for pf.
+ (ieee_enum_type): Likewise, for i.
+
+Tue Nov 26 17:01:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * wrstabs.c (stab_array_type): Add casts when printing
+ bfd_signed_vma values.
+
+ * configure: Rebuild with autoconf 2.12.
+
+Mon Nov 25 16:53:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (disassemble_data): Don't crash if there is no
+ symbol.
+
+Fri Nov 22 17:29:14 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ar.c (open_inarch): Don't call bfd_openr with a null name.
+
+Fri Nov 1 12:08:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils.texi: Add section on reporting bugs.
+
+Thu Oct 31 18:20:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (struct stab_handle): Add bincl_list field.
+ (parse_stab): Pass value to push_bincl. Call find_excl for
+ N_EXCL.
+ (struct bincl_file): Add hash, file and file_types fields.
+ (push_bincl): Add hash parameter. Save it in the new hash field.
+ Save the file number in the new file field.
+ (pop_bincl): Put the bincl_file on bincl_list, rather than freeing
+ it. Save the file types in the new file_types field.
+ (find_excl): New static function.
+
+ * ieee.c (ieee_lineno): Don't compare line number addresses to
+ info->highaddr (undo part of October 28 patch).
+
+Tue Oct 29 16:40:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (objdump_print_value): Don't print the empty string
+ for zero.
+
+Mon Oct 28 16:58:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (struct stab_handle): Add function_end field.
+ (start_stab): Initialize function_end.
+ (finish_stab): Pass info->function_end to debug_end_function.
+ (parse_stab): If info->function_end is set, use it as the address
+ which ends a function.
+
+ * ieee.c (ieee_array_type): Remember the correct size.
+
+ * ieee.c (ieee_finish_compilation_unit): Permit coalescing ranges
+ that are up to 0x1000 bytes apart, not just 64.
+ (ieee_add_bb11_blocks): Don't bother to emit a BB11 that is less
+ than 0x100 bytes.
+ (ieee_lineno): Only emit line numbers that are less than
+ info->highaddr.
+
+Fri Oct 25 12:12:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (struct ieee_defined_enum): Add defined field.
+ (ieee_enum_type): If the enum tag has been seen before but not
+ defined, reuse the same type index, and define it.
+ (ieee_tag_type): If this enum has not been defined, add an
+ undefined entry to the list of enums.
+
+ * objdump.c (disassemble_bytes): Let the disassembler override the
+ number of bytes printed on a line.
+
+Thu Oct 24 16:42:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (prefix_addresses): New static variable.
+ (long_options): Add "prefix-addresses".
+ (compare_symbols): Sort BSF_FUNCTION symbols before other
+ symbols.
+ (find_symbol_for_address): New static function, broken out of
+ objdump_print_address.
+ (objdump_print_addr_with_sym): New static function, broken out of
+ objdump_print_address.
+ (objdump_print_address): Call new functions.
+ (disassemble_bytes): New static function, broken out of
+ disassemble_data. Change disassembly format, unless
+ prefix_addresses is set.
+ (disassemble_data): Call disassemble_bytes. Unless
+ prefix_addresses is set, disassemble in chunks headed by a
+ symbol.
+ * binutils.texi, objdump.1: Document --prefix-addresses.
+
+ * rddbg.c (read_section_stabs_debugging_info): Preserve the
+ backslash when concatenating multiple stabs strings.
+
+Thu Oct 10 11:36:31 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * dlltool.c (scan_open_obj_file): Fix loop exit test.
+ Add missing parameter to def_exports.
+
+Tue Oct 8 12:06:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (LEX_OPTIONS): Set to empty string. -I -Cem is the
+ default for flex, and is not recognized by lex.
+
+Thu Oct 3 17:41:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils.texi (Target Selection): Document that you can now
+ specify targets using configuration triplets.
+
+ * ar.c (usage): Declare. Make sure all callers pass an argument.
+
+Thu Oct 3 15:39:42 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (clean): Remove config.log.
+
+Wed Oct 2 15:49:16 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Bump version date.
+
+Tue Oct 1 15:00:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * version.c (print_version): New function.
+ * bucomm.h (print_version): Declare.
+ * ar.c (program_version): Don't declare.
+ (do_show_version): Remove.
+ (usage): Add help parameter. Print bug report address.
+ (main): Set is_ranlib at start. Check for --help and --version.
+ Call print_version, not do_show_version.
+ * nlmconv.c (program_version): Don't declare.
+ (main): Call print_version.
+ (show_usage): Print bug report address.
+ * nm.c (program_version, print_version): Don't declare.
+ (usage): Print bug report address.
+ (main): Call print_version.
+ * objcopy.c (program_version): Don't declare.
+ (copy_usage): Print bug report address.
+ (strip_usage): Likewise.
+ (strip_main): Call print_version.
+ (copy_main): Likewise.
+ * objdump.c (program_version): Don't declare.
+ (usage): Print bug report address.
+ (main): Call print_version.
+ * size.c (program_version): Don't declare.
+ (usage): Print bug report address.
+ (main): Call print_version.
+ * strings.c (program_version): Don't declare.
+ (main): Call print_version.
+ (usage): Print bug report address.
+ * Makefile.in: Update dependencies.
+
+Thu Sep 19 14:53:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: Revert Monday's reflocalp patch, and apply this patch
+ instead:
+ (write_ieee_debugging_info): Write a dummy type at the end of the
+ global type block.
+
+Mon Sep 16 15:30:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (struct ieee_write_type): Add reflocalp field.
+ (ieee_pointer_type): Set reflocalp after pushing type.
+ (ieee_function_type): If reflocalp is set, make this type local.
+ (ieee_range_type, ieee_array_type, ieee_set_type): Likewise.
+ (ieee_const_type, ieee_volatile_type): Likewise.
+ (ieee_struct_field, ieee_class_baseclass): Likewise.
+
+ * ieee.c (struct ieee_info): Add global_types field.
+ (parse_ieee_bb): When starting a BB1, initialize the types field
+ to the global_types field.
+ (parse_ieee_be): When ending a BB2, copy the types field to the
+ global_types field.
+
+Fri Sep 13 17:32:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (change_leading_char): New static variable.
+ (OPTION_CHANGE_LEADING_CHAR): Define.
+ (copy_options): Add "change-leading-char".
+ (copy_usage): Mention --change-leading-char.
+ (filter_symbols): Add obfd parameter. Change all callers.
+ Implement change_leading_char.
+ (copy_object): Call filter_symbols if change_leading_char.
+ (copy_main): Handle OPTION_CHANGE_LEADING_CHAR.
+ * binutils.texi, objcopy.1: Document --change-leading-char.
+
+Tue Sep 3 14:05:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_enum_type): Don't check index into a NULL names
+ array.
+ * nm.c (sort_symbols_by_size): Always initialize next.
+ * rdcoff.c (parse_coff_type): Warn about an incomprehensible
+ type rather than crashing.
+ * rddbg.c (read_symbol_stabs_debugging_info): Initialize f.
+ * stabs.c (parse_stab_members): Set context in all cases.
+
+Thu Aug 29 16:56:52 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+ * configure: Regenerate.
+
+Thu Aug 29 11:29:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (L_tmpnam): Never define.
+ (display_target_list): Use choose_temp_base instead of tmpnam.
+ (display_info_table): Likewise.
+
+Tue Aug 27 18:15:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (parse_stab): An N_FUN symbol with an empty string
+ indicates the end of a function.
+
+Thu Aug 22 17:08:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * wrstabs.c (struct string_hash_entry): Add next field.
+ (struct stab_write_handle): Change strings to a pointer to
+ string_hash_entry. Add last_strings field. Remove strings_alloc
+ field.
+ (string_hash_newfunc): Initialize next field.
+ (stab_write_symbol): Copy string into hash table rather than into
+ buffer. Keep a list of hash table entries.
+ (write_stabs_in_sections_debugging_info): Initialize last_string.
+ Copy strings from list of hash table entries in memory.
+ (stab_modify_type): If the entry on the stack is a definition,
+ make a new definition rather than failing an assert.
+ (stab_array_type): The size is only zero if high is strictly less
+ than low.
+
+ * ieee.c (struct ieee_info): Add saw_filename field.
+ (parse_ieee): Initialize saw_filename.
+ (parse_ieee_bb): Set saw_filename for a BB1 or BB2. In a BB1,
+ discard the current variables and types. In a BB10, if no
+ filename has been seen, call debug_set_filename.
+ (parse_ieee_ty): In case 'g', the type is optional.
+
+ * prdbg.c (pr_fix_visibility): Don't abort on
+ DEBUG_VISIBILITY_IGNORE.
+
+ * debug.c (debug_name_type): Correct error message.
+
+ * configure.in: Substitute HLDENV.
+ * configure: Rebuild.
+ * Makefile.in (HLDENV): New variable. Use it whenever linking a
+ program.
+
+Thu Aug 15 19:30:41 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Add symbolic doublequotes around the version
+ number.
+
+Thu Aug 8 12:27:52 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Add better support for DEC C compilation.
+ Add new macros as in Makefile.in.
+
+Wed Aug 7 14:27:33 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * configure.in: Call BFD_NEED_DECLARATION on strstr and sbrk.
+ * acconfig.h (NEED_DECLARATION_STRSTR): New macro.
+ (NEED_DECLARATION_SBRK): New macro.
+ * configure, config.in: Rebuild.
+ * bucomm.h (strstr): Declare if NEED_DECLARATION_STRSTR.
+ (sbrk): Declare if HAVE_SBRK and NEED_DECLARATION_SBRK.
+
+ * prdbg.c (pr_end_struct_type): Avoid using a string constant in
+ assert, for the benefit of broken assert macros.
+
+Fri Jul 26 14:06:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (disassemble_data): Set disasm_info.flavour from
+ abfd.
+
+Tue Jul 23 13:59:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (secdata): In non DLLTOOL_PPC case, change alignment
+ of .text section to 2.
+
+Mon Jul 22 08:46:15 1996 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * objdump.c (dump_section_stabs): Fix test for stabs sections
+ ending with numbers. This fixes a problem with .stab being
+ confused with .stab.index.
+
+Wed Jul 10 13:32:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (stab_demangle_fund_type): Return a void * for a
+ template, rather than simply aborting.
+
+Mon Jul 8 15:28:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ar.c (open_inarch): Add file parameter. Change all callers. If
+ this is a newly created archive, set the target based on the
+ file.
+ * arsup.h (open_inarch): Update declaration.
+
+Thu Jul 4 12:00:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (VERSION): Set to cygnus-2.7.1.
+
+ * Released binutils 2.7.
+
+ * rdcoff.c (parse_coff): Get address to pass to debug_end_function
+ from function size, not value of .ef symbol. From Ning
+ Mosberger-Tang <ning@AZStarNet.com>.
+
+Sat Jun 29 21:18:09 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (strip_main): Add -o option, and handle it.
+ (strip_usage): Mention -o.
+ * binutils.texi, strip.1: Mention -o.
+
+Mon Jun 24 17:19:02 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): Autoconf 2.5 or higher.
+
+Mon Jun 24 11:59:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (endian): New static variable.
+ (usage): Mention -EB/-EL/--endian.
+ (long_options): Add "endian".
+ (disassemble_data): If endianness was specified, replace
+ abfd->xvec with a copy of itself with the given endianness.
+ (main): Handle -EB/-EL/--endian.
+ * binutils.texi, objdump.1: Mention -EB/-EL/--endian.
+
+ * objdump.c: Make most variables and functions static.
+
+ * configure.in: On alpha*-*-osf*, link against libbfd.a if not
+ using shared libraries.
+ * configure: Rebuild with autoconf 2.10.
+
+Sun Jun 23 14:47:36 1996 Kim Knuttila <krk@cygnus.com>
+
+ * dlltool.c (secdata): Changed .rdata to .reldata so .reloc will work.
+ (make_one_lib_file): Removed cruft. (#if 1)
+
+Wed Jun 19 14:46:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (stabs): Change from struct internal_nlist * to
+ bfd_byte *.
+ (print_section_stabs): Fetch stabs information directly, rather
+ than assuming that struct internal_nlist is the right size.
+
+ * binutils.texi: Document change to binary format: file position
+ based on load address, not section VMA.
+
+ * bucomm.h: Define SEEK_SET, SEEK_CUR, and SEEK_END if they are
+ not already defined.
+
+Tue Jun 18 18:25:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DISTSTUFF): Add deflex.c.
+
+Tue Jun 18 15:03:44 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * config.h-vms, makefile.vms: New files.
+
+Mon Jun 17 09:47:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (make_one_lib_file): Use BFD_RELOC_RVA rather than
+ BFD_RELOC_32 in IDATA7.
+
+Wed Jun 12 11:52:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * nm.c (struct get_relocs_info): Define.
+ (line_numbers): New static variable.
+ (long_options): Add "line-numbers".
+ (usage): Mention -l and --line-numbers.
+ (main): Handle -l.
+ (print_symbol): Print line numbers if requested.
+ (get_relocs): New static function.
+ * binutils.texi, nm.1: Document -l/--line-numbers.
+
+Tue Jun 11 20:12:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (dump_reloc_set): Add sec parameter. Change all
+ callers. If with_line_numbers is set, display line numbers of
+ relocation entries.
+ * binutils.texi, objdump.1: Document -l with -r.
+
+Mon Jun 10 23:42:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ar.c (open_inarch): Report BFD error message if an archive can
+ not be recognized. List matching formats if the file is
+ ambiguously recognized.
+ (ranlib_touch): Likewise.
+
+Thu Jun 6 13:56:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * README: Add notes on how to build if you don't have ar.
+
+ * Makefile.in: Remove old incorrect setting of CC.
+
+Tue Jun 4 10:52:49 1996 Tom Tromey <tromey@csk3.cygnus.com>
+
+ * Makefile.in (install): Don't check to see if tooldir exists.
+ Make $(tooldir) and $(tooldir)/bin.
+
+Mon Jun 3 17:40:23 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * strings.c (main): Make main an int function, not void.
+
+Fri May 31 13:59:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * nm.c (filter_symbols): Check for BSF_WEAK as well as
+ BSF_GLOBAL.
+ * objcopy.c (filter_symbols): Likewise.
+
+Wed May 8 16:57:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (copy_object): Make clear that it is only a warning
+ when the output file can not represent the architecture.
+
+Fri May 3 11:30:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (disassemble_data): Don't refer to bytes past the end
+ of data.
+
+Wed Apr 24 14:10:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * rddbg.c (read_symbol_stabs_debugging_info): Move call to
+ free_saved_stabs outside the loop over the symbols.
+
+Tue Apr 23 12:56:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (compare_symbols): Sort symbols whose names start with
+ `.' after other symbols. If no other decision can be made, sort
+ symbols by name.
+
+Thu Apr 18 16:02:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dep-in.sed: Substitute $(BFDDIR) for @BFDDIR@.
+ * Makefile.in: Rebuild dependencies.
+ (dep.sed): Substitute $(BFDDIR) for @BFDDIR@.
+
+Tue Apr 16 13:50:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * rdcoff.c: New file.
+ * rddbg.c (read_debugging_info): Read COFF symbols if COFF flavour
+ and no stabs were found.
+ * budbg.h (parse_coff): Declare.
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Add rdcoff.c.
+ (DEBUG_OBJS): Add rdcoff.o.
+
+Mon Apr 15 15:55:01 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * nlmconv.c (choose_temp_base{,_try}): Delete, in libiberty now.
+ (link_inputs): Update call to choose_temp_base.
+
+Mon Apr 8 14:40:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+ * configure: Rebuild.
+
+Fri Mar 29 16:11:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (dump_section_header): Print the SEC_LINK_ONCE flag
+ and the SEC_LINK_DUPLICATES field.
+
+Fri Mar 29 11:35:55 1996 J.T. Conklin (jtc@lisa.cygnus.com)
+
+ * nlmconv.1: Changed to be recognized by catman -w on Solaris.
+
+Thu Mar 28 14:17:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * wrstabs.c (stab_enum_type): Set buf before using it.
+
+Fri Mar 22 15:49:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (struct stab_handle): Add field abfd.
+ (start_stab): Add abfd parameter.
+ (parse_stab_string): Skip the symbol leading char when searching
+ for the value of a global symbol.
+ * budbg.h (start_stab): Update declaration.
+ * rddbg.c (read_section_stabs_debugging_info): Pass abfd to
+ start_stab.
+ (read_symbol_stabs_debugging_info): Likewise.
+
+Thu Mar 21 12:40:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * wrstabs.c (stab_function_type): Output an empty typedef for an
+ unused argument, rather than making up a meaningless name.
+ (stab_variable): Use N_RSYM for a DEBUG_REGISTER variable.
+
+ * ieee.c (struct ieee_info): Add global_vars field.
+ (parse_ieee_be): When ending the global typedef block, copy the
+ variables into info->global_vars.
+ (parse_ieee_atn): Don't require an NN record for a pmisc ATN.
+ (ieee_read_reference): Search the global variables after the local
+ variables.
+
+Wed Mar 20 18:08:19 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * objdump.c (disassemble_data): Make sure sym_name is always set.
+ (dump_section_header): Always put a space after the section name.
+ (dump_bfd_header): Terminate output with newline.
+
+Wed Mar 20 16:35:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * wrstabs.c: New file.
+ * budbg.h (write_stabs_in_sections_debugging_info): Declare.
+ * objcopy.c (write_debugging_info): For COFF or ELF, output stabs
+ in sections.
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Add wrstabs.c.
+ (WRITE_DEBUG_OBJS): New variable.
+ ($(OBJCOPY_PROG)): Use $(WRITE_DEBUG_OBJS), not $(DEBUG_OBJS).
+ ($(STRIP_PROG)): Likewise.
+
+ * stabs.c (parse_stab_members): Make type stub detection more like
+ gdb.
+
+ * ieee.c (struct ieee_handle): Add fields complex_float_index and
+ complex_double_index.
+ (ieee_complex_type): Cache type index in complex_float_index and
+ complex_double_index, depending upon size. Set size on type stack
+ to size * 2.
+
+ * ieee.c (ieee_empty_type): Use builtin_unknown, not 0.
+ (ieee_void_type): Use builtin_void, not 1.
+
+ * ieee.c (parse_ieee_ty): Handle 'V' type code.
+ (parse_ieee_atn): Don't require two numbers for type 10.
+
+ * ieee.c (parse_ieee_be): Add one to offset at end of function or
+ block.
+
+ * ieee.c (struct ieee_block): Add field skip.
+ (parse_ieee_bb): Don't call debug_record_function for __XRYCPP
+ function, and set skip field.
+ (parse_ieee_be): Don't call debug_end_function if skip is set.
+
+ * debug.c (struct debug_handle): Add fields current_write_lineno
+ and current_write_lineno_index.
+ (debug_write): Initialize current_write_lineno and
+ current_write_lineno_index for each unit. Call
+ debug_write_linenos rather than writing out the line numbers
+ directly.
+ (debug_write_function): Call debug_write_linenos.
+ (debug_write_block): Likewise.
+ (debug_write_linenos): New static function.
+
+ * debug.c (debug_write_type): For DEBUG_KIND_FUNCTION, push return
+ type before arguments.
+
+Mon Mar 18 18:05:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add AC_FUNC_VFORK.
+ * configure, config.in: Rebuild.
+ * dlltool.c, nlmconv.c: Include <vfork.h> if HAVE_VFORK_H is
+ defined.
+
+ * stabs.c (parse_stab_range_type): A complex type is defined as a
+ subrange of itself with the high bound zero.
+ * ieee.c (ieee_complex_type): Don't crash on sizes of 12 or 16.
+
+Tue Mar 12 12:09:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_write_undefined_tag): Switch to global_types even
+ if it is not empty.
+ (ieee_tag_type): For an enum, look through info->enums.
+
+ * configure: Rebuild with autoconf 2.8.
+
+ * debug.c (debug_type_samep): Don't loop endlessly in
+ DEBUG_KIND_ENUM case. From Eric Baur <ecb@nexen.com>.
+
+Mon Mar 11 12:35:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * rddbg.c (read_section_stabs_debugging_info): Call save_stab for
+ each stab entry, call stab_context on an error, and call
+ free_saved_stabs before rturning.
+ (read_symbol_stabs_debugging_info): Likewise.
+ (SAVE_STABS_COUNT): Define.
+ (struct saved_stab): Define.
+ (saved_stabs, saved_stabs_index): New static variables.
+ (save_stab, stab_context, free_saved_stabs): New static functios.
+
+ * objdump.c (stab_name): Remove.
+ (struct stab_print): Remove.
+ (stab_print): Remove.
+ (dump_stabs): Don't initialize stab_name.
+ (print_section_stabs): Call bfd_get_stab_name rather than using
+ the stab_name array.
+
+Tue Feb 27 19:52:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * prdbg.c (pr_int_constant): Initialize info correctly.
+ (pr_float_constant): Likewise.
+
+Mon Feb 26 18:11:37 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update to handle shared library support.
+
+Sat Feb 24 11:21:49 1996 Alan Modra <alan@spri.levels.unisa.edu.au>:
+
+ * Makefile.in ($(OBJDUMP_PROG)): Search $(BFDLIB) before
+ $(OPCODES).
+
+Thu Feb 15 12:44:45 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't tamper with LDFLAGS. Call AC_PROG_CC before
+ configure.host.
+ * configure: Rebuild.
+
+ * configure.in: Substitute RPATH_ENVVAR.
+ * configure: Rebuild.
+ * Makefile.in (RPATH_ENVVAR): New variable.
+ (check): Use $(RPATH_ENVVAR) rather than LD_LIBRARY_PATH.
+
+ * objcopy.c (smart_rename): Rather than doing chmod then chown, do
+ chmod without setuid, then chown, then chmod with setuid.
+
+Wed Feb 14 16:46:42 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de>
+
+ * arsup.c (map_over_list): Reindent. Don't assume that the
+ function does not delete the BFD.
+ (ar_addlib_doer): Don't set prev->next if prev is NULL.
+
+Wed Feb 14 15:12:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_regno_to_genreg): Convert register numbers for m68k
+ and i960.
+ (ieee_genreg_to_regno): Likewise.
+
+Mon Feb 12 14:19:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: Extensive changes to write code to put types in the
+ global type block when possible, to output ranges for all memory
+ occupied by the module, and to improve efficiency.
+
+ * debug.c (struct debug_handle): Remove class_mark field. Add
+ id_list and compare_list fields.
+ (struct debug_class_id): Define.
+ (struct debug_type_compare_list): Define.
+ (debug_write): Initialize info->id_list
+ (debug_write_name): Remove reference to info->class_mark.
+ (debug_write_type): Get id for all structs and classes. Simplify
+ test for whether struct has already been written.
+ (debug_write_class_type): Get id for all classes. Simplify test
+ for whether class has already been written.
+ (debug_write_block): Don't write out blocks other than the top
+ level block if they have no local variables.
+ (debug_set_class_id): New static function.
+ (debug_type_samep): New static function.
+ (debug_class_type_samep): New static function.
+ * prdbg.c (pr_start_struct_type): Always print id.
+ (pr_start_class_type): Likewise.
+ (pr_tag_type): Likewise.
+
+ * stabs.c (struct stab_handle): Add syms and symcount fields.
+ (start_stab): Add syms and symcount parameters. Change all
+ callers.
+ (parse_stab_string): Look up global variables in the symbol table
+ to get the right value.
+ * budbg.h (start_stab): Update declaration.
+ * rddbg.c (read_section_stabs_debugging_info): Add syms and
+ symcount parameters. Change all callers.
+
+ * stabs.c (parse_stab_array_type): If the index type is 0, use
+ int.
+
+Wed Feb 7 14:17:45 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c (ieee_start_compilation_unit): Clear modified and
+ modified_alloc fields of info.
+
+ * configure.in: Check for --enable-shared. Substitute new
+ variables BFDLIB and OPCODES.
+ * configure: Rebuild.
+ * Makefile.in (BFDLIB): Set to @BFDLIB@.
+ (OPCODES): Set to @OPCODES@.
+
+Mon Feb 5 16:18:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Support for building bfd and opcodes as shared libraries, based on
+ patches from Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in (HLDFLAGS): New substitution.
+ * configure: Rebuild.
+ * Makefile.in (HLDFLAGS): New variable. Make all links use
+ $(HLDFLAGS) before $(CFLAGS) and $(LDFLAGS).
+ (BFDLIB_DEP): New variable. Replace all occurrences of $(BFD) as
+ a dependency with $(BFDLIB_DEP). Remove $(BFD) as a dependency if
+ there is also a dependency on $(ADDL_DEPS).
+ (BFDLIB): Rename from BFD; change all uses; set to -L../bfd -lbfd.
+ (OPCODES_DEP): New variable. Replace all occurrends of $(OPCODES)
+ as a dependency with $(OPCODES_DEP).
+ (OPCODES): Set to -L../opcodes -lopcodes.
+ (ADDL_DEPS): New variable. Replace all occurrences of
+ $(ADDL_LIBS) as a dependency with $(ADDL_DEPS).
+ (check): Set LD_LIBRARY_PATH in the environment.
+ (config.status): Depend upon BFD configure.host and config.bfd.
+
+Fri Feb 2 17:02:59 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * objdump.c: #include stdarg.h or varargs.h.
+ (objdump_print_value): Change FILE* arg to struct disassemble_info*.
+ All callers updated. Use fprintf_func.
+ (objdump_print_address): Consistently use fprintf_func.
+ (objdump_sprintf): New function.
+ (disassemble_data): Print insn into a buffer, print raw insn ourselves,
+ then print insn mnemonic.
+
+Fri Feb 2 16:48:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Regenerate.
+
+Thu Feb 1 09:38:18 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i[3-6]86-*-win32): Becomes i[3-6]86-*-cygwin32.
+ (powerpc*-*-cygwin32): New.
+ * configure: Regenerated.
+
+Wed Jan 31 13:22:03 1996 Richard Henderson <rth@tamu.edu>
+
+ * Makefile.in (distclean): Remove $(DEMANGLER_PROG).1.
+
+Mon Jan 29 17:36:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from H J Lu <hjl@zoom.com>:
+ * objcopy.c (remove_leading_char): New static variable.
+ (OPTION_REMOVE_LEADING_CHAR): Define.
+ (copy_usage): Mention --remove-leading-char.
+ (filter_symbols): If remove_leading_char, and the first character
+ of a global symbol matches the symbol leading char of the BFD,
+ remove the first character.
+ (copy_object): Filter the symbols if remove_leading_char is set.
+ (copy_main): Handle --remove-leading-char.
+ * binutils.texi, objcopy.1: Document --remove-leading-char.
+
+Sat Jan 27 15:40:13 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * objdump.c (fprintf): Add prototype to avoid compiler warning on
+ SunOS.
+
+Fri Jan 26 11:53:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils.texi (nm): Improve documentation on symbol types.
+ (objdump): Reference the stabs manual from the discussion of the
+ --stabs option.
+
+Thu Jan 25 11:21:46 1996 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw-make.sed: Add a "stamps" target.
+
+Thu Jan 25 13:51:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (dump_headers, dump_section_header): Change objdump -h
+ output to be simpler and to include section file offsets.
+
+Wed Jan 24 12:06:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (parse_stab_members): Don't adjust voffset.
+
+ * ieee.c (ieee_read_cxx_class): Don't multiply voffset by 4.
+ (struct ieee_write_type): Add name field.
+ (struct ieee_type_class): Remove name field. Change all uses to
+ use new name field in type instead.
+ (struct ieee_name_type): Likewise.
+ (ieee_start_struct_type): Initialize name field of type.
+ (ieee_start_class_type): Don't initialize classdef entry of tag.
+ (ieee_class_method_var): Don't adjust voffset.
+ (ieee_end_class_type): Likewise.
+ (ieee_tag_type): Initialize new name field of type.
+ (ieee_typdef): Set name after copying in type information.
+
+ * debug.c (VOFFSET_STATIC_METHOD): Define as -1, not 1.
+
+ * ieee.c (struct ieee_modified_type): Define.
+ (struct ieee_handle): Add modified and modified_alloc fields.
+ (ieee_get_modified_info): New static function.
+ (ieee_pointer_type): Cache type index.
+ (ieee_const_type): Likewise.
+ (ieee_volatile_type): Likewise.
+
+ * ieee.c (ieee_define_named_type): When creating a tag for an
+ anonymous struct, copy the name into memory.
+ (ieee_tag_type): Likewise.
+ * debug.c (debug_write_type): Only check and set id field for an
+ unnamed object.
+ (debug_write_class_type): Likewise.
+
+ * ieee.c: Various changes to write out types for functions and
+ references, and to not write out unnecessary function types.
+
+ * ieee.c (struct ieee_var): Remove variable field. Add kind
+ field, and define some enum constants for it.
+ (parse_ieee_ty): Set kind field of variable for 'x' and 'X' types.
+ (parse_ieee_atn): Make an indirect slot for an external variable,
+ although we otherwise don't record it. Set kind field rather than
+ variable field of pvar.
+ (ieee_read_cxx_class): Try to get the type of a static member.
+ (ieee_read_reference): Check kind field rather than variable
+ field.
+
+Tue Jan 23 15:54:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: Various changes to handle reading C++ reference type
+ information.
+
+ * debug.h (enum debug_var_kind): Add DEBUG_VAR_ILLEGAL.
+ (enum debug_parm_kind): Add DEBUG_PARM_ILLEGAL.
+ * debug.c (debug_get_parameter_types): Handle DEBUG_KIND_FUNCTION.
+
+ * ieee.c: Various changes to write out definitions of C++ classes.
+
+ * debug.c (debug_append_filename): Remove.
+ * debug.h (debug_append_filename): Don't declare.
+
+ * stabs.c (struct stab_handle): Remove last_type field. Add
+ so_string and so_value fields.
+ (finish_stab): Call stab_emit_pending_vars before calling
+ debug_end_function. Don't warn about pending variables.
+ (parse_stab): Accumulate N_SO strings until a non N_SO symbol is
+ seen, rather than calling debug_append_filename. Call
+ stab_emit_pending_vars before calling debug_end_function. Don't
+ set info->last_type.
+
+Tue Jan 23 09:53:54 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * objdump.c (disassemble_data): Handle unknown endianness.
+ Pass fprintf to INIT_DISASSEMBLE_INFO.
+
+Mon Jan 22 16:46:43 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ Add new option --show-raw-insn.
+ * objdump.c (show_raw_insn): New global.
+ (usage): Update.
+ (long_options): Update.
+ (disassemble_data): Set disasm_info.flags if --show-raw-insn.
+
+ * objdump.c (disassemble_data): Set new arch,mach,endian fields in
+ disasm_info.
+
+Mon Jan 22 19:29:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: Extensive changes to pass a single info argument around
+ in the reading routines, rather than several arguments. Add code
+ to read C++ debugging records.
+
+ * debug.h (debug_get_type_size): Declare.
+ (debug_get_field_name): Declare.
+ (debug_get_field_bitpos): Declare.
+ (debug_get_field_bitsize): Declare.
+ (debug_get_field_visibility): Declare.
+ (debug_get_field_physname): Declare.
+ * debug.c (debug_get_real_type): Handle DEBUG_KIND_TAGGED.
+ (debug_get_type_size): New function.
+ (debug_get_field_name): New function.
+ (debug_get_field_bitpos): New function.
+ (debug_get_field_bitsize): New function.
+ (debug_get_field_visibility): New function.
+ (debug_get_field_physname): New function.
+ (debug_write_type): Make sure we pass the real kind, not INDIRECT,
+ to tag_type. Pass the name recursively for INDIRECT.
+
+Fri Jan 19 12:31:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * debug.h (struct debug_write_fns): Remove ellipsis_type. Add int
+ and boolean parameters to function_type. Add boolean parameter to
+ method_type.
+ (debug_make_ellipsis_type): Don't declare.
+ (debug_make_function_type): Add debug_type * and boolean
+ parameters. Change all callers.
+ (debug_make_method_type): Add boolean parameter. Change all
+ callers.
+ (debug_get_parameter_types): Add boolean * parameter. Change all
+ callers.
+ (debug_get_target_type): Declare.
+ * debug.c (struct debug_function_type): Add fields arg_types and
+ varargs.
+ (struct debug_method_type): Add field varargs.
+ (debug_ellipsis_type, ELLIPSIS_P): Remove.
+ (debug_make_ellipsis_type): Remove.
+ (debug_make_function_type): Add arg_types and varargs parameters.
+ (debug_make_method_type): Add varargs parameter.
+ (debug_get_parameter_types): Add pvarargs parameter.
+ (debug_get_target_type): New function.
+ (debug_write_type): In case DEBUG_KIND_FUNCTION, push argument
+ types and pass count to function_type. In DEBUG_KIND_METHOD, use
+ a signed int for the count, don't call ellipsis_type, and pass
+ varargs to method_type.
+ * stabs.c (struct stab_demangle_info): Add varargs field.
+ (stab_demangle_argtypes): Add pvarargs parameter. Change all
+ callers.
+ (stab_demangle_args): Likewise.
+ (stab_demangle_type): In case 'F', pick up argument types.
+ * prdbg.c (pr_ellipsis_type): Remove.
+ (pr_function_type): Add argcount and varargs parameters.
+ (pr_method_type): Add varargs parameter.
+ * ieee.c (ieee_ellipsis_type): Remove.
+ (ieee_function_type): Add argcount and varargs parameters.
+ (ieee_method_type): Add varargs parameter. Remove most of
+ function body, and just call ieee_function_type.
+
+ * stabs.c: Include "demangle.h". Added several new static
+ functions not listed below to demangle argument types; they are
+ all called via stab_demangle_argtypes.
+ (finish_stab): If the kind of an undefined tag is
+ DEBUG_KIND_ILLEGAL, use DEBUG_KIND_STRUCT instead. Warn if there
+ are any pending variable.
+ (parse_stab): Don't close the function when the block depth goes
+ to zero. Pass value to debug_end_function.
+ (parse_stab_string): In case 'T', pass the name to
+ parse_stab_type.
+ (parse_stab_type): In case 'x', use stab_find_tagged_type. In
+ case '#', handle functions with variable numbers of arguments.
+ (parse_stab_struct_type): Add tagname parameter. Change all
+ callers.
+ (parse_stab_members): Add tagname and typenums parameters. Change
+ all callers. If the type of a method is a stub, call
+ parse_stab_argtypes to demangle the argument types and get the
+ physical name of the function.
+ (parse_stab_argtypes): New static function.
+ (stab_record_variable): For a DEBUG_GLOBAL or DEBUG_STATIC
+ variable, call debug_record_variable immediately.
+ (stab_find_tagged_type): New static function.
+
+ * debug.h (enum debug_type_kind): Add DEBUG_KIND_ILLEGAL.
+ (struct debug_write_fns): Add field ellipsis_type. Add id
+ parameter to start_struct_type, start_class_type, and tag_type.
+ (debug_make_ellipsis_type): Declare.
+ (debug_find_named_type): Declare.
+ (debug_get_type_kind): Declare.
+ (debug_get_return_type): Declare.
+ (debug_get_parameter_types): Declare.
+ (debug_get_fields): Declare.
+ (debug_get_field_type): Declare.
+ * debug.c (struct debug_handle): Add fields class_id and base_id.
+ (struct debug_class_type): Add field id.
+ (struct debug_method_variant): Rename argtypes to physname.
+ Change all uses.
+ (debug_ellipsis_type): New static variable.
+ (ELLIPSIS_P): New macro.
+ (debug_make_ellipsis_type): New function.
+ (debug_make_method_variant): Rename argtypes to physname.
+ (debug_make_static_method_variant): Likewise.
+ (debug_name_type): Always put types in the global namespace.
+ (debug_find_named_type): New function.
+ (debug_find_tagged_type): Treat DEBUG_KIND_ILLEGAL specially,
+ rather than DEBUG_KIND_VOID.
+ (debug_get_real_type): New static function.
+ (debug_get_type_kind): New function.
+ (debug_get_return_type): New function.
+ (debug_get_parameter_types): New function.
+ (debug_get_fields): New function.
+ (debug_get_field_type): New function.
+ (debug_write): Initialize base_id.
+ (debug_write_type): Pass new id argument to tag_type. Handle
+ DEBUG_KIND_ILLEGAL. Use id for DEBUG_KIND_STRUCT and
+ DEBUG_KIND_UNION. Handle ellipsis for method arguments.
+ (debug_write_class_type): Don't dereference kclass if it is NULL.
+ Use id.
+ * prdbg.c (pr_fns): Add pr_ellipsis_type.
+ (pr_ellipsis_type): New static function.
+ (pr_pointer_type): If this is a pointer to an array, parenthesize
+ it correctly.
+ (pr_start_struct_type): Add id parameter.
+ (pr_start_class_type): Likewise.
+ (pr_tag_type): Likewise.
+ (pr_fix_visibility): Add the visibility to the top of the stack,
+ not the second element on the stack.
+ (pr_struct_field): Pop the stack before calling pr_fix_visibility.
+ (pr_class_static_member): Likewise.
+ (pr_class_start_method): Don't push a type, just set the method
+ name in the type on the top of the stack.
+ (pr_class_end_method): Don't pop the stack.
+ (pr_class_method_variant): Rename argtypes parameter to physname.
+ Append const and volatile rather than prepending them. Add a
+ space after the physname.
+ (pr_class_static_method_variant): Likewise.
+ * ieee.c (ieee_fns): Add ieee_ellipsis_type.
+ (ieee_define_named_type): Use DEBUG_KIND_ILLEGAL rather than
+ DEBUG_KIND_VOID.
+ (write_ieee_debugging_info): Likewise.
+ (ieee_typdef): Likewise.
+ (ieee_ellipsis_type): New static function.
+ (ieee_start_struct_type): Add id parameter.
+ (ieee_start_class_type): Likewise.
+ (ieee_tag_type): Likewise.
+ (ieee_class_method_variant): Rename name to physname.
+ (ieee_class_static_method_variant): Likewise.
+
+ * Makefile.in (DEBUG_OBJS): Remove prdbg.o.
+ ($(OBJDUMP_PROG)): Depend upon, and link against, prdbg.o.
+
+Thu Jan 18 17:35:06 1996 Kim Knuttila <krk@cygnus.com>
+
+ * dlltool.c (make_tail): Changed the order of the sections to avoid
+ an alignment problem.
+
+Wed Jan 17 14:23:00 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * srconv.c (wr_du): Set du.stackfrmt to 0.
+ (wr_un, wr_sc): Emit all sections, even those with 0 size.
+
+Tue Jan 16 16:15:49 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * srconv.c (wr_hd): Space size within segment was being
+ stored in segment identifier field.
+
+Tue Jan 16 12:07:25 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in (BUILD_NLMCONV, BUILD_SRCONV, SYSINFO_PROG,
+ BUILD_DLLTOOL): Put definitions for these into makefile when
+ configuring, instead of always clearing in mpw-make.sed.
+ * mpw-make.sed: Edit out any host_alias or target_alias settings,
+ fix pathname to BFD internal include files, remove dependency
+ calculation rules.
+
+Thu Jan 11 17:31:38 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * objdump.c (dump_section_header): Add new section flags
+ SEC_{EXCLUDE,SORT_ENTRIES}.
+
+Thu Jan 11 11:45:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (filter_symbols): NULL terminate the output symbols.
+ (copy_object): Allocate space for a possible extra NULL pointer.
+
+ * debug.c (debug_make_undefined_tagged_type): Make sure we are
+ given a kind of type we can handle.
+ (debug_write_type): Handle undefined enums and structs.
+ (debug_write_class_type): Handle undefined classes.
+ * prdbg.c (pr_enum_type): Handle an undefined enum.
+ * ieee.c (ieee_enum_type): Likewise.
+
+Wed Jan 10 15:33:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Updated dependencies.
+ (ALLOCA, MALLOC): Remove variables.
+ (ADDL_LIBS): Remove $(MALLOC) from definition.
+ * alloca.c, gmalloc.c: Remove.
+
+Mon Jan 8 18:02:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: Add global function write_ieee_debugging_info and a
+ bunch of static functions and structs used to write out IEEE
+ debugging information.
+ * budbg.h (write_ieee_debugging_info): Declare.
+
+ * ieee.c (struct ieee_type): Add pslot field.
+ (enum builtin_types): Define.
+ (ieee_builtin_type): For a pointer, return a pointer to the named
+ type. Use enum values rather than numbers.
+ (ieee_alloc_type): New static function.
+ (ieee_read_type_index): Use ieee_alloc_type.
+ (parse_ieee_bb): Likewise.
+ (parse_ieee_ty): Likewise. Use ieee_builtin_type for array range,
+ rather than making a new integer type. Store the new type in the
+ slot, if there is one.
+ (parse_ieee_atn): Treat ATN10 as defining a register variable.
+ (ieee_regno_to_genreg): Rename from ieee_regno_to_gen. Change all
+ callers.
+ (ieee_genreg_to_regno): New static function.
+
+ * stabs.c (parse_stab_type): Add new typename parameter. Change
+ all callers.
+ (parse_stab_range_type): Add new typename parameter. Change all
+ callers.
+
+ * debug.h (struct debug_write_fns): Add tag parameter to
+ enum_type, start_struct_type, and start_class_type.
+ * debug.c (debug_write_type): Pass any tag name to
+ start_struct_type, debug_write_class_type, and enum_type. If
+ DEBUG_KIND_TAGGED, pass the name in the recursive call.
+ (debug_write_class_type): Accept a new tag parameter, and pass it
+ to start_class_type.
+ * prdbg.c (pop_type): Don't remove '+' character.
+ (pr_enum_type): Accept and use tag parameter.
+ (pr_start_struct_type): Likewise.
+ (pr_start_class_type): Likewise.
+ (pr_class_baseclass): Adjust algorithm used to find where to put
+ the baseclass name.
+ (pr_tag): Don't bother to insert the tag name.
+
+ * objcopy.c: Include budbg.h.
+ (convert_debugging): New static variable.
+ (OPTION_DEBUGGING): Define.
+ (copy_options): Add "debugging".
+ (copy_usage): Mention --debugging.
+ (is_strip_section): Skip debugging sections if convert_debugging.
+ (setup_section, copy_section): Likewise.
+ (filter_symbols): Skip debugging symbols if convert_debugging.
+ (copy_object): If convert_debugging, read and write debugging
+ information.
+ (write_debugging_info): New static function.
+ (copy_main): Handle --debugging.
+ * Makefile.in (DEBUG_OBJS): New variable.
+ ($(OBJCOPY_PROG)): Depend upon and link against $(DEBUG_OBJS).
+ ($(STRIP_PROG)): Likewise.
+ (OBJDUMP_OBJS): Remove variable.
+ ($(OBJDUMP_PROG)): Use objdump.o $(DEBUG_OBJS) rather than
+ $(OBJDUMP_OBJS).
+ * binutils.texi, objcopy.1: Document --debugging.
+
+Thu Jan 4 16:31:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.c: New file with code to read IEEE debugging information.
+ * budbg.h (parse_ieee): Declare.
+ * rddbg.c (read_debugging_info): Handle IEEE flavour files.
+ (read_ieee_debugging_info): New static function.
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Add ieee.c.
+ (OBJDUMP_OBJS): Add ieee.o.
+
+ * bucomm.h (xrealloc): Change type of first parameter from char *
+ to PTR.
+
+Tue Jan 2 17:44:07 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Add targets to automatically rebuild dependencies.
+ Remove targets which just listed dependencies of .o files.
+ (DEP): New variable.
+ (HFILES, GENERATED_HFILES): New variables.
+ (CFILES, GENERATED_CFILES): New variables.
+ (underscore.c): Don't do anything, just depend upon stamp-under.
+ (stamp-under): New target; do what underscore.c used to do.
+ (nlmconv.o): Depend upon sym.h and ecoff.h.
+ (.dep, .dep1, dep.sed, dep, dep-in): New targets.
+ (stage1, stage2, stage3, against, comparison): Remove.
+ (de-stage1, de-stage2, de-stage3): Remove.
+ (clean, distclean): Remove stamp-under and dep.sed.
+ * dep-in.sed: New file.
+
+ Implement generic debugging support. Implement a stabs reader and
+ a generic printer.
+ * budbg.h, debug.c, debug.h, prdbg.c, rddbg.c, stabs.c: New files.
+ * objdump.c: Include "debug.h" and "budbg.h".
+ (dump_debugging): New global variable.
+ (usage): Mention --debugging.
+ (long_options): Add "debugging".
+ (display_bfd): Handle --debugging.
+ * Makefile.in (OBJDUMP_OBJS): New variable.
+ ($(OBJDUMP_PROG)): Use $(OBJDUMP_OBJS).
+ * binutils.texi, objdump.1: Document --debugging.
+
+Sat Dec 30 09:59:51 1995 Jeffrey A Law (law@cygnus.com)
+
+ * nm.c ( long_options): Add "--defined-only" option.
+ (usage): Update for new "--defined-only" option.
+ (filter_symbols): Handle "--defined-only".
+
+Fri Dec 29 16:04:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * arparse.y: Include "bucomm.h", not <sysdep.h>.
+ * nlmheader.y: Don't include "sysdep.h".
+
+Tue Dec 26 18:23:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * nm.c (print_symdef_entry): Check return value of
+ bfd_get_elt_at_index.
+
+Sat Dec 23 11:03:16 1995 Michael Meissner <meissner@tiktok.cgynsu.com>
+
+ * configure.in (DLLTOOL_DEFS): Build dlltool for PowerPC if target
+ is powerpc*-*-win* in addition to powerpc*-*-*pe*.
+
+Fri Dec 15 16:30:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (endian_string): New static function.
+ (display_target_list): Use it.
+ * nlmconv.c (main): Use new bfd_big_endian macro.
+
+Fri Dec 15 07:51:34 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (fill_ordinals): Start from 1 if no other instructions
+ given.
+
+Tue Dec 12 12:05:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (clean): Remove $(DEMANGLER_PROG).1. From Ronald
+ F. Guilmette <rfg@monkeys.com>.
+
+Mon Dec 11 14:33:05 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mac-binutils.r: Fix copyright and version strings.
+
+ * Makefile.in (version): Remove, no longer used.
+
+Fri Dec 1 14:41:56 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed (install, install-only): Edit in Mac-specific
+ install procedure.
+
+Thu Nov 30 20:26:02 1995 Kim Knuttila <krk@cygnus.com>
+
+ * dlltool.c (ppc_jtab): The binary glue for PowerPC dll linkage,
+ including the return instruction.
+ sinfo: added a preferred alignment field.
+ (secdata): section data for the PowerPC version.
+ (make_one_lib_file): More symbols, More sections (pdata, rdata)
+ (make_tail): Use idata$6 instead of idata$7 for ppc. Also added a
+ NULL idata$3 descriptor (temporary).
+
+Tue Nov 28 17:23:44 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * dlltool.c (fill_ordinals): Don't reference d_export_vec if
+ there are no exported functions.
+
+Mon Nov 27 13:05:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Regenerate with autoconf 2.7.
+
+Wed Nov 22 13:17:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c (fill_ordinals): Start assigning ordinals at 1.
+
+ * Makefile.in (EXPECT): Use $$r, not $${rootme}.
+ (check): Set r, not rootme.
+
+Tue Nov 21 18:04:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use BFD_NEED_DECLARATION.
+ * acconfig.h: Put NEED_DECLARATION_FPRINTF in @TOP@ section.
+ * configure, config.in: Rebuild with autoconf 2.6.
+
+Fri Nov 17 10:34:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): Use @host@ and @target@, not
+ $(host_canonical) and $(target_canonical).
+
+Thu Nov 16 03:39:20 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Version 2.6 released.
+ * Makefile.in (VERSION): Update to 2.6.
+
+Wed Nov 15 12:14:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): Define.
+ (check): Pass CC and CFLAGS to runtest.
+
+ * nm.c (display_rel_file): Don't require a DYNAMIC object when
+ dumping the dynamic symbol table.
+
+ * objdump.c (compare_symbols): Sort global symbols before local
+ symbols before debugging symbols.
+ (objdump_print_address): Don't futz around looking for a global
+ symbol with the same value.
+
+Tue Nov 14 17:19:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * dlltool.c: Use FOPEN_* macros rather than "r" or "w".
+
+ * dlltool.c (fill_ordinals): Correct memset call.
+
+Sun Nov 12 12:56:05 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed (DEMANGLER_PROG): Edit out attempts to do anything
+ with the man page.
+
+Fri Nov 10 11:41:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (setup_section): Copy the section lma independently of
+ the vma.
+
+Wed Nov 8 11:33:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * arsup.c (ar_open): Cast malloc return value.
+
+Tue Nov 7 09:01:26 1995 Kim Knuttila <krk@cygnus.com>
+
+ * configure.in, configure (DLLTOOL_DEFS): Added ppc target.
+ * dlltool.c (MPPC): Added basic PPC definitions.
+
+Tue Nov 7 14:02:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't treat rs6000-*-lynx* specially.
+ * configure: Rebuild.
+ * config/rslynx: Remove.
+ * Makefile.in: Remove @target_makefile_fragment@.
+
+Mon Nov 6 15:00:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bucomm.h: Include <sys/types.h>.
+ * ar.c: Don't include <sys/types.h> or <stdio.h>.
+ * bucomm.c, dlltool.c, nlmconv.c, objcopy.c, objdump.c: Likewise.
+
+Fri Nov 3 12:38:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c: Include <sys/types.h>.
+
+ Permit user to override DEMANGLER_PROG from command line. From
+ Manfred Hollstein <manfred@lts.sel.alcatel.de>.
+ * Makefile.in ($(DEMANGLER_PROG)): Depend upon
+ $(DEMANGLER_PROG).1.
+ (install): Don't depend upon $(DEMANGLER_PROG).1. Only install
+ $(DEMANGLER_PROG).1 if $(DEMANGLER_PROG) is not empty.
+
+Wed Nov 1 15:04:57 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * Makefile.in (syslex.o): add -I$(srcdir) if compiling in a
+ separate directory.
+
+Mon Oct 30 14:24:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (objdump_print_value): New static function.
+ (objdump_print_address): Use it. If we need the right section for
+ the symbol, and we can't find it, print an offset from the section
+ rather than using a symbol from some other section.
+
+Thu Oct 26 10:23:14 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (no_idata4, no_idata5): New.
+ (arm_jtab): Use correct encoding of jump instruction.
+ (usage, main, make_head, make_tail): Act on no_idata4, no_idata5.
+
+Wed Oct 25 12:10:07 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit paths to generated y.tab.[ch] files.
+
+Fri Oct 20 18:40:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils.texi: Change --with-targets to --enable-targets.
+
+Thu Oct 19 17:47:41 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in: Remove extraneous tab on otherwise empty line,
+ which confuses many non-GNU versions of "make".
+
+Wed Oct 18 16:31:58 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (i386_jtab, arm_jtab): New
+ (gen_lib_file): Rewritten to use bfd.
+
+Fri Oct 13 16:10:07 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Makefile.in (install): Don't give error message if dlltool
+ wasn't built.
+
+Fri Oct 13 11:04:37 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * deflex.l: Allow quoting of IDs.
+ * defparse.y (%union): string deleted.
+ (command): DESCRIPTION takes ID.
+ * dlltool.c (gen_def_file): Quote outgoing name if
+ necessary. Preserve NONAME.
+ (gen_lib_file): Run ranlib.
+ (workout_prefix): Deleted.
+ (main, usage, long_options): Add --as, --ranlib, --ar options.
+
+Wed Oct 11 13:36:13 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (mtable): HOW_ALIGN_LONG, new.
+ (d_ord): Deleted.
+ (d_low_ord, d_high_ord, d_named_funcs): New.
+ (gen_exp_file): Create noname entries correctly.
+ (gen_lib_file): Dump exports alphabetically.
+ (process_duplicates): Count nonamed functions.
+ (fill_ordinals): Keep track of highest ord too.
+ (mangle_defs): Create alphabetically ordered list of names.
+
+Tue Oct 10 09:39:09 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in (TOOL_PROGS): Include DLLTOOL_PROG.
+
+Mon Oct 9 13:06:31 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (add_underscore): New.
+ (xlate): Use new name.
+ (main, usage): Update.
+
+Fri Oct 6 14:08:51 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * sysinfo.y: Eliminate unused terminals "[" and "]" and unused
+ nonterminal "name". One s/r conflict remains.
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * nm.c (print_symname): Don't try to demangle an empty
+ name.
+ * objdump.c (slurp_symtab): Reset symcount if there are
+ no symbols.
+ (slurp_dynamic_symtab): Likewise, for dynsymcount.
+ (disassemble_data): Fix memory leak: free sorted_syms when done.
+ (display_bfd): Likewise, for syms and dynsyms.
+ (dump_relocs): Don't print header before possibly generating an
+ error message.
+ (dump_dynamic_relocs): Likewise.
+
+ * ar.1, nm.1, objdump.1, size.1, strings.1, strip.1: Fix typos and
+ formatting bugs.
+
+Fri Oct 6 12:00:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ar.c (do_quick_append): Comment out.
+ (replace_members): Add quick argument.
+ (main): Don't call do_quick_append.
+ (open_inarch): Don't call quick_append to create an empty archive.
+ Instead call bfd_openw/bfd_set_format/bfd_close.
+
+Thu Oct 5 20:53:08 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * bucomm.c: Always include time.h.
+
+Thu Oct 5 17:25:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (compare_symbols): Sort gnu_compiled and gcc2_compiled
+ symbols after other symbols with the same value. Likewise for
+ symbols which look like file names.
+ (objdump_print_address): Always chose the first reasonable symbol
+ with a given value.
+
+Tue Oct 3 22:38:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * arsup.c (ar_save): Use rename, not unlink/link/unlink.
+
+Mon Oct 2 12:10:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * strings.c (main): Exit with zero status if no files are given
+ and standard input is read.
+
+Thu Sep 28 20:03:07 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Calculate underscore and put into makefile
+ fragment, generate config.h.
+ * mpw-make.sed: New file, sed commands to edit Unix makefile
+ into MPW syntax.
+ * mpw-make.in: Remove.
+ * mac-binutils.r: New file, Mac resources.
+
+Thu Sep 28 15:49:00 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c: (gen_exp_file): Always emit a .reloc section if
+ relocatable.
+ (imp_name_lab): New.
+ (gen_def_file): New.
+ (gen_lib_file): Use imp_name_lab.
+ (main): Initialize imp_name_lab.
+
+Mon Sep 25 12:05:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_HEADER_SYS_WAIT.
+ * configure: Rebuild.
+ * config.in: Rebuild.
+ * dlltool.c: Include "libiberty.h" and "bucomm.h". Don't include
+ <stdio.h>, <stdlib.h>, or <string.h>. Don't include <wait.h>.
+ Include <sys/types.h>. Use HAVE_SYS_WAIT_H to control whether to
+ include <sys/wait.h> or define the wait macros by hand. Don't
+ declare xmalloc.
+ (gen_lib_file): Don't assume that sprintf returns the number of
+ characters; use strlen instead.
+
+Fri Sep 22 17:16:41 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (disassemble_data): Don't use the old BFD based
+ disassembler interface. Make info a const pointer.
+
+Wed Sep 13 18:33:44 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (start_address): New variable.
+ (stop_address): New variable.
+ (usage): Mention --start-address and --stop-address.
+ (OPTION_START_ADDRESS, OPTION_STOP_ADDRESS): Define.
+ (long_options): Add "start-address" and "stop-address".
+ (disassemble_data): Handle start_address and stop_address.
+ (dump_data, dump_reloc_set): Likewise.
+ (main): Don't set seenflag for -l. Handle OPTION_START_ADDRESS
+ and OPTION_STOP_ADDRESS.
+ * objcopy.c (parse_vma): Move to bucomm.c.
+ * bucomm.c (parse_vma): New function, moved in from objcopy.c.
+ * bucomm.h (parse_vma): Declare.
+ * binutils.texi, objdump.1: Document new objdump options.
+
+Tue Sep 12 12:37:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target.
+
+ * ar.c (replace_members): Don't call write_archive if nothing
+ changed.
+
+ * objdump.c (disassemble_data): Add casts to avoid gcc warnings.
+
+Thu Sep 7 12:12:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.in: Rename from config.h.in.
+ * configure.in: Call AC_CONFIG_HEADER with config.h:config.in.
+ Check for config.h:config.in when creating stamp-h.
+ * configure: Rebuild.
+ * Makefile.in (stamp-h): Depend upon config.in rather than
+ config.h.in. Set CONFIG_HEADERS to config.h:config.in when
+ calling config.status.
+
+ * Makefile.in (distclean): Remove config.h, stamp-h, and
+ config.log.
+
+ * nm.c (value_format): Initialize based on BFD64 and
+ BFD_HOST_64BIT_LONG.
+ (print_radix): New static variable.
+ (set_print_radix): Set print_radix. Adjust changes to
+ value_format.
+ (print_value): New static function, to print 64 bit octal and
+ decimal values correctly.
+ (print_symbol_info_bsd): Check BFD64, not BFD_HOST_64_BIT. Use
+ print_value.
+ (print_symbol_info_sysv): Use print_value.
+ (print_symbol_info_posix): Likewise.
+
+Wed Sep 6 15:02:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (*.o): Remove incorrect dependencies on
+ $(BFDDIR)/hosts/std-host.h.
+
+ * Makefile.in (INSTALL_DATA): Add -m 644.
+ (INSTALL_XFORM1): Likewise.
+ (CC_FOR_BUILD): Set to @CC_FOR_BUILD@ rather than $(CC).
+ (mostlyclean): Remove config.log.
+ (distclean): Remove config.cache.
+
+ * configure.in: Call BFD_CC_FOR_BUILD and BFD_BINARY_FOPEN.
+ * configure: Rebuild.
+
+Tue Sep 5 20:22:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Rewrite to use autoconf.
+ * aclocal.m4: New file.
+ * configure: New file, built by autoconf.
+ * acconfig.h: New file.
+ * config.h.in: New file, built by autoheader.
+ * Makefile.in: Various changes for new configure script. Also:
+ (PROGS): Remove $(SYSINFO_PROG).
+ (ALL_CFLAGS): Remove $(TDEFINES).
+ (version.o): Use $(ALL_CFLAGS).
+ (cplus-dem.o, dlltool.o, nlmconv.o): Likewise.
+ (sysdump.o): Depend upon bucomm.h and config.h.
+ (srconv.o, arsup.o, strings.o): Depend upon config.h.
+ (filemode.o): Don't depend upon ../bfd/sysdep.h.
+ (bucomm.o): Depend upon config.h, not ../bfd/sysdep.h.
+ (size.o, objdump.o, nm.o, ar.o, objcopy.o): Likewise.
+ (nlmheader.o, nlmconv.o): Likewise.
+ (distclean): Don't remove sysdep.h.
+ * bucomm.h: Include "ansidecl.h", <stdio.h>, and "config.h".
+ Include "fopen-same.h" or "fopen-bin.h", based on
+ USE_BINARY_FOPEN. Include <errno.h>, and declare errno if it is
+ not a macro. Include <unistd.h>, <string.h>, <strings.h>,
+ <stdlib.h>, and <fcntl.h> if they are present. Declare strchr,
+ strrchr, and strstr if no string header file exists. Include
+ <sys/file.h> if it exists and <fcntl.h> does not. Define
+ O_RDONLY and O_RDWR if necessary.
+ * ar.c: Don't include "sysdep.h". Do include <sys/types.h> and
+ <sys/stat.h>. Use HAVE_GOOD_UTIME_H rather than POSIX_UTIME. Use
+ HAVE_UTIMES rather than !USE_UTIME. Don't include <errno.h>, and
+ don't declare errno.
+ * arsup.c: Don't include <sysdep.h>.
+ * bucomm.c: Don't include "sysdep.h". Include <stdio.h>,
+ <sys/types.h>, and <sys/stat.h>. Include <time.h> if it defines
+ time_t. Define time_t if necessary.
+ * coffdump.c: Don't include "sysdep.h".
+ * coffgrok.c, filemode.c, nlmconv.c, size.c: Likewise.
+ * srconv.c, strings.c: Likewise.
+ * nm.c: Don't include "sysdep.h". Don't try to define HAVE_SBRK.
+ * objcopy.c: Don't include "sysdep.h". Include <sys/types.h> and
+ <sys/stat.h>.
+ (simple_copy): Use creat rather than assuming that O_CREAT is
+ defined.
+ * objdump.c: Don't include "sysdep.h". Use
+ NEED_DECLARATION_PRINTF rather than !FPRINTF_ALREADY_DECLARED.
+ * sysdump.c: Include "bfd.h" and "bucomm.h". Don't include
+ "sysdep.h" or <stdlib.h>.
+ (dump_symbol_info): Rename from symbol_info. Change all callers.
+
+Mon Sep 4 14:30:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (host_makefile_frag): Don't set. Substitute for
+ @CC@, @CFLAGS@, @HDEFINES@ and @LDFLAGS@ in Makefile.
+ * Makefile.in (AR_FLAGS): Set to rc rather than qv.
+ (CC): Define as @CC@.
+ (CFLAGS): Set to @CFLAGS@.
+ (LDFLAGS): Define as @LDFLAGS@.
+ (ALL_CFLAGS): Use @HDEFINES@ rather than $(HDEFINES).
+
+ * configure.in: Don't bother to call config.bfd for each target.
+ Just call it for the default target, and use the shell variable to
+ decide whether underscores are used.
+
+Thu Aug 31 19:21:48 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in: match i[3-6]86-*-win32, not just i386-*-win32.
+
+Thu Aug 31 16:30:22 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (add_indirect): New.
+ (asm_prefix): New
+ (gen_exp_file): Timestamp should be 0. Insert prefix when
+ needed. New code for indirection.
+ (gen_lib_file): Timestamp should be 0. Insert prefix
+ when needed.
+ (usage): Document --add-indirect.
+ (main): Cope with new option.
+
+ * objdump.c (dump_private_headers): New.
+ (usage): Document new option.
+ (long_option): Add private-headers.
+ (dump_bfd_private_header): New.
+ (main): Cope with new option.
+
+Thu Aug 31 04:09:16 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * dlltool.c (run): Add missing 3rd arg to waitpid.
+
+Wed Aug 30 11:02:11 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in (TOOL_PROGS): Include dlltool if needed.
+
+Tue Aug 29 13:25:21 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (rva): Deleted.
+ (rvaafter, rva_before): Use new assembler pseudo.
+ (flush_page, gen_exp_file, gen_lib_file): Use new way of RVAing.
+ (gen_exp_file): Don't generate .edata if no need.
+ (gen_lib_file): Don't make timestamp.
+ Put _iname in idata$7.
+ (workout_prefix): Fix memory initialization bug.
+ (usage): Tidy up, delete many single char options.
+ (main): rva option is gone.
+
+Mon Aug 21 18:41:28 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (options): image-base is a synonym for rva.
+ (gen_lib_file): Put dll name into ibase$7.
+
+Sun Aug 20 09:59:00 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ Modified to generate archives and objects rather than .s files.
+ * dlltool.c (run) New function.
+ (gen_exp_file, gen_lib_file): Use run.
+ (workout_prefix): New.
+ (usage): Document new options.
+ (main): Parse new options.
+
+Wed Aug 16 16:26:52 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (gen_exp_file): Fix RVA handling.
+ (rva_s, rva_n): Delete.
+
+Fri Aug 11 18:27:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * nm.c (main): Ignore -e.
+
+Thu Aug 10 17:35:00 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (config.texi): New target. Write out a setting for
+ texinfo variable VERSION.
+ (binutils.dvi, binutils.info): Depend on it.
+ * binutils.texi: Include it, and reference @value{VERSION} instead
+ of explicitly specifying 2.2(!).
+
+Thu Aug 10 16:07:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * coffgrok.c (do_type): Handle array dimensions the same way gdb
+ does.
+
+Tue Aug 8 17:10:42 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c (mtable): New fields.
+ (ASM_RVA_BEFORE, ASM_RVA_AFTER): New.
+ (flush_page): Use new macros.
+
+Sat Aug 5 00:16:37 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * objcopy.c (mark_symbols_used_in_relocations): Handle sections
+ with no relocations.
+ * coffgrok.c (do_sections_p1): Likewise.
+
+Mon Jul 31 12:51:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * strings.c (print_strings): For compatibility with existing
+ strings programs, print strings which are not terminated with a
+ null byte or a newline.
+ * binutils.texi, strings.1: Update documentation accordingly.
+
+ * ar.c (replace_members): For compatibility with existing ar
+ programs, permit users to add the same file multiple times.
+
+Tue Jul 25 11:21:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * strings.c (DATA_FLAGS): Remove SEC_DATA.
+ (main): If no file names are given, scan standard input.
+ * binutils.texi, strings.1: strings now scans non-data sections by
+ default.
+
+Mon Jul 24 13:52:28 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * srconv.c (wr_hd): Set afl field to 4 for bfd_arch_sh.
+ (writeINT): When size == -2, use 2 bytes for the h8300 and 4 bytes
+ for the sh.
+
+ * sysdump.c (fillup): Return size - 1, the last byte is a checksum
+ and shouldn't be counted.
+ * sysroff.info (hd): Changed segment identifier from a byte to a 1
+ bit field. The sysroff 2.0-01 specification seems to be in error
+ here. Reduce width of following "spare" field from 4 to 3 bits.
+ (rl): Changed order and width of first 4 bitfields to correspond
+ to sysroff specification.
+ (dln_head, dln_inside, dln_tail): Removed.
+
+Tue Jul 18 23:00:03 1995 Fred Fish <fnf@cygnus.com>
+
+ * nm.c (sort_symbols_by_size): Enclose expression being casted
+ in parens so result is casted, not just first operand. Can't
+ do pointer arithmetic on void* pointers.
+
+Fri Jul 14 13:42:42 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * sysdump.c (dh): Changed format of output to be 16 hex digits
+ followed by 16 ascii characters, similar to Emacs' hexl-mode,
+ to make it easier to read.
+ (xcalloc): fix typo.
+
+Thu Jul 13 15:27:44 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * srconv.c (wr_tr): Write out handcrafted tr block.
+ (walk_tree_symbol): Use evallen and evalue instead of
+ vallen & value because of corresponding changes in
+ sysroff.info.
+
+ * sysdump.c (sysroff_swap_tr_in, sysroff_print_tr_out): New
+ functions.
+
+ * sysroff.info (tr): the tr block is a special case --- a block
+ without contents --- which can't be handled by generated code.
+ (den, dpp): only first byte is present for DENend, DPPend.
+ (dsy): describe a conditional portion of block, rename some fields.
+ (dps): describe a conditional portion of block.
+ (dfl): removed.
+
+ * sysinfo.y (yyerror): write error message to standard error.
+
+Thu Jul 13 10:43:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DISTSTUFF): Add arparse.h and sysinfo.h.
+ (mostlyclean): Remove y.output.
+ (clean): Remove sysroff, sysroff.c, sysroff.h, and sysinfo.
+
+ * nlmconv.c (powerpc_mangle_relocs): Cast memset arg to size_t.
+ * objcopy.c (copy_object): Likewise.
+
+ * nm.c (HAVE_SBRK): Define execpt on amigados and WINDOWS_NT.
+ (struct size_sym): Define.
+ (show_stats): New static variable.
+ (long_options): Add undocumented option "stats".
+ (main): Print memory stats if requested.
+ (sort_bfd, sort_dynamic, sort_x, sort_y): New static variables.
+ (numeric_forward): Use minisymbols rather than asymbols.
+ (non_numeric_forward): Likewise.
+ (size_forward1): Rename from size_forward. Use minisymbols.
+ (size_forward2): New static function.
+ (sort_symbols_by_size): Take new arguments dynamic, size, and
+ symsizep. Use minisymbols. Don't store the size back in the
+ symbol; store in a newly allocate struct size_sym array.
+ (display_rel_file): Read minisymbols rather than asymbols. Set
+ sort_* variables. Call print_size_symbols if sorting by size.
+ (filter_symbols): Take new arguments dynamic and size. Use
+ minisymbols.
+ (print_symbols): Likewise. Call print_symbol for actual printing.
+ (print_size_symbols): New static function.
+ (print_symbol): New static function.
+
+Wed Jul 12 10:43:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (dump_section_stabs): Only print each stabs section
+ once.
+ (compare_relocs): Make it clear to gcc that this always returns a
+ value.
+
+Wed Jul 12 10:40:23 1995 H.J. Lu <hjl@nynexst.com>
+
+ * objcopy.c (simple_copy): Preserve errno on failure.
+ (smart_rename): Print error mesage if simple_copy fails.
+
+Tue Jul 11 13:10:52 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * sysdump.c: re-indented file.
+ (module): read blocks sequentially instead of trying to parse
+ them, as that would require changing the parser recognize the
+ difference between a DPSstart and DPSend block.
+ (getone): Add break's between switch blocks as appropriate.
+ (object_body_list): parse blocks according to sysroff spec.
+
+Mon Jul 10 12:37:25 1995 J.T. Conklin <jtc@poseidon.cygnus.com>
+
+ * sysroff.info: re-indented file, prior formatting was confusing
+ because it was indentation did not reflect nesting of conditional
+ records. Change "space size within segment" record in hd record
+ from bit to byte.
+
+ * sysinfo.y (cond_it_field): Use xcalloc instead of calloc.
+
+ * srconv.c (wr_cs): Reformatted cs header array, tag each byte
+ with a comment describing the field.
+ (wr_unit_info): Use SEEK_SET macro instead of constant 0.
+ (main): Use FOPEN_WB macro instead of literal "wb".
+ * sysroff.info: Remove fdl (dfl) field from cs block. Compare
+ ptr->type with ED_TYPE_CONST instead of constant 2 in ed block.
+
+Tue Jul 4 14:48:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * nm.c (size_forward): Check yf against yn, not xn.
+
+ * objcopy.c (copy_archive): Record all output BFD's, and close
+ them before unlinking them and removing the temporary directory,
+ to avoid NFS problems.
+
+ * ar.c (replace_members): In verbose messages, use 'r' when
+ replacing a member, and 'a' when adding one.
+
+ * ar.c (ar_truncate): New static variable.
+ (normalize): Change return type to const char *. Add abfd
+ argument. Change all callers. If ar_truncate, chop the filename
+ to abfd->ar_max_namelen.
+ (main): For the 'f' modifier, set ar_truncate to true. Don't
+ change quick_append to replace if ar_truncate is true.
+ (do_quick_append): If ar_truncate, set BFD_TRADITIONAL_FORMAT.
+ (write_archive): Likewise.
+ * binutils.texi, ar.1: Document 'f' modifier.
+
+ * objcopy.c (enum strip_action): Define strip_unneeded.
+ (OPTION_STRIP_UNNEEDED): Define.
+ (strip_options): Add "strip-unneeded".
+ (copy_options): Likewise.
+ (copy_usage): Mention --strip-unneeded.
+ (strip_usage): Likewise.
+ (is_strip_section): Strip debugging sections if strip_unneeded.
+ (filter_symbols): If strip_unneeded, only keep BSF_KEEP symbols.
+ (copy_object): If strip_all, discard symbols without checking
+ discard_locals.
+ (copy_object): Call filter_symbols if strip_unneeded.
+ (setup_section): Strip debugging sections if strip_unneeded.
+ (copy_section): Likewise.
+ (strip_main): Handle OPTION_STRIP_UNNEEDED.
+ (copy_main): Likewise.
+ * binutils.texi, objcopy.1, strip.1: Document --strip-unneeded.
+
+Mon Jul 3 14:16:47 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i386-*-win32): New configuration.
+ * dlltool.c (killat, xlate, usage, long_options, main):
+ Understand and cope with -k option.
+
+Sat Jul 1 12:25:15 1995 Fred Fish <fnf@cygnus.com>
+
+ * ar.c: (extract_file): Change "#if POSIX_UTIME" to
+ "#ifdef POSIX_UTIME" to match other tests of POSIX_UTIME
+ and avoid lossage when POSIX_UTIME is not defined at all.
+
+Wed Jun 28 17:51:24 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * 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 <shebs@andros.cygnus.com>
+
+ * 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 <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (DISTSTUFF): Don't include info here.
+ (diststuff): Include it here.
+ (realclean): Remove *.info.
+
+ * objdump.c (compare_relocs): If relocation entries have the same
+ address, keep them in file order.
+
+Mon Jun 19 09:06:49 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * dlltool.c: Change names of generated files. .*.s-> -*.s
+
+ * objdump.c (dump_section_stabs): Check for names
+ which are supersets of selected names.
+
+Wed Jun 14 19:43:52 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * dlltool.c (mtable, ARM jump): Must redirect via pc offsetable ptr.
+
+Wed Jun 14 13:27:22 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * deflex.l, defparse.y, dlltool.c: New files.
+ * Makefile.in, configure.in: Support for them.
+
+Mon Jun 12 11:27:54 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * sysdump.c: Include sysdep.h
+ (main): Open input with FOPEN_RB.
+
+Fri Jun 9 17:26:11 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * objdump.c (wide_output): New flag variable.
+ (usage): Print new -w, --wide options.
+ (long_options): Add --wide support.
+ (dump_section_header): If --wide, don't print a newline between
+ the section's first line and the flags.
+ (objdump_print_address): Use unsigned comparisons for the binary
+ search, not signed.
+ (disassemble_data): If --wide, don't put a \n between the
+ disassembly output and relocation information.
+ (main): Support -w option being the same as --wide.
+
+Thu Jun 1 17:09:27 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sat May 6 08:52:24 1995 H.J. Lu (hjl@nynexst.com)
+
+ * objcopy.c (smart_rename): make it smarter, clean up
+ if rename () fails.
+
+Tue May 30 14:24:15 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in: Delete lines with lots of #### because four or more
+ indicate a point for makefile fragment substitution.
+
+Tue May 9 17:17:05 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Don't build nlmconv on PowerPC eabi any more, it
+ is not needed.
+
+Thu Apr 27 20:21:24 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (EXPECT): Define.
+ (RUNTEST): Use one in source tree if present.
+ (check): Set `rootme' for $(EXPECT).
+
+Wed Apr 26 18:26:21 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * srconv.c (main): Add support for -n option which disables
+ prescan of common symbols.
+ (wr_ob): If reading past the end of a section, fill with zeros.
+
+Tue Apr 25 19:14:37 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * objdump.c (dump_section_header): Display load address after
+ virtual memory (run-time) address.
+
+Wed Apr 19 09:44:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (cplus-dem.o): Pass -DVERSION='"$(VERSION)"' to the
+ compile.
+ (DEMANGLER_PROG): No longer uses version.o.
+
+Mon Apr 10 13:29:49 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Merge in support for Mac MPW as a host.
+ (Old change descriptions retained for informational value.)
+
+ * mpw-config.in (TDEFINES): Define as empty in makefile frag.
+
+ * mpw-config.in: Create mk.tmp, define ARCHDEFS in it.
+
+ * mpw-config.in: New file, MPW configure fragment for binutils.
+ * mpw-make.in (install-only): New target.
+ (install): Also depend on install-only.
+
+ * mpw-make.in (cplusfilt): Renamed from c++filt.
+ (INCLUDES): Add more paths.
+
+ * mpw-make.in: New file, MPW makefile fragment for binutils.
+ (Normally automatically generated from Makefile.in.)
+
+Mon Mar 27 11:52:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ar.c (write_archive): Call make_tempname to get output file
+ name, rather than using a fixed name based on the input file.
+
+ * objcopy.c (make_tempname): Copy from here...
+ * bucomm.c (make_tempname): ...to here, and make global.
+ * bucomm.h (make_tempname): Declare.
+
+Fri Mar 24 11:47:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * strings.c: Include "bfd.h" before other headers. Include
+ "sysdep.h".
+ * bucomm.c (print_arelt_descr): Cast st_uid and st_gid to long,
+ and print them with %ld.
+
+Fri Mar 10 13:09:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (strip_options): Add --keep-symbol.
+ (copy_options): Likewise.
+ (copy_usage): Mention --keep-symbol and -K.
+ (strip_usage): Likewise.
+ (keep_symbols): New static variable.
+ (is_strip_symbol): Adjust the return value according to
+ keep_symbols.
+ (strip_main): Handle -K. For -N, check that -K was not given.
+ (copy_main): Likewise.
+ * binutils.texi, objcopy.1, strip.1: Document -K.
+
+Mon Mar 6 13:33:47 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * objcopy.c (copy_archive): Check result of mkdir.
+ (copy_main): Cast an xmalloc result.
+
+ * objdump.c (usage): Break long format string into shorter ones.
+
+Mon Mar 6 13:46:12 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bucomm.c (list_supported_targets): New function.
+ * bucomm.h (list_supported_targets): Declare.
+ * ar.c (usage): Call list_supported_targets.
+ * nm.c (usage): Likewise.
+ * objcopy.c (copy_usage, strip_usage): Likewise.
+ * objdump.c (usage): Likewise.
+ * size.c (usage): Likewise.
+ * strings.c (usage): Likewise.
+
+Tue Feb 28 15:13:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bucomm.c (print_arelt_descr): Cast st_size to long before
+ passing it to fprintf.
+
+Fri Feb 17 13:36:45 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (struct section_list): Add fields remove, set_flags,
+ and flags. Change adjust from boolean to enum.
+ (remove_sections): Remove static variable.
+ (sections_removed): New static variable.
+ (copy_options): Add --set-section-flags.
+ (copy_usage): Mention --set-section-flags.
+ (parse_flags): New static function.
+ (find_section_list): New static function.
+ (is_strip_symbol): Change return type from int to boolean.
+ (is_strip_section): New static function.
+ (filter_symbols): Call is_strip_section.
+ (copy_object): When adding sections, check for specified flags or
+ VMA. Call filter_symbols if any sections are being removed.
+ (setup_section): Use find_section_list function rather than
+ looking through remove_sections and adjust_sections. Handle
+ --set-section-flags.
+ (copy_section): Use find_section_list rather than looking through
+ remove_sections.
+ (strip_main): Use find_section_list instead of adding items to
+ sections_removed.
+ (copy_main): Use find_section_list instead of adding items to
+ sections_removed and adjust_sections. Handle --set-section-flags.
+ * binutils.texi, objcopy.1: Document --set-section-flags.
+
+Tue Feb 14 18:03:03 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (with_source_code): New global variable.
+ (usage): Mention -S/--source.
+ (long_options): Add --source.
+ (prev_functionname, prev_line): New static variables.
+ (struct print_file_list): Define.
+ (print_files): New static variable.
+ (skip_to_line, show_line): New static functions.
+ (disassemble_data): Call show_line to handle -l and -S.
+ (main): Handle -S.
+ * binutils.texi, objdump.1: Document -S/--source.
+
+Thu Feb 9 16:11:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objcopy.c (copy_usage): Rename parameter to avoid shadowing.
+ (strip_usage): Likewise.
+
+ * objcopy.c (struct section_add): Define.
+ (add_sections): New static variable.
+ (copy_options): Accept --add-section.
+ (copy_usage): Mention --add-section.
+ (copy_object): Add sections from the add_sections list.
+ (copy_main): Handle --add-section.
+ * binutils.texi, objcopy.1: Document --add-section.
+
+Wed Feb 1 15:04:57 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * objdump.c (disassemble_data): Pass section offset, not absolute
+ address, to bfd_find_nearest_line.
+
+ * nlmconv.c (powerpc_mangle_relocs): Don't use const with
+ reloc_howto_type.
+
+Thu Jan 26 18:50:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * objdump.c (compare_symbols): Use bfd_asymbol_value (VAR) rather
+ than VAR->value.
+ (objdump_print_address): Likewise.
+ (disassemble_data): Don't change the symbol values. It can
+ confuse bfd_canonicalize_reloc.
+
+Thu Jan 26 12:03:56 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add support for powerpc-*-ebai.
+
+Wed Jan 18 10:02:12 1995 Steve Chamberlain <sac@splat>
+
+ * coffdump.c: Include sysdep.h.
+ (dump_coff_type): Handle coff_secdef_type.
+ * coffgrok.c : Include sysdep.h.
+ * srconv.c: Include libiberty.h
+ (absolute_p, dty_start, dty_end, dump_tree_structure): Remove.
+
+Wed Jan 18 12:24:14 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * coffdump.c (dump_coff_scope): Cast pointer to unsigned long for
+ printf.
+ * coffgrok.c: Include bucomm.h. Don't declare xmalloc.
+ (push_scope): Declare type of parameter link.
+ * size.c: Include libiberty.h.
+ * srconv.c: Include bucomm.h.
+ (find_base): Declare at top of file.
+ (wr_hd): Add default case to architecture switch.
+ (wr_dps_start): Declare type of parameter nest.
+ (wr_du): Comment out variables used only in commented out blocks.
+ (wr_dus): Remove unused variable i.
+ (wr_sc): Remove unused variables myinfo, low, and high.
+ * strings.c: Include libiberty.h.
+ * sysdump.c: Include <ctype.h>.
+
+Tue Dec 20 19:13:44 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ar.c (main): Ignore 'f' modifier used on HP/UX 9.
+
+Thu Dec 15 17:34:12 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * ar.c, nm.c, objcopy.c, objdump.c: Include progress.h.
+ * ar.c, nm.c, objcopy.c, objdump.c (main): Add START_PROGRESS
+ and END_PROGRESS.
+ * ar.c (map_over_members, open_inarch): Call PROGRESS.
+ * nm.c (main, display_archive, filter_symbols, print_symbols):
+ Call PROGRESS.
+
+ * objcopy.c (copy_usage): Break up long usage string.
+
+Wed Dec 14 15:51:56 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * objcopy.c (copy_object): Don't bother setting status after
+ nonfatal() "call", because it won't return.
+
+Fri Dec 9 00:22:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (powerpc_mangle_relocs): Don't switch a reloc to use
+ the section symbol if the symbol is undefined.
+
+Thu Dec 8 14:45:50 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * objcopy.c (add_strip_symbol): Cast return value of xmalloc.
+
+Wed Nov 30 11:05:43 1994 Ian Lance Taylor <ian@rtl.cygnus.com>
+
+ * ar.c (replace_members): Pass current->filename to normalize when
+ checking for duplicates, because the filename of a newly added
+ file will not have been normalized yet.
+
+Thu Nov 17 15:00:13 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ar.c (main): Don't call do_quick_append if any of the archive
+ names are longer than 14 characters.
+
+ * objcopy.c (main): Fix is_strip test. From
+ pirker@eiunix.tuwien.ac.at (Martin Pirker).
+
+Thu Nov 17 15:37:19 1994 Mark W. Eichin <eichin@cygnus.com>
+
+ * objcopy.c (add_strip_symbol): New function, adds a name to an
+ explicit list of symbols to strip.
+ (is_strip_symbol): New function, reports whether the name argument
+ is in the explicit list.
+ (filter_symbols): Check against is_strip_symbol above all.
+ (strip_main): Recognize -N option. If used, don't default to
+ strip_all.
+ (copy_main): Recognize -N option.
+ (strip_usage): Document -N and --strip-symbol options.
+ (copy_usage): Ditto.
+ * objcopy.1, strip.1, binutils.texi: Document -N and
+ --strip-symbol options.
+
+Tue Nov 8 13:12:54 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * objdump.c (display_target_list, display_info_table): Pass an
+ array to tmparg, rather than NULL, since some systems can't handle
+ NULL.
+
+ * objcopy.c (copy_archive): Keep a list of the names of the
+ temporary files we created. Close each input BFD after we open
+ its successor.
+
+Mon Nov 7 15:48:39 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 2.5.3.
+
+Thu Nov 3 19:04:34 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (install-info): Install info files from whatever
+ directory they were found in.
+
+ Patch from DJ Delorie:
+ * configure.bat: do c++filt -> cxxfilt right
+
+ * sysinfo.y: Include system header files early, so any potential
+ declaration of abort() occurs before its use.
+
+ * strings.c (strings_file): Try opening the file in binary mode
+ first.
+
+Wed Nov 2 15:44:13 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ar.c (main): Treat ar qs like ar rs.
+
+Tue Oct 25 16:19:25 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * objcopy.c (gap_fill): Explicitly initialize, for clarity.
+ (pad_to_set, pad_to): New static variables.
+ (copy_options): Accept --pad-to.
+ (copy_usage): Mention --pad-to.
+ (copy_object): Support --pad-to.
+ (compare_section_vma): Sort non loadable sections to the front.
+ Sort sections with the same VMA by size.
+ (copy_main): Handle --pad-to.
+ * binutils.texi, objcopy.1: Document --pad-to.
+
+Thu Oct 20 13:51:31 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objcopy.c (gap_fill_set, gap_fill): New static variables.
+ (copy_options): Accept --gap-fill.
+ (copy_usage): Mention --gap-fill.
+ (copy_object): Support --gap-fill.
+ (get_sections, compare_section_vma): New static functions.
+ (copy_main): Handle --gap-fill.
+ * binutils.texi, objcopy.1: Document --gap-fill.
+
+Wed Oct 19 14:09:16 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (check): Add a dummy else clause to the if
+ statement.
+
+ * objcopy.c (copy_object): Revert yesterday's change.
+ * binutils.texi, objcopy.1: Remove special mention of --set-start
+ and `binary' output format.
+
+Tue Oct 18 11:12:01 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * objcopy.c (copy_object): If the output file format is `binary',
+ and the start address was not set using --set-start, default the
+ start address to zero. This hack is because the `binary' output
+ file format uses the start address to set the virtual address of
+ the first byte in the file.
+ * binutils.texi, objcopy.1: Add some notes on generating S-records
+ and binary files.
+
+ * nm.c (print_symdef_entry): Call print_symname to print the
+ symbol name, so that --demangle works.
+
+ * Makefile.in (mostlyclean): Remove tmpdir.
+
+ * objcopy.c (struct section_list): Add fields used, adjust, val.
+ (adjust_start, set_start_set, set_start): New static variables.
+ (adjust_section_vma, adjust_sections): New static variables.
+ (copy_options): Add --adjust-start, --adjust-vma,
+ --adjust-section-vma, --adjust-warnings, --no-adjust-warnings,
+ --set-start.
+ (parse_vma): New static function.
+ (copy_usage): Mention new options.
+ (copy_object): Handle --set-start and --adjust-start.
+ (setup_section): Correct type of last argument to PTR. Set used
+ field if section is removed. Handle --adjust-vma and
+ --adjust-section-vma.
+ (copy_section): Correct type of last argument to PTR.
+ (mark_symbols_used_in_relocations): Likewise.
+ (strip_main): Clear used field when handling -R.
+ (copy_main): Handle new options.
+ * binutils.texi (objcopy): Document new options.
+ * objcopy.1: Document new options.
+
+Fri Oct 14 14:38:13 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * configure.in (configdirs): Remove definition--testsuite is no
+ longer configured.
+ * Makefile.in (testsuite): Remove target.
+ (site.exp): New target.
+ (check): Rewrite.
+ (clean, distclean): Don't recur into testsuite directory.
+
+Thu Oct 13 19:24:09 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (VERSION): Updated to 2.5.
+ * Version 2.5 released.
+
+Tue Oct 11 15:26:42 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (sysdump.o): Depends upon sysroff.c.
+
+Mon Oct 10 13:50:30 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * nlmconv.c (link_inputs): Pass -Ur flag to ld so that the
+ ctor/dtor tables needed by C++ programs are built.
+
+Sun Oct 9 18:04:00 1994 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (srconv.o): Add dependence on sysroff.c.
+
+Tue Oct 4 12:19:51 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * configure.in: Use ${config_shell} when running config.bfd.
+
+ * Makefile.in (sysroff.h): Split target away from sysroff.c.
+ (srconv.o, sysdump.o): New targets.
+ (srconv, sysdump): Don't depend upon sysroff.c.
+
+Wed Sep 28 13:04:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (arparse.c): Don't ignore errors from mv.
+ (sysinfo.c): Likewise. Also, depend upon arparse.c, to prevent a
+ parallel make from trying to build both arparse.c and sysinfo.c
+ simultaneously.
+ (nlmheader.c): Similar change.
+ (arparse.h): Separate target from arparse.c, so that a parallel
+ make does not try to build both at once. Depend upon arparse.c.
+ (sysinfo.h): Similar change.
+
+ * objdump.c (disassemble_data): Pass the reloc buffer to free, not
+ the pointer used to loop over the relocs.
+
+Sat Sep 24 16:16:57 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * objdump.c (disassemble_data): Cast result of xmalloc.
+
+Wed Sep 21 19:30:35 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objdump.c (sorted_syms, sorted_symcount): New global variables.
+ (objdump_print_address): Use sorted_syms and sorted_symcount
+ instead of syms and symcount.
+ (disassemble_data): Don't bother to get the relocs before looping
+ over the sections. Before filtering and sorting the symbol table,
+ copy it into sorted_syms.
+
+Fri Sep 16 11:27:39 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objdump.c (struct objdump_disasm_info): Add field require_sec.
+ (objdump_print_address): If aux->require_sec, require that the
+ symbol be in aux->sec even if HAS_RELOC is not set. If we can't
+ find a smaller symbol in the right section, look for a larger one.
+ (disassemble_data): Set aux.require_sec around the
+ objdump_print_address call for the instruction address.
+
+Thu Sep 15 21:43:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ar.c: Call xexit rather than exit.
+ (output_filename, output_file, output_bfd): New static variables.
+ (remove_output): New static function.
+ (main): Call xatexit (remove_output). Call xexit rather than
+ returning.
+ (extract_file): Set output_filename and output_file while output
+ file is open.
+ (write_archive): Likewise, but use output_bfd, not output_file.
+ * arsup.c: Include libiberty.h. Call xexit rather than exit.
+ * bucomm.c: Likewise.
+
+ * objdump.c (disassemble_all): New global variable.
+ (usage): Document --disassemble-all.
+ (long_options): Add disassemble-all as a synonym for -D.
+ (compare_symbols): Make pointers const.
+ (compare_relocs): New static function.
+ (disassemble_data): Rename disassemble to disassemble_fn to avoid
+ shadowing. If dump_reloc_info, print relocs along with
+ disassembly. Skip sections which are not SEC_CODE unless
+ disassemble_all or only is set.
+ (display_bfd): Don't call dump_relocs if disassemble is set.
+ (main): Accept and handle -D.
+ * binutils.texi: Document -D/--disassemble-all.
+ * objdump.1: Likewise.
+
+Wed Sep 14 12:19:07 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objdump.c (disassemble_data): Initialize prevline to 0. Make
+ prev_function non const. Copy functionname into an malloc buffer
+ when setting prev_function, instead of assuming that the string
+ will last forever.
+
+ * nm.c: Include libiberty.h.
+ (sort_by_size): New static variable.
+ (long_options): Add --size-sort.
+ (usage): Mention --size-sort.
+ (numeric_forward): Make static. Change from void * to PTR.
+ (numeric_reverse): Likewise.
+ (non_numeric_forward, non_numeric_reverse): Likewise.
+ (sorters): Change declaration from void * to PTR.
+ (size_forward, sort_symbol_by_size): New static functions.
+ (display_rel_file): Handle sort_by_size.
+ (filter_symbols): If sort_by_size, discard absolute and undefined
+ symbols.
+ * binutils.texi (nm): Document --size-sort.
+ * nm.1: Document --size-sort.
+
+Tue Sep 13 21:06:06 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * objcopy.c (copy_main): Initialize input_filename and
+ output_filename to NULL.
+
+Tue Sep 13 14:17:24 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (version.o): Depend upon Makefile, so that version.o
+ gets rebuilt when make variable VERSION is changed.
+
+ * objdump.c (dump_section_header): Print the SEC_NEVER_LOAD flag.
+
+Wed Aug 24 12:40:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Change i[34]86 to i[345]86.
+
+Tue Aug 23 11:00:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ar.c (ranlib_touch): Don't update the archive map if there isn't
+ one.
+
+Mon Aug 22 16:02:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ar.c: Include libiberty.h.
+ (inarch): Remove variable.
+ (map_over_members): Make static. Add arch argument, and use it
+ instead of inarch. Change all callers.
+ (main): Treat --version as -v. Accept -t argument. Accept any
+ number of archive arguments. Catch and use open_inarch return
+ value, rather than using inarch.
+ (open_inarch): Return newly opened BFD, rather than using inarch.
+ (do_quick_append): Make archive_filename const.
+ (write_archive): Add iarch argument, and use it instead of inarch.
+ Change all callers.
+ (delete_members, move_members, replace_members): Likewise.
+ (ranlib_only): Don't exit on success. Catch and use open_inarch
+ return value.
+ (ranlib_touch): New function.
+ * arsup.h (map_over_members): Don't declare.
+ (ar_end, ar_extract): Declare.
+ (open_inarch): Change return value in declaration to bfd *.
+ * arsup.c (map_over_list): Make static. Always pass two arguments
+ to function. Add arch argument, and use it instead of inarch.
+ Change all callers.
+ (ar_directory_doer): Make static. Add ignored second argument.
+ Change all callers.
+ (ar_directory): Use open_inarch return value rather than inarch.
+ (ar_addlib_doer): Make static.
+ (ar_addlib): Use open_inarch return value rather than inarch.
+ (ar_extract): Remove unused local variable abfd.
+
+Thu Aug 11 14:55:57 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ Add support for removing named sections to objcopy and strip.
+ * objcopy.c (struct section_list): Define.
+ (remove_sections): New static variable.
+ (strip_options, copy_options): Add remove-section.
+ (copy_usage, strip_usage): Mention -R and --remove-section.
+ (setup_section): If section is in remove_sections list, ignore it.
+ (copy_section): Likewise.
+ (strip_main, copy_main): Handle -R.
+ * binutils.texi, objcopy.1, strip.1: Document new options.
+
+Wed Aug 10 10:19:55 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * nlmconv.c (powerpc_mangle_relocs): Rename symvalue to sym_value,
+ so as not to conflict with the symvalue typedef in bfd.h.
+
+Mon Aug 1 13:19:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * nlmheader.y: Per current NetWare docs, accept a revision number
+ of 0 and treat a revision number greater than 26 as 0.
+
+Mon Jul 25 12:58:36 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objdump.c (objdump_print_address): Correct handling of end of
+ symbols when looking for next symbol with a different value.
+
+Fri Jul 22 16:48:34 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * nm.c (numeric_forward): Treat undefined symbols as "less than"
+ defined symbols with zero values. If numeric values are equal, or
+ both symbols are undefined, sort alphabetically. Don't assume
+ that the difference of two bfd_vma values will truncate to "int"
+ and still have the same sign.
+ (numeric_reverse): Call numeric_forward and negate the result.
+ (print_symbol_info_bsd): For undefined symbols, print leading
+ spaces equivalent to the width of a printed bfd_vma, rather than
+ assuming that 8 will look right.
+
+Fri Jul 22 10:36:50 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coffgrok.c (doit): Zero all fields of new structure.
+ * srconv.c (sysroff_swap_*_out): Remove redundant trailing arg.
+ * sysinfo.y: Generate sysroff_swap_*_out without requiring extra
+ arg.
+
+Fri Jul 22 10:09:53 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlmheader.y: Make "stack" and "stacksize" synonyms in the lexer
+ rather than the parser.
+
+Thu Jul 21 10:25:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/mh-alphaosf, config/mh-apollo68v, config/mh-delta88:
+ Remove; obsolete.
+
+Sat Jul 16 22:34:39 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objdump.c (slurp_dynamic_symtab): Try to get the dynamic symbols
+ even if the bfd is not marked DYNAMIC. ELF executables are not
+ marked DYNAMIC, but do have dynamic symbols.
+
+Fri Jul 15 01:41:35 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coffgrok.c (do_where): Make data with no type 'int'.
+ (do_define): Keep info on source file of a symbol.
+ * coffgrok.h (coff_symbol): New field.
+ * srconv.c (PROGRAM_VERSION): Now 1.3
+ (wr_rl): Use external ref number for symbol.
+ (wr_dus): Only keep one source file per debug unit.
+ (wr_dln): Always emit line numbers for first source file,
+ (wr_globals): Emit globals in the du of their owning source file.
+
+Mon Jul 11 15:59:03 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlmheader.y: Null terminate var_hdr->threadName.
+
+Fri Jul 8 17:33:22 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (syslex.o, sysinfo.o): Permit C source files to be
+ in $(srcdir), as they will be for FSF releases.
+
+Wed Jul 6 01:13:14 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (setup_sections): Preserve existing section flags when
+ copying in flags from a new section.
+
+Tue Jul 5 15:56:01 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objcopy.c: Include libiberty.h.
+ (copy_file): If output_target is NULL, set it to the target of the
+ input file.
+
+Wed Jun 29 17:17:14 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * nlmconv.c (link_inputs): Fixed memory allocation bug.
+
+Thu Jun 23 12:52:46 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.in: Change --with-targets to --enable-targets.
+
+Tue Jun 21 12:53:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (sysinfo): Does not depend upon $(ADDL_LIBS).
+
+ * nlmconv.c (powerpc_build_stubs): Don't generate the PowerPC
+ NetWare custom header; no longer needed.
+ (powerpc_mangle_relocs): Convert relocs against the uninitialized
+ data section into relocs against the data section.
+
+ * configure.in: Set nlmconv_defs to -DNLMCONV_cputype for all the
+ netware targets. Write it into Makefile as NLMCONV_DEFS.
+ * Makefile.in (nlmconv.o): Pass $(NLMCONV_DEFS) to $(CC).
+ * nlmconv.c: Only compile code for specific CPU types if
+ NLMCONV_cputype is defined.
+
+ * nlmconv.c (main): Change uses of bfd_abs_section, etc., to use
+ bfd_abs_section_ptr or bfd_is_abs_section, etc.
+ (i386_mangle_relocs, alpha_mangle_relocs): Likewise.
+ (powerpc_build_stubs): Likewise.
+ * nm.c (filter_symbols, print_symbols): Likewise.
+ * objcopy.c (filter_symbols): Likewise.
+ (mark_symbols_used_in_relocations): Likewise.
+ * objdump.c (remove_useless_symbols, dump_relocs): Likewise.
+ * size.c (sysv_internal_printer): Likewise.
+
+Mon Jun 20 16:43:03 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (MANPAGES): Remove $(DEMANGLER_PROG).
+ (install): Install it explicitly, from build dir, not srcdir.
+
+Mon Jun 20 16:29:54 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * objdump.c: Don't include elf/internal.h.
+ (bfd_elf_find_section): Don't declare.
+ (read_section_stabs): No special handling for ELF. Always read
+ using BFD sections.
+
+Thu Jun 16 17:25:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Set UNDERSCORE in Makefile based on result of
+ invoking config.bfd with a second argument of ``_''.
+ * Makefile.in (underscore.c): Depend upon Makefile. Don't try to
+ run $(CC) and $(NM), just use $(UNDERSCORE). Create via temporary
+ file.
+ (demangle.o): Remove target.
+ ($(NM_PROG)): Don't depend upon demangle.o, and don't link against
+ demangle.o. It's in libiberty anyhow.
+ (cplus-dem.o): Don't depend upon demangle.o.
+ * binutils.texi: Mention -n and --no-strip-underscores arguments
+ to c++filt.
+
+Wed Jun 15 12:10:31 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nm.c (long_options): Add --no-demangle to turn off --demangle,
+ and --no-cplus for Linux compatibility.
+ (usage): Mention --no-demangle.
+ * binutils.texi: Document --no-demangle.
+
+Fri Jun 10 15:41:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nm.c: HOST_64_BIT was renamed to BFD_HOST_64_BIT.
+
+ * objcopy.c (copy_archive): Make the temporary directory in the
+ same directory as the output BFD, since we may not have write
+ permission on the current directory. Set the permissions of the
+ new directory to 0700, not 0777.
+
+Mon Jun 6 21:36:43 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * configure.in: if this is an rs6000 (and we're not building for
+ any other bfd targets) then build only nm (collect needs it on
+ rs6000-lynx).
+
+ * Makefile.in: define TOOL_PROGS which the list of programes to
+ install in $tooldir -- replaces a hard-coded list.
+
+Fri Jun 3 10:59:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (display_target_list): Remove unused local ok.
+
+Thu May 26 18:05:52 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/mh-alphaosf (CFLAGS): Don't specify both -g and -O;
+ they're not compatible under native cc. Use -O1 instead.
+
+ * Makefile.in (VERSION): Updated to cygnus-2.4.1.
+
+ Changes from binutils-2.4 net release:
+
+ * Makefile.in (MANPAGES): Use $(DEMANGLER_PROG).
+ ($(DEMANGLER_PROG).1): Build from cxxfilt.man, using sed.
+ * cxxfilt.man: Renamed from c++filt.1, replaced "c++filt" with
+ magic token to be replaced by sed.
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: update for latest makefile.in
+
+Fri May 13 23:25:13 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bucomm.c: Check ANSI_PROTOTYPES rather than __STDC__.
+
+Tue May 10 18:22:06 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * objcopy.c (copy_section): Set section size correctly if using
+ interleave.
+
+Sat May 7 16:49:36 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in: Add rule for sysinfo.h
+
+Fri May 6 12:18:33 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in (SRCONV_PROG): Define.
+ (PROGS): Use $(SRCONV_PROG) too.
+
+Thu May 5 19:41:43 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (DISTSTUFF): Add sysinfo.c, syslex.c, in case
+ someone configures with `targets=all'.
+ (distclean): Remove y.*.
+ (syslex.o): Depend on sysinfo.h.
+ (sysinfo.c): Rename y.tab.h to sysinfo.h.
+ (install-info): Don't try to install into $(infodir)/$(srcdir).
+ * syslex.l: Include sysinfo.h, not y.tab.h.
+
+Thu May 5 11:50:55 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * syslex.l (yywrap): Define as function if not defined as a macro.
+
+ * Makefile.in (objdump.o): Deleted special rule.
+ * configure.in: Don't bother building ARCHDEFS variable for
+ Makefile.
+ * objdump.c (ARCH_*): Deleted handling.
+ (disassemble_data): Call `disassembler' from opcodes library.
+
+Thu May 5 13:28:42 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (install): Correct handling of $(tooldir) and
+ $(bindir) being on different devices.
+
+Fri Apr 29 09:50:38 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * sysdump.c (h8300, sh): Add declarations.
+
+Wed Apr 27 11:25:18 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in (syslex, sysinfo): Use CC_FOR_BUILD.
+ * coffdump.c, coffgroc.c, coffgrog.h, srconv.c, sysdump.c,
+ sysroff.info: Major changes.
+
+Tue Apr 26 18:18:24 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * objdump.c (print_section_stabs): Indicate the stab header symbol
+ more clearly, print numbers of unrecognized stab n_type values.
+
+Tue Apr 26 16:22:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (copy_sections): Copy arelent pointers, not arelents.
+
+Mon Apr 25 16:14:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (distclean): Remove $(PROGS) and underscore.c.
+
+Fri Apr 22 11:14:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (setup_sections): Remove special handling of .reginfo
+ section.
+ (copy_sections): Likewise.
+ (alpha_mangle_relocs): Use bfd_ecoff_get_gp_value rather than the
+ special ECOFF .reginfo section.
+
+ * objcopy.c (copy_object): Call bfd_copy_private_bfd_data after
+ copying everything else, to let it fiddle with the file in its
+ final state.
+
+ * objdump.c: Include libiberty.h.
+ (display_target_list): If a format fails, just go on to the next
+ one. Check return value of bfd_set_format.
+ (display_info_table): Likewise. Don't increment loop variable in
+ for loop test, since that skips the first element.
+ (display_target_tables): Rewrite loop for clarity. Ensure that it
+ always prints at least one element.
+
+ * nlmconv.c (main): Use CyGnUsEx rather than CyGnUsSeCs for
+ sections header. Rename from cygnus_sections to cygnus_ext.
+
+Thu Apr 21 12:12:26 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (_DUMMY_NAME_): Don't define.
+ (display_target_list): Use tmpnam to get a file name rather than
+ using _DUMMY_NAME_. Unlink it when done.
+ (display_info_table): Likewise.
+
+ * nlmconv.c (secsec): New static variable.
+ (main): Create .nlmsections section in output BFD. Store
+ information about it in sections header.
+ (setup_sections): Allocate space in sections header.
+ (copy_sections): Copy zero sized sections. Put information about
+ each section in the sections header.
+
+Wed Apr 20 14:34:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (powerpc_build_stubs): Take new outbfd argument.
+ Change caller. Create custom header for new PowerPC NetWare
+ format.
+
+ * Makefile.in (nlmheader.o, nlmconv.o): Update dependencies.
+ * nlmconv.c: Include bfd.h and libiberty.h with "", not <>.
+ * nlmheader.y: Include bfd.h with "", not <>.
+
+Wed Apr 13 10:52:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c: Do an ifdef on __GO32__, not unix.
+
+Wed Apr 6 21:54:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Added -D (--dynamic) option to nm and -T (--dynamic-syms) and -R
+ (--dynamic-reloc) arguments to objdump.
+ * nm.c (dynamic): New static variable.
+ (long_options): Added "dynamic".
+ (usage): Mention -D and --dynamic.
+ (main): Add D to getopt string. Handle -D by setting dynamic.
+ (display_rel_file): If dynamic is non-zero, read dynamic symbols
+ rather than normal symbols.
+ * nm.1: Updated for -D (--dynamic) option.
+ * objdump.c (dump_dynamic_symtab): New global variable.
+ (dump_dynamic_reloc_info): New global variable.
+ (dynsyms, dynsymcount): New global variables.
+ (usage): Mention -R, -T, --dynamic-syms and --dynamic-reloc.
+ (long_options): Added "dynamic-reloc" and "dynamic-syms".
+ (slurp_symtab): If no symbols, return rather than exit.
+ (slurp_dynamic_symtab): New function.
+ (display_bfd): Handle dump_dynamic_symtab and
+ dump_dynamic_reloc_info.
+ (dump_symbols): Take new dynamic argument, indicating whether to
+ display dynamic symbols.
+ (dump_relocs): Move most printing into dump_reloc_set.
+ (dump_dynamic_relocs): New function.
+ (dump_reloc_set): New function, extracted from dump_relocs.
+ (main): Add R and T to getopt string. Handle -T by setting
+ dump_dynamic_symtab and -R by setting dump_dynamic_reloc_info.
+ * objdump.1: Updated for -R (--dynamic-reloc) and -T
+ (--dynamic-syms) options.
+ * binutils.texi: Updated for new nm and objdump options.
+
+Wed Mar 30 15:52:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Update for recent BFD changes to symbol and reloc reading. Rename
+ all uses of get_symtab_upper_bound to bfd_get_symtab_upper_bound.
+ Also:
+ * coffgrok.c (symcount): Change to long.
+ (do_sections_p1): Check for error return from
+ bfd_get_reloc_upper_bound. Change relcount to long, and check for
+ error from bfd_canonicalize_reloc.
+ (coff_grok): Change storage to long. Check for error from
+ bfd_get_symtab_upper_bound and bfd_canonicalize_symtab.
+ * nlmconv.c (main): Change symcount, newsymalloc, newsymcount, and
+ i to long. Check for error from bfd_get_symtab_upper_bound and
+ bfd_canonicalize_symtab.
+ (copy_sections): Change reloc_size and reloc_count to long. Check
+ for error from bfd_get_reloc_upper_bound and
+ bfd_canonicalize_reloc.
+ (mangle_relocs, i386_mangle_relocs, alpha_mangle_relocs): Change
+ reloc_count_ptr argument to long *. Make corresponding changes to
+ variables loaded from *reloc_count_ptr.
+ * nm.c (display_rel_file): Change storage and symcount to long.
+ Check for errors from bfd_get_symtab_upper_bound and
+ bfd_canonicalize_symtab.
+ * objcopy.c (filter_symbols): Change symcount, src_count and
+ dst_count to long.
+ (copy_object): Change symcount to long. Pass another argument to
+ fprintf. Check for errors from bfd_get_symtab_upper_bound and
+ bfd_canonicalize_symtab.
+ (copy_section): Change relcount to long. Check for errors from
+ bfd_get_reloc_upper_bound and bfd_canonicalize_reloc.
+ (mark_symbols_used_in_relocations): Change relcount and i to long.
+ Check for errors form bfd_get_reloc_upper_bound and
+ bfd_canonicalize_reloc.
+ * objdump.c (storage): Remove global variable.
+ (symcount): Changed to long.
+ (slurp_symtab): New local variable storage. Check for errors from
+ bfd_get_symtab_upper_bound and bfd_canonicalize_symtab.
+ (remove_useless_symbols): Change return value and count to long.
+ (objdump_print_address): Change min, max, thisplace and i to long.
+ (disassemble_data): Change i to long.
+ (dump_symbols): Change count to long.
+ (dump_relocs): Change relcount to long. Check for errors from
+ bfd_ret_reloc_upper_bound and bfd_canonicalize_reloc.
+ (display_info_table): Add casts when passing LONGEST_ARCH for
+ printf %* argument.
+
+Tue Mar 29 14:59:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nm.c (display_archive): Close each archive element after it has
+ been displayed.
+ * objdump.c (display_file): Likewise.
+
+Mon Mar 28 13:04:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Change error message to refer to bfd/config.bfd
+ rather than bfd/configure.in.
+
+Sun Mar 27 16:23:39 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * More fixes for object formats which allow multiple sections
+ with the same name:
+ * objcopy.c (setup_section): Make a new output section even if
+ one already exists with the given name.
+ (copy_section): Use isection->output_section rather than trying
+ to look the output section up by its (possibly non-unique) name.
+
+ * Makefile.in (install-info): Look for binutils.info in the
+ current directory, then in $(srcdir). Don't use $<.
+
+Mon Mar 21 12:55:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (objdump_print_address): Make static. Declare with
+ prototype. Change vardiff from int to bfd_signed_vma. Correct
+ binary search termination condition. When looking for same
+ section symbol in relocatable file, handle final symbol correctly.
+
+Sun Mar 20 11:26:36 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in: Avoid bug in hpux sed.
+
+ * objcopy.c: Changes to keep it from stripping symbols used
+ in output relocations.
+ (mark_symbols_used_in_relocations): New function. Mark symbols
+ used in output relocations with BSF_KEEP.
+ (filter_symbols): Do not strip symbols marked with BSF_KEEP.
+ (copy_object): Reorder actions. First setup sections, then
+ build the output symbol table, then copy the section contents.
+
+Fri Mar 18 10:53:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ar.c (write_archive): Allocate space for the null byte. From
+ Robert Lipe <robertl@arnet.com>.
+
+Thu Mar 17 16:20:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in: Built nm.new and strip.new to avoid problems with
+ collect when . is in PATH.
+ (STRIP_PROG): Change from strip to strip.new.
+ (NM_PROG): Change from nm to nm.new.
+ (install): Remove the .new when installing.
+
+Wed Mar 16 16:27:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (powerpc_build_stubs): Set BSF_DYNAMIC flag for each
+ symbol for which we build a stub.
+ (powerpc_mangle_relocs): Only reset TOC pointer for a call to a
+ symbol with BSF_DYNAMIC flag set.
+
+Tue Mar 15 23:04:13 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * objcopy.c (filter_symbols): Use bfd_is_local_label to determine
+ if a symbol represents a compiler-generated local label.
+ (copy_object): Give the BFD backends a chance to copy any private
+ bfd data from the input BFD to the output BFD.
+ (setup_section): Give the BFD backends a chance to copy any private
+ section data from the input section to the output section.
+
+Mon Mar 14 11:15:58 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * objcopy.c (mangle_section): Delete unused function.
+ (setup_section): Set osection here instead of calling
+ mangle section to do it.
+
+Mon Mar 14 12:11:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ar.c (write_archive): Close inarch before unlinking it.
+
+Fri Mar 11 22:20:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (main): For PowerPC, call powerpc_build_stubs and
+ powerpc_resolve_stubs. Use __GOT0, not __toc_start. Handle it if
+ the start and end symbols are not in the text section.
+ (struct powerpc_stub): New struct definition.
+ (powerpc_stubs, powerpc_stub_insns): New static variables.
+ (powerpc_initial_got_size): New static variable.
+ (powerpc_build_stubs): New function.
+ (powerpc_resolve_stubs): New function.
+ (powerpc_mangle_relocs): Clear extraneous data in .got section.
+ Rearrange reloc handling to handle ELF relocs that are not
+ partial_inplace. Resolve PC relative relocs.
+
+Wed Mar 9 13:48:11 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ar.c (move_members): Fix it so that the abi positional modifiers
+ don't delete all archive members following the insert point.
+
+Tue Mar 8 13:14:43 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * coffgrok.[ch]: New files, understand coff objects.
+ * coffdump.c: Uses coffgrok to dump out the debug info of a coff
+ file.
+ * sysroff.info: Description of a SYSROFF object file.
+ * sysinfo.y, syslex.l: Parse info file, generate a reader, writer,
+ header files and a printer.
+ * srconv.c: Uses coffgrok.c and sysroff.info to convert a coff
+ file to a SYSROFF file.
+
+Sat Feb 26 13:35:26 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * ar.c (do_quick_append): Pad with a genuine character 10,
+ rather than whatever '\n' might happen to be.
+
+Tue Feb 22 18:25:52 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * nlmconv.c (main): Ignore debugging symbols when looking for
+ special symbols by name.
+
+Sun Feb 20 18:47:42 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * nlmconv.c: Include libiberty.h.
+
+ Support for PowerPC NetWare.
+ * nlmconv.c (main): For PowerPC NetWare, automatically define the
+ special symbols __toc_start.
+ (select_output_format): Handle bfd_arch_powerpc.
+ (mangle_relocs): Likewise.
+ (powerpc_mangle_relocs): New function.
+
+Thu Feb 17 09:28:23 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ar.c, bucomm.c, nlmconv.c, nm.c, objcopy.c, objdump.c,
+ size.c: Use bfd_get_error and bfd_set_error and new error names.
+
+Fri Feb 11 15:54:51 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objcopy.c (strip_main, copy_main): Add missing 'break' in switch.
+
+Mon Feb 7 19:45:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (disassemble_data): Handle bfd_arch_powerpc.
+
+Sun Feb 6 22:08:20 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * strings.c objdump.c nlmconv.c objcopy.c nm.c ar.c size.c (main):
+ Call xmalloc_set_program_name.
+
+Fri Feb 4 10:46:01 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objcopy.c (filter_bytes): Make MEMHUNK a char *, not PTR, so we
+ can do arithmetic on it.
+
+Thu Feb 3 14:06:41 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objdump.c (dump_section_stabs, read_section_stabs,
+ print_section_stabs): Functions broken out of dump_stabs_1.
+ Free the stabs and strings when done with them.
+
+Wed Feb 2 13:42:23 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * nlmconv.c (main): Use bfd_get_flavour instead of struct member.
+ * ar.c (print_contents, extract_file), size.c
+ (print_berkeley_format, print_sysv_format): Use bfd_get_filename and
+ bfd_my_archive instead of dereferencing the structs directly.
+
+ * ar.c: Use bfd_fatal and bfd_nonfatal instead of bfd_perror and exit.
+ Indent. Remove DEFUNs.
+
+ * nlmconv.c (main), objcopy.c (copy_file): Print matching formats
+ if ambiguous match.
+ * nm.c (display_file, display_archive), size.c (display_bfd):
+ Eliminate gotos.
+ Print matching formats if there is an ambiguous match. Use
+ bfd_nonfatal instead of hardcoded error message if nothing matches.
+
+ * arsup.c, ar.c, objdump.c: Use bfd_get_filename instead of
+ abfd->filename.
+
+ * nm.c (display_archive): New function, from code in display_file.
+ (display_rel_file): Renamed from do_one_rel_file.
+
+ * size.c: Indent.
+ (display_archive): New function from code in display_file.
+ (display_file): Check bfd_close error return.
+
+ * strings.c (strings_object_file): Check bfd_check_format
+ error return.
+
+ * strings.c, objdump.c, size.c: Use bfd_nonfatal instead of bfd_perror.
+
+ * bucomm.c: Delete references to exit_handler. It wasn't set
+ anywhere, and now that we're using the libiberty xmalloc, it
+ wouldn't always get called before exiting.
+ (list_matching_formats): Function moved from objdump.c.
+ * bucomm.h: Declare it.
+
+ * objdump.c (disassemble_data): Move some variable decls closer to
+ their use. Add some comments. Replace a nested block with a
+ return.
+
+Mon Jan 31 18:50:41 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * objdump.c (display_target_list, display_info_table): Check that
+ the bfd of the dummy output file is not null.
+
+Wed Jan 26 13:13:18 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objcopy.c (filter_bytes): New function.
+ (copy_section): Call it.
+ (copy_options, copy_usage, copy_main): Add --byte option to
+ activate it. Appropriate the -b option (which was an undocumented
+ synonym for -F) for it, also. Add --interleave, -i option for
+ additional control.
+ (setup_section, copy_section, mangle_section): Renamed with no `s'
+ on the end.
+ * objcopy.1, binutils.texi: Document the new options.
+
+ * objdump.c (display_target_tables, display_target_list):
+ New functions broken out of display_info.
+ Eliminate some magic constants. Use more meaningful variable names.
+ (dump_bfd_header): New function broken out of display_bfd.
+ (dump_section_header): New function broken out of dump_headers.
+ (remove_useless_symbols): Don't shadow global variable name with
+ parameter.
+ (objdump_print_address): Fix backward test.
+
+Tue Jan 25 19:40:54 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * bucomm.c (print_arelt_descr): Change decl of `when' to time_t.
+ * objdump.h: Removed.
+
+Mon Jan 24 13:29:02 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objdump.c (display_file): Remove call to list_matching_formats.
+ It would never be called.
+ (list_matching_formats): Take an arg giving the list of matching
+ formats.
+ (display_bfd): Pass the arg, and get it filled in by calling
+ bfd_check_format_matches instead of bfd_check_format.
+ (display_info, display_info_table): target_vector was renamed to
+ bfd_target_vector.
+
+ * binutils.texi (objdump): Note some limitations of -h section
+ address printing.
+
+Sat Jan 22 16:20:46 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (MALLOC): Set to emptiness by default.
+ (ALL_CFLAGS): Add and use.
+ (arparse.h): Make it depend on arparse.y.
+ * ar.c (libbfd.h): Don't require to be in ../bfd.
+ * objdump.c (comp): Rename to compare_symbols.
+
+Fri Jan 21 20:22:30 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objdump.c (list_matching_formats): If the file format is ambiguous,
+ print the matching names so the user can choose one.
+ (display_bfd): Call it.
+ (display_file): Call it.
+
+Fri Jan 21 19:17:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (disassemble_data): Support bfd_arch_rs6000.
+
+Mon Jan 17 13:57:25 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * objdump.c (stab_name): Allocate dynamically.
+ (stab_print): Use pointers to strings instead of char arrays.
+ (dump_stabs): Change alloc and init of arrays appropriately.
+ (dump_stabs_1): Always decide whether to print stab_name or
+ the stab's type number, if unnamed.
+
+Fri Jan 14 14:42:48 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objcopy.c (strip_main, copy_main): Don't clobber the input file
+ if copy_file fails.
+
+ * nlmconv.c (main): Warn about an attempt to use a shared library
+ with uninitialized data.
+
+ * nlmconv.c (setup_sections): Make sure that we align the
+ output_offset of each input section appropriately.
+
+Thu Jan 13 17:32:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (dump_relocs): Don't crash if section name is NULL.
+
+Tue Jan 11 19:46:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * filemode.c (filemodestring): Commented out; not used.
+ (mode_string): Use POSIX definitions.
+ (ftypelet): Likewise.
+ (rwx): Removed; no longer used.
+ * bucomm.c: Include bucomm.h.
+ (bfd_nonfatal, bfd_fatal): Argument is const.
+ (fatal): Make __STDC__ version.
+ * bucomm.h (mode_string): Declare.
+ * Makefile.in (bucomm.o): Depend upon bucomm.h
+
+Sun Jan 9 12:03:20 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * bucomm.c (xmalloc, xrealloc): Deleted.
+ * bucomm.h (xmalloc, xrealloc): Fix prototypes, to correspond to
+ libiberty version of functions.
+
+Thu Jan 6 06:18:15 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * binutils.texi: Add a chapter summarizing the ways to select
+ aspects of the target for each program.
+
+ * objdump.c (long_options, usage): Add long equivalents for all
+ remaining short options that lacked them.
+ * binutils.texi objdump.1: Document them.
+
+ * size.c (usage): Tweak usage message.
+ * size.1: Add missing `=' in examples.
+
+ * binutils.texi strip.1 objcopy.1 nlmconv.1 objcopy.c nlmconv.c:
+ Use "--target=bfdname" as the option to select the BFD target,
+ like nm and size already do.
+ Reserve "--format=format" for textual output selection options, but
+ for now keep old option names as obsolete for backward compatibility.
+
+ * strings.c (main, strings_object_file, usage): Add --target option.
+ * binutils.texi strings.1: Document it.
+
+Sat Jan 1 13:58:24 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ar.c (main): Add \n in error message.
+
+Thu Dec 23 12:23:11 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ gcc -Wall lint:
+ * ar.c (main): Put parens around assignment used as truth value.
+ * objcopy.c (strip_main): Remove unused variables. Return 0.
+ (copy_main): Remove unused variables. Return 0.
+ * objdump.c (display_bfd): Declare return value as void.
+ (stab_print): Use "" instead of 0 to initialize array.
+ (dump_stabs_1): Print vma using printf_vma.
+ (display_info): Put parens around assignment used as truth value.
+ * strings.c (print_strings): Cast printf arguments.
+
+ * objcopy.c (copy_main): Use copy_options, not strip_options.
+
+ * nlmheader.y (command): Warn about illegal date values.
+
+Wed Dec 15 11:18:03 1993 David J. MacKenzie (djm@frosty.eng.umd.edu)
+
+ * bucomm.c bucomm.h: Run through indent. De-ansidecl-ify.
+ (bfd_nonfatal): New function.
+ (bfd_fatal): Call it.
+
+ * objcopy.c (smart_rename): Do a copy if the dest file has
+ multiple hard links. Remove source file on successful copy.
+ Try to preserve mode and owner on successful rename.
+
+ * objcopy.c: Run through indent. Clean up a bit.
+ Make global variables static.
+ Make {input,output}_{target,filename}, show_version local
+ to various functions.
+ New global variable `status' for exit status.
+ (strip_main, copy_main): New functions with code from main.
+ (nonfatal): New macro. Use it globally instead of bfd_perror and
+ bfd_fatal.
+
+ (copy_object): Call mangle_sections with bfd_map_over_sections.
+ (mangle_sections): Adjust for new calling convention.
+
+Fri Dec 10 11:28:11 1993 Ian Lance Taylor (ian@deneb.cygnus.com)
+
+ * nlmheader.y (command): Accept MAP and FULLMAP without arguments.
+ * nlmconv.c (main): Change error message for MAP and FULLMAP.
+
+Thu Dec 9 17:47:19 1993 Ian Lance Taylor (ian@deneb.cygnus.com)
+
+ * nlmconv.c (main): Warn about imported symbols that are not in
+ the IMPORT list even if the IMPORT keyword is not used.
+
+ * nlmconv.c (debug, unlink_on_exit): New static variables.
+ (long_options): Add "debug" and "linker".
+ (main): Handle -d and -l arguments. Make command line input and
+ output files optional. Parse the command file before opening the
+ BFD's, which requires storing more information in local variables.
+ If INPUT names multiple files, link them together. Use OUTPUT for
+ the output file name if not named on command line.
+ (show_usage): Changed for new options.
+ (link_inputs): New function to automatically invoke linker to
+ handle multiple INPUT files.
+ (choose_temp_base_try, choose_temp_base, pexecute): New functions,
+ mostly copied from gcc/gcc.c.
+ * nlmconv.h (input_files, output_file): Declare.
+ * nlmheader.y (input_files, output_file): Define.
+ (command): Support INPUT with a string_list argument. Support
+ OUTPUT.
+ (string_list): Renamed from module_list.
+ * Makefile.in (nlmconv.o): Define LD_NAME based on
+ program_transform_name.
+
+Wed Dec 8 10:09:04 1993 Ian Lance Taylor (ian@deneb.cygnus.com)
+
+ * nlmheader.y (nlmheader_identify): New function. Use it to print
+ the program name just once, instead of with every error message.
+
+Mon Dec 6 16:11:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (long_options): Changed --header-info to --header-file
+ to match documentation and usage message.
+
+Sun Dec 5 01:31:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * objdump.c (dump_relocs): Avoid dereferencing a NULL sym_ptr_ptr
+ in a relocation.
+
+Thu Dec 2 16:00:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (main): Change various types from bfd_size_type to
+ size_t, since they have to be arguments to fread and fwrite.
+ Change set from char * to unsigned char *.
+ (select_output_format): Make mach argument unsigned. Handle
+ bfd_arch_alpha.
+ (setup_sections): Don't copy the .reginfo section of an ECOFF
+ file. Call bfd_set_reloc to initialize the relocation fields.
+ (copy_sections): Don't copy the .reginfo section of an ECOFF file.
+ Combine all relocs for a section.
+ (mangle_relocs): Change type of relocs to permit specific
+ functions to change it. Call alpha_mangle_relocs for alpha,
+ default_mangle_relocs for other architectures.
+ (default_mangle_relocs): New function. Adjust the address of all
+ relocs by the output_offset.
+ (i386_mangle_relocs): Change type of relocs argument. Cast length
+ argument to memmove to size_t.
+ (alpha_mangle_relocs): New function.
+
+Wed Nov 17 17:38:58 1993 Sean Eric Fagan (sef@cygnus.com)
+
+ * nlmconv.c (select_output_format): Use nlm32-sparc for
+ bfd_arch_sparc.
+
+Wed Nov 17 14:41:35 1993 Jeffrey Osier (jeffrey@thepub.cygnus.com)
+
+ * nlmconv.1: added man page
+ * objcopy.1: fixed format errors
+
+Wed Nov 17 12:03:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in: Use CFLAGS as well as LDFLAGS when linking.
+
+Wed Nov 17 04:50:55 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * strings.1: Fix typo.
+
+Mon Nov 15 12:03:20 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * Makefile.in (DISTSTUFF): Build "info".
+ (VERSION): Updated to cygnus-2.3.1; 2.3 has gone out.
+
+Sun Nov 14 00:27:24 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * objdump.c (dump_stabs): Handle stabs-in-som as implemented
+ by the new BFD SOM assembler.
+
+Sat Nov 13 07:14:05 1993 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * ar.1 c++filt.1 nm.1 objcopy.1 objdump.1 ranlib.1 size.1
+ strings.1 strip.1: Replace \(em in NAME section with \- so
+ makewhatis can grok it.
+
+Tue Nov 9 15:22:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (i386_mangle_relocs): Adjust reloc address by
+ section output_offset.
+
+Fri Nov 5 12:11:52 1993 Jeffrey Osier (jeffrey@thepub.cygnus.com)
+
+ * binutils.texi: added nlmconv chapter
+
+Wed Nov 3 16:10:50 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Change RUNTESTFLAGS to RUNTEST_FLAGS
+
+Wed Nov 3 15:09:23 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * Makefile.in (distclean): Don't get rid of dvi or info files.
+
+Tue Nov 2 13:29:59 1993 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * objcopy.c (S_ISLNK): Define as 0 if there's no S_IFLNK.
+
+Fri Oct 29 16:02:34 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * binutils.texi: Move objcopy docs into alphabetical order.
+
+ * objdump.c: Use xmalloc instead of malloc.
+
+Fri Oct 29 11:11:14 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * objdump.c (info): Rename to formats_info.
+ (dump_stabs_1): Better comments and formatting.
+
+Thu Oct 28 19:43:16 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * ar.c (main): Always create the archive when quick appending,
+ even if no input files have been given.
+
+Wed Oct 27 12:03:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (main): Set sharedDebugRecordOffset and
+ sharedDebugRecordCount fields in extended header.
+
+ * nlmconv.c (main): Force moduleName field to upper case.
+
+Mon Oct 25 16:45:42 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objcopy.c (main): Give a usage message if there are too many
+ arguments.
+
+Mon Oct 25 10:37:08 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * Makefile.in (install-info): Rewrite to take advantage of VPATH,
+ so FSF distributions (with info files in $(srcdir)) install
+ properly.
+ (DISTSTUFF): Build nlmheader.c too.
+
+Fri Oct 22 11:43:23 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * ar.c (program_name): Don't define here.
+ * objdump.c: Include "bucomm.h".
+ (xmalloc): Don't declare here.
+ (program_name): Don't define here.
+ (program_version): Fixed type in declaration.
+ * size.c: Include "bucomm.h".
+ (program_name): Don't declare here.
+
+Fri Oct 22 14:10:41 1993 Mark Eichin (eichin@cygnus.com)
+
+ * objdump.c (fprintf): hide declaration in FPRINTF_ALREADY_DECLARED
+
+Fri Oct 1 12:43:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (i386_mangle_relocs): Resolve and remove PC relative
+ relocs against defined symbols in the same section.
+
+Thu Sep 30 16:46:26 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * Makefile.in (binutils.dvi): use TEXIDIR to find texinfo.tex
+
+Sat Sep 25 18:09:29 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objcopy.c (simple_copy, smart_rename): New functions.
+ (main): Use them.
+
+Fri Sep 24 15:38:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (clean, distclean): Recurse into testsuite.
+
+Thu Sep 23 01:05:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objcopy.c (setup_sections, copy_sections): If stripping, don't
+ copy SEC_DEBUGGING sections.
+ * objdump.c (dump_headers): Print SEC_DEBUGGING flag.
+
+ * objdump.c (usage): Mention --stabs.
+
+ * objcopy.c (copy_object): Copy all applicable file flags.
+ (copy_file): Don't copy EXEC_P specially here.
+
+Mon Sep 20 19:28:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (main): Adjust data section size to correspond to bss
+ alignment adjustment. Clear BSF_SECTION_SYM if symbol is moved to
+ a different section. Use time_t for time variable.
+ (setup_sections): Only put sections with contents in output NLM.
+ (i386_mangle_relocs): No symbols are common at this point. Add
+ casts to avoid warnings.
+
+Fri Sep 10 11:00:40 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * objdump.c: Made the --stabs option work for stabs-in-coff.
+ (ELF_STAB_DISPLAY): Removed.
+ (dump_elf_stabs): Renamed to dump_stabs, changed to run for
+ any object file format.
+ (dump_elf_stabs_1): Renamed to dump_stabs_1, added calls to
+ generic BFD routines for non-ELF case, changed format of message
+ for no-section-found case.
+ (display_bfd): Always call dump_stabs if requested.
+ (dump_data): Call bfd_section_size to get section size.
+
+Fri Sep 10 08:12:23 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (install): Don't put strings in tooldir/bin.
+
+Mon Sep 6 15:39:04 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (total_bss_size): Removed.
+ (main): Set the bss vma to always follow the data section. Move
+ symbols into new sections, and adjust values by output_offset.
+ (setup_sections): Don't copy all sections, but instead point all
+ text sections to .text, all data sections to .data, and all bss
+ sections to .bss.
+ (copy_sections): Adjust accordingly.
+
+Thu Sep 2 12:34:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Only build nlmconv if configured for a NetWare target.
+ * configure.in: If we have some *-*-netware* target, or are using
+ all targets, set BUILD_NLMCONV to $(NLMCONV_PROG) in Makefile.
+ * Makefile.in (PROGS): Use $(BUILD_NLMCONV) rather than
+ $(NLMCONV_PROG).
+
+Tue Aug 31 14:13:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * objdump.c (ARCH_all): Define ARCH_hppa too.
+ (dump_headers): Don't test for SEC_BALIGN if it's not defined by
+ bfd.h.
+
+Tue Aug 31 13:29:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * nlmconv.c (main): Force creation of .bss section. Set up the
+ sections before looking at the symbols. Move all common symbols
+ into .bss section. Automatically define _edata and _end. Only
+ export symbols in the export list, with multiple prefixes if
+ necessary. Warn if no version. Always create extended header.
+ Set date automatically if not already set.
+ (setup_sections): Count size of bss sections.
+ (mangle_relocs, i386_mangle_relocs): Accept section argument, and
+ take reloc_count as a changeable pointer; changed callers.
+ (i386_mangle_relocs): Remove PC relative relocs within a section,
+ as they require no adjustment.
+ * nlmheader.y: Fixed memory allocation throughout: token STRING is
+ now allocated on the heap, and freed if not needed. Null
+ terminated copyright message. Accept version with only two
+ strings.
+ (symbol_list_opt): New nonterminal, either symbol_list or empty.
+ (symbol_list): Use left recursion to avoid overflowing parser
+ stack.
+ (yylex): Rearranged beginning of line check. Accept quoted
+ strings using single quotes. End generic argument at comment
+ character or parentheses.
+ (string_list_append): Fixed.
+ (string_list_append1): New function.
+
+ * bucomm.h: The first argument to xrealloc is PTR, not char *.
+ * bucomm.c (xrealloc): Use PTR rather than char *.
+ * Makefile.in (objdump.o): Depend upon config.status to notice
+ --with-targets changes.
+ (nlmconv.o): Depend upon bucomm.h.
+
+Tue Aug 17 09:46:01 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * configure.in: Don't pass cpu to config.bfd.
+
+Thu Aug 12 16:43:04 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in ($(NM_PROG)): Depend on demangle.o.
+ (demangle.o): New target.
+ (cplus-dem.o): Depend on it, to force compilation order when doing
+ parallel compiles.
+
+ * nm.c (print_symbol_info_{bsd,sysv,posix}): Take a bfd arg.
+ (struct output_fns print_symbol_info): Ditto.
+ (long_options, usage, main): Add -C --demangle option.
+ (print_symname): New function, demangling if requested.
+ (print_symbols, print_symbol_info_{bsd,sysv,posix}): Use it.
+
+Wed Aug 11 22:57:23 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in: Put CFLAGS last in compilation rules and omit from
+ linking rules. Use ARCHDEFS to compile objdump.c.
+ Update dependencies.
+ * configure.in: Construct ARCHDEFS based on the BFD target makefile
+ fragments.
+ * objdump.c: Conditionalize calls to the print_insn_ARCH functions
+ according to ARCHDEFS.
+
+Thu Aug 12 08:06:15 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ar.c: Removed obsolete and non-functional GNU960 code.
+
+Wed Aug 11 13:08:26 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * size.c (berkeley_sum): New function.
+ (bsssize, datasize, textsize): New global variables.
+ (bss_section_name, data_section_name, text_section_name): Removed.
+ (print_berkeley_format): Map berkeley_sum over all the sections,
+ rather than only reporting sizes of specifically named sections.
+ * Makefile.in ($(OBJDUMP_PROG)): Removed dependency on size.o.
+
+Tue Aug 10 10:46:01 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * nlmconv.c, nlmconv.h, nlmheader.y: New files for program to
+ convert object files into NetWare Loadable Modules.
+ * Makefile.in (NLMCONV_PROG): New macro, define to be nlmconv.
+ (PROGS): Add NLMCONV_PROG.
+ (nlmheader.c, nlmheader.o, nlmconv.o, $(NLMCONV_PROG)): New
+ targets.
+
+Thu Aug 5 15:48:32 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in: define MAKEOVERRIDES to an empty string
+
+Wed Aug 4 17:08:08 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * objcopy.c (copy_file): Make failures to process a file nonfatal.
+
+Mon Aug 2 11:28:23 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * nm.c: Add -B option, like --format=bsd.
+
+Tue Jul 27 16:29:54 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objcopy.c (copy_file): If the file is neither an object nor an
+ archive, give an error rather than returning success.
+
+Mon Jul 19 16:13:40 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * objdump.c (objdump_print_address): Prefer non-local symbols over
+ local ones, and especially discriminate against debugging symbols.
+ Also, for relocateable files, try to find a symbol in the current
+ section, instead of picking one from some random section with a
+ convenient value (read, section offset).
+ (disassemble_data): Cast argument to malloc to size_t first.
+ (dump_data): Likewise.
+ (dump_relocs): If a single section name is specified, show relocs
+ only for that section. Otherwise, silently omit sections without
+ relocs. Format table nicely even if values are printed using 16
+ digits instead of 8.
+
+Fri Jul 16 15:19:59 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * nm.c: Changes for final version of POSIX.2.
+ (print_symbol_filename_{bsd,sysv,posix}): New functions.
+ (formats): Add an element for a pointer to them.
+ (print_symbols): Call it.
+ (print_object_filename_posix, print_archive_member_posix): Produce
+ output according to new POSIX.2 spec.
+
+ * strings.c (print_strings): Handle STREAM being NULL.
+ (strings_a_section): Pass a NULL.
+ (main): Don't open /dev/null.
+
+Thu Jul 15 12:44:09 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (disassemble_data): Handle the m88k.
+ (display_bfd): Use bfd_errmsg, rather than just claiming that the
+ bfd is not an object file.
+
+Mon Jul 12 17:55:34 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in (TAGS): make work again by naming directories
+ explicitly rather than depending on undefined macros.
+ (INSTALL_XFORM): correct bad install target.
+
+Fri Jul 2 16:58:34 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * strings.c: Doc fixes.
+
+Sun Jun 27 13:35:24 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in: Note dependencies on bucomm.h.
+ (cplus-dem.o): Link c++filt with version.o.
+
+ * strings.c: Include bucomm.h and add prototypes to other decls.
+ Remove -h option.
+
+ * bucomm.h: Declare xrealloc.
+
+ * nm.c, objcopy.c, objdump.c, size.c, strings.c (main, usage): Add
+ --help option. Put "GNU" in the version message.
+ (usage): Take stream and exit status as args.
+ (main): Pass new args to usage.
+
+Fri Jun 25 23:12:12 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * strings.c, strings.1: New files.
+ * binutils.texi: Document strings.
+ * Makefile.in: Add rules for it.
+
+Fri Jun 25 20:44:43 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * objdump.c: Use size-independent bfd elf section names.
+
+Sun Jun 20 23:09:06 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * objdump.c (objdump_print_address): Handle wide offsets by
+ calling sprintf_vma.
+
+Fri Jun 18 14:29:12 1993 Per Bothner (bothner@deneb.cygnus.com)
+
+ * objdump.c (syms2): Removed unused variable.
+ * objdump.c (remove_useless_symbols): New function.
+ * objdump.c (comp): Simplify.
+ * objdump.c (dis-assemble_data): Make simpler and more
+ efficient how we filter out useless symbols: Just filter
+ BEFORE the sort (using remove_useless_symbols).
+ * objdump.c (objdump_print_address): Simplify.
+ Change output syntax to match gdb.
+
+Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: canonicalize install.sh; for use within
+ this directory (and subdirs)
+
+Mon Jun 14 12:13:22 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in (install, install-info): remove parentdir support,
+ use INSTALL_XFORM; define INSTALL_XFORM
+
+Thu Jun 10 17:29:21 1993 Per Bothner (bothner@cygnus.com)
+
+ * objcopy.c (copy_object): Fix bad size passed to xmalloc().
+
+Mon Jun 7 12:41:12 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (INCLUDES): Add -I../bfd for sysdep.h and bfd.h.
+ * configure.in: No longer need to configure to get sysdep.h.
+ * objcopy.c (copy_object): Fix symbol table handling.
+
+Fri Jun 4 17:20:03 1993 Per Bothner (bothner@cygnus.com)
+
+ * objcopy.c (filter_symbols): Cannot filter the symbols
+ in place, because that confuses the relocs, so take separate
+ parameter for output array.
+ * objcopy.c (sympp): Make two variables: isympp and osympp.
+ * objcopy.c (copy_object): Allocate separate array (osympp)
+ for filtered symbols.
+
+Fri Jun 4 10:51:44 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: change recursion test to presence of a configured
+ testsuite directory
+
+Thu Jun 3 14:05:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (underscore.c): Hack the backquoted command so it
+ doesn't cause Solaris make to bomb.
+
+Thu Jun 3 10:40:19 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * Makefile.in: added c++filt and objcopy to MANPAGES variable
+
+Thu Jun 3 00:32:52 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: rename LOADLIBES to EXTRALIBS
+
+Wed Jun 2 18:30:24 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * c++filt.1, objcopy.1: new man pages
+
+Fri May 28 15:01:24 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (install): Also install ar and ranlib in
+ $(tooldir)/bin; needed for building libgcc.a.
+ * objdump.c (objdump_print_address): Fix the check
+ "coincidental" label matches by dis-allowing undefined
+ or com symbols.
+
+Thu May 27 16:58:31 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * biutils.texi: revised c++filt chapter
+
+Wed May 26 17:24:17 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Pass down CC and CFLAGS.
+
+Tue May 25 00:26:47 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * objdump.c (slurp_symtab): Print warning for bad symbol table.
+ (bfd_elf32_find_section, Elf32_Internal_Shdr): Updated
+ declarations and uses.
+
+ * Makefile.in (DISTSTUFF): Don't build binutils.mm.
+
+Fri May 21 10:51:19 1993 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * nm.c: Add -f/--format, -P/--portability, -t/--radix options.
+ Make global variables static.
+ (main): Make -v like -n, not -V, and make -A like -o, for POSIX.2.
+ (set_print_radix, set_output_format,
+ print_{object_filename,archive_filename,archive_member,symbol_info}
+ {bsd,sysv,posix}): New functions.
+ (display_file, print_symbols): Call them.
+
+ * ar.c: Improve error messages.
+
+ * nm.c (main): Handle long options that just set a flag.
+
+ * nm.c (main), ar.c (do_show_version), objcopy.c (main), size.c
+ (main): Exit after printing the version number, per the GNU coding
+ standards.
+
+Mon May 17 13:20:25 1993 Per Bothner (bothner@cygnus.com)
+
+ * README, Makefile.in: Minor updates for 2.2.
+
+Fri May 14 11:12:26 1993 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in (underscore.c): Automatically generate
+ (using nm) a file with the variable prepends_underscore.
+ * Makefile.in (c++filt): Link underscore.o with cplus-dem.o
+ so that initial underscores get removed iff appropriate.
+ * binutils.texi: Preliminary documentation for c++filt.
+ * Makefile.in, binutils.texi: Set to version 2.2.
+
+ * NEWS: Mention copy->objcopy renaming and new c++filt program.
+
+Wed May 12 12:05:36 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (cplus-dem.o, $(DEMANGLER_PROG)): Build the
+ demangler via cplus-dem.o, rather than directly from the .c file.
+
+ * objcopy.c: Renamed from copy.c, updated comments accordingly.
+ * Makefile.in, binutils.texi: Renamed copy to objcopy.
+ * is-strip.c, maybe-strip.c, not-strip.c: Updated comments for
+ rename of copy to objcopy.
+
+Mon May 10 17:20:18 1993 Per Bothner (bothner@cygnus.com)
+
+ * binutils.texi (strip, -v option): Fix typo.
+
+Fri May 7 13:57:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (RUNTEST): Define.
+ (FLAGS_TO_PASS): Pass down RUNTEST.
+
+Tue May 4 10:06:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (DEMANGLER_PROG): Name it c++filt.
+ (PROG): Also build and install COPY_PROG.
+
+Mon May 3 19:11:48 1993 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Change definition of $(tooldir) to match FSF.
+
+Wed Apr 28 23:41:32 1993 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * size.c (usage): Add missing options.
+ (main): Clean up option parser.
+
+ * objdump.c (usage): Add missing options.
+ (display_file): Print program name before calling
+ bdf_perror.
+
+ * nm.c (usage): Add missing options.
+ (main): Clean up option parser.
+ (display_file): Print program name before calling
+ bdf_perror.
+
+ * copy.c (copy_usage, strip_usage): Add missing options.
+
+ * ar.c (usage): New function.
+ (main): Call it.
+ (open_inarch, do_quick_append): Print program name before calling
+ bdf_perror.
+
+Thu Apr 22 15:01:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * nm.c (main): Accept and ignore -A and -B for MIPS compatibility.
+
+Mon Apr 19 14:06:59 1993 Rob Savoye (rob@cygnus.com)
+
+ * Makefile.in: Added FLAGS_TO_PASS so tests get run on freshly
+ built binaries if they exist. (otherwise the path)
+
+Wed Apr 7 22:22:50 1993 Rob Savoye (rob@cygnus.com)
+
+ * Makefile.in: Changed check target to use DejaGnu.
+
+Thu Apr 1 12:37:13 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in: Remove am29k-pinsn.c, i960-pinsn.c.
+ objdump.c: a29k and i960 are `disassemble' not `print'.
+
+ * objdump.c: Rename print_address to objdump_print_address
+ and change parameters.
+ (disassemble_data): Use objdump_print_address.
+
+Wed Mar 31 10:25:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * objdump.c (disassemble_data): print_insn_sparc is now a
+ `disassemble' not a `print'.
+ Makefile.in: Remove sparc-pinsn.c (now in libopcodes.a).
+
+ * objdump.c (disassemble_data): Use new read_memory_func stuff.
+
+Thu Mar 25 10:38:11 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * objdump.c (fprintf): Declaration of variadic function had better
+ be a prototype for ANSI C systems.
+
+Mon Mar 22 23:19:46 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: rename test-install to install-check
+
+Fri Mar 19 14:40:08 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * objdump.c (disassemble_data): Add H8500.
+
+Fri Mar 19 10:56:51 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * objdump.c (usage): Mention long options.
+
+Thu Mar 18 14:22:17 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * nm.c: Modify behavior of -o flag for archives to match
+ BSD4.4 and Sunos 4: Prefix archive name before each line.
+
+ * m68k-pinsn.c: Removed. Subsumed by ../opcodes/m68k-dis.c.
+ * i386-pinsn.c: Removed. Subsumed by ../opcodes/i386-dis.c.
+ * Makefile.in: Adjust accordingly.
+ * objdump.c: Support new-style disassemblers (ones that use
+ the interface of ../include/dis-asm.h).
+
+Thu Feb 25 15:57:00 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: When making tar file, remove texinfo/*,
+ except for texinfo/texinfo.tex.
+ * ardup.c: Add extern declaration of strdup.
+ * Makefile.in (testsuite): Add 'else true' since otherwise
+ Ultrix /bin/sh complains.
+
+Wed Feb 24 19:44:18 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Set VERSION to 2.1.
+ * README, NEWS: Updates.
+ * nm.c: Add -v as a synonym for -V.
+
+Tue Feb 23 19:00:50 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * configure.in: added testsuite to configdirs.
+ * Makefile.in: added support for building testsuite.
+
+Mon Feb 22 22:52:10 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * objdump.c (disassemble_data): Print function names when
+ given by bfd_find_nearest_line. If not - still print
+ line numbers.
+
+Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * binutils/testsuite: made modifications to testcases, etc., to allow
+ them to work properly given the reorganization of deja-gnu and the
+ relocation of the testcases from deja-gnu to a "tool" subdirectory.
+
+Mon Feb 22 10:27:24 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * objdump.c (dump_data): Free up section contents each time
+ through the loop. Reported by minyard@bnr.ca.
+
+Sun Feb 21 10:55:55 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * binutils/testsuite: Initial creation of binutils/testsuite.
+ Migrated dejagnu testcases and support files for testing nm to
+ binutils/testsuite from deja-gnu. These files were moved "as is"
+ with no modifications. This migration is part of a major overhaul
+ of dejagnu. The modifications to these testcases, etc., which
+ will allow them to work with the new version of dejagnu will be
+ made in a future update.
+
+Fri Feb 12 10:05:20 1993 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (LIBIBERTY_SRC_DIR, LIBIBERTY_BIN_DIR): New macros.
+ * Makefile.in (LIBIBERTY): Use LIBIBERTY_BIN_DIR.
+ * Makefile.in (DEMANGLER_PROG): New program to build. Add macro
+ and rule.
+ * Makefile.in (PROGS): Add DEMANGLER_PROG.
+
+Tue Jan 26 11:56:33 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * copy.c, nm.c, objdump.c, size.c: Use new bfd_is_com_section
+ macro rather than checking for equality to bfd_com_section.
+
+Fri Jan 8 15:50:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (disassemble_data): Fix code to find first useless
+ symbol.
+
+Thu Jan 7 13:13:31 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * objdump.c (disassemble_data): Use mips_print_insn for MIPS.
+ Don't core dump if bfd_find_nearest_line returns false.
+
+Wed Jan 6 17:14:01 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * objdump.c (disassemble_data): know how to disassemble z8000s
+ too.
+
+Wed Jan 6 15:16:27 1993 Per Bothner (bothner@cygnus.com)
+
+ * arsup.h (interactive), bucomm.h (program_name): Prefix
+ with 'extern', to avoid warnings from some compilers.
+
+Wed Jan 6 15:14:11 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * arparse.y: fix unnecessary shift/reduce
+
+Tue Dec 22 15:46:56 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Make check depend on all.
+ * Makefile.in (distclean): Remove sysdep.h.
+ * size.c: Use %u format where appropriate.
+ * objdump.c: Standardize: L_SET -> SEEK_SET.
+ * objdump.c: Use new macro bfd_asymbol_bfd.
+ * configure.in: Allow std-host as the default ${mys_host}.
+
+Thu Dec 17 19:38:19 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added dvi target, define and use TEXI2DVI
+
+Tue Dec 15 18:05:07 1992 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in (dist): Fix permissions before release.
+ * size.c: Use bfd_size_type (and long) where appropriate.
+ * ar.c: Make writing a map the default, to be compatible
+ with SYSV and Posix.2. Remove some bogus kludges that
+ handled __.SYMDEF directly.
+ * NEWS: New file.
+
+Mon Nov 9 13:36:53 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: flex no longer needs the -S flag
+
+Sat Nov 7 15:06:13 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * ar.c (extract_file): utime needs a pointer to a utimbuf
+
+ * Makefile.in: handle -I includes better, adding $(BASEDIR)/bfd to
+ the list (since some of the bfd/hosts/*.h files include other
+ files from that directory)
+
+Fri Nov 6 00:12:51 1992 John Gilmore (gnu@cygnus.com)
+
+ * i960-pinsn.c (MEM_MAX, MEM_SIZ): Set upper bound properly.
+
+Thu Nov 5 03:37:15 1992 John Gilmore (gnu@cygnus.com)
+
+ Clean up some old BFD ansification macros.
+
+ * arsup.h, bucomm.h, objdump.h: Remove EXFUN from binutils.
+ It still remains as a local macro in gmalloc.c, which is derived
+ from some other copy of GNU Malloc somewhere (FIXME).
+
+ * ar.c, objdump.c, size.c: Replace EXFUN with PROTO. Make static
+ fns really static.
+ * arsup.h: Declare extract_files.
+
+Mon Nov 2 12:42:11 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * ar.c (extract_file): instead of checking USG: if POSIX_UTIME,
+ use utime and utimbuf structure, otherwise if USE_UTIME use utime
+ and array of two longs, otherwise use utimes.
+
+Thu Oct 15 13:57:35 1992 Per Bothner (bothner@cygnus.com)
+
+ * binutils.tex: Document yesterday's changes to strip and copy.
+
+Wed Oct 14 13:22:14 1992 Per Bothner (bothner@cygnus.com)
+
+ * copy.c: Re-do command-line parsing to use getopt_long().
+ Add long option names. Re-think option letters to be more
+ consistent.
+ * copy.c: New function filter_symbols() for stripping only
+ debug-symbols and/or local symbols. Use these to support
+ the previously-missing options of the old FSF strip.
+
+Tue Oct 13 01:24:20 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in (host): Use ${srcdir}/../bfd/configure.host rather
+ than repeating a copy of it here.
+
+Wed Oct 7 12:53:52 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * copy.c (main): Even if is_strip, accept -d argument indicating
+ alternate output format. Needed by gdb for Nindy.
+
+ * m68k-pinsn.c (print_insn_arg): Handle new "`" operand type.
+
+Tue Oct 6 16:33:56 1992 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * binutils.texi: added documentation for "copy"
+
+Tue Oct 6 14:22:56 1992 Per Bothner (bothner at PersSony)
+
+ * Makefile.in (*clean rules): Some cleaning up.
+ * Makefile.in (dist): Make diststuff in gprof for a dist.
+
+ * ar.c (do_show_version): New function.
+ * ar.c (main): Fix so "ar -V" works.
+
+Thu Oct 1 22:44:45 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: now uses the cpu-vendor-os triple instead of
+ nested cases.
+
+Fri Sep 25 22:41:08 1992 John Gilmore (gnu@cygnus.com)
+
+ * i960-pinsn.c: Change bzero to memset.
+ * sparc-pinsn.c: Change index to strchr.
+
+Mon Sep 21 14:39:56 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68k-pinsn (print_insn_arg, fetch_arg): added support for
+ operands to memory management instructions, from WRS.
+
+Tue Sep 15 15:26:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): if $(tooldir) exists, install nm and
+ strip in $(tooldir)/bin.
+
+Thu Sep 3 11:57:40 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Let's call it version 2.0.
+
+Wed Sep 2 00:25:13 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Bump to version 0.98.
+ * TODO, README: Minor updates.
+
+ * Makefile.in: Added mostlyclean, distclean rules,
+ and cleaned up clean, realclean.
+
+Sun Aug 30 21:18:59 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: map program names through program_transform_name
+ when installing.
+
+Sun Aug 30 18:09:03 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Bump to versions 1.97.90.
+ * cplus-dem.c: Removed. Was nowhere used - and if some
+ programs are changed to to demangling should now use the
+ versions in libiberty.
+
+Thu Aug 27 12:58:09 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ * configure.in: add we32k
+
+Mon Aug 24 14:53:42 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ar.c (map_over_members): if the element of the archive has a
+ null name, fill it in.
+
+ * nm.c (do_one_rel_file): only warn if a bfd's flags say there
+ will be symbols and there aren't any.
+
+Wed Aug 19 11:20:25 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68k-pinsn.c: handle new operand type 'r', introduced for cas2.
+
+Tue Aug 18 20:45:48 1992 Rob Savoye (rob@cygnus.com)
+
+ * nm.c objdump.c: Added support for a +version (-V)
+ to print the version number.
+
+ * ar.c, copy.c: Added support for a -V option to print
+ the version number.
+
+Tue Aug 18 13:28:44 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/mh-apollo68v: removed -g from CC definition.
+
+ * Makefile.in: always create installation directories.
+
+Mon Aug 17 18:33:41 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * m68k-pinsn.c: Minor fix in style of output (don't use
+ range to indicate floating point control registers).
+
+Tue Aug 11 23:42:21 1992 Per Bothner (bothner@cygnus.com)
+
+ * ar.c (main): Don't *always* set the verbose flag!
+
+Wed Aug 5 11:25:27 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * copy.c: When is_strip (because it is invoked as the strip
+ program), follow traditional argv processing:
+ 'strip file1 file2' now strips file1 and file2, rather
+ than stripping file1 (as input), leaving output in file2.
+
+Mon Jul 27 16:28:08 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * objdump.c (display_info, display_info_table): Call
+ bfd_set_format() on dummy bfd before using it (twice).
+ * ar.c: Make sure archive is created on command 'r'
+ even when no elements are inserted. (Clean up and
+ simplify some non-working related code.)
+
+Mon Jul 20 02:48:38 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * configure.in: hppa support doesn't assume hp OS (from sef).
+
+Sat Jul 18 14:35:22 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognize hppa hosts (bsd & hpux), error messages
+ to stderr, not stdout
+
+Fri Jul 17 18:39:44 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * ar.1, binutils.texi, i960-pinsn.c, nm.1, objdump.1, ranlib.1,
+ size.1, sparc-pinsn.c, strip.1: removed rcsid's.
+
+Thu Jul 16 16:55:24 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.dos: removed rcsid.
+
+Thu Jul 16 08:23:07 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * objdump.c (display_bfd): print state of BFD_IS_RELAXABLE too
+
+Tue Jun 30 20:26:15 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * Makefile.in: Add program_suffix (parallel to program_prefix)
+
+Thu Jun 25 04:52:45 1992 John Gilmore (gnu at cygnus.com)
+
+ * nm.c (sorters): Lint. Remove excess whitespace.
+
+Wed Jun 24 13:48:07 1992 Per Bothner (bothner@cygnus.com)
+
+ * nm.c (valueof macro): Add missing parentheses.
+ (Their lack screwed up numeric_forward().)
+
+Sun Jun 14 10:33:27 1992 John Gilmore (gnu at cygnus.com)
+
+ * objdump.c (dump_elf_stabs): Also dump .stab.index and
+ .stab.excl sections.
+ (dump_elf_stabs_1): Split out main body of old dump_elf_stabs.
+ * objdump.1, binutils.texi: Document new sections dumped.
+
+Fri Jun 12 22:23:35 1992 John Gilmore (gnu at cygnus.com)
+
+ * size.c, objdump.c, bucomm.c: Lint.
+
+Thu Jun 11 01:19:06 1992 John Gilmore (gnu at cygnus.com)
+
+ * objdump.c (dump_elf_stabs): New feature: --stabs prints out a
+ .stab section from an ELF file. Installed under #ifdef
+ ELF_STAB_DISPLAY so it can be easily disabled, since it requires
+ bfd-internals header files and such.
+ * objdump.1, binutils.texi: Update for --stabs. Also fix
+ objdump's doc to use -- rather than + for long options.
+ (FIXME: Not yet fixed everywhere in binutils.texinfo.)
+
+Wed Jun 10 07:53:24 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * objdump.c(display_info), patches from
+ mohring@informatik.tu-muenchen.de to print the table much more
+ nicely.
+
+Thu May 28 13:36:16 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * objdump.c: Add another enum->int cast, for the sake of
+ old compilers (such as PCC).
+
+Wed May 27 13:01:44 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * arlex.l: Don't include <sysdep.h> (unneeded conflicts).
+ Add declaration of strdup().
+
+Fri May 22 13:40:37 1992 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Use srcdir instead of VPATH in ldgram/ldlex
+ rules, since these are used when building a distribution.
+ * Makefile.in (arlex.c): Don't re-direct output, since that
+ leaves a bogus output files if it fails.
+
+ * arlex.l: Make work with lex, for what it's worth.
+ * Makefile.in: Better lex support.
+ * Makefile.in (dist): Generate flex and bison outputs
+ for distribution.
+
+Thu May 14 17:17:59 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: get BISON definition right.
+
+Fri May 8 07:47:08 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * sanity.sh: default TMPDIR to ".".
+
+Thu May 7 12:34:50 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * binutils.texi: add doc for ar command language.
+
+Wed May 6 18:05:36 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * arparse.y: make END call ar_end
+ * arsup.c (ar_end): added, deletes temp file if archive session
+ aborted.
+
+
+Wed May 6 11:08:53 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: use bison & flex from ../ if they exist. Also,
+ FLEX->LEX.
+
+ * sanity.sh: remove temporary directory when finished.
+
+Tue May 5 12:00:58 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Bump to version 1.97.
+ * ar.c: Declare errno for machines that need it.
+
+Mon May 4 23:29:51 1992 John Gilmore (gnu@cygnus.com)
+
+ * objdump.c (display_info): Handle error cases without coredump.
+ Close the dummy temporary file we open in the loop.
+ * Makefile.in (arsup.o): Add kludge to build with Sun Make.
+
+Fri May 1 16:20:23 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added test-install target.
+
+ * sanity.sh: new file.
+
+ * Makefile.in: use sanity test on make check.
+
+Tue Apr 21 13:38:37 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: rework CFLAGS so that they can be passed on the
+ command line to make. Remove MINUS_G. Default CFLAGS to -g.
+
+Wed Apr 15 14:33:07 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * arsup.c, arsup.h, arparse.y, arlex.l: support for archive
+ scripting language.
+
+Fri Mar 6 21:54:53 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added check target.
+
+Thu Mar 5 21:35:49 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added clean-info target.
+
+Tue Mar 3 15:36:37 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: remove $(COPY_PROG) from PROGS. It shouldn't be
+ installed. added tooldir and program_prefix.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Sun Feb 16 12:53:02 1992 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Bump version to 1.96, and remove -beta
+ suffix from distribution name.
+ * m68k-pinsn.c: New macro COERCE_SIGNED_CHAR to extract
+ the signed value of a character (even if chars are unsigned).
+ * sparc-pinsn.c: Add new operand types.
+
+Thu Feb 6 12:14:19 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * objdump.c (disassemble_data): don't print a section's contents
+ if it's not loadable (eg bss)
+
+Tue Jan 28 11:11:06 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * m68k-pinsn.c (print_insn_arg): fixed so that -ve branch
+ displacements don't get printed as large +ve ones.
+
+Fri Jan 24 14:47:53 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * copy.c, nm.c, objdump.c, size.c : changed to use the
+ new reloc scheme.
+
+
+Mon Dec 30 18:34:41 1991 Per Bothner (bothner at cygnus.com)
+
+ * bucomm.c (print_arelt_descr): Tweek the output format
+ so that 'ar tv' output follows Posix 1003.2/D11.
+ Output is now also identical to Sun's (except __.SYMDEF).
+
+Mon Dec 30 06:09:53 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Make `make' output more readable.
+
+Wed Dec 18 15:04:45 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Bump to version 1.94.
+
+Wed Dec 11 16:48:09 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * ar.c: added "b" to fopens for dos
+ * configdj.bat, makefile.dos new files from DJ
+
+Tue Dec 10 04:07:26 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Sat Dec 7 17:09:37 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * bucomm.h: created to hold prototypes of bucomm.c
+ * objdump.h: created to hold prototyes of objdump.c
+ * am29k-pinsn.c: include objdump.h
+ * ar.c: include bucomm.h, get ar.h from the right place and
+ include libbfd.h
+ * bucomm.c: defunize bfd_fatal
+ * copy.c: include bucomm.h, lint.
+ * i960-pinsn.h: include bucomm.h
+ * m68k-pinsn.h: lint
+ * nm.c: include bucomm.h, lint
+ * objdump.c: lint
+ * sparc-pinsn.c: include objdump.h
+
+
+
+Fri Dec 6 23:02:14 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: added standards.text support. install using
+ INSTALL_PROGRAM and INSTALL_DATA.
+
+ * configure.in: configure now does all of it's work from objdir so
+ make file existence tests against ${srcdir}.
+
+Thu Dec 5 22:46:22 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+Wed Dec 4 22:42:03 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Bump to version 1.93.
+ * Makefile.in: Add make-strip.o:maybe-strip.c dependency
+ for make versions that provide half-baked VPATH-support (e.g. Sun's).
+ * size.c: Improvements suggested by
+ "david d [zoo] zuhn" <zoo@aps1.spa.umn.edu>:
+ - Don't emit (Berkeley) headers if no files were found.
+ - Return a non-zero return code on failure.
+
+Sat Nov 30 21:34:19 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ Changes due to include file renaming:
+ * am29k-pinsn.c: a29k-opcode.h -> opcode/a29k.h
+ * sparc-pinsn.c: sparc-opcode.h -> opcode/sparc.h
+ * m68k-pinsn.c: m68k-opcode.h -> opcode/m68k.h
+ * nm.c: stab.gnu.h -> aout/stab_gnu.h
+
+Tue Nov 19 19:20:43 1991 Per Bothner (bothner at cygnus.com)
+
+ * README: Mention MINIMIZE flag for bfd's make.
+
+Mon Nov 18 12:05:37 1991 Per Bothner (bothner at cygnus.com)
+
+ * README: Various improvements.
+
+Sun Nov 17 23:40:59 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Bump to version 1.92.
+ * version.c, Makefile.in: Get version string from Makefile.
+ * copy.c, is-strip.c, not-strip.c, maybe-strip.c, Makefile.in:
+ Make the same change that we earlier did for ar/ranlib:
+ Generate two different binaries for strip and copy and use
+ a global variable with different values to distinguish
+ ostrip from copy. (-1 means to use argv[0] to decide,
+ so you can get the old behavior, but it is no longer the default).
+ * copy.c (copy_file): Set EXEC_P of output bfd if input is so.
+ * copy.c (main): If is_strip==-1, compare last 5 chars
+ of argv[0], not the whole path.
+ * copy.c (main): Return 0, not 1.
+ * copy.c (setup_sections): Fix due to change in bfd_make_section
+ now failing if asked for a duplicate section.
+ * strip.c, ostrip.c: Removed obsolete files.
+ * ar.c, not-ranlib.c, maybe-ranlib.c:
+ Change encoding of is_ranlib variable to be consistent
+ with is_strip for strip.copy (i.e -1 to means use argv[0]).
+
+Thu Nov 14 20:11:02 1991 Per Bothner (bothner at cygnus.com)
+
+ * version.c (program_version): Update to version 1.92.
+
+Tue Nov 12 16:17:53 1991 Per Bothner (bothner at cygnus.com)
+
+ * ar.c (get_pos_bfd): Previous fix was missing a "break".
+
+Thu Nov 7 08:55:56 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * am29k-pinsn.c: Fixed bug in mtacc, dmac and fmac instruction
+ encodings. (Thaks to David Wood)
+
+Sun Nov 3 14:50:23 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in ($(DIST_NAME).tar.Z), TODO: Various fixes.
+ * ar.c (get_pos_bfd): Fix to handling of before/after
+ positioning options.
+ * bucomm.c (fatal): MISSING_VFPRINTF is no longer an issue,
+ since libiberty contains vfprintf etc if otherwise missing.
+ * m68k-pinsn.c (print_insn_arg): Support BB/BW/BL
+ type operands, as used by branch instructions.
+ * nm.c: Delegate printing of symbols to BFD,
+ by using bfd_print_symbol to do the formatting.
+
+Mon Oct 28 11:20:47 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * ar.c (write_archive.c): added unlink before rename since some
+ systems can't rename onto an existant file.
+
+Mon Oct 21 09:47:23 1991 Steve Chamberlain (steve at rtl.cygnus.com)
+
+ * nm.c: now doesn't crash if a symbol with no section and no
+ SEC_ABS appears.
+
+Thu Oct 17 15:25:50 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, version.c: Bump to version 1.91.
+
+Wed Oct 16 11:45:36 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, ar.c, bucomm.c, copy.c, cplus-dem.c, filemode.c,
+ i960-pinsn.c, m68k-pinsn.c, nm.c, objdump.c, size.c, sparc-pinsn.c,
+ * strip.c: Add or update Copyright notice.
+ * TODO: Add note on 'nm -a'.
+ * version.c: Update version number to 1.90.
+ * Makefile.in: Fix making of documentation for dist.
+
+Tue Oct 15 00:17:17 1991 Per Bothner (bothner at cygnus.com)
+
+ * README: New file.
+ * Makefile.in: New kludgy rules for making a tarfile.
+ * Makefile.in: Fix bindir path.
+
+Mon Oct 14 17:34:29 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * Makefile.in: add targets binutils.mm, binutils.me
+
+Fri Oct 11 22:44:21 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Avoid Sun Make VPATH bugs by adding dependencies.
+
+Fri Oct 11 12:51:33 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * Makefile.in: add target "binutils.ms"
+
+ * binutils.texinfo: minor restructuring for texi2roff comfort.
+
+Fri Oct 11 04:12:28 1991 John Gilmore (gnu at cygnus.com)
+
+ Restructure configuration scheme for bfd, binutils, ld.
+
+ * include/sys/h-*.h: Move to bfd/hosts/h-*.h.
+ * configure.in: Revise to symlink sysdep.h to ../bfd/hosts/h-xxx.h.
+ Change some config names to match other dirs.
+ * *.c: Include bfd.h before sysdep.h, so ansidecl and PROTO()
+ get defined first.
+ * Makefile.in: Use -I. to get sysdep.h.
+
+Wed Oct 9 22:42:56 1991 Per Bothner (bothner at cygnus.com)
+
+ * nm.c (print_symbols): Handle NULL name field of symbol.
+ * Makefile.in: Removed spurious comment.
+
+Tue Oct 8 16:55:03 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * binutils.texinfo: minor typos, phrasing, formatting fixes.
+
+Tue Oct 8 15:13:20 1991 Per Bothner (bothner at cygnus.com)
+
+ * configure.in: Get host file from ../bfd/config, not config.
+ * config/*: Remove config directory and its files.
+
+Tue Oct 8 13:58:59 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * Makefile.in: new targets binutils.dvi, binutils.info
+
+ * binutils.texinfo: remove most remaining FIXME's, delete
+ references to __.SYMDEF by name
+
+
+Tue Oct 8 10:23:44 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * objdump.c (print_address) Print addresses nicely.
+
+Mon Oct 7 11:31:05 1991 Per Bothner (bothner at cygnus.com)
+
+ * ar.c, Makefile.in, new files {is,not,maybe}-ranlib.c:
+ Make two different binaries for ar and ranlib, instead of
+ distinguishing them at run time using argv[0].
+ (Old behavior is still available if you "make ar_with_ranlib",
+ but it is not the default.)
+ * ranlib.sh (new): An alternative one-line
+ shell implementation of ranlib.
+
+Fri Oct 4 21:49:44 1991 John Gilmore (gnu at cygnus.com)
+
+ * objdump.c: Cope with renames of a few BFD types & enums.
+
+Fri Oct 4 19:08:09 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * binutils.texinfo: add new file (rudimentary docn)
+
+Mon Sep 30 12:30:39 1991 Per Bothner (bothner at cygnus.com)
+
+ * config/hmake-news: Add new file (for Sony NEWSOS3).
+ * bucomm.c (fatal): Conditionally compile fatal() depending on
+ MISSING_VFPRINTF, and don't confuse the issue with NO_VARARGS.
+ * objdump.c (dump_headers): Trivial output format change.
+ * objdump.c (display_info): Loop over integers, not enums,
+ to appease old compilers.
+
+Mon May 20 16:14:07 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+
+ *objdump.c *nm.c *copy.c :hanged some types to work with 64 bit object files
+
+Thu May 16 16:06:55 1991 Steve Chamberlain (steve at cygint.cygnus.com)
+ from bother
+ * objdump.c (print_address): Make disasembled output more
+ consistent with gdb and as: Add 0x when printing hex.
+ Don't print extra leading zeros.
+ Attempt to not print "filename.o".
+ * objdump.c: Add some enum-to-int casts to accomodate old compilers.
+
+
+Fri May 3 22:21:44 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * copy.c: Change =& constructs to = &, since they confuse older
+ C compilers.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
new file mode 100644
index 00000000000..4f3014f3287
--- /dev/null
+++ b/binutils/Makefile.am
@@ -0,0 +1,495 @@
+## Process this file with automake to generate Makefile.in
+
+## FIXME: Work around apparent bug in automake.
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+SUBDIRS = po
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+## These aren't set by automake, because they appear in
+## bfd/acinclude.m4, which is included by binutils/acinclude.m4, and
+## thus is not seen by automake.
+CC_FOR_BUILD = @CC_FOR_BUILD@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi`
+YFLAGS = -d
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi`
+
+# these two are almost the same program
+AR_PROG=ar
+RANLIB_PROG=ranlib
+
+# objcopy and strip should be the same program
+OBJCOPY_PROG=objcopy
+STRIP_PROG=strip-new
+
+STRINGS_PROG=strings
+
+READELF_PROG=readelf
+
+# These should all be the same program too.
+SIZE_PROG=size
+NM_PROG=nm-new
+OBJDUMP_PROG=objdump
+
+# This is the demangler, as a standalone program.
+# Note: This one is used as the installed name too, unlike the above.
+DEMANGLER_PROG=c++filt
+
+ADDR2LINE_PROG=addr2line
+
+NLMCONV_PROG=nlmconv
+DLLTOOL_PROG=dlltool
+WINDRES_PROG=windres
+DLLWRAP_PROG=dllwrap
+
+SRCONV_PROG=srconv$(EXEEXT) sysdump$(EXEEXT) coffdump$(EXEEXT)
+
+man_MANS = ar.1 nm.1 objdump.1 ranlib.1 size.1 strings.1 strip.1 objcopy.1 \
+ addr2line.1 nlmconv.1 $(DEMANGLER_PROG).1
+
+PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRINGS_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ $(ADDR2LINE_PROG) $(READELF_PROG) @BUILD_DLLWRAP@ @BUILD_MISC@
+
+bin_PROGRAMS = $(SIZE_PROG) $(OBJDUMP_PROG) $(AR_PROG) $(STRINGS_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ $(ADDR2LINE_PROG) $(READELF_PROG) @BUILD_DLLWRAP@ @BUILD_MISC@
+
+## We need a special rule to install the programs which are built with -new
+noinst_PROGRAMS = $(NM_PROG) $(STRIP_PROG)
+
+EXTRA_PROGRAMS = $(NLMCONV_PROG) srconv sysdump coffdump $(DLLTOOL_PROG) $(WINDRES_PROG) $(DLLWRAP_PROG)
+
+# Stuff that goes in tooldir/ if appropriate
+TOOL_PROGS = nm-new strip-new ar ranlib dlltool
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+
+DEP = mkdep
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) @HDEFINES@ -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+HFILES = arsup.h bucomm.h budbg.h coffgrok.h debug.h nlmconv.h dlltool.h \
+ windres.h winduni.h dyn-string.h
+
+GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h
+
+CFILES = addr2line.c ar.c arsup.c bucomm.c coffdump.c coffgrok.c debug.c \
+ dlltool.c filemode.c ieee.c is-ranlib.c is-strip.c maybe-ranlib.c \
+ maybe-strip.c nlmconv.c nm.c not-ranlib.c not-strip.c \
+ objcopy.c objdump.c prdbg.c rdcoff.c rddbg.c size.c srconv.c \
+ stabs.c strings.c sysdump.c version.c wrstabs.c \
+ windres.c resrc.c rescoff.c resbin.c winduni.c readelf.c \
+ resres.c dyn-string.c dllwrap.c rename.c
+
+GENERATED_CFILES = \
+ underscore.c arparse.c arlex.c sysroff.c sysinfo.c syslex.c \
+ defparse.c deflex.c nlmheader.c rcparse.c rclex.c
+
+DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
+WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
+
+# Code shared by all the binutils.
+BULIBS = bucomm.c version.c filemode.c
+
+BFDLIB = ../bfd/libbfd.la
+
+OPCODES = ../opcodes/libopcodes.la
+
+LIBIBERTY = ../libiberty/libiberty.a
+
+POTFILES = $(CFILES) $(DEBUG_SRCS) $(HFILES)
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+EXPECT = `if [ -f $$r/../expect/expect ] ; then \
+ echo $$r/../expect/expect ; \
+ else echo expect ; fi`
+RUNTEST = `if [ -f ${srcdir}/../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+CC_FOR_TARGET = ` \
+ if [ -f $$r/../gcc/xgcc ] ; then \
+ if [ -f $$r/../newlib/Makefile ] ; then \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+ else \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+ fi; \
+ else \
+ if [ "@host@" = "@target@" ] ; then \
+ echo $(CC); \
+ else \
+ echo gcc | sed '$(transform)'; \
+ fi; \
+ fi`
+
+check-DEJAGNU: site.exp
+ srcdir=`cd $(srcdir) && pwd`; export srcdir; \
+ r=`pwd`; export r; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcdir}/testsuite \
+ CC_FOR_TARGET="$(CC_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS)" $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+installcheck:
+ /bin/sh $(srcdir)/sanity.sh $(bindir)
+
+info_TEXINFOS = binutils.texi
+
+LDADD = $(BFDLIB) $(LIBIBERTY) $(INTLLIBS)
+
+size_SOURCES = size.c $(BULIBS)
+
+objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+
+strings_SOURCES = strings.c $(BULIBS)
+
+readelf_SOURCES = readelf.c version.c
+readelf_LDADD = $(INTLLIBS) $(LIBIBERTY)
+
+strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+
+nm_new_SOURCES = nm.c $(BULIBS)
+
+objdump_SOURCES = objdump.c prdbg.c $(DEBUG_SRCS) $(BULIBS)
+objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS)
+
+underscore.c: stamp-under ; @true
+
+stamp-under: Makefile
+ echo '/*WARNING: This file is automatically generated!*/' >underscore.t
+ echo "int prepends_underscore = @UNDERSCORE@;" >>underscore.t
+ $(SHELL) $(srcdir)/../move-if-change underscore.t underscore.c
+ touch stamp-under
+
+cplus-dem.o: $(BASEDIR)/libiberty/cplus-dem.c $(INCDIR)/getopt.h
+ $(COMPILE) -c -DMAIN -DVERSION='"$(VERSION)"' $(BASEDIR)/libiberty/cplus-dem.c
+
+c__filt_SOURCES =
+c__filt_LDADD = cplus-dem.o underscore.o $(LIBIBERTY) $(INTLLIBS)
+
+ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c $(BULIBS)
+ar_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+ranlib_SOURCES = ar.c is-ranlib.c arparse.y arlex.l arsup.c rename.c $(BULIBS)
+ranlib_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+addr2line_SOURCES = addr2line.c $(BULIBS)
+
+# The following is commented out for the convertion to automake.
+# This rule creates a single binary that switches between ar and ranlib
+# by looking at argv[0]. Use this kludge to save some disk space.
+# However, you have to install things by hand.
+# (That is after 'make install', replace the installed ranlib by a link to ar.)
+# Alternatively, you can install ranlib.sh as ranlib.
+# ar_with_ranlib: $(ADDL_DEPS) ar.o maybe-ranlib.o
+# $(HLDENV) $(CC) $(HLDFLAGS) $(CFLAGS) $(LDFLAGS) -o $(AR_PROG) ar.o maybe-ranlib.o $(ADDL_LIBS) $(EXTRALIBS)
+# -rm -f $(RANLIB_PROG)
+# -ln $(AR_PROG) $(RANLIB_PROG)
+#
+# objcopy and strip in one binary that uses argv[0] to decide its action.
+#
+#objcopy_with_strip: $(ADDL_DEPS) objcopy.o maybe-strip.o
+# $(HLDENV) $(CC) $(HLDFLAGS) $(CFLAGS) $(LDFLAGS) -o $(OBJCOPY_PROG) objcopy.o maybe-strip.o $(ADDL_LIBS) $(EXTRALIBS)
+# -rm -f $(STRIP_PROG)
+# -ln $(OBJCOPY_PROG) $(STRIP_PROG)
+
+sysroff.c: sysinfo$(EXEEXT_FOR_BUILD) sysroff.info
+ ./sysinfo$(EXEEXT_FOR_BUILD) -c <$(srcdir)/sysroff.info >sysroff.c
+ ./sysinfo$(EXEEXT_FOR_BUILD) -i <$(srcdir)/sysroff.info >>sysroff.c
+ ./sysinfo$(EXEEXT_FOR_BUILD) -g <$(srcdir)/sysroff.info >>sysroff.c
+
+sysroff.h: sysinfo$(EXEEXT_FOR_BUILD) sysroff.info
+ ./sysinfo$(EXEEXT_FOR_BUILD) -d <$(srcdir)/sysroff.info >sysroff.h
+
+sysinfo$(EXEEXT_FOR_BUILD): sysinfo.o syslex.o
+ $(CC_FOR_BUILD) $(CFLAGS) $(LDFLAGS) -o $@ sysinfo.o syslex.o
+
+syslex.o: syslex.c sysinfo.h
+ if [ -r syslex.c ]; then \
+ $(CC_FOR_BUILD) -c -I. $(CFLAGS) syslex.c ; \
+ else \
+ $(CC_FOR_BUILD) -c -I. -I$(srcdir) $(CFLAGS) $(srcdir)/syslex.c ;\
+ fi
+
+sysinfo.o: sysinfo.c
+ if [ -r sysinfo.c ]; then \
+ $(CC_FOR_BUILD) -c -I. $(CFLAGS) sysinfo.c ; \
+ else \
+ $(CC_FOR_BUILD) -c -I. $(CFLAGS) $(srcdir)/sysinfo.c ; \
+ fi
+
+srconv_SOURCES = srconv.c coffgrok.c $(BULIBS)
+
+dlltool_SOURCES = dlltool.c defparse.y deflex.l $(BULIBS)
+dlltool_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+dlltool.o:dlltool.c
+ $(COMPILE) -c $(DLLTOOL_DEFS) $(srcdir)/dlltool.c
+
+coffdump_SOURCES = coffdump.c coffgrok.c $(BULIBS)
+
+sysdump_SOURCES = sysdump.c $(BULIBS)
+
+# coff/sym.h and coff/ecoff.h won't be found by the automatic dependency
+# scripts, since they are only included conditionally.
+nlmconv.o: nlmconv.c $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+ ldname=`echo ld | sed '$(transform)'`; \
+ $(COMPILE) -c -DLD_NAME="\"$${ldname}\"" @NLMCONV_DEFS@ $(srcdir)/nlmconv.c
+
+nlmconv_SOURCES = nlmconv.c nlmheader.y $(BULIBS)
+
+windres_SOURCES = windres.c resrc.c rescoff.c resbin.c rcparse.y rclex.l \
+ winduni.c resres.c $(BULIBS)
+windres_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+dllwrap_SOURCES = dllwrap.c dyn-string.c
+dllwrap_LDADD = $(LIBIBERTY)
+
+
+DISTSTUFF = arparse.c arparse.h arlex.c nlmheader.c sysinfo.c sysinfo.h \
+ syslex.c deflex.c defparse.h defparse.c rclex.c rcparse.h rcparse.c
+
+diststuff: $(DISTSTUFF) info
+
+DISTCLEANFILES = stamp-under sysinfo underscore.c sysroff.c sysroff.h \
+ site.exp site.bak
+
+# Targets to rebuild dependencies in this Makefile.
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(GENERATED_CFILES)
+ rm -f .dep2
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ $(DEP) -f .dep2 $(INCLUDES) $?
+ $(SHELL) $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ objdir=`pwd`; \
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@BFDDIR@!$(BFDDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!' \
+ -e "s!@OBJDIR@!$${objdir}!"
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+###
+# DOCUMENTATION TARGETS
+config.texi: Makefile
+ rm -f config.texi
+ echo '@set VERSION $(VERSION)' > config.texi
+
+binutils.dvi: $(srcdir)/binutils.texi config.texi
+
+binutils.info: $(srcdir)/binutils.texi config.texi
+
+MAINTAINERCLEANFILES = config.texi
+
+$(DEMANGLER_PROG).1: cxxfilt.man Makefile
+ sed -e 's/@PROGRAM@/$(DEMANGLER_PROG)/' < $(srcdir)/cxxfilt.man \
+ > $(DEMANGLER_PROG).1
+
+MOSTLYCLEANFILES = sysinfo $(DEMANGLER_PROG).1 binutils.log binutils.sum \
+ abcdefgh*
+mostlyclean-local:
+ -rm -rf tmpdir
+
+CLEANFILES = dep.sed .dep .dep1
+
+.PHONY: install-exec-local
+
+install-exec-local: $(bin_PROGRAMS) $(noinst_PROGRAMS)
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+ $(mkinstalldirs) $(tooldir)/bin
+ for i in $(TOOL_PROGS); do \
+ if [ -f $$i$(EXEEXT) ]; then \
+ j=`echo $$i | sed -e 's/-new//'`; \
+ k=`echo $$j | sed '$(transform)'`; \
+ if [ "$(bindir)/$$k$(EXEEXT)" != "$(tooldir)/bin/$$j$(EXEEXT)" ]; then \
+ rm -f $(tooldir)/bin/$$j$(EXEEXT); \
+ ln $(bindir)/$$k$(EXEEXT) $(tooldir)/bin/$$j$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$i$(EXEEXT) $(tooldir)/bin/$$j$(EXEEXT); \
+ fi; \
+ else true; \
+ fi; \
+ done
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+addr2line.o: addr2line.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/getopt.h $(INCDIR)/libiberty.h $(INCDIR)/demangle.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+ar.o: ar.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/progress.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/aout/ar.h $(BFDDIR)/libbfd.h arsup.h
+arsup.o: arsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ arsup.h $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h
+bucomm.o: bucomm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h
+coffdump.o: coffdump.c coffgrok.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h
+coffgrok.o: coffgrok.c bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ coffgrok.h
+debug.o: debug.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h
+dlltool.o: dlltool.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h $(INCDIR)/demangle.h dlltool.h
+filemode.o: filemode.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+ieee.o: ieee.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/ieee.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h
+is-ranlib.o: is-ranlib.c
+is-strip.o: is-strip.c
+maybe-ranlib.o: maybe-ranlib.c
+maybe-strip.o: maybe-strip.c
+nlmconv.o: nlmconv.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(BFDDIR)/libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmconv.h
+nm.o: nm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/progress.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/getopt.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ranlib.h \
+ $(INCDIR)/demangle.h $(INCDIR)/libiberty.h
+not-ranlib.o: not-ranlib.c
+not-strip.o: not-strip.c
+objcopy.o: objcopy.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/progress.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h $(INCDIR)/libiberty.h budbg.h
+objdump.o: objdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/getopt.h $(INCDIR)/progress.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h $(INCDIR)/dis-asm.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/demangle.h debug.h budbg.h $(INCDIR)/aout/aout64.h
+prdbg.o: prdbg.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h
+rdcoff.o: rdcoff.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/coff/internal.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h $(INCDIR)/demangle.h debug.h \
+ budbg.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+rddbg.o: rddbg.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h
+size.o: size.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/getopt.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h
+srconv.o: srconv.c bucomm.h config.h $(INCDIR)/fopen-same.h \
+ sysroff.h coffgrok.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h sysroff.c
+stabs.o: stabs.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/demangle.h debug.h budbg.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+strings.o: strings.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h
+sysdump.o: sysdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h sysroff.h \
+ sysroff.c
+version.o: version.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+wrstabs.o: wrstabs.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def
+windres.o: windres.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/getopt.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h $(INCDIR)/obstack.h windres.h \
+ winduni.h
+resrc.o: resrc.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+rescoff.o: rescoff.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+resbin.o: resbin.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+winduni.o: winduni.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h winduni.h
+readelf.o: readelf.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/dwarf2.h $(INCDIR)/elf/i386.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/mips.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/m68k.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/m32r.h $(INCDIR)/elf/d10v.h \
+ $(INCDIR)/elf/d30v.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/mn10200.h \
+ $(INCDIR)/elf/mn10300.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/arc.h \
+ $(INCDIR)/elf/fr30.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h
+resres.o: resres.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+dyn-string.o: dyn-string.c config.h $(INCDIR)/ansidecl.h \
+ dyn-string.h
+dllwrap.o: dllwrap.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h dyn-string.h
+rename.o: rename.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+underscore.o: underscore.c
+arparse.o: arparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h arsup.h
+arlex.o: arlex.c $(INCDIR)/libiberty.h arparse.h
+sysroff.o: sysroff.c
+sysinfo.o: sysinfo.c
+syslex.o: syslex.c sysinfo.h
+defparse.o: defparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h dlltool.h
+deflex.o: deflex.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+ defparse.h dlltool.h
+nlmheader.o: nlmheader.c ../bfd/bfd.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ nlmconv.h
+rcparse.o: rcparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+rclex.o: rclex.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h rcparse.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
new file mode 100644
index 00000000000..c32ae4d7234
--- /dev/null
+++ b/binutils/Makefile.in
@@ -0,0 +1,1358 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AR = @AR@
+AS = @AS@
+BUILD_DLLTOOL = @BUILD_DLLTOOL@
+BUILD_DLLWRAP = @BUILD_DLLWRAP@
+BUILD_MISC = @BUILD_MISC@
+BUILD_NLMCONV = @BUILD_NLMCONV@
+BUILD_SRCONV = @BUILD_SRCONV@
+BUILD_WINDRES = @BUILD_WINDRES@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+DLLTOOL_DEFS = @DLLTOOL_DEFS@
+EXEEXT = @EXEEXT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+HDEFINES = @HDEFINES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NLMCONV_DEFS = @NLMCONV_DEFS@
+NM = @NM@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+UNDERSCORE = @UNDERSCORE@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
+VERSION = @VERSION@
+l = @l@
+
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+SUBDIRS = po
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+CC_FOR_BUILD = @CC_FOR_BUILD@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi`
+YFLAGS = -d
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi`
+
+# these two are almost the same program
+AR_PROG = ar
+RANLIB_PROG = ranlib
+
+# objcopy and strip should be the same program
+OBJCOPY_PROG = objcopy
+STRIP_PROG = strip-new
+
+STRINGS_PROG = strings
+
+READELF_PROG = readelf
+
+# These should all be the same program too.
+SIZE_PROG = size
+NM_PROG = nm-new
+OBJDUMP_PROG = objdump
+
+# This is the demangler, as a standalone program.
+# Note: This one is used as the installed name too, unlike the above.
+DEMANGLER_PROG = c++filt
+
+ADDR2LINE_PROG = addr2line
+
+NLMCONV_PROG = nlmconv
+DLLTOOL_PROG = dlltool
+WINDRES_PROG = windres
+DLLWRAP_PROG = dllwrap
+
+SRCONV_PROG = srconv$(EXEEXT) sysdump$(EXEEXT) coffdump$(EXEEXT)
+
+man_MANS = ar.1 nm.1 objdump.1 ranlib.1 size.1 strings.1 strip.1 objcopy.1 \
+ addr2line.1 nlmconv.1 $(DEMANGLER_PROG).1
+
+
+PROGS = $(SIZE_PROG) $(OBJDUMP_PROG) $(NM_PROG) $(AR_PROG) $(STRINGS_PROG) $(STRIP_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ $(ADDR2LINE_PROG) $(READELF_PROG) @BUILD_DLLWRAP@ @BUILD_MISC@
+
+bin_PROGRAMS = $(SIZE_PROG) $(OBJDUMP_PROG) $(AR_PROG) $(STRINGS_PROG) $(RANLIB_PROG) $(DEMANGLER_PROG) $(OBJCOPY_PROG) @BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ $(ADDR2LINE_PROG) $(READELF_PROG) @BUILD_DLLWRAP@ @BUILD_MISC@
+
+noinst_PROGRAMS = $(NM_PROG) $(STRIP_PROG)
+
+EXTRA_PROGRAMS = $(NLMCONV_PROG) srconv sysdump coffdump $(DLLTOOL_PROG) $(WINDRES_PROG) $(DLLWRAP_PROG)
+
+# Stuff that goes in tooldir/ if appropriate
+TOOL_PROGS = nm-new strip-new ar ranlib dlltool
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+
+DEP = mkdep
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) @HDEFINES@ -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+HFILES = arsup.h bucomm.h budbg.h coffgrok.h debug.h nlmconv.h dlltool.h \
+ windres.h winduni.h dyn-string.h
+
+
+GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h
+
+CFILES = addr2line.c ar.c arsup.c bucomm.c coffdump.c coffgrok.c debug.c \
+ dlltool.c filemode.c ieee.c is-ranlib.c is-strip.c maybe-ranlib.c \
+ maybe-strip.c nlmconv.c nm.c not-ranlib.c not-strip.c \
+ objcopy.c objdump.c prdbg.c rdcoff.c rddbg.c size.c srconv.c \
+ stabs.c strings.c sysdump.c version.c wrstabs.c \
+ windres.c resrc.c rescoff.c resbin.c winduni.c readelf.c \
+ resres.c dyn-string.c dllwrap.c rename.c
+
+
+GENERATED_CFILES = \
+ underscore.c arparse.c arlex.c sysroff.c sysinfo.c syslex.c \
+ defparse.c deflex.c nlmheader.c rcparse.c rclex.c
+
+
+DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
+WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
+
+# Code shared by all the binutils.
+BULIBS = bucomm.c version.c filemode.c
+
+BFDLIB = ../bfd/libbfd.la
+
+OPCODES = ../opcodes/libopcodes.la
+
+LIBIBERTY = ../libiberty/libiberty.a
+
+POTFILES = $(CFILES) $(DEBUG_SRCS) $(HFILES)
+
+EXPECT = `if [ -f $$r/../expect/expect ] ; then \
+ echo $$r/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f ${srcdir}/../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+
+CC_FOR_TARGET = ` \
+ if [ -f $$r/../gcc/xgcc ] ; then \
+ if [ -f $$r/../newlib/Makefile ] ; then \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+ else \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+ fi; \
+ else \
+ if [ "@host@" = "@target@" ] ; then \
+ echo $(CC); \
+ else \
+ echo gcc | sed '$(transform)'; \
+ fi; \
+ fi`
+
+
+info_TEXINFOS = binutils.texi
+
+LDADD = $(BFDLIB) $(LIBIBERTY) $(INTLLIBS)
+
+size_SOURCES = size.c $(BULIBS)
+
+objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+
+strings_SOURCES = strings.c $(BULIBS)
+
+readelf_SOURCES = readelf.c version.c
+readelf_LDADD = $(INTLLIBS) $(LIBIBERTY)
+
+strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
+
+nm_new_SOURCES = nm.c $(BULIBS)
+
+objdump_SOURCES = objdump.c prdbg.c $(DEBUG_SRCS) $(BULIBS)
+objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS)
+
+c__filt_SOURCES =
+c__filt_LDADD = cplus-dem.o underscore.o $(LIBIBERTY) $(INTLLIBS)
+
+ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c $(BULIBS)
+ar_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+ranlib_SOURCES = ar.c is-ranlib.c arparse.y arlex.l arsup.c rename.c $(BULIBS)
+ranlib_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+addr2line_SOURCES = addr2line.c $(BULIBS)
+
+srconv_SOURCES = srconv.c coffgrok.c $(BULIBS)
+
+dlltool_SOURCES = dlltool.c defparse.y deflex.l $(BULIBS)
+dlltool_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+coffdump_SOURCES = coffdump.c coffgrok.c $(BULIBS)
+
+sysdump_SOURCES = sysdump.c $(BULIBS)
+
+nlmconv_SOURCES = nlmconv.c nlmheader.y $(BULIBS)
+
+windres_SOURCES = windres.c resrc.c rescoff.c resbin.c rcparse.y rclex.l \
+ winduni.c resres.c $(BULIBS)
+
+windres_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(INTLLIBS)
+
+dllwrap_SOURCES = dllwrap.c dyn-string.c
+dllwrap_LDADD = $(LIBIBERTY)
+
+DISTSTUFF = arparse.c arparse.h arlex.c nlmheader.c sysinfo.c sysinfo.h \
+ syslex.c deflex.c defparse.h defparse.c rclex.c rcparse.h rcparse.c
+
+
+DISTCLEANFILES = stamp-under sysinfo underscore.c sysroff.c sysroff.h \
+ site.exp site.bak
+
+
+MAINTAINERCLEANFILES = config.texi
+
+MOSTLYCLEANFILES = sysinfo $(DEMANGLER_PROG).1 binutils.log binutils.sum \
+ abcdefgh*
+
+
+CLEANFILES = dep.sed .dep .dep1
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = size$(EXEEXT) objdump$(EXEEXT) ar$(EXEEXT) \
+strings$(EXEEXT) ranlib$(EXEEXT) c++filt$(EXEEXT) objcopy$(EXEEXT) \
+@BUILD_NLMCONV@ @BUILD_SRCONV@ @BUILD_DLLTOOL@ @BUILD_WINDRES@ \
+addr2line$(EXEEXT) readelf$(EXEEXT) @BUILD_DLLWRAP@ @BUILD_MISC@
+noinst_PROGRAMS = nm-new$(EXEEXT) strip-new$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+nlmconv_OBJECTS = nlmconv.o nlmheader.o bucomm.o version.o filemode.o
+nlmconv_LDADD = $(LDADD)
+nlmconv_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+nlmconv_LDFLAGS =
+srconv_OBJECTS = srconv.o coffgrok.o bucomm.o version.o filemode.o
+srconv_LDADD = $(LDADD)
+srconv_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+srconv_LDFLAGS =
+sysdump_OBJECTS = sysdump.o bucomm.o version.o filemode.o
+sysdump_LDADD = $(LDADD)
+sysdump_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+sysdump_LDFLAGS =
+coffdump_OBJECTS = coffdump.o coffgrok.o bucomm.o version.o filemode.o
+coffdump_LDADD = $(LDADD)
+coffdump_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+coffdump_LDFLAGS =
+dlltool_OBJECTS = dlltool.o defparse.o deflex.o bucomm.o version.o \
+filemode.o
+dlltool_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+dlltool_LDFLAGS =
+windres_OBJECTS = windres.o resrc.o rescoff.o resbin.o rcparse.o \
+rclex.o winduni.o resres.o bucomm.o version.o filemode.o
+windres_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+windres_LDFLAGS =
+dllwrap_OBJECTS = dllwrap.o dyn-string.o
+dllwrap_DEPENDENCIES = ../libiberty/libiberty.a
+dllwrap_LDFLAGS =
+size_OBJECTS = size.o bucomm.o version.o filemode.o
+size_LDADD = $(LDADD)
+size_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+size_LDFLAGS =
+objdump_OBJECTS = objdump.o prdbg.o rddbg.o debug.o stabs.o ieee.o \
+rdcoff.o bucomm.o version.o filemode.o
+objdump_DEPENDENCIES = ../opcodes/libopcodes.la ../bfd/libbfd.la \
+../libiberty/libiberty.a
+objdump_LDFLAGS =
+ar_OBJECTS = arparse.o arlex.o ar.o not-ranlib.o arsup.o rename.o \
+bucomm.o version.o filemode.o
+ar_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+ar_LDFLAGS =
+strings_OBJECTS = strings.o bucomm.o version.o filemode.o
+strings_LDADD = $(LDADD)
+strings_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+strings_LDFLAGS =
+ranlib_OBJECTS = ar.o is-ranlib.o arparse.o arlex.o arsup.o rename.o \
+bucomm.o version.o filemode.o
+ranlib_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+ranlib_LDFLAGS =
+c__filt_OBJECTS =
+c__filt_DEPENDENCIES = cplus-dem.o underscore.o \
+../libiberty/libiberty.a
+c__filt_LDFLAGS =
+objcopy_OBJECTS = objcopy.o not-strip.o rename.o rddbg.o debug.o \
+stabs.o ieee.o rdcoff.o wrstabs.o bucomm.o version.o filemode.o
+objcopy_LDADD = $(LDADD)
+objcopy_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+objcopy_LDFLAGS =
+addr2line_OBJECTS = addr2line.o bucomm.o version.o filemode.o
+addr2line_LDADD = $(LDADD)
+addr2line_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+addr2line_LDFLAGS =
+readelf_OBJECTS = readelf.o version.o
+readelf_DEPENDENCIES = ../libiberty/libiberty.a
+readelf_LDFLAGS =
+nm_new_OBJECTS = nm.o bucomm.o version.o filemode.o
+nm_new_LDADD = $(LDADD)
+nm_new_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+nm_new_LDFLAGS =
+strip_new_OBJECTS = objcopy.o is-strip.o rename.o rddbg.o debug.o \
+stabs.o ieee.o rdcoff.o wrstabs.o bucomm.o version.o filemode.o
+strip_new_LDADD = $(LDADD)
+strip_new_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a
+strip_new_LDFLAGS =
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LEXLIB = @LEXLIB@
+YLWRAP = $(top_srcdir)/../ylwrap
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi`
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+INFO_DEPS = binutils.info
+DVIS = binutils.dvi
+TEXINFOS = binutils.texi
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+
+NROFF = nroff
+DIST_COMMON = README ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+NEWS acinclude.m4 aclocal.m4 arlex.c arparse.c config.in configure \
+configure.in deflex.c defparse.c nlmheader.c rclex.c rcparse.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(nlmconv_SOURCES) $(srconv_SOURCES) $(sysdump_SOURCES) $(coffdump_SOURCES) $(dlltool_SOURCES) $(windres_SOURCES) $(dllwrap_SOURCES) $(size_SOURCES) $(objdump_SOURCES) $(ar_SOURCES) $(strings_SOURCES) $(ranlib_SOURCES) $(c__filt_SOURCES) $(objcopy_SOURCES) $(addr2line_SOURCES) $(readelf_SOURCES) $(nm_new_SOURCES) $(strip_new_SOURCES)
+OBJECTS = $(nlmconv_OBJECTS) $(srconv_OBJECTS) $(sysdump_OBJECTS) $(coffdump_OBJECTS) $(dlltool_OBJECTS) $(windres_OBJECTS) $(dllwrap_OBJECTS) $(size_OBJECTS) $(objdump_OBJECTS) $(ar_OBJECTS) $(strings_OBJECTS) $(ranlib_OBJECTS) $(c__filt_OBJECTS) $(objcopy_OBJECTS) $(addr2line_OBJECTS) $(readelf_OBJECTS) $(nm_new_OBJECTS) $(strip_new_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .dvi .info .l .lo .o .ps .s .texi .texinfo .txi .y
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+nlmconv$(EXEEXT): $(nlmconv_OBJECTS) $(nlmconv_DEPENDENCIES)
+ @rm -f nlmconv$(EXEEXT)
+ $(LINK) $(nlmconv_LDFLAGS) $(nlmconv_OBJECTS) $(nlmconv_LDADD) $(LIBS)
+
+srconv$(EXEEXT): $(srconv_OBJECTS) $(srconv_DEPENDENCIES)
+ @rm -f srconv$(EXEEXT)
+ $(LINK) $(srconv_LDFLAGS) $(srconv_OBJECTS) $(srconv_LDADD) $(LIBS)
+
+sysdump$(EXEEXT): $(sysdump_OBJECTS) $(sysdump_DEPENDENCIES)
+ @rm -f sysdump$(EXEEXT)
+ $(LINK) $(sysdump_LDFLAGS) $(sysdump_OBJECTS) $(sysdump_LDADD) $(LIBS)
+
+coffdump$(EXEEXT): $(coffdump_OBJECTS) $(coffdump_DEPENDENCIES)
+ @rm -f coffdump$(EXEEXT)
+ $(LINK) $(coffdump_LDFLAGS) $(coffdump_OBJECTS) $(coffdump_LDADD) $(LIBS)
+
+dlltool$(EXEEXT): $(dlltool_OBJECTS) $(dlltool_DEPENDENCIES)
+ @rm -f dlltool$(EXEEXT)
+ $(LINK) $(dlltool_LDFLAGS) $(dlltool_OBJECTS) $(dlltool_LDADD) $(LIBS)
+
+windres$(EXEEXT): $(windres_OBJECTS) $(windres_DEPENDENCIES)
+ @rm -f windres$(EXEEXT)
+ $(LINK) $(windres_LDFLAGS) $(windres_OBJECTS) $(windres_LDADD) $(LIBS)
+
+dllwrap$(EXEEXT): $(dllwrap_OBJECTS) $(dllwrap_DEPENDENCIES)
+ @rm -f dllwrap$(EXEEXT)
+ $(LINK) $(dllwrap_LDFLAGS) $(dllwrap_OBJECTS) $(dllwrap_LDADD) $(LIBS)
+
+size$(EXEEXT): $(size_OBJECTS) $(size_DEPENDENCIES)
+ @rm -f size$(EXEEXT)
+ $(LINK) $(size_LDFLAGS) $(size_OBJECTS) $(size_LDADD) $(LIBS)
+
+objdump$(EXEEXT): $(objdump_OBJECTS) $(objdump_DEPENDENCIES)
+ @rm -f objdump$(EXEEXT)
+ $(LINK) $(objdump_LDFLAGS) $(objdump_OBJECTS) $(objdump_LDADD) $(LIBS)
+
+ar$(EXEEXT): $(ar_OBJECTS) $(ar_DEPENDENCIES)
+ @rm -f ar$(EXEEXT)
+ $(LINK) $(ar_LDFLAGS) $(ar_OBJECTS) $(ar_LDADD) $(LIBS)
+
+strings$(EXEEXT): $(strings_OBJECTS) $(strings_DEPENDENCIES)
+ @rm -f strings$(EXEEXT)
+ $(LINK) $(strings_LDFLAGS) $(strings_OBJECTS) $(strings_LDADD) $(LIBS)
+
+ranlib$(EXEEXT): $(ranlib_OBJECTS) $(ranlib_DEPENDENCIES)
+ @rm -f ranlib$(EXEEXT)
+ $(LINK) $(ranlib_LDFLAGS) $(ranlib_OBJECTS) $(ranlib_LDADD) $(LIBS)
+
+c++filt$(EXEEXT): $(c__filt_OBJECTS) $(c__filt_DEPENDENCIES)
+ @rm -f c++filt$(EXEEXT)
+ $(LINK) $(c__filt_LDFLAGS) $(c__filt_OBJECTS) $(c__filt_LDADD) $(LIBS)
+
+objcopy$(EXEEXT): $(objcopy_OBJECTS) $(objcopy_DEPENDENCIES)
+ @rm -f objcopy$(EXEEXT)
+ $(LINK) $(objcopy_LDFLAGS) $(objcopy_OBJECTS) $(objcopy_LDADD) $(LIBS)
+
+addr2line$(EXEEXT): $(addr2line_OBJECTS) $(addr2line_DEPENDENCIES)
+ @rm -f addr2line$(EXEEXT)
+ $(LINK) $(addr2line_LDFLAGS) $(addr2line_OBJECTS) $(addr2line_LDADD) $(LIBS)
+
+readelf$(EXEEXT): $(readelf_OBJECTS) $(readelf_DEPENDENCIES)
+ @rm -f readelf$(EXEEXT)
+ $(LINK) $(readelf_LDFLAGS) $(readelf_OBJECTS) $(readelf_LDADD) $(LIBS)
+
+nm-new$(EXEEXT): $(nm_new_OBJECTS) $(nm_new_DEPENDENCIES)
+ @rm -f nm-new$(EXEEXT)
+ $(LINK) $(nm_new_LDFLAGS) $(nm_new_OBJECTS) $(nm_new_LDADD) $(LIBS)
+
+strip-new$(EXEEXT): $(strip_new_OBJECTS) $(strip_new_DEPENDENCIES)
+ @rm -f strip-new$(EXEEXT)
+ $(LINK) $(strip_new_LDFLAGS) $(strip_new_OBJECTS) $(strip_new_LDADD) $(LIBS)
+.l.c:
+ $(SHELL) $(YLWRAP) "$(LEX)" $< $(LEX_OUTPUT_ROOT).c $@ -- $(AM_LFLAGS) $(LFLAGS)
+.y.c:
+ $(SHELL) $(YLWRAP) "$(YACC)" $< y.tab.c $*.c y.tab.h $*.h -- $(AM_YFLAGS) $(YFLAGS)
+arparse.h: arparse.c
+defparse.h: defparse.c
+nlmheader.h: nlmheader.c
+rcparse.h: rcparse.c
+
+
+binutils.info: binutils.texi
+binutils.dvi: binutils.texi
+
+
+DVIPS = dvips
+
+.texi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.txi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f binutils.aux binutils.cp binutils.cps binutils.dvi binutils.fn \
+ binutils.fns binutils.ky binutils.kys binutils.ps \
+ binutils.log binutils.pg binutils.toc binutils.tp \
+ binutils.tps binutils.vr binutils.vrs binutils.op binutils.tr \
+ binutils.cv binutils.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+clean-info: mostlyclean-aminfo
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+
+RUNTESTFLAGS =
+
+DEJATOOL = $(PACKAGE)
+
+RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @test ! -f site.bak || rm -f site.bak
+ @echo '## these variables are automatically generated by make ##' > $@-t
+ @echo '# Do not edit here. If you wish to override these values' >> $@-t
+ @echo '# edit the last section' >> $@-t
+ @echo 'set tool $(DEJATOOL)' >> $@-t
+ @echo 'set srcdir $(srcdir)' >> $@-t
+ @echo 'set objdir' `pwd` >> $@-t
+ @echo 'set host_alias $(host_alias)' >> $@-t
+ @echo 'set host_triplet $(host_triplet)' >> $@-t
+ @echo 'set target_alias $(target_alias)' >> $@-t
+ @echo 'set target_triplet $(target_triplet)' >> $@-t
+ @echo 'set build_alias $(build_alias)' >> $@-t
+ @echo 'set build_triplet $(build_triplet)' >> $@-t
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t
+ @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv $@-t site.exp
+info-am: $(INFO_DEPS)
+info: info-recursive
+dvi-am: $(DVIS)
+dvi: dvi-recursive
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-binPROGRAMS install-exec-local
+install-exec: install-exec-recursive
+
+install-data-am: install-man
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+uninstall: uninstall-recursive
+all-am: Makefile $(PROGRAMS) $(MANS) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
+
+
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ -test -z "arlexldeflexlrclexlarparseharparsecdefparsehdefparsecnlmheaderhnlmheadercrcparsehrcparsec$(MAINTAINERCLEANFILES)" || rm -f arlexl deflexl rclexl arparseh arparsec defparseh defparsec nlmheaderh nlmheaderc rcparseh rcparsec $(MAINTAINERCLEANFILES)
+mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \
+ mostlyclean-noinstPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-aminfo mostlyclean-tags \
+ mostlyclean-generic mostlyclean-local
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-binPROGRAMS clean-noinstPROGRAMS \
+ clean-compile clean-libtool clean-aminfo clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-binPROGRAMS \
+ distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-aminfo distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \
+ maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-aminfo maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-info-am uninstall-info \
+mostlyclean-aminfo distclean-aminfo clean-aminfo \
+maintainer-clean-aminfo install-man1 uninstall-man1 install-man \
+uninstall-man install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir check-DEJAGNU \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-info-am install-info all-recursive-am install-exec-local \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+check-DEJAGNU: site.exp
+ srcdir=`cd $(srcdir) && pwd`; export srcdir; \
+ r=`pwd`; export r; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcdir}/testsuite \
+ CC_FOR_TARGET="$(CC_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS)" $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+installcheck:
+ /bin/sh $(srcdir)/sanity.sh $(bindir)
+
+underscore.c: stamp-under ; @true
+
+stamp-under: Makefile
+ echo '/*WARNING: This file is automatically generated!*/' >underscore.t
+ echo "int prepends_underscore = @UNDERSCORE@;" >>underscore.t
+ $(SHELL) $(srcdir)/../move-if-change underscore.t underscore.c
+ touch stamp-under
+
+cplus-dem.o: $(BASEDIR)/libiberty/cplus-dem.c $(INCDIR)/getopt.h
+ $(COMPILE) -c -DMAIN -DVERSION='"$(VERSION)"' $(BASEDIR)/libiberty/cplus-dem.c
+
+# The following is commented out for the convertion to automake.
+# This rule creates a single binary that switches between ar and ranlib
+# by looking at argv[0]. Use this kludge to save some disk space.
+# However, you have to install things by hand.
+# (That is after 'make install', replace the installed ranlib by a link to ar.)
+# Alternatively, you can install ranlib.sh as ranlib.
+# ar_with_ranlib: $(ADDL_DEPS) ar.o maybe-ranlib.o
+# $(HLDENV) $(CC) $(HLDFLAGS) $(CFLAGS) $(LDFLAGS) -o $(AR_PROG) ar.o maybe-ranlib.o $(ADDL_LIBS) $(EXTRALIBS)
+# -rm -f $(RANLIB_PROG)
+# -ln $(AR_PROG) $(RANLIB_PROG)
+#
+# objcopy and strip in one binary that uses argv[0] to decide its action.
+#
+#objcopy_with_strip: $(ADDL_DEPS) objcopy.o maybe-strip.o
+# $(HLDENV) $(CC) $(HLDFLAGS) $(CFLAGS) $(LDFLAGS) -o $(OBJCOPY_PROG) objcopy.o maybe-strip.o $(ADDL_LIBS) $(EXTRALIBS)
+# -rm -f $(STRIP_PROG)
+# -ln $(OBJCOPY_PROG) $(STRIP_PROG)
+
+sysroff.c: sysinfo$(EXEEXT_FOR_BUILD) sysroff.info
+ ./sysinfo$(EXEEXT_FOR_BUILD) -c <$(srcdir)/sysroff.info >sysroff.c
+ ./sysinfo$(EXEEXT_FOR_BUILD) -i <$(srcdir)/sysroff.info >>sysroff.c
+ ./sysinfo$(EXEEXT_FOR_BUILD) -g <$(srcdir)/sysroff.info >>sysroff.c
+
+sysroff.h: sysinfo$(EXEEXT_FOR_BUILD) sysroff.info
+ ./sysinfo$(EXEEXT_FOR_BUILD) -d <$(srcdir)/sysroff.info >sysroff.h
+
+sysinfo$(EXEEXT_FOR_BUILD): sysinfo.o syslex.o
+ $(CC_FOR_BUILD) $(CFLAGS) $(LDFLAGS) -o $@ sysinfo.o syslex.o
+
+syslex.o: syslex.c sysinfo.h
+ if [ -r syslex.c ]; then \
+ $(CC_FOR_BUILD) -c -I. $(CFLAGS) syslex.c ; \
+ else \
+ $(CC_FOR_BUILD) -c -I. -I$(srcdir) $(CFLAGS) $(srcdir)/syslex.c ;\
+ fi
+
+sysinfo.o: sysinfo.c
+ if [ -r sysinfo.c ]; then \
+ $(CC_FOR_BUILD) -c -I. $(CFLAGS) sysinfo.c ; \
+ else \
+ $(CC_FOR_BUILD) -c -I. $(CFLAGS) $(srcdir)/sysinfo.c ; \
+ fi
+
+dlltool.o:dlltool.c
+ $(COMPILE) -c $(DLLTOOL_DEFS) $(srcdir)/dlltool.c
+
+# coff/sym.h and coff/ecoff.h won't be found by the automatic dependency
+# scripts, since they are only included conditionally.
+nlmconv.o: nlmconv.c $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+ ldname=`echo ld | sed '$(transform)'`; \
+ $(COMPILE) -c -DLD_NAME="\"$${ldname}\"" @NLMCONV_DEFS@ $(srcdir)/nlmconv.c
+
+
+diststuff: $(DISTSTUFF) info
+
+# Targets to rebuild dependencies in this Makefile.
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(GENERATED_CFILES)
+ rm -f .dep2
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ $(DEP) -f .dep2 $(INCLUDES) $?
+ $(SHELL) $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ objdir=`pwd`; \
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@BFDDIR@!$(BFDDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!' \
+ -e "s!@OBJDIR@!$${objdir}!"
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+###
+# DOCUMENTATION TARGETS
+config.texi: Makefile
+ rm -f config.texi
+ echo '@set VERSION $(VERSION)' > config.texi
+
+binutils.dvi: $(srcdir)/binutils.texi config.texi
+
+binutils.info: $(srcdir)/binutils.texi config.texi
+
+$(DEMANGLER_PROG).1: cxxfilt.man Makefile
+ sed -e 's/@PROGRAM@/$(DEMANGLER_PROG)/' < $(srcdir)/cxxfilt.man \
+ > $(DEMANGLER_PROG).1
+mostlyclean-local:
+ -rm -rf tmpdir
+
+.PHONY: install-exec-local
+
+install-exec-local: $(bin_PROGRAMS) $(noinst_PROGRAMS)
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+ $(mkinstalldirs) $(tooldir)/bin
+ for i in $(TOOL_PROGS); do \
+ if [ -f $$i$(EXEEXT) ]; then \
+ j=`echo $$i | sed -e 's/-new//'`; \
+ k=`echo $$j | sed '$(transform)'`; \
+ if [ "$(bindir)/$$k$(EXEEXT)" != "$(tooldir)/bin/$$j$(EXEEXT)" ]; then \
+ rm -f $(tooldir)/bin/$$j$(EXEEXT); \
+ ln $(bindir)/$$k$(EXEEXT) $(tooldir)/bin/$$j$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$i$(EXEEXT) $(tooldir)/bin/$$j$(EXEEXT); \
+ fi; \
+ else true; \
+ fi; \
+ done
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+addr2line.o: addr2line.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/getopt.h $(INCDIR)/libiberty.h $(INCDIR)/demangle.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+ar.o: ar.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/progress.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/aout/ar.h $(BFDDIR)/libbfd.h arsup.h
+arsup.o: arsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ arsup.h $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h
+bucomm.o: bucomm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h
+coffdump.o: coffdump.c coffgrok.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h
+coffgrok.o: coffgrok.c bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ coffgrok.h
+debug.o: debug.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h
+dlltool.o: dlltool.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h $(INCDIR)/demangle.h dlltool.h
+filemode.o: filemode.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+ieee.o: ieee.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/ieee.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h
+is-ranlib.o: is-ranlib.c
+is-strip.o: is-strip.c
+maybe-ranlib.o: maybe-ranlib.c
+maybe-strip.o: maybe-strip.c
+nlmconv.o: nlmconv.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(BFDDIR)/libnlm.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ $(INCDIR)/nlm/external.h nlmconv.h
+nm.o: nm.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/progress.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/getopt.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ranlib.h \
+ $(INCDIR)/demangle.h $(INCDIR)/libiberty.h
+not-ranlib.o: not-ranlib.c
+not-strip.o: not-strip.c
+objcopy.o: objcopy.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/progress.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h $(INCDIR)/libiberty.h budbg.h
+objdump.o: objdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/getopt.h $(INCDIR)/progress.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h $(INCDIR)/dis-asm.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/demangle.h debug.h budbg.h $(INCDIR)/aout/aout64.h
+prdbg.o: prdbg.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h
+rdcoff.o: rdcoff.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/coff/internal.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h $(INCDIR)/demangle.h debug.h \
+ budbg.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+rddbg.o: rddbg.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h
+size.o: size.c ../bfd/bfd.h $(INCDIR)/ansidecl.h $(INCDIR)/getopt.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h
+srconv.o: srconv.c bucomm.h config.h $(INCDIR)/fopen-same.h \
+ sysroff.h coffgrok.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h sysroff.c
+stabs.o: stabs.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/demangle.h debug.h budbg.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+strings.o: strings.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h
+sysdump.o: sysdump.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h sysroff.h \
+ sysroff.c
+version.o: version.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+wrstabs.o: wrstabs.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ debug.h budbg.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
+ $(INCDIR)/aout/stab.def
+windres.o: windres.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/getopt.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/libiberty.h $(INCDIR)/obstack.h windres.h \
+ winduni.h
+resrc.o: resrc.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+rescoff.o: rescoff.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+resbin.o: resbin.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+winduni.o: winduni.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h winduni.h
+readelf.o: readelf.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/external.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/dwarf2.h $(INCDIR)/elf/i386.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/elf/v850.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/mips.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/m68k.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/m32r.h $(INCDIR)/elf/d10v.h \
+ $(INCDIR)/elf/d30v.h $(INCDIR)/elf/sh.h $(INCDIR)/elf/mn10200.h \
+ $(INCDIR)/elf/mn10300.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/arc.h \
+ $(INCDIR)/elf/fr30.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h
+resres.o: resres.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+dyn-string.o: dyn-string.c config.h $(INCDIR)/ansidecl.h \
+ dyn-string.h
+dllwrap.o: dllwrap.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h bucomm.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/getopt.h dyn-string.h
+rename.o: rename.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h
+underscore.o: underscore.c
+arparse.o: arparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h arsup.h
+arlex.o: arlex.c $(INCDIR)/libiberty.h arparse.h
+sysroff.o: sysroff.c
+sysinfo.o: sysinfo.c
+syslex.o: syslex.c sysinfo.h
+defparse.o: defparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h dlltool.h
+deflex.o: deflex.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+ defparse.h dlltool.h
+nlmheader.o: nlmheader.c ../bfd/bfd.h bucomm.h config.h \
+ $(INCDIR)/fopen-same.h $(INCDIR)/nlm/common.h $(INCDIR)/nlm/internal.h \
+ nlmconv.h
+rcparse.o: rcparse.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h
+rclex.o: rclex.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ bucomm.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ windres.h winduni.h rcparse.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/binutils/NEWS b/binutils/NEWS
new file mode 100644
index 00000000000..76dcebdda08
--- /dev/null
+++ b/binutils/NEWS
@@ -0,0 +1,163 @@
+-*- text -*-
+
+Changes in binutils 2.10:
+
+* objdump support for -mi386:intel which causes disassembly to be displayed with
+ intel syntax.
+
+* New program: readelf. This displays the contents of ELF format files,
+ regardless of target machine.
+
+* objcopy now takes --change-section-lma, --change-section-vma, and
+ --change-section-address options. The old --adjust-section-vma option is
+ equivalent to --change-section-address. The other --adjust-* options are now
+ renamed to --change-*, although --adjust-* continues to work.
+
+* dlltool now supports the IMPORTS command.
+
+* dlltool now takes --export-all-symbols, --no-export-all-symbols,
+ --exclude-symbols, and --no-default-excludes options.
+
+Changes in binutils 2.9:
+
+* Added windres program, which can be used to manipulate resources in WIN32
+ files as used on Windows 95 and Windows NT.
+
+* The objcopy --gap-fill and --pad-to options operate on the LMA rather than
+ the VMA of the sections.
+
+* Added S modifier to ar to not build a symbol table.
+
+Changes in binutils 2.8:
+
+* The objdump disassembly format has been changed, and hopefully improved. Use
+ the new --prefix-addresses option to get the old format. There are also new
+ --disassemble-zeroes and --no-show-raw-insn options which affect disassembler
+ output.
+
+* Formats may now be specified as configuration triplets. For example,
+ objdump -b i386-pc-linux. The triplets are not passed through config.sub,
+ so they must be in canonical form.
+
+* Added new addr2line program. This uses the debugging information to convert
+ an address into a file name and line number within a program.
+
+* Added --change-leading-char argument to objcopy.
+
+* Added --weaken argument to objcopy.
+
+* objdump --dynamic-reloc now works on ELF executables and shared libraries.
+
+* Added --adjust-vma option to objdump.
+
+* Added -C/--demangle option to objdump.
+
+* Added -p/--preserve-dates option to strip and objcopy.
+
+Changes in binutils 2.7:
+
+* Added --enable-shared and --enable-commonbfdlib options to configure.
+
+* Added --debugging argument to objdump and objcopy.
+
+* Added --defined-only argument to nm.
+
+* Added --remove-leading-char argument to objcopy.
+
+* The objdump --line-numbers option is now meaningful with --reloc.
+
+* Added --line-numbers option to nm.
+
+* Added --endian/-EB/-EL option to objdump.
+
+* Added support for Alpha OpenVMS/AXP.
+
+Changes in binutils 2.6:
+
+* Added -N/--strip-symbol and -K/--keep-symbol arguments to strip and objcopy.
+
+* Added several arguments to objcopy to provide some control over how the new
+ file is laid out in memory. Also added binary output format to BFD to permit
+ generating plain binary files.
+
+* Added --start-address and --stop-address options to objdump.
+
+* ar and ranlib now work on AIX. The tools are now built by default on AIX.
+
+Changes in binutils 2.5:
+
+* Changed objdump -dr to dump the relocs interspersed with the assembly
+ listing, for a more useful listing of relocateable files.
+
+* Changed objdump -d/--disassemble to only disassemble SEC_CODE sections.
+ Added -D/--disassemble-all option to disassemble all sections.
+
+* Added --size-sort option to nm.
+
+* strip and objcopy should now be able to handle dynamically linked ELF
+ executables.
+
+Changes in binutils 2.4:
+
+* Support for HP-PA (by Jeff Law), i386 Mach (by David Mackenzie), RS/6000 and
+ PowerPC (except ar and ranlib; by Ian Taylor).
+
+* Support for Irix 5.
+
+* Programs `strip' and `objcopy' will not attempt to write dynamically linked
+ ELF output files, since BFD currently can't create them properly.
+
+Changes in binutils 2.3:
+
+* A new --stabs argument has been added to objdump to dump stabs sections in
+ ELF and COFF files.
+
+* A new program, nlmconv, has been added. It can convert object files into
+ Novell NetWare Loadable Modules.
+
+* The strings program has been added.
+
+Changes in binutils 2.2:
+
+* The 'copy' program has been renamed to 'objcopy', for consistency with
+ 'objdump', and because 'copy' might more plausibly be used as a synonym for
+ 'cp'.
+
+* The new stand-alone program c++filt is a filter that converts encoded
+ (mangled) C++ assembly-level identifiers to user-level names. (Note: This
+ may get moved to the gcc distribution.)
+
+* nm -o on an archive now prefixes each line with the archive name, matching
+ the output from BSD nm.
+
+* ar (and ld) can now read (but not write) BSD4.4-style archives.
+
+* New support for H8500, Z8000, and the Hitach SH.
+
+* Dis-assembler interface changed to allow sharing with gdb.
+
+* There is new Elf code, but it is not yet ready for general use.
+
+* There is the beginnings of a test suite.
+
+Changes in binutils 2.1:
+
+* There is now support for writing ECOFF files, so ld and the other utilities
+ should work on Risc/Ultrix and Irix. Please let us know how well this works.
+
+* ar now automatically creates a symbol table (a __.SYMDEF member, in the BSD
+ version), if there are any object files in the archive. So running ranlib is
+ now redundant (unless the non-standard q command is used). This is required
+ for Posix.2 conformance.
+
+* The archive-reading code now reads both BSD-style and SYSV-style archives
+ independently of the selected target format. This is to encourage people to
+ switch to SYSV-format, which has a number of advantages.
+
+* The strip and copy programs now have options to remove debug-symbols only
+ and/or local symbols only. They now also support long options.
+
+
+Local variables:
+fill-column: 79
+End:
diff --git a/binutils/README b/binutils/README
new file mode 100644
index 00000000000..4b2d2772449
--- /dev/null
+++ b/binutils/README
@@ -0,0 +1,189 @@
+These are the GNU binutils. These are utilities of use when dealing
+with object files.
+
+The linker (ld) is in a separate directory, which should be ../ld.
+Linker-specific notes are in ../ld/README.
+
+As of version 2.5, the assembler (as) is also included in this package, in
+../gas. Assembler-specific notes can be found in ../gas/README.
+
+Recent changes are in ./NEWS, ../ld/NEWS, and ../gas/NEWS.
+
+Unpacking and Installation -- quick overview
+============================================
+
+When you unpack the binutils-2.9.tar.gz file, you'll get a directory
+called something like `binutils-2.9', which contains various files and
+directories. Most of the files in the top directory are for
+information and for configuration. The actual source code is in
+subdirectories.
+
+To build binutils, you can just do:
+
+ cd binutils-2.9
+ ./configure [options]
+ make
+ make install # copies the programs files into /usr/local/bin
+ # by default.
+
+This will configure and build all the libraries as well as the
+assembler, the binutils, and the linker.
+
+If you have GNU make, we recommend building in a different directory:
+
+ mkdir objdir
+ cd objdir
+ ../binutils-2.9/configure [options]
+ make
+ make install
+
+This relies on the VPATH feature of GNU make.
+
+By default, the binutils will be configured to support the system on
+which they are built. When doing cross development, use the --target
+configure option to specify a different target.
+
+The --enable-targets option adds support for more binary file formats
+besides the default. List them as the argument to --enable-targets,
+separated by commas. For example:
+
+ ./configure --enable-targets=sun3,rs6000-aix,decstation
+
+The name 'all' compiles in support for all valid BFD targets (this was
+the default in releases before 2.3):
+
+ ./configure --enable-targets=all
+
+You can also specify the --enable-shared option when you run
+configure. This will build the BFD and opcodes libraries as shared
+libraries. You can use arguments with the --enable-shared option to
+indicate that only certain libraries should be built shared; for
+example, --enable-shared=bfd. The only potential shared libraries in
+a binutils release are bfd and opcodes.
+
+The binutils will be linked against the shared libraries. The build
+step will attempt to place the correct library in the runtime search
+path for the binaries. However, in some cases, after you install the
+binaries, you may have to set an environment variable, normally
+LD_LIBRARY_PATH, so that the system can find the installed libbfd
+shared library.
+
+To build under openVMS/AXP, see the file makefile.vms in the top level
+directory.
+
+If you don't have ar
+====================
+
+If your system does not already have an ar program, the normal
+binutils build process will not work. In this case, run configure as
+usual. Before running make, run this script:
+
+#!/bin/sh
+MAKE_PROG="${MAKE-make}"
+MAKE="${MAKE_PROG} AR=true LINK=true"
+export MAKE
+${MAKE} $* all-libiberty
+${MAKE} $* all-intl
+${MAKE} $* all-bfd
+cd binutils
+MAKE="${MAKE_PROG}"
+export MAKE
+${MAKE} $* ar_DEPENDENCIES= ar_LDADD='../bfd/*.o `cat ../libiberty/required-list ../libiberty/needed-list | sed -e "s,\([^ ][^ ]*\),../libiberty/\1,g"` `if test -f ../intl/gettext.o; then echo '../intl/*.o'; fi`' ar
+
+This script will build an ar program in binutils/ar. Move binutils/ar
+into a directory on your PATH. After doing this, you can run make as
+usual to build the complete binutils distribution. You do not need
+the ranlib program in order to build the distribution.
+
+Porting
+=======
+
+Binutils-2.9 supports many different architectures, but there
+are many more not supported, including some that were supported
+by earlier versions. We are hoping for volunteers to
+improve this situation.
+
+The major effort in porting binutils to a new host and/or target
+architecture involves the BFD library. There is some documentation
+in ../bfd/doc. The file ../gdb/doc/gdbint.texinfo (distributed
+with gdb-4.x) may also be of help.
+
+Reporting bugs
+==============
+
+Send bug reports and patches to bug-gnu-utils@gnu.org. Always mention
+the version number you are running; this is printed by running any of
+the binutils with the --version option. We appreciate reports about
+bugs, but we do not promise to fix them.
+
+VMS
+===
+
+This section was written by Klaus K"ampf <kkaempf@rmi.de>. It
+describes how to build and install the binutils on openVMS (Alpha and
+Vax). (The BFD library only supports reading Vax object files.)
+
+Compiling the release:
+
+To compile the gnu binary utilities and the gnu assembler, you'll
+need DEC C or GNU C for openVMS/Alpha. You'll need *both* compilers
+on openVMS/Vax.
+
+Compiling with either DEC C or GNU C works on openVMS/Alpha only. Some
+of the opcodes and binutils files trap a bug in the DEC C optimizer,
+so these files must be compiled with /noopt.
+
+Compiling on openVMS/Vax is a bit complicated, as the bfd library traps
+a bug in GNU C and the gnu assembler a bug in (my version of) DEC C.
+
+I never tried compiling with VAX C.
+
+
+You further need GNU Make Version 3.76 or later. This is available
+at ftp.progis.de or any GNU archive site. The makefiles assume that
+gmake starts gnu make as a foreign command.
+
+If you're compiling with DEC C or VAX C, you must run
+
+ $ @setup
+
+before starting gnu-make. This isn't needed with GNU C.
+
+On the Alpha you can choose the compiler by editing the toplevel
+makefile.vms. Either select CC=cc (for DEC C) or CC=gcc (for GNU C)
+
+
+Installing the release
+
+Provided that your directory setup conforms to the GNU on openVMS
+standard, you already have a concealed deviced named 'GNU_ROOT'.
+In this case, a simple
+
+ $ gmake install
+
+suffices to copy all programs and libraries to the proper directories.
+
+Define the programs as foreign commands by adding these lines to your
+login.com:
+
+ $ gas :== $GNU_ROOT:[bin]as.exe
+ $ size :== $GNU_ROOT:[bin]size.exe
+ $ nm :== $GNU_ROOT:[bin]nm.exe
+ $ objdump :== $GNU_ROOT:[bin]objdump.exe
+ $ strings :== $GNU_ROOT:[bin]strings.exe
+
+If you have a different directory setup, copy the binary utilities
+([.binutils]size.exe, [.binutils]nm.exe, [.binutils]objdump.exe,
+and [.binutils]strings.exe) and the gnu assembler and preprocessor
+([.gas]as.exe and [.gas]gasp.exe]) to a directory of your choice
+and define all programs as foreign commands.
+
+
+If you're satiesfied with the compilation, you may want to remove
+unneeded objects and libraries:
+
+ $ gmake clean
+
+
+If you have any problems or questions about the binutils on VMS, feel
+free to mail me at kkaempf@rmi.de.
diff --git a/binutils/acinclude.m4 b/binutils/acinclude.m4
new file mode 100644
index 00000000000..71b09b9f6ac
--- /dev/null
+++ b/binutils/acinclude.m4
@@ -0,0 +1 @@
+sinclude(../bfd/acinclude.m4)
diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4
new file mode 100644
index 00000000000..88a1565f2b8
--- /dev/null
+++ b/binutils/aclocal.m4
@@ -0,0 +1,1120 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+sinclude(../bfd/acinclude.m4)
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+# serial 35 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_REQUIRE([AC_SYS_SYMBOL_UNDERSCORE])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ AC_SYS_LIBTOOL_CYGWIN
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+AC_ARG_ENABLE(libtool-lock,
+[ --disable-libtool-lock force libtool not to do file locking],
+need_locks=$enableval,
+need_locks=yes)
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+])
+
+# AC_LIBTOOL_DLOPEN - check for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [lt_dlopen=yes])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED,
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED,
+[AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC,
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC,
+[AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL,
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL,
+[AC_ENABLE_FAST_INSTALL(no)])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_SYS_NM_PARSE - Check for command to grab the raw symbol name followed
+# by C symbol name from nm.
+AC_DEFUN(AC_SYS_NM_PARSE,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+changequote([,])dnl
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+changequote(,)dnl
+lt_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+])
+
+# AC_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin
+AC_DEFUN(AC_SYS_LIBTOOL_CYGWIN,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# AC_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
+# with an underscore?
+AC_DEFUN(AC_SYS_SYMBOL_UNDERSCORE,
+[AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+AC_SUBST(USE_SYMBOL_UNDERSCORE)dnl
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM, [
+AC_CHECK_LIB(mw, _mwvalidcheckl)
+AC_CHECK_LIB(m, cos)
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [
+ AC_CHECK_LIB(ltdl, main, LIBLTDL="-lltdl", [
+ case "$enable_ltdl_install" in
+ no) AC_MSG_WARN([libltdl not installed, but installation disabled]) ;;
+ "") enable_ltdl_install=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-install" ;;
+ esac
+ ])
+ if test x"$enable_ltdl_install" != x"no"; then
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+AC_DEFUN(AM_SYS_NM_PARSE, [indir([AC_SYS_NM_PARSE])])dnl
+AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE, [indir([AC_SYS_SYMBOL_UNDERSCORE])])dnl
+AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN, [indir([AC_SYS_LIBTOOL_CYGWIN])])dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+
+dnl AM_PROG_LEX
+dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT
+AC_DEFUN(AM_PROG_LEX,
+[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1)
+AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex")
+AC_PROG_LEX
+AC_DECL_YYTEXT])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/binutils/addr2line.1 b/binutils/addr2line.1
new file mode 100644
index 00000000000..87ce103f8e3
--- /dev/null
+++ b/binutils/addr2line.1
@@ -0,0 +1,127 @@
+.\" Copyright (c) 1997 Free Software Foundation
+.\" See COPYING for conditions for redistribution
+.TH addr2line 1 "27 March 1997" "Cygnus Solutions" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+addr2line \- convert addresses into file names and line numbers
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B addr2line
+.RB "[\|" "\-b\ "\c
+.I bfdname\c
+.RB " | " "\-\-target="\c
+.I bfdname\c
+\&\|]
+.RB "[\|" \-C | \-\-demangle "\|]"
+.RB "[\|" "\-e\ "\c
+.I filename\c
+.RB " | " "\-\-exe="\c
+.I filename\c
+\&\|]
+.RB "[\|" \-f | \-\-functions "\|]"
+.RB "[\|" \-s | \-\-basenames "\|]"
+.RB "[\|" \-H | \-\-help "\|]"
+.RB "[\|" \-V | \-\-version "\|]"
+.RB "[\|" addr addr ... "\|]"
+.ad b
+.hy 1
+.SH DESCRIPTION
+\c
+.B addr2line
+translates program addresses into file names and line numbers. Given
+an address and an executable, it uses the debugging information in the
+executable to figure out which file name and line number are
+associated with a given address.
+
+The executable to use is specified with the
+.B \-e
+option. The default is
+.B a.out\c
+\&.
+
+.B addr2line
+has two modes of operation.
+
+In the first, hexadecimal addresses are specified on the command line,
+and
+.B addr2line
+displays the file name and line number for each address.
+
+In the second,
+.B addr2line
+reads hexadecimal addresses from standard input, and prints the file
+name and line number for each address on standard output. In this
+mode,
+.B addr2line
+may be used in a pipe to convert dynamically chosen addresses.
+
+The format of the output is FILENAME:LINENO. The file name and line
+number for each address is printed on a separate line. If the
+.B \-f
+option is used, then each FILENAME:LINENO line is preceded by a
+FUNCTIONNAME line which is the name of the function containing the
+address.
+
+If the file name or function name can not be determined,
+.B addr2line
+will print two question marks in their place. If the line number can
+not be determined,
+.B addr2line
+will print 0.
+
+.SH OPTIONS
+.TP
+.BI "\-b " "bfdname"\c
+.TP
+.BI "\-\-target=" "bfdname"
+Specify the object-code format for the object files to be
+\c
+.I bfdname\c
+\&.
+
+.TP
+.B \-C
+.TP
+.B \-\-demangle
+Decode (\fIdemangle\fP) low-level symbol names into user-level names.
+Besides removing any initial underscore prepended by the system, this
+makes C++ function names readable.
+
+.TP
+.BI "\-e " "filename"\c
+.TP
+.BI "\-\-exe=" "filename"
+Specify the name of the executable for which addresses should be
+translated. The default file is
+.B a.out\c
+\&.
+
+.TP
+.B \-f
+.TP
+.B \-\-functions
+Display function names as well as file and line number information.
+
+.TP
+.B \-s
+.TP
+.B \-\-basenames
+Display only the base of each file name.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (October 1991).
diff --git a/binutils/addr2line.c b/binutils/addr2line.c
new file mode 100644
index 00000000000..3cee867f3e1
--- /dev/null
+++ b/binutils/addr2line.c
@@ -0,0 +1,335 @@
+/* addr2line.c -- convert addresses to line number and function name
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+ Contributed by Ulrich Lauther <Ulrich.Lauther@zfe.siemens.de>
+
+ 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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Derived from objdump.c and nm.c by Ulrich.Lauther@zfe.siemens.de
+
+ Usage:
+ addr2line [options] addr addr ...
+ or
+ addr2line [options]
+
+ both forms write results to stdout, the second form reads addresses
+ to be converted from stdin. */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "bfd.h"
+#include "getopt.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "bucomm.h"
+
+extern char *program_version;
+
+static boolean with_functions; /* -f, show function names. */
+static boolean do_demangle; /* -C, demangle names. */
+static boolean base_names; /* -s, strip directory names. */
+
+static int naddr; /* Number of addresses to process. */
+static char **addr; /* Hex addresses to process. */
+
+static asymbol **syms; /* Symbol table. */
+
+static struct option long_options[] =
+{
+ {"basenames", no_argument, NULL, 's'},
+ {"demangle", no_argument, NULL, 'C'},
+ {"exe", required_argument, NULL, 'e'},
+ {"functions", no_argument, NULL, 'f'},
+ {"target", required_argument, NULL, 'b'},
+ {"help", no_argument, NULL, 'H'},
+ {"version", no_argument, NULL, 'V'},
+ {0, no_argument, 0, 0}
+};
+
+static void usage PARAMS ((FILE *, int));
+static void slurp_symtab PARAMS ((bfd *));
+static void find_address_in_section PARAMS ((bfd *, asection *, PTR));
+static void translate_addresses PARAMS ((bfd *));
+static void process_file PARAMS ((const char *, const char *));
+
+/* Print a usage message to STREAM and exit with STATUS. */
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, _("\
+Usage: %s [-CfsHV] [-b bfdname] [--target=bfdname]\n\
+ [-e executable] [--exe=executable] [--demangle]\n\
+ [--basenames] [--functions] [addr addr ...]\n"),
+ program_name);
+ list_supported_targets (program_name, stream);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+/* Read in the symbol table. */
+
+static void
+slurp_symtab (abfd)
+ bfd *abfd;
+{
+ long storage;
+ long symcount;
+
+ if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
+ return;
+
+ storage = bfd_get_symtab_upper_bound (abfd);
+ if (storage < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ syms = (asymbol **) xmalloc (storage);
+
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+}
+
+/* These global variables are used to pass information between
+ translate_addresses and find_address_in_section. */
+
+static bfd_vma pc;
+static const char *filename;
+static const char *functionname;
+static unsigned int line;
+static boolean found;
+
+/* Look for an address in a section. This is called via
+ bfd_map_over_sections. */
+
+static void
+find_address_in_section (abfd, section, data)
+ bfd *abfd;
+ asection *section;
+ PTR data;
+{
+ bfd_vma vma;
+ bfd_size_type size;
+
+ if (found)
+ return;
+
+ if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ vma = bfd_get_section_vma (abfd, section);
+ if (pc < vma)
+ return;
+
+ size = bfd_get_section_size_before_reloc (section);
+ if (pc >= vma + size)
+ return;
+
+ found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
+ &filename, &functionname, &line);
+}
+
+/* Read hexadecimal addresses from stdin, translate into
+ file_name:line_number and optionally function name. */
+
+static void
+translate_addresses (abfd)
+ bfd *abfd;
+{
+ int read_stdin = (naddr == 0);
+
+ for (;;)
+ {
+ if (read_stdin)
+ {
+ char addr_hex[100];
+
+ if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
+ break;
+ pc = bfd_scan_vma (addr_hex, NULL, 16);
+ }
+ else
+ {
+ if (naddr <= 0)
+ break;
+ --naddr;
+ pc = bfd_scan_vma (*addr++, NULL, 16);
+ }
+
+ found = false;
+ bfd_map_over_sections (abfd, find_address_in_section, (PTR) NULL);
+
+ if (! found)
+ {
+ if (with_functions)
+ printf ("??\n");
+ printf ("??:0\n");
+ }
+ else
+ {
+ if (with_functions)
+ {
+ if (functionname == NULL || *functionname == '\0')
+ printf ("??\n");
+ else if (! do_demangle)
+ printf ("%s\n", functionname);
+ else
+ {
+ char *res;
+
+ res = cplus_demangle (functionname, DMGL_ANSI | DMGL_PARAMS);
+ if (res == NULL)
+ printf ("%s\n", functionname);
+ else
+ {
+ printf ("%s\n", res);
+ free (res);
+ }
+ }
+ }
+
+ if (base_names && filename != NULL)
+ {
+ char *h;
+
+ h = strrchr (filename, '/');
+ if (h != NULL)
+ filename = h + 1;
+ }
+
+ printf ("%s:%u\n", filename ? filename : "??", line);
+ }
+
+ /* fflush() is essential for using this command as a server
+ child process that reads addresses from a pipe and responds
+ with line number information, processing one address at a
+ time. */
+ fflush (stdout);
+ }
+}
+
+/* Process a file. */
+
+static void
+process_file (filename, target)
+ const char *filename;
+ const char *target;
+{
+ bfd *abfd;
+ char **matching;
+
+ abfd = bfd_openr (filename, target);
+ if (abfd == NULL)
+ bfd_fatal (filename);
+
+ if (bfd_check_format (abfd, bfd_archive))
+ fatal (_("%s: can not get addresses from archive"), filename);
+
+ if (! bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ xexit (1);
+ }
+
+ slurp_symtab (abfd);
+
+ translate_addresses (abfd);
+
+ if (syms != NULL)
+ {
+ free (syms);
+ syms = NULL;
+ }
+
+ bfd_close (abfd);
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *filename;
+ char *target;
+ int c;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = *argv;
+ xmalloc_set_program_name (program_name);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ filename = NULL;
+ target = NULL;
+ while ((c = getopt_long (argc, argv, "b:Ce:sfHV", long_options, (int *) 0))
+ != EOF)
+ {
+ switch (c)
+ {
+ case 0:
+ break; /* we've been given a long option */
+ case 'b':
+ target = optarg;
+ break;
+ case 'C':
+ do_demangle = true;
+ break;
+ case 'e':
+ filename = optarg;
+ break;
+ case 's':
+ base_names = true;
+ break;
+ case 'f':
+ with_functions = true;
+ break;
+ case 'V':
+ print_version ("addr2line");
+ break;
+ case 'H':
+ usage (stdout, 0);
+ break;
+ default:
+ usage (stderr, 1);
+ break;
+ }
+ }
+
+ if (filename == NULL)
+ filename = "a.out";
+
+ addr = argv + optind;
+ naddr = argc - optind;
+
+ process_file (filename, target);
+
+ return 0;
+}
diff --git a/binutils/ar.1 b/binutils/ar.1
new file mode 100644
index 00000000000..e4e8cff8134
--- /dev/null
+++ b/binutils/ar.1
@@ -0,0 +1,509 @@
+.\" Copyright (c) 1991 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH ar 1 "5 November 1991" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+ar \- create, modify, and extract from archives.
+
+.SH SYNOPSIS
+.hy 0
+.na
+.BR ar " [\|" "-" "\|]"\c
+.I {dmpqrtx}[abcilosSuvV] \c
+[\|\c
+.I membername\c
+\&\|] \c
+.I archive\c
+\& \c
+.I files\c
+\&.\|.\|.
+
+.ad b
+.hy 1
+.SH DESCRIPTION
+The GNU \c
+.B ar\c
+\& program creates, modifies, and extracts from
+archives. An \c
+.I archive\c
+\& is a single file holding a collection of
+other files in a structure that makes it possible to retrieve
+the original individual files (called \c
+.I members\c
+\& of the archive).
+
+The original files' contents, mode (permissions), timestamp, owner, and
+group are preserved in the archive, and may be reconstituted on
+extraction.
+
+GNU \c
+.B ar\c
+\& can maintain archives whose members have names of any
+length; however, depending on how \c
+.B ar\c
+\& is configured on your
+system, a limit on member-name length may be imposed (for compatibility
+with archive formats maintained with other tools). If it exists, the
+limit is often 15 characters (typical of formats related to a.out) or 16
+characters (typical of formats related to coff).
+
+\c
+.B ar\c
+\& is considered a binary utility because archives of this sort
+are most often used as \c
+.I libraries\c
+\& holding commonly needed
+subroutines.
+
+\c
+.B ar\c
+\& will create an index to the symbols defined in relocatable
+object modules in the archive when you specify the modifier `\|\c
+.B s\c
+\|'.
+Once created, this index is updated in the archive whenever \c
+.B ar\c
+\&
+makes a change to its contents (save for the `\|\c
+.B q\c
+\|' update operation).
+An archive with such an index speeds up linking to the library, and
+allows routines in the library to call each other without regard to
+their placement in the archive.
+
+You may use `\|\c
+.B nm \-s\c
+\|' or `\|\c
+.B nm \-\-print\-armap\c
+\|' to list this index
+table. If an archive lacks the table, another form of \c
+.B ar\c
+\& called
+\c
+.B ranlib\c
+\& can be used to add just the table.
+
+\c
+.B ar\c
+\& insists on at least two arguments to execute: one
+keyletter specifying the \c
+.I operation\c
+\& (optionally accompanied by other
+keyletters specifying \c
+.I modifiers\c
+\&), and the archive name to act on.
+
+Most operations can also accept further \c
+.I files\c
+\& arguments,
+specifying particular files to operate on.
+
+.SH OPTIONS
+GNU \c
+.B ar\c
+\& allows you to mix the operation code \c
+.I p\c
+\& and modifier
+flags \c
+.I mod\c
+\& in any order, within the first command-line argument.
+
+If you wish, you may begin the first command-line argument with a
+dash.
+
+The \c
+.I p\c
+\& keyletter specifies what operation to execute; it may be
+any of the following, but you must specify only one of them:
+
+.TP
+.B d
+\c
+.I Delete\c
+\& modules from the archive. Specify the names of modules to
+be deleted as \c
+.I files\c
+\&; the archive is untouched if you
+specify no files to delete.
+
+If you specify the `\|\c
+.B v\c
+\|' modifier, \c
+.B ar\c
+\& will list each module
+as it is deleted.
+
+.TP
+.B m
+Use this operation to \c
+.I move\c
+\& members in an archive.
+
+The ordering of members in an archive can make a difference in how
+programs are linked using the library, if a symbol is defined in more
+than one member.
+
+If no modifiers are used with \c
+.B m\c
+\&, any members you name in the
+\c
+.I files\c
+\& arguments are moved to the \c
+.I end\c
+\& of the archive;
+you can use the `\|\c
+.B a\c
+\|', `\|\c
+.B b\c
+\|', or `\|\c
+.B i\c
+\|' modifiers to move them to a
+specified place instead.
+
+.TP
+.B p
+\c
+.I Print\c
+\& the specified members of the archive, to the standard
+output file. If the `\|\c
+.B v\c
+\|' modifier is specified, show the member
+name before copying its contents to standard output.
+
+If you specify no \c
+.I files\c
+\&, all the files in the archive are printed.
+
+.TP
+.B q
+\c
+.I Quick append\c
+\&; add \c
+.I files\c
+\& to the end of \c
+.I archive\c
+\&,
+without checking for replacement.
+
+The modifiers `\|\c
+.B a\c
+\|', `\|\c
+.B b\c
+\|', and `\|\c
+.B i\c
+\|' do \c
+.I not\c
+\& affect this
+operation; new members are always placed at the end of the archive.
+
+The modifier `\|\c
+.B v\c
+\|' makes \c
+.B ar\c
+\& list each file as it is appended.
+
+Since the point of this operation is speed, the archive's symbol table
+index is not updated, even if it already existed; you can use `\|\c
+.B ar s\c
+\|' or
+\c
+.B ranlib\c
+\& explicitly to update the symbol table index.
+
+However, too many different systems assume quick append rebuilds the
+index, so GNU
+.B ar
+implements `\|\c
+.B q\c
+\|' as a synonym for `\|\c
+.B r\c
+\|'.
+
+.TP
+.B r
+Insert \c
+.I files\c
+\& into \c
+.I archive\c
+\& (with \c
+.I replacement\c
+\&). This
+operation differs from `\|\c
+.B q\c
+\|' in that any previously existing members
+are deleted if their names match those being added.
+
+If one of the files named in \c
+.I files\c
+\& doesn't exist, \c
+.B ar\c
+\&
+displays an error message, and leaves undisturbed any existing members
+of the archive matching that name.
+
+By default, new members are added at the end of the file; but you may
+use one of the modifiers `\|\c
+.B a\c
+\|', `\|\c
+.B b\c
+\|', or `\|\c
+.B i\c
+\|' to request
+placement relative to some existing member.
+
+The modifier `\|\c
+.B v\c
+\|' used with this operation elicits a line of
+output for each file inserted, along with one of the letters `\|\c
+.B a\c
+\|' or
+`\|\c
+.B r\c
+\|' to indicate whether the file was appended (no old member
+deleted) or replaced.
+
+.TP
+.B t
+Display a \c
+.I table\c
+\& listing the contents of \c
+.I archive\c
+\&, or those
+of the files listed in \c
+.I files\c
+\& that are present in the
+archive. Normally only the member name is shown; if you also want to
+see the modes (permissions), timestamp, owner, group, and size, you can
+request that by also specifying the `\|\c
+.B v\c
+\|' modifier.
+
+If you do not specify any \c
+.I files\c
+\&, all files in the archive
+are listed.
+
+If there is more than one file with the same name (say, `\|\c
+.B fie\c
+\|') in
+an archive (say `\|\c
+.B b.a\c
+\|'), `\|\c
+.B ar t b.a fie\c
+\|' will list only the
+first instance; to see them all, you must ask for a complete
+listing\(em\&in our example, `\|\c
+.B ar t b.a\c
+\|'.
+
+.TP
+.B x
+\c
+.I Extract\c
+\& members (named \c
+.I files\c
+\&) from the archive. You can
+use the `\|\c
+.B v\c
+\|' modifier with this operation, to request that
+\c
+.B ar\c
+\& list each name as it extracts it.
+
+If you do not specify any \c
+.I files\c
+\&, all files in the archive
+are extracted.
+
+.PP
+
+A number of modifiers (\c
+.I mod\c
+\&) may immediately follow the \c
+.I p\c
+\&
+keyletter, to specify variations on an operation's behavior:
+
+.TP
+.B a
+Add new files \c
+.I after\c
+\& an existing member of the
+archive. If you use the modifier \c
+.B a\c
+\&, the name of an existing archive
+member must be present as the \c
+.I membername\c
+\& argument, before the
+\c
+.I archive\c
+\& specification.
+
+.TP
+.B b
+Add new files \c
+.I before\c
+\& an existing member of the
+archive. If you use the modifier \c
+.B b\c
+\&, the name of an existing archive
+member must be present as the \c
+.I membername\c
+\& argument, before the
+\c
+.I archive\c
+\& specification. (same as `\|\c
+.B i\c
+\|').
+
+.TP
+.B c
+\c
+.I Create\c
+\& the archive. The specified \c
+.I archive\c
+\& is always
+created if it didn't exist, when you request an update. But a warning is
+issued unless you specify in advance that you expect to create it, by
+using this modifier.
+
+.TP
+.B f
+Truncate names in the archive.
+.B ar
+will normally permit file names of any length. This will cause it to
+create archives which are not compatible with the native
+.B ar
+program on some systems. If this is a concern, the
+.B f
+modifier may be used to truncate file names when putting them in the
+archive.
+
+.TP
+.B i
+Insert new files \c
+.I before\c
+\& an existing member of the
+archive. If you use the modifier \c
+.B i\c
+\&, the name of an existing archive
+member must be present as the \c
+.I membername\c
+\& argument, before the
+\c
+.I archive\c
+\& specification. (same as `\|\c
+.B b\c
+\|').
+
+.TP
+.B l
+This modifier is accepted but not used.
+
+.TP
+.B o
+Preserve the \c
+.I original\c
+\& dates of members when extracting them. If
+you do not specify this modifier, files extracted from the archive
+will be stamped with the time of extraction.
+
+.TP
+.B s
+Write an object-file index into the archive, or update an existing one,
+even if no other change is made to the archive. You may use this modifier
+flag either with any operation, or alone. Running `\|\c
+.B ar s\c
+\|' on an
+archive is equivalent to running `\|\c
+.B ranlib\c
+\|' on it.
+
+.TP
+.B S
+Do not generate an archive symbol table. This can speed up building a
+large library in several steps. The resulting archive can not be used
+with the linker. In order to build a symbol table, you must omit the
+`\|\c
+.B S\c
+\|' modifier on the last execution of `\|\c
+.B ar\c
+\|', or you must run `\|\c
+.B ranlib\c
+\|' on the archive.
+
+.TP
+.B u
+Normally, \c
+.B ar r\c
+\&.\|.\|. inserts all files
+listed into the archive. If you would like to insert \c
+.I only\c
+\& those
+of the files you list that are newer than existing members of the same
+names, use this modifier. The `\|\c
+.B u\c
+\|' modifier is allowed only for the
+operation `\|\c
+.B r\c
+\|' (replace). In particular, the combination `\|\c
+.B qu\c
+\|' is
+not allowed, since checking the timestamps would lose any speed
+advantage from the operation `\|\c
+.B q\c
+\|'.
+
+.TP
+.B v
+This modifier requests the \c
+.I verbose\c
+\& version of an operation. Many
+operations display additional information, such as filenames processed,
+when the modifier `\|\c
+.B v\c
+\|' is appended.
+
+.TP
+.B V
+This modifier shows the version number of
+.BR ar .
+
+.PP
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+, Roland H. Pesch (October 1991).
+.BR nm ( 1 )\c
+\&,
+.BR ranlib ( 1 )\c
+\&.
+
+.SH COPYING
+Copyright (c) 1991 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/ar.c b/binutils/ar.c
new file mode 100644
index 00000000000..c951ef7b450
--- /dev/null
+++ b/binutils/ar.c
@@ -0,0 +1,1338 @@
+/* ar.c - Archive modify and extract.
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ Bugs: should use getopt the way tar does (complete w/optional -) and
+ should have long options too. GNU ar used to check file against filesystem
+ in quick_update and replace operations (would check mtime). Doesn't warn
+ when name truncated. No way to specify pos_end. Error messages should be
+ more consistant.
+*/
+#include "bfd.h"
+#include "libiberty.h"
+#include "progress.h"
+#include "bucomm.h"
+#include "aout/ar.h"
+#include "libbfd.h"
+#include "arsup.h"
+#include <sys/stat.h>
+
+#ifdef __GO32___
+#define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
+#else
+#define EXT_NAME_LEN 6 /* ditto for *NIX */
+#endif
+
+#define BUFSIZE 8192
+
+/* Kludge declaration from BFD! This is ugly! FIXME! XXX */
+
+struct ar_hdr *
+ bfd_special_undocumented_glue PARAMS ((bfd * abfd, const char *filename));
+
+/* Static declarations */
+
+static void
+mri_emul PARAMS ((void));
+
+static const char *
+normalize PARAMS ((const char *, bfd *));
+
+static void
+remove_output PARAMS ((void));
+
+static void
+map_over_members PARAMS ((bfd *, void (*)(bfd *), char **, int));
+
+static void
+print_contents PARAMS ((bfd * member));
+
+static void
+delete_members PARAMS ((bfd *, char **files_to_delete));
+
+#if 0
+static void
+do_quick_append PARAMS ((const char *archive_filename,
+ char **files_to_append));
+#endif
+
+static void
+move_members PARAMS ((bfd *, char **files_to_move));
+
+static void
+replace_members PARAMS ((bfd *, char **files_to_replace, boolean quick));
+
+static void
+print_descr PARAMS ((bfd * abfd));
+
+static void
+write_archive PARAMS ((bfd *));
+
+static void
+ranlib_only PARAMS ((const char *archname));
+
+static void
+ranlib_touch PARAMS ((const char *archname));
+
+static void
+usage PARAMS ((int));
+
+/** Globals and flags */
+
+int mri_mode;
+
+/* This flag distinguishes between ar and ranlib:
+ 1 means this is 'ranlib'; 0 means this is 'ar'.
+ -1 means if we should use argv[0] to decide. */
+extern int is_ranlib;
+
+/* Nonzero means don't warn about creating the archive file if necessary. */
+int silent_create = 0;
+
+/* Nonzero means describe each action performed. */
+int verbose = 0;
+
+/* Nonzero means preserve dates of members when extracting them. */
+int preserve_dates = 0;
+
+/* Nonzero means don't replace existing members whose dates are more recent
+ than the corresponding files. */
+int newer_only = 0;
+
+/* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
+ member). -1 means we've been explicitly asked to not write a symbol table;
+ +1 means we've been explictly asked to write it;
+ 0 is the default.
+ Traditionally, the default in BSD has been to not write the table.
+ However, for POSIX.2 compliance the default is now to write a symbol table
+ if any of the members are object files. */
+int write_armap = 0;
+
+/* Nonzero means it's the name of an existing member; position new or moved
+ files with respect to this one. */
+char *posname = NULL;
+
+/* Sez how to use `posname': pos_before means position before that member.
+ pos_after means position after that member. pos_end means always at end.
+ pos_default means default appropriately. For the latter two, `posname'
+ should also be zero. */
+enum pos
+ {
+ pos_default, pos_before, pos_after, pos_end
+ } postype = pos_default;
+
+static bfd **
+get_pos_bfd PARAMS ((bfd **, enum pos, const char *));
+
+/* Whether to truncate names of files stored in the archive. */
+static boolean ar_truncate = false;
+
+int interactive = 0;
+
+static void
+mri_emul ()
+{
+ interactive = isatty (fileno (stdin));
+ yyparse ();
+}
+
+/* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
+ COUNT is the length of the FILES chain; FUNCTION is called on each entry
+ whose name matches one in FILES. */
+
+static void
+map_over_members (arch, function, files, count)
+ bfd *arch;
+ void (*function) PARAMS ((bfd *));
+ char **files;
+ int count;
+{
+ bfd *head;
+
+ if (count == 0)
+ {
+ for (head = arch->next; head; head = head->next)
+ {
+ PROGRESS (1);
+ function (head);
+ }
+ return;
+ }
+ /* This may appear to be a baroque way of accomplishing what we want.
+ However we have to iterate over the filenames in order to notice where
+ a filename is requested but does not exist in the archive. Ditto
+ mapping over each file each time -- we want to hack multiple
+ references. */
+
+ 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
+ until the elements are opened. */
+ struct stat buf;
+ bfd_stat_arch_elt (head, &buf);
+ }
+ if ((head->filename != NULL) &&
+ (!strcmp (*files, head->filename)))
+ {
+ found = true;
+ function (head);
+ }
+ }
+ if (!found)
+ /* xgettext:c-format */
+ fprintf (stderr, _("no entry %s in archive\n"), *files);
+ }
+}
+
+boolean operation_alters_arch = false;
+
+static void
+usage (help)
+ int help;
+{
+ FILE *s;
+
+ s = help ? stdout : stderr;
+
+ if (! is_ranlib)
+ {
+ /* xgettext:c-format */
+ fprintf (s, _("Usage: %s [-]{dmpqrstx}[abcilosSuvV] [member-name] archive-file file...\n"), program_name);
+ /* xgettext:c-format */
+ fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
+ fprintf (s, _(" commands:\n"));
+ fprintf (s, _(" d - delete file(s) from the archive\n"));
+ fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
+ fprintf (s, _(" p - print file(s) found in the archive\n"));
+ fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
+ fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
+ fprintf (s, _(" t - display contents of archive\n"));
+ fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
+ fprintf (s, _(" command specific modifiers:\n"));
+ fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
+ fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
+ fprintf (s, _(" [f] - truncate inserted file names\n"));
+ fprintf (s, _(" [o] - preserve original dates\n"));
+ fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
+ fprintf (s, _(" generic modifiers:\n"));
+ fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
+ fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
+ fprintf (s, _(" [S] - do not build a symbol table\n"));
+ fprintf (s, _(" [v] - be verbose\n"));
+ fprintf (s, _(" [V] - display the version number\n"));
+ }
+ else
+ /* xgettext:c-format */
+ fprintf (s, _("Usage: %s [-vV] archive\n"), program_name);
+
+ list_supported_targets (program_name, stderr);
+
+ if (help)
+ fprintf (s, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+
+ xexit (help ? 0 : 1);
+}
+
+/* Normalize a file name specified on the command line into a file
+ name which we will use in an archive. */
+
+static const char *
+normalize (file, abfd)
+ const char *file;
+ bfd *abfd;
+{
+ const char *filename;
+
+ filename = strrchr (file, '/');
+ if (filename != (char *) NULL)
+ filename++;
+ else
+ filename = file;
+
+ if (ar_truncate
+ && abfd != NULL
+ && strlen (filename) > abfd->xvec->ar_max_namelen)
+ {
+ char *s;
+
+ /* Space leak. */
+ s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
+ memcpy (s, filename, abfd->xvec->ar_max_namelen);
+ s[abfd->xvec->ar_max_namelen] = '\0';
+ filename = s;
+ }
+
+ return filename;
+}
+
+/* Remove any output file. This is only called via xatexit. */
+
+static char *output_filename = NULL;
+static FILE *output_file = NULL;
+static bfd *output_bfd = NULL;
+
+static void
+remove_output ()
+{
+ if (output_filename != NULL)
+ {
+ if (output_bfd != NULL && output_bfd->iostream != NULL)
+ fclose ((FILE *) (output_bfd->iostream));
+ if (output_file != NULL)
+ fclose (output_file);
+ unlink (output_filename);
+ }
+}
+
+/* The option parsing should be in its own function.
+ It will be when I have getopt working. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *arg_ptr;
+ char c;
+ enum
+ {
+ none = 0, delete, replace, print_table,
+ print_files, extract, move, quick_append
+ } operation = none;
+ int arg_index;
+ char **files;
+ char *inarch_filename;
+ int show_version;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ if (is_ranlib < 0)
+ {
+ char *temp;
+
+ temp = strrchr (program_name, '/');
+ if (temp == NULL)
+ temp = program_name;
+ else
+ ++temp;
+ if (strlen (temp) >= 6
+ && strcmp (temp + strlen (temp) - 6, "ranlib") == 0)
+ is_ranlib = 1;
+ else
+ is_ranlib = 0;
+ }
+
+ if (argc > 1 && argv[1][0] == '-')
+ {
+ if (strcmp (argv[1], "--help") == 0)
+ usage (1);
+ else if (strcmp (argv[1], "--version") == 0)
+ {
+ if (is_ranlib)
+ print_version ("ranlib");
+ else
+ print_version ("ar");
+ }
+ }
+
+ START_PROGRESS (program_name, 0);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ show_version = 0;
+
+ xatexit (remove_output);
+
+ if (is_ranlib)
+ {
+ boolean touch = false;
+
+ if (argc < 2 || strcmp (argv[1], "--help") == 0)
+ usage (0);
+ if (strcmp (argv[1], "-V") == 0
+ || strcmp (argv[1], "-v") == 0
+ || strncmp (argv[1], "--v", 3) == 0)
+ print_version ("ranlib");
+ arg_index = 1;
+ if (strcmp (argv[1], "-t") == 0)
+ {
+ ++arg_index;
+ touch = true;
+ }
+ while (arg_index < argc)
+ {
+ if (! touch)
+ ranlib_only (argv[arg_index]);
+ else
+ ranlib_touch (argv[arg_index]);
+ ++arg_index;
+ }
+ xexit (0);
+ }
+
+ if (argc == 2 && strcmp (argv[1], "-M") == 0)
+ {
+ mri_emul ();
+ xexit (0);
+ }
+
+ if (argc < 2)
+ usage (0);
+
+ arg_ptr = argv[1];
+
+ if (*arg_ptr == '-')
+ ++arg_ptr; /* compatibility */
+
+ while ((c = *arg_ptr++) != '\0')
+ {
+ switch (c)
+ {
+ case 'd':
+ case 'm':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 't':
+ case 'x':
+ if (operation != none)
+ fatal (_("two different operation options specified"));
+ switch (c)
+ {
+ case 'd':
+ operation = delete;
+ operation_alters_arch = true;
+ break;
+ case 'm':
+ operation = move;
+ operation_alters_arch = true;
+ break;
+ case 'p':
+ operation = print_files;
+ break;
+ case 'q':
+ operation = quick_append;
+ operation_alters_arch = true;
+ break;
+ case 'r':
+ operation = replace;
+ operation_alters_arch = true;
+ break;
+ case 't':
+ operation = print_table;
+ break;
+ case 'x':
+ operation = extract;
+ break;
+ }
+ case 'l':
+ break;
+ case 'c':
+ silent_create = 1;
+ break;
+ case 'o':
+ preserve_dates = 1;
+ break;
+ case 'V':
+ show_version = true;
+ break;
+ case 's':
+ write_armap = 1;
+ break;
+ case 'S':
+ write_armap = -1;
+ break;
+ case 'u':
+ newer_only = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'a':
+ postype = pos_after;
+ break;
+ case 'b':
+ postype = pos_before;
+ break;
+ case 'i':
+ postype = pos_before;
+ break;
+ case 'M':
+ mri_mode = 1;
+ break;
+ case 'f':
+ ar_truncate = true;
+ break;
+ default:
+ /* xgettext:c-format */
+ fprintf (stderr, _("%s: illegal option -- %c\n"), program_name, c);
+ usage (0);
+ }
+ }
+
+ if (show_version)
+ print_version ("ar");
+
+ if (argc < 3)
+ usage (0);
+
+ if (mri_mode)
+ {
+ mri_emul ();
+ }
+ else
+ {
+ bfd *arch;
+
+ /* We can't write an armap when using ar q, so just do ar r
+ instead. */
+ if (operation == quick_append && write_armap)
+ operation = replace;
+
+ if ((operation == none || operation == print_table)
+ && write_armap == 1)
+ {
+ ranlib_only (argv[2]);
+ xexit (0);
+ }
+
+ if (operation == none)
+ fatal (_("no operation specified"));
+
+ if (newer_only && operation != replace)
+ fatal (_("`u' is only meaningful with the `r' option."));
+
+ arg_index = 2;
+
+ if (postype != pos_default)
+ posname = argv[arg_index++];
+
+ inarch_filename = argv[arg_index++];
+
+ files = arg_index < argc ? argv + arg_index : NULL;
+
+#if 0
+ /* We don't use do_quick_append any more. Too many systems
+ expect ar to always rebuild the symbol table even when q is
+ used. */
+
+ /* We can't do a quick append if we need to construct an
+ extended name table, because do_quick_append won't be able to
+ rebuild the name table. Unfortunately, at this point we
+ don't actually know the maximum name length permitted by this
+ object file format. So, we guess. FIXME. */
+ if (operation == quick_append && ! ar_truncate)
+ {
+ char **chk;
+
+ for (chk = files; chk != NULL && *chk != '\0'; chk++)
+ {
+ if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
+ {
+ operation = replace;
+ break;
+ }
+ }
+ }
+
+ if (operation == quick_append)
+ {
+ /* Note that quick appending to a non-existent archive creates it,
+ even if there are no files to append. */
+ do_quick_append (inarch_filename, files);
+ xexit (0);
+ }
+#endif
+
+ arch = open_inarch (inarch_filename,
+ files == NULL ? (char *) NULL : files[0]);
+
+ switch (operation)
+ {
+ case print_table:
+ map_over_members (arch, print_descr, files, argc - 3);
+ break;
+
+ case print_files:
+ map_over_members (arch, print_contents, files, argc - 3);
+ break;
+
+ case extract:
+ map_over_members (arch, extract_file, files, argc - 3);
+ break;
+
+ case delete:
+ if (files != NULL)
+ delete_members (arch, files);
+ break;
+
+ case move:
+ if (files != NULL)
+ move_members (arch, files);
+ break;
+
+ case replace:
+ case quick_append:
+ if (files != NULL || write_armap > 0)
+ replace_members (arch, files, operation == quick_append);
+ break;
+
+ /* Shouldn't happen! */
+ default:
+ /* xgettext:c-format */
+ fprintf (stderr, _("%s: internal error -- this option not implemented\n"),
+ program_name);
+ xexit (1);
+ }
+ }
+
+ END_PROGRESS (program_name);
+
+ xexit (0);
+ return 0;
+}
+
+bfd *
+open_inarch (archive_filename, file)
+ const char *archive_filename;
+ const char *file;
+{
+ const char *target;
+ bfd **last_one;
+ bfd *next_one;
+ struct stat sbuf;
+ bfd *arch;
+ char **matching;
+
+ bfd_set_error (bfd_error_no_error);
+
+ target = NULL;
+
+ if (stat (archive_filename, &sbuf) != 0)
+ {
+#ifndef __GO32__
+
+/* KLUDGE ALERT! Temporary fix until I figger why
+ * stat() is wrong ... think it's buried in GO32's IDT
+ * - Jax
+ */
+ if (errno != ENOENT)
+ bfd_fatal (archive_filename);
+#endif
+
+ if (!operation_alters_arch)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ perror (archive_filename);
+ maybequit ();
+ return NULL;
+ }
+
+ /* Try to figure out the target to use for the archive from the
+ first object on the list. */
+ if (file != NULL)
+ {
+ bfd *obj;
+
+ obj = bfd_openr (file, NULL);
+ if (obj != NULL)
+ {
+ if (bfd_check_format (obj, bfd_object))
+ target = bfd_get_target (obj);
+ (void) bfd_close (obj);
+ }
+ }
+
+ /* Create an empty archive. */
+ arch = bfd_openw (archive_filename, target);
+ if (arch == NULL
+ || ! bfd_set_format (arch, bfd_archive)
+ || ! bfd_close (arch))
+ bfd_fatal (archive_filename);
+ }
+
+ arch = bfd_openr (archive_filename, target);
+ if (arch == NULL)
+ {
+ bloser:
+ bfd_fatal (archive_filename);
+ }
+
+ if (! bfd_check_format_matches (arch, bfd_archive, &matching))
+ {
+ bfd_nonfatal (archive_filename);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ xexit (1);
+ }
+
+ last_one = &(arch->next);
+ /* Read all the contents right away, regardless. */
+ for (next_one = bfd_openr_next_archived_file (arch, NULL);
+ next_one;
+ next_one = bfd_openr_next_archived_file (arch, next_one))
+ {
+ PROGRESS (1);
+ *last_one = next_one;
+ last_one = &next_one->next;
+ }
+ *last_one = (bfd *) NULL;
+ if (bfd_get_error () != bfd_error_no_more_archived_files)
+ goto bloser;
+ return arch;
+}
+
+static void
+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)
+ /* xgettext:c-format */
+ fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
+
+ if (verbose)
+ /* xgettext:c-format */
+ printf (_("\n<member %s>\n\n"), bfd_get_filename (abfd));
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ size = buf.st_size;
+ while (ncopied < size)
+ {
+
+ int nread;
+ int tocopy = size - ncopied;
+ if (tocopy > BUFSIZE)
+ tocopy = BUFSIZE;
+
+ nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke
+ abstraction! */
+ if (nread != tocopy)
+ /* xgettext:c-format */
+ fatal (_("%s is not a valid archive"),
+ bfd_get_filename (bfd_my_archive (abfd)));
+ fwrite (cbuf, 1, nread, stdout);
+ ncopied += tocopy;
+ }
+ free (cbuf);
+}
+
+/* Extract a member of the archive into its own file.
+
+ We defer opening the new file until after we have read a BUFSIZ chunk of the
+ old one, since we know we have just read the archive header for the old
+ one. Since most members are shorter than BUFSIZ, this means we will read
+ the old header, read the old data, write a new inode for the new file, and
+ write the new data, and be done. This 'optimization' is what comes from
+ sitting next to a bare disk and hearing it every time it seeks. -- Gnu
+ Gilmore */
+
+void
+extract_file (abfd)
+ bfd *abfd;
+{
+ FILE *ostream;
+ char *cbuf = xmalloc (BUFSIZE);
+ int nread, tocopy;
+ long ncopied = 0;
+ long size;
+ struct stat buf;
+
+ if (bfd_stat_arch_elt (abfd, &buf) != 0)
+ /* xgettext:c-format */
+ fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
+ size = buf.st_size;
+
+ if (size < 0)
+ /* xgettext:c-format */
+ fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
+
+ if (verbose)
+ printf ("x - %s\n", bfd_get_filename (abfd));
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ ostream = NULL;
+ if (size == 0)
+ {
+ /* Seems like an abstraction violation, eh? Well it's OK! */
+ output_filename = bfd_get_filename (abfd);
+
+ ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
+ if (ostream == NULL)
+ {
+ perror (bfd_get_filename (abfd));
+ xexit (1);
+ }
+
+ output_file = ostream;
+ }
+ else
+ while (ncopied < size)
+ {
+ tocopy = size - ncopied;
+ if (tocopy > BUFSIZE)
+ tocopy = BUFSIZE;
+
+ nread = bfd_read (cbuf, 1, tocopy, abfd);
+ if (nread != tocopy)
+ /* xgettext:c-format */
+ fatal (_("%s is not a valid archive"),
+ bfd_get_filename (bfd_my_archive (abfd)));
+
+ /* See comment above; this saves disk arm motion */
+ if (ostream == NULL)
+ {
+ /* Seems like an abstraction violation, eh? Well it's OK! */
+ output_filename = bfd_get_filename (abfd);
+
+ ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
+ if (ostream == NULL)
+ {
+ perror (bfd_get_filename (abfd));
+ xexit (1);
+ }
+
+ output_file = ostream;
+ }
+ fwrite (cbuf, 1, nread, ostream);
+ ncopied += tocopy;
+ }
+
+ if (ostream != NULL)
+ fclose (ostream);
+
+ output_file = NULL;
+ output_filename = NULL;
+
+ chmod (bfd_get_filename (abfd), buf.st_mode);
+
+ if (preserve_dates)
+ set_times (bfd_get_filename (abfd), &buf);
+
+ free (cbuf);
+}
+
+#if 0
+
+/* We don't use this anymore. Too many systems expect ar to rebuild
+ the symbol table even when q is used. */
+
+/* Just do it quickly; don't worry about dups, armap, or anything like that */
+
+static void
+do_quick_append (archive_filename, files_to_append)
+ const char *archive_filename;
+ char **files_to_append;
+{
+ FILE *ofile, *ifile;
+ char *buf = xmalloc (BUFSIZE);
+ long tocopy, thistime;
+ bfd *temp;
+ struct stat sbuf;
+ boolean newfile = false;
+ bfd_set_error (bfd_error_no_error);
+
+ if (stat (archive_filename, &sbuf) != 0)
+ {
+
+#ifndef __GO32__
+
+/* KLUDGE ALERT! Temporary fix until I figger why
+ * stat() is wrong ... think it's buried in GO32's IDT
+ * - Jax
+ */
+
+ if (errno != ENOENT)
+ bfd_fatal (archive_filename);
+#endif
+
+ newfile = true;
+ }
+
+ ofile = fopen (archive_filename, FOPEN_AUB);
+ if (ofile == NULL)
+ {
+ perror (program_name);
+ xexit (1);
+ }
+
+ temp = bfd_openr (archive_filename, NULL);
+ if (temp == NULL)
+ {
+ bfd_fatal (archive_filename);
+ }
+ if (newfile == false)
+ {
+ if (bfd_check_format (temp, bfd_archive) != true)
+ /* xgettext:c-format */
+ fatal (_("%s is not an archive"), archive_filename);
+ }
+ else
+ {
+ fwrite (ARMAG, 1, SARMAG, ofile);
+ if (!silent_create)
+ /* xgettext:c-format */
+ fprintf (stderr, _("%s: creating %s\n"),
+ program_name, archive_filename);
+ }
+
+ if (ar_truncate)
+ temp->flags |= BFD_TRADITIONAL_FORMAT;
+
+ /* assume it's an achive, go straight to the end, sans $200 */
+ fseek (ofile, 0, 2);
+
+ for (; files_to_append && *files_to_append; ++files_to_append)
+ {
+ struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
+ if (hdr == NULL)
+ {
+ bfd_fatal (*files_to_append);
+ }
+
+ BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
+
+ ifile = fopen (*files_to_append, FOPEN_RB);
+ if (ifile == NULL)
+ {
+ bfd_nonfatal (*files_to_append);
+ }
+
+ if (stat (*files_to_append, &sbuf) != 0)
+ {
+ bfd_nonfatal (*files_to_append);
+ }
+
+ tocopy = sbuf.st_size;
+
+ /* XXX should do error-checking! */
+ fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
+
+ while (tocopy > 0)
+ {
+ thistime = tocopy;
+ if (thistime > BUFSIZE)
+ thistime = BUFSIZE;
+ fread (buf, 1, thistime, ifile);
+ fwrite (buf, 1, thistime, ofile);
+ tocopy -= thistime;
+ }
+ fclose (ifile);
+ if ((sbuf.st_size % 2) == 1)
+ putc ('\012', ofile);
+ }
+ fclose (ofile);
+ bfd_close (temp);
+ free (buf);
+}
+
+#endif /* 0 */
+
+static void
+write_archive (iarch)
+ bfd *iarch;
+{
+ bfd *obfd;
+ 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));
+ new_name = make_tempname (old_name);
+
+ output_filename = new_name;
+
+ obfd = bfd_openw (new_name, bfd_get_target (iarch));
+
+ if (obfd == NULL)
+ bfd_fatal (old_name);
+
+ output_bfd = obfd;
+
+ bfd_set_format (obfd, bfd_archive);
+
+ /* Request writing the archive symbol table unless we've
+ been explicitly requested not to. */
+ obfd->has_armap = write_armap >= 0;
+
+ if (ar_truncate)
+ {
+ /* This should really use bfd_set_file_flags, but that rejects
+ archives. */
+ obfd->flags |= BFD_TRADITIONAL_FORMAT;
+ }
+
+ if (bfd_set_archive_head (obfd, contents_head) != true)
+ bfd_fatal (old_name);
+
+ if (!bfd_close (obfd))
+ bfd_fatal (old_name);
+
+ output_bfd = NULL;
+ output_filename = NULL;
+
+ /* We don't care if this fails; we might be creating the archive. */
+ bfd_close (iarch);
+
+ if (smart_rename (new_name, old_name, 0) != 0)
+ xexit (1);
+}
+
+/* Return a pointer to the pointer to the entry which should be rplacd'd
+ into when altering. DEFAULT_POS should be how to interpret pos_default,
+ and should be a pos value. */
+
+static bfd **
+get_pos_bfd (contents, default_pos, default_posname)
+ bfd **contents;
+ enum pos default_pos;
+ const char *default_posname;
+{
+ bfd **after_bfd = contents;
+ enum pos realpos;
+ const char *realposname;
+
+ if (postype == pos_default)
+ {
+ realpos = default_pos;
+ realposname = default_posname;
+ }
+ else
+ {
+ realpos = postype;
+ realposname = posname;
+ }
+
+ if (realpos == pos_end)
+ {
+ while (*after_bfd)
+ after_bfd = &((*after_bfd)->next);
+ }
+ else
+ {
+ for (; *after_bfd; after_bfd = &(*after_bfd)->next)
+ if (strcmp ((*after_bfd)->filename, realposname) == 0)
+ {
+ if (realpos == pos_after)
+ after_bfd = &(*after_bfd)->next;
+ break;
+ }
+ }
+ return after_bfd;
+}
+
+static void
+delete_members (arch, files_to_delete)
+ bfd *arch;
+ char **files_to_delete;
+{
+ bfd **current_ptr_ptr;
+ boolean found;
+ boolean something_changed = false;
+ for (; *files_to_delete != NULL; ++files_to_delete)
+ {
+ /* In a.out systems, the armap is optional. It's also called
+ __.SYMDEF. So if the user asked to delete it, we should remember
+ that fact. This isn't quite right for COFF systems (where
+ __.SYMDEF might be regular member), but it's very unlikely
+ to be a problem. FIXME */
+
+ if (!strcmp (*files_to_delete, "__.SYMDEF"))
+ {
+ arch->has_armap = false;
+ write_armap = -1;
+ continue;
+ }
+
+ found = false;
+ current_ptr_ptr = &(arch->next);
+ while (*current_ptr_ptr)
+ {
+ if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0)
+ {
+ found = true;
+ something_changed = true;
+ if (verbose)
+ printf ("d - %s\n",
+ *files_to_delete);
+ *current_ptr_ptr = ((*current_ptr_ptr)->next);
+ goto next_file;
+ }
+ else
+ {
+ current_ptr_ptr = &((*current_ptr_ptr)->next);
+ }
+ }
+
+ if (verbose && found == false)
+ {
+ /* xgettext:c-format */
+ printf (_("No member named `%s'\n"), *files_to_delete);
+ }
+ next_file:
+ ;
+ }
+
+ if (something_changed == true)
+ {
+ write_archive (arch);
+ }
+}
+
+
+/* Reposition existing members within an archive */
+
+static void
+move_members (arch, files_to_move)
+ bfd *arch;
+ char **files_to_move;
+{
+ bfd **after_bfd; /* New entries go after this one */
+ bfd **current_ptr_ptr; /* cdr pointer into contents */
+
+ for (; *files_to_move; ++files_to_move)
+ {
+ current_ptr_ptr = &(arch->next);
+ while (*current_ptr_ptr)
+ {
+ bfd *current_ptr = *current_ptr_ptr;
+ if (strcmp (normalize (*files_to_move, arch),
+ current_ptr->filename) == 0)
+ {
+ /* Move this file to the end of the list - first cut from
+ where it is. */
+ bfd *link;
+ *current_ptr_ptr = current_ptr->next;
+
+ /* Now glue to end */
+ after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
+ link = *after_bfd;
+ *after_bfd = current_ptr;
+ current_ptr->next = link;
+
+ if (verbose)
+ printf ("m - %s\n", *files_to_move);
+
+ goto next_file;
+ }
+
+ current_ptr_ptr = &((*current_ptr_ptr)->next);
+ }
+ /* xgettext:c-format */
+ fprintf (stderr, _("%s: no entry %s in archive %s!\n"),
+ program_name, *files_to_move, arch->filename);
+ xexit (1);
+ next_file:;
+ }
+
+ write_archive (arch);
+}
+
+/* Ought to default to replacing in place, but this is existing practice! */
+
+static void
+replace_members (arch, files_to_move, quick)
+ bfd *arch;
+ char **files_to_move;
+ boolean quick;
+{
+ boolean changed = false;
+ bfd **after_bfd; /* New entries go after this one */
+ bfd *current;
+ bfd **current_ptr;
+ bfd *temp;
+
+ while (files_to_move && *files_to_move)
+ {
+ if (! quick)
+ {
+ current_ptr = &arch->next;
+ while (*current_ptr)
+ {
+ current = *current_ptr;
+
+ /* For compatibility with existing ar programs, we
+ permit the same file to be added multiple times. */
+ if (strcmp (normalize (*files_to_move, arch),
+ normalize (current->filename, arch)) == 0
+ && current->arelt_data != NULL)
+ {
+ if (newer_only)
+ {
+ struct stat fsbuf, asbuf;
+
+ if (stat (*files_to_move, &fsbuf) != 0)
+ {
+ if (errno != ENOENT)
+ bfd_fatal (*files_to_move);
+ goto next_file;
+ }
+ if (bfd_stat_arch_elt (current, &asbuf) != 0)
+ /* xgettext:c-format */
+ fatal (_("internal stat error on %s"), current->filename);
+
+ if (fsbuf.st_mtime <= asbuf.st_mtime)
+ goto next_file;
+ }
+
+ after_bfd = get_pos_bfd (&arch->next, pos_after,
+ current->filename);
+ temp = *after_bfd;
+
+ *after_bfd = bfd_openr (*files_to_move, NULL);
+ if (*after_bfd == (bfd *) NULL)
+ {
+ bfd_fatal (*files_to_move);
+ }
+ (*after_bfd)->next = temp;
+
+ /* snip out this entry from the chain */
+ *current_ptr = (*current_ptr)->next;
+
+ if (verbose)
+ {
+ printf ("r - %s\n", *files_to_move);
+ }
+
+ changed = true;
+
+ goto next_file;
+ }
+ current_ptr = &(current->next);
+ }
+ }
+
+ /* Add to the end of the archive. */
+
+ after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
+ temp = *after_bfd;
+ *after_bfd = bfd_openr (*files_to_move, NULL);
+ if (*after_bfd == (bfd *) NULL)
+ {
+ bfd_fatal (*files_to_move);
+ }
+ if (verbose)
+ {
+ printf ("a - %s\n", *files_to_move);
+ }
+
+ (*after_bfd)->next = temp;
+
+ changed = true;
+
+ next_file:;
+
+ files_to_move++;
+ }
+
+ if (changed)
+ write_archive (arch);
+}
+
+static void
+ranlib_only (archname)
+ const char *archname;
+{
+ bfd *arch;
+
+ write_armap = 1;
+ arch = open_inarch (archname, (char *) NULL);
+ if (arch == NULL)
+ xexit (1);
+ write_archive (arch);
+}
+
+/* Update the timestamp of the symbol map of an archive. */
+
+static void
+ranlib_touch (archname)
+ const char *archname;
+{
+#ifdef __GO32__
+ /* I don't think updating works on go32. */
+ ranlib_only (archname);
+#else
+ int f;
+ bfd *arch;
+ char **matching;
+
+ f = open (archname, O_RDWR, 0);
+ if (f < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ bfd_fatal (archname);
+ }
+
+ arch = bfd_fdopenr (archname, (const char *) NULL, f);
+ if (arch == NULL)
+ bfd_fatal (archname);
+ if (! bfd_check_format_matches (arch, bfd_archive, &matching))
+ {
+ bfd_nonfatal (archname);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ xexit (1);
+ }
+
+ if (! bfd_has_map (arch))
+ /* xgettext:c-format */
+ fatal (_("%s: no archive map to update"), archname);
+
+ bfd_update_armap_timestamp (arch);
+
+ if (! bfd_close (arch))
+ bfd_fatal (archname);
+#endif
+}
+
+/* Things which are interesting to map over all or some of the files: */
+
+static void
+print_descr (abfd)
+ bfd *abfd;
+{
+ print_arelt_descr (stdout, abfd, verbose);
+}
diff --git a/binutils/arlex.l b/binutils/arlex.l
new file mode 100644
index 00000000000..74e13d13dfe
--- /dev/null
+++ b/binutils/arlex.l
@@ -0,0 +1,83 @@
+%{
+/* arlex.l - Strange script language lexer */
+
+/* Copyright (C) 1992, 95, 1997 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* Contributed by Steve Chamberlain
+ sac@cygnus.com
+
+*/
+#define DONTDECLARE_MALLOC
+#include <ansidecl.h>
+#include "libiberty.h"
+#include "arparse.h"
+
+int linenumber;
+%}
+%%
+
+"ADDLIB" { return ADDLIB; }
+"ADDMOD" { return ADDMOD; }
+"CLEAR" { return CLEAR; }
+"CREATE" { return CREATE; }
+"DELETE" { return DELETE; }
+"DIRECTORY" { return DIRECTORY; }
+"END" { return END; }
+"EXTRACT" { return EXTRACT; }
+"FULLDIR" { return FULLDIR; }
+"HELP" { return HELP; }
+"LIST" { return LIST; }
+"OPEN" { return OPEN; }
+"REPLACE" { return REPLACE; }
+"VERBOSE" { return VERBOSE; }
+"SAVE" { return SAVE; }
+"addlib" { return ADDLIB; }
+"addmod" { return ADDMOD; }
+"clear" { return CLEAR; }
+"create" { return CREATE; }
+"delete" { return DELETE; }
+"directory" { return DIRECTORY; }
+"end" { return END; }
+"extract" { return EXTRACT; }
+"fulldir" { return FULLDIR; }
+"help" { return HELP; }
+"list" { return LIST; }
+"open" { return OPEN; }
+"replace" { return REPLACE; }
+"verbose" { return VERBOSE; }
+"save" { return SAVE; }
+"+\n" { linenumber ++; }
+"(" { return '('; }
+")" { return ')'; }
+"," { return ','; }
+[A-Za-z0-9/$:.\-\_]+ {
+ yylval.name = xstrdup (yytext);
+ return FILENAME;
+ }
+"*".* { }
+";".* { }
+" " { }
+"\n" { linenumber ++; return NEWLINE; }
+
+%%
+#ifndef yywrap
+/* Needed for lex, though not flex. */
+int yywrap() { return 1; }
+#endif
diff --git a/binutils/arparse.y b/binutils/arparse.y
new file mode 100644
index 00000000000..d6c7600a87c
--- /dev/null
+++ b/binutils/arparse.y
@@ -0,0 +1,202 @@
+%{
+/* arparse.y - Stange script language parser */
+
+/* Copyright (C) 1992, 93, 95, 97, 98, 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* Contributed by Steve Chamberlain
+ sac@cygnus.com
+
+*/
+#define DONTDECLARE_MALLOC
+#include "bfd.h"
+#include "bucomm.h"
+#include "arsup.h"
+extern int verbose;
+extern int yylex PARAMS ((void));
+static int yyerror PARAMS ((const char *));
+%}
+
+%union {
+ char *name;
+struct list *list ;
+
+};
+
+%token NEWLINE
+%token VERBOSE
+%token <name> FILENAME
+%token ADDLIB
+%token LIST
+%token ADDMOD
+%token CLEAR
+%token CREATE
+%token DELETE
+%token DIRECTORY
+%token END
+%token EXTRACT
+%token FULLDIR
+%token HELP
+%token QUIT
+%token REPLACE
+%token SAVE
+%token OPEN
+
+%type <list> modulelist
+%type <list> modulename
+%type <name> optional_filename
+%%
+
+start:
+ { prompt(); } session
+ ;
+
+session:
+ session command_line
+ |
+ ;
+
+command_line:
+ command NEWLINE { prompt(); }
+
+command:
+ open_command
+ | create_command
+ | verbose_command
+ | directory_command
+ | addlib_command
+ | clear_command
+ | addmod_command
+ | save_command
+ | extract_command
+ | replace_command
+ | delete_command
+ | list_command
+ | END { ar_end(); return 0; }
+ | error
+ | FILENAME { yyerror("foo"); }
+ |
+ ;
+
+
+extract_command:
+ EXTRACT modulename
+ { ar_extract($2); }
+ ;
+
+replace_command:
+ REPLACE modulename
+ { ar_replace($2); }
+ ;
+
+clear_command:
+ CLEAR
+ { ar_clear(); }
+ ;
+
+delete_command:
+ DELETE modulename
+ { ar_delete($2); }
+ ;
+addmod_command:
+ ADDMOD modulename
+ { ar_addmod($2); }
+ ;
+
+list_command:
+ LIST
+ { ar_list(); }
+ ;
+
+save_command:
+ SAVE
+ { ar_save(); }
+ ;
+
+
+
+open_command:
+ OPEN FILENAME
+ { ar_open($2,0); }
+ ;
+
+create_command:
+ CREATE FILENAME
+ { ar_open($2,1); }
+ ;
+
+
+addlib_command:
+ ADDLIB FILENAME modulelist
+ { ar_addlib($2,$3); }
+ ;
+directory_command:
+ DIRECTORY FILENAME modulelist optional_filename
+ { ar_directory($2, $3, $4); }
+ ;
+
+
+
+optional_filename:
+ FILENAME
+ { $$ = $1; }
+ | { $$ = 0; }
+ ;
+
+modulelist:
+ '(' modulename ')'
+ { $$ = $2; }
+ |
+ { $$ = 0; }
+ ;
+
+modulename:
+ modulename optcomma FILENAME
+ { struct list *n = (struct list *) malloc(sizeof(struct list));
+ n->next = $1;
+ n->name = $3;
+ $$ = n;
+ }
+ | { $$ = 0; }
+ ;
+
+
+optcomma:
+ ','
+ |
+ ;
+
+
+verbose_command:
+ VERBOSE
+ { verbose = !verbose; }
+ ;
+
+
+%%
+
+static int
+yyerror (x)
+ const char *x;
+{
+ extern int linenumber;
+
+ printf (_("Syntax error in archive script, line %d\n"), linenumber + 1);
+ return 0;
+}
diff --git a/binutils/arsup.c b/binutils/arsup.c
new file mode 100644
index 00000000000..38fd6953c89
--- /dev/null
+++ b/binutils/arsup.c
@@ -0,0 +1,456 @@
+/* arsup.c - Archive support for MRI compatibility
+ Copyright (C) 1992, 93, 94, 95, 96, 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* Contributed by Steve Chamberlain
+ sac@cygnus.com
+
+This file looks after requests from arparse.y, to provide the MRI
+style librarian command syntax + 1 word LIST
+
+*/
+
+#include "bfd.h"
+#include "arsup.h"
+#include "libiberty.h"
+#include "bucomm.h"
+
+static void map_over_list
+ PARAMS ((bfd *, void (*function) (bfd *, bfd *), struct list *));
+static void ar_directory_doer PARAMS ((bfd *, bfd *));
+static void ar_addlib_doer PARAMS ((bfd *, bfd *));
+
+extern int verbose;
+
+static void
+map_over_list (arch, function, list)
+ bfd *arch;
+ void (*function) PARAMS ((bfd *, bfd *));
+ struct list *list;
+{
+ bfd *head;
+
+ if (list == NULL)
+ {
+ bfd *next;
+
+ head = arch->next;
+ while (head != NULL)
+ {
+ next = head->next;
+ function (head, (bfd *) NULL);
+ head = next;
+ }
+ }
+ else
+ {
+ struct list *ptr;
+
+ /* This may appear to be a baroque way of accomplishing what we
+ want. however we have to iterate over the filenames in order
+ to notice where a filename is requested but does not exist in
+ the archive. Ditto mapping over each file each time -- we
+ want to hack multiple references. */
+ for (ptr = list; ptr; ptr = ptr->next)
+ {
+ boolean found = false;
+ bfd *prev = arch;
+
+ for (head = arch->next; head; head = head->next)
+ {
+ if (head->filename != NULL
+ && strcmp (ptr->name, head->filename) == 0)
+ {
+ found = true;
+ function (head, prev);
+ }
+ prev = head;
+ }
+ if (! found)
+ fprintf (stderr, _("No entry %s in archive.\n"), ptr->name);
+ }
+ }
+}
+
+
+FILE *outfile;
+
+/*ARGSUSED*/
+static void
+ar_directory_doer (abfd, ignore)
+ bfd *abfd;
+ bfd *ignore;
+{
+ print_arelt_descr(outfile, abfd, verbose);
+}
+
+void
+ar_directory (ar_name, list, output)
+ char *ar_name;
+ struct list *list;
+ char *output;
+{
+ bfd *arch;
+
+ arch = open_inarch (ar_name, (char *) NULL);
+ if (output)
+ {
+ outfile = fopen(output,"w");
+ if (outfile == 0)
+ {
+ outfile = stdout;
+ fprintf (stderr,_("Can't open file %s\n"), output);
+ output = 0;
+ }
+ }
+ else
+ outfile = stdout;
+
+ map_over_list (arch, ar_directory_doer, list);
+
+ bfd_close (arch);
+
+ if (output)
+ fclose (outfile);
+}
+
+void
+DEFUN_VOID(prompt)
+{
+ extern int interactive;
+ if (interactive)
+ {
+ printf("AR >");
+ fflush(stdout);
+ }
+}
+
+void
+maybequit ()
+{
+ if (! interactive)
+ xexit (9);
+}
+
+
+bfd *obfd;
+char *real_name ;
+void
+DEFUN(ar_open,(name, t),
+ char *name AND
+ int t)
+
+{
+ char *tname = (char *) xmalloc (strlen (name) + 10);
+ real_name = name;
+ sprintf(tname, "%s-tmp", name);
+ obfd = bfd_openw(tname, NULL);
+
+ if (!obfd) {
+ fprintf(stderr,_("%s: Can't open output archive %s\n"), program_name,
+ tname);
+
+ maybequit();
+ }
+ else {
+ if (!t) {
+ bfd **ptr;
+ bfd *element;
+ bfd *ibfd;
+ ibfd = bfd_openr(name, NULL);
+ if (!ibfd) {
+ fprintf(stderr,_("%s: Can't open input archive %s\n"),
+ program_name, name);
+ maybequit();
+ return;
+ }
+ if (bfd_check_format(ibfd, bfd_archive) != true) {
+ fprintf(stderr,_("%s: file %s is not an archive\n"), program_name,
+ name);
+ maybequit();
+ return;
+ }
+ ptr = &(obfd->archive_head);
+ element = bfd_openr_next_archived_file(ibfd, NULL);
+
+ while (element) {
+ *ptr = element;
+ ptr = &element->next;
+ element = bfd_openr_next_archived_file(ibfd, element);
+ }
+ }
+
+ bfd_set_format(obfd, bfd_archive);
+
+ obfd->has_armap = 1;
+ }
+}
+
+
+static void
+ar_addlib_doer (abfd, prev)
+ bfd *abfd;
+ bfd *prev;
+{
+ /* Add this module to the output bfd */
+ if (prev != NULL)
+ prev->next = abfd->next;
+ abfd->next = obfd->archive_head;
+ obfd->archive_head = abfd;
+}
+
+void
+ar_addlib (name, list)
+ char *name;
+ struct list *list;
+{
+ if (obfd == NULL)
+ {
+ fprintf (stderr, _("%s: no output archive specified yet\n"), program_name);
+ maybequit ();
+ }
+ else
+ {
+ bfd *arch;
+
+ arch = open_inarch (name, (char *) NULL);
+ if (arch != NULL)
+ map_over_list (arch, ar_addlib_doer, list);
+
+ /* Don't close the bfd, since it will make the elements disasppear */
+ }
+}
+
+void
+DEFUN(ar_addmod, (list),
+ struct list *list)
+{
+ if (!obfd) {
+ fprintf(stderr, _("%s: no open output archive\n"), program_name);
+ maybequit();
+ }
+ else
+ {
+ while (list) {
+ bfd *abfd = bfd_openr(list->name, NULL);
+ if (!abfd) {
+ fprintf(stderr,_("%s: can't open file %s\n"), program_name,
+ list->name);
+ maybequit();
+ }
+ else {
+ abfd->next = obfd->archive_head;
+ obfd->archive_head = abfd;
+ }
+ list = list->next;
+ }
+ }
+}
+
+
+
+void
+DEFUN_VOID(ar_clear)
+{
+if (obfd)
+ obfd->archive_head = 0;
+}
+
+void
+DEFUN(ar_delete, (list),
+ struct list *list)
+{
+ if (!obfd) {
+ fprintf(stderr, _("%s: no open output archive\n"), program_name);
+ maybequit();
+ }
+ else
+ {
+ while (list) {
+ /* Find this name in the archive */
+ bfd *member = obfd->archive_head;
+ bfd **prev = &(obfd->archive_head);
+ int found = 0;
+ while (member) {
+ if (strcmp(member->filename, list->name) == 0) {
+ *prev = member->next;
+ found = 1;
+ }
+ else {
+ prev = &(member->next);
+ }
+ member = member->next;
+ }
+ if (!found) {
+ fprintf(stderr,_("%s: can't find module file %s\n"), program_name,
+ list->name);
+ maybequit();
+ }
+ list = list->next;
+ }
+ }
+}
+
+
+void
+DEFUN_VOID(ar_save)
+{
+
+ if (!obfd) {
+ fprintf(stderr, _("%s: no open output archive\n"), program_name);
+ maybequit();
+ }
+ else {
+ char *ofilename = xstrdup (bfd_get_filename (obfd));
+ bfd_close(obfd);
+
+ rename (ofilename, real_name);
+ obfd = 0;
+ free(ofilename);
+ }
+}
+
+
+
+void
+DEFUN(ar_replace, (list),
+ struct list *list)
+{
+ if (!obfd) {
+ fprintf(stderr, _("%s: no open output archive\n"), program_name);
+ maybequit();
+ }
+ else
+ {
+ while (list) {
+ /* Find this name in the archive */
+ bfd *member = obfd->archive_head;
+ bfd **prev = &(obfd->archive_head);
+ int found = 0;
+ while (member)
+ {
+ if (strcmp(member->filename, list->name) == 0)
+ {
+ /* Found the one to replace */
+ bfd *abfd = bfd_openr(list->name, 0);
+ if (!abfd)
+ {
+ fprintf(stderr, _("%s: can't open file %s\n"), program_name, list->name);
+ maybequit();
+ }
+ else {
+ *prev = abfd;
+ abfd->next = member->next;
+ found = 1;
+ }
+ }
+ else {
+ prev = &(member->next);
+ }
+ member = member->next;
+ }
+ if (!found) {
+ bfd *abfd = bfd_openr(list->name, 0);
+ fprintf(stderr,_("%s: can't find module file %s\n"), program_name,
+ list->name);
+ if (!abfd)
+ {
+ fprintf(stderr, _("%s: can't open file %s\n"), program_name, list->name);
+ maybequit();
+ }
+ else
+ {
+ *prev = abfd;
+ }
+ }
+
+ list = list->next;
+ }
+ }
+}
+
+/* And I added this one */
+void
+DEFUN_VOID(ar_list)
+{
+ if (!obfd)
+ {
+ fprintf(stderr, _("%s: no open output archive\n"), program_name);
+ maybequit();
+ }
+ else {
+ bfd *abfd;
+ outfile = stdout;
+ verbose =1 ;
+ printf(_("Current open archive is %s\n"), bfd_get_filename (obfd));
+ for (abfd = obfd->archive_head;
+ abfd != (bfd *)NULL;
+ abfd = abfd->next)
+ {
+ ar_directory_doer (abfd, (bfd *) NULL);
+ }
+ }
+}
+
+
+void
+DEFUN_VOID(ar_end)
+{
+ if (obfd)
+ {
+ fclose((FILE *)(obfd->iostream));
+ unlink(bfd_get_filename (obfd));
+ }
+}
+void
+DEFUN(ar_extract,(list),
+ struct list *list)
+{
+ if (!obfd)
+ {
+
+ fprintf(stderr, _("%s: no open archive\n"), program_name);
+ maybequit();
+ }
+ else
+ {
+ while (list) {
+ /* Find this name in the archive */
+ bfd *member = obfd->archive_head;
+ int found = 0;
+ while (member && !found)
+ {
+ if (strcmp(member->filename, list->name) == 0)
+ {
+ extract_file(member);
+ found = 1;
+ }
+
+ member = member->next;
+ }
+ if (!found) {
+ bfd_openr(list->name, 0);
+ fprintf(stderr,_("%s: can't find module file %s\n"), program_name,
+ list->name);
+
+ }
+ list = list->next;
+ }
+ }
+}
diff --git a/binutils/arsup.h b/binutils/arsup.h
new file mode 100644
index 00000000000..f54a34bcf35
--- /dev/null
+++ b/binutils/arsup.h
@@ -0,0 +1,75 @@
+/* arsup.h - archive support header file
+ Copyright 1992 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+struct list {
+ char *name;
+ struct list *next;
+};
+
+void
+maybequit PARAMS ((void));
+
+void
+prompt PARAMS ((void));
+
+void
+ar_clear PARAMS ((void));
+
+void
+ar_replace PARAMS ((struct list *));
+
+void
+ar_delete PARAMS ((struct list *));
+
+void
+ar_save PARAMS ((void));
+
+void
+ar_list PARAMS ((void));
+
+void
+ar_open PARAMS ((char *, int));
+
+void
+ar_directory PARAMS ((char *, struct list *, char *));
+
+void
+ar_addmod PARAMS ((struct list *));
+
+void
+ar_addlib PARAMS ((char *, struct list *));
+
+void
+ar_end PARAMS ((void));
+
+void
+ar_extract PARAMS ((struct list *));
+
+bfd *
+open_inarch PARAMS ((const char *archive_filename, const char *));
+
+int
+yyparse PARAMS ((void));
+
+/* Functions from ar.c */
+
+void
+extract_file PARAMS ((bfd * abfd));
+
+extern int interactive;
diff --git a/binutils/binutils.texi b/binutils/binutils.texi
new file mode 100644
index 00000000000..5f7c646b275
--- /dev/null
+++ b/binutils/binutils.texi
@@ -0,0 +1,2904 @@
+\input texinfo @c -*- Texinfo -*-
+@setfilename binutils.info
+@include config.texi
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Binutils: (binutils). The GNU binary utilities "ar", "objcopy",
+ "objdump", "nm", "nlmconv", "size", "readelf"
+ "strings", "strip", "ranlib" and "dlltool".
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@synindex ky cp
+@c
+@c This file documents the GNU binary utilities "ar", "ld", "objcopy",
+@c "objdump", "nm", "size", "strings", "strip", "readelf" and "ranlib".
+@c
+@c Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+@c
+@c This text may be freely distributed under the terms of the GNU
+@c General Public License.
+@c
+
+@setchapternewpage odd
+@settitle @sc{gnu} Binary Utilities
+@titlepage
+@finalout
+@title The @sc{gnu} Binary Utilities
+@subtitle Version @value{VERSION}
+@sp 1
+@subtitle May 1993
+@author Roland H. Pesch
+@author Jeffrey M. Osier
+@author Cygnus Support
+@page
+
+@tex
+{\parskip=0pt \hfill Cygnus Support\par \hfill
+\TeX{}info \texinfoversion\par }
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+
+@node Top
+@top Introduction
+
+@cindex version
+This brief manual contains preliminary documentation for the @sc{gnu} binary
+utilities (collectively version @value{VERSION}):
+
+@iftex
+@table @code
+@item ar
+Create, modify, and extract from archives
+
+@item nm
+List symbols from object files
+
+@item objcopy
+Copy and translate object files
+
+@item objdump
+Display information from object files
+
+@item ranlib
+Generate index to archive contents
+
+@item readelf
+Display the contents of ELF format files.
+
+@item size
+List file section sizes and total size
+
+@item strings
+List printable strings from files
+
+@item strip
+Discard symbols
+
+@item c++filt
+Demangle encoded C++ symbols
+
+@item addr2line
+Convert addresses into file names and line numbers
+
+@item nlmconv
+Convert object code into a Netware Loadable Module
+
+@item windres
+Manipulate Windows resources
+
+@item dlltool
+Create the files needed to build and use Dynamic Link Libraries
+@end table
+@end iftex
+
+@menu
+* ar:: Create, modify, and extract from archives
+* nm:: List symbols from object files
+* objcopy:: Copy and translate object files
+* objdump:: Display information from object files
+* ranlib:: Generate index to archive contents
+* readelf:: Display the contents of ELF format files.
+* size:: List section sizes and total size
+* strings:: List printable strings from files
+* strip:: Discard symbols
+* c++filt:: Filter to demangle encoded C++ symbols
+* addr2line:: Convert addresses to file and line
+* nlmconv:: Converts object code into an NLM
+* windres:: Manipulate Windows resources
+* dlltool:: Create files needed to build and use DLLs
+* Selecting The Target System:: How these utilities determine the target.
+* Reporting Bugs:: Reporting Bugs
+* Index:: Index
+@end menu
+
+@node ar
+@chapter ar
+
+@kindex ar
+@cindex archives
+@cindex collections of files
+@smallexample
+ar [-]@var{p}[@var{mod} [@var{relpos}]] @var{archive} [@var{member}@dots{}]
+ar -M [ <mri-script ]
+@end smallexample
+
+The @sc{gnu} @code{ar} program creates, modifies, and extracts from
+archives. An @dfn{archive} is a single file holding a collection of
+other files in a structure that makes it possible to retrieve
+the original individual files (called @dfn{members} of the archive).
+
+The original files' contents, mode (permissions), timestamp, owner, and
+group are preserved in the archive, and can be restored on
+extraction.
+
+@cindex name length
+@sc{gnu} @code{ar} can maintain archives whose members have names of any
+length; however, depending on how @code{ar} is configured on your
+system, a limit on member-name length may be imposed for compatibility
+with archive formats maintained with other tools. If it exists, the
+limit is often 15 characters (typical of formats related to a.out) or 16
+characters (typical of formats related to coff).
+
+@cindex libraries
+@code{ar} is considered a binary utility because archives of this sort
+are most often used as @dfn{libraries} holding commonly needed
+subroutines.
+
+@cindex symbol index
+@code{ar} creates an index to the symbols defined in relocatable
+object modules in the archive when you specify the modifier @samp{s}.
+Once created, this index is updated in the archive whenever @code{ar}
+makes a change to its contents (save for the @samp{q} update operation).
+An archive with such an index speeds up linking to the library, and
+allows routines in the library to call each other without regard to
+their placement in the archive.
+
+You may use @samp{nm -s} or @samp{nm --print-armap} to list this index
+table. If an archive lacks the table, another form of @code{ar} called
+@code{ranlib} can be used to add just the table.
+
+@cindex compatibility, @code{ar}
+@cindex @code{ar} compatibility
+@sc{gnu} @code{ar} is designed to be compatible with two different
+facilities. You can control its activity using command-line options,
+like the different varieties of @code{ar} on Unix systems; or, if you
+specify the single command-line option @samp{-M}, you can control it
+with a script supplied via standard input, like the MRI ``librarian''
+program.
+
+@menu
+* ar cmdline:: Controlling @code{ar} on the command line
+* ar scripts:: Controlling @code{ar} with a script
+@end menu
+
+@page
+@node ar cmdline
+@section Controlling @code{ar} on the command line
+
+@smallexample
+ar [-]@var{p}[@var{mod} [@var{relpos}]] @var{archive} [@var{member}@dots{}]
+@end smallexample
+
+@cindex Unix compatibility, @code{ar}
+When you use @code{ar} in the Unix style, @code{ar} insists on at least two
+arguments to execute: one keyletter specifying the @emph{operation}
+(optionally accompanied by other keyletters specifying
+@emph{modifiers}), and the archive name to act on.
+
+Most operations can also accept further @var{member} arguments,
+specifying particular files to operate on.
+
+@sc{gnu} @code{ar} allows you to mix the operation code @var{p} and modifier
+flags @var{mod} in any order, within the first command-line argument.
+
+If you wish, you may begin the first command-line argument with a
+dash.
+
+@cindex operations on archive
+The @var{p} keyletter specifies what operation to execute; it may be
+any of the following, but you must specify only one of them:
+
+@table @code
+@item d
+@cindex deleting from archive
+@emph{Delete} modules from the archive. Specify the names of modules to
+be deleted as @var{member}@dots{}; the archive is untouched if you
+specify no files to delete.
+
+If you specify the @samp{v} modifier, @code{ar} lists each module
+as it is deleted.
+
+@item m
+@cindex moving in archive
+Use this operation to @emph{move} members in an archive.
+
+The ordering of members in an archive can make a difference in how
+programs are linked using the library, if a symbol is defined in more
+than one member.
+
+If no modifiers are used with @code{m}, any members you name in the
+@var{member} arguments are moved to the @emph{end} of the archive;
+you can use the @samp{a}, @samp{b}, or @samp{i} modifiers to move them to a
+specified place instead.
+
+@item p
+@cindex printing from archive
+@emph{Print} the specified members of the archive, to the standard
+output file. If the @samp{v} modifier is specified, show the member
+name before copying its contents to standard output.
+
+If you specify no @var{member} arguments, all the files in the archive are
+printed.
+
+@item q
+@cindex quick append to archive
+@emph{Quick append}; Historically, add the files @var{member}@dots{} to the end of
+@var{archive}, without checking for replacement.
+
+The modifiers @samp{a}, @samp{b}, and @samp{i} do @emph{not} affect this
+operation; new members are always placed at the end of the archive.
+
+The modifier @samp{v} makes @code{ar} list each file as it is appended.
+
+Since the point of this operation is speed, the archive's symbol table
+index is not updated, even if it already existed; you can use @samp{ar s} or
+@code{ranlib} explicitly to update the symbol table index.
+
+However, too many different systems assume quick append rebuilds the
+index, so GNU ar implements @code{q} as a synonym for @code{r}.
+
+@item r
+@cindex replacement in archive
+Insert the files @var{member}@dots{} into @var{archive} (with
+@emph{replacement}). This operation differs from @samp{q} in that any
+previously existing members are deleted if their names match those being
+added.
+
+If one of the files named in @var{member}@dots{} does not exist, @code{ar}
+displays an error message, and leaves undisturbed any existing members
+of the archive matching that name.
+
+By default, new members are added at the end of the file; but you may
+use one of the modifiers @samp{a}, @samp{b}, or @samp{i} to request
+placement relative to some existing member.
+
+The modifier @samp{v} used with this operation elicits a line of
+output for each file inserted, along with one of the letters @samp{a} or
+@samp{r} to indicate whether the file was appended (no old member
+deleted) or replaced.
+
+@item t
+@cindex contents of archive
+Display a @emph{table} listing the contents of @var{archive}, or those
+of the files listed in @var{member}@dots{} that are present in the
+archive. Normally only the member name is shown; if you also want to
+see the modes (permissions), timestamp, owner, group, and size, you can
+request that by also specifying the @samp{v} modifier.
+
+If you do not specify a @var{member}, all files in the archive
+are listed.
+
+@cindex repeated names in archive
+@cindex name duplication in archive
+If there is more than one file with the same name (say, @samp{fie}) in
+an archive (say @samp{b.a}), @samp{ar t b.a fie} lists only the
+first instance; to see them all, you must ask for a complete
+listing---in our example, @samp{ar t b.a}.
+@c WRS only; per Gumby, this is implementation-dependent, and in a more
+@c recent case in fact works the other way.
+
+@item x
+@cindex extract from archive
+@emph{Extract} members (named @var{member}) from the archive. You can
+use the @samp{v} modifier with this operation, to request that
+@code{ar} list each name as it extracts it.
+
+If you do not specify a @var{member}, all files in the archive
+are extracted.
+
+@end table
+
+A number of modifiers (@var{mod}) may immediately follow the @var{p}
+keyletter, to specify variations on an operation's behavior:
+
+@table @code
+@item a
+@cindex relative placement in archive
+Add new files @emph{after} an existing member of the
+archive. If you use the modifier @samp{a}, the name of an existing archive
+member must be present as the @var{relpos} argument, before the
+@var{archive} specification.
+
+@item b
+Add new files @emph{before} an existing member of the
+archive. If you use the modifier @samp{b}, the name of an existing archive
+member must be present as the @var{relpos} argument, before the
+@var{archive} specification. (same as @samp{i}).
+
+@item c
+@cindex creating archives
+@emph{Create} the archive. The specified @var{archive} is always
+created if it did not exist, when you request an update. But a warning is
+issued unless you specify in advance that you expect to create it, by
+using this modifier.
+
+@item f
+Truncate names in the archive. @sc{gnu} @code{ar} will normally permit file
+names of any length. This will cause it to create archives which are
+not compatible with the native @code{ar} program on some systems. If
+this is a concern, the @samp{f} modifier may be used to truncate file
+names when putting them in the archive.
+
+@item i
+Insert new files @emph{before} an existing member of the
+archive. If you use the modifier @samp{i}, the name of an existing archive
+member must be present as the @var{relpos} argument, before the
+@var{archive} specification. (same as @samp{b}).
+
+@item l
+This modifier is accepted but not used.
+@c whaffor ar l modifier??? presumably compat; with
+@c what???---doc@@cygnus.com, 25jan91
+
+@item o
+@cindex dates in archive
+Preserve the @emph{original} dates of members when extracting them. If
+you do not specify this modifier, files extracted from the archive
+are stamped with the time of extraction.
+
+@item s
+@cindex writing archive index
+Write an object-file index into the archive, or update an existing one,
+even if no other change is made to the archive. You may use this modifier
+flag either with any operation, or alone. Running @samp{ar s} on an
+archive is equivalent to running @samp{ranlib} on it.
+
+@item S
+@cindex not writing archive index
+Do not generate an archive symbol table. This can speed up building a
+large library in several steps. The resulting archive can not be used
+with the linker. In order to build a symbol table, you must omit the
+@samp{S} modifier on the last execution of @samp{ar}, or you must run
+@samp{ranlib} on the archive.
+
+@item u
+@cindex updating an archive
+Normally, @samp{ar r}@dots{} inserts all files
+listed into the archive. If you would like to insert @emph{only} those
+of the files you list that are newer than existing members of the same
+names, use this modifier. The @samp{u} modifier is allowed only for the
+operation @samp{r} (replace). In particular, the combination @samp{qu} is
+not allowed, since checking the timestamps would lose any speed
+advantage from the operation @samp{q}.
+
+@item v
+This modifier requests the @emph{verbose} version of an operation. Many
+operations display additional information, such as filenames processed,
+when the modifier @samp{v} is appended.
+
+@item V
+This modifier shows the version number of @code{ar}.
+@end table
+
+@node ar scripts
+@section Controlling @code{ar} with a script
+
+@smallexample
+ar -M [ <@var{script} ]
+@end smallexample
+
+@cindex MRI compatibility, @code{ar}
+@cindex scripts, @code{ar}
+If you use the single command-line option @samp{-M} with @code{ar}, you
+can control its operation with a rudimentary command language. This
+form of @code{ar} operates interactively if standard input is coming
+directly from a terminal. During interactive use, @code{ar} prompts for
+input (the prompt is @samp{AR >}), and continues executing even after
+errors. If you redirect standard input to a script file, no prompts are
+issued, and @code{ar} abandons execution (with a nonzero exit code)
+on any error.
+
+The @code{ar} command language is @emph{not} designed to be equivalent
+to the command-line options; in fact, it provides somewhat less control
+over archives. The only purpose of the command language is to ease the
+transition to @sc{gnu} @code{ar} for developers who already have scripts
+written for the MRI ``librarian'' program.
+
+The syntax for the @code{ar} command language is straightforward:
+@itemize @bullet
+@item
+commands are recognized in upper or lower case; for example, @code{LIST}
+is the same as @code{list}. In the following descriptions, commands are
+shown in upper case for clarity.
+
+@item
+a single command may appear on each line; it is the first word on the
+line.
+
+@item
+empty lines are allowed, and have no effect.
+
+@item
+comments are allowed; text after either of the characters @samp{*}
+or @samp{;} is ignored.
+
+@item
+Whenever you use a list of names as part of the argument to an @code{ar}
+command, you can separate the individual names with either commas or
+blanks. Commas are shown in the explanations below, for clarity.
+
+@item
+@samp{+} is used as a line continuation character; if @samp{+} appears
+at the end of a line, the text on the following line is considered part
+of the current command.
+@end itemize
+
+Here are the commands you can use in @code{ar} scripts, or when using
+@code{ar} interactively. Three of them have special significance:
+
+@code{OPEN} or @code{CREATE} specify a @dfn{current archive}, which is
+a temporary file required for most of the other commands.
+
+@code{SAVE} commits the changes so far specified by the script. Prior
+to @code{SAVE}, commands affect only the temporary copy of the current
+archive.
+
+@table @code
+@item ADDLIB @var{archive}
+@itemx ADDLIB @var{archive} (@var{module}, @var{module}, @dots{} @var{module})
+Add all the contents of @var{archive} (or, if specified, each named
+@var{module} from @var{archive}) to the current archive.
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@item ADDMOD @var{member}, @var{member}, @dots{} @var{member}
+@c FIXME! w/Replacement?? If so, like "ar r @var{archive} @var{names}"
+@c else like "ar q..."
+Add each named @var{member} as a module in the current archive.
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@item CLEAR
+Discard the contents of the current archive, canceling the effect of
+any operations since the last @code{SAVE}. May be executed (with no
+effect) even if no current archive is specified.
+
+@item CREATE @var{archive}
+Creates an archive, and makes it the current archive (required for many
+other commands). The new archive is created with a temporary name; it
+is not actually saved as @var{archive} until you use @code{SAVE}.
+You can overwrite existing archives; similarly, the contents of any
+existing file named @var{archive} will not be destroyed until @code{SAVE}.
+
+@item DELETE @var{module}, @var{module}, @dots{} @var{module}
+Delete each listed @var{module} from the current archive; equivalent to
+@samp{ar -d @var{archive} @var{module} @dots{} @var{module}}.
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@item DIRECTORY @var{archive} (@var{module}, @dots{} @var{module})
+@itemx DIRECTORY @var{archive} (@var{module}, @dots{} @var{module}) @var{outputfile}
+List each named @var{module} present in @var{archive}. The separate
+command @code{VERBOSE} specifies the form of the output: when verbose
+output is off, output is like that of @samp{ar -t @var{archive}
+@var{module}@dots{}}. When verbose output is on, the listing is like
+@samp{ar -tv @var{archive} @var{module}@dots{}}.
+
+Output normally goes to the standard output stream; however, if you
+specify @var{outputfile} as a final argument, @code{ar} directs the
+output to that file.
+
+@item END
+Exit from @code{ar}, with a @code{0} exit code to indicate successful
+completion. This command does not save the output file; if you have
+changed the current archive since the last @code{SAVE} command, those
+changes are lost.
+
+@item EXTRACT @var{module}, @var{module}, @dots{} @var{module}
+Extract each named @var{module} from the current archive, writing them
+into the current directory as separate files. Equivalent to @samp{ar -x
+@var{archive} @var{module}@dots{}}.
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@ignore
+@c FIXME Tokens but no commands???
+@item FULLDIR
+
+@item HELP
+@end ignore
+
+@item LIST
+Display full contents of the current archive, in ``verbose'' style
+regardless of the state of @code{VERBOSE}. The effect is like @samp{ar
+tv @var{archive}}). (This single command is a @sc{gnu} @code{ld}
+enhancement, rather than present for MRI compatibility.)
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@item OPEN @var{archive}
+Opens an existing archive for use as the current archive (required for
+many other commands). Any changes as the result of subsequent commands
+will not actually affect @var{archive} until you next use @code{SAVE}.
+
+@item REPLACE @var{module}, @var{module}, @dots{} @var{module}
+In the current archive, replace each existing @var{module} (named in
+the @code{REPLACE} arguments) from files in the current working directory.
+To execute this command without errors, both the file, and the module in
+the current archive, must exist.
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@item VERBOSE
+Toggle an internal flag governing the output from @code{DIRECTORY}.
+When the flag is on, @code{DIRECTORY} output matches output from
+@samp{ar -tv }@dots{}.
+
+@item SAVE
+Commit your changes to the current archive, and actually save it as a
+file with the name specified in the last @code{CREATE} or @code{OPEN}
+command.
+
+Requires prior use of @code{OPEN} or @code{CREATE}.
+
+@end table
+
+@iftex
+@node ld
+@chapter ld
+@cindex linker
+@kindex ld
+The @sc{gnu} linker @code{ld} is now described in a separate manual.
+@xref{Top,, Overview,, Using LD: the @sc{gnu} linker}.
+@end iftex
+
+@node nm
+@chapter nm
+@cindex symbols
+@kindex nm
+
+@smallexample
+nm [ -a | --debug-syms ] [ -g | --extern-only ]
+ [ -B ] [ -C | --demangle ] [ -D | --dynamic ]
+ [ -s | --print-armap ] [ -A | -o | --print-file-name ]
+ [ -n | -v | --numeric-sort ] [ -p | --no-sort ]
+ [ -r | --reverse-sort ] [ --size-sort ] [ -u | --undefined-only ]
+ [ -t @var{radix} | --radix=@var{radix} ] [ -P | --portability ]
+ [ --target=@var{bfdname} ] [ -f @var{format} | --format=@var{format} ]
+ [ --defined-only ] [-l | --line-numbers ]
+ [ --no-demangle ] [ -V | --version ] [ --help ] [ @var{objfile}@dots{} ]
+@end smallexample
+
+@sc{gnu} @code{nm} lists the symbols from object files @var{objfile}@dots{}.
+If no object files are listed as arguments, @code{nm} assumes
+@file{a.out}.
+
+For each symbol, @code{nm} shows:
+
+@itemize @bullet
+@item
+The symbol value, in the radix selected by options (see below), or
+hexadecimal by default.
+
+@item
+The symbol type. At least the following types are used; others are, as
+well, depending on the object file format. If lowercase, the symbol is
+local; if uppercase, the symbol is global (external).
+
+@c Some more detail on exactly what these symbol types are used for
+@c would be nice.
+@table @code
+@item A
+The symbol's value is absolute, and will not be changed by further
+linking.
+
+@item B
+The symbol is in the uninitialized data section (known as BSS).
+
+@item C
+The symbol is common. Common symbols are uninitialized data. When
+linking, multiple common symbols may appear with the same name. If the
+symbol is defined anywhere, the common symbols are treated as undefined
+references. For more details on common symbols, see the discussion of
+--warn-common in @ref{Options,,Linker options,ld.info,The GNU linker}.
+
+@item D
+The symbol is in the initialized data section.
+
+@item G
+The symbol is in an initialized data section for small objects. Some
+object file formats permit more efficient access to small data objects,
+such as a global int variable as opposed to a large global array.
+
+@item I
+The symbol is an indirect reference to another symbol. This is a GNU
+extension to the a.out object file format which is rarely used.
+
+@item N
+The symbol is a debugging symbol.
+
+@item R
+The symbol is in a read only data section.
+
+@item S
+The symbol is in an uninitialized data section for small objects.
+
+@item T
+The symbol is in the text (code) section.
+
+@item U
+The symbol is undefined.
+
+@item W
+The symbol is weak. When a weak defined symbol is linked with a normal
+defined symbol, the normal defined symbol is used with no error. When a
+weak undefined symbol is linked and the symbol is not defined, the value
+of the weak symbol becomes zero with no error.
+
+@item -
+The symbol is a stabs symbol in an a.out object file. In this case, the
+next values printed are the stabs other field, the stabs desc field, and
+the stab type. Stabs symbols are used to hold debugging information;
+for more information, see @ref{Top,Stabs,Stabs Overview,stabs.info, The
+``stabs'' debug format}.
+
+@item ?
+The symbol type is unknown, or object file format specific.
+@end table
+
+@item
+The symbol name.
+@end itemize
+
+The long and short forms of options, shown here as alternatives, are
+equivalent.
+
+@table @code
+@item -A
+@itemx -o
+@itemx --print-file-name
+@cindex input file name
+@cindex file name
+@cindex source file name
+Precede each symbol by the name of the input file (or archive element)
+in which it was found, rather than identifying the input file once only,
+before all of its symbols.
+
+@item -a
+@itemx --debug-syms
+@cindex debugging symbols
+Display all symbols, even debugger-only symbols; normally these are not
+listed.
+
+@item -B
+@cindex @code{nm} format
+@cindex @code{nm} compatibility
+The same as @samp{--format=bsd} (for compatibility with the MIPS @code{nm}).
+
+@item -C
+@itemx --demangle
+@cindex demangling in nm
+Decode (@dfn{demangle}) low-level symbol names into user-level names.
+Besides removing any initial underscore prepended by the system, this
+makes C++ function names readable. @xref{c++filt}, for more information
+on demangling.
+
+@item --no-demangle
+Do not demangle low-level symbol names. This is the default.
+
+@item -D
+@itemx --dynamic
+@cindex dynamic symbols
+Display the dynamic symbols rather than the normal symbols. This is
+only meaningful for dynamic objects, such as certain types of shared
+libraries.
+
+@item -f @var{format}
+@itemx --format=@var{format}
+@cindex @code{nm} format
+@cindex @code{nm} compatibility
+Use the output format @var{format}, which can be @code{bsd},
+@code{sysv}, or @code{posix}. The default is @code{bsd}.
+Only the first character of @var{format} is significant; it can be
+either upper or lower case.
+
+@item -g
+@itemx --extern-only
+@cindex external symbols
+Display only external symbols.
+
+@item -l
+@itemx --line-numbers
+@cindex symbol line numbers
+For each symbol, use debugging information to try to find a filename and
+line number. For a defined symbol, look for the line number of the
+address of the symbol. For an undefined symbol, look for the line
+number of a relocation entry which refers to the symbol. If line number
+information can be found, print it after the other symbol information.
+
+@item -n
+@itemx -v
+@itemx --numeric-sort
+Sort symbols numerically by their addresses, rather than alphabetically
+by their names.
+
+@item -p
+@itemx --no-sort
+@cindex sorting symbols
+Do not bother to sort the symbols in any order; print them in the order
+encountered.
+
+@item -P
+@itemx --portability
+Use the POSIX.2 standard output format instead of the default format.
+Equivalent to @samp{-f posix}.
+
+@item -s
+@itemx --print-armap
+@cindex symbol index, listing
+When listing symbols from archive members, include the index: a mapping
+(stored in the archive by @code{ar} or @code{ranlib}) of which modules
+contain definitions for which names.
+
+@item -r
+@itemx --reverse-sort
+Reverse the order of the sort (whether numeric or alphabetic); let the
+last come first.
+
+@item --size-sort
+Sort symbols by size. The size is computed as the difference between
+the value of the symbol and the value of the symbol with the next higher
+value. The size of the symbol is printed, rather than the value.
+
+@item -t @var{radix}
+@itemx --radix=@var{radix}
+Use @var{radix} as the radix for printing the symbol values. It must be
+@samp{d} for decimal, @samp{o} for octal, or @samp{x} for hexadecimal.
+
+@item --target=@var{bfdname}
+@cindex object code format
+Specify an object code format other than your system's default format.
+@xref{Target Selection}, for more information.
+
+@item -u
+@itemx --undefined-only
+@cindex external symbols
+@cindex undefined symbols
+Display only undefined symbols (those external to each object file).
+
+@item --defined-only
+@cindex external symbols
+@cindex undefined symbols
+Display only defined symbols for each object file.
+
+@item -V
+@itemx --version
+Show the version number of @code{nm} and exit.
+
+@item --help
+Show a summary of the options to @code{nm} and exit.
+@end table
+
+@node objcopy
+@chapter objcopy
+
+@smallexample
+objcopy [ -F @var{bfdname} | --target=@var{bfdname} ]
+ [ -I @var{bfdname} | --input-target=@var{bfdname} ]
+ [ -O @var{bfdname} | --output-target=@var{bfdname} ]
+ [ -S | --strip-all ] [ -g | --strip-debug ]
+ [ -K @var{symbolname} | --keep-symbol=@var{symbolname} ]
+ [ -N @var{symbolname} | --strip-symbol=@var{symbolname} ]
+ [ -L @var{symbolname} | --localize-symbol=@var{symbolname} ]
+ [ -W @var{symbolname} | --weaken-symbol=@var{symbolname} ]
+ [ -x | --discard-all ] [ -X | --discard-locals ]
+ [ -b @var{byte} | --byte=@var{byte} ]
+ [ -i @var{interleave} | --interleave=@var{interleave} ]
+ [ -R @var{sectionname} | --remove-section=@var{sectionname} ]
+ [ -p | --preserve-dates ] [ --debugging ]
+ [ --gap-fill=@var{val} ] [ --pad-to=@var{address} ]
+ [ --set-start=@var{val} ] [ --adjust-start=@var{incr} ]
+ [ --change-addresses=@var{incr} ]
+ [ --change-section-address=@var{section}@{=,+,-@}@var{val} ]
+ [ --change-section-lma=@var{section}@{=,+,-@}@var{val} ]
+ [ --change-section-vma=@var{section}@{=,+,-@}@var{val} ]
+ [ --change-warnings ] [ --no-change-warnings ]
+ [ --set-section-flags=@var{section}=@var{flags} ]
+ [ --add-section=@var{sectionname}=@var{filename} ]
+ [ --change-leading-char ] [ --remove-leading-char ]
+ [ --weaken ]
+ [ -v | --verbose ] [ -V | --version ] [ --help ]
+ @var{infile} [@var{outfile}]
+@end smallexample
+
+The @sc{gnu} @code{objcopy} utility copies the contents of an object
+file to another. @code{objcopy} uses the @sc{gnu} @sc{bfd} Library to
+read and write the object files. It can write the destination object
+file in a format different from that of the source object file. The
+exact behavior of @code{objcopy} is controlled by command-line options.
+
+@code{objcopy} creates temporary files to do its translations and
+deletes them afterward. @code{objcopy} uses @sc{bfd} to do all its
+translation work; it has access to all the formats described in @sc{bfd}
+and thus is able to recognize most formats without being told
+explicitly. @xref{BFD,,BFD,ld.info,Using LD}.
+
+@code{objcopy} can be used to generate S-records by using an output
+target of @samp{srec} (e.g., use @samp{-O srec}).
+
+@code{objcopy} can be used to generate a raw binary file by using an
+output target of @samp{binary} (e.g., use @samp{-O binary}). When
+@code{objcopy} generates a raw binary file, it will essentially produce
+a memory dump of the contents of the input object file. All symbols and
+relocation information will be discarded. The memory dump will start at
+the load address of the lowest section copied into the output file.
+
+When generating an S-record or a raw binary file, it may be helpful to
+use @samp{-S} to remove sections containing debugging information. In
+some cases @samp{-R} will be useful to remove sections which contain
+information which is not needed by the binary file.
+
+@table @code
+@item @var{infile}
+@itemx @var{outfile}
+The source and output files, respectively.
+If you do not specify @var{outfile}, @code{objcopy} creates a
+temporary file and destructively renames the result with
+the name of @var{infile}.
+
+@item -I @var{bfdname}
+@itemx --input-target=@var{bfdname}
+Consider the source file's object format to be @var{bfdname}, rather than
+attempting to deduce it. @xref{Target Selection}, for more information.
+
+@item -O @var{bfdname}
+@itemx --output-target=@var{bfdname}
+Write the output file using the object format @var{bfdname}.
+@xref{Target Selection}, for more information.
+
+@item -F @var{bfdname}
+@itemx --target=@var{bfdname}
+Use @var{bfdname} as the object format for both the input and the output
+file; i.e., simply transfer data from source to destination with no
+translation. @xref{Target Selection}, for more information.
+
+@item -R @var{sectionname}
+@itemx --remove-section=@var{sectionname}
+Remove any section named @var{sectionname} from the output file. This
+option may be given more than once. Note that using this option
+inappropriately may make the output file unusable.
+
+@item -S
+@itemx --strip-all
+Do not copy relocation and symbol information from the source file.
+
+@item -g
+@itemx --strip-debug
+Do not copy debugging symbols from the source file.
+
+@item --strip-unneeded
+Strip all symbols that are not needed for relocation processing.
+
+@item -K @var{symbolname}
+@itemx --keep-symbol=@var{symbolname}
+Copy only symbol @var{symbolname} from the source file. This option may
+be given more than once.
+
+@item -N @var{symbolname}
+@itemx --strip-symbol=@var{symbolname}
+Do not copy symbol @var{symbolname} from the source file. This option
+may be given more than once.
+
+@item -L @var{symbolname}
+@itemx --localize-symbol=@var{symbolname}
+Make symbol @var{symbolname} local to the file, so that it is not
+visible externally. This option may be given more than once.
+
+@item -W @var{symbolname}
+@itemx --weaken-symbol=@var{symbolname}
+Make symbol @var{symbolname} weak. This option may be given more than once.
+
+@item -x
+@itemx --discard-all
+Do not copy non-global symbols from the source file.
+@c FIXME any reason to prefer "non-global" to "local" here?
+
+@item -X
+@itemx --discard-locals
+Do not copy compiler-generated local symbols.
+(These usually start with @samp{L} or @samp{.}.)
+
+@item -b @var{byte}
+@itemx --byte=@var{byte}
+Keep only every @var{byte}th byte of the input file (header data is not
+affected). @var{byte} can be in the range from 0 to @var{interleave}-1,
+where @var{interleave} is given by the @samp{-i} or @samp{--interleave}
+option, or the default of 4. This option is useful for creating files
+to program @sc{rom}. It is typically used with an @code{srec} output
+target.
+
+@item -i @var{interleave}
+@itemx --interleave=@var{interleave}
+Only copy one out of every @var{interleave} bytes. Select which byte to
+copy with the @var{-b} or @samp{--byte} option. The default is 4.
+@code{objcopy} ignores this option if you do not specify either @samp{-b} or
+@samp{--byte}.
+
+@item -p
+@itemx --preserve-dates
+Set the access and modification dates of the output file to be the same
+as those of the input file.
+
+@item --debugging
+Convert debugging information, if possible. This is not the default
+because only certain debugging formats are supported, and the
+conversion process can be time consuming.
+
+@item --gap-fill @var{val}
+Fill gaps between sections with @var{val}. This operation applies to
+the @emph{load address} (LMA) of the sections. It is done by increasing
+the size of the section with the lower address, and filling in the extra
+space created with @var{val}.
+
+@item --pad-to @var{address}
+Pad the output file up to the load address @var{address}. This is
+done by increasing the size of the last section. The extra space is
+filled in with the value specified by @samp{--gap-fill} (default zero).
+
+@item --set-start @var{val}
+Set the address of the new file to @var{val}. Not all object file
+formats support setting the start address.
+
+@item --change-start @var{incr}
+@itemx --adjust-start @var{incr}
+@cindex changing start address
+Change the start address by adding @var{incr}. Not all object file
+formats support setting the start address.
+
+@item --change-addresses @var{incr}
+@itemx --adjust-vma @var{incr}
+@cindex changing object addresses
+Change the VMA and LMA addresses of all sections, as well as the start
+address, by adding @var{incr}. Some object file formats do not permit
+section addresses to be changed arbitrarily. Note that this does not
+relocate the sections; if the program expects sections to be loaded at a
+certain address, and this option is used to change the sections such
+that they are loaded at a different address, the program may fail.
+
+@item --change-section-address @var{section}@{=,+,-@}@var{val}
+@itemx --adjust-section-vma @var{section}@{=,+,-@}@var{val}
+@cindex changing section address
+Set or change both the VMA address and the LMA address of the named
+@var{section}. If @samp{=} is used, the section address is set to
+@var{val}. Otherwise, @var{val} is added to or subtracted from the
+section address. See the comments under @samp{--change-addresses},
+above. If @var{section} does not exist in the input file, a warning will
+be issued, unless @samp{--no-change-warnings} is used.
+
+@item --change-section-lma @var{section}@{=,+,-@}@var{val}
+@cindex changing section LMA
+Set or change the LMA address of the named @var{section}. The LMA
+address is the address where the section will be loaded into memory at
+program load time. Normally this is the same as the VMA address, which
+is the address of the section at program run time, but on some systems,
+especially those where a program is held in ROM, the two can be
+different. If @samp{=} is used, the section address is set to
+@var{val}. Otherwise, @var{val} is added to or subtracted from the
+section address. See the comments under @samp{--change-addresses},
+above. If @var{section} does not exist in the input file, a warning
+will be issued, unless @samp{--no-change-warnings} is used.
+
+@item --change-section-vma @var{section}@{=,+,-@}@var{val}
+@cindex changing section VMA
+Set or change the VMA address of the named @var{section}. The VMA
+address is the address where the section will be located once the
+program has started executing. Normally this is the same as the LMA
+address, which is the address where the section will be loaded into
+memory, but on some systems, especially those where a program is held in
+ROM, the two can be different. If @samp{=} is used, the section address
+is set to @var{val}. Otherwise, @var{val} is added to or subtracted
+from the section address. See the comments under
+@samp{--change-addresses}, above. If @var{section} does not exist in
+the input file, a warning will be issued, unless
+@samp{--no-change-warnings} is used.
+
+@item --change-warnings
+@itemx --adjust-warnings
+If @samp{--change-section-address} or @samp{--change-section-lma} or
+@samp{--change-section-vma} is used, and the named section does not
+exist, issue a warning. This is the default.
+
+@item --no-change-warnings
+@itemx --no-adjust-warnings
+Do not issue a warning if @samp{--change-section-address} or
+@samp{--adjust-section-lma} or @samp{--adjust-section-vma} is used, even
+if the named section does not exist.
+
+@item --set-section-flags @var{section}=@var{flags}
+Set the flags for the named section. The @var{flags} argument is a
+comma separated string of flag names. The recognized names are
+@samp{alloc}, @samp{contents}, @samp{load}, @samp{readonly},
+@samp{code}, @samp{data}, and @samp{rom}. You can set the
+@samp{contents} flag for a section which does not have contents, but it
+is not meaningful to clear the @samp{contents} flag of a section which
+does have contents--just remove the section instead. Not all flags are
+meaningful for all object file formats.
+
+@item --add-section @var{sectionname}=@var{filename}
+Add a new section named @var{sectionname} while copying the file. The
+contents of the new section are taken from the file @var{filename}. The
+size of the section will be the size of the file. This option only
+works on file formats which can support sections with arbitrary names.
+
+@item --change-leading-char
+Some object file formats use special characters at the start of
+symbols. The most common such character is underscore, which compilers
+often add before every symbol. This option tells @code{objcopy} to
+change the leading character of every symbol when it converts between
+object file formats. If the object file formats use the same leading
+character, this option has no effect. Otherwise, it will add a
+character, or remove a character, or change a character, as
+appropriate.
+
+@item --remove-leading-char
+If the first character of a global symbol is a special symbol leading
+character used by the object file format, remove the character. The
+most common symbol leading character is underscore. This option will
+remove a leading underscore from all global symbols. This can be useful
+if you want to link together objects of different file formats with
+different conventions for symbol names. This is different from
+@code{--change-leading-char} because it always changes the symbol name
+when appropriate, regardless of the object file format of the output
+file.
+
+@item --weaken
+Change all global symbols in the file to be weak. This can be useful
+when building an object which will be linked against other objects using
+the @code{-R} option to the linker. This option is only effective when
+using an object file format which supports weak symbols.
+
+@item -V
+@itemx --version
+Show the version number of @code{objcopy}.
+
+@item -v
+@itemx --verbose
+Verbose output: list all object files modified. In the case of
+archives, @samp{objcopy -V} lists all members of the archive.
+
+@item --help
+Show a summary of the options to @code{objcopy}.
+@end table
+
+@node objdump
+@chapter objdump
+
+@cindex object file information
+@kindex objdump
+
+@smallexample
+objdump [ -a | --archive-headers ]
+ [ -b @var{bfdname} | --target=@var{bfdname} ] [ --debugging ]
+ [ -C | --demangle ] [ -d | --disassemble ]
+ [ -D | --disassemble-all ] [ --disassemble-zeroes ]
+ [ -EB | -EL | --endian=@{big | little @} ]
+ [ -f | --file-headers ]
+ [ -h | --section-headers | --headers ] [ -i | --info ]
+ [ -j @var{section} | --section=@var{section} ]
+ [ -l | --line-numbers ] [ -S | --source ]
+ [ -m @var{machine} | --architecture=@var{machine} ]
+ [ -p | --private-headers ]
+ [ -r | --reloc ] [ -R | --dynamic-reloc ]
+ [ -s | --full-contents ] [ --stabs ]
+ [ -t | --syms ] [ -T | --dynamic-syms ] [ -x | --all-headers ]
+ [ -w | --wide ] [ --start-address=@var{address} ]
+ [ --stop-address=@var{address} ]
+ [ --prefix-addresses] [ --[no-]show-raw-insn ]
+ [ --adjust-vma=@var{offset} ]
+ [ --version ] [ --help ]
+ @var{objfile}@dots{}
+@end smallexample
+
+@code{objdump} displays information about one or more object files.
+The options control what particular information to display. This
+information is mostly useful to programmers who are working on the
+compilation tools, as opposed to programmers who just want their
+program to compile and work.
+
+@var{objfile}@dots{} are the object files to be examined. When you
+specify archives, @code{objdump} shows information on each of the member
+object files.
+
+The long and short forms of options, shown here as alternatives, are
+equivalent. At least one option besides @samp{-l} must be given.
+
+@table @code
+@item -a
+@itemx --archive-header
+@cindex archive headers
+If any of the @var{objfile} files are archives, display the archive
+header information (in a format similar to @samp{ls -l}). Besides the
+information you could list with @samp{ar tv}, @samp{objdump -a} shows
+the object file format of each archive member.
+
+@item --adjust-vma=@var{offset}
+@cindex section addresses in objdump
+@cindex VMA in objdump
+When dumping information, first add @var{offset} to all the section
+addresses. This is useful if the section addresses do not correspond to
+the symbol table, which can happen when putting sections at particular
+addresses when using a format which can not represent section addresses,
+such as a.out.
+
+@item -b @var{bfdname}
+@itemx --target=@var{bfdname}
+@cindex object code format
+Specify that the object-code format for the object files is
+@var{bfdname}. This option may not be necessary; @var{objdump} can
+automatically recognize many formats.
+
+For example,
+@example
+objdump -b oasys -m vax -h fu.o
+@end example
+@noindent
+displays summary information from the section headers (@samp{-h}) of
+@file{fu.o}, which is explicitly identified (@samp{-m}) as a VAX object
+file in the format produced by Oasys compilers. You can list the
+formats available with the @samp{-i} option.
+@xref{Target Selection}, for more information.
+
+@item -C
+@itemx --demangle
+@cindex demangling in objdump
+Decode (@dfn{demangle}) low-level symbol names into user-level names.
+Besides removing any initial underscore prepended by the system, this
+makes C++ function names readable. @xref{c++filt}, for more information
+on demangling.
+
+@item --debugging
+Display debugging information. This attempts to parse debugging
+information stored in the file and print it out using a C like syntax.
+Only certain types of debugging information have been implemented.
+
+@item -d
+@itemx --disassemble
+@cindex disassembling object code
+@cindex machine instructions
+Display the assembler mnemonics for the machine instructions from
+@var{objfile}. This option only disassembles those sections which are
+expected to contain instructions.
+
+@item -D
+@itemx --disassemble-all
+Like @samp{-d}, but disassemble the contents of all sections, not just
+those expected to contain instructions.
+
+@item --prefix-addresses
+When disassembling, print the complete address on each line. This is
+the older disassembly format.
+
+@item --disassemble-zeroes
+Normally the disassembly output will skip blocks of zeroes. This
+option directs the disassembler to disassemble those blocks, just like
+any other data.
+
+@item -EB
+@itemx -EL
+@itemx --endian=@{big|little@}
+@cindex endianness
+@cindex disassembly endianness
+Specify the endianness of the object files. This only affects
+disassembly. This can be useful when disassembling a file format which
+does not describe endianness information, such as S-records.
+
+@item -f
+@itemx --file-header
+@cindex object file header
+Display summary information from the overall header of
+each of the @var{objfile} files.
+
+@item -h
+@itemx --section-header
+@itemx --header
+@cindex section headers
+Display summary information from the section headers of the
+object file.
+
+File segments may be relocated to nonstandard addresses, for example by
+using the @samp{-Ttext}, @samp{-Tdata}, or @samp{-Tbss} options to
+@code{ld}. However, some object file formats, such as a.out, do not
+store the starting address of the file segments. In those situations,
+although @code{ld} relocates the sections correctly, using @samp{objdump
+-h} to list the file section headers cannot show the correct addresses.
+Instead, it shows the usual addresses, which are implicit for the
+target.
+
+@item --help
+Print a summary of the options to @code{objdump} and exit.
+
+@item -i
+@itemx --info
+@cindex architectures available
+@cindex object formats available
+Display a list showing all architectures and object formats available
+for specification with @samp{-b} or @samp{-m}.
+
+@item -j @var{name}
+@itemx --section=@var{name}
+@cindex section information
+Display information only for section @var{name}.
+
+@item -l
+@itemx --line-numbers
+@cindex source filenames for object files
+Label the display (using debugging information) with the filename and
+source line numbers corresponding to the object code or relocs shown.
+Only useful with @samp{-d}, @samp{-D}, or @samp{-r}.
+
+@item -m @var{machine}
+@itemx --architecture=@var{machine}
+@cindex architecture
+@cindex disassembly architecture
+Specify the architecture to use when disassembling object files. This
+can be useful when disassembling object files which do not describe
+architecture information, such as S-records. You can list the available
+architectures with the @samp{-i} option.
+
+@item -p
+@itemx --private-headers
+Print information that is specific to the object file format. The exact
+information printed depends upon the object file format. For some
+object file formats, no additional information is printed.
+
+@item -r
+@itemx --reloc
+@cindex relocation entries, in object file
+Print the relocation entries of the file. If used with @samp{-d} or
+@samp{-D}, the relocations are printed interspersed with the
+disassembly.
+
+@item -R
+@itemx --dynamic-reloc
+@cindex dynamic relocation entries, in object file
+Print the dynamic relocation entries of the file. This is only
+meaningful for dynamic objects, such as certain types of shared
+libraries.
+
+@item -s
+@itemx --full-contents
+@cindex sections, full contents
+@cindex object file sections
+Display the full contents of any sections requested.
+
+@item -S
+@itemx --source
+@cindex source disassembly
+@cindex disassembly, with source
+Display source code intermixed with disassembly, if possible. Implies
+@samp{-d}.
+
+@item --show-raw-insn
+When disassembling instructions, print the instruction in hex as well as
+in symbolic form. This is the default except when
+@code{--prefix-addresses} is used.
+
+@item --no-show-raw-insn
+When disassembling instructions, do not print the instruction bytes.
+This is the default when @code{--prefix-addresses} is used.
+
+@item --stabs
+@cindex stab
+@cindex .stab
+@cindex debug symbols
+@cindex ELF object file format
+Display the full contents of any sections requested. Display the
+contents of the .stab and .stab.index and .stab.excl sections from an
+ELF file. This is only useful on systems (such as Solaris 2.0) in which
+@code{.stab} debugging symbol-table entries are carried in an ELF
+section. In most other file formats, debugging symbol-table entries are
+interleaved with linkage symbols, and are visible in the @samp{--syms}
+output. For more information on stabs symbols, see @ref{Top,Stabs,Stabs
+Overview,stabs.info, The ``stabs'' debug format}.
+
+@item --start-address=@var{address}
+@cindex start-address
+Start displaying data at the specified address. This affects the output
+of the @code{-d}, @code{-r} and @code{-s} options.
+
+@item --stop-address=@var{address}
+@cindex stop-address
+Stop displaying data at the specified address. This affects the output
+of the @code{-d}, @code{-r} and @code{-s} options.
+
+@item -t
+@itemx --syms
+@cindex symbol table entries, printing
+Print the symbol table entries of the file.
+This is similar to the information provided by the @samp{nm} program.
+
+@item -T
+@itemx --dynamic-syms
+@cindex dynamic symbol table entries, printing
+Print the dynamic symbol table entries of the file. This is only
+meaningful for dynamic objects, such as certain types of shared
+libraries. This is similar to the information provided by the @samp{nm}
+program when given the @samp{-D} (@samp{--dynamic}) option.
+
+@item --version
+Print the version number of @code{objdump} and exit.
+
+@item -x
+@itemx --all-header
+@cindex all header information, object file
+@cindex header information, all
+Display all available header information, including the symbol table and
+relocation entries. Using @samp{-x} is equivalent to specifying all of
+@samp{-a -f -h -r -t}.
+
+@item -w
+@itemx --wide
+@cindex wide output, printing
+Format some lines for output devices that have more than 80 columns.
+@end table
+
+@node ranlib
+@chapter ranlib
+
+@kindex ranlib
+@cindex archive contents
+@cindex symbol index
+
+@smallexample
+ranlib [-vV] @var{archive}
+@end smallexample
+
+@code{ranlib} generates an index to the contents of an archive and
+stores it in the archive. The index lists each symbol defined by a
+member of an archive that is a relocatable object file.
+
+You may use @samp{nm -s} or @samp{nm --print-armap} to list this index.
+
+An archive with such an index speeds up linking to the library and
+allows routines in the library to call each other without regard to
+their placement in the archive.
+
+The @sc{gnu} @code{ranlib} program is another form of @sc{gnu} @code{ar}; running
+@code{ranlib} is completely equivalent to executing @samp{ar -s}.
+@xref{ar}.
+
+@table @code
+@item -v
+@itemx -V
+Show the version number of @code{ranlib}.
+@end table
+
+@node size
+@chapter size
+
+@kindex size
+@cindex section sizes
+
+@smallexample
+size [ -A | -B | --format=@var{compatibility} ]
+ [ --help ] [ -d | -o | -x | --radix=@var{number} ]
+ [ --target=@var{bfdname} ] [ -V | --version ]
+ [ @var{objfile}@dots{} ]
+@end smallexample
+
+The @sc{gnu} @code{size} utility lists the section sizes---and the total
+size---for each of the object or archive files @var{objfile} in its
+argument list. By default, one line of output is generated for each
+object file or each module in an archive.
+
+@var{objfile}@dots{} are the object files to be examined.
+If none are specified, the file @code{a.out} will be used.
+
+The command line options have the following meanings:
+
+@table @code
+@item -A
+@itemx -B
+@itemx --format=@var{compatibility}
+@cindex @code{size} display format
+Using one of these options, you can choose whether the output from @sc{gnu}
+@code{size} resembles output from System V @code{size} (using @samp{-A},
+or @samp{--format=sysv}), or Berkeley @code{size} (using @samp{-B}, or
+@samp{--format=berkeley}). The default is the one-line format similar to
+Berkeley's.
+@c Bonus for doc-source readers: you can also say --format=strange (or
+@c anything else that starts with 's') for sysv, and --format=boring (or
+@c anything else that starts with 'b') for Berkeley.
+
+Here is an example of the Berkeley (default) format of output from
+@code{size}:
+@smallexample
+size --format=Berkeley ranlib size
+text data bss dec hex filename
+294880 81920 11592 388392 5ed28 ranlib
+294880 81920 11888 388688 5ee50 size
+@end smallexample
+
+@noindent
+This is the same data, but displayed closer to System V conventions:
+
+@smallexample
+size --format=SysV ranlib size
+ranlib :
+section size addr
+.text 294880 8192
+.data 81920 303104
+.bss 11592 385024
+Total 388392
+
+
+size :
+section size addr
+.text 294880 8192
+.data 81920 303104
+.bss 11888 385024
+Total 388688
+@end smallexample
+
+@item --help
+Show a summary of acceptable arguments and options.
+
+@item -d
+@itemx -o
+@itemx -x
+@itemx --radix=@var{number}
+@cindex @code{size} number format
+@cindex radix for section sizes
+Using one of these options, you can control whether the size of each
+section is given in decimal (@samp{-d}, or @samp{--radix=10}); octal
+(@samp{-o}, or @samp{--radix=8}); or hexadecimal (@samp{-x}, or
+@samp{--radix=16}). In @samp{--radix=@var{number}}, only the three
+values (8, 10, 16) are supported. The total size is always given in two
+radices; decimal and hexadecimal for @samp{-d} or @samp{-x} output, or
+octal and hexadecimal if you're using @samp{-o}.
+
+@item --target=@var{bfdname}
+@cindex object code format
+Specify that the object-code format for @var{objfile} is
+@var{bfdname}. This option may not be necessary; @code{size} can
+automatically recognize many formats.
+@xref{Target Selection}, for more information.
+
+@item -V
+@itemx --version
+Display the version number of @code{size}.
+@end table
+
+@node strings
+@chapter strings
+@kindex strings
+@cindex listings strings
+@cindex printing strings
+@cindex strings, printing
+
+@smallexample
+strings [-afov] [-@var{min-len}] [-n @var{min-len}] [-t @var{radix}] [-]
+ [--all] [--print-file-name] [--bytes=@var{min-len}]
+ [--radix=@var{radix}] [--target=@var{bfdname}]
+ [--help] [--version] @var{file}@dots{}
+@end smallexample
+
+For each @var{file} given, @sc{gnu} @code{strings} prints the printable
+character sequences that are at least 4 characters long (or the number
+given with the options below) and are followed by an unprintable
+character. By default, it only prints the strings from the initialized
+and loaded sections of object files; for other types of files, it prints
+the strings from the whole file.
+
+@code{strings} is mainly useful for determining the contents of non-text
+files.
+
+@table @code
+@item -a
+@itemx --all
+@itemx -
+Do not scan only the initialized and loaded sections of object files;
+scan the whole files.
+
+@item -f
+@itemx --print-file-name
+Print the name of the file before each string.
+
+@item --help
+Print a summary of the program usage on the standard output and exit.
+
+@item -@var{min-len}
+@itemx -n @var{min-len}
+@itemx --bytes=@var{min-len}
+Print sequences of characters that are at least @var{min-len} characters
+long, instead of the default 4.
+
+@item -o
+Like @samp{-t o}. Some other versions of @code{strings} have @samp{-o}
+act like @samp{-t d} instead. Since we can not be compatible with both
+ways, we simply chose one.
+
+@item -t @var{radix}
+@itemx --radix=@var{radix}
+Print the offset within the file before each string. The single
+character argument specifies the radix of the offset---@samp{o} for
+octal, @samp{x} for hexadecimal, or @samp{d} for decimal.
+
+@item --target=@var{bfdname}
+@cindex object code format
+Specify an object code format other than your system's default format.
+@xref{Target Selection}, for more information.
+
+@item -v
+@itemx --version
+Print the program version number on the standard output and exit.
+@end table
+
+@node strip
+@chapter strip
+
+@kindex strip
+@cindex removing symbols
+@cindex discarding symbols
+@cindex symbols, discarding
+
+@smallexample
+strip [ -F @var{bfdname} | --target=@var{bfdname} ]
+ [ -I @var{bfdname} | --input-target=@var{bfdname} ]
+ [ -O @var{bfdname} | --output-target=@var{bfdname} ]
+ [ -s | --strip-all ] [ -S | -g | --strip-debug ]
+ [ -K @var{symbolname} | --keep-symbol=@var{symbolname} ]
+ [ -N @var{symbolname} | --strip-symbol=@var{symbolname} ]
+ [ -x | --discard-all ] [ -X | --discard-locals ]
+ [ -R @var{sectionname} | --remove-section=@var{sectionname} ]
+ [ -o @var{file} ] [ -p | --preserve-dates ]
+ [ -v | --verbose ] [ -V | --version ] [ --help ]
+ @var{objfile}@dots{}
+@end smallexample
+
+@sc{gnu} @code{strip} discards all symbols from object files
+@var{objfile}. The list of object files may include archives.
+At least one object file must be given.
+
+@code{strip} modifies the files named in its argument,
+rather than writing modified copies under different names.
+
+@table @code
+@item -F @var{bfdname}
+@itemx --target=@var{bfdname}
+Treat the original @var{objfile} as a file with the object
+code format @var{bfdname}, and rewrite it in the same format.
+@xref{Target Selection}, for more information.
+
+@item --help
+Show a summary of the options to @code{strip} and exit.
+
+@item -I @var{bfdname}
+@itemx --input-target=@var{bfdname}
+Treat the original @var{objfile} as a file with the object
+code format @var{bfdname}.
+@xref{Target Selection}, for more information.
+
+@item -O @var{bfdname}
+@itemx --output-target=@var{bfdname}
+Replace @var{objfile} with a file in the output format @var{bfdname}.
+@xref{Target Selection}, for more information.
+
+@item -R @var{sectionname}
+@itemx --remove-section=@var{sectionname}
+Remove any section named @var{sectionname} from the output file. This
+option may be given more than once. Note that using this option
+inappropriately may make the output file unusable.
+
+@item -s
+@itemx --strip-all
+Remove all symbols.
+
+@item -g
+@itemx -S
+@itemx --strip-debug
+Remove debugging symbols only.
+
+@item --strip-unneeded
+Remove all symbols that are not needed for relocation processing.
+
+@item -K @var{symbolname}
+@itemx --keep-symbol=@var{symbolname}
+Keep only symbol @var{symbolname} from the source file. This option may
+be given more than once.
+
+@item -N @var{symbolname}
+@itemx --strip-symbol=@var{symbolname}
+Remove symbol @var{symbolname} from the source file. This option may be
+given more than once, and may be combined with strip options other than
+@code{-K}.
+
+@item -o @var{file}
+Put the stripped output in @var{file}, rather than replacing the
+existing file. When this argument is used, only one @var{objfile}
+argument may be specified.
+
+@item -p
+@itemx --preserve-dates
+Preserve the access and modification dates of the file.
+
+@item -x
+@itemx --discard-all
+Remove non-global symbols.
+
+@item -X
+@itemx --discard-locals
+Remove compiler-generated local symbols.
+(These usually start with @samp{L} or @samp{.}.)
+
+@item -V
+@itemx --version
+Show the version number for @code{strip}.
+
+@item -v
+@itemx --verbose
+Verbose output: list all object files modified. In the case of
+archives, @samp{strip -v} lists all members of the archive.
+@end table
+
+@node c++filt
+@chapter c++filt
+
+@kindex c++filt
+@cindex demangling C++ symbols
+
+@smallexample
+c++filt [ -_ | --strip-underscores ]
+ [ -j | --java ]
+ [ -n | --no-strip-underscores ]
+ [ -s @var{format} | --format=@var{format} ]
+ [ --help ] [ --version ] [ @var{symbol}@dots{} ]
+@end smallexample
+
+The C++ and Java languages provides function overloading, which means
+that you can write many functions with the same name (providing each
+takes parameters of different types). All C++ and Java function names
+are encoded into a low-level assembly label (this process is known as
+@dfn{mangling}). The @code{c++filt} program does the inverse mapping: it
+decodes (@dfn{demangles}) low-level names into user-level names so that
+the linker can keep these overloaded functions from clashing.
+
+Every alphanumeric word (consisting of letters, digits, underscores,
+dollars, or periods) seen in the input is a potential label. If the
+label decodes into a C++ name, the C++ name replaces the low-level
+name in the output.
+
+You can use @code{c++filt} to decipher individual symbols:
+
+@example
+c++filt @var{symbol}
+@end example
+
+If no @var{symbol} arguments are given, @code{c++filt} reads symbol
+names from the standard input and writes the demangled names to the
+standard output. All results are printed on the standard output.
+
+@table @code
+@item -_
+@itemx --strip-underscores
+On some systems, both the C and C++ compilers put an underscore in front
+of every name. For example, the C name @code{foo} gets the low-level
+name @code{_foo}. This option removes the initial underscore. Whether
+@code{c++filt} removes the underscore by default is target dependent.
+
+@item -j
+@itemx --java
+Prints demangled names using Java syntax. The default is to use C++
+syntax.
+
+@item -n
+@itemx --no-strip-underscores
+Do not remove the initial underscore.
+
+@item -s @var{format}
+@itemx --format=@var{format}
+@sc{gnu} @code{nm} can decode three different methods of mangling, used by
+different C++ compilers. The argument to this option selects which
+method it uses:
+
+@table @code
+@item gnu
+the one used by the @sc{gnu} compiler (the default method)
+@item lucid
+the one used by the Lucid compiler
+@item arm
+the one specified by the C++ Annotated Reference Manual
+@item hp
+the one used by the HP compiler
+@item edg
+the one used by the EDG compiler
+@end table
+
+@item --help
+Print a summary of the options to @code{c++filt} and exit.
+
+@item --version
+Print the version number of @code{c++filt} and exit.
+@end table
+
+@quotation
+@emph{Warning:} @code{c++filt} is a new utility, and the details of its
+user interface are subject to change in future releases. In particular,
+a command-line option may be required in the the future to decode a name
+passed as an argument on the command line; in other words,
+
+@example
+c++filt @var{symbol}
+@end example
+
+@noindent
+may in a future release become
+
+@example
+c++filt @var{option} @var{symbol}
+@end example
+@end quotation
+
+@node addr2line
+@chapter addr2line
+
+@kindex addr2line
+@cindex address to file name and line number
+
+@smallexample
+addr2line [ -b @var{bfdname} | --target=@var{bfdname} ]
+ [ -C | --demangle ]
+ [ -e @var{filename} | --exe=@var{filename} ]
+ [ -f | --functions ] [ -s | --basename ]
+ [ -H | --help ] [ -V | --version ]
+ [ addr addr ... ]
+@end smallexample
+
+@code{addr2line} translates program addresses into file names and line
+numbers. Given an address and an executable, it uses the debugging
+information in the executable to figure out which file name and line
+number are associated with a given address.
+
+The executable to use is specified with the @code{-e} option. The
+default is @file{a.out}.
+
+@code{addr2line} has two modes of operation.
+
+In the first, hexadecimal addresses are specified on the command line,
+and @code{addr2line} displays the file name and line number for each
+address.
+
+In the second, @code{addr2line} reads hexadecimal addresses from
+standard input, and prints the file name and line number for each
+address on standard output. In this mode, @code{addr2line} may be used
+in a pipe to convert dynamically chosen addresses.
+
+The format of the output is @samp{FILENAME:LINENO}. The file name and
+line number for each address is printed on a separate line. If the
+@code{-f} option is used, then each @samp{FILENAME:LINENO} line is
+preceded by a @samp{FUNCTIONNAME} line which is the name of the function
+containing the address.
+
+If the file name or function name can not be determined,
+@code{addr2line} will print two question marks in their place. If the
+line number can not be determined, @code{addr2line} will print 0.
+
+The long and short forms of options, shown here as alternatives, are
+equivalent.
+
+@table @code
+@item -b @var{bfdname}
+@itemx --target=@var{bfdname}
+@cindex object code format
+Specify that the object-code format for the object files is
+@var{bfdname}.
+
+@item -C
+@itemx --demangle
+@cindex demangling in objdump
+Decode (@dfn{demangle}) low-level symbol names into user-level names.
+Besides removing any initial underscore prepended by the system, this
+makes C++ function names readable. @xref{c++filt}, for more information
+on demangling.
+
+@item -e @var{filename}
+@itemx --exe=@var{filename}
+Specify the name of the executable for which addresses should be
+translated. The default file is @file{a.out}.
+
+@item -f
+@itemx --functions
+Display function names as well as file and line number information.
+
+@item -s
+@itemx --basenames
+Display only the base of each file name.
+@end table
+
+@node nlmconv
+@chapter nlmconv
+
+@code{nlmconv} converts a relocatable object file into a NetWare
+Loadable Module.
+
+@ignore
+@code{nlmconv} currently works with @samp{i386} object
+files in @code{coff}, @sc{elf}, or @code{a.out} format, and @sc{SPARC}
+object files in @sc{elf}, or @code{a.out} format@footnote{
+@code{nlmconv} should work with any @samp{i386} or @sc{sparc} object
+format in the Binary File Descriptor library. It has only been tested
+with the above formats.}.
+@end ignore
+
+@quotation
+@emph{Warning:} @code{nlmconv} is not always built as part of the binary
+utilities, since it is only useful for NLM targets.
+@end quotation
+
+@smallexample
+nlmconv [ -I @var{bfdname} | --input-target=@var{bfdname} ]
+ [ -O @var{bfdname} | --output-target=@var{bfdname} ]
+ [ -T @var{headerfile} | --header-file=@var{headerfile} ]
+ [ -d | --debug] [ -l @var{linker} | --linker=@var{linker} ]
+ [ -h | --help ] [ -V | --version ]
+ @var{infile} @var{outfile}
+@end smallexample
+
+@code{nlmconv} converts the relocatable @samp{i386} object file
+@var{infile} into the NetWare Loadable Module @var{outfile}, optionally
+reading @var{headerfile} for NLM header information. For instructions
+on writing the NLM command file language used in header files, see the
+@samp{linkers} section, @samp{NLMLINK} in particular, of the @cite{NLM
+Development and Tools Overview}, which is part of the NLM Software
+Developer's Kit (``NLM SDK''), available from Novell, Inc.
+@code{nlmconv} uses the @sc{gnu} Binary File Descriptor library to read
+@var{infile}; see @ref{BFD,,BFD,ld.info,Using LD}, for
+more information.
+
+@code{nlmconv} can perform a link step. In other words, you can list
+more than one object file for input if you list them in the definitions
+file (rather than simply specifying one input file on the command line).
+In this case, @code{nlmconv} calls the linker for you.
+
+@table @code
+@item -I @var{bfdname}
+@itemx --input-target=@var{bfdname}
+Object format of the input file. @code{nlmconv} can usually determine
+the format of a given file (so no default is necessary).
+@xref{Target Selection}, for more information.
+
+@item -O @var{bfdname}
+@itemx --output-target=@var{bfdname}
+Object format of the output file. @code{nlmconv} infers the output
+format based on the input format, e.g. for a @samp{i386} input file the
+output format is @samp{nlm32-i386}.
+@xref{Target Selection}, for more information.
+
+@item -T @var{headerfile}
+@itemx --header-file=@var{headerfile}
+Reads @var{headerfile} for NLM header information. For instructions on
+writing the NLM command file language used in header files, see@ see the
+@samp{linkers} section, of the @cite{NLM Development and Tools
+Overview}, which is part of the NLM Software Developer's Kit, available
+from Novell, Inc.
+
+@item -d
+@itemx --debug
+Displays (on standard error) the linker command line used by @code{nlmconv}.
+
+@item -l @var{linker}
+@itemx --linker=@var{linker}
+Use @var{linker} for any linking. @var{linker} can be an absolute or a
+relative pathname.
+
+@item -h
+@itemx --help
+Prints a usage summary.
+
+@item -V
+@itemx --version
+Prints the version number for @code{nlmconv}.
+@end table
+
+@node windres
+@chapter windres
+
+@code{windres} may be used to manipulate Windows resources.
+
+@quotation
+@emph{Warning:} @code{windres} is not always built as part of the binary
+utilities, since it is only useful for Windows targets.
+@end quotation
+
+@smallexample
+windres [options] [input-file] [output-file]
+@end smallexample
+
+@code{windres} reads resources from an input file and copies them into
+an output file. Either file may be in one of three formats:
+
+@table @code
+@item rc
+A text format read by the Resource Compiler.
+
+@item res
+A binary format generated by the Resource Compiler.
+
+@item coff
+A COFF object or executable.
+@end table
+
+The exact description of these different formats is available in
+documentation from Microsoft.
+
+When @code{windres} converts from the @code{rc} format to the @code{res}
+format, it is acting like the Windows Resource Compiler. When
+@code{windres} converts from the @code{res} format to the @code{coff}
+format, it is acting like the Windows @code{CVTRES} program.
+
+When @code{windres} generates an @code{rc} file, the output is similar
+but not identical to the format expected for the input. When an input
+@code{rc} file refers to an external filename, an output @code{rc} file
+will instead include the file contents.
+
+If the input or output format is not specified, @code{windres} will
+guess based on the file name, or, for the input file, the file contents.
+A file with an extension of @file{.rc} will be treated as an @code{rc}
+file, a file with an extension of @file{.res} will be treated as a
+@code{res} file, and a file with an extension of @file{.o} or
+@file{.exe} will be treated as a @code{coff} file.
+
+If no output file is specified, @code{windres} will print the resources
+in @code{rc} format to standard output.
+
+The normal use is for you to write an @code{rc} file, use @code{windres}
+to convert it to a COFF object file, and then link the COFF file into
+your application. This will make the resources described in the
+@code{rc} file available to Windows.
+
+@table @code
+@item -i @var{filename}
+@itemx --input @var{filename}
+The name of the input file. If this option is not used, then
+@code{windres} will use the first non-option argument as the input file
+name. If there are no non-option arguments, then @code{windres} will
+read from standard input. @code{windres} can not read a COFF file from
+standard input.
+
+@item -o @var{filename}
+@itemx --output @var{filename}
+The name of the output file. If this option is not used, then
+@code{windres} will use the first non-option argument, after any used
+for the input file name, as the output file name. If there is no
+non-option argument, then @code{windres} will write to standard output.
+@code{windres} can not write a COFF file to standard output.
+
+@item -I @var{format}
+@itemx --input-format @var{format}
+The input format to read. @var{format} may be @samp{res}, @samp{rc}, or
+@samp{coff}. If no input format is specified, @code{windres} will
+guess, as described above.
+
+@item -O @var{format}
+@itemx --output-format @var{format}
+The output format to generate. @var{format} may be @samp{res},
+@samp{rc}, or @samp{coff}. If no output format is specified,
+@code{windres} will guess, as described above.
+
+@item -F @var{target}
+@itemx --target @var{target}
+Specify the BFD format to use for a COFF file as input or output. This
+is a BFD target name; you can use the @code{--help} option to see a list
+of supported targets. Normally @code{windres} will use the default
+format, which is the first one listed by the @code{--help} option.
+@ref{Target Selection}.
+
+@item --preprocessor @var{program}
+When @code{windres} reads an @code{rc} file, it runs it through the C
+preprocessor first. This option may be used to specify the preprocessor
+to use, including any leading arguments. The default preprocessor
+argument is @code{gcc -E -xc-header -DRC_INVOKED}.
+
+@item --include-dir @var{directory}
+Specify an include directory to use when reading an @code{rc} file.
+@code{windres} will pass this to the preprocessor as an @code{-I}
+option. @code{windres} will also search this directory when looking for
+files named in the @code{rc} file.
+
+@item --define @var{sym[=val]}
+Specify a @code{-D} option to pass to the preprocessor when reading an
+@code{rc} file.
+
+@item --language @var{val}
+Specify the default language to use when reading an @code{rc} file.
+@var{val} should be a hexadecimal language code. The low eight bits are
+the language, and the high eight bits are the sublanguage.
+
+@item --help
+Prints a usage summary.
+
+@item --version
+Prints the version number for @code{windres}.
+
+@item --yydebug
+If @code{windres} is compiled with @code{YYDEBUG} defined as @code{1},
+this will turn on parser debugging.
+@end table
+
+
+@node dlltool
+@chapter Create files needed to build and use DLLs
+@cindex DLL
+@kindex dlltool
+
+@code{dlltool} may be used to create the files needed to build and use
+dynamic link libraries (DLLs).
+
+@quotation
+@emph{Warning:} @code{dlltool} is not always built as part of the binary
+utilities, since it is only useful for those targets which support DLLs.
+@end quotation
+
+@smallexample
+dlltool [-d|--input-def @var{def-file-name}]
+ [-b|--base-file @var{base-file-name}]
+ [-e|--output-exp @var{exports-file-name}]
+ [-z|--output-def @var{def-file-name}]
+ [-l|--output-lib @var{library-file-name}]
+ [--export-all-symbols] [--no-export-all-symbols]
+ [--exclude-symbols @var{list}]
+ [--no-default-excludes]
+ [-S|--as @var{path-to-assembler}] [-f|--as-flags @var{options}]
+ [-D|--dllname @var{name}] [-m|--machine @var{machine}]
+ [-a|--add-indirect] [-U|--add-underscore] [-k|--kill-at]
+ [-A|--add-stdcall-alias]
+ [-x|--no-idata4] [-c|--no-idata5] [-i|--interwork]
+ [-n|--nodelete] [-v|--verbose] [-h|--help] [-V|--version]
+ [object-file @dots{}]
+@end smallexample
+
+@code{dlltool} reads its inputs, which can come from the @samp{-d} and
+@samp{-b} options as well as object files specified on the command
+line. It then processes these inputs and if the @samp{-e} option has
+been specified it creates a exports file. If the @samp{-l} option
+has been specified it creates a library file and if the @samp{-z} option
+has been specified it creates a def file. Any or all of the -e, -l
+and -z options can be present in one invocation of dlltool.
+
+When creating a DLL, along with the source for the DLL, it is necessary
+to have three other files. @code{dlltool} can help with the creation of
+these files.
+
+The first file is a @samp{.def} file which specifies which functions are
+exported from the DLL, which functions the DLL imports, and so on. This
+is a text file and can be created by hand, or @code{dlltool} can be used
+to create it using the @samp{-z} option. In this case @code{dlltool}
+will scan the object files specified on its command line looking for
+those functions which have been specially marked as being exported and
+put entries for them in the .def file it creates.
+
+In order to mark a function as being exported from a DLL, it needs to
+have an @samp{-export:<name_of_function>} entry in the @samp{.drectve}
+section of the object file. This can be done in C by using the
+asm() operator:
+
+@smallexample
+ asm (".section .drectve");
+ asm (".ascii \"-export:my_func\"");
+
+ int my_func (void) @{ @dots{} @}
+@end smallexample
+
+The second file needed for DLL creation is an exports file. This file
+is linked with the object files that make up the body of the DLL and it
+handles the interface between the DLL and the outside world. This is a
+binary file and it can be created by giving the @samp{-e} option to
+@code{dlltool} when it is creating or reading in a .def file.
+
+The third file needed for DLL creation is the library file that programs
+will link with in order to access the functions in the DLL. This file
+can be created by giving the @samp{-l} option to dlltool when it
+is creating or reading in a .def file.
+
+@code{dlltool} builds the library file by hand, but it builds the
+exports file by creating temporary files containing assembler statements
+and then assembling these. The @samp{-S} command line option can be
+used to specify the path to the assembler that dlltool will use,
+and the @samp{-f} option can be used to pass specific flags to that
+assembler. The @samp{-n} can be used to prevent dlltool from deleting
+these temporary assembler files when it is done, and if @samp{-n} is
+specified twice then this will prevent dlltool from deleting the
+temporary object files it used to build the library.
+
+Here is an example of creating a DLL from a source file @samp{dll.c} and
+also creating a program (from an object file called @samp{program.o})
+that uses that DLL:
+
+@smallexample
+ gcc -c dll.c
+ dlltool -e exports.o -l dll.lib dll.o
+ gcc dll.o exports.o -o dll.dll
+ gcc program.o dll.lib -o program
+@end smallexample
+
+The command line options have the following meanings:
+
+@table @code
+
+@item -d @var{filename}
+@itemx --input-def @var{filename}
+@cindex input .def file
+Specifies the name of a .def file to be read in and processed.
+
+@item -b @var{filename}
+@itemx --base-file @var{filename}
+@cindex base files
+Specifies the name of a base file to be read in and processed. The
+contents of this file will be added to the relocation section in the
+exports file generated by dlltool.
+
+@item -e @var{filename}
+@itemx --output-exp @var{filename}
+Specifies the name of the export file to be created by dlltool.
+
+@item -z @var{filename}
+@itemx --output-def @var{filename}
+Specifies the name of the .def file to be created by dlltool.
+
+@item -l @var{filename}
+@itemx --output-lib @var{filename}
+Specifies the name of the library file to be created by dlltool.
+
+@item --export-all-symbols
+Treat all global and weak defined symbols found in the input object
+files as symbols to be exported. There is a small list of symbols which
+are not exported by default; see the @code{--no-default-excludes}
+option. You may add to the list of symbols to not export by using the
+@code{--exclude-symbols} option.
+
+@item --no-export-all-symbols
+Only export symbols explicitly listed in an input .def file or in
+@samp{.drectve} sections in the input object files. This is the default
+behaviour. The @samp{.drectve} sections are created by @samp{dllexport}
+attributes in the source code.
+
+@item --exclude-symbols @var{list}
+Do not export the symbols in @var{list}. This is a list of symbol names
+separated by comma or colon characters. The symbol names should not
+contain a leading underscore. This is only meaningful when
+@code{--export-all-symbols} is used.
+
+@item --no-default-excludes
+When @code{--export-all-symbols} is used, it will by default avoid
+exporting certain special symbols. The current list of symbols to avoid
+exporting is @samp{DllMain@@12}, @samp{DllEntryPoint@@0},
+@samp{impure_ptr}. You may use the @code{--no-default-excludes} option
+to go ahead and export these special symbols. This is only meaningful
+when @code{--export-all-symbols} is used.
+
+@item -S @var{path}
+@itemx --as @var{path}
+Specifies the path, including the filename, of the assembler to be used
+to create the exports file.
+
+@item -f @var{switches}
+@itemx --as-flags @var{switches}
+Specifies any specific command line switches to be passed to the
+assembler when building the exports file. This option will work even if
+the @samp{-S} option is not used. This option only takes one argument,
+and if it occurs more than once on the command line, then later
+occurrences will override earlier occurrences. So if it is necessary to
+pass multiple switches to the assembler they should be enclosed in
+double quotes.
+
+@item -D @var{name}
+@itemx --dll-name @var{name}
+Specifies the name to be stored in the .def file as the name of the DLL
+when the @samp{-e} option is used. If this option is not present, then
+the filename given to the @samp{-e} option will be used as the name of
+the DLL.
+
+@item -m @var{machine}
+@itemx -machine @var{machine}
+Specifies the type of machine for which the library file should be
+built. @code{dlltool} has a built in default type, depending upon how
+it was created, but this option can be used to override that. This is
+normally only useful when creating DLLs for an ARM processor, when the
+contents of the DLL are actually encode using THUMB instructions.
+
+@item -a
+@itemx --add-indirect
+Specifies that when @code{dlltool} is creating the exports file it
+should add a section which allows the exported functions to be
+referenced without using the import library. Whatever the hell that
+means!
+
+@item -U
+@itemx --add-underscore
+Specifies that when @code{dlltool} is creating the exports file it
+should prepend an underscore to the names of the exported functions.
+
+@item -k
+@itemx --kill-at
+Specifies that when @code{dlltool} is creating the exports file it
+should not append the string @samp{@@ <number>}. These numbers are
+called ordinal numbers and they represent another way of accessing the
+function in a DLL, other than by name.
+
+@item -A
+@itemx --add-stdcall-alias
+Specifies that when @code{dlltool} is creating the exports file it
+should add aliases for stdcall symbols without @samp{@@ <number>}
+in addition to the symbols with @samp{@@ <number>}.
+
+@item -x
+@itemx --no-idata4
+Specifies that when @code{dlltool} is creating the exports and library
+files it should omit the .idata4 section. This is for compatibility
+with certain operating systems.
+
+@item -c
+@itemx --no-idata5
+Specifies that when @code{dlltool} is creating the exports and library
+files it should omit the .idata5 section. This is for compatibility
+with certain operating systems.
+
+@item -i
+@itemx --interwork
+Specifies that @code{dlltool} should mark the objects in the library
+file and exports file that it produces as supporting interworking
+between ARM and THUMB code.
+
+@item -n
+@itemx --nodelete
+Makes @code{dlltool} preserve the temporary assembler files it used to
+create the exports file. If this option is repeated then dlltool will
+also preserve the temporary object files it uses to create the library
+file.
+
+@item -v
+@itemx --verbose
+Make dlltool describe what it is doing.
+
+@item -h
+@itemx --help
+Displays a list of command line options and then exits.
+
+@item -V
+@itemx --version
+Displays dlltool's version number and then exits.
+
+@end table
+
+@node readelf
+@chapter readelf
+
+@cindex ELF file information
+@kindex readelf
+
+@smallexample
+readelf [ -a | --all ]
+ [ -h | --file-header]
+ [ -l | --program-headers | --segments]
+ [ -S | --section-headers | --sections]
+ [ -e | --headers]
+ [ -s | --syms | --symbols]
+ [ -r | --relocs]
+ [ -d | --dynamic]
+ [ -V | --version-info]
+ [ -D | --use-dynamic]
+ [ -x <number> | --hex-dump=<number>]
+ [ -w[liapr] | --debug-dump[=info,=line,=abbrev,=pubnames,=ranges]]
+ [ --histogram]
+ [ -v | --version]
+ [ -H | --help]
+ @var{elffile}@dots{}
+@end smallexample
+
+@code{readelf} displays information about one or more ELF format object
+files. The options control what particular information to display.
+
+@var{elffile}@dots{} are the object files to be examined. At the
+moment, @code{readelf} does not support examining archives, nor does it
+support examing 64 bit ELF files.
+
+The long and short forms of options, shown here as alternatives, are
+equivalent. At least one option besides @samp{-v} or @samp{-H} must be
+given.
+
+@table @code
+@item -a
+@itemx --all
+Equivalent to specifiying @samp{--file-header},
+@samp{--program-headers}, @samp{--sections}, @samp{--symbols},
+@samp{--relocs}, @samp{--dynamic} and @samp{--version-info}.
+
+@item -h
+@itemx --file-header
+@cindex ELF file header information
+Displays the information contained in the ELF header at the start of the
+file.
+
+@item -l
+@itemx --program-headers
+@itemx --segments
+@cindex ELF program header information
+@cindex ELF segment information
+Displays the information contained in the file's segment headers, if it
+has any.
+
+@item -S
+@itemx --sections
+@itemx --section-headers
+@cindex ELF section information
+Displays the information contained in the file's section headers, if it
+has any.
+
+@item -s
+@itemx --symbols
+@itemx --syms
+@cindex ELF symbol table information
+Displays the entries in symbol table section of the file, if it has one.
+
+@item -e
+@itemx --headers
+Display all the headers in the file. Equivalent to @samp{-h -l -S}.
+
+@item -r
+@itemx --relocs
+@cindex ELF reloc information
+Displays the contents of the file's relocation section, if it ha one.
+
+@item -d
+@itemx --dynamic
+@cindex ELF dynamic section information
+Displays the contents of the file's dynamic section, if it has one.
+
+@item -V
+@itemx --version-info
+@cindex ELF version sections informations
+Displays the contents of the version sections in the file, it they
+exist.
+
+@item -D
+@itemx --use-dynamic
+When displaying symbols, this option makes @code{readelf} use the
+symblol table in the file's dynamic section, rather than the one in the
+symbols section.
+
+@item -x <number>
+@itemx --hex-dump=<number>
+Displays the contents of the indicated section as a hexadecimal dump.
+
+@item -w[liapr]
+@itemx --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]
+Displays the contents of the debug sections in the file, if any are
+present. If one of the optional letters or words follows the switch
+then only data found in those specific sections will be dumped.
+
+@item --histogram
+Display a histogram of bucket list lengths when displaying the contents
+of the symbol tables.
+
+@item -v
+@itemx --version
+Display the version number of readelf.
+
+@item -H
+@itemx --help
+Display the command line options understood by @code{readelf}.
+
+@end table
+
+
+@node Selecting The Target System
+@chapter Selecting the target system
+
+You can specify three aspects of the target system to the @sc{gnu}
+binary file utilities, each in several ways:
+
+@itemize @bullet
+@item
+the target
+
+@item
+the architecture
+
+@item
+the linker emulation (which applies to the linker only)
+@end itemize
+
+In the following summaries, the lists of ways to specify values are in
+order of decreasing precedence. The ways listed first override those
+listed later.
+
+The commands to list valid values only list the values for which the
+programs you are running were configured. If they were configured with
+@samp{--enable-targets=all}, the commands list most of the available
+values, but a few are left out; not all targets can be configured in at
+once because some of them can only be configured @dfn{native} (on hosts
+with the same type as the target system).
+
+@menu
+* Target Selection::
+* Architecture Selection::
+* Linker Emulation Selection::
+@end menu
+
+@node Target Selection
+@section Target Selection
+
+A @dfn{target} is an object file format. A given target may be
+supported for multiple architectures (@pxref{Architecture Selection}).
+A target selection may also have variations for different operating
+systems or architectures.
+
+The command to list valid target values is @samp{objdump -i}
+(the first column of output contains the relevant information).
+
+Some sample values are: @samp{a.out-hp300bsd}, @samp{ecoff-littlemips},
+@samp{a.out-sunos-big}.
+
+You can also specify a target using a configuration triplet. This is
+the same sort of name that is passed to configure to specify a target.
+When you use a configuration triplet as an argument, it must be fully
+canonicalized. You can see the canonical version of a triplet by
+running the shell script @file{config.sub} which is included with the
+sources.
+
+Some sample configuration triplets are: @samp{m68k-hp-bsd},
+@samp{mips-dec-ultrix}, @samp{sparc-sun-sunos}.
+
+@subheading @code{objdump} Target
+
+Ways to specify:
+
+@enumerate
+@item
+command line option: @samp{-b} or @samp{--target}
+
+@item
+environment variable @code{GNUTARGET}
+
+@item
+deduced from the input file
+@end enumerate
+
+@subheading @code{objcopy} and @code{strip} Input Target
+
+Ways to specify:
+
+@enumerate
+@item
+command line options: @samp{-I} or @samp{--input-target}, or @samp{-F} or @samp{--target}
+
+@item
+environment variable @code{GNUTARGET}
+
+@item
+deduced from the input file
+@end enumerate
+
+@subheading @code{objcopy} and @code{strip} Output Target
+
+Ways to specify:
+
+@enumerate
+@item
+command line options: @samp{-O} or @samp{--output-target}, or @samp{-F} or @samp{--target}
+
+@item
+the input target (see ``@code{objcopy} and @code{strip} Input Target'' above)
+
+@item
+environment variable @code{GNUTARGET}
+
+@item
+deduced from the input file
+@end enumerate
+
+@subheading @code{nm}, @code{size}, and @code{strings} Target
+
+Ways to specify:
+
+@enumerate
+@item
+command line option: @samp{--target}
+
+@item
+environment variable @code{GNUTARGET}
+
+@item
+deduced from the input file
+@end enumerate
+
+@subheading Linker Input Target
+
+Ways to specify:
+
+@enumerate
+@item
+command line option: @samp{-b} or @samp{--format}
+(@pxref{Options,,Options,ld.info,Using LD})
+
+@item
+script command @code{TARGET}
+(@pxref{Option Commands,,Option Commands,ld.info,Using LD})
+
+@item
+environment variable @code{GNUTARGET}
+(@pxref{Environment,,Environment,ld.info,Using LD})
+
+@item
+the default target of the selected linker emulation
+(@pxref{Linker Emulation Selection})
+@end enumerate
+
+@subheading Linker Output Target
+
+Ways to specify:
+
+@enumerate
+@item
+command line option: @samp{-oformat}
+(@pxref{Options,,Options,ld.info,Using LD})
+
+@item
+script command @code{OUTPUT_FORMAT}
+(@pxref{Option Commands,,Option Commands,ld.info,Using LD})
+
+@item
+the linker input target (see ``Linker Input Target'' above)
+@end enumerate
+
+@node Architecture Selection
+@section Architecture selection
+
+An @dfn{architecture} is a type of @sc{cpu} on which an object file is
+to run. Its name may contain a colon, separating the name of the
+processor family from the name of the particular @sc{cpu}.
+
+The command to list valid architecture values is @samp{objdump -i} (the
+second column contains the relevant information).
+
+Sample values: @samp{m68k:68020}, @samp{mips:3000}, @samp{sparc}.
+
+@subheading @code{objdump} Architecture
+
+Ways to specify:
+
+@enumerate
+@item
+command line option: @samp{-m} or @samp{--architecture}
+
+@item
+deduced from the input file
+@end enumerate
+
+@subheading @code{objcopy}, @code{nm}, @code{size}, @code{strings} Architecture
+
+Ways to specify:
+
+@enumerate
+@item
+deduced from the input file
+@end enumerate
+
+@subheading Linker Input Architecture
+
+Ways to specify:
+
+@enumerate
+@item
+deduced from the input file
+@end enumerate
+
+@subheading Linker Output Architecture
+
+Ways to specify:
+
+@enumerate
+@item
+script command @code{OUTPUT_ARCH}
+(@pxref{Option Commands,,Option Commands,ld.info,Using LD})
+
+@item
+the default architecture from the linker output target
+(@pxref{Target Selection})
+@end enumerate
+
+@node Linker Emulation Selection
+@section Linker emulation selection
+
+A linker @dfn{emulation} is a ``personality'' of the linker, which gives
+the linker default values for the other aspects of the target system.
+In particular, it consists of
+
+@itemize @bullet
+@item
+the linker script
+
+@item
+the target
+
+@item
+several ``hook'' functions that are run at certain stages of the linking
+process to do special things that some targets require
+@end itemize
+
+The command to list valid linker emulation values is @samp{ld -V}.
+
+Sample values: @samp{hp300bsd}, @samp{mipslit}, @samp{sun4}.
+
+Ways to specify:
+
+@enumerate
+@item
+command line option: @samp{-m}
+(@pxref{Options,,Options,ld.info,Using LD})
+
+@item
+environment variable @code{LDEMULATION}
+
+@item
+compiled-in @code{DEFAULT_EMULATION} from @file{Makefile},
+which comes from @code{EMUL} in @file{config/@var{target}.mt}
+@end enumerate
+
+@node Reporting Bugs
+@chapter Reporting Bugs
+@cindex bugs
+@cindex reporting bugs
+
+Your bug reports play an essential role in making the binary utilities
+reliable.
+
+Reporting a bug may help you by bringing a solution to your problem, or
+it may not. But in any case the principal function of a bug report is
+to help the entire community by making the next version of the binary
+utilities work better. Bug reports are your contribution to their
+maintenance.
+
+In order for a bug report to serve its purpose, you must include the
+information that enables us to fix the bug.
+
+@menu
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+@end menu
+
+@node Bug Criteria
+@section Have you found a bug?
+@cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+@itemize @bullet
+@cindex fatal signal
+@cindex crash
+@item
+If a binary utility gets a fatal signal, for any input whatever, that is
+a bug. Reliable utilities never crash.
+
+@cindex error on valid input
+@item
+If a binary utility produces an error message for valid input, that is a
+bug.
+
+@item
+If you are an experienced user of binary utilities, your suggestions for
+improvement are welcome in any case.
+@end itemize
+
+@node Bug Reporting
+@section How to report bugs
+@cindex bug reports
+@cindex bugs, reporting
+
+A number of companies and individuals offer support for @sc{gnu}
+products. If you obtained the binary utilities from a support
+organization, we recommend you contact that organization first.
+
+You can find contact information for many support companies and
+individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
+distribution.
+
+In any event, we also recommend that you send bug reports for the binary
+utilities to @samp{bug-gnu-utils@@gnu.org}.
+
+The fundamental principle of reporting bugs usefully is this:
+@strong{report all the facts}. If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the
+problem and assume that some details do not matter. Thus, you might
+assume that the name of a file you use in an example does not matter.
+Well, probably it does not, but one cannot be sure. Perhaps the bug is
+a stray memory reference which happens to fetch from the location where
+that pathname is stored in memory; perhaps, if the pathname were
+different, the contents of that location would fool the utility into
+doing the right thing despite the bug. Play it safe and give a
+specific, complete example. That is the easiest thing for you to do,
+and the most helpful.
+
+Keep in mind that the purpose of a bug report is to enable us to fix the bug if
+it is new to us. Therefore, always write your bug reports on the assumption
+that the bug has not been reported previously.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?'' Those bug reports are useless, and we urge everyone to
+@emph{refuse to respond to them} except to chide the sender to report
+bugs properly.
+
+To enable us to fix the bug, you should include all these things:
+
+@itemize @bullet
+@item
+The version of the utility. Each utility announces it if you start it
+with the @samp{--version} argument.
+
+Without this, we will not know whether there is any point in looking for
+the bug in the current version of the binary utilities.
+
+@item
+Any patches you may have applied to the source, including any patches
+made to the @code{BFD} library.
+
+@item
+The type of machine you are using, and the operating system name and
+version number.
+
+@item
+What compiler (and its version) was used to compile the utilities---e.g.
+``@code{gcc-2.7}''.
+
+@item
+The command arguments you gave the utility to observe the bug. To
+guarantee you will not omit something important, list them all. A copy
+of the Makefile (or the output from make) is sufficient.
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we might not encounter the bug.
+
+@item
+A complete input file, or set of input files, that will reproduce the
+bug. If the utility is reading an object file or files, then it is
+generally most helpful to send the actual object files, uuencoded if
+necessary to get them through the mail system. Making them available
+for anonymous FTP is not as good, but may be the only reasonable choice
+for large object files.
+
+If the source files were produced exclusively using @sc{gnu} programs
+(e.g., @code{gcc}, @code{gas}, and/or the @sc{gnu} @code{ld}), then it
+may be OK to send the source files rather than the object files. In
+this case, be sure to say exactly what version of @code{gcc}, or
+whatever, was used to produce the object files. Also say how
+@code{gcc}, or whatever, was configured.
+
+@item
+A description of what behavior you observe that you believe is
+incorrect. For example, ``It gets a fatal signal.''
+
+Of course, if the bug is that the utility gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might
+not notice unless it is glaringly wrong. You might as well not give us
+a chance to make a mistake.
+
+Even if the problem you experience is a fatal signal, you should still
+say so explicitly. Suppose something strange is going on, such as, your
+copy of the utility is out of synch, or you have encountered a bug in
+the C library on your system. (This has happened!) Your copy might
+crash and ours would not. If you told us to expect a crash, then when
+ours fails to crash, we would know that the bug was not happening for
+us. If you had not told us to expect a crash, then we would not be able
+to draw any conclusion from our observations.
+
+@item
+If you wish to suggest changes to the source, send us context diffs, as
+generated by @code{diff} with the @samp{-u}, @samp{-c}, or @samp{-p}
+option. Always send diffs from the old file to the new file. If you
+even discuss something in the @code{ld} source, refer to it by context,
+not by line number.
+
+The line numbers in our development sources will not match those in your
+sources. Your line numbers would convey no useful information to us.
+@end itemize
+
+Here are some things that are not necessary:
+
+@itemize @bullet
+@item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating
+which changes to the input file will make the bug go away and which
+changes will not affect it.
+
+This is often time consuming and not very useful, because the way we
+will find the bug is by running a single example under the debugger
+with breakpoints, not by pure deduction from a series of examples.
+We recommend that you save your time for something else.
+
+Of course, if you can find a simpler example to report @emph{instead}
+of the original one, that is a convenience for us. Errors in the
+output will be easier to spot, running under the debugger will take
+less time, and so on.
+
+However, simplification is not vital; if you do not want to do this,
+report the bug anyway and send us the entire test case you used.
+
+@item
+A patch for the bug.
+
+A patch for the bug does help us if it is a good one. But do not omit
+the necessary information, such as the test case, on the assumption that
+a patch is all we need. We might see problems with your patch and decide
+to fix the problem another way, or we might not understand it at all.
+
+Sometimes with programs as complicated as the binary utilities it is
+very hard to construct an example that will make the program follow a
+certain path through the code. If you do not send us the example, we
+will not be able to construct one, so we will not be able to verify that
+the bug is fixed.
+
+And if we cannot understand what bug you are trying to fix, or why your
+patch should be an improvement, we will not install it. A test case will
+help us to understand.
+
+@item
+A guess about what the bug is or what it depends on.
+
+Such guesses are usually wrong. Even we cannot guess right about such
+things without first using the debugger to find the facts.
+@end itemize
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/binutils/bucomm.c b/binutils/bucomm.c
new file mode 100644
index 00000000000..a5b0054887a
--- /dev/null
+++ b/binutils/bucomm.c
@@ -0,0 +1,266 @@
+/* bucomm.c -- Bin Utils COMmon code.
+ Copyright (C) 1991, 92, 93, 94, 95, 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* We might put this in a library someday so it could be dynamically
+ loaded, but for now it's not necessary. */
+
+#include "bfd.h"
+#include "libiberty.h"
+#include "bucomm.h"
+
+#include <sys/stat.h>
+#include <time.h> /* ctime, maybe time_t */
+
+#ifndef HAVE_TIME_T_IN_TIME_H
+#ifndef HAVE_TIME_T_IN_TYPES_H
+typedef long time_t;
+#endif
+#endif
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* Error reporting */
+
+char *program_name;
+
+void
+bfd_nonfatal (string)
+ CONST char *string;
+{
+ CONST char *errmsg = bfd_errmsg (bfd_get_error ());
+
+ if (string)
+ fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
+ else
+ fprintf (stderr, "%s: %s\n", program_name, errmsg);
+}
+
+void
+bfd_fatal (string)
+ CONST char *string;
+{
+ bfd_nonfatal (string);
+ xexit (1);
+}
+
+static void
+report (format, args)
+ const char * format;
+ va_list args;
+{
+ fprintf (stderr, "%s: ", program_name);
+ vfprintf (stderr, format, args);
+ putc ('\n', stderr);
+}
+
+#ifdef ANSI_PROTOTYPES
+void
+fatal (const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ report (format, args);
+ va_end (args);
+ xexit (1);
+}
+
+void
+non_fatal (const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ report (format, args);
+ va_end (args);
+}
+#else
+void
+fatal (va_alist)
+ va_dcl
+{
+ char *Format;
+ va_list args;
+
+ va_start (args);
+ Format = va_arg (args, char *);
+ report (Format, args);
+ va_end (args);
+ xexit (1);
+}
+
+void
+non_fatal (va_alist)
+ va_dcl
+{
+ char *Format;
+ va_list args;
+
+ va_start (args);
+ Format = va_arg (args, char *);
+ report (Format, args);
+ va_end (args);
+}
+#endif
+
+/* Set the default BFD target based on the configured target. Doing
+ this permits the binutils to be configured for a particular target,
+ and linked against a shared BFD library which was configured for a
+ different target. */
+
+void
+set_default_bfd_target ()
+{
+ /* The macro TARGET is defined by Makefile. */
+ const char *target = TARGET;
+
+ if (! bfd_set_default_target (target))
+ fatal (_("can't set BFD default target to `%s': %s"),
+ target, bfd_errmsg (bfd_get_error ()));
+}
+
+/* After a false return from bfd_check_format_matches with
+ bfd_get_error () == bfd_error_file_ambiguously_recognized, print
+ the possible matching targets. */
+
+void
+list_matching_formats (p)
+ char **p;
+{
+ fprintf (stderr, _("%s: Matching formats:"), program_name);
+ while (*p)
+ fprintf (stderr, " %s", *p++);
+ fputc ('\n', stderr);
+}
+
+/* List the supported targets. */
+
+void
+list_supported_targets (name, f)
+ const char *name;
+ FILE *f;
+{
+ extern bfd_target *bfd_target_vector[];
+ int t;
+
+ if (name == NULL)
+ fprintf (f, _("Supported targets:"));
+ else
+ fprintf (f, _("%s: supported targets:"), name);
+ for (t = 0; bfd_target_vector[t] != NULL; t++)
+ fprintf (f, " %s", bfd_target_vector[t]->name);
+ fprintf (f, "\n");
+}
+
+/* Display the archive header for an element as if it were an ls -l listing:
+
+ Mode User\tGroup\tSize\tDate Name */
+
+void
+print_arelt_descr (file, abfd, verbose)
+ FILE *file;
+ bfd *abfd;
+ boolean verbose;
+{
+ struct stat buf;
+
+ if (verbose)
+ {
+ if (bfd_stat_arch_elt (abfd, &buf) == 0)
+ {
+ char modebuf[11];
+ char timebuf[40];
+ time_t when = buf.st_mtime;
+ CONST char *ctime_result = (CONST char *) ctime (&when);
+
+ /* POSIX format: skip weekday and seconds from ctime output. */
+ sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
+
+ mode_string (buf.st_mode, modebuf);
+ modebuf[10] = '\0';
+ /* POSIX 1003.2/D11 says to skip first character (entry type). */
+ fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
+ (long) buf.st_uid, (long) buf.st_gid,
+ (long) buf.st_size, timebuf);
+ }
+ }
+
+ fprintf (file, "%s\n", bfd_get_filename (abfd));
+}
+
+/* Return the name of a temporary file in the same directory as FILENAME. */
+
+char *
+make_tempname (filename)
+ char *filename;
+{
+ static char template[] = "stXXXXXX";
+ char *tmpname;
+ char *slash = strrchr (filename, '/');
+
+#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32)
+ if (slash == NULL)
+ slash = strrchr (filename, '\\');
+#endif
+
+ if (slash != (char *) NULL)
+ {
+ char c;
+
+ c = *slash;
+ *slash = 0;
+ tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
+ strcpy (tmpname, filename);
+ strcat (tmpname, "/");
+ strcat (tmpname, template);
+ mktemp (tmpname);
+ *slash = c;
+ }
+ else
+ {
+ tmpname = xmalloc (sizeof (template));
+ strcpy (tmpname, template);
+ mktemp (tmpname);
+ }
+ return tmpname;
+}
+
+/* Parse a string into a VMA, with a fatal error if it can't be
+ parsed. */
+
+bfd_vma
+parse_vma (s, arg)
+ const char *s;
+ const char *arg;
+{
+ bfd_vma ret;
+ const char *end;
+
+ ret = bfd_scan_vma (s, &end, 0);
+
+ if (*end != '\0')
+ fatal (_("%s: bad number: %s"), arg, s);
+
+ return ret;
+}
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
new file mode 100644
index 00000000000..36e6a7959e6
--- /dev/null
+++ b/binutils/bucomm.h
@@ -0,0 +1,183 @@
+/* bucomm.h -- binutils common include file.
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _BUCOMM_H
+#define _BUCOMM_H
+
+#include "ansidecl.h"
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "config.h"
+
+#ifdef USE_BINARY_FOPEN
+#include "fopen-bin.h"
+#else
+#include "fopen-same.h"
+#endif
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#else
+extern char *strchr ();
+extern char *strrchr ();
+#endif
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#endif
+
+#ifdef NEED_DECLARATION_STRSTR
+extern char *strstr ();
+#endif
+
+#ifdef HAVE_SBRK
+#ifdef NEED_DECLARATION_SBRK
+extern char *sbrk ();
+#endif
+#endif
+
+#ifdef NEED_DECLARATION_GETENV
+extern char *getenv ();
+#endif
+
+#ifdef NEED_DECLARATION_ENVIRON
+extern char **environ;
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#if defined(__GNUC__) && !defined(C_ALLOCA)
+# undef alloca
+# define alloca __builtin_alloca
+#else
+# if defined(HAVE_ALLOCA_H) && !defined(C_ALLOCA)
+# include <alloca.h>
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+char *alloca ();
+# else
+void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* HAVE_ALLOCA_H */
+#endif
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+/* bucomm.c */
+void bfd_nonfatal PARAMS ((CONST char *));
+
+void bfd_fatal PARAMS ((CONST char *));
+
+void fatal PARAMS ((CONST char *, ...));
+
+void non_fatal PARAMS ((CONST char *, ...));
+
+void set_default_bfd_target PARAMS ((void));
+
+void list_matching_formats PARAMS ((char **p));
+
+void list_supported_targets PARAMS ((const char *, FILE *));
+
+void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose));
+
+char *make_tempname PARAMS ((char *));
+
+bfd_vma parse_vma PARAMS ((const char *, const char *));
+
+extern char *program_name;
+
+/* filemode.c */
+void mode_string PARAMS ((unsigned long mode, char *buf));
+
+/* version.c */
+extern void print_version PARAMS ((const char *));
+
+/* rename.c */
+extern void set_times PARAMS ((const char *, const struct stat *));
+
+extern int smart_rename PARAMS ((const char *, const char *, int));
+
+/* libiberty */
+PTR xmalloc PARAMS ((size_t));
+
+PTR xrealloc PARAMS ((PTR, size_t));
+
+#endif /* _BUCOMM_H */
diff --git a/binutils/budbg.h b/binutils/budbg.h
new file mode 100644
index 00000000000..d8ee8895e76
--- /dev/null
+++ b/binutils/budbg.h
@@ -0,0 +1,58 @@
+/* budbg.c -- Interfaces to the generic debugging information routines.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef BUDBG_H
+#define BUDBG_H
+
+#include <stdio.h>
+
+/* Routine used to read generic debugging information. */
+
+extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long));
+
+/* Routine used to print generic debugging information. */
+
+extern boolean print_debugging_info PARAMS ((FILE *, PTR));
+
+/* Routines used to read and write stabs information. */
+
+extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long));
+
+extern boolean finish_stab PARAMS ((PTR, PTR));
+
+extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *));
+
+extern boolean write_stabs_in_sections_debugging_info
+ PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **,
+ bfd_size_type *));
+
+/* Routines used to read and write IEEE debugging information. */
+
+extern boolean parse_ieee
+ PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type));
+
+extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR));
+
+/* Routine used to read COFF debugging information. */
+
+extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR));
+
+#endif
diff --git a/binutils/coffdump.c b/binutils/coffdump.c
new file mode 100644
index 00000000000..dc84d509176
--- /dev/null
+++ b/binutils/coffdump.c
@@ -0,0 +1,541 @@
+/* Coff file dumper.
+ Copyright (C) 1994, 1998, 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Steve Chamberlain <sac@cygnus.com>
+
+ This module reads a type tree generated by coffgrok and prints
+ it out so we can test the grokker.
+*/
+
+#include <bfd.h>
+#include <getopt.h>
+#include <libiberty.h>
+
+#include "coffgrok.h"
+#include "bucomm.h"
+
+#define PROGRAM_VERSION "1.0"
+
+static int atnl;
+static void dump_coff_scope ();
+
+static void
+tab (x)
+int x;
+{
+ static int indent;
+ int i;
+
+ if (atnl)
+ {
+ if (x < 0)
+ {
+ printf (")");
+ indent += x;
+
+ return;
+ }
+ else
+ {
+ printf ("\n");
+ atnl = 0;
+ }
+ }
+
+ if (x == -1)
+ {
+ for (i = 0; i < indent; i++)
+ printf (" ");
+
+ indent += x;
+ printf (")");
+ return;
+ }
+
+ indent += x;
+
+ for (i = 0; i < indent; i++)
+ printf (" ");
+
+ if (x)
+ {
+ printf ("(");
+ }
+}
+
+static void nl ()
+{
+ atnl = 1;
+}
+
+static void
+dump_coff_lines (p)
+ struct coff_line *p;
+{
+ int i;
+ int online = 0;
+ tab(1);
+ printf(_("#lines %d "),p->nlines);
+ for (i = 0; i < p->nlines; i++)
+ {
+ printf("(%d 0x%x)", p->lines[i], p->addresses[i]);
+ online++;
+ if (online > 6)
+ {
+ nl();
+ tab(0);
+ online = 0;
+ }
+ }
+ nl();
+ tab(-1);
+}
+
+static void
+dump_coff_type (p)
+ struct coff_type *p;
+{
+ tab (1);
+ printf ("size %d ", p->size);
+ switch (p->type)
+ {
+ case coff_secdef_type:
+ printf ("section definition at %x size %x\n",
+ p->u.asecdef.address,
+ p->u.asecdef.size);
+ nl();
+ break;
+ case coff_pointer_type:
+ printf ("pointer to");
+ nl ();
+ dump_coff_type (p->u.pointer.points_to);
+ break;
+ case coff_array_type:
+ printf ("array [%d] of", p->u.array.dim);
+ nl ();
+ dump_coff_type (p->u.array.array_of);
+ break;
+ case coff_function_type:
+ printf ("function returning");
+ nl ();
+ dump_coff_type (p->u.function.function_returns);
+ dump_coff_lines (p->u.function.lines);
+ printf ("arguments");
+ nl ();
+ dump_coff_scope (p->u.function.parameters);
+ tab (0);
+ printf ("code");
+ nl ();
+ dump_coff_scope (p->u.function.code);
+ tab(0);
+ break;
+ case coff_structdef_type:
+ printf ("structure definition");
+ nl ();
+ dump_coff_scope (p->u.astructdef.elements);
+ break;
+ case coff_structref_type:
+ if (!p->u.aenumref.ref)
+ printf ("structure ref to UNKNOWN struct");
+ else
+ printf ("structure ref to %s", p->u.aenumref.ref->name);
+ break;
+ case coff_enumref_type:
+ printf ("enum ref to %s", p->u.astructref.ref->name);
+ break;
+ case coff_enumdef_type:
+ printf ("enum definition");
+ nl ();
+ dump_coff_scope (p->u.aenumdef.elements);
+ break;
+ case coff_basic_type:
+ switch (p->u.basic)
+ {
+ case T_NULL:
+ printf ("NULL");
+ break;
+ case T_VOID:
+ printf ("VOID");
+ break;
+ case T_CHAR:
+ printf ("CHAR");
+ break;
+ case T_SHORT:
+ printf ("SHORT");
+ break;
+ case T_INT:
+ printf ("INT ");
+ break;
+ case T_LONG:
+ printf ("LONG");
+ break;
+ case T_FLOAT:
+ printf ("FLOAT");
+ break;
+ case T_DOUBLE:
+ printf ("DOUBLE");
+ break;
+ case T_STRUCT:
+ printf ("STRUCT");
+ break;
+ case T_UNION:
+ printf ("UNION");
+ break;
+ case T_ENUM:
+ printf ("ENUM");
+ break;
+ case T_MOE:
+ printf ("MOE ");
+ break;
+ case T_UCHAR:
+ printf ("UCHAR");
+ break;
+ case T_USHORT:
+ printf ("USHORT");
+ break;
+ case T_UINT:
+ printf ("UINT");
+ break;
+ case T_ULONG:
+ printf ("ULONG");
+ break;
+ case T_LNGDBL:
+ printf ("LNGDBL");
+ break;
+ default:
+ abort ();
+ }
+ }
+ nl ();
+ tab (-1);
+}
+
+static void
+dump_coff_where (p)
+ struct coff_where *p;
+{
+ tab (1);
+ switch (p->where)
+ {
+ case coff_where_stack:
+ printf ("Stack offset %x", p->offset);
+ break;
+ case coff_where_memory:
+ printf ("Memory section %s+%x", p->section->name, p->offset);
+ break;
+ case coff_where_register:
+ printf ("Register %d", p->offset);
+ break;
+ case coff_where_member_of_struct:
+ printf ("Struct Member offset %x", p->offset);
+ break;
+ case coff_where_member_of_enum:
+ printf ("Enum Member offset %x", p->offset);
+ break;
+ case coff_where_unknown:
+ printf ("Undefined symbol");
+ break;
+ case coff_where_strtag:
+ printf ("STRTAG");
+ case coff_where_entag:
+ printf ("ENTAG");
+ break;
+ case coff_where_typedef:
+ printf ("TYPEDEF");
+ break;
+ default:
+ abort ();
+ }
+ nl ();
+ tab (-1);
+}
+
+static void
+dump_coff_visible (p)
+ struct coff_visible *p;
+{
+ tab (1);
+ switch (p->type)
+ {
+ case coff_vis_ext_def:
+ printf ("coff_vis_ext_def");
+ break;
+ case coff_vis_ext_ref:
+ printf ("coff_vis_ext_ref");
+ break;
+ case coff_vis_int_def:
+ printf ("coff_vis_int_def");
+ break;
+ case coff_vis_common:
+ printf ("coff_vis_common");
+ break;
+ case coff_vis_auto:
+ printf ("coff_vis_auto");
+ break;
+ case coff_vis_autoparam:
+ printf ("coff_vis_autoparam");
+ break;
+ case coff_vis_regparam:
+ printf ("coff_vis_regparam");
+ break;
+ case coff_vis_register:
+ printf ("coff_vis_register");
+ break;
+ case coff_vis_tag:
+ printf ("coff_vis_tag");
+ break;
+ case coff_vis_member_of_struct:
+ printf ("coff_vis_member_of_struct");
+ break;
+ case coff_vis_member_of_enum:
+ printf ("coff_vis_member_of_enum");
+ break;
+ default:
+ abort ();
+ }
+ nl ();
+ tab (-1);
+}
+
+
+void
+dump_coff_symbol (p)
+ struct coff_symbol *p;
+{
+ tab (1);
+ printf ("List of symbols");
+ nl ();
+ while (p)
+ {
+ tab (1);
+ tab (1);
+ printf ("Symbol %s, tag %d, number %d", p->name, p->tag, p->number);
+ nl ();
+ tab (-1);
+ tab (1);
+ printf ("Type");
+ nl ();
+ dump_coff_type (p->type);
+ tab (-1);
+ tab (1);
+ printf ("Where");
+ dump_coff_where (p->where);
+ tab (-1);
+ tab (1);
+ printf ("Visible");
+ dump_coff_visible (p->visible);
+ tab (-1);
+ p = p->next;
+ tab (-1);
+ }
+ tab (-1);
+}
+
+static void
+dump_coff_scope (p)
+ struct coff_scope *p;
+{
+if (p) {
+ tab (1);
+ printf ("List of blocks %lx ",(unsigned long) p);
+
+ if (p->sec) {
+ printf( " %s %x..%x", p->sec->name,p->offset, p->offset + p->size -1);
+ }
+ nl ();
+ tab (0);
+ printf ("*****************");
+ nl ();
+ while (p)
+ {
+ tab (0);
+ printf ("vars %d", p->nvars);
+ nl ();
+ dump_coff_symbol (p->vars_head);
+ printf ("blocks");
+ nl ();
+ dump_coff_scope (p->list_head);
+ nl ();
+ p = p->next;
+ }
+
+ tab (0);
+ printf ("*****************");
+ nl ();
+ tab (-1);
+}
+}
+
+static void
+dump_coff_sfile (p)
+ struct coff_sfile *p;
+{
+ tab (1);
+ printf ("List of source files");
+ nl ();
+ while (p)
+ {
+ tab (0);
+ printf ("Source file %s", p->name);
+ nl ();
+ dump_coff_scope (p->scope);
+ p = p->next;
+ }
+ tab (-1);
+}
+
+static void
+dump_coff_section(ptr)
+struct coff_section *ptr;
+{
+ int i;
+ tab(1);
+ printf("section %s %d %d address %x size %x number %d nrelocs %d",
+ ptr->name, ptr->code, ptr->data, ptr->address,ptr->size, ptr->number, ptr->nrelocs);
+ nl();
+
+ for (i = 0; i < ptr->nrelocs; i++)
+ {
+ tab(0);
+ printf("(%x %s %x)",
+ ptr->relocs[i].offset,
+ ptr->relocs[i].symbol->name,
+ ptr->relocs[i].addend);
+ nl();
+ }
+ tab(-1);
+
+}
+
+void
+coff_dump (ptr)
+ struct coff_ofile *ptr;
+{
+ int i;
+ printf ("Coff dump");
+ nl ();
+ printf ("#souces %d", ptr->nsources);
+ nl ();
+ dump_coff_sfile (ptr->source_head);
+ for (i = 0; i < ptr->nsections; i++)
+ dump_coff_section(ptr->sections + i);
+}
+
+
+
+char * program_name;
+
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, "Usage: %s [-hV] in-file\n", program_name);
+ exit (status);
+}
+
+static void
+show_help ()
+{
+ printf (_("%s: Print a human readable interpretation of a SYSROFF object file\n"),
+ program_name);
+ show_usage (stdout, 0);
+}
+
+
+int
+main (ac, av)
+ int ac;
+ char *av[];
+{
+ bfd *abfd;
+ struct coff_ofile *tree;
+ char **matching;
+ char *input_file = NULL;
+ int opt;
+ static struct option long_options[] =
+ {
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'V' },
+ { NULL, no_argument, 0, 0 }
+ };
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = av[0];
+ xmalloc_set_program_name (program_name);
+
+ while ((opt = getopt_long (ac, av, "hV", long_options,
+ (int *) NULL))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'h':
+ show_help ();
+ /*NOTREACHED*/
+ case 'V':
+ printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
+ exit (0);
+ /*NOTREACHED*/
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /*NOTREACHED*/
+ }
+ }
+
+ if (optind < ac)
+ {
+ input_file = av[optind];
+ }
+
+ if (!input_file)
+ {
+ fprintf (stderr,_("%s: no input file specified\n"),
+ program_name);
+ exit(1);
+ }
+ abfd = bfd_openr (input_file, 0);
+
+ if (!abfd)
+ bfd_fatal (input_file);
+
+ if (! bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (input_file);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ exit (1);
+ }
+
+ tree = coff_grok (abfd);
+
+ coff_dump(tree);
+ printf("\n");
+ return 0;
+}
diff --git a/binutils/coffgrok.c b/binutils/coffgrok.c
new file mode 100644
index 00000000000..8c4e6c9c98e
--- /dev/null
+++ b/binutils/coffgrok.c
@@ -0,0 +1,737 @@
+/* coffgrok.c
+ Copyright (C) 1994, 95, 97, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Steve Chamberlain (sac@cygnus.com)
+
+ This module reads a coff file and builds a really simple type tree
+ which can be read by other programs. The first application is a
+ coff->sysroff converter. It can be tested with coffdump.c.
+
+*/
+
+#include <bfd.h>
+#include "bucomm.h"
+
+#include "coff/internal.h"
+#include "../bfd/libcoff.h"
+#include "coffgrok.h"
+int lofile = 1;
+static struct coff_scope *top_scope;
+static struct coff_scope *file_scope;
+static struct coff_ofile *ofile;
+
+struct coff_symbol *last_function_symbol;
+struct coff_type *last_function_type;
+struct coff_type *last_struct;
+struct coff_type *last_enum;
+struct coff_sfile *cur_sfile;
+
+static struct coff_symbol **tindex;
+
+
+static asymbol **syms;
+static long symcount;
+
+#define N(x) ((x)->_n._n_nptr[1])
+
+static struct coff_ptr_struct *rawsyms;
+static int rawcount;
+static bfd *abfd;
+extern char *xcalloc ();
+#define PTR_SIZE 4
+#define SHORT_SIZE 2
+#define INT_SIZE 4
+#define LONG_SIZE 4
+#define FLOAT_SIZE 4
+#define DOUBLE_SIZE 8
+
+#define INDEXOF(p) ((struct coff_ptr_struct *)(p)-(rawsyms))
+
+static struct coff_scope *
+empty_scope ()
+{
+ struct coff_scope *l;
+ l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1));
+ return l;
+}
+
+static struct coff_symbol *
+empty_symbol ()
+{
+ return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1));
+}
+
+/*int l;*/
+static void
+push_scope (link)
+ int link;
+{
+ struct coff_scope *n = empty_scope ();
+ if (link)
+ {
+ if (top_scope)
+ {
+ if (top_scope->list_tail)
+ {
+ top_scope->list_tail->next = n;
+ }
+ else
+ {
+ top_scope->list_head = n;
+ }
+ top_scope->list_tail = n;
+ }
+ }
+ n->parent = top_scope;
+
+ top_scope = n;
+}
+
+static void
+pop_scope ()
+{
+ top_scope = top_scope->parent;
+}
+
+static void
+do_sections_p1 (head)
+ struct coff_ofile *head;
+{
+ asection *section;
+ int idx;
+ struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1,
+ sizeof (struct coff_section)));
+ head->nsections = abfd->section_count + 1;
+ head->sections = all;
+
+ for (idx = 0, section = abfd->sections; section; section = section->next, idx++)
+ {
+ long relsize;
+ int i = section->target_index;
+ arelent **relpp;
+ long relcount;
+
+ relsize = bfd_get_reloc_upper_bound (abfd, section);
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ if (relsize == 0)
+ continue;
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
+ if (relcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ head->sections[i].name = (char *) (section->name);
+ head->sections[i].code = section->flags & SEC_CODE;
+ head->sections[i].data = section->flags & SEC_DATA;
+ if (strcmp (section->name, ".bss") == 0)
+ head->sections[i].data = 1;
+ head->sections[i].address = section->lma;
+ head->sections[i].size = section->_raw_size;
+ head->sections[i].number = idx;
+ head->sections[i].nrelocs = section->reloc_count;
+ head->sections[i].relocs =
+ (struct coff_reloc *) (xcalloc (section->reloc_count,
+ sizeof (struct coff_reloc)));
+ head->sections[i].bfd_section = section;
+ }
+ head->sections[0].name = "ABSOLUTE";
+ head->sections[0].code = 0;
+ head->sections[0].data = 0;
+ head->sections[0].address = 0;
+ head->sections[0].size = 0;
+ head->sections[0].number = 0;
+}
+
+static void
+do_sections_p2 (head)
+ struct coff_ofile *head;
+{
+ asection *section;
+ for (section = abfd->sections; section; section = section->next)
+ {
+ unsigned int j;
+
+ for (j = 0; j < section->reloc_count; j++)
+ {
+ int idx;
+ int i = section->target_index;
+ struct coff_reloc *r = head->sections[i].relocs + j;
+ arelent *sr = section->relocation + j;
+ r->offset = sr->address;
+ r->addend = sr->addend;
+ idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms;
+ r->symbol = tindex[idx];
+ }
+ }
+}
+
+static struct coff_where *
+do_where (i)
+ int i;
+{
+ struct internal_syment *sym = &rawsyms[i].u.syment;
+ struct coff_where *where =
+ (struct coff_where *) (xmalloc (sizeof (struct coff_where)));
+ where->offset = sym->n_value;
+
+ if (sym->n_scnum == -1)
+ sym->n_scnum = 0;
+
+ switch (sym->n_sclass)
+ {
+ case C_FIELD:
+ where->where = coff_where_member_of_struct;
+ where->offset = sym->n_value / 8;
+ where->bitoffset = sym->n_value % 8;
+ where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size;
+ break;
+ case C_MOE:
+ where->where = coff_where_member_of_enum;
+ break;
+ case C_MOS:
+ case C_MOU:
+ where->where = coff_where_member_of_struct;
+ break;
+ case C_AUTO:
+ case C_ARG:
+ where->where = coff_where_stack;
+ break;
+ case C_EXT:
+ case C_STAT:
+ case C_EXTDEF:
+ case C_LABEL:
+ where->where = coff_where_memory;
+ where->section = &ofile->sections[sym->n_scnum];
+ break;
+ case C_REG:
+ case C_REGPARM:
+ where->where = coff_where_register;
+ break;
+ case C_ENTAG:
+ where->where = coff_where_entag;
+ break;
+ case C_STRTAG:
+ case C_UNTAG:
+ where->where = coff_where_strtag;
+ break;
+ case C_TPDEF:
+ where->where = coff_where_typedef;
+ break;
+ default:
+ abort ();
+ break;
+ }
+ return where;
+}
+
+static
+struct coff_line *
+do_lines (i, name)
+ int i;
+ char *name;
+{
+ struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1);
+ asection *s;
+ unsigned int l;
+
+ /* Find out if this function has any line numbers in the table */
+ for (s = abfd->sections; s; s = s->next)
+ {
+ for (l = 0; l < s->lineno_count; l++)
+ {
+ if (s->lineno[l].line_number == 0)
+ {
+ if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native)
+ {
+ /* These lines are for this function - so count them and stick them on */
+ int c = 0;
+ /* Find the linenumber of the top of the function, since coff linenumbers
+ are relative to the start of the function. */
+ int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno;
+
+ l++;
+ for (c = 0; s->lineno[l + c + 1].line_number; c++)
+ ;
+
+ /* Add two extra records, one for the prologue and one for the epilogue */
+ c += 1;
+ res->nlines = c;
+ res->lines = (int *) (xcalloc (sizeof (int), c));
+ res->addresses = (int *) (xcalloc (sizeof (int), c));
+ res->lines[0] = start_line;
+ res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma;
+ for (c = 0; s->lineno[l + c + 1].line_number; c++)
+ {
+ res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1;
+ res->addresses[c + 1] = s->lineno[l + c].u.offset;
+ }
+ return res;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+static
+struct coff_type *
+do_type (i)
+ int i;
+{
+ struct internal_syment *sym = &rawsyms[i].u.syment;
+ union internal_auxent *aux = &rawsyms[i + 1].u.auxent;
+ struct coff_type *res =
+ (struct coff_type *) xmalloc (sizeof (struct coff_type));
+ int type = sym->n_type;
+ int which_dt = 0;
+ int dimind = 0;
+
+ res->type = coff_basic_type;
+ res->u.basic = type & 0xf;
+
+ switch (type & 0xf)
+ {
+ case T_NULL:
+ case T_VOID:
+ if (sym->n_numaux && sym->n_sclass == C_STAT)
+ {
+ /* This is probably a section definition */
+ res->type = coff_secdef_type;
+ res->size = aux->x_scn.x_scnlen;
+ }
+ else
+ {
+ if (type == 0)
+ {
+ /* Don't know what this is, let's make it a simple int */
+ res->size = INT_SIZE;
+ res->u.basic = T_UINT;
+ }
+ else
+ {
+ /* Else it could be a function or pointer to void */
+ res->size = 0;
+ }
+ }
+ break;
+
+
+ break;
+ case T_UCHAR:
+ case T_CHAR:
+ res->size = 1;
+ break;
+ case T_USHORT:
+ case T_SHORT:
+ res->size = SHORT_SIZE;
+ break;
+ case T_UINT:
+ case T_INT:
+ res->size = INT_SIZE;
+ break;
+ case T_ULONG:
+ case T_LONG:
+ res->size = LONG_SIZE;
+ break;
+ case T_FLOAT:
+ res->size = FLOAT_SIZE;
+ break;
+ case T_DOUBLE:
+ res->size = DOUBLE_SIZE;
+ break;
+ case T_STRUCT:
+ case T_UNION:
+ if (sym->n_numaux)
+ {
+ if (aux->x_sym.x_tagndx.p)
+ {
+ /* Refering to a struct defined elsewhere */
+ res->type = coff_structref_type;
+ res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
+ res->size = res->u.astructref.ref ?
+ res->u.astructref.ref->type->size : 0;
+ }
+ else
+ {
+ /* A definition of a struct */
+ last_struct = res;
+ res->type = coff_structdef_type;
+ res->u.astructdef.elements = empty_scope ();
+ res->u.astructdef.idx = 0;
+ res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT;
+ res->size = aux->x_sym.x_misc.x_lnsz.x_size;
+ }
+ }
+ else
+ {
+ /* No auxents - it's anonynmous */
+ res->type = coff_structref_type;
+ res->u.astructref.ref = 0;
+ res->size = 0;
+ }
+ break;
+ case T_ENUM:
+ if (aux->x_sym.x_tagndx.p)
+ {
+ /* Refering to a enum defined elsewhere */
+ res->type = coff_enumref_type;
+ res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)];
+ res->size = res->u.aenumref.ref->type->size;
+ }
+ else
+ {
+ /* A definition of an enum */
+ last_enum = res;
+ res->type = coff_enumdef_type;
+ res->u.aenumdef.elements = empty_scope ();
+ res->size = aux->x_sym.x_misc.x_lnsz.x_size;
+ }
+ break;
+ case T_MOE:
+ break;
+ }
+
+ for (which_dt = 5; which_dt >= 0; which_dt--)
+ {
+ switch ((type >> ((which_dt * 2) + 4)) & 0x3)
+ {
+ case 0:
+ break;
+ case DT_ARY:
+ {
+ struct coff_type *ptr = ((struct coff_type *)
+ xmalloc (sizeof (struct coff_type)));
+ int els = (dimind < DIMNUM
+ ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind]
+ : 0);
+ ++dimind;
+ ptr->type = coff_array_type;
+ ptr->size = els * res->size;
+ ptr->u.array.dim = els;
+ ptr->u.array.array_of = res;
+ res = ptr;
+ break;
+ }
+ case DT_PTR:
+ {
+ struct coff_type *ptr =
+ (struct coff_type *) xmalloc (sizeof (struct coff_type));
+ ptr->size = PTR_SIZE;
+ ptr->type = coff_pointer_type;
+ ptr->u.pointer.points_to = res;
+ res = ptr;
+ break;
+ }
+ case DT_FCN:
+ {
+ struct coff_type *ptr
+ = (struct coff_type *) xmalloc (sizeof (struct coff_type));
+ ptr->size = 0;
+ ptr->type = coff_function_type;
+ ptr->u.function.function_returns = res;
+ ptr->u.function.parameters = empty_scope ();
+ ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]);
+ ptr->u.function.code = 0;
+ last_function_type = ptr;
+ res = ptr;
+ break;
+ }
+ }
+ }
+ return res;
+}
+
+static struct coff_visible *
+do_visible (i)
+ int i;
+{
+ struct internal_syment *sym = &rawsyms[i].u.syment;
+ struct coff_visible *visible =
+ (struct coff_visible *) (xmalloc (sizeof (struct coff_visible)));
+ enum coff_vis_type t;
+ switch (sym->n_sclass)
+ {
+ case C_MOS:
+ case C_MOU:
+ case C_FIELD:
+ t = coff_vis_member_of_struct;
+ break;
+ case C_MOE:
+ t = coff_vis_member_of_enum;
+ break;
+
+ case C_REGPARM:
+ t = coff_vis_regparam;
+ break;
+
+ case C_REG:
+ t = coff_vis_register;
+ break;
+ case C_STRTAG:
+ case C_UNTAG:
+ case C_ENTAG:
+ case C_TPDEF:
+ t = coff_vis_tag;
+ break;
+ case C_AUTOARG:
+ case C_ARG:
+ t = coff_vis_autoparam;
+ break;
+ case C_AUTO:
+
+
+ t = coff_vis_auto;
+ break;
+ case C_LABEL:
+ case C_STAT:
+ t = coff_vis_int_def;
+ break;
+ case C_EXT:
+ if (sym->n_scnum == N_UNDEF)
+ {
+ if (sym->n_value)
+ t = coff_vis_common;
+ else
+ t = coff_vis_ext_ref;
+ }
+ else
+ t = coff_vis_ext_def;
+ break;
+ default:
+ abort ();
+ break;
+
+ }
+ visible->type = t;
+ return visible;
+}
+
+static int
+do_define (i, b)
+ int i;
+ struct coff_scope *b;
+{
+ static int symbol_index;
+ struct internal_syment *sym = &rawsyms[i].u.syment;
+
+ /* Define a symbol and attach to block b */
+ struct coff_symbol *s = empty_symbol ();
+
+ s->number = ++symbol_index;
+ s->name = sym->_n._n_nptr[1];
+ s->sfile = cur_sfile;
+ /* Glue onto the ofile list */
+ if (lofile >= 0)
+ {
+ if (ofile->symbol_list_tail)
+ ofile->symbol_list_tail->next_in_ofile_list = s;
+ else
+ ofile->symbol_list_head = s;
+ ofile->symbol_list_tail = s;
+ /* And the block list */
+ }
+ if (b->vars_tail)
+ b->vars_tail->next = s;
+ else
+ b->vars_head = s;
+
+ b->vars_tail = s;
+ b->nvars++;
+ s->type = do_type (i);
+ s->where = do_where (i);
+ s->visible = do_visible (i);
+
+ tindex[i] = s;
+
+ /* We remember the lowest address in each section for each source file */
+
+ if (s->where->where == coff_where_memory
+ && s->type->type == coff_secdef_type)
+ {
+ struct coff_isection *is = cur_sfile->section + s->where->section->number;
+
+ if (!is->init)
+ {
+ is->low = s->where->offset;
+ is->high = s->where->offset + s->type->size;
+ is->init = 1;
+ is->parent = s->where->section;
+ }
+
+ }
+
+ if (s->type->type == coff_function_type)
+ last_function_symbol = s;
+
+ return i + sym->n_numaux + 1;
+}
+
+
+static
+struct coff_ofile *
+doit ()
+{
+ int i;
+ int infile = 0;
+ struct coff_ofile *head =
+ (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile));
+ ofile = head;
+ head->source_head = 0;
+ head->source_tail = 0;
+ head->nsources = 0;
+ head->symbol_list_tail = 0;
+ head->symbol_list_head = 0;
+ do_sections_p1 (head);
+ push_scope (1);
+
+ for (i = 0; i < rawcount;)
+ {
+ struct internal_syment *sym = &rawsyms[i].u.syment;
+ switch (sym->n_sclass)
+ {
+ case C_FILE:
+ {
+ /* new source file announced */
+ struct coff_sfile *n =
+ (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile));
+ n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1);
+ cur_sfile = n;
+ n->name = sym->_n._n_nptr[1];
+ n->next = 0;
+
+ if (infile)
+ {
+ pop_scope ();
+ }
+ infile = 1;
+ push_scope (1);
+ file_scope = n->scope = top_scope;
+
+ if (head->source_tail)
+ head->source_tail->next = n;
+ else
+ head->source_head = n;
+ head->source_tail = n;
+ head->nsources++;
+ i += sym->n_numaux + 1;
+ }
+ break;
+ case C_FCN:
+ {
+ char *name = sym->_n._n_nptr[1];
+ if (name[1] == 'b')
+ {
+ /* Function start */
+ push_scope (0);
+ last_function_type->u.function.code = top_scope;
+ top_scope->sec = ofile->sections + sym->n_scnum;
+ top_scope->offset = sym->n_value;
+ }
+ else
+ {
+ top_scope->size = sym->n_value - top_scope->offset + 1;
+ pop_scope ();
+
+ }
+ i += sym->n_numaux + 1;
+ }
+ break;
+
+ case C_BLOCK:
+ {
+ char *name = sym->_n._n_nptr[1];
+ if (name[1] == 'b')
+ {
+ /* Block start */
+ push_scope (1);
+ top_scope->sec = ofile->sections + sym->n_scnum;
+ top_scope->offset = sym->n_value;
+
+ }
+ else
+ {
+ top_scope->size = sym->n_value - top_scope->offset + 1;
+ pop_scope ();
+ }
+ i += sym->n_numaux + 1;
+ }
+ break;
+ case C_REGPARM:
+ case C_ARG:
+ i = do_define (i, last_function_symbol->type->u.function.parameters);
+ break;
+ case C_MOS:
+ case C_MOU:
+ case C_FIELD:
+ i = do_define (i, last_struct->u.astructdef.elements);
+ break;
+ case C_MOE:
+ i = do_define (i, last_enum->u.aenumdef.elements);
+ break;
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_UNTAG:
+ /* Various definition */
+ i = do_define (i, top_scope);
+ break;
+ case C_EXT:
+ case C_LABEL:
+ i = do_define (i, file_scope);
+ break;
+ case C_STAT:
+ case C_TPDEF:
+ case C_AUTO:
+ case C_REG:
+ i = do_define (i, top_scope);
+ break;
+ default:
+ abort ();
+ case C_EOS:
+ i += sym->n_numaux + 1;
+ break;
+ }
+ }
+ do_sections_p2 (head);
+ return head;
+}
+
+struct coff_ofile *
+coff_grok (inabfd)
+ bfd *inabfd;
+{
+ long storage;
+ struct coff_ofile *p;
+ abfd = inabfd;
+ storage = bfd_get_symtab_upper_bound (abfd);
+
+ if (storage < 0)
+ bfd_fatal (abfd->filename);
+
+ syms = (asymbol **) xmalloc (storage);
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+ if (symcount < 0)
+ bfd_fatal (abfd->filename);
+ rawsyms = obj_raw_syments (abfd);
+ rawcount = obj_raw_syment_count (abfd);;
+ tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount));
+
+ p = doit ();
+ return p;
+}
diff --git a/binutils/coffgrok.h b/binutils/coffgrok.h
new file mode 100644
index 00000000000..c0ade42a61f
--- /dev/null
+++ b/binutils/coffgrok.h
@@ -0,0 +1,206 @@
+#define T_NULL 0
+#define T_VOID 1 /* function argument (only used by compiler) */
+#define T_CHAR 2 /* character */
+#define T_SHORT 3 /* short integer */
+#define T_INT 4 /* integer */
+#define T_LONG 5 /* long integer */
+#define T_FLOAT 6 /* floating point */
+#define T_DOUBLE 7 /* double word */
+#define T_STRUCT 8 /* structure */
+#define T_UNION 9 /* union */
+#define T_ENUM 10 /* enumeration */
+#define T_MOE 11 /* member of enumeration*/
+#define T_UCHAR 12 /* unsigned character */
+#define T_USHORT 13 /* unsigned short */
+#define T_UINT 14 /* unsigned integer */
+#define T_ULONG 15 /* unsigned long */
+#define T_LNGDBL 16 /* long double */
+
+
+ struct coff_reloc
+ {
+ int offset;
+ struct coff_symbol *symbol;
+ int addend;
+ };
+
+ struct coff_section
+ {
+ char *name;
+ int code;
+ int data;
+ int address;
+ int number; /* 0..n, .text = 0 */
+ int nrelocs;
+ int size;
+ struct coff_reloc *relocs;
+ struct sec *bfd_section;
+ };
+
+struct coff_ofile
+{
+ int nsources;
+ struct coff_sfile *source_head;
+ struct coff_sfile *source_tail;
+ int nsections;
+ struct coff_section *sections;
+ struct coff_symbol *symbol_list_head;
+ struct coff_symbol *symbol_list_tail;
+};
+
+struct coff_isection {
+ int low;
+ int high;
+ int init;
+ struct coff_section *parent;
+};
+
+struct coff_sfile
+{
+ char *name;
+ struct coff_scope *scope;
+ struct coff_sfile *next;
+
+ /* Vector which maps where in each output section
+ the input file has it's data */
+ struct coff_isection *section;
+
+};
+
+
+ struct coff_type
+{
+ int size;
+ enum
+ {
+ coff_pointer_type, coff_function_type, coff_array_type, coff_structdef_type, coff_basic_type,
+ coff_structref_type, coff_enumref_type, coff_enumdef_type, coff_secdef_type
+ } type;
+ union
+ {
+ struct
+ {
+ int address;
+ int size;
+ } asecdef;
+
+ struct
+ {
+ int isstruct;
+ struct coff_scope *elements;
+ int idx;
+ }
+ astructdef;
+ struct
+ {
+ struct coff_symbol *ref;
+ } astructref;
+
+ struct
+ {
+ struct coff_scope *elements;
+ int idx;
+ } aenumdef;
+ struct
+ {
+ struct coff_symbol *ref;
+ } aenumref;
+
+ struct
+ {
+ struct coff_type *points_to;
+ } pointer;
+ struct
+ {
+ int dim;
+ struct coff_type *array_of;
+ } array;
+
+ struct
+ {
+ struct coff_type *function_returns;
+ struct coff_scope *parameters;
+ struct coff_scope *code;
+ struct coff_line *lines;
+ } function;
+ int basic; /* One of T_VOID.. T_UINT */
+ } u;
+};
+
+
+ struct coff_line
+ {
+ int nlines;
+ int *lines;
+ int *addresses;
+ };
+
+
+ struct coff_scope
+ {
+ struct coff_section *sec; /* What section */
+ int offset; /* where */
+ int size; /* How big */
+ struct coff_scope *parent; /* one up */
+
+ struct coff_scope *next; /*next along */
+
+ int nvars;
+
+ struct coff_symbol *vars_head; /* symbols */
+ struct coff_symbol *vars_tail;
+
+ struct coff_scope *list_head; /* children */
+ struct coff_scope *list_tail;
+
+ };
+
+
+ struct coff_visible
+ {
+ enum coff_vis_type
+ {
+ coff_vis_ext_def,
+ coff_vis_ext_ref,
+ coff_vis_int_def,
+ coff_vis_common,
+ coff_vis_auto,
+ coff_vis_register,
+ coff_vis_tag,
+ coff_vis_member_of_struct,
+ coff_vis_member_of_enum,
+ coff_vis_autoparam,
+ coff_vis_regparam,
+ } type;
+ };
+
+ struct coff_where
+ {
+ enum
+ {
+ coff_where_stack, coff_where_memory, coff_where_register, coff_where_unknown,
+ coff_where_strtag, coff_where_member_of_struct,
+ coff_where_member_of_enum, coff_where_entag, coff_where_typedef
+
+ } where;
+ int offset;
+ int bitoffset;
+ int bitsize;
+ struct coff_section *section;
+ };
+
+ struct coff_symbol
+ {
+ char *name;
+ int tag;
+ struct coff_type *type;
+ struct coff_where *where;
+ struct coff_visible *visible;
+ struct coff_symbol *next;
+ struct coff_symbol *next_in_ofile_list; /* For the ofile list */
+ int number;
+ int er_number;
+ struct coff_sfile *sfile;
+ };
+
+struct coff_ofile *coff_grok();
diff --git a/binutils/config.in b/binutils/config.in
new file mode 100644
index 00000000000..38272ddfa58
--- /dev/null
+++ b/binutils/config.in
@@ -0,0 +1,183 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the sbrk function. */
+#undef HAVE_SBRK
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the utimes function. */
+#undef HAVE_UTIMES
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Is the type time_t defined in <time.h>? */
+#undef HAVE_TIME_T_IN_TIME_H
+
+/* Is the type time_t defined in <sys/types.h>? */
+#undef HAVE_TIME_T_IN_TYPES_H
+
+/* Does <utime.h> define struct utimbuf? */
+#undef HAVE_GOOD_UTIME_H
+
+/* Define if fprintf is not declared in system header files. */
+#undef NEED_DECLARATION_FPRINTF
+
+/* Define if strstr is not declared in system header files. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Define if sbrk is not declared in system header files. */
+#undef NEED_DECLARATION_SBRK
+
+/* Define if getenv is not declared in system header files. */
+#undef NEED_DECLARATION_GETENV
+
+/* Define if environ is not declared in system header files. */
+#undef NEED_DECLARATION_ENVIRON
+
+/* Use b modifier when opening binary files? */
+#undef USE_BINARY_FOPEN
+
+/* Configured target name. */
+#undef TARGET
+
diff --git a/binutils/configure b/binutils/configure
new file mode 100755
index 00000000000..594e154f303
--- /dev/null
+++ b/binutils/configure
@@ -0,0 +1,5567 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock force libtool not to do file locking"
+ac_help="$ac_help
+ --enable-targets alternative target configurations"
+ac_help="$ac_help
+ --enable-commonbfdlib build shared BFD/opcodes/libiberty library"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=ar.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:594: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:615: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:633: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:668: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:721: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:778: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=binutils
+
+VERSION=2.9.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:824: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:837: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:850: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:863: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:876: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:962: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:992: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1022: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1073: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1105: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1116 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1147: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1152: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1180: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1223: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1247: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1250: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1286: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1302: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:1340: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* \($ac_symcode\) *\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if { (eval echo configure:1407: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:1459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+echo "$ac_t""$ac_result" 1>&6
+
+echo $ac_n "checking for _ prefix in compiled symbols""... $ac_c" 1>&6
+echo "configure:1505: checking for _ prefix in compiled symbols" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_symbol_underscore'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if { (eval echo configure:1514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { (eval echo configure:1517: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -rf conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_sys_symbol_underscore" 1>&6
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1543: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1585 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1586: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1607: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1612 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1642: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1674: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ DLLTOOL="false"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1709: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1741: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ AS="false"
+fi
+fi
+
+
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ need_locks=$enableval
+else
+ need_locks=yes
+fi
+
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+ case "${enableval}" in
+ yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; }
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi
+# Check whether --enable-commonbfdlib or --disable-commonbfdlib was given.
+if test "${enable_commonbfdlib+set}" = set; then
+ enableval="$enable_commonbfdlib"
+ case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) { echo "configure: error: bad value ${enableval} for BFD commonbfdlib option" 1>&2; exit 1; } ;;
+esac
+fi
+
+
+
+
+
+if test -z "$target" ; then
+ { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; }
+fi
+if test -z "$host" ; then
+ { echo "configure: error: Unrecognized host system type; please check config.sub." 1>&2; exit 1; }
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1906: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1936: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1987: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2019: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2030 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2035: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2061: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2066: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2075: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2094: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2131: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2162: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2177 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2194 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2200: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2211 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+missing_dir=`cd $ac_aux_dir && pwd`
+for ac_prog in flex lex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2247: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=""$missing_dir/missing flex""
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2280: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:2314: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2322 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:2333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:2356: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:2377: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 2389 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+ cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+
+ALL_LINGUAS=
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:2420: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2441: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2446 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2454: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2471 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2489 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2510 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2521: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2545: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2550 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2599: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2620: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 2627 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2634: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2660: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2665 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2693: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2698 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:2728: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2733 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:2740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:2761: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2766 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:2794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2826: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2831 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2856: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2861 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2911: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2919 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2963: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2968 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2973: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3002: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3007 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:3055: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3063 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:3203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3231: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3236 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3241: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3271: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3276 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3328: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3333 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:3390: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3395 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:3402: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:3423: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:3443: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:3462: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3467 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3472: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:3489: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3494 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3501: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:3517: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3525 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:3536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:3552: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3557 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3592: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3626: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3631 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3681: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3717: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 3749 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:3757: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3789: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3823: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3859: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:3949: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:3977: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3982 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3987: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:4050: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:4073: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4078 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:4089: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:4106: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4111 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:4118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:4137: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:4147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+# host-specific stuff:
+
+HDEFINES=
+
+. ${srcdir}/../bfd/configure.host
+
+
+AR=${AR-ar}
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4180: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:4219: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test -z "$CC_FOR_BUILD"; then
+ if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD='$(CC)'
+ else
+ CC_FOR_BUILD=gcc
+ fi
+fi
+
+# Also set EXEEXT_FOR_BUILD.
+if test "x$cross_compiling" = "xno"; then
+ EXEEXT_FOR_BUILD='$(EXEEXT)'
+else
+ echo $ac_n "checking for build system executable suffix""... $ac_c" 1>&6
+echo "configure:4286: checking for build system executable suffix" >&5
+if eval "test \"`echo '$''{'bfd_cv_build_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > ac_c_test.c << 'EOF'
+int main() {
+/* Nothing needed here */
+}
+EOF
+ ${CC_FOR_BUILD} -o ac_c_test am_c_test.c 1>&5 2>&5
+ bfd_cv_build_exeext=`echo ac_c_test.* | grep -v ac_c_test.c | sed -e s/ac_c_test//`
+ rm -f ac_c_test*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no
+fi
+
+echo "$ac_t""$bfd_cv_build_exeext" 1>&6
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+
+
+for ac_hdr in string.h strings.h stdlib.h unistd.h fcntl.h sys/file.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4311: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4316 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4321: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:4348: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4353 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:4369: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:4392: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4397 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:4404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:4425: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4430 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:4458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:4490: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4495 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4520: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4525 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:4575: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4583 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:4602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_func in sbrk utimes
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4626: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4631 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for time_t in time.h""... $ac_c" 1>&6
+echo "configure:4680: checking for time_t in time.h" >&5
+if eval "test \"`echo '$''{'bu_cv_decl_time_t_time_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4685 "configure"
+#include "confdefs.h"
+#include <time.h>
+int main() {
+time_t i;
+; return 0; }
+EOF
+if { (eval echo configure:4692: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bu_cv_decl_time_t_time_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bu_cv_decl_time_t_time_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bu_cv_decl_time_t_time_h" 1>&6
+if test $bu_cv_decl_time_t_time_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIME_T_IN_TIME_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for time_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:4713: checking for time_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'bu_cv_decl_time_t_types_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4718 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+time_t i;
+; return 0; }
+EOF
+if { (eval echo configure:4725: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bu_cv_decl_time_t_types_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bu_cv_decl_time_t_types_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bu_cv_decl_time_t_types_h" 1>&6
+if test $bu_cv_decl_time_t_types_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TIME_T_IN_TYPES_H 1
+EOF
+
+fi
+
+# Under Next 3.2 <utime.h> apparently does not define struct utimbuf
+# by default.
+echo $ac_n "checking for utime.h""... $ac_c" 1>&6
+echo "configure:4748: checking for utime.h" >&5
+if eval "test \"`echo '$''{'bu_cv_header_utime_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4753 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#include <utime.h>
+int main() {
+struct utimbuf s;
+; return 0; }
+EOF
+if { (eval echo configure:4764: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bu_cv_header_utime_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bu_cv_header_utime_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bu_cv_header_utime_h" 1>&6
+if test $bu_cv_header_utime_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GOOD_UTIME_H 1
+EOF
+
+fi
+
+echo $ac_n "checking whether fprintf must be declared""... $ac_c" 1>&6
+echo "configure:4785: checking whether fprintf must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_fprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4790 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) fprintf
+; return 0; }
+EOF
+if { (eval echo configure:4811: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_fprintf=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_fprintf=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_fprintf" 1>&6
+if test $bfd_cv_decl_needed_fprintf = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_FPRINTF 1
+EOF
+
+fi
+
+echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6
+echo "configure:4832: checking whether strstr must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4837 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strstr
+; return 0; }
+EOF
+if { (eval echo configure:4858: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strstr" 1>&6
+if test $bfd_cv_decl_needed_strstr = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRSTR 1
+EOF
+
+fi
+
+echo $ac_n "checking whether sbrk must be declared""... $ac_c" 1>&6
+echo "configure:4879: checking whether sbrk must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_sbrk'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4884 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) sbrk
+; return 0; }
+EOF
+if { (eval echo configure:4905: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_sbrk=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_sbrk=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_sbrk" 1>&6
+if test $bfd_cv_decl_needed_sbrk = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_SBRK 1
+EOF
+
+fi
+
+echo $ac_n "checking whether getenv must be declared""... $ac_c" 1>&6
+echo "configure:4926: checking whether getenv must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_getenv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4931 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) getenv
+; return 0; }
+EOF
+if { (eval echo configure:4952: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_getenv=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_getenv=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_getenv" 1>&6
+if test $bfd_cv_decl_needed_getenv = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_GETENV 1
+EOF
+
+fi
+
+echo $ac_n "checking whether environ must be declared""... $ac_c" 1>&6
+echo "configure:4973: checking whether environ must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_environ'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4978 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) environ
+; return 0; }
+EOF
+if { (eval echo configure:4999: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_environ=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_environ=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_environ" 1>&6
+if test $bfd_cv_decl_needed_environ = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_ENVIRON 1
+EOF
+
+fi
+
+
+
+case "${host}" in
+*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows)
+ cat >> confdefs.h <<\EOF
+#define USE_BINARY_FOPEN 1
+EOF
+ ;;
+esac
+
+# target-specific stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets"; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ 2>/dev/null`
+ if test -n "$result"; then
+ canon_targets="$canon_targets $result"
+ else
+ # Allow targets that config.sub doesn't recognize, like "all".
+ canon_targets="$canon_targets $targ"
+ fi
+ done
+fi
+
+all_targets=false
+BUILD_NLMCONV=
+NLMCONV_DEFS=
+BUILD_SRCONV=
+BUILD_DLLTOOL=
+DLLTOOL_DEFS=
+BUILD_WINDRES=
+BUILD_DLLWRAP=
+BUILD_MISC=
+
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall"; then
+ all_targets=true
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ BUILD_SRCONV='$(SRCONV_PROG)'
+ NLMCONV_DEFS="-DNLMCONV_I386 -DNLMCONV_ALPHA -DNLMCONV_POWERPC -DNLMCONV_SPARC"
+ else
+ case $targ in
+ i[3456]86*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_I386"
+ ;;
+ alpha*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_ALPHA"
+ ;;
+ powerpc*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_POWERPC"
+ ;;
+ sparc*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_SPARC"
+ ;;
+ esac
+ case $targ in
+ *-*-hms*) BUILD_SRCONV='$(SRCONV_PROG)' ;;
+ esac
+ case $targ in
+ arm-*pe*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ ;;
+ thumb-*pe*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ ;;
+ i[3-6]86-*pe* | i[3-6]86-*-cygwin* | i[3-6]86-*-mingw32*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ ;;
+ powerpc*-*-*pe* | powerpc*-*-cygwin*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_PPC"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ ;;
+ esac
+ fi
+done
+
+
+
+
+
+
+
+
+
+
+cat >> confdefs.h <<EOF
+#define TARGET "${target}"
+EOF
+
+
+targ=$target
+. $srcdir/../bfd/config.bfd
+if test "x$targ_underscore" = "xyes"; then
+ UNDERSCORE=1
+else
+ UNDERSCORE=0
+fi
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile po/Makefile.in:po/Make-in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@USE_SYMBOL_UNDERSCORE@%$USE_SYMBOL_UNDERSCORE%g
+s%@LN_S@%$LN_S%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@CPP@%$CPP%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@HDEFINES@%$HDEFINES%g
+s%@AR@%$AR%g
+s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g
+s%@EXEEXT_FOR_BUILD@%$EXEEXT_FOR_BUILD%g
+s%@NLMCONV_DEFS@%$NLMCONV_DEFS%g
+s%@BUILD_NLMCONV@%$BUILD_NLMCONV%g
+s%@BUILD_SRCONV@%$BUILD_SRCONV%g
+s%@BUILD_DLLTOOL@%$BUILD_DLLTOOL%g
+s%@DLLTOOL_DEFS@%$DLLTOOL_DEFS%g
+s%@BUILD_WINDRES@%$BUILD_WINDRES%g
+s%@BUILD_DLLWRAP@%$BUILD_DLLWRAP%g
+s%@BUILD_MISC@%$BUILD_MISC%g
+s%@UNDERSCORE@%$UNDERSCORE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile po/Makefile.in:po/Make-in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+case "x$CONFIG_FILES" in
+*) sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile ;;
+esac
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/binutils/configure.bat b/binutils/configure.bat
new file mode 100755
index 00000000000..f7d70f1150b
--- /dev/null
+++ b/binutils/configure.bat
@@ -0,0 +1,63 @@
+@echo off
+if "%1" == "h8/300" goto h8300
+
+echo Configuring binutils for go32
+update ../bfd/hosts/go32.h sysdep.h
+goto common
+
+:h8300
+echo Configuring binutils for H8/300
+update ..\bfd\hosts\h-go32.h sysdep.h
+
+:common
+
+echo # Makefile generated by "configure.bat"> Makefile
+
+if exist config.sed del config.sed
+
+sed -n "/^VERSION=/ p" Makefile.in | sed -e "s/^/s^/" -e "s/=/^\"/" -e "s/$/\"^/" > config.sed
+sed -f config.sed version.c > version2.c
+
+if exist config.sed del config.sed
+
+echo "s/version\./version2\./g ">> config.sed
+echo "s/-DVERSION=[^ ]* // ">> config.sed
+
+echo "s/^ \$(srcdir)\/move-if-change/ update/ ">> config.sed
+echo "/^###$/ i\ ">> config.sed
+echo "CC = gcc ">> config.sed
+echo "s/:\([^ ]\)/: \1/g ">> config.sed
+echo "s/^ \ *\.\// go32 / ">> config.sed
+echo "s/`echo \$(srcdir)\///g ">> config.sed
+echo "s/ | sed 's,\^\\\.\/,,'`//g ">> config.sed
+echo "s/^ cd \$(srcdir)[ ]*;// ">> config.sed
+
+echo "/^arparse\.c/ i\ ">> config.sed
+echo "arparse.o: arparse.c\ ">> config.sed
+echo " $(CC) -c $(CFLAGS) $(INCLUDES) $(HDEFINES) $(TDEFINES) arparse.c ">> config.sed
+echo "/\$(BISON)/ c\ ">> config.sed
+echo " bison $(BISONFLAGS) -o $@ arparse.y ">> config.sed
+echo "/y\.tab\./ d ">> config.sed
+
+echo "/^arlex.c/ { ">> config.sed
+echo " i\ ">> config.sed
+echo "arlex.o: arlex.c ">> config.sed
+echo " i\ ">> config.sed
+echo " $(CC) -c $(CFLAGS) $(INCLUDES) $(HDEFINES) $(TDEFINES) arlex.c ">> config.sed
+echo "} ">> config.sed
+echo "/\$(LEX)/ c\ ">> config.sed
+echo " flex $(LEX_OPTIONS) arlex.l ">> config.sed
+echo "s/lex\.yy\./lexyy./g ">> config.sed
+
+echo "s/'"/\\"/g ">> config.sed
+echo "s/"'/\\"/g ">> config.sed
+
+echo "s/c++filt/cxxfilt/g ">> config.sed
+
+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
+sed -f config2.sed Makefile.in >> Makefile
+del config.sed
+del config2.sed
+
+echo int prepends_underscore = 1; > underscore.c
+
diff --git a/binutils/configure.com b/binutils/configure.com
new file mode 100644
index 00000000000..99463d5ecdb
--- /dev/null
+++ b/binutils/configure.com
@@ -0,0 +1,76 @@
+$!
+$! This file configures binutils for use with openVMS/Alpha
+$! We do not use the configure script, since we do not have /bin/sh
+$! to execute it.
+$!
+$! Written by Klaus K"ampf (kkaempf@rmi.de)
+$!
+$arch_indx = 1 + ((f$getsyi("CPU").ge.128).and.1) ! vax==1, alpha==2
+$arch = f$element(arch_indx,"|","|VAX|Alpha|")
+$!
+$!
+$! Generate config.h
+$!
+$ create []config.h
+/* config.h. Generated automatically by configure. */
+/* config.in. Generated automatically from configure.in by autoheader. */
+/* Is the type time_t defined in <time.h>? */
+#define HAVE_TIME_T_IN_TIME_H 1
+/* Is the type time_t defined in <sys/types.h>? */
+#define HAVE_TIME_T_IN_TYPES_H 1
+/* Does <utime.h> define struct utimbuf? */
+#define HAVE_GOOD_UTIME_H 1
+/* Whether fprintf must be declared even if <stdio.h> is included. */
+#define NEED_DECLARATION_FPRINTF 1
+/* Whether sbrk must be declared even if <unistd.h> is included. */
+#undef NEED_DECLARATION_SBRK
+/* Do we need to use the b modifier when opening binary files? */
+/* #undef USE_BINARY_FOPEN */
+/* Define if you have the sbrk function. */
+/* #undef HAVE_SBRK 1 */
+/* Define if you have the utimes function. */
+#define HAVE_UTIMES 1
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+$ write sys$output "Generated `config.h'"
+$!
+$!
+$! Edit VERSION in makefile.vms-in
+$!
+$ edit/tpu/nojournal/nosection/nodisplay/command=sys$input -
+ []makefile.vms-in /output=[]makefile.vms
+$DECK
+!
+! Get VERSION from configure.in
+!
+ mfile := CREATE_BUFFER("mfile", "CONFIGURE.IN");
+ rang := CREATE_RANGE(BEGINNING_OF(mfile), END_OF(mfile));
+ match_pos := SEARCH_QUIETLY('AM_INIT_AUTOMAKE(binutils, ', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ vers := CURRENT_LINE-")";
+ ELSE;
+ vers := "unknown";
+ ENDIF;
+
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
+ match_pos := SEARCH_QUIETLY('@VERSION@', FORWARD, EXACT, rang);
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT(vers);
+ WRITE_FILE(file, GET_INFO(COMMAND_LINE, "output_file"));
+ QUIT
+$ EOD
+$ write sys$output "Created `makefile.vms'"
diff --git a/binutils/configure.in b/binutils/configure.in
new file mode 100644
index 00000000000..298dcd89c64
--- /dev/null
+++ b/binutils/configure.in
@@ -0,0 +1,221 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+AC_PREREQ(2.13)
+AC_INIT(ar.c)
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE(binutils, 2.9.4)
+
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(targets,
+[ --enable-targets alternative target configurations],
+[case "${enableval}" in
+ yes | "") AC_ERROR(enable-targets option must specify target names or 'all')
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac])dnl
+AC_ARG_ENABLE(commonbfdlib,
+[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library],
+[case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for BFD commonbfdlib option]) ;;
+esac])dnl
+
+AM_CONFIG_HEADER(config.h:config.in)
+
+if test -z "$target" ; then
+ AC_MSG_ERROR(Unrecognized target system type; please check config.sub.)
+fi
+if test -z "$host" ; then
+ AC_MSG_ERROR(Unrecognized host system type; please check config.sub.)
+fi
+
+AC_PROG_CC
+
+AC_PROG_YACC
+AM_PROG_LEX
+
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+# host-specific stuff:
+
+HDEFINES=
+
+. ${srcdir}/../bfd/configure.host
+
+AC_SUBST(HDEFINES)
+AR=${AR-ar}
+AC_SUBST(AR)
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+
+BFD_CC_FOR_BUILD
+
+AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h fcntl.h sys/file.h)
+AC_HEADER_SYS_WAIT
+AC_FUNC_ALLOCA
+AC_CHECK_FUNCS(sbrk utimes)
+
+AC_MSG_CHECKING(for time_t in time.h)
+AC_CACHE_VAL(bu_cv_decl_time_t_time_h,
+[AC_TRY_COMPILE([#include <time.h>], [time_t i;],
+bu_cv_decl_time_t_time_h=yes, bu_cv_decl_time_t_time_h=no)])
+AC_MSG_RESULT($bu_cv_decl_time_t_time_h)
+if test $bu_cv_decl_time_t_time_h = yes; then
+ AC_DEFINE([HAVE_TIME_T_IN_TIME_H], 1,
+ [Is the type time_t defined in <time.h>?])
+fi
+
+AC_MSG_CHECKING(for time_t in sys/types.h)
+AC_CACHE_VAL(bu_cv_decl_time_t_types_h,
+[AC_TRY_COMPILE([#include <sys/types.h>], [time_t i;],
+bu_cv_decl_time_t_types_h=yes, bu_cv_decl_time_t_types_h=no)])
+AC_MSG_RESULT($bu_cv_decl_time_t_types_h)
+if test $bu_cv_decl_time_t_types_h = yes; then
+ AC_DEFINE([HAVE_TIME_T_IN_TYPES_H], 1,
+ [Is the type time_t defined in <sys/types.h>?])
+fi
+
+# Under Next 3.2 <utime.h> apparently does not define struct utimbuf
+# by default.
+AC_MSG_CHECKING([for utime.h])
+AC_CACHE_VAL(bu_cv_header_utime_h,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#include <utime.h>],
+[struct utimbuf s;],
+bu_cv_header_utime_h=yes, bu_cv_header_utime_h=no)])
+AC_MSG_RESULT($bu_cv_header_utime_h)
+if test $bu_cv_header_utime_h = yes; then
+ AC_DEFINE(HAVE_GOOD_UTIME_H, 1, [Does <utime.h> define struct utimbuf?])
+fi
+
+BFD_NEED_DECLARATION(fprintf)
+BFD_NEED_DECLARATION(strstr)
+BFD_NEED_DECLARATION(sbrk)
+BFD_NEED_DECLARATION(getenv)
+BFD_NEED_DECLARATION(environ)
+
+BFD_BINARY_FOPEN
+
+# target-specific stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets"; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ 2>/dev/null`
+ if test -n "$result"; then
+ canon_targets="$canon_targets $result"
+ else
+ # Allow targets that config.sub doesn't recognize, like "all".
+ canon_targets="$canon_targets $targ"
+ fi
+ done
+fi
+
+all_targets=false
+BUILD_NLMCONV=
+NLMCONV_DEFS=
+BUILD_SRCONV=
+BUILD_DLLTOOL=
+DLLTOOL_DEFS=
+BUILD_WINDRES=
+BUILD_DLLWRAP=
+BUILD_MISC=
+
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall"; then
+ all_targets=true
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ BUILD_SRCONV='$(SRCONV_PROG)'
+ NLMCONV_DEFS="-DNLMCONV_I386 -DNLMCONV_ALPHA -DNLMCONV_POWERPC -DNLMCONV_SPARC"
+ else
+ case $targ in
+changequote(,)dnl
+ i[3456]86*-*-netware*)
+changequote([,])dnl
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_I386"
+ ;;
+ alpha*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_ALPHA"
+ ;;
+ powerpc*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_POWERPC"
+ ;;
+ sparc*-*-netware*)
+ BUILD_NLMCONV='$(NLMCONV_PROG)$(EXEEXT)'
+ NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_SPARC"
+ ;;
+ esac
+ case $targ in
+ *-*-hms*) BUILD_SRCONV='$(SRCONV_PROG)' ;;
+ esac
+ case $targ in
+ arm-*pe*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ ;;
+ thumb-*pe*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ ;;
+changequote(,)dnl
+ i[3-6]86-*pe* | i[3-6]86-*-cygwin* | i[3-6]86-*-mingw32*)
+changequote([,])dnl
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ ;;
+ powerpc*-*-*pe* | powerpc*-*-cygwin*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_PPC"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ ;;
+ esac
+ fi
+done
+
+AC_SUBST(NLMCONV_DEFS)
+AC_SUBST(BUILD_NLMCONV)
+AC_SUBST(BUILD_SRCONV)
+AC_SUBST(BUILD_DLLTOOL)
+AC_SUBST(DLLTOOL_DEFS)
+AC_SUBST(BUILD_WINDRES)
+AC_SUBST(BUILD_DLLWRAP)
+AC_SUBST(BUILD_MISC)
+
+AC_DEFINE_UNQUOTED(TARGET, "${target}", [Configured target name.])
+
+targ=$target
+. $srcdir/../bfd/config.bfd
+if test "x$targ_underscore" = "xyes"; then
+ UNDERSCORE=1
+else
+ UNDERSCORE=0
+fi
+AC_SUBST(UNDERSCORE)
+
+AC_OUTPUT(Makefile po/Makefile.in:po/Make-in,
+[
+case "x$CONFIG_FILES" in
+*) sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile ;;
+esac
+])
diff --git a/binutils/cxxfilt.man b/binutils/cxxfilt.man
new file mode 100644
index 00000000000..a4d5d45106b
--- /dev/null
+++ b/binutils/cxxfilt.man
@@ -0,0 +1,114 @@
+.\" Copyright (c) 1991 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH @PROGRAM@ 1 "June 1993" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+@PROGRAM@ \- demangle C++ symbols
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B @PROGRAM@
+.RB "[\|" \-_ | \-\-strip-underscores "\|]"
+.RB "[\|" "\-s {gnu,lucid,arm} " | " \-\-format={gnu,lucid,arm}" "\|]"
+.RB "[\|" \-\-help "\|]"
+.RB "[\|" \-\-version "\|]"
+.RB "[\|" symbol "...\|]"
+.SH DESCRIPTION
+The C++ language provides function overloading, which means that you can
+write many functions with the same name (providing each takes parameters
+of different types). All C++ function names are encoded into a
+low-level assembly label (this process is known as
+.I mangling\c
+). The
+.B @PROGRAM@
+program does the inverse mapping: it decodes (\fIdemangles\fR)
+low-level names into user-level names so that the linker can keep
+these overloaded functions from clashing.
+.PP
+Every alphanumeric word (consisting of letters, digits, underscores,
+dollars, or periods) seen in the input is a potential label. If the
+label decodes into a C++ name, the C++ name replaces the low-level
+name in the output.
+.PP
+You can use
+.B @PROGRAM@
+to decipher individual symbols by specifying these symbols on the
+command line.
+.PP
+If no
+.B symbol
+arguments are given,
+.B @PROGRAM@
+reads symbol names from the standard input and writes the demangled
+names to the standard output. All results are printed on the standard
+output.
+.SH OPTIONS
+.TP
+.B \-_
+.TP
+.B \-\-strip\-underscores
+On some systems, both the C and C++ compilers put an
+underscore in front of every name. For example, the C name
+.B foo
+gets the low-level name
+.BR _foo .
+This option removes the leading underscore.
+
+.TP
+.B "\-s {gnu,lucid,arm}"
+.TP
+.B \-\-format={gnu,lucid,arm}
+GNU
+.B nm
+can decode three different methods of mangling, used by different C++
+compilers. This option selects which method it uses: the one used by
+the GNU compiler, the one used by the Lucid compiler, or the one
+specified by the C++ Annotated Reference Manual. The default is the
+GNU style.
+
+.TP
+.B \-\-help
+Print a summary of the options to
+.B @PROGRAM@
+and exit.
+
+.TP
+.B \-\-version
+Print the version number of
+.B @PROGRAM@
+and exit.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (June 1993).
+
+.SH COPYING
+Copyright (c) 1993 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/debug.c b/binutils/debug.c
new file mode 100644
index 00000000000..173d6273887
--- /dev/null
+++ b/binutils/debug.c
@@ -0,0 +1,3568 @@
+/* debug.c -- Handle generic debugging information.
+ Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file implements a generic debugging format. We may eventually
+ have readers which convert different formats into this generic
+ format, and writers which write it out. The initial impetus for
+ this was writing a convertor from stabs to HP IEEE-695 debugging
+ format. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "debug.h"
+
+/* Global information we keep for debugging. A pointer to this
+ structure is the debugging handle passed to all the routines. */
+
+struct debug_handle
+{
+ /* A linked list of compilation units. */
+ struct debug_unit *units;
+ /* The current compilation unit. */
+ struct debug_unit *current_unit;
+ /* The current source file. */
+ struct debug_file *current_file;
+ /* The current function. */
+ struct debug_function *current_function;
+ /* The current block. */
+ struct debug_block *current_block;
+ /* The current line number information for the current unit. */
+ struct debug_lineno *current_lineno;
+ /* Mark. This is used by debug_write. */
+ unsigned int mark;
+ /* A struct/class ID used by debug_write. */
+ unsigned int class_id;
+ /* The base for class_id for this call to debug_write. */
+ unsigned int base_id;
+ /* The current line number in debug_write. */
+ struct debug_lineno *current_write_lineno;
+ unsigned int current_write_lineno_index;
+ /* A list of classes which have assigned ID's during debug_write.
+ This is linked through the next_id field of debug_class_type. */
+ struct debug_class_id *id_list;
+ /* A list used to avoid recursion during debug_type_samep. */
+ struct debug_type_compare_list *compare_list;
+};
+
+/* Information we keep for a single compilation unit. */
+
+struct debug_unit
+{
+ /* The next compilation unit. */
+ struct debug_unit *next;
+ /* A list of files included in this compilation unit. The first
+ file is always the main one, and that is where the main file name
+ is stored. */
+ struct debug_file *files;
+ /* Line number information for this compilation unit. This is not
+ stored by function, because assembler code may have line number
+ information without function information. */
+ struct debug_lineno *linenos;
+};
+
+/* Information kept for a single source file. */
+
+struct debug_file
+{
+ /* The next source file in this compilation unit. */
+ struct debug_file *next;
+ /* The name of the source file. */
+ const char *filename;
+ /* Global functions, variables, types, etc. */
+ struct debug_namespace *globals;
+};
+
+/* A type. */
+
+struct debug_type
+{
+ /* Kind of type. */
+ enum debug_type_kind kind;
+ /* Size of type (0 if not known). */
+ unsigned int size;
+ /* Type which is a pointer to this type. */
+ debug_type pointer;
+ /* Tagged union with additional information about the type. */
+ union
+ {
+ /* DEBUG_KIND_INDIRECT. */
+ struct debug_indirect_type *kindirect;
+ /* DEBUG_KIND_INT. */
+ /* Whether the integer is unsigned. */
+ boolean kint;
+ /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
+ DEBUG_KIND_UNION_CLASS. */
+ struct debug_class_type *kclass;
+ /* DEBUG_KIND_ENUM. */
+ struct debug_enum_type *kenum;
+ /* DEBUG_KIND_POINTER. */
+ struct debug_type *kpointer;
+ /* DEBUG_KIND_FUNCTION. */
+ struct debug_function_type *kfunction;
+ /* DEBUG_KIND_REFERENCE. */
+ struct debug_type *kreference;
+ /* DEBUG_KIND_RANGE. */
+ struct debug_range_type *krange;
+ /* DEBUG_KIND_ARRAY. */
+ struct debug_array_type *karray;
+ /* DEBUG_KIND_SET. */
+ struct debug_set_type *kset;
+ /* DEBUG_KIND_OFFSET. */
+ struct debug_offset_type *koffset;
+ /* DEBUG_KIND_METHOD. */
+ struct debug_method_type *kmethod;
+ /* DEBUG_KIND_CONST. */
+ struct debug_type *kconst;
+ /* DEBUG_KIND_VOLATILE. */
+ struct debug_type *kvolatile;
+ /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */
+ struct debug_named_type *knamed;
+ } u;
+};
+
+/* Information kept for an indirect type. */
+
+struct debug_indirect_type
+{
+ /* Slot where the final type will appear. */
+ debug_type *slot;
+ /* Tag. */
+ const char *tag;
+};
+
+/* Information kept for a struct, union, or class. */
+
+struct debug_class_type
+{
+ /* NULL terminated array of fields. */
+ debug_field *fields;
+ /* A mark field which indicates whether the struct has already been
+ printed. */
+ unsigned int mark;
+ /* This is used to uniquely identify unnamed structs when printing. */
+ unsigned int id;
+ /* The remaining fields are only used for DEBUG_KIND_CLASS and
+ DEBUG_KIND_UNION_CLASS. */
+ /* NULL terminated array of base classes. */
+ debug_baseclass *baseclasses;
+ /* NULL terminated array of methods. */
+ debug_method *methods;
+ /* The type of the class providing the virtual function table for
+ this class. This may point to the type itself. */
+ debug_type vptrbase;
+};
+
+/* Information kept for an enum. */
+
+struct debug_enum_type
+{
+ /* NULL terminated array of names. */
+ const char **names;
+ /* Array of corresponding values. */
+ bfd_signed_vma *values;
+};
+
+/* Information kept for a function. FIXME: We should be able to
+ record the parameter types. */
+
+struct debug_function_type
+{
+ /* Return type. */
+ debug_type return_type;
+ /* NULL terminated array of argument types. */
+ debug_type *arg_types;
+ /* Whether the function takes a variable number of arguments. */
+ boolean varargs;
+};
+
+/* Information kept for a range. */
+
+struct debug_range_type
+{
+ /* Range base type. */
+ debug_type type;
+ /* Lower bound. */
+ bfd_signed_vma lower;
+ /* Upper bound. */
+ bfd_signed_vma upper;
+};
+
+/* Information kept for an array. */
+
+struct debug_array_type
+{
+ /* Element type. */
+ debug_type element_type;
+ /* Range type. */
+ debug_type range_type;
+ /* Lower bound. */
+ bfd_signed_vma lower;
+ /* Upper bound. */
+ bfd_signed_vma upper;
+ /* Whether this array is really a string. */
+ boolean stringp;
+};
+
+/* Information kept for a set. */
+
+struct debug_set_type
+{
+ /* Base type. */
+ debug_type type;
+ /* Whether this set is really a bitstring. */
+ boolean bitstringp;
+};
+
+/* Information kept for an offset type (a based pointer). */
+
+struct debug_offset_type
+{
+ /* The type the pointer is an offset from. */
+ debug_type base_type;
+ /* The type the pointer points to. */
+ debug_type target_type;
+};
+
+/* Information kept for a method type. */
+
+struct debug_method_type
+{
+ /* The return type. */
+ debug_type return_type;
+ /* The object type which this method is for. */
+ debug_type domain_type;
+ /* A NULL terminated array of argument types. */
+ debug_type *arg_types;
+ /* Whether the method takes a variable number of arguments. */
+ boolean varargs;
+};
+
+/* Information kept for a named type. */
+
+struct debug_named_type
+{
+ /* Name. */
+ struct debug_name *name;
+ /* Real type. */
+ debug_type type;
+};
+
+/* A field in a struct or union. */
+
+struct debug_field
+{
+ /* Name of the field. */
+ const char *name;
+ /* Type of the field. */
+ struct debug_type *type;
+ /* Visibility of the field. */
+ enum debug_visibility visibility;
+ /* Whether this is a static member. */
+ boolean static_member;
+ union
+ {
+ /* If static_member is false. */
+ struct
+ {
+ /* Bit position of the field in the struct. */
+ unsigned int bitpos;
+ /* Size of the field in bits. */
+ unsigned int bitsize;
+ } f;
+ /* If static_member is true. */
+ struct
+ {
+ const char *physname;
+ } s;
+ } u;
+};
+
+/* A base class for an object. */
+
+struct debug_baseclass
+{
+ /* Type of the base class. */
+ struct debug_type *type;
+ /* Bit position of the base class in the object. */
+ unsigned int bitpos;
+ /* Whether the base class is virtual. */
+ boolean virtual;
+ /* Visibility of the base class. */
+ enum debug_visibility visibility;
+};
+
+/* A method of an object. */
+
+struct debug_method
+{
+ /* The name of the method. */
+ const char *name;
+ /* A NULL terminated array of different types of variants. */
+ struct debug_method_variant **variants;
+};
+
+/* The variants of a method function of an object. These indicate
+ which method to run. */
+
+struct debug_method_variant
+{
+ /* The physical name of the function. */
+ const char *physname;
+ /* The type of the function. */
+ struct debug_type *type;
+ /* The visibility of the function. */
+ enum debug_visibility visibility;
+ /* Whether the function is const. */
+ boolean constp;
+ /* Whether the function is volatile. */
+ boolean volatilep;
+ /* The offset to the function in the virtual function table. */
+ bfd_vma voffset;
+ /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */
+#define VOFFSET_STATIC_METHOD ((bfd_vma) -1)
+ /* Context of a virtual method function. */
+ struct debug_type *context;
+};
+
+/* A variable. This is the information we keep for a variable object.
+ This has no name; a name is associated with a variable in a
+ debug_name structure. */
+
+struct debug_variable
+{
+ /* Kind of variable. */
+ enum debug_var_kind kind;
+ /* Type. */
+ debug_type type;
+ /* Value. The interpretation of the value depends upon kind. */
+ bfd_vma val;
+};
+
+/* A function. This has no name; a name is associated with a function
+ in a debug_name structure. */
+
+struct debug_function
+{
+ /* Return type. */
+ debug_type return_type;
+ /* Parameter information. */
+ struct debug_parameter *parameters;
+ /* Block information. The first structure on the list is the main
+ block of the function, and describes function local variables. */
+ struct debug_block *blocks;
+};
+
+/* A function parameter. */
+
+struct debug_parameter
+{
+ /* Next parameter. */
+ struct debug_parameter *next;
+ /* Name. */
+ const char *name;
+ /* Type. */
+ debug_type type;
+ /* Kind. */
+ enum debug_parm_kind kind;
+ /* Value (meaning depends upon kind). */
+ bfd_vma val;
+};
+
+/* A typed constant. */
+
+struct debug_typed_constant
+{
+ /* Type. */
+ debug_type type;
+ /* Value. FIXME: We may eventually need to support non-integral
+ values. */
+ bfd_vma val;
+};
+
+/* Information about a block within a function. */
+
+struct debug_block
+{
+ /* Next block with the same parent. */
+ struct debug_block *next;
+ /* Parent block. */
+ struct debug_block *parent;
+ /* List of child blocks. */
+ struct debug_block *children;
+ /* Start address of the block. */
+ bfd_vma start;
+ /* End address of the block. */
+ bfd_vma end;
+ /* Local variables. */
+ struct debug_namespace *locals;
+};
+
+/* Line number information we keep for a compilation unit. FIXME:
+ This structure is easy to create, but can be very space
+ inefficient. */
+
+struct debug_lineno
+{
+ /* More line number information for this block. */
+ struct debug_lineno *next;
+ /* Source file. */
+ struct debug_file *file;
+ /* Line numbers, terminated by a -1 or the end of the array. */
+#define DEBUG_LINENO_COUNT 10
+ unsigned long linenos[DEBUG_LINENO_COUNT];
+ /* Addresses for the line numbers. */
+ bfd_vma addrs[DEBUG_LINENO_COUNT];
+};
+
+/* A namespace. This is a mapping from names to objects. FIXME: This
+ should be implemented as a hash table. */
+
+struct debug_namespace
+{
+ /* List of items in this namespace. */
+ struct debug_name *list;
+ /* Pointer to where the next item in this namespace should go. */
+ struct debug_name **tail;
+};
+
+/* Kinds of objects that appear in a namespace. */
+
+enum debug_object_kind
+{
+ /* A type. */
+ DEBUG_OBJECT_TYPE,
+ /* A tagged type (really a different sort of namespace). */
+ DEBUG_OBJECT_TAG,
+ /* A variable. */
+ DEBUG_OBJECT_VARIABLE,
+ /* A function. */
+ DEBUG_OBJECT_FUNCTION,
+ /* An integer constant. */
+ DEBUG_OBJECT_INT_CONSTANT,
+ /* A floating point constant. */
+ DEBUG_OBJECT_FLOAT_CONSTANT,
+ /* A typed constant. */
+ DEBUG_OBJECT_TYPED_CONSTANT
+};
+
+/* Linkage of an object that appears in a namespace. */
+
+enum debug_object_linkage
+{
+ /* Local variable. */
+ DEBUG_LINKAGE_AUTOMATIC,
+ /* Static--either file static or function static, depending upon the
+ namespace is. */
+ DEBUG_LINKAGE_STATIC,
+ /* Global. */
+ DEBUG_LINKAGE_GLOBAL,
+ /* No linkage. */
+ DEBUG_LINKAGE_NONE
+};
+
+/* A name in a namespace. */
+
+struct debug_name
+{
+ /* Next name in this namespace. */
+ struct debug_name *next;
+ /* Name. */
+ const char *name;
+ /* Mark. This is used by debug_write. */
+ unsigned int mark;
+ /* Kind of object. */
+ enum debug_object_kind kind;
+ /* Linkage of object. */
+ enum debug_object_linkage linkage;
+ /* Tagged union with additional information about the object. */
+ union
+ {
+ /* DEBUG_OBJECT_TYPE. */
+ struct debug_type *type;
+ /* DEBUG_OBJECT_TAG. */
+ struct debug_type *tag;
+ /* DEBUG_OBJECT_VARIABLE. */
+ struct debug_variable *variable;
+ /* DEBUG_OBJECT_FUNCTION. */
+ struct debug_function *function;
+ /* DEBUG_OBJECT_INT_CONSTANT. */
+ bfd_vma int_constant;
+ /* DEBUG_OBJECT_FLOAT_CONSTANT. */
+ double float_constant;
+ /* DEBUG_OBJECT_TYPED_CONSTANT. */
+ struct debug_typed_constant *typed_constant;
+ } u;
+};
+
+/* During debug_write, a linked list of these structures is used to
+ keep track of ID numbers that have been assigned to classes. */
+
+struct debug_class_id
+{
+ /* Next ID number. */
+ struct debug_class_id *next;
+ /* The type with the ID. */
+ struct debug_type *type;
+ /* The tag; NULL if no tag. */
+ const char *tag;
+};
+
+/* During debug_type_samep, a linked list of these structures is kept
+ on the stack to avoid infinite recursion. */
+
+struct debug_type_compare_list
+{
+ /* Next type on list. */
+ struct debug_type_compare_list *next;
+ /* The types we are comparing. */
+ struct debug_type *t1;
+ struct debug_type *t2;
+};
+
+/* During debug_get_real_type, a linked list of these structures is
+ kept on the stack to avoid infinite recursion. */
+
+struct debug_type_real_list
+{
+ /* Next type on list. */
+ struct debug_type_real_list *next;
+ /* The type we are checking. */
+ struct debug_type *t;
+};
+
+/* Local functions. */
+
+static void debug_error PARAMS ((const char *));
+static struct debug_name *debug_add_to_namespace
+ PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
+ enum debug_object_kind, enum debug_object_linkage));
+static struct debug_name *debug_add_to_current_namespace
+ PARAMS ((struct debug_handle *, const char *, enum debug_object_kind,
+ enum debug_object_linkage));
+static struct debug_type *debug_make_type
+ PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
+static struct debug_type *debug_get_real_type
+ PARAMS ((PTR, debug_type, struct debug_type_real_list *));
+static boolean debug_write_name
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_name *));
+static boolean debug_write_type
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_type *, struct debug_name *));
+static boolean debug_write_class_type
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_type *, const char *));
+static boolean debug_write_function
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ const char *, enum debug_object_linkage, struct debug_function *));
+static boolean debug_write_block
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ struct debug_block *));
+static boolean debug_write_linenos
+ PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
+ bfd_vma));
+static boolean debug_set_class_id
+ PARAMS ((struct debug_handle *, const char *, struct debug_type *));
+static boolean debug_type_samep
+ PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
+static boolean debug_class_type_samep
+ PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *));
+
+/* Issue an error message. */
+
+static void
+debug_error (message)
+ const char *message;
+{
+ fprintf (stderr, "%s\n", message);
+}
+
+/* Add an object to a namespace. */
+
+static struct debug_name *
+debug_add_to_namespace (info, nsp, name, kind, linkage)
+ struct debug_handle *info;
+ struct debug_namespace **nsp;
+ const char *name;
+ enum debug_object_kind kind;
+ enum debug_object_linkage linkage;
+{
+ struct debug_name *n;
+ struct debug_namespace *ns;
+
+ n = (struct debug_name *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->name = name;
+ n->kind = kind;
+ n->linkage = linkage;
+
+ ns = *nsp;
+ if (ns == NULL)
+ {
+ ns = (struct debug_namespace *) xmalloc (sizeof *ns);
+ memset (ns, 0, sizeof *ns);
+
+ ns->tail = &ns->list;
+
+ *nsp = ns;
+ }
+
+ *ns->tail = n;
+ ns->tail = &n->next;
+
+ return n;
+}
+
+/* Add an object to the current namespace. */
+
+static struct debug_name *
+debug_add_to_current_namespace (info, name, kind, linkage)
+ struct debug_handle *info;
+ const char *name;
+ enum debug_object_kind kind;
+ enum debug_object_linkage linkage;
+{
+ struct debug_namespace **nsp;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error (_("debug_add_to_current_namespace: no current file"));
+ return NULL;
+ }
+
+ if (info->current_block != NULL)
+ nsp = &info->current_block->locals;
+ else
+ nsp = &info->current_file->globals;
+
+ return debug_add_to_namespace (info, nsp, name, kind, linkage);
+}
+
+/* Return a handle for debugging information. */
+
+PTR
+debug_init ()
+{
+ struct debug_handle *ret;
+
+ ret = (struct debug_handle *) xmalloc (sizeof *ret);
+ memset (ret, 0, sizeof *ret);
+ return (PTR) ret;
+}
+
+/* Set the source filename. This implicitly starts a new compilation
+ unit. */
+
+boolean
+debug_set_filename (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_file *nfile;
+ struct debug_unit *nunit;
+
+ if (name == NULL)
+ name = "";
+
+ nfile = (struct debug_file *) xmalloc (sizeof *nfile);
+ memset (nfile, 0, sizeof *nfile);
+
+ nfile->filename = name;
+
+ nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
+ memset (nunit, 0, sizeof *nunit);
+
+ nunit->files = nfile;
+ info->current_file = nfile;
+
+ if (info->current_unit != NULL)
+ info->current_unit->next = nunit;
+ else
+ {
+ assert (info->units == NULL);
+ info->units = nunit;
+ }
+
+ info->current_unit = nunit;
+
+ info->current_function = NULL;
+ info->current_block = NULL;
+ info->current_lineno = NULL;
+
+ return true;
+}
+
+/* Change source files to the given file name. This is used for
+ include files in a single compilation unit. */
+
+boolean
+debug_start_source (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_file *f, **pf;
+
+ if (name == NULL)
+ name = "";
+
+ if (info->current_unit == NULL)
+ {
+ debug_error (_("debug_start_source: no debug_set_filename call"));
+ return false;
+ }
+
+ for (f = info->current_unit->files; f != NULL; f = f->next)
+ {
+ if (f->filename[0] == name[0]
+ && f->filename[1] == name[1]
+ && strcmp (f->filename, name) == 0)
+ {
+ info->current_file = f;
+ return true;
+ }
+ }
+
+ f = (struct debug_file *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->filename = name;
+
+ for (pf = &info->current_file->next;
+ *pf != NULL;
+ pf = &(*pf)->next)
+ ;
+ *pf = f;
+
+ info->current_file = f;
+
+ return true;
+}
+
+/* Record a function definition. This implicitly starts a function
+ block. The debug_type argument is the type of the return value.
+ The boolean indicates whether the function is globally visible.
+ The bfd_vma is the address of the start of the function. Currently
+ the parameter types are specified by calls to
+ debug_record_parameter. FIXME: There is no way to specify nested
+ functions. */
+
+boolean
+debug_record_function (handle, name, return_type, global, addr)
+ PTR handle;
+ const char *name;
+ debug_type return_type;
+ boolean global;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_function *f;
+ struct debug_block *b;
+ struct debug_name *n;
+
+ if (name == NULL)
+ name = "";
+ if (return_type == NULL)
+ return false;
+
+ if (info->current_unit == NULL)
+ {
+ debug_error (_("debug_record_function: no debug_set_filename call"));
+ return false;
+ }
+
+ f = (struct debug_function *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->return_type = return_type;
+
+ b = (struct debug_block *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->start = addr;
+ b->end = (bfd_vma) -1;
+
+ f->blocks = b;
+
+ info->current_function = f;
+ info->current_block = b;
+
+ /* FIXME: If we could handle nested functions, this would be the
+ place: we would want to use a different namespace. */
+ n = debug_add_to_namespace (info,
+ &info->current_file->globals,
+ name,
+ DEBUG_OBJECT_FUNCTION,
+ (global
+ ? DEBUG_LINKAGE_GLOBAL
+ : DEBUG_LINKAGE_STATIC));
+ if (n == NULL)
+ return false;
+
+ n->u.function = f;
+
+ return true;
+}
+
+/* Record a parameter for the current function. */
+
+boolean
+debug_record_parameter (handle, name, type, kind, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_parameter *p, **pp;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ if (info->current_unit == NULL
+ || info->current_function == NULL)
+ {
+ debug_error (_("debug_record_parameter: no current function"));
+ return false;
+ }
+
+ p = (struct debug_parameter *) xmalloc (sizeof *p);
+ memset (p, 0, sizeof *p);
+
+ p->name = name;
+ p->type = type;
+ p->kind = kind;
+ p->val = val;
+
+ for (pp = &info->current_function->parameters;
+ *pp != NULL;
+ pp = &(*pp)->next)
+ ;
+ *pp = p;
+
+ return true;
+}
+
+/* End a function. FIXME: This should handle function nesting. */
+
+boolean
+debug_end_function (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ if (info->current_unit == NULL
+ || info->current_block == NULL
+ || info->current_function == NULL)
+ {
+ debug_error (_("debug_end_function: no current function"));
+ return false;
+ }
+
+ if (info->current_block->parent != NULL)
+ {
+ debug_error (_("debug_end_function: some blocks were not closed"));
+ return false;
+ }
+
+ info->current_block->end = addr;
+
+ info->current_function = NULL;
+ info->current_block = NULL;
+
+ return true;
+}
+
+/* Start a block in a function. All local information will be
+ recorded in this block, until the matching call to debug_end_block.
+ debug_start_block and debug_end_block may be nested. The bfd_vma
+ argument is the address at which this block starts. */
+
+boolean
+debug_start_block (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *b, **pb;
+
+ /* We must always have a current block: debug_record_function sets
+ one up. */
+ if (info->current_unit == NULL
+ || info->current_block == NULL)
+ {
+ debug_error (_("debug_start_block: no current block"));
+ return false;
+ }
+
+ b = (struct debug_block *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->parent = info->current_block;
+ b->start = addr;
+ b->end = (bfd_vma) -1;
+
+ /* This new block is a child of the current block. */
+ for (pb = &info->current_block->children;
+ *pb != NULL;
+ pb = &(*pb)->next)
+ ;
+ *pb = b;
+
+ info->current_block = b;
+
+ return true;
+}
+
+/* Finish a block in a function. This matches the call to
+ debug_start_block. The argument is the address at which this block
+ ends. */
+
+boolean
+debug_end_block (handle, addr)
+ PTR handle;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *parent;
+
+ if (info->current_unit == NULL
+ || info->current_block == NULL)
+ {
+ debug_error (_("debug_end_block: no current block"));
+ return false;
+ }
+
+ parent = info->current_block->parent;
+ if (parent == NULL)
+ {
+ debug_error (_("debug_end_block: attempt to close top level block"));
+ return false;
+ }
+
+ info->current_block->end = addr;
+
+ info->current_block = parent;
+
+ return true;
+}
+
+/* Associate a line number in the current source file and function
+ with a given address. */
+
+boolean
+debug_record_line (handle, lineno, addr)
+ PTR handle;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_lineno *l;
+ unsigned int i;
+
+ if (info->current_unit == NULL)
+ {
+ debug_error (_("debug_record_line: no current unit"));
+ return false;
+ }
+
+ l = info->current_lineno;
+ if (l != NULL && l->file == info->current_file)
+ {
+ for (i = 0; i < DEBUG_LINENO_COUNT; i++)
+ {
+ if (l->linenos[i] == (unsigned long) -1)
+ {
+ l->linenos[i] = lineno;
+ l->addrs[i] = addr;
+ return true;
+ }
+ }
+ }
+
+ /* If we get here, then either 1) there is no current_lineno
+ structure, which means this is the first line number in this
+ compilation unit, 2) the current_lineno structure is for a
+ different file, or 3) the current_lineno structure is full.
+ Regardless, we want to allocate a new debug_lineno structure, put
+ it in the right place, and make it the new current_lineno
+ structure. */
+
+ l = (struct debug_lineno *) xmalloc (sizeof *l);
+ memset (l, 0, sizeof *l);
+
+ l->file = info->current_file;
+ l->linenos[0] = lineno;
+ l->addrs[0] = addr;
+ for (i = 1; i < DEBUG_LINENO_COUNT; i++)
+ l->linenos[i] = (unsigned long) -1;
+
+ if (info->current_lineno != NULL)
+ info->current_lineno->next = l;
+ else
+ info->current_unit->linenos = l;
+
+ info->current_lineno = l;
+
+ return true;
+}
+
+/* Start a named common block. This is a block of variables that may
+ move in memory. */
+
+boolean
+debug_start_common_block (handle, name)
+ PTR handle;
+ const char *name;
+{
+ /* FIXME */
+ debug_error (_("debug_start_common_block: not implemented"));
+ return false;
+}
+
+/* End a named common block. */
+
+boolean
+debug_end_common_block (handle, name)
+ PTR handle;
+ const char *name;
+{
+ /* FIXME */
+ debug_error (_("debug_end_common_block: not implemented"));
+ return false;
+}
+
+/* Record a named integer constant. */
+
+boolean
+debug_record_int_const (handle, name, val)
+ PTR handle;
+ const char *name;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+
+ if (name == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ n->u.int_constant = val;
+
+ return true;
+}
+
+/* Record a named floating point constant. */
+
+boolean
+debug_record_float_const (handle, name, val)
+ PTR handle;
+ const char *name;
+ double val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+
+ if (name == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ n->u.float_constant = val;
+
+ return true;
+}
+
+/* Record a typed constant with an integral value. */
+
+boolean
+debug_record_typed_const (handle, name, type, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_name *n;
+ struct debug_typed_constant *tc;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
+ DEBUG_LINKAGE_NONE);
+ if (n == NULL)
+ return false;
+
+ tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
+ memset (tc, 0, sizeof *tc);
+
+ tc->type = type;
+ tc->val = val;
+
+ n->u.typed_constant = tc;
+
+ return true;
+}
+
+/* Record a label. */
+
+boolean
+debug_record_label (handle, name, type, addr)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma addr;
+{
+ /* FIXME. */
+ debug_error (_("debug_record_label not implemented"));
+ return false;
+}
+
+/* Record a variable. */
+
+boolean
+debug_record_variable (handle, name, type, kind, val)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_namespace **nsp;
+ enum debug_object_linkage linkage;
+ struct debug_name *n;
+ struct debug_variable *v;
+
+ if (name == NULL || type == NULL)
+ return false;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error (_("debug_record_variable: no current file"));
+ return false;
+ }
+
+ if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
+ {
+ nsp = &info->current_file->globals;
+ if (kind == DEBUG_GLOBAL)
+ linkage = DEBUG_LINKAGE_GLOBAL;
+ else
+ linkage = DEBUG_LINKAGE_STATIC;
+ }
+ else
+ {
+ if (info->current_block == NULL)
+ {
+ debug_error (_("debug_record_variable: no current block"));
+ return false;
+ }
+ nsp = &info->current_block->locals;
+ linkage = DEBUG_LINKAGE_AUTOMATIC;
+ }
+
+ n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
+ if (n == NULL)
+ return false;
+
+ v = (struct debug_variable *) xmalloc (sizeof *v);
+ memset (v, 0, sizeof *v);
+
+ v->kind = kind;
+ v->type = type;
+ v->val = val;
+
+ n->u.variable = v;
+
+ return true;
+}
+
+/* Make a type with a given kind and size. */
+
+/*ARGSUSED*/
+static struct debug_type *
+debug_make_type (info, kind, size)
+ struct debug_handle *info;
+ enum debug_type_kind kind;
+ unsigned int size;
+{
+ struct debug_type *t;
+
+ t = (struct debug_type *) xmalloc (sizeof *t);
+ memset (t, 0, sizeof *t);
+
+ t->kind = kind;
+ t->size = size;
+
+ return t;
+}
+
+/* Make an indirect type which may be used as a placeholder for a type
+ which is referenced before it is defined. */
+
+debug_type
+debug_make_indirect_type (handle, slot, tag)
+ PTR handle;
+ debug_type *slot;
+ const char *tag;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_indirect_type *i;
+
+ t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ i = (struct debug_indirect_type *) xmalloc (sizeof *i);
+ memset (i, 0, sizeof *i);
+
+ i->slot = slot;
+ i->tag = tag;
+
+ t->u.kindirect = i;
+
+ return t;
+}
+
+/* Make a void type. There is only one of these. */
+
+debug_type
+debug_make_void_type (handle)
+ PTR handle;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_VOID, 0);
+}
+
+/* Make an integer type of a given size. The boolean argument is true
+ if the integer is unsigned. */
+
+debug_type
+debug_make_int_type (handle, size, unsignedp)
+ PTR handle;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ t = debug_make_type (info, DEBUG_KIND_INT, size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kint = unsignedp;
+
+ return t;
+}
+
+/* Make a floating point type of a given size. FIXME: On some
+ platforms, like an Alpha, you probably need to be able to specify
+ the format. */
+
+debug_type
+debug_make_float_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_FLOAT, size);
+}
+
+/* Make a boolean type of a given size. */
+
+debug_type
+debug_make_bool_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_BOOL, size);
+}
+
+/* Make a complex type of a given size. */
+
+debug_type
+debug_make_complex_type (handle, size)
+ PTR handle;
+ unsigned int size;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+
+ return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
+}
+
+/* Make a structure type. The second argument is true for a struct,
+ false for a union. The third argument is the size of the struct.
+ The fourth argument is a NULL terminated array of fields. */
+
+debug_type
+debug_make_struct_type (handle, structp, size, fields)
+ PTR handle;
+ boolean structp;
+ bfd_vma size;
+ debug_field *fields;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_class_type *c;
+
+ t = debug_make_type (info,
+ structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
+ size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ c = (struct debug_class_type *) xmalloc (sizeof *c);
+ memset (c, 0, sizeof *c);
+
+ c->fields = fields;
+
+ t->u.kclass = c;
+
+ return t;
+}
+
+/* Make an object type. The first three arguments after the handle
+ are the same as for debug_make_struct_type. The next arguments are
+ a NULL terminated array of base classes, a NULL terminated array of
+ methods, the type of the object holding the virtual function table
+ if it is not this object, and a boolean which is true if this
+ object has its own virtual function table. */
+
+debug_type
+debug_make_object_type (handle, structp, size, fields, baseclasses,
+ methods, vptrbase, ownvptr)
+ PTR handle;
+ boolean structp;
+ bfd_vma size;
+ debug_field *fields;
+ debug_baseclass *baseclasses;
+ debug_method *methods;
+ debug_type vptrbase;
+ boolean ownvptr;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_class_type *c;
+
+ t = debug_make_type (info,
+ structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
+ size);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ c = (struct debug_class_type *) xmalloc (sizeof *c);
+ memset (c, 0, sizeof *c);
+
+ c->fields = fields;
+ c->baseclasses = baseclasses;
+ c->methods = methods;
+ if (ownvptr)
+ c->vptrbase = t;
+ else
+ c->vptrbase = vptrbase;
+
+ t->u.kclass = c;
+
+ return t;
+}
+
+/* Make an enumeration type. The arguments are a null terminated
+ array of strings, and an array of corresponding values. */
+
+debug_type
+debug_make_enum_type (handle, names, values)
+ PTR handle;
+ const char **names;
+ bfd_signed_vma *values;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_enum_type *e;
+
+ t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ e = (struct debug_enum_type *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->names = names;
+ e->values = values;
+
+ t->u.kenum = e;
+
+ return t;
+}
+
+/* Make a pointer to a given type. */
+
+debug_type
+debug_make_pointer_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (type->pointer != DEBUG_TYPE_NULL)
+ return type->pointer;
+
+ t = debug_make_type (info, DEBUG_KIND_POINTER, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kpointer = type;
+
+ type->pointer = t;
+
+ return t;
+}
+
+/* Make a function returning a given type. FIXME: We should be able
+ to record the parameter types. */
+
+debug_type
+debug_make_function_type (handle, type, arg_types, varargs)
+ PTR handle;
+ debug_type type;
+ debug_type *arg_types;
+ boolean varargs;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_function_type *f;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ f = (struct debug_function_type *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->return_type = type;
+ f->arg_types = arg_types;
+ f->varargs = varargs;
+
+ t->u.kfunction = f;
+
+ return t;
+}
+
+/* Make a reference to a given type. */
+
+debug_type
+debug_make_reference_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kreference = type;
+
+ return t;
+}
+
+/* Make a range of a given type from a lower to an upper bound. */
+
+debug_type
+debug_make_range_type (handle, type, lower, upper)
+ PTR handle;
+ debug_type type;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_range_type *r;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_RANGE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ r = (struct debug_range_type *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+
+ r->type = type;
+ r->lower = lower;
+ r->upper = upper;
+
+ t->u.krange = r;
+
+ return t;
+}
+
+/* Make an array type. The second argument is the type of an element
+ of the array. The third argument is the type of a range of the
+ array. The fourth and fifth argument are the lower and upper
+ bounds, respectively. The sixth argument is true if this array is
+ actually a string, as in C. */
+
+debug_type
+debug_make_array_type (handle, element_type, range_type, lower, upper,
+ stringp)
+ PTR handle;
+ debug_type element_type;
+ debug_type range_type;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+ boolean stringp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_array_type *a;
+
+ if (element_type == NULL || range_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_ARRAY, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ a = (struct debug_array_type *) xmalloc (sizeof *a);
+ memset (a, 0, sizeof *a);
+
+ a->element_type = element_type;
+ a->range_type = range_type;
+ a->lower = lower;
+ a->upper = upper;
+ a->stringp = stringp;
+
+ t->u.karray = a;
+
+ return t;
+}
+
+/* Make a set of a given type. For example, a Pascal set type. The
+ boolean argument is true if this set is actually a bitstring, as in
+ CHILL. */
+
+debug_type
+debug_make_set_type (handle, type, bitstringp)
+ PTR handle;
+ debug_type type;
+ boolean bitstringp;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_set_type *s;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_SET, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ s = (struct debug_set_type *) xmalloc (sizeof *s);
+ memset (s, 0, sizeof *s);
+
+ s->type = type;
+ s->bitstringp = bitstringp;
+
+ t->u.kset = s;
+
+ return t;
+}
+
+/* Make a type for a pointer which is relative to an object. The
+ second argument is the type of the object to which the pointer is
+ relative. The third argument is the type that the pointer points
+ to. */
+
+debug_type
+debug_make_offset_type (handle, base_type, target_type)
+ PTR handle;
+ debug_type base_type;
+ debug_type target_type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_offset_type *o;
+
+ if (base_type == NULL || target_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_OFFSET, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ o = (struct debug_offset_type *) xmalloc (sizeof *o);
+ memset (o, 0, sizeof *o);
+
+ o->base_type = base_type;
+ o->target_type = target_type;
+
+ t->u.koffset = o;
+
+ return t;
+}
+
+/* Make a type for a method function. The second argument is the
+ return type, the third argument is the domain, and the fourth
+ argument is a NULL terminated array of argument types. */
+
+debug_type
+debug_make_method_type (handle, return_type, domain_type, arg_types, varargs)
+ PTR handle;
+ debug_type return_type;
+ debug_type domain_type;
+ debug_type *arg_types;
+ boolean varargs;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_method_type *m;
+
+ if (return_type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_METHOD, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ m = (struct debug_method_type *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->return_type = return_type;
+ m->domain_type = domain_type;
+ m->arg_types = arg_types;
+ m->varargs = varargs;
+
+ t->u.kmethod = m;
+
+ return t;
+}
+
+/* Make a const qualified version of a given type. */
+
+debug_type
+debug_make_const_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_CONST, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kconst = type;
+
+ return t;
+}
+
+/* Make a volatile qualified version of a given type. */
+
+debug_type
+debug_make_volatile_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ t->u.kvolatile = type;
+
+ return t;
+}
+
+/* Make an undefined tagged type. For example, a struct which has
+ been mentioned, but not defined. */
+
+debug_type
+debug_make_undefined_tagged_type (handle, name, kind)
+ PTR handle;
+ const char *name;
+ enum debug_type_kind kind;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+
+ if (name == NULL)
+ return DEBUG_TYPE_NULL;
+
+ switch (kind)
+ {
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ case DEBUG_KIND_ENUM:
+ break;
+
+ default:
+ debug_error (_("debug_make_undefined_type: unsupported kind"));
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, kind, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ return debug_tag_type (handle, name, t);
+}
+
+/* Make a base class for an object. The second argument is the base
+ class type. The third argument is the bit position of this base
+ class in the object (always 0 unless doing multiple inheritance).
+ The fourth argument is whether this is a virtual class. The fifth
+ argument is the visibility of the base class. */
+
+/*ARGSUSED*/
+debug_baseclass
+debug_make_baseclass (handle, type, bitpos, virtual, visibility)
+ PTR handle;
+ debug_type type;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct debug_baseclass *b;
+
+ b = (struct debug_baseclass *) xmalloc (sizeof *b);
+ memset (b, 0, sizeof *b);
+
+ b->type = type;
+ b->bitpos = bitpos;
+ b->virtual = virtual;
+ b->visibility = visibility;
+
+ return b;
+}
+
+/* Make a field for a struct. The second argument is the name. The
+ third argument is the type of the field. The fourth argument is
+ the bit position of the field. The fifth argument is the size of
+ the field (it may be zero). The sixth argument is the visibility
+ of the field. */
+
+/*ARGSUSED*/
+debug_field
+debug_make_field (handle, name, type, bitpos, bitsize, visibility)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct debug_field *f;
+
+ f = (struct debug_field *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->name = name;
+ f->type = type;
+ f->static_member = false;
+ f->u.f.bitpos = bitpos;
+ f->u.f.bitsize = bitsize;
+ f->visibility = visibility;
+
+ return f;
+}
+
+/* Make a static member of an object. The second argument is the
+ name. The third argument is the type of the member. The fourth
+ argument is the physical name of the member (i.e., the name as a
+ global variable). The fifth argument is the visibility of the
+ member. */
+
+/*ARGSUSED*/
+debug_field
+debug_make_static_member (handle, name, type, physname, visibility)
+ PTR handle;
+ const char *name;
+ debug_type type;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct debug_field *f;
+
+ f = (struct debug_field *) xmalloc (sizeof *f);
+ memset (f, 0, sizeof *f);
+
+ f->name = name;
+ f->type = type;
+ f->static_member = true;
+ f->u.s.physname = physname;
+ f->visibility = visibility;
+
+ return f;
+}
+
+/* Make a method. The second argument is the name, and the third
+ argument is a NULL terminated array of method variants. */
+
+/*ARGSUSED*/
+debug_method
+debug_make_method (handle, name, variants)
+ PTR handle;
+ const char *name;
+ debug_method_variant *variants;
+{
+ struct debug_method *m;
+
+ m = (struct debug_method *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->name = name;
+ m->variants = variants;
+
+ return m;
+}
+
+/* Make a method argument. The second argument is the real name of
+ the function. The third argument is the type of the function. The
+ fourth argument is the visibility. The fifth argument is whether
+ this is a const function. The sixth argument is whether this is a
+ volatile function. The seventh argument is the offset in the
+ virtual function table, if any. The eighth argument is the virtual
+ function context. FIXME: Are the const and volatile arguments
+ necessary? Could we just use debug_make_const_type? */
+
+/*ARGSUSED*/
+debug_method_variant
+debug_make_method_variant (handle, physname, type, visibility, constp,
+ volatilep, voffset, context)
+ PTR handle;
+ const char *physname;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ debug_type context;
+{
+ struct debug_method_variant *m;
+
+ m = (struct debug_method_variant *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->physname = physname;
+ m->type = type;
+ m->visibility = visibility;
+ m->constp = constp;
+ m->volatilep = volatilep;
+ m->voffset = voffset;
+ m->context = context;
+
+ return m;
+}
+
+/* Make a static method argument. The arguments are the same as for
+ debug_make_method_variant, except that the last two are omitted
+ since a static method can not also be virtual. */
+
+debug_method_variant
+debug_make_static_method_variant (handle, physname, type, visibility,
+ constp, volatilep)
+ PTR handle;
+ const char *physname;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct debug_method_variant *m;
+
+ m = (struct debug_method_variant *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->physname = physname;
+ m->type = type;
+ m->visibility = visibility;
+ m->constp = constp;
+ m->volatilep = volatilep;
+ m->voffset = VOFFSET_STATIC_METHOD;
+
+ return m;
+}
+
+/* Name a type. */
+
+debug_type
+debug_name_type (handle, name, type)
+ PTR handle;
+ const char *name;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_named_type *n;
+ struct debug_name *nm;
+
+ if (name == NULL || type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (info->current_unit == NULL
+ || info->current_file == NULL)
+ {
+ debug_error (_("debug_name_type: no current file"));
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ n = (struct debug_named_type *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = type;
+
+ t->u.knamed = n;
+
+ /* We always add the name to the global namespace. This is probably
+ wrong in some cases, but it seems to be right for stabs. FIXME. */
+
+ nm = debug_add_to_namespace (info, &info->current_file->globals, name,
+ DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
+ if (nm == NULL)
+ return false;
+
+ nm->u.type = t;
+
+ n->name = nm;
+
+ return t;
+}
+
+/* Tag a type. */
+
+debug_type
+debug_tag_type (handle, name, type)
+ PTR handle;
+ const char *name;
+ debug_type type;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_type *t;
+ struct debug_named_type *n;
+ struct debug_name *nm;
+
+ if (name == NULL || type == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (info->current_file == NULL)
+ {
+ debug_error (_("debug_tag_type: no current file"));
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (type->kind == DEBUG_KIND_TAGGED)
+ {
+ if (strcmp (type->u.knamed->name->name, name) == 0)
+ return type;
+ debug_error (_("debug_tag_type: extra tag attempted"));
+ return DEBUG_TYPE_NULL;
+ }
+
+ t = debug_make_type (info, DEBUG_KIND_TAGGED, 0);
+ if (t == NULL)
+ return DEBUG_TYPE_NULL;
+
+ n = (struct debug_named_type *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = type;
+
+ t->u.knamed = n;
+
+ /* We keep a global namespace of tags for each compilation unit. I
+ don't know if that is the right thing to do. */
+
+ nm = debug_add_to_namespace (info, &info->current_file->globals, name,
+ DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
+ if (nm == NULL)
+ return false;
+
+ nm->u.tag = t;
+
+ n->name = nm;
+
+ return t;
+}
+
+/* Record the size of a given type. */
+
+/*ARGSUSED*/
+boolean
+debug_record_type_size (handle, type, size)
+ PTR handle;
+ debug_type type;
+ unsigned int size;
+{
+ if (type->size != 0 && type->size != size)
+ fprintf (stderr, _("Warning: changing type size from %d to %d\n"),
+ type->size, size);
+
+ type->size = size;
+
+ return true;
+}
+
+/* Find a named type. */
+
+debug_type
+debug_find_named_type (handle, name)
+ PTR handle;
+ const char *name;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_block *b;
+ struct debug_file *f;
+
+ /* We only search the current compilation unit. I don't know if
+ this is right or not. */
+
+ if (info->current_unit == NULL)
+ {
+ debug_error (_("debug_find_named_type: no current compilation unit"));
+ return DEBUG_TYPE_NULL;
+ }
+
+ for (b = info->current_block; b != NULL; b = b->parent)
+ {
+ if (b->locals != NULL)
+ {
+ struct debug_name *n;
+
+ for (n = b->locals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TYPE
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.type;
+ }
+ }
+ }
+
+ for (f = info->current_unit->files; f != NULL; f = f->next)
+ {
+ if (f->globals != NULL)
+ {
+ struct debug_name *n;
+
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TYPE
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.type;
+ }
+ }
+ }
+
+ return DEBUG_TYPE_NULL;
+}
+
+/* Find a tagged type. */
+
+debug_type
+debug_find_tagged_type (handle, name, kind)
+ PTR handle;
+ const char *name;
+ enum debug_type_kind kind;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_unit *u;
+
+ /* We search the globals of all the compilation units. I don't know
+ if this is correct or not. It would be easy to change. */
+
+ for (u = info->units; u != NULL; u = u->next)
+ {
+ struct debug_file *f;
+
+ for (f = u->files; f != NULL; f = f->next)
+ {
+ struct debug_name *n;
+
+ if (f->globals != NULL)
+ {
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (n->kind == DEBUG_OBJECT_TAG
+ && (kind == DEBUG_KIND_ILLEGAL
+ || n->u.tag->kind == kind)
+ && n->name[0] == name[0]
+ && strcmp (n->name, name) == 0)
+ return n->u.tag;
+ }
+ }
+ }
+ }
+
+ return DEBUG_TYPE_NULL;
+}
+
+/* Get a base type. We build a linked list on the stack to avoid
+ crashing if the type is defined circularly. */
+
+static struct debug_type *
+debug_get_real_type (handle, type, list)
+ PTR handle;
+ debug_type type;
+ struct debug_type_real_list *list;
+{
+ struct debug_type_real_list *l;
+ struct debug_type_real_list rl;
+
+ switch (type->kind)
+ {
+ default:
+ return type;
+
+ case DEBUG_KIND_INDIRECT:
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ break;
+ }
+
+ for (l = list; l != NULL; l = l->next)
+ {
+ if (l->t == type)
+ {
+ fprintf (stderr,
+ _("debug_get_real_type: circular debug information for %s\n"),
+ debug_get_type_name (handle, type));
+ return NULL;
+ }
+ }
+
+ rl.next = list;
+ rl.t = type;
+
+ switch (type->kind)
+ {
+ /* The default case is just here to avoid warnings. */
+ default:
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_real_type (handle, *type->u.kindirect->slot, &rl);
+ return type;
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ return debug_get_real_type (handle, type->u.knamed->type, &rl);
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the kind of a type. */
+
+enum debug_type_kind
+debug_get_type_kind (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return DEBUG_KIND_ILLEGAL;
+ type = debug_get_real_type (handle, type, NULL);
+ if (type == NULL)
+ return DEBUG_KIND_ILLEGAL;
+ return type->kind;
+}
+
+/* Get the name of a type. */
+
+const char *
+debug_get_type_name (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type->kind == DEBUG_KIND_INDIRECT)
+ {
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_type_name (handle, *type->u.kindirect->slot);
+ return type->u.kindirect->tag;
+ }
+ if (type->kind == DEBUG_KIND_NAMED
+ || type->kind == DEBUG_KIND_TAGGED)
+ return type->u.knamed->name->name;
+ return NULL;
+}
+
+/* Get the size of a type. */
+
+bfd_vma
+debug_get_type_size (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return 0;
+
+ /* We don't call debug_get_real_type, because somebody might have
+ called debug_record_type_size on a named or indirect type. */
+
+ if (type->size != 0)
+ return type->size;
+
+ switch (type->kind)
+ {
+ default:
+ return 0;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot != NULL)
+ return debug_get_type_size (handle, *type->u.kindirect->slot);
+ return 0;
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ return debug_get_type_size (handle, type->u.knamed->type);
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the return type of a function or method type. */
+
+debug_type
+debug_get_return_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+ type = debug_get_real_type (handle, type, NULL);
+ if (type == NULL)
+ return DEBUG_TYPE_NULL;
+ switch (type->kind)
+ {
+ default:
+ return DEBUG_TYPE_NULL;
+ case DEBUG_KIND_FUNCTION:
+ return type->u.kfunction->return_type;
+ case DEBUG_KIND_METHOD:
+ return type->u.kmethod->return_type;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the parameter types of a function or method type (except that
+ we don't currently store the parameter types of a function). */
+
+const debug_type *
+debug_get_parameter_types (handle, type, pvarargs)
+ PTR handle;
+ debug_type type;
+ boolean *pvarargs;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type, NULL);
+ if (type == NULL)
+ return NULL;
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_FUNCTION:
+ *pvarargs = type->u.kfunction->varargs;
+ return type->u.kfunction->arg_types;
+ case DEBUG_KIND_METHOD:
+ *pvarargs = type->u.kmethod->varargs;
+ return type->u.kmethod->arg_types;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the target type of a type. */
+
+debug_type
+debug_get_target_type (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type, NULL);
+ if (type == NULL)
+ return NULL;
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_POINTER:
+ return type->u.kpointer;
+ case DEBUG_KIND_REFERENCE:
+ return type->u.kreference;
+ case DEBUG_KIND_CONST:
+ return type->u.kconst;
+ case DEBUG_KIND_VOLATILE:
+ return type->u.kvolatile;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the NULL terminated array of fields for a struct, union, or
+ class. */
+
+const debug_field *
+debug_get_fields (handle, type)
+ PTR handle;
+ debug_type type;
+{
+ if (type == NULL)
+ return NULL;
+ type = debug_get_real_type (handle, type, NULL);
+ if (type == NULL)
+ return NULL;
+ switch (type->kind)
+ {
+ default:
+ return NULL;
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ return type->u.kclass->fields;
+ }
+ /*NOTREACHED*/
+}
+
+/* Get the type of a field. */
+
+/*ARGSUSED*/
+debug_type
+debug_get_field_type (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return NULL;
+ return field->type;
+}
+
+/* Get the name of a field. */
+
+/*ARGSUSED*/
+const char *
+debug_get_field_name (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return NULL;
+ return field->name;
+}
+
+/* Get the bit position of a field. */
+
+/*ARGSUSED*/
+bfd_vma
+debug_get_field_bitpos (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || field->static_member)
+ return (bfd_vma) -1;
+ return field->u.f.bitpos;
+}
+
+/* Get the bit size of a field. */
+
+/*ARGSUSED*/
+bfd_vma
+debug_get_field_bitsize (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || field->static_member)
+ return (bfd_vma) -1;
+ return field->u.f.bitsize;
+}
+
+/* Get the visibility of a field. */
+
+/*ARGSUSED*/
+enum debug_visibility
+debug_get_field_visibility (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL)
+ return DEBUG_VISIBILITY_IGNORE;
+ return field->visibility;
+}
+
+/* Get the physical name of a field. */
+
+const char *
+debug_get_field_physname (handle, field)
+ PTR handle;
+ debug_field field;
+{
+ if (field == NULL || ! field->static_member)
+ return NULL;
+ return field->u.s.physname;
+}
+
+/* Write out the debugging information. This is given a handle to
+ debugging information, and a set of function pointers to call. */
+
+boolean
+debug_write (handle, fns, fhandle)
+ PTR handle;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ struct debug_unit *u;
+
+ /* We use a mark to tell whether we have already written out a
+ particular name. We use an integer, so that we don't have to
+ clear the mark fields if we happen to write out the same
+ information more than once. */
+ ++info->mark;
+
+ /* The base_id field holds an ID value which will never be used, so
+ that we can tell whether we have assigned an ID during this call
+ to debug_write. */
+ info->base_id = info->class_id;
+
+ /* We keep a linked list of classes for which was have assigned ID's
+ during this call to debug_write. */
+ info->id_list = NULL;
+
+ for (u = info->units; u != NULL; u = u->next)
+ {
+ struct debug_file *f;
+ boolean first_file;
+
+ info->current_write_lineno = u->linenos;
+ info->current_write_lineno_index = 0;
+
+ if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
+ return false;
+
+ first_file = true;
+ for (f = u->files; f != NULL; f = f->next)
+ {
+ struct debug_name *n;
+
+ if (first_file)
+ first_file = false;
+ else
+ {
+ if (! (*fns->start_source) (fhandle, f->filename))
+ return false;
+ }
+
+ if (f->globals != NULL)
+ {
+ for (n = f->globals->list; n != NULL; n = n->next)
+ {
+ if (! debug_write_name (info, fns, fhandle, n))
+ return false;
+ }
+ }
+ }
+
+ /* Output any line number information which hasn't already been
+ handled. */
+ if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out an element in a namespace. */
+
+static boolean
+debug_write_name (info, fns, fhandle, n)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_name *n;
+{
+ switch (n->kind)
+ {
+ case DEBUG_OBJECT_TYPE:
+ if (! debug_write_type (info, fns, fhandle, n->u.type, n)
+ || ! (*fns->typdef) (fhandle, n->name))
+ return false;
+ return true;
+ case DEBUG_OBJECT_TAG:
+ if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
+ return false;
+ return (*fns->tag) (fhandle, n->name);
+ case DEBUG_OBJECT_VARIABLE:
+ if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
+ n->u.variable->val);
+ case DEBUG_OBJECT_FUNCTION:
+ return debug_write_function (info, fns, fhandle, n->name,
+ n->linkage, n->u.function);
+ case DEBUG_OBJECT_INT_CONSTANT:
+ return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);
+ case DEBUG_OBJECT_FLOAT_CONSTANT:
+ return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);
+ case DEBUG_OBJECT_TYPED_CONSTANT:
+ if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->typed_constant) (fhandle, n->name,
+ n->u.typed_constant->val);
+ default:
+ abort ();
+ return false;
+ }
+ /*NOTREACHED*/
+}
+
+/* Write out a type. If the type is DEBUG_KIND_NAMED or
+ DEBUG_KIND_TAGGED, then the name argument is the name for which we
+ are about to call typedef or tag. If the type is anything else,
+ then the name argument is a tag from a DEBUG_KIND_TAGGED type which
+ points to this one. */
+
+static boolean
+debug_write_type (info, fns, fhandle, type, name)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_type *type;
+ struct debug_name *name;
+{
+ unsigned int i;
+ int is;
+ const char *tag;
+
+ /* If we have a name for this type, just output it. We only output
+ typedef names after they have been defined. We output type tags
+ whenever we are not actually defining them. */
+ if ((type->kind == DEBUG_KIND_NAMED
+ || type->kind == DEBUG_KIND_TAGGED)
+ && (type->u.knamed->name->mark == info->mark
+ || (type->kind == DEBUG_KIND_TAGGED
+ && type->u.knamed->name != name)))
+ {
+ if (type->kind == DEBUG_KIND_NAMED)
+ return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
+ else
+ {
+ struct debug_type *real;
+ unsigned int id;
+
+ real = debug_get_real_type ((PTR) info, type, NULL);
+ if (real == NULL)
+ return (*fns->empty_type) (fhandle);
+ id = 0;
+ if ((real->kind == DEBUG_KIND_STRUCT
+ || real->kind == DEBUG_KIND_UNION
+ || real->kind == DEBUG_KIND_CLASS
+ || real->kind == DEBUG_KIND_UNION_CLASS)
+ && real->u.kclass != NULL)
+ {
+ if (real->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info,
+ type->u.knamed->name->name,
+ real))
+ return false;
+ }
+ id = real->u.kclass->id;
+ }
+
+ return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,
+ real->kind);
+ }
+ }
+
+ /* Mark the name after we have already looked for a known name, so
+ that we don't just define a type in terms of itself. We need to
+ mark the name here so that a struct containing a pointer to
+ itself will work. */
+ if (name != NULL)
+ name->mark = info->mark;
+
+ tag = NULL;
+ if (name != NULL
+ && type->kind != DEBUG_KIND_NAMED
+ && type->kind != DEBUG_KIND_TAGGED)
+ {
+ assert (name->kind == DEBUG_OBJECT_TAG);
+ tag = name->name;
+ }
+
+ switch (type->kind)
+ {
+ case DEBUG_KIND_ILLEGAL:
+ debug_error (_("debug_write_type: illegal type encountered"));
+ return false;
+ case DEBUG_KIND_INDIRECT:
+ if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
+ return (*fns->empty_type) (fhandle);
+ return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot,
+ name);
+ case DEBUG_KIND_VOID:
+ return (*fns->void_type) (fhandle);
+ case DEBUG_KIND_INT:
+ return (*fns->int_type) (fhandle, type->size, type->u.kint);
+ case DEBUG_KIND_FLOAT:
+ return (*fns->float_type) (fhandle, type->size);
+ case DEBUG_KIND_COMPLEX:
+ return (*fns->complex_type) (fhandle, type->size);
+ case DEBUG_KIND_BOOL:
+ return (*fns->bool_type) (fhandle, type->size);
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ if (type->u.kclass != NULL)
+ {
+ if (type->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info, tag, type))
+ return false;
+ }
+
+ if (info->mark == type->u.kclass->mark)
+ {
+ /* We are currently outputting this struct, or we have
+ already output it. I don't know if this can happen,
+ but it can happen for a class. */
+ assert (type->u.kclass->id > info->base_id);
+ return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
+ type->kind);
+ }
+ type->u.kclass->mark = info->mark;
+ }
+
+ if (! (*fns->start_struct_type) (fhandle, tag,
+ (type->u.kclass != NULL
+ ? type->u.kclass->id
+ : 0),
+ type->kind == DEBUG_KIND_STRUCT,
+ type->size))
+ return false;
+ if (type->u.kclass != NULL
+ && type->u.kclass->fields != NULL)
+ {
+ for (i = 0; type->u.kclass->fields[i] != NULL; i++)
+ {
+ struct debug_field *f;
+
+ f = type->u.kclass->fields[i];
+ if (! debug_write_type (info, fns, fhandle, f->type,
+ (struct debug_name *) NULL)
+ || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
+ f->u.f.bitsize, f->visibility))
+ return false;
+ }
+ }
+ return (*fns->end_struct_type) (fhandle);
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ return debug_write_class_type (info, fns, fhandle, type, tag);
+ case DEBUG_KIND_ENUM:
+ if (type->u.kenum == NULL)
+ return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
+ (bfd_signed_vma *) NULL);
+ return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
+ type->u.kenum->values);
+ case DEBUG_KIND_POINTER:
+ if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->pointer_type) (fhandle);
+ case DEBUG_KIND_FUNCTION:
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kfunction->return_type,
+ (struct debug_name *) NULL))
+ return false;
+ if (type->u.kfunction->arg_types == NULL)
+ is = -1;
+ else
+ {
+ for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kfunction->arg_types[is],
+ (struct debug_name *) NULL))
+ return false;
+ }
+ return (*fns->function_type) (fhandle, is,
+ type->u.kfunction->varargs);
+ case DEBUG_KIND_REFERENCE:
+ if (! debug_write_type (info, fns, fhandle, type->u.kreference,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->reference_type) (fhandle);
+ case DEBUG_KIND_RANGE:
+ if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->range_type) (fhandle, type->u.krange->lower,
+ type->u.krange->upper);
+ case DEBUG_KIND_ARRAY:
+ if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type,
+ (struct debug_name *) NULL)
+ || ! debug_write_type (info, fns, fhandle,
+ type->u.karray->range_type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->array_type) (fhandle, type->u.karray->lower,
+ type->u.karray->upper,
+ type->u.karray->stringp);
+ case DEBUG_KIND_SET:
+ if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
+ case DEBUG_KIND_OFFSET:
+ if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
+ (struct debug_name *) NULL)
+ || ! debug_write_type (info, fns, fhandle,
+ type->u.koffset->target_type,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->offset_type) (fhandle);
+ case DEBUG_KIND_METHOD:
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->return_type,
+ (struct debug_name *) NULL))
+ return false;
+ if (type->u.kmethod->arg_types == NULL)
+ is = -1;
+ else
+ {
+ for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->arg_types[is],
+ (struct debug_name *) NULL))
+ return false;
+ }
+ if (type->u.kmethod->domain_type != NULL)
+ {
+ if (! debug_write_type (info, fns, fhandle,
+ type->u.kmethod->domain_type,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ return (*fns->method_type) (fhandle,
+ type->u.kmethod->domain_type != NULL,
+ is,
+ type->u.kmethod->varargs);
+ case DEBUG_KIND_CONST:
+ if (! debug_write_type (info, fns, fhandle, type->u.kconst,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->const_type) (fhandle);
+ case DEBUG_KIND_VOLATILE:
+ if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
+ (struct debug_name *) NULL))
+ return false;
+ return (*fns->volatile_type) (fhandle);
+ case DEBUG_KIND_NAMED:
+ return debug_write_type (info, fns, fhandle, type->u.knamed->type,
+ (struct debug_name *) NULL);
+ case DEBUG_KIND_TAGGED:
+ return debug_write_type (info, fns, fhandle, type->u.knamed->type,
+ type->u.knamed->name);
+ default:
+ abort ();
+ return false;
+ }
+}
+
+/* Write out a class type. */
+
+static boolean
+debug_write_class_type (info, fns, fhandle, type, tag)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_type *type;
+ const char *tag;
+{
+ unsigned int i;
+ unsigned int id;
+ struct debug_type *vptrbase;
+
+ if (type->u.kclass == NULL)
+ {
+ id = 0;
+ vptrbase = NULL;
+ }
+ else
+ {
+ if (type->u.kclass->id <= info->base_id)
+ {
+ if (! debug_set_class_id (info, tag, type))
+ return false;
+ }
+
+ if (info->mark == type->u.kclass->mark)
+ {
+ /* We are currently outputting this class, or we have
+ already output it. This can happen when there are
+ methods for an anonymous class. */
+ assert (type->u.kclass->id > info->base_id);
+ return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
+ type->kind);
+ }
+ type->u.kclass->mark = info->mark;
+ id = type->u.kclass->id;
+
+ vptrbase = type->u.kclass->vptrbase;
+ if (vptrbase != NULL && vptrbase != type)
+ {
+ if (! debug_write_type (info, fns, fhandle, vptrbase,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ }
+
+ if (! (*fns->start_class_type) (fhandle, tag, id,
+ type->kind == DEBUG_KIND_CLASS,
+ type->size,
+ vptrbase != NULL,
+ vptrbase == type))
+ return false;
+
+ if (type->u.kclass != NULL)
+ {
+ if (type->u.kclass->fields != NULL)
+ {
+ for (i = 0; type->u.kclass->fields[i] != NULL; i++)
+ {
+ struct debug_field *f;
+
+ f = type->u.kclass->fields[i];
+ if (! debug_write_type (info, fns, fhandle, f->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (f->static_member)
+ {
+ if (! (*fns->class_static_member) (fhandle, f->name,
+ f->u.s.physname,
+ f->visibility))
+ return false;
+ }
+ else
+ {
+ if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
+ f->u.f.bitsize, f->visibility))
+ return false;
+ }
+ }
+ }
+
+ if (type->u.kclass->baseclasses != NULL)
+ {
+ for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
+ {
+ struct debug_baseclass *b;
+
+ b = type->u.kclass->baseclasses[i];
+ if (! debug_write_type (info, fns, fhandle, b->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
+ b->visibility))
+ return false;
+ }
+ }
+
+ if (type->u.kclass->methods != NULL)
+ {
+ for (i = 0; type->u.kclass->methods[i] != NULL; i++)
+ {
+ struct debug_method *m;
+ unsigned int j;
+
+ m = type->u.kclass->methods[i];
+ if (! (*fns->class_start_method) (fhandle, m->name))
+ return false;
+ for (j = 0; m->variants[j] != NULL; j++)
+ {
+ struct debug_method_variant *v;
+
+ v = m->variants[j];
+ if (v->context != NULL)
+ {
+ if (! debug_write_type (info, fns, fhandle, v->context,
+ (struct debug_name *) NULL))
+ return false;
+ }
+ if (! debug_write_type (info, fns, fhandle, v->type,
+ (struct debug_name *) NULL))
+ return false;
+ if (v->voffset != VOFFSET_STATIC_METHOD)
+ {
+ if (! (*fns->class_method_variant) (fhandle, v->physname,
+ v->visibility,
+ v->constp,
+ v->volatilep,
+ v->voffset,
+ v->context != NULL))
+ return false;
+ }
+ else
+ {
+ if (! (*fns->class_static_method_variant) (fhandle,
+ v->physname,
+ v->visibility,
+ v->constp,
+ v->volatilep))
+ return false;
+ }
+ }
+ if (! (*fns->class_end_method) (fhandle))
+ return false;
+ }
+ }
+ }
+
+ return (*fns->end_class_type) (fhandle);
+}
+
+/* Write out information for a function. */
+
+static boolean
+debug_write_function (info, fns, fhandle, name, linkage, function)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ const char *name;
+ enum debug_object_linkage linkage;
+ struct debug_function *function;
+{
+ struct debug_parameter *p;
+ struct debug_block *b;
+
+ if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
+ return false;
+
+ if (! debug_write_type (info, fns, fhandle, function->return_type,
+ (struct debug_name *) NULL))
+ return false;
+
+ if (! (*fns->start_function) (fhandle, name,
+ linkage == DEBUG_LINKAGE_GLOBAL))
+ return false;
+
+ for (p = function->parameters; p != NULL; p = p->next)
+ {
+ if (! debug_write_type (info, fns, fhandle, p->type,
+ (struct debug_name *) NULL)
+ || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
+ return false;
+ }
+
+ for (b = function->blocks; b != NULL; b = b->next)
+ {
+ if (! debug_write_block (info, fns, fhandle, b))
+ return false;
+ }
+
+ return (*fns->end_function) (fhandle);
+}
+
+/* Write out information for a block. */
+
+static boolean
+debug_write_block (info, fns, fhandle, block)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ struct debug_block *block;
+{
+ struct debug_name *n;
+ struct debug_block *b;
+
+ if (! debug_write_linenos (info, fns, fhandle, block->start))
+ return false;
+
+ /* I can't see any point to writing out a block with no local
+ variables, so we don't bother, except for the top level block. */
+ if (block->locals != NULL || block->parent == NULL)
+ {
+ if (! (*fns->start_block) (fhandle, block->start))
+ return false;
+ }
+
+ if (block->locals != NULL)
+ {
+ for (n = block->locals->list; n != NULL; n = n->next)
+ {
+ if (! debug_write_name (info, fns, fhandle, n))
+ return false;
+ }
+ }
+
+ for (b = block->children; b != NULL; b = b->next)
+ {
+ if (! debug_write_block (info, fns, fhandle, b))
+ return false;
+ }
+
+ if (! debug_write_linenos (info, fns, fhandle, block->end))
+ return false;
+
+ if (block->locals != NULL || block->parent == NULL)
+ {
+ if (! (*fns->end_block) (fhandle, block->end))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out line number information up to ADDRESS. */
+
+static boolean
+debug_write_linenos (info, fns, fhandle, address)
+ struct debug_handle *info;
+ const struct debug_write_fns *fns;
+ PTR fhandle;
+ bfd_vma address;
+{
+ while (info->current_write_lineno != NULL)
+ {
+ struct debug_lineno *l;
+
+ l = info->current_write_lineno;
+
+ while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
+ {
+ if (l->linenos[info->current_write_lineno_index]
+ == (unsigned long) -1)
+ break;
+
+ if (l->addrs[info->current_write_lineno_index] >= address)
+ return true;
+
+ if (! (*fns->lineno) (fhandle, l->file->filename,
+ l->linenos[info->current_write_lineno_index],
+ l->addrs[info->current_write_lineno_index]))
+ return false;
+
+ ++info->current_write_lineno_index;
+ }
+
+ info->current_write_lineno = l->next;
+ info->current_write_lineno_index = 0;
+ }
+
+ return true;
+}
+
+/* Get the ID number for a class. If during the same call to
+ debug_write we find a struct with the same definition with the same
+ name, we use the same ID. This type of things happens because the
+ same struct will be defined by multiple compilation units. */
+
+static boolean
+debug_set_class_id (info, tag, type)
+ struct debug_handle *info;
+ const char *tag;
+ struct debug_type *type;
+{
+ struct debug_class_type *c;
+ struct debug_class_id *l;
+
+ assert (type->kind == DEBUG_KIND_STRUCT
+ || type->kind == DEBUG_KIND_UNION
+ || type->kind == DEBUG_KIND_CLASS
+ || type->kind == DEBUG_KIND_UNION_CLASS);
+
+ c = type->u.kclass;
+
+ if (c->id > info->base_id)
+ return true;
+
+ for (l = info->id_list; l != NULL; l = l->next)
+ {
+ if (l->type->kind != type->kind)
+ continue;
+
+ if (tag == NULL)
+ {
+ if (l->tag != NULL)
+ continue;
+ }
+ else
+ {
+ if (l->tag == NULL
+ || l->tag[0] != tag[0]
+ || strcmp (l->tag, tag) != 0)
+ continue;
+ }
+
+ if (debug_type_samep (info, l->type, type))
+ {
+ c->id = l->type->u.kclass->id;
+ return true;
+ }
+ }
+
+ /* There are no identical types. Use a new ID, and add it to the
+ list. */
+ ++info->class_id;
+ c->id = info->class_id;
+
+ l = (struct debug_class_id *) xmalloc (sizeof *l);
+ memset (l, 0, sizeof *l);
+
+ l->type = type;
+ l->tag = tag;
+
+ l->next = info->id_list;
+ info->id_list = l;
+
+ return true;
+}
+
+/* See if two types are the same. At this point, we don't care about
+ tags and the like. */
+
+static boolean
+debug_type_samep (info, t1, t2)
+ struct debug_handle *info;
+ struct debug_type *t1;
+ struct debug_type *t2;
+{
+ struct debug_type_compare_list *l;
+ struct debug_type_compare_list top;
+ boolean ret;
+
+ if (t1 == NULL)
+ return t2 == NULL;
+ if (t2 == NULL)
+ return false;
+
+ while (t1->kind == DEBUG_KIND_INDIRECT)
+ {
+ t1 = *t1->u.kindirect->slot;
+ if (t1 == NULL)
+ return false;
+ }
+ while (t2->kind == DEBUG_KIND_INDIRECT)
+ {
+ t2 = *t2->u.kindirect->slot;
+ if (t2 == NULL)
+ return false;
+ }
+
+ if (t1 == t2)
+ return true;
+
+ /* As a special case, permit a typedef to match a tag, since C++
+ debugging output will sometimes add a typedef where C debugging
+ output will not. */
+ if (t1->kind == DEBUG_KIND_NAMED
+ && t2->kind == DEBUG_KIND_TAGGED)
+ return debug_type_samep (info, t1->u.knamed->type, t2);
+ else if (t1->kind == DEBUG_KIND_TAGGED
+ && t2->kind == DEBUG_KIND_NAMED)
+ return debug_type_samep (info, t1, t2->u.knamed->type);
+
+ if (t1->kind != t2->kind
+ || t1->size != t2->size)
+ return false;
+
+ /* Get rid of the trivial cases first. */
+ switch (t1->kind)
+ {
+ default:
+ break;
+ case DEBUG_KIND_VOID:
+ case DEBUG_KIND_FLOAT:
+ case DEBUG_KIND_COMPLEX:
+ case DEBUG_KIND_BOOL:
+ return true;
+ case DEBUG_KIND_INT:
+ return t1->u.kint == t2->u.kint;
+ }
+
+ /* We have to avoid an infinite recursion. We do this by keeping a
+ list of types which we are comparing. We just keep the list on
+ the stack. If we encounter a pair of types we are currently
+ comparing, we just assume that they are equal. */
+ for (l = info->compare_list; l != NULL; l = l->next)
+ {
+ if (l->t1 == t1 && l->t2 == t2)
+ return true;
+ }
+
+ top.t1 = t1;
+ top.t2 = t2;
+ top.next = info->compare_list;
+ info->compare_list = &top;
+
+ switch (t1->kind)
+ {
+ default:
+ abort ();
+ ret = false;
+ break;
+
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_CLASS:
+ case DEBUG_KIND_UNION_CLASS:
+ if (t1->u.kclass == NULL)
+ ret = t2->u.kclass == NULL;
+ else if (t2->u.kclass == NULL)
+ ret = false;
+ else if (t1->u.kclass->id > info->base_id
+ && t1->u.kclass->id == t2->u.kclass->id)
+ ret = true;
+ else
+ ret = debug_class_type_samep (info, t1, t2);
+ break;
+
+ case DEBUG_KIND_ENUM:
+ if (t1->u.kenum == NULL)
+ ret = t2->u.kenum == NULL;
+ else if (t2->u.kenum == NULL)
+ ret = false;
+ else
+ {
+ const char **pn1, **pn2;
+ bfd_signed_vma *pv1, *pv2;
+
+ pn1 = t1->u.kenum->names;
+ pn2 = t2->u.kenum->names;
+ pv1 = t1->u.kenum->values;
+ pv2 = t2->u.kenum->values;
+ while (*pn1 != NULL && *pn2 != NULL)
+ {
+ if (**pn1 != **pn2
+ || *pv1 != *pv2
+ || strcmp (*pn1, *pn2) != 0)
+ break;
+ ++pn1;
+ ++pn2;
+ ++pv1;
+ ++pv2;
+ }
+ ret = *pn1 == NULL && *pn2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_POINTER:
+ ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
+ break;
+
+ case DEBUG_KIND_FUNCTION:
+ if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
+ || ! debug_type_samep (info, t1->u.kfunction->return_type,
+ t2->u.kfunction->return_type)
+ || ((t1->u.kfunction->arg_types == NULL)
+ != (t2->u.kfunction->arg_types == NULL)))
+ ret = false;
+ else if (t1->u.kfunction->arg_types == NULL)
+ ret = true;
+ else
+ {
+ struct debug_type **a1, **a2;
+
+ a1 = t1->u.kfunction->arg_types;
+ a2 = t2->u.kfunction->arg_types;
+ while (*a1 != NULL && *a2 != NULL)
+ {
+ if (! debug_type_samep (info, *a1, *a2))
+ break;
+ ++a1;
+ ++a2;
+ }
+ ret = *a1 == NULL && *a2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_REFERENCE:
+ ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference);
+ break;
+
+ case DEBUG_KIND_RANGE:
+ ret = (t1->u.krange->lower == t2->u.krange->lower
+ && t1->u.krange->upper == t2->u.krange->upper
+ && debug_type_samep (info, t1->u.krange->type,
+ t2->u.krange->type));
+
+ case DEBUG_KIND_ARRAY:
+ ret = (t1->u.karray->lower == t2->u.karray->lower
+ && t1->u.karray->upper == t2->u.karray->upper
+ && t1->u.karray->stringp == t2->u.karray->stringp
+ && debug_type_samep (info, t1->u.karray->element_type,
+ t2->u.karray->element_type));
+ break;
+
+ case DEBUG_KIND_SET:
+ ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp
+ && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type));
+ break;
+
+ case DEBUG_KIND_OFFSET:
+ ret = (debug_type_samep (info, t1->u.koffset->base_type,
+ t2->u.koffset->base_type)
+ && debug_type_samep (info, t1->u.koffset->target_type,
+ t2->u.koffset->target_type));
+ break;
+
+ case DEBUG_KIND_METHOD:
+ if (t1->u.kmethod->varargs != t2->u.kmethod->varargs
+ || ! debug_type_samep (info, t1->u.kmethod->return_type,
+ t2->u.kmethod->return_type)
+ || ! debug_type_samep (info, t1->u.kmethod->domain_type,
+ t2->u.kmethod->domain_type)
+ || ((t1->u.kmethod->arg_types == NULL)
+ != (t2->u.kmethod->arg_types == NULL)))
+ ret = false;
+ else if (t1->u.kmethod->arg_types == NULL)
+ ret = true;
+ else
+ {
+ struct debug_type **a1, **a2;
+
+ a1 = t1->u.kmethod->arg_types;
+ a2 = t2->u.kmethod->arg_types;
+ while (*a1 != NULL && *a2 != NULL)
+ {
+ if (! debug_type_samep (info, *a1, *a2))
+ break;
+ ++a1;
+ ++a2;
+ }
+ ret = *a1 == NULL && *a2 == NULL;
+ }
+ break;
+
+ case DEBUG_KIND_CONST:
+ ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst);
+ break;
+
+ case DEBUG_KIND_VOLATILE:
+ ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile);
+ break;
+
+ case DEBUG_KIND_NAMED:
+ case DEBUG_KIND_TAGGED:
+ ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0
+ && debug_type_samep (info, t1->u.knamed->type,
+ t2->u.knamed->type));
+ break;
+ }
+
+ info->compare_list = top.next;
+
+ return ret;
+}
+
+/* See if two classes are the same. This is a subroutine of
+ debug_type_samep. */
+
+static boolean
+debug_class_type_samep (info, t1, t2)
+ struct debug_handle *info;
+ struct debug_type *t1;
+ struct debug_type *t2;
+{
+ struct debug_class_type *c1, *c2;
+
+ c1 = t1->u.kclass;
+ c2 = t2->u.kclass;
+
+ if ((c1->fields == NULL) != (c2->fields == NULL)
+ || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
+ || (c1->methods == NULL) != (c2->methods == NULL)
+ || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
+ return false;
+
+ if (c1->fields != NULL)
+ {
+ struct debug_field **pf1, **pf2;
+
+ for (pf1 = c1->fields, pf2 = c2->fields;
+ *pf1 != NULL && *pf2 != NULL;
+ pf1++, pf2++)
+ {
+ struct debug_field *f1, *f2;
+
+ f1 = *pf1;
+ f2 = *pf2;
+ if (f1->name[0] != f2->name[0]
+ || f1->visibility != f2->visibility
+ || f1->static_member != f2->static_member)
+ return false;
+ if (f1->static_member)
+ {
+ if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
+ return false;
+ }
+ else
+ {
+ if (f1->u.f.bitpos != f2->u.f.bitpos
+ || f1->u.f.bitsize != f2->u.f.bitsize)
+ return false;
+ }
+ /* We do the checks which require function calls last. We
+ don't require that the types of fields have the same
+ names, since that sometimes fails in the presence of
+ typedefs and we really don't care. */
+ if (strcmp (f1->name, f2->name) != 0
+ || ! debug_type_samep (info,
+ debug_get_real_type ((PTR) info,
+ f1->type, NULL),
+ debug_get_real_type ((PTR) info,
+ f2->type, NULL)))
+ return false;
+ }
+ if (*pf1 != NULL || *pf2 != NULL)
+ return false;
+ }
+
+ if (c1->vptrbase != NULL)
+ {
+ if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
+ return false;
+ }
+
+ if (c1->baseclasses != NULL)
+ {
+ struct debug_baseclass **pb1, **pb2;
+
+ for (pb1 = c1->baseclasses, pb2 = c2->baseclasses;
+ *pb1 != NULL && *pb2 != NULL;
+ ++pb1, ++pb2)
+ {
+ struct debug_baseclass *b1, *b2;
+
+ b1 = *pb1;
+ b2 = *pb2;
+ if (b1->bitpos != b2->bitpos
+ || b1->virtual != b2->virtual
+ || b1->visibility != b2->visibility
+ || ! debug_type_samep (info, b1->type, b2->type))
+ return false;
+ }
+ if (*pb1 != NULL || *pb2 != NULL)
+ return false;
+ }
+
+ if (c1->methods != NULL)
+ {
+ struct debug_method **pm1, **pm2;
+
+ for (pm1 = c1->methods, pm2 = c2->methods;
+ *pm1 != NULL && *pm2 != NULL;
+ ++pm1, ++pm2)
+ {
+ struct debug_method *m1, *m2;
+
+ m1 = *pm1;
+ m2 = *pm2;
+ if (m1->name[0] != m2->name[0]
+ || strcmp (m1->name, m2->name) != 0
+ || (m1->variants == NULL) != (m2->variants == NULL))
+ return false;
+ if (m1->variants == NULL)
+ {
+ struct debug_method_variant **pv1, **pv2;
+
+ for (pv1 = m1->variants, pv2 = m2->variants;
+ *pv1 != NULL && *pv2 != NULL;
+ ++pv1, ++pv2)
+ {
+ struct debug_method_variant *v1, *v2;
+
+ v1 = *pv1;
+ v2 = *pv2;
+ if (v1->physname[0] != v2->physname[0]
+ || v1->visibility != v2->visibility
+ || v1->constp != v2->constp
+ || v1->volatilep != v2->volatilep
+ || v1->voffset != v2->voffset
+ || (v1->context == NULL) != (v2->context == NULL)
+ || strcmp (v1->physname, v2->physname) != 0
+ || ! debug_type_samep (info, v1->type, v2->type))
+ return false;
+ if (v1->context != NULL)
+ {
+ if (! debug_type_samep (info, v1->context,
+ v2->context))
+ return false;
+ }
+ }
+ if (*pv1 != NULL || *pv2 != NULL)
+ return false;
+ }
+ }
+ if (*pm1 != NULL || *pm2 != NULL)
+ return false;
+ }
+
+ return true;
+}
diff --git a/binutils/debug.h b/binutils/debug.h
new file mode 100644
index 00000000000..1b890b234f1
--- /dev/null
+++ b/binutils/debug.h
@@ -0,0 +1,798 @@
+/* debug.h -- Describe generic debugging information.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/* This header file describes a generic debugging information format.
+ We may eventually have readers which convert different formats into
+ this generic format, and writers which write it out. The initial
+ impetus for this was writing a convertor from stabs to HP IEEE-695
+ debugging format. */
+
+/* Different kinds of types. */
+
+enum debug_type_kind
+{
+ /* Not used. */
+ DEBUG_KIND_ILLEGAL,
+ /* Indirect via a pointer. */
+ DEBUG_KIND_INDIRECT,
+ /* Void. */
+ DEBUG_KIND_VOID,
+ /* Integer. */
+ DEBUG_KIND_INT,
+ /* Floating point. */
+ DEBUG_KIND_FLOAT,
+ /* Complex. */
+ DEBUG_KIND_COMPLEX,
+ /* Boolean. */
+ DEBUG_KIND_BOOL,
+ /* Struct. */
+ DEBUG_KIND_STRUCT,
+ /* Union. */
+ DEBUG_KIND_UNION,
+ /* Class. */
+ DEBUG_KIND_CLASS,
+ /* Union class (can this really happen?). */
+ DEBUG_KIND_UNION_CLASS,
+ /* Enumeration type. */
+ DEBUG_KIND_ENUM,
+ /* Pointer. */
+ DEBUG_KIND_POINTER,
+ /* Function. */
+ DEBUG_KIND_FUNCTION,
+ /* Reference. */
+ DEBUG_KIND_REFERENCE,
+ /* Range. */
+ DEBUG_KIND_RANGE,
+ /* Array. */
+ DEBUG_KIND_ARRAY,
+ /* Set. */
+ DEBUG_KIND_SET,
+ /* Based pointer. */
+ DEBUG_KIND_OFFSET,
+ /* Method. */
+ DEBUG_KIND_METHOD,
+ /* Const qualified type. */
+ DEBUG_KIND_CONST,
+ /* Volatile qualified type. */
+ DEBUG_KIND_VOLATILE,
+ /* Named type. */
+ DEBUG_KIND_NAMED,
+ /* Tagged type. */
+ DEBUG_KIND_TAGGED
+};
+
+/* Different kinds of variables. */
+
+enum debug_var_kind
+{
+ /* Not used. */
+ DEBUG_VAR_ILLEGAL,
+ /* A global variable. */
+ DEBUG_GLOBAL,
+ /* A static variable. */
+ DEBUG_STATIC,
+ /* A local static variable. */
+ DEBUG_LOCAL_STATIC,
+ /* A local variable. */
+ DEBUG_LOCAL,
+ /* A register variable. */
+ DEBUG_REGISTER
+};
+
+/* Different kinds of function parameters. */
+
+enum debug_parm_kind
+{
+ /* Not used. */
+ DEBUG_PARM_ILLEGAL,
+ /* A stack based parameter. */
+ DEBUG_PARM_STACK,
+ /* A register parameter. */
+ DEBUG_PARM_REG,
+ /* A stack based reference parameter. */
+ DEBUG_PARM_REFERENCE,
+ /* A register reference parameter. */
+ DEBUG_PARM_REF_REG
+};
+
+/* Different kinds of visibility. */
+
+enum debug_visibility
+{
+ /* A public field (e.g., a field in a C struct). */
+ DEBUG_VISIBILITY_PUBLIC,
+ /* A protected field. */
+ DEBUG_VISIBILITY_PROTECTED,
+ /* A private field. */
+ DEBUG_VISIBILITY_PRIVATE,
+ /* A field which should be ignored. */
+ DEBUG_VISIBILITY_IGNORE
+};
+
+/* A type. */
+
+typedef struct debug_type *debug_type;
+
+#define DEBUG_TYPE_NULL ((debug_type) NULL)
+
+/* A field in a struct or union. */
+
+typedef struct debug_field *debug_field;
+
+#define DEBUG_FIELD_NULL ((debug_field) NULL)
+
+/* A base class for an object. */
+
+typedef struct debug_baseclass *debug_baseclass;
+
+#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL)
+
+/* A method of an object. */
+
+typedef struct debug_method *debug_method;
+
+#define DEBUG_METHOD_NULL ((debug_method) NULL)
+
+/* The arguments to a method function of an object. These indicate
+ which method to run. */
+
+typedef struct debug_method_variant *debug_method_variant;
+
+#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL)
+
+/* This structure is passed to debug_write. It holds function
+ pointers that debug_write will call based on the accumulated
+ debugging information. */
+
+struct debug_write_fns
+{
+ /* This is called at the start of each new compilation unit with the
+ name of the main file in the new unit. */
+ boolean (*start_compilation_unit) PARAMS ((PTR, const char *));
+
+ /* This is called at the start of each source file within a
+ compilation unit, before outputting any global information for
+ that file. The argument is the name of the file. */
+ boolean (*start_source) PARAMS ((PTR, const char *));
+
+ /* Each writer must keep a stack of types. */
+
+ /* Push an empty type onto the type stack. This type can appear if
+ there is a reference to a type which is never defined. */
+ boolean (*empty_type) PARAMS ((PTR));
+
+ /* Push a void type onto the type stack. */
+ boolean (*void_type) PARAMS ((PTR));
+
+ /* Push an integer type onto the type stack, given the size and
+ whether it is unsigned. */
+ boolean (*int_type) PARAMS ((PTR, unsigned int, boolean));
+
+ /* Push a floating type onto the type stack, given the size. */
+ boolean (*float_type) PARAMS ((PTR, unsigned int));
+
+ /* Push a complex type onto the type stack, given the size. */
+ boolean (*complex_type) PARAMS ((PTR, unsigned int));
+
+ /* Push a boolean type onto the type stack, given the size. */
+ boolean (*bool_type) PARAMS ((PTR, unsigned int));
+
+ /* Push an enum type onto the type stack, given the tag, a NULL
+ terminated array of names and the associated values. If there is
+ no tag, the tag argument will be NULL. If this is an undefined
+ enum, the names and values arguments will be NULL. */
+ boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
+ bfd_signed_vma *));
+
+ /* Pop the top type on the type stack, and push a pointer to that
+ type onto the type stack. */
+ boolean (*pointer_type) PARAMS ((PTR));
+
+ /* Push a function type onto the type stack. The second argument
+ indicates the number of argument types that have been pushed onto
+ the stack. If the number of argument types is passed as -1, then
+ the argument types of the function are unknown, and no types have
+ been pushed onto the stack. The third argument is true if the
+ function takes a variable number of arguments. The return type
+ of the function is pushed onto the type stack below the argument
+ types, if any. */
+ boolean (*function_type) PARAMS ((PTR, int, boolean));
+
+ /* Pop the top type on the type stack, and push a reference to that
+ type onto the type stack. */
+ boolean (*reference_type) PARAMS ((PTR));
+
+ /* Pop the top type on the type stack, and push a range of that type
+ with the given lower and upper bounds onto the type stack. */
+ boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+
+ /* Push an array type onto the type stack. The top type on the type
+ stack is the range, and the next type on the type stack is the
+ element type. These should be popped before the array type is
+ pushed. The arguments are the lower bound, the upper bound, and
+ whether the array is a string. */
+ boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma,
+ boolean));
+
+ /* Pop the top type on the type stack, and push a set of that type
+ onto the type stack. The argument indicates whether this set is
+ a bitstring. */
+ boolean (*set_type) PARAMS ((PTR, boolean));
+
+ /* Push an offset type onto the type stack. The top type on the
+ type stack is the target type, and the next type on the type
+ stack is the base type. These should be popped before the offset
+ type is pushed. */
+ boolean (*offset_type) PARAMS ((PTR));
+
+ /* Push a method type onto the type stack. If the second argument
+ is true, the top type on the stack is the class to which the
+ method belongs; otherwise, the class must be determined by the
+ class to which the method is attached. The third argument is the
+ number of argument types; these are pushed onto the type stack in
+ reverse order (the first type popped is the last argument to the
+ method). A value of -1 for the third argument means that no
+ argument information is available. The fourth argument is true
+ if the function takes a variable number of arguments. The next
+ type on the type stack below the domain and the argument types is
+ the return type of the method. All these types must be popped,
+ and then the method type must be pushed. */
+ boolean (*method_type) PARAMS ((PTR, boolean, int, boolean));
+
+ /* Pop the top type off the type stack, and push a const qualified
+ version of that type onto the type stack. */
+ boolean (*const_type) PARAMS ((PTR));
+
+ /* Pop the top type off the type stack, and push a volatile
+ qualified version of that type onto the type stack. */
+ boolean (*volatile_type) PARAMS ((PTR));
+
+ /* Start building a struct. This is followed by calls to the
+ struct_field function, and finished by a call to the
+ end_struct_type function. The second argument is the tag; this
+ will be NULL if there isn't one. If the second argument is NULL,
+ the third argument is a constant identifying this struct for use
+ with tag_type. The fourth argument is true for a struct, false
+ for a union. The fifth argument is the size. If this is an
+ undefined struct or union, the size will be 0 and struct_field
+ will not be called before end_struct_type is called. */
+ boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int,
+ boolean, unsigned int));
+
+ /* Add a field to the struct type currently being built. The type
+ of the field should be popped off the type stack. The arguments
+ are the name, the bit position, the bit size (may be zero if the
+ field is not packed), and the visibility. */
+ boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma,
+ enum debug_visibility));
+
+ /* Finish building a struct, and push it onto the type stack. */
+ boolean (*end_struct_type) PARAMS ((PTR));
+
+ /* Start building a class. This is followed by calls to several
+ functions: struct_field, class_static_member, class_baseclass,
+ class_start_method, class_method_variant,
+ class_static_method_variant, and class_end_method. The class is
+ finished by a call to end_class_type. The first five arguments
+ are the same as for start_struct_type. The sixth argument is
+ true if there is a virtual function table; if there is, the
+ seventh argument is true if the virtual function table can be
+ found in the type itself, and is false if the type of the object
+ holding the virtual function table should be popped from the type
+ stack. */
+ boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int,
+ boolean, unsigned int, boolean,
+ boolean));
+
+ /* Add a static member to the class currently being built. The
+ arguments are the field name, the physical name, and the
+ visibility. The type must be popped off the type stack. */
+ boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
+ enum debug_visibility));
+
+ /* Add a baseclass to the class currently being built. The type of
+ the baseclass must be popped off the type stack. The arguments
+ are the bit position, whether the class is virtual, and the
+ visibility. */
+ boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean,
+ enum debug_visibility));
+
+ /* Start adding a method to the class currently being built. This
+ is followed by calls to class_method_variant and
+ class_static_method_variant to describe different variants of the
+ method which take different arguments. The method is finished
+ with a call to class_end_method. The argument is the method
+ name. */
+ boolean (*class_start_method) PARAMS ((PTR, const char *));
+
+ /* Describe a variant to the class method currently being built.
+ The type of the variant must be popped off the type stack. The
+ second argument is the physical name of the function. The
+ following arguments are the visibility, whether the variant is
+ const, whether the variant is volatile, the offset in the virtual
+ function table, and whether the context is on the type stack
+ (below the variant type). */
+ boolean (*class_method_variant) PARAMS ((PTR, const char *,
+ enum debug_visibility,
+ boolean, boolean,
+ bfd_vma, boolean));
+
+ /* Describe a static variant to the class method currently being
+ built. The arguments are the same as for class_method_variant,
+ except that the last two arguments are omitted. The type of the
+ variant must be popped off the type stack. */
+ boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
+ enum debug_visibility,
+ boolean, boolean));
+
+ /* Finish describing a class method. */
+ boolean (*class_end_method) PARAMS ((PTR));
+
+ /* Finish describing a class, and push it onto the type stack. */
+ boolean (*end_class_type) PARAMS ((PTR));
+
+ /* Push a type on the stack which was given a name by an earlier
+ call to typdef. */
+ boolean (*typedef_type) PARAMS ((PTR, const char *));
+
+ /* Push a tagged type on the stack which was defined earlier. If
+ the second argument is not NULL, the type was defined by a call
+ to tag. If the second argument is NULL, the type was defined by
+ a call to start_struct_type or start_class_type with a tag of
+ NULL and the number of the third argument. Either way, the
+ fourth argument is the tag kind. Note that this may be called
+ for a struct (class) being defined, in between the call to
+ start_struct_type (start_class_type) and the call to
+ end_struct_type (end_class_type). */
+ boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int,
+ enum debug_type_kind));
+
+ /* Pop the type stack, and typedef it to the given name. */
+ boolean (*typdef) PARAMS ((PTR, const char *));
+
+ /* Pop the type stack, and declare it as a tagged struct or union or
+ enum or whatever. The tag passed down here is redundant, since
+ was also passed when enum_type, start_struct_type, or
+ start_class_type was called. */
+ boolean (*tag) PARAMS ((PTR, const char *));
+
+ /* This is called to record a named integer constant. */
+ boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma));
+
+ /* This is called to record a named floating point constant. */
+ boolean (*float_constant) PARAMS ((PTR, const char *, double));
+
+ /* This is called to record a typed integer constant. The type is
+ popped off the type stack. */
+ boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma));
+
+ /* This is called to record a variable. The type is popped off the
+ type stack. */
+ boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind,
+ bfd_vma));
+
+ /* Start writing out a function. The return type must be popped off
+ the stack. The boolean is true if the function is global. This
+ is followed by calls to function_parameter, followed by block
+ information. */
+ boolean (*start_function) PARAMS ((PTR, const char *, boolean));
+
+ /* Record a function parameter for the current function. The type
+ must be popped off the stack. */
+ boolean (*function_parameter) PARAMS ((PTR, const char *,
+ enum debug_parm_kind, bfd_vma));
+
+ /* Start writing out a block. There is at least one top level block
+ per function. Blocks may be nested. The argument is the
+ starting address of the block. */
+ boolean (*start_block) PARAMS ((PTR, bfd_vma));
+
+ /* Finish writing out a block. The argument is the ending address
+ of the block. */
+ boolean (*end_block) PARAMS ((PTR, bfd_vma));
+
+ /* Finish writing out a function. */
+ boolean (*end_function) PARAMS ((PTR));
+
+ /* Record line number information for the current compilation unit. */
+ boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+};
+
+/* Exported functions. */
+
+/* The first argument to most of these functions is a handle. This
+ handle is returned by the debug_init function. The purpose of the
+ handle is to permit the debugging routines to not use static
+ variables, and hence to be reentrant. This would be useful for a
+ program which wanted to handle two executables simultaneously. */
+
+/* Return a debugging handle. */
+
+extern PTR debug_init PARAMS ((void));
+
+/* Set the source filename. This implicitly starts a new compilation
+ unit. */
+
+extern boolean debug_set_filename PARAMS ((PTR, const char *));
+
+/* Change source files to the given file name. This is used for
+ include files in a single compilation unit. */
+
+extern boolean debug_start_source PARAMS ((PTR, const char *));
+
+/* Record a function definition. This implicitly starts a function
+ block. The debug_type argument is the type of the return value.
+ The boolean indicates whether the function is globally visible.
+ The bfd_vma is the address of the start of the function. Currently
+ the parameter types are specified by calls to
+ debug_record_parameter. */
+
+extern boolean debug_record_function
+ PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma));
+
+/* Record a parameter for the current function. */
+
+extern boolean debug_record_parameter
+ PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma));
+
+/* End a function definition. The argument is the address where the
+ function ends. */
+
+extern boolean debug_end_function PARAMS ((PTR, bfd_vma));
+
+/* Start a block in a function. All local information will be
+ recorded in this block, until the matching call to debug_end_block.
+ debug_start_block and debug_end_block may be nested. The argument
+ is the address at which this block starts. */
+
+extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
+
+/* Finish a block in a function. This matches the call to
+ debug_start_block. The argument is the address at which this block
+ ends. */
+
+extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
+
+/* Associate a line number in the current source file with a given
+ address. */
+
+extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
+
+/* Start a named common block. This is a block of variables that may
+ move in memory. */
+
+extern boolean debug_start_common_block PARAMS ((PTR, const char *));
+
+/* End a named common block. */
+
+extern boolean debug_end_common_block PARAMS ((PTR, const char *));
+
+/* Record a named integer constant. */
+
+extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma));
+
+/* Record a named floating point constant. */
+
+extern boolean debug_record_float_const PARAMS ((PTR, const char *, double));
+
+/* Record a typed constant with an integral value. */
+
+extern boolean debug_record_typed_const
+ PARAMS ((PTR, const char *, debug_type, bfd_vma));
+
+/* Record a label. */
+
+extern boolean debug_record_label
+ PARAMS ((PTR, const char *, debug_type, bfd_vma));
+
+/* Record a variable. */
+
+extern boolean debug_record_variable
+ PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma));
+
+/* Make an indirect type. The first argument is a pointer to the
+ location where the real type will be placed. The second argument
+ is the type tag, if there is one; this may be NULL; the only
+ purpose of this argument is so that debug_get_type_name can return
+ something useful. This function may be used when a type is
+ referenced before it is defined. */
+
+extern debug_type debug_make_indirect_type
+ PARAMS ((PTR, debug_type *, const char *));
+
+/* Make a void type. */
+
+extern debug_type debug_make_void_type PARAMS ((PTR));
+
+/* Make an integer type of a given size. The boolean argument is true
+ if the integer is unsigned. */
+
+extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean));
+
+/* Make a floating point type of a given size. FIXME: On some
+ platforms, like an Alpha, you probably need to be able to specify
+ the format. */
+
+extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int));
+
+/* Make a boolean type of a given size. */
+
+extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int));
+
+/* Make a complex type of a given size. */
+
+extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int));
+
+/* Make a structure type. The second argument is true for a struct,
+ false for a union. The third argument is the size of the struct.
+ The fourth argument is a NULL terminated array of fields. */
+
+extern debug_type debug_make_struct_type
+ PARAMS ((PTR, boolean, bfd_vma, debug_field *));
+
+/* Make an object type. The first three arguments after the handle
+ are the same as for debug_make_struct_type. The next arguments are
+ a NULL terminated array of base classes, a NULL terminated array of
+ methods, the type of the object holding the virtual function table
+ if it is not this object, and a boolean which is true if this
+ object has its own virtual function table. */
+
+extern debug_type debug_make_object_type
+ PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *,
+ debug_method *, debug_type, boolean));
+
+/* Make an enumeration type. The arguments are a null terminated
+ array of strings, and an array of corresponding values. */
+
+extern debug_type debug_make_enum_type
+ PARAMS ((PTR, const char **, bfd_signed_vma *));
+
+/* Make a pointer to a given type. */
+
+extern debug_type debug_make_pointer_type
+ PARAMS ((PTR, debug_type));
+
+/* Make a function type. The second argument is the return type. The
+ third argument is a NULL terminated array of argument types. The
+ fourth argument is true if the function takes a variable number of
+ arguments. If the third argument is NULL, then the argument types
+ are unknown. */
+
+extern debug_type debug_make_function_type
+ PARAMS ((PTR, debug_type, debug_type *, boolean));
+
+/* Make a reference to a given type. */
+
+extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type));
+
+/* Make a range of a given type from a lower to an upper bound. */
+
+extern debug_type debug_make_range_type
+ PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma));
+
+/* Make an array type. The second argument is the type of an element
+ of the array. The third argument is the type of a range of the
+ array. The fourth and fifth argument are the lower and upper
+ bounds, respectively (if the bounds are not known, lower should be
+ 0 and upper should be -1). The sixth argument is true if this
+ array is actually a string, as in C. */
+
+extern debug_type debug_make_array_type
+ PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma,
+ boolean));
+
+/* Make a set of a given type. For example, a Pascal set type. The
+ boolean argument is true if this set is actually a bitstring, as in
+ CHILL. */
+
+extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean));
+
+/* Make a type for a pointer which is relative to an object. The
+ second argument is the type of the object to which the pointer is
+ relative. The third argument is the type that the pointer points
+ to. */
+
+extern debug_type debug_make_offset_type
+ PARAMS ((PTR, debug_type, debug_type));
+
+/* Make a type for a method function. The second argument is the
+ return type. The third argument is the domain. The fourth
+ argument is a NULL terminated array of argument types. The fifth
+ argument is true if the function takes a variable number of
+ arguments, in which case the array of argument types indicates the
+ types of the first arguments. The domain and the argument array
+ may be NULL, in which case this is a stub method and that
+ information is not available. Stabs debugging uses this, and gets
+ the argument types from the mangled name. */
+
+extern debug_type debug_make_method_type
+ PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean));
+
+/* Make a const qualified version of a given type. */
+
+extern debug_type debug_make_const_type PARAMS ((PTR, debug_type));
+
+/* Make a volatile qualified version of a given type. */
+
+extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type));
+
+/* Make an undefined tagged type. For example, a struct which has
+ been mentioned, but not defined. */
+
+extern debug_type debug_make_undefined_tagged_type
+ PARAMS ((PTR, const char *, enum debug_type_kind));
+
+/* Make a base class for an object. The second argument is the base
+ class type. The third argument is the bit position of this base
+ class in the object. The fourth argument is whether this is a
+ virtual class. The fifth argument is the visibility of the base
+ class. */
+
+extern debug_baseclass debug_make_baseclass
+ PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility));
+
+/* Make a field for a struct. The second argument is the name. The
+ third argument is the type of the field. The fourth argument is
+ the bit position of the field. The fifth argument is the size of
+ the field (it may be zero). The sixth argument is the visibility
+ of the field. */
+
+extern debug_field debug_make_field
+ PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma,
+ enum debug_visibility));
+
+/* Make a static member of an object. The second argument is the
+ name. The third argument is the type of the member. The fourth
+ argument is the physical name of the member (i.e., the name as a
+ global variable). The fifth argument is the visibility of the
+ member. */
+
+extern debug_field debug_make_static_member
+ PARAMS ((PTR, const char *, debug_type, const char *,
+ enum debug_visibility));
+
+/* Make a method. The second argument is the name, and the third
+ argument is a NULL terminated array of method variants. Each
+ method variant is a method with this name but with different
+ argument types. */
+
+extern debug_method debug_make_method
+ PARAMS ((PTR, const char *, debug_method_variant *));
+
+/* Make a method variant. The second argument is the physical name of
+ the function. The third argument is the type of the function,
+ probably constructed by debug_make_method_type. The fourth
+ argument is the visibility. The fifth argument is whether this is
+ a const function. The sixth argument is whether this is a volatile
+ function. The seventh argument is the index in the virtual
+ function table, if any. The eighth argument is the virtual
+ function context. */
+
+extern debug_method_variant debug_make_method_variant
+ PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
+ boolean, bfd_vma, debug_type));
+
+/* Make a static method argument. The arguments are the same as for
+ debug_make_method_variant, except that the last two are omitted
+ since a static method can not also be virtual. */
+
+extern debug_method_variant debug_make_static_method_variant
+ PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean,
+ boolean));
+
+/* Name a type. This returns a new type with an attached name. */
+
+extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type));
+
+/* Give a tag to a type, such as a struct or union. This returns a
+ new type with an attached tag. */
+
+extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type));
+
+/* Record the size of a given type. */
+
+extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int));
+
+/* Find a named type. */
+
+extern debug_type debug_find_named_type PARAMS ((PTR, const char *));
+
+/* Find a tagged type. */
+
+extern debug_type debug_find_tagged_type
+ PARAMS ((PTR, const char *, enum debug_type_kind));
+
+/* Get the kind of a type. */
+
+extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type));
+
+/* Get the name of a type. */
+
+extern const char *debug_get_type_name PARAMS ((PTR, debug_type));
+
+/* Get the size of a type. */
+
+extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type));
+
+/* Get the return type of a function or method type. */
+
+extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
+
+/* Get the NULL terminated array of parameter types for a function or
+ method type (actually, parameter types are not currently stored for
+ function types). This may be used to determine whether a method
+ type is a stub method or not. The last argument points to a
+ boolean which is set to true if the function takes a variable
+ number of arguments. */
+
+extern const debug_type *debug_get_parameter_types PARAMS ((PTR,
+ debug_type,
+ boolean *));
+
+/* Get the target type of a pointer or reference or const or volatile
+ type. */
+
+extern debug_type debug_get_target_type PARAMS ((PTR, debug_type));
+
+/* Get the NULL terminated array of fields for a struct, union, or
+ class. */
+
+extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type));
+
+/* Get the type of a field. */
+
+extern debug_type debug_get_field_type PARAMS ((PTR, debug_field));
+
+/* Get the name of a field. */
+
+extern const char *debug_get_field_name PARAMS ((PTR, debug_field));
+
+/* Get the bit position of a field within the containing structure.
+ If the field is a static member, this will return (bfd_vma) -1. */
+
+extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field));
+
+/* Get the bit size of a field. If the field is a static member, this
+ will return (bfd_vma) -1. */
+
+extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field));
+
+/* Get the visibility of a field. */
+
+extern enum debug_visibility debug_get_field_visibility
+ PARAMS ((PTR, debug_field));
+
+/* Get the physical name of a field, if it is a static member. If the
+ field is not a static member, this will return NULL. */
+
+extern const char *debug_get_field_physname PARAMS ((PTR, debug_field));
+
+/* Write out the recorded debugging information. This takes a set of
+ function pointers which are called to do the actual writing. The
+ first PTR is the debugging handle. The second PTR is a handle
+ which is passed to the functions. */
+
+extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR));
+
+#endif /* DEBUG_H */
diff --git a/binutils/deflex.l b/binutils/deflex.l
new file mode 100644
index 00000000000..e7fa3626394
--- /dev/null
+++ b/binutils/deflex.l
@@ -0,0 +1,86 @@
+%{/* deflex.l - Lexer for .def files */
+
+/* Copyright (C) 1995, 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* Contributed by Steve Chamberlain
+ sac@cygnus.com
+
+*/
+#define DONTDECLARE_MALLOC
+#include "libiberty.h"
+#include "defparse.h"
+#include "dlltool.h"
+
+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 VERSIONK;}
+"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 = xstrdup (yytext);
+ return ID;
+ }
+
+"\""[^\"]*"\"" {
+ yylval.id = xstrdup (yytext+1);
+ yylval.id[yyleng-2] = 0;
+ return ID;
+ }
+
+"\'"[^\']*"\'" {
+ yylval.id = xstrdup (yytext+1);
+ yylval.id[yyleng-2] = 0;
+ return ID;
+ }
+"*".* { }
+";".* { }
+" " { }
+"\t" { }
+"\n" { linenumber ++ ;}
+"=" { return '=';}
+"." { return '.';}
+"@" { return '@';}
+"," { return ',';}
+%%
+#ifndef yywrap
+/* Needed for lex, though not flex. */
+int yywrap() { return 1; }
+#endif
diff --git a/binutils/defparse.y b/binutils/defparse.y
new file mode 100644
index 00000000000..1cb63609615
--- /dev/null
+++ b/binutils/defparse.y
@@ -0,0 +1,157 @@
+%{ /* defparse.y - parser for .def files */
+
+/* Copyright (C) 1995, 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "dlltool.h"
+%}
+
+%union {
+ char *id;
+ int number;
+};
+
+%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA
+%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT
+%token READ WRITE EXECUTE SHARED NONAME
+%token <id> ID
+%token <number> NUMBER
+%type <number> opt_base opt_ordinal opt_NONAME opt_CONSTANT opt_DATA
+%type <number> attr attr_list opt_number
+%type <id> opt_name opt_equal_name
+
+%%
+
+start: start command
+ | command
+ ;
+
+command:
+ NAME opt_name opt_base { def_name ($2, $3); }
+ | LIBRARY opt_name opt_base { def_library ($2, $3); }
+ | EXPORTS explist
+ | DESCRIPTION ID { def_description ($2);}
+ | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
+ | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
+ | CODE attr_list { def_code ($2);}
+ | DATA attr_list { def_data ($2);}
+ | SECTIONS seclist
+ | IMPORTS implist
+ | VERSIONK NUMBER { def_version ($2,0);}
+ | VERSIONK NUMBER '.' NUMBER { def_version ($2,$4);}
+ ;
+
+
+explist:
+ /* EMPTY */
+ | expline
+ | explist expline
+ ;
+
+expline:
+ ID opt_equal_name opt_ordinal opt_NONAME opt_CONSTANT opt_DATA
+ { def_exports ($1, $2, $3, $4, $5, $6);}
+ ;
+implist:
+ implist impline
+ | impline
+ ;
+
+impline:
+ ID '=' ID '.' ID '.' ID { def_import ($1,$3,$5,$7, 0); }
+ | ID '=' ID '.' ID '.' NUMBER { def_import ($1,$3,$5, 0,$7); }
+ | ID '=' ID '.' ID { def_import ($1,$3, 0,$5, 0); }
+ | ID '=' ID '.' NUMBER { def_import ($1,$3, 0, 0,$5); }
+ | ID '.' ID '.' ID { def_import ( 0,$1,$3,$5, 0); }
+ | ID '.' ID '.' NUMBER { def_import ( 0,$1,$3, 0,$5); }
+ | ID '.' ID { def_import ( 0,$1, 0,$3, 0); }
+ | ID '.' NUMBER { def_import ( 0,$1, 0, 0,$3); }
+;
+
+seclist:
+ seclist secline
+ | secline
+ ;
+
+secline:
+ ID attr_list { def_section ($1,$2);}
+ ;
+
+attr_list:
+ attr_list opt_comma attr
+ | attr
+ ;
+
+opt_comma:
+ ','
+ |
+ ;
+opt_number: ',' NUMBER { $$=$2;}
+ | { $$=-1;}
+ ;
+
+attr:
+ READ { $$ = 1;}
+ | WRITE { $$ = 2;}
+ | EXECUTE { $$=4;}
+ | SHARED { $$=8;}
+ ;
+
+opt_CONSTANT:
+ CONSTANT {$$=1;}
+ | {$$=0;}
+ ;
+
+opt_NONAME:
+ NONAME {$$=1;}
+ | {$$=0;}
+ ;
+
+opt_DATA:
+ DATA { $$ = 1; }
+ | { $$ = 0; }
+ ;
+
+opt_name: ID { $$ =$1; }
+ | ID '.' ID
+ {
+ char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
+ sprintf (name, "%s.%s", $1, $3);
+ $$ = name;
+ }
+ | { $$=""; }
+ ;
+
+opt_ordinal:
+ '@' NUMBER { $$=$2;}
+ | { $$=-1;}
+ ;
+
+opt_equal_name:
+ '=' ID { $$ = $2; }
+ | { $$ = 0; }
+ ;
+
+opt_base: BASE '=' NUMBER { $$= $3;}
+ | { $$=-1;}
+ ;
+
+
+
diff --git a/binutils/dep-in.sed b/binutils/dep-in.sed
new file mode 100644
index 00000000000..f61921a4828
--- /dev/null
+++ b/binutils/dep-in.sed
@@ -0,0 +1,17 @@
+:loop
+/\\$/N
+/\\$/b loop
+
+s!@INCDIR@!$(INCDIR)!g
+s!@BFDDIR@!$(BFDDIR)!g
+s!@SRCDIR@/!!g
+s!@OBJDIR@/!!g
+
+s/\\\n */ /g
+
+s/ *$//
+s/ */ /g
+/:$/d
+
+s/\(.\{50\}[^ ]*\) /\1 \\\
+ /g
diff --git a/binutils/dlltool.c b/binutils/dlltool.c
new file mode 100644
index 00000000000..ed5cf5e3fcc
--- /dev/null
+++ b/binutils/dlltool.c
@@ -0,0 +1,3199 @@
+/* dlltool.c -- tool to generate stuff for PE style DLLs
+ Copyright (C) 1995, 96, 97, 98, 1999 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/*
+ This program allows you to build the files necessary to create
+ DLLs to run on a system which understands PE format image files.
+ (eg, Windows NT)
+
+ See "Peering Inside the PE: A Tour of the Win32 Portable Executable
+ File Format", MSJ 1994, Volume 9 for more information.
+ Also see "Microsoft Portable Executable and Common Object File Format,
+ Specification 4.1" for more information.
+
+ A DLL contains an export table which contains the information
+ which the runtime loader needs to tie up references from a
+ referencing program.
+
+ The export table is generated by this program by reading
+ in a .DEF file or scanning the .a and .o files which will be in the
+ DLL. A .o file can contain information in special ".drectve" sections
+ with export information.
+
+ A DEF file contains any number of the following commands:
+
+
+ NAME <name> [ , <base> ]
+ The result is going to be <name>.EXE
+
+ LIBRARY <name> [ , <base> ]
+ The result is going to be <name>.DLL
+
+ EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
+ Declares name1 as an exported symbol from the
+ DLL, with optional ordinal number <integer>
+
+ IMPORTS ( ( <internal-name> = <module-name> . <integer> )
+ | ( [ <internal-name> = ] <module-name> . <external-name> )) *
+ Declares that <external-name> or the exported function whoes ordinal number
+ is <integer> is to be imported from the file <module-name>. If
+ <internal-name> is specified then this is the name that the imported
+ function will be refered to in the body of the DLL.
+
+ DESCRIPTION <string>
+ Puts <string> into output .exp file in the .rdata section
+
+ [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
+ Generates --stack|--heap <number-reserve>,<number-commit>
+ in the output .drectve section. The linker will
+ see this and act upon it.
+
+ [CODE|DATA] <attr>+
+ SECTIONS ( <sectionname> <attr>+ )*
+ <attr> = READ | WRITE | EXECUTE | SHARED
+ Generates --attr <sectionname> <attr> in the output
+ .drectve section. The linker will see this and act
+ upon it.
+
+
+ A -export:<name> in a .drectve section in an input .o or .a
+ file to this program is equivalent to a EXPORTS <name>
+ in a .DEF file.
+
+
+
+ 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 .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:
+
+ file1.c:
+ asm (".section .drectve");
+ asm (".ascii \"-export:adef\"");
+
+ void adef (char * s)
+ {
+ printf ("hello from the dll %s\n", s);
+ }
+
+ void 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\"");
+
+ void cdef (char * s)
+ {
+ printf ("hello from the dll %s\n", s);
+ }
+
+ void ddef (char * s)
+ {
+ printf ("hello from the dll and the other entry point %s\n", s);
+ }
+
+ printf()
+ {
+ return 9;
+ }
+
+ main.c
+
+ void main()
+ {
+ cdef();
+ }
+
+ thedll.def
+
+ LIBRARY thedll
+ HEAPSIZE 0x40000, 0x2000
+ EXPORTS bdef @ 20
+ cdef @ 30 NONAME
+
+ SECTIONS donkey READ WRITE
+ aardvark EXECUTE
+
+ # compile up the parts of the dll
+
+ 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)
+
+ ar qcv thedll.in file1.o file2.o
+ ranlib thedll.in
+
+ # run this tool over the library and the def file
+ ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
+
+ # build the dll with the library with file1.o, file2.o and the export table
+ ld -o thedll.dll thedll.o thedll.in
+
+ # 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.a
+
+ */
+
+/* .idata section description
+
+ The .idata section is the import table. It is a collection of several
+ subsections used to keep the pieces for each dll together: .idata$[234567].
+ IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
+
+ .idata$2 = Import Directory Table
+ = array of IMAGE_IMPORT_DESCRIPTOR's.
+
+ DWORD Import Lookup Table; - pointer to .idata$4
+ DWORD TimeDateStamp; - currently always 0
+ DWORD ForwarderChain; - currently always 0
+ DWORD Name; - pointer to dll's name
+ PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
+
+ .idata$3 = null terminating entry for .idata$2.
+
+ .idata$4 = Import Lookup Table
+ = array of array of pointers to hint name table.
+ There is one for each dll being imported from, and each dll's set is
+ terminated by a trailing NULL.
+
+ .idata$5 = Import Address Table
+ = array of array of pointers to hint name table.
+ There is one for each dll being imported from, and each dll's set is
+ terminated by a trailing NULL.
+ Initially, this table is identical to the Import Lookup Table. However,
+ at load time, the loader overwrites the entries with the address of the
+ function.
+
+ .idata$6 = Hint Name Table
+ = Array of { short, asciz } entries, one for each imported function.
+ The `short' is the function's ordinal number.
+
+ .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
+*/
+
+/* AIX requires this to be the first thing in the file. */
+#ifndef __GNUC__
+# ifdef _AIX
+ #pragma alloca
+#endif
+#endif
+
+#define show_allnames 0
+
+#define PAGE_SIZE 4096
+#define PAGE_MASK (-PAGE_SIZE)
+#include "bfd.h"
+#include "libiberty.h"
+#include "bucomm.h"
+#include "getopt.h"
+#include "demangle.h"
+#include "dlltool.h"
+
+#include <ctype.h>
+#include <time.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef DLLTOOL_ARM
+#include "coff/arm.h"
+#include "coff/internal.h"
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#else /* ! HAVE_SYS_WAIT_H */
+#if ! defined (_WIN32) || defined (__CYGWIN32__)
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w)&0377) == 0)
+#endif
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0177)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) >> 8) & 0377)
+#endif
+#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w) & 0xff) == 0)
+#endif
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0x7f)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
+#endif
+#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
+#endif /* ! HAVE_SYS_WAIT_H */
+
+/* ifunc and ihead data structures: ttk@cygnus.com 1997
+
+ When IMPORT declarations are encountered in a .def file the
+ function import information is stored in a structure referenced by
+ the global variable IMPORT_LIST. The structure is a linked list
+ containing the names of the dll files each function is imported
+ from and a linked list of functions being imported from that dll
+ file. This roughly parallels the structure of the .idata section
+ in the PE object file.
+
+ The contents of .def file are interpreted from within the
+ process_def_file function. Every time an IMPORT declaration is
+ encountered, it is broken up into its component parts and passed to
+ def_import. IMPORT_LIST is initialized to NULL in function main. */
+
+typedef struct ifunct
+{
+ char *name; /* name of function being imported */
+ int ord; /* two-byte ordinal value associated with function */
+ struct ifunct *next;
+} ifunctype;
+
+typedef struct iheadt
+{
+ char *dllname; /* name of dll file imported from */
+ long nfuncs; /* number of functions in list */
+ struct ifunct *funchead; /* first function in list */
+ struct ifunct *functail; /* last function in list */
+ struct iheadt *next; /* next dll file in list */
+} iheadtype;
+
+/* Structure containing all import information as defined in .def file
+ (qv "ihead structure"). */
+
+static iheadtype *import_list = NULL;
+
+static char *as_name = "as";
+static char * as_flags = "";
+
+static int no_idata4;
+static int no_idata5;
+static char *exp_name;
+static char *imp_name;
+static char *head_label;
+static char *imp_name_lab;
+static char *dll_name;
+
+static int add_indirect = 0;
+static int add_underscore = 0;
+static int dontdeltemps = 0;
+
+#ifdef DLLTOOL_ARM
+static int interwork = 0;
+#endif
+
+/* True if we should export all symbols. Otherwise, we only export
+ symbols listed in .drectve sections or in the def file. */
+static boolean export_all_symbols;
+
+/* True if we should exclude the symbols in DEFAULT_EXCLUDES when
+ exporting all symbols. */
+static boolean do_default_excludes;
+
+/* Default symbols to exclude when exporting all the symbols. */
+static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";
+
+static char *def_file;
+
+extern char * program_name;
+
+static int machine;
+static int killat;
+static int add_stdcall_alias;
+static int verbose;
+static FILE *output_def;
+static FILE *base_file;
+
+#ifdef DLLTOOL_BEOS
+static const char *mname = "beos";
+#endif
+
+#ifdef DLLTOOL_ARM
+static const char *mname = "arm";
+#endif
+
+#ifdef DLLTOOL_I386
+static const char *mname = "i386";
+#endif
+
+#ifdef DLLTOOL_PPC
+static const char *mname = "ppc";
+#endif
+
+#define PATHMAX 250 /* What's the right name for this ? */
+
+#define TMP_ASM "dc.s"
+#define TMP_HEAD_S "dh.s"
+#define TMP_HEAD_O "dh.o"
+#define TMP_TAIL_S "dt.s"
+#define TMP_TAIL_O "dt.o"
+#define TMP_STUB "ds"
+
+/* This bit of assemly does jmp * ....
+s set how_jtab_roff to mark where the 32bit abs branch should go */
+static const unsigned char i386_jtab[] =
+{
+ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
+};
+
+static const unsigned char arm_jtab[] =
+{
+ 0x00, 0xc0, 0x9f, 0xe5,
+ 0x00, 0xf0, 0x9c, 0xe5,
+ 0, 0, 0, 0
+};
+
+static const unsigned char thumb_jtab[] =
+{
+ 0xc0, 0xb4,
+ 0x02, 0x4e,
+ 0x36, 0x68,
+ 0x01, 0x96,
+ 0x40, 0xbd,
+ 0xc0, 0x46,
+ 0, 0, 0, 0
+};
+
+/* This is the glue sequence for PowerPC PE. There is a */
+/* tocrel16-tocdefn reloc against the first instruction. */
+/* We also need a IMGLUE reloc against the glue function */
+/* to restore the toc saved by the third instruction in */
+/* the glue. */
+static const unsigned char ppc_jtab[] =
+{
+ 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
+ /* Reloc TOCREL16 __imp_xxx */
+ 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
+ 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
+ 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
+ 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
+ 0x20, 0x04, 0x80, 0x4E /* bctr */
+};
+
+#ifdef DLLTOOL_PPC
+/* the glue instruction, picks up the toc from the stw in */
+/* the above code: "lwz r2,4(r1)" */
+static bfd_vma ppc_glue_insn = 0x80410004;
+#endif
+
+/* The outfile array must be big enough to contain a fully
+ qualified path name, plus an arbitary series of command
+ line switches. We hope that PATH_MAX times two will be
+ enough. */
+static char outfile [PATHMAX * 2];
+
+struct mac
+ {
+ const char *type;
+ const char *how_byte;
+ const char *how_short;
+ const char *how_long;
+ const char *how_asciz;
+ const char *how_comment;
+ const char *how_jump;
+ const char *how_global;
+ const char *how_space;
+ const char *how_align_short;
+ const char *how_align_long;
+ const char *how_bfd_target;
+ enum bfd_architecture how_bfd_arch;
+ const unsigned char *how_jtab;
+ int how_jtab_size; /* size of the jtab entry */
+ int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
+ };
+
+static const struct mac
+mtable[] =
+{
+ {
+#define MARM 0
+ "arm", ".byte", ".short", ".long", ".asciz", "@",
+ "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
+ ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
+ arm_jtab, sizeof (arm_jtab), 8
+ }
+ ,
+ {
+#define M386 1
+ "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
+ i386_jtab, sizeof (i386_jtab), 2
+ }
+ ,
+ {
+#define MPPC 2
+ "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
+ ppc_jtab, sizeof (ppc_jtab), 0
+ }
+ ,
+ {
+#define MTHUMB 3
+ "thumb", ".byte", ".short", ".long", ".asciz", "@",
+ "push\t{r6, r7}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tstr\tr6, [sp, #4]\n\tpop\t{r6, pc}\n\tnop",
+ ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
+ thumb_jtab, sizeof (thumb_jtab), 12
+ }
+ ,
+{ 0}
+};
+
+typedef struct dlist
+{
+ char *text;
+ struct dlist *next;
+}
+dlist_type;
+
+typedef struct export
+ {
+ const char *name;
+ const char *internal_name;
+ int ordinal;
+ int constant;
+ int noname;
+ int data;
+ int hint;
+ struct export *next;
+ }
+export_type;
+
+/* A list of symbols which we should not export. */
+
+struct string_list
+{
+ struct string_list *next;
+ char *string;
+};
+
+static struct string_list *excludes;
+
+static const char *rvaafter PARAMS ((int));
+static const char *rvabefore PARAMS ((int));
+static const char *asm_prefix PARAMS ((int));
+static void append_import PARAMS ((const char *, const char *, int));
+static void run PARAMS ((const char *, char *));
+static void scan_drectve_symbols PARAMS ((bfd *));
+static void scan_filtered_symbols PARAMS ((bfd *, PTR, long, unsigned int));
+static void add_excludes PARAMS ((const char *));
+static boolean match_exclude PARAMS ((const char *));
+static void set_default_excludes PARAMS ((void));
+static long filter_symbols PARAMS ((bfd *, PTR, long, unsigned int));
+static void scan_all_symbols PARAMS ((bfd *));
+static void scan_open_obj_file PARAMS ((bfd *));
+static void scan_obj_file PARAMS ((const char *));
+static void dump_def_info PARAMS ((FILE *));
+static int sfunc PARAMS ((const void *, const void *));
+static void flush_page PARAMS ((FILE *, long *, int, int));
+static void gen_def_file PARAMS ((void));
+static void generate_idata_ofile PARAMS ((FILE *));
+static void gen_exp_file PARAMS ((void));
+static const char *xlate PARAMS ((const char *));
+#if 0
+static void dump_iat PARAMS ((FILE *, export_type *));
+#endif
+static char *make_label PARAMS ((const char *, const char *));
+static bfd *make_one_lib_file PARAMS ((export_type *, int));
+static bfd *make_head PARAMS ((void));
+static bfd *make_tail PARAMS ((void));
+static void gen_lib_file PARAMS ((void));
+static int pfunc PARAMS ((const void *, const void *));
+static int nfunc PARAMS ((const void *, const void *));
+static void remove_null_names PARAMS ((export_type **));
+static void dtab PARAMS ((export_type **));
+static void process_duplicates PARAMS ((export_type **));
+static void fill_ordinals PARAMS ((export_type **));
+static int alphafunc PARAMS ((const void *, const void *));
+static void mangle_defs PARAMS ((void));
+static void usage PARAMS ((FILE *, int));
+static void display PARAMS ((const char *, va_list));
+static void inform PARAMS ((const char *, ...));
+static void warn PARAMS ((const char *, ...));
+
+static void
+display (message, args)
+ const char * message;
+ va_list args;
+{
+ if (program_name != NULL)
+ fprintf (stderr, "%s: ", program_name);
+
+ vfprintf (stderr, message, args);
+
+ if (message [strlen (message) - 1] != '\n')
+ fputc ('\n', stderr);
+}
+
+
+static void
+#ifdef __STDC__
+inform (const char * message, ...)
+#else
+inform (message, va_alist)
+ const char * message;
+ va_dcl
+#endif
+{
+ va_list args;
+
+ if (!verbose)
+ return;
+
+#ifdef __STDC__
+ va_start (args, message);
+#else
+ va_start (args);
+#endif
+
+ display (message, args);
+
+ va_end (args);
+}
+
+static void
+#ifdef __STDC__
+warn (const char * message, ...)
+#else
+warn (message, va_alist)
+ const char * message;
+ va_dcl
+#endif
+{
+ va_list args;
+
+#ifdef __STDC__
+ va_start (args, message);
+#else
+ va_start (args);
+#endif
+
+ display (message, args);
+
+ va_end (args);
+}
+
+static const char *
+rvaafter (machine)
+ int machine;
+{
+ switch (machine)
+ {
+ case MARM:
+ case M386:
+ case MPPC:
+ case MTHUMB:
+ break;
+ default:
+ /* xgettext:c-format */
+ fatal (_("Internal error: Unknown machine type: %d\n"), machine);
+ break;
+ }
+ return "";
+}
+
+static const char *
+rvabefore (machine)
+ int machine;
+{
+ switch (machine)
+ {
+ case MARM:
+ case M386:
+ case MPPC:
+ case MTHUMB:
+ return ".rva\t";
+ default:
+ /* xgettext:c-format */
+ fatal (_("Internal error: Unknown machine type: %d\n"), machine);
+ break;
+ }
+ return "";
+}
+
+static const char *
+asm_prefix (machine)
+ int machine;
+{
+ switch (machine)
+ {
+ case MARM:
+ case MPPC:
+ case MTHUMB:
+ break;
+ case M386:
+ return "_";
+ default:
+ /* xgettext:c-format */
+ fatal (_("Internal error: Unknown machine type: %d\n"), machine);
+ break;
+ }
+ return "";
+}
+
+#define ASM_BYTE mtable[machine].how_byte
+#define ASM_SHORT mtable[machine].how_short
+#define ASM_LONG mtable[machine].how_long
+#define ASM_TEXT mtable[machine].how_asciz
+#define ASM_C mtable[machine].how_comment
+#define ASM_JUMP mtable[machine].how_jump
+#define ASM_GLOBAL mtable[machine].how_global
+#define ASM_SPACE mtable[machine].how_space
+#define ASM_ALIGN_SHORT mtable[machine].how_align_short
+#define ASM_RVA_BEFORE rvabefore(machine)
+#define ASM_RVA_AFTER rvaafter(machine)
+#define ASM_PREFIX asm_prefix(machine)
+#define ASM_ALIGN_LONG mtable[machine].how_align_long
+#define HOW_BFD_TARGET 0 /* always default*/
+#define HOW_BFD_ARCH mtable[machine].how_bfd_arch
+#define HOW_JTAB mtable[machine].how_jtab
+#define HOW_JTAB_SIZE mtable[machine].how_jtab_size
+#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
+static char **oav;
+
+void
+process_def_file (name)
+ const char *name;
+{
+ FILE *f = fopen (name, FOPEN_RT);
+
+ if (!f)
+ /* xgettext:c-format */
+ fatal (_("Can't open def file: %s"), name);
+
+ yyin = f;
+
+ /* xgettext:c-format */
+ inform (_("Processing def file: %s"), name);
+
+ yyparse ();
+
+ inform (_("Processed def file"));
+}
+
+/**********************************************************************/
+
+/* Communications with the parser */
+
+static const char *d_name; /* Arg to NAME or LIBRARY */
+static int d_nfuncs; /* Number of functions exported */
+static int d_named_nfuncs; /* Number of named functions exported */
+static int d_low_ord; /* Lowest ordinal index */
+static int d_high_ord; /* Highest ordinal index */
+static export_type *d_exports; /*list of exported functions */
+static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
+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;
+
+int
+yyerror (err)
+ const char *err;
+{
+ /* xgettext:c-format */
+ warn (_("Syntax error in def file %s:%d\n"), def_file, linenumber);
+
+ return 0;
+}
+
+void
+def_exports (name, internal_name, ordinal, noname, constant, data)
+ const char *name;
+ const char *internal_name;
+ int ordinal;
+ int noname;
+ int constant;
+ int data;
+{
+ struct export *p = (struct export *) xmalloc (sizeof (*p));
+
+ p->name = name;
+ p->internal_name = internal_name ? internal_name : name;
+ p->ordinal = ordinal;
+ p->constant = constant;
+ p->noname = noname;
+ p->data = data;
+ p->next = d_exports;
+ d_exports = p;
+ d_nfuncs++;
+}
+
+void
+def_name (name, base)
+ const char *name;
+ int base;
+{
+ /* xgettext:c-format */
+ inform (_("NAME: %s base: %x"), name, base);
+
+ if (d_is_dll)
+ warn (_("Can't have LIBRARY and NAME\n"));
+
+ d_name = name;
+ /* if --dllname not provided, use the one in the DEF file.
+ FIXME: Is this appropriate for executables? */
+ if (! dll_name)
+ dll_name = xstrdup (name);
+ d_is_exe = 1;
+}
+
+void
+def_library (name, base)
+ const char *name;
+ int base;
+{
+ /* xgettext:c-format */
+ inform (_("LIBRARY: %s base: %x"), name, base);
+
+ if (d_is_exe)
+ warn (_("%s: Can't have LIBRARY and NAME\n"), program_name);
+
+ d_name = name;
+ /* if --dllname not provided, use the one in the DEF file. */
+ if (! dll_name)
+ dll_name = xstrdup (name);
+ d_is_dll = 1;
+}
+
+void
+def_description (desc)
+ const char *desc;
+{
+ dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
+ d->text = xstrdup (desc);
+ d->next = d_list;
+ d_list = d;
+}
+
+void
+new_directive (dir)
+ char *dir;
+{
+ dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
+ d->text = xstrdup (dir);
+ d->next = a_list;
+ a_list = d;
+}
+
+void
+def_heapsize (reserve, commit)
+ int reserve;
+ 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 (xstrdup (b));
+}
+
+void
+def_stacksize (reserve, commit)
+ int reserve;
+ 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 (xstrdup (b));
+}
+
+/* append_import simply adds the given import definition to the global
+ import_list. It is used by def_import. */
+
+static void
+append_import (symbol_name, dll_name, func_ordinal)
+ const char *symbol_name;
+ const char *dll_name;
+ int func_ordinal;
+{
+ iheadtype **pq;
+ iheadtype *q;
+
+ for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
+ {
+ if (strcmp ((*pq)->dllname, dll_name) == 0)
+ {
+ q = *pq;
+ q->functail->next = xmalloc (sizeof (ifunctype));
+ q->functail = q->functail->next;
+ q->functail->ord = func_ordinal;
+ q->functail->name = xstrdup (symbol_name);
+ q->functail->next = NULL;
+ q->nfuncs++;
+ return;
+ }
+ }
+
+ q = xmalloc (sizeof (iheadtype));
+ q->dllname = xstrdup (dll_name);
+ q->nfuncs = 1;
+ q->funchead = xmalloc (sizeof (ifunctype));
+ q->functail = q->funchead;
+ q->next = NULL;
+ q->functail->name = xstrdup (symbol_name);
+ q->functail->ord = func_ordinal;
+ q->functail->next = NULL;
+
+ *pq = q;
+}
+
+/* def_import is called from within defparse.y when an IMPORT
+ declaration is encountered. Depending on the form of the
+ declaration, the module name may or may not need ".dll" to be
+ appended to it, the name of the function may be stored in internal
+ or entry, and there may or may not be an ordinal value associated
+ with it. */
+
+/* A note regarding the parse modes:
+ In defparse.y we have to accept import declarations which follow
+ any one of the following forms:
+ <func_name_in_app> = <dll_name>.<func_name_in_dll>
+ <func_name_in_app> = <dll_name>.<number>
+ <dll_name>.<func_name_in_dll>
+ <dll_name>.<number>
+ Furthermore, the dll's name may or may not end with ".dll", which
+ complicates the parsing a little. Normally the dll's name is
+ passed to def_import() in the "module" parameter, but when it ends
+ with ".dll" it gets passed in "module" sans ".dll" and that needs
+ to be reappended.
+
+ def_import gets five parameters:
+ APP_NAME - the name of the function in the application, if
+ present, or NULL if not present.
+ MODULE - the name of the dll, possibly sans extension (ie, '.dll').
+ DLLEXT - the extension of the dll, if present, NULL if not present.
+ ENTRY - the name of the function in the dll, if present, or NULL.
+ ORD_VAL - the numerical tag of the function in the dll, if present,
+ or NULL. Exactly one of <entry> or <ord_val> must be
+ present (i.e., not NULL). */
+
+void
+def_import (app_name, module, dllext, entry, ord_val)
+ const char *app_name;
+ const char *module;
+ const char *dllext;
+ const char *entry;
+ int ord_val;
+{
+ const char *application_name;
+ char *buf;
+
+ if (entry != NULL)
+ application_name = entry;
+ else
+ {
+ if (app_name != NULL)
+ application_name = app_name;
+ else
+ application_name = "";
+ }
+
+ if (dllext != NULL)
+ {
+ buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
+ sprintf (buf, "%s.%s", module, dllext);
+ module = buf;
+ }
+
+ append_import (application_name, module, ord_val);
+}
+
+void
+def_version (major, minor)
+ int major;
+ int minor;
+{
+ printf ("VERSION %d.%d\n", major, minor);
+}
+
+void
+def_section (name, attr)
+ const char *name;
+ int attr;
+{
+ char buf[200];
+ char atts[5];
+ char *d = atts;
+ if (attr & 1)
+ *d++ = 'R';
+
+ if (attr & 2)
+ *d++ = 'W';
+ if (attr & 4)
+ *d++ = 'X';
+ if (attr & 8)
+ *d++ = 'S';
+ *d++ = 0;
+ sprintf (buf, "-attr %s %s", name, atts);
+ new_directive (xstrdup (buf));
+}
+
+void
+def_code (attr)
+ int attr;
+{
+
+ def_section ("CODE", attr);
+}
+
+void
+def_data (attr)
+ int attr;
+{
+ def_section ("DATA", attr);
+}
+
+/**********************************************************************/
+
+static void
+run (what, args)
+ const char *what;
+ char *args;
+{
+ char *s;
+ int pid, wait_status;
+ int i;
+ const char **argv;
+ char *errmsg_fmt, *errmsg_arg;
+ char *temp_base = choose_temp_base ();
+
+ inform ("run: %s %s\n", what, args);
+
+ /* Count the args */
+ i = 0;
+ for (s = args; *s; s++)
+ if (*s == ' ')
+ i++;
+ i++;
+ argv = alloca (sizeof (char *) * (i + 3));
+ i = 0;
+ argv[i++] = what;
+ s = args;
+ while (1)
+ {
+ while (*s == ' ')
+ ++s;
+ argv[i++] = s;
+ while (*s != ' ' && *s != 0)
+ s++;
+ if (*s == 0)
+ break;
+ *s++ = 0;
+ }
+ argv[i++] = NULL;
+
+ pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
+ &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
+
+ if (pid == -1)
+ {
+ inform (strerror (errno));
+
+ fatal (errmsg_fmt, errmsg_arg);
+ }
+
+ pid = pwait (pid, & wait_status, 0);
+
+ if (pid == -1)
+ {
+ /* xgettext:c-format */
+ fatal (_("wait: %s"), strerror (errno));
+ }
+ else if (WIFSIGNALED (wait_status))
+ {
+ /* xgettext:c-format */
+ fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
+ }
+ else if (WIFEXITED (wait_status))
+ {
+ if (WEXITSTATUS (wait_status) != 0)
+ /* xgettext:c-format */
+ warn (_("%s exited with status %d\n"),
+ what, WEXITSTATUS (wait_status));
+ }
+ else
+ abort ();
+}
+
+/* Look for a list of symbols to export in the .drectve section of
+ ABFD. Pass each one to def_exports. */
+
+static void
+scan_drectve_symbols (abfd)
+ bfd *abfd;
+{
+ asection * s;
+ int size;
+ char * buf;
+ char * p;
+ char * e;
+
+ /* Look for .drectve's */
+ s = bfd_get_section_by_name (abfd, ".drectve");
+
+ if (s == NULL)
+ return;
+
+ size = bfd_get_section_size_before_reloc (s);
+ buf = xmalloc (size);
+
+ bfd_get_section_contents (abfd, s, buf, 0, size);
+
+ /* xgettext:c-format */
+ inform (_("Sucking in info from .drective section in %s\n"),
+ bfd_get_filename (abfd));
+
+ /* Search for -export: strings */
+ p = buf;
+ e = buf + size;
+ while (p < e)
+ {
+ if (p[0] == '-'
+ && strncmp (p, "-export:", 8) == 0)
+ {
+ char * name;
+ char * c;
+
+ p += 8;
+ name = p;
+ while (p < e && *p != ' ' && *p != '-')
+ p++;
+ c = xmalloc (p - name + 1);
+ memcpy (c, name, p - name);
+ c[p - name] = 0;
+
+ /* FIXME: The 5th arg is for the `constant' field.
+ What should it be? Not that it matters since it's not
+ currently useful. */
+ def_exports (c, 0, -1, 0, 0, 0);
+
+ if (add_stdcall_alias && strchr (c, '@'))
+ {
+ char *exported_name = xstrdup (c);
+ char *atsym = strchr (exported_name, '@');
+ *atsym = '\0';
+ def_exports (exported_name, xstrdup (c), -1, 0, 0, 0);
+ }
+ }
+ else
+ p++;
+ }
+ free (buf);
+}
+
+/* Look through the symbols in MINISYMS, and add each one to list of
+ symbols to export. */
+
+static void
+scan_filtered_symbols (abfd, minisyms, symcount, size)
+ bfd *abfd;
+ PTR minisyms;
+ long symcount;
+ unsigned int size;
+{
+ asymbol *store;
+ bfd_byte *from, *fromend;
+
+ store = bfd_make_empty_symbol (abfd);
+ if (store == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ from = (bfd_byte *) minisyms;
+ fromend = from + symcount * size;
+ for (; from < fromend; from += size)
+ {
+ asymbol *sym;
+ const char *symbol_name;
+
+ sym = bfd_minisymbol_to_symbol (abfd, false, from, store);
+ if (sym == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ symbol_name = bfd_asymbol_name (sym);
+ if (bfd_get_symbol_leading_char (abfd) == symbol_name[0])
+ ++symbol_name;
+
+ def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 0);
+
+ if (add_stdcall_alias && strchr (symbol_name, '@'))
+ {
+ char *exported_name = xstrdup (symbol_name);
+ char *atsym = strchr (exported_name, '@');
+ *atsym = '\0';
+ def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0);
+ }
+ }
+}
+
+/* Add a list of symbols to exclude. */
+
+static void
+add_excludes (new_excludes)
+ const char *new_excludes;
+{
+ char *local_copy;
+ char *exclude_string;
+
+ local_copy = xstrdup (new_excludes);
+
+ exclude_string = strtok (local_copy, ",:");
+ for (; exclude_string; exclude_string = strtok (NULL, ",:"))
+ {
+ struct string_list *new_exclude;
+
+ new_exclude = ((struct string_list *)
+ xmalloc (sizeof (struct string_list)));
+ new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2);
+ /* FIXME: Is it always right to add a leading underscore? */
+ sprintf (new_exclude->string, "_%s", exclude_string);
+ new_exclude->next = excludes;
+ excludes = new_exclude;
+
+ /* xgettext:c-format */
+ inform (_("Excluding symbol: %s\n"), exclude_string);
+ }
+
+ free (local_copy);
+}
+
+/* See if STRING is on the list of symbols to exclude. */
+
+static boolean
+match_exclude (string)
+ const char *string;
+{
+ struct string_list *excl_item;
+
+ for (excl_item = excludes; excl_item; excl_item = excl_item->next)
+ if (strcmp (string, excl_item->string) == 0)
+ return true;
+ return false;
+}
+
+/* Add the default list of symbols to exclude. */
+
+static void
+set_default_excludes (void)
+{
+ add_excludes (default_excludes);
+}
+
+/* Choose which symbols to export. */
+
+static long
+filter_symbols (abfd, minisyms, symcount, size)
+ bfd *abfd;
+ PTR minisyms;
+ long symcount;
+ unsigned int size;
+{
+ bfd_byte *from, *fromend, *to;
+ asymbol *store;
+
+ store = bfd_make_empty_symbol (abfd);
+ if (store == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ from = (bfd_byte *) minisyms;
+ fromend = from + symcount * size;
+ to = (bfd_byte *) minisyms;
+
+ for (; from < fromend; from += size)
+ {
+ int keep = 0;
+ asymbol *sym;
+
+ sym = bfd_minisymbol_to_symbol (abfd, false, (const PTR) from, store);
+ if (sym == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ /* Check for external and defined only symbols. */
+ keep = (((sym->flags & BSF_GLOBAL) != 0
+ || (sym->flags & BSF_WEAK) != 0
+ || bfd_is_com_section (sym->section))
+ && ! bfd_is_und_section (sym->section));
+
+ keep = keep && ! match_exclude (sym->name);
+
+ if (keep)
+ {
+ memcpy (to, from, size);
+ to += size;
+ }
+ }
+
+ return (to - (bfd_byte *) minisyms) / size;
+}
+
+/* Export all symbols in ABFD, except for ones we were told not to
+ export. */
+
+static void
+scan_all_symbols (abfd)
+ bfd *abfd;
+{
+ long symcount;
+ PTR minisyms;
+ unsigned int size;
+
+ /* Ignore bfds with an import descriptor table. We assume that any
+ such BFD contains symbols which are exported from another DLL,
+ and we don't want to reexport them from here. */
+ if (bfd_get_section_by_name (abfd, ".idata$4"))
+ return;
+
+ if (! (bfd_get_file_flags (abfd) & HAS_SYMS))
+ {
+ /* xgettext:c-format */
+ warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
+ return;
+ }
+
+ symcount = bfd_read_minisymbols (abfd, false, &minisyms, &size);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (symcount == 0)
+ {
+ /* xgettext:c-format */
+ warn (_("%s: no symbols\n"), bfd_get_filename (abfd));
+ return;
+ }
+
+ /* Discard the symbols we don't want to export. It's OK to do this
+ in place; we'll free the storage anyway. */
+
+ symcount = filter_symbols (abfd, minisyms, symcount, size);
+ scan_filtered_symbols (abfd, minisyms, symcount, size);
+
+ free (minisyms);
+}
+
+/* Look at the object file to decide which symbols to export. */
+
+static void
+scan_open_obj_file (abfd)
+ bfd *abfd;
+{
+ if (export_all_symbols)
+ scan_all_symbols (abfd);
+ else
+ scan_drectve_symbols (abfd);
+
+ /* FIXME: we ought to read in and block out the base relocations */
+
+ /* xgettext:c-format */
+ inform (_("%s: Done reading %s\n"), bfd_get_filename (abfd));
+}
+
+static void
+scan_obj_file (filename)
+ const char *filename;
+{
+ bfd * f = bfd_openr (filename, 0);
+
+ if (!f)
+ /* xgettext:c-format */
+ fatal (_("Unable to open object file: %s"), filename);
+
+ /* xgettext:c-format */
+ inform (_("Scanning object file %s"), filename);
+
+ if (bfd_check_format (f, bfd_archive))
+ {
+ bfd *arfile = bfd_openr_next_archived_file (f, 0);
+ while (arfile)
+ {
+ if (bfd_check_format (arfile, bfd_object))
+ scan_open_obj_file (arfile);
+ bfd_close (arfile);
+ arfile = bfd_openr_next_archived_file (f, arfile);
+ }
+ }
+ else if (bfd_check_format (f, bfd_object))
+ {
+ scan_open_obj_file (f);
+ }
+
+ bfd_close (f);
+}
+
+/**********************************************************************/
+
+static void
+dump_def_info (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");
+ for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+ {
+ fprintf (f, "%s %d = %s %s @ %d %s%s%s\n",
+ ASM_C,
+ i,
+ exp->name,
+ exp->internal_name,
+ exp->ordinal,
+ exp->noname ? "NONAME " : "",
+ exp->constant ? "CONSTANT" : "",
+ exp->data ? "DATA" : "");
+ }
+}
+
+/* Generate the .exp file */
+
+static int
+sfunc (a, b)
+ const void *a;
+ const void *b;
+{
+ return *(const long *) a - *(const long *) b;
+}
+
+static void
+flush_page (f, need, page_addr, on_page)
+ FILE *f;
+ long *need;
+ int page_addr;
+ int on_page;
+{
+ int i;
+
+ /* Flush this page */
+ fprintf (f, "\t%s\t0x%08x\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%lx\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);
+}
+
+static void
+gen_def_file ()
+{
+ int i;
+ export_type *exp;
+
+ inform (_("Adding exports to output file"));
+
+ fprintf (output_def, ";");
+ for (i = 0; oav[i]; i++)
+ fprintf (output_def, " %s", oav[i]);
+
+ fprintf (output_def, "\nEXPORTS\n");
+
+ for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+ {
+ char *quote = strchr (exp->name, '.') ? "\"" : "";
+ char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
+
+ if (strcmp (exp->name, exp->internal_name) == 0)
+ {
+
+ fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
+ quote,
+ exp->name,
+ quote,
+ exp->ordinal,
+ exp->noname ? " NONAME" : "",
+ exp->data ? " DATA" : "",
+ res ? res : "");
+ }
+ else
+ {
+ char *quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
+ /* char *alias = */
+ fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
+ quote,
+ exp->name,
+ quote,
+ quote1,
+ exp->internal_name,
+ quote1,
+ exp->ordinal,
+ exp->noname ? " NONAME" : "",
+ exp->data ? " DATA" : "",
+ res ? res : "");
+ }
+ if (res)
+ free (res);
+ }
+
+ inform (_("Added exports to output file"));
+}
+
+/* generate_idata_ofile generates the portable assembly source code
+ for the idata sections. It appends the source code to the end of
+ the file. */
+
+static void
+generate_idata_ofile (filvar)
+ FILE *filvar;
+{
+ iheadtype *headptr;
+ ifunctype *funcptr;
+ int headindex;
+ int funcindex;
+ int nheads;
+
+ if (import_list == NULL)
+ return;
+
+ fprintf (filvar, "%s Import data sections\n", ASM_C);
+ fprintf (filvar, "\n\t.section\t.idata$2\n");
+ fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
+ fprintf (filvar, "doi_idata:\n");
+
+ nheads = 0;
+ for (headptr = import_list; headptr != NULL; headptr = headptr->next)
+ {
+ fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
+ ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
+ ASM_C, headptr->dllname);
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG);
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG);
+ fprintf (filvar, "\t%sdllname%d%s\n",
+ ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
+ fprintf (filvar, "\t%slisttwo%d%s\n\n",
+ ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
+ nheads++;
+ }
+
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG);
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG);
+
+ fprintf (filvar, "\n\t.section\t.idata$4\n");
+ headindex = 0;
+ for (headptr = import_list; headptr != NULL; headptr = headptr->next)
+ {
+ fprintf (filvar, "listone%d:\n", headindex);
+ for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
+ fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
+ ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
+ fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
+ headindex++;
+ }
+
+ fprintf (filvar, "\n\t.section\t.idata$5\n");
+ headindex = 0;
+ for (headptr = import_list; headptr != NULL; headptr = headptr->next)
+ {
+ fprintf (filvar, "listtwo%d:\n", headindex);
+ for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
+ fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
+ ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
+ headindex++;
+ }
+
+ fprintf (filvar, "\n\t.section\t.idata$6\n");
+ headindex = 0;
+ for (headptr = import_list; headptr != NULL; headptr = headptr->next)
+ {
+ funcindex = 0;
+ for (funcptr = headptr->funchead; funcptr != NULL;
+ funcptr = funcptr->next)
+ {
+ fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
+ fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
+ ((funcptr->ord) & 0xFFFF));
+ fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
+ fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
+ funcindex++;
+ }
+ headindex++;
+ }
+
+ fprintf (filvar, "\n\t.section\t.idata$7\n");
+ headindex = 0;
+ for (headptr = import_list; headptr != NULL; headptr = headptr->next)
+ {
+ fprintf (filvar,"dllname%d:\n", headindex);
+ fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
+ fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
+ headindex++;
+ }
+}
+
+static void
+gen_exp_file ()
+{
+ FILE *f;
+ int i;
+ export_type *exp;
+ dlist_type *dl;
+
+ /* xgettext:c-format */
+ inform (_("Generating export file: %s\n"), exp_name);
+
+ f = fopen (TMP_ASM, FOPEN_WT);
+ if (!f)
+ /* xgettext:c-format */
+ fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM);
+
+ /* xgettext:c-format */
+ inform (_("Opened temporary file: %s"), TMP_ASM);
+
+ dump_def_info (f);
+
+ if (d_exports)
+ {
+ fprintf (f, "\t.section .edata\n\n");
+ fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
+ fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0),
+ ASM_C);
+ fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
+ fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
+ fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
+
+
+ fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
+ fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
+ ASM_C,
+ d_named_nfuncs, d_low_ord, d_high_ord);
+ fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
+ show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
+ fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
+
+ fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
+ ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
+
+ fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
+
+ fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
+
+
+ fprintf(f,"%s Export address Table\n", ASM_C);
+ fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
+ fprintf (f, "afuncs:\n");
+ i = d_low_ord;
+
+ for (exp = d_exports; exp; exp = exp->next)
+ {
+ if (exp->ordinal != i)
+ {
+#if 0
+ fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
+ ASM_SPACE,
+ (exp->ordinal - i) * 4,
+ ASM_C,
+ i, exp->ordinal - 1);
+ i = exp->ordinal;
+#endif
+ while (i < exp->ordinal)
+ {
+ fprintf(f,"\t%s\t0\n", ASM_LONG);
+ i++;
+ }
+ }
+ fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
+ ASM_PREFIX,
+ exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
+ i++;
+ }
+
+ fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
+ fprintf (f, "anames:\n");
+
+ for (i = 0; (exp = d_exports_lexically[i]); i++)
+ {
+ if (!exp->noname || show_allnames)
+ fprintf (f, "\t%sn%d%s\n",
+ ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
+ }
+
+ fprintf (f,"%s Export Oridinal Table\n", ASM_C);
+ fprintf (f, "anords:\n");
+ for (i = 0; (exp = d_exports_lexically[i]); i++)
+ {
+ if (!exp->noname || show_allnames)
+ fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
+ }
+
+ fprintf(f,"%s Export Name Table\n", ASM_C);
+ for (i = 0; (exp = d_exports_lexically[i]); i++)
+ if (!exp->noname || show_allnames)
+ fprintf (f, "n%d: %s \"%s\"\n",
+ exp->ordinal, ASM_TEXT, exp->name);
+
+ if (a_list)
+ {
+ 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);
+ }
+ }
+ if (d_list)
+ {
+ fprintf (f, "\t.section .rdata\n");
+ for (dl = d_list; dl; dl = dl->next)
+ {
+ char *p;
+ int l;
+ /* We dont output as ascii 'cause there can
+ 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;
+ }
+ if (++l == 10)
+ {
+ fprintf (f, "\n");
+ l = 0;
+ }
+ }
+ }
+ }
+ }
+
+
+ /* Add to the output file a way of getting to the exported names
+ without using the import library. */
+ if (add_indirect)
+ {
+ fprintf (f, "\t.section\t.rdata\n");
+ for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+ if (!exp->noname || show_allnames)
+ {
+ /* We use a single underscore for MS compatibility, and a
+ double underscore for backward compatibility with old
+ cygwin releases. */
+ fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
+ fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
+ fprintf (f, "__imp_%s:\n", exp->name);
+ fprintf (f, "_imp__%s:\n", exp->name);
+ fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
+ }
+ }
+
+ /* 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.init\n");
+ fprintf (f, "lab:\n");
+
+ fseek (base_file, 0, SEEK_END);
+ numbytes = ftell (base_file);
+ fseek (base_file, 0, SEEK_SET);
+ copy = xmalloc (numbytes);
+ fread (copy, 1, numbytes, base_file);
+ num_entries = numbytes / sizeof (long);
+
+
+ fprintf (f, "\t.section\t.reloc\n");
+ if (num_entries)
+ {
+ int src;
+ int dst = 0;
+ int last = -1;
+ int totsize = 0;
+
+ qsort (copy, num_entries, sizeof (long), sfunc);
+ /* Delete duplcates */
+ for (src = 0; src < num_entries; src++)
+ {
+ if (last != copy[src])
+ last = copy[dst++] = copy[src];
+ }
+ num_entries = dst;
+ addr = copy[0];
+ page_addr = addr & PAGE_MASK; /* work out the page addr */
+ on_page = 0;
+ for (j = 0; j < num_entries; j++)
+ {
+ totsize += 2;
+ addr = copy[j];
+ if ((addr & PAGE_MASK) != page_addr)
+ {
+ totsize += 8 + (on_page & 1)*2;
+ flush_page (f, need, page_addr, on_page);
+ on_page = 0;
+ page_addr = addr & PAGE_MASK;
+ }
+ need[on_page++] = addr;
+ }
+
+ /* Pad the section to an even 32-byte boundary. This will make
+ the BeOS loader much happier, and shouldn't matter for other
+ OSes. */
+ while ((totsize + 8 + (on_page & 1)*2) % 32 != 0)
+ {
+ /* 0x0000 is an absolute relocation that should be ignored. */
+ need[on_page++] = 0x0000;
+ totsize += 2;
+ }
+
+ flush_page (f, need, page_addr, on_page);
+
+ /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
+ }
+ }
+
+ generate_idata_ofile (f);
+
+ fclose (f);
+
+ /* assemble the file */
+ sprintf (outfile, "%s -o %s %s", as_flags, exp_name, TMP_ASM);
+
+#ifdef DLLTOOL_ARM
+ if (interwork)
+ strcat (outfile, " -mthumb-interwork");
+#endif
+
+ run (as_name, outfile);
+
+ if (dontdeltemps == 0)
+ unlink (TMP_ASM);
+
+ inform (_("Generated exports file"));
+}
+
+static const char *
+xlate (name)
+ const char *name;
+{
+ if (add_underscore)
+ {
+ char *copy = xmalloc (strlen (name) + 2);
+ copy[0] = '_';
+ strcpy (copy + 1, name);
+ name = copy;
+ }
+
+ if (killat)
+ {
+ char *p;
+ p = strchr (name, '@');
+ if (p)
+ *p = 0;
+ }
+ return name;
+}
+
+/**********************************************************************/
+
+#if 0
+
+static void
+dump_iat (f, exp)
+ FILE *f;
+ export_type *exp;
+{
+ if (exp->noname && !show_allnames )
+ {
+ fprintf (f, "\t%s\t0x%08x\n",
+ ASM_LONG,
+ exp->ordinal | 0x80000000); /* hint or orindal ?? */
+ }
+ else
+ {
+ fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
+ exp->ordinal,
+ ASM_RVA_AFTER);
+ }
+}
+
+#endif
+
+typedef struct
+{
+ int id;
+ const char *name;
+ int flags;
+ int align;
+ asection *sec;
+ asymbol *sym;
+ asymbol **sympp;
+ int size;
+ unsigned char *data;
+} sinfo;
+
+#ifndef DLLTOOL_PPC
+
+#define TEXT 0
+#define DATA 1
+#define BSS 2
+#define IDATA7 3
+#define IDATA5 4
+#define IDATA4 5
+#define IDATA6 6
+
+#define NSECS 7
+
+static sinfo secdata[NSECS] =
+{
+ { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
+ { DATA, ".data", SEC_DATA, 2},
+ { BSS, ".bss", 0, 2},
+ { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
+ { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
+ { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
+ { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
+};
+
+#else
+
+/* Sections numbered to make the order the same as other PowerPC NT */
+/* compilers. This also keeps funny alignment thingies from happening. */
+#define TEXT 0
+#define PDATA 1
+#define RDATA 2
+#define IDATA5 3
+#define IDATA4 4
+#define IDATA6 5
+#define IDATA7 6
+#define DATA 7
+#define BSS 8
+
+#define NSECS 9
+
+static sinfo secdata[NSECS] =
+{
+ { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
+ { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
+ { RDATA, ".reldata", SEC_HAS_CONTENTS, 2},
+ { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
+ { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
+ { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
+ { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
+ { DATA, ".data", SEC_DATA, 2},
+ { BSS, ".bss", 0, 2}
+};
+
+#endif
+
+/*
+This is what we're trying to make. We generate the imp symbols with
+both single and double underscores, for compatibility.
+
+ .text
+ .global _GetFileVersionInfoSizeW@8
+ .global __imp_GetFileVersionInfoSizeW@8
+_GetFileVersionInfoSizeW@8:
+ jmp * __imp_GetFileVersionInfoSizeW@8
+ .section .idata$7 # To force loading of head
+ .long __version_a_head
+# Import Address Table
+ .section .idata$5
+__imp_GetFileVersionInfoSizeW@8:
+ .rva ID2
+
+# Import Lookup Table
+ .section .idata$4
+ .rva ID2
+# Hint/Name table
+ .section .idata$6
+ID2: .short 2
+ .asciz "GetFileVersionInfoSizeW"
+
+
+For the PowerPC, here's the variation on the above scheme:
+
+# Rather than a simple "jmp *", the code to get to the dll function
+# looks like:
+ .text
+ lwz r11,[tocv]__imp_function_name(r2)
+# RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
+ lwz r12,0(r11)
+ stw r2,4(r1)
+ mtctr r12
+ lwz r2,4(r11)
+ bctr
+*/
+
+static char *
+make_label (prefix, name)
+ const char *prefix;
+ const char *name;
+{
+ int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
+ char *copy = xmalloc (len +1 );
+ strcpy (copy, ASM_PREFIX);
+ strcat (copy, prefix);
+ strcat (copy, name);
+ return copy;
+}
+
+static bfd *
+make_one_lib_file (exp, i)
+ export_type *exp;
+ int i;
+{
+#if 0
+ {
+ FILE *f;
+ char *prefix="d";
+ sprintf (outfile, "%ss%05d.s", prefix, i);
+ f = fopen (outfile, FOPEN_WT);
+ fprintf (f, "\t.text\n");
+ fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, 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);
+ fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
+ exp->name, ASM_JUMP, exp->name);
+
+ fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
+ fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
+
+
+ fprintf (f,"%s Import Address Table\n", ASM_C);
+
+ fprintf (f, "\t.section .idata$5\n");
+ fprintf (f, "__imp_%s:\n", exp->name);
+ fprintf (f, "_imp__%s:\n", exp->name);
+
+ dump_iat (f, exp);
+
+ fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
+ fprintf (f, "\t.section .idata$4\n");
+
+ dump_iat (f, exp);
+
+ if(!exp->noname || show_allnames)
+ {
+ fprintf (f, "%s Hint/Name table\n", ASM_C);
+ fprintf (f, "\t.section .idata$6\n");
+ fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
+ fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
+ }
+
+ fclose (f);
+
+ sprintf (outfile, "%s -o %ss%05d.o %ss%d.s",
+ as_flags, prefix, i, prefix, i);
+
+#ifdef DLLTOOL_ARM
+ if (interwork)
+ strcat (outfile, " -mthumb-interwork");
+#endif
+
+ run (as_name, outfile);
+ }
+#else /* if 0 */
+ {
+ bfd * abfd;
+ asymbol * exp_label;
+ asymbol * iname;
+ asymbol * iname2;
+ asymbol * iname_lab;
+ asymbol ** iname_lab_pp;
+ asymbol ** iname_pp;
+#ifdef DLLTOOL_PPC
+ asymbol ** fn_pp;
+ asymbol ** toc_pp;
+#define EXTRA 2
+#endif
+#ifndef EXTRA
+#define EXTRA 0
+#endif
+ asymbol * ptrs[NSECS + 4 + EXTRA + 1];
+
+ char * outname = xmalloc (10);
+ int oidx = 0;
+
+
+ sprintf (outname, "%s%05d.o", TMP_STUB, i);
+
+ abfd = bfd_openw (outname, HOW_BFD_TARGET);
+
+ if (!abfd)
+ /* xgettext:c-format */
+ fatal (_("bfd_open failed open stub file: %s"), outname);
+
+ /* xgettext:c-format */
+ inform (_("Creating stub file: %s"), outname);
+
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
+
+#ifdef DLLTOOL_ARM
+ if (interwork)
+ bfd_set_private_flags (abfd, F_INTERWORK);
+#endif
+
+ /* First make symbols for the sections */
+ for (i = 0; i < NSECS; i++)
+ {
+ sinfo *si = secdata + i;
+ if (si->id != i)
+ abort();
+ si->sec = bfd_make_section_old_way (abfd, si->name);
+ bfd_set_section_flags (abfd,
+ si->sec,
+ si->flags);
+
+ bfd_set_section_alignment(abfd, si->sec, si->align);
+ si->sec->output_section = si->sec;
+ si->sym = bfd_make_empty_symbol(abfd);
+ si->sym->name = si->sec->name;
+ si->sym->section = si->sec;
+ si->sym->flags = BSF_LOCAL;
+ si->sym->value = 0;
+ ptrs[oidx] = si->sym;
+ si->sympp = ptrs + oidx;
+ si->size = 0;
+ si->data = NULL;
+
+ oidx++;
+ }
+
+ if (! exp->data)
+ {
+ exp_label = bfd_make_empty_symbol (abfd);
+ exp_label->name = make_label ("", exp->name);
+
+ /* On PowerPC, the function name points to a descriptor in
+ the rdata section, the first element of which is a
+ pointer to the code (..function_name), and the second
+ points to the .toc */
+#ifdef DLLTOOL_PPC
+ if (machine == MPPC)
+ exp_label->section = secdata[RDATA].sec;
+ else
+#endif
+ exp_label->section = secdata[TEXT].sec;
+
+ exp_label->flags = BSF_GLOBAL;
+ exp_label->value = 0;
+
+#ifdef DLLTOOL_ARM
+ if (machine == MTHUMB)
+ bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
+#endif
+ ptrs[oidx++] = exp_label;
+ }
+
+ /* Generate imp symbols with one underscore for Microsoft
+ compatibility, and with two underscores for backward
+ compatibility with old versions of cygwin. */
+ iname = bfd_make_empty_symbol(abfd);
+ iname->name = make_label ("__imp_", exp->name);
+ iname->section = secdata[IDATA5].sec;
+ iname->flags = BSF_GLOBAL;
+ iname->value = 0;
+
+ iname2 = bfd_make_empty_symbol(abfd);
+ iname2->name = make_label ("_imp__", exp->name);
+ iname2->section = secdata[IDATA5].sec;
+ iname2->flags = BSF_GLOBAL;
+ iname2->value = 0;
+
+ iname_lab = bfd_make_empty_symbol(abfd);
+
+ iname_lab->name = head_label;
+ iname_lab->section = (asection *)&bfd_und_section;
+ iname_lab->flags = 0;
+ iname_lab->value = 0;
+
+
+ iname_pp = ptrs + oidx;
+ ptrs[oidx++] = iname;
+ ptrs[oidx++] = iname2;
+
+ iname_lab_pp = ptrs + oidx;
+ ptrs[oidx++] = iname_lab;
+
+#ifdef DLLTOOL_PPC
+ /* The symbol refering to the code (.text) */
+ {
+ asymbol *function_name;
+
+ function_name = bfd_make_empty_symbol(abfd);
+ function_name->name = make_label ("..", exp->name);
+ function_name->section = secdata[TEXT].sec;
+ function_name->flags = BSF_GLOBAL;
+ function_name->value = 0;
+
+ fn_pp = ptrs + oidx;
+ ptrs[oidx++] = function_name;
+ }
+
+ /* The .toc symbol */
+ {
+ asymbol *toc_symbol; /* The .toc symbol */
+
+ toc_symbol = bfd_make_empty_symbol (abfd);
+ toc_symbol->name = make_label (".", "toc");
+ toc_symbol->section = (asection *)&bfd_und_section;
+ toc_symbol->flags = BSF_GLOBAL;
+ toc_symbol->value = 0;
+
+ toc_pp = ptrs + oidx;
+ ptrs[oidx++] = toc_symbol;
+ }
+#endif
+
+ ptrs[oidx] = 0;
+
+ for (i = 0; i < NSECS; i++)
+ {
+ sinfo *si = secdata + i;
+ asection *sec = si->sec;
+ arelent *rel;
+ arelent **rpp;
+
+ switch (i)
+ {
+ case TEXT:
+ if (! exp->data)
+ {
+ si->size = HOW_JTAB_SIZE;
+ si->data = xmalloc (HOW_JTAB_SIZE);
+ memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
+
+ /* add the reloc into idata$5 */
+ rel = xmalloc (sizeof (arelent));
+
+ rpp = xmalloc (sizeof (arelent *) * 2);
+ rpp[0] = rel;
+ rpp[1] = 0;
+
+ rel->address = HOW_JTAB_ROFF;
+ rel->addend = 0;
+
+ if (machine == MPPC)
+ {
+ rel->howto = bfd_reloc_type_lookup (abfd,
+ BFD_RELOC_16_GOTOFF);
+ rel->sym_ptr_ptr = iname_pp;
+ }
+ else
+ {
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+ rel->sym_ptr_ptr = secdata[IDATA5].sympp;
+ }
+ sec->orelocation = rpp;
+ sec->reloc_count = 1;
+ }
+ break;
+ case IDATA4:
+ case IDATA5:
+ /* An idata$4 or idata$5 is one word long, and has an
+ rva to idata$6 */
+
+ si->data = xmalloc (4);
+ si->size = 4;
+
+ if (exp->noname)
+ {
+ si->data[0] = exp->ordinal ;
+ si->data[1] = exp->ordinal >> 8;
+ si->data[2] = exp->ordinal >> 16;
+ si->data[3] = 0x80;
+ }
+ else
+ {
+ sec->reloc_count = 1;
+ memset (si->data, 0, si->size);
+ rel = xmalloc (sizeof (arelent));
+ rpp = xmalloc (sizeof (arelent *) * 2);
+ rpp[0] = rel;
+ rpp[1] = 0;
+ rel->address = 0;
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
+ rel->sym_ptr_ptr = secdata[IDATA6].sympp;
+ sec->orelocation = rpp;
+ }
+
+ break;
+
+ case IDATA6:
+ if (!exp->noname)
+ {
+ /* This used to add 1 to exp->hint. I don't know
+ why it did that, and it does not match what I see
+ in programs compiled with the MS tools. */
+ int idx = exp->hint;
+ si->size = strlen (xlate (exp->name)) + 3;
+ si->data = xmalloc (si->size);
+ si->data[0] = idx & 0xff;
+ si->data[1] = idx >> 8;
+ strcpy (si->data + 2, xlate (exp->name));
+ }
+ break;
+ case IDATA7:
+ si->size = 4;
+ si->data =xmalloc(4);
+ memset (si->data, 0, si->size);
+ rel = xmalloc (sizeof (arelent));
+ rpp = xmalloc (sizeof (arelent *) * 2);
+ rpp[0] = rel;
+ rel->address = 0;
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
+ rel->sym_ptr_ptr = iname_lab_pp;
+ sec->orelocation = rpp;
+ sec->reloc_count = 1;
+ break;
+
+#ifdef DLLTOOL_PPC
+ case PDATA:
+ {
+ /* The .pdata section is 5 words long. */
+ /* Think of it as: */
+ /* struct */
+ /* { */
+ /* bfd_vma BeginAddress, [0x00] */
+ /* EndAddress, [0x04] */
+ /* ExceptionHandler, [0x08] */
+ /* HandlerData, [0x0c] */
+ /* PrologEndAddress; [0x10] */
+ /* }; */
+
+ /* So this pdata section setups up this as a glue linkage to
+ a dll routine. There are a number of house keeping things
+ we need to do:
+
+ 1. In the name of glue trickery, the ADDR32 relocs for 0,
+ 4, and 0x10 are set to point to the same place:
+ "..function_name".
+ 2. There is one more reloc needed in the pdata section.
+ The actual glue instruction to restore the toc on
+ return is saved as the offset in an IMGLUE reloc.
+ So we need a total of four relocs for this section.
+
+ 3. Lastly, the HandlerData field is set to 0x03, to indicate
+ that this is a glue routine.
+ */
+ arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
+
+ /* alignment must be set to 2**2 or you get extra stuff */
+ bfd_set_section_alignment(abfd, sec, 2);
+
+ si->size = 4 * 5;
+ si->data =xmalloc(4 * 5);
+ memset (si->data, 0, si->size);
+ rpp = xmalloc (sizeof (arelent *) * 5);
+ rpp[0] = imglue = xmalloc (sizeof (arelent));
+ rpp[1] = ba_rel = xmalloc (sizeof (arelent));
+ rpp[2] = ea_rel = xmalloc (sizeof (arelent));
+ rpp[3] = pea_rel = xmalloc (sizeof (arelent));
+ rpp[4] = 0;
+
+ /* stick the toc reload instruction in the glue reloc */
+ bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
+
+ imglue->addend = 0;
+ imglue->howto = bfd_reloc_type_lookup (abfd,
+ BFD_RELOC_32_GOTOFF);
+ imglue->sym_ptr_ptr = fn_pp;
+
+ ba_rel->address = 0;
+ ba_rel->addend = 0;
+ ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+ ba_rel->sym_ptr_ptr = fn_pp;
+
+ bfd_put_32(abfd, 0x18, si->data + 0x04);
+ ea_rel->address = 4;
+ ea_rel->addend = 0;
+ ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+ ea_rel->sym_ptr_ptr = fn_pp;
+
+ /* mark it as glue */
+ bfd_put_32(abfd, 0x03, si->data + 0x0c);
+
+ /* mark the prolog end address */
+ bfd_put_32(abfd, 0x0D, si->data + 0x10);
+ pea_rel->address = 0x10;
+ pea_rel->addend = 0;
+ pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+ pea_rel->sym_ptr_ptr = fn_pp;
+
+ sec->orelocation = rpp;
+ sec->reloc_count = 4;
+ break;
+ }
+ case RDATA:
+ /* Each external function in a PowerPC PE file has a two word
+ descriptor consisting of:
+ 1. The address of the code.
+ 2. The address of the appropriate .toc
+ We use relocs to build this.
+ */
+
+ si->size = 8;
+ si->data = xmalloc (8);
+ memset (si->data, 0, si->size);
+
+ rpp = xmalloc (sizeof (arelent *) * 3);
+ rpp[0] = rel = xmalloc (sizeof (arelent));
+ rpp[1] = xmalloc (sizeof (arelent));
+ rpp[2] = 0;
+
+ rel->address = 0;
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+ rel->sym_ptr_ptr = fn_pp;
+
+ rel = rpp[1];
+
+ rel->address = 4;
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
+ rel->sym_ptr_ptr = toc_pp;
+
+ sec->orelocation = rpp;
+ sec->reloc_count = 2;
+ break;
+#endif /* DLLTOOL_PPC */
+ }
+ }
+
+ {
+ bfd_vma vma = 0;
+ /* Size up all the sections */
+ for (i = 0; i < NSECS; i++)
+ {
+ sinfo *si = secdata + i;
+
+ bfd_set_section_size (abfd, si->sec, si->size);
+ bfd_set_section_vma (abfd, si->sec, vma);
+
+/* vma += si->size;*/
+ }
+ }
+ /* Write them out */
+ for (i = 0; i < NSECS; i++)
+ {
+ sinfo *si = secdata + i;
+
+ if (i == IDATA5 && no_idata5)
+ continue;
+
+ if (i == IDATA4 && no_idata4)
+ continue;
+
+ bfd_set_section_contents (abfd, si->sec,
+ si->data, 0,
+ si->size);
+ }
+
+ bfd_set_symtab (abfd, ptrs, oidx);
+ bfd_close (abfd);
+ abfd = bfd_openr (outname, HOW_BFD_TARGET);
+ return abfd;
+ }
+#endif
+}
+
+static bfd *
+make_head ()
+{
+ FILE * f = fopen (TMP_HEAD_S, FOPEN_WT);
+
+ fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
+ fprintf (f, "\t.section .idata$2\n");
+
+ fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
+
+ fprintf (f, "%s:\n", head_label);
+
+ fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
+ ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
+
+ fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
+ fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
+ fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
+ fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
+ fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
+ ASM_RVA_BEFORE,
+ imp_name_lab,
+ ASM_RVA_AFTER,
+ ASM_C);
+ fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
+ ASM_RVA_BEFORE,
+ ASM_RVA_AFTER, ASM_C);
+
+ fprintf (f, "%sStuff for compatibility\n", ASM_C);
+
+ if (!no_idata5)
+ {
+ fprintf (f, "\t.section\t.idata$5\n");
+ fprintf (f, "\t%s\t0\n", ASM_LONG);
+ fprintf (f, "fthunk:\n");
+ }
+ if (!no_idata4)
+ {
+ fprintf (f, "\t.section\t.idata$4\n");
+
+ fprintf (f, "\t%s\t0\n", ASM_LONG);
+ fprintf (f, "\t.section .idata$4\n");
+ fprintf (f, "hname:\n");
+ }
+ fclose (f);
+
+ sprintf (outfile, "%s -o %s %s", as_flags, TMP_HEAD_O, TMP_HEAD_S);
+
+#ifdef DLLTOOL_ARM
+ if (interwork)
+ strcat (outfile, " -mthumb-interwork");
+#endif
+
+ run (as_name, outfile);
+
+ return bfd_openr (TMP_HEAD_O, HOW_BFD_TARGET);
+}
+
+static bfd *
+make_tail ()
+{
+ FILE * f = fopen (TMP_TAIL_S, FOPEN_WT);
+
+ if (!no_idata4)
+ {
+ fprintf (f, "\t.section .idata$4\n");
+ fprintf (f, "\t%s\t0\n", ASM_LONG);
+ }
+ if (!no_idata5)
+ {
+ fprintf (f, "\t.section .idata$5\n");
+ fprintf (f, "\t%s\t0\n", ASM_LONG);
+ }
+
+#ifdef DLLTOOL_PPC
+ /* Normally, we need to see a null descriptor built in idata$3 to
+ act as the terminator for the list. The ideal way, I suppose,
+ would be to mark this section as a comdat type 2 section, so
+ only one would appear in the final .exe (if our linker supported
+ comdat, that is) or cause it to be inserted by something else (say
+ crt0)
+ */
+
+ fprintf (f, "\t.section .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);
+#endif
+
+#ifdef DLLTOOL_PPC
+ /* Other PowerPC NT compilers use idata$6 for the dllname, so I
+ do too. Original, huh? */
+ fprintf (f, "\t.section .idata$6\n");
+#else
+ fprintf (f, "\t.section .idata$7\n");
+#endif
+
+ fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
+ fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
+ imp_name_lab, ASM_TEXT, dll_name);
+
+ fclose (f);
+
+ sprintf (outfile, "%s -o %s %s", as_flags, TMP_TAIL_O, TMP_TAIL_S);
+
+#ifdef DLLTOOL_ARM
+ if (interwork)
+ strcat (outfile, " -mthumb-interwork");
+#endif
+
+ run (as_name, outfile);
+
+ return bfd_openr (TMP_TAIL_O, HOW_BFD_TARGET);
+}
+
+static void
+gen_lib_file ()
+{
+ int i;
+ export_type *exp;
+ bfd *ar_head;
+ bfd *ar_tail;
+ bfd *outarch;
+ bfd * head = 0;
+
+ unlink (imp_name);
+
+ outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
+
+ if (!outarch)
+ /* xgettext:c-format */
+ fatal (_("Can't open .lib file: %s"), imp_name);
+
+ /* xgettext:c-format */
+ inform (_("Creating library file: %s\n"), imp_name);
+
+ bfd_set_format (outarch, bfd_archive);
+ outarch->has_armap = 1;
+
+ /* Work out a reasonable size of things to put onto one line. */
+
+ ar_head = make_head ();
+ ar_tail = make_tail();
+
+ if (ar_head == NULL || ar_tail == NULL)
+ return;
+
+ for (i = 0; (exp = d_exports_lexically[i]); i++)
+ {
+ bfd *n = make_one_lib_file (exp, i);
+ n->next = head;
+ head = n;
+ }
+
+ /* Now stick them all into the archive */
+
+ ar_head->next = head;
+ ar_tail->next = ar_head;
+ head = ar_tail;
+
+ if (! bfd_set_archive_head (outarch, head))
+ bfd_fatal ("bfd_set_archive_head");
+
+ if (! bfd_close (outarch))
+ bfd_fatal (imp_name);
+
+ while (head != NULL)
+ {
+ bfd *n = head->next;
+ bfd_close (head);
+ head = n;
+ }
+
+ /* Delete all the temp files */
+
+ if (dontdeltemps == 0)
+ {
+ unlink (TMP_HEAD_O);
+ unlink (TMP_HEAD_S);
+ unlink (TMP_TAIL_O);
+ unlink (TMP_TAIL_S);
+ }
+
+ if (dontdeltemps < 2)
+ {
+ for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+ {
+ sprintf (outfile, "%s%05d.o", TMP_STUB, i);
+ if (unlink (outfile) < 0)
+ /* xgettext:c-format */
+ warn (_("cannot delete %s: %s\n"), outfile, strerror (errno));
+ }
+ }
+
+ inform (_("Created lib file"));
+}
+
+/**********************************************************************/
+
+/* Run through the information gathered from the .o files and the
+ .def file and work out the best stuff */
+static int
+pfunc (a, b)
+ const void *a;
+ const void *b;
+{
+ export_type *ap = *(export_type **) a;
+ export_type *bp = *(export_type **) b;
+ if (ap->ordinal == bp->ordinal)
+ return 0;
+
+ /* unset ordinals go to the bottom */
+ if (ap->ordinal == -1)
+ return 1;
+ if (bp->ordinal == -1)
+ return -1;
+ return (ap->ordinal - bp->ordinal);
+}
+
+static int
+nfunc (a, b)
+ const void *a;
+ const void *b;
+{
+ export_type *ap = *(export_type **) a;
+ export_type *bp = *(export_type **) b;
+
+ return (strcmp (ap->name, bp->name));
+}
+
+static void
+remove_null_names (ptr)
+ export_type **ptr;
+{
+ int src;
+ int dst;
+ for (dst = src = 0; src < d_nfuncs; src++)
+ {
+ if (ptr[src])
+ {
+ ptr[dst] = ptr[src];
+ dst++;
+ }
+ }
+ d_nfuncs = dst;
+}
+
+static void
+dtab (ptr)
+ export_type **ptr;
+{
+#ifdef SACDEBUG
+ int i;
+ for (i = 0; i < d_nfuncs; i++)
+ {
+ if (ptr[i])
+ {
+ printf ("%d %s @ %d %s%s%s\n",
+ i, ptr[i]->name, ptr[i]->ordinal,
+ ptr[i]->noname ? "NONAME " : "",
+ ptr[i]->constant ? "CONSTANT" : "",
+ ptr[i]->data ? "DATA" : "");
+ }
+ else
+ printf ("empty\n");
+ }
+#endif
+}
+
+static void
+process_duplicates (d_export_vec)
+ export_type **d_export_vec;
+{
+ int more = 1;
+ int i;
+ while (more)
+ {
+
+ more = 0;
+ /* Remove duplicates */
+ qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
+
+ dtab (d_export_vec);
+ for (i = 0; i < d_nfuncs - 1; i++)
+ {
+ if (strcmp (d_export_vec[i]->name,
+ d_export_vec[i + 1]->name) == 0)
+ {
+
+ export_type *a = d_export_vec[i];
+ export_type *b = d_export_vec[i + 1];
+
+ more = 1;
+
+ /* xgettext:c-format */
+ inform (_("Warning, ignoring duplicate EXPORT %s %d,%d\n"),
+ a->name, a->ordinal, b->ordinal);
+
+ if (a->ordinal != -1
+ && b->ordinal != -1)
+ /* xgettext:c-format */
+ fatal (_("Error, duplicate EXPORT with oridinals: %s"),
+ a->name);
+
+ /* Merge attributes */
+ b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
+ b->constant |= a->constant;
+ b->noname |= a->noname;
+ b->data |= a->data;
+ d_export_vec[i] = 0;
+ }
+
+ dtab (d_export_vec);
+ remove_null_names (d_export_vec);
+ dtab (d_export_vec);
+ }
+ }
+
+
+ /* Count the names */
+ for (i = 0; i < d_nfuncs; i++)
+ {
+ if (!d_export_vec[i]->noname)
+ d_named_nfuncs++;
+ }
+}
+
+static void
+fill_ordinals (d_export_vec)
+ export_type **d_export_vec;
+{
+ int lowest = -1;
+ int i;
+ char *ptr;
+ int size = 65536;
+
+ qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
+
+ /* fill in the unset ordinals with ones from our range */
+
+ ptr = (char *) xmalloc (size);
+
+ memset (ptr, 0, size);
+
+ /* 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)
+ {
+ ptr[d_export_vec[i]->ordinal] = 1;
+ if (lowest == -1 || d_export_vec[i]->ordinal < lowest)
+ {
+ lowest = d_export_vec[i]->ordinal;
+ }
+ }
+ }
+
+ /* Start at 1 for compatibility with MS toolchain. */
+ if (lowest == -1)
+ lowest = 1;
+
+ /* Now fill in ordinals where the user wants us to choose. */
+ for (i = 0; i < d_nfuncs; i++)
+ {
+ if (d_export_vec[i]->ordinal == -1)
+ {
+ register int j;
+
+ /* First try within or after any user supplied range. */
+ for (j = lowest; j < size; j++)
+ if (ptr[j] == 0)
+ {
+ ptr[j] = 1;
+ d_export_vec[i]->ordinal = j;
+ goto done;
+ }
+
+ /* Then try before the range. */
+ for (j = lowest; j >0; 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 and highest ordinal numbers. */
+ if (d_nfuncs)
+ {
+ if (d_export_vec[0])
+ d_low_ord = d_export_vec[0]->ordinal;
+ if (d_export_vec[d_nfuncs-1])
+ d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
+ }
+}
+
+static int
+alphafunc (av,bv)
+ const void *av;
+ const void *bv;
+{
+ const export_type **a = (const export_type **) av;
+ const export_type **b = (const export_type **) bv;
+
+ return strcmp ((*a)->name, (*b)->name);
+}
+
+static void
+mangle_defs ()
+{
+ /* First work out the minimum ordinal chosen */
+
+ export_type *exp;
+
+ int i;
+ int hint = 0;
+ export_type **d_export_vec
+ = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
+
+ inform (_("Processing definitions"));
+
+ for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+ {
+ d_export_vec[i] = exp;
+ }
+
+ process_duplicates (d_export_vec);
+ fill_ordinals (d_export_vec);
+
+ /* Put back the list in the new order */
+ d_exports = 0;
+ for (i = d_nfuncs - 1; i >= 0; i--)
+ {
+ d_export_vec[i]->next = d_exports;
+ d_exports = d_export_vec[i];
+ }
+
+ /* Build list in alpha order */
+ d_exports_lexically = (export_type **)
+ xmalloc (sizeof (export_type *) * (d_nfuncs + 1));
+
+ for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+ {
+ d_exports_lexically[i] = exp;
+ }
+ d_exports_lexically[i] = 0;
+
+ qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
+
+ /* Fill exp entries with their hint values */
+
+ for (i = 0; i < d_nfuncs; i++)
+ {
+ if (!d_exports_lexically[i]->noname || show_allnames)
+ d_exports_lexically[i]->hint = hint++;
+ }
+
+ inform (_("Processed definitions"));
+}
+
+/**********************************************************************/
+
+static void
+usage (file, status)
+ FILE *file;
+ int status;
+{
+ /* xgetext:c-format */
+ fprintf (file, _("Usage %s <options> <object-files>\n"), program_name);
+ /* xgetext:c-format */
+ fprintf (file, _(" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: %s]\n"), mname);
+ fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
+ fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
+ fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
+ fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
+ fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
+ fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n"));
+ fprintf (file, _(" --export-all-symbols Export all symbols to .def\n"));
+ fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n"));
+ fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n"));
+ fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n"));
+ fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n"));
+ fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n"));
+ fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n"));
+ fprintf (file, _(" -U --add-underscore Add underscores to symbols in interface library.\n"));
+ fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n"));
+ fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n"));
+ fprintf (file, _(" -S --as <name> Use <name> for assembler.\n"));
+ fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n"));
+#ifdef DLLTOOL_ARM
+ fprintf (file, _(" -i --interwork Support ARM/Thumb interworking.\n"));
+#endif
+ fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
+ fprintf (file, _(" -v --verbose Be verbose.\n"));
+ fprintf (file, _(" -V --version Display the program version.\n"));
+ fprintf (file, _(" -h --help Display this information.\n"));
+
+ exit (status);
+}
+
+#define OPTION_EXPORT_ALL_SYMS 150
+#define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
+#define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
+#define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
+#define OPTION_NO_IDATA4 'x'
+#define OPTION_NO_IDATA5 'c'
+
+static const struct option long_options[] =
+{
+ {"no-delete", no_argument, NULL, 'n'},
+ {"dllname", required_argument, NULL, 'D'},
+ {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
+ {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
+ {"output-exp", required_argument, NULL, 'e'},
+ {"output-def", required_argument, NULL, 'z'},
+ {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
+ {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
+ {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
+ {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
+ {"output-lib", required_argument, NULL, 'l'},
+ {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
+ {"input-def", required_argument, NULL, 'd'},
+ {"add-underscore", no_argument, NULL, 'U'},
+ {"kill-at", no_argument, NULL, 'k'},
+ {"add-stdcall-alias", no_argument, NULL, 'A'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"version", no_argument, NULL, 'V'},
+ {"help", no_argument, NULL, 'h'},
+ {"machine", required_argument, NULL, 'm'},
+ {"add-indirect", no_argument, NULL, 'a'},
+ {"base-file", required_argument, NULL, 'b'},
+ {"as", required_argument, NULL, 'S'},
+ {"as-flags", required_argument, NULL, 'f'},
+#ifdef DLLTOOL_ARM
+ {"interwork", no_argument, NULL, 'i'},
+#endif
+ {0}
+};
+
+int
+main (ac, av)
+ int ac;
+ char **av;
+{
+ int c;
+ int i;
+ char *firstarg = 0;
+ program_name = av[0];
+ oav = av;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ while ((c = getopt_long (ac, av, "xcz:S:aD:l:e:nkAvVb:Uh?m:d:f:i",
+ long_options, 0))
+ != EOF)
+ {
+ switch (c)
+ {
+ case OPTION_NO_IDATA4:
+ no_idata4 = 1;
+ break;
+ case OPTION_NO_IDATA5:
+ no_idata5 = 1;
+ break;
+ case OPTION_EXPORT_ALL_SYMS:
+ export_all_symbols = true;
+ break;
+ case OPTION_NO_EXPORT_ALL_SYMS:
+ export_all_symbols = false;
+ break;
+ case OPTION_EXCLUDE_SYMS:
+ add_excludes (optarg);
+ break;
+ case OPTION_NO_DEFAULT_EXCLUDES:
+ do_default_excludes = false;
+ break;
+ case 'S':
+ as_name = optarg;
+ break;
+ case 'f':
+ as_flags = optarg;
+ break;
+
+ /* ignored for compatibility */
+ case 'u':
+ break;
+ case 'a':
+ add_indirect = 1;
+ break;
+ case 'z':
+ output_def = fopen (optarg, FOPEN_WT);
+ break;
+ case 'D':
+ dll_name = optarg;
+ break;
+ case 'l':
+ imp_name = optarg;
+ break;
+ case 'e':
+ exp_name = optarg;
+ break;
+ case 'h':
+ usage (stdout, 0);
+ break;
+ case 'm':
+ mname = optarg;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'V':
+ print_version (program_name);
+ break;
+#ifdef DLLTOOL_ARM
+ case 'i':
+ interwork = 1;
+ break;
+#endif
+ case 'y':
+#if 0
+ /* We don't currently define YYDEBUG when building
+ defparse.y. */
+ yydebug = 1;
+#endif
+ break;
+ case 'U':
+ add_underscore = 1;
+ break;
+ case 'k':
+ killat = 1;
+ break;
+ case 'A':
+ add_stdcall_alias = 1;
+ break;
+ case 'd':
+ def_file = optarg;
+ break;
+ case 'n':
+ dontdeltemps++;
+ break;
+ case 'b':
+ base_file = fopen (optarg, FOPEN_RB);
+
+ if (!base_file)
+ /* xgettext:c-format */
+ fatal (_("Unable to open base-file: %s"), optarg);
+
+ break;
+ default:
+ usage (stderr, 1);
+ break;
+ }
+ }
+
+ for (i = 0; mtable[i].type; i++)
+ {
+ if (strcmp (mtable[i].type, mname) == 0)
+ break;
+ }
+
+ if (!mtable[i].type)
+ /* xgettext:c-format */
+ fatal (_("Machine '%s' not supported"), mname);
+
+ machine = i;
+
+#ifdef DLLTOOL_ARM
+ /* Always enable interworking for Thumb targets. */
+ if (machine == MTHUMB && (! interwork))
+ interwork = 1;
+#endif
+
+ if (!dll_name && exp_name)
+ {
+ int len = strlen (exp_name) + 5;
+ dll_name = xmalloc (len);
+ strcpy (dll_name, exp_name);
+ strcat (dll_name, ".dll");
+ }
+
+ /* Don't use the default exclude list if we're reading only the
+ symbols in the .drectve section. The default excludes are meant
+ to avoid exporting DLL entry point and Cygwin32 impure_ptr. */
+ if (! export_all_symbols)
+ do_default_excludes = false;
+
+ if (do_default_excludes)
+ set_default_excludes ();
+
+ if (def_file)
+ process_def_file (def_file);
+
+ while (optind < ac)
+ {
+ if (!firstarg)
+ firstarg = av[optind];
+ scan_obj_file (av[optind]);
+ optind++;
+ }
+
+ mangle_defs ();
+
+ if (exp_name)
+ gen_exp_file ();
+
+ if (imp_name)
+ {
+ /* Make imp_name safe for use as a label. */
+ char *p;
+
+ imp_name_lab = xstrdup (imp_name);
+ for (p = imp_name_lab; *p; p++)
+ {
+ if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
+ *p = '_';
+ }
+ head_label = make_label("_head_", imp_name_lab);
+ gen_lib_file ();
+ }
+
+ if (output_def)
+ gen_def_file ();
+
+ return 0;
+}
diff --git a/binutils/dlltool.h b/binutils/dlltool.h
new file mode 100644
index 00000000000..b4167c897f3
--- /dev/null
+++ b/binutils/dlltool.h
@@ -0,0 +1,42 @@
+/* dlltool.h -- header file for dlltool
+ Copyright (C) 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include <stdio.h>
+
+extern void def_code PARAMS ((int));
+extern void def_data PARAMS ((int));
+extern void def_description PARAMS ((const char *));
+extern void def_exports
+ PARAMS ((const char *, const char *, int, int, int, int));
+extern void def_heapsize PARAMS ((int, int));
+extern void def_import
+ PARAMS ((const char *, const char *, const char *, const char *, int));
+extern void def_library PARAMS ((const char *, int));
+extern void def_name PARAMS ((const char *, int));
+extern void def_section PARAMS ((const char *, int));
+extern void def_stacksize PARAMS ((int, int));
+extern void def_version PARAMS ((int, int));
+extern int yyparse PARAMS ((void));
+extern int yyerror PARAMS ((const char *));
+extern int yydebug;
+extern int yylex PARAMS ((void));
+extern FILE *yyin;
+extern int linenumber;
diff --git a/binutils/dllwrap.c b/binutils/dllwrap.c
new file mode 100644
index 00000000000..574611b3dd9
--- /dev/null
+++ b/binutils/dllwrap.c
@@ -0,0 +1,1050 @@
+/* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Contributed by Mumit Khan (khan@xraylith.wisc.edu).
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* AIX requires this to be the first thing in the file. */
+#ifndef __GNUC__
+# ifdef _AIX
+ #pragma alloca
+#endif
+#endif
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "bfd.h"
+#include "libiberty.h"
+#include "bucomm.h"
+#include "getopt.h"
+#include "dyn-string.h"
+
+#include <ctype.h>
+#include <time.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#else /* ! HAVE_SYS_WAIT_H */
+#if ! defined (_WIN32) || defined (__CYGWIN32__)
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w)&0377) == 0)
+#endif
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0177)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) >> 8) & 0377)
+#endif
+#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w) & 0xff) == 0)
+#endif
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0x7f)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
+#endif
+#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
+#endif /* ! HAVE_SYS_WAIT_H */
+
+static char *program_version = "0.2.4";
+static char *driver_name = "gcc";
+static char *cygwin_driver_flags =
+ "-Wl,--dll -nostartfiles";
+static char *mingw32_driver_flags = "-mdll";
+static char *generic_driver_flags = "-Wl,--dll";
+
+static char *entry_point;
+
+static char *dlltool_name = "dlltool";
+
+static char *target = TARGET;
+
+typedef enum {
+ UNKNOWN_TARGET,
+ CYGWIN_TARGET,
+ MINGW32_TARGET
+}
+target_type;
+
+static target_type which_target = UNKNOWN_TARGET;
+
+static int dontdeltemps = 0;
+static int dry_run = 0;
+
+static char *program_name;
+
+static int verbose = 0;
+
+static char *dll_file_name;
+static char *dll_name;
+static char *base_file_name;
+static char *exp_file_name;
+static char *def_file_name;
+static int delete_base_file = 1;
+static int delete_exp_file = 1;
+static int delete_def_file = 1;
+
+static int run PARAMS ((const char *, char *));
+static void usage PARAMS ((FILE *, int));
+static void delete_temp_files PARAMS ((void));
+static void cleanup_and_exit PARAMS ((int status));
+
+/**********************************************************************/
+
+static void
+delete_temp_files ()
+{
+ if (delete_base_file && base_file_name)
+ {
+ if (verbose)
+ fprintf (stderr, "%s temporary base file %s\n",
+ dontdeltemps ? "Keeping" : "Deleting",
+ base_file_name);
+ if (! dontdeltemps)
+ {
+ unlink (base_file_name);
+ free (base_file_name);
+ }
+ }
+
+ if (delete_exp_file && exp_file_name)
+ {
+ if (verbose)
+ fprintf (stderr, "%s temporary exp file %s\n",
+ dontdeltemps ? "Keeping" : "Deleting",
+ exp_file_name);
+ if (! dontdeltemps)
+ {
+ unlink (exp_file_name);
+ free (exp_file_name);
+ }
+ }
+ if (delete_def_file && def_file_name)
+ {
+ if (verbose)
+ fprintf (stderr, "%s temporary def file %s\n",
+ dontdeltemps ? "Keeping" : "Deleting",
+ def_file_name);
+ if (! dontdeltemps)
+ {
+ unlink (def_file_name);
+ free (def_file_name);
+ }
+ }
+}
+
+static void
+cleanup_and_exit (int status)
+{
+ delete_temp_files ();
+ exit (status);
+}
+
+static int
+run (what, args)
+ const char *what;
+ char *args;
+{
+ char *s;
+ int pid, wait_status, retcode;
+ int i;
+ const char **argv;
+ char *errmsg_fmt, *errmsg_arg;
+ char *temp_base = choose_temp_base ();
+ int in_quote;
+ char sep;
+
+ if (verbose || dry_run)
+ fprintf (stderr, "%s %s\n", what, args);
+
+ /* Count the args */
+ i = 0;
+ for (s = args; *s; s++)
+ if (*s == ' ')
+ i++;
+ i++;
+ argv = alloca (sizeof (char *) * (i + 3));
+ i = 0;
+ argv[i++] = what;
+ s = args;
+ while (1)
+ {
+ while (*s == ' ' && *s != 0)
+ s++;
+ if (*s == 0)
+ break;
+ in_quote = (*s == '\'' || *s == '"');
+ sep = (in_quote) ? *s++ : ' ';
+ argv[i++] = s;
+ while (*s != sep && *s != 0)
+ s++;
+ if (*s == 0)
+ break;
+ *s++ = 0;
+ if (in_quote)
+ s++;
+ }
+ argv[i++] = NULL;
+
+ if (dry_run)
+ return 0;
+
+ pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
+ &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
+
+ if (pid == -1)
+ {
+ int errno_val = errno;
+
+ fprintf (stderr, "%s: ", program_name);
+ fprintf (stderr, errmsg_fmt, errmsg_arg);
+ fprintf (stderr, ": %s\n", strerror (errno_val));
+ return 1;
+ }
+
+ retcode = 0;
+ pid = pwait (pid, &wait_status, 0);
+ if (pid == -1)
+ {
+ fprintf (stderr, "%s: wait: %s\n", program_name, strerror (errno));
+ retcode = 1;
+ }
+ else if (WIFSIGNALED (wait_status))
+ {
+ fprintf (stderr, "%s: subprocess got fatal signal %d\n",
+ program_name, WTERMSIG (wait_status));
+ retcode = 1;
+ }
+ else if (WIFEXITED (wait_status))
+ {
+ if (WEXITSTATUS (wait_status) != 0)
+ {
+ fprintf (stderr, "%s: %s exited with status %d\n",
+ program_name, what, WEXITSTATUS (wait_status));
+ retcode = 1;
+ }
+ }
+ else
+ retcode = 1;
+
+ return retcode;
+}
+
+static char *
+mybasename (name)
+ const char *name;
+{
+ const char *base = name;
+
+ while (*name)
+ {
+ if (*name == '/' || *name == '\\')
+ {
+ base = name + 1;
+ }
+ ++name;
+ }
+ return (char *) base;
+}
+
+static int
+strhash (const char *str)
+{
+ const unsigned char *s;
+ unsigned long hash;
+ unsigned int c;
+ unsigned int len;
+
+ hash = 0;
+ len = 0;
+ s = (const unsigned char *) str;
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ ++len;
+ }
+ hash += len + (len << 17);
+ hash ^= hash >> 2;
+
+ return hash;
+}
+
+/**********************************************************************/
+
+void
+print_version (name)
+ const char *name;
+{
+ /* This output is intended to follow the GNU standards document. */
+ /* xgettext:c-format */
+ printf ("GNU %s %s\n", name, program_version);
+ printf ("Copyright 1998 Free Software Foundation, Inc.\n");
+ printf ("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n");
+ exit (0);
+}
+
+static void
+usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, "Usage %s <options> <object-files>\n", program_name);
+ fprintf (file, " Generic options:\n");
+ fprintf (file, " --quiet, -q Work quietly\n");
+ fprintf (file, " --verbose, -v Verbose\n");
+ fprintf (file, " --version Print dllwrap version\n");
+ fprintf (file, " --implib <outname> Synonym for --output-lib\n");
+ fprintf (file, " Options for %s:\n", program_name);
+ fprintf (file, " --driver-name <driver> Defaults to \"gcc\"\n");
+ fprintf (file, " --driver-flags <flags> Override default ld flags\n");
+ fprintf (file, " --dlltool-name <dlltool> Defaults to \"dlltool\"\n");
+ fprintf (file, " --entry <entry> Specify alternate DLL entry point\n");
+ fprintf (file, " --image-base <base> Specify image base address\n");
+ fprintf (file, " --target <machine> i386-cygwin32 or i386-mingw32\n");
+ fprintf (file, " --dry-run Show what needs to be run\n");
+ fprintf (file, " Options passed to DLLTOOL:\n");
+ fprintf (file, " --machine <machine>\n");
+ fprintf (file, " --output-exp <outname> Generate export file.\n");
+ fprintf (file, " --output-lib <outname> Generate input library.\n");
+ fprintf (file, " --add-indirect Add dll indirects to export file.\n");
+ fprintf (file, " --dllname <name> Name of input dll to put into output lib.\n");
+ fprintf (file, " --def <deffile> Name input .def file\n");
+ fprintf (file, " --output-def <deffile> Name output .def file\n");
+ fprintf (file, " --export-all-symbols Export all symbols to .def\n");
+ fprintf (file, " --no-export-all-symbols Only export .drectve symbols\n");
+ fprintf (file, " --exclude-symbols <list> Exclude <list> from .def\n");
+ fprintf (file, " --no-default-excludes Zap default exclude symbols\n");
+ fprintf (file, " --base-file <basefile> Read linker generated base file\n");
+ fprintf (file, " --no-idata4 Don't generate idata$4 section\n");
+ fprintf (file, " --no-idata5 Don't generate idata$5 section\n");
+ fprintf (file, " -U Add underscores to .lib\n");
+ fprintf (file, " -k Kill @<n> from exported names\n");
+ fprintf (file, " --add-stdcall-alias Add aliases without @<n>\n");
+ fprintf (file, " --as <name> Use <name> for assembler\n");
+ fprintf (file, " --nodelete Keep temp files.\n");
+ fprintf (file, " Rest are passed unmodified to the language driver\n");
+ fprintf (file, "\n\n");
+ exit (status);
+}
+
+#define OPTION_START 149
+
+/* GENERIC options. */
+#define OPTION_QUIET (OPTION_START + 1)
+#define OPTION_VERBOSE (OPTION_QUIET + 1)
+#define OPTION_VERSION (OPTION_VERBOSE + 1)
+
+/* DLLWRAP options. */
+#define OPTION_DRY_RUN (OPTION_VERSION + 1)
+#define OPTION_DRIVER_NAME (OPTION_DRY_RUN + 1)
+#define OPTION_DRIVER_FLAGS (OPTION_DRIVER_NAME + 1)
+#define OPTION_DLLTOOL_NAME (OPTION_DRIVER_FLAGS + 1)
+#define OPTION_ENTRY (OPTION_DLLTOOL_NAME + 1)
+#define OPTION_IMAGE_BASE (OPTION_ENTRY + 1)
+#define OPTION_TARGET (OPTION_IMAGE_BASE + 1)
+
+/* DLLTOOL options. */
+#define OPTION_NODELETE (OPTION_TARGET + 1)
+#define OPTION_DLLNAME (OPTION_NODELETE + 1)
+#define OPTION_NO_IDATA4 (OPTION_DLLNAME + 1)
+#define OPTION_NO_IDATA5 (OPTION_NO_IDATA4 + 1)
+#define OPTION_OUTPUT_EXP (OPTION_NO_IDATA5 + 1)
+#define OPTION_OUTPUT_DEF (OPTION_OUTPUT_EXP + 1)
+#define OPTION_EXPORT_ALL_SYMS (OPTION_OUTPUT_DEF + 1)
+#define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
+#define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1)
+#define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
+#define OPTION_OUTPUT_LIB (OPTION_NO_DEFAULT_EXCLUDES + 1)
+#define OPTION_DEF (OPTION_OUTPUT_LIB + 1)
+#define OPTION_ADD_UNDERSCORE (OPTION_DEF + 1)
+#define OPTION_KILLAT (OPTION_ADD_UNDERSCORE + 1)
+#define OPTION_HELP (OPTION_KILLAT + 1)
+#define OPTION_MACHINE (OPTION_HELP + 1)
+#define OPTION_ADD_INDIRECT (OPTION_MACHINE + 1)
+#define OPTION_BASE_FILE (OPTION_ADD_INDIRECT + 1)
+#define OPTION_AS (OPTION_BASE_FILE + 1)
+
+static const struct option long_options[] =
+{
+ /* generic options. */
+ {"quiet", no_argument, NULL, 'q'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"version", no_argument, NULL, OPTION_VERSION},
+ {"implib", required_argument, NULL, OPTION_OUTPUT_LIB},
+
+ /* dllwrap options. */
+ {"dry-run", no_argument, NULL, OPTION_DRY_RUN},
+ {"driver-name", required_argument, NULL, OPTION_DRIVER_NAME},
+ {"driver-flags", required_argument, NULL, OPTION_DRIVER_FLAGS},
+ {"dlltool-name", required_argument, NULL, OPTION_DLLTOOL_NAME},
+ {"entry", required_argument, NULL, 'e'},
+ {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
+ {"target", required_argument, NULL, OPTION_TARGET},
+
+ /* dlltool options. */
+ {"no-delete", no_argument, NULL, 'n'},
+ {"dllname", required_argument, NULL, OPTION_DLLNAME},
+ {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
+ {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
+ {"output-exp", required_argument, NULL, OPTION_OUTPUT_EXP},
+ {"output-def", required_argument, NULL, OPTION_OUTPUT_DEF},
+ {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS},
+ {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS},
+ {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
+ {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
+ {"output-lib", required_argument, NULL, OPTION_OUTPUT_LIB},
+ {"def", required_argument, NULL, OPTION_DEF},
+ {"add-underscore", no_argument, NULL, 'U'},
+ {"killat", no_argument, NULL, 'k'},
+ {"add-stdcall-alias", no_argument, NULL, 'A'},
+ {"help", no_argument, NULL, 'h'},
+ {"machine", required_argument, NULL, OPTION_MACHINE},
+ {"add-indirect", no_argument, NULL, OPTION_ADD_INDIRECT},
+ {"base-file", required_argument, NULL, OPTION_BASE_FILE},
+ {"as", required_argument, NULL, OPTION_AS},
+ {0}
+};
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int i;
+
+ char **saved_argv = 0;
+ int cmdline_len = 0;
+
+ int export_all = 0;
+
+ int *dlltool_arg_indices;
+ int *driver_arg_indices;
+
+ char *driver_flags = 0;
+ char *output_lib_file_name = 0;
+
+ dyn_string_t dlltool_cmdline;
+ dyn_string_t driver_cmdline;
+
+ int def_file_seen = 0;
+
+ char *image_base_str = 0;
+
+ program_name = argv[0];
+
+ saved_argv = (char **) xmalloc (argc * sizeof (char*));
+ dlltool_arg_indices = (int *) xmalloc (argc * sizeof (int));
+ driver_arg_indices = (int *) xmalloc (argc * sizeof (int));
+ for (i = 0; i < argc; ++i)
+ {
+ size_t len = strlen (argv[i]);
+ char *arg = (char *) xmalloc (len + 1);
+ strcpy (arg, argv[i]);
+ cmdline_len += len;
+ saved_argv[i] = arg;
+ dlltool_arg_indices[i] = 0;
+ driver_arg_indices[i] = 1;
+ }
+ cmdline_len++;
+
+ /* We recognize dllwrap and dlltool options, and everything else is
+ passed onto the language driver (eg., to GCC). We collect options
+ to dlltool and driver in dlltool_args and driver_args. */
+
+ opterr = 0;
+ while ((c = getopt_long_only (argc, argv, "nkAqve:Uho:l:L:I:",
+ long_options, (int *) 0)) != EOF)
+ {
+ int dlltool_arg;
+ int driver_arg;
+ int single_word_option_value_pair;
+
+ dlltool_arg = 0;
+ driver_arg = 1;
+ single_word_option_value_pair = 0;
+
+ if (c != '?')
+ {
+ /* We recognize this option, so it has to be either dllwrap or
+ dlltool option. Do not pass to driver unless it's one of the
+ generic options that are passed to all the tools (such as -v)
+ which are dealt with later. */
+ driver_arg = 0;
+ }
+
+ /* deal with generic and dllwrap options first. */
+ switch (c)
+ {
+ case 'h':
+ usage (stdout, 0);
+ break;
+ case 'q':
+ verbose = 0;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case OPTION_VERSION:
+ print_version (program_name);
+ break;
+ case 'e':
+ entry_point = optarg;
+ break;
+ case OPTION_IMAGE_BASE:
+ image_base_str = optarg;
+ break;
+ case OPTION_DEF:
+ def_file_name = optarg;
+ def_file_seen = 1;
+ delete_def_file = 0;
+ break;
+ case 'n':
+ dontdeltemps = 1;
+ dlltool_arg = 1;
+ break;
+ case 'o':
+ dll_file_name = optarg;
+ break;
+ case 'I':
+ case 'l':
+ case 'L':
+ driver_arg = 1;
+ break;
+ case OPTION_DLLNAME:
+ dll_name = optarg;
+ break;
+ case OPTION_DRY_RUN:
+ dry_run = 1;
+ break;
+ case OPTION_DRIVER_NAME:
+ driver_name = optarg;
+ break;
+ case OPTION_DRIVER_FLAGS:
+ driver_flags = optarg;
+ break;
+ case OPTION_DLLTOOL_NAME:
+ dlltool_name = optarg;
+ break;
+ case OPTION_TARGET:
+ target = optarg;
+ break;
+ case OPTION_BASE_FILE:
+ base_file_name = optarg;
+ delete_base_file = 0;
+ break;
+ case OPTION_OUTPUT_EXP:
+ exp_file_name = optarg;
+ delete_exp_file = 0;
+ break;
+ case OPTION_EXPORT_ALL_SYMS:
+ export_all = 1;
+ break;
+ case OPTION_OUTPUT_LIB:
+ output_lib_file_name = optarg;
+ break;
+ case '?':
+ break;
+ default:
+ dlltool_arg = 1;
+ break;
+ }
+
+ /* Handle passing through --option=value case. */
+ if (optarg
+ && saved_argv[optind-1][0] == '-'
+ && saved_argv[optind-1][1] == '-'
+ && strchr (saved_argv[optind-1], '='))
+ single_word_option_value_pair = 1;
+
+ if (dlltool_arg)
+ {
+ dlltool_arg_indices[optind-1] = 1;
+ if (optarg && ! single_word_option_value_pair)
+ {
+ dlltool_arg_indices[optind-2] = 1;
+ }
+ }
+
+ if (! driver_arg)
+ {
+ driver_arg_indices[optind-1] = 0;
+ if (optarg && ! single_word_option_value_pair)
+ {
+ driver_arg_indices[optind-2] = 0;
+ }
+ }
+ }
+
+ /* sanity checks. */
+ if (! dll_name && ! dll_file_name)
+ {
+ fprintf (stderr,
+ "%s: Must provide at least one of -o or --dllname options\n",
+ program_name);
+ exit (1);
+ }
+ else if (! dll_name)
+ {
+ dll_name = xstrdup (mybasename (dll_file_name));
+ }
+ else if (! dll_file_name)
+ {
+ dll_file_name = xstrdup (dll_name);
+ }
+
+ if (! def_file_seen)
+ {
+ char *fileprefix = choose_temp_base ();
+ def_file_name = (char *) xmalloc (strlen (fileprefix) + 5);
+ sprintf (def_file_name, "%s.def",
+ (dontdeltemps) ? mybasename (fileprefix) : fileprefix);
+ delete_def_file = 1;
+ free (fileprefix);
+ delete_def_file = 1;
+ fprintf (stderr, "Warning: no export definition file provided\n");
+ fprintf (stderr,
+ "dllwrap will create one, but may not be what you want\n");
+ }
+
+ /* set the target platform. */
+ if (strstr (target, "cygwin32"))
+ which_target = CYGWIN_TARGET;
+ else if (strstr (target, "mingw32"))
+ which_target = MINGW32_TARGET;
+ else
+ which_target = UNKNOWN_TARGET;
+
+ /* re-create the command lines as a string, taking care to quote stuff. */
+ dlltool_cmdline = dyn_string_new (cmdline_len);
+ if (verbose)
+ {
+ dyn_string_append (dlltool_cmdline, " -v");
+ }
+ dyn_string_append (dlltool_cmdline, " --dllname ");
+ dyn_string_append (dlltool_cmdline, dll_name);
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (dlltool_arg_indices[i])
+ {
+ char *arg = saved_argv[i];
+ int quote = (strchr (arg, ' ') || strchr (arg, '\t'));
+ dyn_string_append (dlltool_cmdline,
+ (quote) ? " \"" : " ");
+ dyn_string_append (dlltool_cmdline, arg);
+ dyn_string_append (dlltool_cmdline,
+ (quote) ? "\"" : "");
+ }
+ }
+
+ driver_cmdline = dyn_string_new (cmdline_len);
+ if (! driver_flags || strlen (driver_flags) == 0)
+ {
+ switch (which_target)
+ {
+ case CYGWIN_TARGET:
+ driver_flags = cygwin_driver_flags;
+ break;
+
+ case MINGW32_TARGET:
+ driver_flags = mingw32_driver_flags;
+ break;
+
+ default:
+ driver_flags = generic_driver_flags;
+ break;
+ }
+ }
+ dyn_string_append (driver_cmdline, driver_flags);
+ dyn_string_append (driver_cmdline, " -o ");
+ dyn_string_append (driver_cmdline, dll_file_name);
+
+ if (! entry_point || strlen (entry_point) == 0)
+ {
+ switch (which_target)
+ {
+ case CYGWIN_TARGET:
+ entry_point = "__cygwin_dll_entry@12";
+ break;
+
+ case MINGW32_TARGET:
+ entry_point = "_DllMainCRTStartup@12";
+ break;
+
+ default:
+ entry_point = "_DllMain@12";
+ break;
+ }
+ }
+ dyn_string_append (driver_cmdline, " -Wl,-e,");
+ dyn_string_append (driver_cmdline, entry_point);
+ dyn_string_append (dlltool_cmdline, " --exclude-symbol=");
+ dyn_string_append (dlltool_cmdline,
+ (entry_point[0] == '_') ? entry_point+1 : entry_point);
+
+ if (! image_base_str || strlen (image_base_str) == 0)
+ {
+ char *tmpbuf = (char *) xmalloc (sizeof ("0x12345678") + 1);
+ unsigned long hash = strhash (dll_file_name);
+ sprintf (tmpbuf, "0x%.8lX", 0x60000000|((hash<<16)&0xFFC0000));
+ image_base_str = tmpbuf;
+ }
+
+ dyn_string_append (driver_cmdline, " -Wl,--image-base,");
+ dyn_string_append (driver_cmdline, image_base_str);
+
+ if (verbose)
+ {
+ dyn_string_append (driver_cmdline, " -v");
+ }
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (driver_arg_indices[i])
+ {
+ char *arg = saved_argv[i];
+ int quote = (strchr (arg, ' ') || strchr (arg, '\t'));
+ dyn_string_append (driver_cmdline,
+ (quote) ? " \"" : " ");
+ dyn_string_append (driver_cmdline, arg);
+ dyn_string_append (driver_cmdline,
+ (quote) ? "\"" : "");
+ }
+ }
+
+ /*
+ * Step pre-1. If no --def <EXPORT_DEF> is specified, then create it
+ * and then pass it on.
+ */
+
+ if (! def_file_seen)
+ {
+ int i;
+ dyn_string_t step_pre1;
+
+ step_pre1 = dyn_string_new (1024);
+
+ dyn_string_append (step_pre1, dlltool_cmdline->s);
+ if (export_all)
+ {
+ dyn_string_append (step_pre1, " --export-all --exclude-symbol=");
+ dyn_string_append (step_pre1,
+ "_cygwin_dll_entry@12,DllMainCRTStartup@12,DllMain@12,DllEntryPoint@12");
+ }
+ dyn_string_append (step_pre1, " --output-def ");
+ dyn_string_append (step_pre1, def_file_name);
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (driver_arg_indices[i])
+ {
+ char *arg = saved_argv[i];
+ size_t len = strlen (arg);
+ if (len >= 2 && arg[len-2] == '.'
+ && (arg[len-1] == 'o' || arg[len-1] == 'a'))
+ {
+ int quote = (strchr (arg, ' ') || strchr (arg, '\t'));
+ dyn_string_append (step_pre1,
+ (quote) ? " \"" : " ");
+ dyn_string_append (step_pre1, arg);
+ dyn_string_append (step_pre1,
+ (quote) ? "\"" : "");
+ }
+ }
+ }
+
+ if (run (dlltool_name, step_pre1->s))
+ cleanup_and_exit (1);
+
+ dyn_string_delete (step_pre1);
+ }
+
+ dyn_string_append (dlltool_cmdline, " --def ");
+ dyn_string_append (dlltool_cmdline, def_file_name);
+
+ if (verbose)
+ {
+ fprintf (stderr, "DLLTOOL name : %s\n", dlltool_name);
+ fprintf (stderr, "DLLTOOL options : %s\n", dlltool_cmdline->s);
+ fprintf (stderr, "DRIVER name : %s\n", driver_name);
+ fprintf (stderr, "DRIVER options : %s\n", driver_cmdline->s);
+ }
+
+ /*
+ * Step 1. Call GCC/LD to create base relocation file. If using GCC, the
+ * driver command line will look like the following:
+ *
+ * % gcc -Wl,--dll --Wl,--base-file,foo.base [rest of command line]
+ *
+ * If the user does not specify a base name, create temporary one that
+ * is deleted at exit.
+ *
+ */
+
+ if (! base_file_name)
+ {
+ char *fileprefix = choose_temp_base ();
+ base_file_name = (char *) xmalloc (strlen (fileprefix) + 6);
+ sprintf (base_file_name, "%s.base",
+ (dontdeltemps) ? mybasename (fileprefix) : fileprefix);
+ delete_base_file = 1;
+ free (fileprefix);
+ }
+
+ {
+ int quote;
+
+ dyn_string_t step1 = dyn_string_new (driver_cmdline->length
+ + strlen (base_file_name)
+ + 20);
+ dyn_string_append (step1, "-Wl,--base-file,");
+ quote = (strchr (base_file_name, ' ')
+ || strchr (base_file_name, '\t'));
+ dyn_string_append (step1,
+ (quote) ? "\"" : "");
+ dyn_string_append (step1, base_file_name);
+ dyn_string_append (step1,
+ (quote) ? "\"" : "");
+ if (driver_cmdline->length)
+ {
+ dyn_string_append (step1, " ");
+ dyn_string_append (step1, driver_cmdline->s);
+ }
+
+ if (run (driver_name, step1->s))
+ cleanup_and_exit (1);
+
+ dyn_string_delete (step1);
+ }
+
+
+
+ /*
+ * Step 2. generate the exp file by running dlltool.
+ * dlltool command line will look like the following:
+ *
+ * % dlltool -Wl,--dll --Wl,--base-file,foo.base [rest of command line]
+ *
+ * If the user does not specify a base name, create temporary one that
+ * is deleted at exit.
+ *
+ */
+
+ if (! exp_file_name)
+ {
+ char *p = strrchr (dll_name, '.');
+ size_t prefix_len = (p) ? p - dll_name : strlen (dll_name);
+ exp_file_name = (char *) xmalloc (prefix_len + 4 + 1);
+ strncpy (exp_file_name, dll_name, prefix_len);
+ exp_file_name[prefix_len] = '\0';
+ strcat (exp_file_name, ".exp");
+ delete_exp_file = 1;
+ }
+
+ {
+ int quote;
+ dyn_string_t step2 = dyn_string_new (dlltool_cmdline->length
+ + strlen (base_file_name)
+ + strlen (exp_file_name)
+ + 20);
+
+ dyn_string_append (step2, "--base-file ");
+ quote = (strchr (base_file_name, ' ')
+ || strchr (base_file_name, '\t'));
+ dyn_string_append (step2,
+ (quote) ? "\"" : "");
+ dyn_string_append (step2, base_file_name);
+ dyn_string_append (step2,
+ (quote) ? "\" " : " ");
+
+ dyn_string_append (step2, "--output-exp ");
+ quote = (strchr (exp_file_name, ' ')
+ || strchr (exp_file_name, '\t'));
+ dyn_string_append (step2,
+ (quote) ? "\"" : "");
+ dyn_string_append (step2, exp_file_name);
+ dyn_string_append (step2,
+ (quote) ? "\"" : "");
+
+ if (dlltool_cmdline->length)
+ {
+ dyn_string_append (step2, " ");
+ dyn_string_append (step2, dlltool_cmdline->s);
+ }
+
+ if (run (dlltool_name, step2->s))
+ cleanup_and_exit (1);
+
+ dyn_string_delete (step2);
+ }
+
+ /*
+ * Step 3. Call GCC/LD to again, adding the exp file this time.
+ * driver command line will look like the following:
+ *
+ * % gcc -Wl,--dll --Wl,--base-file,foo.base foo.exp [rest ...]
+ */
+
+ {
+ int quote;
+
+ dyn_string_t step3 = dyn_string_new (driver_cmdline->length
+ + strlen (exp_file_name)
+ + strlen (base_file_name)
+ + 20);
+ dyn_string_append (step3, "-Wl,--base-file,");
+ quote = (strchr (base_file_name, ' ')
+ || strchr (base_file_name, '\t'));
+ dyn_string_append (step3,
+ (quote) ? "\"" : "");
+ dyn_string_append (step3, base_file_name);
+ dyn_string_append (step3,
+ (quote) ? "\" " : " ");
+
+ quote = (strchr (exp_file_name, ' ')
+ || strchr (exp_file_name, '\t'));
+ dyn_string_append (step3,
+ (quote) ? "\"" : "");
+ dyn_string_append (step3, exp_file_name);
+ dyn_string_append (step3,
+ (quote) ? "\"" : "");
+
+ if (driver_cmdline->length)
+ {
+ dyn_string_append (step3, " ");
+ dyn_string_append (step3, driver_cmdline->s);
+ }
+
+ if (run (driver_name, step3->s))
+ cleanup_and_exit (1);
+
+ dyn_string_delete (step3);
+ }
+
+
+ /*
+ * Step 4. Run DLLTOOL again using the same command line.
+ */
+
+ {
+ int quote;
+ dyn_string_t step4 = dyn_string_new (dlltool_cmdline->length
+ + strlen (base_file_name)
+ + strlen (exp_file_name)
+ + 20);
+
+ dyn_string_append (step4, "--base-file ");
+ quote = (strchr (base_file_name, ' ')
+ || strchr (base_file_name, '\t'));
+ dyn_string_append (step4,
+ (quote) ? "\"" : "");
+ dyn_string_append (step4, base_file_name);
+ dyn_string_append (step4,
+ (quote) ? "\" " : " ");
+
+ dyn_string_append (step4, "--output-exp ");
+ quote = (strchr (exp_file_name, ' ')
+ || strchr (exp_file_name, '\t'));
+ dyn_string_append (step4,
+ (quote) ? "\"" : "");
+ dyn_string_append (step4, exp_file_name);
+ dyn_string_append (step4,
+ (quote) ? "\"" : "");
+
+ if (dlltool_cmdline->length)
+ {
+ dyn_string_append (step4, " ");
+ dyn_string_append (step4, dlltool_cmdline->s);
+ }
+
+ if (output_lib_file_name)
+ {
+ dyn_string_append (step4, " --output-lib ");
+ dyn_string_append (step4, output_lib_file_name);
+ }
+
+ if (run (dlltool_name, step4->s))
+ cleanup_and_exit (1);
+
+ dyn_string_delete (step4);
+ }
+
+
+ /*
+ * Step 5. Link it all together and be done with it.
+ * driver command line will look like the following:
+ *
+ * % gcc -Wl,--dll foo.exp [rest ...]
+ *
+ */
+
+ {
+ int quote;
+
+ dyn_string_t step5 = dyn_string_new (driver_cmdline->length
+ + strlen (exp_file_name)
+ + 20);
+ quote = (strchr (exp_file_name, ' ')
+ || strchr (exp_file_name, '\t'));
+ dyn_string_append (step5,
+ (quote) ? "\"" : "");
+ dyn_string_append (step5, exp_file_name);
+ dyn_string_append (step5,
+ (quote) ? "\"" : "");
+
+ if (driver_cmdline->length)
+ {
+ dyn_string_append (step5, " ");
+ dyn_string_append (step5, driver_cmdline->s);
+ }
+
+ if (run (driver_name, step5->s))
+ cleanup_and_exit (1);
+
+ dyn_string_delete (step5);
+ }
+
+ cleanup_and_exit (0);
+
+ return 0;
+}
diff --git a/binutils/dyn-string.c b/binutils/dyn-string.c
new file mode 100644
index 00000000000..a4a304343c3
--- /dev/null
+++ b/binutils/dyn-string.c
@@ -0,0 +1,107 @@
+/* An abstract string datatype.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+ This file is part of GNU CC.
+
+ GNU CC 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, or (at your option)
+ any later version.
+
+ GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free
+ Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This file lives in at least two places: binutils and gcc.
+ Don't change one without the other. */
+
+#include "config.h"
+#ifdef IN_GCC
+#include "system.h"
+#include "gansidecl.h"
+#else
+#include "ansidecl.h"
+#endif
+#include "dyn-string.h"
+
+extern char *xmalloc ();
+extern char *xrealloc ();
+
+/* Create a new dynamic string capable of holding at least SPACE
+ characters, including the terminating NUL. If SPACE is 0, it
+ will be silently increased to 1. */
+
+dyn_string_t
+dyn_string_new (space)
+ int space;
+{
+ dyn_string_t result = (dyn_string_t) xmalloc (sizeof (struct dyn_string));
+
+ if (space == 0)
+ /* We need at least one byte in which to store the terminating
+ NUL. */
+ space = 1;
+
+ result->allocated = space;
+ result->s = (char*) xmalloc (space);
+ result->length = 0;
+ result->s[0] = '\0';
+
+ return result;
+}
+
+/* Free the memory used by DS. */
+
+void
+dyn_string_delete (ds)
+ dyn_string_t ds;
+{
+ free (ds->s);
+ free (ds);
+}
+
+/* Append the NUL-terminated string S to DS, resizing DS if
+ necessary. */
+
+dyn_string_t
+dyn_string_append (ds, s)
+ dyn_string_t ds;
+ char *s;
+{
+ int len = strlen (s);
+ dyn_string_resize (ds, ds->length + len + 1 /* '\0' */);
+ strcpy (ds->s + ds->length, s);
+ ds->length += len;
+
+ return ds;
+}
+
+/* Increase the capacity of DS so that it can hold at least SPACE
+ characters, including the terminating NUL. This function will not
+ (at present) reduce the capacity of DS. */
+
+dyn_string_t
+dyn_string_resize (ds, space)
+ dyn_string_t ds;
+ int space;
+{
+ int new_allocated = ds->allocated;
+
+ while (space > new_allocated)
+ new_allocated *= 2;
+
+ if (new_allocated != ds->allocated)
+ {
+ /* We actually need more space. */
+ ds->allocated = new_allocated;
+ ds->s = (char*) xrealloc (ds->s, ds->allocated);
+ }
+
+ return ds;
+}
diff --git a/binutils/dyn-string.h b/binutils/dyn-string.h
new file mode 100644
index 00000000000..a22bbbf6546
--- /dev/null
+++ b/binutils/dyn-string.h
@@ -0,0 +1,34 @@
+/* An abstract string datatype.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+ This file is part of GNU CC.
+
+ GNU CC 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, or (at your option)
+ any later version.
+
+ GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free
+ Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This file lives in at least two places: binutils and gcc.
+ Don't change one without the other. */
+
+typedef struct dyn_string
+{
+ int allocated; /* The amount of space allocated for the string. */
+ int length; /* The actual length of the string. */
+ char *s; /* The string itself, NUL-terminated. */
+}* dyn_string_t;
+
+extern dyn_string_t dyn_string_new PARAMS((int));
+extern void dyn_string_delete PARAMS((dyn_string_t));
+extern dyn_string_t dyn_string_append PARAMS((dyn_string_t, char*));
+extern dyn_string_t dyn_string_resize PARAMS((dyn_string_t, int));
diff --git a/binutils/filemode.c b/binutils/filemode.c
new file mode 100644
index 00000000000..58b52ba7489
--- /dev/null
+++ b/binutils/filemode.c
@@ -0,0 +1,266 @@
+/* filemode.c -- make a string describing file modes
+ Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bucomm.h"
+
+static char ftypelet PARAMS ((unsigned long));
+static void setst PARAMS ((unsigned long, char *));
+
+/* filemodestring - fill in string STR with an ls-style ASCII
+ representation of the st_mode field of file stats block STATP.
+ 10 characters are stored in STR; no terminating null is added.
+ The characters stored in STR are:
+
+ 0 File type. 'd' for directory, 'c' for character
+ special, 'b' for block special, 'm' for multiplex,
+ 'l' for symbolic link, 's' for socket, 'p' for fifo,
+ '-' for any other file type
+
+ 1 'r' if the owner may read, '-' otherwise.
+
+ 2 'w' if the owner may write, '-' otherwise.
+
+ 3 'x' if the owner may execute, 's' if the file is
+ set-user-id, '-' otherwise.
+ 'S' if the file is set-user-id, but the execute
+ bit isn't set.
+
+ 4 'r' if group members may read, '-' otherwise.
+
+ 5 'w' if group members may write, '-' otherwise.
+
+ 6 'x' if group members may execute, 's' if the file is
+ set-group-id, '-' otherwise.
+ 'S' if it is set-group-id but not executable.
+
+ 7 'r' if any user may read, '-' otherwise.
+
+ 8 'w' if any user may write, '-' otherwise.
+
+ 9 'x' if any user may execute, 't' if the file is "sticky"
+ (will be retained in swap space after execution), '-'
+ otherwise.
+ 'T' if the file is sticky but not executable. */
+
+#if 0
+
+/* This is not used; only mode_string is used. */
+
+void
+filemodestring (statp, str)
+ struct stat *statp;
+ char *str;
+{
+ mode_string ((unsigned long) statp->st_mode, str);
+}
+
+#endif
+
+/* Get definitions for the file permission bits. */
+
+#ifndef S_IRWXU
+#define S_IRWXU 0700
+#endif
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR 0200
+#endif
+#ifndef S_IXUSR
+#define S_IXUSR 0100
+#endif
+
+#ifndef S_IRWXG
+#define S_IRWXG 0070
+#endif
+#ifndef S_IRGRP
+#define S_IRGRP 0040
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP 0020
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0010
+#endif
+
+#ifndef S_IRWXO
+#define S_IRWXO 0007
+#endif
+#ifndef S_IROTH
+#define S_IROTH 0004
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH 0002
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001
+#endif
+
+/* Like filemodestring, but only the relevant part of the `struct stat'
+ is given as an argument. */
+
+void
+mode_string (mode, str)
+ unsigned long mode;
+ char *str;
+{
+ str[0] = ftypelet ((unsigned long) mode);
+ str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-';
+ str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-';
+ str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-';
+ str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-';
+ str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-';
+ str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-';
+ str[7] = (mode & S_IROTH) != 0 ? 'r' : '-';
+ str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-';
+ str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-';
+ setst ((unsigned long) mode, str);
+}
+
+/* Return a character indicating the type of file described by
+ file mode BITS:
+ 'd' for directories
+ 'b' for block special files
+ 'c' for character special files
+ 'm' for multiplexor files
+ 'l' for symbolic links
+ 's' for sockets
+ 'p' for fifos
+ '-' for any other file type. */
+
+#ifndef S_ISDIR
+#ifdef S_IFDIR
+#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
+#else /* ! defined (S_IFDIR) */
+#define S_ISDIR(i) (((i) & 0170000) == 040000)
+#endif /* ! defined (S_IFDIR) */
+#endif /* ! defined (S_ISDIR) */
+
+#ifndef S_ISBLK
+#ifdef S_IFBLK
+#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK)
+#else /* ! defined (S_IFBLK) */
+#define S_ISBLK(i) 0
+#endif /* ! defined (S_IFBLK) */
+#endif /* ! defined (S_ISBLK) */
+
+#ifndef S_ISCHR
+#ifdef S_IFCHR
+#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR)
+#else /* ! defined (S_IFCHR) */
+#define S_ISCHR(i) 0
+#endif /* ! defined (S_IFCHR) */
+#endif /* ! defined (S_ISCHR) */
+
+#ifndef S_ISFIFO
+#ifdef S_IFIFO
+#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO)
+#else /* ! defined (S_IFIFO) */
+#define S_ISFIFO(i) 0
+#endif /* ! defined (S_IFIFO) */
+#endif /* ! defined (S_ISFIFO) */
+
+#ifndef S_ISSOCK
+#ifdef S_IFSOCK
+#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK)
+#else /* ! defined (S_IFSOCK) */
+#define S_ISSOCK(i) 0
+#endif /* ! defined (S_IFSOCK) */
+#endif /* ! defined (S_ISSOCK) */
+
+#ifndef S_ISLNK
+#ifdef S_IFLNK
+#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK)
+#else /* ! defined (S_IFLNK) */
+#define S_ISLNK(i) 0
+#endif /* ! defined (S_IFLNK) */
+#endif /* ! defined (S_ISLNK) */
+
+static char
+ftypelet (bits)
+ unsigned long bits;
+{
+ if (S_ISDIR (bits))
+ return 'd';
+ if (S_ISLNK (bits))
+ return 'l';
+ if (S_ISBLK (bits))
+ return 'b';
+ if (S_ISCHR (bits))
+ return 'c';
+ if (S_ISSOCK (bits))
+ return 's';
+ if (S_ISFIFO (bits))
+ return 'p';
+
+#ifdef S_IFMT
+#ifdef S_IFMPC
+ if ((bits & S_IFMT) == S_IFMPC
+ || (bits & S_IFMT) == S_IFMPB)
+ return 'm';
+#endif
+#ifdef S_IFNWK
+ if ((bits & S_IFMT) == S_IFNWK)
+ return 'n';
+#endif
+#endif
+
+ return '-';
+}
+
+/* Set the 's' and 't' flags in file attributes string CHARS,
+ according to the file mode BITS. */
+
+static void
+setst (bits, chars)
+ unsigned long bits;
+ char *chars;
+{
+#ifdef S_ISUID
+ if (bits & S_ISUID)
+ {
+ if (chars[3] != 'x')
+ /* Set-uid, but not executable by owner. */
+ chars[3] = 'S';
+ else
+ chars[3] = 's';
+ }
+#endif
+#ifdef S_ISGID
+ if (bits & S_ISGID)
+ {
+ if (chars[6] != 'x')
+ /* Set-gid, but not executable by group. */
+ chars[6] = 'S';
+ else
+ chars[6] = 's';
+ }
+#endif
+#ifdef S_ISVTX
+ if (bits & S_ISVTX)
+ {
+ if (chars[9] != 'x')
+ /* Sticky, but not executable by others. */
+ chars[9] = 'T';
+ else
+ chars[9] = 't';
+ }
+#endif
+}
diff --git a/binutils/ieee.c b/binutils/ieee.c
new file mode 100644
index 00000000000..17a5b882131
--- /dev/null
+++ b/binutils/ieee.c
@@ -0,0 +1,7609 @@
+/* ieee.c -- Read and write IEEE-695 debugging information.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file reads and writes IEEE-695 debugging information. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "bfd.h"
+#include "ieee.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* This structure holds an entry on the block stack. */
+
+struct ieee_block
+{
+ /* The kind of block. */
+ int kind;
+ /* The source file name, for a BB5 block. */
+ const char *filename;
+ /* The index of the function type, for a BB4 or BB6 block. */
+ unsigned int fnindx;
+ /* True if this function is being skipped. */
+ boolean skip;
+};
+
+/* This structure is the block stack. */
+
+#define BLOCKSTACK_SIZE (16)
+
+struct ieee_blockstack
+{
+ /* The stack pointer. */
+ struct ieee_block *bsp;
+ /* The stack. */
+ struct ieee_block stack[BLOCKSTACK_SIZE];
+};
+
+/* This structure holds information for a variable. */
+
+struct ieee_var
+{
+ /* Start of name. */
+ const char *name;
+ /* Length of name. */
+ unsigned long namlen;
+ /* Type. */
+ debug_type type;
+ /* Slot if we make an indirect type. */
+ debug_type *pslot;
+ /* Kind of variable or function. */
+ enum
+ {
+ IEEE_UNKNOWN,
+ IEEE_EXTERNAL,
+ IEEE_GLOBAL,
+ IEEE_STATIC,
+ IEEE_LOCAL,
+ IEEE_FUNCTION
+ } kind;
+};
+
+/* This structure holds all the variables. */
+
+struct ieee_vars
+{
+ /* Number of slots allocated. */
+ unsigned int alloc;
+ /* Variables. */
+ struct ieee_var *vars;
+};
+
+/* This structure holds information for a type. We need this because
+ we don't want to represent bitfields as real types. */
+
+struct ieee_type
+{
+ /* Type. */
+ debug_type type;
+ /* Slot if this is type is referenced before it is defined. */
+ debug_type *pslot;
+ /* Slots for arguments if we make indirect types for them. */
+ debug_type *arg_slots;
+ /* If this is a bitfield, this is the size in bits. If this is not
+ a bitfield, this is zero. */
+ unsigned long bitsize;
+};
+
+/* This structure holds all the type information. */
+
+struct ieee_types
+{
+ /* Number of slots allocated. */
+ unsigned int alloc;
+ /* Types. */
+ struct ieee_type *types;
+ /* Builtin types. */
+#define BUILTIN_TYPE_COUNT (60)
+ debug_type builtins[BUILTIN_TYPE_COUNT];
+};
+
+/* This structure holds a linked last of structs with their tag names,
+ so that we can convert them to C++ classes if necessary. */
+
+struct ieee_tag
+{
+ /* Next tag. */
+ struct ieee_tag *next;
+ /* This tag name. */
+ const char *name;
+ /* The type of the tag. */
+ debug_type type;
+ /* The tagged type is an indirect type pointing at this slot. */
+ debug_type slot;
+ /* This is an array of slots used when a field type is converted
+ into a indirect type, in case it needs to be later converted into
+ a reference type. */
+ debug_type *fslots;
+};
+
+/* This structure holds the information we pass around to the parsing
+ functions. */
+
+struct ieee_info
+{
+ /* The debugging handle. */
+ PTR dhandle;
+ /* The BFD. */
+ bfd *abfd;
+ /* The start of the bytes to be parsed. */
+ const bfd_byte *bytes;
+ /* The end of the bytes to be parsed. */
+ const bfd_byte *pend;
+ /* The block stack. */
+ struct ieee_blockstack blockstack;
+ /* Whether we have seen a BB1 or BB2. */
+ boolean saw_filename;
+ /* The variables. */
+ struct ieee_vars vars;
+ /* The global variables, after a global typedef block. */
+ struct ieee_vars *global_vars;
+ /* The types. */
+ struct ieee_types types;
+ /* The global types, after a global typedef block. */
+ struct ieee_types *global_types;
+ /* The list of tagged structs. */
+ struct ieee_tag *tags;
+};
+
+/* Basic builtin types, not including the pointers. */
+
+enum builtin_types
+{
+ builtin_unknown = 0,
+ builtin_void = 1,
+ builtin_signed_char = 2,
+ builtin_unsigned_char = 3,
+ builtin_signed_short_int = 4,
+ builtin_unsigned_short_int = 5,
+ builtin_signed_long = 6,
+ builtin_unsigned_long = 7,
+ builtin_signed_long_long = 8,
+ builtin_unsigned_long_long = 9,
+ builtin_float = 10,
+ builtin_double = 11,
+ builtin_long_double = 12,
+ builtin_long_long_double = 13,
+ builtin_quoted_string = 14,
+ builtin_instruction_address = 15,
+ builtin_int = 16,
+ builtin_unsigned = 17,
+ builtin_unsigned_int = 18,
+ builtin_char = 19,
+ builtin_long = 20,
+ builtin_short = 21,
+ builtin_unsigned_short = 22,
+ builtin_short_int = 23,
+ builtin_signed_short = 24,
+ builtin_bcd_float = 25
+};
+
+/* These are the values found in the derivation flags of a 'b'
+ component record of a 'T' type extension record in a C++ pmisc
+ record. These are bitmasks. */
+
+/* Set for a private base class, clear for a public base class.
+ Protected base classes are not supported. */
+#define BASEFLAGS_PRIVATE (0x1)
+/* Set for a virtual base class. */
+#define BASEFLAGS_VIRTUAL (0x2)
+/* Set for a friend class, clear for a base class. */
+#define BASEFLAGS_FRIEND (0x10)
+
+/* These are the values found in the specs flags of a 'd', 'm', or 'v'
+ component record of a 'T' type extension record in a C++ pmisc
+ record. The same flags are used for a 'M' record in a C++ pmisc
+ record. */
+
+/* The lower two bits hold visibility information. */
+#define CXXFLAGS_VISIBILITY (0x3)
+/* This value in the lower two bits indicates a public member. */
+#define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
+/* This value in the lower two bits indicates a private member. */
+#define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
+/* This value in the lower two bits indicates a protected member. */
+#define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
+/* Set for a static member. */
+#define CXXFLAGS_STATIC (0x4)
+/* Set for a virtual override. */
+#define CXXFLAGS_OVERRIDE (0x8)
+/* Set for a friend function. */
+#define CXXFLAGS_FRIEND (0x10)
+/* Set for a const function. */
+#define CXXFLAGS_CONST (0x20)
+/* Set for a volatile function. */
+#define CXXFLAGS_VOLATILE (0x40)
+/* Set for an overloaded function. */
+#define CXXFLAGS_OVERLOADED (0x80)
+/* Set for an operator function. */
+#define CXXFLAGS_OPERATOR (0x100)
+/* Set for a constructor or destructor. */
+#define CXXFLAGS_CTORDTOR (0x400)
+/* Set for a constructor. */
+#define CXXFLAGS_CTOR (0x200)
+/* Set for an inline function. */
+#define CXXFLAGS_INLINE (0x800)
+
+/* Local functions. */
+
+static void ieee_error
+ PARAMS ((struct ieee_info *, const bfd_byte *, const char *));
+static void ieee_eof PARAMS ((struct ieee_info *));
+static char *savestring PARAMS ((const char *, unsigned long));
+static boolean ieee_read_number
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static boolean ieee_read_optional_number
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *));
+static boolean ieee_read_id
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *));
+static boolean ieee_read_optional_id
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *, boolean *));
+static boolean ieee_read_expression
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static debug_type ieee_builtin_type
+ PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int));
+static boolean ieee_alloc_type
+ PARAMS ((struct ieee_info *, unsigned int, boolean));
+static boolean ieee_read_type_index
+ PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *));
+static int ieee_regno_to_genreg PARAMS ((bfd *, int));
+static int ieee_genreg_to_regno PARAMS ((bfd *, int));
+static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean ieee_read_cxx_misc
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_cxx_class
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_cxx_defaults
+ PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long));
+static boolean ieee_read_reference
+ PARAMS ((struct ieee_info *, const bfd_byte **));
+static boolean ieee_require_asn
+ PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *));
+static boolean ieee_require_atn65
+ PARAMS ((struct ieee_info *, const bfd_byte **, const char **,
+ unsigned long *));
+
+/* Report an error in the IEEE debugging information. */
+
+static void
+ieee_error (info, p, s)
+ struct ieee_info *info;
+ const bfd_byte *p;
+ const char *s;
+{
+ if (p != NULL)
+ fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
+ (unsigned long) (p - info->bytes), s, *p);
+ else
+ fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
+}
+
+/* Report an unexpected EOF in the IEEE debugging information. */
+
+static void
+ieee_eof (info)
+ struct ieee_info *info;
+{
+ ieee_error (info, (const bfd_byte *) NULL,
+ _("unexpected end of debugging information"));
+}
+
+/* Save a string in memory. */
+
+static char *
+savestring (start, len)
+ const char *start;
+ unsigned long len;
+{
+ char *ret;
+
+ ret = (char *) xmalloc (len + 1);
+ memcpy (ret, start, len);
+ ret[len] = '\0';
+ return ret;
+}
+
+/* Read a number which must be present in an IEEE file. */
+
+static boolean
+ieee_read_number (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ return ieee_read_optional_number (info, pp, pv, (boolean *) NULL);
+}
+
+/* Read a number in an IEEE file. If ppresent is not NULL, the number
+ need not be there. */
+
+static boolean
+ieee_read_optional_number (info, pp, pv, ppresent)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+ boolean *ppresent;
+{
+ ieee_record_enum_type b;
+
+ if (*pp >= info->pend)
+ {
+ if (ppresent != NULL)
+ {
+ *ppresent = false;
+ return true;
+ }
+ ieee_eof (info);
+ return false;
+ }
+
+ b = (ieee_record_enum_type) **pp;
+ ++*pp;
+
+ if (b <= ieee_number_end_enum)
+ {
+ *pv = (bfd_vma) b;
+ if (ppresent != NULL)
+ *ppresent = true;
+ return true;
+ }
+
+ if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
+ {
+ unsigned int i;
+
+ i = (int) b - (int) ieee_number_repeat_start_enum;
+ if (*pp + i - 1 >= info->pend)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ *pv = 0;
+ for (; i > 0; i--)
+ {
+ *pv <<= 8;
+ *pv += **pp;
+ ++*pp;
+ }
+
+ if (ppresent != NULL)
+ *ppresent = true;
+
+ return true;
+ }
+
+ if (ppresent != NULL)
+ {
+ --*pp;
+ *ppresent = false;
+ return true;
+ }
+
+ ieee_error (info, *pp - 1, _("invalid number"));
+ return false;
+}
+
+/* Read a required string from an IEEE file. */
+
+static boolean
+ieee_read_id (info, pp, pname, pnamlen)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL);
+}
+
+/* Read a string from an IEEE file. If ppresent is not NULL, the
+ string is optional. */
+
+static boolean
+ieee_read_optional_id (info, pp, pname, pnamlen, ppresent)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+ boolean *ppresent;
+{
+ bfd_byte b;
+ unsigned long len;
+
+ if (*pp >= info->pend)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ b = **pp;
+ ++*pp;
+
+ if (b <= 0x7f)
+ len = b;
+ else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
+ {
+ len = **pp;
+ ++*pp;
+ }
+ else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
+ {
+ len = (**pp << 8) + (*pp)[1];
+ *pp += 2;
+ }
+ else
+ {
+ if (ppresent != NULL)
+ {
+ --*pp;
+ *ppresent = false;
+ return true;
+ }
+ ieee_error (info, *pp - 1, _("invalid string length"));
+ return false;
+ }
+
+ if ((unsigned long) (info->pend - *pp) < len)
+ {
+ ieee_eof (info);
+ return false;
+ }
+
+ *pname = (const char *) *pp;
+ *pnamlen = len;
+ *pp += len;
+
+ if (ppresent != NULL)
+ *ppresent = true;
+
+ return true;
+}
+
+/* Read an expression from an IEEE file. Since this code is only used
+ to parse debugging information, I haven't bothered to write a full
+ blown IEEE expression parser. I've only thrown in the things I've
+ seen in debugging information. This can be easily extended if
+ necessary. */
+
+static boolean
+ieee_read_expression (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ const bfd_byte *expr_start;
+#define EXPR_STACK_SIZE (10)
+ bfd_vma expr_stack[EXPR_STACK_SIZE];
+ bfd_vma *esp;
+
+ expr_start = *pp;
+
+ esp = expr_stack;
+
+ while (1)
+ {
+ const bfd_byte *start;
+ bfd_vma val;
+ boolean present;
+ ieee_record_enum_type c;
+
+ start = *pp;
+
+ if (! ieee_read_optional_number (info, pp, &val, &present))
+ return false;
+
+ if (present)
+ {
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (info, start, _("expression stack overflow"));
+ return false;
+ }
+ *esp++ = val;
+ continue;
+ }
+
+ c = (ieee_record_enum_type) **pp;
+
+ if (c >= ieee_module_beginning_enum)
+ break;
+
+ ++*pp;
+
+ if (c == ieee_comma)
+ break;
+
+ switch (c)
+ {
+ default:
+ ieee_error (info, start, _("unsupported IEEE expression operator"));
+ break;
+
+ case ieee_variable_R_enum:
+ {
+ bfd_vma indx;
+ asection *s;
+
+ if (! ieee_read_number (info, pp, &indx))
+ return false;
+ for (s = info->abfd->sections; s != NULL; s = s->next)
+ if ((bfd_vma) s->target_index == indx)
+ break;
+ if (s == NULL)
+ {
+ ieee_error (info, start, _("unknown section"));
+ return false;
+ }
+
+ if (esp - expr_stack >= EXPR_STACK_SIZE)
+ {
+ ieee_error (info, start, _("expression stack overflow"));
+ return false;
+ }
+
+ *esp++ = bfd_get_section_vma (info->abfd, s);
+ }
+ break;
+
+ case ieee_function_plus_enum:
+ case ieee_function_minus_enum:
+ {
+ bfd_vma v1, v2;
+
+ if (esp - expr_stack < 2)
+ {
+ ieee_error (info, start, _("expression stack underflow"));
+ return false;
+ }
+
+ v1 = *--esp;
+ v2 = *--esp;
+ *esp++ = v1 + v2;
+ }
+ break;
+ }
+ }
+
+ if (esp - 1 != expr_stack)
+ {
+ ieee_error (info, expr_start, _("expression stack mismatch"));
+ return false;
+ }
+
+ *pv = *--esp;
+
+ return true;
+}
+
+/* Return an IEEE builtin type. */
+
+static debug_type
+ieee_builtin_type (info, p, indx)
+ struct ieee_info *info;
+ const bfd_byte *p;
+ unsigned int indx;
+{
+ PTR dhandle;
+ debug_type type;
+ const char *name;
+
+ if (indx < BUILTIN_TYPE_COUNT
+ && info->types.builtins[indx] != DEBUG_TYPE_NULL)
+ return info->types.builtins[indx];
+
+ dhandle = info->dhandle;
+
+ if (indx >= 32 && indx < 64)
+ {
+ type = debug_make_pointer_type (dhandle,
+ ieee_builtin_type (info, p, indx - 32));
+ assert (indx < BUILTIN_TYPE_COUNT);
+ info->types.builtins[indx] = type;
+ return type;
+ }
+
+ switch ((enum builtin_types) indx)
+ {
+ default:
+ ieee_error (info, p, _("unknown builtin type"));
+ return NULL;
+
+ case builtin_unknown:
+ type = debug_make_void_type (dhandle);
+ name = NULL;
+ break;
+
+ case builtin_void:
+ type = debug_make_void_type (dhandle);
+ name = "void";
+ break;
+
+ case builtin_signed_char:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "signed char";
+ break;
+
+ case builtin_unsigned_char:
+ type = debug_make_int_type (dhandle, 1, true);
+ name = "unsigned char";
+ break;
+
+ case builtin_signed_short_int:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short int";
+ break;
+
+ case builtin_unsigned_short_int:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short int";
+ break;
+
+ case builtin_signed_long:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "signed long";
+ break;
+
+ case builtin_unsigned_long:
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned long";
+ break;
+
+ case builtin_signed_long_long:
+ type = debug_make_int_type (dhandle, 8, false);
+ name = "signed long long";
+ break;
+
+ case builtin_unsigned_long_long:
+ type = debug_make_int_type (dhandle, 8, true);
+ name = "unsigned long long";
+ break;
+
+ case builtin_float:
+ type = debug_make_float_type (dhandle, 4);
+ name = "float";
+ break;
+
+ case builtin_double:
+ type = debug_make_float_type (dhandle, 8);
+ name = "double";
+ break;
+
+ case builtin_long_double:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_float_type (dhandle, 12);
+ name = "long double";
+ break;
+
+ case builtin_long_long_double:
+ type = debug_make_float_type (dhandle, 16);
+ name = "long long double";
+ break;
+
+ case builtin_quoted_string:
+ type = debug_make_array_type (dhandle,
+ ieee_builtin_type (info, p,
+ ((unsigned int)
+ builtin_char)),
+ ieee_builtin_type (info, p,
+ ((unsigned int)
+ builtin_int)),
+ 0, -1, true);
+ name = "QUOTED STRING";
+ break;
+
+ case builtin_instruction_address:
+ /* FIXME: This should be a code address. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "instruction address";
+ break;
+
+ case builtin_int:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "int";
+ break;
+
+ case builtin_unsigned:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned";
+ break;
+
+ case builtin_unsigned_int:
+ /* FIXME: The size for this type should depend upon the
+ processor. */
+ type = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned int";
+ break;
+
+ case builtin_char:
+ type = debug_make_int_type (dhandle, 1, false);
+ name = "char";
+ break;
+
+ case builtin_long:
+ type = debug_make_int_type (dhandle, 4, false);
+ name = "long";
+ break;
+
+ case builtin_short:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short";
+ break;
+
+ case builtin_unsigned_short:
+ type = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short";
+ break;
+
+ case builtin_short_int:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "short int";
+ break;
+
+ case builtin_signed_short:
+ type = debug_make_int_type (dhandle, 2, false);
+ name = "signed short";
+ break;
+
+ case builtin_bcd_float:
+ ieee_error (info, p, _("BCD float type not supported"));
+ return false;
+ }
+
+ if (name != NULL)
+ type = debug_name_type (dhandle, name, type);
+
+ assert (indx < BUILTIN_TYPE_COUNT);
+
+ info->types.builtins[indx] = type;
+
+ return type;
+}
+
+/* Allocate more space in the type table. If ref is true, this is a
+ reference to the type; if it is not already defined, we should set
+ up an indirect type. */
+
+static boolean
+ieee_alloc_type (info, indx, ref)
+ struct ieee_info *info;
+ unsigned int indx;
+ boolean ref;
+{
+ unsigned int nalloc;
+ register struct ieee_type *t;
+ struct ieee_type *tend;
+
+ if (indx >= info->types.alloc)
+ {
+ nalloc = info->types.alloc;
+ if (nalloc == 0)
+ nalloc = 4;
+ while (indx >= nalloc)
+ nalloc *= 2;
+
+ info->types.types = ((struct ieee_type *)
+ xrealloc (info->types.types,
+ nalloc * sizeof *info->types.types));
+
+ memset (info->types.types + info->types.alloc, 0,
+ (nalloc - info->types.alloc) * sizeof *info->types.types);
+
+ tend = info->types.types + nalloc;
+ for (t = info->types.types + info->types.alloc; t < tend; t++)
+ t->type = DEBUG_TYPE_NULL;
+
+ info->types.alloc = nalloc;
+ }
+
+ if (ref)
+ {
+ t = info->types.types + indx;
+ if (t->type == NULL)
+ {
+ t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
+ *t->pslot = DEBUG_TYPE_NULL;
+ t->type = debug_make_indirect_type (info->dhandle, t->pslot,
+ (const char *) NULL);
+ if (t->type == NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read a type index and return the corresponding type. */
+
+static boolean
+ieee_read_type_index (info, pp, ptype)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ debug_type *ptype;
+{
+ const bfd_byte *start;
+ bfd_vma indx;
+
+ start = *pp;
+
+ if (! ieee_read_number (info, pp, &indx))
+ return false;
+
+ if (indx < 256)
+ {
+ *ptype = ieee_builtin_type (info, start, indx);
+ if (*ptype == NULL)
+ return false;
+ return true;
+ }
+
+ indx -= 256;
+ if (! ieee_alloc_type (info, indx, true))
+ return false;
+
+ *ptype = info->types.types[indx].type;
+
+ return true;
+}
+
+/* Parse IEEE debugging information for a file. This is passed the
+ bytes which compose the Debug Information Part of an IEEE file. */
+
+boolean
+parse_ieee (dhandle, abfd, bytes, len)
+ PTR dhandle;
+ bfd *abfd;
+ const bfd_byte *bytes;
+ bfd_size_type len;
+{
+ struct ieee_info info;
+ unsigned int i;
+ const bfd_byte *p, *pend;
+
+ info.dhandle = dhandle;
+ info.abfd = abfd;
+ info.bytes = bytes;
+ info.pend = bytes + len;
+ info.blockstack.bsp = info.blockstack.stack;
+ info.saw_filename = false;
+ info.vars.alloc = 0;
+ info.vars.vars = NULL;
+ info.global_vars = NULL;
+ info.types.alloc = 0;
+ info.types.types = NULL;
+ info.global_types = NULL;
+ info.tags = NULL;
+ for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
+ info.types.builtins[i] = DEBUG_TYPE_NULL;
+
+ p = bytes;
+ pend = info.pend;
+ while (p < pend)
+ {
+ const bfd_byte *record_start;
+ ieee_record_enum_type c;
+
+ record_start = p;
+
+ c = (ieee_record_enum_type) *p++;
+
+ if (c == ieee_at_record_enum)
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
+
+ if (c <= ieee_number_repeat_end_enum)
+ {
+ ieee_error (&info, record_start, _("unexpected number"));
+ return false;
+ }
+
+ switch (c)
+ {
+ default:
+ ieee_error (&info, record_start, _("unexpected record type"));
+ return false;
+
+ case ieee_bb_record_enum:
+ if (! parse_ieee_bb (&info, &p))
+ return false;
+ break;
+
+ case ieee_be_record_enum:
+ if (! parse_ieee_be (&info, &p))
+ return false;
+ break;
+
+ case ieee_nn_record:
+ if (! parse_ieee_nn (&info, &p))
+ return false;
+ break;
+
+ case ieee_ty_record_enum:
+ if (! parse_ieee_ty (&info, &p))
+ return false;
+ break;
+
+ case ieee_atn_record_enum:
+ if (! parse_ieee_atn (&info, &p))
+ return false;
+ break;
+ }
+ }
+
+ if (info.blockstack.bsp != info.blockstack.stack)
+ {
+ ieee_error (&info, (const bfd_byte *) NULL,
+ _("blocks left on stack at end"));
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle an IEEE BB record. */
+
+static boolean
+parse_ieee_bb (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *block_start;
+ bfd_byte b;
+ bfd_vma size;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy = NULL;
+ unsigned int fnindx;
+ boolean skip;
+
+ block_start = *pp;
+
+ b = **pp;
+ ++*pp;
+
+ if (! ieee_read_number (info, pp, &size)
+ || ! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ fnindx = (unsigned int) -1;
+ skip = false;
+
+ switch (b)
+ {
+ case 1:
+ /* BB1: Type definitions local to a module. */
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_set_filename (info->dhandle, namcopy))
+ return false;
+ info->saw_filename = true;
+
+ /* Discard any variables or types we may have seen before. */
+ if (info->vars.vars != NULL)
+ free (info->vars.vars);
+ info->vars.vars = NULL;
+ info->vars.alloc = 0;
+ if (info->types.types != NULL)
+ free (info->types.types);
+ info->types.types = NULL;
+ info->types.alloc = 0;
+
+ /* Initialize the types to the global types. */
+ if (info->global_types != NULL)
+ {
+ info->types.alloc = info->global_types->alloc;
+ info->types.types = ((struct ieee_type *)
+ xmalloc (info->types.alloc
+ * sizeof (*info->types.types)));
+ memcpy (info->types.types, info->global_types->types,
+ info->types.alloc * sizeof (*info->types.types));
+ }
+
+ break;
+
+ case 2:
+ /* BB2: Global type definitions. The name is supposed to be
+ empty, but we don't check. */
+ if (! debug_set_filename (info->dhandle, "*global*"))
+ return false;
+ info->saw_filename = true;
+ break;
+
+ case 3:
+ /* BB3: High level module block begin. We don't have to do
+ anything here. The name is supposed to be the same as for
+ the BB1, but we don't check. */
+ break;
+
+ case 4:
+ /* BB4: Global function. */
+ {
+ bfd_vma stackspace, typindx, offset;
+ debug_type return_type;
+
+ if (! ieee_read_number (info, pp, &stackspace)
+ || ! ieee_read_number (info, pp, &typindx)
+ || ! ieee_read_expression (info, pp, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start, typindx);
+ if (return_type == DEBUG_TYPE_NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy, return_type,
+ true, offset))
+ return false;
+ }
+ break;
+
+ case 5:
+ /* BB5: File name for source line numbers. */
+ {
+ unsigned int i;
+
+ /* We ignore the date and time. FIXME. */
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+ boolean present;
+
+ if (! ieee_read_optional_number (info, pp, &ignore, &present))
+ return false;
+ if (! present)
+ break;
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_start_source (info->dhandle, namcopy))
+ return false;
+ }
+ break;
+
+ case 6:
+ /* BB6: Local function or block. */
+ {
+ bfd_vma stackspace, typindx, offset;
+
+ if (! ieee_read_number (info, pp, &stackspace)
+ || ! ieee_read_number (info, pp, &typindx)
+ || ! ieee_read_expression (info, pp, &offset))
+ return false;
+
+ /* We have no way to record the stack space. FIXME. */
+
+ if (namlen == 0)
+ {
+ if (! debug_start_block (info->dhandle, offset))
+ return false;
+ /* Change b to indicate that this is a block
+ rather than a function. */
+ b = 0x86;
+ }
+ else
+ {
+ /* The MRI C++ compiler will output a fake function named
+ __XRYCPP to hold C++ debugging information. We skip
+ that function. This is not crucial, but it makes
+ converting from IEEE to other debug formats work
+ better. */
+ if (strncmp (name, "__XRYCPP", namlen) == 0)
+ skip = true;
+ else
+ {
+ debug_type return_type;
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start,
+ typindx);
+ if (return_type == NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy,
+ return_type, false, offset))
+ return false;
+ }
+ }
+ }
+ break;
+
+ case 10:
+ /* BB10: Assembler module scope. In the normal case, we
+ completely ignore all this information. FIXME. */
+ {
+ const char *inam, *vstr;
+ unsigned long inamlen, vstrlen;
+ bfd_vma tool_type;
+ boolean present;
+ unsigned int i;
+
+ if (! info->saw_filename)
+ {
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_set_filename (info->dhandle, namcopy))
+ return false;
+ info->saw_filename = true;
+ }
+
+ if (! ieee_read_id (info, pp, &inam, &inamlen)
+ || ! ieee_read_number (info, pp, &tool_type)
+ || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
+ return false;
+ for (i = 0; i < 6; i++)
+ {
+ bfd_vma ignore;
+
+ if (! ieee_read_optional_number (info, pp, &ignore, &present))
+ return false;
+ if (! present)
+ break;
+ }
+ }
+ break;
+
+ case 11:
+ /* BB11: Module section. We completely ignore all this
+ information. FIXME. */
+ {
+ bfd_vma sectype, secindx, offset, map;
+ boolean present;
+
+ if (! ieee_read_number (info, pp, &sectype)
+ || ! ieee_read_number (info, pp, &secindx)
+ || ! ieee_read_expression (info, pp, &offset)
+ || ! ieee_read_optional_number (info, pp, &map, &present))
+ return false;
+ }
+ break;
+
+ default:
+ ieee_error (info, block_start, _("unknown BB type"));
+ return false;
+ }
+
+
+ /* Push this block on the block stack. */
+
+ if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
+ {
+ ieee_error (info, (const bfd_byte *) NULL, _("stack overflow"));
+ return false;
+ }
+
+ info->blockstack.bsp->kind = b;
+ if (b == 5)
+ info->blockstack.bsp->filename = namcopy;
+ info->blockstack.bsp->fnindx = fnindx;
+ info->blockstack.bsp->skip = skip;
+ ++info->blockstack.bsp;
+
+ return true;
+}
+
+/* Handle an IEEE BE record. */
+
+static boolean
+parse_ieee_be (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ bfd_vma offset;
+
+ if (info->blockstack.bsp <= info->blockstack.stack)
+ {
+ ieee_error (info, *pp, _("stack underflow"));
+ return false;
+ }
+ --info->blockstack.bsp;
+
+ switch (info->blockstack.bsp->kind)
+ {
+ case 2:
+ /* When we end the global typedefs block, we copy out the the
+ contents of info->vars. This is because the variable indices
+ may be reused in the local blocks. However, we need to
+ preserve them so that we can locate a function returning a
+ reference variable whose type is named in the global typedef
+ block. */
+ info->global_vars = ((struct ieee_vars *)
+ xmalloc (sizeof *info->global_vars));
+ info->global_vars->alloc = info->vars.alloc;
+ info->global_vars->vars = ((struct ieee_var *)
+ xmalloc (info->vars.alloc
+ * sizeof (*info->vars.vars)));
+ memcpy (info->global_vars->vars, info->vars.vars,
+ info->vars.alloc * sizeof (*info->vars.vars));
+
+ /* We also copy out the non builtin parts of info->types, since
+ the types are discarded when we start a new block. */
+ info->global_types = ((struct ieee_types *)
+ xmalloc (sizeof *info->global_types));
+ info->global_types->alloc = info->types.alloc;
+ info->global_types->types = ((struct ieee_type *)
+ xmalloc (info->types.alloc
+ * sizeof (*info->types.types)));
+ memcpy (info->global_types->types, info->types.types,
+ info->types.alloc * sizeof (*info->types.types));
+ memset (info->global_types->builtins, 0,
+ sizeof (info->global_types->builtins));
+
+ break;
+
+ case 4:
+ case 6:
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ if (! info->blockstack.bsp->skip)
+ {
+ if (! debug_end_function (info->dhandle, offset + 1))
+ return false;
+ }
+ break;
+
+ case 0x86:
+ /* This is BE6 when BB6 started a block rather than a local
+ function. */
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ if (! debug_end_block (info->dhandle, offset + 1))
+ return false;
+ break;
+
+ case 5:
+ /* When we end a BB5, we look up the stack for the last BB5, if
+ there is one, so that we can call debug_start_source. */
+ if (info->blockstack.bsp > info->blockstack.stack)
+ {
+ struct ieee_block *bl;
+
+ bl = info->blockstack.bsp;
+ do
+ {
+ --bl;
+ if (bl->kind == 5)
+ {
+ if (! debug_start_source (info->dhandle, bl->filename))
+ return false;
+ break;
+ }
+ }
+ while (bl != info->blockstack.stack);
+ }
+ break;
+
+ case 11:
+ if (! ieee_read_expression (info, pp, &offset))
+ return false;
+ /* We just ignore the module size. FIXME. */
+ break;
+
+ default:
+ /* Other block types do not have any trailing information. */
+ break;
+ }
+
+ return true;
+}
+
+/* Parse an NN record. */
+
+static boolean
+parse_ieee_nn (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *nn_start;
+ bfd_vma varindx;
+ const char *name;
+ unsigned long namlen;
+
+ nn_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx)
+ || ! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (info, nn_start, _("illegal variable index"));
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= info->vars.alloc)
+ {
+ unsigned int alloc;
+
+ alloc = info->vars.alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ info->vars.vars = ((struct ieee_var *)
+ xrealloc (info->vars.vars,
+ alloc * sizeof *info->vars.vars));
+ memset (info->vars.vars + info->vars.alloc, 0,
+ (alloc - info->vars.alloc) * sizeof *info->vars.vars);
+ info->vars.alloc = alloc;
+ }
+
+ info->vars.vars[varindx].name = name;
+ info->vars.vars[varindx].namlen = namlen;
+
+ return true;
+}
+
+/* Parse a TY record. */
+
+static boolean
+parse_ieee_ty (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
+ bfd_vma typeindx, varindx, tc;
+ PTR dhandle;
+ boolean tag, typdef;
+ debug_type *arg_slots;
+ unsigned long type_bitsize;
+ debug_type type;
+
+ ty_start = *pp;
+
+ if (! ieee_read_number (info, pp, &typeindx))
+ return false;
+
+ if (typeindx < 256)
+ {
+ ieee_error (info, ty_start, _("illegal type index"));
+ return false;
+ }
+
+ typeindx -= 256;
+ if (! ieee_alloc_type (info, typeindx, false))
+ return false;
+
+ if (**pp != 0xce)
+ {
+ ieee_error (info, *pp, _("unknown TY code"));
+ return false;
+ }
+ ++*pp;
+
+ ty_var_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx))
+ return false;
+
+ if (varindx < 32)
+ {
+ ieee_error (info, ty_var_start, _("illegal variable index"));
+ return false;
+ }
+ varindx -= 32;
+
+ if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
+ {
+ ieee_error (info, ty_var_start, _("undefined variable in TY"));
+ return false;
+ }
+
+ ty_code_start = *pp;
+
+ if (! ieee_read_number (info, pp, &tc))
+ return false;
+
+ dhandle = info->dhandle;
+
+ tag = false;
+ typdef = false;
+ arg_slots = NULL;
+ type_bitsize = 0;
+ switch (tc)
+ {
+ default:
+ ieee_error (info, ty_code_start, _("unknown TY code"));
+ return false;
+
+ case '!':
+ /* Unknown type, with size. We treat it as int. FIXME. */
+ {
+ bfd_vma size;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+ type = debug_make_int_type (dhandle, size, false);
+ }
+ break;
+
+ case 'A': /* Array. */
+ case 'a': /* FORTRAN array in column/row order. FIXME: Not
+ distinguished from normal array. */
+ {
+ debug_type ele_type;
+ bfd_vma lower, upper;
+
+ if (! ieee_read_type_index (info, pp, &ele_type)
+ || ! ieee_read_number (info, pp, &lower)
+ || ! ieee_read_number (info, pp, &upper))
+ return false;
+ type = debug_make_array_type (dhandle, ele_type,
+ ieee_builtin_type (info, ty_code_start,
+ ((unsigned int)
+ builtin_int)),
+ (bfd_signed_vma) lower,
+ (bfd_signed_vma) upper,
+ false);
+ }
+ break;
+
+ case 'E':
+ /* Simple enumeration. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ const char **names;
+ unsigned int c;
+ bfd_signed_vma *vals;
+ unsigned int i;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+ /* FIXME: we ignore the enumeration size. */
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ memset (names, 0, alloc * sizeof *names);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ }
+
+ names[c] = savestring (name, namlen);
+ if (names[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ names[c] = NULL;
+
+ vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
+ for (i = 0; i < c; i++)
+ vals[i] = i;
+
+ type = debug_make_enum_type (dhandle, names, vals);
+ tag = true;
+ }
+ break;
+
+ case 'G':
+ /* Struct with bit fields. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ debug_field *fields;
+ unsigned int c;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ debug_type ftype;
+ bfd_vma bitpos, bitsize;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_type_index (info, pp, &ftype)
+ || ! ieee_read_number (info, pp, &bitpos)
+ || ! ieee_read_number (info, pp, &bitsize))
+ return false;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[c] = debug_make_field (dhandle, savestring (name, namlen),
+ ftype, bitpos, bitsize,
+ DEBUG_VISIBILITY_PUBLIC);
+ if (fields[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ fields[c] = NULL;
+
+ type = debug_make_struct_type (dhandle, true, size, fields);
+ tag = true;
+ }
+ break;
+
+ case 'N':
+ /* Enumeration. */
+ {
+ unsigned int alloc;
+ const char **names;
+ bfd_signed_vma *vals;
+ unsigned int c;
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ bfd_vma val;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (info, pp, &val))
+ return false;
+
+ /* If the length of the name is zero, then the value is
+ actually the size of the enum. We ignore this
+ information. FIXME. */
+ if (namlen == 0)
+ continue;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ vals = ((bfd_signed_vma *)
+ xrealloc (vals, alloc * sizeof *vals));
+ }
+
+ names[c] = savestring (name, namlen);
+ if (names[c] == NULL)
+ return false;
+ vals[c] = (bfd_signed_vma) val;
+ ++c;
+ }
+
+ names[c] = NULL;
+
+ type = debug_make_enum_type (dhandle, names, vals);
+ tag = true;
+ }
+ break;
+
+ case 'O': /* Small pointer. We don't distinguish small and large
+ pointers. FIXME. */
+ case 'P': /* Large pointer. */
+ {
+ debug_type t;
+
+ if (! ieee_read_type_index (info, pp, &t))
+ return false;
+ type = debug_make_pointer_type (dhandle, t);
+ }
+ break;
+
+ case 'R':
+ /* Range. */
+ {
+ bfd_vma low, high, signedp, size;
+
+ if (! ieee_read_number (info, pp, &low)
+ || ! ieee_read_number (info, pp, &high)
+ || ! ieee_read_number (info, pp, &signedp)
+ || ! ieee_read_number (info, pp, &size))
+ return false;
+
+ type = debug_make_range_type (dhandle,
+ debug_make_int_type (dhandle, size,
+ ! signedp),
+ (bfd_signed_vma) low,
+ (bfd_signed_vma) high);
+ }
+ break;
+
+ case 'S': /* Struct. */
+ case 'U': /* Union. */
+ {
+ bfd_vma size;
+ unsigned int alloc;
+ debug_field *fields;
+ unsigned int c;
+
+ if (! ieee_read_number (info, pp, &size))
+ return false;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ c = 0;
+ while (1)
+ {
+ const char *name;
+ unsigned long namlen;
+ boolean present;
+ bfd_vma tindx;
+ bfd_vma offset;
+ debug_type ftype;
+ bfd_vma bitsize;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ if (! present)
+ break;
+ if (! ieee_read_number (info, pp, &tindx)
+ || ! ieee_read_number (info, pp, &offset))
+ return false;
+
+ if (tindx < 256)
+ {
+ ftype = ieee_builtin_type (info, ty_code_start, tindx);
+ bitsize = 0;
+ offset *= 8;
+ }
+ else
+ {
+ struct ieee_type *t;
+
+ tindx -= 256;
+ if (! ieee_alloc_type (info, tindx, true))
+ return false;
+ t = info->types.types + tindx;
+ ftype = t->type;
+ bitsize = t->bitsize;
+ if (bitsize == 0)
+ offset *= 8;
+ }
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[c] = debug_make_field (dhandle, savestring (name, namlen),
+ ftype, offset, bitsize,
+ DEBUG_VISIBILITY_PUBLIC);
+ if (fields[c] == NULL)
+ return false;
+ ++c;
+ }
+
+ fields[c] = NULL;
+
+ type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
+ tag = true;
+ }
+ break;
+
+ case 'T':
+ /* Typedef. */
+ if (! ieee_read_type_index (info, pp, &type))
+ return false;
+ typdef = true;
+ break;
+
+ case 'X':
+ /* Procedure. FIXME: This is an extern declaration, which we
+ have no way of representing. */
+ {
+ bfd_vma attr;
+ debug_type rtype;
+ bfd_vma nargs;
+ boolean present;
+ struct ieee_var *pv;
+
+ /* FIXME: We ignore the attribute and the argument names. */
+
+ if (! ieee_read_number (info, pp, &attr)
+ || ! ieee_read_type_index (info, pp, &rtype)
+ || ! ieee_read_number (info, pp, &nargs))
+ return false;
+ do
+ {
+ const char *name;
+ unsigned long namlen;
+
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ }
+ while (present);
+
+ pv = info->vars.vars + varindx;
+ pv->kind = IEEE_EXTERNAL;
+ if (pv->namlen > 0
+ && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
+ {
+ /* Set up the return type as an indirect type pointing to
+ the variable slot, so that we can change it to a
+ reference later if appropriate. */
+ pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
+ *pv->pslot = rtype;
+ rtype = debug_make_indirect_type (dhandle, pv->pslot,
+ (const char *) NULL);
+ }
+
+ type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
+ false);
+ }
+ break;
+
+ case 'V':
+ /* Void. This is not documented, but the MRI compiler emits it. */
+ type = debug_make_void_type (dhandle);
+ break;
+
+ case 'Z':
+ /* Array with 0 lower bound. */
+ {
+ debug_type etype;
+ bfd_vma high;
+
+ if (! ieee_read_type_index (info, pp, &etype)
+ || ! ieee_read_number (info, pp, &high))
+ return false;
+
+ type = debug_make_array_type (dhandle, etype,
+ ieee_builtin_type (info, ty_code_start,
+ ((unsigned int)
+ builtin_int)),
+ 0, (bfd_signed_vma) high, false);
+ }
+ break;
+
+ case 'c': /* Complex. */
+ case 'd': /* Double complex. */
+ {
+ const char *name;
+ unsigned long namlen;
+
+ /* FIXME: I don't know what the name means. */
+
+ if (! ieee_read_id (info, pp, &name, &namlen))
+ return false;
+
+ type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
+ }
+ break;
+
+ case 'f':
+ /* Pascal file name. FIXME. */
+ ieee_error (info, ty_code_start, _("Pascal file name not supported"));
+ return false;
+
+ case 'g':
+ /* Bitfield type. */
+ {
+ bfd_vma signedp, bitsize, dummy;
+ const bfd_byte *hold;
+ boolean present;
+
+ if (! ieee_read_number (info, pp, &signedp)
+ || ! ieee_read_number (info, pp, &bitsize))
+ return false;
+
+ /* I think the documentation says that there is a type index,
+ but some actual files do not have one. */
+ hold = *pp;
+ if (! ieee_read_optional_number (info, pp, &dummy, &present))
+ return false;
+ if (! present)
+ {
+ /* FIXME: This is just a guess. */
+ type = debug_make_int_type (dhandle, 4,
+ signedp ? false : true);
+ }
+ else
+ {
+ *pp = hold;
+ if (! ieee_read_type_index (info, pp, &type))
+ return false;
+ }
+ type_bitsize = bitsize;
+ }
+ break;
+
+ case 'n':
+ /* Qualifier. */
+ {
+ bfd_vma kind;
+ debug_type t;
+
+ if (! ieee_read_number (info, pp, &kind)
+ || ! ieee_read_type_index (info, pp, &t))
+ return false;
+
+ switch (kind)
+ {
+ default:
+ ieee_error (info, ty_start, _("unsupported qualifer"));
+ return false;
+
+ case 1:
+ type = debug_make_const_type (dhandle, t);
+ break;
+
+ case 2:
+ type = debug_make_volatile_type (dhandle, t);
+ break;
+ }
+ }
+ break;
+
+ case 's':
+ /* Set. */
+ {
+ bfd_vma size;
+ debug_type etype;
+
+ if (! ieee_read_number (info, pp, &size)
+ || ! ieee_read_type_index (info, pp, &etype))
+ return false;
+
+ /* FIXME: We ignore the size. */
+
+ type = debug_make_set_type (dhandle, etype, false);
+ }
+ break;
+
+ case 'x':
+ /* Procedure with compiler dependencies. */
+ {
+ struct ieee_var *pv;
+ bfd_vma attr, frame_type, push_mask, nargs, level, father;
+ debug_type rtype;
+ debug_type *arg_types;
+ boolean varargs;
+ boolean present;
+
+ /* FIXME: We ignore some of this information. */
+
+ pv = info->vars.vars + varindx;
+
+ if (! ieee_read_number (info, pp, &attr)
+ || ! ieee_read_number (info, pp, &frame_type)
+ || ! ieee_read_number (info, pp, &push_mask)
+ || ! ieee_read_type_index (info, pp, &rtype)
+ || ! ieee_read_number (info, pp, &nargs))
+ return false;
+ if (nargs == (bfd_vma) -1)
+ {
+ arg_types = NULL;
+ varargs = false;
+ }
+ else
+ {
+ unsigned int i;
+
+ arg_types = ((debug_type *)
+ xmalloc ((nargs + 1) * sizeof *arg_types));
+ for (i = 0; i < nargs; i++)
+ if (! ieee_read_type_index (info, pp, arg_types + i))
+ return false;
+
+ /* If the last type is pointer to void, this is really a
+ varargs function. */
+ varargs = false;
+ if (nargs > 0)
+ {
+ debug_type last;
+
+ last = arg_types[nargs - 1];
+ if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
+ && (debug_get_type_kind (dhandle,
+ debug_get_target_type (dhandle,
+ last))
+ == DEBUG_KIND_VOID))
+ {
+ --nargs;
+ varargs = true;
+ }
+ }
+
+ /* If there are any pointer arguments, turn them into
+ indirect types in case we later need to convert them to
+ reference types. */
+ for (i = 0; i < nargs; i++)
+ {
+ if (debug_get_type_kind (dhandle, arg_types[i])
+ == DEBUG_KIND_POINTER)
+ {
+ if (arg_slots == NULL)
+ {
+ arg_slots = ((debug_type *)
+ xmalloc (nargs * sizeof *arg_slots));
+ memset (arg_slots, 0, nargs * sizeof *arg_slots);
+ }
+ arg_slots[i] = arg_types[i];
+ arg_types[i] =
+ debug_make_indirect_type (dhandle,
+ arg_slots + i,
+ (const char *) NULL);
+ }
+ }
+
+ arg_types[nargs] = DEBUG_TYPE_NULL;
+ }
+ if (! ieee_read_number (info, pp, &level)
+ || ! ieee_read_optional_number (info, pp, &father, &present))
+ return false;
+
+ /* We can't distinguish between a global function and a static
+ function. */
+ pv->kind = IEEE_FUNCTION;
+
+ if (pv->namlen > 0
+ && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
+ {
+ /* Set up the return type as an indirect type pointing to
+ the variable slot, so that we can change it to a
+ reference later if appropriate. */
+ pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
+ *pv->pslot = rtype;
+ rtype = debug_make_indirect_type (dhandle, pv->pslot,
+ (const char *) NULL);
+ }
+
+ type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
+ }
+ break;
+ }
+
+ /* Record the type in the table. */
+
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ info->vars.vars[varindx].type = type;
+
+ if ((tag || typdef)
+ && info->vars.vars[varindx].namlen > 0)
+ {
+ const char *name;
+
+ name = savestring (info->vars.vars[varindx].name,
+ info->vars.vars[varindx].namlen);
+ if (typdef)
+ type = debug_name_type (dhandle, name, type);
+ else if (tc == 'E' || tc == 'N')
+ type = debug_tag_type (dhandle, name, type);
+ else
+ {
+ struct ieee_tag *it;
+
+ /* We must allocate all struct tags as indirect types, so
+ that if we later see a definition of the tag as a C++
+ record we can update the indirect slot and automatically
+ change all the existing references. */
+ it = (struct ieee_tag *) xmalloc (sizeof *it);
+ memset (it, 0, sizeof *it);
+ it->next = info->tags;
+ info->tags = it;
+ it->name = name;
+ it->slot = type;
+
+ type = debug_make_indirect_type (dhandle, &it->slot, name);
+ type = debug_tag_type (dhandle, name, type);
+
+ it->type = type;
+ }
+ if (type == NULL)
+ return false;
+ }
+
+ info->types.types[typeindx].type = type;
+ info->types.types[typeindx].arg_slots = arg_slots;
+ info->types.types[typeindx].bitsize = type_bitsize;
+
+ /* We may have already allocated type as an indirect type pointing
+ to slot. It does no harm to replace the indirect type with the
+ real type. Filling in slot as well handles the indirect types
+ which are already hanging around. */
+ if (info->types.types[typeindx].pslot != NULL)
+ *info->types.types[typeindx].pslot = type;
+
+ return true;
+}
+
+/* Parse an ATN record. */
+
+static boolean
+parse_ieee_atn (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *atn_start, *atn_code_start;
+ bfd_vma varindx;
+ struct ieee_var *pvar;
+ debug_type type;
+ bfd_vma atn_code;
+ PTR dhandle;
+ bfd_vma v, v2, v3, v4, v5;
+ const char *name;
+ unsigned long namlen;
+ char *namcopy;
+ boolean present;
+ int blocktype;
+
+ atn_start = *pp;
+
+ if (! ieee_read_number (info, pp, &varindx)
+ || ! ieee_read_type_index (info, pp, &type))
+ return false;
+
+ atn_code_start = *pp;
+
+ if (! ieee_read_number (info, pp, &atn_code))
+ return false;
+
+ if (varindx == 0)
+ {
+ pvar = NULL;
+ name = "";
+ namlen = 0;
+ }
+ else if (varindx < 32)
+ {
+ /* The MRI compiler reportedly sometimes emits variable lifetime
+ information for a register. We just ignore it. */
+ if (atn_code == 9)
+ return ieee_read_number (info, pp, &v);
+
+ ieee_error (info, atn_start, _("illegal variable index"));
+ return false;
+ }
+ else
+ {
+ varindx -= 32;
+ if (varindx >= info->vars.alloc
+ || info->vars.vars[varindx].name == NULL)
+ {
+ /* The MRI compiler or linker sometimes omits the NN record
+ for a pmisc record. */
+ if (atn_code == 62)
+ {
+ if (varindx >= info->vars.alloc)
+ {
+ unsigned int alloc;
+
+ alloc = info->vars.alloc;
+ if (alloc == 0)
+ alloc = 4;
+ while (varindx >= alloc)
+ alloc *= 2;
+ info->vars.vars = ((struct ieee_var *)
+ xrealloc (info->vars.vars,
+ (alloc
+ * sizeof *info->vars.vars)));
+ memset (info->vars.vars + info->vars.alloc, 0,
+ ((alloc - info->vars.alloc)
+ * sizeof *info->vars.vars));
+ info->vars.alloc = alloc;
+ }
+
+ pvar = info->vars.vars + varindx;
+ pvar->name = "";
+ pvar->namlen = 0;
+ }
+ else
+ {
+ ieee_error (info, atn_start, _("undefined variable in ATN"));
+ return false;
+ }
+ }
+
+ pvar = info->vars.vars + varindx;
+
+ pvar->type = type;
+
+ name = pvar->name;
+ namlen = pvar->namlen;
+ }
+
+ dhandle = info->dhandle;
+
+ /* If we are going to call debug_record_variable with a pointer
+ type, change the type to an indirect type so that we can later
+ change it to a reference type if we encounter a C++ pmisc 'R'
+ record. */
+ if (pvar != NULL
+ && type != DEBUG_TYPE_NULL
+ && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER)
+ {
+ switch (atn_code)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 8:
+ case 10:
+ pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot);
+ *pvar->pslot = type;
+ type = debug_make_indirect_type (dhandle, pvar->pslot,
+ (const char *) NULL);
+ pvar->type = type;
+ break;
+ }
+ }
+
+ switch (atn_code)
+ {
+ default:
+ ieee_error (info, atn_code_start, _("unknown ATN type"));
+ return false;
+
+ case 1:
+ /* Automatic variable. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
+
+ case 2:
+ /* Register variable. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
+ ieee_regno_to_genreg (info->abfd, v));
+
+ case 3:
+ /* Static variable. */
+ if (! ieee_require_asn (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (info->blockstack.bsp <= info->blockstack.stack)
+ blocktype = 0;
+ else
+ blocktype = info->blockstack.bsp[-1].kind;
+ if (pvar != NULL)
+ {
+ if (blocktype == 4 || blocktype == 6)
+ pvar->kind = IEEE_LOCAL;
+ else
+ pvar->kind = IEEE_STATIC;
+ }
+ return debug_record_variable (dhandle, namcopy, type,
+ (blocktype == 4 || blocktype == 6
+ ? DEBUG_LOCAL_STATIC
+ : DEBUG_STATIC),
+ v);
+
+ case 4:
+ /* External function. We don't currently record these. FIXME. */
+ if (pvar != NULL)
+ pvar->kind = IEEE_EXTERNAL;
+ return true;
+
+ case 5:
+ /* External variable. We don't currently record these. FIXME. */
+ if (pvar != NULL)
+ pvar->kind = IEEE_EXTERNAL;
+ return true;
+
+ case 7:
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_number (info, pp, &v3, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v4, &present))
+ return false;
+ }
+
+ /* We just ignore the two optional fields in v3 and v4, since
+ they are not defined. */
+
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+
+ /* We have no way to record the column number. FIXME. */
+
+ return debug_record_line (dhandle, v, v3);
+
+ case 8:
+ /* Global variable. */
+ if (! ieee_require_asn (info, pp, &v))
+ return false;
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_GLOBAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
+
+ case 9:
+ /* Variable lifetime information. */
+ if (! ieee_read_number (info, pp, &v))
+ return false;
+
+ /* We have no way to record this information. FIXME. */
+ return true;
+
+ case 10:
+ /* Locked register. The spec says that there are two required
+ fields, but at least on occasion the MRI compiler only emits
+ one. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+
+ /* I think this means a variable that is both in a register and
+ a frame slot. We ignore the frame slot. FIXME. */
+
+ namcopy = savestring (name, namlen);
+ if (type == NULL)
+ type = debug_make_void_type (dhandle);
+ if (pvar != NULL)
+ pvar->kind = IEEE_LOCAL;
+ return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v);
+
+ case 11:
+ /* Reserved for FORTRAN common. */
+ ieee_error (info, atn_code_start, _("unsupported ATN11"));
+
+ /* Return true to keep going. */
+ return true;
+
+ case 12:
+ /* Based variable. */
+ v3 = 0;
+ v4 = 0x80;
+ v5 = 0;
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_number (info, pp, &v3, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v4, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v5, &present))
+ return false;
+ }
+ }
+
+ /* We have no way to record this information. FIXME. */
+
+ ieee_error (info, atn_code_start, _("unsupported ATN12"));
+
+ /* Return true to keep going. */
+ return true;
+
+ case 16:
+ /* Constant. The description of this that I have is ambiguous,
+ so I'm not going to try to implement it. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_number (info, pp, &v2, &present))
+ return false;
+ if (present)
+ {
+ if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+ }
+ }
+
+ if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum)
+ {
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+ }
+
+ return true;
+
+ case 19:
+ /* Static variable from assembler. */
+ v2 = 0;
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_optional_number (info, pp, &v2, &present)
+ || ! ieee_require_asn (info, pp, &v3))
+ return false;
+ namcopy = savestring (name, namlen);
+ /* We don't really handle this correctly. FIXME. */
+ return debug_record_variable (dhandle, namcopy,
+ debug_make_void_type (dhandle),
+ v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC,
+ v3);
+
+ case 62:
+ /* Procedure miscellaneous information. */
+ case 63:
+ /* Variable miscellaneous information. */
+ case 64:
+ /* Module miscellaneous information. */
+ if (! ieee_read_number (info, pp, &v)
+ || ! ieee_read_number (info, pp, &v2)
+ || ! ieee_read_optional_id (info, pp, &name, &namlen, &present))
+ return false;
+
+ if (atn_code == 62 && v == 80)
+ {
+ if (present)
+ {
+ ieee_error (info, atn_code_start,
+ _("unexpected string in C++ misc"));
+ return false;
+ }
+ return ieee_read_cxx_misc (info, pp, v2);
+ }
+
+ /* We just ignore all of this stuff. FIXME. */
+
+ for (; v2 > 0; --v2)
+ {
+ switch ((ieee_record_enum_type) **pp)
+ {
+ default:
+ ieee_error (info, *pp, _("bad misc record"));
+ return false;
+
+ case ieee_at_record_enum:
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+ break;
+
+ case ieee_e2_first_byte_enum:
+ if (! ieee_require_asn (info, pp, &v3))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ /*NOTREACHED*/
+}
+
+/* Handle C++ debugging miscellaneous records. This is called for
+ procedure miscellaneous records of type 80. */
+
+static boolean
+ieee_read_cxx_misc (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ bfd_vma category;
+
+ start = *pp;
+
+ /* Get the category of C++ misc record. */
+ if (! ieee_require_asn (info, pp, &category))
+ return false;
+ --count;
+
+ switch (category)
+ {
+ default:
+ ieee_error (info, start, _("unrecognized C++ misc record"));
+ return false;
+
+ case 'T':
+ if (! ieee_read_cxx_class (info, pp, count))
+ return false;
+ break;
+
+ case 'M':
+ {
+ bfd_vma flags;
+ const char *name;
+ unsigned long namlen;
+
+ /* The IEEE spec indicates that the 'M' record only has a
+ flags field. The MRI compiler also emits the name of the
+ function. */
+
+ if (! ieee_require_asn (info, pp, &flags))
+ return false;
+ if (*pp < info->pend
+ && (ieee_record_enum_type) **pp == ieee_at_record_enum)
+ {
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+ }
+
+ /* This is emitted for method functions, but I don't think we
+ care very much. It might help if it told us useful
+ information like the class with which this function is
+ associated, but it doesn't, so it isn't helpful. */
+ }
+ break;
+
+ case 'B':
+ if (! ieee_read_cxx_defaults (info, pp, count))
+ return false;
+ break;
+
+ case 'z':
+ {
+ const char *name, *mangled, *class;
+ unsigned long namlen, mangledlen, classlen;
+ bfd_vma control;
+
+ /* Pointer to member. */
+
+ if (! ieee_require_atn65 (info, pp, &name, &namlen)
+ || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)
+ || ! ieee_require_atn65 (info, pp, &class, &classlen)
+ || ! ieee_require_asn (info, pp, &control))
+ return false;
+
+ /* FIXME: We should now track down name and change its type. */
+ }
+ break;
+
+ case 'R':
+ if (! ieee_read_reference (info, pp))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/* Read a C++ class definition. This is a pmisc type 80 record of
+ category 'T'. */
+
+static boolean
+ieee_read_cxx_class (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ bfd_vma class;
+ const char *tag;
+ unsigned long taglen;
+ struct ieee_tag *it;
+ PTR dhandle;
+ debug_field *fields;
+ unsigned int field_count, field_alloc;
+ debug_baseclass *baseclasses;
+ unsigned int baseclasses_count, baseclasses_alloc;
+ const debug_field *structfields;
+ struct ieee_method
+ {
+ const char *name;
+ unsigned long namlen;
+ debug_method_variant *variants;
+ unsigned count;
+ unsigned int alloc;
+ } *methods;
+ unsigned int methods_count, methods_alloc;
+ debug_type vptrbase;
+ boolean ownvptr;
+ debug_method *dmethods;
+
+ start = *pp;
+
+ if (! ieee_require_asn (info, pp, &class))
+ return false;
+ --count;
+
+ if (! ieee_require_atn65 (info, pp, &tag, &taglen))
+ return false;
+ --count;
+
+ /* Find the C struct with this name. */
+ for (it = info->tags; it != NULL; it = it->next)
+ if (it->name[0] == tag[0]
+ && strncmp (it->name, tag, taglen) == 0
+ && strlen (it->name) == taglen)
+ break;
+ if (it == NULL)
+ {
+ ieee_error (info, start, _("undefined C++ object"));
+ return false;
+ }
+
+ dhandle = info->dhandle;
+
+ fields = NULL;
+ field_count = 0;
+ field_alloc = 0;
+ baseclasses = NULL;
+ baseclasses_count = 0;
+ baseclasses_alloc = 0;
+ methods = NULL;
+ methods_count = 0;
+ methods_alloc = 0;
+ vptrbase = DEBUG_TYPE_NULL;
+ ownvptr = false;
+
+ structfields = debug_get_fields (dhandle, it->type);
+
+ while (count > 0)
+ {
+ bfd_vma id;
+ const bfd_byte *spec_start;
+
+ spec_start = *pp;
+
+ if (! ieee_require_asn (info, pp, &id))
+ return false;
+ --count;
+
+ switch (id)
+ {
+ default:
+ ieee_error (info, spec_start, _("unrecognized C++ object spec"));
+ return false;
+
+ case 'b':
+ {
+ bfd_vma flags, cinline;
+ const char *basename, *fieldname;
+ unsigned long baselen, fieldlen;
+ char *basecopy;
+ debug_type basetype;
+ bfd_vma bitpos;
+ boolean virtualp;
+ enum debug_visibility visibility;
+ debug_baseclass baseclass;
+
+ /* This represents a base or friend class. */
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &basename, &baselen)
+ || ! ieee_require_asn (info, pp, &cinline)
+ || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))
+ return false;
+ count -= 4;
+
+ /* We have no way of recording friend information, so we
+ just ignore it. */
+ if ((flags & BASEFLAGS_FRIEND) != 0)
+ break;
+
+ /* I assume that either all of the members of the
+ baseclass are included in the object, starting at the
+ beginning of the object, or that none of them are
+ included. */
+
+ if ((fieldlen == 0) == (cinline == 0))
+ {
+ ieee_error (info, start, _("unsupported C++ object type"));
+ return false;
+ }
+
+ basecopy = savestring (basename, baselen);
+ basetype = debug_find_tagged_type (dhandle, basecopy,
+ DEBUG_KIND_ILLEGAL);
+ free (basecopy);
+ if (basetype == DEBUG_TYPE_NULL)
+ {
+ ieee_error (info, start, _("C++ base class not defined"));
+ return false;
+ }
+
+ if (fieldlen == 0)
+ bitpos = 0;
+ else
+ {
+ const debug_field *pf;
+
+ if (structfields == NULL)
+ {
+ ieee_error (info, start, _("C++ object has no fields"));
+ return false;
+ }
+
+ for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (fname[0] == fieldname[0]
+ && strncmp (fname, fieldname, fieldlen) == 0
+ && strlen (fname) == fieldlen)
+ break;
+ }
+ if (*pf == DEBUG_FIELD_NULL)
+ {
+ ieee_error (info, start,
+ _("C++ base class not found in container"));
+ return false;
+ }
+
+ bitpos = debug_get_field_bitpos (dhandle, *pf);
+ }
+
+ if ((flags & BASEFLAGS_VIRTUAL) != 0)
+ virtualp = true;
+ else
+ virtualp = false;
+ if ((flags & BASEFLAGS_PRIVATE) != 0)
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ else
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+
+ baseclass = debug_make_baseclass (dhandle, basetype, bitpos,
+ virtualp, visibility);
+ if (baseclass == DEBUG_BASECLASS_NULL)
+ return false;
+
+ if (baseclasses_count + 1 >= baseclasses_alloc)
+ {
+ baseclasses_alloc += 10;
+ baseclasses = ((debug_baseclass *)
+ xrealloc (baseclasses,
+ (baseclasses_alloc
+ * sizeof *baseclasses)));
+ }
+
+ baseclasses[baseclasses_count] = baseclass;
+ ++baseclasses_count;
+ baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;
+ }
+ break;
+
+ case 'd':
+ {
+ bfd_vma flags;
+ const char *fieldname, *mangledname;
+ unsigned long fieldlen, mangledlen;
+ char *fieldcopy;
+ boolean staticp;
+ debug_type ftype;
+ const debug_field *pf = NULL;
+ enum debug_visibility visibility;
+ debug_field field;
+
+ /* This represents a data member. */
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)
+ || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))
+ return false;
+ count -= 3;
+
+ fieldcopy = savestring (fieldname, fieldlen);
+
+ staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false;
+
+ if (staticp)
+ {
+ struct ieee_var *pv, *pvend;
+
+ /* See if we can find a definition for this variable. */
+ pv = info->vars.vars;
+ pvend = pv + info->vars.alloc;
+ for (; pv < pvend; pv++)
+ if (pv->namlen == mangledlen
+ && strncmp (pv->name, mangledname, mangledlen) == 0)
+ break;
+ if (pv < pvend)
+ ftype = pv->type;
+ else
+ {
+ /* This can happen if the variable is never used. */
+ ftype = ieee_builtin_type (info, start,
+ (unsigned int) builtin_void);
+ }
+ }
+ else
+ {
+ unsigned int findx;
+
+ if (structfields == NULL)
+ {
+ ieee_error (info, start, _("C++ object has no fields"));
+ return false;
+ }
+
+ for (pf = structfields, findx = 0;
+ *pf != DEBUG_FIELD_NULL;
+ pf++, findx++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (fname[0] == mangledname[0]
+ && strncmp (fname, mangledname, mangledlen) == 0
+ && strlen (fname) == mangledlen)
+ break;
+ }
+ if (*pf == DEBUG_FIELD_NULL)
+ {
+ ieee_error (info, start,
+ _("C++ data member not found in container"));
+ return false;
+ }
+
+ ftype = debug_get_field_type (dhandle, *pf);
+
+ if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)
+ {
+ /* We might need to convert this field into a
+ reference type later on, so make it an indirect
+ type. */
+ if (it->fslots == NULL)
+ {
+ unsigned int fcnt;
+ const debug_field *pfcnt;
+
+ fcnt = 0;
+ for (pfcnt = structfields;
+ *pfcnt != DEBUG_FIELD_NULL;
+ pfcnt++)
+ ++fcnt;
+ it->fslots = ((debug_type *)
+ xmalloc (fcnt * sizeof *it->fslots));
+ memset (it->fslots, 0,
+ fcnt * sizeof *it->fslots);
+ }
+
+ if (ftype == DEBUG_TYPE_NULL)
+ return false;
+ it->fslots[findx] = ftype;
+ ftype = debug_make_indirect_type (dhandle,
+ it->fslots + findx,
+ (const char *) NULL);
+ }
+ }
+ if (ftype == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (flags & CXXFLAGS_VISIBILITY)
+ {
+ default:
+ ieee_error (info, start, _("unknown C++ visibility"));
+ return false;
+
+ case CXXFLAGS_VISIBILITY_PUBLIC:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PRIVATE:
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PROTECTED:
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ }
+
+ if (staticp)
+ {
+ char *mangledcopy;
+
+ mangledcopy = savestring (mangledname, mangledlen);
+
+ field = debug_make_static_member (dhandle, fieldcopy,
+ ftype, mangledcopy,
+ visibility);
+ }
+ else
+ {
+ bfd_vma bitpos, bitsize;
+
+ bitpos = debug_get_field_bitpos (dhandle, *pf);
+ bitsize = debug_get_field_bitsize (dhandle, *pf);
+ if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
+ {
+ ieee_error (info, start, _("bad C++ field bit pos or size"));
+ return false;
+ }
+ field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
+ bitsize, visibility);
+ }
+
+ if (field == DEBUG_FIELD_NULL)
+ return false;
+
+ if (field_count + 1 >= field_alloc)
+ {
+ field_alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, field_alloc * sizeof *fields));
+ }
+
+ fields[field_count] = field;
+ ++field_count;
+ fields[field_count] = DEBUG_FIELD_NULL;
+ }
+ break;
+
+ case 'm':
+ case 'v':
+ {
+ bfd_vma flags, voffset, control;
+ const char *name, *mangled;
+ unsigned long namlen, mangledlen;
+ struct ieee_var *pv, *pvend;
+ debug_type type;
+ enum debug_visibility visibility;
+ boolean constp, volatilep;
+ char *mangledcopy;
+ debug_method_variant mv;
+ struct ieee_method *meth;
+ unsigned int im;
+
+ if (! ieee_require_asn (info, pp, &flags)
+ || ! ieee_require_atn65 (info, pp, &name, &namlen)
+ || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
+ return false;
+ count -= 3;
+ if (id != 'v')
+ voffset = 0;
+ else
+ {
+ if (! ieee_require_asn (info, pp, &voffset))
+ return false;
+ --count;
+ }
+ if (! ieee_require_asn (info, pp, &control))
+ return false;
+ --count;
+
+ /* We just ignore the control information. */
+
+ /* We have no way to represent friend information, so we
+ just ignore it. */
+ if ((flags & CXXFLAGS_FRIEND) != 0)
+ break;
+
+ /* We should already have seen a type for the function. */
+ pv = info->vars.vars;
+ pvend = pv + info->vars.alloc;
+ for (; pv < pvend; pv++)
+ if (pv->namlen == mangledlen
+ && strncmp (pv->name, mangled, mangledlen) == 0)
+ break;
+
+ if (pv >= pvend)
+ {
+ /* We won't have type information for this function if
+ it is not included in this file. We don't try to
+ handle this case. FIXME. */
+ type = (debug_make_function_type
+ (dhandle,
+ ieee_builtin_type (info, start,
+ (unsigned int) builtin_void),
+ (debug_type *) NULL,
+ false));
+ }
+ else
+ {
+ debug_type return_type;
+ const debug_type *arg_types;
+ boolean varargs;
+
+ if (debug_get_type_kind (dhandle, pv->type)
+ != DEBUG_KIND_FUNCTION)
+ {
+ ieee_error (info, start,
+ _("bad type for C++ method function"));
+ return false;
+ }
+
+ return_type = debug_get_return_type (dhandle, pv->type);
+ arg_types = debug_get_parameter_types (dhandle, pv->type,
+ &varargs);
+ if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
+ {
+ ieee_error (info, start,
+ _("no type information for C++ method function"));
+ return false;
+ }
+
+ type = debug_make_method_type (dhandle, return_type, it->type,
+ (debug_type *) arg_types,
+ varargs);
+ }
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (flags & CXXFLAGS_VISIBILITY)
+ {
+ default:
+ ieee_error (info, start, _("unknown C++ visibility"));
+ return false;
+
+ case CXXFLAGS_VISIBILITY_PUBLIC:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PRIVATE:
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+
+ case CXXFLAGS_VISIBILITY_PROTECTED:
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ }
+
+ constp = (flags & CXXFLAGS_CONST) != 0 ? true : false;
+ volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false;
+
+ mangledcopy = savestring (mangled, mangledlen);
+
+ if ((flags & CXXFLAGS_STATIC) != 0)
+ {
+ if (id == 'v')
+ {
+ ieee_error (info, start, _("C++ static virtual method"));
+ return false;
+ }
+ mv = debug_make_static_method_variant (dhandle, mangledcopy,
+ type, visibility,
+ constp, volatilep);
+ }
+ else
+ {
+ debug_type vcontext;
+
+ if (id != 'v')
+ vcontext = DEBUG_TYPE_NULL;
+ else
+ {
+ /* FIXME: How can we calculate this correctly? */
+ vcontext = it->type;
+ }
+ mv = debug_make_method_variant (dhandle, mangledcopy, type,
+ visibility, constp,
+ volatilep, voffset,
+ vcontext);
+ }
+ if (mv == DEBUG_METHOD_VARIANT_NULL)
+ return false;
+
+ for (meth = methods, im = 0; im < methods_count; meth++, im++)
+ if (meth->namlen == namlen
+ && strncmp (meth->name, name, namlen) == 0)
+ break;
+ if (im >= methods_count)
+ {
+ if (methods_count >= methods_alloc)
+ {
+ methods_alloc += 10;
+ methods = ((struct ieee_method *)
+ xrealloc (methods,
+ methods_alloc * sizeof *methods));
+ }
+ methods[methods_count].name = name;
+ methods[methods_count].namlen = namlen;
+ methods[methods_count].variants = NULL;
+ methods[methods_count].count = 0;
+ methods[methods_count].alloc = 0;
+ meth = methods + methods_count;
+ ++methods_count;
+ }
+
+ if (meth->count + 1 >= meth->alloc)
+ {
+ meth->alloc += 10;
+ meth->variants = ((debug_method_variant *)
+ xrealloc (meth->variants,
+ (meth->alloc
+ * sizeof *meth->variants)));
+ }
+
+ meth->variants[meth->count] = mv;
+ ++meth->count;
+ meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;
+ }
+ break;
+
+ case 'o':
+ {
+ bfd_vma spec;
+
+ /* We have no way to store this information, so we just
+ ignore it. */
+ if (! ieee_require_asn (info, pp, &spec))
+ return false;
+ --count;
+ if ((spec & 4) != 0)
+ {
+ const char *filename;
+ unsigned long filenamlen;
+ bfd_vma lineno;
+
+ if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)
+ || ! ieee_require_asn (info, pp, &lineno))
+ return false;
+ count -= 2;
+ }
+ else if ((spec & 8) != 0)
+ {
+ const char *mangled;
+ unsigned long mangledlen;
+
+ if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
+ return false;
+ --count;
+ }
+ else
+ {
+ ieee_error (info, start,
+ _("unrecognized C++ object overhead spec"));
+ return false;
+ }
+ }
+ break;
+
+ case 'z':
+ {
+ const char *vname, *basename;
+ unsigned long vnamelen, baselen;
+ bfd_vma vsize, control;
+
+ /* A virtual table pointer. */
+
+ if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)
+ || ! ieee_require_asn (info, pp, &vsize)
+ || ! ieee_require_atn65 (info, pp, &basename, &baselen)
+ || ! ieee_require_asn (info, pp, &control))
+ return false;
+ count -= 4;
+
+ /* We just ignore the control number. We don't care what
+ the virtual table name is. We have no way to store the
+ virtual table size, and I don't think we care anyhow. */
+
+ /* FIXME: We can't handle multiple virtual table pointers. */
+
+ if (baselen == 0)
+ ownvptr = true;
+ else
+ {
+ char *basecopy;
+
+ basecopy = savestring (basename, baselen);
+ vptrbase = debug_find_tagged_type (dhandle, basecopy,
+ DEBUG_KIND_ILLEGAL);
+ free (basecopy);
+ if (vptrbase == DEBUG_TYPE_NULL)
+ {
+ ieee_error (info, start, _("undefined C++ vtable"));
+ return false;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ /* Now that we have seen all the method variants, we can call
+ debug_make_method for each one. */
+
+ if (methods_count == 0)
+ dmethods = NULL;
+ else
+ {
+ unsigned int i;
+
+ dmethods = ((debug_method *)
+ xmalloc ((methods_count + 1) * sizeof *dmethods));
+ for (i = 0; i < methods_count; i++)
+ {
+ char *namcopy;
+
+ namcopy = savestring (methods[i].name, methods[i].namlen);
+ dmethods[i] = debug_make_method (dhandle, namcopy,
+ methods[i].variants);
+ if (dmethods[i] == DEBUG_METHOD_NULL)
+ return false;
+ }
+ dmethods[i] = DEBUG_METHOD_NULL;
+ free (methods);
+ }
+
+ /* The struct type was created as an indirect type pointing at
+ it->slot. We update it->slot to automatically update all
+ references to this struct. */
+ it->slot = debug_make_object_type (dhandle,
+ class != 'u',
+ debug_get_type_size (dhandle,
+ it->slot),
+ fields, baseclasses, dmethods,
+ vptrbase, ownvptr);
+ if (it->slot == DEBUG_TYPE_NULL)
+ return false;
+
+ return true;
+}
+
+/* Read C++ default argument value and reference type information. */
+
+static boolean
+ieee_read_cxx_defaults (info, pp, count)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ unsigned long count;
+{
+ const bfd_byte *start;
+ const char *fnname;
+ unsigned long fnlen;
+ bfd_vma defcount;
+
+ start = *pp;
+
+ /* Giving the function name before the argument count is an addendum
+ to the spec. The function name is demangled, though, so this
+ record must always refer to the current function. */
+
+ if (info->blockstack.bsp <= info->blockstack.stack
+ || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
+ {
+ ieee_error (info, start, _("C++ default values not in a function"));
+ return false;
+ }
+
+ if (! ieee_require_atn65 (info, pp, &fnname, &fnlen)
+ || ! ieee_require_asn (info, pp, &defcount))
+ return false;
+ count -= 2;
+
+ while (defcount-- > 0)
+ {
+ bfd_vma type, val;
+ const char *strval;
+ unsigned long strvallen;
+
+ if (! ieee_require_asn (info, pp, &type))
+ return false;
+ --count;
+
+ switch (type)
+ {
+ case 0:
+ case 4:
+ break;
+
+ case 1:
+ case 2:
+ if (! ieee_require_asn (info, pp, &val))
+ return false;
+ --count;
+ break;
+
+ case 3:
+ case 7:
+ if (! ieee_require_atn65 (info, pp, &strval, &strvallen))
+ return false;
+ --count;
+ break;
+
+ default:
+ ieee_error (info, start, _("unrecognized C++ default type"));
+ return false;
+ }
+
+ /* We have no way to record the default argument values, so we
+ just ignore them. FIXME. */
+ }
+
+ /* Any remaining arguments are indices of parameters that are really
+ reference type. */
+ if (count > 0)
+ {
+ PTR dhandle;
+ debug_type *arg_slots;
+
+ dhandle = info->dhandle;
+ arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots;
+ while (count-- > 0)
+ {
+ bfd_vma indx;
+ debug_type target;
+
+ if (! ieee_require_asn (info, pp, &indx))
+ return false;
+ /* The index is 1 based. */
+ --indx;
+ if (arg_slots == NULL
+ || arg_slots[indx] == DEBUG_TYPE_NULL
+ || (debug_get_type_kind (dhandle, arg_slots[indx])
+ != DEBUG_KIND_POINTER))
+ {
+ ieee_error (info, start, _("reference parameter is not a pointer"));
+ return false;
+ }
+
+ target = debug_get_target_type (dhandle, arg_slots[indx]);
+ arg_slots[indx] = debug_make_reference_type (dhandle, target);
+ if (arg_slots[indx] == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Read a C++ reference definition. */
+
+static boolean
+ieee_read_reference (info, pp)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+{
+ const bfd_byte *start;
+ bfd_vma flags;
+ const char *class, *name;
+ unsigned long classlen, namlen;
+ debug_type *pslot;
+ debug_type target;
+
+ start = *pp;
+
+ if (! ieee_require_asn (info, pp, &flags))
+ return false;
+
+ /* Giving the class name before the member name is in an addendum to
+ the spec. */
+ if (flags == 3)
+ {
+ if (! ieee_require_atn65 (info, pp, &class, &classlen))
+ return false;
+ }
+
+ if (! ieee_require_atn65 (info, pp, &name, &namlen))
+ return false;
+
+ pslot = NULL;
+ if (flags != 3)
+ {
+ int pass;
+
+ /* We search from the last variable indices to the first in
+ hopes of finding local variables correctly. We search the
+ local variables on the first pass, and the global variables
+ on the second. FIXME: This probably won't work in all cases.
+ On the other hand, I don't know what will. */
+ for (pass = 0; pass < 2; pass++)
+ {
+ struct ieee_vars *vars;
+ int i;
+ struct ieee_var *pv = NULL;
+
+ if (pass == 0)
+ vars = &info->vars;
+ else
+ {
+ vars = info->global_vars;
+ if (vars == NULL)
+ break;
+ }
+
+ for (i = (int) vars->alloc - 1; i >= 0; i--)
+ {
+ boolean found;
+
+ pv = vars->vars + i;
+
+ if (pv->pslot == NULL
+ || pv->namlen != namlen
+ || strncmp (pv->name, name, namlen) != 0)
+ continue;
+
+ found = false;
+ switch (flags)
+ {
+ default:
+ ieee_error (info, start,
+ _("unrecognized C++ reference type"));
+ return false;
+
+ case 0:
+ /* Global variable or function. */
+ if (pv->kind == IEEE_GLOBAL
+ || pv->kind == IEEE_EXTERNAL
+ || pv->kind == IEEE_FUNCTION)
+ found = true;
+ break;
+
+ case 1:
+ /* Global static variable or function. */
+ if (pv->kind == IEEE_STATIC
+ || pv->kind == IEEE_FUNCTION)
+ found = true;
+ break;
+
+ case 2:
+ /* Local variable. */
+ if (pv->kind == IEEE_LOCAL)
+ found = true;
+ break;
+ }
+
+ if (found)
+ break;
+ }
+
+ if (i >= 0)
+ {
+ pslot = pv->pslot;
+ break;
+ }
+ }
+ }
+ else
+ {
+ struct ieee_tag *it;
+
+ for (it = info->tags; it != NULL; it = it->next)
+ {
+ if (it->name[0] == class[0]
+ && strncmp (it->name, class, classlen) == 0
+ && strlen (it->name) == classlen)
+ {
+ if (it->fslots != NULL)
+ {
+ const debug_field *pf;
+ unsigned int findx;
+
+ pf = debug_get_fields (info->dhandle, it->type);
+ if (pf == NULL)
+ {
+ ieee_error (info, start,
+ "C++ reference in class with no fields");
+ return false;
+ }
+
+ for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++)
+ {
+ const char *fname;
+
+ fname = debug_get_field_name (info->dhandle, *pf);
+ if (fname == NULL)
+ return false;
+ if (strncmp (fname, name, namlen) == 0
+ && strlen (fname) == namlen)
+ {
+ pslot = it->fslots + findx;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (pslot == NULL)
+ {
+ ieee_error (info, start, _("C++ reference not found"));
+ return false;
+ }
+
+ /* We allocated the type of the object as an indirect type pointing
+ to *pslot, which we can now update to be a reference type. */
+ if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
+ {
+ ieee_error (info, start, _("C++ reference is not pointer"));
+ return false;
+ }
+
+ target = debug_get_target_type (info->dhandle, *pslot);
+ *pslot = debug_make_reference_type (info->dhandle, target);
+ if (*pslot == DEBUG_TYPE_NULL)
+ return false;
+
+ return true;
+}
+
+/* Require an ASN record. */
+
+static boolean
+ieee_require_asn (info, pp, pv)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ bfd_vma *pv;
+{
+ const bfd_byte *start;
+ ieee_record_enum_type c;
+ bfd_vma varindx;
+
+ start = *pp;
+
+ c = (ieee_record_enum_type) **pp;
+ if (c != ieee_e2_first_byte_enum)
+ {
+ ieee_error (info, start, _("missing required ASN"));
+ return false;
+ }
+ ++*pp;
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ if (c != ieee_asn_record_enum)
+ {
+ ieee_error (info, start, _("missing required ASN"));
+ return false;
+ }
+ ++*pp;
+
+ /* Just ignore the variable index. */
+ if (! ieee_read_number (info, pp, &varindx))
+ return false;
+
+ return ieee_read_expression (info, pp, pv);
+}
+
+/* Require an ATN65 record. */
+
+static boolean
+ieee_require_atn65 (info, pp, pname, pnamlen)
+ struct ieee_info *info;
+ const bfd_byte **pp;
+ const char **pname;
+ unsigned long *pnamlen;
+{
+ const bfd_byte *start;
+ ieee_record_enum_type c;
+ bfd_vma name_indx, type_indx, atn_code;
+
+ start = *pp;
+
+ c = (ieee_record_enum_type) **pp;
+ if (c != ieee_at_record_enum)
+ {
+ ieee_error (info, start, _("missing required ATN65"));
+ return false;
+ }
+ ++*pp;
+
+ c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
+ if (c != ieee_atn_record_enum)
+ {
+ ieee_error (info, start, _("missing required ATN65"));
+ return false;
+ }
+ ++*pp;
+
+ if (! ieee_read_number (info, pp, &name_indx)
+ || ! ieee_read_number (info, pp, &type_indx)
+ || ! ieee_read_number (info, pp, &atn_code))
+ return false;
+
+ /* Just ignore name_indx. */
+
+ if (type_indx != 0 || atn_code != 65)
+ {
+ ieee_error (info, start, _("bad ATN65 record"));
+ return false;
+ }
+
+ return ieee_read_id (info, pp, pname, pnamlen);
+}
+
+/* Convert a register number in IEEE debugging information into a
+ generic register number. */
+
+static int
+ieee_regno_to_genreg (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ /* For some reasons stabs adds 2 to the floating point register
+ numbers. */
+ if (r >= 16)
+ r += 2;
+ break;
+
+ case bfd_arch_i960:
+ /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+ 32 to 35 for fp0 to fp3. */
+ --r;
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/* Convert a generic register number to an IEEE specific one. */
+
+static int
+ieee_genreg_to_regno (abfd, r)
+ bfd *abfd;
+ int r;
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_m68k:
+ /* For some reason stabs add 2 to the floating point register
+ numbers. */
+ if (r >= 18)
+ r -= 2;
+ break;
+
+ case bfd_arch_i960:
+ /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
+ 32 to 35 for fp0 to fp3. */
+ ++r;
+ break;
+
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/* These routines build IEEE debugging information out of the generic
+ debugging information. */
+
+/* We build the IEEE debugging information byte by byte. Rather than
+ waste time copying data around, we use a linked list of buffers to
+ hold the data. */
+
+#define IEEE_BUFSIZE (490)
+
+struct ieee_buf
+{
+ /* Next buffer. */
+ struct ieee_buf *next;
+ /* Number of data bytes in this buffer. */
+ unsigned int c;
+ /* Bytes. */
+ bfd_byte buf[IEEE_BUFSIZE];
+};
+
+/* A list of buffers. */
+
+struct ieee_buflist
+{
+ /* Head of list. */
+ struct ieee_buf *head;
+ /* Tail--last buffer on list. */
+ struct ieee_buf *tail;
+};
+
+/* In order to generate the BB11 blocks required by the HP emulator,
+ we keep track of ranges of addresses which correspond to a given
+ compilation unit. */
+
+struct ieee_range
+{
+ /* Next range. */
+ struct ieee_range *next;
+ /* Low address. */
+ bfd_vma low;
+ /* High address. */
+ bfd_vma high;
+};
+
+/* This structure holds information for a class on the type stack. */
+
+struct ieee_type_class
+{
+ /* The name index in the debugging information. */
+ unsigned int indx;
+ /* The pmisc records for the class. */
+ struct ieee_buflist pmiscbuf;
+ /* The number of pmisc records. */
+ unsigned int pmisccount;
+ /* The name of the class holding the virtual table, if not this
+ class. */
+ const char *vclass;
+ /* Whether this class holds its own virtual table. */
+ boolean ownvptr;
+ /* The largest virtual table offset seen so far. */
+ bfd_vma voffset;
+ /* The current method. */
+ const char *method;
+ /* Additional pmisc records used to record fields of reference type. */
+ struct ieee_buflist refs;
+};
+
+/* This is how we store types for the writing routines. Most types
+ are simply represented by a type index. */
+
+struct ieee_write_type
+{
+ /* Type index. */
+ unsigned int indx;
+ /* The size of the type, if known. */
+ unsigned int size;
+ /* The name of the type, if any. */
+ const char *name;
+ /* If this is a function or method type, we build the type here, and
+ only add it to the output buffers if we need it. */
+ struct ieee_buflist fndef;
+ /* If this is a struct, this is where the struct definition is
+ built. */
+ struct ieee_buflist strdef;
+ /* If this is a class, this is where the class information is built. */
+ struct ieee_type_class *classdef;
+ /* Whether the type is unsigned. */
+ unsigned int unsignedp : 1;
+ /* Whether this is a reference type. */
+ unsigned int referencep : 1;
+ /* Whether this is in the local type block. */
+ unsigned int localp : 1;
+ /* Whether this is a duplicate struct definition which we are
+ ignoring. */
+ unsigned int ignorep : 1;
+};
+
+/* This is the type stack used by the debug writing routines. FIXME:
+ We could generate more efficient output if we remembered when we
+ have output a particular type before. */
+
+struct ieee_type_stack
+{
+ /* Next entry on stack. */
+ struct ieee_type_stack *next;
+ /* Type information. */
+ struct ieee_write_type type;
+};
+
+/* This is a list of associations between a name and some types.
+ These are used for typedefs and tags. */
+
+struct ieee_name_type
+{
+ /* Next type for this name. */
+ struct ieee_name_type *next;
+ /* ID number. For a typedef, this is the index of the type to which
+ this name is typedefed. */
+ unsigned int id;
+ /* Type. */
+ struct ieee_write_type type;
+ /* If this is a tag which has not yet been defined, this is the
+ kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */
+ enum debug_type_kind kind;
+};
+
+/* We use a hash table to associate names and types. */
+
+struct ieee_name_type_hash_table
+{
+ struct bfd_hash_table root;
+};
+
+struct ieee_name_type_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Information for this name. */
+ struct ieee_name_type *types;
+};
+
+/* This is a list of enums. */
+
+struct ieee_defined_enum
+{
+ /* Next enum. */
+ struct ieee_defined_enum *next;
+ /* Type index. */
+ unsigned int indx;
+ /* Whether this enum has been defined. */
+ boolean defined;
+ /* Tag. */
+ const char *tag;
+ /* Names. */
+ const char **names;
+ /* Values. */
+ bfd_signed_vma *vals;
+};
+
+/* We keep a list of modified versions of types, so that we don't
+ output them more than once. */
+
+struct ieee_modified_type
+{
+ /* Pointer to this type. */
+ unsigned int pointer;
+ /* Function with unknown arguments returning this type. */
+ unsigned int function;
+ /* Const version of this type. */
+ unsigned int const_qualified;
+ /* Volatile version of this type. */
+ unsigned int volatile_qualified;
+ /* List of arrays of this type of various bounds. */
+ struct ieee_modified_array_type *arrays;
+};
+
+/* A list of arrays bounds. */
+
+struct ieee_modified_array_type
+{
+ /* Next array bounds. */
+ struct ieee_modified_array_type *next;
+ /* Type index with these bounds. */
+ unsigned int indx;
+ /* Low bound. */
+ bfd_signed_vma low;
+ /* High bound. */
+ bfd_signed_vma high;
+};
+
+/* This is a list of pending function parameter information. We don't
+ output them until we see the first block. */
+
+struct ieee_pending_parm
+{
+ /* Next pending parameter. */
+ struct ieee_pending_parm *next;
+ /* Name. */
+ const char *name;
+ /* Type index. */
+ unsigned int type;
+ /* Whether the type is a reference. */
+ boolean referencep;
+ /* Kind. */
+ enum debug_parm_kind kind;
+ /* Value. */
+ bfd_vma val;
+};
+
+/* This is the handle passed down by debug_write. */
+
+struct ieee_handle
+{
+ /* BFD we are writing to. */
+ bfd *abfd;
+ /* Whether we got an error in a subroutine called via traverse or
+ map_over_sections. */
+ boolean error;
+ /* Current data buffer list. */
+ struct ieee_buflist *current;
+ /* Current data buffer. */
+ struct ieee_buf *curbuf;
+ /* Filename of current compilation unit. */
+ const char *filename;
+ /* Module name of current compilation unit. */
+ const char *modname;
+ /* List of buffer for global types. */
+ struct ieee_buflist global_types;
+ /* List of finished data buffers. */
+ struct ieee_buflist data;
+ /* List of buffers for typedefs in the current compilation unit. */
+ struct ieee_buflist types;
+ /* List of buffers for variables and functions in the current
+ compilation unit. */
+ struct ieee_buflist vars;
+ /* List of buffers for C++ class definitions in the current
+ compilation unit. */
+ struct ieee_buflist cxx;
+ /* List of buffers for line numbers in the current compilation unit. */
+ struct ieee_buflist linenos;
+ /* Ranges for the current compilation unit. */
+ struct ieee_range *ranges;
+ /* Ranges for all debugging information. */
+ struct ieee_range *global_ranges;
+ /* Nested pending ranges. */
+ struct ieee_range *pending_ranges;
+ /* Type stack. */
+ struct ieee_type_stack *type_stack;
+ /* Next unallocated type index. */
+ unsigned int type_indx;
+ /* Next unallocated name index. */
+ unsigned int name_indx;
+ /* Typedefs. */
+ struct ieee_name_type_hash_table typedefs;
+ /* Tags. */
+ struct ieee_name_type_hash_table tags;
+ /* Enums. */
+ struct ieee_defined_enum *enums;
+ /* Modified versions of types. */
+ struct ieee_modified_type *modified;
+ /* Number of entries allocated in modified. */
+ unsigned int modified_alloc;
+ /* 4 byte complex type. */
+ unsigned int complex_float_index;
+ /* 8 byte complex type. */
+ unsigned int complex_double_index;
+ /* The depth of block nesting. This is 0 outside a function, and 1
+ just after start_function is called. */
+ unsigned int block_depth;
+ /* The name of the current function. */
+ const char *fnname;
+ /* List of buffers for the type of the function we are currently
+ writing out. */
+ struct ieee_buflist fntype;
+ /* List of buffers for the parameters of the function we are
+ currently writing out. */
+ struct ieee_buflist fnargs;
+ /* Number of arguments written to fnargs. */
+ unsigned int fnargcount;
+ /* Pending function parameters. */
+ struct ieee_pending_parm *pending_parms;
+ /* Current line number filename. */
+ const char *lineno_filename;
+ /* Line number name index. */
+ unsigned int lineno_name_indx;
+ /* Filename of pending line number. */
+ const char *pending_lineno_filename;
+ /* Pending line number. */
+ unsigned long pending_lineno;
+ /* Address of pending line number. */
+ bfd_vma pending_lineno_addr;
+ /* Highest address seen at end of procedure. */
+ bfd_vma highaddr;
+};
+
+static boolean ieee_init_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *));
+static boolean ieee_change_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *));
+static boolean ieee_append_buffer
+ PARAMS ((struct ieee_handle *, struct ieee_buflist *,
+ struct ieee_buflist *));
+static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int));
+static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int));
+static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *));
+static boolean ieee_write_asn
+ PARAMS ((struct ieee_handle *, unsigned int, bfd_vma));
+static boolean ieee_write_atn65
+ PARAMS ((struct ieee_handle *, unsigned int, const char *));
+static boolean ieee_push_type
+ PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean,
+ boolean));
+static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
+static void ieee_pop_unused_type PARAMS ((struct ieee_handle *));
+static unsigned int ieee_pop_type_used
+ PARAMS ((struct ieee_handle *, boolean));
+static boolean ieee_add_range
+ PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma));
+static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
+static boolean ieee_define_type
+ PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean));
+static boolean ieee_define_named_type
+ PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int,
+ boolean, boolean, struct ieee_buflist *));
+static struct ieee_modified_type *ieee_get_modified_info
+ PARAMS ((struct ieee_handle *, unsigned int));
+static struct bfd_hash_entry *ieee_name_type_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean ieee_write_undefined_tag
+ PARAMS ((struct ieee_name_type_hash_entry *, PTR));
+static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *));
+static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR));
+static boolean ieee_add_bb11
+ PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma));
+static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
+static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility));
+static boolean ieee_class_method_var
+ PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean,
+ boolean, boolean, bfd_vma, boolean));
+
+static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean ieee_start_source PARAMS ((PTR, const char *));
+static boolean ieee_empty_type PARAMS ((PTR));
+static boolean ieee_void_type PARAMS ((PTR));
+static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean ieee_float_type PARAMS ((PTR, unsigned int));
+static boolean ieee_complex_type PARAMS ((PTR, unsigned int));
+static boolean ieee_bool_type PARAMS ((PTR, unsigned int));
+static boolean ieee_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean ieee_pointer_type PARAMS ((PTR));
+static boolean ieee_function_type PARAMS ((PTR, int, boolean));
+static boolean ieee_reference_type PARAMS ((PTR));
+static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean ieee_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean ieee_set_type PARAMS ((PTR, boolean));
+static boolean ieee_offset_type PARAMS ((PTR));
+static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean ieee_const_type PARAMS ((PTR));
+static boolean ieee_volatile_type PARAMS ((PTR));
+static boolean ieee_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean ieee_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean ieee_end_struct_type PARAMS ((PTR));
+static boolean ieee_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean ieee_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean ieee_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean ieee_class_start_method PARAMS ((PTR, const char *));
+static boolean ieee_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean ieee_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean ieee_class_end_method PARAMS ((PTR));
+static boolean ieee_end_class_type PARAMS ((PTR));
+static boolean ieee_typedef_type PARAMS ((PTR, const char *));
+static boolean ieee_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean ieee_typdef PARAMS ((PTR, const char *));
+static boolean ieee_tag PARAMS ((PTR, const char *));
+static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean ieee_float_constant PARAMS ((PTR, const char *, double));
+static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean ieee_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean ieee_start_function PARAMS ((PTR, const char *, boolean));
+static boolean ieee_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean ieee_start_block PARAMS ((PTR, bfd_vma));
+static boolean ieee_end_block PARAMS ((PTR, bfd_vma));
+static boolean ieee_end_function PARAMS ((PTR));
+static boolean ieee_lineno
+ PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns ieee_fns =
+{
+ ieee_start_compilation_unit,
+ ieee_start_source,
+ ieee_empty_type,
+ ieee_void_type,
+ ieee_int_type,
+ ieee_float_type,
+ ieee_complex_type,
+ ieee_bool_type,
+ ieee_enum_type,
+ ieee_pointer_type,
+ ieee_function_type,
+ ieee_reference_type,
+ ieee_range_type,
+ ieee_array_type,
+ ieee_set_type,
+ ieee_offset_type,
+ ieee_method_type,
+ ieee_const_type,
+ ieee_volatile_type,
+ ieee_start_struct_type,
+ ieee_struct_field,
+ ieee_end_struct_type,
+ ieee_start_class_type,
+ ieee_class_static_member,
+ ieee_class_baseclass,
+ ieee_class_start_method,
+ ieee_class_method_variant,
+ ieee_class_static_method_variant,
+ ieee_class_end_method,
+ ieee_end_class_type,
+ ieee_typedef_type,
+ ieee_tag_type,
+ ieee_typdef,
+ ieee_tag,
+ ieee_int_constant,
+ ieee_float_constant,
+ ieee_typed_constant,
+ ieee_variable,
+ ieee_start_function,
+ ieee_function_parameter,
+ ieee_start_block,
+ ieee_end_block,
+ ieee_end_function,
+ ieee_lineno
+};
+
+/* Initialize a buffer to be empty. */
+
+/*ARGSUSED*/
+static boolean
+ieee_init_buffer (info, buflist)
+ struct ieee_handle *info;
+ struct ieee_buflist *buflist;
+{
+ buflist->head = NULL;
+ buflist->tail = NULL;
+ return true;
+}
+
+/* See whether a buffer list has any data. */
+
+#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL)
+
+/* Change the current buffer to a specified buffer chain. */
+
+static boolean
+ieee_change_buffer (info, buflist)
+ struct ieee_handle *info;
+ struct ieee_buflist *buflist;
+{
+ if (buflist->head == NULL)
+ {
+ struct ieee_buf *buf;
+
+ buf = (struct ieee_buf *) xmalloc (sizeof *buf);
+ buf->next = NULL;
+ buf->c = 0;
+ buflist->head = buf;
+ buflist->tail = buf;
+ }
+
+ info->current = buflist;
+ info->curbuf = buflist->tail;
+
+ return true;
+}
+
+/* Append a buffer chain. */
+
+/*ARGSUSED*/
+static boolean
+ieee_append_buffer (info, mainbuf, newbuf)
+ struct ieee_handle *info;
+ struct ieee_buflist *mainbuf;
+ struct ieee_buflist *newbuf;
+{
+ if (newbuf->head != NULL)
+ {
+ if (mainbuf->head == NULL)
+ mainbuf->head = newbuf->head;
+ else
+ mainbuf->tail->next = newbuf->head;
+ mainbuf->tail = newbuf->tail;
+ }
+ return true;
+}
+
+/* Write a byte into the buffer. We use a macro for speed and a
+ function for the complex cases. */
+
+#define ieee_write_byte(info, b) \
+ ((info)->curbuf->c < IEEE_BUFSIZE \
+ ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \
+ : ieee_real_write_byte ((info), (b)))
+
+static boolean
+ieee_real_write_byte (info, b)
+ struct ieee_handle *info;
+ int b;
+{
+ if (info->curbuf->c >= IEEE_BUFSIZE)
+ {
+ struct ieee_buf *n;
+
+ n = (struct ieee_buf *) xmalloc (sizeof *n);
+ n->next = NULL;
+ n->c = 0;
+ if (info->current->head == NULL)
+ info->current->head = n;
+ else
+ info->current->tail->next = n;
+ info->current->tail = n;
+ info->curbuf = n;
+ }
+
+ info->curbuf->buf[info->curbuf->c] = b;
+ ++info->curbuf->c;
+
+ return true;
+}
+
+/* Write out two bytes. */
+
+static boolean
+ieee_write_2bytes (info, i)
+ struct ieee_handle *info;
+ int i;
+{
+ return (ieee_write_byte (info, i >> 8)
+ && ieee_write_byte (info, i & 0xff));
+}
+
+/* Write out an integer. */
+
+static boolean
+ieee_write_number (info, v)
+ struct ieee_handle *info;
+ bfd_vma v;
+{
+ bfd_vma t;
+ bfd_byte ab[20];
+ bfd_byte *p;
+ unsigned int c;
+
+ if (v <= (bfd_vma) ieee_number_end_enum)
+ return ieee_write_byte (info, (int) v);
+
+ t = v;
+ p = ab + sizeof ab;
+ while (t != 0)
+ {
+ *--p = t & 0xff;
+ t >>= 8;
+ }
+ c = (ab + 20) - p;
+
+ if (c > (unsigned int) (ieee_number_repeat_end_enum
+ - ieee_number_repeat_start_enum))
+ {
+ fprintf (stderr, _("IEEE numeric overflow: 0x"));
+ fprintf_vma (stderr, v);
+ fprintf (stderr, "\n");
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c))
+ return false;
+ for (; c > 0; --c, ++p)
+ {
+ if (! ieee_write_byte (info, *p))
+ return false;
+ }
+
+ return true;
+}
+
+/* Write out a string. */
+
+static boolean
+ieee_write_id (info, s)
+ struct ieee_handle *info;
+ const char *s;
+{
+ unsigned int len;
+
+ len = strlen (s);
+ if (len <= 0x7f)
+ {
+ if (! ieee_write_byte (info, len))
+ return false;
+ }
+ else if (len <= 0xff)
+ {
+ if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum)
+ || ! ieee_write_byte (info, len))
+ return false;
+ }
+ else if (len <= 0xffff)
+ {
+ if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum)
+ || ! ieee_write_2bytes (info, len))
+ return false;
+ }
+ else
+ {
+ fprintf (stderr, _("IEEE string length overflow: %u\n"), len);
+ return false;
+ }
+
+ for (; *s != '\0'; s++)
+ if (! ieee_write_byte (info, *s))
+ return false;
+
+ return true;
+}
+
+/* Write out an ASN record. */
+
+static boolean
+ieee_write_asn (info, indx, val)
+ struct ieee_handle *info;
+ unsigned int indx;
+ bfd_vma val;
+{
+ return (ieee_write_2bytes (info, (int) ieee_asn_record_enum)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, val));
+}
+
+/* Write out an ATN65 record. */
+
+static boolean
+ieee_write_atn65 (info, indx, s)
+ struct ieee_handle *info;
+ unsigned int indx;
+ const char *s;
+{
+ return (ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, 0)
+ && ieee_write_number (info, 65)
+ && ieee_write_id (info, s));
+}
+
+/* Push a type index onto the type stack. */
+
+static boolean
+ieee_push_type (info, indx, size, unsignedp, localp)
+ struct ieee_handle *info;
+ unsigned int indx;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+{
+ struct ieee_type_stack *ts;
+
+ ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
+ memset (ts, 0, sizeof *ts);
+
+ ts->type.indx = indx;
+ ts->type.size = size;
+ ts->type.unsignedp = unsignedp;
+ ts->type.localp = localp;
+
+ ts->next = info->type_stack;
+ info->type_stack = ts;
+
+ return true;
+}
+
+/* Pop a type index off the type stack. */
+
+static unsigned int
+ieee_pop_type (info)
+ struct ieee_handle *info;
+{
+ return ieee_pop_type_used (info, true);
+}
+
+/* Pop an unused type index off the type stack. */
+
+static void
+ieee_pop_unused_type (info)
+ struct ieee_handle *info;
+{
+ (void) ieee_pop_type_used (info, false);
+}
+
+/* Pop a used or unused type index off the type stack. */
+
+static unsigned int
+ieee_pop_type_used (info, used)
+ struct ieee_handle *info;
+ boolean used;
+{
+ struct ieee_type_stack *ts;
+ unsigned int ret;
+
+ ts = info->type_stack;
+ assert (ts != NULL);
+
+ /* If this is a function type, and we need it, we need to append the
+ actual definition to the typedef block now. */
+ if (used && ! ieee_buffer_emptyp (&ts->type.fndef))
+ {
+ struct ieee_buflist *buflist;
+
+ if (ts->type.localp)
+ {
+ /* Make sure we have started the types block. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ buflist = &info->types;
+ }
+ else
+ {
+ /* Make sure we started the global type block. */
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ buflist = &info->global_types;
+ }
+
+ if (! ieee_append_buffer (info, buflist, &ts->type.fndef))
+ return false;
+ }
+
+ ret = ts->type.indx;
+ info->type_stack = ts->next;
+ free (ts);
+ return ret;
+}
+
+/* Add a range of bytes included in the current compilation unit. */
+
+static boolean
+ieee_add_range (info, global, low, high)
+ struct ieee_handle *info;
+ boolean global;
+ bfd_vma low;
+ bfd_vma high;
+{
+ struct ieee_range **plist, *r, **pr;
+
+ if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high)
+ return true;
+
+ if (global)
+ plist = &info->global_ranges;
+ else
+ plist = &info->ranges;
+
+ for (r = *plist; r != NULL; r = r->next)
+ {
+ if (high >= r->low && low <= r->high)
+ {
+ /* The new range overlaps r. */
+ if (low < r->low)
+ r->low = low;
+ if (high > r->high)
+ r->high = high;
+ pr = &r->next;
+ while (*pr != NULL && (*pr)->low <= r->high)
+ {
+ struct ieee_range *n;
+
+ if ((*pr)->high > r->high)
+ r->high = (*pr)->high;
+ n = (*pr)->next;
+ free (*pr);
+ *pr = n;
+ }
+ return true;
+ }
+ }
+
+ r = (struct ieee_range *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+
+ r->low = low;
+ r->high = high;
+
+ /* Store the ranges sorted by address. */
+ for (pr = plist; *pr != NULL; pr = &(*pr)->next)
+ if ((*pr)->low > high)
+ break;
+ r->next = *pr;
+ *pr = r;
+
+ return true;
+}
+
+/* Start a new range for which we only have the low address. */
+
+static boolean
+ieee_start_range (info, low)
+ struct ieee_handle *info;
+ bfd_vma low;
+{
+ struct ieee_range *r;
+
+ r = (struct ieee_range *) xmalloc (sizeof *r);
+ memset (r, 0, sizeof *r);
+ r->low = low;
+ r->next = info->pending_ranges;
+ info->pending_ranges = r;
+ return true;
+}
+
+/* Finish a range started by ieee_start_range. */
+
+static boolean
+ieee_end_range (info, high)
+ struct ieee_handle *info;
+ bfd_vma high;
+{
+ struct ieee_range *r;
+ bfd_vma low;
+
+ assert (info->pending_ranges != NULL);
+ r = info->pending_ranges;
+ low = r->low;
+ info->pending_ranges = r->next;
+ free (r);
+ return ieee_add_range (info, false, low, high);
+}
+
+/* Start defining a type. */
+
+static boolean
+ieee_define_type (info, size, unsignedp, localp)
+ struct ieee_handle *info;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+{
+ return ieee_define_named_type (info, (const char *) NULL,
+ (unsigned int) -1, size, unsignedp,
+ localp, (struct ieee_buflist *) NULL);
+}
+
+/* Start defining a named type. */
+
+static boolean
+ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist)
+ struct ieee_handle *info;
+ const char *name;
+ unsigned int indx;
+ unsigned int size;
+ boolean unsignedp;
+ boolean localp;
+ struct ieee_buflist *buflist;
+{
+ unsigned int type_indx;
+ unsigned int name_indx;
+
+ if (indx != (unsigned int) -1)
+ type_indx = indx;
+ else
+ {
+ type_indx = info->type_indx;
+ ++info->type_indx;
+ }
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+
+ if (name == NULL)
+ name = "";
+
+ /* If we were given a buffer, use it; otherwise, use either the
+ local or the global type information, and make sure that the type
+ block is started. */
+ if (buflist != NULL)
+ {
+ if (! ieee_change_buffer (info, buflist))
+ return false;
+ }
+ else if (localp)
+ {
+ if (! ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types))
+ return false;
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types))
+ return false;
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ }
+
+ /* Push the new type on the type stack, write out an NN record, and
+ write out the start of a TY record. The caller will then finish
+ the TY record. */
+ if (! ieee_push_type (info, type_indx, size, unsignedp, localp))
+ return false;
+
+ return (ieee_write_byte (info, (int) ieee_nn_record)
+ && ieee_write_number (info, name_indx)
+ && ieee_write_id (info, name)
+ && ieee_write_byte (info, (int) ieee_ty_record_enum)
+ && ieee_write_number (info, type_indx)
+ && ieee_write_byte (info, 0xce)
+ && ieee_write_number (info, name_indx));
+}
+
+/* Get an entry to the list of modified versions of a type. */
+
+static struct ieee_modified_type *
+ieee_get_modified_info (info, indx)
+ struct ieee_handle *info;
+ unsigned int indx;
+{
+ if (indx >= info->modified_alloc)
+ {
+ unsigned int nalloc;
+
+ nalloc = info->modified_alloc;
+ if (nalloc == 0)
+ nalloc = 16;
+ while (indx >= nalloc)
+ nalloc *= 2;
+ info->modified = ((struct ieee_modified_type *)
+ xrealloc (info->modified,
+ nalloc * sizeof *info->modified));
+ memset (info->modified + info->modified_alloc, 0,
+ (nalloc - info->modified_alloc) * sizeof *info->modified);
+ info->modified_alloc = nalloc;
+ }
+
+ return info->modified + indx;
+}
+
+/* Routines for the hash table mapping names to types. */
+
+/* Initialize an entry in the hash table. */
+
+static struct bfd_hash_entry *
+ieee_name_type_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct ieee_name_type_hash_entry *ret =
+ (struct ieee_name_type_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct ieee_name_type_hash_entry *)
+ bfd_hash_allocate (table, sizeof *ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct ieee_name_type_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret)
+ {
+ /* Set local fields. */
+ ret->types = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in the hash table. */
+
+#define ieee_name_type_hash_lookup(table, string, create, copy) \
+ ((struct ieee_name_type_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* Traverse the hash table. */
+
+#define ieee_name_type_hash_traverse(table, func, info) \
+ (bfd_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* The general routine to write out IEEE debugging information. */
+
+boolean
+write_ieee_debugging_info (abfd, dhandle)
+ bfd *abfd;
+ PTR dhandle;
+{
+ struct ieee_handle info;
+ asection *s;
+ const char *err;
+ struct ieee_buf *b;
+
+ memset (&info, 0, sizeof info);
+ info.abfd = abfd;
+ info.type_indx = 256;
+ info.name_indx = 32;
+
+ if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc)
+ || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc))
+ return false;
+
+ if (! ieee_init_buffer (&info, &info.global_types)
+ || ! ieee_init_buffer (&info, &info.data)
+ || ! ieee_init_buffer (&info, &info.types)
+ || ! ieee_init_buffer (&info, &info.vars)
+ || ! ieee_init_buffer (&info, &info.cxx)
+ || ! ieee_init_buffer (&info, &info.linenos)
+ || ! ieee_init_buffer (&info, &info.fntype)
+ || ! ieee_init_buffer (&info, &info.fnargs))
+ return false;
+
+ if (! debug_write (dhandle, &ieee_fns, (PTR) &info))
+ return false;
+
+ if (info.filename != NULL)
+ {
+ if (! ieee_finish_compilation_unit (&info))
+ return false;
+ }
+
+ /* Put any undefined tags in the global typedef information. */
+ info.error = false;
+ ieee_name_type_hash_traverse (&info.tags,
+ ieee_write_undefined_tag,
+ (PTR) &info);
+ if (info.error)
+ return false;
+
+ /* Prepend the global typedef information to the other data. */
+ if (! ieee_buffer_emptyp (&info.global_types))
+ {
+ /* The HP debugger seems to have a bug in which it ignores the
+ last entry in the global types, so we add a dummy entry. */
+ if (! ieee_change_buffer (&info, &info.global_types)
+ || ! ieee_write_byte (&info, (int) ieee_nn_record)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_id (&info, "")
+ || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (&info, info.type_indx)
+ || ! ieee_write_byte (&info, 0xce)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_number (&info, 'P')
+ || ! ieee_write_number (&info, (int) builtin_void + 32)
+ || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
+ return false;
+
+ if (! ieee_append_buffer (&info, &info.global_types, &info.data))
+ return false;
+ info.data = info.global_types;
+ }
+
+ /* Make sure that we have declare BB11 blocks for each range in the
+ file. They are added to info->vars. */
+ info.error = false;
+ if (! ieee_init_buffer (&info, &info.vars))
+ return false;
+ bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info);
+ if (info.error)
+ return false;
+ if (! ieee_buffer_emptyp (&info.vars))
+ {
+ if (! ieee_change_buffer (&info, &info.vars)
+ || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
+ return false;
+
+ if (! ieee_append_buffer (&info, &info.data, &info.vars))
+ return false;
+ }
+
+ /* Now all the data is in info.data. Write it out to the BFD. We
+ normally would need to worry about whether all the other sections
+ are set up yet, but the IEEE backend will handle this particular
+ case correctly regardless. */
+ if (ieee_buffer_emptyp (&info.data))
+ {
+ /* There is no debugging information. */
+ return true;
+ }
+ err = NULL;
+ s = bfd_make_section (abfd, ".debug");
+ if (s == NULL)
+ err = "bfd_make_section";
+ if (err == NULL)
+ {
+ if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS))
+ err = "bfd_set_section_flags";
+ }
+ if (err == NULL)
+ {
+ bfd_size_type size;
+
+ size = 0;
+ for (b = info.data.head; b != NULL; b = b->next)
+ size += b->c;
+ if (! bfd_set_section_size (abfd, s, size))
+ err = "bfd_set_section_size";
+ }
+ if (err == NULL)
+ {
+ file_ptr offset;
+
+ offset = 0;
+ for (b = info.data.head; b != NULL; b = b->next)
+ {
+ if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c))
+ {
+ err = "bfd_set_section_contents";
+ break;
+ }
+ offset += b->c;
+ }
+ }
+
+ if (err != NULL)
+ {
+ fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ bfd_hash_table_free (&info.typedefs.root);
+ bfd_hash_table_free (&info.tags.root);
+
+ return true;
+}
+
+/* Write out information for an undefined tag. This is called via
+ ieee_name_type_hash_traverse. */
+
+static boolean
+ieee_write_undefined_tag (h, p)
+ struct ieee_name_type_hash_entry *h;
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_name_type *nt;
+
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ unsigned int name_indx;
+ char code;
+
+ if (nt->kind == DEBUG_KIND_ILLEGAL)
+ continue;
+
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+ else
+ {
+ if (! ieee_change_buffer (info, &info->global_types))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_id (info, nt->type.name)
+ || ! ieee_write_byte (info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (info, nt->type.indx)
+ || ! ieee_write_byte (info, 0xce)
+ || ! ieee_write_number (info, name_indx))
+ {
+ info->error = true;
+ return false;
+ }
+
+ switch (nt->kind)
+ {
+ default:
+ abort ();
+ info->error = true;
+ return false;
+ case DEBUG_KIND_STRUCT:
+ case DEBUG_KIND_CLASS:
+ code = 'S';
+ break;
+ case DEBUG_KIND_UNION:
+ case DEBUG_KIND_UNION_CLASS:
+ code = 'U';
+ break;
+ case DEBUG_KIND_ENUM:
+ code = 'E';
+ break;
+ }
+ if (! ieee_write_number (info, code)
+ || ! ieee_write_number (info, 0))
+ {
+ info->error = true;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Start writing out information for a compilation unit. */
+
+static boolean
+ieee_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *modname;
+ char *c, *s;
+ unsigned int nindx;
+
+ if (info->filename != NULL)
+ {
+ if (! ieee_finish_compilation_unit (info))
+ return false;
+ }
+
+ info->filename = filename;
+ modname = strrchr (filename, '/');
+ if (modname != NULL)
+ ++modname;
+ else
+ {
+ modname = strrchr (filename, '\\');
+ if (modname != NULL)
+ ++modname;
+ else
+ modname = filename;
+ }
+ c = xstrdup (modname);
+ s = strrchr (c, '.');
+ if (s != NULL)
+ *s = '\0';
+ info->modname = c;
+
+ if (! ieee_init_buffer (info, &info->types)
+ || ! ieee_init_buffer (info, &info->vars)
+ || ! ieee_init_buffer (info, &info->cxx)
+ || ! ieee_init_buffer (info, &info->linenos))
+ return false;
+ info->ranges = NULL;
+
+ /* Always include a BB1 and a BB3 block. That is what the output of
+ the MRI linker seems to look like. */
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 3)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+
+ return true;
+}
+
+/* Finish up a compilation unit. */
+
+static boolean
+ieee_finish_compilation_unit (info)
+ struct ieee_handle *info;
+{
+ struct ieee_range *r;
+
+ if (! ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+
+ if (! ieee_buffer_emptyp (&info->cxx))
+ {
+ /* Append any C++ information to the global function and
+ variable information. */
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ /* We put the pmisc records in a dummy procedure, just as the
+ MRI compiler does. */
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 6)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "__XRYCPP")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, info->highaddr - 1)
+ || ! ieee_append_buffer (info, &info->vars, &info->cxx)
+ || ! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, info->highaddr - 1))
+ return false;
+ }
+
+ if (! ieee_buffer_emptyp (&info->vars))
+ {
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+
+ if (info->pending_lineno_filename != NULL)
+ {
+ /* Force out the pending line number. */
+ if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1))
+ return false;
+ }
+ if (! ieee_buffer_emptyp (&info->linenos))
+ {
+ if (! ieee_change_buffer (info, &info->linenos)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ if (strcmp (info->filename, info->lineno_filename) != 0)
+ {
+ /* We were not in the main file. We just closed the
+ included line number block, and now we must close the
+ main line number block. */
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ }
+ }
+
+ if (! ieee_append_buffer (info, &info->data, &info->types)
+ || ! ieee_append_buffer (info, &info->data, &info->vars)
+ || ! ieee_append_buffer (info, &info->data, &info->linenos))
+ return false;
+
+ /* Build BB10/BB11 blocks based on the ranges we recorded. */
+ if (! ieee_change_buffer (info, &info->data))
+ return false;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 10)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "GNU objcopy"))
+ return false;
+
+ for (r = info->ranges; r != NULL; r = r->next)
+ {
+ bfd_vma low, high;
+ asection *s;
+ int kind;
+
+ low = r->low;
+ high = r->high;
+
+ /* Find the section corresponding to this range. */
+ for (s = info->abfd->sections; s != NULL; s = s->next)
+ {
+ if (bfd_get_section_vma (info->abfd, s) <= low
+ && high <= (bfd_get_section_vma (info->abfd, s)
+ + bfd_section_size (info->abfd, s)))
+ break;
+ }
+
+ if (s == NULL)
+ {
+ /* Just ignore this range. */
+ continue;
+ }
+
+ /* Coalesce ranges if it seems reasonable. */
+ while (r->next != NULL
+ && high + 0x1000 >= r->next->low
+ && (r->next->high
+ <= (bfd_get_section_vma (info->abfd, s)
+ + bfd_section_size (info->abfd, s))))
+ {
+ r = r->next;
+ high = r->high;
+ }
+
+ if ((s->flags & SEC_CODE) != 0)
+ kind = 1;
+ else if ((s->flags & SEC_READONLY) != 0)
+ kind = 3;
+ else
+ kind = 2;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 11)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, kind)
+ || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE)
+ || ! ieee_write_number (info, low)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, high - low))
+ return false;
+
+ /* Add this range to the list of global ranges. */
+ if (! ieee_add_range (info, true, low, high))
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+
+ return true;
+}
+
+/* Add BB11 blocks describing each range that we have not already
+ described. */
+
+static void
+ieee_add_bb11_blocks (abfd, sec, data)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+{
+ struct ieee_handle *info = (struct ieee_handle *) data;
+ bfd_vma low, high;
+ struct ieee_range *r;
+
+ low = bfd_get_section_vma (abfd, sec);
+ high = low + bfd_section_size (abfd, sec);
+
+ /* Find the first range at or after this section. The ranges are
+ sorted by address. */
+ for (r = info->global_ranges; r != NULL; r = r->next)
+ if (r->high > low)
+ break;
+
+ while (low < high)
+ {
+ if (r == NULL || r->low >= high)
+ {
+ if (! ieee_add_bb11 (info, sec, low, high))
+ info->error = true;
+ return;
+ }
+
+ if (low < r->low
+ && r->low - low > 0x100)
+ {
+ if (! ieee_add_bb11 (info, sec, low, r->low))
+ {
+ info->error = true;
+ return;
+ }
+ }
+ low = r->high;
+
+ r = r->next;
+ }
+}
+
+/* Add a single BB11 block for a range. We add it to info->vars. */
+
+static boolean
+ieee_add_bb11 (info, sec, low, high)
+ struct ieee_handle *info;
+ asection *sec;
+ bfd_vma low;
+ bfd_vma high;
+{
+ int kind;
+
+ if (! ieee_buffer_emptyp (&info->vars))
+ {
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+ }
+ else
+ {
+ const char *filename, *modname;
+ char *c, *s;
+
+ /* Start the enclosing BB10 block. */
+ filename = bfd_get_filename (info->abfd);
+ modname = strrchr (filename, '/');
+ if (modname != NULL)
+ ++modname;
+ else
+ {
+ modname = strrchr (filename, '\\');
+ if (modname != NULL)
+ ++modname;
+ else
+ modname = filename;
+ }
+ c = xstrdup (modname);
+ s = strrchr (c, '.');
+ if (s != NULL)
+ *s = '\0';
+
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 10)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, c)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "GNU objcopy"))
+ return false;
+
+ free (c);
+ }
+
+ if ((sec->flags & SEC_CODE) != 0)
+ kind = 1;
+ else if ((sec->flags & SEC_READONLY) != 0)
+ kind = 3;
+ else
+ kind = 2;
+
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 11)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, kind)
+ || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE)
+ || ! ieee_write_number (info, low)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, high - low))
+ return false;
+
+ return true;
+}
+
+/* Start recording information from a particular source file. This is
+ used to record which file defined which types, variables, etc. It
+ is not used for line numbers, since the lineno entry point passes
+ down the file name anyhow. IEEE debugging information doesn't seem
+ to store this information anywhere. */
+
+/*ARGSUSED*/
+static boolean
+ieee_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ return true;
+}
+
+/* Make an empty type. */
+
+static boolean
+ieee_empty_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
+}
+
+/* Make a void type. */
+
+static boolean
+ieee_void_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_push_type (info, (int) builtin_void, 0, false, false);
+}
+
+/* Make an integer type. */
+
+static boolean
+ieee_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int indx;
+
+ switch (size)
+ {
+ case 1:
+ indx = (int) builtin_signed_char;
+ break;
+ case 2:
+ indx = (int) builtin_signed_short_int;
+ break;
+ case 4:
+ indx = (int) builtin_signed_long;
+ break;
+ case 8:
+ indx = (int) builtin_signed_long_long;
+ break;
+ default:
+ fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size);
+ return false;
+ }
+
+ if (unsignedp)
+ ++indx;
+
+ return ieee_push_type (info, indx, size, unsignedp, false);
+}
+
+/* Make a floating point type. */
+
+static boolean
+ieee_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int indx;
+
+ switch (size)
+ {
+ case 4:
+ indx = (int) builtin_float;
+ break;
+ case 8:
+ indx = (int) builtin_double;
+ break;
+ case 12:
+ /* FIXME: This size really depends upon the processor. */
+ indx = (int) builtin_long_double;
+ break;
+ case 16:
+ indx = (int) builtin_long_long_double;
+ break;
+ default:
+ fprintf (stderr, _("IEEE unsupported float type size %u\n"), size);
+ return false;
+ }
+
+ return ieee_push_type (info, indx, size, false, false);
+}
+
+/* Make a complex type. */
+
+static boolean
+ieee_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ char code;
+
+ switch (size)
+ {
+ case 4:
+ if (info->complex_float_index != 0)
+ return ieee_push_type (info, info->complex_float_index, size * 2,
+ false, false);
+ code = 'c';
+ break;
+ case 12:
+ case 16:
+ /* These cases can be output by gcc -gstabs. Outputting the
+ wrong type is better than crashing. */
+ case 8:
+ if (info->complex_double_index != 0)
+ return ieee_push_type (info, info->complex_double_index, size * 2,
+ false, false);
+ code = 'd';
+ break;
+ default:
+ fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size);
+ return false;
+ }
+
+ /* FIXME: I don't know what the string is for. */
+ if (! ieee_define_type (info, size * 2, false, false)
+ || ! ieee_write_number (info, code)
+ || ! ieee_write_id (info, ""))
+ return false;
+
+ if (size == 4)
+ info->complex_float_index = info->type_stack->type.indx;
+ else
+ info->complex_double_index = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a boolean type. IEEE doesn't support these, so we just make
+ an integer type instead. */
+
+static boolean
+ieee_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ return ieee_int_type (p, size, true);
+}
+
+/* Make an enumeration. */
+
+static boolean
+ieee_enum_type (p, tag, names, vals)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *vals;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_defined_enum *e;
+ boolean localp, simple;
+ unsigned int indx;
+ int i = 0;
+
+ localp = false;
+ indx = (unsigned int) -1;
+ for (e = info->enums; e != NULL; e = e->next)
+ {
+ if (tag == NULL)
+ {
+ if (e->tag != NULL)
+ continue;
+ }
+ else
+ {
+ if (e->tag == NULL
+ || tag[0] != e->tag[0]
+ || strcmp (tag, e->tag) != 0)
+ continue;
+ }
+
+ if (! e->defined)
+ {
+ /* This enum tag has been seen but not defined. */
+ indx = e->indx;
+ break;
+ }
+
+ if (names != NULL && e->names != NULL)
+ {
+ for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
+ {
+ if (names[i][0] != e->names[i][0]
+ || vals[i] != e->vals[i]
+ || strcmp (names[i], e->names[i]) != 0)
+ break;
+ }
+ }
+
+ if ((names == NULL && e->names == NULL)
+ || (names != NULL
+ && e->names != NULL
+ && names[i] == NULL
+ && e->names[i] == NULL))
+ {
+ /* We've seen this enum before. */
+ return ieee_push_type (info, e->indx, 0, true, false);
+ }
+
+ if (tag != NULL)
+ {
+ /* We've already seen an enum of the same name, so we must make
+ sure to output this one locally. */
+ localp = true;
+ break;
+ }
+ }
+
+ /* If this is a simple enumeration, in which the values start at 0
+ and always increment by 1, we can use type E. Otherwise we must
+ use type N. */
+
+ simple = true;
+ if (names != NULL)
+ {
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (vals[i] != i)
+ {
+ simple = false;
+ break;
+ }
+ }
+ }
+
+ if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
+ (struct ieee_buflist *) NULL)
+ || ! ieee_write_number (info, simple ? 'E' : 'N'))
+ return false;
+ if (simple)
+ {
+ /* FIXME: This is supposed to be the enumeration size, but we
+ don't store that. */
+ if (! ieee_write_number (info, 4))
+ return false;
+ }
+ if (names != NULL)
+ {
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (! ieee_write_id (info, names[i]))
+ return false;
+ if (! simple)
+ {
+ if (! ieee_write_number (info, vals[i]))
+ return false;
+ }
+ }
+ }
+
+ if (! localp)
+ {
+ if (indx == (unsigned int) -1)
+ {
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+ e->indx = info->type_stack->type.indx;
+ e->tag = tag;
+
+ e->next = info->enums;
+ info->enums = e;
+ }
+
+ e->names = names;
+ e->vals = vals;
+ e->defined = true;
+ }
+
+ return true;
+}
+
+/* Make a pointer type. */
+
+static boolean
+ieee_pointer_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ /* A pointer to a simple builtin type can be obtained by adding 32.
+ FIXME: Will this be a short pointer, and will that matter? */
+ if (indx < 32)
+ return ieee_push_type (info, indx + 32, 0, true, false);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (p, indx);
+ if (m == NULL)
+ return false;
+
+ /* FIXME: The size should depend upon the architecture. */
+ if (m->pointer > 0)
+ return ieee_push_type (info, m->pointer, 4, true, false);
+ }
+
+ if (! ieee_define_type (info, 4, true, localp)
+ || ! ieee_write_number (info, 'P')
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->pointer = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a function type. This will be called for a method, but we
+ don't want to actually add it to the type table in that case. We
+ handle this by defining the type in a private buffer, and only
+ adding that buffer to the typedef block if we are going to use it. */
+
+static boolean
+ieee_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int *args = NULL;
+ int i;
+ unsigned int retindx;
+ struct ieee_buflist fndef;
+ struct ieee_modified_type *m;
+
+ localp = false;
+
+ if (argcount > 0)
+ {
+ args = (unsigned int *) xmalloc (argcount * sizeof *args);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (info->type_stack->type.localp)
+ localp = true;
+ args[i] = ieee_pop_type (info);
+ }
+ }
+ else if (argcount < 0)
+ varargs = false;
+
+ if (info->type_stack->type.localp)
+ localp = true;
+ retindx = ieee_pop_type (info);
+
+ m = NULL;
+ if (argcount < 0 && ! localp)
+ {
+ m = ieee_get_modified_info (p, retindx);
+ if (m == NULL)
+ return false;
+
+ if (m->function > 0)
+ return ieee_push_type (info, m->function, 0, true, false);
+ }
+
+ /* An attribute of 0x41 means that the frame and push mask are
+ unknown. */
+ if (! ieee_init_buffer (info, &fndef)
+ || ! ieee_define_named_type (info, (const char *) NULL,
+ (unsigned int) -1, 0, true, localp,
+ &fndef)
+ || ! ieee_write_number (info, 'x')
+ || ! ieee_write_number (info, 0x41)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, retindx)
+ || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
+ return false;
+ if (argcount > 0)
+ {
+ for (i = 0; i < argcount; i++)
+ if (! ieee_write_number (info, args[i]))
+ return false;
+ free (args);
+ }
+ if (varargs)
+ {
+ /* A varargs function is represented by writing out the last
+ argument as type void *, although this makes little sense. */
+ if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
+ return false;
+ }
+
+ if (! ieee_write_number (info, 0))
+ return false;
+
+ /* We wrote the information into fndef, in case we don't need it.
+ It will be appended to info->types by ieee_pop_type. */
+ info->type_stack->type.fndef = fndef;
+
+ if (m != NULL)
+ m->function = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a reference type. */
+
+static boolean
+ieee_reference_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* IEEE appears to record a normal pointer type, and then use a
+ pmisc record to indicate that it is really a reference. */
+
+ if (! ieee_pointer_type (p))
+ return false;
+ info->type_stack->type.referencep = true;
+ return true;
+}
+
+/* Make a range type. */
+
+static boolean
+ieee_range_type (p, low, high)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ ieee_pop_unused_type (info);
+ return (ieee_define_type (info, size, unsignedp, localp)
+ && ieee_write_number (info, 'R')
+ && ieee_write_number (info, (bfd_vma) low)
+ && ieee_write_number (info, (bfd_vma) high)
+ && ieee_write_number (info, unsignedp ? 0 : 1)
+ && ieee_write_number (info, size));
+}
+
+/* Make an array type. */
+
+/*ARGSUSED*/
+static boolean
+ieee_array_type (p, low, high, stringp)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+ boolean stringp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int eleindx;
+ boolean localp;
+ unsigned int size;
+ struct ieee_modified_type *m = NULL;
+ struct ieee_modified_array_type *a;
+
+ /* IEEE does not store the range, so we just ignore it. */
+ ieee_pop_unused_type (info);
+ localp = info->type_stack->type.localp;
+ size = info->type_stack->type.size;
+ eleindx = ieee_pop_type (info);
+
+ /* If we don't know the range, treat the size as exactly one
+ element. */
+ if (low < high)
+ size *= (high - low) + 1;
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, eleindx);
+ if (m == NULL)
+ return false;
+
+ for (a = m->arrays; a != NULL; a = a->next)
+ {
+ if (a->low == low && a->high == high)
+ return ieee_push_type (info, a->indx, size, false, false);
+ }
+ }
+
+ if (! ieee_define_type (info, size, false, localp)
+ || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
+ || ! ieee_write_number (info, eleindx))
+ return false;
+ if (low != 0)
+ {
+ if (! ieee_write_number (info, low))
+ return false;
+ }
+
+ if (! ieee_write_number (info, high + 1))
+ return false;
+
+ if (! localp)
+ {
+ a = (struct ieee_modified_array_type *) xmalloc (sizeof *a);
+ memset (a, 0, sizeof *a);
+
+ a->indx = info->type_stack->type.indx;
+ a->low = low;
+ a->high = high;
+
+ a->next = m->arrays;
+ m->arrays = a;
+ }
+
+ return true;
+}
+
+/* Make a set type. */
+
+static boolean
+ieee_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ unsigned int eleindx;
+
+ localp = info->type_stack->type.localp;
+ eleindx = ieee_pop_type (info);
+
+ /* FIXME: We don't know the size, so we just use 4. */
+
+ return (ieee_define_type (info, 0, true, localp)
+ && ieee_write_number (info, 's')
+ && ieee_write_number (info, 4)
+ && ieee_write_number (info, eleindx));
+}
+
+/* Make an offset type. */
+
+static boolean
+ieee_offset_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int targetindx, baseindx;
+
+ targetindx = ieee_pop_type (info);
+ baseindx = ieee_pop_type (info);
+
+ /* FIXME: The MRI C++ compiler does not appear to generate any
+ useful type information about an offset type. It just records a
+ pointer to member as an integer. The MRI/HP IEEE spec does
+ describe a pmisc record which can be used for a pointer to
+ member. Unfortunately, it does not describe the target type,
+ which seems pretty important. I'm going to punt this for now. */
+
+ return ieee_int_type (p, 4, true);
+}
+
+/* Make a method type. */
+
+static boolean
+ieee_method_type (p, domain, argcount, varargs)
+ PTR p;
+ boolean domain;
+ int argcount;
+ boolean varargs;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
+ method, but the definition is incomplete. We just output an 'x'
+ type. */
+
+ if (domain)
+ ieee_pop_unused_type (info);
+
+ return ieee_function_type (p, argcount, varargs);
+}
+
+/* Make a const qualified type. */
+
+static boolean
+ieee_const_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, indx);
+ if (m == NULL)
+ return false;
+
+ if (m->const_qualified > 0)
+ return ieee_push_type (info, m->const_qualified, size, unsignedp,
+ false);
+ }
+
+ if (! ieee_define_type (info, size, unsignedp, localp)
+ || ! ieee_write_number (info, 'n')
+ || ! ieee_write_number (info, 1)
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->const_qualified = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Make a volatile qualified type. */
+
+static boolean
+ieee_volatile_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp, localp;
+ unsigned int indx;
+ struct ieee_modified_type *m = NULL;
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (! localp)
+ {
+ m = ieee_get_modified_info (info, indx);
+ if (m == NULL)
+ return false;
+
+ if (m->volatile_qualified > 0)
+ return ieee_push_type (info, m->volatile_qualified, size, unsignedp,
+ false);
+ }
+
+ if (! ieee_define_type (info, size, unsignedp, localp)
+ || ! ieee_write_number (info, 'n')
+ || ! ieee_write_number (info, 2)
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ if (! localp)
+ m->volatile_qualified = info->type_stack->type.indx;
+
+ return true;
+}
+
+/* Convert an enum debug_visibility into a CXXFLAGS value. */
+
+static unsigned int
+ieee_vis_to_flags (visibility)
+ enum debug_visibility visibility;
+{
+ switch (visibility)
+ {
+ default:
+ abort ();
+ case DEBUG_VISIBILITY_PUBLIC:
+ return CXXFLAGS_VISIBILITY_PUBLIC;
+ case DEBUG_VISIBILITY_PRIVATE:
+ return CXXFLAGS_VISIBILITY_PRIVATE;
+ case DEBUG_VISIBILITY_PROTECTED:
+ return CXXFLAGS_VISIBILITY_PROTECTED;
+ }
+ /*NOTREACHED*/
+}
+
+/* Start defining a struct type. We build it in the strdef field on
+ the stack, to avoid confusing type definitions required by the
+ fields with the struct type itself. */
+
+static boolean
+ieee_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp, ignorep;
+ boolean copy;
+ char ab[20];
+ const char *look;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt, *ntlook;
+ struct ieee_buflist strdef;
+
+ localp = false;
+ ignorep = false;
+
+ /* We need to create a tag for internal use even if we don't want
+ one for external use. This will let us refer to an anonymous
+ struct. */
+ if (tag != NULL)
+ {
+ look = tag;
+ copy = false;
+ }
+ else
+ {
+ sprintf (ab, "__anon%u", id);
+ look = ab;
+ copy = true;
+ }
+
+ /* If we already have references to the tag, we must use the
+ existing type index. */
+ h = ieee_name_type_hash_lookup (&info->tags, look, true, copy);
+ if (h == NULL)
+ return false;
+
+ nt = NULL;
+ for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next)
+ {
+ if (ntlook->id == id)
+ nt = ntlook;
+ else if (! ntlook->type.localp)
+ {
+ /* We are creating a duplicate definition of a globally
+ defined tag. Force it to be local to avoid
+ confusion. */
+ localp = true;
+ }
+ }
+
+ if (nt != NULL)
+ {
+ assert (localp == nt->type.localp);
+ if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp)
+ {
+ /* We've already seen a global definition of the type.
+ Ignore this new definition. */
+ ignorep = true;
+ }
+ }
+ else
+ {
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+ nt->id = id;
+ nt->type.name = h->root.string;
+ nt->next = h->types;
+ h->types = nt;
+ nt->type.indx = info->type_indx;
+ ++info->type_indx;
+ }
+
+ nt->kind = DEBUG_KIND_ILLEGAL;
+
+ if (! ieee_init_buffer (info, &strdef)
+ || ! ieee_define_named_type (info, tag, nt->type.indx, size, true,
+ localp, &strdef)
+ || ! ieee_write_number (info, structp ? 'S' : 'U')
+ || ! ieee_write_number (info, size))
+ return false;
+
+ if (! ignorep)
+ {
+ const char *hold;
+
+ /* We never want nt->type.name to be NULL. We want the rest of
+ the type to be the object set up on the type stack; it will
+ have a NULL name if tag is NULL. */
+ hold = nt->type.name;
+ nt->type = info->type_stack->type;
+ nt->type.name = hold;
+ }
+
+ info->type_stack->type.name = tag;
+ info->type_stack->type.strdef = strdef;
+ info->type_stack->type.ignorep = ignorep;
+
+ return true;
+}
+
+/* Add a field to a struct. */
+
+static boolean
+ieee_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int size;
+ boolean unsignedp;
+ boolean referencep;
+ boolean localp;
+ unsigned int indx;
+ bfd_vma offset;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->next != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
+
+ /* If we are ignoring this struct definition, just pop and ignore
+ the type. */
+ if (info->type_stack->next->type.ignorep)
+ {
+ ieee_pop_unused_type (info);
+ return true;
+ }
+
+ size = info->type_stack->type.size;
+ unsignedp = info->type_stack->type.unsignedp;
+ referencep = info->type_stack->type.referencep;
+ localp = info->type_stack->type.localp;
+ indx = ieee_pop_type (info);
+
+ if (localp)
+ info->type_stack->type.localp = true;
+
+ if (info->type_stack->type.classdef != NULL)
+ {
+ unsigned int flags;
+ unsigned int nindx;
+
+ /* This is a class. We must add a description of this field to
+ the class records we are building. */
+
+ flags = ieee_vis_to_flags (visibility);
+ nindx = info->type_stack->type.classdef->indx;
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'd')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, name)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 4;
+
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ /* We need to output a record recording that this field is
+ really of reference type. We put this on the refs field
+ of classdef, so that it can be appended to the C++
+ records after the class is defined. */
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->refs)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 4)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, 3)
+ || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+ }
+
+ /* If the bitsize doesn't match the expected size, we need to output
+ a bitfield type. */
+ if (size == 0 || bitsize == 0 || bitsize == size * 8)
+ offset = bitpos / 8;
+ else
+ {
+ if (! ieee_define_type (info, 0, unsignedp,
+ info->type_stack->type.localp)
+ || ! ieee_write_number (info, 'g')
+ || ! ieee_write_number (info, unsignedp ? 0 : 1)
+ || ! ieee_write_number (info, bitsize)
+ || ! ieee_write_number (info, indx))
+ return false;
+ indx = ieee_pop_type (info);
+ offset = bitpos;
+ }
+
+ /* Switch to the struct we are building in order to output this
+ field definition. */
+ return (ieee_change_buffer (info, &info->type_stack->type.strdef)
+ && ieee_write_id (info, name)
+ && ieee_write_number (info, indx)
+ && ieee_write_number (info, offset));
+}
+
+/* Finish up a struct type. */
+
+static boolean
+ieee_end_struct_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_buflist *pb;
+
+ assert (info->type_stack != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->type.strdef));
+
+ /* If we were ignoring this struct definition because it was a
+ duplicate defintion, just through away whatever bytes we have
+ accumulated. Leave the type on the stack. */
+ if (info->type_stack->type.ignorep)
+ return true;
+
+ /* If this is not a duplicate definition of this tag, then localp
+ will be false, and we can put it in the global type block.
+ FIXME: We should avoid outputting duplicate definitions which are
+ the same. */
+ if (! info->type_stack->type.localp)
+ {
+ /* Make sure we have started the global type block. */
+ if (ieee_buffer_emptyp (&info->global_types))
+ {
+ if (! ieee_change_buffer (info, &info->global_types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 2)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ pb = &info->global_types;
+ }
+ else
+ {
+ /* Make sure we have started the types block. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+ pb = &info->types;
+ }
+
+ /* Append the struct definition to the types. */
+ if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef)
+ || ! ieee_init_buffer (info, &info->type_stack->type.strdef))
+ return false;
+
+ /* Leave the struct on the type stack. */
+
+ return true;
+}
+
+/* Start a class type. */
+
+static boolean
+ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *vclass;
+ struct ieee_buflist pmiscbuf;
+ unsigned int indx;
+ struct ieee_type_class *classdef;
+
+ /* A C++ class is output as a C++ struct along with a set of pmisc
+ records describing the class. */
+
+ /* We need to have a name so that we can associate the struct and
+ the class. */
+ if (tag == NULL)
+ {
+ char *t;
+
+ t = (char *) xmalloc (20);
+ sprintf (t, "__anon%u", id);
+ tag = t;
+ }
+
+ /* We can't write out the virtual table information until we have
+ finished the class, because we don't know the virtual table size.
+ We get the size from the largest voffset we see. */
+ vclass = NULL;
+ if (vptr && ! ownvptr)
+ {
+ vclass = info->type_stack->type.name;
+ assert (vclass != NULL);
+ /* We don't call ieee_pop_unused_type, since the class should
+ get defined. */
+ (void) ieee_pop_type (info);
+ }
+
+ if (! ieee_start_struct_type (p, tag, id, structp, size))
+ return false;
+
+ indx = info->name_indx;
+ ++info->name_indx;
+
+ /* We write out pmisc records into the classdef field. We will
+ write out the pmisc start after we know the number of records we
+ need. */
+ if (! ieee_init_buffer (info, &pmiscbuf)
+ || ! ieee_change_buffer (info, &pmiscbuf)
+ || ! ieee_write_asn (info, indx, 'T')
+ || ! ieee_write_asn (info, indx, structp ? 'o' : 'u')
+ || ! ieee_write_atn65 (info, indx, tag))
+ return false;
+
+ classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef);
+ memset (classdef, 0, sizeof *classdef);
+
+ classdef->indx = indx;
+ classdef->pmiscbuf = pmiscbuf;
+ classdef->pmisccount = 3;
+ classdef->vclass = vclass;
+ classdef->ownvptr = ownvptr;
+
+ info->type_stack->type.classdef = classdef;
+
+ return true;
+}
+
+/* Add a static member to a class. */
+
+static boolean
+ieee_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int flags;
+ unsigned int nindx;
+
+ /* We don't care about the type. Hopefully there will be a call to
+ ieee_variable declaring the physical name and the type, since
+ that is where an IEEE consumer must get the type. */
+ ieee_pop_unused_type (info);
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL);
+
+ flags = ieee_vis_to_flags (visibility);
+ flags |= CXXFLAGS_STATIC;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'd')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, name)
+ || ! ieee_write_atn65 (info, nindx, physname))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 4;
+
+ return true;
+}
+
+/* Add a base class to a class. */
+
+static boolean
+ieee_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ const char *bname;
+ boolean localp;
+ unsigned int bindx;
+ char *fname;
+ unsigned int flags;
+ unsigned int nindx;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.name != NULL
+ && info->type_stack->next != NULL
+ && info->type_stack->next->type.classdef != NULL
+ && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
+
+ bname = info->type_stack->type.name;
+ localp = info->type_stack->type.localp;
+ bindx = ieee_pop_type (info);
+
+ /* We are currently defining both a struct and a class. We must
+ write out a field definition in the struct which holds the base
+ class. The stabs debugging reader will create a field named
+ _vb$CLASS for a virtual base class, so we just use that. FIXME:
+ we should not depend upon a detail of stabs debugging. */
+ if (virtual)
+ {
+ fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$");
+ sprintf (fname, "_vb$%s", bname);
+ flags = BASEFLAGS_VIRTUAL;
+ }
+ else
+ {
+ if (localp)
+ info->type_stack->type.localp = true;
+
+ fname = (char *) xmalloc (strlen (bname) + sizeof "_b$");
+ sprintf (fname, "_b$%s", bname);
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.strdef)
+ || ! ieee_write_id (info, fname)
+ || ! ieee_write_number (info, bindx)
+ || ! ieee_write_number (info, bitpos / 8))
+ return false;
+ flags = 0;
+ }
+
+ if (visibility == DEBUG_VISIBILITY_PRIVATE)
+ flags |= BASEFLAGS_PRIVATE;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'b')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx, bname)
+ || ! ieee_write_asn (info, nindx, 0)
+ || ! ieee_write_atn65 (info, nindx, fname))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 5;
+
+ free (fname);
+
+ return true;
+}
+
+/* Start building a method for a class. */
+
+static boolean
+ieee_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method == NULL);
+
+ info->type_stack->type.classdef->method = name;
+
+ return true;
+}
+
+/* Define a new method variant, either static or not. */
+
+static boolean
+ieee_class_method_var (info, physname, visibility, staticp, constp,
+ volatilep, voffset, context)
+ struct ieee_handle *info;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean staticp;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ unsigned int flags;
+ unsigned int nindx;
+ boolean virtual;
+
+ /* We don't need the type of the method. An IEEE consumer which
+ wants the type must track down the function by the physical name
+ and get the type from that. */
+ ieee_pop_unused_type (info);
+
+ /* We don't use the context. FIXME: We probably ought to use it to
+ adjust the voffset somehow, but I don't really know how. */
+ if (context)
+ ieee_pop_unused_type (info);
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method != NULL);
+
+ flags = ieee_vis_to_flags (visibility);
+
+ /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR,
+ CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */
+
+ if (staticp)
+ flags |= CXXFLAGS_STATIC;
+ if (constp)
+ flags |= CXXFLAGS_CONST;
+ if (volatilep)
+ flags |= CXXFLAGS_VOLATILE;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ virtual = context || voffset > 0;
+
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm')
+ || ! ieee_write_asn (info, nindx, flags)
+ || ! ieee_write_atn65 (info, nindx,
+ info->type_stack->type.classdef->method)
+ || ! ieee_write_atn65 (info, nindx, physname))
+ return false;
+
+ if (virtual)
+ {
+ if (voffset > info->type_stack->type.classdef->voffset)
+ info->type_stack->type.classdef->voffset = voffset;
+ if (! ieee_write_asn (info, nindx, voffset))
+ return false;
+ ++info->type_stack->type.classdef->pmisccount;
+ }
+
+ if (! ieee_write_asn (info, nindx, 0))
+ return false;
+
+ info->type_stack->type.classdef->pmisccount += 5;
+
+ return true;
+}
+
+/* Define a new method variant. */
+
+static boolean
+ieee_class_method_variant (p, physname, visibility, constp, volatilep,
+ voffset, context)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_class_method_var (info, physname, visibility, false, constp,
+ volatilep, voffset, context);
+}
+
+/* Define a new static method variant. */
+
+static boolean
+ieee_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ return ieee_class_method_var (info, physname, visibility, true, constp,
+ volatilep, 0, false);
+}
+
+/* Finish up a method. */
+
+static boolean
+ieee_class_end_method (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL
+ && info->type_stack->type.classdef->method != NULL);
+
+ info->type_stack->type.classdef->method = NULL;
+
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+ieee_end_class_type (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int nindx;
+
+ assert (info->type_stack != NULL
+ && info->type_stack->type.classdef != NULL);
+
+ /* If we were ignoring this class definition because it was a
+ duplicate definition, just through away whatever bytes we have
+ accumulated. Leave the type on the stack. */
+ if (info->type_stack->type.ignorep)
+ return true;
+
+ nindx = info->type_stack->type.classdef->indx;
+
+ /* If we have a virtual table, we can write out the information now. */
+ if (info->type_stack->type.classdef->vclass != NULL
+ || info->type_stack->type.classdef->ownvptr)
+ {
+ if (! ieee_change_buffer (info,
+ &info->type_stack->type.classdef->pmiscbuf)
+ || ! ieee_write_asn (info, nindx, 'z')
+ || ! ieee_write_atn65 (info, nindx, "")
+ || ! ieee_write_asn (info, nindx,
+ info->type_stack->type.classdef->voffset))
+ return false;
+ if (info->type_stack->type.classdef->ownvptr)
+ {
+ if (! ieee_write_atn65 (info, nindx, ""))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_atn65 (info, nindx,
+ info->type_stack->type.classdef->vclass))
+ return false;
+ }
+ if (! ieee_write_asn (info, nindx, 0))
+ return false;
+ info->type_stack->type.classdef->pmisccount += 5;
+ }
+
+ /* Now that we know the number of pmisc records, we can write out
+ the atn62 which starts the pmisc records, and append them to the
+ C++ buffers. */
+
+ if (! ieee_change_buffer (info, &info->cxx)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info,
+ info->type_stack->type.classdef->pmisccount))
+ return false;
+
+ if (! ieee_append_buffer (info, &info->cxx,
+ &info->type_stack->type.classdef->pmiscbuf))
+ return false;
+ if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs))
+ {
+ if (! ieee_append_buffer (info, &info->cxx,
+ &info->type_stack->type.classdef->refs))
+ return false;
+ }
+
+ return ieee_end_struct_type (p);
+}
+
+/* Push a previously seen typedef onto the type stack. */
+
+static boolean
+ieee_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false);
+
+ /* h should never be NULL, since that would imply that the generic
+ debugging code has asked for a typedef which it has not yet
+ defined. */
+ assert (h != NULL);
+
+ /* We always use the most recently defined type for this name, which
+ will be the first one on the list. */
+
+ nt = h->types;
+ if (! ieee_push_type (info, nt->type.indx, nt->type.size,
+ nt->type.unsignedp, nt->type.localp))
+ return false;
+
+ /* Copy over any other type information we may have. */
+ info->type_stack->type = nt->type;
+
+ return true;
+}
+
+/* Push a tagged type onto the type stack. */
+
+static boolean
+ieee_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean localp;
+ boolean copy;
+ char ab[20];
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ if (kind == DEBUG_KIND_ENUM)
+ {
+ struct ieee_defined_enum *e;
+
+ if (name == NULL)
+ abort ();
+ for (e = info->enums; e != NULL; e = e->next)
+ if (e->tag != NULL && strcmp (e->tag, name) == 0)
+ return ieee_push_type (info, e->indx, 0, true, false);
+
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->indx = info->type_indx;
+ ++info->type_indx;
+ e->tag = name;
+ e->defined = false;
+
+ e->next = info->enums;
+ info->enums = e;
+
+ return ieee_push_type (info, e->indx, 0, true, false);
+ }
+
+ localp = false;
+
+ copy = false;
+ if (name == NULL)
+ {
+ sprintf (ab, "__anon%u", id);
+ name = ab;
+ copy = true;
+ }
+
+ h = ieee_name_type_hash_lookup (&info->tags, name, true, copy);
+ if (h == NULL)
+ return false;
+
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ if (nt->id == id)
+ {
+ if (! ieee_push_type (info, nt->type.indx, nt->type.size,
+ nt->type.unsignedp, nt->type.localp))
+ return false;
+ /* Copy over any other type information we may have. */
+ info->type_stack->type = nt->type;
+ return true;
+ }
+
+ if (! nt->type.localp)
+ {
+ /* This is a duplicate of a global type, so it must be
+ local. */
+ localp = true;
+ }
+ }
+
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+
+ nt->id = id;
+ nt->type.name = h->root.string;
+ nt->type.indx = info->type_indx;
+ nt->type.localp = localp;
+ ++info->type_indx;
+ nt->kind = kind;
+
+ nt->next = h->types;
+ h->types = nt;
+
+ if (! ieee_push_type (info, nt->type.indx, 0, false, localp))
+ return false;
+
+ info->type_stack->type.name = h->root.string;
+
+ return true;
+}
+
+/* Output a typedef. */
+
+static boolean
+ieee_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_write_type type;
+ unsigned int indx;
+ boolean found;
+ boolean localp;
+ struct ieee_name_type_hash_entry *h;
+ struct ieee_name_type *nt;
+
+ type = info->type_stack->type;
+ indx = type.indx;
+
+ /* If this is a simple builtin type using a builtin name, we don't
+ want to output the typedef itself. We also want to change the
+ type index to correspond to the name being used. We recognize
+ names used in stabs debugging output even if they don't exactly
+ correspond to the names used for the IEEE builtin types. */
+ found = false;
+ if (indx <= (unsigned int) builtin_bcd_float)
+ {
+ switch ((enum builtin_types) indx)
+ {
+ default:
+ break;
+
+ case builtin_void:
+ if (strcmp (name, "void") == 0)
+ found = true;
+ break;
+
+ case builtin_signed_char:
+ case builtin_char:
+ if (strcmp (name, "signed char") == 0)
+ {
+ indx = (unsigned int) builtin_signed_char;
+ found = true;
+ }
+ else if (strcmp (name, "char") == 0)
+ {
+ indx = (unsigned int) builtin_char;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_char:
+ if (strcmp (name, "unsigned char") == 0)
+ found = true;
+ break;
+
+ case builtin_signed_short_int:
+ case builtin_short:
+ case builtin_short_int:
+ case builtin_signed_short:
+ if (strcmp (name, "signed short int") == 0)
+ {
+ indx = (unsigned int) builtin_signed_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "short") == 0)
+ {
+ indx = (unsigned int) builtin_short;
+ found = true;
+ }
+ else if (strcmp (name, "short int") == 0)
+ {
+ indx = (unsigned int) builtin_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "signed short") == 0)
+ {
+ indx = (unsigned int) builtin_signed_short;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_short_int:
+ case builtin_unsigned_short:
+ if (strcmp (name, "unsigned short int") == 0
+ || strcmp (name, "short unsigned int") == 0)
+ {
+ indx = builtin_unsigned_short_int;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned short") == 0)
+ {
+ indx = builtin_unsigned_short;
+ found = true;
+ }
+ break;
+
+ case builtin_signed_long:
+ case builtin_int: /* FIXME: Size depends upon architecture. */
+ case builtin_long:
+ if (strcmp (name, "signed long") == 0)
+ {
+ indx = builtin_signed_long;
+ found = true;
+ }
+ else if (strcmp (name, "int") == 0)
+ {
+ indx = builtin_int;
+ found = true;
+ }
+ else if (strcmp (name, "long") == 0
+ || strcmp (name, "long int") == 0)
+ {
+ indx = builtin_long;
+ found = true;
+ }
+ break;
+
+ case builtin_unsigned_long:
+ case builtin_unsigned: /* FIXME: Size depends upon architecture. */
+ case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */
+ if (strcmp (name, "unsigned long") == 0
+ || strcmp (name, "long unsigned int") == 0)
+ {
+ indx = builtin_unsigned_long;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned") == 0)
+ {
+ indx = builtin_unsigned;
+ found = true;
+ }
+ else if (strcmp (name, "unsigned int") == 0)
+ {
+ indx = builtin_unsigned_int;
+ found = true;
+ }
+ break;
+
+ case builtin_signed_long_long:
+ if (strcmp (name, "signed long long") == 0
+ || strcmp (name, "long long int") == 0)
+ found = true;
+ break;
+
+ case builtin_unsigned_long_long:
+ if (strcmp (name, "unsigned long long") == 0
+ || strcmp (name, "long long unsigned int") == 0)
+ found = true;
+ break;
+
+ case builtin_float:
+ if (strcmp (name, "float") == 0)
+ found = true;
+ break;
+
+ case builtin_double:
+ if (strcmp (name, "double") == 0)
+ found = true;
+ break;
+
+ case builtin_long_double:
+ if (strcmp (name, "long double") == 0)
+ found = true;
+ break;
+
+ case builtin_long_long_double:
+ if (strcmp (name, "long long double") == 0)
+ found = true;
+ break;
+ }
+
+ if (found)
+ type.indx = indx;
+ }
+
+ h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false);
+ if (h == NULL)
+ return false;
+
+ /* See if we have already defined this type with this name. */
+ localp = type.localp;
+ for (nt = h->types; nt != NULL; nt = nt->next)
+ {
+ if (nt->id == indx)
+ {
+ /* If this is a global definition, then we don't need to
+ do anything here. */
+ if (! nt->type.localp)
+ {
+ ieee_pop_unused_type (info);
+ return true;
+ }
+ }
+ else
+ {
+ /* This is a duplicate definition, so make this one local. */
+ localp = true;
+ }
+ }
+
+ /* We need to add a new typedef for this type. */
+
+ nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
+ memset (nt, 0, sizeof *nt);
+ nt->id = indx;
+ nt->type = type;
+ nt->type.name = name;
+ nt->type.localp = localp;
+ nt->kind = DEBUG_KIND_ILLEGAL;
+
+ nt->next = h->types;
+ h->types = nt;
+
+ if (found)
+ {
+ /* This is one of the builtin typedefs, so we don't need to
+ actually define it. */
+ ieee_pop_unused_type (info);
+ return true;
+ }
+
+ indx = ieee_pop_type (info);
+
+ if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size,
+ type.unsignedp, localp,
+ (struct ieee_buflist *) NULL)
+ || ! ieee_write_number (info, 'T')
+ || ! ieee_write_number (info, indx))
+ return false;
+
+ /* Remove the type we just added to the type stack. This should not
+ be ieee_pop_unused_type, since the type is used, we just don't
+ need it now. */
+ (void) ieee_pop_type (info);
+
+ return true;
+}
+
+/* Output a tag for a type. We don't have to do anything here. */
+
+static boolean
+ieee_tag (p, name)
+ PTR p;
+ const char *name;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* This should not be ieee_pop_unused_type, since we want the type
+ to be defined. */
+ (void) ieee_pop_type (info);
+ return true;
+}
+
+/* Output an integer constant. */
+
+static boolean
+ieee_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ /* FIXME. */
+ return true;
+}
+
+/* Output a floating point constant. */
+
+static boolean
+ieee_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+ /* FIXME. */
+ return true;
+}
+
+/* Output a typed constant. */
+
+static boolean
+ieee_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* FIXME. */
+ ieee_pop_unused_type (info);
+ return true;
+}
+
+/* Output a variable. */
+
+static boolean
+ieee_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ unsigned int name_indx;
+ unsigned int size;
+ boolean referencep;
+ unsigned int type_indx;
+ boolean asn;
+ int refflag;
+
+ size = info->type_stack->type.size;
+ referencep = info->type_stack->type.referencep;
+ type_indx = ieee_pop_type (info);
+
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ name_indx = info->name_indx;
+ ++info->name_indx;
+
+ /* Write out an NN and an ATN record for this variable. */
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_id (info, name)
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, name_indx)
+ || ! ieee_write_number (info, type_indx))
+ return false;
+ switch (kind)
+ {
+ default:
+ abort ();
+ return false;
+ case DEBUG_GLOBAL:
+ if (! ieee_write_number (info, 8)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 0;
+ asn = true;
+ break;
+ case DEBUG_STATIC:
+ if (! ieee_write_number (info, 3)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 1;
+ asn = true;
+ break;
+ case DEBUG_LOCAL_STATIC:
+ if (! ieee_write_number (info, 3)
+ || ! ieee_add_range (info, false, val, val + size))
+ return false;
+ refflag = 2;
+ asn = true;
+ break;
+ case DEBUG_LOCAL:
+ if (! ieee_write_number (info, 1)
+ || ! ieee_write_number (info, val))
+ return false;
+ refflag = 2;
+ asn = false;
+ break;
+ case DEBUG_REGISTER:
+ if (! ieee_write_number (info, 2)
+ || ! ieee_write_number (info,
+ ieee_genreg_to_regno (info->abfd, val)))
+ return false;
+ refflag = 2;
+ asn = false;
+ break;
+ }
+
+ if (asn)
+ {
+ if (! ieee_write_asn (info, name_indx, val))
+ return false;
+ }
+
+ /* If this is really a reference type, then we just output it with
+ pointer type, and must now output a C++ record indicating that it
+ is really reference type. */
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+
+ /* If this is a global variable, we want to output the misc
+ record in the C++ misc record block. Otherwise, we want to
+ output it just after the variable definition, which is where
+ the current buffer is. */
+ if (refflag != 2)
+ {
+ if (! ieee_change_buffer (info, &info->cxx))
+ return false;
+ }
+
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 3)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, refflag)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+
+ return true;
+}
+
+/* Start outputting information for a function. */
+
+static boolean
+ieee_start_function (p, name, global)
+ PTR p;
+ const char *name;
+ boolean global;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ boolean referencep;
+ unsigned int retindx, typeindx;
+
+ referencep = info->type_stack->type.referencep;
+ retindx = ieee_pop_type (info);
+
+ /* Besides recording a BB4 or BB6 block, we record the type of the
+ function in the BB1 typedef block. We can't write out the full
+ type until we have seen all the parameters, so we accumulate it
+ in info->fntype and info->fnargs. */
+ if (! ieee_buffer_emptyp (&info->fntype))
+ {
+ /* FIXME: This might happen someday if we support nested
+ functions. */
+ abort ();
+ }
+
+ info->fnname = name;
+
+ /* An attribute of 0x40 means that the push mask is unknown. */
+ if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true,
+ &info->fntype)
+ || ! ieee_write_number (info, 'x')
+ || ! ieee_write_number (info, 0x40)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, retindx))
+ return false;
+
+ typeindx = ieee_pop_type (info);
+
+ if (! ieee_init_buffer (info, &info->fnargs))
+ return false;
+ info->fnargcount = 0;
+
+ /* If the function return value is actually a reference type, we
+ must add a record indicating that. */
+ if (referencep)
+ {
+ unsigned int nindx;
+
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->cxx)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, 3)
+ || ! ieee_write_asn (info, nindx, 'R')
+ || ! ieee_write_asn (info, nindx, global ? 0 : 1)
+ || ! ieee_write_atn65 (info, nindx, name))
+ return false;
+ }
+
+ assert (! ieee_buffer_emptyp (&info->vars));
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ /* The address is written out as the first block. */
+
+ ++info->block_depth;
+
+ return (ieee_write_byte (info, (int) ieee_bb_record_enum)
+ && ieee_write_byte (info, global ? 4 : 6)
+ && ieee_write_number (info, 0)
+ && ieee_write_id (info, name)
+ && ieee_write_number (info, 0)
+ && ieee_write_number (info, typeindx));
+}
+
+/* Add a function parameter. This will normally be called before the
+ first block, so we postpone them until we see the block. */
+
+static boolean
+ieee_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+ struct ieee_pending_parm *m, **pm;
+
+ assert (info->block_depth == 1);
+
+ m = (struct ieee_pending_parm *) xmalloc (sizeof *m);
+ memset (m, 0, sizeof *m);
+
+ m->next = NULL;
+ m->name = name;
+ m->referencep = info->type_stack->type.referencep;
+ m->type = ieee_pop_type (info);
+ m->kind = kind;
+ m->val = val;
+
+ for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next)
+ ;
+ *pm = m;
+
+ /* Add the type to the fnargs list. */
+ if (! ieee_change_buffer (info, &info->fnargs)
+ || ! ieee_write_number (info, m->type))
+ return false;
+ ++info->fnargcount;
+
+ return true;
+}
+
+/* Output pending function parameters. */
+
+static boolean
+ieee_output_pending_parms (info)
+ struct ieee_handle *info;
+{
+ struct ieee_pending_parm *m;
+ unsigned int refcount;
+
+ refcount = 0;
+ for (m = info->pending_parms; m != NULL; m = m->next)
+ {
+ enum debug_var_kind vkind;
+
+ switch (m->kind)
+ {
+ default:
+ abort ();
+ return false;
+ case DEBUG_PARM_STACK:
+ case DEBUG_PARM_REFERENCE:
+ vkind = DEBUG_LOCAL;
+ break;
+ case DEBUG_PARM_REG:
+ case DEBUG_PARM_REF_REG:
+ vkind = DEBUG_REGISTER;
+ break;
+ }
+
+ if (! ieee_push_type (info, m->type, 0, false, false))
+ return false;
+ info->type_stack->type.referencep = m->referencep;
+ if (m->referencep)
+ ++refcount;
+ if (! ieee_variable ((PTR) info, m->name, vkind, m->val))
+ return false;
+ }
+
+ /* If there are any reference parameters, we need to output a
+ miscellaneous record indicating them. */
+ if (refcount > 0)
+ {
+ unsigned int nindx, varindx;
+
+ /* FIXME: The MRI compiler outputs the demangled function name
+ here, but we are outputting the mangled name. */
+ nindx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, nindx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 62)
+ || ! ieee_write_number (info, 80)
+ || ! ieee_write_number (info, refcount + 3)
+ || ! ieee_write_asn (info, nindx, 'B')
+ || ! ieee_write_atn65 (info, nindx, info->fnname)
+ || ! ieee_write_asn (info, nindx, 0))
+ return false;
+ for (m = info->pending_parms, varindx = 1;
+ m != NULL;
+ m = m->next, varindx++)
+ {
+ if (m->referencep)
+ {
+ if (! ieee_write_asn (info, nindx, varindx))
+ return false;
+ }
+ }
+ }
+
+ m = info->pending_parms;
+ while (m != NULL)
+ {
+ struct ieee_pending_parm *next;
+
+ next = m->next;
+ free (m);
+ m = next;
+ }
+
+ info->pending_parms = NULL;
+
+ return true;
+}
+
+/* Start a block. If this is the first block, we output the address
+ to finish the BB4 or BB6, and then output the function parameters. */
+
+static boolean
+ieee_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ if (! ieee_change_buffer (info, &info->vars))
+ return false;
+
+ if (info->block_depth == 1)
+ {
+ if (! ieee_write_number (info, addr)
+ || ! ieee_output_pending_parms (info))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 6)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, "")
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, addr))
+ return false;
+ }
+
+ if (! ieee_start_range (info, addr))
+ return false;
+
+ ++info->block_depth;
+
+ return true;
+}
+
+/* End a block. */
+
+static boolean
+ieee_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ /* The address we are given is the end of the block, but IEEE seems
+ to want to the address of the last byte in the block, so we
+ subtract one. */
+ if (! ieee_change_buffer (info, &info->vars)
+ || ! ieee_write_byte (info, (int) ieee_be_record_enum)
+ || ! ieee_write_number (info, addr - 1))
+ return false;
+
+ if (! ieee_end_range (info, addr))
+ return false;
+
+ --info->block_depth;
+
+ if (addr > info->highaddr)
+ info->highaddr = addr;
+
+ return true;
+}
+
+/* End a function. */
+
+static boolean
+ieee_end_function (p)
+ PTR p;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->block_depth == 1);
+
+ --info->block_depth;
+
+ /* Now we can finish up fntype, and add it to the typdef section.
+ At this point, fntype is the 'x' type up to the argument count,
+ and fnargs is the argument types. We must add the argument
+ count, and we must add the level. FIXME: We don't record varargs
+ functions correctly. In fact, stabs debugging does not give us
+ enough information to do so. */
+ if (! ieee_change_buffer (info, &info->fntype)
+ || ! ieee_write_number (info, info->fnargcount)
+ || ! ieee_change_buffer (info, &info->fnargs)
+ || ! ieee_write_number (info, 0))
+ return false;
+
+ /* Make sure the typdef block has been started. */
+ if (ieee_buffer_emptyp (&info->types))
+ {
+ if (! ieee_change_buffer (info, &info->types)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 1)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->modname))
+ return false;
+ }
+
+ if (! ieee_append_buffer (info, &info->types, &info->fntype)
+ || ! ieee_append_buffer (info, &info->types, &info->fnargs))
+ return false;
+
+ info->fnname = NULL;
+ if (! ieee_init_buffer (info, &info->fntype)
+ || ! ieee_init_buffer (info, &info->fnargs))
+ return false;
+ info->fnargcount = 0;
+
+ return true;
+}
+
+/* Record line number information. */
+
+static boolean
+ieee_lineno (p, filename, lineno, addr)
+ PTR p;
+ const char *filename;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct ieee_handle *info = (struct ieee_handle *) p;
+
+ assert (info->filename != NULL);
+
+ /* The HP simulator seems to get confused when more than one line is
+ listed for the same address, at least if they are in different
+ files. We handle this by always listing the last line for a
+ given address, since that seems to be the one that gdb uses. */
+ if (info->pending_lineno_filename != NULL
+ && addr != info->pending_lineno_addr)
+ {
+ /* Make sure we have a line number block. */
+ if (! ieee_buffer_emptyp (&info->linenos))
+ {
+ if (! ieee_change_buffer (info, &info->linenos))
+ return false;
+ }
+ else
+ {
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_change_buffer (info, &info->linenos)
+ || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 5)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->filename)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ info->lineno_filename = info->filename;
+ }
+
+ if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0)
+ {
+ if (strcmp (info->filename, info->lineno_filename) != 0)
+ {
+ /* We were not in the main file. Close the block for the
+ included file. */
+ if (! ieee_write_byte (info, (int) ieee_be_record_enum))
+ return false;
+ if (strcmp (info->filename, info->pending_lineno_filename) == 0)
+ {
+ /* We need a new NN record, and we aren't about to
+ output one. */
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ }
+ if (strcmp (info->filename, info->pending_lineno_filename) != 0)
+ {
+ /* We are not changing to the main file. Open a block for
+ the new included file. */
+ info->lineno_name_indx = info->name_indx;
+ ++info->name_indx;
+ if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
+ || ! ieee_write_byte (info, 5)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_id (info, info->pending_lineno_filename)
+ || ! ieee_write_byte (info, (int) ieee_nn_record)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_id (info, ""))
+ return false;
+ }
+ info->lineno_filename = info->pending_lineno_filename;
+ }
+
+ if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
+ || ! ieee_write_number (info, info->lineno_name_indx)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_number (info, 7)
+ || ! ieee_write_number (info, info->pending_lineno)
+ || ! ieee_write_number (info, 0)
+ || ! ieee_write_asn (info, info->lineno_name_indx,
+ info->pending_lineno_addr))
+ return false;
+ }
+
+ info->pending_lineno_filename = filename;
+ info->pending_lineno = lineno;
+ info->pending_lineno_addr = addr;
+
+ return true;
+}
diff --git a/binutils/is-ranlib.c b/binutils/is-ranlib.c
new file mode 100644
index 00000000000..fde72a43da5
--- /dev/null
+++ b/binutils/is-ranlib.c
@@ -0,0 +1,3 @@
+/* Linked with ar.o to flag that this program is 'ranlib' (not 'ar'). */
+
+int is_ranlib = 1;
diff --git a/binutils/is-strip.c b/binutils/is-strip.c
new file mode 100644
index 00000000000..215341a325c
--- /dev/null
+++ b/binutils/is-strip.c
@@ -0,0 +1,4 @@
+/* Linked with objcopy.o to flag that this program is 'strip' (not
+ 'objcopy'). */
+
+int is_strip = 1;
diff --git a/binutils/mac-binutils.r b/binutils/mac-binutils.r
new file mode 100644
index 00000000000..7b1a3035e28
--- /dev/null
+++ b/binutils/mac-binutils.r
@@ -0,0 +1,42 @@
+/* Resources for GNU binutils. */
+
+#include "SysTypes.r"
+
+/* Version resources. */
+
+resource 'vers' (1) {
+ 0,
+ 0,
+ 0,
+ 0,
+ verUs,
+ VERSION_STRING,
+ VERSION_STRING " (C) 1986-95 FSF, Inc."
+};
+
+resource 'vers' (2, purgeable) {
+ 0,
+ 0,
+ 0,
+ 0,
+ verUs,
+ VERSION_STRING,
+ "binutils " VERSION_STRING " for MPW"
+};
+
+#ifdef WANT_CFRG
+
+#include "CodeFragmentTypes.r"
+
+resource 'cfrg' (0) {
+ {
+ kPowerPC,
+ kFullLib,
+ kNoVersionNum, kNoVersionNum,
+ 0,0,
+ kIsApp, kOnDiskFlat, kZeroOffset, kWholeFork,
+ PROG_NAME
+ }
+};
+
+#endif /* WANT_CFRG */
diff --git a/binutils/makefile.vms-in b/binutils/makefile.vms-in
new file mode 100644
index 00000000000..a809d1b13cd
--- /dev/null
+++ b/binutils/makefile.vms-in
@@ -0,0 +1,98 @@
+#
+# Makefile for binutils under openVMS (Alpha and Vax)
+#
+# For use with gnu-make for vms
+#
+# Created by Klaus K"ampf, kkaempf@rmi.de
+#
+#
+
+# Distribution version, filled in by configure.com
+VERSION=@VERSION@
+
+ifeq ($(ARCH),ALPHA)
+TARGET=""vms-alpha""
+else
+TARGET=""vms-vax""
+endif
+
+ifeq ($(CC),gcc)
+CFLAGS=/include=([],[-.include],[-.bfd])$(DEFS)
+DEFS=/define=("TARGET=$(TARGET)")
+LIBS=,gnu_cc_library:libgcc/lib,sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crt0.obj
+else
+CFLAGS=/noopt/debug/include=([],[-.include],[-.bfd])$(DEFS)\
+/warnings=disable=(missingreturn,implicitfunc,longextern)
+DEFS=/define=("TARGET=$(TARGET)","const=","unlink=remove")
+LIBS=,sys$$library:vaxcrtl.olb/lib
+endif
+
+BFDLIB = [-.bfd]libbfd.olb/lib
+BFDLIB_DEP = [-.bfd]libbfd.olb
+LIBIBERTY_DEP = [-.libiberty]libiberty.olb
+LIBIBERTY = [-.libiberty]libiberty.olb/lib
+OPCODES_DEP = [-.opcodes]libopcodes.olb
+OPCODES = [-.opcodes]libopcodes.olb/lib
+
+DEBUG_OBJS = rddbg.obj,debug.obj,stabs.obj,ieee.obj,rdcoff.obj
+
+WRITE_DEBUG_OBJS = $(DEBUG_OBJS),wrstabs.obj
+
+BULIBS = []bucomm.obj,version.obj,filemode.obj
+
+ADDL_DEPS = $(BULIBS),$(BFDLIB_DEP),$(LIBIBERTY_DEP)
+ADDL_LIBS = $(BULIBS),$(BFDLIB),$(LIBIBERTY)
+
+SIZEOBJS = $(ADDL_DEPS),size.obj
+
+STRINGSOBJS = $(ADDL_DEPS),strings.obj
+
+NMOBJS = $(ADDL_DEPS),nm.obj
+
+OBJDUMPOBJS = $(ADDL_DEPS),objdump.obj,prdbg.obj,$(DEBUG_OBJS),$(OPCODES_DEP)
+
+all: config.h size.exe strings.exe objdump.exe nm.exe
+
+size.exe: $(SIZEOBJS)
+ link/exe=$@ size.obj,$(ADDL_LIBS)$(LIBS)
+
+strings.exe: $(STRINGSOBJS)
+ link/exe=$@ strings.obj,$(ADDL_LIBS)$(LIBS)
+
+nm.exe: $(NMOBJS)
+ link/exe=$@ nm.obj,$(ADDL_LIBS)$(LIBS)
+
+objdump.exe: $(OBJDUMPOBJS)
+ link/exe=$@ objdump.obj,prdbg.obj,$(DEBUG_OBJS),$(BFDLIB),$(OPCODES),$(ADDL_LIBS)$(LIBS)
+
+
+version.obj: version.c
+ $(CC) $(CFLAGS)/define=(VERSION="""$(VERSION)""") $<
+
+config.h:
+ $$ @configure
+ $(MAKE) -f makefile.vms "CC=$(CC)"
+
+[-.bfd]libbfd.olb:
+ $(CD) [-.bfd]
+ $(MAKE) -f makefile.vms "CC=$(CC)"
+ $(CD) [-.binutils]
+
+[-.libiberty]libiberty.olb:
+ $(CD) [-.libiberty]
+ $(MAKE) -f makefile.vms "CC=$(CC)"
+ $(CD) [-.binutils]
+
+[-.opcodes]libopcodes.olb:
+ $(CD) [-.opcodes]
+ $(MAKE) -f makefile.vms "CC=$(CC)"
+ $(CD) [-.binutils]
+
+clean:
+ $$ purge
+ $(RM) *.obj;
+ $(RM) *.exe;
+
+distclean: clean
+ $(RM) config.h;
+ $(RM) makefile.vms;
diff --git a/binutils/maybe-ranlib.c b/binutils/maybe-ranlib.c
new file mode 100644
index 00000000000..f37bc0ff216
--- /dev/null
+++ b/binutils/maybe-ranlib.c
@@ -0,0 +1,4 @@
+/* Linked with ar.o to flag that this program decides at runtime
+ (using argv[0] if it is is 'ar' or 'ranlib'. */
+
+int is_ranlib = -1;
diff --git a/binutils/maybe-strip.c b/binutils/maybe-strip.c
new file mode 100644
index 00000000000..6467c99e935
--- /dev/null
+++ b/binutils/maybe-strip.c
@@ -0,0 +1,4 @@
+/* Linked with objcopy.o to flag that this program decides at runtime
+ (using argv[0] if it is is 'strip' or 'objcopy'. */
+
+int is_strip = -1;
diff --git a/binutils/mpw-config.in b/binutils/mpw-config.in
new file mode 100644
index 00000000000..21a067ddd6b
--- /dev/null
+++ b/binutils/mpw-config.in
@@ -0,0 +1,27 @@
+# Configuration fragment for binutils.
+
+Set target_arch `echo {target_canonical} | sed -e 's/-.*-.*//'`
+
+# (should canonicalize arch name) */
+
+Set archname ARCH_{target_arch}
+
+Set underscore 0
+
+If "{target_canonical}" =~ /sh-hitachi-hms/
+ Set underscore 1
+End If
+
+Echo '# From mpw-config.in' > "{o}"mk.tmp
+Echo "ARCHDEFS = -d" {archname} >> "{o}"mk.tmp
+Echo "UNDERSCORE = " {underscore} >> "{o}"mk.tmp
+Echo "BUILD_NLMCONV = " >> "{o}"mk.tmp
+Echo "BUILD_SRCONV = " >> "{o}"mk.tmp
+Echo "SYSINFO_PROG = " >> "{o}"mk.tmp
+Echo "BUILD_DLLTOOL = " >> "{o}"mk.tmp
+Echo '# End from mpw-config.in' >> "{o}"mk.tmp
+
+Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new
+Echo '#include "mpw.h"' >> "{o}"config.new
+
+MoveIfChange "{o}"config.new "{o}"config.h
diff --git a/binutils/mpw-make.sed b/binutils/mpw-make.sed
new file mode 100644
index 00000000000..03abffe18f8
--- /dev/null
+++ b/binutils/mpw-make.sed
@@ -0,0 +1,115 @@
+# Sed commands to finish translating the binutils Unix makefile into MPW syntax.
+
+# Add a rule.
+/^#### .*/a\
+\
+"{o}"underscore.c.o \\Option-f "{o}"underscore.c\
+
+# Comment out any alias settings.
+/^host_alias =/s/^/#/
+/^target_alias =/s/^/#/
+
+# Whack out unused host define bits.
+/HDEFINES/s/@HDEFINES@//
+
+# Don't build specialized tools.
+/BUILD_NLMCONV/s/@BUILD_NLMCONV@//
+/BUILD_SRCONV/s/@BUILD_SRCONV@//
+/BUILD_DLLTOOL/s/@BUILD_DLLTOOL@//
+
+/UNDERSCORE/s/@UNDERSCORE@/{UNDERSCORE}/
+
+# Don't need this.
+/@HLDFLAGS@/s/@HLDFLAGS@//
+
+# Point at the libraries directly.
+/@BFDLIB@/s/@BFDLIB@/::bfd:libbfd.o/
+/@OPCODES@/s/@OPCODES@/::opcodes:libopcodes.o/
+
+# Whack out target makefile fragment.
+/target_makefile_fragment/s/target_makefile_fragment@//
+
+# Fix and add to the include paths.
+/^INCLUDES = .*$/s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/
+/BFDDIR/s/-i {BFDDIR} /-i "{BFDDIR}": /
+/INCDIR/s/-i {INCDIR} /-i "{INCDIR}": /
+
+# Use byacc instead of bison (for now anyway).
+/BISON/s/^BISON =.*$/BISON = byacc/
+#/BISONFLAGS/s/^BISONFLAGS =.*$/BISONFLAGS = /
+
+# Embed the version in symbolic doublequotes that will expand to
+# the right thing for each compiler.
+/VERSION/s/'"{VERSION}"'/{dq}{VERSION}{dq}/
+
+# '+' is a special char to MPW, don't use it ever.
+/c++filt/s/c++filt/cplusfilt/
+
+# All of the binutils use the same Rez file, change names to refer to it.
+/^{[A-Z]*_PROG}/s/$/ "{s}"mac-binutils.r/
+/{[A-Z]*_PROG}\.r/s/{[A-Z]*_PROG}\.r/mac-binutils.r/
+
+# There are auto-generated references to BFD .h files that are not
+# in the objdir (like bfd.h) but are in the source dir.
+/::bfd:lib/s/::bfd:lib\([a-z]*\)\.h/{BFDDIR}:lib\1.h/g
+
+# Fix the locations of generated files.
+/config/s/"{s}"config\.h/"{o}"config.h/g
+/config/s/^config\.h/"{o}"config\.h/
+/underscore/s/"{s}"underscore\.c/"{o}"underscore.c/g
+/underscore/s/^underscore\.c/"{o}"underscore\.c/
+
+# Fix paths to generated source files.
+/lex.yy.c/s/"{s}"lex\.yy\.c/"{o}"lex.yy.c/g
+/lex.yy.c/s/^lex\.yy\.c/"{o}"lex.yy.c/
+/arlex.c/s/"{s}"arlex\.c/"{o}"arlex.c/g
+/arlex.c/s/^arlex\.c/"{o}"arlex.c/
+/y.tab.c/s/"{s}"y\.tab\.c/"{o}"y.tab.c/g
+/y.tab.c/s/^y\.tab\.c/"{o}"y.tab.c/
+/arparse.c/s/"{s}"arparse\.c/"{o}"arparse.c/g
+/arparse.c/s/^arparse\.c/"{o}"arparse.c/
+/y.tab.h/s/"{s}"y\.tab\.h/"{o}"y.tab.h/g
+/y.tab.h/s/^y\.tab\.h/"{o}"y.tab.h/
+/arparse.h/s/"{s}"arparse\.h/"{o}"arparse.h/g
+/arparse.h/s/^arparse\.h/"{o}"arparse.h/
+
+/"{s}"{INCDIR}/s/"{s}"{INCDIR}/"{INCDIR}"/g
+
+# The generated lexer may include an ifdef for older Mac compilers that
+# needs to work with newer compilers also.
+/lex.yy.c/s/Rename -y \([^ ]*\) \([^ ]*\)$/sed -e 's,ifdef macintosh,if defined(macintosh) || defined(__MWERKS__),' \1 > \2/
+
+# Fix an over-eagerness.
+/echo.*WARNING.*This file/s/'.*'/' '/
+
+# Add a "stamps" target.
+$a\
+stamps \\Option-f stamp-under\
+
+/^install \\Option-f /,/^$/c\
+install \\Option-f all install-only\
+\
+install-only \\Option-f\
+ NewFolderRecursive "{bindir}"\
+ # Need to copy all the tools\
+ For prog in {PROGS}\
+ Set progname `echo {prog} | sed -e 's/.new//'`\
+ Duplicate -y :{prog} "{bindir}"{progname}\
+ End For\
+
+
+/true/s/ ; @true$//
+
+# dot files are trouble, remove them and their actions.
+/^\.dep/,/^$/d
+
+# Remove un-useful targets.
+/^Makefile \\Option-f/,/^$/d
+/^"{o}"config.h \\Option-f/,/^$/d
+/^config.status \\Option-f/,/^$/d
+
+# Don't try to make the demangler's man page, it's useless.
+/^{DEMANGLER_PROG}\.1 \\Option-f/,/^$/d
+# Don't depend on it either.
+/{DEMANGLER_PROG}/s/ {DEMANGLER_PROG}\.1//
+
diff --git a/binutils/nlmconv.1 b/binutils/nlmconv.1
new file mode 100644
index 00000000000..cbc3aedd101
--- /dev/null
+++ b/binutils/nlmconv.1
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1991, 1996 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH nlmconv 1 "March 1996" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+nlmconv \- converts object code into an NLM
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B nlmconv
+.RB "[\|" \-I\ \fIbfdname\fB\ |\ \-\-input\-target=\fIbfdname\fR "\|]"
+.RB "[\|" \-O\ \fIbfdname\fB\ |\ \-\-output\-target=\fIbfdname\fR "\|]"
+.RB "[\|" \-T\ \fIheaderfile\fB\ |\ \-\-header\-file=\fIheaderfile\fR "\|]"
+.RB "[\|" \-V\ |\ \-\-version\fR "\|]"
+.RB "[\|" \-\-help\fR "\|]"
+.B infile
+.B outfile
+.SH DESCRIPTION
+.B nlmconv
+converts the relocatable object file
+.B infile
+into the NetWare Loadable Module
+.BR outfile ,
+optionally reading
+.I headerfile
+for NLM header information. For instructions on writing the NLM
+command file language used in header files, see
+.IR "The NetWare Tool Maker Specification Manual" ,
+available from Novell, Inc.
+.B nlmconv
+currently works with i386 object files in
+.BR COFF ,
+.BR ELF ,
+or
+.B a.out
+format, and with SPARC object files in
+.B ELF
+or
+.B a.out
+format.
+.br
+.B nlmconv
+uses the GNU Binary File Descriptor library to read
+.IR infile .
+.SH OPTIONS
+.TP
+.B \-I \fIbfdname\fR, \fB\-\-input\-target=\fIbfdname
+Consider the source file's object format to be
+.IR bfdname ,
+rather than attempting to deduce it.
+.TP
+.B \-O \fIbfdname\fR, \fB\-\-output\-target=\fIbfdname
+Write the output file using the object format
+.IR bfdname .
+.B nlmconv
+infers the output format based on the input format, e.g. for an i386
+input file the output format is
+.IR nlm32\-i386 .
+.TP
+.B \-T \fIheaderfile\fR, \fB\-\-header\-file=\fIheaderfile
+Reads
+.I headerfile
+for NLM header information. For instructions on writing the NLM
+command file language used in header files, see
+.IR "The NetWare Tool Maker Specification Manual" ,
+available from Novell, Inc.
+.TP
+.B \-V\fR, \fB\-\-version
+Show the version number of
+.B nlmconv
+and exit.
+.TP
+.B \-h\fR, \fB\-\-help
+Show a summary of the options to
+.B nlmconv
+and exit.
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (June 1993).
+
+.SH COPYING
+Copyright (c) 1993 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/nlmconv.c b/binutils/nlmconv.c
new file mode 100644
index 00000000000..f1c8b6c268a
--- /dev/null
+++ b/binutils/nlmconv.c
@@ -0,0 +1,2212 @@
+/* nlmconv.c -- NLM conversion program
+ Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This program can be used to convert any appropriate object file
+ into a NetWare Loadable Module (an NLM). It will accept a linker
+ specification file which is identical to that accepted by the
+ NetWare linker, NLMLINK. */
+
+/* AIX requires this to be the first thing in the file. */
+#ifndef __GNUC__
+# ifdef _AIX
+ #pragma alloca
+#endif
+#endif
+
+#include "bfd.h"
+#include "libiberty.h"
+#include "bucomm.h"
+
+#include <ansidecl.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <assert.h>
+#include <getopt.h>
+
+/* Internal BFD NLM header. */
+#include "libnlm.h"
+#include "nlmconv.h"
+
+#ifdef NLMCONV_ALPHA
+#include "coff/sym.h"
+#include "coff/ecoff.h"
+#endif
+
+/* If strerror is just a macro, we want to use the one from libiberty
+ since it will handle undefined values. */
+#undef strerror
+extern char *strerror ();
+
+#ifndef localtime
+extern struct tm *localtime ();
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#endif
+
+/* Global variables. */
+
+/* The name used to invoke the program. */
+char *program_name;
+
+/* Local variables. */
+
+/* Whether to print out debugging information (currently just controls
+ whether it prints the linker command if there is one). */
+static int debug;
+
+/* The symbol table. */
+static asymbol **symbols;
+
+/* A section we create in the output file to hold pointers to where
+ the sections of the input file end up. We will put a pointer to
+ this section in the NLM header. These is an entry for each input
+ section. The format is
+ null terminated section name
+ zeroes to adjust to 4 byte boundary
+ 4 byte section data file pointer
+ 4 byte section size
+ We don't need a version number. The way we find this information
+ is by finding a stamp in the NLM header information. If we need to
+ change the format of this information, we can simply change the
+ stamp. */
+static asection *secsec;
+
+/* A temporary file name to be unlinked on exit. Actually, for most
+ errors, we leave it around. It's not clear whether that is helpful
+ or not. */
+static char *unlink_on_exit;
+
+/* The list of long options. */
+static struct option long_options[] =
+{
+ { "debug", no_argument, 0, 'd' },
+ { "header-file", required_argument, 0, 'T' },
+ { "help", no_argument, 0, 'h' },
+ { "input-target", required_argument, 0, 'I' },
+ { "input-format", required_argument, 0, 'I' }, /* Obsolete */
+ { "linker", required_argument, 0, 'l' },
+ { "output-target", required_argument, 0, 'O' },
+ { "output-format", required_argument, 0, 'O' }, /* Obsolete */
+ { "version", no_argument, 0, 'V' },
+ { NULL, no_argument, 0, 0 }
+};
+
+/* Local routines. */
+
+static void show_help PARAMS ((void));
+static void show_usage PARAMS ((FILE *, int));
+static const char *select_output_format PARAMS ((enum bfd_architecture,
+ unsigned long, boolean));
+static void setup_sections PARAMS ((bfd *, asection *, PTR));
+static void copy_sections PARAMS ((bfd *, asection *, PTR));
+static void mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
+ long *, char *,
+ bfd_size_type));
+static void default_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
+ long *, char *,
+ bfd_size_type));
+static char *link_inputs PARAMS ((struct string_list *, char *));
+
+#ifdef NLMCONV_I386
+static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
+ long *, char *,
+ bfd_size_type));
+#endif
+
+#ifdef NLMCONV_ALPHA
+static void alpha_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
+ long *, char *,
+ bfd_size_type));
+#endif
+
+#ifdef NLMCONV_POWERPC
+static void powerpc_build_stubs PARAMS ((bfd *, bfd *, asymbol ***, long *));
+static void powerpc_resolve_stubs PARAMS ((bfd *, bfd *));
+static void powerpc_mangle_relocs PARAMS ((bfd *, asection *, arelent ***,
+ long *, char *,
+ bfd_size_type));
+#endif
+
+/* The main routine. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int opt;
+ char *input_file = NULL;
+ const char *input_format = NULL;
+ const char *output_format = NULL;
+ const char *header_file = NULL;
+ char *ld_arg = NULL;
+ Nlm_Internal_Fixed_Header fixed_hdr_struct;
+ Nlm_Internal_Variable_Header var_hdr_struct;
+ Nlm_Internal_Version_Header version_hdr_struct;
+ Nlm_Internal_Copyright_Header copyright_hdr_struct;
+ Nlm_Internal_Extended_Header extended_hdr_struct;
+ bfd *inbfd;
+ bfd *outbfd;
+ asymbol **newsyms, **outsyms;
+ long symcount, newsymalloc, newsymcount;
+ long symsize;
+ asection *text_sec, *bss_sec, *data_sec;
+ bfd_vma vma;
+ bfd_size_type align;
+ asymbol *endsym;
+ long i;
+ char inlead, outlead;
+ boolean gotstart, gotexit, gotcheck;
+ struct stat st;
+ FILE *custom_data = NULL;
+ FILE *help_data = NULL;
+ FILE *message_data = NULL;
+ FILE *rpc_data = NULL;
+ FILE *shared_data = NULL;
+ size_t custom_size = 0;
+ size_t help_size = 0;
+ size_t message_size = 0;
+ size_t module_size = 0;
+ size_t rpc_size = 0;
+ asection *custom_section = NULL;
+ asection *help_section = NULL;
+ asection *message_section = NULL;
+ asection *module_section = NULL;
+ asection *rpc_section = NULL;
+ asection *shared_section = NULL;
+ bfd *sharedbfd;
+ size_t shared_offset = 0;
+ size_t shared_size = 0;
+ Nlm_Internal_Fixed_Header sharedhdr;
+ int len;
+ char *modname;
+ char **matching;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ while ((opt = getopt_long (argc, argv, "dhI:l:O:T:V", long_options,
+ (int *) NULL))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'd':
+ debug = 1;
+ break;
+ case 'h':
+ show_help ();
+ /*NOTREACHED*/
+ case 'I':
+ input_format = optarg;
+ break;
+ case 'l':
+ ld_arg = optarg;
+ break;
+ case 'O':
+ output_format = optarg;
+ break;
+ case 'T':
+ header_file = optarg;
+ break;
+ case 'V':
+ print_version ("nlmconv");
+ /*NOTREACHED*/
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /*NOTREACHED*/
+ }
+ }
+
+ /* The input and output files may be named on the command line. */
+ output_file = NULL;
+ if (optind < argc)
+ {
+ input_file = argv[optind];
+ ++optind;
+ if (optind < argc)
+ {
+ output_file = argv[optind];
+ ++optind;
+ if (optind < argc)
+ show_usage (stderr, 1);
+ if (strcmp (input_file, output_file) == 0)
+ {
+ fprintf (stderr,
+ _("%s: input and output files must be different\n"),
+ program_name);
+ exit (1);
+ }
+ }
+ }
+
+ /* Initialize the header information to default values. */
+ fixed_hdr = &fixed_hdr_struct;
+ memset ((PTR) &fixed_hdr_struct, 0, sizeof fixed_hdr_struct);
+ var_hdr = &var_hdr_struct;
+ memset ((PTR) &var_hdr_struct, 0, sizeof var_hdr_struct);
+ version_hdr = &version_hdr_struct;
+ memset ((PTR) &version_hdr_struct, 0, sizeof version_hdr_struct);
+ copyright_hdr = &copyright_hdr_struct;
+ memset ((PTR) &copyright_hdr_struct, 0, sizeof copyright_hdr_struct);
+ extended_hdr = &extended_hdr_struct;
+ memset ((PTR) &extended_hdr_struct, 0, sizeof extended_hdr_struct);
+ check_procedure = NULL;
+ custom_file = NULL;
+ debug_info = false;
+ exit_procedure = "_Stop";
+ export_symbols = NULL;
+ map_file = NULL;
+ full_map = false;
+ help_file = NULL;
+ import_symbols = NULL;
+ message_file = NULL;
+ modules = NULL;
+ sharelib_file = NULL;
+ start_procedure = "_Prelude";
+ verbose = false;
+ rpc_file = NULL;
+
+ parse_errors = 0;
+
+ /* Parse the header file (if there is one). */
+ if (header_file != NULL)
+ {
+ if (! nlmlex_file (header_file)
+ || yyparse () != 0
+ || parse_errors != 0)
+ exit (1);
+ }
+
+ if (input_files != NULL)
+ {
+ if (input_file != NULL)
+ {
+ fprintf (stderr,
+ _("%s: input file named both on command line and with INPUT\n"),
+ program_name);
+ exit (1);
+ }
+ if (input_files->next == NULL)
+ input_file = input_files->string;
+ else
+ input_file = link_inputs (input_files, ld_arg);
+ }
+ else if (input_file == NULL)
+ {
+ fprintf (stderr, _("%s: no input file\n"), program_name);
+ show_usage (stderr, 1);
+ }
+
+ inbfd = bfd_openr (input_file, input_format);
+ if (inbfd == NULL)
+ bfd_fatal (input_file);
+
+ if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (input_file);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ exit (1);
+ }
+
+ if (output_format == NULL)
+ output_format = select_output_format (bfd_get_arch (inbfd),
+ bfd_get_mach (inbfd),
+ bfd_big_endian (inbfd));
+
+ assert (output_format != NULL);
+
+ /* Use the output file named on the command line if it exists.
+ Otherwise use the file named in the OUTPUT statement. */
+ if (output_file == NULL)
+ {
+ fprintf (stderr, _("%s: no name for output file\n"),
+ program_name);
+ show_usage (stderr, 1);
+ }
+
+ outbfd = bfd_openw (output_file, output_format);
+ if (outbfd == NULL)
+ bfd_fatal (output_file);
+ if (! bfd_set_format (outbfd, bfd_object))
+ bfd_fatal (output_file);
+
+ assert (bfd_get_flavour (outbfd) == bfd_target_nlm_flavour);
+
+ if (bfd_arch_get_compatible (inbfd, outbfd) == NULL)
+ fprintf (stderr,
+ _("%s: warning:input and output formats are not compatible\n"),
+ program_name);
+
+ /* Move the values read from the command file into outbfd. */
+ *nlm_fixed_header (outbfd) = fixed_hdr_struct;
+ *nlm_variable_header (outbfd) = var_hdr_struct;
+ *nlm_version_header (outbfd) = version_hdr_struct;
+ *nlm_copyright_header (outbfd) = copyright_hdr_struct;
+ *nlm_extended_header (outbfd) = extended_hdr_struct;
+
+ /* Start copying the input BFD to the output BFD. */
+ if (! bfd_set_file_flags (outbfd, bfd_get_file_flags (inbfd)))
+ bfd_fatal (bfd_get_filename (outbfd));
+
+ symsize = bfd_get_symtab_upper_bound (inbfd);
+ if (symsize < 0)
+ bfd_fatal (input_file);
+ symbols = (asymbol **) xmalloc (symsize);
+ symcount = bfd_canonicalize_symtab (inbfd, symbols);
+ if (symcount < 0)
+ bfd_fatal (input_file);
+
+ /* Make sure we have a .bss section. */
+ bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
+ if (bss_sec == NULL)
+ {
+ bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
+ if (bss_sec == NULL
+ || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
+ || ! bfd_set_section_alignment (outbfd, bss_sec, 1))
+ bfd_fatal (_("make .bss section"));
+ }
+
+ /* We store the original section names in the .nlmsections section,
+ so that programs which understand it can resurrect the original
+ sections from the NLM. We will put a pointer to .nlmsections in
+ the NLM header area. */
+ secsec = bfd_make_section (outbfd, ".nlmsections");
+ if (secsec == NULL)
+ bfd_fatal (_("make .nlmsections section"));
+ if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
+ bfd_fatal (_("set .nlmsections flags"));
+
+#ifdef NLMCONV_POWERPC
+ /* For PowerPC NetWare we need to build stubs for calls to undefined
+ symbols. Because each stub requires an entry in the TOC section
+ which must be at the same location as other entries in the TOC
+ section, we must do this before determining where the TOC section
+ goes in setup_sections. */
+ if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
+ powerpc_build_stubs (inbfd, outbfd, &symbols, &symcount);
+#endif
+
+ /* Set up the sections. */
+ bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
+
+ text_sec = bfd_get_section_by_name (outbfd, NLM_CODE_NAME);
+
+ /* The .bss section immediately follows the .data section. */
+ data_sec = bfd_get_section_by_name (outbfd, NLM_INITIALIZED_DATA_NAME);
+ if (data_sec != NULL)
+ {
+ bfd_size_type add;
+
+ vma = bfd_get_section_size_before_reloc (data_sec);
+ align = 1 << bss_sec->alignment_power;
+ add = ((vma + align - 1) &~ (align - 1)) - vma;
+ vma += add;
+ if (! bfd_set_section_vma (outbfd, bss_sec, vma))
+ bfd_fatal (_("set .bss vma"));
+ if (add != 0)
+ {
+ bfd_size_type data_size;
+
+ data_size = bfd_get_section_size_before_reloc (data_sec);
+ if (! bfd_set_section_size (outbfd, data_sec, data_size + add))
+ bfd_fatal (_("set .data size"));
+ }
+ }
+
+ /* Adjust symbol information. */
+ inlead = bfd_get_symbol_leading_char (inbfd);
+ outlead = bfd_get_symbol_leading_char (outbfd);
+ gotstart = false;
+ gotexit = false;
+ gotcheck = false;
+ newsymalloc = 10;
+ newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
+ newsymcount = 0;
+ endsym = NULL;
+ for (i = 0; i < symcount; i++)
+ {
+ register asymbol *sym;
+
+ sym = symbols[i];
+
+ /* Add or remove a leading underscore. */
+ if (inlead != outlead)
+ {
+ if (inlead != '\0')
+ {
+ if (bfd_asymbol_name (sym)[0] == inlead)
+ {
+ if (outlead == '\0')
+ ++sym->name;
+ else
+ {
+ char *new;
+
+ new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
+ new[0] = outlead;
+ strcpy (new + 1, bfd_asymbol_name (sym) + 1);
+ sym->name = new;
+ }
+ }
+ }
+ else
+ {
+ char *new;
+
+ new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
+ new[0] = outlead;
+ strcpy (new + 1, bfd_asymbol_name (sym));
+ sym->name = new;
+ }
+ }
+
+ /* NLM's have an uninitialized data section, but they do not
+ have a common section in the Unix sense. Move all common
+ symbols into the .bss section, and mark them as exported. */
+ if (bfd_is_com_section (bfd_get_section (sym)))
+ {
+ bfd_vma size;
+
+ sym->section = bss_sec;
+ size = sym->value;
+ sym->value = bss_sec->_raw_size;
+ bss_sec->_raw_size += size;
+ align = 1 << bss_sec->alignment_power;
+ bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
+ sym->flags |= BSF_EXPORT | BSF_GLOBAL;
+ }
+ else if (bfd_get_section (sym)->output_section != NULL)
+ {
+ /* Move the symbol into the output section. */
+ sym->value += bfd_get_section (sym)->output_offset;
+ sym->section = bfd_get_section (sym)->output_section;
+ /* This is no longer a section symbol. */
+ sym->flags &=~ BSF_SECTION_SYM;
+ }
+
+ /* Force _edata and _end to be defined. This would normally be
+ done by the linker, but the manipulation of the common
+ symbols will confuse it. */
+ if ((sym->flags & BSF_DEBUGGING) == 0
+ && bfd_asymbol_name (sym)[0] == '_'
+ && bfd_is_und_section (bfd_get_section (sym)))
+ {
+ if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
+ {
+ sym->section = bss_sec;
+ sym->value = 0;
+ }
+ if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
+ {
+ sym->section = bss_sec;
+ endsym = sym;
+ }
+
+#ifdef NLMCONV_POWERPC
+ /* For PowerPC NetWare, we define __GOT0. This is the start
+ of the .got section. */
+ if (bfd_get_arch (inbfd) == bfd_arch_powerpc
+ && strcmp (bfd_asymbol_name (sym), "__GOT0") == 0)
+ {
+ asection *got_sec;
+
+ got_sec = bfd_get_section_by_name (inbfd, ".got");
+ assert (got_sec != (asection *) NULL);
+ sym->value = got_sec->output_offset;
+ sym->section = got_sec->output_section;
+ }
+#endif
+ }
+
+ /* If this is a global symbol, check the export list. */
+ if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
+ {
+ register struct string_list *l;
+ int found_simple;
+
+ /* Unfortunately, a symbol can appear multiple times on the
+ export list, with and without prefixes. */
+ found_simple = 0;
+ for (l = export_symbols; l != NULL; l = l->next)
+ {
+ if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
+ found_simple = 1;
+ else
+ {
+ char *zbase;
+
+ zbase = strchr (l->string, '@');
+ if (zbase != NULL
+ && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
+ {
+ /* We must add a symbol with this prefix. */
+ if (newsymcount >= newsymalloc)
+ {
+ newsymalloc += 10;
+ newsyms = ((asymbol **)
+ xrealloc ((PTR) newsyms,
+ (newsymalloc
+ * sizeof (asymbol *))));
+ }
+ newsyms[newsymcount] =
+ (asymbol *) xmalloc (sizeof (asymbol));
+ *newsyms[newsymcount] = *sym;
+ newsyms[newsymcount]->name = l->string;
+ ++newsymcount;
+ }
+ }
+ }
+ if (! found_simple)
+ {
+ /* The unmodified symbol is actually not exported at
+ all. */
+ sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
+ sym->flags |= BSF_LOCAL;
+ }
+ }
+
+ /* If it's an undefined symbol, see if it's on the import list.
+ Change the prefix if necessary. */
+ if (bfd_is_und_section (bfd_get_section (sym)))
+ {
+ register struct string_list *l;
+
+ for (l = import_symbols; l != NULL; l = l->next)
+ {
+ if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
+ break;
+ else
+ {
+ char *zbase;
+
+ zbase = strchr (l->string, '@');
+ if (zbase != NULL
+ && strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
+ {
+ sym->name = l->string;
+ break;
+ }
+ }
+ }
+ if (l == NULL)
+ fprintf (stderr,
+ _("%s: warning: symbol %s imported but not in import list\n"),
+ program_name, bfd_asymbol_name (sym));
+ }
+
+ /* See if it's one of the special named symbols. */
+ if ((sym->flags & BSF_DEBUGGING) == 0)
+ {
+ bfd_vma val;
+
+ /* FIXME: If these symbols are not in the .text section, we
+ add the .text section size to the value. This may not be
+ correct for all targets. I'm not sure how this should
+ really be handled. */
+ if (strcmp (bfd_asymbol_name (sym), start_procedure) == 0)
+ {
+ val = bfd_asymbol_value (sym);
+ if (bfd_get_section (sym) == data_sec
+ && text_sec != (asection *) NULL)
+ val += bfd_section_size (outbfd, text_sec);
+ if (! bfd_set_start_address (outbfd, val))
+ bfd_fatal (_("set start address"));
+ gotstart = true;
+ }
+ if (strcmp (bfd_asymbol_name (sym), exit_procedure) == 0)
+ {
+ val = bfd_asymbol_value (sym);
+ if (bfd_get_section (sym) == data_sec
+ && text_sec != (asection *) NULL)
+ val += bfd_section_size (outbfd, text_sec);
+ nlm_fixed_header (outbfd)->exitProcedureOffset = val;
+ gotexit = true;
+ }
+ if (check_procedure != NULL
+ && strcmp (bfd_asymbol_name (sym), check_procedure) == 0)
+ {
+ val = bfd_asymbol_value (sym);
+ if (bfd_get_section (sym) == data_sec
+ && text_sec != (asection *) NULL)
+ val += bfd_section_size (outbfd, text_sec);
+ nlm_fixed_header (outbfd)->checkUnloadProcedureOffset = val;
+ gotcheck = true;
+ }
+ }
+ }
+
+ if (endsym != NULL)
+ {
+ endsym->value = bfd_get_section_size_before_reloc (bss_sec);
+
+ /* FIXME: If any relocs referring to _end use inplace addends,
+ then I think they need to be updated. This is handled by
+ i386_mangle_relocs. Is it needed for any other object
+ formats? */
+ }
+
+ if (newsymcount == 0)
+ outsyms = symbols;
+ else
+ {
+ outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
+ * sizeof (asymbol *));
+ memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
+ memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
+ outsyms[symcount + newsymcount] = NULL;
+ }
+
+ bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
+
+ if (! gotstart)
+ fprintf (stderr, _("%s: warning: START procedure %s not defined\n"),
+ program_name, start_procedure);
+ if (! gotexit)
+ fprintf (stderr, _("%s: warning: EXIT procedure %s not defined\n"),
+ program_name, exit_procedure);
+ if (check_procedure != NULL
+ && ! gotcheck)
+ fprintf (stderr, _("%s: warning: CHECK procedure %s not defined\n"),
+ program_name, check_procedure);
+
+ /* Add additional sections required for the header information. */
+ if (custom_file != NULL)
+ {
+ custom_data = fopen (custom_file, "r");
+ if (custom_data == NULL
+ || fstat (fileno (custom_data), &st) < 0)
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, custom_file,
+ strerror (errno));
+ custom_file = NULL;
+ }
+ else
+ {
+ custom_size = st.st_size;
+ custom_section = bfd_make_section (outbfd, ".nlmcustom");
+ if (custom_section == NULL
+ || ! bfd_set_section_size (outbfd, custom_section, custom_size)
+ || ! bfd_set_section_flags (outbfd, custom_section,
+ SEC_HAS_CONTENTS))
+ bfd_fatal (_("custom section"));
+ }
+ }
+ if (help_file != NULL)
+ {
+ help_data = fopen (help_file, "r");
+ if (help_data == NULL
+ || fstat (fileno (help_data), &st) < 0)
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, help_file,
+ strerror (errno));
+ help_file = NULL;
+ }
+ else
+ {
+ help_size = st.st_size;
+ help_section = bfd_make_section (outbfd, ".nlmhelp");
+ if (help_section == NULL
+ || ! bfd_set_section_size (outbfd, help_section, help_size)
+ || ! bfd_set_section_flags (outbfd, help_section,
+ SEC_HAS_CONTENTS))
+ bfd_fatal (_("help section"));
+ strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ }
+ }
+ if (message_file != NULL)
+ {
+ message_data = fopen (message_file, "r");
+ if (message_data == NULL
+ || fstat (fileno (message_data), &st) < 0)
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, message_file,
+ strerror (errno));
+ message_file = NULL;
+ }
+ else
+ {
+ message_size = st.st_size;
+ message_section = bfd_make_section (outbfd, ".nlmmessages");
+ if (message_section == NULL
+ || ! bfd_set_section_size (outbfd, message_section, message_size)
+ || ! bfd_set_section_flags (outbfd, message_section,
+ SEC_HAS_CONTENTS))
+ bfd_fatal (_("message section"));
+ strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ }
+ }
+ if (modules != NULL)
+ {
+ struct string_list *l;
+
+ module_size = 0;
+ for (l = modules; l != NULL; l = l->next)
+ module_size += strlen (l->string) + 1;
+ module_section = bfd_make_section (outbfd, ".nlmmodules");
+ if (module_section == NULL
+ || ! bfd_set_section_size (outbfd, module_section, module_size)
+ || ! bfd_set_section_flags (outbfd, module_section,
+ SEC_HAS_CONTENTS))
+ bfd_fatal (_("module section"));
+ }
+ if (rpc_file != NULL)
+ {
+ rpc_data = fopen (rpc_file, "r");
+ if (rpc_data == NULL
+ || fstat (fileno (rpc_data), &st) < 0)
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, rpc_file,
+ strerror (errno));
+ rpc_file = NULL;
+ }
+ else
+ {
+ rpc_size = st.st_size;
+ rpc_section = bfd_make_section (outbfd, ".nlmrpc");
+ if (rpc_section == NULL
+ || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
+ || ! bfd_set_section_flags (outbfd, rpc_section,
+ SEC_HAS_CONTENTS))
+ bfd_fatal (_("rpc section"));
+ strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ }
+ }
+ if (sharelib_file != NULL)
+ {
+ sharedbfd = bfd_openr (sharelib_file, output_format);
+ if (sharedbfd == NULL
+ || ! bfd_check_format (sharedbfd, bfd_object))
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
+ bfd_errmsg (bfd_get_error ()));
+ sharelib_file = NULL;
+ }
+ else
+ {
+ sharedhdr = *nlm_fixed_header (sharedbfd);
+ bfd_close (sharedbfd);
+ shared_data = fopen (sharelib_file, "r");
+ if (shared_data == NULL
+ || (fstat (fileno (shared_data), &st) < 0))
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
+ strerror (errno));
+ sharelib_file = NULL;
+ }
+ else
+ {
+ /* If we were clever, we could just copy out the
+ sections of the shared library which we actually
+ need. However, we would have to figure out the sizes
+ of the external and public information, and that can
+ not be done without reading through them. */
+ if (sharedhdr.uninitializedDataSize > 0)
+ {
+ /* There is no place to record this information. */
+ fprintf (stderr,
+ _("%s:%s: warning: shared libraries can not have uninitialized data\n"),
+ program_name, sharelib_file);
+ }
+ shared_offset = st.st_size;
+ if (shared_offset > (size_t) sharedhdr.codeImageOffset)
+ shared_offset = sharedhdr.codeImageOffset;
+ if (shared_offset > (size_t) sharedhdr.dataImageOffset)
+ shared_offset = sharedhdr.dataImageOffset;
+ if (shared_offset > (size_t) sharedhdr.relocationFixupOffset)
+ shared_offset = sharedhdr.relocationFixupOffset;
+ if (shared_offset > (size_t) sharedhdr.externalReferencesOffset)
+ shared_offset = sharedhdr.externalReferencesOffset;
+ if (shared_offset > (size_t) sharedhdr.publicsOffset)
+ shared_offset = sharedhdr.publicsOffset;
+ shared_size = st.st_size - shared_offset;
+ shared_section = bfd_make_section (outbfd, ".nlmshared");
+ if (shared_section == NULL
+ || ! bfd_set_section_size (outbfd, shared_section,
+ shared_size)
+ || ! bfd_set_section_flags (outbfd, shared_section,
+ SEC_HAS_CONTENTS))
+ bfd_fatal (_("shared section"));
+ strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ }
+ }
+ }
+
+ /* Check whether a version was given. */
+ if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
+ fprintf (stderr, _("%s: warning: No version number given\n"),
+ program_name);
+
+ /* At least for now, always create an extended header, because that
+ is what NLMLINK does. */
+ strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+
+ strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
+
+ /* If the date was not given, force it in. */
+ if (nlm_version_header (outbfd)->month == 0
+ && nlm_version_header (outbfd)->day == 0
+ && nlm_version_header (outbfd)->year == 0)
+ {
+ time_t now;
+ struct tm *ptm;
+
+ time (&now);
+ ptm = localtime (&now);
+ nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
+ nlm_version_header (outbfd)->day = ptm->tm_mday;
+ nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
+ strncpy (version_hdr->stamp, "VeRsIoN#", 8);
+ }
+
+#ifdef NLMCONV_POWERPC
+ /* Resolve the stubs we build for PowerPC NetWare. */
+ if (bfd_get_arch (inbfd) == bfd_arch_powerpc)
+ powerpc_resolve_stubs (inbfd, outbfd);
+#endif
+
+ /* Copy over the sections. */
+ bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
+
+ /* Finish up the header information. */
+ if (custom_file != NULL)
+ {
+ PTR data;
+
+ data = xmalloc (custom_size);
+ if (fread (data, 1, custom_size, custom_data) != custom_size)
+ fprintf (stderr, _("%s:%s: read: %s\n"), program_name, custom_file,
+ strerror (errno));
+ else
+ {
+ if (! bfd_set_section_contents (outbfd, custom_section, data,
+ (file_ptr) 0, custom_size))
+ bfd_fatal (_("custom section"));
+ nlm_fixed_header (outbfd)->customDataOffset =
+ custom_section->filepos;
+ nlm_fixed_header (outbfd)->customDataSize = custom_size;
+ }
+ free (data);
+ }
+ if (! debug_info)
+ {
+ /* As a special hack, the backend recognizes a debugInfoOffset
+ of -1 to mean that it should not output any debugging
+ information. This can not be handling by fiddling with the
+ symbol table because exported symbols appear in both the
+ export information and the debugging information. */
+ nlm_fixed_header (outbfd)->debugInfoOffset = (file_ptr) -1;
+ }
+ if (map_file != NULL)
+ fprintf (stderr,
+ _("%s: warning: MAP and FULLMAP are not supported; try ld -M\n"),
+ program_name);
+ if (help_file != NULL)
+ {
+ PTR data;
+
+ data = xmalloc (help_size);
+ if (fread (data, 1, help_size, help_data) != help_size)
+ fprintf (stderr, _("%s:%s: read: %s\n"), program_name, help_file,
+ strerror (errno));
+ else
+ {
+ if (! bfd_set_section_contents (outbfd, help_section, data,
+ (file_ptr) 0, help_size))
+ bfd_fatal (_("help section"));
+ nlm_extended_header (outbfd)->helpFileOffset =
+ help_section->filepos;
+ nlm_extended_header (outbfd)->helpFileLength = help_size;
+ }
+ free (data);
+ }
+ if (message_file != NULL)
+ {
+ PTR data;
+
+ data = xmalloc (message_size);
+ if (fread (data, 1, message_size, message_data) != message_size)
+ fprintf (stderr, _("%s:%s: read: %s\n"), program_name, message_file,
+ strerror (errno));
+ else
+ {
+ if (! bfd_set_section_contents (outbfd, message_section, data,
+ (file_ptr) 0, message_size))
+ bfd_fatal (_("message section"));
+ nlm_extended_header (outbfd)->messageFileOffset =
+ message_section->filepos;
+ nlm_extended_header (outbfd)->messageFileLength = message_size;
+
+ /* FIXME: Are these offsets correct on all platforms? Are
+ they 32 bits on all platforms? What endianness? */
+ nlm_extended_header (outbfd)->languageID =
+ bfd_h_get_32 (outbfd, (bfd_byte *) data + 106);
+ nlm_extended_header (outbfd)->messageCount =
+ bfd_h_get_32 (outbfd, (bfd_byte *) data + 110);
+ }
+ free (data);
+ }
+ if (modules != NULL)
+ {
+ PTR data;
+ unsigned char *set;
+ struct string_list *l;
+ bfd_size_type c;
+
+ data = xmalloc (module_size);
+ c = 0;
+ set = (unsigned char *) data;
+ for (l = modules; l != NULL; l = l->next)
+ {
+ *set = strlen (l->string);
+ strncpy (set + 1, l->string, *set);
+ set += *set + 1;
+ ++c;
+ }
+ if (! bfd_set_section_contents (outbfd, module_section, data,
+ (file_ptr) 0, module_size))
+ bfd_fatal (_("module section"));
+ nlm_fixed_header (outbfd)->moduleDependencyOffset =
+ module_section->filepos;
+ nlm_fixed_header (outbfd)->numberOfModuleDependencies = c;
+ }
+ if (rpc_file != NULL)
+ {
+ PTR data;
+
+ data = xmalloc (rpc_size);
+ if (fread (data, 1, rpc_size, rpc_data) != rpc_size)
+ fprintf (stderr, _("%s:%s: read: %s\n"), program_name, rpc_file,
+ strerror (errno));
+ else
+ {
+ if (! bfd_set_section_contents (outbfd, rpc_section, data,
+ (file_ptr) 0, rpc_size))
+ bfd_fatal (_("rpc section"));
+ nlm_extended_header (outbfd)->RPCDataOffset =
+ rpc_section->filepos;
+ nlm_extended_header (outbfd)->RPCDataLength = rpc_size;
+ }
+ free (data);
+ }
+ if (sharelib_file != NULL)
+ {
+ PTR data;
+
+ data = xmalloc (shared_size);
+ if (fseek (shared_data, shared_offset, SEEK_SET) != 0
+ || fread (data, 1, shared_size, shared_data) != shared_size)
+ fprintf (stderr, _("%s:%s: read: %s\n"), program_name, sharelib_file,
+ strerror (errno));
+ else
+ {
+ if (! bfd_set_section_contents (outbfd, shared_section, data,
+ (file_ptr) 0, shared_size))
+ bfd_fatal (_("shared section"));
+ }
+ nlm_extended_header (outbfd)->sharedCodeOffset =
+ sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
+ nlm_extended_header (outbfd)->sharedCodeLength =
+ sharedhdr.codeImageSize;
+ nlm_extended_header (outbfd)->sharedDataOffset =
+ sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
+ nlm_extended_header (outbfd)->sharedDataLength =
+ sharedhdr.dataImageSize;
+ nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
+ (sharedhdr.relocationFixupOffset
+ - shared_offset
+ + shared_section->filepos);
+ nlm_extended_header (outbfd)->sharedRelocationFixupCount =
+ sharedhdr.numberOfRelocationFixups;
+ nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
+ (sharedhdr.externalReferencesOffset
+ - shared_offset
+ + shared_section->filepos);
+ nlm_extended_header (outbfd)->sharedExternalReferenceCount =
+ sharedhdr.numberOfExternalReferences;
+ nlm_extended_header (outbfd)->sharedPublicsOffset =
+ sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
+ nlm_extended_header (outbfd)->sharedPublicsCount =
+ sharedhdr.numberOfPublics;
+ nlm_extended_header (outbfd)->sharedDebugRecordOffset =
+ sharedhdr.debugInfoOffset - shared_offset + shared_section->filepos;
+ nlm_extended_header (outbfd)->sharedDebugRecordCount =
+ sharedhdr.numberOfDebugRecords;
+ nlm_extended_header (outbfd)->SharedInitializationOffset =
+ sharedhdr.codeStartOffset;
+ nlm_extended_header (outbfd)->SharedExitProcedureOffset =
+ sharedhdr.exitProcedureOffset;
+ free (data);
+ }
+ len = strlen (output_file);
+ if (len > NLM_MODULE_NAME_SIZE - 2)
+ len = NLM_MODULE_NAME_SIZE - 2;
+ nlm_fixed_header (outbfd)->moduleName[0] = len;
+
+ strncpy (nlm_fixed_header (outbfd)->moduleName + 1, output_file,
+ NLM_MODULE_NAME_SIZE - 2);
+ nlm_fixed_header (outbfd)->moduleName[NLM_MODULE_NAME_SIZE - 1] = '\0';
+ for (modname = nlm_fixed_header (outbfd)->moduleName;
+ *modname != '\0';
+ modname++)
+ if (islower ((unsigned char) *modname))
+ *modname = toupper (*modname);
+
+ strncpy (nlm_variable_header (outbfd)->oldThreadName, " LONG",
+ NLM_OLD_THREAD_NAME_LENGTH);
+
+ nlm_cygnus_ext_header (outbfd)->offset = secsec->filepos;
+ nlm_cygnus_ext_header (outbfd)->length = bfd_section_size (outbfd, secsec);
+
+ if (! bfd_close (outbfd))
+ bfd_fatal (output_file);
+ if (! bfd_close (inbfd))
+ bfd_fatal (input_file);
+
+ if (unlink_on_exit != NULL)
+ unlink (unlink_on_exit);
+
+ return 0;
+}
+
+/* Display a help message and exit. */
+
+static void
+show_help ()
+{
+ printf (_("%s: Convert an object file into a NetWare Loadable Module\n"),
+ program_name);
+ show_usage (stdout, 0);
+}
+
+/* Show a usage message and exit. */
+
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, _("\
+Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n\
+ [--input-target=bfdname] [--output-target=bfdname]\n\
+ [--header-file=file] [--linker=linker] [--debug]\n\
+ [--help] [--version]\n\
+ [in-file [out-file]]\n"),
+ program_name);
+ if (status == 0)
+ fprintf (file, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+/* Select the output format based on the input architecture, machine,
+ and endianness. This chooses the appropriate NLM target. */
+
+static const char *
+select_output_format (arch, mach, bigendian)
+ enum bfd_architecture arch;
+ unsigned long mach;
+ boolean bigendian;
+{
+ switch (arch)
+ {
+#ifdef NLMCONV_I386
+ case bfd_arch_i386:
+ return "nlm32-i386";
+#endif
+#ifdef NLMCONV_SPARC
+ case bfd_arch_sparc:
+ return "nlm32-sparc";
+#endif
+#ifdef NLMCONV_ALPHA
+ case bfd_arch_alpha:
+ return "nlm32-alpha";
+#endif
+#ifdef NLMCONV_POWERPC
+ case bfd_arch_powerpc:
+ return "nlm32-powerpc";
+#endif
+ default:
+ fprintf (stderr, _("%s: support not compiled in for %s\n"),
+ program_name, bfd_printable_arch_mach (arch, mach));
+ exit (1);
+ /* Avoid warning. */
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+
+/* The BFD sections are copied in two passes. This function selects
+ the output section for each input section, and sets up the section
+ name, size, etc. */
+
+static void
+setup_sections (inbfd, insec, data_ptr)
+ bfd *inbfd;
+ asection *insec;
+ PTR data_ptr;
+{
+ bfd *outbfd = (bfd *) data_ptr;
+ flagword f;
+ const char *outname;
+ asection *outsec;
+ bfd_vma offset;
+ bfd_size_type align;
+ bfd_size_type add;
+ bfd_size_type secsecsize;
+
+ f = bfd_get_section_flags (inbfd, insec);
+ if (f & SEC_CODE)
+ outname = NLM_CODE_NAME;
+ else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
+ outname = NLM_INITIALIZED_DATA_NAME;
+ else if (f & SEC_ALLOC)
+ outname = NLM_UNINITIALIZED_DATA_NAME;
+ else
+ outname = bfd_section_name (inbfd, insec);
+
+ outsec = bfd_get_section_by_name (outbfd, outname);
+ if (outsec == NULL)
+ {
+ outsec = bfd_make_section (outbfd, outname);
+ if (outsec == NULL)
+ bfd_fatal (_("make section"));
+ }
+
+ insec->output_section = outsec;
+
+ offset = bfd_section_size (outbfd, outsec);
+ align = 1 << bfd_section_alignment (inbfd, insec);
+ add = ((offset + align - 1) &~ (align - 1)) - offset;
+ insec->output_offset = offset + add;
+
+ if (! bfd_set_section_size (outbfd, outsec,
+ (bfd_section_size (outbfd, outsec)
+ + bfd_section_size (inbfd, insec)
+ + add)))
+ bfd_fatal (_("set section size"));
+
+ if ((bfd_section_alignment (inbfd, insec)
+ > bfd_section_alignment (outbfd, outsec))
+ && ! bfd_set_section_alignment (outbfd, outsec,
+ bfd_section_alignment (inbfd, insec)))
+ bfd_fatal (_("set section alignment"));
+
+ if (! bfd_set_section_flags (outbfd, outsec,
+ f | bfd_get_section_flags (outbfd, outsec)))
+ bfd_fatal (_("set section flags"));
+
+ bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);
+
+ /* For each input section we allocate space for an entry in
+ .nlmsections. */
+ secsecsize = bfd_section_size (outbfd, secsec);
+ secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
+ secsecsize = (secsecsize + 3) &~ 3;
+ secsecsize += 8;
+ if (! bfd_set_section_size (outbfd, secsec, secsecsize))
+ bfd_fatal (_("set .nlmsections size"));
+}
+
+/* Copy the section contents. */
+
+static void
+copy_sections (inbfd, insec, data_ptr)
+ bfd *inbfd;
+ asection *insec;
+ PTR data_ptr;
+{
+ static bfd_size_type secsecoff = 0;
+ bfd *outbfd = (bfd *) data_ptr;
+ const char *inname;
+ asection *outsec;
+ bfd_size_type size;
+ PTR contents;
+ long reloc_size;
+ bfd_byte buf[4];
+ bfd_size_type add;
+
+ inname = bfd_section_name (inbfd, insec);
+
+ outsec = insec->output_section;
+ assert (outsec != NULL);
+
+ size = bfd_get_section_size_before_reloc (insec);
+
+ /* FIXME: Why are these necessary? */
+ insec->_cooked_size = insec->_raw_size;
+ insec->reloc_done = true;
+
+ if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
+ contents = NULL;
+ else
+ {
+ contents = xmalloc (size);
+ if (! bfd_get_section_contents (inbfd, insec, contents,
+ (file_ptr) 0, size))
+ bfd_fatal (bfd_get_filename (inbfd));
+ }
+
+ reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
+ if (reloc_size < 0)
+ bfd_fatal (bfd_get_filename (inbfd));
+ if (reloc_size != 0)
+ {
+ arelent **relocs;
+ long reloc_count;
+
+ relocs = (arelent **) xmalloc (reloc_size);
+ reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
+ if (reloc_count < 0)
+ bfd_fatal (bfd_get_filename (inbfd));
+ mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
+ size);
+
+ /* FIXME: refers to internal BFD fields. */
+ if (outsec->orelocation != (arelent **) NULL)
+ {
+ bfd_size_type total_count;
+ arelent **combined;
+
+ total_count = reloc_count + outsec->reloc_count;
+ combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
+ memcpy (combined, outsec->orelocation,
+ outsec->reloc_count * sizeof (arelent *));
+ memcpy (combined + outsec->reloc_count, relocs,
+ (size_t) (reloc_count * sizeof (arelent *)));
+ free (outsec->orelocation);
+ reloc_count = total_count;
+ relocs = combined;
+ }
+
+ bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
+ }
+
+ if (contents != NULL)
+ {
+ if (! bfd_set_section_contents (outbfd, outsec, contents,
+ insec->output_offset, size))
+ bfd_fatal (bfd_get_filename (outbfd));
+ free (contents);
+ }
+
+ /* Add this section to .nlmsections. */
+ if (! bfd_set_section_contents (outbfd, secsec, (PTR) inname, secsecoff,
+ strlen (inname) + 1))
+ bfd_fatal (_("set .nlmsection contents"));
+ secsecoff += strlen (inname) + 1;
+
+ add = ((secsecoff + 3) &~ 3) - secsecoff;
+ if (add != 0)
+ {
+ bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
+ if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
+ bfd_fatal (_("set .nlmsection contents"));
+ secsecoff += add;
+ }
+
+ if (contents != NULL)
+ bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
+ else
+ bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
+ if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
+ bfd_fatal (_("set .nlmsection contents"));
+ secsecoff += 4;
+
+ bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
+ if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
+ bfd_fatal (_("set .nlmsection contents"));
+ secsecoff += 4;
+}
+
+/* Some, perhaps all, NetWare targets require changing the relocs used
+ by the input formats. */
+
+static void
+mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
+ contents_size)
+ bfd *outbfd;
+ asection *insec;
+ arelent ***relocs_ptr;
+ long *reloc_count_ptr;
+ char *contents;
+ bfd_size_type contents_size;
+{
+ switch (bfd_get_arch (outbfd))
+ {
+#ifdef NLMCONV_I386
+ case bfd_arch_i386:
+ i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
+ contents, contents_size);
+ break;
+#endif
+#ifdef NLMCONV_ALPHA
+ case bfd_arch_alpha:
+ alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
+ contents, contents_size);
+ break;
+#endif
+#ifdef NLMCONV_POWERPC
+ case bfd_arch_powerpc:
+ powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
+ contents, contents_size);
+ break;
+#endif
+ default:
+ default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
+ contents, contents_size);
+ break;
+ }
+}
+
+/* By default all we need to do for relocs is change the address by
+ the output_offset. */
+
+/*ARGSUSED*/
+static void
+default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
+ contents_size)
+ bfd *outbfd;
+ asection *insec;
+ arelent ***relocs_ptr;
+ long *reloc_count_ptr;
+ char *contents;
+ bfd_size_type contents_size;
+{
+ if (insec->output_offset != 0)
+ {
+ long reloc_count;
+ register arelent **relocs;
+ register long i;
+
+ reloc_count = *reloc_count_ptr;
+ relocs = *relocs_ptr;
+ for (i = 0; i < reloc_count; i++, relocs++)
+ (*relocs)->address += insec->output_offset;
+ }
+}
+
+#ifdef NLMCONV_I386
+
+/* NetWare on the i386 supports a restricted set of relocs, which are
+ different from those used on other i386 targets. This routine
+ converts the relocs. It is, obviously, very target dependent. At
+ the moment, the nlm32-i386 backend performs similar translations;
+ however, it is more reliable and efficient to do them here. */
+
+static reloc_howto_type nlm_i386_pcrel_howto =
+ HOWTO (1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ true, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ 0, /* special_function */
+ "DISP32", /* name */
+ true, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ true); /* pcrel_offset */
+
+static void
+i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
+ contents_size)
+ bfd *outbfd;
+ asection *insec;
+ arelent ***relocs_ptr;
+ long *reloc_count_ptr;
+ char *contents;
+ bfd_size_type contents_size;
+{
+ long reloc_count, i;
+ arelent **relocs;
+
+ reloc_count = *reloc_count_ptr;
+ relocs = *relocs_ptr;
+ for (i = 0; i < reloc_count; i++)
+ {
+ arelent *rel;
+ asymbol *sym;
+ bfd_size_type address;
+ bfd_vma addend;
+
+ rel = *relocs++;
+ sym = *rel->sym_ptr_ptr;
+
+ /* We're moving the relocs from the input section to the output
+ section, so we must adjust the address accordingly. */
+ address = rel->address;
+ rel->address += insec->output_offset;
+
+ /* Note that no serious harm will ensue if we fail to change a
+ reloc. The backend will fail when writing out the reloc. */
+
+ /* Make sure this reloc is within the data we have. We use only
+ 4 byte relocs here, so we insist on having 4 bytes. */
+ if (address + 4 > contents_size)
+ continue;
+
+ /* A PC relative reloc entirely within a single section is
+ completely unnecessary. This can be generated by ld -r. */
+ if (sym == insec->symbol
+ && rel->howto != NULL
+ && rel->howto->pc_relative
+ && ! rel->howto->pcrel_offset)
+ {
+ --*reloc_count_ptr;
+ --relocs;
+ memmove (relocs, relocs + 1,
+ (size_t) ((reloc_count - i) * sizeof (arelent *)));
+ continue;
+ }
+
+ /* Get the amount the relocation will add in. */
+ addend = rel->addend + sym->value;
+
+ /* NetWare doesn't support PC relative relocs against defined
+ symbols, so we have to eliminate them by doing the relocation
+ now. We can only do this if the reloc is within a single
+ section. */
+ if (rel->howto != NULL
+ && rel->howto->pc_relative
+ && bfd_get_section (sym) == insec->output_section)
+ {
+ bfd_vma val;
+
+ if (rel->howto->pcrel_offset)
+ addend -= address;
+
+ val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
+ val += addend;
+ bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
+
+ --*reloc_count_ptr;
+ --relocs;
+ memmove (relocs, relocs + 1,
+ (size_t) ((reloc_count - i) * sizeof (arelent *)));
+ continue;
+ }
+
+ /* NetWare doesn't support reloc addends, so we get rid of them
+ here by simply adding them into the object data. We handle
+ the symbol value, if any, the same way. */
+ if (addend != 0
+ && rel->howto != NULL
+ && rel->howto->rightshift == 0
+ && rel->howto->size == 2
+ && rel->howto->bitsize == 32
+ && rel->howto->bitpos == 0
+ && rel->howto->src_mask == 0xffffffff
+ && rel->howto->dst_mask == 0xffffffff)
+ {
+ bfd_vma val;
+
+ val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
+ val += addend;
+ bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
+
+ /* Adjust the reloc for the changes we just made. */
+ rel->addend = 0;
+ if (! bfd_is_und_section (bfd_get_section (sym)))
+ rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
+ }
+
+ /* NetWare uses a reloc with pcrel_offset set. We adjust
+ pc_relative relocs accordingly. We are going to change the
+ howto field, so we can only do this if the current one is
+ compatible. We should check that special_function is NULL
+ here, but at the moment coff-i386 uses a special_function
+ which does not affect what we are doing here. */
+ if (rel->howto != NULL
+ && rel->howto->pc_relative
+ && ! rel->howto->pcrel_offset
+ && rel->howto->rightshift == 0
+ && rel->howto->size == 2
+ && rel->howto->bitsize == 32
+ && rel->howto->bitpos == 0
+ && rel->howto->src_mask == 0xffffffff
+ && rel->howto->dst_mask == 0xffffffff)
+ {
+ bfd_vma val;
+
+ /* When pcrel_offset is not set, it means that the negative
+ of the address of the memory location is stored in the
+ memory location. We must add it back in. */
+ val = bfd_get_32 (outbfd, (bfd_byte *) contents + address);
+ val += address;
+ bfd_put_32 (outbfd, val, (bfd_byte *) contents + address);
+
+ /* We must change to a new howto. */
+ rel->howto = &nlm_i386_pcrel_howto;
+ }
+ }
+}
+
+#endif /* NLMCONV_I386 */
+
+#ifdef NLMCONV_ALPHA
+
+/* On the Alpha the first reloc for every section must be a special
+ relocs which hold the GP address. Also, the first reloc in the
+ file must be a special reloc which holds the address of the .lita
+ section. */
+
+static reloc_howto_type nlm32_alpha_nw_howto =
+ HOWTO (ALPHA_R_NW_RELOC, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "NW_RELOC", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false); /* pcrel_offset */
+
+/*ARGSUSED*/
+static void
+alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
+ contents_size)
+ bfd *outbfd;
+ asection *insec;
+ register arelent ***relocs_ptr;
+ long *reloc_count_ptr;
+ char *contents;
+ bfd_size_type contents_size;
+{
+ long old_reloc_count;
+ arelent **old_relocs;
+ register arelent **relocs;
+
+ old_reloc_count = *reloc_count_ptr;
+ old_relocs = *relocs_ptr;
+ relocs = (arelent **) xmalloc ((old_reloc_count + 3) * sizeof (arelent *));
+ *relocs_ptr = relocs;
+
+ if (nlm_alpha_backend_data (outbfd)->lita_address == 0)
+ {
+ bfd *inbfd;
+ asection *lita_section;
+
+ inbfd = insec->owner;
+ lita_section = bfd_get_section_by_name (inbfd, _LITA);
+ if (lita_section != (asection *) NULL)
+ {
+ nlm_alpha_backend_data (outbfd)->lita_address =
+ bfd_get_section_vma (inbfd, lita_section);
+ nlm_alpha_backend_data (outbfd)->lita_size =
+ bfd_section_size (inbfd, lita_section);
+ }
+ else
+ {
+ /* Avoid outputting this reloc again. */
+ nlm_alpha_backend_data (outbfd)->lita_address = 4;
+ }
+
+ *relocs = (arelent *) xmalloc (sizeof (arelent));
+ (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ (*relocs)->address = nlm_alpha_backend_data (outbfd)->lita_address;
+ (*relocs)->addend = nlm_alpha_backend_data (outbfd)->lita_size + 1;
+ (*relocs)->howto = &nlm32_alpha_nw_howto;
+ ++relocs;
+ ++(*reloc_count_ptr);
+ }
+
+ /* Get the GP value from bfd. */
+ if (nlm_alpha_backend_data (outbfd)->gp == 0)
+ nlm_alpha_backend_data (outbfd)->gp =
+ bfd_ecoff_get_gp_value (insec->owner);
+
+ *relocs = (arelent *) xmalloc (sizeof (arelent));
+ (*relocs)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ (*relocs)->address = nlm_alpha_backend_data (outbfd)->gp;
+ (*relocs)->addend = 0;
+ (*relocs)->howto = &nlm32_alpha_nw_howto;
+ ++relocs;
+ ++(*reloc_count_ptr);
+
+ memcpy ((PTR) relocs, (PTR) old_relocs,
+ (size_t) old_reloc_count * sizeof (arelent *));
+ relocs[old_reloc_count] = (arelent *) NULL;
+
+ free (old_relocs);
+
+ if (insec->output_offset != 0)
+ {
+ register bfd_size_type i;
+
+ for (i = 0; i < (bfd_size_type) old_reloc_count; i++, relocs++)
+ (*relocs)->address += insec->output_offset;
+ }
+}
+
+#endif /* NLMCONV_ALPHA */
+
+#ifdef NLMCONV_POWERPC
+
+/* We keep a linked list of stubs which we must build. Because BFD
+ requires us to know the sizes of all sections before we can set the
+ contents of any, we must figure out which stubs we want to build
+ before we can actually build any of them. */
+
+struct powerpc_stub
+{
+ /* Next stub in linked list. */
+ struct powerpc_stub *next;
+
+ /* Symbol whose value is the start of the stub. This is a symbol
+ whose name begins with `.'. */
+ asymbol *start;
+
+ /* Symbol we are going to create a reloc against. This is a symbol
+ with the same name as START but without the leading `.'. */
+ asymbol *reloc;
+
+ /* The TOC index for this stub. This is the index into the TOC
+ section at which the reloc is created. */
+ unsigned int toc_index;
+};
+
+/* The linked list of stubs. */
+
+static struct powerpc_stub *powerpc_stubs;
+
+/* This is what a stub looks like. The first instruction will get
+ adjusted with the correct TOC index. */
+
+static unsigned long powerpc_stub_insns[] =
+{
+ 0x81820000, /* lwz r12,0(r2) */
+ 0x90410014, /* stw r2,20(r1) */
+ 0x800c0000, /* lwz r0,0(r12) */
+ 0x804c0004, /* lwz r2,r(r12) */
+ 0x7c0903a6, /* mtctr r0 */
+ 0x4e800420, /* bctr */
+ 0, /* Traceback table. */
+ 0xc8000,
+ 0
+};
+
+#define POWERPC_STUB_INSN_COUNT \
+ (sizeof powerpc_stub_insns / sizeof powerpc_stub_insns[0])
+
+#define POWERPC_STUB_SIZE (4 * POWERPC_STUB_INSN_COUNT)
+
+/* Each stub uses a four byte TOC entry. */
+#define POWERPC_STUB_TOC_ENTRY_SIZE (4)
+
+/* The original size of the .got section. */
+static bfd_size_type powerpc_initial_got_size;
+
+/* Look for all undefined symbols beginning with `.', and prepare to
+ build a stub for each one. */
+
+static void
+powerpc_build_stubs (inbfd, outbfd, symbols_ptr, symcount_ptr)
+ bfd *inbfd;
+ bfd *outbfd;
+ asymbol ***symbols_ptr;
+ long *symcount_ptr;
+{
+ asection *stub_sec;
+ asection *got_sec;
+ unsigned int got_base;
+ long i;
+ long symcount;
+ long stubcount;
+
+ /* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
+ the section to prevent copy_sections from reading from it. */
+ stub_sec = bfd_make_section (inbfd, ".stubs");
+ if (stub_sec == (asection *) NULL
+ || ! bfd_set_section_flags (inbfd, stub_sec,
+ (SEC_CODE
+ | SEC_RELOC
+ | SEC_ALLOC
+ | SEC_LOAD))
+ || ! bfd_set_section_alignment (inbfd, stub_sec, 2))
+ bfd_fatal (".stubs");
+
+ /* Get the TOC section, which is named .got. */
+ got_sec = bfd_get_section_by_name (inbfd, ".got");
+ if (got_sec == (asection *) NULL)
+ {
+ got_sec = bfd_make_section (inbfd, ".got");
+ if (got_sec == (asection *) NULL
+ || ! bfd_set_section_flags (inbfd, got_sec,
+ (SEC_DATA
+ | SEC_RELOC
+ | SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS))
+ || ! bfd_set_section_alignment (inbfd, got_sec, 2))
+ bfd_fatal (".got");
+ }
+
+ powerpc_initial_got_size = bfd_section_size (inbfd, got_sec);
+ got_base = powerpc_initial_got_size;
+ got_base = (got_base + 3) &~ 3;
+
+ stubcount = 0;
+
+ symcount = *symcount_ptr;
+ for (i = 0; i < symcount; i++)
+ {
+ asymbol *sym;
+ asymbol *newsym;
+ char *newname;
+ struct powerpc_stub *item;
+
+ sym = (*symbols_ptr)[i];
+
+ /* We must make a stub for every undefined symbol whose name
+ starts with '.'. */
+ if (bfd_asymbol_name (sym)[0] != '.'
+ || ! bfd_is_und_section (bfd_get_section (sym)))
+ continue;
+
+ /* Make a new undefined symbol with the same name but without
+ the leading `.'. */
+ newsym = (asymbol *) xmalloc (sizeof (asymbol));
+ *newsym = *sym;
+ newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
+ strcpy (newname, bfd_asymbol_name (sym) + 1);
+ newsym->name = newname;
+
+ /* Define the `.' symbol to be in the stub section. */
+ sym->section = stub_sec;
+ sym->value = stubcount * POWERPC_STUB_SIZE;
+ /* We set the BSF_DYNAMIC flag here so that we can check it when
+ we are mangling relocs. FIXME: This is a hack. */
+ sym->flags = BSF_LOCAL | BSF_DYNAMIC;
+
+ /* Add this stub to the linked list. */
+ item = (struct powerpc_stub *) xmalloc (sizeof (struct powerpc_stub));
+ item->start = sym;
+ item->reloc = newsym;
+ item->toc_index = got_base + stubcount * POWERPC_STUB_TOC_ENTRY_SIZE;
+
+ item->next = powerpc_stubs;
+ powerpc_stubs = item;
+
+ ++stubcount;
+ }
+
+ if (stubcount > 0)
+ {
+ asymbol **s;
+ struct powerpc_stub *l;
+
+ /* Add the new symbols we just created to the symbol table. */
+ *symbols_ptr = (asymbol **) xrealloc ((char *) *symbols_ptr,
+ ((symcount + stubcount)
+ * sizeof (asymbol)));
+ *symcount_ptr += stubcount;
+ s = &(*symbols_ptr)[symcount];
+ for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
+ *s++ = l->reloc;
+
+ /* Set the size of the .stubs section and increase the size of
+ the .got section. */
+ if (! bfd_set_section_size (inbfd, stub_sec,
+ stubcount * POWERPC_STUB_SIZE)
+ || ! bfd_set_section_size (inbfd, got_sec,
+ (got_base
+ + (stubcount
+ * POWERPC_STUB_TOC_ENTRY_SIZE))))
+ bfd_fatal (_("stub section sizes"));
+ }
+}
+
+/* Resolve all the stubs for PowerPC NetWare. We fill in the contents
+ of the output section, and create new relocs in the TOC. */
+
+static void
+powerpc_resolve_stubs (inbfd, outbfd)
+ bfd *inbfd;
+ bfd *outbfd;
+{
+ bfd_byte buf[POWERPC_STUB_SIZE];
+ unsigned int i;
+ unsigned int stubcount;
+ arelent **relocs;
+ asection *got_sec;
+ arelent **r;
+ struct powerpc_stub *l;
+
+ if (powerpc_stubs == (struct powerpc_stub *) NULL)
+ return;
+
+ for (i = 0; i < POWERPC_STUB_INSN_COUNT; i++)
+ bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[i], buf + i * 4);
+
+ got_sec = bfd_get_section_by_name (inbfd, ".got");
+ assert (got_sec != (asection *) NULL);
+ assert (got_sec->output_section->orelocation == (arelent **) NULL);
+
+ stubcount = 0;
+ for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
+ ++stubcount;
+ relocs = (arelent **) xmalloc (stubcount * sizeof (arelent *));
+
+ r = relocs;
+ for (l = powerpc_stubs; l != (struct powerpc_stub *) NULL; l = l->next)
+ {
+ arelent *reloc;
+
+ /* Adjust the first instruction to use the right TOC index. */
+ bfd_put_32 (outbfd, (bfd_vma) powerpc_stub_insns[0] + l->toc_index, buf);
+
+ /* Write this stub out. */
+ if (! bfd_set_section_contents (outbfd,
+ bfd_get_section (l->start),
+ buf,
+ l->start->value,
+ POWERPC_STUB_SIZE))
+ bfd_fatal (_("writing stub"));
+
+ /* Create a new reloc for the TOC entry. */
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = &l->reloc;
+ reloc->address = l->toc_index + got_sec->output_offset;
+ reloc->addend = 0;
+ reloc->howto = bfd_reloc_type_lookup (inbfd, BFD_RELOC_32);
+
+ *r++ = reloc;
+ }
+
+ bfd_set_reloc (outbfd, got_sec->output_section, relocs, stubcount);
+}
+
+/* Adjust relocation entries for PowerPC NetWare. We do not output
+ TOC relocations. The object code already contains the offset from
+ the TOC pointer. When the function is called, the TOC register,
+ r2, will be set to the correct TOC value, so there is no need for
+ any further reloc. */
+
+/*ARGSUSED*/
+static void
+powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr, contents,
+ contents_size)
+ bfd *outbfd;
+ asection *insec;
+ register arelent ***relocs_ptr;
+ long *reloc_count_ptr;
+ char *contents;
+ bfd_size_type contents_size;
+{
+ reloc_howto_type *toc_howto;
+ long reloc_count;
+ register arelent **relocs;
+ register long i;
+
+ toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
+ if (toc_howto == (reloc_howto_type *) NULL)
+ abort ();
+
+ /* If this is the .got section, clear out all the contents beyond
+ the initial size. We must do this here because copy_sections is
+ going to write out whatever we return in the contents field. */
+ if (strcmp (bfd_get_section_name (insec->owner, insec), ".got") == 0)
+ memset (contents + powerpc_initial_got_size, 0,
+ (size_t) (bfd_get_section_size_after_reloc (insec)
+ - powerpc_initial_got_size));
+
+ reloc_count = *reloc_count_ptr;
+ relocs = *relocs_ptr;
+ for (i = 0; i < reloc_count; i++)
+ {
+ arelent *rel;
+ asymbol *sym;
+ bfd_vma sym_value;
+
+ rel = *relocs++;
+ sym = *rel->sym_ptr_ptr;
+
+ /* Convert any relocs against the .bss section into relocs
+ against the .data section. */
+ if (strcmp (bfd_get_section_name (outbfd, bfd_get_section (sym)),
+ NLM_UNINITIALIZED_DATA_NAME) == 0)
+ {
+ asection *datasec;
+
+ datasec = bfd_get_section_by_name (outbfd,
+ NLM_INITIALIZED_DATA_NAME);
+ if (datasec != NULL)
+ {
+ rel->addend += (bfd_get_section_vma (outbfd,
+ bfd_get_section (sym))
+ + sym->value);
+ rel->sym_ptr_ptr = datasec->symbol_ptr_ptr;
+ sym = *rel->sym_ptr_ptr;
+ }
+ }
+
+ /* We must be able to resolve all PC relative relocs at this
+ point. If we get a branch to an undefined symbol we build a
+ stub, since NetWare will resolve undefined symbols into a
+ pointer to a function descriptor. */
+ if (rel->howto->pc_relative)
+ {
+ /* This check for whether a symbol is in the same section as
+ the reloc will be wrong if there is a PC relative reloc
+ between two sections both of which were placed in the
+ same output section. This should not happen. */
+ if (bfd_get_section (sym) != insec->output_section)
+ fprintf (stderr, _("%s: unresolved PC relative reloc against %s\n"),
+ program_name, bfd_asymbol_name (sym));
+ else
+ {
+ bfd_vma val;
+
+ assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
+ val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
+ val = ((val &~ rel->howto->dst_mask)
+ | (((val & rel->howto->src_mask)
+ + (sym->value - rel->address)
+ + rel->addend)
+ & rel->howto->dst_mask));
+ bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
+
+ /* If this reloc is against an stubbed symbol and the
+ next instruction is
+ cror 31,31,31
+ then we replace the next instruction with
+ lwz r2,20(r1)
+ This reloads the TOC pointer after a stub call. */
+ if (bfd_asymbol_name (sym)[0] == '.'
+ && (sym->flags & BSF_DYNAMIC) != 0
+ && (bfd_get_32 (outbfd,
+ (bfd_byte *) contents + rel->address + 4)
+ == 0x4ffffb82)) /* cror 31,31,31 */
+ bfd_put_32 (outbfd, (bfd_vma) 0x80410014, /* lwz r2,20(r1) */
+ (bfd_byte *) contents + rel->address + 4);
+
+ --*reloc_count_ptr;
+ --relocs;
+ memmove (relocs, relocs + 1,
+ (size_t) ((reloc_count - 1) * sizeof (arelent *)));
+ continue;
+ }
+ }
+
+ /* When considering a TOC reloc, we do not want to include the
+ symbol value. The symbol will be start of the TOC section
+ (which is named .got). We do want to include the addend. */
+ if (rel->howto == toc_howto)
+ sym_value = 0;
+ else
+ sym_value = sym->value;
+
+ /* If this is a relocation against a symbol with a value, or
+ there is a reloc addend, we need to update the addend in the
+ object file. */
+ if (sym_value + rel->addend != 0)
+ {
+ bfd_vma val;
+
+ switch (rel->howto->size)
+ {
+ case 1:
+ val = bfd_get_16 (outbfd,
+ (bfd_byte *) contents + rel->address);
+ val = ((val &~ rel->howto->dst_mask)
+ | (((val & rel->howto->src_mask)
+ + sym_value
+ + rel->addend)
+ & rel->howto->dst_mask));
+ if ((bfd_signed_vma) val < - 0x8000
+ || (bfd_signed_vma) val >= 0x8000)
+ fprintf (stderr,
+ _("%s: overflow when adjusting relocation against %s\n"),
+ program_name, bfd_asymbol_name (sym));
+ bfd_put_16 (outbfd, val, (bfd_byte *) contents + rel->address);
+ break;
+
+ case 2:
+ val = bfd_get_32 (outbfd,
+ (bfd_byte *) contents + rel->address);
+ val = ((val &~ rel->howto->dst_mask)
+ | (((val & rel->howto->src_mask)
+ + sym_value
+ + rel->addend)
+ & rel->howto->dst_mask));
+ bfd_put_32 (outbfd, val, (bfd_byte *) contents + rel->address);
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (! bfd_is_und_section (bfd_get_section (sym)))
+ rel->sym_ptr_ptr = bfd_get_section (sym)->symbol_ptr_ptr;
+ rel->addend = 0;
+ }
+
+ /* Now that we have incorporated the addend, remove any TOC
+ relocs. */
+ if (rel->howto == toc_howto)
+ {
+ --*reloc_count_ptr;
+ --relocs;
+ memmove (relocs, relocs + 1,
+ (size_t) ((reloc_count - i) * sizeof (arelent *)));
+ continue;
+ }
+
+ rel->address += insec->output_offset;
+ }
+}
+
+#endif /* NLMCONV_POWERPC */
+
+/* Name of linker. */
+#ifndef LD_NAME
+#define LD_NAME "ld"
+#endif
+
+/* Temporary file name base. */
+static char *temp_filename;
+
+/* The user has specified several input files. Invoke the linker to
+ link them all together, and convert and delete the resulting output
+ file. */
+
+static char *
+link_inputs (inputs, ld)
+ struct string_list *inputs;
+ char *ld;
+{
+ size_t c;
+ struct string_list *q;
+ char **argv;
+ size_t i;
+ int pid;
+ int status;
+ char *errfmt;
+ char *errarg;
+
+ c = 0;
+ for (q = inputs; q != NULL; q = q->next)
+ ++c;
+
+ argv = (char **) alloca ((c + 5) * sizeof(char *));
+
+#ifndef __MSDOS__
+ if (ld == NULL)
+ {
+ char *p;
+
+ /* Find the linker to invoke based on how nlmconv was run. */
+ p = program_name + strlen (program_name);
+ while (p != program_name)
+ {
+ if (p[-1] == '/')
+ {
+ ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
+ memcpy (ld, program_name, p - program_name);
+ strcpy (ld + (p - program_name), LD_NAME);
+ break;
+ }
+ --p;
+ }
+ }
+#endif
+
+ if (ld == NULL)
+ ld = (char *) LD_NAME;
+
+ temp_filename = choose_temp_base ();
+
+ unlink_on_exit = xmalloc (strlen (temp_filename) + 3);
+ sprintf (unlink_on_exit, "%s.O", temp_filename);
+
+ argv[0] = ld;
+ argv[1] = (char *) "-Ur";
+ argv[2] = (char *) "-o";
+ argv[3] = unlink_on_exit;
+ i = 4;
+ for (q = inputs; q != NULL; q = q->next, i++)
+ argv[i] = q->string;
+ argv[i] = NULL;
+
+ if (debug)
+ {
+ for (i = 0; argv[i] != NULL; i++)
+ fprintf (stderr, " %s", argv[i]);
+ fprintf (stderr, "\n");
+ }
+
+ pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
+ PEXECUTE_SEARCH | PEXECUTE_ONE);
+ if (pid == -1)
+ {
+ fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
+ fprintf (stderr, errfmt, errarg);
+ unlink (unlink_on_exit);
+ exit (1);
+ }
+
+ if (pwait (pid, &status, 0) < 0)
+ {
+ perror ("pwait");
+ unlink (unlink_on_exit);
+ exit (1);
+ }
+
+ if (status != 0)
+ {
+ fprintf (stderr, _("%s: Execution of %s failed\n"), program_name, ld);
+ unlink (unlink_on_exit);
+ exit (1);
+ }
+
+ return unlink_on_exit;
+}
diff --git a/binutils/nlmconv.h b/binutils/nlmconv.h
new file mode 100644
index 00000000000..c92a557bb7f
--- /dev/null
+++ b/binutils/nlmconv.h
@@ -0,0 +1,84 @@
+/* nlmconv.h -- header file for NLM conversion program
+ Copyright (C) 1993 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ bfd.h, nlm/common.h and nlm/internal.h must be included before this
+ file. */
+
+/* A linked list of strings. */
+
+struct string_list
+{
+ struct string_list *next;
+ char *string;
+};
+
+/* The NLM header parser in nlmheader.y stores information in the
+ following variables. */
+
+extern Nlm_Internal_Fixed_Header *fixed_hdr;
+extern Nlm_Internal_Variable_Header *var_hdr;
+extern Nlm_Internal_Version_Header *version_hdr;
+extern Nlm_Internal_Copyright_Header *copyright_hdr;
+extern Nlm_Internal_Extended_Header *extended_hdr;
+
+/* Procedure named by CHECK. */
+extern char *check_procedure;
+/* File named by CUSTOM. */
+extern char *custom_file;
+/* Whether to generate debugging information (DEBUG). */
+extern boolean debug_info;
+/* Procedure named by EXIT. */
+extern char *exit_procedure;
+/* Exported symbols (EXPORT). */
+extern struct string_list *export_symbols;
+/* List of files from INPUT. */
+extern struct string_list *input_files;
+/* Map file name (MAP, FULLMAP). */
+extern char *map_file;
+/* Whether a full map has been requested (FULLMAP). */
+extern boolean full_map;
+/* File named by HELP. */
+extern char *help_file;
+/* Imported symbols (IMPORT). */
+extern struct string_list *import_symbols;
+/* File named by MESSAGES. */
+extern char *message_file;
+/* Autoload module list (MODULE). */
+extern struct string_list *modules;
+/* File named by OUTPUT. */
+extern char *output_file;
+/* File named by SHARELIB. */
+extern char *sharelib_file;
+/* Start procedure name (START). */
+extern char *start_procedure;
+/* VERBOSE. */
+extern boolean verbose;
+/* RPC description file (XDCDATA). */
+extern char *rpc_file;
+
+/* The number of serious parse errors. */
+extern int parse_errors;
+
+/* The parser. */
+extern int yyparse PARAMS ((void));
+
+/* Tell the lexer what file to read. */
+extern boolean nlmlex_file PARAMS ((const char *));
diff --git a/binutils/nlmheader.y b/binutils/nlmheader.y
new file mode 100644
index 00000000000..0f1e22aa5e3
--- /dev/null
+++ b/binutils/nlmheader.y
@@ -0,0 +1,978 @@
+%{/* nlmheader.y - parse NLM header specification keywords.
+ Copyright (C) 1993, 94, 95, 97, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This bison file parses the commands recognized by the NetWare NLM
+ linker, except for lists of object files. It stores the
+ information in global variables.
+
+ This implementation is based on the description in the NetWare Tool
+ Maker Specification manual, edition 1.0. */
+
+#include <ansidecl.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "bfd.h"
+#include "bucomm.h"
+#include "nlm/common.h"
+#include "nlm/internal.h"
+#include "nlmconv.h"
+
+/* Information is stored in the structures pointed to by these
+ variables. */
+
+Nlm_Internal_Fixed_Header *fixed_hdr;
+Nlm_Internal_Variable_Header *var_hdr;
+Nlm_Internal_Version_Header *version_hdr;
+Nlm_Internal_Copyright_Header *copyright_hdr;
+Nlm_Internal_Extended_Header *extended_hdr;
+
+/* Procedure named by CHECK. */
+char *check_procedure;
+/* File named by CUSTOM. */
+char *custom_file;
+/* Whether to generate debugging information (DEBUG). */
+boolean debug_info;
+/* Procedure named by EXIT. */
+char *exit_procedure;
+/* Exported symbols (EXPORT). */
+struct string_list *export_symbols;
+/* List of files from INPUT. */
+struct string_list *input_files;
+/* Map file name (MAP, FULLMAP). */
+char *map_file;
+/* Whether a full map has been requested (FULLMAP). */
+boolean full_map;
+/* File named by HELP. */
+char *help_file;
+/* Imported symbols (IMPORT). */
+struct string_list *import_symbols;
+/* File named by MESSAGES. */
+char *message_file;
+/* Autoload module list (MODULE). */
+struct string_list *modules;
+/* File named by OUTPUT. */
+char *output_file;
+/* File named by SHARELIB. */
+char *sharelib_file;
+/* Start procedure name (START). */
+char *start_procedure;
+/* VERBOSE. */
+boolean verbose;
+/* RPC description file (XDCDATA). */
+char *rpc_file;
+
+/* The number of serious errors that have occurred. */
+int parse_errors;
+
+/* The current symbol prefix when reading a list of import or export
+ symbols. */
+static char *symbol_prefix;
+
+/* Parser error message handler. */
+#define yyerror(msg) nlmheader_error (msg);
+
+/* Local functions. */
+static int yylex PARAMS ((void));
+static void nlmlex_file_push PARAMS ((const char *));
+static boolean nlmlex_file_open PARAMS ((const char *));
+static int nlmlex_buf_init PARAMS ((void));
+static char nlmlex_buf_add PARAMS ((int));
+static long nlmlex_get_number PARAMS ((const char *));
+static void nlmheader_identify PARAMS ((void));
+static void nlmheader_warn PARAMS ((const char *, int));
+static void nlmheader_error PARAMS ((const char *));
+static struct string_list * string_list_cons PARAMS ((char *,
+ struct string_list *));
+static struct string_list * string_list_append PARAMS ((struct string_list *,
+ struct string_list *));
+static struct string_list * string_list_append1 PARAMS ((struct string_list *,
+ char *));
+static char *xstrdup PARAMS ((const char *));
+
+%}
+
+%union
+{
+ char *string;
+ struct string_list *list;
+};
+
+/* The reserved words. */
+
+%token CHECK CODESTART COPYRIGHT CUSTOM DATE DEBUG DESCRIPTION EXIT
+%token EXPORT FLAG_ON FLAG_OFF FULLMAP HELP IMPORT INPUT MAP MESSAGES
+%token MODULE MULTIPLE OS_DOMAIN OUTPUT PSEUDOPREEMPTION REENTRANT
+%token SCREENNAME SHARELIB STACK START SYNCHRONIZE
+%token THREADNAME TYPE VERBOSE VERSIONK XDCDATA
+
+/* Arguments. */
+
+%token <string> STRING
+%token <string> QUOTED_STRING
+
+/* Typed non-terminals. */
+%type <list> symbol_list_opt symbol_list string_list
+%type <string> symbol
+
+%%
+
+/* Keywords must start in the leftmost column of the file. Arguments
+ may appear anywhere else. The lexer uses this to determine what
+ token to return, so we don't have to worry about it here. */
+
+/* The entire file is just a list of commands. */
+
+file:
+ commands
+ ;
+
+/* A possibly empty list of commands. */
+
+commands:
+ /* May be empty. */
+ | command commands
+ ;
+
+/* A single command. There is where most of the work takes place. */
+
+command:
+ CHECK STRING
+ {
+ check_procedure = $2;
+ }
+ | CODESTART STRING
+ {
+ nlmheader_warn (_("CODESTART is not implemented; sorry"), -1);
+ free ($2);
+ }
+ | COPYRIGHT QUOTED_STRING
+ {
+ int len;
+
+ strncpy (copyright_hdr->stamp, "CoPyRiGhT=", 10);
+ len = strlen ($2);
+ if (len >= NLM_MAX_COPYRIGHT_MESSAGE_LENGTH)
+ {
+ nlmheader_warn (_("copyright string is too long"),
+ NLM_MAX_COPYRIGHT_MESSAGE_LENGTH - 1);
+ len = NLM_MAX_COPYRIGHT_MESSAGE_LENGTH - 1;
+ }
+ copyright_hdr->copyrightMessageLength = len;
+ strncpy (copyright_hdr->copyrightMessage, $2, len);
+ copyright_hdr->copyrightMessage[len] = '\0';
+ free ($2);
+ }
+ | CUSTOM STRING
+ {
+ custom_file = $2;
+ }
+ | DATE STRING STRING STRING
+ {
+ /* We don't set the version stamp here, because we use the
+ version stamp to detect whether the required VERSION
+ keyword was given. */
+ version_hdr->month = nlmlex_get_number ($2);
+ version_hdr->day = nlmlex_get_number ($3);
+ version_hdr->year = nlmlex_get_number ($4);
+ free ($2);
+ free ($3);
+ free ($4);
+ if (version_hdr->month < 1 || version_hdr->month > 12)
+ nlmheader_warn (_("illegal month"), -1);
+ if (version_hdr->day < 1 || version_hdr->day > 31)
+ nlmheader_warn (_("illegal day"), -1);
+ if (version_hdr->year < 1900 || version_hdr->year > 3000)
+ nlmheader_warn (_("illegal year"), -1);
+ }
+ | DEBUG
+ {
+ debug_info = true;
+ }
+ | DESCRIPTION QUOTED_STRING
+ {
+ int len;
+
+ len = strlen ($2);
+ if (len > NLM_MAX_DESCRIPTION_LENGTH)
+ {
+ nlmheader_warn (_("description string is too long"),
+ NLM_MAX_DESCRIPTION_LENGTH);
+ len = NLM_MAX_DESCRIPTION_LENGTH;
+ }
+ var_hdr->descriptionLength = len;
+ strncpy (var_hdr->descriptionText, $2, len);
+ var_hdr->descriptionText[len] = '\0';
+ free ($2);
+ }
+ | EXIT STRING
+ {
+ exit_procedure = $2;
+ }
+ | EXPORT
+ {
+ symbol_prefix = NULL;
+ }
+ symbol_list_opt
+ {
+ export_symbols = string_list_append (export_symbols, $3);
+ }
+ | FLAG_ON STRING
+ {
+ fixed_hdr->flags |= nlmlex_get_number ($2);
+ free ($2);
+ }
+ | FLAG_OFF STRING
+ {
+ fixed_hdr->flags &=~ nlmlex_get_number ($2);
+ free ($2);
+ }
+ | FULLMAP
+ {
+ map_file = "";
+ full_map = true;
+ }
+ | FULLMAP STRING
+ {
+ map_file = $2;
+ full_map = true;
+ }
+ | HELP STRING
+ {
+ help_file = $2;
+ }
+ | IMPORT
+ {
+ symbol_prefix = NULL;
+ }
+ symbol_list_opt
+ {
+ import_symbols = string_list_append (import_symbols, $3);
+ }
+ | INPUT string_list
+ {
+ input_files = string_list_append (input_files, $2);
+ }
+ | MAP
+ {
+ map_file = "";
+ }
+ | MAP STRING
+ {
+ map_file = $2;
+ }
+ | MESSAGES STRING
+ {
+ message_file = $2;
+ }
+ | MODULE string_list
+ {
+ modules = string_list_append (modules, $2);
+ }
+ | MULTIPLE
+ {
+ fixed_hdr->flags |= 0x2;
+ }
+ | OS_DOMAIN
+ {
+ fixed_hdr->flags |= 0x10;
+ }
+ | OUTPUT STRING
+ {
+ if (output_file == NULL)
+ output_file = $2;
+ else
+ nlmheader_warn (_("ignoring duplicate OUTPUT statement"), -1);
+ }
+ | PSEUDOPREEMPTION
+ {
+ fixed_hdr->flags |= 0x8;
+ }
+ | REENTRANT
+ {
+ fixed_hdr->flags |= 0x1;
+ }
+ | SCREENNAME QUOTED_STRING
+ {
+ int len;
+
+ len = strlen ($2);
+ if (len >= NLM_MAX_SCREEN_NAME_LENGTH)
+ {
+ nlmheader_warn (_("screen name is too long"),
+ NLM_MAX_SCREEN_NAME_LENGTH);
+ len = NLM_MAX_SCREEN_NAME_LENGTH;
+ }
+ var_hdr->screenNameLength = len;
+ strncpy (var_hdr->screenName, $2, len);
+ var_hdr->screenName[NLM_MAX_SCREEN_NAME_LENGTH] = '\0';
+ free ($2);
+ }
+ | SHARELIB STRING
+ {
+ sharelib_file = $2;
+ }
+ | STACK STRING
+ {
+ var_hdr->stackSize = nlmlex_get_number ($2);
+ free ($2);
+ }
+ | START STRING
+ {
+ start_procedure = $2;
+ }
+ | SYNCHRONIZE
+ {
+ fixed_hdr->flags |= 0x4;
+ }
+ | THREADNAME QUOTED_STRING
+ {
+ int len;
+
+ len = strlen ($2);
+ if (len >= NLM_MAX_THREAD_NAME_LENGTH)
+ {
+ nlmheader_warn (_("thread name is too long"),
+ NLM_MAX_THREAD_NAME_LENGTH);
+ len = NLM_MAX_THREAD_NAME_LENGTH;
+ }
+ var_hdr->threadNameLength = len;
+ strncpy (var_hdr->threadName, $2, len);
+ var_hdr->threadName[len] = '\0';
+ free ($2);
+ }
+ | TYPE STRING
+ {
+ fixed_hdr->moduleType = nlmlex_get_number ($2);
+ free ($2);
+ }
+ | VERBOSE
+ {
+ verbose = true;
+ }
+ | VERSIONK STRING STRING STRING
+ {
+ long val;
+
+ strncpy (version_hdr->stamp, "VeRsIoN#", 8);
+ version_hdr->majorVersion = nlmlex_get_number ($2);
+ val = nlmlex_get_number ($3);
+ if (val < 0 || val > 99)
+ nlmheader_warn (_("illegal minor version number (must be between 0 and 99)"),
+ -1);
+ else
+ version_hdr->minorVersion = val;
+ val = nlmlex_get_number ($4);
+ if (val < 0)
+ nlmheader_warn (_("illegal revision number (must be between 0 and 26)"),
+ -1);
+ else if (val > 26)
+ version_hdr->revision = 0;
+ else
+ version_hdr->revision = val;
+ free ($2);
+ free ($3);
+ free ($4);
+ }
+ | VERSIONK STRING STRING
+ {
+ long val;
+
+ strncpy (version_hdr->stamp, "VeRsIoN#", 8);
+ version_hdr->majorVersion = nlmlex_get_number ($2);
+ val = nlmlex_get_number ($3);
+ if (val < 0 || val > 99)
+ nlmheader_warn (_("illegal minor version number (must be between 0 and 99)"),
+ -1);
+ else
+ version_hdr->minorVersion = val;
+ version_hdr->revision = 0;
+ free ($2);
+ free ($3);
+ }
+ | XDCDATA STRING
+ {
+ rpc_file = $2;
+ }
+ ;
+
+/* A possibly empty list of symbols. */
+
+symbol_list_opt:
+ /* Empty. */
+ {
+ $$ = NULL;
+ }
+ | symbol_list
+ {
+ $$ = $1;
+ }
+ ;
+
+/* A list of symbols in an import or export list. Prefixes may appear
+ in parentheses. We need to use left recursion here to avoid
+ building up a large import list on the parser stack. */
+
+symbol_list:
+ symbol
+ {
+ $$ = string_list_cons ($1, NULL);
+ }
+ | symbol_prefix
+ {
+ $$ = NULL;
+ }
+ | symbol_list symbol
+ {
+ $$ = string_list_append1 ($1, $2);
+ }
+ | symbol_list symbol_prefix
+ {
+ $$ = $1;
+ }
+ ;
+
+/* A prefix for subsequent symbols. */
+
+symbol_prefix:
+ '(' STRING ')'
+ {
+ if (symbol_prefix != NULL)
+ free (symbol_prefix);
+ symbol_prefix = $2;
+ }
+ ;
+
+/* A single symbol. */
+
+symbol:
+ STRING
+ {
+ if (symbol_prefix == NULL)
+ $$ = $1;
+ else
+ {
+ $$ = xmalloc (strlen (symbol_prefix) + strlen ($1) + 2);
+ sprintf ($$, "%s@%s", symbol_prefix, $1);
+ free ($1);
+ }
+ }
+ ;
+
+/* A list of strings. */
+
+string_list:
+ /* May be empty. */
+ {
+ $$ = NULL;
+ }
+ | STRING string_list
+ {
+ $$ = string_list_cons ($1, $2);
+ }
+ ;
+
+%%
+
+/* If strerror is just a macro, we want to use the one from libiberty
+ since it will handle undefined values. */
+#undef strerror
+extern char *strerror ();
+
+/* The lexer is simple, too simple for flex. Keywords are only
+ recognized at the start of lines. Everything else must be an
+ argument. A comma is treated as whitespace. */
+
+/* The states the lexer can be in. */
+
+enum lex_state
+{
+ /* At the beginning of a line. */
+ BEGINNING_OF_LINE,
+ /* In the middle of a line. */
+ IN_LINE
+};
+
+/* We need to keep a stack of files to handle file inclusion. */
+
+struct input
+{
+ /* The file to read from. */
+ FILE *file;
+ /* The name of the file. */
+ char *name;
+ /* The current line number. */
+ int lineno;
+ /* The current state. */
+ enum lex_state state;
+ /* The next file on the stack. */
+ struct input *next;
+};
+
+/* The current input file. */
+
+static struct input current;
+
+/* The character which introduces comments. */
+#define COMMENT_CHAR '#'
+
+/* Start the lexer going on the main input file. */
+
+boolean
+nlmlex_file (name)
+ const char *name;
+{
+ current.next = NULL;
+ return nlmlex_file_open (name);
+}
+
+/* Start the lexer going on a subsidiary input file. */
+
+static void
+nlmlex_file_push (name)
+ const char *name;
+{
+ struct input *push;
+
+ push = (struct input *) xmalloc (sizeof (struct input));
+ *push = current;
+ if (nlmlex_file_open (name))
+ current.next = push;
+ else
+ {
+ current = *push;
+ free (push);
+ }
+}
+
+/* Start lexing from a file. */
+
+static boolean
+nlmlex_file_open (name)
+ const char *name;
+{
+ current.file = fopen (name, "r");
+ if (current.file == NULL)
+ {
+ fprintf (stderr, "%s:%s: %s\n", program_name, name, strerror (errno));
+ ++parse_errors;
+ return false;
+ }
+ current.name = xstrdup (name);
+ current.lineno = 1;
+ current.state = BEGINNING_OF_LINE;
+ return true;
+}
+
+/* Table used to turn keywords into tokens. */
+
+struct keyword_tokens_struct
+{
+ const char *keyword;
+ int token;
+};
+
+struct keyword_tokens_struct keyword_tokens[] =
+{
+ { "CHECK", CHECK },
+ { "CODESTART", CODESTART },
+ { "COPYRIGHT", COPYRIGHT },
+ { "CUSTOM", CUSTOM },
+ { "DATE", DATE },
+ { "DEBUG", DEBUG },
+ { "DESCRIPTION", DESCRIPTION },
+ { "EXIT", EXIT },
+ { "EXPORT", EXPORT },
+ { "FLAG_ON", FLAG_ON },
+ { "FLAG_OFF", FLAG_OFF },
+ { "FULLMAP", FULLMAP },
+ { "HELP", HELP },
+ { "IMPORT", IMPORT },
+ { "INPUT", INPUT },
+ { "MAP", MAP },
+ { "MESSAGES", MESSAGES },
+ { "MODULE", MODULE },
+ { "MULTIPLE", MULTIPLE },
+ { "OS_DOMAIN", OS_DOMAIN },
+ { "OUTPUT", OUTPUT },
+ { "PSEUDOPREEMPTION", PSEUDOPREEMPTION },
+ { "REENTRANT", REENTRANT },
+ { "SCREENNAME", SCREENNAME },
+ { "SHARELIB", SHARELIB },
+ { "STACK", STACK },
+ { "STACKSIZE", STACK },
+ { "START", START },
+ { "SYNCHRONIZE", SYNCHRONIZE },
+ { "THREADNAME", THREADNAME },
+ { "TYPE", TYPE },
+ { "VERBOSE", VERBOSE },
+ { "VERSION", VERSIONK },
+ { "XDCDATA", XDCDATA }
+};
+
+#define KEYWORD_COUNT (sizeof (keyword_tokens) / sizeof (keyword_tokens[0]))
+
+/* The lexer accumulates strings in these variables. */
+static char *lex_buf;
+static int lex_size;
+static int lex_pos;
+
+/* Start accumulating strings into the buffer. */
+#define BUF_INIT() \
+ ((void) (lex_buf != NULL ? lex_pos = 0 : nlmlex_buf_init ()))
+
+static int
+nlmlex_buf_init ()
+{
+ lex_size = 10;
+ lex_buf = xmalloc (lex_size + 1);
+ lex_pos = 0;
+ return 0;
+}
+
+/* Finish a string in the buffer. */
+#define BUF_FINISH() ((void) (lex_buf[lex_pos] = '\0'))
+
+/* Accumulate a character into the buffer. */
+#define BUF_ADD(c) \
+ ((void) (lex_pos < lex_size \
+ ? lex_buf[lex_pos++] = (c) \
+ : nlmlex_buf_add (c)))
+
+static char
+nlmlex_buf_add (c)
+ int c;
+{
+ if (lex_pos >= lex_size)
+ {
+ lex_size *= 2;
+ lex_buf = xrealloc (lex_buf, lex_size + 1);
+ }
+
+ return lex_buf[lex_pos++] = c;
+}
+
+/* The lexer proper. This is called by the bison generated parsing
+ code. */
+
+static int
+yylex ()
+{
+ int c;
+
+tail_recurse:
+
+ c = getc (current.file);
+
+ /* Commas are treated as whitespace characters. */
+ while (isspace ((unsigned char) c) || c == ',')
+ {
+ current.state = IN_LINE;
+ if (c == '\n')
+ {
+ ++current.lineno;
+ current.state = BEGINNING_OF_LINE;
+ }
+ c = getc (current.file);
+ }
+
+ /* At the end of the file we either pop to the previous file or
+ finish up. */
+ if (c == EOF)
+ {
+ fclose (current.file);
+ free (current.name);
+ if (current.next == NULL)
+ return 0;
+ else
+ {
+ struct input *next;
+
+ next = current.next;
+ current = *next;
+ free (next);
+ goto tail_recurse;
+ }
+ }
+
+ /* A comment character always means to drop everything until the
+ next newline. */
+ if (c == COMMENT_CHAR)
+ {
+ do
+ {
+ c = getc (current.file);
+ }
+ while (c != '\n');
+ ++current.lineno;
+ current.state = BEGINNING_OF_LINE;
+ goto tail_recurse;
+ }
+
+ /* An '@' introduces an include file. */
+ if (c == '@')
+ {
+ do
+ {
+ c = getc (current.file);
+ if (c == '\n')
+ ++current.lineno;
+ }
+ while (isspace ((unsigned char) c));
+ BUF_INIT ();
+ while (! isspace ((unsigned char) c) && c != EOF)
+ {
+ BUF_ADD (c);
+ c = getc (current.file);
+ }
+ BUF_FINISH ();
+
+ ungetc (c, current.file);
+
+ nlmlex_file_push (lex_buf);
+ goto tail_recurse;
+ }
+
+ /* A non-space character at the start of a line must be the start of
+ a keyword. */
+ if (current.state == BEGINNING_OF_LINE)
+ {
+ BUF_INIT ();
+ while (isalnum ((unsigned char) c) || c == '_')
+ {
+ if (islower ((unsigned char) c))
+ BUF_ADD (toupper ((unsigned char) c));
+ else
+ BUF_ADD (c);
+ c = getc (current.file);
+ }
+ BUF_FINISH ();
+
+ if (c != EOF && ! isspace ((unsigned char) c) && c != ',')
+ {
+ nlmheader_identify ();
+ fprintf (stderr, _("%s:%d: illegal character in keyword: %c\n"),
+ current.name, current.lineno, c);
+ }
+ else
+ {
+ unsigned int i;
+
+ for (i = 0; i < KEYWORD_COUNT; i++)
+ {
+ if (lex_buf[0] == keyword_tokens[i].keyword[0]
+ && strcmp (lex_buf, keyword_tokens[i].keyword) == 0)
+ {
+ /* Pushing back the final whitespace avoids worrying
+ about \n here. */
+ ungetc (c, current.file);
+ current.state = IN_LINE;
+ return keyword_tokens[i].token;
+ }
+ }
+
+ nlmheader_identify ();
+ fprintf (stderr, _("%s:%d: unrecognized keyword: %s\n"),
+ current.name, current.lineno, lex_buf);
+ }
+
+ ++parse_errors;
+ /* Treat the rest of this line as a comment. */
+ ungetc (COMMENT_CHAR, current.file);
+ goto tail_recurse;
+ }
+
+ /* Parentheses just represent themselves. */
+ if (c == '(' || c == ')')
+ return c;
+
+ /* Handle quoted strings. */
+ if (c == '"' || c == '\'')
+ {
+ int quote;
+ int start_lineno;
+
+ quote = c;
+ start_lineno = current.lineno;
+
+ c = getc (current.file);
+ BUF_INIT ();
+ while (c != quote && c != EOF)
+ {
+ BUF_ADD (c);
+ if (c == '\n')
+ ++current.lineno;
+ c = getc (current.file);
+ }
+ BUF_FINISH ();
+
+ if (c == EOF)
+ {
+ nlmheader_identify ();
+ fprintf (stderr, _("%s:%d: end of file in quoted string\n"),
+ current.name, start_lineno);
+ ++parse_errors;
+ }
+
+ /* FIXME: Possible memory leak. */
+ yylval.string = xstrdup (lex_buf);
+ return QUOTED_STRING;
+ }
+
+ /* Gather a generic argument. */
+ BUF_INIT ();
+ while (! isspace (c)
+ && c != ','
+ && c != COMMENT_CHAR
+ && c != '('
+ && c != ')')
+ {
+ BUF_ADD (c);
+ c = getc (current.file);
+ }
+ BUF_FINISH ();
+
+ ungetc (c, current.file);
+
+ /* FIXME: Possible memory leak. */
+ yylval.string = xstrdup (lex_buf);
+ return STRING;
+}
+
+/* Get a number from a string. */
+
+static long
+nlmlex_get_number (s)
+ const char *s;
+{
+ long ret;
+ char *send;
+
+ ret = strtol (s, &send, 10);
+ if (*send != '\0')
+ nlmheader_warn (_("bad number"), -1);
+ return ret;
+}
+
+/* Prefix the nlmconv warnings with a note as to where they come from.
+ We don't use program_name on every warning, because then some
+ versions of the emacs next-error function can't recognize the line
+ number. */
+
+static void
+nlmheader_identify ()
+{
+ static int done;
+
+ if (! done)
+ {
+ fprintf (stderr, _("%s: problems in NLM command language input:\n"),
+ program_name);
+ done = 1;
+ }
+}
+
+/* Issue a warning. */
+
+static void
+nlmheader_warn (s, imax)
+ const char *s;
+ int imax;
+{
+ nlmheader_identify ();
+ fprintf (stderr, "%s:%d: %s", current.name, current.lineno, s);
+ if (imax != -1)
+ fprintf (stderr, " (max %d)", imax);
+ fprintf (stderr, "\n");
+}
+
+/* Report an error. */
+
+static void
+nlmheader_error (s)
+ const char *s;
+{
+ nlmheader_warn (s, -1);
+ ++parse_errors;
+}
+
+/* Add a string to a string list. */
+
+static struct string_list *
+string_list_cons (s, l)
+ char *s;
+ struct string_list *l;
+{
+ struct string_list *ret;
+
+ ret = (struct string_list *) xmalloc (sizeof (struct string_list));
+ ret->next = l;
+ ret->string = s;
+ return ret;
+}
+
+/* Append a string list to another string list. */
+
+static struct string_list *
+string_list_append (l1, l2)
+ struct string_list *l1;
+ struct string_list *l2;
+{
+ register struct string_list **pp;
+
+ for (pp = &l1; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = l2;
+ return l1;
+}
+
+/* Append a string to a string list. */
+
+static struct string_list *
+string_list_append1 (l, s)
+ struct string_list *l;
+ char *s;
+{
+ struct string_list *n;
+ register struct string_list **pp;
+
+ n = (struct string_list *) xmalloc (sizeof (struct string_list));
+ n->next = NULL;
+ n->string = s;
+ for (pp = &l; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = n;
+ return l;
+}
+
+/* Duplicate a string in memory. */
+
+static char *
+xstrdup (s)
+ const char *s;
+{
+ unsigned long len;
+ char *ret;
+
+ len = strlen (s);
+ ret = xmalloc (len + 1);
+ strcpy (ret, s);
+ return ret;
+}
diff --git a/binutils/nm.1 b/binutils/nm.1
new file mode 100644
index 00000000000..c2ad99e559a
--- /dev/null
+++ b/binutils/nm.1
@@ -0,0 +1,230 @@
+.\" Copyright (c) 1991 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH nm 1 "5 November 1991" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+nm \- list symbols from object files.
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B nm
+.RB "[\|" \-a | \-\-debug\-syms "\|]"
+.RB "[\|" \-g | \-\-extern\-only "\|]"
+.RB "[\|" \-B "\|]"
+.RB "[\|" \-C | \-\-demangle "\|]"
+.RB "[\|" \-D | \-\-dynamic "\|]"
+.RB "[\|" \-s | \-\-print\-armap "\|]"
+.RB "[\|" \-o | \-\-print\-file\-name "\|]"
+.RB "[\|" \-n | \-\-numeric\-sort "\|]"
+.RB "[\|" \-p | \-\-no\-sort "\|]"
+.RB "[\|" \-r | \-\-reverse\-sort "\|]"
+.RB "[\|" \-\-size\-sort "\|]"
+.RB "[\|" \-u | \-\-undefined\-only "\|]"
+.RB "[\|" \-l | \-\-line\-numbers "\|]"
+.RB "[\|" \-\-help "\|]"
+.RB "[\|" \-\-version "\|]"
+.RB "[\|" "\-t \fIradix" | \-\-radix=\fIradix "\|]"
+.RB "[\|" \-P | --portability "\|]"
+.RB "[\|" "\-f \fIformat" | \-\-format=\fIformat "\|]"
+.RB "[\|" "\-\-target=\fIbfdname" "\|]"
+.RB "[\|" \c
+.I objfile\c
+\&.\|.\|.\|]
+.ad b
+.hy 1
+.SH DESCRIPTION
+GNU \c
+.B nm\c
+\& lists the symbols from object files \c
+.I objfile\c
+\&. If no object files are given as arguments, \c
+.B nm\c
+\& assumes `\|\c
+.B a.out\c
+\|'.
+
+.SH OPTIONS
+The long and short forms of options, shown here as alternatives, are
+equivalent.
+
+.TP
+.B \-A
+.TP
+.B \-o
+.TP
+.B \-\-print\-file\-name
+Precede each symbol by the name of the input file where it was found,
+rather than identifying the input file once only before all of its
+symbols.
+
+.TP
+.B \-a
+.TP
+.B \-\-debug\-syms
+Display debugger-only symbols; normally these are not listed.
+
+.TP
+.B \-B
+The same as
+.B \-\-format=bsd
+(for compatibility with the MIPS \fBnm\fP).
+
+.TP
+.B \-C
+.TP
+.B \-\-demangle
+Decode (\fIdemangle\fP) low-level symbol names into user-level names.
+Besides removing any initial underscore prepended by the system, this
+makes C++ function names readable.
+
+.TP
+.B \-D
+.TP
+.B \-\-dynamic
+Display the dynamic symbols rather than the normal symbols. This is
+only meaningful for dynamic objects, such as certain types of shared
+libraries.
+
+.TP
+.B "\-f \fIformat"
+Use the output format \fIformat\fP, which can be ``bsd'',
+``sysv'', or ``posix''. The default is ``bsd''.
+Only the first character of \fIformat\fP is significant; it can be
+either upper or lower case.
+
+.TP
+.B \-g
+.TP
+.B \-\-extern\-only
+Display only external symbols.
+
+.TP
+.B \-n
+.TP
+.B \-v
+.TP
+.B \-\-numeric\-sort
+Sort symbols numerically by their addresses, not alphabetically by their
+names.
+
+.TP
+.B \-p
+.TP
+.B \-\-no\-sort
+Don't bother to sort the symbols in any order; just print them in the
+order encountered.
+
+.TP
+.B \-P
+.TP
+.B \-\-portability
+Use the POSIX.2 standard output format instead of the default format.
+Equivalent to ``\-f posix''.
+
+.TP
+.B \-s
+.TP
+.B \-\-print\-armap
+When listing symbols from archive members, include the index: a mapping
+(stored in the archive by \c
+.B ar\c
+\& or \c
+.B ranlib\c
+\&) of what modules
+contain definitions for what names.
+
+.TP
+.B \-r
+.TP
+.B \-\-reverse\-sort
+Reverse the sense of the sort (whether numeric or alphabetic); let the
+last come first.
+
+.TP
+.B \-\-size\-sort
+Sort symbols by size. The size is computed as the difference between
+the value of the symbol and the value of the symbol with the next higher
+value. The size of the symbol is printed, rather than the value.
+
+.TP
+.B "\-t \fIradix"
+.TP
+.B "\-\-radix=\fIradix"
+Use \fIradix\fP as the radix for printing the symbol values. It must be
+``d'' for decimal, ``o'' for octal, or ``x'' for hexadecimal.
+
+.TP
+.BI "\-\-target=" "bfdname"
+Specify an object code format other than your system's default format.
+See
+.BR objdump ( 1 ),
+for information on listing available formats.
+
+.TP
+.B \-u
+.TP
+.B \-\-undefined\-only
+Display only undefined symbols (those external to each object file).
+
+.TP
+.B \-l
+.TP
+.B \-\-line\-numbers
+For each symbol, use debugging information to try to find a filename and
+line number. For a defined symbol, look for the line number of the
+address of the symbol. For an undefined symbol, look for the line
+number of a relocation entry which refers to the symbol. If line number
+information can be found, print it after the other symbol information.
+
+.TP
+.B \-V
+.TP
+.B \-\-version
+Show the version number of
+.B nm
+and exit.
+
+.TP
+.B \-\-help
+Show a summary of the options to
+.B nm
+and exit.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (October 1991);
+.BR ar "(" 1 "),"
+.BR objdump ( 1 ),
+.BR ranlib "(" 1 ")."
+
+
+.SH COPYING
+Copyright (c) 1991 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/nm.c b/binutils/nm.c
new file mode 100644
index 00000000000..c51b7fbcc40
--- /dev/null
+++ b/binutils/nm.c
@@ -0,0 +1,1558 @@
+/* nm.c -- Describe symbol table of a rel file.
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "progress.h"
+#include "bucomm.h"
+#include "getopt.h"
+#include "aout/stab_gnu.h"
+#include "aout/ranlib.h"
+#include "demangle.h"
+#include "libiberty.h"
+
+/* When sorting by size, we use this structure to hold the size and a
+ pointer to the minisymbol. */
+
+struct size_sym
+{
+ const PTR minisym;
+ bfd_vma size;
+};
+
+/* When fetching relocs, we use this structure to pass information to
+ get_relocs. */
+
+struct get_relocs_info
+{
+ asection **secs;
+ arelent ***relocs;
+ long *relcount;
+ asymbol **syms;
+};
+
+static void
+usage PARAMS ((FILE *, int));
+
+static void
+set_print_radix PARAMS ((char *));
+
+static void
+set_output_format PARAMS ((char *));
+
+static void
+display_archive PARAMS ((bfd *));
+
+static boolean
+display_file PARAMS ((char *filename));
+
+static void
+display_rel_file PARAMS ((bfd * file, bfd * archive));
+
+static long
+filter_symbols PARAMS ((bfd *, boolean, PTR, long, unsigned int));
+
+static long
+sort_symbols_by_size PARAMS ((bfd *, boolean, PTR, long, unsigned int,
+ struct size_sym **));
+
+static void
+print_symbols PARAMS ((bfd *, boolean, PTR, long, unsigned int, bfd *));
+
+static void
+print_size_symbols PARAMS ((bfd *, boolean, struct size_sym *, long, bfd *));
+
+static void
+print_symname PARAMS ((const char *, const char *, bfd *));
+
+static void
+print_symbol PARAMS ((bfd *, asymbol *, bfd *));
+
+static void
+print_symdef_entry PARAMS ((bfd * abfd));
+
+/* The sorting functions. */
+
+static int
+numeric_forward PARAMS ((const PTR, const PTR));
+
+static int
+numeric_reverse PARAMS ((const PTR, const PTR));
+
+static int
+non_numeric_forward PARAMS ((const PTR, const PTR));
+
+static int
+non_numeric_reverse PARAMS ((const PTR, const PTR));
+
+static int
+size_forward1 PARAMS ((const PTR, const PTR));
+
+static int
+size_forward2 PARAMS ((const PTR, const PTR));
+
+/* The output formatting functions. */
+
+static void
+print_object_filename_bsd PARAMS ((char *filename));
+
+static void
+print_object_filename_sysv PARAMS ((char *filename));
+
+static void
+print_object_filename_posix PARAMS ((char *filename));
+
+
+static void
+print_archive_filename_bsd PARAMS ((char *filename));
+
+static void
+print_archive_filename_sysv PARAMS ((char *filename));
+
+static void
+print_archive_filename_posix PARAMS ((char *filename));
+
+
+static void
+print_archive_member_bsd PARAMS ((char *archive, CONST char *filename));
+
+static void
+print_archive_member_sysv PARAMS ((char *archive, CONST char *filename));
+
+static void
+print_archive_member_posix PARAMS ((char *archive, CONST char *filename));
+
+
+static void
+print_symbol_filename_bsd PARAMS ((bfd * archive_bfd, bfd * abfd));
+
+static void
+print_symbol_filename_sysv PARAMS ((bfd * archive_bfd, bfd * abfd));
+
+static void
+print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd));
+
+
+static void
+print_value PARAMS ((bfd_vma));
+
+static void
+print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd));
+
+static void
+print_symbol_info_sysv PARAMS ((symbol_info * info, bfd * abfd));
+
+static void
+print_symbol_info_posix PARAMS ((symbol_info * info, bfd * abfd));
+
+static void
+get_relocs PARAMS ((bfd *, asection *, PTR));
+
+/* Support for different output formats. */
+struct output_fns
+ {
+ /* Print the name of an object file given on the command line. */
+ void (*print_object_filename) PARAMS ((char *filename));
+
+ /* Print the name of an archive file given on the command line. */
+ void (*print_archive_filename) PARAMS ((char *filename));
+
+ /* Print the name of an archive member file. */
+ void (*print_archive_member) PARAMS ((char *archive, CONST char *filename));
+
+ /* Print the name of the file (and archive, if there is one)
+ containing a symbol. */
+ void (*print_symbol_filename) PARAMS ((bfd * archive_bfd, bfd * abfd));
+
+ /* Print a line of information about a symbol. */
+ void (*print_symbol_info) PARAMS ((symbol_info * info, bfd * abfd));
+ };
+static struct output_fns formats[] =
+{
+ {print_object_filename_bsd,
+ print_archive_filename_bsd,
+ print_archive_member_bsd,
+ print_symbol_filename_bsd,
+ print_symbol_info_bsd},
+ {print_object_filename_sysv,
+ print_archive_filename_sysv,
+ print_archive_member_sysv,
+ print_symbol_filename_sysv,
+ print_symbol_info_sysv},
+ {print_object_filename_posix,
+ print_archive_filename_posix,
+ print_archive_member_posix,
+ print_symbol_filename_posix,
+ print_symbol_info_posix}
+};
+
+/* Indices in `formats'. */
+#define FORMAT_BSD 0
+#define FORMAT_SYSV 1
+#define FORMAT_POSIX 2
+#define FORMAT_DEFAULT FORMAT_BSD
+
+/* The output format to use. */
+static struct output_fns *format = &formats[FORMAT_DEFAULT];
+
+
+/* Command options. */
+
+static int do_demangle = 0; /* Pretty print C++ symbol names. */
+static int external_only = 0; /* print external symbols only */
+static int defined_only = 0; /* Print defined symbols only */
+static int no_sort = 0; /* don't sort; print syms in order found */
+static int print_debug_syms = 0; /* print debugger-only symbols too */
+static int print_armap = 0; /* describe __.SYMDEF data in archive files. */
+static int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
+static int sort_numerically = 0; /* sort in numeric rather than alpha order */
+static int sort_by_size = 0; /* sort by size of symbol */
+static int undefined_only = 0; /* print undefined symbols only */
+static int dynamic = 0; /* print dynamic symbols. */
+static int show_version = 0; /* show the version number */
+static int show_stats = 0; /* show statistics */
+static int line_numbers = 0; /* print line numbers for symbols */
+
+/* When to print the names of files. Not mutually exclusive in SYSV format. */
+static int filename_per_file = 0; /* Once per file, on its own line. */
+static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
+
+/* Print formats for printing a symbol value. */
+#ifndef BFD64
+static char value_format[] = "%08lx";
+#else
+#if BFD_HOST_64BIT_LONG
+static char value_format[] = "%016lx";
+#else
+/* We don't use value_format for this case. */
+#endif
+#endif
+static int print_radix = 16;
+/* Print formats for printing stab info. */
+static char other_format[] = "%02x";
+static char desc_format[] = "%04x";
+
+static char *target = NULL;
+
+/* Used to cache the line numbers for a BFD. */
+static bfd *lineno_cache_bfd;
+static bfd *lineno_cache_rel_bfd;
+
+static struct option long_options[] =
+{
+ {"debug-syms", no_argument, &print_debug_syms, 1},
+ {"demangle", no_argument, &do_demangle, 1},
+ {"dynamic", no_argument, &dynamic, 1},
+ {"extern-only", no_argument, &external_only, 1},
+ {"format", required_argument, 0, 'f'},
+ {"help", no_argument, 0, 'h'},
+ {"line-numbers", no_argument, 0, 'l'},
+ {"no-cplus", no_argument, &do_demangle, 0}, /* Linux compatibility. */
+ {"no-demangle", no_argument, &do_demangle, 0},
+ {"no-sort", no_argument, &no_sort, 1},
+ {"numeric-sort", no_argument, &sort_numerically, 1},
+ {"portability", no_argument, 0, 'P'},
+ {"print-armap", no_argument, &print_armap, 1},
+ {"print-file-name", no_argument, 0, 'o'},
+ {"radix", required_argument, 0, 't'},
+ {"reverse-sort", no_argument, &reverse_sort, 1},
+ {"size-sort", no_argument, &sort_by_size, 1},
+ {"stats", no_argument, &show_stats, 1},
+ {"target", required_argument, 0, 200},
+ {"defined-only", no_argument, &defined_only, 1},
+ {"undefined-only", no_argument, &undefined_only, 1},
+ {"version", no_argument, &show_version, 1},
+ {0, no_argument, 0, 0}
+};
+
+/* Some error-reporting functions */
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, _("\
+Usage: %s [-aABCDglnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n\
+ [--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n\
+ [--numeric-sort] [--no-sort] [--reverse-sort] [--size-sort]\n\
+ [--undefined-only] [--portability] [-f {bsd,sysv,posix}]\n\
+ [--format={bsd,sysv,posix}] [--demangle] [--no-demangle] [--dynamic]\n\
+ [--defined-only] [--line-numbers]\n\
+ [--version] [--help]\n\
+ [file...]\n"),
+ program_name);
+ list_supported_targets (program_name, stream);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+/* Set the radix for the symbol value and size according to RADIX. */
+
+static void
+set_print_radix (radix)
+ char *radix;
+{
+ switch (*radix)
+ {
+ case 'x':
+ break;
+ case 'd':
+ case 'o':
+ if (*radix == 'd')
+ print_radix = 10;
+ else
+ print_radix = 8;
+#ifndef BFD64
+ value_format[4] = *radix;
+#else
+#if BFD_HOST_64BIT_LONG
+ value_format[5] = *radix;
+#else
+ /* This case requires special handling for octal and decimal
+ printing. */
+#endif
+#endif
+ other_format[3] = desc_format[3] = *radix;
+ break;
+ default:
+ fprintf (stderr, _("%s: %s: invalid radix\n"), program_name, radix);
+ exit (1);
+ }
+}
+
+static void
+set_output_format (f)
+ char *f;
+{
+ int i;
+
+ switch (*f)
+ {
+ case 'b':
+ case 'B':
+ i = FORMAT_BSD;
+ break;
+ case 'p':
+ case 'P':
+ i = FORMAT_POSIX;
+ break;
+ case 's':
+ case 'S':
+ i = FORMAT_SYSV;
+ break;
+ default:
+ fprintf (stderr, _("%s: %s: invalid output format\n"), program_name, f);
+ exit (1);
+ }
+ format = &formats[i];
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int retval;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = *argv;
+ xmalloc_set_program_name (program_name);
+
+ START_PROGRESS (program_name, 0);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ while ((c = getopt_long (argc, argv, "aABCDef:glnopPrst:uvV", long_options, (int *) 0)) != EOF)
+ {
+ switch (c)
+ {
+ case 'a':
+ print_debug_syms = 1;
+ break;
+ case 'A':
+ case 'o':
+ filename_per_symbol = 1;
+ break;
+ case 'B': /* For MIPS compatibility. */
+ set_output_format ("bsd");
+ break;
+ case 'C':
+ do_demangle = 1;
+ break;
+ case 'D':
+ dynamic = 1;
+ break;
+ case 'e':
+ /* Ignored for HP/UX compatibility. */
+ break;
+ case 'f':
+ set_output_format (optarg);
+ break;
+ case 'g':
+ external_only = 1;
+ break;
+ case 'h':
+ usage (stdout, 0);
+ case 'l':
+ line_numbers = 1;
+ break;
+ case 'n':
+ case 'v':
+ sort_numerically = 1;
+ break;
+ case 'p':
+ no_sort = 1;
+ break;
+ case 'P':
+ set_output_format ("posix");
+ break;
+ case 'r':
+ reverse_sort = 1;
+ break;
+ case 's':
+ print_armap = 1;
+ break;
+ case 't':
+ set_print_radix (optarg);
+ break;
+ case 'u':
+ undefined_only = 1;
+ break;
+ case 'V':
+ show_version = 1;
+ break;
+
+ case 200: /* --target */
+ target = optarg;
+ break;
+
+ case 0: /* A long option that just sets a flag. */
+ break;
+
+ default:
+ usage (stderr, 1);
+ }
+ }
+
+ if (show_version)
+ print_version ("nm");
+
+ /* OK, all options now parsed. If no filename specified, do a.out. */
+ if (optind == argc)
+ return !display_file ("a.out");
+
+ retval = 0;
+
+ if (argc - optind > 1)
+ filename_per_file = 1;
+
+ /* We were given several filenames to do. */
+ while (optind < argc)
+ {
+ PROGRESS (1);
+ if (!display_file (argv[optind++]))
+ retval++;
+ }
+
+ END_PROGRESS (program_name);
+
+#ifdef HAVE_SBRK
+ if (show_stats)
+ {
+ char *lim = (char *) sbrk (0);
+
+ fprintf (stderr, _("%s: data size %ld\n"), program_name,
+ (long) (lim - (char *) &environ));
+ }
+#endif
+
+ exit (retval);
+ return retval;
+}
+
+static void
+display_archive (file)
+ bfd *file;
+{
+ bfd *arfile = NULL;
+ bfd *last_arfile = NULL;
+ char **matching;
+
+ (*format->print_archive_filename) (bfd_get_filename (file));
+
+ if (print_armap)
+ print_symdef_entry (file);
+
+ for (;;)
+ {
+ PROGRESS (1);
+
+ arfile = bfd_openr_next_archived_file (file, arfile);
+
+ if (arfile == NULL)
+ {
+ if (bfd_get_error () != bfd_error_no_more_archived_files)
+ bfd_fatal (bfd_get_filename (file));
+ break;
+ }
+
+ if (bfd_check_format_matches (arfile, bfd_object, &matching))
+ {
+ (*format->print_archive_member) (bfd_get_filename (file),
+ bfd_get_filename (arfile));
+ display_rel_file (arfile, file);
+ }
+ else
+ {
+ bfd_nonfatal (bfd_get_filename (arfile));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ }
+
+ if (last_arfile != NULL)
+ {
+ bfd_close (last_arfile);
+ lineno_cache_bfd = NULL;
+ lineno_cache_rel_bfd = NULL;
+ }
+ last_arfile = arfile;
+ }
+
+ if (last_arfile != NULL)
+ {
+ bfd_close (last_arfile);
+ lineno_cache_bfd = NULL;
+ lineno_cache_rel_bfd = NULL;
+ }
+}
+
+static boolean
+display_file (filename)
+ char *filename;
+{
+ boolean retval = true;
+ bfd *file;
+ char **matching;
+
+ file = bfd_openr (filename, target);
+ if (file == NULL)
+ {
+ bfd_nonfatal (filename);
+ return false;
+ }
+
+ if (bfd_check_format (file, bfd_archive))
+ {
+ display_archive (file);
+ }
+ else if (bfd_check_format_matches (file, bfd_object, &matching))
+ {
+ (*format->print_object_filename) (filename);
+ display_rel_file (file, NULL);
+ }
+ else
+ {
+ bfd_nonfatal (filename);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ retval = false;
+ }
+
+ if (bfd_close (file) == false)
+ bfd_fatal (filename);
+
+ lineno_cache_bfd = NULL;
+ lineno_cache_rel_bfd = NULL;
+
+ return retval;
+}
+
+/* These globals are used to pass information into the sorting
+ routines. */
+static bfd *sort_bfd;
+static boolean sort_dynamic;
+static asymbol *sort_x;
+static asymbol *sort_y;
+
+/* Symbol-sorting predicates */
+#define valueof(x) ((x)->section->vma + (x)->value)
+
+/* Numeric sorts. Undefined symbols are always considered "less than"
+ defined symbols with zero values. Common symbols are not treated
+ specially -- i.e., their sizes are used as their "values". */
+
+static int
+numeric_forward (P_x, P_y)
+ const PTR P_x;
+ const PTR P_y;
+{
+ asymbol *x, *y;
+ asection *xs, *ys;
+
+ x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
+ y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
+ if (x == NULL || y == NULL)
+ bfd_fatal (bfd_get_filename (sort_bfd));
+
+ xs = bfd_get_section (x);
+ ys = bfd_get_section (y);
+
+ if (bfd_is_und_section (xs))
+ {
+ if (! bfd_is_und_section (ys))
+ return -1;
+ }
+ else if (bfd_is_und_section (ys))
+ return 1;
+ else if (valueof (x) != valueof (y))
+ return valueof (x) < valueof (y) ? -1 : 1;
+
+ return non_numeric_forward (P_x, P_y);
+}
+
+static int
+numeric_reverse (x, y)
+ const PTR x;
+ const PTR y;
+{
+ return - numeric_forward (x, y);
+}
+
+static int
+non_numeric_forward (P_x, P_y)
+ const PTR P_x;
+ const PTR P_y;
+{
+ asymbol *x, *y;
+ const char *xn, *yn;
+
+ x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
+ y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
+ if (x == NULL || y == NULL)
+ bfd_fatal (bfd_get_filename (sort_bfd));
+
+ xn = bfd_asymbol_name (x);
+ yn = bfd_asymbol_name (y);
+
+ return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
+ ((yn == NULL) ? 1 : strcmp (xn, yn)));
+}
+
+static int
+non_numeric_reverse (x, y)
+ const PTR x;
+ const PTR y;
+{
+ return - non_numeric_forward (x, y);
+}
+
+static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
+{
+ { non_numeric_forward, non_numeric_reverse },
+ { numeric_forward, numeric_reverse }
+};
+
+/* This sort routine is used by sort_symbols_by_size. It is similar
+ to numeric_forward, but when symbols have the same value it sorts
+ by section VMA. This simplifies the sort_symbols_by_size code
+ which handles symbols at the end of sections. Also, this routine
+ tries to sort file names before other symbols with the same value.
+ That will make the file name have a zero size, which will make
+ sort_symbols_by_size choose the non file name symbol, leading to
+ more meaningful output. For similar reasons, this code sorts
+ gnu_compiled_* and gcc2_compiled before other symbols with the same
+ value. */
+
+static int
+size_forward1 (P_x, P_y)
+ const PTR P_x;
+ const PTR P_y;
+{
+ asymbol *x, *y;
+ asection *xs, *ys;
+ const char *xn, *yn;
+ size_t xnl, ynl;
+ int xf, yf;
+
+ x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
+ y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
+ if (x == NULL || y == NULL)
+ bfd_fatal (bfd_get_filename (sort_bfd));
+
+ xs = bfd_get_section (x);
+ ys = bfd_get_section (y);
+
+ if (bfd_is_und_section (xs))
+ abort ();
+ if (bfd_is_und_section (ys))
+ abort ();
+
+ if (valueof (x) != valueof (y))
+ return valueof (x) < valueof (y) ? -1 : 1;
+
+ if (xs->vma != ys->vma)
+ return xs->vma < ys->vma ? -1 : 1;
+
+ xn = bfd_asymbol_name (x);
+ yn = bfd_asymbol_name (y);
+ xnl = strlen (xn);
+ ynl = strlen (yn);
+
+ /* The symbols gnu_compiled and gcc2_compiled convey even less
+ information than the file name, so sort them out first. */
+
+ xf = (strstr (xn, "gnu_compiled") != NULL
+ || strstr (xn, "gcc2_compiled") != NULL);
+ yf = (strstr (yn, "gnu_compiled") != NULL
+ || strstr (yn, "gcc2_compiled") != NULL);
+
+ if (xf && ! yf)
+ return -1;
+ if (! xf && yf)
+ return 1;
+
+ /* We use a heuristic for the file name. It may not work on non
+ Unix systems, but it doesn't really matter; the only difference
+ is precisely which symbol names get printed. */
+
+#define file_symbol(s, sn, snl) \
+ (((s)->flags & BSF_FILE) != 0 \
+ || ((sn)[(snl) - 2] == '.' \
+ && ((sn)[(snl) - 1] == 'o' \
+ || (sn)[(snl) - 1] == 'a')))
+
+ xf = file_symbol (x, xn, xnl);
+ yf = file_symbol (y, yn, ynl);
+
+ if (xf && ! yf)
+ return -1;
+ if (! xf && yf)
+ return 1;
+
+ return non_numeric_forward (P_x, P_y);
+}
+
+/* This sort routine is used by sort_symbols_by_size. It is sorting
+ an array of size_sym structures into size order. */
+
+static int
+size_forward2 (P_x, P_y)
+ const PTR P_x;
+ const PTR P_y;
+{
+ const struct size_sym *x = (const struct size_sym *) P_x;
+ const struct size_sym *y = (const struct size_sym *) P_y;
+
+ if (x->size < y->size)
+ return reverse_sort ? 1 : -1;
+ else if (x->size > y->size)
+ return reverse_sort ? -1 : 1;
+ else
+ return sorters[0][reverse_sort] (x->minisym, y->minisym);
+}
+
+/* Sort the symbols by size. We guess the size by assuming that the
+ difference between the address of a symbol and the address of the
+ next higher symbol is the size. FIXME: ELF actually stores a size
+ with each symbol. We should use it. */
+
+static long
+sort_symbols_by_size (abfd, dynamic, minisyms, symcount, size, symsizesp)
+ bfd *abfd;
+ boolean dynamic;
+ PTR minisyms;
+ long symcount;
+ unsigned int size;
+ struct size_sym **symsizesp;
+{
+ struct size_sym *symsizes;
+ bfd_byte *from, *fromend;
+ asymbol *sym = NULL;
+ asymbol *store_sym, *store_next;
+
+ qsort (minisyms, symcount, size, size_forward1);
+
+ /* We are going to return a special set of symbols and sizes to
+ print. */
+ symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
+ *symsizesp = symsizes;
+
+ /* Note that filter_symbols has already removed all absolute and
+ undefined symbols. Here we remove all symbols whose size winds
+ up as zero. */
+
+ from = (bfd_byte *) minisyms;
+ fromend = from + symcount * size;
+
+ store_sym = sort_x;
+ store_next = sort_y;
+
+ if (from < fromend)
+ {
+ sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from,
+ store_sym);
+ if (sym == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+ }
+
+ for (; from < fromend; from += size)
+ {
+ asymbol *next;
+ asection *sec;
+ bfd_vma sz;
+ asymbol *temp;
+
+ if (from + size < fromend)
+ {
+ next = bfd_minisymbol_to_symbol (abfd,
+ dynamic,
+ (const PTR) (from + size),
+ store_next);
+ if (next == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+ }
+ else
+ next = NULL;
+
+ sec = bfd_get_section (sym);
+
+ if (bfd_is_com_section (sec))
+ sz = sym->value;
+ else
+ {
+ if (from + size < fromend
+ && sec == bfd_get_section (next))
+ sz = valueof (next) - valueof (sym);
+ else
+ sz = (bfd_get_section_vma (abfd, sec)
+ + bfd_section_size (abfd, sec)
+ - valueof (sym));
+ }
+
+ if (sz != 0)
+ {
+ symsizes->minisym = (const PTR) from;
+ symsizes->size = sz;
+ ++symsizes;
+ }
+
+ sym = next;
+
+ temp = store_sym;
+ store_sym = store_next;
+ store_next = temp;
+ }
+
+ symcount = symsizes - *symsizesp;
+
+ /* We must now sort again by size. */
+ qsort ((PTR) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
+
+ return symcount;
+}
+
+/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
+
+static void
+display_rel_file (abfd, archive_bfd)
+ bfd *abfd;
+ bfd *archive_bfd;
+{
+ long symcount;
+ PTR minisyms;
+ unsigned int size;
+ struct size_sym *symsizes;
+
+ if (! dynamic)
+ {
+ if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+ {
+ fprintf (stderr, _("%s: no symbols\n"), bfd_get_filename (abfd));
+ return;
+ }
+ }
+
+ symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (symcount == 0)
+ {
+ fprintf (stderr, _("%s: no symbols\n"), bfd_get_filename (abfd));
+ return;
+ }
+
+ /* Discard the symbols we don't want to print.
+ It's OK to do this in place; we'll free the storage anyway
+ (after printing). */
+
+ symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
+
+ symsizes = NULL;
+ if (! no_sort)
+ {
+ sort_bfd = abfd;
+ sort_dynamic = dynamic;
+ sort_x = bfd_make_empty_symbol (abfd);
+ sort_y = bfd_make_empty_symbol (abfd);
+ if (sort_x == NULL || sort_y == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (! sort_by_size)
+ qsort (minisyms, symcount, size,
+ sorters[sort_numerically][reverse_sort]);
+ else
+ symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
+ size, &symsizes);
+ }
+
+ if (! sort_by_size)
+ print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
+ else
+ print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
+
+ free (minisyms);
+}
+
+/* Choose which symbol entries to print;
+ compact them downward to get rid of the rest.
+ Return the number of symbols to be printed. */
+
+static long
+filter_symbols (abfd, dynamic, minisyms, symcount, size)
+ bfd *abfd;
+ boolean dynamic;
+ PTR minisyms;
+ long symcount;
+ unsigned int size;
+{
+ bfd_byte *from, *fromend, *to;
+ asymbol *store;
+
+ store = bfd_make_empty_symbol (abfd);
+ if (store == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ from = (bfd_byte *) minisyms;
+ fromend = from + symcount * size;
+ to = (bfd_byte *) minisyms;
+
+ for (; from < fromend; from += size)
+ {
+ int keep = 0;
+ asymbol *sym;
+
+ PROGRESS (1);
+
+ sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from, store);
+ if (sym == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (undefined_only)
+ keep = bfd_is_und_section (sym->section);
+ else if (external_only)
+ keep = ((sym->flags & BSF_GLOBAL) != 0
+ || (sym->flags & BSF_WEAK) != 0
+ || bfd_is_und_section (sym->section)
+ || bfd_is_com_section (sym->section));
+ else
+ keep = 1;
+
+ if (keep
+ && ! print_debug_syms
+ && (sym->flags & BSF_DEBUGGING) != 0)
+ keep = 0;
+
+ if (keep
+ && sort_by_size
+ && (bfd_is_abs_section (sym->section)
+ || bfd_is_und_section (sym->section)))
+ keep = 0;
+
+ if (keep
+ && defined_only)
+ {
+ if (bfd_is_und_section (sym->section))
+ keep = 0;
+ }
+
+ if (keep)
+ {
+ memcpy (to, from, size);
+ to += size;
+ }
+ }
+
+ return (to - (bfd_byte *) minisyms) / size;
+}
+
+/* Print symbol name NAME, read from ABFD, with printf format FORMAT,
+ demangling it if requested. */
+
+static void
+print_symname (format, name, abfd)
+ const char *format;
+ const char *name;
+ bfd *abfd;
+{
+ if (do_demangle && *name)
+ {
+ char *res;
+
+ /* In this mode, give a user-level view of the symbol name
+ even if it's not mangled; strip off any leading
+ underscore. */
+ if (bfd_get_symbol_leading_char (abfd) == name[0])
+ name++;
+
+ res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ if (res)
+ {
+ printf (format, res);
+ free (res);
+ return;
+ }
+ }
+
+ printf (format, name);
+}
+
+/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
+ containing ABFD. */
+
+static void
+print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd)
+ bfd *abfd;
+ boolean dynamic;
+ PTR minisyms;
+ long symcount;
+ unsigned int size;
+ bfd *archive_bfd;
+{
+ asymbol *store;
+ bfd_byte *from, *fromend;
+
+ store = bfd_make_empty_symbol (abfd);
+ if (store == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ from = (bfd_byte *) minisyms;
+ fromend = from + symcount * size;
+ for (; from < fromend; from += size)
+ {
+ asymbol *sym;
+
+ sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store);
+ if (sym == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ print_symbol (abfd, sym, archive_bfd);
+ }
+}
+
+/* Print the symbols when sorting by size. */
+
+static void
+print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd)
+ bfd *abfd;
+ boolean dynamic;
+ struct size_sym *symsizes;
+ long symcount;
+ bfd *archive_bfd;
+{
+ asymbol *store;
+ struct size_sym *from, *fromend;
+
+ store = bfd_make_empty_symbol (abfd);
+ if (store == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ from = symsizes;
+ fromend = from + symcount;
+ for (; from < fromend; from++)
+ {
+ asymbol *sym;
+
+ sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store);
+ if (sym == NULL)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ /* Set the symbol value so that we actually display the symbol
+ size. */
+ sym->value = from->size - bfd_section_vma (abfd, bfd_get_section (sym));
+
+ print_symbol (abfd, sym, archive_bfd);
+ }
+}
+
+/* Print a single symbol. */
+
+static void
+print_symbol (abfd, sym, archive_bfd)
+ bfd *abfd;
+ asymbol *sym;
+ bfd *archive_bfd;
+{
+ PROGRESS (1);
+
+ (*format->print_symbol_filename) (archive_bfd, abfd);
+
+ if (undefined_only)
+ {
+ if (bfd_is_und_section (bfd_get_section (sym)))
+ print_symname ("%s", bfd_asymbol_name (sym), abfd);
+ }
+ else
+ {
+ symbol_info syminfo;
+
+ bfd_get_symbol_info (abfd, sym, &syminfo);
+ (*format->print_symbol_info) (&syminfo, abfd);
+ }
+
+ if (line_numbers)
+ {
+ static asymbol **syms;
+ static long symcount;
+ const char *filename, *functionname;
+ unsigned int lineno;
+
+ /* We need to get the canonical symbols in order to call
+ bfd_find_nearest_line. This is inefficient, but, then, you
+ don't have to use --line-numbers. */
+ if (abfd != lineno_cache_bfd && syms != NULL)
+ {
+ free (syms);
+ syms = NULL;
+ }
+ if (syms == NULL)
+ {
+ long symsize;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ syms = (asymbol **) xmalloc (symsize);
+ symcount = bfd_canonicalize_symtab (abfd, syms);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ lineno_cache_bfd = abfd;
+ }
+
+ if (bfd_is_und_section (bfd_get_section (sym)))
+ {
+ static asection **secs;
+ static arelent ***relocs;
+ static long *relcount;
+ static unsigned int seccount;
+ unsigned int i;
+ const char *symname;
+
+ /* For an undefined symbol, we try to find a reloc for the
+ symbol, and print the line number of the reloc. */
+
+ if (abfd != lineno_cache_rel_bfd && relocs != NULL)
+ {
+ for (i = 0; i < seccount; i++)
+ if (relocs[i] != NULL)
+ free (relocs[i]);
+ free (secs);
+ free (relocs);
+ free (relcount);
+ secs = NULL;
+ relocs = NULL;
+ relcount = NULL;
+ }
+
+ if (relocs == NULL)
+ {
+ struct get_relocs_info info;
+
+ seccount = bfd_count_sections (abfd);
+
+ secs = (asection **) xmalloc (seccount * sizeof *secs);
+ relocs = (arelent ***) xmalloc (seccount * sizeof *relocs);
+ relcount = (long *) xmalloc (seccount * sizeof *relcount);
+
+ info.secs = secs;
+ info.relocs = relocs;
+ info.relcount = relcount;
+ info.syms = syms;
+ bfd_map_over_sections (abfd, get_relocs, (PTR) &info);
+ lineno_cache_rel_bfd = abfd;
+ }
+
+ symname = bfd_asymbol_name (sym);
+ for (i = 0; i < seccount; i++)
+ {
+ long j;
+
+ for (j = 0; j < relcount[i]; j++)
+ {
+ arelent *r;
+
+ r = relocs[i][j];
+ if (r->sym_ptr_ptr != NULL
+ && (*r->sym_ptr_ptr)->section == sym->section
+ && (*r->sym_ptr_ptr)->value == sym->value
+ && strcmp (symname,
+ bfd_asymbol_name (*r->sym_ptr_ptr)) == 0
+ && bfd_find_nearest_line (abfd, secs[i], syms,
+ r->address, &filename,
+ &functionname, &lineno))
+ {
+ /* We only print the first one we find. */
+ printf ("\t%s:%u", filename, lineno);
+ i = seccount;
+ break;
+ }
+ }
+ }
+ }
+ else if (bfd_get_section (sym)->owner == abfd)
+ {
+ if (bfd_find_nearest_line (abfd, bfd_get_section (sym), syms,
+ sym->value, &filename, &functionname,
+ &lineno)
+ && filename != NULL
+ && lineno != 0)
+ {
+ printf ("\t%s:%u", filename, lineno);
+ }
+ }
+ }
+
+ putchar ('\n');
+}
+
+/* The following 3 groups of functions are called unconditionally,
+ once at the start of processing each file of the appropriate type.
+ They should check `filename_per_file' and `filename_per_symbol',
+ as appropriate for their output format, to determine whether to
+ print anything. */
+
+/* Print the name of an object file given on the command line. */
+
+static void
+print_object_filename_bsd (filename)
+ char *filename;
+{
+ if (filename_per_file && !filename_per_symbol)
+ printf ("\n%s:\n", filename);
+}
+
+static void
+print_object_filename_sysv (filename)
+ char *filename;
+{
+ if (undefined_only)
+ printf (_("\n\nUndefined symbols from %s:\n\n"), filename);
+ else
+ printf (_("\n\nSymbols from %s:\n\n"), filename);
+ printf (_("\
+Name Value Class Type Size Line Section\n\n"));
+}
+
+static void
+print_object_filename_posix (filename)
+ char *filename;
+{
+ if (filename_per_file && !filename_per_symbol)
+ printf ("%s:\n", filename);
+}
+
+/* Print the name of an archive file given on the command line. */
+
+static void
+print_archive_filename_bsd (filename)
+ char *filename;
+{
+ if (filename_per_file)
+ printf ("\n%s:\n", filename);
+}
+
+static void
+print_archive_filename_sysv (filename)
+ char *filename;
+{
+}
+
+static void
+print_archive_filename_posix (filename)
+ char *filename;
+{
+}
+
+/* Print the name of an archive member file. */
+
+static void
+print_archive_member_bsd (archive, filename)
+ char *archive;
+ CONST char *filename;
+{
+ if (!filename_per_symbol)
+ printf ("\n%s:\n", filename);
+}
+
+static void
+print_archive_member_sysv (archive, filename)
+ char *archive;
+ CONST char *filename;
+{
+ if (undefined_only)
+ printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename);
+ else
+ printf (_("\n\nSymbols from %s[%s]:\n\n"), archive, filename);
+ printf (_("\
+Name Value Class Type Size Line Section\n\n"));
+}
+
+static void
+print_archive_member_posix (archive, filename)
+ char *archive;
+ CONST char *filename;
+{
+ if (!filename_per_symbol)
+ printf ("%s[%s]:\n", archive, filename);
+}
+
+/* Print the name of the file (and archive, if there is one)
+ containing a symbol. */
+
+static void
+print_symbol_filename_bsd (archive_bfd, abfd)
+ bfd *archive_bfd, *abfd;
+{
+ if (filename_per_symbol)
+ {
+ if (archive_bfd)
+ printf ("%s:", bfd_get_filename (archive_bfd));
+ printf ("%s:", bfd_get_filename (abfd));
+ }
+}
+
+static void
+print_symbol_filename_sysv (archive_bfd, abfd)
+ bfd *archive_bfd, *abfd;
+{
+ if (filename_per_symbol)
+ {
+ if (archive_bfd)
+ printf ("%s:", bfd_get_filename (archive_bfd));
+ printf ("%s:", bfd_get_filename (abfd));
+ }
+}
+
+static void
+print_symbol_filename_posix (archive_bfd, abfd)
+ bfd *archive_bfd, *abfd;
+{
+ if (filename_per_symbol)
+ {
+ if (archive_bfd)
+ printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
+ bfd_get_filename (abfd));
+ else
+ printf ("%s: ", bfd_get_filename (abfd));
+ }
+}
+
+/* Print a symbol value. */
+
+static void
+print_value (val)
+ bfd_vma val;
+{
+#if ! defined (BFD64) || BFD_HOST_64BIT_LONG
+ printf (value_format, val);
+#else
+ /* We have a 64 bit value to print, but the host is only 32 bit. */
+ if (print_radix == 16)
+ fprintf_vma (stdout, val);
+ else
+ {
+ char buf[30];
+ char *s;
+
+ s = buf + sizeof buf;
+ *--s = '\0';
+ while (val > 0)
+ {
+ *--s = (val % print_radix) + '0';
+ val /= print_radix;
+ }
+ while ((buf + sizeof buf - 1) - s < 16)
+ *--s = '0';
+ printf ("%s", s);
+ }
+#endif
+}
+
+/* Print a line of information about a symbol. */
+
+static void
+print_symbol_info_bsd (info, abfd)
+ symbol_info *info;
+ bfd *abfd;
+{
+ if (info->type == 'U')
+ {
+ printf ("%*s",
+#ifdef BFD64
+ 16,
+#else
+ 8,
+#endif
+ "");
+ }
+ else
+ print_value (info->value);
+ printf (" %c", info->type);
+ if (info->type == '-')
+ {
+ /* A stab. */
+ printf (" ");
+ printf (other_format, info->stab_other);
+ printf (" ");
+ printf (desc_format, info->stab_desc);
+ printf (" %5s", info->stab_name);
+ }
+ print_symname (" %s", info->name, abfd);
+}
+
+static void
+print_symbol_info_sysv (info, abfd)
+ symbol_info *info;
+ bfd *abfd;
+{
+ print_symname ("%-20s|", info->name, abfd); /* Name */
+ if (info->type == 'U')
+ printf (" "); /* Value */
+ else
+ print_value (info->value);
+ printf ("| %c |", info->type); /* Class */
+ if (info->type == '-')
+ {
+ /* A stab. */
+ printf ("%18s| ", info->stab_name); /* (C) Type */
+ printf (desc_format, info->stab_desc); /* Size */
+ printf ("| |"); /* Line, Section */
+ }
+ else
+ printf (" | | |"); /* Type, Size, Line, Section */
+}
+
+static void
+print_symbol_info_posix (info, abfd)
+ symbol_info *info;
+ bfd *abfd;
+{
+ print_symname ("%s ", info->name, abfd);
+ printf ("%c ", info->type);
+ if (info->type == 'U')
+ printf (" ");
+ else
+ print_value (info->value);
+ /* POSIX.2 wants the symbol size printed here, when applicable;
+ BFD currently doesn't provide it, so we take the easy way out by
+ considering it to never be applicable. */
+}
+
+static void
+print_symdef_entry (abfd)
+ bfd *abfd;
+{
+ symindex idx = BFD_NO_MORE_SYMBOLS;
+ carsym *thesym;
+ boolean everprinted = false;
+
+ for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
+ idx != BFD_NO_MORE_SYMBOLS;
+ idx = bfd_get_next_mapent (abfd, idx, &thesym))
+ {
+ bfd *elt;
+ if (!everprinted)
+ {
+ printf (_("\nArchive index:\n"));
+ everprinted = true;
+ }
+ elt = bfd_get_elt_at_index (abfd, idx);
+ if (elt == NULL)
+ bfd_fatal ("bfd_get_elt_at_index");
+ if (thesym->name != (char *) NULL)
+ {
+ print_symname ("%s", thesym->name, abfd);
+ printf (" in %s\n", bfd_get_filename (elt));
+ }
+ }
+}
+
+/* This function is used to get the relocs for a particular section.
+ It is called via bfd_map_over_sections. */
+
+static void
+get_relocs (abfd, sec, dataarg)
+ bfd *abfd;
+ asection *sec;
+ PTR dataarg;
+{
+ struct get_relocs_info *data = (struct get_relocs_info *) dataarg;
+
+ *data->secs = sec;
+
+ if ((sec->flags & SEC_RELOC) == 0)
+ {
+ *data->relocs = NULL;
+ *data->relcount = 0;
+ }
+ else
+ {
+ long relsize;
+
+ relsize = bfd_get_reloc_upper_bound (abfd, sec);
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ *data->relocs = (arelent **) xmalloc (relsize);
+ *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs,
+ data->syms);
+ if (*data->relcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ }
+
+ ++data->secs;
+ ++data->relocs;
+ ++data->relcount;
+}
diff --git a/binutils/not-ranlib.c b/binutils/not-ranlib.c
new file mode 100644
index 00000000000..afb9ceb3d67
--- /dev/null
+++ b/binutils/not-ranlib.c
@@ -0,0 +1,3 @@
+/* Linked with ar.o to flag that this program is 'ar' (not 'ranlib'). */
+
+int is_ranlib = 0;
diff --git a/binutils/not-strip.c b/binutils/not-strip.c
new file mode 100644
index 00000000000..98093ce391a
--- /dev/null
+++ b/binutils/not-strip.c
@@ -0,0 +1,4 @@
+/* Linked with objcopy.o to flag that this program is 'objcopy' (not
+ 'strip'). */
+
+int is_strip = 0;
diff --git a/binutils/objcopy.1 b/binutils/objcopy.1
new file mode 100644
index 00000000000..aee77601498
--- /dev/null
+++ b/binutils/objcopy.1
@@ -0,0 +1,319 @@
+.\" Copyright (c) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH objcopy 1 "October 1994" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+objcopy \- copy and translate object files
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B objcopy
+.RB "[\|" \-F\ \fIbfdname\fR\ |\ \fB\-\-target=\fIbfdname\fR "\|]"
+.RB "[\|" \-I\ \fIbfdname\fR\ |\ \fB\-\-input\-target=\fIbfdname\fR "\|]"
+.RB "[\|" \-O\ \fIbfdname\fR\ |\ \fB\-\-output\-target=\fIbfdname\fR "\|]"
+.RB "[\|" \-R\ \fIsectionname\fR\ |\ \fB\-\-remove\-section=\fIsectionname\fR "\|]"
+.RB "[\|" \-S\fR\ |\ \fB\-\-strip\-all\fR "\|]"
+.RB "[\|" \-g\fR\ |\ \fB\-\-strip\-debug\fR "\|]"
+.RB "[\|" \-\-strip\-unneeded\fR "\|]"
+.RB "[\|" \-K\ \fIsymbolname\fR\ |\ \fB\-\-keep\-symbol=\fIsymbolname\fR "\|]"
+.RB "[\|" \-N\ \fIsymbolname\fR\ |\ \fB\-\-strip\-symbol=\fIsymbolname\fR "\|]"
+.RB "[\|" \-L\ \fIsymbolname\fR\ |\ \fB\-\-localize\-symbol=\fIsymbolname\fR "\|]"
+.RB "[\|" \-W\ \fIsymbolname\fR\ |\ \fB\-\-weaken\-symbol=\fIsymbolname\fR "\|]"
+.RB "[\|" \-x\fR\ |\ \fB\-\-discard\-all\fR "\|]"
+.RB "[\|" \-X\fR\ |\ \fB\-\-discard\-locals\fR "\|]"
+.RB "[\|" \-b\ \fIbyte\fR\ |\ \fB\-\-byte=\fIbyte\fR "\|]"
+.RB "[\|" \-i\ \fIinterleave\fR\ |\ \fB\-\-interleave=\fIinterleave\fR "\|]"
+.RB "[\|" \-p\fR\ |\ \fB\-\-preserve\-dates\fR "\|]"
+.RB "[\|" \-\-debugging "\|]"
+.RB "[\|" \-\-gap\-fill=\fIval\fR "\|]"
+.RB "[\|" \-\-pad\-to=\fIaddress\fR "\|]"
+.RB "[\|" \-\-set\-start=\fIval\fR "\|]"
+.RB "[\|" \-\-change\-start=\fIincr\fR "\|]"
+.RB "[\|" \-\-change\-addresses=\fIincr\fR "\|]"
+.RB "[\|" \-\-change\-section\-address=\fIsection{=,+,-}val\fR "\|]"
+.RB "[\|" \-\-change\-section\-lma=\fIsection{=,+,-}val\fR "\|]"
+.RB "[\|" \-\-change\-section\-vma=\fIsection{=,+,-}val\fR "\|]"
+.RB "[\|" \-\-change\-warnings\fR "\|]"
+.RB "[\|" \-\-no\-change\-warnings\fR "\|]"
+.RB "[\|" \-\-set\-section\-flags=\fIsection=flags\fR "\|]"
+.RB "[\|" \-\-add\-section=\fIsectionname=filename\fR "\|]"
+.RB "[\|" \-\-change\-leading\-char\fR "\|]"
+.RB "[\|" \-\-remove\-leading\-char\fR "\|]"
+.RB "[\|" \-\-weaken\fR "\|]"
+.RB "[\|" \-v\ |\ \-\-verbose\fR "\|]"
+.RB "[\|" \-V\ |\ \-\-version\fR "\|]"
+.RB "[\|" \-\-help\fR "\|]"
+.B infile
+.RB "[\|" outfile\fR "\|]"
+.SH DESCRIPTION
+The GNU
+.B objcopy
+utility copies the contents of an object file to another.
+.B objcopy
+uses the GNU BFD Library to read and write the object files. It can
+write the destination object file in a format different from that of
+the source object file. The exact behavior of
+.B objcopy
+is controlled by command-line options.
+.PP
+.B objcopy
+creates temporary files to do its translations and deletes them
+afterward.
+.B objcopy
+uses BFD to do all its translation work; it knows about all the
+formats BFD knows about, and thus is able to recognize most formats
+without being told explicitly.
+.PP
+.B objcopy
+can be used to generate S-records by using an output target of
+.B srec
+(e.g., use
+.B -O srec).
+.PP
+.B objcopy
+can be used to generate a raw binary file by using an output target of
+.B binary
+(e.g., use
+.B -O binary).
+When
+.B objcopy
+generates a raw binary file, it will essentially produce a memory dump
+of the contents of the input object file. All symbols and relocation
+information will be discarded. The memory dump will start at the
+virtual address of the lowest section copied into the output file.
+.PP
+When generating an S-record or a raw binary file, it may be helpful to
+use
+.B -S
+to remove sections containing debugging information. In some cases
+.B -R
+will be useful to remove sections which contain information which is
+not needed by the binary file.
+.PP
+.I infile
+and
+.I outfile
+are the source and output files respectively. If you do not specify
+.IR outfile ,
+.B objcopy
+creates a temporary file and destructively renames the result with the
+name of the input file.
+
+.SH OPTIONS
+.TP
+.B \-I \fIbfdname\fR, \fB\-\-input\-target=\fIbfdname
+Consider the source file's object format to be
+.IR bfdname ,
+rather than attempting to deduce it.
+.TP
+.B \-O \fIbfdname\fR, \fB\-\-output\-target=\fIbfdname
+Write the output file using the object format
+.IR bfdname .
+.TP
+.B \-F \fIbfdname\fR, \fB\-\-target=\fIbfdname
+Use
+.I bfdname
+as the object format for both the input and the output file; i.e.
+simply transfer data from source to destination with no translation.
+.TP
+.B \-R \fIsectionname\fR, \fB\-\-remove-section=\fIsectionname
+Remove the named section from the file. This option may be given more
+than once. Note that using this option inappropriately may make the
+output file unusable.
+.TP
+.B \-S\fR, \fB\-\-strip\-all
+Do not copy relocation and symbol information from the source file.
+.TP
+.B \-g\fR, \fB\-\-strip\-debug
+Do not copy debugging symbols from the source file.
+.TP
+.B \-\-strip\-unneeded
+Strip all symbols that are not needed for relocation processing.
+.TP
+.B \-K \fIsymbolname\fR, \fB\-\-keep\-symbol=\fIsymbolname
+Copy only symbol \fIsymbolname\fP from the source file. This option
+may be given more than once.
+.TP
+.B \-N \fIsymbolname\fR, \fB\-\-strip\-symbol=\fIsymbolname
+Do not copy symbol \fIsymbolname\fP from the source file. This option
+may be given more than once.
+.TP
+.B \-L \fIsymbolname\fR, \fB\-\-localize\-symbol=\fIsymbolname
+Make symbol \fIsymbolname\fP local to the file, so that it is not
+visible externally. This option may be given more than once.
+.TP
+.B \-W \fIsymbolname\fR, \fB\-\-weaken\-symbol=\fIsymbolname
+Make symbol \fIsymbolname\fP weak. This option may be given more than once.
+.TP
+.B \-x\fR, \fB \-\-discard\-all
+Do not copy non-global symbols from the source file.
+.TP
+.B \-X\fR, \fB\-\-discard\-locals
+Do not copy compiler-generated local symbols. (These usually start
+with "L" or ".").
+.TP
+.B \-b \fIbyte\fR, \fB\-\-byte=\fIbyte
+Keep only every \fIbyte\fPth byte of the input file (header data is
+not affected). \fIbyte\fP can be in the range from 0 to the
+interleave-1. This option is useful for creating files to program
+ROMs. It is typically used with an srec output target.
+.TP
+.B \-i \fIinterleave\fR, \fB\-\-interleave=\fIinterleave
+Only copy one out of every \fIinterleave\fP bytes. Which one to copy is
+selected by the \fB\-b\fP or \fB\-\-byte\fP option. The default is 4.
+The interleave is ignored if neither \fB\-b\fP nor \fB\-\-byte\fP is given.
+.TP
+.B \-p\fR, \fB\-\-preserve\-dates
+Set the access and modification dates of the output file to be the same
+as those of the input file.
+.TP
+.B \-\-debugging
+Convert debugging information, if possible. This is not the default
+because only certain debugging formats are supported, and the
+conversion process can be time consuming.
+.TP
+.B \-\-gap\-fill=\fIval
+Fill gaps between sections with \fIval\fP. This operation applies to
+the \fIload address\fP (LMA) of the sections. It is done by increasing
+the size of the section with the lower address, and filling in the extra
+space created with \fIval\fP.
+.TP
+.B \-\-pad\-to=\fIaddress
+Pad the output file up to the load address \fIaddress\fP. This is
+done by increasing the size of the last section. The extra space is
+filled in with the value specified by \fB\-\-gap\-fill\fP (default
+zero).
+.TP
+.B \fB\-\-set\-start=\fIval
+Set the start address of the new file to \fIval\fP. Not all object
+file formats support setting the start address.
+.TP
+.B \fB\-\-change\-start=\fIincr\fR, \fB\-\-adjust\-start=\fIincr
+Changes the start address by adding \fIincr\fP. Not all object file
+formats support setting the start address.
+.TP
+.B \fB\-\-change\-addresses=\fIincr\fR, \fB\-\-adjust\-vma=\fIincr
+Changes the address of all sections, as well as the start address, by
+adding \fIincr\fP. Some object file formats do not permit section
+addresses to be changed arbitrarily. Note that this does not relocate
+the sections; if the program expects sections to be loaded at a
+certain address, and this option is used to change the sections such
+that they are loaded at a different address, the program may fail.
+.TP
+.B \fB\-\-change\-section\-address=\fIsection{=,+,-}val\fR, \fB\-\-adjust\-section\-vma=\fIsection{=,+,-}val
+Set or changes the VMA and LMA addresses of the named \fIsection\fP.
+If \fI=\fP is used, the section address is set to \fIval\fP.
+Otherwise, \fIval\fP is added to or subtracted from the section
+address. See the comments under \fB\-\-change\-addresses\fP, above. If
+\fIsection\fP does not exist in the input file, a warning will be
+issued, unless \fB\-\-no\-change\-warnings\fP is used.
+.TP
+.B \fB\-\-change\-section\-lma=\fIsection{=,+,-}val
+Set or change the LMA address of the named \fIsection\fP. If \fI=\fP is
+used, the section address is set to \fIval\fP. Otherwise, \fIval\fP
+is added to or subtracted from the section address. See the comments
+under \fB\-\-change\-addresses\fP, above. If \fIsection\fP does not exist
+in the input file, a warning will be issued, unless
+\fB\-\-no\-change\-warnings\fP is used.
+.TP
+.B \fB\-\-change\-section\-vma=\fIsection{=,+,-}val
+Set or change the VMA address of the named \fIsection\fP. If \fI=\fP is
+used, the section address is set to \fIval\fP. Otherwise, \fIval\fP
+is added to or subtracted from the section address. See the comments
+under \fB\-\-change\-addresses\fP, above. If \fIsection\fP does not exist
+in the input file, a warning will be issued, unless
+\fB\-\-no\-change\-warnings\fP is used.
+.TP
+.B \fB\-\-change\-warnings\fR, \fB\-\-adjust\-warnings
+If \fB\-\-change\-section\-XXX\fP is used, and the named section does
+not exist, issue a warning. This is the default.
+.TP
+.B \fB\-\-no\-change\-warnings\fR, \fB\-\-no\-adjust\-warnings
+Do not issue a warning if \fB\-\-change\-section\-XXX\fP is used, even
+if the named section does not exist.
+.TP
+.B \fB\-\-set\-section\-flags=\fIsection=flags
+Set the flags for the named section. The \fIflags\fP argument is a
+comma separated string of flag names. The recognized names are
+\fIalloc\fP, \fIload\fP, \fIreadonly\fP, \fIcode\fP, \fIdata\fP, and
+\fIrom\fP. Not all flags are meaningful for all object file
+formats.
+.TP
+.B \fB\-\-add\-section=\fIsectionname=filename
+Add a new section named \fIsectionname\fR while copying the file. The
+contents of the new section are taken from the file \fIfilename\fR.
+The size of the section will be the size of the file. This option
+only works on file formats which can support sections with arbitrary
+names.
+.TP
+.B \-\-change\-leading\-char
+Some object file formats use special characters at the start of
+symbols. The most common such character is underscore, which compilers
+often add before every symbol. This option tells
+.B objcopy
+to change the leading character of every symbol when it converts
+between object file formats. If the object file formats use the same
+leading character, this option has no effect. Otherwise, it will add
+a character, or remove a character, or change a character, as
+appropriate.
+.TP
+.B \-\-remove\-leading\-char
+If the first character of a global symbol is a special symbol leading
+character used by the object file format, remove the character. The
+most common symbol leading character is underscore. This option will
+remove a leading underscore from all global symbols. This can be
+useful if you want to link together objects of different file formats
+with different conventions for symbol names. This is different from
+\fB\-\-change\-leading\-char\fP because it always changes the symbol name
+when appropriate, regardless of the object file format of the output
+.TP
+.B \-\-weaken
+Change all global symbols in the file to be weak.
+.TP
+.B \-v\fR, \fB\-\-verbose
+Verbose output: list all object files modified. In the case of
+archives, "\fBobjcopy \-V\fR" lists all members of the archive.
+.TP
+.B \-V\fR, \fB\-\-version
+Show the version number of
+.B objcopy
+and exit.
+.TP
+.B \-\-help
+Show a summary of the options to
+.B objcopy
+and exit.
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (June 1993).
+
+.SH COPYING
+Copyright (c) 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
new file mode 100644
index 00000000000..5fd77775d70
--- /dev/null
+++ b/binutils/objcopy.c
@@ -0,0 +1,2029 @@
+/* objcopy.c -- copy object file from input to output, optionally massaging it.
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "progress.h"
+#include "bucomm.h"
+#include "getopt.h"
+#include "libiberty.h"
+#include "budbg.h"
+#include <sys/stat.h>
+
+/* A list of symbols to explicitly strip out, or to keep. A linked
+ list is good enough for a small number from the command line, but
+ this will slow things down a lot if many symbols are being
+ deleted. */
+
+struct symlist
+{
+ const char *name;
+ struct symlist *next;
+};
+
+static void copy_usage PARAMS ((FILE *, int));
+static void strip_usage PARAMS ((FILE *, int));
+static flagword parse_flags PARAMS ((const char *));
+static struct section_list *find_section_list PARAMS ((const char *, boolean));
+static void setup_section PARAMS ((bfd *, asection *, PTR));
+static void copy_section PARAMS ((bfd *, asection *, PTR));
+static void get_sections PARAMS ((bfd *, asection *, PTR));
+static int compare_section_lma PARAMS ((const PTR, const PTR));
+static void add_specific_symbol PARAMS ((const char *, struct symlist **));
+static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
+static boolean is_strip_section PARAMS ((bfd *, asection *));
+static unsigned int filter_symbols
+ PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
+static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
+static void filter_bytes PARAMS ((char *, bfd_size_type *));
+static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
+static void copy_object PARAMS ((bfd *, bfd *));
+static void copy_archive PARAMS ((bfd *, bfd *, const char *));
+static void copy_file
+ PARAMS ((const char *, const char *, const char *, const char *));
+static int strip_main PARAMS ((int, char **));
+static int copy_main PARAMS ((int, char **));
+
+#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
+
+static asymbol **isympp = NULL; /* Input symbols */
+static asymbol **osympp = NULL; /* Output symbols that survive stripping */
+
+/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
+static int copy_byte = -1;
+static int interleave = 4;
+
+static boolean verbose; /* Print file and target names. */
+static boolean preserve_dates; /* Preserve input file timestamp. */
+static int status = 0; /* Exit status. */
+
+enum strip_action
+ {
+ STRIP_UNDEF,
+ STRIP_NONE, /* don't strip */
+ STRIP_DEBUG, /* strip all debugger symbols */
+ STRIP_UNNEEDED, /* strip unnecessary symbols */
+ STRIP_ALL /* strip all symbols */
+ };
+
+/* Which symbols to remove. */
+static enum strip_action strip_symbols;
+
+enum locals_action
+ {
+ LOCALS_UNDEF,
+ LOCALS_START_L, /* discard locals starting with L */
+ LOCALS_ALL /* discard all locals */
+ };
+
+/* Which local symbols to remove. Overrides STRIP_ALL. */
+static enum locals_action discard_locals;
+
+/* What kind of change to perform. */
+enum change_action
+{
+ CHANGE_IGNORE,
+ CHANGE_MODIFY,
+ CHANGE_SET
+};
+
+/* Structure used to hold lists of sections and actions to take. */
+struct section_list
+{
+ struct section_list * next; /* Next section to change. */
+ const char * name; /* Section name. */
+ boolean used; /* Whether this entry was used. */
+ boolean remove; /* Whether to remove this section. */
+ enum change_action change_vma;/* Whether to change or set VMA. */
+ bfd_vma vma_val; /* Amount to change by or set to. */
+ enum change_action change_lma;/* Whether to change or set LMA. */
+ bfd_vma lma_val; /* Amount to change by or set to. */
+ boolean set_flags; /* Whether to set the section flags. */
+ flagword flags; /* What to set the section flags to. */
+};
+
+static struct section_list *change_sections;
+static boolean sections_removed;
+
+/* Changes to the start address. */
+static bfd_vma change_start = 0;
+static boolean set_start_set = false;
+static bfd_vma set_start;
+
+/* Changes to section addresses. */
+static bfd_vma change_section_address = 0;
+
+/* Filling gaps between sections. */
+static boolean gap_fill_set = false;
+static bfd_byte gap_fill = 0;
+
+/* Pad to a given address. */
+static boolean pad_to_set = false;
+static bfd_vma pad_to;
+
+/* List of sections to add. */
+
+struct section_add
+{
+ /* Next section to add. */
+ struct section_add *next;
+ /* Name of section to add. */
+ const char *name;
+ /* Name of file holding section contents. */
+ const char *filename;
+ /* Size of file. */
+ size_t size;
+ /* Contents of file. */
+ bfd_byte *contents;
+ /* BFD section, after it has been added. */
+ asection *section;
+};
+
+static struct section_add *add_sections;
+
+/* Whether to convert debugging information. */
+
+static boolean convert_debugging = false;
+
+/* Whether to change the leading character in symbol names. */
+
+static boolean change_leading_char = false;
+
+/* Whether to remove the leading character from global symbol names. */
+
+static boolean remove_leading_char = false;
+
+/* List of symbols to strip, keep, localize, and weaken. */
+
+static struct symlist *strip_specific_list = NULL;
+static struct symlist *keep_specific_list = NULL;
+static struct symlist *localize_specific_list = NULL;
+static struct symlist *weaken_specific_list = NULL;
+
+/* If this is true, we weaken global symbols (set BSF_WEAK). */
+
+static boolean weaken = false;
+
+/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
+
+#define OPTION_ADD_SECTION 150
+#define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
+#define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
+#define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
+#define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
+#define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
+#define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
+#define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
+#define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
+#define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
+#define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
+#define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
+#define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
+#define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
+#define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
+#define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
+#define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
+
+/* Options to handle if running as "strip". */
+
+static struct option strip_options[] =
+{
+ {"discard-all", no_argument, 0, 'x'},
+ {"discard-locals", no_argument, 0, 'X'},
+ {"format", required_argument, 0, 'F'}, /* Obsolete */
+ {"help", no_argument, 0, 'h'},
+ {"input-format", required_argument, 0, 'I'}, /* Obsolete */
+ {"input-target", required_argument, 0, 'I'},
+ {"keep-symbol", required_argument, 0, 'K'},
+ {"output-format", required_argument, 0, 'O'}, /* Obsolete */
+ {"output-target", required_argument, 0, 'O'},
+ {"preserve-dates", no_argument, 0, 'p'},
+ {"remove-section", required_argument, 0, 'R'},
+ {"strip-all", no_argument, 0, 's'},
+ {"strip-debug", no_argument, 0, 'S'},
+ {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
+ {"strip-symbol", required_argument, 0, 'N'},
+ {"target", required_argument, 0, 'F'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {0, no_argument, 0, 0}
+};
+
+/* Options to handle if running as "objcopy". */
+
+static struct option copy_options[] =
+{
+ {"add-section", required_argument, 0, OPTION_ADD_SECTION},
+ {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
+ {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
+ {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
+ {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
+ {"byte", required_argument, 0, 'b'},
+ {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
+ {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
+ {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
+ {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
+ {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
+ {"change-start", required_argument, 0, OPTION_CHANGE_START},
+ {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
+ {"debugging", no_argument, 0, OPTION_DEBUGGING},
+ {"discard-all", no_argument, 0, 'x'},
+ {"discard-locals", no_argument, 0, 'X'},
+ {"format", required_argument, 0, 'F'}, /* Obsolete */
+ {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
+ {"help", no_argument, 0, 'h'},
+ {"input-format", required_argument, 0, 'I'}, /* Obsolete */
+ {"input-target", required_argument, 0, 'I'},
+ {"interleave", required_argument, 0, 'i'},
+ {"keep-symbol", required_argument, 0, 'K'},
+ {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
+ {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
+ {"output-format", required_argument, 0, 'O'}, /* Obsolete */
+ {"output-target", required_argument, 0, 'O'},
+ {"pad-to", required_argument, 0, OPTION_PAD_TO},
+ {"preserve-dates", no_argument, 0, 'p'},
+ {"localize-symbol", required_argument, 0, 'L'},
+ {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
+ {"remove-section", required_argument, 0, 'R'},
+ {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
+ {"set-start", required_argument, 0, OPTION_SET_START},
+ {"strip-all", no_argument, 0, 'S'},
+ {"strip-debug", no_argument, 0, 'g'},
+ {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
+ {"strip-symbol", required_argument, 0, 'N'},
+ {"target", required_argument, 0, 'F'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {"weaken", no_argument, 0, OPTION_WEAKEN},
+ {"weaken-symbol", required_argument, 0, 'W'},
+ {0, no_argument, 0, 0}
+};
+
+/* IMPORTS */
+extern char *program_name;
+
+/* This flag distinguishes between strip and objcopy:
+ 1 means this is 'strip'; 0 means this is 'objcopy'.
+ -1 means if we should use argv[0] to decide. */
+extern int is_strip;
+
+
+static void
+copy_usage (stream, exit_status)
+ FILE *stream;
+ int exit_status;
+{
+ fprintf (stream, _("\
+Usage: %s [-vVSpgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
+ [-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
+ [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
+ [--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n\
+ [--discard-locals] [--debugging] [--remove-section=section]\n"),
+ program_name);
+ fprintf (stream, _("\
+ [--gap-fill=val] [--pad-to=address] [--preserve-dates]\n\
+ [--set-start=val] \n\
+ [--change-start=incr] [--change-addresses=incr] \n\
+ (--adjust-start and --adjust-vma are aliases for these two) \n\
+ [--change-section-address=section{=,+,-}val]\n\
+ (--adjust-section-vma is an alias for --change-section-address)\n\
+ [--change-section-lma=section{=,+,-}val]\n\
+ [--change-section-vma=section{=,+,-}val]\n\
+ [--adjust-warnings] [--no-adjust-warnings]\n\
+ [--change-warnings] [--no-change-warnings]\n\
+ [--set-section-flags=section=flags] [--add-section=sectionname=filename]\n\
+ [--keep-symbol symbol] [-K symbol] [--strip-symbol symbol] [-N symbol]\n\
+ [--localize-symbol symbol] [-L symbol] [--weaken-symbol symbol]\n\
+ [-W symbol] [--change-leading-char] [--remove-leading-char] [--weaken]\n\
+ [--verbose] [--version] [--help] in-file [out-file]\n"));
+ list_supported_targets (program_name, stream);
+ if (exit_status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (exit_status);
+}
+
+static void
+strip_usage (stream, exit_status)
+ FILE *stream;
+ int exit_status;
+{
+ fprintf (stream, _("\
+Usage: %s [-vVsSpgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-R section]\n\
+ [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
+ [--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n\
+ [--discard-locals] [--keep-symbol symbol] [-K symbol]\n\
+ [--strip-symbol symbol] [-N symbol] [--remove-section=section]\n\
+ [-o file] [--preserve-dates] [--verbose] [--version] [--help] file...\n"),
+ program_name);
+ list_supported_targets (program_name, stream);
+ if (exit_status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (exit_status);
+}
+
+/* Parse section flags into a flagword, with a fatal error if the
+ string can't be parsed. */
+
+static flagword
+parse_flags (s)
+ const char *s;
+{
+ flagword ret;
+ const char *snext;
+ int len;
+
+ ret = SEC_NO_FLAGS;
+
+ do
+ {
+ snext = strchr (s, ',');
+ if (snext == NULL)
+ len = strlen (s);
+ else
+ {
+ len = snext - s;
+ ++snext;
+ }
+
+ if (0) ;
+#define PARSE_FLAG(fname,fval) \
+ else if (strncasecmp (fname, s, len) == 0) ret |= fval
+ PARSE_FLAG ("alloc", SEC_ALLOC);
+ PARSE_FLAG ("load", SEC_LOAD);
+ PARSE_FLAG ("readonly", SEC_READONLY);
+ PARSE_FLAG ("code", SEC_CODE);
+ PARSE_FLAG ("data", SEC_DATA);
+ PARSE_FLAG ("rom", SEC_ROM);
+ PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
+#undef PARSE_FLAG
+ else
+ {
+ char *copy;
+
+ copy = xmalloc (len + 1);
+ strncpy (copy, s, len);
+ copy[len] = '\0';
+ non_fatal (_("unrecognized section flag `%s'"), copy);
+ fatal (_("supported flags: alloc, load, readonly, code, data, rom, contents"));
+ }
+
+ s = snext;
+ }
+ while (s != NULL);
+
+ return ret;
+}
+
+/* Find and optionally add an entry in the change_sections list. */
+
+static struct section_list *
+find_section_list (name, add)
+ const char *name;
+ boolean add;
+{
+ register struct section_list *p;
+
+ for (p = change_sections; p != NULL; p = p->next)
+ if (strcmp (p->name, name) == 0)
+ return p;
+
+ if (! add)
+ return NULL;
+
+ p = (struct section_list *) xmalloc (sizeof (struct section_list));
+ p->name = name;
+ p->used = false;
+ p->remove = false;
+ p->change_vma = CHANGE_IGNORE;
+ p->change_lma = CHANGE_IGNORE;
+ p->vma_val = 0;
+ p->lma_val = 0;
+ p->set_flags = false;
+ p->flags = 0;
+
+ p->next = change_sections;
+ change_sections = p;
+
+ return p;
+}
+
+/* Add a symbol to strip_specific_list. */
+
+static void
+add_specific_symbol (name, list)
+ const char *name;
+ struct symlist **list;
+{
+ struct symlist *tmp_list;
+
+ tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
+ tmp_list->name = name;
+ tmp_list->next = *list;
+ *list = tmp_list;
+}
+
+/* See whether a symbol should be stripped or kept based on
+ strip_specific_list and keep_symbols. */
+
+static boolean
+is_specified_symbol (name, list)
+ const char *name;
+ struct symlist *list;
+{
+ struct symlist *tmp_list;
+
+ for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
+ {
+ if (strcmp (name, tmp_list->name) == 0)
+ return true;
+ }
+ return false;
+}
+
+/* See if a section is being removed. */
+
+static boolean
+is_strip_section (abfd, sec)
+ bfd *abfd;
+ asection *sec;
+{
+ struct section_list *p;
+
+ if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
+ && (strip_symbols == STRIP_DEBUG
+ || strip_symbols == STRIP_UNNEEDED
+ || strip_symbols == STRIP_ALL
+ || discard_locals == LOCALS_ALL
+ || convert_debugging))
+ return true;
+
+ if (! sections_removed)
+ return false;
+ p = find_section_list (bfd_get_section_name (abfd, sec), false);
+ return p != NULL && p->remove ? true : false;
+}
+
+/* Choose which symbol entries to copy; put the result in OSYMS.
+ We don't copy in place, because that confuses the relocs.
+ Return the number of symbols to print. */
+
+static unsigned int
+filter_symbols (abfd, obfd, osyms, isyms, symcount)
+ bfd *abfd;
+ bfd *obfd;
+ asymbol **osyms, **isyms;
+ long symcount;
+{
+ register asymbol **from = isyms, **to = osyms;
+ long src_count = 0, dst_count = 0;
+
+ for (; src_count < symcount; src_count++)
+ {
+ asymbol *sym = from[src_count];
+ flagword flags = sym->flags;
+ const char *name = bfd_asymbol_name (sym);
+ int keep;
+
+ if (change_leading_char
+ && (bfd_get_symbol_leading_char (abfd)
+ != bfd_get_symbol_leading_char (obfd))
+ && (bfd_get_symbol_leading_char (abfd) == '\0'
+ || (name[0] == bfd_get_symbol_leading_char (abfd))))
+ {
+ if (bfd_get_symbol_leading_char (obfd) == '\0')
+ name = bfd_asymbol_name (sym) = name + 1;
+ else
+ {
+ char *n;
+
+ n = xmalloc (strlen (name) + 2);
+ n[0] = bfd_get_symbol_leading_char (obfd);
+ if (bfd_get_symbol_leading_char (abfd) == '\0')
+ strcpy (n + 1, name);
+ else
+ strcpy (n + 1, name + 1);
+ name = bfd_asymbol_name (sym) = n;
+ }
+ }
+
+ if (remove_leading_char
+ && ((flags & BSF_GLOBAL) != 0
+ || (flags & BSF_WEAK) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)))
+ && name[0] == bfd_get_symbol_leading_char (abfd))
+ name = bfd_asymbol_name (sym) = name + 1;
+
+ if (strip_symbols == STRIP_ALL)
+ keep = 0;
+ else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
+ || ((flags & BSF_SECTION_SYM) != 0
+ && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
+ & BSF_KEEP) != 0))
+ keep = 1;
+ else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
+ || (flags & BSF_WEAK) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)))
+ keep = strip_symbols != STRIP_UNNEEDED;
+ else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
+ keep = (strip_symbols != STRIP_DEBUG
+ && strip_symbols != STRIP_UNNEEDED
+ && ! convert_debugging);
+ else /* Local symbol. */
+ keep = (strip_symbols != STRIP_UNNEEDED
+ && (discard_locals != LOCALS_ALL
+ && (discard_locals != LOCALS_START_L
+ || ! bfd_is_local_label (abfd, sym))));
+
+ if (keep && is_specified_symbol (name, strip_specific_list))
+ keep = 0;
+ if (!keep && is_specified_symbol (name, keep_specific_list))
+ keep = 1;
+ if (keep && is_strip_section (abfd, bfd_get_section (sym)))
+ keep = 0;
+
+ if (keep && (flags & BSF_GLOBAL) != 0
+ && (weaken || is_specified_symbol (name, weaken_specific_list)))
+ {
+ sym->flags &=~ BSF_GLOBAL;
+ sym->flags |= BSF_WEAK;
+ }
+ if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
+ && is_specified_symbol (name, localize_specific_list))
+ {
+ sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
+ sym->flags |= BSF_LOCAL;
+ }
+
+ if (keep)
+ to[dst_count++] = sym;
+ }
+
+ to[dst_count] = NULL;
+
+ return dst_count;
+}
+
+/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
+ Adjust *SIZE. */
+
+static void
+filter_bytes (memhunk, size)
+ char *memhunk;
+ bfd_size_type *size;
+{
+ char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
+
+ for (; from < end; from += interleave)
+ *to++ = *from;
+ if (*size % interleave > copy_byte)
+ *size = (*size / interleave) + 1;
+ else
+ *size /= interleave;
+}
+
+/* Copy object file IBFD onto OBFD. */
+
+static void
+copy_object (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ bfd_vma start;
+ long symcount;
+ asection **osections = NULL;
+ bfd_size_type *gaps = NULL;
+ bfd_size_type max_gap = 0;
+ long symsize;
+ PTR dhandle;
+
+
+ if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ if (verbose)
+ printf (_("copy from %s(%s) to %s(%s)\n"),
+ bfd_get_filename (ibfd), bfd_get_target (ibfd),
+ bfd_get_filename (obfd), bfd_get_target (obfd));
+
+ if (set_start_set)
+ start = set_start;
+ else
+ start = bfd_get_start_address (ibfd);
+ start += change_start;
+
+ if (!bfd_set_start_address (obfd, start)
+ || !bfd_set_file_flags (obfd,
+ (bfd_get_file_flags (ibfd)
+ & bfd_applicable_file_flags (obfd))))
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ /* Copy architecture of input file to output file */
+ if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
+ bfd_get_mach (ibfd)))
+ non_fatal (_("Warning: Output file cannot represent architecture %s"),
+ bfd_printable_arch_mach (bfd_get_arch (ibfd),
+ bfd_get_mach (ibfd)));
+
+ if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ if (isympp)
+ free (isympp);
+
+ if (osympp != isympp)
+ free (osympp);
+
+ /* BFD mandates that all output sections be created and sizes set before
+ any output is done. Thus, we traverse all sections multiple times. */
+ bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
+
+ if (add_sections != NULL)
+ {
+ struct section_add *padd;
+ struct section_list *pset;
+
+ for (padd = add_sections; padd != NULL; padd = padd->next)
+ {
+ padd->section = bfd_make_section (obfd, padd->name);
+ if (padd->section == NULL)
+ {
+ non_fatal (_("can't create section `%s': %s"),
+ padd->name, bfd_errmsg (bfd_get_error ()));
+ status = 1;
+ return;
+ }
+ else
+ {
+ flagword flags;
+
+ if (! bfd_set_section_size (obfd, padd->section, padd->size))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ pset = find_section_list (padd->name, false);
+ if (pset != NULL)
+ pset->used = true;
+
+ if (pset != NULL && pset->set_flags)
+ flags = pset->flags | SEC_HAS_CONTENTS;
+ else
+ flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
+
+ if (! bfd_set_section_flags (obfd, padd->section, flags))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ if (pset != NULL)
+ {
+ if (pset->change_vma != CHANGE_IGNORE)
+ if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ if (pset->change_lma != CHANGE_IGNORE)
+ {
+ padd->section->lma = pset->lma_val;
+
+ if (! bfd_set_section_alignment
+ (obfd, padd->section,
+ bfd_section_alignment (obfd, padd->section)))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+ }
+ }
+ }
+ }
+ }
+
+ if (gap_fill_set || pad_to_set)
+ {
+ asection **set;
+ unsigned int c, i;
+
+ /* We must fill in gaps between the sections and/or we must pad
+ the last section to a specified address. We do this by
+ grabbing a list of the sections, sorting them by VMA, and
+ increasing the section sizes as required to fill the gaps.
+ We write out the gap contents below. */
+
+ c = bfd_count_sections (obfd);
+ osections = (asection **) xmalloc (c * sizeof (asection *));
+ set = osections;
+ bfd_map_over_sections (obfd, get_sections, (void *) &set);
+
+ qsort (osections, c, sizeof (asection *), compare_section_lma);
+
+ gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
+ memset (gaps, 0, c * sizeof (bfd_size_type));
+
+ if (gap_fill_set)
+ {
+ for (i = 0; i < c - 1; i++)
+ {
+ flagword flags;
+ bfd_size_type size;
+ bfd_vma gap_start, gap_stop;
+
+ flags = bfd_get_section_flags (obfd, osections[i]);
+ if ((flags & SEC_HAS_CONTENTS) == 0
+ || (flags & SEC_LOAD) == 0)
+ continue;
+
+ size = bfd_section_size (obfd, osections[i]);
+ gap_start = bfd_section_lma (obfd, osections[i]) + size;
+ gap_stop = bfd_section_lma (obfd, osections[i + 1]);
+ if (gap_start < gap_stop)
+ {
+ if (! bfd_set_section_size (obfd, osections[i],
+ size + (gap_stop - gap_start)))
+ {
+ non_fatal (_("Can't fill gap after %s: %s"),
+ bfd_get_section_name (obfd, osections[i]),
+ bfd_errmsg (bfd_get_error ()));
+ status = 1;
+ break;
+ }
+ gaps[i] = gap_stop - gap_start;
+ if (max_gap < gap_stop - gap_start)
+ max_gap = gap_stop - gap_start;
+ }
+ }
+ }
+
+ if (pad_to_set)
+ {
+ bfd_vma lma;
+ bfd_size_type size;
+
+ lma = bfd_section_lma (obfd, osections[c - 1]);
+ size = bfd_section_size (obfd, osections[c - 1]);
+ if (lma + size < pad_to)
+ {
+ if (! bfd_set_section_size (obfd, osections[c - 1],
+ pad_to - lma))
+ {
+ non_fatal (_("Can't add padding to %s: %s"),
+ bfd_get_section_name (obfd, osections[c - 1]),
+ bfd_errmsg (bfd_get_error ()));
+ status = 1;
+ }
+ else
+ {
+ gaps[c - 1] = pad_to - (lma + size);
+ if (max_gap < pad_to - (lma + size))
+ max_gap = pad_to - (lma + size);
+ }
+ }
+ }
+ }
+
+ /* Symbol filtering must happen after the output sections have
+ been created, but before their contents are set. */
+ dhandle = NULL;
+ symsize = bfd_get_symtab_upper_bound (ibfd);
+ if (symsize < 0)
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ osympp = isympp = (asymbol **) xmalloc (symsize);
+ symcount = bfd_canonicalize_symtab (ibfd, isympp);
+ if (symcount < 0)
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ if (convert_debugging)
+ dhandle = read_debugging_info (ibfd, isympp, symcount);
+
+ if (strip_symbols == STRIP_DEBUG
+ || strip_symbols == STRIP_ALL
+ || strip_symbols == STRIP_UNNEEDED
+ || discard_locals != LOCALS_UNDEF
+ || strip_specific_list != NULL
+ || keep_specific_list != NULL
+ || localize_specific_list != NULL
+ || weaken_specific_list != NULL
+ || sections_removed
+ || convert_debugging
+ || change_leading_char
+ || remove_leading_char
+ || weaken)
+ {
+ /* Mark symbols used in output relocations so that they
+ are kept, even if they are local labels or static symbols.
+
+ Note we iterate over the input sections examining their
+ relocations since the relocations for the output sections
+ haven't been set yet. mark_symbols_used_in_relocations will
+ ignore input sections which have no corresponding output
+ section. */
+ if (strip_symbols != STRIP_ALL)
+ bfd_map_over_sections (ibfd,
+ mark_symbols_used_in_relocations,
+ (PTR)isympp);
+ osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
+ symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
+ }
+
+ if (convert_debugging && dhandle != NULL)
+ {
+ if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
+ {
+ status = 1;
+ return;
+ }
+ }
+
+ bfd_set_symtab (obfd, osympp, symcount);
+
+ /* This has to happen after the symbol table has been set. */
+ bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
+
+ if (add_sections != NULL)
+ {
+ struct section_add *padd;
+
+ for (padd = add_sections; padd != NULL; padd = padd->next)
+ {
+ if (! bfd_set_section_contents (obfd, padd->section,
+ (PTR) padd->contents,
+ (file_ptr) 0,
+ (bfd_size_type) padd->size))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+ }
+ }
+
+ if (gap_fill_set || pad_to_set)
+ {
+ bfd_byte *buf;
+ int c, i;
+
+ /* Fill in the gaps. */
+
+ if (max_gap > 8192)
+ max_gap = 8192;
+ buf = (bfd_byte *) xmalloc (max_gap);
+ memset (buf, gap_fill, (size_t) max_gap);
+
+ c = bfd_count_sections (obfd);
+ for (i = 0; i < c; i++)
+ {
+ if (gaps[i] != 0)
+ {
+ bfd_size_type left;
+ file_ptr off;
+
+ left = gaps[i];
+ off = bfd_section_size (obfd, osections[i]) - left;
+ while (left > 0)
+ {
+ bfd_size_type now;
+
+ if (left > 8192)
+ now = 8192;
+ else
+ now = left;
+
+ if (! bfd_set_section_contents (obfd, osections[i], buf,
+ off, now))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ left -= now;
+ off += now;
+ }
+ }
+ }
+ }
+
+ /* Allow the BFD backend to copy any private data it understands
+ from the input BFD to the output BFD. This is done last to
+ permit the routine to look at the filtered symbol table, which is
+ important for the ECOFF code at least. */
+ if (!bfd_copy_private_bfd_data (ibfd, obfd))
+ {
+ non_fatal (_("%s: error copying private BFD data: %s"),
+ bfd_get_filename (obfd),
+ bfd_errmsg (bfd_get_error ()));
+ status = 1;
+ return;
+ }
+}
+
+/* Read each archive element in turn from IBFD, copy the
+ contents to temp file, and keep the temp file handle. */
+
+static void
+copy_archive (ibfd, obfd, output_target)
+ bfd *ibfd;
+ bfd *obfd;
+ const char *output_target;
+{
+ struct name_list
+ {
+ struct name_list *next;
+ char *name;
+ bfd *obfd;
+ } *list, *l;
+ bfd **ptr = &obfd->archive_head;
+ bfd *this_element;
+ char *dir = make_tempname (bfd_get_filename (obfd));
+
+ /* Make a temp directory to hold the contents. */
+#if defined (_WIN32) && !defined (__CYGWIN32__)
+ if (mkdir (dir) != 0)
+#else
+ if (mkdir (dir, 0700) != 0)
+#endif
+ {
+ fatal (_("cannot mkdir %s for archive copying (error: %s)"),
+ dir, strerror (errno));
+ }
+ obfd->has_armap = ibfd->has_armap;
+
+ list = NULL;
+
+ this_element = bfd_openr_next_archived_file (ibfd, NULL);
+ while (!status && this_element != (bfd *) NULL)
+ {
+ /* Create an output file for this member. */
+ char *output_name = concat (dir, "/", bfd_get_filename (this_element),
+ (char *) NULL);
+ bfd *output_bfd = bfd_openw (output_name, output_target);
+ bfd *last_element;
+
+ l = (struct name_list *) xmalloc (sizeof (struct name_list));
+ l->name = output_name;
+ l->next = list;
+ list = l;
+
+ if (output_bfd == (bfd *) NULL)
+ RETURN_NONFATAL (output_name);
+
+ if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ if (bfd_check_format (this_element, bfd_object) == true)
+ copy_object (this_element, output_bfd);
+
+ if (!bfd_close (output_bfd))
+ {
+ bfd_nonfatal (bfd_get_filename (output_bfd));
+ /* Error in new object file. Don't change archive. */
+ status = 1;
+ }
+
+ /* Open the newly output file and attach to our list. */
+ output_bfd = bfd_openr (output_name, output_target);
+
+ l->obfd = output_bfd;
+
+ *ptr = output_bfd;
+ ptr = &output_bfd->next;
+
+ last_element = this_element;
+
+ this_element = bfd_openr_next_archived_file (ibfd, last_element);
+
+ bfd_close (last_element);
+ }
+ *ptr = (bfd *) NULL;
+
+ if (!bfd_close (obfd))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ if (!bfd_close (ibfd))
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ /* Delete all the files that we opened. */
+ for (l = list; l != NULL; l = l->next)
+ {
+ bfd_close (l->obfd);
+ unlink (l->name);
+ }
+ rmdir (dir);
+}
+
+/* The top-level control. */
+
+static void
+copy_file (input_filename, output_filename, input_target, output_target)
+ const char *input_filename;
+ const char *output_filename;
+ const char *input_target;
+ const char *output_target;
+{
+ bfd *ibfd;
+ char **matching;
+
+ /* To allow us to do "strip *" without dying on the first
+ non-object file, failures are nonfatal. */
+
+ ibfd = bfd_openr (input_filename, input_target);
+ if (ibfd == NULL)
+ RETURN_NONFATAL (input_filename);
+
+ if (bfd_check_format (ibfd, bfd_archive))
+ {
+ bfd *obfd;
+
+ /* bfd_get_target does not return the correct value until
+ bfd_check_format succeeds. */
+ if (output_target == NULL)
+ output_target = bfd_get_target (ibfd);
+
+ obfd = bfd_openw (output_filename, output_target);
+ if (obfd == NULL)
+ RETURN_NONFATAL (output_filename);
+
+ copy_archive (ibfd, obfd, output_target);
+ }
+ else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
+ {
+ bfd *obfd;
+
+ /* bfd_get_target does not return the correct value until
+ bfd_check_format succeeds. */
+ if (output_target == NULL)
+ output_target = bfd_get_target (ibfd);
+
+ obfd = bfd_openw (output_filename, output_target);
+ if (obfd == NULL)
+ RETURN_NONFATAL (output_filename);
+
+ copy_object (ibfd, obfd);
+
+ if (!bfd_close (obfd))
+ RETURN_NONFATAL (output_filename);
+
+ if (!bfd_close (ibfd))
+ RETURN_NONFATAL (input_filename);
+ }
+ else
+ {
+ bfd_nonfatal (input_filename);
+
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+
+ status = 1;
+ }
+}
+
+/* Create a section in OBFD with the same name and attributes
+ as ISECTION in IBFD. */
+
+static void
+setup_section (ibfd, isection, obfdarg)
+ bfd *ibfd;
+ sec_ptr isection;
+ PTR obfdarg;
+{
+ bfd *obfd = (bfd *) obfdarg;
+ struct section_list *p;
+ sec_ptr osection;
+ bfd_size_type size;
+ bfd_vma vma;
+ bfd_vma lma;
+ flagword flags;
+ char *err;
+
+ if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
+ && (strip_symbols == STRIP_DEBUG
+ || strip_symbols == STRIP_UNNEEDED
+ || strip_symbols == STRIP_ALL
+ || discard_locals == LOCALS_ALL
+ || convert_debugging))
+ return;
+
+ p = find_section_list (bfd_section_name (ibfd, isection), false);
+ if (p != NULL)
+ p->used = true;
+
+ if (p != NULL && p->remove)
+ return;
+
+ osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
+
+ if (osection == NULL)
+ {
+ err = "making";
+ goto loser;
+ }
+
+ size = bfd_section_size (ibfd, isection);
+ if (copy_byte >= 0)
+ size = (size + interleave - 1) / interleave;
+ if (! bfd_set_section_size (obfd, osection, size))
+ {
+ err = "size";
+ goto loser;
+ }
+
+ vma = bfd_section_vma (ibfd, isection);
+ if (p != NULL && p->change_vma == CHANGE_MODIFY)
+ vma += p->vma_val;
+ else if (p != NULL && p->change_vma == CHANGE_SET)
+ vma = p->vma_val;
+ else
+ vma += change_section_address;
+
+ if (! bfd_set_section_vma (obfd, osection, vma))
+ {
+ err = "vma";
+ goto loser;
+ }
+
+ lma = isection->lma;
+ if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
+ {
+ if (p->change_lma == CHANGE_MODIFY)
+ lma += p->lma_val;
+ else if (p->change_lma == CHANGE_SET)
+ lma = p->lma_val;
+ else
+ abort ();
+ }
+ else
+ lma += change_section_address;
+
+ 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))
+ == false)
+ {
+ err = "alignment";
+ goto loser;
+ }
+
+ flags = bfd_get_section_flags (ibfd, isection);
+ if (p != NULL && p->set_flags)
+ flags = p->flags | (flags & SEC_HAS_CONTENTS);
+ if (!bfd_set_section_flags (obfd, osection, flags))
+ {
+ err = "flags";
+ goto loser;
+ }
+
+ /* 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))
+ {
+ err = "private data";
+ goto loser;
+ }
+
+ /* All went well */
+ return;
+
+loser:
+ non_fatal (_("%s: section `%s': error in %s: %s"),
+ bfd_get_filename (ibfd),
+ bfd_section_name (ibfd, isection),
+ err, bfd_errmsg (bfd_get_error ()));
+ status = 1;
+}
+
+/* Copy the data of input section ISECTION of IBFD
+ to an output section with the same name in OBFD.
+ If stripping then don't copy any relocation info. */
+
+static void
+copy_section (ibfd, isection, obfdarg)
+ bfd *ibfd;
+ sec_ptr isection;
+ PTR obfdarg;
+{
+ bfd *obfd = (bfd *) obfdarg;
+ struct section_list *p;
+ arelent **relpp;
+ long relcount;
+ sec_ptr osection;
+ bfd_size_type size;
+ long relsize;
+
+ /* If we have already failed earlier on, do not keep on generating
+ complaints now. */
+ if (status != 0)
+ return;
+
+ if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
+ && (strip_symbols == STRIP_DEBUG
+ || strip_symbols == STRIP_UNNEEDED
+ || strip_symbols == STRIP_ALL
+ || discard_locals == LOCALS_ALL
+ || convert_debugging))
+ {
+ return;
+ }
+
+ p = find_section_list (bfd_section_name (ibfd, isection), false);
+
+ if (p != NULL && p->remove)
+ return;
+
+ osection = isection->output_section;
+ size = bfd_get_section_size_before_reloc (isection);
+
+ if (size == 0 || osection == 0)
+ return;
+
+
+ relsize = bfd_get_reloc_upper_bound (ibfd, isection);
+ if (relsize < 0)
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ if (relsize == 0)
+ bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
+ else
+ {
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
+ if (relcount < 0)
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ if (strip_symbols == STRIP_ALL)
+ {
+ /* Remove relocations which are not in
+ keep_strip_specific_list. */
+ arelent **temp_relpp;
+ long temp_relcount = 0;
+ long i;
+
+ temp_relpp = (arelent **) xmalloc (relsize);
+ for (i = 0; i < relcount; i++)
+ if (is_specified_symbol
+ (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
+ keep_specific_list))
+ temp_relpp [temp_relcount++] = relpp [i];
+ relcount = temp_relcount;
+ free (relpp);
+ relpp = temp_relpp;
+ }
+ bfd_set_reloc (obfd, osection,
+ (relcount == 0 ? (arelent **) NULL : relpp), relcount);
+ }
+
+ isection->_cooked_size = isection->_raw_size;
+ isection->reloc_done = true;
+
+ if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
+ {
+ PTR memhunk = (PTR) xmalloc ((unsigned) size);
+
+ if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
+ size))
+ RETURN_NONFATAL (bfd_get_filename (ibfd));
+
+ if (copy_byte >= 0)
+ filter_bytes (memhunk, &size);
+
+ if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
+ size))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+
+ free (memhunk);
+ }
+ else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
+ {
+ PTR memhunk = (PTR) xmalloc ((unsigned) size);
+
+ /* We don't permit the user to turn off the SEC_HAS_CONTENTS
+ flag--they can just remove the section entirely and add it
+ back again. However, we do permit them to turn on the
+ SEC_HAS_CONTENTS flag, and take it to mean that the section
+ contents should be zeroed out. */
+
+ memset (memhunk, 0, size);
+ if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
+ size))
+ RETURN_NONFATAL (bfd_get_filename (obfd));
+ free (memhunk);
+ }
+}
+
+/* Get all the sections. This is used when --gap-fill or --pad-to is
+ used. */
+
+static void
+get_sections (obfd, osection, secppparg)
+ bfd *obfd;
+ asection *osection;
+ PTR secppparg;
+{
+ asection ***secppp = (asection ***) secppparg;
+
+ **secppp = osection;
+ ++(*secppp);
+}
+
+/* Sort sections by VMA. This is called via qsort, and is used when
+ --gap-fill or --pad-to is used. We force non loadable or empty
+ sections to the front, where they are easier to ignore. */
+
+static int
+compare_section_lma (arg1, arg2)
+ const PTR arg1;
+ const PTR arg2;
+{
+ const asection **sec1 = (const asection **) arg1;
+ const asection **sec2 = (const asection **) arg2;
+ flagword flags1, flags2;
+
+ /* Sort non loadable sections to the front. */
+ flags1 = (*sec1)->flags;
+ flags2 = (*sec2)->flags;
+ if ((flags1 & SEC_HAS_CONTENTS) == 0
+ || (flags1 & SEC_LOAD) == 0)
+ {
+ if ((flags2 & SEC_HAS_CONTENTS) != 0
+ && (flags2 & SEC_LOAD) != 0)
+ return -1;
+ }
+ else
+ {
+ if ((flags2 & SEC_HAS_CONTENTS) == 0
+ || (flags2 & SEC_LOAD) == 0)
+ return 1;
+ }
+
+ /* Sort sections by LMA. */
+ if ((*sec1)->lma > (*sec2)->lma)
+ return 1;
+ else if ((*sec1)->lma < (*sec2)->lma)
+ return -1;
+
+ /* Sort sections with the same LMA by size. */
+ if ((*sec1)->_raw_size > (*sec2)->_raw_size)
+ return 1;
+ else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
+ return -1;
+
+ return 0;
+}
+
+/* Mark all the symbols which will be used in output relocations with
+ the BSF_KEEP flag so that those symbols will not be stripped.
+
+ Ignore relocations which will not appear in the output file. */
+
+static void
+mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
+ bfd *ibfd;
+ sec_ptr isection;
+ PTR symbolsarg;
+{
+ asymbol **symbols = (asymbol **) symbolsarg;
+ long relsize;
+ arelent **relpp;
+ long relcount, i;
+
+ /* Ignore an input section with no corresponding output section. */
+ if (isection->output_section == NULL)
+ return;
+
+ relsize = bfd_get_reloc_upper_bound (ibfd, isection);
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (ibfd));
+
+ if (relsize == 0)
+ return;
+
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
+ if (relcount < 0)
+ bfd_fatal (bfd_get_filename (ibfd));
+
+ /* Examine each symbol used in a relocation. If it's not one of the
+ special bfd section symbols, then mark it with BSF_KEEP. */
+ for (i = 0; i < relcount; i++)
+ {
+ if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
+ && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
+ && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
+ (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
+ }
+
+ if (relpp != NULL)
+ free (relpp);
+}
+
+/* Write out debugging information. */
+
+static boolean
+write_debugging_info (obfd, dhandle, symcountp, symppp)
+ bfd *obfd;
+ PTR dhandle;
+ long *symcountp;
+ asymbol ***symppp;
+{
+ if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
+ return write_ieee_debugging_info (obfd, dhandle);
+
+ if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
+ || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
+ {
+ bfd_byte *syms, *strings;
+ bfd_size_type symsize, stringsize;
+ asection *stabsec, *stabstrsec;
+
+ if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
+ &symsize, &strings,
+ &stringsize))
+ return false;
+
+ stabsec = bfd_make_section (obfd, ".stab");
+ stabstrsec = bfd_make_section (obfd, ".stabstr");
+ if (stabsec == NULL
+ || stabstrsec == NULL
+ || ! bfd_set_section_size (obfd, stabsec, symsize)
+ || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
+ || ! bfd_set_section_alignment (obfd, stabsec, 2)
+ || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
+ || ! bfd_set_section_flags (obfd, stabsec,
+ (SEC_HAS_CONTENTS
+ | SEC_READONLY
+ | SEC_DEBUGGING))
+ || ! bfd_set_section_flags (obfd, stabstrsec,
+ (SEC_HAS_CONTENTS
+ | SEC_READONLY
+ | SEC_DEBUGGING)))
+ {
+ non_fatal (_("%s: can't create debugging section: %s"),
+ bfd_get_filename (obfd),
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ /* We can get away with setting the section contents now because
+ the next thing the caller is going to do is copy over the
+ real sections. We may someday have to split the contents
+ setting out of this function. */
+ if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
+ symsize)
+ || ! bfd_set_section_contents (obfd, stabstrsec, strings,
+ (file_ptr) 0, stringsize))
+ {
+ non_fatal (_("%s: can't set debugging section contents: %s"),
+ bfd_get_filename (obfd),
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ return true;
+ }
+
+ non_fatal (_("%s: don't know how to write debugging information for %s"),
+ bfd_get_filename (obfd), bfd_get_target (obfd));
+ return false;
+}
+
+static int
+strip_main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *input_target = NULL, *output_target = NULL;
+ boolean show_version = false;
+ int c, i;
+ struct section_list *p;
+ char *output_file = NULL;
+
+ while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpgxXVv",
+ strip_options, (int *) 0)) != EOF)
+ {
+ switch (c)
+ {
+ case 'I':
+ input_target = optarg;
+ break;
+ case 'O':
+ output_target = optarg;
+ break;
+ case 'F':
+ input_target = output_target = optarg;
+ break;
+ case 'R':
+ p = find_section_list (optarg, true);
+ p->remove = true;
+ sections_removed = true;
+ break;
+ case 's':
+ strip_symbols = STRIP_ALL;
+ break;
+ case 'S':
+ case 'g':
+ strip_symbols = STRIP_DEBUG;
+ break;
+ case OPTION_STRIP_UNNEEDED:
+ strip_symbols = STRIP_UNNEEDED;
+ break;
+ case 'K':
+ add_specific_symbol (optarg, &keep_specific_list);
+ break;
+ case 'N':
+ add_specific_symbol (optarg, &strip_specific_list);
+ break;
+ case 'o':
+ output_file = optarg;
+ break;
+ case 'p':
+ preserve_dates = true;
+ break;
+ case 'x':
+ discard_locals = LOCALS_ALL;
+ break;
+ case 'X':
+ discard_locals = LOCALS_START_L;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ case 'V':
+ show_version = true;
+ break;
+ case 0:
+ break; /* we've been given a long option */
+ case 'h':
+ strip_usage (stdout, 0);
+ default:
+ strip_usage (stderr, 1);
+ }
+ }
+
+ if (show_version)
+ print_version ("strip");
+
+ /* Default is to strip all symbols. */
+ if (strip_symbols == STRIP_UNDEF
+ && discard_locals == LOCALS_UNDEF
+ && strip_specific_list == NULL)
+ strip_symbols = STRIP_ALL;
+
+ if (output_target == (char *) NULL)
+ output_target = input_target;
+
+ i = optind;
+ if (i == argc
+ || (output_file != NULL && (i + 1) < argc))
+ strip_usage (stderr, 1);
+
+ for (; i < argc; i++)
+ {
+ int hold_status = status;
+ struct stat statbuf;
+ char *tmpname;
+
+ if (preserve_dates)
+ {
+ if (stat (argv[i], &statbuf) < 0)
+ {
+ non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
+ continue;
+ }
+ }
+
+ if (output_file != NULL)
+ tmpname = output_file;
+ else
+ tmpname = make_tempname (argv[i]);
+ status = 0;
+
+ copy_file (argv[i], tmpname, input_target, output_target);
+ if (status == 0)
+ {
+ if (preserve_dates)
+ set_times (tmpname, &statbuf);
+ if (output_file == NULL)
+ smart_rename (tmpname, argv[i], preserve_dates);
+ status = hold_status;
+ }
+ else
+ unlink (tmpname);
+ if (output_file == NULL)
+ free (tmpname);
+ }
+
+ return 0;
+}
+
+static int
+copy_main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *input_filename = NULL, *output_filename = NULL;
+ char *input_target = NULL, *output_target = NULL;
+ boolean show_version = false;
+ boolean change_warn = true;
+ int c;
+ struct section_list *p;
+ struct stat statbuf;
+
+ while ((c = getopt_long (argc, argv, "b:i:I:K:N:s:O:d:F:L:R:SpgxXVvW:",
+ copy_options, (int *) 0)) != EOF)
+ {
+ switch (c)
+ {
+ case 'b':
+ copy_byte = atoi (optarg);
+ if (copy_byte < 0)
+ fatal (_("byte number must be non-negative"));
+ break;
+ case 'i':
+ interleave = atoi (optarg);
+ if (interleave < 1)
+ fatal (_("interleave must be positive"));
+ break;
+ case 'I':
+ case 's': /* "source" - 'I' is preferred */
+ input_target = optarg;
+ break;
+ case 'O':
+ case 'd': /* "destination" - 'O' is preferred */
+ output_target = optarg;
+ break;
+ case 'F':
+ input_target = output_target = optarg;
+ break;
+ case 'R':
+ p = find_section_list (optarg, true);
+ p->remove = true;
+ sections_removed = true;
+ break;
+ case 'S':
+ strip_symbols = STRIP_ALL;
+ break;
+ case 'g':
+ strip_symbols = STRIP_DEBUG;
+ break;
+ case OPTION_STRIP_UNNEEDED:
+ strip_symbols = STRIP_UNNEEDED;
+ break;
+ case 'K':
+ add_specific_symbol (optarg, &keep_specific_list);
+ break;
+ case 'N':
+ add_specific_symbol (optarg, &strip_specific_list);
+ break;
+ case 'L':
+ add_specific_symbol (optarg, &localize_specific_list);
+ break;
+ case 'W':
+ add_specific_symbol (optarg, &weaken_specific_list);
+ break;
+ case 'p':
+ preserve_dates = true;
+ break;
+ case 'x':
+ discard_locals = LOCALS_ALL;
+ break;
+ case 'X':
+ discard_locals = LOCALS_START_L;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ case 'V':
+ show_version = true;
+ break;
+ case OPTION_WEAKEN:
+ weaken = true;
+ break;
+ case OPTION_ADD_SECTION:
+ {
+ const char *s;
+ struct stat st;
+ struct section_add *pa;
+ int len;
+ char *name;
+ FILE *f;
+
+ s = strchr (optarg, '=');
+
+ if (s == NULL)
+ fatal (_("bad format for --add-section NAME=FILENAME"));
+
+ if (stat (s + 1, & st) < 0)
+ fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
+
+ pa = (struct section_add *) xmalloc (sizeof (struct section_add));
+
+ len = s - optarg;
+ name = (char *) xmalloc (len + 1);
+ strncpy (name, optarg, len);
+ name[len] = '\0';
+ pa->name = name;
+
+ pa->filename = s + 1;
+
+ pa->size = st.st_size;
+
+ pa->contents = (bfd_byte *) xmalloc (pa->size);
+ f = fopen (pa->filename, FOPEN_RB);
+
+ if (f == NULL)
+ fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
+
+ if (fread (pa->contents, 1, pa->size, f) == 0
+ || ferror (f))
+ fatal (_("%s: fread failed"), pa->filename);
+
+ fclose (f);
+
+ pa->next = add_sections;
+ add_sections = pa;
+ }
+ break;
+ case OPTION_CHANGE_START:
+ change_start = parse_vma (optarg, "--change-start");
+ break;
+ case OPTION_CHANGE_SECTION_ADDRESS:
+ case OPTION_CHANGE_SECTION_LMA:
+ case OPTION_CHANGE_SECTION_VMA:
+ {
+ const char *s;
+ int len;
+ char *name;
+ char *option;
+ bfd_vma val;
+ enum change_action what;
+
+ switch (c)
+ {
+ case OPTION_CHANGE_SECTION_ADDRESS: option = "--change-section-address"; break;
+ case OPTION_CHANGE_SECTION_LMA: option = "--change-section-lma"; break;
+ case OPTION_CHANGE_SECTION_VMA: option = "--change-section-vma"; break;
+ }
+
+ s = strchr (optarg, '=');
+ if (s == NULL)
+ {
+ s = strchr (optarg, '+');
+ if (s == NULL)
+ {
+ s = strchr (optarg, '-');
+ if (s == NULL)
+ fatal (_("bad format for %s"), option);
+ }
+ }
+
+ len = s - optarg;
+ name = (char *) xmalloc (len + 1);
+ strncpy (name, optarg, len);
+ name[len] = '\0';
+
+ p = find_section_list (name, true);
+
+ val = parse_vma (s + 1, option);
+
+ switch (*s)
+ {
+ case '=': what = CHANGE_SET; break;
+ case '-': val = - val; /* Drop through. */
+ case '+': what = CHANGE_MODIFY; break;
+ }
+
+ switch (c)
+ {
+ case OPTION_CHANGE_SECTION_ADDRESS:
+ p->change_vma = what;
+ p->vma_val = val;
+ /* Drop through. */
+
+ case OPTION_CHANGE_SECTION_LMA:
+ p->change_lma = what;
+ p->lma_val = val;
+ break;
+
+ case OPTION_CHANGE_SECTION_VMA:
+ p->change_vma = what;
+ p->vma_val = val;
+ break;
+ }
+ }
+ break;
+ case OPTION_CHANGE_ADDRESSES:
+ change_section_address = parse_vma (optarg, "--change-addresses");
+ change_start = change_section_address;
+ break;
+ case OPTION_CHANGE_WARNINGS:
+ change_warn = true;
+ break;
+ case OPTION_CHANGE_LEADING_CHAR:
+ change_leading_char = true;
+ break;
+ case OPTION_DEBUGGING:
+ convert_debugging = true;
+ break;
+ case OPTION_GAP_FILL:
+ {
+ bfd_vma gap_fill_vma;
+
+ gap_fill_vma = parse_vma (optarg, "--gap-fill");
+ gap_fill = (bfd_byte) gap_fill_vma;
+ if ((bfd_vma) gap_fill != gap_fill_vma)
+ {
+ char buff[20];
+
+ sprintf_vma (buff, gap_fill_vma);
+
+ non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
+ buff, gap_fill);
+ }
+ gap_fill_set = true;
+ }
+ break;
+ case OPTION_NO_CHANGE_WARNINGS:
+ change_warn = false;
+ break;
+ case OPTION_PAD_TO:
+ pad_to = parse_vma (optarg, "--pad-to");
+ pad_to_set = true;
+ break;
+ case OPTION_REMOVE_LEADING_CHAR:
+ remove_leading_char = true;
+ break;
+ case OPTION_SET_SECTION_FLAGS:
+ {
+ const char *s;
+ int len;
+ char *name;
+
+ s = strchr (optarg, '=');
+ if (s == NULL)
+ fatal (_("bad format for --set-section-flags"));
+
+ len = s - optarg;
+ name = (char *) xmalloc (len + 1);
+ strncpy (name, optarg, len);
+ name[len] = '\0';
+
+ p = find_section_list (name, true);
+
+ p->set_flags = true;
+ p->flags = parse_flags (s + 1);
+ }
+ break;
+ case OPTION_SET_START:
+ set_start = parse_vma (optarg, "--set-start");
+ set_start_set = true;
+ break;
+ case 0:
+ break; /* we've been given a long option */
+ case 'h':
+ copy_usage (stdout, 0);
+ default:
+ copy_usage (stderr, 1);
+ }
+ }
+
+ if (show_version)
+ print_version ("objcopy");
+
+ if (copy_byte >= interleave)
+ fatal (_("byte number must be less than interleave"));
+
+ if (optind == argc || optind + 2 < argc)
+ copy_usage (stderr, 1);
+
+ input_filename = argv[optind];
+ if (optind + 1 < argc)
+ output_filename = argv[optind + 1];
+
+ /* Default is to strip no symbols. */
+ if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
+ strip_symbols = STRIP_NONE;
+
+ if (output_target == (char *) NULL)
+ output_target = input_target;
+
+ if (preserve_dates)
+ {
+ if (stat (input_filename, &statbuf) < 0)
+ fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
+ }
+
+ /* If there is no destination file then create a temp and rename
+ the result into the input. */
+
+ if (output_filename == (char *) NULL)
+ {
+ char *tmpname = make_tempname (input_filename);
+
+ copy_file (input_filename, tmpname, input_target, output_target);
+ if (status == 0)
+ {
+ if (preserve_dates)
+ set_times (tmpname, &statbuf);
+ smart_rename (tmpname, input_filename, preserve_dates);
+ }
+ else
+ unlink (tmpname);
+ }
+ else
+ {
+ copy_file (input_filename, output_filename, input_target, output_target);
+ if (status == 0 && preserve_dates)
+ set_times (output_filename, &statbuf);
+ }
+
+ if (change_warn)
+ {
+ for (p = change_sections; p != NULL; p = p->next)
+ {
+ if (! p->used)
+ {
+ if (p->change_vma != CHANGE_IGNORE)
+ {
+ char buff [20];
+
+ sprintf_vma (buff, p->vma_val);
+
+ /* xgettext:c-format */
+ non_fatal (_("Warning: --change-section-vma %s%c0x%s never used"),
+ p->name,
+ p->change_vma == CHANGE_SET ? '=' : '+',
+ buff);
+ }
+
+ if (p->change_lma != CHANGE_IGNORE)
+ {
+ char buff [20];
+
+ sprintf_vma (buff, p->lma_val);
+
+ /* xgettext:c-format */
+ non_fatal (_("Warning: --change-section-lma %s%c0x%s never used"),
+ p->name,
+ p->change_lma == CHANGE_SET ? '=' : '+',
+ buff);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ START_PROGRESS (program_name, 0);
+
+ strip_symbols = STRIP_UNDEF;
+ discard_locals = LOCALS_UNDEF;
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ if (is_strip < 0)
+ {
+ int i = strlen (program_name);
+ is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0);
+ }
+
+ if (is_strip)
+ strip_main (argc, argv);
+ else
+ copy_main (argc, argv);
+
+ END_PROGRESS (program_name);
+
+ return status;
+}
diff --git a/binutils/objdump.1 b/binutils/objdump.1
new file mode 100644
index 00000000000..ddc153ed8a3
--- /dev/null
+++ b/binutils/objdump.1
@@ -0,0 +1,412 @@
+.\" Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH objdump 1 "5 November 1991" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+objdump \- display information from object files.
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B objdump
+.RB "[\|" \-a | \-\-archive\-headers "\|]"
+.RB "[\|" "\-b\ "\c
+.I bfdname\c
+.RB " | " "\-\-target="\c
+.I bfdname\c
+\&\|]
+.RB "[\|" \-C | \-\-demangle "\|]"
+.RB "[\|" \-\-debugging "\|]"
+.RB "[\|" \-d | \-\-disassemble "\|]"
+.RB "[\|" \-D | \-\-disassemble-all "\|]"
+.RB "[\|" \-\-disassemble\-zeroes "\|]"
+.RB "[\|" \-EB | \-EL | \-\-endian=\c
+.I {big|little}\c
+\&\|]
+.RB "[\|" \-f | \-\-file\-headers "\|]"
+.RB "[\|" \-h | \-\-section\-headers
+.RB "| " \-\-headers "\|]"
+.RB "[\|" \-i | \-\-info "\|]"
+.RB "[\|" "\-j\ "\c
+.I section\c
+.RB " | " "\-\-section="\c
+.I section\c
+\&\|]
+.RB "[\|" \-l | \-\-line\-numbers "\|]"
+.RB "[\|" "\-m\ "\c
+.I machine\c
+.RB " | " "\-\-architecture="\c
+.I machine\c
+\&\|]
+.RB "[\|" \-p | \-\-private\-headers "\|]"
+.RB "[\|" \-\-prefix\-addresses "\|]"
+.RB "[\|" \-r | \-\-reloc "\|]"
+.RB "[\|" \-R | \-\-dynamic\-reloc "\|]"
+.RB "[\|" \-s | \-\-full\-contents "\|]"
+.RB "[\|" \-S | \-\-source "\|]"
+.RB "[\|" \-\-[no\-]show\-raw\-insn "\|]"
+.RB "[\|" \-\-stabs "\|]"
+.RB "[\|" \-t | \-\-syms "\|]"
+.RB "[\|" \-T | \-\-dynamic\-syms "\|]"
+.RB "[\|" \-x | \-\-all\-headers "\|]"
+.RB "[\|" "\-\-start\-address="\c
+.I address\c
+\&\|]
+.RB "[\|" "\-\-stop\-address="\c
+.I address\c
+\&\|]
+.RB "[\|" "\-\-adjust\-vma="\c
+.I offset\c
+\&\|]
+.RB "[\|" \-\-version "\|]"
+.RB "[\|" \-\-help "\|]"
+.I objfile\c
+\&.\|.\|.
+.ad b
+.hy 1
+.SH DESCRIPTION
+\c
+.B objdump\c
+\& displays information about one or more object files.
+The options control what particular information to display. This
+information is mostly useful to programmers who are working on the
+compilation tools, as opposed to programmers who just want their
+program to compile and work.
+.PP
+.IR "objfile" .\|.\|.
+are the object files to be examined. When you specify archives,
+\c
+.B objdump\c
+\& shows information on each of the member object files.
+
+.SH OPTIONS
+Where long and short forms of an option are shown together, they are
+equivalent. At least one option besides
+.B \-l
+(\fB\-\-line\-numbers\fP) must be given.
+
+.TP
+.B \-a
+.TP
+.B \-\-archive\-headers
+If any files from \c
+.I objfile\c
+\& are archives, display the archive
+header information (in a format similar to `\|\c
+.B ls \-l\c
+\|'). Besides the
+information you could list with `\|\c
+.B ar tv\c
+\|', `\|\c
+.B objdump \-a\c
+\|' shows
+the object file format of each archive member.
+
+.TP
+.BI "\-\-adjust\-vma=" "offset"
+When dumping information, first add
+.I offset
+to all the section addresses. This is useful if the section addresses
+do not correspond to the symbol table, which can happen when putting
+sections at particular addresses when using a format which can not
+represent section addresses, such as a.out.
+
+.TP
+.BI "\-b " "bfdname"\c
+.TP
+.BI "\-\-target=" "bfdname"
+Specify the object-code format for the object files to be
+\c
+.I bfdname\c
+\&. This may not be necessary; \c
+.I objdump\c
+\& can
+automatically recognize many formats. For example,
+.sp
+.br
+objdump\ \-b\ oasys\ \-m\ vax\ \-h\ fu.o
+.br
+.sp
+display summary information from the section headers (`\|\c
+.B \-h\c
+\|') of
+`\|\c
+.B fu.o\c
+\|', which is explicitly identified (`\|\c
+.B \-m\c
+\|') as a Vax object
+file in the format produced by Oasys compilers. You can list the
+formats available with the `\|\c
+.B \-i\c
+\|' option.
+
+.TP
+.B \-C
+.TP
+.B \-\-demangle
+Decode (\fIdemangle\fP) low-level symbol names into user-level names.
+Besides removing any initial underscore prepended by the system, this
+makes C++ function names readable.
+
+.TP
+.B \-\-debugging
+Display debugging information. This attempts to parse debugging
+information stored in the file and print it out using a C like syntax.
+Only certain types of debugging information have been implemented.
+
+.TP
+.B \-d
+.TP
+.B \-\-disassemble
+Display the assembler mnemonics for the machine
+instructions from \c
+.I objfile\c
+\&.
+This option only disassembles those sections which are
+expected to contain instructions.
+
+.TP
+.B \-D
+.TP
+.B \-\-disassemble-all
+Like \fB\-d\fP, but disassemble the contents of all sections, not just
+those expected to contain instructions.
+
+.TP
+.B \-\-prefix\-addresses
+When disassembling, print the complete address on each line. This is
+the older disassembly format.
+
+.TP
+.B \-\-disassemble\-zeroes
+Normally the disassembly output will skip blocks of zeroes. This
+option directs the disassembler to disassemble those blocks, just like
+any other data.
+
+.TP
+.B \-EB
+.TP
+.B \-EL
+.TP
+.BI "\-\-endian=" "{big|little}"
+Specify the endianness of the object files. This only affects
+disassembly. This can be useful when disassembling a file format which
+does not describe endianness information, such as S-records.
+
+.TP
+.B \-f
+.TP
+.B \-\-file\-headers
+Display summary information from the overall header of
+each file in \c
+.I objfile\c
+\&.
+
+.TP
+.B \-h
+.TP
+.B \-\-section\-headers
+.TP
+.B \-\-headers
+Display summary information from the section headers of the
+object file.
+
+.TP
+.B \-\-help
+Print a summary of the options to
+.B objdump
+and exit.
+
+.TP
+.B \-i
+.TP
+.B \-\-info
+Display a list showing all architectures and object formats available
+for specification with \c
+.B \-b\c
+\& or \c
+.B \-m\c
+\&.
+
+.TP
+.BI "\-j " "name"\c
+.TP
+.BI "\-\-section=" "name"
+Display information only for section \c
+.I name\c
+\&.
+
+.TP
+.B \-l
+.TP
+.B \-\-line\-numbers
+Label the display (using debugging information) with the filename
+and source line numbers corresponding to the object code shown.
+Only useful with \fB\-d\fP, \fB\-D\fP, or \fB\-r\fP.
+
+.TP
+.BI "\-m " "machine"\c
+.TP
+.BI "\-\-architecture=" "machine"
+Specify the architecture to use when disassembling object files. This
+can be useful when disassembling object files which do not describe
+architecture information, such as S-records. You can list the available
+architectures with the \fB\-i\fP option.
+
+.TP
+.B \-p
+.TP
+.B \-\-private\-headers
+Print information that is specific to the object file format. The
+exact information printed depends upon the object file format. For
+some object file formats, no additional information is printed.
+
+.TP
+.B \-r
+.TP
+.B \-\-reloc
+Print the relocation entries of the file. If used with \fB\-d\fP or
+\fB\-D\fP, the relocations are printed interspersed with the
+disassembly.
+
+.TP
+.B \-R
+.TP
+.B \-\-dynamic\-reloc
+Print the dynamic relocation entries of the file. This is only
+meaningful for dynamic objects, such as certain types of shared
+libraries.
+
+.TP
+.B \-s
+.TP
+.B \-\-full\-contents
+Display the full contents of any sections requested.
+
+.TP
+.B \-S
+.TP
+.B \-\-source
+Display source code intermixed with disassembly, if possible. Implies
+\fB-d\fP.
+
+.TP
+.B \-\-show\-raw\-insn
+When disassembling instructions, print the instruction in hex as well as
+in symbolic form. This is the default except when
+.B \-\-prefix\-addresses
+is used.
+
+.TP
+.B \-\-no\-show\-raw\-insn
+When disassembling instructions, do not print the instruction bytes.
+This is the default when
+.B \-\-prefix\-addresses
+is used.
+
+.TP
+.B \-\-stabs
+Display the contents of the .stab, .stab.index, and .stab.excl
+sections from an ELF file. This is only useful on systems (such as
+Solaris 2.0) in which .stab debugging symbol-table entries are carried
+in an ELF section. In most other file formats, debugging symbol-table
+entries are interleaved with linkage symbols, and are visible in the
+.B \-\-syms
+output.
+
+.TP
+.BI "\-\-start\-address=" "address"
+Start displaying data at the specified address. This affects the output
+of the
+.B \-d\c
+,
+.B \-r
+and
+.B \-s
+options.
+
+.TP
+.BI "\-\-stop\-address=" "address"
+Stop displaying data at the specified address. This affects the output
+of the
+.B \-d\c
+,
+.B \-r
+and
+.B \-s
+options.
+
+.TP
+.B \-t
+.TP
+.B \-\-syms
+Symbol Table. Print the symbol table entries of the file.
+This is similar to the information provided by the `\|\c
+.B nm\c
+\|' program.
+
+.TP
+.B \-T
+.TP
+.B \-\-dynamic\-syms
+Dynamic Symbol Table. Print the dynamic symbol table entries of the
+file. This is only meaningful for dynamic objects, such as certain
+types of shared libraries. This is similar to the information
+provided by the `\|\c
+.B nm\c
+\|' program when given the
+.B \-D (\-\-dynamic)
+option.
+
+.TP
+.B \-\-version
+Print the version number of
+.B objdump
+and exit.
+
+.TP
+.B \-x
+.TP
+.B \-\-all\-headers
+Display all available header information, including the symbol table and
+relocation entries. Using `\|\c
+.B \-x\c
+\|' is equivalent to specifying all of
+`\|\c
+.B \-a \-f \-h \-r \-t\c
+\|'.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (October 1991);
+.BR nm "(" 1 ")."
+
+.SH COPYING
+Copyright (c) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/objdump.c b/binutils/objdump.c
new file mode 100644
index 00000000000..3f9e8c4c3f6
--- /dev/null
+++ b/binutils/objdump.c
@@ -0,0 +1,2829 @@
+/* objdump.c -- dump information about an object file.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ 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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "getopt.h"
+#include "progress.h"
+#include "bucomm.h"
+#include <ctype.h>
+#include "dis-asm.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "debug.h"
+#include "budbg.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* Internal headers for the ELF .stab-dump code - sorry. */
+#define BYTES_IN_WORD 32
+#include "aout/aout64.h"
+
+#ifdef NEED_DECLARATION_FPRINTF
+/* This is needed by INIT_DISASSEMBLE_INFO. */
+extern int fprintf PARAMS ((FILE *, const char *, ...));
+#endif
+
+static char *default_target = NULL; /* default at runtime */
+
+static int show_version = 0; /* show the version number */
+static int dump_section_contents; /* -s */
+static int dump_section_headers; /* -h */
+static boolean dump_file_header; /* -f */
+static int dump_symtab; /* -t */
+static int dump_dynamic_symtab; /* -T */
+static int dump_reloc_info; /* -r */
+static int dump_dynamic_reloc_info; /* -R */
+static int dump_ar_hdrs; /* -a */
+static int dump_private_headers; /* -p */
+static int prefix_addresses; /* --prefix-addresses */
+static int with_line_numbers; /* -l */
+static boolean with_source_code; /* -S */
+static int show_raw_insn; /* --show-raw-insn */
+static int dump_stab_section_info; /* --stabs */
+static int do_demangle; /* -C, --demangle */
+static boolean disassemble; /* -d */
+static boolean disassemble_all; /* -D */
+static int disassemble_zeroes; /* --disassemble-zeroes */
+static boolean formats_info; /* -i */
+static char *only; /* -j secname */
+static int wide_output; /* -w */
+static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
+static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */
+static int dump_debugging; /* --debugging */
+static bfd_vma adjust_section_vma = 0; /* --adjust-vma */
+
+/* Extra info to pass to the disassembler address printing function. */
+struct objdump_disasm_info {
+ bfd *abfd;
+ asection *sec;
+ boolean require_sec;
+};
+
+/* Architecture to disassemble for, or default if NULL. */
+static char *machine = (char *) NULL;
+
+/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */
+static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
+
+/* The symbol table. */
+static asymbol **syms;
+
+/* Number of symbols in `syms'. */
+static long symcount = 0;
+
+/* The sorted symbol table. */
+static asymbol **sorted_syms;
+
+/* Number of symbols in `sorted_syms'. */
+static long sorted_symcount = 0;
+
+/* The dynamic symbol table. */
+static asymbol **dynsyms;
+
+/* Number of symbols in `dynsyms'. */
+static long dynsymcount = 0;
+
+/* Static declarations. */
+
+static void
+usage PARAMS ((FILE *, int));
+
+static void
+display_file PARAMS ((char *filename, char *target));
+
+static void
+dump_section_header PARAMS ((bfd *, asection *, PTR));
+
+static void
+dump_headers PARAMS ((bfd *));
+
+static void
+dump_data PARAMS ((bfd *abfd));
+
+static void
+dump_relocs PARAMS ((bfd *abfd));
+
+static void
+dump_dynamic_relocs PARAMS ((bfd * abfd));
+
+static void
+dump_reloc_set PARAMS ((bfd *, asection *, arelent **, long));
+
+static void
+dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
+
+static void
+dump_bfd_header PARAMS ((bfd *));
+
+static void
+dump_bfd_private_header PARAMS ((bfd *));
+
+static void
+display_bfd PARAMS ((bfd *abfd));
+
+static void
+display_target_list PARAMS ((void));
+
+static void
+display_info_table PARAMS ((int, int));
+
+static void
+display_target_tables PARAMS ((void));
+
+static void
+display_info PARAMS ((void));
+
+static void
+objdump_print_value PARAMS ((bfd_vma, struct disassemble_info *, boolean));
+
+static void
+objdump_print_symname PARAMS ((bfd *, struct disassemble_info *, asymbol *));
+
+static asymbol *
+find_symbol_for_address PARAMS ((bfd *, asection *, bfd_vma, boolean, long *));
+
+static void
+objdump_print_addr_with_sym PARAMS ((bfd *, asection *, asymbol *, bfd_vma,
+ struct disassemble_info *, boolean));
+
+static void
+objdump_print_addr PARAMS ((bfd_vma, struct disassemble_info *, boolean));
+
+static void
+objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
+
+static void
+show_line PARAMS ((bfd *, asection *, bfd_vma));
+
+static void
+disassemble_bytes PARAMS ((struct disassemble_info *, disassembler_ftype,
+ boolean, bfd_byte *, bfd_vma, bfd_vma,
+ arelent ***, arelent **));
+
+static void
+disassemble_data PARAMS ((bfd *));
+
+static const char *
+endian_string PARAMS ((enum bfd_endian));
+
+static asymbol **
+slurp_symtab PARAMS ((bfd *));
+
+static asymbol **
+slurp_dynamic_symtab PARAMS ((bfd *));
+
+static long
+remove_useless_symbols PARAMS ((asymbol **, long));
+
+static int
+compare_symbols PARAMS ((const PTR, const PTR));
+
+static int
+compare_relocs PARAMS ((const PTR, const PTR));
+
+static void
+dump_stabs PARAMS ((bfd *));
+
+static boolean
+read_section_stabs PARAMS ((bfd *, const char *, const char *));
+
+static void
+print_section_stabs PARAMS ((bfd *, const char *, const char *));
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, _("\
+Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
+ [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
+ [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\
+ [--section-headers] [--headers]\n\
+ [--info] [--section=section-name] [--line-numbers] [--source]\n"),
+ program_name);
+ fprintf (stream, _("\
+ [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
+ [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
+ [--wide] [--version] [--help] [--private-headers]\n\
+ [--start-address=addr] [--stop-address=addr]\n\
+ [--prefix-addresses] [--[no-]show-raw-insn] [--demangle]\n\
+ [--adjust-vma=offset] [-EB|-EL] [--endian={big|little}] objfile...\n\
+at least one option besides -l (--line-numbers) must be given\n"));
+ list_supported_targets (program_name, stream);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
+
+#define OPTION_ENDIAN (150)
+#define OPTION_START_ADDRESS (OPTION_ENDIAN + 1)
+#define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1)
+#define OPTION_ADJUST_VMA (OPTION_STOP_ADDRESS + 1)
+
+static struct option long_options[]=
+{
+ {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
+ {"all-headers", no_argument, NULL, 'x'},
+ {"private-headers", no_argument, NULL, 'p'},
+ {"architecture", required_argument, NULL, 'm'},
+ {"archive-headers", no_argument, NULL, 'a'},
+ {"debugging", no_argument, &dump_debugging, 1},
+ {"demangle", no_argument, &do_demangle, 1},
+ {"disassemble", no_argument, NULL, 'd'},
+ {"disassemble-all", no_argument, NULL, 'D'},
+ {"disassemble-zeroes", no_argument, &disassemble_zeroes, 1},
+ {"dynamic-reloc", no_argument, NULL, 'R'},
+ {"dynamic-syms", no_argument, NULL, 'T'},
+ {"endian", required_argument, NULL, OPTION_ENDIAN},
+ {"file-headers", no_argument, NULL, 'f'},
+ {"full-contents", no_argument, NULL, 's'},
+ {"headers", no_argument, NULL, 'h'},
+ {"help", no_argument, NULL, 'H'},
+ {"info", no_argument, NULL, 'i'},
+ {"line-numbers", no_argument, NULL, 'l'},
+ {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
+ {"prefix-addresses", no_argument, &prefix_addresses, 1},
+ {"reloc", no_argument, NULL, 'r'},
+ {"section", required_argument, NULL, 'j'},
+ {"section-headers", no_argument, NULL, 'h'},
+ {"show-raw-insn", no_argument, &show_raw_insn, 1},
+ {"source", no_argument, NULL, 'S'},
+ {"stabs", no_argument, &dump_stab_section_info, 1},
+ {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
+ {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
+ {"syms", no_argument, NULL, 't'},
+ {"target", required_argument, NULL, 'b'},
+ {"version", no_argument, &show_version, 1},
+ {"wide", no_argument, &wide_output, 'w'},
+ {0, no_argument, 0, 0}
+};
+
+static void
+dump_section_header (abfd, section, ignored)
+ bfd *abfd;
+ asection *section;
+ PTR ignored;
+{
+ char *comma = "";
+
+ printf ("%3d %-13s %08lx ", section->index,
+ bfd_get_section_name (abfd, section),
+ (unsigned long) bfd_section_size (abfd, section));
+ printf_vma (bfd_get_section_vma (abfd, section));
+ printf (" ");
+ printf_vma (section->lma);
+ printf (" %08lx 2**%u", section->filepos,
+ bfd_get_section_alignment (abfd, section));
+ if (! wide_output)
+ printf ("\n ");
+ printf (" ");
+
+#define PF(x, y) \
+ if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; }
+
+ PF (SEC_HAS_CONTENTS, "CONTENTS");
+ PF (SEC_ALLOC, "ALLOC");
+ PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
+ PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
+ PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
+ PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
+ PF (SEC_LOAD, "LOAD");
+ PF (SEC_RELOC, "RELOC");
+#ifdef SEC_BALIGN
+ PF (SEC_BALIGN, "BALIGN");
+#endif
+ PF (SEC_READONLY, "READONLY");
+ PF (SEC_CODE, "CODE");
+ PF (SEC_DATA, "DATA");
+ PF (SEC_ROM, "ROM");
+ PF (SEC_DEBUGGING, "DEBUGGING");
+ PF (SEC_NEVER_LOAD, "NEVER_LOAD");
+ PF (SEC_EXCLUDE, "EXCLUDE");
+ PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
+
+ if ((section->flags & SEC_LINK_ONCE) != 0)
+ {
+ const char *ls;
+
+ switch (section->flags & SEC_LINK_DUPLICATES)
+ {
+ default:
+ abort ();
+ case SEC_LINK_DUPLICATES_DISCARD:
+ ls = "LINK_ONCE_DISCARD";
+ break;
+ case SEC_LINK_DUPLICATES_ONE_ONLY:
+ ls = "LINK_ONCE_ONE_ONLY";
+ break;
+ case SEC_LINK_DUPLICATES_SAME_SIZE:
+ ls = "LINK_ONCE_SAME_SIZE";
+ break;
+ case SEC_LINK_DUPLICATES_SAME_CONTENTS:
+ ls = "LINK_ONCE_SAME_CONTENTS";
+ break;
+ }
+ printf ("%s%s", comma, ls);
+ comma = ", ";
+ }
+
+ printf ("\n");
+#undef PF
+}
+
+static void
+dump_headers (abfd)
+ bfd *abfd;
+{
+ printf (_("Sections:\n"));
+#ifndef BFD64
+ printf (_("Idx Name Size VMA LMA File off Algn\n"));
+#else
+ printf (_("Idx Name Size VMA LMA File off Algn\n"));
+#endif
+ bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
+}
+
+static asymbol **
+slurp_symtab (abfd)
+ bfd *abfd;
+{
+ asymbol **sy = (asymbol **) NULL;
+ long storage;
+
+ if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+ {
+ fprintf (stderr, _("%s: no symbols\n"), bfd_get_filename (abfd));
+ symcount = 0;
+ return NULL;
+ }
+
+ storage = bfd_get_symtab_upper_bound (abfd);
+ if (storage < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (storage)
+ {
+ sy = (asymbol **) xmalloc (storage);
+ }
+ symcount = bfd_canonicalize_symtab (abfd, sy);
+ if (symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ if (symcount == 0)
+ fprintf (stderr, _("%s: no symbols\n"), bfd_get_filename (abfd));
+ return sy;
+}
+
+/* Read in the dynamic symbols. */
+
+static asymbol **
+slurp_dynamic_symtab (abfd)
+ bfd *abfd;
+{
+ asymbol **sy = (asymbol **) NULL;
+ long storage;
+
+ storage = bfd_get_dynamic_symtab_upper_bound (abfd);
+ if (storage < 0)
+ {
+ if (!(bfd_get_file_flags (abfd) & DYNAMIC))
+ {
+ fprintf (stderr, _("%s: %s: not a dynamic object\n"),
+ program_name, bfd_get_filename (abfd));
+ dynsymcount = 0;
+ return NULL;
+ }
+
+ bfd_fatal (bfd_get_filename (abfd));
+ }
+
+ if (storage)
+ {
+ sy = (asymbol **) xmalloc (storage);
+ }
+ dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
+ if (dynsymcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ if (dynsymcount == 0)
+ fprintf (stderr, _("%s: %s: No dynamic symbols\n"),
+ program_name, bfd_get_filename (abfd));
+ return sy;
+}
+
+/* Filter out (in place) symbols that are useless for disassembly.
+ COUNT is the number of elements in SYMBOLS.
+ Return the number of useful symbols. */
+
+static long
+remove_useless_symbols (symbols, count)
+ asymbol **symbols;
+ long count;
+{
+ register asymbol **in_ptr = symbols, **out_ptr = symbols;
+
+ while (--count >= 0)
+ {
+ asymbol *sym = *in_ptr++;
+
+ if (sym->name == NULL || sym->name[0] == '\0')
+ continue;
+ if (sym->flags & (BSF_DEBUGGING))
+ continue;
+ if (bfd_is_und_section (sym->section)
+ || bfd_is_com_section (sym->section))
+ continue;
+
+ *out_ptr++ = sym;
+ }
+ return out_ptr - symbols;
+}
+
+/* Sort symbols into value order. */
+
+static int
+compare_symbols (ap, bp)
+ const PTR ap;
+ const PTR bp;
+{
+ const asymbol *a = *(const asymbol **)ap;
+ const asymbol *b = *(const asymbol **)bp;
+ const char *an, *bn;
+ size_t anl, bnl;
+ boolean af, bf;
+ flagword aflags, bflags;
+
+ if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
+ return 1;
+ else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
+ return -1;
+
+ if (a->section > b->section)
+ return 1;
+ else if (a->section < b->section)
+ return -1;
+
+ an = bfd_asymbol_name (a);
+ bn = bfd_asymbol_name (b);
+ anl = strlen (an);
+ bnl = strlen (bn);
+
+ /* The symbols gnu_compiled and gcc2_compiled convey no real
+ information, so put them after other symbols with the same value. */
+
+ af = (strstr (an, "gnu_compiled") != NULL
+ || strstr (an, "gcc2_compiled") != NULL);
+ bf = (strstr (bn, "gnu_compiled") != NULL
+ || strstr (bn, "gcc2_compiled") != NULL);
+
+ if (af && ! bf)
+ return 1;
+ if (! af && bf)
+ return -1;
+
+ /* We use a heuristic for the file name, to try to sort it after
+ more useful symbols. It may not work on non Unix systems, but it
+ doesn't really matter; the only difference is precisely which
+ symbol names get printed. */
+
+#define file_symbol(s, sn, snl) \
+ (((s)->flags & BSF_FILE) != 0 \
+ || ((sn)[(snl) - 2] == '.' \
+ && ((sn)[(snl) - 1] == 'o' \
+ || (sn)[(snl) - 1] == 'a')))
+
+ af = file_symbol (a, an, anl);
+ bf = file_symbol (b, bn, bnl);
+
+ if (af && ! bf)
+ return 1;
+ if (! af && bf)
+ return -1;
+
+ /* Try to sort global symbols before local symbols before function
+ symbols before debugging symbols. */
+
+ aflags = a->flags;
+ bflags = b->flags;
+
+ if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
+ {
+ if ((aflags & BSF_DEBUGGING) != 0)
+ return 1;
+ else
+ return -1;
+ }
+ if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
+ {
+ if ((aflags & BSF_FUNCTION) != 0)
+ return -1;
+ else
+ return 1;
+ }
+ if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
+ {
+ if ((aflags & BSF_LOCAL) != 0)
+ return 1;
+ else
+ return -1;
+ }
+ if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
+ {
+ if ((aflags & BSF_GLOBAL) != 0)
+ return -1;
+ else
+ return 1;
+ }
+
+ /* Symbols that start with '.' might be section names, so sort them
+ after symbols that don't start with '.'. */
+ if (an[0] == '.' && bn[0] != '.')
+ return 1;
+ if (an[0] != '.' && bn[0] == '.')
+ return -1;
+
+ /* Finally, if we can't distinguish them in any other way, try to
+ get consistent results by sorting the symbols by name. */
+ return strcmp (an, bn);
+}
+
+/* Sort relocs into address order. */
+
+static int
+compare_relocs (ap, bp)
+ const PTR ap;
+ const PTR bp;
+{
+ const arelent *a = *(const arelent **)ap;
+ const arelent *b = *(const arelent **)bp;
+
+ if (a->address > b->address)
+ return 1;
+ else if (a->address < b->address)
+ return -1;
+
+ /* So that associated relocations tied to the same address show up
+ in the correct order, we don't do any further sorting. */
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+ else
+ return 0;
+}
+
+/* Print VMA to STREAM. If SKIP_ZEROES is true, omit leading zeroes. */
+
+static void
+objdump_print_value (vma, info, skip_zeroes)
+ bfd_vma vma;
+ struct disassemble_info *info;
+ boolean skip_zeroes;
+{
+ char buf[30];
+ char *p;
+
+ sprintf_vma (buf, vma);
+ if (! skip_zeroes)
+ p = buf;
+ else
+ {
+ for (p = buf; *p == '0'; ++p)
+ ;
+ if (*p == '\0')
+ --p;
+ }
+ (*info->fprintf_func) (info->stream, "%s", p);
+}
+
+/* Print the name of a symbol. */
+
+static void
+objdump_print_symname (abfd, info, sym)
+ bfd *abfd;
+ struct disassemble_info *info;
+ asymbol *sym;
+{
+ char *alloc;
+ const char *name;
+ const char *print;
+
+ alloc = NULL;
+ name = bfd_asymbol_name (sym);
+ if (! do_demangle || name[0] == '\0')
+ print = name;
+ else
+ {
+ /* Demangle the name. */
+ if (bfd_get_symbol_leading_char (abfd) == name[0])
+ ++name;
+
+ alloc = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ if (alloc == NULL)
+ print = name;
+ else
+ print = alloc;
+ }
+
+ if (info != NULL)
+ (*info->fprintf_func) (info->stream, "%s", print);
+ else
+ printf ("%s", print);
+
+ if (alloc != NULL)
+ free (alloc);
+}
+
+/* Locate a symbol given a bfd, a section, and a VMA. If REQUIRE_SEC
+ is true, then always require the symbol to be in the section. This
+ returns NULL if there is no suitable symbol. If PLACE is not NULL,
+ then *PLACE is set to the index of the symbol in sorted_syms. */
+
+static asymbol *
+find_symbol_for_address (abfd, sec, vma, require_sec, place)
+ bfd *abfd;
+ asection *sec;
+ bfd_vma vma;
+ boolean require_sec;
+ long *place;
+{
+ /* @@ Would it speed things up to cache the last two symbols returned,
+ and maybe their address ranges? For many processors, only one memory
+ operand can be present at a time, so the 2-entry cache wouldn't be
+ constantly churned by code doing heavy memory accesses. */
+
+ /* Indices in `sorted_syms'. */
+ long min = 0;
+ long max = sorted_symcount;
+ long thisplace;
+
+ if (sorted_symcount < 1)
+ return NULL;
+
+ /* Perform a binary search looking for the closest symbol to the
+ required value. We are searching the range (min, max]. */
+ while (min + 1 < max)
+ {
+ asymbol *sym;
+
+ thisplace = (max + min) / 2;
+ sym = sorted_syms[thisplace];
+
+ if (bfd_asymbol_value (sym) > vma)
+ max = thisplace;
+ else if (bfd_asymbol_value (sym) < vma)
+ min = thisplace;
+ else
+ {
+ min = thisplace;
+ break;
+ }
+ }
+
+ /* The symbol we want is now in min, the low end of the range we
+ were searching. If there are several symbols with the same
+ value, we want the first one. */
+ thisplace = min;
+ while (thisplace > 0
+ && (bfd_asymbol_value (sorted_syms[thisplace])
+ == bfd_asymbol_value (sorted_syms[thisplace - 1])))
+ --thisplace;
+
+ /* If the file is relocateable, and the symbol could be from this
+ section, prefer a symbol from this section over symbols from
+ others, even if the other symbol's value might be closer.
+
+ Note that this may be wrong for some symbol references if the
+ sections have overlapping memory ranges, but in that case there's
+ no way to tell what's desired without looking at the relocation
+ table. */
+
+ if (sorted_syms[thisplace]->section != sec
+ && (require_sec
+ || ((abfd->flags & HAS_RELOC) != 0
+ && vma >= bfd_get_section_vma (abfd, sec)
+ && vma < (bfd_get_section_vma (abfd, sec)
+ + bfd_section_size (abfd, sec)))))
+ {
+ long i;
+
+ for (i = thisplace + 1; i < sorted_symcount; i++)
+ {
+ if (bfd_asymbol_value (sorted_syms[i])
+ != bfd_asymbol_value (sorted_syms[thisplace]))
+ break;
+ }
+ --i;
+ for (; i >= 0; i--)
+ {
+ if (sorted_syms[i]->section == sec
+ && (i == 0
+ || sorted_syms[i - 1]->section != sec
+ || (bfd_asymbol_value (sorted_syms[i])
+ != bfd_asymbol_value (sorted_syms[i - 1]))))
+ {
+ thisplace = i;
+ break;
+ }
+ }
+
+ if (sorted_syms[thisplace]->section != sec)
+ {
+ /* We didn't find a good symbol with a smaller value.
+ Look for one with a larger value. */
+ for (i = thisplace + 1; i < sorted_symcount; i++)
+ {
+ if (sorted_syms[i]->section == sec)
+ {
+ thisplace = i;
+ break;
+ }
+ }
+ }
+
+ if (sorted_syms[thisplace]->section != sec
+ && (require_sec
+ || ((abfd->flags & HAS_RELOC) != 0
+ && vma >= bfd_get_section_vma (abfd, sec)
+ && vma < (bfd_get_section_vma (abfd, sec)
+ + bfd_section_size (abfd, sec)))))
+ {
+ /* There is no suitable symbol. */
+ return NULL;
+ }
+ }
+
+ if (place != NULL)
+ *place = thisplace;
+
+ return sorted_syms[thisplace];
+}
+
+/* Print an address to INFO symbolically. */
+
+static void
+objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
+ bfd *abfd;
+ asection *sec;
+ asymbol *sym;
+ bfd_vma vma;
+ struct disassemble_info *info;
+ boolean skip_zeroes;
+{
+ objdump_print_value (vma, info, skip_zeroes);
+
+ if (sym == NULL)
+ {
+ bfd_vma secaddr;
+
+ (*info->fprintf_func) (info->stream, " <%s",
+ bfd_get_section_name (abfd, sec));
+ secaddr = bfd_get_section_vma (abfd, sec);
+ if (vma < secaddr)
+ {
+ (*info->fprintf_func) (info->stream, "-0x");
+ objdump_print_value (secaddr - vma, info, true);
+ }
+ else if (vma > secaddr)
+ {
+ (*info->fprintf_func) (info->stream, "+0x");
+ objdump_print_value (vma - secaddr, info, true);
+ }
+ (*info->fprintf_func) (info->stream, ">");
+ }
+ else
+ {
+ (*info->fprintf_func) (info->stream, " <");
+ objdump_print_symname (abfd, info, sym);
+ if (bfd_asymbol_value (sym) > vma)
+ {
+ (*info->fprintf_func) (info->stream, "-0x");
+ objdump_print_value (bfd_asymbol_value (sym) - vma, info, true);
+ }
+ else if (vma > bfd_asymbol_value (sym))
+ {
+ (*info->fprintf_func) (info->stream, "+0x");
+ objdump_print_value (vma - bfd_asymbol_value (sym), info, true);
+ }
+ (*info->fprintf_func) (info->stream, ">");
+ }
+}
+
+/* Print VMA to INFO, symbolically if possible. If SKIP_ZEROES is
+ true, don't output leading zeroes. */
+
+static void
+objdump_print_addr (vma, info, skip_zeroes)
+ bfd_vma vma;
+ struct disassemble_info *info;
+ boolean skip_zeroes;
+{
+ struct objdump_disasm_info *aux;
+ asymbol *sym;
+
+ if (sorted_symcount < 1)
+ {
+ (*info->fprintf_func) (info->stream, "0x");
+ objdump_print_value (vma, info, skip_zeroes);
+ return;
+ }
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
+ (long *) NULL);
+ objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
+ skip_zeroes);
+}
+
+/* Print VMA to INFO. This function is passed to the disassembler
+ routine. */
+
+static void
+objdump_print_address (vma, info)
+ bfd_vma vma;
+ struct disassemble_info *info;
+{
+ objdump_print_addr (vma, info, ! prefix_addresses);
+}
+
+/* Determine of the given address has a symbol associated with it. */
+
+static int
+objdump_symbol_at_address (vma, info)
+ bfd_vma vma;
+ struct disassemble_info * info;
+{
+ struct objdump_disasm_info * aux;
+ asymbol * sym;
+
+ /* No symbols - do not bother checking. */
+ if (sorted_symcount < 1)
+ return 0;
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
+ (long *) NULL);
+
+ return (sym != NULL && (bfd_asymbol_value (sym) == vma));
+}
+
+/* Hold the last function name and the last line number we displayed
+ in a disassembly. */
+
+static char *prev_functionname;
+static unsigned int prev_line;
+
+/* We keep a list of all files that we have seen when doing a
+ dissassembly with source, so that we know how much of the file to
+ display. This can be important for inlined functions. */
+
+struct print_file_list
+{
+ struct print_file_list *next;
+ char *filename;
+ unsigned int line;
+ FILE *f;
+};
+
+static struct print_file_list *print_files;
+
+/* The number of preceding context lines to show when we start
+ displaying a file for the first time. */
+
+#define SHOW_PRECEDING_CONTEXT_LINES (5)
+
+/* Skip ahead to a given line in a file, optionally printing each
+ line. */
+
+static void
+skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean));
+
+static void
+skip_to_line (p, line, show)
+ struct print_file_list *p;
+ unsigned int line;
+ boolean show;
+{
+ while (p->line < line)
+ {
+ char buf[100];
+
+ if (fgets (buf, sizeof buf, p->f) == NULL)
+ {
+ fclose (p->f);
+ p->f = NULL;
+ break;
+ }
+
+ if (show)
+ printf ("%s", buf);
+
+ if (strchr (buf, '\n') != NULL)
+ ++p->line;
+ }
+}
+
+/* Show the line number, or the source line, in a dissassembly
+ listing. */
+
+static void
+show_line (abfd, section, off)
+ bfd *abfd;
+ asection *section;
+ bfd_vma off;
+{
+ CONST char *filename;
+ CONST char *functionname;
+ unsigned int line;
+
+ if (! with_line_numbers && ! with_source_code)
+ return;
+
+ if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
+ &functionname, &line))
+ return;
+
+ if (filename != NULL && *filename == '\0')
+ filename = NULL;
+ if (functionname != NULL && *functionname == '\0')
+ functionname = NULL;
+
+ if (with_line_numbers)
+ {
+ if (functionname != NULL
+ && (prev_functionname == NULL
+ || strcmp (functionname, prev_functionname) != 0))
+ printf ("%s():\n", functionname);
+ if (line > 0 && line != prev_line)
+ printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
+ }
+
+ if (with_source_code
+ && filename != NULL
+ && line > 0)
+ {
+ struct print_file_list **pp, *p;
+
+ for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
+ if (strcmp ((*pp)->filename, filename) == 0)
+ break;
+ p = *pp;
+
+ if (p != NULL)
+ {
+ if (p != print_files)
+ {
+ int l;
+
+ /* We have reencountered a file name which we saw
+ earlier. This implies that either we are dumping out
+ code from an included file, or the same file was
+ linked in more than once. There are two common cases
+ of an included file: inline functions in a header
+ file, and a bison or flex skeleton file. In the
+ former case we want to just start printing (but we
+ back up a few lines to give context); in the latter
+ case we want to continue from where we left off. I
+ can't think of a good way to distinguish the cases,
+ so I used a heuristic based on the file name. */
+ if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
+ l = p->line;
+ else
+ {
+ l = line - SHOW_PRECEDING_CONTEXT_LINES;
+ if (l <= 0)
+ l = 1;
+ }
+
+ if (p->f == NULL)
+ {
+ p->f = fopen (p->filename, "r");
+ p->line = 0;
+ }
+ if (p->f != NULL)
+ skip_to_line (p, l, false);
+
+ if (print_files->f != NULL)
+ {
+ fclose (print_files->f);
+ print_files->f = NULL;
+ }
+ }
+
+ if (p->f != NULL)
+ {
+ skip_to_line (p, line, true);
+ *pp = p->next;
+ p->next = print_files;
+ print_files = p;
+ }
+ }
+ else
+ {
+ FILE *f;
+
+ f = fopen (filename, "r");
+ if (f != NULL)
+ {
+ int l;
+
+ p = ((struct print_file_list *)
+ xmalloc (sizeof (struct print_file_list)));
+ p->filename = xmalloc (strlen (filename) + 1);
+ strcpy (p->filename, filename);
+ p->line = 0;
+ p->f = f;
+
+ if (print_files != NULL && print_files->f != NULL)
+ {
+ fclose (print_files->f);
+ print_files->f = NULL;
+ }
+ p->next = print_files;
+ print_files = p;
+
+ l = line - SHOW_PRECEDING_CONTEXT_LINES;
+ if (l <= 0)
+ l = 1;
+ skip_to_line (p, l, false);
+ if (p->f != NULL)
+ skip_to_line (p, line, true);
+ }
+ }
+ }
+
+ if (functionname != NULL
+ && (prev_functionname == NULL
+ || strcmp (functionname, prev_functionname) != 0))
+ {
+ if (prev_functionname != NULL)
+ free (prev_functionname);
+ prev_functionname = xmalloc (strlen (functionname) + 1);
+ strcpy (prev_functionname, functionname);
+ }
+
+ if (line > 0 && line != prev_line)
+ prev_line = line;
+}
+
+/* Pseudo FILE object for strings. */
+typedef struct
+{
+ char *buffer;
+ size_t size;
+ char *current;
+} SFILE;
+
+/* sprintf to a "stream" */
+
+static int
+#ifdef ANSI_PROTOTYPES
+objdump_sprintf (SFILE *f, const char *format, ...)
+#else
+objdump_sprintf (va_alist)
+ va_dcl
+#endif
+{
+#ifndef ANSI_PROTOTYPES
+ SFILE *f;
+ const char *format;
+#endif
+ char *buf;
+ va_list args;
+ size_t n;
+
+#ifdef ANSI_PROTOTYPES
+ va_start (args, format);
+#else
+ va_start (args);
+ f = va_arg (args, SFILE *);
+ format = va_arg (args, const char *);
+#endif
+
+ vasprintf (&buf, format, args);
+
+ va_end (args);
+
+ if (buf == NULL)
+ {
+ fprintf (stderr, _("Out of virtual memory\n"));
+ exit (1);
+ }
+
+ n = strlen (buf);
+
+ while ((f->buffer + f->size) - f->current < n + 1)
+ {
+ size_t curroff;
+
+ curroff = f->current - f->buffer;
+ f->size *= 2;
+ f->buffer = xrealloc (f->buffer, f->size);
+ f->current = f->buffer + curroff;
+ }
+
+ memcpy (f->current, buf, n);
+ f->current += n;
+ f->current[0] = '\0';
+
+ free (buf);
+
+ return n;
+}
+
+/* The number of zeroes we want to see before we start skipping them.
+ The number is arbitrarily chosen. */
+
+#define SKIP_ZEROES (8)
+
+/* The number of zeroes to skip at the end of a section. If the
+ number of zeroes at the end is between SKIP_ZEROES_AT_END and
+ SKIP_ZEROES, they will be disassembled. If there are fewer than
+ SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic
+ attempt to avoid disassembling zeroes inserted by section
+ alignment. */
+
+#define SKIP_ZEROES_AT_END (3)
+
+/* Disassemble some data in memory between given values. */
+
+static void
+disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
+ relppend)
+ struct disassemble_info *info;
+ disassembler_ftype disassemble_fn;
+ boolean insns;
+ bfd_byte *data;
+ bfd_vma start;
+ bfd_vma stop;
+ arelent ***relppp;
+ arelent **relppend;
+{
+ struct objdump_disasm_info *aux;
+ asection *section;
+ int bytes_per_line;
+ boolean done_dot;
+ int skip_addr_chars;
+ bfd_vma i;
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ section = aux->sec;
+
+ if (insns)
+ bytes_per_line = 4;
+ else
+ bytes_per_line = 16;
+
+ /* Figure out how many characters to skip at the start of an
+ address, to make the disassembly look nicer. We discard leading
+ zeroes in chunks of 4, ensuring that there is always a leading
+ zero remaining. */
+ skip_addr_chars = 0;
+ if (! prefix_addresses)
+ {
+ char buf[30];
+ char *s;
+
+ sprintf_vma (buf,
+ section->vma + bfd_section_size (section->owner, section));
+ s = buf;
+ while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'
+ && s[4] == '0')
+ {
+ skip_addr_chars += 4;
+ s += 4;
+ }
+ }
+
+ info->insn_info_valid = 0;
+
+ done_dot = false;
+ i = start;
+ while (i < stop)
+ {
+ bfd_vma z;
+ int bytes = 0;
+ boolean need_nl = false;
+
+ /* If we see more than SKIP_ZEROES bytes of zeroes, we just
+ print `...'. */
+ for (z = i; z < stop; z++)
+ if (data[z] != 0)
+ break;
+ if (! disassemble_zeroes
+ && (info->insn_info_valid == 0
+ || info->branch_delay_insns == 0)
+ && (z - i >= SKIP_ZEROES
+ || (z == stop && z - i < SKIP_ZEROES_AT_END)))
+ {
+ printf ("\t...\n");
+
+ /* If there are more nonzero bytes to follow, we only skip
+ zeroes in multiples of 4, to try to avoid running over
+ the start of an instruction which happens to start with
+ zero. */
+ if (z != stop)
+ z = i + ((z - i) &~ 3);
+
+ bytes = z - i;
+ }
+ else
+ {
+ char buf[50];
+ SFILE sfile;
+ int bpc = 0;
+ int pb = 0;
+
+ done_dot = false;
+
+ if (with_line_numbers || with_source_code)
+ show_line (aux->abfd, section, i);
+
+ if (! prefix_addresses)
+ {
+ char *s;
+
+ sprintf_vma (buf, section->vma + i);
+ for (s = buf + skip_addr_chars; *s == '0'; s++)
+ *s = ' ';
+ if (*s == '\0')
+ *--s = '0';
+ printf ("%s:\t", buf + skip_addr_chars);
+ }
+ else
+ {
+ aux->require_sec = true;
+ objdump_print_address (section->vma + i, info);
+ aux->require_sec = false;
+ putchar (' ');
+ }
+
+ if (insns)
+ {
+ sfile.size = 120;
+ sfile.buffer = xmalloc (sfile.size);
+ sfile.current = sfile.buffer;
+ info->fprintf_func = (fprintf_ftype) objdump_sprintf;
+ info->stream = (FILE *) &sfile;
+ info->bytes_per_line = 0;
+ info->bytes_per_chunk = 0;
+
+ /* FIXME: This is wrong. It tests the number of bytes
+ in the last instruction, not the current one. */
+ if (*relppp < relppend
+ && (**relppp)->address >= i
+ && (**relppp)->address < i + bytes)
+ info->flags = INSN_HAS_RELOC;
+ else
+ info->flags = 0;
+
+ bytes = (*disassemble_fn) (section->vma + i, info);
+ info->fprintf_func = (fprintf_ftype) fprintf;
+ info->stream = stdout;
+ if (info->bytes_per_line != 0)
+ bytes_per_line = info->bytes_per_line;
+ if (bytes < 0)
+ break;
+ }
+ else
+ {
+ long j;
+
+ bytes = bytes_per_line;
+ if (i + bytes > stop)
+ bytes = stop - i;
+
+ for (j = i; j < i + bytes; ++j)
+ {
+ if (isprint (data[j]))
+ buf[j - i] = data[j];
+ else
+ buf[j - i] = '.';
+ }
+ buf[j - i] = '\0';
+ }
+
+ if (prefix_addresses
+ ? show_raw_insn > 0
+ : show_raw_insn >= 0)
+ {
+ long j;
+
+ /* If ! prefix_addresses and ! wide_output, we print
+ bytes_per_line bytes per line. */
+ pb = bytes;
+ if (pb > bytes_per_line && ! prefix_addresses && ! wide_output)
+ pb = bytes_per_line;
+
+ if (info->bytes_per_chunk)
+ bpc = info->bytes_per_chunk;
+ else
+ bpc = 1;
+
+ for (j = i; j < i + pb; j += bpc)
+ {
+ int k;
+ if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
+ {
+ for (k = bpc - 1; k >= 0; k--)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ else
+ {
+ for (k = 0; k < bpc; k++)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ }
+
+ for (; pb < bytes_per_line; pb += bpc)
+ {
+ int k;
+
+ for (k = 0; k < bpc; k++)
+ printf (" ");
+ putchar (' ');
+ }
+
+ /* Separate raw data from instruction by extra space. */
+ if (insns)
+ putchar ('\t');
+ else
+ printf (" ");
+ }
+
+ if (! insns)
+ printf ("%s", buf);
+ else
+ {
+ printf ("%s", sfile.buffer);
+ free (sfile.buffer);
+ }
+
+ if (prefix_addresses
+ ? show_raw_insn > 0
+ : show_raw_insn >= 0)
+ {
+ while (pb < bytes)
+ {
+ long j;
+ char *s;
+
+ putchar ('\n');
+ j = i + pb;
+
+ sprintf_vma (buf, section->vma + j);
+ for (s = buf + skip_addr_chars; *s == '0'; s++)
+ *s = ' ';
+ if (*s == '\0')
+ *--s = '0';
+ printf ("%s:\t", buf + skip_addr_chars);
+
+ pb += bytes_per_line;
+ if (pb > bytes)
+ pb = bytes;
+ for (; j < i + pb; j += bpc)
+ {
+ int k;
+
+ if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
+ {
+ for (k = bpc - 1; k >= 0; k--)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ else
+ {
+ for (k = 0; k < bpc; k++)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ }
+ }
+ }
+
+ if (!wide_output)
+ putchar ('\n');
+ else
+ need_nl = true;
+ }
+
+ if (dump_reloc_info
+ && (section->flags & SEC_RELOC) != 0)
+ {
+ while ((*relppp) < relppend
+ && ((**relppp)->address >= (bfd_vma) i
+ && (**relppp)->address < (bfd_vma) i + bytes))
+ {
+ arelent *q;
+
+ q = **relppp;
+
+ if (wide_output)
+ putchar ('\t');
+ else
+ printf ("\t\t\t");
+
+ objdump_print_value (section->vma + q->address, info, true);
+
+ printf (": %s\t", q->howto->name);
+
+ if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
+ printf ("*unknown*");
+ else
+ {
+ const char *sym_name;
+
+ sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
+ if (sym_name != NULL && *sym_name != '\0')
+ objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);
+ else
+ {
+ asection *sym_sec;
+
+ sym_sec = bfd_get_section (*q->sym_ptr_ptr);
+ sym_name = bfd_get_section_name (aux->abfd, sym_sec);
+ if (sym_name == NULL || *sym_name == '\0')
+ sym_name = "*unknown*";
+ printf ("%s", sym_name);
+ }
+ }
+
+ if (q->addend)
+ {
+ printf ("+0x");
+ objdump_print_value (q->addend, info, true);
+ }
+
+ printf ("\n");
+ need_nl = false;
+ ++(*relppp);
+ }
+ }
+
+ if (need_nl)
+ printf ("\n");
+
+ i += bytes;
+ }
+}
+
+/* Disassemble the contents of an object file. */
+
+static void
+disassemble_data (abfd)
+ bfd *abfd;
+{
+ long i;
+ disassembler_ftype disassemble_fn;
+ struct disassemble_info disasm_info;
+ struct objdump_disasm_info aux;
+ asection *section;
+
+ print_files = NULL;
+ prev_functionname = NULL;
+ prev_line = -1;
+
+ /* We make a copy of syms to sort. We don't want to sort syms
+ because that will screw up the relocs. */
+ sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
+ memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
+
+ sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
+
+ /* Sort the symbols into section and symbol order */
+ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+
+ INIT_DISASSEMBLE_INFO(disasm_info, stdout, fprintf);
+ disasm_info.application_data = (PTR) &aux;
+ aux.abfd = abfd;
+ aux.require_sec = false;
+ disasm_info.print_address_func = objdump_print_address;
+ disasm_info.symbol_at_address_func = objdump_symbol_at_address;
+
+ if (machine != (char *) NULL)
+ {
+ const bfd_arch_info_type *info = bfd_scan_arch (machine);
+ if (info == NULL)
+ {
+ fprintf (stderr, _("%s: Can't use supplied machine %s\n"),
+ program_name,
+ machine);
+ exit (1);
+ }
+ abfd->arch_info = info;
+ }
+
+ if (endian != BFD_ENDIAN_UNKNOWN)
+ {
+ struct bfd_target *xvec;
+
+ xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target));
+ memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
+ xvec->byteorder = endian;
+ abfd->xvec = xvec;
+ }
+
+ disassemble_fn = disassembler (abfd);
+ if (!disassemble_fn)
+ {
+ fprintf (stderr, _("%s: Can't disassemble for architecture %s\n"),
+ program_name,
+ bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
+ return;
+ }
+
+ disasm_info.flavour = bfd_get_flavour (abfd);
+ disasm_info.arch = bfd_get_arch (abfd);
+ disasm_info.mach = bfd_get_mach (abfd);
+ if (bfd_big_endian (abfd))
+ disasm_info.endian = BFD_ENDIAN_BIG;
+ else if (bfd_little_endian (abfd))
+ disasm_info.endian = BFD_ENDIAN_LITTLE;
+ else
+ /* ??? Aborting here seems too drastic. We could default to big or little
+ instead. */
+ disasm_info.endian = BFD_ENDIAN_UNKNOWN;
+
+ for (section = abfd->sections;
+ section != (asection *) NULL;
+ section = section->next)
+ {
+ bfd_byte *data = NULL;
+ bfd_size_type datasize = 0;
+ arelent **relbuf = NULL;
+ arelent **relpp = NULL;
+ arelent **relppend = NULL;
+ long stop;
+ asymbol *sym = NULL;
+ long place = 0;
+
+ if ((section->flags & SEC_LOAD) == 0
+ || (! disassemble_all
+ && only == NULL
+ && (section->flags & SEC_CODE) == 0))
+ continue;
+ if (only != (char *) NULL && strcmp (only, section->name) != 0)
+ continue;
+
+ if (dump_reloc_info
+ && (section->flags & SEC_RELOC) != 0)
+ {
+ long relsize;
+
+ relsize = bfd_get_reloc_upper_bound (abfd, section);
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (relsize > 0)
+ {
+ long relcount;
+
+ relbuf = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
+ if (relcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ /* Sort the relocs by address. */
+ qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
+
+ relpp = relbuf;
+ relppend = relpp + relcount;
+
+ /* Skip over the relocs belonging to addresses below the
+ start address. */
+ if (start_address != (bfd_vma) -1)
+ {
+ while (relpp < relppend
+ && (*relpp)->address < start_address)
+ ++relpp;
+ }
+ }
+ }
+
+ printf (_("Disassembly of section %s:\n"), section->name);
+
+ datasize = bfd_get_section_size_before_reloc (section);
+ if (datasize == 0)
+ continue;
+
+ data = (bfd_byte *) xmalloc ((size_t) datasize);
+
+ bfd_get_section_contents (abfd, section, data, 0, datasize);
+
+ aux.sec = section;
+ disasm_info.buffer = data;
+ disasm_info.buffer_vma = section->vma;
+ disasm_info.buffer_length = datasize;
+ if (start_address == (bfd_vma) -1
+ || start_address < disasm_info.buffer_vma)
+ i = 0;
+ else
+ i = start_address - disasm_info.buffer_vma;
+ if (stop_address == (bfd_vma) -1)
+ stop = datasize;
+ else
+ {
+ if (stop_address < disasm_info.buffer_vma)
+ stop = 0;
+ else
+ stop = stop_address - disasm_info.buffer_vma;
+ if (stop > disasm_info.buffer_length)
+ stop = disasm_info.buffer_length;
+ }
+
+ sym = find_symbol_for_address (abfd, section, section->vma + i,
+ true, &place);
+
+ while (i < stop)
+ {
+ asymbol *nextsym;
+ long nextstop;
+ boolean insns;
+
+ if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + i)
+ {
+ int x;
+
+ for (x = place;
+ (x < sorted_symcount
+ && bfd_asymbol_value (sorted_syms[x]) <= section->vma + i);
+ ++x)
+ continue;
+ disasm_info.symbols = & sorted_syms[place];
+ disasm_info.num_symbols = x - place;
+ }
+ else
+ disasm_info.symbols = NULL;
+
+ if (! prefix_addresses)
+ {
+ printf ("\n");
+ objdump_print_addr_with_sym (abfd, section, sym,
+ section->vma + i,
+ &disasm_info,
+ false);
+ printf (":\n");
+ }
+
+ if (sym != NULL && bfd_asymbol_value (sym) > section->vma + i)
+ nextsym = sym;
+ else if (sym == NULL)
+ nextsym = NULL;
+ else
+ {
+ while (place < sorted_symcount
+ /* ??? Why the test for != section? */
+ && (sorted_syms[place]->section != section
+ || (bfd_asymbol_value (sorted_syms[place])
+ <= bfd_asymbol_value (sym))))
+ ++place;
+ if (place >= sorted_symcount)
+ nextsym = NULL;
+ else
+ nextsym = sorted_syms[place];
+ }
+
+ if (sym != NULL && bfd_asymbol_value (sym) > section->vma + i)
+ {
+ nextstop = bfd_asymbol_value (sym) - section->vma;
+ if (nextstop > stop)
+ nextstop = stop;
+ }
+ else if (nextsym == NULL)
+ nextstop = stop;
+ else
+ {
+ nextstop = bfd_asymbol_value (nextsym) - section->vma;
+ if (nextstop > stop)
+ nextstop = stop;
+ }
+
+ /* If a symbol is explicitly marked as being an object
+ rather than a function, just dump the bytes without
+ disassembling them. */
+ if (disassemble_all
+ || sym == NULL
+ || bfd_asymbol_value (sym) > section->vma + i
+ || ((sym->flags & BSF_OBJECT) == 0
+ && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
+ == NULL)
+ && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
+ == NULL))
+ || (sym->flags & BSF_FUNCTION) != 0)
+ insns = true;
+ else
+ insns = false;
+
+ disassemble_bytes (&disasm_info, disassemble_fn, insns, data, i,
+ nextstop, &relpp, relppend);
+
+ i = nextstop;
+ sym = nextsym;
+ }
+
+ free (data);
+ if (relbuf != NULL)
+ free (relbuf);
+ }
+ free (sorted_syms);
+}
+
+
+/* Define a table of stab values and print-strings. We wish the initializer
+ could be a direct-mapped table, but instead we build one the first
+ time we need it. */
+
+static void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name,
+ char *strsect_name));
+
+/* Dump the stabs sections from an object file that has a section that
+ uses Sun stabs encoding. */
+
+static void
+dump_stabs (abfd)
+ bfd *abfd;
+{
+ dump_section_stabs (abfd, ".stab", ".stabstr");
+ dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr");
+ dump_section_stabs (abfd, ".stab.index", ".stab.indexstr");
+ dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
+}
+
+static bfd_byte *stabs;
+static bfd_size_type stab_size;
+
+static char *strtab;
+static bfd_size_type stabstr_size;
+
+/* Read ABFD's stabs section STABSECT_NAME into `stabs'
+ and string table section STRSECT_NAME into `strtab'.
+ If the section exists and was read, allocate the space and return true.
+ Otherwise return false. */
+
+static boolean
+read_section_stabs (abfd, stabsect_name, strsect_name)
+ bfd *abfd;
+ const char *stabsect_name;
+ const char *strsect_name;
+{
+ asection *stabsect, *stabstrsect;
+
+ stabsect = bfd_get_section_by_name (abfd, stabsect_name);
+ if (0 == stabsect)
+ {
+ printf (_("No %s section present\n\n"), stabsect_name);
+ return false;
+ }
+
+ stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
+ if (0 == stabstrsect)
+ {
+ fprintf (stderr, _("%s: %s has no %s section\n"), program_name,
+ bfd_get_filename (abfd), strsect_name);
+ return false;
+ }
+
+ stab_size = bfd_section_size (abfd, stabsect);
+ stabstr_size = bfd_section_size (abfd, stabstrsect);
+
+ stabs = (bfd_byte *) xmalloc (stab_size);
+ strtab = (char *) xmalloc (stabstr_size);
+
+ if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size))
+ {
+ fprintf (stderr, _("%s: Reading %s section of %s failed: %s\n"),
+ program_name, stabsect_name, bfd_get_filename (abfd),
+ bfd_errmsg (bfd_get_error ()));
+ free (stabs);
+ free (strtab);
+ return false;
+ }
+
+ if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0,
+ stabstr_size))
+ {
+ fprintf (stderr, _("%s: Reading %s section of %s failed: %s\n"),
+ program_name, strsect_name, bfd_get_filename (abfd),
+ bfd_errmsg (bfd_get_error ()));
+ free (stabs);
+ free (strtab);
+ return false;
+ }
+
+ return true;
+}
+
+/* Stabs entries use a 12 byte format:
+ 4 byte string table index
+ 1 byte stab type
+ 1 byte stab other field
+ 2 byte stab desc field
+ 4 byte stab value
+ FIXME: This will have to change for a 64 bit object format. */
+
+#define STRDXOFF (0)
+#define TYPEOFF (4)
+#define OTHEROFF (5)
+#define DESCOFF (6)
+#define VALOFF (8)
+#define STABSIZE (12)
+
+/* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
+ using string table section STRSECT_NAME (in `strtab'). */
+
+static void
+print_section_stabs (abfd, stabsect_name, strsect_name)
+ bfd *abfd;
+ const char *stabsect_name;
+ const char *strsect_name;
+{
+ int i;
+ unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
+ bfd_byte *stabp, *stabs_end;
+
+ stabp = stabs;
+ stabs_end = stabp + stab_size;
+
+ printf (_("Contents of %s section:\n\n"), stabsect_name);
+ printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
+
+ /* Loop through all symbols and print them.
+
+ We start the index at -1 because there is a dummy symbol on
+ the front of stabs-in-{coff,elf} sections that supplies sizes. */
+
+ for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
+ {
+ const char *name;
+ unsigned long strx;
+ unsigned char type, other;
+ unsigned short desc;
+ bfd_vma value;
+
+ strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
+ type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
+ other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
+ desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
+ value = bfd_h_get_32 (abfd, stabp + VALOFF);
+
+ printf ("\n%-6d ", i);
+ /* Either print the stab name, or, if unnamed, print its number
+ again (makes consistent formatting for tools like awk). */
+ name = bfd_get_stab_name (type);
+ if (name != NULL)
+ printf ("%-6s", name);
+ else if (type == N_UNDF)
+ printf ("HdrSym");
+ else
+ printf ("%-6d", type);
+ printf (" %-6d %-6d ", other, desc);
+ printf_vma (value);
+ printf (" %-6lu", strx);
+
+ /* Symbols with type == 0 (N_UNDF) specify the length of the
+ string table associated with this file. We use that info
+ to know how to relocate the *next* file's string table indices. */
+
+ if (type == N_UNDF)
+ {
+ file_string_table_offset = next_file_string_table_offset;
+ next_file_string_table_offset += value;
+ }
+ else
+ {
+ /* Using the (possibly updated) string table offset, print the
+ string (if any) associated with this symbol. */
+
+ if ((strx + file_string_table_offset) < stabstr_size)
+ printf (" %s", &strtab[strx + file_string_table_offset]);
+ else
+ printf (" *");
+ }
+ }
+ printf ("\n\n");
+}
+
+static void
+dump_section_stabs (abfd, stabsect_name, strsect_name)
+ bfd *abfd;
+ char *stabsect_name;
+ char *strsect_name;
+{
+ asection *s;
+
+ /* Check for section names for which stabsect_name is a prefix, to
+ handle .stab0, etc. */
+ for (s = abfd->sections;
+ s != NULL;
+ s = s->next)
+ {
+ int len;
+
+ len = strlen (stabsect_name);
+
+ /* If the prefix matches, and the files section name ends with a
+ nul or a digit, then we match. I.e., we want either an exact
+ match or a section followed by a number. */
+ if (strncmp (stabsect_name, s->name, len) == 0
+ && (s->name[len] == '\000'
+ || isdigit ((unsigned char) s->name[len])))
+ {
+ if (read_section_stabs (abfd, s->name, strsect_name))
+ {
+ print_section_stabs (abfd, s->name, strsect_name);
+ free (stabs);
+ free (strtab);
+ }
+ }
+ }
+}
+
+static void
+dump_bfd_header (abfd)
+ bfd *abfd;
+{
+ char *comma = "";
+
+ printf (_("architecture: %s, "),
+ bfd_printable_arch_mach (bfd_get_arch (abfd),
+ bfd_get_mach (abfd)));
+ printf (_("flags 0x%08x:\n"), abfd->flags);
+
+#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
+ PF (HAS_RELOC, "HAS_RELOC");
+ PF (EXEC_P, "EXEC_P");
+ PF (HAS_LINENO, "HAS_LINENO");
+ PF (HAS_DEBUG, "HAS_DEBUG");
+ PF (HAS_SYMS, "HAS_SYMS");
+ PF (HAS_LOCALS, "HAS_LOCALS");
+ PF (DYNAMIC, "DYNAMIC");
+ PF (WP_TEXT, "WP_TEXT");
+ PF (D_PAGED, "D_PAGED");
+ PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
+ printf (_("\nstart address 0x"));
+ printf_vma (abfd->start_address);
+ printf ("\n");
+}
+
+static void
+dump_bfd_private_header (abfd)
+bfd *abfd;
+{
+ bfd_print_private_bfd_data (abfd, stdout);
+}
+
+static void
+display_bfd (abfd)
+ bfd *abfd;
+{
+ char **matching;
+
+ if (!bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ return;
+ }
+
+ /* If we are adjusting section VMA's, change them all now. Changing
+ the BFD information is a hack. However, we must do it, or
+ bfd_find_nearest_line will not do the right thing. */
+ if (adjust_section_vma != 0)
+ {
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ s->vma += adjust_section_vma;
+ s->lma += adjust_section_vma;
+ }
+ }
+
+ printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd),
+ abfd->xvec->name);
+ if (dump_ar_hdrs)
+ print_arelt_descr (stdout, abfd, true);
+ if (dump_file_header)
+ dump_bfd_header (abfd);
+ if (dump_private_headers)
+ dump_bfd_private_header (abfd);
+ putchar ('\n');
+ if (dump_section_headers)
+ dump_headers (abfd);
+ if (dump_symtab || dump_reloc_info || disassemble || dump_debugging)
+ {
+ syms = slurp_symtab (abfd);
+ }
+ if (dump_dynamic_symtab || dump_dynamic_reloc_info)
+ {
+ dynsyms = slurp_dynamic_symtab (abfd);
+ }
+ if (dump_symtab)
+ dump_symbols (abfd, false);
+ if (dump_dynamic_symtab)
+ dump_symbols (abfd, true);
+ if (dump_stab_section_info)
+ dump_stabs (abfd);
+ if (dump_reloc_info && ! disassemble)
+ dump_relocs (abfd);
+ if (dump_dynamic_reloc_info)
+ dump_dynamic_relocs (abfd);
+ if (dump_section_contents)
+ dump_data (abfd);
+ if (disassemble)
+ disassemble_data (abfd);
+ if (dump_debugging)
+ {
+ PTR dhandle;
+
+ dhandle = read_debugging_info (abfd, syms, symcount);
+ if (dhandle != NULL)
+ {
+ if (! print_debugging_info (stdout, dhandle))
+ fprintf (stderr, _("%s: printing debugging information failed\n"),
+ bfd_get_filename (abfd));
+ }
+ }
+ if (syms)
+ {
+ free (syms);
+ syms = NULL;
+ }
+ if (dynsyms)
+ {
+ free (dynsyms);
+ dynsyms = NULL;
+ }
+}
+
+static void
+display_file (filename, target)
+ char *filename;
+ char *target;
+{
+ bfd *file, *arfile = (bfd *) NULL;
+
+ file = bfd_openr (filename, target);
+ if (file == NULL)
+ {
+ bfd_nonfatal (filename);
+ return;
+ }
+
+ if (bfd_check_format (file, bfd_archive) == true)
+ {
+ bfd *last_arfile = NULL;
+
+ printf (_("In archive %s:\n"), bfd_get_filename (file));
+ for (;;)
+ {
+ bfd_set_error (bfd_error_no_error);
+
+ arfile = bfd_openr_next_archived_file (file, arfile);
+ if (arfile == NULL)
+ {
+ if (bfd_get_error () != bfd_error_no_more_archived_files)
+ {
+ bfd_nonfatal (bfd_get_filename (file));
+ }
+ break;
+ }
+
+ display_bfd (arfile);
+
+ if (last_arfile != NULL)
+ bfd_close (last_arfile);
+ last_arfile = arfile;
+ }
+
+ if (last_arfile != NULL)
+ bfd_close (last_arfile);
+ }
+ else
+ display_bfd (file);
+
+ bfd_close (file);
+}
+
+/* Actually display the various requested regions */
+
+static void
+dump_data (abfd)
+ bfd *abfd;
+{
+ asection *section;
+ bfd_byte *data = 0;
+ bfd_size_type datasize = 0;
+ bfd_size_type i;
+ bfd_size_type start, stop;
+
+ for (section = abfd->sections; section != NULL; section =
+ section->next)
+ {
+ int onaline = 16;
+
+ if (only == (char *) NULL ||
+ strcmp (only, section->name) == 0)
+ {
+ if (section->flags & SEC_HAS_CONTENTS)
+ {
+ printf (_("Contents of section %s:\n"), section->name);
+
+ if (bfd_section_size (abfd, section) == 0)
+ continue;
+ data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
+ datasize = bfd_section_size (abfd, section);
+
+
+ bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
+
+ if (start_address == (bfd_vma) -1
+ || start_address < section->vma)
+ start = 0;
+ else
+ start = start_address - section->vma;
+ if (stop_address == (bfd_vma) -1)
+ stop = bfd_section_size (abfd, section);
+ else
+ {
+ if (stop_address < section->vma)
+ stop = 0;
+ else
+ stop = stop_address - section->vma;
+ if (stop > bfd_section_size (abfd, section))
+ stop = bfd_section_size (abfd, section);
+ }
+ for (i = start; i < stop; i += onaline)
+ {
+ bfd_size_type j;
+
+ printf (" %04lx ", (unsigned long int) (i + section->vma));
+ for (j = i; j < i + onaline; j++)
+ {
+ if (j < stop)
+ printf ("%02x", (unsigned) (data[j]));
+ else
+ printf (" ");
+ if ((j & 3) == 3)
+ printf (" ");
+ }
+
+ printf (" ");
+ for (j = i; j < i + onaline; j++)
+ {
+ if (j >= stop)
+ printf (" ");
+ else
+ printf ("%c", isprint (data[j]) ? data[j] : '.');
+ }
+ putchar ('\n');
+ }
+ free (data);
+ }
+ }
+ }
+}
+
+/* Should perhaps share code and display with nm? */
+static void
+dump_symbols (abfd, dynamic)
+ bfd *abfd;
+ boolean dynamic;
+{
+ asymbol **current;
+ long max;
+ long count;
+
+ if (dynamic)
+ {
+ current = dynsyms;
+ max = dynsymcount;
+ if (max == 0)
+ return;
+ printf ("DYNAMIC SYMBOL TABLE:\n");
+ }
+ else
+ {
+ current = syms;
+ max = symcount;
+ if (max == 0)
+ return;
+ printf ("SYMBOL TABLE:\n");
+ }
+
+ for (count = 0; count < max; count++)
+ {
+ if (*current)
+ {
+ bfd *cur_bfd = bfd_asymbol_bfd (*current);
+
+ if (cur_bfd != NULL)
+ {
+ const char *name;
+ char *alloc;
+
+ name = bfd_asymbol_name (*current);
+ alloc = NULL;
+ if (do_demangle && name != NULL && *name != '\0')
+ {
+ const char *n;
+
+ /* If we want to demangle the name, we demangle it
+ here, and temporarily clobber it while calling
+ bfd_print_symbol. FIXME: This is a gross hack. */
+
+ n = name;
+ if (bfd_get_symbol_leading_char (cur_bfd) == *n)
+ ++n;
+ alloc = cplus_demangle (n, DMGL_ANSI | DMGL_PARAMS);
+ if (alloc != NULL)
+ (*current)->name = alloc;
+ else
+ (*current)->name = n;
+ }
+
+ bfd_print_symbol (cur_bfd, stdout, *current,
+ bfd_print_symbol_all);
+
+ (*current)->name = name;
+ if (alloc != NULL)
+ free (alloc);
+
+ printf ("\n");
+ }
+ }
+ current++;
+ }
+ printf ("\n");
+ printf ("\n");
+}
+
+static void
+dump_relocs (abfd)
+ bfd *abfd;
+{
+ arelent **relpp;
+ long relcount;
+ asection *a;
+
+ for (a = abfd->sections; a != (asection *) NULL; a = a->next)
+ {
+ long relsize;
+
+ if (bfd_is_abs_section (a))
+ continue;
+ if (bfd_is_und_section (a))
+ continue;
+ if (bfd_is_com_section (a))
+ continue;
+
+ if (only)
+ {
+ if (strcmp (only, a->name))
+ continue;
+ }
+ else if ((a->flags & SEC_RELOC) == 0)
+ continue;
+
+ relsize = bfd_get_reloc_upper_bound (abfd, a);
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ printf ("RELOCATION RECORDS FOR [%s]:", a->name);
+
+ if (relsize == 0)
+ {
+ printf (" (none)\n\n");
+ }
+ else
+ {
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
+ if (relcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ else if (relcount == 0)
+ {
+ printf (" (none)\n\n");
+ }
+ else
+ {
+ printf ("\n");
+ dump_reloc_set (abfd, a, relpp, relcount);
+ printf ("\n\n");
+ }
+ free (relpp);
+ }
+ }
+}
+
+static void
+dump_dynamic_relocs (abfd)
+ bfd *abfd;
+{
+ long relsize;
+ arelent **relpp;
+ long relcount;
+
+ relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
+ if (relsize < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ printf ("DYNAMIC RELOCATION RECORDS");
+
+ if (relsize == 0)
+ {
+ printf (" (none)\n\n");
+ }
+ else
+ {
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
+ if (relcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+ else if (relcount == 0)
+ {
+ printf (" (none)\n\n");
+ }
+ else
+ {
+ printf ("\n");
+ dump_reloc_set (abfd, (asection *) NULL, relpp, relcount);
+ printf ("\n\n");
+ }
+ free (relpp);
+ }
+}
+
+static void
+dump_reloc_set (abfd, sec, relpp, relcount)
+ bfd *abfd;
+ asection *sec;
+ arelent **relpp;
+ long relcount;
+{
+ arelent **p;
+ char *last_filename, *last_functionname;
+ unsigned int last_line;
+
+ /* Get column headers lined up reasonably. */
+ {
+ static int width;
+ if (width == 0)
+ {
+ char buf[30];
+ sprintf_vma (buf, (bfd_vma) -1);
+ width = strlen (buf) - 7;
+ }
+ printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
+ }
+
+ last_filename = NULL;
+ last_functionname = NULL;
+ last_line = 0;
+
+ for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--)
+ {
+ arelent *q = *p;
+ const char *filename, *functionname;
+ unsigned int line;
+ const char *sym_name;
+ const char *section_name;
+
+ if (start_address != (bfd_vma) -1
+ && q->address < start_address)
+ continue;
+ if (stop_address != (bfd_vma) -1
+ && q->address > stop_address)
+ continue;
+
+ if (with_line_numbers
+ && sec != NULL
+ && bfd_find_nearest_line (abfd, sec, syms, q->address,
+ &filename, &functionname, &line))
+ {
+ if (functionname != NULL
+ && (last_functionname == NULL
+ || strcmp (functionname, last_functionname) != 0))
+ {
+ printf ("%s():\n", functionname);
+ if (last_functionname != NULL)
+ free (last_functionname);
+ last_functionname = xstrdup (functionname);
+ }
+ if (line > 0
+ && (line != last_line
+ || (filename != NULL
+ && last_filename != NULL
+ && strcmp (filename, last_filename) != 0)))
+ {
+ printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
+ last_line = line;
+ if (last_filename != NULL)
+ free (last_filename);
+ if (filename == NULL)
+ last_filename = NULL;
+ else
+ last_filename = xstrdup (filename);
+ }
+ }
+
+ if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
+ {
+ sym_name = (*(q->sym_ptr_ptr))->name;
+ section_name = (*(q->sym_ptr_ptr))->section->name;
+ }
+ else
+ {
+ sym_name = NULL;
+ section_name = NULL;
+ }
+ if (sym_name)
+ {
+ printf_vma (q->address);
+ printf (" %-16s ", q->howto->name);
+ objdump_print_symname (abfd, (struct disassemble_info *) NULL,
+ *q->sym_ptr_ptr);
+ }
+ else
+ {
+ if (section_name == (CONST char *) NULL)
+ section_name = "*unknown*";
+ printf_vma (q->address);
+ printf (" %-16s [%s]",
+ q->howto->name,
+ section_name);
+ }
+ if (q->addend)
+ {
+ printf ("+0x");
+ printf_vma (q->addend);
+ }
+ printf ("\n");
+ }
+}
+
+/* The length of the longest architecture name + 1. */
+#define LONGEST_ARCH sizeof("rs6000:6000")
+
+static const char *
+endian_string (endian)
+ enum bfd_endian endian;
+{
+ if (endian == BFD_ENDIAN_BIG)
+ return "big endian";
+ else if (endian == BFD_ENDIAN_LITTLE)
+ return "little endian";
+ else
+ return "endianness unknown";
+}
+
+/* List the targets that BFD is configured to support, each followed
+ by its endianness and the architectures it supports. */
+
+static void
+display_target_list ()
+{
+ extern bfd_target *bfd_target_vector[];
+ char *dummy_name;
+ int t;
+
+ dummy_name = choose_temp_base ();
+ for (t = 0; bfd_target_vector[t]; t++)
+ {
+ bfd_target *p = bfd_target_vector[t];
+ bfd *abfd = bfd_openw (dummy_name, p->name);
+ int a;
+
+ printf ("%s\n (header %s, data %s)\n", p->name,
+ endian_string (p->header_byteorder),
+ endian_string (p->byteorder));
+
+ if (abfd == NULL)
+ {
+ bfd_nonfatal (dummy_name);
+ continue;
+ }
+
+ if (! bfd_set_format (abfd, bfd_object))
+ {
+ if (bfd_get_error () != bfd_error_invalid_operation)
+ bfd_nonfatal (p->name);
+ continue;
+ }
+
+ for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
+ if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
+ printf (" %s\n",
+ bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
+ }
+ unlink (dummy_name);
+ free (dummy_name);
+}
+
+/* Print a table showing which architectures are supported for entries
+ FIRST through LAST-1 of bfd_target_vector (targets across,
+ architectures down). */
+
+static void
+display_info_table (first, last)
+ int first;
+ int last;
+{
+ extern bfd_target *bfd_target_vector[];
+ int t, a;
+ char *dummy_name;
+
+ /* Print heading of target names. */
+ printf ("\n%*s", (int) LONGEST_ARCH, " ");
+ for (t = first; t < last && bfd_target_vector[t]; t++)
+ printf ("%s ", bfd_target_vector[t]->name);
+ putchar ('\n');
+
+ dummy_name = choose_temp_base ();
+ for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
+ if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
+ {
+ printf ("%*s ", (int) LONGEST_ARCH - 1,
+ bfd_printable_arch_mach (a, 0));
+ for (t = first; t < last && bfd_target_vector[t]; t++)
+ {
+ bfd_target *p = bfd_target_vector[t];
+ boolean ok = true;
+ bfd *abfd = bfd_openw (dummy_name, p->name);
+
+ if (abfd == NULL)
+ {
+ bfd_nonfatal (p->name);
+ ok = false;
+ }
+
+ if (ok)
+ {
+ if (! bfd_set_format (abfd, bfd_object))
+ {
+ if (bfd_get_error () != bfd_error_invalid_operation)
+ bfd_nonfatal (p->name);
+ ok = false;
+ }
+ }
+
+ if (ok)
+ {
+ if (! bfd_set_arch_mach (abfd, a, 0))
+ ok = false;
+ }
+
+ if (ok)
+ printf ("%s ", p->name);
+ else
+ {
+ int l = strlen (p->name);
+ while (l--)
+ putchar ('-');
+ putchar (' ');
+ }
+ }
+ putchar ('\n');
+ }
+ unlink (dummy_name);
+ free (dummy_name);
+}
+
+/* Print tables of all the target-architecture combinations that
+ BFD has been configured to support. */
+
+static void
+display_target_tables ()
+{
+ int t, columns;
+ extern bfd_target *bfd_target_vector[];
+ char *colum;
+
+ columns = 0;
+ colum = getenv ("COLUMNS");
+ if (colum != NULL)
+ columns = atoi (colum);
+ if (columns == 0)
+ columns = 80;
+
+ t = 0;
+ while (bfd_target_vector[t] != NULL)
+ {
+ int oldt = t, wid;
+
+ wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
+ ++t;
+ while (wid < columns && bfd_target_vector[t] != NULL)
+ {
+ int newwid;
+
+ newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
+ if (newwid >= columns)
+ break;
+ wid = newwid;
+ ++t;
+ }
+ display_info_table (oldt, t);
+ }
+}
+
+static void
+display_info ()
+{
+ printf (_("BFD header file version %s\n"), BFD_VERSION);
+ display_target_list ();
+ display_target_tables ();
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ char *target = default_target;
+ boolean seenflag = false;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = *argv;
+ xmalloc_set_program_name (program_name);
+
+ START_PROGRESS (program_name, 0);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ while ((c = getopt_long (argc, argv, "pib:m:VCdDlfahrRtTxsSj:wE:",
+ long_options, (int *) 0))
+ != EOF)
+ {
+ if (c != 'l' && c != OPTION_START_ADDRESS && c != OPTION_STOP_ADDRESS)
+ seenflag = true;
+ switch (c)
+ {
+ case 0:
+ break; /* we've been given a long option */
+ case 'm':
+ machine = optarg;
+ break;
+ case 'j':
+ only = optarg;
+ break;
+ case 'l':
+ with_line_numbers = 1;
+ break;
+ case 'b':
+ target = optarg;
+ break;
+ case 'f':
+ dump_file_header = true;
+ break;
+ case 'i':
+ formats_info = true;
+ break;
+ case 'p':
+ dump_private_headers = 1;
+ break;
+ case 'x':
+ dump_private_headers = 1;
+ dump_symtab = 1;
+ dump_reloc_info = 1;
+ dump_file_header = true;
+ dump_ar_hdrs = 1;
+ dump_section_headers = 1;
+ break;
+ case 't':
+ dump_symtab = 1;
+ break;
+ case 'T':
+ dump_dynamic_symtab = 1;
+ break;
+ case 'C':
+ do_demangle = 1;
+ break;
+ case 'd':
+ disassemble = true;
+ break;
+ case 'D':
+ disassemble = disassemble_all = true;
+ break;
+ case 'S':
+ disassemble = true;
+ with_source_code = true;
+ break;
+ case 's':
+ dump_section_contents = 1;
+ break;
+ case 'r':
+ dump_reloc_info = 1;
+ break;
+ case 'R':
+ dump_dynamic_reloc_info = 1;
+ break;
+ case 'a':
+ dump_ar_hdrs = 1;
+ break;
+ case 'h':
+ dump_section_headers = 1;
+ break;
+ case 'H':
+ usage (stdout, 0);
+ case 'V':
+ show_version = 1;
+ break;
+ case 'w':
+ wide_output = 1;
+ break;
+ case OPTION_ADJUST_VMA:
+ adjust_section_vma = parse_vma (optarg, "--adjust-vma");
+ break;
+ case OPTION_START_ADDRESS:
+ start_address = parse_vma (optarg, "--start-address");
+ break;
+ case OPTION_STOP_ADDRESS:
+ stop_address = parse_vma (optarg, "--stop-address");
+ break;
+ case 'E':
+ if (strcmp (optarg, "B") == 0)
+ endian = BFD_ENDIAN_BIG;
+ else if (strcmp (optarg, "L") == 0)
+ endian = BFD_ENDIAN_LITTLE;
+ else
+ {
+ fprintf (stderr, _("%s: unrecognized -E option\n"), program_name);
+ usage (stderr, 1);
+ }
+ break;
+ case OPTION_ENDIAN:
+ if (strncmp (optarg, "big", strlen (optarg)) == 0)
+ endian = BFD_ENDIAN_BIG;
+ else if (strncmp (optarg, "little", strlen (optarg)) == 0)
+ endian = BFD_ENDIAN_LITTLE;
+ else
+ {
+ fprintf (stderr, _("%s: unrecognized --endian type `%s'\n"),
+ program_name, optarg);
+ usage (stderr, 1);
+ }
+ break;
+ default:
+ usage (stderr, 1);
+ }
+ }
+
+ if (show_version)
+ print_version ("objdump");
+
+ if (seenflag == false)
+ usage (stderr, 1);
+
+ if (formats_info)
+ {
+ display_info ();
+ }
+ else
+ {
+ if (optind == argc)
+ display_file ("a.out", target);
+ else
+ for (; optind < argc;)
+ display_file (argv[optind++], target);
+ }
+
+ END_PROGRESS (program_name);
+
+ return 0;
+}
diff --git a/binutils/po/Make-in b/binutils/po/Make-in
new file mode 100644
index 00000000000..0552db1feef
--- /dev/null
+++ b/binutils/po/Make-in
@@ -0,0 +1,251 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/binutils/po/POTFILES.in b/binutils/po/POTFILES.in
new file mode 100644
index 00000000000..47f38608ca9
--- /dev/null
+++ b/binutils/po/POTFILES.in
@@ -0,0 +1,52 @@
+readelf.c
+addr2line.c
+ar.c
+arsup.c
+arsup.h
+bucomm.c
+bucomm.h
+budbg.h
+coffdump.c
+coffgrok.c
+coffgrok.h
+debug.c
+debug.h
+dlltool.c
+dlltool.h
+dllwrap.c
+dyn-string.c
+dyn-string.h
+filemode.c
+ieee.c
+is-ranlib.c
+is-strip.c
+maybe-ranlib.c
+maybe-strip.c
+nlmconv.c
+nlmconv.h
+nm.c
+not-ranlib.c
+not-strip.c
+objcopy.c
+objdump.c
+prdbg.c
+rdcoff.c
+rddbg.c
+rename.c
+resbin.c
+rescoff.c
+resrc.c
+resres.c
+size.c
+srconv.c
+stabs.c
+strings.c
+sysdump.c
+version.c
+windres.c
+windres.h
+winduni.c
+winduni.h
+wrstabs.c
+testsuite/binutils-all/readelf.h
+testsuite/binutils-all/testprog.c
diff --git a/binutils/po/binutils.pot b/binutils/po/binutils.pot
new file mode 100644
index 00000000000..beeb383aebd
--- /dev/null
+++ b/binutils/po/binutils.pot
@@ -0,0 +1,3443 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1999-04-26 10:11-0600\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: addr2line.c:76
+#, c-format
+msgid ""
+"Usage: %s [-CfsHV] [-b bfdname] [--target=bfdname]\n"
+" [-e executable] [--exe=executable] [--demangle]\n"
+" [--basenames] [--functions] [addr addr ...]\n"
+msgstr ""
+
+#: addr2line.c:83 ar.c:255 nlmconv.c:1141 nm.c:304 objcopy.c:318 objcopy.c:337
+#: objdump.c:236 readelf.c:1133 size.c:89 strings.c:512 windres.c:723
+msgid "Report bugs to bug-gnu-utils@gnu.org\n"
+msgstr ""
+
+#: addr2line.c:243
+#, c-format
+msgid "%s: can not get addresses from archive"
+msgstr ""
+
+#: ar.c:207
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr ""
+
+#: ar.c:224
+#, c-format
+msgid ""
+"Usage: %s [-]{dmpqrstx}[abcilosSuvV] [member-name] archive-file file...\n"
+msgstr ""
+
+#: ar.c:226
+#, c-format
+msgid " %s -M [<mri-script]\n"
+msgstr ""
+
+#: ar.c:227
+msgid " commands:\n"
+msgstr ""
+
+#: ar.c:228
+msgid " d - delete file(s) from the archive\n"
+msgstr ""
+
+#: ar.c:229
+msgid " m[ab] - move file(s) in the archive\n"
+msgstr ""
+
+#: ar.c:230
+msgid " p - print file(s) found in the archive\n"
+msgstr ""
+
+#: ar.c:231
+msgid " q[f] - quick append file(s) to the archive\n"
+msgstr ""
+
+#: ar.c:232
+msgid ""
+" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"
+msgstr ""
+
+#: ar.c:233
+msgid " t - display contents of archive\n"
+msgstr ""
+
+#: ar.c:234
+msgid " x[o] - extract file(s) from the archive\n"
+msgstr ""
+
+#: ar.c:235
+msgid " command specific modifiers:\n"
+msgstr ""
+
+#: ar.c:236
+msgid " [a] - put file(s) after [member-name]\n"
+msgstr ""
+
+#: ar.c:237
+msgid " [b] - put file(s) before [member-name] (same as [i])\n"
+msgstr ""
+
+#: ar.c:238
+msgid " [f] - truncate inserted file names\n"
+msgstr ""
+
+#: ar.c:239
+msgid " [o] - preserve original dates\n"
+msgstr ""
+
+#: ar.c:240
+msgid ""
+" [u] - only replace files that are newer than current archive "
+"contents\n"
+msgstr ""
+
+#: ar.c:241
+msgid " generic modifiers:\n"
+msgstr ""
+
+#: ar.c:242
+msgid " [c] - do not warn if the library had to be created\n"
+msgstr ""
+
+#: ar.c:243
+msgid " [s] - create an archive index (cf. ranlib)\n"
+msgstr ""
+
+#: ar.c:244
+msgid " [S] - do not build a symbol table\n"
+msgstr ""
+
+#: ar.c:245
+msgid " [v] - be verbose\n"
+msgstr ""
+
+#: ar.c:246
+msgid " [V] - display the version number\n"
+msgstr ""
+
+#: ar.c:250
+#, c-format
+msgid "Usage: %s [-vV] archive\n"
+msgstr ""
+
+#: ar.c:431
+msgid "two different operation options specified"
+msgstr ""
+
+#: ar.c:500
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr ""
+
+#: ar.c:532
+msgid "no operation specified"
+msgstr ""
+
+#: ar.c:535
+msgid "`u' is only meaningful with the `r' option."
+msgstr ""
+
+#: ar.c:615
+#, c-format
+msgid "%s: internal error -- this option not implemented\n"
+msgstr ""
+
+#: ar.c:730 ar.c:782 ar.c:1212
+#, c-format
+msgid "internal stat error on %s"
+msgstr ""
+
+#: ar.c:734
+#, c-format
+msgid ""
+"\n"
+"<member %s>\n"
+"\n"
+msgstr ""
+
+#: ar.c:751 ar.c:819
+#, c-format
+msgid "%s is not a valid archive"
+msgstr ""
+
+#: ar.c:787
+#, c-format
+msgid "stat returns negative size for %s"
+msgstr ""
+
+#: ar.c:908
+#, c-format
+msgid "%s is not an archive"
+msgstr ""
+
+#: ar.c:915
+#, c-format
+msgid "%s: creating %s\n"
+msgstr ""
+
+#: ar.c:1110
+#, c-format
+msgid "No member named `%s'\n"
+msgstr ""
+
+#: ar.c:1162
+#, c-format
+msgid "%s: no entry %s in archive %s!\n"
+msgstr ""
+
+#: ar.c:1322
+#, c-format
+msgid "%s: no archive map to update"
+msgstr ""
+
+#: arsup.c:86
+#, c-format
+msgid "No entry %s in archive.\n"
+msgstr ""
+
+#: arsup.c:118
+#, c-format
+msgid "Can't open file %s\n"
+msgstr ""
+
+#: arsup.c:166
+#, c-format
+msgid "%s: Can't open output archive %s\n"
+msgstr ""
+
+#: arsup.c:178
+#, c-format
+msgid "%s: Can't open input archive %s\n"
+msgstr ""
+
+#: arsup.c:184
+#, c-format
+msgid "%s: file %s is not an archive\n"
+msgstr ""
+
+#: arsup.c:225
+#, c-format
+msgid "%s: no output archive specified yet\n"
+msgstr ""
+
+#: arsup.c:245 arsup.c:280 arsup.c:316 arsup.c:336 arsup.c:394
+#, c-format
+msgid "%s: no open output archive\n"
+msgstr ""
+
+#: arsup.c:253 arsup.c:354 arsup.c:374
+#, c-format
+msgid "%s: can't open file %s\n"
+msgstr ""
+
+#: arsup.c:301 arsup.c:370 arsup.c:449
+#, c-format
+msgid "%s: can't find module file %s\n"
+msgstr ""
+
+#: arsup.c:401
+#, c-format
+msgid "Current open archive is %s\n"
+msgstr ""
+
+#: arsup.c:428
+#, c-format
+msgid "%s: no open archive\n"
+msgstr ""
+
+#: bucomm.c:139
+#, c-format
+msgid "can't set BFD default target to `%s': %s"
+msgstr ""
+
+#: bucomm.c:151
+#, c-format
+msgid "%s: Matching formats:"
+msgstr ""
+
+#: bucomm.c:168
+msgid "Supported targets:"
+msgstr ""
+
+#: bucomm.c:170
+#, c-format
+msgid "%s: supported targets:"
+msgstr ""
+
+#: bucomm.c:263
+#, c-format
+msgid "%s: bad number: %s"
+msgstr ""
+
+#: coffdump.c:94
+#, c-format
+msgid "#lines %d "
+msgstr ""
+
+#: coffdump.c:456 sysdump.c:719
+#, c-format
+msgid "%s: Print a human readable interpretation of a SYSROFF object file\n"
+msgstr ""
+
+#: coffdump.c:498 srconv.c:1940 sysdump.c:755
+#, c-format
+msgid "GNU %s version %s\n"
+msgstr ""
+
+#: coffdump.c:516 srconv.c:1977 sysdump.c:775
+#, c-format
+msgid "%s: no input file specified\n"
+msgstr ""
+
+#: debug.c:653
+msgid "debug_add_to_current_namespace: no current file"
+msgstr ""
+
+#: debug.c:736
+msgid "debug_start_source: no debug_set_filename call"
+msgstr ""
+
+#: debug.c:795
+msgid "debug_record_function: no debug_set_filename call"
+msgstr ""
+
+#: debug.c:851
+msgid "debug_record_parameter: no current function"
+msgstr ""
+
+#: debug.c:885
+msgid "debug_end_function: no current function"
+msgstr ""
+
+#: debug.c:891
+msgid "debug_end_function: some blocks were not closed"
+msgstr ""
+
+#: debug.c:921
+msgid "debug_start_block: no current block"
+msgstr ""
+
+#: debug.c:959
+msgid "debug_end_block: no current block"
+msgstr ""
+
+#: debug.c:966
+msgid "debug_end_block: attempt to close top level block"
+msgstr ""
+
+#: debug.c:992
+msgid "debug_record_line: no current unit"
+msgstr ""
+
+#. FIXME
+#: debug.c:1046
+msgid "debug_start_common_block: not implemented"
+msgstr ""
+
+#. FIXME
+#: debug.c:1058
+msgid "debug_end_common_block: not implemented"
+msgstr ""
+
+#. FIXME.
+#: debug.c:1152
+msgid "debug_record_label not implemented"
+msgstr ""
+
+#: debug.c:1178
+msgid "debug_record_variable: no current file"
+msgstr ""
+
+#: debug.c:1194
+msgid "debug_record_variable: no current block"
+msgstr ""
+
+#: debug.c:1764
+msgid "debug_make_undefined_type: unsupported kind"
+msgstr ""
+
+#: debug.c:1970
+msgid "debug_name_type: no current file"
+msgstr ""
+
+#: debug.c:2018
+msgid "debug_tag_type: no current file"
+msgstr ""
+
+#: debug.c:2026
+msgid "debug_tag_type: extra tag attempted"
+msgstr ""
+
+#: debug.c:2066
+#, c-format
+msgid "Warning: changing type size from %d to %d\n"
+msgstr ""
+
+#: debug.c:2090
+msgid "debug_find_named_type: no current compilation unit"
+msgstr ""
+
+#: debug.c:2197
+#, c-format
+msgid "debug_get_real_type: circular debug information for %s\n"
+msgstr ""
+
+#: debug.c:2663
+msgid "debug_write_type: illegal type encountered"
+msgstr ""
+
+#: dlltool.c:627 dlltool.c:646 dlltool.c:666
+#, c-format
+msgid "Internal error: Unknown machine type: %d\n"
+msgstr ""
+
+#: dlltool.c:700
+#, c-format
+msgid "Can't open def file: %s"
+msgstr ""
+
+#: dlltool.c:705
+#, c-format
+msgid "Processing def file: %s"
+msgstr ""
+
+#: dlltool.c:709
+msgid "Processed def file"
+msgstr ""
+
+#: dlltool.c:734
+#, c-format
+msgid "Syntax error in def file %s:%d\n"
+msgstr ""
+
+#: dlltool.c:767
+#, c-format
+msgid "NAME: %s base: %x"
+msgstr ""
+
+#: dlltool.c:770
+msgid "Can't have LIBRARY and NAME\n"
+msgstr ""
+
+#: dlltool.c:786
+#, c-format
+msgid "LIBRARY: %s base: %x"
+msgstr ""
+
+#: dlltool.c:789
+#, c-format
+msgid "%s: Can't have LIBRARY and NAME\n"
+msgstr ""
+
+#: dlltool.c:1044
+#, c-format
+msgid "wait: %s"
+msgstr ""
+
+#: dlltool.c:1049
+#, c-format
+msgid "subprocess got fatal signal %d"
+msgstr ""
+
+#: dlltool.c:1055
+#, c-format
+msgid "%s exited with status %d\n"
+msgstr ""
+
+#: dlltool.c:1087
+#, c-format
+msgid "Sucking in info from .drective section in %s\n"
+msgstr ""
+
+#: dlltool.c:1197
+#, c-format
+msgid "Excluding symbol: %s\n"
+msgstr ""
+
+#: dlltool.c:1292 dlltool.c:1303 nm.c:902 nm.c:913 objdump.c:379 objdump.c:396
+#, c-format
+msgid "%s: no symbols\n"
+msgstr ""
+
+#. FIXME: we ought to read in and block out the base relocations
+#: dlltool.c:1330
+#, c-format
+msgid "%s: Done reading %s\n"
+msgstr ""
+
+#: dlltool.c:1341
+#, c-format
+msgid "Unable to open object file: %s"
+msgstr ""
+
+#: dlltool.c:1344
+#, c-format
+msgid "Scanning object file %s"
+msgstr ""
+
+#: dlltool.c:1434
+msgid "Adding exports to output file"
+msgstr ""
+
+#: dlltool.c:1479
+msgid "Added exports to output file"
+msgstr ""
+
+#: dlltool.c:1587
+#, c-format
+msgid "Generating export file: %s\n"
+msgstr ""
+
+#: dlltool.c:1592
+#, c-format
+msgid "Unable to open temporary assembler file: %s"
+msgstr ""
+
+#: dlltool.c:1595
+#, c-format
+msgid "Opened temporary file: %s"
+msgstr ""
+
+#: dlltool.c:1828
+msgid "Generated exports file"
+msgstr ""
+
+#: dlltool.c:2081
+#, c-format
+msgid "bfd_open failed open stub file: %s"
+msgstr ""
+
+#: dlltool.c:2084
+#, c-format
+msgid "Creating stub file: %s"
+msgstr ""
+
+#: dlltool.c:2593
+#, c-format
+msgid "Can't open .lib file: %s"
+msgstr ""
+
+#: dlltool.c:2596
+#, c-format
+msgid "Creating library file: %s\n"
+msgstr ""
+
+#: dlltool.c:2652
+#, c-format
+msgid "cannot delete %s: %s\n"
+msgstr ""
+
+#: dlltool.c:2656
+msgid "Created lib file"
+msgstr ""
+
+#: dlltool.c:2757
+#, c-format
+msgid "Warning, ignoring duplicate EXPORT %s %d,%d\n"
+msgstr ""
+
+#: dlltool.c:2763
+#, c-format
+msgid "Error, duplicate EXPORT with oridinals: %s"
+msgstr ""
+
+#: dlltool.c:2890
+msgid "Processing definitions"
+msgstr ""
+
+#: dlltool.c:2928
+msgid "Processed definitions"
+msgstr ""
+
+#. xgetext:c-format
+#: dlltool.c:2939
+#, c-format
+msgid "Usage %s <options> <object-files>\n"
+msgstr ""
+
+#. xgetext:c-format
+#: dlltool.c:2941
+#, c-format
+msgid ""
+" -m --machine <machine> Create {arm, i386, ppc, thumb} DLL. [default: "
+"%s]\n"
+msgstr ""
+
+#: dlltool.c:2942
+msgid " -e --output-exp <outname> Generate an export file.\n"
+msgstr ""
+
+#: dlltool.c:2943
+msgid " -l --output-lib <outname> Generate an interface library.\n"
+msgstr ""
+
+#: dlltool.c:2944
+msgid " -a --add-indirect Add dll indirects to export file.\n"
+msgstr ""
+
+#: dlltool.c:2945
+msgid ""
+" -D --dllname <name> Name of input dll to put into interface lib.\n"
+msgstr ""
+
+#: dlltool.c:2946
+msgid " -d --input-def <deffile> Name of .def file to be read in.\n"
+msgstr ""
+
+#: dlltool.c:2947
+msgid " -z --output-def <deffile> Name of .def file to be created.\n"
+msgstr ""
+
+#: dlltool.c:2948
+msgid " --export-all-symbols Export all symbols to .def\n"
+msgstr ""
+
+#: dlltool.c:2949
+msgid " --no-export-all-symbols Only export listed symbols\n"
+msgstr ""
+
+#: dlltool.c:2950
+msgid " --exclude-symbols <list> Don't export <list>\n"
+msgstr ""
+
+#: dlltool.c:2951
+msgid " --no-default-excludes Clear default exclude symbols\n"
+msgstr ""
+
+#: dlltool.c:2952
+msgid " -b --base-file <basefile> Read linker generated base file.\n"
+msgstr ""
+
+#: dlltool.c:2953
+msgid " -x --no-idata4 Don't generate idata$4 section.\n"
+msgstr ""
+
+#: dlltool.c:2954
+msgid " -c --no-idata5 Don't generate idata$5 section.\n"
+msgstr ""
+
+#: dlltool.c:2955
+msgid ""
+" -U --add-underscore Add underscores to symbols in interface "
+"library.\n"
+msgstr ""
+
+#: dlltool.c:2956
+msgid " -k --kill-at Kill @<n> from exported names.\n"
+msgstr ""
+
+#: dlltool.c:2957
+msgid " -A --add-stdcall-alias Add aliases without @<n>.\n"
+msgstr ""
+
+#: dlltool.c:2958
+msgid " -S --as <name> Use <name> for assembler.\n"
+msgstr ""
+
+#: dlltool.c:2959
+msgid " -f --as-flags <flags> Pass <flags> to the assembler.\n"
+msgstr ""
+
+#: dlltool.c:2961
+msgid " -i --interwork Support ARM/Thumb interworking.\n"
+msgstr ""
+
+#: dlltool.c:2963
+msgid ""
+" -n --no-delete Keep temp files (repeat for extra "
+"preservation).\n"
+msgstr ""
+
+#: dlltool.c:2964
+msgid " -v --verbose Be verbose.\n"
+msgstr ""
+
+#: dlltool.c:2965
+msgid " -V --version Display the program version.\n"
+msgstr ""
+
+#: dlltool.c:2966
+msgid " -h --help Display this information.\n"
+msgstr ""
+
+#: dlltool.c:3120
+#, c-format
+msgid "Unable to open base-file: %s"
+msgstr ""
+
+#: dlltool.c:3137
+#, c-format
+msgid "Machine '%s' not supported"
+msgstr ""
+
+#: ieee.c:316
+msgid "unexpected end of debugging information"
+msgstr ""
+
+#: ieee.c:411
+msgid "invalid number"
+msgstr ""
+
+#: ieee.c:470
+msgid "invalid string length"
+msgstr ""
+
+#: ieee.c:527 ieee.c:568
+msgid "expression stack overflow"
+msgstr ""
+
+#: ieee.c:547
+msgid "unsupported IEEE expression operator"
+msgstr ""
+
+#: ieee.c:562
+msgid "unknown section"
+msgstr ""
+
+#: ieee.c:583
+msgid "expression stack underflow"
+msgstr ""
+
+#: ieee.c:597
+msgid "expression stack mismatch"
+msgstr ""
+
+#: ieee.c:636
+msgid "unknown builtin type"
+msgstr ""
+
+#: ieee.c:781
+msgid "BCD float type not supported"
+msgstr ""
+
+#: ieee.c:927
+msgid "unexpected number"
+msgstr ""
+
+#: ieee.c:934
+msgid "unexpected record type"
+msgstr ""
+
+#: ieee.c:967
+msgid "blocks left on stack at end"
+msgstr ""
+
+#: ieee.c:1232
+msgid "unknown BB type"
+msgstr ""
+
+#: ieee.c:1241
+msgid "stack overflow"
+msgstr ""
+
+#: ieee.c:1266
+msgid "stack underflow"
+msgstr ""
+
+#: ieee.c:1380 ieee.c:1452 ieee.c:2151
+msgid "illegal variable index"
+msgstr ""
+
+#: ieee.c:1430
+msgid "illegal type index"
+msgstr ""
+
+#: ieee.c:1440 ieee.c:1477
+msgid "unknown TY code"
+msgstr ""
+
+#: ieee.c:1459
+msgid "undefined variable in TY"
+msgstr ""
+
+#. Pascal file name. FIXME.
+#: ieee.c:1870
+msgid "Pascal file name not supported"
+msgstr ""
+
+#: ieee.c:1918
+msgid "unsupported qualifer"
+msgstr ""
+
+#: ieee.c:2189
+msgid "undefined variable in ATN"
+msgstr ""
+
+#: ieee.c:2232
+msgid "unknown ATN type"
+msgstr ""
+
+#. Reserved for FORTRAN common.
+#: ieee.c:2354
+msgid "unsupported ATN11"
+msgstr ""
+
+#. We have no way to record this information. FIXME.
+#: ieee.c:2381
+msgid "unsupported ATN12"
+msgstr ""
+
+#: ieee.c:2441
+msgid "unexpected string in C++ misc"
+msgstr ""
+
+#: ieee.c:2454
+msgid "bad misc record"
+msgstr ""
+
+#: ieee.c:2497
+msgid "unrecognized C++ misc record"
+msgstr ""
+
+#: ieee.c:2614
+msgid "undefined C++ object"
+msgstr ""
+
+#: ieee.c:2648
+msgid "unrecognized C++ object spec"
+msgstr ""
+
+#: ieee.c:2684
+msgid "unsupported C++ object type"
+msgstr ""
+
+#: ieee.c:2694
+msgid "C++ base class not defined"
+msgstr ""
+
+#: ieee.c:2706 ieee.c:2811
+msgid "C++ object has no fields"
+msgstr ""
+
+#: ieee.c:2725
+msgid "C++ base class not found in container"
+msgstr ""
+
+#: ieee.c:2832
+msgid "C++ data member not found in container"
+msgstr ""
+
+#: ieee.c:2873 ieee.c:3023
+msgid "unknown C++ visibility"
+msgstr ""
+
+#: ieee.c:2907
+msgid "bad C++ field bit pos or size"
+msgstr ""
+
+#: ieee.c:2999
+msgid "bad type for C++ method function"
+msgstr ""
+
+#: ieee.c:3009
+msgid "no type information for C++ method function"
+msgstr ""
+
+#: ieee.c:3048
+msgid "C++ static virtual method"
+msgstr ""
+
+#: ieee.c:3143
+msgid "unrecognized C++ object overhead spec"
+msgstr ""
+
+#: ieee.c:3182
+msgid "undefined C++ vtable"
+msgstr ""
+
+#: ieee.c:3253
+msgid "C++ default values not in a function"
+msgstr ""
+
+#: ieee.c:3293
+msgid "unrecognized C++ default type"
+msgstr ""
+
+#: ieee.c:3324
+msgid "reference parameter is not a pointer"
+msgstr ""
+
+#: ieee.c:3409
+msgid "unrecognized C++ reference type"
+msgstr ""
+
+#: ieee.c:3491
+msgid "C++ reference not found"
+msgstr ""
+
+#: ieee.c:3499
+msgid "C++ reference is not pointer"
+msgstr ""
+
+#: ieee.c:3528 ieee.c:3536
+msgid "missing required ASN"
+msgstr ""
+
+#: ieee.c:3566 ieee.c:3574
+msgid "missing required ATN65"
+msgstr ""
+
+#: ieee.c:3588
+msgid "bad ATN65 record"
+msgstr ""
+
+#: ieee.c:4235
+msgid "IEEE numeric overflow: 0x"
+msgstr ""
+
+#: ieee.c:4281
+#, c-format
+msgid "IEEE string length overflow: %u\n"
+msgstr ""
+
+#: ieee.c:5315
+#, c-format
+msgid "IEEE unsupported integer type size %u\n"
+msgstr ""
+
+#: ieee.c:5351
+#, c-format
+msgid "IEEE unsupported float type size %u\n"
+msgstr ""
+
+#: ieee.c:5387
+#, c-format
+msgid "IEEE unsupported complex type size %u\n"
+msgstr ""
+
+#: nlmconv.c:275 srconv.c:1966
+#, c-format
+msgid "%s: input and output files must be different\n"
+msgstr ""
+
+#: nlmconv.c:325
+#, c-format
+msgid "%s: input file named both on command line and with INPUT\n"
+msgstr ""
+
+#: nlmconv.c:336
+#, c-format
+msgid "%s: no input file\n"
+msgstr ""
+
+#: nlmconv.c:366
+#, c-format
+msgid "%s: no name for output file\n"
+msgstr ""
+
+#: nlmconv.c:381
+#, c-format
+msgid "%s: warning:input and output formats are not compatible\n"
+msgstr ""
+
+#: nlmconv.c:411
+msgid "make .bss section"
+msgstr ""
+
+#: nlmconv.c:420
+msgid "make .nlmsections section"
+msgstr ""
+
+#: nlmconv.c:422
+msgid "set .nlmsections flags"
+msgstr ""
+
+#: nlmconv.c:450
+msgid "set .bss vma"
+msgstr ""
+
+#: nlmconv.c:457
+msgid "set .data size"
+msgstr ""
+
+#: nlmconv.c:638
+#, c-format
+msgid "%s: warning: symbol %s imported but not in import list\n"
+msgstr ""
+
+#: nlmconv.c:658
+msgid "set start address"
+msgstr ""
+
+#: nlmconv.c:707
+#, c-format
+msgid "%s: warning: START procedure %s not defined\n"
+msgstr ""
+
+#: nlmconv.c:710
+#, c-format
+msgid "%s: warning: EXIT procedure %s not defined\n"
+msgstr ""
+
+#: nlmconv.c:714
+#, c-format
+msgid "%s: warning: CHECK procedure %s not defined\n"
+msgstr ""
+
+#: nlmconv.c:736 nlmconv.c:928
+msgid "custom section"
+msgstr ""
+
+#: nlmconv.c:757 nlmconv.c:960
+msgid "help section"
+msgstr ""
+
+#: nlmconv.c:779 nlmconv.c:979
+msgid "message section"
+msgstr ""
+
+#: nlmconv.c:795 nlmconv.c:1012
+msgid "module section"
+msgstr ""
+
+#: nlmconv.c:815 nlmconv.c:1029
+msgid "rpc section"
+msgstr ""
+
+#: nlmconv.c:852
+#, c-format
+msgid "%s:%s: warning: shared libraries can not have uninitialized data\n"
+msgstr ""
+
+#: nlmconv.c:873 nlmconv.c:1049
+msgid "shared section"
+msgstr ""
+
+#: nlmconv.c:881
+#, c-format
+msgid "%s: warning: No version number given\n"
+msgstr ""
+
+#: nlmconv.c:922 nlmconv.c:954 nlmconv.c:973 nlmconv.c:1023 nlmconv.c:1043
+#, c-format
+msgid "%s:%s: read: %s\n"
+msgstr ""
+
+#: nlmconv.c:946
+#, c-format
+msgid "%s: warning: MAP and FULLMAP are not supported; try ld -M\n"
+msgstr ""
+
+#: nlmconv.c:1121
+#, c-format
+msgid "%s: Convert an object file into a NetWare Loadable Module\n"
+msgstr ""
+
+#: nlmconv.c:1133
+#, c-format
+msgid ""
+"Usage: %s [-dhV] [-I bfdname] [-O bfdname] [-T header-file] [-l linker]\n"
+" [--input-target=bfdname] [--output-target=bfdname]\n"
+" [--header-file=file] [--linker=linker] [--debug]\n"
+" [--help] [--version]\n"
+" [in-file [out-file]]\n"
+msgstr ""
+
+#: nlmconv.c:1173
+#, c-format
+msgid "%s: support not compiled in for %s\n"
+msgstr ""
+
+#: nlmconv.c:1216
+msgid "make section"
+msgstr ""
+
+#: nlmconv.c:1230
+msgid "set section size"
+msgstr ""
+
+#: nlmconv.c:1236
+msgid "set section alignment"
+msgstr ""
+
+#: nlmconv.c:1240
+msgid "set section flags"
+msgstr ""
+
+#: nlmconv.c:1251
+msgid "set .nlmsections size"
+msgstr ""
+
+#: nlmconv.c:1339 nlmconv.c:1347 nlmconv.c:1356 nlmconv.c:1361
+msgid "set .nlmsection contents"
+msgstr ""
+
+#: nlmconv.c:1864
+msgid "stub section sizes"
+msgstr ""
+
+#: nlmconv.c:1913
+msgid "writing stub"
+msgstr ""
+
+#: nlmconv.c:2003
+#, c-format
+msgid "%s: unresolved PC relative reloc against %s\n"
+msgstr ""
+
+#: nlmconv.c:2068
+#, c-format
+msgid "%s: overflow when adjusting relocation against %s\n"
+msgstr ""
+
+#: nlmconv.c:2191
+#, c-format
+msgid "%s: execution of %s failed: "
+msgstr ""
+
+#: nlmconv.c:2206
+#, c-format
+msgid "%s: Execution of %s failed\n"
+msgstr ""
+
+#: nm.c:292
+#, c-format
+msgid ""
+"Usage: %s [-aABCDglnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n"
+" [--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n"
+" [--numeric-sort] [--no-sort] [--reverse-sort] [--size-sort]\n"
+" [--undefined-only] [--portability] [-f {bsd,sysv,posix}]\n"
+" [--format={bsd,sysv,posix}] [--demangle] [--no-demangle] [--dynamic]\n"
+" [--defined-only] [--line-numbers]\n"
+" [--version] [--help]\n"
+" [file...]\n"
+msgstr ""
+
+#: nm.c:337
+#, c-format
+msgid "%s: %s: invalid radix\n"
+msgstr ""
+
+#: nm.c:363
+#, c-format
+msgid "%s: %s: invalid output format\n"
+msgstr ""
+
+#: nm.c:490
+#, c-format
+msgid "%s: data size %ld\n"
+msgstr ""
+
+#: nm.c:1281
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Undefined symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: nm.c:1283
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: nm.c:1284 nm.c:1338
+msgid ""
+"Name Value Class Type Size Line "
+"Section\n"
+"\n"
+msgstr ""
+
+#: nm.c:1335
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Undefined symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: nm.c:1337
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: nm.c:1508
+msgid ""
+"\n"
+"Archive index:\n"
+msgstr ""
+
+#: objcopy.c:293
+#, c-format
+msgid ""
+"Usage: %s [-vVSpgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n"
+" [-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n"
+" [--input-target=bfdname] [--output-target=bfdname] "
+"[--target=bfdname]\n"
+" [--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n"
+" [--discard-locals] [--debugging] [--remove-section=section]\n"
+msgstr ""
+
+#: objcopy.c:300
+msgid ""
+" [--gap-fill=val] [--pad-to=address] [--preserve-dates]\n"
+" [--set-start=val] \n"
+" [--change-start=incr] [--change-addresses=incr] \n"
+" (--adjust-start and --adjust-vma are aliases for these two) \n"
+" [--change-section-address=section{=,+,-}val]\n"
+" (--adjust-section-vma is an alias for --change-section-address)\n"
+" [--change-section-lma=section{=,+,-}val]\n"
+" [--change-section-vma=section{=,+,-}val]\n"
+" [--adjust-warnings] [--no-adjust-warnings]\n"
+" [--change-warnings] [--no-change-warnings]\n"
+" [--set-section-flags=section=flags] "
+"[--add-section=sectionname=filename]\n"
+" [--keep-symbol symbol] [-K symbol] [--strip-symbol symbol] [-N "
+"symbol]\n"
+" [--localize-symbol symbol] [-L symbol] [--weaken-symbol symbol]\n"
+" [-W symbol] [--change-leading-char] [--remove-leading-char] "
+"[--weaken]\n"
+" [--verbose] [--version] [--help] in-file [out-file]\n"
+msgstr ""
+
+#: objcopy.c:327
+#, c-format
+msgid ""
+"Usage: %s [-vVsSpgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-R section]\n"
+" [--input-target=bfdname] [--output-target=bfdname] "
+"[--target=bfdname]\n"
+" [--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n"
+" [--discard-locals] [--keep-symbol symbol] [-K symbol]\n"
+" [--strip-symbol symbol] [-N symbol] [--remove-section=section]\n"
+" [-o file] [--preserve-dates] [--verbose] [--version] [--help] "
+"file...\n"
+msgstr ""
+
+#: objcopy.c:383
+#, c-format
+msgid "unrecognized section flag `%s'"
+msgstr ""
+
+#: objcopy.c:384
+msgid "supported flags: alloc, load, readonly, code, data, rom, contents"
+msgstr ""
+
+#: objcopy.c:623
+#, c-format
+msgid "copy from %s(%s) to %s(%s)\n"
+msgstr ""
+
+#: objcopy.c:642
+#, c-format
+msgid "Warning: Output file cannot represent architecture %s"
+msgstr ""
+
+#: objcopy.c:669
+#, c-format
+msgid "can't create section `%s': %s"
+msgstr ""
+
+#: objcopy.c:755
+#, c-format
+msgid "Can't fill gap after %s: %s"
+msgstr ""
+
+#: objcopy.c:780
+#, c-format
+msgid "Can't add padding to %s: %s"
+msgstr ""
+
+#: objcopy.c:916
+#, c-format
+msgid "%s: error copying private BFD data: %s"
+msgstr ""
+
+#: objcopy.c:950
+#, c-format
+msgid "cannot mkdir %s for archive copying (error: %s)"
+msgstr ""
+
+#: objcopy.c:1204
+#, c-format
+msgid "%s: section `%s': error in %s: %s"
+msgstr ""
+
+#: objcopy.c:1476
+#, c-format
+msgid "%s: can't create debugging section: %s"
+msgstr ""
+
+#: objcopy.c:1491
+#, c-format
+msgid "%s: can't set debugging section contents: %s"
+msgstr ""
+
+#: objcopy.c:1500
+#, c-format
+msgid "%s: don't know how to write debugging information for %s"
+msgstr ""
+
+#: objcopy.c:1605
+#, c-format
+msgid "%s: cannot stat: %s"
+msgstr ""
+
+#: objcopy.c:1655
+msgid "byte number must be non-negative"
+msgstr ""
+
+#: objcopy.c:1660
+msgid "interleave must be positive"
+msgstr ""
+
+#: objcopy.c:1729
+msgid "bad format for --add-section NAME=FILENAME"
+msgstr ""
+
+#: objcopy.c:1732
+#, c-format
+msgid "cannot stat: %s: %s"
+msgstr ""
+
+#: objcopy.c:1750
+#, c-format
+msgid "cannot open: %s: %s"
+msgstr ""
+
+#: objcopy.c:1754
+#, c-format
+msgid "%s: fread failed"
+msgstr ""
+
+#: objcopy.c:1791
+#, c-format
+msgid "bad format for %s"
+msgstr ""
+
+#: objcopy.c:1855
+#, c-format
+msgid "Warning: truncating gap-fill from 0x%s to 0x%x"
+msgstr ""
+
+#: objcopy.c:1879
+msgid "bad format for --set-section-flags"
+msgstr ""
+
+#: objcopy.c:1909
+msgid "byte number must be less than interleave"
+msgstr ""
+
+#: objcopy.c:1928
+#, c-format
+msgid "Cannot stat: %s: %s"
+msgstr ""
+
+#: objcopy.c:1968
+#, c-format
+msgid "Warning: --change-section-vma %s%c0x%s never used"
+msgstr ""
+
+#: objcopy.c:1981
+#, c-format
+msgid "Warning: --change-section-lma %s%c0x%s never used"
+msgstr ""
+
+#: objdump.c:219
+#, c-format
+msgid ""
+"Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n"
+" [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n"
+" [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n"
+" [--section-headers] [--headers]\n"
+" [--info] [--section=section-name] [--line-numbers] [--source]\n"
+msgstr ""
+
+#: objdump.c:226
+msgid ""
+" [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n"
+" [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n"
+" [--wide] [--version] [--help] [--private-headers]\n"
+" [--start-address=addr] [--stop-address=addr]\n"
+" [--prefix-addresses] [--[no-]show-raw-insn] [--demangle]\n"
+" [--adjust-vma=offset] [-EB|-EL] [--endian={big|little}] objfile...\n"
+"at least one option besides -l (--line-numbers) must be given\n"
+msgstr ""
+
+#: objdump.c:361
+msgid "Sections:\n"
+msgstr ""
+
+#: objdump.c:363
+msgid "Idx Name Size VMA LMA File off Algn\n"
+msgstr ""
+
+#: objdump.c:365
+msgid ""
+"Idx Name Size VMA LMA File off "
+"Algn\n"
+msgstr ""
+
+#: objdump.c:414
+#, c-format
+msgid "%s: %s: not a dynamic object\n"
+msgstr ""
+
+#: objdump.c:431
+#, c-format
+msgid "%s: %s: No dynamic symbols\n"
+msgstr ""
+
+#: objdump.c:1131
+msgid "Out of virtual memory\n"
+msgstr ""
+
+#: objdump.c:1532
+#, c-format
+msgid "%s: Can't use supplied machine %s\n"
+msgstr ""
+
+#: objdump.c:1553
+#, c-format
+msgid "%s: Can't disassemble for architecture %s\n"
+msgstr ""
+
+#: objdump.c:1627
+#, c-format
+msgid "Disassembly of section %s:\n"
+msgstr ""
+
+#: objdump.c:1798
+#, c-format
+msgid ""
+"No %s section present\n"
+"\n"
+msgstr ""
+
+#: objdump.c:1805
+#, c-format
+msgid "%s: %s has no %s section\n"
+msgstr ""
+
+#: objdump.c:1818 objdump.c:1829
+#, c-format
+msgid "%s: Reading %s section of %s failed: %s\n"
+msgstr ""
+
+#: objdump.c:1871
+#, c-format
+msgid ""
+"Contents of %s section:\n"
+"\n"
+msgstr ""
+
+#: objdump.c:1971
+#, c-format
+msgid "architecture: %s, "
+msgstr ""
+
+#: objdump.c:1974
+#, c-format
+msgid "flags 0x%08x:\n"
+msgstr ""
+
+#: objdump.c:1987
+msgid ""
+"\n"
+"start address 0x"
+msgstr ""
+
+#: objdump.c:2030
+#, c-format
+msgid ""
+"\n"
+"%s: file format %s\n"
+msgstr ""
+
+#: objdump.c:2071
+#, c-format
+msgid "%s: printing debugging information failed\n"
+msgstr ""
+
+#: objdump.c:2105
+#, c-format
+msgid "In archive %s:\n"
+msgstr ""
+
+#: objdump.c:2158
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: objdump.c:2661
+#, c-format
+msgid "BFD header file version %s\n"
+msgstr ""
+
+#: objdump.c:2786
+#, c-format
+msgid "%s: unrecognized -E option\n"
+msgstr ""
+
+#: objdump.c:2797
+#, c-format
+msgid "%s: unrecognized --endian type `%s'\n"
+msgstr ""
+
+#: rdcoff.c:204
+#, c-format
+msgid "%s: parse_coff_type: Bad type code 0x%x\n"
+msgstr ""
+
+#: rdcoff.c:423 rdcoff.c:531 rdcoff.c:712
+#, c-format
+msgid "%s: bfd_coff_get_syment failed: %s\n"
+msgstr ""
+
+#: rdcoff.c:439 rdcoff.c:732
+#, c-format
+msgid "%s: bfd_coff_get_auxent failed: %s\n"
+msgstr ""
+
+#: rdcoff.c:798
+#, c-format
+msgid "%s: %ld: .bf without preceding function\n"
+msgstr ""
+
+#: rdcoff.c:848
+#, c-format
+msgid "%s: %ld: unexpected .ef\n"
+msgstr ""
+
+#: rddbg.c:87
+#, c-format
+msgid "%s: no recognized debugging information\n"
+msgstr ""
+
+#: rddbg.c:400
+msgid "Last stabs entries before error:\n"
+msgstr ""
+
+#: readelf.c:229 readelf.c:255
+#, c-format
+msgid "%s: Error: "
+msgstr ""
+
+#: readelf.c:241 readelf.c:270
+#, c-format
+msgid "%s: Warning: "
+msgstr ""
+
+#: readelf.c:300 readelf.c:325
+#, c-format
+msgid "Unhandled data length: %d\n"
+msgstr ""
+
+#: readelf.c:420
+msgid "Don't know about relocations on this machine architecture\n"
+msgstr ""
+
+#: readelf.c:426
+msgid ""
+" Offset Info Type Symbol's Value Symbol's Name "
+"Addend\n"
+msgstr ""
+
+#: readelf.c:429
+msgid " Offset Info Type Symbol's Value Symbol's Name\n"
+msgstr ""
+
+#: readelf.c:533
+#, c-format
+msgid "unrecognised: %-7lx"
+msgstr ""
+
+#: readelf.c:551
+#, c-format
+msgid "<string table index %3ld>"
+msgstr ""
+
+#: readelf.c:703
+#, c-format
+msgid "Processor Specific: %lx"
+msgstr ""
+
+#: readelf.c:706
+#, c-format
+msgid "Operating System specific: %lx"
+msgstr ""
+
+#: readelf.c:708 readelf.c:961
+#, c-format
+msgid "<unknown>: %lx"
+msgstr ""
+
+#: readelf.c:722
+msgid "NONE (None)"
+msgstr ""
+
+#: readelf.c:723
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: readelf.c:724
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: readelf.c:725
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: readelf.c:726
+msgid "CORE (Core file)"
+msgstr ""
+
+#: readelf.c:730
+#, c-format
+msgid "Processor Specific: (%x)"
+msgstr ""
+
+#: readelf.c:732
+#, c-format
+msgid "OS Specific: (%x)"
+msgstr ""
+
+#: readelf.c:734 readelf.c:793 readelf.c:897 readelf.c:1072
+#, c-format
+msgid "<unknown>: %x"
+msgstr ""
+
+#: readelf.c:747
+msgid "None"
+msgstr ""
+
+#: readelf.c:894
+msgid "ELFDATA2LSB (little endian)"
+msgstr ""
+
+#: readelf.c:895
+msgid "ELFDATA2MSB (big endian)"
+msgstr ""
+
+#: readelf.c:1108
+msgid "Usage: readelf {options} elf-file(s)\n"
+msgstr ""
+
+#: readelf.c:1109
+msgid " Options are:\n"
+msgstr ""
+
+#: readelf.c:1110
+msgid ""
+" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"
+msgstr ""
+
+#: readelf.c:1111
+msgid " -h or --file-header Display the ELF file header\n"
+msgstr ""
+
+#: readelf.c:1112
+msgid " -l or --program-headers or --segments\n"
+msgstr ""
+
+#: readelf.c:1113
+msgid " Display the program headers\n"
+msgstr ""
+
+#: readelf.c:1114
+msgid " -S or --section-headers or --sections\n"
+msgstr ""
+
+#: readelf.c:1115
+msgid " Display the sections' header\n"
+msgstr ""
+
+#: readelf.c:1116
+msgid " -e or --headers Equivalent to: -h -l -S\n"
+msgstr ""
+
+#: readelf.c:1117
+msgid " -s or --syms or --symbols Display the symbol table\n"
+msgstr ""
+
+#: readelf.c:1118
+msgid " -r or --relocs Display the relocations (if present)\n"
+msgstr ""
+
+#: readelf.c:1119
+msgid " -d or --dynamic Display the dynamic segment (if present)\n"
+msgstr ""
+
+#: readelf.c:1120
+msgid " -V or --version-info Display the version sections (if present)\n"
+msgstr ""
+
+#: readelf.c:1121
+msgid ""
+" -D or --use-dynamic Use the dynamic section info when displaying "
+"symbols\n"
+msgstr ""
+
+#: readelf.c:1122
+msgid " -x <number> or --hex-dump=<number>\n"
+msgstr ""
+
+#: readelf.c:1123
+msgid " Dump the contents of section <number>\n"
+msgstr ""
+
+#: readelf.c:1124
+msgid " -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"
+msgstr ""
+
+#: readelf.c:1125
+msgid ""
+" Display the contents of DWARF2 debug sections\n"
+msgstr ""
+
+#: readelf.c:1127
+msgid " -i <number> or --instruction-dump=<number>\n"
+msgstr ""
+
+#: readelf.c:1128
+msgid ""
+" Disassemble the contents of section <number>\n"
+msgstr ""
+
+#: readelf.c:1130
+msgid " --histogram Display histogram of bucket list lengths\n"
+msgstr ""
+
+#: readelf.c:1131
+msgid " -v or --version Display the version number of readelf\n"
+msgstr ""
+
+#: readelf.c:1132
+msgid " -H or --help Display this information\n"
+msgstr ""
+
+#: readelf.c:1150
+msgid "Out of memory allocating dump request table."
+msgstr ""
+
+#: readelf.c:1274
+#, c-format
+msgid "Unrecognised debug option '%s'\n"
+msgstr ""
+
+#: readelf.c:1299
+#, c-format
+msgid "Invalid option '-%c'\n"
+msgstr ""
+
+#: readelf.c:1312
+msgid "Nothing to do.\n"
+msgstr ""
+
+#: readelf.c:1323 readelf.c:1336 readelf.c:2459
+msgid "none"
+msgstr ""
+
+#: readelf.c:1324
+msgid "ELF32"
+msgstr ""
+
+#: readelf.c:1325
+msgid "ELF64"
+msgstr ""
+
+#: readelf.c:1326 readelf.c:1339 readelf.c:1352
+msgid "<unknown>"
+msgstr ""
+
+#: readelf.c:1337
+msgid "2's compilment, little endian"
+msgstr ""
+
+#: readelf.c:1338
+msgid "2's compilment, big endian"
+msgstr ""
+
+#: readelf.c:1349
+msgid "UNIX - System V"
+msgstr ""
+
+#: readelf.c:1350
+msgid "UNIX - HP-UX"
+msgstr ""
+
+#: readelf.c:1351
+msgid "Standalone App"
+msgstr ""
+
+#: readelf.c:1366
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
+#: readelf.c:1374
+msgid "ELF Header:\n"
+msgstr ""
+
+#: readelf.c:1375
+msgid " Magic: "
+msgstr ""
+
+#: readelf.c:1379
+#, c-format
+msgid " Class: %s\n"
+msgstr ""
+
+#: readelf.c:1381 readelf.c:1397
+#, c-format
+msgid " Data: %s\n"
+msgstr ""
+
+#: readelf.c:1383
+#, c-format
+msgid " Version: %d %s\n"
+msgstr ""
+
+#: readelf.c:1387
+#, c-format
+msgid " OS/ABI: %s\n"
+msgstr ""
+
+#: readelf.c:1389
+#, c-format
+msgid " ABI Version: %d\n"
+msgstr ""
+
+#: readelf.c:1391
+#, c-format
+msgid " Type: %s\n"
+msgstr ""
+
+#: readelf.c:1393
+#, c-format
+msgid " Machine: %s\n"
+msgstr ""
+
+#: readelf.c:1395
+#, c-format
+msgid " Version: 0x%lx\n"
+msgstr ""
+
+#: readelf.c:1399
+#, c-format
+msgid " Entry point address: 0x%lx\n"
+msgstr ""
+
+#: readelf.c:1401
+#, c-format
+msgid " Start of program headers: %ld (bytes into file)\n"
+msgstr ""
+
+#: readelf.c:1403
+#, c-format
+msgid " Start of section headers: %ld (bytes into file)\n"
+msgstr ""
+
+#: readelf.c:1405
+#, c-format
+msgid " Flags: 0x%lx%s\n"
+msgstr ""
+
+#: readelf.c:1408
+#, c-format
+msgid " Size of this header: %ld (bytes)\n"
+msgstr ""
+
+#: readelf.c:1410
+#, c-format
+msgid " Size of program headers: %ld (bytes)\n"
+msgstr ""
+
+#: readelf.c:1412
+#, c-format
+msgid " Number of program headers: %ld\n"
+msgstr ""
+
+#: readelf.c:1414
+#, c-format
+msgid " Size of section headers: %ld (bytes)\n"
+msgstr ""
+
+#: readelf.c:1416
+#, c-format
+msgid " Number of section headers: %ld\n"
+msgstr ""
+
+#: readelf.c:1418
+#, c-format
+msgid " Section header string table index: %ld\n"
+msgstr ""
+
+#: readelf.c:1428
+msgid "Not a 32 bit ELF file\n"
+msgstr ""
+
+#: readelf.c:1448
+msgid ""
+"\n"
+"There are no program headers in this file.\n"
+msgstr ""
+
+#: readelf.c:1454
+#, c-format
+msgid ""
+"\n"
+"Elf file is %s\n"
+msgstr ""
+
+#: readelf.c:1455
+#, c-format
+msgid "Entry point 0x%lx\n"
+msgstr ""
+
+#: readelf.c:1456
+#, c-format
+msgid "There are %d program headers, starting at offset %lx:\n"
+msgstr ""
+
+#: readelf.c:1469 readelf.c:1619 readelf.c:1662 readelf.c:2018 readelf.c:2142
+#: readelf.c:3043 readelf.c:3057
+msgid "Out of memory\n"
+msgstr ""
+
+#: readelf.c:1492
+#, c-format
+msgid ""
+"\n"
+"Program Header%s:\n"
+msgstr ""
+
+#: readelf.c:1494
+msgid ""
+" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"
+msgstr ""
+
+#: readelf.c:1529
+msgid "more than one dynamic segment\n"
+msgstr ""
+
+#: readelf.c:1537
+msgid "Unable to find program interpreter name\n"
+msgstr ""
+
+#: readelf.c:1544
+#, c-format
+msgid ""
+"\n"
+" [Requesting program interpreter: %s]"
+msgstr ""
+
+#: readelf.c:1562
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+msgstr ""
+
+#: readelf.c:1563
+msgid " Segment Sections...\n"
+msgstr ""
+
+#: readelf.c:1697
+msgid ""
+"\n"
+"There are no sections in this file.\n"
+msgstr ""
+
+#: readelf.c:1703
+#, c-format
+msgid "There are %d section headers, starting at offset %lx:\n"
+msgstr ""
+
+#: readelf.c:1737
+msgid "File contains multiple dynamic symbol tables\n"
+msgstr ""
+
+#: readelf.c:1750
+msgid "File contains multiple dynamic string tables\n"
+msgstr ""
+
+#: readelf.c:1777
+#, c-format
+msgid ""
+"\n"
+"Section Header%s:\n"
+msgstr ""
+
+#: readelf.c:1779
+msgid ""
+" [Nr] Name Type Addr Off Size ES Flg Lk "
+"Inf Al\n"
+msgstr ""
+
+#: readelf.c:1844
+#, c-format
+msgid ""
+"\n"
+"Relocation section at offset 0x%lx contains %ld bytes:\n"
+msgstr ""
+
+#: readelf.c:1851
+msgid ""
+"\n"
+"There are no dynamic relocations in this file.\n"
+msgstr ""
+
+#: readelf.c:1877
+msgid ""
+"\n"
+"Relocation section "
+msgstr ""
+
+#: readelf.c:1884
+#, c-format
+msgid " at offset 0x%lx contains %lu entries:\n"
+msgstr ""
+
+#: readelf.c:1910
+msgid ""
+"\n"
+"There are no relocations in this file.\n"
+msgstr ""
+
+#: readelf.c:1998
+msgid ""
+"\n"
+"There is no dynamic segment in this file.\n"
+msgstr ""
+
+#: readelf.c:2056
+msgid "Unable to seek to end of file!"
+msgstr ""
+
+#: readelf.c:2062
+msgid "Unable to determine the number of symbols to load\n"
+msgstr ""
+
+#: readelf.c:2092
+msgid "Unable to seek to end of file\n"
+msgstr ""
+
+#: readelf.c:2098
+msgid "Unable to determine the length of the dynamic string table\n"
+msgstr ""
+
+#: readelf.c:2159
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment at offset 0x%x contains %d entries:\n"
+msgstr ""
+
+#: readelf.c:2162
+msgid " Tag Type Name/Value\n"
+msgstr ""
+
+#: readelf.c:2169
+#, c-format
+msgid " 0x%-8.8lx (%s)%*s"
+msgstr ""
+
+#: readelf.c:2182
+msgid "Auxiliary library"
+msgstr ""
+
+#: readelf.c:2184
+msgid "Filter library"
+msgstr ""
+
+#: readelf.c:2196 readelf.c:2217 readelf.c:2243
+msgid "Flags:"
+msgstr ""
+
+#: readelf.c:2198 readelf.c:2219 readelf.c:2245
+msgid " None\n"
+msgstr ""
+
+#: readelf.c:2348
+#, c-format
+msgid "Shared library: [%s]"
+msgstr ""
+
+#: readelf.c:2353
+msgid " program interpreter\n"
+msgstr ""
+
+#: readelf.c:2357
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: readelf.c:2361
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: readelf.c:2413
+#, c-format
+msgid "Not needed object: [%s]\n"
+msgstr ""
+
+#: readelf.c:2505
+#, c-format
+msgid ""
+"\n"
+"Version definition section '%s' contains %ld entries:\n"
+msgstr ""
+
+#: readelf.c:2508
+msgid " Addr: 0x"
+msgstr ""
+
+#: readelf.c:2510 readelf.c:2699
+#, c-format
+msgid " Offset: %#08lx Link: %lx (%s)\n"
+msgstr ""
+
+#: readelf.c:2540
+#, c-format
+msgid " %#06x: Rev: %d Flags: %s"
+msgstr ""
+
+#: readelf.c:2543
+#, c-format
+msgid " Index: %d Cnt: %d "
+msgstr ""
+
+#: readelf.c:2554
+#, c-format
+msgid "Name: %s\n"
+msgstr ""
+
+#: readelf.c:2556
+#, c-format
+msgid "Name index: %ld\n"
+msgstr ""
+
+#: readelf.c:2571
+#, c-format
+msgid " %#06x: Parent %d: %s\n"
+msgstr ""
+
+#: readelf.c:2574
+#, c-format
+msgid " %#06x: Parent %d, name index: %ld\n"
+msgstr ""
+
+#: readelf.c:2593
+#, c-format
+msgid ""
+"\n"
+"Version needs section '%s' contains %ld entries:\n"
+msgstr ""
+
+#: readelf.c:2596
+msgid " Addr: 0x"
+msgstr ""
+
+#: readelf.c:2598
+#, c-format
+msgid " Offset: %#08lx Link to section: %ld (%s)\n"
+msgstr ""
+
+#: readelf.c:2624
+#, c-format
+msgid " %#06x: Version: %d"
+msgstr ""
+
+#: readelf.c:2627
+#, c-format
+msgid " File: %s"
+msgstr ""
+
+#: readelf.c:2629
+#, c-format
+msgid " File: %lx"
+msgstr ""
+
+#: readelf.c:2631
+#, c-format
+msgid " Cnt: %d\n"
+msgstr ""
+
+#: readelf.c:2649
+#, c-format
+msgid " %#06x: Name: %s"
+msgstr ""
+
+#: readelf.c:2652
+#, c-format
+msgid " %#06x: Name index: %lx"
+msgstr ""
+
+#: readelf.c:2655
+#, c-format
+msgid " Flags: %s Version: %d\n"
+msgstr ""
+
+#: readelf.c:2694
+#, c-format
+msgid ""
+"\n"
+"Version symbols section '%s' contains %d entries:\n"
+msgstr ""
+
+#: readelf.c:2697
+msgid " Addr: "
+msgstr ""
+
+#: readelf.c:2726
+msgid " 0 (*local*) "
+msgstr ""
+
+#: readelf.c:2730
+msgid " 1 (*global*) "
+msgstr ""
+
+#: readelf.c:2953
+msgid ""
+"\n"
+"No version information found in this file.\n"
+msgstr ""
+
+#: readelf.c:2966
+msgid "LOCAL"
+msgstr ""
+
+#: readelf.c:2967
+msgid "GLOBAL"
+msgstr ""
+
+#: readelf.c:2968
+msgid "WEAK"
+msgstr ""
+
+#: readelf.c:2971 readelf.c:2995
+#, c-format
+msgid "<processor specific>: %d"
+msgstr ""
+
+#: readelf.c:2973 readelf.c:2997
+#, c-format
+msgid "<OS specific>: %d"
+msgstr ""
+
+#: readelf.c:2975 readelf.c:2999
+#, c-format
+msgid "<unknown>: %d"
+msgstr ""
+
+#: readelf.c:2988
+msgid "NOTYPE"
+msgstr ""
+
+#: readelf.c:2989
+msgid "OBJECT"
+msgstr ""
+
+#: readelf.c:2990
+msgid "FUNC"
+msgstr ""
+
+#: readelf.c:2991
+msgid "SECTION"
+msgstr ""
+
+#: readelf.c:2992
+msgid "FILE"
+msgstr ""
+
+#: readelf.c:3049
+msgid "Unable to read in dynamic data\n"
+msgstr ""
+
+#: readelf.c:3091
+msgid "Unable to seek to start of dynamic information"
+msgstr ""
+
+#: readelf.c:3097
+msgid "Failed to read in number of buckets\n"
+msgstr ""
+
+#: readelf.c:3103
+msgid "Failed to read in number of chains\n"
+msgstr ""
+
+#: readelf.c:3123
+msgid ""
+"\n"
+"Symbol table for image:\n"
+msgstr ""
+
+#: readelf.c:3124
+msgid " Num Buc: Value Size Type Bind Ot Ndx Name\n"
+msgstr ""
+
+#: readelf.c:3169
+#, c-format
+msgid ""
+"\n"
+"Symbol table '%s' contains %lu entries:\n"
+msgstr ""
+
+#: readelf.c:3172
+msgid " Num: Value Size Type Bind Ot Ndx Name\n"
+msgstr ""
+
+#: readelf.c:3291
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: readelf.c:3350
+msgid ""
+"\n"
+"Dynamic symbol information is not available for displaying symbols.\n"
+msgstr ""
+
+#: readelf.c:3362
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length (total of %d buckets):\n"
+msgstr ""
+
+#: readelf.c:3364
+msgid " Length Number %% of total Coverage\n"
+msgstr ""
+
+#: readelf.c:3369 readelf.c:3388 readelf.c:5271 readelf.c:5461
+msgid "Out of memory"
+msgstr ""
+
+#: readelf.c:3434
+#, c-format
+msgid ""
+"\n"
+"Dynamic info segment at offset 0x%lx contains %d entries:\n"
+msgstr ""
+
+#: readelf.c:3437
+msgid " Num: Name BoundTo Flags\n"
+msgstr ""
+
+#: readelf.c:3485
+#, c-format
+msgid ""
+"\n"
+"Assembly dump of section %s\n"
+msgstr ""
+
+#: readelf.c:3508
+#, c-format
+msgid ""
+"\n"
+"Section '%s' has no data to dump.\n"
+msgstr ""
+
+#: readelf.c:3513
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section '%s':\n"
+msgstr ""
+
+#: readelf.c:3663
+msgid "badly formed extended line op encountered!"
+msgstr ""
+
+#: readelf.c:3670
+#, c-format
+msgid " Extended opcode %d: "
+msgstr ""
+
+#: readelf.c:3675
+msgid ""
+"End of Sequence\n"
+"\n"
+msgstr ""
+
+#: readelf.c:3682
+#, c-format
+msgid "set Address to 0x%lx\n"
+msgstr ""
+
+#: readelf.c:3687
+msgid " define new File Table entry\n"
+msgstr ""
+
+#: readelf.c:3688 readelf.c:3806
+msgid " Entry\tDir\tTime\tSize\tName\n"
+msgstr ""
+
+#: readelf.c:3690
+#, c-format
+msgid " %d\t"
+msgstr ""
+
+#: readelf.c:3693 readelf.c:3695 readelf.c:3697 readelf.c:3818 readelf.c:3820
+#: readelf.c:3822
+#, c-format
+msgid "%lu\t"
+msgstr ""
+
+#: readelf.c:3698
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+msgstr ""
+
+#: readelf.c:3702
+#, c-format
+msgid "UNKNOWN: length %d\n"
+msgstr ""
+
+#: readelf.c:3724
+#, c-format
+msgid ""
+"\n"
+"Dump of debug contents of section %s:\n"
+"\n"
+msgstr ""
+
+#: readelf.c:3736
+msgid "The line info appears to be corrupt - the section is too small\n"
+msgstr ""
+
+#: readelf.c:3744
+msgid "Only DWARF version 2 line info is currently supported.\n"
+msgstr ""
+
+#: readelf.c:3759
+#, c-format
+msgid " Length: %ld\n"
+msgstr ""
+
+#: readelf.c:3760
+#, c-format
+msgid " DWARF Version: %d\n"
+msgstr ""
+
+#: readelf.c:3761
+#, c-format
+msgid " Prolgue Length: %d\n"
+msgstr ""
+
+#: readelf.c:3762
+#, c-format
+msgid " Minimum Instruction Length: %d\n"
+msgstr ""
+
+#: readelf.c:3763
+#, c-format
+msgid " Initial value of 'is_stmt': %d\n"
+msgstr ""
+
+#: readelf.c:3764
+#, c-format
+msgid " Line Base: %d\n"
+msgstr ""
+
+#: readelf.c:3765
+#, c-format
+msgid " Line Range: %d\n"
+msgstr ""
+
+#: readelf.c:3766
+#, c-format
+msgid " Opcode Base: %d\n"
+msgstr ""
+
+#: readelf.c:3775
+msgid ""
+"\n"
+" Opcodes:\n"
+msgstr ""
+
+#: readelf.c:3778
+#, c-format
+msgid " Opcode %d has %d args\n"
+msgstr ""
+
+#: readelf.c:3784
+msgid ""
+"\n"
+" The Directory Table is empty.\n"
+msgstr ""
+
+#: readelf.c:3787
+msgid ""
+"\n"
+" The Directory Table:\n"
+msgstr ""
+
+#: readelf.c:3791
+#, c-format
+msgid " %s\n"
+msgstr ""
+
+#: readelf.c:3802
+msgid ""
+"\n"
+" The File Name Table is empty.\n"
+msgstr ""
+
+#: readelf.c:3805
+msgid ""
+"\n"
+" The File Name Table:\n"
+msgstr ""
+
+#: readelf.c:3813
+#, c-format
+msgid " %d\t"
+msgstr ""
+
+#: readelf.c:3824
+#, c-format
+msgid "%s\n"
+msgstr ""
+
+#. Now display the statements.
+#: readelf.c:3832
+msgid ""
+"\n"
+" Line Number Statements:\n"
+msgstr ""
+
+#: readelf.c:3850
+msgid " Copy\n"
+msgstr ""
+
+#: readelf.c:3857
+#, c-format
+msgid " Advance PC by %d to %lx\n"
+msgstr ""
+
+#: readelf.c:3865
+#, c-format
+msgid " Advance Line by %d to %d\n"
+msgstr ""
+
+#: readelf.c:3872
+#, c-format
+msgid " Set File Name to entry %d in the File Name Table\n"
+msgstr ""
+
+#: readelf.c:3880
+#, c-format
+msgid " Set column to %d\n"
+msgstr ""
+
+#: readelf.c:3887
+#, c-format
+msgid " Set is_stmt to %d\n"
+msgstr ""
+
+#: readelf.c:3892
+msgid " Set basic block\n"
+msgstr ""
+
+#: readelf.c:3899
+#, c-format
+msgid " Advance PC by constant %d to 0x%lx\n"
+msgstr ""
+
+#: readelf.c:3907
+#, c-format
+msgid " Advance PC by fixed size amount %d to 0x%lx\n"
+msgstr ""
+
+#: readelf.c:3915
+#, c-format
+msgid " Special opcode %d: advance Address by %d to 0x%lx"
+msgstr ""
+
+#: readelf.c:3919
+#, c-format
+msgid " and Line by %d to %d\n"
+msgstr ""
+
+#: readelf.c:3942 readelf.c:4361
+#, c-format
+msgid ""
+"Contents of the %s section:\n"
+"\n"
+msgstr ""
+
+#: readelf.c:3961
+msgid "Only DWARF 2 pubnames are currently supported"
+msgstr ""
+
+#: readelf.c:3965
+#, c-format
+msgid " Length: %ld\n"
+msgstr ""
+
+#: readelf.c:3967
+#, c-format
+msgid " Version: %d\n"
+msgstr ""
+
+#: readelf.c:3969
+#, c-format
+msgid " Offset into .debug_info section: %ld\n"
+msgstr ""
+
+#: readelf.c:3971
+#, c-format
+msgid " Size of area in .debug_info section: %ld\n"
+msgstr ""
+
+#: readelf.c:3974
+msgid ""
+"\n"
+" Offset\tName\n"
+msgstr ""
+
+#: readelf.c:4056
+#, c-format
+msgid "Unknown TAG value: %lx"
+msgstr ""
+
+#: readelf.c:4151
+#, c-format
+msgid "Unknown AT value: %lx"
+msgstr ""
+
+#: readelf.c:4188
+#, c-format
+msgid "Unknown FORM value: %lx"
+msgstr ""
+
+#: readelf.c:4367
+msgid " Number TAG\n"
+msgstr ""
+
+#: readelf.c:4373
+#, c-format
+msgid " %ld %s [%s]\n"
+msgstr ""
+
+#: readelf.c:4376
+msgid "has children"
+msgstr ""
+
+#: readelf.c:4376
+msgid "no children"
+msgstr ""
+
+#: readelf.c:4380
+#, c-format
+msgid " %-18s %s\n"
+msgstr ""
+
+#: readelf.c:4399
+#, c-format
+msgid " %lu byte block: "
+msgstr ""
+
+#: readelf.c:4568
+msgid "(User defined location op)"
+msgstr ""
+
+#: readelf.c:4570
+msgid "(Unknown location op)"
+msgstr ""
+
+#: readelf.c:4687
+#, c-format
+msgid "Unable to handle FORM: %d"
+msgstr ""
+
+#: readelf.c:4691
+#, c-format
+msgid "Unrecognised form: %d"
+msgstr ""
+
+#: readelf.c:4704
+msgid "(not inlined)"
+msgstr ""
+
+#: readelf.c:4705
+msgid "(inlined)"
+msgstr ""
+
+#: readelf.c:4706
+msgid "(declared as inline but ignored)"
+msgstr ""
+
+#: readelf.c:4707
+msgid "(declared as inline and inlined)"
+msgstr ""
+
+#: readelf.c:4708
+#, c-format
+msgid " (Unknown inline attribute value: %lx)"
+msgstr ""
+
+#: readelf.c:4838 readelf.c:4962
+#, c-format
+msgid ""
+"The section %s contains:\n"
+"\n"
+msgstr ""
+
+#: readelf.c:4860
+msgid "Only version 2 DWARF debug information is currently supported.\n"
+msgstr ""
+
+#: readelf.c:4864
+msgid " Compilation Unit:\n"
+msgstr ""
+
+#: readelf.c:4865
+#, c-format
+msgid " Length: %ld\n"
+msgstr ""
+
+#: readelf.c:4866
+#, c-format
+msgid " Version: %d\n"
+msgstr ""
+
+#: readelf.c:4867
+#, c-format
+msgid " Abbrev Offset: %ld\n"
+msgstr ""
+
+#: readelf.c:4868
+#, c-format
+msgid " Pointer Size: %d\n"
+msgstr ""
+
+#: readelf.c:4888
+msgid "Unable to locate .debug_abbrev section!\n"
+msgstr ""
+
+#: readelf.c:4928
+#, c-format
+msgid "Unable to locate entry %d in the abbreviation table\n"
+msgstr ""
+
+#: readelf.c:4933
+#, c-format
+msgid " <%d><%x>: Abbrev Number: %d (%s)\n"
+msgstr ""
+
+#: readelf.c:4980
+#, c-format
+msgid " Length: %ld\n"
+msgstr ""
+
+#: readelf.c:4981
+#, c-format
+msgid " Version: %d\n"
+msgstr ""
+
+#: readelf.c:4982
+#, c-format
+msgid " Offset into .debug_info: %lx\n"
+msgstr ""
+
+#: readelf.c:4983
+#, c-format
+msgid " Pointer Size: %d\n"
+msgstr ""
+
+#: readelf.c:4984
+#, c-format
+msgid " Segment Size: %d\n"
+msgstr ""
+
+#: readelf.c:4986
+msgid ""
+"\n"
+" Address Length\n"
+msgstr ""
+
+#: readelf.c:5021
+#, c-format
+msgid "Displaying the debug contents of section %s is not yet supported.\n"
+msgstr ""
+
+#: readelf.c:5063
+#, c-format
+msgid ""
+"\n"
+"Section '%s' has no debugging data.\n"
+msgstr ""
+
+#: readelf.c:5079
+#, c-format
+msgid "Unrecognised debug section: %s\n"
+msgstr ""
+
+#: readelf.c:5118
+msgid "Some sections were not dumped because they do not exist!\n"
+msgstr ""
+
+#: readelf.c:5293
+#, c-format
+msgid ""
+"\n"
+"Section '%s' contains %d entries:\n"
+msgstr ""
+
+#: readelf.c:5454
+msgid "conflict list with without table"
+msgstr ""
+
+#: readelf.c:5482
+#, c-format
+msgid ""
+"\n"
+"Section '.conflict' contains %d entries:\n"
+msgstr ""
+
+#: readelf.c:5483
+msgid " Num: Index Value Name"
+msgstr ""
+
+#: readelf.c:5560
+#, c-format
+msgid "Cannot stat input file %s.\n"
+msgstr ""
+
+#: readelf.c:5567
+#, c-format
+msgid "Input file %s not found.\n"
+msgstr ""
+
+#: readelf.c:5573
+#, c-format
+msgid "%s: Failed to read file header\n"
+msgstr ""
+
+#: readelf.c:5587
+#, c-format
+msgid ""
+"\n"
+"File: %s\n"
+msgstr ""
+
+#: rename.c:121
+#, c-format
+msgid "%s: cannot set time: %s"
+msgstr ""
+
+#. We have to clean up here.
+#: rename.c:160 rename.c:193
+#, c-format
+msgid "%s: rename: %s"
+msgstr ""
+
+#: rename.c:201
+#, c-format
+msgid "%s: simple_copy: %s"
+msgstr ""
+
+#: resbin.c:130
+#, c-format
+msgid "%s: not enough binary data"
+msgstr ""
+
+#: resbin.c:149
+msgid "null terminated unicode string"
+msgstr ""
+
+#: resbin.c:179 resbin.c:185
+msgid "resource ID"
+msgstr ""
+
+#: resbin.c:229
+msgid "cursor"
+msgstr ""
+
+#: resbin.c:263 resbin.c:270
+msgid "menu header"
+msgstr ""
+
+#: resbin.c:280
+msgid "menuex header"
+msgstr ""
+
+#: resbin.c:284
+msgid "menuex offset"
+msgstr ""
+
+#: resbin.c:291
+#, c-format
+msgid "unsupported menu version %d"
+msgstr ""
+
+#: resbin.c:319 resbin.c:334 resbin.c:400
+msgid "menuitem header"
+msgstr ""
+
+#: resbin.c:430
+msgid "menuitem"
+msgstr ""
+
+#: resbin.c:471 resbin.c:499
+msgid "dialog header"
+msgstr ""
+
+#: resbin.c:489
+#, c-format
+msgid "unexpected dialog signature %d"
+msgstr ""
+
+#: resbin.c:531
+msgid "dialog font point size"
+msgstr ""
+
+#: resbin.c:539
+msgid "dialogex font information"
+msgstr ""
+
+#: resbin.c:564 resbin.c:582
+msgid "dialog control"
+msgstr ""
+
+#: resbin.c:574
+msgid "dialogex control"
+msgstr ""
+
+#: resbin.c:603
+msgid "dialog control end"
+msgstr ""
+
+#: resbin.c:615
+msgid "dialog control data"
+msgstr ""
+
+#: resbin.c:658
+msgid "stringtable string length"
+msgstr ""
+
+#: resbin.c:668
+msgid "stringtable string"
+msgstr ""
+
+#: resbin.c:701
+msgid "fontdir header"
+msgstr ""
+
+#: resbin.c:714
+msgid "fontdir"
+msgstr ""
+
+#: resbin.c:730
+msgid "fontdir device name"
+msgstr ""
+
+#: resbin.c:736
+msgid "fontdir face name"
+msgstr ""
+
+#: resbin.c:779
+msgid "accelerator"
+msgstr ""
+
+#: resbin.c:843
+msgid "group cursor header"
+msgstr ""
+
+#: resbin.c:847
+#, c-format
+msgid "unexpected group cursor type %d"
+msgstr ""
+
+#: resbin.c:862
+msgid "group cursor"
+msgstr ""
+
+#: resbin.c:901
+msgid "group icon header"
+msgstr ""
+
+#: resbin.c:905
+#, c-format
+msgid "unexpected group icon type %d"
+msgstr ""
+
+#: resbin.c:920
+msgid "group icon"
+msgstr ""
+
+#: resbin.c:991 resbin.c:1210
+msgid "unexpected version string"
+msgstr ""
+
+#: resbin.c:1025
+#, c-format
+msgid "version length %d does not match resource length %lu"
+msgstr ""
+
+#: resbin.c:1029
+#, c-format
+msgid "unexpected version type %d"
+msgstr ""
+
+#: resbin.c:1041
+#, c-format
+msgid "unexpected fixed version information length %d"
+msgstr ""
+
+#: resbin.c:1044
+msgid "fixed version info"
+msgstr ""
+
+#: resbin.c:1048
+#, c-format
+msgid "unexpected fixed version signature %lu"
+msgstr ""
+
+#: resbin.c:1052
+#, c-format
+msgid "unexpected fixed version info version %lu"
+msgstr ""
+
+#: resbin.c:1081
+msgid "version var info"
+msgstr ""
+
+#: resbin.c:1098
+#, c-format
+msgid "unexpected stringfileinfo value length %d"
+msgstr ""
+
+#: resbin.c:1108
+#, c-format
+msgid "unexpected version stringtable value length %d"
+msgstr ""
+
+#: resbin.c:1142
+#, c-format
+msgid "unexpected version string length %d != %d + %d"
+msgstr ""
+
+#: resbin.c:1153
+#, c-format
+msgid "unexpected version string length %d < %d"
+msgstr ""
+
+#: resbin.c:1170
+#, c-format
+msgid "unexpected varfileinfo value length %d"
+msgstr ""
+
+#: resbin.c:1189
+msgid "version varfileinfo"
+msgstr ""
+
+#: resbin.c:1204
+#, c-format
+msgid "unexpected version value length %d"
+msgstr ""
+
+#: rescoff.c:128
+msgid "filename required for COFF input"
+msgstr ""
+
+#: rescoff.c:145
+#, c-format
+msgid "%s: %s: no resource section\n"
+msgstr ""
+
+#: rescoff.c:154
+msgid "can't read resource section"
+msgstr ""
+
+#: rescoff.c:180
+#, c-format
+msgid "%s: %s: address out of bounds"
+msgstr ""
+
+#: rescoff.c:199
+msgid "directory"
+msgstr ""
+
+#: rescoff.c:227
+msgid "named directory entry"
+msgstr ""
+
+#: rescoff.c:236
+msgid "directory entry name"
+msgstr ""
+
+#: rescoff.c:256
+msgid "named subdirectory"
+msgstr ""
+
+#: rescoff.c:264
+msgid "named resource"
+msgstr ""
+
+#: rescoff.c:279
+msgid "ID directory entry"
+msgstr ""
+
+#: rescoff.c:296
+msgid "ID subdirectory"
+msgstr ""
+
+#: rescoff.c:304
+msgid "ID resource"
+msgstr ""
+
+#: rescoff.c:330
+msgid "resource type unknown"
+msgstr ""
+
+#: rescoff.c:333
+msgid "data entry"
+msgstr ""
+
+#: rescoff.c:341
+msgid "resource data"
+msgstr ""
+
+#: rescoff.c:346
+msgid "resource data size"
+msgstr ""
+
+#: rescoff.c:441
+msgid "filename required for COFF output"
+msgstr ""
+
+#: rescoff.c:729
+msgid "can't get BFD_RELOC_RVA relocation type"
+msgstr ""
+
+#: resrc.c:150
+#, c-format
+msgid "can't popen `%s': %s"
+msgstr ""
+
+#: resrc.c:163
+#, c-format
+msgid "%s: warning: preprocessor failed\n"
+msgstr ""
+
+#: resrc.c:208
+#, c-format
+msgid "%s: unexpected EOF"
+msgstr ""
+
+#: resrc.c:265
+#, c-format
+msgid "%s: read of %lu returned %lu"
+msgstr ""
+
+#: resrc.c:307 resrc.c:538 resrc.c:811 resrc.c:965
+#, c-format
+msgid "stat failed on bitmap file `%s': %s"
+msgstr ""
+
+#: resrc.c:360
+#, c-format
+msgid "cursor file `%s' does not contain cursor data"
+msgstr ""
+
+#: resrc.c:392 resrc.c:682
+#, c-format
+msgid "%s: fseek to %lu failed: %s"
+msgstr ""
+
+#: resrc.c:651
+#, c-format
+msgid "icon file `%s' does not contain icon data"
+msgstr ""
+
+#: resrc.c:1170
+#, c-format
+msgid "can't open `%s' for output: %s"
+msgstr ""
+
+#: size.c:79
+#, c-format
+msgid ""
+"Usage: %s [-ABdoxV] [--format=berkeley|sysv] [--radix=8|10|16]\n"
+" [--target=bfdname] [--version] [--help] [file...]\n"
+msgstr ""
+
+#: size.c:83
+msgid "default is --format=berkeley\n"
+msgstr ""
+
+#: size.c:85
+msgid "default is --format=sysv\n"
+msgstr ""
+
+#: size.c:139
+#, c-format
+msgid "invalid argument to --format: %s\n"
+msgstr ""
+
+#: size.c:166
+#, c-format
+msgid "Invalid radix: %s\n"
+msgstr ""
+
+#: srconv.c:1879
+#, c-format
+msgid "Usage: %s [-dhVq] in-file [out-file]\n"
+msgstr ""
+
+#: srconv.c:1886
+#, c-format
+msgid "%s: Convert a COFF object file into a SYSROFF object file\n"
+msgstr ""
+
+#: srconv.c:2024
+#, c-format
+msgid "%s: unable to open output file %s\n"
+msgstr ""
+
+#: stabs.c:349 stabs.c:1762
+msgid "numeric overflow"
+msgstr ""
+
+#: stabs.c:360
+#, c-format
+msgid "Bad stab: %s\n"
+msgstr ""
+
+#: stabs.c:370
+#, c-format
+msgid "Warning: %s: %s\n"
+msgstr ""
+
+#: stabs.c:492
+msgid "N_LBRAC not within function\n"
+msgstr ""
+
+#: stabs.c:531
+msgid "Too many N_RBRACs\n"
+msgstr ""
+
+#: stabs.c:780
+msgid "unknown C++ encoded name"
+msgstr ""
+
+#. Complain and keep going, so compilers can invent new
+#. cross-reference types.
+#: stabs.c:1306
+msgid "unrecognized cross reference type"
+msgstr ""
+
+#. Does this actually ever happen? Is that why we are worrying
+#. about dealing with it rather than just calling error_type?
+#: stabs.c:1854
+msgid "missing index type"
+msgstr ""
+
+#: stabs.c:2181
+msgid "unknown virtual character for baseclass"
+msgstr ""
+
+#: stabs.c:2199
+msgid "unknown visibility character for baseclass"
+msgstr ""
+
+#: stabs.c:2391
+msgid "unnamed $vb type"
+msgstr ""
+
+#: stabs.c:2397
+msgid "unrecognized C++ abbreviation"
+msgstr ""
+
+#: stabs.c:2477
+msgid "unknown visibility character for field"
+msgstr ""
+
+#: stabs.c:2733
+msgid "const/volatile indicator missing"
+msgstr ""
+
+#: stabs.c:2973
+#, c-format
+msgid "No mangling for \"%s\"\n"
+msgstr ""
+
+#: stabs.c:3286
+msgid "Undefined N_EXCL"
+msgstr ""
+
+#: stabs.c:3374
+#, c-format
+msgid "Type file number %d out of range\n"
+msgstr ""
+
+#: stabs.c:3379
+#, c-format
+msgid "Type index number %d out of range\n"
+msgstr ""
+
+#: stabs.c:3466
+#, c-format
+msgid "Unrecognized XCOFF type %d\n"
+msgstr ""
+
+#: stabs.c:3765
+#, c-format
+msgid "bad mangled name `%s'\n"
+msgstr ""
+
+#: stabs.c:3861
+msgid "no argument types in mangled string\n"
+msgstr ""
+
+#: strings.c:159
+#, c-format
+msgid "%s: invalid number %s\n"
+msgstr ""
+
+#: strings.c:494
+#, c-format
+msgid "%s: invalid integer argument %s\n"
+msgstr ""
+
+#: strings.c:505
+#, c-format
+msgid ""
+"Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n"
+" [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n"
+" [--target=bfdname] [--help] [--version] file...\n"
+msgstr ""
+
+#: sysdump.c:712
+#, c-format
+msgid "Usage: %s [-hV] in-file\n"
+msgstr ""
+
+#: sysdump.c:783
+#, c-format
+msgid "%s: cannot open input file %s\n"
+msgstr ""
+
+#: version.c:39
+msgid "Copyright 1997, 1998, 1999 Free Software Foundation, Inc.\n"
+msgstr ""
+
+#: version.c:40
+msgid ""
+"This program is free software; you may redistribute it under the terms of\n"
+"the GNU General Public License. This program has absolutely no warranty.\n"
+msgstr ""
+
+#: windres.c:228
+#, c-format
+msgid "can't open %s `%s': %s"
+msgstr ""
+
+#: windres.c:407
+msgid ": expected to be a directory\n"
+msgstr ""
+
+#: windres.c:419
+msgid ": expected to be a leaf\n"
+msgstr ""
+
+#: windres.c:428
+#, c-format
+msgid "%s: warning: "
+msgstr ""
+
+#: windres.c:430
+msgid ": duplicate value\n"
+msgstr ""
+
+#: windres.c:593
+#, c-format
+msgid "%s: unknown format type `%s'\n"
+msgstr ""
+
+#: windres.c:594
+#, c-format
+msgid "%s: supported formats:"
+msgstr ""
+
+#. Otherwise, we give up.
+#: windres.c:681
+#, c-format
+msgid "can not determine type of file `%s'; use the -I option"
+msgstr ""
+
+#: windres.c:695
+#, c-format
+msgid "Usage: %s [options] [input-file] [output-file]\n"
+msgstr ""
+
+#: windres.c:697
+msgid ""
+"Options:\n"
+" -i FILE, --input FILE Name input file\n"
+" -o FILE, --output FILE Name output file\n"
+" -I FORMAT, --input-format FORMAT\n"
+" Specify input format\n"
+" -O FORMAT, --output-format FORMAT\n"
+" Specify output format\n"
+" -F TARGET, --target TARGET Specify COFF target\n"
+" --preprocessor PROGRAM Program to use to preprocess rc file\n"
+" --include-dir DIR Include directory when preprocessing rc file\n"
+" --define SYM[=VAL] Define SYM when preprocessing rc file\n"
+" --language VAL Set language when reading rc file\n"
+msgstr ""
+
+#: windres.c:711
+msgid " --yydebug Turn on parser debugging\n"
+msgstr ""
+
+#: windres.c:714
+msgid ""
+" --help Print this help message\n"
+" --version Print version information\n"
+msgstr ""
+
+#: windres.c:717
+msgid ""
+"FORMAT is one of rc, res, or coff, and is deduced from the file name\n"
+"extension if not specified. A single file name is an input file.\n"
+"No input-file is stdin, default rc. No output-file is stdout, default rc.\n"
+msgstr ""
+
+#: windres.c:918
+msgid "no resources"
+msgstr ""
+
+#: wrstabs.c:366 wrstabs.c:2028
+#, c-format
+msgid "string_hash_lookup failed: %s\n"
+msgstr ""
+
+#: wrstabs.c:666
+#, c-format
+msgid "stab_int_type: bad size %u\n"
+msgstr ""
+
+#: wrstabs.c:1468
+#, c-format
+msgid "%s: warning: unknown size for field `%s' in struct\n"
+msgstr ""
diff --git a/binutils/prdbg.c b/binutils/prdbg.c
new file mode 100644
index 00000000000..958cbd2c6bf
--- /dev/null
+++ b/binutils/prdbg.c
@@ -0,0 +1,1862 @@
+/* prdbg.c -- Print out generic debugging information.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file prints out the generic debugging information, by
+ supplying a set of routines to debug_write. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* This is the structure we use as a handle for these routines. */
+
+struct pr_handle
+{
+ /* File to print information to. */
+ FILE *f;
+ /* Current indentation level. */
+ unsigned int indent;
+ /* Type stack. */
+ struct pr_stack *stack;
+ /* Parameter number we are about to output. */
+ int parameter;
+};
+
+/* The type stack. */
+
+struct pr_stack
+{
+ /* Next element on the stack. */
+ struct pr_stack *next;
+ /* This element. */
+ char *type;
+ /* Current visibility of fields if this is a class. */
+ enum debug_visibility visibility;
+ /* Name of the current method we are handling. */
+ const char *method;
+};
+
+static void indent PARAMS ((struct pr_handle *));
+static boolean push_type PARAMS ((struct pr_handle *, const char *));
+static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
+static boolean append_type PARAMS ((struct pr_handle *, const char *));
+static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
+static boolean indent_type PARAMS ((struct pr_handle *));
+static char *pop_type PARAMS ((struct pr_handle *));
+static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
+static boolean pr_fix_visibility
+ PARAMS ((struct pr_handle *, enum debug_visibility));
+
+static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean pr_start_source PARAMS ((PTR, const char *));
+static boolean pr_empty_type PARAMS ((PTR));
+static boolean pr_void_type PARAMS ((PTR));
+static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean pr_float_type PARAMS ((PTR, unsigned int));
+static boolean pr_complex_type PARAMS ((PTR, unsigned int));
+static boolean pr_bool_type PARAMS ((PTR, unsigned int));
+static boolean pr_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean pr_pointer_type PARAMS ((PTR));
+static boolean pr_function_type PARAMS ((PTR, int, boolean));
+static boolean pr_reference_type PARAMS ((PTR));
+static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean pr_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean pr_set_type PARAMS ((PTR, boolean));
+static boolean pr_offset_type PARAMS ((PTR));
+static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean pr_const_type PARAMS ((PTR));
+static boolean pr_volatile_type PARAMS ((PTR));
+static boolean pr_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean pr_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean pr_end_struct_type PARAMS ((PTR));
+static boolean pr_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean pr_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean pr_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean pr_class_start_method PARAMS ((PTR, const char *));
+static boolean pr_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean pr_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean pr_class_end_method PARAMS ((PTR));
+static boolean pr_end_class_type PARAMS ((PTR));
+static boolean pr_typedef_type PARAMS ((PTR, const char *));
+static boolean pr_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean pr_typdef PARAMS ((PTR, const char *));
+static boolean pr_tag PARAMS ((PTR, const char *));
+static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean pr_float_constant PARAMS ((PTR, const char *, double));
+static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean pr_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
+static boolean pr_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean pr_start_block PARAMS ((PTR, bfd_vma));
+static boolean pr_end_block PARAMS ((PTR, bfd_vma));
+static boolean pr_end_function PARAMS ((PTR));
+static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns pr_fns =
+{
+ pr_start_compilation_unit,
+ pr_start_source,
+ pr_empty_type,
+ pr_void_type,
+ pr_int_type,
+ pr_float_type,
+ pr_complex_type,
+ pr_bool_type,
+ pr_enum_type,
+ pr_pointer_type,
+ pr_function_type,
+ pr_reference_type,
+ pr_range_type,
+ pr_array_type,
+ pr_set_type,
+ pr_offset_type,
+ pr_method_type,
+ pr_const_type,
+ pr_volatile_type,
+ pr_start_struct_type,
+ pr_struct_field,
+ pr_end_struct_type,
+ pr_start_class_type,
+ pr_class_static_member,
+ pr_class_baseclass,
+ pr_class_start_method,
+ pr_class_method_variant,
+ pr_class_static_method_variant,
+ pr_class_end_method,
+ pr_end_class_type,
+ pr_typedef_type,
+ pr_tag_type,
+ pr_typdef,
+ pr_tag,
+ pr_int_constant,
+ pr_float_constant,
+ pr_typed_constant,
+ pr_variable,
+ pr_start_function,
+ pr_function_parameter,
+ pr_start_block,
+ pr_end_block,
+ pr_end_function,
+ pr_lineno
+};
+
+/* Print out the generic debugging information recorded in dhandle. */
+
+boolean
+print_debugging_info (f, dhandle)
+ FILE *f;
+ PTR dhandle;
+{
+ struct pr_handle info;
+
+ info.f = f;
+ info.indent = 0;
+ info.stack = NULL;
+ info.parameter = 0;
+
+ return debug_write (dhandle, &pr_fns, (PTR) &info);
+}
+
+/* Indent to the current indentation level. */
+
+static void
+indent (info)
+ struct pr_handle *info;
+{
+ unsigned int i;
+
+ for (i = 0; i < info->indent; i++)
+ putc (' ', info->f);
+}
+
+/* Push a type on the type stack. */
+
+static boolean
+push_type (info, type)
+ struct pr_handle *info;
+ const char *type;
+{
+ struct pr_stack *n;
+
+ if (type == NULL)
+ return false;
+
+ n = (struct pr_stack *) xmalloc (sizeof *n);
+ memset (n, 0, sizeof *n);
+
+ n->type = xstrdup (type);
+ n->visibility = DEBUG_VISIBILITY_IGNORE;
+ n->method = NULL;
+ n->next = info->stack;
+ info->stack = n;
+
+ return true;
+}
+
+/* Prepend a string onto the type on the top of the type stack. */
+
+static boolean
+prepend_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ char *n;
+
+ assert (info->stack != NULL);
+
+ n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
+ sprintf (n, "%s%s", s, info->stack->type);
+ free (info->stack->type);
+ info->stack->type = n;
+
+ return true;
+}
+
+/* Append a string to the type on the top of the type stack. */
+
+static boolean
+append_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ unsigned int len;
+
+ if (s == NULL)
+ return false;
+
+ assert (info->stack != NULL);
+
+ len = strlen (info->stack->type);
+ info->stack->type = (char *) xrealloc (info->stack->type,
+ len + strlen (s) + 1);
+ strcpy (info->stack->type + len, s);
+
+ return true;
+}
+
+/* We use an underscore to indicate where the name should go in a type
+ string. This function substitutes a string for the underscore. If
+ there is no underscore, the name follows the type. */
+
+static boolean
+substitute_type (info, s)
+ struct pr_handle *info;
+ const char *s;
+{
+ char *u;
+
+ assert (info->stack != NULL);
+
+ u = strchr (info->stack->type, '|');
+ if (u != NULL)
+ {
+ char *n;
+
+ n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
+
+ memcpy (n, info->stack->type, u - info->stack->type);
+ strcpy (n + (u - info->stack->type), s);
+ strcat (n, u + 1);
+
+ free (info->stack->type);
+ info->stack->type = n;
+
+ return true;
+ }
+
+ if (strchr (s, '|') != NULL
+ && (strchr (info->stack->type, '{') != NULL
+ || strchr (info->stack->type, '(') != NULL))
+ {
+ if (! prepend_type (info, "(")
+ || ! append_type (info, ")"))
+ return false;
+ }
+
+ if (*s == '\0')
+ return true;
+
+ return (append_type (info, " ")
+ && append_type (info, s));
+}
+
+/* Indent the type at the top of the stack by appending spaces. */
+
+static boolean
+indent_type (info)
+ struct pr_handle *info;
+{
+ unsigned int i;
+
+ for (i = 0; i < info->indent; i++)
+ {
+ if (! append_type (info, " "))
+ return false;
+ }
+
+ return true;
+}
+
+/* Pop a type from the type stack. */
+
+static char *
+pop_type (info)
+ struct pr_handle *info;
+{
+ struct pr_stack *o;
+ char *ret;
+
+ assert (info->stack != NULL);
+
+ o = info->stack;
+ info->stack = o->next;
+ ret = o->type;
+ free (o);
+
+ return ret;
+}
+
+/* Print a VMA value into a string. */
+
+static void
+print_vma (vma, buf, unsignedp, hexp)
+ bfd_vma vma;
+ char *buf;
+ boolean unsignedp;
+ boolean hexp;
+{
+ if (sizeof (vma) <= sizeof (unsigned long))
+ {
+ if (hexp)
+ sprintf (buf, "0x%lx", (unsigned long) vma);
+ else if (unsignedp)
+ sprintf (buf, "%lu", (unsigned long) vma);
+ else
+ sprintf (buf, "%ld", (long) vma);
+ }
+ else
+ {
+ buf[0] = '0';
+ buf[1] = 'x';
+ sprintf_vma (buf + 2, vma);
+ }
+}
+
+/* Start a new compilation unit. */
+
+static boolean
+pr_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->indent == 0);
+
+ fprintf (info->f, "%s:\n", filename);
+
+ return true;
+}
+
+/* Start a source file within a compilation unit. */
+
+static boolean
+pr_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->indent == 0);
+
+ fprintf (info->f, " %s:\n", filename);
+
+ return true;
+}
+
+/* Push an empty type onto the type stack. */
+
+static boolean
+pr_empty_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, "<undefined>");
+}
+
+/* Push a void type onto the type stack. */
+
+static boolean
+pr_void_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, "void");
+}
+
+/* Push an integer type onto the type stack. */
+
+static boolean
+pr_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
+ return push_type (info, ab);
+}
+
+/* Push a floating type onto the type stack. */
+
+static boolean
+pr_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ if (size == 4)
+ return push_type (info, "float");
+ else if (size == 8)
+ return push_type (info, "double");
+
+ sprintf (ab, "float%d", size * 8);
+ return push_type (info, ab);
+}
+
+/* Push a complex type onto the type stack. */
+
+static boolean
+pr_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ if (! pr_float_type (p, size))
+ return false;
+
+ return prepend_type (info, "complex ");
+}
+
+/* Push a boolean type onto the type stack. */
+
+static boolean
+pr_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[10];
+
+ sprintf (ab, "bool%d", size * 8);
+
+ return push_type (info, ab);
+}
+
+/* Push an enum type onto the type stack. */
+
+static boolean
+pr_enum_type (p, tag, names, values)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *values;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ unsigned int i;
+ bfd_signed_vma val;
+
+ if (! push_type (info, "enum "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag)
+ || ! append_type (info, " "))
+ return false;
+ }
+ if (! append_type (info, "{ "))
+ return false;
+
+ if (names == NULL)
+ {
+ if (! append_type (info, "/* undefined */"))
+ return false;
+ }
+ else
+ {
+ val = 0;
+ for (i = 0; names[i] != NULL; i++)
+ {
+ if (i > 0)
+ {
+ if (! append_type (info, ", "))
+ return false;
+ }
+
+ if (! append_type (info, names[i]))
+ return false;
+
+ if (values[i] != val)
+ {
+ char ab[20];
+
+ print_vma (values[i], ab, false, false);
+ if (! append_type (info, " = ")
+ || ! append_type (info, ab))
+ return false;
+ val = values[i];
+ }
+
+ ++val;
+ }
+ }
+
+ return append_type (info, " }");
+}
+
+/* Turn the top type on the stack into a pointer. */
+
+static boolean
+pr_pointer_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ assert (info->stack != NULL);
+
+ s = strchr (info->stack->type, '|');
+ if (s != NULL && s[1] == '[')
+ return substitute_type (info, "(*|)");
+ return substitute_type (info, "*|");
+}
+
+/* Turn the top type on the stack into a function returning that type. */
+
+static boolean
+pr_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char **arg_types;
+ unsigned int len;
+ char *s;
+
+ assert (info->stack != NULL);
+
+ len = 10;
+
+ if (argcount <= 0)
+ {
+ arg_types = NULL;
+ len += 15;
+ }
+ else
+ {
+ int i;
+
+ arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ arg_types[i] = pop_type (info);
+ if (arg_types[i] == NULL)
+ return false;
+ len += strlen (arg_types[i]) + 2;
+ }
+ if (varargs)
+ len += 5;
+ }
+
+ /* Now the return type is on the top of the stack. */
+
+ s = (char *) xmalloc (len);
+ strcpy (s, "(|) (");
+
+ if (argcount < 0)
+ strcat (s, "/* unknown */");
+ else
+ {
+ int i;
+
+ for (i = 0; i < argcount; i++)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, arg_types[i]);
+ }
+ if (varargs)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, "...");
+ }
+ if (argcount > 0)
+ free (arg_types);
+ }
+
+ strcat (s, ")");
+
+ if (! substitute_type (info, s))
+ return false;
+
+ free (s);
+
+ return true;
+}
+
+/* Turn the top type on the stack into a reference to that type. */
+
+static boolean
+pr_reference_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->stack != NULL);
+
+ return substitute_type (info, "&|");
+}
+
+/* Make a range type. */
+
+static boolean
+pr_range_type (p, lower, upper)
+ PTR p;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char abl[20], abu[20];
+
+ assert (info->stack != NULL);
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ print_vma (lower, abl, false, false);
+ print_vma (upper, abu, false, false);
+
+ return (prepend_type (info, "range (")
+ && append_type (info, "):")
+ && append_type (info, abl)
+ && append_type (info, ":")
+ && append_type (info, abu));
+}
+
+/* Make an array type. */
+
+/*ARGSUSED*/
+static boolean
+pr_array_type (p, lower, upper, stringp)
+ PTR p;
+ bfd_signed_vma lower;
+ bfd_signed_vma upper;
+ boolean stringp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *range_type;
+ char abl[20], abu[20], ab[50];
+
+ range_type = pop_type (info);
+ if (range_type == NULL)
+ return false;
+
+ if (lower == 0)
+ {
+ if (upper == -1)
+ sprintf (ab, "|[]");
+ else
+ {
+ print_vma (upper + 1, abu, false, false);
+ sprintf (ab, "|[%s]", abu);
+ }
+ }
+ else
+ {
+ print_vma (lower, abl, false, false);
+ print_vma (upper, abu, false, false);
+ sprintf (ab, "|[%s:%s]", abl, abu);
+ }
+
+ if (! substitute_type (info, ab))
+ return false;
+
+ if (strcmp (range_type, "int") != 0)
+ {
+ if (! append_type (info, ":")
+ || ! append_type (info, range_type))
+ return false;
+ }
+
+ if (stringp)
+ {
+ if (! append_type (info, " /* string */"))
+ return false;
+ }
+
+ return true;
+}
+
+/* Make a set type. */
+
+/*ARGSUSED*/
+static boolean
+pr_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ if (! prepend_type (info, "set { ")
+ || ! append_type (info, " }"))
+ return false;
+
+ if (bitstringp)
+ {
+ if (! append_type (info, "/* bitstring */"))
+ return false;
+ }
+
+ return true;
+}
+
+/* Make an offset type. */
+
+static boolean
+pr_offset_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ return (substitute_type (info, "")
+ && prepend_type (info, " ")
+ && prepend_type (info, t)
+ && append_type (info, "::|"));
+}
+
+/* Make a method type. */
+
+static boolean
+pr_method_type (p, domain, argcount, varargs)
+ PTR p;
+ boolean domain;
+ int argcount;
+ boolean varargs;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ unsigned int len;
+ char *domain_type;
+ char **arg_types;
+ char *s;
+
+ len = 10;
+
+ if (! domain)
+ domain_type = NULL;
+ else
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ domain_type = pop_type (info);
+ if (domain_type == NULL)
+ return false;
+ if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
+ && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
+ domain_type += sizeof "class " - 1;
+ else if (strncmp (domain_type, "union class ",
+ sizeof "union class ") == 0
+ && (strchr (domain_type + sizeof "union class " - 1, ' ')
+ == NULL))
+ domain_type += sizeof "union class " - 1;
+ len += strlen (domain_type);
+ }
+
+ if (argcount <= 0)
+ {
+ arg_types = NULL;
+ len += 15;
+ }
+ else
+ {
+ int i;
+
+ arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ if (! substitute_type (info, ""))
+ return false;
+ arg_types[i] = pop_type (info);
+ if (arg_types[i] == NULL)
+ return false;
+ len += strlen (arg_types[i]) + 2;
+ }
+ if (varargs)
+ len += 5;
+ }
+
+ /* Now the return type is on the top of the stack. */
+
+ s = (char *) xmalloc (len);
+ if (! domain)
+ *s = '\0';
+ else
+ strcpy (s, domain_type);
+ strcat (s, "::| (");
+
+ if (argcount < 0)
+ strcat (s, "/* unknown */");
+ else
+ {
+ int i;
+
+ for (i = 0; i < argcount; i++)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, arg_types[i]);
+ }
+ if (varargs)
+ {
+ if (i > 0)
+ strcat (s, ", ");
+ strcat (s, "...");
+ }
+ if (argcount > 0)
+ free (arg_types);
+ }
+
+ strcat (s, ")");
+
+ if (! substitute_type (info, s))
+ return false;
+
+ free (s);
+
+ return true;
+}
+
+/* Make a const qualified type. */
+
+static boolean
+pr_const_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return substitute_type (info, "const |");
+}
+
+/* Make a volatile qualified type. */
+
+static boolean
+pr_volatile_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return substitute_type (info, "volatile |");
+}
+
+/* Start accumulating a struct type. */
+
+static boolean
+pr_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ info->indent += 2;
+
+ if (! push_type (info, structp ? "struct " : "union "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag))
+ return false;
+ }
+ else
+ {
+ char idbuf[20];
+
+ sprintf (idbuf, "%%anon%u", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ if (! append_type (info, " {"))
+ return false;
+ if (size != 0 || tag != NULL)
+ {
+ char ab[30];
+
+ if (! append_type (info, " /*"))
+ return false;
+
+ if (size != 0)
+ {
+ sprintf (ab, " size %u", size);
+ if (! append_type (info, ab))
+ return false;
+ }
+ if (tag != NULL)
+ {
+ sprintf (ab, " id %u", id);
+ if (! append_type (info, ab))
+ return false;
+ }
+ if (! append_type (info, " */"))
+ return false;
+ }
+ if (! append_type (info, "\n"))
+ return false;
+
+ info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
+
+ return indent_type (info);
+}
+
+/* Output the visibility of a field in a struct. */
+
+static boolean
+pr_fix_visibility (info, visibility)
+ struct pr_handle *info;
+ enum debug_visibility visibility;
+{
+ const char *s;
+ char *t;
+ unsigned int len;
+
+ assert (info->stack != NULL);
+
+ if (info->stack->visibility == visibility)
+ return true;
+
+ assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
+
+ switch (visibility)
+ {
+ case DEBUG_VISIBILITY_PUBLIC:
+ s = "public";
+ break;
+ case DEBUG_VISIBILITY_PRIVATE:
+ s = "private";
+ break;
+ case DEBUG_VISIBILITY_PROTECTED:
+ s = "protected";
+ break;
+ case DEBUG_VISIBILITY_IGNORE:
+ s = "/* ignore */";
+ break;
+ default:
+ abort ();
+ return false;
+ }
+
+ /* Trim off a trailing space in the struct string, to make the
+ output look a bit better, then stick on the visibility string. */
+
+ t = info->stack->type;
+ len = strlen (t);
+ assert (t[len - 1] == ' ');
+ t[len - 1] = '\0';
+
+ if (! append_type (info, s)
+ || ! append_type (info, ":\n")
+ || ! indent_type (info))
+ return false;
+
+ info->stack->visibility = visibility;
+
+ return true;
+}
+
+/* Add a field to a struct type. */
+
+static boolean
+pr_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ if (! append_type (info, "; /* "))
+ return false;
+
+ if (bitsize != 0)
+ {
+ print_vma (bitsize, ab, true, false);
+ if (! append_type (info, "bitsize ")
+ || ! append_type (info, ab)
+ || ! append_type (info, ", "))
+ return false;
+ }
+
+ print_vma (bitpos, ab, true, false);
+ if (! append_type (info, "bitpos ")
+ || ! append_type (info, ab)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return append_type (info, t);
+}
+
+/* Finish a struct type. */
+
+static boolean
+pr_end_struct_type (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ assert (info->stack != NULL);
+ assert (info->indent >= 2);
+
+ info->indent -= 2;
+
+ /* Change the trailing indentation to have a close brace. */
+ s = info->stack->type + strlen (info->stack->type) - 2;
+ assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
+
+ *s++ = '}';
+ *s = '\0';
+
+ return true;
+}
+
+/* Start a class type. */
+
+static boolean
+pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *tv = NULL;
+
+ info->indent += 2;
+
+ if (vptr && ! ownvptr)
+ {
+ tv = pop_type (info);
+ if (tv == NULL)
+ return false;
+ }
+
+ if (! push_type (info, structp ? "class " : "union class "))
+ return false;
+ if (tag != NULL)
+ {
+ if (! append_type (info, tag))
+ return false;
+ }
+ else
+ {
+ char idbuf[20];
+
+ sprintf (idbuf, "%%anon%u", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ if (! append_type (info, " {"))
+ return false;
+ if (size != 0 || vptr || ownvptr || tag != NULL)
+ {
+ if (! append_type (info, " /*"))
+ return false;
+
+ if (size != 0)
+ {
+ char ab[20];
+
+ sprintf (ab, "%u", size);
+ if (! append_type (info, " size ")
+ || ! append_type (info, ab))
+ return false;
+ }
+
+ if (vptr)
+ {
+ if (! append_type (info, " vtable "))
+ return false;
+ if (ownvptr)
+ {
+ if (! append_type (info, "self "))
+ return false;
+ }
+ else
+ {
+ if (! append_type (info, tv)
+ || ! append_type (info, " "))
+ return false;
+ }
+ }
+
+ if (tag != NULL)
+ {
+ char ab[30];
+
+ sprintf (ab, " id %u", id);
+ if (! append_type (info, ab))
+ return false;
+ }
+
+ if (! append_type (info, " */"))
+ return false;
+ }
+
+ info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
+
+ return (append_type (info, "\n")
+ && indent_type (info));
+}
+
+/* Add a static member to a class. */
+
+static boolean
+pr_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ if (! prepend_type (info, "static ")
+ || ! append_type (info, "; /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return append_type (info, t);
+}
+
+/* Add a base class to a class. */
+
+static boolean
+pr_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ const char *prefix;
+ char ab[20];
+ char *s, *l, *n;
+
+ assert (info->stack != NULL && info->stack->next != NULL);
+
+ if (! substitute_type (info, ""))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (strncmp (t, "class ", sizeof "class " - 1) == 0)
+ t += sizeof "class " - 1;
+
+ /* Push it back on to take advantage of the prepend_type and
+ append_type routines. */
+ if (! push_type (info, t))
+ return false;
+
+ if (virtual)
+ {
+ if (! prepend_type (info, "virtual "))
+ return false;
+ }
+
+ switch (visibility)
+ {
+ case DEBUG_VISIBILITY_PUBLIC:
+ prefix = "public ";
+ break;
+ case DEBUG_VISIBILITY_PROTECTED:
+ prefix = "protected ";
+ break;
+ case DEBUG_VISIBILITY_PRIVATE:
+ prefix = "private ";
+ break;
+ default:
+ prefix = "/* unknown visibility */ ";
+ break;
+ }
+
+ if (! prepend_type (info, prefix))
+ return false;
+
+ if (bitpos != 0)
+ {
+ print_vma (bitpos, ab, true, false);
+ if (! append_type (info, " /* bitpos ")
+ || ! append_type (info, ab)
+ || ! append_type (info, " */"))
+ return false;
+ }
+
+ /* Now the top of the stack is something like "public A / * bitpos
+ 10 * /". The next element on the stack is something like "class
+ xx { / * size 8 * /\n...". We want to substitute the top of the
+ stack in before the {. */
+ s = strchr (info->stack->next->type, '{');
+ assert (s != NULL);
+ --s;
+
+ /* If there is already a ':', then we already have a baseclass, and
+ we must append this one after a comma. */
+ for (l = info->stack->next->type; l != s; l++)
+ if (*l == ':')
+ break;
+ if (! prepend_type (info, l == s ? " : " : ", "))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
+ memcpy (n, info->stack->type, s - info->stack->type);
+ strcpy (n + (s - info->stack->type), t);
+ strcat (n, s);
+
+ free (info->stack->type);
+ info->stack->type = n;
+
+ free (t);
+
+ return true;
+}
+
+/* Start adding a method to a class. */
+
+static boolean
+pr_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ assert (info->stack != NULL);
+ info->stack->method = name;
+ return true;
+}
+
+/* Add a variant to a method. */
+
+static boolean
+pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
+ context)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean context;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *method_type;
+ char *context_type;
+
+ assert (info->stack != NULL);
+ assert (info->stack->next != NULL);
+
+ /* Put the const and volatile qualifiers on the type. */
+ if (volatilep)
+ {
+ if (! append_type (info, " volatile"))
+ return false;
+ }
+ if (constp)
+ {
+ if (! append_type (info, " const"))
+ return false;
+ }
+
+ /* Stick the name of the method into its type. */
+ if (! substitute_type (info,
+ (context
+ ? info->stack->next->next->method
+ : info->stack->next->method)))
+ return false;
+
+ /* Get the type. */
+ method_type = pop_type (info);
+ if (method_type == NULL)
+ return false;
+
+ /* Pull off the context type if there is one. */
+ if (! context)
+ context_type = NULL;
+ else
+ {
+ context_type = pop_type (info);
+ if (context_type == NULL)
+ return false;
+ }
+
+ /* Now the top of the stack is the class. */
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ if (! append_type (info, method_type)
+ || ! append_type (info, " /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " "))
+ return false;
+ if (context || voffset != 0)
+ {
+ char ab[20];
+
+ if (context)
+ {
+ if (! append_type (info, "context ")
+ || ! append_type (info, context_type)
+ || ! append_type (info, " "))
+ return false;
+ }
+ print_vma (voffset, ab, true, false);
+ if (! append_type (info, "voffset ")
+ || ! append_type (info, ab))
+ return false;
+ }
+
+ return (append_type (info, " */;\n")
+ && indent_type (info));
+}
+
+/* Add a static variant to a method. */
+
+static boolean
+pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *method_type;
+
+ assert (info->stack != NULL);
+ assert (info->stack->next != NULL);
+ assert (info->stack->next->method != NULL);
+
+ /* Put the const and volatile qualifiers on the type. */
+ if (volatilep)
+ {
+ if (! append_type (info, " volatile"))
+ return false;
+ }
+ if (constp)
+ {
+ if (! append_type (info, " const"))
+ return false;
+ }
+
+ /* Mark it as static. */
+ if (! prepend_type (info, "static "))
+ return false;
+
+ /* Stick the name of the method into its type. */
+ if (! substitute_type (info, info->stack->next->method))
+ return false;
+
+ /* Get the type. */
+ method_type = pop_type (info);
+ if (method_type == NULL)
+ return false;
+
+ /* Now the top of the stack is the class. */
+
+ if (! pr_fix_visibility (info, visibility))
+ return false;
+
+ return (append_type (info, method_type)
+ && append_type (info, " /* ")
+ && append_type (info, physname)
+ && append_type (info, " */;\n")
+ && indent_type (info));
+}
+
+/* Finish up a method. */
+
+static boolean
+pr_class_end_method (p)
+ PTR p;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ info->stack->method = NULL;
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+pr_end_class_type (p)
+ PTR p;
+{
+ return pr_end_struct_type (p);
+}
+
+/* Push a type on the stack using a typedef name. */
+
+static boolean
+pr_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ return push_type (info, name);
+}
+
+/* Push a type on the stack using a tag name. */
+
+static boolean
+pr_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ const char *t, *tag;
+ char idbuf[20];
+
+ switch (kind)
+ {
+ case DEBUG_KIND_STRUCT:
+ t = "struct ";
+ break;
+ case DEBUG_KIND_UNION:
+ t = "union ";
+ break;
+ case DEBUG_KIND_ENUM:
+ t = "enum ";
+ break;
+ case DEBUG_KIND_CLASS:
+ t = "class ";
+ break;
+ case DEBUG_KIND_UNION_CLASS:
+ t = "union class ";
+ break;
+ default:
+ abort ();
+ return false;
+ }
+
+ if (! push_type (info, t))
+ return false;
+ if (name != NULL)
+ tag = name;
+ else
+ {
+ sprintf (idbuf, "%%anon%u", id);
+ tag = idbuf;
+ }
+
+ if (! append_type (info, tag))
+ return false;
+ if (name != NULL && kind != DEBUG_KIND_ENUM)
+ {
+ sprintf (idbuf, " /* id %u */", id);
+ if (! append_type (info, idbuf))
+ return false;
+ }
+
+ return true;
+}
+
+/* Output a typedef. */
+
+static boolean
+pr_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *s;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ s = pop_type (info);
+ if (s == NULL)
+ return false;
+
+ indent (info);
+ fprintf (info->f, "typedef %s;\n", s);
+
+ free (s);
+
+ return true;
+}
+
+/* Output a tag. The tag should already be in the string on the
+ stack, so all we have to do here is print it out. */
+
+/*ARGSUSED*/
+static boolean
+pr_tag (p, name)
+ PTR p;
+ const char *name;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ indent (info);
+ fprintf (info->f, "%s;\n", t);
+
+ free (t);
+
+ return true;
+}
+
+/* Output an integer constant. */
+
+static boolean
+pr_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+
+ indent (info);
+ print_vma (val, ab, false, false);
+ fprintf (info->f, "const int %s = %s;\n", name, ab);
+ return true;
+}
+
+/* Output a floating point constant. */
+
+static boolean
+pr_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+
+ indent (info);
+ fprintf (info->f, "const double %s = %g;\n", name, val);
+ return true;
+}
+
+/* Output a typed constant. */
+
+static boolean
+pr_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ char ab[20];
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ indent (info);
+ print_vma (val, ab, false, false);
+ fprintf (info->f, "const %s %s = %s;\n", t, name, ab);
+
+ free (t);
+
+ return true;
+}
+
+/* Output a variable. */
+
+static boolean
+pr_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ char ab[20];
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ indent (info);
+ switch (kind)
+ {
+ case DEBUG_STATIC:
+ case DEBUG_LOCAL_STATIC:
+ fprintf (info->f, "static ");
+ break;
+ case DEBUG_REGISTER:
+ fprintf (info->f, "register ");
+ break;
+ default:
+ break;
+ }
+ print_vma (val, ab, true, true);
+ fprintf (info->f, "%s /* %s */;\n", t, ab);
+
+ free (t);
+
+ return true;
+}
+
+/* Start outputting a function. */
+
+static boolean
+pr_start_function (p, name, global)
+ PTR p;
+ const char *name;
+ boolean global;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ indent (info);
+ if (! global)
+ fprintf (info->f, "static ");
+ fprintf (info->f, "%s (", t);
+
+ info->parameter = 1;
+
+ return true;
+}
+
+/* Output a function parameter. */
+
+static boolean
+pr_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char *t;
+ char ab[20];
+
+ if (kind == DEBUG_PARM_REFERENCE
+ || kind == DEBUG_PARM_REF_REG)
+ {
+ if (! pr_reference_type (p))
+ return false;
+ }
+
+ if (! substitute_type (info, name))
+ return false;
+
+ t = pop_type (info);
+ if (t == NULL)
+ return false;
+
+ if (info->parameter != 1)
+ fprintf (info->f, ", ");
+
+ if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
+ fprintf (info->f, "register ");
+
+ print_vma (val, ab, true, true);
+ fprintf (info->f, "%s /* %s */", t, ab);
+
+ free (t);
+
+ ++info->parameter;
+
+ return true;
+}
+
+/* Start writing out a block. */
+
+static boolean
+pr_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+
+ if (info->parameter > 0)
+ {
+ fprintf (info->f, ")\n");
+ info->parameter = 0;
+ }
+
+ indent (info);
+ print_vma (addr, ab, true, true);
+ fprintf (info->f, "{ /* %s */\n", ab);
+
+ info->indent += 2;
+
+ return true;
+}
+
+/* Write out line number information. */
+
+static boolean
+pr_lineno (p, filename, lineno, addr)
+ PTR p;
+ const char *filename;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+
+ indent (info);
+ print_vma (addr, ab, true, true);
+ fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab);
+
+ return true;
+}
+
+/* Finish writing out a block. */
+
+static boolean
+pr_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct pr_handle *info = (struct pr_handle *) p;
+ char ab[20];
+
+ info->indent -= 2;
+
+ indent (info);
+ print_vma (addr, ab, true, true);
+ fprintf (info->f, "} /* %s */\n", ab);
+
+ return true;
+}
+
+/* Finish writing out a function. */
+
+/*ARGSUSED*/
+static boolean
+pr_end_function (p)
+ PTR p;
+{
+ return true;
+}
diff --git a/binutils/ranlib.1 b/binutils/ranlib.1
new file mode 100644
index 00000000000..7efb5c8e850
--- /dev/null
+++ b/binutils/ranlib.1
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1991 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH ranlib 1 "5 November 1991" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+ranlib \- generate index to archive.
+
+.SH SYNOPSIS
+.hy 0
+.na
+.B ranlib \c
+.RB "[\|" \-v | \-V "\|]"
+.I archive\c
+\&
+.ad b
+.hy 1
+.SH DESCRIPTION
+.B ranlib
+generates an index to the contents of an archive, and
+stores it in the archive. The index lists each symbol defined by a
+member of an archive that is a relocatable object file.
+.PP
+You may use
+.RB ` "nm \-s" '
+or
+.RB ` "nm \-\-print-armap" '
+to list this index.
+.PP
+An archive with such an index speeds up linking to the library, and
+allows routines in the library to call each other without regard to
+their placement in the archive.
+.PP
+The GNU
+.B ranlib
+program is another form of GNU
+.BR ar ;
+running
+.B ranlib
+is completely equivalent to executing
+.RB ` "ar \-s" '.
+
+.SH OPTIONS
+.TP
+.B \-v
+Print the version number of
+.B ranlib
+and exit.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (October 1991);
+.BR ar "(" 1 "),"
+.BR nm "(" 1 ")."
+
+
+.SH COPYING
+Copyright (c) 1991 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/ranlib.sh b/binutils/ranlib.sh
new file mode 100755
index 00000000000..2b6fbc479c6
--- /dev/null
+++ b/binutils/ranlib.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# A simple ranlib script, to use less disk space than a ranlib program.
+ar s $1
diff --git a/binutils/rclex.l b/binutils/rclex.l
new file mode 100644
index 00000000000..06a66077f28
--- /dev/null
+++ b/binutils/rclex.l
@@ -0,0 +1,465 @@
+%{ /* rclex.l -- lexer for Windows rc files parser */
+/* Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This is a lex input file which generates a lexer used by the
+ Windows rc file parser. It basically just recognized a bunch of
+ keywords. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windres.h"
+#include "rcparse.h"
+
+#include <ctype.h>
+#include <assert.h>
+
+/* Whether we are in rcdata mode, in which we returns the lengths of
+ strings. */
+
+static int rcdata_mode;
+
+/* List of allocated strings. */
+
+struct alloc_string
+{
+ struct alloc_string *next;
+ char *s;
+};
+
+static struct alloc_string *strings;
+
+/* Local functions. */
+
+static void cpp_line PARAMS ((const char *));
+static char *handle_quotes PARAMS ((const char *, unsigned long *));
+static char *get_string PARAMS ((int));
+
+%}
+
+%%
+
+"BEGIN" { return BEG; }
+"{" { return BEG; }
+"END" { return END; }
+"}" { return END; }
+"ACCELERATORS" { return ACCELERATORS; }
+"VIRTKEY" { return VIRTKEY; }
+"ASCII" { return ASCII; }
+"NOINVERT" { return NOINVERT; }
+"SHIFT" { return SHIFT; }
+"CONTROL" { return CONTROL; }
+"ALT" { return ALT; }
+"BITMAP" { return BITMAP; }
+"CURSOR" { return CURSOR; }
+"DIALOG" { return DIALOG; }
+"DIALOGEX" { return DIALOGEX; }
+"EXSTYLE" { return EXSTYLE; }
+"CAPTION" { return CAPTION; }
+"CLASS" { return CLASS; }
+"STYLE" { return STYLE; }
+"AUTO3STATE" { return AUTO3STATE; }
+"AUTOCHECKBOX" { return AUTOCHECKBOX; }
+"AUTORADIOBUTTON" { return AUTORADIOBUTTON; }
+"CHECKBOX" { return CHECKBOX; }
+"COMBOBOX" { return COMBOBOX; }
+"CTEXT" { return CTEXT; }
+"DEFPUSHBUTTON" { return DEFPUSHBUTTON; }
+"EDITTEXT" { return EDITTEXT; }
+"GROUPBOX" { return GROUPBOX; }
+"LISTBOX" { return LISTBOX; }
+"LTEXT" { return LTEXT; }
+"PUSHBOX" { return PUSHBOX; }
+"PUSHBUTTON" { return PUSHBUTTON; }
+"RADIOBUTTON" { return RADIOBUTTON; }
+"RTEXT" { return RTEXT; }
+"SCROLLBAR" { return SCROLLBAR; }
+"STATE3" { return STATE3; }
+"USERBUTTON" { return USERBUTTON; }
+"BEDIT" { return BEDIT; }
+"HEDIT" { return HEDIT; }
+"IEDIT" { return IEDIT; }
+"FONT" { return FONT; }
+"ICON" { return ICON; }
+"LANGUAGE" { return LANGUAGE; }
+"CHARACTERISTICS" { return CHARACTERISTICS; }
+"VERSION" { return VERSIONK; }
+"MENU" { return MENU; }
+"MENUEX" { return MENUEX; }
+"MENUITEM" { return MENUITEM; }
+"SEPARATOR" { return SEPARATOR; }
+"POPUP" { return POPUP; }
+"CHECKED" { return CHECKED; }
+"GRAYED" { return GRAYED; }
+"HELP" { return HELP; }
+"INACTIVE" { return INACTIVE; }
+"MENUBARBREAK" { return MENUBARBREAK; }
+"MENUBREAK" { return MENUBREAK; }
+"MESSAGETABLE" { return MESSAGETABLE; }
+"RCDATA" { return RCDATA; }
+"STRINGTABLE" { return STRINGTABLE; }
+"VERSIONINFO" { return VERSIONINFO; }
+"FILEVERSION" { return FILEVERSION; }
+"PRODUCTVERSION" { return PRODUCTVERSION; }
+"FILEFLAGSMASK" { return FILEFLAGSMASK; }
+"FILEFLAGS" { return FILEFLAGS; }
+"FILEOS" { return FILEOS; }
+"FILETYPE" { return FILETYPE; }
+"FILESUBTYPE" { return FILESUBTYPE; }
+"VALUE" { return VALUE; }
+"MOVEABLE" { return MOVEABLE; }
+"FIXED" { return FIXED; }
+"PURE" { return PURE; }
+"IMPURE" { return IMPURE; }
+"PRELOAD" { return PRELOAD; }
+"LOADONCALL" { return LOADONCALL; }
+"DISCARDABLE" { return DISCARDABLE; }
+"NOT" { return NOT; }
+
+"BLOCK"[ \t\n]*"\""[^\#\n]*"\"" {
+ char *s, *send;
+
+ /* This is a hack to let us parse version
+ information easily. */
+
+ s = strchr (yytext, '"');
+ ++s;
+ send = strchr (s, '"');
+ if (strncmp (s, "StringFileInfo",
+ sizeof "StringFileInfo" - 1) == 0
+ && s + sizeof "StringFileInfo" - 1 == send)
+ return BLOCKSTRINGFILEINFO;
+ else if (strncmp (s, "VarFileInfo",
+ sizeof "VarFileInfo" - 1) == 0
+ && s + sizeof "VarFileInfo" - 1 == send)
+ return BLOCKVARFILEINFO;
+ else
+ {
+ char *r;
+
+ r = get_string (send - s + 1);
+ strncpy (r, s, send - s);
+ r[send - s] = '\0';
+ yylval.s = r;
+ return BLOCK;
+ }
+ }
+
+"#"[^\n]* {
+ cpp_line (yytext);
+ }
+
+[0-9][x0-9A-Fa-f]*L {
+ yylval.i.val = strtoul (yytext, 0, 0);
+ yylval.i.dword = 1;
+ return NUMBER;
+ }
+
+[0-9][x0-9A-Fa-f]* {
+ yylval.i.val = strtoul (yytext, 0, 0);
+ yylval.i.dword = 0;
+ return NUMBER;
+ }
+
+("\""[^\"\n]*"\""[ \t]*)+ {
+ char *s;
+ unsigned long length;
+
+ s = handle_quotes (yytext, &length);
+ if (! rcdata_mode)
+ {
+ yylval.s = s;
+ return QUOTEDSTRING;
+ }
+ else
+ {
+ yylval.ss.length = length;
+ yylval.ss.s = s;
+ return SIZEDSTRING;
+ }
+ }
+
+[A-Za-z][^ ,\t\r\n]* {
+ char *s;
+
+ /* I rejected comma in a string in order to
+ handle VIRTKEY, CONTROL in an accelerator
+ resource. This means that an unquoted
+ file name can not contain a comma. I
+ don't know what rc permits. */
+
+ s = get_string (strlen (yytext) + 1);
+ strcpy (s, yytext);
+ yylval.s = s;
+ return STRING;
+ }
+
+[\n] { ++rc_lineno; }
+[ \t\r]+ { /* ignore whitespace */ }
+. { return *yytext; }
+
+%%
+#ifndef yywrap
+/* This is needed for some versions of lex. */
+int yywrap ()
+{
+ return 1;
+}
+#endif
+
+/* Handle a C preprocessor line. */
+
+static void
+cpp_line (s)
+ const char *s;
+{
+ int line;
+ char *send, *fn;
+
+ ++s;
+ while (isspace ((unsigned char) *s))
+ ++s;
+
+ line = strtol (s, &send, 0);
+ if (*send != '\0' && ! isspace ((unsigned char) *send))
+ return;
+
+ /* Subtract 1 because we are about to count the newline. */
+ rc_lineno = line - 1;
+
+ s = send;
+ while (isspace ((unsigned char) *s))
+ ++s;
+
+ if (*s != '"')
+ return;
+
+ ++s;
+ send = strchr (s, '"');
+ if (send == NULL)
+ return;
+
+ fn = (char *) xmalloc (send - s + 1);
+ strncpy (fn, s, send - s);
+ fn[send - s] = '\0';
+
+ free (rc_filename);
+ rc_filename = fn;
+}
+
+/* Handle a quoted string. The quotes are stripped. A pair of quotes
+ in a string are turned into a single quote. Adjacent strings are
+ merged separated by whitespace are merged, as in C. */
+
+static char *
+handle_quotes (input, len)
+ const char *input;
+ unsigned long *len;
+{
+ char *ret, *s;
+ const char *t;
+ int ch;
+
+ ret = get_string (strlen (input) + 1);
+
+ s = ret;
+ t = input;
+ if (*t == '"')
+ ++t;
+ while (*t != '\0')
+ {
+ if (*t == '\\')
+ {
+ ++t;
+ switch (*t)
+ {
+ case '\0':
+ rcparse_warning ("backslash at end of string");
+ break;
+
+ case '\"':
+ rcparse_warning ("use \"\" to put \" in a string");
+ break;
+
+ case 'a':
+ *s++ = ESCAPE_A;
+ ++t;
+ break;
+
+ case 'b':
+ *s++ = ESCAPE_B;
+ ++t;
+ break;
+
+ case 'f':
+ *s++ = ESCAPE_F;
+ ++t;
+ break;
+
+ case 'n':
+ *s++ = ESCAPE_N;
+ ++t;
+ break;
+
+ case 'r':
+ *s++ = ESCAPE_R;
+ ++t;
+ break;
+
+ case 't':
+ *s++ = ESCAPE_T;
+ ++t;
+ break;
+
+ case 'v':
+ *s++ = ESCAPE_V;
+ ++t;
+ break;
+
+ case '\\':
+ *s++ = *t++;
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ ch = *t - '0';
+ ++t;
+ if (*t >= '0' && *t <= '7')
+ {
+ ch = (ch << 3) | (*t - '0');
+ ++t;
+ if (*t >= '0' && *t <= '7')
+ {
+ ch = (ch << 3) | (*t - '0');
+ ++t;
+ }
+ }
+ *s++ = ch;
+ break;
+
+ case 'x':
+ ++t;
+ ch = 0;
+ while (1)
+ {
+ if (*t >= '0' && *t <= '9')
+ ch = (ch << 4) | (*t - '0');
+ else if (*t >= 'a' && *t <= 'f')
+ ch = (ch << 4) | (*t - 'a');
+ else if (*t >= 'A' && *t <= 'F')
+ ch = (ch << 4) | (*t - 'A');
+ else
+ break;
+ ++t;
+ }
+ *s++ = ch;
+ break;
+
+ default:
+ rcparse_warning ("unrecognized escape sequence");
+ *s++ = '\\';
+ *s++ = *t++;
+ break;
+ }
+ }
+ else if (*t != '"')
+ *s++ = *t++;
+ else if (t[1] == '\0')
+ break;
+ else if (t[1] == '"')
+ {
+ *s++ = '"';
+ t += 2;
+ }
+ else
+ {
+ ++t;
+ assert (isspace ((unsigned char) *t));
+ while (isspace ((unsigned char) *t))
+ ++t;
+ if (*t == '\0')
+ break;
+ assert (*t == '"');
+ ++t;
+ }
+ }
+
+ *s = '\0';
+
+ *len = s - ret;
+
+ return ret;
+}
+
+/* Allocate a string of a given length. */
+
+static char *
+get_string (len)
+ int len;
+{
+ struct alloc_string *as;
+
+ as = (struct alloc_string *) xmalloc (sizeof *as);
+ as->s = xmalloc (len);
+
+ as->next = strings;
+ strings = as->next;
+
+ return as->s;
+}
+
+/* Discard all the strings we have allocated. The parser calls this
+ when it no longer needs them. */
+
+void
+rcparse_discard_strings ()
+{
+ struct alloc_string *as;
+
+ as = strings;
+ while (as != NULL)
+ {
+ struct alloc_string *n;
+
+ free (as->s);
+ n = as->next;
+ free (as);
+ as = n;
+ }
+
+ strings = NULL;
+}
+
+/* Enter rcdata mode. */
+
+void
+rcparse_rcdata ()
+{
+ rcdata_mode = 1;
+}
+
+/* Go back to normal mode from rcdata mode. */
+
+void
+rcparse_normal ()
+{
+ rcdata_mode = 0;
+}
diff --git a/binutils/rcparse.y b/binutils/rcparse.y
new file mode 100644
index 00000000000..67079a5fd81
--- /dev/null
+++ b/binutils/rcparse.y
@@ -0,0 +1,1617 @@
+%{ /* rcparse.y -- parser for Windows rc files
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This is a parser for Windows rc files. It is based on the parser
+ by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windres.h"
+
+#include <ctype.h>
+
+/* The current language. */
+
+static unsigned short language;
+
+/* The resource information during a sub statement. */
+
+static struct res_res_info sub_res_info;
+
+/* Dialog information. This is built by the nonterminals styles and
+ controls. */
+
+static struct dialog dialog;
+
+/* This is used when building a style. It is modified by the
+ nonterminal styleexpr. */
+
+static unsigned long style;
+
+/* These are used when building a control. They are set before using
+ control_params. */
+
+static unsigned long base_style;
+static unsigned long default_style;
+static unsigned long class;
+
+%}
+
+%union
+{
+ struct accelerator acc;
+ struct accelerator *pacc;
+ struct dialog_control *dialog_control;
+ struct menuitem *menuitem;
+ struct
+ {
+ struct rcdata_item *first;
+ struct rcdata_item *last;
+ } rcdata;
+ struct rcdata_item *rcdata_item;
+ struct stringtable_data *stringtable;
+ struct fixed_versioninfo *fixver;
+ struct ver_info *verinfo;
+ struct ver_stringinfo *verstring;
+ struct ver_varinfo *vervar;
+ struct res_id id;
+ struct res_res_info res_info;
+ struct
+ {
+ unsigned short on;
+ unsigned short off;
+ } memflags;
+ struct
+ {
+ unsigned long val;
+ /* Nonzero if this number was explicitly specified as long. */
+ int dword;
+ } i;
+ unsigned long il;
+ unsigned short is;
+ const char *s;
+ struct
+ {
+ unsigned long length;
+ const char *s;
+ } ss;
+};
+
+%token BEG END
+%token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
+%token BITMAP
+%token CURSOR
+%token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
+%token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
+%token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
+%token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
+%token BEDIT HEDIT IEDIT
+%token FONT
+%token ICON
+%token LANGUAGE CHARACTERISTICS VERSIONK
+%token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
+%token MENUBARBREAK MENUBREAK
+%token MESSAGETABLE
+%token RCDATA
+%token STRINGTABLE
+%token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
+%token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
+%token VALUE
+%token <s> BLOCK
+%token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
+%token NOT
+%token <s> QUOTEDSTRING STRING
+%token <i> NUMBER
+%token <ss> SIZEDSTRING
+
+%type <pacc> acc_entries
+%type <acc> acc_entry acc_event
+%type <dialog_control> control control_params
+%type <menuitem> menuitems menuitem menuexitems menuexitem
+%type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
+%type <rcdata_item> opt_control_data
+%type <fixver> fixedverinfo
+%type <verinfo> verblocks
+%type <verstring> vervals
+%type <vervar> vertrans
+%type <res_info> suboptions memflags_move_discard memflags_move
+%type <memflags> memflag
+%type <id> id
+%type <il> exstyle parennumber
+%type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
+%type <is> acc_options acc_option menuitem_flags menuitem_flag
+%type <s> optstringc file_name
+%type <i> sizednumexpr sizedposnumexpr
+
+%left '|'
+%left '^'
+%left '&'
+%left '+' '-'
+%left '*' '/' '%'
+%right '~' NEG
+
+%%
+
+input:
+ /* empty */
+ | input newcmd accelerator
+ | input newcmd bitmap
+ | input newcmd cursor
+ | input newcmd dialog
+ | input newcmd font
+ | input newcmd icon
+ | input newcmd language
+ | input newcmd menu
+ | input newcmd menuex
+ | input newcmd messagetable
+ | input newcmd rcdata
+ | input newcmd stringtable
+ | input newcmd user
+ | input newcmd versioninfo
+ ;
+
+newcmd:
+ /* empty */
+ {
+ rcparse_discard_strings ();
+ }
+ ;
+
+/* Accelerator resources. */
+
+accelerator:
+ id ACCELERATORS suboptions BEG acc_entries END
+ {
+ define_accelerator ($1, &$3, $5);
+ }
+ ;
+
+acc_entries:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | acc_entries acc_entry
+ {
+ struct accelerator *a;
+
+ a = (struct accelerator *) res_alloc (sizeof *a);
+ *a = $2;
+ if ($1 == NULL)
+ $$ = a;
+ else
+ {
+ struct accelerator **pp;
+
+ for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = a;
+ $$ = $1;
+ }
+ }
+ ;
+
+acc_entry:
+ acc_event cposnumexpr
+ {
+ $$ = $1;
+ $$.id = $2;
+ }
+ | acc_event cposnumexpr ',' acc_options
+ {
+ $$ = $1;
+ $$.id = $2;
+ $$.flags |= $4;
+ if (($$.flags & ACC_VIRTKEY) == 0
+ && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0)
+ rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
+ }
+ ;
+
+acc_event:
+ QUOTEDSTRING
+ {
+ const char *s = $1;
+ char ch;
+
+ $$.next = NULL;
+ $$.id = 0;
+ ch = *s;
+ if (ch != '^')
+ $$.flags = 0;
+ else
+ {
+ $$.flags = ACC_CONTROL | ACC_VIRTKEY;
+ ++s;
+ ch = *s;
+ ch = toupper ((unsigned char) ch);
+ }
+ $$.key = ch;
+ if (s[1] != '\0')
+ rcparse_warning (_("accelerator should only be one character"));
+ }
+ | posnumexpr
+ {
+ $$.next = NULL;
+ $$.flags = 0;
+ $$.id = 0;
+ $$.key = $1;
+ }
+ ;
+
+acc_options:
+ acc_option
+ {
+ $$ = $1;
+ }
+ | acc_options ',' acc_option
+ {
+ $$ = $1 | $3;
+ }
+ /* I've had one report that the comma is optional. */
+ | acc_options acc_option
+ {
+ $$ = $1 | $2;
+ }
+ ;
+
+acc_option:
+ VIRTKEY
+ {
+ $$ = ACC_VIRTKEY;
+ }
+ | ASCII
+ {
+ /* This is just the absence of VIRTKEY. */
+ $$ = 0;
+ }
+ | NOINVERT
+ {
+ $$ = ACC_NOINVERT;
+ }
+ | SHIFT
+ {
+ $$ = ACC_SHIFT;
+ }
+ | CONTROL
+ {
+ $$ = ACC_CONTROL;
+ }
+ | ALT
+ {
+ $$ = ACC_ALT;
+ }
+ ;
+
+/* Bitmap resources. */
+
+bitmap:
+ id BITMAP memflags_move file_name
+ {
+ define_bitmap ($1, &$3, $4);
+ }
+ ;
+
+/* Cursor resources. */
+
+cursor:
+ id CURSOR memflags_move_discard file_name
+ {
+ define_cursor ($1, &$3, $4);
+ }
+ ;
+
+/* Dialog resources. */
+
+dialog:
+ id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
+ cnumexpr
+ {
+ memset (&dialog, 0, sizeof dialog);
+ dialog.x = $5;
+ dialog.y = $6;
+ dialog.width = $7;
+ dialog.height = $8;
+ dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
+ dialog.exstyle = $4;
+ dialog.menu.named = 1;
+ dialog.class.named = 1;
+ dialog.font = NULL;
+ dialog.ex = NULL;
+ dialog.controls = NULL;
+ sub_res_info = $3;
+ }
+ styles BEG controls END
+ {
+ define_dialog ($1, &sub_res_info, &dialog);
+ }
+ | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
+ cnumexpr
+ {
+ memset (&dialog, 0, sizeof dialog);
+ dialog.x = $5;
+ dialog.y = $6;
+ dialog.width = $7;
+ dialog.height = $8;
+ dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
+ dialog.exstyle = $4;
+ dialog.menu.named = 1;
+ dialog.class.named = 1;
+ dialog.font = NULL;
+ dialog.ex = ((struct dialog_ex *)
+ res_alloc (sizeof (struct dialog_ex)));
+ memset (dialog.ex, 0, sizeof (struct dialog_ex));
+ dialog.controls = NULL;
+ sub_res_info = $3;
+ }
+ styles BEG controls END
+ {
+ define_dialog ($1, &sub_res_info, &dialog);
+ }
+ | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
+ cnumexpr cnumexpr
+ {
+ memset (&dialog, 0, sizeof dialog);
+ dialog.x = $5;
+ dialog.y = $6;
+ dialog.width = $7;
+ dialog.height = $8;
+ dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
+ dialog.exstyle = $4;
+ dialog.menu.named = 1;
+ dialog.class.named = 1;
+ dialog.font = NULL;
+ dialog.ex = ((struct dialog_ex *)
+ res_alloc (sizeof (struct dialog_ex)));
+ memset (dialog.ex, 0, sizeof (struct dialog_ex));
+ dialog.ex->help = $9;
+ dialog.controls = NULL;
+ sub_res_info = $3;
+ }
+ styles BEG controls END
+ {
+ define_dialog ($1, &sub_res_info, &dialog);
+ }
+ ;
+
+exstyle:
+ /* empty */
+ {
+ $$ = 0;
+ }
+ | EXSTYLE '=' numexpr
+ {
+ $$ = $3;
+ }
+ ;
+
+styles:
+ /* empty */
+ | styles CAPTION QUOTEDSTRING
+ {
+ unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
+ }
+ | styles CLASS id
+ {
+ dialog.class = $3;
+ }
+ | styles STYLE
+ { style = dialog.style; }
+ styleexpr
+ {
+ dialog.style = style;
+ }
+ | styles EXSTYLE numexpr
+ {
+ dialog.exstyle = $3;
+ }
+ | styles FONT numexpr ',' QUOTEDSTRING
+ {
+ dialog.style |= DS_SETFONT;
+ dialog.pointsize = $3;
+ unicode_from_ascii ((int *) NULL, &dialog.font, $5);
+ }
+ | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
+ {
+ dialog.style |= DS_SETFONT;
+ dialog.pointsize = $3;
+ unicode_from_ascii ((int *) NULL, &dialog.font, $5);
+ if (dialog.ex == NULL)
+ rcparse_warning (_("extended FONT requires DIALOGEX"));
+ else
+ {
+ dialog.ex->weight = $6;
+ dialog.ex->italic = $7;
+ }
+ }
+ | styles MENU id
+ {
+ dialog.menu = $3;
+ }
+ | styles CHARACTERISTICS numexpr
+ {
+ sub_res_info.characteristics = $3;
+ }
+ | styles LANGUAGE numexpr cnumexpr
+ {
+ sub_res_info.language = $3 | ($4 << 8);
+ }
+ | styles VERSIONK numexpr
+ {
+ sub_res_info.version = $3;
+ }
+ ;
+
+controls:
+ /* empty */
+ | controls control
+ {
+ struct dialog_control **pp;
+
+ for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = $2;
+ }
+ ;
+
+control:
+ AUTO3STATE
+ {
+ default_style = BS_AUTO3STATE | WS_TABSTOP;
+ base_style = BS_AUTO3STATE;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | AUTOCHECKBOX
+ {
+ default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
+ base_style = BS_AUTOCHECKBOX;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | AUTORADIOBUTTON
+ {
+ default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
+ base_style = BS_AUTORADIOBUTTON;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | BEDIT
+ {
+ default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ class = CTL_EDIT;
+ }
+ control_params
+ {
+ $$ = $3;
+ if (dialog.ex == NULL)
+ rcparse_warning (_("IEDIT requires DIALOGEX"));
+ res_string_to_id (&$$->class, "BEDIT");
+ }
+ | CHECKBOX
+ {
+ default_style = BS_CHECKBOX | WS_TABSTOP;
+ base_style = BS_CHECKBOX | WS_TABSTOP;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | COMBOBOX
+ {
+ default_style = CBS_SIMPLE | WS_TABSTOP;
+ base_style = 0;
+ class = CTL_COMBOBOX;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
+ cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
+ if ($11 != NULL)
+ {
+ if (dialog.ex == NULL)
+ rcparse_warning (_("control data requires DIALOGEX"));
+ $$->data = $11;
+ }
+ }
+ | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
+ cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
+ if (dialog.ex == NULL)
+ rcparse_warning (_("help ID requires DIALOGEX"));
+ $$->help = $11;
+ $$->data = $12;
+ }
+ | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
+ cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
+ if ($12 != NULL)
+ {
+ if (dialog.ex == NULL)
+ rcparse_warning ("control data requires DIALOGEX");
+ $$->data = $12;
+ }
+ $$->class.named = 1;
+ unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5);
+ }
+ | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
+ cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
+ if (dialog.ex == NULL)
+ rcparse_warning ("help ID requires DIALOGEX");
+ $$->help = $12;
+ $$->data = $13;
+ $$->class.named = 1;
+ unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5);
+ }
+ | CTEXT
+ {
+ default_style = SS_CENTER | WS_GROUP;
+ base_style = SS_CENTER;
+ class = CTL_STATIC;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | DEFPUSHBUTTON
+ {
+ default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
+ base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | EDITTEXT
+ {
+ default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ class = CTL_EDIT;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | GROUPBOX
+ {
+ default_style = BS_GROUPBOX;
+ base_style = BS_GROUPBOX;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | HEDIT
+ {
+ default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ class = CTL_EDIT;
+ }
+ control_params
+ {
+ $$ = $3;
+ if (dialog.ex == NULL)
+ rcparse_warning (_("IEDIT requires DIALOGEX"));
+ res_string_to_id (&$$->class, "HEDIT");
+ }
+ | ICON optstringc numexpr cnumexpr cnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $4, $5, 0, 0, CTL_STATIC,
+ SS_ICON | WS_CHILD | WS_VISIBLE, 0);
+ if ($6 != NULL)
+ {
+ if (dialog.ex == NULL)
+ rcparse_warning (_("control data requires DIALOGEX"));
+ $$->data = $6;
+ }
+ }
+ | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+ icon_styleexpr optcnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
+ style, $9);
+ if ($10 != NULL)
+ {
+ if (dialog.ex == NULL)
+ rcparse_warning (_("control data requires DIALOGEX"));
+ $$->data = $10;
+ }
+ }
+ | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+ icon_styleexpr cnumexpr cnumexpr opt_control_data
+ {
+ $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
+ style, $9);
+ if (dialog.ex == NULL)
+ rcparse_warning (_("help ID requires DIALOGEX"));
+ $$->help = $10;
+ $$->data = $11;
+ }
+ | IEDIT
+ {
+ default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
+ class = CTL_EDIT;
+ }
+ control_params
+ {
+ $$ = $3;
+ if (dialog.ex == NULL)
+ rcparse_warning (_("IEDIT requires DIALOGEX"));
+ res_string_to_id (&$$->class, "IEDIT");
+ }
+ | LISTBOX
+ {
+ default_style = LBS_NOTIFY | WS_BORDER;
+ base_style = LBS_NOTIFY | WS_BORDER;
+ class = CTL_LISTBOX;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | LTEXT
+ {
+ default_style = SS_LEFT | WS_GROUP;
+ base_style = SS_LEFT;
+ class = CTL_STATIC;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | PUSHBOX
+ {
+ default_style = BS_PUSHBOX | WS_TABSTOP;
+ base_style = BS_PUSHBOX;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | PUSHBUTTON
+ {
+ default_style = BS_PUSHBUTTON | WS_TABSTOP;
+ base_style = BS_PUSHBUTTON | WS_TABSTOP;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | RADIOBUTTON
+ {
+ default_style = BS_RADIOBUTTON | WS_TABSTOP;
+ base_style = BS_RADIOBUTTON;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | RTEXT
+ {
+ default_style = SS_RIGHT | WS_GROUP;
+ base_style = SS_RIGHT;
+ class = CTL_STATIC;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | SCROLLBAR
+ {
+ default_style = SBS_HORZ;
+ base_style = 0;
+ class = CTL_SCROLLBAR;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | STATE3
+ {
+ default_style = BS_3STATE | WS_TABSTOP;
+ base_style = BS_3STATE;
+ class = CTL_BUTTON;
+ }
+ control_params
+ {
+ $$ = $3;
+ }
+ | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
+ numexpr ',' numexpr ','
+ { style = WS_CHILD | WS_VISIBLE; }
+ styleexpr optcnumexpr
+ {
+ $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
+ style, $16);
+ }
+ ;
+
+/* Parameters for a control. The static variables DEFAULT_STYLE,
+ BASE_STYLE, and CLASS must be initialized before this nonterminal
+ is used. DEFAULT_STYLE is the style to use if no style expression
+ is specified. BASE_STYLE is the base style to use if a style
+ expression is specified; the style expression modifies the base
+ style. CLASS is the class of the control. */
+
+control_params:
+ optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+ opt_control_data
+ {
+ $$ = define_control ($1, $2, $3, $4, $5, $6, class,
+ default_style | WS_CHILD | WS_VISIBLE, 0);
+ if ($7 != NULL)
+ {
+ if (dialog.ex == NULL)
+ rcparse_warning (_("control data requires DIALOGEX"));
+ $$->data = $7;
+ }
+ }
+ | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+ control_params_styleexpr optcnumexpr opt_control_data
+ {
+ $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
+ if ($9 != NULL)
+ {
+ if (dialog.ex == NULL)
+ rcparse_warning (_("control data requires DIALOGEX"));
+ $$->data = $9;
+ }
+ }
+ | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+ control_params_styleexpr cnumexpr cnumexpr opt_control_data
+ {
+ $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
+ if (dialog.ex == NULL)
+ rcparse_warning (_("help ID requires DIALOGEX"));
+ $$->help = $9;
+ $$->data = $10;
+ }
+ ;
+
+optstringc:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | QUOTEDSTRING ','
+ {
+ $$ = $1;
+ }
+ ;
+
+opt_control_data:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | BEG optrcdata_data END
+ {
+ $$ = $2.first;
+ }
+ ;
+
+/* These only exist to parse a reduction out of a common case. */
+
+control_styleexpr:
+ ','
+ { style = WS_CHILD | WS_VISIBLE; }
+ styleexpr
+ ;
+
+icon_styleexpr:
+ ','
+ { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
+ styleexpr
+ ;
+
+control_params_styleexpr:
+ ','
+ { style = base_style | WS_CHILD | WS_VISIBLE; }
+ styleexpr
+ ;
+
+/* Font resources. */
+
+font:
+ id FONT memflags_move_discard file_name
+ {
+ define_font ($1, &$3, $4);
+ }
+ ;
+
+/* Icon resources. */
+
+icon:
+ id ICON memflags_move_discard file_name
+ {
+ define_icon ($1, &$3, $4);
+ }
+ ;
+
+/* Language command. This changes the static variable language, which
+ affects all subsequent resources. */
+
+language:
+ LANGUAGE numexpr cnumexpr
+ {
+ language = $2 | ($3 << 8);
+ }
+ ;
+
+/* Menu resources. */
+
+menu:
+ id MENU suboptions BEG menuitems END
+ {
+ define_menu ($1, &$3, $5);
+ }
+ ;
+
+menuitems:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | menuitems menuitem
+ {
+ if ($1 == NULL)
+ $$ = $2;
+ else
+ {
+ struct menuitem **pp;
+
+ for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = $2;
+ $$ = $1;
+ }
+ }
+ ;
+
+menuitem:
+ MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
+ {
+ $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
+ }
+ | MENUITEM SEPARATOR
+ {
+ $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
+ }
+ | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
+ {
+ $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
+ }
+ ;
+
+menuitem_flags:
+ /* empty */
+ {
+ $$ = 0;
+ }
+ | menuitem_flags ',' menuitem_flag
+ {
+ $$ = $1 | $3;
+ }
+ | menuitem_flags menuitem_flag
+ {
+ $$ = $1 | $2;
+ }
+ ;
+
+menuitem_flag:
+ CHECKED
+ {
+ $$ = MENUITEM_CHECKED;
+ }
+ | GRAYED
+ {
+ $$ = MENUITEM_GRAYED;
+ }
+ | HELP
+ {
+ $$ = MENUITEM_HELP;
+ }
+ | INACTIVE
+ {
+ $$ = MENUITEM_INACTIVE;
+ }
+ | MENUBARBREAK
+ {
+ $$ = MENUITEM_MENUBARBREAK;
+ }
+ | MENUBREAK
+ {
+ $$ = MENUITEM_MENUBREAK;
+ }
+ ;
+
+/* Menuex resources. */
+
+menuex:
+ id MENUEX suboptions BEG menuexitems END
+ {
+ define_menu ($1, &$3, $5);
+ }
+ ;
+
+menuexitems:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | menuexitems menuexitem
+ {
+ if ($1 == NULL)
+ $$ = $2;
+ else
+ {
+ struct menuitem **pp;
+
+ for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = $2;
+ $$ = $1;
+ }
+ }
+ ;
+
+menuexitem:
+ MENUITEM QUOTEDSTRING
+ {
+ $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
+ }
+ | MENUITEM QUOTEDSTRING cnumexpr
+ {
+ $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
+ }
+ | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
+ {
+ $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
+ }
+ | MENUITEM SEPARATOR
+ {
+ $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
+ }
+ | POPUP QUOTEDSTRING BEG menuexitems END
+ {
+ $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
+ }
+ | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
+ {
+ $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
+ }
+ | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
+ {
+ $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
+ }
+ | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
+ BEG menuexitems END
+ {
+ $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
+ }
+ ;
+
+/* Messagetable resources. */
+
+messagetable:
+ id MESSAGETABLE memflags_move file_name
+ {
+ define_messagetable ($1, &$3, $4);
+ }
+ ;
+
+/* Rcdata resources. */
+
+rcdata:
+ id RCDATA suboptions BEG optrcdata_data END
+ {
+ define_rcdata ($1, &$3, $5.first);
+ }
+ ;
+
+/* We use a different lexing algorithm, because rcdata strings may
+ contain embedded null bytes, and we need to know the length to use. */
+
+optrcdata_data:
+ {
+ rcparse_rcdata ();
+ }
+ optrcdata_data_int
+ {
+ rcparse_normal ();
+ $$ = $2;
+ }
+ ;
+
+optrcdata_data_int:
+ /* empty */
+ {
+ $$.first = NULL;
+ $$.last = NULL;
+ }
+ | rcdata_data
+ {
+ $$ = $1;
+ }
+ ;
+
+rcdata_data:
+ SIZEDSTRING
+ {
+ struct rcdata_item *ri;
+
+ ri = define_rcdata_string ($1.s, $1.length);
+ $$.first = ri;
+ $$.last = ri;
+ }
+ | sizednumexpr
+ {
+ struct rcdata_item *ri;
+
+ ri = define_rcdata_number ($1.val, $1.dword);
+ $$.first = ri;
+ $$.last = ri;
+ }
+ | rcdata_data ',' SIZEDSTRING
+ {
+ struct rcdata_item *ri;
+
+ ri = define_rcdata_string ($3.s, $3.length);
+ $$.first = $1.first;
+ $1.last->next = ri;
+ $$.last = ri;
+ }
+ | rcdata_data ',' sizednumexpr
+ {
+ struct rcdata_item *ri;
+
+ ri = define_rcdata_number ($3.val, $3.dword);
+ $$.first = $1.first;
+ $1.last->next = ri;
+ $$.last = ri;
+ }
+ ;
+
+/* Stringtable resources. */
+
+stringtable:
+ STRINGTABLE suboptions BEG
+ { sub_res_info = $2; }
+ string_data END
+ ;
+
+string_data:
+ /* empty */
+ | string_data numexpr QUOTEDSTRING
+ {
+ define_stringtable (&sub_res_info, $2, $3);
+ }
+ | string_data numexpr ',' QUOTEDSTRING
+ {
+ define_stringtable (&sub_res_info, $2, $4);
+ }
+ ;
+
+/* User defined resources. We accept general suboptions in the
+ file_name case to keep the parser happy. */
+
+user:
+ id id suboptions BEG optrcdata_data END
+ {
+ define_user_data ($1, $2, &$3, $5.first);
+ }
+ | id id suboptions file_name
+ {
+ define_user_file ($1, $2, &$3, $4);
+ }
+ ;
+
+/* Versioninfo resources. */
+
+versioninfo:
+ id VERSIONINFO fixedverinfo BEG verblocks END
+ {
+ define_versioninfo ($1, language, $3, $5);
+ }
+ ;
+
+fixedverinfo:
+ /* empty */
+ {
+ $$ = ((struct fixed_versioninfo *)
+ res_alloc (sizeof (struct fixed_versioninfo)));
+ memset ($$, 0, sizeof (struct fixed_versioninfo));
+ }
+ | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
+ {
+ $1->file_version_ms = ($3 << 16) | $4;
+ $1->file_version_ls = ($5 << 16) | $6;
+ $$ = $1;
+ }
+ | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
+ {
+ $1->product_version_ms = ($3 << 16) | $4;
+ $1->product_version_ls = ($5 << 16) | $6;
+ $$ = $1;
+ }
+ | fixedverinfo FILEFLAGSMASK numexpr
+ {
+ $1->file_flags_mask = $3;
+ $$ = $1;
+ }
+ | fixedverinfo FILEFLAGS numexpr
+ {
+ $1->file_flags = $3;
+ $$ = $1;
+ }
+ | fixedverinfo FILEOS numexpr
+ {
+ $1->file_os = $3;
+ $$ = $1;
+ }
+ | fixedverinfo FILETYPE numexpr
+ {
+ $1->file_type = $3;
+ $$ = $1;
+ }
+ | fixedverinfo FILESUBTYPE numexpr
+ {
+ $1->file_subtype = $3;
+ $$ = $1;
+ }
+ ;
+
+/* To handle verblocks successfully, the lexer handles BLOCK
+ specially. A BLOCK "StringFileInfo" is returned as
+ BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
+ BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
+ with the string as the value. */
+
+verblocks:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
+ {
+ $$ = append_ver_stringfileinfo ($1, $4, $6);
+ }
+ | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
+ {
+ $$ = append_ver_varfileinfo ($1, $5, $6);
+ }
+ ;
+
+vervals:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
+ {
+ $$ = append_verval ($1, $3, $5);
+ }
+ ;
+
+vertrans:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | vertrans cnumexpr cnumexpr
+ {
+ $$ = append_vertrans ($1, $2, $3);
+ }
+ ;
+
+/* A resource ID. */
+
+id:
+ posnumexpr
+ {
+ $$.named = 0;
+ $$.u.id = $1;
+ }
+ | STRING
+ {
+ char *copy, *s;
+
+ /* It seems that resource ID's are forced to upper case. */
+ copy = xstrdup ($1);
+ for (s = copy; *s != '\0'; s++)
+ if (islower ((unsigned char) *s))
+ *s = toupper ((unsigned char) *s);
+ res_string_to_id (&$$, copy);
+ free (copy);
+ }
+ ;
+
+/* Generic suboptions. These may appear before the BEGIN in any
+ multiline statement. */
+
+suboptions:
+ /* empty */
+ {
+ memset (&$$, 0, sizeof (struct res_res_info));
+ $$.language = language;
+ /* FIXME: Is this the right default? */
+ $$.memflags = MEMFLAG_MOVEABLE;
+ }
+ | suboptions memflag
+ {
+ $$ = $1;
+ $$.memflags |= $2.on;
+ $$.memflags &=~ $2.off;
+ }
+ | suboptions CHARACTERISTICS numexpr
+ {
+ $$ = $1;
+ $$.characteristics = $3;
+ }
+ | suboptions LANGUAGE numexpr cnumexpr
+ {
+ $$ = $1;
+ $$.language = $3 | ($4 << 8);
+ }
+ | suboptions VERSIONK numexpr
+ {
+ $$ = $1;
+ $$.version = $3;
+ }
+ ;
+
+/* Memory flags which default to MOVEABLE and DISCARDABLE. */
+
+memflags_move_discard:
+ /* empty */
+ {
+ memset (&$$, 0, sizeof (struct res_res_info));
+ $$.language = language;
+ $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
+ }
+ | memflags_move_discard memflag
+ {
+ $$ = $1;
+ $$.memflags |= $2.on;
+ $$.memflags &=~ $2.off;
+ }
+ ;
+
+/* Memory flags which default to MOVEABLE. */
+
+memflags_move:
+ /* empty */
+ {
+ memset (&$$, 0, sizeof (struct res_res_info));
+ $$.language = language;
+ $$.memflags = MEMFLAG_MOVEABLE;
+ }
+ | memflags_move memflag
+ {
+ $$ = $1;
+ $$.memflags |= $2.on;
+ $$.memflags &=~ $2.off;
+ }
+ ;
+
+/* Memory flags. This returns a struct with two integers, because we
+ sometimes want to set bits and we sometimes want to clear them. */
+
+memflag:
+ MOVEABLE
+ {
+ $$.on = MEMFLAG_MOVEABLE;
+ $$.off = 0;
+ }
+ | FIXED
+ {
+ $$.on = 0;
+ $$.off = MEMFLAG_MOVEABLE;
+ }
+ | PURE
+ {
+ $$.on = MEMFLAG_PURE;
+ $$.off = 0;
+ }
+ | IMPURE
+ {
+ $$.on = 0;
+ $$.off = MEMFLAG_PURE;
+ }
+ | PRELOAD
+ {
+ $$.on = MEMFLAG_PRELOAD;
+ $$.off = 0;
+ }
+ | LOADONCALL
+ {
+ $$.on = 0;
+ $$.off = MEMFLAG_PRELOAD;
+ }
+ | DISCARDABLE
+ {
+ $$.on = MEMFLAG_DISCARDABLE;
+ $$.off = 0;
+ }
+ ;
+
+/* A file name. */
+
+file_name:
+ QUOTEDSTRING
+ {
+ $$ = $1;
+ }
+ | STRING
+ {
+ $$ = $1;
+ }
+ ;
+
+/* A style expression. This changes the static variable STYLE. We do
+ it this way because rc appears to permit a style to be set to
+ something like
+ WS_GROUP | NOT WS_TABSTOP
+ to mean that a default of WS_TABSTOP should be removed. Anything
+ which wants to accept a style must first set STYLE to the default
+ value. The styleexpr nonterminal will change STYLE as specified by
+ the user. Note that we do not accept arbitrary expressions here,
+ just numbers separated by '|'. */
+
+styleexpr:
+ parennumber
+ {
+ style |= $1;
+ }
+ | NOT parennumber
+ {
+ style &=~ $2;
+ }
+ | styleexpr '|' parennumber
+ {
+ style |= $3;
+ }
+ | styleexpr '|' NOT parennumber
+ {
+ style &=~ $4;
+ }
+ ;
+
+parennumber:
+ NUMBER
+ {
+ $$ = $1.val;
+ }
+ | '(' numexpr ')'
+ {
+ $$ = $2;
+ }
+ ;
+
+/* An optional expression with a leading comma. */
+
+optcnumexpr:
+ /* empty */
+ {
+ $$ = 0;
+ }
+ | cnumexpr
+ {
+ $$ = $1;
+ }
+ ;
+
+/* An expression with a leading comma. */
+
+cnumexpr:
+ ',' numexpr
+ {
+ $$ = $2;
+ }
+ ;
+
+/* A possibly negated numeric expression. */
+
+numexpr:
+ sizednumexpr
+ {
+ $$ = $1.val;
+ }
+ ;
+
+/* A possibly negated expression with a size. */
+
+sizednumexpr:
+ NUMBER
+ {
+ $$ = $1;
+ }
+ | '(' sizednumexpr ')'
+ {
+ $$ = $2;
+ }
+ | '~' sizednumexpr %prec '~'
+ {
+ $$.val = ~ $2.val;
+ $$.dword = $2.dword;
+ }
+ | '-' sizednumexpr %prec NEG
+ {
+ $$.val = - $2.val;
+ $$.dword = $2.dword;
+ }
+ | sizednumexpr '*' sizednumexpr
+ {
+ $$.val = $1.val * $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '/' sizednumexpr
+ {
+ $$.val = $1.val / $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '%' sizednumexpr
+ {
+ $$.val = $1.val % $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '+' sizednumexpr
+ {
+ $$.val = $1.val + $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '-' sizednumexpr
+ {
+ $$.val = $1.val - $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '&' sizednumexpr
+ {
+ $$.val = $1.val & $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '^' sizednumexpr
+ {
+ $$.val = $1.val ^ $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizednumexpr '|' sizednumexpr
+ {
+ $$.val = $1.val | $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ ;
+
+/* An expression with a leading comma which does not use unary
+ negation. */
+
+cposnumexpr:
+ ',' posnumexpr
+ {
+ $$ = $2;
+ }
+ ;
+
+/* An expression which does not use unary negation. */
+
+posnumexpr:
+ sizedposnumexpr
+ {
+ $$ = $1.val;
+ }
+ ;
+
+/* An expression which does not use unary negation. We separate unary
+ negation to avoid parsing conflicts when two numeric expressions
+ appear consecutively. */
+
+sizedposnumexpr:
+ NUMBER
+ {
+ $$ = $1;
+ }
+ | '(' sizednumexpr ')'
+ {
+ $$ = $2;
+ }
+ | '~' sizednumexpr %prec '~'
+ {
+ $$.val = ~ $2.val;
+ $$.dword = $2.dword;
+ }
+ | sizedposnumexpr '*' sizednumexpr
+ {
+ $$.val = $1.val * $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '/' sizednumexpr
+ {
+ $$.val = $1.val / $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '%' sizednumexpr
+ {
+ $$.val = $1.val % $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '+' sizednumexpr
+ {
+ $$.val = $1.val + $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '-' sizednumexpr
+ {
+ $$.val = $1.val - $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '&' sizednumexpr
+ {
+ $$.val = $1.val & $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '^' sizednumexpr
+ {
+ $$.val = $1.val ^ $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ | sizedposnumexpr '|' sizednumexpr
+ {
+ $$.val = $1.val | $3.val;
+ $$.dword = $1.dword || $3.dword;
+ }
+ ;
+
+%%
+
+/* Set the language from the command line. */
+
+void
+rcparse_set_language (lang)
+ int lang;
+{
+ language = lang;
+}
diff --git a/binutils/rdcoff.c b/binutils/rdcoff.c
new file mode 100644
index 00000000000..ee68bc6d449
--- /dev/null
+++ b/binutils/rdcoff.c
@@ -0,0 +1,889 @@
+/* stabs.c -- Parse COFF debugging information
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains code which parses COFF debugging information. */
+
+#include "bfd.h"
+#include "coff/internal.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* FIXME: We should not need this BFD internal file. We need it for
+ the N_BTMASK, etc., values. */
+#include "libcoff.h"
+
+/* These macros extract the right mask and shifts for this BFD. They
+ assume that there is a local variable named ABFD. This is so that
+ macros like ISFCN and DECREF, from coff/internal.h, will work
+ without modification. */
+#define N_BTMASK (coff_data (abfd)->local_n_btmask)
+#define N_BTSHFT (coff_data (abfd)->local_n_btshft)
+#define N_TMASK (coff_data (abfd)->local_n_tmask)
+#define N_TSHIFT (coff_data (abfd)->local_n_tshift)
+
+/* This structure is used to hold the symbols, as well as the current
+ location within the symbols. */
+
+struct coff_symbols
+{
+ /* The symbols. */
+ asymbol **syms;
+ /* The number of symbols. */
+ long symcount;
+ /* The index of the current symbol. */
+ long symno;
+ /* The index of the current symbol in the COFF symbol table (where
+ each auxent counts as a symbol). */
+ long coff_symno;
+};
+
+/* The largest basic type we are prepared to handle. */
+
+#define T_MAX (T_LNGDBL)
+
+/* This structure is used to hold slots. */
+
+struct coff_slots
+{
+ /* Next set of slots. */
+ struct coff_slots *next;
+ /* Slots. */
+#define COFF_SLOTS (16)
+ debug_type slots[COFF_SLOTS];
+};
+
+/* This structure is used to map symbol indices to types. */
+
+struct coff_types
+{
+ /* Slots. */
+ struct coff_slots *slots;
+ /* Basic types. */
+ debug_type basic[T_MAX + 1];
+};
+
+static debug_type *coff_get_slot PARAMS ((struct coff_types *, int));
+static debug_type parse_coff_type
+ PARAMS ((bfd *, struct coff_symbols *, struct coff_types *, long, int,
+ union internal_auxent *, boolean, PTR));
+static debug_type parse_coff_base_type
+ PARAMS ((bfd *, struct coff_symbols *, struct coff_types *, long, int,
+ union internal_auxent *, PTR));
+static debug_type parse_coff_struct_type
+ PARAMS ((bfd *, struct coff_symbols *, struct coff_types *, int,
+ union internal_auxent *, PTR));
+static debug_type parse_coff_enum_type
+ PARAMS ((bfd *, struct coff_symbols *, struct coff_types *,
+ union internal_auxent *, PTR));
+static boolean parse_coff_symbol
+ PARAMS ((bfd *, struct coff_types *, asymbol *, long,
+ struct internal_syment *, PTR, debug_type, boolean));
+
+/* Return the slot for a type. */
+
+static debug_type *
+coff_get_slot (types, indx)
+ struct coff_types *types;
+ int indx;
+{
+ struct coff_slots **pps;
+
+ pps = &types->slots;
+
+ while (indx >= COFF_SLOTS)
+ {
+ if (*pps == NULL)
+ {
+ *pps = (struct coff_slots *) xmalloc (sizeof **pps);
+ memset (*pps, 0, sizeof **pps);
+ }
+ pps = &(*pps)->next;
+ indx -= COFF_SLOTS;
+ }
+
+ if (*pps == NULL)
+ {
+ *pps = (struct coff_slots *) xmalloc (sizeof **pps);
+ memset (*pps, 0, sizeof **pps);
+ }
+
+ return (*pps)->slots + indx;
+}
+
+/* Parse a COFF type code in NTYPE. */
+
+static debug_type
+parse_coff_type (abfd, symbols, types, coff_symno, ntype, pauxent, useaux,
+ dhandle)
+ bfd *abfd;
+ struct coff_symbols *symbols;
+ struct coff_types *types;
+ long coff_symno;
+ int ntype;
+ union internal_auxent *pauxent;
+ boolean useaux;
+ PTR dhandle;
+{
+ debug_type type;
+
+ if ((ntype & ~N_BTMASK) != 0)
+ {
+ int newtype;
+
+ newtype = DECREF (ntype);
+
+ if (ISPTR (ntype))
+ {
+ type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
+ pauxent, useaux, dhandle);
+ type = debug_make_pointer_type (dhandle, type);
+ }
+ else if (ISFCN (ntype))
+ {
+ type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
+ pauxent, useaux, dhandle);
+ type = debug_make_function_type (dhandle, type, (debug_type *) NULL,
+ false);
+ }
+ else if (ISARY (ntype))
+ {
+ int n;
+
+ if (pauxent == NULL)
+ n = 0;
+ else
+ {
+ unsigned short *dim;
+ int i;
+
+ /* FIXME: If pauxent->x_sym.x_tagndx.l == 0, gdb sets
+ the c_naux field of the syment to 0. */
+
+ /* Move the dimensions down, so that the next array
+ picks up the next one. */
+ dim = pauxent->x_sym.x_fcnary.x_ary.x_dimen;
+ n = dim[0];
+ for (i = 0; *dim != 0 && i < DIMNUM - 1; i++, dim++)
+ *dim = *(dim + 1);
+ *dim = 0;
+ }
+
+ type = parse_coff_type (abfd, symbols, types, coff_symno, newtype,
+ pauxent, false, dhandle);
+ type = debug_make_array_type (dhandle, type,
+ parse_coff_base_type (abfd, symbols,
+ types,
+ coff_symno,
+ T_INT,
+ NULL, dhandle),
+ 0, n - 1, false);
+ }
+ else
+ {
+ fprintf (stderr, _("%s: parse_coff_type: Bad type code 0x%x\n"),
+ program_name, ntype);
+ return DEBUG_TYPE_NULL;
+ }
+
+ return type;
+ }
+
+ if (pauxent != NULL && pauxent->x_sym.x_tagndx.l > 0)
+ {
+ debug_type *slot;
+
+ /* This is a reference to an existing type. FIXME: gdb checks
+ that the class is not C_STRTAG, nor C_UNTAG, nor C_ENTAG. */
+ slot = coff_get_slot (types, pauxent->x_sym.x_tagndx.l);
+ if (*slot != DEBUG_TYPE_NULL)
+ return *slot;
+ else
+ return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
+ }
+
+ /* If the aux entry has already been used for something, useaux will
+ have been set to false, indicating that parse_coff_base_type
+ should not use it. We need to do it this way, rather than simply
+ passing pauxent as NULL, because we need to be able handle
+ multiple array dimensions while still discarding pauxent after
+ having handled all of them. */
+ if (! useaux)
+ pauxent = NULL;
+
+ return parse_coff_base_type (abfd, symbols, types, coff_symno, ntype,
+ pauxent, dhandle);
+}
+
+/* Parse a basic COFF type in NTYPE. */
+
+static debug_type
+parse_coff_base_type (abfd, symbols, types, coff_symno, ntype, pauxent,
+ dhandle)
+ bfd *abfd;
+ struct coff_symbols *symbols;
+ struct coff_types *types;
+ long coff_symno;
+ int ntype;
+ union internal_auxent *pauxent;
+ PTR dhandle;
+{
+ debug_type ret;
+ boolean set_basic;
+ const char *name;
+ debug_type *slot;
+
+ if (ntype >= 0
+ && ntype <= T_MAX
+ && types->basic[ntype] != DEBUG_TYPE_NULL)
+ return types->basic[ntype];
+
+ set_basic = true;
+ name = NULL;
+
+ switch (ntype)
+ {
+ default:
+ ret = debug_make_void_type (dhandle);
+ break;
+
+ case T_NULL:
+ case T_VOID:
+ ret = debug_make_void_type (dhandle);
+ name = "void";
+ break;
+
+ case T_CHAR:
+ ret = debug_make_int_type (dhandle, 1, false);
+ name = "char";
+ break;
+
+ case T_SHORT:
+ ret = debug_make_int_type (dhandle, 2, false);
+ name = "short";
+ break;
+
+ case T_INT:
+ /* FIXME: Perhaps the size should depend upon the architecture. */
+ ret = debug_make_int_type (dhandle, 4, false);
+ name = "int";
+ break;
+
+ case T_LONG:
+ ret = debug_make_int_type (dhandle, 4, false);
+ name = "long";
+ break;
+
+ case T_FLOAT:
+ ret = debug_make_float_type (dhandle, 4);
+ name = "float";
+ break;
+
+ case T_DOUBLE:
+ ret = debug_make_float_type (dhandle, 8);
+ name = "double";
+ break;
+
+ case T_LNGDBL:
+ ret = debug_make_float_type (dhandle, 12);
+ name = "long double";
+ break;
+
+ case T_UCHAR:
+ ret = debug_make_int_type (dhandle, 1, true);
+ name = "unsigned char";
+ break;
+
+ case T_USHORT:
+ ret = debug_make_int_type (dhandle, 2, true);
+ name = "unsigned short";
+ break;
+
+ case T_UINT:
+ ret = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned int";
+ break;
+
+ case T_ULONG:
+ ret = debug_make_int_type (dhandle, 4, true);
+ name = "unsigned long";
+ break;
+
+ case T_STRUCT:
+ if (pauxent == NULL)
+ ret = debug_make_struct_type (dhandle, true, 0,
+ (debug_field *) NULL);
+ else
+ ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
+ dhandle);
+
+ slot = coff_get_slot (types, coff_symno);
+ *slot = ret;
+
+ set_basic = false;
+ break;
+
+ case T_UNION:
+ if (pauxent == NULL)
+ ret = debug_make_struct_type (dhandle, false, 0, (debug_field *) NULL);
+ else
+ ret = parse_coff_struct_type (abfd, symbols, types, ntype, pauxent,
+ dhandle);
+
+ slot = coff_get_slot (types, coff_symno);
+ *slot = ret;
+
+ set_basic = false;
+ break;
+
+ case T_ENUM:
+ if (pauxent == NULL)
+ ret = debug_make_enum_type (dhandle, (const char **) NULL,
+ (bfd_signed_vma *) NULL);
+ else
+ ret = parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle);
+
+ slot = coff_get_slot (types, coff_symno);
+ *slot = ret;
+
+ set_basic = false;
+ break;
+ }
+
+ if (name != NULL)
+ ret = debug_name_type (dhandle, name, ret);
+
+ if (set_basic
+ && ntype >= 0
+ && ntype <= T_MAX)
+ types->basic[ntype] = ret;
+
+ return ret;
+}
+
+/* Parse a struct type. */
+
+static debug_type
+parse_coff_struct_type (abfd, symbols, types, ntype, pauxent, dhandle)
+ bfd *abfd;
+ struct coff_symbols *symbols;
+ struct coff_types *types;
+ int ntype;
+ union internal_auxent *pauxent;
+ PTR dhandle;
+{
+ long symend;
+ int alloc;
+ debug_field *fields;
+ int count;
+ boolean done;
+
+ symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
+
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ count = 0;
+
+ done = false;
+ while (! done
+ && symbols->coff_symno < symend
+ && symbols->symno < symbols->symcount)
+ {
+ asymbol *sym;
+ long this_coff_symno;
+ struct internal_syment syment;
+ union internal_auxent auxent;
+ union internal_auxent *psubaux;
+ bfd_vma bitpos = 0, bitsize = 0;
+
+ sym = symbols->syms[symbols->symno];
+
+ if (! bfd_coff_get_syment (abfd, sym, &syment))
+ {
+ fprintf (stderr, _("%s: bfd_coff_get_syment failed: %s\n"),
+ program_name, bfd_errmsg (bfd_get_error ()));
+ return DEBUG_TYPE_NULL;
+ }
+
+ this_coff_symno = symbols->coff_symno;
+
+ ++symbols->symno;
+ symbols->coff_symno += 1 + syment.n_numaux;
+
+ if (syment.n_numaux == 0)
+ psubaux = NULL;
+ else
+ {
+ if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
+ {
+ fprintf (stderr, _("%s: bfd_coff_get_auxent failed: %s\n"),
+ program_name, bfd_errmsg (bfd_get_error ()));
+ return DEBUG_TYPE_NULL;
+ }
+ psubaux = &auxent;
+ }
+
+ switch (syment.n_sclass)
+ {
+ case C_MOS:
+ case C_MOU:
+ bitpos = 8 * bfd_asymbol_value (sym);
+ bitsize = 0;
+ break;
+
+ case C_FIELD:
+ bitpos = bfd_asymbol_value (sym);
+ bitsize = auxent.x_sym.x_misc.x_lnsz.x_size;
+ break;
+
+ case C_EOS:
+ done = true;
+ break;
+ }
+
+ if (! done)
+ {
+ debug_type ftype;
+ debug_field f;
+
+ ftype = parse_coff_type (abfd, symbols, types, this_coff_symno,
+ syment.n_type, psubaux, true, dhandle);
+ f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype,
+ bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC);
+ if (f == DEBUG_FIELD_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (count + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc (fields, alloc * sizeof *fields));
+ }
+
+ fields[count] = f;
+ ++count;
+ }
+ }
+
+ fields[count] = DEBUG_FIELD_NULL;
+
+ return debug_make_struct_type (dhandle, ntype == T_STRUCT,
+ pauxent->x_sym.x_misc.x_lnsz.x_size,
+ fields);
+}
+
+/* Parse an enum type. */
+
+static debug_type
+parse_coff_enum_type (abfd, symbols, types, pauxent, dhandle)
+ bfd *abfd;
+ struct coff_symbols *symbols;
+ struct coff_types *types;
+ union internal_auxent *pauxent;
+ PTR dhandle;
+{
+ long symend;
+ int alloc;
+ const char **names;
+ bfd_signed_vma *vals;
+ int count;
+ boolean done;
+
+ symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l;
+
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals);
+ count = 0;
+
+ done = false;
+ while (! done
+ && symbols->coff_symno < symend
+ && symbols->symno < symbols->symcount)
+ {
+ asymbol *sym;
+ struct internal_syment syment;
+
+ sym = symbols->syms[symbols->symno];
+
+ if (! bfd_coff_get_syment (abfd, sym, &syment))
+ {
+ fprintf (stderr, _("%s: bfd_coff_get_syment failed: %s\n"),
+ program_name, bfd_errmsg (bfd_get_error ()));
+ return DEBUG_TYPE_NULL;
+ }
+
+ ++symbols->symno;
+ symbols->coff_symno += 1 + syment.n_numaux;
+
+ switch (syment.n_sclass)
+ {
+ case C_MOE:
+ if (count + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc (names, alloc * sizeof *names));
+ vals = ((bfd_signed_vma *)
+ xrealloc (vals, alloc * sizeof *vals));
+ }
+
+ names[count] = bfd_asymbol_name (sym);
+ vals[count] = bfd_asymbol_value (sym);
+ ++count;
+ break;
+
+ case C_EOS:
+ done = true;
+ break;
+ }
+ }
+
+ names[count] = NULL;
+
+ return debug_make_enum_type (dhandle, names, vals);
+}
+
+/* Handle a single COFF symbol. */
+
+static boolean
+parse_coff_symbol (abfd, types, sym, coff_symno, psyment, dhandle, type,
+ within_function)
+ bfd *abfd;
+ struct coff_types *types;
+ asymbol *sym;
+ long coff_symno;
+ struct internal_syment *psyment;
+ PTR dhandle;
+ debug_type type;
+ boolean within_function;
+{
+ switch (psyment->n_sclass)
+ {
+ case C_NULL:
+ break;
+
+ case C_AUTO:
+ if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
+ DEBUG_LOCAL, bfd_asymbol_value (sym)))
+ return false;
+ break;
+
+ case C_EXT:
+ if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
+ DEBUG_GLOBAL, bfd_asymbol_value (sym)))
+ return false;
+ break;
+
+ case C_STAT:
+ if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
+ (within_function
+ ? DEBUG_LOCAL_STATIC
+ : DEBUG_STATIC),
+ bfd_asymbol_value (sym)))
+ return false;
+ break;
+
+ case C_REG:
+ /* FIXME: We may need to convert the register number. */
+ if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type,
+ DEBUG_REGISTER, bfd_asymbol_value (sym)))
+ return false;
+ break;
+
+ case C_LABEL:
+ break;
+
+ case C_ARG:
+ if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
+ DEBUG_PARM_STACK, bfd_asymbol_value (sym)))
+ return false;
+ break;
+
+ case C_REGPARM:
+ /* FIXME: We may need to convert the register number. */
+ if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type,
+ DEBUG_PARM_REG, bfd_asymbol_value (sym)))
+ return false;
+ break;
+
+ case C_TPDEF:
+ type = debug_name_type (dhandle, bfd_asymbol_name (sym), type);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ break;
+
+ case C_STRTAG:
+ case C_UNTAG:
+ case C_ENTAG:
+ {
+ debug_type *slot;
+
+ type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ /* Store the named type into the slot, so that references get
+ the name. */
+ slot = coff_get_slot (types, coff_symno);
+ *slot = type;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/* This is the main routine. It looks through all the symbols and
+ handles them. */
+
+boolean
+parse_coff (abfd, syms, symcount, dhandle)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+{
+ struct coff_symbols symbols;
+ struct coff_types types;
+ int i;
+ long next_c_file;
+ const char *fnname;
+ int fnclass;
+ int fntype;
+ bfd_vma fnend;
+ alent *linenos;
+ boolean within_function;
+ long this_coff_symno;
+
+ symbols.syms = syms;
+ symbols.symcount = symcount;
+ symbols.symno = 0;
+ symbols.coff_symno = 0;
+
+ types.slots = NULL;
+ for (i = 0; i <= T_MAX; i++)
+ types.basic[i] = DEBUG_TYPE_NULL;
+
+ next_c_file = -1;
+ fnname = NULL;
+ fnclass = 0;
+ fntype = 0;
+ fnend = 0;
+ linenos = NULL;
+ within_function = false;
+
+ while (symbols.symno < symcount)
+ {
+ asymbol *sym;
+ const char *name;
+ struct internal_syment syment;
+ union internal_auxent auxent;
+ union internal_auxent *paux;
+ debug_type type;
+
+ sym = syms[symbols.symno];
+
+ if (! bfd_coff_get_syment (abfd, sym, &syment))
+ {
+ fprintf (stderr, _("%s: bfd_coff_get_syment failed: %s\n"),
+ program_name, bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ name = bfd_asymbol_name (sym);
+
+ this_coff_symno = symbols.coff_symno;
+
+ ++symbols.symno;
+ symbols.coff_symno += 1 + syment.n_numaux;
+
+ /* We only worry about the first auxent, because that is the
+ only one which is relevant for debugging information. */
+ if (syment.n_numaux == 0)
+ paux = NULL;
+ else
+ {
+ if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent))
+ {
+ fprintf (stderr, _("%s: bfd_coff_get_auxent failed: %s\n"),
+ program_name, bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+ paux = &auxent;
+ }
+
+ if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE)
+ {
+ /* The last C_FILE symbol points to the first external
+ symbol. */
+ if (! debug_set_filename (dhandle, "*globals*"))
+ return false;
+ }
+
+ switch (syment.n_sclass)
+ {
+ case C_EFCN:
+ case C_EXTDEF:
+ case C_ULABEL:
+ case C_USTATIC:
+ case C_LINE:
+ case C_ALIAS:
+ case C_HIDDEN:
+ /* Just ignore these classes. */
+ break;
+
+ case C_FILE:
+ next_c_file = syment.n_value;
+ if (! debug_set_filename (dhandle, name))
+ return false;
+ break;
+
+ case C_STAT:
+ /* Ignore static symbols with a type of T_NULL. These
+ represent section entries. */
+ if (syment.n_type == T_NULL)
+ break;
+ /* Fall through. */
+ case C_EXT:
+ if (ISFCN (syment.n_type))
+ {
+ fnname = name;
+ fnclass = syment.n_sclass;
+ fntype = syment.n_type;
+ if (syment.n_numaux > 0)
+ fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize;
+ else
+ fnend = 0;
+ linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym));
+ break;
+ }
+ type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
+ syment.n_type, paux, true, dhandle);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
+ dhandle, type, within_function))
+ return false;
+ break;
+
+ case C_FCN:
+ if (strcmp (name, ".bf") == 0)
+ {
+ if (fnname == NULL)
+ {
+ fprintf (stderr, _("%s: %ld: .bf without preceding function\n"),
+ program_name, this_coff_symno);
+ return false;
+ }
+
+ type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
+ DECREF (fntype), paux, false, dhandle);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (! debug_record_function (dhandle, fnname, type,
+ fnclass == C_EXT,
+ bfd_asymbol_value (sym)))
+ return false;
+
+ if (linenos != NULL)
+ {
+ int base;
+ bfd_vma addr;
+
+ if (syment.n_numaux == 0)
+ base = 0;
+ else
+ base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1;
+
+ addr = bfd_get_section_vma (abfd, bfd_get_section (sym));
+
+ ++linenos;
+
+ while (linenos->line_number != 0)
+ {
+ if (! debug_record_line (dhandle,
+ linenos->line_number + base,
+ linenos->u.offset + addr))
+ return false;
+ ++linenos;
+ }
+ }
+
+ fnname = NULL;
+ linenos = NULL;
+ fnclass = 0;
+ fntype = 0;
+
+ within_function = true;
+ }
+ else if (strcmp (name, ".ef") == 0)
+ {
+ if (! within_function)
+ {
+ fprintf (stderr, _("%s: %ld: unexpected .ef\n"),
+ program_name, this_coff_symno);
+ return false;
+ }
+
+ if (bfd_asymbol_value (sym) > fnend)
+ fnend = bfd_asymbol_value (sym);
+ if (! debug_end_function (dhandle, fnend))
+ return false;
+
+ fnend = 0;
+ within_function = false;
+ }
+ break;
+
+ case C_BLOCK:
+ if (strcmp (name, ".bb") == 0)
+ {
+ if (! debug_start_block (dhandle, bfd_asymbol_value (sym)))
+ return false;
+ }
+ else if (strcmp (name, ".eb") == 0)
+ {
+ if (! debug_end_block (dhandle, bfd_asymbol_value (sym)))
+ return false;
+ }
+ break;
+
+ default:
+ type = parse_coff_type (abfd, &symbols, &types, this_coff_symno,
+ syment.n_type, paux, true, dhandle);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment,
+ dhandle, type, within_function))
+ return false;
+ break;
+ }
+ }
+
+ return true;
+}
diff --git a/binutils/rddbg.c b/binutils/rddbg.c
new file mode 100644
index 00000000000..9428c37ad5c
--- /dev/null
+++ b/binutils/rddbg.c
@@ -0,0 +1,448 @@
+/* rddbg.c -- Read debugging information into a generic form.
+ Copyright (C) 1995, 96, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file reads debugging information into a generic form. This
+ file knows how to dig the debugging information out of an object
+ file. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "debug.h"
+#include "budbg.h"
+
+static boolean read_section_stabs_debugging_info
+ PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
+static boolean read_symbol_stabs_debugging_info
+ PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
+static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
+static void save_stab PARAMS ((int, int, bfd_vma, const char *));
+static void stab_context PARAMS ((void));
+static void free_saved_stabs PARAMS ((void));
+
+/* Read debugging information from a BFD. Returns a generic debugging
+ pointer. */
+
+PTR
+read_debugging_info (abfd, syms, symcount)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+{
+ PTR dhandle;
+ boolean found;
+
+ dhandle = debug_init ();
+ if (dhandle == NULL)
+ return NULL;
+
+ if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
+ &found))
+ return NULL;
+
+ if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
+ {
+ if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
+ &found))
+ return NULL;
+ }
+
+ if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
+ {
+ if (! read_ieee_debugging_info (abfd, dhandle, &found))
+ return NULL;
+ }
+
+ /* Try reading the COFF symbols if we didn't find any stabs in COFF
+ sections. */
+ if (! found
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+ && symcount > 0)
+ {
+ if (! parse_coff (abfd, syms, symcount, dhandle))
+ return NULL;
+ found = true;
+ }
+
+ if (! found)
+ {
+ fprintf (stderr, _("%s: no recognized debugging information\n"),
+ bfd_get_filename (abfd));
+ return NULL;
+ }
+
+ return dhandle;
+}
+
+/* Read stabs in sections debugging information from a BFD. */
+
+static boolean
+read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+ boolean *pfound;
+{
+ static struct
+ {
+ const char *secname;
+ const char *strsecname;
+ } names[] = { { ".stab", ".stabstr" } };
+ unsigned int i;
+ PTR shandle;
+
+ *pfound = false;
+ shandle = NULL;
+
+ for (i = 0; i < sizeof names / sizeof names[0]; i++)
+ {
+ asection *sec, *strsec;
+
+ sec = bfd_get_section_by_name (abfd, names[i].secname);
+ strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
+ if (sec != NULL && strsec != NULL)
+ {
+ bfd_size_type stabsize, strsize;
+ bfd_byte *stabs, *strings;
+ bfd_byte *stab;
+ bfd_size_type stroff, next_stroff;
+
+ stabsize = bfd_section_size (abfd, sec);
+ stabs = (bfd_byte *) xmalloc (stabsize);
+ if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ bfd_get_filename (abfd), names[i].secname,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ strsize = bfd_section_size (abfd, strsec);
+ strings = (bfd_byte *) xmalloc (strsize);
+ if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ bfd_get_filename (abfd), names[i].strsecname,
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ if (shandle == NULL)
+ {
+ shandle = start_stab (dhandle, abfd, true, syms, symcount);
+ if (shandle == NULL)
+ return false;
+ }
+
+ *pfound = true;
+
+ stroff = 0;
+ next_stroff = 0;
+ for (stab = stabs; stab < stabs + stabsize; stab += 12)
+ {
+ bfd_size_type strx;
+ int type;
+ int other;
+ int desc;
+ bfd_vma value;
+
+ /* This code presumes 32 bit values. */
+
+ strx = bfd_get_32 (abfd, stab);
+ type = bfd_get_8 (abfd, stab + 4);
+ other = bfd_get_8 (abfd, stab + 5);
+ desc = bfd_get_16 (abfd, stab + 6);
+ value = bfd_get_32 (abfd, stab + 8);
+
+ if (type == 0)
+ {
+ /* Special type 0 stabs indicate the offset to the
+ next string table. */
+ stroff = next_stroff;
+ next_stroff += value;
+ }
+ else
+ {
+ char *f, *s;
+
+ f = NULL;
+ s = (char *) strings + stroff + strx;
+ while (s[strlen (s) - 1] == '\\'
+ && stab + 12 < stabs + stabsize)
+ {
+ char *p;
+
+ stab += 12;
+ p = s + strlen (s) - 1;
+ *p = '\0';
+ s = concat (s,
+ ((char *) strings
+ + stroff
+ + bfd_get_32 (abfd, stab)),
+ (const char *) NULL);
+
+ /* We have to restore the backslash, because, if
+ the linker is hashing stabs strings, we may
+ see the same string more than once. */
+ *p = '\\';
+
+ if (f != NULL)
+ free (f);
+ f = s;
+ }
+
+ save_stab (type, desc, value, s);
+
+ if (! parse_stab (dhandle, shandle, type, desc, value, s))
+ {
+ stab_context ();
+ free_saved_stabs ();
+ return false;
+ }
+
+ /* Don't free f, since I think the stabs code
+ expects strings to hang around. This should be
+ straightened out. FIXME. */
+ }
+ }
+
+ free_saved_stabs ();
+ free (stabs);
+
+ /* Don't free strings, since I think the stabs code expects
+ the strings to hang around. This should be straightened
+ out. FIXME. */
+ }
+ }
+
+ if (shandle != NULL)
+ {
+ if (! finish_stab (dhandle, shandle))
+ return false;
+ }
+
+ return true;
+}
+
+/* Read stabs in the symbol table. */
+
+static boolean
+read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
+ bfd *abfd;
+ asymbol **syms;
+ long symcount;
+ PTR dhandle;
+ boolean *pfound;
+{
+ PTR shandle;
+ asymbol **ps, **symend;
+
+ shandle = NULL;
+ symend = syms + symcount;
+ for (ps = syms; ps < symend; ps++)
+ {
+ symbol_info i;
+
+ bfd_get_symbol_info (abfd, *ps, &i);
+
+ if (i.type == '-')
+ {
+ const char *s;
+ char *f;
+
+ if (shandle == NULL)
+ {
+ shandle = start_stab (dhandle, abfd, false, syms, symcount);
+ if (shandle == NULL)
+ return false;
+ }
+
+ *pfound = true;
+
+ s = i.name;
+ f = NULL;
+ while (s[strlen (s) - 1] == '\\'
+ && ps + 1 < symend)
+ {
+ char *sc, *n;
+
+ ++ps;
+ sc = xstrdup (s);
+ sc[strlen (sc) - 1] = '\0';
+ n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
+ free (sc);
+ if (f != NULL)
+ free (f);
+ f = n;
+ s = n;
+ }
+
+ save_stab (i.stab_type, i.stab_desc, i.value, s);
+
+ if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
+ i.value, s))
+ {
+ stab_context ();
+ free_saved_stabs ();
+ return false;
+ }
+
+ /* Don't free f, since I think the stabs code expects
+ strings to hang around. This should be straightened out.
+ FIXME. */
+ }
+ }
+
+ free_saved_stabs ();
+
+ if (shandle != NULL)
+ {
+ if (! finish_stab (dhandle, shandle))
+ return false;
+ }
+
+ return true;
+}
+
+/* Read IEEE debugging information. */
+
+static boolean
+read_ieee_debugging_info (abfd, dhandle, pfound)
+ bfd *abfd;
+ PTR dhandle;
+ boolean *pfound;
+{
+ asection *dsec;
+ bfd_size_type size;
+ bfd_byte *contents;
+
+ /* The BFD backend puts the debugging information into a section
+ named .debug. */
+
+ dsec = bfd_get_section_by_name (abfd, ".debug");
+ if (dsec == NULL)
+ return true;
+
+ size = bfd_section_size (abfd, dsec);
+ contents = (bfd_byte *) xmalloc (size);
+ if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
+ return false;
+
+ if (! parse_ieee (dhandle, abfd, contents, size))
+ return false;
+
+ free (contents);
+
+ *pfound = true;
+
+ return true;
+}
+
+/* Record stabs strings, so that we can give some context for errors. */
+
+#define SAVE_STABS_COUNT (16)
+
+struct saved_stab
+{
+ int type;
+ int desc;
+ bfd_vma value;
+ char *string;
+};
+
+static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
+static int saved_stabs_index;
+
+/* Save a stabs string. */
+
+static void
+save_stab (type, desc, value, string)
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ if (saved_stabs[saved_stabs_index].string != NULL)
+ free (saved_stabs[saved_stabs_index].string);
+ saved_stabs[saved_stabs_index].type = type;
+ saved_stabs[saved_stabs_index].desc = desc;
+ saved_stabs[saved_stabs_index].value = value;
+ saved_stabs[saved_stabs_index].string = xstrdup (string);
+ saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
+}
+
+/* Provide context for an error. */
+
+static void
+stab_context ()
+{
+ int i;
+
+ fprintf (stderr, _("Last stabs entries before error:\n"));
+ fprintf (stderr, "n_type n_desc n_value string\n");
+
+ i = saved_stabs_index;
+ do
+ {
+ struct saved_stab *stabp;
+
+ stabp = saved_stabs + i;
+ if (stabp->string != NULL)
+ {
+ const char *s;
+
+ s = bfd_get_stab_name (stabp->type);
+ if (s != NULL)
+ fprintf (stderr, "%-6s", s);
+ else if (stabp->type == 0)
+ fprintf (stderr, "HdrSym");
+ else
+ fprintf (stderr, "%-6d", stabp->type);
+ fprintf (stderr, " %-6d ", stabp->desc);
+ fprintf_vma (stderr, stabp->value);
+ if (stabp->type != 0)
+ fprintf (stderr, " %s", stabp->string);
+ fprintf (stderr, "\n");
+ }
+ i = (i + 1) % SAVE_STABS_COUNT;
+ }
+ while (i != saved_stabs_index);
+}
+
+/* Free the saved stab strings. */
+
+static void
+free_saved_stabs ()
+{
+ int i;
+
+ for (i = 0; i < SAVE_STABS_COUNT; i++)
+ {
+ if (saved_stabs[i].string != NULL)
+ {
+ free (saved_stabs[i].string);
+ saved_stabs[i].string = NULL;
+ }
+ }
+
+ saved_stabs_index = 0;
+}
diff --git a/binutils/readelf.c b/binutils/readelf.c
new file mode 100644
index 00000000000..549bf1a68b6
--- /dev/null
+++ b/binutils/readelf.c
@@ -0,0 +1,5682 @@
+/* readelf.c -- display contents of an ELF format file
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+ Originally developed by Eric Youngdale <eric@andante.jic.com>
+ Modifications by Nick Clifton <nickc@cygnus.com>
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+#include <assert.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "bfd.h"
+
+#include "elf/common.h"
+#include "elf/external.h"
+#include "elf/internal.h"
+#include "elf/dwarf2.h"
+
+/* The following headers use the elf/reloc-macros.h file to
+ automatically generate relocation recognition functions
+ such as elf_mips_reloc_type() */
+
+#define RELOC_MACROS_GEN_FUNC
+
+#include "elf/i386.h"
+#include "elf/v850.h"
+#include "elf/ppc.h"
+#include "elf/mips.h"
+#include "elf/alpha.h"
+#include "elf/arm.h"
+#include "elf/m68k.h"
+#include "elf/sparc.h"
+#include "elf/m32r.h"
+#include "elf/d10v.h"
+#include "elf/d30v.h"
+#include "elf/sh.h"
+#include "elf/mn10200.h"
+#include "elf/mn10300.h"
+#include "elf/hppa.h"
+#include "elf/arc.h"
+#include "elf/fr30.h"
+#include "elf/mcore.h"
+
+#include "bucomm.h"
+#include "getopt.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+char * program_name = "readelf";
+unsigned int dynamic_addr;
+unsigned int dynamic_size;
+unsigned int rela_addr;
+unsigned int rela_size;
+char * dynamic_strings;
+char * string_table;
+Elf_Internal_Sym * dynamic_symbols;
+Elf_Internal_Syminfo * dynamic_syminfo;
+unsigned long dynamic_syminfo_offset;
+unsigned int dynamic_syminfo_nent;
+char program_interpreter [64];
+int dynamic_info[DT_JMPREL + 1];
+int version_info[16];
+int loadaddr = 0;
+Elf_Internal_Ehdr elf_header;
+Elf_Internal_Shdr * section_headers;
+Elf_Internal_Dyn * dynamic_segment;
+int show_name;
+int do_dynamic;
+int do_syms;
+int do_reloc;
+int do_sections;
+int do_segments;
+int do_using_dynamic;
+int do_header;
+int do_dump;
+int do_version;
+int do_histogram;
+int do_debugging;
+int do_debug_info;
+int do_debug_abbrevs;
+int do_debug_lines;
+int do_debug_pubnames;
+int do_debug_aranges;
+int binary_class;
+
+/* A dynamic array of flags indicating which sections require dumping. */
+char * dump_sects = NULL;
+unsigned int num_dump_sects = 0;
+
+#define HEX_DUMP (1 << 0)
+#define DISASS_DUMP (1 << 1)
+#define DEBUG_DUMP (1 << 2)
+
+/* Forward declarations for dumb compilers. */
+static unsigned long (* byte_get) PARAMS ((unsigned char *, int));
+static const char * get_mips_dynamic_type PARAMS ((unsigned long type));
+static const char * get_dynamic_type PARAMS ((unsigned long type));
+static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *));
+static char * get_file_type PARAMS ((unsigned e_type));
+static char * get_machine_name PARAMS ((unsigned e_machine));
+static char * get_machine_data PARAMS ((unsigned e_data));
+static char * get_machine_flags PARAMS ((unsigned, unsigned e_machine));
+static const char * get_mips_segment_type PARAMS ((unsigned long type));
+static const char * get_segment_type PARAMS ((unsigned long p_type));
+static const char * get_mips_section_type_name PARAMS ((unsigned int sh_type));
+static const char * get_section_type_name PARAMS ((unsigned int sh_type));
+static char * get_symbol_binding PARAMS ((unsigned int binding));
+static char * get_symbol_type PARAMS ((unsigned int type));
+static void usage PARAMS ((void));
+static void parse_args PARAMS ((int argc, char ** argv));
+static int process_file_header PARAMS ((void));
+static int process_program_headers PARAMS ((FILE *));
+static int process_section_headers PARAMS ((FILE *));
+static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *entry));
+static int process_dynamic_segment PARAMS ((FILE *));
+static int process_symbol_table PARAMS ((FILE *));
+static int process_section_contents PARAMS ((FILE *));
+static void process_file PARAMS ((char * file_name));
+static int process_relocs PARAMS ((FILE *));
+static int process_version_sections PARAMS ((FILE *));
+static char * get_ver_flags PARAMS ((unsigned int flags));
+static char * get_symbol_index_type PARAMS ((unsigned int type));
+static int get_section_headers PARAMS ((FILE * file));
+static int get_file_header PARAMS ((FILE * file));
+static Elf_Internal_Sym * get_elf_symbols PARAMS ((FILE * file, unsigned long offset, unsigned long number));
+static int * get_dynamic_data PARAMS ((FILE * file, unsigned int number));
+#ifdef SUPPORT_DISASSEMBLY
+static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
+#endif
+static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
+static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
+static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
+static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
+static int process_extended_line_op PARAMS ((unsigned char *, int));
+static void reset_state_machine PARAMS ((int));
+static char * get_TAG_name PARAMS ((unsigned long));
+static char * get_AT_name PARAMS ((unsigned long));
+static char * get_FORM_name PARAMS ((unsigned long));
+static void free_abbrevs PARAMS ((void));
+static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
+static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
+static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
+static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
+static void decode_location_expression PARAMS ((unsigned char *, unsigned int));
+static void request_dump PARAMS ((unsigned int, char));
+static const char * get_elf_class PARAMS ((unsigned char));
+static const char * get_data_encoding PARAMS ((unsigned char));
+static const char * get_osabi_name PARAMS ((unsigned char));
+
+typedef int Elf32_Word;
+
+#define SECTION_NAME(X) (string_table + (X)->sh_name)
+
+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
+
+#define BYTE_GET(field) byte_get (field, sizeof (field))
+
+#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
+
+#define GET_DATA_ALLOC(offset, size, var, type, reason) \
+ if (fseek (file, offset, SEEK_SET)) \
+ { \
+ error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
+ return 0; \
+ } \
+ \
+ var = (type) malloc (size); \
+ \
+ if (var == NULL) \
+ { \
+ error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
+ return 0; \
+ } \
+ \
+ if (fread (var, size, 1, file) != 1) \
+ { \
+ error (_("Unable to read in %d bytes of %s\n"), size, reason); \
+ free (var); \
+ var = NULL; \
+ return 0; \
+ }
+
+
+#define GET_DATA(offset, var, reason) \
+ if (fseek (file, offset, SEEK_SET)) \
+ { \
+ error (_("Unable to seek to %x for %s\n"), offset, reason); \
+ return 0; \
+ } \
+ else if (fread (& var, sizeof (var), 1, file) != 1) \
+ { \
+ error (_("Unable to read data at %x for %s\n"), offset, reason); \
+ return 0; \
+ }
+
+#ifdef ANSI_PROTOTYPES
+static void
+error (const char * message, ...)
+{
+ va_list args;
+
+ fprintf (stderr, _("%s: Error: "), program_name);
+ va_start (args, message);
+ vfprintf (stderr, message, args);
+ va_end (args);
+ return;
+}
+
+static void
+warn (const char * message, ...)
+{
+ va_list args;
+
+ fprintf (stderr, _("%s: Warning: "), program_name);
+ va_start (args, message);
+ vfprintf (stderr, message, args);
+ va_end (args);
+ return;
+}
+#else
+static void
+error (va_alist)
+ va_dcl
+{
+ char * message;
+ va_list args;
+
+ fprintf (stderr, _("%s: Error: "), program_name);
+ va_start (args);
+ message = va_arg (args, char *);
+ vfprintf (stderr, message, args);
+ va_end (args);
+ return;
+}
+
+static void
+warn (va_alist)
+ va_dcl
+{
+ char * message;
+ va_list args;
+
+ fprintf (stderr, _("%s: Warning: "), program_name);
+ va_start (args);
+ message = va_arg (args, char *);
+ vfprintf (stderr, message, args);
+ va_end (args);
+ return;
+}
+#endif
+
+static unsigned long int
+byte_get_little_endian (field, size)
+ unsigned char * field;
+ int size;
+{
+ switch (size)
+ {
+ case 1:
+ return * field;
+
+ case 2:
+ return ((unsigned int) (field [0]))
+ | (((unsigned int) (field [1])) << 8);
+
+ case 4:
+ return ((unsigned long) (field [0]))
+ | (((unsigned long) (field [1])) << 8)
+ | (((unsigned long) (field [2])) << 16)
+ | (((unsigned long) (field [3])) << 24);
+
+ default:
+ error (_("Unhandled data length: %d\n"), size);
+ abort();
+ }
+}
+
+static unsigned long int
+byte_get_big_endian (field, size)
+ unsigned char * field;
+ int size;
+{
+ switch (size)
+ {
+ case 1:
+ return * field;
+
+ case 2:
+ return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
+
+ case 4:
+ return ((unsigned long) (field [3]))
+ | (((unsigned long) (field [2])) << 8)
+ | (((unsigned long) (field [1])) << 16)
+ | (((unsigned long) (field [0])) << 24);
+
+ default:
+ error (_("Unhandled data length: %d\n"), size);
+ abort();
+ }
+}
+
+
+/* Display the contents of the relocation data
+ found at the specified offset. */
+static int
+dump_relocations (file, rel_offset, rel_size, symtab, strtab)
+ FILE * file;
+ unsigned long rel_offset;
+ unsigned long rel_size;
+ Elf_Internal_Sym * symtab;
+ char * strtab;
+{
+ unsigned int i;
+ int is_rela;
+ Elf_Internal_Rel * rels;
+ Elf_Internal_Rela * relas;
+
+
+ /* Compute number of relocations and read them in. */
+ switch (elf_header.e_machine)
+ {
+ /* Targets that use REL relocations. */
+ case EM_ARM:
+ case EM_386:
+ case EM_486:
+ case EM_CYGNUS_M32R:
+ case EM_CYGNUS_D10V:
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ {
+ Elf32_External_Rel * erels;
+
+ GET_DATA_ALLOC (rel_offset, rel_size, erels,
+ Elf32_External_Rel *, "relocs");
+
+ rel_size = rel_size / sizeof (Elf32_External_Rel);
+
+ rels = (Elf_Internal_Rel *) malloc (rel_size *
+ sizeof (Elf_Internal_Rel));
+
+ for (i = 0; i < rel_size; i++)
+ {
+ rels[i].r_offset = BYTE_GET (erels[i].r_offset);
+ rels[i].r_info = BYTE_GET (erels[i].r_info);
+ }
+
+ free (erels);
+
+ is_rela = 0;
+ relas = (Elf_Internal_Rela *) rels;
+ }
+ break;
+
+ /* Targets that use RELA relocations. */
+ case EM_68K:
+ case EM_SPARC:
+ case EM_PPC:
+ case EM_CYGNUS_V850:
+ case EM_CYGNUS_D30V:
+ case EM_CYGNUS_MN10200:
+ case EM_CYGNUS_MN10300:
+ case EM_CYGNUS_FR30:
+ case EM_SH:
+ case EM_ALPHA:
+ case EM_MCORE:
+ {
+ Elf32_External_Rela * erelas;
+
+ GET_DATA_ALLOC (rel_offset, rel_size, erelas,
+ Elf32_External_Rela *, "relocs");
+
+ rel_size = rel_size / sizeof (Elf32_External_Rela);
+
+ relas = (Elf_Internal_Rela *) malloc (rel_size *
+ sizeof (Elf_Internal_Rela));
+
+ for (i = 0; i < rel_size; i++)
+ {
+ relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
+ relas[i].r_info = BYTE_GET (erelas[i].r_info);
+ relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+ }
+
+ free (erelas);
+
+ is_rela = 1;
+ rels = (Elf_Internal_Rel *) relas;
+ }
+ break;
+
+ default:
+ warn (_("Don't know about relocations on this machine architecture\n"));
+ return 0;
+ }
+
+ if (is_rela)
+ printf
+ (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
+ else
+ printf
+ (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
+
+ for (i = 0; i < rel_size; i++)
+ {
+ const char * rtype;
+ unsigned long offset;
+ unsigned long info;
+ int symtab_index;
+
+ if (is_rela)
+ {
+ offset = relas [i].r_offset;
+ info = relas [i].r_info;
+ }
+ else
+ {
+ offset = rels [i].r_offset;
+ info = rels [i].r_info;
+ }
+
+ printf (" %8.8lx %5.5lx ", offset, info);
+
+ switch (elf_header.e_machine)
+ {
+ default:
+ rtype = NULL;
+ break;
+
+ case EM_CYGNUS_M32R:
+ rtype = elf_m32r_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_386:
+ case EM_486:
+ rtype = elf_i386_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_68K:
+ rtype = elf_m68k_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_SPARC:
+ rtype = elf_sparc_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_V850:
+ rtype = v850_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_D10V:
+ rtype = elf_d10v_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_D30V:
+ rtype = elf_d30v_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_SH:
+ rtype = elf_sh_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_MN10300:
+ rtype = elf_mn10300_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_MN10200:
+ rtype = elf_mn10200_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_FR30:
+ rtype = elf_fr30_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_MCORE:
+ rtype = elf_mcore_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_PPC:
+ rtype = elf_ppc_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ rtype = elf_mips_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_ALPHA:
+ rtype = elf_alpha_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_ARM:
+ rtype = elf_arm_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_CYGNUS_ARC:
+ rtype = elf_arc_reloc_type (ELF32_R_TYPE (info));
+ break;
+
+ case EM_PARISC:
+ rtype = elf32_hppa_reloc_type (ELF32_R_TYPE (info));
+ break;
+ }
+
+ if (rtype == NULL)
+ printf (_("unrecognised: %-7lx"), ELF32_R_TYPE (info));
+ else
+ printf ("%-21.21s", rtype);
+
+ symtab_index = ELF32_R_SYM (info);
+
+ if (symtab_index && symtab != NULL)
+ {
+ Elf_Internal_Sym * psym;
+
+ psym = symtab + symtab_index;
+
+ printf (" %08lx ", (unsigned long) psym->st_value);
+
+ if (psym->st_name == 0)
+ printf ("%-25.25s",
+ SECTION_NAME (section_headers + psym->st_shndx));
+ else if (strtab == NULL)
+ printf (_("<string table index %3ld>"), psym->st_name);
+ else
+ printf ("%-25.25s", strtab + psym->st_name);
+
+ if (is_rela)
+ printf (" + %lx", (unsigned long) relas [i].r_addend);
+ }
+
+ putchar ('\n');
+ }
+
+ free (relas);
+
+ return 1;
+}
+
+static const char *
+get_mips_dynamic_type (type)
+ unsigned long type;
+{
+ switch (type)
+ {
+ case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
+ case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
+ case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
+ case DT_MIPS_IVERSION: return "MIPS_IVERSION";
+ case DT_MIPS_FLAGS: return "MIPS_FLAGS";
+ case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
+ case DT_MIPS_MSYM: return "MIPS_MSYM";
+ case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
+ case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
+ case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
+ case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
+ case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
+ case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
+ case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
+ case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
+ case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
+ case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
+ case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
+ case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
+ case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
+ case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
+ case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
+ case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
+ case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
+ case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
+ case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
+ case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
+ case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
+ case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
+ case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
+ case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
+ case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
+ case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
+ case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
+ case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
+ case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
+ case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
+ case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
+ case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
+ case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
+ case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
+ case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
+ case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
+ default:
+ return NULL;
+ }
+}
+
+static const char *
+get_dynamic_type (type)
+ unsigned long type;
+{
+ static char buff [32];
+
+ switch (type)
+ {
+ case DT_NULL: return "NULL";
+ case DT_NEEDED: return "NEEDED";
+ case DT_PLTRELSZ: return "PLTRELSZ";
+ case DT_PLTGOT: return "PLTGOT";
+ case DT_HASH: return "HASH";
+ case DT_STRTAB: return "STRTAB";
+ case DT_SYMTAB: return "SYMTAB";
+ case DT_RELA: return "RELA";
+ case DT_RELASZ: return "RELASZ";
+ case DT_RELAENT: return "RELAENT";
+ case DT_STRSZ: return "STRSZ";
+ case DT_SYMENT: return "SYMENT";
+ case DT_INIT: return "INIT";
+ case DT_FINI: return "FINI";
+ case DT_SONAME: return "SONAME";
+ case DT_RPATH: return "RPATH";
+ case DT_SYMBOLIC: return "SYMBOLIC";
+ case DT_REL: return "REL";
+ case DT_RELSZ: return "RELSZ";
+ case DT_RELENT: return "RELENT";
+ case DT_PLTREL: return "PLTREL";
+ case DT_DEBUG: return "DEBUG";
+ case DT_TEXTREL: return "TEXTREL";
+ case DT_JMPREL: return "JMPREL";
+ case DT_BIND_NOW: return "BIND_NOW";
+ case DT_INIT_ARRAY: return "INIT_ARRAY";
+ case DT_FINI_ARRAY: return "FINI_ARRAY";
+ case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
+ case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
+
+ case DT_PLTPADSZ: return "PLTPADSZ";
+ case DT_MOVEENT: return "MOVEENT";
+ case DT_MOVESZ: return "MOVESZ";
+ case DT_FEATURE_1: return "FEATURE_1";
+ case DT_POSFLAG_1: return "POSFLAG_1";
+ case DT_SYMINSZ: return "SYMINSZ";
+ case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
+
+ case DT_ADDRRNGLO: return "ADDRRNGLO";
+ case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
+
+ case DT_VERSYM: return "VERSYM";
+
+ case DT_RELACOUNT: return "RELACOUNT";
+ case DT_RELCOUNT: return "RELCOUNT";
+ case DT_FLAGS_1: return "FLAGS_1";
+ case DT_VERDEF: return "VERDEF";
+ case DT_VERDEFNUM: return "VERDEFNUM";
+ case DT_VERNEED: return "VERNEED";
+ case DT_VERNEEDNUM: return "VERNEEDNUM";
+
+ case DT_AUXILIARY: return "AUXILARY";
+ case DT_USED: return "USED";
+ case DT_FILTER: return "FILTER";
+
+ default:
+ if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
+ {
+ const char * result;
+
+ switch (elf_header.e_machine)
+ {
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ result = get_mips_dynamic_type (type);
+ break;
+ default:
+ result = NULL;
+ break;
+ }
+
+ if (result != NULL)
+ return result;
+
+ sprintf (buff, _("Processor Specific: %lx"), type);
+ }
+ else if ((type >= DT_LOOS) && (type <= DT_HIOS))
+ sprintf (buff, _("Operating System specific: %lx"), type);
+ else
+ sprintf (buff, _("<unknown>: %lx"), type);
+
+ return buff;
+ }
+}
+
+static char *
+get_file_type (e_type)
+ unsigned e_type;
+{
+ static char buff [32];
+
+ switch (e_type)
+ {
+ case ET_NONE: return _("NONE (None)");
+ case ET_REL: return _("REL (Relocatable file)");
+ case ET_EXEC: return _("EXEC (Executable file)");
+ case ET_DYN: return _("DYN (Shared object file)");
+ case ET_CORE: return _("CORE (Core file)");
+
+ default:
+ if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
+ sprintf (buff, _("Processor Specific: (%x)"), e_type);
+ else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
+ sprintf (buff, _("OS Specific: (%x)"), e_type);
+ else
+ sprintf (buff, _("<unknown>: %x"), e_type);
+ return buff;
+ }
+}
+
+static char *
+get_machine_name (e_machine)
+ unsigned e_machine;
+{
+ static char buff [32];
+
+ switch (e_machine)
+ {
+ case EM_NONE: return _("None");
+ case EM_M32: return "WE32100";
+ case EM_SPARC: return "Sparc";
+ case EM_386: return "Intel 80386";
+ case EM_68K: return "MC68000";
+ case EM_88K: return "MC88000";
+ case EM_486: return "Intel 80486";
+ case EM_860: return "Intel 80860";
+ case EM_MIPS: return "MIPS R3000 big-endian";
+ case EM_S370: return "Amdahl";
+ case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
+ case EM_OLD_SPARCV9: return "Sparc v9 (old)";
+ case EM_PARISC: return "HPPA";
+ case EM_PPC_OLD: return "Power PC (old)";
+ case EM_SPARC32PLUS: return "Sparc v8+" ;
+ case EM_960: return "Intel 90860";
+ case EM_PPC: return "PowerPC";
+ case EM_V800: return "NEC V800";
+ case EM_FR20: return "Fujitsu FR20";
+ case EM_RH32: return "TRW RH32";
+ case EM_MCORE: return "MCORE";
+ case EM_ARM: return "ARM";
+ case EM_OLD_ALPHA: return "Digital Alpha (old)";
+ case EM_SH: return "Hitachi SH";
+ case EM_SPARCV9: return "Sparc v9";
+ case EM_TRICORE: return "Siemens Tricore";
+ case EM_ARC: return "Argonaut RISC Core";
+ case EM_H8_300: return "Hitachi H8/300";
+ case EM_H8_300H: return "Hitachi H8/300H";
+ case EM_H8S: return "Hitachi H8S";
+ case EM_H8_500: return "Hitachi H8/500";
+ case EM_IA_64: return "Intel Merced";
+ case EM_MIPS_X: return "Stanford MIPS-X";
+ case EM_COLDFIRE: return "Motorola Coldfire";
+ case EM_68HC12: return "Motorola M68HC12";
+ case EM_ALPHA: return "Alpha";
+ case EM_CYGNUS_D10V: return "d10v";
+ case EM_CYGNUS_D30V: return "d30v";
+ case EM_CYGNUS_ARC: return "Arc";
+ case EM_CYGNUS_M32R: return "Mitsubishi M32r";
+ case EM_CYGNUS_V850: return "NEC v850";
+ case EM_CYGNUS_MN10300: return "mn10300";
+ case EM_CYGNUS_MN10200: return "mn10200";
+ case EM_CYGNUS_FR30: return "Fujitsu FR30";
+
+ default:
+ sprintf (buff, _("<unknown>: %x"), e_machine);
+ return buff;
+ }
+}
+
+static char *
+get_machine_flags (e_flags, e_machine)
+ unsigned e_flags;
+ unsigned e_machine;
+{
+ static char buf [1024];
+
+ buf[0] = '\0';
+ if (e_flags)
+ {
+ switch (e_machine)
+ {
+ default:
+ break;
+
+ case EM_PPC:
+ if (e_flags & EF_PPC_EMB)
+ strcat (buf, ", emb");
+
+ if (e_flags & EF_PPC_RELOCATABLE)
+ strcat (buf, ", relocatable");
+
+ if (e_flags & EF_PPC_RELOCATABLE_LIB)
+ strcat (buf, ", relocatable-lib");
+ break;
+
+ case EM_CYGNUS_V850:
+ switch (e_flags & EF_V850_ARCH)
+ {
+ case E_V850E_ARCH:
+ strcat (buf, ", v850e");
+ break;
+ case E_V850EA_ARCH:
+ strcat (buf, ", v850ea");
+ break;
+ case E_V850_ARCH:
+ strcat (buf, ", v850");
+ break;
+ default:
+ strcat (buf, ", unknown v850 architecture variant");
+ break;
+ }
+ break;
+
+ case EM_CYGNUS_M32R:
+ if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
+ strcat (buf, ", m32r");
+
+ break;
+
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ if (e_flags & EF_MIPS_NOREORDER)
+ strcat (buf, ", noreorder");
+
+ if (e_flags & EF_MIPS_PIC)
+ strcat (buf, ", pic");
+
+ if (e_flags & EF_MIPS_CPIC)
+ strcat (buf, ", cpic");
+
+ if (e_flags & EF_MIPS_ABI2)
+ strcat (buf, ", abi2");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
+ strcat (buf, ", mips1");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
+ strcat (buf, ", mips2");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
+ strcat (buf, ", mips3");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
+ strcat (buf, ", mips4");
+ break;
+ }
+ }
+
+ return buf;
+}
+
+static char *
+get_machine_data (e_data)
+ unsigned e_data;
+{
+ static char buff [32];
+
+ switch (e_data)
+ {
+ case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
+ case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
+ default:
+ sprintf (buff, _("<unknown>: %x"), e_data);
+ return buff;
+ }
+}
+
+static const char *
+get_mips_segment_type (type)
+ unsigned long type;
+{
+ switch (type)
+ {
+ case PT_MIPS_REGINFO:
+ return "REGINFO";
+ case PT_MIPS_RTPROC:
+ return "RTPROC";
+ case PT_MIPS_OPTIONS:
+ return "OPTIONS";
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+static const char *
+get_segment_type (p_type)
+ unsigned long p_type;
+{
+ static char buff [32];
+
+ switch (p_type)
+ {
+ case PT_NULL: return "NULL";
+ case PT_LOAD: return "LOAD";
+ case PT_DYNAMIC: return "DYNAMIC";
+ case PT_INTERP: return "INTERP";
+ case PT_NOTE: return "NOTE";
+ case PT_SHLIB: return "SHLIB";
+ case PT_PHDR: return "PHDR";
+
+ default:
+ if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
+ {
+ const char * result;
+
+ switch (elf_header.e_machine)
+ {
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ result = get_mips_segment_type (p_type);
+ break;
+ default:
+ result = NULL;
+ break;
+ }
+
+ if (result != NULL)
+ return result;
+
+ sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
+ }
+ else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
+ sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
+ else
+ sprintf (buff, _("<unknown>: %lx"), p_type);
+
+ return buff;
+ }
+}
+
+static const char *
+get_mips_section_type_name (sh_type)
+ unsigned int sh_type;
+{
+ switch (sh_type)
+ {
+ case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
+ case SHT_MIPS_MSYM: return "MIPS_MSYM";
+ case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
+ case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
+ case SHT_MIPS_UCODE: return "MIPS_UCODE";
+ case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
+ case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
+ case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
+ case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
+ case SHT_MIPS_RELD: return "MIPS_RELD";
+ case SHT_MIPS_IFACE: return "MIPS_IFACE";
+ case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
+ case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
+ case SHT_MIPS_SHDR: return "MIPS_SHDR";
+ case SHT_MIPS_FDESC: return "MIPS_FDESC";
+ case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
+ case SHT_MIPS_DENSE: return "MIPS_DENSE";
+ case SHT_MIPS_PDESC: return "MIPS_PDESC";
+ case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
+ case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
+ case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
+ case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
+ case SHT_MIPS_LINE: return "MIPS_LINE";
+ case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
+ case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
+ case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
+ case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
+ case SHT_MIPS_DWARF: return "MIPS_DWARF";
+ case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
+ case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
+ case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
+ case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
+ case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
+ case SHT_MIPS_XLATE: return "MIPS_XLATE";
+ case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
+ case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
+ case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
+ case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
+ case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static const char *
+get_section_type_name (sh_type)
+ unsigned int sh_type;
+{
+ static char buff [32];
+
+ switch (sh_type)
+ {
+ case SHT_NULL: return "NULL";
+ case SHT_PROGBITS: return "PROGBITS";
+ case SHT_SYMTAB: return "SYMTAB";
+ case SHT_STRTAB: return "STRTAB";
+ case SHT_RELA: return "RELA";
+ case SHT_HASH: return "HASH";
+ case SHT_DYNAMIC: return "DYNAMIC";
+ case SHT_NOTE: return "NOTE";
+ case SHT_NOBITS: return "NOBITS";
+ case SHT_REL: return "REL";
+ case SHT_SHLIB: return "SHLIB";
+ case SHT_DYNSYM: return "DYNSYM";
+ case SHT_GNU_verdef: return "VERDEF";
+ case SHT_GNU_verneed: return "VERNEED";
+ case SHT_GNU_versym: return "VERSYM";
+ case 0x6ffffff0: return "VERSYM";
+ case 0x6ffffffc: return "VERDEF";
+ case 0x7ffffffd: return "AUXILIARY";
+ case 0x7fffffff: return "FILTER";
+
+ default:
+ if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
+ {
+ const char * result;
+
+ switch (elf_header.e_machine)
+ {
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ result = get_mips_section_type_name (sh_type);
+ break;
+ default:
+ result = NULL;
+ break;
+ }
+
+ if (result != NULL)
+ return result;
+
+ sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
+ }
+ else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
+ sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
+ else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
+ sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
+ else
+ sprintf (buff, _("<unknown>: %x"), sh_type);
+
+ return buff;
+ }
+}
+
+struct option options [] =
+{
+ {"all", no_argument, 0, 'a'},
+ {"file-header", no_argument, 0, 'h'},
+ {"program-headers", no_argument, 0, 'l'},
+ {"headers", no_argument, 0, 'e'},
+ {"histogram", no_argument, & do_histogram, 1},
+ {"segments", no_argument, 0, 'l'},
+ {"sections", no_argument, 0, 'S'},
+ {"section-headers", no_argument, 0, 'S'},
+ {"symbols", no_argument, 0, 's'},
+ {"syms", no_argument, 0, 's'},
+ {"relocs", no_argument, 0, 'r'},
+ {"dynamic", no_argument, 0, 'd'},
+ {"version-info", no_argument, 0, 'V'},
+ {"use-dynamic", no_argument, 0, 'D'},
+ {"hex-dump", required_argument, 0, 'x'},
+ {"debug-dump", optional_argument, 0, 'w'},
+#ifdef SUPPORT_DISASSEMBLY
+ {"instruction-dump", required_argument, 0, 'i'},
+#endif
+
+ {"version", no_argument, 0, 'v'},
+ {"help", no_argument, 0, 'H'},
+ {0, no_argument, 0, 0}
+};
+
+static void
+usage ()
+{
+ fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
+ fprintf (stdout, _(" Options are:\n"));
+ fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
+ fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
+ fprintf (stdout, _(" -l or --program-headers or --segments\n"));
+ fprintf (stdout, _(" Display the program headers\n"));
+ fprintf (stdout, _(" -S or --section-headers or --sections\n"));
+ fprintf (stdout, _(" Display the sections' header\n"));
+ fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
+ fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
+ fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
+ fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
+ fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
+ fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
+ fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
+ fprintf (stdout, _(" Dump the contents of section <number>\n"));
+ fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
+ fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
+#ifdef SUPPORT_DISASSEMBLY
+ fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
+ fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
+#endif
+ fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
+ fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
+ fprintf (stdout, _(" -H or --help Display this information\n"));
+ fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+
+ exit (0);
+}
+
+static void
+request_dump (section, type)
+ unsigned int section;
+ char type;
+{
+ if (section >= num_dump_sects)
+ {
+ char * new_dump_sects;
+
+ new_dump_sects = (char *) calloc (section + 1, 1);
+
+ if (new_dump_sects == NULL)
+ error (_("Out of memory allocating dump request table."));
+ else
+ {
+ /* Copy current flag settings. */
+ memcpy (new_dump_sects, dump_sects, num_dump_sects);
+
+ free (dump_sects);
+
+ dump_sects = new_dump_sects;
+ num_dump_sects = section + 1;
+ }
+ }
+
+ if (dump_sects)
+ dump_sects [section] |= type;
+
+ return;
+}
+
+static void
+parse_args (argc, argv)
+ int argc;
+ char ** argv;
+{
+ int c;
+
+ if (argc < 2)
+ usage ();
+
+ while ((c = getopt_long
+ (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
+ {
+ char * cp;
+ int section;
+
+ switch (c)
+ {
+ case 0:
+ /* Long options. */
+ break;
+ case 'H':
+ usage ();
+ break;
+
+ case 'a':
+ do_syms ++;
+ do_reloc ++;
+ do_dynamic ++;
+ do_header ++;
+ do_sections ++;
+ do_segments ++;
+ do_version ++;
+ do_histogram ++;
+ break;
+ case 'e':
+ do_header ++;
+ do_sections ++;
+ do_segments ++;
+ break;
+ case 'D':
+ do_using_dynamic ++;
+ break;
+ case 'r':
+ do_reloc ++;
+ break;
+ case 'h':
+ do_header ++;
+ break;
+ case 'l':
+ do_segments ++;
+ break;
+ case 's':
+ do_syms ++;
+ break;
+ case 'S':
+ do_sections ++;
+ break;
+ case 'd':
+ do_dynamic ++;
+ break;
+ case 'x':
+ do_dump ++;
+ section = strtoul (optarg, & cp, 0);
+ if (! * cp && section >= 0)
+ {
+ request_dump (section, HEX_DUMP);
+ break;
+ }
+ goto oops;
+ case 'w':
+ do_dump ++;
+ if (optarg == 0)
+ do_debugging = 1;
+ else
+ {
+ do_debugging = 0;
+ switch (optarg[0])
+ {
+ case 'i':
+ case 'I':
+ do_debug_info = 1;
+ break;
+
+ case 'a':
+ case 'A':
+ do_debug_abbrevs = 1;
+ break;
+
+ case 'l':
+ case 'L':
+ do_debug_lines = 1;
+ break;
+
+ case 'p':
+ case 'P':
+ do_debug_pubnames = 1;
+ break;
+
+ case 'r':
+ case 'R':
+ do_debug_aranges = 1;
+ break;
+
+ default:
+ warn (_("Unrecognised debug option '%s'\n"), optarg);
+ break;
+ }
+ }
+ break;
+#ifdef SUPPORT_DISASSEMBLY
+ case 'i':
+ do_dump ++;
+ section = strtoul (optarg, & cp, 0);
+ if (! * cp && section >= 0)
+ {
+ request_dump (section, DISASS_DUMP);
+ break;
+ }
+ goto oops;
+#endif
+ case 'v':
+ print_version (program_name);
+ break;
+ case 'V':
+ do_version ++;
+ break;
+ default:
+ oops:
+ /* xgettext:c-format */
+ error (_("Invalid option '-%c'\n"), c);
+ /* Drop through. */
+ case '?':
+ usage ();
+ }
+ }
+
+ if (!do_dynamic && !do_syms && !do_reloc && !do_sections
+ && !do_segments && !do_header && !do_dump && !do_version
+ && !do_histogram && !do_debugging)
+ usage ();
+ else if (argc < 3)
+ {
+ warn (_("Nothing to do.\n"));
+ usage();
+ }
+}
+
+static const char *
+get_elf_class (elf_class)
+ unsigned char elf_class;
+{
+ switch (elf_class)
+ {
+ case ELFCLASSNONE: return _("none");
+ case ELFCLASS32: return _("ELF32");
+ case ELFCLASS64: return _("ELF64");
+ default: return _("<unknown>");
+ }
+}
+
+static const char *
+get_data_encoding (encoding)
+ unsigned char encoding;
+{
+ switch (encoding)
+ {
+ case ELFDATANONE: return _("none");
+ case ELFDATA2LSB: return _("2's compilment, little endian");
+ case ELFDATA2MSB: return _("2's compilment, big endian");
+ default: return _("<unknown>");
+ }
+}
+
+static const char *
+get_osabi_name (osabi)
+ unsigned char osabi;
+{
+ switch (osabi)
+ {
+ case ELFOSABI_SYSV: return _("UNIX - System V");
+ case ELFOSABI_HPUX: return _("UNIX - HP-UX");
+ case ELFOSABI_STANDALONE: return _("Standalone App");
+ default: return _("<unknown>");
+ }
+}
+
+/* Decode the data held in 'elf_header'. */
+static int
+process_file_header ()
+{
+ if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
+ || elf_header.e_ident [EI_MAG1] != ELFMAG1
+ || elf_header.e_ident [EI_MAG2] != ELFMAG2
+ || elf_header.e_ident [EI_MAG3] != ELFMAG3)
+ {
+ error
+ (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
+ return 0;
+ }
+
+ if (do_header)
+ {
+ int i;
+
+ printf (_("ELF Header:\n"));
+ printf (_(" Magic: "));
+ for (i = 0; i < EI_NIDENT; i ++)
+ printf ("%2.2x ", elf_header.e_ident [i]);
+ printf ("\n");
+ printf (_(" Class: %s\n"),
+ get_elf_class (elf_header.e_ident [EI_CLASS]));
+ printf (_(" Data: %s\n"),
+ get_data_encoding (elf_header.e_ident [EI_DATA]));
+ printf (_(" Version: %d %s\n"),
+ elf_header.e_ident [EI_VERSION],
+ elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
+ elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown>" : "");
+ printf (_(" OS/ABI: %s\n"),
+ get_osabi_name (elf_header.e_ident [EI_OSABI]));
+ printf (_(" ABI Version: %d\n"),
+ elf_header.e_ident [EI_ABIVERSION]);
+ printf (_(" Type: %s\n"),
+ get_file_type (elf_header.e_type));
+ printf (_(" Machine: %s\n"),
+ get_machine_name (elf_header.e_machine));
+ printf (_(" Version: 0x%lx\n"),
+ (unsigned long) elf_header.e_version);
+ printf (_(" Data: %s\n"),
+ get_machine_data (elf_header.e_ident [EI_DATA]));
+ printf (_(" Entry point address: 0x%lx\n"),
+ (unsigned long) elf_header.e_entry);
+ printf (_(" Start of program headers: %ld (bytes into file)\n"),
+ (long) elf_header.e_phoff);
+ printf (_(" Start of section headers: %ld (bytes into file)\n"),
+ (long) elf_header.e_shoff);
+ printf (_(" Flags: 0x%lx%s\n"),
+ (unsigned long) elf_header.e_flags,
+ get_machine_flags (elf_header.e_flags, elf_header.e_machine));
+ printf (_(" Size of this header: %ld (bytes)\n"),
+ (long) elf_header.e_ehsize);
+ printf (_(" Size of program headers: %ld (bytes)\n"),
+ (long) elf_header.e_phentsize);
+ printf (_(" Number of program headers: %ld\n"),
+ (long) elf_header.e_phnum);
+ printf (_(" Size of section headers: %ld (bytes)\n"),
+ (long) elf_header.e_shentsize);
+ printf (_(" Number of section headers: %ld\n"),
+ (long) elf_header.e_shnum);
+ printf (_(" Section header string table index: %ld\n"),
+ (long) elf_header.e_shstrndx);
+ }
+
+ /* Test class after dumping header so that at least the header can be
+ display on 64 bit binaries. */
+
+ binary_class = elf_header.e_ident [EI_CLASS];
+ if (binary_class != ELFCLASS32)
+ {
+ error (_("Not a 32 bit ELF file\n"));
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static int
+process_program_headers (file)
+ FILE * file;
+{
+ Elf32_External_Phdr * phdrs;
+ Elf32_Internal_Phdr * program_headers;
+ Elf32_Internal_Phdr * segment;
+ unsigned int i;
+
+ if (elf_header.e_phnum == 0)
+ {
+ if (do_segments)
+ printf (_("\nThere are no program headers in this file.\n"));
+ return 1;
+ }
+
+ if (do_segments && !do_header)
+ {
+ printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
+ printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
+ printf (_("There are %d program headers, starting at offset %lx:\n"),
+ elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
+ }
+
+ GET_DATA_ALLOC (elf_header.e_phoff,
+ elf_header.e_phentsize * elf_header.e_phnum,
+ phdrs, Elf32_External_Phdr *, "program headers");
+
+ program_headers = (Elf32_Internal_Phdr *) malloc
+ (elf_header.e_phnum * sizeof (Elf32_Internal_Phdr));
+
+ if (program_headers == NULL)
+ {
+ error (_("Out of memory\n"));
+ return 0;
+ }
+
+ for (i = 0, segment = program_headers;
+ i < elf_header.e_phnum;
+ i ++, segment ++)
+ {
+ segment->p_type = BYTE_GET (phdrs[i].p_type);
+ segment->p_offset = BYTE_GET (phdrs[i].p_offset);
+ segment->p_vaddr = BYTE_GET (phdrs[i].p_vaddr);
+ segment->p_paddr = BYTE_GET (phdrs[i].p_paddr);
+ segment->p_filesz = BYTE_GET (phdrs[i].p_filesz);
+ segment->p_memsz = BYTE_GET (phdrs[i].p_memsz);
+ segment->p_flags = BYTE_GET (phdrs[i].p_flags);
+ segment->p_align = BYTE_GET (phdrs[i].p_align);
+ }
+
+ free (phdrs);
+
+ if (do_segments)
+ {
+ printf
+ (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
+ printf
+ (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
+ }
+
+ loadaddr = -1;
+ dynamic_addr = 0;
+
+ for (i = 0, segment = program_headers;
+ i < elf_header.e_phnum;
+ i ++, segment ++)
+ {
+ if (do_segments)
+ {
+ printf (" %-11.11s ", get_segment_type (segment->p_type));
+ printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
+ printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
+ printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
+ printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
+ printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
+ printf ("%c%c%c ",
+ (segment->p_flags & PF_R ? 'R' : ' '),
+ (segment->p_flags & PF_W ? 'W' : ' '),
+ (segment->p_flags & PF_X ? 'E' : ' '));
+ printf ("%#lx", (unsigned long) segment->p_align);
+ }
+
+ switch (segment->p_type)
+ {
+ case PT_LOAD:
+ if (loadaddr == -1)
+ loadaddr = (segment->p_vaddr & 0xfffff000)
+ - (segment->p_offset & 0xfffff000);
+ break;
+
+ case PT_DYNAMIC:
+ if (dynamic_addr)
+ error (_("more than one dynamic segment\n"));
+
+ dynamic_addr = segment->p_offset;
+ dynamic_size = segment->p_filesz;
+ break;
+
+ case PT_INTERP:
+ if (fseek (file, segment->p_offset, SEEK_SET))
+ error (_("Unable to find program interpreter name\n"));
+ else
+ {
+ program_interpreter[0] = 0;
+ fscanf (file, "%63s", program_interpreter);
+
+ if (do_segments)
+ printf (_("\n [Requesting program interpreter: %s]"),
+ program_interpreter);
+ }
+ break;
+ }
+
+ if (do_segments)
+ putc ('\n', stdout);
+ }
+
+ if (loadaddr == -1)
+ {
+ /* Very strange. */
+ loadaddr = 0;
+ }
+
+ if (do_segments && section_headers != NULL)
+ {
+ printf (_("\n Section to Segment mapping:\n"));
+ printf (_(" Segment Sections...\n"));
+
+ assert (string_table != NULL);
+
+ for (i = 0; i < elf_header.e_phnum; i++)
+ {
+ int j;
+ Elf32_Internal_Shdr * section;
+
+ segment = program_headers + i;
+ section = section_headers;
+
+ printf (" %2.2d ", i);
+
+ for (j = 0; j < elf_header.e_shnum; j++, section ++)
+ {
+ if (section->sh_size > 0
+ /* Compare allocated sections by VMA, unallocated
+ sections by file offset. */
+ && (section->sh_flags & SHF_ALLOC
+ ? (section->sh_addr >= segment->p_vaddr
+ && section->sh_addr + section->sh_size
+ <= segment->p_vaddr + segment->p_memsz)
+ : (section->sh_offset >= segment->p_offset
+ && (section->sh_offset + section->sh_size
+ <= segment->p_offset + segment->p_filesz))))
+ printf ("%s ", SECTION_NAME (section));
+ }
+
+ putc ('\n',stdout);
+ }
+ }
+
+ free (program_headers);
+
+ return 1;
+}
+
+
+static int
+get_section_headers (file)
+ FILE * file;
+{
+ Elf32_External_Shdr * shdrs;
+ Elf32_Internal_Shdr * internal;
+ unsigned int i;
+
+ GET_DATA_ALLOC (elf_header.e_shoff,
+ elf_header.e_shentsize * elf_header.e_shnum,
+ shdrs, Elf32_External_Shdr *, "section headers");
+
+ section_headers = (Elf32_Internal_Shdr *) malloc
+ (elf_header.e_shnum * sizeof (Elf32_Internal_Shdr));
+
+ if (section_headers == NULL)
+ {
+ error (_("Out of memory\n"));
+ return 0;
+ }
+
+ for (i = 0, internal = section_headers;
+ i < elf_header.e_shnum;
+ i ++, internal ++)
+ {
+ internal->sh_name = BYTE_GET (shdrs[i].sh_name);
+ internal->sh_type = BYTE_GET (shdrs[i].sh_type);
+ internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
+ internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
+ internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
+ internal->sh_size = BYTE_GET (shdrs[i].sh_size);
+ internal->sh_link = BYTE_GET (shdrs[i].sh_link);
+ internal->sh_info = BYTE_GET (shdrs[i].sh_info);
+ internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
+ internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
+ }
+
+ free (shdrs);
+
+ return 1;
+}
+
+static Elf_Internal_Sym *
+get_elf_symbols (file, offset, number)
+ FILE * file;
+ unsigned long offset;
+ unsigned long number;
+{
+ Elf32_External_Sym * esyms;
+ Elf_Internal_Sym * isyms;
+ Elf_Internal_Sym * psym;
+ unsigned int j;
+
+ GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
+ esyms, Elf32_External_Sym *, "symbols");
+
+ isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
+
+ if (isyms == NULL)
+ {
+ error (_("Out of memory\n"));
+ free (esyms);
+
+ return NULL;
+ }
+
+ for (j = 0, psym = isyms;
+ j < number;
+ j ++, psym ++)
+ {
+ psym->st_name = BYTE_GET (esyms[j].st_name);
+ psym->st_value = BYTE_GET (esyms[j].st_value);
+ psym->st_size = BYTE_GET (esyms[j].st_size);
+ psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
+ psym->st_info = BYTE_GET (esyms[j].st_info);
+ psym->st_other = BYTE_GET (esyms[j].st_other);
+ }
+
+ free (esyms);
+
+ return isyms;
+}
+
+static int
+process_section_headers (file)
+ FILE * file;
+{
+ Elf32_Internal_Shdr * section;
+ int i;
+
+ section_headers = NULL;
+
+ if (elf_header.e_shnum == 0)
+ {
+ if (do_sections)
+ printf (_("\nThere are no sections in this file.\n"));
+
+ return 1;
+ }
+
+ if (do_sections && !do_header)
+ printf (_("There are %d section headers, starting at offset %lx:\n"),
+ elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
+
+ if (! get_section_headers (file))
+ return 0;
+
+ /* Read in the string table, so that we have names to display. */
+ section = section_headers + elf_header.e_shstrndx;
+
+ if (section->sh_size != 0)
+ {
+ unsigned long string_table_offset;
+
+ string_table_offset = section->sh_offset;
+
+ GET_DATA_ALLOC (section->sh_offset, section->sh_size,
+ string_table, char *, "string table");
+ }
+
+ /* Scan the sections for the dynamic symbol table
+ and dynamic string table and debug sections. */
+ dynamic_symbols = NULL;
+ dynamic_strings = NULL;
+ dynamic_syminfo = NULL;
+ for (i = 0, section = section_headers;
+ i < elf_header.e_shnum;
+ i ++, section ++)
+ {
+ char * name = SECTION_NAME (section);
+
+ if (section->sh_type == SHT_DYNSYM)
+ {
+ if (dynamic_symbols != NULL)
+ {
+ error (_("File contains multiple dynamic symbol tables\n"));
+ continue;
+ }
+
+ dynamic_symbols = get_elf_symbols
+ (file, section->sh_offset,
+ section->sh_size / section->sh_entsize);
+ }
+ else if (section->sh_type == SHT_STRTAB
+ && strcmp (name, ".dynstr") == 0)
+ {
+ if (dynamic_strings != NULL)
+ {
+ error (_("File contains multiple dynamic string tables\n"));
+ continue;
+ }
+
+ GET_DATA_ALLOC (section->sh_offset, section->sh_size,
+ dynamic_strings, char *, "dynamic strings");
+ }
+ else if ((do_debugging || do_debug_info || do_debug_abbrevs
+ || do_debug_lines || do_debug_pubnames || do_debug_aranges)
+ && strncmp (name, ".debug_", 7) == 0)
+ {
+ name += 7;
+
+ if (do_debugging
+ || (do_debug_info && (strcmp (name, "info") == 0))
+ || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
+ || (do_debug_lines && (strcmp (name, "line") == 0))
+ || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
+ || (do_debug_aranges && (strcmp (name, "aranges") == 0))
+ )
+ request_dump (i, DEBUG_DUMP);
+ }
+ }
+
+ if (! do_sections)
+ return 1;
+
+ printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
+ printf
+ (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
+
+ for (i = 0, section = section_headers;
+ i < elf_header.e_shnum;
+ i ++, section ++)
+ {
+ printf (" [%2d] %-17.17s %-15.15s ",
+ i,
+ SECTION_NAME (section),
+ get_section_type_name (section->sh_type));
+
+ printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
+ (unsigned long) section->sh_addr,
+ (unsigned long) section->sh_offset,
+ (unsigned long) section->sh_size,
+ (unsigned long) section->sh_entsize);
+
+ printf (" %c%c%c %2ld %3lx %ld\n",
+ (section->sh_flags & SHF_WRITE ? 'W' : ' '),
+ (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
+ (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
+ (unsigned long) section->sh_link,
+ (unsigned long) section->sh_info,
+ (unsigned long) section->sh_addralign);
+ }
+
+ return 1;
+}
+
+/* Process the reloc section. */
+static int
+process_relocs (file)
+ FILE * file;
+{
+ unsigned long rel_size;
+ unsigned long rel_offset;
+
+
+ if (!do_reloc)
+ return 1;
+
+ if (do_using_dynamic)
+ {
+ rel_size = 0;
+ rel_offset = 0;
+
+ if (dynamic_info[DT_REL])
+ {
+ rel_offset = dynamic_info[DT_REL];
+ rel_size = dynamic_info[DT_RELSZ];
+ }
+ else if (dynamic_info [DT_RELA])
+ {
+ rel_offset = dynamic_info[DT_RELA];
+ rel_size = dynamic_info[DT_RELASZ];
+ }
+ else if (dynamic_info[DT_JMPREL])
+ {
+ rel_offset = dynamic_info[DT_JMPREL];
+ rel_size = dynamic_info[DT_PLTRELSZ];
+ }
+
+ if (rel_size)
+ {
+ printf
+ (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
+ rel_offset, rel_size);
+
+ dump_relocations (file, rel_offset - loadaddr, rel_size,
+ dynamic_symbols, dynamic_strings);
+ }
+ else
+ printf (_("\nThere are no dynamic relocations in this file.\n"));
+ }
+ else
+ {
+ Elf32_Internal_Shdr * section;
+ unsigned long i;
+ int found = 0;
+
+ for (i = 0, section = section_headers;
+ i < elf_header.e_shnum;
+ i++, section ++)
+ {
+ if ( section->sh_type != SHT_RELA
+ && section->sh_type != SHT_REL)
+ continue;
+
+ rel_offset = section->sh_offset;
+ rel_size = section->sh_size;
+
+ if (rel_size)
+ {
+ Elf32_Internal_Shdr * strsec;
+ Elf32_Internal_Shdr * symsec;
+ Elf_Internal_Sym * symtab;
+ char * strtab;
+
+ printf (_("\nRelocation section "));
+
+ if (string_table == NULL)
+ printf ("%d", section->sh_name);
+ else
+ printf ("'%s'", SECTION_NAME (section));
+
+ printf (_(" at offset 0x%lx contains %lu entries:\n"),
+ rel_offset, (unsigned long) (rel_size / section->sh_entsize));
+
+ symsec = section_headers + section->sh_link;
+
+ symtab = get_elf_symbols (file, symsec->sh_offset,
+ symsec->sh_size / symsec->sh_entsize);
+
+ if (symtab == NULL)
+ continue;
+
+ strsec = section_headers + symsec->sh_link;
+
+ GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
+ char *, "string table");
+
+ dump_relocations (file, rel_offset, rel_size, symtab, strtab);
+
+ free (strtab);
+ free (symtab);
+
+ found = 1;
+ }
+ }
+
+ if (! found)
+ printf (_("\nThere are no relocations in this file.\n"));
+ }
+
+ return 1;
+}
+
+
+static void
+dynamic_segment_mips_val (entry)
+ Elf_Internal_Dyn * entry;
+{
+ switch (entry->d_tag)
+ {
+ case DT_MIPS_FLAGS:
+ if (entry->d_un.d_val == 0)
+ printf ("NONE\n");
+ else
+ {
+ static const char * opts[] =
+ {
+ "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
+ "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
+ "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
+ "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
+ "RLD_ORDER_SAFE"
+ };
+ unsigned int cnt;
+ int first = 1;
+ for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
+ if (entry->d_un.d_val & (1 << cnt))
+ {
+ printf ("%s%s", first ? "" : " ", opts[cnt]);
+ first = 0;
+ }
+ puts ("");
+ }
+ break;
+
+ case DT_MIPS_IVERSION:
+ if (dynamic_strings != NULL)
+ printf ("Interface Version: %s\n",
+ dynamic_strings + entry->d_un.d_val);
+ else
+ printf ("%ld\n", (long) entry->d_un.d_ptr);
+ break;
+
+ case DT_MIPS_TIME_STAMP:
+ {
+ char timebuf[20];
+ time_t time = entry->d_un.d_val;
+ strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
+ printf ("Time Stamp: %s\n", timebuf);
+ }
+ break;
+
+ case DT_MIPS_RLD_VERSION:
+ case DT_MIPS_LOCAL_GOTNO:
+ case DT_MIPS_CONFLICTNO:
+ case DT_MIPS_LIBLISTNO:
+ case DT_MIPS_SYMTABNO:
+ case DT_MIPS_UNREFEXTNO:
+ case DT_MIPS_HIPAGENO:
+ case DT_MIPS_DELTA_CLASS_NO:
+ case DT_MIPS_DELTA_INSTANCE_NO:
+ case DT_MIPS_DELTA_RELOC_NO:
+ case DT_MIPS_DELTA_SYM_NO:
+ case DT_MIPS_DELTA_CLASSSYM_NO:
+ case DT_MIPS_COMPACT_SIZE:
+ printf ("%ld\n", (long) entry->d_un.d_ptr);
+ break;
+
+ default:
+ printf ("%#lx\n", (long) entry->d_un.d_ptr);
+ }
+}
+
+/* Parse the dynamic segment */
+static int
+process_dynamic_segment (file)
+ FILE * file;
+{
+ Elf_Internal_Dyn * entry;
+ Elf32_External_Dyn * edyn;
+ unsigned int i;
+
+ if (dynamic_size == 0)
+ {
+ if (do_dynamic)
+ printf (_("\nThere is no dynamic segment in this file.\n"));
+
+ return 1;
+ }
+
+ GET_DATA_ALLOC (dynamic_addr, dynamic_size,
+ edyn, Elf32_External_Dyn *, "dynamic segment");
+
+ /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
+ how large .dynamic is now. We can do this even before the byte
+ swapping since the DT_NULL tag is recognizable. */
+ dynamic_size = 0;
+ while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
+ ;
+
+ dynamic_segment = (Elf_Internal_Dyn *)
+ malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
+
+ if (dynamic_segment == NULL)
+ {
+ error (_("Out of memory\n"));
+ free (edyn);
+ return 0;
+ }
+
+ for (i = 0, entry = dynamic_segment;
+ i < dynamic_size;
+ i ++, entry ++)
+ {
+ entry->d_tag = BYTE_GET (edyn [i].d_tag);
+ entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
+ }
+
+ free (edyn);
+
+ /* Find the appropriate symbol table. */
+ if (dynamic_symbols == NULL)
+ {
+ for (i = 0, entry = dynamic_segment;
+ i < dynamic_size;
+ ++i, ++ entry)
+ {
+ unsigned long offset;
+ long num_syms;
+
+ if (entry->d_tag != DT_SYMTAB)
+ continue;
+
+ dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
+
+ /* Since we do not know how big the symbol table is,
+ we default to reading in the entire file (!) and
+ processing that. This is overkill, I know, but it
+ should work. */
+
+ offset = entry->d_un.d_val - loadaddr;
+
+ if (fseek (file, 0, SEEK_END))
+ error (_("Unable to seek to end of file!"));
+
+ num_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
+
+ if (num_syms < 1)
+ {
+ error (_("Unable to determine the number of symbols to load\n"));
+ continue;
+ }
+
+ dynamic_symbols = get_elf_symbols (file, offset, num_syms);
+ }
+ }
+
+ /* Similarly find a string table. */
+ if (dynamic_strings == NULL)
+ {
+ for (i = 0, entry = dynamic_segment;
+ i < dynamic_size;
+ ++i, ++ entry)
+ {
+ unsigned long offset;
+ long str_tab_len;
+
+ if (entry->d_tag != DT_STRTAB)
+ continue;
+
+ dynamic_info[DT_STRTAB] = entry->d_un.d_val;
+
+ /* Since we do not know how big the string table is,
+ we default to reading in the entire file (!) and
+ processing that. This is overkill, I know, but it
+ should work. */
+
+ offset = entry->d_un.d_val - loadaddr;
+ if (fseek (file, 0, SEEK_END))
+ error (_("Unable to seek to end of file\n"));
+ str_tab_len = ftell (file) - offset;
+
+ if (str_tab_len < 1)
+ {
+ error
+ (_("Unable to determine the length of the dynamic string table\n"));
+ continue;
+ }
+
+ GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
+ "dynamic string table");
+
+ break;
+ }
+ }
+
+ /* And find the syminfo section if available. */
+ if (dynamic_syminfo == NULL)
+ {
+ unsigned int syminsz = 0;
+
+ for (i = 0, entry = dynamic_segment;
+ i < dynamic_size;
+ ++i, ++ entry)
+ {
+ if (entry->d_tag == DT_SYMINENT)
+ {
+ /* Note: these braces are necessary to avoid a syntax
+ error from the SunOS4 C compiler. */
+ assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
+ }
+ else if (entry->d_tag == DT_SYMINSZ)
+ syminsz = entry->d_un.d_val;
+ else if (entry->d_tag == DT_SYMINFO)
+ dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
+ }
+
+ if (dynamic_syminfo_offset != 0 && syminsz != 0)
+ {
+ Elf_External_Syminfo *extsyminfo;
+ Elf_Internal_Syminfo *syminfo;
+
+ /* There is a syminfo section. Read the data. */
+ GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
+ Elf_External_Syminfo *, "symbol information");
+
+ dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
+ if (dynamic_syminfo == NULL)
+ {
+ error (_("Out of memory\n"));
+ return 0;
+ }
+
+ dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
+ for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
+ ++i, ++syminfo)
+ {
+ syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
+ syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
+ }
+
+ free (extsyminfo);
+ }
+ }
+
+ if (do_dynamic && dynamic_addr)
+ printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
+ dynamic_addr, dynamic_size);
+ if (do_dynamic)
+ printf (_(" Tag Type Name/Value\n"));
+
+ for (i = 0, entry = dynamic_segment;
+ i < dynamic_size;
+ i++, entry ++)
+ {
+ if (do_dynamic)
+ printf (_(" 0x%-8.8lx (%s)%*s"),
+ (unsigned long) entry->d_tag,
+ get_dynamic_type (entry->d_tag),
+ 27 - strlen (get_dynamic_type (entry->d_tag)),
+ " ");
+
+ switch (entry->d_tag)
+ {
+ case DT_AUXILIARY:
+ case DT_FILTER:
+ if (do_dynamic)
+ {
+ if (entry->d_tag == DT_AUXILIARY)
+ printf (_("Auxiliary library"));
+ else
+ printf (_("Filter library"));
+
+ if (dynamic_strings)
+ printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
+ else
+ printf (": %#lx\n", (long) entry->d_un.d_val);
+ }
+ break;
+
+ case DT_FEATURE_1:
+ if (do_dynamic)
+ {
+ printf (_("Flags:"));
+ if (entry->d_un.d_val == 0)
+ printf (_(" None\n"));
+ else
+ {
+ unsigned long int val = entry->d_un.d_val;
+ if (val & DTF_1_PARINIT)
+ {
+ printf (" PARINIT");
+ val ^= DTF_1_PARINIT;
+ }
+ if (val != 0)
+ printf (" %lx", val);
+ puts ("");
+ }
+ }
+ break;
+
+ case DT_POSFLAG_1:
+ if (do_dynamic)
+ {
+ printf (_("Flags:"));
+ if (entry->d_un.d_val == 0)
+ printf (_(" None\n"));
+ else
+ {
+ unsigned long int val = entry->d_un.d_val;
+ if (val & DF_P1_LAZYLOAD)
+ {
+ printf (" LAZYLOAD");
+ val ^= DF_P1_LAZYLOAD;
+ }
+ if (val & DF_P1_GROUPPERM)
+ {
+ printf (" GROUPPERM");
+ val ^= DF_P1_GROUPPERM;
+ }
+ if (val != 0)
+ printf (" %lx", val);
+ puts ("");
+ }
+ }
+ break;
+
+ case DT_FLAGS_1:
+ if (do_dynamic)
+ {
+ printf (_("Flags:"));
+ if (entry->d_un.d_val == 0)
+ printf (_(" None\n"));
+ else
+ {
+ unsigned long int val = entry->d_un.d_val;
+ if (val & DF_1_NOW)
+ {
+ printf (" NOW");
+ val ^= DF_1_NOW;
+ }
+ if (val & DF_1_GLOBAL)
+ {
+ printf (" GLOBAL");
+ val ^= DF_1_GLOBAL;
+ }
+ if (val & DF_1_GROUP)
+ {
+ printf (" GROUP");
+ val ^= DF_1_GROUP;
+ }
+ if (val & DF_1_NODELETE)
+ {
+ printf (" NODELETE");
+ val ^= DF_1_NODELETE;
+ }
+ if (val & DF_1_LOADFLTR)
+ {
+ printf (" LOADFLTR");
+ val ^= DF_1_LOADFLTR;
+ }
+ if (val & DF_1_INITFIRST)
+ {
+ printf (" INITFIRST");
+ val ^= DF_1_INITFIRST;
+ }
+ if (val & DF_1_NOOPEN)
+ {
+ printf (" NOOPEN");
+ val ^= DF_1_NOOPEN;
+ }
+ if (val & DF_1_ORIGIN)
+ {
+ printf (" ORIGIN");
+ val ^= DF_1_ORIGIN;
+ }
+ if (val & DF_1_DIRECT)
+ {
+ printf (" DIRECT");
+ val ^= DF_1_DIRECT;
+ }
+ if (val & DF_1_TRANS)
+ {
+ printf (" TRANS");
+ val ^= DF_1_TRANS;
+ }
+ if (val & DF_1_INTERPOSE)
+ {
+ printf (" INTERPOSE");
+ val ^= DF_1_INTERPOSE;
+ }
+ if (val != 0)
+ printf (" %lx", val);
+ puts ("");
+ }
+ }
+ break;
+
+ case DT_PLTREL:
+ if (do_dynamic)
+ puts (get_dynamic_type (entry->d_un.d_val));
+ break;
+
+ case DT_NULL :
+ case DT_NEEDED :
+ case DT_PLTGOT :
+ case DT_HASH :
+ case DT_STRTAB :
+ case DT_SYMTAB :
+ case DT_RELA :
+ case DT_INIT :
+ case DT_FINI :
+ case DT_SONAME :
+ case DT_RPATH :
+ case DT_SYMBOLIC:
+ case DT_REL :
+ case DT_DEBUG :
+ case DT_TEXTREL :
+ case DT_JMPREL :
+ dynamic_info[entry->d_tag] = entry->d_un.d_val;
+
+ if (do_dynamic)
+ {
+ char * name;
+
+ if (dynamic_strings == NULL)
+ name = NULL;
+ else
+ name = dynamic_strings + entry->d_un.d_val;
+
+ if (name)
+ {
+ switch (entry->d_tag)
+ {
+ case DT_NEEDED:
+ printf (_("Shared library: [%s]"), name);
+
+ if (strcmp (name, program_interpreter))
+ printf ("\n");
+ else
+ printf (_(" program interpreter\n"));
+ break;
+
+ case DT_SONAME:
+ printf (_("Library soname: [%s]\n"), name);
+ break;
+
+ case DT_RPATH:
+ printf (_("Library rpath: [%s]\n"), name);
+ break;
+
+ default:
+ printf ("%#lx\n", (long) entry->d_un.d_val);
+ }
+ }
+ else
+ printf ("%#lx\n", (long) entry->d_un.d_val);
+ }
+ break;
+
+ case DT_PLTRELSZ:
+ case DT_RELASZ :
+ case DT_STRSZ :
+ case DT_RELSZ :
+ case DT_RELAENT :
+ case DT_SYMENT :
+ case DT_RELENT :
+ case DT_PLTPADSZ:
+ case DT_MOVEENT :
+ case DT_MOVESZ :
+ case DT_INIT_ARRAYSZ:
+ case DT_FINI_ARRAYSZ:
+ if (do_dynamic)
+ printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
+ break;
+
+ case DT_VERDEFNUM:
+ case DT_VERNEEDNUM:
+ case DT_RELACOUNT:
+ case DT_RELCOUNT:
+ if (do_dynamic)
+ printf ("%lu\n", (unsigned long) entry->d_un.d_val);
+ break;
+
+ case DT_SYMINSZ:
+ case DT_SYMINENT:
+ case DT_SYMINFO:
+ case DT_USED:
+ case DT_INIT_ARRAY:
+ case DT_FINI_ARRAY:
+ if (do_dynamic)
+ {
+ if (dynamic_strings != NULL && entry->d_tag == DT_USED)
+ {
+ char * name;
+
+ name = dynamic_strings + entry->d_un.d_val;
+
+ if (* name)
+ {
+ printf (_("Not needed object: [%s]\n"), name);
+ break;
+ }
+ }
+
+ printf ("%#lx\n", (long) entry->d_un.d_val);
+ }
+ break;
+
+ case DT_BIND_NOW:
+ /* The value of this entry is ignored. */
+ break;
+
+ default:
+ if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
+ version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
+ entry->d_un.d_val;
+
+ if (do_dynamic)
+ {
+ switch (elf_header.e_machine)
+ {
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ dynamic_segment_mips_val (entry);
+ break;
+ default:
+ printf ("%#lx\n", (long) entry->d_un.d_ptr);
+ }
+ }
+ break;
+ }
+ }
+
+ return 1;
+}
+
+static char *
+get_ver_flags (flags)
+ unsigned int flags;
+{
+ static char buff [32];
+
+ buff[0] = 0;
+
+ if (flags == 0)
+ return _("none");
+
+ if (flags & VER_FLG_BASE)
+ strcat (buff, "BASE ");
+
+ if (flags & VER_FLG_WEAK)
+ {
+ if (flags & VER_FLG_BASE)
+ strcat (buff, "| ");
+
+ strcat (buff, "WEAK ");
+ }
+
+ if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
+ strcat (buff, "| <unknown>");
+
+ return buff;
+}
+
+/* Display the contents of the version sections. */
+static int
+process_version_sections (file)
+ FILE * file;
+{
+ Elf32_Internal_Shdr * section;
+ unsigned i;
+ int found = 0;
+
+ if (! do_version)
+ return 1;
+
+ for (i = 0, section = section_headers;
+ i < elf_header.e_shnum;
+ i++, section ++)
+ {
+ switch (section->sh_type)
+ {
+ case SHT_GNU_verdef:
+ {
+ Elf_External_Verdef * edefs;
+ unsigned int idx;
+ unsigned int cnt;
+
+ found = 1;
+
+ printf
+ (_("\nVersion definition section '%s' contains %ld entries:\n"),
+ SECTION_NAME (section), section->sh_info);
+
+ printf (_(" Addr: 0x"));
+ printf_vma (section->sh_addr);
+ printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
+ section->sh_offset, section->sh_link,
+ SECTION_NAME (section_headers + section->sh_link));
+
+ GET_DATA_ALLOC (section->sh_offset, section->sh_size,
+ edefs, Elf_External_Verdef *,
+ "version definition section");
+
+ for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
+ {
+ char * vstart;
+ Elf_External_Verdef * edef;
+ Elf_Internal_Verdef ent;
+ Elf_External_Verdaux * eaux;
+ Elf_Internal_Verdaux aux;
+ int j;
+ int isum;
+
+ vstart = ((char *) edefs) + idx;
+
+ edef = (Elf_External_Verdef *) vstart;
+
+ ent.vd_version = BYTE_GET (edef->vd_version);
+ ent.vd_flags = BYTE_GET (edef->vd_flags);
+ ent.vd_ndx = BYTE_GET (edef->vd_ndx);
+ ent.vd_cnt = BYTE_GET (edef->vd_cnt);
+ ent.vd_hash = BYTE_GET (edef->vd_hash);
+ ent.vd_aux = BYTE_GET (edef->vd_aux);
+ ent.vd_next = BYTE_GET (edef->vd_next);
+
+ printf (_(" %#06x: Rev: %d Flags: %s"),
+ idx, ent.vd_version, get_ver_flags (ent.vd_flags));
+
+ printf (_(" Index: %d Cnt: %d "),
+ ent.vd_ndx, ent.vd_cnt);
+
+ vstart += ent.vd_aux;
+
+ eaux = (Elf_External_Verdaux *) vstart;
+
+ aux.vda_name = BYTE_GET (eaux->vda_name);
+ aux.vda_next = BYTE_GET (eaux->vda_next);
+
+ if (dynamic_strings)
+ printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
+ else
+ printf (_("Name index: %ld\n"), aux.vda_name);
+
+ isum = idx + ent.vd_aux;
+
+ for (j = 1; j < ent.vd_cnt; j ++)
+ {
+ isum += aux.vda_next;
+ vstart += aux.vda_next;
+
+ eaux = (Elf_External_Verdaux *) vstart;
+
+ aux.vda_name = BYTE_GET (eaux->vda_name);
+ aux.vda_next = BYTE_GET (eaux->vda_next);
+
+ if (dynamic_strings)
+ printf (_(" %#06x: Parent %d: %s\n"),
+ isum, j, dynamic_strings + aux.vda_name);
+ else
+ printf (_(" %#06x: Parent %d, name index: %ld\n"),
+ isum, j, aux.vda_name);
+ }
+
+ idx += ent.vd_next;
+ }
+
+ free (edefs);
+ }
+ break;
+
+ case SHT_GNU_verneed:
+ {
+ Elf_External_Verneed * eneed;
+ unsigned int idx;
+ unsigned int cnt;
+
+ found = 1;
+
+ printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
+ SECTION_NAME (section), section->sh_info);
+
+ printf (_(" Addr: 0x"));
+ printf_vma (section->sh_addr);
+ printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
+ section->sh_offset, section->sh_link,
+ SECTION_NAME (section_headers + section->sh_link));
+
+ GET_DATA_ALLOC (section->sh_offset, section->sh_size,
+ eneed, Elf_External_Verneed *,
+ "version need section");
+
+ for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
+ {
+ Elf_External_Verneed * entry;
+ Elf_Internal_Verneed ent;
+ int j;
+ int isum;
+ char * vstart;
+
+ vstart = ((char *) eneed) + idx;
+
+ entry = (Elf_External_Verneed *) vstart;
+
+ ent.vn_version = BYTE_GET (entry->vn_version);
+ ent.vn_cnt = BYTE_GET (entry->vn_cnt);
+ ent.vn_file = BYTE_GET (entry->vn_file);
+ ent.vn_aux = BYTE_GET (entry->vn_aux);
+ ent.vn_next = BYTE_GET (entry->vn_next);
+
+ printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
+
+ if (dynamic_strings)
+ printf (_(" File: %s"), dynamic_strings + ent.vn_file);
+ else
+ printf (_(" File: %lx"), ent.vn_file);
+
+ printf (_(" Cnt: %d\n"), ent.vn_cnt);
+
+ vstart += ent.vn_aux;
+
+ for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
+ {
+ Elf_External_Vernaux * eaux;
+ Elf_Internal_Vernaux aux;
+
+ eaux = (Elf_External_Vernaux *) vstart;
+
+ aux.vna_hash = BYTE_GET (eaux->vna_hash);
+ aux.vna_flags = BYTE_GET (eaux->vna_flags);
+ aux.vna_other = BYTE_GET (eaux->vna_other);
+ aux.vna_name = BYTE_GET (eaux->vna_name);
+ aux.vna_next = BYTE_GET (eaux->vna_next);
+
+ if (dynamic_strings)
+ printf (_(" %#06x: Name: %s"),
+ isum, dynamic_strings + aux.vna_name);
+ else
+ printf (_(" %#06x: Name index: %lx"),
+ isum, aux.vna_name);
+
+ printf (_(" Flags: %s Version: %d\n"),
+ get_ver_flags (aux.vna_flags), aux.vna_other);
+
+ isum += aux.vna_next;
+ vstart += aux.vna_next;
+ }
+
+ idx += ent.vn_next;
+ }
+
+ free (eneed);
+ }
+ break;
+
+ case SHT_GNU_versym:
+ {
+ Elf32_Internal_Shdr * link_section;
+ int total;
+ int cnt;
+ unsigned char * edata;
+ unsigned short * data;
+ char * strtab;
+ Elf_Internal_Sym * symbols;
+ Elf32_Internal_Shdr * string_sec;
+
+ link_section = section_headers + section->sh_link;
+ total = section->sh_size / section->sh_entsize;
+
+ found = 1;
+
+ symbols = get_elf_symbols
+ (file, link_section->sh_offset,
+ link_section->sh_size / link_section->sh_entsize);
+
+ string_sec = section_headers + link_section->sh_link;
+
+ GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
+ strtab, char *, "version string table");
+
+ printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
+ SECTION_NAME (section), total);
+
+ printf (_(" Addr: "));
+ printf_vma (section->sh_addr);
+ printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
+ section->sh_offset, section->sh_link,
+ SECTION_NAME (link_section));
+
+ GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
+ - loadaddr,
+ total * sizeof (short), edata,
+ unsigned char *, "version symbol data");
+
+ data = (unsigned short *) malloc (total * sizeof (short));
+
+ for (cnt = total; cnt --;)
+ data [cnt] = byte_get (edata + cnt * sizeof (short),
+ sizeof (short));
+
+ free (edata);
+
+ for (cnt = 0; cnt < total; cnt += 4)
+ {
+ int j, nn;
+
+ printf (" %03x:", cnt);
+
+ for (j = 0; (j < 4) && (cnt + j) < total; ++j)
+ switch (data [cnt + j])
+ {
+ case 0:
+ fputs (_(" 0 (*local*) "), stdout);
+ break;
+
+ case 1:
+ fputs (_(" 1 (*global*) "), stdout);
+ break;
+
+ default:
+ nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
+ data [cnt + j] & 0x8000 ? 'h' : ' ');
+
+ if (symbols [cnt + j].st_shndx < SHN_LORESERVE
+ && section_headers[symbols [cnt + j].st_shndx].sh_type
+ == SHT_NOBITS)
+ {
+ /* We must test both. */
+ Elf_Internal_Verneed ivn;
+ unsigned long offset;
+
+ offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
+ - loadaddr;
+
+ do
+ {
+ Elf_External_Verneed evn;
+ Elf_External_Vernaux evna;
+ Elf_Internal_Vernaux ivna;
+ unsigned long vna_off;
+
+ GET_DATA (offset, evn, "version need");
+
+ ivn.vn_aux = BYTE_GET (evn.vn_aux);
+ ivn.vn_next = BYTE_GET (evn.vn_next);
+
+ vna_off = offset + ivn.vn_aux;
+
+ do
+ {
+ GET_DATA (vna_off, evna,
+ "version need aux (1)");
+
+ ivna.vna_next = BYTE_GET (evna.vna_next);
+ ivna.vna_other = BYTE_GET (evna.vna_other);
+
+ vna_off += ivna.vna_next;
+ }
+ while (ivna.vna_other != data [cnt + j]
+ && ivna.vna_next != 0);
+
+ if (ivna.vna_other == data [cnt + j])
+ {
+ ivna.vna_name = BYTE_GET (evna.vna_name);
+
+ nn += printf ("(%s%-*s",
+ strtab + ivna.vna_name,
+ 12 - strlen (strtab
+ + ivna.vna_name),
+ ")");
+ break;
+ }
+ else if (ivn.vn_next == 0)
+ {
+ if (data [cnt + j] != 0x8001)
+ {
+ Elf_Internal_Verdef ivd;
+ Elf_External_Verdef evd;
+
+ offset = version_info
+ [DT_VERSIONTAGIDX (DT_VERDEF)]
+ - loadaddr;
+
+ do
+ {
+ GET_DATA (offset, evd,
+ "version definition");
+
+ ivd.vd_next = BYTE_GET (evd.vd_next);
+ ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+
+ offset += ivd.vd_next;
+ }
+ while (ivd.vd_ndx
+ != (data [cnt + j] & 0x7fff)
+ && ivd.vd_next != 0);
+
+ if (ivd.vd_ndx
+ == (data [cnt + j] & 0x7fff))
+ {
+ Elf_External_Verdaux evda;
+ Elf_Internal_Verdaux ivda;
+
+ ivd.vd_aux = BYTE_GET (evd.vd_aux);
+
+ GET_DATA (offset + ivd.vd_aux, evda,
+ "version definition aux");
+
+ ivda.vda_name =
+ BYTE_GET (evda.vda_name);
+
+ nn +=
+ printf ("(%s%-*s",
+ strtab + ivda.vda_name,
+ 12
+ - strlen (strtab
+ + ivda.vda_name),
+ ")");
+ }
+ }
+
+ break;
+ }
+ else
+ offset += ivn.vn_next;
+ }
+ while (ivn.vn_next);
+ }
+ else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
+ {
+ Elf_Internal_Verneed ivn;
+ unsigned long offset;
+
+ offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
+ - loadaddr;
+
+ do
+ {
+ Elf_Internal_Vernaux ivna;
+ Elf_External_Verneed evn;
+ Elf_External_Vernaux evna;
+ unsigned long a_off;
+
+ GET_DATA (offset, evn, "version need");
+
+ ivn.vn_aux = BYTE_GET (evn.vn_aux);
+ ivn.vn_next = BYTE_GET (evn.vn_next);
+
+ a_off = offset + ivn.vn_aux;
+
+ do
+ {
+ GET_DATA (a_off, evna,
+ "version need aux (2)");
+
+ ivna.vna_next = BYTE_GET (evna.vna_next);
+ ivna.vna_other = BYTE_GET (evna.vna_other);
+
+ a_off += ivna.vna_next;
+ }
+ while (ivna.vna_other != data [cnt + j]
+ && ivna.vna_next != 0);
+
+ if (ivna.vna_other == data [cnt + j])
+ {
+ ivna.vna_name = BYTE_GET (evna.vna_name);
+
+ nn += printf ("(%s%-*s",
+ strtab + ivna.vna_name,
+ 12 - strlen (strtab
+ + ivna.vna_name),
+ ")");
+ break;
+ }
+
+ offset += ivn.vn_next;
+ }
+ while (ivn.vn_next);
+ }
+ else if (data [cnt + j] != 0x8001)
+ {
+ Elf_Internal_Verdef ivd;
+ Elf_External_Verdef evd;
+ unsigned long offset;
+
+ offset = version_info
+ [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
+
+ do
+ {
+ GET_DATA (offset, evd, "version def");
+
+ ivd.vd_next = BYTE_GET (evd.vd_next);
+ ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+
+ offset += ivd.vd_next;
+ }
+ while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
+ && ivd.vd_next != 0);
+
+ if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
+ {
+ Elf_External_Verdaux evda;
+ Elf_Internal_Verdaux ivda;
+
+ ivd.vd_aux = BYTE_GET (evd.vd_aux);
+
+ GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
+ evda, "version def aux");
+
+ ivda.vda_name = BYTE_GET (evda.vda_name);
+
+ nn += printf ("(%s%-*s",
+ strtab + ivda.vda_name,
+ 12 - strlen (strtab
+ + ivda.vda_name),
+ ")");
+ }
+ }
+
+ if (nn < 18)
+ printf ("%*c", 18 - nn, ' ');
+ }
+
+ putchar ('\n');
+ }
+
+ free (data);
+ free (strtab);
+ free (symbols);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (! found)
+ printf (_("\nNo version information found in this file.\n"));
+
+ return 1;
+}
+
+static char *
+get_symbol_binding (binding)
+ unsigned int binding;
+{
+ static char buff [32];
+
+ switch (binding)
+ {
+ case STB_LOCAL: return _("LOCAL");
+ case STB_GLOBAL: return _("GLOBAL");
+ case STB_WEAK: return _("WEAK");
+ default:
+ if (binding >= STB_LOPROC && binding <= STB_HIPROC)
+ sprintf (buff, _("<processor specific>: %d"), binding);
+ else if (binding >= STB_LOOS && binding <= STB_HIOS)
+ sprintf (buff, _("<OS specific>: %d"), binding);
+ else
+ sprintf (buff, _("<unknown>: %d"), binding);
+ return buff;
+ }
+}
+
+static char *
+get_symbol_type (type)
+ unsigned int type;
+{
+ static char buff [32];
+
+ switch (type)
+ {
+ case STT_NOTYPE: return _("NOTYPE");
+ case STT_OBJECT: return _("OBJECT");
+ case STT_FUNC: return _("FUNC");
+ case STT_SECTION: return _("SECTION");
+ case STT_FILE: return _("FILE");
+ default:
+ if (type >= STT_LOPROC && type <= STT_HIPROC)
+ sprintf (buff, _("<processor specific>: %d"), type);
+ else if (type >= STT_LOOS && type <= STT_HIOS)
+ sprintf (buff, _("<OS specific>: %d"), type);
+ else
+ sprintf (buff, _("<unknown>: %d"), type);
+ return buff;
+ }
+}
+
+static char *
+get_symbol_index_type (type)
+ unsigned int type;
+{
+ switch (type)
+ {
+ case SHN_UNDEF: return "UND";
+ case SHN_ABS: return "ABS";
+ case SHN_COMMON: return "COM";
+ default:
+ if (type >= SHN_LOPROC && type <= SHN_HIPROC)
+ return "PRC";
+ else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
+ return "RSV";
+ else if (type >= SHN_LOOS && type <= SHN_HIOS)
+ return "OS ";
+ else
+ {
+ static char buff [32];
+
+ sprintf (buff, "%3d", type);
+ return buff;
+ }
+ }
+}
+
+
+static int *
+get_dynamic_data (file, number)
+ FILE * file;
+ unsigned int number;
+{
+ char * e_data;
+ int * i_data;
+
+ e_data = (char *) malloc (number * 4);
+
+ if (e_data == NULL)
+ {
+ error (_("Out of memory\n"));
+ return NULL;
+ }
+
+ if (fread (e_data, 4, number, file) != number)
+ {
+ error (_("Unable to read in dynamic data\n"));
+ return NULL;
+ }
+
+ i_data = (int *) malloc (number * sizeof (* i_data));
+
+ if (i_data == NULL)
+ {
+ error (_("Out of memory\n"));
+ free (e_data);
+ return NULL;
+ }
+
+ while (number--)
+ i_data [number] = byte_get (e_data + number * 4, 4);
+
+ free (e_data);
+
+ return i_data;
+}
+
+/* Dump the symbol table */
+static int
+process_symbol_table (file)
+ FILE * file;
+{
+ Elf32_Internal_Shdr * section;
+ char nb [4];
+ char nc [4];
+ int nbuckets;
+ int nchains;
+ int * buckets = NULL;
+ int * chains = NULL;
+
+ if (! do_syms && !do_histogram)
+ return 1;
+
+ if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
+ || do_histogram))
+ {
+ if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
+ {
+ error (_("Unable to seek to start of dynamic information"));
+ return 0;
+ }
+
+ if (fread (nb, sizeof (nb), 1, file) != 1)
+ {
+ error (_("Failed to read in number of buckets\n"));
+ return 0;
+ }
+
+ if (fread (nc, sizeof (nc), 1, file) != 1)
+ {
+ error (_("Failed to read in number of chains\n"));
+ return 0;
+ }
+
+ nbuckets = byte_get (nb, 4);
+ nchains = byte_get (nc, 4);
+
+ buckets = get_dynamic_data (file, nbuckets);
+ chains = get_dynamic_data (file, nchains);
+
+ if (buckets == NULL || chains == NULL)
+ return 0;
+ }
+
+ if (do_syms
+ && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
+ {
+ int hn;
+ int si;
+
+ printf (_("\nSymbol table for image:\n"));
+ printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
+
+ for (hn = 0; hn < nbuckets; hn++)
+ {
+ if (! buckets [hn])
+ continue;
+
+ for (si = buckets [hn]; si; si = chains [si])
+ {
+ Elf_Internal_Sym * psym;
+
+ psym = dynamic_symbols + si;
+
+ printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
+ si, hn,
+ (unsigned long) psym->st_value,
+ (unsigned long) psym->st_size,
+ get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+ get_symbol_binding (ELF_ST_BIND (psym->st_info)),
+ psym->st_other);
+
+ printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
+
+ printf (" %s\n", dynamic_strings + psym->st_name);
+ }
+ }
+ }
+ else if (do_syms && !do_using_dynamic)
+ {
+ unsigned int i;
+
+ for (i = 0, section = section_headers;
+ i < elf_header.e_shnum;
+ i++, section++)
+ {
+ unsigned int si;
+ char * strtab;
+ Elf_Internal_Sym * symtab;
+ Elf_Internal_Sym * psym;
+
+
+ if ( section->sh_type != SHT_SYMTAB
+ && section->sh_type != SHT_DYNSYM)
+ continue;
+
+ printf (_("\nSymbol table '%s' contains %lu entries:\n"),
+ SECTION_NAME (section),
+ (unsigned long) (section->sh_size / section->sh_entsize));
+ fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
+ stdout);
+
+ symtab = get_elf_symbols (file, section->sh_offset,
+ section->sh_size / section->sh_entsize);
+ if (symtab == NULL)
+ continue;
+
+ if (section->sh_link == elf_header.e_shstrndx)
+ strtab = string_table;
+ else
+ {
+ Elf32_Internal_Shdr * string_sec;
+
+ string_sec = section_headers + section->sh_link;
+
+ GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
+ strtab, char *, "string table");
+ }
+
+ for (si = 0, psym = symtab;
+ si < section->sh_size / section->sh_entsize;
+ si ++, psym ++)
+ {
+ printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
+ si,
+ (unsigned long) psym->st_value,
+ (unsigned long) psym->st_size,
+ get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+ get_symbol_binding (ELF_ST_BIND (psym->st_info)),
+ psym->st_other);
+
+ if (psym->st_shndx == 0)
+ fputs (" UND", stdout);
+ else if ((psym->st_shndx & 0xffff) == 0xfff1)
+ fputs (" ABS", stdout);
+ else if ((psym->st_shndx & 0xffff) == 0xfff2)
+ fputs (" COM", stdout);
+ else
+ printf ("%4x", psym->st_shndx);
+
+ printf (" %s", strtab + psym->st_name);
+
+ if (section->sh_type == SHT_DYNSYM &&
+ version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
+ {
+ unsigned char data[2];
+ unsigned short vers_data;
+ unsigned long offset;
+ int is_nobits;
+ int check_def;
+
+ offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
+ - loadaddr;
+
+ GET_DATA (offset + si * sizeof (vers_data), data,
+ "version data");
+
+ vers_data = byte_get (data, 2);
+
+ is_nobits = psym->st_shndx < SHN_LORESERVE ?
+ (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
+ : 0;
+
+ check_def = (psym->st_shndx != SHN_UNDEF);
+
+ if ((vers_data & 0x8000) || vers_data > 1)
+ {
+ if (is_nobits || ! check_def)
+ {
+ Elf_External_Verneed evn;
+ Elf_Internal_Verneed ivn;
+ Elf_Internal_Vernaux ivna;
+
+ /* We must test both. */
+ offset = version_info
+ [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
+
+ GET_DATA (offset, evn, "version need");
+
+ ivn.vn_aux = BYTE_GET (evn.vn_aux);
+ ivn.vn_next = BYTE_GET (evn.vn_next);
+
+ do
+ {
+ unsigned long vna_off;
+
+ vna_off = offset + ivn.vn_aux;
+
+ do
+ {
+ Elf_External_Vernaux evna;
+
+ GET_DATA (vna_off, evna,
+ "version need aux (3)");
+
+ ivna.vna_other = BYTE_GET (evna.vna_other);
+ ivna.vna_next = BYTE_GET (evna.vna_next);
+ ivna.vna_name = BYTE_GET (evna.vna_name);
+
+ vna_off += ivna.vna_next;
+ }
+ while (ivna.vna_other != vers_data
+ && ivna.vna_next != 0);
+
+ if (ivna.vna_other == vers_data)
+ break;
+
+ offset += ivn.vn_next;
+ }
+ while (ivn.vn_next != 0);
+
+ if (ivna.vna_other == vers_data)
+ {
+ printf ("@%s (%d)",
+ strtab + ivna.vna_name, ivna.vna_other);
+ check_def = 0;
+ }
+ else if (! is_nobits)
+ error (_("bad dynamic symbol"));
+ else
+ check_def = 1;
+ }
+
+ if (check_def)
+ {
+ if (vers_data != 0x8001)
+ {
+ Elf_Internal_Verdef ivd;
+ Elf_Internal_Verdaux ivda;
+ Elf_External_Verdaux evda;
+ unsigned long offset;
+
+ offset =
+ version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
+ - loadaddr;
+
+ do
+ {
+ Elf_External_Verdef evd;
+
+ GET_DATA (offset, evd, "version def");
+
+ ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+ ivd.vd_aux = BYTE_GET (evd.vd_aux);
+ ivd.vd_next = BYTE_GET (evd.vd_next);
+
+ offset += ivd.vd_next;
+ }
+ while (ivd.vd_ndx != (vers_data & 0x7fff)
+ && ivd.vd_next != 0);
+
+ offset -= ivd.vd_next;
+ offset += ivd.vd_aux;
+
+ GET_DATA (offset, evda, "version def aux");
+
+ ivda.vda_name = BYTE_GET (evda.vda_name);
+
+ if (psym->st_name != ivda.vda_name)
+ printf ((vers_data & 0x8000)
+ ? "@%s" : "@@%s",
+ strtab + ivda.vda_name);
+ }
+ }
+ }
+ }
+
+ putchar ('\n');
+ }
+
+ free (symtab);
+ if (strtab != string_table)
+ free (strtab);
+ }
+ }
+ else if (do_syms)
+ printf
+ (_("\nDynamic symbol information is not available for displaying symbols.\n"));
+
+ if (do_histogram && buckets != NULL)
+ {
+ int *lengths;
+ int *counts;
+ int hn;
+ int si;
+ int maxlength = 0;
+ int nzero_counts = 0;
+ int nsyms = 0;
+
+ printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
+ nbuckets);
+ printf (_(" Length Number %% of total Coverage\n"));
+
+ lengths = (int *) calloc (nbuckets, sizeof (int));
+ if (lengths == NULL)
+ {
+ error (_("Out of memory"));
+ return 0;
+ }
+ for (hn = 0; hn < nbuckets; ++hn)
+ {
+ if (! buckets [hn])
+ continue;
+
+ for (si = buckets[hn]; si; si = chains[si])
+ {
+ ++nsyms;
+ if (maxlength < ++lengths[hn])
+ ++maxlength;
+ }
+ }
+
+ counts = (int *) calloc (maxlength + 1, sizeof (int));
+ if (counts == NULL)
+ {
+ error (_("Out of memory"));
+ return 0;
+ }
+
+ for (hn = 0; hn < nbuckets; ++hn)
+ ++ counts [lengths [hn]];
+
+ printf (" 0 %-10d (%5.1f%%)\n",
+ counts[0], (counts[0] * 100.0) / nbuckets);
+ for (si = 1; si <= maxlength; ++si)
+ {
+ nzero_counts += counts[si] * si;
+ printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
+ si, counts[si], (counts[si] * 100.0) / nbuckets,
+ (nzero_counts * 100.0) / nsyms);
+ }
+
+ free (counts);
+ free (lengths);
+ }
+
+ if (buckets != NULL)
+ {
+ free (buckets);
+ free (chains);
+ }
+
+ return 1;
+}
+
+static int
+process_syminfo (file)
+ FILE * file;
+{
+ int i;
+
+ if (dynamic_syminfo == NULL
+ || !do_dynamic)
+ /* No syminfo, this is ok. */
+ return 1;
+
+ /* There better should be a dynamic symbol section. */
+ if (dynamic_symbols == NULL || dynamic_strings == NULL)
+ return 0;
+
+ if (dynamic_addr)
+ printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
+ dynamic_syminfo_offset, dynamic_syminfo_nent);
+
+ printf (_(" Num: Name BoundTo Flags\n"));
+ for (i = 0; i < dynamic_syminfo_nent; ++i)
+ {
+ unsigned short int flags = dynamic_syminfo[i].si_flags;
+
+ printf ("%4d: %-30s ", i,
+ dynamic_strings + dynamic_symbols[i].st_name);
+
+ switch (dynamic_syminfo[i].si_boundto)
+ {
+ case SYMINFO_BT_SELF:
+ fputs ("SELF ", stdout);
+ break;
+ case SYMINFO_BT_PARENT:
+ fputs ("PARENT ", stdout);
+ break;
+ default:
+ if (dynamic_syminfo[i].si_boundto > 0
+ && dynamic_syminfo[i].si_boundto < dynamic_size)
+ printf ("%-10s ",
+ dynamic_strings
+ + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
+ else
+ printf ("%-10d ", dynamic_syminfo[i].si_boundto);
+ break;
+ }
+
+ if (flags & SYMINFO_FLG_DIRECT)
+ printf (" DIRECT");
+ if (flags & SYMINFO_FLG_PASSTHRU)
+ printf (" PASSTHRU");
+ if (flags & SYMINFO_FLG_COPY)
+ printf (" COPY");
+ if (flags & SYMINFO_FLG_LAZYLOAD)
+ printf (" LAZYLOAD");
+
+ puts ("");
+ }
+
+ return 1;
+}
+
+#ifdef SUPPORT_DISASSEMBLY
+static void
+disassemble_section (section, file)
+ Elf32_Internal_Shdr * section;
+ FILE * file;
+{
+ printf (_("\nAssembly dump of section %s\n"),
+ SECTION_NAME (section));
+
+ /* XXX -- to be done --- XXX */
+
+ return 1;
+}
+#endif
+
+static int
+dump_section (section, file)
+ Elf32_Internal_Shdr * section;
+ FILE * file;
+{
+ int bytes;
+ int addr;
+ unsigned char * data;
+ unsigned char * start;
+
+ bytes = section->sh_size;
+
+ if (bytes == 0)
+ {
+ printf (_("\nSection '%s' has no data to dump.\n"),
+ SECTION_NAME (section));
+ return 0;
+ }
+ else
+ printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
+
+ addr = section->sh_addr;
+
+ GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
+ "section data");
+
+ data = start;
+
+ while (bytes)
+ {
+ int j;
+ int k;
+ int lbytes;
+
+ lbytes = (bytes > 16 ? 16 : bytes);
+
+ printf (" 0x%8.8x ", addr);
+
+ switch (elf_header.e_ident [EI_DATA])
+ {
+ case ELFDATA2LSB:
+ for (j = 15; j >= 0; j --)
+ {
+ if (j < lbytes)
+ printf ("%2.2x", data [j]);
+ else
+ printf (" ");
+
+ if (!(j & 0x3))
+ printf (" ");
+ }
+ break;
+
+ case ELFDATA2MSB:
+ for (j = 0; j < 16; j++)
+ {
+ if (j < lbytes)
+ printf ("%2.2x", data [j]);
+ else
+ printf (" ");
+
+ if ((j & 3) == 3)
+ printf (" ");
+ }
+ break;
+ }
+
+ for (j = 0; j < lbytes; j++)
+ {
+ k = data [j];
+ if (k >= ' ' && k < 0x80)
+ printf ("%c", k);
+ else
+ printf (".");
+ }
+
+ putchar ('\n');
+
+ data += lbytes;
+ addr += lbytes;
+ bytes -= lbytes;
+ }
+
+ free (start);
+
+ return 1;
+}
+
+
+static unsigned long int
+read_leb128 (data, length_return, sign)
+ unsigned char * data;
+ int * length_return;
+ int sign;
+{
+ unsigned long int result = 0;
+ unsigned int num_read = 0;
+ int shift = 0;
+ unsigned char byte;
+
+ do
+ {
+ byte = * data ++;
+ num_read ++;
+
+ result |= (byte & 0x7f) << shift;
+
+ shift += 7;
+
+ }
+ while (byte & 0x80);
+
+ if (length_return != NULL)
+ * length_return = num_read;
+
+ if (sign && (shift < 32) && (byte & 0x40))
+ result |= -1 << shift;
+
+ return result;
+}
+
+typedef struct State_Machine_Registers
+{
+ unsigned long address;
+ unsigned int file;
+ unsigned int line;
+ unsigned int column;
+ int is_stmt;
+ int basic_block;
+ int end_sequence;
+/* This variable hold the number of the last entry seen
+ in the File Table. */
+ unsigned int last_file_entry;
+} SMR;
+
+static SMR state_machine_regs;
+
+static void
+reset_state_machine (is_stmt)
+ int is_stmt;
+{
+ state_machine_regs.address = 0;
+ state_machine_regs.file = 1;
+ state_machine_regs.line = 1;
+ state_machine_regs.column = 0;
+ state_machine_regs.is_stmt = is_stmt;
+ state_machine_regs.basic_block = 0;
+ state_machine_regs.end_sequence = 0;
+ state_machine_regs.last_file_entry = 0;
+}
+
+/* Handled an extend line op. Returns true if this is the end
+ of sequence. */
+static int
+process_extended_line_op (data, is_stmt)
+ unsigned char * data;
+ int is_stmt;
+{
+ unsigned char op_code;
+ int bytes_read;
+ unsigned int len;
+ unsigned char * name;
+ unsigned long adr;
+
+ len = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+
+ if (len == 0)
+ {
+ warn (_("badly formed extended line op encountered!"));
+ return bytes_read;
+ }
+
+ len += bytes_read;
+ op_code = * data ++;
+
+ printf (_(" Extended opcode %d: "), op_code);
+
+ switch (op_code)
+ {
+ case DW_LNE_end_sequence:
+ printf (_("End of Sequence\n\n"));
+ reset_state_machine (is_stmt);
+ break;
+
+ case DW_LNE_set_address:
+ /* XXX - assumption here that address size is 4! */
+ adr = byte_get (data, 4);
+ printf (_("set Address to 0x%lx\n"), adr);
+ state_machine_regs.address = adr;
+ break;
+
+ case DW_LNE_define_file:
+ printf (_(" define new File Table entry\n"));
+ printf (_(" Entry\tDir\tTime\tSize\tName\n"));
+
+ printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
+ name = data;
+ data += strlen (data) + 1;
+ printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+ data += bytes_read;
+ printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+ data += bytes_read;
+ printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+ printf (_("%s\n\n"), name);
+ break;
+
+ default:
+ printf (_("UNKNOWN: length %d\n"), len - bytes_read);
+ break;
+ }
+
+ return len;
+}
+
+
+static int
+display_debug_lines (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file;
+{
+ DWARF2_External_LineInfo * external;
+ DWARF2_Internal_LineInfo info;
+ unsigned char * standard_opcodes;
+ unsigned char * data = start;
+ unsigned char * end = start + section->sh_size;
+ unsigned char * end_of_sequence;
+ int i;
+
+ printf (_("\nDump of debug contents of section %s:\n\n"),
+ SECTION_NAME (section));
+
+ while (data < end)
+ {
+ external = (DWARF2_External_LineInfo *) data;
+
+ /* Check the length of the block. */
+ info.li_length = BYTE_GET (external->li_length);
+ if (info.li_length > section->sh_size)
+ {
+ warn
+ (_("The line info appears to be corrupt - the section is too small\n"));
+ return 0;
+ }
+
+ /* Check its version number. */
+ info.li_version = BYTE_GET (external->li_version);
+ if (info.li_version != 2)
+ {
+ warn (_("Only DWARF version 2 line info is currently supported.\n"));
+ return 0;
+ }
+
+ info.li_prologue_length = BYTE_GET (external->li_prologue_length);
+ info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
+ info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
+ info.li_line_base = BYTE_GET (external->li_line_base);
+ info.li_line_range = BYTE_GET (external->li_line_range);
+ info.li_opcode_base = BYTE_GET (external->li_opcode_base);
+
+ /* Sign extend the line base field. */
+ info.li_line_base <<= 24;
+ info.li_line_base >>= 24;
+
+ printf (_(" Length: %ld\n"), info.li_length);
+ printf (_(" DWARF Version: %d\n"), info.li_version);
+ printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
+ printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
+ printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
+ printf (_(" Line Base: %d\n"), info.li_line_base);
+ printf (_(" Line Range: %d\n"), info.li_line_range);
+ printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
+
+ end_of_sequence = data + info.li_length + sizeof (info.li_length);
+
+ reset_state_machine (info.li_default_is_stmt);
+
+ /* Display the contents of the Opcodes table. */
+ standard_opcodes = data + sizeof (* external);
+
+ printf (_("\n Opcodes:\n"));
+
+ for (i = 1; i < info.li_opcode_base; i++)
+ printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
+
+ /* Display the contents of the Directory table. */
+ data = standard_opcodes + info.li_opcode_base - 1;
+
+ if (* data == 0)
+ printf (_("\n The Directory Table is empty.\n"));
+ else
+ {
+ printf (_("\n The Directory Table:\n"));
+
+ while (* data != 0)
+ {
+ printf (_(" %s\n"), data);
+
+ data += strlen (data) + 1;
+ }
+ }
+
+ /* Skip the NUL at the end of the table. */
+ data ++;
+
+ /* Display the contents of the File Name table. */
+ if (* data == 0)
+ printf (_("\n The File Name Table is empty.\n"));
+ else
+ {
+ printf (_("\n The File Name Table:\n"));
+ printf (_(" Entry\tDir\tTime\tSize\tName\n"));
+
+ while (* data != 0)
+ {
+ char * name;
+ int bytes_read;
+
+ printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
+ name = data;
+
+ data += strlen (data) + 1;
+
+ printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+ data += bytes_read;
+ printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+ data += bytes_read;
+ printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
+ data += bytes_read;
+ printf (_("%s\n"), name);
+ }
+ }
+
+ /* Skip the NUL at the end of the table. */
+ data ++;
+
+ /* Now display the statements. */
+ printf (_("\n Line Number Statements:\n"));
+
+
+ while (data < end_of_sequence)
+ {
+ unsigned char op_code;
+ int adv;
+ int bytes_read;
+
+ op_code = * data ++;
+
+ switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ data += process_extended_line_op (data, info.li_default_is_stmt);
+ break;
+
+ case DW_LNS_copy:
+ printf (_(" Copy\n"));
+ break;
+
+ case DW_LNS_advance_pc:
+ adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ state_machine_regs.address += adv;
+ printf (_(" Advance PC by %d to %lx\n"), adv,
+ state_machine_regs.address);
+ break;
+
+ case DW_LNS_advance_line:
+ adv = read_leb128 (data, & bytes_read, 1);
+ data += bytes_read;
+ state_machine_regs.line += adv;
+ printf (_(" Advance Line by %d to %d\n"), adv,
+ state_machine_regs.line);
+ break;
+
+ case DW_LNS_set_file:
+ adv = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ printf (_(" Set File Name to entry %d in the File Name Table\n"),
+ adv);
+ state_machine_regs.file = adv;
+ break;
+
+ case DW_LNS_set_column:
+ adv = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ printf (_(" Set column to %d\n"), adv);
+ state_machine_regs.column = adv;
+ break;
+
+ case DW_LNS_negate_stmt:
+ adv = state_machine_regs.is_stmt;
+ adv = ! adv;
+ printf (_(" Set is_stmt to %d\n"), adv);
+ state_machine_regs.is_stmt = adv;
+ break;
+
+ case DW_LNS_set_basic_block:
+ printf (_(" Set basic block\n"));
+ state_machine_regs.basic_block = 1;
+ break;
+
+ case DW_LNS_const_add_pc:
+ adv = (255 - info.li_opcode_base) / info.li_line_range;
+ state_machine_regs.address += adv;
+ printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
+ state_machine_regs.address);
+ break;
+
+ case DW_LNS_fixed_advance_pc:
+ adv = byte_get (data, 2);
+ data += 2;
+ state_machine_regs.address += adv;
+ printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
+ adv, state_machine_regs.address);
+ break;
+
+ default:
+ op_code -= info.li_opcode_base;
+ adv = (op_code / info.li_line_range) * info.li_min_insn_length;
+ state_machine_regs.address += adv;
+ printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
+ op_code, adv, state_machine_regs.address);
+ adv += (op_code % info.li_line_range) + info.li_line_base;
+ state_machine_regs.line += adv;
+ printf (_(" and Line by %d to %d\n"),
+ adv, state_machine_regs.line);
+ break;
+ }
+ }
+ printf ("\n");
+ }
+
+ return 1;
+}
+
+static int
+display_debug_pubnames (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file;
+{
+ DWARF2_External_PubNames * external;
+ DWARF2_Internal_PubNames pubnames;
+ unsigned char * end;
+
+ end = start + section->sh_size;
+
+ printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+
+ while (start < end)
+ {
+ unsigned char * data;
+ unsigned long offset;
+
+ external = (DWARF2_External_PubNames *) start;
+
+ pubnames.pn_length = BYTE_GET (external->pn_length);
+ pubnames.pn_version = BYTE_GET (external->pn_version);
+ pubnames.pn_offset = BYTE_GET (external->pn_offset);
+ pubnames.pn_size = BYTE_GET (external->pn_size);
+
+ data = start + sizeof (* external);
+ start += pubnames.pn_length + sizeof (external->pn_length);
+
+ if (pubnames.pn_version != 2)
+ {
+ warn (_("Only DWARF 2 pubnames are currently supported"));
+ continue;
+ }
+
+ printf (_(" Length: %ld\n"),
+ pubnames.pn_length);
+ printf (_(" Version: %d\n"),
+ pubnames.pn_version);
+ printf (_(" Offset into .debug_info section: %ld\n"),
+ pubnames.pn_offset);
+ printf (_(" Size of area in .debug_info section: %ld\n"),
+ pubnames.pn_size);
+
+ printf (_("\n Offset\tName\n"));
+
+ do
+ {
+ offset = byte_get (data, 4);
+
+ if (offset != 0)
+ {
+ data += 4;
+ printf (" %ld\t\t%s\n", offset, data);
+ data += strlen (data) + 1;
+ }
+ }
+ while (offset != 0);
+ }
+
+ printf ("\n");
+ return 1;
+}
+
+static char *
+get_TAG_name (tag)
+ unsigned long tag;
+{
+ switch (tag)
+ {
+ case DW_TAG_padding: return "DW_TAG_padding";
+ case DW_TAG_array_type: return "DW_TAG_array_type";
+ case DW_TAG_class_type: return "DW_TAG_class_type";
+ case DW_TAG_entry_point: return "DW_TAG_entry_point";
+ case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
+ case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
+ case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
+ case DW_TAG_label: return "DW_TAG_label";
+ case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
+ case DW_TAG_member: return "DW_TAG_member";
+ case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
+ case DW_TAG_reference_type: return "DW_TAG_reference_type";
+ case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
+ case DW_TAG_string_type: return "DW_TAG_string_type";
+ case DW_TAG_structure_type: return "DW_TAG_structure_type";
+ case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
+ case DW_TAG_typedef: return "DW_TAG_typedef";
+ case DW_TAG_union_type: return "DW_TAG_union_type";
+ case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
+ case DW_TAG_variant: return "DW_TAG_variant";
+ case DW_TAG_common_block: return "DW_TAG_common_block";
+ case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
+ case DW_TAG_inheritance: return "DW_TAG_inheritance";
+ case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
+ case DW_TAG_module: return "DW_TAG_module";
+ case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
+ case DW_TAG_set_type: return "DW_TAG_set_type";
+ case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
+ case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
+ case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
+ case DW_TAG_base_type: return "DW_TAG_base_type";
+ case DW_TAG_catch_block: return "DW_TAG_catch_block";
+ case DW_TAG_const_type: return "DW_TAG_const_type";
+ case DW_TAG_constant: return "DW_TAG_constant";
+ case DW_TAG_enumerator: return "DW_TAG_enumerator";
+ case DW_TAG_file_type: return "DW_TAG_file_type";
+ case DW_TAG_friend: return "DW_TAG_friend";
+ case DW_TAG_namelist: return "DW_TAG_namelist";
+ case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
+ case DW_TAG_packed_type: return "DW_TAG_packed_type";
+ case DW_TAG_subprogram: return "DW_TAG_subprogram";
+ case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
+ case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
+ case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
+ case DW_TAG_try_block: return "DW_TAG_try_block";
+ case DW_TAG_variant_part: return "DW_TAG_variant_part";
+ case DW_TAG_variable: return "DW_TAG_variable";
+ case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
+ case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
+ case DW_TAG_format_label: return "DW_TAG_format_label";
+ case DW_TAG_function_template: return "DW_TAG_function_template";
+ case DW_TAG_class_template: return "DW_TAG_class_template";
+ default:
+ {
+ static char buffer [100];
+
+ sprintf (buffer, _("Unknown TAG value: %lx"), tag);
+ return buffer;
+ }
+ }
+}
+
+static char *
+get_AT_name (attribute)
+ unsigned long attribute;
+{
+ switch (attribute)
+ {
+ case DW_AT_sibling: return "DW_AT_sibling";
+ case DW_AT_location: return "DW_AT_location";
+ case DW_AT_name: return "DW_AT_name";
+ case DW_AT_ordering: return "DW_AT_ordering";
+ case DW_AT_subscr_data: return "DW_AT_subscr_data";
+ case DW_AT_byte_size: return "DW_AT_byte_size";
+ case DW_AT_bit_offset: return "DW_AT_bit_offset";
+ case DW_AT_bit_size: return "DW_AT_bit_size";
+ case DW_AT_element_list: return "DW_AT_element_list";
+ case DW_AT_stmt_list: return "DW_AT_stmt_list";
+ case DW_AT_low_pc: return "DW_AT_low_pc";
+ case DW_AT_high_pc: return "DW_AT_high_pc";
+ case DW_AT_language: return "DW_AT_language";
+ case DW_AT_member: return "DW_AT_member";
+ case DW_AT_discr: return "DW_AT_discr";
+ case DW_AT_discr_value: return "DW_AT_discr_value";
+ case DW_AT_visibility: return "DW_AT_visibility";
+ case DW_AT_import: return "DW_AT_import";
+ case DW_AT_string_length: return "DW_AT_string_length";
+ case DW_AT_common_reference: return "DW_AT_common_reference";
+ case DW_AT_comp_dir: return "DW_AT_comp_dir";
+ case DW_AT_const_value: return "DW_AT_const_value";
+ case DW_AT_containing_type: return "DW_AT_containing_type";
+ case DW_AT_default_value: return "DW_AT_default_value";
+ case DW_AT_inline: return "DW_AT_inline";
+ case DW_AT_is_optional: return "DW_AT_is_optional";
+ case DW_AT_lower_bound: return "DW_AT_lower_bound";
+ case DW_AT_producer: return "DW_AT_producer";
+ case DW_AT_prototyped: return "DW_AT_prototyped";
+ case DW_AT_return_addr: return "DW_AT_return_addr";
+ case DW_AT_start_scope: return "DW_AT_start_scope";
+ case DW_AT_stride_size: return "DW_AT_stride_size";
+ case DW_AT_upper_bound: return "DW_AT_upper_bound";
+ case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
+ case DW_AT_accessibility: return "DW_AT_accessibility";
+ case DW_AT_address_class: return "DW_AT_address_class";
+ case DW_AT_artificial: return "DW_AT_artificial";
+ case DW_AT_base_types: return "DW_AT_base_types";
+ case DW_AT_calling_convention: return "DW_AT_calling_convention";
+ case DW_AT_count: return "DW_AT_count";
+ case DW_AT_data_member_location: return "DW_AT_data_member_location";
+ case DW_AT_decl_column: return "DW_AT_decl_column";
+ case DW_AT_decl_file: return "DW_AT_decl_file";
+ case DW_AT_decl_line: return "DW_AT_decl_line";
+ case DW_AT_declaration: return "DW_AT_declaration";
+ case DW_AT_discr_list: return "DW_AT_discr_list";
+ case DW_AT_encoding: return "DW_AT_encoding";
+ case DW_AT_external: return "DW_AT_external";
+ case DW_AT_frame_base: return "DW_AT_frame_base";
+ case DW_AT_friend: return "DW_AT_friend";
+ case DW_AT_identifier_case: return "DW_AT_identifier_case";
+ case DW_AT_macro_info: return "DW_AT_macro_info";
+ case DW_AT_namelist_items: return "DW_AT_namelist_items";
+ case DW_AT_priority: return "DW_AT_priority";
+ case DW_AT_segment: return "DW_AT_segment";
+ case DW_AT_specification: return "DW_AT_specification";
+ case DW_AT_static_link: return "DW_AT_static_link";
+ case DW_AT_type: return "DW_AT_type";
+ case DW_AT_use_location: return "DW_AT_use_location";
+ case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
+ case DW_AT_virtuality: return "DW_AT_virtuality";
+ case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
+ case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
+ case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
+ case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
+ case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
+ case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
+ case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
+ case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
+ case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
+ case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
+ case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
+ case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
+ case DW_AT_sf_names: return "DW_AT_sf_names";
+ case DW_AT_src_info: return "DW_AT_src_info";
+ case DW_AT_mac_info: return "DW_AT_mac_info";
+ case DW_AT_src_coords: return "DW_AT_src_coords";
+ case DW_AT_body_begin: return "DW_AT_body_begin";
+ case DW_AT_body_end: return "DW_AT_body_end";
+ default:
+ {
+ static char buffer [100];
+
+ sprintf (buffer, _("Unknown AT value: %lx"), attribute);
+ return buffer;
+ }
+ }
+}
+
+static char *
+get_FORM_name (form)
+ unsigned long form;
+{
+ switch (form)
+ {
+ case DW_FORM_addr: return "DW_FORM_addr";
+ case DW_FORM_block2: return "DW_FORM_block2";
+ case DW_FORM_block4: return "DW_FORM_block4";
+ case DW_FORM_data2: return "DW_FORM_data2";
+ case DW_FORM_data4: return "DW_FORM_data4";
+ case DW_FORM_data8: return "DW_FORM_data8";
+ case DW_FORM_string: return "DW_FORM_string";
+ case DW_FORM_block: return "DW_FORM_block";
+ case DW_FORM_block1: return "DW_FORM_block1";
+ case DW_FORM_data1: return "DW_FORM_data1";
+ case DW_FORM_flag: return "DW_FORM_flag";
+ case DW_FORM_sdata: return "DW_FORM_sdata";
+ case DW_FORM_strp: return "DW_FORM_strp";
+ case DW_FORM_udata: return "DW_FORM_udata";
+ case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
+ case DW_FORM_ref1: return "DW_FORM_ref1";
+ case DW_FORM_ref2: return "DW_FORM_ref2";
+ case DW_FORM_ref4: return "DW_FORM_ref4";
+ case DW_FORM_ref8: return "DW_FORM_ref8";
+ case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
+ case DW_FORM_indirect: return "DW_FORM_indirect";
+ default:
+ {
+ static char buffer [100];
+
+ sprintf (buffer, _("Unknown FORM value: %lx"), form);
+ return buffer;
+ }
+ }
+}
+
+/* FIXME: There are better and more effiecint ways to handle
+ these structures. For now though, I just want something that
+ is simple to implement. */
+typedef struct abbrev_attr
+{
+ unsigned long attribute;
+ unsigned long form;
+ struct abbrev_attr * next;
+}
+abbrev_attr;
+
+typedef struct abbrev_entry
+{
+ unsigned long entry;
+ unsigned long tag;
+ int children;
+ struct abbrev_attr * first_attr;
+ struct abbrev_attr * last_attr;
+ struct abbrev_entry * next;
+}
+abbrev_entry;
+
+static abbrev_entry * first_abbrev = NULL;
+static abbrev_entry * last_abbrev = NULL;
+
+static void
+free_abbrevs PARAMS ((void))
+{
+ abbrev_entry * abbrev;
+
+ for (abbrev = first_abbrev; abbrev;)
+ {
+ abbrev_entry * next = abbrev->next;
+ abbrev_attr * attr;
+
+ for (attr = abbrev->first_attr; attr;)
+ {
+ abbrev_attr * next = attr->next;
+
+ free (attr);
+ attr = next;
+ }
+
+ free (abbrev);
+ abbrev = next;
+ }
+
+ last_abbrev = first_abbrev = NULL;
+}
+
+static void
+add_abbrev (number, tag, children)
+ unsigned long number;
+ unsigned long tag;
+ int children;
+{
+ abbrev_entry * entry;
+
+ entry = (abbrev_entry *) malloc (sizeof (* entry));
+
+ if (entry == NULL)
+ /* ugg */
+ return;
+
+ entry->entry = number;
+ entry->tag = tag;
+ entry->children = children;
+ entry->first_attr = NULL;
+ entry->last_attr = NULL;
+ entry->next = NULL;
+
+ if (first_abbrev == NULL)
+ first_abbrev = entry;
+ else
+ last_abbrev->next = entry;
+
+ last_abbrev = entry;
+}
+
+static void
+add_abbrev_attr (attribute, form)
+ unsigned long attribute;
+ unsigned long form;
+{
+ abbrev_attr * attr;
+
+ attr = (abbrev_attr *) malloc (sizeof (* attr));
+
+ if (attr == NULL)
+ /* ugg */
+ return;
+
+ attr->attribute = attribute;
+ attr->form = form;
+ attr->next = NULL;
+
+ if (last_abbrev->first_attr == NULL)
+ last_abbrev->first_attr = attr;
+ else
+ last_abbrev->last_attr->next = attr;
+
+ last_abbrev->last_attr = attr;
+}
+
+/* Processes the (partial) contents of a .debug_abbrev section.
+ Returns NULL if the end of the section was encountered.
+ Returns the address after the last byte read if the end of
+ an abbreviation set was found. */
+
+static unsigned char *
+process_abbrev_section (start, end)
+ unsigned char * start;
+ unsigned char * end;
+{
+ if (first_abbrev != NULL)
+ return NULL;
+
+ while (start < end)
+ {
+ int bytes_read;
+ unsigned long entry;
+ unsigned long tag;
+ unsigned long attribute;
+ int children;
+
+ entry = read_leb128 (start, & bytes_read, 0);
+ start += bytes_read;
+
+ if (entry == 0)
+ return start;
+
+ tag = read_leb128 (start, & bytes_read, 0);
+ start += bytes_read;
+
+ children = * start ++;
+
+ add_abbrev (entry, tag, children);
+
+ do
+ {
+ unsigned long form;
+
+ attribute = read_leb128 (start, & bytes_read, 0);
+ start += bytes_read;
+
+ form = read_leb128 (start, & bytes_read, 0);
+ start += bytes_read;
+
+ if (attribute != 0)
+ add_abbrev_attr (attribute, form);
+ }
+ while (attribute != 0);
+ }
+
+ return NULL;
+}
+
+
+static int
+display_debug_abbrev (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file;
+{
+ abbrev_entry * entry;
+ unsigned char * end = start + section->sh_size;
+
+ printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+
+ do
+ {
+ start = process_abbrev_section (start, end);
+
+ printf (_(" Number TAG\n"));
+
+ for (entry = first_abbrev; entry; entry = entry->next)
+ {
+ abbrev_attr * attr;
+
+ printf (_(" %ld %s [%s]\n"),
+ entry->entry,
+ get_TAG_name (entry->tag),
+ entry->children ? _("has children") : _("no children"));
+
+ for (attr = entry->first_attr; attr; attr = attr->next)
+ {
+ printf (_(" %-18s %s\n"),
+ get_AT_name (attr->attribute),
+ get_FORM_name (attr->form));
+ }
+ }
+ }
+ while (start);
+
+ printf ("\n");
+
+ return 1;
+}
+
+
+static unsigned char *
+display_block (data, length)
+ unsigned char * data;
+ unsigned long length;
+{
+ printf (_(" %lu byte block: "), length);
+
+ while (length --)
+ printf ("%lx ", byte_get (data ++, 1));
+
+ return data;
+}
+
+static void
+decode_location_expression (data, pointer_size)
+ unsigned char * data;
+ unsigned int pointer_size;
+{
+ unsigned char op;
+ int bytes_read;
+
+ op = * data ++;
+
+ switch (op)
+ {
+ case DW_OP_addr: printf ("DW_OP_addr: %lx", byte_get (data, pointer_size)); break;
+ case DW_OP_deref: printf ("DW_OP_deref"); break;
+ case DW_OP_const1u: printf ("DW_OP_const1u: %lu", byte_get (data, 1)); break;
+ case DW_OP_const1s: printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1)); break;
+ case DW_OP_const2u: printf ("DW_OP_const2u: %lu", byte_get (data, 2)); break;
+ case DW_OP_const2s: printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2)); break;
+ case DW_OP_const4u: printf ("DW_OP_const4u: %lu", byte_get (data, 4)); break;
+ case DW_OP_const4s: printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4)); break;
+ case DW_OP_const8u: printf ("DW_OP_const8u: %lu %lu", byte_get (data, 4), byte_get (data + 4, 4)); break;
+ case DW_OP_const8s: printf ("DW_OP_const8s: %ld %ld", byte_get (data, 4), byte_get (data + 4, 4)); break;
+ case DW_OP_constu: printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0)); break;
+ case DW_OP_consts: printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_dup: printf ("DW_OP_dup"); break;
+ case DW_OP_drop: printf ("DW_OP_drop"); break;
+ case DW_OP_over: printf ("DW_OP_over"); break;
+ case DW_OP_pick: printf ("DW_OP_pick: %ld", byte_get (data, 1)); break;
+ case DW_OP_swap: printf ("DW_OP_swap"); break;
+ case DW_OP_rot: printf ("DW_OP_rot"); break;
+ case DW_OP_xderef: printf ("DW_OP_xderef"); break;
+ case DW_OP_abs: printf ("DW_OP_abs"); break;
+ case DW_OP_and: printf ("DW_OP_and"); break;
+ case DW_OP_div: printf ("DW_OP_div"); break;
+ case DW_OP_minus: printf ("DW_OP_minus"); break;
+ case DW_OP_mod: printf ("DW_OP_mod"); break;
+ case DW_OP_mul: printf ("DW_OP_mul"); break;
+ case DW_OP_neg: printf ("DW_OP_neg"); break;
+ case DW_OP_not: printf ("DW_OP_not"); break;
+ case DW_OP_or: printf ("DW_OP_or"); break;
+ case DW_OP_plus: printf ("DW_OP_plus"); break;
+ case DW_OP_plus_uconst: printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0)); break;
+ case DW_OP_shl: printf ("DW_OP_shl"); break;
+ case DW_OP_shr: printf ("DW_OP_shr"); break;
+ case DW_OP_shra: printf ("DW_OP_shra"); break;
+ case DW_OP_xor: printf ("DW_OP_xor"); break;
+ case DW_OP_bra: printf ("DW_OP_bra: %ld", byte_get (data, 2)); break;
+ case DW_OP_eq: printf ("DW_OP_eq"); break;
+ case DW_OP_ge: printf ("DW_OP_ge"); break;
+ case DW_OP_gt: printf ("DW_OP_gt"); break;
+ case DW_OP_le: printf ("DW_OP_le"); break;
+ case DW_OP_lt: printf ("DW_OP_lt"); break;
+ case DW_OP_ne: printf ("DW_OP_ne"); break;
+ case DW_OP_skip: printf ("DW_OP_skip: %ld", byte_get (data, 2)); break;
+ case DW_OP_lit0: printf ("DW_OP_lit0"); break;
+ case DW_OP_lit1: printf ("DW_OP_lit1"); break;
+ case DW_OP_lit2: printf ("DW_OP_lit2"); break;
+ case DW_OP_lit3: printf ("DW_OP_lit3"); break;
+ case DW_OP_lit4: printf ("DW_OP_lit4"); break;
+ case DW_OP_lit5: printf ("DW_OP_lit5"); break;
+ case DW_OP_lit6: printf ("DW_OP_lit6"); break;
+ case DW_OP_lit7: printf ("DW_OP_lit7"); break;
+ case DW_OP_lit8: printf ("DW_OP_lit8"); break;
+ case DW_OP_lit9: printf ("DW_OP_lit9"); break;
+ case DW_OP_lit10: printf ("DW_OP_lit10"); break;
+ case DW_OP_lit11: printf ("DW_OP_lit11"); break;
+ case DW_OP_lit12: printf ("DW_OP_lit12"); break;
+ case DW_OP_lit13: printf ("DW_OP_lit13"); break;
+ case DW_OP_lit14: printf ("DW_OP_lit14"); break;
+ case DW_OP_lit15: printf ("DW_OP_lit15"); break;
+ case DW_OP_lit16: printf ("DW_OP_lit16"); break;
+ case DW_OP_lit17: printf ("DW_OP_lit17"); break;
+ case DW_OP_lit18: printf ("DW_OP_lit18"); break;
+ case DW_OP_lit19: printf ("DW_OP_lit19"); break;
+ case DW_OP_lit20: printf ("DW_OP_lit20"); break;
+ case DW_OP_lit21: printf ("DW_OP_lit21"); break;
+ case DW_OP_lit22: printf ("DW_OP_lit22"); break;
+ case DW_OP_lit23: printf ("DW_OP_lit23"); break;
+ case DW_OP_lit24: printf ("DW_OP_lit24"); break;
+ case DW_OP_lit25: printf ("DW_OP_lit25"); break;
+ case DW_OP_lit26: printf ("DW_OP_lit26"); break;
+ case DW_OP_lit27: printf ("DW_OP_lit27"); break;
+ case DW_OP_lit28: printf ("DW_OP_lit28"); break;
+ case DW_OP_lit29: printf ("DW_OP_lit29"); break;
+ case DW_OP_lit30: printf ("DW_OP_lit30"); break;
+ case DW_OP_lit31: printf ("DW_OP_lit31"); break;
+ case DW_OP_reg0: printf ("DW_OP_reg0"); break;
+ case DW_OP_reg1: printf ("DW_OP_reg1"); break;
+ case DW_OP_reg2: printf ("DW_OP_reg2"); break;
+ case DW_OP_reg3: printf ("DW_OP_reg3"); break;
+ case DW_OP_reg4: printf ("DW_OP_reg4"); break;
+ case DW_OP_reg5: printf ("DW_OP_reg5"); break;
+ case DW_OP_reg6: printf ("DW_OP_reg6"); break;
+ case DW_OP_reg7: printf ("DW_OP_reg7"); break;
+ case DW_OP_reg8: printf ("DW_OP_reg8"); break;
+ case DW_OP_reg9: printf ("DW_OP_reg9"); break;
+ case DW_OP_reg10: printf ("DW_OP_reg10"); break;
+ case DW_OP_reg11: printf ("DW_OP_reg11"); break;
+ case DW_OP_reg12: printf ("DW_OP_reg12"); break;
+ case DW_OP_reg13: printf ("DW_OP_reg13"); break;
+ case DW_OP_reg14: printf ("DW_OP_reg14"); break;
+ case DW_OP_reg15: printf ("DW_OP_reg15"); break;
+ case DW_OP_reg16: printf ("DW_OP_reg16"); break;
+ case DW_OP_reg17: printf ("DW_OP_reg17"); break;
+ case DW_OP_reg18: printf ("DW_OP_reg18"); break;
+ case DW_OP_reg19: printf ("DW_OP_reg19"); break;
+ case DW_OP_reg20: printf ("DW_OP_reg20"); break;
+ case DW_OP_reg21: printf ("DW_OP_reg21"); break;
+ case DW_OP_reg22: printf ("DW_OP_reg22"); break;
+ case DW_OP_reg23: printf ("DW_OP_reg23"); break;
+ case DW_OP_reg24: printf ("DW_OP_reg24"); break;
+ case DW_OP_reg25: printf ("DW_OP_reg25"); break;
+ case DW_OP_reg26: printf ("DW_OP_reg26"); break;
+ case DW_OP_reg27: printf ("DW_OP_reg27"); break;
+ case DW_OP_reg28: printf ("DW_OP_reg28"); break;
+ case DW_OP_reg29: printf ("DW_OP_reg29"); break;
+ case DW_OP_reg30: printf ("DW_OP_reg30"); break;
+ case DW_OP_reg31: printf ("DW_OP_reg31"); break;
+ case DW_OP_breg0: printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg1: printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg2: printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg3: printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg4: printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg5: printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg6: printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg7: printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg8: printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg9: printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg10: printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg11: printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg12: printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg13: printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg14: printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg15: printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg16: printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg17: printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg18: printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg19: printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg20: printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg21: printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg22: printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg23: printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg24: printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg25: printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg26: printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg27: printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg28: printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg29: printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg30: printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_breg31: printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_regx: printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0)); break;
+ case DW_OP_fbreg: printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1)); break;
+ case DW_OP_bregx: printf ("DW_OP_bregx: %lu %ld", read_leb128 (data, & bytes_read, 0), read_leb128 (data + bytes_read, NULL, 1)); break;
+ case DW_OP_piece: printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0)); break;
+ case DW_OP_deref_size: printf ("DW_OP_deref_size: %ld", byte_get (data, 1)); break;
+ case DW_OP_xderef_size: printf ("DW_OP_xderef_size: %ld", byte_get (data, 1)); break;
+ case DW_OP_nop: printf ("DW_OP_nop"); break;
+
+ default:
+ if (op >= DW_OP_lo_user
+ && op <= DW_OP_hi_user)
+ printf (_("(User defined location op)"));
+ else
+ printf (_("(Unknown location op)"));
+ break;
+ }
+}
+
+
+static unsigned char *
+read_and_display_attr (attribute, form, data, pointer_size)
+ unsigned long attribute;
+ unsigned long form;
+ unsigned char * data;
+ unsigned long pointer_size;
+{
+ unsigned long uvalue;
+ unsigned char * block_start;
+ int bytes_read;
+ int is_ref = 0;
+
+ printf (" %-18s:", get_AT_name (attribute));
+
+ switch (form)
+ {
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ is_ref = 1;
+ }
+
+ switch (form)
+ {
+ case DW_FORM_ref_addr:
+ case DW_FORM_addr:
+ uvalue = byte_get (data, pointer_size);
+ printf (is_ref ? " <%x>" : " %#x", uvalue);
+ data += pointer_size;
+ break;
+
+ case DW_FORM_ref1:
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ uvalue = byte_get (data ++, 1);
+ printf (is_ref ? " <%x>" : " %d", uvalue);
+ break;
+
+ case DW_FORM_ref2:
+ case DW_FORM_data2:
+ uvalue = byte_get (data, 2);
+ data += 2;
+ printf (is_ref ? " <%x>" : " %d", uvalue);
+ break;
+
+ case DW_FORM_ref4:
+ case DW_FORM_data4:
+ uvalue = byte_get (data, 4);
+ data += 4;
+ printf (is_ref ? " <%x>" : " %d", uvalue);
+ break;
+
+ case DW_FORM_ref8:
+ case DW_FORM_data8:
+ uvalue = byte_get (data, 4);
+ printf (" %lx", uvalue);
+ printf (" %lx", byte_get (data + 4, 4));
+ data += 8;
+ break;
+
+ case DW_FORM_string:
+ printf (" %s", data);
+ data += strlen (data) + 1;
+ break;
+
+ case DW_FORM_sdata:
+ uvalue = read_leb128 (data, & bytes_read, 1);
+ data += bytes_read;
+ printf (" %ld", (long) uvalue);
+ break;
+
+ case DW_FORM_ref_udata:
+ case DW_FORM_udata:
+ uvalue = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ printf (is_ref ? " <%lx>" : " %ld", uvalue);
+ break;
+
+ case DW_FORM_block:
+ uvalue = read_leb128 (data, & bytes_read, 0);
+ block_start = data + bytes_read;
+ data = display_block (block_start, uvalue);
+ uvalue = * block_start;
+ break;
+
+ case DW_FORM_block1:
+ uvalue = byte_get (data, 1);
+ block_start = data + 1;
+ data = display_block (block_start, uvalue);
+ uvalue = * block_start;
+ break;
+
+ case DW_FORM_block2:
+ uvalue = byte_get (data, 2);
+ block_start = data + 2;
+ data = display_block (block_start, uvalue);
+ uvalue = * block_start;
+ break;
+
+ case DW_FORM_block4:
+ uvalue = byte_get (data, 4);
+ block_start = data + 4;
+ data = display_block (block_start, uvalue);
+ uvalue = * block_start;
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_indirect:
+ warn (_("Unable to handle FORM: %d"), form);
+ break;
+
+ default:
+ warn (_("Unrecognised form: %d"), form);
+ break;
+ }
+
+ /* For some attributes we can display futher information. */
+
+ printf ("\t");
+
+ switch (attribute)
+ {
+ case DW_AT_inline:
+ switch (uvalue)
+ {
+ case DW_INL_not_inlined: printf (_("(not inlined)")); break;
+ case DW_INL_inlined: printf (_("(inlined)")); break;
+ case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
+ case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
+ default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
+ }
+ break;
+
+ case DW_AT_frame_base:
+ if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
+ printf ("(reg %ld)", uvalue - DW_OP_reg0);
+ break;
+
+ case DW_AT_language:
+ switch (uvalue)
+ {
+ case DW_LANG_C: printf ("(non-ANSI C)"); break;
+ case DW_LANG_C89: printf ("(ANSI C)"); break;
+ case DW_LANG_C_plus_plus: printf ("(C++)"); break;
+ case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
+ case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
+ case DW_LANG_Modula2: printf ("(Modula 2)"); break;
+ case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
+ case DW_LANG_Ada83: printf ("(Ada)"); break;
+ case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
+ case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
+ case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
+ default: printf ("(Unknown: %lx)", uvalue); break;
+ }
+ break;
+
+ case DW_AT_encoding:
+ switch (uvalue)
+ {
+ case DW_ATE_void: printf ("(void)"); break;
+ case DW_ATE_address: printf ("(machine address)"); break;
+ case DW_ATE_boolean: printf ("(boolean)"); break;
+ case DW_ATE_complex_float: printf ("(complex float)"); break;
+ case DW_ATE_float: printf ("(float)"); break;
+ case DW_ATE_signed: printf ("(signed)"); break;
+ case DW_ATE_signed_char: printf ("(signed char)"); break;
+ case DW_ATE_unsigned: printf ("(unsigned)"); break;
+ case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
+ default:
+ if (uvalue >= DW_ATE_lo_user
+ && uvalue <= DW_ATE_hi_user)
+ printf ("(user defined type)");
+ else
+ printf ("(unknown type)");
+ break;
+ }
+ break;
+
+ case DW_AT_accessibility:
+ switch (uvalue)
+ {
+ case DW_ACCESS_public: printf ("(public)"); break;
+ case DW_ACCESS_protected: printf ("(protected)"); break;
+ case DW_ACCESS_private: printf ("(private)"); break;
+ default: printf ("(unknown accessibility)"); break;
+ }
+ break;
+
+ case DW_AT_visibility:
+ switch (uvalue)
+ {
+ case DW_VIS_local: printf ("(local)"); break;
+ case DW_VIS_exported: printf ("(exported)"); break;
+ case DW_VIS_qualified: printf ("(qualified)"); break;
+ default: printf ("(unknown visibility)"); break;
+ }
+ break;
+
+ case DW_AT_virtuality:
+ switch (uvalue)
+ {
+ case DW_VIRTUALITY_none: printf ("(none)"); break;
+ case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
+ case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
+ default: printf ("(unknown virtuality)"); break;
+ }
+ break;
+
+ case DW_AT_identifier_case:
+ switch (uvalue)
+ {
+ case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
+ case DW_ID_up_case: printf ("(up_case)"); break;
+ case DW_ID_down_case: printf ("(down_case)"); break;
+ case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
+ default: printf ("(unknown case)"); break;
+ }
+ break;
+
+ case DW_AT_calling_convention:
+ switch (uvalue)
+ {
+ case DW_CC_normal: printf ("(normal)"); break;
+ case DW_CC_program: printf ("(program)"); break;
+ case DW_CC_nocall: printf ("(nocall)"); break;
+ default:
+ if (uvalue >= DW_CC_lo_user
+ && uvalue <= DW_CC_hi_user)
+ printf ("(user defined)");
+ else
+ printf ("(unknown convention)");
+ }
+ break;
+
+ case DW_AT_location:
+ case DW_AT_data_member_location:
+ case DW_AT_vtable_elem_location:
+ printf ("(");
+ decode_location_expression (block_start, pointer_size);
+ printf (")");
+ break;
+
+ default:
+ break;
+ }
+
+ printf ("\n");
+ return data;
+}
+
+static int
+display_debug_info (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file;
+{
+ unsigned char * end = start + section->sh_size;
+ unsigned char * section_begin = start;
+
+ printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+
+ while (start < end)
+ {
+ DWARF2_External_CompUnit * external;
+ DWARF2_Internal_CompUnit compunit;
+ unsigned char * tags;
+ int i;
+ int level;
+
+ external = (DWARF2_External_CompUnit *) start;
+
+ compunit.cu_length = BYTE_GET (external->cu_length);
+ compunit.cu_version = BYTE_GET (external->cu_version);
+ compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
+ compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
+
+ tags = start + sizeof (* external);
+ start += compunit.cu_length + sizeof (external->cu_length);
+
+ if (compunit.cu_version != 2)
+ {
+ warn (_("Only version 2 DWARF debug information is currently supported.\n"));
+ continue;
+ }
+
+ printf (_(" Compilation Unit:\n"));
+ printf (_(" Length: %ld\n"), compunit.cu_length);
+ printf (_(" Version: %d\n"), compunit.cu_version);
+ printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
+ printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
+
+ if (first_abbrev != NULL)
+ free_abbrevs ();
+
+ /* Read in the abbrevs used by this compilation unit. */
+
+ {
+ Elf32_Internal_Shdr * sec;
+ unsigned char * begin;
+
+ /* Locate the .debug_abbrev section and process it. */
+ for (i = 0, sec = section_headers;
+ i < elf_header.e_shnum;
+ i ++, sec ++)
+ if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
+ break;
+
+ if (i == -1 || sec->sh_size == 0)
+ {
+ warn (_("Unable to locate .debug_abbrev section!\n"));
+ return 0;
+ }
+
+ GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
+ "debug_abbrev section data");
+
+ process_abbrev_section (begin + compunit.cu_abbrev_offset,
+ begin + sec->sh_size);
+
+ free (begin);
+ }
+
+ level = 0;
+ while (tags < start)
+ {
+ int bytes_read;
+ int abbrev_number;
+ abbrev_entry * entry;
+ abbrev_attr * attr;
+
+ abbrev_number = read_leb128 (tags, & bytes_read, 0);
+ tags += bytes_read;
+
+ /* A null DIE marks the end of a list of children. */
+ if (abbrev_number == 0)
+ {
+ --level;
+ continue;
+ }
+
+ /* Scan through the abbreviation list until we reach the
+ correct entry. */
+ for (entry = first_abbrev;
+ entry && entry->entry != abbrev_number;
+ entry = entry->next)
+ continue;
+
+ if (entry == NULL)
+ {
+ warn (_("Unable to locate entry %d in the abbreviation table\n"),
+ abbrev_number);
+ return 0;
+ }
+
+ printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
+ level, tags - section_begin - bytes_read,
+ abbrev_number,
+ get_TAG_name (entry->tag));
+
+ for (attr = entry->first_attr; attr; attr = attr->next)
+ tags = read_and_display_attr (attr->attribute,
+ attr->form,
+ tags,
+ compunit.cu_pointer_size);
+
+ if (entry->children)
+ ++level;
+ }
+ }
+
+ printf ("\n");
+
+ return 1;
+}
+
+static int
+display_debug_aranges (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file;
+{
+ unsigned char * end = start + section->sh_size;
+
+ printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+
+ while (start < end)
+ {
+ DWARF2_External_ARange * external;
+ DWARF2_Internal_ARange arange;
+ unsigned char * ranges;
+ unsigned long length;
+ unsigned long address;
+
+ external = (DWARF2_External_ARange *) start;
+
+ arange.ar_length = BYTE_GET (external->ar_length);
+ arange.ar_version = BYTE_GET (external->ar_version);
+ arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
+ arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
+ arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
+
+ printf (_(" Length: %ld\n"), arange.ar_length);
+ printf (_(" Version: %d\n"), arange.ar_version);
+ printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
+ printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
+ printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
+
+ printf (_("\n Address Length\n"));
+
+ ranges = start + sizeof (* external);
+
+ for (;;)
+ {
+ address = byte_get (ranges, arange.ar_pointer_size);
+
+ if (address == 0)
+ break;
+
+ ranges += arange.ar_pointer_size;
+
+ length = byte_get (ranges, arange.ar_pointer_size);
+
+ ranges += arange.ar_pointer_size;
+
+ printf (" %8.8lx %lu\n", address, length);
+ }
+
+ start += arange.ar_length + sizeof (external->ar_length);
+ }
+
+ printf ("\n");
+
+ return 1;
+}
+
+
+static int
+display_debug_not_supported (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file;
+{
+ printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
+ SECTION_NAME (section));
+
+ return 1;
+}
+
+ /* A structure containing the name of a debug section and a pointer
+ to a function that can decode it. */
+struct
+{
+ char * name;
+ int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+}
+debug_displays[] =
+{
+ { ".debug_info", display_debug_info },
+ { ".debug_abbrev", display_debug_abbrev },
+ { ".debug_line", display_debug_lines },
+ { ".debug_aranges", display_debug_aranges },
+ { ".debug_pubnames", display_debug_pubnames },
+ { ".debug_macinfo", display_debug_not_supported },
+ { ".debug_frame", display_debug_not_supported },
+ { ".debug_str", display_debug_not_supported },
+ { ".debug_static_func", display_debug_not_supported },
+ { ".debug_static_vars", display_debug_not_supported },
+ { ".debug_types", display_debug_not_supported },
+ { ".debug_weaknames", display_debug_not_supported }
+};
+
+static int
+display_debug_section (section, file)
+ Elf32_Internal_Shdr * section;
+ FILE * file;
+{
+ char * name = SECTION_NAME (section);
+ bfd_size_type length;
+ unsigned char * start;
+ int i;
+
+ length = section->sh_size;
+ if (length == 0)
+ {
+ printf (_("\nSection '%s' has no debugging data.\n"), name);
+ return 0;
+ }
+
+ GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
+ "debug section data");
+
+ /* See if we know how to display the contents of this section. */
+ for (i = NUM_ELEM (debug_displays); i--;)
+ if (strcmp (debug_displays[i].name, name) == 0)
+ {
+ debug_displays[i].display (section, start, file);
+ break;
+ }
+
+ if (i == -1)
+ printf (_("Unrecognised debug section: %s\n"), name);
+
+ free (start);
+
+ /* If we loaded in the abbrev section at some point,
+ we must release it here. */
+ if (first_abbrev != NULL)
+ free_abbrevs ();
+
+ return 1;
+}
+
+static int
+process_section_contents (file)
+ FILE * file;
+{
+ Elf32_Internal_Shdr * section;
+ unsigned int i;
+
+ if (! do_dump)
+ return 1;
+
+ for (i = 0, section = section_headers;
+ i < elf_header.e_shnum
+ && i < num_dump_sects;
+ i ++, section ++)
+ {
+#ifdef SUPPORT_DISASSEMBLY
+ if (dump_sects[i] & DISASS_DUMP)
+ disassemble_section (section, file);
+#endif
+ if (dump_sects[i] & HEX_DUMP)
+ dump_section (section, file);
+
+ if (dump_sects[i] & DEBUG_DUMP)
+ display_debug_section (section, file);
+ }
+
+ if (i < num_dump_sects)
+ warn (_("Some sections were not dumped because they do not exist!\n"));
+
+ return 1;
+}
+
+static void
+process_mips_fpe_exception (mask)
+ int mask;
+{
+ if (mask)
+ {
+ int first = 1;
+ if (mask & OEX_FPU_INEX)
+ fputs ("INEX", stdout), first = 0;
+ if (mask & OEX_FPU_UFLO)
+ printf ("%sUFLO", first ? "" : "|"), first = 0;
+ if (mask & OEX_FPU_OFLO)
+ printf ("%sOFLO", first ? "" : "|"), first = 0;
+ if (mask & OEX_FPU_DIV0)
+ printf ("%sDIV0", first ? "" : "|"), first = 0;
+ if (mask & OEX_FPU_INVAL)
+ printf ("%sINVAL", first ? "" : "|");
+ }
+ else
+ fputs ("0", stdout);
+}
+
+static int
+process_mips_specific (file)
+ FILE *file;
+{
+ Elf_Internal_Dyn *entry;
+ size_t liblist_offset = 0;
+ size_t liblistno = 0;
+ size_t conflictsno = 0;
+ size_t options_offset = 0;
+ size_t conflicts_offset = 0;
+
+ /* We have a lot of special sections. Thanks SGI! */
+ if (dynamic_segment == NULL)
+ /* No information available. */
+ return 0;
+
+ for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
+ switch (entry->d_tag)
+ {
+ case DT_MIPS_LIBLIST:
+ liblist_offset = entry->d_un.d_val - loadaddr;
+ break;
+ case DT_MIPS_LIBLISTNO:
+ liblistno = entry->d_un.d_val;
+ break;
+ case DT_MIPS_OPTIONS:
+ options_offset = entry->d_un.d_val - loadaddr;
+ break;
+ case DT_MIPS_CONFLICT:
+ conflicts_offset = entry->d_un.d_val - loadaddr;
+ break;
+ case DT_MIPS_CONFLICTNO:
+ conflictsno = entry->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+
+ if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
+ {
+ Elf32_External_Lib *elib;
+ size_t cnt;
+
+ GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
+ elib, Elf32_External_Lib *, "liblist");
+
+ printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
+ fputs (" Library Time Stamp Checksum Version Flags\n",
+ stdout);
+
+ for (cnt = 0; cnt < liblistno; ++cnt)
+ {
+ Elf32_Lib liblist;
+ time_t time;
+ char timebuf[20];
+
+ liblist.l_name = BYTE_GET (elib[cnt].l_name);
+ time = BYTE_GET (elib[cnt].l_time_stamp);
+ liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
+ liblist.l_version = BYTE_GET (elib[cnt].l_version);
+ liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
+
+ strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
+
+ printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
+ dynamic_strings + liblist.l_name, timebuf,
+ liblist.l_checksum, liblist.l_version);
+
+ if (liblist.l_flags == 0)
+ puts (" NONE");
+ else
+ {
+ static const struct
+ {
+ const char *name;
+ int bit;
+ } l_flags_vals[] =
+ {
+ { " EXACT_MATCH", LL_EXACT_MATCH },
+ { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
+ { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
+ { " EXPORTS", LL_EXPORTS },
+ { " DELAY_LOAD", LL_DELAY_LOAD },
+ { " DELTA", LL_DELTA }
+ };
+ int flags = liblist.l_flags;
+ int fcnt;
+
+ for (fcnt = 0;
+ fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
+ ++fcnt)
+ if ((flags & l_flags_vals[fcnt].bit) != 0)
+ {
+ fputs (l_flags_vals[fcnt].name, stdout);
+ flags ^= l_flags_vals[fcnt].bit;
+ }
+ if (flags != 0)
+ printf (" %#x", (unsigned int) flags);
+
+ puts ("");
+ }
+ }
+
+ free (elib);
+ }
+
+ if (options_offset != 0)
+ {
+ Elf_External_Options *eopt;
+ Elf_Internal_Shdr *sect = section_headers;
+ Elf_Internal_Options *iopt;
+ Elf_Internal_Options *option;
+ size_t offset;
+ int cnt;
+
+ /* Find the section header so that we get the size. */
+ while (sect->sh_type != SHT_MIPS_OPTIONS)
+ ++sect;
+
+ GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
+ Elf_External_Options *, "options");
+
+ iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
+ * sizeof (*iopt));
+ if (iopt == NULL)
+ {
+ error (_("Out of memory"));
+ return 0;
+ }
+
+ offset = cnt = 0;
+ option = iopt;
+ while (offset < sect->sh_size)
+ {
+ Elf_External_Options *eoption;
+
+ eoption = (Elf_External_Options *) ((char *) eopt + offset);
+
+ option->kind = BYTE_GET (eoption->kind);
+ option->size = BYTE_GET (eoption->size);
+ option->section = BYTE_GET (eoption->section);
+ option->info = BYTE_GET (eoption->info);
+
+ offset += option->size;
+ ++option;
+ ++cnt;
+ }
+
+ printf (_("\nSection '%s' contains %d entries:\n"),
+ string_table + sect->sh_name, cnt);
+
+ option = iopt;
+ while (cnt-- > 0)
+ {
+ size_t len;
+
+ switch (option->kind)
+ {
+ case ODK_NULL:
+ /* This shouldn't happen. */
+ printf (" NULL %d %lx", option->section, option->info);
+ break;
+ case ODK_REGINFO:
+ printf (" REGINFO ");
+ if (elf_header.e_machine == EM_MIPS)
+ {
+ /* 32bit form. */
+ Elf32_External_RegInfo *ereg;
+ Elf32_RegInfo reginfo;
+
+ ereg = (Elf32_External_RegInfo *) (option + 1);
+ reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
+ reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
+ reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
+ reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
+ reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
+ reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
+
+ printf ("GPR %08lx GP 0x%lx\n",
+ reginfo.ri_gprmask,
+ (unsigned long) reginfo.ri_gp_value);
+ printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
+ reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
+ reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
+ }
+ else
+ {
+ /* 64 bit form. */
+ Elf64_External_RegInfo *ereg;
+ Elf64_Internal_RegInfo reginfo;
+
+ ereg = (Elf64_External_RegInfo *) (option + 1);
+ reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
+ reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
+ reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
+ reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
+ reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
+ reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
+
+ printf ("GPR %08lx GP 0x",
+ reginfo.ri_gprmask);
+ printf_vma (reginfo.ri_gp_value);
+ printf ("\n");
+
+ printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
+ reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
+ reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
+ }
+ ++option;
+ continue;
+ case ODK_EXCEPTIONS:
+ fputs (" EXCEPTIONS fpe_min(", stdout);
+ process_mips_fpe_exception (option->info & OEX_FPU_MIN);
+ fputs (") fpe_max(", stdout);
+ process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
+ fputs (")", stdout);
+
+ if (option->info & OEX_PAGE0)
+ fputs (" PAGE0", stdout);
+ if (option->info & OEX_SMM)
+ fputs (" SMM", stdout);
+ if (option->info & OEX_FPDBUG)
+ fputs (" FPDBUG", stdout);
+ if (option->info & OEX_DISMISS)
+ fputs (" DISMISS", stdout);
+ break;
+ case ODK_PAD:
+ fputs (" PAD ", stdout);
+ if (option->info & OPAD_PREFIX)
+ fputs (" PREFIX", stdout);
+ if (option->info & OPAD_POSTFIX)
+ fputs (" POSTFIX", stdout);
+ if (option->info & OPAD_SYMBOL)
+ fputs (" SYMBOL", stdout);
+ break;
+ case ODK_HWPATCH:
+ fputs (" HWPATCH ", stdout);
+ if (option->info & OHW_R4KEOP)
+ fputs (" R4KEOP", stdout);
+ if (option->info & OHW_R8KPFETCH)
+ fputs (" R8KPFETCH", stdout);
+ if (option->info & OHW_R5KEOP)
+ fputs (" R5KEOP", stdout);
+ if (option->info & OHW_R5KCVTL)
+ fputs (" R5KCVTL", stdout);
+ break;
+ case ODK_FILL:
+ fputs (" FILL ", stdout);
+ /* XXX Print content of info word? */
+ break;
+ case ODK_TAGS:
+ fputs (" TAGS ", stdout);
+ /* XXX Print content of info word? */
+ break;
+ case ODK_HWAND:
+ fputs (" HWAND ", stdout);
+ if (option->info & OHWA0_R4KEOP_CHECKED)
+ fputs (" R4KEOP_CHECKED", stdout);
+ if (option->info & OHWA0_R4KEOP_CLEAN)
+ fputs (" R4KEOP_CLEAN", stdout);
+ break;
+ case ODK_HWOR:
+ fputs (" HWOR ", stdout);
+ if (option->info & OHWA0_R4KEOP_CHECKED)
+ fputs (" R4KEOP_CHECKED", stdout);
+ if (option->info & OHWA0_R4KEOP_CLEAN)
+ fputs (" R4KEOP_CLEAN", stdout);
+ break;
+ case ODK_GP_GROUP:
+ printf (" GP_GROUP %#06lx self-contained %#06lx",
+ option->info & OGP_GROUP,
+ (option->info & OGP_SELF) >> 16);
+ break;
+ case ODK_IDENT:
+ printf (" IDENT %#06lx self-contained %#06lx",
+ option->info & OGP_GROUP,
+ (option->info & OGP_SELF) >> 16);
+ break;
+ default:
+ /* This shouldn't happen. */
+ printf (" %3d ??? %d %lx",
+ option->kind, option->section, option->info);
+ break;
+ }
+
+ len = sizeof (*eopt);
+ while (len < option->size)
+ if (((char *) option)[len] >= ' '
+ && ((char *) option)[len] < 0x7f)
+ printf ("%c", ((char *) option)[len++]);
+ else
+ printf ("\\%03o", ((char *) option)[len++]);
+
+ fputs ("\n", stdout);
+ ++option;
+ }
+
+ free (eopt);
+ }
+
+ if (conflicts_offset != 0 && conflictsno != 0)
+ {
+ Elf32_External_Conflict *econf32;
+ Elf64_External_Conflict *econf64;
+ Elf32_Conflict *iconf;
+ size_t cnt;
+
+ if (dynamic_symbols == NULL)
+ {
+ error (_("conflict list with without table"));
+ return 0;
+ }
+
+ iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
+ if (iconf == NULL)
+ {
+ error (_("Out of memory"));
+ return 0;
+ }
+
+ if (binary_class == ELFCLASS32)
+ {
+ GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
+ econf32, Elf32_External_Conflict *, "conflict");
+
+ for (cnt = 0; cnt < conflictsno; ++cnt)
+ iconf[cnt] = BYTE_GET (econf32[cnt]);
+ }
+ else
+ {
+ GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
+ econf64, Elf64_External_Conflict *, "conflict");
+
+ for (cnt = 0; cnt < conflictsno; ++cnt)
+ iconf[cnt] = BYTE_GET (econf64[cnt]);
+ }
+
+ printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
+ puts (_(" Num: Index Value Name"));
+
+ for (cnt = 0; cnt < conflictsno; ++cnt)
+ {
+ Elf_Internal_Sym *psym = &dynamic_symbols[iconf[cnt]];
+
+ printf ("%5u: %8lu %#10lx %s\n",
+ cnt, iconf[cnt], (unsigned long) psym->st_value,
+ dynamic_strings + psym->st_name);
+ }
+
+
+ free (iconf);
+ }
+
+ return 1;
+}
+
+static int
+process_arch_specific (file)
+ FILE *file;
+{
+ switch (elf_header.e_machine)
+ {
+ case EM_MIPS:
+ case EM_MIPS_RS4_BE:
+ return process_mips_specific (file);
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static int
+get_file_header (file)
+ FILE * file;
+{
+ Elf32_External_Ehdr ehdr;
+
+ if (fread (& ehdr, sizeof (ehdr), 1, file) != 1)
+ return 0;
+
+ memcpy (elf_header.e_ident, ehdr.e_ident, EI_NIDENT);
+
+ if (elf_header.e_ident [EI_DATA] == ELFDATA2LSB)
+ byte_get = byte_get_little_endian;
+ else
+ byte_get = byte_get_big_endian;
+
+ elf_header.e_entry = BYTE_GET (ehdr.e_entry);
+ elf_header.e_phoff = BYTE_GET (ehdr.e_phoff);
+ elf_header.e_shoff = BYTE_GET (ehdr.e_shoff);
+ elf_header.e_version = BYTE_GET (ehdr.e_version);
+ elf_header.e_flags = BYTE_GET (ehdr.e_flags);
+ elf_header.e_type = BYTE_GET (ehdr.e_type);
+ elf_header.e_machine = BYTE_GET (ehdr.e_machine);
+ elf_header.e_ehsize = BYTE_GET (ehdr.e_ehsize);
+ elf_header.e_phentsize = BYTE_GET (ehdr.e_phentsize);
+ elf_header.e_phnum = BYTE_GET (ehdr.e_phnum);
+ elf_header.e_shentsize = BYTE_GET (ehdr.e_shentsize);
+ elf_header.e_shnum = BYTE_GET (ehdr.e_shnum);
+ elf_header.e_shstrndx = BYTE_GET (ehdr.e_shstrndx);
+
+ return 1;
+}
+
+static void
+process_file (file_name)
+ char * file_name;
+{
+ FILE * file;
+ struct stat statbuf;
+ unsigned int i;
+
+ if (stat (file_name, & statbuf) < 0)
+ {
+ error (_("Cannot stat input file %s.\n"), file_name);
+ return;
+ }
+
+ file = fopen (file_name, "rb");
+ if (file == NULL)
+ {
+ error (_("Input file %s not found.\n"), file_name);
+ return;
+ }
+
+ if (! get_file_header (file))
+ {
+ error (_("%s: Failed to read file header\n"), file_name);
+ fclose (file);
+ return;
+ }
+
+ /* Initialise per file variables. */
+ for (i = NUM_ELEM (version_info); i--;)
+ version_info[i] = 0;
+
+ for (i = NUM_ELEM (dynamic_info); i--;)
+ dynamic_info[i] = 0;
+
+ /* Process the file. */
+ if (show_name)
+ printf (_("\nFile: %s\n"), file_name);
+
+ if (! process_file_header ())
+ {
+ fclose (file);
+ return;
+ }
+
+ process_section_headers (file);
+
+ process_program_headers (file);
+
+ process_dynamic_segment (file);
+
+ process_relocs (file);
+
+ process_symbol_table (file);
+
+ process_syminfo (file);
+
+ process_version_sections (file);
+
+ process_section_contents (file);
+
+ process_arch_specific (file);
+
+ fclose (file);
+
+ if (section_headers)
+ {
+ free (section_headers);
+ section_headers = NULL;
+ }
+
+ if (string_table)
+ {
+ free (string_table);
+ string_table = NULL;
+ }
+
+ if (dynamic_strings)
+ {
+ free (dynamic_strings);
+ dynamic_strings = NULL;
+ }
+
+ if (dynamic_symbols)
+ {
+ free (dynamic_symbols);
+ dynamic_symbols = NULL;
+ }
+
+ if (dynamic_syminfo)
+ {
+ free (dynamic_syminfo);
+ dynamic_syminfo = NULL;
+ }
+}
+
+#ifdef SUPPORT_DISASSEMBLY
+/* Needed by the i386 disassembler. For extra credit, someone could
+fix this so that we insert symbolic addresses here, esp for GOT/PLT
+symbols */
+
+void
+print_address (unsigned int addr, FILE * outfile)
+{
+ fprintf (outfile,"0x%8.8x", addr);
+}
+
+/* Needed by the i386 disassembler. */
+void
+db_task_printsym (unsigned int addr)
+{
+ print_address (addr, stderr);
+}
+#endif
+
+int
+main (argc, argv)
+ int argc;
+ char ** argv;
+{
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ parse_args (argc, argv);
+
+ if (optind < (argc - 1))
+ show_name = 1;
+
+ while (optind < argc)
+ process_file (argv [optind ++]);
+
+ if (dump_sects != NULL)
+ free (dump_sects);
+
+ return 0;
+}
diff --git a/binutils/rename.c b/binutils/rename.c
new file mode 100644
index 00000000000..fdc7263d1fc
--- /dev/null
+++ b/binutils/rename.c
@@ -0,0 +1,210 @@
+/* rename.c -- rename a file, preserving symlinks.
+ Copyright (C) 1999 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bucomm.h"
+
+#include <sys/stat.h>
+
+#ifdef HAVE_GOOD_UTIME_H
+#include <utime.h>
+#else /* ! HAVE_GOOD_UTIME_H */
+#ifdef HAVE_UTIMES
+#include <sys/time.h>
+#endif /* HAVE_UTIMES */
+#endif /* ! HAVE_GOOD_UTIME_H */
+
+static int simple_copy PARAMS ((const char *, const char *));
+
+/* The number of bytes to copy at once. */
+#define COPY_BUF 8192
+
+/* Copy file FROM to file TO, performing no translations.
+ Return 0 if ok, -1 if error. */
+
+static int
+simple_copy (from, to)
+ const char *from;
+ const char *to;
+{
+ int fromfd, tofd, nread;
+ int saved;
+ char buf[COPY_BUF];
+
+ fromfd = open (from, O_RDONLY);
+ if (fromfd < 0)
+ return -1;
+ tofd = creat (to, 0777);
+ if (tofd < 0)
+ {
+ saved = errno;
+ close (fromfd);
+ errno = saved;
+ return -1;
+ }
+ while ((nread = read (fromfd, buf, sizeof buf)) > 0)
+ {
+ if (write (tofd, buf, nread) != nread)
+ {
+ saved = errno;
+ close (fromfd);
+ close (tofd);
+ errno = saved;
+ return -1;
+ }
+ }
+ saved = errno;
+ close (fromfd);
+ close (tofd);
+ if (nread < 0)
+ {
+ errno = saved;
+ return -1;
+ }
+ return 0;
+}
+
+/* Set the times of the file DESTINATION to be the same as those in
+ STATBUF. */
+
+void
+set_times (destination, statbuf)
+ const char *destination;
+ const struct stat *statbuf;
+{
+ int result;
+
+ {
+#ifdef HAVE_GOOD_UTIME_H
+ struct utimbuf tb;
+
+ tb.actime = statbuf->st_atime;
+ tb.modtime = statbuf->st_mtime;
+ result = utime (destination, &tb);
+#else /* ! HAVE_GOOD_UTIME_H */
+#ifndef HAVE_UTIMES
+ long tb[2];
+
+ tb[0] = statbuf->st_atime;
+ tb[1] = statbuf->st_mtime;
+ result = utime (destination, tb);
+#else /* HAVE_UTIMES */
+ struct timeval tv[2];
+
+ tv[0].tv_sec = statbuf->st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = statbuf->st_mtime;
+ tv[1].tv_usec = 0;
+ result = utimes (destination, tv);
+#endif /* HAVE_UTIMES */
+#endif /* ! HAVE_GOOD_UTIME_H */
+ }
+
+ if (result != 0)
+ non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
+}
+
+#ifndef S_ISLNK
+#ifdef S_IFLNK
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#else
+#define S_ISLNK(m) 0
+#define lstat stat
+#endif
+#endif
+
+/* Rename FROM to TO, copying if TO is a link.
+ Return 0 if ok, -1 if error. */
+
+int
+smart_rename (from, to, preserve_dates)
+ const char *from;
+ const char *to;
+ int preserve_dates;
+{
+ int exists;
+ struct stat s;
+ int ret = 0;
+
+ exists = lstat (to, &s);
+
+#if defined (_WIN32) && !defined (__CYGWIN32__)
+ /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
+ fail instead. Also, chown is not present. */
+
+ if (exists == 0)
+ remove (to);
+
+ ret = rename (from, to);
+ if (ret != 0)
+ {
+ /* We have to clean up here. */
+
+ non_fatal (_("%s: rename: %s"), to, strerror (errno));
+ unlink (from);
+ }
+#else
+ /* Use rename only if TO is not a symbolic link and has
+ only one hard link. */
+ if (exists < 0 || (!S_ISLNK (s.st_mode) && s.st_nlink == 1))
+ {
+ ret = rename (from, to);
+ if (ret == 0)
+ {
+ if (exists)
+ {
+ /* Try to preserve the permission bits and ownership of
+ TO. First get the mode right except for the setuid
+ bit. Then change the ownership. Then fix the setuid
+ bit. We do the chmod before the chown because if the
+ chown succeeds, and we are a normal user, we won't be
+ able to do the chmod afterward. We don't bother to
+ fix the setuid bit first because that might introduce
+ a fleeting security problem, and because the chown
+ will clear the setuid bit anyhow. We only fix the
+ setuid bit if the chown succeeds, because we don't
+ want to introduce an unexpected setuid file owned by
+ the user running objcopy. */
+ chmod (to, s.st_mode & 0777);
+ if (chown (to, s.st_uid, s.st_gid) >= 0)
+ chmod (to, s.st_mode & 07777);
+ }
+ }
+ else
+ {
+ /* We have to clean up here. */
+ non_fatal (_("%s: rename: %s"), to, strerror (errno));
+ unlink (from);
+ }
+ }
+ else
+ {
+ ret = simple_copy (from, to);
+ if (ret != 0)
+ non_fatal (_("%s: simple_copy: %s"), to, strerror (errno));
+
+ if (preserve_dates)
+ set_times (to, &s);
+ unlink (from);
+ }
+#endif /* _WIN32 && !__CYGWIN32__ */
+
+ return ret;
+}
diff --git a/binutils/resbin.c b/binutils/resbin.c
new file mode 100644
index 00000000000..8fc07fbb292
--- /dev/null
+++ b/binutils/resbin.c
@@ -0,0 +1,2387 @@
+/* resbin.c -- manipulate the Windows binary resource format.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains functions to convert between the binary resource
+ format and the internal structures that we want to use. The same
+ binary resource format is used in both res and COFF files. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windres.h"
+
+/* Macros to swap in values. */
+
+#define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s))
+#define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s))
+
+/* Local functions. */
+
+static void toosmall PARAMS ((const char *));
+static unichar *get_unicode
+ PARAMS ((const unsigned char *, unsigned long, int, int *));
+static int get_resid
+ PARAMS ((struct res_id *, const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_generic
+ PARAMS ((enum res_type, const unsigned char *, unsigned long));
+static struct res_resource *bin_to_res_cursor
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_menu
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct menuitem *bin_to_res_menuitems
+ PARAMS ((const unsigned char *, unsigned long, int, int *));
+static struct menuitem *bin_to_res_menuexitems
+ PARAMS ((const unsigned char *, unsigned long, int, int *));
+static struct res_resource *bin_to_res_dialog
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_string
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_fontdir
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_accelerators
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_rcdata
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_group_cursor
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_group_icon
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_version
+ PARAMS ((const unsigned char *, unsigned long, int));
+static struct res_resource *bin_to_res_userdata
+ PARAMS ((const unsigned char *, unsigned long, int));
+
+/* Given a resource type ID, a pointer to data, a length, return a
+ res_resource structure which represents that resource. The caller
+ is responsible for initializing the res_info and coff_info fields
+ of the returned structure. */
+
+struct res_resource *
+bin_to_res (type, data, length, big_endian)
+ struct res_id type;
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ if (type.named)
+ return bin_to_res_userdata (data, length, big_endian);
+ else
+ {
+ switch (type.u.id)
+ {
+ default:
+ return bin_to_res_userdata (data, length, big_endian);
+ case RT_CURSOR:
+ return bin_to_res_cursor (data, length, big_endian);
+ case RT_BITMAP:
+ return bin_to_res_generic (RES_TYPE_BITMAP, data, length);
+ case RT_ICON:
+ return bin_to_res_generic (RES_TYPE_ICON, data, length);
+ case RT_MENU:
+ return bin_to_res_menu (data, length, big_endian);
+ case RT_DIALOG:
+ return bin_to_res_dialog (data, length, big_endian);
+ case RT_STRING:
+ return bin_to_res_string (data, length, big_endian);
+ case RT_FONTDIR:
+ return bin_to_res_fontdir (data, length, big_endian);
+ case RT_FONT:
+ return bin_to_res_generic (RES_TYPE_FONT, data, length);
+ case RT_ACCELERATOR:
+ return bin_to_res_accelerators (data, length, big_endian);
+ case RT_RCDATA:
+ return bin_to_res_rcdata (data, length, big_endian);
+ case RT_MESSAGETABLE:
+ return bin_to_res_generic (RES_TYPE_MESSAGETABLE, data, length);
+ case RT_GROUP_CURSOR:
+ return bin_to_res_group_cursor (data, length, big_endian);
+ case RT_GROUP_ICON:
+ return bin_to_res_group_icon (data, length, big_endian);
+ case RT_VERSION:
+ return bin_to_res_version (data, length, big_endian);
+ }
+ }
+}
+
+/* Give an error if the binary data is too small. */
+
+static void
+toosmall (msg)
+ const char *msg;
+{
+ fatal (_("%s: not enough binary data"), msg);
+}
+
+/* Swap in a NULL terminated unicode string. */
+
+static unichar *
+get_unicode (data, length, big_endian, retlen)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+ int *retlen;
+{
+ int c, i;
+ unichar *ret;
+
+ c = 0;
+ while (1)
+ {
+ if (length < (unsigned long) c * 2 + 2)
+ toosmall (_("null terminated unicode string"));
+ if (get_16 (big_endian, data + c * 2) == 0)
+ break;
+ ++c;
+ }
+
+ ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));
+
+ for (i = 0; i < c; i++)
+ ret[i] = get_16 (big_endian, data + i * 2);
+ ret[i] = 0;
+
+ if (retlen != NULL)
+ *retlen = c;
+
+ return ret;
+}
+
+/* Get a resource identifier. This returns the number of bytes used. */
+
+static int
+get_resid (id, data, length, big_endian)
+ struct res_id *id;
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ int first;
+
+ if (length < 2)
+ toosmall (_("resource ID"));
+
+ first = get_16 (big_endian, data);
+ if (first == 0xffff)
+ {
+ if (length < 4)
+ toosmall (_("resource ID"));
+ id->named = 0;
+ id->u.id = get_16 (big_endian, data + 2);
+ return 4;
+ }
+ else
+ {
+ id->named = 1;
+ id->u.n.name = get_unicode (data, length, big_endian, &id->u.n.length);
+ return id->u.n.length * 2 + 2;
+ }
+}
+
+/* Convert a resource which just stores uninterpreted data from
+ binary. */
+
+struct res_resource *
+bin_to_res_generic (type, data, length)
+ enum res_type type;
+ const unsigned char *data;
+ unsigned long length;
+{
+ struct res_resource *r;
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = type;
+ r->u.data.data = data;
+ r->u.data.length = length;
+
+ return r;
+}
+
+/* Convert a cursor resource from binary. */
+
+struct res_resource *
+bin_to_res_cursor (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ struct cursor *c;
+ struct res_resource *r;
+
+ if (length < 4)
+ toosmall (_("cursor"));
+
+ c = (struct cursor *) res_alloc (sizeof *c);
+ c->xhotspot = get_16 (big_endian, data);
+ c->yhotspot = get_16 (big_endian, data + 2);
+ c->length = length - 4;
+ c->data = data + 4;
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_CURSOR;
+ r->u.cursor = c;
+
+ return r;
+}
+
+/* Convert a menu resource from binary. */
+
+struct res_resource *
+bin_to_res_menu (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ struct res_resource *r;
+ struct menu *m;
+ int version, read;
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_MENU;
+
+ m = (struct menu *) res_alloc (sizeof *m);
+ r->u.menu = m;
+
+ if (length < 2)
+ toosmall (_("menu header"));
+
+ version = get_16 (big_endian, data);
+
+ if (version == 0)
+ {
+ if (length < 4)
+ toosmall (_("menu header"));
+ m->help = 0;
+ m->items = bin_to_res_menuitems (data + 4, length - 4, big_endian,
+ &read);
+ }
+ else if (version == 1)
+ {
+ unsigned int offset;
+
+ if (length < 8)
+ toosmall (_("menuex header"));
+ m->help = get_32 (big_endian, data + 4);
+ offset = get_16 (big_endian, data + 2);
+ if (offset + 4 >= length)
+ toosmall (_("menuex offset"));
+ m->items = bin_to_res_menuexitems (data + 4 + offset,
+ length - (4 + offset),
+ big_endian,
+ &read);
+ }
+ else
+ fatal (_("unsupported menu version %d"), version);
+
+ return r;
+}
+
+/* Convert menu items from binary. */
+
+static struct menuitem *
+bin_to_res_menuitems (data, length, big_endian, read)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+ int *read;
+{
+ struct menuitem *first, **pp;
+
+ first = NULL;
+ pp = &first;
+
+ *read = 0;
+
+ while (length > 0)
+ {
+ int flags, slen, itemlen;
+ unsigned int stroff;
+ struct menuitem *mi;
+
+ if (length < 4)
+ toosmall (_("menuitem header"));
+
+ mi = (struct menuitem *) res_alloc (sizeof *mi);
+ mi->state = 0;
+ mi->help = 0;
+
+ flags = get_16 (big_endian, data);
+ mi->type = flags &~ (MENUITEM_POPUP | MENUITEM_ENDMENU);
+
+ if ((flags & MENUITEM_POPUP) == 0)
+ stroff = 4;
+ else
+ stroff = 2;
+
+ if (length < stroff + 2)
+ toosmall (_("menuitem header"));
+
+ if (get_16 (big_endian, data + stroff) == 0)
+ {
+ slen = 0;
+ mi->text = NULL;
+ }
+ else
+ mi->text = get_unicode (data + stroff, length - stroff, big_endian,
+ &slen);
+
+ itemlen = stroff + slen * 2 + 2;
+
+ if ((flags & MENUITEM_POPUP) == 0)
+ {
+ mi->popup = NULL;
+ mi->id = get_16 (big_endian, data + 2);
+ }
+ else
+ {
+ int subread;
+
+ mi->id = 0;
+ mi->popup = bin_to_res_menuitems (data + itemlen, length - itemlen,
+ big_endian, &subread);
+ itemlen += subread;
+ }
+
+ mi->next = NULL;
+ *pp = mi;
+ pp = &mi->next;
+
+ data += itemlen;
+ length -= itemlen;
+ *read += itemlen;
+
+ if ((flags & MENUITEM_ENDMENU) != 0)
+ return first;
+ }
+
+ return first;
+}
+
+/* Convert menuex items from binary. */
+
+static struct menuitem *
+bin_to_res_menuexitems (data, length, big_endian, read)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+ int *read;
+{
+ struct menuitem *first, **pp;
+
+ first = NULL;
+ pp = &first;
+
+ *read = 0;
+
+ while (length > 0)
+ {
+ int flags, slen;
+ unsigned int itemlen;
+ struct menuitem *mi;
+
+ if (length < 14)
+ toosmall (_("menuitem header"));
+
+ mi = (struct menuitem *) res_alloc (sizeof *mi);
+ mi->type = get_32 (big_endian, data);
+ mi->state = get_32 (big_endian, data + 4);
+ mi->id = get_16 (big_endian, data + 8);
+
+ flags = get_16 (big_endian, data + 10);
+
+ if (get_16 (big_endian, data + 12) == 0)
+ {
+ slen = 0;
+ mi->text = NULL;
+ }
+ else
+ mi->text = get_unicode (data + 12, length - 12, big_endian, &slen);
+
+ itemlen = 12 + slen * 2 + 2;
+ itemlen = (itemlen + 3) &~ 3;
+
+ if ((flags & 1) == 0)
+ {
+ mi->popup = NULL;
+ mi->help = 0;
+ }
+ else
+ {
+ int subread;
+
+ if (length < itemlen + 4)
+ toosmall (_("menuitem"));
+ mi->help = get_32 (big_endian, data + itemlen);
+ itemlen += 4;
+
+ mi->popup = bin_to_res_menuexitems (data + itemlen,
+ length - itemlen,
+ big_endian, &subread);
+ itemlen += subread;
+ }
+
+ mi->next = NULL;
+ *pp = mi;
+ pp = &mi->next;
+
+ data += itemlen;
+ length -= itemlen;
+ *read += itemlen;
+
+ if ((flags & 0x80) != 0)
+ return first;
+ }
+
+ return first;
+}
+
+/* Convert a dialog resource from binary. */
+
+static struct res_resource *
+bin_to_res_dialog (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ int version;
+ struct dialog *d;
+ int c, sublen, i;
+ unsigned int off;
+ struct dialog_control **pp;
+ struct res_resource *r;
+
+ if (length < 18)
+ toosmall (_("dialog header"));
+
+ d = (struct dialog *) res_alloc (sizeof *d);
+
+ version = get_16 (big_endian, data);
+ if (version != 1)
+ {
+ d->ex = NULL;
+ d->style = get_32 (big_endian, data);
+ d->exstyle = get_32 (big_endian, data + 4);
+ off = 8;
+ }
+ else
+ {
+ int signature;
+
+ signature = get_16 (big_endian, data + 2);
+ if (signature != 0xffff)
+ fatal (_("unexpected dialog signature %d"), signature);
+
+ d->ex = (struct dialog_ex *) res_alloc (sizeof (struct dialog_ex));
+ d->ex->help = get_32 (big_endian, data + 4);
+ d->exstyle = get_32 (big_endian, data + 8);
+ d->style = get_32 (big_endian, data + 12);
+ off = 16;
+ }
+
+ if (length < off + 10)
+ toosmall (_("dialog header"));
+
+ c = get_16 (big_endian, data + off);
+ d->x = get_16 (big_endian, data + off + 2);
+ d->y = get_16 (big_endian, data + off + 4);
+ d->width = get_16 (big_endian, data + off + 6);
+ d->height = get_16 (big_endian, data + off + 8);
+
+ off += 10;
+
+ sublen = get_resid (&d->menu, data + off, length - off, big_endian);
+ off += sublen;
+
+ sublen = get_resid (&d->class, data + off, length - off, big_endian);
+ off += sublen;
+
+ d->caption = get_unicode (data + off, length - off, big_endian, &sublen);
+ off += sublen * 2 + 2;
+
+ if ((d->style & DS_SETFONT) == 0)
+ {
+ d->pointsize = 0;
+ d->font = NULL;
+ if (d->ex != NULL)
+ {
+ d->ex->weight = 0;
+ d->ex->italic = 0;
+ }
+ }
+ else
+ {
+ if (length < off + 2)
+ toosmall (_("dialog font point size"));
+
+ d->pointsize = get_16 (big_endian, data + off);
+ off += 2;
+
+ if (d->ex != NULL)
+ {
+ if (length < off + 4)
+ toosmall (_("dialogex font information"));
+ d->ex->weight = get_16 (big_endian, data + off);
+ d->ex->italic = get_16 (big_endian, data + off + 2);
+ off += 4;
+ }
+
+ d->font = get_unicode (data + off, length - off, big_endian, &sublen);
+ off += sublen * 2 + 2;
+ }
+
+ d->controls = NULL;
+ pp = &d->controls;
+
+ for (i = 0; i < c; i++)
+ {
+ struct dialog_control *dc;
+ int datalen;
+
+ off = (off + 3) &~ 3;
+
+ dc = (struct dialog_control *) res_alloc (sizeof *dc);
+
+ if (d->ex == NULL)
+ {
+ if (length < off + 8)
+ toosmall (_("dialog control"));
+
+ dc->style = get_32 (big_endian, data + off);
+ dc->exstyle = get_32 (big_endian, data + off + 4);
+ dc->help = 0;
+ off += 8;
+ }
+ else
+ {
+ if (length < off + 12)
+ toosmall (_("dialogex control"));
+ dc->help = get_32 (big_endian, data + off);
+ dc->exstyle = get_32 (big_endian, data + off + 4);
+ dc->style = get_32 (big_endian, data + off + 8);
+ off += 12;
+ }
+
+ if (length < off + 10)
+ toosmall (_("dialog control"));
+
+ dc->x = get_16 (big_endian, data + off);
+ dc->y = get_16 (big_endian, data + off + 2);
+ dc->width = get_16 (big_endian, data + off + 4);
+ dc->height = get_16 (big_endian, data + off + 6);
+
+ if (d->ex != NULL)
+ dc->id = get_32 (big_endian, data + off + 8);
+ else
+ dc->id = get_16 (big_endian, data + off + 8);
+
+ off += 10 + (d->ex != NULL ? 2 : 0);
+
+ sublen = get_resid (&dc->class, data + off, length - off, big_endian);
+ off += sublen;
+
+ sublen = get_resid (&dc->text, data + off, length - off, big_endian);
+ off += sublen;
+
+ if (length < off + 2)
+ toosmall (_("dialog control end"));
+
+ datalen = get_16 (big_endian, data + off);
+ off += 2;
+
+ if (datalen == 0)
+ dc->data = NULL;
+ else
+ {
+ off = (off + 3) &~ 3;
+
+ if (length < off + datalen)
+ toosmall (_("dialog control data"));
+
+ dc->data = ((struct rcdata_item *)
+ res_alloc (sizeof (struct rcdata_item)));
+ dc->data->next = NULL;
+ dc->data->type = RCDATA_BUFFER;
+ dc->data->u.buffer.length = datalen;
+ dc->data->u.buffer.data = data + off;
+
+ off += datalen;
+ }
+
+ dc->next = NULL;
+ *pp = dc;
+ pp = &dc->next;
+ }
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_DIALOG;
+ r->u.dialog = d;
+
+ return r;
+}
+
+/* Convert a stringtable resource from binary. */
+
+static struct res_resource *
+bin_to_res_string (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ struct stringtable *st;
+ int i;
+ struct res_resource *r;
+
+ st = (struct stringtable *) res_alloc (sizeof *st);
+
+ for (i = 0; i < 16; i++)
+ {
+ unsigned int slen;
+
+ if (length < 2)
+ toosmall (_("stringtable string length"));
+ slen = get_16 (big_endian, data);
+ st->strings[i].length = slen;
+
+ if (slen > 0)
+ {
+ unichar *s;
+ unsigned int j;
+
+ if (length < 2 + 2 * slen)
+ toosmall (_("stringtable string"));
+
+ s = (unichar *) res_alloc (slen * sizeof (unichar));
+ st->strings[i].string = s;
+
+ for (j = 0; j < slen; j++)
+ s[j] = get_16 (big_endian, data + 2 + j * 2);
+ }
+
+ data += 2 + 2 * slen;
+ length -= 2 + 2 * slen;
+ }
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_STRINGTABLE;
+ r->u.stringtable = st;
+
+ return r;
+}
+
+/* Convert a fontdir resource from binary. */
+
+static struct res_resource *
+bin_to_res_fontdir (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ int c, i;
+ struct fontdir *first, **pp;
+ struct res_resource *r;
+
+ if (length < 2)
+ toosmall (_("fontdir header"));
+
+ c = get_16 (big_endian, data);
+
+ first = NULL;
+ pp = &first;
+
+ for (i = 0; i < c; i++)
+ {
+ struct fontdir *fd;
+ unsigned int off;
+
+ if (length < 56)
+ toosmall (_("fontdir"));
+
+ fd = (struct fontdir *) res_alloc (sizeof *fd);
+ fd->index = get_16 (big_endian, data);
+
+ /* To work out the length of the fontdir data, we must get the
+ length of the device name and face name strings, even though
+ we don't store them in the fontdir structure. The
+ documentation says that these are NULL terminated char
+ strings, not Unicode strings. */
+
+ off = 56;
+
+ while (off < length && data[off] != '\0')
+ ++off;
+ if (off >= length)
+ toosmall (_("fontdir device name"));
+ ++off;
+
+ while (off < length && data[off] != '\0')
+ ++off;
+ if (off >= length)
+ toosmall (_("fontdir face name"));
+ ++off;
+
+ fd->length = off;
+ fd->data = data;
+
+ fd->next = NULL;
+ *pp = fd;
+ pp = &fd->next;
+
+ /* The documentation does not indicate that any rounding is
+ required. */
+
+ data += off;
+ length -= off;
+ }
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_FONTDIR;
+ r->u.fontdir = first;
+
+ return r;
+}
+
+/* Convert an accelerators resource from binary. */
+
+static struct res_resource *
+bin_to_res_accelerators (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ struct accelerator *first, **pp;
+ struct res_resource *r;
+
+ first = NULL;
+ pp = &first;
+
+ while (1)
+ {
+ struct accelerator *a;
+
+ if (length < 8)
+ toosmall (_("accelerator"));
+
+ a = (struct accelerator *) res_alloc (sizeof *a);
+
+ a->flags = get_16 (big_endian, data);
+ a->key = get_16 (big_endian, data + 2);
+ a->id = get_16 (big_endian, data + 4);
+
+ a->next = NULL;
+ *pp = a;
+ pp = &a->next;
+
+ if ((a->flags & ACC_LAST) != 0)
+ break;
+
+ data += 8;
+ length -= 8;
+ }
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_ACCELERATOR;
+ r->u.acc = first;
+
+ return r;
+}
+
+/* Convert an rcdata resource from binary. */
+
+static struct res_resource *
+bin_to_res_rcdata (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ struct rcdata_item *ri;
+ struct res_resource *r;
+
+ ri = (struct rcdata_item *) res_alloc (sizeof *ri);
+
+ ri->next = NULL;
+ ri->type = RCDATA_BUFFER;
+ ri->u.buffer.length = length;
+ ri->u.buffer.data = data;
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_RCDATA;
+ r->u.rcdata = ri;
+
+ return r;
+}
+
+/* Convert a group cursor resource from binary. */
+
+static struct res_resource *
+bin_to_res_group_cursor (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ int type, c, i;
+ struct group_cursor *first, **pp;
+ struct res_resource *r;
+
+ if (length < 6)
+ toosmall (_("group cursor header"));
+
+ type = get_16 (big_endian, data + 2);
+ if (type != 2)
+ fatal (_("unexpected group cursor type %d"), type);
+
+ c = get_16 (big_endian, data + 4);
+
+ data += 6;
+ length -= 6;
+
+ first = NULL;
+ pp = &first;
+
+ for (i = 0; i < c; i++)
+ {
+ struct group_cursor *gc;
+
+ if (length < 14)
+ toosmall (_("group cursor"));
+
+ gc = (struct group_cursor *) res_alloc (sizeof *gc);
+
+ gc->width = get_16 (big_endian, data);
+ gc->height = get_16 (big_endian, data + 2);
+ gc->planes = get_16 (big_endian, data + 4);
+ gc->bits = get_16 (big_endian, data + 6);
+ gc->bytes = get_32 (big_endian, data + 8);
+ gc->index = get_16 (big_endian, data + 12);
+
+ gc->next = NULL;
+ *pp = gc;
+ pp = &gc->next;
+
+ data += 14;
+ length -= 14;
+ }
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_GROUP_CURSOR;
+ r->u.group_cursor = first;
+
+ return r;
+}
+
+/* Convert a group icon resource from binary. */
+
+static struct res_resource *
+bin_to_res_group_icon (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ int type, c, i;
+ struct group_icon *first, **pp;
+ struct res_resource *r;
+
+ if (length < 6)
+ toosmall (_("group icon header"));
+
+ type = get_16 (big_endian, data + 2);
+ if (type != 1)
+ fatal (_("unexpected group icon type %d"), type);
+
+ c = get_16 (big_endian, data + 4);
+
+ data += 6;
+ length -= 6;
+
+ first = NULL;
+ pp = &first;
+
+ for (i = 0; i < c; i++)
+ {
+ struct group_icon *gi;
+
+ if (length < 14)
+ toosmall (_("group icon"));
+
+ gi = (struct group_icon *) res_alloc (sizeof *gi);
+
+ gi->width = data[0];
+ gi->height = data[1];
+ gi->colors = data[2];
+ gi->planes = get_16 (big_endian, data + 4);
+ gi->bits = get_16 (big_endian, data + 6);
+ gi->bytes = get_32 (big_endian, data + 8);
+ gi->index = get_16 (big_endian, data + 12);
+
+ gi->next = NULL;
+ *pp = gi;
+ pp = &gi->next;
+
+ data += 14;
+ length -= 14;
+ }
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_GROUP_ICON;
+ r->u.group_icon = first;
+
+ return r;
+}
+
+/* Extract data from a version header. If KEY is not NULL, then the
+ key must be KEY; otherwise, the key is returned in *PKEY. This
+ sets *LEN to the total length, *VALLEN to the value length, *TYPE
+ to the type, and *OFF to the offset to the children. */
+
+static void
+get_version_header (data, length, big_endian, key, pkey, len, vallen, type,
+ off)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+ const char *key;
+ unichar **pkey;
+ int *len;
+ int *vallen;
+ int *type;
+ int *off;
+{
+ if (length < 8)
+ toosmall (key);
+
+ *len = get_16 (big_endian, data);
+ *vallen = get_16 (big_endian, data + 2);
+ *type = get_16 (big_endian, data + 4);
+
+ *off = 6;
+
+ length -= 6;
+ data += 6;
+
+ if (key == NULL)
+ {
+ int sublen;
+
+ *pkey = get_unicode (data, length, big_endian, &sublen);
+ *off += sublen * 2 + 2;
+ }
+ else
+ {
+ while (1)
+ {
+ if (length < 2)
+ toosmall (key);
+ if (get_16 (big_endian, data) != (unsigned char) *key)
+ fatal (_("unexpected version string"));
+
+ *off += 2;
+ length -= 2;
+ data += 2;
+
+ if (*key == '\0')
+ break;
+
+ ++key;
+ }
+ }
+
+ *off = (*off + 3) &~ 3;
+}
+
+/* Convert a version resource from binary. */
+
+static struct res_resource *
+bin_to_res_version (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ int verlen, vallen, type, off;
+ struct fixed_versioninfo *fi;
+ struct ver_info *first, **pp;
+ struct versioninfo *v;
+ struct res_resource *r;
+
+ get_version_header (data, length, big_endian, "VS_VERSION_INFO",
+ (unichar *) NULL, &verlen, &vallen, &type, &off);
+
+ if ((unsigned int) verlen != length)
+ fatal (_("version length %d does not match resource length %lu"),
+ verlen, length);
+
+ if (type != 0)
+ fatal (_("unexpected version type %d"), type);
+
+ data += off;
+ length -= off;
+
+ if (vallen == 0)
+ fi = NULL;
+ else
+ {
+ unsigned long signature, fiv;
+
+ if (vallen != 52)
+ fatal (_("unexpected fixed version information length %d"), vallen);
+
+ if (length < 52)
+ toosmall (_("fixed version info"));
+
+ signature = get_32 (big_endian, data);
+ if (signature != 0xfeef04bd)
+ fatal (_("unexpected fixed version signature %lu"), signature);
+
+ fiv = get_32 (big_endian, data + 4);
+ if (fiv != 0 && fiv != 0x10000)
+ fatal (_("unexpected fixed version info version %lu"), fiv);
+
+ fi = (struct fixed_versioninfo *) res_alloc (sizeof *fi);
+
+ fi->file_version_ms = get_32 (big_endian, data + 8);
+ fi->file_version_ls = get_32 (big_endian, data + 12);
+ fi->product_version_ms = get_32 (big_endian, data + 16);
+ fi->product_version_ls = get_32 (big_endian, data + 20);
+ fi->file_flags_mask = get_32 (big_endian, data + 24);
+ fi->file_flags = get_32 (big_endian, data + 28);
+ fi->file_os = get_32 (big_endian, data + 32);
+ fi->file_type = get_32 (big_endian, data + 36);
+ fi->file_subtype = get_32 (big_endian, data + 40);
+ fi->file_date_ms = get_32 (big_endian, data + 44);
+ fi->file_date_ls = get_32 (big_endian, data + 48);
+
+ data += 52;
+ length -= 52;
+ }
+
+ first = NULL;
+ pp = &first;
+
+ while (length > 0)
+ {
+ struct ver_info *vi;
+ int ch;
+
+ if (length < 8)
+ toosmall (_("version var info"));
+
+ vi = (struct ver_info *) res_alloc (sizeof *vi);
+
+ ch = get_16 (big_endian, data + 6);
+
+ if (ch == 'S')
+ {
+ struct ver_stringinfo **ppvs;
+
+ vi->type = VERINFO_STRING;
+
+ get_version_header (data, length, big_endian, "StringFileInfo",
+ (unichar *) NULL, &verlen, &vallen, &type,
+ &off);
+
+ if (vallen != 0)
+ fatal (_("unexpected stringfileinfo value length %d"), vallen);
+
+ data += off;
+ length -= off;
+
+ get_version_header (data, length, big_endian, (const char *) NULL,
+ &vi->u.string.language, &verlen, &vallen,
+ &type, &off);
+
+ if (vallen != 0)
+ fatal (_("unexpected version stringtable value length %d"), vallen);
+
+ data += off;
+ length -= off;
+ verlen -= off;
+
+ vi->u.string.strings = NULL;
+ ppvs = &vi->u.string.strings;
+
+ /* It's convenient to round verlen to a 4 byte alignment,
+ since we round the subvariables in the loop. */
+ verlen = (verlen + 3) &~ 3;
+
+ while (verlen > 0)
+ {
+ struct ver_stringinfo *vs;
+ int subverlen, vslen, valoff;
+
+ vs = (struct ver_stringinfo *) res_alloc (sizeof *vs);
+
+ get_version_header (data, length, big_endian,
+ (const char *) NULL, &vs->key, &subverlen,
+ &vallen, &type, &off);
+
+ subverlen = (subverlen + 3) &~ 3;
+
+ data += off;
+ length -= off;
+
+ vs->value = get_unicode (data, length, big_endian, &vslen);
+ valoff = vslen * 2 + 2;
+ valoff = (valoff + 3) &~ 3;
+
+ if (off + valoff != subverlen)
+ fatal (_("unexpected version string length %d != %d + %d"),
+ subverlen, off, valoff);
+
+ vs->next = NULL;
+ *ppvs = vs;
+ ppvs = &vs->next;
+
+ data += valoff;
+ length -= valoff;
+
+ if (verlen < subverlen)
+ fatal (_("unexpected version string length %d < %d"),
+ verlen, subverlen);
+
+ verlen -= subverlen;
+ }
+ }
+ else if (ch == 'V')
+ {
+ struct ver_varinfo **ppvv;
+
+ vi->type = VERINFO_VAR;
+
+ get_version_header (data, length, big_endian, "VarFileInfo",
+ (unichar *) NULL, &verlen, &vallen, &type,
+ &off);
+
+ if (vallen != 0)
+ fatal (_("unexpected varfileinfo value length %d"), vallen);
+
+ data += off;
+ length -= off;
+
+ get_version_header (data, length, big_endian, (const char *) NULL,
+ &vi->u.var.key, &verlen, &vallen, &type, &off);
+
+ data += off;
+ length -= off;
+
+ vi->u.var.var = NULL;
+ ppvv = &vi->u.var.var;
+
+ while (vallen > 0)
+ {
+ struct ver_varinfo *vv;
+
+ if (length < 4)
+ toosmall (_("version varfileinfo"));
+
+ vv = (struct ver_varinfo *) res_alloc (sizeof *vv);
+
+ vv->language = get_16 (big_endian, data);
+ vv->charset = get_16 (big_endian, data + 2);
+
+ vv->next = NULL;
+ *ppvv = vv;
+ ppvv = &vv->next;
+
+ data += 4;
+ length -= 4;
+
+ if (vallen < 4)
+ fatal (_("unexpected version value length %d"), vallen);
+
+ vallen -= 4;
+ }
+ }
+ else
+ fatal (_("unexpected version string"));
+
+ vi->next = NULL;
+ *pp = vi;
+ pp = &vi->next;
+ }
+
+ v = (struct versioninfo *) res_alloc (sizeof *v);
+ v->fixed = fi;
+ v->var = first;
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_VERSIONINFO;
+ r->u.versioninfo = v;
+
+ return r;
+}
+
+/* Convert an arbitrary user defined resource from binary. */
+
+static struct res_resource *
+bin_to_res_userdata (data, length, big_endian)
+ const unsigned char *data;
+ unsigned long length;
+ int big_endian;
+{
+ struct rcdata_item *ri;
+ struct res_resource *r;
+
+ ri = (struct rcdata_item *) res_alloc (sizeof *ri);
+
+ ri->next = NULL;
+ ri->type = RCDATA_BUFFER;
+ ri->u.buffer.length = length;
+ ri->u.buffer.data = data;
+
+ r = (struct res_resource *) res_alloc (sizeof *r);
+ r->type = RES_TYPE_USERDATA;
+ r->u.rcdata = ri;
+
+ return r;
+}
+
+/* Macros to swap out values. */
+
+#define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
+#define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
+
+/* Local functions used to convert resources to binary format. */
+
+static void dword_align_bin PARAMS ((struct bindata ***, unsigned long *));
+static struct bindata *resid_to_bin PARAMS ((struct res_id, int));
+static struct bindata *unicode_to_bin PARAMS ((const unichar *, int));
+static struct bindata *res_to_bin_accelerator
+ PARAMS ((const struct accelerator *, int));
+static struct bindata *res_to_bin_cursor
+ PARAMS ((const struct cursor *, int));
+static struct bindata *res_to_bin_group_cursor
+ PARAMS ((const struct group_cursor *, int));
+static struct bindata *res_to_bin_dialog
+ PARAMS ((const struct dialog *, int));
+static struct bindata *res_to_bin_fontdir
+ PARAMS ((const struct fontdir *, int));
+static struct bindata *res_to_bin_group_icon
+ PARAMS ((const struct group_icon *, int));
+static struct bindata *res_to_bin_menu
+ PARAMS ((const struct menu *, int));
+static struct bindata *res_to_bin_menuitems
+ PARAMS ((const struct menuitem *, int));
+static struct bindata *res_to_bin_menuexitems
+ PARAMS ((const struct menuitem *, int));
+static struct bindata *res_to_bin_rcdata
+ PARAMS ((const struct rcdata_item *, int));
+static struct bindata *res_to_bin_stringtable
+ PARAMS ((const struct stringtable *, int));
+static struct bindata *string_to_unicode_bin PARAMS ((const char *, int));
+static struct bindata *res_to_bin_versioninfo
+ PARAMS ((const struct versioninfo *, int));
+static struct bindata *res_to_bin_generic
+ PARAMS ((unsigned long, const unsigned char *));
+
+/* Convert a resource to binary. */
+
+struct bindata *
+res_to_bin (res, big_endian)
+ const struct res_resource *res;
+ int big_endian;
+{
+ switch (res->type)
+ {
+ default:
+ abort ();
+ case RES_TYPE_BITMAP:
+ case RES_TYPE_FONT:
+ case RES_TYPE_ICON:
+ case RES_TYPE_MESSAGETABLE:
+ return res_to_bin_generic (res->u.data.length, res->u.data.data);
+ case RES_TYPE_ACCELERATOR:
+ return res_to_bin_accelerator (res->u.acc, big_endian);
+ case RES_TYPE_CURSOR:
+ return res_to_bin_cursor (res->u.cursor, big_endian);
+ case RES_TYPE_GROUP_CURSOR:
+ return res_to_bin_group_cursor (res->u.group_cursor, big_endian);
+ case RES_TYPE_DIALOG:
+ return res_to_bin_dialog (res->u.dialog, big_endian);
+ case RES_TYPE_FONTDIR:
+ return res_to_bin_fontdir (res->u.fontdir, big_endian);
+ case RES_TYPE_GROUP_ICON:
+ return res_to_bin_group_icon (res->u.group_icon, big_endian);
+ case RES_TYPE_MENU:
+ return res_to_bin_menu (res->u.menu, big_endian);
+ case RES_TYPE_RCDATA:
+ return res_to_bin_rcdata (res->u.rcdata, big_endian);
+ case RES_TYPE_STRINGTABLE:
+ return res_to_bin_stringtable (res->u.stringtable, big_endian);
+ case RES_TYPE_USERDATA:
+ return res_to_bin_rcdata (res->u.rcdata, big_endian);
+ case RES_TYPE_VERSIONINFO:
+ return res_to_bin_versioninfo (res->u.versioninfo, big_endian);
+ }
+}
+
+/* Align to a 32 bit boundary. PPP points to the of a list of bindata
+ structures. LENGTH points to the length of the structures. If
+ necessary, this adds a new bindata to bring length up to a 32 bit
+ boundary. It updates *PPP and *LENGTH. */
+
+static void
+dword_align_bin (ppp, length)
+ struct bindata ***ppp;
+ unsigned long *length;
+{
+ int add;
+ struct bindata *d;
+
+ if ((*length & 3) == 0)
+ return;
+
+ add = 4 - (*length & 3);
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = add;
+ d->data = (unsigned char *) reswr_alloc (add);
+ memset (d->data, 0, add);
+
+ d->next = NULL;
+ **ppp = d;
+ *ppp = &(**ppp)->next;
+
+ *length += add;
+}
+
+/* Convert a resource ID to binary. This always returns exactly one
+ bindata structure. */
+
+static struct bindata *
+resid_to_bin (id, big_endian)
+ struct res_id id;
+ int big_endian;
+{
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+
+ if (! id.named)
+ {
+ d->length = 4;
+ d->data = (unsigned char *) reswr_alloc (4);
+ put_16 (big_endian, 0xffff, d->data);
+ put_16 (big_endian, id.u.id, d->data + 2);
+ }
+ else
+ {
+ int i;
+
+ d->length = id.u.n.length * 2 + 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+ for (i = 0; i < id.u.n.length; i++)
+ put_16 (big_endian, id.u.n.name[i], d->data + i * 2);
+ put_16 (big_endian, 0, d->data + i * 2);
+ }
+
+ d->next = NULL;
+
+ return d;
+}
+
+/* Convert a null terminated unicode string to binary. This always
+ returns exactly one bindata structure. */
+
+static struct bindata *
+unicode_to_bin (str, big_endian)
+ const unichar *str;
+ int big_endian;
+{
+ int len;
+ struct bindata *d;
+
+ len = 0;
+ if (str != NULL)
+ {
+ const unichar *s;
+
+ for (s = str; *s != 0; s++)
+ ++len;
+ }
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = len * 2 + 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ if (str == NULL)
+ put_16 (big_endian, 0, d->data);
+ else
+ {
+ const unichar *s;
+ int i;
+
+ for (s = str, i = 0; *s != 0; s++, i++)
+ put_16 (big_endian, *s, d->data + i * 2);
+ put_16 (big_endian, 0, d->data + i * 2);
+ }
+
+ d->next = NULL;
+
+ return d;
+}
+
+/* Convert an accelerator resource to binary. */
+
+static struct bindata *
+res_to_bin_accelerator (accelerators, big_endian)
+ const struct accelerator *accelerators;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ const struct accelerator *a;
+
+ first = NULL;
+ pp = &first;
+
+ for (a = accelerators; a != NULL; a = a->next)
+ {
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 8;
+ d->data = (unsigned char *) reswr_alloc (8);
+
+ put_16 (big_endian,
+ a->flags | (a->next != NULL ? 0 : ACC_LAST),
+ d->data);
+ put_16 (big_endian, a->key, d->data + 2);
+ put_16 (big_endian, a->id, d->data + 4);
+ put_16 (big_endian, 0, d->data + 8);
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ return first;
+}
+
+/* Convert a cursor resource to binary. */
+
+static struct bindata *
+res_to_bin_cursor (c, big_endian)
+ const struct cursor *c;
+ int big_endian;
+{
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 4;
+ d->data = (unsigned char *) reswr_alloc (4);
+
+ put_16 (big_endian, c->xhotspot, d->data);
+ put_16 (big_endian, c->yhotspot, d->data + 2);
+
+ d->next = (struct bindata *) reswr_alloc (sizeof *d);
+ d->next->length = c->length;
+ d->next->data = (unsigned char *) c->data;
+ d->next->next = NULL;
+
+ return d;
+}
+
+/* Convert a group cursor resource to binary. */
+
+static struct bindata *
+res_to_bin_group_cursor (group_cursors, big_endian)
+ const struct group_cursor *group_cursors;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ int c;
+ const struct group_cursor *gc;
+
+ first = (struct bindata *) reswr_alloc (sizeof *first);
+ first->length = 6;
+ first->data = (unsigned char *) reswr_alloc (6);
+
+ put_16 (big_endian, 0, first->data);
+ put_16 (big_endian, 2, first->data + 2);
+
+ first->next = NULL;
+ pp = &first->next;
+
+ c = 0;
+ for (gc = group_cursors; gc != NULL; gc = gc->next)
+ {
+ struct bindata *d;
+
+ ++c;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 14;
+ d->data = (unsigned char *) reswr_alloc (14);
+
+ put_16 (big_endian, gc->width, d->data);
+ put_16 (big_endian, gc->height, d->data + 2);
+ put_16 (big_endian, gc->planes, d->data + 4);
+ put_16 (big_endian, gc->bits, d->data + 6);
+ put_32 (big_endian, gc->bytes, d->data + 8);
+ put_16 (big_endian, gc->index, d->data + 12);
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ put_16 (big_endian, c, first->data + 4);
+
+ return first;
+}
+
+/* Convert a dialog resource to binary. */
+
+static struct bindata *
+res_to_bin_dialog (dialog, big_endian)
+ const struct dialog *dialog;
+ int big_endian;
+{
+ int dialogex;
+ struct bindata *first, **pp;
+ unsigned long length;
+ int off, c;
+ struct dialog_control *dc;
+
+ dialogex = extended_dialog (dialog);
+
+ first = (struct bindata *) reswr_alloc (sizeof *first);
+ first->length = dialogex ? 26 : 18;
+ first->data = (unsigned char *) reswr_alloc (first->length);
+
+ length = first->length;
+
+ if (! dialogex)
+ {
+ put_32 (big_endian, dialog->style, first->data);
+ put_32 (big_endian, dialog->exstyle, first->data + 4);
+ off = 8;
+ }
+ else
+ {
+ put_16 (big_endian, 1, first->data);
+ put_16 (big_endian, 0xffff, first->data + 2);
+
+ if (dialog->ex == NULL)
+ put_32 (big_endian, 0, first->data + 4);
+ else
+ put_32 (big_endian, dialog->ex->help, first->data + 4);
+ put_32 (big_endian, dialog->exstyle, first->data + 8);
+ put_32 (big_endian, dialog->style, first->data + 12);
+ off = 16;
+ }
+
+ put_16 (big_endian, dialog->x, first->data + off + 2);
+ put_16 (big_endian, dialog->y, first->data + off + 4);
+ put_16 (big_endian, dialog->width, first->data + off + 6);
+ put_16 (big_endian, dialog->height, first->data + off + 8);
+
+ pp = &first->next;
+
+ *pp = resid_to_bin (dialog->menu, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ *pp = resid_to_bin (dialog->class, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ *pp = unicode_to_bin (dialog->caption, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ if ((dialog->style & DS_SETFONT) != 0)
+ {
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = dialogex ? 6 : 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ length += d->length;
+
+ put_16 (big_endian, dialog->pointsize, d->data);
+
+ if (dialogex)
+ {
+ if (dialog->ex == NULL)
+ {
+ put_16 (big_endian, 0, d->data + 2);
+ put_16 (big_endian, 0, d->data + 4);
+ }
+ else
+ {
+ put_16 (big_endian, dialog->ex->weight, d->data + 2);
+ put_16 (big_endian, dialog->ex->italic, d->data + 4);
+ }
+ }
+
+ *pp = d;
+ pp = &d->next;
+
+ *pp = unicode_to_bin (dialog->font, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+ }
+
+ c = 0;
+ for (dc = dialog->controls; dc != NULL; dc = dc->next)
+ {
+ struct bindata *d;
+ int dcoff;
+
+ ++c;
+
+ dword_align_bin (&pp, &length);
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = dialogex ? 24 : 18;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ length += d->length;
+
+ if (! dialogex)
+ {
+ put_32 (big_endian, dc->style, d->data);
+ put_32 (big_endian, dc->exstyle, d->data + 4);
+ dcoff = 8;
+ }
+ else
+ {
+ put_32 (big_endian, dc->help, d->data);
+ put_32 (big_endian, dc->exstyle, d->data + 4);
+ put_32 (big_endian, dc->style, d->data + 8);
+ dcoff = 12;
+ }
+
+ put_16 (big_endian, dc->x, d->data + dcoff);
+ put_16 (big_endian, dc->y, d->data + dcoff + 2);
+ put_16 (big_endian, dc->width, d->data + dcoff + 4);
+ put_16 (big_endian, dc->height, d->data + dcoff + 6);
+
+ if (dialogex)
+ put_32 (big_endian, dc->id, d->data + dcoff + 8);
+ else
+ put_16 (big_endian, dc->id, d->data + dcoff + 8);
+
+ *pp = d;
+ pp = &d->next;
+
+ *pp = resid_to_bin (dc->class, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ *pp = resid_to_bin (dc->text, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 2;
+ d->data = (unsigned char *) reswr_alloc (2);
+
+ length += 2;
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+
+ if (dc->data == NULL)
+ put_16 (big_endian, 0, d->data);
+ else
+ {
+ unsigned long sublen;
+
+ dword_align_bin (&pp, &length);
+
+ *pp = res_to_bin_rcdata (dc->data, big_endian);
+ sublen = 0;
+ while (*pp != NULL)
+ {
+ sublen += (*pp)->length;
+ pp = &(*pp)->next;
+ }
+
+ put_16 (big_endian, sublen, d->data);
+
+ length += sublen;
+ }
+ }
+ put_16 (big_endian, c, first->data + off);
+
+ return first;
+}
+
+/* Convert a fontdir resource to binary. */
+
+static struct bindata *
+res_to_bin_fontdir (fontdirs, big_endian)
+ const struct fontdir *fontdirs;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ int c;
+ const struct fontdir *fd;
+
+ first = (struct bindata *) reswr_alloc (sizeof *first);
+ first->length = 2;
+ first->data = (unsigned char *) reswr_alloc (2);
+
+ first->next = NULL;
+ pp = &first->next;
+
+ c = 0;
+ for (fd = fontdirs; fd != NULL; fd = fd->next)
+ {
+ struct bindata *d;
+
+ ++c;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 2;
+ d->data = (unsigned char *) reswr_alloc (2);
+
+ put_16 (big_endian, fd->index, d->data);
+
+ *pp = d;
+ pp = &d->next;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = fd->length;
+ d->data = (unsigned char *) fd->data;
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ put_16 (big_endian, c, first->data);
+
+ return first;
+}
+
+/* Convert a group icon resource to binary. */
+
+static struct bindata *
+res_to_bin_group_icon (group_icons, big_endian)
+ const struct group_icon *group_icons;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ int c;
+ const struct group_icon *gi;
+
+ first = (struct bindata *) reswr_alloc (sizeof *first);
+ first->length = 6;
+ first->data = (unsigned char *) reswr_alloc (6);
+
+ put_16 (big_endian, 0, first->data);
+ put_16 (big_endian, 1, first->data + 2);
+
+ first->next = NULL;
+ pp = &first->next;
+
+ c = 0;
+ for (gi = group_icons; gi != NULL; gi = gi->next)
+ {
+ struct bindata *d;
+
+ ++c;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 14;
+ d->data = (unsigned char *) reswr_alloc (14);
+
+ d->data[0] = gi->width;
+ d->data[1] = gi->height;
+ d->data[2] = gi->colors;
+ d->data[3] = 0;
+ put_16 (big_endian, gi->planes, d->data + 4);
+ put_16 (big_endian, gi->bits, d->data + 6);
+ put_32 (big_endian, gi->bytes, d->data + 8);
+ put_16 (big_endian, gi->index, d->data + 12);
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ put_16 (big_endian, c, first->data + 4);
+
+ return first;
+}
+
+/* Convert a menu resource to binary. */
+
+static struct bindata *
+res_to_bin_menu (menu, big_endian)
+ const struct menu *menu;
+ int big_endian;
+{
+ int menuex;
+ struct bindata *d;
+
+ menuex = extended_menu (menu);
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = menuex ? 8 : 4;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ if (! menuex)
+ {
+ put_16 (big_endian, 0, d->data);
+ put_16 (big_endian, 0, d->data + 2);
+
+ d->next = res_to_bin_menuitems (menu->items, big_endian);
+ }
+ else
+ {
+ put_16 (big_endian, 1, d->data);
+ put_16 (big_endian, 4, d->data + 2);
+ put_32 (big_endian, menu->help, d->data + 4);
+
+ d->next = res_to_bin_menuexitems (menu->items, big_endian);
+ }
+
+ return d;
+}
+
+/* Convert menu items to binary. */
+
+static struct bindata *
+res_to_bin_menuitems (items, big_endian)
+ const struct menuitem *items;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ const struct menuitem *mi;
+
+ first = NULL;
+ pp = &first;
+
+ for (mi = items; mi != NULL; mi = mi->next)
+ {
+ struct bindata *d;
+ int flags;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = mi->popup == NULL ? 4 : 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ flags = mi->type;
+ if (mi->next == NULL)
+ flags |= MENUITEM_ENDMENU;
+ if (mi->popup != NULL)
+ flags |= MENUITEM_POPUP;
+
+ put_16 (big_endian, flags, d->data);
+
+ if (mi->popup == NULL)
+ put_16 (big_endian, mi->id, d->data + 2);
+
+ *pp = d;
+ pp = &d->next;
+
+ *pp = unicode_to_bin (mi->text, big_endian);
+ pp = &(*pp)->next;
+
+ if (mi->popup != NULL)
+ {
+ *pp = res_to_bin_menuitems (mi->popup, big_endian);
+ while (*pp != NULL)
+ pp = &(*pp)->next;
+ }
+ }
+
+ return first;
+}
+
+/* Convert menuex items to binary. */
+
+static struct bindata *
+res_to_bin_menuexitems (items, big_endian)
+ const struct menuitem *items;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ unsigned long length;
+ const struct menuitem *mi;
+
+ first = NULL;
+ pp = &first;
+
+ length = 0;
+
+ for (mi = items; mi != NULL; mi = mi->next)
+ {
+ struct bindata *d;
+ int flags;
+
+ dword_align_bin (&pp, &length);
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 12;
+ d->data = (unsigned char *) reswr_alloc (12);
+
+ length += 12;
+
+ put_32 (big_endian, mi->type, d->data);
+ put_32 (big_endian, mi->state, d->data + 4);
+ put_16 (big_endian, mi->id, d->data + 8);
+
+ flags = 0;
+ if (mi->next == NULL)
+ flags |= 0x80;
+ if (mi->popup != NULL)
+ flags |= 1;
+ put_16 (big_endian, flags, d->data + 10);
+
+ *pp = d;
+ pp = &d->next;
+
+ *pp = unicode_to_bin (mi->text, big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ if (mi->popup != NULL)
+ {
+ dword_align_bin (&pp, &length);
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 4;
+ d->data = (unsigned char *) reswr_alloc (4);
+
+ put_32 (big_endian, mi->help, d->data);
+
+ *pp = d;
+ pp = &d->next;
+
+ *pp = res_to_bin_menuexitems (mi->popup, big_endian);
+ while (*pp != NULL)
+ {
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+ }
+ }
+ }
+
+ return first;
+}
+
+/* Convert an rcdata resource to binary. This is also used to convert
+ other information which happens to be stored in rcdata_item lists
+ to binary. */
+
+static struct bindata *
+res_to_bin_rcdata (items, big_endian)
+ const struct rcdata_item *items;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ const struct rcdata_item *ri;
+
+ first = NULL;
+ pp = &first;
+
+ for (ri = items; ri != NULL; ri = ri->next)
+ {
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+
+ switch (ri->type)
+ {
+ default:
+ abort ();
+
+ case RCDATA_WORD:
+ d->length = 2;
+ d->data = (unsigned char *) reswr_alloc (2);
+ put_16 (big_endian, ri->u.word, d->data);
+ break;
+
+ case RCDATA_DWORD:
+ d->length = 4;
+ d->data = (unsigned char *) reswr_alloc (4);
+ put_32 (big_endian, ri->u.dword, d->data);
+ break;
+
+ case RCDATA_STRING:
+ d->length = ri->u.string.length;
+ d->data = (unsigned char *) ri->u.string.s;
+ break;
+
+ case RCDATA_WSTRING:
+ {
+ unsigned long i;
+
+ d->length = ri->u.wstring.length * 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+ for (i = 0; i < ri->u.wstring.length; i++)
+ put_16 (big_endian, ri->u.wstring.w[i], d->data + i * 2);
+ break;
+ }
+
+ case RCDATA_BUFFER:
+ d->length = ri->u.buffer.length;
+ d->data = (unsigned char *) ri->u.buffer.data;
+ break;
+ }
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ return first;
+}
+
+/* Convert a stringtable resource to binary. */
+
+static struct bindata *
+res_to_bin_stringtable (st, big_endian)
+ const struct stringtable *st;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ int i;
+
+ first = NULL;
+ pp = &first;
+
+ for (i = 0; i < 16; i++)
+ {
+ int slen, j;
+ struct bindata *d;
+ unichar *s;
+
+ slen = st->strings[i].length;
+ s = st->strings[i].string;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 2 + slen * 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ put_16 (big_endian, slen, d->data);
+
+ for (j = 0; j < slen; j++)
+ put_16 (big_endian, s[j], d->data + 2 + j * 2);
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ return first;
+}
+
+/* Convert an ASCII string to a unicode binary string. This always
+ returns exactly one bindata structure. */
+
+static struct bindata *
+string_to_unicode_bin (s, big_endian)
+ const char *s;
+ int big_endian;
+{
+ size_t len, i;
+ struct bindata *d;
+
+ len = strlen (s);
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = len * 2 + 2;
+ d->data = (unsigned char *) reswr_alloc (d->length);
+
+ for (i = 0; i < len; i++)
+ put_16 (big_endian, s[i], d->data + i * 2);
+ put_16 (big_endian, 0, d->data + i * 2);
+
+ d->next = NULL;
+
+ return d;
+}
+
+/* Convert a versioninfo resource to binary. */
+
+static struct bindata *
+res_to_bin_versioninfo (versioninfo, big_endian)
+ const struct versioninfo *versioninfo;
+ int big_endian;
+{
+ struct bindata *first, **pp;
+ unsigned long length;
+ struct ver_info *vi;
+
+ first = (struct bindata *) reswr_alloc (sizeof *first);
+ first->length = 6;
+ first->data = (unsigned char *) reswr_alloc (6);
+
+ length = 6;
+
+ if (versioninfo->fixed == NULL)
+ put_16 (big_endian, 0, first->data + 2);
+ else
+ put_16 (big_endian, 52, first->data + 2);
+
+ put_16 (big_endian, 0, first->data + 4);
+
+ pp = &first->next;
+
+ *pp = string_to_unicode_bin ("VS_VERSION_INFO", big_endian);
+ length += (*pp)->length;
+ pp = &(*pp)->next;
+
+ dword_align_bin (&pp, &length);
+
+ if (versioninfo->fixed != NULL)
+ {
+ const struct fixed_versioninfo *fi;
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = 52;
+ d->data = (unsigned char *) reswr_alloc (52);
+
+ length += 52;
+
+ fi = versioninfo->fixed;
+
+ put_32 (big_endian, 0xfeef04bd, d->data);
+ put_32 (big_endian, 0x10000, d->data + 4);
+ put_32 (big_endian, fi->file_version_ms, d->data + 8);
+ put_32 (big_endian, fi->file_version_ls, d->data + 12);
+ put_32 (big_endian, fi->product_version_ms, d->data + 16);
+ put_32 (big_endian, fi->product_version_ls, d->data + 20);
+ put_32 (big_endian, fi->file_flags_mask, d->data + 24);
+ put_32 (big_endian, fi->file_flags, d->data + 28);
+ put_32 (big_endian, fi->file_os, d->data + 32);
+ put_32 (big_endian, fi->file_type, d->data + 36);
+ put_32 (big_endian, fi->file_subtype, d->data + 40);
+ put_32 (big_endian, fi->file_date_ms, d->data + 44);
+ put_32 (big_endian, fi->file_date_ls, d->data + 48);
+
+ d->next = NULL;
+ *pp = d;
+ pp = &d->next;
+ }
+
+ for (vi = versioninfo->var; vi != NULL; vi = vi->next)
+ {
+ struct bindata *vid;
+ unsigned long vilen;
+
+ dword_align_bin (&pp, &length);
+
+ vid = (struct bindata *) reswr_alloc (sizeof *vid);
+ vid->length = 6;
+ vid->data = (unsigned char *) reswr_alloc (6);
+
+ length += 6;
+ vilen = 6;
+
+ put_16 (big_endian, 0, vid->data + 2);
+ put_16 (big_endian, 0, vid->data + 4);
+
+ *pp = vid;
+ pp = &vid->next;
+
+ switch (vi->type)
+ {
+ default:
+ abort ();
+
+ case VERINFO_STRING:
+ {
+ unsigned long hold, vslen;
+ struct bindata *vsd;
+ const struct ver_stringinfo *vs;
+
+ *pp = string_to_unicode_bin ("StringFileInfo", big_endian);
+ length += (*pp)->length;
+ vilen += (*pp)->length;
+ pp = &(*pp)->next;
+
+ hold = length;
+ dword_align_bin (&pp, &length);
+ vilen += length - hold;
+
+ vsd = (struct bindata *) reswr_alloc (sizeof *vsd);
+ vsd->length = 6;
+ vsd->data = (unsigned char *) reswr_alloc (6);
+
+ length += 6;
+ vilen += 6;
+ vslen = 6;
+
+ put_16 (big_endian, 0, vsd->data + 2);
+ put_16 (big_endian, 0, vsd->data + 4);
+
+ *pp = vsd;
+ pp = &vsd->next;
+
+ *pp = unicode_to_bin (vi->u.string.language, big_endian);
+ length += (*pp)->length;
+ vilen += (*pp)->length;
+ vslen += (*pp)->length;
+ pp = &(*pp)->next;
+
+ for (vs = vi->u.string.strings; vs != NULL; vs = vs->next)
+ {
+ struct bindata *vssd;
+ unsigned long vsslen;
+
+ hold = length;
+ dword_align_bin (&pp, &length);
+ vilen += length - hold;
+ vslen += length - hold;
+
+ vssd = (struct bindata *) reswr_alloc (sizeof *vssd);
+ vssd->length = 6;
+ vssd->data = (unsigned char *) reswr_alloc (6);
+
+ length += 6;
+ vilen += 6;
+ vslen += 6;
+ vsslen = 6;
+
+ put_16 (big_endian, 1, vssd->data + 4);
+
+ *pp = vssd;
+ pp = &vssd->next;
+
+ *pp = unicode_to_bin (vs->key, big_endian);
+ length += (*pp)->length;
+ vilen += (*pp)->length;
+ vslen += (*pp)->length;
+ vsslen += (*pp)->length;
+ pp = &(*pp)->next;
+
+ hold = length;
+ dword_align_bin (&pp, &length);
+ vilen += length - hold;
+ vslen += length - hold;
+ vsslen += length - hold;
+
+ *pp = unicode_to_bin (vs->value, big_endian);
+ put_16 (big_endian, (*pp)->length / 2, vssd->data + 2);
+ length += (*pp)->length;
+ vilen += (*pp)->length;
+ vslen += (*pp)->length;
+ vsslen += (*pp)->length;
+ pp = &(*pp)->next;
+
+ put_16 (big_endian, vsslen, vssd->data);
+ }
+
+ put_16 (big_endian, vslen, vsd->data);
+
+ break;
+ }
+
+ case VERINFO_VAR:
+ {
+ unsigned long hold, vvlen, vvvlen;
+ struct bindata *vvd;
+ const struct ver_varinfo *vv;
+
+ *pp = string_to_unicode_bin ("VarFileInfo", big_endian);
+ length += (*pp)->length;
+ vilen += (*pp)->length;
+ pp = &(*pp)->next;
+
+ hold = length;
+ dword_align_bin (&pp, &length);
+ vilen += length - hold;
+
+ vvd = (struct bindata *) reswr_alloc (sizeof *vvd);
+ vvd->length = 6;
+ vvd->data = (unsigned char *) reswr_alloc (6);
+
+ length += 6;
+ vilen += 6;
+ vvlen = 6;
+
+ put_16 (big_endian, 0, vvd->data + 4);
+
+ *pp = vvd;
+ pp = &vvd->next;
+
+ *pp = unicode_to_bin (vi->u.var.key, big_endian);
+ length += (*pp)->length;
+ vilen += (*pp)->length;
+ vvlen += (*pp)->length;
+ pp = &(*pp)->next;
+
+ hold = length;
+ dword_align_bin (&pp, &length);
+ vilen += length - hold;
+ vvlen += length - hold;
+
+ vvvlen = 0;
+
+ for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
+ {
+ struct bindata *vvsd;
+
+ vvsd = (struct bindata *) reswr_alloc (sizeof *vvsd);
+ vvsd->length = 4;
+ vvsd->data = (unsigned char *) reswr_alloc (4);
+
+ length += 4;
+ vilen += 4;
+ vvlen += 4;
+ vvvlen += 4;
+
+ put_16 (big_endian, vv->language, vvsd->data);
+ put_16 (big_endian, vv->charset, vvsd->data + 2);
+
+ vvsd->next = NULL;
+ *pp = vvsd;
+ pp = &vvsd->next;
+ }
+
+ put_16 (big_endian, vvlen, vvd->data);
+ put_16 (big_endian, vvvlen, vvd->data + 2);
+
+ break;
+ }
+ }
+
+ put_16 (big_endian, vilen, vid->data);
+ }
+
+ put_16 (big_endian, length, first->data);
+
+ return first;
+}
+
+/* Convert a generic resource to binary. */
+
+static struct bindata *
+res_to_bin_generic (length, data)
+ unsigned long length;
+ const unsigned char *data;
+{
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+ d->length = length;
+ d->data = (unsigned char *) data;
+
+ d->next = NULL;
+
+ return d;
+}
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
new file mode 100644
index 00000000000..9a028c73053
--- /dev/null
+++ b/binutils/rescoff.c
@@ -0,0 +1,776 @@
+/* rescoff.c -- read and write resources in Windows COFF files.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains function that read and write Windows resources
+ in COFF files. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windres.h"
+
+#include <assert.h>
+
+/* In order to use the address of a resource data entry, we need to
+ get the image base of the file. Right now we extract it from
+ internal BFD information. FIXME. */
+
+#include "coff/internal.h"
+#include "libcoff.h"
+
+/* Information we extract from the file. */
+
+struct coff_file_info
+{
+ /* File name. */
+ const char *filename;
+ /* Data read from the file. */
+ const bfd_byte *data;
+ /* End of data read from file. */
+ const bfd_byte *data_end;
+ /* Address of the resource section minus the image base of the file. */
+ bfd_vma secaddr;
+ /* Non-zero if the file is big endian. */
+ int big_endian;
+};
+
+/* A resource directory table in a COFF file. */
+
+struct extern_res_directory
+{
+ /* Characteristics. */
+ bfd_byte characteristics[4];
+ /* Time stamp. */
+ bfd_byte time[4];
+ /* Major version number. */
+ bfd_byte major[2];
+ /* Minor version number. */
+ bfd_byte minor[2];
+ /* Number of named directory entries. */
+ bfd_byte name_count[2];
+ /* Number of directory entries with IDs. */
+ bfd_byte id_count[2];
+};
+
+/* A resource directory entry in a COFF file. */
+
+struct extern_res_entry
+{
+ /* Name or ID. */
+ bfd_byte name[4];
+ /* Address of resource entry or subdirectory. */
+ bfd_byte rva[4];
+};
+
+/* A resource data entry in a COFF file. */
+
+struct extern_res_data
+{
+ /* Address of resource data. This is apparently a file relative
+ address, rather than a section offset. */
+ bfd_byte rva[4];
+ /* Size of resource data. */
+ bfd_byte size[4];
+ /* Code page. */
+ bfd_byte codepage[4];
+ /* Reserved. */
+ bfd_byte reserved[4];
+};
+
+/* Macros to swap in values. */
+
+#define getfi_16(fi, s) ((fi)->big_endian ? bfd_getb16 (s) : bfd_getl16 (s))
+#define getfi_32(fi, s) ((fi)->big_endian ? bfd_getb32 (s) : bfd_getl32 (s))
+
+/* Local functions. */
+
+static void overrun PARAMS ((const struct coff_file_info *, const char *));
+static struct res_directory *read_coff_res_dir
+ PARAMS ((const bfd_byte *, const struct coff_file_info *,
+ const struct res_id *, int));
+static struct res_resource *read_coff_data_entry
+ PARAMS ((const bfd_byte *, const struct coff_file_info *,
+ const struct res_id *));
+
+/* Read the resources in a COFF file. */
+
+struct res_directory *
+read_coff_rsrc (filename, target)
+ const char *filename;
+ const char *target;
+{
+ bfd *abfd;
+ char **matching;
+ asection *sec;
+ bfd_size_type size;
+ bfd_byte *data;
+ struct coff_file_info finfo;
+
+ if (filename == NULL)
+ fatal (_("filename required for COFF input"));
+
+ abfd = bfd_openr (filename, target);
+ if (abfd == NULL)
+ bfd_fatal (filename);
+
+ if (! bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ list_matching_formats (matching);
+ xexit (1);
+ }
+
+ sec = bfd_get_section_by_name (abfd, ".rsrc");
+ if (sec == NULL)
+ {
+ fprintf (stderr, _("%s: %s: no resource section\n"), program_name,
+ filename);
+ xexit (1);
+ }
+
+ size = bfd_section_size (abfd, sec);
+ data = (bfd_byte *) res_alloc (size);
+
+ if (! bfd_get_section_contents (abfd, sec, data, 0, size))
+ bfd_fatal (_("can't read resource section"));
+
+ finfo.filename = filename;
+ finfo.data = data;
+ finfo.data_end = data + size;
+ finfo.secaddr = (bfd_get_section_vma (abfd, sec)
+ - pe_data (abfd)->pe_opthdr.ImageBase);
+ finfo.big_endian = bfd_big_endian (abfd);
+
+ bfd_close (abfd);
+
+ /* Now just read in the top level resource directory. Note that we
+ don't free data, since we create resource entries that point into
+ it. If we ever want to free up the resource information we read,
+ this will have to be cleaned up. */
+
+ return read_coff_res_dir (data, &finfo, (const struct res_id *) NULL, 0);
+}
+
+/* Give an error if we are out of bounds. */
+
+static void
+overrun (finfo, msg)
+ const struct coff_file_info *finfo;
+ const char *msg;
+{
+ fatal (_("%s: %s: address out of bounds"), finfo->filename, msg);
+}
+
+/* Read a resource directory. */
+
+static struct res_directory *
+read_coff_res_dir (data, finfo, type, level)
+ const bfd_byte *data;
+ const struct coff_file_info *finfo;
+ const struct res_id *type;
+ int level;
+{
+ const struct extern_res_directory *erd;
+ struct res_directory *rd;
+ int name_count, id_count, i;
+ struct res_entry **pp;
+ const struct extern_res_entry *ere;
+
+ if ((size_t) (finfo->data_end - data) < sizeof (struct extern_res_directory))
+ overrun (finfo, _("directory"));
+
+ erd = (const struct extern_res_directory *) data;
+
+ rd = (struct res_directory *) res_alloc (sizeof *rd);
+ rd->characteristics = getfi_32 (finfo, erd->characteristics);
+ rd->time = getfi_32 (finfo, erd->time);
+ rd->major = getfi_16 (finfo, erd->major);
+ rd->minor = getfi_16 (finfo, erd->minor);
+ rd->entries = NULL;
+
+ name_count = getfi_16 (finfo, erd->name_count);
+ id_count = getfi_16 (finfo, erd->id_count);
+
+ pp = &rd->entries;
+
+ /* The resource directory entries immediately follow the directory
+ table. */
+ ere = (const struct extern_res_entry *) (erd + 1);
+
+ for (i = 0; i < name_count; i++, ere++)
+ {
+ unsigned long name, rva;
+ struct res_entry *re;
+ const bfd_byte *ers;
+ int length, j;
+
+ if ((const bfd_byte *) ere >= finfo->data_end)
+ overrun (finfo, _("named directory entry"));
+
+ name = getfi_32 (finfo, ere->name);
+ rva = getfi_32 (finfo, ere->rva);
+
+ /* For some reason the high bit in NAME is set. */
+ name &=~ 0x80000000;
+
+ if (name > (size_t) (finfo->data_end - finfo->data))
+ overrun (finfo, _("directory entry name"));
+
+ ers = finfo->data + name;
+
+ re = (struct res_entry *) res_alloc (sizeof *re);
+ re->next = NULL;
+ re->id.named = 1;
+ length = getfi_16 (finfo, ers);
+ re->id.u.n.length = length;
+ re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar));
+ for (j = 0; j < length; j++)
+ re->id.u.n.name[j] = getfi_16 (finfo, ers + j * 2 + 2);
+
+ if (level == 0)
+ type = &re->id;
+
+ if ((rva & 0x80000000) != 0)
+ {
+ rva &=~ 0x80000000;
+ if (rva >= (size_t) (finfo->data_end - finfo->data))
+ overrun (finfo, _("named subdirectory"));
+ re->subdir = 1;
+ re->u.dir = read_coff_res_dir (finfo->data + rva, finfo, type,
+ level + 1);
+ }
+ else
+ {
+ if (rva >= (size_t) (finfo->data_end - finfo->data))
+ overrun (finfo, _("named resource"));
+ re->subdir = 0;
+ re->u.res = read_coff_data_entry (finfo->data + rva, finfo, type);
+ }
+
+ *pp = re;
+ pp = &re->next;
+ }
+
+ for (i = 0; i < id_count; i++, ere++)
+ {
+ unsigned long name, rva;
+ struct res_entry *re;
+
+ if ((const bfd_byte *) ere >= finfo->data_end)
+ overrun (finfo, _("ID directory entry"));
+
+ name = getfi_32 (finfo, ere->name);
+ rva = getfi_32 (finfo, ere->rva);
+
+ re = (struct res_entry *) res_alloc (sizeof *re);
+ re->next = NULL;
+ re->id.named = 0;
+ re->id.u.id = name;
+
+ if (level == 0)
+ type = &re->id;
+
+ if ((rva & 0x80000000) != 0)
+ {
+ rva &=~ 0x80000000;
+ if (rva >= (size_t) (finfo->data_end - finfo->data))
+ overrun (finfo, _("ID subdirectory"));
+ re->subdir = 1;
+ re->u.dir = read_coff_res_dir (finfo->data + rva, finfo, type,
+ level + 1);
+ }
+ else
+ {
+ if (rva >= (size_t) (finfo->data_end - finfo->data))
+ overrun (finfo, _("ID resource"));
+ re->subdir = 0;
+ re->u.res = read_coff_data_entry (finfo->data + rva, finfo, type);
+ }
+
+ *pp = re;
+ pp = &re->next;
+ }
+
+ return rd;
+}
+
+/* Read a resource data entry. */
+
+static struct res_resource *
+read_coff_data_entry (data, finfo, type)
+ const bfd_byte *data;
+ const struct coff_file_info *finfo;
+ const struct res_id *type;
+{
+ const struct extern_res_data *erd;
+ struct res_resource *r;
+ unsigned long size, rva;
+ const bfd_byte *resdata;
+
+ if (type == NULL)
+ fatal (_("resource type unknown"));
+
+ if ((size_t) (finfo->data_end - data) < sizeof (struct extern_res_data))
+ overrun (finfo, _("data entry"));
+
+ erd = (const struct extern_res_data *) data;
+
+ size = getfi_32 (finfo, erd->size);
+ rva = getfi_32 (finfo, erd->rva);
+ if (rva < finfo->secaddr
+ || rva - finfo->secaddr >= (size_t) (finfo->data_end - finfo->data))
+ overrun (finfo, _("resource data"));
+
+ resdata = finfo->data + (rva - finfo->secaddr);
+
+ if (size > (size_t) (finfo->data_end - resdata))
+ overrun (finfo, _("resource data size"));
+
+ r = bin_to_res (*type, resdata, size, finfo->big_endian);
+
+ memset (&r->res_info, 0, sizeof (struct res_res_info));
+ r->coff_info.codepage = getfi_32 (finfo, erd->codepage);
+ r->coff_info.reserved = getfi_32 (finfo, erd->reserved);
+
+ return r;
+}
+
+/* This structure is used to build a list of bindata structures. */
+
+struct bindata_build
+{
+ /* The data. */
+ struct bindata *d;
+ /* The last structure we have added to the list. */
+ struct bindata *last;
+ /* The size of the list as a whole. */
+ unsigned long length;
+};
+
+/* This structure keeps track of information as we build the directory
+ tree. */
+
+struct coff_write_info
+{
+ /* These fields are based on the BFD. */
+ /* The BFD itself. */
+ bfd *abfd;
+ /* Non-zero if the file is big endian. */
+ int big_endian;
+ /* Pointer to section symbol used to build RVA relocs. */
+ asymbol **sympp;
+
+ /* These fields are computed initially, and then not changed. */
+ /* Length of directory tables and entries. */
+ unsigned long dirsize;
+ /* Length of directory entry strings. */
+ unsigned long dirstrsize;
+ /* Length of resource data entries. */
+ unsigned long dataentsize;
+
+ /* These fields are updated as we add data. */
+ /* Directory tables and entries. */
+ struct bindata_build dirs;
+ /* Directory entry strings. */
+ struct bindata_build dirstrs;
+ /* Resource data entries. */
+ struct bindata_build dataents;
+ /* Actual resource data. */
+ struct bindata_build resources;
+ /* Relocations. */
+ arelent **relocs;
+ /* Number of relocations. */
+ unsigned int reloc_count;
+};
+
+/* Macros to swap out values. */
+
+#define putcwi_16(cwi, v, s) \
+ ((cwi->big_endian) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s)))
+#define putcwi_32(cwi, v, s) \
+ ((cwi->big_endian) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s)))
+
+static void coff_bin_sizes
+ PARAMS ((const struct res_directory *, struct coff_write_info *));
+static unsigned char *coff_alloc PARAMS ((struct bindata_build *, size_t));
+static void coff_to_bin
+ PARAMS ((const struct res_directory *, struct coff_write_info *));
+static void coff_res_to_bin
+ PARAMS ((const struct res_resource *, struct coff_write_info *));
+
+/* Write resources to a COFF file. RESOURCES should already be
+ sorted.
+
+ Right now we always create a new file. Someday we should also
+ offer the ability to merge resources into an existing file. This
+ would require doing the basic work of objcopy, just modifying or
+ adding the .rsrc section. */
+
+void
+write_coff_file (filename, target, resources)
+ const char *filename;
+ const char *target;
+ const struct res_directory *resources;
+{
+ bfd *abfd;
+ asection *sec;
+ struct coff_write_info cwi;
+ struct bindata *d;
+ unsigned long length, offset;
+
+ if (filename == NULL)
+ fatal (_("filename required for COFF output"));
+
+ abfd = bfd_openw (filename, target);
+ if (abfd == NULL)
+ bfd_fatal (filename);
+
+ if (! bfd_set_format (abfd, bfd_object))
+ bfd_fatal ("bfd_set_format");
+
+ /* FIXME: This is obviously i386 specific. */
+ if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0))
+ bfd_fatal ("bfd_set_arch_mach");
+
+ if (! bfd_set_file_flags (abfd, HAS_SYMS | HAS_RELOC))
+ bfd_fatal ("bfd_set_file_flags");
+
+ sec = bfd_make_section (abfd, ".rsrc");
+ if (sec == NULL)
+ bfd_fatal ("bfd_make_section");
+
+ if (! bfd_set_section_flags (abfd, sec,
+ (SEC_HAS_CONTENTS | SEC_ALLOC
+ | SEC_LOAD | SEC_DATA)))
+ bfd_fatal ("bfd_set_section_flags");
+
+ if (! bfd_set_symtab (abfd, sec->symbol_ptr_ptr, 1))
+ bfd_fatal ("bfd_set_symtab");
+
+ /* Requiring this is probably a bug in BFD. */
+ sec->output_section = sec;
+
+ /* The order of data in the .rsrc section is
+ resource directory tables and entries
+ resource directory strings
+ resource data entries
+ actual resource data
+
+ We build these different types of data in different lists. */
+
+ cwi.abfd = abfd;
+ cwi.big_endian = bfd_big_endian (abfd);
+ cwi.sympp = sec->symbol_ptr_ptr;
+ cwi.dirsize = 0;
+ cwi.dirstrsize = 0;
+ cwi.dataentsize = 0;
+ cwi.dirs.d = NULL;
+ cwi.dirs.last = NULL;
+ cwi.dirs.length = 0;
+ cwi.dirstrs.d = NULL;
+ cwi.dirstrs.last = NULL;
+ cwi.dirstrs.length = 0;
+ cwi.dataents.d = NULL;
+ cwi.dataents.last = NULL;
+ cwi.dataents.length = 0;
+ cwi.resources.d = NULL;
+ cwi.resources.last = NULL;
+ cwi.resources.length = 0;
+ cwi.relocs = NULL;
+ cwi.reloc_count = 0;
+
+ /* Work out the sizes of the resource directory entries, so that we
+ know the various offsets we will need. */
+ coff_bin_sizes (resources, &cwi);
+
+ /* Force the directory strings to be 32 bit aligned. Every other
+ structure is 32 bit aligned anyhow. */
+ cwi.dirstrsize = (cwi.dirstrsize + 3) &~ 3;
+
+ /* Actually convert the resources to binary. */
+ coff_to_bin (resources, &cwi);
+
+ /* Add another 2 bytes to the directory strings if needed for
+ alignment. */
+ if ((cwi.dirstrs.length & 3) != 0)
+ {
+ unsigned char *ex;
+
+ ex = coff_alloc (&cwi.dirstrs, 2);
+ ex[0] = 0;
+ ex[1] = 0;
+ }
+
+ /* Make sure that the data we built came out to the same size as we
+ calculated initially. */
+ assert (cwi.dirs.length == cwi.dirsize);
+ assert (cwi.dirstrs.length == cwi.dirstrsize);
+ assert (cwi.dataents.length == cwi.dataentsize);
+
+ length = (cwi.dirsize
+ + cwi.dirstrsize
+ + cwi.dataentsize
+ + cwi.resources.length);
+
+ if (! bfd_set_section_size (abfd, sec, length))
+ bfd_fatal ("bfd_set_section_size");
+
+ bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);
+
+ offset = 0;
+ for (d = cwi.dirs.d; d != NULL; d = d->next)
+ {
+ if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
+ bfd_fatal ("bfd_set_section_contents");
+ offset += d->length;
+ }
+ for (d = cwi.dirstrs.d; d != NULL; d = d->next)
+ {
+ if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
+ bfd_fatal ("bfd_set_section_contents");
+ offset += d->length;
+ }
+ for (d = cwi.dataents.d; d != NULL; d = d->next)
+ {
+ if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
+ bfd_fatal ("bfd_set_section_contents");
+ offset += d->length;
+ }
+ for (d = cwi.resources.d; d != NULL; d = d->next)
+ {
+ if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
+ bfd_fatal ("bfd_set_section_contents");
+ offset += d->length;
+ }
+
+ assert (offset == length);
+
+ if (! bfd_close (abfd))
+ bfd_fatal ("bfd_close");
+
+ /* We allocated the relocs array using malloc. */
+ free (cwi.relocs);
+}
+
+/* Work out the sizes of the various fixed size resource directory
+ entries. This updates fields in CWI. */
+
+static void
+coff_bin_sizes (resdir, cwi)
+ const struct res_directory *resdir;
+ struct coff_write_info *cwi;
+{
+ const struct res_entry *re;
+
+ cwi->dirsize += sizeof (struct extern_res_directory);
+
+ for (re = resdir->entries; re != NULL; re = re->next)
+ {
+ cwi->dirsize += sizeof (struct extern_res_entry);
+
+ if (re->id.named)
+ cwi->dirstrsize += re->id.u.n.length * 2 + 2;
+
+ if (re->subdir)
+ coff_bin_sizes (re->u.dir, cwi);
+ else
+ cwi->dataentsize += sizeof (struct extern_res_data);
+ }
+}
+
+/* Allocate data for a particular list. */
+
+static unsigned char *
+coff_alloc (bb, size)
+ struct bindata_build *bb;
+ size_t size;
+{
+ struct bindata *d;
+
+ d = (struct bindata *) reswr_alloc (sizeof *d);
+
+ d->next = NULL;
+ d->data = (unsigned char *) reswr_alloc (size);
+ d->length = size;
+
+ if (bb->d == NULL)
+ bb->d = d;
+ else
+ bb->last->next = d;
+ bb->last = d;
+ bb->length += size;
+
+ return d->data;
+}
+
+/* Convert the resource directory RESDIR to binary. */
+
+static void
+coff_to_bin (resdir, cwi)
+ const struct res_directory *resdir;
+ struct coff_write_info *cwi;
+{
+ struct extern_res_directory *erd;
+ int ci, cn;
+ const struct res_entry *e;
+ struct extern_res_entry *ere;
+
+ /* Write out the directory table. */
+
+ erd = ((struct extern_res_directory *)
+ coff_alloc (&cwi->dirs, sizeof (*erd)));
+
+ putcwi_32 (cwi, resdir->characteristics, erd->characteristics);
+ putcwi_32 (cwi, resdir->time, erd->time);
+ putcwi_16 (cwi, resdir->major, erd->major);
+ putcwi_16 (cwi, resdir->minor, erd->minor);
+
+ ci = 0;
+ cn = 0;
+ for (e = resdir->entries; e != NULL; e = e->next)
+ {
+ if (e->id.named)
+ ++cn;
+ else
+ ++ci;
+ }
+
+ putcwi_16 (cwi, cn, erd->name_count);
+ putcwi_16 (cwi, ci, erd->id_count);
+
+ /* Write out the data entries. Note that we allocate space for all
+ the entries before writing them out. That permits a recursive
+ call to work correctly when writing out subdirectories. */
+
+ ere = ((struct extern_res_entry *)
+ coff_alloc (&cwi->dirs, (ci + cn) * sizeof (*ere)));
+ for (e = resdir->entries; e != NULL; e = e->next, ere++)
+ {
+ if (! e->id.named)
+ putcwi_32 (cwi, e->id.u.id, ere->name);
+ else
+ {
+ unsigned char *str;
+ int i;
+
+ /* For some reason existing files seem to have the high bit
+ set on the address of the name, although that is not
+ documented. */
+ putcwi_32 (cwi,
+ 0x80000000 | (cwi->dirsize + cwi->dirstrs.length),
+ ere->name);
+
+ str = coff_alloc (&cwi->dirstrs, e->id.u.n.length * 2 + 2);
+ putcwi_16 (cwi, e->id.u.n.length, str);
+ for (i = 0; i < e->id.u.n.length; i++)
+ putcwi_16 (cwi, e->id.u.n.name[i], str + i * 2 + 2);
+ }
+
+ if (e->subdir)
+ {
+ putcwi_32 (cwi, 0x80000000 | cwi->dirs.length, ere->rva);
+ coff_to_bin (e->u.dir, cwi);
+ }
+ else
+ {
+ putcwi_32 (cwi,
+ cwi->dirsize + cwi->dirstrsize + cwi->dataents.length,
+ ere->rva);
+
+ coff_res_to_bin (e->u.res, cwi);
+ }
+ }
+}
+
+/* Convert the resource RES to binary. */
+
+static void
+coff_res_to_bin (res, cwi)
+ const struct res_resource *res;
+ struct coff_write_info *cwi;
+{
+ arelent *r;
+ struct extern_res_data *erd;
+ struct bindata *d;
+ unsigned long length;
+
+ /* For some reason, although every other address is a section
+ offset, the address of the resource data itself is an RVA. That
+ means that we need to generate a relocation for it. We allocate
+ the relocs array using malloc so that we can use realloc. FIXME:
+ This relocation handling is correct for the i386, but probably
+ not for any other target. */
+
+ r = (arelent *) reswr_alloc (sizeof (arelent));
+ r->sym_ptr_ptr = cwi->sympp;
+ r->address = cwi->dirsize + cwi->dirstrsize + cwi->dataents.length;
+ r->addend = 0;
+ r->howto = bfd_reloc_type_lookup (cwi->abfd, BFD_RELOC_RVA);
+ if (r->howto == NULL)
+ bfd_fatal (_("can't get BFD_RELOC_RVA relocation type"));
+
+ cwi->relocs = xrealloc (cwi->relocs,
+ (cwi->reloc_count + 2) * sizeof (arelent *));
+ cwi->relocs[cwi->reloc_count] = r;
+ cwi->relocs[cwi->reloc_count + 1] = NULL;
+ ++cwi->reloc_count;
+
+ erd = (struct extern_res_data *) coff_alloc (&cwi->dataents, sizeof (*erd));
+
+ putcwi_32 (cwi,
+ (cwi->dirsize
+ + cwi->dirstrsize
+ + cwi->dataentsize
+ + cwi->resources.length),
+ erd->rva);
+ putcwi_32 (cwi, res->coff_info.codepage, erd->codepage);
+ putcwi_32 (cwi, res->coff_info.reserved, erd->reserved);
+
+ d = res_to_bin (res, cwi->big_endian);
+
+ if (cwi->resources.d == NULL)
+ cwi->resources.d = d;
+ else
+ cwi->resources.last->next = d;
+
+ length = 0;
+ for (; d->next != NULL; d = d->next)
+ length += d->length;
+ length += d->length;
+ cwi->resources.last = d;
+ cwi->resources.length += length;
+
+ putcwi_32 (cwi, length, erd->size);
+
+ /* Force the next resource to have 32 bit alignment. */
+
+ if ((length & 3) != 0)
+ {
+ int add;
+ unsigned char *ex;
+
+ add = 4 - (length & 3);
+
+ ex = coff_alloc (&cwi->resources, add);
+ memset (ex, 0, add);
+ }
+}
diff --git a/binutils/resrc.c b/binutils/resrc.c
new file mode 100644
index 00000000000..9ba3c117807
--- /dev/null
+++ b/binutils/resrc.c
@@ -0,0 +1,2265 @@
+/* resrc.c -- read and write Windows rc files.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains functions that read and write Windows rc files.
+ These are text files that represent resources. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windres.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#if defined (_WIN32) && ! defined (__CYGWIN32__)
+#define popen _popen
+#define pclose _pclose
+#endif
+
+/* The default preprocessor. */
+
+#define DEFAULT_PREPROCESSOR "gcc -E -xc-header -DRC_INVOKED"
+
+/* We read the directory entries in a cursor or icon file into
+ instances of this structure. */
+
+struct icondir
+{
+ /* Width of image. */
+ unsigned char width;
+ /* Height of image. */
+ unsigned char height;
+ /* Number of colors in image. */
+ unsigned char colorcount;
+ union
+ {
+ struct
+ {
+ /* Color planes. */
+ unsigned short planes;
+ /* Bits per pixel. */
+ unsigned short bits;
+ } icon;
+ struct
+ {
+ /* X coordinate of hotspot. */
+ unsigned short xhotspot;
+ /* Y coordinate of hotspot. */
+ unsigned short yhotspot;
+ } cursor;
+ } u;
+ /* Bytes in image. */
+ unsigned long bytes;
+ /* File offset of image. */
+ unsigned long offset;
+};
+
+/* The name of the rc file we are reading. */
+
+char *rc_filename;
+
+/* The line number in the rc file. */
+
+int rc_lineno;
+
+/* The pipe we are reading from, so that we can close it if we exit. */
+
+static FILE *cpp_pipe;
+
+/* As we read the rc file, we attach information to this structure. */
+
+static struct res_directory *resources;
+
+/* The number of cursor resources we have written out. */
+
+static int cursors;
+
+/* The number of font resources we have written out. */
+
+static int fonts;
+
+/* Font directory information. */
+
+struct fontdir *fontdirs;
+
+/* Resource info to use for fontdirs. */
+
+struct res_res_info fontdirs_resinfo;
+
+/* The number of icon resources we have written out. */
+
+static int icons;
+
+/* Local functions. */
+
+static void close_pipe PARAMS ((void));
+static void unexpected_eof PARAMS ((const char *));
+static int get_word PARAMS ((FILE *, const char *));
+static unsigned long get_long PARAMS ((FILE *, const char *));
+static void get_data
+ PARAMS ((FILE *, unsigned char *, unsigned long, const char *));
+static void define_fontdirs PARAMS ((void));
+
+/* Read an rc file. */
+
+struct res_directory *
+read_rc_file (filename, preprocessor, preprocargs, language)
+ const char *filename;
+ const char *preprocessor;
+ const char *preprocargs;
+ int language;
+{
+ char *cmd;
+
+ if (preprocessor == NULL)
+ preprocessor = DEFAULT_PREPROCESSOR;
+
+ if (preprocargs == NULL)
+ preprocargs = "";
+ if (filename == NULL)
+ filename = "-";
+
+ cmd = xmalloc (strlen (preprocessor)
+ + strlen (preprocargs)
+ + strlen (filename)
+ + 10);
+ sprintf (cmd, "%s %s %s", preprocessor, preprocargs, filename);
+
+ cpp_pipe = popen (cmd, FOPEN_RT);
+ if (cpp_pipe == NULL)
+ fatal (_("can't popen `%s': %s"), cmd, strerror (errno));
+ free (cmd);
+
+ xatexit (close_pipe);
+
+ rc_filename = xstrdup (filename);
+ rc_lineno = 1;
+ if (language != -1)
+ rcparse_set_language (language);
+ yyin = cpp_pipe;
+ yyparse ();
+
+ if (pclose (cpp_pipe) != 0)
+ fprintf (stderr, _("%s: warning: preprocessor failed\n"), program_name);
+ cpp_pipe = NULL;
+
+ if (fontdirs != NULL)
+ define_fontdirs ();
+
+ free (rc_filename);
+ rc_filename = NULL;
+
+ return resources;
+}
+
+/* Close the pipe if it is open. This is called via xatexit. */
+
+void
+close_pipe ()
+{
+ if (cpp_pipe != NULL)
+ pclose (cpp_pipe);
+}
+
+/* Report an error while reading an rc file. */
+
+void
+yyerror (msg)
+ const char *msg;
+{
+ fatal ("%s:%d: %s", rc_filename, rc_lineno, msg);
+}
+
+/* Issue a warning while reading an rc file. */
+
+void
+rcparse_warning (msg)
+ const char *msg;
+{
+ fprintf (stderr, "%s:%d: %s\n", rc_filename, rc_lineno, msg);
+}
+
+/* Die if we get an unexpected end of file. */
+
+static void
+unexpected_eof (msg)
+ const char *msg;
+{
+ fatal (_("%s: unexpected EOF"), msg);
+}
+
+/* Read a 16 bit word from a file. The data is assumed to be little
+ endian. */
+
+static int
+get_word (e, msg)
+ FILE *e;
+ const char *msg;
+{
+ int b1, b2;
+
+ b1 = getc (e);
+ b2 = getc (e);
+ if (feof (e))
+ unexpected_eof (msg);
+ return ((b2 & 0xff) << 8) | (b1 & 0xff);
+}
+
+/* Read a 32 bit word from a file. The data is assumed to be little
+ endian. */
+
+static unsigned long
+get_long (e, msg)
+ FILE *e;
+ const char *msg;
+{
+ int b1, b2, b3, b4;
+
+ b1 = getc (e);
+ b2 = getc (e);
+ b3 = getc (e);
+ b4 = getc (e);
+ if (feof (e))
+ unexpected_eof (msg);
+ return (((((((b4 & 0xff) << 8)
+ | (b3 & 0xff)) << 8)
+ | (b2 & 0xff)) << 8)
+ | (b1 & 0xff));
+}
+
+/* Read data from a file. This is a wrapper to do error checking. */
+
+static void
+get_data (e, p, c, msg)
+ FILE *e;
+ unsigned char *p;
+ unsigned long c;
+ const char *msg;
+{
+ unsigned long got;
+
+ got = fread (p, 1, c, e);
+ if (got == c)
+ return;
+
+ fatal (_("%s: read of %lu returned %lu"), msg, c, got);
+}
+
+/* Define an accelerator resource. */
+
+void
+define_accelerator (id, resinfo, data)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ struct accelerator *data;
+{
+ struct res_resource *r;
+
+ r = define_standard_resource (&resources, RT_ACCELERATOR, id,
+ resinfo->language, 0);
+ r->type = RES_TYPE_ACCELERATOR;
+ r->u.acc = data;
+ r->res_info = *resinfo;
+}
+
+/* Define a bitmap resource. Bitmap data is stored in a file. The
+ first 14 bytes of the file are a standard header, which is not
+ included in the resource data. */
+
+#define BITMAP_SKIP (14)
+
+void
+define_bitmap (id, resinfo, filename)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ const char *filename;
+{
+ FILE *e;
+ char *real_filename;
+ struct stat s;
+ unsigned char *data;
+ int i;
+ struct res_resource *r;
+
+ e = open_file_search (filename, FOPEN_RB, "bitmap file", &real_filename);
+
+ if (stat (real_filename, &s) < 0)
+ fatal (_("stat failed on bitmap file `%s': %s"), real_filename,
+ strerror (errno));
+
+ data = (unsigned char *) res_alloc (s.st_size - BITMAP_SKIP);
+
+ for (i = 0; i < BITMAP_SKIP; i++)
+ getc (e);
+
+ get_data (e, data, s.st_size - BITMAP_SKIP, real_filename);
+
+ fclose (e);
+ free (real_filename);
+
+ r = define_standard_resource (&resources, RT_BITMAP, id,
+ resinfo->language, 0);
+
+ r->type = RES_TYPE_BITMAP;
+ r->u.data.length = s.st_size - BITMAP_SKIP;
+ r->u.data.data = data;
+ r->res_info = *resinfo;
+}
+
+/* Define a cursor resource. A cursor file may contain a set of
+ bitmaps, each representing the same cursor at various different
+ resolutions. They each get written out with a different ID. The
+ real cursor resource is then a group resource which can be used to
+ select one of the actual cursors. */
+
+void
+define_cursor (id, resinfo, filename)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ const char *filename;
+{
+ FILE *e;
+ char *real_filename;
+ int type, count, i;
+ struct icondir *icondirs;
+ int first_cursor;
+ struct res_resource *r;
+ struct group_cursor *first, **pp;
+
+ e = open_file_search (filename, FOPEN_RB, "cursor file", &real_filename);
+
+ /* A cursor file is basically an icon file. The start of the file
+ is a three word structure. The first word is ignored. The
+ second word is the type of data. The third word is the number of
+ entries. */
+
+ get_word (e, real_filename);
+ type = get_word (e, real_filename);
+ count = get_word (e, real_filename);
+ if (type != 2)
+ fatal (_("cursor file `%s' does not contain cursor data"), real_filename);
+
+ /* Read in the icon directory entries. */
+
+ icondirs = (struct icondir *) xmalloc (count * sizeof *icondirs);
+
+ for (i = 0; i < count; i++)
+ {
+ icondirs[i].width = getc (e);
+ icondirs[i].height = getc (e);
+ icondirs[i].colorcount = getc (e);
+ getc (e);
+ icondirs[i].u.cursor.xhotspot = get_word (e, real_filename);
+ icondirs[i].u.cursor.yhotspot = get_word (e, real_filename);
+ icondirs[i].bytes = get_long (e, real_filename);
+ icondirs[i].offset = get_long (e, real_filename);
+
+ if (feof (e))
+ unexpected_eof (real_filename);
+ }
+
+ /* Define each cursor as a unique resource. */
+
+ first_cursor = cursors;
+
+ for (i = 0; i < count; i++)
+ {
+ unsigned char *data;
+ struct res_id name;
+ struct cursor *c;
+
+ if (fseek (e, icondirs[i].offset, SEEK_SET) != 0)
+ fatal (_("%s: fseek to %lu failed: %s"), real_filename,
+ icondirs[i].offset, strerror (errno));
+
+ data = (unsigned char *) res_alloc (icondirs[i].bytes);
+
+ get_data (e, data, icondirs[i].bytes, real_filename);
+
+ c = (struct cursor *) res_alloc (sizeof *c);
+ c->xhotspot = icondirs[i].u.cursor.xhotspot;
+ c->yhotspot = icondirs[i].u.cursor.yhotspot;
+ c->length = icondirs[i].bytes;
+ c->data = data;
+
+ ++cursors;
+
+ name.named = 0;
+ name.u.id = cursors;
+
+ r = define_standard_resource (&resources, RT_CURSOR, name,
+ resinfo->language, 0);
+ r->type = RES_TYPE_CURSOR;
+ r->u.cursor = c;
+ r->res_info = *resinfo;
+ }
+
+ fclose (e);
+ free (real_filename);
+
+ /* Define a cursor group resource. */
+
+ first = NULL;
+ pp = &first;
+ for (i = 0; i < count; i++)
+ {
+ struct group_cursor *cg;
+
+ cg = (struct group_cursor *) res_alloc (sizeof *cg);
+ cg->next = NULL;
+ cg->width = icondirs[i].width;
+ cg->height = 2 * icondirs[i].height;
+
+ /* FIXME: What should these be set to? */
+ cg->planes = 1;
+ cg->bits = 1;
+
+ cg->bytes = icondirs[i].bytes + 4;
+ cg->index = first_cursor + i + 1;
+
+ *pp = cg;
+ pp = &(*pp)->next;
+ }
+
+ free (icondirs);
+
+ r = define_standard_resource (&resources, RT_GROUP_CURSOR, id,
+ resinfo->language, 0);
+ r->type = RES_TYPE_GROUP_CURSOR;
+ r->u.group_cursor = first;
+ r->res_info = *resinfo;
+}
+
+/* Define a dialog resource. */
+
+void
+define_dialog (id, resinfo, dialog)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ const struct dialog *dialog;
+{
+ struct dialog *copy;
+ struct res_resource *r;
+
+ copy = (struct dialog *) res_alloc (sizeof *copy);
+ *copy = *dialog;
+
+ r = define_standard_resource (&resources, RT_DIALOG, id,
+ resinfo->language, 0);
+ r->type = RES_TYPE_DIALOG;
+ r->u.dialog = copy;
+ r->res_info = *resinfo;
+}
+
+/* Define a dialog control. This does not define a resource, but
+ merely allocates and fills in a structure. */
+
+struct dialog_control *
+define_control (text, id, x, y, width, height, class, style, exstyle)
+ const char *text;
+ unsigned long id;
+ unsigned long x;
+ unsigned long y;
+ unsigned long width;
+ unsigned long height;
+ unsigned long class;
+ unsigned long style;
+ unsigned long exstyle;
+{
+ struct dialog_control *n;
+
+ n = (struct dialog_control *) res_alloc (sizeof *n);
+ n->next = NULL;
+ n->id = id;
+ n->style = style;
+ n->exstyle = exstyle;
+ n->x = x;
+ n->y = y;
+ n->width = width;
+ n->height = height;
+ n->class.named = 0;
+ n->class.u.id = class;
+ if (text != NULL)
+ res_string_to_id (&n->text, text);
+ else
+ {
+ n->text.named = 0;
+ n->text.u.id = 0;
+ }
+ n->data = NULL;
+ n->help = 0;
+
+ return n;
+}
+
+/* Define a font resource. */
+
+void
+define_font (id, resinfo, filename)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ const char *filename;
+{
+ FILE *e;
+ char *real_filename;
+ struct stat s;
+ unsigned char *data;
+ struct res_resource *r;
+ long offset;
+ long fontdatalength;
+ unsigned char *fontdata;
+ struct fontdir *fd;
+ const char *device, *face;
+ struct fontdir **pp;
+
+ e = open_file_search (filename, FOPEN_RB, "font file", &real_filename);
+
+ if (stat (real_filename, &s) < 0)
+ fatal (_("stat failed on bitmap file `%s': %s"), real_filename,
+ strerror (errno));
+
+ data = (unsigned char *) res_alloc (s.st_size);
+
+ get_data (e, data, s.st_size, real_filename);
+
+ fclose (e);
+ free (real_filename);
+
+ r = define_standard_resource (&resources, RT_FONT, id,
+ resinfo->language, 0);
+
+ r->type = RES_TYPE_FONT;
+ r->u.data.length = s.st_size;
+ r->u.data.data = data;
+ r->res_info = *resinfo;
+
+ /* For each font resource, we must add an entry in the FONTDIR
+ resource. The FONTDIR resource includes some strings in the font
+ file. To find them, we have to do some magic on the data we have
+ read. */
+
+ offset = ((((((data[47] << 8)
+ | data[46]) << 8)
+ | data[45]) << 8)
+ | data[44]);
+ if (offset > 0 && offset < s.st_size)
+ device = (char *) data + offset;
+ else
+ device = "";
+
+ offset = ((((((data[51] << 8)
+ | data[50]) << 8)
+ | data[49]) << 8)
+ | data[48]);
+ if (offset > 0 && offset < s.st_size)
+ face = (char *) data + offset;
+ else
+ face = "";
+
+ ++fonts;
+
+ fontdatalength = 58 + strlen (device) + strlen (face);
+ fontdata = (unsigned char *) res_alloc (fontdatalength);
+ memcpy (fontdata, data, 56);
+ strcpy ((char *) fontdata + 56, device);
+ strcpy ((char *) fontdata + 57 + strlen (device), face);
+
+ fd = (struct fontdir *) res_alloc (sizeof *fd);
+ fd->next = NULL;
+ fd->index = fonts;
+ fd->length = fontdatalength;
+ fd->data = fontdata;
+
+ for (pp = &fontdirs; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = fd;
+
+ /* For the single fontdirs resource, we always use the resource
+ information of the last font. I don't know what else to do. */
+ fontdirs_resinfo = *resinfo;
+}
+
+/* Define the fontdirs resource. This is called after the entire rc
+ file has been parsed, if any font resources were seen. */
+
+static void
+define_fontdirs ()
+{
+ struct res_resource *r;
+ struct res_id id;
+
+ id.named = 0;
+ id.u.id = 1;
+
+ r = define_standard_resource (&resources, RT_FONTDIR, id, 0x409, 0);
+
+ r->type = RES_TYPE_FONTDIR;
+ r->u.fontdir = fontdirs;
+ r->res_info = fontdirs_resinfo;
+}
+
+/* Define an icon resource. An icon file may contain a set of
+ bitmaps, each representing the same icon at various different
+ resolutions. They each get written out with a different ID. The
+ real icon resource is then a group resource which can be used to
+ select one of the actual icon bitmaps. */
+
+void
+define_icon (id, resinfo, filename)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ const char *filename;
+{
+ FILE *e;
+ char *real_filename;
+ int type, count, i;
+ struct icondir *icondirs;
+ int first_icon;
+ struct res_resource *r;
+ struct group_icon *first, **pp;
+
+ e = open_file_search (filename, FOPEN_RB, "icon file", &real_filename);
+
+ /* The start of an icon file is a three word structure. The first
+ word is ignored. The second word is the type of data. The third
+ word is the number of entries. */
+
+ get_word (e, real_filename);
+ type = get_word (e, real_filename);
+ count = get_word (e, real_filename);
+ if (type != 1)
+ fatal (_("icon file `%s' does not contain icon data"), real_filename);
+
+ /* Read in the icon directory entries. */
+
+ icondirs = (struct icondir *) xmalloc (count * sizeof *icondirs);
+
+ for (i = 0; i < count; i++)
+ {
+ icondirs[i].width = getc (e);
+ icondirs[i].height = getc (e);
+ icondirs[i].colorcount = getc (e);
+ getc (e);
+ icondirs[i].u.icon.planes = get_word (e, real_filename);
+ icondirs[i].u.icon.bits = get_word (e, real_filename);
+ icondirs[i].bytes = get_long (e, real_filename);
+ icondirs[i].offset = get_long (e, real_filename);
+
+ if (feof (e))
+ unexpected_eof (real_filename);
+ }
+
+ /* Define each icon as a unique resource. */
+
+ first_icon = icons;
+
+ for (i = 0; i < count; i++)
+ {
+ unsigned char *data;
+ struct res_id name;
+
+ if (fseek (e, icondirs[i].offset, SEEK_SET) != 0)
+ fatal (_("%s: fseek to %lu failed: %s"), real_filename,
+ icondirs[i].offset, strerror (errno));
+
+ data = (unsigned char *) res_alloc (icondirs[i].bytes);
+
+ get_data (e, data, icondirs[i].bytes, real_filename);
+
+ ++icons;
+
+ name.named = 0;
+ name.u.id = icons;
+
+ r = define_standard_resource (&resources, RT_ICON, name,
+ resinfo->language, 0);
+ r->type = RES_TYPE_ICON;
+ r->u.data.length = icondirs[i].bytes;
+ r->u.data.data = data;
+ r->res_info = *resinfo;
+ }
+
+ fclose (e);
+ free (real_filename);
+
+ /* Define an icon group resource. */
+
+ first = NULL;
+ pp = &first;
+ for (i = 0; i < count; i++)
+ {
+ struct group_icon *cg;
+
+ /* For some reason, at least in some files the planes and bits
+ are zero. We instead set them from the color. This is
+ copied from rcl. */
+
+ cg = (struct group_icon *) res_alloc (sizeof *cg);
+ cg->next = NULL;
+ cg->width = icondirs[i].width;
+ cg->height = icondirs[i].height;
+ cg->colors = icondirs[i].colorcount;
+
+ cg->planes = 1;
+ cg->bits = 0;
+ while ((1 << cg->bits) < cg->colors)
+ ++cg->bits;
+
+ cg->bytes = icondirs[i].bytes;
+ cg->index = first_icon + i + 1;
+
+ *pp = cg;
+ pp = &(*pp)->next;
+ }
+
+ free (icondirs);
+
+ r = define_standard_resource (&resources, RT_GROUP_ICON, id,
+ resinfo->language, 0);
+ r->type = RES_TYPE_GROUP_ICON;
+ r->u.group_icon = first;
+ r->res_info = *resinfo;
+}
+
+/* Define a menu resource. */
+
+void
+define_menu (id, resinfo, menuitems)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ struct menuitem *menuitems;
+{
+ struct menu *m;
+ struct res_resource *r;
+
+ m = (struct menu *) res_alloc (sizeof *m);
+ m->items = menuitems;
+ m->help = 0;
+
+ r = define_standard_resource (&resources, RT_MENU, id, resinfo->language, 0);
+ r->type = RES_TYPE_MENU;
+ r->u.menu = m;
+ r->res_info = *resinfo;
+}
+
+/* Define a menu item. This does not define a resource, but merely
+ allocates and fills in a structure. */
+
+struct menuitem *
+define_menuitem (text, menuid, type, state, help, menuitems)
+ const char *text;
+ int menuid;
+ unsigned long type;
+ unsigned long state;
+ unsigned long help;
+ struct menuitem *menuitems;
+{
+ struct menuitem *mi;
+
+ mi = (struct menuitem *) res_alloc (sizeof *mi);
+ mi->next = NULL;
+ mi->type = type;
+ mi->state = state;
+ mi->id = menuid;
+ if (text == NULL)
+ mi->text = NULL;
+ else
+ unicode_from_ascii ((int *) NULL, &mi->text, text);
+ mi->help = help;
+ mi->popup = menuitems;
+ return mi;
+}
+
+/* Define a messagetable resource. */
+
+void
+define_messagetable (id, resinfo, filename)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ const char *filename;
+{
+ FILE *e;
+ char *real_filename;
+ struct stat s;
+ unsigned char *data;
+ struct res_resource *r;
+
+ e = open_file_search (filename, FOPEN_RB, "messagetable file",
+ &real_filename);
+
+ if (stat (real_filename, &s) < 0)
+ fatal (_("stat failed on bitmap file `%s': %s"), real_filename,
+ strerror (errno));
+
+ data = (unsigned char *) res_alloc (s.st_size);
+
+ get_data (e, data, s.st_size, real_filename);
+
+ fclose (e);
+ free (real_filename);
+
+ r = define_standard_resource (&resources, RT_MESSAGETABLE, id,
+ resinfo->language, 0);
+
+ r->type = RES_TYPE_MESSAGETABLE;
+ r->u.data.length = s.st_size;
+ r->u.data.data = data;
+ r->res_info = *resinfo;
+}
+
+/* Define an rcdata resource. */
+
+void
+define_rcdata (id, resinfo, data)
+ struct res_id id;
+ const struct res_res_info *resinfo;
+ struct rcdata_item *data;
+{
+ struct res_resource *r;
+
+ r = define_standard_resource (&resources, RT_RCDATA, id,
+ resinfo->language, 0);
+ r->type = RES_TYPE_RCDATA;
+ r->u.rcdata = data;
+ r->res_info = *resinfo;
+}
+
+/* Create an rcdata item holding a string. */
+
+struct rcdata_item *
+define_rcdata_string (string, len)
+ const char *string;
+ unsigned long len;
+{
+ struct rcdata_item *ri;
+ char *s;
+
+ ri = (struct rcdata_item *) res_alloc (sizeof *ri);
+ ri->next = NULL;
+ ri->type = RCDATA_STRING;
+ ri->u.string.length = len;
+ s = (char *) res_alloc (len);
+ memcpy (s, string, len);
+ ri->u.string.s = s;
+
+ return ri;
+}
+
+/* Create an rcdata item holding a number. */
+
+struct rcdata_item *
+define_rcdata_number (val, dword)
+ unsigned long val;
+ int dword;
+{
+ struct rcdata_item *ri;
+
+ ri = (struct rcdata_item *) res_alloc (sizeof *ri);
+ ri->next = NULL;
+ ri->type = dword ? RCDATA_DWORD : RCDATA_WORD;
+ ri->u.word = val;
+
+ return ri;
+}
+
+/* Define a stringtable resource. This is called for each string
+ which appears in a STRINGTABLE statement. */
+
+void
+define_stringtable (resinfo, stringid, string)
+ const struct res_res_info *resinfo;
+ unsigned long stringid;
+ const char *string;
+{
+ struct res_id id;
+ struct res_resource *r;
+
+ id.named = 0;
+ id.u.id = (stringid >> 4) + 1;
+ r = define_standard_resource (&resources, RT_STRING, id,
+ resinfo->language, 1);
+
+ if (r->type == RES_TYPE_UNINITIALIZED)
+ {
+ int i;
+
+ r->type = RES_TYPE_STRINGTABLE;
+ r->u.stringtable = ((struct stringtable *)
+ res_alloc (sizeof (struct stringtable)));
+ for (i = 0; i < 16; i++)
+ {
+ r->u.stringtable->strings[i].length = 0;
+ r->u.stringtable->strings[i].string = NULL;
+ }
+
+ r->res_info = *resinfo;
+ }
+
+ unicode_from_ascii (&r->u.stringtable->strings[stringid & 0xf].length,
+ &r->u.stringtable->strings[stringid & 0xf].string,
+ string);
+}
+
+/* Define a user data resource where the data is in the rc file. */
+
+void
+define_user_data (id, type, resinfo, data)
+ struct res_id id;
+ struct res_id type;
+ const struct res_res_info *resinfo;
+ struct rcdata_item *data;
+{
+ struct res_id ids[3];
+ struct res_resource *r;
+
+ ids[0] = type;
+ ids[1] = id;
+ ids[2].named = 0;
+ ids[2].u.id = resinfo->language;
+
+ r = define_resource (&resources, 3, ids, 0);
+ r->type = RES_TYPE_USERDATA;
+ r->u.userdata = data;
+ r->res_info = *resinfo;
+}
+
+/* Define a user data resource where the data is in a file. */
+
+void
+define_user_file (id, type, resinfo, filename)
+ struct res_id id;
+ struct res_id type;
+ const struct res_res_info *resinfo;
+ const char *filename;
+{
+ FILE *e;
+ char *real_filename;
+ struct stat s;
+ unsigned char *data;
+ struct res_id ids[3];
+ struct res_resource *r;
+
+ e = open_file_search (filename, FOPEN_RB, "font file", &real_filename);
+
+ if (stat (real_filename, &s) < 0)
+ fatal (_("stat failed on bitmap file `%s': %s"), real_filename,
+ strerror (errno));
+
+ data = (unsigned char *) res_alloc (s.st_size);
+
+ get_data (e, data, s.st_size, real_filename);
+
+ fclose (e);
+ free (real_filename);
+
+ ids[0] = type;
+ ids[1] = id;
+ ids[2].named = 0;
+ ids[2].u.id = resinfo->language;
+
+ r = define_resource (&resources, 3, ids, 0);
+ r->type = RES_TYPE_USERDATA;
+ r->u.userdata = ((struct rcdata_item *)
+ res_alloc (sizeof (struct rcdata_item)));
+ r->u.userdata->next = NULL;
+ r->u.userdata->type = RCDATA_BUFFER;
+ r->u.userdata->u.buffer.length = s.st_size;
+ r->u.userdata->u.buffer.data = data;
+ r->res_info = *resinfo;
+}
+
+/* Define a versioninfo resource. */
+
+void
+define_versioninfo (id, language, fixedverinfo, verinfo)
+ struct res_id id;
+ int language;
+ struct fixed_versioninfo *fixedverinfo;
+ struct ver_info *verinfo;
+{
+ struct res_resource *r;
+
+ r = define_standard_resource (&resources, RT_VERSION, id, language, 0);
+ r->type = RES_TYPE_VERSIONINFO;
+ r->u.versioninfo = ((struct versioninfo *)
+ res_alloc (sizeof (struct versioninfo)));
+ r->u.versioninfo->fixed = fixedverinfo;
+ r->u.versioninfo->var = verinfo;
+ r->res_info.language = language;
+}
+
+/* Add string version info to a list of version information. */
+
+struct ver_info *
+append_ver_stringfileinfo (verinfo, language, strings)
+ struct ver_info *verinfo;
+ const char *language;
+ struct ver_stringinfo *strings;
+{
+ struct ver_info *vi, **pp;
+
+ vi = (struct ver_info *) res_alloc (sizeof *vi);
+ vi->next = NULL;
+ vi->type = VERINFO_STRING;
+ unicode_from_ascii ((int *) NULL, &vi->u.string.language, language);
+ vi->u.string.strings = strings;
+
+ for (pp = &verinfo; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = vi;
+
+ return verinfo;
+}
+
+/* Add variable version info to a list of version information. */
+
+struct ver_info *
+append_ver_varfileinfo (verinfo, key, var)
+ struct ver_info *verinfo;
+ const char *key;
+ struct ver_varinfo *var;
+{
+ struct ver_info *vi, **pp;
+
+ vi = (struct ver_info *) res_alloc (sizeof *vi);
+ vi->next = NULL;
+ vi->type = VERINFO_VAR;
+ unicode_from_ascii ((int *) NULL, &vi->u.var.key, key);
+ vi->u.var.var = var;
+
+ for (pp = &verinfo; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = vi;
+
+ return verinfo;
+}
+
+/* Append version string information to a list. */
+
+struct ver_stringinfo *
+append_verval (strings, key, value)
+ struct ver_stringinfo *strings;
+ const char *key;
+ const char *value;
+{
+ struct ver_stringinfo *vs, **pp;
+
+ vs = (struct ver_stringinfo *) res_alloc (sizeof *vs);
+ vs->next = NULL;
+ unicode_from_ascii ((int *) NULL, &vs->key, key);
+ unicode_from_ascii ((int *) NULL, &vs->value, value);
+
+ for (pp = &strings; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = vs;
+
+ return strings;
+}
+
+/* Append version variable information to a list. */
+
+struct ver_varinfo *
+append_vertrans (var, language, charset)
+ struct ver_varinfo *var;
+ unsigned long language;
+ unsigned long charset;
+{
+ struct ver_varinfo *vv, **pp;
+
+ vv = (struct ver_varinfo *) res_alloc (sizeof *vv);
+ vv->next = NULL;
+ vv->language = language;
+ vv->charset = charset;
+
+ for (pp = &var; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = vv;
+
+ return var;
+}
+
+/* Local functions used to write out an rc file. */
+
+static void indent PARAMS ((FILE *, int));
+static void write_rc_directory
+ PARAMS ((FILE *, const struct res_directory *, const struct res_id *,
+ const struct res_id *, int *, int));
+static void write_rc_subdir
+ PARAMS ((FILE *, const struct res_entry *, const struct res_id *,
+ const struct res_id *, int *, int));
+static void write_rc_resource
+ PARAMS ((FILE *, const struct res_id *, const struct res_id *,
+ const struct res_resource *, int *));
+static void write_rc_accelerators
+ PARAMS ((FILE *, const struct accelerator *));
+static void write_rc_cursor PARAMS ((FILE *, const struct cursor *));
+static void write_rc_group_cursor
+ PARAMS ((FILE *, const struct group_cursor *));
+static void write_rc_dialog PARAMS ((FILE *, const struct dialog *));
+static void write_rc_dialog_control
+ PARAMS ((FILE *, const struct dialog_control *));
+static void write_rc_fontdir PARAMS ((FILE *, const struct fontdir *));
+static void write_rc_group_icon PARAMS ((FILE *, const struct group_icon *));
+static void write_rc_menu PARAMS ((FILE *, const struct menu *, int));
+static void write_rc_menuitems
+ PARAMS ((FILE *, const struct menuitem *, int, int));
+static void write_rc_rcdata PARAMS ((FILE *, const struct rcdata_item *, int));
+static void write_rc_stringtable
+ PARAMS ((FILE *, const struct res_id *, const struct stringtable *));
+static void write_rc_versioninfo PARAMS ((FILE *, const struct versioninfo *));
+static void write_rc_filedata
+ PARAMS ((FILE *, unsigned long, const unsigned char *));
+
+/* Indent a given number of spaces. */
+
+static void
+indent (e, c)
+ FILE *e;
+ int c;
+{
+ int i;
+
+ for (i = 0; i < c; i++)
+ putc (' ', e);
+}
+
+/* Dump the resources we have read in the format of an rc file.
+
+ Actually, we don't use the format of an rc file, because it's way
+ too much of a pain--for example, we'd have to write icon resources
+ into a file and refer to that file. We just generate a readable
+ format that kind of looks like an rc file, and is useful for
+ understanding the contents of a resource file. Someday we may want
+ to generate an rc file which the rc compiler can read; if that day
+ comes, this code will have to be fixed up. */
+
+void
+write_rc_file (filename, resources)
+ const char *filename;
+ const struct res_directory *resources;
+{
+ FILE *e;
+ int language;
+
+ if (filename == NULL)
+ e = stdout;
+ else
+ {
+ e = fopen (filename, FOPEN_WT);
+ if (e == NULL)
+ fatal (_("can't open `%s' for output: %s"), filename, strerror (errno));
+ }
+
+ language = -1;
+ write_rc_directory (e, resources, (const struct res_id *) NULL,
+ (const struct res_id *) NULL, &language, 1);
+}
+
+/* Write out a directory. E is the file to write to. RD is the
+ directory. TYPE is a pointer to the level 1 ID which serves as the
+ resource type. NAME is a pointer to the level 2 ID which serves as
+ an individual resource name. LANGUAGE is a pointer to the current
+ language. LEVEL is the level in the tree. */
+
+static void
+write_rc_directory (e, rd, type, name, language, level)
+ FILE *e;
+ const struct res_directory *rd;
+ const struct res_id *type;
+ const struct res_id *name;
+ int *language;
+ int level;
+{
+ const struct res_entry *re;
+
+ /* Print out some COFF information that rc files can't represent. */
+
+ if (rd->time != 0)
+ fprintf (e, "// Time stamp: %lu\n", rd->time);
+ if (rd->characteristics != 0)
+ fprintf (e, "// Characteristics: %lu\n", rd->characteristics);
+ if (rd->major != 0 || rd->minor != 0)
+ fprintf (e, "// Version: %d %d\n", rd->major, rd->minor);
+
+ for (re = rd->entries; re != NULL; re = re->next)
+ {
+ switch (level)
+ {
+ case 1:
+ /* If we're at level 1, the key of this resource is the
+ type. This normally duplicates the information we have
+ stored with the resource itself, but we need to remember
+ the type if this is a user define resource type. */
+ type = &re->id;
+ break;
+
+ case 2:
+ /* If we're at level 2, the key of this resource is the name
+ we are going to use in the rc printout. */
+ name = &re->id;
+ break;
+
+ case 3:
+ /* If we're at level 3, then this key represents a language.
+ Use it to update the current language. */
+ if (! re->id.named
+ && re->id.u.id != (unsigned long) (unsigned int) *language
+ && (re->id.u.id & 0xffff) == re->id.u.id)
+ {
+ fprintf (e, "LANGUAGE %lu, %lu\n",
+ re->id.u.id & 0xff, (re->id.u.id >> 8) & 0xff);
+ *language = re->id.u.id;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (re->subdir)
+ write_rc_subdir (e, re, type, name, language, level);
+ else
+ {
+ if (level == 3)
+ {
+ /* This is the normal case: the three levels are
+ TYPE/NAME/LANGUAGE. NAME will have been set at level
+ 2, and represents the name to use. We probably just
+ set LANGUAGE, and it will probably match what the
+ resource itself records if anything. */
+ write_rc_resource (e, type, name, re->u.res, language);
+ }
+ else
+ {
+ fprintf (e, "// Resource at unexpected level %d\n", level);
+ write_rc_resource (e, type, (struct res_id *) NULL, re->u.res,
+ language);
+ }
+ }
+ }
+}
+
+/* Write out a subdirectory entry. E is the file to write to. RE is
+ the subdirectory entry. TYPE and NAME are pointers to higher level
+ IDs, or NULL. LANGUAGE is a pointer to the current language.
+ LEVEL is the level in the tree. */
+
+static void
+write_rc_subdir (e, re, type, name, language, level)
+ FILE *e;
+ const struct res_entry *re;
+ const struct res_id *type;
+ const struct res_id *name;
+ int *language;
+ int level;
+{
+ fprintf (e, "\n");
+ switch (level)
+ {
+ case 1:
+ fprintf (e, "// Type: ");
+ if (re->id.named)
+ res_id_print (e, re->id, 1);
+ else
+ {
+ const char *s;
+
+ switch (re->id.u.id)
+ {
+ case RT_CURSOR: s = "cursor"; break;
+ case RT_BITMAP: s = "bitmap"; break;
+ case RT_ICON: s = "icon"; break;
+ case RT_MENU: s = "menu"; break;
+ case RT_DIALOG: s = "dialog"; break;
+ case RT_STRING: s = "stringtable"; break;
+ case RT_FONTDIR: s = "fontdir"; break;
+ case RT_FONT: s = "font"; break;
+ case RT_ACCELERATOR: s = "accelerators"; break;
+ case RT_RCDATA: s = "rcdata"; break;
+ case RT_MESSAGETABLE: s = "messagetable"; break;
+ case RT_GROUP_CURSOR: s = "group cursor"; break;
+ case RT_GROUP_ICON: s = "group icon"; break;
+ case RT_VERSION: s = "version"; break;
+ case RT_DLGINCLUDE: s = "dlginclude"; break;
+ case RT_PLUGPLAY: s = "plugplay"; break;
+ case RT_VXD: s = "vxd"; break;
+ case RT_ANICURSOR: s = "anicursor"; break;
+ case RT_ANIICON: s = "aniicon"; break;
+ default: s = NULL; break;
+ }
+
+ if (s != NULL)
+ fprintf (e, "%s", s);
+ else
+ res_id_print (e, re->id, 1);
+ }
+ fprintf (e, "\n");
+ break;
+
+ case 2:
+ fprintf (e, "// Name: ");
+ res_id_print (e, re->id, 1);
+ fprintf (e, "\n");
+ break;
+
+ case 3:
+ fprintf (e, "// Language: ");
+ res_id_print (e, re->id, 1);
+ fprintf (e, "\n");
+ break;
+
+ default:
+ fprintf (e, "// Level %d: ", level);
+ res_id_print (e, re->id, 1);
+ fprintf (e, "\n");
+ }
+
+ write_rc_directory (e, re->u.dir, type, name, language, level + 1);
+}
+
+/* Write out a single resource. E is the file to write to. TYPE is a
+ pointer to the type of the resource. NAME is a pointer to the name
+ of the resource; it will be NULL if there is a level mismatch. RES
+ is the resource data. LANGUAGE is a pointer to the current
+ language. */
+
+static void
+write_rc_resource (e, type, name, res, language)
+ FILE *e;
+ const struct res_id *type;
+ const struct res_id *name;
+ const struct res_resource *res;
+ int *language;
+{
+ const char *s;
+ int rt;
+ int menuex = 0;
+
+ fprintf (e, "\n");
+
+ switch (res->type)
+ {
+ default:
+ abort ();
+
+ case RES_TYPE_ACCELERATOR:
+ s = "ACCELERATOR";
+ rt = RT_ACCELERATOR;
+ break;
+
+ case RES_TYPE_BITMAP:
+ s = "BITMAP";
+ rt = RT_BITMAP;
+ break;
+
+ case RES_TYPE_CURSOR:
+ s = "CURSOR";
+ rt = RT_CURSOR;
+ break;
+
+ case RES_TYPE_GROUP_CURSOR:
+ s = "GROUP_CURSOR";
+ rt = RT_GROUP_CURSOR;
+ break;
+
+ case RES_TYPE_DIALOG:
+ if (extended_dialog (res->u.dialog))
+ s = "DIALOGEX";
+ else
+ s = "DIALOG";
+ rt = RT_DIALOG;
+ break;
+
+ case RES_TYPE_FONT:
+ s = "FONT";
+ rt = RT_FONT;
+ break;
+
+ case RES_TYPE_FONTDIR:
+ s = "FONTDIR";
+ rt = RT_FONTDIR;
+ break;
+
+ case RES_TYPE_ICON:
+ s = "ICON";
+ rt = RT_ICON;
+ break;
+
+ case RES_TYPE_GROUP_ICON:
+ s = "GROUP_ICON";
+ rt = RT_GROUP_ICON;
+ break;
+
+ case RES_TYPE_MENU:
+ if (extended_menu (res->u.menu))
+ {
+ s = "MENUEX";
+ menuex = 1;
+ }
+ else
+ {
+ s = "MENU";
+ menuex = 0;
+ }
+ rt = RT_MENU;
+ break;
+
+ case RES_TYPE_MESSAGETABLE:
+ s = "MESSAGETABLE";
+ rt = RT_MESSAGETABLE;
+ break;
+
+ case RES_TYPE_RCDATA:
+ s = "RCDATA";
+ rt = RT_RCDATA;
+ break;
+
+ case RES_TYPE_STRINGTABLE:
+ s = "STRINGTABLE";
+ rt = RT_STRING;
+ break;
+
+ case RES_TYPE_USERDATA:
+ s = NULL;
+ rt = 0;
+ break;
+
+ case RES_TYPE_VERSIONINFO:
+ s = "VERSIONINFO";
+ rt = RT_VERSION;
+ break;
+ }
+
+ if (rt != 0
+ && type != NULL
+ && (type->named || type->u.id != (unsigned long) rt))
+ {
+ fprintf (e, "// Unexpected resource type mismatch: ");
+ res_id_print (e, *type, 1);
+ fprintf (e, " != %d", rt);
+ }
+
+ if (res->coff_info.codepage != 0)
+ fprintf (e, "// Code page: %lu\n", res->coff_info.codepage);
+ if (res->coff_info.reserved != 0)
+ fprintf (e, "// COFF reserved value: %lu\n", res->coff_info.reserved);
+
+ if (name != NULL)
+ res_id_print (e, *name, 0);
+ else
+ fprintf (e, "??Unknown-Name??");
+
+ fprintf (e, " ");
+ if (s != NULL)
+ fprintf (e, "%s", s);
+ else if (type != NULL)
+ res_id_print (e, *type, 0);
+ else
+ fprintf (e, "??Unknown-Type??");
+
+ if (res->res_info.memflags != 0)
+ {
+ if ((res->res_info.memflags & MEMFLAG_MOVEABLE) != 0)
+ fprintf (e, " MOVEABLE");
+ if ((res->res_info.memflags & MEMFLAG_PURE) != 0)
+ fprintf (e, " PURE");
+ if ((res->res_info.memflags & MEMFLAG_PRELOAD) != 0)
+ fprintf (e, " PRELOAD");
+ if ((res->res_info.memflags & MEMFLAG_DISCARDABLE) != 0)
+ fprintf (e, " DISCARDABLE");
+ }
+
+ if (res->type == RES_TYPE_DIALOG)
+ {
+ fprintf (e, " %d, %d, %d, %d", res->u.dialog->x, res->u.dialog->y,
+ res->u.dialog->width, res->u.dialog->height);
+ if (res->u.dialog->ex != NULL
+ && res->u.dialog->ex->help != 0)
+ fprintf (e, ", %lu", res->u.dialog->ex->help);
+ }
+
+ fprintf (e, "\n");
+
+ if ((res->res_info.language != 0 && res->res_info.language != *language)
+ || res->res_info.characteristics != 0
+ || res->res_info.version != 0)
+ {
+ int modifiers;
+
+ switch (res->type)
+ {
+ case RES_TYPE_ACCELERATOR:
+ case RES_TYPE_DIALOG:
+ case RES_TYPE_MENU:
+ case RES_TYPE_RCDATA:
+ case RES_TYPE_STRINGTABLE:
+ modifiers = 1;
+ break;
+
+ default:
+ modifiers = 0;
+ break;
+ }
+
+ if (res->res_info.language != 0 && res->res_info.language != *language)
+ fprintf (e, "%sLANGUAGE %d, %d\n",
+ modifiers ? "// " : "",
+ res->res_info.language & 0xff,
+ (res->res_info.language >> 8) & 0xff);
+ if (res->res_info.characteristics != 0)
+ fprintf (e, "%sCHARACTERISTICS %lu\n",
+ modifiers ? "// " : "",
+ res->res_info.characteristics);
+ if (res->res_info.version != 0)
+ fprintf (e, "%sVERSION %lu\n",
+ modifiers ? "// " : "",
+ res->res_info.version);
+ }
+
+ switch (res->type)
+ {
+ default:
+ abort ();
+
+ case RES_TYPE_ACCELERATOR:
+ write_rc_accelerators (e, res->u.acc);
+ break;
+
+ case RES_TYPE_CURSOR:
+ write_rc_cursor (e, res->u.cursor);
+ break;
+
+ case RES_TYPE_GROUP_CURSOR:
+ write_rc_group_cursor (e, res->u.group_cursor);
+ break;
+
+ case RES_TYPE_DIALOG:
+ write_rc_dialog (e, res->u.dialog);
+ break;
+
+ case RES_TYPE_FONTDIR:
+ write_rc_fontdir (e, res->u.fontdir);
+ break;
+
+ case RES_TYPE_GROUP_ICON:
+ write_rc_group_icon (e, res->u.group_icon);
+ break;
+
+ case RES_TYPE_MENU:
+ write_rc_menu (e, res->u.menu, menuex);
+ break;
+
+ case RES_TYPE_RCDATA:
+ write_rc_rcdata (e, res->u.rcdata, 0);
+ break;
+
+ case RES_TYPE_STRINGTABLE:
+ write_rc_stringtable (e, name, res->u.stringtable);
+ break;
+
+ case RES_TYPE_USERDATA:
+ write_rc_rcdata (e, res->u.userdata, 0);
+ break;
+
+ case RES_TYPE_VERSIONINFO:
+ write_rc_versioninfo (e, res->u.versioninfo);
+ break;
+
+ case RES_TYPE_BITMAP:
+ case RES_TYPE_FONT:
+ case RES_TYPE_ICON:
+ case RES_TYPE_MESSAGETABLE:
+ write_rc_filedata (e, res->u.data.length, res->u.data.data);
+ break;
+ }
+}
+
+/* Write out accelerator information. */
+
+static void
+write_rc_accelerators (e, accelerators)
+ FILE *e;
+ const struct accelerator *accelerators;
+{
+ const struct accelerator *acc;
+
+ fprintf (e, "BEGIN\n");
+ for (acc = accelerators; acc != NULL; acc = acc->next)
+ {
+ int printable;
+
+ fprintf (e, " ");
+
+ if ((acc->key & 0x7f) == acc->key
+ && isprint ((unsigned char) acc->key)
+ && (acc->flags & ACC_VIRTKEY) == 0)
+ {
+ fprintf (e, "\"%c\"", acc->key);
+ printable = 1;
+ }
+ else
+ {
+ fprintf (e, "%d", acc->key);
+ printable = 0;
+ }
+
+ fprintf (e, ", %d", acc->id);
+
+ if (! printable)
+ {
+ if ((acc->flags & ACC_VIRTKEY) != 0)
+ fprintf (e, ", VIRTKEY");
+ else
+ fprintf (e, ", ASCII");
+ }
+
+ if ((acc->flags & ACC_SHIFT) != 0)
+ fprintf (e, ", SHIFT");
+ if ((acc->flags & ACC_CONTROL) != 0)
+ fprintf (e, ", CONTROL");
+ if ((acc->flags & ACC_ALT) != 0)
+ fprintf (e, ", ALT");
+
+ fprintf (e, "\n");
+ }
+
+ fprintf (e, "END\n");
+}
+
+/* Write out cursor information. This would normally be in a separate
+ file, which the rc file would include. */
+
+static void
+write_rc_cursor (e, cursor)
+ FILE *e;
+ const struct cursor *cursor;
+{
+ fprintf (e, "// Hotspot: x: %d; y: %d\n", cursor->xhotspot,
+ cursor->yhotspot);
+ write_rc_filedata (e, cursor->length, cursor->data);
+}
+
+/* Write out group cursor data. This would normally be built from the
+ cursor data. */
+
+static void
+write_rc_group_cursor (e, group_cursor)
+ FILE *e;
+ const struct group_cursor *group_cursor;
+{
+ const struct group_cursor *gc;
+
+ for (gc = group_cursor; gc != NULL; gc = gc->next)
+ {
+ fprintf (e, "// width: %d; height %d; planes %d; bits %d\n",
+ gc->width, gc->height, gc->planes, gc->bits);
+ fprintf (e, "// data bytes: %lu; index: %d\n",
+ gc->bytes, gc->index);
+ }
+}
+
+/* Write dialog data. */
+
+static void
+write_rc_dialog (e, dialog)
+ FILE *e;
+ const struct dialog *dialog;
+{
+ const struct dialog_control *control;
+
+ if (dialog->style != 0)
+ fprintf (e, "STYLE 0x%lx\n", dialog->style);
+ if (dialog->exstyle != 0)
+ fprintf (e, "EXSTYLE 0x%lx\n", dialog->exstyle);
+ if ((dialog->class.named && dialog->class.u.n.length > 0)
+ || dialog->class.u.id != 0)
+ {
+ fprintf (e, "CLASS ");
+ res_id_print (e, dialog->class, 0);
+ fprintf (e, "\n");
+ }
+ if (dialog->caption != NULL)
+ {
+ fprintf (e, "CAPTION \"");
+ unicode_print (e, dialog->caption, -1);
+ fprintf (e, "\"\n");
+ }
+ if ((dialog->menu.named && dialog->menu.u.n.length > 0)
+ || dialog->menu.u.id != 0)
+ {
+ fprintf (e, "MENU ");
+ res_id_print (e, dialog->menu, 0);
+ fprintf (e, "\n");
+ }
+ if (dialog->font != NULL)
+ {
+ fprintf (e, "FONT %d, \"", dialog->pointsize);
+ unicode_print (e, dialog->font, -1);
+ fprintf (e, "\"");
+ if (dialog->ex != NULL
+ && (dialog->ex->weight != 0 || dialog->ex->italic != 0))
+ fprintf (e, ", %d, %d", dialog->ex->weight, dialog->ex->italic);
+ fprintf (e, "\n");
+ }
+
+ fprintf (e, "BEGIN\n");
+
+ for (control = dialog->controls; control != NULL; control = control->next)
+ write_rc_dialog_control (e, control);
+
+ fprintf (e, "END\n");
+}
+
+/* For each predefined control keyword, this table provides the class
+ and the style. */
+
+struct control_info
+{
+ const char *name;
+ unsigned short class;
+ unsigned long style;
+};
+
+static const struct control_info control_info[] =
+{
+ { "AUTO3STATE", CTL_BUTTON, BS_AUTO3STATE },
+ { "AUTOCHECKBOX", CTL_BUTTON, BS_AUTOCHECKBOX },
+ { "AUTORADIOBUTTON", CTL_BUTTON, BS_AUTORADIOBUTTON },
+ { "CHECKBOX", CTL_BUTTON, BS_CHECKBOX },
+ { "COMBOBOX", CTL_COMBOBOX, (unsigned long) -1 },
+ { "CTEXT", CTL_STATIC, SS_CENTER },
+ { "DEFPUSHBUTTON", CTL_BUTTON, BS_DEFPUSHBUTTON },
+ { "EDITTEXT", CTL_EDIT, (unsigned long) -1 },
+ { "GROUPBOX", CTL_BUTTON, BS_GROUPBOX },
+ { "ICON", CTL_STATIC, SS_ICON },
+ { "LISTBOX", CTL_LISTBOX, (unsigned long) -1 },
+ { "LTEXT", CTL_STATIC, SS_LEFT },
+ { "PUSHBOX", CTL_BUTTON, BS_PUSHBOX },
+ { "PUSHBUTTON", CTL_BUTTON, BS_PUSHBUTTON },
+ { "RADIOBUTTON", CTL_BUTTON, BS_RADIOBUTTON },
+ { "RTEXT", CTL_STATIC, SS_RIGHT },
+ { "SCROLLBAR", CTL_SCROLLBAR, (unsigned long) -1 },
+ { "STATE3", CTL_BUTTON, BS_3STATE },
+ /* It's important that USERBUTTON come after all the other button
+ types, so that it won't be matched too early. */
+ { "USERBUTTON", CTL_BUTTON, (unsigned long) -1 },
+ { NULL, 0, 0 }
+};
+
+/* Write a dialog control. */
+
+static void
+write_rc_dialog_control (e, control)
+ FILE *e;
+ const struct dialog_control *control;
+{
+ const struct control_info *ci;
+
+ fprintf (e, " ");
+
+ if (control->class.named)
+ ci = NULL;
+ else
+ {
+ for (ci = control_info; ci->name != NULL; ++ci)
+ if (ci->class == control->class.u.id
+ && (ci->style == (unsigned long) -1
+ || ci->style == (control->style & 0xff)))
+ break;
+ }
+ if (ci == NULL)
+ fprintf (e, "CONTROL");
+ else if (ci->name != NULL)
+ fprintf (e, "%s", ci->name);
+ else
+ fprintf (e, "CONTROL");
+
+ if (control->text.named || control->text.u.id != 0)
+ {
+ fprintf (e, " ");
+ res_id_print (e, control->text, 1);
+ fprintf (e, ",");
+ }
+
+ fprintf (e, " %d, ", control->id);
+
+ if (ci == NULL)
+ {
+ if (control->class.named)
+ fprintf (e, "\"");
+ res_id_print (e, control->class, 0);
+ if (control->class.named)
+ fprintf (e, "\"");
+ fprintf (e, ", 0x%lx, ", control->style);
+ }
+
+ fprintf (e, "%d, %d", control->x, control->y);
+
+ if (control->style != SS_ICON
+ || control->exstyle != 0
+ || control->width != 0
+ || control->height != 0
+ || control->help != 0)
+ {
+ fprintf (e, ", %d, %d", control->width, control->height);
+
+ /* FIXME: We don't need to print the style if it is the default.
+ More importantly, in certain cases we actually need to turn
+ off parts of the forced style, by using NOT. */
+ fprintf (e, ", 0x%lx", control->style);
+
+ if (control->exstyle != 0 || control->help != 0)
+ fprintf (e, ", 0x%lx, %lu", control->exstyle, control->help);
+ }
+
+ fprintf (e, "\n");
+
+ if (control->data != NULL)
+ write_rc_rcdata (e, control->data, 2);
+}
+
+/* Write out font directory data. This would normally be built from
+ the font data. */
+
+static void
+write_rc_fontdir (e, fontdir)
+ FILE *e;
+ const struct fontdir *fontdir;
+{
+ const struct fontdir *fc;
+
+ for (fc = fontdir; fc != NULL; fc = fc->next)
+ {
+ fprintf (e, "// Font index: %d\n", fc->index);
+ write_rc_filedata (e, fc->length, fc->data);
+ }
+}
+
+/* Write out group icon data. This would normally be built from the
+ icon data. */
+
+static void
+write_rc_group_icon (e, group_icon)
+ FILE *e;
+ const struct group_icon *group_icon;
+{
+ const struct group_icon *gi;
+
+ for (gi = group_icon; gi != NULL; gi = gi->next)
+ {
+ fprintf (e, "// width: %d; height %d; colors: %d; planes %d; bits %d\n",
+ gi->width, gi->height, gi->colors, gi->planes, gi->bits);
+ fprintf (e, "// data bytes: %lu; index: %d\n",
+ gi->bytes, gi->index);
+ }
+}
+
+/* Write out a menu resource. */
+
+static void
+write_rc_menu (e, menu, menuex)
+ FILE *e;
+ const struct menu *menu;
+ int menuex;
+{
+ if (menu->help != 0)
+ fprintf (e, "// Help ID: %lu\n", menu->help);
+ write_rc_menuitems (e, menu->items, menuex, 0);
+}
+
+/* Write out menuitems. */
+
+static void
+write_rc_menuitems (e, menuitems, menuex, ind)
+ FILE *e;
+ const struct menuitem *menuitems;
+ int menuex;
+ int ind;
+{
+ const struct menuitem *mi;
+
+ indent (e, ind);
+ fprintf (e, "BEGIN\n");
+
+ for (mi = menuitems; mi != NULL; mi = mi->next)
+ {
+ indent (e, ind + 2);
+
+ if (mi->popup == NULL)
+ fprintf (e, "MENUITEM");
+ else
+ fprintf (e, "POPUP");
+
+ if (! menuex
+ && mi->popup == NULL
+ && mi->text == NULL
+ && mi->type == 0
+ && mi->id == 0)
+ {
+ fprintf (e, " SEPARATOR\n");
+ continue;
+ }
+
+ if (mi->text == NULL)
+ fprintf (e, " \"\"");
+ else
+ {
+ fprintf (e, " \"");
+ unicode_print (e, mi->text, -1);
+ fprintf (e, "\"");
+ }
+
+ if (! menuex)
+ {
+ if (mi->popup == NULL)
+ fprintf (e, ", %d", mi->id);
+
+ if ((mi->type & MENUITEM_CHECKED) != 0)
+ fprintf (e, ", CHECKED");
+ if ((mi->type & MENUITEM_GRAYED) != 0)
+ fprintf (e, ", GRAYED");
+ if ((mi->type & MENUITEM_HELP) != 0)
+ fprintf (e, ", HELP");
+ if ((mi->type & MENUITEM_INACTIVE) != 0)
+ fprintf (e, ", INACTIVE");
+ if ((mi->type & MENUITEM_MENUBARBREAK) != 0)
+ fprintf (e, ", MENUBARBREAK");
+ if ((mi->type & MENUITEM_MENUBREAK) != 0)
+ fprintf (e, ", MENUBREAK");
+ }
+ else
+ {
+ if (mi->id != 0 || mi->type != 0 || mi->state != 0 || mi->help != 0)
+ {
+ fprintf (e, ", %d", mi->id);
+ if (mi->type != 0 || mi->state != 0 || mi->help != 0)
+ {
+ fprintf (e, ", %lu", mi->type);
+ if (mi->state != 0 || mi->help != 0)
+ {
+ fprintf (e, ", %lu", mi->state);
+ if (mi->help != 0)
+ fprintf (e, ", %lu", mi->help);
+ }
+ }
+ }
+ }
+
+ fprintf (e, "\n");
+
+ if (mi->popup != NULL)
+ write_rc_menuitems (e, mi->popup, menuex, ind + 2);
+ }
+
+ indent (e, ind);
+ fprintf (e, "END\n");
+}
+
+/* Write out an rcdata resource. This is also used for other types of
+ resources that need to print arbitrary data. */
+
+static void
+write_rc_rcdata (e, rcdata, ind)
+ FILE *e;
+ const struct rcdata_item *rcdata;
+ int ind;
+{
+ const struct rcdata_item *ri;
+
+ indent (e, ind);
+ fprintf (e, "BEGIN\n");
+
+ for (ri = rcdata; ri != NULL; ri = ri->next)
+ {
+ if (ri->type == RCDATA_BUFFER && ri->u.buffer.length == 0)
+ continue;
+
+ indent (e, ind + 2);
+
+ switch (ri->type)
+ {
+ default:
+ abort ();
+
+ case RCDATA_WORD:
+ fprintf (e, "%d", ri->u.word);
+ break;
+
+ case RCDATA_DWORD:
+ fprintf (e, "%luL", ri->u.dword);
+ break;
+
+ case RCDATA_STRING:
+ {
+ const char *s;
+ unsigned long i;
+
+ fprintf (e, "\"");
+ s = ri->u.string.s;
+ for (i = 0; i < ri->u.string.length; i++)
+ {
+ if (isprint ((unsigned char) *s))
+ putc (*s, e);
+ else
+ fprintf (e, "\\%03o", *s);
+ }
+ fprintf (e, "\"");
+ break;
+ }
+
+ case RCDATA_WSTRING:
+ fprintf (e, "L\"");
+ unicode_print (e, ri->u.wstring.w, ri->u.wstring.length);
+ fprintf (e, "\"");
+ break;
+
+ case RCDATA_BUFFER:
+ {
+ unsigned long i;
+ int first;
+
+ /* Assume little endian data. */
+
+ first = 1;
+ for (i = 0; i + 3 < ri->u.buffer.length; i += 4)
+ {
+ unsigned long l;
+
+ l = ((((((ri->u.buffer.data[i + 3] << 8)
+ | ri->u.buffer.data[i + 2]) << 8)
+ | ri->u.buffer.data[i + 1]) << 8)
+ | ri->u.buffer.data[i]);
+ if (first)
+ first = 0;
+ else
+ {
+ fprintf (e, ",\n");
+ indent (e, ind + 2);
+ }
+ fprintf (e, "%luL", l);
+ }
+
+ if (i + 1 < ri->u.buffer.length)
+ {
+ int i;
+
+ i = (ri->u.buffer.data[i + 1] << 8) | ri->u.buffer.data[i];
+ if (first)
+ first = 0;
+ else
+ {
+ fprintf (e, ",\n");
+ indent (e, ind + 2);
+ }
+ fprintf (e, "%d", i);
+ i += 2;
+ }
+
+ if (i < ri->u.buffer.length)
+ {
+ if (first)
+ first = 0;
+ else
+ {
+ fprintf (e, ",\n");
+ indent (e, ind + 2);
+ }
+ if ((ri->u.buffer.data[i] & 0x7f) == ri->u.buffer.data[i]
+ && isprint (ri->u.buffer.data[i]))
+ fprintf (e, "\"%c\"", ri->u.buffer.data[i]);
+ else
+ fprintf (e, "\"\%03o\"", ri->u.buffer.data[i]);
+ }
+
+ break;
+ }
+ }
+
+ if (ri->next != NULL)
+ fprintf (e, ",");
+ fprintf (e, "\n");
+ }
+
+ indent (e, ind);
+ fprintf (e, "END\n");
+}
+
+/* Write out a stringtable resource. */
+
+static void
+write_rc_stringtable (e, name, stringtable)
+ FILE *e;
+ const struct res_id *name;
+ const struct stringtable *stringtable;
+{
+ unsigned long offset;
+ int i;
+
+ if (name != NULL && ! name->named)
+ offset = (name->u.id - 1) << 4;
+ else
+ {
+ fprintf (e, "// %s string table name\n",
+ name == NULL ? "Missing" : "Invalid");
+ offset = 0;
+ }
+
+ fprintf (e, "BEGIN\n");
+
+ for (i = 0; i < 16; i++)
+ {
+ if (stringtable->strings[i].length != 0)
+ {
+ fprintf (e, " %lu, \"", offset + i);
+ unicode_print (e, stringtable->strings[i].string,
+ stringtable->strings[i].length);
+ fprintf (e, "\"\n");
+ }
+ }
+
+ fprintf (e, "END\n");
+}
+
+/* Write out a versioninfo resource. */
+
+static void
+write_rc_versioninfo (e, versioninfo)
+ FILE *e;
+ const struct versioninfo *versioninfo;
+{
+ const struct fixed_versioninfo *f;
+ const struct ver_info *vi;
+
+ f = versioninfo->fixed;
+ if (f->file_version_ms != 0 || f->file_version_ls != 0)
+ fprintf (e, " FILEVERSION %lu, %lu, %lu, %lu\n",
+ (f->file_version_ms >> 16) & 0xffff,
+ f->file_version_ms & 0xffff,
+ (f->file_version_ls >> 16) & 0xffff,
+ f->file_version_ls & 0xffff);
+ if (f->product_version_ms != 0 || f->product_version_ls != 0)
+ fprintf (e, " PRODUCTVERSION %lu, %lu, %lu, %lu\n",
+ (f->product_version_ms >> 16) & 0xffff,
+ f->product_version_ms & 0xffff,
+ (f->product_version_ls >> 16) & 0xffff,
+ f->product_version_ls & 0xffff);
+ if (f->file_flags_mask != 0)
+ fprintf (e, " FILEFLAGSMASK 0x%lx\n", f->file_flags_mask);
+ if (f->file_flags != 0)
+ fprintf (e, " FILEFLAGS 0x%lx\n", f->file_flags);
+ if (f->file_os != 0)
+ fprintf (e, " FILEOS 0x%lx\n", f->file_os);
+ if (f->file_type != 0)
+ fprintf (e, " FILETYPE 0x%lx\n", f->file_type);
+ if (f->file_subtype != 0)
+ fprintf (e, " FILESUBTYPE 0x%lx\n", f->file_subtype);
+ if (f->file_date_ms != 0 || f->file_date_ls != 0)
+ fprintf (e, "// Date: %lu, %lu\n", f->file_date_ms, f->file_date_ls);
+
+ fprintf (e, "BEGIN\n");
+
+ for (vi = versioninfo->var; vi != NULL; vi = vi->next)
+ {
+ switch (vi->type)
+ {
+ case VERINFO_STRING:
+ {
+ const struct ver_stringinfo *vs;
+
+ fprintf (e, " BLOCK \"StringFileInfo\"\n");
+ fprintf (e, " BEGIN\n");
+ fprintf (e, " BLOCK \"");
+ unicode_print (e, vi->u.string.language, -1);
+ fprintf (e, "\"\n");
+ fprintf (e, " BEGIN\n");
+
+ for (vs = vi->u.string.strings; vs != NULL; vs = vs->next)
+ {
+ fprintf (e, " VALUE \"");
+ unicode_print (e, vs->key, -1);
+ fprintf (e, "\", \"");
+ unicode_print (e, vs->value, -1);
+ fprintf (e, "\"\n");
+ }
+
+ fprintf (e, " END\n");
+ fprintf (e, " END\n");
+ break;
+ }
+
+ case VERINFO_VAR:
+ {
+ const struct ver_varinfo *vv;
+
+ fprintf (e, " BLOCK \"VarFileInfo\"\n");
+ fprintf (e, " BEGIN\n");
+ fprintf (e, " VALUE \"");
+ unicode_print (e, vi->u.var.key, -1);
+ fprintf (e, "\"");
+
+ for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
+ fprintf (e, ", 0x%x, %d", (unsigned int) vv->language,
+ vv->charset);
+
+ fprintf (e, "\n END\n");
+
+ break;
+ }
+ }
+ }
+
+ fprintf (e, "END\n");
+}
+
+/* Write out data which would normally be read from a file. */
+
+static void
+write_rc_filedata (e, length, data)
+ FILE *e;
+ unsigned long length;
+ const unsigned char *data;
+{
+ unsigned long i;
+
+ for (i = 0; i + 15 < length; i += 16)
+ {
+ fprintf (e, "// %4lx: ", i);
+ fprintf (e, "%02x %02x %02x %02x %02x %02x %02x %02x ",
+ data[i + 0], data[i + 1], data[i + 2], data[i + 3],
+ data[i + 4], data[i + 5], data[i + 6], data[i + 7]);
+ fprintf (e, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ data[i + 8], data[i + 9], data[i + 10], data[i + 11],
+ data[i + 12], data[i + 13], data[i + 14], data[i + 15]);
+ }
+
+ if (i < length)
+ {
+ fprintf (e, "// %4lx:", i);
+ while (i < length)
+ {
+ fprintf (e, " %02x", data[i]);
+ ++i;
+ }
+ fprintf (e, "\n");
+ }
+}
diff --git a/binutils/resres.c b/binutils/resres.c
new file mode 100644
index 00000000000..39264f445a2
--- /dev/null
+++ b/binutils/resres.c
@@ -0,0 +1,656 @@
+/* resres.c: read_res_file and write_res_file implementation for windres.
+
+ Copyright 1998, 1999 Free Software Foundation, Inc.
+ Written by Anders Norlander <anorland@hem2.passagen.se>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "windres.h"
+
+#include <assert.h>
+#include <time.h>
+
+struct res_hdr
+ {
+ unsigned long data_size;
+ unsigned long header_size;
+ };
+
+static void write_res_directory
+ PARAMS ((const struct res_directory *,
+ const struct res_id *, const struct res_id *,
+ int *, int));
+static void write_res_resource
+ PARAMS ((const struct res_id *, const struct res_id *,
+ const struct res_resource *, int *));
+static void write_res_bin
+ PARAMS ((const struct res_resource *, const struct res_id *,
+ const struct res_id *, const struct res_res_info *));
+
+static void write_res_id PARAMS ((const struct res_id *));
+static void write_res_info PARAMS ((const struct res_res_info *));
+static void write_res_data PARAMS ((const void *, size_t, int));
+static void write_res_header
+ PARAMS ((unsigned long, const struct res_id *, const struct res_id *,
+ const struct res_res_info *));
+
+static int read_resource_entry PARAMS ((void));
+static void read_res_data PARAMS ((void *, size_t, int));
+static void read_res_id PARAMS ((struct res_id *));
+static unichar *read_unistring PARAMS ((int *));
+static void skip_null_resource PARAMS ((void));
+
+static unsigned long get_id_size PARAMS ((const struct res_id *));
+static void res_align_file PARAMS ((void));
+
+static void
+ res_add_resource
+ PARAMS ((struct res_resource *, const struct res_id *,
+ const struct res_id *, int, int));
+
+void
+ res_append_resource
+ PARAMS ((struct res_directory **, struct res_resource *,
+ int, const struct res_id *, int));
+
+static struct res_directory *resources = NULL;
+
+static FILE *fres;
+static const char *filename;
+
+extern char *program_name;
+
+/* Read resource file */
+struct res_directory *
+read_res_file (fn)
+ const char *fn;
+{
+ filename = fn;
+ fres = fopen (filename, "rb");
+ if (fres == NULL)
+ fatal ("can't open `%s' for output: %s", filename, strerror (errno));
+
+ skip_null_resource ();
+
+ while (read_resource_entry ())
+ ;
+
+ fclose (fres);
+
+ return resources;
+}
+
+/* Write resource file */
+void
+write_res_file (fn, resdir)
+ const char *fn;
+ const struct res_directory *resdir;
+{
+ int language;
+ static const unsigned char sign[] =
+ {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ long fpos;
+
+ filename = fn;
+
+ fres = fopen (filename, "wb");
+ if (fres == NULL)
+ fatal ("can't open `%s' for output: %s", filename, strerror (errno));
+
+ /* Write 32 bit resource signature */
+ write_res_data (sign, sizeof (sign), 1);
+
+ /* write resources */
+
+ language = -1;
+ write_res_directory (resdir, (const struct res_id *) NULL,
+ (const struct res_id *) NULL, &language, 1);
+
+ /* end file on DWORD boundary */
+ fpos = ftell (fres);
+ if (fpos % 4)
+ write_res_data (sign, fpos % 4, 1);
+
+ fclose (fres);
+}
+
+/* Read a resource entry, returns 0 when all resources are read */
+static int
+read_resource_entry (void)
+{
+ struct res_id type;
+ struct res_id name;
+ struct res_res_info resinfo;
+ struct res_hdr reshdr;
+ long version;
+ void *buff;
+
+ struct res_resource *r;
+
+ res_align_file ();
+
+ /* Read header */
+ if (fread (&reshdr, sizeof (reshdr), 1, fres) != 1)
+ return 0;
+
+ /* read resource type */
+ read_res_id (&type);
+ /* read resource id */
+ read_res_id (&name);
+
+ res_align_file ();
+
+ /* Read additional resource header */
+ read_res_data (&resinfo.version, sizeof (resinfo.version), 1);
+ read_res_data (&resinfo.memflags, sizeof (resinfo.memflags), 1);
+ read_res_data (&resinfo.language, sizeof (resinfo.language), 1);
+ read_res_data (&version, sizeof (version), 1);
+ read_res_data (&resinfo.characteristics, sizeof (resinfo.characteristics), 1);
+
+ res_align_file ();
+
+ /* Allocate buffer for data */
+ buff = res_alloc (reshdr.data_size);
+ /* Read data */
+ read_res_data (buff, reshdr.data_size, 1);
+ /* Convert binary data to resource */
+ r = bin_to_res (type, buff, reshdr.data_size, 0);
+ r->res_info = resinfo;
+ /* Add resource to resource directory */
+ res_add_resource (r, &type, &name, resinfo.language, 0);
+
+ return 1;
+}
+
+/* write resource directory to binary resource file */
+static void
+write_res_directory (rd, type, name, language, level)
+ const struct res_directory *rd;
+ const struct res_id *type;
+ const struct res_id *name;
+ int *language;
+ int level;
+{
+ const struct res_entry *re;
+
+ for (re = rd->entries; re != NULL; re = re->next)
+ {
+ switch (level)
+ {
+ case 1:
+ /* If we're at level 1, the key of this resource is the
+ type. This normally duplicates the information we have
+ stored with the resource itself, but we need to remember
+ the type if this is a user define resource type. */
+ type = &re->id;
+ break;
+
+ case 2:
+ /* If we're at level 2, the key of this resource is the name
+ we are going to use in the rc printout. */
+ name = &re->id;
+ break;
+
+ case 3:
+ /* If we're at level 3, then this key represents a language.
+ Use it to update the current language. */
+ if (!re->id.named
+ && re->id.u.id != *language
+ && (re->id.u.id & 0xffff) == re->id.u.id)
+ {
+ *language = re->id.u.id;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (re->subdir)
+ write_res_directory (re->u.dir, type, name, language, level + 1);
+ else
+ {
+ if (level == 3)
+ {
+ /* This is the normal case: the three levels are
+ TYPE/NAME/LANGUAGE. NAME will have been set at level
+ 2, and represents the name to use. We probably just
+ set LANGUAGE, and it will probably match what the
+ resource itself records if anything. */
+ write_res_resource (type, name, re->u.res, language);
+ }
+ else
+ {
+ fprintf (stderr, "// Resource at unexpected level %d\n", level);
+ write_res_resource (type, (struct res_id *) NULL, re->u.res,
+ language);
+ }
+ }
+ }
+
+}
+
+static void
+write_res_resource (type, name, res, language)
+ const struct res_id *type;
+ const struct res_id *name;
+ const struct res_resource *res;
+ int *language;
+{
+ int rt;
+
+ switch (res->type)
+ {
+ default:
+ abort ();
+
+ case RES_TYPE_ACCELERATOR:
+ rt = RT_ACCELERATOR;
+ break;
+
+ case RES_TYPE_BITMAP:
+ rt = RT_BITMAP;
+ break;
+
+ case RES_TYPE_CURSOR:
+ rt = RT_CURSOR;
+ break;
+
+ case RES_TYPE_GROUP_CURSOR:
+ rt = RT_GROUP_CURSOR;
+ break;
+
+ case RES_TYPE_DIALOG:
+ rt = RT_DIALOG;
+ break;
+
+ case RES_TYPE_FONT:
+ rt = RT_FONT;
+ break;
+
+ case RES_TYPE_FONTDIR:
+ rt = RT_FONTDIR;
+ break;
+
+ case RES_TYPE_ICON:
+ rt = RT_ICON;
+ break;
+
+ case RES_TYPE_GROUP_ICON:
+ rt = RT_GROUP_ICON;
+ break;
+
+ case RES_TYPE_MENU:
+ rt = RT_MENU;
+ break;
+
+ case RES_TYPE_MESSAGETABLE:
+ rt = RT_MESSAGETABLE;
+ break;
+
+ case RES_TYPE_RCDATA:
+ rt = RT_RCDATA;
+ break;
+
+ case RES_TYPE_STRINGTABLE:
+ rt = RT_STRING;
+ break;
+
+ case RES_TYPE_USERDATA:
+ rt = 0;
+ break;
+
+ case RES_TYPE_VERSIONINFO:
+ rt = RT_VERSION;
+ break;
+ }
+
+ if (rt != 0
+ && type != NULL
+ && (type->named || type->u.id != rt))
+ {
+ fprintf (stderr, "// Unexpected resource type mismatch: ");
+ res_id_print (stderr, *type, 1);
+ fprintf (stderr, " != %d", rt);
+ abort ();
+ }
+
+ write_res_bin (res, type, name, &res->res_info);
+ return;
+}
+
+/* Write a resource in binary resource format */
+static void
+write_res_bin (res, type, name, resinfo)
+ const struct res_resource *res;
+ const struct res_id *type;
+ const struct res_id *name;
+ const struct res_res_info *resinfo;
+{
+ unsigned long datasize = 0;
+ const struct bindata *bin_rep, *data;
+
+ bin_rep = res_to_bin (res, 0);
+ for (data = bin_rep; data != NULL; data = data->next)
+ datasize += data->length;
+
+ write_res_header (datasize, type, name, resinfo);
+
+ for (data = bin_rep; data != NULL; data = data->next)
+ write_res_data (data->data, data->length, 1);
+}
+
+/* Get number of bytes needed to store an id in binary format */
+static unsigned long
+get_id_size (id)
+ const struct res_id *id;
+{
+ if (id->named)
+ return sizeof (unichar) * (id->u.n.length + 1);
+ else
+ return sizeof (unichar) * 2;
+}
+
+/* Write a resource header */
+static void
+write_res_header (datasize, type, name, resinfo)
+ unsigned long datasize;
+ const struct res_id *type;
+ const struct res_id *name;
+ const struct res_res_info *resinfo;
+{
+ struct res_hdr reshdr;
+ reshdr.data_size = datasize;
+ reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);
+
+ res_align_file ();
+ write_res_data (&reshdr, sizeof (reshdr), 1);
+ write_res_id (type);
+ write_res_id (name);
+
+ res_align_file ();
+
+ write_res_info (resinfo);
+ res_align_file ();
+}
+
+
+/* Write data to file, abort on failure */
+static void
+write_res_data (data, size, count)
+ const void *data;
+ size_t size;
+ int count;
+{
+ if (fwrite (data, size, count, fres) != count)
+ fatal ("%s: %s: could not write to file", program_name, filename);
+}
+
+/* Read data from file, abort on failure */
+static void
+read_res_data (data, size, count)
+ void *data;
+ size_t size;
+ int count;
+{
+ if (fread (data, size, count, fres) != count)
+ fatal ("%s: %s: unexpected end of file", program_name, filename);
+}
+
+/* Write a resource id */
+static void
+write_res_id (id)
+ const struct res_id *id;
+{
+ if (id->named)
+ {
+ unsigned long len = id->u.n.length;
+ unichar null_term = 0;
+ write_res_data (id->u.n.name, len * sizeof (unichar), 1);
+ write_res_data (&null_term, sizeof (null_term), 1);
+ }
+ else
+ {
+ unsigned short i = 0xFFFF;
+ write_res_data (&i, sizeof (i), 1);
+ i = id->u.id;
+ write_res_data (&i, sizeof (i), 1);
+ }
+}
+
+/* Write resource info */
+static void
+write_res_info (info)
+ const struct res_res_info *info;
+{
+ write_res_data (&info->version, sizeof (info->version), 1);
+ write_res_data (&info->memflags, sizeof (info->memflags), 1);
+ write_res_data (&info->language, sizeof (info->language), 1);
+ write_res_data (&info->version, sizeof (info->version), 1);
+ write_res_data (&info->characteristics, sizeof (info->characteristics), 1);
+}
+
+/* read a resource identifier */
+void
+read_res_id (id)
+ struct res_id *id;
+{
+ unsigned short ord;
+ unichar *id_s = NULL;
+ int len;
+
+ read_res_data (&ord, sizeof (ord), 1);
+ if (ord == 0xFFFF) /* an ordinal id */
+ {
+ read_res_data (&ord, sizeof (ord), 1);
+ id->named = 0;
+ id->u.id = ord;
+ }
+ else
+ /* named id */
+ {
+ if (fseek (fres, -sizeof (ord), SEEK_CUR) != 0)
+ fatal ("%s: %s: could not seek in file", program_name, filename);
+ id_s = read_unistring (&len);
+ id->named = 1;
+ id->u.n.length = len;
+ id->u.n.name = id_s;
+ }
+}
+
+/* Read a null terminated UNICODE string */
+static unichar *
+read_unistring (len)
+ int *len;
+{
+ unichar *s;
+ unichar c;
+ unichar *p;
+ int l;
+
+ *len = 0;
+ l = 0;
+
+ /* there are hardly any names longer than 256 characters */
+ p = s = (unichar *) xmalloc (sizeof (unichar) * 256);
+ do
+ {
+ read_res_data (&c, sizeof (c), 1);
+ *p++ = c;
+ if (c != 0)
+ l++;
+ }
+ while (c != 0);
+ *len = l;
+ return s;
+}
+
+/* align file on DWORD boundary */
+static void
+res_align_file (void)
+{
+ if (fseek (fres, ftell (fres) % 4, SEEK_CUR) != 0)
+ fatal ("%s: %s: unable to align file", program_name, filename);
+}
+
+/* Check if file is a win32 binary resource file, if so
+ skip past the null resource. Returns 0 if successful, -1 on
+ error.
+ */
+static void
+skip_null_resource (void)
+{
+ struct res_hdr reshdr =
+ {0, 0};
+ read_res_data (&reshdr, sizeof (reshdr), 1);
+ if ((reshdr.data_size != 0) || (reshdr.header_size != 0x20))
+ goto skip_err;
+
+ /* Subtract size of HeaderSize and DataSize */
+ if (fseek (fres, reshdr.header_size - 8, SEEK_CUR) != 0)
+ goto skip_err;
+
+ return;
+
+skip_err:
+ fprintf (stderr, "%s: %s: Not a valid WIN32 resource file\n", program_name,
+ filename);
+ xexit (1);
+}
+
+/* Add a resource to resource directory */
+void
+res_add_resource (r, type, id, language, dupok)
+ struct res_resource *r;
+ const struct res_id *type;
+ const struct res_id *id;
+ int language;
+ int dupok;
+{
+ struct res_id a[3];
+
+ a[0] = *type;
+ a[1] = *id;
+ a[2].named = 0;
+ a[2].u.id = language;
+ res_append_resource (&resources, r, 3, a, dupok);
+}
+
+/* Append a resource to resource directory.
+ This is just copied from define_resource
+ and modified to add an existing resource.
+ */
+void
+res_append_resource (resources, resource, cids, ids, dupok)
+ struct res_directory **resources;
+ struct res_resource *resource;
+ int cids;
+ const struct res_id *ids;
+ int dupok;
+{
+ struct res_entry *re = NULL;
+ int i;
+
+ assert (cids > 0);
+ for (i = 0; i < cids; i++)
+ {
+ struct res_entry **pp;
+
+ if (*resources == NULL)
+ {
+ static unsigned long timeval;
+
+ /* Use the same timestamp for every resource created in a
+ single run. */
+ if (timeval == 0)
+ timeval = time (NULL);
+
+ *resources = ((struct res_directory *)
+ res_alloc (sizeof **resources));
+ (*resources)->characteristics = 0;
+ (*resources)->time = timeval;
+ (*resources)->major = 0;
+ (*resources)->minor = 0;
+ (*resources)->entries = NULL;
+ }
+
+ for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
+ if (res_id_cmp ((*pp)->id, ids[i]) == 0)
+ break;
+
+ if (*pp != NULL)
+ re = *pp;
+ else
+ {
+ re = (struct res_entry *) res_alloc (sizeof *re);
+ re->next = NULL;
+ re->id = ids[i];
+ if ((i + 1) < cids)
+ {
+ re->subdir = 1;
+ re->u.dir = NULL;
+ }
+ else
+ {
+ re->subdir = 0;
+ re->u.res = NULL;
+ }
+
+ *pp = re;
+ }
+
+ if ((i + 1) < cids)
+ {
+ if (!re->subdir)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ res_ids_print (stderr, i, ids);
+ fprintf (stderr, ": expected to be a directory\n");
+ xexit (1);
+ }
+
+ resources = &re->u.dir;
+ }
+ }
+
+ if (re->subdir)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ res_ids_print (stderr, cids, ids);
+ fprintf (stderr, ": expected to be a leaf\n");
+ xexit (1);
+ }
+
+ if (re->u.res != NULL)
+ {
+ if (dupok)
+ return;
+
+ fprintf (stderr, "%s: warning: ", program_name);
+ res_ids_print (stderr, cids, ids);
+ fprintf (stderr, ": duplicate value\n");
+ }
+
+ re->u.res = resource;
+}
diff --git a/binutils/sanity.sh b/binutils/sanity.sh
new file mode 100755
index 00000000000..942cabf9ac0
--- /dev/null
+++ b/binutils/sanity.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+### quick sanity test for the binutils.
+###
+### This file was written and is maintained by K. Richard Pixley,
+### rich@cygnus.com.
+
+### fail on errors
+set -e
+
+### first arg is directory in which binaries to be tested reside.
+case "$1" in
+"") BIN=. ;;
+*) BIN="$1" ;;
+esac
+
+### size
+for i in size objdump nm ar strip ranlib ; do
+ ${BIN}/size ${BIN}/$i > /dev/null
+done
+
+### objdump
+for i in size objdump nm ar strip ranlib ; do
+ ${BIN}/objdump -ahifdrtxsl ${BIN}/$i > /dev/null
+done
+
+### nm
+for i in size objdump nm ar strip ranlib ; do
+ ${BIN}/nm ${BIN}/$i > /dev/null
+done
+
+### strip
+TMPDIR=./binutils-$$
+mkdir ${TMPDIR}
+
+cp ${BIN}/strip ${TMPDIR}/strip
+
+for i in size objdump nm ar ranlib ; do
+ cp ${BIN}/$i ${TMPDIR}/$i
+ ${BIN}/strip ${TMPDIR}/$i
+ cp ${BIN}/$i ${TMPDIR}/$i
+ ${TMPDIR}/strip ${TMPDIR}/$i
+done
+
+### ar
+
+### ranlib
+
+rm -rf ${TMPDIR}
+
+exit 0
diff --git a/binutils/size.1 b/binutils/size.1
new file mode 100644
index 00000000000..3b19bd25930
--- /dev/null
+++ b/binutils/size.1
@@ -0,0 +1,161 @@
+.\" Copyright (c) 1991 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH size 1 "5 November 1991" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+size \- list section sizes and total size.
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B size
+.RB "[\|" \-A \||\| \-B \||\| \c
+.BI "\-\-format=" compatibility\c
+\&\|]
+.RB "[\|" \-\-help "\|]"
+.RB "[\|" \-d \||\| \-o \||\| \-x\c
+\||\|\c
+.BI "\-\-radix=" number\c
+\&\|]
+.RB "[\|" \c
+.BI "\-\-target=" bfdname\c
+\&\|]
+.RB "[\|" \-V \||\| \-\-version "\|]"
+.I objfile\c
+\&.\|.\|.
+.ad b
+.hy 1
+.SH DESCRIPTION
+The GNU \c
+.B size\c
+\& utility lists the section sizes\(em\&and the total
+size\(em\&for each of the object files
+.I objfile
+in its argument list.
+By default, one line of output is generated for each object file or each
+module in an archive.
+
+.SH OPTIONS
+.TP
+.B \-A
+.TP
+.B \-B
+.TP
+.BI "\-\-format " "compatibility"
+Using one of these options, you can choose whether the output from GNU
+\c
+.B size\c
+\& resembles output from System V \c
+.B size\c
+\& (using `\|\c
+.B \-A\c
+\|',
+or `\|\c
+.B \-\-format=sysv\c
+\|'), or Berkeley \c
+.B size\c
+\& (using `\|\c
+.B \-B\c
+\|', or
+`\|\c
+.B \-\-format=berkeley\c
+\|'). The default is the one-line format similar to
+Berkeley's.
+
+.TP
+.B \-\-help
+Show a summary of acceptable arguments and options.
+
+.TP
+.B \-d
+.TP
+.B \-o
+.TP
+.B \-x
+.TP
+.BI "\-\-radix " "number"
+Using one of these options, you can control whether the size of each
+section is given in decimal (`\|\c
+.B \-d\c
+\|', or `\|\c
+.B \-\-radix 10\c
+\|'); octal
+(`\|\c
+.B \-o\c
+\|', or `\|\c
+.B \-\-radix 8\c
+\|'); or hexadecimal (`\|\c
+.B \-x\c
+\|', or
+`\|\c
+.B \-\-radix 16\c
+\|'). In `\|\c
+.B \-\-radix \c
+.I number\c
+\&\c
+\|', only the three
+values (8, 10, 16) are supported. The total size is always given in two
+radices; decimal and hexadecimal for `\|\c
+.B \-d\c
+\|' or `\|\c
+.B \-x\c
+\|' output, or
+octal and hexadecimal if you're using `\|\c
+.B \-o\c
+\|'.
+
+.TP
+.BI "\-\-target " "bfdname"
+You can specify a particular object-code format for \c
+.I objfile\c
+\& as
+\c
+.I bfdname\c
+\&. This may not be necessary; \c
+.I size\c
+\& can
+automatically recognize many formats. See
+.BR objdump ( 1 )
+for information
+on listing available formats.
+
+.TP
+.B \-V
+.TP
+.B \-\-version
+Display version number information on \c
+.B size\c
+\& itself.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.BR info ;
+.IR "The GNU Binary Utilities" ,
+ Roland H. Pesch (October 1991);
+.BR ar "(" 1 "),"
+.BR objdump ( 1 ).
+
+.SH COPYING
+Copyright (c) 1991 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/size.c b/binutils/size.c
new file mode 100644
index 00000000000..f57c7eda9b0
--- /dev/null
+++ b/binutils/size.c
@@ -0,0 +1,515 @@
+/* size.c -- report size of various sections of an executable file.
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Extensions/incompatibilities:
+ o - BSD output has filenames at the end.
+ o - BSD output can appear in different radicies.
+ o - SysV output has less redundant whitespace. Filename comes at end.
+ o - SysV output doesn't show VMA which is always the same as the PMA.
+ o - We also handle core files.
+ o - We also handle archives.
+ If you write shell scripts which manipulate this info then you may be
+ out of luck; there's no --compatibility or --pedantic option.
+*/
+
+#include "bfd.h"
+#include "getopt.h"
+#include "bucomm.h"
+#include "libiberty.h"
+
+#ifndef BSD_DEFAULT
+#define BSD_DEFAULT 1
+#endif
+
+/* Program options. */
+
+enum
+ {
+ decimal, octal, hex
+ } radix = decimal;
+int berkeley_format = BSD_DEFAULT; /* 0 means use AT&T-style output. */
+int show_version = 0;
+int show_help = 0;
+
+/* Program exit status. */
+int return_code = 0;
+
+static char *target = NULL;
+
+/* Static declarations */
+
+static void usage PARAMS ((FILE *, int));
+static void display_file PARAMS ((char *filename));
+static void display_bfd PARAMS ((bfd *));
+static void display_archive PARAMS ((bfd *));
+static int size_number PARAMS ((bfd_size_type));
+#if 0
+static void lprint_number PARAMS ((int, bfd_size_type));
+#endif
+static void rprint_number PARAMS ((int, bfd_size_type));
+static void print_berkeley_format PARAMS ((bfd *));
+static void sysv_internal_sizer PARAMS ((bfd *, asection *, PTR));
+static void sysv_internal_printer PARAMS ((bfd *, asection *, PTR));
+static void print_sysv_format PARAMS ((bfd *));
+static void print_sizes PARAMS ((bfd * file));
+static void berkeley_sum PARAMS ((bfd *, sec_ptr, PTR));
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, _("\
+Usage: %s [-ABdoxV] [--format=berkeley|sysv] [--radix=8|10|16]\n\
+ [--target=bfdname] [--version] [--help] [file...]\n"), program_name);
+#if BSD_DEFAULT
+ fputs (_("default is --format=berkeley\n"), stream);
+#else
+ fputs (_("default is --format=sysv\n"), stream);
+#endif
+ list_supported_targets (program_name, stream);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+struct option long_options[] =
+{
+ {"format", required_argument, 0, 200},
+ {"radix", required_argument, 0, 201},
+ {"target", required_argument, 0, 202},
+ {"version", no_argument, &show_version, 1},
+ {"help", no_argument, &show_help, 1},
+ {0, no_argument, 0, 0}
+};
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int temp;
+ int c;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = *argv;
+ xmalloc_set_program_name (program_name);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ while ((c = getopt_long (argc, argv, "ABVdox", long_options,
+ (int *) 0)) != EOF)
+ switch (c)
+ {
+ case 200: /* --format */
+ switch (*optarg)
+ {
+ case 'B':
+ case 'b':
+ berkeley_format = 1;
+ break;
+ case 'S':
+ case 's':
+ berkeley_format = 0;
+ break;
+ default:
+ fprintf (stderr, _("invalid argument to --format: %s\n"), optarg);
+ usage (stderr, 1);
+ }
+ break;
+
+ case 202: /* --target */
+ target = optarg;
+ break;
+
+ case 201: /* --radix */
+#ifdef ANSI_LIBRARIES
+ temp = strtol (optarg, NULL, 10);
+#else
+ temp = atol (optarg);
+#endif
+ switch (temp)
+ {
+ case 10:
+ radix = decimal;
+ break;
+ case 8:
+ radix = octal;
+ break;
+ case 16:
+ radix = hex;
+ break;
+ default:
+ printf (_("Invalid radix: %s\n"), optarg);
+ usage (stderr, 1);
+ }
+ break;
+
+ case 'A':
+ berkeley_format = 0;
+ break;
+ case 'B':
+ berkeley_format = 1;
+ break;
+ case 'V':
+ show_version = 1;
+ break;
+ case 'd':
+ radix = decimal;
+ break;
+ case 'x':
+ radix = hex;
+ break;
+ case 'o':
+ radix = octal;
+ break;
+ case 0:
+ break;
+ case '?':
+ usage (stderr, 1);
+ }
+
+ if (show_version)
+ print_version ("size");
+ if (show_help)
+ usage (stdout, 0);
+
+ if (optind == argc)
+ display_file ("a.out");
+ else
+ for (; optind < argc;)
+ display_file (argv[optind++]);
+
+ return return_code;
+}
+
+/* Display stats on file or archive member ABFD. */
+
+static void
+display_bfd (abfd)
+ bfd *abfd;
+{
+ char **matching;
+
+ if (bfd_check_format (abfd, bfd_archive))
+ /* An archive within an archive. */
+ return;
+
+ if (bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ print_sizes (abfd);
+ printf ("\n");
+ return;
+ }
+
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ bfd_nonfatal (bfd_get_filename (abfd));
+ list_matching_formats (matching);
+ free (matching);
+ return_code = 3;
+ return;
+ }
+
+ if (bfd_check_format_matches (abfd, bfd_core, &matching))
+ {
+ CONST char *core_cmd;
+
+ print_sizes (abfd);
+ fputs (" (core file", stdout);
+
+ core_cmd = bfd_core_file_failing_command (abfd);
+ if (core_cmd)
+ printf (" invoked as %s", core_cmd);
+
+ puts (")\n");
+ return;
+ }
+
+ bfd_nonfatal (bfd_get_filename (abfd));
+
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+
+ return_code = 3;
+}
+
+static void
+display_archive (file)
+ bfd *file;
+{
+ bfd *arfile = (bfd *) NULL;
+
+ for (;;)
+ {
+ bfd_set_error (bfd_error_no_error);
+
+ arfile = bfd_openr_next_archived_file (file, arfile);
+ if (arfile == NULL)
+ {
+ if (bfd_get_error () != bfd_error_no_more_archived_files)
+ {
+ bfd_nonfatal (bfd_get_filename (file));
+ return_code = 2;
+ }
+ break;
+ }
+
+ display_bfd (arfile);
+ /* Don't close the archive elements; we need them for next_archive */
+ }
+}
+
+static void
+display_file (filename)
+ char *filename;
+{
+ bfd *file = bfd_openr (filename, target);
+ if (file == NULL)
+ {
+ bfd_nonfatal (filename);
+ return_code = 1;
+ return;
+ }
+
+ if (bfd_check_format (file, bfd_archive) == true)
+ display_archive (file);
+ else
+ display_bfd (file);
+
+ if (bfd_close (file) == false)
+ {
+ bfd_nonfatal (filename);
+ return_code = 1;
+ return;
+ }
+}
+
+/* This is what lexical functions are for. */
+
+static int
+size_number (num)
+ bfd_size_type num;
+{
+ char buffer[40];
+ sprintf (buffer,
+ (radix == decimal ? "%lu" :
+ ((radix == octal) ? "0%lo" : "0x%lx")),
+ (unsigned long) num);
+
+ return strlen (buffer);
+}
+
+#if 0
+
+/* This is not used. */
+
+static void
+lprint_number (width, num)
+ int width;
+ bfd_size_type num;
+{
+ char buffer[40];
+ sprintf (buffer,
+ (radix == decimal ? "%lu" :
+ ((radix == octal) ? "0%lo" : "0x%lx")),
+ (unsigned long) num);
+
+ printf ("%-*s", width, buffer);
+}
+
+#endif
+
+static void
+rprint_number (width, num)
+ int width;
+ bfd_size_type num;
+{
+ char buffer[40];
+ sprintf (buffer,
+ (radix == decimal ? "%lu" :
+ ((radix == octal) ? "0%lo" : "0x%lx")),
+ (unsigned long) num);
+
+ printf ("%*s", width, buffer);
+}
+
+static bfd_size_type bsssize;
+static bfd_size_type datasize;
+static bfd_size_type textsize;
+
+static void
+berkeley_sum (abfd, sec, ignore)
+ bfd *abfd;
+ sec_ptr sec;
+ PTR ignore;
+{
+ flagword flags;
+ bfd_size_type size;
+
+ flags = bfd_get_section_flags (abfd, sec);
+ if ((flags & SEC_ALLOC) == 0)
+ return;
+
+ size = bfd_get_section_size_before_reloc (sec);
+ if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0)
+ textsize += size;
+ else if ((flags & SEC_HAS_CONTENTS) != 0)
+ datasize += size;
+ else
+ bsssize += size;
+}
+
+static void
+print_berkeley_format (abfd)
+ bfd *abfd;
+{
+ static int files_seen = 0;
+ bfd_size_type total;
+
+ bsssize = 0;
+ datasize = 0;
+ textsize = 0;
+
+ bfd_map_over_sections (abfd, berkeley_sum, (PTR) NULL);
+
+ if (files_seen++ == 0)
+#if 0
+ /* Intel doesn't like bss/stk because they don't have core files. */
+ puts ((radix == octal) ? " text\t data\tbss/stk\t oct\t hex\tfilename" :
+ " text\t data\tbss/stk\t dec\t hex\tfilename");
+#else
+ puts ((radix == octal) ? " text\t data\t bss\t oct\t hex\tfilename" :
+ " text\t data\t bss\t dec\t hex\tfilename");
+#endif
+
+ total = textsize + datasize + bsssize;
+
+ rprint_number (7, textsize);
+ putchar ('\t');
+ rprint_number (7, datasize);
+ putchar ('\t');
+ rprint_number (7, bsssize);
+ printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"),
+ (unsigned long) total, (unsigned long) total);
+
+ fputs (bfd_get_filename (abfd), stdout);
+ if (bfd_my_archive (abfd))
+ printf (" (ex %s)", bfd_get_filename (bfd_my_archive (abfd)));
+}
+
+/* I REALLY miss lexical functions! */
+bfd_size_type svi_total = 0;
+bfd_vma svi_maxvma = 0;
+int svi_namelen = 0;
+int svi_vmalen = 0;
+int svi_sizelen = 0;
+
+static void
+sysv_internal_sizer (file, sec, ignore)
+ bfd *file;
+ sec_ptr sec;
+ PTR ignore;
+{
+ bfd_size_type size = bfd_section_size (file, sec);
+ if (!bfd_is_abs_section (sec)
+ && !bfd_is_com_section (sec)
+ && !bfd_is_und_section (sec))
+ {
+ int namelen = strlen (bfd_section_name (file, sec));
+ if (namelen > svi_namelen)
+ svi_namelen = namelen;
+
+ svi_total += size;
+ if (bfd_section_vma (file, sec) > svi_maxvma)
+ svi_maxvma = bfd_section_vma (file, sec);
+ }
+}
+
+static void
+sysv_internal_printer (file, sec, ignore)
+ bfd *file;
+ sec_ptr sec;
+ PTR ignore;
+{
+ bfd_size_type size = bfd_section_size (file, sec);
+ if (!bfd_is_abs_section (sec)
+ && !bfd_is_com_section (sec)
+ && !bfd_is_und_section (sec))
+ {
+ svi_total += size;
+
+ printf ("%-*s ", svi_namelen, bfd_section_name (file, sec));
+ rprint_number (svi_sizelen, size);
+ printf (" ");
+ rprint_number (svi_vmalen, bfd_section_vma (file, sec));
+ printf ("\n");
+ }
+}
+
+static void
+print_sysv_format (file)
+ bfd *file;
+{
+ /* size all of the columns */
+ svi_total = 0;
+ svi_maxvma = 0;
+ svi_namelen = 0;
+ bfd_map_over_sections (file, sysv_internal_sizer, (PTR) NULL);
+ svi_vmalen = size_number ((bfd_size_type)svi_maxvma);
+ if ((size_t) svi_vmalen < sizeof ("addr") - 1)
+ svi_vmalen = sizeof ("addr")-1;
+
+ svi_sizelen = size_number (svi_total);
+ if ((size_t) svi_sizelen < sizeof ("size") - 1)
+ svi_sizelen = sizeof ("size")-1;
+
+ svi_total = 0;
+ printf ("%s ", bfd_get_filename (file));
+ if (bfd_my_archive (file))
+ printf (" (ex %s)", bfd_get_filename (bfd_my_archive (file)));
+
+ printf (":\n%-*s %*s %*s\n", svi_namelen, "section",
+ svi_sizelen, "size", svi_vmalen, "addr");
+ bfd_map_over_sections (file, sysv_internal_printer, (PTR) NULL);
+
+ printf ("%-*s ", svi_namelen, "Total");
+ rprint_number (svi_sizelen, svi_total);
+ printf ("\n\n");
+}
+
+static void
+print_sizes (file)
+ bfd *file;
+{
+ if (berkeley_format)
+ print_berkeley_format (file);
+ else
+ print_sysv_format (file);
+}
diff --git a/binutils/srconv.c b/binutils/srconv.c
new file mode 100644
index 00000000000..8b0f2b7b5ee
--- /dev/null
+++ b/binutils/srconv.c
@@ -0,0 +1,2036 @@
+/* srconv.c -- Sysroff conversion program
+ Copyright (C) 1994, 95, 96, 98, 1999 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Written by Steve Chamberlain (sac@cygnus.com)
+
+ This program can be used to convert a coff object file
+ into a Hitachi OM/LM (Sysroff) format.
+
+ All debugging information is preserved */
+
+#include <bfd.h>
+#include "bucomm.h"
+#include "sysroff.h"
+#include "coffgrok.h"
+#include <libiberty.h>
+#include <getopt.h>
+
+#include "coff/internal.h"
+#include "../bfd/libcoff.h"
+
+#define PROGRAM_VERSION "1.5"
+/*#define FOOP1 1 */
+
+static int addrsize;
+static char *toolname;
+static char **rnames;
+
+static void wr_cs ();
+static void walk_tree_scope ();
+static void wr_globals ();
+static int find_base ();
+
+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 segmented_p;
+static int code;
+
+static int ids1[20000];
+static int ids2[20000];
+
+static int base1 = 0x18;
+static int base2 = 0x2018;
+
+static int
+get_member_id (x)
+ int x;
+{
+ if (ids2[x])
+ {
+ return ids2[x];
+ }
+ ids2[x] = base2++;
+ return ids2[x];
+}
+
+static int
+get_ordinary_id (x)
+ int x;
+{
+ if (ids1[x])
+ {
+ return ids1[x];
+ }
+ ids1[x] = base1++;
+ return ids1[x];
+}
+static char *
+section_translate (n)
+ char *n;
+{
+ if (strcmp (n, ".text") == 0)
+ return "P";
+ if (strcmp (n, ".data") == 0)
+ return "D";
+ if (strcmp (n, ".bss") == 0)
+ return "B";
+ return n;
+}
+
+
+
+#define DATE "940201073000"; /* Just a time on my birthday */
+
+
+static
+char *
+strip_suffix (name)
+ char *name;
+{
+ int i;
+ char *res;
+ for (i = 0; name[i] != 0 && name[i] != '.'; i++)
+ ;
+ res = (char *) xmalloc (i + 1);
+ memcpy (res, name, i);
+ res[i] = 0;
+ return res;
+}
+
+
+/* IT LEN stuff CS */
+static void
+checksum (file, ptr, size, code)
+ FILE *file;
+ char *ptr;
+ int size;
+ int code;
+{
+ int j;
+ int last;
+ int sum = 0;
+ int bytes = size / 8;
+ last = !(code & 0xff00);
+ if (size & 0x7)
+ abort ();
+ ptr[0] = code | (last ? 0x80 : 0);
+ ptr[1] = bytes + 1;
+
+ for (j = 0; j < bytes; j++)
+ {
+ sum += ptr[j];
+ }
+ /* Glue on a checksum too */
+ ptr[bytes] = ~sum;
+ fwrite (ptr, bytes + 1, 1, file);
+}
+
+
+
+
+static void
+writeINT (n, ptr, idx, size, file)
+ int n;
+ char *ptr;
+ int *idx;
+ int size;
+ FILE *file;
+{
+ int byte = *idx / 8;
+
+ if (size == -2)
+ size = addrsize;
+ else if (size == -1)
+ size = 0;
+
+ if (byte > 240)
+ {
+ /* Lets write out that record and do another one */
+ checksum (file, ptr, *idx, code | 0x1000);
+ *idx = 16;
+ byte = *idx / 8;
+ }
+ switch (size)
+ {
+ case 0:
+ break;
+ case 1:
+ ptr[byte] = n;
+ break;
+ case 2:
+ ptr[byte + 0] = n >> 8;
+ ptr[byte + 1] = n;
+ break;
+ case 4:
+ ptr[byte + 0] = n >> 24;
+ ptr[byte + 1] = n >> 16;
+ ptr[byte + 2] = n >> 8;
+ ptr[byte + 3] = n >> 0;
+ break;
+ default:
+ abort ();
+ }
+ *idx += size * 8;
+}
+
+
+static void
+writeBITS (val, ptr, idx, size)
+ int val;
+ char *ptr;
+ int *idx;
+ int size;
+{
+ int byte = *idx / 8;
+ int bit = *idx % 8;
+ int old;
+ *idx += size;
+
+ old = ptr[byte];
+ /* Turn off all about to change bits */
+ old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
+ /* Turn on the bits we want */
+ old |= (val & ((1 << size) - 1)) << (8 - bit - size);
+ ptr[byte] = old;
+}
+
+static void
+writeBARRAY (data, ptr, idx, size, file)
+ barray data;
+ char *ptr;
+ int *idx;
+ int size;
+ FILE *file;
+{
+ int i;
+ writeINT (data.len, ptr, idx, 1, file);
+ for (i = 0; i < data.len; i++)
+ {
+ writeINT (data.data[i], ptr, idx, 1, file);
+ }
+}
+
+
+static void
+writeCHARS (string, ptr, idx, size, file)
+ char *string;
+ char *ptr;
+ int *idx;
+ int size;
+ FILE *file;
+{
+ int i = *idx / 8;
+
+ if (i > 240)
+ {
+ /* Lets write out that record and do another one */
+ checksum (file, ptr, *idx, code | 0x1000);
+ *idx = 16;
+ i = *idx / 8;
+ }
+
+ if (size == 0)
+ {
+ /* Variable length string */
+ size = strlen (string);
+ ptr[i++] = size;
+ }
+
+ /* BUG WAITING TO HAPPEN */
+ memcpy (ptr + i, string, size);
+ i += size;
+ *idx = i * 8;
+}
+
+#define SYSROFF_SWAP_OUT
+#include "sysroff.c"
+
+
+static char *rname_sh[] =
+{
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
+};
+
+static char *rname_h8300[] =
+{
+ "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
+};
+
+static void
+wr_tr ()
+{
+ /* The TR block is not normal - it doesn't have any contents. */
+
+ static char b[] = {
+ 0xff, /* IT */
+ 0x03, /* RL */
+ 0xfd, /* CS */
+ };
+ fwrite (b, 1, sizeof (b), file);
+}
+
+static void
+wr_un (ptr, sfile, first, nsecs)
+ struct coff_ofile *ptr;
+ struct coff_sfile *sfile;
+ int first;
+ int nsecs;
+{
+ struct IT_un un;
+
+ struct coff_symbol *s;
+
+ un.spare1 = 0;
+
+ if (bfd_get_file_flags (abfd) & EXEC_P)
+ un.format = FORMAT_LM;
+ else
+ un.format = FORMAT_OM;
+ un.spare1 = 0;
+
+
+#if 1
+ 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 */
+
+ if (first)
+ {
+ for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
+ {
+ if (s->visible->type == coff_vis_ext_def
+ || s->visible->type == coff_vis_common)
+ un.nextdefs++;
+
+ if (s->visible->type == coff_vis_ext_ref)
+ un.nextrefs++;
+ }
+ }
+ un.tool = toolname;
+ un.tcd = DATE;
+ un.linker = "L_GX00";
+ un.lcd = DATE;
+ un.name = sfile->name;
+ sysroff_swap_un_out (file, &un);
+}
+
+
+static void
+wr_hd (p)
+ struct coff_ofile *p;
+{
+ struct IT_hd hd;
+
+ hd.spare1 = 0;
+ if (bfd_get_file_flags (abfd) & EXEC_P)
+ {
+ hd.mt = MTYPE_ABS_LM;
+ }
+ else
+ {
+ hd.mt = MTYPE_OMS_OR_LMS;
+ }
+ hd.cd = DATE;
+
+ hd.nu = p->nsources; /* Always one unit */
+ hd.code = 0; /* Always ASCII */
+ hd.ver = "0200"; /* Version 2.00 */
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_h8300:
+ hd.au = 8;
+ hd.si = 0;
+ hd.spcsz = 32;
+ hd.segsz = 0;
+ hd.segsh = 0;
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_h8300:
+ hd.cpu = "H8300";
+ hd.afl = 2;
+ addrsize = 2;
+ toolname = "C_H8/300";
+ break;
+ case bfd_mach_h8300h:
+ hd.cpu = "H8300H";
+ hd.afl = 4;
+ addrsize = 4;
+ toolname = "C_H8/300H";
+ break;
+ case bfd_mach_h8300s:
+ hd.cpu = "H8300S";
+ hd.afl = 4;
+ addrsize = 4;
+ toolname = "C_H8/300S";
+ break;
+ default:
+ abort();
+ }
+ rnames = rname_h8300;
+ break;
+ case bfd_arch_sh:
+ hd.au = 8;
+ hd.si = 0;
+ hd.afl = 4;
+ hd.spcsz = 32;
+ hd.segsz = 0;
+ hd.segsh = 0;
+ hd.cpu = "SH";
+ addrsize = 4;
+ toolname = "C_SH";
+ rnames = rname_sh;
+ break;
+ default:
+ abort ();
+ }
+
+ if (! bfd_get_file_flags(abfd) & EXEC_P)
+ {
+ hd.ep = 0;
+ }
+ else
+ {
+ hd.ep = 1;
+ hd.uan = 0;
+ hd.sa = 0;
+ hd.sad = 0;
+ hd.address = bfd_get_start_address (abfd);
+ }
+
+ hd.os = "";
+ hd.sys = "";
+ hd.mn = strip_suffix (bfd_get_filename (abfd));
+
+ sysroff_swap_hd_out (file, &hd);
+}
+
+
+static void
+wr_sh (p, sec)
+ struct coff_ofile *p;
+ struct coff_section *sec;
+{
+ struct IT_sh sh;
+ sh.unit = 0;
+ sh.section = sec->number;
+#ifdef FOOP1
+ sh.section = 0;
+#endif
+ sysroff_swap_sh_out (file, &sh);
+}
+
+
+static void
+wr_ob (p, section)
+ struct coff_ofile *p;
+ struct coff_section *section;
+{
+ bfd_size_type i;
+ int first = 1;
+ unsigned char stuff[200];
+
+ i = 0;
+ 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->bfd_section->_raw_size)
+ todo = section->bfd_section->_raw_size - i;
+
+ if (first)
+ {
+ ob.saf = 1;
+ if (bfd_get_file_flags (abfd) & EXEC_P)
+ ob.address = section->address;
+ else
+ ob.address = 0;
+
+ first = 0;
+ }
+ else
+ {
+ ob.saf = 0;
+ }
+
+ ob.cpf = 0; /* Never compress */
+ 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 */ );
+ i += todo;
+ }
+ /* Now fill the rest with blanks */
+ while (i < (bfd_size_type) section->size)
+ {
+ struct IT_ob ob;
+ int todo = 200; /* Copy in 200 byte lumps */
+ ob.spare = 0;
+ if (i + todo > (bfd_size_type) 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
+wr_rl (ptr, sec)
+ struct coff_ofile *ptr;
+ struct coff_section *sec;
+{
+ int nr = sec->nrelocs;
+ int i;
+ for (i = 0; i < nr; i++)
+ {
+ struct coff_reloc *r = sec->relocs + i;
+ struct coff_symbol *ref;
+ struct IT_rl rl;
+ rl.apol = 0;
+ rl.boundary = 0;
+ rl.segment = 1;
+ rl.sign = 0;
+ rl.check = 0;
+ rl.addr = r->offset;
+ rl.bitloc = 0;
+ rl.flen = 32; /* SH Specific */
+ /* What sort of reloc ? Look in the section to find out */
+ ref = r->symbol;
+ if (ref->visible->type == coff_vis_ext_ref)
+ {
+ rl.bcount = 4; /* Always 4 for us */
+ rl.op = OP_EXT_REF;
+ rl.symn = ref->er_number;
+ }
+ else if (ref->visible->type == coff_vis_common)
+ {
+ rl.bcount = 11; /* Always 11 for us */
+ rl.op = OP_SEC_REF;
+ rl.secn = ref->where->section->number;
+ rl.copcode_is_3 = 3;
+ rl.alength_is_4 = 4;
+ rl.addend = ref->where->offset - ref->where->section->address;
+ rl.aopcode_is_0x20 = 0x20;
+ }
+
+ else
+ {
+ rl.bcount = 11; /* Always 11 for us */
+ rl.op = OP_SEC_REF;
+ rl.secn = ref->where->section->number;
+ rl.copcode_is_3 = 3;
+ rl.alength_is_4 = 4;
+ rl.addend = -ref->where->section->address;
+ rl.aopcode_is_0x20 = 0x20;
+ }
+ rl.end = 0xff;
+ if (rl.op == OP_SEC_REF
+ || rl.op == OP_EXT_REF)
+ {
+ sysroff_swap_rl_out (file, &rl);
+ }
+ }
+}
+
+static void
+wr_object_body (p)
+ struct coff_ofile *p;
+{
+ int i;
+ for (i = 1; i < p->nsections; i++)
+ {
+ wr_sh (p, p->sections + i);
+ wr_ob (p, p->sections + i);
+ wr_rl (p, p->sections + i);
+ }
+}
+
+static void
+wr_dps_start (sfile, section, scope, type, nest)
+ struct coff_sfile *sfile;
+ struct coff_section *section;
+ struct coff_scope *scope;
+ int type;
+ int nest;
+{
+ struct IT_dps dps;
+ dps.end = 0;
+ dps.opt = 0;
+ dps.type = type;
+ if (scope->sec)
+ {
+ dps.san = scope->sec->number;
+ dps.address = scope->offset - find_base (sfile, scope->sec);
+ dps.block_size = scope->size;
+ if (debug)
+ {
+ printf ("DPS %s %d %x\n",
+ sfile->name,
+ nest,
+ dps.address);
+
+ }
+ }
+ else
+ {
+ dps.san = 0;
+ dps.address = 0;
+ dps.block_size = 0;
+ }
+
+ dps.nesting = nest;
+ dps.neg = 0x1001;
+ sysroff_swap_dps_out (file, &dps);
+}
+
+static void
+wr_dps_end (section, scope, type)
+ struct coff_section *section;
+ struct coff_scope *scope;
+ int type;
+{
+ struct IT_dps dps;
+ dps.end = 1;
+ dps.type = type;
+ sysroff_swap_dps_out (file, &dps);
+}
+
+static int *
+nints (x)
+ int x;
+{
+ return (int *) (xcalloc (sizeof (int), x));
+}
+
+static void walk_tree_symbol ();
+static void
+walk_tree_type_1 (sfile, symbol, type, nest)
+ struct coff_sfile *sfile;
+ struct coff_symbol *symbol;
+ struct coff_type *type;
+ int nest;
+{
+ switch (type->type)
+ {
+ case coff_secdef_type:
+ case coff_basic_type:
+ {
+ struct IT_dbt dbt;
+
+ switch (type->u.basic)
+ {
+ case T_NULL:
+ case T_VOID:
+ dbt.btype = BTYPE_VOID;
+ dbt.sign = BTYPE_UNSPEC;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ break;
+ case T_CHAR:
+ dbt.btype = BTYPE_CHAR;
+ dbt.sign = BTYPE_UNSPEC;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ break;
+ case T_SHORT:
+ case T_INT:
+ case T_LONG:
+ dbt.btype = BTYPE_INT;
+ dbt.sign = SIGN_SIGNED;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ break;
+ case T_FLOAT:
+ dbt.btype = BTYPE_FLOAT;
+ dbt.fptype = FPTYPE_SINGLE;
+ break;
+ case T_DOUBLE:
+ dbt.btype = BTYPE_FLOAT;
+ dbt.fptype = FPTYPE_DOUBLE;
+ break;
+ case T_LNGDBL:
+ dbt.btype = BTYPE_FLOAT;
+ dbt.fptype = FPTYPE_EXTENDED;
+ break;
+ case T_UCHAR:
+ dbt.btype = BTYPE_CHAR;
+ dbt.sign = SIGN_UNSIGNED;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ break;
+ case T_USHORT:
+ case T_UINT:
+ case T_ULONG:
+ dbt.btype = BTYPE_INT;
+ dbt.sign = SIGN_UNSIGNED;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ break;
+ }
+ dbt.bitsize = type->size;
+ dbt.neg = 0x1001;
+ sysroff_swap_dbt_out (file, &dbt);
+ break;
+ }
+ case coff_pointer_type:
+ {
+ struct IT_dpt dpt;
+ walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1);
+ dpt.neg = 0x1001;
+ sysroff_swap_dpt_out (file, &dpt);
+ break;
+ }
+
+ case coff_function_type:
+ {
+ struct IT_dfp dfp;
+ struct coff_symbol *param;
+ dfp.end = 0;
+ dfp.spare = 0;
+ dfp.nparams = type->u.function.parameters->nvars;
+ dfp.neg = 0x1001;
+
+ walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1);
+
+ sysroff_swap_dfp_out (file, &dfp);
+
+ for (param = type->u.function.parameters->vars_head;
+ param;
+ param = param->next)
+ {
+ walk_tree_symbol (sfile, 0, param, nest);
+ }
+ dfp.end = 1;
+ sysroff_swap_dfp_out (file, &dfp);
+ break;
+ }
+
+ case coff_structdef_type:
+ {
+ struct IT_dbt dbt;
+ struct IT_dds dds;
+ struct coff_symbol *member;
+ dds.spare = 0;
+ dbt.btype = BTYPE_STRUCT;
+ dbt.bitsize = type->size;
+ dbt.sign = SIGN_UNSPEC;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ dbt.sid = get_member_id (type->u.astructdef.idx);
+ dbt.neg = 0x1001;
+ sysroff_swap_dbt_out (file, &dbt);
+ dds.end = 0;
+ dds.neg = 0x1001;
+ sysroff_swap_dds_out (file, &dds);
+ for (member = type->u.astructdef.elements->vars_head;
+ member;
+ member = member->next)
+ {
+ walk_tree_symbol (sfile, 0, member, nest + 1);
+ }
+
+ dds.end = 1;
+ sysroff_swap_dds_out (file, &dds);
+
+ }
+ break;
+ case coff_structref_type:
+ {
+ struct IT_dbt dbt;
+ dbt.btype = BTYPE_TAG;
+ dbt.bitsize = type->size;
+ dbt.sign = SIGN_UNSPEC;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ if (type->u.astructref.ref)
+ {
+ dbt.sid = get_member_id (type->u.astructref.ref->number);
+ }
+ else
+ {
+ dbt.sid = 0;
+ }
+
+ dbt.neg = 0x1001;
+ sysroff_swap_dbt_out (file, &dbt);
+ }
+ break;
+ case coff_array_type:
+ {
+ struct IT_dar dar;
+ int j;
+ int dims = 1; /* Only output one dimension at a time */
+ dar.dims = dims;
+ dar.variable = nints (dims);
+ dar.subtype = nints (dims);
+ dar.spare = nints (dims);
+ dar.max_variable = nints (dims);
+ dar.maxspare = nints (dims);
+ dar.max = nints (dims);
+ dar.min_variable = nints (dims);
+ dar.min = nints (dims);
+ dar.minspare = nints (dims);
+ dar.neg = 0x1001;
+ dar.length = type->size / type->u.array.dim;
+ for (j = 0; j < dims; j++)
+ {
+ dar.variable[j] = VARIABLE_FIXED;
+ dar.subtype[j] = SUB_INTEGER;
+ dar.spare[j] = 0;
+ dar.max_variable[j] = 0;
+ dar.max[j] = type->u.array.dim;
+ dar.min_variable[j] = 0;
+ dar.min[j] = 1; /* Why isn't this 0 ? */
+ }
+ walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1);
+ sysroff_swap_dar_out (file, &dar);
+ }
+ break;
+ case coff_enumdef_type:
+ {
+ struct IT_dbt dbt;
+ struct IT_den den;
+ struct coff_symbol *member;
+ dbt.btype = BTYPE_ENUM;
+ dbt.bitsize = type->size;
+ dbt.sign = SIGN_UNSPEC;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ dbt.sid = get_member_id (type->u.aenumdef.idx);
+ dbt.neg = 0x1001;
+ sysroff_swap_dbt_out (file, &dbt);
+
+ den.end = 0;
+ den.neg = 0x1001;
+ den.spare = 0;
+ sysroff_swap_den_out (file, &den);
+ for (member = type->u.aenumdef.elements->vars_head;
+ member;
+ member = member->next)
+ {
+ walk_tree_symbol (sfile, 0, member, nest + 1);
+ }
+
+ den.end = 1;
+ sysroff_swap_den_out (file, &den);
+ }
+ break;
+
+ break;
+ case coff_enumref_type:
+ {
+ struct IT_dbt dbt;
+ dbt.btype = BTYPE_TAG;
+ dbt.bitsize = type->size;
+ dbt.sign = SIGN_UNSPEC;
+ dbt.fptype = FPTYPE_NOTSPEC;
+ dbt.sid = get_member_id (type->u.aenumref.ref->number);
+ dbt.neg = 0x1001;
+ sysroff_swap_dbt_out (file, &dbt);
+ }
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* 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)
+
+ struct
+ coff_sfile *sfile;
+ struct coff_symbol *symbol;
+ struct coff_type *type;
+ int nest;
+{
+ if (symbol->type->type == coff_function_type)
+ {
+
+ struct IT_dty dty;
+ dty.end = 0;
+ dty.neg = 0x1001;
+
+ sysroff_swap_dty_out (file, &dty);
+ walk_tree_type_1 (sfile, symbol, type, nest);
+ dty.end = 1;
+ sysroff_swap_dty_out (file, &dty);
+
+ wr_dps_start (sfile,
+ symbol->where->section,
+ symbol->type->u.function.code,
+ BLOCK_TYPE_FUNCTION, nest);
+ wr_dps_start (sfile, symbol->where->section,
+ symbol->type->u.function.code,
+ BLOCK_TYPE_BLOCK, nest);
+ walk_tree_scope (symbol->where->section,
+ sfile,
+ symbol->type->u.function.code,
+ nest + 1, BLOCK_TYPE_BLOCK);
+
+ wr_dps_end (symbol->where->section,
+ symbol->type->u.function.code,
+ BLOCK_TYPE_BLOCK);
+ wr_dps_end (symbol->where->section,
+ symbol->type->u.function.code, BLOCK_TYPE_FUNCTION);
+
+ }
+ else
+ {
+ struct IT_dty dty;
+ dty.end = 0;
+ dty.neg = 0x1001;
+ sysroff_swap_dty_out (file, &dty);
+ walk_tree_type_1 (sfile, symbol, type, nest);
+ dty.end = 1;
+ sysroff_swap_dty_out (file, &dty);
+ }
+
+}
+
+
+
+static void
+walk_tree_symbol (sfile, section, symbol, nest)
+ struct coff_sfile *sfile;
+ struct coff_section *section;
+ struct coff_symbol *symbol;
+ int nest;
+{
+ struct IT_dsy dsy;
+
+ memset(&dsy, 0, sizeof(dsy));
+ dsy.nesting = nest;
+
+ switch (symbol->type->type)
+ {
+ case coff_function_type:
+ dsy.type = STYPE_FUNC;
+ dsy.assign = 1;
+ break;
+ case coff_structref_type:
+ case coff_pointer_type:
+ case coff_array_type:
+ case coff_basic_type:
+ case coff_enumref_type:
+ dsy.type = STYPE_VAR;
+ dsy.assign = 1;
+ break;
+ case coff_enumdef_type:
+ dsy.type = STYPE_TAG;
+ dsy.assign = 0;
+ dsy.magic = 2;
+ break;
+ case coff_structdef_type:
+ dsy.type = STYPE_TAG;
+ dsy.assign = 0;
+ dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1;
+ break;
+ case coff_secdef_type:
+ return;
+ default:
+ abort ();
+ }
+
+ if (symbol->where->where == coff_where_member_of_struct)
+ {
+ dsy.assign = 0;
+ dsy.type = STYPE_MEMBER;
+ }
+ if (symbol->where->where == coff_where_member_of_enum)
+ {
+ dsy.type = STYPE_ENUM;
+ dsy.assign = 0;
+ dsy.evallen = 4;
+ dsy.evalue = symbol->where->offset;
+ }
+
+ if (symbol->type->type == coff_structdef_type
+ || symbol->where->where == coff_where_entag
+ || symbol->where->where == coff_where_strtag)
+ {
+ dsy.snumber = get_member_id (symbol->number);
+ }
+ else
+ {
+ dsy.snumber = get_ordinary_id (symbol->number);
+ }
+
+
+ dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name;
+
+ switch (symbol->visible->type)
+ {
+ case coff_vis_common:
+ case coff_vis_ext_def:
+ dsy.ainfo = AINFO_STATIC_EXT_DEF;
+ break;
+ case coff_vis_ext_ref:
+ dsy.ainfo = AINFO_STATIC_EXT_REF;
+ break;
+ case coff_vis_int_def:
+ dsy.ainfo = AINFO_STATIC_INT;
+ break;
+ case coff_vis_auto:
+ case coff_vis_autoparam:
+ dsy.ainfo = AINFO_AUTO;
+ break;
+ case coff_vis_register:
+ case coff_vis_regparam:
+ dsy.ainfo = AINFO_REG;
+ break;
+ break;
+ case coff_vis_tag:
+ case coff_vis_member_of_struct:
+ case coff_vis_member_of_enum:
+ break;
+ default:
+ abort ();
+ }
+
+ dsy.dlength = symbol->type->size;
+ switch (symbol->where->where)
+ {
+ case coff_where_memory:
+
+ dsy.section = symbol->where->section->number;
+#ifdef FOOP
+ dsy.section = 0;
+#endif
+ break;
+ case coff_where_member_of_struct:
+ case coff_where_member_of_enum:
+ case coff_where_stack:
+ case coff_where_register:
+ case coff_where_unknown:
+ case coff_where_strtag:
+
+ case coff_where_entag:
+ case coff_where_typedef:
+ break;
+ default:
+ abort ();
+ }
+
+ switch (symbol->where->where)
+ {
+ case coff_where_memory:
+ dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section);
+ break;
+ case coff_where_stack:
+ dsy.address = symbol->where->offset;
+ break;
+ case coff_where_member_of_struct:
+
+
+ if (symbol->where->bitsize)
+ {
+ int bits = (symbol->where->offset * 8 + symbol->where->bitoffset);
+ dsy.bitunit = 1;
+ dsy.field_len = symbol->where->bitsize;
+ dsy.field_off = (bits / 32) * 4;
+ dsy.field_bitoff = bits % 32;
+ }
+ else
+ {
+ dsy.bitunit = 0;
+
+ dsy.field_len = symbol->type->size;
+ dsy.field_off = symbol->where->offset;
+ }
+ break;
+ case coff_where_member_of_enum:
+ /* dsy.bitunit = 0;
+ dsy.field_len = symbol->type->size;
+ dsy.field_off = symbol->where->offset; */
+ break;
+ case coff_where_register:
+ case coff_where_unknown:
+ case coff_where_strtag:
+
+ case coff_where_entag:
+ case coff_where_typedef:
+ break;
+ default:
+ abort ();
+ }
+
+ if (symbol->where->where == coff_where_register)
+ dsy.reg = rnames[symbol->where->offset];
+
+ switch (symbol->visible->type)
+ {
+ case coff_vis_common:
+ /* We do this 'cause common C symbols are treated as extdefs */
+ case coff_vis_ext_def:
+ case coff_vis_ext_ref:
+
+ dsy.ename = symbol->name;
+ break;
+
+ case coff_vis_regparam:
+ case coff_vis_autoparam:
+ dsy.type = STYPE_PARAMETER;
+ break;
+
+ case coff_vis_int_def:
+
+ case coff_vis_auto:
+ case coff_vis_register:
+ case coff_vis_tag:
+ case coff_vis_member_of_struct:
+ case coff_vis_member_of_enum:
+ break;
+ default:
+ abort ();
+ }
+
+ dsy.sfn = 0;
+ dsy.sln = 2;
+
+ dsy.neg = 0x1001;
+
+
+ sysroff_swap_dsy_out (file, &dsy);
+
+ walk_tree_type (sfile, symbol, symbol->type, nest);
+}
+
+
+static void
+walk_tree_scope (section, sfile, scope, nest, type)
+ struct coff_section *section;
+ struct coff_sfile *sfile;
+ struct coff_scope *scope;
+ int nest;
+ int type;
+{
+ struct coff_symbol *vars;
+ struct coff_scope *child;
+
+ if (scope->vars_head
+ || (scope->list_head && scope->list_head->vars_head))
+ {
+ wr_dps_start (sfile, section, scope, type, nest);
+
+ if (nest == 0)
+ wr_globals (tree, sfile, nest + 1);
+
+ for (vars = scope->vars_head; vars; vars = vars->next)
+ {
+ walk_tree_symbol (sfile, section, vars, nest);
+ }
+
+ for (child = scope->list_head; child; child = child->next)
+ {
+ walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK);
+ }
+
+ wr_dps_end (section, scope, type);
+ }
+}
+static void
+walk_tree_sfile (section, sfile)
+ struct coff_section *section;
+ struct coff_sfile *sfile;
+{
+ walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT);
+
+}
+
+static void
+wr_program_structure (p, sfile)
+ struct coff_ofile *p;
+ struct coff_sfile *sfile;
+{
+
+ walk_tree_sfile (p->sections + 4, sfile);
+
+}
+
+static void
+wr_du (p, sfile, n)
+ struct coff_ofile *p;
+ struct coff_sfile *sfile;
+ int n;
+{
+ struct IT_du du;
+ int lim;
+#if 0
+ struct coff_symbol *symbol;
+ static int incit = 0x500000;
+ int used = 0;
+#endif
+ int i;
+ int j;
+ unsigned int *lowest = (unsigned *) nints (p->nsections);
+ unsigned int *highest = (unsigned *) nints (p->nsections);
+ du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1;
+ du.optimized = 0;
+ du.stackfrmt = 0;
+ du.spare = 0;
+ du.unit = n;
+ du.sections = p->nsections - 1;
+ du.san = (int *) xcalloc (sizeof (int), du.sections);
+ du.address = nints (du.sections);
+ du.length = nints (du.sections);
+
+ for (i = 0; i < du.sections; i++)
+ {
+ lowest[i] = ~0;
+ highest[i] = 0;
+ }
+
+ /* Look through all the symbols and try and work out the extents in this
+ source file */
+#if 0
+ for (symbol = sfile->scope->vars_head;
+ symbol;
+ symbol = symbol->next)
+ {
+ if (symbol->type->type == coff_secdef_type)
+ {
+ unsigned int low = symbol->where->offset;
+ unsigned int high = symbol->where->offset + symbol->type->size - 1;
+ struct coff_section *section = symbol->where->section;
+
+ int sn = section->number;
+ if (low < lowest[sn])
+ lowest[sn] = low;
+ if (high > highest[sn])
+ highest[sn] = high;
+ }
+ }
+
+
+ for (i = 0; i < du.sections; i++)
+ {
+ if (highest[i] == 0)
+ {
+ lowest[i] = highest[i] = incit;
+ }
+ du.san[used] = i;
+ du.length[used] = highest[i] - lowest[i];
+ du.address[used] = bfd_get_file_flags (abfd) & EXEC_P ? lowest[i] : 0;
+ if (debug)
+ {
+ printf (" section %6s 0x%08x..0x%08x\n",
+ p->sections[i + 1].name,
+ lowest[i],
+ highest[i]);
+ }
+ used++;
+ }
+
+#endif
+ lim = du.sections;
+ for (j = 0; j < lim; j++)
+ {
+ int src = j;
+ int dst = j;
+ du.san[dst] = dst;
+ if (sfile->section[src].init)
+ {
+ du.length[dst]
+ = sfile->section[src].high - sfile->section[src].low + 1;
+ du.address[dst]
+ = sfile->section[src].low;
+ }
+ else
+ {
+ du.length[dst] = 0;
+ du.address[dst] = 0;
+ }
+ if (debug)
+ {
+ if (sfile->section[src].parent)
+ {
+ printf (" section %6s 0x%08x..0x%08x\n",
+ sfile->section[src].parent->name,
+ du.address[dst],
+ du.address[dst] + du.length[dst] - 1);
+ }
+ }
+ du.sections = dst + 1;
+ }
+
+ du.tool = "c_gcc";
+ du.date = DATE;
+
+ sysroff_swap_du_out (file, &du);
+}
+
+static void
+wr_dus (p, sfile)
+ struct coff_ofile *p;
+ struct coff_sfile *sfile;
+{
+
+ struct IT_dus dus;
+
+ dus.efn = 0x1001;
+ dus.ns = 1; /* p->nsources; sac 14 jul 94 */
+ dus.drb = nints (dus.ns);
+ dus.fname = (char **) xcalloc (sizeof (char *), dus.ns);
+ dus.spare = nints (dus.ns);
+ dus.ndir = 0;
+ /* Find the filenames */
+#if 0
+ i = 0;
+
+ for (sfile = p->source_head;
+ sfile;
+ sfile = sfile->next)
+ {
+ dus.drb[i] = 0;
+ dus.spare[i] = 0;
+ dus.fname[i] = sfile->name;
+ i++;
+ }
+#else
+ dus.drb[0] = 0;
+ dus.fname[0] = sfile->name;
+#endif
+
+ sysroff_swap_dus_out (file, &dus);
+
+}
+
+/* Find the offset of the .text section for this sfile in the
+ .text section for the output file */
+
+static int
+find_base (sfile, section)
+ struct coff_sfile *sfile;
+ struct coff_section *section;
+{
+ return sfile->section[section->number].low;
+}
+static void
+wr_dln (p, sfile, n)
+ struct coff_ofile *p;
+ struct coff_sfile *sfile;
+ int n;
+
+{
+#if 0
+ if (n == 0)
+ {
+ /* Count up all the linenumbers */
+ struct coff_symbol *sy;
+ int lc = 0;
+ struct IT_dln dln;
+
+ int idx;
+
+ for (sy = p->symbol_list_head;
+ sy;
+ sy = sy->next_in_ofile_list)
+ {
+ struct coff_type *t = sy->type;
+ if (t->type == coff_function_type)
+ {
+ struct coff_line *l = t->u.function.lines;
+ lc += l->nlines;
+ }
+ }
+
+ dln.sfn = nints (lc);
+ dln.sln = nints (lc);
+ dln.lln = nints (lc);
+ dln.section = nints (lc);
+
+ dln.from_address = nints (lc);
+ dln.to_address = nints (lc);
+
+
+ dln.neg = 0x1001;
+
+ dln.nln = lc;
+
+ /* Run through once more and fill up the structure */
+ idx = 0;
+ for (sy = p->symbol_list_head;
+ sy;
+ sy = sy->next_in_ofile_list)
+ {
+ if (sy->type->type == coff_function_type)
+ {
+ int i;
+ struct coff_line *l = sy->type->u.function.lines;
+ for (i = 0; i < l->nlines; i++)
+ {
+ dln.section[idx] = sy->where->section->number;
+ dln.sfn[idx] = n;
+ dln.sln[idx] = l->lines[i];
+ dln.from_address[idx] = l->addresses[i];
+ if (idx)
+ dln.to_address[idx - 1] = dln.from_address[idx];
+ idx++;
+ }
+ }
+ n++;
+ }
+ sysroff_swap_dln_out (file, &dln);
+ }
+
+#endif
+#if 1
+ /* Count up all the linenumbers */
+
+ struct coff_symbol *sy;
+ int lc = 0;
+ struct IT_dln dln;
+
+ int idx;
+
+ for (sy = sfile->scope->vars_head;
+ sy;
+ sy = sy->next)
+ {
+ struct coff_type *t = sy->type;
+ if (t->type == coff_function_type)
+ {
+ struct coff_line *l = t->u.function.lines;
+ if (l)
+ lc += l->nlines;
+ }
+ }
+
+ dln.sfn = nints (lc);
+ dln.sln = nints (lc);
+ dln.cc = nints (lc);
+ dln.section = nints (lc);
+
+ dln.from_address = nints (lc);
+ dln.to_address = nints (lc);
+
+
+ dln.neg = 0x1001;
+
+ dln.nln = lc;
+
+ /* Run through once more and fill up the structure */
+ idx = 0;
+ for (sy = sfile->scope->vars_head;
+ sy;
+ sy = sy->next)
+ {
+ if (sy->type->type == coff_function_type)
+ {
+ int i;
+ struct coff_line *l = sy->type->u.function.lines;
+ if (l)
+ {
+ int base = find_base (sfile, sy->where->section);
+ for (i = 0; i < l->nlines; i++)
+ {
+ dln.section[idx] = sy->where->section->number;
+ dln.sfn[idx] = 0;
+ dln.sln[idx] = l->lines[i];
+ dln.from_address[idx] =
+ l->addresses[i] + sy->where->section->address - base;
+ dln.cc[idx] = 0;
+ if (idx)
+ dln.to_address[idx - 1] = dln.from_address[idx];
+ idx++;
+
+ }
+ dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2;
+ }
+ }
+ }
+ if (lc)
+ sysroff_swap_dln_out (file, &dln);
+#endif
+}
+
+/* Write the global symbols out to the debug info */
+static void
+wr_globals (p, sfile, n)
+ struct coff_ofile *p;
+ struct coff_sfile *sfile;
+ int n;
+{
+ struct coff_symbol *sy;
+ for (sy = p->symbol_list_head;
+ sy;
+ sy = sy->next_in_ofile_list)
+ {
+ if (sy->visible->type == coff_vis_ext_def
+ || sy->visible->type == coff_vis_ext_ref)
+ {
+ /* Only write out symbols if they belong to
+ the current source file */
+ if (sy->sfile == sfile)
+ walk_tree_symbol (sfile, 0, sy, 0);
+
+ }
+ }
+}
+
+static void
+wr_debug (p)
+ struct coff_ofile *p;
+{
+ struct coff_sfile *sfile;
+ int n = 0;
+ for (sfile = p->source_head;
+ sfile;
+ sfile = sfile->next)
+
+ {
+ if (debug)
+ {
+ printf ("%s\n", sfile->name);
+ }
+ wr_du (p, sfile, n);
+ wr_dus (p, sfile);
+ wr_program_structure (p, sfile);
+ wr_dln (p, sfile, n);
+ n++;
+ }
+}
+
+static void
+wr_cs ()
+{
+ /* It seems that the CS struct is not normal - the size is wrong
+ heres one I prepared earlier.. */
+ static char b[] = {
+ 0x80, /* IT */
+ 0x21, /* RL */
+ 0x00, /* number of chars in variable length part */
+ 0x80, /* hd */
+ 0x00, /* hs */
+ 0x80, /* un */
+ 0x00, /* us */
+ 0x80, /* sc */
+ 0x00, /* ss */
+ 0x80, /* er */
+ 0x80, /* ed */
+ 0x80, /* sh */
+ 0x80, /* ob */
+ 0x80, /* rl */
+ 0x80, /* du */
+ 0x80, /* dps */
+ 0x80, /* dsy */
+ 0x80, /* dty */
+ 0x80, /* dln */
+ 0x80, /* dso */
+ 0x80, /* dus */
+ 0x00, /* dss */
+ 0x80, /* dbt */
+ 0x00, /* dpp */
+ 0x80, /* dfp */
+ 0x80, /* den */
+ 0x80, /* dds */
+ 0x80, /* dar */
+ 0x80, /* dpt */
+ 0x00, /* dul */
+ 0x00, /* dse */
+ 0x00, /* dot */
+ 0xDE /* CS */
+ };
+ fwrite (b, 1, sizeof (b), file);
+}
+
+/* Write out the SC records for a unit. Create an SC
+ for all the sections which appear in the output file, even
+ if there isn't an equivalent one on the input */
+
+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;
+
+ struct myinfo
+ {
+ struct coff_section *sec;
+ struct coff_symbol *symbol;
+ };
+ struct coff_symbol *symbol;
+
+ struct myinfo *info
+ = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
+
+
+
+ for (i = 0; i < total_sec; i++)
+ {
+ info[i].sec = ptr->sections + i;
+ info[i].symbol = 0;
+ }
+
+ for (symbol = sfile->scope->vars_head;
+ symbol;
+ symbol = symbol->next)
+ {
+
+ if (symbol->type->type == coff_secdef_type)
+ {
+ for (i = 0; i < total_sec; i++)
+ {
+ if (symbol->where->section == info[i].sec)
+ {
+ info[i].symbol = symbol;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Now output all the section info, and fake up some stuff for sections
+ we don't have */
+
+ for (i = 1; i < total_sec; i++)
+ {
+ struct IT_sc sc;
+ char *name;
+ symbol = info[i].symbol;
+ sc.spare = 0;
+ sc.spare1 = 0;
+ if (!symbol)
+ {
+ /* Don't have a symbol set aside for this section, which means that nothing
+ in this file does anything for the section. */
+ sc.format = !(bfd_get_file_flags (abfd) & EXEC_P);
+ sc.addr = 0;
+ sc.length = 0;
+ name = info[i].sec->name;
+ }
+ else
+ {
+ if (bfd_get_file_flags (abfd) & EXEC_P)
+ {
+ sc.format = 0;
+ sc.addr = symbol->where->offset;
+ }
+ else
+ {
+ sc.format = 1;
+ sc.addr = 0;
+ }
+ sc.length = symbol->type->size;
+ name = symbol->name;
+ }
+
+ sc.align = 4;
+
+ sc.concat = CONCAT_SIMPLE;
+ sc.read = 3;
+ sc.write = 3;
+ sc.exec = 3;
+ sc.init = 3;
+ sc.mode = 3;
+ sc.spare = 0;
+ sc.segadd = 0;
+ sc.spare1 = 0; /* If not zero, then it doesn't work */
+ sc.name = section_translate (name);
+ if (strlen (sc.name) == 1)
+ {
+ switch (sc.name[0])
+ {
+ case 'D':
+ case 'B':
+ sc.contents = CONTENTS_DATA;
+ break;
+ default:
+ sc.contents = CONTENTS_CODE;
+ }
+ }
+ else
+ {
+ sc.contents = CONTENTS_CODE;
+ }
+#if 0
+ /* NEW */
+ if (sc.length) {
+#endif
+ sysroff_swap_sc_out (file, &sc);
+ scount++;
+#if 0
+ }
+#endif
+ }
+return scount;
+}
+
+
+/* Write out the ER records for a unit. */
+static void
+wr_er (ptr, sfile, first)
+ struct coff_ofile *ptr;
+ struct coff_sfile *sfile;
+ int first;
+{
+ int idx = 0;
+ struct coff_symbol *sym;
+ if (first)
+ {
+ for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list)
+ {
+ if (sym->visible->type == coff_vis_ext_ref)
+ {
+ struct IT_er er;
+ er.spare = 0;
+ er.type = ER_NOTSPEC;
+ er.name = sym->name;
+ sysroff_swap_er_out (file, &er);
+ sym->er_number = idx++;
+ }
+ }
+ }
+}
+
+/* Write out the ED records for a unit. */
+static void
+wr_ed (ptr, sfile, first)
+ struct coff_ofile *ptr;
+ struct coff_sfile *sfile;
+ int first;
+{
+ struct coff_symbol *s;
+ if (first)
+ {
+ for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
+ {
+ if (s->visible->type == coff_vis_ext_def
+ || s->visible->type == coff_vis_common)
+ {
+ struct IT_ed ed;
+
+ ed.section = s->where->section->number;
+ ed.spare = 0;
+ if (s->where->section->data)
+ {
+ ed.type = ED_TYPE_DATA;
+ }
+ else if (s->where->section->code & SEC_CODE)
+ {
+ ed.type = ED_TYPE_ENTRY;
+ }
+ else
+ {
+ ed.type = ED_TYPE_NOTSPEC;
+ ed.type = ED_TYPE_DATA;
+ }
+ ed.address = s->where->offset - s->where->section->address;
+ ed.name = s->name;
+ sysroff_swap_ed_out (file, &ed);
+ }
+ }
+ }
+}
+
+static void
+wr_unit_info (ptr)
+ struct coff_ofile *ptr;
+{
+ struct coff_sfile *sfile;
+ int first = 1;
+ for (sfile = ptr->source_head;
+ sfile;
+ sfile = sfile->next)
+ {
+ 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, SEEK_SET);
+ wr_un (ptr, sfile, first, nsecs);
+ fseek (file, p2, SEEK_SET);
+ wr_er (ptr, sfile, first);
+ wr_ed (ptr, sfile, first);
+ first = 0;
+ }
+}
+
+static void
+wr_module (p)
+ struct coff_ofile *p;
+{
+ wr_cs ();
+ wr_hd (p);
+ wr_unit_info (p);
+ wr_object_body (p);
+ wr_debug (p);
+ wr_tr ();
+}
+
+static int
+align (x)
+ int x;
+{
+ return (x + 3) & ~3;
+}
+
+/* Find all the common variables and turn them into
+ ordinary defs - dunno why, but thats what hitachi does with 'em */
+
+static void
+prescan (tree)
+ struct coff_ofile *tree;
+{
+ struct coff_symbol *s;
+ struct coff_section *common_section;
+ /* Find the common section - always section 3 */
+ common_section = tree->sections + 3;
+ for (s = tree->symbol_list_head;
+ s;
+ s = s->next_in_ofile_list)
+ {
+ if (s->visible->type == coff_vis_common)
+ {
+ struct coff_where *w = s->where;
+ /* 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;
+ common_section->size += s->type->size;
+ common_section->size = align (common_section->size);
+ }
+ }
+}
+
+char *program_name;
+
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name);
+ exit (status);
+}
+
+static void
+show_help ()
+{
+ printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"),
+ program_name);
+ show_usage (stdout, 0);
+}
+
+
+
+int
+main (ac, av)
+ int ac;
+ char *av[];
+{
+ int opt;
+ static struct option long_options[] =
+ {
+ {"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}
+ };
+ char **matching;
+ char *input_file;
+ char *output_file;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = av[0];
+ xmalloc_set_program_name (program_name);
+
+ while ((opt = getopt_long (ac, av, "dhVqn", long_options,
+ (int *) NULL))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'q':
+ quick = 1;
+ break;
+ case 'n':
+ noprescan = 1;
+ break;
+ case 'd':
+ debug = 1;
+ break;
+ case 'h':
+ show_help ();
+ /*NOTREACHED */
+ case 'V':
+ printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
+ exit (0);
+ /*NOTREACHED */
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /*NOTREACHED */
+ }
+ }
+
+ /* The input and output files may be named on the command line. */
+ output_file = NULL;
+ if (optind < ac)
+ {
+ input_file = av[optind];
+ ++optind;
+ if (optind < ac)
+ {
+ output_file = av[optind];
+ ++optind;
+ if (optind < ac)
+ show_usage (stderr, 1);
+ if (strcmp (input_file, output_file) == 0)
+ {
+ fprintf (stderr,
+ _("%s: input and output files must be different\n"),
+ program_name);
+ exit (1);
+ }
+ }
+ }
+ else
+ input_file = 0;
+
+ if (!input_file)
+ {
+ fprintf (stderr, _("%s: no input file specified\n"),
+ program_name);
+ exit (1);
+ }
+
+ 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 */
+
+ int len = strlen (input_file);
+ output_file = xmalloc (len + 5);
+ strcpy (output_file, input_file);
+ if (len > 3
+ && output_file[len - 2] == '.'
+ && output_file[len - 1] == 'o')
+ {
+ output_file[len] = 'b';
+ output_file[len + 1] = 'j';
+ output_file[len + 2] = 0;
+ }
+ else
+ {
+ strcat (output_file, ".obj");
+ }
+ }
+
+ abfd = bfd_openr (input_file, 0);
+
+ if (!abfd)
+ bfd_fatal (input_file);
+
+ if (!bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ bfd_nonfatal (input_file);
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+ exit (1);
+ }
+
+ file = fopen (output_file, FOPEN_WB);
+
+ if (!file)
+ {
+ fprintf (stderr, _("%s: unable to open output file %s\n"),
+ program_name, output_file);
+ exit (1);
+ }
+
+ if (debug)
+ printf ("ids %d %d\n", base1, base2);
+ tree = coff_grok (abfd);
+ if (!noprescan)
+ prescan (tree);
+ wr_module (tree);
+ return 0;
+}
diff --git a/binutils/stabs.c b/binutils/stabs.c
new file mode 100644
index 00000000000..a47b3bd4cad
--- /dev/null
+++ b/binutils/stabs.c
@@ -0,0 +1,5188 @@
+/* stabs.c -- Parse stabs debugging information
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains code which parses stabs debugging information.
+ The organization of this code is based on the gdb stabs reading
+ code. The job it does is somewhat different, because it is not
+ trying to identify the correct address for anything. */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* Meaningless definition needs by aout64.h. FIXME. */
+#define BYTES_IN_WORD 4
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+
+#ifndef DIR_SEPARATOR
+#ifdef _WIN32
+#define DIR_SEPARATOR '\\'
+#else
+#define DIR_SEPARATOR '/'
+#endif
+#endif
+
+/* The number of predefined XCOFF types. */
+
+#define XCOFF_TYPE_COUNT 34
+
+/* This structure is used as a handle so that the stab parsing doesn't
+ need to use any static variables. */
+
+struct stab_handle
+{
+ /* The BFD. */
+ bfd *abfd;
+ /* True if this is stabs in sections. */
+ boolean sections;
+ /* The symbol table. */
+ asymbol **syms;
+ /* The number of symbols. */
+ long symcount;
+ /* The accumulated file name string. */
+ char *so_string;
+ /* The value of the last N_SO symbol. */
+ bfd_vma so_value;
+ /* The value of the start of the file, so that we can handle file
+ relative N_LBRAC and N_RBRAC symbols. */
+ bfd_vma file_start_offset;
+ /* The offset of the start of the function, so that we can handle
+ function relative N_LBRAC and N_RBRAC symbols. */
+ bfd_vma function_start_offset;
+ /* The version number of gcc which compiled the current compilation
+ unit, 0 if not compiled by gcc. */
+ int gcc_compiled;
+ /* Whether an N_OPT symbol was seen that was not generated by gcc,
+ so that we can detect the SunPRO compiler. */
+ boolean n_opt_found;
+ /* The main file name. */
+ char *main_filename;
+ /* A stack of unfinished N_BINCL files. */
+ struct bincl_file *bincl_stack;
+ /* A list of finished N_BINCL files. */
+ struct bincl_file *bincl_list;
+ /* Whether we are inside a function or not. */
+ boolean within_function;
+ /* The address of the end of the function, used if we have seen an
+ N_FUN symbol while in a function. This is -1 if we have not seen
+ an N_FUN (the normal case). */
+ bfd_vma function_end;
+ /* The depth of block nesting. */
+ int block_depth;
+ /* List of pending variable definitions. */
+ struct stab_pending_var *pending;
+ /* Number of files for which we have types. */
+ unsigned int files;
+ /* Lists of types per file. */
+ struct stab_types **file_types;
+ /* Predefined XCOFF types. */
+ debug_type xcoff_types[XCOFF_TYPE_COUNT];
+ /* Undefined tags. */
+ struct stab_tag *tags;
+ /* Set by parse_stab_type if it sees a structure defined as a cross
+ reference to itself. Reset by parse_stab_type otherwise. */
+ boolean self_crossref;
+};
+
+/* A list of these structures is used to hold pending variable
+ definitions seen before the N_LBRAC of a block. */
+
+struct stab_pending_var
+{
+ /* Next pending variable definition. */
+ struct stab_pending_var *next;
+ /* Name. */
+ const char *name;
+ /* Type. */
+ debug_type type;
+ /* Kind. */
+ enum debug_var_kind kind;
+ /* Value. */
+ bfd_vma val;
+};
+
+/* A list of these structures is used to hold the types for a single
+ file. */
+
+struct stab_types
+{
+ /* Next set of slots for this file. */
+ struct stab_types *next;
+ /* Types indexed by type number. */
+#define STAB_TYPES_SLOTS (16)
+ debug_type types[STAB_TYPES_SLOTS];
+};
+
+/* We keep a list of undefined tags that we encounter, so that we can
+ fill them in if the tag is later defined. */
+
+struct stab_tag
+{
+ /* Next undefined tag. */
+ struct stab_tag *next;
+ /* Tag name. */
+ const char *name;
+ /* Type kind. */
+ enum debug_type_kind kind;
+ /* Slot to hold real type when we discover it. If we don't, we fill
+ in an undefined tag type. */
+ debug_type slot;
+ /* Indirect type we have created to point at slot. */
+ debug_type type;
+};
+
+static char *savestring PARAMS ((const char *, int));
+static bfd_vma parse_number PARAMS ((const char **, boolean *));
+static void bad_stab PARAMS ((const char *));
+static void warn_stab PARAMS ((const char *, const char *));
+static boolean parse_stab_string
+ PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *));
+static debug_type parse_stab_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ debug_type **));
+static boolean parse_stab_type_number
+ PARAMS ((const char **, int *));
+static debug_type parse_stab_range_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ const int *));
+static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **));
+static debug_type parse_stab_sun_floating_type
+ PARAMS ((PTR, const char **));
+static debug_type parse_stab_enum_type PARAMS ((PTR, const char **));
+static debug_type parse_stab_struct_type
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean,
+ const int *));
+static boolean parse_stab_baseclasses
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **));
+static boolean parse_stab_struct_fields
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_field **,
+ boolean *));
+static boolean parse_stab_cpp_abbrev
+ PARAMS ((PTR, struct stab_handle *, const char **, debug_field *));
+static boolean parse_stab_one_struct_field
+ PARAMS ((PTR, struct stab_handle *, const char **, const char *,
+ debug_field *, boolean *));
+static boolean parse_stab_members
+ PARAMS ((PTR, struct stab_handle *, const char *, const char **,
+ const int *, debug_method **));
+static debug_type parse_stab_argtypes
+ PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *,
+ debug_type, const char *, boolean, boolean, const char **));
+static boolean parse_stab_tilde_field
+ PARAMS ((PTR, struct stab_handle *, const char **, const int *,
+ debug_type *, boolean *));
+static debug_type parse_stab_array_type
+ PARAMS ((PTR, struct stab_handle *, const char **, boolean));
+static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma));
+static const char *pop_bincl PARAMS ((struct stab_handle *));
+static boolean find_excl
+ PARAMS ((struct stab_handle *, const char *, bfd_vma));
+static boolean stab_record_variable
+ PARAMS ((PTR, struct stab_handle *, const char *, debug_type,
+ enum debug_var_kind, bfd_vma));
+static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *));
+static debug_type *stab_find_slot
+ PARAMS ((struct stab_handle *, const int *));
+static debug_type stab_find_type
+ PARAMS ((PTR, struct stab_handle *, const int *));
+static boolean stab_record_type
+ PARAMS ((PTR, struct stab_handle *, const int *, debug_type));
+static debug_type stab_xcoff_builtin_type
+ PARAMS ((PTR, struct stab_handle *, int));
+static debug_type stab_find_tagged_type
+ PARAMS ((PTR, struct stab_handle *, const char *, int,
+ enum debug_type_kind));
+static debug_type *stab_demangle_argtypes
+ PARAMS ((PTR, struct stab_handle *, const char *, boolean *));
+
+/* Save a string in memory. */
+
+static char *
+savestring (start, len)
+ const char *start;
+ int len;
+{
+ char *ret;
+
+ ret = (char *) xmalloc (len + 1);
+ memcpy (ret, start, len);
+ ret[len] = '\0';
+ return ret;
+}
+
+/* Read a number from a string. */
+
+static bfd_vma
+parse_number (pp, poverflow)
+ const char **pp;
+ boolean *poverflow;
+{
+ unsigned long ul;
+ const char *orig;
+
+ if (poverflow != NULL)
+ *poverflow = false;
+
+ orig = *pp;
+
+ errno = 0;
+ ul = strtoul (*pp, (char **) pp, 0);
+ if (ul + 1 != 0 || errno == 0)
+ {
+ /* If bfd_vma is larger than unsigned long, and the number is
+ meant to be negative, we have to make sure that we sign
+ extend properly. */
+ if (*orig == '-')
+ return (bfd_vma) (bfd_signed_vma) (long) ul;
+ return (bfd_vma) ul;
+ }
+
+ /* Note that even though strtoul overflowed, it should have set *pp
+ to the end of the number, which is where we want it. */
+
+ if (sizeof (bfd_vma) > sizeof (unsigned long))
+ {
+ const char *p;
+ boolean neg;
+ int base;
+ bfd_vma over, lastdig;
+ boolean overflow;
+ bfd_vma v;
+
+ /* Our own version of strtoul, for a bfd_vma. */
+
+ p = orig;
+
+ neg = false;
+ if (*p == '+')
+ ++p;
+ else if (*p == '-')
+ {
+ neg = true;
+ ++p;
+ }
+
+ base = 10;
+ if (*p == '0')
+ {
+ if (p[1] == 'x' || p[1] == 'X')
+ {
+ base = 16;
+ p += 2;
+ }
+ else
+ {
+ base = 8;
+ ++p;
+ }
+ }
+
+ over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
+ lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
+
+ overflow = false;
+ v = 0;
+ while (1)
+ {
+ int d;
+
+ d = *p++;
+ if (isdigit ((unsigned char) d))
+ d -= '0';
+ else if (isupper ((unsigned char) d))
+ d -= 'A';
+ else if (islower ((unsigned char) d))
+ d -= 'a';
+ else
+ break;
+
+ if (d >= base)
+ break;
+
+ if (v > over || (v == over && (bfd_vma) d > lastdig))
+ {
+ overflow = true;
+ break;
+ }
+ }
+
+ if (! overflow)
+ {
+ if (neg)
+ v = - v;
+ return v;
+ }
+ }
+
+ /* If we get here, the number is too large to represent in a
+ bfd_vma. */
+
+ if (poverflow != NULL)
+ *poverflow = true;
+ else
+ warn_stab (orig, _("numeric overflow"));
+
+ return 0;
+}
+
+/* Give an error for a bad stab string. */
+
+static void
+bad_stab (p)
+ const char *p;
+{
+ fprintf (stderr, _("Bad stab: %s\n"), p);
+}
+
+/* Warn about something in a stab string. */
+
+static void
+warn_stab (p, err)
+ const char *p;
+ const char *err;
+{
+ fprintf (stderr, _("Warning: %s: %s\n"), err, p);
+}
+
+/* Create a handle to parse stabs symbols with. */
+
+/*ARGSUSED*/
+PTR
+start_stab (dhandle, abfd, sections, syms, symcount)
+ PTR dhandle;
+ bfd *abfd;
+ boolean sections;
+ asymbol **syms;
+ long symcount;
+{
+ struct stab_handle *ret;
+
+ ret = (struct stab_handle *) xmalloc (sizeof *ret);
+ memset (ret, 0, sizeof *ret);
+ ret->abfd = abfd;
+ ret->sections = sections;
+ ret->syms = syms;
+ ret->symcount = symcount;
+ ret->files = 1;
+ ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
+ ret->file_types[0] = NULL;
+ ret->function_end = (bfd_vma) -1;
+ return (PTR) ret;
+}
+
+/* When we have processed all the stabs information, we need to go
+ through and fill in all the undefined tags. */
+
+boolean
+finish_stab (dhandle, handle)
+ PTR dhandle;
+ PTR handle;
+{
+ struct stab_handle *info = (struct stab_handle *) handle;
+ struct stab_tag *st;
+
+ if (info->within_function)
+ {
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, info->function_end))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+
+ for (st = info->tags; st != NULL; st = st->next)
+ {
+ enum debug_type_kind kind;
+
+ kind = st->kind;
+ if (kind == DEBUG_KIND_ILLEGAL)
+ kind = DEBUG_KIND_STRUCT;
+ st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
+ if (st->slot == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle a single stabs symbol. */
+
+boolean
+parse_stab (dhandle, handle, type, desc, value, string)
+ PTR dhandle;
+ PTR handle;
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ struct stab_handle *info = (struct stab_handle *) handle;
+
+ /* gcc will emit two N_SO strings per compilation unit, one for the
+ directory name and one for the file name. We just collect N_SO
+ strings as we see them, and start the new compilation unit when
+ we see a non N_SO symbol. */
+ if (info->so_string != NULL
+ && (type != N_SO || *string == '\0' || value != info->so_value))
+ {
+ if (! debug_set_filename (dhandle, info->so_string))
+ return false;
+ info->main_filename = info->so_string;
+
+ info->gcc_compiled = 0;
+ info->n_opt_found = false;
+
+ /* Generally, for stabs in the symbol table, the N_LBRAC and
+ N_RBRAC symbols are relative to the N_SO symbol value. */
+ if (! info->sections)
+ info->file_start_offset = info->so_value;
+
+ /* We need to reset the mapping from type numbers to types. We
+ can't free the old mapping, because of the use of
+ debug_make_indirect_type. */
+ info->files = 1;
+ info->file_types = ((struct stab_types **)
+ xmalloc (sizeof *info->file_types));
+ info->file_types[0] = NULL;
+
+ info->so_string = NULL;
+
+ /* Now process whatever type we just got. */
+ }
+
+ switch (type)
+ {
+ case N_FN:
+ case N_FN_SEQ:
+ break;
+
+ case N_LBRAC:
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (info->n_opt_found && desc == 1)
+ break;
+
+ if (! info->within_function)
+ {
+ fprintf (stderr, _("N_LBRAC not within function\n"));
+ return false;
+ }
+
+ /* Start an inner lexical block. */
+ if (! debug_start_block (dhandle,
+ (value
+ + info->file_start_offset
+ + info->function_start_offset)))
+ return false;
+
+ /* Emit any pending variable definitions. */
+ if (! stab_emit_pending_vars (dhandle, info))
+ return false;
+
+ ++info->block_depth;
+ break;
+
+ case N_RBRAC:
+ /* Ignore extra outermost context from SunPRO cc and acc. */
+ if (info->n_opt_found && desc == 1)
+ break;
+
+ /* We shouldn't have any pending variable definitions here, but,
+ if we do, we probably need to emit them before closing the
+ block. */
+ if (! stab_emit_pending_vars (dhandle, info))
+ return false;
+
+ /* End an inner lexical block. */
+ if (! debug_end_block (dhandle,
+ (value
+ + info->file_start_offset
+ + info->function_start_offset)))
+ return false;
+
+ --info->block_depth;
+ if (info->block_depth < 0)
+ {
+ fprintf (stderr, _("Too many N_RBRACs\n"));
+ return false;
+ }
+ break;
+
+ case N_SO:
+ /* This always ends a function. */
+ if (info->within_function)
+ {
+ bfd_vma endval;
+
+ endval = value;
+ if (*string != '\0'
+ && info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, endval))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+
+ /* An empty string is emitted by gcc at the end of a compilation
+ unit. */
+ if (*string == '\0')
+ return true;
+
+ /* Just accumulate strings until we see a non N_SO symbol. If
+ the string starts with a directory separator or some other
+ form of absolute path specification, we discard the previously
+ accumulated strings. */
+ if (info->so_string == NULL)
+ info->so_string = xstrdup (string);
+ else
+ {
+ char *f;
+
+ f = info->so_string;
+
+ if ( (string[0] == '/')
+ || (string[0] == DIR_SEPARATOR)
+ || ( (DIR_SEPARATOR == '\\')
+ && (string[1] == ':')
+ && ( (string[2] == DIR_SEPARATOR)
+ || (string[2] == '/'))))
+ info->so_string = xstrdup (string);
+ else
+ info->so_string = concat (info->so_string, string,
+ (const char *) NULL);
+ free (f);
+ }
+
+ info->so_value = value;
+
+ break;
+
+ case N_SOL:
+ /* Start an include file. */
+ if (! debug_start_source (dhandle, string))
+ return false;
+ break;
+
+ case N_BINCL:
+ /* Start an include file which may be replaced. */
+ push_bincl (info, string, value);
+ if (! debug_start_source (dhandle, string))
+ return false;
+ break;
+
+ case N_EINCL:
+ /* End an N_BINCL include. */
+ if (! debug_start_source (dhandle, pop_bincl (info)))
+ return false;
+ break;
+
+ case N_EXCL:
+ /* This is a duplicate of a header file named by N_BINCL which
+ was eliminated by the linker. */
+ if (! find_excl (info, string, value))
+ return false;
+ break;
+
+ case N_SLINE:
+ if (! debug_record_line (dhandle, desc,
+ value + info->function_start_offset))
+ return false;
+ break;
+
+ case N_BCOMM:
+ if (! debug_start_common_block (dhandle, string))
+ return false;
+ break;
+
+ case N_ECOMM:
+ if (! debug_end_common_block (dhandle, string))
+ return false;
+ break;
+
+ case N_FUN:
+ if (*string == '\0')
+ {
+ if (info->within_function)
+ {
+ /* This always marks the end of a function; we don't
+ need to worry about info->function_end. */
+ if (info->sections)
+ value += info->function_start_offset;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, value))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+ break;
+ }
+
+ /* A const static symbol in the .text section will have an N_FUN
+ entry. We need to use these to mark the end of the function,
+ in case we are looking at gcc output before it was changed to
+ always emit an empty N_FUN. We can't call debug_end_function
+ here, because it might be a local static symbol. */
+ if (info->within_function
+ && (info->function_end == (bfd_vma) -1
+ || value < info->function_end))
+ info->function_end = value;
+
+ /* Fall through. */
+ /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
+ symbols, and if it does not start with :S, gdb relocates the
+ value to the start of the section. gcc always seems to use
+ :S, so we don't worry about this. */
+ /* Fall through. */
+ default:
+ {
+ const char *colon;
+
+ colon = strchr (string, ':');
+ if (colon != NULL
+ && (colon[1] == 'f' || colon[1] == 'F'))
+ {
+ if (info->within_function)
+ {
+ bfd_vma endval;
+
+ endval = value;
+ if (info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, endval))
+ return false;
+ info->function_end = (bfd_vma) -1;
+ }
+ /* For stabs in sections, line numbers and block addresses
+ are offsets from the start of the function. */
+ if (info->sections)
+ info->function_start_offset = value;
+ info->within_function = true;
+ }
+
+ if (! parse_stab_string (dhandle, info, type, desc, value, string))
+ return false;
+ }
+ break;
+
+ case N_OPT:
+ if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
+ info->gcc_compiled = 2;
+ else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
+ info->gcc_compiled = 1;
+ else
+ info->n_opt_found = true;
+ break;
+
+ case N_OBJ:
+ case N_ENDM:
+ case N_MAIN:
+ break;
+ }
+
+ return true;
+}
+
+/* Parse the stabs string. */
+
+static boolean
+parse_stab_string (dhandle, info, stabtype, desc, value, string)
+ PTR dhandle;
+ struct stab_handle *info;
+ int stabtype;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ const char *p;
+ char *name;
+ int type;
+ debug_type dtype;
+ boolean synonym;
+ boolean self_crossref;
+ unsigned int lineno;
+ debug_type *slot;
+
+ p = strchr (string, ':');
+ if (p == NULL)
+ return true;
+
+ while (p[1] == ':')
+ {
+ p += 2;
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (string);
+ return false;
+ }
+ }
+
+ /* GCC 2.x puts the line number in desc. SunOS apparently puts in
+ the number of bytes occupied by a type or object, which we
+ ignore. */
+ if (info->gcc_compiled >= 2)
+ lineno = desc;
+ else
+ lineno = 0;
+
+ /* FIXME: Sometimes the special C++ names start with '.'. */
+ name = NULL;
+ if (string[0] == '$')
+ {
+ switch (string[1])
+ {
+ case 't':
+ name = "this";
+ break;
+ case 'v':
+ /* Was: name = "vptr"; */
+ break;
+ case 'e':
+ name = "eh_throw";
+ break;
+ case '_':
+ /* This was an anonymous type that was never fixed up. */
+ break;
+ case 'X':
+ /* SunPRO (3.0 at least) static variable encoding. */
+ break;
+ default:
+ warn_stab (string, _("unknown C++ encoded name"));
+ break;
+ }
+ }
+
+ if (name == NULL)
+ {
+ if (p == string || (string[0] == ' ' && p == string + 1))
+ name = NULL;
+ else
+ name = savestring (string, p - string);
+ }
+
+ ++p;
+ if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+ type = 'l';
+ else
+ type = *p++;
+
+ switch (type)
+ {
+ case 'c':
+ /* c is a special case, not followed by a type-number.
+ SYMBOL:c=iVALUE for an integer constant symbol.
+ SYMBOL:c=rVALUE for a floating constant symbol.
+ SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ if (*p != '=')
+ {
+ bad_stab (string);
+ return false;
+ }
+ ++p;
+ switch (*p++)
+ {
+ case 'r':
+ /* Floating point constant. */
+ if (! debug_record_float_const (dhandle, name, atof (p)))
+ return false;
+ break;
+ case 'i':
+ /* Integer constant. */
+ /* Defining integer constants this way is kind of silly,
+ since 'e' constants allows the compiler to give not only
+ the value, but the type as well. C has at least int,
+ long, unsigned int, and long long as constant types;
+ other languages probably should have at least unsigned as
+ well as signed constants. */
+ if (! debug_record_int_const (dhandle, name, atoi (p)))
+ return false;
+ break;
+ case 'e':
+ /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
+ can be represented as integral.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ &p, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (*p != ',')
+ {
+ bad_stab (string);
+ return false;
+ }
+ if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
+ return false;
+ break;
+ default:
+ bad_stab (string);
+ return false;
+ }
+
+ break;
+
+ case 'C':
+ /* The name of a caught exception. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ &p, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_label (dhandle, name, dtype, value))
+ return false;
+ break;
+
+ case 'f':
+ case 'F':
+ /* A function definition. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
+ return false;
+
+ /* Sun acc puts declared types of arguments here. We don't care
+ about their actual types (FIXME -- we should remember the whole
+ function prototype), but the list may define some new types
+ that we have to remember, so we must scan it now. */
+ while (*p == ';')
+ {
+ ++p;
+ if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL)
+ == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ break;
+
+ case 'G':
+ {
+ char leading;
+ long c;
+ asymbol **ps;
+
+ /* A global symbol. The value must be extracted from the
+ symbol table. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ leading = bfd_get_symbol_leading_char (info->abfd);
+ for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
+ {
+ const char *n;
+
+ n = bfd_asymbol_name (*ps);
+ if (leading != '\0' && *n == leading)
+ ++n;
+ if (*n == *name && strcmp (n, name) == 0)
+ break;
+ }
+ if (c > 0)
+ value = bfd_asymbol_value (*ps);
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
+ value))
+ return false;
+ }
+ break;
+
+ /* This case is faked by a conditional above, when there is no
+ code letter in the dbx data. Dbx data never actually
+ contains 'l'. */
+ case 'l':
+ case 's':
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
+ value))
+ return false;
+ break;
+
+ case 'p':
+ /* A function parameter. */
+ if (*p != 'F')
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ else
+ {
+ /* pF is a two-letter code that means a function parameter in
+ Fortran. The type-number specifies the type of the return
+ value. Translate it into a pointer-to-function type. */
+ ++p;
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype != DEBUG_TYPE_NULL)
+ {
+ debug_type ftype;
+
+ ftype = debug_make_function_type (dhandle, dtype,
+ (debug_type *) NULL, false);
+ dtype = debug_make_pointer_type (dhandle, ftype);
+ }
+ }
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
+ value))
+ return false;
+
+ /* FIXME: At this point gdb considers rearranging the parameter
+ address on a big endian machine if it is smaller than an int.
+ We have no way to do that, since we don't really know much
+ about the target. */
+
+ break;
+
+ case 'P':
+ if (stabtype == N_FUN)
+ {
+ /* Prototype of a function referenced by this file. */
+ while (*p == ';')
+ {
+ ++p;
+ if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL)
+ == DEBUG_TYPE_NULL)
+ return false;
+ }
+ break;
+ }
+ /* Fall through. */
+ case 'R':
+ /* Parameter which is in a register. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
+ value))
+ return false;
+ break;
+
+ case 'r':
+ /* Register variable (either global or local). */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
+ value))
+ return false;
+
+ /* FIXME: At this point gdb checks to combine pairs of 'p' and
+ 'r' stabs into a single 'P' stab. */
+
+ break;
+
+ case 'S':
+ /* Static symbol at top level of file */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
+ value))
+ return false;
+ break;
+
+ case 't':
+ /* A typedef. */
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (name == NULL)
+ {
+ /* A nameless type. Nothing to do. */
+ return true;
+ }
+
+ dtype = debug_name_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+
+ if (slot != NULL)
+ *slot = dtype;
+
+ break;
+
+ case 'T':
+ /* Struct, union, or enum tag. For GNU C++, this can be be followed
+ by 't' which means we are typedef'ing it as well. */
+ if (*p != 't')
+ {
+ synonym = false;
+ /* FIXME: gdb sets synonym to true if the current language
+ is C++. */
+ }
+ else
+ {
+ synonym = true;
+ ++p;
+ }
+
+ dtype = parse_stab_type (dhandle, info, name, &p, &slot);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (name == NULL)
+ return true;
+
+ /* INFO->SELF_CROSSREF is set by parse_stab_type if this type is
+ a cross reference to itself. These are generated by some
+ versions of g++. */
+ self_crossref = info->self_crossref;
+
+ dtype = debug_tag_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (slot != NULL)
+ *slot = dtype;
+
+ /* See if we have a cross reference to this tag which we can now
+ fill in. Avoid filling in a cross reference to ourselves,
+ because that would lead to circular debugging information. */
+ if (! self_crossref)
+ {
+ register struct stab_tag **pst;
+
+ for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
+ {
+ if ((*pst)->name[0] == name[0]
+ && strcmp ((*pst)->name, name) == 0)
+ {
+ (*pst)->slot = dtype;
+ *pst = (*pst)->next;
+ break;
+ }
+ }
+ }
+
+ if (synonym)
+ {
+ dtype = debug_name_type (dhandle, name, dtype);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+
+ if (slot != NULL)
+ *slot = dtype;
+ }
+
+ break;
+
+ case 'V':
+ /* Static symbol of local scope */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ /* FIXME: gdb checks os9k_stabs here. */
+ if (! stab_record_variable (dhandle, info, name, dtype,
+ DEBUG_LOCAL_STATIC, value))
+ return false;
+ break;
+
+ case 'v':
+ /* Reference parameter. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
+ value))
+ return false;
+ break;
+
+ case 'a':
+ /* Reference parameter which is in a register. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
+ value))
+ return false;
+ break;
+
+ case 'X':
+ /* This is used by Sun FORTRAN for "function result value".
+ Sun claims ("dbx and dbxtool interfaces", 2nd ed)
+ that Pascal uses it too, but when I tried it Pascal used
+ "x:3" (local symbol) instead. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
+ (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return false;
+ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
+ value))
+ return false;
+ break;
+
+ default:
+ bad_stab (string);
+ return false;
+ }
+
+ /* FIXME: gdb converts structure values to structure pointers in a
+ couple of cases, depending upon the target. */
+
+ return true;
+}
+
+/* Parse a stabs type. The typename argument is non-NULL if this is a
+ typedef or a tag definition. The pp argument points to the stab
+ string, and is updated. The slotp argument points to a place to
+ store the slot used if the type is being defined. */
+
+static debug_type
+parse_stab_type (dhandle, info, typename, pp, slotp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *typename;
+ const char **pp;
+ debug_type **slotp;
+{
+ const char *orig;
+ int typenums[2];
+ int size;
+ boolean stringp;
+ int descriptor;
+ debug_type dtype;
+
+ if (slotp != NULL)
+ *slotp = NULL;
+
+ orig = *pp;
+
+ size = -1;
+ stringp = false;
+
+ info->self_crossref = false;
+
+ /* Read type number if present. The type number may be omitted.
+ for instance in a two-dimensional array declared with type
+ "ar1;1;10;ar1;1;10;4". */
+ if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-')
+ {
+ /* 'typenums=' not present, type is anonymous. Read and return
+ the definition, but don't put it in the type vector. */
+ typenums[0] = typenums[1] = -1;
+ }
+ else
+ {
+ if (! parse_stab_type_number (pp, typenums))
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != '=')
+ {
+ /* Type is not being defined here. Either it already
+ exists, or this is a forward reference to it. */
+ return stab_find_type (dhandle, info, typenums);
+ }
+
+ /* Only set the slot if the type is being defined. This means
+ that the mapping from type numbers to types will only record
+ the name of the typedef which defines a type. If we don't do
+ this, then something like
+ typedef int foo;
+ int i;
+ will record that i is of type foo. Unfortunately, stabs
+ information is ambiguous about variable types. For this code,
+ typedef int foo;
+ int i;
+ foo j;
+ the stabs information records both i and j as having the same
+ type. This could be fixed by patching the compiler. */
+ if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
+ *slotp = stab_find_slot (info, typenums);
+
+ /* Type is being defined here. */
+ /* Skip the '='. */
+ ++*pp;
+
+ while (**pp == '@')
+ {
+ const char *p = *pp + 1;
+ const char *attr;
+
+ if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-')
+ {
+ /* Member type. */
+ break;
+ }
+
+ /* Type attributes. */
+ attr = p;
+
+ for (; *p != ';'; ++p)
+ {
+ if (*p == '\0')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ }
+ *pp = p + 1;
+
+ switch (*attr)
+ {
+ case 's':
+ size = atoi (attr + 1);
+ if (size <= 0)
+ size = -1;
+ break;
+
+ case 'S':
+ stringp = true;
+ break;
+
+ default:
+ /* Ignore unrecognized type attributes, so future
+ compilers can invent new ones. */
+ break;
+ }
+ }
+ }
+
+ descriptor = **pp;
+ ++*pp;
+
+ switch (descriptor)
+ {
+ case 'x':
+ {
+ enum debug_type_kind code;
+ const char *q1, *q2, *p;
+
+ /* A cross reference to another type. */
+
+ switch (**pp)
+ {
+ case 's':
+ code = DEBUG_KIND_STRUCT;
+ break;
+ case 'u':
+ code = DEBUG_KIND_UNION;
+ break;
+ case 'e':
+ code = DEBUG_KIND_ENUM;
+ break;
+ default:
+ /* Complain and keep going, so compilers can invent new
+ cross-reference types. */
+ warn_stab (orig, _("unrecognized cross reference type"));
+ code = DEBUG_KIND_STRUCT;
+ break;
+ }
+ ++*pp;
+
+ q1 = strchr (*pp, '<');
+ p = strchr (*pp, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ while (q1 != NULL && p > q1 && p[1] == ':')
+ {
+ q2 = strchr (q1, '>');
+ if (q2 == NULL || q2 < p)
+ break;
+ p += 2;
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ }
+
+ /* Some versions of g++ can emit stabs like
+ fleep:T20=xsfleep:
+ which define structures in terms of themselves. We need to
+ tell the caller to avoid building a circular structure. */
+ if (typename != NULL
+ && strncmp (typename, *pp, p - *pp) == 0
+ && typename[p - *pp] == '\0')
+ info->self_crossref = true;
+
+ dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);
+
+ *pp = p + 1;
+ }
+ break;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '(':
+ {
+ const char *hold;
+ int xtypenums[2];
+
+ /* This type is defined as another type. */
+
+ (*pp)--;
+ hold = *pp;
+
+ /* Peek ahead at the number to detect void. */
+ if (! parse_stab_type_number (pp, xtypenums))
+ return DEBUG_TYPE_NULL;
+
+ if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
+ {
+ /* This type is being defined as itself, which means that
+ it is void. */
+ dtype = debug_make_void_type (dhandle);
+ }
+ else
+ {
+ *pp = hold;
+
+ /* Go back to the number and have parse_stab_type get it.
+ This means that we can deal with something like
+ t(1,2)=(3,4)=... which the Lucid compiler uses. */
+ dtype = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (dtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (typenums[0] != -1)
+ {
+ if (! stab_record_type (dhandle, info, typenums, dtype))
+ return DEBUG_TYPE_NULL;
+ }
+
+ break;
+ }
+
+ case '*':
+ dtype = debug_make_pointer_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL));
+ break;
+
+ case '&':
+ /* Reference to another type. */
+ dtype = (debug_make_reference_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL)));
+ break;
+
+ case 'f':
+ /* Function returning another type. */
+ /* FIXME: gdb checks os9k_stabs here. */
+ dtype = (debug_make_function_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL),
+ (debug_type *) NULL, false));
+ break;
+
+ case 'k':
+ /* Const qualifier on some type (Sun). */
+ /* FIXME: gdb accepts 'c' here if os9k_stabs. */
+ dtype = debug_make_const_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL));
+ break;
+
+ case 'B':
+ /* Volatile qual on some type (Sun). */
+ /* FIXME: gdb accepts 'i' here if os9k_stabs. */
+ dtype = (debug_make_volatile_type
+ (dhandle,
+ parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL)));
+ break;
+
+ case '@':
+ /* Offset (class & variable) type. This is used for a pointer
+ relative to an object. */
+ {
+ debug_type domain;
+ debug_type memtype;
+
+ /* Member type. */
+
+ domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (domain == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (memtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ dtype = debug_make_offset_type (dhandle, domain, memtype);
+ }
+ break;
+
+ case '#':
+ /* Method (class & fn) type. */
+ if (**pp == '#')
+ {
+ debug_type return_type;
+
+ ++*pp;
+ return_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (return_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+ dtype = debug_make_method_type (dhandle, return_type,
+ DEBUG_TYPE_NULL,
+ (debug_type *) NULL, false);
+ }
+ else
+ {
+ debug_type domain;
+ debug_type return_type;
+ debug_type *args;
+ unsigned int n;
+ unsigned int alloc;
+ boolean varargs;
+
+ domain = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (domain == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ return_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (return_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ alloc = 10;
+ args = (debug_type *) xmalloc (alloc * sizeof *args);
+ n = 0;
+ while (**pp != ';')
+ {
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (n + 1 >= alloc)
+ {
+ alloc += 10;
+ args = ((debug_type *)
+ xrealloc ((PTR) args, alloc * sizeof *args));
+ }
+
+ args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (args[n] == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ ++n;
+ }
+ ++*pp;
+
+ /* If the last type is not void, then this function takes a
+ variable number of arguments. Otherwise, we must strip
+ the void type. */
+ if (n == 0
+ || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
+ varargs = true;
+ else
+ {
+ --n;
+ varargs = false;
+ }
+
+ args[n] = DEBUG_TYPE_NULL;
+
+ dtype = debug_make_method_type (dhandle, return_type, domain, args,
+ varargs);
+ }
+ break;
+
+ case 'r':
+ /* Range type. */
+ dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
+ break;
+
+ case 'b':
+ /* FIXME: gdb checks os9k_stabs here. */
+ /* Sun ACC builtin int type. */
+ dtype = parse_stab_sun_builtin_type (dhandle, pp);
+ break;
+
+ case 'R':
+ /* Sun ACC builtin float type. */
+ dtype = parse_stab_sun_floating_type (dhandle, pp);
+ break;
+
+ case 'e':
+ /* Enumeration type. */
+ dtype = parse_stab_enum_type (dhandle, pp);
+ break;
+
+ case 's':
+ case 'u':
+ /* Struct or union type. */
+ dtype = parse_stab_struct_type (dhandle, info, typename, pp,
+ descriptor == 's', typenums);
+ break;
+
+ case 'a':
+ /* Array type. */
+ if (**pp != 'r')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ dtype = parse_stab_array_type (dhandle, info, pp, stringp);
+ break;
+
+ case 'S':
+ dtype = debug_make_set_type (dhandle,
+ parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL),
+ stringp);
+ break;
+
+ default:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (dtype == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (typenums[0] != -1)
+ {
+ if (! stab_record_type (dhandle, info, typenums, dtype))
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (size != -1)
+ {
+ if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
+ return false;
+ }
+
+ return dtype;
+}
+
+/* Read a number by which a type is referred to in dbx data, or
+ perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a
+ single number N is equivalent to (0,N). Return the two numbers by
+ storing them in the vector TYPENUMS. */
+
+static boolean
+parse_stab_type_number (pp, typenums)
+ const char **pp;
+ int *typenums;
+{
+ const char *orig;
+
+ orig = *pp;
+
+ if (**pp != '(')
+ {
+ typenums[0] = 0;
+ typenums[1] = (int) parse_number (pp, (boolean *) NULL);
+ }
+ else
+ {
+ ++*pp;
+ typenums[0] = (int) parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ typenums[1] = (int) parse_number (pp, (boolean *) NULL);
+ if (**pp != ')')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ }
+
+ return true;
+}
+
+/* Parse a range type. */
+
+static debug_type
+parse_stab_range_type (dhandle, info, typename, pp, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *typename;
+ const char **pp;
+ const int *typenums;
+{
+ const char *orig;
+ int rangenums[2];
+ boolean self_subrange;
+ debug_type index_type;
+ const char *s2, *s3;
+ bfd_signed_vma n2, n3;
+ boolean ov2, ov3;
+
+ orig = *pp;
+
+ index_type = DEBUG_TYPE_NULL;
+
+ /* First comes a type we are a subrange of.
+ In C it is usually 0, 1 or the type being defined. */
+ if (! parse_stab_type_number (pp, rangenums))
+ return DEBUG_TYPE_NULL;
+
+ self_subrange = (rangenums[0] == typenums[0]
+ && rangenums[1] == typenums[1]);
+
+ if (**pp == '=')
+ {
+ *pp = orig;
+ index_type = parse_stab_type (dhandle, info, (const char *) NULL,
+ pp, (debug_type **) NULL);
+ if (index_type == DEBUG_TYPE_NULL)
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (**pp == ';')
+ ++*pp;
+
+ /* The remaining two operands are usually lower and upper bounds of
+ the range. But in some special cases they mean something else. */
+ s2 = *pp;
+ n2 = parse_number (pp, &ov2);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ s3 = *pp;
+ n3 = parse_number (pp, &ov3);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (ov2 || ov3)
+ {
+ /* gcc will emit range stabs for long long types. Handle this
+ as a special case. FIXME: This needs to be more general. */
+#define LLLOW "01000000000000000000000;"
+#define LLHIGH "0777777777777777777777;"
+#define ULLHIGH "01777777777777777777777;"
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0
+ && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0)
+ return debug_make_int_type (dhandle, 8, false);
+ if (! ov2
+ && n2 == 0
+ && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0)
+ return debug_make_int_type (dhandle, 8, true);
+ }
+
+ warn_stab (orig, _("numeric overflow"));
+ }
+
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ /* A type defined as a subrange of itself, with both bounds 0,
+ is void. */
+ if (self_subrange && n2 == 0 && n3 == 0)
+ return debug_make_void_type (dhandle);
+
+ /* A type defined as a subrange of itself, with n2 positive and
+ n3 zero, is a complex type, and n2 is the number of bytes. */
+ if (self_subrange && n3 == 0 && n2 > 0)
+ return debug_make_complex_type (dhandle, n2);
+
+ /* If n3 is zero and n2 is positive, this is a floating point
+ type, and n2 is the number of bytes. */
+ if (n3 == 0 && n2 > 0)
+ return debug_make_float_type (dhandle, n2);
+
+ /* If the upper bound is -1, this is an unsigned int. */
+ if (n2 == 0 && n3 == -1)
+ {
+ /* When gcc is used with -gstabs, but not -gstabs+, it will emit
+ long long int:t6=r1;0;-1;
+ long long unsigned int:t7=r1;0;-1;
+ We hack here to handle this reasonably. */
+ if (typename != NULL)
+ {
+ if (strcmp (typename, "long long int") == 0)
+ return debug_make_int_type (dhandle, 8, false);
+ else if (strcmp (typename, "long long unsigned int") == 0)
+ return debug_make_int_type (dhandle, 8, true);
+ }
+ /* FIXME: The size here really depends upon the target. */
+ return debug_make_int_type (dhandle, 4, true);
+ }
+
+ /* A range of 0 to 127 is char. */
+ if (self_subrange && n2 == 0 && n3 == 127)
+ return debug_make_int_type (dhandle, 1, false);
+
+ /* FIXME: gdb checks for the language CHILL here. */
+
+ if (n2 == 0)
+ {
+ if (n3 < 0)
+ return debug_make_int_type (dhandle, - n3, true);
+ else if (n3 == 0xff)
+ return debug_make_int_type (dhandle, 1, true);
+ else if (n3 == 0xffff)
+ return debug_make_int_type (dhandle, 2, true);
+ else if (n3 == 0xffffffff)
+ return debug_make_int_type (dhandle, 4, true);
+#ifdef BFD64
+ else if (n3 == ((((bfd_vma) 0xffffffff) << 32) | 0xffffffff))
+ return debug_make_int_type (dhandle, 8, true);
+#endif
+ }
+ else if (n3 == 0
+ && n2 < 0
+ && (self_subrange || n2 == -8))
+ return debug_make_int_type (dhandle, - n2, true);
+ else if (n2 == - n3 - 1 || n2 == n3 + 1)
+ {
+ if (n3 == 0x7f)
+ return debug_make_int_type (dhandle, 1, false);
+ else if (n3 == 0x7fff)
+ return debug_make_int_type (dhandle, 2, false);
+ else if (n3 == 0x7fffffff)
+ return debug_make_int_type (dhandle, 4, false);
+#ifdef BFD64
+ else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff))
+ return debug_make_int_type (dhandle, 8, false);
+#endif
+ }
+ }
+
+ /* At this point I don't have the faintest idea how to deal with a
+ self_subrange type; I'm going to assume that this is used as an
+ idiom, and that all of them are special cases. So . . . */
+ if (self_subrange)
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ index_type = stab_find_type (dhandle, info, rangenums);
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ /* Does this actually ever happen? Is that why we are worrying
+ about dealing with it rather than just calling error_type? */
+ warn_stab (orig, _("missing index type"));
+ index_type = debug_make_int_type (dhandle, 4, false);
+ }
+
+ return debug_make_range_type (dhandle, index_type, n2, n3);
+}
+
+/* Sun's ACC uses a somewhat saner method for specifying the builtin
+ typedefs in every file (for int, long, etc):
+
+ type = b <signed> <width>; <offset>; <nbits>
+ signed = u or s. Possible c in addition to u or s (for char?).
+ offset = offset from high order bit to start bit of type.
+ width is # bytes in object of this type, nbits is # bits in type.
+
+ The width/offset stuff appears to be for small objects stored in
+ larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
+ FIXME. */
+
+static debug_type
+parse_stab_sun_builtin_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ boolean unsignedp;
+ bfd_vma bits;
+
+ orig = *pp;
+
+ switch (**pp)
+ {
+ case 's':
+ unsignedp = false;
+ break;
+ case 'u':
+ unsignedp = true;
+ break;
+ default:
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* For some odd reason, all forms of char put a c here. This is strange
+ because no other type has this honor. We can safely ignore this because
+ we actually determine 'char'acterness by the number of bits specified in
+ the descriptor. */
+ if (**pp == 'c')
+ ++*pp;
+
+ /* The first number appears to be the number of bytes occupied
+ by this type, except that unsigned short is 4 instead of 2.
+ Since this information is redundant with the third number,
+ we will ignore it. */
+ (void) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* The second number is always 0, so ignore it too. */
+ (void) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ /* The third number is the number of bits for this type. */
+ bits = parse_number (pp, (boolean *) NULL);
+
+ /* The type *should* end with a semicolon. If it are embedded
+ in a larger type the semicolon may be the only way to know where
+ the type ends. If this type is at the end of the stabstring we
+ can deal with the omitted semicolon (but we don't have to like
+ it). Don't bother to complain(), Sun's compiler omits the semicolon
+ for "void". */
+ if (**pp == ';')
+ ++*pp;
+
+ if (bits == 0)
+ return debug_make_void_type (dhandle);
+
+ return debug_make_int_type (dhandle, bits / 8, unsignedp);
+}
+
+/* Parse a builtin floating type generated by the Sun compiler. */
+
+static debug_type
+parse_stab_sun_floating_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ bfd_vma details;
+ bfd_vma bytes;
+
+ orig = *pp;
+
+ /* The first number has more details about the type, for example
+ FN_COMPLEX. */
+ details = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ /* The second number is the number of bytes occupied by this type */
+ bytes = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+
+ if (details == NF_COMPLEX
+ || details == NF_COMPLEX16
+ || details == NF_COMPLEX32)
+ return debug_make_complex_type (dhandle, bytes);
+
+ return debug_make_float_type (dhandle, bytes);
+}
+
+/* Handle an enum type. */
+
+static debug_type
+parse_stab_enum_type (dhandle, pp)
+ PTR dhandle;
+ const char **pp;
+{
+ const char *orig;
+ const char **names;
+ bfd_signed_vma *values;
+ unsigned int n;
+ unsigned int alloc;
+
+ orig = *pp;
+
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ /* The aix4 compiler emits an extra field before the enum members;
+ my guess is it's a type of some sort. Just ignore it. */
+ if (**pp == '-')
+ {
+ while (**pp != ':')
+ ++*pp;
+ ++*pp;
+ }
+
+ /* Read the value-names and their values.
+ The input syntax is NAME:VALUE,NAME:VALUE, and so on.
+ A semicolon or comma instead of a NAME means the end. */
+ alloc = 10;
+ names = (const char **) xmalloc (alloc * sizeof *names);
+ values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);
+ n = 0;
+ while (**pp != '\0' && **pp != ';' && **pp != ',')
+ {
+ const char *p;
+ char *name;
+ bfd_signed_vma val;
+
+ p = *pp;
+ while (*p != ':')
+ ++p;
+
+ name = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+ val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ if (n + 1 >= alloc)
+ {
+ alloc += 10;
+ names = ((const char **)
+ xrealloc ((PTR) names, alloc * sizeof *names));
+ values = ((bfd_signed_vma *)
+ xrealloc ((PTR) values, alloc * sizeof *values));
+ }
+
+ names[n] = name;
+ values[n] = val;
+ ++n;
+ }
+
+ names[n] = NULL;
+ values[n] = 0;
+
+ if (**pp == ';')
+ ++*pp;
+
+ return debug_make_enum_type (dhandle, names, values);
+}
+
+/* Read the description of a structure (or union type) and return an object
+ describing the type.
+
+ PP points to a character pointer that points to the next unconsumed token
+ in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
+ *PP will point to "4a:1,0,32;;". */
+
+static debug_type
+parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *tagname;
+ const char **pp;
+ boolean structp;
+ const int *typenums;
+{
+ const char *orig;
+ bfd_vma size;
+ debug_baseclass *baseclasses;
+ debug_field *fields;
+ boolean statics;
+ debug_method *methods;
+ debug_type vptrbase;
+ boolean ownvptr;
+
+ orig = *pp;
+
+ /* Get the size. */
+ size = parse_number (pp, (boolean *) NULL);
+
+ /* Get the other information. */
+ if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
+ || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
+ || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
+ || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
+ &ownvptr))
+ return DEBUG_TYPE_NULL;
+
+ if (! statics
+ && baseclasses == NULL
+ && methods == NULL
+ && vptrbase == DEBUG_TYPE_NULL
+ && ! ownvptr)
+ return debug_make_struct_type (dhandle, structp, size, fields);
+
+ return debug_make_object_type (dhandle, structp, size, fields, baseclasses,
+ methods, vptrbase, ownvptr);
+}
+
+/* The stabs for C++ derived classes contain baseclass information which
+ is marked by a '!' character after the total size. This function is
+ called when we encounter the baseclass marker, and slurps up all the
+ baseclass information.
+
+ Immediately following the '!' marker is the number of base classes that
+ the class is derived from, followed by information for each base class.
+ For each base class, there are two visibility specifiers, a bit offset
+ to the base class information within the derived class, a reference to
+ the type for the base class, and a terminating semicolon.
+
+ A typical example, with two base classes, would be "!2,020,19;0264,21;".
+ ^^ ^ ^ ^ ^ ^ ^
+ Baseclass information marker __________________|| | | | | | |
+ Number of baseclasses __________________________| | | | | | |
+ Visibility specifiers (2) ________________________| | | | | |
+ Offset in bits from start of class _________________| | | | |
+ Type number for base class ___________________________| | | |
+ Visibility specifiers (2) _______________________________| | |
+ Offset in bits from start of class ________________________| |
+ Type number of base class ____________________________________|
+
+ Return true for success, false for failure. */
+
+static boolean
+parse_stab_baseclasses (dhandle, info, pp, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_baseclass **retp;
+{
+ const char *orig;
+ unsigned int c, i;
+ debug_baseclass *classes;
+
+ *retp = NULL;
+
+ orig = *pp;
+
+ if (**pp != '!')
+ {
+ /* No base classes. */
+ return true;
+ }
+ ++*pp;
+
+ c = (unsigned int) parse_number (pp, (boolean *) NULL);
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp));
+
+ for (i = 0; i < c; i++)
+ {
+ boolean virtual;
+ enum debug_visibility visibility;
+ bfd_vma bitpos;
+ debug_type type;
+
+ switch (**pp)
+ {
+ case '0':
+ virtual = false;
+ break;
+ case '1':
+ virtual = true;
+ break;
+ default:
+ warn_stab (orig, _("unknown virtual character for baseclass"));
+ virtual = false;
+ break;
+ }
+ ++*pp;
+
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ case '2':
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ default:
+ warn_stab (orig, _("unknown visibility character for baseclass"));
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+
+ /* The remaining value is the bit offset of the portion of the
+ object corresponding to this baseclass. Always zero in the
+ absence of multiple inheritance. */
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
+ visibility);
+ if (classes[i] == DEBUG_BASECLASS_NULL)
+ return false;
+
+ if (**pp != ';')
+ return false;
+ ++*pp;
+ }
+
+ classes[i] = DEBUG_BASECLASS_NULL;
+
+ *retp = classes;
+
+ return true;
+}
+
+/* Read struct or class data fields. They have the form:
+
+ NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
+
+ At the end, we see a semicolon instead of a field.
+
+ In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
+ a static field.
+
+ The optional VISIBILITY is one of:
+
+ '/0' (VISIBILITY_PRIVATE)
+ '/1' (VISIBILITY_PROTECTED)
+ '/2' (VISIBILITY_PUBLIC)
+ '/9' (VISIBILITY_IGNORE)
+
+ or nothing, for C style fields with public visibility.
+
+ Returns 1 for success, 0 for failure. */
+
+static boolean
+parse_stab_struct_fields (dhandle, info, pp, retp, staticsp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_field **retp;
+ boolean *staticsp;
+{
+ const char *orig;
+ const char *p;
+ debug_field *fields;
+ unsigned int c;
+ unsigned int alloc;
+
+ *retp = NULL;
+ *staticsp = false;
+
+ orig = *pp;
+
+ c = 0;
+ alloc = 10;
+ fields = (debug_field *) xmalloc (alloc * sizeof *fields);
+ while (**pp != ';')
+ {
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ p = *pp;
+
+ /* Add 1 to c to leave room for NULL pointer at end. */
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ fields = ((debug_field *)
+ xrealloc ((PTR) fields, alloc * sizeof *fields));
+ }
+
+ /* If it starts with CPLUS_MARKER it is a special abbreviation,
+ unless the CPLUS_MARKER is followed by an underscore, in
+ which case it is just the name of an anonymous type, which we
+ should handle like any other type name. We accept either '$'
+ or '.', because a field name can never contain one of these
+ characters except as a CPLUS_MARKER. */
+
+ if ((*p == '$' || *p == '.') && p[1] != '_')
+ {
+ ++*pp;
+ if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
+ return false;
+ ++c;
+ continue;
+ }
+
+ /* Look for the ':' that separates the field name from the field
+ values. Data members are delimited by a single ':', while member
+ functions are delimited by a pair of ':'s. When we hit the member
+ functions (if any), terminate scan loop and return. */
+
+ p = strchr (p, ':');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ if (p[1] == ':')
+ break;
+
+ if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
+ staticsp))
+ return false;
+
+ ++c;
+ }
+
+ fields[c] = DEBUG_FIELD_NULL;
+
+ *retp = fields;
+
+ return true;
+}
+
+/* Special GNU C++ name. */
+
+static boolean
+parse_stab_cpp_abbrev (dhandle, info, pp, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ debug_field *retp;
+{
+ const char *orig;
+ int cpp_abbrev;
+ debug_type context;
+ const char *name;
+ const char *typename;
+ debug_type type;
+ bfd_vma bitpos;
+
+ *retp = DEBUG_FIELD_NULL;
+
+ orig = *pp;
+
+ if (**pp != 'v')
+ {
+ bad_stab (*pp);
+ return false;
+ }
+ ++*pp;
+
+ cpp_abbrev = **pp;
+ ++*pp;
+
+ /* At this point, *pp points to something like "22:23=*22...", where
+ the type number before the ':' is the "context" and everything
+ after is a regular type definition. Lookup the type, find it's
+ name, and construct the field name. */
+
+ context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+
+ switch (cpp_abbrev)
+ {
+ case 'f':
+ /* $vf -- a virtual function table pointer. */
+ name = "_vptr$";
+ break;
+ case 'b':
+ /* $vb -- a virtual bsomethingorother */
+ typename = debug_get_type_name (dhandle, context);
+ if (typename == NULL)
+ {
+ warn_stab (orig, _("unnamed $vb type"));
+ typename = "FOO";
+ }
+ name = concat ("_vb$", typename, (const char *) NULL);
+ break;
+ default:
+ warn_stab (orig, _("unrecognized C++ abbreviation"));
+ name = "INVALID_CPLUSPLUS_ABBREV";
+ break;
+ }
+
+ if (**pp != ':')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ *retp = debug_make_field (dhandle, name, type, bitpos, 0,
+ DEBUG_VISIBILITY_PRIVATE);
+ if (*retp == DEBUG_FIELD_NULL)
+ return false;
+
+ return true;
+}
+
+/* Parse a single field in a struct or union. */
+
+static boolean
+parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ const char *p;
+ debug_field *retp;
+ boolean *staticsp;
+{
+ const char *orig;
+ char *name;
+ enum debug_visibility visibility;
+ debug_type type;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+
+ orig = *pp;
+
+ /* FIXME: gdb checks ARM_DEMANGLING here. */
+
+ name = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+
+ if (**pp != '/')
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ else
+ {
+ ++*pp;
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ case '2':
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ default:
+ warn_stab (orig, _("unknown visibility character for field"));
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+ }
+
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (**pp == ':')
+ {
+ char *varname;
+
+ /* This is a static class member. */
+ ++*pp;
+ p = strchr (*pp, ';');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ varname = savestring (*pp, p - *pp);
+
+ *pp = p + 1;
+
+ *retp = debug_make_static_member (dhandle, name, type, varname,
+ visibility);
+ *staticsp = true;
+
+ return true;
+ }
+
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitpos = parse_number (pp, (boolean *) NULL);
+ if (**pp != ',')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ bitsize = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (bitpos == 0 && bitsize == 0)
+ {
+ /* This can happen in two cases: (1) at least for gcc 2.4.5 or
+ so, it is a field which has been optimized out. The correct
+ stab for this case is to use VISIBILITY_IGNORE, but that is a
+ recent invention. (2) It is a 0-size array. For example
+ union { int num; char str[0]; } foo. Printing "<no value>"
+ for str in "p foo" is OK, since foo.str (and thus foo.str[3])
+ will continue to work, and a 0-size array as a whole doesn't
+ have any contents to print.
+
+ I suspect this probably could also happen with gcc -gstabs
+ (not -gstabs+) for static fields, and perhaps other C++
+ extensions. Hopefully few people use -gstabs with gdb, since
+ it is intended for dbx compatibility. */
+ visibility = DEBUG_VISIBILITY_IGNORE;
+ }
+
+ /* FIXME: gdb does some stuff here to mark fields as unpacked. */
+
+ *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);
+
+ return true;
+}
+
+/* Read member function stabs info for C++ classes. The form of each member
+ function data is:
+
+ NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
+
+ An example with two member functions is:
+
+ afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
+
+ For the case of overloaded operators, the format is op$::*.funcs, where
+ $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
+ name (such as `+=') and `.' marks the end of the operator name. */
+
+static boolean
+parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *tagname;
+ const char **pp;
+ const int *typenums;
+ debug_method **retp;
+{
+ const char *orig;
+ debug_method *methods;
+ unsigned int c;
+ unsigned int alloc;
+
+ *retp = NULL;
+
+ orig = *pp;
+
+ alloc = 0;
+ methods = NULL;
+ c = 0;
+
+ while (**pp != ';')
+ {
+ const char *p;
+ char *name;
+ debug_method_variant *variants;
+ unsigned int cvars;
+ unsigned int allocvars;
+ debug_type look_ahead_type;
+
+ p = strchr (*pp, ':');
+ if (p == NULL || p[1] != ':')
+ break;
+
+ /* FIXME: Some systems use something other than '$' here. */
+ if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$')
+ {
+ name = savestring (*pp, p - *pp);
+ *pp = p + 2;
+ }
+ else
+ {
+ /* This is a completely wierd case. In order to stuff in the
+ names that might contain colons (the usual name delimiter),
+ Mike Tiemann defined a different name format which is
+ signalled if the identifier is "op$". In that case, the
+ format is "op$::XXXX." where XXXX is the name. This is
+ used for names like "+" or "=". YUUUUUUUK! FIXME! */
+ *pp = p + 2;
+ for (p = *pp; *p != '.' && *p != '\0'; p++)
+ ;
+ if (*p != '.')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ name = savestring (*pp, p - *pp);
+ *pp = p + 1;
+ }
+
+ allocvars = 10;
+ variants = ((debug_method_variant *)
+ xmalloc (allocvars * sizeof *variants));
+ cvars = 0;
+
+ look_ahead_type = DEBUG_TYPE_NULL;
+
+ do
+ {
+ debug_type type;
+ boolean stub;
+ char *argtypes;
+ enum debug_visibility visibility;
+ boolean constp, volatilep, staticp;
+ bfd_vma voffset;
+ debug_type context;
+ const char *physname;
+ boolean varargs;
+
+ if (look_ahead_type != DEBUG_TYPE_NULL)
+ {
+ /* g++ version 1 kludge */
+ type = look_ahead_type;
+ look_ahead_type = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ if (**pp != ':')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ }
+
+ ++*pp;
+ p = strchr (*pp, ';');
+ if (p == NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ stub = false;
+ if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
+ && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
+ stub = true;
+
+ argtypes = savestring (*pp, p - *pp);
+ *pp = p + 1;
+
+ switch (**pp)
+ {
+ case '0':
+ visibility = DEBUG_VISIBILITY_PRIVATE;
+ break;
+ case '1':
+ visibility = DEBUG_VISIBILITY_PROTECTED;
+ break;
+ default:
+ visibility = DEBUG_VISIBILITY_PUBLIC;
+ break;
+ }
+ ++*pp;
+
+ constp = false;
+ volatilep = false;
+ switch (**pp)
+ {
+ case 'A':
+ /* Normal function. */
+ ++*pp;
+ break;
+ case 'B':
+ /* const member function. */
+ constp = true;
+ ++*pp;
+ break;
+ case 'C':
+ /* volatile member function. */
+ volatilep = true;
+ ++*pp;
+ break;
+ case 'D':
+ /* const volatile member function. */
+ constp = true;
+ volatilep = true;
+ ++*pp;
+ break;
+ case '*':
+ case '?':
+ case '.':
+ /* File compiled with g++ version 1; no information. */
+ break;
+ default:
+ warn_stab (orig, _("const/volatile indicator missing"));
+ break;
+ }
+
+ staticp = false;
+ switch (**pp)
+ {
+ case '*':
+ /* virtual member function, followed by index. The sign
+ bit is supposedly set to distinguish
+ pointers-to-methods from virtual function indicies. */
+ ++*pp;
+ voffset = parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ voffset &= 0x7fffffff;
+
+ if (**pp == ';' || *pp == '\0')
+ {
+ /* Must be g++ version 1. */
+ context = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ /* Figure out from whence this virtual function
+ came. It may belong to virtual function table of
+ one of its baseclasses. */
+ look_ahead_type = parse_stab_type (dhandle, info,
+ (const char *) NULL,
+ pp,
+ (debug_type **) NULL);
+ if (**pp == ':')
+ {
+ /* g++ version 1 overloaded methods. */
+ context = DEBUG_TYPE_NULL;
+ }
+ else
+ {
+ context = look_ahead_type;
+ look_ahead_type = DEBUG_TYPE_NULL;
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+ }
+ }
+ break;
+
+ case '?':
+ /* static member function. */
+ ++*pp;
+ staticp = true;
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ if (strncmp (argtypes, name, strlen (name)) != 0)
+ stub = true;
+ break;
+
+ default:
+ warn_stab (orig, "member function type missing");
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ break;
+
+ case '.':
+ ++*pp;
+ voffset = 0;
+ context = DEBUG_TYPE_NULL;
+ break;
+ }
+
+ /* If the type is not a stub, then the argtypes string is
+ the physical name of the function. Otherwise the
+ argtypes string is the mangled form of the argument
+ types, and the full type and the physical name must be
+ extracted from them. */
+ if (! stub)
+ physname = argtypes;
+ else
+ {
+ debug_type class_type, return_type;
+
+ class_type = stab_find_type (dhandle, info, typenums);
+ if (class_type == DEBUG_TYPE_NULL)
+ return false;
+ return_type = debug_get_return_type (dhandle, type);
+ if (return_type == DEBUG_TYPE_NULL)
+ {
+ bad_stab (orig);
+ return false;
+ }
+ type = parse_stab_argtypes (dhandle, info, class_type, name,
+ tagname, return_type, argtypes,
+ constp, volatilep, &physname);
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+ }
+
+ if (cvars + 1 >= allocvars)
+ {
+ allocvars += 10;
+ variants = ((debug_method_variant *)
+ xrealloc ((PTR) variants,
+ allocvars * sizeof *variants));
+ }
+
+ if (! staticp)
+ variants[cvars] = debug_make_method_variant (dhandle, physname,
+ type, visibility,
+ constp, volatilep,
+ voffset, context);
+ else
+ variants[cvars] = debug_make_static_method_variant (dhandle,
+ physname,
+ type,
+ visibility,
+ constp,
+ volatilep);
+ if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
+ return false;
+
+ ++cvars;
+ }
+ while (**pp != ';' && **pp != '\0');
+
+ variants[cvars] = DEBUG_METHOD_VARIANT_NULL;
+
+ if (**pp != '\0')
+ ++*pp;
+
+ if (c + 1 >= alloc)
+ {
+ alloc += 10;
+ methods = ((debug_method *)
+ xrealloc ((PTR) methods, alloc * sizeof *methods));
+ }
+
+ methods[c] = debug_make_method (dhandle, name, variants);
+
+ ++c;
+ }
+
+ if (methods != NULL)
+ methods[c] = DEBUG_METHOD_NULL;
+
+ *retp = methods;
+
+ return true;
+}
+
+/* Parse a string representing argument types for a method. Stabs
+ tries to save space by packing argument types into a mangled
+ string. This string should give us enough information to extract
+ both argument types and the physical name of the function, given
+ the tag name. */
+
+static debug_type
+parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname,
+ return_type, argtypes, constp, volatilep, pphysname)
+ PTR dhandle;
+ struct stab_handle *info;
+ debug_type class_type;
+ const char *fieldname;
+ const char *tagname;
+ debug_type return_type;
+ const char *argtypes;
+ boolean constp;
+ boolean volatilep;
+ const char **pphysname;
+{
+ boolean is_full_physname_constructor;
+ boolean is_constructor;
+ boolean is_destructor;
+ debug_type *args;
+ boolean varargs;
+
+ /* Constructors are sometimes handled specially. */
+ is_full_physname_constructor = ((argtypes[0] == '_'
+ && argtypes[1] == '_'
+ && (isdigit ((unsigned char) argtypes[2])
+ || argtypes[2] == 'Q'
+ || argtypes[2] == 't'))
+ || strncmp (argtypes, "__ct", 4) == 0);
+
+ is_constructor = (is_full_physname_constructor
+ || (tagname != NULL
+ && strcmp (fieldname, tagname) == 0));
+ is_destructor = ((argtypes[0] == '_'
+ && (argtypes[1] == '$' || argtypes[1] == '.')
+ && argtypes[2] == '_')
+ || strncmp (argtypes, "__dt", 4) == 0);
+
+ if (is_destructor || is_full_physname_constructor)
+ *pphysname = argtypes;
+ else
+ {
+ unsigned int len;
+ const char *const_prefix;
+ const char *volatile_prefix;
+ char buf[20];
+ unsigned int mangled_name_len;
+ char *physname;
+
+ len = tagname == NULL ? 0 : strlen (tagname);
+ const_prefix = constp ? "C" : "";
+ volatile_prefix = volatilep ? "V" : "";
+
+ if (len == 0)
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ else if (tagname != NULL && strchr (tagname, '<') != NULL)
+ {
+ /* Template methods are fully mangled. */
+ sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+ tagname = NULL;
+ len = 0;
+ }
+ else
+ sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+
+ mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
+ + strlen (buf)
+ + len
+ + strlen (argtypes)
+ + 1);
+
+ if (fieldname[0] == 'o'
+ && fieldname[1] == 'p'
+ && (fieldname[2] == '$' || fieldname[2] == '.'))
+ {
+ const char *opname;
+
+ opname = cplus_mangle_opname (fieldname + 3, 0);
+ if (opname == NULL)
+ {
+ fprintf (stderr, _("No mangling for \"%s\"\n"), fieldname);
+ return DEBUG_TYPE_NULL;
+ }
+ mangled_name_len += strlen (opname);
+ physname = (char *) xmalloc (mangled_name_len);
+ strncpy (physname, fieldname, 3);
+ strcpy (physname + 3, opname);
+ }
+ else
+ {
+ physname = (char *) xmalloc (mangled_name_len);
+ if (is_constructor)
+ physname[0] = '\0';
+ else
+ strcpy (physname, fieldname);
+ }
+
+ strcat (physname, buf);
+ if (tagname != NULL)
+ strcat (physname, tagname);
+ strcat (physname, argtypes);
+
+ *pphysname = physname;
+ }
+
+ if (*argtypes == '\0' || is_destructor)
+ {
+ args = (debug_type *) xmalloc (sizeof *args);
+ *args = NULL;
+ return debug_make_method_type (dhandle, return_type, class_type, args,
+ false);
+ }
+
+ args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs);
+ if (args == NULL)
+ return DEBUG_TYPE_NULL;
+
+ return debug_make_method_type (dhandle, return_type, class_type, args,
+ varargs);
+}
+
+/* The tail end of stabs for C++ classes that contain a virtual function
+ pointer contains a tilde, a %, and a type number.
+ The type number refers to the base class (possibly this class itself) which
+ contains the vtable pointer for the current class.
+
+ This function is called when we have parsed all the method declarations,
+ so we can look for the vptr base class info. */
+
+static boolean
+parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ const int *typenums;
+ debug_type *retvptrbase;
+ boolean *retownvptr;
+{
+ const char *orig;
+ const char *hold;
+ int vtypenums[2];
+
+ *retvptrbase = DEBUG_TYPE_NULL;
+ *retownvptr = false;
+
+ orig = *pp;
+
+ /* If we are positioned at a ';', then skip it. */
+ if (**pp == ';')
+ ++*pp;
+
+ if (**pp != '~')
+ return true;
+
+ ++*pp;
+
+ if (**pp == '=' || **pp == '+' || **pp == '-')
+ {
+ /* Obsolete flags that used to indicate the presence of
+ constructors and/or destructors. */
+ ++*pp;
+ }
+
+ if (**pp != '%')
+ return true;
+
+ ++*pp;
+
+ hold = *pp;
+
+ /* The next number is the type number of the base class (possibly
+ our own class) which supplies the vtable for this class. */
+ if (! parse_stab_type_number (pp, vtypenums))
+ return false;
+
+ if (vtypenums[0] == typenums[0]
+ && vtypenums[1] == typenums[1])
+ *retownvptr = true;
+ else
+ {
+ debug_type vtype;
+ const char *p;
+
+ *pp = hold;
+
+ vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ for (p = *pp; *p != ';' && *p != '\0'; p++)
+ ;
+ if (*p != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+
+ *retvptrbase = vtype;
+
+ *pp = p + 1;
+ }
+
+ return true;
+}
+
+/* Read a definition of an array type. */
+
+static debug_type
+parse_stab_array_type (dhandle, info, pp, stringp)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char **pp;
+ boolean stringp;
+{
+ const char *orig;
+ const char *p;
+ int typenums[2];
+ debug_type index_type;
+ boolean adjustable;
+ bfd_signed_vma lower, upper;
+ debug_type element_type;
+
+ /* Format of an array type:
+ "ar<index type>;lower;upper;<array_contents_type>".
+ OS9000: "arlower,upper;<array_contents_type>".
+
+ Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
+ for these, produce a type like float[][]. */
+
+ orig = *pp;
+
+ /* FIXME: gdb checks os9k_stabs here. */
+
+ /* If the index type is type 0, we take it as int. */
+ p = *pp;
+ if (! parse_stab_type_number (&p, typenums))
+ return false;
+ if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
+ {
+ index_type = debug_find_named_type (dhandle, "int");
+ if (index_type == DEBUG_TYPE_NULL)
+ {
+ index_type = debug_make_int_type (dhandle, 4, false);
+ if (index_type == DEBUG_TYPE_NULL)
+ return false;
+ }
+ *pp = p;
+ }
+ else
+ {
+ index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ }
+
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return DEBUG_TYPE_NULL;
+ }
+ ++*pp;
+
+ adjustable = false;
+
+ if (! isdigit ((unsigned char) **pp) && **pp != '-')
+ {
+ ++*pp;
+ adjustable = true;
+ }
+
+ lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! isdigit ((unsigned char) **pp) && **pp != '-')
+ {
+ ++*pp;
+ adjustable = true;
+ }
+
+ upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL);
+ if (**pp != ';')
+ {
+ bad_stab (orig);
+ return false;
+ }
+ ++*pp;
+
+ element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
+ (debug_type **) NULL);
+ if (element_type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (adjustable)
+ {
+ lower = 0;
+ upper = -1;
+ }
+
+ return debug_make_array_type (dhandle, element_type, index_type, lower,
+ upper, stringp);
+}
+
+/* This struct holds information about files we have seen using
+ N_BINCL. */
+
+struct bincl_file
+{
+ /* The next N_BINCL file. */
+ struct bincl_file *next;
+ /* The next N_BINCL on the stack. */
+ struct bincl_file *next_stack;
+ /* The file name. */
+ const char *name;
+ /* The hash value. */
+ bfd_vma hash;
+ /* The file index. */
+ unsigned int file;
+ /* The list of types defined in this file. */
+ struct stab_types *file_types;
+};
+
+/* Start a new N_BINCL file, pushing it onto the stack. */
+
+static void
+push_bincl (info, name, hash)
+ struct stab_handle *info;
+ const char *name;
+ bfd_vma hash;
+{
+ struct bincl_file *n;
+
+ n = (struct bincl_file *) xmalloc (sizeof *n);
+ n->next = info->bincl_list;
+ n->next_stack = info->bincl_stack;
+ n->name = name;
+ n->hash = hash;
+ n->file = info->files;
+ n->file_types = NULL;
+ info->bincl_list = n;
+ info->bincl_stack = n;
+
+ ++info->files;
+ info->file_types = ((struct stab_types **)
+ xrealloc ((PTR) info->file_types,
+ (info->files
+ * sizeof *info->file_types)));
+ info->file_types[n->file] = NULL;
+}
+
+/* Finish an N_BINCL file, at an N_EINCL, popping the name off the
+ stack. */
+
+static const char *
+pop_bincl (info)
+ struct stab_handle *info;
+{
+ struct bincl_file *o;
+
+ o = info->bincl_stack;
+ if (o == NULL)
+ return info->main_filename;
+ info->bincl_stack = o->next_stack;
+
+ o->file_types = info->file_types[o->file];
+
+ if (info->bincl_stack == NULL)
+ return info->main_filename;
+ return info->bincl_stack->name;
+}
+
+/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */
+
+static boolean
+find_excl (info, name, hash)
+ struct stab_handle *info;
+ const char *name;
+ bfd_vma hash;
+{
+ struct bincl_file *l;
+
+ ++info->files;
+ info->file_types = ((struct stab_types **)
+ xrealloc ((PTR) info->file_types,
+ (info->files
+ * sizeof *info->file_types)));
+
+ for (l = info->bincl_list; l != NULL; l = l->next)
+ if (l->hash == hash && strcmp (l->name, name) == 0)
+ break;
+ if (l == NULL)
+ {
+ warn_stab (name, _("Undefined N_EXCL"));
+ info->file_types[info->files - 1] = NULL;
+ return true;
+ }
+
+ info->file_types[info->files - 1] = l->file_types;
+
+ return true;
+}
+
+/* Handle a variable definition. gcc emits variable definitions for a
+ block before the N_LBRAC, so we must hold onto them until we see
+ it. The SunPRO compiler emits variable definitions after the
+ N_LBRAC, so we can call debug_record_variable immediately. */
+
+static boolean
+stab_record_variable (dhandle, info, name, type, kind, val)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *name;
+ debug_type type;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct stab_pending_var *v;
+
+ if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
+ || ! info->within_function
+ || (info->gcc_compiled == 0 && info->n_opt_found))
+ return debug_record_variable (dhandle, name, type, kind, val);
+
+ v = (struct stab_pending_var *) xmalloc (sizeof *v);
+ memset (v, 0, sizeof *v);
+
+ v->next = info->pending;
+ v->name = name;
+ v->type = type;
+ v->kind = kind;
+ v->val = val;
+ info->pending = v;
+
+ return true;
+}
+
+/* Emit pending variable definitions. This is called after we see the
+ N_LBRAC that starts the block. */
+
+static boolean
+stab_emit_pending_vars (dhandle, info)
+ PTR dhandle;
+ struct stab_handle *info;
+{
+ struct stab_pending_var *v;
+
+ v = info->pending;
+ while (v != NULL)
+ {
+ struct stab_pending_var *next;
+
+ if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
+ return false;
+
+ next = v->next;
+ free (v);
+ v = next;
+ }
+
+ info->pending = NULL;
+
+ return true;
+}
+
+/* Find the slot for a type in the database. */
+
+static debug_type *
+stab_find_slot (info, typenums)
+ struct stab_handle *info;
+ const int *typenums;
+{
+ int filenum;
+ int index;
+ struct stab_types **ps;
+
+ filenum = typenums[0];
+ index = typenums[1];
+
+ if (filenum < 0 || (unsigned int) filenum >= info->files)
+ {
+ fprintf (stderr, _("Type file number %d out of range\n"), filenum);
+ return NULL;
+ }
+ if (index < 0)
+ {
+ fprintf (stderr, _("Type index number %d out of range\n"), index);
+ return NULL;
+ }
+
+ ps = info->file_types + filenum;
+
+ while (index >= STAB_TYPES_SLOTS)
+ {
+ if (*ps == NULL)
+ {
+ *ps = (struct stab_types *) xmalloc (sizeof **ps);
+ memset (*ps, 0, sizeof **ps);
+ }
+ ps = &(*ps)->next;
+ index -= STAB_TYPES_SLOTS;
+ }
+ if (*ps == NULL)
+ {
+ *ps = (struct stab_types *) xmalloc (sizeof **ps);
+ memset (*ps, 0, sizeof **ps);
+ }
+
+ return (*ps)->types + index;
+}
+
+/* Find a type given a type number. If the type has not been
+ allocated yet, create an indirect type. */
+
+static debug_type
+stab_find_type (dhandle, info, typenums)
+ PTR dhandle;
+ struct stab_handle *info;
+ const int *typenums;
+{
+ debug_type *slot;
+
+ if (typenums[0] == 0 && typenums[1] < 0)
+ {
+ /* A negative type number indicates an XCOFF builtin type. */
+ return stab_xcoff_builtin_type (dhandle, info, typenums[1]);
+ }
+
+ slot = stab_find_slot (info, typenums);
+ if (slot == NULL)
+ return DEBUG_TYPE_NULL;
+
+ if (*slot == DEBUG_TYPE_NULL)
+ return debug_make_indirect_type (dhandle, slot, (const char *) NULL);
+
+ return *slot;
+}
+
+/* Record that a given type number refers to a given type. */
+
+static boolean
+stab_record_type (dhandle, info, typenums, type)
+ PTR dhandle;
+ struct stab_handle *info;
+ const int *typenums;
+ debug_type type;
+{
+ debug_type *slot;
+
+ slot = stab_find_slot (info, typenums);
+ if (slot == NULL)
+ return false;
+
+ /* gdb appears to ignore type redefinitions, so we do as well. */
+
+ *slot = type;
+
+ return true;
+}
+
+/* Return an XCOFF builtin type. */
+
+static debug_type
+stab_xcoff_builtin_type (dhandle, info, typenum)
+ PTR dhandle;
+ struct stab_handle *info;
+ int typenum;
+{
+ debug_type rettype;
+ const char *name;
+
+ if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
+ {
+ fprintf (stderr, _("Unrecognized XCOFF type %d\n"), typenum);
+ return DEBUG_TYPE_NULL;
+ }
+ if (info->xcoff_types[-typenum] != NULL)
+ return info->xcoff_types[-typenum];
+
+ switch (-typenum)
+ {
+ case 1:
+ /* The size of this and all the other types are fixed, defined
+ by the debugging format. */
+ name = "int";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 2:
+ name = "char";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 3:
+ name = "short";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 4:
+ name = "long";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 5:
+ name = "unsigned char";
+ rettype = debug_make_int_type (dhandle, 1, true);
+ break;
+ case 6:
+ name = "signed char";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 7:
+ name = "unsigned short";
+ rettype = debug_make_int_type (dhandle, 2, true);
+ break;
+ case 8:
+ name = "unsigned int";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ break;
+ case 9:
+ name = "unsigned";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ case 10:
+ name = "unsigned long";
+ rettype = debug_make_int_type (dhandle, 4, true);
+ break;
+ case 11:
+ name = "void";
+ rettype = debug_make_void_type (dhandle);
+ break;
+ case 12:
+ /* IEEE single precision (32 bit). */
+ name = "float";
+ rettype = debug_make_float_type (dhandle, 4);
+ break;
+ case 13:
+ /* IEEE double precision (64 bit). */
+ name = "double";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 14:
+ /* This is an IEEE double on the RS/6000, and different machines
+ with different sizes for "long double" should use different
+ negative type numbers. See stabs.texinfo. */
+ name = "long double";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 15:
+ name = "integer";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 16:
+ name = "boolean";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 17:
+ name = "short real";
+ rettype = debug_make_float_type (dhandle, 4);
+ break;
+ case 18:
+ name = "real";
+ rettype = debug_make_float_type (dhandle, 8);
+ break;
+ case 19:
+ /* FIXME */
+ name = "stringptr";
+ rettype = NULL;
+ break;
+ case 20:
+ /* FIXME */
+ name = "character";
+ rettype = debug_make_int_type (dhandle, 1, true);
+ break;
+ case 21:
+ name = "logical*1";
+ rettype = debug_make_bool_type (dhandle, 1);
+ break;
+ case 22:
+ name = "logical*2";
+ rettype = debug_make_bool_type (dhandle, 2);
+ break;
+ case 23:
+ name = "logical*4";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 24:
+ name = "logical";
+ rettype = debug_make_bool_type (dhandle, 4);
+ break;
+ case 25:
+ /* Complex type consisting of two IEEE single precision values. */
+ name = "complex";
+ rettype = debug_make_complex_type (dhandle, 8);
+ break;
+ case 26:
+ /* Complex type consisting of two IEEE double precision values. */
+ name = "double complex";
+ rettype = debug_make_complex_type (dhandle, 16);
+ break;
+ case 27:
+ name = "integer*1";
+ rettype = debug_make_int_type (dhandle, 1, false);
+ break;
+ case 28:
+ name = "integer*2";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 29:
+ name = "integer*4";
+ rettype = debug_make_int_type (dhandle, 4, false);
+ break;
+ case 30:
+ /* FIXME */
+ name = "wchar";
+ rettype = debug_make_int_type (dhandle, 2, false);
+ break;
+ case 31:
+ name = "long long";
+ rettype = debug_make_int_type (dhandle, 8, false);
+ break;
+ case 32:
+ name = "unsigned long long";
+ rettype = debug_make_int_type (dhandle, 8, true);
+ break;
+ case 33:
+ name = "logical*8";
+ rettype = debug_make_bool_type (dhandle, 8);
+ break;
+ case 34:
+ name = "integer*8";
+ rettype = debug_make_int_type (dhandle, 8, false);
+ break;
+ default:
+ abort ();
+ }
+
+ rettype = debug_name_type (dhandle, name, rettype);
+
+ info->xcoff_types[-typenum] = rettype;
+
+ return rettype;
+}
+
+/* Find or create a tagged type. */
+
+static debug_type
+stab_find_tagged_type (dhandle, info, p, len, kind)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *p;
+ int len;
+ enum debug_type_kind kind;
+{
+ char *name;
+ debug_type dtype;
+ struct stab_tag *st;
+
+ name = savestring (p, len);
+
+ /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same
+ namespace. This is right for C, and I don't know how to handle
+ other languages. FIXME. */
+ dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL);
+ if (dtype != DEBUG_TYPE_NULL)
+ {
+ free (name);
+ return dtype;
+ }
+
+ /* We need to allocate an entry on the undefined tag list. */
+ for (st = info->tags; st != NULL; st = st->next)
+ {
+ if (st->name[0] == name[0]
+ && strcmp (st->name, name) == 0)
+ {
+ if (st->kind == DEBUG_KIND_ILLEGAL)
+ st->kind = kind;
+ free (name);
+ break;
+ }
+ }
+ if (st == NULL)
+ {
+ st = (struct stab_tag *) xmalloc (sizeof *st);
+ memset (st, 0, sizeof *st);
+
+ st->next = info->tags;
+ st->name = name;
+ st->kind = kind;
+ st->slot = DEBUG_TYPE_NULL;
+ st->type = debug_make_indirect_type (dhandle, &st->slot, name);
+ info->tags = st;
+ }
+
+ return st->type;
+}
+
+/* In order to get the correct argument types for a stubbed method, we
+ need to extract the argument types from a C++ mangled string.
+ Since the argument types can refer back to the return type, this
+ means that we must demangle the entire physical name. In gdb this
+ is done by calling cplus_demangle and running the results back
+ through the C++ expression parser. Since we have no expression
+ parser, we must duplicate much of the work of cplus_demangle here.
+
+ We assume that GNU style demangling is used, since this is only
+ done for method stubs, and only g++ should output that form of
+ debugging information. */
+
+/* This structure is used to hold a pointer to type information which
+ demangling a string. */
+
+struct stab_demangle_typestring
+{
+ /* The start of the type. This is not null terminated. */
+ const char *typestring;
+ /* The length of the type. */
+ unsigned int len;
+};
+
+/* This structure is used to hold information while demangling a
+ string. */
+
+struct stab_demangle_info
+{
+ /* The debugging information handle. */
+ PTR dhandle;
+ /* The stab information handle. */
+ struct stab_handle *info;
+ /* The array of arguments we are building. */
+ debug_type *args;
+ /* Whether the method takes a variable number of arguments. */
+ boolean varargs;
+ /* The array of types we have remembered. */
+ struct stab_demangle_typestring *typestrings;
+ /* The number of typestrings. */
+ unsigned int typestring_count;
+ /* The number of typestring slots we have allocated. */
+ unsigned int typestring_alloc;
+};
+
+static void stab_bad_demangle PARAMS ((const char *));
+static unsigned int stab_demangle_count PARAMS ((const char **));
+static boolean stab_demangle_get_count
+ PARAMS ((const char **, unsigned int *));
+static boolean stab_demangle_prefix
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_function_name
+ PARAMS ((struct stab_demangle_info *, const char **, const char *));
+static boolean stab_demangle_signature
+ PARAMS ((struct stab_demangle_info *, const char **));
+static boolean stab_demangle_qualified
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_template
+ PARAMS ((struct stab_demangle_info *, const char **, char **));
+static boolean stab_demangle_class
+ PARAMS ((struct stab_demangle_info *, const char **, const char **));
+static boolean stab_demangle_args
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+ boolean *));
+static boolean stab_demangle_arg
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type **,
+ unsigned int *, unsigned int *));
+static boolean stab_demangle_type
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_fund_type
+ PARAMS ((struct stab_demangle_info *, const char **, debug_type *));
+static boolean stab_demangle_remember_type
+ PARAMS ((struct stab_demangle_info *, const char *, int));
+
+/* Warn about a bad demangling. */
+
+static void
+stab_bad_demangle (s)
+ const char *s;
+{
+ fprintf (stderr, _("bad mangled name `%s'\n"), s);
+}
+
+/* Get a count from a stab string. */
+
+static unsigned int
+stab_demangle_count (pp)
+ const char **pp;
+{
+ unsigned int count;
+
+ count = 0;
+ while (isdigit ((unsigned char) **pp))
+ {
+ count *= 10;
+ count += **pp - '0';
+ ++*pp;
+ }
+ return count;
+}
+
+/* Require a count in a string. The count may be multiple digits, in
+ which case it must end in an underscore. */
+
+static boolean
+stab_demangle_get_count (pp, pi)
+ const char **pp;
+ unsigned int *pi;
+{
+ if (! isdigit ((unsigned char) **pp))
+ return false;
+
+ *pi = **pp - '0';
+ ++*pp;
+ if (isdigit ((unsigned char) **pp))
+ {
+ unsigned int count;
+ const char *p;
+
+ count = *pi;
+ p = *pp;
+ do
+ {
+ count *= 10;
+ count += *p - '0';
+ ++p;
+ }
+ while (isdigit ((unsigned char) *p));
+ if (*p == '_')
+ {
+ *pp = p + 1;
+ *pi = count;
+ }
+ }
+
+ return true;
+}
+
+/* This function demangles a physical name, returning a NULL
+ terminated array of argument types. */
+
+static debug_type *
+stab_demangle_argtypes (dhandle, info, physname, pvarargs)
+ PTR dhandle;
+ struct stab_handle *info;
+ const char *physname;
+ boolean *pvarargs;
+{
+ struct stab_demangle_info minfo;
+
+ minfo.dhandle = dhandle;
+ minfo.info = info;
+ minfo.args = NULL;
+ minfo.varargs = false;
+ minfo.typestring_alloc = 10;
+ minfo.typestrings = ((struct stab_demangle_typestring *)
+ xmalloc (minfo.typestring_alloc
+ * sizeof *minfo.typestrings));
+ minfo.typestring_count = 0;
+
+ /* cplus_demangle checks for special GNU mangled forms, but we can't
+ see any of them in mangled method argument types. */
+
+ if (! stab_demangle_prefix (&minfo, &physname))
+ goto error_return;
+
+ if (*physname != '\0')
+ {
+ if (! stab_demangle_signature (&minfo, &physname))
+ goto error_return;
+ }
+
+ free (minfo.typestrings);
+ minfo.typestrings = NULL;
+
+ if (minfo.args == NULL)
+ fprintf (stderr, _("no argument types in mangled string\n"));
+
+ *pvarargs = minfo.varargs;
+ return minfo.args;
+
+ error_return:
+ if (minfo.typestrings != NULL)
+ free (minfo.typestrings);
+ return NULL;
+}
+
+/* Demangle the prefix of the mangled name. */
+
+static boolean
+stab_demangle_prefix (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *scan;
+ unsigned int i;
+
+ /* cplus_demangle checks for global constructors and destructors,
+ but we can't see them in mangled argument types. */
+
+ /* Look for `__'. */
+ scan = *pp;
+ do
+ {
+ scan = strchr (scan, '_');
+ }
+ while (scan != NULL && *++scan != '_');
+
+ if (scan == NULL)
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+
+ --scan;
+
+ /* We found `__'; move ahead to the last contiguous `__' pair. */
+ i = strspn (scan, "_");
+ if (i > 2)
+ scan += i - 2;
+
+ if (scan == *pp
+ && (isdigit ((unsigned char) scan[2])
+ || scan[2] == 'Q'
+ || scan[2] == 't'))
+ {
+ /* This is a GNU style constructor name. */
+ *pp = scan + 2;
+ return true;
+ }
+ else if (scan == *pp
+ && ! isdigit ((unsigned char) scan[2])
+ && scan[2] != 't')
+ {
+ /* Look for the `__' that separates the prefix from the
+ signature. */
+ while (*scan == '_')
+ ++scan;
+ scan = strstr (scan, "__");
+ if (scan == NULL || scan[2] == '\0')
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+
+ return stab_demangle_function_name (minfo, pp, scan);
+ }
+ else if (scan[2] != '\0')
+ {
+ /* The name doesn't start with `__', but it does contain `__'. */
+ return stab_demangle_function_name (minfo, pp, scan);
+ }
+ else
+ {
+ stab_bad_demangle (*pp);
+ return false;
+ }
+ /*NOTREACHED*/
+}
+
+/* Demangle a function name prefix. The scan argument points to the
+ double underscore which separates the function name from the
+ signature. */
+
+static boolean
+stab_demangle_function_name (minfo, pp, scan)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ const char *scan;
+{
+ const char *name;
+
+ /* The string from *pp to scan is the name of the function. We
+ don't care about the name, since we just looking for argument
+ types. However, for conversion operators, the name may include a
+ type which we must remember in order to handle backreferences. */
+
+ name = *pp;
+ *pp = scan + 2;
+
+ if (*pp - name >= 5
+ && strncmp (name, "type", 4) == 0
+ && (name[4] == '$' || name[4] == '.'))
+ {
+ const char *tem;
+
+ /* This is a type conversion operator. */
+ tem = name + 5;
+ if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
+ return false;
+ }
+ else if (name[0] == '_'
+ && name[1] == '_'
+ && name[2] == 'o'
+ && name[3] == 'p')
+ {
+ const char *tem;
+
+ /* This is a type conversion operator. */
+ tem = name + 4;
+ if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
+ return false;
+ }
+
+ return true;
+}
+
+/* Demangle the signature. This is where the argument types are
+ found. */
+
+static boolean
+stab_demangle_signature (minfo, pp)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+{
+ const char *orig;
+ boolean expect_func, func_done;
+ const char *hold;
+
+ orig = *pp;
+
+ expect_func = false;
+ func_done = false;
+ hold = NULL;
+
+ while (**pp != '\0')
+ {
+ switch (**pp)
+ {
+ case 'Q':
+ hold = *pp;
+ if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ expect_func = true;
+ hold = NULL;
+ break;
+
+ case 'S':
+ /* Static member function. FIXME: Can this happen? */
+ if (hold == NULL)
+ hold = *pp;
+ ++*pp;
+ break;
+
+ case 'C':
+ /* Const member function. */
+ if (hold == NULL)
+ hold = *pp;
+ ++*pp;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (hold == NULL)
+ hold = *pp;
+ if (! stab_demangle_class (minfo, pp, (const char **) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ expect_func = true;
+ hold = NULL;
+ break;
+
+ case 'F':
+ /* Function. I don't know if this actually happens with g++
+ output. */
+ hold = NULL;
+ func_done = true;
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ break;
+
+ case 't':
+ /* Template. */
+ if (hold == NULL)
+ hold = *pp;
+ if (! stab_demangle_template (minfo, pp, (char **) NULL)
+ || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
+ return false;
+ hold = NULL;
+ expect_func = true;
+ break;
+
+ case '_':
+ /* At the outermost level, we cannot have a return type
+ specified, so if we run into another '_' at this point we
+ are dealing with a mangled name that is either bogus, or
+ has been mangled by some algorithm we don't know how to
+ deal with. So just reject the entire demangling. */
+ stab_bad_demangle (orig);
+ return false;
+
+ default:
+ /* Assume we have stumbled onto the first outermost function
+ argument token, and start processing args. */
+ func_done = true;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ break;
+ }
+
+ if (expect_func)
+ {
+ func_done = true;
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ }
+ }
+
+ if (! func_done)
+ {
+ /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
+ bar__3fooi is 'foo::bar(int)'. We get here when we find the
+ first case, and need to ensure that the '(void)' gets added
+ to the current declp. */
+ if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
+ return false;
+ }
+
+ return true;
+}
+
+/* Demangle a qualified name, such as "Q25Outer5Inner" which is the
+ mangled form of "Outer::Inner". */
+
+static boolean
+stab_demangle_qualified (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+ const char *p;
+ unsigned int qualifiers;
+ debug_type context;
+
+ orig = *pp;
+
+ switch ((*pp)[1])
+ {
+ case '_':
+ /* GNU mangled name with more than 9 classes. The count is
+ preceded by an underscore (to distinguish it from the <= 9
+ case) and followed by an underscore. */
+ p = *pp + 2;
+ if (! isdigit ((unsigned char) *p) || *p == '0')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ qualifiers = atoi (p);
+ while (isdigit ((unsigned char) *p))
+ ++p;
+ if (*p != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp = p + 1;
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ qualifiers = (*pp)[1] - '0';
+ /* Skip an optional underscore after the count. */
+ if ((*pp)[2] == '_')
+ ++*pp;
+ *pp += 2;
+ break;
+
+ case '0':
+ default:
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ context = DEBUG_TYPE_NULL;
+
+ /* Pick off the names. */
+ while (qualifiers-- > 0)
+ {
+ if (**pp == '_')
+ ++*pp;
+ if (**pp == 't')
+ {
+ char *name;
+
+ if (! stab_demangle_template (minfo, pp,
+ ptype != NULL ? &name : NULL))
+ return false;
+
+ if (ptype != NULL)
+ {
+ context = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ name, strlen (name),
+ DEBUG_KIND_CLASS);
+ free (name);
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+ else
+ {
+ unsigned int len;
+
+ len = stab_demangle_count (pp);
+ if (strlen (*pp) < len)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (ptype != NULL)
+ {
+ const debug_field *fields;
+
+ fields = NULL;
+ if (context != DEBUG_TYPE_NULL)
+ fields = debug_get_fields (minfo->dhandle, context);
+
+ context = DEBUG_TYPE_NULL;
+
+ if (fields != NULL)
+ {
+ char *name;
+
+ /* Try to find the type by looking through the
+ fields of context until we find a field with the
+ same type. This ought to work for a class
+ defined within a class, but it won't work for,
+ e.g., an enum defined within a class. stabs does
+ not give us enough information to figure out the
+ latter case. */
+
+ name = savestring (*pp, len);
+
+ for (; *fields != DEBUG_FIELD_NULL; fields++)
+ {
+ debug_type ft;
+ const char *dn;
+
+ ft = debug_get_field_type (minfo->dhandle, *fields);
+ if (ft == NULL)
+ return false;
+ dn = debug_get_type_name (minfo->dhandle, ft);
+ if (dn != NULL && strcmp (dn, name) == 0)
+ {
+ context = ft;
+ break;
+ }
+ }
+
+ free (name);
+ }
+
+ if (context == DEBUG_TYPE_NULL)
+ {
+ /* We have to fall back on finding the type by name.
+ If there are more types to come, then this must
+ be a class. Otherwise, it could be anything. */
+
+ if (qualifiers == 0)
+ {
+ char *name;
+
+ name = savestring (*pp, len);
+ context = debug_find_named_type (minfo->dhandle,
+ name);
+ free (name);
+ }
+
+ if (context == DEBUG_TYPE_NULL)
+ {
+ context = stab_find_tagged_type (minfo->dhandle,
+ minfo->info,
+ *pp, len,
+ (qualifiers == 0
+ ? DEBUG_KIND_ILLEGAL
+ : DEBUG_KIND_CLASS));
+ if (context == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+ }
+
+ *pp += len;
+ }
+ }
+
+ if (ptype != NULL)
+ *ptype = context;
+
+ return true;
+}
+
+/* Demangle a template. If PNAME is not NULL, this sets *PNAME to a
+ string representation of the template. */
+
+static boolean
+stab_demangle_template (minfo, pp, pname)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ char **pname;
+{
+ const char *orig;
+ unsigned int r, i;
+
+ orig = *pp;
+
+ ++*pp;
+
+ /* Skip the template name. */
+ r = stab_demangle_count (pp);
+ if (r == 0 || strlen (*pp) < r)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp += r;
+
+ /* Get the size of the parameter list. */
+ if (stab_demangle_get_count (pp, &r) == 0)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ for (i = 0; i < r; i++)
+ {
+ if (**pp == 'Z')
+ {
+ /* This is a type parameter. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
+ return false;
+ }
+ else
+ {
+ const char *old_p;
+ boolean pointerp, realp, integralp, charp, boolp;
+ boolean done;
+
+ old_p = *pp;
+ pointerp = false;
+ realp = false;
+ integralp = false;
+ charp = false;
+ boolp = false;
+ done = false;
+
+ /* This is a value parameter. */
+
+ if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
+ return false;
+
+ while (*old_p != '\0' && ! done)
+ {
+ switch (*old_p)
+ {
+ case 'P':
+ case 'p':
+ case 'R':
+ pointerp = true;
+ done = true;
+ break;
+ case 'C': /* Const. */
+ case 'S': /* Signed. */
+ case 'U': /* Unsigned. */
+ case 'V': /* Volatile. */
+ case 'F': /* Function. */
+ case 'M': /* Member function. */
+ case 'O': /* ??? */
+ ++old_p;
+ break;
+ case 'Q': /* Qualified name. */
+ integralp = true;
+ done = true;
+ break;
+ case 'T': /* Remembered type. */
+ abort ();
+ case 'v': /* Void. */
+ abort ();
+ case 'x': /* Long long. */
+ case 'l': /* Long. */
+ case 'i': /* Int. */
+ case 's': /* Short. */
+ case 'w': /* Wchar_t. */
+ integralp = true;
+ done = true;
+ break;
+ case 'b': /* Bool. */
+ boolp = true;
+ done = true;
+ break;
+ case 'c': /* Char. */
+ charp = true;
+ done = true;
+ break;
+ case 'r': /* Long double. */
+ case 'd': /* Double. */
+ case 'f': /* Float. */
+ realp = true;
+ done = true;
+ break;
+ default:
+ /* Assume it's a user defined integral type. */
+ integralp = true;
+ done = true;
+ break;
+ }
+ }
+
+ if (integralp)
+ {
+ if (**pp == 'm')
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ else if (charp)
+ {
+ unsigned int val;
+
+ if (**pp == 'm')
+ ++*pp;
+ val = stab_demangle_count (pp);
+ if (val == 0)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+ else if (boolp)
+ {
+ unsigned int val;
+
+ val = stab_demangle_count (pp);
+ if (val != 0 && val != 1)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+ else if (realp)
+ {
+ if (**pp == 'm')
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ if (**pp == '.')
+ {
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ if (**pp == 'e')
+ {
+ ++*pp;
+ while (isdigit ((unsigned char) **pp))
+ ++*pp;
+ }
+ }
+ else if (pointerp)
+ {
+ unsigned int len;
+
+ if (! stab_demangle_get_count (pp, &len))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ *pp += len;
+ }
+ }
+ }
+
+ /* We can translate this to a string fairly easily by invoking the
+ regular demangling routine. */
+ if (pname != NULL)
+ {
+ char *s1, *s2, *s3, *s4;
+ char *from, *to;
+
+ s1 = savestring (orig, *pp - orig);
+
+ s2 = concat ("NoSuchStrinG__", s1, (const char *) NULL);
+
+ free (s1);
+
+ s3 = cplus_demangle (s2, DMGL_ANSI);
+
+ free (s2);
+
+ if (s3 != NULL)
+ s4 = strstr (s3, "::NoSuchStrinG");
+ if (s3 == NULL || s4 == NULL)
+ {
+ stab_bad_demangle (orig);
+ if (s3 != NULL)
+ free (s3);
+ return false;
+ }
+
+ /* Eliminating all spaces, except those between > characters,
+ makes it more likely that the demangled name will match the
+ name which g++ used as the structure name. */
+ for (from = to = s3; from != s4; ++from)
+ if (*from != ' '
+ || (from[1] == '>' && from > s3 && from[-1] == '>'))
+ *to++ = *from;
+
+ *pname = savestring (s3, to - s3);
+
+ free (s3);
+ }
+
+ return true;
+}
+
+/* Demangle a class name. */
+
+static boolean
+stab_demangle_class (minfo, pp, pstart)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ const char **pstart;
+{
+ const char *orig;
+ unsigned int n;
+
+ orig = *pp;
+
+ n = stab_demangle_count (pp);
+ if (strlen (*pp) < n)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (pstart != NULL)
+ *pstart = *pp;
+
+ *pp += n;
+
+ return true;
+}
+
+/* Demangle function arguments. If the pargs argument is not NULL, it
+ is set to a NULL terminated array holding the arguments. */
+
+static boolean
+stab_demangle_args (minfo, pp, pargs, pvarargs)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type **pargs;
+ boolean *pvarargs;
+{
+ const char *orig;
+ unsigned int alloc, count;
+
+ orig = *pp;
+
+ alloc = 10;
+ if (pargs != NULL)
+ {
+ *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
+ *pvarargs = false;
+ }
+ count = 0;
+
+ while (**pp != '_' && **pp != '\0' && **pp != 'e')
+ {
+ if (**pp == 'N' || **pp == 'T')
+ {
+ char temptype;
+ unsigned int r, t;
+
+ temptype = **pp;
+ ++*pp;
+
+ if (temptype == 'T')
+ r = 1;
+ else
+ {
+ if (! stab_demangle_get_count (pp, &r))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ }
+
+ if (! stab_demangle_get_count (pp, &t))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (t >= minfo->typestring_count)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ while (r-- > 0)
+ {
+ const char *tem;
+
+ tem = minfo->typestrings[t].typestring;
+ if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
+ return false;
+ }
+ }
+ else
+ {
+ if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
+ return false;
+ }
+ }
+
+ if (pargs != NULL)
+ (*pargs)[count] = DEBUG_TYPE_NULL;
+
+ if (**pp == 'e')
+ {
+ if (pargs != NULL)
+ *pvarargs = true;
+ ++*pp;
+ }
+
+ return true;
+}
+
+/* Demangle a single argument. */
+
+static boolean
+stab_demangle_arg (minfo, pp, pargs, pcount, palloc)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type **pargs;
+ unsigned int *pcount;
+ unsigned int *palloc;
+{
+ const char *start;
+ debug_type type;
+
+ start = *pp;
+ if (! stab_demangle_type (minfo, pp,
+ pargs == NULL ? (debug_type *) NULL : &type)
+ || ! stab_demangle_remember_type (minfo, start, *pp - start))
+ return false;
+
+ if (pargs != NULL)
+ {
+ if (type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (*pcount + 1 >= *palloc)
+ {
+ *palloc += 10;
+ *pargs = ((debug_type *)
+ xrealloc (*pargs, *palloc * sizeof **pargs));
+ }
+ (*pargs)[*pcount] = type;
+ ++*pcount;
+ }
+
+ return true;
+}
+
+/* Demangle a type. If the ptype argument is not NULL, *ptype is set
+ to the newly allocated type. */
+
+static boolean
+stab_demangle_type (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+
+ orig = *pp;
+
+ switch (**pp)
+ {
+ case 'P':
+ case 'p':
+ /* A pointer type. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'R':
+ /* A reference type. */
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'A':
+ /* An array. */
+ {
+ unsigned long high;
+
+ ++*pp;
+ high = 0;
+ while (**pp != '\0' && **pp != '_')
+ {
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ high *= 10;
+ high += **pp - '0';
+ ++*pp;
+ }
+ if (**pp != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ {
+ debug_type int_type;
+
+ int_type = debug_find_named_type (minfo->dhandle, "int");
+ if (int_type == NULL)
+ int_type = debug_make_int_type (minfo->dhandle, 4, false);
+ *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
+ 0, high, false);
+ }
+ }
+ break;
+
+ case 'T':
+ /* A back reference to a remembered type. */
+ {
+ unsigned int i;
+ const char *p;
+
+ ++*pp;
+ if (! stab_demangle_get_count (pp, &i))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ if (i >= minfo->typestring_count)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ p = minfo->typestrings[i].typestring;
+ if (! stab_demangle_type (minfo, &p, ptype))
+ return false;
+ }
+ break;
+
+ case 'F':
+ /* A function. */
+ {
+ debug_type *args;
+ boolean varargs;
+
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp,
+ (ptype == NULL
+ ? (debug_type **) NULL
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
+ return false;
+ if (**pp != '_')
+ {
+ /* cplus_demangle will accept a function without a return
+ type, but I don't know when that will happen, or what
+ to do if it does. */
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
+ varargs);
+
+ }
+ break;
+
+ case 'M':
+ case 'O':
+ {
+ boolean memberp, constp, volatilep;
+ debug_type *args;
+ boolean varargs;
+ unsigned int n;
+ const char *name;
+
+ memberp = **pp == 'M';
+ constp = false;
+ volatilep = false;
+ args = NULL;
+ varargs = false;
+
+ ++*pp;
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ n = stab_demangle_count (pp);
+ if (strlen (*pp) < n)
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ name = *pp;
+ *pp += n;
+
+ if (memberp)
+ {
+ if (**pp == 'C')
+ {
+ constp = true;
+ ++*pp;
+ }
+ else if (**pp == 'V')
+ {
+ volatilep = true;
+ ++*pp;
+ }
+ if (**pp != 'F')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+ if (! stab_demangle_args (minfo, pp,
+ (ptype == NULL
+ ? (debug_type **) NULL
+ : &args),
+ (ptype == NULL
+ ? (boolean *) NULL
+ : &varargs)))
+ return false;
+ }
+
+ if (**pp != '_')
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ ++*pp;
+
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+
+ if (ptype != NULL)
+ {
+ debug_type class_type;
+
+ class_type = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ name, (int) n,
+ DEBUG_KIND_CLASS);
+ if (class_type == DEBUG_TYPE_NULL)
+ return false;
+
+ if (! memberp)
+ *ptype = debug_make_offset_type (minfo->dhandle, class_type,
+ *ptype);
+ else
+ {
+ /* FIXME: We have no way to record constp or
+ volatilep. */
+ *ptype = debug_make_method_type (minfo->dhandle, *ptype,
+ class_type, args, varargs);
+ }
+ }
+ }
+ break;
+
+ case 'G':
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ break;
+
+ case 'C':
+ ++*pp;
+ if (! stab_demangle_type (minfo, pp, ptype))
+ return false;
+ if (ptype != NULL)
+ *ptype = debug_make_const_type (minfo->dhandle, *ptype);
+ break;
+
+ case 'Q':
+ {
+ const char *hold;
+
+ hold = *pp;
+ if (! stab_demangle_qualified (minfo, pp, ptype))
+ return false;
+ }
+ break;
+
+ default:
+ if (! stab_demangle_fund_type (minfo, pp, ptype))
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+/* Demangle a fundamental type. If the ptype argument is not NULL,
+ *ptype is set to the newly allocated type. */
+
+static boolean
+stab_demangle_fund_type (minfo, pp, ptype)
+ struct stab_demangle_info *minfo;
+ const char **pp;
+ debug_type *ptype;
+{
+ const char *orig;
+ boolean constp, volatilep, unsignedp, signedp;
+ boolean done;
+
+ orig = *pp;
+
+ constp = false;
+ volatilep = false;
+ unsignedp = false;
+ signedp = false;
+
+ done = false;
+ while (! done)
+ {
+ switch (**pp)
+ {
+ case 'C':
+ constp = true;
+ ++*pp;
+ break;
+
+ case 'U':
+ unsignedp = true;
+ ++*pp;
+ break;
+
+ case 'S':
+ signedp = true;
+ ++*pp;
+ break;
+
+ case 'V':
+ volatilep = true;
+ ++*pp;
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+ }
+
+ switch (**pp)
+ {
+ case '\0':
+ case '_':
+ /* cplus_demangle permits this, but I don't know what it means. */
+ stab_bad_demangle (orig);
+ break;
+
+ case 'v': /* void */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "void");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_void_type (minfo->dhandle);
+ }
+ ++*pp;
+ break;
+
+ case 'x': /* long long */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "long long unsigned int"
+ : "long long int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'l': /* long */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "long unsigned int"
+ : "long int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'i': /* int */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "unsigned int"
+ : "int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 's': /* short */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "short unsigned int"
+ : "short int"));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'b': /* bool */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "bool");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_bool_type (minfo->dhandle, 4);
+ }
+ ++*pp;
+ break;
+
+ case 'c': /* char */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle,
+ (unsignedp
+ ? "unsigned char"
+ : (signedp
+ ? "signed char"
+ : "char")));
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp);
+ }
+ ++*pp;
+ break;
+
+ case 'w': /* wchar_t */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_int_type (minfo->dhandle, 2, true);
+ }
+ ++*pp;
+ break;
+
+ case 'r': /* long double */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "long double");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 8);
+ }
+ ++*pp;
+ break;
+
+ case 'd': /* double */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "double");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 8);
+ }
+ ++*pp;
+ break;
+
+ case 'f': /* float */
+ if (ptype != NULL)
+ {
+ *ptype = debug_find_named_type (minfo->dhandle, "float");
+ if (*ptype == DEBUG_TYPE_NULL)
+ *ptype = debug_make_float_type (minfo->dhandle, 4);
+ }
+ ++*pp;
+ break;
+
+ case 'G':
+ ++*pp;
+ if (! isdigit ((unsigned char) **pp))
+ {
+ stab_bad_demangle (orig);
+ return false;
+ }
+ /* Fall through. */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ const char *hold;
+
+ if (! stab_demangle_class (minfo, pp, &hold))
+ return false;
+ if (ptype != NULL)
+ {
+ char *name;
+
+ name = savestring (hold, *pp - hold);
+ *ptype = debug_find_named_type (minfo->dhandle, name);
+ free (name);
+ if (*ptype == DEBUG_TYPE_NULL)
+ {
+ /* FIXME: It is probably incorrect to assume that
+ undefined types are tagged types. */
+ *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ hold, *pp - hold,
+ DEBUG_KIND_ILLEGAL);
+ if (*ptype == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+ }
+ break;
+
+ case 't':
+ {
+ char *name;
+
+ if (! stab_demangle_template (minfo, pp,
+ ptype != NULL ? &name : NULL))
+ return false;
+ if (ptype != NULL)
+ {
+ *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
+ name, strlen (name),
+ DEBUG_KIND_CLASS);
+ free (name);
+ if (*ptype == DEBUG_TYPE_NULL)
+ return false;
+ }
+ }
+ break;
+
+ default:
+ stab_bad_demangle (orig);
+ return false;
+ }
+
+ if (ptype != NULL)
+ {
+ if (constp)
+ *ptype = debug_make_const_type (minfo->dhandle, *ptype);
+ if (volatilep)
+ *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
+ }
+
+ return true;
+}
+
+/* Remember a type string in a demangled string. */
+
+static boolean
+stab_demangle_remember_type (minfo, p, len)
+ struct stab_demangle_info *minfo;
+ const char *p;
+ int len;
+{
+ if (minfo->typestring_count >= minfo->typestring_alloc)
+ {
+ minfo->typestring_alloc += 10;
+ minfo->typestrings = ((struct stab_demangle_typestring *)
+ xrealloc (minfo->typestrings,
+ (minfo->typestring_alloc
+ * sizeof *minfo->typestrings)));
+ }
+
+ minfo->typestrings[minfo->typestring_count].typestring = p;
+ minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
+ ++minfo->typestring_count;
+
+ return true;
+}
diff --git a/binutils/stamp-h.in b/binutils/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/binutils/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/binutils/strings.1 b/binutils/strings.1
new file mode 100644
index 00000000000..408de29400b
--- /dev/null
+++ b/binutils/strings.1
@@ -0,0 +1,151 @@
+.\" Copyright (c) 1993 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH strings 1 "25 June 1993" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+strings \- print the strings of printable characters in files
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B strings
+.RB "[\|" \-a | \-\c
+.RB | \-\-all "\|]"
+.RB "[\|" \-f | \-\-print\-file\-name "\|]"
+.RB "[\|" \-o "\|]"
+.RB "[\|" \-\-help "\|]"
+.RB "[\|" \-v | \-\-version "\|]"
+.RB "[\|" \-n
+.I min\-len\c
+.RI | \-min\-len\c
+.RB | "\-\-bytes="\c
+.I min\-len\c
+\&\|]
+.RB "[\|" \-t
+.I {o,x,d}\c
+.RB "[\|" "\-\-target=\fIbfdname" "\|]"
+.RB | "\-\-radix="\c
+.I {o,x,d}\c
+\&\|]
+.I file\c
+.ad b
+.hy 1
+.SH DESCRIPTION
+For each
+.I file
+given, GNU \c
+.B strings
+prints the printable character sequences that are at least 4
+characters long (or the number given with the options below) and are
+followed by an unprintable character. By default, it only prints the
+strings from the initialized and loaded sections of object files; for
+other types of files, it prints the strings from the whole file.
+
+.PP
+.B strings
+is mainly useful for determining the contents of non-text files.
+
+.SH OPTIONS
+The long and short forms of options, shown here as alternatives, are
+equivalent.
+
+.TP
+.B \-a
+.TP
+.B \-\-all
+.TP
+.B \-
+Do not scan only the initialized and loaded sections of object files;
+scan the whole files.
+
+.TP
+.B \-f
+.TP
+.B \-\-print\-file\-name
+Print the name of the file before each string.
+
+.TP
+.B \-\-help
+Print a summary of the options to
+.B strings
+on the standard output and exit.
+
+.TP
+.B \-v
+.TP
+.B \-\-version
+Print the version number
+of
+.B strings
+on the standard output and exit.
+
+.TP
+.B "\-n \fImin\-len\fP"
+.TP
+.B "\-\fImin\-len\fP"
+.TP
+.B "\-bytes=\fImin\-len\fP"
+Print sequences of characters that are at least
+.I min\-len
+characters long, instead of the default 4.
+
+.TP
+.BR "\-t " {o,x,d}
+.TP
+.BR "\-\-radix=" {o,x,d}
+Print the offset within the file before each string. The single
+character argument specifies the radix of the offset\(emoctal,
+hexadecimal, or decimal.
+
+.TP
+.BI "\-\-target=" "bfdname"
+Specify an object code format other than your system's default format.
+See
+.BR objdump ( 1 ),
+for information on listing available formats.
+
+.TP
+.B \-o
+Like
+.BR "\-t o" .
+
+.PP
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+The GNU Binary Utilities\c
+\&, Roland H. Pesch (October 1991);
+.BR ar ( 1 ),
+.BR nm ( 1 ),
+.BR objdump ( 1 ),
+.BR ranlib ( 1 ).
+
+
+.SH COPYING
+Copyright (c) 1993 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/strings.c b/binutils/strings.c
new file mode 100644
index 00000000000..8ffe6a16625
--- /dev/null
+++ b/binutils/strings.c
@@ -0,0 +1,514 @@
+/* strings -- print the strings of printable characters in files
+ Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Usage: strings [options] file...
+
+ Options:
+ --all
+ -a
+ - Do not scan only the initialized data section of object files.
+
+ --print-file-name
+ -f Print the name of the file before each string.
+
+ --bytes=min-len
+ -n min-len
+ -min-len Print graphic char sequences, MIN-LEN or more bytes long,
+ that are followed by a NUL or a newline. Default is 4.
+
+ --radix={o,x,d}
+ -t {o,x,d} Print the offset within the file before each string,
+ in octal/hex/decimal.
+
+ -o Like -to. (Some other implementations have -o like -to,
+ others like -td. We chose one arbitrarily.)
+
+ --target=BFDNAME
+ Specify a non-default object file format.
+
+ --help
+ -h Print the usage message on the standard output.
+
+ --version
+ -v Print the program version number.
+
+ Written by Richard Stallman <rms@gnu.ai.mit.edu>
+ and David MacKenzie <djm@gnu.ai.mit.edu>. */
+
+#include "bfd.h"
+#include <stdio.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <errno.h>
+#include "bucomm.h"
+#include "libiberty.h"
+
+#ifdef isascii
+#define isgraphic(c) (isascii (c) && isprint (c))
+#else
+#define isgraphic(c) (isprint (c))
+#endif
+
+#ifndef errno
+extern int errno;
+#endif
+
+/* The BFD section flags that identify an initialized data section. */
+#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
+
+/* Radix for printing addresses (must be 8, 10 or 16). */
+static int address_radix;
+
+/* Minimum length of sequence of graphic chars to trigger output. */
+static int string_min;
+
+/* true means print address within file for each string. */
+static boolean print_addresses;
+
+/* true means print filename for each string. */
+static boolean print_filenames;
+
+/* true means for object files scan only the data section. */
+static boolean datasection_only;
+
+/* true if we found an initialized data section in the current file. */
+static boolean got_a_section;
+
+/* The BFD object file format. */
+static char *target;
+
+static struct option long_options[] =
+{
+ {"all", no_argument, NULL, 'a'},
+ {"print-file-name", no_argument, NULL, 'f'},
+ {"bytes", required_argument, NULL, 'n'},
+ {"radix", required_argument, NULL, 't'},
+ {"target", required_argument, NULL, 'T'},
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
+ {NULL, 0, NULL, 0}
+};
+
+static void strings_a_section PARAMS ((bfd *, asection *, PTR));
+static boolean strings_object_file PARAMS ((const char *));
+static boolean strings_file PARAMS ((char *file));
+static int integer_arg PARAMS ((char *s));
+static void print_strings PARAMS ((const char *filename, FILE *stream,
+ file_ptr address, int stop_point,
+ int magiccount, char *magic));
+static void usage PARAMS ((FILE *stream, int status));
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int optc;
+ int exit_status = 0;
+ boolean files_given = false;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+ string_min = -1;
+ print_addresses = false;
+ print_filenames = false;
+ datasection_only = true;
+ target = NULL;
+
+ while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789",
+ long_options, (int *) 0)) != EOF)
+ {
+ switch (optc)
+ {
+ case 'a':
+ datasection_only = false;
+ break;
+
+ case 'f':
+ print_filenames = true;
+ break;
+
+ case 'h':
+ usage (stdout, 0);
+
+ case 'n':
+ string_min = integer_arg (optarg);
+ if (string_min < 1)
+ {
+ fprintf (stderr, _("%s: invalid number %s\n"),
+ program_name, optarg);
+ exit (1);
+ }
+ break;
+
+ case 'o':
+ print_addresses = true;
+ address_radix = 8;
+ break;
+
+ case 't':
+ print_addresses = true;
+ if (optarg[1] != '\0')
+ usage (stderr, 1);
+ switch (optarg[0])
+ {
+ case 'o':
+ address_radix = 8;
+ break;
+
+ case 'd':
+ address_radix = 10;
+ break;
+
+ case 'x':
+ address_radix = 16;
+ break;
+
+ default:
+ usage (stderr, 1);
+ }
+ break;
+
+ case 'T':
+ target = optarg;
+ break;
+
+ case 'v':
+ print_version ("strings");
+ break;
+
+ case '?':
+ usage (stderr, 1);
+
+ default:
+ if (string_min < 0)
+ string_min = optc;
+ else
+ string_min = string_min * 10 + optc - '0';
+ break;
+ }
+ }
+
+ if (string_min < 0)
+ string_min = 4;
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ if (optind >= argc)
+ {
+ datasection_only = false;
+ print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
+ files_given = true;
+ }
+ else
+ {
+ for (; optind < argc; ++optind)
+ {
+ if (strcmp (argv[optind], "-") == 0)
+ datasection_only = false;
+ else
+ {
+ files_given = true;
+ exit_status |= (strings_file (argv[optind]) == false);
+ }
+ }
+ }
+
+ if (files_given == false)
+ usage (stderr, 1);
+
+ return (exit_status);
+}
+
+/* Scan section SECT of the file ABFD, whose printable name is FILE.
+ If it contains initialized data,
+ set `got_a_section' and print the strings in it. */
+
+static void
+strings_a_section (abfd, sect, filearg)
+ bfd *abfd;
+ asection *sect;
+ PTR filearg;
+{
+ const char *file = (const char *) filearg;
+
+ if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
+ {
+ bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
+ PTR mem = xmalloc (sz);
+ if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
+ {
+ got_a_section = true;
+ print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
+ }
+ free (mem);
+ }
+}
+
+/* Scan all of the sections in FILE, and print the strings
+ in the initialized data section(s).
+
+ Return true if successful,
+ false if not (such as if FILE is not an object file). */
+
+static boolean
+strings_object_file (file)
+ const char *file;
+{
+ bfd *abfd = bfd_openr (file, target);
+
+ if (abfd == NULL)
+ {
+ /* Treat the file as a non-object file. */
+ return false;
+ }
+
+ /* This call is mainly for its side effect of reading in the sections.
+ We follow the traditional behavior of `strings' in that we don't
+ complain if we don't recognize a file to be an object file. */
+ if (bfd_check_format (abfd, bfd_object) == false)
+ {
+ bfd_close (abfd);
+ return false;
+ }
+
+ got_a_section = false;
+ bfd_map_over_sections (abfd, strings_a_section, (PTR) file);
+
+ if (!bfd_close (abfd))
+ {
+ bfd_nonfatal (file);
+ return false;
+ }
+
+ return got_a_section;
+}
+
+/* Print the strings in FILE. Return true if ok, false if an error occurs. */
+
+static boolean
+strings_file (file)
+ char *file;
+{
+ /* If we weren't told to scan the whole file,
+ try to open it as an object file and only look at
+ initialized data sections. If that fails, fall back to the
+ whole file. */
+ if (!datasection_only || !strings_object_file (file))
+ {
+ FILE *stream;
+
+ stream = fopen (file, "rb");
+ /* Not all systems permit "rb", so try "r" if it failed. */
+ if (stream == NULL)
+ stream = fopen (file, "r");
+ if (stream == NULL)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ perror (file);
+ return false;
+ }
+
+ print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
+
+ if (fclose (stream) == EOF)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ perror (file);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* Find the strings in file FILENAME, read from STREAM.
+ Assume that STREAM is positioned so that the next byte read
+ is at address ADDRESS in the file.
+ Stop reading at address STOP_POINT in the file, if nonzero.
+
+ If STREAM is NULL, do not read from it.
+ The caller can supply a buffer of characters
+ to be processed before the data in STREAM.
+ MAGIC is the address of the buffer and
+ MAGICCOUNT is how many characters are in it.
+ Those characters come at address ADDRESS and the data in STREAM follow. */
+
+static void
+print_strings (filename, stream, address, stop_point, magiccount, magic)
+ const char *filename;
+ FILE *stream;
+ file_ptr address;
+ int stop_point;
+ int magiccount;
+ char *magic;
+{
+ char *buf = (char *) xmalloc (string_min + 1);
+
+ while (1)
+ {
+ file_ptr start;
+ int i;
+ int c;
+
+ /* See if the next `string_min' chars are all graphic chars. */
+ tryline:
+ if (stop_point && address >= stop_point)
+ break;
+ start = address;
+ for (i = 0; i < string_min; i++)
+ {
+ if (magiccount)
+ {
+ magiccount--;
+ c = *magic++;
+ }
+ else
+ {
+ if (stream == NULL)
+ return;
+ c = getc (stream);
+ if (c == EOF)
+ return;
+ }
+ address++;
+ if (!isgraphic (c))
+ /* Found a non-graphic. Try again starting with next char. */
+ goto tryline;
+ buf[i] = c;
+ }
+
+ /* We found a run of `string_min' graphic characters. Print up
+ to the next non-graphic character. */
+
+ if (print_filenames)
+ printf ("%s: ", filename);
+ if (print_addresses)
+ switch (address_radix)
+ {
+ case 8:
+ printf ("%7lo ", (unsigned long) start);
+ break;
+
+ case 10:
+ printf ("%7ld ", (long) start);
+ break;
+
+ case 16:
+ printf ("%7lx ", (unsigned long) start);
+ break;
+ }
+
+ buf[i] = '\0';
+ fputs (buf, stdout);
+
+ while (1)
+ {
+ if (magiccount)
+ {
+ magiccount--;
+ c = *magic++;
+ }
+ else
+ {
+ if (stream == NULL)
+ break;
+ c = getc (stream);
+ if (c == EOF)
+ break;
+ }
+ address++;
+ if (! isgraphic (c))
+ break;
+ putchar (c);
+ }
+
+ putchar ('\n');
+ }
+}
+
+/* Parse string S as an integer, using decimal radix by default,
+ but allowing octal and hex numbers as in C. */
+
+static int
+integer_arg (s)
+ char *s;
+{
+ int value;
+ int radix = 10;
+ char *p = s;
+ int c;
+
+ if (*p != '0')
+ radix = 10;
+ else if (*++p == 'x')
+ {
+ radix = 16;
+ p++;
+ }
+ else
+ radix = 8;
+
+ value = 0;
+ while (((c = *p++) >= '0' && c <= '9')
+ || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
+ {
+ value *= radix;
+ if (c >= '0' && c <= '9')
+ value += c - '0';
+ else
+ value += (c & ~40) - 'A';
+ }
+
+ if (c == 'b')
+ value *= 512;
+ else if (c == 'B')
+ value *= 1024;
+ else
+ p--;
+
+ if (*p)
+ {
+ fprintf (stderr, _("%s: invalid integer argument %s\n"), program_name, s);
+ exit (1);
+ }
+ return value;
+}
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, _("\
+Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
+ [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
+ [--target=bfdname] [--help] [--version] file...\n"),
+ program_name);
+ list_supported_targets (program_name, stream);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
diff --git a/binutils/strip.1 b/binutils/strip.1
new file mode 100644
index 00000000000..708817ded13
--- /dev/null
+++ b/binutils/strip.1
@@ -0,0 +1,185 @@
+.\" Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH strip 1 "5 November 1991" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+strip \- Discard symbols from object files.
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B strip
+.RB "[\|" \-F\ \fIbfdname\fR\ |\ \fB\-\-target=\fIbfdname\fP "\|]"
+.RB "[\|" \-I\ \fIbfdname\fR\ |\ \fB\-\-input\-target=\fIbfdname\fP "\|]"
+.RB "[\|" \-O\ \fIbfdname\fR\ |\ \fB\-\-output\-target=\fIbfdname\fP "\|]"
+.RB "[\|" \-R\ \fIsectionname\fR\ |\ \fB\-\-remove\-section=\fIsectionname\fP "\|]"
+.RB "[\|" \-s\fR\ |\ \fB\-\-strip\-all "\|]"
+.RB "[\|" \-S\fR\ |\ \fB\-g\fR\ |\ \fB\-\-strip\-debug "\|]"
+.RB "[\|" \-\-strip\-unneeded\fR "\|]"
+.RB "[\|" \-x\fR\ |\ \fB\-\-discard\-all "\|]"
+.RB "[\|" \-X\fR\ |\ \fB\-\-discard\-locals "\|]"
+.RB "[\|" \-K\ \fIsymbolname\fR\ |\ \fB\-\-keep\-symbol=\fIsymbolname\fR "\|]"
+.RB "[\|" \-N\ \fIsymbolname\fR\ |\ \fB\-\-strip\-symbol=\fIsymbolname\fR "\|]"
+.RB "[\|" \-o\ \fIfile\f\R "\|]"
+.RB "[\|" \-p\fR\ |\ \fB\-\-preserve\-dates "\|]"
+.RB "[\|" \-v\fR\ |\ \fB\-\-verbose "\|]"
+.RB "[\|" \-V\fR\ |\ \fB\-\-version "\|]"
+.RB "[\|" \-V\fR\ |\ \fB\-\-help "\|]"
+.I objfile\c
+\&.\|.\|.
+
+.SH DESCRIPTION
+GNU
+.B strip
+discards all symbols from the object files
+.IR objfile .
+The list of object files may include archives.
+At least one object file must be given.
+
+.P
+.B strip
+modifies the files named in its argument,
+rather than writing modified copies under different names.
+
+.SH OPTIONS
+.TP
+.B "\-F \fIbfdname"
+.TP
+.B "\-\-target=\fIbfdname"
+Treat the original \fIobjfile\fP as a file with the object
+code format \fIbfdname\fP, and rewrite it in the same format.
+
+.TP
+.B \-\-help
+Show a summary of the options to
+.B strip
+and exit.
+
+.TP
+.B "\-I \fIbfdname
+.TP
+.B "\-\-input\-target=\fIbfdname"
+Treat the original \fIobjfile\fP as a file with the object
+code format \fIbfdname\fP.
+
+.TP
+.B "\-O \fIbfdname\fP"
+.TP
+.B "\-\-output\-target=\fIbfdname"
+Replace \fIobjfile\fP with a file in the output format \fIbfdname\fP.
+
+.TP
+.B "\-R \fIsectionname\fP"
+.TP
+.B "\-\-remove\-section=\fIsectionname"
+Remove the named section from the file. This option may be given more
+than once. Note that using this option inappropriately may make the
+object file unusable.
+
+.TP
+.B \-s
+.TP
+.B \-\-strip\-all
+Remove all symbols.
+
+.TP
+.B \-S
+.TP
+.B \-g
+.TP
+.B \-\-strip\-debug
+Remove debugging symbols only.
+
+.TP
+.B \-\-strip\-unneeded
+Strip all symbols that are not needed for relocation processing.
+
+.TP
+.B \-N \fIsymbolname\fR
+.TP
+.B \-\-strip\-symbol=\fIsymbolname
+Remove symbol \fIsymbolname\fP from the source file. This option
+may be given more than once, and may be combined with other strip
+options.
+
+.TP
+.B \-o \fIfile\fR
+Put the stripped output in \fIfile\fR, rather than replacing the
+existing file. When this argument is used, only one \fIobjfile\fR
+argument may be specified.
+
+.TP
+.B \-p
+.TP
+.B \-\-preserve-dates
+Preserve the access and modification dates of the file.
+
+.TP
+.B \-x
+.TP
+.B \-\-discard\-all
+Remove non-global symbols.
+
+.TP
+.B \-X
+.TP
+.B \-\-discard\-locals
+Remove compiler-generated local symbols.
+(These usually start with ``L'' or ``.''.)
+
+.TP
+.B \-K \fIsymbolname\fR, \fB\-\-keep\-symbol=\fIsymbolname
+Copy only symbol \fIsymbolname\fP from the source file. This option
+may be given more than once.
+
+.TP
+.B \-N \fIsymbolname\fR, \fB\-\-strip\-symbol=\fIsymbolname
+Do not copy symbol \fIsymbolname\fP from the source file. This option
+may be given more than once, and may be combined with strip options
+other than \fB\-K\fR.
+
+.TP
+.B \-v
+.TP
+.B \-\-verbose
+Verbose output: list all object files modified. In the case of
+archives,
+.B "strip \-v"
+lists all members of the archive.
+
+.TP
+.B \-V
+.TP
+.B \-\-version
+Show the version number for \fBstrip\fP and exit.
+
+.SH "SEE ALSO"
+.RB "`\|" binutils "\|'"
+entry in
+.BR info ;
+.IR "The GNU Binary Utilities" ,
+Roland H. Pesch (October 1991).
+
+.SH COPYING
+Copyright (c) 1991 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/binutils/sysdump.c b/binutils/sysdump.c
new file mode 100644
index 00000000000..c821e8cf457
--- /dev/null
+++ b/binutils/sysdump.c
@@ -0,0 +1,790 @@
+/* Sysroff object format dumper.
+ Copyright (C) 1994, 95, 98, 1999 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/* Written by Steve Chamberlain <sac@cygnus.com>.
+
+ This program reads a SYSROFF object file and prints it in an
+ almost human readable form to stdout. */
+
+#include "bfd.h"
+#include "bucomm.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <libiberty.h>
+#include <getopt.h>
+#include "sysroff.h"
+
+#define PROGRAM_VERSION "1.0"
+
+static int dump = 1;
+static int segmented_p;
+static int code;
+static int addrsize = 4;
+static FILE *file;
+
+char *
+getCHARS (ptr, idx, size, max)
+ unsigned char *ptr;
+ int *idx;
+ int size;
+ int max;
+{
+ int oc = *idx / 8;
+ char *r;
+ int b = size;
+ if (b >= max)
+ {
+ return "*undefined*";
+ }
+
+ if (b == 0)
+ {
+ /* Got to work out the length of the string from self */
+ b = ptr[oc++];
+ (*idx) += 8;
+ }
+
+ *idx += b * 8;
+ r = xcalloc (b + 1, 1);
+ memcpy (r, ptr + oc, b);
+ r[b] = 0;
+ return r;
+}
+
+static void
+dh (ptr, size)
+ unsigned char *ptr;
+ int size;
+{
+ int i;
+ int j;
+ int span = 16;
+
+ printf ("\n************************************************************\n");
+
+ for (i = 0; i < size; i += span)
+ {
+ for (j = 0; j < span; j++)
+ {
+ if (j + i < size)
+ printf ("%02x ", ptr[i + j]);
+ else
+ printf (" ");
+ }
+
+ for (j = 0; j < span && j + i < size; j++)
+ {
+ int c = ptr[i + j];
+ if (c < 32 || c > 127)
+ c = '.';
+ printf ("%c", c);
+ }
+ printf ("\n");
+ }
+}
+
+int
+fillup (ptr)
+ char *ptr;
+{
+ int size;
+ int sum;
+ int i;
+ size = getc (file) - 2;
+ fread (ptr, 1, size, file);
+ sum = code + size + 2;
+ for (i = 0; i < size; i++)
+ {
+ sum += ptr[i];
+ }
+
+ if ((sum & 0xff) != 0xff)
+ {
+ printf ("SUM IS %x\n", sum);
+ }
+ if (dump)
+ dh (ptr, size);
+
+ return size - 1;
+}
+
+barray
+getBARRAY (ptr, idx, dsize, max)
+ unsigned char *ptr;
+ int *idx;
+ int dsize;
+ int max;
+{
+ barray res;
+ int i;
+ int byte = *idx / 8;
+ int size = ptr[byte++];
+ res.len = size;
+ res.data = (unsigned char *) xmalloc (size);
+ for (i = 0; i < size; i++)
+ {
+ res.data[i] = ptr[byte++];
+ }
+ return res;
+}
+
+int
+getINT (ptr, idx, size, max)
+ unsigned char *ptr;
+ int *idx;
+ int size;
+ int max;
+{
+ int n = 0;
+ int byte = *idx / 8;
+
+ if (byte >= max)
+ {
+ return 0;
+ }
+ if (size == -2)
+ size = addrsize;
+ if (size == -1)
+ size = 0;
+ switch (size)
+ {
+ case 0:
+ return 0;
+ case 1:
+ n = (ptr[byte]);
+ break;
+ case 2:
+ n = (ptr[byte + 0] << 8) + ptr[byte + 1];
+ break;
+ case 4:
+ n = (ptr[byte + 0] << 24) + (ptr[byte + 1] << 16) + (ptr[byte + 2] << 8) + (ptr[byte + 3]);
+ break;
+ default:
+ abort ();
+ }
+ *idx += size * 8;
+ return n;
+}
+
+int
+getBITS (ptr, idx, size, max)
+ char *ptr;
+ int *idx;
+ int size, max;
+{
+ int byte = *idx / 8;
+ int bit = *idx % 8;
+
+ if (byte >= max)
+ return 0;
+
+ *idx += size;
+
+ return (ptr[byte] >> (8 - bit - size)) & ((1 << size) - 1);
+}
+
+static void
+itheader (name, code)
+ char *name;
+ int code;
+{
+ printf ("\n%s 0x%02x\n", name, code);
+}
+
+static int indent;
+static void
+p ()
+{
+ int i;
+ for (i = 0; i < indent; i++)
+ {
+ printf ("| ");
+ }
+ printf ("> ");
+}
+
+static void
+tabout ()
+{
+ p ();
+}
+
+static void
+pbarray (y)
+ barray *y;
+{
+ int x;
+ printf ("%d (", y->len);
+ for (x = 0; x < y->len; x++)
+ {
+ printf ("(%02x %c)", y->data[x], isprint (y->data[x]) ? y->data[x] : '.');
+ }
+ printf (")\n");
+}
+
+#define SYSROFF_PRINT
+#define SYSROFF_SWAP_IN
+
+#include "sysroff.c"
+
+/*
+ * FIXME: sysinfo, which generates sysroff.[ch] from sysroff.info, can't
+ * hack the special case of the tr block, which has no contents. So we
+ * implement our own functions for reading in and printing out the tr
+ * block.
+ */
+
+#define IT_tr_CODE 0x7f
+void
+sysroff_swap_tr_in()
+{
+ char raw[255];
+
+ memset(raw, 0, 255);
+ fillup(raw);
+}
+
+void
+sysroff_print_tr_out()
+{
+ itheader("tr", IT_tr_CODE);
+}
+
+static int
+getone (type)
+ int type;
+{
+ int c = getc (file);
+ code = c;
+
+ if ((c & 0x7f) != type)
+ {
+ ungetc (c, file);
+ return 0;
+ }
+
+ switch (c & 0x7f)
+ {
+ case IT_cs_CODE:
+ {
+ struct IT_cs dummy;
+ sysroff_swap_cs_in (&dummy);
+ sysroff_print_cs_out (&dummy);
+ }
+ break;
+ case IT_dln_CODE:
+ {
+ struct IT_dln dummy;
+ sysroff_swap_dln_in (&dummy);
+ sysroff_print_dln_out (&dummy);
+ }
+ break;
+ case IT_hd_CODE:
+ {
+ struct IT_hd dummy;
+ sysroff_swap_hd_in (&dummy);
+ addrsize = dummy.afl;
+ sysroff_print_hd_out (&dummy);
+ }
+ break;
+ case IT_dar_CODE:
+ {
+ struct IT_dar dummy;
+ sysroff_swap_dar_in (&dummy);
+ sysroff_print_dar_out (&dummy);
+ }
+ break;
+ case IT_dsy_CODE:
+ {
+ struct IT_dsy dummy;
+ sysroff_swap_dsy_in (&dummy);
+ sysroff_print_dsy_out (&dummy);
+ }
+ break;
+ case IT_dfp_CODE:
+ {
+ struct IT_dfp dummy;
+ sysroff_swap_dfp_in (&dummy);
+ sysroff_print_dfp_out (&dummy);
+ }
+ break;
+ case IT_dso_CODE:
+ {
+ struct IT_dso dummy;
+ sysroff_swap_dso_in (&dummy);
+ sysroff_print_dso_out (&dummy);
+ }
+ break;
+ case IT_dpt_CODE:
+ {
+ struct IT_dpt dummy;
+ sysroff_swap_dpt_in (&dummy);
+ sysroff_print_dpt_out (&dummy);
+ }
+ break;
+ case IT_den_CODE:
+ {
+ struct IT_den dummy;
+ sysroff_swap_den_in (&dummy);
+ sysroff_print_den_out (&dummy);
+ }
+ break;
+ case IT_dbt_CODE:
+ {
+ struct IT_dbt dummy;
+ sysroff_swap_dbt_in (&dummy);
+ sysroff_print_dbt_out (&dummy);
+ }
+ break;
+ case IT_dty_CODE:
+ {
+ struct IT_dty dummy;
+ sysroff_swap_dty_in (&dummy);
+ sysroff_print_dty_out (&dummy);
+ }
+ break;
+ case IT_un_CODE:
+ {
+ struct IT_un dummy;
+ sysroff_swap_un_in (&dummy);
+ sysroff_print_un_out (&dummy);
+ }
+ break;
+ case IT_sc_CODE:
+ {
+ struct IT_sc dummy;
+ sysroff_swap_sc_in (&dummy);
+ sysroff_print_sc_out (&dummy);
+ }
+ break;
+ case IT_er_CODE:
+ {
+ struct IT_er dummy;
+ sysroff_swap_er_in (&dummy);
+ sysroff_print_er_out (&dummy);
+ }
+ break;
+ case IT_ed_CODE:
+ {
+ struct IT_ed dummy;
+ sysroff_swap_ed_in (&dummy);
+ sysroff_print_ed_out (&dummy);
+ }
+ break;
+ case IT_sh_CODE:
+ {
+ struct IT_sh dummy;
+ sysroff_swap_sh_in (&dummy);
+ sysroff_print_sh_out (&dummy);
+ }
+ break;
+ case IT_ob_CODE:
+ {
+ struct IT_ob dummy;
+ sysroff_swap_ob_in (&dummy);
+ sysroff_print_ob_out (&dummy);
+ }
+ break;
+ case IT_rl_CODE:
+ {
+ struct IT_rl dummy;
+ sysroff_swap_rl_in (&dummy);
+ sysroff_print_rl_out (&dummy);
+ }
+ break;
+ case IT_du_CODE:
+ {
+ struct IT_du dummy;
+ sysroff_swap_du_in (&dummy);
+
+ sysroff_print_du_out (&dummy);
+ }
+ break;
+ case IT_dus_CODE:
+ {
+ struct IT_dus dummy;
+ sysroff_swap_dus_in (&dummy);
+ sysroff_print_dus_out (&dummy);
+ }
+ break;
+ case IT_dul_CODE:
+ {
+ struct IT_dul dummy;
+ sysroff_swap_dul_in (&dummy);
+ sysroff_print_dul_out (&dummy);
+ }
+ break;
+ case IT_dss_CODE:
+ {
+ struct IT_dss dummy;
+ sysroff_swap_dss_in (&dummy);
+ sysroff_print_dss_out (&dummy);
+ }
+ break;
+ case IT_hs_CODE:
+ {
+ struct IT_hs dummy;
+ sysroff_swap_hs_in (&dummy);
+ sysroff_print_hs_out (&dummy);
+ }
+ break;
+ case IT_dps_CODE:
+ {
+ struct IT_dps dummy;
+ sysroff_swap_dps_in (&dummy);
+ sysroff_print_dps_out (&dummy);
+ }
+ break;
+ case IT_tr_CODE:
+ {
+ sysroff_swap_tr_in ();
+ sysroff_print_tr_out ();
+ }
+ break;
+ case IT_dds_CODE:
+ {
+ struct IT_dds dummy;
+ sysroff_swap_dds_in (&dummy);
+ sysroff_print_dds_out (&dummy);
+ }
+ break;
+ default:
+ printf ("GOT A %x\n", c);
+ return 0;
+ break;
+ }
+ return 1;
+}
+
+static int
+opt (x)
+ int x;
+{
+ return getone (x);
+}
+
+#if 0
+
+/* This is no longer used. */
+
+static void
+unit_info_list ()
+{
+ while (opt (IT_un_CODE))
+ {
+ getone (IT_us_CODE);
+
+ while (getone (IT_sc_CODE))
+ getone (IT_ss_CODE);
+
+ while (getone (IT_er_CODE))
+ ;
+
+ while (getone (IT_ed_CODE))
+ ;
+ }
+}
+
+#endif
+
+#if 0
+
+/* This is no longer used. */
+
+static void
+object_body_list ()
+{
+ while (getone (IT_sh_CODE))
+ {
+ while (getone (IT_ob_CODE))
+ ;
+ while (getone (IT_rl_CODE))
+ ;
+ }
+}
+
+#endif
+
+static void
+must (x)
+ int x;
+{
+ if (!getone (x))
+ {
+ printf ("WANTED %x!!\n", x);
+ }
+}
+
+static void
+tab (i, s)
+ int i;
+ char *s;
+{
+ indent += i;
+ if (s)
+ {
+ p ();
+ printf (s);
+ printf ("\n");
+ }
+}
+
+static void derived_type ();
+
+static void
+dump_symbol_info ()
+{
+ tab (1, "SYMBOL INFO");
+ while (opt (IT_dsy_CODE))
+ {
+ if (opt (IT_dty_CODE))
+ {
+ must (IT_dbt_CODE);
+ derived_type ();
+ must (IT_dty_CODE);
+ }
+ }
+ tab (-1, "");
+}
+
+static void
+derived_type ()
+{
+ tab (1, "DERIVED TYPE");
+ while (1)
+ {
+ if (opt (IT_dpp_CODE))
+ {
+ dump_symbol_info ();
+ must (IT_dpp_CODE);
+ }
+ else if (opt (IT_dfp_CODE))
+ {
+ dump_symbol_info ();
+ must (IT_dfp_CODE);
+ }
+ else if (opt (IT_den_CODE))
+ {
+ dump_symbol_info ();
+ must (IT_den_CODE);
+ }
+ else if (opt (IT_den_CODE))
+ {
+ dump_symbol_info ();
+ must (IT_den_CODE);
+ }
+ else if (opt (IT_dds_CODE))
+ {
+ dump_symbol_info ();
+ must (IT_dds_CODE);
+ }
+ else if (opt (IT_dar_CODE))
+ {
+ }
+ else if (opt (IT_dpt_CODE))
+ {
+ }
+ else if (opt (IT_dul_CODE))
+ {
+ }
+ else if (opt (IT_dse_CODE))
+ {
+ }
+ else if (opt (IT_dot_CODE))
+ {
+ }
+ else
+ break;
+ }
+
+ tab (-1, "");
+}
+
+#if 0
+
+/* This is no longer used. */
+
+static void
+program_structure ()
+{
+ tab (1, "PROGRAM STRUCTURE");
+ while (opt (IT_dps_CODE))
+ {
+ must (IT_dso_CODE);
+ opt (IT_dss_CODE);
+ dump_symbol_info ();
+ must (IT_dps_CODE);
+ }
+ tab (-1, "");
+}
+
+#endif
+
+#if 0
+
+/* This is no longer used. */
+
+static void
+debug_list ()
+{
+ tab (1, "DEBUG LIST");
+
+ must (IT_du_CODE);
+ opt (IT_dus_CODE);
+ program_structure ();
+ must (IT_dln_CODE);
+
+ tab (-1, "");
+}
+
+#endif
+
+static void
+module ()
+{
+ int c = 0;
+ int l = 0;
+
+ tab (1, "MODULE***\n");
+
+ do
+ {
+ c = getc (file);
+ ungetc (c, file);
+
+ c &= 0x7f;
+ }
+ while (getone (c) && c != IT_tr_CODE);
+
+#if 0
+ must (IT_cs_CODE);
+ must (IT_hd_CODE);
+ opt (IT_hs_CODE);
+
+ unit_info_list ();
+ object_body_list ();
+ debug_list ();
+
+ must (IT_tr_CODE);
+#endif
+ tab (-1, "");
+
+ c = getc (file);
+ while (c != EOF)
+ {
+ printf ("%02x ", c);
+ l++;
+ if (l == 32)
+ {
+ printf ("\n");
+ l = 0;
+ }
+ c = getc (file);
+ }
+}
+
+char *program_name;
+
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, _("Usage: %s [-hV] in-file\n"), program_name);
+ exit (status);
+}
+
+static void
+show_help ()
+{
+ printf (_("%s: Print a human readable interpretation of a SYSROFF object file\n"),
+ program_name);
+ show_usage (stdout, 0);
+}
+
+int
+main (ac, av)
+ int ac;
+ char **av;
+{
+ char *input_file = NULL;
+ int opt;
+ static struct option long_options[] =
+ {
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {NULL, no_argument, 0, 0}
+ };
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = av[0];
+ xmalloc_set_program_name (program_name);
+
+ while ((opt = getopt_long (ac, av, "hV", long_options, (int *) NULL)) != EOF)
+ {
+ switch (opt)
+ {
+ case 'h':
+ show_help ();
+ /*NOTREACHED*/
+ case 'V':
+ printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
+ exit (0);
+ /*NOTREACHED*/
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /*NOTREACHED*/
+ }
+ }
+
+ /* The input and output files may be named on the command line. */
+
+ if (optind < ac)
+ {
+ input_file = av[optind];
+ }
+
+ if (!input_file)
+ {
+ fprintf (stderr, _("%s: no input file specified\n"),
+ program_name);
+ exit (1);
+ }
+
+ file = fopen (input_file, FOPEN_RB);
+ if (!file)
+ {
+ fprintf (stderr, _("%s: cannot open input file %s\n"),
+ program_name, input_file);
+ exit (1);
+ }
+
+ module ();
+ return 0;
+}
diff --git a/binutils/sysinfo.y b/binutils/sysinfo.y
new file mode 100644
index 00000000000..0aa87375dd6
--- /dev/null
+++ b/binutils/sysinfo.y
@@ -0,0 +1,415 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+
+extern char *word;
+extern char writecode;
+extern int number;
+extern int unit;
+char nice_name[1000];
+char *it;
+int sofar;
+int width;
+int code;
+char * repeat;
+char *oldrepeat;
+char *name;
+int rdepth;
+char *loop [] = {"","n","m","/*BAD*/"};
+char *names[] = {" ","[n]","[n][m]"};
+char *pnames[]= {"","*","**"};
+%}
+
+
+%union {
+ int i;
+ char *s;
+}
+%token COND
+%token REPEAT
+%token '(' ')'
+%token <s> TYPE
+%token <s> NAME
+%token <i> NUMBER UNIT
+%type <i> attr_size
+%type <s> attr_desc attr_id attr_type
+%%
+
+top: {
+ switch (writecode)
+ {
+ case 'i':
+ printf("#ifdef SYSROFF_SWAP_IN\n");
+ break;
+ case 'p':
+ printf("#ifdef SYSROFF_p\n");
+ break;
+ case 'd':
+ break;
+ case 'g':
+ printf("#ifdef SYSROFF_SWAP_OUT\n");
+ break;
+ case 'c':
+ printf("#ifdef SYSROFF_PRINT\n");
+ printf("#include <stdio.h>\n");
+ printf("#include <stdlib.h>\n");
+ break;
+ }
+ }
+it_list {
+ switch (writecode) {
+ case 'i':
+ case 'p':
+ case 'g':
+ case 'c':
+ printf("#endif\n");
+ break;
+ case 'd':
+ break;
+ }
+}
+
+ ;
+
+
+it_list: it it_list
+ |
+ ;
+
+it:
+ '(' NAME NUMBER
+ {
+ it = $2; code = $3;
+ switch (writecode)
+ {
+ case 'd':
+ printf("\n\n\n#define IT_%s_CODE 0x%x\n", it,code);
+ printf("struct IT_%s { \n", it);
+ break;
+ case 'i':
+ printf("void sysroff_swap_%s_in(ptr)\n",$2);
+ printf("struct IT_%s *ptr;\n", it);
+ printf("{\n");
+ printf("char raw[255];\n");
+ printf("\tint idx = 0 ;\n");
+ printf("\tint size;\n");
+ printf("memset(raw,0,255);\n");
+ printf("memset(ptr,0,sizeof(*ptr));\n");
+ printf("size = fillup(raw);\n");
+ break;
+ case 'g':
+ printf("void sysroff_swap_%s_out(file,ptr)\n",$2);
+ printf("FILE * file;\n");
+ printf("struct IT_%s *ptr;\n", it);
+ printf("{\n");
+ printf("\tchar raw[255];\n");
+ printf("\tint idx = 16 ;\n");
+ printf("\tmemset (raw, 0, 255);\n");
+ printf("\tcode = IT_%s_CODE;\n", it);
+ break;
+ case 'o':
+ printf("void sysroff_swap_%s_out(abfd,ptr)\n",$2);
+ printf("bfd * abfd;\n");
+ printf("struct IT_%s *ptr;\n",it);
+ printf("{\n");
+ printf("int idx = 0 ;\n");
+ break;
+ case 'c':
+ printf("void sysroff_print_%s_out(ptr)\n",$2);
+ printf("struct IT_%s *ptr;\n", it);
+ printf("{\n");
+ printf("itheader(\"%s\", IT_%s_CODE);\n",$2,$2);
+ break;
+
+ case 't':
+ break;
+ }
+
+ }
+ it_field_list
+')'
+{
+ switch (writecode) {
+ case 'd':
+ printf("};\n");
+ break;
+ case 'g':
+ printf("\tchecksum(file,raw, idx, IT_%s_CODE);\n", it);
+
+ case 'i':
+
+ case 'o':
+ case 'c':
+ printf("}\n");
+ }
+}
+;
+
+
+
+it_field_list:
+ it_field it_field_list
+ | cond_it_field it_field_list
+ | repeat_it_field it_field_list
+ |
+ ;
+
+repeat_it_field: '(' REPEAT NAME
+ {
+ rdepth++;
+ switch (writecode)
+ {
+ case 'c':
+ if (rdepth==1)
+ printf("\tprintf(\"repeat %%d\\n\", %s);\n",$3);
+ if (rdepth==2)
+ printf("\tprintf(\"repeat %%d\\n\", %s[n]);\n",$3);
+ case 'i':
+ case 'g':
+ case 'o':
+
+ if (rdepth==1)
+ {
+ printf("\t{ int n; for (n = 0; n < %s; n++) {\n", $3);
+ }
+ if (rdepth == 2) {
+ printf("\t{ int m; for (m = 0; m < %s[n]; m++) {\n", $3);
+ }
+
+ break;
+ }
+
+ oldrepeat = repeat;
+ repeat = $3;
+ }
+
+ it_field_list ')'
+
+ {
+ repeat = oldrepeat;
+ oldrepeat =0;
+ rdepth--;
+ switch (writecode)
+ {
+ case 'i':
+ case 'g':
+ case 'o':
+ case 'c':
+ printf("\t}}\n");
+ }
+ }
+ ;
+
+
+cond_it_field: '(' COND NAME
+ {
+ switch (writecode)
+ {
+ case 'i':
+ case 'g':
+ case 'o':
+ case 'c':
+ printf("\tif (%s) {\n", $3);
+ break;
+ }
+ }
+
+ it_field_list ')'
+ {
+ switch (writecode)
+ {
+ case 'i':
+ case 'g':
+ case 'o':
+ case 'c':
+ printf("\t}\n");
+ }
+ }
+ ;
+
+it_field:
+ '(' attr_desc '(' attr_type attr_size ')' attr_id
+ {name = $7; }
+ enums ')'
+ {
+ char *desc = $2;
+ char *type = $4;
+ int size = $5;
+ char *id = $7;
+char *p = names[rdepth];
+char *ptr = pnames[rdepth];
+ switch (writecode)
+ {
+ case 'g':
+ if (size % 8)
+ {
+
+ printf("\twriteBITS(ptr->%s%s,raw,&idx,%d);\n",
+ id,
+ names[rdepth], size);
+
+ }
+ else {
+ printf("\twrite%s(ptr->%s%s,raw,&idx,%d,file);\n",
+ type,
+ id,
+ names[rdepth],size/8);
+ }
+ break;
+ case 'i':
+ {
+
+ if (rdepth >= 1)
+
+ {
+ printf("if (!ptr->%s) ptr->%s = (%s*)xcalloc(%s, sizeof(ptr->%s[0]));\n",
+ id,
+ id,
+ type,
+ repeat,
+ id);
+ }
+
+ if (rdepth == 2)
+ {
+ printf("if (!ptr->%s[n]) ptr->%s[n] = (%s**)xcalloc(%s[n], sizeof(ptr->%s[n][0]));\n",
+ id,
+ id,
+ type,
+ repeat,
+ id);
+ }
+
+ }
+
+ if (size % 8)
+ {
+ printf("\tptr->%s%s = getBITS(raw,&idx, %d,size);\n",
+ id,
+ names[rdepth],
+ size);
+ }
+ else {
+ printf("\tptr->%s%s = get%s(raw,&idx, %d,size);\n",
+ id,
+ names[rdepth],
+ type,
+ size/8);
+ }
+ break;
+ case 'o':
+ printf("\tput%s(raw,%d,%d,&idx,ptr->%s%s);\n", type,size/8,size%8,id,names[rdepth]);
+ break;
+ case 'd':
+ if (repeat)
+ printf("\t/* repeat %s */\n", repeat);
+
+ if (type[0] == 'I') {
+ printf("\tint %s%s; \t/* %s */\n",ptr,id, desc);
+ }
+ else if (type[0] =='C') {
+ printf("\tchar %s*%s;\t /* %s */\n",ptr,id, desc);
+ }
+ else {
+ printf("\tbarray %s%s;\t /* %s */\n",ptr,id, desc);
+ }
+ break;
+ case 'c':
+ printf("tabout();\n");
+ printf("\tprintf(\"/*%-30s*/ ptr->%s = \");\n", desc, id);
+
+ if (type[0] == 'I')
+ printf("\tprintf(\"%%d\\n\",ptr->%s%s);\n", id,p);
+ else if (type[0] == 'C')
+ printf("\tprintf(\"%%s\\n\",ptr->%s%s);\n", id,p);
+
+ else if (type[0] == 'B')
+ {
+ printf("\tpbarray(&ptr->%s%s);\n", id,p);
+ }
+ else abort();
+ break;
+ }
+ }
+
+ ;
+
+
+attr_type:
+ TYPE { $$ = $1; }
+ | { $$ = "INT";}
+ ;
+
+attr_desc:
+ '(' NAME ')'
+ { $$ = $2; }
+ ;
+
+attr_size:
+ NUMBER UNIT
+ { $$ = $1 * $2; }
+ ;
+
+
+attr_id:
+ '(' NAME ')' { $$ = $2; }
+ | { $$ = "dummy";}
+ ;
+
+enums:
+ | '(' enum_list ')' ;
+
+enum_list:
+ |
+ enum_list '(' NAME NAME ')' {
+ switch (writecode)
+ {
+ case 'd':
+ printf("#define %s %s\n", $3,$4);
+ break;
+ case 'c':
+ printf("if (ptr->%s%s == %s) { tabout(); printf(\"%s\\n\");}\n", name, names[rdepth],$4,$3);
+ }
+ }
+
+ ;
+
+
+
+%%
+/* four modes
+
+ -d write structure defintions for sysroff in host format
+ -i write functions to swap into sysroff format in
+ -o write functions to swap into sysroff format out
+ -c write code to print info in human form */
+
+int yydebug;
+char writecode;
+
+int
+main(ac,av)
+int ac;
+char **av;
+{
+ yydebug=0;
+ if (ac > 1)
+ writecode = av[1][1];
+if (writecode == 'd')
+ {
+ printf("typedef struct { unsigned char *data; int len; } barray; \n");
+ printf("typedef int INT;\n");
+ printf("typedef char * CHARS;\n");
+
+ }
+ yyparse();
+return 0;
+}
+
+int
+yyerror(s)
+ char *s;
+{
+ fprintf(stderr, "%s\n" , s);
+ return 0;
+}
diff --git a/binutils/syslex.l b/binutils/syslex.l
new file mode 100644
index 00000000000..a39484287a7
--- /dev/null
+++ b/binutils/syslex.l
@@ -0,0 +1,51 @@
+%{
+#include "sysinfo.h"
+char *word;
+int number;
+int unit;
+
+#ifndef yywrap
+static int yywrap () { return 1; }
+#endif
+%}
+%%
+"(" { return '(';}
+")" { return ')';}
+"[" { return '[';}
+"]" { return ']';}
+" " { ; }
+";".* { ; }
+"\t" { ; }
+"\n" { ; }
+"\""[^\"]*"\"" {
+yylval.s = malloc(strlen (yytext));
+strcpy(yylval.s, yytext+1);
+yylval.s[strlen(yylval.s)-1] = 0;
+ return NAME;
+ }
+
+0x[0-9a-f]+ {
+ yylval.i = strtol(yytext,0,16);
+ return NUMBER;
+ }
+
+[0-9]+ {
+ yylval.i = atoi(yytext);
+ return NUMBER;
+ }
+
+
+"bits" { yylval.i =1 ;return UNIT;}
+"bit" { yylval.i = 1; return UNIT;}
+"bytes" { yylval.i= 8; return UNIT;}
+"byte" { yylval.i = 8; return UNIT;}
+
+"int" { yylval.s = "INT"; return TYPE;}
+"barray" { yylval.s = "BARRAY"; return TYPE;}
+"chars" { yylval.s = "CHARS"; return TYPE;}
+"variable" { yylval.i = 0; return NUMBER;}
+"counted" { yylval.i = -4; return NUMBER;}
+"addrsize" { yylval.i = -2; return NUMBER; }
+"segsize" { yylval.i = -1; return NUMBER; }
+"cond" { return COND;}
+"repeat" { return REPEAT;}
diff --git a/binutils/sysroff.info b/binutils/sysroff.info
new file mode 100644
index 00000000000..3af001a1016
--- /dev/null
+++ b/binutils/sysroff.info
@@ -0,0 +1,504 @@
+("cs" 0x0
+ (("size") (1 byte) ("size"))
+
+ (("hd") (1 byte) ("hd"))
+ (("hs") (1 byte) ("hs"))
+ (("un") (1 byte) ("un"))
+ (("us") (1 byte) ("us"))
+
+ (("sc") (1 byte) ("sc"))
+ (("ss") (1 byte) ("ss"))
+ (("er") (1 byte) ("er"))
+ (("ed") (1 byte) ("ed"))
+
+ (("sh") (1 byte) ("sh"))
+ (("ob") (1 byte) ("ob"))
+ (("rl") (1 byte) ("rl"))
+ (("du") (1 byte) ("du"))
+
+ (("dps") (1 byte) ("dps"))
+ (("dsy") (1 byte) ("dsy"))
+ (("dty") (1 byte) ("dty"))
+ (("dln") (1 byte) ("dln"))
+
+ (("dso") (1 byte) ("dso"))
+ (("dus") (1 byte) ("dus"))
+ (("dss") (1 byte) ("dss"))
+ (("dbt") (1 byte) ("dbt"))
+
+ (("dpp") (1 byte) ("dpp"))
+ (("dfp") (1 byte) ("dfp"))
+ (("den") (1 byte) ("den"))
+ (("dds") (1 byte) ("dds"))
+
+ (("dar") (1 byte) ("dar"))
+ (("dpt") (1 byte) ("dpt"))
+ (("dul") (1 byte) ("dul"))
+ (("dse") (1 byte) ("dse"))
+
+ (("dot") (1 byte) ("dot")))
+
+
+("hd" 0x04
+ (("module type") (4 bits) ("mt")
+ (("MTYPE_ABS_LM" "0")
+ ("MTYPE_REL_LM" "1")
+ ("MTYPE_OMS_OR_LMS" "2")
+ ("MTYPE_UNSPEC" "0xf")))
+ (("spare")(4 bits) ("spare1"))
+ (("creation date")( chars 12 bytes)( "cd"))
+ (("number of units") (2 bytes) ("nu"))
+ (("code") (1 byte) ("code"))
+ (("version") (chars 4 bytes) ("ver"))
+ (("address update") (1 byte) ("au"))
+ (("segment identifier") (1 bit) ("si"))
+ (("address field length") (4 bits) ("afl"))
+ (("spare")(3 bits) ("spare2"))
+ (("space size within segment") (1 byte) ("spcsz"))
+ (("segment size") (1 byte) ("segsz"))
+ (("segment shift") (1 byte) ("segsh"))
+ (("entry point") (1 byte) ("ep"))
+ (cond "ptr->ep"
+ (cond "ptr->mt != MTYPE_ABS_LM"
+ (("unit appearance number") (2 bytes) ("uan"))
+ (("section appearance number") (2 bytes) ("sa")))
+ (cond "segmented_p"
+ (("segment address") (segsize bytes) ("sad")))
+ (("address") (addrsize bytes) ("address")))
+ (("os name") (chars variable bytes) ("os"))
+ (("sys name") (chars variable bytes) ("sys"))
+ (("module name") (chars variable bytes) ("mn"))
+ (("cpu") (chars variable bytes) ("cpu")))
+
+
+("hs" 0x05
+ (("neg number") (2 bytes) ("neg")))
+
+
+("un" 0x06
+ (("format") (2 bits) ("format")
+ (("FORMAT_LM" "0")
+ ("FORMAT_OM" "1")
+ ("FORMAT_OMS_OR_LMS" "2")))
+ (("spare") (6 bits) ("spare1"))
+ (("number of sections") (2 bytes) ("nsections"))
+ (("number of external refs") (2 bytes) ("nextrefs"))
+ (("number of external defs") (2 bytes) ("nextdefs"))
+ (("unit name") (chars variable byte) ("name"))
+ (("tool name") (chars variable byte) ("tool"))
+ (("creation date") (chars 12 bytes) ("tcd"))
+ (("linker name") (chars variable byte) ("linker"))
+ (("creation date") (chars 12 bytes) ("lcd")))
+
+
+("us" 0x07
+ (("negotiation number") (2 bytes) ("neg")))
+
+
+("sc" 0x08
+ (("format") (2 bits) ("format"))
+ (("spare") (6 bits) ("spare"))
+ (("segment address") (segsize bytes) ("segadd"))
+ (("address") (addrsize bytes) ("addr"))
+ (("length") (addrsize bytes) ("length"))
+ (("alignment") (addrsize bytes) ("align"))
+ (("contents") (4 bits) ("contents")
+ (("CONTENTS_CODE" "0")
+ ("CONTENTS_DATA" "1")
+ ("CONTENTS_STACK" "2")
+ ("CONTENTS_DUMMY" "3")
+ ("CONTENTS_SPECIAL" "4")
+ ("CONTENTS_NONSPEC" "0xf")))
+ (("concat") (4 bits) ("concat")
+ (("CONCAT_SIMPLE" "0")
+ ("CONCAT_SHAREDC" "1")
+ ("CONCAT_DUMMY" "2")
+ ("CONCAT_GROUP" "3")
+ ("CONCAT_SHARED" "4")
+ ("CONCAT_PRIVATE" "5")
+ ("CONCAT_UNSPEC" "0xf")))
+ (("read") (2 bits) ("read"))
+ (("write") (2 bits) ("write"))
+ (("exec") (2 bits) ("exec"))
+ (("initialized") (2 bits) ("init"))
+ (("mode") (2 bits) ("mode"))
+ (("spare") (6 bits) ("spare1"))
+ (("name") (chars variable byte) ("name")))
+
+
+("ss" 0x09
+ (("neg number") (2 bytes) ("neg")))
+
+
+("er" 0x0c
+ (("symbol type") (2 bits) ("type")
+ (("ER_ENTRY" "0")
+ ("ER_DATA" "1")
+ ("ER_NOTDEF" "2")
+ ("ER_NOTSPEC" "3")))
+ (("spare") (6 bits) ("spare"))
+ (("symbol name") (chars variable byte) ("name")))
+
+
+("ed" 0x14
+ (("section appearance number") (2 bytes) ("section"))
+ (("symbol type") (3 bits) ("type")
+ (("ED_TYPE_ENTRY" "0")
+ ("ED_TYPE_DATA" "1")
+ ("ED_TYPE_CONST" "2")
+ ("ED_TYPE_NOTSPEC" "7")))
+ (("spare") (5 bits) ("spare"))
+ (cond "ptr->type==ED_TYPE_ENTRY || ptr->type==ED_TYPE_DATA"
+ (("symbol address") (addrsize bytes) ("address")))
+ (cond "ptr->type==ED_TYPE_CONST"
+ (("constant value") (addrsize bytes) ("constant")))
+ (("symbol name") (chars variable byte) ("name")))
+
+
+("sh" 0x1a
+ (("unit appearance number") (2 bytes) ("unit"))
+ (("section appearance number") (2 bytes) ("section")))
+
+
+("ob" 0x1c
+ (("starting address flag") (1 bit) ("saf"))
+ (("compression flag") (1 bit) ("cpf"))
+ (("spare") (6 bits) ("spare"))
+ (cond "ptr->saf"
+ ( ("starting address") (addrsize bytes) ("address")))
+ (cond "ptr->cpf"
+ (("comp reps") (addrsize bytes) ("compreps")))
+ (("data") (barray counted byte) ("data")))
+
+
+("rl" 0x20
+ (("boundary of relocateable area") (4 bits) ("boundary"))
+ (("address polarity") (1 bit) ("apol"))
+ (("segment number") (1 bit) ("segment"))
+ (("sign of relocation") (1 bit) ("sign"))
+ (("check range") (1 bit) ("check"))
+ (("reloc address") (addrsize bytes) ("addr"))
+
+ (("bit loc") (1 byte) ("bitloc"))
+ (("field length") (1 byte) ("flen"))
+ (("bcount") (1 byte) ("bcount"))
+ (("operator") (1 byte) ("op")
+ (("OP_RELOC_ADDR" "1")
+ ("OP_SEC_REF" "0")
+ ("OP_EXT_REF" "2")))
+ (cond "ptr->op == OP_EXT_REF"
+ (("symbol number") (2 bytes) ("symn")) )
+
+ (cond "ptr->op == OP_SEC_REF"
+ (("section number") (2 bytes) ("secn"))
+ (("const opcode") (1 byte) ("copcode_is_3"))
+ (("addend length") (1 byte) ("alength_is_4"))
+ (("addend") (4 byte) ("addend"))
+ (("plus opcode") (1 byte) ("aopcode_is_0x20")))
+
+ (cond "ptr->op == OP_RELOC_ADDR"
+ (("dunno") (2 bytes) ("dunno")))
+
+ (("end") (1 byte) ("end")))
+
+
+("du" 0x30
+ (("format") (2 bits) ("format"))
+ (("optimized") (1 bit) ("optimized"))
+ (("stackfrmt") (2 bits) ("stackfrmt"))
+ (("spare") (3 bits) ("spare"))
+ (("unit number") (2 bytes) ("unit"))
+ (("sections") (2 bytes) ("sections"))
+ (repeat "ptr->sections"
+ (("section appearance number") (2 bytes) ("san"))
+ (("address") (addrsize bytes) ("address"))
+ (("section length") (addrsize bytes) ("length")))
+ (("tool name") (chars variable byte) ("tool"))
+ (("creation date") (chars 12 bytes) ("date")))
+
+
+("dsy" 0x34
+ (("symbol type") (7 bits) ("type")
+ (("STYPE_VAR" "0")
+ ("STYPE_LAB" "1")
+ ("STYPE_PROC" "2")
+ ("STYPE_FUNC" "3")
+ ("STYPE_TYPE" "4")
+ ("STYPE_CONST" "5")
+ ("STYPE_ENTRY" "6")
+ ("STYPE_MEMBER" "7")
+ ("STYPE_ENUM" "8")
+ ("STYPE_TAG" "9")
+ ("STYPE_PACKAGE" "10")
+ ("STYPE_GENERIC" "11")
+ ("STYPE_TASK" "12")
+ ("STYPE_EXCEPTION" "13")
+ ("STYPE_PARAMETER" "14")
+ ("STYPE_EQUATE" "15")
+ ("STYPE_UNSPEC" "0x7f")))
+ (("assignment info") (1 bit) ("assign"))
+ (("symbol id") (2 bytes) ("snumber"))
+ (("symbol name") (chars variable bytes) ("sname"))
+ (("nesting level") (2 bytes) ("nesting"))
+ (cond "ptr->assign"
+ (("assignment type") (1 byte) ("ainfo")
+ (("AINFO_REG" "1")
+ ("AINFO_STATIC_EXT_DEF" "2")
+ ("AINFO_STATIC_EXT_REF" "3")
+ ("AINFO_STATIC_INT" "4")
+ ("AINFO_STATIC_COM" "5")
+ ("AINFO_AUTO" "6")
+ ("AINFO_CONST" "7")
+ ("AINFO_UNSPEC" "0xff")))
+ (("data length") (addrsize bytes) ("dlength"))
+ (cond "ptr->ainfo == AINFO_STATIC_EXT_DEF
+ || ptr->ainfo == AINFO_STATIC_INT
+ || ptr->ainfo == AINFO_STATIC_COM"
+ (("section number") (2 bytes) ("section")))
+ (cond "ptr->ainfo == AINFO_STATIC_EXT_DEF
+ || ptr->ainfo == AINFO_STATIC_INT
+ || ptr->ainfo == AINFO_STATIC_COM
+ || ptr->ainfo == AINFO_AUTO"
+ (("address") (addrsize bytes) ("address")))
+ (cond "ptr->ainfo == AINFO_REG"
+ (("register name") (chars variable bytes) ("reg")))
+ (cond "ptr->ainfo == AINFO_STATIC_EXT_DEF
+ || ptr->ainfo == AINFO_STATIC_EXT_REF"
+ (("external name") (chars variable bytes) ("ename")))
+ (cond "ptr->ainfo == AINFO_CONST"
+ (("constant") (chars variable bytes) ("constant"))))
+ (cond "ptr->type == STYPE_MEMBER"
+ (("assignment unit") (1 bit) ("bitunit"))
+ (("spare") (7 bits) ("spare2"))
+ (("field length") (addrsize bytes) ("field_len"))
+ (("field offset") (addrsize bytes) ("field_off"))
+ (cond "ptr->bitunit"
+ (("bit offset") (addrsize bytes) ("field_bitoff"))))
+ (cond "ptr->type== STYPE_ENUM"
+ (("value length") (1 byte) ("evallen"))
+ (("value") (4 bytes) ("evalue")))
+ (cond "ptr->type == STYPE_CONST"
+ (("value") (chars variable bytes) ("cvalue")))
+ (cond "ptr->type == STYPE_EQUATE"
+ (("value length") (1 byte) ("qvallen"))
+ (("value") (4 bytes) ("qvalue"))
+ (("basic type") (1 byte) ("btype"))
+ (("size information") (addrsize bytes) ("sizeinfo"))
+ (("sign") (2 bits) ("sign"))
+ (("floating point type") (6 bits) ("flt_type")))
+ (("source file number") (2 bytes) ("sfn"))
+ (("source line number") (2 bytes) ("sln"))
+ (("negotiation number") (2 bytes) ("neg"))
+ (cond "ptr->type == STYPE_TAG"
+ (("magic") (1 byte) ("magic"))))
+
+
+
+("dul" 0x52
+ (("max declaration type flag") (1 bit) ("max_variable"))
+ (("max spare") (7 bits) ("maxspare"))
+ (cond "ptr->max_variable == 0"
+ (("maximum") (addrsize bytes) ("max"))
+ (("max mode") (chars variable bytes) ("maxmode")))
+
+ (("min declaration type flag") (1 bit) ("min_variable"))
+ (("min spare") (7 bits) ("minspare"))
+ (cond "ptr->min_variable == 0"
+ (("minimum") (addrsize bytes) ("min"))
+ (("min mode") (chars variable bytes) ("minmode"))))
+
+
+("dty" 0x36
+ (("end flag") (1 bit) ("end"))
+ (("spare") (7 bits) ("spare"))
+ (cond "!ptr->end"
+ (("negotiation") (2 bytes) ("neg"))))
+
+
+("dbt" 0x44
+ (("basic type") (1 byte) ("btype")
+ (("BTYPE_VOID" "0")
+ ("BTYPE_UNDEF" "1")
+ ("BTYPE_CHAR" "2")
+ ("BTYPE_INT" "3")
+ ("BTYPE_FLOAT" "4")
+ ("BTYPE_BIT" "5")
+ ("BTYPE_STRING" "6")
+ ("BTYPE_DECIMAL" "7")
+ ("BTYPE_ENUM" "8")
+ ("BTYPE_STRUCT" "9")
+ ("BTYPE_TYPE" "10")
+ ("BTYPE_TAG" "11")
+ ("BTYPE_UNSPEC" "0xff")))
+ (("size info") (addrsize bytes) ("bitsize"))
+ (("sign") (2 bits) ("sign")
+ (("SIGN_SIGNED" "0")
+ ("SIGN_UNSIGNED" "1")
+ ("SIGN_UNSPEC" "3")))
+ (("floating point type") (6 bits) ("fptype")
+ (("FPTYPE_SINGLE" "0")
+ ("FPTYPE_DOUBLE" "1")
+ ("FPTYPE_EXTENDED" "2")
+ ("FPTYPE_NOTSPEC" "0x3f")))
+ (cond "ptr->btype==BTYPE_TAG || ptr->btype == BTYPE_TYPE"
+ (("symbol id") (2 bytes) ("sid")))
+ (("negotiation") (2 bytes) ("neg")))
+
+("dar" 0x4e
+ (("element length" ) (addrsize bytes) ("length"))
+ (("dims") (1 byte) ("dims"))
+ (repeat "ptr->dims"
+ (("variable flag") (1 bit) ("variable")
+ (("VARIABLE_FIXED" "0")
+ ("VARIABLE_VARIABLE" "1")))
+
+ (("subscript type") (1 bit) ("subtype")
+ (("SUB_INTEGER" "0")
+ ("SUB_TYPE" "1")))
+
+ (("spare") (6 bits) ("spare"))
+
+ (cond "ptr->subtype[n] == SUB_TYPE"
+ (("sub symbol id") (2 bytes) ("sid")))
+
+ (cond "ptr->subtype[n] == SUB_INTEGER"
+ (("max declaration type flag") (1 bit) ("max_variable"))
+ (("max spare") (7 bits) ("maxspare"))
+ ;; FIXME: next field should be conditional on max_variable,
+ (("maximum") (addrsize bytes) ("max"))
+
+ (("min declaration type flag") (1 bit) ("min_variable"))
+ (("min spare") (7 bits) ("minspare"))
+ ;; FIXME: next field should be conditional on min_variable
+ (("minimum") (addrsize bytes) ("min"))))
+ (("negotiation") (2 bytes) ("neg")))
+
+
+("dso" 0x3a
+ (("function name") (2 bytes) ("sid"))
+ (("sp update count") (4 bytes) ("spupdates"))
+ (repeat "ptr->spupdates"
+ (("update address") (addrsize bytes) ("address"))
+ (("offset") (addrsize bytes) ("offset"))))
+
+("dln" 0x38
+ (("number of lines") (2 bytes) ("nln"))
+ (repeat "ptr->nln"
+ (("source file number") (2 bytes) ("sfn"))
+ (("source line number") (2 bytes) ("sln"))
+ (("section number") (2 bytes) ("section"))
+ (("from address") (addrsize bytes) ("from_address"))
+ (("to address") (addrsize bytes) ("to_address"))
+ (("call count") (2 bytes) ("cc"))
+ )
+ (("neg") (2 bytes) ("neg")))
+
+("dpp" 0x46
+ (("start/end") (1 bit) ("end"))
+ (("spare") (7 bits) ("spare"))
+ (cond "!ptr->end"
+ (("params") (1 byte) ("params"))
+ (("neg number") (2 bytes) ("neg"))))
+
+("den" 0x4a
+ (("start/end") (1 bit) ("end"))
+ (("spare") (7 bits) ("spare"))
+ (cond "!ptr->end"
+ (("neg number") (2 bytes) ("neg"))))
+
+("dfp" 0x48
+ (("start/end flag") (1 bit) ("end"))
+ (("spare") (7 bits) ("spare"))
+ (cond "!ptr->end"
+ (("number of parameters") (1 byte) ("nparams"))
+ (("neg number") (2 bytes) ("neg"))))
+
+("dds" 0x4c
+ (("start/end") (1 bit) ("end"))
+ (("spare") (7 bits) ("spare"))
+ (cond "!ptr->end"
+ (("neg number") (2 bytes) ("neg"))))
+
+("dpt" 0x50
+ (("neg number") (2 bytes) ("neg"))
+ (("dunno") (1 byte) ("dunno")))
+
+("dse" 0x54
+ (("neg number") (2 bytes) ("neg"))
+ (("dunno") (1 byte) ("dunno")))
+
+("dot" 0x56
+ (("unknown") (1 byte) ("unknown")))
+; FIXME: unknown field should be repeated symbol number?
+
+
+("dss" 0x42
+ (("type") (1 byte) ("type"))
+ (("external/internal") (1 bit) ("internal"))
+ (("spare") (7 bits) ("spare"))
+ (cond "!ptr->internal"
+ ( ("package name") (chars variable byte) ("package")))
+ (cond "ptr->internal"
+ (("symbol id") (2 bytes) ("id")))
+ (("record type") (2 bytes) ("record"))
+ (("rules") (chars variable byte) ("rules"))
+ (("number of symbols") (2 bytes) ("nsymbols"))
+ (("unknown" ) (2 bytes) ("fixme")))
+
+("pss" 0x40
+ (("negotiation number") (2 bytes) ("efn"))
+ (("number of source files") (2 bytes) ("ns"))
+ (repeat "ptr->ns"
+ (("directory reference bit") (1 bit) ("drb"))
+ (("spare") (7 bits) ("spare"))
+ (("completed file name") (chars variable byte) ("fname"))
+ (cond "ptr->drb[n]"
+ (("directory apperance number") (2 bytes) ("dan"))))
+
+ (("number of directories") (2 bytes) ("ndir"))
+ (repeat "ptr->ndir"
+ (("directory name") (chars variable bytes) ("dname"))))
+
+
+; FIXME: the tr block has no contents. sysinfo, etc. aren't prepared
+; to deal with that.
+; ("tr" 0x7f)
+
+
+("dus" 0x40
+ (("negotiation number") (2 bytes) ("efn"))
+ (("number of source files") (2 bytes) ("ns"))
+ (repeat "ptr->ns"
+ (("directory reference bit") (1 bit) ("drb"))
+ (("spare") (7 bits) ("spare"))
+ (("completed file name") (chars variable byte) ("fname"))
+ (cond "ptr->drb[n]"
+ (("directory apperance number") (2 bytes) ("dan"))))
+ (("number of directories") (2 bytes) ("ndir"))
+ (repeat "ptr->ndir"
+ (("directory name") (chars variable bytes) ("dname"))))
+
+
+("dps" 0x32
+ (("start/end flag") (1 bit) ("end"))
+ (("block type") (7 bits) ("type")
+ (("BLOCK_TYPE_COMPUNIT" "0")
+ ("BLOCK_TYPE_PROCEDURE" "2")
+ ("BLOCK_TYPE_FUNCTION" "3")
+ ("BLOCK_TYPE_BLOCK" "4")
+ ("BLOCK_TYPE_BASIC" "9")))
+ (cond "!ptr->end"
+ (("optimization") (1 byte) ("opt"))
+ (("section number") (2 bytes) ("san"))
+ (("address") (addrsize bytes) ("address"))
+ (("block size") (addrsize bytes) ("block_size"))
+ (("nesting") (1 byte) ("nesting"))
+ (cond "ptr->type == BLOCK_TYPE_PROCEDURE
+ || ptr->type == BLOCK_TYPE_FUNCTION"
+ (("return address") (1 bit) ("retaddr"))
+ (("interrupt function flag") (1 bit) ("intrflag"))
+ (("stack update flag") (1 bit) ("stackflag"))
+ (("intra page JMP") (1 bit) ("intrpagejmp"))
+ (("spare") (4 bits) ("spare")))
+ (("neg number") (2 bytes) ("neg"))))
+
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
new file mode 100644
index 00000000000..15a0577791f
--- /dev/null
+++ b/binutils/testsuite/ChangeLog
@@ -0,0 +1,585 @@
+1999-03-12 Nick Clifton <nickc@cygnus.com>
+
+ * binutils-all/readelf.wi: Remove FR30 specific componnts.
+ * binutils-all/readelf.s: Remove RELA specific components.
+
+1999-02-16 Nick Clifton <nickc@cygnus.com>
+
+ * binutils-all/readelf.s: Do not assume section alignment is 4.
+ * binutils-all/readelf.r: Do not assume rela's are being used.
+ * binutils-all/readelf.exp: disable tests for non ELF based
+ targets.
+
+1999-02-02 Nick Clifton <nickc@cygnus.com>
+
+ * binutils-all/readelf.wi: Amend to match new readelf output.
+ * binutils-all/readelf.r: Do not assume that RELAs will be used.
+
+1999-01-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/default.exp: Add definitions of READELF and READELFFLAGS.
+
+ * binutils-all/readelf.exp: New file: Readelf tests
+ * binutils-all/readelf.h: New file: Expected results for 'readelf -h'
+ * binutils-all/readelf.s: New file: Expected results for 'readelf -S'
+ * binutils-all/readelf.ss: New file: Expected results for 'readelf -s'
+ * binutils-all/readelf.r: New file: Expected results for 'readelf -r'
+ * binutils-all/readelf.wi: New file: Expected results for 'readelf -wi'
+
+Wed Dec 9 19:11:39 1998 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objcopy.exp (copy_executable): Expect comparison
+ failure for mips*-*-elf.
+
+Fri Oct 16 22:57:12 1998 Felix Lee <flee@cygnus.com>
+
+ * binutils-all/objcopy.exp: fix "no symbols" message.
+
+Tue Jul 28 15:14:04 1998 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objcopy.exp: Keep "main" and "_main" for strip with
+ saving symbol tests. Look for either "main" or "_main" in the output
+ file. Fix test for "no symbols" in the output file.
+
+1998-07-22 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * binutils-all/objcopy.exp: Polish output about fail for objcopy
+ (simple copy), strip with/without saving a symbol for object file
+ and executable.
+
+Wed Jul 1 16:27:40 1998 Nick Clifton <nickc@cygnus.com>
+
+ * binutils-all/objcopy.exp: ARM simple objcopy now passes.
+
+Wed Jun 24 09:20:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * binutils-all/objdump.exp: Look for '.data' rather than 'data'
+ when parsing output of objdump -h.
+ * binutils-all/size.exp: Look for '.data' rather than 'data' when
+ parsing output of size -A.
+
+1998-07-20 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * objcopy.exp: Two new tests - strip object file with saving a
+ symbol and strip executable file with saving a symbol.
+
+Fri May 29 14:50:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Don't xfail the simple objcopy test
+ when cross compiling.
+
+Thu Nov 6 14:32:37 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/utils-lib.exp: Temporary definition of target_assemble and
+ default_target_assemble so that testing can work with older
+ dejagnu versions.
+
+Wed Sep 24 12:09:15 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * binutils-all/objcopy.exp(strip_executable): Make a new copy of
+ the executable being tested.
+
+Mon Sep 15 21:25:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * binutils-all/objcopy.exp: Compile the executables to be tested
+ on the target with a status wrapper (as necessary).
+
+ * binutils-all/ar.exp: If testing on a remote host, don't bother
+ looking on the local host for the program being tested. Use the
+ correct filenames on the remote host.
+
+ * binutils-all/nm.exp: Ditto.
+
+ * binutils-all/size.exp: Ditto.
+
+ * binutils-all/objdump.exp: Ditto.
+ (cpus_expected): Add the target CPU to the regexp of CPUs to be
+ expected, if it's not already there.
+
+Thu Aug 28 09:57:27 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * binutils-all/objdump.exp (cpus_expected): Add arc.
+
+Tue Aug 5 00:03:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Look for nm-new and strip-new.
+
+Tue Jun 3 17:12:54 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/default.exp: Remove expect_before statement.
+
+ * binutils-all/objcopy.exp: Don't use global exec_output variable;
+ the output is returned from remote_load instead.
+
+Mon May 12 22:14:20 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * binutils-all/objcopy.exp(strip_test): Tests that
+ fail to compile are untested, not unresolved.
+ (copy_setup): Ditto.
+
+ * lib/utils-lib.exp(default_binutils_assemble): Call
+ target_assemble instead of target_compile.
+
+Wed Apr 30 20:37:51 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ Changes to support multilib and remote hosted testing, along with
+ general cleanups and simplifications.
+
+ * lib/utils-lib.exp(binutil_version): Use remote_exec.
+ (default_binutils_run): Ditto.
+ (default_binutils_assemble): Remove first argument; call
+ target_compile to actually do the assembly.
+ (default_binutils_compile,default_binutils_remove,prune_warnings):
+ Delete.
+
+ * config/default.exp: Remove AS and ASFLAGS.
+ (binutils_compile,binutils_remove): Delete.
+ (binutils_assemble): Remove first argument.
+
+ * binutils-all/ar.exp: See if we're running the tests on
+ a remote host, and download/upload files as appropriate.
+ Replace calls to binutils_remove with remote_file. Replace
+ calls to binutils_compile with target_compile. Remove initial
+ argument to binutils_assemble. Use remote_load to execute
+ programs on the target.
+ * binutils-all/nm.exp: Ditto.
+ * binutils-all/objcopy.exp: Ditto.
+ * binutils-all/objdump.exp: Ditto.
+ * binutils-all/size.exp: Ditto.
+
+Mon Apr 14 12:36:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/ar.exp (long_filenames): Check for a file system
+ with a 14 character file name length limit.
+
+Tue Apr 1 09:52:15 1997 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objdump.exp: Handle d10v.
+
+Fri Feb 7 16:45:34 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * binutils-all/ar.exp: Use prune_warnings instead of
+ prune_system_crud.
+ * binutils-all/objcopy.exp: Ditto.
+
+Wed Jan 29 00:16:43 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * binutils-all/nm.exp: Use / between $srcdir and $subdir.
+ * binutils-all/objcopy.exp: Ditto.
+ * binutils-all/objdump.exp: Ditto.
+ * binutils-all/size.exp: Ditto.
+ * binutils-all/hppa/objdump.exp: Ditto.
+
+
+Wed Oct 16 22:57:59 1996 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objdump.exp: Add mn10200 and mn10300 to expected
+ cpus list.
+
+Tue Oct 1 15:06:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils-lib.exp (binutil_version): Fix for current version
+ printing.
+
+Sun Aug 4 22:25:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Fix end of line matching in srec tests
+ to work with TCL 7.5.
+
+Sat Jun 29 12:51:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Simple copy test works for i960 b.out
+ targets.
+
+Mon Jun 24 14:33:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: On OSF/1, the simple copy test will
+ succeed with gas, and fail with /bin/as, so mark it as an expected
+ failure only if it fails.
+
+Tue Mar 26 16:55:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objcopy.exp: No longer expect adjust-section-vma
+ test to fail for hppa*-*-proelf*.
+
+Mon Mar 11 08:25:14 1996 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objdump.exp: Look for "$CODE$", not just "CODE".
+
+Wed Jan 31 11:55:13 1996 Jeffrey A Law (law@cygnus.com)
+
+ * binutils-all/objcopy.exp: Expect adjust-section-vma tests to
+ fail for hppa*-*-proelf* targets.
+
+Thu Jan 25 13:53:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objdump.exp: Update for objdump -h format change.
+ * binutils-all/objcopy.exp: Likewise.
+
+Mon Jan 15 18:14:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Use the lma, not the vma, when testing
+ address adjustments.
+
+Fri Dec 15 16:31:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objdump.exp: Update objdump -i test for current
+ objdump output.
+
+Mon Nov 27 15:15:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Correct fail calls to always use the
+ same string as the pass call.
+
+Wed Nov 22 13:18:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils-lib.exp (prune_system_crud): Discard -g -O warnings
+ from native compilers on OSF/1 and SunOS.
+
+Fri Nov 17 10:36:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils-lib.exp (default_binutils_compiler: Change error
+ message to say compilation rather than assembly.
+
+Wed Nov 15 18:34:42 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * binutils-all/objcopy.exp: Simple copy test does appear to work
+ on i*86-svr4.
+
+Wed Nov 15 12:19:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: If assembly fails, call unresolved.
+ Test running objcopy and strip on a final executable.
+ * binutils-all/testprog.c: New file.
+ * config/default.exp (STRIP, STRIPFLAGS): Define.
+ (binutils_compile): New procedure.
+ * lib/utils-lib.exp (default_binutils_compile): New procedure.
+
+Fri Nov 3 13:22:33 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils-lib.exp (default_binutils_run): Don't use verbose
+ -log, reverting part of Oct 2 change.
+
+Wed Nov 1 15:09:57 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * binutils-all/objcopy.exp: Add setup_xfails for
+ m68*-motorola-sysv* and m88*-motorola-sysv*.
+
+Wed Oct 4 14:38:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/nm.exp: Add setup_xfails for XCOFF.
+
+Mon Oct 2 12:41:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/ar.exp: New file.
+ * binutils-all/bintest.s: Make text_symbol and data_symbol global.
+ Add new static symbols static_text_symbol and static_data_symbol.
+ * binutils-all/nm.exp: Adjust accordingly.
+ * config/default.exp (AR): Set if not set.
+ (binutils_remove): New procedure.
+ * lib/utils-lib.exp (default_binutils_run): Call
+ prune_system_crud on program output. Use verbose -log instead of
+ both verbose and send_log.
+ (default_binutils_remove): New procedure.
+
+ * lib/utils-lib.exp (default_binutils_assemble): Call
+ prune_system_crud on assembler output.
+
+Tue Sep 26 14:07:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add setup_xfails for simple copy test
+ for i386 COFF targets.
+
+Wed Sep 13 13:20:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils-lib.exp (prune_system_crud): Define if not defined.
+ * binutils-all/objcopy.exp: Call prune_system_crud on cmp output.
+
+Sat Aug 19 17:38:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add xfail for i*86-*-aout* for simple
+ copy test.
+
+Wed Aug 16 16:52:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/nm.exp: Add setup_xfail for mips*-sony-bsd* for
+ tests which fail on ECOFF targets.
+
+ * binutils-all/objcopy.exp: Change i*86-*-linux xfail for simple
+ copy test to check for i*86-*-linuxaout* instead.
+
+Tue Aug 8 17:48:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add setup_xfail for a29k-*-vxworks*
+ for simple copy test.
+
+Tue Jul 25 11:57:12 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Change setup_xfail for simple copy
+ test from i960-*-vxworks5.1 to i960-*-vxworks*.
+
+Mon Jul 10 12:25:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add setup_xfail for z8*-*-coff for
+ simple copy test.
+ * binutils-all/objdump.exp (cpus_expected): Add z8001 and z8002.
+
+Sun May 21 20:32:53 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * binutils-all/hppa/objdump.exp (addendbug): Handle PA ELF targets
+ too.
+ * binutils-all/objcopy.exp (simple copy): Don't expect PA ELF
+ targets to fail.
+
+Tue Apr 4 14:52:08 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * binutils-all/hppa: Renamed from binutils-hppa.
+
+Wed Mar 29 12:02:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add setup_xfail for simple copy test
+ for h8500-*-hms and h8500-*-coff.
+
+Tue Mar 28 11:18:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add setup_xfail for simple copy test
+ for m68*-ericsson-ose and m88*-*-coff.
+
+Mon Mar 27 11:27:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objcopy.exp: Add setup_xfail for simple copy test
+ for m68*-*-vxworks*.
+
+Fri Mar 24 11:44:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-hppa/objdump.exp: Correct hppa*-*-* check.
+
+Tue Mar 21 10:48:45 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * binutils-hppa/addendbug.s: New testcase.
+ * binutils-hppa/objdump.exp: Run it.
+
+Mon Mar 20 11:31:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/utils-lib.exp (default_binutils_run): Quote any dollar signs
+ in progargs before passing it to exec.
+
+Fri Mar 17 16:39:31 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/hppa.sed: Sed script to transform bintest.s into proper
+ PA assembly code.
+ * binutils-all/nm.exp: Enable these tests on the PA.
+ * binutils-all/objcopy.exp: Enable these tests on the PA. Expect
+ simple copy to fail.
+ * binutils-all/objdump.exp: Enable these tests on the PA. Handle
+ "CODE" as a section name.
+ * binutils-all/size.exp: Enable these tests on the PA.
+ * lib/utils-lib.exp (default_binutils_assemble): For "hppa*-*-*",
+ run the assembly through a sed script before passing it to the
+ assembler.
+
+Wed Mar 15 16:47:13 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/objdump.exp: Force section sizes to be interpreted
+ in hex. Change objdump -h failure mode to always use the same
+ string.
+
+Thu Jan 5 13:01:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * binutils-all/nm.exp: Just check for irix4*, rather than
+ irix\[0-4\]*, to avoid DejaGnu bug.
+
+Thu Dec 15 19:35:31 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * binutils-all/objcopy.exp: Expect simple-objcopy test to fail
+ for various other targets for which gas doesn't use bfd: sh-hms,
+ m68k-hpux, m68k-sunos, m68k-coff, i386-linux, a29k-udi, a29k-coff,
+ i960-vxworks5.1, i960-coff, h8300-hms, h8300-coff.
+
+Wed Dec 14 15:54:46 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * binutils-all/size.exp: Skip tests requiring bintest.o on hppa,
+ since it (correctly) generates syntax errors on that platform.
+ * binutils-all/objdump.exp: Ditto.
+ * binutils-all/nm.exp: Ditto.
+ * binutils-all/objcopy.exp: Ditto. Also, move setup_xfail for
+ sh-coff to branch where objcopy execution produced no error
+ messages. Expect failure for hp300 also.
+
+Thu Dec 8 14:36:15 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * binutils-all/objdump.exp (cpus_expected): New variable, taken
+ from objdump -i test, added ns32k and powerpc, sorted.
+ (objdump -i, -f tests): Use $cpus_expected.
+
+ * binutils-all/objcopy.exp: For simple-copy test, expect failure
+ for sh-coff.
+
+Tue Oct 25 16:00:14 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * binutils-all/objcopy.exp: Adjust --adjust-section-vma tests for
+ new S-record section handling.
+
+Tue Oct 18 11:18:21 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * binutils-all/nm.exp: nm with no arguments and nm -P do not work
+ as expected on ECOFF targets; add calls to setup_xfail.
+
+ * binutils-all/objcopy.exp: New file.
+ * config/default.exp: Initialize OBJCOPY and OBJCOPYFLAGS.
+
+Fri Oct 14 14:46:22 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ Rewrite testsuite.
+ * configure.in, Makefile.in: Remove.
+ * binutils-all/configure.in, binutils-all/Makefile.in: Remove.
+ * binutils-all/bintest.c: Remove.
+ * binutils-all/bintest.s: New file.
+ * binutils-all/nm.exp, binutils-all/objdump.exp: Rewrite.
+ * binutils-all/size.exp: Rewrite.
+ * config/default.exp: Load utils-lib.exp. Set AS and ASFLAGS.
+ Don't go up one directory from $base_dir. Create tmpdir.
+ (binutils_run, binutils-assemble): New procedures.
+ * config/unix.exp: Remove.
+ * config/mt-a29k-udi, config/mt-i386-aout: Remove.
+ * config/mt-i960-nindy, config/mt-lynx, config/mt-m68k: Remove.
+ * config/mt-mips-ecoff, config/mt-slite: Remove.
+ * config/mt-sparc-aout, config/mt-vxworks: Remove.
+ * lib/utils-lib.exp (binutil_version): Don't redirect standard
+ input when getting version. Don't unset errorInfo.
+ (default_binutils_run): New procedure.
+ (default_binutils_assemble): New procedure.
+
+Thu Sep 29 12:45:39 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * VMS does not permit `.' in directory names: renamed binutils.all
+ to binutils-all.
+ * configure.in (configdirs): Change binutils.all to binutils-all.
+
+Fri Sep 23 16:01:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Use mt-m68k for m68k*-*-aout* and m68k*-*-coff*,
+ not for m68k-*-*.
+
+Fri Sep 23 13:54:50 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * binutils.all/objdump.exp: Added ARM to list of CPU types.
+
+Thu Sep 22 11:04:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * binutils.all/objdump.exp: Update for new usage message.
+ * binutils.all/size.exp: Use a double backslash in the string to
+ get a single backslash to the regexp matcher. Accept $TEXT$,
+ $DATA$ and $BSS$ as well as .text, .data and .bss, for HP/UX.
+
+Fri Sep 2 12:53:10 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/unix.exp: If nm.new does not exist, use [transform nm].
+ * config/default.exp: Likewise.
+
+Wed Aug 24 12:41:37 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in, binutils.all/configure.in: Change i386 to
+ i[345]86.
+
+Tue Jul 19 15:23:53 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * config/mt-mips-ecoff: Add -Tidp.ld option.
+
+Thu Jun 30 12:41:55 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/default.exp: Use nm.new, not nm, from newly built tree.
+
+Tue May 17 14:04:05 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * config/default.exp, config/unix.exp: Replace error
+ proc calls with perror.
+
+Tue May 10 11:20:54 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * configure.in (sparclite): Match on sparclite*-*-*.
+
+Wed Apr 13 18:25:19 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/unix.exp: Use nm.new, not nm, from newly built tree.
+
+ * binutils.all/objdump.exp: Add more wildcards to list of
+ single-letter options in pattern for usage message.
+
+ * binutils.all/nm.exp: Deleted debug-symbols test, since it only
+ works for a.out/stabs systems. Fixed regexps to make underscores
+ optional, since some C compilers don't prepend them. Deleted
+ check for foo.o symbol, since again some systems don't generate
+ it.
+
+Mon Apr 11 10:31:00 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in (check): Set TCL_LIBRARY for runtest.
+
+Mon Feb 14 19:34:03 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Makefile.in: Use new config features of DejaGnu in site.exp
+ file. "Make check" should now work for all crosses.
+
+Fri Jan 28 18:00:29 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * binutils.all/objdump.exp: In usage message, accept
+ "section-name" as well as "section_name".
+
+Mon Jan 17 16:57:02 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * binutils.all/objdump.exp: Trim list of format names expected,
+ and accept any known CPU type.
+
+Thu Dec 2 20:50:24 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Makefile.in: Remove some stuff from the site.exp file.
+ * config/unix.exp: Add global before seeing if the variables for
+ nm, objdump, and size exist.
+
+Wed Nov 3 11:12:32 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/udi.exp,unix.exp: Transform tool name.
+ * binutils.all/*.exp: Clear errorInfo after exec.
+
+Fri Jul 2 12:41:20 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * binutils.all/*.exp: Use -- for long arguments rather than +.
+
+Fri Jun 4 10:52:29 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: change srctrigger to Makefile.in
+
+Wed May 26 17:27:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Pass down CC and CFLAGS.
+
+Fri May 7 13:58:44 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * binutils.all/objdump.exp: Update for new usage message.
+
+Mon Apr 19 14:08:52 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * binutils.all/*.exp: Use the new util_test proc.
+ * Makefile.in: Create a local site.exp file with config info.
+
+Thu Mar 25 05:38:47 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * nm.all/configure.in (srcname): Delete extra quote.
+
+Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * binutils/testsuite: made modifications to testcases, etc., to allow
+ them to work properly given the reorganization of deja-gnu and the
+ relocation of the testcases from deja-gnu to a "tool" subdirectory.
+
+Sun Feb 21 10:55:55 1993 Mike Werner (mtw@poseidon.cygnus.com)
+
+ * binutils/testsuite: Initial creation of binutils/testsuite.
+ Migrated dejagnu testcases and support files for testing nm to
+ binutils/testsuite from deja-gnu. These files were moved "as is"
+ with no modifications. This migration is part of a major overhaul
+ of dejagnu. The modifications to these testcases, etc., which
+ will allow them to work with the new version of dejagnu will be
+ made in a future update.
+
diff --git a/binutils/testsuite/binutils-all/ar.exp b/binutils/testsuite/binutils-all/ar.exp
new file mode 100644
index 00000000000..4b38c6b066e
--- /dev/null
+++ b/binutils/testsuite/binutils-all/ar.exp
@@ -0,0 +1,219 @@
+# Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# Written by Ian Lance Taylor <ian@cygnus.com>
+
+if ![is_remote host] {
+ if {[which $AR] == 0} then {
+ perror "$AR does not exist"
+ return
+ }
+}
+
+# send_user "Version [binutil_version $AR]"
+
+# Test long file name support
+
+proc long_filenames { } {
+ global AR
+ global host_triplet
+
+ set testname "ar long file names"
+
+ set n1 "abcdefghijklmnopqrstuvwxyz1"
+ set n2 "abcdefghijklmnopqrstuvwxyz2"
+ set file1 tmpdir/$n1
+ set file2 tmpdir/$n2
+
+ remote_file build delete $file1
+
+ # Some file systems truncate file names at 14 characters, which
+ # makes it impossible to run this test. Check for that now.
+ set status [catch "set f [open tmpdir/$n1 w]" errs]
+ if { $status != 0 } {
+ verbose -log "open tmpdir/$n1 returned $errs"
+ unsupported $testname
+ return
+ }
+ puts $f "first"
+ close $f
+
+
+ remote_file build delete $file2
+
+ set status [catch "set f [open tmpdir/$n2 w]" errs]
+ if { $status != 0 } {
+ verbose -log "open tmpdir/$n2 returned $errs"
+ unsupported $testname
+ return
+ }
+ puts $f "second"
+ close $f
+
+ if [is_remote host] {
+ set file1 [remote_download host $file1];
+ set file2 [remote_download host $file2];
+ set dest artest.a
+ } else {
+ set dest tmpdir/artest.a
+ }
+
+ remote_file host delete $dest;
+
+ set got [binutils_run $AR "rc $dest $file1 $file2"]
+ if [is_remote host] {
+ remote_upload host $file1 tmpdir/$n1
+ }
+
+ set f [open tmpdir/$n1 r]
+ gets $f string
+ close $f
+ if ![string match "first" $string] {
+ verbose -log "reading tmpdir/$n1 returned $string"
+ unsupported $testname
+ return
+ }
+
+ remote_file host delete $dest;
+ set got [binutils_run $AR "rc $dest $file1 $file2"]
+
+ if ![string match "" $got] {
+ fail $testname
+ return
+ }
+
+ remote_file build delete tmpdir/$n1
+ remote_file build delete tmpdir/$n2
+
+ set got [binutils_run $AR "t $dest"]
+ regsub "\[\r\n \t\]*$" "$got" "" got;
+ if ![string match "$n1*$n2" $got] {
+ fail $testname
+ return
+ }
+
+ if [is_remote host] {
+ remote_file host delete $file1;
+ remote_file host delete $file2;
+ }
+
+ verbose -log "$AR x $dest"
+ set exec_output [binutils_run $AR "x $dest"]
+ set exec_output [prune_warnings $exec_output]
+ if ![string match "" $exec_output] {
+ verbose -log $exec_output
+ fail $testname
+ return
+ }
+
+ if [is_remote host] {
+ remote_upload host $n1 tmpdir/$n1;
+ remote_upload host $n2 tmpdir/$n2;
+ set file1 tmpdir/$n1
+ set file2 tmpdir/$n2
+ } else {
+ set file1 $n1
+ set file2 $n2
+ }
+
+ if ![file exists $file1] {
+ verbose -log "$file1 does not exist"
+ fail $testname
+ return
+ }
+ if ![file exists $file2] {
+ verbose -log "$file2 does not exist"
+ fail $testname
+ return
+ }
+
+ set f [open $file1 r]
+ if { [gets $f line] == -1 || $line != "first" } {
+ verbose -log "$file1 contents:"
+ verbose -log "$line"
+ close $f
+ fail $testname
+ return
+ }
+ close $f
+
+ set f [open $file2 r]
+ if { [gets $f line] == -1 || $line != "second" } {
+ verbose -log "$file2 contents:"
+ verbose -log "$line"
+ close $f
+ fail $testname
+ return
+ }
+ close $f
+
+ pass $testname
+}
+
+# Test building the symbol table.
+
+proc symbol_table { } {
+ global AR
+ global AS
+ global NM
+ global srcdir
+ global subdir
+
+ set testname "ar symbol table"
+
+ if ![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o] {
+ unresolved $testname
+ return
+ }
+
+ if [is_remote host] {
+ set archive artest.a
+ set objfile [remote_download host tmpdir/bintest.o]
+ remote_file host delete $archive
+ } else {
+ set archive tmpdir/artest.a
+ set objfile tmpdir/bintest.o
+ }
+
+ remote_file build delete tmpdir/artest.a
+
+ set got [binutils_run $AR "rc $archive ${objfile}"]
+ if ![string match "" $got] {
+ fail $testname
+ return
+ }
+
+ set got [binutils_run $NM "--print-armap $archive"]
+ if { ![string match "*text_symbol in bintest.o*" $got] \
+ || ![string match "*data_symbol in bintest.o*" $got] \
+ || ![string match "*common_symbol in bintest.o*" $got] \
+ || [string match "*static_text_symbol in bintest.o*" $got] \
+ || [string match "*static_data_symbol in bintest.o*" $got] \
+ || [string match "*external_symbol in bintest.o*" $got] } {
+ fail $testname
+ return
+ }
+
+ pass $testname
+}
+
+# Run the tests.
+
+long_filenames
+symbol_table
diff --git a/binutils/testsuite/binutils-all/bintest.s b/binutils/testsuite/binutils-all/bintest.s
new file mode 100644
index 00000000000..9e006502219
--- /dev/null
+++ b/binutils/testsuite/binutils-all/bintest.s
@@ -0,0 +1,12 @@
+ .globl text_symbol
+ .text
+text_symbol:
+static_text_symbol:
+ .long 1
+ .long external_symbol
+ .globl data_symbol
+ .data
+data_symbol:
+static_data_symbol:
+ .long 2
+ .comm common_symbol,4
diff --git a/binutils/testsuite/binutils-all/hppa/addendbug.s b/binutils/testsuite/binutils-all/hppa/addendbug.s
new file mode 100644
index 00000000000..659306f0741
--- /dev/null
+++ b/binutils/testsuite/binutils-all/hppa/addendbug.s
@@ -0,0 +1,23 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT initialize_char_syntax,CODE
+ .EXPORT initialize_char_syntax,ENTRY,PRIV_LEV=3,RTNVAL=GR
+initialize_char_syntax
+ .PROC
+ .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ addil L'is_idchar-$global$-32,%r27
+ .EXIT
+ .PROCEND
+is_idchar .comm 256
diff --git a/binutils/testsuite/binutils-all/hppa/objdump.exp b/binutils/testsuite/binutils-all/hppa/objdump.exp
new file mode 100644
index 00000000000..a46b289769a
--- /dev/null
+++ b/binutils/testsuite/binutils-all/hppa/objdump.exp
@@ -0,0 +1,59 @@
+# Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye <rob@cygnus.com>
+# and rewritten by Ian Lance Taylor <ian@cygnus.com>
+
+if ![istarget hppa*-*-*] then {
+ return
+}
+
+if {[which $OBJDUMP] == 0} then {
+ perror "$OBJDUMP does not exist"
+ return
+}
+
+send_user "Version [binutil_version $OBJDUMP]"
+
+if {![binutils_assemble $srcdir/$subdir/addendbug.s tmpdir/addendbug.o]} then {
+ return
+}
+
+if [is_remote host] {
+ set objfile [remote_download host tmpdir/addendbug.o]
+} else {
+ set objfile tmpdir/addendbug.o
+}
+
+# Make sure the SOM BFD code sign extends constants in R_DATA_OVERRIDE fixups.
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -r $objfile"]
+
+if [istarget hppa*-*-*elf*] then {
+ set want "00000000 R_PARISC_DPREL21L\[ \]+is_idchar\\+0xffffffe0.*"
+} else {
+ set want "00000000 R_DP_RELATIVE\[ \]+is_idchar\\+0xffffffe0.*"
+}
+
+
+if [regexp $want $got] then {
+ pass "addendbug test"
+} else {
+ fail "addendbug test"
+}
diff --git a/binutils/testsuite/binutils-all/nm.exp b/binutils/testsuite/binutils-all/nm.exp
new file mode 100644
index 00000000000..76c7c5f38c9
--- /dev/null
+++ b/binutils/testsuite/binutils-all/nm.exp
@@ -0,0 +1,123 @@
+# Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye <rob@cygnus.com>
+# and rewritten by Ian Lance Taylor <ian@cygnus.com>
+
+if ![is_remote host] {
+ if {[which $NM] == 0} then {
+ perror "$NM does not exist"
+ return
+ }
+}
+
+send_user "Version [binutil_version $NM]"
+
+
+if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
+ return
+}
+
+if [is_remote host] {
+ set tempfile [remote_download host tmpdir/bintest.o]
+} else {
+ set tempfile tmpdir/bintest.o
+}
+
+# Test nm with no arguments.
+
+# This test does not work correctly on ECOFF targets, because ECOFF
+# stores most symbols twice, which messes up the nm output.
+setup_xfail "alpha*-*-osf*" "alpha*-*-netware*"
+setup_xfail "mips*-*-ultrix*" "mips*-*-ecoff*" "mips*-*-irix4*"
+setup_xfail "mips*-*-riscos*" "mips*-*-sysv3*" "mips*-sony-bsd*"
+
+# This test does not work correctly on XCOFF targets, because XCOFF
+# does not enter static symbols in the symbol table.
+setup_xfail "*-*-aix*"
+
+set got [binutils_run $NM "$NMFLAGS $tempfile"]
+
+if [info exists vars] then { unset vars }
+while {[regexp "(\[a-zA-Z\]) (\[a-z_\]*_symbol)(.*)" $got all type symbol rest]} {
+ set vars($symbol) $type
+ set got $rest
+}
+
+if {![info exists vars(text_symbol)] \
+ || $vars(text_symbol) != "T" \
+ || ![info exists vars(data_symbol)] \
+ || $vars(data_symbol) != "D" \
+ || ![info exists vars(common_symbol)] \
+ || $vars(common_symbol) != "C" \
+ || ![info exists vars(external_symbol)] \
+ || $vars(external_symbol) != "U" \
+ || ![info exists vars(static_text_symbol)] \
+ || $vars(static_text_symbol) != "t" \
+ || ![info exists vars(static_data_symbol)] \
+ || $vars(static_data_symbol) != "d"} {
+ fail "nm (no arguments)"
+} else {
+ pass "nm (no arguments)"
+}
+
+# Test nm -g
+
+set got [binutils_run $NM "$NMFLAGS -g $tempfile"]
+
+if [info exists vars] then { unset vars }
+while {[regexp "(\[a-z_\]*_symbol)(.*)" $got all symbol rest]} {
+ set vars($symbol) 1
+ set got $rest
+}
+
+if {![info exists vars(text_symbol)] \
+ || ![info exists vars(data_symbol)] \
+ || ![info exists vars(common_symbol)] \
+ || ![info exists vars(external_symbol)] \
+ || [info exists vars(static_text_symbol)] \
+ || [info exists vars(static_data_symbol)]} {
+ fail "nm -g"
+} else {
+ pass "nm -g"
+}
+
+# Test nm -P
+
+# This test does not work correctly on ECOFF targets, because ECOFF
+# stores most symbols twice, which messes up the nm output.
+setup_xfail "alpha*-*-osf*" "alpha*-*-netware*"
+setup_xfail "mips*-*-ultrix*" "mips*-*-ecoff*" "mips*-*-irix4*"
+setup_xfail "mips*-*-riscos*" "mips*-*-sysv3*" "mips*-sony-bsd*"
+
+# This test does not work correctly on XCOFF targets, because XCOFF
+# does not enter static symbols in the symbol table.
+setup_xfail "*-*-aix*"
+
+set got [binutils_run $NM "$NMFLAGS -P $tempfile"]
+
+set want "common_symbol C \[0\]*4.*data_symbol D \[0-9a-fA-F\]*.*external_symbol U.*static_data_symbol d \[0-9a-fA-F\]*.*static_text_symbol t \[0-9a-fA-F\]*.*text_symbol T \[0-9a-fA-F\]*"
+
+if [regexp $want $got] then {
+ pass "nm -P"
+} else {
+ fail "nm -P"
+}
+
+# There are certainly other tests that could be run.
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
new file mode 100644
index 00000000000..78972f1c0c1
--- /dev/null
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -0,0 +1,591 @@
+# Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# Written by Ian Lance Taylor <ian@cygnus.com>
+
+if ![is_remote host] {
+ if {[which $OBJCOPY] == 0} then {
+ perror "$OBJCOPY does not exist"
+ return
+ }
+}
+
+send_user "Version [binutil_version $OBJCOPY]"
+
+if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
+ perror "unresolved 1"
+ unresolved "objcopy (simple copy)"
+ return
+}
+
+if ![is_remote host] {
+ set tempfile tmpdir/bintest.o;
+ set copyfile tmpdir/copy;
+} else {
+ set tempfile [remote_download host tmpdir/bintest.o]
+ set copyfile copy
+}
+
+# Test that objcopy does not modify a file when copying it.
+
+set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS $tempfile ${copyfile}.o"]
+
+if ![string match "" $got] then {
+ fail "objcopy (simple copy)"
+} else {
+ send_log "cmp $tempfile ${copyfile}.o\n"
+ verbose "cmp $tempfile ${copyfile}.o"
+ if [is_remote host] {
+ set src1 tmpdir/bintest.o
+ set src2 tmpdir/copy.o
+ remote_upload host $tempfile $src1;
+ remote_upload host ${copyfile}.o $src2;
+ } else {
+ set src1 ${tempfile}
+ set src2 ${copyfile}.o
+ }
+ set status [remote_exec build cmp "${src1} ${src2}"];
+ set exec_output [lindex $status 1];
+ set exec_output [prune_warnings $exec_output]
+
+ # On some systems the result of objcopy will not be identical.
+ # Usually this is just because gas isn't using bfd to write the files
+ # 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 "m68*-*-hpux*" "m68*-*-sunos*" "m68*-*-coff" "m68*-*-vxworks*"
+ setup_xfail "m68*-ericsson-ose" "m68k*-motorola-sysv*"
+ setup_xfail "i*86-*-linuxaout*" "i*86-*-aout*"
+ setup_xfail "i*86-*-sysv3" "i*86-*-isc*" "i*86-*-sco*" "i*86-*-coff"
+ setup_xfail "i*86-*-aix*" "i*86-*-go32*"
+ setup_xfail "a29k-*-udi" "a29k-*-coff" "a29k-*-vxworks*"
+ setup_xfail "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" "m88*-motorola-sysv*"
+ setup_xfail "z8*-*-coff"
+
+ if [string match "" $exec_output] then {
+ pass "objcopy (simple copy)"
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output" 1
+
+ # On OSF/1, this succeeds with gas and fails with /bin/as.
+ setup_xfail "alpha*-*-osf*"
+
+ # This fails for COFF i960-vxworks targets.
+ setup_xfail "i960-*-vxworks*"
+
+ fail "objcopy (simple copy)"
+ }
+}
+
+# Test generating S records.
+
+# We make the srec filename 8.3 compatible. Note that the header string
+# matched against depends on the name of the file. Ugh.
+
+if [is_remote host] {
+ set srecfile copy.sre
+ set header_string S00B0000636F70792E737265C1
+} else {
+ set srecfile ${copyfile}.srec
+ set header_string S0130000746D706469722F636F70792E7372656397
+}
+
+set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${srecfile}"]
+
+if ![string match "" $got] then {
+ fail "objcopy -O srec"
+} else {
+ if [is_remote host] {
+ remote_upload host ${srecfile} tmpdir/copy.srec;
+ set srecfile tmpdir/copy.srec;
+ }
+ set file [open ${srecfile} r]
+
+ # The first S record is fixed by the file name we are using.
+ gets $file line
+ send_log "$line\n"
+ verbose $line
+ if ![regexp "$header_string.*" $line] {
+ send_log "bad header\n"
+ fail "objcopy -O srec"
+ } else {
+ while {[gets $file line] != -1 \
+ && [regexp "^S\[123\]\[0-9a-fA-F\]+\[\r\n\]*$" $line]} {
+ send_log "$line\n"
+ verbose $line
+ set line "**EOF**"
+ }
+ send_log "$line\n"
+ verbose $line
+ if ![regexp "^S\[789\]\[0-9a-fA-F\]+\[\r\n\]*$" $line] then {
+ send_log "bad trailer\n"
+ fail "objcopy -O srec"
+ } else {
+ if {[gets $file line] != -1} then {
+ send_log "garbage at end\n"
+ send_log "$line\n"
+ verbose $line
+ fail "objcopy -O srec"
+ } else {
+ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"]
+ if ![regexp "file format srec" $got] then {
+ send_log "objdump failed\n"
+ fail "objcopy -O srec"
+ } else {
+ pass "objcopy -O srec"
+ }
+ }
+ }
+ }
+
+ close $file
+}
+
+# Test setting and adjusting the start address. We only test this
+# while generating S records, because we may not be able to set the
+# start address for other object file formats, and the S record case
+# is the only useful one anyhow.
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $tempfile"]
+if ![regexp "start address (\[0-9a-fA-FxX\]+)" $got all origstart] then {
+ perror "objdump can not recognize bintest.o"
+ set origstart ""
+} else {
+ set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${copyfile}.srec --set-start 0x7654"]
+ if ![string match "" $got] then {
+ fail "objcopy --set-start"
+ } else {
+ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"]
+ if ![regexp "file format srec.*start address (\[0-9a-fA-FxX\]+)" $got all srecstart] then {
+ fail "objcopy --set-start"
+ } else {
+ if {$srecstart != 0x7654} then {
+ send_log "$srecstart != 0x7654\n"
+ fail "objcopy --set-start"
+ } else {
+ pass "objcopy --set-start"
+ }
+ }
+ }
+
+ set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${copyfile}.srec --adjust-start 0x123"]
+ if ![string match "" $got] then {
+ fail "objcopy --adjust-start"
+ } else {
+ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"]
+ if ![regexp "file format srec.*start address (\[0-9a-fA-FxX\]+)" $got all srecstart] then {
+ fail "objcopy --adjust-start"
+ } else {
+ if {$srecstart != $origstart + 0x123} then {
+ send_log "$srecstart != $origstart + 0x123\n"
+ fail "objcopy --adjust-start"
+ } else {
+ pass "objcopy --adjust-start"
+ }
+ }
+ }
+}
+
+# Test adjusting the overall VMA, and adjusting the VMA of a
+# particular section. We again only test this when generating S
+# records.
+
+set low ""
+set lowname ""
+
+set headers [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $tempfile"]
+
+set headers_regexp "\[ 0-9\]+(\[^ \]+)\[ \]*(\[0-9a-fA-F\]+)\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)\[ \]+\[0-9a-fA-F\]+\[ \]+2\[*\]\[*\]\[0-9\]+(.*)"
+
+set got $headers
+while {[regexp $headers_regexp $got all name size vma rest]} {
+ set vma 0x$vma
+ set size 0x$size
+ if {$size != 0} {
+ if {$low == "" || $vma < $low} {
+ set low $vma
+ set lowname $name
+ }
+ }
+ set got $rest
+}
+
+if {$low == "" || $origstart == ""} then {
+ perror "objdump can not recognize bintest.o"
+} else {
+ set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${copyfile}.srec --adjust-vma 0x123"]
+ if ![string match "" $got] then {
+ fail "objcopy --adjust-vma"
+ } else {
+ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -fh ${copyfile}.srec"]
+ set want "file format srec.*start address\[ \]*(\[0-9a-fA-FxX\]+).*sec1\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)"
+ if ![regexp $want $got all start vma] then {
+ fail "objcopy --adjust-vma"
+ } else {
+ set vma 0x$vma
+ if {$vma != $low + 0x123} then {
+ send_log "$vma != $low + 0x123\n"
+ fail "objcopy --adjust-vma"
+ } else {
+ if {$start != $origstart + 0x123} then {
+ send_log "$start != $origstart + 0x123\n"
+ fail "objcopy --adjust-vma"
+ } else {
+ pass "objcopy --adjust-vma"
+ }
+ }
+ }
+ }
+
+ set arg ""
+ set got $headers
+ while {[regexp $headers_regexp $got all name size vma rest]} {
+ set vma 0x$vma
+ if {$vma == $low} then {
+ set arg "$arg --adjust-section-vma $name+4"
+ }
+ set got $rest
+ }
+
+ set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${copyfile}.srec $arg"]
+ if ![string match "" $got] then {
+ fail "objcopy --adjust-section-vma +"
+ } else {
+ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h ${copyfile}.srec"]
+ set want "file format srec.*sec1\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)"
+ if ![regexp $want $got all vma] then {
+ fail "objcopy --adjust-section-vma +"
+ } else {
+ set vma 0x$vma
+ if {$vma != $low + 4} then {
+ send_log "$vma != $low + 4\n"
+ fail "objcopy --adjust-section-vma +"
+ } else {
+ pass "objcopy --adjust-section-vma +"
+ }
+ }
+ }
+
+ regsub -all "\\+4" $arg "=[expr $low + 4]" argeq
+ set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${copyfile}.srec $argeq"]
+ if ![string match "" $got] then {
+ fail "objcopy --adjust-section-vma ="
+ } else {
+ set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h ${copyfile}.srec"]
+ set want "file format srec.*sec1\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)"
+ if ![regexp $want $got all vma] then {
+ fail "objcopy --adjust-section-vma ="
+ } else {
+ set vma 0x$vma
+ if {$vma != $low + 4} then {
+ send_log "$vma != $low + 4\n"
+ fail "objcopy --adjust-section-vma ="
+ } else {
+ pass "objcopy --adjust-section-vma ="
+ }
+ }
+ }
+}
+
+# Test stripping an object.
+
+proc strip_test { } {
+ global CC
+ global STRIP
+ global STRIPFLAGS
+ global NM
+ global NMFLAGS
+ global srcdir
+ global subdir
+
+ set test "strip"
+
+ if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
+ untested $test
+ return
+ }
+
+ if [is_remote host] {
+ set objfile [remote_download host tmpdir/testprog.o];
+ } else {
+ set objfile tmpdir/testprog.o
+ }
+
+ set exec_output [binutils_run $STRIP "$STRIPFLAGS $objfile"]
+ if ![string match "" $exec_output] {
+ fail $test
+ return
+ }
+
+ set exec_output [binutils_run $NM "-a $NMFLAGS $objfile"]
+ if ![string match "*: no symbols*" $exec_output] {
+ fail $test
+ return
+ }
+
+ pass $test
+}
+
+strip_test
+
+# Test stripping an object file with saving a symbol
+
+proc strip_test_with_saving_a_symbol { } {
+ global CC
+ global STRIP
+ global STRIPFLAGS
+ global NM
+ global NMFLAGS
+ global srcdir
+ global subdir
+
+ set test "strip with saving a symbol"
+
+ if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
+ untested $test
+ return
+ }
+
+ if [is_remote host] {
+ set objfile [remote_download host tmpdir/testprog.o];
+ } else {
+ set objfile tmpdir/testprog.o
+ }
+
+ set exec_output [binutils_run $STRIP "$STRIPFLAGS -K main -K _main $objfile"]
+ if ![string match "" $exec_output] {
+ fail $test
+ return
+ }
+
+ set exec_output [binutils_run $NM "$NMFLAGS $objfile"]
+ if {![regexp {^([0-9a-fA-F]+)?[ ]+T main} $exec_output] \
+ && ![regexp {^([0-9a-fA-F]+)?[ ]+T _main} $exec_output]} {
+ fail $test
+ return
+ }
+
+ pass $test
+}
+
+strip_test_with_saving_a_symbol
+
+# Build a final executable.
+
+proc copy_setup { } {
+ global srcdir
+ global subdir
+
+ set res [build_wrapper testglue.o];
+ set flags { debug };
+
+ if { $res != "" } {
+ lappend flags "additional_flags=[lindex $res 1]";
+ set add_libs "testglue.o";
+ } else {
+ set add_libs "";
+ }
+
+ if { [target_compile "$srcdir/$subdir/testprog.c $add_libs" tmpdir/testprog executable $flags] != "" } {
+ return 2
+ }
+
+ set result [remote_load target tmpdir/testprog];
+ set status [lindex $result 0];
+
+ if { $status != "pass" } {
+ perror "unresolved setup, status = $status"
+ return 3
+ }
+
+ return 0
+}
+
+# Test copying an executable.
+
+proc copy_executable { prog flags test1 test2 } {
+
+ if [is_remote host] {
+ set testfile [remote_download host tmpdir/testprog];
+ set testcopy copyprog
+ } else {
+ set testfile tmpdir/testprog
+ set testcopy tmpdir/copyprog
+ }
+ remote_file host delete $testcopy;
+
+ set exec_output [binutils_run $prog "$flags $testfile $testcopy"]
+
+ if ![string match "" $exec_output] {
+ fail $test1
+ fail $test2
+ return
+ }
+
+ if [is_remote host] {
+ remote_upload host $testcopy tmpdir/copyprog
+ }
+
+ set status [remote_exec build "cmp" "tmpdir/testprog tmpdir/copyprog"]
+ set exec_output [lindex $status 1];
+
+ if [string match "" $exec_output] then {
+ pass $test1
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+
+ # This will fail for many reasons. For example, it will most
+ # likely fail if a non-GNU linker is used. Therefore, we do
+ # not insist that it pass. If you are using an assembler and
+ # linker based on the same BFD as objcopy, it is worth
+ # investigating to see why this failure occurs. If we are
+ # cross compiling, we assume that a GNU linker is being used,
+ # and expect it to succeed.
+ if {[isnative]} then {
+ setup_xfail "*-*-*"
+ }
+
+ # This also fails for mips*-*-elf targets. See elf32-mips.c
+ # mips_elf_sym_is_global.
+ setup_xfail "mips*-*-elf"
+
+ fail $test1
+ }
+
+ set output [remote_load target tmpdir/copyprog]
+ set status [lindex $output 0];
+ if { $status != "pass" } {
+ fail $test2
+ } else {
+ pass $test2
+ }
+}
+
+# Test stripping an executable
+
+proc strip_executable { prog flags test } {
+ global NM
+ global NMFLAGS
+
+ remote_download build tmpdir/copyprog tmpdir/striprog
+ if [is_remote host] {
+ set copyfile [remote_download host tmpdir/striprog];
+ } else {
+ set copyfile tmpdir/striprog
+ }
+
+ set exec_output [binutils_run $prog "$flags ${copyfile}"]
+ if ![string match "" $exec_output] {
+ fail $test
+ return
+ }
+
+ if [is_remote host] {
+ remote_upload host ${copyfile} tmpdir/striprog;
+ }
+
+ set result [remote_load target tmpdir/striprog]
+ set status [lindex $result 0];
+ if { $status != "pass" } {
+ fail $test
+ return
+ }
+
+ set exec_output [binutils_run $NM "$NMFLAGS ${copyfile}"]
+ if ![string match "*: no symbols*" $exec_output] {
+ fail $test
+ return
+ }
+ pass $test
+}
+
+# Test stripping an executable with saving a symbol
+
+proc strip_executable_with_saving_a_symbol { prog flags test } {
+ global NM
+ global NMFLAGS
+
+ remote_download build tmpdir/copyprog tmpdir/striprog
+ if [is_remote host] {
+ set copyfile [remote_download host tmpdir/striprog];
+ } else {
+ set copyfile tmpdir/striprog
+ }
+
+ set exec_output [binutils_run $prog "$flags ${copyfile}"]
+ if ![string match "" $exec_output] {
+ fail $test
+ return
+ }
+
+ if [is_remote host] {
+ remote_upload host ${copyfile} tmpdir/striprog;
+ }
+
+ set result [remote_load target tmpdir/striprog]
+ set status [lindex $result 0];
+ if { $status != "pass" } {
+ fail $test
+ return
+ }
+
+ set exec_output [binutils_run $NM "$NMFLAGS ${copyfile}"]
+ if {![regexp {^[0-9a-fA-F]+ T main} $exec_output] \
+ && ![regexp {^[0-9a-fA-F]+ T _main} $exec_output]} {
+ fail $test
+ return
+ }
+ pass $test
+}
+
+set test1 "simple objcopy of executable"
+set test2 "run objcopy of executable"
+set test3 "run stripped executable"
+set test4 "run stripped executable with saving a symbol"
+
+switch [copy_setup] {
+ "1" {
+ # do nothing
+ }
+ "2" {
+ untested $test1
+ untested $test2
+ untested $test3
+ untested $test4
+ }
+ "3" {
+ unresolved $test1
+ unresolved $test2
+ unresolved $test3
+ unresolved $test4
+ }
+ "0" {
+ copy_executable "$OBJCOPY" "$OBJCOPYFLAGS" "$test1" "$test2"
+ strip_executable "$STRIP" "$STRIPFLAGS" "$test3"
+ strip_executable_with_saving_a_symbol "$STRIP" "-K main -K _main $STRIPFLAGS" "$test4"
+ }
+}
diff --git a/binutils/testsuite/binutils-all/objdump.exp b/binutils/testsuite/binutils-all/objdump.exp
new file mode 100644
index 00000000000..7c50f02fb6d
--- /dev/null
+++ b/binutils/testsuite/binutils-all/objdump.exp
@@ -0,0 +1,140 @@
+# Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye <rob@cygnus.com>
+# and rewritten by Ian Lance Taylor <ian@cygnus.com>
+
+if ![is_remote host] {
+ if {[which $OBJDUMP] == 0} then {
+ perror "$OBJDUMP does not exist"
+ return
+ }
+}
+
+send_user "Version [binutil_version $OBJDUMP]"
+
+# Simple test of objdump -i
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -i"]
+
+set cpus_expected "(a29k|alliant|alpha|arc|arm|convex|d10v|d30v|h8|hppa|i386|i860|i960|m32r|m68k|m88k|mips|mn10200|mn10300|ns32k|powerpc|pyramid|romp|rs6000|sh|sparc|tahoe|v850|vax|we32k|z8k|z8001|z8002)"
+
+# Make sure the target CPU shows up in the list.
+if ![regexp $cpus_expected $target_cpu] {
+ regsub "^\[(\]" "$cpus_expected" "(${target_cpu}|" cpus_expected;
+}
+
+set want "BFD header file version.*srec.*header .* endian.*, data .* endian.*$cpus_expected"
+
+if [regexp $want $got] then {
+ pass "objdump -i"
+} else {
+ fail "objdump -i"
+}
+
+# The remaining tests require a test file.
+
+
+if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
+ return
+}
+if [is_remote host] {
+ set testfile [remote_download host tmpdir/bintest.o]
+} else {
+ set testfile tmpdir/bintest.o
+}
+
+# Test objdump -f
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $testfile"]
+
+set want "$testfile:\[ \]*file format.*architecture:\[ \]*${cpus_expected}.*HAS_RELOC.*HAS_SYMS"
+
+if ![regexp $want $got] then {
+ fail "objdump -f"
+} else {
+ pass "objdump -f"
+}
+
+# Test objdump -h
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $testfile"]
+
+set want "$testfile:\[ \]*file format.*Sections.*\[0-9\]+\[ \]+\[^ \]*(text|TEXT|\\\$CODE\\\$)\[^ \]*\[ \]*(\[0-9a-fA-F\]+).*\[0-9\]+\[ \]+\[^ \]*(\\.data|DATA)\[^ \]*\[ \]*(\[0-9a-fA-F\]+)"
+
+if ![regexp $want $got all text_name text_size data_name data_size] then {
+ fail "objdump -h"
+} else {
+ verbose "text name is $text_name size is $text_size"
+ verbose "data name is $data_name size is $data_size"
+ if {[expr "0x$text_size"] < 8 || [expr "0x$data_size"] < 4} then {
+ send_log "sizes too small\n"
+ fail "objdump -h"
+ } else {
+ pass "objdump -h"
+ }
+}
+
+# Test objdump -t
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -t $testfile"]
+
+if [info exists vars] then { unset vars }
+while {[regexp "(\[a-z\]*_symbol)(.*)" $got all symbol rest]} {
+ set vars($symbol) 1
+ set got $rest
+}
+
+if {![info exists vars(text_symbol)] \
+ || ![info exists vars(data_symbol)] \
+ || ![info exists vars(common_symbol)] \
+ || ![info exists vars(external_symbol)]} then {
+ fail "objdump -t"
+} else {
+ pass "objdump -t"
+}
+
+# Test objdump -r
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -r $testfile"]
+
+set want "$testfile:\[ \]*file format.*RELOCATION RECORDS FOR \\\[\[^\]\]*(text|TEXT|\\\$CODE\\\$)\[^\]\]*\\\].*external_symbol"
+
+if [regexp $want $got] then {
+ pass "objdump -r"
+} else {
+ fail "objdump -r"
+}
+
+# Test objdump -s
+
+set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s $testfile"]
+
+set want "$testfile:\[ \]*file format.*Contents.*(text|TEXT|\\\$CODE\\\$)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000001|01000000).*Contents.*(data|DATA)\[^0-9\]*\[ \]*\[0-9a-fA-F\]*\[ \]*(00000002|02000000)"
+
+if [regexp $want $got] then {
+ pass "objdump -s"
+} else {
+ fail "objdump -s"
+}
+
+# Options which are not tested: -a -d -D -R -T -x -l --stabs
+# I don't see any generic way to test any of these other than -a.
+# Tests could be written for specific targets, and that should be done
+# if specific problems are found.
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
new file mode 100644
index 00000000000..b2f744c7e15
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -0,0 +1,217 @@
+# Copyright (C) 1999 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# Written by Nick Clifto <nickc@cygnus.com>
+# Based on scripts written by Ian Lance Taylor <ian@cygnus.com>
+# and Ken Raeburn <raeburn@cygnus.com>.
+
+# First some helpful procedures, then the tests themselves
+
+# Return the contents of the filename given
+proc file_contents { filename } {
+ set file [open $filename r]
+ set contents [read $file]
+ close $file
+ return $contents
+}
+
+# regexp_diff, based on simple_diff taken from ld test suite
+# compares two files line-by-line
+# file1 contains strings, file2 contains regexps and #-comments
+# blank lines are ignored in either file
+# returns non-zero if differences exist
+#
+proc regexp_diff { file_1 file_2 } {
+
+ set eof -1
+ set end_1 0
+ set end_2 0
+ set differences 0
+ set diff_pass 0
+
+ if [file exists $file_1] then {
+ set file_a [open $file_1 r]
+ } else {
+ warning "$file_1 doesn't exist"
+ return 1
+ }
+
+ if [file exists $file_2] then {
+ set file_b [open $file_2 r]
+ } else {
+ fail "$file_2 doesn't exist"
+ close $file_a
+ return 1
+ }
+
+ verbose " Regexp-diff'ing: $file_1 $file_2" 2
+
+ while { 1 } {
+ set line_a ""
+ set line_b ""
+ while { [string length $line_a] == 0 } {
+ if { [gets $file_a line_a] == $eof } {
+ set end_1 1
+ break
+ }
+ }
+ while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
+ if [ string match "#pass" $line_b ] {
+ set end_2 1
+ set diff_pass 1
+ break
+ }
+ if { [gets $file_b line_b] == $eof } {
+ set end_2 1
+ break
+ }
+ }
+
+ if { $diff_pass } {
+ break
+ } elseif { $end_1 && $end_2 } {
+ break
+ } elseif { $end_1 } {
+ send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
+ verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
+ set differences 1
+ break
+ } elseif { $end_2 } {
+ send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
+ verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
+ set differences 1
+ break
+ } else {
+ verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
+ if ![regexp "^$line_b$" "$line_a"] {
+ send_log "regexp_diff match failure\n"
+ send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
+ set differences 1
+ break
+ }
+ }
+ }
+
+ if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
+ send_log "$file_1 and $file_2 are different lengths\n"
+ verbose "$file_1 and $file_2 are different lengths" 3
+ set differences 1
+ }
+
+ close $file_a
+ close $file_b
+
+ return $differences
+}
+
+# Run an individual readelf test.
+# Basically readelf is run on the binary_file with the given options.
+# Readelf's output is captured and then compared against the contents
+# of the regexp_file.
+
+proc readelf_test { options binary_file regexp_file xfails } {
+
+ global READELF
+ global READELFFLAGS
+ global srcdir
+ global subdir
+
+ send_log "exec $READELF $READELFFLAGS $options $binary_file > readelf.out"
+ catch "exec $READELF $READELFFLAGS $options $binary_file > readelf.out" got
+
+ if { [llength $xfails] != 0 } then {
+ setup_xfail $xfails
+ }
+
+ if ![string match "" $got] then {
+ send_log $got
+ fail "readelf $options"
+ return
+ }
+
+ if { [regexp_diff readelf.out $srcdir/$subdir/$regexp_file] } then {
+ fail "readelf $options"
+ verbose "output is \n[file_contents readelf.out]" 2
+ return
+ }
+
+ pass "readelf $options"
+}
+
+
+
+# Only ELF based toolchains need readelf.
+# For now be paranoid and assume that if ELF is not mentioned
+# in the target string, then the target is not an ELF based port.
+
+if ![istarget "*-*elf"] then {
+ verbose "$READELF is only intenteded for ELF targets" 2
+ return
+}
+
+if ![is_remote host] {
+ if {[which $READELF] == 0} then {
+ perror "$READELF does not exist"
+ return
+ }
+}
+
+send_user "Version [binutil_version $READELF]"
+
+# Assemle the test file.
+if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
+ perror "unresolved 1"
+ unresolved "readelf - failed to assemble"
+ return
+}
+
+if ![is_remote host] {
+ set tempfile tmpdir/bintest.o;
+} else {
+ set tempfile [remote_download host tmpdir/bintest.o]
+}
+
+# Run the tests
+readelf_test -h $tempfile readelf.h {}
+
+# The v850 fails the next two tests because it creates two special
+# sections of its own: .call_table_data and .call_table_text
+# The regexp scripts are not expecting these sections...
+
+readelf_test -S $tempfile readelf.s {v850*-*-*}
+readelf_test -s $tempfile readelf.ss {v850*-*-*}
+readelf_test -r $tempfile readelf.r {}
+
+
+# Compile the second test file.
+if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
+ untested "readelf -w"
+ return
+}
+
+if [is_remote host] {
+ set tempfile [remote_download host tmpdir/testprog.o];
+} else {
+ set tempfile tmpdir/testprog.o
+}
+
+# The xfail targets here do not default to DWARF2 format debug information
+# The symptom is that the output of 'readelf -wi' is empty.
+
+readelf_test -wi $tempfile readelf.wi {v850*-*-*}
diff --git a/binutils/testsuite/binutils-all/readelf.h b/binutils/testsuite/binutils-all/readelf.h
new file mode 100644
index 00000000000..555afe9a7a2
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.h
@@ -0,0 +1,16 @@
+ELF Header:
+ Magic: 7f 45 4c 46 0[12] 0[12] 01 00 00 00 00 00 00 00 00 00
+ Type: REL \(Relocatable file\)
+ Machine: .*
+ Version: 0x1
+ Data: ELFDATA.* endian\)
+ Entry point address: 0x0
+ Start of program headers: 0 \(bytes into file\)
+ Start of section headers: .* \(bytes into file\)
+ Flags: .*
+ Size of this header: .* \(bytes\)
+ Size of program headers: 0 \(bytes\)
+ Number of program headers: 0
+ Size of section headers: .* \(bytes\)
+ Number of section headers: .*
+ Section header string table index: .*
diff --git a/binutils/testsuite/binutils-all/readelf.r b/binutils/testsuite/binutils-all/readelf.r
new file mode 100644
index 00000000000..4bea721451a
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.r
@@ -0,0 +1,4 @@
+
+Relocation section '.rel.*text' at offset 0x.* contains 1 entries:
+ Offset Info Type Symbol's Value Symbol's Name.*
+ 00000004 00.* R_.* 00000000 external_symbol.*
diff --git a/binutils/testsuite/binutils-all/readelf.s b/binutils/testsuite/binutils-all/readelf.s
new file mode 100644
index 00000000000..58b1245e9a3
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.s
@@ -0,0 +1,13 @@
+There are .* section headers, starting at offset .*:
+
+Section Headers:
+ \[Nr\] Name Type Addr Off Size ES Flg Lk Inf Al
+ \[ 0\] NULL 00000000 000000 000000 00 0 0 0
+ \[ 1\] .text PROGBITS 00000000 000034 000008 00 AX 0 0 .
+ \[ 2\] .rel.+text +REL. +0+ 0+.* 00000. 0. . 1 4
+ \[ 3\] .data PROGBITS 00000000 00003c 000004 00 WA 0 0 .
+ \[ 4\] .bss NOBITS 00000000 000040 000000 00 WA 0 0 .
+ \[ 5\] .shstrtab STRTAB 00000000 000040 0000.* 00 0 0 .
+ \[ 6\] .symtab SYMTAB 00000000 0+.* 0+.* 10 7 6 4
+ \[ 7\] .strtab STRTAB 00000000 0+.* 0+.* 00 0 0 1
+
diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
new file mode 100644
index 00000000000..3760b38427d
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.ss
@@ -0,0 +1,13 @@
+
+Symbol table '.symtab' contains .* entries:
+ Num: Value Size Type Bind Ot Ndx Name
+ 0: 0 0 NOTYPE LOCAL 0 UND
+ 1: 0 0 SECTION LOCAL 0 1
+ 2: 0 0 SECTION LOCAL 0 3
+ 3: 0 0 SECTION LOCAL 0 4
+ 4: 0 0 NOTYPE LOCAL 0 1 static_text_symbol
+ 5: 0 0 NOTYPE LOCAL 0 3 static_data_symbol
+ .: 0 0 NOTYPE GLOBAL 0 1 text_symbol
+ .: 0 0 NOTYPE GLOBAL 0 UND external_symbol
+ .*: 0 0 NOTYPE GLOBAL 0 3 data_symbol
+ .*: 4 4 OBJECT GLOBAL 0 COM common_symbol
diff --git a/binutils/testsuite/binutils-all/readelf.wi b/binutils/testsuite/binutils-all/readelf.wi
new file mode 100644
index 00000000000..3cb2eccf019
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.wi
@@ -0,0 +1,78 @@
+The section .debug_info contains:
+
+ Compilation Unit:
+ Length: .*
+ Version: 2
+ Abbrev Offset: 0
+ Pointer Size: 4
+ Abbrev Number: 1 \(DW_TAG_compile_unit\)
+ DW_AT_name : .*/testprog.c
+ DW_AT_comp_dir : .*/binutils
+ DW_AT_producer : GNU C .*
+ DW_AT_language : 1 \(ANSI C\)
+ DW_AT_low_pc : 0
+ DW_AT_high_pc : .*
+ DW_AT_stmt_list : 0
+ Abbrev Number: 2 \(DW_TAG_subprogram\)
+ DW_AT_external : 1
+ DW_AT_name : fn
+ DW_AT_decl_file : 1
+ DW_AT_decl_line : a
+ DW_AT_type : .*
+ DW_AT_low_pc : 0
+ DW_AT_high_pc : .*
+ DW_AT_frame_base : 1 byte block: .*
+ Abbrev Number: 3 \(DW_TAG_base_type\)
+ DW_AT_name : int
+ DW_AT_byte_size : 4
+ DW_AT_encoding : 5 \(signed\)
+ Abbrev Number: 4 \(DW_TAG_subprogram\)
+ DW_AT_sibling : .*
+ DW_AT_external : 1
+ DW_AT_name : main
+ DW_AT_decl_file : 1
+ DW_AT_decl_line : 10
+ DW_AT_type : .*
+ DW_AT_low_pc : .*
+ DW_AT_high_pc : .*
+ DW_AT_frame_base : 1 byte block: .*
+ Abbrev Number: 5 \(DW_TAG_lexical_block\)
+ DW_AT_low_pc : .*
+ DW_AT_high_pc : .*
+
+ Extra data at end of comp unit:
+ .*: Abbrev Number: 6 \(DW_TAG_variable\)
+ DW_AT_name : common
+ DW_AT_decl_file : 1
+ DW_AT_decl_line : 3
+ DW_AT_type : .*
+ DW_AT_external : 1
+ DW_AT_location : 5 byte block: 3 . 0 0 0 \(DW_OP_addr: 0\)
+ .*: Abbrev Number: 6 \(DW_TAG_variable\)
+ DW_AT_name : global
+ DW_AT_decl_file : 1
+ DW_AT_decl_line : 4
+ DW_AT_type : .*
+ DW_AT_external : 1
+ DW_AT_location : 5 byte block: 3 . 0 0 0 \(DW_OP_addr: 0\)
+ .*: Abbrev Number: 7 \(DW_TAG_variable\)
+ DW_AT_name : local
+ DW_AT_decl_file : 1
+ DW_AT_decl_line : 5
+ DW_AT_type : .*
+ DW_AT_location : 5 byte block: 3 . 0 0 . \(DW_OP_addr: .\)
+ .*: Abbrev Number: 8 \(DW_TAG_array_type\)
+ DW_AT_sibling : .*
+ DW_AT_type : .*
+ .*: Abbrev Number: 9 \(DW_TAG_subrange_type\)
+ DW_AT_upper_bound : 6
+ .*: Abbrev Number: 3 \(DW_TAG_base_type\)
+ DW_AT_name : char
+ DW_AT_byte_size : 1
+ DW_AT_encoding : . \(.* char\)
+ .*: Abbrev Number: 7 \(DW_TAG_variable\)
+ DW_AT_name : string
+ DW_AT_decl_file : 1
+ DW_AT_decl_line : 6
+ DW_AT_type : .*
+ DW_AT_location : 5 byte block: 3 . 0 0 . \(DW_OP_addr: .\)
diff --git a/binutils/testsuite/binutils-all/size.exp b/binutils/testsuite/binutils-all/size.exp
new file mode 100644
index 00000000000..b908c9198bf
--- /dev/null
+++ b/binutils/testsuite/binutils-all/size.exp
@@ -0,0 +1,78 @@
+# Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye <rob@cygnus.com>
+# and rewritten by Ian Lance Taylor <ian@cygnus.com>
+
+if ![is_remote host] {
+ if {[which $SIZE] == 0} then {
+ perror "$SIZE does not exist"
+ return
+ }
+}
+
+send_user "Version [binutil_version $SIZE]"
+
+
+if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
+ return
+}
+
+if [is_remote host] {
+ set testfile [remote_download host tmpdir/bintest.o]
+} else {
+ set testfile tmpdir/bintest.o
+}
+
+set dec "\[0-9\]+"
+set hex "\[0-9a-fA-F\]+"
+
+# Test size with no arguments
+
+set got [binutils_run $SIZE "$SIZEFLAGS $testfile"]
+
+set want "($dec)\[ \]+($dec)\[ \]+($dec)\[ \]+($dec)\[ \]+($hex)\[ \]+${testfile}"
+
+if ![regexp $want $got all text data bss dtot hextot] then {
+ fail "size (no arguments)"
+} else {
+ if {$text < 8 || $data < 4} then {
+ fail "size (no arguments)"
+ } else {
+ pass "size (no arguments)"
+ }
+}
+
+# Test size -A
+
+set got [binutils_run $SIZE "$SIZEFLAGS -A ${testfile}"]
+
+set want "${testfile}.*(text|TEXT)\[^\n\r\]*\[ \]($dec)\[ \]+$dec.*(\\.data|DATA)\[^\n\r\]*\[ \]($dec)\[ \]+$dec"
+
+if ![regexp $want $got all textname textsize dataname datasize] then {
+ fail "size -A"
+} else {
+ verbose "text size: $textsize"
+ verbose "data size: $datasize"
+ if {$textsize < 8 || $datasize < 4} then {
+ fail "size -A"
+ } else {
+ pass "size -A"
+ }
+}
diff --git a/binutils/testsuite/binutils-all/testprog.c b/binutils/testsuite/binutils-all/testprog.c
new file mode 100644
index 00000000000..210656b4487
--- /dev/null
+++ b/binutils/testsuite/binutils-all/testprog.c
@@ -0,0 +1,28 @@
+/* This program is used to test objcopy and strip. */
+
+int common;
+int global = 1;
+static int local = 2;
+static char string[] = "string";
+
+int
+fn ()
+{
+ return 3;
+}
+
+int
+main ()
+{
+ if (common != 0
+ || global != 1
+ || local != 2
+ || strcmp (string, "string") != 0)
+ {
+ printf ("failed\n");
+ exit (1);
+ }
+
+ printf ("ok\n");
+ exit (0);
+}
diff --git a/binutils/testsuite/config/default.exp b/binutils/testsuite/config/default.exp
new file mode 100644
index 00000000000..2a2802e3a14
--- /dev/null
+++ b/binutils/testsuite/config/default.exp
@@ -0,0 +1,88 @@
+# Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+load_lib util-defs.exp
+load_lib utils-lib.exp
+
+if ![info exists NM] then {
+ set NM [findfile $base_dir/nm-new $base_dir/nm-new [transform nm]]
+}
+if ![info exists NMFLAGS] then {
+ set NMFLAGS ""
+}
+
+if ![info exists SIZE] then {
+ set SIZE [findfile $base_dir/size]
+}
+if ![info exists SIZEFLAGS] then {
+ set SIZEFLAGS ""
+}
+
+if ![info exists OBJDUMP] then {
+ set OBJDUMP [findfile $base_dir/objdump]
+}
+if ![info exists OBJDUMPFLAGS] then {
+ set OBJDUMPFLAGS ""
+}
+
+if ![info exists OBJCOPY] then {
+ set OBJCOPY [findfile $base_dir/objcopy]
+}
+if ![info exists OBJCOPYFLAGS] then {
+ set OBJCOPYFLAGS ""
+}
+
+if ![info exists AR] then {
+ set AR [findfile $base_dir/ar]
+}
+
+if ![info exists STRIP] then {
+ set STRIP [findfile $base_dir/strip-new $base_dir/strip-new [transform strip]]
+}
+if ![info exists STRIPFLAGS] then {
+ set STRIPFLAGS ""
+}
+
+if ![info exists READELF] then {
+ set READELF [findfile $base_dir/readelf]
+}
+if ![info exists READELFFLAGS] then {
+ set READELFFLAGS ""
+}
+
+if ![file isdirectory tmpdir] {catch "exec mkdir tmpdir" status}
+
+#
+# binutils_run
+# run a program, returning the output
+# sets binutils_run_failed if the program does not exist
+#
+proc binutils_run { prog progargs } {
+ default_binutils_run $prog $progargs
+}
+
+#
+# binutils_assemble
+# assemble a file
+#
+proc binutils_assemble { source object } {
+ default_binutils_assemble $source $object
+}
diff --git a/binutils/testsuite/config/hppa.sed b/binutils/testsuite/config/hppa.sed
new file mode 100644
index 00000000000..d8607d85d0c
--- /dev/null
+++ b/binutils/testsuite/config/hppa.sed
@@ -0,0 +1,4 @@
+s/# Old OSF sed blows up if you have a sed command starting with "#"//
+s/# Avoid it by putting the comments within real sed commands.//
+s/# Fix the definition of common_symbol to be correct for the PA assebmlers.//
+s/ \.comm common_symbol,4/common_symbol .comm 4/
diff --git a/binutils/testsuite/lib/utils-lib.exp b/binutils/testsuite/lib/utils-lib.exp
new file mode 100644
index 00000000000..e27f21710c9
--- /dev/null
+++ b/binutils/testsuite/lib/utils-lib.exp
@@ -0,0 +1,161 @@
+# Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-dejagnu@prep.ai.mit.edu
+
+# This file was written by Rob Savoye <rob@cygnus.com>
+# and extended by Ian Lance Taylor <ian@cygnus.com>
+
+proc binutil_version { prog } {
+ if ![is_remote host] {
+ set path [which $prog];
+ if {$path == 0} then {
+ perror "$prog can't be run, file not found."
+ return ""
+ }
+ } else {
+ set path $prog
+ }
+ set state [remote_exec host $prog --version];
+ set tmp "[lindex $state 1]\n";
+ # Should find a way to discard constant parts, keep whatever's
+ # left, so the version string could be almost anything at all...
+ regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" "$tmp" version cyg number
+ if ![info exists number] then {
+ return "$path (no version number)\n"
+ }
+ return "$path $number\n"
+}
+
+#
+# default_binutils_run
+# run a program, returning the output
+# sets binutils_run_failed if the program does not exist
+#
+proc default_binutils_run { prog progargs } {
+ global binutils_run_failed
+ global host_triplet
+
+ set binutils_run_failed 0
+
+ if ![is_remote host] {
+ if {[which $prog] == 0} then {
+ perror "$prog does not exist"
+ set binutils_run_failed 1
+ return ""
+ }
+ }
+
+ send_log "$prog $progargs\n"
+ verbose "$prog $progargs"
+
+ # Gotta quote dollar-signs because they get mangled by the
+ # shell otherwise.
+ regsub -all "\\$" "$progargs" "\\$" progargs
+
+ set state [remote_exec host $prog $progargs]
+ set exec_output [prune_warnings [lindex $state 1]];
+ if {![string match "" $exec_output]} then {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ }
+ return $exec_output
+}
+
+#
+# default_binutils_assemble
+# assemble a file
+#
+proc default_binutils_assemble { source object } {
+ global srcdir
+ global host_triplet
+
+ # The HPPA assembler syntax is a little different than most, to make
+ # the test source file assemble we need to run it through sed.
+ #
+ # This is a hack in that it won't scale well if other targets need
+ # similar transformations to assemble. We'll generalize the hack
+ # if/when other targets need similar handling.
+ if [istarget "hppa*-*-*" ] then {
+ send_log "sed -f $srcdir/config/hppa.sed < $source > asm.s\n"
+ verbose "sed -f $srcdir/config/hppa.sed < $source > asm.s"
+ catch "exec sed -f $srcdir/config/hppa.sed < $source > asm.s";
+ set source asm.s
+ }
+
+ set exec_output [target_assemble $source $object ""];
+ set exec_output [prune_warnings $exec_output]
+
+ if [string match "" $exec_output] {
+ return 1
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ perror "$source: assembly failed"
+ return 0
+ }
+}
+
+if ![info exists target_assemble] {
+#
+# Stolen from dejagnu/lib/target.exp--please remove after 1/1/98.
+#
+uplevel #0 {
+ proc target_assemble { source destfile flags } {
+ return [default_target_assemble $source $destfile $flags];
+ }
+
+ proc default_target_assemble { source destfile flags } {
+ global AS_FOR_TARGET;
+ global ASFLAGS_FOR_TARGET;
+
+ if [info exists AS_FOR_TARGET] {
+ set AS "$AS_FOR_TARGET";
+ } else {
+ if ![board_info target exists assembler] {
+ set AS [find_gas];
+ } else {
+ set AS [board_info target assembler];
+ }
+ }
+
+ if [info exists ASFLAGS_FOR_TARGET] {
+ append flags " $ASFLAGS_FOR_TARGET";
+ }
+
+ if [is_remote host] {
+ set source [remote_download host $source];
+ set dest "a.out"
+ } else {
+ set dest $destfile
+ }
+ set status [remote_exec host "$AS $source $flags -o $dest"]
+ if [is_remote host] {
+ remote_upload host $dest $destfile
+ }
+
+ set comp_output [prune_warnings [lindex $status 1]];
+ if { [lindex $status 0] != 0 } {
+ verbose -log "assembler exited with status [lindex $status 0]";
+ }
+ if { [lindex $status 1] != "" } {
+ verbose -log "assembler output is:\n[lindex $status 1]" 2;
+ }
+ return ${comp_output};
+}
+}
+}
diff --git a/binutils/version.c b/binutils/version.c
new file mode 100644
index 00000000000..105593997a7
--- /dev/null
+++ b/binutils/version.c
@@ -0,0 +1,44 @@
+/* version.c -- binutils version information
+ Copyright 1991, 1996, 1997, 1998, 1999 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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "bfd.h"
+#include "bucomm.h"
+
+/* This is the version numbers for the binutils. They all change in
+ lockstep -- it's easier that way. */
+
+const char *program_version = VERSION;
+
+/* Print the version number and copyright information, and exit. This
+ implements the --version option for the various programs. */
+
+void
+print_version (name)
+ const char *name;
+{
+ /* This output is intended to follow the GNU standards document. */
+ /* xgettext:c-format */
+ printf ("GNU %s %s\n", name, program_version);
+ printf (_("Copyright 1997, 1998, 1999 Free Software Foundation, Inc.\n"));
+ printf (_("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n"));
+ exit (0);
+}
diff --git a/binutils/windres.c b/binutils/windres.c
new file mode 100644
index 00000000000..7de28c259e6
--- /dev/null
+++ b/binutils/windres.c
@@ -0,0 +1,947 @@
+/* windres.c -- a program to manipulate Windows resources
+ Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This program can read and write Windows resources in various
+ formats. In particular, it can act like the rc resource compiler
+ program, and it can act like the cvtres res to COFF conversion
+ program.
+
+ It is based on information taken from the following sources:
+
+ * Microsoft documentation.
+
+ * The rcl program, written by Gunther Ebert
+ <gunther.ebert@ixos-leipzig.de>.
+
+ * The res2coff program, written by Pedro A. Aranda <paag@tid.es>.
+
+ */
+
+#include "bfd.h"
+#include "getopt.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "obstack.h"
+#include "windres.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <time.h>
+
+/* An enumeration of format types. */
+
+enum res_format
+{
+ /* Unknown format. */
+ RES_FORMAT_UNKNOWN,
+ /* Textual RC file. */
+ RES_FORMAT_RC,
+ /* Binary RES file. */
+ RES_FORMAT_RES,
+ /* COFF file. */
+ RES_FORMAT_COFF
+};
+
+/* A structure used to map between format types and strings. */
+
+struct format_map
+{
+ const char *name;
+ enum res_format format;
+};
+
+/* A mapping between names and format types. */
+
+static const struct format_map format_names[] =
+{
+ { "rc", RES_FORMAT_RC },
+ { "res", RES_FORMAT_RES },
+ { "coff", RES_FORMAT_COFF },
+ { NULL, RES_FORMAT_UNKNOWN }
+};
+
+/* A mapping from file extensions to format types. */
+
+static const struct format_map format_fileexts[] =
+{
+ { "rc", RES_FORMAT_RC },
+ { "res", RES_FORMAT_RES },
+ { "exe", RES_FORMAT_COFF },
+ { "obj", RES_FORMAT_COFF },
+ { "o", RES_FORMAT_COFF },
+ { NULL, RES_FORMAT_UNKNOWN }
+};
+
+/* A list of include directories. */
+
+struct include_dir
+{
+ struct include_dir *next;
+ char *dir;
+};
+
+static struct include_dir *include_dirs;
+
+/* Long options. */
+
+/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
+
+#define OPTION_DEFINE 150
+#define OPTION_HELP (OPTION_DEFINE + 1)
+#define OPTION_INCLUDE_DIR (OPTION_HELP + 1)
+#define OPTION_LANGUAGE (OPTION_INCLUDE_DIR + 1)
+#define OPTION_PREPROCESSOR (OPTION_LANGUAGE + 1)
+#define OPTION_VERSION (OPTION_PREPROCESSOR + 1)
+#define OPTION_YYDEBUG (OPTION_VERSION + 1)
+
+static const struct option long_options[] =
+{
+ {"define", required_argument, 0, OPTION_DEFINE},
+ {"help", no_argument, 0, OPTION_HELP},
+ {"include-dir", required_argument, 0, OPTION_INCLUDE_DIR},
+ {"input-format", required_argument, 0, 'I'},
+ {"language", required_argument, 0, OPTION_LANGUAGE},
+ {"output-format", required_argument, 0, 'O'},
+ {"preprocessor", required_argument, 0, OPTION_PREPROCESSOR},
+ {"target", required_argument, 0, 'F'},
+ {"version", no_argument, 0, OPTION_VERSION},
+ {"yydebug", no_argument, 0, OPTION_YYDEBUG},
+ {0, no_argument, 0, 0}
+};
+
+/* Static functions. */
+
+static void res_init PARAMS ((void));
+static int extended_menuitems PARAMS ((const struct menuitem *));
+static enum res_format format_from_name PARAMS ((const char *));
+static enum res_format format_from_filename PARAMS ((const char *, int));
+static void usage PARAMS ((FILE *, int));
+static int cmp_res_entry PARAMS ((const PTR, const PTR));
+static struct res_directory *sort_resources PARAMS ((struct res_directory *));
+
+/* When we are building a resource tree, we allocate everything onto
+ an obstack, so that we can free it all at once if we want. */
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+/* The resource building obstack. */
+
+static struct obstack res_obstack;
+
+/* Initialize the resource building obstack. */
+
+static void
+res_init ()
+{
+ obstack_init (&res_obstack);
+}
+
+/* Allocate space on the resource building obstack. */
+
+PTR
+res_alloc (bytes)
+ size_t bytes;
+{
+ return (PTR) obstack_alloc (&res_obstack, bytes);
+}
+
+/* We also use an obstack to save memory used while writing out a set
+ of resources. */
+
+static struct obstack reswr_obstack;
+
+/* Initialize the resource writing obstack. */
+
+static void
+reswr_init ()
+{
+ obstack_init (&reswr_obstack);
+}
+
+/* Allocate space on the resource writing obstack. */
+
+PTR
+reswr_alloc (bytes)
+ size_t bytes;
+{
+ return (PTR) obstack_alloc (&reswr_obstack, bytes);
+}
+
+/* Open a file using the include directory search list. */
+
+FILE *
+open_file_search (filename, mode, errmsg, real_filename)
+ const char *filename;
+ const char *mode;
+ const char *errmsg;
+ char **real_filename;
+{
+ FILE *e;
+ struct include_dir *d;
+
+ e = fopen (filename, mode);
+ if (e != NULL)
+ {
+ *real_filename = xstrdup (filename);
+ return e;
+ }
+
+ if (errno == ENOENT)
+ {
+ for (d = include_dirs; d != NULL; d = d->next)
+ {
+ char *n;
+
+ n = (char *) xmalloc (strlen (d->dir) + strlen (filename) + 2);
+ sprintf (n, "%s/%s", d->dir, filename);
+ e = fopen (n, mode);
+ if (e != NULL)
+ {
+ *real_filename = n;
+ return e;
+ }
+
+ if (errno != ENOENT)
+ break;
+ }
+ }
+
+ fatal (_("can't open %s `%s': %s"), errmsg, filename, strerror (errno));
+
+ /* Return a value to avoid a compiler warning. */
+ return NULL;
+}
+
+/* Compare two resource ID's. We consider name entries to come before
+ numeric entries, because that is how they appear in the COFF .rsrc
+ section. */
+
+int
+res_id_cmp (a, b)
+ struct res_id a;
+ struct res_id b;
+{
+ if (! a.named)
+ {
+ if (b.named)
+ return 1;
+ if (a.u.id > b.u.id)
+ return 1;
+ else if (a.u.id < b.u.id)
+ return -1;
+ else
+ return 0;
+ }
+ else
+ {
+ unichar *as, *ase, *bs, *bse;
+
+ if (! b.named)
+ return -1;
+
+ as = a.u.n.name;
+ ase = as + a.u.n.length;
+ bs = b.u.n.name;
+ bse = bs + b.u.n.length;
+
+ while (as < ase)
+ {
+ int i;
+
+ if (bs >= bse)
+ return 1;
+ i = (int) *as - (int) *bs;
+ if (i != 0)
+ return i;
+ ++as;
+ ++bs;
+ }
+
+ if (bs < bse)
+ return -1;
+
+ return 0;
+ }
+}
+
+/* Print a resource ID. */
+
+void
+res_id_print (stream, id, quote)
+ FILE *stream;
+ struct res_id id;
+ int quote;
+{
+ if (! id.named)
+ fprintf (stream, "%lu", id.u.id);
+ else
+ {
+ if (quote)
+ putc ('"', stream);
+ unicode_print (stream, id.u.n.name, id.u.n.length);
+ if (quote)
+ putc ('"', stream);
+ }
+}
+
+/* Print a list of resource ID's. */
+
+void
+res_ids_print (stream, cids, ids)
+ FILE *stream;
+ int cids;
+ const struct res_id *ids;
+{
+ int i;
+
+ for (i = 0; i < cids; i++)
+ {
+ res_id_print (stream, ids[i], 1);
+ if (i + 1 < cids)
+ fprintf (stream, ": ");
+ }
+}
+
+/* Convert an ASCII string to a resource ID. */
+
+void
+res_string_to_id (res_id, string)
+ struct res_id *res_id;
+ const char *string;
+{
+ res_id->named = 1;
+ unicode_from_ascii (&res_id->u.n.length, &res_id->u.n.name, string);
+}
+
+/* Define a resource. The arguments are the resource tree, RESOURCES,
+ and the location at which to put it in the tree, CIDS and IDS.
+ This returns a newly allocated res_resource structure, which the
+ caller is expected to initialize. If DUPOK is non-zero, then if a
+ resource with this ID exists, it is returned. Otherwise, a warning
+ is issued, and a new resource is created replacing the existing
+ one. */
+
+struct res_resource *
+define_resource (resources, cids, ids, dupok)
+ struct res_directory **resources;
+ int cids;
+ const struct res_id *ids;
+ int dupok;
+{
+ struct res_entry *re = NULL;
+ int i;
+
+ assert (cids > 0);
+ for (i = 0; i < cids; i++)
+ {
+ struct res_entry **pp;
+
+ if (*resources == NULL)
+ {
+ static unsigned long timeval;
+
+ /* Use the same timestamp for every resource created in a
+ single run. */
+ if (timeval == 0)
+ timeval = time (NULL);
+
+ *resources = ((struct res_directory *)
+ res_alloc (sizeof **resources));
+ (*resources)->characteristics = 0;
+ (*resources)->time = timeval;
+ (*resources)->major = 0;
+ (*resources)->minor = 0;
+ (*resources)->entries = NULL;
+ }
+
+ for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
+ if (res_id_cmp ((*pp)->id, ids[i]) == 0)
+ break;
+
+ if (*pp != NULL)
+ re = *pp;
+ else
+ {
+ re = (struct res_entry *) res_alloc (sizeof *re);
+ re->next = NULL;
+ re->id = ids[i];
+ if ((i + 1) < cids)
+ {
+ re->subdir = 1;
+ re->u.dir = NULL;
+ }
+ else
+ {
+ re->subdir = 0;
+ re->u.res = NULL;
+ }
+
+ *pp = re;
+ }
+
+ if ((i + 1) < cids)
+ {
+ if (! re->subdir)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ res_ids_print (stderr, i, ids);
+ fprintf (stderr, _(": expected to be a directory\n"));
+ xexit (1);
+ }
+
+ resources = &re->u.dir;
+ }
+ }
+
+ if (re->subdir)
+ {
+ fprintf (stderr, "%s: ", program_name);
+ res_ids_print (stderr, cids, ids);
+ fprintf (stderr, _(": expected to be a leaf\n"));
+ xexit (1);
+ }
+
+ if (re->u.res != NULL)
+ {
+ if (dupok)
+ return re->u.res;
+
+ fprintf (stderr, _("%s: warning: "), program_name);
+ res_ids_print (stderr, cids, ids);
+ fprintf (stderr, _(": duplicate value\n"));
+ }
+
+ re->u.res = ((struct res_resource *)
+ res_alloc (sizeof (struct res_resource)));
+
+ re->u.res->type = RES_TYPE_UNINITIALIZED;
+ memset (&re->u.res->res_info, 0, sizeof (struct res_res_info));
+ memset (&re->u.res->coff_info, 0, sizeof (struct res_coff_info));
+
+ return re->u.res;
+}
+
+/* Define a standard resource. This is a version of define_resource
+ that just takes type, name, and language arguments. */
+
+struct res_resource *
+define_standard_resource (resources, type, name, language, dupok)
+ struct res_directory **resources;
+ int type;
+ struct res_id name;
+ int language;
+ int dupok;
+{
+ struct res_id a[3];
+
+ a[0].named = 0;
+ a[0].u.id = type;
+ a[1] = name;
+ a[2].named = 0;
+ a[2].u.id = language;
+ return define_resource (resources, 3, a, dupok);
+}
+
+/* Comparison routine for resource sorting. */
+
+static int
+cmp_res_entry (p1, p2)
+ const PTR p1;
+ const PTR p2;
+{
+ const struct res_entry **re1, **re2;
+
+ re1 = (const struct res_entry **) p1;
+ re2 = (const struct res_entry **) p2;
+ return res_id_cmp ((*re1)->id, (*re2)->id);
+}
+
+/* Sort the resources. */
+
+static struct res_directory *
+sort_resources (resdir)
+ struct res_directory *resdir;
+{
+ int c, i;
+ struct res_entry *re;
+ struct res_entry **a;
+
+ if (resdir->entries == NULL)
+ return resdir;
+
+ c = 0;
+ for (re = resdir->entries; re != NULL; re = re->next)
+ ++c;
+
+ /* This is a recursive routine, so using xmalloc is probably better
+ than alloca. */
+ a = (struct res_entry **) xmalloc (c * sizeof (struct res_entry *));
+
+ for (i = 0, re = resdir->entries; re != NULL; re = re->next, i++)
+ a[i] = re;
+
+ qsort (a, c, sizeof (struct res_entry *), cmp_res_entry);
+
+ resdir->entries = a[0];
+ for (i = 0; i < c - 1; i++)
+ a[i]->next = a[i + 1];
+ a[i]->next = NULL;
+
+ free (a);
+
+ /* Now sort the subdirectories. */
+
+ for (re = resdir->entries; re != NULL; re = re->next)
+ if (re->subdir)
+ re->u.dir = sort_resources (re->u.dir);
+
+ return resdir;
+}
+
+/* Return whether the dialog resource DIALOG is a DIALOG or a
+ DIALOGEX. */
+
+int
+extended_dialog (dialog)
+ const struct dialog *dialog;
+{
+ const struct dialog_control *c;
+
+ if (dialog->ex != NULL)
+ return 1;
+
+ for (c = dialog->controls; c != NULL; c = c->next)
+ if (c->data != NULL || c->help != 0)
+ return 1;
+
+ return 0;
+}
+
+/* Return whether MENUITEMS are a MENU or a MENUEX. */
+
+int
+extended_menu (menu)
+ const struct menu *menu;
+{
+ return extended_menuitems (menu->items);
+}
+
+static int
+extended_menuitems (menuitems)
+ const struct menuitem *menuitems;
+{
+ const struct menuitem *mi;
+
+ for (mi = menuitems; mi != NULL; mi = mi->next)
+ {
+ if (mi->help != 0 || mi->state != 0)
+ return 1;
+ if (mi->popup != NULL && mi->id != 0)
+ return 1;
+ if ((mi->type
+ & ~ (MENUITEM_CHECKED
+ | MENUITEM_GRAYED
+ | MENUITEM_HELP
+ | MENUITEM_INACTIVE
+ | MENUITEM_MENUBARBREAK
+ | MENUITEM_MENUBREAK))
+ != 0)
+ return 1;
+ if (mi->popup != NULL)
+ {
+ if (extended_menuitems (mi->popup))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Convert a string to a format type, or exit if it can't be done. */
+
+static enum res_format
+format_from_name (name)
+ const char *name;
+{
+ const struct format_map *m;
+
+ for (m = format_names; m->name != NULL; m++)
+ if (strcasecmp (m->name, name) == 0)
+ break;
+
+ if (m->name == NULL)
+ {
+ fprintf (stderr, _("%s: unknown format type `%s'\n"), program_name, name);
+ fprintf (stderr, _("%s: supported formats:"), program_name);
+ for (m = format_names; m->name != NULL; m++)
+ fprintf (stderr, " %s", m->name);
+ fprintf (stderr, "\n");
+ xexit (1);
+ }
+
+ return m->format;
+}
+
+/* Work out a format type given a file name. If INPUT is non-zero,
+ it's OK to look at the file itself. */
+
+static enum res_format
+format_from_filename (filename, input)
+ const char *filename;
+ int input;
+{
+ const char *ext;
+ FILE *e;
+ unsigned char b1, b2, b3, b4, b5;
+ int magic;
+
+ /* If we have an extension, see if we recognize it as implying a
+ particular format. */
+ ext = strrchr (filename, '.');
+ if (ext != NULL)
+ {
+ const struct format_map *m;
+
+ ++ext;
+ for (m = format_fileexts; m->name != NULL; m++)
+ if (strcasecmp (m->name, ext) == 0)
+ return m->format;
+ }
+
+ /* If we don't recognize the name of an output file, assume it's a
+ COFF file. */
+
+ if (! input)
+ return RES_FORMAT_COFF;
+
+ /* Read the first few bytes of the file to see if we can guess what
+ it is. */
+
+ e = fopen (filename, FOPEN_RB);
+ if (e == NULL)
+ fatal ("%s: %s", filename, strerror (errno));
+
+ b1 = getc (e);
+ b2 = getc (e);
+ b3 = getc (e);
+ b4 = getc (e);
+ b5 = getc (e);
+
+ fclose (e);
+
+ /* A PE executable starts with 0x4d 0x5a. */
+ if (b1 == 0x4d && b2 == 0x5a)
+ return RES_FORMAT_COFF;
+
+ /* A COFF .o file starts with a COFF magic number. */
+ magic = (b2 << 8) | b1;
+ switch (magic)
+ {
+ case 0x14c: /* i386 */
+ case 0x166: /* MIPS */
+ case 0x184: /* Alpha */
+ case 0x268: /* 68k */
+ case 0x1f0: /* PowerPC */
+ case 0x290: /* PA */
+ return RES_FORMAT_COFF;
+ }
+
+ /* A RES file starts with 0x0 0x0 0x0 0x0 0x20 0x0 0x0 0x0. */
+ if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0 && b5 == 0x20)
+ return RES_FORMAT_RES;
+
+ /* If every character is printable or space, assume it's an RC file. */
+ if ((isprint (b1) || isspace (b1))
+ && (isprint (b2) || isspace (b2))
+ && (isprint (b3) || isspace (b3))
+ && (isprint (b4) || isspace (b4))
+ && (isprint (b5) || isspace (b5)))
+ return RES_FORMAT_RC;
+
+ /* Otherwise, we give up. */
+ fatal (_("can not determine type of file `%s'; use the -I option"),
+ filename);
+
+ /* Return something to silence the compiler warning. */
+ return RES_FORMAT_UNKNOWN;
+}
+
+/* Print a usage message and exit. */
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, _("Usage: %s [options] [input-file] [output-file]\n"),
+ program_name);
+ fprintf (stream, _("\
+Options:\n\
+ -i FILE, --input FILE Name input file\n\
+ -o FILE, --output FILE Name output file\n\
+ -I FORMAT, --input-format FORMAT\n\
+ Specify input format\n\
+ -O FORMAT, --output-format FORMAT\n\
+ Specify output format\n\
+ -F TARGET, --target TARGET Specify COFF target\n\
+ --preprocessor PROGRAM Program to use to preprocess rc file\n\
+ --include-dir DIR Include directory when preprocessing rc file\n\
+ --define SYM[=VAL] Define SYM when preprocessing rc file\n\
+ --language VAL Set language when reading rc file\n"));
+#ifdef YYDEBUG
+ fprintf (stream, _("\
+ --yydebug Turn on parser debugging\n"));
+#endif
+ fprintf (stream, _("\
+ --help Print this help message\n\
+ --version Print version information\n"));
+ fprintf (stream, _("\
+FORMAT is one of rc, res, or coff, and is deduced from the file name\n\
+extension if not specified. A single file name is an input file.\n\
+No input-file is stdin, default rc. No output-file is stdout, default rc.\n"));
+ list_supported_targets (program_name, stream);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+/* The main function. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ char *input_filename;
+ char *output_filename;
+ enum res_format input_format;
+ enum res_format output_format;
+ char *target;
+ char *preprocessor;
+ char *preprocargs;
+ int language;
+ struct res_directory *resources;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ bfd_init ();
+ set_default_bfd_target ();
+
+ res_init ();
+
+ input_filename = NULL;
+ output_filename = NULL;
+ input_format = RES_FORMAT_UNKNOWN;
+ output_format = RES_FORMAT_UNKNOWN;
+ target = NULL;
+ preprocessor = NULL;
+ preprocargs = NULL;
+ language = -1;
+
+ while ((c = getopt_long (argc, argv, "i:o:I:O:F:", long_options,
+ (int *) 0)) != EOF)
+ {
+ switch (c)
+ {
+ case 'i':
+ input_filename = optarg;
+ break;
+
+ case 'o':
+ output_filename = optarg;
+ break;
+
+ case 'I':
+ input_format = format_from_name (optarg);
+ break;
+
+ case 'O':
+ output_format = format_from_name (optarg);
+ break;
+
+ case 'F':
+ target = optarg;
+ break;
+
+ case OPTION_PREPROCESSOR:
+ preprocessor = optarg;
+ break;
+
+ case OPTION_DEFINE:
+ if (preprocargs == NULL)
+ {
+ preprocargs = xmalloc (strlen (optarg) + 3);
+ sprintf (preprocargs, "-D%s", optarg);
+ }
+ else
+ {
+ char *n;
+
+ n = xmalloc (strlen (preprocargs) + strlen (optarg) + 4);
+ sprintf (n, "%s -D%s", preprocargs, optarg);
+ free (preprocargs);
+ preprocargs = n;
+ }
+ break;
+
+ case OPTION_INCLUDE_DIR:
+ if (preprocargs == NULL)
+ {
+ preprocargs = xmalloc (strlen (optarg) + 3);
+ sprintf (preprocargs, "-I%s", optarg);
+ }
+ else
+ {
+ char *n;
+
+ n = xmalloc (strlen (preprocargs) + strlen (optarg) + 4);
+ sprintf (n, "%s -I%s", preprocargs, optarg);
+ free (preprocargs);
+ preprocargs = n;
+ }
+
+ {
+ struct include_dir *n, **pp;
+
+ n = (struct include_dir *) xmalloc (sizeof *n);
+ n->next = NULL;
+ n->dir = optarg;
+
+ for (pp = &include_dirs; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = n;
+ }
+
+ break;
+
+ case OPTION_LANGUAGE:
+ language = strtol (optarg, (char **) NULL, 16);
+ break;
+
+#ifdef YYDEBUG
+ case OPTION_YYDEBUG:
+ yydebug = 1;
+ break;
+#endif
+
+ case OPTION_HELP:
+ usage (stdout, 0);
+ break;
+
+ case OPTION_VERSION:
+ print_version ("windres");
+ break;
+
+ default:
+ usage (stderr, 1);
+ break;
+ }
+ }
+
+ if (input_filename == NULL && optind < argc)
+ {
+ input_filename = argv[optind];
+ ++optind;
+ }
+
+ if (output_filename == NULL && optind < argc)
+ {
+ output_filename = argv[optind];
+ ++optind;
+ }
+
+ if (argc != optind)
+ usage (stderr, 1);
+
+ if (input_format == RES_FORMAT_UNKNOWN)
+ {
+ if (input_filename == NULL)
+ input_format = RES_FORMAT_RC;
+ else
+ input_format = format_from_filename (input_filename, 1);
+ }
+
+ if (output_format == RES_FORMAT_UNKNOWN)
+ {
+ if (output_filename == NULL)
+ output_format = RES_FORMAT_RC;
+ else
+ output_format = format_from_filename (output_filename, 0);
+ }
+
+ /* Read the input file. */
+
+ switch (input_format)
+ {
+ default:
+ abort ();
+ case RES_FORMAT_RC:
+ resources = read_rc_file (input_filename, preprocessor, preprocargs,
+ language);
+ break;
+ case RES_FORMAT_RES:
+ resources = read_res_file (input_filename);
+ break;
+ case RES_FORMAT_COFF:
+ resources = read_coff_rsrc (input_filename, target);
+ break;
+ }
+
+ if (resources == NULL)
+ fatal (_("no resources"));
+
+ /* Sort the resources. This is required for COFF, convenient for
+ rc, and unimportant for res. */
+
+ resources = sort_resources (resources);
+
+ /* Write the output file. */
+
+ reswr_init ();
+
+ switch (output_format)
+ {
+ default:
+ abort ();
+ case RES_FORMAT_RC:
+ write_rc_file (output_filename, resources);
+ break;
+ case RES_FORMAT_RES:
+ write_res_file (output_filename, resources);
+ break;
+ case RES_FORMAT_COFF:
+ write_coff_file (output_filename, target, resources);
+ break;
+ }
+
+ xexit (0);
+ return 0;
+}
+
diff --git a/binutils/windres.h b/binutils/windres.h
new file mode 100644
index 00000000000..a3c789abd02
--- /dev/null
+++ b/binutils/windres.h
@@ -0,0 +1,847 @@
+/* windres.h -- header file for windres program.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <ansidecl.h>
+
+/* This is the header file for the windres program. It defines
+ structures and declares functions used within the program. */
+
+#include "winduni.h"
+
+/* We represent resources internally as a tree, similar to the tree
+ used in the .rsrc section of a COFF file. The root is a
+ res_directory structure. */
+
+struct res_directory
+{
+ /* Resource flags. According to the MS docs, this is currently
+ always zero. */
+ unsigned long characteristics;
+ /* Time/date stamp. */
+ unsigned long time;
+ /* Major version number. */
+ unsigned short major;
+ /* Minor version number. */
+ unsigned short minor;
+ /* Directory entries. */
+ struct res_entry *entries;
+};
+
+/* A resource ID is stored in a res_id structure. */
+
+struct res_id
+{
+ /* Non-zero if this entry has a name rather than an ID. */
+ unsigned int named : 1;
+ union
+ {
+ /* If the named field is non-zero, this is the name. */
+ struct
+ {
+ /* Length of the name. */
+ int length;
+ /* Pointer to the name, which is a Unicode string. */
+ unichar *name;
+ } n;
+ /* If the named field is zero, this is the ID. */
+ unsigned long id;
+ } u;
+};
+
+/* Each entry in the tree is a res_entry structure. We mix
+ directories and resources because in a COFF file all entries in a
+ directory are sorted together, whether the entries are
+ subdirectories or resources. */
+
+struct res_entry
+{
+ /* Next entry. */
+ struct res_entry *next;
+ /* Resource ID. */
+ struct res_id id;
+ /* Non-zero if this entry is a subdirectory rather than a leaf. */
+ unsigned int subdir : 1;
+ union
+ {
+ /* If the subdir field is non-zero, this is a pointer to the
+ subdirectory. */
+ struct res_directory *dir;
+ /* If the subdir field is zero, this is a pointer to the resource
+ data. */
+ struct res_resource *res;
+ } u;
+};
+
+/* Types of resources. */
+
+enum res_type
+{
+ RES_TYPE_UNINITIALIZED,
+ RES_TYPE_ACCELERATOR,
+ RES_TYPE_BITMAP,
+ RES_TYPE_CURSOR,
+ RES_TYPE_GROUP_CURSOR,
+ RES_TYPE_DIALOG,
+ RES_TYPE_FONT,
+ RES_TYPE_FONTDIR,
+ RES_TYPE_ICON,
+ RES_TYPE_GROUP_ICON,
+ RES_TYPE_MENU,
+ RES_TYPE_MESSAGETABLE,
+ RES_TYPE_RCDATA,
+ RES_TYPE_STRINGTABLE,
+ RES_TYPE_USERDATA,
+ RES_TYPE_VERSIONINFO
+};
+
+/* A res file and a COFF file store information differently. The
+ res_info structures holds data which in a res file is stored with
+ each resource, but in a COFF file is stored elsewhere. */
+
+struct res_res_info
+{
+ /* Language. In a COFF file, the third level of the directory is
+ keyed by the language, so the language of a resource is defined
+ by its location in the resource tree. */
+ unsigned short language;
+ /* Characteristics of the resource. Entirely user defined. In a
+ COFF file, the res_directory structure has a characteristics
+ field, but I don't know if it's related to the one in the res
+ file. */
+ unsigned long characteristics;
+ /* Version of the resource. Entirely user defined. In a COFF file,
+ the res_directory structure has a characteristics field, but I
+ don't know if it's related to the one in the res file. */
+ unsigned long version;
+ /* Memory flags. This is a combination of the MEMFLAG values
+ defined below. Most of these values are historical, and are not
+ meaningful for win32. I don't think there is any way to store
+ this information in a COFF file. */
+ unsigned short memflags;
+};
+
+/* Each resource in a COFF file has some information which can does
+ not appear in a res file. */
+
+struct res_coff_info
+{
+ /* The code page used for the data. I don't really know what this
+ should be. */
+ unsigned long codepage;
+ /* A resource entry in a COFF file has a reserved field, which we
+ record here when reading a COFF file. When writing a COFF file,
+ we set this field to zero. */
+ unsigned long reserved;
+};
+
+/* Resource data is stored in a res_resource structure. */
+
+struct res_resource
+{
+ /* The type of resource. */
+ enum res_type type;
+ /* The data for the resource. */
+ union
+ {
+ struct
+ {
+ unsigned long length;
+ const unsigned char *data;
+ } data;
+ struct accelerator *acc;
+ struct cursor *cursor;
+ struct group_cursor *group_cursor;
+ struct dialog *dialog;
+ struct fontdir *fontdir;
+ struct group_icon *group_icon;
+ struct menu *menu;
+ struct rcdata_item *rcdata;
+ struct stringtable *stringtable;
+ struct rcdata_item *userdata;
+ struct versioninfo *versioninfo;
+ } u;
+ /* Information from a res file. */
+ struct res_res_info res_info;
+ /* Information from a COFF file. */
+ struct res_coff_info coff_info;
+};
+
+/* Memory flags in the memflags field of a struct res_resource. */
+
+#define MEMFLAG_MOVEABLE 0x10
+#define MEMFLAG_PURE 0x20
+#define MEMFLAG_PRELOAD 0x40
+#define MEMFLAG_DISCARDABLE 0x1000
+
+/* Standard resource type codes. These are used in the ID field of a
+ res_entry structure. */
+
+#define RT_CURSOR 1
+#define RT_BITMAP 2
+#define RT_ICON 3
+#define RT_MENU 4
+#define RT_DIALOG 5
+#define RT_STRING 6
+#define RT_FONTDIR 7
+#define RT_FONT 8
+#define RT_ACCELERATOR 9
+#define RT_RCDATA 10
+#define RT_MESSAGETABLE 11
+#define RT_GROUP_CURSOR 12
+#define RT_GROUP_ICON 14
+#define RT_VERSION 16
+#define RT_DLGINCLUDE 17
+#define RT_PLUGPLAY 19
+#define RT_VXD 20
+#define RT_ANICURSOR 21
+#define RT_ANIICON 22
+
+/* An accelerator resource is a linked list of these structures. */
+
+struct accelerator
+{
+ /* Next accelerator. */
+ struct accelerator *next;
+ /* Flags. A combination of the ACC values defined below. */
+ unsigned short flags;
+ /* Key value. */
+ unsigned short key;
+ /* Resource ID. */
+ unsigned short id;
+};
+
+/* Accelerator flags in the flags field of a struct accelerator.
+ These are the same values that appear in a res file. I hope. */
+
+#define ACC_VIRTKEY 0x01
+#define ACC_NOINVERT 0x02
+#define ACC_SHIFT 0x04
+#define ACC_CONTROL 0x08
+#define ACC_ALT 0x10
+#define ACC_LAST 0x80
+
+/* A cursor resource. */
+
+struct cursor
+{
+ /* X coordinate of hotspot. */
+ short xhotspot;
+ /* Y coordinate of hotspot. */
+ short yhotspot;
+ /* Length of bitmap data. */
+ unsigned long length;
+ /* Data. */
+ const unsigned char *data;
+};
+
+/* A group_cursor resource is a list of group_cursor structures. */
+
+struct group_cursor
+{
+ /* Next cursor in group. */
+ struct group_cursor *next;
+ /* Width. */
+ unsigned short width;
+ /* Height. */
+ unsigned short height;
+ /* Planes. */
+ unsigned short planes;
+ /* Bits per pixel. */
+ unsigned short bits;
+ /* Number of bytes in cursor resource. */
+ unsigned long bytes;
+ /* Index of cursor resource. */
+ unsigned short index;
+};
+
+/* A dialog resource. */
+
+struct dialog
+{
+ /* Basic window style. */
+ unsigned long style;
+ /* Extended window style. */
+ unsigned long exstyle;
+ /* X coordinate. */
+ unsigned short x;
+ /* Y coordinate. */
+ unsigned short y;
+ /* Width. */
+ unsigned short width;
+ /* Height. */
+ unsigned short height;
+ /* Menu name. */
+ struct res_id menu;
+ /* Class name. */
+ struct res_id class;
+ /* Caption. */
+ unichar *caption;
+ /* Font point size. */
+ unsigned short pointsize;
+ /* Font name. */
+ unichar *font;
+ /* Extended information for a dialogex. */
+ struct dialog_ex *ex;
+ /* Controls. */
+ struct dialog_control *controls;
+};
+
+/* An extended dialog has additional information. */
+
+struct dialog_ex
+{
+ /* Help ID. */
+ unsigned long help;
+ /* Font weight. */
+ unsigned short weight;
+ /* Whether the font is italic. */
+ unsigned short italic;
+};
+
+/* Window style flags, from the winsup Defines.h header file. These
+ can appear in the style field of a struct dialog or a struct
+ dialog_control. */
+
+#define CW_USEDEFAULT (0x80000000)
+#define WS_BORDER (0x800000L)
+#define WS_CAPTION (0xc00000L)
+#define WS_CHILD (0x40000000L)
+#define WS_CHILDWINDOW (0x40000000L)
+#define WS_CLIPCHILDREN (0x2000000L)
+#define WS_CLIPSIBLINGS (0x4000000L)
+#define WS_DISABLED (0x8000000L)
+#define WS_DLGFRAME (0x400000L)
+#define WS_GROUP (0x20000L)
+#define WS_HSCROLL (0x100000L)
+#define WS_ICONIC (0x20000000L)
+#define WS_MAXIMIZE (0x1000000L)
+#define WS_MAXIMIZEBOX (0x10000L)
+#define WS_MINIMIZE (0x20000000L)
+#define WS_MINIMIZEBOX (0x20000L)
+#define WS_OVERLAPPED (0L)
+#define WS_OVERLAPPEDWINDOW (0xcf0000L)
+#define WS_POPUP (0x80000000L)
+#define WS_POPUPWINDOW (0x80880000L)
+#define WS_SIZEBOX (0x40000L)
+#define WS_SYSMENU (0x80000L)
+#define WS_TABSTOP (0x10000L)
+#define WS_THICKFRAME (0x40000L)
+#define WS_TILED (0L)
+#define WS_TILEDWINDOW (0xcf0000L)
+#define WS_VISIBLE (0x10000000L)
+#define WS_VSCROLL (0x200000L)
+#define MDIS_ALLCHILDSTYLES (0x1)
+#define BS_3STATE (0x5L)
+#define BS_AUTO3STATE (0x6L)
+#define BS_AUTOCHECKBOX (0x3L)
+#define BS_AUTORADIOBUTTON (0x9L)
+#define BS_BITMAP (0x80L)
+#define BS_BOTTOM (0x800L)
+#define BS_CENTER (0x300L)
+#define BS_CHECKBOX (0x2L)
+#define BS_DEFPUSHBUTTON (0x1L)
+#define BS_GROUPBOX (0x7L)
+#define BS_ICON (0x40L)
+#define BS_LEFT (0x100L)
+#define BS_LEFTTEXT (0x20L)
+#define BS_MULTILINE (0x2000L)
+#define BS_NOTIFY (0x4000L)
+#define BS_OWNERDRAW (0xbL)
+#define BS_PUSHBOX (0xcL) /* FIXME! What should this be? */
+#define BS_PUSHBUTTON (0L)
+#define BS_PUSHLIKE (0x1000L)
+#define BS_RADIOBUTTON (0x4L)
+#define BS_RIGHT (0x200L)
+#define BS_RIGHTBUTTON (0x20L)
+#define BS_TEXT (0L)
+#define BS_TOP (0x400L)
+#define BS_USERBUTTON (0x8L)
+#define BS_VCENTER (0xc00L)
+#define CBS_AUTOHSCROLL (0x40L)
+#define CBS_DISABLENOSCROLL (0x800L)
+#define CBS_DROPDOWN (0x2L)
+#define CBS_DROPDOWNLIST (0x3L)
+#define CBS_HASSTRINGS (0x200L)
+#define CBS_LOWERCASE (0x4000L)
+#define CBS_NOINTEGRALHEIGHT (0x400L)
+#define CBS_OEMCONVERT (0x80L)
+#define CBS_OWNERDRAWFIXED (0x10L)
+#define CBS_OWNERDRAWVARIABLE (0x20L)
+#define CBS_SIMPLE (0x1L)
+#define CBS_SORT (0x100L)
+#define CBS_UPPERCASE (0x2000L)
+#define ES_AUTOHSCROLL (0x80L)
+#define ES_AUTOVSCROLL (0x40L)
+#define ES_CENTER (0x1L)
+#define ES_LEFT (0L)
+#define ES_LOWERCASE (0x10L)
+#define ES_MULTILINE (0x4L)
+#define ES_NOHIDESEL (0x100L)
+#define ES_NUMBER (0x2000L)
+#define ES_OEMCONVERT (0x400L)
+#define ES_PASSWORD (0x20L)
+#define ES_READONLY (0x800L)
+#define ES_RIGHT (0x2L)
+#define ES_UPPERCASE (0x8L)
+#define ES_WANTRETURN (0x1000L)
+#define LBS_DISABLENOSCROLL (0x1000L)
+#define LBS_EXTENDEDSEL (0x800L)
+#define LBS_HASSTRINGS (0x40L)
+#define LBS_MULTICOLUMN (0x200L)
+#define LBS_MULTIPLESEL (0x8L)
+#define LBS_NODATA (0x2000L)
+#define LBS_NOINTEGRALHEIGHT (0x100L)
+#define LBS_NOREDRAW (0x4L)
+#define LBS_NOSEL (0x4000L)
+#define LBS_NOTIFY (0x1L)
+#define LBS_OWNERDRAWFIXED (0x10L)
+#define LBS_OWNERDRAWVARIABLE (0x20L)
+#define LBS_SORT (0x2L)
+#define LBS_STANDARD (0xa00003L)
+#define LBS_USETABSTOPS (0x80L)
+#define LBS_WANTKEYBOARDINPUT (0x400L)
+#define SBS_BOTTOMALIGN (0x4L)
+#define SBS_HORZ (0L)
+#define SBS_LEFTALIGN (0x2L)
+#define SBS_RIGHTALIGN (0x4L)
+#define SBS_SIZEBOX (0x8L)
+#define SBS_SIZEBOXBOTTOMRIGHTALIGN (0x4L)
+#define SBS_SIZEBOXTOPLEFTALIGN (0x2L)
+#define SBS_SIZEGRIP (0x10L)
+#define SBS_TOPALIGN (0x2L)
+#define SBS_VERT (0x1L)
+#define SS_BITMAP (0xeL)
+#define SS_BLACKFRAME (0x7L)
+#define SS_BLACKRECT (0x4L)
+#define SS_CENTER (0x1L)
+#define SS_CENTERIMAGE (0x200L)
+#define SS_ENHMETAFILE (0xfL)
+#define SS_ETCHEDFRAME (0x12L)
+#define SS_ETCHEDHORZ (0x10L)
+#define SS_ETCHEDVERT (0x11L)
+#define SS_GRAYFRAME (0x8L)
+#define SS_GRAYRECT (0x5L)
+#define SS_ICON (0x3L)
+#define SS_LEFT (0L)
+#define SS_LEFTNOWORDWRAP (0xcL)
+#define SS_NOPREFIX (0x80L)
+#define SS_NOTIFY (0x100L)
+#define SS_OWNERDRAW (0xdL)
+#define SS_REALSIZEIMAGE (0x800L)
+#define SS_RIGHT (0x2L)
+#define SS_RIGHTJUST (0x400L)
+#define SS_SIMPLE (0xbL)
+#define SS_SUNKEN (0x1000L)
+#define SS_USERITEM (0xaL)
+#define SS_WHITEFRAME (0x9L)
+#define SS_WHITERECT (0x6L)
+#define DS_3DLOOK (0x4L)
+#define DS_ABSALIGN (0x1L)
+#define DS_CENTER (0x800L)
+#define DS_CENTERMOUSE (0x1000L)
+#define DS_CONTEXTHELP (0x2000L)
+#define DS_CONTROL (0x400L)
+#define DS_FIXEDSYS (0x8L)
+#define DS_LOCALEDIT (0x20L)
+#define DS_MODALFRAME (0x80L)
+#define DS_NOFAILCREATE (0x10L)
+#define DS_NOIDLEMSG (0x100L)
+#define DS_SETFONT (0x40L)
+#define DS_SETFOREGROUND (0x200L)
+#define DS_SYSMODAL (0x2L)
+
+/* A dialog control. */
+
+struct dialog_control
+{
+ /* Next control. */
+ struct dialog_control *next;
+ /* ID. */
+ unsigned short id;
+ /* Style. */
+ unsigned long style;
+ /* Extended style. */
+ unsigned long exstyle;
+ /* X coordinate. */
+ unsigned short x;
+ /* Y coordinate. */
+ unsigned short y;
+ /* Width. */
+ unsigned short width;
+ /* Height. */
+ unsigned short height;
+ /* Class name. */
+ struct res_id class;
+ /* Associated text. */
+ struct res_id text;
+ /* Extra data for the window procedure. */
+ struct rcdata_item *data;
+ /* Help ID. Only used in an extended dialog. */
+ unsigned long help;
+};
+
+/* Control classes. These can be used as the ID field in a struct
+ dialog_control. */
+
+#define CTL_BUTTON 0x80
+#define CTL_EDIT 0x81
+#define CTL_STATIC 0x82
+#define CTL_LISTBOX 0x83
+#define CTL_SCROLLBAR 0x84
+#define CTL_COMBOBOX 0x85
+
+/* A fontdir resource is a list of fontdir structures. */
+
+struct fontdir
+{
+ struct fontdir *next;
+ /* Index of font entry. */
+ short index;
+ /* Length of font information. */
+ unsigned long length;
+ /* Font information. */
+ const unsigned char *data;
+};
+
+/* A group_icon resource is a list of group_icon structures. */
+
+struct group_icon
+{
+ /* Next icon in group. */
+ struct group_icon *next;
+ /* Width. */
+ unsigned char width;
+ /* Height. */
+ unsigned char height;
+ /* Color count. */
+ unsigned char colors;
+ /* Planes. */
+ unsigned short planes;
+ /* Bits per pixel. */
+ unsigned short bits;
+ /* Number of bytes in cursor resource. */
+ unsigned long bytes;
+ /* Index of cursor resource. */
+ unsigned short index;
+};
+
+/* A menu resource. */
+
+struct menu
+{
+ /* List of menuitems. */
+ struct menuitem *items;
+ /* Help ID. I don't think there is any way to set this in an rc
+ file, but it can appear in the binary format. */
+ unsigned long help;
+};
+
+/* A menu resource is a list of menuitem structures. */
+
+struct menuitem
+{
+ /* Next menuitem. */
+ struct menuitem *next;
+ /* Type. In a normal menu, rather than a menuex, this is the flags
+ field. */
+ unsigned long type;
+ /* State. This is only used in a menuex. */
+ unsigned long state;
+ /* Id. */
+ unsigned short id;
+ /* Unicode text. */
+ unichar *text;
+ /* Popup menu items for a popup. */
+ struct menuitem *popup;
+ /* Help ID. This is only used in a menuex. */
+ unsigned long help;
+};
+
+/* Menu item flags. These can appear in the flags field of a struct
+ menuitem. */
+
+#define MENUITEM_GRAYED 0x001
+#define MENUITEM_INACTIVE 0x002
+#define MENUITEM_BITMAP 0x004
+#define MENUITEM_OWNERDRAW 0x100
+#define MENUITEM_CHECKED 0x008
+#define MENUITEM_POPUP 0x010
+#define MENUITEM_MENUBARBREAK 0x020
+#define MENUITEM_MENUBREAK 0x040
+#define MENUITEM_ENDMENU 0x080
+#define MENUITEM_HELP 0x4000
+
+/* An rcdata resource is a pointer to a list of rcdata_item
+ structures. */
+
+struct rcdata_item
+{
+ /* Next data item. */
+ struct rcdata_item *next;
+ /* Type of data. */
+ enum
+ {
+ RCDATA_WORD,
+ RCDATA_DWORD,
+ RCDATA_STRING,
+ RCDATA_WSTRING,
+ RCDATA_BUFFER
+ } type;
+ union
+ {
+ unsigned int word;
+ unsigned long dword;
+ struct
+ {
+ unsigned long length;
+ const char *s;
+ } string;
+ struct
+ {
+ unsigned long length;
+ const unichar *w;
+ } wstring;
+ struct
+ {
+ unsigned long length;
+ const unsigned char *data;
+ } buffer;
+ } u;
+};
+
+/* A stringtable resource is a pointer to a stringtable structure. */
+
+struct stringtable
+{
+ /* Each stringtable resource is a list of 16 unicode strings. */
+ struct
+ {
+ /* Length of string. */
+ int length;
+ /* String data if length > 0. */
+ unichar *string;
+ } strings[16];
+};
+
+/* A versioninfo resource points to a versioninfo structure. */
+
+struct versioninfo
+{
+ /* Fixed version information. */
+ struct fixed_versioninfo *fixed;
+ /* Variable version information. */
+ struct ver_info *var;
+};
+
+/* The fixed portion of a versioninfo resource. */
+
+struct fixed_versioninfo
+{
+ /* The file version, which is two 32 bit integers. */
+ unsigned long file_version_ms;
+ unsigned long file_version_ls;
+ /* The product version, which is two 32 bit integers. */
+ unsigned long product_version_ms;
+ unsigned long product_version_ls;
+ /* The file flags mask. */
+ unsigned long file_flags_mask;
+ /* The file flags. */
+ unsigned long file_flags;
+ /* The OS type. */
+ unsigned long file_os;
+ /* The file type. */
+ unsigned long file_type;
+ /* The file subtype. */
+ unsigned long file_subtype;
+ /* The date, which in Windows is two 32 bit integers. */
+ unsigned long file_date_ms;
+ unsigned long file_date_ls;
+};
+
+/* A list of variable version information. */
+
+struct ver_info
+{
+ /* Next item. */
+ struct ver_info *next;
+ /* Type of data. */
+ enum { VERINFO_STRING, VERINFO_VAR } type;
+ union
+ {
+ /* StringFileInfo data. */
+ struct
+ {
+ /* Language. */
+ unichar *language;
+ /* Strings. */
+ struct ver_stringinfo *strings;
+ } string;
+ /* VarFileInfo data. */
+ struct
+ {
+ /* Key. */
+ unichar *key;
+ /* Values. */
+ struct ver_varinfo *var;
+ } var;
+ } u;
+};
+
+/* A list of string version information. */
+
+struct ver_stringinfo
+{
+ /* Next string. */
+ struct ver_stringinfo *next;
+ /* Key. */
+ unichar *key;
+ /* Value. */
+ unichar *value;
+};
+
+/* A list of variable version information. */
+
+struct ver_varinfo
+{
+ /* Next item. */
+ struct ver_varinfo *next;
+ /* Language ID. */
+ unsigned short language;
+ /* Character set ID. */
+ unsigned short charset;
+};
+
+/* This structure is used when converting resource information to
+ binary. */
+
+struct bindata
+{
+ /* Next data. */
+ struct bindata *next;
+ /* Length of data. */
+ unsigned long length;
+ /* Data. */
+ unsigned char *data;
+};
+
+/* Function declarations. */
+
+extern struct res_directory *read_rc_file
+ PARAMS ((const char *, const char *, const char *, int));
+extern struct res_directory *read_res_file PARAMS ((const char *));
+extern struct res_directory *read_coff_rsrc
+ PARAMS ((const char *, const char *));
+extern void write_rc_file
+ PARAMS ((const char *, const struct res_directory *));
+extern void write_res_file
+ PARAMS ((const char *, const struct res_directory *));
+extern void write_coff_file
+ PARAMS ((const char *, const char *, const struct res_directory *));
+
+extern struct res_resource *bin_to_res
+ PARAMS ((struct res_id, const unsigned char *, unsigned long, int));
+extern struct bindata *res_to_bin PARAMS ((const struct res_resource *, int));
+
+extern FILE *open_file_search
+ PARAMS ((const char *, const char *, const char *, char **));
+
+extern PTR res_alloc PARAMS ((size_t));
+extern PTR reswr_alloc PARAMS ((size_t));
+
+/* Resource ID handling. */
+
+extern int res_id_cmp PARAMS ((struct res_id, struct res_id));
+extern void res_id_print PARAMS ((FILE *, struct res_id, int));
+extern void res_ids_print PARAMS ((FILE *, int, const struct res_id *));
+extern void res_string_to_id PARAMS ((struct res_id *, const char *));
+
+/* Manipulation of the resource tree. */
+
+extern struct res_resource *define_resource
+ PARAMS ((struct res_directory **, int, const struct res_id *, int));
+extern struct res_resource *define_standard_resource
+ PARAMS ((struct res_directory **, int, struct res_id, int, int));
+
+extern int extended_dialog PARAMS ((const struct dialog *));
+extern int extended_menu PARAMS ((const struct menu *));
+
+/* Communication between the rc file support and the parser and lexer. */
+
+extern int yydebug;
+extern FILE *yyin;
+extern char *rc_filename;
+extern int rc_lineno;
+extern int yyparse PARAMS ((void));
+extern int yylex PARAMS ((void));
+extern void yyerror PARAMS ((const char *));
+extern void rcparse_warning PARAMS ((const char *));
+extern void rcparse_set_language PARAMS ((int));
+extern void rcparse_discard_strings PARAMS ((void));
+extern void rcparse_rcdata PARAMS ((void));
+extern void rcparse_normal PARAMS ((void));
+
+extern void define_accelerator
+ PARAMS ((struct res_id, const struct res_res_info *, struct accelerator *));
+extern void define_bitmap
+ PARAMS ((struct res_id, const struct res_res_info *, const char *));
+extern void define_cursor
+ PARAMS ((struct res_id, const struct res_res_info *, const char *));
+extern void define_dialog
+ PARAMS ((struct res_id, const struct res_res_info *, const struct dialog *));
+extern struct dialog_control *define_control
+ PARAMS ((const char *, unsigned long, unsigned long, unsigned long,
+ unsigned long, unsigned long, unsigned long, unsigned long,
+ unsigned long));
+extern void define_font
+ PARAMS ((struct res_id, const struct res_res_info *, const char *));
+extern void define_icon
+ PARAMS ((struct res_id, const struct res_res_info *, const char *));
+extern void define_menu
+ PARAMS ((struct res_id, const struct res_res_info *, struct menuitem *));
+extern struct menuitem *define_menuitem
+ PARAMS ((const char *, int, unsigned long, unsigned long, unsigned long,
+ struct menuitem *));
+extern void define_messagetable
+ PARAMS ((struct res_id, const struct res_res_info *, const char *));
+extern void define_rcdata
+ PARAMS ((struct res_id, const struct res_res_info *, struct rcdata_item *));
+extern struct rcdata_item *define_rcdata_string
+ PARAMS ((const char *, unsigned long));
+extern struct rcdata_item *define_rcdata_number PARAMS ((unsigned long, int));
+extern void define_stringtable
+ PARAMS ((const struct res_res_info *, unsigned long, const char *));
+extern void define_user_data
+ PARAMS ((struct res_id, struct res_id, const struct res_res_info *,
+ struct rcdata_item *));
+extern void define_user_file
+ PARAMS ((struct res_id, struct res_id, const struct res_res_info *,
+ const char *));
+extern void define_versioninfo
+ PARAMS ((struct res_id, int, struct fixed_versioninfo *,
+ struct ver_info *));
+extern struct ver_info *append_ver_stringfileinfo
+ PARAMS ((struct ver_info *, const char *, struct ver_stringinfo *));
+extern struct ver_info *append_ver_varfileinfo
+ PARAMS ((struct ver_info *, const char *, struct ver_varinfo *));
+extern struct ver_stringinfo *append_verval
+ PARAMS ((struct ver_stringinfo *, const char *, const char *));
+extern struct ver_varinfo *append_vertrans
+ PARAMS ((struct ver_varinfo *, unsigned long, unsigned long));
diff --git a/binutils/winduni.c b/binutils/winduni.c
new file mode 100644
index 00000000000..d79f47a3d7b
--- /dev/null
+++ b/binutils/winduni.c
@@ -0,0 +1,147 @@
+/* winduni.c -- unicode support for the windres program.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains unicode support routines for the windres
+ program. Ideally, we would have generic unicode support which
+ would work on all systems. However, we don't. Instead, on a
+ Windows host, we are prepared to call some Windows routines. This
+ means that we will generate different output on Windows and Unix
+ hosts, but that seems better than not really supporting unicode at
+ all. */
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "winduni.h"
+
+#include <ctype.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+/* Convert an ASCII string to a unicode string. We just copy it,
+ expanding chars to shorts, rather than doing something intelligent. */
+
+void
+unicode_from_ascii (length, unicode, ascii)
+ int *length;
+ unichar **unicode;
+ const char *ascii;
+{
+ int len;
+ const char *s;
+ unsigned short *w;
+
+ len = strlen (ascii);
+
+ if (length != NULL)
+ *length = len;
+
+ *unicode = ((unichar *) res_alloc ((len + 1) * sizeof (unichar)));
+
+#ifdef _WIN32
+ /* FIXME: On Windows, we should be using MultiByteToWideChar to set
+ the length. */
+ MultiByteToWideChar (CP_ACP, 0, ascii, len + 1, *unicode, len + 1);
+#else
+ for (s = ascii, w = *unicode; *s != '\0'; s++, w++)
+ *w = *s & 0xff;
+ *w = 0;
+#endif
+}
+
+/* Print the unicode string UNICODE to the file E. LENGTH is the
+ number of characters to print, or -1 if we should print until the
+ end of the string. FIXME: On a Windows host, we should be calling
+ some Windows function, probably WideCharToMultiByte. */
+
+void
+unicode_print (e, unicode, length)
+ FILE *e;
+ const unichar *unicode;
+ int length;
+{
+ while (1)
+ {
+ unichar ch;
+
+ if (length == 0)
+ return;
+ if (length > 0)
+ --length;
+
+ ch = *unicode;
+
+ if (ch == 0 && length < 0)
+ return;
+
+ ++unicode;
+
+ if ((ch & 0x7f) == ch)
+ {
+ if (ch == '\\')
+ fputs ("\\", e);
+ else if (isprint (ch))
+ putc (ch, e);
+ else
+ {
+ switch (ch)
+ {
+ case ESCAPE_A:
+ fputs ("\\a", e);
+ break;
+
+ case ESCAPE_B:
+ fputs ("\\b", e);
+ break;
+
+ case ESCAPE_F:
+ fputs ("\\f", e);
+ break;
+
+ case ESCAPE_N:
+ fputs ("\\n", e);
+ break;
+
+ case ESCAPE_R:
+ fputs ("\\r", e);
+ break;
+
+ case ESCAPE_T:
+ fputs ("\\t", e);
+ break;
+
+ case ESCAPE_V:
+ fputs ("\\v", e);
+ break;
+
+ default:
+ fprintf (e, "\\%03o", (unsigned int) ch);
+ break;
+ }
+ }
+ }
+ else if ((ch & 0xff) == ch)
+ fprintf (e, "\\%03o", (unsigned int) ch);
+ else
+ fprintf (e, "\\x%x", (unsigned int) ch);
+ }
+}
diff --git a/binutils/winduni.h b/binutils/winduni.h
new file mode 100644
index 00000000000..13a9af2e736
--- /dev/null
+++ b/binutils/winduni.h
@@ -0,0 +1,60 @@
+/* winduni.h -- header file for unicode support for windres program.
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <ansidecl.h>
+
+/* This header file declares the types and functions we use for
+ unicode support in windres. Our unicode support is very limited at
+ present.
+
+ We don't put this stuff in windres.h so that winduni.c doesn't have
+ to include windres.h. winduni.c needs to includes windows.h, and
+ that would conflict with the definitions of Windows macros we
+ already have in windres.h. */
+
+/* We use this type to hold a unicode character. */
+
+typedef unsigned short unichar;
+
+/* Escape character translations. */
+
+#define ESCAPE_A (007)
+#define ESCAPE_B (010)
+#define ESCAPE_F (014)
+#define ESCAPE_N (012)
+#define ESCAPE_R (015)
+#define ESCAPE_T (011)
+#define ESCAPE_V (013)
+
+/* Convert an ASCII string to a unicode string. */
+
+extern void unicode_from_ascii
+ PARAMS ((int *, unichar **, const char *));
+
+/* Print a unicode string to a file. */
+
+extern void unicode_print PARAMS ((FILE *, const unichar *, int));
+
+/* Windres support routine called by unicode_from_ascii. This is both
+ here and in windres.h. It should probably be in a separate header
+ file, but it hardly seems worth it for one function. */
+
+extern PTR res_alloc PARAMS ((size_t));
diff --git a/binutils/wrstabs.c b/binutils/wrstabs.c
new file mode 100644
index 00000000000..e428174f5b2
--- /dev/null
+++ b/binutils/wrstabs.c
@@ -0,0 +1,2416 @@
+/* wrstabs.c -- Output stabs debugging information
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file contains code which writes out stabs debugging
+ information. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "bfd.h"
+#include "bucomm.h"
+#include "libiberty.h"
+#include "debug.h"
+#include "budbg.h"
+
+/* Meaningless definition needs by aout64.h. FIXME. */
+#define BYTES_IN_WORD 4
+
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+
+/* The size of a stabs symbol. This presumes 32 bit values. */
+
+#define STAB_SYMBOL_SIZE (12)
+
+/* An entry in a string hash table. */
+
+struct string_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Next string in this table. */
+ struct string_hash_entry *next;
+ /* Index in string table. */
+ long index;
+ /* Size of type if this is a typedef. */
+ unsigned int size;
+};
+
+/* A string hash table. */
+
+struct string_hash_table
+{
+ struct bfd_hash_table table;
+};
+
+/* The type stack. Each element on the stack is a string. */
+
+struct stab_type_stack
+{
+ /* The next element on the stack. */
+ struct stab_type_stack *next;
+ /* This element as a string. */
+ char *string;
+ /* The type index of this element. */
+ long index;
+ /* The size of the type. */
+ unsigned int size;
+ /* Whether type string defines a new type. */
+ boolean definition;
+ /* String defining struct fields. */
+ char *fields;
+ /* NULL terminated array of strings defining base classes for a
+ class. */
+ char **baseclasses;
+ /* String defining class methods. */
+ char *methods;
+ /* String defining vtable pointer for a class. */
+ char *vtable;
+};
+
+/* This structure is used to keep track of type indices for tagged
+ types. */
+
+struct stab_tag
+{
+ /* The type index. */
+ long index;
+ /* The tag name. */
+ const char *tag;
+ /* The kind of type. This is set to DEBUG_KIND_ILLEGAL when the
+ type is defined. */
+ enum debug_type_kind kind;
+ /* The size of the struct. */
+ unsigned int size;
+};
+
+/* We remember various sorts of type indices. They are not related,
+ but, for convenience, we keep all the information in this
+ structure. */
+
+struct stab_type_cache
+{
+ /* The void type index. */
+ long void_type;
+ /* Signed integer type indices, indexed by size - 1. */
+ long signed_integer_types[8];
+ /* Unsigned integer type indices, indexed by size - 1. */
+ long unsigned_integer_types[8];
+ /* Floating point types, indexed by size - 1. */
+ long float_types[16];
+ /* Pointers to types, indexed by the type index. */
+ long *pointer_types;
+ size_t pointer_types_alloc;
+ /* Functions returning types, indexed by the type index. */
+ long *function_types;
+ size_t function_types_alloc;
+ /* References to types, indexed by the type index. */
+ long *reference_types;
+ size_t reference_types_alloc;
+ /* Struct/union/class type indices, indexed by the struct id. */
+ struct stab_tag *struct_types;
+ size_t struct_types_alloc;
+};
+
+/* This is the handle passed through debug_write. */
+
+struct stab_write_handle
+{
+ /* The BFD. */
+ bfd *abfd;
+ /* This buffer holds the symbols. */
+ bfd_byte *symbols;
+ size_t symbols_size;
+ size_t symbols_alloc;
+ /* This is a list of hash table entries for the strings. */
+ struct string_hash_entry *strings;
+ /* The last string hash table entry. */
+ struct string_hash_entry *last_string;
+ /* The size of the strings. */
+ size_t strings_size;
+ /* This hash table eliminates duplicate strings. */
+ struct string_hash_table strhash;
+ /* The type stack. */
+ struct stab_type_stack *type_stack;
+ /* The next type index. */
+ long type_index;
+ /* The type cache. */
+ struct stab_type_cache type_cache;
+ /* A mapping from typedef names to type indices. */
+ struct string_hash_table typedef_hash;
+ /* If this is not -1, it is the offset to the most recent N_SO
+ symbol, and the value of that symbol needs to be set. */
+ long so_offset;
+ /* If this is not -1, it is the offset to the most recent N_FUN
+ symbol, and the value of that symbol needs to be set. */
+ long fun_offset;
+ /* The last text section address seen. */
+ bfd_vma last_text_address;
+ /* The block nesting depth. */
+ unsigned int nesting;
+ /* The function address. */
+ bfd_vma fnaddr;
+ /* A pending LBRAC symbol. */
+ bfd_vma pending_lbrac;
+ /* The current line number file name. */
+ const char *lineno_filename;
+};
+
+static struct bfd_hash_entry *string_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean stab_write_symbol
+ PARAMS ((struct stab_write_handle *, int, int, bfd_vma, const char *));
+static boolean stab_push_string
+ PARAMS ((struct stab_write_handle *, const char *, long, boolean,
+ unsigned int));
+static boolean stab_push_defined_type
+ PARAMS ((struct stab_write_handle *, long, unsigned int));
+static char *stab_pop_type PARAMS ((struct stab_write_handle *));
+static boolean stab_modify_type
+ PARAMS ((struct stab_write_handle *, int, unsigned int, long **, size_t *));
+static long stab_get_struct_index
+ PARAMS ((struct stab_write_handle *, const char *, unsigned int,
+ enum debug_type_kind, unsigned int *));
+static boolean stab_class_method_var
+ PARAMS ((struct stab_write_handle *, const char *, enum debug_visibility,
+ boolean, boolean, boolean, bfd_vma, boolean));
+
+static boolean stab_start_compilation_unit PARAMS ((PTR, const char *));
+static boolean stab_start_source PARAMS ((PTR, const char *));
+static boolean stab_empty_type PARAMS ((PTR));
+static boolean stab_void_type PARAMS ((PTR));
+static boolean stab_int_type PARAMS ((PTR, unsigned int, boolean));
+static boolean stab_float_type PARAMS ((PTR, unsigned int));
+static boolean stab_complex_type PARAMS ((PTR, unsigned int));
+static boolean stab_bool_type PARAMS ((PTR, unsigned int));
+static boolean stab_enum_type
+ PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
+static boolean stab_pointer_type PARAMS ((PTR));
+static boolean stab_function_type PARAMS ((PTR, int, boolean));
+static boolean stab_reference_type PARAMS ((PTR));
+static boolean stab_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
+static boolean stab_array_type
+ PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
+static boolean stab_set_type PARAMS ((PTR, boolean));
+static boolean stab_offset_type PARAMS ((PTR));
+static boolean stab_method_type PARAMS ((PTR, boolean, int, boolean));
+static boolean stab_const_type PARAMS ((PTR));
+static boolean stab_volatile_type PARAMS ((PTR));
+static boolean stab_start_struct_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
+static boolean stab_struct_field
+ PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
+static boolean stab_end_struct_type PARAMS ((PTR));
+static boolean stab_start_class_type
+ PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
+ boolean));
+static boolean stab_class_static_member
+ PARAMS ((PTR, const char *, const char *, enum debug_visibility));
+static boolean stab_class_baseclass
+ PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
+static boolean stab_class_start_method PARAMS ((PTR, const char *));
+static boolean stab_class_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
+ bfd_vma, boolean));
+static boolean stab_class_static_method_variant
+ PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
+static boolean stab_class_end_method PARAMS ((PTR));
+static boolean stab_end_class_type PARAMS ((PTR));
+static boolean stab_typedef_type PARAMS ((PTR, const char *));
+static boolean stab_tag_type
+ PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
+static boolean stab_typdef PARAMS ((PTR, const char *));
+static boolean stab_tag PARAMS ((PTR, const char *));
+static boolean stab_int_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean stab_float_constant PARAMS ((PTR, const char *, double));
+static boolean stab_typed_constant PARAMS ((PTR, const char *, bfd_vma));
+static boolean stab_variable
+ PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
+static boolean stab_start_function PARAMS ((PTR, const char *, boolean));
+static boolean stab_function_parameter
+ PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
+static boolean stab_start_block PARAMS ((PTR, bfd_vma));
+static boolean stab_end_block PARAMS ((PTR, bfd_vma));
+static boolean stab_end_function PARAMS ((PTR));
+static boolean stab_lineno
+ PARAMS ((PTR, const char *, unsigned long, bfd_vma));
+
+static const struct debug_write_fns stab_fns =
+{
+ stab_start_compilation_unit,
+ stab_start_source,
+ stab_empty_type,
+ stab_void_type,
+ stab_int_type,
+ stab_float_type,
+ stab_complex_type,
+ stab_bool_type,
+ stab_enum_type,
+ stab_pointer_type,
+ stab_function_type,
+ stab_reference_type,
+ stab_range_type,
+ stab_array_type,
+ stab_set_type,
+ stab_offset_type,
+ stab_method_type,
+ stab_const_type,
+ stab_volatile_type,
+ stab_start_struct_type,
+ stab_struct_field,
+ stab_end_struct_type,
+ stab_start_class_type,
+ stab_class_static_member,
+ stab_class_baseclass,
+ stab_class_start_method,
+ stab_class_method_variant,
+ stab_class_static_method_variant,
+ stab_class_end_method,
+ stab_end_class_type,
+ stab_typedef_type,
+ stab_tag_type,
+ stab_typdef,
+ stab_tag,
+ stab_int_constant,
+ stab_float_constant,
+ stab_typed_constant,
+ stab_variable,
+ stab_start_function,
+ stab_function_parameter,
+ stab_start_block,
+ stab_end_block,
+ stab_end_function,
+ stab_lineno
+};
+
+/* Routine to create an entry in a string hash table. */
+
+static struct bfd_hash_entry *
+string_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct string_hash_entry *ret = (struct string_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct string_hash_entry *) NULL)
+ ret = ((struct string_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
+ if (ret == (struct string_hash_entry *) NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct string_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret)
+ {
+ /* Initialize the local fields. */
+ ret->next = NULL;
+ ret->index = -1;
+ ret->size = 0;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in a string hash table. */
+
+#define string_hash_lookup(t, string, create, copy) \
+ ((struct string_hash_entry *) \
+ bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
+
+/* Add a symbol to the stabs debugging information we are building. */
+
+static boolean
+stab_write_symbol (info, type, desc, value, string)
+ struct stab_write_handle *info;
+ int type;
+ int desc;
+ bfd_vma value;
+ const char *string;
+{
+ bfd_size_type strx;
+ bfd_byte sym[STAB_SYMBOL_SIZE];
+
+ if (string == NULL)
+ strx = 0;
+ else
+ {
+ struct string_hash_entry *h;
+
+ h = string_hash_lookup (&info->strhash, string, true, true);
+ if (h == NULL)
+ {
+ fprintf (stderr, _("string_hash_lookup failed: %s\n"),
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+ if (h->index != -1)
+ strx = h->index;
+ else
+ {
+ strx = info->strings_size;
+ h->index = strx;
+ if (info->last_string == NULL)
+ info->strings = h;
+ else
+ info->last_string->next = h;
+ info->last_string = h;
+ info->strings_size += strlen (string) + 1;
+ }
+ }
+
+ /* This presumes 32 bit values. */
+ bfd_put_32 (info->abfd, strx, sym);
+ bfd_put_8 (info->abfd, type, sym + 4);
+ bfd_put_8 (info->abfd, 0, sym + 5);
+ bfd_put_16 (info->abfd, desc, sym + 6);
+ bfd_put_32 (info->abfd, value, sym + 8);
+
+ if (info->symbols_size + STAB_SYMBOL_SIZE > info->symbols_alloc)
+ {
+ info->symbols_alloc *= 2;
+ info->symbols = (bfd_byte *) xrealloc (info->symbols,
+ info->symbols_alloc);
+ }
+
+ memcpy (info->symbols + info->symbols_size, sym, STAB_SYMBOL_SIZE);
+
+ info->symbols_size += STAB_SYMBOL_SIZE;
+
+ return true;
+}
+
+/* Push a string on to the type stack. */
+
+static boolean
+stab_push_string (info, string, index, definition, size)
+ struct stab_write_handle *info;
+ const char *string;
+ long index;
+ boolean definition;
+ unsigned int size;
+{
+ struct stab_type_stack *s;
+
+ s = (struct stab_type_stack *) xmalloc (sizeof *s);
+ s->string = xstrdup (string);
+ s->index = index;
+ s->definition = definition;
+ s->size = size;
+
+ s->fields = NULL;
+ s->baseclasses = NULL;
+ s->methods = NULL;
+ s->vtable = NULL;
+
+ s->next = info->type_stack;
+ info->type_stack = s;
+
+ return true;
+}
+
+/* Push a type index which has already been defined. */
+
+static boolean
+stab_push_defined_type (info, index, size)
+ struct stab_write_handle *info;
+ long index;
+ unsigned int size;
+{
+ char buf[20];
+
+ sprintf (buf, "%ld", index);
+ return stab_push_string (info, buf, index, false, size);
+}
+
+/* Pop a type off the type stack. The caller is responsible for
+ freeing the string. */
+
+static char *
+stab_pop_type (info)
+ struct stab_write_handle *info;
+{
+ struct stab_type_stack *s;
+ char *ret;
+
+ s = info->type_stack;
+ assert (s != NULL);
+
+ info->type_stack = s->next;
+
+ ret = s->string;
+
+ free (s);
+
+ return ret;
+}
+
+/* The general routine to write out stabs in sections debugging
+ information. This accumulates the stabs symbols and the strings in
+ two obstacks. We can't easily write out the information as we go
+ along, because we need to know the section sizes before we can
+ write out the section contents. ABFD is the BFD and DHANDLE is the
+ handle for the debugging information. This sets *PSYMS to point to
+ the symbols, *PSYMSIZE the size of the symbols, *PSTRINGS to the
+ strings, and *PSTRINGSIZE to the size of the strings. */
+
+boolean
+write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize,
+ pstrings, pstringsize)
+ bfd *abfd;
+ PTR dhandle;
+ bfd_byte **psyms;
+ bfd_size_type *psymsize;
+ bfd_byte **pstrings;
+ bfd_size_type *pstringsize;
+{
+ struct stab_write_handle info;
+ struct string_hash_entry *h;
+ bfd_byte *p;
+
+ info.abfd = abfd;
+
+ info.symbols_size = 0;
+ info.symbols_alloc = 500;
+ info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc);
+
+ info.strings = NULL;
+ info.last_string = NULL;
+ /* Reserve 1 byte for a null byte. */
+ info.strings_size = 1;
+
+ if (! bfd_hash_table_init (&info.strhash.table, string_hash_newfunc)
+ || ! bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc))
+ {
+ fprintf (stderr, "bfd_hash_table_init_failed: %s\n",
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ info.type_stack = NULL;
+ info.type_index = 1;
+ memset (&info.type_cache, 0, sizeof info.type_cache);
+ info.so_offset = -1;
+ info.fun_offset = -1;
+ info.last_text_address = 0;
+ info.nesting = 0;
+ info.fnaddr = 0;
+ info.pending_lbrac = (bfd_vma) -1;
+
+ /* The initial symbol holds the string size. */
+ if (! stab_write_symbol (&info, 0, 0, 0, (const char *) NULL))
+ return false;
+
+ /* Output an initial N_SO symbol. */
+ info.so_offset = info.symbols_size;
+ if (! stab_write_symbol (&info, N_SO, 0, 0, bfd_get_filename (abfd)))
+ return false;
+
+ if (! debug_write (dhandle, &stab_fns, (PTR) &info))
+ return false;
+
+ assert (info.pending_lbrac == (bfd_vma) -1);
+
+ /* Output a trailing N_SO. */
+ if (! stab_write_symbol (&info, N_SO, 0, info.last_text_address,
+ (const char *) NULL))
+ return false;
+
+ /* Put the string size in the initial symbol. */
+ bfd_put_32 (abfd, info.strings_size, info.symbols + 8);
+
+ *psyms = info.symbols;
+ *psymsize = info.symbols_size;
+
+ *pstringsize = info.strings_size;
+ *pstrings = (bfd_byte *) xmalloc (info.strings_size);
+
+ p = *pstrings;
+ *p++ = '\0';
+ for (h = info.strings; h != NULL; h = h->next)
+ {
+ strcpy ((char *) p, h->root.string);
+ p += strlen ((char *) p) + 1;
+ }
+
+ return true;
+}
+
+/* Start writing out information for a compilation unit. */
+
+static boolean
+stab_start_compilation_unit (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ /* We would normally output an N_SO symbol here. However, that
+ would force us to reset all of our type information. I think we
+ will be better off just outputting an N_SOL symbol, and not
+ worrying about splitting information between files. */
+
+ info->lineno_filename = filename;
+
+ return stab_write_symbol (info, N_SOL, 0, 0, filename);
+}
+
+/* Start writing out information for a particular source file. */
+
+static boolean
+stab_start_source (p, filename)
+ PTR p;
+ const char *filename;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ /* FIXME: The symbol's value is supposed to be the text section
+ address. However, we would have to fill it in later, and gdb
+ doesn't care, so we don't bother with it. */
+
+ info->lineno_filename = filename;
+
+ return stab_write_symbol (info, N_SOL, 0, 0, filename);
+}
+
+/* Push an empty type. This shouldn't normally happen. We just use a
+ void type. */
+
+static boolean
+stab_empty_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ /* We don't call stab_void_type if the type is not yet defined,
+ because that might screw up the typedef. */
+
+ if (info->type_cache.void_type != 0)
+ return stab_push_defined_type (info, info->type_cache.void_type, 0);
+ else
+ {
+ long index;
+ char buf[40];
+
+ index = info->type_index;
+ ++info->type_index;
+
+ sprintf (buf, "%ld=%ld", index, index);
+
+ return stab_push_string (info, buf, index, false, 0);
+ }
+}
+
+/* Push a void type. */
+
+static boolean
+stab_void_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ if (info->type_cache.void_type != 0)
+ return stab_push_defined_type (info, info->type_cache.void_type, 0);
+ else
+ {
+ long index;
+ char buf[40];
+
+ index = info->type_index;
+ ++info->type_index;
+
+ info->type_cache.void_type = index;
+
+ sprintf (buf, "%ld=%ld", index, index);
+
+ return stab_push_string (info, buf, index, true, 0);
+ }
+}
+
+/* Push an integer type. */
+
+static boolean
+stab_int_type (p, size, unsignedp)
+ PTR p;
+ unsigned int size;
+ boolean unsignedp;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ long *cache;
+
+ if (size <= 0 || (size > sizeof (long) && size != 8))
+ {
+ fprintf (stderr, _("stab_int_type: bad size %u\n"), size);
+ return false;
+ }
+
+ if (unsignedp)
+ cache = info->type_cache.signed_integer_types;
+ else
+ cache = info->type_cache.unsigned_integer_types;
+
+ if (cache[size - 1] != 0)
+ return stab_push_defined_type (info, cache[size - 1], size);
+ else
+ {
+ long index;
+ char buf[100];
+
+ index = info->type_index;
+ ++info->type_index;
+
+ cache[size - 1] = index;
+
+ sprintf (buf, "%ld=r%ld;", index, index);
+ if (unsignedp)
+ {
+ strcat (buf, "0;");
+ if (size < sizeof (long))
+ sprintf (buf + strlen (buf), "%ld;", ((long) 1 << (size * 8)) - 1);
+ else if (size == sizeof (long))
+ strcat (buf, "-1;");
+ else if (size == 8)
+ strcat (buf, "01777777777777777777777;");
+ else
+ abort ();
+ }
+ else
+ {
+ if (size <= sizeof (long))
+ sprintf (buf + strlen (buf), "%ld;%ld;",
+ (long) - ((unsigned long) 1 << (size * 8 - 1)),
+ (long) (((unsigned long) 1 << (size * 8 - 1)) - 1));
+ else if (size == 8)
+ strcat (buf, "01000000000000000000000;0777777777777777777777;");
+ else
+ abort ();
+ }
+
+ return stab_push_string (info, buf, index, true, size);
+ }
+}
+
+/* Push a floating point type. */
+
+static boolean
+stab_float_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ if (size > 0
+ && size - 1 < (sizeof info->type_cache.float_types
+ / sizeof info->type_cache.float_types[0])
+ && info->type_cache.float_types[size - 1] != 0)
+ return stab_push_defined_type (info,
+ info->type_cache.float_types[size - 1],
+ size);
+ else
+ {
+ long index;
+ char *int_type;
+ char buf[50];
+
+ /* Floats are defined as a subrange of int. */
+ if (! stab_int_type (info, 4, false))
+ return false;
+ int_type = stab_pop_type (info);
+
+ index = info->type_index;
+ ++info->type_index;
+
+ if (size > 0
+ && size - 1 < (sizeof info->type_cache.float_types
+ / sizeof info->type_cache.float_types[0]))
+ info->type_cache.float_types[size - 1] = index;
+
+ sprintf (buf, "%ld=r%s;%u;0;", index, int_type, size);
+
+ free (int_type);
+
+ return stab_push_string (info, buf, index, true, size);
+ }
+}
+
+/* Push a complex type. */
+
+static boolean
+stab_complex_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char buf[50];
+ long index;
+
+ index = info->type_index;
+ ++info->type_index;
+
+ sprintf (buf, "%ld=r%ld;%u;0;", index, index, size);
+
+ return stab_push_string (info, buf, index, true, size * 2);
+}
+
+/* Push a boolean type. We use an XCOFF predefined type, since gdb
+ always recognizes them. */
+
+static boolean
+stab_bool_type (p, size)
+ PTR p;
+ unsigned int size;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ long index;
+
+ switch (size)
+ {
+ case 1:
+ index = -21;
+ break;
+
+ case 2:
+ index = -22;
+ break;
+
+ default:
+ case 4:
+ index = -16;
+ break;
+
+ case 8:
+ index = -33;
+ break;
+ }
+
+ return stab_push_defined_type (info, index, size);
+}
+
+/* Push an enum type. */
+
+static boolean
+stab_enum_type (p, tag, names, vals)
+ PTR p;
+ const char *tag;
+ const char **names;
+ bfd_signed_vma *vals;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ size_t len;
+ const char **pn;
+ char *buf;
+ long index = 0;
+ bfd_signed_vma *pv;
+
+ if (names == NULL)
+ {
+ assert (tag != NULL);
+
+ buf = (char *) xmalloc (10 + strlen (tag));
+ sprintf (buf, "xe%s:", tag);
+ /* FIXME: The size is just a guess. */
+ if (! stab_push_string (info, buf, 0, false, 4))
+ return false;
+ free (buf);
+ return true;
+ }
+
+ len = 10;
+ if (tag != NULL)
+ len += strlen (tag);
+ for (pn = names; *pn != NULL; pn++)
+ len += strlen (*pn) + 20;
+
+ buf = (char *) xmalloc (len);
+
+ if (tag == NULL)
+ strcpy (buf, "e");
+ else
+ {
+ index = info->type_index;
+ ++info->type_index;
+ sprintf (buf, "%s:T%ld=e", tag, index);
+ }
+
+ for (pn = names, pv = vals; *pn != NULL; pn++, pv++)
+ sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv);
+ strcat (buf, ";");
+
+ if (tag == NULL)
+ {
+ /* FIXME: The size is just a guess. */
+ if (! stab_push_string (info, buf, 0, false, 4))
+ return false;
+ }
+ else
+ {
+ /* FIXME: The size is just a guess. */
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)
+ || ! stab_push_defined_type (info, index, 4))
+ return false;
+ }
+
+ free (buf);
+
+ return true;
+}
+
+/* Push a modification of the top type on the stack. Cache the
+ results in CACHE and CACHE_ALLOC. */
+
+static boolean
+stab_modify_type (info, mod, size, cache, cache_alloc)
+ struct stab_write_handle *info;
+ int mod;
+ unsigned int size;
+ long **cache;
+ size_t *cache_alloc;
+{
+ long targindex;
+ long index;
+ char *s, *buf;
+
+ assert (info->type_stack != NULL);
+ targindex = info->type_stack->index;
+
+ if (targindex <= 0
+ || cache == NULL)
+ {
+ boolean definition;
+
+ /* Either the target type has no index, or we aren't caching
+ this modifier. Either way we have no way of recording the
+ new type, so we don't bother to define one. */
+ definition = info->type_stack->definition;
+ s = stab_pop_type (info);
+ buf = (char *) xmalloc (strlen (s) + 2);
+ sprintf (buf, "%c%s", mod, s);
+ free (s);
+ if (! stab_push_string (info, buf, 0, definition, size))
+ return false;
+ free (buf);
+ }
+ else
+ {
+ if ((size_t) targindex >= *cache_alloc)
+ {
+ size_t alloc;
+
+ alloc = *cache_alloc;
+ if (alloc == 0)
+ alloc = 10;
+ while ((size_t) targindex >= alloc)
+ alloc *= 2;
+ *cache = (long *) xrealloc (*cache, alloc * sizeof (long));
+ memset (*cache + *cache_alloc, 0,
+ (alloc - *cache_alloc) * sizeof (long));
+ *cache_alloc = alloc;
+ }
+
+ index = (*cache)[targindex];
+ if (index != 0 && ! info->type_stack->definition)
+ {
+ /* We have already defined a modification of this type, and
+ the entry on the type stack is not a definition, so we
+ can safely discard it (we may have a definition on the
+ stack, even if we already defined a modification, if it
+ is a struct which we did not define at the time it was
+ referenced). */
+ free (stab_pop_type (info));
+ if (! stab_push_defined_type (info, index, size))
+ return false;
+ }
+ else
+ {
+ index = info->type_index;
+ ++info->type_index;
+
+ s = stab_pop_type (info);
+ buf = (char *) xmalloc (strlen (s) + 20);
+ sprintf (buf, "%ld=%c%s", index, mod, s);
+ free (s);
+
+ (*cache)[targindex] = index;
+
+ if (! stab_push_string (info, buf, index, true, size))
+ return false;
+
+ free (buf);
+ }
+ }
+
+ return true;
+}
+
+/* Push a pointer type. */
+
+static boolean
+stab_pointer_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ /* FIXME: The size should depend upon the architecture. */
+ return stab_modify_type (info, '*', 4, &info->type_cache.pointer_types,
+ &info->type_cache.pointer_types_alloc);
+}
+
+/* Push a function type. */
+
+static boolean
+stab_function_type (p, argcount, varargs)
+ PTR p;
+ int argcount;
+ boolean varargs;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ int i;
+
+ /* We have no way to represent the argument types, so we just
+ discard them. However, if they define new types, we must output
+ them. We do this by producing empty typedefs. */
+ for (i = 0; i < argcount; i++)
+ {
+ if (! info->type_stack->definition)
+ free (stab_pop_type (info));
+ else
+ {
+ char *s, *buf;
+
+ s = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (s) + 3);
+ sprintf (buf, ":t%s", s);
+ free (s);
+
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
+ return false;
+
+ free (buf);
+ }
+ }
+
+ return stab_modify_type (info, 'f', 0, &info->type_cache.function_types,
+ &info->type_cache.function_types_alloc);
+}
+
+/* Push a reference type. */
+
+static boolean
+stab_reference_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ /* FIXME: The size should depend upon the architecture. */
+ return stab_modify_type (info, '&', 4, &info->type_cache.reference_types,
+ &info->type_cache.reference_types_alloc);
+}
+
+/* Push a range type. */
+
+static boolean
+stab_range_type (p, low, high)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ unsigned int size;
+ char *s, *buf;
+
+ definition = info->type_stack->definition;
+ size = info->type_stack->size;
+
+ s = stab_pop_type (info);
+ buf = (char *) xmalloc (strlen (s) + 100);
+ sprintf (buf, "r%s;%ld;%ld;", s, (long) low, (long) high);
+ free (s);
+
+ if (! stab_push_string (info, buf, 0, definition, size))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Push an array type. */
+
+static boolean
+stab_array_type (p, low, high, stringp)
+ PTR p;
+ bfd_signed_vma low;
+ bfd_signed_vma high;
+ boolean stringp;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ unsigned int element_size;
+ char *range, *element, *buf;
+ long index;
+ unsigned int size;
+
+ definition = info->type_stack->definition;
+ range = stab_pop_type (info);
+
+ definition = definition || info->type_stack->definition;
+ element_size = info->type_stack->size;
+ element = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (range) + strlen (element) + 100);
+
+ if (! stringp)
+ {
+ index = 0;
+ *buf = '\0';
+ }
+ else
+ {
+ /* We need to define a type in order to include the string
+ attribute. */
+ index = info->type_index;
+ ++info->type_index;
+ definition = true;
+ sprintf (buf, "%ld=@S;", index);
+ }
+
+ sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s",
+ range, (long) low, (long) high, element);
+ free (range);
+ free (element);
+
+ if (high < low)
+ size = 0;
+ else
+ size = element_size * ((high - low) + 1);
+ if (! stab_push_string (info, buf, index, definition, size))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Push a set type. */
+
+static boolean
+stab_set_type (p, bitstringp)
+ PTR p;
+ boolean bitstringp;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ char *s, *buf;
+ long index;
+
+ definition = info->type_stack->definition;
+
+ s = stab_pop_type (info);
+ buf = (char *) xmalloc (strlen (s) + 30);
+
+ if (! bitstringp)
+ {
+ *buf = '\0';
+ index = 0;
+ }
+ else
+ {
+ /* We need to define a type in order to include the string
+ attribute. */
+ index = info->type_index;
+ ++info->type_index;
+ definition = true;
+ sprintf (buf, "%ld=@S;", index);
+ }
+
+ sprintf (buf + strlen (buf), "S%s", s);
+ free (s);
+
+ if (! stab_push_string (info, buf, index, definition, 0))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Push an offset type. */
+
+static boolean
+stab_offset_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ char *target, *base, *buf;
+
+ definition = info->type_stack->definition;
+ target = stab_pop_type (info);
+
+ definition = definition || info->type_stack->definition;
+ base = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (target) + strlen (base) + 3);
+ sprintf (buf, "@%s,%s", base, target);
+ free (base);
+ free (target);
+
+ if (! stab_push_string (info, buf, 0, definition, 0))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Push a method type. */
+
+static boolean
+stab_method_type (p, domainp, argcount, varargs)
+ PTR p;
+ boolean domainp;
+ int argcount;
+ boolean varargs;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ char *domain, *return_type, *buf;
+ char **args;
+ int i;
+ size_t len;
+
+ /* We don't bother with stub method types, because that would
+ require a mangler for C++ argument types. This will waste space
+ in the debugging output. */
+
+ /* We need a domain. I'm not sure DOMAINP can ever be false,
+ anyhow. */
+ if (! domainp)
+ {
+ if (! stab_empty_type (p))
+ return false;
+ }
+
+ definition = info->type_stack->definition;
+ domain = stab_pop_type (info);
+
+ /* A non-varargs function is indicated by making the last parameter
+ type be void. */
+
+ if (argcount < 0)
+ {
+ args = NULL;
+ argcount = 0;
+ }
+ else if (argcount == 0)
+ {
+ if (varargs)
+ args = NULL;
+ else
+ {
+ args = (char **) xmalloc (1 * sizeof (*args));
+ if (! stab_empty_type (p))
+ return false;
+ definition = definition || info->type_stack->definition;
+ args[0] = stab_pop_type (info);
+ argcount = 1;
+ }
+ }
+ else
+ {
+ args = (char **) xmalloc ((argcount + 1) * sizeof (*args));
+ for (i = argcount - 1; i >= 0; i--)
+ {
+ definition = definition || info->type_stack->definition;
+ args[i] = stab_pop_type (info);
+ }
+ if (! varargs)
+ {
+ if (! stab_empty_type (p))
+ return false;
+ definition = definition || info->type_stack->definition;
+ args[argcount] = stab_pop_type (info);
+ ++argcount;
+ }
+ }
+
+ definition = definition || info->type_stack->definition;
+ return_type = stab_pop_type (info);
+
+ len = strlen (domain) + strlen (return_type) + 10;
+ for (i = 0; i < argcount; i++)
+ len += strlen (args[i]);
+
+ buf = (char *) xmalloc (len);
+
+ sprintf (buf, "#%s,%s", domain, return_type);
+ free (domain);
+ free (return_type);
+ for (i = 0; i < argcount; i++)
+ {
+ strcat (buf, ",");
+ strcat (buf, args[i]);
+ free (args[i]);
+ }
+ strcat (buf, ";");
+
+ if (args != NULL)
+ free (args);
+
+ if (! stab_push_string (info, buf, 0, definition, 0))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Push a const version of a type. */
+
+static boolean
+stab_const_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ return stab_modify_type (info, 'k', info->type_stack->size,
+ (long **) NULL, (size_t *) NULL);
+}
+
+/* Push a volatile version of a type. */
+
+static boolean
+stab_volatile_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ return stab_modify_type (info, 'B', info->type_stack->size,
+ (long **) NULL, (size_t *) NULL);
+}
+
+/* Get the type index to use for a struct/union/class ID. This should
+ return -1 if it fails. */
+
+static long
+stab_get_struct_index (info, tag, id, kind, psize)
+ struct stab_write_handle *info;
+ const char *tag;
+ unsigned int id;
+ enum debug_type_kind kind;
+ unsigned int *psize;
+{
+ if (id >= info->type_cache.struct_types_alloc)
+ {
+ size_t alloc;
+
+ alloc = info->type_cache.struct_types_alloc;
+ if (alloc == 0)
+ alloc = 10;
+ while (id >= alloc)
+ alloc *= 2;
+ info->type_cache.struct_types =
+ (struct stab_tag *) xrealloc (info->type_cache.struct_types,
+ alloc * sizeof (struct stab_tag));
+ memset ((info->type_cache.struct_types
+ + info->type_cache.struct_types_alloc),
+ 0,
+ ((alloc - info->type_cache.struct_types_alloc)
+ * sizeof (struct stab_tag)));
+ info->type_cache.struct_types_alloc = alloc;
+ }
+
+ if (info->type_cache.struct_types[id].index == 0)
+ {
+ info->type_cache.struct_types[id].index = info->type_index;
+ ++info->type_index;
+ info->type_cache.struct_types[id].tag = tag;
+ info->type_cache.struct_types[id].kind = kind;
+ }
+
+ if (kind == DEBUG_KIND_ILLEGAL)
+ {
+ /* This is a definition of the struct. */
+ info->type_cache.struct_types[id].kind = kind;
+ info->type_cache.struct_types[id].size = *psize;
+ }
+ else
+ *psize = info->type_cache.struct_types[id].size;
+
+ return info->type_cache.struct_types[id].index;
+}
+
+/* Start outputting a struct. We ignore the tag, and handle it in
+ stab_tag. */
+
+/*ARGSUSED*/
+static boolean
+stab_start_struct_type (p, tag, id, structp, size)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ long index;
+ boolean definition;
+ char *buf;
+
+ buf = (char *) xmalloc (40);
+
+ if (id == 0)
+ {
+ index = 0;
+ *buf = '\0';
+ definition = false;
+ }
+ else
+ {
+ index = stab_get_struct_index (info, tag, id, DEBUG_KIND_ILLEGAL,
+ &size);
+ if (index < 0)
+ return false;
+ sprintf (buf, "%ld=", index);
+ definition = true;
+ }
+
+ sprintf (buf + strlen (buf), "%c%u",
+ structp ? 's' : 'u',
+ size);
+
+ if (! stab_push_string (info, buf, index, definition, size))
+ return false;
+
+ info->type_stack->fields = (char *) xmalloc (1);
+ info->type_stack->fields[0] = '\0';
+
+ return true;
+}
+
+/* Add a field to a struct. */
+
+static boolean
+stab_struct_field (p, name, bitpos, bitsize, visibility)
+ PTR p;
+ const char *name;
+ bfd_vma bitpos;
+ bfd_vma bitsize;
+ enum debug_visibility visibility;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ unsigned int size;
+ char *s, *n;
+ const char *vis;
+
+ definition = info->type_stack->definition;
+ size = info->type_stack->size;
+ s = stab_pop_type (info);
+
+ /* Add this field to the end of the current struct fields, which is
+ currently on the top of the stack. */
+
+ assert (info->type_stack->fields != NULL);
+ n = (char *) xmalloc (strlen (info->type_stack->fields)
+ + strlen (name)
+ + strlen (s)
+ + 50);
+
+ switch (visibility)
+ {
+ default:
+ abort ();
+
+ case DEBUG_VISIBILITY_PUBLIC:
+ vis = "";
+ break;
+
+ case DEBUG_VISIBILITY_PRIVATE:
+ vis = "/0";
+ break;
+
+ case DEBUG_VISIBILITY_PROTECTED:
+ vis = "/1";
+ break;
+ }
+
+ if (bitsize == 0)
+ {
+ bitsize = size * 8;
+ if (bitsize == 0)
+ fprintf (stderr,
+ _("%s: warning: unknown size for field `%s' in struct\n"),
+ bfd_get_filename (info->abfd), name);
+ }
+
+ sprintf (n, "%s%s:%s%s,%ld,%ld;", info->type_stack->fields, name, vis, s,
+ (long) bitpos, (long) bitsize);
+
+ free (info->type_stack->fields);
+ info->type_stack->fields = n;
+
+ if (definition)
+ info->type_stack->definition = true;
+
+ return true;
+}
+
+/* Finish up a struct. */
+
+static boolean
+stab_end_struct_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ long index;
+ unsigned int size;
+ char *fields, *first, *buf;
+
+ assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+
+ definition = info->type_stack->definition;
+ index = info->type_stack->index;
+ size = info->type_stack->size;
+ fields = info->type_stack->fields;
+ first = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (first) + strlen (fields) + 2);
+ sprintf (buf, "%s%s;", first, fields);
+ free (first);
+ free (fields);
+
+ if (! stab_push_string (info, buf, index, definition, size))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Start outputting a class. */
+
+static boolean
+stab_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
+ PTR p;
+ const char *tag;
+ unsigned int id;
+ boolean structp;
+ unsigned int size;
+ boolean vptr;
+ boolean ownvptr;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ char *vstring;
+
+ if (! vptr || ownvptr)
+ {
+ definition = false;
+ vstring = NULL;
+ }
+ else
+ {
+ definition = info->type_stack->definition;
+ vstring = stab_pop_type (info);
+ }
+
+ if (! stab_start_struct_type (p, tag, id, structp, size))
+ return false;
+
+ if (vptr)
+ {
+ char *vtable;
+
+ if (ownvptr)
+ {
+ assert (info->type_stack->index > 0);
+ vtable = (char *) xmalloc (20);
+ sprintf (vtable, "~%%%ld", info->type_stack->index);
+ }
+ else
+ {
+ vtable = (char *) xmalloc (strlen (vstring) + 3);
+ sprintf (vtable, "~%%%s", vstring);
+ free (vstring);
+ }
+
+ info->type_stack->vtable = vtable;
+ }
+
+ if (definition)
+ info->type_stack->definition = true;
+
+ return true;
+}
+
+/* Add a static member to the class on the type stack. */
+
+static boolean
+stab_class_static_member (p, name, physname, visibility)
+ PTR p;
+ const char *name;
+ const char *physname;
+ enum debug_visibility visibility;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ char *s, *n;
+ const char *vis;
+
+ definition = info->type_stack->definition;
+ s = stab_pop_type (info);
+
+ /* Add this field to the end of the current struct fields, which is
+ currently on the top of the stack. */
+
+ assert (info->type_stack->fields != NULL);
+ n = (char *) xmalloc (strlen (info->type_stack->fields)
+ + strlen (name)
+ + strlen (s)
+ + strlen (physname)
+ + 10);
+
+ switch (visibility)
+ {
+ default:
+ abort ();
+
+ case DEBUG_VISIBILITY_PUBLIC:
+ vis = "";
+ break;
+
+ case DEBUG_VISIBILITY_PRIVATE:
+ vis = "/0";
+ break;
+
+ case DEBUG_VISIBILITY_PROTECTED:
+ vis = "/1";
+ break;
+ }
+
+ sprintf (n, "%s%s:%s%s:%s;", info->type_stack->fields, name, vis, s,
+ physname);
+
+ free (info->type_stack->fields);
+ info->type_stack->fields = n;
+
+ if (definition)
+ info->type_stack->definition = true;
+
+ return true;
+}
+
+/* Add a base class to the class on the type stack. */
+
+static boolean
+stab_class_baseclass (p, bitpos, virtual, visibility)
+ PTR p;
+ bfd_vma bitpos;
+ boolean virtual;
+ enum debug_visibility visibility;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ boolean definition;
+ char *s;
+ char *buf;
+ unsigned int c;
+ char **baseclasses;
+
+ definition = info->type_stack->definition;
+ s = stab_pop_type (info);
+
+ /* Build the base class specifier. */
+
+ buf = (char *) xmalloc (strlen (s) + 25);
+ buf[0] = virtual ? '1' : '0';
+ switch (visibility)
+ {
+ default:
+ abort ();
+
+ case DEBUG_VISIBILITY_PRIVATE:
+ buf[1] = '0';
+ break;
+
+ case DEBUG_VISIBILITY_PROTECTED:
+ buf[1] = '1';
+ break;
+
+ case DEBUG_VISIBILITY_PUBLIC:
+ buf[1] = '2';
+ break;
+ }
+
+ sprintf (buf + 2, "%ld,%s;", (long) bitpos, s);
+ free (s);
+
+ /* Add the new baseclass to the existing ones. */
+
+ assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+
+ if (info->type_stack->baseclasses == NULL)
+ c = 0;
+ else
+ {
+ c = 0;
+ while (info->type_stack->baseclasses[c] != NULL)
+ ++c;
+ }
+
+ baseclasses = (char **) xrealloc (info->type_stack->baseclasses,
+ (c + 2) * sizeof (*baseclasses));
+ baseclasses[c] = buf;
+ baseclasses[c + 1] = NULL;
+
+ info->type_stack->baseclasses = baseclasses;
+
+ if (definition)
+ info->type_stack->definition = true;
+
+ return true;
+}
+
+/* Start adding a method to the class on the type stack. */
+
+static boolean
+stab_class_start_method (p, name)
+ PTR p;
+ const char *name;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *m;
+
+ assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+
+ if (info->type_stack->methods == NULL)
+ {
+ m = (char *) xmalloc (strlen (name) + 3);
+ *m = '\0';
+ }
+ else
+ {
+ m = (char *) xrealloc (info->type_stack->methods,
+ (strlen (info->type_stack->methods)
+ + strlen (name)
+ + 4));
+ }
+
+ sprintf (m + strlen (m), "%s::", name);
+
+ info->type_stack->methods = m;
+
+ return true;
+}
+
+/* Add a variant, either static or not, to the current method. */
+
+static boolean
+stab_class_method_var (info, physname, visibility, staticp, constp, volatilep,
+ voffset, contextp)
+ struct stab_write_handle *info;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean staticp;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean contextp;
+{
+ boolean definition;
+ char *type;
+ char *context = NULL;
+ char visc, qualc, typec;
+
+ definition = info->type_stack->definition;
+ type = stab_pop_type (info);
+
+ if (contextp)
+ {
+ definition = definition || info->type_stack->definition;
+ context = stab_pop_type (info);
+ }
+
+ assert (info->type_stack != NULL && info->type_stack->methods != NULL);
+
+ switch (visibility)
+ {
+ default:
+ abort ();
+
+ case DEBUG_VISIBILITY_PRIVATE:
+ visc = '0';
+ break;
+
+ case DEBUG_VISIBILITY_PROTECTED:
+ visc = '1';
+ break;
+
+ case DEBUG_VISIBILITY_PUBLIC:
+ visc = '2';
+ break;
+ }
+
+ if (constp)
+ {
+ if (volatilep)
+ qualc = 'D';
+ else
+ qualc = 'B';
+ }
+ else
+ {
+ if (volatilep)
+ qualc = 'C';
+ else
+ qualc = 'A';
+ }
+
+ if (staticp)
+ typec = '?';
+ else if (! contextp)
+ typec = '.';
+ else
+ typec = '*';
+
+ info->type_stack->methods =
+ (char *) xrealloc (info->type_stack->methods,
+ (strlen (info->type_stack->methods)
+ + strlen (type)
+ + strlen (physname)
+ + (contextp ? strlen (context) : 0)
+ + 40));
+
+ sprintf (info->type_stack->methods + strlen (info->type_stack->methods),
+ "%s:%s;%c%c%c", type, physname, visc, qualc, typec);
+ free (type);
+
+ if (contextp)
+ {
+ sprintf (info->type_stack->methods + strlen (info->type_stack->methods),
+ "%ld;%s;", (long) voffset, context);
+ free (context);
+ }
+
+ if (definition)
+ info->type_stack->definition = true;
+
+ return true;
+}
+
+/* Add a variant to the current method. */
+
+static boolean
+stab_class_method_variant (p, physname, visibility, constp, volatilep,
+ voffset, contextp)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+ bfd_vma voffset;
+ boolean contextp;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ return stab_class_method_var (info, physname, visibility, false, constp,
+ volatilep, voffset, contextp);
+}
+
+/* Add a static variant to the current method. */
+
+static boolean
+stab_class_static_method_variant (p, physname, visibility, constp, volatilep)
+ PTR p;
+ const char *physname;
+ enum debug_visibility visibility;
+ boolean constp;
+ boolean volatilep;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ return stab_class_method_var (info, physname, visibility, true, constp,
+ volatilep, 0, false);
+}
+
+/* Finish up a method. */
+
+static boolean
+stab_class_end_method (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ assert (info->type_stack != NULL && info->type_stack->methods != NULL);
+
+ /* We allocated enough room on info->type_stack->methods to add the
+ trailing semicolon. */
+ strcat (info->type_stack->methods, ";");
+
+ return true;
+}
+
+/* Finish up a class. */
+
+static boolean
+stab_end_class_type (p)
+ PTR p;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ size_t len;
+ unsigned int i = 0;
+ char *buf;
+
+ assert (info->type_stack != NULL && info->type_stack->fields != NULL);
+
+ /* Work out the size we need to allocate for the class definition. */
+
+ len = (strlen (info->type_stack->string)
+ + strlen (info->type_stack->fields)
+ + 10);
+ if (info->type_stack->baseclasses != NULL)
+ {
+ len += 20;
+ for (i = 0; info->type_stack->baseclasses[i] != NULL; i++)
+ len += strlen (info->type_stack->baseclasses[i]);
+ }
+ if (info->type_stack->methods != NULL)
+ len += strlen (info->type_stack->methods);
+ if (info->type_stack->vtable != NULL)
+ len += strlen (info->type_stack->vtable);
+
+ /* Build the class definition. */
+
+ buf = (char *) xmalloc (len);
+
+ strcpy (buf, info->type_stack->string);
+
+ if (info->type_stack->baseclasses != NULL)
+ {
+ sprintf (buf + strlen (buf), "!%u,", i);
+ for (i = 0; info->type_stack->baseclasses[i] != NULL; i++)
+ {
+ strcat (buf, info->type_stack->baseclasses[i]);
+ free (info->type_stack->baseclasses[i]);
+ }
+ free (info->type_stack->baseclasses);
+ info->type_stack->baseclasses = NULL;
+ }
+
+ strcat (buf, info->type_stack->fields);
+ free (info->type_stack->fields);
+ info->type_stack->fields = NULL;
+
+ if (info->type_stack->methods != NULL)
+ {
+ strcat (buf, info->type_stack->methods);
+ free (info->type_stack->methods);
+ info->type_stack->methods = NULL;
+ }
+
+ strcat (buf, ";");
+
+ if (info->type_stack->vtable != NULL)
+ {
+ strcat (buf, info->type_stack->vtable);
+ free (info->type_stack->vtable);
+ info->type_stack->vtable = NULL;
+ }
+
+ /* Replace the string on the top of the stack with the complete
+ class definition. */
+ free (info->type_stack->string);
+ info->type_stack->string = buf;
+
+ return true;
+}
+
+/* Push a typedef which was previously defined. */
+
+static boolean
+stab_typedef_type (p, name)
+ PTR p;
+ const char *name;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ struct string_hash_entry *h;
+
+ h = string_hash_lookup (&info->typedef_hash, name, false, false);
+ assert (h != NULL && h->index > 0);
+
+ return stab_push_defined_type (info, h->index, h->size);
+}
+
+/* Push a struct, union or class tag. */
+
+static boolean
+stab_tag_type (p, name, id, kind)
+ PTR p;
+ const char *name;
+ unsigned int id;
+ enum debug_type_kind kind;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ long index;
+ unsigned int size;
+
+ index = stab_get_struct_index (info, name, id, kind, &size);
+ if (index < 0)
+ return false;
+
+ return stab_push_defined_type (info, index, size);
+}
+
+/* Define a typedef. */
+
+static boolean
+stab_typdef (p, name)
+ PTR p;
+ const char *name;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ long index;
+ unsigned int size;
+ char *s, *buf;
+ struct string_hash_entry *h;
+
+ index = info->type_stack->index;
+ size = info->type_stack->size;
+ s = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (name) + strlen (s) + 20);
+
+ if (index > 0)
+ sprintf (buf, "%s:t%s", name, s);
+ else
+ {
+ index = info->type_index;
+ ++info->type_index;
+ sprintf (buf, "%s:t%ld=%s", name, index, s);
+ }
+
+ free (s);
+
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
+ return false;
+
+ free (buf);
+
+ h = string_hash_lookup (&info->typedef_hash, name, true, false);
+ if (h == NULL)
+ {
+ fprintf (stderr, _("string_hash_lookup failed: %s\n"),
+ bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+
+ /* I don't think we care about redefinitions. */
+
+ h->index = index;
+ h->size = size;
+
+ return true;
+}
+
+/* Define a tag. */
+
+static boolean
+stab_tag (p, tag)
+ PTR p;
+ const char *tag;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *s, *buf;
+
+ s = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3);
+
+ sprintf (buf, "%s:T%s", tag, s);
+ free (s);
+
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Define an integer constant. */
+
+static boolean
+stab_int_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *buf;
+
+ buf = (char *) xmalloc (strlen (name) + 20);
+ sprintf (buf, "%s:c=i%ld", name, (long) val);
+
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Define a floating point constant. */
+
+static boolean
+stab_float_constant (p, name, val)
+ PTR p;
+ const char *name;
+ double val;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *buf;
+
+ buf = (char *) xmalloc (strlen (name) + 20);
+ sprintf (buf, "%s:c=f%g", name, val);
+
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Define a typed constant. */
+
+static boolean
+stab_typed_constant (p, name, val)
+ PTR p;
+ const char *name;
+ bfd_vma val;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *s, *buf;
+
+ s = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (name) + strlen (s) + 20);
+ sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val);
+ free (s);
+
+ if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Record a variable. */
+
+static boolean
+stab_variable (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_var_kind kind;
+ bfd_vma val;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *s, *buf;
+ int stab_type;
+ const char *kindstr;
+
+ s = stab_pop_type (info);
+
+ switch (kind)
+ {
+ default:
+ abort ();
+
+ case DEBUG_GLOBAL:
+ stab_type = N_GSYM;
+ kindstr = "G";
+ break;
+
+ case DEBUG_STATIC:
+ stab_type = N_STSYM;
+ kindstr = "S";
+ break;
+
+ case DEBUG_LOCAL_STATIC:
+ stab_type = N_STSYM;
+ kindstr = "V";
+ break;
+
+ case DEBUG_LOCAL:
+ stab_type = N_LSYM;
+ kindstr = "";
+
+ /* Make sure that this is a type reference or definition. */
+ if (! isdigit ((unsigned char) *s))
+ {
+ char *n;
+ long index;
+
+ index = info->type_index;
+ ++info->type_index;
+ n = (char *) xmalloc (strlen (s) + 20);
+ sprintf (n, "%ld=%s", index, s);
+ free (s);
+ s = n;
+ }
+ break;
+
+ case DEBUG_REGISTER:
+ stab_type = N_RSYM;
+ kindstr = "r";
+ break;
+ }
+
+ buf = (char *) xmalloc (strlen (name) + strlen (s) + 3);
+ sprintf (buf, "%s:%s%s", name, kindstr, s);
+ free (s);
+
+ if (! stab_write_symbol (info, stab_type, 0, val, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Start outputting a function. */
+
+static boolean
+stab_start_function (p, name, globalp)
+ PTR p;
+ const char *name;
+ boolean globalp;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *rettype, *buf;
+
+ assert (info->nesting == 0 && info->fun_offset == -1);
+
+ rettype = stab_pop_type (info);
+
+ buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3);
+ sprintf (buf, "%s:%c%s", name,
+ globalp ? 'F' : 'f',
+ rettype);
+
+ /* We don't know the value now, so we set it in start_block. */
+ info->fun_offset = info->symbols_size;
+
+ if (! stab_write_symbol (info, N_FUN, 0, 0, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Output a function parameter. */
+
+static boolean
+stab_function_parameter (p, name, kind, val)
+ PTR p;
+ const char *name;
+ enum debug_parm_kind kind;
+ bfd_vma val;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+ char *s, *buf;
+ int stab_type;
+ char kindc;
+
+ s = stab_pop_type (info);
+
+ switch (kind)
+ {
+ default:
+ abort ();
+
+ case DEBUG_PARM_STACK:
+ stab_type = N_PSYM;
+ kindc = 'p';
+ break;
+
+ case DEBUG_PARM_REG:
+ stab_type = N_RSYM;
+ kindc = 'P';
+ break;
+
+ case DEBUG_PARM_REFERENCE:
+ stab_type = N_PSYM;
+ kindc = 'v';
+ break;
+
+ case DEBUG_PARM_REF_REG:
+ stab_type = N_RSYM;
+ kindc = 'a';
+ break;
+ }
+
+ buf = (char *) xmalloc (strlen (name) + strlen (s) + 3);
+ sprintf (buf, "%s:%c%s", name, kindc, s);
+ free (s);
+
+ if (! stab_write_symbol (info, stab_type, 0, val, buf))
+ return false;
+
+ free (buf);
+
+ return true;
+}
+
+/* Start a block. */
+
+static boolean
+stab_start_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ /* Fill in any slots which have been waiting for the first known
+ text address. */
+
+ if (info->so_offset != -1)
+ {
+ bfd_put_32 (info->abfd, addr, info->symbols + info->so_offset + 8);
+ info->so_offset = -1;
+ }
+
+ if (info->fun_offset != -1)
+ {
+ bfd_put_32 (info->abfd, addr, info->symbols + info->fun_offset + 8);
+ info->fun_offset = -1;
+ }
+
+ ++info->nesting;
+
+ /* We will be called with a top level block surrounding the
+ function, but stabs information does not output that block, so we
+ ignore it. */
+
+ if (info->nesting == 1)
+ {
+ info->fnaddr = addr;
+ return true;
+ }
+
+ /* We have to output the LBRAC symbol after any variables which are
+ declared inside the block. We postpone the LBRAC until the next
+ start_block or end_block. */
+
+ /* If we have postponed an LBRAC, output it now. */
+ if (info->pending_lbrac != (bfd_vma) -1)
+ {
+ if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac,
+ (const char *) NULL))
+ return false;
+ }
+
+ /* Remember the address and output it later. */
+
+ info->pending_lbrac = addr - info->fnaddr;
+
+ return true;
+}
+
+/* End a block. */
+
+static boolean
+stab_end_block (p, addr)
+ PTR p;
+ bfd_vma addr;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ if (addr > info->last_text_address)
+ info->last_text_address = addr;
+
+ /* If we have postponed an LBRAC, output it now. */
+ if (info->pending_lbrac != (bfd_vma) -1)
+ {
+ if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac,
+ (const char *) NULL))
+ return false;
+ info->pending_lbrac = (bfd_vma) -1;
+ }
+
+ assert (info->nesting > 0);
+
+ --info->nesting;
+
+ /* We ignore the outermost block. */
+ if (info->nesting == 0)
+ return true;
+
+ return stab_write_symbol (info, N_RBRAC, 0, addr - info->fnaddr,
+ (const char *) NULL);
+}
+
+/* End a function. */
+
+/*ARGSUSED*/
+static boolean
+stab_end_function (p)
+ PTR p;
+{
+ return true;
+}
+
+/* Output a line number. */
+
+static boolean
+stab_lineno (p, file, lineno, addr)
+ PTR p;
+ const char *file;
+ unsigned long lineno;
+ bfd_vma addr;
+{
+ struct stab_write_handle *info = (struct stab_write_handle *) p;
+
+ assert (info->lineno_filename != NULL);
+
+ if (addr > info->last_text_address)
+ info->last_text_address = addr;
+
+ if (strcmp (file, info->lineno_filename) != 0)
+ {
+ if (! stab_write_symbol (info, N_SOL, 0, addr, file))
+ return false;
+ info->lineno_filename = file;
+ }
+
+ return stab_write_symbol (info, N_SLINE, lineno, addr - info->fnaddr,
+ (const char *) NULL);
+}
diff --git a/config-ml.in b/config-ml.in
new file mode 100644
index 00000000000..503f7cf1a18
--- /dev/null
+++ b/config-ml.in
@@ -0,0 +1,687 @@
+# Configure fragment invoked in the post-target section for subdirs
+# wanting multilib support.
+#
+# It is advisable to support a few --enable/--disable options to let the
+# user select which libraries s/he really wants.
+#
+# Subdirectories wishing to use multilib should put the following lines
+# in the "post-target" section of configure.in.
+#
+# if [ "${srcdir}" = "." ] ; then
+# if [ "${with_target_subdir}" != "." ] ; then
+# . ${with_multisrctop}../../config-ml.in
+# else
+# . ${with_multisrctop}../config-ml.in
+# fi
+# else
+# . ${srcdir}/../config-ml.in
+# fi
+#
+# See librx/configure.in in the libg++ distribution for an example of how
+# to handle autoconf'd libraries.
+#
+# Things are complicated because 6 separate cases must be handled:
+# 2 (native, cross) x 3 (absolute-path, relative-not-dot, dot) = 6.
+#
+# srcdir=. is special. It must handle make programs that don't handle VPATH.
+# To implement this, a symlink tree is built for each library and for each
+# multilib subdir.
+#
+# The build tree is layed out as
+#
+# ./
+# libg++
+# newlib
+# m68020/
+# libg++
+# newlib
+# m68881/
+# libg++
+# newlib
+#
+# The nice feature about this arrangement is that inter-library references
+# in the build tree work without having to care where you are. Note that
+# inter-library references also work in the source tree because symlink trees
+# are built when srcdir=.
+#
+# Unfortunately, trying to access the libraries in the build tree requires
+# the user to manually choose which library to use as GCC won't be able to
+# find the right one. This is viewed as the lesser of two evils.
+#
+# Configure variables:
+# ${with_target_subdir} = "." for native, or ${target_alias} for cross.
+# Set by top level Makefile.
+# ${with_multisrctop} = how many levels of multilibs there are in the source
+# tree. It exists to handle the case of configuring in the source tree:
+# ${srcdir} is not constant.
+# ${with_multisubdir} = name of multilib subdirectory (eg: m68020/m68881).
+#
+# Makefile variables:
+# MULTISRCTOP = number of multilib levels in source tree (+1 if cross)
+# (FIXME: note that this is different than ${with_multisrctop}. Check out.).
+# MULTIBUILDTOP = number of multilib levels in build tree
+# MULTIDIRS = list of multilib subdirs (eg: m68000 m68020 ...)
+# (only defined in each library's main Makefile).
+# MULTISUBDIR = installed subdirectory name with leading '/' (eg: /m68000)
+# (only defined in each multilib subdir).
+
+# FIXME: Multilib is currently disabled by default for everything other than
+# newlib. It is up to each target to turn on multilib support for the other
+# libraries as desired.
+
+# We have to handle being invoked by both Cygnus configure and Autoconf.
+#
+# Cygnus configure incoming variables:
+# srcdir, subdir, host, arguments
+#
+# Autoconf incoming variables:
+# srcdir, host, ac_configure_args
+#
+# We *could* figure srcdir and host out, but we'd have to do work that
+# our caller has already done to figure them out and requiring these two
+# seems reasonable.
+# Note that `host' in this case is GCC's `target'. Target libraries are
+# configured for a particular host.
+
+if [ -n "${ac_configure_args}" ]; then
+ Makefile=${ac_file-Makefile}
+ ml_config_shell=${CONFIG_SHELL-/bin/sh}
+ ml_arguments="${ac_configure_args}"
+ ml_realsrcdir=${srcdir}
+else
+ Makefile=${Makefile-Makefile}
+ ml_config_shell=${config_shell-/bin/sh}
+ ml_arguments="${arguments}"
+ if [ -n "${subdir}" -a "${subdir}" != "." ] ; then
+ ml_realsrcdir=${srcdir}/${subdir}
+ else
+ ml_realsrcdir=${srcdir}
+ fi
+fi
+
+# Scan all the arguments and set all the ones we need.
+
+ml_verbose=--verbose
+for option in ${ml_arguments}
+do
+ case $option in
+ --*) ;;
+ -*) option=-$option ;;
+ esac
+
+ case $option in
+ --*=*)
+ optarg=`echo $option | sed -e 's/^[^=]*=//'`
+ ;;
+ esac
+
+ case $option in
+ --disable-*)
+ enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'`
+ eval $enableopt=no
+ ;;
+ --enable-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+ enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $enableopt="$optarg"
+ ;;
+ --norecursion | --no*)
+ ml_norecursion=yes
+ ;;
+ --silent | --sil* | --quiet | --q*)
+ ml_verbose=--silent
+ ;;
+ --verbose | --v | --verb*)
+ ml_verbose=--verbose
+ ;;
+ --with-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+ withopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $withopt="$optarg"
+ ;;
+ --without-*)
+ withopt=`echo ${option} | sed 's:^--::;s:out::;s:-:_:g'`
+ eval $withopt=no
+ ;;
+ esac
+done
+
+# Only do this if --enable-multilib.
+if [ "${enable_multilib}" = yes ]; then
+
+# Compute whether this is the library's top level directory
+# (ie: not a multilib subdirectory, and not a subdirectory like libg++/src).
+# ${with_multisubdir} tells us we're in the right branch, but we could be
+# in a subdir of that.
+# ??? The previous version could void this test by separating the process into
+# two files: one that only the library's toplevel configure.in ran (to
+# configure the multilib subdirs), and another that all configure.in's ran to
+# update the Makefile. It seemed reasonable to collapse all multilib support
+# into one file, but it does leave us with having to perform this test.
+ml_toplevel_p=no
+if [ -z "${with_multisubdir}" ]; then
+ if [ "${srcdir}" = "." ]; then
+ # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}.
+ # ${with_target_subdir} = "." for native, otherwise target alias.
+ if [ "${with_target_subdir}" = "." ]; then
+ if [ -f ${ml_realsrcdir}/../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ else
+ if [ -f ${ml_realsrcdir}/../../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ fi
+ else
+ # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}.
+ if [ -f ${ml_realsrcdir}/../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ fi
+fi
+
+# If this is the library's top level directory, set multidirs to the
+# multilib subdirs to support. This lives at the top because we need
+# `multidirs' set right away.
+
+if [ "${ml_toplevel_p}" = yes ]; then
+
+multidirs=
+for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do
+ dir=`echo $i | sed -e 's/;.*$//'`
+ if [ "${dir}" = "." ]; then
+ true
+ else
+ if [ -z "${multidirs}" ]; then
+ multidirs="${dir}"
+ else
+ multidirs="${multidirs} ${dir}"
+ fi
+ fi
+done
+
+# Target libraries are configured for the host they run on, so we check
+# $host here, not $target.
+
+case "${host}" in
+arc-*-elf*)
+ if [ x$enable_biendian != xyes ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *be*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+arm-*-*)
+ if [ x"$enable_fpu" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *fpu*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_26bit" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *26bit*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_underscore" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *under*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_interwork" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *interwork*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *le* ) : ;;
+ *be* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+m68*-*-*)
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68881 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68881* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68000 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68000* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68020 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68020* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+mips*-*-*)
+ if [ x$enable_single_float = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *single* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *el* ) : ;;
+ *eb* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+powerpc*-*-* | rs6000*-*-*)
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powercpu = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ power | */power | */power/* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powerpccpu = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *powerpc* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powerpcos = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-linux* | *mcall-solaris* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mlittle* | *mbig* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_sysv = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-sysv* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_aix = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-aix* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+esac
+
+# Remove extraneous blanks from multidirs.
+# Tests like `if [ -n "$multidirs" ]' require it.
+multidirs=`echo "$multidirs" | sed -e 's/^[ ][ ]*//' -e 's/[ ][ ]*$//' -e 's/[ ][ ]*/ /g'`
+
+# Add code to library's top level makefile to handle building the multilib
+# subdirs.
+
+cat > Multi.tem <<\EOF
+
+# FIXME: There should be an @-sign in front of the `if'.
+# Leave out until this is tested a bit more.
+multi-do:
+ if [ -z "$(MULTIDIRS)" ]; then \
+ true; \
+ else \
+ rootpre=`pwd`/; export rootpre; \
+ srcrootpre=`cd $(srcdir); pwd`/; export srcrootpre; \
+ lib=`echo $${rootpre} | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \
+ compiler="$(CC)"; \
+ for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \
+ dir=`echo $$i | sed -e 's/;.*$$//'`; \
+ if [ "$${dir}" = "." ]; then \
+ true; \
+ else \
+ if [ -d ../$${dir}/$${lib} ]; then \
+ flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
+ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS) $${flags}" \
+ CXXFLAGS="$(CXXFLAGS) $${flags}" \
+ LIBCFLAGS="$(LIBCFLAGS) $${flags}" \
+ LIBCXXFLAGS="$(LIBCXXFLAGS) $${flags}" \
+ LDFLAGS="$(LDFLAGS) $${flags}" \
+ $(DO)); then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ else true; \
+ fi; \
+ fi; \
+ done; \
+ fi
+
+# FIXME: There should be an @-sign in front of the `if'.
+# Leave out until this is tested a bit more.
+multi-clean:
+ if [ -z "$(MULTIDIRS)" ]; then \
+ true; \
+ else \
+ lib=`pwd | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \
+ for dir in Makefile $(MULTIDIRS); do \
+ if [ -f ../$${dir}/$${lib}/Makefile ]; then \
+ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \
+ then true; \
+ else exit 1; \
+ fi; \
+ else true; \
+ fi; \
+ done; \
+ fi
+EOF
+
+cat ${Makefile} Multi.tem > Makefile.tem
+rm -f ${Makefile} Multi.tem
+mv Makefile.tem ${Makefile}
+
+fi # ${ml_toplevel_p} = yes
+
+if [ "${ml_verbose}" = --verbose ]; then
+ echo "Adding multilib support to Makefile in ${ml_realsrcdir}"
+ if [ "${ml_toplevel_p}" = yes ]; then
+ echo "multidirs=${multidirs}"
+ fi
+ echo "with_multisubdir=${with_multisubdir}"
+fi
+
+if [ "${srcdir}" = "." ]; then
+ if [ "${with_target_subdir}" != "." ]; then
+ ml_srcdotdot="../"
+ else
+ ml_srcdotdot=""
+ fi
+else
+ ml_srcdotdot=""
+fi
+
+if [ -z "${with_multisubdir}" ]; then
+ ml_subdir=
+ ml_builddotdot=
+ : # ml_srcdotdot= # already set
+else
+ ml_subdir="/${with_multisubdir}"
+ # The '[^/][^/]*' appears that way to work around a SunOS sed bug.
+ ml_builddotdot=`echo ${with_multisubdir} | sed -e 's:[^/][^/]*:..:g'`/
+ if [ "$srcdir" = "." ]; then
+ ml_srcdotdot=${ml_srcdotdot}${ml_builddotdot}
+ else
+ : # ml_srcdotdot= # already set
+ fi
+fi
+
+if [ "${ml_toplevel_p}" = yes ]; then
+ ml_do='$(MAKE)'
+ ml_clean='$(MAKE)'
+else
+ ml_do=true
+ ml_clean=true
+fi
+
+# TOP is used by newlib and should not be used elsewhere for this purpose.
+# MULTI{SRC,BUILD}TOP are the proper ones to use. MULTISRCTOP is empty
+# when srcdir != builddir. MULTIBUILDTOP is always some number of ../'s.
+# FIXME: newlib needs to be updated to use MULTI{SRC,BUILD}TOP so we can
+# delete TOP. Newlib may wish to continue to use TOP for its own purposes
+# of course.
+# MULTIDIRS is non-empty for the cpu top level Makefile (eg: newlib/Makefile)
+# and lists the subdirectories to recurse into.
+# MULTISUBDIR is non-empty in each cpu subdirectory's Makefile
+# (eg: newlib/h8300h/Makefile) and is the installed subdirectory name with
+# a leading '/'.
+# MULTIDO is used for targets like all, install, and check where
+# $(FLAGS_TO_PASS) augmented with the subdir's compiler option is needed.
+# MULTICLEAN is used for the *clean targets.
+#
+# ??? It is possible to merge MULTIDO and MULTICLEAN into one. They are
+# currently kept separate because we don't want the *clean targets to require
+# the existence of the compiler (which MULTIDO currently requires) and
+# therefore we'd have to record the directory options as well as names
+# (currently we just record the names and use --print-multi-lib to get the
+# options).
+
+sed -e "s:^TOP[ ]*=[ ]*\([./]*\)[ ]*$:TOP = ${ml_builddotdot}\1:" \
+ -e "s:^MULTISRCTOP[ ]*=.*$:MULTISRCTOP = ${ml_srcdotdot}:" \
+ -e "s:^MULTIBUILDTOP[ ]*=.*$:MULTIBUILDTOP = ${ml_builddotdot}:" \
+ -e "s:^MULTIDIRS[ ]*=.*$:MULTIDIRS = ${multidirs}:" \
+ -e "s:^MULTISUBDIR[ ]*=.*$:MULTISUBDIR = ${ml_subdir}:" \
+ -e "s:^MULTIDO[ ]*=.*$:MULTIDO = $ml_do:" \
+ -e "s:^MULTICLEAN[ ]*=.*$:MULTICLEAN = $ml_clean:" \
+ ${Makefile} > Makefile.tem
+rm -f ${Makefile}
+mv Makefile.tem ${Makefile}
+
+# If this is the library's top level, configure each multilib subdir.
+# This is done at the end because this is the loop that runs configure
+# in each multilib subdir and it seemed reasonable to finish updating the
+# Makefile before going on to configure the subdirs.
+
+if [ "${ml_toplevel_p}" = yes ]; then
+
+# We must freshly configure each subdirectory. This bit of code is
+# actually partially stolen from the main configure script. FIXME.
+
+if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then
+
+ if [ "${ml_verbose}" = --verbose ]; then
+ echo "Running configure in multilib subdirs ${multidirs}"
+ echo "pwd: `pwd`"
+ fi
+
+ ml_origdir=`pwd`
+ ml_libdir=`echo $ml_origdir | sed -e 's,^.*/,,'`
+ # cd to top-level-build-dir/${with_target_subdir}
+ cd ..
+
+ for ml_dir in ${multidirs}; do
+
+ if [ "${ml_verbose}" = --verbose ]; then
+ echo "Running configure in multilib subdir ${ml_dir}"
+ echo "pwd: `pwd`"
+ fi
+
+ if [ -d ${ml_dir} ]; then true; else mkdir ${ml_dir}; fi
+ if [ -d ${ml_dir}/${ml_libdir} ]; then true; else mkdir ${ml_dir}/${ml_libdir}; fi
+
+ # Eg: if ${ml_dir} = m68000/m68881, dotdot = ../../
+ dotdot=../`echo ${ml_dir} | sed -e 's|[^/]||g' -e 's|/|../|g'`
+
+ case ${srcdir} in
+ ".")
+ echo Building symlink tree in `pwd`/${ml_dir}/${ml_libdir}
+ if [ "${with_target_subdir}" != "." ]; then
+ ml_unsubdir="../"
+ else
+ ml_unsubdir=""
+ fi
+ (cd ${ml_dir}/${ml_libdir};
+ ../${dotdot}${ml_unsubdir}symlink-tree ../${dotdot}${ml_unsubdir}${ml_libdir} "")
+ if [ -f ${ml_dir}/${ml_libdir}/Makefile ]; then
+ if [ x"${MAKE}" = x ]; then
+ (cd ${ml_dir}/${ml_libdir}; make distclean)
+ else
+ (cd ${ml_dir}/${ml_libdir}; ${MAKE} distclean)
+ fi
+ fi
+ ml_newsrcdir="."
+ ml_srcdiroption=
+ multisrctop=${dotdot}
+ ;;
+ *)
+ case "${srcdir}" in
+ /*) # absolute path
+ ml_newsrcdir=${srcdir}
+ ;;
+ *) # otherwise relative
+ ml_newsrcdir=${dotdot}${srcdir}
+ ;;
+ esac
+ ml_srcdiroption="-srcdir=${ml_newsrcdir}"
+ multisrctop=
+ ;;
+ esac
+
+ case "${progname}" in
+ /*) ml_recprog=${progname} ;;
+ *) ml_recprog=${dotdot}${progname} ;;
+ esac
+
+ # FIXME: POPDIR=${PWD=`pwd`} doesn't work here.
+ ML_POPDIR=`pwd`
+ cd ${ml_dir}/${ml_libdir}
+
+ if [ -f ${ml_newsrcdir}/configure ]; then
+ ml_recprog=${ml_newsrcdir}/configure
+ fi
+ if eval ${ml_config_shell} ${ml_recprog} \
+ --with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \
+ ${ml_arguments} ${ml_srcdiroption} ; then
+ true
+ else
+ exit 1
+ fi
+
+ cd ${ML_POPDIR}
+
+ done
+
+ cd ${ml_origdir}
+fi
+
+fi # ${ml_toplevel_p} = yes
+fi # ${enable_multilib} = yes
diff --git a/config.guess b/config.guess
new file mode 100755
index 00000000000..3c75a80de33
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1008 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy \
+ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9] )
+
+ sed 's/^ //' << EOF >dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy`
+ rm -f dummy.c dummy
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ if test -x /usr/bin/objformat; then
+ if test "elf" = "`/usr/bin/objformat`"; then
+ echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+ exit 0
+ fi
+ fi
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:[Cc][Yy][Gg][Ww][Ii][Nn]*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin32
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than generic posix subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # change UNAME_MACHINE based on the output of uname instead of
+ # i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin32
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ armv*) UNAME_MACHINE=$UNAME_MACHINE ;;
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us.
+ ld_help_string=`ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc)
+ # Determine Lib Version
+ cat >dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ ${CC-cc} dummy.c -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.c dummy
+ echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:5:7)
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+# 5.0.4c returns "Pent II". 5.0.5 returns PentII
+ (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*PentII' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pent II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config.if b/config.if
new file mode 100644
index 00000000000..bcc026908d8
--- /dev/null
+++ b/config.if
@@ -0,0 +1,87 @@
+#! /dev/null
+# Don't call it directly. This shell script fragment is called to
+# determine:
+#
+# 1. libstcxx_interface: the interface name for libstdc++.
+# 2. cxx_interface: the interface name for c++.
+# 3. libc_interface: the interface name for libc.
+#
+
+# Get the top level src dir.
+if [ -z "${topsrcdir}" -a -z "${top_srcdir}" ]
+then
+ echo "Undefined top level src dir: topsrcdir and top_srcdir are empty" >&2
+ exit 1
+fi
+
+if [ -n "${topsrcdir}" ]
+then
+ if_topsrcdir=${topsrcdir}
+else
+ if_topsrcdir=${top_srcdir}
+fi
+
+if [ -f ${if_topsrcdir}/libstdc++/Makefile.in ]; then
+# We check libstdc++ for libstdcxx_interface.
+libstdcxx_interface=`grep "^INTERFACE" ${if_topsrcdir}/libstdc++/Makefile.in | sed 's/INTERFACE[ ]*=[ ]*\(.*\)/\1/'`
+else
+libstdcxx_interface=
+fi
+
+if [ -f ${if_topsrcdir}/gcc/cp/Makefile.in ]; then
+# We check gcc/cp for cxx_interface.
+cxx_interface=`grep "^INTERFACE" ${if_topsrcdir}/gcc/cp/Makefile.in | sed 's/INTERFACE[ ]*=[ ]*\(.*\)/\1/'`
+else
+cxx_interface=
+fi
+
+# The trickiest part is libc_interface.
+if [ -z "${libc_interface}" ]
+then
+ case ${target_os} in
+ *linux*libc1*|*linux*libc5*)
+ case ${target_alias} in
+ *alpha*|*powerpc*)
+ libc_interface=-libc5.9-
+ ;;
+ *)
+ libc_interface=-libc5-
+ ;;
+ esac
+ ;;
+ *linux*gnu*)
+ # We have to work harder to figure it out.
+ if [ ${target_alias} = ${build_alias} ]
+ then
+ dummy=if$$
+ cat >$dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ printf("%d\n", __GLIBC_MINOR__);
+ return 0;
+}
+EOF
+ ${CC-cc} $dummy.c -o $dummy 2>/dev/null
+ if [ "$?" = 0 ]
+ then
+ libc_interface=-libc6.`./$dummy`-
+ rm -f $dummy.c $dummy
+ else
+ # It should never happen.
+ echo "Cannot find the GNU C library minor version number." >&2
+ rm -f $dummy.c $dummy
+ exit 1
+ fi
+ else
+ # Cross compiling. Assume glibc 2.1.
+ libc_interface=-libc6.1-
+ fi
+ ;;
+ *)
+ libc_interface=-
+ ;;
+ esac
+fi
diff --git a/config.sub b/config.sub
new file mode 100755
index 00000000000..3d4f5fd21b1
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1292 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# CYGNUS LOCAL marketing-names
+# Here we handle any "marketing" names - translating them to
+# standard triplets
+case $1 in
+ mips-tx39-elf)
+ set mipstx39-unknown-elf
+ ;;
+ *)
+ ;;
+esac
+# END CYGNUS LOCAL marketing-names
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond ) # EGCS LOCAL
+ os=
+ basic_machine=$1
+ ;;
+ -scout) # EGCS LOCAL
+ ;;
+ -wrs) # EGCS LOCAL
+ os=vxworks
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 \
+ | tron | a29k | 580 | i960 | h8300 \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | alpha | alphaev[45678] | alphaev56 | alphapca5[67] \
+ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp11 \
+ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+ | mipstx39 | mipstx39el \
+ | sparc | sparclet | sparclite | sparc64 | sparc86x | v850 \
+ | c4x)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m88110 | m680[012346]0 | m683?2 | m68360 | m5200 | z8k | v70 \
+ | h8500 | w65 | fr30 | mcore) # CYGNUS / EGCS LOCAL
+ basic_machine=$basic_machine-unknown
+ ;;
+ strongarm) # CYGNUS LOCAL nickc/strongarm
+ basic_machine=$basic_machine-unknown
+ ;;
+ thumb)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # CYGNUS LOCAL vr4111/gavin
+ mips64vr4111 | mips64vr4111el)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # END CYGNUS LOCAL vr4111/gavin
+ mips64vr4300 | mips64vr4300el) # EGCS LOCAL jsmith/vr4300
+ basic_machine=$basic_machine-unknown
+ ;;
+ mips64vr4100 | mips64vr4100el) # EGCS LOCAL jsmith/vr4100
+ basic_machine=$basic_machine-unknown
+ ;;
+ mips64vr5000 | mips64vr5000el) # EGCS LOCAL ian/vr5000
+ basic_machine=$basic_machine-unknown
+ ;;
+ mips16)
+ basic_machine=$basic_machine-unknown
+ ;;
+ tic30) # CYGNUS LOCAL ian/tic30
+ basic_machine=$basic_machine-unknown
+ ;;
+ c30) # CYGNUS LOCAL ian/tic30
+ basic_machine=tic30-unknown
+ ;;
+
+ tic80) # CYGNUS LOCAL fnf/TIc80
+ basic_machine=$basic_machine-unknown
+ ;;
+ v850e) # CYGNUS LOCAL jtc/v850
+ basic_machine=$basic_machine-unknown
+ ;;
+ v850ea) # CYGNUS LOCAL jtc/v850
+ basic_machine=$basic_machine-unknown
+ ;;
+ d10v)
+ basic_machine=$basic_machine-unknown
+ ;;
+ d30v) # CYGNUS LOCAL hunt/d30v
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+ | xmp-* | ymp-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* \
+ | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+ | alpha-* | alphaev[45678]-* | alphaev56-* | alphapca5[67]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* \
+ | xps100-* | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | sparcv9-* | sparc86x-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-* | arm*-* \
+ | fr30-* | mcore-*) # CYGNUS LOCAL
+ ;;
+ m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-* | d10v-*) # EGCS LOCAL
+ ;;
+ strongarm-*) # CYGNUS LOCAL nickc/strongarm
+ ;;
+ thumb-*) # EGCS LOCAL angela/thumb
+ ;;
+ v850-*) # EGCS LOCAL
+ ;;
+ v850e-*) # CYGNUS LOCAL
+ ;;
+ v850ea-*) # CYGNUS LOCAL
+ ;;
+ d30v-*) # EGCS LOCAL
+ ;;
+ # CYGNUS LOCAL vr4111/gavin
+ mips64vr4111-* | mips64vr4111el-*)
+ ;;
+ # END CYGNUS LOCAL vr4111/gavin
+ mips64vr4300-* | mips64vr4300el-*) # EGCS LOCAL jsmith/vr4300
+ ;;
+ mips64vr4100-* | mips64vr4100el-*) # EGCS LOCAL jsmith/vr4100
+ ;;
+ mips16-*) # EGCS LOCAL krk/mips16
+ ;;
+ tic30-*) # EGCS LOCAL ian/tic30
+ ;;
+ c30-*) # EGCS LOCAL ian/tic30
+ basic_machine=tic30-unknown
+ ;;
+ tic80-*) # CYGNUS LOCAL fnf/TIc80
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd) # EGCS LOCAL
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif) # EGCS LOCAL
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k) # EGCS LOCAL
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd) # EGCS LOCAL
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE) # EGCS LOCAL
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray) # EGCS LOCAL
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms) # EGCS LOCAL
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ w89k-*) # EGCS LOCAL
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ op50n-*) # EGCS LOCAL
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ op60c-*) # EGCS LOCAL
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ hppro) # EGCS LOCAL
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9] )
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9] )
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9] )
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | \
+ hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893 )
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679] )
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf) # EGCS LOCAL
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach) # EGCS LOCAL
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta) # EGCS LOCAL
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ i386-go32 | go32) # EGCS LOCAL
+ basic_machine=i386-unknown
+ os=-go32
+ ;;
+ i386-mingw32 | mingw32)
+ basic_machine=i386-unknown
+ os=-mingw32
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor) # EGCS LOCAL
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos) # EGCS LOCAL
+ basic_machine=i386-unknown
+ os=-msdos
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown # EGCS LOCAL
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-corel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70) # EGCS LOCAL
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960) # EGCS LOCAL
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ OSE68000 | ose68000) # EGCS LOCAL
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k) # EGCS LOCAL
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | k6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | k6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rom68k) # EGCS LOCAL
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200) # EGCS LOCAL
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs) # EGCS LOCAL
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000) # EGCS LOCAL
+ basic_machine=m68k-tandem
+ ;;
+ stratus) # EGCS LOCAL
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810) # EGCS LOCAL
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*) # EGCS LOCAL
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff) # EGCS LOCAL
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k) # EGCS LOCAL
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n) # EGCS LOCAL
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c) # EGCS LOCAL
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc | sparcv9)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw) # EGCS LOCAL
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw) # EGCS LOCAL
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* )
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ # EGCS LOCAL
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mon960* | -lnews* )
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ # END EGCS LOCAL
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd) # EGCS LOCAL
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*) # EGCS LOCAL
+ os=-ose
+ ;;
+ -es1800*) # EGCS LOCAL
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-corel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco) # EGCS LOCAL
+ os=-aout
+ ;;
+ mips*-cisco) # EGCS LOCAL
+ os=-elf
+ ;;
+ mips*-*) # EGCS LOCAL
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec) # EGCS LOCAL
+ os=-proelf
+ ;;
+ *-winbond) # EGCS LOCAL
+ os=-proelf
+ ;;
+ *-oki) # EGCS LOCAL
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k) # EGCS LOCAL
+ os=-coff
+ ;;
+ *-*bug) # EGCS LOCAL
+ os=-coff
+ ;;
+ *-apple) # EGCS LOCAL
+ os=-macos
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*) # EGCS LOCAL
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*) # EGCS LOCAL
+ vendor=apple
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/config/ChangeLog b/config/ChangeLog
new file mode 100644
index 00000000000..7d6fc609368
--- /dev/null
+++ b/config/ChangeLog
@@ -0,0 +1,392 @@
+1999-04-07 Michael Meissner <meissner@cygnus.com>
+
+ * mt-d30v: New file, pass -g -Os -Wa,-C as default options.
+
+1999-02-08 Syd Polk <spolk@cygnus.com>
+
+ * acinclude.m4: Added macros to find itcl files.
+ Export TCL_CFLAGS from tclConfig.sh.
+ Export TCL_LIB_FULL_PATH, TK_LIB_FULL_PATH, ITCL_LIB_FULL_PATH,
+ ITK_LIB_FULL_PATH, and TIX_LIB_FULL_PATH
+ Replace TIX macros with better ones from snavigator.
+
+Tue Feb 2 22:51:21 1999 Philip Blundell <philb@gnu.org>
+
+ * mh-armpic: New file. Patch from Jim Pick <jim@jimpick.com>.
+ * mt-armpic: Likewise.
+
+Mon Jan 18 19:41:08 1999 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.mh: Activate commented out dependencies for
+ gdb: libtermcap.
+
+Wed Nov 18 20:29:46 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * cygwin.mh: Add extra libtermcap target information.
+ Add commented out dependency for gdb to libtermcap for
+ future readline requirement.
+
+Mon Nov 2 15:15:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * mh-cygwin32: delete
+ * mh-cygwin: was mh-cygwin32
+
+1998-10-26 Syd Polk <spolk@cygnus.com>
+
+ * acinclude.m4: TCLHDIR and TKHDIR need to be run through
+ cygpath for Microsoft builds.
+
+1998-10-20 Syd Polk <spolk@cygnus.com>
+
+ * acinclude.m4: Re-exported TCL_LIBS and TCL_LD_SEARCH_FLAGS
+ because itcl needs them.
+
+Mon Aug 31 17:50:53 1998 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * mh-aix43 (NM_FOR_TARGET): Add -X32_64 as well.
+
+Sat Aug 29 14:32:55 1998 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * mh-aix43: New file.
+
+Mon Aug 10 00:15:47 1998 HJ Lu (hjl@gnu.org)
+
+ * mt-linux (CXXFLAGS_FOR_TARGET): Add -D_GNU_SOURCE.
+
+1998-05-29 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * acinclude.m4: New collection of generic autoconf macros.
+
+Wed Apr 22 12:24:28 1998 Michael Meissner <meissner@cygnus.com>
+
+ * mt-ospace: New file, support using -Os instead of -O2 to compile
+ the libraries.
+
+Wed Apr 22 10:53:14 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * mt-linux (CXXFLAGS_FOR_TARGET): Set this instead of CXXFLAGS.
+
+Sat Apr 11 22:43:17 1998 J. Kean Johnston <jkj@sco.com>
+
+ * mh-svsv5: New file - support for SCO UnixWare 7 / SVR5.
+
+Thu Mar 26 01:54:25 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * mh-cygwin32: stop configuring and building dosrel.
+
+Thu Sep 11 16:43:27 1997 Jim Wilson <wilson@cygnus.com>
+
+ * mh-elfalphapic, mt-elfalphapic: New files.
+
+Wed Jul 23 12:32:18 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * mh-go32 (CFLAGS): Don't set -fno-omit-frame-pointer.
+
+Mon Jun 16 19:06:41 1997 Geoff Keating <geoffk@ozemail.com.au>
+
+ * mh-ppcpic: New file.
+ * mt-ppcpic: New file.
+
+Thu Mar 27 15:52:40 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mh-cygwin32: override CXXFLAGS, setting to -O2 only
+ (no debug)
+
+Tue Mar 25 18:16:43 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mh-cygwin32: override LIBGCC2_DEBUG_CFLAGS so debug info
+ isn't included in cygwin32-hosted libgcc2.a by default
+
+Wed Jan 8 19:56:43 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * mh-cygwin32: override CFLAGS so debug info isn't included
+ in cygwin32-hosted tools by default
+
+Tue Dec 31 16:04:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-linux: Remove.
+
+Mon Nov 11 10:29:51 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * mt-ppc: Delete file, options moved to newlib configure.
+
+Fri Oct 4 12:21:03 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * mh-dgux386: New file. x86 dgux specific flags
+
+Mon Sep 30 15:10:07 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw (EXTRALIBS_PPC_XCOFF): New, was EXTRALIBS_PPC.
+ (EXTRALIBS_PPC): Use shared libraries instead of xcoff.
+
+Sat Aug 17 04:56:25 1996 Geoffrey Noer <noer@skaro.cygnus.com>
+
+ * mh-cygwin32: don't -D_WIN32 here anymore
+
+Thu Aug 15 19:46:44 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw (SEGFLAG_68K, SEGFLAG_PPC): Remove.
+ (EXTRALIBS_PPC): Add libgcc.xcoff.
+
+Thu Aug 8 14:51:47 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * mt-ppc: New file, add -mrelocatable-lib and -mno-eabi to all
+ target builds for PowerPC eabi targets.
+
+Fri Jul 12 12:06:01 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw: New subdir, Mac MPW configuration support bits.
+
+Mon Jul 8 17:30:52 1996 Jim Wilson <wilson@cygnus.com>
+
+ * mh-irix6: New file.
+
+Mon Jul 8 15:15:37 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * mt-sparcpic (PICFLAG_FOR_TARGET): Use -fPIC.
+
+Fri Jul 5 11:49:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-irix4 (RANLIB): Don't define; Irix 4 does have ranlib.
+
+Sun Jun 23 22:59:25 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * mh-cygwin32: new file. Like mh-go32 without the CFLAGS entry.
+
+Tue Mar 26 14:10:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-go32 (CFLAGS): Define.
+
+Thu Mar 14 19:20:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-necv4: New file.
+
+Thu Feb 15 13:07:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-cxux (CC): New variable.
+ (CFLAGS, LDFLAGS): Remove.
+ * mh-ncrsvr43 (CC): New variable.
+ (CFLAGS): Remove.
+ * mh-solaris (CFLAGS): Remove.
+
+ * mh-go32: Remove most variable settings, since they presumed a
+ Canadian Cross, which is now handled correctly by the configure
+ script.
+
+ * mh-sparcpic (PICFLAG): Set to -fPIC, not -fpic.
+
+Mon Feb 12 14:53:39 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * mh-m68kpic, mt-m68kpic: New files.
+
+Thu Feb 1 14:15:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw (CC_MWC68K): Add options similar to those used
+ in CC_MWCPPC, and -mc68020 -model far.
+ (AR_MWLINK68K): Add -xm library.
+ (AR_AR): Define.
+ (CC_LD_MWLINK68K): Remove -d.
+ (EXTRALIBS_MWC68K): Define.
+
+Thu Jan 25 16:05:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-ncrsvr43 (CFLAGS): Remove -Hnocopyr.
+
+Tue Nov 7 15:41:30 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw (CC_MWC68K, CC_MWCPPC): Remove unused include path.
+ (CC_MWCPPC): Add -mpw_chars, disable warnings, add comments
+ explaining reasons for various flags.
+ (EXTRALIBS_PPC, EXTRALIBS_MWCPPC ): Put runtime library first.
+
+Fri Oct 13 14:44:25 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * mh-aix, mh-sun: Removed.
+
+ * mh-decstation (X11_EXTRA_CFLAGS): Define.
+
+ * mh-sco, mh-solaris, mh-sysv4 (X11_EXTRA_LIBS): Define.
+
+ * mh-hp300, mh-hpux, mh-hpux8, mh-solaris, mh-sun3, mh-sysv4: Don't
+ hardcode location of X stuff here.
+
+Thu Sep 28 13:14:56 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw: Add definitions for various 68K and PowerMac
+ compilers, add definitions for library and link steps for
+ PowerMacs.
+
+Thu Sep 14 08:20:04 1995 Fred Fish <fnf@cygnus.com>
+
+ * mh-hp300 (CC): Add "CC = cc -Wp,-H256000" to avoid
+ "too much defining" errors from the HPUX compiler.
+
+Thu Aug 17 17:28:56 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * mh-hp300 (RANLIB): Use "ar ts", in case GNU ar was used and
+ didn't build a symbol table.
+
+Thu Jun 22 17:47:24 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw (CC): Define ANSI_PROTOTYPES.
+
+Mon Apr 10 12:29:48 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-mh-mpw (EXTRALIBS): Always link in Math.o, CSANELIB.o,
+ and ToolLibs.o.
+
+ * mpw-mh-mpw (CC): Define ALMOST_STDC.
+ (CFLAGS): Remove ALMOST_STDC, -mc68881.
+ (LDFLAGS): add -w.
+
+ * mpw-mh-mpw (CFLAGS): Add -b option to put strings at the ends of
+ functions.
+
+ * mpw-mh-mpw: New file, host makefile definitions for MPW.
+
+Fri Mar 31 11:35:17 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * mt-netware: New file.
+
+Mon Mar 13 12:31:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-hpux8: New file.
+ * mh-hpux: Use X11R5 rather than X11R4.
+
+Thu Feb 9 11:04:13 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mh-linux (SYSV): Don't define.
+ (RANLIB): Don't define.
+
+Wed Jan 11 16:29:34 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * m?-*pic (LIBCXXFLAGS): Add -fno-implicit-templates.
+
+Thu Nov 3 17:27:19 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * mh-irix4 (CC): Increase maximum string length.
+
+ * mh-sco (CC): Define away const, it doesn't work right; elements
+ of arrays of ptr-to-const are considered const themselves.
+
+Sat Jul 16 12:17:49 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * mh-cxux: New file, from Bob Rusk (rrusk@mail.csd.harris.com).
+
+Sat Jun 4 17:22:12 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * mh-ncrsvr43: New file from Tom McConnell
+ <tmcconne@sedona.intel.com>.
+
+Thu May 19 00:32:11 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * mh-hpux (CC): Add -Wp,-H256000 to avoid "too much defining"
+ errors from the HPUX 8 compilers.
+
+Wed May 4 20:14:47 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * mh-lynxrs6k: set SHELL to /bin/bash
+
+Tue Apr 12 12:38:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mh-irix4 (CC): Change -XNh1500 to -XNh2000.
+
+Sat Dec 25 20:03:45 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * mt-hppa: Delete.
+
+Tue Nov 16 22:54:39 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mh-a68bsd: Define CC to gcc.
+
+Mon Nov 15 16:56:51 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mh-linux: Don't put -static in LDFLAGS. Add comments.
+
+Mon Nov 15 13:37:58 1993 david d `zoo' zuhn (zoo@cirdan.cygnus.com)
+
+ * mh-sysv4 (AR_FLAGS): change from cq to cr
+
+Fri Nov 5 08:12:32 1993 D. V. Henkel-Wallace (gumby@blues.cygnus.com)
+
+ * mh-unixware: remove. It's the same as sysv4, and config.guess
+ can't tell the difference. So don't allow skew.
+
+Wed Oct 20 20:35:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mh-hp300: Revert yesterday's change, but add comment explaining.
+
+Tue Oct 19 18:58:21 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mh-hp300: Don't define CFLAGS to empty. Why should hp300 be
+ different from anything else? ("gdb doesn't understand the native
+ debug format" isn't a good enough answer because we might be using
+ gcc).
+
+Tue Oct 5 12:17:40 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mh-alphaosf: Remove, no longer necessary now that gdb knows
+ how to handle OSF/1 shared libraries.
+
+Tue Jul 6 11:27:33 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * mh-alphaosf: New file.
+
+Thu Jul 1 15:49:33 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mh-riscos: New file.
+
+Mon Jun 14 12:03:18 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * mh-aix, mh-aix386, mh-decstation, mh-delta88, mh-hpux, mh-irix4,
+ mh-ncr3000, mh-solaris, mh-sysv, mh-sysv4: remove INSTALL=cp line,
+ now that we're using install.sh globally
+
+Fri Jun 4 16:09:34 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mh-sysv4 (INSTALL): Use cp, not /usr/ucb/install.
+
+Thu Apr 8 11:21:52 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mt-a29k, mt-ebmon29k, mt-os68k, mt-ose68000, mt-ose68k,
+ mt-vxworks68, mt-vxworks960: Removed obsolete, unused target
+ Makefile fragment files.
+
+Mon Mar 8 15:05:25 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * mh-aix386: New file; old mh-aix, plus no-op RANLIB.
+
+Thu Oct 1 13:50:48 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * mh-solaris: INSTALL is NOT /usr/ucb/install
+
+Mon Aug 24 14:25:35 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * mt-ose68000, mt-ose68k: renamed from mt-OSE*.
+
+Tue Jul 21 02:11:01 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * mt-OSE68k, mt-680000: new configs.
+
+Thu Jul 16 17:12:09 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * mh-irix4: merged changes from progressive.
+
+Tue Jun 9 23:29:38 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Everywhere: Change RANLIB=echo>/dev/null (which confuses
+ some shells - and I don't blame them) to RANLIB=true.
+ * mh-solaris: Use /usr/ucb/install for INSTALL.
+
+Sun May 31 14:45:23 1992 Mark Eichin (eichin at cygnus.com)
+
+ * mh-solaris2: Add new configuration for Solaris 2 (sysv, no ranlib)
+
+Fri Apr 10 23:10:08 1992 Fred Fish (fnf@cygnus.com)
+
+ * mh-ncr3000: Add new configuration for NCR 3000.
+
+Tue Dec 10 00:10:55 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * ChangeLog: fresh changelog.
+
diff --git a/config/acinclude.m4 b/config/acinclude.m4
new file mode 100755
index 00000000000..f799ced44dd
--- /dev/null
+++ b/config/acinclude.m4
@@ -0,0 +1,1994 @@
+dnl This file is included into all any other acinclude file that needs
+dnl to use these macros.
+
+dnl This is copied from autoconf 2.12, but does calls our own AC_PROG_CC_WORKS,
+dnl and doesn't call AC_PROG_CXX_GNU, cause we test for that in AC_PROG_CC_WORKS.
+dnl We are probably using a cross compiler, which will not be able to fully
+dnl link an executable. This should really be fixed in autoconf itself.
+dnl Find a working G++ cross compiler. This only works for the GNU C++ compiler.
+AC_DEFUN(CYG_AC_PROG_CXX_CROSS,
+[AC_BEFORE([$0], [AC_PROG_CXXCPP])
+AC_CHECK_PROGS(CXX, $CCC c++ g++ gcc CC cxx cc++, gcc)
+
+CYG_AC_PROG_GXX_WORKS
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+dnl Check whether -g works, even if CXXFLAGS is set, in case the package
+dnl plays around with CXXFLAGS (such as to build both debugging and
+dnl normal versions of a library), tasteless as that idea is.
+ ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS=
+ AC_PROG_CXX_G
+ if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ elif test $ac_cv_prog_cxx_g = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-O2"
+ fi
+else
+ GXX=
+ test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
+fi
+])
+
+dnl See if the G++ compiler we found works.
+AC_DEFUN(CYG_AC_PROG_GXX_WORKS,
+[AC_MSG_CHECKING([whether the G++ compiler ($CXX $CXXFLAGS $LDFLAGS) actually works])
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+dnl Try a test case. We only compile, because it's close to impossible
+dnl to get a correct fully linked executable with a cross compiler. For
+dnl most cross compilers, this test is bogus. For G++, we can use various
+dnl other compile line options to get a decent idea that the cross compiler
+dnl actually does work, even though we can't produce an executable without
+dnl more info about the target it's being compiled for. This only works
+dnl for the GNU C++ compiler.
+
+dnl Transform the name of the compiler to it's cross variant, unless
+dnl CXX is set. This is also what CXX gets set to in the generated
+dnl Makefile.
+if test x"${CXX}" = xc++ ; then
+ CXX=`echo gcc | sed -e "${program_transform_name}"`
+fi
+
+dnl Get G++'s full path to libgcc.a
+libgccpath=`${CXX} --print-libgcc`
+
+dnl If we don't have a path with libgcc.a on the end, this isn't G++.
+if test `echo $libgccpath | sed -e 's:/.*/::'` = libgcc.a ; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+
+dnl If we are using G++, look for the files that need to exist if this
+dnl compiler works.
+if test x"${ac_cv_prog_gxx}" = xyes ; then
+ gccfiles=`echo $libgccpath | sed -e 's:/libgcc.a::'`
+ if test -f ${gccfiles}/specs -a -f ${gccfiles}/cpp -a -f ${gccfiles}/cc1plus; then
+ gccfiles=yes
+ else
+ gccfiles=no
+ fi
+ gcclibs=`echo $libgccpath | sed -e 's:lib/gcc-lib/::' -e 's:/libgcc.a::' -e 's,\(.*\)/.*,\1,g'`/lib
+ if test -d ${gcclibs}/ldscripts -a -f ${gcclibs}/libc.a -a -f ${gcclibs}/libstdc++.a ; then
+ gcclibs=yes
+ else
+ gcclibs=no
+ fi
+fi
+
+dnl If everything is OK, then we can safely assume the compiler works.
+if test x"${gccfiles}" = xno -o x"${gcclibs}" = xno; then
+ ac_cv_prog_cxx_works=no
+ AC_MSG_ERROR(${CXX} is a non-working cross compiler)
+else
+ ac_cv_prog_cxx_works=yes
+fi
+
+AC_LANG_RESTORE
+AC_MSG_RESULT($ac_cv_prog_cxx_works)
+if test x"$ac_cv_prog_cxx_works" = xno; then
+ AC_MSG_ERROR([installation or configuration problem: C++ compiler cannot create executables.])
+fi
+AC_MSG_CHECKING([whether the G++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler])
+AC_MSG_RESULT($ac_cv_prog_cxx_cross)
+cross_compiling=$ac_cv_prog_cxx_cross
+AC_SUBST(CXX)
+])
+
+dnl ====================================================================
+dnl Find a working GCC cross compiler. This only works for the GNU gcc compiler.
+dnl This is based on the macros above for G++.
+AC_DEFUN(CYG_AC_PROG_CC_CROSS,
+[AC_BEFORE([$0], [AC_PROG_CCPP])
+AC_CHECK_PROGS(CC, cc, gcc)
+
+CYG_AC_PROG_GCC_WORKS
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+dnl Check whether -g works, even if CFLAGS is set, in case the package
+dnl plays around with CFLAGS (such as to build both debugging and
+dnl normal versions of a library), tasteless as that idea is.
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ AC_PROG_CC_G
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GXX=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+])
+
+dnl See if the GCC compiler we found works.
+AC_DEFUN(CYG_AC_PROG_GCC_WORKS,
+[AC_MSG_CHECKING([whether the Gcc compiler ($CC $CFLAGS $LDFLAGS) actually works])
+AC_LANG_SAVE
+AC_LANG_C
+dnl Try a test case. We only compile, because it's close to impossible
+dnl to get a correct fully linked executable with a cross
+dnl compiler. For most cross compilers, this test is bogus. For G++,
+dnl we can use various other compile line options to get a decent idea
+dnl that the cross compiler actually does work, even though we can't
+dnl produce an executable without more info about the target it's
+dnl being compiled for. This only works for the GNU C++ compiler.
+
+dnl Transform the name of the compiler to it's cross variant, unless
+dnl CXX is set. This is also what CC gets set to in the generated Makefile.
+if test x"${CC}" = xcc ; then
+ CC=`echo gcc | sed -e "${program_transform_name}"`
+fi
+
+dnl Get Gcc's full path to libgcc.a
+libgccpath=`${CC} --print-libgcc`
+
+dnl If we don't have a path with libgcc.a on the end, this isn't G++.
+if test `echo $libgccpath | sed -e 's:/.*/::'` = libgcc.a ; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+
+dnl If we are using Gcc, look for the files that need to exist if this
+dnl compiler works.
+if test x"${ac_cv_prog_gcc}" = xyes ; then
+ gccfiles=`echo $libgccpath | sed -e 's:/libgcc.a::'`
+ if test -f ${gccfiles}/specs -a -f ${gccfiles}/cpp -a -f ${gccfiles}/cc1plus; then
+ gccfiles=yes
+ else
+ gccfiles=no
+ fi
+ gcclibs=`echo $libgccpath | sed -e 's:lib/gcc-lib/::' -e 's:/libgcc.a::' -e 's,\(.*\)/.*,\1,g'`/lib
+ if test -d ${gcclibs}/ldscripts -a -f ${gcclibs}/libc.a -a -f ${gcclibs}/libstdc++.a ; then
+ gcclibs=yes
+ else
+ gcclibs=no
+ fi
+fi
+
+dnl If everything is OK, then we can safely assume the compiler works.
+if test x"${gccfiles}" = xno -o x"${gcclibs}" = xno; then
+ ac_cv_prog_cc_works=no
+ AC_MSG_ERROR(${CC} is a non-working cross compiler)
+else
+ ac_cv_prog_cc_works=yes
+fi
+
+AC_LANG_RESTORE
+AC_MSG_RESULT($ac_cv_prog_cc_works)
+if test x"$ac_cv_prog_cc_works" = xno; then
+ AC_MSG_ERROR([installation or configuration problem: C++ compiler cannot create executables.])
+fi
+AC_MSG_CHECKING([whether the Gcc compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler])
+AC_MSG_RESULT($ac_cv_prog_cc_cross)
+cross_compiling=$ac_cv_prog_cc_cross
+AC_SUBST(CC)
+])
+
+dnl ====================================================================
+dnl Find the BFD library in the build tree. This is used to access and
+dnl manipulate object or executable files.
+AC_DEFUN(CYG_AC_PATH_BFD, [
+AC_MSG_CHECKING(for the bfd header in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+dnl Look for the header file
+AC_CACHE_VAL(ac_cv_c_bfdh,[
+for i in $dirlist; do
+ if test -f "$i/bfd/bfd.h" ; then
+ ac_cv_c_bfdh=`(cd $i/bfd; pwd)`
+ break
+ fi
+done
+])
+if test x"${ac_cv_c_bfdh}" != x; then
+ BFDHDIR="-I${ac_cv_c_bfdh}"
+ AC_MSG_RESULT(${ac_cv_c_bfdh})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(BFDHDIR)
+
+dnl Look for the library
+AC_MSG_CHECKING(for the bfd library in the build tree)
+AC_CACHE_VAL(ac_cv_c_bfdlib,[
+for i in $dirlist; do
+ if test -f "$i/bfd/Makefile" ; then
+ ac_cv_c_bfdlib=`(cd $i/bfd; pwd)`
+ fi
+done
+])
+dnl We list two directories cause bfd now uses libtool
+if test x"${ac_cv_c_bfdlib}" != x; then
+ BFDLIB="-L${ac_cv_c_bfdlib} -L${ac_cv_c_bfdlib}/.libs"
+ AC_MSG_RESULT(${ac_cv_c_bfdlib})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(BFDLIB)
+])
+
+dnl ====================================================================
+dnl Find the libiberty library. This defines many commonly used C
+dnl functions that exists in various states based on the underlying OS.
+AC_DEFUN(CYG_AC_PATH_LIBERTY, [
+AC_MSG_CHECKING(for the liberty library in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_liberty,[
+for i in $dirlist; do
+ if test -f "$i/libiberty/Makefile" ; then
+ ac_cv_c_liberty=`(cd $i/libiberty; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_liberty}" != x; then
+ LIBERTY="-L${ac_cv_c_liberty}"
+ AC_MSG_RESULT(${ac_cv_c_liberty})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(LIBERTY)
+])
+
+dnl ====================================================================
+dnl Find the opcodes library. This is used to do dissasemblies.
+AC_DEFUN(CYG_AC_PATH_OPCODES, [
+AC_MSG_CHECKING(for the opcodes library in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_opc,[
+for i in $dirlist; do
+ if test -f "$i/opcodes/Makefile" ; then
+ ac_cv_c_opc=`(cd $i/opcodes; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_opc}" != x; then
+ OPCODESLIB="-L${ac_cv_c_opc}"
+ AC_MSG_RESULT(${ac_cv_c_opc})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(OPCODESLIB)
+])
+
+dnl ====================================================================
+dnl Look for the DejaGnu header file in the source tree. This file
+dnl defines the functions used to testing support.
+AC_DEFUN(CYG_AC_PATH_DEJAGNU, [
+AC_MSG_CHECKING(for the testing support files in the source tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_dejagnu,[
+for i in $dirlist; do
+ if test -f "$srcdir/$i/ecc/ecc/infra/testlib/current/include/dejagnu.h" ; then
+ ac_cv_c_dejagnu=`(cd $srcdir/$i/ecc/ecc/infra/testlib/current/include; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_dejagnu}" != x; then
+ DEJAGNUHDIR="-I${ac_cv_c_dejagnu}"
+ AC_MSG_RESULT(${ac_cv_c_dejagnu})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_CACHE_VAL(ac_cv_c_dejagnulib,[
+for i in $dirlist; do
+ if test -f "$srcdir/$i/infra/testlib/current/lib/hostutil.exp" ; then
+ ac_cv_c_dejagnulib=`(cd $srcdir/$i/infra/testlib/current/lib; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_dejagnulib}" != x; then
+ DEJAGNULIB="${ac_cv_c_dejagnulib}"
+else
+ DEJAGNULIB=""
+fi
+AC_MSG_CHECKING(for runtest in the source tree)
+AC_CACHE_VAL(ac_cv_c_runtest,[
+for i in $dirlist; do
+ if test -f "$srcdir/$i/dejagnu/runtest" ; then
+ ac_cv_c_runtest=`(cd $srcdir/$i/dejagnu; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_runtest}" != x; then
+ RUNTESTDIR="${ac_cv_c_runtest}"
+ AC_MSG_RESULT(${ac_cv_c_runtest})
+else
+ RUNTESTDIR=""
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(RUNTESTDIR)
+AC_SUBST(DEJAGNULIB)
+AC_SUBST(DEJAGNUHDIR)
+])
+
+dnl ====================================================================
+dnl Find the libintl library in the build tree. This is for
+dnl internationalization support.
+AC_DEFUN(CYG_AC_PATH_INTL, [
+AC_MSG_CHECKING(for the intl header in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+dnl Look for the header file
+AC_CACHE_VAL(ac_cv_c_intlh,[
+for i in $dirlist; do
+ if test -f "$i/intl/libintl.h" ; then
+ ac_cv_c_intlh=`(cd $i/intl; pwd)`
+ break
+ fi
+done
+])
+if test x"${ac_cv_c_intlh}" != x; then
+ INTLHDIR="-I${ac_cv_c_intlh}"
+ AC_MSG_RESULT(${ac_cv_c_intlh})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(INTLHDIR)
+
+dnl Look for the library
+AC_MSG_CHECKING(for the libintl library in the build tree)
+AC_CACHE_VAL(ac_cv_c_intllib,[
+for i in $dirlist; do
+ if test -f "$i/intl/Makefile" ; then
+ ac_cv_c_intllib=`(cd $i/intl; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_intllib}" != x; then
+ INTLLIB="-L${ac_cv_c_intllib} -lintl"
+ AC_MSG_RESULT(${ac_cv_c_intllib})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(INTLLIB)
+])
+
+dnl ====================================================================
+dnl Find the simulator library.
+AC_DEFUN(CYG_AC_PATH_SIM, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.. ../../../../../../../../../.."
+case "$target_cpu" in
+ powerpc) target_dir=ppc ;;
+ sparc*) target_dir=erc32 ;;
+ mips*) target_dir=mips ;;
+ *) target_dir=$target_cpu ;;
+esac
+dnl First look for the header file
+AC_MSG_CHECKING(for the simulator header file)
+AC_CACHE_VAL(ac_cv_c_simh,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/include/remote-sim.h" ; then
+ ac_cv_c_simh=`(cd ${srcdir}/$i/include; pwd)`
+ break
+ fi
+done
+])
+if test x"${ac_cv_c_simh}" != x; then
+ SIMHDIR="-I${ac_cv_c_simh}"
+ AC_MSG_RESULT(${ac_cv_c_simh})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(SIMHDIR)
+
+dnl See whether it's a devo or Foundry branch simulator
+AC_MSG_CHECKING(Whether this is a devo simulator )
+AC_CACHE_VAL(ac_cv_c_simdevo,[
+ CPPFLAGS="$CPPFLAGS $SIMHDIR"
+ AC_EGREP_HEADER([SIM_DESC sim_open.*struct _bfd], remote-sim.h,
+ ac_cv_c_simdevo=yes,
+ ac_cv_c_simdevo=no)
+])
+if test x"$ac_cv_c_simdevo" = x"yes" ; then
+ AC_DEFINE(HAVE_DEVO_SIM)
+fi
+AC_MSG_RESULT(${ac_cv_c_simdevo})
+AC_SUBST(HAVE_DEVO_SIM)
+
+dnl Next look for the library
+AC_MSG_CHECKING(for the simulator library)
+AC_CACHE_VAL(ac_cv_c_simlib,[
+for i in $dirlist; do
+ if test -f "$i/sim/$target_dir/Makefile" ; then
+ ac_cv_c_simlib=`(cd $i/sim/$target_dir; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_simlib}" != x; then
+ SIMLIB="-L${ac_cv_c_simlib}"
+else
+ AC_MSG_RESULT(none)
+ dnl FIXME: this is kinda bogus, cause umtimately the TM will build
+ dnl all the libraries for several architectures. But for now, this
+ dnl will work till then.
+dnl AC_MSG_CHECKING(for the simulator installed with the compiler libraries)
+ dnl Transform the name of the compiler to it's cross variant, unless
+ dnl CXX is set. This is also what CXX gets set to in the generated
+ dnl Makefile.
+ CROSS_GCC=`echo gcc | sed -e "s/^/$target/"`
+
+ dnl Get G++'s full path to libgcc.a
+changequote(,)
+ gccpath=`${CROSS_GCC} --print-libgcc | sed -e 's:[a-z0-9A-Z\.\-]*/libgcc.a::' -e 's:lib/gcc-lib/::'`lib
+changequote([,])
+ if test -f $gccpath/libsim.a -o -f $gccpath/libsim.so ; then
+ ac_cv_c_simlib="$gccpath/"
+ SIMLIB="-L${ac_cv_c_simlib}"
+ AC_MSG_RESULT(${ac_cv_c_simlib})
+ else
+ AM_CONDITIONAL(PSIM, test x$psim = xno)
+ SIMLIB=""
+ AC_MSG_RESULT(none)
+dnl ac_cv_c_simlib=none
+ fi
+fi
+AC_SUBST(SIMLIB)
+])
+
+dnl ====================================================================
+dnl Find the libiberty library.
+AC_DEFUN(CYG_AC_PATH_LIBIBERTY, [
+AC_MSG_CHECKING(for the libiberty library in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_libib,[
+for i in $dirlist; do
+ if test -f "$i/libiberty/Makefile" ; then
+ ac_cv_c_libib=`(cd $i/libiberty/; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_libib}" != x; then
+ LIBIBERTY="-L${ac_cv_c_libib}"
+ AC_MSG_RESULT(${ac_cv_c_libib})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(LIBIBERTY)
+])
+
+dnl ====================================================================
+AC_DEFUN(CYG_AC_PATH_DEVO, [
+AC_MSG_CHECKING(for devo headers in the source tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_devoh,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/include/remote-sim.h" ; then
+ ac_cv_c_devoh=`(cd ${srcdir}/$i/include; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_devoh}" != x; then
+ DEVOHDIR="-I${ac_cv_c_devoh}"
+ AC_MSG_RESULT(${ac_cv_c_devoh})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(DEVOHDIR)
+])
+
+dnl ====================================================================
+dnl find the IDE library and headers.
+AC_DEFUN(CYG_AC_PATH_IDE, [
+AC_MSG_CHECKING(for IDE headers in the source tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+IDEHDIR=
+IDELIB=
+AC_CACHE_VAL(ac_cv_c_ideh,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/libide/src/event.h" ; then
+ ac_cv_c_ideh=`(cd ${srcdir}/$i/libide/src; pwd)`;
+ fi
+done
+])
+if test x"${ac_cv_c_ideh}" != x; then
+ IDEHDIR="-I${ac_cv_c_ideh}"
+ AC_MSG_RESULT(${ac_cv_c_ideh})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_MSG_CHECKING(for LIBIDE TCL headers in the source tree)
+AC_CACHE_VAL(ac_cv_c_idetclh,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/libidetcl/src/idetcl.h" ; then
+ ac_cv_c_idetclh=`(cd ${srcdir}/$i/libidetcl/src; pwd)`;
+ fi
+done
+])
+if test x"${ac_cv_c_idetclh}" != x; then
+ IDEHDIR="${IDEHDIR} -I${ac_cv_c_idetclh}"
+ AC_MSG_RESULT(${ac_cv_c_idetclh})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_MSG_CHECKING(for IDE headers in the build tree)
+AC_CACHE_VAL(ac_cv_c_ideh2,[
+for i in $dirlist; do
+ if test -f "$i/libide/src/Makefile" ; then
+ ac_cv_c_ideh2=`(cd $i/libide/src; pwd)`;
+ fi
+done
+])
+if test x"${ac_cv_c_ideh2}" != x; then
+ IDEHDIR="${IDEHDIR} -I${ac_cv_c_ideh2}"
+ AC_MSG_RESULT(${ac_cv_c_ideh2})
+else
+ AC_MSG_RESULT(none)
+fi
+
+dnl look for the library
+AC_MSG_CHECKING(for IDE library)
+AC_CACHE_VAL(ac_cv_c_idelib,[
+if test x"${ac_cv_c_idelib}" = x ; then
+ for i in $dirlist; do
+ if test -f "$i/libide/src/Makefile" ; then
+ ac_cv_c_idelib=`(cd $i/libide/src; pwd)`
+ break
+ fi
+ done
+fi])
+if test x"${ac_cv_c_idelib}" != x ; then
+ IDELIB="-L${ac_cv_c_idelib}"
+ AC_MSG_RESULT(${ac_cv_c_idelib})
+else
+ AC_MSG_RESULT(none)
+fi
+
+dnl find libiddetcl.a if it exists
+AC_MSG_CHECKING(for IDE TCL library)
+AC_CACHE_VAL(ac_cv_c_idetcllib,[
+if test x"${ac_cv_c_idetcllib}" = x ; then
+ for i in $dirlist; do
+ if test -f "$i/libidetcl/src/Makefile" ; then
+ ac_cv_c_idetcllib=`(cd $i/libidetcl/src; pwd)`
+ break
+ fi
+ done
+fi
+])
+if test x"${ac_cv_c_idetcllib}" != x ; then
+ IDELIB="${IDELIB} -L${ac_cv_c_idetcllib}"
+ IDETCLLIB="-lidetcl"
+ AC_MSG_RESULT(${ac_cv_c_idetcllib})
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(IDEHDIR)
+AC_SUBST(IDELIB)
+AC_SUBST(IDETCLLIB)
+])
+
+dnl ====================================================================
+dnl Find all the ILU headers and libraries
+AC_DEFUN(CYG_AC_PATH_ILU, [
+AC_MSG_CHECKING(for ILU kernel headers in the source tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_iluh,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/ilu/runtime/kernel/method.h" ; then
+ ac_cv_c_iluh=`(cd ${srcdir}/$i/ilu/runtime/kernel; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_iluh}" != x; then
+ ILUHDIR="-I${ac_cv_c_iluh}"
+ AC_MSG_RESULT(${ac_cv_c_iluh})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_MSG_CHECKING(for ILU kernel headers in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+AC_CACHE_VAL(ac_cv_c_iluh5,[
+for i in $dirlist; do
+ if test -f "$i/ilu/runtime/kernel/iluconf.h" ; then
+ ac_cv_c_iluh5=`(cd $i/ilu/runtime/kernel; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_iluh5}" != x; then
+ ILUHDIR="${ILUHDIR} -I${ac_cv_c_iluh5}"
+ AC_MSG_RESULT(${ac_cv_c_iluh5})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_MSG_CHECKING(for ILU C++ headers in the source tree)
+AC_CACHE_VAL(ac_cv_c_iluh2,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/ilu/stubbers/cpp/resource.h" ; then
+ ac_cv_c_iluh2=`(cd ${srcdir}/$i/ilu/stubbers/cpp; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_iluh2}" != x; then
+ ILUHDIR="${ILUHDIR} -I${ac_cv_c_iluh2}"
+ AC_MSG_RESULT(${ac_cv_c_iluh2})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_MSG_CHECKING(for ILU C headers)
+AC_CACHE_VAL(ac_cv_c_iluh3,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/ilu/stubbers/c/resource.h" ; then
+ ac_cv_c_iluh3=`(cd ${srcdir}/$i/ilu/stubbers/c ; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_iluh3}" != x; then
+ ILUHDIR="${ILUHDIR} -I${ac_cv_c_iluh3}"
+ AC_MSG_RESULT(${ac_cv_c_iluh3})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_MSG_CHECKING(for ILU C runtime headers)
+AC_CACHE_VAL(ac_cv_c_iluh4,[
+for i in $dirlist; do
+ if test -f "${srcdir}/$i/ilu/runtime/c/ilucstub.h" ; then
+ ac_cv_c_iluh4=`(cd ${srcdir}/$i/ilu/runtime/c ; pwd)`
+ fi
+done
+])
+if test x"${ac_cv_c_iluh4}" != x; then
+ ILUHDIR="${ILUHDIR} -I${ac_cv_c_iluh4}"
+ AC_MSG_RESULT(${ac_cv_c_iluh4})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_CACHE_VAL(ac_cv_c_ilupath,[
+for i in $dirlist; do
+ if test -f "$i/ilu/Makefile" ; then
+ ac_cv_c_ilupath=`(cd $i/ilu; pwd)`
+ break
+ fi
+done
+])
+ILUTOP=${ac_cv_c_ilupath}
+
+AC_MSG_CHECKING(for the ILU library in the build tree)
+AC_CACHE_VAL(ac_cv_c_ilulib,[
+if test -f "$ac_cv_c_ilupath/runtime/kernel/Makefile" ; then
+ ac_cv_c_ilulib=`(cd $ac_cv_c_ilupath/runtime/kernel; pwd)`
+ AC_MSG_RESULT(found ${ac_cv_c_ilulib}/libilu.a)
+else
+ AC_MSG_RESULT(no)
+fi])
+
+AC_MSG_CHECKING(for the ILU C++ bindings library in the build tree)
+AC_CACHE_VAL(ac_cv_c_ilulib2,[
+if test -f "$ac_cv_c_ilupath/runtime/cpp/Makefile" ; then
+ ac_cv_c_ilulib2=`(cd $ac_cv_c_ilupath/runtime/cpp; pwd)`
+ AC_MSG_RESULT(found ${ac_cv_c_ilulib2}/libilu-c++.a)
+else
+ AC_MSG_RESULT(no)
+fi])
+
+AC_MSG_CHECKING(for the ILU C bindings library in the build tree)
+AC_CACHE_VAL(ac_cv_c_ilulib3,[
+if test -f "$ac_cv_c_ilupath/runtime/c/Makefile" ; then
+ ac_cv_c_ilulib3=`(cd $ac_cv_c_ilupath/runtime/c; pwd)`
+ AC_MSG_RESULT(found ${ac_cv_c_ilulib3}/libilu-c.a)
+else
+ AC_MSG_RESULT(no)
+fi])
+
+AC_MSG_CHECKING(for the ILU Tk bindings library in the build tree)
+AC_CACHE_VAL(ac_cv_c_ilulib4,[
+if test -f "$ac_cv_c_ilupath/runtime/mainloop/Makefile" ; then
+ ac_cv_c_ilulib4=`(cd $ac_cv_c_ilupath/runtime/mainloop; pwd)`
+ AC_MSG_RESULT(found ${ac_cv_c_ilulib4}/libilu-tk.a)
+else
+ AC_MSG_RESULT(no)
+fi])
+
+if test x"${ac_cv_c_ilulib}" = x -a x"${ac_cv_c_ilulib2}" = x; then
+ ILUHDIR=""
+fi
+
+if test x"${ac_cv_c_ilulib}" != x -a x"${ac_cv_c_ilulib2}" != x; then
+ ILULIB="-L${ac_cv_c_ilulib} -L${ac_cv_c_ilulib2} -L${ac_cv_c_ilulib3} -L${ac_cv_c_ilulib4}"
+else
+ ILULIB=""
+fi
+
+if test x"${ILULIB}" = x; then
+ AC_MSG_CHECKING(for ILU libraries installed with the compiler)
+ AC_CACHE_VAL(ac_cv_c_ilulib5,[
+ NATIVE_GCC=`echo gcc | sed -e "${program_transform_name}"`
+
+ dnl Get G++'s full path to it's libraries
+ ac_cv_c_ilulib5=`${NATIVE_GCC} --print-libgcc | sed -e 's:lib/gcc-lib/.*::'`lib
+ if test -f $ac_cv_c_ilulib5/libilu-c.a -o -f $ac_cv_c_ilulib5/libilu-c.so ; then
+ if test x"${ILUHDIR}" = x; then
+ ILUHDIR="-I${ac_cv_c_ilulib5}/../include"
+ fi
+ ILULIB="-L${ac_cv_c_ilulib5}"
+ AC_MSG_RESULT(${ac_cv_c_ilulib5})
+ else
+ ac_cv_c_ilulib=none
+ AC_MSG_RESULT(none)
+ fi
+fi])
+AC_SUBST(ILUHDIR)
+AC_SUBST(ILULIB)
+AC_SUBST(ILUTOP)
+])
+
+dnl ====================================================================
+dnl This defines the byte order for the host. We can't use
+dnl AC_C_BIGENDIAN, cause we want to create a config file and
+dnl substitue the real value, so the header files work right
+AC_DEFUN(CYG_AC_C_ENDIAN, [
+AC_MSG_CHECKING(to see if this is a little endian host)
+AC_CACHE_VAL(ac_cv_c_little_endian, [
+ac_cv_c_little_endian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/param.h>], [
+#if !BYTE_ORDER || !_BIG_ENDIAN || !_LITTLE_ENDIAN
+ bogus endian macros
+#endif], [# It does; now see whether it defined to _LITTLE_ENDIAN or not.
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/param.h>], [
+#if BYTE_ORDER != _LITTLE_ENDIAN
+ not big endian
+#endif], ac_cv_c_little_endian=yes, ac_cv_c_little_endian=no)
+])
+if test ${ac_cv_c_little_endian} = unknown; then
+old_cflags=$CFLAGS
+CFLAGS=-g
+AC_TRY_RUN([
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[0] == 1);
+}],
+ac_cv_c_little_endian=no,
+ac_cv_c_little_endian=yes,[
+dnl Yes, this is ugly, and only used for a canadian cross anyway. This
+dnl is just to keep configure from stopping here.
+case "${host}" in
+changequote(,)
+ i[3456]86-*-*) ac_cv_c_little_endian=yes ;;
+ sparc*-*-*) ac_cv_c_little_endian=no ;;
+changequote([,])
+ *) AC_MSG_WARN(Can't cross compile this test) ;;
+esac])
+CFLAGS=$old_cflags
+fi])
+
+if test x"${ac_cv_c_little_endian}" = xyes; then
+ AC_DEFINE(LITTLE_ENDIAN_HOST)
+ ENDIAN="CYG_LSBFIRST";
+else
+ ENDIAN="CYG_MSBFIRST";
+fi
+AC_MSG_RESULT(${ac_cv_c_little_endian})
+AC_SUBST(ENDIAN)
+])
+
+dnl ====================================================================
+dnl Look for the path to libgcc, so we can use it to directly link
+dnl in libgcc.a with LD.
+AC_DEFUN(CYG_AC_PATH_LIBGCC,
+[AC_MSG_CHECKING([Looking for the path to libgcc.a])
+AC_LANG_SAVE
+AC_LANG_C
+
+dnl Get Gcc's full path to libgcc.a
+libgccpath=`${CC} --print-libgcc`
+
+dnl If we don't have a path with libgcc.a on the end, this isn't G++.
+if test `echo $libgccpath | sed -e 's:/.*/::'` = libgcc.a ; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+
+dnl
+if test x"${ac_cv_prog_gcc}" = xyes ; then
+ gccpath=`echo $libgccpath | sed -e 's:/libgcc.a::'`
+ LIBGCC="-L${gccpath}"
+ AC_MSG_RESULT(${gccpath})
+else
+ LIBGCC=""
+ AC_MSG_ERROR(Not using gcc)
+fi
+
+AC_LANG_RESTORE
+AC_SUBST(LIBGCC)
+])
+
+dnl ====================================================================
+dnl Ok, lets find the tcl source trees so we can use the headers
+dnl Warning: transition of version 9 to 10 will break this algorithm
+dnl because 10 sorts before 9. We also look for just tcl. We have to
+dnl be careful that we don't match stuff like tclX by accident.
+dnl the alternative search directory is involked by --with-tclinclude
+AC_DEFUN(CYG_AC_PATH_TCL, [
+ CYG_AC_PATH_TCLH
+ CYG_AC_PATH_TCLCONFIG
+ CYG_AC_LOAD_TCLCONFIG
+])
+AC_DEFUN(CYG_AC_PATH_TCLH, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+no_tcl=true
+AC_MSG_CHECKING(for Tcl headers in the source tree)
+AC_ARG_WITH(tclinclude, [ --with-tclinclude directory where tcl headers are], with_tclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tclh,[
+dnl first check to see if --with-tclinclude was specified
+if test x"${with_tclinclude}" != x ; then
+ if test -f ${with_tclinclude}/tcl.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)`
+ elif test -f ${with_tclinclude}/generic/tcl.h ; then
+ ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory doesn't contain headers])
+ fi
+fi
+
+dnl next check if it came with Tcl configuration file
+if test x"${ac_cv_c_tclconfig}" != x ; then
+ for i in $dirlist; do
+ if test -f $ac_cv_c_tclconfig/$i/generic/tcl.h ; then
+ ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/$i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tclh}" = x ; then
+ dnl find the top level Tcl source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/tcl* 2>/dev/null`" ; then
+ tclpath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Tcl source dir. We do it this way, cause there
+ dnl might be multiple version of Tcl, and we want the most recent one.
+ for i in `ls -dr $tclpath/tcl* 2>/dev/null ` ; do
+ if test -f $i/generic/tcl.h ; then
+ ac_cv_c_tclh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl check if its installed with the compiler
+if test x"${ac_cv_c_tclh}" = x ; then
+ dnl Get the path to the compiler
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/include
+ if test -f $ccpath/tcl.h; then
+ ac_cv_c_tclh=$ccpath
+ fi
+fi
+
+dnl see if one is installed
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_RESULT(none)
+ AC_CHECK_HEADER(tcl.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="")
+else
+ AC_MSG_RESULT(${ac_cv_c_tclh})
+fi
+])
+ TCLHDIR=""
+if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([Can't find any Tcl headers])
+fi
+if test x"${ac_cv_c_tclh}" != x ; then
+ no_tcl=""
+ if test x"${ac_cv_c_tclh}" != x"installed" ; then
+ if test x"${CC}" = xcl ; then
+ tmp="`cygpath --windows ${ac_cv_c_tclh}`"
+ ac_cv_c_tclh="`echo $tmp | sed -e s#\\\\\\\\#/#g`"
+ fi
+ AC_MSG_RESULT(${ac_cv_c_tclh})
+ TCLHDIR="-I${ac_cv_c_tclh}"
+ fi
+fi
+
+AC_SUBST(TCLHDIR)
+])
+
+dnl ====================================================================
+dnl Ok, lets find the tcl configuration
+AC_DEFUN(CYG_AC_PATH_TCLCONFIG, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+dnl First, look for one uninstalled.
+dnl the alternative search directory is invoked by --with-tclconfig
+if test x"${no_tcl}" = x ; then
+ dnl we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tclconfig, [ --with-tclconfig directory containing tcl configuration (tclConfig.sh)],
+ with_tclconfig=${withval})
+ AC_MSG_CHECKING([for Tcl configuration script])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ dnl First check to see if --with-tclconfig was specified.
+ if test x"${with_tclconfig}" != x ; then
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ dnl next check if it came with Tcl configuration file in the source tree
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in $dirlist; do
+ if test -f $srcdir/$i/unix/tclConfig.sh ; then
+ ac_cv_c_tclconfig=`(cd $srcdir/$i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+ dnl check in a few other locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ dnl find the top level Tcl source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $i/tcl* 2>/dev/null`" ; then
+ tclconfpath=$i
+ break
+ fi
+ done
+
+ dnl find the exact Tcl dir. We do it this way, cause there
+ dnl might be multiple version of Tcl, and we want the most recent one.
+ for i in `ls -dr $tclconfpath/tcl* 2>/dev/null ` ; do
+ if test -f $i/unix/tclConfig.sh ; then
+ ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ dnl Check to see if it's installed. We have to look in the $CC path
+ dnl to find it, cause our $prefix may not match the compilers.
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ dnl Get the path to the compiler
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/lib
+ if test -f $ccpath/tclConfig.sh; then
+ ac_cv_c_tclconfig=$ccpath
+ fi
+ fi
+ ]) dnl end of cache_val
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCLCONFIG=""
+ AC_MSG_WARN(Can't find Tcl configuration definitions)
+ else
+ no_tcl=""
+ TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh
+ AC_MSG_RESULT(${TCLCONFIG})
+ fi
+fi
+AC_SUBST(TCLCONFIG)
+])
+
+dnl Defined as a separate macro so we don't have to cache the values
+dnl from PATH_TCLCONFIG (because this can also be cached).
+AC_DEFUN(CYG_AC_LOAD_TCLCONFIG, [
+ . $TCLCONFIG
+
+dnl AC_SUBST(TCL_VERSION)
+dnl AC_SUBST(TCL_MAJOR_VERSION)
+dnl AC_SUBST(TCL_MINOR_VERSION)
+dnl AC_SUBST(TCL_CC)
+ AC_SUBST(TCL_DEFS)
+
+dnl not used, don't export to save symbols
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FULL_PATH)
+ AC_SUBST(TCL_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_PREFIX)
+
+ AC_SUBST(TCL_CFLAGS)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_EXEC_PREFIX)
+
+ AC_SUBST(TCL_SHLIB_CFLAGS)
+ AC_SUBST(TCL_SHLIB_LD)
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_SHLIB_LD_LIBS)
+dnl AC_SUBST(TCL_SHLIB_SUFFIX)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_DL_LIBS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_LD_SEARCH_FLAGS)
+dnl don't export, not used outside of configure
+dnl AC_SUBST(TCL_COMPAT_OBJS)
+ AC_SUBST(TCL_RANLIB)
+ AC_SUBST(TCL_BUILD_LIB_SPEC)
+ AC_SUBST(TCL_LIB_SPEC)
+dnl AC_SUBST(TCL_LIB_VERSIONS_OK)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX)
+])
+
+dnl ====================================================================
+AC_DEFUN(CYG_AC_PATH_TK, [
+ CYG_AC_PATH_TKH
+ CYG_AC_PATH_TKCONFIG
+ CYG_AC_LOAD_TKCONFIG
+])
+AC_DEFUN(CYG_AC_PATH_TKH, [
+#
+# Ok, lets find the tk source trees so we can use the headers
+# If the directory (presumably symlink) named "tk" exists, use that one
+# in preference to any others. Same logic is used when choosing library
+# and again with Tcl. The search order is the best place to look first, then in
+# decreasing significance. The loop breaks if the trigger file is found.
+# Note the gross little conversion here of srcdir by cd'ing to the found
+# directory. This converts the path from a relative to an absolute, so
+# recursive cache variables for the path will work right. We check all
+# the possible paths in one loop rather than many seperate loops to speed
+# things up.
+# the alternative search directory is involked by --with-tkinclude
+#
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+no_tk=true
+AC_MSG_CHECKING(for Tk headers in the source tree)
+AC_ARG_WITH(tkinclude, [ --with-tkinclude directory where tk headers are], with_tkinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tkh,[
+dnl first check to see if --with-tkinclude was specified
+if test x"${with_tkinclude}" != x ; then
+ if test -f ${with_tkinclude}/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)`
+ elif test -f ${with_tkinclude}/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory doesn't contain headers])
+ fi
+fi
+
+dnl next check if it came with Tk configuration file
+if test x"${ac_cv_c_tkconfig}" != x ; then
+ for i in $dirlist; do
+ if test -f $ac_cv_c_tkconfig/$i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/$i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tkh}" = x ; then
+ dnl find the top level Tk source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/tk* 2>/dev/null`" ; then
+ tkpath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Tk source dir. We do it this way, cause there
+ dnl might be multiple version of Tk, and we want the most recent one.
+ for i in `ls -dr $tkpath/tk* 2>/dev/null ` ; do
+ if test -f $i/generic/tk.h ; then
+ ac_cv_c_tkh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl see if one is installed
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_RESULT(none)
+ dnl Get the path to the compiler. We do it this way instead of using
+ dnl AC_CHECK_HEADER, cause this doesn't depend in having X configured.
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/include
+ if test -f $ccpath/tk.h; then
+ ac_cv_c_tkh=$ccpath
+ fi
+else
+ AC_MSG_RESULT(${ac_cv_c_tkh})
+fi
+])
+ TKHDIR=""
+if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([Can't find any Tk headers])
+fi
+if test x"${ac_cv_c_tkh}" != x ; then
+ no_tk=""
+ if test x"${ac_cv_c_tkh}" != x"installed" ; then
+ if test x"${CC}" = xcl ; then
+ tmp="`cygpath --windows ${ac_cv_c_tkh}`"
+ ac_cv_c_tkh="`echo $tmp | sed -e s#\\\\\\\\#/#g`"
+ fi
+ AC_MSG_RESULT([found in ${ac_cv_c_tkh}])
+ TKHDIR="-I${ac_cv_c_tkh}"
+ fi
+fi
+
+AC_SUBST(TKHDIR)
+])
+
+AC_DEFUN(CYG_AC_PATH_TKCONFIG, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+dnl First, look for one uninstalled.
+dnl the alternative search directory is invoked by --with-tkconfig
+if test x"${no_tk}" = x ; then
+ dnl we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tkconfig, [ --with-tkconfig directory containing tk configuration (tkConfig.sh)],
+ with_tkconfig=${withval})
+ AC_MSG_CHECKING([for Tk configuration script])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ dnl First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ dnl next check if it came with Tk configuration file in the source tree
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in $dirlist; do
+ if test -f $srcdir/$i/unix/tkConfig.sh ; then
+ ac_cv_c_tkconfig=`(cd $srcdir/$i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+ dnl check in a few other locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ dnl find the top level Tk source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $i/tk* 2>/dev/null`" ; then
+ tkconfpath=$i
+ break
+ fi
+ done
+
+ dnl find the exact Tk dir. We do it this way, cause there
+ dnl might be multiple version of Tk, and we want the most recent one.
+ for i in `ls -dr $tkconfpath/tk* 2>/dev/null ` ; do
+ if test -f $i/unix/tkConfig.sh ; then
+ ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ dnl Check to see if it's installed. We have to look in the $CC path
+ dnl to find it, cause our $prefix may not match the compilers.
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ dnl Get the path to the compiler
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/lib
+ if test -f $ccpath/tkConfig.sh; then
+ ac_cv_c_tkconfig=$ccpath
+ fi
+ fi
+ ]) dnl end of cache_val
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TKCONFIG=""
+ AC_MSG_WARN(Can't find Tk configuration definitions)
+ else
+ no_tk=""
+ TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh
+ AC_MSG_RESULT(${TKCONFIG})
+ fi
+fi
+AC_SUBST(TKCONFIG)
+])
+
+dnl Defined as a separate macro so we don't have to cache the values
+dnl from PATH_TKCONFIG (because this can also be cached).
+AC_DEFUN(CYG_AC_LOAD_TKCONFIG, [
+ if test -f "$TKCONFIG" ; then
+ . $TKCONFIG
+ fi
+
+ AC_SUBST(TK_VERSION)
+dnl not actually used, don't export to save symbols
+dnl AC_SUBST(TK_MAJOR_VERSION)
+dnl AC_SUBST(TK_MINOR_VERSION)
+ AC_SUBST(TK_DEFS)
+
+dnl not used, don't export to save symbols
+ AC_SUBST(TK_LIB_FILE)
+ AC_SUBST(TK_LIB_FULL_PATH)
+ AC_SUBST(TK_LIBS)
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_PREFIX)
+
+dnl not used, don't export to save symbols
+dnl AC_SUBST(TK_EXEC_PREFIX)
+ AC_SUBST(TK_BUILD_INCLUDES)
+ AC_SUBST(TK_XINCLUDES)
+ AC_SUBST(TK_XLIBSW)
+ AC_SUBST(TK_BUILD_LIB_SPEC)
+ AC_SUBST(TK_LIB_SPEC)
+])
+
+dnl ====================================================================
+dnl Ok, lets find the itcl source trees so we can use the headers
+dnl the alternative search directory is involked by --with-itclinclude
+AC_DEFUN(CYG_AC_PATH_ITCL, [
+ CYG_AC_PATH_ITCLH
+ CYG_AC_PATH_ITCLLIB
+ CYG_AC_PATH_ITCLSH
+ CYG_AC_PATH_ITCLMKIDX
+])
+AC_DEFUN(CYG_AC_PATH_ITCLH, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+no_itcl=true
+AC_MSG_CHECKING(for Itcl headers in the source tree)
+AC_ARG_WITH(itclinclude, [ --with-itclinclude directory where itcl headers are], with_itclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_itclh,[
+dnl first check to see if --with-itclinclude was specified
+if test x"${with_itclinclude}" != x ; then
+ if test -f ${with_itclinclude}/itcl.h ; then
+ ac_cv_c_itclh=`(cd ${with_itclinclude}; pwd)`
+ elif test -f ${with_itclinclude}/src/itcl.h ; then
+ ac_cv_c_itclh=`(cd ${with_itclinclude}/src; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclinclude} directory doesn't contain headers])
+ fi
+fi
+
+dnl next check if it came with Itcl configuration file
+if test x"${ac_cv_c_itclconfig}" != x ; then
+ for i in $dirlist; do
+ if test -f $ac_cv_c_itclconfig/$i/src/itcl.h ; then
+ ac_cv_c_itclh=`(cd $ac_cv_c_itclconfig/$i/src; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_itclh}" = x ; then
+ dnl find the top level Itcl source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/itcl* 2>/dev/null`" ; then
+ itclpath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Itcl source dir. We do it this way, cause there
+ dnl might be multiple version of Itcl, and we want the most recent one.
+ for i in `ls -dr $itclpath/itcl* 2>/dev/null ` ; do
+ if test -f $i/src/itcl.h ; then
+ ac_cv_c_itclh=`(cd $i/src; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl see if one is installed
+if test x"${ac_cv_c_itclh}" = x ; then
+ AC_MSG_RESULT(none)
+ AC_CHECK_HEADER(itcl.h, ac_cv_c_itclh=installed, ac_cv_c_itclh="")
+else
+ AC_MSG_RESULT(${ac_cv_c_itclh})
+fi
+])
+ ITCLHDIR=""
+if test x"${ac_cv_c_itclh}" = x ; then
+ AC_MSG_ERROR([Can't find any Itcl headers])
+fi
+if test x"${ac_cv_c_itclh}" != x ; then
+ no_itcl=""
+ if test x"${ac_cv_c_itclh}" != x"installed" ; then
+ AC_MSG_RESULT(${ac_cv_c_itclh})
+ ITCLHDIR="-I${ac_cv_c_itclh}"
+ fi
+fi
+
+AC_SUBST(ITCLHDIR)
+])
+
+dnl Ok, lets find the itcl library
+dnl First, look for one uninstalled.
+dnl the alternative search directory is invoked by --with-itcllib
+AC_DEFUN(CYG_AC_PATH_ITCLLIB, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+if test x"${no_itcl}" = x ; then
+ dnl we reset no_itcl incase something fails here
+ no_itcl=true
+ AC_ARG_WITH(itcllib,
+ [ --with-itcllib directory where the itcl library is],
+ with_itcllib=${withval})
+ AC_MSG_CHECKING([for Itcl library])
+ AC_CACHE_VAL(ac_cv_c_itcllib,[
+ dnl First check to see if --with-itcllib was specified.
+ if test x"${with_itcllib}" != x ; then
+ if test -f "${with_itcllib}/libitcl$TCL_SHARED_LIB_SUFFIX" ; then
+ ac_cv_c_itcllib=`(cd ${with_itcllib}; pwd)`/libitcl$TCL_SHARED_LIB_SUFFIX
+ else
+ if test -f "${with_itcllib}/libitcl$TCL_UNSHARED_LIB_SUFFIX"; then
+ ac_cv_c_itcllib=`(cd ${with_itcllib}; pwd)`/libitcl$TCL_UNSHARED_LIB_SUFFIX
+ fi
+ fi
+ fi
+ dnl then check for a Itcl library. Since these are uninstalled,
+ dnl use the simple lib name root.
+ if test x"${ac_cv_c_itcllib}" = x ; then
+ dnl find the top level Itcl build directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $i/itcl* 2>/dev/null`" ; then
+ itclpath=$i/itcl
+ break
+ fi
+ done
+ dnl Itcl 7.5 and greater puts library in subdir. Look there first.
+ if test -f "$itclpath/src/libitcl.$TCL_SHLIB_SUFFIX" ; then
+ ac_cv_c_itcllib=`(cd $itclpath/src; pwd)`
+ elif test -f "$itclpath/src/libitcl.a"; then
+ ac_cv_c_itcllib=`(cd $itclpath/src; pwd)`
+ fi
+ fi
+ dnl check in a few other private locations
+ if test x"${ac_cv_c_itcllib}" = x ; then
+ for i in ${dirlist}; do
+ if test -n "`ls -dr ${srcdir}/$i/itcl* 2>/dev/null`" ; then
+ itclpath=${srcdir}/$i
+ break
+ fi
+ done
+ for i in `ls -dr ${itclpath}/itcl* 2>/dev/null` ; do
+ dnl Itcl 7.5 and greater puts library in subdir. Look there first.
+ if test -f "$i/src/libitcl$TCL_SHLIB_SUFFIX" ; then
+ ac_cv_c_itcllib=`(cd $i/src; pwd)`
+ break
+ elif test -f "$i/src/libitcl.a"; then
+ ac_cv_c_itcllib=`(cd $i/src; pwd)`
+ break
+ fi
+ done
+ fi
+
+ dnl see if one is conveniently installed with the compiler
+ if test x"${ac_cv_c_itcllib}" = x ; then
+ dnl Get the path to the compiler
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/lib
+ dnl Itcl 7.5 and greater puts library in subdir. Look there first.
+ if test -f "${ccpath}/libitcl$TCL_SHLIB_SUFFIX" ; then
+ ac_cv_c_itcllib=`(cd ${ccpath}; pwd)`
+ elif test -f "${ccpath}/libitcl.a"; then
+ ac_cv_c_itcllib=`(cd ${ccpath}; pwd)`
+ fi
+ fi
+ ])
+ if test x"${ac_cv_c_itcllib}" = x ; then
+ ITCLLIB=""
+ AC_MSG_WARN(Can't find Itcl library)
+ else
+ ITCLLIB="-L${ac_cv_c_itcllib}"
+ AC_MSG_RESULT(${ac_cv_c_itcllib})
+ no_itcl=""
+ fi
+fi
+
+AC_PROVIDE([$0])
+AC_SUBST(ITCLLIB)
+])
+
+
+dnl ====================================================================
+dnl Ok, lets find the itcl source trees so we can use the itcl_sh script
+dnl the alternative search directory is involked by --with-itclinclude
+AC_DEFUN(CYG_AC_PATH_ITCLSH, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+no_itcl=true
+AC_MSG_CHECKING(for the itcl_sh script)
+AC_ARG_WITH(itclinclude, [ --with-itclinclude directory where itcl headers are], with_itclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_itclsh,[
+dnl first check to see if --with-itclinclude was specified
+if test x"${with_itclinclude}" != x ; then
+ if test -f ${with_itclinclude}/itcl_sh ; then
+ ac_cv_c_itclsh=`(cd ${with_itclinclude}; pwd)`
+ elif test -f ${with_itclinclude}/src/itcl_sh ; then
+ ac_cv_c_itclsh=`(cd ${with_itclinclude}/src; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclinclude} directory doesn't contain itcl_sh])
+ fi
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_itclsh}" = x ; then
+ dnl find the top level Itcl source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/itcl* 2>/dev/null`" ; then
+ itclpath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Itcl source dir. We do it this way, cause there
+ dnl might be multiple version of Itcl, and we want the most recent one.
+ for i in `ls -dr $itclpath/itcl* 2>/dev/null ` ; do
+ if test -f $i/src/itcl_sh ; then
+ ac_cv_c_itclsh=`(cd $i/src; pwd)`/itcl_sh
+ break
+ fi
+ done
+fi
+
+dnl see if one is installed
+if test x"${ac_cv_c_itclsh}" = x ; then
+ AC_MSG_RESULT(none)
+ AC_PATH_PROG(ac_cv_c_itclsh, itcl_sh)
+else
+ AC_MSG_RESULT(${ac_cv_c_itclsh})
+fi
+])
+
+if test x"${ac_cv_c_itclsh}" = x ; then
+ AC_MSG_ERROR([Can't find the itcl_sh script])
+fi
+if test x"${ac_cv_c_itclsh}" != x ; then
+ no_itcl=""
+ AC_MSG_RESULT(${ac_cv_c_itclsh})
+ ITCLSH="${ac_cv_c_itclsh}"
+fi
+AC_SUBST(ITCLSH)
+])
+
+
+dnl ====================================================================
+dnl Ok, lets find the itcl source trees so we can use the itcl_sh script
+dnl the alternative search directory is involked by --with-itclinclude
+AC_DEFUN(CYG_AC_PATH_ITCLMKIDX, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+no_itcl=true
+AC_MSG_CHECKING(for itcl_mkindex.tcl script)
+AC_ARG_WITH(itclinclude, [ --with-itclinclude directory where itcl headers are], with_itclinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_itclmkidx,[
+dnl first check to see if --with-itclinclude was specified
+if test x"${with_itclinclude}" != x ; then
+ if test -f ${with_itclinclude}/itcl_sh ; then
+ ac_cv_c_itclmkidx=`(cd ${with_itclinclude}; pwd)`
+ elif test -f ${with_itclinclude}/src/itcl_sh ; then
+ ac_cv_c_itclmkidx=`(cd ${with_itclinclude}/src; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclinclude} directory doesn't contain itcl_sh])
+ fi
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_itclmkidx}" = x ; then
+ dnl find the top level Itcl source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/itcl* 2>/dev/null`" ; then
+ itclpath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Itcl source dir. We do it this way, cause there
+ dnl might be multiple version of Itcl, and we want the most recent one.
+ for i in `ls -dr $itclpath/itcl* 2>/dev/null ` ; do
+ if test -f $i/library/itcl_mkindex.tcl ; then
+ ac_cv_c_itclmkidx=`(cd $i/library; pwd)`/itcl_mkindex.tcl
+ break
+ fi
+ done
+fi
+if test x"${ac_cv_c_itclmkidx}" = x ; then
+ dnl Get the path to the compiler
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/share
+ dnl Itcl 7.5 and greater puts library in subdir. Look there first.
+ for i in `ls -dr $ccpath/itcl* 2>/dev/null ` ; do
+ if test -f $i/itcl_mkindex.tcl ; then
+ ac_cv_c_itclmkidx=`(cd $i; pwd)`/itcl_mkindex.tcl
+ break
+ fi
+ done
+fi
+])
+
+if test x"${ac_cv_c_itclmkidx}" = x ; then
+ AC_MSG_ERROR([Can't find the itcl_mkindex.tcl script])
+fi
+if test x"${ac_cv_c_itclmkidx}" != x ; then
+ no_itcl=""
+ AC_MSG_RESULT(${ac_cv_c_itclmkidx})
+ ITCLMKIDX="${ac_cv_c_itclmkidx}"
+else
+ AC_MSG_RESULT(none)
+fi
+AC_SUBST(ITCLMKIDX)
+])
+
+dnl ====================================================================
+dnl Ok, lets find the tix source trees so we can use the headers
+dnl the alternative search directory is involked by --with-tixinclude
+AC_DEFUN(CYG_AC_PATH_TIX, [
+ CYG_AC_PATH_TIXH
+ CYG_AC_PATH_TIXLIB
+])
+AC_DEFUN(CYG_AC_PATH_TIXH, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+no_tix=true
+AC_MSG_CHECKING(for Tix headers in the source tree)
+AC_ARG_WITH(tixinclude, [ --with-tixinclude directory where tix headers are], with_tixinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_tixh,[
+dnl first check to see if --with-tixinclude was specified
+if test x"${with_tixinclude}" != x ; then
+ if test -f ${with_tixinclude}/tix.h ; then
+ ac_cv_c_tixh=`(cd ${with_tixinclude}; pwd)`
+ elif test -f ${with_tixinclude}/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd ${with_tixinclude}/generic; pwd)`
+ else
+ AC_MSG_ERROR([${with_tixinclude} directory doesn't contain headers])
+ fi
+fi
+
+dnl next check if it came with Tix configuration file
+if test x"${ac_cv_c_tixconfig}" != x ; then
+ for i in $dirlist; do
+ if test -f $ac_cv_c_tixconfig/$i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $ac_cv_c_tixconfig/$i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_tixh}" = x ; then
+ dnl find the top level Tix source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/tix* 2>/dev/null`" ; then
+ tixpath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Tix source dir. We do it this way, cause there
+ dnl might be multiple version of Tix, and we want the most recent one.
+ for i in `ls -dr $tixpath/tix* 2>/dev/null ` ; do
+ if test -f $i/generic/tix.h ; then
+ ac_cv_c_tixh=`(cd $i/generic; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl see if one is installed
+if test x"${ac_cv_c_tixh}" = x ; then
+ AC_MSG_RESULT(none)
+ dnl Get the path to the compiler
+
+ dnl Get the path to the compiler. We do it this way instead of using
+ dnl AC_CHECK_HEADER, cause this doesn't depend in having X configured.
+ ccpath=`which ${CC} | sed -e 's:/bin/.*::'`/include
+ if test -f $ccpath/tix.h; then
+ ac_cv_c_tixh=installed
+ fi
+else
+ AC_MSG_RESULT(${ac_cv_c_tixh})
+fi
+])
+if test x"${ac_cv_c_tixh}" = x ; then
+ AC_MSG_ERROR([Can't find any Tix headers])
+fi
+if test x"${ac_cv_c_tixh}" != x ; then
+ no_tix=""
+ AC_MSG_RESULT(${ac_cv_c_tixh})
+ if test x"${ac_cv_c_tixh}" != x"installed" ; then
+ TIXHDIR="-I${ac_cv_c_tixh}"
+ fi
+fi
+
+AC_SUBST(TIXHDIR)
+])
+
+AC_DEFUN(CYG_AC_PATH_TIXCONFIG, [
+#
+# Ok, lets find the tix configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-tixconfig
+#
+
+if test x"${no_tix}" = x ; then
+ # we reset no_tix in case something fails here
+ no_tix=true
+ AC_ARG_WITH(tixconfig, [ --with-tixconfig directory containing tix configuration (tixConfig.sh)],
+ with_tixconfig=${withval})
+ AC_MSG_CHECKING([for Tix configuration])
+ AC_CACHE_VAL(ac_cv_c_tixconfig,[
+
+ # First check to see if --with-tixconfig was specified.
+ if test x"${with_tixconfig}" != x ; then
+ if test -f "${with_tixconfig}/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd ${with_tixconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_tixconfig} directory doesn't contain tixConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tix library
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ../tix \
+ `ls -dr ../tix[[4]]* 2>/dev/null` \
+ ../../tix \
+ `ls -dr ../../tix[[4]]* 2>/dev/null` \
+ ../../../tix \
+ `ls -dr ../../../tix[[4]]* 2>/dev/null` ; do
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tix \
+ `ls -dr ${srcdir}/../tix[[4-9]]* 2>/dev/null` ; do
+ if test -f "$i/tixConfig.sh" ; then
+ ac_cv_c_tixconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_tixconfig}" = x ; then
+ TIXCONFIG="# no Tix configs found"
+ AC_MSG_WARN(Can't find Tix configuration definitions)
+ else
+ no_tix=
+ TIXCONFIG=${ac_cv_c_tixconfig}/tixConfig.sh
+ AC_MSG_RESULT(found $TIXCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_TIXCONFIG (because this can also be cached).
+AC_DEFUN(CYG_AC_LOAD_TIXCONFIG, [
+ if test -f "$TIXCONFIG" ; then
+ . $TIXCONFIG
+ fi
+
+ AC_SUBST(TIX_BUILD_LIB_SPEC)
+ AC_SUBST(TIX_LIB_FULL_PATH)
+])
+
+AC_DEFUN(CYG_AC_PATH_ITCLCONFIG, [
+#
+# Ok, lets find the itcl configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itclconfig
+#
+
+if test x"${no_itcl}" = x ; then
+ # we reset no_itcl in case something fails here
+ no_itcl=true
+ AC_ARG_WITH(itclconfig, [ --with-itclconfig directory containing itcl configuration (itclConfig.sh)],
+ with_itclconfig=${withval})
+ AC_MSG_CHECKING([for Itcl configuration])
+ AC_CACHE_VAL(ac_cv_c_itclconfig,[
+
+ # First check to see if --with-itclconfig was specified.
+ if test x"${with_itclconfig}" != x ; then
+ if test -f "${with_itclconfig}/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd ${with_itclconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itclconfig} directory doesn't contain itclConfig.sh])
+ fi
+ fi
+
+ # then check for a private itcl library
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ../itcl/itcl \
+ `ls -dr ../itcl/itcl[[3]]* 2>/dev/null` \
+ ../../itcl/itcl \
+ `ls -dr ../../itcl/itcl[[3]]* 2>/dev/null` \
+ ../../../itcl/itcl \
+ `ls -dr ../../../itcl/itcl[[3]]* 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itcl \
+ `ls -dr ${srcdir}/../itcl/itcl[[3]]* 2>/dev/null` ; do
+ if test -f "$i/itcl/itclConfig.sh" ; then
+ ac_cv_c_itclconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itclconfig}" = x ; then
+ ITCLCONFIG="# no itcl configs found"
+ AC_MSG_WARN(Can't find itcl configuration definitions)
+ else
+ no_itcl=
+ ITCLCONFIG=${ac_cv_c_itclconfig}/itclConfig.sh
+ AC_MSG_RESULT(found $ITCLCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITCLCONFIG (because this can also be cached).
+AC_DEFUN(CYG_AC_LOAD_ITCLCONFIG, [
+ if test -f "$ITCLCONFIG" ; then
+ . $ITCLCONFIG
+ fi
+
+ AC_SUBST(ITCL_BUILD_LIB_SPEC)
+ AC_SUBST(ITCL_SH)
+ AC_SUBST(ITCL_LIB_FILE)
+ AC_SUBST(ITCL_LIB_FULL_PATH)
+
+])
+
+
+AC_DEFUN(CYG_AC_PATH_ITKCONFIG, [
+#
+# Ok, lets find the itk configuration
+# First, look for one uninstalled.
+# the alternative search directory is invoked by --with-itkconfig
+#
+
+if test x"${no_itk}" = x ; then
+ # we reset no_itk in case something fails here
+ no_itk=true
+ AC_ARG_WITH(itkconfig, [ --with-itkconfig directory containing itk configuration (itkConfig.sh)],
+ with_itkconfig=${withval})
+ AC_MSG_CHECKING([for Itk configuration])
+ AC_CACHE_VAL(ac_cv_c_itkconfig,[
+
+ # First check to see if --with-itkconfig was specified.
+ if test x"${with_itkconfig}" != x ; then
+ if test -f "${with_itkconfig}/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd ${with_itkconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_itkconfig} directory doesn't contain itkConfig.sh])
+ fi
+ fi
+
+ # then check for a private itk library
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ../itcl/itk \
+ `ls -dr ../itcl/itk[[3]]* 2>/dev/null` \
+ ../../itcl/itk \
+ `ls -dr ../../itcl/itk[[3]]* 2>/dev/null` \
+ ../../../itcl/itk \
+ `ls -dr ../../../itcl/itk[[3]]* 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few common install locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do
+ if test -f "$i/itcl/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ # check in a few other private locations
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../itcl/itk \
+ `ls -dr ${srcdir}/../itcl/itk[[3]]* 2>/dev/null` ; do
+ if test -f "$i/itkConfig.sh" ; then
+ ac_cv_c_itkconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_itkconfig}" = x ; then
+ ITCLCONFIG="# no itk configs found"
+ AC_MSG_WARN(Can't find itk configuration definitions)
+ else
+ no_itk=
+ ITKCONFIG=${ac_cv_c_itkconfig}/itkConfig.sh
+ AC_MSG_RESULT(found $ITKCONFIG)
+ fi
+fi
+
+])
+
+# Defined as a separate macro so we don't have to cache the values
+# from PATH_ITKCONFIG (because this can also be cached).
+AC_DEFUN(CYG_AC_LOAD_ITKCONFIG, [
+ if test -f "$ITKCONFIG" ; then
+ . $ITKCONFIG
+ fi
+
+ AC_SUBST(ITK_BUILD_LIB_SPEC)
+ AC_SUBST(ITK_LIB_FILE)
+ AC_SUBST(ITK_LIB_FULL_PATH)
+])
+
+
+dnl ====================================================================
+dnl Ok, lets find the libgui source trees so we can use the headers
+dnl the alternative search directory is involked by --with-libguiinclude
+AC_DEFUN(CYG_AC_PATH_LIBGUI, [
+ CYG_AC_PATH_LIBGUIH
+ CYG_AC_PATH_LIBGUILIB
+])
+AC_DEFUN(CYG_AC_PATH_LIBGUIH, [
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../..../../../../../../../../../../.."
+no_libgui=true
+AC_MSG_CHECKING(for Libgui headers in the source tree)
+AC_ARG_WITH(libguiinclude, [ --with-libguiinclude directory where libgui headers are], with_libguiinclude=${withval})
+AC_CACHE_VAL(ac_cv_c_libguih,[
+dnl first check to see if --with-libguiinclude was specified
+if test x"${with_libguiinclude}" != x ; then
+ if test -f ${with_libguiinclude}/guitcl.h ; then
+ ac_cv_c_libguih=`(cd ${with_libguiinclude}; pwd)`
+ elif test -f ${with_libguiinclude}/src/guitcl.h ; then
+ ac_cv_c_libguih=`(cd ${with_libguiinclude}/src; pwd)`
+ else
+ AC_MSG_ERROR([${with_libguiinclude} directory doesn't contain headers])
+ fi
+fi
+
+dnl next check if it came with Libgui configuration file
+if test x"${ac_cv_c_libguiconfig}" != x ; then
+ for i in $dirlist; do
+ if test -f $ac_cv_c_libguiconfig/$i/src/guitcl.h ; then
+ ac_cv_c_libguih=`(cd $ac_cv_c_libguiconfig/$i/src; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl next check in private source directory
+dnl since ls returns lowest version numbers first, reverse its output
+if test x"${ac_cv_c_libguih}" = x ; then
+ dnl find the top level Libgui source directory
+ for i in $dirlist; do
+ if test -n "`ls -dr $srcdir/$i/libgui* 2>/dev/null`" ; then
+ libguipath=$srcdir/$i
+ break
+ fi
+ done
+
+ dnl find the exact Libgui source dir. We do it this way, cause there
+ dnl might be multiple version of Libgui, and we want the most recent one.
+ for i in `ls -dr $libguipath/libgui* 2>/dev/null ` ; do
+ if test -f $i/src/guitcl.h ; then
+ ac_cv_c_libguih=`(cd $i/src; pwd)`
+ break
+ fi
+ done
+fi
+
+dnl see if one is installed
+if test x"${ac_cv_c_libguih}" = x ; then
+ AC_MSG_RESULT(none)
+ AC_CHECK_HEADER(guitcl.h, ac_cv_c_libguih=installed, ac_cv_c_libguih="")
+fi
+])
+LIBGUIHDIR=""
+if test x"${ac_cv_c_libguih}" = x ; then
+ AC_MSG_WARN([Can't find any Libgui headers])
+fi
+if test x"${ac_cv_c_libguih}" != x ; then
+ no_libgui=""
+ if test x"${ac_cv_c_libguih}" != x"installed" ; then
+ LIBGUIHDIR="-I${ac_cv_c_libguih}"
+ fi
+fi
+AC_MSG_RESULT(${ac_cv_c_libguih})
+AC_SUBST(LIBGUIHDIR)
+])
+
+dnl ====================================================================
+dnl find the GUI library
+AC_DEFUN(CYG_AC_PATH_LIBGUILIB, [
+AC_MSG_CHECKING(for GUI library in the build tree)
+dirlist=".. ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../.. ../../../../../../../.. ../../../../../../../../.. ../../../../../../../../../.."
+dnl look for the library
+AC_MSG_CHECKING(for GUI library)
+AC_CACHE_VAL(ac_cv_c_libguilib,[
+if test x"${ac_cv_c_libguilib}" = x ; then
+ for i in $dirlist; do
+ if test -f "$i/libgui/src/Makefile" ; then
+ ac_cv_c_libguilib=`(cd $i/libgui/src; pwd)`
+ break
+ fi
+ done
+fi
+])
+if test x"${ac_cv_c_libguilib}" != x ; then
+ GUILIB="${GUILIB} -L${ac_cv_c_libguilib}"
+ LIBGUILIB="-lgui"
+ AC_MSG_RESULT(${ac_cv_c_libguilib})
+else
+ AC_MSG_RESULT(none)
+fi
+
+AC_SUBST(GUILIB)
+AC_SUBST(LIBGUILIB)
+])
diff --git a/config/mh-a68bsd b/config/mh-a68bsd
new file mode 100644
index 00000000000..c991289dd5f
--- /dev/null
+++ b/config/mh-a68bsd
@@ -0,0 +1,12 @@
+RANLIB=true
+
+#None of the Apollo compilers can compile gas or binutils. The preprocessor
+# chokes on bfd, the compiler won't let you assign integers to enums, and
+# other problems. Defining CC to gcc is a questionable way to say "don't use
+# the apollo compiler" (the preferred version of GCC could be called cc,
+# or whatever), but I'm not sure leaving CC as cc is any better...
+
+#CC=cc -A ansi -A runtype,any -A systype,any -U__STDC__ -DNO_STDARG
+CC=gcc
+
+BISON=yacc
diff --git a/config/mh-aix386 b/config/mh-aix386
new file mode 100644
index 00000000000..4accd1cddfb
--- /dev/null
+++ b/config/mh-aix386
@@ -0,0 +1 @@
+RANLIB = @:
diff --git a/config/mh-aix43 b/config/mh-aix43
new file mode 100644
index 00000000000..9eb750c2966
--- /dev/null
+++ b/config/mh-aix43
@@ -0,0 +1,4 @@
+# AIX 4.3 and above requires -X32_64 flag to all ar and nm commands
+# to handle both 32-bit and 64-bit objects.
+AR_FOR_TARGET=ar -X32_64
+NM_FOR_TARGET=nm -X32_64
diff --git a/config/mh-apollo68 b/config/mh-apollo68
new file mode 100644
index 00000000000..4497ed93585
--- /dev/null
+++ b/config/mh-apollo68
@@ -0,0 +1,3 @@
+HDEFINES = -DUSG
+RANLIB=true
+CC= cc -A ansi -A runtype,any -A systype,any -U__STDC__ -DUSG
diff --git a/config/mh-armpic b/config/mh-armpic
new file mode 100644
index 00000000000..35cf2c8ee4e
--- /dev/null
+++ b/config/mh-armpic
@@ -0,0 +1 @@
+PICFLAG=-fPIC
diff --git a/config/mh-cxux b/config/mh-cxux
new file mode 100644
index 00000000000..54b2a16c834
--- /dev/null
+++ b/config/mh-cxux
@@ -0,0 +1,14 @@
+# Configuration for Harris CX/UX 7 (and maybe 6), based on sysv4 configuration.
+
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4
+RANLIB = true
+
+# C++ debugging is not yet supported under SVR4 (DWARF)
+CXXFLAGS=-O
+
+# The l flag generates a warning from the SVR4 archiver, remove it.
+AR_FLAGS = cq
+
+# Under CX/UX, we want to tell the compiler to use ANSI mode.
+CC=cc -Xa
diff --git a/config/mh-cygwin b/config/mh-cygwin
new file mode 100644
index 00000000000..241027fb8de
--- /dev/null
+++ b/config/mh-cygwin
@@ -0,0 +1,6 @@
+EXTRA_TARGET_HOST_ALL_MODULES=all-libtermcap
+EXTRA_TARGET_HOST_INSTALL_MODULES=install-libtermcap
+
+all-gdb: all-libtermcap
+
+install-gdb: all-libtermcap
diff --git a/config/mh-decstation b/config/mh-decstation
new file mode 100644
index 00000000000..37201926d5f
--- /dev/null
+++ b/config/mh-decstation
@@ -0,0 +1,5 @@
+CC = cc -Wf,-XNg1000
+
+# for X11, since the native DECwindows include files are really broken when
+# it comes to function prototypes.
+X11_EXTRA_CFLAGS = "-DNeedFunctionPrototypes=0"
diff --git a/config/mh-delta88 b/config/mh-delta88
new file mode 100644
index 00000000000..bc9c45302d5
--- /dev/null
+++ b/config/mh-delta88
@@ -0,0 +1,4 @@
+RANLIB = true
+
+
+
diff --git a/config/mh-dgux b/config/mh-dgux
new file mode 100644
index 00000000000..e7d85d6126a
--- /dev/null
+++ b/config/mh-dgux
@@ -0,0 +1,4 @@
+HDEFINES=-DHOST_SYS=DGUX_SYS
+CC=gcc -Wall -ansi -D__using_DGUX
+RANLIB=true
+
diff --git a/config/mh-dgux386 b/config/mh-dgux386
new file mode 100644
index 00000000000..15885c3e042
--- /dev/null
+++ b/config/mh-dgux386
@@ -0,0 +1,22 @@
+# from mh-dgux
+HDEFINES=-DHOST_SYS=DGUX_SYS
+CC=gcc -Wall -ansi -D__using_DGUX
+RANLIB = true
+
+# from mh-sysv4
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4
+RANLIB = true
+
+# C++ debugging is not yet supported under SVR4 (DWARF)
+CXXFLAGS=-O
+
+# The l flag generates a warning from the SVR4 archiver, remove it.
+AR_FLAGS = cr
+
+X11_EXTRA_LIBS = -lnsl
+
+# from angela
+# no debugging due to broken compiler, use BSD style timeofday
+CFLAGS=-O -D_BSD_TIMEOFDAY_FLAVOR
+
diff --git a/config/mh-djgpp b/config/mh-djgpp
new file mode 100644
index 00000000000..f12007b0e0f
--- /dev/null
+++ b/config/mh-djgpp
@@ -0,0 +1,4 @@
+# We don't want to use debugging information on DOS. Unfortunately,
+# this requires that we set CFLAGS.
+# This used to set -fno-omit-frame-pointer.
+CFLAGS=-O2
diff --git a/config/mh-elfalphapic b/config/mh-elfalphapic
new file mode 100644
index 00000000000..35cf2c8ee4e
--- /dev/null
+++ b/config/mh-elfalphapic
@@ -0,0 +1 @@
+PICFLAG=-fPIC
diff --git a/config/mh-hp300 b/config/mh-hp300
new file mode 100644
index 00000000000..761724d92de
--- /dev/null
+++ b/config/mh-hp300
@@ -0,0 +1,13 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV
+# Avoid "too much defining" errors from HPUX compiler.
+CC = cc -Wp,-H256000
+# If "ar" in $PATH is GNU ar, the symbol table may need rebuilding.
+# If it's HP/UX ar, this should be harmless.
+RANLIB = ar ts
+
+# Native cc can't bootstrap gcc with -g. Defining CFLAGS here loses (a)
+# for non-gcc directories, (b) if we are compiling with gcc, not
+# native cc. Neither (a) nor (b) has a trivial fix though.
+
+CFLAGS =
diff --git a/config/mh-hpux b/config/mh-hpux
new file mode 100644
index 00000000000..4d71c9dc837
--- /dev/null
+++ b/config/mh-hpux
@@ -0,0 +1,4 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+CC = cc -Wp,-H256000
+SYSV = -DSYSV
+RANLIB = true
diff --git a/config/mh-hpux8 b/config/mh-hpux8
new file mode 100644
index 00000000000..4d71c9dc837
--- /dev/null
+++ b/config/mh-hpux8
@@ -0,0 +1,4 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+CC = cc -Wp,-H256000
+SYSV = -DSYSV
+RANLIB = true
diff --git a/config/mh-interix b/config/mh-interix
new file mode 100644
index 00000000000..19b8ecfd339
--- /dev/null
+++ b/config/mh-interix
@@ -0,0 +1,14 @@
+# The shell may not be in /bin.
+SHELL = sh
+RANLIB = true
+
+# We don't want debugging info in Interix-hosted toolchains.
+# Accomplish this by overriding CFLAGS. This is also a workaround
+# for LD crash when building shared libstdc++.
+CFLAGS=-O2
+CXXFLAGS=-O2
+
+# We also need to override LIBGCC2_DEBUG_CFLAGS so libgcc2 will be
+# built without debugging information
+
+LIBGCC2_DEBUG_CFLAGS=
diff --git a/config/mh-irix4 b/config/mh-irix4
new file mode 100644
index 00000000000..6872145e833
--- /dev/null
+++ b/config/mh-irix4
@@ -0,0 +1,7 @@
+# Makefile changes for SGI's running IRIX-4.x.
+# Tell compiler to use K&R C. We can't compile under the SGI Ansi
+# environment. Also bump switch table size so that cp-parse will
+# compile. Bump string length limit so linker builds.
+
+CC = cc -cckr -Wf,-XNg1500 -Wf,-XNk1000 -Wf,-XNh2000 -Wf,-XNl8192
+SYSV = -DSYSV
diff --git a/config/mh-irix5 b/config/mh-irix5
new file mode 100644
index 00000000000..8bd7c99f844
--- /dev/null
+++ b/config/mh-irix5
@@ -0,0 +1,3 @@
+# Makefile changes for SGI's running IRIX-5.x.
+SYSV = -DSYSV
+RANLIB = true
diff --git a/config/mh-irix6 b/config/mh-irix6
new file mode 100644
index 00000000000..6d25c16b2f4
--- /dev/null
+++ b/config/mh-irix6
@@ -0,0 +1,7 @@
+# Makefile changes for SGI's running IRIX-6.x.
+SYSV = -DSYSV
+RANLIB = true
+# Specify the ABI, to ensure that all Irix 6 systems will behave the same.
+# Also, using -32 avoids bugs that exist in the n32/n64 support in some
+# versions of the SGI compiler.
+CC = cc -32
diff --git a/config/mh-lynxos b/config/mh-lynxos
new file mode 100644
index 00000000000..9afcb79fca7
--- /dev/null
+++ b/config/mh-lynxos
@@ -0,0 +1,2 @@
+# /bin/cc is less than useful for our purposes. Always use GCC
+CC = /bin/gcc
diff --git a/config/mh-lynxrs6k b/config/mh-lynxrs6k
new file mode 100644
index 00000000000..b2793996eff
--- /dev/null
+++ b/config/mh-lynxrs6k
@@ -0,0 +1,8 @@
+# LynxOS running on the rs6000 doesn't have ranlib
+RANLIB = true
+
+# /bin/cc is less than useful for our purposes. Always use GCC
+CC = /usr/cygnus/progressive/bin/gcc
+
+# /bin/sh is too buggy, so use /bin/bash instead.
+SHELL = /bin/bash
diff --git a/config/mh-m68kpic b/config/mh-m68kpic
new file mode 100644
index 00000000000..92e48d90fbd
--- /dev/null
+++ b/config/mh-m68kpic
@@ -0,0 +1 @@
+PICFLAG=-fpic
diff --git a/config/mh-mingw32 b/config/mh-mingw32
new file mode 100644
index 00000000000..8c4839d89d6
--- /dev/null
+++ b/config/mh-mingw32
@@ -0,0 +1,12 @@
+# We don't want debugging info in Win32-hosted toolchains.
+# Accomplish this by overriding CFLAGS.
+CFLAGS=-O2
+CXXFLAGS=-O2
+
+# We also need to override LIBGCC2_DEBUG_CFLAGS so libgcc2 will be
+# built without debugging information
+
+LIBGCC2_DEBUG_CFLAGS=
+
+# custom installation rules for mingw32 (append .exe to binaries, etc.)
+# INSTALL_DOSREL=install-dosrel
diff --git a/config/mh-ncr3000 b/config/mh-ncr3000
new file mode 100644
index 00000000000..5bbd8037009
--- /dev/null
+++ b/config/mh-ncr3000
@@ -0,0 +1,17 @@
+# Host configuration file for an NCR 3000 (i486/SVR4) system.
+
+# The NCR 3000 ships with a MetaWare compiler installed as /bin/cc.
+# This compiler not only emits obnoxious copyright messages every time
+# you run it, but it chokes and dies on a whole bunch of GNU source
+# files. Default to using the AT&T compiler installed in /usr/ccs/ATT/cc.
+# Unfortunately though, the AT&T compiler sometimes generates code that
+# the assembler barfs on if -g is used, so disable it by default as well.
+CC = /usr/ccs/ATT/cc
+CFLAGS =
+
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4
+RANLIB = true
+
+# The l flag generates a warning from the SVR4 archiver, remove it.
+AR_FLAGS = cq
diff --git a/config/mh-ncrsvr43 b/config/mh-ncrsvr43
new file mode 100644
index 00000000000..43b09912ca9
--- /dev/null
+++ b/config/mh-ncrsvr43
@@ -0,0 +1,9 @@
+# Host configuration file for an NCR 3000 (i486/SVR43) system.
+
+# The MetaWare compiler will generate a copyright message unless you
+# turn it off by adding the -Hnocopyr flag.
+CC = cc -Hnocopyr
+
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4
+RANLIB = true
diff --git a/config/mh-necv4 b/config/mh-necv4
new file mode 100644
index 00000000000..e887736f8be
--- /dev/null
+++ b/config/mh-necv4
@@ -0,0 +1,11 @@
+# Host Makefile fragment for NEC MIPS SVR4.
+
+# The C compiler on NEC MIPS SVR4 needs bigger tables.
+CC = cc -ZXNd=5000 -ZXNg=1000
+
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4
+RANLIB = true
+
+# NEC -lX11 needs some other libraries.
+X11_EXTRA_LIBS = -lsocket -lnsl
diff --git a/config/mh-papic b/config/mh-papic
new file mode 100644
index 00000000000..35cf2c8ee4e
--- /dev/null
+++ b/config/mh-papic
@@ -0,0 +1 @@
+PICFLAG=-fPIC
diff --git a/config/mh-ppcpic b/config/mh-ppcpic
new file mode 100644
index 00000000000..35cf2c8ee4e
--- /dev/null
+++ b/config/mh-ppcpic
@@ -0,0 +1 @@
+PICFLAG=-fPIC
diff --git a/config/mh-riscos b/config/mh-riscos
new file mode 100644
index 00000000000..e586b30b1a9
--- /dev/null
+++ b/config/mh-riscos
@@ -0,0 +1,15 @@
+# This is for a MIPS running RISC/os 4.52C.
+
+# This is needed for GDB, but needs to be in the top-level make because
+# if a library is compiled with the bsd headers and gets linked with the
+# sysv system libraries all hell can break loose (e.g. a jmp_buf might be
+# a different size).
+# ptrace(2) apparently has problems in the BSD environment. No workaround is
+# known except to select the sysv environment. Could we use /proc instead?
+# These "sysv environments" and "bsd environments" often end up being a pain.
+#
+# This is not part of CFLAGS because perhaps not all C compilers have this
+# option.
+CC= cc -systype sysv
+
+RANLIB = true
diff --git a/config/mh-sco b/config/mh-sco
new file mode 100644
index 00000000000..cc337c98f93
--- /dev/null
+++ b/config/mh-sco
@@ -0,0 +1,10 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV
+RANLIB = true
+# You may need this if you don't have bison.
+# BISON = yacc -Sm10400
+# The native C compiler botches some simple uses of const. Unfortunately,
+# it doesn't defined anything like "__sco__" for us to test for in ansidecl.h.
+CC = cc -Dconst=
+
+X11_EXTRA_LIBS = -lsocket -lm -lintl -lmalloc
diff --git a/config/mh-solaris b/config/mh-solaris
new file mode 100644
index 00000000000..ddbea549b93
--- /dev/null
+++ b/config/mh-solaris
@@ -0,0 +1,6 @@
+# Makefile changes for Suns running Solaris 2
+
+SYSV = -DSYSV
+RANLIB = true
+
+X11_EXTRA_LIBS = -lnsl -lsocket
diff --git a/config/mh-sparcpic b/config/mh-sparcpic
new file mode 100644
index 00000000000..f6dbc22e3ca
--- /dev/null
+++ b/config/mh-sparcpic
@@ -0,0 +1 @@
+PICFLAG=`case "${LIBCFLAGS} ${LIBCXXFLAGS}" in *-fpic* ) echo -fpic ;; * ) echo -fPIC ;; esac`
diff --git a/config/mh-sun3 b/config/mh-sun3
new file mode 100644
index 00000000000..dcd5155b736
--- /dev/null
+++ b/config/mh-sun3
@@ -0,0 +1,3 @@
+# Sun's C compiler needs the -J flag to be able to compile cp-parse.c
+# without overflowing the jump tables (-J says to use a 32 bit table)
+CC = cc -J
diff --git a/config/mh-sysv b/config/mh-sysv
new file mode 100644
index 00000000000..16b1187b447
--- /dev/null
+++ b/config/mh-sysv
@@ -0,0 +1,3 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV
+RANLIB = true
diff --git a/config/mh-sysv4 b/config/mh-sysv4
new file mode 100644
index 00000000000..81066510600
--- /dev/null
+++ b/config/mh-sysv4
@@ -0,0 +1,11 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4
+RANLIB = true
+
+# C++ debugging is not yet supported under SVR4 (DWARF)
+CXXFLAGS=-O
+
+# The l flag generates a warning from the SVR4 archiver, remove it.
+AR_FLAGS = cr
+
+X11_EXTRA_LIBS = -lnsl
diff --git a/config/mh-sysv5 b/config/mh-sysv5
new file mode 100644
index 00000000000..1fa38e53cc8
--- /dev/null
+++ b/config/mh-sysv5
@@ -0,0 +1,8 @@
+# Define SYSV as -DSYSV if you are using a System V operating system.
+SYSV = -DSYSV -DSVR4 -DSVR5
+RANLIB = true
+
+# The l flag generates a warning from the SVR4 archiver, remove it.
+AR_FLAGS = cr
+
+X11_EXTRA_LIBS = -lnsl
diff --git a/config/mh-vaxult2 b/config/mh-vaxult2
new file mode 100644
index 00000000000..3de2dc8ffe3
--- /dev/null
+++ b/config/mh-vaxult2
@@ -0,0 +1,2 @@
+# The old BSD pcc isn't up to compiling parts of gdb so use gcc
+CC = gcc
diff --git a/config/mh-x86pic b/config/mh-x86pic
new file mode 100644
index 00000000000..92e48d90fbd
--- /dev/null
+++ b/config/mh-x86pic
@@ -0,0 +1 @@
+PICFLAG=-fpic
diff --git a/config/mpw-mh-mpw b/config/mpw-mh-mpw
new file mode 100644
index 00000000000..543ef4fb2a1
--- /dev/null
+++ b/config/mpw-mh-mpw
@@ -0,0 +1,157 @@
+# This is an MPW makefile fragment.
+
+# Since there are a multiplicity of Mac compilers and two different
+# processors, this file is primarily a library of options for each
+# compiler. Somebody else (such as a configure or build script) will
+# make the actual choice.
+
+# Compiler to use for compiling.
+
+CC_MPW_C = C -d MPW_C -d ALMOST_STDC -d ANSI_PROTOTYPES -d MPW -mc68020 -model far -b -w
+
+CC_SC = SC -d ALMOST_STDC -d ANSI_PROTOTYPES -d MPW -mc68020 -model far -b -i '' -i :
+
+CC_MWC68K = MWC68K -d MPW -enum int -mpw_chars -sym on -w off -mc68020 -model far
+
+CC_PPCC = PPCC -d powerc=1 -d pascal= -d ALMOST_STDC -d ANSI_PROTOTYPES -d MPW -w
+
+CC_MRC = MrC -d powerc=1 -d pascal= -d ALMOST_STDC -d ANSI_PROTOTYPES -d MPW -i '' -i : -jm
+
+CC_SMrC = SMrC -d MPW
+
+# "-mpw_chars" is necessary because GNU sources often mix signed and
+# unsigned casually.
+# "-w off" is not a great idea, but CW7 is complaining about enum
+# assignments.
+# "-opt global,peep,l4,speed" is sometimes good, and sometimes bad.
+# We must use {CIncludes} so that MPW tools will work; {MWCIncludes}
+# defines stdout, islower, etc, in ways that are incompatible with MPW's
+# runtime. However, this cannot be done via -i "{CIncludes}", since
+# that does not affect how <>-type includes happen; instead, the variable
+# MWCIncludes must be set to point at {CIncludes}.
+
+CC_MWCPPC = MWCPPC -d MPW -enum int -mpw_chars -sym on -w off
+
+# Note that GCC does *not* wire in a definition of "pascal", so that
+# it can be handled in another way if desired.
+
+CC_68K_GCC = gC -Dpascal= -DANSI_PROTOTYPES -DMPW
+
+CC_PPC_GCC = gC -Dpowerc=1 -Dpascal= -DANSI_PROTOTYPES -DMPW
+
+# Nothing for the default CFLAGS.
+
+CFLAGS =
+
+# Tool to use for making libraries/archives.
+
+AR_LIB = Lib
+
+AR_MWLINK68K = MWLink68K -xm library
+
+AR_PPCLINK = PPCLink -xm library
+
+AR_MWLINKPPC = MWLinkPPC -xm library
+
+AR_AR = ar
+
+AR_FLAGS = -o
+
+RANLIB_NULL = null-command
+
+RANLIB_RANLIB = ranlib
+
+# Compiler and/or linker to use for linking.
+
+CC_LD_LINK = Link -w -d -model far {CC_LD_TOOL_FLAGS}
+
+CC_LD_MWLINK68K = MWLink68K -w {CC_LD_TOOL_FLAGS} -sym on -model far
+
+CC_LD_PPCLINK = PPCLink -main __start -outputformat xcoff
+
+CC_LD_MWLINKPPC = MWLinkPPC -w {CC_LD_TOOL_FLAGS} -sym on
+
+CC_LD_GLD = gC
+
+# Extension for linker output.
+
+PROG_EXT_68K =
+
+PROG_EXT_XCOFF = .xcoff
+
+# Nothing for the default LDFLAGS.
+
+LDFLAGS = -w
+
+CC_LD_TOOL_FLAGS = -c 'MPS ' -t MPST
+
+# Libraries to link against.
+
+# It would appear that the math libraries are not
+# needed except to provide a definition for scalb,
+# which is called from ldexp, which is referenced
+# in the m68k opcodes library.
+
+EXTRALIBS_C = \Option-d
+ "{CLibraries}"StdClib.o \Option-d
+ "{CLibraries}"Math.o \Option-d
+ "{CLibraries}"CSANELib.o \Option-d
+ "{Libraries}"Stubs.o \Option-d
+ "{Libraries}"Runtime.o \Option-d
+ "{Libraries}"Interface.o \Option-d
+ "{Libraries}"ToolLibs.o
+
+EXTRALIBS_MWC68K = \Option-d
+ "{CLibraries}"StdClib.o \Option-d
+ "{CLibraries}"Math.o \Option-d
+ "{CLibraries}"CSANELib.o \Option-d
+ "{Libraries}"Stubs.o \Option-d
+ "{Libraries}"Runtime.o \Option-d
+ "{Libraries}"Interface.o \Option-d
+ "{Libraries}"ToolLibs.o \Option-d
+ "{MW68KLibraries}MPW ANSI (4i) C.68K.Lib"
+
+EXTRALIBS_PPC_XCOFF = \Option-d
+ "{PPCLibraries}"StdCRuntime.o \Option-d
+ "{PPCLibraries}"InterfaceLib.xcoff \Option-d
+ "{PPCLibraries}"MathLib.xcoff \Option-d
+ "{PPCLibraries}"StdCLib.xcoff \Option-d
+ "{PPCLibraries}"PPCToolLibs.o \Option-d
+ "{PPCLibraries}"PPCCRuntime.o \Option-d
+ "{GCCPPCLibraries}"libgcc.xcoff
+
+EXTRALIBS_PPC = \Option-d
+ "{PPCLibraries}"StdCRuntime.o \Option-d
+ "{SharedLibraries}"InterfaceLib \Option-d
+ "{SharedLibraries}"MathLib \Option-d
+ "{SharedLibraries}"StdCLib \Option-d
+ "{PPCLibraries}"PPCToolLibs.o \Option-d
+ "{PPCLibraries}"PPCCRuntime.o \Option-d
+ "{GCCPPCLibraries}"libgcc.xcoff
+
+EXTRALIBS_MWCPPC = \Option-d
+ "{MWPPCLibraries}"MWStdCRuntime.Lib \Option-d
+ "{MWPPCLibraries}"InterfaceLib \Option-d
+ "{MWPPCLibraries}"StdCLib \Option-d
+ "{MWPPCLibraries}"MathLib \Option-d
+ "{MWPPCLibraries}"PPCToolLibs.o
+
+# Tool to make PEF with, if needed.
+
+MAKEPEF_NULL = null-command
+
+MAKEPEF_PPC = MakePEF
+
+MAKEPEF_FLAGS = \Option-d
+ -l InterfaceLib.xcoff=InterfaceLib \Option-d
+ -l MathLib.xcoff=MathLib \Option-d
+ -l StdCLib.xcoff=StdCLib
+
+MAKEPEF_TOOL_FLAGS = -ft MPST -fc 'MPS '
+
+# Resource compiler to use.
+
+REZ_68K = Rez
+
+REZ_PPC = Rez -d WANT_CFRG
+
diff --git a/config/mpw/ChangeLog b/config/mpw/ChangeLog
new file mode 100644
index 00000000000..3cdefbf7a75
--- /dev/null
+++ b/config/mpw/ChangeLog
@@ -0,0 +1,53 @@
+Tue Nov 26 12:34:12 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed: Fix some comments.
+
+Mon Sep 16 14:42:52 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed (HLDENV): Edit out all references.
+
+Thu Aug 15 19:49:23 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * true: New script, identical to mpw-true.
+ * g-mpw-make.sed: Add @DASH_C_FLAG@ and @SEGMENT_FLAG()@
+ to the editors for compile commands.
+
+Thu Aug 1 15:01:42 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-true, mpw-touch, null-command: New scripts.
+ * README: Describe usage in more detail.
+
+Tue Dec 12 14:51:51 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed: Don't edit out "version=" occurrences.
+
+Fri Dec 1 11:46:18 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed (bindir, libdir): Edit the positions of
+ pathname separators to work with other pathnames better.
+
+Tue Nov 7 15:08:07 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed: Add comment about Duplicate vs Catenate,
+ add additional pattern for editing link-compile commands.
+
+Tue Oct 24 14:28:51 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed: Add handling for *.tab.[hc] files.
+ (CHILL_FOR_TARGET, CHILL_LIB): Edit out tricky definitions
+ of these.
+
+Thu Sep 28 21:05:10 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * g-mpw-make.sed: New file, generic sed commands to translate
+ Unix makefiles into MPW makefile syntax.
+
+Fri Mar 17 11:51:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * README: Clarify instructions.
+ * fi: Remove.
+
+Wed Dec 21 15:45:53 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * MoveIfChange, README, fi, forward-include, open-brace,
+ tr-7to8-src: New files.
diff --git a/config/mpw/MoveIfChange b/config/mpw/MoveIfChange
new file mode 100644
index 00000000000..0dbc12582f5
--- /dev/null
+++ b/config/mpw/MoveIfChange
@@ -0,0 +1,19 @@
+# Rename a file only if it is different from a previously existing
+# file of the same name. This is useful for keeping make from doing
+# too much work if the contents of a file haven't changed.
+
+# This is an MPW translation of the standard GNU sh script move-if-change.
+
+Set exit 0
+
+If "`exists -f "{2}"`"
+ Compare "{1}" "{2}" >dev:null
+ If {status} != 0
+ Rename -y "{1}" "{2}"
+ Else
+ Echo "{2}" is unchanged
+ Delete -i -y "{1}"
+ End
+Else
+ Rename -y "{1}" "{2}"
+End
diff --git a/config/mpw/README b/config/mpw/README
new file mode 100644
index 00000000000..554700adc81
--- /dev/null
+++ b/config/mpw/README
@@ -0,0 +1,23 @@
+This directory contains MPW scripts and related files that are needed to
+build Cygnus GNU tools for MPW. The scripts should be somewhere on the
+command path; our usual practice has been to have a separate directory
+for the scripts, and put the tools (byacc, flex, and sed at least) there
+also; then it's easier to drag the support bits around as a group, or to
+upgrade MPW versions. The complete package of scripts and tool binaries
+is usually available as pub/mac/buildtools.cpt.hqx on ftp.cygnus.com.
+
+"tr-7to8-src" is actually the source to an MPW script that transforms
+sequences like "\Option-d" into the actual 8-bit chars that MPW needs.
+It's only the source because it can't itself include any 8-bit chars.
+It *can* be processed into a genuine "tr-7to8" by using itself:
+
+ tr-7to8 tr-7to8-src | sed -e 's/Src//' >new-tr-7to8
+
+Use this to verify:
+
+ compare tr-7to8 new-tr-7to8
+
+If you don't have a working tr-7to8, then you will have to manually
+replace all occurrences of "\Option-d" with real Option-d (which looks
+like a delta), then do similarly with all the other "\Option-..."
+strings, and then change "\SrcOption-d" into the string "\Option-d".
diff --git a/config/mpw/forward-include b/config/mpw/forward-include
new file mode 100644
index 00000000000..ddd6bd71105
--- /dev/null
+++ b/config/mpw/forward-include
@@ -0,0 +1,3 @@
+Echo '#include' ¶""{1}"¶" >"{2}".tem
+MoveIfChange "{2}".tem "{2}"
+
diff --git a/config/mpw/g-mpw-make.sed b/config/mpw/g-mpw-make.sed
new file mode 100644
index 00000000000..e7d3c770736
--- /dev/null
+++ b/config/mpw/g-mpw-make.sed
@@ -0,0 +1,293 @@
+# Sed commands to translate Unix makefiles into MPW makefiles.
+# These are nominally generic, but work best on the makefiles used
+# for GNU programs.
+
+# Whack out any commented-out lines that are probably commands;
+# they can only cause trouble later on.
+/^# /d
+
+# Change dependency char.
+/:$/s/:/ \\Option-f/g
+/^[^ :#][^:]*:/s/\([ ]*\):\([ ]*\)/ \\Option-f /g
+
+# Change syntax of Makefile vars.
+/\$/s/\${\([a-zA-Z0-9_-]*\)}/{\1}/g
+/\$/s/\$(\([a-zA-Z0-9_-]*\))/{\1}/g
+/ $@/s/ $@/ {Targ}/
+
+# Double-$ are literals to Unix but not to MPW make.
+/\$\$/s/\$\$/$/g
+
+# Change pathname syntax.
+/\//s,\.\./\/\.\./,:::,g
+/\//s,\.\./,::,g
+/\.\//s,\./,:,g
+/\//s,/,:,g
+# Undo excess changes.
+/and/s,and:or$,and/or,
+/and/s,and:or ,and/or ,
+/want/s,want:need,want/need,
+# Fixing up sed commands.
+/-e/s_":\([^:]*\):d"_"/\1/d"_g
+/-e/s_":\([^:]*\):,:\([^:]*\):d"_"/\1/,/\2/d"_g
+
+/=/s/ = \.$/ = :/
+
+# Make these go away so that later edits not confused.
+/HLDENV/s/{HLDENV}//
+
+# Comment out any explicit srcdir setting.
+/srcdir/s/^srcdir/# srcdir/
+
+/BASEDIR/s/^BASEDIR =.*$/BASEDIR = "{srcroot}"/
+/{BASEDIR}:/s/{BASEDIR}:/{BASEDIR}/g
+/{srcdir}:/s/{srcdir}:/"{srcdir}"/g
+/"{srcdir}":/s/"{srcdir}":/"{srcdir}"/g
+
+# Tweak some conventions that are backwards for the Mac.
+/bindir/s/{exec_prefix}:bin/{exec_prefix}bin:/
+/libdir/s/{exec_prefix}:lib/{exec_prefix}lib:/
+
+# Comment out settings of anything set by mpw host config.
+/CC/s/^CC *=/#CC =/
+/CFLAGS/s/^CFLAGS *=/#CFLAGS =/
+/AR/s/^AR *=/#AR =/
+/AR_FLAGS/s/^AR_FLAGS *=/#AR_FLAGS =/
+/RANLIB/s/^RANLIB *=/#RANLIB =/
+/CC_LD/s/^CC_LD *=/#CC_LD =/
+/LDFLAGS/s/^LDFLAGS *=/#LDFLAGS =/
+
+# Change -I usages.
+/-I/s/-I\./-i :/g
+/-I/s/-I::bfd/-i ::bfd:/g
+/-I/s/-I::include/-i ::include:/g
+/-I/s/-I/-i /g
+
+# Change -D usage.
+/-D/s/\([ =]\)-D\([^ ]*\)/\1-d \2/g
+
+# Change continuation char.
+/\\$/s/\\$/\\Option-d/
+
+# Change wildcard char.
+/\*/s/\*/\\Option-x/g
+
+# Change path of various types of source files. This rule does not allow
+# for file names with multiple dots in the name.
+/\.[chly]/s/\([ ><=]\)\([-a-zA-Z0-9_${}:"]*\)\.\([chly]\)/\1"{s}"\2.\3/g
+/\.[chly]/s/^\([-a-zA-Z0-9_${}:"]*\)\.\([chly]\)/"{s}"\1.\2/
+# Allow files named *.tab.[ch] as a special case.
+/\.tab\.[ch]/s/\([ ><=]\)\([-a-zA-Z0-9_${}:"]*\.tab\)\.\([ch]\)/\1"{s}"\2.\3/g
+/\.tab\.[ch]/s/^\([-a-zA-Z0-9_${}:"]*\.tab\)\.\([ch]\)/"{s}"\1.\2/
+# Fix some overenthusiasms.
+/{s}/s/"{s}""{srcdir}"/"{srcdir}"/g
+/{s}/s/"{s}"{\([a-zA-Z0-9_]*\)dir}/"{\1dir}"/g
+/{s}/s/"{s}"{\([a-zA-Z0-9_]*\)DIR}/"{\1DIR}"/g
+/{s}/s/"{s}""{\([a-zA-Z0-9_]*\)dir}"/"{\1dir}"/g
+/{s}/s/"{s}""{\([a-zA-Z0-9_]*\)DIR}"/"{\1DIR}"/g
+/{s}/s/"{s}":/:/g
+/{s}/s/^"{s}"//g
+/{s}/s/"{s}""{s}"/"{s}"/g
+/{s}/s/"{s}""{srcdir}"/"{s}"/g
+/{s}/s/"{srcdir}""{s}"/"{s}"/g
+
+# The .def files are also typically source files.
+/\.def/s/\([ ><]\)\([-a-zA-Z0-9_${}:"]*\)\.def/\1"{s}"\2.def/g
+/\.def/s/^\([-a-zA-Z0-9_${}:"]*\)\.def/"{s}"\1.def/g
+
+# Change extension and path of objects.
+/\.o/s/\([ =]\)\([-a-zA-Z0-9_${}:"]*\)\.o/\1"{o}"\2.c.o/g
+/\.o/s/^\([-a-zA-Z0-9_${}:"]*\)\.o/"{o}"\1.c.o/
+# Allow *.tab.o files as a special case of a 2-dot-name file.
+/\.o/s/\([ =]\)\([-a-zA-Z0-9_${}:"]*\)\.tab\.o/\1"{o}"\2.tab.c.o/g
+/\.o/s/^\([-a-zA-Z0-9_${}:"]*\)\.tab\.o/"{o}"\1.tab.c.o/
+# Clean up.
+/"{o}"/s/"{o}""{o}"/"{o}"/g
+/"{o}"/s/^"{o}"\([a-zA-Z0-9_]*\)=/\1=/
+
+# Change extension of libs.
+/\.a/s/lib\([a-z]*\)\.a/lib\1.o/g
+
+# Remove non-fail option.
+/-/s/^\([ ]*\)-/\1/
+# Fix overeagernesses - assumes no one-letter commands.
+/^[ ]*[a-z] /s/^\([ ]*\)\([a-z]\) /\1-\2 /
+
+# Remove non-echo option. (watch out for autoconf things)
+/@/s/^\([ ]*\)@/\1/
+
+# Change cp to Duplicate.
+# Catenate is perhaps more accurate, but the pattern would have to
+# identify the output file and add a '>' redirection into it.
+/cp/s/^\([ ]*\)cp /\1Duplicate -d -y /
+# Change mv to Rename.
+/mv/s/^\([ ]*\)mv /\1Rename -y /
+/Rename/s/^\([ ]*\)Rename -y -f/\1Rename -y/
+# Change rm to Delete.
+/rm -rf/s/^\([ ]*\)rm -rf /\1Delete -i -y /
+/rm -f/s/^\([ ]*\)rm -f /\1Delete -i -y /
+/rm/s/^\([ ]*\)rm /\1Delete -i -y /
+# Note that we don't mess with ln - directory-specific scripts
+# must decide what to do with symlinks.
+# Change cat to Catenate.
+/cat/s/^\([ ]*\)cat /\1Catenate /
+# Change touch to mpw-touch.
+/touch/s/^\([ ]*\)touch /\1mpw-touch /
+# Change mkdir to NewFolder.
+/mkdir/s/^\([ ]*\)mkdir /\1NewFolder /
+# Change var setting to Set.
+/=/s/^\([ ]*\)\([-a-zA-Z0-9_]*\)=\([^;]*\); \\Option-d/\1Set \2 \3/
+
+# Change tests.
+/if /s/if \[ *-f \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" != ""/
+/if /s/if \[ *-f \([^ ]*\) ] *; *then *\\Option-d/If "`Exists "\1"`" != ""/
+/if /s/if \[ ! *-f \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" == ""/
+/if /s/if \[ ! *-f \([^ ]*\) ] *; *then \\Option-d/If "`Exists "\1"`" == ""/
+
+/if /s/if \[ *-d \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" != ""/
+/if /s/if \[ *-d \([^ ]*\) ] *; *then *\\Option-d/If "`Exists "\1"`" != ""/
+/if /s/if \[ ! *-d \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" == ""/
+/if /s/if \[ ! *-d \([^ ]*\) ] *; *then *\\Option-d/If "`Exists "\1"`" == ""/
+
+/if /s/if \[ -d \([^ ]*\) ] *; then true *; else mkdir \([^ ;]*\) *; fi/If "`Exists "\1"`" != "" NewFolder \2 End If/
+
+/if /s/if \[ \([^ ]*\) = \([^ ]*\) ] *; *\\Option-d/If "\1" == "\2"/
+/if /s/if \[ \([^ ]*\) = \([^ ]*\) ] *; *then *\\Option-d/If "\1" == "\2"/
+
+/if /s/if \[ \([^ ]*\) != \([^ ]*\) ] *; *\\Option-d/If "\1" != "\2"/
+/if /s/if \[ \([^ ]*\) != \([^ ]*\) ] *; *then *\\Option-d/If "\1" != "\2"/
+
+/if /s/if \[ \([^ ]*\) -eq \([^ ]*\) ] *; *\\Option-d/If "\1" != "\2"/
+/if /s/if \[ \([^ ]*\) -eq \([^ ]*\) ] *; *then *\\Option-d/If "\1" != "\2"/
+
+/^[ ]*else true$/c\
+ Else\
+ mpw-true\
+
+
+/else/s/^\([ ]*\)else[ ]*$/\1Else/
+/else/s/^\([ ]*\)else[; ]*\\Option-d$/\1Else/
+
+/^[ ]*else[ ]*true[ ]*$/c\
+ Else\
+ mpw-true
+
+/^[ ]*else[ ]*true[; ]*fi$/c\
+ Else\
+ mpw-true\
+ End If
+
+/fi/s/^\([ ]*\)fi *$/\1End/
+/fi/s/^\([ ]*\)fi *; *\\Option-d/\1End/
+
+# Change looping.
+/for/s/^\([ ]*\)for \([-a-zA-Z0-9_]*\) in \([^;]*\); *do *\\Option-d/\1For \2 In \3/
+/^\([ ]*\)do *\\Option-d/d
+/done/s/^\([ ]*\)done *; *\\Option-d/\1End/
+/done/s/^\([ ]*\)done$/\1End/
+
+# Trailing semicolons and continued lines are unneeded sh syntax.
+/; \\Option-d/s/; \\Option-d//
+
+# Change move-if-change to MoveIfChange.
+/move-if-change/s/\([^ ]*\)move-if-change/MoveIfChange/g
+
+# Change $(SHELL) to the script name by itself.
+/SHELL/s/^\([ ]*\){SHELL} /\1/
+
+# Change syntax of default rule dependency.
+/^\.c\.o/s/^\.c\.o \\Option-f$/.c.o \\Option-f .c/
+
+# Change default rule's action.
+/{CC} -c/s/{CC} -c \(.*\) \$<$/{CC} @DASH_C_FLAG@ {DepDir}{Default}.c \1 @SEGMENT_FLAG({Default})@ -o {TargDir}{Default}.c.o/
+
+# This is pretty disgusting, but I can't seem to detect empty rules.
+/Option-f$/s/Option-f$/Option-f _oldest/g
+
+# Remove -c from explicit compiler calls. (but should not if GCC)
+# Handle the case of a source file that is "{xxx}"file.c.
+/ -c /s/{\([A-Z_]*\)CC}\(.*\) -c \(.*\)"\([^"]*\)"\([-a-z_]*\)\.c/{\1CC}\2 @DASH_C_FLAG@ \3"\4"\5.c -o "{o}"\5.c.o/
+# Handle the case of a source file that is "{xxx}"dir:file.c.
+/ -c /s/{\([A-Z_]*\)CC}\(.*\) -c \(.*\)"\([^"]*\)"\([-a-z_]*\):\([-a-z_]*\)\.c/{\1CC}\2 @DASH_C_FLAG@ \3"\4"\5:\6.c -o "{o}"\6.c.o/
+
+# Change linking cc to linking sequence.
+/-o/s/^\([ ]*\){CC} \(.*\){\([A-Z_]*\)CFLAGS} \(.*\){LDFLAGS} \(.*\)-o \([^ ]*\) \(.*\)$/\1{CC_LD} \2 {\3CFLAGS} \4 {LDFLAGS} \5 -o \6{PROG_EXT} \7\
+\1{MAKEPEF} \6{PROG_EXT} -o \6 {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\
+\1{REZ} "{s}"\6.r -o \6 -append -d PROG_NAME='"'\6'"' -d VERSION_STRING='"'{version}'"'/
+/-o/s/^\([ ]*\){CC} \(.*\){\([A-Z_]*\)CFLAGS} \(.*\)-o \([^ ]*\) \(.*\){LDFLAGS} \(.*\)$/\1{CC_LD} \2 {\3CFLAGS} \4 {LDFLAGS} \6 -o \5{PROG_EXT} \7\
+\1{MAKEPEF} \5{PROG_EXT} -o \5 {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\
+\1{REZ} "{s}"\5.r -o \5 -append -d PROG_NAME='"'\5'"' -d VERSION_STRING='"'{version}'"'/
+/-o/s/^\([ ]*\){HOST_CC} \(.*\)-o \([^ ]*\) \(.*\)$/\1{HOST_CC_LD} \2 -o \3{PROG_EXT} \4\
+\1{MAKEPEF} \3{PROG_EXT} -o \3 {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\
+\1{REZ} "{s}"\3.r -o \3 -append -d PROG_NAME='"'\3'"' -d VERSION_STRING='"'{version}'"'/
+
+# Comment out .NOEXPORT rules.
+/\.NOEXPORT/s/^\.NOEXPORT/#\.NOEXPORT/
+# Comment out .PHONY rules.
+/\.PHONY/s/^\.PHONY/#\.PHONY/
+# Comment out .PRECIOUS rules.
+/\.PRECIOUS/s/^\.PRECIOUS/#\.PRECIOUS/
+# Comment out .SUFFIXES rules.
+/\.SUFFIXES/s/^\.SUFFIXES/#\.SUFFIXES/
+
+# Set the install program appropriately.
+/INSTALL/s/^INSTALL *= *`.*`:install.sh -c/INSTALL = Duplicate -y/
+
+# Don't try to decide whether to use the tree's own tools.
+/bison/s/`.*bison:bison.*`/bison -y/
+/byacc/s/`.*byacc:byacc.*`/byacc/
+/flex/s/`.*flex:flex.*`/flex/
+
+# Turn transformed C comments in echo commands back into comments.
+/echo/s,echo '\(.*\):\\Option-x\(.*\)\\Option-x:\(.*\)',echo '\1/*\2*/\3',
+
+# Whack out various clever expressions that search for tools, since
+# the clever code is too /bin/sh specific.
+
+/^AR_FOR_TARGET = `/,/`$/c\
+AR_FOR_TARGET = ::binutils:ar\
+
+
+/^RANLIB_FOR_TARGET = `/,/`$/c\
+RANLIB_FOR_TARGET = ::binutils:ranlib\
+
+
+/^RANLIB_TEST_FOR_TARGET = /,/ranlib ] )$/c\
+RANLIB_TEST_FOR_TARGET = \
+
+
+/^EXPECT = `/,/`$/c\
+EXPECT = \
+
+
+/^RUNTEST = `/,/`$/c\
+RUNTEST = \
+
+
+/^CC_FOR_TARGET = `/,/`$/c\
+CC_FOR_TARGET = \
+
+
+/^CXX_FOR_TARGET = `/,/`$/c\
+CXX_FOR_TARGET = \
+
+
+/^CHILL_FOR_TARGET = `/,/`$/c\
+CHILL_FOR_TARGET = \
+
+
+/^CHILL_LIB = `/,/`$/c\
+CHILL_LIB = \
+
+/sanit/s/{start-sanit...-[a-z0-9]*}//
+/sanit/s/{end-sanit...-[a-z0-9]*}//
+
+# Add standard defines and default rules.
+/^# srcdir/a\
+\
+s = "{srcdir}"\
+\
+o = :\
+\
+"{o}" \\Option-f : "{s}"
+
diff --git a/config/mpw/mpw-touch b/config/mpw/mpw-touch
new file mode 100644
index 00000000000..c743a5122b5
--- /dev/null
+++ b/config/mpw/mpw-touch
@@ -0,0 +1,7 @@
+# "Touch" command.
+
+If "`Exists "{1}"`" != ""
+ SetFile -m . "{1}"
+Else
+ Echo ' ' > "{1}"
+End If
diff --git a/config/mpw/mpw-true b/config/mpw/mpw-true
new file mode 100644
index 00000000000..0506530d3c6
--- /dev/null
+++ b/config/mpw/mpw-true
@@ -0,0 +1 @@
+Exit 0
diff --git a/config/mpw/null-command b/config/mpw/null-command
new file mode 100644
index 00000000000..4844c8ec553
--- /dev/null
+++ b/config/mpw/null-command
@@ -0,0 +1 @@
+# This command does nothing.
diff --git a/config/mpw/open-brace b/config/mpw/open-brace
new file mode 100644
index 00000000000..58465dcc18c
--- /dev/null
+++ b/config/mpw/open-brace
@@ -0,0 +1,4 @@
+# MPW makefiles seem not to have any way to get a literal open
+# brace into a rule anywhere, so this does the job.
+
+Echo '{'
diff --git a/config/mpw/tr-7to8-src b/config/mpw/tr-7to8-src
new file mode 100644
index 00000000000..b20b649c895
--- /dev/null
+++ b/config/mpw/tr-7to8-src
@@ -0,0 +1,9 @@
+StreamEdit -e \Option-d
+ '/\Option-x/ \Option-d
+ Replace /\Option-d\SrcOption-d/ "\Option-d\Option-d" -c \Option-5 ; \Option-d
+ Replace /\Option-d\SrcOption-f/ "\Option-d\Option-f" -c \Option-5 ; \Option-d
+ Replace /\Option-d\SrcOption-8/ "\Option-d\Option-8" -c \Option-5 ; \Option-d
+ Replace /\Option-d\SrcOption-5/ "\Option-d\Option-5" -c \Option-5 ; \Option-d
+ Replace /\Option-d\SrcOption-x/ "\Option-d\Option-x" -c \Option-5 ; \Option-d
+ Replace /\Option-d\SrcOption-r/ "\Option-d\Option-r" -c \Option-5' \Option-d
+ "{1}"
diff --git a/config/mpw/true b/config/mpw/true
new file mode 100644
index 00000000000..0506530d3c6
--- /dev/null
+++ b/config/mpw/true
@@ -0,0 +1 @@
+Exit 0
diff --git a/config/mt-armpic b/config/mt-armpic
new file mode 100644
index 00000000000..35b8c9e4dc2
--- /dev/null
+++ b/config/mt-armpic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fPIC
diff --git a/config/mt-d30v b/config/mt-d30v
new file mode 100644
index 00000000000..d34b774b3f6
--- /dev/null
+++ b/config/mt-d30v
@@ -0,0 +1,4 @@
+# Build libraries optimizing for space, not speed.
+# Turn off warnings about symbols named the same as registers
+ CFLAGS_FOR_TARGET = -g -Os -Wa,-C
+ CXXFLAGS_FOR_TARGET = -g -Os -Wa,-C
diff --git a/config/mt-elfalphapic b/config/mt-elfalphapic
new file mode 100644
index 00000000000..35b8c9e4dc2
--- /dev/null
+++ b/config/mt-elfalphapic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fPIC
diff --git a/config/mt-linux b/config/mt-linux
new file mode 100644
index 00000000000..a09e6f18af5
--- /dev/null
+++ b/config/mt-linux
@@ -0,0 +1,2 @@
+# When using glibc 2 on Linux we must always use vtable thunks.
+CXXFLAGS_FOR_TARGET = $(CXXFLAGS) -fvtable-thunks -D_GNU_SOURCE
diff --git a/config/mt-m68kpic b/config/mt-m68kpic
new file mode 100644
index 00000000000..ff987275575
--- /dev/null
+++ b/config/mt-m68kpic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fpic
diff --git a/config/mt-netware b/config/mt-netware
new file mode 100644
index 00000000000..9482f9b36d2
--- /dev/null
+++ b/config/mt-netware
@@ -0,0 +1 @@
+GDB_NLM_DEPS = all-gcc all-ld
diff --git a/config/mt-ospace b/config/mt-ospace
new file mode 100644
index 00000000000..7f091041d8a
--- /dev/null
+++ b/config/mt-ospace
@@ -0,0 +1,3 @@
+# Build libraries optimizing for space, not speed.
+ CFLAGS_FOR_TARGET = -g -Os
+ CXXFLAGS_FOR_TARGET = -g -Os
diff --git a/config/mt-papic b/config/mt-papic
new file mode 100644
index 00000000000..35b8c9e4dc2
--- /dev/null
+++ b/config/mt-papic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fPIC
diff --git a/config/mt-ppcpic b/config/mt-ppcpic
new file mode 100644
index 00000000000..35b8c9e4dc2
--- /dev/null
+++ b/config/mt-ppcpic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fPIC
diff --git a/config/mt-sparcpic b/config/mt-sparcpic
new file mode 100644
index 00000000000..fd0ec271afc
--- /dev/null
+++ b/config/mt-sparcpic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=`case "${LIBCFLAGS} ${LIBCXXFLAGS}" in *-fpic* ) echo -fpic ;; * ) echo -fPIC ;; esac`
diff --git a/config/mt-v810 b/config/mt-v810
new file mode 100644
index 00000000000..97da6c26592
--- /dev/null
+++ b/config/mt-v810
@@ -0,0 +1,4 @@
+CC_FOR_TARGET = ca732 -ansi
+AS_FOR_TARGET = as732
+AR_FOR_TARGET = ar732
+RANLIB_FOR_TARGET = true
diff --git a/config/mt-x86pic b/config/mt-x86pic
new file mode 100644
index 00000000000..ff987275575
--- /dev/null
+++ b/config/mt-x86pic
@@ -0,0 +1 @@
+PICFLAG_FOR_TARGET=-fpic
diff --git a/configure b/configure
new file mode 100755
index 00000000000..cad60b77c50
--- /dev/null
+++ b/configure
@@ -0,0 +1,1595 @@
+#!/bin/sh
+
+### WARNING: this file contains embedded tabs. Do not run untabify on this file.
+
+# Configuration script
+# Copyright (C) 1988, 90, 91, 92, 93, 94, 95, 96, 1997
+# Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This file was originally written by K. Richard Pixley.
+
+#
+# Shell script to create proper links to machine-dependent files in
+# preparation for compilation.
+#
+# If configure succeeds, it leaves its status in config.status.
+# If configure fails after disturbing the status quo,
+# config.status is removed.
+#
+
+export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0 $argv; kill $$)
+
+remove=rm
+hard_link=ln
+symbolic_link='ln -s'
+
+#for Test
+#remove="echo rm"
+#hard_link="echo ln"
+#symbolic_link="echo ln -s"
+
+# clear some things potentially inherited from environment.
+
+Makefile=Makefile
+Makefile_in=Makefile.in
+arguments=
+build_alias=
+cache_file=config.cache
+cache_file_option=
+configdirs=
+extraconfigdirs=
+diroptions=
+exec_prefix=
+exec_prefixoption=
+fatal=
+floating_point=default
+gas=default
+gcc_version=
+gcc_version_trigger=
+host_alias=NOHOST
+host_makefile_frag=
+moveifchange=
+norecursion=
+other_options=
+package_makefile_frag=
+package_makefile_rules_frag=
+prefix=/usr/local
+progname=
+program_prefix=
+program_prefixoption=
+program_suffix=
+program_suffixoption=
+program_transform_name=
+program_transform_nameoption=
+redirect=
+removing=
+site=
+site_makefile_frag=
+site_option=
+srcdir=
+srctrigger=
+subdirs=
+target_alias=NOTARGET
+target_makefile_frag=
+undefs=NOUNDEFS
+version="$Revision$"
+x11=default
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+### we might need to use some other shell than /bin/sh for running subshells
+
+### If we are on Windows, search for the shell. This will permit people
+### to not have /bin/sh, but to be able to see /SOME/PATH/sh configure
+### without also having to set CONFIG_SHELL. This code will work when
+### using bash, which sets OSTYPE.
+case "${OSTYPE}" in
+*win32*)
+ if [ x${CONFIG_SHELL} = x ]; then
+ if [ ! -f /bin/sh ]; then
+ if [ x${SHELL} != x ] && [ -f ${SHELL} ]; then
+ CONFIG_SHELL=${SHELL}
+ export CONFIG_SHELL
+ else
+ for prog in sh sh.exe bash bash.exe; do
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/$prog; then
+ CONFIG_SHELL=$dir/$prog
+ export CONFIG_SHELL
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ test -n "${CONFIG_SHELL}" && break
+ done
+ fi
+ fi
+ fi
+ ;;
+esac
+
+config_shell=${CONFIG_SHELL-/bin/sh}
+
+NO_EDIT="This file was generated automatically by configure. Do not edit."
+
+## this is a little touchy and won't always work, but...
+##
+## if the argv[0] starts with a slash then it is an absolute name that can (and
+## must) be used as is.
+##
+## otherwise, if argv[0] has no slash in it, we can assume that it is on the
+## path. Since PATH might include "." we also add `pwd` to the end of PATH.
+##
+
+progname=$0
+# if PWD already has a value, it is probably wrong.
+if [ -n "$PWD" ]; then PWD=`pwd`; fi
+
+case "${progname}" in
+/*) ;;
+*/*) ;;
+*)
+ PATH=$PATH:${PWD=`pwd`} ; export PATH
+ ;;
+esac
+
+# Loop over all args
+
+while :
+do
+
+# Break out if there are no more args
+ case $# in
+ 0)
+ break
+ ;;
+ esac
+
+# Get the first arg, and shuffle
+ option=$1
+ shift
+
+# Make all options have two hyphens
+ orig_option=$option # Save original for error messages
+ case $option in
+ --*) ;;
+ -*) option=-$option ;;
+ esac
+
+# Split out the argument for options that take them
+ case $option in
+ --*=*)
+ optarg=`echo $option | sed -e 's/^[^=]*=//'`
+ arguments="$arguments $option"
+ ;;
+# These options have mandatory values. Since we didn't find an = sign,
+# the value must be in the next argument
+ --bu* | --cache* | --ex* | --ho* | --pre* | --program-p* | --program-s* | --program-t* | --si* | --sr* | --ta* | --tm* | --x-* | --bi* | --sb* | --li* | --da* | --sy* | --sh* | --lo* | --in* | --ol* | --ma*)
+ optarg=$1
+ shift
+ arguments="$arguments $option=$optarg"
+ ;;
+ --v)
+ arguments="$arguments -v"
+ ;;
+ --*)
+ arguments="$arguments $option"
+ ;;
+ esac
+
+# Now, process the options
+ case $option in
+
+ --bi*)
+ bindir=$optarg
+ diroptions="$diroptions --bindir=$optarg"
+ ;;
+ --build* | --bu*)
+ case "$build_alias" in
+ "") build_alias=$optarg ;;
+ *) echo '***' Can only configure for one build machine at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ --cache*)
+ cache_file=$optarg
+ ;;
+ --da*)
+ datadir=$optarg
+ diroptions="$diroptions --datadir=$optarg"
+ ;;
+ --disable-*)
+ enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'`
+ eval $enableopt=no
+ disableoptions="$disableoptions $option"
+ ;;
+ --enable-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+
+ enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval "$enableopt='$optarg'"
+ enableoptions="$enableoptions '$option'"
+ ;;
+ --exec-prefix* | --ex*)
+ exec_prefix=$optarg
+ exec_prefixoption="--exec-prefix=$optarg"
+ ;;
+ --gas | --g*)
+ gas=yes
+ ;;
+ --help | --he*)
+ fatal=yes
+ ;;
+ --host* | --ho*)
+ case $host_alias in
+ NOHOST) host_alias=$optarg ;;
+ *) echo '***' Can only configure for one host at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ --inc*)
+ includedir=$optarg
+ diroptions="$diroptions --includedir=$optarg"
+ ;;
+ --inf*)
+ infodir=$optarg
+ diroptions="$diroptions --infodir=$optarg"
+ ;;
+ --libd*)
+ libdir=$optarg
+ diroptions="$diroptions --libdir=$optarg"
+ ;;
+ --libe*)
+ libexecdir=$optarg
+ diroptions="$diroptions --libexecdir=$optarg"
+ ;;
+ --lo*)
+ localstatedir=$optarg
+ diroptions="$diroptions --localstatedir=$optarg"
+ ;;
+ --ma*)
+ mandir=$optarg
+ diroptions="$diroptions --mandir=$optarg"
+ ;;
+ --nfp | --nf*)
+ floating_point=no
+ floating_pointoption="--nfp"
+ ;;
+ --norecursion | --no*)
+ norecursion=yes
+ ;;
+ --ol*)
+ oldincludedir=$optarg
+ diroptions="$diroptions --oldincludedir=$optarg"
+ ;;
+ --prefix* | --pre*)
+ prefix=$optarg
+ prefixoption="--prefix=$optarg"
+ ;;
+ --program-prefix* | --program-p*)
+ program_prefix=$optarg
+ program_prefixoption="--program-prefix=$optarg"
+ ;;
+ --program-suffix* | --program-s*)
+ program_suffix=$optarg
+ program_suffixoption="--program-suffix=$optarg"
+ ;;
+ --program-transform-name* | --program-t*)
+ # Double any backslashes or dollar signs in the argument
+ program_transform_name="${program_transform_name} -e `echo ${optarg} | sed -e 's/\\\\/\\\\\\\\/g' -e 's/\\\$/$$/g'`"
+ program_transform_nameoption="${program_transform_nameoption} --program-transform-name='$optarg'"
+ ;;
+ --rm)
+ removing=--rm
+ ;;
+ --sb*)
+ sbindir=$optarg
+ diroptions="$diroptions --sbindir=$optarg"
+ ;;
+ --sh*)
+ sharedstatedir=$optarg
+ diroptions="$diroptions --sharedstatedir=$optarg"
+ ;;
+ --silent | --sil* | --quiet | --q*)
+ redirect=">/dev/null"
+ verbose=--silent
+ ;;
+ --site* | --sit*)
+ site=$optarg
+ site_option="--site=$optarg"
+ ;;
+ --srcdir*/ | --sr*/)
+ # Remove trailing slashes. Otherwise, when the file name gets
+ # bolted into an object file as debug info, it has two slashes
+ # in it. Ordinarily this is ok, but emacs takes double slash
+ # to mean "forget the first part".
+ srcdir=`echo $optarg | sed -e 's:/$::'`
+ ;;
+ --srcdir* | --sr*)
+ srcdir=$optarg
+ ;;
+ --sy*)
+ sysconfdir=$optarg
+ diroptions="$diroptions --sysconfdir=$optarg"
+ ;;
+ --target* | --ta*)
+ case $target_alias in
+ NOTARGET) target_alias=$optarg ;;
+ *) echo '***' Can only configure for one target at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ --tmpdir* | --tm*)
+ TMPDIR=$optarg
+ tmpdiroption="--tmpdir=$optarg"
+ ;;
+ --verbose | --v | --verb*)
+ redirect=
+ verbose=--verbose
+ ;;
+ --version | --V | --vers*)
+ echo "This is Cygnus Configure version" `echo ${version} | sed 's/[ $:]//g'`
+ exit 0
+ ;;
+ --with-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+
+ withopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $withopt="$optarg"
+ withoptions="$withoptions $option"
+ ;;
+ --without-*)
+ withopt=`echo ${option} | sed 's:^--::;s:out::;s:-:_:g'`
+ eval $withopt=no
+ withoutoptions="$withoutoptions $option"
+ ;;
+ --x) with_x=yes
+ withoptions="$withoptions --with-x"
+ ;;
+ --x-i* | --x-l*) other_options="$other_options $orig_option"
+ ;;
+ --*)
+ echo "configure: Unrecognized option: \"$orig_option\"; use --help for usage." >&2
+ exit 1
+ ;;
+ *)
+ case $undefs in
+ NOUNDEFS) undefs=$option ;;
+ *) echo '***' Can only configure for one host and one target at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ esac
+done
+
+# process host and target
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET UNDEFS
+#
+# The rules are:
+# 1. You aren't allowed to specify --host, --target, and undefs at the
+# same time.
+# 2. Host defaults to undefs.
+# 3. If undefs is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target defaults to undefs.
+# 5. If undefs is not specified, then target defaults to host.
+
+case "${fatal}" in
+"")
+ # Make sure that host, target & undefs aren't all specified at the
+ # same time.
+ case $host_alias---$target_alias---$undefs in
+ NOHOST---*---* | *---NOTARGET---* | *---*---NOUNDEFS)
+ ;;
+ *) echo '***' Can only configure for one host and one target at a time. 1>&2
+ fatal=yes
+ break 2
+ ;;
+ esac
+
+ # Now, do defaulting for host.
+ case $host_alias in
+ NOHOST)
+ case $undefs in
+ NOUNDEFS)
+ # Neither --host option nor undefs were present.
+ # Call config.guess.
+ guesssys=`echo ${progname} | sed 's/configure$/config.guess/'`
+ if host_alias=`${config_shell} ${guesssys}`
+ then
+ # If the string we are going to use for
+ # the target is a prefix of the string
+ # we just guessed for the host, then
+ # assume we are running native, and force
+ # the same string for both target and host.
+ case $target_alias in
+ NOTARGET) ;;
+ *)
+ if expr $host_alias : $target_alias >/dev/null
+ then
+ host_alias=$target_alias
+ fi
+ ;;
+ esac
+ echo "Configuring for a ${host_alias} host." 1>&2
+ arguments="--host=$host_alias $arguments"
+ else
+ echo 'Config.guess failed to determine the host type. You need to specify one.' 1>&2
+ fatal=yes
+ fi
+ ;;
+ *)
+ host_alias=$undefs
+ arguments="--host=$host_alias $arguments"
+ undefs=NOUNDEFS
+ ;;
+ esac
+ esac
+
+ # Do defaulting for target. If --target option isn't present, default
+ # to undefs. If undefs isn't present, default to host.
+ case $target_alias in
+ NOTARGET)
+ case $undefs in
+ NOUNDEFS)
+ target_alias=$host_alias
+ ;;
+ *)
+ target_alias=$undefs
+ arguments="--target=$target_alias $arguments"
+ ;;
+ esac
+ esac
+ ;;
+*) ;;
+esac
+
+if [ -n "${fatal}" -o "${host_alias}" = "help" ] ; then
+ exec 1>&2
+ echo Usage: configure [OPTIONS] [HOST]
+ echo
+ echo Options: [defaults in brackets]
+ echo ' --prefix=MYDIR install into MYDIR [/usr/local]'
+ echo ' --exec-prefix=MYDIR install host-dependent files into MYDIR [/usr/local]'
+ echo ' --help print this message [normal config]'
+ echo ' --build=BUILD configure for building on BUILD [BUILD=HOST]'
+ echo ' --host=HOST configure for HOST [determined via config.guess]'
+ echo ' --norecursion configure this directory only [recurse]'
+ echo ' --program-prefix=FOO prepend FOO to installed program names [""]'
+ echo ' --program-suffix=FOO append FOO to installed program names [""]'
+ echo ' --program-transform-name=P transform installed names by sed pattern P [""]'
+ echo ' --site=SITE configure with site-specific makefile for SITE'
+ echo ' --srcdir=DIR find the sources in DIR [. or ..]'
+ echo ' --target=TARGET configure for TARGET [TARGET=HOST]'
+ echo ' --tmpdir=TMPDIR create temporary files in TMPDIR [/tmp]'
+ echo ' --nfp configure for software floating point [hard float]'
+ echo ' --with-FOO, --with-FOO=BAR package FOO is available (parameter BAR)'
+ echo ' --without-FOO package FOO is NOT available'
+ echo ' --enable-FOO, --enable-FOO=BAR include feature FOO (parameter BAR)'
+ echo ' --disable-FOO do not include feature FOO'
+ echo
+ echo 'Where HOST and TARGET are something like "sparc-sunos", "mips-sgi-irix5", etc.'
+ echo
+ if [ -r config.status ] ; then
+ cat config.status
+ fi
+
+ exit 1
+fi
+
+configsub=`echo ${progname} | sed 's/configure$/config.sub/'`
+moveifchange=`echo ${progname} | sed 's/configure$/move-if-change/'`
+topsrcdir=`cd \`dirname ${progname}\`; pwd`
+
+
+# this is a hack. sun4 must always be a valid host alias or this will fail.
+if ${config_shell} ${configsub} sun4 >/dev/null 2>&1 ; then
+ true
+else
+ echo '***' cannot find config.sub. 1>&2
+ exit 1
+fi
+
+touch config.junk
+if ${config_shell} ${moveifchange} config.junk config.trash ; then
+ true
+else
+ echo '***' cannot find move-if-change. 1>&2
+ exit 1
+fi
+rm -f config.junk config.trash
+
+case "${srcdir}" in
+"")
+ if [ -r configure.in ] ; then
+ srcdir=.
+ else
+ if [ -r ${progname}.in ] ; then
+ srcdir=`echo ${progname} | sed 's:/configure$::'`
+ else
+ echo '***' "Can't find configure.in. Try using --srcdir=some_dir" 1>&2
+ exit 1
+ fi
+ fi
+ ;;
+*)
+ # Set srcdir to "." if that's what it is.
+ # This is important for multilib support.
+ if [ ! -d ${srcdir} ] ; then
+ echo "Invalid source directory ${srcdir}" >&2
+ exit 1
+ fi
+ pwd=`pwd`
+ srcpwd=`cd ${srcdir} ; pwd`
+ if [ "${pwd}" = "${srcpwd}" ] ; then
+ srcdir=.
+ fi
+esac
+
+### warn about some conflicting configurations.
+
+case "${srcdir}" in
+".") ;;
+*)
+ if [ -f ${srcdir}/config.status ] ; then
+ echo '***' Cannot configure here in \"${PWD=`pwd`}\" when \"${srcdir}\" is currently configured. 1>&2
+ exit 1
+ fi
+esac
+
+
+# default exec_prefix
+case "${exec_prefixoption}" in
+"") exec_prefix="\$(prefix)" ;;
+*) ;;
+esac
+
+# Define the trigger file to make sure configure will re-run whenever
+# the gcc version number changes.
+if [ "${with_gcc_version_trigger+set}" = set ]; then
+ gcc_version_trigger="$with_gcc_version_trigger"
+ gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${with_gcc_version_trigger}`
+else
+ # If gcc's sources are available, define the trigger file.
+ if [ -f ${topsrcdir}/gcc/version.c ] ; then
+ gcc_version_trigger=${topsrcdir}/gcc/version.c
+ gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}`
+ case "$arguments" in
+ *--with-gcc-version-trigger=$gcc_version_trigger* )
+ ;;
+ * )
+ # Make sure configure.in knows about this.
+ arguments="--with-gcc-version-trigger=$gcc_version_trigger $arguments"
+ ;;
+ esac
+ withoptions="--with-gcc-version-trigger=$gcc_version_trigger $withoptions"
+ fi
+fi
+
+### break up ${srcdir}/configure.in.
+case "`grep '^# per\-host:' ${srcdir}/configure.in`" in
+"")
+ echo '***' ${srcdir}/configure.in has no \"per-host:\" line. 1>&2
+ # Check for a directory that's been converted to use autoconf since
+ # it was last configured.
+ if grep AC_OUTPUT ${srcdir}/configure.in >/dev/null ; then
+ echo '***' Hmm, looks like this directory has been autoconfiscated. 1>&2
+ if [ -r ${srcdir}/configure ] ; then
+ echo '***' Running the local configure script. 1>&2
+ case "${cache_file}" in
+ "") cache_file_option= ;;
+ *) cache_file_option="--cache-file=${cache_file}" ;;
+ esac
+ srcdiroption="--srcdir=${srcdir}"
+ case "${build_alias}" in
+ "") buildopt= ;;
+ *) buildopt="--build=${build_alias}" ;;
+ esac
+ eval exec ${config_shell} ${srcdir}/configure ${verbose} \
+ ${buildopt} --host=${host_alias} --target=${target_alias} \
+ ${prefixoption} ${tmpdiroption} ${exec_prefixoption} \
+ ${srcdiroption} ${diroptions} \
+ ${program_prefixoption} ${program_suffixoption} \
+ ${program_transform_nameoption} ${site_option} \
+ ${withoptions} ${withoutoptions} \
+ ${enableoptions} ${disableoptions} ${floating_pointoption} \
+ ${cache_file_option} ${removing} ${other_options} ${redirect}
+ else
+ echo '***' There is no configure script present though. 1>&2
+ fi
+ fi
+ exit 1
+ ;;
+*) ;;
+esac
+
+case "`grep '^# per\-target:' ${srcdir}/configure.in`" in
+"")
+ echo '***' ${srcdir}/configure.in has no \"per-target:\" line. 1>&2
+ exit 1
+ ;;
+*) ;;
+esac
+
+case "${TMPDIR}" in
+"") TMPDIR=/tmp ; export TMPDIR ;;
+*) ;;
+esac
+
+# keep this filename short for &%*%$*# 14 char file names
+tmpfile=${TMPDIR}/cONf$$
+# Note that under many versions of sh a trap handler for 0 will *override* any
+# exit status you explicitly specify! At this point, the only non-error exit
+# is at the end of the script; these actions are duplicated there, minus
+# the "exit 1". Don't use "exit 0" anywhere after this without resetting the
+# trap handler, or you'll lose.
+trap "rm -f Makefile.tem ${tmpfile}.com ${tmpfile}.tgt ${tmpfile}.hst ${tmpfile}.pos; exit 1" 0 1 2 15
+
+# split ${srcdir}/configure.in into common, per-host, per-target,
+# and post-target parts. Post-target is optional.
+sed -e '/^# per\-host:/,$d' ${srcdir}/configure.in > ${tmpfile}.com
+sed -e '1,/^# per\-host:/d' -e '/^# per\-target:/,$d' ${srcdir}/configure.in > ${tmpfile}.hst
+if grep '^# post-target:' ${srcdir}/configure.in >/dev/null ; then
+ sed -e '1,/^# per\-target:/d' -e '/^# post\-target:/,$d' ${srcdir}/configure.in > ${tmpfile}.tgt
+ sed -e '1,/^# post\-target:/d' ${srcdir}/configure.in > ${tmpfile}.pos
+else
+ sed -e '1,/^# per\-target:/d' ${srcdir}/configure.in > ${tmpfile}.tgt
+ echo >${tmpfile}.pos
+fi
+
+### do common part of configure.in
+
+# If the language specific compiler does not exist, but the "gcc" directory does,
+# we will skip this directory; in this case the sub-directory's common part
+# of configure.in will create a small shell script "skip-this-dir" containing
+# commands to completely clean up any temporary or created files.
+
+. ${tmpfile}.com
+
+if test -f skip-this-dir; then
+ # Perform the same cleanup as the trap handler, minus the "exit 1" of course,
+ # and reset the trap handler.
+ trap 0
+ rm -f Makefile* ${tmpfile}.com ${tmpfile}.tgt ${tmpfile}.hst ${tmpfile}.pos
+ # Execute the final clean-up actions
+ ${config_shell} skip-this-dir
+ # and stop configuring this directory.
+ exit 0
+fi
+
+# some sanity checks on configure.in
+case "${srctrigger}" in
+"")
+ echo '***' srctrigger not set in ${PWD=`pwd`}/configure.in. 1>&2
+ exit 1
+ ;;
+*) ;;
+esac
+
+case "${build_alias}" in
+"")
+ if result=`${config_shell} ${configsub} ${host_alias}` ; then
+ build_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+ build_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+ build_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+ build=${build_cpu}-${build_vendor}-${build_os}
+ build_alias=${host_alias}
+ fi
+ ;;
+*)
+ if result=`${config_shell} ${configsub} ${build_alias}` ; then
+ buildopt="--build=${build_alias}"
+ build_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+ build_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+ build_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+ build=${build_cpu}-${build_vendor}-${build_os}
+ else
+ echo "Unrecognized build system name ${build_alias}." 1>&2
+ exit 1
+ fi
+ ;;
+esac
+
+if result=`${config_shell} ${configsub} ${host_alias}` ; then
+ true
+else
+ echo "Unrecognized host system name ${host_alias}." 1>&2
+ exit 1
+fi
+host_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+host=${host_cpu}-${host_vendor}-${host_os}
+
+. ${tmpfile}.hst
+
+if result=`${config_shell} ${configsub} ${target_alias}` ; then
+ true
+else
+ echo "Unrecognized target system name ${target_alias}." 1>&2
+ exit 1
+fi
+target_cpu=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $result | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+target=${target_cpu}-${target_vendor}-${target_os}
+
+. ${tmpfile}.tgt
+
+# Find the source files, if location was not specified.
+case "${srcdir}" in
+"")
+ srcdirdefaulted=1
+ srcdir=.
+ if [ ! -r ${srctrigger} ] ; then
+ srcdir=..
+ fi
+ ;;
+*) ;;
+esac
+
+if [ ! -r ${srcdir}/${srctrigger} ] ; then
+ case "${srcdirdefaulted}" in
+ "") echo '***' "${progname}: Can't find ${srcname} sources in ${PWD=`pwd`}/${srcdir}" 1>&2 ;;
+ *) echo '***' "${progname}: Can't find ${srcname} sources in ${PWD=`pwd`}/. or ${PWD=`pwd`}/.." 1>&2 ;;
+ esac
+
+ echo '***' \(At least ${srctrigger} is missing.\) 1>&2
+ exit 1
+fi
+
+# Some systems (e.g., one of the i386-aix systems the gas testers are
+# using) don't handle "\$" correctly, so don't use it here.
+tooldir='$(exec_prefix)'/${target_alias}
+
+if [ "${host_alias}" != "${target_alias}" ] ; then
+ if [ "${program_prefixoption}" = "" ] ; then
+ if [ "${program_suffixoption}" = "" ] ; then
+ if [ "${program_transform_nameoption}" = "" ] ; then
+ program_prefix=${target_alias}- ;
+ fi
+ fi
+ fi
+fi
+
+# Merge program_prefix and program_suffix onto program_transform_name.
+# (program_suffix used to use $, but it's hard to preserve $ through both
+# make and sh.)
+if [ "${program_suffix}" != "" ] ; then
+ program_transform_name="-e s,\\\\(.*\\\\),\\\\1${program_suffix}, ${program_transform_name}"
+fi
+
+if [ "${program_prefix}" != "" ] ; then
+ program_transform_name="-e s,^,${program_prefix}, ${program_transform_name}"
+fi
+
+# If CC and CXX are not set in the environment, and the Makefile
+# exists, try to extract them from it. This is to handle running
+# ./config.status by hand.
+if [ -z "${CC}" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^CC[ ]*=/ s/CC[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CC=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+if [ -z "${CFLAGS}" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^CFLAGS[ ]*=/ s/CFLAGS[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CFLAGS=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+if [ -z "${CXX}" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^CXX[ ]*=/ s/CXX[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CXX=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+if [ -z "${CXXFLAGS}" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^CXXFLAGS[ ]*=/ s/CXXFLAGS[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CXXFLAGS=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+# Generate a default definition for YACC. This is used if the makefile can't
+# locate bison or byacc in objdir.
+
+for prog in 'bison -y' byacc yacc
+do
+ set dummy $prog; tmp=$2
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/$tmp; then
+ DEFAULT_YACC="$prog"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ test -n "$DEFAULT_YACC" && break
+done
+
+# Generate a default definition for M4. This is used if the makefile can't
+# locate m4 in objdir.
+
+for prog in gm4 gnum4 m4
+do
+ set dummy $prog; tmp=$2
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/$tmp; then
+ DEFAULT_M4="$prog"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ test -n "$DEFAULT_M4" && break
+done
+
+# Generate a default definition for LEX. This is used if the makefile can't
+# locate flex in objdir.
+
+for prog in flex lex
+do
+ set dummy $prog; tmp=$2
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/$tmp; then
+ DEFAULT_LEX="$prog"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ test -n "$DEFAULT_LEX" && break
+done
+
+if [ "${build}" != "${host}" ]; then
+ # If we are doing a Canadian Cross, in which the host and build systems
+ # are not the same, we set reasonable default values for the tools.
+
+ tools="AR AR_FOR_TARGET AS AS_FOR_TARGET BISON CC_FOR_BUILD"
+ tools="${tools} CC_FOR_TARGET CXX_FOR_TARGET"
+ tools="${tools} DLLTOOL DLLTOOL_FOR_TARGET GCC_FOR_TARGET HOST_PREFIX"
+ tools="${tools} HOST_PREFIX_1 LD LD_FOR_TARGET LEX MAKEINFO NM"
+ tools="${tools} NM_FOR_TARGET RANLIB RANLIB_FOR_TARGET"
+ tools="${tools} WINDRES WINDRES_FOR_TARGET YACC"
+
+ for var in ${tools}; do
+ if [ -z "`eval 'echo $'"${var}"`" ] && [ -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+s/\\\n//g
+t loop
+/^'"${var}"'[ ]*=/ s/'"${var}"'[ ]*=[ ]*\(.*\)/\1/p' \
+ < Makefile > Makefile.v
+ t=`tail -1 Makefile.v`
+ if [ -n "${t}" ]; then
+ eval "${var}='${t}'"
+ fi
+ rm -f Makefile.v
+ fi
+ done
+
+ AR=${AR-${host_alias}-ar}
+ AR_FOR_TARGET=${AR_FOR_TARGET-${target_alias}-ar}
+ AS=${AS-${host_alias}-as}
+ AS_FOR_TARGET=${AS_FOR_TARGET-${target_alias}-as}
+ BISON=${BISON-bison}
+ CC=${CC-${host_alias}-gcc}
+ CFLAGS=${CFLAGS-"-g -O2"}
+ CXX=${CXX-${host_alias}-c++}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
+ CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
+ CC_FOR_TARGET=${CC_FOR_TARGET-${target_alias}-gcc}
+ CXX_FOR_TARGET=${CXX_FOR_TARGET-${target_alias}-c++}
+ DLLTOOL=${DLLTOOL-${host_alias}-dlltool}
+ DLLTOOL_FOR_TARGET=${DLLTOOL_FOR_TARGET-${target_alias}-dlltool}
+ GCC_FOR_TARGET=${GCC_FOR_TARGET-${CC_FOR_TARGET-${target_alias}-gcc}}
+ HOST_PREFIX=${build_alias}-
+ HOST_PREFIX_1=${build_alias}-
+ LD=${LD-${host_alias}-ld}
+ LD_FOR_TARGET=${LD_FOR_TARGET-${target_alias}-ld}
+ MAKEINFO=${MAKEINFO-makeinfo}
+ NM=${NM-${host_alias}-nm}
+ NM_FOR_TARGET=${NM_FOR_TARGET-${target_alias}-nm}
+ RANLIB=${RANLIB-${host_alias}-ranlib}
+ RANLIB_FOR_TARGET=${RANLIB_FOR_TARGET-${target_alias}-ranlib}
+ WINDRES=${WINDRES-${host_alias}-windres}
+ WINDRES_FOR_TARGET=${WINDRES_FOR_TARGET-${target_alias}-windres}
+
+ if [ -z "${YACC}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/bison; then
+ YACC="bison -y"
+ break
+ fi
+ if test -f $dir/byacc; then
+ YACC=byacc
+ break
+ fi
+ if test -f $dir/yacc; then
+ YACC=yacc
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if [ -z "${YACC}" ]; then
+ YACC="bison -y"
+ fi
+ fi
+
+ if [ -z "${LEX}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/flex; then
+ LEX=flex
+ break
+ fi
+ if test -f $dir/lex; then
+ LEX=lex
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ LEX=${LEX-flex}
+ fi
+
+ # Export variables which autoconf might try to set.
+ export AS
+ export AR
+ export CC_FOR_BUILD
+ export DLLTOOL
+ export LD
+ export NM
+ export RANLIB
+ export WINDRES
+else
+ # If CC is still not set, try to get gcc.
+ if [ -z "${CC}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ CC="gcc"
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC} -g -c conftest.c 2>&1`"; then
+ CFLAGS=${CFLAGS-"-g -O2"}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
+ else
+ CFLAGS=${CFLAGS-"-O2"}
+ CXXFLAGS=${CXXFLAGS-"-O2"}
+ fi
+ rm -f conftest*
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ CC=${CC-cc}
+ else
+ if test -z "${CFLAGS}"; then
+ # Here CC is set but CFLAGS is not. Use a quick hack to use -O2 if CC
+ # is set to a version of gcc.
+ case "${CC}" in
+ *gcc)
+ echo 'void f(){}' > conftest.c
+ if test -z "`${CC} -g -c conftest.c 2>&1`"; then
+ CFLAGS=${CFLAGS-"-g -O2"}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
+ else
+ CFLAGS=${CFLAGS-"-O2"}
+ CXXFLAGS=${CXXFLAGS-"-O2"}
+ fi
+ rm -f conftest*
+ ;;
+ esac
+ fi
+ fi
+
+ CXX=${CXX-"c++"}
+ CFLAGS=${CFLAGS-"-g"}
+ CXXFLAGS=${CXXFLAGS-"-g -O2"}
+fi
+
+export CC
+export CXX
+export CFLAGS
+export CXXFLAGS
+
+
+for subdir in . ${subdirs} ; do
+
+ # ${subdir} is relative path from . to the directory we're currently
+ # configuring.
+ # ${invsubdir} is inverse of ${subdir), *with* trailing /, if needed.
+ invsubdir=`echo ${subdir}/ | sed -e 's|\./||g' -e 's|[^/]*/|../|g'`
+
+ ### figure out what to do with srcdir
+ case "${srcdir}" in
+ ".") # no -srcdir option. We're building in place.
+ makesrcdir=. ;;
+ /*) # absolute path
+ makesrcdir=`echo ${srcdir}/${subdir} | sed -e 's|/\.$||'`
+ ;;
+ *) # otherwise relative
+ case "${subdir}" in
+ .) makesrcdir=${srcdir} ;;
+ *) makesrcdir=${invsubdir}${srcdir}/${subdir} ;;
+ esac
+ ;;
+ esac
+
+ if [ "${subdir}/" != "./" ] ; then
+ Makefile=${subdir}/Makefile
+ fi
+
+ if [ ! -d ${subdir} ] ; then
+ if mkdir ${subdir} ; then
+ true
+ else
+ echo '***' "${progname}: could not make ${PWD=`pwd`}/${subdir}" 1>&2
+ exit 1
+ fi
+ fi
+
+ case "${removing}" in
+ "")
+ case "${subdir}" in
+ .) ;;
+ *) eval echo Building in ${subdir} ${redirect} ;;
+ esac
+
+ # FIXME Should this be done recursively ??? (Useful for e.g. gdbtest)
+ # Set up the list of links to be made.
+ # ${links} is the list of link names, and ${files} is the list of names to link to.
+
+ # Make the links.
+ configlinks="${links}"
+ if [ -r ${subdir}/config.status ] ; then
+ mv -f ${subdir}/config.status ${subdir}/config.back
+ fi
+ while [ -n "${files}" ] ; do
+ # set file to car of files, files to cdr of files
+ set ${files}; file=$1; shift; files=$*
+ set ${links}; link=$1; shift; links=$*
+
+ if [ ! -r ${srcdir}/${file} ] ; then
+ if [ ! -r ${file} ] ; then
+
+ echo '***' "${progname}: cannot create a link \"${link}\"," 1>&2
+ echo '***' "since the file \"${srcdir}/${file}\" does not exist." 1>&2
+ exit 1
+ else
+ srcfile=${file}
+ fi
+ else
+ srcfile=${srcdir}/${file}
+ fi
+
+ ${remove} -f ${link}
+ # Make a symlink if possible, otherwise try a hard link
+ if ${symbolic_link} ${srcfile} ${link} >/dev/null 2>&1 ; then
+ true
+ else
+ # We need to re-remove the file because Lynx leaves a
+ # very strange directory there when it fails an NFS symlink.
+ ${remove} -r -f ${link}
+ ${hard_link} ${srcfile} ${link}
+ fi
+ if [ ! -r ${link} ] ; then
+ echo '***' "${progname}: unable to link \"${link}\" to \"${srcfile}\"." 1>&2
+ exit 1
+ fi
+
+ echo "Linked \"${link}\" to \"${srcfile}\"."
+ done
+
+ # Create a .gdbinit file which runs the one in srcdir
+ # and tells GDB to look there for source files.
+
+ if [ -r ${srcdir}/${subdir}/.gdbinit ] ; then
+ case ${srcdir} in
+ .) ;;
+ *) cat > ${subdir}/.gdbinit <<EOF
+# ${NO_EDIT}
+dir ${makesrcdir}
+dir .
+source ${makesrcdir}/.gdbinit
+EOF
+ ;;
+ esac
+ fi
+
+ # Install a makefile, and make it set VPATH
+ # if necessary so that the sources are found.
+ # Also change its value of srcdir.
+ # NOTE: Makefile generation constitutes the majority of the time in configure. Hence, this section has
+ # been somewhat optimized and is perhaps a bit twisty.
+
+ # code is order so as to try to sed the smallest input files we know.
+ # so do these separately because I don't trust the order of sed -e expressions.
+
+ # the five makefile fragments MUST end up in the resulting Makefile in this order:
+ # package macros, target, host, site, and package rules.
+
+ if [ -f ${srcdir}/${subdir}/${Makefile_in} ] ; then
+
+ # Conditionalize the makefile for this package from "Makefile.in" (or whatever it's called) into Makefile.tem.
+ rm -f ${subdir}/${Makefile}.tem
+ case "${package_makefile_rules_frag}" in
+ "") cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem ;;
+ *)
+ if [ ! -f ${package_makefile_rules_frag} ] ; then
+ package_makefile_rules_frag=${srcdir}/${package_makefile_rules_frag}
+ fi
+ if [ -f ${package_makefile_rules_frag} ] ; then
+ sed -e "/^####/ r ${package_makefile_rules_frag}" ${srcdir}/${subdir}/${Makefile_in} > ${Makefile}.tem
+ else
+ echo '***' Expected package makefile rules fragment \"${package_makefile_rules_frag}\" 1>&2
+ echo '***' is missing in ${PWD=`pwd`}. 1>&2
+ cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem
+ fi
+ esac
+ # working copy now in ${Makefile}.tem
+
+ # Conditionalize for this site.
+ rm -f ${Makefile}
+ case "${site}" in
+ "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ *)
+ site_makefile_frag=${srcdir}/config/ms-${site}
+
+ if [ -f ${site_makefile_frag} ] ; then
+ sed -e "/^####/ r ${site_makefile_frag}" ${subdir}/Makefile.tem \
+ > ${Makefile}
+ else
+ mv ${subdir}/Makefile.tem ${Makefile}
+ site_makefile_frag=
+ fi
+ ;;
+ esac
+ # working copy now in ${Makefile}
+
+ # Conditionalize the makefile for this host.
+ rm -f ${subdir}/Makefile.tem
+ case "${host_makefile_frag}" in
+ "") mv ${Makefile} ${subdir}/Makefile.tem ;;
+ *)
+ if [ ! -f ${host_makefile_frag} ] ; then
+ host_makefile_frag=${srcdir}/${host_makefile_frag}
+ fi
+ if [ -f ${host_makefile_frag} ] ; then
+ sed -e "/^####/ r ${host_makefile_frag}" ${Makefile} > ${subdir}/Makefile.tem
+ else
+ echo '***' Expected host makefile fragment \"${host_makefile_frag}\" 1>&2
+ echo '***' is missing in ${PWD=`pwd`}. 1>&2
+ mv ${Makefile} ${subdir}/Makefile.tem
+ fi
+ esac
+ # working copy now in ${subdir)/Makefile.tem
+
+ # Conditionalize the makefile for this target.
+ rm -f ${Makefile}
+ case "${target_makefile_frag}" in
+ "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ *)
+ if [ ! -f ${target_makefile_frag} ] ; then
+ target_makefile_frag=${srcdir}/${target_makefile_frag}
+ fi
+ if [ -f ${target_makefile_frag} ] ; then
+ sed -e "/^####/ r ${target_makefile_frag}" ${subdir}/Makefile.tem > ${Makefile}
+ else
+ mv ${subdir}/Makefile.tem ${Makefile}
+ target_makefile_frag=
+ fi
+ ;;
+ esac
+ # working copy now in ${Makefile}
+
+ # Emit the default values of this package's macros.
+ rm -f ${subdir}/Makefile.tem
+ case "${package_makefile_frag}" in
+ "") mv ${Makefile} ${subdir}/Makefile.tem ;;
+ *)
+ if [ ! -f ${package_makefile_frag} ] ; then
+ package_makefile_frag=${srcdir}/${package_makefile_frag}
+ fi
+ if [ -f ${package_makefile_frag} ] ; then
+ sed -e "/^####/ r ${package_makefile_frag}" ${Makefile} > ${subdir}/Makefile.tem
+ else
+ echo '***' Expected package makefile fragment \"${package_makefile_rules_frag}\" 1>&2
+ echo '***' is missing in ${PWD=`pwd`}. 1>&2
+ mv ${Makefile} ${subdir}/Makefile.tem
+ fi
+ esac
+ # real copy now in ${subdir}/Makefile.tem
+
+ # prepend warning about editting, and a bunch of variables.
+ rm -f ${Makefile}
+ cat > ${Makefile} <<EOF
+# ${NO_EDIT}
+VPATH = ${makesrcdir}
+links = ${configlinks}
+host_alias = ${host_alias}
+host_cpu = ${host_cpu}
+host_vendor = ${host_vendor}
+host_os = ${host_os}
+host_canonical = ${host_cpu}-${host_vendor}-${host_os}
+target_alias = ${target_alias}
+target_cpu = ${target_cpu}
+target_vendor = ${target_vendor}
+target_os = ${target_os}
+target_canonical = ${target_cpu}-${target_vendor}-${target_os}
+EOF
+ case "${build}" in
+ "") ;;
+ *) cat >> ${Makefile} << EOF
+build_alias = ${build_alias}
+build_cpu = ${build_cpu}
+build_vendor = ${build_vendor}
+build_os = ${build_os}
+build_canonical = ${build_cpu}-${build_vendor}-${build_os}
+EOF
+ esac
+
+ case "${package_makefile_frag}" in
+ "") ;;
+ /*) echo package_makefile_frag = ${package_makefile_frag} >>${Makefile} ;;
+ *) echo package_makefile_frag = ${invsubdir}${package_makefile_frag} >>${Makefile} ;;
+ esac
+
+ case "${target_makefile_frag}" in
+ "") ;;
+ /*) echo target_makefile_frag = ${target_makefile_frag} >>${Makefile} ;;
+ *) echo target_makefile_frag = ${invsubdir}${target_makefile_frag} >>${Makefile} ;;
+ esac
+
+ case "${host_makefile_frag}" in
+ "") ;;
+ /*) echo host_makefile_frag = ${host_makefile_frag} >>${Makefile} ;;
+ *) echo host_makefile_frag = ${invsubdir}${host_makefile_frag} >>${Makefile} ;;
+ esac
+
+ if [ "${site_makefile_frag}" != "" ] ; then
+ echo site_makefile_frag = ${invsubdir}${site_makefile_frag} >>${Makefile}
+ fi
+
+ # record if we want to build shared libs.
+ if test -z "${enable_shared}"; then
+ echo enable_shared = no >> ${Makefile}
+ else
+ echo enable_shared = ${enable_shared} >> ${Makefile}
+ fi
+ # record if we want to rumtime library stuff installed in libsubdir.
+ if test -z "${enable_version_specific_runtime_libs}"; then
+ echo enable_version_specific_runtime_libs = no >> ${Makefile}
+ else
+ echo enable_version_specific_runtime_libs = ${enable_version_specific_runtime_libs} >> ${Makefile}
+ fi
+
+ # Emit a macro which describes the file containing gcc's
+ # version number.
+ echo gcc_version_trigger = ${gcc_version_trigger} >> ${Makefile}
+ # And emit a macro defining gcc's version number.
+ echo gcc_version = ${gcc_version} >> ${Makefile}
+
+ # reset prefix, exec_prefix, srcdir, SUBDIRS, NONSUBDIRS,
+ # remove any form feeds.
+ if [ -z "${subdirs}" ]; then
+ rm -f ${subdir}/Makefile.tm2
+ sed -e "s:^SUBDIRS[ ]*=.*$:SUBDIRS = ${configdirs}:" \
+ -e "s:^NONSUBDIRS[ ]*=.*$:NONSUBDIRS = ${noconfigdirs}:" \
+ ${subdir}/Makefile.tem > ${subdir}/Makefile.tm2
+ rm -f ${subdir}/Makefile.tem
+ mv ${subdir}/Makefile.tm2 ${subdir}/Makefile.tem
+ fi
+ sed -e "s|^prefix[ ]*=.*$|prefix = ${prefix}|" \
+ -e "s|^exec_prefix[ ]*=.*$|exec_prefix = ${exec_prefix}|" \
+ -e "s|^bindir[ ]*=.*$|bindir = ${bindir}|" \
+ -e "s|^sbindir[ ]*=.*$|sbindir = ${sbindir}|" \
+ -e "s|^libexecdir[ ]*=.*$|libexecdir = ${libexecdir}|" \
+ -e "s|^datadir[ ]*=.*$|datadir = ${datadir}|" \
+ -e "s|^sysconfdir[ ]*=.*$|sysconfdir = ${sysconfdir}|" \
+ -e "s|^sharedstatedir[ ]*=.*$|sharedstatedir = ${sharedstatedir}|" \
+ -e "s|^localstatedir[ ]*=.*$|localstatedir = ${localstatedir}|" \
+ -e "s|^libdir[ ]*=.*$|libdir = ${libdir}|" \
+ -e "s|^includedir[ ]*=.*$|includedir = ${includedir}|" \
+ -e "s|^oldincludedir[ ]*=.*$|oldincludedir = ${oldincludedir}|" \
+ -e "s|^infodir[ ]*=.*$|infodir = ${infodir}|" \
+ -e "s|^mandir[ ]*=.*$|mandir = ${mandir}|" \
+ -e "/^CC[ ]*=/{
+ :loop1
+ /\\\\$/ N
+ s/\\\\\\n//g
+ t loop1
+ s%^CC[ ]*=.*$%CC = ${CC}%
+ }" \
+ -e "/^CXX[ ]*=/{
+ :loop2
+ /\\\\$/ N
+ s/\\\\\\n//g
+ t loop2
+ s%^CXX[ ]*=.*$%CXX = ${CXX}%
+ }" \
+ -e "/^CFLAGS[ ]*=/{
+ :loop3
+ /\\\\$/ N
+ s/\\\\\\n//g
+ t loop3
+ s%^CFLAGS[ ]*=.*$%CFLAGS = ${CFLAGS}%
+ }" \
+ -e "/^CXXFLAGS[ ]*=/{
+ :loop4
+ /\\\\$/ N
+ s/\\\\\\n//g
+ t loop4
+ s%^CXXFLAGS[ ]*=.*$%CXXFLAGS = ${CXXFLAGS}%
+ }" \
+ -e "s|^SHELL[ ]*=.*$|SHELL = ${config_shell}|" \
+ -e "s|^srcdir[ ]*=.*$|srcdir = ${makesrcdir}|" \
+ -e "s/ //" \
+ -e "s:^program_prefix[ ]*=.*$:program_prefix = ${program_prefix}:" \
+ -e "s:^program_suffix[ ]*=.*$:program_suffix = ${program_suffix}:" \
+ -e "s:^program_transform_name[ ]*=.*$:program_transform_name = ${program_transform_name}:" \
+ -e "s|^tooldir[ ]*=.*$|tooldir = ${tooldir}|" \
+ -e "s:^DEFAULT_YACC[ ]*=.*$:DEFAULT_YACC = ${DEFAULT_YACC}:" \
+ -e "s:^DEFAULT_LEX[ ]*=.*$:DEFAULT_LEX = ${DEFAULT_LEX}:" \
+ -e "s:^DEFAULT_M4[ ]*=.*$:DEFAULT_M4 = ${DEFAULT_M4}:" \
+ ${subdir}/Makefile.tem >> ${Makefile}
+
+
+ # If this is a Canadian Cross, preset the values of many more
+ # tools.
+ if [ "${build}" != "${host}" ]; then
+ for var in ${tools}; do
+ val=`eval 'echo $'"${var}"`
+ sed -e "/^${var}[ ]*=/{
+ :loop1
+ /\\\\$/ N
+ /\\\\$/ b loop1
+ s/\\\\\\n//g
+ s%^${var}[ ]*=.*$%${var} = ${val}%
+ }" ${Makefile} > ${Makefile}.tem
+ mv -f ${Makefile}.tem ${Makefile}
+ done
+ fi
+
+ # final copy now in ${Makefile}
+
+ else
+ echo "No Makefile.in found in ${srcdir}/${subdir}, unable to configure" 1>&2
+ fi
+
+ rm -f ${subdir}/Makefile.tem
+
+ case "${host_makefile_frag}" in
+ "") using= ;;
+ *) using="and \"${host_makefile_frag}\"" ;;
+ esac
+
+ case "${target_makefile_frag}" in
+ "") ;;
+ *) using="${using} and \"${target_makefile_frag}\"" ;;
+ esac
+
+ case "${site_makefile_frag}" in
+ "") ;;
+ *) using="${using} and \"${site_makefile_frag}\"" ;;
+ esac
+
+ newusing=`echo "${using}" | sed 's/and/using/'`
+ using=${newusing}
+ echo "Created \"${Makefile}\" in" ${PWD=`pwd`} ${using}
+
+ . ${tmpfile}.pos
+
+ # describe the chosen configuration in config.status.
+ # Make that file a shellscript which will reestablish
+ # the same configuration. Used in Makefiles to rebuild
+ # Makefiles.
+
+ case "${norecursion}" in
+ "") arguments="${arguments} --norecursion" ;;
+ *) ;;
+ esac
+
+ if [ ${subdir} = . ] ; then
+ echo "#!/bin/sh
+# ${NO_EDIT}
+# This directory was configured as follows:
+${progname}" ${arguments} "
+# ${using}" > ${subdir}/config.new
+ else
+ echo "#!/bin/sh
+# ${NO_EDIT}
+# This directory was configured as follows:
+cd ${invsubdir}
+${progname}" ${arguments} "
+# ${using}" > ${subdir}/config.new
+ fi
+ chmod a+x ${subdir}/config.new
+ if [ -r ${subdir}/config.back ] ; then
+ mv -f ${subdir}/config.back ${subdir}/config.status
+ fi
+ ${config_shell} ${moveifchange} ${subdir}/config.new ${subdir}/config.status
+ ;;
+
+ *) rm -f ${Makefile} ${subdir}/config.status ${links} ;;
+ esac
+done
+
+# If there are subdirectories, then recur.
+if [ -z "${norecursion}" ] && [ -n "${configdirs}" ] ; then
+ for configdir in ${configdirs} ${extraconfigdirs} ; do
+
+ # If configdir contains ',' it is
+ # srcdir,builddir,target_alias
+ # These come from extraconfigdirs.
+ case ${configdir} in
+ *,*)
+ eval `echo ${configdir} | sed -e 's/\([^,]*\),\([^,]*\),\(.*\)/cfg_dir=\1 bld_dir=\2 tgt_alias=\3/'`
+ ;;
+ *)
+ cfg_dir=${configdir}
+ bld_dir=${configdir}
+ tgt_alias=${target_alias}
+ ;;
+ esac
+
+ if [ -d ${srcdir}/${cfg_dir} ] ; then
+ eval echo Configuring ${configdir}... ${redirect}
+ case "${srcdir}" in
+ ".") ;;
+ *)
+ if [ ! -d ./${bld_dir} ] ; then
+ if mkdir ./${bld_dir} ; then
+ true
+ else
+ echo '***' "${progname}: could not make ${PWD=`pwd`}/${bld_dir}" 1>&2
+ exit 1
+ fi
+ fi
+ ;;
+ esac
+
+ POPDIR=${PWD=`pwd`}
+ cd ${bld_dir}
+
+### figure out what to do with srcdir
+ case "${srcdir}" in
+ ".") newsrcdir=${srcdir} ;; # no -srcdir option. We're building in place.
+ /*) # absolute path
+ newsrcdir=${srcdir}/${cfg_dir}
+ srcdiroption="--srcdir=${newsrcdir}"
+ ;;
+ ?:*) # absolute path on win32
+ newsrcdir=${srcdir}/${cfg_dir}
+ srcdiroption="--srcdir=${newsrcdir}"
+ ;;
+ *) # otherwise relative
+ newsrcdir=../${srcdir}/${cfg_dir}
+ srcdiroption="--srcdir=${newsrcdir}"
+ ;;
+ esac
+
+ # Handle --cache-file=../XXX
+ case "${cache_file}" in
+ "") # empty
+ ;;
+ /*) # absolute path
+ cache_file_option="--cache-file=${cache_file}"
+ ;;
+ ?:*) # absolute path on win32
+ cache_file_option="--cache-file=${cache_file}"
+ ;;
+ *) # relative path
+ cache_file_option="--cache-file=../${cache_file}"
+ ;;
+ esac
+
+### check for guested configure, otherwise fix possibly relative progname
+ if [ -f ${newsrcdir}/configure ] ; then
+ recprog=${newsrcdir}/configure
+ elif [ -f ${newsrcdir}/configure.in ] ; then
+ case "${progname}" in
+ /*) recprog=${progname} ;;
+ ?:*) recprog=${progname} ;;
+ *) recprog=../${progname} ;;
+ esac
+ else
+ eval echo No configuration information in ${cfg_dir} ${redirect}
+ recprog=
+ fi
+
+### The recursion line is here.
+ if [ ! -z "${recprog}" ] ; then
+ if eval ${config_shell} ${recprog} ${verbose} ${buildopt} --host=${host_alias} --target=${tgt_alias} \
+ ${prefixoption} ${tmpdiroption} ${exec_prefixoption} \
+ ${srcdiroption} ${diroptions} ${program_prefixoption} ${program_suffixoption} ${program_transform_nameoption} ${site_option} ${withoptions} ${withoutoptions} ${enableoptions} ${disableoptions} ${floating_pointoption} ${cache_file_option} ${removing} ${other_options} ${redirect} ; then
+ true
+ else
+ echo Configure in `pwd` failed, exiting. 1>&2
+ exit 1
+ fi
+ fi
+
+ cd ${POPDIR}
+ fi
+ done
+fi
+
+# Perform the same cleanup as the trap handler, minus the "exit 1" of course,
+# and reset the trap handler.
+rm -f ${tmpfile}.com ${tmpfile}.tgt ${tmpfile}.hst ${tmpfile}.pos
+trap 0
+
+exit 0
+
+#
+# Local Variables:
+# fill-column: 131
+# End:
+#
+
+# end of configure
diff --git a/configure.bat b/configure.bat
new file mode 100644
index 00000000000..d76a37ecd9d
--- /dev/null
+++ b/configure.bat
@@ -0,0 +1,17 @@
+@echo off
+
+chdir libiberty
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\bfd
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\opcodes
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\gprof
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\binutils
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\gas
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\ld
+call configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..
diff --git a/configure.in b/configure.in
new file mode 100644
index 00000000000..e4e5c43c69d
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,1184 @@
+#! /bin/bash
+##############################################################################
+
+## This file is a shell script fragment that supplies the information
+## necessary to tailor a template configure script into the configure
+## script appropriate for this directory. For more information, check
+## any existing configure script.
+
+## Be warned, there are two types of configure.in files. There are those
+## used by Autoconf, which are macros which are expanded into a configure
+## script by autoconf. The other sort, of which this is one, is executed
+## by Cygnus configure.
+
+## For more information on these two systems, check out the documentation
+## for 'Autoconf' (autoconf.texi) and 'Configure' (configure.texi).
+
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+##############################################################################
+
+### To add a new directory to the tree, first choose whether it is a target
+### or a host dependent tool. Then put it into the appropriate list
+### (library or tools, host or target), doing a dependency sort. For
+### example, gdb requires that byacc (or bison) be built first, so it is in
+### the ${host_tools} list after byacc and bison.
+
+
+# these libraries are used by various programs built for the host environment
+#
+host_libs="intl mmalloc libiberty opcodes bfd readline gash db tcl tk tcl8.1 tk8.1 tclX itcl tix libgui"
+
+if [ "${enable_gdbgui}" = "yes" ] ; then
+ host_libs="${host_libs} libgui"
+fi
+
+# these tools are built for the host environment
+# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
+# know that we are building the simulator.
+host_tools="texinfo byacc flex bison binutils ld gas gcc sim gdb make patch prms send-pr gprof gdbtest tgas etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool ispell grep diff rcs cvssrc fileutils shellutils time textutils wdiff find emacs emacs19 uudecode hello tar gzip indent recode release sed utils guile perl apache inet gawk findutils snavigator libtool gettext zip"
+
+# these libraries are built for the target environment, and are built after
+# the host libraries and the host tools (which may be a cross compiler)
+#
+target_libs="target-libiberty \
+ target-libgloss \
+ target-newlib \
+ target-libio \
+ target-librx \
+ target-libstdc++ \
+ target-libg++"
+
+# these tools are built using the target libs, and are intended to run only
+# in the target environment
+#
+# note: any program that *uses* libraries that are in the "target_libs"
+# list belongs in this list. those programs are also very likely
+# candidates for the "native_only" list which follows
+#
+target_tools="target-examples target-groff target-gperf"
+
+################################################################################
+
+## These two lists are of directories that are to be removed from the
+## ${configdirs} list for either cross-compilations or for native-
+## compilations. For example, it doesn't make that much sense to
+## cross-compile Emacs, nor is it terribly useful to compile target-libiberty in
+## a native environment.
+
+# directories to be built in the native environment only
+#
+# This must be a single line because of the way it is searched by grep in
+# the code below.
+native_only="autoconf automake libtool cvssrc emacs emacs19 fileutils find gawk gettext grep gzip hello indent ispell m4 rcs recode sed shellutils tar textutils gash uudecode wdiff gprof target-groff guile perl apache inet time ash bash bzip2 prms snavigator gnuserv target-gperf"
+
+# directories to be built in a cross environment only
+#
+cross_only="target-libgloss target-newlib target-cygmon target-opcodes target-libstub"
+
+## All tools belong in one of the four categories, and are assigned above
+## We assign ${configdirs} this way to remove all embedded newlines. This
+## is important because configure will choke if they ever get through.
+## ${configdirs} is directories we build using the host tools.
+## ${target_configdirs} is directories we build using the target tools.
+#
+configdirs=`echo ${host_libs} ${host_tools}`
+target_configdirs=`echo ${target_libs} ${target_tools}`
+
+################################################################################
+
+srctrigger=move-if-change
+srcname="gnu development package"
+
+# This gets set non-empty for some net releases of packages.
+appdirs=""
+
+# per-host:
+
+# Work in distributions that contain no compiler tools, like Autoconf.
+if [ -d ${srcdir}/config ]; then
+case "${host}" in
+ m68k-hp-hpux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hp300"
+ ;;
+ m68k-apollo-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-apollo68"
+ ;;
+ m68k-apollo-bsd*)
+ host_makefile_frag="${host_makefile_frag} config/mh-a68bsd"
+ ;;
+ m88k-dg-dgux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-dgux"
+ ;;
+ m88k-harris-cxux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-cxux"
+ ;;
+ m88k-motorola-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-delta88"
+ ;;
+ mips*-dec-ultrix*)
+ host_makefile_frag="${host_makefile_frag} config/mh-decstation"
+ ;;
+ mips*-nec-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-necv4"
+ ;;
+ mips*-sgi-irix6*)
+ host_makefile_frag="${host_makefile_frag} config/mh-irix6"
+ ;;
+ mips*-sgi-irix5*)
+ host_makefile_frag="${host_makefile_frag} config/mh-irix5"
+ ;;
+ mips*-sgi-irix4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-irix4"
+ ;;
+ mips*-sgi-irix3*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+ mips*-*-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv4"
+ ;;
+ mips*-*-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-riscos"
+ ;;
+ i[3456]86-*-sysv5*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv5"
+ ;;
+ i[3456]86-*-dgux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-dgux386"
+ ;;
+ i[3456]86-ncr-sysv4.3*)
+ host_makefile_frag="${host_makefile_frag} config/mh-ncrsvr43"
+ ;;
+ i[3456]86-ncr-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-ncr3000"
+ ;;
+ i[3456]86-*-sco3.2v5*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+ i[3456]86-*-sco*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sco"
+ ;;
+ i[3456]86-*-udk*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv5"
+ ;;
+ i[3456]86-*-isc*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+ i[3456]86-*-solaris2*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv4"
+ ;;
+ i[3456]86-*-aix*)
+ host_makefile_frag="${host_makefile_frag} config/mh-aix386"
+ ;;
+ i[3456]86-*-msdosdjgpp*)
+ host_makefile_frag="${host_makefile_frag} config/mh-djgpp"
+ ;;
+ *-cygwin*)
+ host_makefile_frag="${host_makefile_frag} config/mh-cygwin"
+ ;;
+ *-mingw32*)
+ host_makefile_frag="${host_makefile_frag} config/mh-mingw32"
+ ;;
+ *-interix*)
+ host_makefile_frag="${host_makefile_frag} config/mh-interix"
+ ;;
+ *-windows*)
+ host_makefile_frag="${host_makefile_frag} config/mh-windows"
+ ;;
+ vax-*-ultrix2*)
+ host_makefile_frag="${host_makefile_frag} config/mh-vaxult2"
+ ;;
+ *-*-solaris2*)
+ host_makefile_frag="${host_makefile_frag} config/mh-solaris"
+ ;;
+ m68k-sun-sunos*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sun3"
+ ;;
+ *-hp-hpux[78]*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hpux8"
+ ;;
+ *-hp-hpux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hpux"
+ ;;
+ *-*-hiux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-hpux"
+ ;;
+ rs6000-*-lynxos*)
+ host_makefile_frag="${host_makefile_frag} config/mh-lynxrs6k"
+ ;;
+ *-*-lynxos*)
+ host_makefile_frag="${host_makefile_frag} config/mh-lynxos"
+ ;;
+ *-*-aix4.[3456789]* | *-*-aix[56789].*)
+ host_makefile_frag="${host_makefile_frag} config/mh-aix43"
+ ;;
+ *-*-sysv4*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv4"
+ ;;
+ *-*-sysv*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sysv"
+ ;;
+esac
+fi
+
+# If we aren't going to be using gcc, see if we can extract a definition
+# of CC from the fragment.
+if [ -z "${CC}" ] && [ "${build}" = "${host}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ found=
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ found=yes
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if [ -z "${found}" ] && [ -n "${host_makefile_frag}" ] && [ -f "${srcdir}/${host_makefile_frag}" ]; then
+ xx=`sed -n -e 's/^[ ]*CC[ ]*=[ ]*\(.*\)$/\1/p' < ${srcdir}/${host_makefile_frag}`
+ if [ -n "${xx}" ] ; then
+ CC=$xx
+ fi
+ fi
+fi
+
+# We default to --with-shared on platforms where -fpic is meaningless.
+# Well, we don't yet, but we will.
+if false && [ "${host}" = "${target}" ] && [ x${enable_shared} = x ]; then
+ case "${target}" in
+ alpha*-dec-osf*) enable_shared=yes ;;
+ alpha*-*-linux*) enable_shared=yes ;;
+ mips-sgi-irix5*) enable_shared=yes ;;
+ *) enable_shared=no ;;
+ esac
+fi
+
+case "${enable_shared}" in
+ yes) shared=yes ;;
+ no) shared=no ;;
+ "") shared=no ;;
+ *) shared=yes ;;
+esac
+
+if [ x${shared} = xyes ]; then
+ case "${host}" in
+ alpha*-*-linux*)
+ host_makefile_frag="${host_makefile_frag} config/mh-elfalphapic"
+ ;;
+ arm*-*-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-armpic"
+ ;;
+ hppa*-*-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-papic"
+ ;;
+ i[3456]86-*-cygwin*)
+ # We don't want -fPIC on Cygwin.
+ ;;
+ i[3456]86-*-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-x86pic"
+ ;;
+ sparc64-*-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-sparcpic"
+ ;;
+ powerpc*-*-aix*)
+ # We don't want -fPIC on AIX.
+ ;;
+ powerpc*-*-*)
+ host_makefile_frag="${host_makefile_frag} config/mh-ppcpic"
+ ;;
+ *-*-*)
+ if test -f ${srcdir}/config/mh-${host_cpu}pic; then
+ host_makefile_frag="${host_makefile_frag} config/mh-${host_cpu}pic"
+ fi
+ ;;
+ esac
+fi
+
+rm -f mh-frag
+if [ -n "${host_makefile_frag}" ] ; then
+ for f in ${host_makefile_frag}
+ do
+ cat ${srcdir}/$f >> mh-frag
+ done
+ host_makefile_frag=mh-frag
+fi
+
+# per-target:
+
+case "${target}" in
+ v810*)
+ target_makefile_frag="${target_makefile_frag} config/mt-v810"
+ ;;
+ i[3456]86-*-netware*)
+ target_makefile_frag="${target_makefile_frag} config/mt-netware"
+ ;;
+ powerpc-*-netware*)
+ target_makefile_frag="${target_makefile_frag} config/mt-netware"
+ ;;
+ *-*-linux-gnu)
+ target_makefile_frag="${target_makefile_frag} config/mt-linux"
+ ;;
+esac
+
+# If --enable-target-optspace always use -Os instead of -O2 to build
+# the target libraries, similarly if it is not specified, use -Os
+# on selected platforms.
+case "${enable_target_optspace}:${target}" in
+ yes:*)
+ target_makefile_frag="${target_makefile_frag} config/mt-ospace"
+ ;;
+ # CYGNUS LOCAL d10v, d30v, fr30
+ :d30v-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-d30v"
+ ;;
+ :m32r-* | :d10v-* | :fr30-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-ospace"
+ ;;
+ no:* | :*)
+ ;;
+ *)
+ echo "*** bad value \"${enable_target_optspace}\" for --enable-target-optspace flag; ignored" 1>&2
+ ;;
+esac
+
+skipdirs=
+gasdir=gas
+use_gnu_ld=
+use_gnu_as=
+
+# some tools are so dependent upon X11 that if we're not building with X,
+# it's not even worth trying to configure, much less build, that tool.
+
+case ${with_x} in
+ yes | "") # the default value for this tree is that X11 is available
+ ;;
+ no)
+ skipdirs="${skipdirs} tk libgui gash"
+ ;;
+ *)
+ echo "*** bad value \"${with_x}\" for -with-x flag; ignored" 1>&2
+ ;;
+esac
+
+# Some tools are only suitable for building in a "native" situation.
+# Those are added when we have a host==target configuration. For cross
+# toolchains, we add some directories that should only be useful in a
+# cross-compiler.
+
+is_cross_compiler=
+
+if [ x"${host}" = x"${target}" ] ; then
+ # when doing a native toolchain, don't build the targets
+ # that are in the 'cross only' list
+ skipdirs="${skipdirs} ${cross_only}"
+ is_cross_compiler=no
+else
+ # similarly, don't build the targets in the 'native only'
+ # list when building a cross compiler
+ skipdirs="${skipdirs} ${native_only}"
+ is_cross_compiler=yes
+fi
+
+# We always want to use the same name for this directory, so that dejagnu
+# can reliably find it.
+target_subdir=${target_alias}
+
+if [ ! -d ${target_subdir} ] ; then
+ if mkdir ${target_subdir} ; then true
+ else
+ echo "'*** could not make ${PWD=`pwd`}/${target_subdir}" 1>&2
+ exit 1
+ fi
+fi
+
+copy_dirs=
+
+# Handle --with-headers=XXX. The contents of the named directory are
+# copied to $(tooldir)/sys-include.
+if [ x"${with_headers}" != x ]; then
+ if [ x${is_cross_compiler} = xno ]; then
+ echo 1>&2 '***' --with-headers is only supported when cross compiling
+ exit 1
+ fi
+ case "${exec_prefixoption}" in
+ "") x=${prefix} ;;
+ *) x=${exec_prefix} ;;
+ esac
+ copy_dirs="${copy_dirs} ${with_headers} $x/${target_alias}/sys-include"
+fi
+
+# Handle --with-libs=XXX. Multiple directories are permitted. The
+# contents are copied to $(tooldir)/lib.
+if [ x"${with_libs}" != x ]; then
+ if [ x${is_cross_compiler} = xno ]; then
+ echo 1>&2 '***' --with-libs is only supported when cross compiling
+ exit 1
+ fi
+ # Copy the libraries in reverse order, so that files in the first named
+ # library override files in subsequent libraries.
+ case "${exec_prefixoption}" in
+ "") x=${prefix} ;;
+ *) x=${exec_prefix} ;;
+ esac
+ for l in ${with_libs}; do
+ copy_dirs="$l $x/${target_alias}/lib ${copy_dirs}"
+ done
+fi
+
+# If both --with-headers and --with-libs are specified, default to
+# --without-newlib.
+if [ x"${with_headers}" != x ] && [ x"${with_libs}" != x ]; then
+ if [ x"${with_newlib}" = x ]; then
+ with_newlib=no
+ fi
+fi
+
+# Recognize --with-newlib/--without-newlib.
+if [ x${with_newlib} = xno ]; then
+ skipdirs="${skipdirs} target-newlib"
+elif [ x${with_newlib} = xyes ]; then
+ skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
+fi
+
+# Default to using --with-stabs for certain targets.
+if [ x${with_stabs} = x ]; then
+ case "${target}" in
+ mips*-*-irix6*)
+ ;;
+ mips*-*-* | alpha*-*-osf*)
+ with_stabs=yes;
+ withoptions="${withoptions} --with-stabs"
+ ;;
+ esac
+fi
+
+# Handle ${copy_dirs}
+set fnord ${copy_dirs}
+shift
+while [ $# != 0 ]; do
+ if [ -f $2/COPIED ] && [ x"`cat $2/COPIED`" = x"$1" ]; then
+ :
+ else
+ echo Copying $1 to $2
+
+ # Use the install script to create the directory and all required
+ # parent directories.
+ if [ -d $2 ]; then
+ :
+ else
+ echo >config.temp
+ ${srcdir}/install-sh -c -m 644 config.temp $2/COPIED
+ fi
+
+ # Copy the directory, assuming we have tar.
+ # FIXME: Should we use B in the second tar? Not all systems support it.
+ (cd $1; tar -cf - .) | (cd $2; tar -xpf -)
+
+ # It is the responsibility of the user to correctly adjust all
+ # symlinks. If somebody can figure out how to handle them correctly
+ # here, feel free to add the code.
+
+ echo $1 > $2/COPIED
+ fi
+ shift; shift
+done
+
+# Configure extra directories which are host specific
+
+case "${host}" in
+ i[3456]86-*-go32*)
+ configdirs="$configdirs dosrel" ;;
+ i[3456]86-*-mingw32*)
+ configdirs="$configdirs dosrel" ;;
+ *-cygwin*)
+ configdirs="$configdirs libtermcap dosrel" ;;
+esac
+
+# Remove more programs from consideration, based on the host or
+# target this usually means that a port of the program doesn't
+# exist yet.
+
+noconfigdirs=""
+
+case "${host}" in
+ i[3456]86-*-vsta)
+ noconfigdirs="tcl expect dejagnu make texinfo bison patch flex byacc send-pr gprof uudecode dejagnu diff guile perl apache inet itcl tix db snavigator gnuserv gettext"
+ ;;
+ i[3456]86-*-go32* | i[3456]86-*-msdosdjgpp*)
+ noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl apache inet itcl tix db snavigator gnuserv gettext"
+ ;;
+ i[3456]86-*-mingw32*)
+ # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl apache inet itcl tix db snavigator gnuserv"
+ noconfigdirs="expect dejagnu cvs autoconf automake send-pr gprof rcs guile perl texinfo apache inet libtool"
+ ;;
+ i[3456]86-*-beos*)
+ noconfigdirs="$noconfigdirs tk itcl tix libgui gdb"
+ ;;
+ *-*-cygwin*)
+ noconfigdirs="autoconf automake send-pr gprof rcs guile perl texinfo apache inet"
+ ;;
+ *-*-netbsd*)
+ noconfigdirs="rcs"
+ ;;
+ ppc*-*-pe)
+ noconfigdirs="patch diff make tk tcl expect dejagnu cvssrc autoconf automake texinfo bison send-pr gprof rcs guile perl apache inet itcl tix db snavigator gnuserv"
+ ;;
+esac
+
+
+case "${target}" in
+ *-*-netware)
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-librx target-newlib target-libiberty target-libgloss"
+ ;;
+ *-*-rtems*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ *-*-vxworks*)
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ ;;
+ alpha*-dec-osf*)
+ # ld works, but does not support shared libraries. emacs doesn't
+ # work. newlib is not 64 bit ready. I'm not sure about fileutils.
+ # gas doesn't generate exception information.
+ noconfigdirs="$noconfigdirs gas ld emacs fileutils target-newlib target-libgloss"
+ ;;
+ alpha*-*-*vms*)
+ noconfigdirs="$noconfigdirs gdb ld target-newlib target-libgloss"
+ ;;
+ alpha*-*-linux*)
+ # newlib is not 64 bit ready
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ # linux has rx in libc
+ skipdirs="$skipdirs target-librx"
+ ;;
+ alpha*-*-*)
+ # newlib is not 64 bit ready
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ ;;
+ arc-*-*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ arm-*-pe*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ arm-*-coff*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-cygmon"
+ fi
+ ;;
+ arm-*-elf*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-cygmon"
+ fi
+ ;;
+ arm-*-oabi*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ c4x-*-*)
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ ;;
+ thumb-*-coff)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+# CYGNUS LOCAL clm/arm-elf
+ thumb-*-elf)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ thumb-*-oabi)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+# END CYGNUS LOCAL
+# CYGNUS LOCAL nickc/strongarm
+ strongarm-*-elf)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-cygmon"
+ fi
+ ;;
+ strongarm-*-coff)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-cygmon"
+ fi
+ ;;
+# END CYGNUS LOCAL
+ thumb-*-pe) # CYGNUS LOCAL nickc/thumb
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ arm-*-riscix*)
+ noconfigdirs="$noconfigdirs ld target-libgloss"
+ ;;
+ d10v-*-*)
+ noconfigdirs="$noconfigdirs target-librx target-libg++ target-libstdc++ target-libio"
+ ;;
+# CYGNUS LOCAL d30v
+ d30v-*-*)
+ ;;
+# END CYGNUS LOCAL
+# CYGNUS LOCAL fr30
+ fr30-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+# END CYGNUS LOCAL
+ h8300*-*-* | \
+ h8500-*-*)
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ ;;
+ hppa*-*-*elf* | \
+ hppa*-*-lites*)
+ # Do configure ld/binutils/gas for this case.
+ ;;
+ hppa*-*-*)
+ # HP's C compiler doesn't handle Emacs correctly (but on BSD and Mach
+ # cc is gcc, and on any system a user should be able to link cc to
+ # whatever they want. FIXME, emacs emacs19).
+ case "${CC}" in
+ "" | cc*) noconfigdirs="$noconfigdirs emacs emacs19" ;;
+ *) ;;
+ esac
+ noconfigdirs="$noconfigdirs ld shellutils"
+ ;;
+ i[3456]86-*-coff | i[3456]86-*-elf)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ i[3456]86-*-go32* | i[3456]-*-msdosdjgpp*)
+ # but don't build gdb
+ noconfigdirs="$noconfigdirs gdb target-libg++ target-libstdc++ target-libio target-librx"
+ ;;
+ *-*-linux*)
+ # linux has rx in libc
+ skipdirs="$skipdirs target-librx"
+ ;;
+ i[3456]86-*-mingw32*)
+ target_configdirs="$target_configdirs target-mingw"
+ noconfigdirs="$noconfigdirs expect target-libgloss"
+
+ # Can't build gdb for mingw32 if not native.
+ case "${host}" in
+ i[3456]86-*-mingw32) ;; # keep gdb tcl tk expect etc.
+ *) noconfigdirs="$noconfigdirs gdb tcl tk expect itcl tix db snavigator gnuserv"
+ ;;
+ esac
+ ;;
+ *-*-cygwin*)
+ target_configdirs="$target_configdirs target-libtermcap target-winsup"
+ noconfigdirs="$noconfigdirs target-libgloss"
+ # always build newlib.
+ skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
+
+ # Can't build gdb for Cygwin if not native.
+ case "${host}" in
+ *-*-cygwin*) ;; # keep gdb tcl tk expect etc.
+ *) noconfigdirs="$noconfigdirs gdb tcl tk expect itcl tix libgui db snavigator gnuserv"
+ ;;
+ esac
+ ;;
+ i[3456]86-*-pe)
+ noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ ;;
+ i[3456]86-*-sco3.2v5*)
+ # The linker does not yet know about weak symbols in COFF,
+ # and is not configured to handle mixed ELF and COFF.
+ noconfigdirs="$noconfigdirs ld target-libgloss"
+ ;;
+ i[3456]86-*-sco*)
+ noconfigdirs="$noconfigdirs gprof target-libgloss"
+ ;;
+ i[3456]86-*-solaris2*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ i[3456]86-*-sysv4*)
+ # The SYSV4 C compiler doesn't handle Emacs correctly
+ case "${CC}" in
+ "" | cc*) noconfigdirs="$noconfigdirs emacs emacs19" ;;
+ *) ;;
+ esac
+ # but that's okay since emacs doesn't work anyway
+ noconfigdirs="$noconfigdirs emacs emacs19 target-libgloss"
+ ;;
+ i[3456]86-*-beos*)
+ noconfigdirs="$noconfigdirs gdb target-newlib target-libgloss"
+ ;;
+ m68k-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-cygmon"
+ fi
+ ;;
+ m68k-*-coff*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-cygmon"
+ fi
+ ;;
+ mn10200-*-*)
+ noconfigdirs="$noconfigdirs"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ mn10300-*-*)
+ noconfigdirs="$noconfigdirs"
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ powerpc-*-aix*)
+ # copied from rs6000-*-* entry
+ noconfigdirs="$noconfigdirs gprof cvssrc target-libgloss"
+ # This is needed until gcc and ld are fixed to work together.
+ use_gnu_ld=no
+ ;;
+ powerpc*-*-winnt* | powerpc*-*-pe* | ppc*-*-pe)
+ target_configdirs="$target_configdirs target-winsup"
+ noconfigdirs="$noconfigdirs gdb tcl tk make expect target-libgloss itcl tix db snavigator gnuserv"
+ # always build newlib.
+ skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
+ ;;
+ # This is temporary until we can link against shared libraries
+ powerpcle-*-solaris*)
+ noconfigdirs="$noconfigdirs gdb sim make tcl tk expect itcl tix db snavigator gnuserv"
+ ;;
+ powerpc-*-eabi)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ rs6000-*-lynxos*)
+ # The CVS server code doesn't work on the RS/6000
+ # Newlib makes problems for libg++ in crosses.
+ noconfigdirs="$noconfigdirs target-newlib gprof cvssrc"
+ ;;
+ rs6000-*-aix*)
+ noconfigdirs="$noconfigdirs gprof"
+ # This is needed until gcc and ld are fixed to work together.
+ use_gnu_ld=no
+ ;;
+ rs6000-*-*)
+ noconfigdirs="$noconfigdirs gprof"
+ ;;
+ m68k-apollo-*)
+ noconfigdirs="$noconfigdirs ld binutils gprof target-libgloss"
+ ;;
+ mips*-*-irix5*)
+ # The GNU linker does not support shared libraries.
+ # emacs is emacs 18, which does not work on Irix 5 (emacs19 does work)
+ noconfigdirs="$noconfigdirs ld gprof emacs target-libgloss"
+ ;;
+ mips*-*-irix6*)
+ # The GNU assembler and linker do not support IRIX 6.
+ # emacs is emacs 18, which does not work on Irix 5 (emacs19 does work)
+ noconfigdirs="$noconfigdirs ld gas gprof emacs target-libgloss"
+ ;;
+ mips*-dec-bsd*)
+ noconfigdirs="$noconfigdirs gprof target-libgloss"
+ ;;
+ mips*-*-bsd*)
+ noconfigdirs="$noconfigdirs gprof target-libgloss"
+ ;;
+ mipstx39-*-*)
+ noconfigdirs="$noconfigdirs gprof" # same as generic mips
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ ;;
+ mips*-*-*)
+ noconfigdirs="$noconfigdirs gprof"
+ ;;
+ romp-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes target-libgloss"
+ ;;
+ sh-*-*)
+ case "${host}" in
+ i[3456]86-*-vsta) ;; # don't add gprof back in
+ i[3456]86-*-go32*) ;; # don't add gprof back in
+ i[3456]86-*-msdosdjgpp*) ;; # don't add gprof back in
+ *) skipdirs=`echo " ${skipdirs} " | sed -e 's/ gprof / /'` ;;
+ esac
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ sparc-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ sparc64-*-elf*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-libstub target-cygmon"
+ fi
+ ;;
+ sparclite-*-*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ target_configdirs="${target_configdirs} target-bsp target-libstub target-cygmon"
+ fi
+ ;;
+ sparc-*-sunos4*)
+ if [ x${is_cross_compiler} != xno ] ; then
+ noconfigdirs="$noconfigdirs gdb gdbtest target-newlib target-libgloss"
+ else
+ use_gnu_ld=no
+ fi
+ ;;
+ v810-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libio target-libg++ target-libstdc++ opcodes target-libgloss"
+ ;;
+ v850-*-*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ v850e-*-*) # CYGNUS LOCAL v850e
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;;
+ v850ea-*-*)
+ noconfigdirs="$noconfigdirs target-libgloss"
+ ;; # END CYGNUS LOCAL
+ vax-*-vms)
+ noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes target-libgloss"
+ ;;
+ vax-*-*)
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ ;;
+ *-*-lynxos*)
+ # Newlib makes problems for libg++ in crosses.
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ ;;
+ *-*-macos* | \
+ *-*-mpw*)
+ # Macs want a resource compiler.
+ configdirs="$configdirs grez"
+ ;;
+esac
+
+# If we aren't building newlib, then don't build libgloss, since libgloss
+# depends upon some newlib header files.
+case "${noconfigdirs}" in
+ *target-libgloss*) ;;
+ *target-newlib*) noconfigdirs="$noconfigdirs target-libgloss" ;;
+esac
+
+# Make sure we don't let GNU ld be added if we didn't want it.
+if [ x$with_gnu_ld = xno ]; then
+ use_gnu_ld=no
+ noconfigdirs="$noconfigdirs ld"
+fi
+
+# Make sure we don't let GNU as be added if we didn't want it.
+if [ x$with_gnu_as = xno ]; then
+ use_gnu_as=no
+ noconfigdirs="$noconfigdirs gas"
+fi
+
+# Remove the entries in $skipdirs and $noconfigdirs from $configdirs and
+# $target_configdirs.
+# If we have the source for $noconfigdirs entries, add them to $notsupp.
+
+notsupp=""
+for dir in . $skipdirs $noconfigdirs ; do
+ dirname=`echo $dir | sed -e s/target-//g`
+ if [ $dir != . ] && echo " ${configdirs} " | grep " ${dir} " >/dev/null 2>&1; then
+ configdirs=`echo " ${configdirs} " | sed -e "s/ ${dir} / /"`
+ if [ -r $srcdir/$dirname/configure ] \
+ || [ -r $srcdir/$dirname/configure.in ]; then
+ if echo " ${skipdirs} " | grep " ${dir} " >/dev/null 2>&1; then
+ true
+ else
+ notsupp="$notsupp $dir"
+ fi
+ fi
+ fi
+ if [ $dir != . ] && echo " ${target_configdirs} " | grep " ${dir} " >/dev/null 2>&1; then
+ target_configdirs=`echo " ${target_configdirs} " | sed -e "s/ ${dir} / /"`
+ if [ -r $srcdir/$dirname/configure ] \
+ || [ -r $srcdir/$dirname/configure.in ]; then
+ if echo " ${skipdirs} " | grep " ${dir} " >/dev/null 2>&1; then
+ true
+ else
+ notsupp="$notsupp $dir"
+ fi
+ fi
+ fi
+done
+
+# Sometimes the tools are distributed with libiberty but with no other
+# libraries. In that case, we don't want to build target-libiberty.
+if [ -n "${target_configdirs}" ]; then
+ others=
+ for i in `echo ${target_configdirs} | sed -e s/target-//g` ; do
+ if [ "$i" != "libiberty" ]; then
+ if [ -r $srcdir/$i/configure ] || [ -r $srcdir/$i/configure.in ]; then
+ others=yes;
+ break;
+ fi
+ fi
+ done
+ if [ -z "${others}" ]; then
+ target_configdirs=
+ fi
+fi
+
+# Deconfigure all subdirectories, in case we are changing the
+# configuration from one where a subdirectory is supported to one where it
+# is not.
+if [ -z "${norecursion}" ] && [ -n "${configdirs}" ]; then
+ for i in `echo ${configdirs} | sed -e s/target-//g` ; do
+ rm -f $i/Makefile
+ done
+fi
+if [ -z "${norecursion}" ] && [ -n "${target_configdirs}" ]; then
+ for i in `echo ${target_configdirs} | sed -e s/target-//g` ; do
+ rm -f ${target_subdir}/$i/Makefile
+ done
+fi
+
+# Produce a warning message for the subdirs we can't configure.
+# This isn't especially interesting in the Cygnus tree, but in the individual
+# FSF releases, it's important to let people know when their machine isn't
+# supported by the one or two programs in a package.
+
+if [ -n "${notsupp}" ] && [ -z "${norecursion}" ]; then
+ # If $appdirs is non-empty, at least one of those directories must still
+ # be configured, or we error out. (E.g., if the gas release supports a
+ # specified target in some subdirs but not the gas subdir, we shouldn't
+ # pretend that all is well.)
+ if [ -n "$appdirs" ]; then
+ for dir in $appdirs ; do
+ if [ -r $dir/Makefile.in ]; then
+ if echo " ${configdirs} " | grep " ${dir} " >/dev/null 2>&1; then
+ appdirs=""
+ break
+ fi
+ if echo " ${target_configdirs} " | grep " ${dir} " >/dev/null 2>&1; then
+ appdirs=""
+ break
+ fi
+ fi
+ done
+ if [ -n "$appdirs" ]; then
+ echo "*** This configuration is not supported by this package." 1>&2
+ exit 1
+ fi
+ fi
+ # Okay, some application will build, or we don't care to check. Still
+ # notify of subdirs not getting built.
+ echo "*** This configuration is not supported in the following subdirectories:" 1>&2
+ echo " ${notsupp}" 1>&2
+ echo " (Any other directories should still work fine.)" 1>&2
+fi
+
+# Set with_gnu_as and with_gnu_ld as appropriate.
+#
+# This is done by determining whether or not the appropriate directory
+# is available, and by checking whether or not specific configurations
+# have requested that this magic not happen.
+#
+# The command line options always override the explicit settings in
+# configure.in, and the settings in configure.in override this magic.
+#
+# If the default for a toolchain is to use GNU as and ld, and you don't
+# want to do that, then you should use the --without-gnu-as and
+# --without-gnu-ld options for the configure script.
+
+if [ x${use_gnu_as} = x ] ; then
+ if [ x${with_gnu_as} != xno ] && echo " ${configdirs} " | grep " ${gasdir} " > /dev/null 2>&1 && [ -d ${srcdir}/${gasdir} ] ; then
+ with_gnu_as=yes
+ withoptions="$withoptions --with-gnu-as"
+ fi
+fi
+
+if [ x${use_gnu_ld} = x ] ; then
+ if [ x${with_gnu_ld} != xno ] && echo " ${configdirs} " | grep " ld " > /dev/null 2>&1 && [ -d ${srcdir}/ld ] ; then
+ with_gnu_ld=yes
+ withoptions="$withoptions --with-gnu-ld"
+ fi
+fi
+
+# If using newlib, add --with-newlib to the withoptions so that gcc/configure
+# can detect this case.
+
+if [ x${with_newlib} != xno ] && echo " ${target_configdirs} " | grep " target-newlib " > /dev/null 2>&1 && [ -d ${srcdir}/newlib ] ; then
+ with_newlib=yes
+ withoptions="$withoptions --with-newlib"
+fi
+
+if [ x${shared} = xyes ]; then
+ case "${target}" in
+ hppa*)
+ target_makefile_frag="${target_makefile_frag} config/mt-papic"
+ ;;
+ i[3456]86-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-x86pic"
+ ;;
+ powerpc*-*)
+ target_makefile_frag="${target_makefile_frag} config/mt-ppcpic"
+ ;;
+ alpha*-*-linux*)
+ target_makefile_frag="${target_makefile_frag} config/mt-elfalphapic"
+ ;;
+ *)
+ if test -f ${srcdir}/config/mt-${target_cpu}pic; then
+ target_makefile_frag="${target_makefile_frag} config/mt-${target_cpu}pic"
+ fi
+ ;;
+ esac
+fi
+
+rm -f mt-frag
+if [ -n "${target_makefile_frag}" ] ; then
+ for f in ${target_makefile_frag}
+ do
+ cat ${srcdir}/$f >> mt-frag
+ done
+ target_makefile_frag=mt-frag
+fi
+
+# post-target:
+
+# Make sure that the compiler is able to generate an executable. If it
+# can't, we are probably in trouble. We don't care whether we can run the
+# executable--we might be using a cross compiler--we only care whether it
+# can be created. At this point the main configure script has set CC.
+echo "int main () { return 0; }" > conftest.c
+${CC} -o conftest ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} conftest.c
+if [ $? = 0 ] && [ -s conftest -o -s conftest.exe ]; then
+ :
+else
+ echo 1>&2 "*** The command '${CC} -o conftest ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} conftest.c' failed."
+ echo 1>&2 "*** You must set the environment variable CC to a working compiler."
+ rm -f conftest*
+ exit 1
+fi
+rm -f conftest*
+
+# The Solaris /usr/ucb/cc compiler does not appear to work.
+case "${host}" in
+ sparc-sun-solaris2*)
+ CCBASE="`echo ${CC-cc} | sed 's/ .*$//'`"
+ if [ "`/usr/bin/which $CCBASE`" = "/usr/ucb/cc" ] ; then
+ could_use=
+ [ -d /opt/SUNWspro/bin ] && could_use="/opt/SUNWspro/bin"
+ if [ -d /opt/cygnus/bin ] ; then
+ if [ "$could_use" = "" ] ; then
+ could_use="/opt/cygnus/bin"
+ else
+ could_use="$could_use or /opt/cygnus/bin"
+ fi
+ fi
+ if [ "$could_use" = "" ] ; then
+ echo "Warning: compilation may fail because you're using"
+ echo "/usr/ucb/cc. You should change your PATH or CC "
+ echo "variable and rerun configure."
+ else
+ echo "Warning: compilation may fail because you're using"
+ echo "/usr/ucb/cc, when you should use the C compiler from"
+ echo "$could_use. You should change your"
+ echo "PATH or CC variable and rerun configure."
+ fi
+ fi
+ ;;
+esac
+
+# If --enable-shared was set, we must set LD_LIBRARY_PATH so that the
+# binutils tools will find libbfd.so.
+if [ "${shared}" = "yes" ]; then
+ sed -e 's/^SET_LIB_PATH[ ]*=.*$/SET_LIB_PATH = $(REALLY_SET_LIB_PATH)/' \
+ Makefile > Makefile.tem
+ rm -f Makefile
+ mv -f Makefile.tem Makefile
+
+ case "${host}" in
+ *-*-hpux*)
+ sed -e 's/^RPATH_ENVVAR[ ]*=.*$/RPATH_ENVVAR = SHLIB_PATH/' \
+ Makefile > Makefile.tem
+ rm -f Makefile
+ mv -f Makefile.tem Makefile
+ ;;
+ esac
+fi
+
+# Record target_configdirs and the configure arguments in Makefile.
+target_configdirs=`echo "${target_configdirs}" | sed -e 's/target-//g'`
+targargs=`echo "${arguments}" | \
+ sed -e 's/--no[^ ]*//' \
+ -e 's/--cache[a-z-]*=[^ ]*//' \
+ -e 's/--ho[a-z-]*=[^ ]*//' \
+ -e 's/--bu[a-z-]*=[^ ]*//' \
+ -e 's/--ta[a-z-]*=[^ ]*//'`
+
+# Passing a --with-cross-host argument lets the target libraries know
+# whether they are being built with a cross-compiler or being built
+# native. However, it would be better to use other mechanisms to make the
+# sorts of decisions they want to make on this basis. Please consider
+# this option to be deprecated. FIXME.
+if [ x${is_cross_compiler} = xyes ]; then
+ targargs="--with-cross-host=${host_alias} ${targargs}"
+fi
+
+# Default to --enable-multilib.
+if [ x${enable_multilib} = x ]; then
+ targargs="--enable-multilib ${targargs}"
+fi
+
+# Pass --with-newlib if appropriate. Note that target_configdirs has
+# changed from the earlier setting of with_newlib.
+if [ x${with_newlib} != xno ] && echo " ${target_configdirs} " | grep " newlib " > /dev/null 2>&1 && [ -d ${srcdir}/newlib ] ; then
+ targargs="--with-newlib ${targargs}"
+fi
+
+# provide a proper gxx_include_dir.
+# Note, if you change the default, make sure to fix both here and in
+# the gcc, libio, libstdc++ and libg++ subdirectories.
+# Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
+gxx_include_dir=
+if test -n "${with_gxx_include_dir}"; then
+ case "${with_gxx_include_dir}" in
+ yes )
+ echo "configure.in: error: bad value ${withval} given for g++ include directory" 1>&2
+ exit 1
+ ;;
+ no )
+ ;;
+ * )
+ gxx_include_dir=${with_gxx_include_dir}
+ ;;
+ esac
+fi
+if test x${gxx_include_dir} = x; then
+ if test x${enable_version_specific_runtime_libs} = xyes; then
+ gxx_include_dir='${libsubdir}/include/g++'
+ else
+ . ${topsrcdir}/config.if
+ gxx_include_dir='${prefix}/include/g++'-${libstdcxx_interface}
+ fi
+else
+ gxx_include_dir=${gxx_include_dir}
+fi
+
+targargs="--host=${target_alias} --build=${build_alias} ${targargs}"
+sed -e "s:^TARGET_CONFIGDIRS[ ]*=.*$:TARGET_CONFIGDIRS = ${target_configdirs}:" \
+ -e "s%^CONFIG_ARGUMENTS[ ]*=.*$%CONFIG_ARGUMENTS = ${targargs}%" \
+ -e "s%^TARGET_SUBDIR[ ]*=.*$%TARGET_SUBDIR = ${target_subdir}%" \
+ -e "s%^gxx_include_dir[ ]*=.*$%gxx_include_dir=${gxx_include_dir}%" \
+ Makefile > Makefile.tem
+rm -f Makefile
+mv -f Makefile.tem Makefile
+
+#
+# Local Variables:
+# fill-column: 131
+# End:
+#
diff --git a/etc/ChangeLog b/etc/ChangeLog
new file mode 100644
index 00000000000..0453a3e1339
--- /dev/null
+++ b/etc/ChangeLog
@@ -0,0 +1,507 @@
+1999-04-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * add-log.el, add-log.vi: New files.
+
+Wed Jan 20 01:33:50 1999 Angela Marie Thomas (angela@cygnus.com)
+
+ * comp-tools-verify: Remove some checks that are no longer valid.
+
+1998-12-03 Nick Clifton <nickc@cygnus.com>
+
+ * targetdoc/fr30.texi: New document.
+
+Thu Oct 1 21:15:59 1998 Angela Marie Thomas (angela@cygnus.com)
+
+ * comp-tools-fix, cross-tools-fix: Replace /usr/include
+ with ${FIXINCDIR}.
+
+Tue Aug 11 19:22:11 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * make-rel-sym-tree (version): Update calculation.
+
+Fri Jun 12 21:34:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.texi: Various additions.
+ * Makefile.in (TEXI2HTML, DVIPS): New variables.
+ (standards.ps): New target.
+ (configure.dvi): Copy .tin files in as well.
+ (configure.ps, configure.html): New targets.
+ (clean): Remove configdev.jpg and configbuild.jpg.
+ * configdev.fig: New file.
+ * configdev.ein: New file (EPS version of configdev.fig).
+ * configdev.jin: New file (JPEG version of configdev.fig).
+ * configbuild.fig: New file.
+ * configbuild.ein: New file (EPS version of configbuild.fig).
+ * configbuild.jin: New file (JPEG version of configbuild.fig).
+
+Wed Jun 10 14:41:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.texi: New file.
+ * configdev.tin: New file.
+ * configbuild.tin: New file.
+ * Makefile.in (MAKEINFO): Use makeinfo from texinfo directory if
+ it exists.
+ (TEXI2DVI): Likewise for texi2dvi.
+ (INFOFILES): Add configure.info.
+ (DVIFILES): Add configure.dvi.
+ (info): Only build info files if the source files exist.
+ (install-info): Only install info files if they exist.
+ (dvi): Only build DVI files if the sources files exist.
+ (configure.info): New target.
+ (configure.dvi): New target.
+ (clean): Remove configdev and configbuild derived files.
+
+ Remove obsolete documentation.
+ * intro.texi: Remove.
+ * install.texi: Remove.
+ * config-names.texi: Remove.
+ * screen1.eps: Remove.
+ * screen1.obj: Remove.
+ * screen2.eps: Remove.
+ * screen2.obj: Remove.
+ * Makefile.in: Remove references to the above.
+
+Thu May 21 14:34:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * targetdoc/arm-interwork.texi: Add note about ignoring linker
+ warning message when using --support-old-code.
+
+Mon May 18 14:27:37 1998 Angela Marie Thomas (angela@cygnus.com)
+
+ * Install.in, comp-tools-fix, comp-tools-verify, cross-tools-fix:
+ Use $GCCvn rather than substitute everywhere.
+
+Thu May 14 14:43:10 1998 Nick Clifton <nickc@cygnus.com>
+
+ * targetdoc/arm-interwork.texi: Document dlltool support of
+ interworking.
+
+Thu May 7 16:49:38 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * Install.in: Remove references to TCL_LIBRARY, TK_LIBRARY,
+ and GDBTK_FILENAME.
+
+Wed Apr 1 17:11:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * targetdoc/arm-interwork.texi: Document ARM/thumb interworking.
+
+Tue Mar 31 15:28:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * standards.texi, make-stds.texi: Update to current FSF versions.
+ * Makefile.in (standards.info): Depend upon make-std.texi.
+
+Tue Mar 24 16:13:26 1998 Stu Grossman <grossman@bhuna.cygnus.co.uk>
+
+ * configure: Regenerate with autoconf 2.12.1 to fix shell issues
+ for NT native builds.
+
+Mon Mar 9 16:41:04 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * make-rel-sym-tree (binprogs): Add objcopy.
+
+Tue Feb 24 18:11:58 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * make-rel-sym-tree: as.new -> as-new, ld.new -> ld-new
+ nm.new -> nm-new. Make symlinks to crt*.o.
+
+Fri Nov 21 12:54:58 1997 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in: Add --no-split argument to avoid creating files
+ with names longer than 14 characters.
+
+Thu Sep 25 13:13:11 1997 Jason Molenda (crash@pern.cygnus.com)
+
+ * intro.texi: Add closing ifset.
+
+Mon Sep 1 10:31:32 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * Install.in: Move setting HOST and TARGET to the beginning
+ of the file for editing convenience.
+
+Mon Sep 1 10:28:37 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * Install.in.: More friendly options/messages when extracting
+ from a file instead of a tape device.
+
+Tue Jun 17 15:50:23 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * Install.in: Add /usr/bsd to PATH for Irix (home of compress)
+
+Thu Jun 12 13:47:00 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * Install.in (show_exec_prefix_msg): fix quoting
+
+Wed Jun 4 15:31:43 1997 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * rebuilding.texi: Removed.
+
+Sat May 24 18:02:20 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * cross-tools-fix: Remove host check since it doesn't matter
+ for this case.
+ * Install.in (guess_system): clean up more unused hosts.
+ * Install.in, cross-tools-fix, comp-tools-fix, comp-tools-verify:
+ Hack for host check to not warn the user for certain cases.
+
+Fri May 23 23:46:10 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * subst-strings: Remove a lot of unused code
+ * Install.in: Remove reference to TAPEdflt, use variables instead of
+ string substitution when able.
+
+Fri Apr 11 17:25:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change file named in AC_INIT to Makefile.in.
+ * configure: Rebuild.
+
+Fri Apr 11 18:12:42 1997 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Install.in (guess_system): Back out change to INSTALLHOST to
+ call all IRIX systems "mips-sgi-irix4"
+
+ * Makefile.in: Remove references to configure.texi and cfg-paper.texi.
+
+Thu Apr 10 23:26:45 1997 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * srctree.texi, emacs-relnotes.texi, cfg-paper.texi: Remove.
+ * Install.in: Remove Ultrix-specific hacks.
+ Update Cygnus phone numbers.
+ (guess_system): Remove some old systems (Ultrix, OSF1 v1 & 2,
+ m68k-HPUX, m68k SunOS, etc.)
+ (show_gnu_root_msg): Remove.
+ Removed all the remove option code.
+
+Thu Apr 10 23:23:33 1997 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * configure.man, configure.texi: Remote.
+
+Mon Apr 7 18:15:00 1997 Brendan Kehoe <brendan@cygnus.com>
+
+ * Fix the version string for OSF1 4.0 to recognize either
+ V4.* or X4.*
+
+Mon Apr 7 15:34:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * standards.texi, make-stds.texi: Update to current FSF versions.
+
+Tue Nov 19 15:36:14 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * make-rel-sym-tree: New file.
+
+Wed Oct 23 00:34:07 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * Lots of patches from progressive...
+ * Install.in: restore DDOPTS for AIX 4.x
+ * Install.in, subst-strings: add case for DG Aviion
+ * subst-strings: fix typo in INSTALLdir var setting
+ * comp-tools-verify: set SHLIB_PATH for shared libs
+ * Install.in, subst-strings: add case for solaris2.5
+ * Install.in: fix regression for hppa1.1 check
+ * comp-tools-fix: set LD_LIBRARY_PATH
+ * comp-tools-fix: If fixincludes fixes /usr/include/limits.h,
+ install it as syslimits.h.
+
+Wed Oct 16 19:20:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * Install.in (guess_system): Treat powerpc-ibm-aix4.1 the same as
+ rs6000-ibm-aix4.1, since the compiler now uses common mode by
+ default.
+
+Wed Oct 2 15:39:07 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * configure.in (AC_PROG_INSTALL): Added.
+ * Makefile.in (distclean): Remove config.cache.
+
+Wed Oct 2 14:33:58 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * configure.in: Switch to autoconf configure.in.
+ * configure: New.
+ * Makefile.in: Use autoconf-substituted values.
+
+Tue Jun 25 18:56:08 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (datadir): Changed to $(prefix)/share.
+
+Fri Mar 29 11:38:01 1996 J.T. Conklin (jtc@lisa.cygnus.com)
+
+ * configure.man: Changed to be recognized by catman -w on Solaris.
+
+Wed Dec 6 15:40:28 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * comp-tools-fix (fixincludes): Define FIXPROTO_DEFINES from
+ .../install-tools/fixproto-defines.
+
+Sun Nov 12 19:31:27 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * comp-tools-verify (verify_cxx_initializers): delete argv,
+ argc declarations, add -static to compile line.
+ (verify_cxx_hello_world): delete argv, argc declarations, add
+ -static to compile line.
+
+Wed Sep 20 13:21:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean.
+
+Mon Aug 28 17:25:49 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Install.in (PATH): add /usr/ucb to $PATH (for SunOS 4.1.x).
+
+Tue Aug 15 21:51:58 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Install.in (guess_system): Match OSF/1 v3.x as the same as
+ v2.x--v2.x binaries are upward compatible.
+
+Tue Aug 15 21:46:54 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Install.in (guess_system): recognize HP 9000/800 systems as the
+ same as HP 9000/700 systems.
+
+Tue Aug 8 13:11:56 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Install.in: For emacs, run show_emacs_alternate_msg and exit.
+ (show_emacs_alternate_msg): New message saying how emacs can't be
+ installed in an alternate prefix.
+
+Thu Jun 8 00:42:56 1995 Angela Marie Thomas <angela@cirdan.cygnus.com>
+
+ * subst-strings: change du commands to $BINDIR/. & $SRCDIR/. just
+ in case they are symlinks.
+
+Tue Apr 18 14:23:10 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * cdk-fix: Extracted table of targets that don't need their
+ headers fixed from gcc's configure script.
+
+ * cdk-fix, cdk-verify: Use ${HOST} instead of ||HOSTstr||
+
+ * cdk-fix, cdk-verify: New files, install script fragments used
+ for Cygnus Developer's Kit.
+
+ * Install.in (do_mkdir): New function.
+
+ * Install.in: Added support for --with and --without options.
+ Changed so that tape commands are not run when extracting
+ from a file.
+ (do_mt): Changed to take only one argument.
+
+Wed Mar 29 11:16:38 1995 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Install.in: catch UNAME==alpha-dec-osf2.x and correct entry for
+ alpha-dec-osf1.x
+
+Fri Jan 27 12:04:29 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * subst-strings (mips-sgi-irix5): New entry in table.
+
+Thu Jan 19 12:15:44 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Install.in: Major rewrite, bundle dependent code (for example,
+ fixincludes for comp-tools) will be inserted into the Install
+ script when it is generated.
+
+Tue Jan 17 16:51:32 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (Makefile): Rebuild using $(SHELL).
+
+Thu Nov 3 19:30:33 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (install-info): Depend on info.
+
+Fri Aug 19 16:16:38 1994 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * Install.in: set $FIX_HEADER so fixproto can find fix-header.
+
+Fri May 6 16:18:58 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Makefile.in (install-info): add a semicolon in the if statement.
+
+Fri Apr 29 16:56:07 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * cfg-paper.texi: Update some outdated information.
+
+ * Makefile.in (install-info): Pass file, not directory, as last
+ arg to INSTALL_DATA.
+ (uninstall): New target.
+
+Thu Apr 28 14:42:22 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.texi: Comment out @smallbook.
+
+ * Makefile.in: Define TEXI2DVI and TEXIDIR, and use the latter.
+ Remove info files in realclean, not clean, per coding standards.
+ Remove TeX output in clean.
+
+Tue Apr 26 17:18:03 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: fixincludes output is actually put in fixincludes.log,
+ but echo'ed messages claim it is fixinc.log. This is the same
+ messages as I logged in March 4 1994, but for some reason we found
+ the change hadn't been done. I'll have to dig through the logs
+ and find out what I really did do that day. :)
+
+Mon Apr 25 20:28:19 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: use eval to call do_mt() for Ultrix brokenness.
+
+Mon Apr 25 20:00:00 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in(do_mt): exit with error status 1 if # of parameters
+ != 3.
+
+Mon Apr 25 19:42:36 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: lose TAPE_FORWARD and TAPE_REWIND, add do_mt()
+ to do all tape movement operations. Currently untested. Addresses
+ PR # 4886 from bull.
+
+ * Install.in: add 1994 to the copyright thing.
+
+Fri Apr 22 19:05:13 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * standards.texi: Update from FSF.
+
+Fri Apr 22 15:46:10 1994 Jason Molenda (crash@cygnus.com)
+
+ * Install.in: Add $DDOPTS, has ``bs=124b'' for all systems except
+ AIX (some versions of AIX don't understand bs=124b. Silly OS).
+
+Mon Apr 4 22:55:05 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: null out $TOOLS before adding stuff to it
+ non-destructively.
+
+Wed Mar 30 21:45:35 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * standards.texi: Fix typo.
+
+ * configure.texi, configure.man: Document --disable-.
+
+Mon Mar 28 13:22:15 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * standards.texi: Update from FSF.
+
+Sat Mar 26 09:21:44 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * standards.texi, make-stds.texi: Update from FSF.
+
+Fri Mar 25 22:59:45 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.texi, configure.man: Document --enable-* options.
+
+Wed Mar 23 23:38:24 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: set CPP to be gcc -E for fixincludes.
+
+Wed Mar 23 13:42:48 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: set PATH to $PATH:/bin:/usr/bin so we can pick
+ up native tools even if the user doesn't have them in his
+ path.
+
+ * Install.in: ``hppa-1.1-hp-hpux'' -> ``hppa1.1-hp-hpux''.
+
+Tue Mar 15 22:09:20 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: TAPE_REWIND and TAPE_FORWARD variables for Unixunaware,
+ added switch statement to detect if system is Unixunaware.
+
+Fri Mar 4 12:10:30 1994 Jason Molenda (crash@sendai.cygnus.com)
+
+ * Install.in: fixincludes output is actually put in fixincludes.log,
+ but echo'ed messages claim it is fixinc.log.
+
+Wed Nov 3 02:58:02 1993 Jeffrey Osier (jeffrey@thepub.cygnus.com)
+
+ * subst-strings: output TEXBUNDLE for more install notes matching
+ * install-texi.in: PRMS info now exists
+
+Tue Oct 26 16:57:12 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * subst-strings: match solaris*. Also, add default case to catch
+ and error out for unrecognized systems.
+
+Thu Aug 19 18:21:31 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Install.in: handle the new fixproto work
+
+Mon Jul 19 12:05:41 1993 david d `zoo' zuhn (zoo@cirdan.cygnus.com)
+
+ * Install.in: remove "MT=tctl" for AIX (not needed, and barely
+ worked anyway)
+
+Mon Jun 14 19:09:22 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * subst-strings: changed HOST to recognize Solaris for install notes
+
+Thu Jun 10 16:01:25 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * dos-inst.texi: new file.
+
+Wed Jun 9 19:23:59 1993 Jeffrey Osier (jeffrey@rtl.cygnus.com)
+
+ * install-texi.in: added conditionals (nearly complete)
+ cleaned up
+ added support for other releases (not done)
+
+Wed Jun 9 15:53:58 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (install-info): Use INSTALL_DATA.
+ ({dist,real}clean): Also delete Makefile and config.status.
+
+Fri Jun 4 17:09:56 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * subst-strings: added data for OS_STRING
+
+ * subst-strings: added support for OS_STRING
+
+Thu Jun 3 00:37:01 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Install.in: pull COPYING and COPYING.LIB off of the tape
+
+Tue Jun 1 16:52:08 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * subst-strings: replace RELEASE_DIR too
+
+Mon Mar 22 23:55:27 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add installcheck target
+
+Wed Mar 17 02:21:15 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Install.in: fix 'source only' extraction bug where it looked for
+ the src dir under H-<host>/src instead of src; also remove stray
+ reference to EMACSHIBIN
+
+Mon Mar 15 01:25:45 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * make-stds.texi: added 'installcheck' to the standard targets
+
+Tue Mar 9 19:48:28 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * standards.texi: added INFO-DIR-ENTRY, updated version from the FSF
+
+Tue Feb 9 12:40:23 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (standards.info): Added -I$(srcdir) to find
+ make-stds.texi.
+
+Mon Feb 1 16:32:56 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * standards.texi: updated to latest FSF version, which includes:
+
+ * make-stds.texi: new file
+
+Mon Nov 30 01:31:40 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * install-texi.in, relnotes.texi, intro.texi: changed Cygnus phone
+ numbers from the old Palo Alto ones to the new Mtn. View numbers
+
+Mon Nov 16 16:50:43 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: define $(RM) to "rm -f"
+
+Sun Oct 11 16:05:48 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * intro.texi: added INFO-DIR-ENTRY
+
diff --git a/etc/Makefile.in b/etc/Makefile.in
new file mode 100644
index 00000000000..eedc8c9c1ac
--- /dev/null
+++ b/etc/Makefile.in
@@ -0,0 +1,156 @@
+#
+# Makefile.in for etc
+#
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(libdir)
+datadir = @datadir@
+
+mandir = @mandir@
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = @infodir@
+
+SHELL = /bin/sh
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+MAKEINFO = `if [ -f ../texinfo/makeinfo/makeinfo ]; \
+ then echo ../texinfo/makeinfo/makeinfo; \
+ else echo makeinfo; fi`
+TEXI2DVI = `if [ -f ../texinfo/util/texi2dvi ]; \
+ then echo ../texinfo/util/texi2dvi; \
+ else echo texi2dvi; fi`
+TEXI2HTML = texi2html
+DVIPS = dvips
+
+# Where to find texinfo.tex to format documentation with TeX.
+TEXIDIR = $(srcdir)/../texinfo
+
+#### Host, target, and site specific Makefile fragments come in here.
+###
+
+INFOFILES = standards.info configure.info
+DVIFILES = standards.dvi configure.dvi
+
+all:
+
+install:
+
+uninstall:
+
+info:
+ for f in $(INFOFILES); do \
+ if test -f $(srcdir)/`echo $$f | sed -e 's/.info$$/.texi/'`; then \
+ if $(MAKE) "MAKEINFO=$(MAKEINFO)" $$f; then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ fi; \
+ done
+
+install-info: info
+ $(SHELL) $(srcdir)/../mkinstalldirs $(infodir)
+ if test ! -f standards.info; then cd $(srcdir); fi; \
+ if test -f standards.info; then \
+ for i in standards.info*; do \
+ $(INSTALL_DATA) $$i $(infodir)/$$i; \
+ done; \
+ fi
+ if test ! -f configure.info; then cd $(srcdir); fi; \
+ if test -f configure.info; then \
+ for i in configure.info*; do \
+ $(INSTALL_DATA) $$i $(infodir)/$$i; \
+ done; \
+ fi
+
+dvi:
+ for f in $(DVIFILES); do \
+ if test -f $(srcdir)/`echo $$f | sed -e 's/.dvi$$/.texi/'`; then \
+ if $(MAKE) "TEXI2DVI=$(TEXI2DVI)" $$f; then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ fi; \
+ done
+
+standards.info: $(srcdir)/standards.texi $(srcdir)/make-stds.texi
+ $(MAKEINFO) --no-split -I$(srcdir) -o standards.info $(srcdir)/standards.texi
+
+standards.dvi: $(srcdir)/standards.texi
+ TEXINPUTS=$(TEXIDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/standards.texi
+
+standards.ps: standards.dvi
+ $(DVIPS) standards.dvi -o standards.ps
+
+# makeinfo requires images to be in the current directory.
+configure.info: $(srcdir)/configure.texi $(srcdir)/configdev.tin $(srcdir)/configbuild.tin
+ rm -f configdev.txt configbuild.txt
+ cp $(srcdir)/configdev.tin configdev.txt
+ cp $(srcdir)/configbuild.tin configbuild.txt
+ $(MAKEINFO) -I$(srcdir) -o configure.info $(srcdir)/configure.texi
+ rm -f configdev.txt configbuild.txt
+
+# texi2dvi wants both the .txt and the .eps files.
+configure.dvi: $(srcdir)/configure.texi $(srcdir)/configdev.tin $(srcdir)/configbuild.tin $(srcdir)/configdev.ein $(srcdir)/configbuild.ein
+ rm -f configdev.txt configbuild.txt
+ cp $(srcdir)/configdev.tin configdev.txt
+ cp $(srcdir)/configbuild.tin configbuild.txt
+ rm -f configdev.eps configbuild.eps
+ cp $(srcdir)/configdev.ein configdev.eps
+ cp $(srcdir)/configbuild.ein configbuild.eps
+ TEXINPUTS=$(TEXIDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/configure.texi
+ rm -f configdev.txt configbuild.txt
+ rm -f configdev.eps configbuild.eps
+
+# dvips requires images to be in the current directory
+configure.ps: configure.dvi $(srcdir)/configdev.ein $(srcdir)/configbuild.ein
+ rm -f configdev.eps configbuild.eps
+ cp $(srcdir)/configdev.ein configdev.eps
+ cp $(srcdir)/configbuild.ein configbuild.eps
+ $(DVIPS) configure.dvi -o configure.ps
+ rm -f configdev.eps configbuild.eps
+
+configure.html: $(srcdir)/configure.texi
+ $(TEXI2HTML) -split_chapter $(srcdir)/configure.texi
+
+clean:
+ rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
+ rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs
+ rm -f configdev.txt configbuild.txt configdev.eps configbuild.eps
+ rm -f configdev.jpg configbuild.jpg
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.status config.cache
+
+maintainer-clean realclean: distclean
+ rm -f *.info*
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+ $(SHELL) ./config.status
+
+## these last targets are for standards.texi conformance
+dist:
+check:
+installcheck:
+TAGS:
diff --git a/etc/add-log.el b/etc/add-log.el
new file mode 100644
index 00000000000..60c88e8c949
--- /dev/null
+++ b/etc/add-log.el
@@ -0,0 +1,573 @@
+;;; ============ NOTE WELL! =============
+;;;
+;;; You only need to use this file if you're using a version of Emacs
+;;; prior to 20.1 to work on GDB. The only difference between this
+;;; and the standard add-log.el provided with 19.34 is that it
+;;; generates dates using the terser format used by Emacs 20. This is
+;;; the format recommended for use in GDB ChangeLogs.
+;;;
+;;; To use this code, you should create a directory `~/elisp', save the code
+;;; below in `~/elisp/add-log.el', and then put something like this in
+;;; your `~/.emacs' file, to tell Emacs where to find it:
+;;;
+;;; (setq load-path
+;;; (cons (expand-file-name "~/elisp")
+;;; load-path))
+;;;
+;;; If you want, you can also byte-compile it --- it'll run a little
+;;; faster, and use a little less memory. (Not that those matter much for
+;;; this file.) To do that, after you've saved the text as
+;;; ~/elisp/add-log.el, bring it up in Emacs, and type
+;;;
+;;; C-u M-x byte-compile-file
+;;;
+;;; --- Jim Blandy
+
+;;; add-log.el --- change log maintenance commands for Emacs
+
+;; Copyright (C) 1985, 1986, 1988, 1993, 1994 Free Software Foundation, Inc.
+
+;; Keywords: maint
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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, or (at your option)
+;; any later version.
+
+;; GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This facility is documented in the Emacs Manual.
+
+;;; Code:
+
+(defvar change-log-default-name nil
+ "*Name of a change log file for \\[add-change-log-entry].")
+
+(defvar add-log-current-defun-function nil
+ "\
+*If non-nil, function to guess name of current function from surrounding text.
+\\[add-change-log-entry] calls this function (if nil, `add-log-current-defun'
+instead) with no arguments. It returns a string or nil if it cannot guess.")
+
+;;;###autoload
+(defvar add-log-full-name nil
+ "*Full name of user, for inclusion in ChangeLog daily headers.
+This defaults to the value returned by the `user-full-name' function.")
+
+;;;###autoload
+(defvar add-log-mailing-address nil
+ "*Electronic mail address of user, for inclusion in ChangeLog daily headers.
+This defaults to the value of `user-mail-address'.")
+
+(defvar change-log-font-lock-keywords
+ '(("^[SMTWF].+" . font-lock-function-name-face) ; Date line.
+ ("^\t\\* \\([^ :\n]+\\)" 1 font-lock-comment-face) ; File name.
+ ("(\\([^)\n]+\\)):" 1 font-lock-keyword-face)) ; Function name.
+ "Additional expressions to highlight in Change Log mode.")
+
+(defvar change-log-mode-map nil
+ "Keymap for Change Log major mode.")
+(if change-log-mode-map
+ nil
+ (setq change-log-mode-map (make-sparse-keymap))
+ (define-key change-log-mode-map "\M-q" 'change-log-fill-paragraph))
+
+(defun change-log-name ()
+ (or change-log-default-name
+ (if (eq system-type 'vax-vms)
+ "$CHANGE_LOG$.TXT"
+ (if (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))
+ "changelo"
+ "ChangeLog"))))
+
+;;;###autoload
+(defun prompt-for-change-log-name ()
+ "Prompt for a change log name."
+ (let* ((default (change-log-name))
+ (name (expand-file-name
+ (read-file-name (format "Log file (default %s): " default)
+ nil default))))
+ ;; Handle something that is syntactically a directory name.
+ ;; Look for ChangeLog or whatever in that directory.
+ (if (string= (file-name-nondirectory name) "")
+ (expand-file-name (file-name-nondirectory default)
+ name)
+ ;; Handle specifying a file that is a directory.
+ (if (file-directory-p name)
+ (expand-file-name (file-name-nondirectory default)
+ (file-name-as-directory name))
+ name))))
+
+;;;###autoload
+(defun find-change-log (&optional file-name)
+ "Find a change log file for \\[add-change-log-entry] and return the name.
+
+Optional arg FILE-NAME specifies the file to use.
+If FILE-NAME is nil, use the value of `change-log-default-name'.
+If 'change-log-default-name' is nil, behave as though it were 'ChangeLog'
+\(or whatever we use on this operating system).
+
+If 'change-log-default-name' contains a leading directory component, then
+simply find it in the current directory. Otherwise, search in the current
+directory and its successive parents for a file so named.
+
+Once a file is found, `change-log-default-name' is set locally in the
+current buffer to the complete file name."
+ ;; If user specified a file name or if this buffer knows which one to use,
+ ;; just use that.
+ (or file-name
+ (setq file-name (and change-log-default-name
+ (file-name-directory change-log-default-name)
+ change-log-default-name))
+ (progn
+ ;; Chase links in the source file
+ ;; and use the change log in the dir where it points.
+ (setq file-name (or (and buffer-file-name
+ (file-name-directory
+ (file-chase-links buffer-file-name)))
+ default-directory))
+ (if (file-directory-p file-name)
+ (setq file-name (expand-file-name (change-log-name) file-name)))
+ ;; Chase links before visiting the file.
+ ;; This makes it easier to use a single change log file
+ ;; for several related directories.
+ (setq file-name (file-chase-links file-name))
+ (setq file-name (expand-file-name file-name))
+ ;; Move up in the dir hierarchy till we find a change log file.
+ (let ((file1 file-name)
+ parent-dir)
+ (while (and (not (or (get-file-buffer file1) (file-exists-p file1)))
+ (progn (setq parent-dir
+ (file-name-directory
+ (directory-file-name
+ (file-name-directory file1))))
+ ;; Give up if we are already at the root dir.
+ (not (string= (file-name-directory file1)
+ parent-dir))))
+ ;; Move up to the parent dir and try again.
+ (setq file1 (expand-file-name
+ (file-name-nondirectory (change-log-name))
+ parent-dir)))
+ ;; If we found a change log in a parent, use that.
+ (if (or (get-file-buffer file1) (file-exists-p file1))
+ (setq file-name file1)))))
+ ;; Make a local variable in this buffer so we needn't search again.
+ (set (make-local-variable 'change-log-default-name) file-name)
+ file-name)
+
+;;;###autoload
+(defun add-change-log-entry (&optional whoami file-name other-window new-entry)
+ "Find change log file and add an entry for today.
+Optional arg (interactive prefix) non-nil means prompt for user name and site.
+Second arg is file name of change log. If nil, uses `change-log-default-name'.
+Third arg OTHER-WINDOW non-nil means visit in other window.
+Fourth arg NEW-ENTRY non-nil means always create a new entry at the front;
+never append to an existing entry."
+ (interactive (list current-prefix-arg
+ (prompt-for-change-log-name)))
+ (or add-log-full-name
+ (setq add-log-full-name (user-full-name)))
+ (or add-log-mailing-address
+ (setq add-log-mailing-address user-mail-address))
+ (if whoami
+ (progn
+ (setq add-log-full-name (read-input "Full name: " add-log-full-name))
+ ;; Note that some sites have room and phone number fields in
+ ;; full name which look silly when inserted. Rather than do
+ ;; anything about that here, let user give prefix argument so that
+ ;; s/he can edit the full name field in prompter if s/he wants.
+ (setq add-log-mailing-address
+ (read-input "Mailing address: " add-log-mailing-address))))
+ (let ((defun (funcall (or add-log-current-defun-function
+ 'add-log-current-defun)))
+ paragraph-end entry)
+
+ (setq file-name (expand-file-name (find-change-log file-name)))
+
+ ;; Set ENTRY to the file name to use in the new entry.
+ (and buffer-file-name
+ ;; Never want to add a change log entry for the ChangeLog file itself.
+ (not (string= buffer-file-name file-name))
+ (setq entry (if (string-match
+ (concat "^" (regexp-quote (file-name-directory
+ file-name)))
+ buffer-file-name)
+ (substring buffer-file-name (match-end 0))
+ (file-name-nondirectory buffer-file-name))))
+
+ (if (and other-window (not (equal file-name buffer-file-name)))
+ (find-file-other-window file-name)
+ (find-file file-name))
+ (or (eq major-mode 'change-log-mode)
+ (change-log-mode))
+ (undo-boundary)
+ (goto-char (point-min))
+ (let ((heading (format "%s %s <%s>"
+ (format-time-string "%Y-%m-%d")
+ add-log-full-name
+ add-log-mailing-address)))
+ (if (looking-at (regexp-quote heading))
+ (forward-line 1)
+ (insert heading "\n\n")))
+
+ ;; Search only within the first paragraph.
+ (if (looking-at "\n*[^\n* \t]")
+ (skip-chars-forward "\n")
+ (forward-paragraph 1))
+ (setq paragraph-end (point))
+ (goto-char (point-min))
+
+ ;; Now insert the new line for this entry.
+ (cond ((re-search-forward "^\\s *\\*\\s *$" paragraph-end t)
+ ;; Put this file name into the existing empty entry.
+ (if entry
+ (insert entry)))
+ ((and (not new-entry)
+ (let (case-fold-search)
+ (re-search-forward
+ (concat (regexp-quote (concat "* " entry))
+ ;; Don't accept `foo.bar' when
+ ;; looking for `foo':
+ "\\(\\s \\|[(),:]\\)")
+ paragraph-end t)))
+ ;; Add to the existing entry for the same file.
+ (re-search-forward "^\\s *$\\|^\\s \\*")
+ (goto-char (match-beginning 0))
+ ;; Delete excess empty lines; make just 2.
+ (while (and (not (eobp)) (looking-at "^\\s *$"))
+ (delete-region (point) (save-excursion (forward-line 1) (point))))
+ (insert "\n\n")
+ (forward-line -2)
+ (indent-relative-maybe))
+ (t
+ ;; Make a new entry.
+ (forward-line 1)
+ (while (looking-at "\\sW")
+ (forward-line 1))
+ (while (and (not (eobp)) (looking-at "^\\s *$"))
+ (delete-region (point) (save-excursion (forward-line 1) (point))))
+ (insert "\n\n\n")
+ (forward-line -2)
+ (indent-to left-margin)
+ (insert "* " (or entry ""))))
+ ;; Now insert the function name, if we have one.
+ ;; Point is at the entry for this file,
+ ;; either at the end of the line or at the first blank line.
+ (if defun
+ (progn
+ ;; Make it easy to get rid of the function name.
+ (undo-boundary)
+ (insert (if (save-excursion
+ (beginning-of-line 1)
+ (looking-at "\\s *$"))
+ ""
+ " ")
+ "(" defun "): "))
+ ;; No function name, so put in a colon unless we have just a star.
+ (if (not (save-excursion
+ (beginning-of-line 1)
+ (looking-at "\\s *\\(\\*\\s *\\)?$")))
+ (insert ": ")))))
+
+;;;###autoload
+(defun add-change-log-entry-other-window (&optional whoami file-name)
+ "Find change log file in other window and add an entry for today.
+Optional arg (interactive prefix) non-nil means prompt for user name and site.
+Second arg is file name of change log. \
+If nil, uses `change-log-default-name'."
+ (interactive (if current-prefix-arg
+ (list current-prefix-arg
+ (prompt-for-change-log-name))))
+ (add-change-log-entry whoami file-name t))
+;;;###autoload (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window)
+
+;;;###autoload
+(defun change-log-mode ()
+ "Major mode for editing change logs; like Indented Text Mode.
+Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74.
+New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window].
+Each entry behaves as a paragraph, and the entries for one day as a page.
+Runs `change-log-mode-hook'."
+ (interactive)
+ (kill-all-local-variables)
+ (indented-text-mode)
+ (setq major-mode 'change-log-mode
+ mode-name "Change Log"
+ left-margin 8
+ fill-column 74
+ indent-tabs-mode t
+ tab-width 8)
+ (use-local-map change-log-mode-map)
+ ;; Let each entry behave as one paragraph:
+ ;; We really do want "^" in paragraph-start below: it is only the lines that
+ ;; begin at column 0 (despite the left-margin of 8) that we are looking for.
+ (set (make-local-variable 'paragraph-start) "\\s *$\\|\f\\|^\\sw")
+ (set (make-local-variable 'paragraph-separate) "\\s *$\\|\f\\|^\\sw")
+ ;; Let all entries for one day behave as one page.
+ ;; Match null string on the date-line so that the date-line
+ ;; is grouped with what follows.
+ (set (make-local-variable 'page-delimiter) "^\\<\\|^\f")
+ (set (make-local-variable 'version-control) 'never)
+ (set (make-local-variable 'adaptive-fill-regexp) "\\s *")
+ (set (make-local-variable 'font-lock-defaults)
+ '(change-log-font-lock-keywords t))
+ (run-hooks 'change-log-mode-hook))
+
+;; It might be nice to have a general feature to replace this. The idea I
+;; have is a variable giving a regexp matching text which should not be
+;; moved from bol by filling. change-log-mode would set this to "^\\s *\\s(".
+;; But I don't feel up to implementing that today.
+(defun change-log-fill-paragraph (&optional justify)
+ "Fill the paragraph, but preserve open parentheses at beginning of lines.
+Prefix arg means justify as well."
+ (interactive "P")
+ (let ((end (save-excursion (forward-paragraph) (point)))
+ (beg (save-excursion (backward-paragraph)(point)))
+ (paragraph-start (concat paragraph-start "\\|\\s *\\s(")))
+ (fill-region beg end justify)))
+
+(defvar add-log-current-defun-header-regexp
+ "^\\([A-Z][A-Z_ ]*[A-Z_]\\|[-_a-zA-Z]+\\)[ \t]*[:=]"
+ "*Heuristic regexp used by `add-log-current-defun' for unknown major modes.")
+
+;;;###autoload
+(defun add-log-current-defun ()
+ "Return name of function definition point is in, or nil.
+
+Understands C, Lisp, LaTeX (\"functions\" are chapters, sections, ...),
+Texinfo (@node titles), Perl, and Fortran.
+
+Other modes are handled by a heuristic that looks in the 10K before
+point for uppercase headings starting in the first column or
+identifiers followed by `:' or `=', see variable
+`add-log-current-defun-header-regexp'.
+
+Has a preference of looking backwards."
+ (condition-case nil
+ (save-excursion
+ (let ((location (point)))
+ (cond ((memq major-mode '(emacs-lisp-mode lisp-mode scheme-mode
+ lisp-interaction-mode))
+ ;; If we are now precisely at the beginning of a defun,
+ ;; make sure beginning-of-defun finds that one
+ ;; rather than the previous one.
+ (or (eobp) (forward-char 1))
+ (beginning-of-defun)
+ ;; Make sure we are really inside the defun found, not after it.
+ (if (and (looking-at "\\s(")
+ (progn (end-of-defun)
+ (< location (point)))
+ (progn (forward-sexp -1)
+ (>= location (point))))
+ (progn
+ (if (looking-at "\\s(")
+ (forward-char 1))
+ (forward-sexp 1)
+ (skip-chars-forward " '")
+ (buffer-substring (point)
+ (progn (forward-sexp 1) (point))))))
+ ((and (memq major-mode '(c-mode c++-mode c++-c-mode objc-mode))
+ (save-excursion (beginning-of-line)
+ ;; Use eq instead of = here to avoid
+ ;; error when at bob and char-after
+ ;; returns nil.
+ (while (eq (char-after (- (point) 2)) ?\\)
+ (forward-line -1))
+ (looking-at "[ \t]*#[ \t]*define[ \t]")))
+ ;; Handle a C macro definition.
+ (beginning-of-line)
+ (while (eq (char-after (- (point) 2)) ?\\) ;not =; note above
+ (forward-line -1))
+ (search-forward "define")
+ (skip-chars-forward " \t")
+ (buffer-substring (point)
+ (progn (forward-sexp 1) (point))))
+ ((memq major-mode '(c-mode c++-mode c++-c-mode objc-mode))
+ (beginning-of-line)
+ ;; See if we are in the beginning part of a function,
+ ;; before the open brace. If so, advance forward.
+ (while (not (looking-at "{\\|\\(\\s *$\\)"))
+ (forward-line 1))
+ (or (eobp)
+ (forward-char 1))
+ (beginning-of-defun)
+ (if (progn (end-of-defun)
+ (< location (point)))
+ (progn
+ (backward-sexp 1)
+ (let (beg tem)
+
+ (forward-line -1)
+ ;; Skip back over typedefs of arglist.
+ (while (and (not (bobp))
+ (looking-at "[ \t\n]"))
+ (forward-line -1))
+ ;; See if this is using the DEFUN macro used in Emacs,
+ ;; or the DEFUN macro used by the C library.
+ (if (condition-case nil
+ (and (save-excursion
+ (end-of-line)
+ (while (= (preceding-char) ?\\)
+ (end-of-line 2))
+ (backward-sexp 1)
+ (beginning-of-line)
+ (setq tem (point))
+ (looking-at "DEFUN\\b"))
+ (>= location tem))
+ (error nil))
+ (progn
+ (goto-char tem)
+ (down-list 1)
+ (if (= (char-after (point)) ?\")
+ (progn
+ (forward-sexp 1)
+ (skip-chars-forward " ,")))
+ (buffer-substring (point)
+ (progn (forward-sexp 1) (point))))
+ (if (looking-at "^[+-]")
+ (get-method-definition)
+ ;; Ordinary C function syntax.
+ (setq beg (point))
+ (if (and (condition-case nil
+ ;; Protect against "Unbalanced parens" error.
+ (progn
+ (down-list 1) ; into arglist
+ (backward-up-list 1)
+ (skip-chars-backward " \t")
+ t)
+ (error nil))
+ ;; Verify initial pos was after
+ ;; real start of function.
+ (save-excursion
+ (goto-char beg)
+ ;; For this purpose, include the line
+ ;; that has the decl keywords. This
+ ;; may also include some of the
+ ;; comments before the function.
+ (while (and (not (bobp))
+ (save-excursion
+ (forward-line -1)
+ (looking-at "[^\n\f]")))
+ (forward-line -1))
+ (>= location (point)))
+ ;; Consistency check: going down and up
+ ;; shouldn't take us back before BEG.
+ (> (point) beg))
+ (let (end middle)
+ ;; Don't include any final newline
+ ;; in the name we use.
+ (if (= (preceding-char) ?\n)
+ (forward-char -1))
+ (setq end (point))
+ (backward-sexp 1)
+ ;; Now find the right beginning of the name.
+ ;; Include certain keywords if they
+ ;; precede the name.
+ (setq middle (point))
+ (forward-word -1)
+ ;; Ignore these subparts of a class decl
+ ;; and move back to the class name itself.
+ (while (looking-at "public \\|private ")
+ (skip-chars-backward " \t:")
+ (setq end (point))
+ (backward-sexp 1)
+ (setq middle (point))
+ (forward-word -1))
+ (and (bolp)
+ (looking-at "struct \\|union \\|class ")
+ (setq middle (point)))
+ (buffer-substring middle end)))))))))
+ ((memq major-mode
+ '(TeX-mode plain-TeX-mode LaTeX-mode;; tex-mode.el
+ plain-tex-mode latex-mode;; cmutex.el
+ ))
+ (if (re-search-backward
+ "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" nil t)
+ (progn
+ (goto-char (match-beginning 0))
+ (buffer-substring (1+ (point));; without initial backslash
+ (progn
+ (end-of-line)
+ (point))))))
+ ((eq major-mode 'texinfo-mode)
+ (if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t)
+ (buffer-substring (match-beginning 1)
+ (match-end 1))))
+ ((eq major-mode 'perl-mode)
+ (if (re-search-backward "^sub[ \t]+\\([^ \t\n]+\\)" nil t)
+ (buffer-substring (match-beginning 1)
+ (match-end 1))))
+ ((eq major-mode 'fortran-mode)
+ ;; must be inside function body for this to work
+ (beginning-of-fortran-subprogram)
+ (let ((case-fold-search t)) ; case-insensitive
+ ;; search for fortran subprogram start
+ (if (re-search-forward
+ "^[ \t]*\\(program\\|subroutine\\|function\
+\\|[ \ta-z0-9*]*[ \t]+function\\)"
+ nil t)
+ (progn
+ ;; move to EOL or before first left paren
+ (if (re-search-forward "[(\n]" nil t)
+ (progn (forward-char -1)
+ (skip-chars-backward " \t"))
+ (end-of-line))
+ ;; Use the name preceding that.
+ (buffer-substring (point)
+ (progn (forward-sexp -1)
+ (point)))))))
+ (t
+ ;; If all else fails, try heuristics
+ (let (case-fold-search)
+ (end-of-line)
+ (if (re-search-backward add-log-current-defun-header-regexp
+ (- (point) 10000)
+ t)
+ (buffer-substring (match-beginning 1)
+ (match-end 1))))))))
+ (error nil)))
+
+(defvar get-method-definition-md)
+
+;; Subroutine used within get-method-definition.
+;; Add the last match in the buffer to the end of `md',
+;; followed by the string END; move to the end of that match.
+(defun get-method-definition-1 (end)
+ (setq get-method-definition-md
+ (concat get-method-definition-md
+ (buffer-substring (match-beginning 1) (match-end 1))
+ end))
+ (goto-char (match-end 0)))
+
+;; For objective C, return the method name if we are in a method.
+(defun get-method-definition ()
+ (let ((get-method-definition-md "["))
+ (save-excursion
+ (if (re-search-backward "^@implementation\\s-*\\([A-Za-z_]*\\)" nil t)
+ (get-method-definition-1 " ")))
+ (save-excursion
+ (cond
+ ((re-search-forward "^\\([-+]\\)[ \t\n\f\r]*\\(([^)]*)\\)?\\s-*" nil t)
+ (get-method-definition-1 "")
+ (while (not (looking-at "[{;]"))
+ (looking-at
+ "\\([A-Za-z_]*:?\\)\\s-*\\(([^)]*)\\)?[A-Za-z_]*[ \t\n\f\r]*")
+ (get-method-definition-1 ""))
+ (concat get-method-definition-md "]"))))))
+
+
+(provide 'add-log)
+
+;;; add-log.el ends here
diff --git a/etc/add-log.vi b/etc/add-log.vi
new file mode 100644
index 00000000000..efb8c77aa2b
--- /dev/null
+++ b/etc/add-log.vi
@@ -0,0 +1,11 @@
+Here is a vi macro to create entries in the recommended format for
+GDB's ChangeLogs.
+
+map  1GO:r !date '+\%Y-\%m-\%d'2GA Jason Molenda (:r !whoamikJxA@:r !hostnameA)kJxkddjO * k$
+
+It contains control and escape sequences, so don't just cut and paste it.
+You'll need to change the "Jason Molenda" bit, of course. :-) Put this
+in your $HOME/.exrc and when you type control-X in move-around-mode,
+you'll have a changelog template inserted.
+
+--- Jason Molenda
diff --git a/etc/configbuild.ein b/etc/configbuild.ein
new file mode 100644
index 00000000000..7a0e214f2d5
--- /dev/null
+++ b/etc/configbuild.ein
@@ -0,0 +1,149 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: configbuild.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 1
+%%CreationDate: Fri Jun 12 20:13:16 1998
+%%For: ian@tito.cygnus.com (Ian Lance Taylor)
+%%Orientation: Portrait
+%%BoundingBox: 0 0 322 173
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {} def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-62.0 226.0 translate
+1 -1 scale
+
+/clp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 1050 900 m 2100 900 l 2100 1425 l 1050 1425 l clp gs col-1 s gr
+% Polyline
+n 1500 1425 m 1500 2100 l gs col-1 s gr
+n 1530.00 1980.00 m 1500.00 2100.00 l 1470.00 1980.00 l 1500.50 1980.50 l 1530.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 1500 2625 m 1500 3300 l gs col-1 s gr
+n 1530.00 3180.00 m 1500.00 3300.00 l 1470.00 3180.00 l 1500.50 3180.50 l 1530.00 3180.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 2925 900 m 3825 900 l 3825 1425 l 2925 1425 l clp gs col-1 s gr
+% Polyline
+n 1155 2100 m 1050 2100 1050 2520 105 arcto 4 {pop} repeat 1050 2625 2220 2625 105 arcto 4 {pop} repeat 2325 2625 2325 2205 105 arcto 4 {pop} repeat 2325 2100 1155 2100 105 arcto 4 {pop} repeat clp gs col-1 s gr
+% Polyline
+n 2850 2100 m 4125 2100 l 4125 2625 l 2850 2625 l clp gs col-1 s gr
+% Polyline
+n 3375 1425 m 3375 2100 l gs col-1 s gr
+n 3405.00 1980.00 m 3375.00 2100.00 l 3345.00 1980.00 l 3375.50 1980.50 l 3405.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 5100 900 m 6300 900 l 6300 1350 l 5100 1350 l clp gs col-1 s gr
+% Polyline
+n 5625 1350 m 5625 2100 l gs col-1 s gr
+n 5655.00 1980.00 m 5625.00 2100.00 l 5595.00 1980.00 l 5625.50 1980.50 l 5655.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 5205 2100 m 5100 2100 5100 2520 105 arcto 4 {pop} repeat 5100 2625 6270 2625 105 arcto 4 {pop} repeat 6375 2625 6375 2205 105 arcto 4 {pop} repeat 6375 2100 5205 2100 105 arcto 4 {pop} repeat clp gs col-1 s gr
+% Polyline
+n 5625 2625 m 5625 3300 l gs col-1 s gr
+n 5655.00 3180.00 m 5625.00 3300.00 l 5595.00 3180.00 l 5625.50 3180.50 l 5655.00 3180.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 5100 3300 m 6225 3300 l 6225 3750 l 5100 3750 l clp gs col-1 s gr
+% Polyline
+ [1 50.0] 50.000000 setdash
+n 2850 2400 m 2325 2400 l gs col-1 s gr [] 0 setdash
+n 2445.00 2430.00 m 2325.00 2400.00 l 2445.00 2370.00 l 2445.50 2400.50 l 2445.00 2430.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+ [1 50.0] 50.000000 setdash
+n 4125 2400 m 5100 2400 l gs col-1 s gr [] 0 setdash
+n 4980.00 2370.00 m 5100.00 2400.00 l 4980.00 2430.00 l 4980.50 2400.50 l 4980.00 2370.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 1050 3300 m 1950 3300 l 1950 3750 l 1050 3750 l clp gs col-1 s gr
+/Times-Roman findfont 180.00 scalefont setfont
+1200 1200 m
+gs 1 -1 sc (config.in) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3000 1200 m
+gs 1 -1 sc (configure) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3000 2400 m
+gs 1 -1 sc (config.status) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+1200 2400 m
+gs 1 -1 sc (config.status) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+1200 3600 m
+gs 1 -1 sc (config.h) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+5250 1200 m
+gs 1 -1 sc (Makefile.in) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+5250 2400 m
+gs 1 -1 sc (config.status) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+5250 3600 m
+gs 1 -1 sc (Makefile) col-1 show gr
+$F2psEnd
+restore
diff --git a/etc/configbuild.fig b/etc/configbuild.fig
new file mode 100644
index 00000000000..747592d3d62
--- /dev/null
+++ b/etc/configbuild.fig
@@ -0,0 +1,50 @@
+#FIG 3.1
+Portrait
+Center
+Inches
+1200 2
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 1050 900 2100 900 2100 1425 1050 1425 1050 900
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1500 1425 1500 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1500 2625 1500 3300
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 2925 900 3825 900 3825 1425 2925 1425 2925 900
+2 4 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5
+ 2325 2625 2325 2100 1050 2100 1050 2625 2325 2625
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 2850 2100 4125 2100 4125 2625 2850 2625 2850 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3375 1425 3375 2100
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 5100 900 6300 900 6300 1350 5100 1350 5100 900
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5625 1350 5625 2100
+2 4 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5
+ 6375 2625 6375 2100 5100 2100 5100 2625 6375 2625
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5625 2625 5625 3300
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 5100 3300 6225 3300 6225 3750 5100 3750 5100 3300
+2 1 2 1 -1 7 0 0 -1 3.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2850 2400 2325 2400
+2 1 2 1 -1 7 0 0 -1 3.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4125 2400 5100 2400
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 1050 3300 1950 3300 1950 3750 1050 3750 1050 3300
+4 0 -1 0 0 0 12 0.0000000 4 180 645 1200 1200 config.in\001
+4 0 -1 0 0 0 12 0.0000000 4 180 705 3000 1200 configure\001
+4 0 -1 0 0 0 12 0.0000000 4 180 990 3000 2400 config.status\001
+4 0 -1 0 0 0 12 0.0000000 4 180 990 1200 2400 config.status\001
+4 0 -1 0 0 0 12 0.0000000 4 180 600 1200 3600 config.h\001
+4 0 -1 0 0 0 12 0.0000000 4 135 855 5250 1200 Makefile.in\001
+4 0 -1 0 0 0 12 0.0000000 4 180 990 5250 2400 config.status\001
+4 0 -1 0 0 0 12 0.0000000 4 135 675 5250 3600 Makefile\001
diff --git a/etc/configbuild.jin b/etc/configbuild.jin
new file mode 100644
index 00000000000..44cd9397aa1
--- /dev/null
+++ b/etc/configbuild.jin
Binary files differ
diff --git a/etc/configbuild.tin b/etc/configbuild.tin
new file mode 100644
index 00000000000..cfdd6fe0743
--- /dev/null
+++ b/etc/configbuild.tin
@@ -0,0 +1,9 @@
+ config.in *configure* Makefile.in
+ | | |
+ | v |
+ | config.status |
+ | | |
+ *config.status*<======+==========>*config.status*
+ | |
+ v v
+ config.h Makefile
diff --git a/etc/configdev.ein b/etc/configdev.ein
new file mode 100644
index 00000000000..7f837850d69
--- /dev/null
+++ b/etc/configdev.ein
@@ -0,0 +1,185 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: configdev.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 1
+%%CreationDate: Mon Jun 15 17:35:19 1998
+%%For: ian@tito.cygnus.com (Ian Lance Taylor)
+%%Orientation: Portrait
+%%BoundingBox: 0 0 344 317
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {} def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-62.0 370.0 translate
+1 -1 scale
+
+/clp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 1050 900 m 2100 900 l 2100 1425 l 1050 1425 l clp gs col-1 s gr
+% Polyline
+n 2925 900 m 3975 900 l 3975 1425 l 2925 1425 l clp gs col-1 s gr
+% Polyline
+n 5550 900 m 6750 900 l 6750 1350 l 5550 1350 l clp gs col-1 s gr
+% Polyline
+n 3750 1800 m 5025 1800 l 5025 2250 l 3750 2250 l clp gs col-1 s gr
+% Polyline
+n 1155 2100 m 1050 2100 1050 2520 105 arcto 4 {pop} repeat 1050 2625 2070 2625 105 arcto 4 {pop} repeat 2175 2625 2175 2205 105 arcto 4 {pop} repeat 2175 2100 1155 2100 105 arcto 4 {pop} repeat clp gs col-1 s gr
+% Polyline
+n 5550 3300 m 6675 3300 l 6675 3750 l 5550 3750 l clp gs col-1 s gr
+% Polyline
+n 5655 2100 m 5550 2100 5550 2520 105 arcto 4 {pop} repeat 5550 2625 6495 2625 105 arcto 4 {pop} repeat 6600 2625 6600 2205 105 arcto 4 {pop} repeat 6600 2100 5655 2100 105 arcto 4 {pop} repeat clp gs col-1 s gr
+% Polyline
+n 3750 3600 m 4875 3600 l 4875 4050 l 3750 4050 l clp gs col-1 s gr
+% Polyline
+n 3855 2700 m 3750 2700 3750 3045 105 arcto 4 {pop} repeat 3750 3150 4545 3150 105 arcto 4 {pop} repeat 4650 3150 4650 2805 105 arcto 4 {pop} repeat 4650 2700 3855 2700 105 arcto 4 {pop} repeat clp gs col-1 s gr
+% Polyline
+n 2850 5700 m 3750 5700 l 3750 6150 l 2850 6150 l clp gs col-1 s gr
+% Polyline
+n 3030 4800 m 2925 4800 2925 5145 105 arcto 4 {pop} repeat 2925 5250 3645 5250 105 arcto 4 {pop} repeat 3750 5250 3750 4905 105 arcto 4 {pop} repeat 3750 4800 3030 4800 105 arcto 4 {pop} repeat clp gs col-1 s gr
+% Polyline
+n 1500 1425 m 1500 2100 l gs col-1 s gr
+n 1530.00 1980.00 m 1500.00 2100.00 l 1470.00 1980.00 l 1500.50 1980.50 l 1530.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 3300 1425 m 3300 4800 l gs col-1 s gr
+n 3330.00 4680.00 m 3300.00 4800.00 l 3270.00 4680.00 l 3300.50 4680.50 l 3330.00 4680.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 3300 1575 m 1875 1575 l 1875 2100 l gs col-1 s gr
+n 1905.00 1980.00 m 1875.00 2100.00 l 1845.00 1980.00 l 1875.50 1980.50 l 1905.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 3300 1575 m 5700 1575 l 5700 2100 l gs col-1 s gr
+n 5730.00 1980.00 m 5700.00 2100.00 l 5670.00 1980.00 l 5700.50 1980.50 l 5730.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 6225 1350 m 6225 2100 l gs col-1 s gr
+n 6255.00 1980.00 m 6225.00 2100.00 l 6195.00 1980.00 l 6225.50 1980.50 l 6255.00 1980.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 6075 2625 m 6075 3300 l gs col-1 s gr
+n 6105.00 3180.00 m 6075.00 3300.00 l 6045.00 3180.00 l 6075.50 3180.50 l 6105.00 3180.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 4200 2250 m 4200 2700 l gs col-1 s gr
+n 4230.00 2580.00 m 4200.00 2700.00 l 4170.00 2580.00 l 4200.50 2580.50 l 4230.00 2580.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 4200 3150 m 4200 3600 l gs col-1 s gr
+n 4230.00 3480.00 m 4200.00 3600.00 l 4170.00 3480.00 l 4200.50 3480.50 l 4230.00 3480.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 4200 4050 m 4200 4500 l 3675 4500 l 3675 4800 l gs col-1 s gr
+n 3705.00 4680.00 m 3675.00 4800.00 l 3645.00 4680.00 l 3675.50 4680.50 l 3705.00 4680.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 3375 5250 m 3375 5700 l gs col-1 s gr
+n 3405.00 5580.00 m 3375.00 5700.00 l 3345.00 5580.00 l 3375.50 5580.50 l 3405.00 5580.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 3300 2925 m 3750 2925 l gs col-1 s gr
+n 3630.00 2895.00 m 3750.00 2925.00 l 3630.00 2955.00 l 3630.50 2925.50 l 3630.00 2895.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 1500 2625 m 1500 3300 l gs col-1 s gr
+n 1530.00 3180.00 m 1500.00 3300.00 l 1470.00 3180.00 l 1500.50 3180.50 l 1530.00 3180.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+% Polyline
+n 1050 3300 m 2100 3300 l 2100 3750 l 1050 3750 l clp gs col-1 s gr
+% Polyline
+n 4875 3825 m 5250 3825 l 5250 2400 l 5550 2400 l gs col-1 s gr
+n 5430.00 2370.00 m 5550.00 2400.00 l 5430.00 2430.00 l 5430.50 2400.50 l 5430.00 2370.00 l clp gs 0.00 setgray ef gr gs col-1 s gr
+/Times-Roman findfont 180.00 scalefont setfont
+1200 1200 m
+gs 1 -1 sc (acconfig.h) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3000 1200 m
+gs 1 -1 sc (configure.in) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+5700 1200 m
+gs 1 -1 sc (Makefile.am) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3900 2100 m
+gs 1 -1 sc (acinclude.m4) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+1200 2400 m
+gs 1 -1 sc (autoheader) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+1200 3600 m
+gs 1 -1 sc (config.in) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+5700 3600 m
+gs 1 -1 sc (Makefile.in) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+5700 2400 m
+gs 1 -1 sc (automake) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3900 3900 m
+gs 1 -1 sc (aclocal.m4) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3900 3000 m
+gs 1 -1 sc (aclocal) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3000 6000 m
+gs 1 -1 sc (configure) col-1 show gr
+/Times-Roman findfont 180.00 scalefont setfont
+3000 5100 m
+gs 1 -1 sc (autoconf) col-1 show gr
+$F2psEnd
+restore
diff --git a/etc/configdev.fig b/etc/configdev.fig
new file mode 100644
index 00000000000..4d386ec4ff7
--- /dev/null
+++ b/etc/configdev.fig
@@ -0,0 +1,80 @@
+#FIG 3.1
+Portrait
+Center
+Inches
+1200 2
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 1050 900 2100 900 2100 1425 1050 1425 1050 900
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 2925 900 3975 900 3975 1425 2925 1425 2925 900
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 5550 900 6750 900 6750 1350 5550 1350 5550 900
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 3750 1800 5025 1800 5025 2250 3750 2250 3750 1800
+2 4 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5
+ 2175 2625 2175 2100 1050 2100 1050 2625 2175 2625
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 5550 3300 6675 3300 6675 3750 5550 3750 5550 3300
+2 4 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5
+ 6600 2625 6600 2100 5550 2100 5550 2625 6600 2625
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 3750 3600 4875 3600 4875 4050 3750 4050 3750 3600
+2 4 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5
+ 4650 3150 4650 2700 3750 2700 3750 3150 4650 3150
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 2850 5700 3750 5700 3750 6150 2850 6150 2850 5700
+2 4 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5
+ 3750 5250 3750 4800 2925 4800 2925 5250 3750 5250
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1500 1425 1500 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3300 1425 3300 4800
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 3300 1575 1875 1575 1875 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 3
+ 1 1 1.00 60.00 120.00
+ 3300 1575 5700 1575 5700 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6225 1350 6225 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6075 2625 6075 3300
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4200 2250 4200 2700
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4200 3150 4200 3600
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 4200 4050 4200 4500 3675 4500 3675 4800
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3375 5250 3375 5700
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3300 2925 3750 2925
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1500 2625 1500 3300
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5
+ 1050 3300 2100 3300 2100 3750 1050 3750 1050 3300
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 4875 3825 5250 3825 5250 2400 5550 2400
+4 0 -1 0 0 0 12 0.0000000 4 180 780 1200 1200 acconfig.h\001
+4 0 -1 0 0 0 12 0.0000000 4 180 885 3000 1200 configure.in\001
+4 0 -1 0 0 0 12 0.0000000 4 135 945 5700 1200 Makefile.am\001
+4 0 -1 0 0 0 12 0.0000000 4 135 990 3900 2100 acinclude.m4\001
+4 0 -1 0 0 0 12 0.0000000 4 135 840 1200 2400 autoheader\001
+4 0 -1 0 0 0 12 0.0000000 4 180 645 1200 3600 config.in\001
+4 0 -1 0 0 0 12 0.0000000 4 135 855 5700 3600 Makefile.in\001
+4 0 -1 0 0 0 12 0.0000000 4 135 735 5700 2400 automake\001
+4 0 -1 0 0 0 12 0.0000000 4 135 810 3900 3900 aclocal.m4\001
+4 0 -1 0 0 0 12 0.0000000 4 135 540 3900 3000 aclocal\001
+4 0 -1 0 0 0 12 0.0000000 4 180 705 3000 6000 configure\001
+4 0 -1 0 0 0 12 0.0000000 4 135 660 3000 5100 autoconf\001
diff --git a/etc/configdev.jin b/etc/configdev.jin
new file mode 100644
index 00000000000..9b11a71acd7
--- /dev/null
+++ b/etc/configdev.jin
Binary files differ
diff --git a/etc/configdev.tin b/etc/configdev.tin
new file mode 100644
index 00000000000..c9b6f34f4d7
--- /dev/null
+++ b/etc/configdev.tin
@@ -0,0 +1,17 @@
+ acconfig.h configure.in Makefile.am
+ | | |
+ | --------------+---------------------- |
+ | | | | |
+ v v | acinclude.m4 | |
+ *autoheader* | | v v
+ | | v --->*automake*
+ v |--->*aclocal* | |
+ config.in | | | v
+ | v | Makefile.in
+ | aclocal.m4---
+ | |
+ v v
+ *autoconf*
+ |
+ v
+ configure
diff --git a/etc/configure b/etc/configure
new file mode 100755
index 00000000000..101fcefecfc
--- /dev/null
+++ b/etc/configure
@@ -0,0 +1,862 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=Makefile.in
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:555: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/etc/configure.in b/etc/configure.in
new file mode 100644
index 00000000000..b785068009e
--- /dev/null
+++ b/etc/configure.in
@@ -0,0 +1,7 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.5)
+AC_INIT(Makefile.in)
+
+AC_PROG_INSTALL
+
+AC_OUTPUT(Makefile)
diff --git a/etc/configure.texi b/etc/configure.texi
new file mode 100644
index 00000000000..91401671f92
--- /dev/null
+++ b/etc/configure.texi
@@ -0,0 +1,2644 @@
+\input texinfo
+@c %**start of header
+@setfilename configure.info
+@settitle The GNU configure and build system
+@setchapternewpage off
+@c %**end of header
+
+@dircategory GNU admin
+@direntry
+* configure: (configure). The GNU configure and build system
+@end direntry
+
+@ifinfo
+This file documents the GNU configure and build system.
+
+Copyright (C) 1998 Cygnus Solutions.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@titlepage
+@title The GNU configure and build system
+@author Ian Lance Taylor
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1998 Cygnus Solutions
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by the Free Software Foundation.
+@end titlepage
+
+@ifinfo
+@node Top
+@top GNU configure and build system
+
+The GNU configure and build system.
+
+@menu
+* Introduction:: Introduction.
+* Getting Started:: Getting Started.
+* Files:: Files.
+* Configuration Names:: Configuration Names.
+* Cross Compilation Tools:: Cross Compilation Tools.
+* Canadian Cross:: Canadian Cross.
+* Cygnus Configure:: Cygnus Configure.
+* Multilibs:: Multilibs.
+* FAQ:: Frequently Asked Questions.
+* Index:: Index.
+@end menu
+
+@end ifinfo
+
+@node Introduction
+@chapter Introduction
+
+This document describes the GNU configure and build systems. It
+describes how autoconf, automake, libtool, and make fit together. It
+also includes a discussion of the older Cygnus configure system.
+
+This document does not describe in detail how to use each of the tools;
+see the respective manuals for that. Instead, it describes which files
+the developer must write, which files are machine generated and how they
+are generated, and where certain common problems should be addressed.
+
+@ifnothtml
+This document draws on several sources, including the autoconf manual by
+David MacKenzie (@pxref{Top, , autoconf overview, autoconf, Autoconf}),
+the automake manual by David MacKenzie and Tom Tromey (@pxref{Top, ,
+automake overview, automake, GNU Automake}), the libtool manual by
+Gordon Matzigkeit (@pxref{Top, , libtool overview, libtool, GNU
+libtool}), and the Cygnus configure manual by K. Richard Pixley.
+@end ifnothtml
+@ifhtml
+This document draws on several sources, including
+@uref{http://www.delorie.com/gnu/docs/autoconf/autoconf_toc.html, the
+autoconf manual} by David MacKenzie,
+@uref{http://www.delorie.com/gnu/docs/automake/automake_toc.html, the
+automake manual} by David MacKenzie and Tom Tromey,
+@uref{http://www.delorie.com/gnu/docs/libtool/libtool_toc.html, the
+libtool manual} by Gordon Matzigkeit, and the Cygnus configure manual by
+K. Richard Pixley.
+@end ifhtml
+
+@menu
+* Goals:: Goals.
+* Tools:: The tools.
+* History:: History.
+* Building:: Building.
+@end menu
+
+@node Goals
+@section Goals
+@cindex goals
+
+The GNU configure and build system has two main goals.
+
+The first is to simplify the development of portable programs. The
+system permits the developer to concentrate on writing the program,
+simplifying many details of portability across Unix and even Windows
+systems, and permitting the developer to describe how to build the
+program using simple rules rather than complex Makefiles.
+
+The second is to simplify the building of programs distributed as source
+code. All programs are built using a simple, standardized, two step
+process. The program builder need not install any special tools in
+order to build the program.
+
+@node Tools
+@section Tools
+
+The GNU configure and build system is comprised of several different
+tools. Program developers must build and install all of these tools.
+
+People who just want to build programs from distributed sources normally
+do not need any special tools beyond a Unix shell, a make program, and a
+C compiler.
+
+@table @asis
+@item autoconf
+provides a general portability framework, based on testing the features
+of the host system at build time.
+@item automake
+a system for describing how to build a program, permitting the developer
+to write a simplified @file{Makefile}.
+@item libtool
+a standardized approach to building shared libraries.
+@item gettext
+provides a framework for translation of text messages into other
+languages; not really discussed in this document.
+@item m4
+autoconf requires the GNU version of m4; the standard Unix m4 does not
+suffice.
+@item perl
+automake requires perl.
+@end table
+
+@node History
+@section History
+@cindex history
+
+This is a very brief and probably inaccurate history.
+
+As the number of Unix variants increased during the 1980s, it became
+harder to write programs which could run on all variants. While it was
+often possible to use @code{#ifdef} to identify particular systems,
+developers frequently did not have access to every system, and the
+characteristics of some systems changed from version to version.
+
+By 1992, at least three different approaches had been developed:
+@itemize @bullet
+@item
+The Metaconfig program, by Larry Wall, Harlan Stenn, and Raphael
+Manfredi.
+@item
+The Cygnus configure script, by K. Richard Pixley, and the gcc configure
+script, by Richard Stallman. These use essentially the same approach,
+and the developers communicated regularly.
+@item
+The autoconf program, by David MacKenzie.
+@end itemize
+
+The Metaconfig program is still used for Perl and a few other programs.
+It is part of the Dist package. I do not know if it is being developed.
+
+In 1994, David MacKenzie and others modified autoconf to incorporate all
+the features of Cygnus configure. Since then, there has been a slow but
+steady conversion of GNU programs from Cygnus configure to autoconf. gcc
+has been converted, eliminating the gcc configure script.
+
+GNU autoconf was regularly maintained until late 1996. As of this
+writing in June, 1998, it has no public maintainer.
+
+Most programs are built using the make program, which requires the
+developer to write Makefiles describing how to build the programs.
+Since most programs are built in pretty much the same way, this led to a
+lot of duplication.
+
+The X Window system is built using the imake tool, which uses a database
+of rules to eliminate the duplication. However, building a tool which
+was developed using imake requires that the builder have imake
+installed, violating one of the goals of the GNU system.
+
+The new BSD make provides a standard library of Makefile fragments,
+which permits developers to write very simple Makefiles. However, this
+requires that the builder install the new BSD make program.
+
+In 1994, David MacKenzie wrote the first version of automake, which
+permitted writing a simple build description which was converted into a
+Makefile which could be used by the standard make program. In 1995, Tom
+Tromey completely rewrote automake in Perl, and he continues to enhance
+it.
+
+Various free packages built libraries, and by around 1995 several
+included support to build shared libraries on various platforms.
+However, there was no consistent approach. In early 1996, Gordon
+Matzigkeit began working on libtool, which provided a standardized
+approach to building shared libraries. This was integrated into
+automake from the start.
+
+The development of automake and libtool was driven by the GNITS project,
+a group of GNU maintainers who designed standardized tools to help meet
+the GNU coding standards.
+
+@node Building
+@section Building
+
+Most readers of this document should already know how to build a tool by
+running @samp{configure} and @samp{make}. This section may serve as a
+quick introduction or reminder.
+
+Building a tool is normally as simple as running @samp{configure}
+followed by @samp{make}. You should normally run @samp{configure} from
+an empty directory, using some path to refer to the @samp{configure}
+script in the source directory. The directory in which you run
+@samp{configure} is called the @dfn{object directory}.
+
+In order to use a object directory which is different from the source
+directory, you must be using the GNU version of @samp{make}, which has
+the required @samp{VPATH} support. Despite this restriction, using a
+different object directory is highly recommended:
+@itemize @bullet
+@item
+It keeps the files generated during the build from cluttering up your
+sources.
+@item
+It permits you to remove the built files by simply removing the entire
+build directory.
+@item
+It permits you to build from the same sources with several sets of
+configure options simultaneously.
+@end itemize
+
+If you don't have GNU @samp{make}, you will have to run @samp{configure}
+in the source directory. All GNU packages should support this; in
+particular, GNU packages should not assume the presence of GNU
+@samp{make}.
+
+After running @samp{configure}, you can build the tools by running
+@samp{make}.
+
+To install the tools, run @samp{make install}. Installing the tools
+will copy the programs and any required support files to the
+@dfn{installation directory}. The location of the installation
+directory is controlled by @samp{configure} options, as described below.
+
+In the Cygnus tree at present, the info files are built and installed as
+a separate step. To build them, run @samp{make info}. To install them,
+run @samp{make install-info}.
+
+All @samp{configure} scripts support a wide variety of options. The
+most interesting ones are @samp{--with} and @samp{--enable} options
+which are generally specific to particular tools. You can usually use
+the @samp{--help} option to get a list of interesting options for a
+particular configure script.
+
+The only generic options you are likely to use are the @samp{--prefix}
+and @samp{--exec-prefix} options. These options are used to specify the
+installation directory.
+
+The directory named by the @samp{--prefix} option will hold machine
+independent files such as info files.
+
+The directory named by the @samp{--exec-prefix} option, which is
+normally a subdirectory of the @samp{--prefix} directory, will hold
+machine dependent files such as executables.
+
+The default for @samp{--prefix} is @file{/usr/local}. The default for
+@samp{--exec-prefix} is the value used for @samp{--prefix}.
+
+The convention used in Cygnus releases is to use a @samp{--prefix}
+option of @file{/usr/cygnus/@var{release}}, where @var{release} is the
+name of the release, and to use a @samp{--exec-prefix} option of
+@file{/usr/cygnus/@var{release}/H-@var{host}}, where @var{host} is the
+configuration name of the host system (@pxref{Configuration Names}).
+
+Do not use either the source or the object directory as the installation
+directory. That will just lead to confusion.
+
+@node Getting Started
+@chapter Getting Started
+
+To start using the GNU configure and build system with your software
+package, you must write three files, and you must run some tools to
+manually generate additional files.
+
+@menu
+* Write configure.in:: Write configure.in.
+* Write Makefile.am:: Write Makefile.am.
+* Write acconfig.h:: Write acconfig.h.
+* Generate files:: Generate files.
+* Getting Started Example:: Example.
+@end menu
+
+@node Write configure.in
+@section Write configure.in
+@cindex @file{configure.in}, writing
+
+You must first write the file @file{configure.in}. This is an autoconf
+input file, and the autoconf manual describes in detail what this file
+should look like.
+
+You will write tests in your @file{configure.in} file to check for
+conditions that may change from one system to another, such as the
+presence of particular header files or functions.
+
+For example, not all systems support the @samp{gettimeofday} function.
+If you want to use the @samp{gettimeofday} function when it is
+available, and to use some other function when it is not, you would
+check for this by putting @samp{AC_CHECK_FUNCS(gettimeofday)} in
+@file{configure.in}.
+
+When the configure script is run at build time, this will arrange to
+define the preprocessor macro @samp{HAVE_GETTIMEOFDAY} to the value 1 if
+the @samp{gettimeofday} function is available, and to not define the
+macro at all if the function is not available. Your code can then use
+@samp{#ifdef} to test whether it is safe to call @samp{gettimeofday}.
+
+If you have an existing body of code, the @samp{autoscan} program may
+help identify potential portability problems, and hence configure tests
+that you will want to use.
+@ifnothtml
+@xref{Invoking autoscan, , , autoconf, the autoconf manual}.
+@end ifnothtml
+@ifhtml
+See @uref{http://www.delorie.com/gnu/docs/autoconf/autoconf_4.html, the
+autoscan documentation}.
+@end ifhtml
+
+Another handy tool for an existing body of code is @samp{ifnames}. This
+will show you all the preprocessor conditionals that the code already
+uses.
+@ifnothtml
+@xref{Invoking ifnames, , , autoconf, the autoconf manual}.
+@end ifnothtml
+@ifhtml
+See @uref{http://www.delorie.com/gnu/docs/autoconf/autoconf_5.html, the
+ifnames documentation}.
+@end ifhtml
+
+Besides the portability tests which are specific to your particular
+package, every @file{configure.in} file should contain the following
+macros.
+
+@table @samp
+@item AC_INIT
+@cindex @samp{AC_INIT}
+This macro takes a single argument, which is the name of a file in your
+package. For example, @samp{AC_INIT(foo.c)}.
+
+@item AC_PREREQ(@var{VERSION})
+@cindex @samp{AC_PREREQ}
+This macro is optional. It may be used to indicate the version of
+@samp{autoconf} that you are using. This will prevent users from
+running an earlier version of @samp{autoconf} and perhaps getting an
+invalid @file{configure} script. For example, @samp{AC_PREREQ(2.12)}.
+
+@item AM_INIT_AUTOMAKE
+@cindex @samp{AM_INIT_AUTOMAKE}
+This macro takes two arguments: the name of the package, and a version
+number. For example, @samp{AM_INIT_AUTOMAKE(foo, 1.0)}. (This macro is
+not needed if you are not using automake).
+
+@item AM_CONFIG_HEADER
+@cindex @samp{AM_CONFIG_HEADER}
+This macro names the header file which will hold the preprocessor macro
+definitions at run time. Normally this should be @file{config.h}. Your
+sources would then use @samp{#include "config.h"} to include it.
+
+This macro may optionally name the input file for that header file; by
+default, this is @file{config.h.in}, but that file name works poorly on
+DOS filesystems. Therefore, it is often better to name it explicitly as
+@file{config.in}.
+
+This is what you should normally put in @file{configure.in}:
+@example
+AM_CONFIG_HEADER(config.h:config.in)
+@end example
+
+@cindex @samp{AC_CONFIG_HEADER}
+(If you are not using automake, use @samp{AC_CONFIG_HEADER} rather than
+@samp{AM_CONFIG_HEADER}).
+
+@item AM_MAINTAINER_MODE
+@cindex @samp{AM_MAINTAINER_MODE}
+This macro always appears in Cygnus configure scripts. Other programs
+may or may not use it.
+
+If this macro is used, the @samp{--enable-maintainer-mode} option is
+required to enable automatic rebuilding of generated files used by the
+configure system. This of course requires that developers be aware of,
+and use, that option.
+
+If this macro is not used, then the generated files will always be
+rebuilt automatically. This will cause problems if the wrong versions
+of autoconf, automake, or others are in the builder's @samp{PATH}.
+
+(If you are not using automake, you do not need to use this macro).
+
+@item AC_EXEEXT
+@cindex @samp{AC_EXEEXT}
+@cindex @samp{AM_EXEEXT}
+Either this macro or @samp{AM_EXEEXT} always appears in Cygnus configure
+files. Other programs may or may not use one of them.
+
+This macro looks for the executable suffix used on the host system. On
+Unix systems, this is the empty string. On Windows systems, this is
+@samp{.exe}. This macro directs automake to use the executable suffix
+as appropriate when creating programs. This macro does not take any
+arguments.
+
+The @samp{AC_EXEEXT} form is new, and is part of a Cygnus patch to
+autoconf to support compiling with Visual C++. Older programs use
+@samp{AM_EXEEXT} instead.
+
+(Programs which do not use automake use neither @samp{AC_EXEEXT} nor
+@samp{AM_EXEEXT}).
+
+@item AC_PROG_CC
+@cindex @samp{AC_PROG_CC}
+If you are writing C code, you will normally want to use this macro. It
+locates the C compiler to use. It does not take any arguments.
+
+However, if this @file{configure.in} file is for a library which is to
+be compiled by a cross compiler which may not fully work, then you will
+not want to use @samp{AC_PROG_CC}. Instead, you will want to use a
+variant which does not call the macro @samp{AC_PROG_CC_WORKS}. Examples
+can be found in various @file{configure.in} files for libraries that are
+compiled with cross compilers, such as libiberty or libgloss. This is
+essentially a bug in autoconf, and there will probably be a better
+workaround at some point.
+
+@item AC_PROG_CXX
+@cindex @samp{AC_PROG_CXX}
+If you are writing C++ code, you will want to use this macro. It
+locates the C++ compiler to use. It does not take any arguments. The
+same cross compiler comments apply as for @samp{AC_PROG_CC}.
+
+@item AM_PROG_LIBTOOL
+@cindex @samp{AM_PROG_LIBTOOL}
+If you want to build libraries, and you want to permit them to be
+shared, or you want to link against libraries which were built using
+libtool, then you will need this macro. This macro is required in order
+to use libtool.
+
+@cindex @samp{AM_DISABLE_SHARED}
+By default, this will cause all libraries to be built as shared
+libraries. To prevent this--to change the default--use
+@samp{AM_DISABLE_SHARED} before @samp{AM_PROG_LIBTOOL}. The configure
+options @samp{--enable-shared} and @samp{--disable-shared} may be used
+to override the default at build time.
+
+@item AC_DEFINE(_GNU_SOURCE)
+@cindex @samp{_GNU_SOURCE}
+GNU packages should normally include this line before any other feature
+tests. This defines the macro @samp{_GNU_SOURCE} when compiling, which
+directs the libc header files to provide the standard GNU system
+interfaces including all GNU extensions. If this macro is not defined,
+certain GNU extensions may not be available.
+
+@item AC_OUTPUT
+@cindex @samp{AC_OUTPUT}
+This macro takes a list of file names which the configure process should
+produce. This is normally a list of one or more @file{Makefile} files
+in different directories. If your package lives entirely in a single
+directory, you would use simply @samp{AC_OUTPUT(Makefile)}. If you also
+have, for example, a @file{lib} subdirectory, you would use
+@samp{AC_OUTPUT(Makefile lib/Makefile)}.
+@end table
+
+If you want to use locally defined macros in your @file{configure.in}
+file, then you will need to write a @file{acinclude.m4} file which
+defines them (if not using automake, this file is called
+@file{aclocal.m4}). Alternatively, you can put separate macros in an
+@file{m4} subdirectory, and put @samp{ACLOCAL_AMFLAGS = -I m4} in your
+@file{Makefile.am} file so that the @samp{aclocal} program will be able
+to find them.
+
+The different macro prefixes indicate which tool defines the macro.
+Macros which start with @samp{AC_} are part of autoconf. Macros which
+start with @samp{AM_} are provided by automake or libtool.
+
+@node Write Makefile.am
+@section Write Makefile.am
+@cindex @file{Makefile.am}, writing
+
+You must write the file @file{Makefile.am}. This is an automake input
+file, and the automake manual describes in detail what this file should
+look like.
+
+The automake commands in @file{Makefile.am} mostly look like variable
+assignments in a @file{Makefile}. automake recognizes special variable
+names, and automatically add make rules to the output as needed.
+
+There will be one @file{Makefile.am} file for each directory in your
+package. For each directory with subdirectories, the @file{Makefile.am}
+file should contain the line
+@smallexample
+SUBDIRS = @var{dir} @var{dir} @dots{}
+@end smallexample
+@noindent
+where each @var{dir} is the name of a subdirectory.
+
+For each @file{Makefile.am}, there should be a corresponding
+@file{Makefile} in the @samp{AC_OUTPUT} macro in @file{configure.in}.
+
+Every @file{Makefile.am} written at Cygnus should contain the line
+@smallexample
+AUTOMAKE_OPTIONS = cygnus
+@end smallexample
+@noindent
+This puts automake into Cygnus mode. See the automake manual for
+details.
+
+You may to include the version number of @samp{automake} that you are
+using on the @samp{AUTOMAKE_OPTIONS} line. For example,
+@smallexample
+AUTOMAKE_OPTIONS = cygnus 1.3
+@end smallexample
+@noindent
+This will prevent users from running an earlier version of
+@samp{automake} and perhaps getting an invalid @file{Makefile.in}.
+
+If your package builds a program, then in the directory where that
+program is built you will normally want a line like
+@smallexample
+bin_PROGRAMS = @var{program}
+@end smallexample
+@noindent
+where @var{program} is the name of the program. You will then want a
+line like
+@smallexample
+@var{program}_SOURCES = @var{file} @var{file} @dots{}
+@end smallexample
+@noindent
+where each @var{file} is the name of a source file to link into the
+program (e.g., @samp{foo.c}).
+
+If your package builds a library, and you do not want the library to
+ever be built as a shared library, then in the directory where that
+library is built you will normally want a line like
+@smallexample
+lib_LIBRARIES = lib@var{name}.a
+@end smallexample
+@noindent
+where @samp{lib@var{name}.a} is the name of the library. You will then
+want a line like
+@smallexample
+lib@var{name}_a_SOURCES = @var{file} @var{file} @dots{}
+@end smallexample
+@noindent
+where each @var{file} is the name of a source file to add to the
+library.
+
+If your package builds a library, and you want to permit building the
+library as a shared library, then in the directory where that library is
+built you will normally want a line like
+@smallexample
+lib_LTLIBRARIES = lib@var{name}.la
+@end smallexample
+The use of @samp{LTLIBRARIES}, and the @samp{.la} extension, indicate a
+library to be built using libtool. As usual, you will then want a line
+like
+@smallexample
+lib@var{name}_la_SOURCES = @var{file} @var{file} @dots{}
+@end smallexample
+
+The strings @samp{bin} and @samp{lib} that appear above in
+@samp{bin_PROGRAMS} and @samp{lib_LIBRARIES} are not arbitrary. They
+refer to particular directories, which may be set by the @samp{--bindir}
+and @samp{--libdir} options to @file{configure}. If those options are
+not used, the default values are based on the @samp{--prefix} or
+@samp{--exec-prefix} options to @file{configure}. It is possible to use
+other names if the program or library should be installed in some other
+directory.
+
+The @file{Makefile.am} file may also contain almost anything that may
+appear in a normal @file{Makefile}. automake also supports many other
+special variables, as well as conditionals.
+
+See the automake manual for more information.
+
+@node Write acconfig.h
+@section Write acconfig.h
+@cindex @file{acconfig.h}, writing
+
+If you are generating a portability header file, (i.e., you are using
+@samp{AM_CONFIG_HEADER} in @file{configure.in}), then you will have to
+write a @file{acconfig.h} file. It will have to contain the following
+lines.
+
+@smallexample
+/* Name of package. */
+#undef PACKAGE
+
+/* Version of package. */
+#undef VERSION
+@end smallexample
+
+This requirement is really a bug in the system, and the requirement may
+be eliminated at some later date.
+
+The @file{acconfig.h} file will also similar comment and @samp{#undef}
+lines for any unusual macros in the @file{configure.in} file, including
+any macro which appears in a @samp{AC_DEFINE} macro.
+
+In particular, if you are writing a GNU package and therefore include
+@samp{AC_DEFINE(_GNU_SOURCE)} in @file{configure.in} as suggested above,
+you will need lines like this in @file{acconfig.h}:
+@smallexample
+/* Enable GNU extensions. */
+#undef _GNU_SOURCE
+@end smallexample
+
+Normally the @samp{autoheader} program will inform you of any such
+requirements by printing an error message when it is run. However, if
+you do anything particular odd in your @file{configure.in} file, you
+will have to make sure that the right entries appear in
+@file{acconfig.h}, since otherwise the results of the tests may not be
+available in the @file{config.h} file which your code will use.
+
+(Thee @samp{PACKAGE} and @samp{VERSION} lines are not required if you
+are not using automake, and in that case you may not need a
+@file{acconfig.h} file at all).
+
+@node Generate files
+@section Generate files
+
+Once you have written @file{configure.in}, @file{Makefile.am},
+@file{acconfig.h}, and possibly @file{acinclude.m4}, you must use
+autoconf and automake programs to produce the first versions of the
+generated files. This is done by executing the following sequence of
+commands.
+
+@smallexample
+aclocal
+autoconf
+autoheader
+automake
+@end smallexample
+
+The @samp{aclocal} and @samp{automake} commands are part of the automake
+package, and the @samp{autoconf} and @samp{autoheader} commands are part
+of the autoconf package.
+
+If you are using a @file{m4} subdirectory for your macros, you will need
+to use the @samp{-I m4} option when you run @samp{aclocal}.
+
+If you are not using the Cygnus tree, use the @samp{-a} option when
+running @samp{automake} command in order to copy the required support
+files into your source directory.
+
+If you are using libtool, you must build and install the libtool package
+with the same @samp{--prefix} and @samp{--exec-prefix} options as you
+used with the autoconf and automake packages. You must do this before
+running any of the above commands. If you are not using the Cygnus
+tree, you will need to run the @samp{libtoolize} program to copy the
+libtool support files into your directory.
+
+Once you have managed to run these commands without getting any errors,
+you should create a new empty directory, and run the @samp{configure}
+script which will have been created by @samp{autoconf} with the
+@samp{--enable-maintainer-mode} option. This will give you a set of
+Makefiles which will include rules to automatically rebuild all the
+generated files.
+
+After doing that, whenever you have changed some of the input files and
+want to regenerated the other files, go to your object directory and run
+@samp{make}. Doing this is more reliable than trying to rebuild the
+files manually, because there are complex order dependencies and it is
+easy to forget something.
+
+@node Getting Started Example
+@section Example
+
+Let's consider a trivial example.
+
+Suppose we want to write a simple version of @samp{touch}. Our program,
+which we will call @samp{poke}, will take a single file name argument,
+and use the @samp{utime} system call to set the modification and access
+times of the file to the current time. We want this program to be
+highly portable.
+
+We'll first see what this looks like without using autoconf and
+automake, and then see what it looks like with them.
+
+@menu
+* Getting Started Example 1:: First Try.
+* Getting Started Example 2:: Second Try.
+* Getting Started Example 3:: Third Try.
+* Generate Files in Example:: Generate Files.
+@end menu
+
+@node Getting Started Example 1
+@subsection First Try
+
+Here is our first try at @samp{poke.c}. Note that we've written it
+without ANSI/ISO C prototypes, since we want it to be highly portable.
+
+@example
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <utime.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+@{
+ if (argc != 2)
+ @{
+ fprintf (stderr, "Usage: poke file\n");
+ exit (1);
+ @}
+
+ if (utime (argv[1], NULL) < 0)
+ @{
+ perror ("utime");
+ exit (1);
+ @}
+
+ exit (0);
+@}
+@end example
+
+We also write a simple @file{Makefile}.
+
+@example
+CC = gcc
+CFLAGS = -g -O2
+
+all: poke
+
+poke: poke.o
+ $(CC) -o poke $(CFLAGS) $(LDFLAGS) poke.o
+@end example
+
+So far, so good.
+
+Unfortunately, there are a few problems.
+
+On older Unix systems derived from BSD 4.3, the @samp{utime} system call
+does not accept a second argument of @samp{NULL}. On those systems, we
+need to pass a pointer to @samp{struct utimbuf} structure.
+Unfortunately, even older systems don't define that structure; on those
+systems, we need to pass an array of two @samp{long} values.
+
+The header file @file{stdlib.h} was invented by ANSI C, and older
+systems don't have a copy. We included it above to get a declaration of
+@samp{exit}.
+
+We can find some of these portability problems by running
+@samp{autoscan}, which will create a @file{configure.scan} file which we
+can use as a prototype for our @file{configure.in} file. I won't show
+the output, but it will notice the potential problems with @samp{utime}
+and @file{stdlib.h}.
+
+In our @file{Makefile}, we don't provide any way to install the program.
+This doesn't matter much for such a simple example, but a real program
+will need an @samp{install} target. For that matter, we will also want
+a @samp{clean} target.
+
+@node Getting Started Example 2
+@subsection Second Try
+
+Here is our second try at this program.
+
+We modify @file{poke.c} to use preprocessor macros to control what
+features are available. (I've cheated a bit by using the same macro
+names which autoconf will use).
+
+@example
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifndef HAVE_UTIME_NULL
+
+#include <time.h>
+
+#ifndef HAVE_STRUCT_UTIMBUF
+
+struct utimbuf
+@{
+ long actime;
+ long modtime;
+@};
+
+#endif
+
+static int
+utime_now (file)
+ char *file;
+@{
+ struct utimbuf now;
+
+ now.actime = now.modtime = time (NULL);
+ return utime (file, &now);
+@}
+
+#define utime(f, p) utime_now (f)
+
+#endif /* HAVE_UTIME_NULL */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+@{
+ if (argc != 2)
+ @{
+ fprintf (stderr, "Usage: poke file\n");
+ exit (1);
+ @}
+
+ if (utime (argv[1], NULL) < 0)
+ @{
+ perror ("utime");
+ exit (1);
+ @}
+
+ exit (0);
+@}
+@end example
+
+Here is the associated @file{Makefile}. We've added support for the
+preprocessor flags we use. We've also added @samp{install} and
+@samp{clean} targets.
+
+@example
+# Set this to your installation directory.
+bindir = /usr/local/bin
+
+# Uncomment this if you have the standard ANSI/ISO C header files.
+# STDC_HDRS = -DSTDC_HEADERS
+
+# Uncomment this if you have utime.h.
+# UTIME_H = -DHAVE_UTIME_H
+
+# Uncomment this if utime (FILE, NULL) works on your system.
+# UTIME_NULL = -DHAVE_UTIME_NULL
+
+# Uncomment this if struct utimbuf is defined in utime.h.
+# UTIMBUF = -DHAVE_STRUCT_UTIMBUF
+
+CC = gcc
+CFLAGS = -g -O2
+
+ALL_CFLAGS = $(STDC_HDRS) $(UTIME_H) $(UTIME_NULL) $(UTIMBUF) $(CFLAGS)
+
+all: poke
+
+poke: poke.o
+ $(CC) -o poke $(ALL_CFLAGS) $(LDFLAGS) poke.o
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) poke.c
+
+install: poke
+ cp poke $(bindir)/poke
+
+clean:
+ rm poke poke.o
+@end example
+
+Some problems with this approach should be clear.
+
+Users who want to compile poke will have to know how @samp{utime} works
+on their systems, so that they can uncomment the @file{Makefile}
+correctly.
+
+The installation is done using @samp{cp}, but many systems have an
+@samp{install} program which may be used, and which supports optional
+features such as stripping debugging information out of the installed
+binary.
+
+The use of @file{Makefile} variables like @samp{CC}, @samp{CFLAGS} and
+@samp{LDFLAGS} follows the requirements of the GNU standards. This is
+convenient for all packages, since it reduces surprises for users.
+However, it is easy to get the details wrong, and wind up with a
+slightly nonstandard distribution.
+
+@node Getting Started Example 3
+@subsection Third Try
+
+For our third try at this program, we will write a @file{configure.in}
+script to discover the configuration features on the host system, rather
+than requiring the user to edit the @file{Makefile}. We will also write
+a @file{Makefile.am} rather than a @file{Makefile}.
+
+The only change to @file{poke.c} is to add a line at the start of the
+file:
+@smallexample
+#include "config.h"
+@end smallexample
+
+The new @file{configure.in} file is as follows.
+
+@example
+AC_INIT(poke.c)
+AM_INIT_AUTOMAKE(poke, 1.0)
+AM_CONFIG_HEADER(config.h:config.in)
+AC_PROG_CC
+AC_HEADER_STDC
+AC_CHECK_HEADERS(utime.h)
+AC_EGREP_HEADER(utimbuf, utime.h, AC_DEFINE(HAVE_STRUCT_UTIMBUF))
+AC_FUNC_UTIME_NULL
+AC_OUTPUT(Makefile)
+@end example
+
+The first four macros in this file, and the last one, were described
+above; see @ref{Write configure.in}. If we omit these macros, then when
+we run @samp{automake} we will get a reminder that we need them.
+
+The other macros are standard autoconf macros.
+
+@table @samp
+@item AC_HEADER_STDC
+Check for standard C headers.
+@item AC_CHECK_HEADERS
+Check whether a particular header file exists.
+@item AC_EGREP_HEADER
+Check for a particular string in a particular header file, in this case
+checking for @samp{utimbuf} in @file{utime.h}.
+@item AC_FUNC_UTIME_NULL
+Check whether @samp{utime} accepts a NULL second argument to set the
+file change time to the current time.
+@end table
+
+See the autoconf manual for a more complete description.
+
+The new @file{Makefile.am} file is as follows. Note how simple this is
+compared to our earlier @file{Makefile}.
+
+@example
+bin_PROGRAMS = poke
+
+poke_SOURCES = poke.c
+@end example
+
+This means that we should build a single program name @samp{poke}. It
+should be installed in the binary directory, which we called
+@samp{bindir} earlier. The program @samp{poke} is built from the source
+file @file{poke.c}.
+
+We must also write a @file{acconfig.h} file. Besides @samp{PACKAGE} and
+@samp{VERSION}, which must be mentioned for all packages which use
+automake, we must include @samp{HAVE_STRUCT_UTIMBUF}, since we mentioned
+it in an @samp{AC_DEFINE}.
+
+@example
+/* Name of package. */
+#undef PACKAGE
+
+/* Version of package. */
+#undef VERSION
+
+/* Whether utime.h defines struct utimbuf. */
+#undef HAVE_STRUCT_UTIMBUF
+@end example
+
+@node Generate Files in Example
+@subsection Generate Files
+
+We must now generate the other files, using the following commands.
+
+@smallexample
+aclocal
+autoconf
+autoheader
+automake
+@end smallexample
+
+When we run @samp{autoheader}, it will remind us of any macros we forgot
+to add to @file{acconfig.h}.
+
+When we run @samp{automake}, it will want to add some files to our
+distribution. It will add them automatically if we use the
+@samp{--add-missing} option.
+
+By default, @samp{automake} will run in GNU mode, which means that it
+will want us to create certain additional files; as of this writing, it
+will want @file{NEWS}, @file{README}, @file{AUTHORS}, and
+@file{ChangeLog}, all of which are files which should appear in a
+standard GNU distribution. We can either add those files, or run
+@samp{automake} with the @samp{--foreign} option.
+
+Running these tools will generate the following files, all of which are
+described in the next chapter.
+
+@itemize @bullet
+@item
+@file{aclocal.m4}
+@item
+@file{configure}
+@item
+@file{config.in}
+@item
+@file{Makefile.in}
+@item
+@file{stamp-h.in}
+@end itemize
+
+@node Files
+@chapter Files
+
+As was seen in the previous chapter, the GNU configure and build system
+uses a number of different files. The developer must write a few files.
+The others are generated by various tools.
+
+The system is rather flexible, and can be used in many different ways.
+In describing the files that it uses, I will describe the common case,
+and mention some other cases that may arise.
+
+@menu
+* Developer Files:: Developer Files.
+* Build Files:: Build Files.
+* Support Files:: Support Files.
+@end menu
+
+@node Developer Files
+@section Developer Files
+
+This section describes the files written or generated by the developer
+of a package.
+
+@menu
+* Developer Files Picture:: Developer Files Picture.
+* Written Developer Files:: Written Developer Files.
+* Generated Developer Files:: Generated Developer Files.
+@end menu
+
+@node Developer Files Picture
+@subsection Developer Files Picture
+
+Here is a picture of the files which are written by the developer, the
+generated files which would be included with a complete source
+distribution, and the tools which create those files.
+@ifinfo
+The file names are plain text and the tool names are enclosed by
+@samp{*} characters
+@end ifinfo
+@ifnotinfo
+The file names are in rectangles with square corners and the tool names
+are in rectangles with rounded corners
+@end ifnotinfo
+(e.g., @samp{autoheader} is the name of a tool, not the name of a file).
+
+@image{configdev}
+
+@node Written Developer Files
+@subsection Written Developer Files
+
+The following files would be written by the developer.
+
+@table @file
+@item configure.in
+@cindex @file{configure.in}
+This is the configuration script. This script contains invocations of
+autoconf macros. It may also contain ordinary shell script code. This
+file will contain feature tests for portability issues. The last thing
+in the file will normally be an @samp{AC_OUTPUT} macro listing which
+files to create when the builder runs the configure script. This file
+is always required when using the GNU configure system. @xref{Write
+configure.in}.
+
+@item Makefile.am
+@cindex @file{Makefile.am}
+This is the automake input file. It describes how the code should be
+built. It consists of definitions of automake variables. It may also
+contain ordinary Makefile targets. This file is only needed when using
+automake (newer tools normally use automake, but there are still older
+tools which have not been converted, in which the developer writes
+@file{Makefile.in} directly). @xref{Write Makefile.am}.
+
+@item acconfig.h
+@cindex @file{acconfig.h}
+When the configure script creates a portability header file, by using
+@samp{AM_CONFIG_HEADER} (or, if not using automake,
+@samp{AC_CONFIG_HEADER}), this file is used to describe macros which are
+not recognized by the @samp{autoheader} command. This is normally a
+fairly uninteresting file, consisting of a collection of @samp{#undef}
+lines with comments. Normally any call to @samp{AC_DEFINE} in
+@file{configure.in} will require a line in this file. @xref{Write
+acconfig.h}.
+
+@item acinclude.m4
+@cindex @file{acinclude.m4}
+This file is not always required. It defines local autoconf macros.
+These macros may then be used in @file{configure.in}. If you don't need
+any local autoconf macros, then you don't need this file at all. In
+fact, in general, you never need local autoconf macros, since you can
+put everything in @file{configure.in}, but sometimes a local macro is
+convenient.
+
+Newer tools may omit @file{acinclude.m4}, and instead use a
+subdirectory, typically named @file{m4}, and define
+@samp{ACLOCAL_AMFLAGS = -I m4} in @file{Makefile.am} to force
+@samp{aclocal} to look there for macro definitions. The macro
+definitions are then placed in separate files in that directory.
+
+The @file{acinclude.m4} file is only used when using automake; in older
+tools, the developer writes @file{aclocal.m4} directly, if it is needed.
+@end table
+
+@node Generated Developer Files
+@subsection Generated Developer Files
+
+The following files would be generated by the developer.
+
+When using automake, these files are normally not generated manually
+after the first time. Instead, the generated @file{Makefile} contains
+rules to automatically rebuild the files as required. When
+@samp{AM_MAINTAINER_MODE} is used in @file{configure.in} (the normal
+case in Cygnus code), the automatic rebuilding rules will only be
+defined if you configure using the @samp{--enable-maintainer-mode}
+option.
+
+When using automatic rebuilding, it is important to ensure that all the
+various tools have been built and installed on your @samp{PATH}. Using
+automatic rebuilding is highly recommended, so much so that I'm not
+going to explain what you have to do if you don't use it.
+
+@table @file
+@item configure
+@cindex @file{configure}
+This is the configure script which will be run when building the
+package. This is generated by @samp{autoconf} from @file{configure.in}
+and @file{aclocal.m4}. This is a shell script.
+
+@item Makefile.in
+@cindex @file{Makefile.in}
+This is the file which the configure script will turn into the
+@file{Makefile} at build time. This file is generated by
+@samp{automake} from @file{Makefile.am}. If you aren't using automake,
+you must write this file yourself. This file is pretty much a normal
+@file{Makefile}, with some configure substitutions for certain
+variables.
+
+@item aclocal.m4
+@cindex @file{aclocal.m4}
+This file is created by the @samp{aclocal} program, based on the
+contents of @file{configure.in} and @file{acinclude.m4} (or, as noted in
+the description of @file{acinclude.m4} above, on the contents of an
+@file{m4} subdirectory). This file contains definitions of autoconf
+macros which @samp{autoconf} will use when generating the file
+@file{configure}. These autoconf macros may be defined by you in
+@file{acinclude.m4} or they may be defined by other packages such as
+automake, libtool or gettext. If you aren't using automake, you will
+normally write this file yourself; in that case, if @file{configure.in}
+uses only standard autoconf macros, this file will not be needed at all.
+
+@item config.in
+@cindex @file{config.in}
+@cindex @file{config.h.in}
+This file is created by @samp{autoheader} based on @file{acconfig.h} and
+@file{configure.in}. At build time, the configure script will define
+some of the macros in it to create @file{config.h}, which may then be
+included by your program. This permits your C code to use preprocessor
+conditionals to change its behaviour based on the characteristics of the
+host system. This file may also be called @file{config.h.in}.
+
+@item stamp.h-in
+@cindex @file{stamp-h.in}
+This rather uninteresting file, which I omitted from the picture, is
+generated by @samp{automake}. It always contains the string
+@samp{timestamp}. It is used as a timestamp file indicating whether
+@file{config.in} is up to date. Using a timestamp file means that
+@file{config.in} can be marked as up to date without actually changing
+its modification time. This is useful since @file{config.in} depends
+upon @file{configure.in}, but it is easy to change @file{configure.in}
+in a way which does not affect @file{config.in}.
+@end table
+
+@node Build Files
+@section Build Files
+
+This section describes the files which are created at configure and
+build time. These are the files which somebody who builds the package
+will see.
+
+Of course, the developer will also build the package. The distinction
+between developer files and build files is not that the developer does
+not see the build files, but that somebody who only builds the package
+does not have to worry about the developer files.
+
+@menu
+* Build Files Picture:: Build Files Picture.
+* Build Files Description:: Build Files Description.
+@end menu
+
+@node Build Files Picture
+@subsection Build Files Picture
+
+Here is a picture of the files which will be created at build time.
+@file{config.status} is both a created file and a shell script which is
+run to create other files, and the picture attempts to show that.
+
+@image{configbuild}
+
+@node Build Files Description
+@subsection Build Files Description
+
+This is a description of the files which are created at build time.
+
+@table @file
+@item config.status
+@cindex @file{config.status}
+The first step in building a package is to run the @file{configure}
+script. The @file{configure} script will create the file
+@file{config.status}, which is itself a shell script. When you first
+run @file{configure}, it will automatically run @file{config.status}.
+An @file{Makefile} derived from an automake generated @file{Makefile.in}
+will contain rules to automatically run @file{config.status} again when
+necessary to recreate certain files if their inputs change.
+
+@item Makefile
+@cindex @file{Makefile}
+This is the file which make will read to build the program. The
+@file{config.status} script will transform @file{Makefile.in} into
+@file{Makefile}.
+
+@item config.h
+@cindex @file{config.h}
+This file defines C preprocessor macros which C code can use to adjust
+its behaviour on different systems. The @file{config.status} script
+will transform @file{config.in} into @file{config.h}.
+
+@item config.cache
+@cindex @file{config.cache}
+This file did not fit neatly into the picture, and I omitted it. It is
+used by the @file{configure} script to cache results between runs. This
+can be an important speedup. If you modify @file{configure.in} in such
+a way that the results of old tests should change (perhaps you have
+added a new library to @samp{LDFLAGS}), then you will have to remove
+@file{config.cache} to force the tests to be rerun.
+
+The autoconf manual explains how to set up a site specific cache file.
+This can speed up running @file{configure} scripts on your system.
+
+@item stamp.h
+@cindex @file{stamp-h}
+This file, which I omitted from the picture, is similar to
+@file{stamp-h.in}. It is used as a timestamp file indicating whether
+@file{config.h} is up to date. This is useful since @file{config.h}
+depends upon @file{config.status}, but it is easy for
+@file{config.status} to change in a way which does not affect
+@file{config.h}.
+@end table
+
+@node Support Files
+@section Support Files
+
+The GNU configure and build system requires several support files to be
+included with your distribution. You do not normally need to concern
+yourself with these. If you are using the Cygnus tree, most are already
+present. Otherwise, they will be installed with your source by
+@samp{automake} (with the @samp{--add-missing} option) and
+@samp{libtoolize}.
+
+You don't have to put the support files in the top level directory. You
+can put them in a subdirectory, and use the @samp{AC_CONFIG_AUX_DIR}
+macro in @file{configure.in} to tell @samp{automake} and the
+@file{configure} script where they are.
+
+In this section, I describe the support files, so that you can know what
+they are and why they are there.
+
+@table @file
+@item ABOUT-NLS
+Added by automake if you are using gettext. This is a documentation
+file about the gettext project.
+@item ansi2knr.c
+Used by an automake generated @file{Makefile} if you put @samp{ansi2knr}
+in @samp{AUTOMAKE_OPTIONS} in @file{Makefile.am}. This permits
+compiling ANSI C code with a K&R C compiler.
+@item ansi2knr.1
+The man page which goes with @file{ansi2knr.c}.
+@item config.guess
+A shell script which determines the configuration name for the system on
+which it is run.
+@item config.sub
+A shell script which canonicalizes a configuration name entered by a
+user.
+@item elisp-comp
+Used to compile Emacs LISP files.
+@item install-sh
+A shell script which installs a program. This is used if the configure
+script can not find an install binary.
+@item ltconfig
+Used by libtool. This is a shell script which configures libtool for
+the particular system on which it is used.
+@item ltmain.sh
+Used by libtool. This is the actual libtool script which is used, after
+it is configured by @file{ltconfig} to build a library.
+@item mdate-sh
+A shell script used by an automake generated @file{Makefile} to pretty
+print the modification time of a file. This is used to maintain version
+numbers for texinfo files.
+@item missing
+A shell script used if some tool is missing entirely. This is used by
+an automake generated @file{Makefile} to avoid certain sorts of
+timestamp problems.
+@item mkinstalldirs
+A shell script which creates a directory, including all parent
+directories. This is used by an automake generated @file{Makefile}
+during installation.
+@item texinfo.tex
+Required if you have any texinfo files. This is used when converting
+Texinfo files into DVI using @samp{texi2dvi} and @TeX{}.
+@item ylwrap
+A shell script used by an automake generated @file{Makefile} to run
+programs like @samp{bison}, @samp{yacc}, @samp{flex}, and @samp{lex}.
+These programs default to producing output files with a fixed name, and
+the @file{ylwrap} script runs them in a subdirectory to avoid file name
+conflicts when using a parallel make program.
+@end table
+
+@node Configuration Names
+@chapter Configuration Names
+@cindex configuration names
+@cindex configuration triplets
+@cindex triplets
+@cindex host names
+@cindex host triplets
+@cindex canonical system names
+@cindex system names
+@cindex system types
+
+The GNU configure system names all systems using a @dfn{configuration
+name}. All such names used to be triplets (they may now contain four
+parts in certain cases), and the term @dfn{configuration triplet} is
+still seen.
+
+@menu
+* Configuration Name Definition:: Configuration Name Definition.
+* Using Configuration Names:: Using Configuration Names.
+@end menu
+
+@node Configuration Name Definition
+@section Configuration Name Definition
+
+This is a string of the form
+@var{cpu}-@var{manufacturer}-@var{operating_system}. In some cases,
+this is extended to a four part form:
+@var{cpu}-@var{manufacturer}-@var{kernel}-@var{operating_system}.
+
+When using a configuration name in a configure option, it is normally
+not necessary to specify an entire name. In particular, the
+@var{manufacturer} field is often omitted, leading to strings such as
+@samp{i386-linux} or @samp{sparc-sunos}. The shell script
+@file{config.sub} will translate these shortened strings into the
+canonical form. autoconf will arrange for @file{config.sub} to be run
+automatically when it is needed.
+
+The fields of a configuration name are as follows:
+
+@table @var
+@item cpu
+The type of processor. This is typically something like @samp{i386} or
+@samp{sparc}. More specific variants are used as well, such as
+@samp{mipsel} to indicate a little endian MIPS processor.
+@item manufacturer
+A somewhat freeform field which indicates the manufacturer of the
+system. This is often simply @samp{unknown}. Other common strings are
+@samp{pc} for an IBM PC compatible system, or the name of a workstation
+vendor, such as @samp{sun}.
+@item operating_system
+The name of the operating system which is run on the system. This will
+be something like @samp{solaris2.5} or @samp{irix6.3}. There is no
+particular restriction on the version number, and strings like
+@samp{aix4.1.4.0} are seen. For an embedded system, which has no
+operating system, this field normally indicates the type of object file
+format, such as @samp{elf} or @samp{coff}.
+@item kernel
+This is used mainly for GNU/Linux. A typical GNU/Linux configuration
+name is @samp{i586-pc-linux-gnulibc1}. In this case the kernel,
+@samp{linux}, is separated from the operating system, @samp{gnulibc1}.
+@end table
+
+The shell script @file{config.guess} will normally print the correct
+configuration name for the system on which it is run. It does by
+running @samp{uname} and by examining other characteristics of the
+system.
+
+Because @file{config.guess} can normally determine the configuration
+name for a machine, it is normally only necessary to specify a
+configuration name when building a cross-compiler or when building using
+a cross-compiler.
+
+@node Using Configuration Names
+@section Using Configuration Names
+
+A configure script will sometimes have to make a decision based on a
+configuration name. You will need to do this if you have to compile
+code differently based on something which can not be tested using a
+standard autoconf feature test.
+
+It is normally better to test for particular features, rather than to
+test for a particular system. This is because as Unix evolves,
+different systems copy features from one another. Even if you need to
+determine whether the feature is supported based on a configuration
+name, you should define a macro which describes the feature, rather than
+defining a macro which describes the particular system you are on.
+
+Testing for a particular system is normally done using a case statement
+in @file{configure.in}. The case statement might look something like
+the following, assuming that @samp{host} is a shell variable holding a
+canonical configuration name (which will be the case if
+@file{configure.in} uses the @samp{AC_CANONICAL_HOST} or
+@samp{AC_CANONICAL_SYSTEM} macro).
+
+@smallexample
+case "$@{host@}" in
+i[3456]86-*-linux-gnu*) do something ;;
+sparc*-sun-solaris2.[56789]*) do something ;;
+sparc*-sun-solaris*) do something ;;
+mips*-*-elf*) do something ;;
+esac
+@end smallexample
+
+It is particularly important to use @samp{*} after the operating system
+field, in order to match the version number which will be generated by
+@file{config.guess}.
+
+In most cases you must be careful to match a range of processor types.
+For most processor families, a trailing @samp{*} suffices, as in
+@samp{mips*} above. For the i386 family, something along the lines of
+@samp{i[3456]86} suffices at present. For the m68k family, you will
+need something like @samp{m68*}. Of course, if you do not need to match
+on the processor, it is simpler to just replace the entire field by a
+@samp{*}, as in @samp{*-*-irix*}.
+
+@node Cross Compilation Tools
+@chapter Cross Compilation Tools
+@cindex cross tools
+
+The GNU configure and build system can be used to build @dfn{cross
+compilation} tools. A cross compilation tool is a tool which runs on
+one system and produces code which runs on another system.
+
+@menu
+* Cross Compilation Concepts:: Cross Compilation Concepts.
+* Host and Target:: Host and Target.
+* Using the Host Type:: Using the Host Type.
+* Specifying the Target:: Specifying the Target.
+* Using the Target Type:: Using the Target Type.
+* Cross Tools in the Cygnus Tree:: Cross Tools in the Cygnus Tree
+@end menu
+
+@node Cross Compilation Concepts
+@section Cross Compilation Concepts
+
+@cindex cross compiler
+A compiler which produces programs which run on a different system is a
+cross compilation compiler, or simply a @dfn{cross compiler}.
+Similarly, we speak of cross assemblers, cross linkers, etc.
+
+In the normal case, a compiler produces code which runs on the same
+system as the one on which the compiler runs. When it is necessary to
+distinguish this case from the cross compilation case, such a compiler
+is called a @dfn{native compiler}. Similarly, we speak of native
+assemblers, etc.
+
+Although the debugger is not strictly speaking a compilation tool, it is
+nevertheless meaningful to speak of a cross debugger: a debugger which
+is used to debug code which runs on another system. Everything that is
+said below about configuring cross compilation tools applies to the
+debugger as well.
+
+@node Host and Target
+@section Host and Target
+@cindex host system
+@cindex target system
+
+When building cross compilation tools, there are two different systems
+involved: the system on which the tools will run, and the system for
+which the tools generate code.
+
+The system on which the tools will run is called the @dfn{host} system.
+
+The system for which the tools generate code is called the @dfn{target}
+system.
+
+For example, suppose you have a compiler which runs on a GNU/Linux
+system and generates ELF programs for a MIPS embedded system. In this
+case the GNU/Linux system is the host, and the MIPS ELF system is the
+target. Such a compiler could be called a GNU/Linux cross MIPS ELF
+compiler, or, equivalently, a @samp{i386-linux-gnu} cross
+@samp{mips-elf} compiler.
+
+Naturally, most programs are not cross compilation tools. For those
+programs, it does not make sense to speak of a target. It only makes
+sense to speak of a target for tools like @samp{gcc} or the
+@samp{binutils} which actually produce running code. For example, it
+does not make sense to speak of the target of a tool like @samp{bison}
+or @samp{make}.
+
+Most cross compilation tools can also serve as native tools. For a
+native compilation tool, it is still meaningful to speak of a target.
+For a native tool, the target is the same as the host. For example, for
+a GNU/Linux native compiler, the host is GNU/Linux, and the target is
+also GNU/Linux.
+
+@node Using the Host Type
+@section Using the Host Type
+
+In almost all cases the host system is the system on which you run the
+@samp{configure} script, and on which you build the tools (for the case
+when they differ, @pxref{Canadian Cross}).
+
+@cindex @samp{AC_CANONICAL_HOST}
+If your configure script needs to know the configuration name of the
+host system, and the package is not a cross compilation tool and
+therefore does not have a target, put @samp{AC_CANONICAL_HOST} in
+@file{configure.in}. This macro will arrange to define a few shell
+variables when the @samp{configure} script is run.
+
+@table @samp
+@item host
+The canonical configuration name of the host. This will normally be
+determined by running the @file{config.guess} shell script, although the
+user is permitted to override this by using an explicit @samp{--host}
+option.
+@item host_alias
+In the unusual case that the user used an explicit @samp{--host} option,
+this will be the argument to @samp{--host}. In the normal case, this
+will be the same as the @samp{host} variable.
+@item host_cpu
+@itemx host_vendor
+@itemx host_os
+The first three parts of the canonical configuration name.
+@end table
+
+The shell variables may be used by putting shell code in
+@file{configure.in}. For an example, see @ref{Using Configuration
+Names}.
+
+@node Specifying the Target
+@section Specifying the Target
+
+By default, the @samp{configure} script will assume that the target is
+the same as the host. This is the more common case; for example, it
+leads to a native compiler rather than a cross compiler.
+
+@cindex @samp{--target} option
+@cindex target option
+@cindex configure target
+If you want to build a cross compilation tool, you must specify the
+target explicitly by using the @samp{--target} option when you run
+@samp{configure}. The argument to @samp{--target} is the configuration
+name of the system for which you wish to generate code.
+@xref{Configuration Names}.
+
+For example, to build tools which generate code for a MIPS ELF embedded
+system, you would use @samp{--target mips-elf}.
+
+@node Using the Target Type
+@section Using the Target Type
+
+@cindex @samp{AC_CANONICAL_SYSTEM}
+When writing @file{configure.in} for a cross compilation tool, you will
+need to use information about the target. To do this, put
+@samp{AC_CANONICAL_SYSTEM} in @file{configure.in}.
+
+@samp{AC_CANONICAL_SYSTEM} will look for a @samp{--target} option and
+canonicalize it using the @file{config.sub} shell script. It will also
+run @samp{AC_CANONICAL_HOST} (@pxref{Using the Host Type}).
+
+The target type will be recorded in the following shell variables. Note
+that the host versions of these variables will also be defined by
+@samp{AC_CANONICAL_HOST}.
+
+@table @samp
+@item target
+The canonical configuration name of the target.
+@item target_alias
+The argument to the @samp{--target} option. If the user did not specify
+a @samp{--target} option, this will be the same as @samp{host_alias}.
+@item target_cpu
+@itemx target_vendor
+@itemx target_os
+The first three parts of the canonical target configuration name.
+@end table
+
+Note that if @samp{host} and @samp{target} are the same string, you can
+assume a native configuration. If they are different, you can assume a
+cross configuration.
+
+It is arguably possible for @samp{host} and @samp{target} to represent
+the same system, but for the strings to not be identical. For example,
+if @samp{config.guess} returns @samp{sparc-sun-sunos4.1.4}, and somebody
+configures with @samp{--target sparc-sun-sunos4.1}, then the slight
+differences between the two versions of SunOS may be unimportant for
+your tool. However, in the general case it can be quite difficult to
+determine whether the differences between two configuration names are
+significant or not. Therefore, by convention, if the user specifies a
+@samp{--target} option without specifying a @samp{--host} option, it is
+assumed that the user wants to configure a cross compilation tool.
+
+The variables @samp{target} and @samp{target_alias} should be handled
+differently.
+
+In general, whenever the user may actually see a string,
+@samp{target_alias} should be used. This includes anything which may
+appear in the file system, such as a directory name or part of a tool
+name. It also includes any tool output, unless it is clearly labelled
+as the canonical target configuration name. This permits the user to
+use the @samp{--target} option to specify how the tool will appear to
+the outside world.
+
+On the other hand, when checking for characteristics of the target
+system, @samp{target} should be used. This is because a wide variety of
+@samp{--target} options may map into the same canonical configuration
+name. You should not attempt to duplicate the canonicalization done by
+@samp{config.sub} in your own code.
+
+By convention, cross tools are installed with a prefix of the argument
+used with the @samp{--target} option, also known as @samp{target_alias}
+(@pxref{Using the Target Type}). If the user does not use the
+@samp{--target} option, and thus is building a native tool, no prefix is
+used.
+
+For example, if gcc is configured with @samp{--target mips-elf}, then
+the installed binary will be named @samp{mips-elf-gcc}. If gcc is
+configured without a @samp{--target} option, then the installed binary
+will be named @samp{gcc}.
+
+The autoconf macro @samp{AC_ARG_PROGRAM} will handle this for you. If
+you are using automake, no more need be done; the programs will
+automatically be installed with the correct prefixes. Otherwise, see
+the autoconf documentation for @samp{AC_ARG_PROGRAM}.
+
+@node Cross Tools in the Cygnus Tree
+@section Cross Tools in the Cygnus Tree
+
+The Cygnus tree is used for various packages including gdb, the GNU
+binutils, and egcs. It is also, of course, used for Cygnus releases.
+
+In the Cygnus tree, the top level @file{configure} script uses the old
+Cygnus configure system, not autoconf. The top level @file{Makefile.in}
+is written to build packages based on what is in the source tree, and
+supports building a large number of tools in a single
+@samp{configure}/@samp{make} step.
+
+The Cygnus tree may be configured with a @samp{--target} option. The
+@samp{--target} option applies recursively to every subdirectory, and
+permits building an entire set of cross tools at once.
+
+@menu
+* Host and Target Libraries:: Host and Target Libraries.
+* Target Library Configure Scripts:: Target Library Configure Scripts.
+* Make Targets in Cygnus Tree:: Make Targets in Cygnus Tree.
+* Target libiberty:: Target libiberty
+@end menu
+
+@node Host and Target Libraries
+@subsection Host and Target Libraries
+
+The Cygnus tree distinguishes host libraries from target libraries.
+
+Host libraries are built with the compiler used to build the programs
+which run on the host, which is called the host compiler. This includes
+libraries such as @samp{bfd} and @samp{tcl}. These libraries are built
+with the host compiler, and are linked into programs like the binutils
+or gcc which run on the host.
+
+Target libraries are built with the target compiler. If gcc is present
+in the source tree, then the target compiler is the gcc that is built
+using the host compiler. Target libraries are libraries such as
+@samp{newlib} and @samp{libstdc++}. These libraries are not linked into
+the host programs, but are instead made available for use with programs
+built with the target compiler.
+
+For the rest of this section, assume that gcc is present in the source
+tree, so that it will be used to build the target libraries.
+
+There is a complication here. The configure process needs to know which
+compiler you are going to use to build a tool; otherwise, the feature
+tests will not work correctly. The Cygnus tree handles this by not
+configuring the target libraries until the target compiler is built. In
+order to permit everything to build using a single
+@samp{configure}/@samp{make}, the configuration of the target libraries
+is actually triggered during the make step.
+
+When the target libraries are configured, the @samp{--target} option is
+not used. Instead, the @samp{--host} option is used with the argument
+of the @samp{--target} option for the overall configuration. If no
+@samp{--target} option was used for the overall configuration, the
+@samp{--host} option will be passed with the output of the
+@file{config.guess} shell script. Any @samp{--build} option is passed
+down unchanged.
+
+This translation of configuration options is done because since the
+target libraries are compiled with the target compiler, they are being
+built in order to run on the target of the overall configuration. By
+the definition of host, this means that their host system is the same as
+the target system of the overall configuration.
+
+The same process is used for both a native configuration and a cross
+configuration. Even when using a native configuration, the target
+libraries will be configured and built using the newly built compiler.
+This is particularly important for the C++ libraries, since there is no
+reason to assume that the C++ compiler used to build the host tools (if
+there even is one) uses the same ABI as the g++ compiler which will be
+used to build the target libraries.
+
+There is one difference between a native configuration and a cross
+configuration. In a native configuration, the target libraries are
+normally configured and built as siblings of the host tools. In a cross
+configuration, the target libraries are normally built in a subdirectory
+whose name is the argument to @samp{--target}. This is mainly for
+historical reasons.
+
+To summarize, running @samp{configure} in the Cygnus tree configures all
+the host libraries and tools, but does not configure any of the target
+libraries. Running @samp{make} then does the following steps:
+
+@itemize @bullet
+@item
+Build the host libraries.
+@item
+Build the host programs, including gcc. Note that we call gcc both a
+host program (since it runs on the host) and a target compiler (since it
+generates code for the target).
+@item
+Using the newly built target compiler, configure the target libraries.
+@item
+Build the target libraries.
+@end itemize
+
+The steps need not be done in precisely this order, since they are
+actually controlled by @file{Makefile} targets.
+
+@node Target Library Configure Scripts
+@subsection Target Library Configure Scripts
+
+There are a few things you must know in order to write a configure
+script for a target library. This is just a quick sketch, and beginners
+shouldn't worry if they don't follow everything here.
+
+The target libraries are configured and built using a newly built target
+compiler. There may not be any startup files or libraries for this
+target compiler. In fact, those files will probably be built as part of
+some target library, which naturally means that they will not exist when
+your target library is configured.
+
+This means that the configure script for a target library may not use
+any test which requires doing a link. This unfortunately includes many
+useful autoconf macros, such as @samp{AC_CHECK_FUNCS}. autoconf macros
+which do a compile but not a link, such as @samp{AC_CHECK_HEADERS}, may
+be used.
+
+This is a severe restriction, but normally not a fatal one, as target
+libraries can often assume the presence of other target libraries, and
+thus know which functions will be available.
+
+As of this writing, the autoconf macro @samp{AC_PROG_CC} does a link to
+make sure that the compiler works. This may fail in a target library,
+so target libraries must use a different set of macros to locate the
+compiler. See the @file{configure.in} file in a directory like
+@file{libiberty} or @file{libgloss} for an example.
+
+As noted in the previous section, target libraries are sometimes built
+in directories which are siblings to the host tools, and are sometimes
+built in a subdirectory. The @samp{--with-target-subdir} configure
+option will be passed when the library is configured. Its value will be
+an empty string if the target library is a sibling. Its value will be
+the name of the subdirectory if the target library is in a subdirectory.
+
+If the overall build is not a native build (i.e., the overall configure
+used the @samp{--target} option), then the library will be configured
+with the @samp{--with-cross-host} option. The value of this option will
+be the host system of the overall build. Recall that the host system of
+the library will be the target of the overall build. If the overall
+build is a native build, the @samp{--with-cross-host} option will not be
+used.
+
+A library which can be built both standalone and as a target library may
+want to install itself into different directories depending upon the
+case. When built standalone, or when built native, the library should
+be installed in @samp{$(libdir)}. When built as a target library which
+is not native, the library should be installed in @samp{$(tooldir)/lib}.
+The @samp{--with-cross-host} option may be used to distinguish these
+cases.
+
+This same test of @samp{--with-cross-host} may be used to see whether it
+is OK to use link tests in the configure script. If the
+@samp{--with-cross-host} option is not used, then the library is being
+built either standalone or native, and a link should work.
+
+@node Make Targets in Cygnus Tree
+@subsection Make Targets in Cygnus Tree
+
+The top level @file{Makefile} in the Cygnus tree defines targets for
+every known subdirectory.
+
+For every subdirectory @var{dir} which holds a host library or program,
+the @file{Makefile} target @samp{all-@var{dir}} will build that library
+or program.
+
+There are dependencies among host tools. For example, building gcc
+requires first building gas, because the gcc build process invokes the
+target assembler. These dependencies are reflected in the top level
+@file{Makefile}.
+
+For every subdirectory @var{dir} which holds a target library, the
+@file{Makefile} target @samp{configure-target-@var{dir}} will configure
+that library. The @file{Makefile} target @samp{all-target-@var{dir}}
+will build that library.
+
+Every @samp{configure-target-@var{dir}} target depends upon
+@samp{all-gcc}, since gcc, the target compiler, is required to configure
+the tool. Every @samp{all-target-@var{dir}} target depends upon the
+corresponding @samp{configure-target-@var{dir}} target.
+
+There are several other targets which may be of interest for each
+directory: @samp{install-@var{dir}}, @samp{clean-@var{dir}}, and
+@samp{check-@var{dir}}. There are also corresponding @samp{target}
+versions of these for the target libraries , such as
+@samp{install-target-@var{dir}}.
+
+@node Target libiberty
+@subsection Target libiberty
+
+The @file{libiberty} subdirectory is currently a special case, in that
+it is the only directory which is built both using the host compiler and
+using the target compiler.
+
+This is because the files in @file{libiberty} are used when building the
+host tools, and they are also incorporated into the @file{libstdc++}
+target library as support code.
+
+This duality does not pose any particular difficulties. It means that
+there are targets for both @samp{all-libiberty} and
+@samp{all-target-libiberty}.
+
+In a native configuration, when target libraries are not built in a
+subdirectory, the same objects are normally used as both the host build
+and the target build. This is normally OK, since libiberty contains
+only C code, and in a native configuration the results of the host
+compiler and the target compiler are normally interoperable.
+
+Irix 6 is again an exception here, since the SGI native compiler
+defaults to using the @samp{O32} ABI, and gcc defaults to using the
+@samp{N32} ABI. On Irix 6, the target libraries are built in a
+subdirectory even for a native configuration, avoiding this problem.
+
+There are currently no other libraries built for both the host and the
+target, but there is no conceptual problem with adding more.
+
+@node Canadian Cross
+@chapter Canadian Cross
+@cindex canadian cross
+@cindex building with a cross compiler
+@cindex cross compiler, building with
+
+It is possible to use the GNU configure and build system to build a
+program which will run on a system which is different from the system on
+which the tools are built. In other words, it is possible to build
+programs using a cross compiler.
+
+This is referred to as a @dfn{Canadian Cross}.
+
+@menu
+* Canadian Cross Example:: Canadian Cross Example.
+* Canadian Cross Concepts:: Canadian Cross Concepts.
+* Build Cross Host Tools:: Build Cross Host Tools.
+* Build and Host Options:: Build and Host Options.
+* CCross not in Cygnus Tree:: Canadian Cross not in Cygnus Tree.
+* CCross in Cygnus Tree:: Canadian Cross in Cygnus Tree.
+* Supporting Canadian Cross:: Supporting Canadian Cross.
+@end menu
+
+@node Canadian Cross Example
+@section Canadian Cross Example
+
+Here is an example of a Canadian Cross.
+
+While running on a GNU/Linux, you can build a program which will run on
+a Solaris system. You would use a GNU/Linux cross Solaris compiler to
+build the program.
+
+Of course, you could not run the resulting program on your GNU/Linux
+system. You would have to copy it over to a Solaris system before you
+would run it.
+
+Of course, you could also simply build the programs on the Solaris
+system in the first place. However, perhaps the Solaris system is not
+available for some reason; perhaps you actually don't have one, but you
+want to build the tools for somebody else to use. Or perhaps your
+GNU/Linux system is much faster than your Solaris system.
+
+A Canadian Cross build is most frequently used when building programs to
+run on a non-Unix system, such as DOS or Windows. It may be simpler to
+configure and build on a Unix system than to support the configuration
+machinery on a non-Unix system.
+
+@node Canadian Cross Concepts
+@section Canadian Cross Concepts
+
+When building a Canadian Cross, there are at least two different systems
+involved: the system on which the tools are being built, and the system
+on which the tools will run.
+
+The system on which the tools are being built is called the @dfn{build}
+system.
+
+The system on which the tools will run is called the host system.
+
+For example, if you are building a Solaris program on a GNU/Linux
+system, as in the previous section, the build system would be GNU/Linux,
+and the host system would be Solaris.
+
+It is, of course, possible to build a cross compiler using a Canadian
+Cross (i.e., build a cross compiler using a cross compiler). In this
+case, the system for which the resulting cross compiler generates code
+is called the target system. (For a more complete discussion of host
+and target systems, @pxref{Host and Target}).
+
+An example of building a cross compiler using a Canadian Cross would be
+building a Windows cross MIPS ELF compiler on a GNU/Linux system. In
+this case the build system would be GNU/Linux, the host system would be
+Windows, and the target system would be MIPS ELF.
+
+The name Canadian Cross comes from the case when the build, host, and
+target systems are all different. At the time that these issues were
+all being hashed out, Canada had three national political parties.
+
+@node Build Cross Host Tools
+@section Build Cross Host Tools
+
+In order to configure a program for a Canadian Cross build, you must
+first build and install the set of cross tools you will use to build the
+program.
+
+These tools will be build cross host tools. That is, they will run on
+the build system, and will produce code that runs on the host system.
+
+It is easy to confuse the meaning of build and host here. Always
+remember that the build system is where you are doing the build, and the
+host system is where the resulting program will run. Therefore, you
+need a build cross host compiler.
+
+In general, you must have a complete cross environment in order to do
+the build. This normally means a cross compiler, cross assembler, and
+so forth, as well as libraries and include files for the host system.
+
+@node Build and Host Options
+@section Build and Host Options
+@cindex configuring a canadian cross
+@cindex canadian cross, configuring
+
+When you run @file{configure}, you must use both the @samp{--build} and
+@samp{--host} options.
+
+@cindex @samp{--build} option
+@cindex build option
+@cindex configure build system
+The @samp{--build} option is used to specify the configuration name of
+the build system. This can normally be the result of running the
+@file{config.guess} shell script, and it is reasonable to use
+@samp{--build=`config.guess`}.
+
+@cindex @samp{--host} option
+@cindex host option
+@cindex configure host
+The @samp{--host} option is used to specify the configuration name of
+the host system.
+
+As we explained earlier, @file{config.guess} is used to set the default
+value for the @samp{--host} option (@pxref{Using the Host Type}). We
+can now see that since @file{config.guess} returns the type of system on
+which it is run, it really identifies the build system. Since the host
+system is normally the same as the build system (i.e., people do not
+normally build using a cross compiler), it is reasonable to use the
+result of @file{config.guess} as the default for the host system when
+the @samp{--host} option is not used.
+
+It might seem that if the @samp{--host} option were used without the
+@samp{--build} option that the configure script could run
+@file{config.guess} to determine the build system, and presume a
+Canadian Cross if the result of @file{config.guess} differed from the
+@samp{--host} option. However, for historical reasons, some configure
+scripts are routinely run using an explicit @samp{--host} option, rather
+than using the default from @file{config.guess}. As noted earlier, it
+is difficult or impossible to reliably compare configuration names
+(@pxref{Using the Target Type}). Therefore, by convention, if the
+@samp{--host} option is used, but the @samp{--build} option is not used,
+then the build system defaults to the host system.
+
+@node CCross not in Cygnus Tree
+@section Canadian Cross not in Cygnus Tree.
+
+If you are not using the Cygnus tree, you must explicitly specify the
+cross tools which you want to use to build the program. This is done by
+setting environment variables before running the @file{configure}
+script.
+
+You must normally set at least the environment variables @samp{CC},
+@samp{AR}, and @samp{RANLIB} to the cross tools which you want to use to
+build.
+
+For some programs, you must set additional cross tools as well, such as
+@samp{AS}, @samp{LD}, or @samp{NM}.
+
+You would set these environment variables to the build cross tools which
+you are going to use.
+
+For example, if you are building a Solaris program on a GNU/Linux
+system, and your GNU/Linux cross Solaris compiler were named
+@samp{solaris-gcc}, then you would set the environment variable
+@samp{CC} to @samp{solaris-gcc}.
+
+@node CCross in Cygnus Tree
+@section Canadian Cross in Cygnus Tree
+@cindex canadian cross in cygnus tree
+
+This section describes configuring and building a Canadian Cross when
+using the Cygnus tree.
+
+@menu
+* Standard Cygnus CCross:: Building a Normal Program.
+* Cross Cygnus CCross:: Building a Cross Program.
+@end menu
+
+@node Standard Cygnus CCross
+@subsection Building a Normal Program
+
+When configuring a Canadian Cross in the Cygnus tree, all the
+appropriate environment variables are automatically set to
+@samp{@var{host}-@var{tool}}, where @var{host} is the value used for the
+@samp{--host} option, and @var{tool} is the name of the tool (e.g.,
+@samp{gcc}, @samp{as}, etc.). These tools must be on your @samp{PATH}.
+
+Adding a prefix of @var{host} will give the usual name for the build
+cross host tools. To see this, consider that when these cross tools
+were built, they were configured to run on the build system and to
+produce code for the host system. That is, they were configured with a
+@samp{--target} option that is the same as the system which we are now
+calling the host. Recall that the default name for installed cross
+tools uses the target system as a prefix (@pxref{Using the Target
+Type}). Since that is the system which we are now calling the host,
+@var{host} is the right prefix to use.
+
+For example, if you configure with @samp{--build=i386-linux-gnu} and
+@samp{--host=solaris}, then the Cygnus tree will automatically default
+to using the compiler @samp{solaris-gcc}. You must have previously
+built and installed this compiler, probably by doing a build with no
+@samp{--host} option and with a @samp{--target} option of
+@samp{solaris}.
+
+@node Cross Cygnus CCross
+@subsection Building a Cross Program
+
+There are additional considerations if you want to build a cross
+compiler, rather than a native compiler, in the Cygnus tree using a
+Canadian Cross.
+
+When you build a cross compiler using the Cygnus tree, then the target
+libraries will normally be built with the newly built target compiler
+(@pxref{Host and Target Libraries}). However, this will not work when
+building with a Canadian Cross. This is because the newly built target
+compiler will be a program which runs on the host system, and therefore
+will not be able to run on the build system.
+
+Therefore, when building a cross compiler with the Cygnus tree, you must
+first install a set of build cross target tools. These tools will be
+used when building the target libraries.
+
+Note that this is not a requirement of a Canadian Cross in general. For
+example, it would be possible to build just the host cross target tools
+on the build system, to copy the tools to the host system, and to build
+the target libraries on the host system. The requirement for build
+cross target tools is imposed by the Cygnus tree, which expects to be
+able to build both host programs and target libraries in a single
+@samp{configure}/@samp{make} step. Because it builds these in a single
+step, it expects to be able to build the target libraries on the build
+system, which means that it must use a build cross target toolchain.
+
+For example, suppose you want to build a Windows cross MIPS ELF compiler
+on a GNU/Linux system. You must have previously installed both a
+GNU/Linux cross Windows compiler and a GNU/Linux cross MIPS ELF
+compiler.
+
+In order to build the Windows (configuration name @samp{i386-cygwin32})
+cross MIPS ELF (configure name @samp{mips-elf}) compiler, you might
+execute the following commands (long command lines are broken across
+lines with a trailing backslash as a continuation character).
+
+@example
+mkdir linux-x-cygwin32
+cd linux-x-cygwin32
+@var{srcdir}/configure --target i386-cygwin32 --prefix=@var{installdir} \
+ --exec-prefix=@var{installdir}/H-i386-linux
+make
+make install
+cd ..
+mkdir linux-x-mips-elf
+cd linux-x-mips-elf
+@var{srcdir}/configure --target mips-elf --prefix=@var{installdir} \
+ --exec-prefix=@var{installdir}/H-i386-linux
+make
+make install
+cd ..
+mkdir cygwin32-x-mips-elf
+cd cygwin32-x-mips-elf
+@var{srcdir}/configure --build=i386-linux-gnu --host=i386-cygwin32 \
+ --target=mips-elf --prefix=@var{wininstalldir} \
+ --exec-prefix=@var{wininstalldir}/H-i386-cygwin32
+make
+make install
+@end example
+
+You would then copy the contents of @var{wininstalldir} over to the
+Windows machine, and run the resulting programs.
+
+@node Supporting Canadian Cross
+@section Supporting Canadian Cross
+
+If you want to make it possible to build a program you are developing
+using a Canadian Cross, you must take some care when writing your
+configure and make rules. Simple cases will normally work correctly.
+However, it is not hard to write configure and make tests which will
+fail in a Canadian Cross.
+
+@menu
+* CCross in Configure:: Supporting Canadian Cross in Configure Scripts.
+* CCross in Make:: Supporting Canadian Cross in Makefiles.
+@end menu
+
+@node CCross in Configure
+@subsection Supporting Canadian Cross in Configure Scripts
+@cindex canadian cross in configure
+
+In a @file{configure.in} file, after calling @samp{AC_PROG_CC}, you can
+find out whether this is a Canadian Cross configure by examining the
+shell variable @samp{cross_compiling}. In a Canadian Cross, which means
+that the compiler is a cross compiler, @samp{cross_compiling} will be
+@samp{yes}. In a normal configuration, @samp{cross_compiling} will be
+@samp{no}.
+
+You ordinarily do not need to know the type of the build system in a
+configure script. However, if you do need that information, you can get
+it by using the macro @samp{AC_CANONICAL_SYSTEM}, the same macro that is
+used to determine the target system. This macro will set the variables
+@samp{build}, @samp{build_alias}, @samp{build_cpu}, @samp{build_vendor},
+and @samp{build_os}, which correspond to the similar @samp{target} and
+@samp{host} variables, except that they describe the build system.
+
+When writing tests in @file{configure.in}, you must remember that you
+want to test the host environment, not the build environment.
+
+Macros like @samp{AC_CHECK_FUNCS} which use the compiler will test the
+host environment. That is because the tests will be done by running the
+compiler, which is actually a build cross host compiler. If the
+compiler can find the function, that means that the function is present
+in the host environment.
+
+Tests like @samp{test -f /dev/ptyp0}, on the other hand, will test the
+build environment. Remember that the configure script is running on the
+build system, not the host system. If your configure scripts examines
+files, those files will be on the build system. Whatever you determine
+based on those files may or may not be the case on the host system.
+
+Most autoconf macros will work correctly for a Canadian Cross. The main
+exception is @samp{AC_TRY_RUN}. This macro tries to compile and run a
+test program. This will fail in a Canadian Cross, because the program
+will be compiled for the host system, which means that it will not run
+on the build system.
+
+The @samp{AC_TRY_RUN} macro provides an optional argument to tell the
+configure script what to do in a Canadian Cross. If that argument is
+not present, you will get a warning when you run @samp{autoconf}:
+@smallexample
+warning: AC_TRY_RUN called without default to allow cross compiling
+@end smallexample
+@noindent
+This tells you that the resulting @file{configure} script will not work
+with a Canadian Cross.
+
+In some cases while it may better to perform a test at configure time,
+it is also possible to perform the test at run time. In such a case you
+can use the cross compiling argument to @samp{AC_TRY_RUN} to tell your
+program that the test could not be performed at configure time.
+
+There are a few other autoconf macros which will not work correctly with
+a Canadian Cross: a partial list is @samp{AC_FUNC_GETPGRP},
+@samp{AC_FUNC_SETPGRP}, @samp{AC_FUNC_SETVBUF_REVERSED}, and
+@samp{AC_SYS_RESTARTABLE_SYSCALLS}. The @samp{AC_CHECK_SIZEOF} macro is
+generally not very useful with a Canadian Cross; it permits an optional
+argument indicating the default size, but there is no way to know what
+the correct default should be.
+
+@node CCross in Make
+@subsection Supporting Canadian Cross in Makefiles.
+@cindex canadian cross in makefile
+
+The main Canadian Cross issue in a @file{Makefile} arises when you want
+to use a subsidiary program to generate code or data which you will then
+include in your real program.
+
+If you compile this subsidiary program using @samp{$(CC)} in the usual
+way, you will not be able to run it. This is because @samp{$(CC)} will
+build a program for the host system, but the program is being built on
+the build system.
+
+You must instead use a compiler for the build system, rather than the
+host system. In the Cygnus tree, this make variable
+@samp{$(CC_FOR_BUILD)} will hold a compiler for the build system.
+
+Note that you should not include @file{config.h} in a file you are
+compiling with @samp{$(CC_FOR_BUILD)}. The @file{configure} script will
+build @file{config.h} with information for the host system. However,
+you are compiling the file using a compiler for the build system (a
+native compiler). Subsidiary programs are normally simple filters which
+do no user interaction, and it is normally possible to write them in a
+highly portable fashion so that the absence of @file{config.h} is not
+crucial.
+
+@cindex @samp{HOST_CC}
+The gcc @file{Makefile.in} shows a complex situation in which certain
+files, such as @file{rtl.c}, must be compiled into both subsidiary
+programs run on the build system and into the final program. This
+approach may be of interest for advanced build system hackers. Note
+that the build system compiler is rather confusingly called
+@samp{HOST_CC}.
+
+@node Cygnus Configure
+@chapter Cygnus Configure
+@cindex cygnus configure
+
+The Cygnus configure script predates autoconf. All of its interesting
+features have been incorporated into autoconf. No new programs should
+be written to use the Cygnus configure script.
+
+However, the Cygnus configure script is still used in a few places: at
+the top of the Cygnus tree and in a few target libraries in the Cygnus
+tree. Until those uses have been replaced with autoconf, some brief
+notes are appropriate here. This is not complete documentation, but it
+should be possible to use this as a guide while examining the scripts
+themselves.
+
+@menu
+* Cygnus Configure Basics:: Cygnus Configure Basics.
+* Cygnus Configure in C++ Libraries:: Cygnus Configure in C++ Libraries.
+@end menu
+
+@node Cygnus Configure Basics
+@section Cygnus Configure Basics
+
+Cygnus configure does not use any generated files; there is no program
+corresponding to @samp{autoconf}. Instead, there is a single shell
+script named @samp{configure} which may be found at the top of the
+Cygnus tree. This shell script was written by hand; it was not
+generated by autoconf, and it is incorrect, and indeed harmful, to run
+@samp{autoconf} in the top level of a Cygnus tree.
+
+Cygnus configure works in a particular directory by examining the file
+@file{configure.in} in that directory. That file is broken into four
+separate shell scripts.
+
+The first is the contents of @file{configure.in} up to a line that
+starts with @samp{# per-host:}. This is the common part.
+
+The second is the rest of @file{configure.in} up to a line that starts
+with @samp{# per-target:}. This is the per host part.
+
+The third is the rest of @file{configure.in} up to a line that starts
+with @samp{# post-target:}. This is the per target part.
+
+The fourth is the remainder of @file{configure.in}. This is the post
+target part.
+
+If any of these comment lines are missing, the corresponding shell
+script is empty.
+
+Cygnus configure will first execute the common part. This must set the
+shell variable @samp{srctrigger} to the name of a source file, to
+confirm that Cygnus configure is looking at the right directory. This
+may set the shell variables @samp{package_makefile_frag} and
+@samp{package_makefile_rules_frag}.
+
+Cygnus configure will next set the @samp{build} and @samp{host} shell
+variables, and execute the per host part. This may set the shell
+variable @samp{host_makefile_frag}.
+
+Cygnus configure will next set the @samp{target} variable, and execute
+the per target part. This may set the shell variable
+@samp{target_makefile_frag}.
+
+Any of these scripts may set the @samp{subdirs} shell variable. This
+variable is a list of subdirectories where a @file{Makefile.in} file may
+be found. Cygnus configure will automatically look for a
+@file{Makefile.in} file in the current directory. The @samp{subdirs}
+shell variable is not normally used, and I believe that the only
+directory which uses it at present is @file{newlib}.
+
+For each @file{Makefile.in}, Cygnus configure will automatically create
+a @file{Makefile} by adding definitions for @samp{make} variables such
+as @samp{host} and @samp{target}, and automatically editing the values
+of @samp{make} variables such as @samp{prefix} if they are present.
+
+Also, if any of the @samp{makefile_frag} shell variables are set, Cygnus
+configure will interpret them as file names relative to either the
+working directory or the source directory, and will read the contents of
+the file into the generated @file{Makefile}. The file contents will be
+read in after the first line in @file{Makefile.in} which starts with
+@samp{####}.
+
+These @file{Makefile} fragments are used to customize behaviour for a
+particular host or target. They serve to select particular files to
+compile, and to define particular preprocessor macros by providing
+values for @samp{make} variables which are then used during compilation.
+Cygnus configure, unlike autoconf, normally does not do feature tests,
+and normally requires support to be added manually for each new host.
+
+The @file{Makefile} fragment support is similar to the autoconf
+@samp{AC_SUBST_FILE} macro.
+
+After creating each @file{Makefile}, the post target script will be run
+(i.e., it may be run several times). This script may further customize
+the @file{Makefile}. When it is run, the shell variable @samp{Makefile}
+will hold the name of the @file{Makefile}, including the appropriate
+directory component.
+
+Like an autoconf generated @file{configure} script, Cygnus configure
+will create a file named @file{config.status} which, when run, will
+automatically recreate the configuration. The @file{config.status} file
+will simply execute the Cygnus configure script again with the
+appropriate arguments.
+
+Any of the parts of @file{configure.in} may set the shell variables
+@samp{files} and @samp{links}. Cygnus configure will set up symlinks
+from the names in @samp{links} to the files named in @samp{files}. This
+is similar to the autoconf @samp{AC_LINK_FILES} macro.
+
+Finally, any of the parts of @file{configure.in} may set the shell
+variable @samp{configdirs} to a set of subdirectories. If it is set,
+Cygnus configure will recursively run the configure process in each
+subdirectory. If the subdirectory uses Cygnus configure, it will
+contain a @file{configure.in} file but no @file{configure} file, in
+which case Cygnus configure will invoke itself recursively. If the
+subdirectory has a @file{configure} file, Cygnus configure assumes that
+it is an autoconf generated @file{configure} script, and simply invokes
+it directly.
+
+@node Cygnus Configure in C++ Libraries
+@section Cygnus Configure in C++ Libraries
+@cindex @file{libstdc++} configure
+@cindex @file{libio} configure
+@cindex @file{libg++} configure
+
+The C++ library configure system, written by Per Bothner, deserves
+special mention. It uses Cygnus configure, but it does feature testing
+like that done by autoconf generated @file{configure} scripts. This
+approach is used in the libraries @file{libio}, @file{libstdc++}, and
+@file{libg++}.
+
+Most of the @file{Makefile} information is written out by the shell
+script @file{libio/config.shared}. Each @file{configure.in} file sets
+certain shell variables, and then invokes @file{config.shared} to create
+two package @file{Makefile} fragments. These fragments are then
+incorporated into the resulting @file{Makefile} by the Cygnus configure
+script.
+
+The file @file{_G_config.h} is created in the @file{libio} object
+directory by running the shell script @file{libio/gen-params}. This
+shell script uses feature tests to define macros and typedefs in
+@file{_G_config.h}.
+
+@node Multilibs
+@chapter Multilibs
+@cindex multilibs
+
+For some targets gcc may have different processor requirements depending
+upon command line options. An obvious example is the
+@samp{-msoft-float} option supported on several processors. This option
+means that the floating point registers are not available, which means
+that floating point operations must be done by calling an emulation
+subroutine rather than by using machine instructions.
+
+For such options, gcc is often configured to compile target libraries
+twice: once with @samp{-msoft-float} and once without. When gcc
+compiles target libraries more than once, the resulting libraries are
+called @dfn{multilibs}.
+
+Multilibs are not really part of the GNU configure and build system, but
+we discuss them here since they require support in the @file{configure}
+scripts and @file{Makefile}s used for target libraries.
+
+@menu
+* Multilibs in gcc:: Multilibs in gcc.
+* Multilibs in Target Libraries:: Multilibs in Target Libraries.
+@end menu
+
+@node Multilibs in gcc
+@section Multilibs in gcc
+
+In gcc, multilibs are defined by setting the variable
+@samp{MULTILIB_OPTIONS} in the target @file{Makefile} fragment. Several
+other @samp{MULTILIB} variables may also be defined there. @xref{Target
+Fragment, , The Target Makefile Fragment, gcc, Using and Porting GNU
+CC}.
+
+If you have built gcc, you can see what multilibs it uses by running it
+with the @samp{-print-multi-lib} option. The output @samp{.;} means
+that no multilibs are used. In general, the output is a sequence of
+lines, one per multilib. The first part of each line, up to the
+@samp{;}, is the name of the multilib directory. The second part is a
+list of compiler options separated by @samp{@@} characters.
+
+Multilibs are built in a tree of directories. The top of the tree,
+represented by @samp{.} in the list of multilib directories, is the
+default library to use when no special compiler options are used. The
+subdirectories of the tree hold versions of the library to use when
+particular compiler options are used.
+
+@node Multilibs in Target Libraries
+@section Multilibs in Target Libraries
+
+The target libraries in the Cygnus tree are automatically built with
+multilibs. That means that each library is built multiple times.
+
+This default is set in the top level @file{configure.in} file, by adding
+@samp{--enable-multilib} to the list of arguments passed to configure
+when it is run for the target libraries (@pxref{Host and Target
+Libraries}).
+
+Each target library uses the shell script @file{config-ml.in}, written
+by Doug Evans, to prepare to build target libraries. This shell script
+is invoked after the @file{Makefile} has been created by the
+@file{configure} script. If multilibs are not enabled, it does nothing,
+otherwise it modifies the @file{Makefile} to support multilibs.
+
+The @file{config-ml.in} script makes one copy of the @file{Makefile} for
+each multilib in the appropriate subdirectory. When configuring in the
+source directory (which is not recommended), it will build a symlink
+tree of the sources in each subdirectory.
+
+The @file{config-ml.in} script sets several variables in the various
+@file{Makefile}s. The @file{Makefile.in} must have definitions for
+these variables already; @file{config-ml.in} simply changes the existing
+values. The @file{Makefile} should use default values for these
+variables which will do the right thing in the subdirectories.
+
+@table @samp
+@item MULTISRCTOP
+@file{config-ml.in} will set this to a sequence of @samp{../} strings,
+where the number of strings is the number of multilib levels in the
+source tree. The default value should be the empty string.
+@item MULTIBUILDTOP
+@file{config-ml.in} will set this to a sequence of @samp{../} strings,
+where the number of strings is number of multilib levels in the object
+directory. The default value should be the empty string. This will
+differ from @samp{MULTISRCTOP} when configuring in the source tree
+(which is not recommended).
+@item MULTIDIRS
+In the top level @file{Makefile} only, @file{config-ml.in} will set this
+to the list of multilib subdirectories. The default value should be the
+empty string.
+@item MULTISUBDIR
+@file{config-ml.in} will set this to the installed subdirectory name to
+use for this subdirectory, with a leading @samp{/}. The default value
+shold be the empty string.
+@item MULTIDO
+@itemx MULTICLEAN
+In the top level @file{Makefile} only, @file{config-ml.in} will set
+these variables to commands to use when doing a recursive make. These
+variables should both default to the string @samp{true}, so that by
+default nothing happens.
+@end table
+
+All references to the parent of the source directory should use the
+variable @samp{MULTISRCTOP}. Instead of writing @samp{$(srcdir)/..},
+you must write @samp{$(srcdir)/$(MULTISRCTOP)..}.
+
+Similarly, references to the parent of the object directory should use
+the variable @samp{MULTIBUILDTOP}.
+
+In the installation target, the libraries should be installed in the
+subdirectory @samp{MULTISUBDIR}. Instead of installing
+@samp{$(libdir)/libfoo.a}, install
+@samp{$(libdir)$(MULTISUBDIR)/libfoo.a}.
+
+The @file{config-ml.in} script also modifies the top level
+@file{Makefile} to add @samp{multi-do} and @samp{multi-clean} targets
+which are used when building multilibs.
+
+The default target of the @file{Makefile} should include the following
+command:
+@smallexample
+@@$(MULTIDO) $(FLAGS_TO_PASS) DO=all multi-do
+@end smallexample
+@noindent
+This assumes that @samp{$(FLAGS_TO_PASS)} is defined as a set of
+variables to pass to a recursive invocation of @samp{make}. This will
+build all the multilibs. Note that the default value of @samp{MULTIDO}
+is @samp{true}, so by default this command will do nothing. It will
+only do something in the top level @file{Makefile} if multilibs were
+enabled.
+
+The @samp{install} target of the @file{Makefile} should include the
+following command:
+@smallexample
+@@$(MULTIDO) $(FLAGS_TO_PASS) DO=install multi-do
+@end smallexample
+
+In general, any operation, other than clean, which should be performed
+on all the multilibs should use a @samp{$(MULTIDO)} line, setting the
+variable @samp{DO} to the target of each recursive call to @samp{make}.
+
+The @samp{clean} targets (@samp{clean}, @samp{mostlyclean}, etc.) should
+use @samp{$(MULTICLEAN)}. For example, the @samp{clean} target should
+do this:
+@smallexample
+@@$(MULTICLEAN) DO=clean multi-clean
+@end smallexample
+
+@node FAQ
+@chapter Frequently Asked Questions
+
+@table @asis
+@item Which do I run first, @samp{autoconf} or @samp{automake}?
+Except when you first add autoconf or automake support to a package, you
+shouldn't run either by hand. Instead, configure with the
+@samp{--enable-maintainer-mode} option, and let @samp{make} take care of
+it.
+
+@cindex undefined macros
+@item @samp{autoconf} says something about undefined macros.
+This means that you have macros in your @file{configure.in} which are
+not defined by @samp{autoconf}. You may be using an old version of
+@samp{autoconf}; try building and installing a newer one. Make sure the
+newly installled @samp{autoconf} is first on your @samp{PATH}. Also,
+see the next question.
+
+@cindex @samp{CY_GNU_GETTEXT} in @file{configure}
+@cindex @samp{AM_PROG_LIBTOOL} in @file{configure}
+@item My @file{configure} script has stuff like @samp{CY_GNU_GETTEXT} in it.
+This means that you have macros in your @file{configure.in} which should
+be defined in your @file{aclocal.m4} file, but aren't. This usually
+means that @samp{aclocal} was not able to appropriate definitions of the
+macros. Make sure that you have installed all the packages you need.
+In particular, make sure that you have installed libtool (this is where
+@samp{AM_PROG_LIBTOOL} is defined) and gettext (this is where
+@samp{CY_GNU_GETTEXT} is defined, at least in the Cygnus version of
+gettext).
+
+@cindex @file{Makefile}, garbage characters
+@item My @file{Makefile} has @samp{@@} characters in it.
+This may mean that you tried to use an autoconf substitution in your
+@file{Makefile.in} without adding the appropriate @samp{AC_SUBST} call
+to your @file{configure} script. Or it may just mean that you need to
+rebuild @file{Makefile} in your build directory. To rebuild
+@file{Makefile} from @file{Makefile.in}, run the shell script
+@file{config.status} with no arguments. If you need to force
+@file{configure} to run again, first run @samp{config.status --recheck}.
+These runs are normally done automatically by @file{Makefile} targets,
+but if your @file{Makefile} has gotten messed up you'll need to help
+them along.
+
+@cindex @samp{config.status --recheck}
+@item Why do I have to run both @samp{config.status --recheck} and @samp{config.status}?
+Normally, you don't; they will be run automatically by @file{Makefile}
+targets. If you do need to run them, use @samp{config.status --recheck}
+to run the @file{configure} script again with the same arguments as the
+first time you ran it. Use @samp{config.status} (with no arguments) to
+regenerate all files (@file{Makefile}, @file{config.h}, etc.) based on
+the results of the configure script. The two cases are separate because
+it isn't always necessary to regenerate all the files after running
+@samp{config.status --recheck}. The @file{Makefile} targets generated
+by automake will use the environment variables @samp{CONFIG_FILES} and
+@samp{CONFIG_HEADERS} to only regenerate files as they are needed.
+
+@item What is the Cygnus tree?
+The Cygnus tree is used for various packages including gdb, the GNU
+binutils, and egcs. It is also, of course, used for Cygnus releases.
+It is the build system which was developed at Cygnus, using the Cygnus
+configure script. It permits building many different packages with a
+single configure and make. The configure scripts in the tree are being
+converted to autoconf, but the general build structure remains intact.
+
+@item Why do I have to keep rebuilding and reinstalling the tools?
+I know, it's a pain. Unfortunately, there are bugs in the tools
+themselves which need to be fixed, and each time that happens everybody
+who uses the tools need to reinstall new versions of them. I don't know
+if there is going to be a clever fix until the tools stabilize.
+
+@item Why not just have a Cygnus tree @samp{make} target to update the tools?
+The tools unfortunately need to be installed before they can be used.
+That means that they must be built using an appropriate prefix, and it
+seems unwise to assume that every configuration uses an appropriate
+prefix. It might be possible to make them work in place, or it might be
+possible to install them in some subdirectory; so far these approaches
+have not been implemented.
+@end table
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/etc/make-stds.texi b/etc/make-stds.texi
new file mode 100644
index 00000000000..2149764b8e9
--- /dev/null
+++ b/etc/make-stds.texi
@@ -0,0 +1,914 @@
+@comment This file is included by both standards.texi and make.texinfo.
+@comment It was broken out of standards.texi on 1/6/93 by roland.
+
+@node Makefile Conventions
+@chapter Makefile Conventions
+@comment standards.texi does not print an index, but make.texinfo does.
+@cindex makefile, conventions for
+@cindex conventions for makefiles
+@cindex standards for makefiles
+
+This
+@ifinfo
+node
+@end ifinfo
+@iftex
+@ifset CODESTD
+section
+@end ifset
+@ifclear CODESTD
+chapter
+@end ifclear
+@end iftex
+describes conventions for writing the Makefiles for GNU programs.
+
+@menu
+* Makefile Basics:: General Conventions for Makefiles
+* Utilities in Makefiles:: Utilities in Makefiles
+* Command Variables:: Variables for Specifying Commands
+* Directory Variables:: Variables for Installation Directories
+* Standard Targets:: Standard Targets for Users
+* Install Command Categories:: Three categories of commands in the `install'
+ rule: normal, pre-install and post-install.
+@end menu
+
+@node Makefile Basics
+@section General Conventions for Makefiles
+
+Every Makefile should contain this line:
+
+@example
+SHELL = /bin/sh
+@end example
+
+@noindent
+to avoid trouble on systems where the @code{SHELL} variable might be
+inherited from the environment. (This is never a problem with GNU
+@code{make}.)
+
+Different @code{make} programs have incompatible suffix lists and
+implicit rules, and this sometimes creates confusion or misbehavior. So
+it is a good idea to set the suffix list explicitly using only the
+suffixes you need in the particular Makefile, like this:
+
+@example
+.SUFFIXES:
+.SUFFIXES: .c .o
+@end example
+
+@noindent
+The first line clears out the suffix list, the second introduces all
+suffixes which may be subject to implicit rules in this Makefile.
+
+Don't assume that @file{.} is in the path for command execution. When
+you need to run programs that are a part of your package during the
+make, please make sure that it uses @file{./} if the program is built as
+part of the make or @file{$(srcdir)/} if the file is an unchanging part
+of the source code. Without one of these prefixes, the current search
+path is used.
+
+The distinction between @file{./} (the @dfn{build directory}) and
+@file{$(srcdir)/} (the @dfn{source directory}) is important because
+users can build in a separate directory using the @samp{--srcdir} option
+to @file{configure}. A rule of the form:
+
+@smallexample
+foo.1 : foo.man sedscript
+ sed -e sedscript foo.man > foo.1
+@end smallexample
+
+@noindent
+will fail when the build directory is not the source directory, because
+@file{foo.man} and @file{sedscript} are in the the source directory.
+
+When using GNU @code{make}, relying on @samp{VPATH} to find the source
+file will work in the case where there is a single dependency file,
+since the @code{make} automatic variable @samp{$<} will represent the
+source file wherever it is. (Many versions of @code{make} set @samp{$<}
+only in implicit rules.) A Makefile target like
+
+@smallexample
+foo.o : bar.c
+ $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
+@end smallexample
+
+@noindent
+should instead be written as
+
+@smallexample
+foo.o : bar.c
+ $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@
+@end smallexample
+
+@noindent
+in order to allow @samp{VPATH} to work correctly. When the target has
+multiple dependencies, using an explicit @samp{$(srcdir)} is the easiest
+way to make the rule work well. For example, the target above for
+@file{foo.1} is best written as:
+
+@smallexample
+foo.1 : foo.man sedscript
+ sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@
+@end smallexample
+
+GNU distributions usually contain some files which are not source
+files---for example, Info files, and the output from Autoconf, Automake,
+Bison or Flex. Since these files normally appear in the source
+directory, they should always appear in the source directory, not in the
+build directory. So Makefile rules to update them should put the
+updated files in the source directory.
+
+However, if a file does not appear in the distribution, then the
+Makefile should not put it in the source directory, because building a
+program in ordinary circumstances should not modify the source directory
+in any way.
+
+Try to make the build and installation targets, at least (and all their
+subtargets) work correctly with a parallel @code{make}.
+
+@node Utilities in Makefiles
+@section Utilities in Makefiles
+
+Write the Makefile commands (and any shell scripts, such as
+@code{configure}) to run in @code{sh}, not in @code{csh}. Don't use any
+special features of @code{ksh} or @code{bash}.
+
+The @code{configure} script and the Makefile rules for building and
+installation should not use any utilities directly except these:
+
+@c dd find
+@c gunzip gzip md5sum
+@c mkfifo mknod tee uname
+
+@example
+cat cmp cp diff echo egrep expr false grep install-info
+ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true
+@end example
+
+The compression program @code{gzip} can be used in the @code{dist} rule.
+
+Stick to the generally supported options for these programs. For
+example, don't use @samp{mkdir -p}, convenient as it may be, because
+most systems don't support it.
+
+It is a good idea to avoid creating symbolic links in makefiles, since a
+few systems don't support them.
+
+The Makefile rules for building and installation can also use compilers
+and related programs, but should do so via @code{make} variables so that the
+user can substitute alternatives. Here are some of the programs we
+mean:
+
+@example
+ar bison cc flex install ld ldconfig lex
+make makeinfo ranlib texi2dvi yacc
+@end example
+
+Use the following @code{make} variables to run those programs:
+
+@example
+$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)
+$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
+@end example
+
+When you use @code{ranlib} or @code{ldconfig}, you should make sure
+nothing bad happens if the system does not have the program in question.
+Arrange to ignore an error from that command, and print a message before
+the command to tell the user that failure of this command does not mean
+a problem. (The Autoconf @samp{AC_PROG_RANLIB} macro can help with
+this.)
+
+If you use symbolic links, you should implement a fallback for systems
+that don't have symbolic links.
+
+Additional utilities that can be used via Make variables are:
+
+@example
+chgrp chmod chown mknod
+@end example
+
+It is ok to use other utilities in Makefile portions (or scripts)
+intended only for particular systems where you know those utilities
+exist.
+
+@node Command Variables
+@section Variables for Specifying Commands
+
+Makefiles should provide variables for overriding certain commands, options,
+and so on.
+
+In particular, you should run most utility programs via variables.
+Thus, if you use Bison, have a variable named @code{BISON} whose default
+value is set with @samp{BISON = bison}, and refer to it with
+@code{$(BISON)} whenever you need to use Bison.
+
+File management utilities such as @code{ln}, @code{rm}, @code{mv}, and
+so on, need not be referred to through variables in this way, since users
+don't need to replace them with other programs.
+
+Each program-name variable should come with an options variable that is
+used to supply options to the program. Append @samp{FLAGS} to the
+program-name variable name to get the options variable name---for
+example, @code{BISONFLAGS}. (The names @code{CFLAGS} for the C
+compiler, @code{YFLAGS} for yacc, and @code{LFLAGS} for lex, are
+exceptions to this rule, but we keep them because they are standard.)
+Use @code{CPPFLAGS} in any compilation command that runs the
+preprocessor, and use @code{LDFLAGS} in any compilation command that
+does linking as well as in any direct use of @code{ld}.
+
+If there are C compiler options that @emph{must} be used for proper
+compilation of certain files, do not include them in @code{CFLAGS}.
+Users expect to be able to specify @code{CFLAGS} freely themselves.
+Instead, arrange to pass the necessary options to the C compiler
+independently of @code{CFLAGS}, by writing them explicitly in the
+compilation commands or by defining an implicit rule, like this:
+
+@smallexample
+CFLAGS = -g
+ALL_CFLAGS = -I. $(CFLAGS)
+.c.o:
+ $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
+@end smallexample
+
+Do include the @samp{-g} option in @code{CFLAGS}, because that is not
+@emph{required} for proper compilation. You can consider it a default
+that is only recommended. If the package is set up so that it is
+compiled with GCC by default, then you might as well include @samp{-O}
+in the default value of @code{CFLAGS} as well.
+
+Put @code{CFLAGS} last in the compilation command, after other variables
+containing compiler options, so the user can use @code{CFLAGS} to
+override the others.
+
+@code{CFLAGS} should be used in every invocation of the C compiler,
+both those which do compilation and those which do linking.
+
+Every Makefile should define the variable @code{INSTALL}, which is the
+basic command for installing a file into the system.
+
+Every Makefile should also define the variables @code{INSTALL_PROGRAM}
+and @code{INSTALL_DATA}. (The default for each of these should be
+@code{$(INSTALL)}.) Then it should use those variables as the commands
+for actual installation, for executables and nonexecutables
+respectively. Use these variables as follows:
+
+@example
+$(INSTALL_PROGRAM) foo $(bindir)/foo
+$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
+@end example
+
+Optionally, you may prepend the value of @code{DESTDIR} to the target
+filename. Doing this allows the installer to create a snapshot of the
+installation to be copied onto the real target filesystem later. Do not
+set the value of @code{DESTDIR} in your Makefile, and do not include it
+in any installed files. With support for @code{DESTDIR}, the above
+examples become:
+
+@example
+$(INSTALL_PROGRAM) foo $(DESTDIR)$(bindir)/foo
+$(INSTALL_DATA) libfoo.a $(DESTDIR)$(libdir)/libfoo.a
+@end example
+
+@noindent
+Always use a file name, not a directory name, as the second argument of
+the installation commands. Use a separate command for each file to be
+installed.
+
+@node Directory Variables
+@section Variables for Installation Directories
+
+Installation directories should always be named by variables, so it is
+easy to install in a nonstandard place. The standard names for these
+variables are described below. They are based on a standard filesystem
+layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and
+other modern operating systems.
+
+These two variables set the root for the installation. All the other
+installation directories should be subdirectories of one of these two,
+and nothing should be directly installed into these two directories.
+
+@table @samp
+@item prefix
+A prefix used in constructing the default values of the variables listed
+below. The default value of @code{prefix} should be @file{/usr/local}.
+When building the complete GNU system, the prefix will be empty and
+@file{/usr} will be a symbolic link to @file{/}.
+(If you are using Autoconf, write it as @samp{@@prefix@@}.)
+
+Running @samp{make install} with a different value of @code{prefix}
+from the one used to build the program should @var{not} recompile
+the program.
+
+@item exec_prefix
+A prefix used in constructing the default values of some of the
+variables listed below. The default value of @code{exec_prefix} should
+be @code{$(prefix)}.
+(If you are using Autoconf, write it as @samp{@@exec_prefix@@}.)
+
+Generally, @code{$(exec_prefix)} is used for directories that contain
+machine-specific files (such as executables and subroutine libraries),
+while @code{$(prefix)} is used directly for other directories.
+
+Running @samp{make install} with a different value of @code{exec_prefix}
+from the one used to build the program should @var{not} recompile the
+program.
+@end table
+
+Executable programs are installed in one of the following directories.
+
+@table @samp
+@item bindir
+The directory for installing executable programs that users can run.
+This should normally be @file{/usr/local/bin}, but write it as
+@file{$(exec_prefix)/bin}.
+(If you are using Autoconf, write it as @samp{@@bindir@@}.)
+
+@item sbindir
+The directory for installing executable programs that can be run from
+the shell, but are only generally useful to system administrators. This
+should normally be @file{/usr/local/sbin}, but write it as
+@file{$(exec_prefix)/sbin}.
+(If you are using Autoconf, write it as @samp{@@sbindir@@}.)
+
+@item libexecdir
+@comment This paragraph adjusted to avoid overfull hbox --roland 5jul94
+The directory for installing executable programs to be run by other
+programs rather than by users. This directory should normally be
+@file{/usr/local/libexec}, but write it as @file{$(exec_prefix)/libexec}.
+(If you are using Autoconf, write it as @samp{@@libexecdir@@}.)
+@end table
+
+Data files used by the program during its execution are divided into
+categories in two ways.
+
+@itemize @bullet
+@item
+Some files are normally modified by programs; others are never normally
+modified (though users may edit some of these).
+
+@item
+Some files are architecture-independent and can be shared by all
+machines at a site; some are architecture-dependent and can be shared
+only by machines of the same kind and operating system; others may never
+be shared between two machines.
+@end itemize
+
+This makes for six different possibilities. However, we want to
+discourage the use of architecture-dependent files, aside from object
+files and libraries. It is much cleaner to make other data files
+architecture-independent, and it is generally not hard.
+
+Therefore, here are the variables Makefiles should use to specify
+directories:
+
+@table @samp
+@item datadir
+The directory for installing read-only architecture independent data
+files. This should normally be @file{/usr/local/share}, but write it as
+@file{$(prefix)/share}.
+(If you are using Autoconf, write it as @samp{@@datadir@@}.)
+As a special exception, see @file{$(infodir)}
+and @file{$(includedir)} below.
+
+@item sysconfdir
+The directory for installing read-only data files that pertain to a
+single machine--that is to say, files for configuring a host. Mailer
+and network configuration files, @file{/etc/passwd}, and so forth belong
+here. All the files in this directory should be ordinary ASCII text
+files. This directory should normally be @file{/usr/local/etc}, but
+write it as @file{$(prefix)/etc}.
+(If you are using Autoconf, write it as @samp{@@sysconfdir@@}.)
+
+Do not install executables here in this directory (they probably belong
+in @file{$(libexecdir)} or @file{$(sbindir)}). Also do not install
+files that are modified in the normal course of their use (programs
+whose purpose is to change the configuration of the system excluded).
+Those probably belong in @file{$(localstatedir)}.
+
+@item sharedstatedir
+The directory for installing architecture-independent data files which
+the programs modify while they run. This should normally be
+@file{/usr/local/com}, but write it as @file{$(prefix)/com}.
+(If you are using Autoconf, write it as @samp{@@sharedstatedir@@}.)
+
+@item localstatedir
+The directory for installing data files which the programs modify while
+they run, and that pertain to one specific machine. Users should never
+need to modify files in this directory to configure the package's
+operation; put such configuration information in separate files that go
+in @file{$(datadir)} or @file{$(sysconfdir)}. @file{$(localstatedir)}
+should normally be @file{/usr/local/var}, but write it as
+@file{$(prefix)/var}.
+(If you are using Autoconf, write it as @samp{@@localstatedir@@}.)
+
+@item libdir
+The directory for object files and libraries of object code. Do not
+install executables here, they probably ought to go in @file{$(libexecdir)}
+instead. The value of @code{libdir} should normally be
+@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}.
+(If you are using Autoconf, write it as @samp{@@libdir@@}.)
+
+@item infodir
+The directory for installing the Info files for this package. By
+default, it should be @file{/usr/local/info}, but it should be written
+as @file{$(prefix)/info}.
+(If you are using Autoconf, write it as @samp{@@infodir@@}.)
+
+@item lispdir
+The directory for installing any Emacs Lisp files in this package. By
+default, it should be @file{/usr/local/share/emacs/site-lisp}, but it
+should be written as @file{$(prefix)/share/emacs/site-lisp}.
+
+If you are using Autoconf, write the default as @samp{@@lispdir@@}.
+In order to make @samp{@@lispdir@@} work, you need the following lines
+in your @file{configure.in} file:
+
+@example
+lispdir='$@{datadir@}/emacs/site-lisp'
+AC_SUBST(lispdir)
+@end example
+
+@item includedir
+@c rewritten to avoid overfull hbox --roland
+The directory for installing header files to be included by user
+programs with the C @samp{#include} preprocessor directive. This
+should normally be @file{/usr/local/include}, but write it as
+@file{$(prefix)/include}.
+(If you are using Autoconf, write it as @samp{@@includedir@@}.)
+
+Most compilers other than GCC do not look for header files in directory
+@file{/usr/local/include}. So installing the header files this way is
+only useful with GCC. Sometimes this is not a problem because some
+libraries are only really intended to work with GCC. But some libraries
+are intended to work with other compilers. They should install their
+header files in two places, one specified by @code{includedir} and one
+specified by @code{oldincludedir}.
+
+@item oldincludedir
+The directory for installing @samp{#include} header files for use with
+compilers other than GCC. This should normally be @file{/usr/include}.
+(If you are using Autoconf, you can write it as @samp{@@oldincludedir@@}.)
+
+The Makefile commands should check whether the value of
+@code{oldincludedir} is empty. If it is, they should not try to use
+it; they should cancel the second installation of the header files.
+
+A package should not replace an existing header in this directory unless
+the header came from the same package. Thus, if your Foo package
+provides a header file @file{foo.h}, then it should install the header
+file in the @code{oldincludedir} directory if either (1) there is no
+@file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo
+package.
+
+To tell whether @file{foo.h} came from the Foo package, put a magic
+string in the file---part of a comment---and @code{grep} for that string.
+@end table
+
+Unix-style man pages are installed in one of the following:
+
+@table @samp
+@item mandir
+The top-level directory for installing the man pages (if any) for this
+package. It will normally be @file{/usr/local/man}, but you should
+write it as @file{$(prefix)/man}.
+(If you are using Autoconf, write it as @samp{@@mandir@@}.)
+
+@item man1dir
+The directory for installing section 1 man pages. Write it as
+@file{$(mandir)/man1}.
+@item man2dir
+The directory for installing section 2 man pages. Write it as
+@file{$(mandir)/man2}
+@item @dots{}
+
+@strong{Don't make the primary documentation for any GNU software be a
+man page. Write a manual in Texinfo instead. Man pages are just for
+the sake of people running GNU software on Unix, which is a secondary
+application only.}
+
+@item manext
+The file name extension for the installed man page. This should contain
+a period followed by the appropriate digit; it should normally be @samp{.1}.
+
+@item man1ext
+The file name extension for installed section 1 man pages.
+@item man2ext
+The file name extension for installed section 2 man pages.
+@item @dots{}
+Use these names instead of @samp{manext} if the package needs to install man
+pages in more than one section of the manual.
+@end table
+
+And finally, you should set the following variable:
+
+@table @samp
+@item srcdir
+The directory for the sources being compiled. The value of this
+variable is normally inserted by the @code{configure} shell script.
+(If you are using Autconf, use @samp{srcdir = @@srcdir@@}.)
+@end table
+
+For example:
+
+@smallexample
+@c I have changed some of the comments here slightly to fix an overfull
+@c hbox, so the make manual can format correctly. --roland
+# Common prefix for installation directories.
+# NOTE: This directory must exist when you start the install.
+prefix = /usr/local
+exec_prefix = $(prefix)
+# Where to put the executable for the command `gcc'.
+bindir = $(exec_prefix)/bin
+# Where to put the directories used by the compiler.
+libexecdir = $(exec_prefix)/libexec
+# Where to put the Info files.
+infodir = $(prefix)/info
+@end smallexample
+
+If your program installs a large number of files into one of the
+standard user-specified directories, it might be useful to group them
+into a subdirectory particular to that program. If you do this, you
+should write the @code{install} rule to create these subdirectories.
+
+Do not expect the user to include the subdirectory name in the value of
+any of the variables listed above. The idea of having a uniform set of
+variable names for installation directories is to enable the user to
+specify the exact same values for several different GNU packages. In
+order for this to be useful, all the packages must be designed so that
+they will work sensibly when the user does so.
+
+@node Standard Targets
+@section Standard Targets for Users
+
+All GNU programs should have the following targets in their Makefiles:
+
+@table @samp
+@item all
+Compile the entire program. This should be the default target. This
+target need not rebuild any documentation files; Info files should
+normally be included in the distribution, and DVI files should be made
+only when explicitly asked for.
+
+By default, the Make rules should compile and link with @samp{-g}, so
+that executable programs have debugging symbols. Users who don't mind
+being helpless can strip the executables later if they wish.
+
+@item install
+Compile the program and copy the executables, libraries, and so on to
+the file names where they should reside for actual use. If there is a
+simple test to verify that a program is properly installed, this target
+should run that test.
+
+Do not strip executables when installing them. Devil-may-care users can
+use the @code{install-strip} target to do that.
+
+If possible, write the @code{install} target rule so that it does not
+modify anything in the directory where the program was built, provided
+@samp{make all} has just been done. This is convenient for building the
+program under one user name and installing it under another.
+
+The commands should create all the directories in which files are to be
+installed, if they don't already exist. This includes the directories
+specified as the values of the variables @code{prefix} and
+@code{exec_prefix}, as well as all subdirectories that are needed.
+One way to do this is by means of an @code{installdirs} target
+as described below.
+
+Use @samp{-} before any command for installing a man page, so that
+@code{make} will ignore any errors. This is in case there are systems
+that don't have the Unix man page documentation system installed.
+
+The way to install Info files is to copy them into @file{$(infodir)}
+with @code{$(INSTALL_DATA)} (@pxref{Command Variables}), and then run
+the @code{install-info} program if it is present. @code{install-info}
+is a program that edits the Info @file{dir} file to add or update the
+menu entry for the given Info file; it is part of the Texinfo package.
+Here is a sample rule to install an Info file:
+
+@comment This example has been carefully formatted for the Make manual.
+@comment Please do not reformat it without talking to roland@gnu.ai.mit.edu.
+@smallexample
+$(DESTDIR)$(infodir)/foo.info: foo.info
+ $(POST_INSTALL)
+# There may be a newer info file in . than in srcdir.
+ -if test -f foo.info; then d=.; \
+ else d=$(srcdir); fi; \
+ $(INSTALL_DATA) $$d/foo.info $(DESTDIR)$@@; \
+# Run install-info only if it exists.
+# Use `if' instead of just prepending `-' to the
+# line so we notice real errors from install-info.
+# We use `$(SHELL) -c' because some shells do not
+# fail gracefully when there is an unknown command.
+ if $(SHELL) -c 'install-info --version' \
+ >/dev/null 2>&1; then \
+ install-info --dir-file=$(DESTDIR)$(infodir)/dir \
+ $(DESTDIR)$(infodir)/foo.info; \
+ else true; fi
+@end smallexample
+
+When writing the @code{install} target, you must classify all the
+commands into three categories: normal ones, @dfn{pre-installation}
+commands and @dfn{post-installation} commands. @xref{Install Command
+Categories}.
+
+@item uninstall
+Delete all the installed files---the copies that the @samp{install}
+target creates.
+
+This rule should not modify the directories where compilation is done,
+only the directories where files are installed.
+
+The uninstallation commands are divided into three categories, just like
+the installation commands. @xref{Install Command Categories}.
+
+@item install-strip
+Like @code{install}, but strip the executable files while installing
+them. In many cases, the definition of this target can be very simple:
+
+@smallexample
+install-strip:
+ $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
+ install
+@end smallexample
+
+Normally we do not recommend stripping an executable unless you are sure
+the program has no bugs. However, it can be reasonable to install a
+stripped executable for actual execution while saving the unstripped
+executable elsewhere in case there is a bug.
+
+@comment The gratuitous blank line here is to make the table look better
+@comment in the printed Make manual. Please leave it in.
+@item clean
+
+Delete all files from the current directory that are normally created by
+building the program. Don't delete the files that record the
+configuration. Also preserve files that could be made by building, but
+normally aren't because the distribution comes with them.
+
+Delete @file{.dvi} files here if they are not part of the distribution.
+
+@item distclean
+Delete all files from the current directory that are created by
+configuring or building the program. If you have unpacked the source
+and built the program without creating any other files, @samp{make
+distclean} should leave only the files that were in the distribution.
+
+@item mostlyclean
+Like @samp{clean}, but may refrain from deleting a few files that people
+normally don't want to recompile. For example, the @samp{mostlyclean}
+target for GCC does not delete @file{libgcc.a}, because recompiling it
+is rarely necessary and takes a lot of time.
+
+@item maintainer-clean
+Delete almost everything from the current directory that can be
+reconstructed with this Makefile. This typically includes everything
+deleted by @code{distclean}, plus more: C source files produced by
+Bison, tags tables, Info files, and so on.
+
+The reason we say ``almost everything'' is that running the command
+@samp{make maintainer-clean} should not delete @file{configure} even if
+@file{configure} can be remade using a rule in the Makefile. More generally,
+@samp{make maintainer-clean} should not delete anything that needs to
+exist in order to run @file{configure} and then begin to build the
+program. This is the only exception; @code{maintainer-clean} should
+delete everything else that can be rebuilt.
+
+The @samp{maintainer-clean} target is intended to be used by a maintainer of
+the package, not by ordinary users. You may need special tools to
+reconstruct some of the files that @samp{make maintainer-clean} deletes.
+Since these files are normally included in the distribution, we don't
+take care to make them easy to reconstruct. If you find you need to
+unpack the full distribution again, don't blame us.
+
+To help make users aware of this, the commands for the special
+@code{maintainer-clean} target should start with these two:
+
+@smallexample
+@@echo 'This command is intended for maintainers to use; it'
+@@echo 'deletes files that may need special tools to rebuild.'
+@end smallexample
+
+@item TAGS
+Update a tags table for this program.
+@c ADR: how?
+
+@item info
+Generate any Info files needed. The best way to write the rules is as
+follows:
+
+@smallexample
+info: foo.info
+
+foo.info: foo.texi chap1.texi chap2.texi
+ $(MAKEINFO) $(srcdir)/foo.texi
+@end smallexample
+
+@noindent
+You must define the variable @code{MAKEINFO} in the Makefile. It should
+run the @code{makeinfo} program, which is part of the Texinfo
+distribution.
+
+Normally a GNU distribution comes with Info files, and that means the
+Info files are present in the source directory. Therefore, the Make
+rule for an info file should update it in the source directory. When
+users build the package, ordinarily Make will not update the Info files
+because they will already be up to date.
+
+@item dvi
+Generate DVI files for all Texinfo documentation.
+For example:
+
+@smallexample
+dvi: foo.dvi
+
+foo.dvi: foo.texi chap1.texi chap2.texi
+ $(TEXI2DVI) $(srcdir)/foo.texi
+@end smallexample
+
+@noindent
+You must define the variable @code{TEXI2DVI} in the Makefile. It should
+run the program @code{texi2dvi}, which is part of the Texinfo
+distribution.@footnote{@code{texi2dvi} uses @TeX{} to do the real work
+of formatting. @TeX{} is not distributed with Texinfo.} Alternatively,
+write just the dependencies, and allow GNU @code{make} to provide the command.
+
+@item dist
+Create a distribution tar file for this program. The tar file should be
+set up so that the file names in the tar file start with a subdirectory
+name which is the name of the package it is a distribution for. This
+name can include the version number.
+
+For example, the distribution tar file of GCC version 1.40 unpacks into
+a subdirectory named @file{gcc-1.40}.
+
+The easiest way to do this is to create a subdirectory appropriately
+named, use @code{ln} or @code{cp} to install the proper files in it, and
+then @code{tar} that subdirectory.
+
+Compress the tar file file with @code{gzip}. For example, the actual
+distribution file for GCC version 1.40 is called @file{gcc-1.40.tar.gz}.
+
+The @code{dist} target should explicitly depend on all non-source files
+that are in the distribution, to make sure they are up to date in the
+distribution.
+@ifset CODESTD
+@xref{Releases, , Making Releases}.
+@end ifset
+@ifclear CODESTD
+@xref{Releases, , Making Releases, standards, GNU Coding Standards}.
+@end ifclear
+
+@item check
+Perform self-tests (if any). The user must build the program before
+running the tests, but need not install the program; you should write
+the self-tests so that they work when the program is built but not
+installed.
+@end table
+
+The following targets are suggested as conventional names, for programs
+in which they are useful.
+
+@table @code
+@item installcheck
+Perform installation tests (if any). The user must build and install
+the program before running the tests. You should not assume that
+@file{$(bindir)} is in the search path.
+
+@item installdirs
+It's useful to add a target named @samp{installdirs} to create the
+directories where files are installed, and their parent directories.
+There is a script called @file{mkinstalldirs} which is convenient for
+this; you can find it in the Texinfo package.
+@c It's in /gd/gnu/lib/mkinstalldirs.
+You can use a rule like this:
+
+@comment This has been carefully formatted to look decent in the Make manual.
+@comment Please be sure not to make it extend any further to the right.--roland
+@smallexample
+# Make sure all installation directories (e.g. $(bindir))
+# actually exist by making them if necessary.
+installdirs: mkinstalldirs
+ $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
+ $(libdir) $(infodir) \
+ $(mandir)
+@end smallexample
+
+This rule should not modify the directories where compilation is done.
+It should do nothing but create installation directories.
+@end table
+
+@node Install Command Categories
+@section Install Command Categories
+
+@cindex pre-installation commands
+@cindex post-installation commands
+When writing the @code{install} target, you must classify all the
+commands into three categories: normal ones, @dfn{pre-installation}
+commands and @dfn{post-installation} commands.
+
+Normal commands move files into their proper places, and set their
+modes. They may not alter any files except the ones that come entirely
+from the package they belong to.
+
+Pre-installation and post-installation commands may alter other files;
+in particular, they can edit global configuration files or data bases.
+
+Pre-installation commands are typically executed before the normal
+commands, and post-installation commands are typically run after the
+normal commands.
+
+The most common use for a post-installation command is to run
+@code{install-info}. This cannot be done with a normal command, since
+it alters a file (the Info directory) which does not come entirely and
+solely from the package being installed. It is a post-installation
+command because it needs to be done after the normal command which
+installs the package's Info files.
+
+Most programs don't need any pre-installation commands, but we have the
+feature just in case it is needed.
+
+To classify the commands in the @code{install} rule into these three
+categories, insert @dfn{category lines} among them. A category line
+specifies the category for the commands that follow.
+
+A category line consists of a tab and a reference to a special Make
+variable, plus an optional comment at the end. There are three
+variables you can use, one for each category; the variable name
+specifies the category. Category lines are no-ops in ordinary execution
+because these three Make variables are normally undefined (and you
+@emph{should not} define them in the makefile).
+
+Here are the three possible category lines, each with a comment that
+explains what it means:
+
+@smallexample
+ $(PRE_INSTALL) # @r{Pre-install commands follow.}
+ $(POST_INSTALL) # @r{Post-install commands follow.}
+ $(NORMAL_INSTALL) # @r{Normal commands follow.}
+@end smallexample
+
+If you don't use a category line at the beginning of the @code{install}
+rule, all the commands are classified as normal until the first category
+line. If you don't use any category lines, all the commands are
+classified as normal.
+
+These are the category lines for @code{uninstall}:
+
+@smallexample
+ $(PRE_UNINSTALL) # @r{Pre-uninstall commands follow.}
+ $(POST_UNINSTALL) # @r{Post-uninstall commands follow.}
+ $(NORMAL_UNINSTALL) # @r{Normal commands follow.}
+@end smallexample
+
+Typically, a pre-uninstall command would be used for deleting entries
+from the Info directory.
+
+If the @code{install} or @code{uninstall} target has any dependencies
+which act as subroutines of installation, then you should start
+@emph{each} dependency's commands with a category line, and start the
+main target's commands with a category line also. This way, you can
+ensure that each command is placed in the right category regardless of
+which of the dependencies actually run.
+
+Pre-installation and post-installation commands should not run any
+programs except for these:
+
+@example
+[ basename bash cat chgrp chmod chown cmp cp dd diff echo
+egrep expand expr false fgrep find getopt grep gunzip gzip
+hostname install install-info kill ldconfig ln ls md5sum
+mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee
+test touch true uname xargs yes
+@end example
+
+@cindex binary packages
+The reason for distinguishing the commands in this way is for the sake
+of making binary packages. Typically a binary package contains all the
+executables and other files that need to be installed, and has its own
+method of installing them---so it does not need to run the normal
+installation commands. But installing the binary package does need to
+execute the pre-installation and post-installation commands.
+
+Programs to build binary packages work by extracting the
+pre-installation and post-installation commands. Here is one way of
+extracting the pre-installation commands:
+
+@smallexample
+make -n install -o all \
+ PRE_INSTALL=pre-install \
+ POST_INSTALL=post-install \
+ NORMAL_INSTALL=normal-install \
+ | gawk -f pre-install.awk
+@end smallexample
+
+@noindent
+where the file @file{pre-install.awk} could contain this:
+
+@smallexample
+$0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ @{on = 0@}
+on @{print $0@}
+$0 ~ /^\t[ \t]*pre_install[ \t]*$/ @{on = 1@}
+@end smallexample
+
+The resulting file of pre-installation commands is executed as a shell
+script as part of installing the binary package.
diff --git a/etc/standards.texi b/etc/standards.texi
new file mode 100644
index 00000000000..910bf8b0479
--- /dev/null
+++ b/etc/standards.texi
@@ -0,0 +1,3093 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename standards.info
+@settitle GNU Coding Standards
+@c This date is automagically updated when you save this file:
+@set lastupdate March 13, 1998
+@c %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Standards: (standards). GNU coding standards.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@c @setchapternewpage odd
+@setchapternewpage off
+
+@c This is used by a cross ref in make-stds.texi
+@set CODESTD 1
+@iftex
+@set CHAPTER chapter
+@end iftex
+@ifinfo
+@set CHAPTER node
+@end ifinfo
+
+@ifinfo
+GNU Coding Standards
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end ifinfo
+
+@titlepage
+@title GNU Coding Standards
+@author Richard Stallman
+@author last updated @value{lastupdate}
+@page
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end titlepage
+
+@ifinfo
+@node Top, Preface, (dir), (dir)
+@top Version
+
+Last updated @value{lastupdate}.
+@end ifinfo
+
+@menu
+* Preface:: About the GNU Coding Standards
+* Intellectual Property:: Keeping Free Software Free
+* Design Advice:: General Program Design
+* Program Behavior:: Program Behavior for All Programs
+* Writing C:: Making The Best Use of C
+* Documentation:: Documenting Programs
+* Managing Releases:: The Release Process
+@end menu
+
+@node Preface
+@chapter About the GNU Coding Standards
+
+The GNU Coding Standards were written by Richard Stallman and other GNU
+Project volunteers. Their purpose is to make the GNU system clean,
+consistent, and easy to install. This document can also be read as a
+guide to writing portable, robust and reliable programs. It focuses on
+programs written in C, but many of the rules and principles are useful
+even if you write in another programming language. The rules often
+state reasons for writing in a certain way.
+
+Corrections or suggestions for this document should be sent to
+@email{gnu@@gnu.org}. If you make a suggestion, please include a
+suggested new wording for it; our time is limited. We prefer a context
+diff to the @file{standards.texi} or @file{make-stds.texi} files, but if
+you don't have those files, please mail your suggestion anyway.
+
+This release of the GNU Coding Standards was last updated
+@value{lastupdate}.
+
+@node Intellectual Property
+@chapter Keeping Free Software Free
+
+This @value{CHAPTER} discusses how you can make sure that GNU software
+remains unencumbered.
+
+@menu
+* Reading Non-Free Code:: Referring to Proprietary Programs
+* Contributions:: Accepting Contributions
+@end menu
+
+@node Reading Non-Free Code
+@section Referring to Proprietary Programs
+
+Don't in any circumstances refer to Unix source code for or during
+your work on GNU! (Or to any other proprietary programs.)
+
+If you have a vague recollection of the internals of a Unix program,
+this does not absolutely mean you can't write an imitation of it, but
+do try to organize the imitation internally along different lines,
+because this is likely to make the details of the Unix version
+irrelevant and dissimilar to your results.
+
+For example, Unix utilities were generally optimized to minimize
+memory use; if you go for speed instead, your program will be very
+different. You could keep the entire input file in core and scan it
+there instead of using stdio. Use a smarter algorithm discovered more
+recently than the Unix program. Eliminate use of temporary files. Do
+it in one pass instead of two (we did this in the assembler).
+
+Or, on the contrary, emphasize simplicity instead of speed. For some
+applications, the speed of today's computers makes simpler algorithms
+adequate.
+
+Or go for generality. For example, Unix programs often have static
+tables or fixed-size strings, which make for arbitrary limits; use
+dynamic allocation instead. Make sure your program handles NULs and
+other funny characters in the input files. Add a programming language
+for extensibility and write part of the program in that language.
+
+Or turn some parts of the program into independently usable libraries.
+Or use a simple garbage collector instead of tracking precisely when
+to free memory, or use a new GNU facility such as obstacks.
+
+
+@node Contributions
+@section Accepting Contributions
+
+If someone else sends you a piece of code to add to the program you are
+working on, we need legal papers to use it---the same sort of legal
+papers we will need to get from you. @emph{Each} significant
+contributor to a program must sign some sort of legal papers in order
+for us to have clear title to the program. The main author alone is not
+enough.
+
+So, before adding in any contributions from other people, please tell
+us, so we can arrange to get the papers. Then wait until we tell you
+that we have received the signed papers, before you actually use the
+contribution.
+
+This applies both before you release the program and afterward. If
+you receive diffs to fix a bug, and they make significant changes, we
+need legal papers for that change.
+
+This also applies to comments and documentation files. For copyright
+law, comments and code are just text. Copyright applies to all kinds of
+text, so we need legal papers for all kinds.
+
+You don't need papers for changes of a few lines here or there, since
+they are not significant for copyright purposes. Also, you don't need
+papers if all you get from the suggestion is some ideas, not actual code
+which you use. For example, if you write a different solution to the
+problem, you don't need to get papers.
+
+We know this is frustrating; it's frustrating for us as well. But if
+you don't wait, you are going out on a limb---for example, what if the
+contributor's employer won't sign a disclaimer? You might have to take
+that code out again!
+
+The very worst thing is if you forget to tell us about the other
+contributor. We could be very embarrassed in court some day as a
+result.
+
+We have more detailed advice for maintainers of programs; if you have
+reached the stage of actually maintaining a program for GNU (whether
+released or not), please ask us for a copy.
+
+@node Design Advice
+@chapter General Program Design
+
+This @value{CHAPTER} discusses some of the issues you should take into
+account when designing your program.
+
+@menu
+* Compatibility:: Compatibility with other implementations
+* Using Extensions:: Using non-standard features
+* ANSI C:: Using ANSI C features
+* Source Language:: Using languages other than C
+@end menu
+
+@node Compatibility
+@section Compatibility with Other Implementations
+
+With occasional exceptions, utility programs and libraries for GNU
+should be upward compatible with those in Berkeley Unix, and upward
+compatible with @sc{ansi} C if @sc{ansi} C specifies their behavior, and
+upward compatible with @sc{POSIX} if @sc{POSIX} specifies their
+behavior.
+
+When these standards conflict, it is useful to offer compatibility
+modes for each of them.
+
+@sc{ansi} C and @sc{POSIX} prohibit many kinds of extensions. Feel free
+to make the extensions anyway, and include a @samp{--ansi},
+@samp{--posix}, or @samp{--compatible} option to turn them off.
+However, if the extension has a significant chance of breaking any real
+programs or scripts, then it is not really upward compatible. Try to
+redesign its interface.
+
+Many GNU programs suppress extensions that conflict with POSIX if the
+environment variable @code{POSIXLY_CORRECT} is defined (even if it is
+defined with a null value). Please make your program recognize this
+variable if appropriate.
+
+When a feature is used only by users (not by programs or command
+files), and it is done poorly in Unix, feel free to replace it
+completely with something totally different and better. (For example,
+@code{vi} is replaced with Emacs.) But it is nice to offer a compatible
+feature as well. (There is a free @code{vi} clone, so we offer it.)
+
+Additional useful features not in Berkeley Unix are welcome.
+
+@node Using Extensions
+@section Using Non-standard Features
+
+Many GNU facilities that already exist support a number of convenient
+extensions over the comparable Unix facilities. Whether to use these
+extensions in implementing your program is a difficult question.
+
+On the one hand, using the extensions can make a cleaner program.
+On the other hand, people will not be able to build the program
+unless the other GNU tools are available. This might cause the
+program to work on fewer kinds of machines.
+
+With some extensions, it might be easy to provide both alternatives.
+For example, you can define functions with a ``keyword'' @code{INLINE}
+and define that as a macro to expand into either @code{inline} or
+nothing, depending on the compiler.
+
+In general, perhaps it is best not to use the extensions if you can
+straightforwardly do without them, but to use the extensions if they
+are a big improvement.
+
+An exception to this rule are the large, established programs (such as
+Emacs) which run on a great variety of systems. Such programs would
+be broken by use of GNU extensions.
+
+Another exception is for programs that are used as part of
+compilation: anything that must be compiled with other compilers in
+order to bootstrap the GNU compilation facilities. If these require
+the GNU compiler, then no one can compile them without having them
+installed already. That would be no good.
+
+@node ANSI C
+@section @sc{ansi} C and pre-@sc{ansi} C
+
+Do not ever use the ``trigraph'' feature of @sc{ansi} C.
+
+@sc{ansi} C is widespread enough now that it is ok to write new programs
+that use @sc{ansi} C features (and therefore will not work in
+non-@sc{ansi} compilers). And if a program is already written in
+@sc{ansi} C, there's no need to convert it to support non-@sc{ansi}
+compilers.
+
+However, it is easy to support non-@sc{ansi} compilers in most programs,
+so you might still consider doing so when you write a program. Instead
+of writing function definitions in @sc{ansi} prototype form,
+
+@example
+int
+foo (int x, int y)
+@dots{}
+@end example
+
+@noindent
+write the definition in pre-@sc{ansi} style like this,
+
+@example
+int
+foo (x, y)
+ int x, y;
+@dots{}
+@end example
+
+@noindent
+and use a separate declaration to specify the argument prototype:
+
+@example
+int foo (int, int);
+@end example
+
+You need such a declaration anyway, in a header file, to get the benefit
+of @sc{ansi} C prototypes in all the files where the function is called.
+And once you have it, you lose nothing by writing the function
+definition in the pre-@sc{ansi} style.
+
+If you don't know non-@sc{ansi} C, there's no need to learn it; just
+write in @sc{ansi} C.
+
+@node Source Language
+@section Using Languages Other Than C
+
+Using a language other than C is like using a non-standard feature: it
+will cause trouble for users. Even if GCC supports the other language,
+users may find it inconvenient to have to install the compiler for that
+other language in order to build your program. For example, if you
+write your program in C++, people will have to install the C++ compiler
+in order to compile your program. Thus, it is better if you write in C.
+
+But there are three situations when there is no disadvantage in using
+some other language:
+
+@itemize @bullet
+@item
+It is okay to use another language if your program contains an
+interpreter for that language.
+
+For example, if your program links with GUILE, it is ok to write part of
+the program in Scheme or another language supported by GUILE.
+
+@item
+It is okay to use another language in a tool specifically intended for
+use with that language.
+
+This is okay because the only people who want to build the tool will be
+those who have installed the other language anyway.
+
+@item
+If an application is of interest to a narrow community, then perhaps
+it's not important if the application is inconvenient to install.
+@end itemize
+
+C has one other advantage over C++ and other compiled languages: more
+people know C, so more people will find it easy to read and modify the
+program if it is written in C.
+
+@node Program Behavior
+@chapter Program Behavior for All Programs
+
+This @value{CHAPTER} describes how to write robust software. It also
+describes general standards for error messages, the command line interface,
+and how libraries should behave.
+
+@menu
+* Semantics:: Writing robust programs
+* Libraries:: Library behavior
+* Errors:: Formatting error messages
+* User Interfaces:: Standards for command line interfaces
+* Option Table:: Table of long options.
+* Memory Usage:: When and how to care about memory needs
+@end menu
+
+@node Semantics
+@section Writing Robust Programs
+
+Avoid arbitrary limits on the length or number of @emph{any} data
+structure, including file names, lines, files, and symbols, by allocating
+all data structures dynamically. In most Unix utilities, ``long lines
+are silently truncated''. This is not acceptable in a GNU utility.
+
+Utilities reading files should not drop NUL characters, or any other
+nonprinting characters @emph{including those with codes above 0177}. The
+only sensible exceptions would be utilities specifically intended for
+interface to certain types of printers that can't handle those characters.
+
+Check every system call for an error return, unless you know you wish to
+ignore errors. Include the system error text (from @code{perror} or
+equivalent) in @emph{every} error message resulting from a failing
+system call, as well as the name of the file if any and the name of the
+utility. Just ``cannot open foo.c'' or ``stat failed'' is not
+sufficient.
+
+Check every call to @code{malloc} or @code{realloc} to see if it
+returned zero. Check @code{realloc} even if you are making the block
+smaller; in a system that rounds block sizes to a power of 2,
+@code{realloc} may get a different block if you ask for less space.
+
+In Unix, @code{realloc} can destroy the storage block if it returns
+zero. GNU @code{realloc} does not have this bug: if it fails, the
+original block is unchanged. Feel free to assume the bug is fixed. If
+you wish to run your program on Unix, and wish to avoid lossage in this
+case, you can use the GNU @code{malloc}.
+
+You must expect @code{free} to alter the contents of the block that was
+freed. Anything you want to fetch from the block, you must fetch before
+calling @code{free}.
+
+If @code{malloc} fails in a noninteractive program, make that a fatal
+error. In an interactive program (one that reads commands from the
+user), it is better to abort the command and return to the command
+reader loop. This allows the user to kill other processes to free up
+virtual memory, and then try the command again.
+
+Use @code{getopt_long} to decode arguments, unless the argument syntax
+makes this unreasonable.
+
+When static storage is to be written in during program execution, use
+explicit C code to initialize it. Reserve C initialized declarations
+for data that will not be changed.
+@c ADR: why?
+
+Try to avoid low-level interfaces to obscure Unix data structures (such
+as file directories, utmp, or the layout of kernel memory), since these
+are less likely to work compatibly. If you need to find all the files
+in a directory, use @code{readdir} or some other high-level interface.
+These will be supported compatibly by GNU.
+
+By default, the GNU system will provide the signal handling functions of
+@sc{BSD} and of @sc{POSIX}. So GNU software should be written to use
+these.
+
+In error checks that detect ``impossible'' conditions, just abort.
+There is usually no point in printing any message. These checks
+indicate the existence of bugs. Whoever wants to fix the bugs will have
+to read the source code and run a debugger. So explain the problem with
+comments in the source. The relevant data will be in variables, which
+are easy to examine with the debugger, so there is no point moving them
+elsewhere.
+
+Do not use a count of errors as the exit status for a program.
+@emph{That does not work}, because exit status values are limited to 8
+bits (0 through 255). A single run of the program might have 256
+errors; if you try to return 256 as the exit status, the parent process
+will see 0 as the status, and it will appear that the program succeeded.
+
+If you make temporary files, check the @code{TMPDIR} environment
+variable; if that variable is defined, use the specified directory
+instead of @file{/tmp}.
+
+@node Libraries
+@section Library Behavior
+
+Try to make library functions reentrant. If they need to do dynamic
+storage allocation, at least try to avoid any nonreentrancy aside from
+that of @code{malloc} itself.
+
+Here are certain name conventions for libraries, to avoid name
+conflicts.
+
+Choose a name prefix for the library, more than two characters long.
+All external function and variable names should start with this
+prefix. In addition, there should only be one of these in any given
+library member. This usually means putting each one in a separate
+source file.
+
+An exception can be made when two external symbols are always used
+together, so that no reasonable program could use one without the
+other; then they can both go in the same file.
+
+External symbols that are not documented entry points for the user
+should have names beginning with @samp{_}. They should also contain
+the chosen name prefix for the library, to prevent collisions with
+other libraries. These can go in the same files with user entry
+points if you like.
+
+Static functions and variables can be used as you like and need not
+fit any naming convention.
+
+@node Errors
+@section Formatting Error Messages
+
+Error messages from compilers should look like this:
+
+@example
+@var{source-file-name}:@var{lineno}: @var{message}
+@end example
+
+Error messages from other noninteractive programs should look like this:
+
+@example
+@var{program}:@var{source-file-name}:@var{lineno}: @var{message}
+@end example
+
+@noindent
+when there is an appropriate source file, or like this:
+
+@example
+@var{program}: @var{message}
+@end example
+
+@noindent
+when there is no relevant source file.
+
+In an interactive program (one that is reading commands from a
+terminal), it is better not to include the program name in an error
+message. The place to indicate which program is running is in the
+prompt or with the screen layout. (When the same program runs with
+input from a source other than a terminal, it is not interactive and
+would do best to print error messages using the noninteractive style.)
+
+The string @var{message} should not begin with a capital letter when
+it follows a program name and/or file name. Also, it should not end
+with a period.
+
+Error messages from interactive programs, and other messages such as
+usage messages, should start with a capital letter. But they should not
+end with a period.
+
+@node User Interfaces
+@section Standards for Command Line Interfaces
+
+Please don't make the behavior of a utility depend on the name used
+to invoke it. It is useful sometimes to make a link to a utility
+with a different name, and that should not change what it does.
+
+Instead, use a run time option or a compilation switch or both
+to select among the alternate behaviors.
+
+Likewise, please don't make the behavior of the program depend on the
+type of output device it is used with. Device independence is an
+important principle of the system's design; do not compromise it
+merely to save someone from typing an option now and then.
+
+If you think one behavior is most useful when the output is to a
+terminal, and another is most useful when the output is a file or a
+pipe, then it is usually best to make the default behavior the one that
+is useful with output to a terminal, and have an option for the other
+behavior.
+
+Compatibility requires certain programs to depend on the type of output
+device. It would be disastrous if @code{ls} or @code{sh} did not do so
+in the way all users expect. In some of these cases, we supplement the
+program with a preferred alternate version that does not depend on the
+output device type. For example, we provide a @code{dir} program much
+like @code{ls} except that its default output format is always
+multi-column format.
+
+It is a good idea to follow the @sc{POSIX} guidelines for the
+command-line options of a program. The easiest way to do this is to use
+@code{getopt} to parse them. Note that the GNU version of @code{getopt}
+will normally permit options anywhere among the arguments unless the
+special argument @samp{--} is used. This is not what @sc{POSIX}
+specifies; it is a GNU extension.
+
+Please define long-named options that are equivalent to the
+single-letter Unix-style options. We hope to make GNU more user
+friendly this way. This is easy to do with the GNU function
+@code{getopt_long}.
+
+One of the advantages of long-named options is that they can be
+consistent from program to program. For example, users should be able
+to expect the ``verbose'' option of any GNU program which has one, to be
+spelled precisely @samp{--verbose}. To achieve this uniformity, look at
+the table of common long-option names when you choose the option names
+for your program (@pxref{Option Table}).
+
+It is usually a good idea for file names given as ordinary arguments to
+be input files only; any output files would be specified using options
+(preferably @samp{-o} or @samp{--output}). Even if you allow an output
+file name as an ordinary argument for compatibility, try to provide an
+option as another way to specify it. This will lead to more consistency
+among GNU utilities, and fewer idiosyncracies for users to remember.
+
+All programs should support two standard options: @samp{--version}
+and @samp{--help}.
+
+@table @code
+@item --version
+This option should direct the program to information about its name,
+version, origin and legal status, all on standard output, and then exit
+successfully. Other options and arguments should be ignored once this
+is seen, and the program should not perform its normal function.
+
+The first line is meant to be easy for a program to parse; the version
+number proper starts after the last space. In addition, it contains
+the canonical name for this program, in this format:
+
+@example
+GNU Emacs 19.30
+@end example
+
+@noindent
+The program's name should be a constant string; @emph{don't} compute it
+from @code{argv[0]}. The idea is to state the standard or canonical
+name for the program, not its file name. There are other ways to find
+out the precise file name where a command is found in @code{PATH}.
+
+If the program is a subsidiary part of a larger package, mention the
+package name in parentheses, like this:
+
+@example
+emacsserver (GNU Emacs) 19.30
+@end example
+
+@noindent
+If the package has a version number which is different from this
+program's version number, you can mention the package version number
+just before the close-parenthesis.
+
+If you @strong{need} to mention the version numbers of libraries which
+are distributed separately from the package which contains this program,
+you can do so by printing an additional line of version info for each
+library you want to mention. Use the same format for these lines as for
+the first line.
+
+Please do not mention all of the libraries that the program uses ``just
+for completeness''---that would produce a lot of unhelpful clutter.
+Please mention library version numbers only if you find in practice that
+they are very important to you in debugging.
+
+The following line, after the version number line or lines, should be a
+copyright notice. If more than one copyright notice is called for, put
+each on a separate line.
+
+Next should follow a brief statement that the program is free software,
+and that users are free to copy and change it on certain conditions. If
+the program is covered by the GNU GPL, say so here. Also mention that
+there is no warranty, to the extent permitted by law.
+
+It is ok to finish the output with a list of the major authors of the
+program, as a way of giving credit.
+
+Here's an example of output that follows these rules:
+
+@smallexample
+GNU Emacs 19.34.5
+Copyright (C) 1996 Free Software Foundation, Inc.
+GNU Emacs comes with NO WARRANTY,
+to the extent permitted by law.
+You may redistribute copies of GNU Emacs
+under the terms of the GNU General Public License.
+For more information about these matters,
+see the files named COPYING.
+@end smallexample
+
+You should adapt this to your program, of course, filling in the proper
+year, copyright holder, name of program, and the references to
+distribution terms, and changing the rest of the wording as necessary.
+
+This copyright notice only needs to mention the most recent year in
+which changes were made---there's no need to list the years for previous
+versions' changes. You don't have to mention the name of the program in
+these notices, if that is inconvenient, since it appeared in the first
+line.
+
+@item --help
+This option should output brief documentation for how to invoke the
+program, on standard output, then exit successfully. Other options and
+arguments should be ignored once this is seen, and the program should
+not perform its normal function.
+
+Near the end of the @samp{--help} option's output there should be a line
+that says where to mail bug reports. It should have this format:
+
+@example
+Report bugs to @var{mailing-address}.
+@end example
+@end table
+
+@node Option Table
+@section Table of Long Options
+
+Here is a table of long options used by GNU programs. It is surely
+incomplete, but we aim to list all the options that a new program might
+want to be compatible with. If you use names not already in the table,
+please send @email{gnu@@gnu.org} a list of them, with their
+meanings, so we can update the table.
+
+@c Please leave newlines between items in this table; it's much easier
+@c to update when it isn't completely squashed together and unreadable.
+@c When there is more than one short option for a long option name, put
+@c a semicolon between the lists of the programs that use them, not a
+@c period. --friedman
+
+@table @samp
+@item after-date
+@samp{-N} in @code{tar}.
+
+@item all
+@samp{-a} in @code{du}, @code{ls}, @code{nm}, @code{stty}, @code{uname},
+and @code{unexpand}.
+
+@item all-text
+@samp{-a} in @code{diff}.
+
+@item almost-all
+@samp{-A} in @code{ls}.
+
+@item append
+@samp{-a} in @code{etags}, @code{tee}, @code{time};
+@samp{-r} in @code{tar}.
+
+@item archive
+@samp{-a} in @code{cp}.
+
+@item archive-name
+@samp{-n} in @code{shar}.
+
+@item arglength
+@samp{-l} in @code{m4}.
+
+@item ascii
+@samp{-a} in @code{diff}.
+
+@item assign
+@samp{-v} in @code{gawk}.
+
+@item assume-new
+@samp{-W} in Make.
+
+@item assume-old
+@samp{-o} in Make.
+
+@item auto-check
+@samp{-a} in @code{recode}.
+
+@item auto-pager
+@samp{-a} in @code{wdiff}.
+
+@item auto-reference
+@samp{-A} in @code{ptx}.
+
+@item avoid-wraps
+@samp{-n} in @code{wdiff}.
+
+@item backward-search
+@samp{-B} in @code{ctags}.
+
+@item basename
+@samp{-f} in @code{shar}.
+
+@item batch
+Used in GDB.
+
+@item baud
+Used in GDB.
+
+@item before
+@samp{-b} in @code{tac}.
+
+@item binary
+@samp{-b} in @code{cpio} and @code{diff}.
+
+@item bits-per-code
+@samp{-b} in @code{shar}.
+
+@item block-size
+Used in @code{cpio} and @code{tar}.
+
+@item blocks
+@samp{-b} in @code{head} and @code{tail}.
+
+@item break-file
+@samp{-b} in @code{ptx}.
+
+@item brief
+Used in various programs to make output shorter.
+
+@item bytes
+@samp{-c} in @code{head}, @code{split}, and @code{tail}.
+
+@item c@t{++}
+@samp{-C} in @code{etags}.
+
+@item catenate
+@samp{-A} in @code{tar}.
+
+@item cd
+Used in various programs to specify the directory to use.
+
+@item changes
+@samp{-c} in @code{chgrp} and @code{chown}.
+
+@item classify
+@samp{-F} in @code{ls}.
+
+@item colons
+@samp{-c} in @code{recode}.
+
+@item command
+@samp{-c} in @code{su};
+@samp{-x} in GDB.
+
+@item compare
+@samp{-d} in @code{tar}.
+
+@item compat
+Used in @code{gawk}.
+
+@item compress
+@samp{-Z} in @code{tar} and @code{shar}.
+
+@item concatenate
+@samp{-A} in @code{tar}.
+
+@item confirmation
+@samp{-w} in @code{tar}.
+
+@item context
+Used in @code{diff}.
+
+@item copyleft
+@samp{-W copyleft} in @code{gawk}.
+
+@item copyright
+@samp{-C} in @code{ptx}, @code{recode}, and @code{wdiff};
+@samp{-W copyright} in @code{gawk}.
+
+@item core
+Used in GDB.
+
+@item count
+@samp{-q} in @code{who}.
+
+@item count-links
+@samp{-l} in @code{du}.
+
+@item create
+Used in @code{tar} and @code{cpio}.
+
+@item cut-mark
+@samp{-c} in @code{shar}.
+
+@item cxref
+@samp{-x} in @code{ctags}.
+
+@item date
+@samp{-d} in @code{touch}.
+
+@item debug
+@samp{-d} in Make and @code{m4};
+@samp{-t} in Bison.
+
+@item define
+@samp{-D} in @code{m4}.
+
+@item defines
+@samp{-d} in Bison and @code{ctags}.
+
+@item delete
+@samp{-D} in @code{tar}.
+
+@item dereference
+@samp{-L} in @code{chgrp}, @code{chown}, @code{cpio}, @code{du},
+@code{ls}, and @code{tar}.
+
+@item dereference-args
+@samp{-D} in @code{du}.
+
+@item diacritics
+@samp{-d} in @code{recode}.
+
+@item dictionary-order
+@samp{-d} in @code{look}.
+
+@item diff
+@samp{-d} in @code{tar}.
+
+@item digits
+@samp{-n} in @code{csplit}.
+
+@item directory
+Specify the directory to use, in various programs. In @code{ls}, it
+means to show directories themselves rather than their contents. In
+@code{rm} and @code{ln}, it means to not treat links to directories
+specially.
+
+@item discard-all
+@samp{-x} in @code{strip}.
+
+@item discard-locals
+@samp{-X} in @code{strip}.
+
+@item dry-run
+@samp{-n} in Make.
+
+@item ed
+@samp{-e} in @code{diff}.
+
+@item elide-empty-files
+@samp{-z} in @code{csplit}.
+
+@item end-delete
+@samp{-x} in @code{wdiff}.
+
+@item end-insert
+@samp{-z} in @code{wdiff}.
+
+@item entire-new-file
+@samp{-N} in @code{diff}.
+
+@item environment-overrides
+@samp{-e} in Make.
+
+@item eof
+@samp{-e} in @code{xargs}.
+
+@item epoch
+Used in GDB.
+
+@item error-limit
+Used in @code{makeinfo}.
+
+@item error-output
+@samp{-o} in @code{m4}.
+
+@item escape
+@samp{-b} in @code{ls}.
+
+@item exclude-from
+@samp{-X} in @code{tar}.
+
+@item exec
+Used in GDB.
+
+@item exit
+@samp{-x} in @code{xargs}.
+
+@item exit-0
+@samp{-e} in @code{unshar}.
+
+@item expand-tabs
+@samp{-t} in @code{diff}.
+
+@item expression
+@samp{-e} in @code{sed}.
+
+@item extern-only
+@samp{-g} in @code{nm}.
+
+@item extract
+@samp{-i} in @code{cpio};
+@samp{-x} in @code{tar}.
+
+@item faces
+@samp{-f} in @code{finger}.
+
+@item fast
+@samp{-f} in @code{su}.
+
+@item fatal-warnings
+@samp{-E} in @code{m4}.
+
+@item file
+@samp{-f} in @code{info}, @code{gawk}, Make, @code{mt}, and @code{tar};
+@samp{-n} in @code{sed};
+@samp{-r} in @code{touch}.
+
+@item field-separator
+@samp{-F} in @code{gawk}.
+
+@item file-prefix
+@samp{-b} in Bison.
+
+@item file-type
+@samp{-F} in @code{ls}.
+
+@item files-from
+@samp{-T} in @code{tar}.
+
+@item fill-column
+Used in @code{makeinfo}.
+
+@item flag-truncation
+@samp{-F} in @code{ptx}.
+
+@item fixed-output-files
+@samp{-y} in Bison.
+
+@item follow
+@samp{-f} in @code{tail}.
+
+@item footnote-style
+Used in @code{makeinfo}.
+
+@item force
+@samp{-f} in @code{cp}, @code{ln}, @code{mv}, and @code{rm}.
+
+@item force-prefix
+@samp{-F} in @code{shar}.
+
+@item format
+Used in @code{ls}, @code{time}, and @code{ptx}.
+
+@item freeze-state
+@samp{-F} in @code{m4}.
+
+@item fullname
+Used in GDB.
+
+@item gap-size
+@samp{-g} in @code{ptx}.
+
+@item get
+@samp{-x} in @code{tar}.
+
+@item graphic
+@samp{-i} in @code{ul}.
+
+@item graphics
+@samp{-g} in @code{recode}.
+
+@item group
+@samp{-g} in @code{install}.
+
+@item gzip
+@samp{-z} in @code{tar} and @code{shar}.
+
+@item hashsize
+@samp{-H} in @code{m4}.
+
+@item header
+@samp{-h} in @code{objdump} and @code{recode}
+
+@item heading
+@samp{-H} in @code{who}.
+
+@item help
+Used to ask for brief usage information.
+
+@item here-delimiter
+@samp{-d} in @code{shar}.
+
+@item hide-control-chars
+@samp{-q} in @code{ls}.
+
+@item idle
+@samp{-u} in @code{who}.
+
+@item ifdef
+@samp{-D} in @code{diff}.
+
+@item ignore
+@samp{-I} in @code{ls};
+@samp{-x} in @code{recode}.
+
+@item ignore-all-space
+@samp{-w} in @code{diff}.
+
+@item ignore-backups
+@samp{-B} in @code{ls}.
+
+@item ignore-blank-lines
+@samp{-B} in @code{diff}.
+
+@item ignore-case
+@samp{-f} in @code{look} and @code{ptx};
+@samp{-i} in @code{diff} and @code{wdiff}.
+
+@item ignore-errors
+@samp{-i} in Make.
+
+@item ignore-file
+@samp{-i} in @code{ptx}.
+
+@item ignore-indentation
+@samp{-I} in @code{etags}.
+
+@item ignore-init-file
+@samp{-f} in Oleo.
+
+@item ignore-interrupts
+@samp{-i} in @code{tee}.
+
+@item ignore-matching-lines
+@samp{-I} in @code{diff}.
+
+@item ignore-space-change
+@samp{-b} in @code{diff}.
+
+@item ignore-zeros
+@samp{-i} in @code{tar}.
+
+@item include
+@samp{-i} in @code{etags};
+@samp{-I} in @code{m4}.
+
+@item include-dir
+@samp{-I} in Make.
+
+@item incremental
+@samp{-G} in @code{tar}.
+
+@item info
+@samp{-i}, @samp{-l}, and @samp{-m} in Finger.
+
+@item initial
+@samp{-i} in @code{expand}.
+
+@item initial-tab
+@samp{-T} in @code{diff}.
+
+@item inode
+@samp{-i} in @code{ls}.
+
+@item interactive
+@samp{-i} in @code{cp}, @code{ln}, @code{mv}, @code{rm};
+@samp{-e} in @code{m4};
+@samp{-p} in @code{xargs};
+@samp{-w} in @code{tar}.
+
+@item intermix-type
+@samp{-p} in @code{shar}.
+
+@item jobs
+@samp{-j} in Make.
+
+@item just-print
+@samp{-n} in Make.
+
+@item keep-going
+@samp{-k} in Make.
+
+@item keep-files
+@samp{-k} in @code{csplit}.
+
+@item kilobytes
+@samp{-k} in @code{du} and @code{ls}.
+
+@item language
+@samp{-l} in @code{etags}.
+
+@item less-mode
+@samp{-l} in @code{wdiff}.
+
+@item level-for-gzip
+@samp{-g} in @code{shar}.
+
+@item line-bytes
+@samp{-C} in @code{split}.
+
+@item lines
+Used in @code{split}, @code{head}, and @code{tail}.
+
+@item link
+@samp{-l} in @code{cpio}.
+
+@item lint
+@itemx lint-old
+Used in @code{gawk}.
+
+@item list
+@samp{-t} in @code{cpio};
+@samp{-l} in @code{recode}.
+
+@item list
+@samp{-t} in @code{tar}.
+
+@item literal
+@samp{-N} in @code{ls}.
+
+@item load-average
+@samp{-l} in Make.
+
+@item login
+Used in @code{su}.
+
+@item machine
+No listing of which programs already use this;
+someone should check to
+see if any actually do, and tell @email{gnu@@gnu.org}.
+
+@item macro-name
+@samp{-M} in @code{ptx}.
+
+@item mail
+@samp{-m} in @code{hello} and @code{uname}.
+
+@item make-directories
+@samp{-d} in @code{cpio}.
+
+@item makefile
+@samp{-f} in Make.
+
+@item mapped
+Used in GDB.
+
+@item max-args
+@samp{-n} in @code{xargs}.
+
+@item max-chars
+@samp{-n} in @code{xargs}.
+
+@item max-lines
+@samp{-l} in @code{xargs}.
+
+@item max-load
+@samp{-l} in Make.
+
+@item max-procs
+@samp{-P} in @code{xargs}.
+
+@item mesg
+@samp{-T} in @code{who}.
+
+@item message
+@samp{-T} in @code{who}.
+
+@item minimal
+@samp{-d} in @code{diff}.
+
+@item mixed-uuencode
+@samp{-M} in @code{shar}.
+
+@item mode
+@samp{-m} in @code{install}, @code{mkdir}, and @code{mkfifo}.
+
+@item modification-time
+@samp{-m} in @code{tar}.
+
+@item multi-volume
+@samp{-M} in @code{tar}.
+
+@item name-prefix
+@samp{-a} in Bison.
+
+@item nesting-limit
+@samp{-L} in @code{m4}.
+
+@item net-headers
+@samp{-a} in @code{shar}.
+
+@item new-file
+@samp{-W} in Make.
+
+@item no-builtin-rules
+@samp{-r} in Make.
+
+@item no-character-count
+@samp{-w} in @code{shar}.
+
+@item no-check-existing
+@samp{-x} in @code{shar}.
+
+@item no-common
+@samp{-3} in @code{wdiff}.
+
+@item no-create
+@samp{-c} in @code{touch}.
+
+@item no-defines
+@samp{-D} in @code{etags}.
+
+@item no-deleted
+@samp{-1} in @code{wdiff}.
+
+@item no-dereference
+@samp{-d} in @code{cp}.
+
+@item no-inserted
+@samp{-2} in @code{wdiff}.
+
+@item no-keep-going
+@samp{-S} in Make.
+
+@item no-lines
+@samp{-l} in Bison.
+
+@item no-piping
+@samp{-P} in @code{shar}.
+
+@item no-prof
+@samp{-e} in @code{gprof}.
+
+@item no-regex
+@samp{-R} in @code{etags}.
+
+@item no-sort
+@samp{-p} in @code{nm}.
+
+@item no-split
+Used in @code{makeinfo}.
+
+@item no-static
+@samp{-a} in @code{gprof}.
+
+@item no-time
+@samp{-E} in @code{gprof}.
+
+@item no-timestamp
+@samp{-m} in @code{shar}.
+
+@item no-validate
+Used in @code{makeinfo}.
+
+@item no-wait
+Used in @code{emacsclient}.
+
+@item no-warn
+Used in various programs to inhibit warnings.
+
+@item node
+@samp{-n} in @code{info}.
+
+@item nodename
+@samp{-n} in @code{uname}.
+
+@item nonmatching
+@samp{-f} in @code{cpio}.
+
+@item nstuff
+@samp{-n} in @code{objdump}.
+
+@item null
+@samp{-0} in @code{xargs}.
+
+@item number
+@samp{-n} in @code{cat}.
+
+@item number-nonblank
+@samp{-b} in @code{cat}.
+
+@item numeric-sort
+@samp{-n} in @code{nm}.
+
+@item numeric-uid-gid
+@samp{-n} in @code{cpio} and @code{ls}.
+
+@item nx
+Used in GDB.
+
+@item old-archive
+@samp{-o} in @code{tar}.
+
+@item old-file
+@samp{-o} in Make.
+
+@item one-file-system
+@samp{-l} in @code{tar}, @code{cp}, and @code{du}.
+
+@item only-file
+@samp{-o} in @code{ptx}.
+
+@item only-prof
+@samp{-f} in @code{gprof}.
+
+@item only-time
+@samp{-F} in @code{gprof}.
+
+@item output
+In various programs, specify the output file name.
+
+@item output-prefix
+@samp{-o} in @code{shar}.
+
+@item override
+@samp{-o} in @code{rm}.
+
+@item overwrite
+@samp{-c} in @code{unshar}.
+
+@item owner
+@samp{-o} in @code{install}.
+
+@item paginate
+@samp{-l} in @code{diff}.
+
+@item paragraph-indent
+Used in @code{makeinfo}.
+
+@item parents
+@samp{-p} in @code{mkdir} and @code{rmdir}.
+
+@item pass-all
+@samp{-p} in @code{ul}.
+
+@item pass-through
+@samp{-p} in @code{cpio}.
+
+@item port
+@samp{-P} in @code{finger}.
+
+@item portability
+@samp{-c} in @code{cpio} and @code{tar}.
+
+@item posix
+Used in @code{gawk}.
+
+@item prefix-builtins
+@samp{-P} in @code{m4}.
+
+@item prefix
+@samp{-f} in @code{csplit}.
+
+@item preserve
+Used in @code{tar} and @code{cp}.
+
+@item preserve-environment
+@samp{-p} in @code{su}.
+
+@item preserve-modification-time
+@samp{-m} in @code{cpio}.
+
+@item preserve-order
+@samp{-s} in @code{tar}.
+
+@item preserve-permissions
+@samp{-p} in @code{tar}.
+
+@item print
+@samp{-l} in @code{diff}.
+
+@item print-chars
+@samp{-L} in @code{cmp}.
+
+@item print-data-base
+@samp{-p} in Make.
+
+@item print-directory
+@samp{-w} in Make.
+
+@item print-file-name
+@samp{-o} in @code{nm}.
+
+@item print-symdefs
+@samp{-s} in @code{nm}.
+
+@item printer
+@samp{-p} in @code{wdiff}.
+
+@item prompt
+@samp{-p} in @code{ed}.
+
+@item query-user
+@samp{-X} in @code{shar}.
+
+@item question
+@samp{-q} in Make.
+
+@item quiet
+Used in many programs to inhibit the usual output. @strong{Note:} every
+program accepting @samp{--quiet} should accept @samp{--silent} as a
+synonym.
+
+@item quiet-unshar
+@samp{-Q} in @code{shar}
+
+@item quote-name
+@samp{-Q} in @code{ls}.
+
+@item rcs
+@samp{-n} in @code{diff}.
+
+@item re-interval
+Used in @code{gawk}.
+
+@item read-full-blocks
+@samp{-B} in @code{tar}.
+
+@item readnow
+Used in GDB.
+
+@item recon
+@samp{-n} in Make.
+
+@item record-number
+@samp{-R} in @code{tar}.
+
+@item recursive
+Used in @code{chgrp}, @code{chown}, @code{cp}, @code{ls}, @code{diff},
+and @code{rm}.
+
+@item reference-limit
+Used in @code{makeinfo}.
+
+@item references
+@samp{-r} in @code{ptx}.
+
+@item regex
+@samp{-r} in @code{tac} and @code{etags}.
+
+@item release
+@samp{-r} in @code{uname}.
+
+@item reload-state
+@samp{-R} in @code{m4}.
+
+@item relocation
+@samp{-r} in @code{objdump}.
+
+@item rename
+@samp{-r} in @code{cpio}.
+
+@item replace
+@samp{-i} in @code{xargs}.
+
+@item report-identical-files
+@samp{-s} in @code{diff}.
+
+@item reset-access-time
+@samp{-a} in @code{cpio}.
+
+@item reverse
+@samp{-r} in @code{ls} and @code{nm}.
+
+@item reversed-ed
+@samp{-f} in @code{diff}.
+
+@item right-side-defs
+@samp{-R} in @code{ptx}.
+
+@item same-order
+@samp{-s} in @code{tar}.
+
+@item same-permissions
+@samp{-p} in @code{tar}.
+
+@item save
+@samp{-g} in @code{stty}.
+
+@item se
+Used in GDB.
+
+@item sentence-regexp
+@samp{-S} in @code{ptx}.
+
+@item separate-dirs
+@samp{-S} in @code{du}.
+
+@item separator
+@samp{-s} in @code{tac}.
+
+@item sequence
+Used by @code{recode} to chose files or pipes for sequencing passes.
+
+@item shell
+@samp{-s} in @code{su}.
+
+@item show-all
+@samp{-A} in @code{cat}.
+
+@item show-c-function
+@samp{-p} in @code{diff}.
+
+@item show-ends
+@samp{-E} in @code{cat}.
+
+@item show-function-line
+@samp{-F} in @code{diff}.
+
+@item show-tabs
+@samp{-T} in @code{cat}.
+
+@item silent
+Used in many programs to inhibit the usual output.
+@strong{Note:} every program accepting
+@samp{--silent} should accept @samp{--quiet} as a synonym.
+
+@item size
+@samp{-s} in @code{ls}.
+
+@item sort
+Used in @code{ls}.
+
+@item source
+@samp{-W source} in @code{gawk}.
+
+@item sparse
+@samp{-S} in @code{tar}.
+
+@item speed-large-files
+@samp{-H} in @code{diff}.
+
+@item split-at
+@samp{-E} in @code{unshar}.
+
+@item split-size-limit
+@samp{-L} in @code{shar}.
+
+@item squeeze-blank
+@samp{-s} in @code{cat}.
+
+@item start-delete
+@samp{-w} in @code{wdiff}.
+
+@item start-insert
+@samp{-y} in @code{wdiff}.
+
+@item starting-file
+Used in @code{tar} and @code{diff} to specify which file within
+a directory to start processing with.
+
+@item statistics
+@samp{-s} in @code{wdiff}.
+
+@item stdin-file-list
+@samp{-S} in @code{shar}.
+
+@item stop
+@samp{-S} in Make.
+
+@item strict
+@samp{-s} in @code{recode}.
+
+@item strip
+@samp{-s} in @code{install}.
+
+@item strip-all
+@samp{-s} in @code{strip}.
+
+@item strip-debug
+@samp{-S} in @code{strip}.
+
+@item submitter
+@samp{-s} in @code{shar}.
+
+@item suffix
+@samp{-S} in @code{cp}, @code{ln}, @code{mv}.
+
+@item suffix-format
+@samp{-b} in @code{csplit}.
+
+@item sum
+@samp{-s} in @code{gprof}.
+
+@item summarize
+@samp{-s} in @code{du}.
+
+@item symbolic
+@samp{-s} in @code{ln}.
+
+@item symbols
+Used in GDB and @code{objdump}.
+
+@item synclines
+@samp{-s} in @code{m4}.
+
+@item sysname
+@samp{-s} in @code{uname}.
+
+@item tabs
+@samp{-t} in @code{expand} and @code{unexpand}.
+
+@item tabsize
+@samp{-T} in @code{ls}.
+
+@item terminal
+@samp{-T} in @code{tput} and @code{ul}.
+@samp{-t} in @code{wdiff}.
+
+@item text
+@samp{-a} in @code{diff}.
+
+@item text-files
+@samp{-T} in @code{shar}.
+
+@item time
+Used in @code{ls} and @code{touch}.
+
+@item to-stdout
+@samp{-O} in @code{tar}.
+
+@item total
+@samp{-c} in @code{du}.
+
+@item touch
+@samp{-t} in Make, @code{ranlib}, and @code{recode}.
+
+@item trace
+@samp{-t} in @code{m4}.
+
+@item traditional
+@samp{-t} in @code{hello};
+@samp{-W traditional} in @code{gawk};
+@samp{-G} in @code{ed}, @code{m4}, and @code{ptx}.
+
+@item tty
+Used in GDB.
+
+@item typedefs
+@samp{-t} in @code{ctags}.
+
+@item typedefs-and-c++
+@samp{-T} in @code{ctags}.
+
+@item typeset-mode
+@samp{-t} in @code{ptx}.
+
+@item uncompress
+@samp{-z} in @code{tar}.
+
+@item unconditional
+@samp{-u} in @code{cpio}.
+
+@item undefine
+@samp{-U} in @code{m4}.
+
+@item undefined-only
+@samp{-u} in @code{nm}.
+
+@item update
+@samp{-u} in @code{cp}, @code{ctags}, @code{mv}, @code{tar}.
+
+@item usage
+Used in @code{gawk}; same as @samp{--help}.
+
+@item uuencode
+@samp{-B} in @code{shar}.
+
+@item vanilla-operation
+@samp{-V} in @code{shar}.
+
+@item verbose
+Print more information about progress. Many programs support this.
+
+@item verify
+@samp{-W} in @code{tar}.
+
+@item version
+Print the version number.
+
+@item version-control
+@samp{-V} in @code{cp}, @code{ln}, @code{mv}.
+
+@item vgrind
+@samp{-v} in @code{ctags}.
+
+@item volume
+@samp{-V} in @code{tar}.
+
+@item what-if
+@samp{-W} in Make.
+
+@item whole-size-limit
+@samp{-l} in @code{shar}.
+
+@item width
+@samp{-w} in @code{ls} and @code{ptx}.
+
+@item word-regexp
+@samp{-W} in @code{ptx}.
+
+@item writable
+@samp{-T} in @code{who}.
+
+@item zeros
+@samp{-z} in @code{gprof}.
+@end table
+
+@node Memory Usage
+@section Memory Usage
+
+If it typically uses just a few meg of memory, don't bother making any
+effort to reduce memory usage. For example, if it is impractical for
+other reasons to operate on files more than a few meg long, it is
+reasonable to read entire input files into core to operate on them.
+
+However, for programs such as @code{cat} or @code{tail}, that can
+usefully operate on very large files, it is important to avoid using a
+technique that would artificially limit the size of files it can handle.
+If a program works by lines and could be applied to arbitrary
+user-supplied input files, it should keep only a line in memory, because
+this is not very hard and users will want to be able to operate on input
+files that are bigger than will fit in core all at once.
+
+If your program creates complicated data structures, just make them in
+core and give a fatal error if @code{malloc} returns zero.
+
+@node Writing C
+@chapter Making The Best Use of C
+
+This @value{CHAPTER} provides advice on how best to use the C language
+when writing GNU software.
+
+@menu
+* Formatting:: Formatting Your Source Code
+* Comments:: Commenting Your Work
+* Syntactic Conventions:: Clean Use of C Constructs
+* Names:: Naming Variables and Functions
+* System Portability:: Portability between different operating systems
+* CPU Portability:: Supporting the range of CPU types
+* System Functions:: Portability and ``standard'' library functions
+* Internationalization:: Techniques for internationalization
+* Mmap:: How you can safely use @code{mmap}.
+@end menu
+
+@node Formatting
+@section Formatting Your Source Code
+
+It is important to put the open-brace that starts the body of a C
+function in column zero, and avoid putting any other open-brace or
+open-parenthesis or open-bracket in column zero. Several tools look
+for open-braces in column zero to find the beginnings of C functions.
+These tools will not work on code not formatted that way.
+
+It is also important for function definitions to start the name of the
+function in column zero. This helps people to search for function
+definitions, and may also help certain tools recognize them. Thus,
+the proper format is this:
+
+@example
+static char *
+concat (s1, s2) /* Name starts in column zero here */
+ char *s1, *s2;
+@{ /* Open brace in column zero here */
+ @dots{}
+@}
+@end example
+
+@noindent
+or, if you want to use @sc{ansi} C, format the definition like this:
+
+@example
+static char *
+concat (char *s1, char *s2)
+@{
+ @dots{}
+@}
+@end example
+
+In @sc{ansi} C, if the arguments don't fit nicely on one line,
+split it like this:
+
+@example
+int
+lots_of_args (int an_integer, long a_long, short a_short,
+ double a_double, float a_float)
+@dots{}
+@end example
+
+For the body of the function, we prefer code formatted like this:
+
+@example
+if (x < foo (y, z))
+ haha = bar[4] + 5;
+else
+ @{
+ while (z)
+ @{
+ haha += foo (z, z);
+ z--;
+ @}
+ return ++x + bar ();
+ @}
+@end example
+
+We find it easier to read a program when it has spaces before the
+open-parentheses and after the commas. Especially after the commas.
+
+When you split an expression into multiple lines, split it
+before an operator, not after one. Here is the right way:
+
+@example
+if (foo_this_is_long && bar > win (x, y, z)
+ && remaining_condition)
+@end example
+
+Try to avoid having two operators of different precedence at the same
+level of indentation. For example, don't write this:
+
+@example
+mode = (inmode[j] == VOIDmode
+ || GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])
+ ? outmode[j] : inmode[j]);
+@end example
+
+Instead, use extra parentheses so that the indentation shows the nesting:
+
+@example
+mode = ((inmode[j] == VOIDmode
+ || (GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])))
+ ? outmode[j] : inmode[j]);
+@end example
+
+Insert extra parentheses so that Emacs will indent the code properly.
+For example, the following indentation looks nice if you do it by hand,
+but Emacs would mess it up:
+
+@example
+v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
+ + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000;
+@end example
+
+But adding a set of parentheses solves the problem:
+
+@example
+v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
+ + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);
+@end example
+
+Format do-while statements like this:
+
+@example
+do
+ @{
+ a = foo (a);
+ @}
+while (a > 0);
+@end example
+
+Please use formfeed characters (control-L) to divide the program into
+pages at logical places (but not within a function). It does not matter
+just how long the pages are, since they do not have to fit on a printed
+page. The formfeeds should appear alone on lines by themselves.
+
+
+@node Comments
+@section Commenting Your Work
+
+Every program should start with a comment saying briefly what it is for.
+Example: @samp{fmt - filter for simple filling of text}.
+
+Please write the comments in a GNU program in English, because English
+is the one language that nearly all programmers in all countries can
+read. If you do not write English well, please write comments in
+English as well as you can, then ask other people to help rewrite them.
+If you can't write comments in English, please find someone to work with
+you and translate your comments into English.
+
+Please put a comment on each function saying what the function does,
+what sorts of arguments it gets, and what the possible values of
+arguments mean and are used for. It is not necessary to duplicate in
+words the meaning of the C argument declarations, if a C type is being
+used in its customary fashion. If there is anything nonstandard about
+its use (such as an argument of type @code{char *} which is really the
+address of the second character of a string, not the first), or any
+possible values that would not work the way one would expect (such as,
+that strings containing newlines are not guaranteed to work), be sure
+to say so.
+
+Also explain the significance of the return value, if there is one.
+
+Please put two spaces after the end of a sentence in your comments, so
+that the Emacs sentence commands will work. Also, please write
+complete sentences and capitalize the first word. If a lower-case
+identifier comes at the beginning of a sentence, don't capitalize it!
+Changing the spelling makes it a different identifier. If you don't
+like starting a sentence with a lower case letter, write the sentence
+differently (e.g., ``The identifier lower-case is @dots{}'').
+
+The comment on a function is much clearer if you use the argument
+names to speak about the argument values. The variable name itself
+should be lower case, but write it in upper case when you are speaking
+about the value rather than the variable itself. Thus, ``the inode
+number NODE_NUM'' rather than ``an inode''.
+
+There is usually no purpose in restating the name of the function in
+the comment before it, because the reader can see that for himself.
+There might be an exception when the comment is so long that the function
+itself would be off the bottom of the screen.
+
+There should be a comment on each static variable as well, like this:
+
+@example
+/* Nonzero means truncate lines in the display;
+ zero means continue them. */
+int truncate_lines;
+@end example
+
+Every @samp{#endif} should have a comment, except in the case of short
+conditionals (just a few lines) that are not nested. The comment should
+state the condition of the conditional that is ending, @emph{including
+its sense}. @samp{#else} should have a comment describing the condition
+@emph{and sense} of the code that follows. For example:
+
+@example
+@group
+#ifdef foo
+ @dots{}
+#else /* not foo */
+ @dots{}
+#endif /* not foo */
+@end group
+@group
+#ifdef foo
+ @dots{}
+#endif /* foo */
+@end group
+@end example
+
+@noindent
+but, by contrast, write the comments this way for a @samp{#ifndef}:
+
+@example
+@group
+#ifndef foo
+ @dots{}
+#else /* foo */
+ @dots{}
+#endif /* foo */
+@end group
+@group
+#ifndef foo
+ @dots{}
+#endif /* not foo */
+@end group
+@end example
+
+@node Syntactic Conventions
+@section Clean Use of C Constructs
+
+Please explicitly declare all arguments to functions.
+Don't omit them just because they are @code{int}s.
+
+Declarations of external functions and functions to appear later in the
+source file should all go in one place near the beginning of the file
+(somewhere before the first function definition in the file), or else
+should go in a header file. Don't put @code{extern} declarations inside
+functions.
+
+It used to be common practice to use the same local variables (with
+names like @code{tem}) over and over for different values within one
+function. Instead of doing this, it is better declare a separate local
+variable for each distinct purpose, and give it a name which is
+meaningful. This not only makes programs easier to understand, it also
+facilitates optimization by good compilers. You can also move the
+declaration of each local variable into the smallest scope that includes
+all its uses. This makes the program even cleaner.
+
+Don't use local variables or parameters that shadow global identifiers.
+
+Don't declare multiple variables in one declaration that spans lines.
+Start a new declaration on each line, instead. For example, instead
+of this:
+
+@example
+@group
+int foo,
+ bar;
+@end group
+@end example
+
+@noindent
+write either this:
+
+@example
+int foo, bar;
+@end example
+
+@noindent
+or this:
+
+@example
+int foo;
+int bar;
+@end example
+
+@noindent
+(If they are global variables, each should have a comment preceding it
+anyway.)
+
+When you have an @code{if}-@code{else} statement nested in another
+@code{if} statement, always put braces around the @code{if}-@code{else}.
+Thus, never write like this:
+
+@example
+if (foo)
+ if (bar)
+ win ();
+ else
+ lose ();
+@end example
+
+@noindent
+always like this:
+
+@example
+if (foo)
+ @{
+ if (bar)
+ win ();
+ else
+ lose ();
+ @}
+@end example
+
+If you have an @code{if} statement nested inside of an @code{else}
+statement, either write @code{else if} on one line, like this,
+
+@example
+if (foo)
+ @dots{}
+else if (bar)
+ @dots{}
+@end example
+
+@noindent
+with its @code{then}-part indented like the preceding @code{then}-part,
+or write the nested @code{if} within braces like this:
+
+@example
+if (foo)
+ @dots{}
+else
+ @{
+ if (bar)
+ @dots{}
+ @}
+@end example
+
+Don't declare both a structure tag and variables or typedefs in the
+same declaration. Instead, declare the structure tag separately
+and then use it to declare the variables or typedefs.
+
+Try to avoid assignments inside @code{if}-conditions. For example,
+don't write this:
+
+@example
+if ((foo = (char *) malloc (sizeof *foo)) == 0)
+ fatal ("virtual memory exhausted");
+@end example
+
+@noindent
+instead, write this:
+
+@example
+foo = (char *) malloc (sizeof *foo);
+if (foo == 0)
+ fatal ("virtual memory exhausted");
+@end example
+
+Don't make the program ugly to placate @code{lint}. Please don't insert any
+casts to @code{void}. Zero without a cast is perfectly fine as a null
+pointer constant, except when calling a varargs function.
+
+@node Names
+@section Naming Variables and Functions
+
+The names of global variables and functions in a program serve as
+comments of a sort. So don't choose terse names---instead, look for
+names that give useful information about the meaning of the variable or
+function. In a GNU program, names should be English, like other
+comments.
+
+Local variable names can be shorter, because they are used only within
+one context, where (presumably) comments explain their purpose.
+
+Please use underscores to separate words in a name, so that the Emacs
+word commands can be useful within them. Stick to lower case; reserve
+upper case for macros and @code{enum} constants, and for name-prefixes
+that follow a uniform convention.
+
+For example, you should use names like @code{ignore_space_change_flag};
+don't use names like @code{iCantReadThis}.
+
+Variables that indicate whether command-line options have been
+specified should be named after the meaning of the option, not after
+the option-letter. A comment should state both the exact meaning of
+the option and its letter. For example,
+
+@example
+@group
+/* Ignore changes in horizontal whitespace (-b). */
+int ignore_space_change_flag;
+@end group
+@end example
+
+When you want to define names with constant integer values, use
+@code{enum} rather than @samp{#define}. GDB knows about enumeration
+constants.
+
+Use file names of 14 characters or less, to avoid creating gratuitous
+problems on older System V systems. You can use the program
+@code{doschk} to test for this. @code{doschk} also tests for potential
+name conflicts if the files were loaded onto an MS-DOS file
+system---something you may or may not care about.
+
+@node System Portability
+@section Portability between System Types
+
+In the Unix world, ``portability'' refers to porting to different Unix
+versions. For a GNU program, this kind of portability is desirable, but
+not paramount.
+
+The primary purpose of GNU software is to run on top of the GNU kernel,
+compiled with the GNU C compiler, on various types of @sc{cpu}. The
+amount and kinds of variation among GNU systems on different @sc{cpu}s
+will be comparable to the variation among Linux-based GNU systems or
+among BSD systems today. So the kinds of portability that are absolutely
+necessary are quite limited.
+
+But many users do run GNU software on non-GNU Unix or Unix-like systems.
+So supporting a variety of Unix-like systems is desirable, although not
+paramount.
+
+The easiest way to achieve portability to most Unix-like systems is to
+use Autoconf. It's unlikely that your program needs to know more
+information about the host platform than Autoconf can provide, simply
+because most of the programs that need such knowledge have already been
+written.
+
+Avoid using the format of semi-internal data bases (e.g., directories)
+when there is a higher-level alternative (@code{readdir}).
+
+As for systems that are not like Unix, such as MSDOS, Windows, the
+Macintosh, VMS, and MVS, supporting them is usually so much work that it
+is better if you don't.
+
+The planned GNU kernel is not finished yet, but you can tell which
+facilities it will provide by looking at the GNU C Library Manual. The
+GNU kernel is based on Mach, so the features of Mach will also be
+available. However, if you use Mach features, you'll probably have
+trouble debugging your program today.
+
+@node CPU Portability
+@section Portability between @sc{cpu}s
+
+Even GNU systems will differ because of differences among @sc{cpu}
+types---for example, difference in byte ordering and alignment
+requirements. It is absolutely essential to handle these differences.
+However, don't make any effort to cater to the possibility that an
+@code{int} will be less than 32 bits. We don't support 16-bit machines
+in GNU.
+
+Don't assume that the address of an @code{int} object is also the
+address of its least-significant byte. This is false on big-endian
+machines. Thus, don't make the following mistake:
+
+@example
+int c;
+@dots{}
+while ((c = getchar()) != EOF)
+ write(file_descriptor, &c, 1);
+@end example
+
+When calling functions, you need not worry about the difference between
+pointers of various types, or between pointers and integers. On most
+machines, there's no difference anyway. As for the few machines where
+there is a difference, all of them support @sc{ansi} C, so you can use
+prototypes (conditionalized to be active only in @sc{ansi} C) to make
+the code work on those systems.
+
+In certain cases, it is ok to pass integer and pointer arguments
+indiscriminately to the same function, and use no prototype on any
+system. For example, many GNU programs have error-reporting functions
+that pass their arguments along to @code{printf} and friends:
+
+@example
+error (s, a1, a2, a3)
+ char *s;
+ int a1, a2, a3;
+@{
+ fprintf (stderr, "error: ");
+ fprintf (stderr, s, a1, a2, a3);
+@}
+@end example
+
+@noindent
+In practice, this works on all machines, and it is much simpler than any
+``correct'' alternative. Be sure @emph{not} to use a prototype
+for such functions.
+
+However, avoid casting pointers to integers unless you really need to.
+These assumptions really reduce portability, and in most programs they
+are easy to avoid. In the cases where casting pointers to integers is
+essential---such as, a Lisp interpreter which stores type information as
+well as an address in one word---it is ok to do so, but you'll have to
+make explicit provisions to handle different word sizes.
+
+@node System Functions
+@section Calling System Functions
+
+C implementations differ substantially. @sc{ansi} C reduces but does not
+eliminate the incompatibilities; meanwhile, many users wish to compile
+GNU software with pre-@sc{ansi} compilers. This chapter gives
+recommendations for how to use the more or less standard C library
+functions to avoid unnecessary loss of portability.
+
+@itemize @bullet
+@item
+Don't use the value of @code{sprintf}. It returns the number of
+characters written on some systems, but not on all systems.
+
+@item
+@code{main} should be declared to return type @code{int}. It should
+terminate either by calling @code{exit} or by returning the integer
+status code; make sure it cannot ever return an undefined value.
+
+@item
+Don't declare system functions explicitly.
+
+Almost any declaration for a system function is wrong on some system.
+To minimize conflicts, leave it to the system header files to declare
+system functions. If the headers don't declare a function, let it
+remain undeclared.
+
+While it may seem unclean to use a function without declaring it, in
+practice this works fine for most system library functions on the
+systems where this really happens; thus, the disadvantage is only
+theoretical. By contrast, actual declarations have frequently caused
+actual conflicts.
+
+@item
+If you must declare a system function, don't specify the argument types.
+Use an old-style declaration, not an @sc{ansi} prototype. The more you
+specify about the function, the more likely a conflict.
+
+@item
+In particular, don't unconditionally declare @code{malloc} or
+@code{realloc}.
+
+Most GNU programs use those functions just once, in functions
+conventionally named @code{xmalloc} and @code{xrealloc}. These
+functions call @code{malloc} and @code{realloc}, respectively, and
+check the results.
+
+Because @code{xmalloc} and @code{xrealloc} are defined in your program,
+you can declare them in other files without any risk of type conflict.
+
+On most systems, @code{int} is the same length as a pointer; thus, the
+calls to @code{malloc} and @code{realloc} work fine. For the few
+exceptional systems (mostly 64-bit machines), you can use
+@strong{conditionalized} declarations of @code{malloc} and
+@code{realloc}---or put these declarations in configuration files
+specific to those systems.
+
+@item
+The string functions require special treatment. Some Unix systems have
+a header file @file{string.h}; others have @file{strings.h}. Neither
+file name is portable. There are two things you can do: use Autoconf to
+figure out which file to include, or don't include either file.
+
+@item
+If you don't include either strings file, you can't get declarations for
+the string functions from the header file in the usual way.
+
+That causes less of a problem than you might think. The newer @sc{ansi}
+string functions should be avoided anyway because many systems still
+don't support them. The string functions you can use are these:
+
+@example
+strcpy strncpy strcat strncat
+strlen strcmp strncmp
+strchr strrchr
+@end example
+
+The copy and concatenate functions work fine without a declaration as
+long as you don't use their values. Using their values without a
+declaration fails on systems where the width of a pointer differs from
+the width of @code{int}, and perhaps in other cases. It is trivial to
+avoid using their values, so do that.
+
+The compare functions and @code{strlen} work fine without a declaration
+on most systems, possibly all the ones that GNU software runs on.
+You may find it necessary to declare them @strong{conditionally} on a
+few systems.
+
+The search functions must be declared to return @code{char *}. Luckily,
+there is no variation in the data type they return. But there is
+variation in their names. Some systems give these functions the names
+@code{index} and @code{rindex}; other systems use the names
+@code{strchr} and @code{strrchr}. Some systems support both pairs of
+names, but neither pair works on all systems.
+
+You should pick a single pair of names and use it throughout your
+program. (Nowadays, it is better to choose @code{strchr} and
+@code{strrchr} for new programs, since those are the standard @sc{ansi}
+names.) Declare both of those names as functions returning @code{char
+*}. On systems which don't support those names, define them as macros
+in terms of the other pair. For example, here is what to put at the
+beginning of your file (or in a header) if you want to use the names
+@code{strchr} and @code{strrchr} throughout:
+
+@example
+#ifndef HAVE_STRCHR
+#define strchr index
+#endif
+#ifndef HAVE_STRRCHR
+#define strrchr rindex
+#endif
+
+char *strchr ();
+char *strrchr ();
+@end example
+@end itemize
+
+Here we assume that @code{HAVE_STRCHR} and @code{HAVE_STRRCHR} are
+macros defined in systems where the corresponding functions exist.
+One way to get them properly defined is to use Autoconf.
+
+@node Internationalization
+@section Internationalization
+
+GNU has a library called GNU gettext that makes it easy to translate the
+messages in a program into various languages. You should use this
+library in every program. Use English for the messages as they appear
+in the program, and let gettext provide the way to translate them into
+other languages.
+
+Using GNU gettext involves putting a call to the @code{gettext} macro
+around each string that might need translation---like this:
+
+@example
+printf (gettext ("Processing file `%s'..."));
+@end example
+
+@noindent
+This permits GNU gettext to replace the string @code{"Processing file
+`%s'..."} with a translated version.
+
+Once a program uses gettext, please make a point of writing calls to
+@code{gettext} when you add new strings that call for translation.
+
+Using GNU gettext in a package involves specifying a @dfn{text domain
+name} for the package. The text domain name is used to separate the
+translations for this package from the translations for other packages.
+Normally, the text domain name should be the same as the name of the
+package---for example, @samp{fileutils} for the GNU file utilities.
+
+To enable gettext to work well, avoid writing code that makes
+assumptions about the structure of words or sentences. When you want
+the precise text of a sentence to vary depending on the data, use two or
+more alternative string constants each containing a complete sentences,
+rather than inserting conditionalized words or phrases into a single
+sentence framework.
+
+Here is an example of what not to do:
+
+@example
+printf ("%d file%s processed", nfiles,
+ nfiles != 1 ? "s" : "");
+@end example
+
+@noindent
+The problem with that example is that it assumes that plurals are made
+by adding `s'. If you apply gettext to the format string, like this,
+
+@example
+printf (gettext ("%d file%s processed"), nfiles,
+ nfiles != 1 ? "s" : "");
+@end example
+
+@noindent
+the message can use different words, but it will still be forced to use
+`s' for the plural. Here is a better way:
+
+@example
+printf ((nfiles != 1 ? "%d files processed"
+ : "%d file processed"),
+ nfiles);
+@end example
+
+@noindent
+This way, you can apply gettext to each of the two strings
+independently:
+
+@example
+printf ((nfiles != 1 ? gettext ("%d files processed")
+ : gettext ("%d file processed")),
+ nfiles);
+@end example
+
+@noindent
+This can be any method of forming the plural of the word for ``file'', and
+also handles languages that require agreement in the word for
+``processed''.
+
+A similar problem appears at the level of sentence structure with this
+code:
+
+@example
+printf ("# Implicit rule search has%s been done.\n",
+ f->tried_implicit ? "" : " not");
+@end example
+
+@noindent
+Adding @code{gettext} calls to this code cannot give correct results for
+all languages, because negation in some languages requires adding words
+at more than one place in the sentence. By contrast, adding
+@code{gettext} calls does the job straightfowardly if the code starts
+out like this:
+
+@example
+printf (f->tried_implicit
+ ? "# Implicit rule search has been done.\n",
+ : "# Implicit rule search has not been done.\n");
+@end example
+
+@node Mmap
+@section Mmap
+
+Don't assume that @code{mmap} either works on all files or fails
+for all files. It may work on some files and fail on others.
+
+The proper way to use @code{mmap} is to try it on the specific file for
+which you want to use it---and if @code{mmap} doesn't work, fall back on
+doing the job in another way using @code{read} and @code{write}.
+
+The reason this precaution is needed is that the GNU kernel (the HURD)
+provides a user-extensible file system, in which there can be many
+different kinds of ``ordinary files.'' Many of them support
+@code{mmap}, but some do not. It is important to make programs handle
+all these kinds of files.
+
+@node Documentation
+@chapter Documenting Programs
+
+@menu
+* GNU Manuals:: Writing proper manuals.
+* Manual Structure Details:: Specific structure conventions.
+* NEWS File:: NEWS files supplement manuals.
+* Change Logs:: Recording Changes
+* Man Pages:: Man pages are secondary.
+* Reading other Manuals:: How far you can go in learning
+ from other manuals.
+@end menu
+
+@node GNU Manuals
+@section GNU Manuals
+
+The preferred way to document part of the GNU system is to write a
+manual in the Texinfo formatting language. See the Texinfo manual,
+either the hardcopy, or the on-line version available through
+@code{info} or the Emacs Info subsystem (@kbd{C-h i}).
+
+Programmers often find it most natural to structure the documentation
+following the structure of the implementation, which they know. But
+this structure is not necessarily good for explaining how to use the
+program; it may be irrelevant and confusing for a user.
+
+At every level, from the sentences in a paragraph to the grouping of
+topics into separate manuals, the right way to structure documentation
+is according to the concepts and questions that a user will have in mind
+when reading it. Sometimes this structure of ideas matches the
+structure of the implementation of the software being documented---but
+often they are different. Often the most important part of learning to
+write good documentation is learning to notice when you are structuring
+the documentation like the implementation, and think about better
+alternatives.
+
+For example, each program in the GNU system probably ought to be
+documented in one manual; but this does not mean each program should
+have its own manual. That would be following the structure of the
+implementation, rather than the structure that helps the user
+understand.
+
+Instead, each manual should cover a coherent @emph{topic}. For example,
+instead of a manual for @code{diff} and a manual for @code{diff3}, we
+have one manual for ``comparison of files'' which covers both of those
+programs, as well as @code{cmp}. By documenting these programs
+together, we can make the whole subject clearer.
+
+The manual which discusses a program should document all of the
+program's command-line options and all of its commands. It should give
+examples of their use. But don't organize the manual as a list of
+features. Instead, organize it logically, by subtopics. Address the
+questions that a user will ask when thinking about the job that the
+program does.
+
+In general, a GNU manual should serve both as tutorial and reference.
+It should be set up for convenient access to each topic through Info,
+and for reading straight through (appendixes aside). A GNU manual
+should give a good introduction to a beginner reading through from the
+start, and should also provide all the details that hackers want.
+
+That is not as hard as it first sounds. Arrange each chapter as a
+logical breakdown of its topic, but order the sections, and write their
+text, so that reading the chapter straight through makes sense. Do
+likewise when structuring the book into chapters, and when structuring a
+section into paragraphs. The watchword is, @emph{at each point, address
+the most fundamental and important issue raised by the preceding text.}
+
+If necessary, add extra chapters at the beginning of the manual which
+are purely tutorial and cover the basics of the subject. These provide
+the framework for a beginner to understand the rest of the manual. The
+Bison manual provides a good example of how to do this.
+
+Don't use Unix man pages as a model for how to write GNU documentation;
+most of them are terse, badly structured, and give inadequate
+explanation of the underlying concepts. (There are, of course
+exceptions.) Also Unix man pages use a particular format which is
+different from what we use in GNU manuals.
+
+Please do not use the term ``pathname'' that is used in Unix
+documentation; use ``file name'' (two words) instead. We use the term
+``path'' only for search paths, which are lists of file names.
+
+Please do not use the term ``illegal'' to refer to erroneous input to a
+computer program. Please use ``invalid'' for this, and reserve the term
+``illegal'' for violations of law.
+
+@node Manual Structure Details
+@section Manual Structure Details
+
+The title page of the manual should state the version of the programs or
+packages documented in the manual. The Top node of the manual should
+also contain this information. If the manual is changing more
+frequently than or independent of the program, also state a version
+number for the manual in both of these places.
+
+Each program documented in the manual should should have a node named
+@samp{@var{program} Invocation} or @samp{Invoking @var{program}}. This
+node (together with its subnodes, if any) should describe the program's
+command line arguments and how to run it (the sort of information people
+would look in a man page for). Start with an @samp{@@example}
+containing a template for all the options and arguments that the program
+uses.
+
+Alternatively, put a menu item in some menu whose item name fits one of
+the above patterns. This identifies the node which that item points to
+as the node for this purpose, regardless of the node's actual name.
+
+There will be automatic features for specifying a program name and
+quickly reading just this part of its manual.
+
+If one manual describes several programs, it should have such a node for
+each program described.
+
+@node NEWS File
+@section The NEWS File
+
+In addition to its manual, the package should have a file named
+@file{NEWS} which contains a list of user-visible changes worth
+mentioning. In each new release, add items to the front of the file and
+identify the version they pertain to. Don't discard old items; leave
+them in the file after the newer items. This way, a user upgrading from
+any previous version can see what is new.
+
+If the @file{NEWS} file gets very long, move some of the older items
+into a file named @file{ONEWS} and put a note at the end referring the
+user to that file.
+
+@node Change Logs
+@section Change Logs
+
+Keep a change log to describe all the changes made to program source
+files. The purpose of this is so that people investigating bugs in the
+future will know about the changes that might have introduced the bug.
+Often a new bug can be found by looking at what was recently changed.
+More importantly, change logs can help you eliminate conceptual
+inconsistencies between different parts of a program, by giving you a
+history of how the conflicting concepts arose and who they came from.
+
+@menu
+* Change Log Concepts::
+* Style of Change Logs::
+* Simple Changes::
+* Conditional Changes::
+@end menu
+
+@node Change Log Concepts
+@subsection Change Log Concepts
+
+You can think of the change log as a conceptual ``undo list'' which
+explains how earlier versions were different from the current version.
+People can see the current version; they don't need the change log
+to tell them what is in it. What they want from a change log is a
+clear explanation of how the earlier version differed.
+
+The change log file is normally called @file{ChangeLog} and covers an
+entire directory. Each directory can have its own change log, or a
+directory can use the change log of its parent directory--it's up to
+you.
+
+Another alternative is to record change log information with a version
+control system such as RCS or CVS. This can be converted automatically
+to a @file{ChangeLog} file.
+
+There's no need to describe the full purpose of the changes or how they
+work together. If you think that a change calls for explanation, you're
+probably right. Please do explain it---but please put the explanation
+in comments in the code, where people will see it whenever they see the
+code. For example, ``New function'' is enough for the change log when
+you add a function, because there should be a comment before the
+function definition to explain what it does.
+
+However, sometimes it is useful to write one line to describe the
+overall purpose of a batch of changes.
+
+The easiest way to add an entry to @file{ChangeLog} is with the Emacs
+command @kbd{M-x add-change-log-entry}. An entry should have an
+asterisk, the name of the changed file, and then in parentheses the name
+of the changed functions, variables or whatever, followed by a colon.
+Then describe the changes you made to that function or variable.
+
+@node Style of Change Logs
+@subsection Style of Change Logs
+
+Here are some examples of change log entries:
+
+@example
+* register.el (insert-register): Return nil.
+(jump-to-register): Likewise.
+
+* sort.el (sort-subr): Return nil.
+
+* tex-mode.el (tex-bibtex-file, tex-file, tex-region):
+Restart the tex shell if process is gone or stopped.
+(tex-shell-running): New function.
+
+* expr.c (store_one_arg): Round size up for move_block_to_reg.
+(expand_call): Round up when emitting USE insns.
+* stmt.c (assign_parms): Round size up for move_block_from_reg.
+@end example
+
+It's important to name the changed function or variable in full. Don't
+abbreviate function or variable names, and don't combine them.
+Subsequent maintainers will often search for a function name to find all
+the change log entries that pertain to it; if you abbreviate the name,
+they won't find it when they search.
+
+For example, some people are tempted to abbreviate groups of function
+names by writing @samp{* register.el (@{insert,jump-to@}-register)};
+this is not a good idea, since searching for @code{jump-to-register} or
+@code{insert-register} would not find that entry.
+
+Separate unrelated change log entries with blank lines. When two
+entries represent parts of the same change, so that they work together,
+then don't put blank lines between them. Then you can omit the file
+name and the asterisk when successive entries are in the same file.
+
+@node Simple Changes
+@subsection Simple Changes
+
+Certain simple kinds of changes don't need much detail in the change
+log.
+
+When you change the calling sequence of a function in a simple fashion,
+and you change all the callers of the function, there is no need to make
+individual entries for all the callers that you changed. Just write in
+the entry for the function being called, ``All callers changed.''
+
+@example
+* keyboard.c (Fcommand_execute): New arg SPECIAL.
+All callers changed.
+@end example
+
+When you change just comments or doc strings, it is enough to write an
+entry for the file, without mentioning the functions. Just ``Doc
+fixes'' is enough for the change log.
+
+There's no need to make change log entries for documentation files.
+This is because documentation is not susceptible to bugs that are hard
+to fix. Documentation does not consist of parts that must interact in a
+precisely engineered fashion. To correct an error, you need not know
+the history of the erroneous passage; it is enough to compare what the
+documentation says with the way the program actually works.
+
+@node Conditional Changes
+@subsection Conditional Changes
+
+C programs often contain compile-time @code{#if} conditionals. Many
+changes are conditional; sometimes you add a new definition which is
+entirely contained in a conditional. It is very useful to indicate in
+the change log the conditions for which the change applies.
+
+Our convention for indicating conditional changes is to use square
+brackets around the name of the condition.
+
+Here is a simple example, describing a change which is conditional but
+does not have a function or entity name associated with it:
+
+@example
+* xterm.c [SOLARIS2]: Include string.h.
+@end example
+
+Here is an entry describing a new definition which is entirely
+conditional. This new definition for the macro @code{FRAME_WINDOW_P} is
+used only when @code{HAVE_X_WINDOWS} is defined:
+
+@example
+* frame.h [HAVE_X_WINDOWS] (FRAME_WINDOW_P): Macro defined.
+@end example
+
+Here is an entry for a change within the function @code{init_display},
+whose definition as a whole is unconditional, but the changes themselves
+are contained in a @samp{#ifdef HAVE_LIBNCURSES} conditional:
+
+@example
+* dispnew.c (init_display) [HAVE_LIBNCURSES]: If X, call tgetent.
+@end example
+
+Here is an entry for a change that takes affect only when
+a certain macro is @emph{not} defined:
+
+@example
+(gethostname) [!HAVE_SOCKETS]: Replace with winsock version.
+@end example
+
+@node Man Pages
+@section Man Pages
+
+In the GNU project, man pages are secondary. It is not necessary or
+expected for every GNU program to have a man page, but some of them do.
+It's your choice whether to include a man page in your program.
+
+When you make this decision, consider that supporting a man page
+requires continual effort each time the program is changed. The time
+you spend on the man page is time taken away from more useful work.
+
+For a simple program which changes little, updating the man page may be
+a small job. Then there is little reason not to include a man page, if
+you have one.
+
+For a large program that changes a great deal, updating a man page may
+be a substantial burden. If a user offers to donate a man page, you may
+find this gift costly to accept. It may be better to refuse the man
+page unless the same person agrees to take full responsibility for
+maintaining it---so that you can wash your hands of it entirely. If
+this volunteer later ceases to do the job, then don't feel obliged to
+pick it up yourself; it may be better to withdraw the man page from the
+distribution until someone else agrees to update it.
+
+When a program changes only a little, you may feel that the
+discrepancies are small enough that the man page remains useful without
+updating. If so, put a prominent note near the beginning of the man
+page explaining that you don't maintain it and that the Texinfo manual
+is more authoritative. The note should say how to access the Texinfo
+documentation.
+
+@node Reading other Manuals
+@section Reading other Manuals
+
+There may be non-free books or documentation files that describe the
+program you are documenting.
+
+It is ok to use these documents for reference, just as the author of a
+new algebra textbook can read other books on algebra. A large portion
+of any non-fiction book consists of facts, in this case facts about how
+a certain program works, and these facts are necessarily the same for
+everyone who writes about the subject. But be careful not to copy your
+outline structure, wording, tables or examples from preexisting non-free
+documentation. Copying from free documentation may be ok; please check
+with the FSF about the individual case.
+
+@node Managing Releases
+@chapter The Release Process
+
+Making a release is more than just bundling up your source files in a
+tar file and putting it up for FTP. You should set up your software so
+that it can be configured to run on a variety of systems. Your Makefile
+should conform to the GNU standards described below, and your directory
+layout should also conform to the standards discussed below. Doing so
+makes it easy to include your package into the larger framework of
+all GNU software.
+
+@menu
+* Configuration:: How Configuration Should Work
+* Makefile Conventions:: Makefile Conventions
+* Releases:: Making Releases
+@end menu
+
+@node Configuration
+@section How Configuration Should Work
+
+Each GNU distribution should come with a shell script named
+@code{configure}. This script is given arguments which describe the
+kind of machine and system you want to compile the program for.
+
+The @code{configure} script must record the configuration options so
+that they affect compilation.
+
+One way to do this is to make a link from a standard name such as
+@file{config.h} to the proper configuration file for the chosen system.
+If you use this technique, the distribution should @emph{not} contain a
+file named @file{config.h}. This is so that people won't be able to
+build the program without configuring it first.
+
+Another thing that @code{configure} can do is to edit the Makefile. If
+you do this, the distribution should @emph{not} contain a file named
+@file{Makefile}. Instead, it should include a file @file{Makefile.in} which
+contains the input used for editing. Once again, this is so that people
+won't be able to build the program without configuring it first.
+
+If @code{configure} does write the @file{Makefile}, then @file{Makefile}
+should have a target named @file{Makefile} which causes @code{configure}
+to be rerun, setting up the same configuration that was set up last
+time. The files that @code{configure} reads should be listed as
+dependencies of @file{Makefile}.
+
+All the files which are output from the @code{configure} script should
+have comments at the beginning explaining that they were generated
+automatically using @code{configure}. This is so that users won't think
+of trying to edit them by hand.
+
+The @code{configure} script should write a file named @file{config.status}
+which describes which configuration options were specified when the
+program was last configured. This file should be a shell script which,
+if run, will recreate the same configuration.
+
+The @code{configure} script should accept an option of the form
+@samp{--srcdir=@var{dirname}} to specify the directory where sources are found
+(if it is not the current directory). This makes it possible to build
+the program in a separate directory, so that the actual source directory
+is not modified.
+
+If the user does not specify @samp{--srcdir}, then @code{configure} should
+check both @file{.} and @file{..} to see if it can find the sources. If
+it finds the sources in one of these places, it should use them from
+there. Otherwise, it should report that it cannot find the sources, and
+should exit with nonzero status.
+
+Usually the easy way to support @samp{--srcdir} is by editing a
+definition of @code{VPATH} into the Makefile. Some rules may need to
+refer explicitly to the specified source directory. To make this
+possible, @code{configure} can add to the Makefile a variable named
+@code{srcdir} whose value is precisely the specified directory.
+
+The @code{configure} script should also take an argument which specifies the
+type of system to build the program for. This argument should look like
+this:
+
+@example
+@var{cpu}-@var{company}-@var{system}
+@end example
+
+For example, a Sun 3 might be @samp{m68k-sun-sunos4.1}.
+
+The @code{configure} script needs to be able to decode all plausible
+alternatives for how to describe a machine. Thus, @samp{sun3-sunos4.1}
+would be a valid alias. For many programs, @samp{vax-dec-ultrix} would
+be an alias for @samp{vax-dec-bsd}, simply because the differences
+between Ultrix and @sc{BSD} are rarely noticeable, but a few programs
+might need to distinguish them.
+@c Real 4.4BSD now runs on some Suns.
+
+There is a shell script called @file{config.sub} that you can use
+as a subroutine to validate system types and canonicalize aliases.
+
+Other options are permitted to specify in more detail the software
+or hardware present on the machine, and include or exclude optional
+parts of the package:
+
+@table @samp
+@item --enable-@var{feature}@r{[}=@var{parameter}@r{]}
+Configure the package to build and install an optional user-level
+facility called @var{feature}. This allows users to choose which
+optional features to include. Giving an optional @var{parameter} of
+@samp{no} should omit @var{feature}, if it is built by default.
+
+No @samp{--enable} option should @strong{ever} cause one feature to
+replace another. No @samp{--enable} option should ever substitute one
+useful behavior for another useful behavior. The only proper use for
+@samp{--enable} is for questions of whether to build part of the program
+or exclude it.
+
+@item --with-@var{package}
+@c @r{[}=@var{parameter}@r{]}
+The package @var{package} will be installed, so configure this package
+to work with @var{package}.
+
+@c Giving an optional @var{parameter} of
+@c @samp{no} should omit @var{package}, if it is used by default.
+
+Possible values of @var{package} include
+@samp{gnu-as} (or @samp{gas}), @samp{gnu-ld}, @samp{gnu-libc},
+@samp{gdb},
+@samp{x},
+and
+@samp{x-toolkit}.
+
+Do not use a @samp{--with} option to specify the file name to use to
+find certain files. That is outside the scope of what @samp{--with}
+options are for.
+
+@item --nfp
+The target machine has no floating point processor.
+
+@item --gas
+The target machine assembler is GAS, the GNU assembler.
+This is obsolete; users should use @samp{--with-gnu-as} instead.
+
+@item --x
+The target machine has the X Window System installed.
+This is obsolete; users should use @samp{--with-x} instead.
+@end table
+
+All @code{configure} scripts should accept all of these ``detail''
+options, whether or not they make any difference to the particular
+package at hand. In particular, they should accept any option that
+starts with @samp{--with-} or @samp{--enable-}. This is so users will
+be able to configure an entire GNU source tree at once with a single set
+of options.
+
+You will note that the categories @samp{--with-} and @samp{--enable-}
+are narrow: they @strong{do not} provide a place for any sort of option
+you might think of. That is deliberate. We want to limit the possible
+configuration options in GNU software. We do not want GNU programs to
+have idiosyncratic configuration options.
+
+Packages that perform part of the compilation process may support cross-compilation.
+In such a case, the host and target machines for the program may be
+different. The @code{configure} script should normally treat the
+specified type of system as both the host and the target, thus producing
+a program which works for the same type of machine that it runs on.
+
+The way to build a cross-compiler, cross-assembler, or what have you, is
+to specify the option @samp{--host=@var{hosttype}} when running
+@code{configure}. This specifies the host system without changing the
+type of target system. The syntax for @var{hosttype} is the same as
+described above.
+
+Bootstrapping a cross-compiler requires compiling it on a machine other
+than the host it will run on. Compilation packages accept a
+configuration option @samp{--build=@var{hosttype}} for specifying the
+configuration on which you will compile them, in case that is different
+from the host.
+
+Programs for which cross-operation is not meaningful need not accept the
+@samp{--host} option, because configuring an entire operating system for
+cross-operation is not a meaningful thing.
+
+Some programs have ways of configuring themselves automatically. If
+your program is set up to do this, your @code{configure} script can simply
+ignore most of its arguments.
+
+@comment The makefile standards are in a separate file that is also
+@comment included by make.texinfo. Done by roland@gnu.ai.mit.edu on 1/6/93.
+@comment For this document, turn chapters into sections, etc.
+@lowersections
+@include make-stds.texi
+@raisesections
+
+@node Releases
+@section Making Releases
+
+Package the distribution of @code{Foo version 69.96} up in a gzipped tar
+file with the name @file{foo-69.96.tar.gz}. It should unpack into a
+subdirectory named @file{foo-69.96}.
+
+Building and installing the program should never modify any of the files
+contained in the distribution. This means that all the files that form
+part of the program in any way must be classified into @dfn{source
+files} and @dfn{non-source files}. Source files are written by humans
+and never changed automatically; non-source files are produced from
+source files by programs under the control of the Makefile.
+
+Naturally, all the source files must be in the distribution. It is okay
+to include non-source files in the distribution, provided they are
+up-to-date and machine-independent, so that building the distribution
+normally will never modify them. We commonly include non-source files
+produced by Bison, @code{lex}, @TeX{}, and @code{makeinfo}; this helps avoid
+unnecessary dependencies between our distributions, so that users can
+install whichever packages they want to install.
+
+Non-source files that might actually be modified by building and
+installing the program should @strong{never} be included in the
+distribution. So if you do distribute non-source files, always make
+sure they are up to date when you make a new distribution.
+
+Make sure that the directory into which the distribution unpacks (as
+well as any subdirectories) are all world-writable (octal mode 777).
+This is so that old versions of @code{tar} which preserve the
+ownership and permissions of the files from the tar archive will be
+able to extract all the files even if the user is unprivileged.
+
+Make sure that all the files in the distribution are world-readable.
+
+Make sure that no file name in the distribution is more than 14
+characters long. Likewise, no file created by building the program
+should have a name longer than 14 characters. The reason for this is
+that some systems adhere to a foolish interpretation of the POSIX
+standard, and refuse to open a longer name, rather than truncating as
+they did in the past.
+
+Don't include any symbolic links in the distribution itself. If the tar
+file contains symbolic links, then people cannot even unpack it on
+systems that don't support symbolic links. Also, don't use multiple
+names for one file in different directories, because certain file
+systems cannot handle this and that prevents unpacking the
+distribution.
+
+Try to make sure that all the file names will be unique on MS-DOS. A
+name on MS-DOS consists of up to 8 characters, optionally followed by a
+period and up to three characters. MS-DOS will truncate extra
+characters both before and after the period. Thus,
+@file{foobarhacker.c} and @file{foobarhacker.o} are not ambiguous; they
+are truncated to @file{foobarha.c} and @file{foobarha.o}, which are
+distinct.
+
+Include in your distribution a copy of the @file{texinfo.tex} you used
+to test print any @file{*.texinfo} or @file{*.texi} files.
+
+Likewise, if your program uses small GNU software packages like regex,
+getopt, obstack, or termcap, include them in the distribution file.
+Leaving them out would make the distribution file a little smaller at
+the expense of possible inconvenience to a user who doesn't know what
+other files to get.
+
+@contents
+
+@bye
+Local variables:
+update-date-leading-regexp: "@c This date is automagically updated when you save this file:\n@set lastupdate "
+update-date-trailing-regexp: ""
+eval: (load "/gd/gnuorg/update-date.el")
+eval: (add-hook 'write-file-hooks 'update-date)
+End:
diff --git a/gas/CONTRIBUTORS b/gas/CONTRIBUTORS
new file mode 100644
index 00000000000..b3fd03eb1bc
--- /dev/null
+++ b/gas/CONTRIBUTORS
@@ -0,0 +1,111 @@
+(This file is under construction.) -*- text -*-
+
+If you've contributed to gas and your name isn't listed here, it is
+not meant as a slight. I just don't know about it. Email me,
+raeburn@cygnus.com and I'll correct the situation.
+
+This file will eventually be deleted: The general info will go into
+the documentation, and info on specific files will go into an AUTHORS
+file, as requested by the FSF.
+
+++++++++++++++++
+
+Dean Elsner wrote the original gas for vax. [more details?]
+
+Jay Fenlason maintained gas for a while, adding support for
+gdb-specific debug information and the 68k series machines, most of
+the preprocessing pass, and extensive changes in messages.c,
+input-file.c, write.c.
+
+K. Richard Pixley maintained gas for a while, adding various
+enhancements and many bug fixes, including merging support for several
+processors, breaking gas up to handle multiple object file format
+backends (including heavy rewrite, testing, an integration of the coff
+and b.out backends), adding configuration including heavy testing and
+verification of cross assemblers and file splits and renaming,
+converted gas to strictly ansi C including full prototypes, added
+support for m680[34]0 & cpu32, considerable work on i960 including a
+coff port (including considerable amounts of reverse engineering), a
+sparc opcode file rewrite, decstation, rs6000, and hp300hpux host
+ports, updated "know" assertions and made them work, much other
+reorganization, cleanup, and lint.
+
+Ken Raeburn currently maintains gas, and wrote the high-level BFD
+interface code to replace most of the code in format-specific I/O
+modules.
+
+The original Vax-VMS support was contributed by David L. Kashtan.
+Eric Youngdale and Pat Rankin have done much work with it since.
+
+The Intel 80386 machine description was written by Eliot Dresselhaus.
+
+Minh Tran-Le at IntelliCorp contributed some AIX 386 support.
+
+The Motorola 88k machine description was contributed by Devon Bowen of
+Buffalo University and Torbjorn Granlund of the Swedish Institute of
+Computer Science.
+
+Keith Knowles at the Open Software Foundation wrote the original MIPS
+back end (tc-mips.c, tc-mips.h), and contributed Rose format support
+that hasn't been merged in yet. Ralph Campbell worked with the MIPS
+code to support a.out format.
+
+Support for the Zilog Z8k and Hitachi H8/300, H8/500 and SH processors
+(tc-z8k, tc-h8300, tc-h8500, tc-sh), and IEEE 695 object file format
+(obj-ieee), was written by Steve Chamberlain of Cygnus Solutions.
+Steve also modified the COFF back end (obj-coffbfd) to use BFD for
+some low-level operations, for use with the Hitachi, 29k and Zilog
+targets.
+
+John Gilmore built the AMD 29000 support, added .include support, and
+simplified the configuration of which versions accept which
+pseudo-ops. He updated the 68k machine description so that Motorola's
+opcodes always produced fixed-size instructions (e.g. jsr), while
+synthetic instructions remained shrinkable (jbsr). John fixed many
+bugs, including true tested cross-compilation support, and one bug in
+relaxation that took a week and required the proverbial one-bit fix.
+
+Ian Lance Taylor of Cygnus Solutions merged the Motorola and MIT
+syntaxes for the 68k, completed support for some COFF targets (68k,
+i386 SVR3, and SCO Unix), wrote the ECOFF support based on Michael
+Meissner's mips-tfile program, wrote the PowerPC and RS/6000 support,
+and made a few other minor patches. He handled the binutils releases
+for versions 2.7 through 2.9.
+
+David Edelsohn contributed fixes for the PowerPC and AIX support.
+
+Steve Chamberlain made gas able to generate listings.
+
+Support for the HP9000/300 was contributed by Glenn Engel of HP.
+
+Support for ELF format files has been worked on by Mark Eichin of
+Cygnus Solutions (original, incomplete implementation), Pete
+Hoogenboom at the University of Utah (HPPA mainly), Michael Meissner
+of the Open Software Foundation (i386 mainly), and Ken Raeburn of
+Cygnus Solutions (sparc, initial 64-bit support).
+
+Several engineers at Cygnus Solutions have also provided many small
+bug fixes and configuration enhancements.
+
+The initial Alpha support was contributed by Carnegie-Mellon
+University. Additional work was done by Ken Raeburn of Cygnus
+Solutions. Richard Henderson then rewrote much of the Alpha support.
+
+Ian Dall updated the support code for the National Semiconductor 32000
+series, and added support for Mach 3 and NetBSD running on the PC532.
+
+Klaus Kaempf ported the assembler and the binutils to openVMS/Alpha.
+
+Steve Haworth contributed the support for the Texas Instruction c30
+(tms320c30).
+
+H.J. Lu has contributed many patches and much testing.
+
+Alan Modra reworked much of the i386 backend, improving the error
+checking, updating the code, and improving the 16 bit support, using
+patches from the work of Martynas Kunigelis and H.J. Lu.
+
+Many others have contributed large or small bugfixes and enhancements. If
+you've contributed significant work and are not mentioned on this list, and
+want to be, let us know. Some of the history has been lost; we aren't
+intentionally leaving anyone out.
diff --git a/gas/COPYING b/gas/COPYING
new file mode 100644
index 00000000000..60549be514a
--- /dev/null
+++ b/gas/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gas/ChangeLog b/gas/ChangeLog
new file mode 100644
index 00000000000..852b6c7787d
--- /dev/null
+++ b/gas/ChangeLog
@@ -0,0 +1,3170 @@
+1999-04-30 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (mcore_s_section): Dump literals before
+ changing section.
+
+1999-04-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_apply_fix3): Insert reloc addend into insn
+ for COFF/PE port.
+
+Mon Apr 26 12:34:37 1999 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-fr30.h (TC_FIX_TYPE): Delete, cgen fields moved to write.h.
+ (TC_INIT_FIX_DATA): Delete.
+ * config/tc-m32r.h (TC_FIX_TYPE): Delete, cgen fields moved to write.h.
+ (TC_INIT_FIX_DATA): Delete.
+ * write.h (struct fix): New member fx_cgen, ifdef USING_CGEN.
+ * write.c (fix_new_internal): Initialize fx_cgen member.
+ * cgen.c (gas_cgen_record_fixup,gas_cgen_record_fixup_exp): Update.
+ (gas_cgen_md_apply_fix3): Update.
+ * config/tc-m32r.c (md_cgen_lookup_reloc): Update.
+ (md_cgen_record_fixup_exp): Update.
+ (FX_OPINFO_R_TYPE): Update.
+
+ * frags.c (frag_var,frag_variant): Initialize fr_cgen here.
+ * config/tc-fr30.h (TC_FRAG_INIT): Delete.
+ * config/tc-m32r.h (TC_FRAG_INIT): Delete.
+ * frags.h (struct frag): Make opindex, opinfo ints.
+
+ * config/tc-fr30.c (FX_OPINFO_R_TYPE): Delete, unused.
+
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-22 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_apply_fix3): Renamed function from
+ md_apply_fix.
+ (md_apply_fix3): Do not fix up absolute relocations against
+ symbolic values.
+
+ * config/tc-mcore.h (MD_APPLY_FIX3): Define.
+
+1999-04-20 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_pseudo_table): Add intercepts for section
+ changes and data-in-text directives.
+ (mcore_cons): New function: intercept cons() operations.
+ (mcore_float_cons): New function: intercept float_cons()
+ operations.
+ (mcore_stringer): New function: intercept stringer() operations.
+
+1999-04-18 Ian Lance Taylor <ian@zembu.com>
+
+ * obj.h (struct format_ops): Change generate_asm_lineno field to
+ take no parameters.
+ * config/obj-ecoff.h (OBJ_GENERATE_ASM_LINENO): Don't define.
+
+ * config/tc-alpha.c (find_opcode_match): Add default case to
+ switch.
+ (find_macro_match): Likewise.
+ (load_expression): Parenthesize && within ||.
+
+ * config/tc-alpha.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
+
+1999-04-17 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c (md_pseudo_table): Add overrides for .bss
+ .text .data .section pseudo ops.
+ (mcore_s_section): New function. Dump lits before changing secs.
+ (mcore_s_text): New function. Dump lits before changing secs.
+ (mcore_s_data): New function. Dump lits before changing secs.
+
+1999-04-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_32bitmode): New.
+ (md_begin): Set mips_32bitmode if needed.
+ (mips_elf_final_processing): Don't set EF_MIPS_ARCH.
+ Set EF_MIPS_32BITMODE.
+
+Fri Apr 16 12:26:39 1999 Bob Manson <manson@charmed.cygnus.com>
+
+ * config/obj-coff.c (c_section_symbol): Fix typo in previous
+ change.
+
+1999-04-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.h (LOCAL_LABELS_FB): Define to 1.
+
+Thu Apr 15 16:52:09 1999 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (pa_get_absolute_exression): Try to handle "5 %r3"
+ expressions correctly.
+
+
+1999-04-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_elf_final_processing): Set EF_MIPS_ARCH.
+
+Mon Apr 12 23:45:07 1999 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (pa_ip, case '3'): New case for PA2.0 fmpyfadd
+ and fmpynfadd instructions.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * as.h (environ): Declare it, if needed.
+ * as.c (dump_statistics): Don't declare environ.
+ * configure.in (environ): Detect declaration.
+ * configure, config.in: Rebuild
+
+ * config/tc-i386.c (i386_immediate): Accept @GOT relocations.
+ (i386_displacement): Allocate enough space for replacement buffer.
+ Clean up replacement buffer initialization.
+
+1999-04-11 Bob Manson <manson@charmed.cygnus.com>:
+
+ * subsegs.c (section_symbol): Don't create a new symbol if one
+ already exists; instead, use the existing one, but set its segment
+ and frag data if it hasn't already been defined.
+ * config/obj-coff.c (c_section_symbol): Likewise.
+
+Sat Apr 10 20:10:02 1999 Richard Henderson <rth@cygnus.com>
+
+ * tc-alpha.c (load_expression): Call as_bad instead of abort.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-mcore.c: New File: Support routines for MCore
+ assembler.
+ * config/tc-mcore.h: New File: Definitions for MCore assembler.
+ * config/obj-coff.c: Add support for mcore-pe target.
+
+ * Makefile.am: Add support for MCore targets.
+ * Makefile.in: Regenerate.
+ * configure.in: Add support for MCore targets.
+ * configure: Regenerate.
+
+ * doc/all.texi: Set MCORE.
+ * doc/as.texinfo: Document MCore specific command line options.
+
+ * write.h: Prevent multiple inclusion.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * asintl.h (LC_MESSAGES): Never define.
+ * as.c (main): Don't pass LC_MESSAGES to setlocale if the system
+ does not define it.
+ * gasp.c (main): Don't pass LC_MESSAGES to setlocale if the system
+ does not define it.
+
+ * Makefile.am (m68k-parse.c): If configuring in the source
+ directory, copy m68k-parse.y into the local directory before
+ running ylwrap, to remove spurious differences when generating
+ snapshots.
+ * Makefile.in: Rebuild.
+
+ * config/tc-sparc.h (md_do_align): Just allocate the number of
+ bytes necessary, rather than always allocating 1024.
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * listing.c (listing_newline): Add cast to avoid warning.
+ * read.c (generate_lineno_debug): Add cases to switch. Reindent.
+ * config/tc-i386.c (i386_scale): Add return value.
+ (build_displacement_string): Remove unused local temp_disp2.
+ (i386_intel_memory_operand): Add parentheses to avoid warning.
+ (i386_intel_operand): Remove unused local end_of_operand_string.
+ (i386_operand): Remove unused local operand_modifier.
+ (i386_operand): Add parens to avoid warning.
+
+1999-04-04 Don Bowman <don@pixsci.com>
+
+ * configure.in: Add mips*-*-vxworks* target; have it define
+ MIPS_STABS_ELF.
+ * configure, config.in: Rebuild.
+
+1999-03-31 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (emulations): Add support for arm-epoc-pe.
+ * configure: Regenerate.
+ * config/te-epoc-pe.h: New file. Define macros specific to
+ arm-epoc-pe target.
+ * config/tc-arm.h: Select epoc-pe-arm target format if configured
+ for arm-epoc-pe target.
+
+Mon Mar 29 10:15:40 CST 1999 Catherine Moore <clm@cygnus.com>
+
+ * tc-mips.c (md_apply_fix): Adjust value for linkonce sections.
+
+Wed Mar 24 14:11:10 1999 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (pa_parse_nonneg_cmpsub_cmpltr): Clean up code to
+ detect ",n" without a condition.
+ (pa_parse_neg_cmpsub_cmpltr): Likewise.
+
+
+Tue Mar 23 11:28:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (pa_ip, case '~'): The condition for a branch on bit
+ instruction is encoded with one bit.
+
+
+1999-03-23 Ian Lance Taylor <ian@zembu.com>
+
+ * doc/internals.texi (CPU backend): Mention that
+ line_separator_chars should not include newline. From thi
+ <ttn@mingle.glug.org>.
+
+1999-03-22 Doug Evans <devans@casey.cygnus.com>
+
+ * config/tc-fr30.c (md_begin): Update call to fr30_cgen_cpu_open.
+ * config/tc-m32r.c (md_begin): Update call to m32r_cgen_cpu_open.
+
+Sun Mar 21 18:08:18 1999 Richard Henderson <rth@cygnus.com>
+
+ * tc-alpha.c (md_assemble): Allow '6' in an opcode.
+
+Thu Mar 18 10:55:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (pa_ip, case 'a'): Do not call pa_parse_..._cmpsub_cmpltr.
+
+
+Thu Mar 18 02:30:07 1999 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (pa_ip, case 'd'): Do not allow ",n".
+
+1999-03-15 Martin Hunt <hunt@cygnus.com>
+
+ * app.c (do_scrub_begin): Change '-' back to a symbol char
+ so we can use multiple opcodes on a line again.
+
+ * config/tc-d30v.c: By default, warn if a symbol has
+ the same name as a register. Plus some minor
+ updates from the branch.
+
+1999-03-13 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Handle BFD_RELOC_8,
+ BFD_RELOC_16 and BFD_RELOC_64.
+
+1999-03-12 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * expr.c (expr): Add missing else.
+
+1999-03-12 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Improve error message.
+
+1999-03-11 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.am (CPU_TYPES): Add fr30.
+ (cgen.o): Add $(CGEN_CPU_PREFIX)-desc.h dependency.
+ (fr30,m32r dependencies): Update.
+ * Makefile.in: Rebuild.
+
+ * cgen.c (gas_cgen_record_fixup): Update use of operand->type.
+ (gas_cgen_record_fixup_exp): Ditto.
+ (gas_cgen_finish_insn): Call cgen_operand_lookup_by_num.
+ (gas_cgen_md_apply_fix3): Ditto. Update call to set_vma_operand.
+ * config/tc-fr30.c (md_begin): Update call to fr30_cgen_cpu_open.
+ (md_cgen_lookup_reloc): Update use of operand->type.
+ * config/tc-m32r.c (md_begin): Update call to fr30_cgen_cpu_open.
+ (md_convert_frag): Call cgen_operand_lookup_by_num.
+ (md_cgen_lookup_reloc): Update use of operand->type.
+ (m32r_cgen_record_fixup_exp): Ditto.
+
+1999-03-09 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * config/tc-mips.c (md_show_usage): Fix message.
+
+1999-03-03 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Syntax): Document new command line switches
+ and LDR reg,=<expr> instruction.
+
+ * config/tc-arm.c: Add support for -mcpu=arm810, -mcpu=arm9 and
+ -mcpu=arm9tdmi.
+
+Fri Feb 19 09:36:30 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/c-arm.texi (ARM-Chars): Fix typo in use of '@'.
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ This patch was created by: Scott Bambrough
+ <scottb@corelcomputer.com>
+
+ * app.c:
+ Special cased '@' character. The '@' character is used as the
+ ARM assembler comment character, as a special character
+ and in ELF .symver pseudo-op's, and as a special character in
+ .type and .section pseudo-ops.
+ (symver_pseudo): New static variable.
+ (symver_state): New static variable.
+ (struct app_save): Add field 'symver_state'.
+ (app_push): Save global symver_state int struct app_save.
+ (app_pop): Restore global symver_state from struct app_save.
+ (do_scrub_chars): Special case handling of '@' character in
+ .symver pseudo-ops.
+
+ * configure.in: Modified to recognize armv* uname syntax from ARM
+ Linux kernel.
+ * configure: Regenerated.
+
+ * config/obj-elf.c (obj_elf_section): Allow '%' as well as '@' as
+ a prefix to the section's type.
+ (obj_elf_type): Allow '%' as well as '@' and '#' as prefixes to
+ the type's typename.
+
+ * config/tc-arm.h: Add support for PIC generation:
+ (pic_code): New boolean.
+ (obj_relocate_extern): Define.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define
+ (TC_CONS_FIX_NEW): Define.
+ (tc_fix_adjustable): Define.
+ (GLOBAL_OFFSET_TABLE_NAME): Define.
+
+ * config/tc-arm.c: Add support for PIC generation:
+ (line_seperator_chars): Allow ';' as a seperator for Linux.
+ (is_immediate_prefix): New macro.
+ (arm_parse_reloc): New function.
+ (s_arm_elf_cons): New function.
+ (do_branch): Special case for BFD_RELOC_ARM_PLT32.
+ (md_undefined_symbol): Special case handling for the Global Offset
+ Table's symbol.
+ (md_apply_fix3): Handle PIC relocs.
+ (tc_gen_reloc): Handle PIC relocs.
+ (md_parse_option): Add support for '-k' command line switch to
+ enable PIC generation.
+ (cons_fix_new_arm): New function.
+ (s_arm_elf_cons): New function.
+
+Tue Feb 16 16:31:53 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add comments for uses of AC_DEFINE.
+ * acinclude.m4: Likewise.
+ * acconfig.h: Remove.
+ * aclocal.m4: Rebuild.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+ * config.in: Rebuild.
+
+1999-02-15 Jim Lemke <jlemke@cygnus.com>
+
+ * config/tc-mips.c (mips_ip: case 'o'): Fix assertion failure for
+ non-constant offset from a base register.
+
+1999-02-14 Ken Raeburn <raeburn@raeburn.org>
+
+ * config/tc-alpha.c (md_show_usage): Put \ before newline in
+ strings always.
+
+Sat Feb 13 14:10:10 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (cpu_types): Enable EV6 PALcode with -m21264.
+ (emit_insn): Look for pc-relative and no-overflow specifiers on
+ internal relocation types.
+
+1999-02-13 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * doc/c-mips.texi (MIPS Opts): Updated list of -mNNNN and
+ -mcpu=NNNN flags.
+
+ * config/tc-mips.c: Remove all the mips_NNNN variables; just use
+ mips_cpu instead.
+ (mips_4650, mips_4010, mips_4100): Variables removed.
+ (hilo_interlocks, gpr_interlocks, append_insn, macro_build, macro,
+ macro2, mips16_macro, mips_ip): Test mips_cpu, not the mips_NNNN
+ variables.
+ (md_begin): Don't bother initializing the mips_NNNN variables;
+ mips_cpu is set, and that's good enough now.
+ (md_parse_option): Have the -mNNNN options set mips_cpu instead of
+ the mips_NNNN variable. The -no-mNNNN flags are now no-ops.
+ (show): New function, to handle wrapping in the CPU lists.
+ (md_show_usage): Update lists of -mcpu and -mNNNN switches.
+
+Sat Feb 13 00:17:26 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_intel_operand): Ignore `SHORT' rather
+ than treat as an immediate specifier.
+
+Thu Feb 11 16:18:31 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c: Prototype many functions.
+ (set_intel_syntax): Accept `prefix'/`noprefix' specifiers.
+ (i386_immediate): Remove unused second argument.
+ (i386_intel_operand): Fix i386_is_reg typo.
+ (i386_operand): Use allow_naked_reg.
+ (output_invalid): Make operand int for K&R.
+
+Thu Feb 11 11:21:02 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (EXTRA_as_new_SOURCES): Uncomment--fixed by automake
+ patch.
+ * Makefile.in: Rebuild.
+
+1999-02-09 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.am (DISTCLEANFILES): Change cgen-opc.h to cgen-desc.h.
+ (cgen.o): Ditto.
+ (EXTRA_as_new_SOURCES): Comment out.
+ (.tcdep): <arch>-opc.h renamed to <arch>-desc.h.
+ * Makefile.in: Rebuild.
+ * doc/Makefile.in: Rebuild.
+ * configure.in: Require autoconf 2.13. Redo using_cgen handling.
+ Delete call to AM_CYGWIN32. Replace AM_EXEEXT with AC_EXEEXT.
+ (AC_OUTPUT): <arch>-opc.h renamed to <arch>-desc.h.
+ * configure: Rebuild.
+ * aclocal.m4: Rebuild.
+ * config.in: Rebuild.
+ * cgen.c: Include cgen-desc.h, not cgen-opc.h.
+ (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ (gas_cgen_cpu_desc): Renamed from gas_cgen_opcode_desc.
+ CGEN_INSN_ATTR renamed to CGEN_INSN_ATTR_VALUE.
+ CGEN_OPERAND_ATTR renamed to CGEN_OPERAND_ATTR_VALUE.
+ (gas_cgen_record_fixup): Remove unnecessary != 0 test.
+ (gas_cgen_record_fixup_exp): Ditto.
+ (gas_cgen_finish_insn): Ditto. Refer to operand table via cpu
+ descriptor, not global variable.
+ (gas_cgen_md_apply_fix3): Refer to operand_table via cpu
+ descriptor, not global variable. Refer to insert_operand handler
+ via cpu descriptor, not global function.
+ * cgen.h (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ * config/tc-fr30.c: Include opcodes/fr30-desc.h.
+ (*): gas_cgen_opcode_desc renamed to gas_cgen_cpu_desc.
+ CGEN_INSN_ATTR renamed to CGEN_INSN_ATTR_VALUE.
+ Update call to CGEN_OPERAND_TYPE,CGEN_INSN_OPERANDS.
+ * config/tc-m32r.c: Ditto.
+ (assemble_two_insns): Update calls to cgen_lookup_get_insn_operands.
+ (md_assemble): Ditto.
+ (md_convert_frag): Update call to CGEN_OPERAND_ENTRY.
+
+1999-02-09 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Fix handling of label1 - label2
+ relocations for ELF targets.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in: Add support for StrongARM target.
+ * configure: Regenerate.
+
+1999-02-05 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.h: Tidy OBJ_ELF and OBJ_COFF definitions.
+
+ * config/tc-arm.c (md_apply_fix3): Fix BFD_RELOC_ARM_PCREL_BRANCH
+ for COFF ports.
+
+Wed Feb 3 11:35:47 1999 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_show_usage): Document pca56 and ev6 options.
+
+Mon Feb 1 20:37:30 1999 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-i386.h (LONG_DOUBLE_MNEM_SUFFIX): Define.
+ (INTEL_DWORD_MNEM_SUFFIX): Define.
+ (BYTE_PTR): Define.
+ (WORD_PTR): Define.
+ (DWORD_PTR): Define.
+ (XWORD_PTR): Define.
+ (SHORT): Define.
+ (OFFSET_FLAT): Define.
+ (FLAT): Define.
+ (NONE_FOUND): Define.
+ (No_dSuf): Define.
+ (No_xSuf): Define.
+ * config/tc-i386.c (set_intel_syntax): New routine.
+ (intel_syntax): Declare.
+ (allow_naked_reg): Declare.
+ (md_pseudo_table): Support .intel_syntax and .att_syntax.
+ (intel_float_operand): New routine.
+ (md_assemble): Handle INTEL_DWORD_MNEM_SUFFIX.
+ Handle brackets as well as parens. Call i386_intel_operand for
+ intel syntax. Reverse operands if appropriate. Handle new
+ suffixes. Handle movzx and movsx.
+ (i386_is_reg): New routine.
+ (i386_immediate): New routine.
+ (i386_scale): New routine.
+ (i386_displacement): New routine.
+ (i386_operand_modifier): New routine.
+ (build_displacement_string): New routine.
+ (i386_parse_seg): New routine.
+ (i386_intel_memory_operand): New routine.
+ (i386_intel_operand): New routine.
+ (i386_operand): Call i386_displacement, i386_immediate,
+ i386_scale, etc. instead of handling inline.
+ (parse_register): Handle registers without prefix.
+
+Mon Feb 1 12:24:58 1999 Catherine Moore <clm@cygnus.com>
+
+ * configure: Regenerate.
+ * configure.in (arm-*-oabi): New.
+ (thumb-*-oabi): New.
+ * config/tc-arm.c (target_oabi): Declare.
+ (md_apply_fix3): Support REL relocs.
+ (md_parse_option): Handle -oabi.
+ (elf32_arm_target_format): New routine.
+ (md_longopts): Add OPTION_OABI.
+ * config/tc-arm.h: Redefine TARGET_FORMAT.
+
+
+1999-01-28 Nick Clifton <nickc@cygnus.com>
+
+ * write.c (write_relocs): Handle out of range error.
+
+ * config/tc-fr30.c (fr30_fix_adjustable): New function.
+ (fr30_force_relocation): Default to 0.
+
+ * config/tc-fr30.h (obj_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+
+ * cgen.c (gas_cgen_md_apply_fix3): Do not apply fixes to VTABLE
+ relocs.
+
+1999-01-16 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Do not generate a sequential
+ merge of two instructions if the left instruciton kills the right.
+
+1999-01-11 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.in: Regenerate.
+ * configure.in: Redo test for using cgen.
+ * configure: Regenerate.
+
+1999-01-09 Nick Clifton <nickc@cygnus.com>
+
+ * config/obj-coff.h (obj_adjust_symtab): Prevent accidental
+ redefinition of this macro.
+
+Tue Jan 5 21:58:03 1999 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-mips.c (mips_frob_file): Disable "Unmatched %hi reloc"
+ warning.
+
+1998-12-29 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (append_insn): For mips16, insert a nop between
+ a read of HI or LO and an immediatly following branch.
+
+1998-12-29 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Another correction to the setting of
+ mips_eabi64.
+
+1998-12-23 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Correct type-o in setting of mips_eabi64.
+
+1998-12-21 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (md_assemble): Emit a NOP after a relaxable 16
+ bit insn when optimizing, so that parallelised instructions will
+ start on a 32 bit boundary.
+
+1998-12-19 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_eabi64): New.
+ (md_begin): Set mips_eabi64.
+ (mips_elf_final_processing): Use it.
+
+1998-12-18 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_elf_final_processing):
+ Correct setting of ABI in e_flags.
+
+Wed Dec 16 16:17:22 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config/tc-fr30.c (md_assemble): Warn about invalid instructions in delay slots.
+
+1998-12-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin,md_parse_option): Handle vr4111.
+
+1998-12-15 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Mark as an error, rather than a
+ warning, values that don't fit in the field.
+
+1998-12-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (mips_abi_string): New.
+ (md_parse_option,md_longopts): Add mabi.
+ (mips_elf_final_processing): Set e_flags based on mabi flag.
+
+1998-12-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_parse_option): Handle vr4111.
+
+98-12-11 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-h8300.c (build_bytes): Change message given if the
+ instruction requires H8/300H mode and we're not in Hmode, to
+ suggest that it may be the operand modes that are the problem, not
+ necessarily the opcode.
+
+1998-12-10 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c: Add line separator character.
+
+Tue Dec 8 19:51:50 1998 Mark Klein <mklein@dis.com>
+
+ * configure.in (hppa-*-mpeix*): New target.
+ * config/obj-som.h (obj_som_compiler): Declare.
+ * config/obj-som.c (compiler_seen): New static variable.
+ (obj_som_compiler): New function.
+ * config/tc-hppa.c: Update tc_data uses for change to bfd/som.h.
+ (md_pseudo_table): Add "compiler" if OBJ_SOM.
+ (pa_type_args): Set hppa_priv_level.
+ (pa_compiler): New static function if OBJ_SOM.
+ * configure: Rebuild.
+
+Tue Dec 8 15:00:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (output_leb128): Don't mark as inline.
+
+1998-12-08 Andrew MacLeod <amacleod@cygnus.com>
+
+ * config/tc-ppc.c (ppc_vbyte): Prototype and new function for
+ AIX .vbyte unaligned data support.
+ (md_pseudo_table): Add 'vbyte' to list of valid pseudos.
+ (ppc_elf_validate_fix): Add eh_frame to list of ELF relocatable
+ sections.
+
+1998-12-07 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble, do_assemble): Improve erroneous
+ input handling.
+
+Mon Dec 7 09:48:34 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c (elf32_arm_force_relocation): Check for
+ BFD_RELOC_ARM_PCREL_BRANCH.
+
+Sun Dec 6 12:46:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Define TARGET_BYTES_{BIG,LITTLE}_ENDIAN after
+ checking the target type.
+ (mips-dec-bsd*): Set endian to little.
+ * configure: Rebuild.
+
+ COFF weak symbol support, based on patches from Mark Elbrecht
+ <snowball3@usa.net>:
+ * config/obj-coff.h (S_IS_WEAK): Define if not BFD_ASSEMBLER.
+ * config/obj-coff.c (obj_coff_weak): New static function.
+ (obj_coff_endef) [both versions]: Handle weak symbols.
+ (coff_frob_symbol): Likewise.
+ (yank_symbols): Likewise.
+ (obj_pseudo_table): Add "weak".
+
+ * configure.in (m68k-*-gnu*): New target. From Aymeric Vincent
+ <aymeric.vincent@emi.u-bordeaux.fr>.
+ * aclocal.m4: Rebuild with current tools.
+ * configure: Rebuild.
+
+ * config/tc-alpha.c (emit_ldgp): Give an error message rather than
+ an assertion failure for a case we can't handle when OBJ_ECOFF.
+
+ * expr.c (operator): And with 0xff to avoid problems with signed
+ char.
+
+1998-12-03 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Generate
+ BFD_RELOC_FR30_48 instead of BFD_RELOC_FR30_32.
+
+1998-12-02 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Enable relocs for
+ LDI:20 insn.
+
+Thu Nov 26 11:23:48 1998 Dave Brolley <brolley@cygnus.com>
+
+ * config/tc-fr30.c (md_pcrel_from_section): Restore previous calculation
+ of pcrel point.
+
+Tue Nov 24 17:21:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_pcrel_from_section): Fix calculation of
+ pcrel point.
+
+Tue Nov 24 14:54:38 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Make static 'etype' have file
+ scope.
+ (d10v_cleanup): Only generate previous insn if a multiline insn is
+ not pending.
+
+Fri Nov 20 11:41:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Add support for
+ FR30_OPERAND_I32.
+
+Thu Nov 19 15:01:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_parse_option): Add support for -marm7xxx and
+ -marm6xxx command line switches.
+
+1998-11-18 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.am (DEP): Use $(srcdir)/../mkdep.
+ (itbl-ops.o): Delete duplicate dependencies.
+ Rebuild dependencies.
+ Add fr30 dependencies.
+ * Makefile.in: Rebuild.
+
+Tue Nov 17 13:42:42 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (md_cgen_lookup_reloc): Updated to match latest
+ opcode list.
+ * listing.c: Ignore line terminator characters found inside
+ strings.
+
+Thu Nov 12 19:21:24 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/gas.pot: Regenerated.
+
+Thu Nov 12 10:54:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c (fr30_is_colon_insn): New name for
+ fr30_is_label_start(). Also checks for delay slot insns.
+
+ * config/tc-fr30.c (fr30_is_label_start): New function: Handle
+ FR30 instructions which contain a colon in the mnemonic.
+
+ * config/tc-fr30.h (TC_START_LABEL): Define this macro.
+
+Wed Nov 11 09:58:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.c: Removed currently superflous code.
+
+Tue Nov 10 13:13:05 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-fr30.h: New file.
+ * config/tc-fr30.c: Tweaking so that it will compile.
+
+Tue Nov 10 14:41:33 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-d10v.h (obj_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+ (d10v_force_relocation): Declare.
+ * config/tc-d10v.c (tc_gen_reloc): Handle Vtable relocs.
+ (md_apply_fix3): Handle Vtable relocs.
+ (d10v_fix_adjustable): New.
+ (d10v_force_relocation): New.
+
+Mon Nov 9 14:25:06 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c: Change default behaviour to ignore potential
+ conflicts between register name and symbol names.
+
+Wed Nov 4 18:42:00 1998 Dave Brolley <brolley@cygnus.com>
+
+ * configure.in: Add fr30-*-*.
+ * config/tc-fr30.c: New file.
+ * Makefile.in: Regenerated.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+ * doc/Makefile.in: Regenerated.
+ * po/gas.pot: Regenerated.
+
+Mon Nov 2 20:54:16 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-m32r.c (assemble_two_insns): Ensure both insns
+ are 16 bit insns.
+
+Mon Nov 2 20:10:18 1998 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * app.c (do_scrub_begin): Set characters above 127 to be symbol
+ characters.
+ (do_scrub_chars): Add some casts to unsigned char to avoid
+ unwanted sign extension.
+ * read.c (lex_type): Set characters about 127 to be symbol
+ characters.
+ * config/tc-i386.c (md_begin): Set identifier_chars and
+ operand_chars for values above 127.
+
+Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Tue Oct 27 13:18:40 1998 Nick Clifton <nickc@cygnus.com>
+
+ * listing.c: Add support for producing a listing from piped
+ input.
+
+Tue Oct 27 08:56:44 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (hilo_interlocks): Remove mips_3900.
+ (append_insn): Account for the tx39's multiply behavior.
+
+1998-10-26 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-m32r.c (assemble_two_insns): Rename assemble_two_insns
+ from assemble_parallel_insns. Add support for '->' to indicate
+ explicitly serializing the instructions.
+ (md_assemble): Ditto.
+
+Sat Oct 24 15:12:19 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sh.c (sh_fix_adjustable): Adjust EXTERN and
+ WEAK handling.
+
+Thu Oct 22 12:41:33 1998 Catherine Moore <clm@cygnus.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Revert last change.
+
+Thu Oct 22 10:03:15 1998 Ron Unrau <runrau@cygnus.com>
+
+ * config/tc-mips.c : support frame and regmask/fregmask when
+ MIPS_STABS_ELF is specified.
+
+Wed Oct 21 11;34:51 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sh.c (sh_fix_adjustable): Only include if OBJ_ELF.
+ (md_apply_fix): Don't return 1 for VTABLE relocs.
+ * config/tc-sh.h (obj_fix_adjustable): Define only if OBJ_ELF.
+
+Tue Oct 20 11:18:28 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * doc/c-i386.texi: Replace occurences of "opcode" with
+ "instruction mnemonic", "instruction", or "mnemonic" when
+ referring to the name of an instruction. Use "opcode" when
+ referring to the sequence of machine bytes.
+
+ * config/tc-i386.c (opcode_chars): Rename to mnemonic_chars.
+ (is_opcode_char): Rename to is_mnemonic_char.
+ (md_assemble and i386_operand): Correct error messages from
+ "opcode" to "instruction mnemonic"
+ Rename throughout opcode[] -> mnemonic[], opp -> mnem_p,
+ MAX_OPCODE_SIZE -> MAX_MNEM_SIZE,
+ DWORD_OPCODE_SUFFIX -> DWORD_MNEM_SUFFIX,
+ WORD_OPCODE_SUFFIX -> WORD_MNEM_SUFFIX,
+ BYTE_OPCODE_SUFFIX -> BYTE_MNEM_SUFFIX,
+ SHORT_OPCODE_SUFFIX -> SHORT_MNEM_SUFFIX
+ LONG_OPCODE_SUFFIX -> LONG_MNEM_SUFFIX
+
+ * config/tc-i386.h (*_MNEM_SUFFIX): Rename from *_OPCODE_SUFFIX.
+
+ * config/tc-i386.c (i386_operand): Check for garbage after
+ register name.
+
+Tue Oct 20 10:49:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_apply_fix3): Change handling of PCREL reloc
+ for BFD_ASSEMBLER to only change value when COFF if TE_PE.
+
+Mon Oct 19 20:20:42 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sh.h (obj_fix_adjustable): Define.
+ * config/tc-sh.c (sh_force_relocation): Handle VT relocs.
+ (md_apply_fix): Likewise.
+ (tc_gen_reloc): Likewise.
+ (sh_fix_adjustable): New.
+
+Mon Oct 19 12:35:43 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (gas_cgen_finish_insn): Update handling of CGEN_INT_INSN_P.
+ * cgen.h (gas_cgen_finish_insn): Update prototype.
+ * config/tc-m32r.c (m32r_insn): CGEN_INT_INSN -> CGEN_INT_INSN_P.
+ cgen_insn_t -> CGEN_INSN_INT.
+ (make_parallel): Update handling of CGEN_INT_INSN_P.
+ (assemble_parallel_insn): Ditto.
+ (target_make_parallel): New function.
+ (md_assemble): Use it.
+
+Mon Oct 19 13:16:12 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-m32r.c (m32r_force_relocation): Fix typo.
+
+Sun Oct 18 18:48:57 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-sh.c (md_assemble): Make sure the entire opcode is
+ converted into lower case.
+
+Fri Oct 16 13:36:34 CDT Catherine Moore <clm@cygnus.com>
+
+ * cgen.c (gas_cgen_md_apply_fix3): Handle VTABLE relocs.
+ (gas_cgen_tc_gen_reloc): Likewise.
+ * config/tc-m32r.h (obj_fix_adjustable): Define.
+ * config/tc-m32r.c (m32r_fix_adjustable): New.
+ (m32r_force_relocation): Handle VTABLE relocs.
+
+Wed Oct 14 11:33:38 1998 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Directives): Document .ltorn directive.
+
+Mon Oct 12 11:07:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (assemble_parallel_insn): Convert second opcode
+ to lower case before parsing.
+
+ * config/tc-d30v.c (parallel_ok): Ignore conflicts when explicitly
+ parallel insns modift buts in the PSW as a side effect.
+
+Thu Oct 8 10:18:33 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (find_format): Test for missing flag and
+ control registers.
+
+ (md_apply_fix3): Fix error messages to avoid
+ assumption about presence of a symbol.
+
+ (parallel_ok): Disallow parallel instructions that both modify the
+ same flag register.
+
+ (find_format): Generate a warning if an odd numbered register is
+ used as the first register in a mutli-register instruction.
+
+Wed Oct 7 14:09:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Do not assume that bad
+ relocations are always associated with a symbol.
+
+Tue Oct 6 09:31:15 1998 Catherine Moore <clm@cygnus.com>
+
+ * tc-sparc.h (TC_FORCE_RELOCATION): Define.
+ (elf32_sparc_force_relocation): Declare.
+ * tc-sparc.c (md_apply_fix3): Handle vtable relocs.
+ (tc_gen_reloc): Handle vtable relocs.
+ (elf32_sparc_force_relocation): New.
+
+Mon Oct 5 09:25:32 1998 Catherine Moore <clm@cygnsu.com>
+
+ * symbols.c (S_IS_FUNCTION): New.
+ * config/tc-v850.h (obj_fix_adjustable): Define.
+ (TC_FORCE_RELOCATION): Define.
+ (v850_force_relocation): Declare.
+ * config/tc-v850.c (tc_gen_reloc): Use offset instead
+ of fx_addnumber for VTABLE reloc addends.
+ (md_apply_fix3): Handle VTABLE relocs.
+ (v850_fix_adjustable): New.
+ (v850_force_relocation): New.
+
+Mon Oct 5 00:48:52 1998 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (fp_operand_format): Add some additional formats.
+ (pa_ip): Do not automatically promote into pa2.0 mode.
+ (pa_level): Handle ".level 2.0".
+
+Sun Oct 4 20:57:43 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Handle AMD_3DNOW_OPCODE.
+ * config/tc-i386.h (template.extension_opcode): Change to
+ unsigned int to allow full range of 8-bit opcode suffixes.
+ (None): Redefine as 0xffff.
+
+ From Jeff B Epler <jepler@usgs.gov>
+ * doc/c-i386.texi (i386-SIMD): New section.
+
+Thu Oct 1 15:37:54 1998 Richard Henderson <rth@cygnus.com>
+
+ * read.c (discard_rest_of_line): New function.
+ * read.h: Declare it.
+ * config/tc-alpha.c (s_alpha_mask, s_alpha_frame): Use it.
+
+Thu Oct 1 10:33:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (find_symbol_matching_register): New function.
+ (find_opcode): Cope with the case where a register name matches
+ a symbol name.
+
+Wed Sep 30 10:52:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_pcrel_from): Rename to
+ v850_pcrel_from_section.
+ (v850_pcrel_from_section): Do not resolves symbols in other
+ sections.
+
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Define.
+
+Mon Sep 28 11:01:20 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Generate an error if a register
+ is supplied for an operand that should not be a register.
+
+Fri Sep 25 10:04:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): But do allow delayed branch
+ instructions to have another instruction in the right bin.
+
+Thu Sep 24 09:28:34 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Do not allow instructions in
+ the right container if the left container holds a branch
+ instruction.
+
+Wed Sep 23 10:54:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (reg_name_search): Only warn if a name matches
+ both a register name and symbol name.
+ (find_format): Allow correct parsing of MVTSYS and MVFSYS insns.
+
+Tue Sep 22 17:49:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Implement EITHER_BUT_PREFER_MU
+ execution unit class.
+
+ (reg_name_search): If a name matches a register and a symbol,
+ prefer the register.
+ (find_format): Disallow flag registers when a general purpose
+ register is required.
+ If a number is required, but a register has been given, check to
+ see if a symbol with the same name as the register exists, and if
+ so, use that symbol.
+
+Tue Sep 22 16:40:52 1998 Jim Wilson <wilson@cygnus.com>
+
+ * config/obj-elf.h (ECOFF_DEBUGGING): Add missing parens.
+
+Tue Sep 22 15:44:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (find_format): Do not accept flag registers as
+ general purpose registers.
+ (find_format): If an immediate value is expected at a given place
+ in a format, but a register name has been provided instead, check
+ to see if that register name matches the name of a predefined
+ symbol and if it does, then use the symbol instead.
+ (reg_name_search): If a register name matches a symbol name,
+ prefer the register name to the symbol name.
+
+Mon Sep 21 10:42:57 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (m32r_do_align): After inserting NOPs, reset
+ the previous insn to empty.
+
+1998-09-20 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Do not break string into two
+ pieces, forcing the use of an ANSI compiler.
+
+Sun Sep 20 00:58:12 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.h (TC_FORCE_RELOCATION): New macro. Force vtable
+ relocs.
+ * config/tc-m68k.c (md_apply_fix_2): Do nothing for vtable relocs.
+
+Tue Sep 15 08:51:07 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit): Handle arm
+ assembler syntax.
+ (obj_elf_vtable_entry): Likewise.
+ * config/tc-arm.h: Define TC_FORCE_RELOCATION for OBJ_ELF.
+ * config/tc-arm.c (md_apply_fix3): Handle VTABLE relocations.
+ (tc_gen_reloc): Likewise.
+ (arm_fix_adjustable): Likewise.
+ (elf32_arm_force_relocation): New.
+ (armelf_frob_symbol): Remove coff-style symbol support.
+
+Wed Sep 9 11:27:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Fix typo in last patch.
+
+Tue Sep 8 18:10:01 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c (arm_adjust_symtab): Move #ifdef
+ OBJ_COFF so that routine is defined for a.out format.
+
+Tue Sep 8 15:56:19 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Detect non-segment registers
+ used as segment prefixes.
+
+Sat Sep 5 19:00:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ehopt.c (check_eh_frame): Check the size of the FDE, and don't
+ optimize across FDE boundaries.
+
+ * config/obj-coff.c (obj_coff_section): Preserve any link once
+ flags when setting the section flags.
+
+Fri Sep 4 17:07:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.h (obj_adjust_symtab): Fixed typo.
+ * config/tc-arm.c (armelf_adjust_symtab): Reformatted.
+
+Fri Sep 4 13:57:43 1998 Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
+
+ * config/tc-sparc.c (in_signed_range): Sign extend 32-bit words
+ to the host width.
+
+Wed Sep 2 11:31:14 1998 Richard Henderson <rth@cygnus.com>
+
+ * frags.c (frag_grow): Include the size of the frag struct in the
+ obstack chunk size.
+
+ * subsegs.c (subseg_set_rest): Adjust the seginfo frchain start
+ if the new subseg comes before the old.
+
+Tue Sep 1 15:01:33 1998 Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
+
+ * config/tc-sparc.c (sparc_ip): Allow all digits in an instruction
+ to handle edge8 and edge16.
+
+Mon Aug 31 09:51:14 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit): Print error message
+ before we clobber the symbol involved.
+
+Mon Aug 31 10:58:06 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-arm.c: Remove OBJ_ELF definitions for
+ S_GET_STORAGE_CLASS and S_SET_STORAGE_CLASS. Only
+ use arm_adjust_symtab for OBJ_COFF.
+ (armelf_adjust_symtab): New Routine.
+ * config/tc-arm.h: Define obj_adjust_symtab to
+ armelf_adjust_symtab for OBJ_ELF.
+
+Sat Aug 29 22:18:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Make all i386-elf targets use bfd_gas.
+ * config/tc-i386.c (tc_i386_force_relocation): New.
+ (tc_i386_fix_adjustable): Don't fix vtable relocs.
+ (md_apply_fix3): Likewise.
+ (tc_gen_reloc): Handle them.
+ * config/tc-i386.h (TC_FORCE_RELOCATION): Always define, calling
+ tc_i386_force_relocation.
+
+Mon Aug 24 13:40:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_show_usage): Improve formatting of --help output.
+
+Fri Aug 21 18:43:48 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Copy previous opcode over
+ current opcode after writing the first insturction of a reverse
+ sequential pair.
+
+Fri Aug 21 07:30:35 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * read.h (generate_lineno_debug): Add prototype.
+ * read.c (generate_lineno_debug): Make non-static.
+
+Thu Aug 20 23:17:04 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Only warn for address/data size
+ prefixes.
+
+Thu Aug 20 14:45:08 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (arm_fix_adjustable): Do not adjust relocations
+ against Thumb function names, as the linker needs this information.
+
+1998-08-20 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * expr.c (operand): Check also that there is no advance in operand
+ after atof_generic in order to decide "is it label 0f or floating
+ point number?".
+
+Wed Aug 19 09:30:16 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c: Replace double dash prefix to M32R specific
+ command line options with a single dash.
+ * doc/c-m32r.texi: Replace double dash prefix with a single dash.
+
+Tue Aug 18 11:59:43 1998 Catherine Moore <clm@cygnus.com>
+
+ * tc-arm.h: Define obj_fix_adjustable for OBJ_ELF.
+ * tc-arm.c (arm_fix_adjustable): New routine.
+
+1998-08-13 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * read.c (s_align, s_comm, s_mri_common, s_fail, s_globl, s_space,
+ s_float_space, s_struct, cons_worker): Move ignore_rest_of_line or
+ demand_empty_rest_of_line before mri_comment_end.
+ (equals): Check garbage after expression before
+ mri_comment_end in MRI mode.
+
+Thu Aug 13 15:08:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): Correct M_SGE_I/M_SGEUI_I case for a
+ small immediate constant to use the constant itself rather than
+ always using 1.
+
+Wed Aug 12 18:47:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-hppa.c (pa_enter): Call as_bad rather than abort.
+ (pa_leave): Likewise.
+
+Wed Aug 12 13:25:03 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Emit a warning for stand-alone
+ prefixes.
+ (i386_operand): Fix an error message.
+
+Tue Aug 11 14:44:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Directives): Document .req directive.
+
+ * config/tc-arm.c (reg_required_here): Display erroneous string if
+ the register name could not be decoded.
+ Do not set inst.instruction if the sift is -1.
+
+Mon Aug 10 15:39:56 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (tc_gen_reloc): Bias WEAK symbols just as
+ we do for EXTERN.
+
+Mon Aug 10 15:06:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (d30v_align): Always perform alignment request,
+ even if it is belived to be unnecessary.
+
+Mon Aug 10 17:48:09 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ config/tc-i386.c (i386_operand): Size immediate constants by
+ suffix (erroneously removed as part of July 7 change).
+
+Sun Aug 9 20:45:32 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/obj-elf.h: Check for redefinition of obj_frob_symbol.
+ * config/tc-arm.c: Define S_GET_STORAGE_CLASS and S_SET_STORAGE_CLASS.
+ (armelf_frob_symbol): New Routine.
+ * config/tc-arm.h: Define obj_frob_symbol if OBJ_ELF.
+
+Sat Aug 8 15:21:28 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (alpha_fix_adjustable): Don't adjust weak syms.
+
+Wed Aug 5 15:54:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_begin): Set BFD private flags depending upon
+ command line switches passed to assembler.
+
+Mon Aug 3 14:02:52 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (GAS_CGEN_MAX_FIXUPS): GAS_ prepended, all uses updated.
+ (gas_cgen_opcode_desc): Declare.
+ (gas_cgen_parse_operand): Declare.
+ (*): Prepend gas_ to gas specific fns to denote them as such.
+ All uses updated.
+ * cgen.c (gas_cgen_opcode_desc): New global
+ (gas_cgen_init_parse): Renamed from cgen_asm_init_parse.
+ (queue_fixup): Renamed from cgen_queue_fixup.
+ (*): Prepend gas_ to gas specific fns to denote them as such.
+ All uses updated.
+ (gas_cgen_md_apply_fix3): Update call to insert_operand.
+ (gas_cgen_finish_insn): Renamed from cgen_asm_finish_insn.
+ * config/tc-m32r.c (md_begin): Remove use of CGEN_SYM.
+ Open opcode table and initialize it.
+ (make_parallel): Use gas_cgen_opcode_desc.
+ (assemble_parallel_insn): Ditto. Remove use of CGEN_SYM.
+ (md_assemble): Ditto.
+
+Sat Aug 1 19:27:30 1998 Richard Henderson <rth@cygnus.com>
+
+ * as.h (debug_info_type): Add entries for unspecified and dwarf*.
+ * ecoff.c (ecoff_generate_asm_lineno): Take no arguments; call
+ as_where ourselves. Provide a stub for !ECOFF_DEBUGGING.
+ * ecoff.h: Move ECOFF_DEBUGGING protection inside GAS_ECOFF_H.
+ Move ecoff_generate_asm_lineno outside ECOFF_DEBUGGING protection.
+ * read.c (generate_lineno_debug): Tidy ECOFF bits. Use
+ DEBUG_UNSPECIFIED rather than DEBUG_NONE for initial test.
+ * config/obj-elf.h (ECOFF_DEBUGGING) [TC_ALPHA]: Define to a variable.
+ (SEPARATE_STAB_SECTIONS): Conditionalize on value of ECOFF_DEBUGGING.
+ (INIT_STAB_SECTION): Likewise.
+ (OBJ_PROCESS_STAB): Likewise.
+
+ * config/tc-alpha.c (md_longopts): New options -mdebug/-no-mdebug.
+ (md_parse_option): Watch for them.
+ (alpha_cur_ent_sym, alpha_flag_mdebug): New variables.
+ (md_begin): Kill neverdef code.
+ (s_alpha_ent, s_alpha_end, s_alpha_mask, s_alpha_frame): New.
+ (s_alpha_prologue): Watch alpha_cur_ent_sym.
+ (s_alpha_coff_wrapper): New.
+ (md_pseudo_table): Trap all ECOFF pseudos.
+
+Fri Jul 31 16:45:54 1998 Ron Unrau <runrau@cygnus.com>
+
+ Start of changes to remove mdebug section from mips*-elf
+ Based on MIPS_STAB_ELF definition
+ * acconfig.h: undef if not configured
+ * config.in: undef if not configured
+ * config/mips-elf.h: only set ECOFF debugging if not stabs-in-elf
+ * config/tc-mips.c (s_ent): set BSF_FUNCTION
+ * stabs.c (s_stab_generic): flush frag
+
+Fri Jul 31 16:14:45 1998 Catherine Moore <clm@cygnus.com>
+
+ * configure.in: (arm-*-elf): Handle.
+ (thumb-*-elf): Handle.
+ * configure: Regenerate.
+ * read.c (stringer): Fix typo in comment.
+ * write.c (fixup_segment): Don't add symbol value to addend if
+ TC_ARM and OBJ_ELF.
+ * config/tc-arm.c (md_section_align): Don't align dwarf debug
+ sections.
+ (tc_gen_reloc): Always set the reloc addend to fixp->fx_offset
+ for OBJ_ELF.
+
+Thu Jul 30 21:38:43 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-d30v.c ({cur,prev}_left_kills_right_p): New variables.
+ (write_2_short): Emit warning if new flag is set.
+ (do_assemble): Set flags if left instruction is one of special
+ "right-instruction-killer" type.
+
+Tue Jun 28 18:12:28 1998 Stan Cox <scox@cygnus.com>
+
+ * config/tc-sparc.c (md_number_to_chars, cons_fix_new_sparc):
+ Always output words in debug_info section as big endian.
+ (sparc_target_format): Choose correct bfd target.
+ (md_apply_fix3): Rename BFD_RELOC_SPARC_32LE to BFD_RELOC_SPARC_REV32.
+
+Tue Jul 28 11:01:21 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Fix "errmsg" initialization
+ to work with internationalization code. Issue an error when two
+ operands match that are not allowed to match.
+
+Mon Jul 27 16:25:58 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * configure.in (install_tooldir): Allow target to specify whether
+ it wants to be installed in $(tooldir)/bin.
+ * configure: Regenerate.
+ * Makefile.am (install-exec-local): Set install-exec-tooldir
+ dependency via configure.
+ * Makefile.in: Regenerate.
+
+Fri Jul 24 19:58:59 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.am (install-exec-local): Split into two ...
+ (install-exec-bindir,install-exec-tooldir): New rules.
+ * Makefile.in: Regenerate.
+
+Fri Jul 24 16:31:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (install-exec-local): Don't remove the file before
+ checking whether $(bindir) == $(tooldir)/bin. From Maciej
+ W. Rozycki <macro@ds2.pg.gda.pl>.
+ * Makefile.in: Rebuild.
+
+Fri Jul 24 09:13:46 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * cgen.c: Include libiberty.h.
+ (cgen_md_apply_fix3): Update call to md_cgen_lookup_reloc.
+ (cgen_tc_gen_reloc): Use xmalloc, not bfd_alloc.
+ * cgen.h (cgen_md_apply_fix3,cgen_tc_gen_reloc): Declare.
+ (md_cgen_lookup_reloc)): Declare.
+ (md_cgen_record_fixup_exp): Declare.
+ * config/tc-m32r.h (md_pcrel_from_section): Declare.
+ (m32r_relax_frag): Declare.
+ (cgen_md_apply_fix3): Decls moved to cgen.h.
+ (cgen_record_fixup_exp,cgen_tc_gen_reloc): Ditto.
+ (m32r_cgen_record_fixup_exp): Delete decl.
+ * config/tc-m32r.c (m32r_cpu_desc): #if 0 out.
+ (assemble_nop): Delete.
+ (expand_debug_syms): Delete unused `exp'.
+ (md_cgen_lookup_reloc): Renamed from CGEN_SYM (lookup_reloc).
+ Add default case for -Wall.
+ (m32r_cgen_record_fixup_exp): Add default case for -Wall.
+ (md_atof): Delete unused wordP.
+
+Thu Jul 23 13:19:50 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Make sure "errmsg" has a non-NULL
+ value.
+
+Wed Jul 22 14:36:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Add documentation for .end, .exitm, .fail,
+ .ifc, .ifeqs, .ifge, .ifgt, .ifle, .iflt, .ifnc, .ifne, .ifnes,
+ .print, .purgem, and .struct. Remove documentation for
+ .app-file.
+
+Tue Jul 21 16:50:52 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (cgen_md_apply_fix3): set_operand renamed to set_vma_operand.
+ Update call to insert_operand.
+
+Fri Jul 17 11:42:20 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (ms_show_usage): Formatting changes.
+
+Wed Jul 15 15:38:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Don't get confused by trailing
+ whitespace after a prefix operator.
+
+Tue Jul 14 15:32:56 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in (i386-*-beos{pe,elf,}*): Recognize.
+
+Tue Jul 14 12:33:44 1998 Chris Torek <torek@bsdi.com>
+
+ * config/tc-sparc.c (log2): New static function.
+ (s_reserve): Use log2 to convert alignment before calling
+ record_alignment.
+ (s_common): Use log2 to convert alignment before calling
+ record_alignment and frag_align.
+ (sparc_cons_align): Use log2.
+
+Tue Jul 14 11:58:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (s_reserve): Set symbol size if OBJ_ELF.
+ (s_common): Likewise.
+
+ * config/tc-sparc.c (sparc_handle_align): Reindent a bit. Correct
+ initialization of waddr.
+ (sparc_elf_final_processing): Add default case to switch.
+
+Tue Jul 14 11:00:16 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * doc/c-i386.texi: Fix a typo. Use the term 80-bit real rather
+ than temporary real.
+
+Mon Jul 13 13:55:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (subsegs_finish): Don't align the segments if there were
+ any errors.
+
+ * config/obj-coff.c (c_symbol_merge): Correct number of bytes when
+ copying aux information.
+
+ * expr.c (make_expr_symbol): Catch attempts to turn an O_big
+ expression into a symbol.
+
+Mon Jul 13 13:29:04 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (mode_from_disp_size): Change arg and return
+ type to unsigned int.
+ (md_assemble): Change type used to store offsets from unsigned
+ long to long.
+ (i386_operand): Switch error check to only call RESTORE_END_STRING
+ once after parse_register.
+
+Fri Jul 10 16:00:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_show_usage): Changed format to match that
+ of gcc, ld, etc.
+
+ * as.c (show_usage): Changed format to match that of gcc, ld, etc.
+
+Thu Jul 9 12:09:57 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (tc_m68k_fix_adjustable): Don't adjust vtable
+ relocs.
+ (md_apply_fix_2): Force the symbol of the vtable reloc to be
+ weak.
+
+Thu Jul 9 11:31:54 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/Makefile.am (MAINTAINERCLEANFILES): Define.
+ * doc/Makefile.in: Rebuild.
+
+Wed Jul 8 12:18:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip, case 'i' and 'j'): Mask off high bits
+ for %lo expressions.
+ (mips_ip, case 'u'): Move range check after code to mask
+ off bits in %hi/%lo expressions. Mask off high bits for
+ %lo expressions.
+
+Tue Jul 7 17:57:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/Makefile.am (gasver.texi): New target.
+ (as.info, as.dvi): Depends upon gasver.texi.
+ * doc/as.texinfo: Include gasver.texi. Mention version number on
+ title page and in top node.
+ * doc/Makefile.in: Rebuild.
+
+Tue Jul 7 11:42:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (listing_listing): For EDICT_LIST, skip all lines up to
+ but not including the line containing the edict.
+ * listing.h (LISTING_EOF): New.
+ * input-scrub.c (input_scrub_next_buffer): Call it.
+
+Tue Jul 7 13:00:37 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_operand): Don't set the size of an
+ immediate address based solely on the suffix and the mode.
+
+ * config/tc-i386.c (md_assemble): Add assertion to make sure
+ overlap2 does not set Imm.
+
+ * config/tc-i386.c (space_chars): Remove. The scrubber converts
+ sequences of whitespace to a single space.
+ (is_space_chars): Just compare with space.
+ (md_begin): Don't initialize space_chars.
+ (md_assemble): Just skip a single whitespace character.
+ (i386_operand): Rewrite base-index parsing to use new
+ parse_register, and to skip white space. Skip white space in a
+ number of other places too. Don't give error message if
+ parse_register fails.
+ (parse_register): Change reg_string parameter to be non-const.
+ Add end_op parameter. Skip white space after the `%', and return
+ end of register string. Give error message here rather than
+ caller.
+
+Fri Jul 3 15:34:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from Matt Semersky <matts@scd.hp.com>:
+ * expr.c (op_encoding): Make const.
+ (expr_set_precedence): New function.
+ (expr_begin): Don't set operator rankings, just call
+ expr_set_precedence.
+ * expr.h (expr_set_precedence): Declare.
+ * read.c (s_mri): Call expr_set_precedence.
+
+Thu Jul 2 16:24:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Statements): Remove paragraph discussing
+ continuing lines with a backslash. This hasn't worked for years,
+ if it ever did.
+
+Thu Jul 2 14:06:22 1998 Klaus Kaempf <kkaempf@rmi.de>
+
+ * obj-vms.c: Add C++ support with ctors/dtors sections. Add weak
+ symbol definitions.
+ (Ctors_Symbols, Dtors_Symbols): New symbol chains.
+ (ps_CTORS, ps_DTORS): New section types.
+ (vms_fixup_xtors_section): New function
+ (Ctors_Psect, Dtors_Psect): Define.
+ (IS_GXX_XTOR): Define
+ (global_symbol_directory): Change check of gxx_bug_fixed to 0.
+ Filter static constructors/destructors and add to
+ Ctors_Symbols/Dtors_Symbols chain.
+ (vms_write_object_file): Write Ctors_Symbols/Dtors_Symbols to
+ appropriate section.
+
+ * tc-alpha.h (TARGET_FORMAT): Rename "evax-alpha" to "vms-alpha".
+ * makefile.vms: Merge vax/vms support.
+
+Wed Jul 1 20:06:20 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_vtable_inherit, obj_elf_vtable_entry): New.
+ (elf_pseudo_table): Add them.
+ * config/tc-mips.c (mips_force_relocation): Force vtable relocs.
+ (md_apply_fix): Accept them.
+ (mips_fix_adjustable): Don't adjust them.
+ (tc_gen_reloc): Mung BFD_RELOC_VTABLE_ENTRY for Rel.
+ * config/tc-ppc.c (md_apply_fix3): Accept vtable relocs.
+ * config/tc-ppc.h (TC_FORCE_RELOCATION_SECTION): Force vtable relocs.
+ (tc_fix_adjustable): Don't adjust them.
+
+Wed Jul 1 16:35:32 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * Makefile.am (CGEN_CPU_PREFIX): New variable.
+ (cgen.o): Use it.
+ * Makefile.in: Regenerate.
+ * configure.in: AC_SUBST cgen_cpu_prefix.
+ * configure: Regenerate.
+
+Wed Jul 1 21:38:56 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh (COND_JUMP_DELAY, COND12_DELAY_LENGTH): Define.
+ Changed all users of COND12_DELAY.
+
+Fri Jun 26 11:21:11 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (set_arch_mach): New function.
+ (md_pseudo_table): Add pseudo-ops to set the current machine type.
+ (md_begin): Default to mn10300 mode.
+ (md_assemble): Only accept instructions for the core mn10300
+ chip and the active machine type.
+
+Wed Jun 24 19:06:04 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.h (segment_info_type): Give the struct a name.
+ * config/tc-h8300.h (tc_reloc_mangle): Add prototype.
+ * config/tc-h8500.h (tc_reloc_mangle): Declare.
+ * config/tc-sh.h (sh_coff_reloc_mangle): Add prototype.
+ * config/tc-w65.h (tc_reloc_mangle): Declare.
+ * config/tc-z8k.h (tc_reloc_mangle): Declare.
+
+Wed Jun 24 13:45:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (v850_comm): Restore old section
+ after common processing.
+
+Wed Jun 24 11:50:54 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * config/obj-vms.c (Create_VMS_Object_File): Force binary file.
+
+Tue Jun 23 17:47:31 1998 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-h8300.c (do_a_fix_imm, build_bytes): Replace cast to
+ char with code that explicitly sign-extends.
+
+Tue Jun 23 13:54:57 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_begin): Restore text section as the current
+ section after creating call table sections.
+ * config/obj-coff.h (SYM_AUXINFO): New macro to conceal ugly
+ code.
+
+ * config/obj-coff.c (c_symbol_merge): Replace complex expresion
+ with call to macro SYM_AUXINFO.
+
+Tue Jun 23 15:09:27 1998 Mike Stump <mrs@wrs.com>
+
+ * Makefile.am (install-exec-local): Don't let EXEEXT interfere
+ with the program transform name.
+ * Makefile.in: Rebuild.
+
+Mon Jun 22 19:52:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (c_symbol_merge): Fix copying of auxiliary
+ information.
+
+Mon Jun 22 15:18:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Be prepared for a space between
+ the open parenthesis and the start of the register operand,
+ because of the June 16 change.
+
+Sun Jun 21 21:27:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): Handle weak symbols correctly if
+ BFD_ASSEMBLER.
+
+Sun Jun 21 12:26:36 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (d30v_align): Always perform alignment request,
+ even if it is belived to be unnecessary.
+
+Fri Jun 19 13:57:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Never adjust relocs against weak
+ symbols.
+ * config/tc-mips.c (md_apply_fix): Adjust accordingly.
+
+Fri Jun 19 09:50:17 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Do not hardcode the
+ shift amount for a repeated operand. The shift amount for the
+ repeated copy comes from the size of the operand.
+
+Fri Jun 19 00:44:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (get_operand): Fix typos in ldm/stm support.
+
+Wed Jun 17 13:07:05 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_show_usage): Fix -mipsN usage.
+
+Tue Jun 16 13:06:21 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * app.c (do_scrub_begin): If tc_symbol_chars is defined, treat all
+ characters in it as LEX_IS_SYMBOL_COMPONENT.
+ * config/tc-i386.h (tc_symbol_chars): Define.
+ (extra_symbol_chars): Declare.
+ * config/tc-i386.c (extra_symbol_chars): Define.
+ (comment_chars): Don't use '/' as comment start if TE_LINUX.
+ (line_comment_chars): Set to '/' if TE_LINUX.
+ * doc/c-i386.texi (i386-prefixes): Update.
+ * doc/internals.texi (CPU backend): Document tc_symbol_chars.
+
+Fri Jun 12 13:36:54 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): If maintainer mode, depend on .pot file.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+1998-06-12 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/tc-d10v.c (md_apply_fix3): Checking displacement
+ constraint in instructions REP & REPI.
+
+Thu Jun 11 08:56:46 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Catch BFD_RELOC_8,
+ BFD_RELOC_16, BFD_RELOC_64 and issue appropriate error messages.
+
+ (check_range): If the operand is shifted, then shift the number
+ before checking its range.
+
+ * write.c (adjust_reloc_syms): Add more checks for NULL pointers.
+
+ * config/tc-v850.c (v850_comm): Set SEC_COMMON bit on special
+ common sections.
+
+Wed Jun 10 17:26:35 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_comm): Create special sections as needed.
+
+1998-06-10 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * config/tc-d10v.c (write_2_short): Addition of swapping
+ instructions for sequential and reverse sequential order when
+ given order is not possible.
+
+Tue Jun 9 13:52:53 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (DEP_INCLUDES): Fix reference to intl build directory.
+ * Makefile.in: Rebuild.
+
+Tue Jun 9 12:20:05 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * doc/c-i386.texi: Update 16 bit documentation.
+
+ * config/tc-i386.h: Change Data16 to Size16, Data32 to Size32,
+ IgnoreDataSize to IgnoreSize as they are used for address size as
+ well as data size.
+ * config/tc-i386.c: Likewise. Add code to reject addr32/data32 in
+ 32-bit mode, similarly addr16/data16 and variants.
+
+Mon Jun 8 18:32:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Fix handling of reverse
+ sequential word multiply instructions.
+
+ (do_assemble): Add extra command line argument, to allow mul32
+ attribute to be preserved across parallel insns.
+ (md_assemble): Insert NOPs between explicitly parallel insns which
+ contain an 32 bit multiply and a 16 multiply.
+
+Mon Jun 8 12:20:30 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c: REPNE renamed to REPNE_PREFIX_OPCODE, and
+ likewise for REPE.
+
+ * config/tc-i386.c (reloc): Add braces.
+
+ * config/tc-i386.c (struct _i386_insn): Rename bi to sib to be
+ consistent with Intel naming.
+ * config/tc-i386.h (base_index_byte): Rename to sib_byte. Don't
+ use bitfields in sib_byte.
+ (modrm_byte): Don't use bitfields here either.
+
+ * config/tc-i386.c (current_templates): Add const.
+ (parse_register): Add const to return, param, and char *s.
+ (i386_operand): Add const to reg_entry *r.
+ * config/tc-i386.h (templates): Add const to start, end.
+
+ Inspired by code for 16 bit gas support from Martynas Kunigelis
+ <martynas@nm3.ktu.lt>:
+ * config/tc-i386.c (md_assemble): Add full support for 16 bit
+ modrm, and Jump, JumpByte, JumpDword, JumpInterSegment insns.
+ (uses_mem_addrmode): Remove.
+ (md_estimate_size_before_relax): Add support here too.
+ (md_relax_table): Rewrite interface to md_relax for 16 bit
+ support.
+ (BYTE, WORD, DWORD, UNKNOWN_SIZE): Remove.
+ (opcode_suffix_to_type): Remove.
+ (CODE16, SMALL, SMALL16, BIG, BIG16): Define.
+ (SIZE_FROM_RELAX_STATE): Modify to suit above.
+ (md_convert_frag): Likewise.
+ (i386_operand): Add support for 16 bit base/index regs,
+ immediates, and displacements. Remove some unnecessary casts, and
+ localise end_of_operand_string, displacement_string_start,
+ displacement_string_end variables. Add GCC_ASM_O_HACK.
+ * config/tc-i386.h (NO_BASE_REGISTER_16): Define.
+
+ * config/tc-i386.c (prefix_hash): Remove.
+ (md_begin): Rewrite without obstacks. Remove prefix hash table
+ handling. Rewrite lexical table handling.
+ (i386_print_statistics): Don't print prefix statistics.
+ (md_assemble): Rewrite instruction parser so that line is not
+ converted to lower case. Don't do a hash_find for prefixes,
+ instead recognise them via opcode modifier.
+ (expecting_operand, paren_not_balanced): Localise variables.
+ * config/tc-i386.h (IsPrefix): Define.
+ (prefix_entry): Remove.
+
+ * config/tc-i386.h (PREFIX_SEPERATOR): Don't define.
+ * config/tc-i386.c (PREFIX_SEPARATOR): Define here instead, using
+ '\\' in case where comment_chars contains '/'.
+
+ * config/tc-i386.c (MATCH): Ensure given operand and template
+ match for JumpAbsolute. Makes e.g. `ljmp table(%ebx)' invalid;
+ you must write `ljmp *table(%ebx)'.
+
+ From H.J. Lu <hjl@gnu.org>:
+ * config/tc-i386.c (BFD_RELOC_16, BFD_RELOC_16_PCREL): Define
+ as 0 ifndef BFD_ASSEMBLER.
+ (md_assemble): Allow immediate operands without suffix or
+ other reg operand to default in size to the current code size.
+
+Mon Jun 8 09:45:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (md_begin): Restore creation of
+ .call_table_text and .call_table_data sections.
+
+Sat Jun 6 00:02:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Set execution type to unknown
+ after emitting a word of noops.
+
+Fri Jun 5 23:27:04 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (mode_from_disp_size): Disp16 is mode 2.
+ (i386_operand): Simplify checks for valid base/index combinations.
+ Disallow `in 4(%dx),%al'.
+
+ * config/tc-i386.c (struct _i386_insn): Make regs, base_reg, and
+ index_reg const.
+ (add_prefix): Change parameter from char to int.
+
+ * config/tc-i386.h (Ugh): Define opcode modifier.
+ * config/tc-i386.c (md_assemble): Print warnings for Ugh insns.
+
+ * config/tc-i386.c (md_assemble): Rewrite MATCH and
+ CONSISTENT_REGISTER_MATCH macros to check register types more
+ thoroughly. Check for illegal suffix/operand combinations
+ when matching insns with operands. Handle new `s' suffix, and
+ associated FloatMF opcode modifier for float insns with memory
+ operands.
+ * config/tc-i386.h (FloatMF): Define new opcode modifier.
+ (No_sSuf, No_bSuf, No_wSuf, No_lSuf): Likewise.
+ (SHORT_OPCODE_SUFFIX, LONG_OPCODE_SUFFIX): Define.
+ * config/tc-i386.c: Rename WORD_PREFIX_OPCODE to
+ DATA_PREFIX_OPCODE throughout.
+
+ * config/tc-i386.c (REGISTER_WARNINGS): Define.
+ (md_assemble): Rewrite suffix/register operand checking code to be
+ more thorough. Remove Abs8,16,32. Change occurrences of Mem to
+ AnyMem, the better to grep.
+ (pi): Remove Abs.
+ (i386_operand): Don't set Mem bits in i.types[this_operand] when
+ given a memory operand. Don't set Abs bits either.
+ (type_names): Remove Mem*, Abs*.
+ * config/tc-i386.h (Mem8, Mem16, Mem32, Abs8, Abs16, Abs32): Don't
+ define opcode_modifiers as these cases are handled by Disp8,
+ Disp16, Disp32 and suffix checks.
+ (COMES_IN_BOTH_DIRECTIONS): Remove.
+ (FloatR): Define. It's OK to share the bit with ReverseRegRegmem.
+
+ * config/tc-i386.c (md_assemble): Don't emit operand size prefix
+ if IgnoreDataSize modifier given. Remove ShortformW modifier
+ test. Add test for ShortForm in W base_opcode modification.
+ Merge Seg2ShortForm and Seg3ShortForm code.
+ * config/tc-i386.h (ShortFormW): Remove.
+ (IgnoreDataSize): Define.
+
+Fri Jun 5 10:50:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): Store previous segment state
+ with previous instruction.
+
+Wed Jun 3 18:21:56 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (SCALE1_WHEN_NO_INDEX): Define.
+ (ebp, esp): Remove static variables.
+ (MATCH): Remove test for InOutPortReg.
+ (i386_operand): Properly handle InOutPortReg here instead.
+ Disallows `inb (%dx,2)', `inb %es:(%dx)' and `mov (%dx),%ax'
+ (md_assemble): Simplify and correct modrm and sib generation.
+ (i386_operand): Add warning for scale without index.
+ Rewrite checks for valid base/index combinations.
+
+ * config/tc-i386.c (END_STRING_AND_SAVE): Protect arguments of
+ macros and enclose in do while(0).
+ (RESTORE_END_STRING): Likewise.
+ (md_assemble): Add one to printed operand number so we start
+ from 1 not 0. Add some more gettext invocations.
+ (i386_operand): Fix `%%s' -> `%%%s'. Inc printed operand
+ number here too.
+
+ * config/tc-i386.h (WAIT_PREFIX, LOCKREP_PREFIX, ADDR_PREFIX,
+ DATA_PREFIX, SEG_PREFIX): Define.
+ * config/tc-i386.c (struct _i386_insn): Remove wait_prefix field.
+ (check_prefix): Remove function.
+ (add_prefix): New function. Add prefix to i.prefix as well as
+ doing checks.
+ (md_assemble): Changes for add_prefix. Remove hack for wait
+ prefix, instead always output prefixes in fixed order. Test
+ for jcxz/loop when selecting between word & dword operations,
+ and add address size prefix rather than operand size prefix.
+ Remove operand -> address size hack when emitting jcxz/loop.
+ (i386_operand): Remove O_Absent check as it's done in expr.
+
+Wed Jun 3 15:09:10 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Recognize m5200 as a cpu_type of m68k.
+ * aclocal.m4: Rebuild with current libtool.
+ * configure: Rebuild.
+
+Wed Jun 3 14:11:59 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Add more calls
+ to relaxable_symbol to prevent references to external symbol from
+ being relaxed.
+
+Wed Jun 3 14:10:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (relaxable_symbol): If TARGET_OS is "elf", all
+ symbols are relaxable.
+
+Wed Jun 3 09:16:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (md_begin): Don't create special
+ sections by default.
+
+Tue Jun 2 14:52:56 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (macro): For div and udiv, close the
+ reorder block as soon as possible.
+
+Tue Jun 2 15:36:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Matt Semersky <matts@scd.hp.com>:
+ * macro.c (macro_mri_mode): New function.
+ * macro.h (macro_mri_mode): Declare.
+ * read.c (s_mri): Call macro_mri_mode when switching in and out of
+ MRI mode.
+
+Tue Jun 2 13:32:22 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * config/tc-alpha.c (s_alpha_comm): Allow alignment parameter in
+ OBJ_EVAX case.
+
+ * config/tc-alpha.c (s_alpha_comm): Defer restoring character
+ until after xstrdup in OBJ_EVAX case.
+
+Tue Jun 2 13:11:13 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/tc-vax.c (md_create_short_jump): Fix off by two bug in
+ offset calculation. Also, use VAX_BRW from vax-inst.h instead
+ of hardcoded magic number.
+ (md_create_long_jump): Use VAX_JMP and VAX_ABSOLUTE_MODE macros.
+
+Tue Jun 2 09:25:34 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * read.c (do_s_func): New function.
+ (s_func): Call it.
+ * read.h (do_s_func): Add prototype.
+
+Mon Jun 1 12:47:30 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-m32r.c (m32r_do_align): Only fill code sections with
+ nops if fill pattern not specified.
+
+Mon Jun 1 14:08:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Andrew Crabtree <andrewc@typhoon.rose.hp.com>:
+ * config/te-go32.h (TE_GO32): Define.
+ * config/tc-i386.h (LOCAL_LABEL): Don't define if TE_GO32.
+
+Sun May 31 15:43:06 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ Implement .func/.endfunc pseudo-ops.
+ * read.h (stabs_generate_asm_func,stabs_generate_asm_endfunc): Declare.
+ (s_func): Declare.
+ * read.c (potable): Add .func,.endfunc.
+ (s_func): New function.
+ * stabs.c (stabs_generate_asm_func,stabs_generate_asm_endfunc): New
+ functions.
+ (in_doc_func_p,current_function_label): New static globals.
+ (stabs_generate_asm_lineno): Emit function relative stabs if in .func.
+
+Fri May 29 18:13:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-a29k.h (WORKING_DOT_WORD): Define.
+ * config/tc-alpha.h (WORKING_DOT_WORD): Define.
+ * config/tc-arm.h (WORKING_DOT_WORD): Define.
+ * config/tc-h8300.h (WORKING_DOT_WORD): Define.
+ * config/tc-h8500.h (WORKING_DOT_WORD): Define.
+ * config/tc-hppa.h (WORKING_DOT_WORD): Define.
+ * config/tc-i860.h (WORKING_DOT_WORD): Define.
+ * config/tc-i960.h (WORKING_DOT_WORD): Define.
+ * config/tc-tic30.h (WORKING_DOT_WORD): Define.
+ * config/tc-w65.h (WORKING_DOT_WORD): Define.
+ * config/tc-z8k.h (WORKING_DOT_WORD): Define.
+ * config/tc-a29k.c: Don't define md_short_jump_size,
+ md_long_jump_size, md_create_short_jump or md_create_long_jump.
+ * config/tc-alpha.c: Likewise.
+ * config/tc-alpha.h: Likewise.
+ * config/tc-arm.c: Likewise.
+ * config/tc-h8300.c: Likewise.
+ * config/tc-h8500.c: Likewise.
+ * config/tc-hppa.c: Likewise.
+ * config/tc-i860.c: Likewise.
+ * config/tc-i960.c: Likewise.
+ * config/tc-ppc.c: Likewise.
+ * config/tc-sh.c: Likewise.
+ * config/tc-sparc.h: Likewise.
+ * config/tc-tic30.c: Likewise.
+ * config/tc-w65.c: Likewise.
+ * config/tc-z8k.c: Likewise.
+
+Fri May 29 16:03:26 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/tc-vax.c (_): Delete this macro used for placeholder
+ values in vax_operand_width_size; it conflicts with the _() macro
+ used for internationalization.
+
+Fri May 29 13:46:07 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (symbol_find_base): Fix case insensitive symbol name
+ code. From Chris Moller <moller@bops.com>.
+
+ Based on patch from Klaus Kaempf <kkaempf@progis.de>:
+ * struc-symbol.h (struct broken_word): Add seg and subseg fields.
+ * read.c (emit_expr): Initialize seg and subseg fields of a new
+ broken word.
+ * write.c (write_object_file): Switch to the appropriate segment
+ and subsegment when processing a broken word.
+
+ * config/tc-m68k.c (mri_assemble): New static function.
+ (build_mri_control_operand): Call mri_assemble rather than
+ md_assemble.
+ (s_mri_else, s_mri_break, s_mri_next, s_mri_for): Likewise.
+ (s_mri_endf, s_mri_endw): Likewise.
+
+Wed May 27 11:16:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_org): Call md_flush_pending_output if it is defined.
+
+ * config/tc-sparc.c (md_show_usage): Add \n\ to new string.
+
+Tue May 26 19:27:52 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * config/tc-sparc.c (OPTION_LITTLE_ENDIAN_DATA): New.
+ (md_parse_option): Add for same.
+ (sparc_md_end): Set bfd_mach_sparc_sparclite_le.
+ (md_apply_fix3, tc_gen_reloc): Allow BFD_RELOC_SPARC_32LE.
+ (cons_fix_new_sparc): Added to create BFD_RELOC_SPARC_32LE.
+
+ * config/tc-sparc.h (cons_fix_new_sparc): Added.
+
+Thu May 21 15:02:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (find_real_start): Relax definition of local
+ labels.
+
+Tue May 19 16:59:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-d30v.c (d30v_align): Apply address adjustment to all
+ symbols at the given address, not just the last one specified.
+
+Tue May 19 08:25:19 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-sparc.c (sparc_handle_align): Use number_to_chars_bigendian
+ or number_to_chars_littleendian to write data.
+
+Mon May 18 17:09:30 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Remove artificially created
+ register name symbols.
+
+Mon May 18 13:47:06 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * write.c (fixup_segment): Change "segment" to "section" in
+ error message.
+
+Mon May 18 16:55:40 1998 Michael Meissner <meissner@cygnus.com>
+
+ * write.c (fixup_segment): Change sym1-sym2 message again.
+
+Mon May 18 09:31:43 1998 Michael Meissner <meissner@cygnus.com>
+
+ * write.c (fixup_segment): Improve error message for sym1-sym2
+ errors when sym1 is in a different segment from sym2.
+
+Wed May 13 10:16:37 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-m32r.c (warn_unmatched_high): New static local.
+ (OPTION_WARN_PARALLEL): Rename from OPTION_WARN.
+ (OPTION_NO_WARN_PARALLEL): Rename from OPTION_NO_WARN.
+ (md_longopts): Recognize --{no-,}warn-unmatched-high.
+ (md_parse_option): Likewise.
+ (md_show_usage): Likewise.
+ (m32r_frob_file): Likewise.
+
+ * read.c (generate_file_debug,generate_lineno_debug): New functions.
+ (read_a_source_file): Call them.
+ * read.h (stabs_generate_asm_file): Declare.
+ * stabs.c (stabs_generate_asm_file): New function.
+ (generate_asm_file): New function.
+ (stabs_generate_asm_lineno): Move file name handling into
+ generate_asm_file.
+
+Tue May 12 12:03:44 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d30v.c (cur_mul32_p, prev_mul32_p): Make static.
+ (d30v_current_align, d30v_current_align_seg): New variables.
+ (d30v_last_label): New variable.
+ (d30v_align, s_d30v_align, s_d30v_text): New functions.
+ (s_d30v_data, s_d30v_section): Likewise.
+ (md_pseudo_table): Call them.
+ (md_begin): Initialize d30v_current_align_seg.
+ (md_assemble): Call d30v_align when needed by known current alignment.
+ (d30v_frob_label, d30v_cons_align): New functions.
+ * config/tc-d30v.h (md_do_align): Remove.
+ (tc_frob_label): Call d30v_frob_label.
+ (md_cons_align): New.
+
+ * config/tc-d30v.c (find_format): Convert complex expressions to
+ expression symbols before processing. Clean up code formatting.
+
+Sun May 10 22:35:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Thu May 7 15:49:07 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_assemble): Handle "bra" just like "jmp"
+ instructions.
+ * config/tc-mn10300.c (md_assemble): Likewise.
+
+Thu May 7 11:47:22 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.am: Update with `make dep-am'.
+ (HFILES): Add cgen.h.
+ (cgen.o): Depend on cgen.h.
+ * Makefile.in: Regenerate.
+
+ * cgen.c (cgen_md_apply_fix3): Don't pass newline to as_warn_where.
+
+Thu May 7 13:20:56 1998 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ * gasp.c (grab_label): Permit a label to be a preprocessor
+ variable by permitting a label to start with a backslash.
+
+Thu May 7 12:50:33 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-mips.c (validate_mips_insn): Removed hack
+ for previously inaccessible bitfields in some INSN_TRAP
+ instructions.
+
+Thu May 7 11:13:00 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-d30v.c (do_assemble): Abort with error message
+ if opcode operands do not match.
+
+Thu May 7 09:36:06 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-mips.c (macro_build, validate_mips_insn): Implement
+ 'q' operand format for 20-bit "break"/"sdbbp" instructions.
+ (mips_ip): Truncate overflowed "break" 'c' operand. Implement
+ similar new 'q' operand.
+
+Thu May 7 07:47:14 1998 Michael Meissner <meissner@cygnus.com>
+
+ * cgen.c (cgen_asm_finish_insn): Fix typo.
+
+Thu May 7 02:19:14 1998 Doug Evans <devans@charmed.cygnus.com>
+
+ * cgen.h: New file.
+ * cgen.c: Include it.
+ (MAX_FIXUPS): Renamed to CGEN_MAX_FIXUPS.
+ (cgen_asm_finish_insn): Result is now void. New arg `result'.
+ All callers updated.
+ * config/tc-m32r.c: Include cgen.h.
+ (m23r_insn): New members num_fixups,fixups.
+
+Wed May 6 16:29:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_apply_fix): Slightly rework some code
+ to avoid compiler warning.
+
+Wed May 6 15:26:34 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Run dec c with /nodebug. Pass CC value when
+ calling make.
+
+ * makefile.vms (OBJS): Add ehopt.obj
+
+Wed May 6 15:11:12 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * doc/c-vax.texi: Correct and extend vax/vms documentation.
+
+Wed May 6 11:51:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d30v.c (do_assemble): Accept a new parameter requesting
+ a short format insn.
+ (md_assemble): Set it for explicitly packed insns.
+
+Tue May 5 13:23:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/obj-coff.c (c_symbol_merge): Do not take address of
+ native fields when performing the memcpy.
+
+Tue May 5 13:10:41 1998 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro,macro2): Implement
+ M_DMULO_I, M_MULO_I, M_DMULOU_I, and M_MULOU_I.
+
+Mon May 4 17:49:14 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Changed to keep
+ relocations against globally visible symbols.
+ * config/tc-m68k.c (relaxable_symbol): New macro.
+ (m68k_ip, md_estimate_size_before_relax): Use it.
+ (tc_m68k_fix_adjustable): Also handle weak symbols.
+
+Mon May 4 16:12:23 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (TC_RELOC_RTSYM_LOC_FIXUP): Keep relocs for all
+ references to externally visible symbols.
+ * config/tc-i386.c (md_apply_fix3): When OBJ_ELF, don't add the
+ values in twice for a PC relative reloc if the symbol is
+ externally defined.
+
+ * config/tc-sparc.h (tc_fix_adjustable) [OBJ_AOUT]: When PIC,
+ don't adjust a PC relative reloc against an externally visible
+ symbol.
+ * config/tc-sparc.c (md_apply_fix3): When generating a.out PIC,
+ for a PC relative fixup against an externally visible defined
+ symbol, arrange to store object file and addend values as though
+ the symbol were not defined.
+ (tc_gen_reloc): Likewise.
+
+Thu Apr 30 13:09:39 1998 Fred Fish <fnf@ninemoons.com>
+
+ * read.c (sizeof_leb128): Referenced externally by write.c so
+ don't inline.
+
+Wed Apr 29 15:45:57 1998 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-m32r.c ({,expand_}debug_sym): New functions to record
+ and expand a 'debug' symbol associated with the next instruction
+ that does not cause a short instruction to be filled with a NOP.
+ (md_pseudo_table): Add support for .debugsym.
+ (assemble_parallel_insn): Add calls to expand_debug_sym as
+ appropriate.
+ (md_assemble): Ditto.
+
+Tue Apr 28 19:16:26 1998 Tom Tromey <tromey@cygnus.com>
+
+ * as.c (main): Conditionally call setlocale.
+ * gasp.c (main): Likewise.
+ * asintl.h: Include <locale.h> if HAVE_LOCALE_H.
+ (LC_MESSAGES): Now can be defined even when ENABLE_NLS.
+
+Tue Apr 28 18:33:23 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * config/tc-d30v.c (md_show_usage): Correct gettext typo.
+
+Tue Apr 28 12:16:30 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-hppa.c: Change all calls to bzero to use memset.
+ (pa_ip): Add cast to avoid warning.
+ (tc_gen_reloc, md_apply_fix): Likewise.
+ (pa_find_space_by_number): Likewise.
+ (hppa_force_relocation): Likewise.
+ (pa_block): Change i to unsigned int.
+ * config/obj-som.h (obj_som_copyright): Declare.
+
+Tue Apr 28 11:35:56 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * ecoff.c (ecoff_build_lineno): Do not use dummy first_lineno
+ for line numbers for assembly source.
+
+Mon Apr 27 15:58:46 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.9.4
+ * configure: Rebuild.
+
+Mon Apr 27 12:07:33 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (cgen_asm_finish_insn): New arg relax_p. All callers updated.
+
+Mon Apr 27 15:16:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.h: Change symbolS in function declaration to struct
+ symbol.
+
+Sun Apr 26 13:44:22 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (parse_reg): Add casts to avoid warnings.
+ (md_convert_frag): Fix i18n typo.
+
+Sat Apr 25 20:12:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * ecoff.c (ecoff_get_cur_proc_sym): New function.
+ * ecoff.h: Protoype it.
+ * config/tc-alpha.c [ELF] (s_alpha_prologue): New function.
+ [EVAX] (s_alpha_prologue): Delete.
+ (md_pseudo_table): Update.
+
+Sat Apr 25 14:00:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (md_assemble): Change bp_error_msg from static
+ array to local pointer.
+ (get_args, parse_expr): Add casts to avoid warnings.
+
+Fri Apr 24 12:47:42 1998 Philippe De Muyter <phdm@macqel.be>
+
+ * read.c (s_set): Cast xmalloc return value to fragS *.
+ * config/tc-m68k.c (m68k_ip): Function made static to match
+ previous forward declaration.
+ (insert_reg, init_regtable, md_convert_frag_1): Likewise.
+
+Fri Apr 24 09:26:46 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Add internationalisation macros to error
+ strings.
+
+ * config/tc-m32r.c (can_make_parallel): Add internationalisation
+ macros to error strings.
+
+Thu Apr 23 19:23:23 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Correct test of whether a
+ reloc is in the TOC csect.
+ (md_apply_fix3): Correct gettext typo.
+
+Thu Apr 23 14:58:31 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (find_real_start): Ignore symbols starting with
+ .L - they are local labels and the branches are not really
+ function calls but rather far jumps.
+
+Wed Apr 22 15:57:21 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir).
+
+Wed Apr 22 14:52:36 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Print operand number rather than
+ using ordinal_names.
+ (i386_operand): Likewise.
+
+Tue Apr 21 22:34:25 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * Makefile.am (INTLLIBS): Define to work around apparent automake
+ bug.
+ All Makefiles: Regenerated.
+
+ * Many files: Added gettext invocations around user-visible
+ strings.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY,
+ HAVE_LC_MESSAGES): Define.
+ * dep-in.sed: Added asintl.h.
+ * po/Make-in: New file.
+ * gasp.c (main): Call setlocale, bindtextdomain, and textdomain.
+ Include "asintl.h".
+ * read.c (Z_): Renamed from `_'.
+ * Makefile.am (SUBDIRS): Added po.
+ (POTFILES): new macro.
+ (po/POTFILES.in): New target.
+ ($(OBJS)): Added asintl.h.
+ (HFILES): Likewise.
+ (INCLUDES): Added -DLOCALEDIR, -I$(top_srcdir)/../intl.
+ (as_new_LDADD): Added $(INTLLIBS).
+ (as_new_DEPENDENCIES): Added $(INTLDEPS).
+ (gasp_new_LDADD): Added $(INTLLIBS).
+ (gasp_new_DEPENDENCIES): New macro.
+ * configure, aclocal.m4: Rebuilt.
+ * configure.in: Call CY_GNU_GETTEXT. Generate po/Makefile.in and
+ po/Makefile.
+ (ALL_LINGUAS): Define.
+ * macro.c: Include "asintl.h".
+ * as.c (main): Call setlocale, bindtextdomain, and textdomain.
+ * as.h: Include "asintl.h".
+ * config/tc-i386.c (ordinal_names): Removed.
+ (md_assemble): Changed error text to avoid ordinal_names.
+ (i386_operand): Likewise.
+ (reloc): Added as_bad to avoid i18n problems.
+ (tc_gen_reloc): Likewise.
+ * config/tc-arm.c (bad_args): Now a #define.
+ (bad_pc): Likewise.
+ * config/obj-vms.c (VMS_stab_parse): Changed type of
+ `long_const_msg'.
+ (global_symbol_directory): Unified strings to avoid i18n
+ problems.
+ * config/tc-m68k.c (get_reloc_code): Added some as_bad calls to
+ avoid i18n problems.
+ * config/tc-ns32k.c (reloc): Added as_bad to avoid i18n problems.
+ * config/tc-ppc.c (md_apply_fix3): Added as_bad_where to avoid
+ i18n problems.
+ * config/tc-sh.c (md_convert_frag): Added as_bad to avoid i18n
+ problems.
+ * config/tc-v850.c (md_assemble): Changed C++ comment into C
+ comment.
+ * config/tc-vax.c (md_assemble): Added as_warn to avoid i18n
+ problems.
+ * as.c (print_version_id): Added an fprintf to avoid i18n
+ problems.
+ * cond.c (cond_finish_check): Added as_bad call to avoid i18n
+ problems.
+ * expr.c (expr): Added as_warn call to avoid i18n problems.
+ * messages.c (as_assert): Changed code to avoid i18n problems.
+ (as_abort): Likewise.
+ * read.c (pseudo_set): Added as_bad call to avoid i18n problems.
+ (s_space): Likewise.
+ * po/Make-in, po/POTFILES.in, po/gas.pot: New files.
+
+Tue Apr 21 17:01:22 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (check_prefix): New static function, split out
+ from md_assemble.
+ (struct _i386_insn): Add wait_prefix field.
+ (md_assemble): Remove wait_prefix local variable. Use
+ check_prefix when adding a prefix.
+
+ * config/tc-i386.c (current_templates): New static variable.
+ (md_assemble): Remove current_templates local variable.
+ (md_assemble, i386_operand): Improve error and warning messages in
+ many places. Add RESTORE_END_STRING in many places before error
+ return. Clarify some comments.
+
+ * config/tc-i386.c (struct _i386_insn): Change seg field to a two
+ element array.
+ (md_assemble): Parse string instruction operands, looking for
+ segment override prefixes. Check for invalid segment prefixes on
+ string instruction.
+ (i386_operand): i.seg[] and max mem_operand changes for string
+ insns.
+ * config/tc-i386.h (EsSeg): Define.
+
+ * config/tc-i386.h (regKludge): Define.
+ (iclrKludge, imulKludge): Don't define.
+ * config/tc-i386.c (md_assemble): Merge imulKludge and iclrKludge
+ code. Move ReverseRegRegmem fudges into Modrm case. Reorder
+ opcode_modifier checks to look for more common cases first. Add
+ default_seg for IsString case.
+
+Tue Apr 21 16:18:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AM_PROG_LEX rather than AC_PROG_LEX and
+ AC_DECL_YYTEXT.
+ * configure: Rebuild with new automake and libtool.
+ * aclocal.m4, Makefile.in: Likewise.
+
+ * doc/Makefile.am (as.dvi): New target.
+ * doc/Makefile.in: Rebuild.
+
+Sat Apr 18 01:21:04 1998 Stan Cox <scox@cygnus.com>
+
+ * configure.in: Added sparc86x support.
+
+ * configure: Rebuild.
+
+ * config/tc-sparc.c (lookup_arch): Added arch_type to struct
+ sparc_arch.
+ (md_parse_option): Warn if -EL is not supported for this architecture.
+
+ * config/tc-sparc.h (SPARC_BIENDIAN) Always define.
+
+Sat Apr 18 01:19:01 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Note when we use get match on
+ the full instruction name.
+
+Wed Apr 15 15:17:27 1998 Richard Henderson <rth@cygnus.com>
+
+ * symbols.c (resolve_symbol_value) [O_symbol]: Also store the symbol
+ back into the expression to handle add/sub simplification correctly.
+
+Wed Apr 15 07:06:04 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-mips.c (hilo_interlocks): Remove 4300.
+
+Mon Apr 13 16:51:04 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (do_msr): Support undocumented 'msr cpsr_flg,
+ #<n>' instruction.
+
+Thu Apr 9 10:29:42 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * symbols.c (max_indent_level): New global.
+ (print_symbol_value_1): Use it.
+ * expr.h (expr_build_dot): Declare.
+ * expr.c (expr_build_dot): New function.
+
+Wed Apr 8 16:16:11 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * symbols.c (print_binary): New function.
+ (print_expr_1): Call it.
+
+Mon Apr 6 12:06:39 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip, case "#B"): Install the offset of the
+ operand in the opcode.
+
+Fri Apr 3 11:58:19 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h: Reorder operand flags and opcode modifier
+ flags for clarity. Remove unused definitions: Unknown,
+ ImmUnknown, DispUnknown, NoModrm.
+ * config/tc-i386.c (type_names): Add missing Debug type.
+ (md_assemble): Better duplicate prefix checking. Quicker string
+ instruction check via new opcode_modifier flag.
+
+Fri Apr 3 11:44:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Invoking): Clarify -Wa example.
+
+Fri Apr 3 09:12:23 1998 Gavin Koch <gavin@cetus.cygnus.com>
+
+ * config/tc-mips.c (mips_pseudo_table): Add weakext entry.
+ (s_mips_weakext): Define.
+ * ecoff.c (ecoff_directive_weakext): Don't define if defined(TC_MIPS).
+ * config/obj-ecoff.c (obj_pseudo_table): Don't add weakext if
+ defined(TC_MIPS).
+
+Thu Apr 2 22:42:02 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (tc_gen_reloc): The difference of two symbols
+ is an error if the value can not be computed at assembly time.
+ * config/tc-mn10300.c (tc_gen-reloc): Likewise.
+
+Thu Apr 2 16:36:47 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (main): Set next field of new include_path structure to
+ NULL. From Avery Pennarun <averyp@gdc.ca>.
+
+ * read.c (s_mri_sect): Call as_bad rather than abort for an
+ unsupported MRI target.
+
+Wed Apr 1 11:08:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (arm_validate_fix): New function. Determine if
+ the destination of a branch instruction should be altered.
+ (find_real_start): New function: Locate the real, Thumb coded
+ start of a Thumb function.
+ (do_t_branch23): Alter the destination of branches to Thumb
+ functions.
+
+ * config/tc-arm.h: Define TC_VALIDATE_FIX.
+
+Tue Mar 31 13:27:33 1998 Dean M. Deaver <deaver@amt.tay1.dec.com>
+
+ * config/tc-arm.c (decode_shift): Handle addressing mode 2 w/rrx
+ also.
+
+Wed Apr 1 13:13:20 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * doc/as.texinfo: Use @itemx for a secondary item in a table.
+ * doc/c-hppa.texi: Likewise.
+
+Tue Mar 31 17:52:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+ * Makefile.am (DEP_INCLUDES): New variable.
+ (.dep1): Change to work when srcdir is not an absolute path.
+ (.tcdep, .objdep, .dep2, dep.sed): Likewise.
+ * Makefile.in: Rebuild.
+
+Mon Mar 30 12:46:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h, config/tc-i386.c: Revert March 24
+ LinearAddress patch.
+
+ * configure.in: Set version to 2.9.1.
+ * configure: Rebuild.
+
+ * Branched binutils 2.9.
+
+Mon Mar 30 11:22:08 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (FWait): Define.
+ * config/tc-i386.c (md_assemble): Emit fwait prefix before any
+ other prefixes. Check FWait flag in opcode table to see which
+ instructions require an fwait prefix.
+
+Mon Mar 30 10:12:00 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * stabs.c (get_stab_string_offset): Always create a stab string
+ section.
+
+Sat Mar 28 22:28:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Fix some gcc -Wall warnings:
+ * atof-generic.c (atof_generic): Add casts to avoid warnings.
+ * ehopt.c (eh_frame_code_alignment): Likewise.
+ * expr.c (integer_constant, operand): Likewise.
+ * frags.c (frag_align): Likewise.
+ * gasp.c (level_0, change_base, doinstr): Likewise.
+ * hash.c (hash_ask): Likewise.
+ * listing.c (listing_page, calc_hex, print_lines): Likewise.
+ (debugging_pseudo): Likewise.
+ * macro.c (define_macro, check_macro): Likewise.
+ * read.c (read_a_source_file, s_align, s_float_space): Likewise.
+ (ignore_rest_of_line, float_cons): Likewise.
+ * symbols.c (decode_local_label_name): Likewise.
+ * write.c (record_alignment, cvs_frag_to_fill): Likewise.
+ (fixup_segment, number_to_chars_bigendian): Likewise.
+ (number_to_chars_littleendian): Likewise.
+ * config/atof-ieee.c (gen_to_words): Likewise.
+ * config/tc-sparc.c (md_begin, md_assemble): Likewise.
+ (sparc_ip, parse_keyword_arg, s_common): Likewise.
+ * read.c (output_big_sleb128): Initialize locals to avoid
+ warnings.
+ (output_big_uleb128, equals): Likewise.
+ * atof-generic.c (atof_generic): Change number_of_digits_* locals
+ to unsigned int. Change zeros to unsigned int.
+ * cond.c (s_if): Add return to default case.
+ * frags.c (frag_now_fix): Change return type to addressT.
+ * frags.h (frag_now_fix): Update declaration.
+ * listing.c (file_info_struct): Change linenum to unsigned int.
+ (struct list_info_struct): Change hll_line to unsigned int.
+ (print_source): Update format string.
+ * read.c (emit_expr): Change scan to unsigned int, and don't
+ bother to initialize it.
+ * symbols.c (dollar_label_count): Change to unsigned long.
+ * write.c (adjust_reloc_syms): Remove unused label reduce_fixup.
+ * config/tc-sparc.c (sparc_memory_model): Only define if OBJ_ELF.
+ * config/tc-sparc.c (tc_gen_reloc): Add return to default case.
+
+Fri Mar 27 12:46:47 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Check legal addressing modes for
+ mcf5200 just as we do for m68000.
+ (m68k_init_after_args): Likewise.
+ (md_estimate_size_before_relax): Likewise.
+
+Fri Mar 27 10:30:01 1998 Catherine Moore <clm@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Store relocation addend in
+ fixup instead of instruction.
+
+Thu Mar 26 23:07:18 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (md_assemble): Swap template arguments to
+ CONSISTENT_REGISTER_MATCH macro in reverse direction test.
+ This macro is currently symmetric, so passing them the wrong
+ way didn't cause any problem, but may if the macro is changed
+ in the future.
+ After copying template to i.tm, use i.tm. rather than t-> to
+ access fields, and make t a const*
+ Move i.tm.operand_types[] swap to immediately after the copy.
+
+Wed Mar 25 13:44:18 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * expr.h (expr_build_uconstant): Add prototype.
+ (expr_build_unary,expr_build_binary): Add prototypes.
+ * expr.c (expr_build_uconstant): New function.
+ (expr_build_unary,expr_build_binary): New functions.
+
+Wed Mar 25 13:10:42 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * gasp.c (IS*): Cast argument to unsigned char, not unsigned int.
+ * macro.c (macro_expand_body): Increase buffer size.
+ * messages.c (as_warn): Likewise.
+ (as_warn_where, as_bad, as_bad_where): Likewise.
+
+Wed Mar 25 12:59:07 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * Makefile.am (DISTSTUFF): New variable.
+ (diststuff): New target.
+ * Makefile.in: Rebuild.
+
+Tue Mar 24 16:51:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.h (md_cleanup, md_elf_section_change_hook): Call
+ m32r_elf_section_change_hook.
+
+ * config/tc-m32r.c (m32r_elf_section_change_hook): New function to
+ emit a nop if a section ends with a 16 bit instruction.
+
+Tue Mar 24 19:48:09 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_bss): Compile unconditionally. Call
+ s_lcomm rather than obj_coff_lcomm.
+ (obj_pseudo_table): Compile .bss pseudo-op unconditionally.
+
+Tue Mar 24 18:30:58 1998 H.J. Lu <hjl@gnu.org>
+
+ * config/tc-i386.h (LinearAddress): Define.
+ * config/tc-i386.c (md_assemble): If LinearAddress is set for the
+ instruction, don't use a default segment.
+
+Mon Mar 23 18:53:40 1998 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.in: (sh*-*-rtems*): Switched from ELF to COFF.
+ * configure: Rebuild.
+
+Fri Mar 20 19:15:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Thu Mar 19 16:03:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): fix code to test the range of
+ PC relative branches. Patch courtesy of Jonathan Walton.
+
+
+Wed Mar 18 09:29:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in (emulations): Add thumb-pe target.
+
+ * configure (emulations): Add thumb-pe target.
+
+1998-03-17 Ken Raeburn <raeburn@cygnus.com>
+
+ * itbl-lex.l (yywrap): Don't define if already defined as a
+ macro.
+
+Fri Mar 13 16:31:38 1998 Tom Tromey <tromey@cygnus.com>
+
+ * depend.c (quote_string_for_make): New function.
+ (wrap_output): Use it.
+
+Thu Mar 12 18:28:22 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Set bss flag in seg_info
+ structure if type is SHT_NOBITS. [Bug fix courtesy of rth]
+
+Sat Feb 28 17:28:55 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_shortopts, md_longopts, md_parse_option):
+ Recognize -GN and -relax.
+ (md_begin): Initialize gp size from -G switch.
+ (alpha_force_relocation): Always force if -relax.
+ (alpha_align): Take a new argument that will specify when to
+ emit an R_ALPHA_ALIGN relocation (though we don't do that now).
+ Change all callers. Emit nop alignment padding as nop+unop pair.
+
+Sat Feb 28 17:06:22 1998 Richard Henderson <rth@cygnus.com>
+
+ * config/obj-elf.c [TC_ALPHA]: Include <elf/alpha.h>.
+ * config/tc-alpha.h (ELF_TC_SPECIAL_SECTIONS): New.
+
+Thu Feb 26 15:49:04 1998 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (write_2_short): Delayed jsr instructions don't
+ require padding to the next long word boundary.
+
+Mon Feb 23 11:29:06 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c: #include symcat.h.
+ * config/tc-m32r.c: Likewise.
+
+Mon Feb 23 10:27:40 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip, case 'P'): Make 'P' arguments be
+ absolute expressions instead of '$' prefixed register names.
+
+Sat Feb 21 22:36:52 1998 Richard Henderson <rth@cygnus.com>
+
+ * read.c (s_set): Record file and line info for symbols when -as.
+ (pseudo_set): Don't overwrite that dummy fragment.
+
+Fri Feb 20 15:03:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Add "section".
+ (ppc_named_section): New static function.
+
+Thu Feb 19 22:25:42 1998 Richard Henderson <rth@cygnus.com>
+
+ * tc-ppc.c (ppc_biei): Cache the last symbol we inserted
+ so we don't have to scan the entire list.
+
+Tue Feb 17 17:02:15 1998 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): For the explicitly parallel
+ case, allow the parallel instructions to modify the same flag
+ bits.
+
+Thu Feb 19 16:08:15 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (list_symbol_table): Categorize symbols by
+ undefined_section rather than sy_frag->line == NULL.
+
+Wed Feb 18 23:39:46 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.am (install-exec-local): Install properly when ln
+ fails or tooldir == prefix.
+
+Tue Feb 17 18:58:51 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c (cgen_md_apply_fix3): Delete call to validate_operand.
+ Test result of insert_operand for error.
+
+Fri Feb 13 16:41:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Add cygnus.
+ * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e.
+ * doc/Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * doc/Makefile.in: Rebuild.
+
+Fri Feb 13 00:47:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Handle operand type 'C'.
+ (macro): Fix handling of M_COP[0-3].
+
+Thu Feb 12 14:06:59 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Ross Harvey <ross@teraflop.com>:
+ * macro.c (ISSEP): Only treat '<' and '>' as separator characters
+ if macro_alternate or macro_mri.
+ (getstring): Remove support for byte constants between < and >.
+ (get_any_string): '<' only starts a string if macro_alternate or
+ macro_mri.
+ (macro_expand_body): Permit keyword parameters following
+ positional parameters.
+
+ NetBSD patches from Gordon W. Ross <gwr@mc.com>:
+ * configure.in (alpha*-*-netbsd*): New target.
+ * config/te-nbsd.h (LOCAL_LABELS_FB): Define.
+ * configure: Rebuild.
+
+ * as.h (flag_warn_suppress_instructionswap): Move from here...
+ * config/tc-d10v.c (flag_warn_suppress_instructionswap): ...to
+ here, and make static.
+
+ * ehopt.c (eh_frame_code_alignment): Only use seg_info if
+ BFD_ASSEMBLER or MANY_SEGMENTS.
+
+ * as.c (show_usage): Update bug-gnu-utils address.
+ * gasp.c (show_usage): Likewise.
+ * doc/as.texinfo (Bug Reporting): Likewise.
+
+Wed Feb 11 23:26:28 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (load_address): Don't use mips III or mips IV
+ insns regardless of the size of a pointer if we're in mips I or
+ MIPS II mode.
+ (macro, macro2, s_cprestore, s_cpadd): Likewise.
+
+Thu Feb 12 03:41:00 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+Fix rac to accept only a0:
+ * tc-d10v.c (parallel_ok, find_opcode):
+ Split OPERAND_ACC into OPERAND_ACC0 and OPERAND_ACC1.
+ Introduce OPERAND_GPR.
+
+Wed Feb 11 16:28:13 1998 Richard Henderson <rth@cygnus.com>
+
+ * read.c (s_fill): Handle non-constant repeat counts by creating
+ an rs_space fragment.
+
+Tue Feb 10 18:31:31 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Change error added Jan 2 1998
+ from as_bad to as_warn.
+
+Tue Feb 10 18:04:00 1998 Jim Lemke <jlemke@cygnus.com>
+
+ * as.c: (perform_an_assembly_pass): Use [TEXT|DATA|BSS]_SECTION_NAME
+ * as.h: Define default values of [TEXT|DATA|BSS]_SECTION_NAME
+ * config/obj-elf.c (elf_begin): Use [TEXT|DATA|BSS]_SECTION_NAME
+
+Tue Feb 10 17:58:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ehopt.c (eh_frame_code_alignment): If not BFD_ASSEMBLER, use
+ seg_fix_rotP rather than fix_root from seg_info.
+
+Tue Feb 10 15:32:22 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * expr.c: Add support for 0x1_2_3_4 bignums.
+
+Tue Feb 10 14:43:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change -linux* to -linux-gnu*.
+ * configure: Rebuild.
+
+ * app.c (do_scrub_begin): Treat \r as whitespace.
+
+Mon Feb 9 14:16:11 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Update dependencies.
+ * Makefile.in: Rebuild.
+
+Sat Feb 7 15:33:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Fri Feb 6 16:08:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (md_begin): If mips_cpu is set, then use it as
+ the argument to bfd_set_arch_mach.
+ (load_address): Use bfd_arch_bits_per_address to determine the
+ bit size of an address instead of looking at the isa level.
+ (macro, macro2, s_cprestore, s_cpadd): Likewise.
+
+Fri Feb 6 14:44:34 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_parse_option): Add -mv850any command line option.
+
+Thu Feb 5 12:39:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ehopt.c: New file.
+ * as.h (enum _relax_state): Add rs_cfa.
+ (check_eh_frame, eh_frame_estimate_size_before_relax): Declare.
+ (eh_frame_relax_frag, eh_frame_convert_frag): Declare.
+ * read.c (emit_expr): Call check_eh_frame.
+ * write.c (cvt_frag_to_fill): Handle rs_cfa.
+ (relax_segment): Likewise.
+ * Makefile.am: Rebuild dependencies.
+ (GAS_CFILES): Add ehopt.c.
+ (GENERIC_OBJS): Add ehopt.o.
+ * doc/internals.texi (Frags): Document rs_cfa.
+
+ * as.c (show_usage): Mention --traditional-format.
+ (parse_args): Accept --traditional-format.
+ * as.h (flag_traditional_format): Declare.
+ * output-file.c (output_file_create): If flag_traditional_format,
+ set BFD_TRADITIONAL_FORMAT on stdoutput.
+ * doc/as.texinfo, doc/as.1: Document --traditional-format.
+
+ * config/tc-mips.c (append_insn): Make sure that if we have a
+ fixup for an unmatched %hi reloc, it does not associated with a
+ variant frag.
+
+ * configure, Makefile.in, aclocal.m4: Rebuild with new libtool.
+ * doc/Makefile.in: Likewise.
+
+Wed Feb 4 15:41:54 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c (check_for_side_effects): New function.
+ (can_make_parallel): Add checks for instruction side effects
+ clashing with the other instruction.
+ (assemble_parallel_insn): Improve warning messages. Return error
+ message from non-swapped instruction order.
+
+Wed Feb 4 20:00:26 1998 James G. Smith <jsmith@teknema.demon.co.uk>
+
+ * config/tc-arm.c: Rename arm_after_pass_hook() to arm_cleanup().
+
+ * config/tc-arm.h: Replace md_after_pass_hook definition with a
+ md_cleanup definition. This moves the forced literal output to
+ the end of the source pass, and avoids macro's inserting literals
+ into the code immediately after the macro expansion.
+
+Wed Feb 4 13:17:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.h (tc_fix_adjustable) [OBJ_ELF]: A reloc against
+ a gas internal symbol is adjustable.
+ * config/tc-ppc.h (tc_fix_adjustable): Likewise.
+
+ * as.h: If gcc version greater than 2.6, use `__format__' and
+ `__printf__' in function attributes, rather than `format' and
+ `printf'.
+
+Mon Feb 2 18:38:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c: Only include elf/sparc.h if OBJ_ELF.
+
+Mon Feb 2 18:30:34 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ Add tms320c30 support:
+ * config/tc-tic30.h: New file.
+ * config/tc-tic30.c: New file.
+ * config/obj-coff.h: If TC_TIC30, include coff/tic30.h and define
+ TARGET_FORMAT as "coff-tic30".
+ * configure.in (tic30-*-*aout*, tic30-*-*coff*): New targets.
+ * Makefile.am: Rebuild dependencies.
+ (CPU_TYPES): Add tic30.
+ (CPU_OBJ_VALID): tic30-aout is valid.
+ (TARGET_CPU_CFILES): Add config/tc-tic30.c.
+ (TARGET_CPU_HFILES): Add config/tc-tic30.h.
+ * configure, Makefile.in: Rebuild.
+
+Mon Feb 2 10:20:37 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Improvements to error messages.
+
+Mon Feb 2 12:39:05 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * config/tc-ppc.c (md_apply_fix3): Change BFD_RELOC_HI16 and
+ BFD_RELOC_HI16_S to store the high bits of any value.
+
+ * config/tc-ppc.h (tc_fix_adjustable): Undo change of Fri Jun 27.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Don't let the
+ assembler calculate relocations to any external symbol at all.
+ * config/tc-ppc.c (md_apply_fix3) [OBJ_ELF]: Correct bugs
+ involving generation of pc-relative relocs.
+ (md_pcrel_from_section) [OBJ_ELF]: The job this code used to do
+ has been moved to md_apply_fix3.
+
+ * config/tc-ppc.c (md_apply_fix3): Fix test for too-far branch.
+ (ppc_elf_suffix): Warn about 'identifier+constant@got' syntax,
+ which actually means (the address of identifier's GOT entry) +
+ constant, which is not particularly useful.
+
+Fri Jan 30 11:02:35 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * read.h (include_dirs): Declare.
+ (include_dir_count,include_dir_maxlen): Declare.
+
+Fri Jan 30 11:47:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Correct check for shared opcodes library.
+ * configure: Rebuild.
+
+ * listing.c (buffer_line): If we can't open the file, set at_end.
+ (listing_print): Remove unused local variable fi.
+
+ * config/m68k-parse.y (reglistpair): Handle register list in
+ either order.
+
+ * config/vms-conf.h: Don't undef VERSION.
+
+Thu Jan 29 14:42:44 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * Makefile.am (CONFIG_OBJS): New variable, containing part of old
+ OBJS variable.
+ (GENERIC_OBJS): New variable, with the rest of the old OBJS
+ variable.
+ (OBJS): Now just $(CONFIG_OBJS) and $(GENERIC_OBJS).
+ ($(srcdir)/make-gas.com): Rename from make-gas.com.
+ (stamp-mk.com): Replace $(OBJS) with $(GENERIC_OBJS).
+ (EXTRA_DIST): Define.
+ * vmsconf.sh: Handle {targ-cpu, obj-format, atof-targ} modules
+ explicitly rather than via the list of object files.
+ (gcc-as.opt): New file created when make-gas.com is run.
+ * config-gas.com: Create {targ-cpu.h, obj-format.h, targ-env.h,
+ itbl-cpu.h} to #include appropriate file rather than copying that
+ file.
+ * config/vms-conf.h: Synchronize with current config.in.
+ * Makefile.in: Rebuild.
+
+Thu Jan 29 18:48:19 1998 Bill Moyer <billm@cygnus.com>
+
+ * config/tc-d30v.c (do_assemble): Added flag_explicitly_parallel.
+ (parallel_ok): Relaxed parallel subinstruction dependency check.
+
+Wed Jan 28 14:35:00 1998 Bill Moyer <billm@cygnus.com>
+
+ * as.h (flag_warn_suppress_instructionswap): added new flag.
+ * tc-d10v.c (md_parse_option,md_longopts): added "--nowarnswap"
+ command line argument.
+ * tc-d10v.c (write_2_short): emit "Swapping instructions"
+ warning only if flag_warn_suppress_instructionswap is false.
+
+Wed Jan 28 16:41:19 1998 J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl>
+
+ * configure.in (i386-*-mingw32*): New target.
+ * configure: Rebuild.
+
+Wed Jan 28 14:51:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Don't set the segment if it
+ hasn't changed, and this is OBJ_AOUT without BFD_ASSEMBLER.
+
+ * config/obj-aout.h (S_IS_LOCAL): Correct typo--pass argument to
+ S_GET_SEGMENT.
+
+Wed Jan 28 13:54:50 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ as.h (unlink): Reverse 13-Feb-97 change; use of unlink vs remove
+ depends upon HAVE_{UNLINK,REMOVE} values rather than host
+ compiler.
+
+Wed Jan 28 13:48:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (RESOLVE_SYMBOL_REDEFINITION): Define.
+
+Wed Jan 28 09:52:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_insert_operand): Display instruction when
+ an error is encountered.
+
+Tue Jan 27 13:32:01 1998 Robert Lipe <robertl@dgii.com>
+
+ * configure.in (i386-*-sco3.2v5*): Defaults to ELF now.
+ (i386-*-sco3.2v5*coff): New target.
+ (i386-*-sco3.2*): New target.
+ * configure: Rebuild.
+
+Tue Jan 27 11:06:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Tidy error message production.
+
+Tue Jan 27 12:24:32 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Add new variable newimm to hold
+ validate_immediate return value in the right type for comparisons
+ to FAIL.
+
+Tue Jan 27 06:51:59 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (MAX_BYTES): Use listing variables not constants.
+ (data_buffer): No longer an array, but a pointer.
+ (calc_hex): sizeof(data_buffer) -> MAX_BYTES.
+ (listing_listing): Allocate data_buffer.
+
+Tue Jan 27 06:38:35 1998 Richard Henderson <rth@cygnus.com>
+
+ * as.c (parse_args): Add --listing-lhs-width, --listing-lhs-width2,
+ --listing-rhs-width, --listing-cont-lines.
+ (show_usage): Update.
+ * listing.c (listing_lhs_width, listing_lhs_width_second): New vars.
+ (listing_lhs_cont_lines, listing_rhs_width): New vars.
+ (print_lines): Use the variables instead of the constants.
+ (listing_listing): Likewise.
+ * listing.h: Declare the new vars.
+
+Tue Jan 27 05:32:05 1998 Richard Henderson <rth@cygnus.com>
+
+ * as.c (parse_args): Add --keep-locals alias for -L.
+ Add --strip-local-absolute.
+ (show_usage): Update.
+ * as.h (flag_strip_local_absolute): New flag.
+ * symbols.c (S_IS_LOCAL): Use it.
+ * config/obj-aout.h (S_IS_LOCAL): Likewise.
+ * config/obj-bout.h (S_IS_LOCAL): Likewise.
+ * config/obj-coff.h (S_IS_LOCAL): Likewise.
+
+Mon Jan 26 13:07:41 1998 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-m32r.c: Detect if explicitly parallel instructions
+ might have an io conflict and issue a warning message.
+
+Thu Jan 22 17:51:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.c (cgen_save_fixups, cgen_restore_fixups,
+ cgen_swap_fixups): Functions to save, restore and swap the fixup
+ chain with a backup copy.
+ (cgen_asm_finish_insn): Returns address of constructed insn.
+
+Wed Jan 21 16:49:10 1998 Richard Henderson <rth@cygnus.com>
+
+ * listing.c (file_info_struct): Remove FILE, add POS.
+ (last_open_file_info, last_open_file): New; a one entry FILE* cache.
+ (file_info): Don't open the file.
+ (buffer_line): Check for the file in the last_open cache, updating
+ as necessary.
+ (print_source): Don't reference file_info->file.
+ (listing_listing): Likewise.
+ (listing_print): Close the file in the cache, if any.
+
+Fri Jan 16 14:51:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (dwarf_file_string): New file static variable.
+ (emit_expr): Look for constant sequence that leads up to a file
+ name in DWARF debugging output.
+ (stringer): Use dwarf_file_string to decide whether to accept a
+ string as a file name.
+
+Fri Jan 16 11:30:37 1998 Richard Henderson <rth@cygnus.com>
+
+ * tc-m68k.c (m68k_ip): Remove absl->reglst MRI hack.
+ (crack_operand): Add reg->reglst MRI hack.
+ (r_seg): Put reglst symbols in reg_section.
+ (m68k_frob_symbol): Frob reglst symbols into absolute_section.
+
+Thu Jan 15 14:19:01 1998 Richard Henderson <rth@cygnus.com>
+
+ * tc-sh.c (get_specific): Handle SGR & DBR.
+
+Thu Jan 15 13:46:48 1998 Richard Henderson <rth@cygnus.com>
+
+ * tc-h8300.c (parse_reg): Take the length of the symbol into
+ account when attempting to match a register name.
+ * tc-h8500.c (parse_reg): Likewise.
+
+Wed Jan 14 17:52:33 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.c: Formatting changes to improve readability.
+
+Wed Jan 14 15:41:41 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (macro): Rework division code to avoid unfilled
+ delay slot.
+
+Wed Jan 14 18:04:20 1998 Michael Meissner <meissner@cygnus.com>
+
+ Based on a patch from Jim Wilson
+ * config/tc-d30v.c (do_assemble): Remove non-ansi default case.
+ (tc_gen_reloc): Handle cross section PC relative relocs
+ correctly.
+
+Wed Jan 14 15:02:19 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't test pinfo flags if INSN_MACRO.
+
+Mon Jan 12 13:04:57 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.c: #include setjmp.h. Clean up pass over `struct foo' usage.
+ (expr_jmp_buf): New static local.
+ (cgen_parse_operand): Allow use of longjmp in parsing to handle errors.
+ (cgen_md_operand): New function.
+ * tc-m32r.c: Clean up pass over `struct foo' usage.
+ (md_estimate_size_before_relax): Use CGEN_INSN_MNEMONIC.
+
+Tue Jan 6 15:36:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * symbols.c (S_SET_SEGMENT): Don't set the segment for section syms.
+ (S_IS_EXTERNAL, S_IS_LOCAL): Correct parenthetication.
+
+Fri Jan 2 16:08:54 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (i386_operand): Give an error if there are
+ unrecognized characters after an expression.
+
+For older changes see ChangeLog-9697
diff --git a/gas/ChangeLog-9295 b/gas/ChangeLog-9295
new file mode 100644
index 00000000000..7ea48e6a9c2
--- /dev/null
+++ b/gas/ChangeLog-9295
@@ -0,0 +1,13110 @@
+Sat Dec 30 23:42:51 1995 Jeffrey A Law (law@cygnus.com)
+
+ * ecoff.c (ecoff_stab): Simplify. Correctly handle sym + offset
+ addresses for static variables.
+
+Thu Dec 21 12:54:32 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (mapping): Make @got give a real GOT relocation,
+ and xgot give the old toc16 relocation.
+ (md_apply_fix3): Support all GOT relocations.
+
+Wed Dec 20 14:57:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_address): Correctly handle a constant in
+ SVR4_PIC case. From Richard Kenner <kenner@vlsi1.ultra.nyu.edu>.
+
+Fri Dec 15 14:25:07 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/tc-sh.c (parse_reg): Recognize SH3 registers.
+ (get_specific): Handle A_SSR, A_SPC and A_REG_B.
+ (build_Mbytes): Handle REG_B.
+
+Fri Dec 15 16:07:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_build_aux): Use new bfd_big_endian macro.
+
+Fri Dec 15 12:11:48 1995 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw-make.sed: If linking, edit ALL_CFLAGS to CFLAGS.
+
+Thu Dec 14 15:09:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Set the s_align field to
+ the number of bytes, rather than to the power of 2.
+
+Tue Dec 12 12:19:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DISTCLEAN_HERE): New variable.
+ (distclean): Use it.
+ (maintainer-clean): Depend upon clean-here rather than clean,
+ distclean, and clean-info. Run make maintainer-clean in doc.
+ Remove files listed in DISTCLEAN_HERE.
+ * doc/Makefile.in (maintainer-clean realclean): Split out from
+ distclean. Depend upon clean-info and distclean.
+
+Mon Dec 11 16:23:51 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mac-as.r: Fix copyright and version strings.
+ (cfrg): Use PROG_NAME instead of literal name.
+
+Mon Dec 11 14:14:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): If tc_unrecognized_line is defined,
+ call it.
+ * config/tc-a29k.h (tc_unrecognized_line): Define.
+ * config/tc-a29k.c (a29k_unrecognized_line): New function.
+ (md_operand): Handle a29k style local dollar labels.
+
+Wed Dec 6 17:52:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-multi.h: If OBJ_MAYBE_ELF, define OBJ_SYMFIELD_TYPE.
+
+Tue Dec 5 13:26:34 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * read.c (s_fill): If md_flush_pending_output is defined, call
+ it.
+
+Mon Dec 4 15:10:53 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/obj-coff.c (size_section, fill_section, fixup_mdeps):
+ Treat rs_align_code like rs_align.
+
+Sun Dec 3 16:46:54 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * config/tc-arm.c (cp_address_required_here): Set pre_inc when
+ converting an absolute address into a PC-relative one.
+
+Fri Dec 1 11:57:56 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Don't always use te-generic.h for emulation.
+ (powerpc-apple-macos): Use emulation te-macos.h.
+ * mpw-make.sed (install, install-only): Edit in Mac-specific
+ install procedure.
+
+Fri Dec 1 10:59:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Improve message about unsupported ELF targets.
+ * configure: Rebuild.
+
+ * config/tc-m88k.c (m88k_do_align): Correct check for whether fill
+ pattern is zero. From Manfred Hollstein.
+
+Thu Nov 30 13:25:49 1995 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (ppc_pe_section): To get the alignment right for
+ the various idata sections, we check the name on the .section pseudo.
+
+Thu Nov 30 11:23:42 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * config/obj-coff.c (fixup_segment): If TC_M88K is defined, do not
+ add section's paddr to add_number; compatibility to native as and
+ ld forbids.
+
+Wed Nov 29 23:14:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: Treat m68k-sysv4 like m68k-elf, not m68k-sysv3.
+
+ * hash.c (struct hash_entry): Moved here...
+ * hash.h (struct hash_entry): ...from here.
+
+ * config/obj-elf.c (elf_frob_symbol): Don't free and clear sy_obj
+ if it's already known to be null.
+
+Wed Nov 29 13:00:20 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Don't adjust the value for 32
+ bit relocs converted to PC relative relocs. This turned out to
+ add the offset from the beginning of .text twice.
+
+Tue Nov 28 10:42:36 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * stabs.c (s_stab_generic): In 's' case, free string from
+ obstack.
+
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): Remove unused field
+ sy_name_offset.
+ * config/obj-multi.h (ELF_TARGET_SYMBOL_FIELDS) [OBJ_MAYBE_ELF]:
+ Ditto.
+
+ * subsegs.h (segment_info_type): Make bitfields unsigned.
+
+ * expr.h (struct expressionS): Make X_op and X_unsigned bitfields,
+ and move them together. On most systems this will reduce the
+ structure size by one word.
+ (operatorT): Define O_max.
+ * expr.c (expr_begin): Verify that X_op is wide enough to hold
+ O_max.
+
+ * read.c (pop_insert): Print error returned by hash table
+ insertion code.
+
+ * as.c (dump_statistics): Split out from main; dump some hash
+ table stats and target-specific stats.
+ (start_time): No longer automatic to main.
+ (main): Set file-level start_time and call dump_statistics at
+ exit. Exit by calling xexit.
+ (show_usage): Make --statistics description less specific.
+ * subsegs.c (subsegs_print_statistics): New function.
+ * write.c (write_print_statistics): New function.
+ (n_fixups): New static variable.
+ (fix_new_internal): Increment it.
+ * read.c (read_print_statistics): New function.
+ * read.h (read_print_statistics): Declare.
+ * symbol.c (symbol_print_statistics): New function.
+ * symbol.h (symbol_print_statistics): Declare.
+ * hash.c (hash_print_statistics): New function.
+ * hash.h (hash_print_statistics): Declare.
+ * config/tc-i386.c (i386_print_statistics): New function.
+ * config/tc-i386.h (i386_print_statistics): Declare.
+ (tc_print_statistics): New macro.
+ * messages.c (as_fatal, as_assert, as_abort): Use xexit, not
+ exit.
+
+ * hash.c (DELETED): Rewrite to use a valid but unique address.
+ (START_POWER): Reduce to 10.
+ (enum stat_enum): New enumerator, replacing STAT_* index macros.
+ Add new values for counting strcmp calls.
+ (GROW_FACTOR): New macro.
+ (hash_grow): Use GROW_FACTOR. Rewrite for quick returns instead
+ of nesting blocks.
+ (FULL_VALUE): New macro. Use 1/4 of table size instead of 1/2.
+ (hash_new): Use FULL_VALUE.
+ (struct hash_control): Definition moved here.
+ (hash_code): Don't mask to low bits.
+ (hash_ask): Mask returned hash code here. Check hash value before
+ calling strcmp; count strcmp calls.
+ * hash.h (struct hash_control): Declare, don't define, here.
+ (HASH_STATLENGTH): Deleted.
+ (struct hash_entry): Add field for hash code.
+ (hash_say, hash_apply): Don't declare.
+
+ * hash.c (destroy): Return void.
+ (applicatee): Ditto.
+ (main): Fix declarations.
+ (hash_apply): Return void. Argument `function' returns void. Put
+ inside "#ifdef TEST".
+ (hash_say): Define only if TEST is defined.
+ * hash.h (hash_apply, hash_say): Declarations deleted.
+
+Mon Nov 27 13:18:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.7.
+
+Tue Nov 21 18:39:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4 (AC_PROG_CC): Remove local definition.
+ * configure: Rebuild with autoconf 2.6.
+
+Mon Nov 20 17:26:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_debug_name_section_size): Remove.
+ (ppc_stabx): Don't increment ppc_debug_name_section_size.
+ (ppc_bc): Likewise.
+ (ppc_frob_file): Remove.
+ * config/tc-ppc.h (tc_frob_file): Don't define.
+ (ppc_frob_file): Don't declare.
+
+Mon Nov 20 13:37:05 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (TARG_CPU_DEP_alpha): Mention alpha-opcode.h.
+ * config/alpha-opcode.h: Include one-operand variants of jmp and
+ jsr.
+
+ * config/te-delt88.h: Renamed from te-delta88.h, to avoid conflict
+ with te-delta.h in 8.3 file systems.
+ * configure.in: Adjusted.
+
+Thu Nov 16 12:49:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (s_err): Remove; just use the one in read.c.
+
+ * config/m68k-parse.y (yylex): In MRI mode, '@' can start an octal
+ number.
+ * expr.c (operand): Handle MRI suffixes after unadorned 0.
+
+Thu Nov 16 00:21:44 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Version 2.6 released.
+ * Makefile.in (VERSION): Updated to 2.6.
+
+ * config/obj-coff.c (write_object_file): Change use of md_do_align
+ to pass a pointer rather than a fill value, to match other uses.
+
+Wed Nov 15 03:52:00 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-ns32k.h (TC_FIX_TYPE): Add missing semicolon.
+
+ * as.c (main): Move md_end call to just after call to
+ perform_an_assembly_pass. Delete cpu-specific code here.
+ * config/tc-i960.h (md_end): New macro, calls brtab_emit.
+ * config/tc-arm.c (md_end): Unused function deleted.
+ * config/tc-ns32k.c (md_end): Ditto.
+
+ * config/tc-i386.c (i386_align_code): New function, moved here
+ from HANDLE_ALIGN macro.
+ * config/tc-i386.h (HANDLE_ALIGN): Call it.
+
+ Mon Jul 31 14:53:19 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (md_do_align): cast fill and 0x90 to char
+ before comparing
+
+ Mon May 1 10:91:49 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (md_do_align): Make ".align n,0x90" generate
+ multi-byte nops to avoid changing gcc. The necessary gcc change
+ might break old assemblers.
+
+ Sat Apr 22 20:53:05 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.h (md_do_align, HANDLE_ALIGN): Add macros to
+ generate optimal multi-byte nop instructions for ".align n"
+ ".align n,0x90", and aligns requiring more than 15 bytes of
+ padding still generate multiple 0x90's as before.
+
+Mon Nov 13 17:40:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (s_mri_until): Call pop_mri_control.
+
+Mon Nov 13 20:39:06 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (ppc-*-macos*, ppc-*-mpw*): New configurations.
+ * configure: Update.
+ * mpw-make.sed: Reorder commands to make sed happier.
+ * config/te-macos.h: New file.
+ * config/tc-ppc.h (TARGET_FORMAT): Set correctly for PowerMac.
+
+Sun Nov 12 21:14:56 1995 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_ip): Fix off-by-2 bug in length check for
+ conditional branches.
+ (md_apply_fix): Likewise.
+
+Thu Nov 9 16:14:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-a29k.c (md_apply_fix): Warn if an attempt is made to
+ generate a reloc which the linker will not handle correctly. Fix
+ overflow checking--R_IREL is 18 bits, not 17.
+
+Wed Nov 8 19:59:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Don't subtract md_pcrel_from
+ from a PC relative reloc if TC_A29K.
+
+ * config/tc-a29k.c (line_separator_chars): Restore '@'. Existing
+ code depends upon it.
+
+ * config/tc-a29k.c (md_operand): Handle $float, $double, and
+ $extend. Based on code from Eric Freudenthal
+ <freudenthal@nyu.edu>.
+ * config/tc-a29k.h (LEX_DOLLAR): Define.
+ * read.c (LEX_DOLLAR): Define if not defined.
+ (lex_type): Use LEX_DOLLAR.
+
+Wed Nov 8 16:38:14 1995 Eric Freudenthal <freudenthal@nyu.edu>
+
+ * configure.in (a29k-nyu-sym1): New target, just like other a29k
+ targets.
+
+Wed Nov 8 11:38:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (c_dot_file_symbol): Cast xmalloc return.
+
+Tue Nov 7 09:14:35 1995 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Added BFD_RELOC_RVA. Currently
+ used only by "dlltool.c".
+
+Mon Nov 6 18:51:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-alpha.c: Undefine inline if not __GNUC__.
+ (md_pseudo_table): Don't define "extern".
+
+Sat Nov 4 00:51:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_biei): Force symbol into text_section.
+
+ * config/tc-ppc.c (md_show_usage): Put backslash at end of line.
+
+Fri Nov 3 13:02:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * macro.c (macro_expand_body): Don't warn about == with a
+ nonexistent parameter, in case it is in a comment field.
+
+ * as.c (main): On TC_A29K, call macro_init with macro_alternate
+ set to 1.
+ * macro.c (get_any_string): Don't keep quotes if macro_strip_at is
+ set, even if macro_alternate is set.
+ (get_apost_token): If macro_strip_at, only skip kind if it is '@'.
+ (sub_actual): If macro_strip_at, and kind is '@', don't look up
+ the token unless it ended in '@'.
+ * config/tc-a29k.c (line_separator_chars): Remove '@'.
+ * doc/c-a29k.texi: Document macro usage on A29K.
+
+Thu Nov 2 23:07:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Handle new 'W' place, meaning a
+ signed word.
+ (install_operand): Likewise.
+
+ * config/obj-elf.c (ecoff_debug_pseudo_table): Add "extern".
+
+Wed Nov 1 15:17:02 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * configure.in (m88k-motorola-sysv*): New target.
+ * configure: Rebuild.
+ * config/te-delta88.h: New file.
+ * config/obj-coff.c (write_object_file): Use md_do_align if it is
+ defined.
+ * config/tc-m88k.h (SUB_SEGMENT_ALIGN): Define.
+ (md_do_align): Define.
+ * config/tc-m88k.c: Include "subsegs.h".
+ (m88k_do_align): New function.
+
+ * config/te-delta.h (STRIP_UNDERSCORE): Don't define.
+ (COFF_NOLOAD_PROBLEM): Define.
+ (LOCAL_LABELS_DOLLAR, LOCAL_LABELS_FB): Define.
+
+Wed Nov 1 16:07:43 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): For a jump instruction with
+ non-constant target, require 7 available bytes in the current
+ frag, not 6.
+
+Tue Oct 31 15:37:16 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * config/obj-elf.h: Include bfd/elf-bfd.h rather than
+ bfd/libelf.h.
+
+Tue Oct 31 16:34:28 1995 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * configure.in (alpha-*-linux*): Use ecoff.
+ * configure: Rebuild.
+ * ecoff.c (ecoff_directive_extern): New function.
+ (ecoff_directive_weakext): New function.
+ (ecoff_build_symbols): Handle weak symbols.
+ (ecoff_setup_ext): Likewise.
+ (ecoff_frob_symbol): Warn about weak common symbols.
+ * ecoff.h (ecoff_directive_extern): Declare.
+ (ecoff_directive_weakext): Declare.
+ * symbols.c (S_IS_WEAK): New function.
+ * symbols.h (S_IS_WEAK): Declare.
+ * config/obj-ecoff.c (obj_pseudo_table): Add "extern" and
+ "weakext".
+ * config/tc-mips.c (mips_pseudo_table): Remove "extern".
+ (s_extern): Remove.
+
+Tue Oct 31 13:29:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_lglobl): Do the right thing.
+
+ * config/tc-ppc.c (ppc_bb): Call SF_SET_PROCESS.
+ (ppc_eb): Likewise. Set the storage class to C_BLOCK, not C_FCN.
+ (ppc_frob_symbol): Don't change C_BLOCK symbols to C_HIDEXT.
+ * config/obj-coff.c (coff_frob_symbol): Don't call
+ SA_SET_SYM_ENDNDX with the current symbol; call it with the next
+ one. If OBJ_XCOFF, try to figure out whether the symbol is going
+ to be dropped.
+
+ * config/tc-ppc.c (md_pseudo_table): Add "bc" and "ec".
+ (ppc_stab_symbol): New static variable.
+ (ppc_change_csect): Check that ppc_toc_csect is not NULL.
+ (ppc_stabx): Set ppc_stab_symbol around call to symbol_make. Set
+ sy_tc.real_name to the stab string.
+ (ppc_bc, ppc_ec): New static functions.
+ (ppc_canonicalize_symbol_name): If ppc_stab_symbol is set, don't
+ do anything.
+ (ppc_symbol_new_hook): If ppc_stab_symbol is set, don't look for a
+ suffix.
+ (ppc_frob_symbol): Set BSF_NOT_AT_END for symbols with csect aux
+ entries.
+
+ * input-scrub.c (input_scrub_push): Reset sb_index.
+
+Mon Oct 30 17:52:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_newline): Don't create a frag in the absolute
+ section.
+
+Sat Oct 28 01:02:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Add "data" and "text".
+ (ppc_csect): Move most of the code to ppc_change_csect, and call
+ it.
+ (ppc_change_csect): New static function, taken from ppc_csect.
+ (ppc_section): New static function.
+ (ppc_saw_abs): New static varable.
+ (ppc_frob_symbol): Create aux entry for absolute symbols. Warn if
+ a symbol has no csect.
+ (ppc_adjust_symtab): New function.
+ * config/tc-ppc.h (tc_adjust_symtab): Define if OBJ_XCOFF.
+ (ppc_adjust_symtab): Declare if OBJ_XCOFF.
+
+ * write.c (write_object_file): If tc_adjust_symtab is defined,
+ call it just before the call to obj_adjust_symtab.
+
+ * symbols.c (symbol_find_or_make): Change name to be const.
+ * symbols.h (symbol_find_or_make): Update declaration.
+
+Thu Oct 26 19:18:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo (Align): Mention SH.
+ * doc/c-m68k.texi (M68K-Directives, .even): Describe behavior, not
+ .align value.
+ * doc/c-z8k.texi (Z8000 Directives, global): Fix minor typo.
+ (Z8000 Directives, even): Don't give numeric align value, instead
+ explain behavior.
+
+Thu Oct 26 11:45:03 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * tc-arm.c (do_ldst): Assemble ldr/str r0, [r1] as a pre-increment
+ instruction.
+
+Wed Oct 25 11:59:24 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (diststuff): Also make info.
+ (maintainer-clean realclean): Also make clean-info.
+
+Tue Oct 24 15:21:33 1995 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (md_pseudo_table): Add new ".nsubspa" opcode.
+ (pa_subspace): For ".nsubspa", always create a new subspace
+ with the given attributes, even if one already exists with the
+ same name.
+
+Tue Oct 24 14:50:38 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.h (TC_FORCE_RELOCATION_SECTION): Rename from
+ TC_FORCE_RELOCATION, taking an additional section argument. If
+ the section of the target symbol is not the same as the current
+ section, always force the relocation to be used.
+ (MD_PCREL_FROM_SECTION): New macro to call md_pcrel_from_section.
+
+ * config/tc-ppc.c (md_pcrel_from_section): Rename from the
+ md_pcrel_from function, taking an additional section argument.
+ Invoke TC_FORCE_RELOCATION_SECTION instead of TC_FORCE_RELOCATION.
+
+ * write.c (TC_FORCE_RELOCATION_SECTION): Define in terms of the
+ older TC_FORCE_RELOCATION if not defined.
+ (MD_PCREL_FROM_SECTION): If not defined, invoke md_pcrel_from.
+ (fixup_segment): Use MD_PCREL_FROM_SECTION instead of
+ md_pcrel_from, and TC_FORCE_RELOCATION_SECTION instead of
+ TC_FORCE_RELOCATION.
+
+Mon Oct 23 16:20:04 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * input-scrub.c (as_where): Set name to null pointer if we don't
+ have a file name.
+ * messages.c (identify): Only print filename if non-null.
+ (as_show_where): Ditto, for line number too.
+ (as_warn_internal, as_bad_internal): Ditto.
+
+ * input-file.c (input_file_open): If the input file can't be
+ opened, consider it an error.
+
+Mon Oct 23 11:15:44 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * config/tc-mips.c: Added mips_4100 control, and support for
+ accepting the 4100 as a MIPS architecture variant (md_begin,
+ macro_build, mips_ip, md_parse_option). Adding suitable
+ command-line OPTIONs, and updating the help text (md_show_usage).
+
+Wed Oct 18 13:20:32 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * subsegs.c (subseg_begin): Only set absolute_frchain.fix_* when
+ BFD_ASSEMBLER is defined.
+
+ * Use one active frag and one obstack per frag chain:
+ * frags.c (frags): Variable deleted.
+ (frag_alloc): New function.
+ (frag_grow, frag_more, frag_variant, frag_now_fix,
+ frag_append_1_char): Refer to frchain_now->frch_obstack instead of
+ frags variable.
+ (frag_new): Ditto. Verify that frch_last and frag_now match on
+ entry and exit, and that old frag_now has non-zero type. Replace
+ "know" uses with "assert". Use frag_alloc instead of mucking with
+ obstack alignment.
+ * frags.h (frags): Declaration deleted.
+ * subsegs.h (struct frchain): Add new field frch_frag_now.
+ * subsegs.c (frchains, dummy_frag, absolute_frchain): New static
+ variables.
+ (subsegs_begin): Initialize frchains obstack. Under gcc, don't
+ give it any stricter alignment than frchainS structures need. Do
+ not initialize frags obstack. Set frag_now to point to
+ dummy_obstack. Initialize absolute_frchain.
+ (subseg_set_rest): Save and restore frag_now in frch_frag_now
+ field of frchainS. Don't create new frags on section switch, and
+ use frag_alloc when creating a new frag chain. For absolute
+ section, set frchain_now to absolute_frchain. Verify that
+ frch_last and frag_now match on entry and exit. Initialize
+ per-chain obstack, and under gcc, set required alignment to that
+ needed by fragS structure.
+
+ * write.c (chain_frchains_together_1): Verify fr_type is nonzero.
+
+ * stabs.c (get_stab_string_offset): Only copy input string if a
+ fresh copy is needed, not if the section already exists.
+ (s_stab_generic): Cache stab section name to bypass lookups, since
+ usually it will match. Could be made faster still by changing the
+ memory allocation rules.
+ (s_xstab): Cache section name to bypass repeated string
+ allocation.
+
+ * frags.c (frag_new): Deleted register declarations.
+
+ * listing.c (frag_now): Don't declare.
+
+ * as.c (chunksize): New variable.
+ (debug_memory): New variable.
+ (main): If debug_memory is set, reduce chunksize and
+ _bfd_chunksize.
+ * as.h (chunksize): Declare it.
+ * read.c (read_begin): Use it.
+
+ * config/tc-alpha.c (md_shortopts): Include 'g'.
+ (md_parse_option): Ignore it.
+
+ * Makefile.in (distclean): Remove Makefile and config.status from
+ testsuite directory.
+ (clean-here): Don't delete testsuite. Instead, delete only the
+ files within it that would be generated by running tests.
+
+ * config/tc-hppa.c (hppa_elf_mark_end_of_function): Call
+ frag_now_fix instead of accessing obstack info directly.
+ * config/tc-arm.c (s_ltorg): Ditto.
+ (md_assemble): Ditto.
+
+ * config/tc-i386.c (md_assemble): Call frag_grow instead of
+ obstack_room.
+
+Wed Oct 18 12:22:59 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * stabs.c (aout_process_stab): Insert debug symbol into symbol
+ chain after parsing value expression, if any, to avoid separating
+ continued .stabs lines.
+
+Mon Oct 16 10:56:41 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_elf_pseudo_table): Remove.
+ (mips_pop_insert): Don't call pop_insert on mips_elf_pseudo_table.
+
+Mon Oct 16 07:07:37 1995 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * config/tc-ppc.c (md_begin): Use new flags PPC_OPCODE_COMMON for
+ -mcom support and PPC_OPCODE_ANY for -many.
+ (md_parse_option): Ditto.
+ (ppc_arch): Ditto.
+ (md_begin): For duplicate instructions, print all duplicates
+ before aborting.
+
+Sun Oct 15 22:06:14 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Support for -mcom to turn on
+ common mode operation.
+ (md_show_usage): Add -mcom to usage message.
+
+Fri Oct 13 13:32:45 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * expr.c (op_rank): Add O_symbol_rva.
+ * expr.h (operatorT): Add O_symbol_rva.
+ * read.c (cons_worker): Set O_symbol_rva when necessary.
+ * write.c (fix_new_exp): Understand O_symbol_rva.
+
+Tue Oct 10 11:34:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c: Correct s_cons arguments. From Michael
+ Joosten <joost@ori.cadlab.de>.
+
+Mon Oct 9 19:59:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_macro): Make count unsigned.
+ (ppc_biei): Set segment to now_seg and value to coff_n_line_nos.
+ (ppc_frob_symbol): Handle C_BINCL and C_EINCL symbols by setting
+ the fix_line field.
+ * config/obj-coff.c (coff_n_line_nos): Rename from n_line_nos, and
+ make non-static. Change all users.
+ * config/obj-coff.h (coff_n_line_nos): Declare.
+
+Fri Oct 6 16:24:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in (AC_ARG_WITH(bfd-assembler)): Fix help message.
+
+ * config/obj-elf.c (obj_elf_common): Convert specified byte
+ alignment to power of two. Set size of local bss symbol.
+
+ * config/tc-m68k.c (tc_gen_reloc): Fix typo in variable name.
+
+Fri Oct 6 15:22:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sb.c, macro.c: Decide whether to include <string.h> or
+ <strings.h> just as as.h does.
+
+Fri Oct 6 09:55:33 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (site.exp): Fix setting of $srcdir.
+
+ * config/tc-arm.c (md_atof): Fix little-endian output.
+ * config/tc-arm.h (ARM_BI_ENDIAN): Move definition so defined for
+ all coff targets.
+
+Thu Oct 5 20:17:30 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo: Split out the NS32k family documentation,
+ despite its being commented out for now.
+ * doc/c-ns32k.texi: New file.
+
+ * sb.c, macro.c: Include string.h.
+
+ * Makefile.in (comparison): Only check *.o; we don't care if
+ timestamps inserted by the native linker differ.
+
+ * config/tc-alpha.c (alpha_align): Only fill with a no-op pattern
+ if alignment stricter than 4 bytes is requested; in that case,
+ align to a 4-byte boundary first.
+
+ Thu Sep 28 19:35:27 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (VMS_RSYM_Parse): eliminate "might be used
+ uninitialized" warning for `Max_Source_Offset'.
+
+Wed Oct 4 16:17:02 1995 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (parse_toc_entry): New function to parse [toc]
+ qualifiers and detect errors if present.
+ (md_assemble): Add call to parse_toc_entry. Also added some support
+ for the [tocv] qualifier.
+ (ppc_pe_tocd): New function to support data in the toc section.
+
+Wed Oct 4 14:03:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_frob_symbol): Don't create an aux entry for
+ an absolute symbol.
+
+Tue Oct 3 12:18:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (isword): Accept all values from -65536 to
+ +65535, so ~VAL will not be rejected.
+
+ * cond.c (s_endif): Call demand_empty_rest_of_line. In MRI mode,
+ skip characters after the pseudo-op.
+ (s_else): Likewise.
+ * read.c (get_line_sb): Don't look past buffer_limit.
+ (s_include): In MRI mode, skip characters after the file name.
+
+Mon Oct 2 16:15:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/m68k-parse.y (m68k_reg_parse): In MRI mode, permit
+ periods in register names.
+
+Sat Sep 30 23:03:31 1995 Jeff Law (law@hurl.cygnus.com)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): DP relative relocs
+ are not adjustable in SOM to avoid confusing the optimizing
+ linker.
+
+Fri Sep 29 15:18:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Add some support for i960 MRI compatibility mode.
+ * config/tc-i960.c (md_pseudo_table): Add endian.
+ (get_args): Don't discard a space between alphanumeric characters.
+ (get_cdisp): Change text_section to now_seg.
+ (s_endian): New static function.
+ * config/tc-i960.h (MRI_MODE_NEEDS_PSEUDO_DOT): Define.
+ * expr.h (operatorT): Add O_logical_not, O_logical_and, and
+ O_logical_or.
+ * expr.c (operand): Treat '!' as logical not operator. If
+ TC_I960, in MRI mode permit `sizeof secname' and `startof
+ secname'.
+ (op_rank): Bump values by 2 to make room for && and ||. Add
+ entries for !, &&, and ||.
+ (expr_begin): Only do MRI changes if TC_M68K.
+ (operator): Recognize || and &&.
+ (expr): Handle new operatorT values.
+ * symbols.c (resolve_symbol_value): Handle new operatorT values.
+ (print_expr_1): Likewise.
+ * read.c (potable): Add debug, err, irep, irepc, print, purgem,
+ and rep.
+ (read_a_source_file): Handle MRI_MODE_NEEDS_PSEUDO_DOT.
+ (mri_comment_field): Only handle weird comments if TC_M68K.
+ (s_err): New function.
+ (s_org): Only punt in MRI mode if TC_M68K.
+ (s_mri_sect): Write TC_I960 version.
+ (s_print, s_purgem): New functions.
+ * read.h (s_err, s_print, s_purgem): Declare.
+ * cond.c (s_ifeqs): Implement.
+ (ignore_input): Handle MRI_MODE_NEEDS_PSEUDO_DOT.
+ * macro.c (macro_strip_at): New static variable.
+ (macro_init): Add strip_at parameter.
+ (do_formals): If macro_strip_at, change NARG to $NARG.
+ (define_macro): Skip a comma after the macro name.
+ (get_apost_token): Skip character if macro_strip_at, even if
+ macro_mri.
+ (macro_expand_body): If macro_strip_at, don't recognize parameters
+ in strings unless they are preceded by an '@'. If macro_strip_at,
+ pass '@' as strip character to sub_actual. If macro_strip_at,
+ strip '@' characters.
+ (macro_expand): If macro_strip_at, change NARG to $NARG.
+ (delete_macro): New function.
+ (expand_irp): Skip leading and trailing '"' characters if irpc.
+ * macro.h (macro_init): Mention new strip_at parameter.
+ (delete_macro): Declare.
+ * as.c (main): If TC_I960, pass flag_mri to macro_init as
+ strip_at; otherwise, pass 0.
+ * gasp.c (process_pseudo_op): Pass 0 to macro_init as strip_at.
+ (main): Likewise.
+ * doc/as.texinfo: Document i960 MRI mode.
+
+ * as.c (show_usage): Mention --defsym.
+
+Thu Sep 28 19:25:04 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Translate "powerpc" into "ppc", remove gen of
+ VERSION, move gen of "conf" here from makefile.
+ * mpw-make.sed: New file, sed commands to translate Unix makefile
+ into MPW syntax.
+ * mpw-make.in: Remove.
+ * mac-as.r: New file, Mac resource file.
+ * as.h (inline): Don't decide about defining if __MWERKS__,
+ remove redundant conditional and definition.
+
+ * stabs.c (s_stab_generic): Fix syntax for OBJ_PROCESS_STAB.
+
+Thu Sep 28 15:43:15 1995 Kim Knuttila <krk@nellie>
+
+ * config/tc-ppc.c (md_apply_fix3): Removed some TE_PE specific
+ manipulations, since I can't prove they're needed.
+ (md_begin): Removed init_regtable, insert_reg, and the call points.
+ (register_name): New function. Parses a register name, if appropriate.
+ (md_assemble): Added call to register_name to handle symbolic names.
+ (ppc_pe_section): Removed all duplicate IMAGE defines, and include
+ coff/pe.h instead.
+
+Thu Sep 28 12:09:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.h (tc_fix_adjustable): Define.
+ (ppc_pe_fix_adjustable): Declare.
+ * config/tc-ppc.c (ppc_pe_fix_adjustable): New function.
+
+Thu Sep 28 01:11:58 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * config/tc-arm.h (TARGET_FORMAT): Define for arm-coff.
+
+Wed Sep 27 12:53:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (S_IS_LOCAL): All symbols in reg_section are local.
+
+ * config/tc-ppc.h (OBJ_XCOFF): Define if OBJ_COFF and not TE_PE.
+ Change OBJ_COFF checks to check OBJ_XCOFF instead.
+ (TARGET_FORMAT): Fully parenthesize.
+ (LEX_QM): Define if TE_PE.
+ * config/tc-ppc.c: Replace OBJ_COFF by OBJ_XCOFF throughout.
+ Remove checks of TE_PE within #ifdef OBJ_XCOFF sections.
+ (init_regtable): Make i unsigned.
+ (ppc_set_current_section): Rename from setCurrentSection. Change
+ all callers.
+ (ppc_arch): Return after as_fatal to avoid gcc warning.
+ (md_assemble): Only declare reloc if OBJ_ELF. Add default to
+ switch on fixups[i].reloc to avoid gcc warning.
+ (IMAGE_SGN_LNK_OTHER): Fix nested comment.
+ (ppc_pe_function): Don't call ppc_canonicalize_symbol_name.
+ (ppc_frob_symbol): Remove TE_PE section checks.
+ (md_estimate_size_before_relax): Return after abort to avoid gcc
+ warning.
+ (md_apply_fix3): Add BFD_RELOC_16_GOT_PCREL to switch.
+ * read.c (LEX_QM): Define as 0 if not defined.
+ (lex_type): Use LEX_QM for '?'.
+
+ * configure.in: No need to check whether ${cpu_type} is powerpc;
+ it never will be.
+ * configure: Rebuild.
+
+Wed Sep 27 11:33:38 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Remove Sep 26 changes to this
+ function, keeping other Sep. 26 changes.
+
+Wed Sep 27 10:29:13 1995 Kim Knuttila <krk@nellie>
+
+ * configure (emulations): Added support for ppcle-*-[pe|winnt]
+ (target_frag): Removed an extraneous PPC definition.
+ * configure.in (emulations): Same
+ * config/tc-ppc.h:
+ * config/tc-ppc.c (md_pseudo_table): Base support for new or altered
+ pseudo ops - <previous, pdata, ydata, reldata, rdata, ualong, znop,
+ section, comm, function> There will be more.
+ (pre_defined_registers): Predefined reg table to name registers, etc
+ (md_begin): Setup reg table initialization
+ (md_assemble): Initial [toc]x(rtoc) support
+ (ppc_frob_label): Removed some xcoff specific processing from TE_PE
+ (ppc_frob_symbol): Removed some xcoff specific processing from TE_PE
+ Added support for more predefined sections
+ (ppc_frob_section): Removed some xcoff specific processing from TE_PE
+ (ppc_fix_adjustable): Removed from TE_PE mainline
+ (md_apply_fix3): For TE_PE toc entries, we don't need to mess
+ with fx_addnumber. Removed for the time being.
+ (lots): Put back missing assignments to ppc_current_csect.
+
+Tue Sep 26 14:57:59 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Support all of the V.4
+ relocations.
+ (ppc_elf_cons): Remove restriction that @ suffixes must be done
+ with .long. Add error if relocation does not fit in the number of
+ bytes provided.
+ (md_assemble): For absolute branches, map PC relative relocations
+ back into an equivalent absolute relocation.
+ (md_pcrel_from): If TC_FORCE_RELOCATION is true, relocation offset
+ is 0, not segment start.
+ (md_apply_fix3): Don't bother writing addend into the instruction,
+ since it is ignored, given that we use RELA relocations for ELF.
+
+ * config/tc-ppc.h (TC_FORCE_RELOCATION): Define to force all
+ branch prediction relocations to always be emitted.
+
+Mon Sep 25 16:08:43 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Lower case reloc before
+ testing.
+ (md_assemble): Be more robust in terms of relocations.
+ (md_apply_fix3): Allow 14 bit relocs to be emitted for external
+ symbols in addition to 26 bit relocs. Properly insert 26/14 bit
+ reloc value fields into the instruction stream.
+
+Mon Sep 25 00:23:16 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-arm.c (md_atof): Output little endian constants in
+ little endian mode.
+
+ * config/obj-coff.c (obj_coff_section): Pass &type, not type,
+ s_mri_sect.
+
+ * configure.in: Fix typo: fmt-elf to fmt=elf.
+
+Fri Sep 22 16:34:46 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Rewrite to use a table of
+ strings and relocations they represent. Add @br{,n}taken for
+ branch taken/not taken support.
+ (md_apply_fix3): Add BFD_RELOC_PPC_B16_BR{,N}TAKEN support.
+
+Thu Sep 21 21:10:17 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): -mrelocatable-lib now only
+ sets EF_PPC_RELOCATABLE_LIB and not also EF_PPC_RELOCATABLE.
+
+Thu Sep 21 16:30:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.c (subseg_set): Permit SEG_ABSOLUTE in know expression.
+ * expr.c (expr): Account for new operatorT values in know
+ expression.
+
+ * write.c (fixup_segment): Clear fixp->fx_subsy if the relocation
+ is fully resolved.
+
+Thu Sep 21 14:11:49 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_flags): New variable to hold the flag bits
+ to set in the ELF header.
+ (md_parse_option): Add support for -mrelocatable-lib. Make both
+ -mrelocatable and -mrelocatable-lib set ppc_flags.
+ (md_begin): Set ELF flags with ppc_flags.
+
+Wed Sep 20 13:01:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean. Add GNU standard maintainer-clean echos.
+ * doc/Makefile.in (maintainer-clean): New target, synonym for
+ realclean.
+
+Tue Sep 19 11:31:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Reject immediate operands for '%'.
+
+ * config/tc-m68k.c (m68k_ip): Reject immediate operands for '|'.
+ Replace 'P' with '0', '1', and '2'.
+
+ * config/tc-m68k.c (parse_mri_control_operand): Change leftstop
+ and rightstop to not be const.
+ (parse_mri_control_expression): Likewise.
+ (build_mri_control_operand): Likewise. Use m68k_ip_op to examine
+ the operand, not m68k_reg_parse.
+ (s_mri_if): In MRI mode, stop at the first '*'.
+ (s_mri_while): Likewise.
+ (s_mri_else): In MRI mode, ignore trailing characters.
+ (s_mri_endi, s_mri_break, s_mri_next, s_mri_for): Likewise.
+ (s_mri_endf, s_mri_repeat, s_mri_until, s_mri_endw): Likewise.
+ * config/m68k-parse.y: Revert yesterday's change.
+ * config/m68k-parse.h: Revert yesterday's change.
+
+Mon Sep 18 15:22:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (parse_mri_control_operand): Change leftstart
+ and rightstart to not be const.
+ (parse_mri_control_expression): Likewise.
+ (build_mri_control_operand): Likewise. If the left side of the
+ comparison is a register, and the right side is not, swap the two
+ sides.
+ * config/m68k-parse.y (m68k_reg_parse): Make globally visible.
+ * config/m68k-parse.h (m68k_reg_parse): Declare.
+
+ * read.c (mri_comment_field): New function.
+ (mri_comment_end): New function.
+ (s_align_bytes): Use mri_comment_field.
+ (s_align_ptwo, s_comm, s_mri_common, s_fail, s_globl): Likewise.
+ (s_float_space, s_struct): Likewise.
+ (s_space): Use mri_comment_field rather than doing it by hand.
+ (cons_worker, equals): Likewise.
+ (s_end): Ignore comments starting with '*' or '!'.
+ * read.h (mri_comment_field): Declare.
+ (mri_comment_end): Declare.
+ * cond.c (s_if): Use mri_comment_field.
+ * config/tc-m68k.c (s_chip, s_reg): Likewise.
+
+ * write.c (fixup_segment): Handle ABS-sym in -sym case rather than
+ sym-sym case.
+ * config/obj-coff.c (fixup_segment): Likewise. Permit negative
+ symbols if TC_M68K.
+ * config/tc-m68k.c (tc_coff_fix2rtype): If fx_tcbit is set, return
+ R_RELLONG_NEG.
+ (tc_gen_reloc): If fx_tcbit is set, abort.
+ (md_apply_fix_2): For a negative reloc, move fx_subsy to fx_addsy,
+ and set fx_tcbit.
+
+ * config/tc-m68k.c (s_reg): Ignore comment field in MRI mode.
+
+Mon Sep 18 14:44:04 1995 Arne H. Juul <arnej@pvv.unit.no>
+
+ * configure.in (mips-dec-netbsd*): New target.
+ * configure: Rebuild.
+
+Sun Sep 17 22:17:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set endian to little for mips-*-ultrix*.
+ * configure: Rebuild.
+
+Fri Sep 15 13:16:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (current_location): New static function. Handle magic
+ symbol `.'; in absolute section, return a constant.
+ (operand): Call current_location for '.' and '$', instead of doing
+ it inline. In MRI mode, call current_location for '*'.
+
+Fri Sep 15 21:39:29 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-m68k.c: Change some "CONST" references to "const".
+
+Fri Sep 15 17:27:41 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Tue Sep 12 17:08:23 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (VMS_stab_parse): simplify first loop;
+ use S_GET_NAME/modify/S_SET_NAME sequence instead of abusing
+ S_GET_NAME when updating symbol name.
+ (local_symbols_DST): first prefix/postfix typo from July 21st.
+ [plus comment reformatting --kr]
+
+Wed Sep 13 12:33:03 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (EXPECT): New variable.
+ (CHECKFLAGS): Remove.
+ (site.exp): New target.
+ (check): Rewrite to invoke runtest directly, rather than recurring
+ down into testsuite.
+ (clean-here): Remove testsuite directory.
+ (clean, distclean): Don't recur into testsuite.
+ * configure.in: Don't call AC_CONFIG_SUBDIRS(testsuite).
+ * configure: Rebuild.
+
+ * write.c (relax_and_size_seg): Change to the segment we are
+ relaxing, in case md_convert_frag, called by cvt_frag_to_fill,
+ wants to call fix_new.
+ * config/tc-m68k.c (m68k_ip): Permit PC relative code if the
+ segment of the symbol is the current segment, not just in
+ text_section.
+ (md_convert_frag_1): Don't call subseg_change.
+ (md_estimate_size_before_relax): Likewise.
+
+Tue Sep 12 10:36:40 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (md_atof): Fix debugging printf, and leave it
+ out by default.
+
+Mon Sep 11 11:39:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/configure.in: Remove unused file.
+
+ * app.c (do_scrub_chars): Grab all available spaces at start of
+ line before preserving a single space. Remove state == 0 test
+ which will never succeed.
+ * macro.c (macro_expand_body): Delete local variables from the
+ formal hash table.
+ (macro_expand): In MRI mode, stop when whitespace is seen in the
+ argument list.
+
+ * sb.c: Include "libiberty.h".
+ * macro.c: Likewise. Also include <stdlib.h> if it exists.
+
+Fri Sep 8 00:27:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): In MRI mode, keep a space before a
+ possible comment character.
+ * config/tc-m68k.c (m68k_ip): In MRI mode, ignore anything after
+ an instruction which takes no operands.
+
+ * Makefile.in (install): Don't install gasp in $(tooldir).
+
+ * config/tc-mips.c (macro): Handle a non zero base register for
+ M_U{L,S}{D,W,H}_A.
+
+ * gasp.c (show_usage): Put program_name argument in first fprintf,
+ not second.
+
+Thu Sep 7 12:33:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (operand): Handle 08 and 09 in MRI mode.
+ * macro.c (ISSEP): Remove duplicated `"' character.
+ (get_any_string): Copy some characters for which ISSEP is true:
+ ';', '>', '(', ')'. Otherwise we can get in an infinite loop.
+ * read.c (s_space): In MRI mode, the expressions stop at the first
+ unquoted space.
+ (cons_worker): In MRI mode, restore the terminating character at
+ the end of the function.
+
+ * read.c (cons_worker): Don't use #elif; old compilers don't
+ support it.
+
+Wed Sep 6 21:13:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): In MRI mode, silently end quoted strings
+ at newline characters. In MRI mode, always keep spaces in the
+ operands field. In MRI mode, treat a line comment character as a
+ regular comment character following a space.
+ * cond.c (ignore_input): Use strncasecmp rather than strncmp when
+ looking for special pseudo-ops.
+ * read.c (cons_worker): In MRI mode, the expressions stop at the
+ first unquoted space.
+ (equals): Likewise.
+
+Wed Sep 6 15:03:53 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (get_operands): Read third arg if it exists.
+ Otherwise, clear it.
+ (get_specific, case F_FR0): Add.
+
+Wed Sep 6 15:03:53 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (get_specific): Delete arg_to_test.
+ (md_assemble): Increase operand array from 2 to 3.
+
+Tue Sep 5 16:47:36 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/tc-mips.c: Remove CYGNUS LOCAL comments.
+ (md_begin): Use 0/1 instead of TRUE/FALSE.
+ (md_show_usage): Break up long format string for the benefit
+ of lame compilers.
+ * config/tc-m68k.c (md_show_usage): Ditto.
+ * gasp.c (show_usage): Ditto.
+ * macro.c (check_macro): Cast result of hash_find.
+
+Tue Sep 5 14:46:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: When testing for a free() declaration in system
+ header files, cast the address to a function pointer, not to an
+ integer.
+
+ * write.c (fix_new_internal): Call TC_INIT_FIX_DATA if TC_FIX_TYPE
+ is defined. Don't initialize fx_bsr. Verify that fx_size field
+ is wide enough to hold stored value.
+ * write.h (struct fix): Change tc_fix_data to type TC_FIX_TYPE if
+ that is defined, otherwise omit it. Delete fx_bsr. Change
+ fx_size to unsigned char.
+ * config/tc-i960.h (TC_FIX_TYPE, fx_bsr, TC_INIT_FIX_DATA): New
+ macros.
+ * config/tc-ns32k.h (TC_FIX_TYPE, fx_bsr, TC_INIT_FIX_DATA): New
+ macros.
+ * config/tc-hppa.h (TC_FIX_TYPE): Define as PTR.
+
+ * config/tc-i860.c (md_apply_fix): Delete code for checking
+ fx_im_disp, and for handling non-zero values, since it never gets
+ set after being initialized to zero.
+
+ * write.h (struct fix): Make fx_im_disp always 2 bits, since the
+ only tc-* files actually using it need that much.
+
+ NS32K changes from Ian Dall:
+ * configure.in: Treat ns32k-pc532-ux* like ns32k-pc532-mach*, and
+ ns32k-pc532-lites* like ns32k-pc532-netbsd*.
+ * config/tc-ns32k.h (LOCAL_LABELS_FB): Define to 1.
+
+Fri Sep 1 17:02:15 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * write.c (fixup_segment): Get TC_FORCE_RELOCATION up the
+ right way!
+
+Fri Sep 1 08:20:19 1995 James G. Smith <jsmith@beauty.cygnus.com>
+
+ * config/tc-mips.c (md_parse_option, md_begin, md_show_usage):
+ Add support for "-mcpu=vr4300" as processor identifier.
+
+Thu Aug 31 16:41:06 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * write.c (fixup_segment): Remove change of 29th.
+ * config/tc-{i386,arm}.h (TC_FORCE_RELOCATION): Keep RVA relocs.
+
+Tue Aug 29 19:42:58 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip) [case POST/PRE/BASE]: Fix typo when
+ looking at outer displacement. Don't set the postindex bit if the
+ index suppress bit is set (for memory indirect addressing mode).
+
+Thu Aug 31 06:49:37 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (tc_gen_reloc): Delete duplicated code.
+
+Wed Aug 30 23:51:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): Free saved_input when the from buffer
+ exactly fills the to buffer.
+
+Wed Aug 30 13:46:39 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (parse_keyword_arg, parse_const_expr_arg): New fns.
+ (sparc_ip): Call them for asi, membar, and prefetch parsing.
+
+Tue Aug 29 15:45:37 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (membar_masks): Deleted.
+ (sparc_ip): Clean up ASI and membar support.
+
+Tue Aug 29 13:20:27 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * read.c (potable): Rva is new entry.
+ (cons_worker): New, split from cons. Handles rva.
+ (cons, s_rva): Call cons_worker.
+ * read.h (s_rva): New declaration.
+ * write.c (fixup_segment): Don't throw away rva relocs.
+ * config/tc-arm.c (md_apply_fix, tc_gen_reloc): Handle RVA.
+ * config/tc-i386.c (tc_coff_fix2type): Handle RVA.
+ * config/tc-i386.h (TC_COUNT_RELOC): Remember RVAs.
+ (TC_RVA_RELOC): New definition.
+
+Sun Aug 27 17:41:05 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (do_swi): Allow optional leading '#'.
+
+Sat Aug 26 17:24:20 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-m68k.c (comment_chars): If TE_DELTA is defined,
+ include '#'.
+ * config/tc-m68k.h (NO_PSEUDO_DOT): Define if TE_DELTA is
+ defined.
+
+ * config/te-delta.h: Include obj-format.h.
+ * config/te-sco386.h: Likewise.
+ * config/te-sysv32.h: Likewise.
+
+ * app.c (scrub_file): Remove.
+ (scrub_from_file, scrub_to_file): Remove.
+ (scrub_string, scrub_last_string): Remove.
+ (scrub_from_string, scrub_to_string): Remove.
+ (saved_input, saved_input_len): New static variables.
+ (struct app_saved): Remove scrub_string, scrub_last_string, and
+ scrub_file fields. Add saved_input and saved_input_len fields.
+ (app_push): Adjust saved fields for changes in struct app_save.
+ Initialize state and saved_input.
+ (app_pop): Adjust saved fields for changes in struct app_save.
+ (do_scrub_chars): Rename from do_scrub_next_char and rewrite to
+ process a buffer at a time rather than a character at a time.
+ (main, as_warn): Remove obsolete testing code.
+ * as.h (do_scrub_next_char): Don't declare.
+ (do_scrub_chars): Declare.
+ (scrub_from_file, scrub_from_string): Don't declare.
+ (scrub_to_file, scrub_to_string): Don't declare.
+ * input-file.c (input_file_get): New static function.
+ (input_file_give_next_buffer): Call do_scrub_chars rather than
+ do_scrub_next_char.
+ * read.c (scrub_string, scrub_string_end): New static variables.
+ (scrub_from_string): New static function.
+ (read_a_source_file): Call do_scrub_chars rather than
+ do_scrub_next_char.
+
+Thu Aug 24 18:50:19 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * gasp.c (as_abort): New function.
+ * sb.c (sb_build): Revert yesterday's patch.
+
+ * Makefile.in (gasp.new): Depend upon ../libiberty/libiberty.a.
+ Just link against libiberty, not against $(LIBS).
+
+Wed Aug 23 15:18:20 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * sb.c (sb_build): Undefine abort before calling it, since gasp
+ does not provide as_abort.
+
+Wed Aug 23 10:40:41 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (set_target_endian): New static to say whether
+ we've initialized target_big_endian or not.
+ (md_parse_option): Set set_target_endian if we set the variable
+ target_big_endian.
+ (md_begin): Only set target_big_endian if !set_target_endian.
+
+Tue Aug 22 03:00:33 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Sat Aug 19 18:08:16 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.h (DST_S_C_SRC_SETREC_W, DST_S_C_SRC_DEFLINES_B):
+ New macros.
+ * config/obj-vms.c (VMS_TBT_Line_PC_Correlation,
+ VMS_TBT_Source_Lines): Make traceback info be robust enough to
+ handle huge source files.
+ (VMS_TBT_Source_File): Reorganize the native- vs cross-assembly
+ support so that actual object file output is clearer.
+ (VMS_TBT_Source_File: Fab, Nam, Date_Xab, File_Header_Xab):
+ Replace static variables with automatic ones.
+
+ Sat Aug 12 20:18:15 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (Module_Name): new file scope variable.
+ (VMS_TBT_Module_Begin): use it instead of local variable.
+ (Write_VMS_MHD_Records): ditto; assign its value here.
+ (Write_VMS_EOM_Record): second argument has type valueT.
+ (VMS_Initialized_Data_Size): simplify search loop; return
+ type is offsetT; second argument is unsigned.
+
+ Sat Jun 17 19:05:25 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * messages.c (as_perror): Use xstrerror instead of strerror.
+
+Mon Aug 21 13:57:20 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (parse_args): Accept --defsym SYM=VALUE.
+ * doc/as.texinfo, doc/as.1: Document --defsym.
+
+ * read.c (read_a_source_file): In MRI mode, don't end the
+ statement inside a quotation.
+ (s_space): Don't warn about a zero repeat count in MRI mode.
+ * config/tc-m68k.c (crack_operand): In MRI mode, don't count
+ parentheses inside quotes.
+ (md_assemble): In MRI mode, anything after the operands field is a
+ comment.
+ (parse_mri_control_operand): Adjust start and stop to remove
+ spaces.
+ (s_mri_for): Likewise.
+
+ * cond.c (s_ifdef): Restore the character after the symbol name,
+ in case it is a newline.
+ (s_if): If ignoring the current tree, don't try to parse the
+ expression.
+
+ * app.c (do_scrub_next_char): If LEX_IS_STRINGQUOTE or
+ LEX_IS_ONECHAR_QUOTE is seen in state 10, preserve one space.
+
+ * doc/as.texinfo: Document irp, irpc, macro, and rept. MRI mode
+ now supports macros, ifc, ifnc, irp, irpc, rept, and endr, without
+ using gasp.
+
+ Add support for macros.
+ * as.c: Include sb.h and macro.h.
+ (max_macro_next): New global variable.
+ (main): Call macro_init.
+ (macro_expr): New static function.
+ * as.h (max_macro_nest): Declare.
+ * read.c (line_label): Rename from mri_line_label. Change all
+ uses.
+ (potable): Add exitm, irp, irpc, macro, mexit, rept.
+ (read_a_source_file): Always clear line_label at the start of a
+ line, not just when flag_mri or LABELS_WITHOUT_COLONS. Fix
+ MRI/LABELS_WITHOUT_COLONS handling. In MRI mode, permit label:
+ equ val. Set line_label when calling colon. In MRI mode, a
+ leading '.' does not imply a pseudo-op. Check for macro expansion
+ before calling md_assemble.
+ (s_irp): New function.
+ (get_line_sb): New static function.
+ (s_macro): New function.
+ (s_mexit): New function.
+ (s_rept): New function.
+ * read.h (line_label): Rename from mri_line_label.
+ (s_irp, s_rept): Declare.
+ (s_macro, s_mexit): Declare.
+ * input-scrub.c: Include sb.h.
+ (sb_index, from_sb): New static variables.
+ (macro_nest): New static variable.
+ (struct input_save): Add sb_index and from_sb fields. Change
+ next_saved_file field to be struct input_save *.
+ (next_saved_file): Changed to be struct input_save *.
+ (input_scrub_push): Change to return type struct input_save *.
+ Save sb_index and from_sb.
+ (input_scrub_pop): Change parameter type to struct input_save *.
+ Restore sb_index and from_sb.
+ (input_scrub_include_sb): New function.
+ (input_scrub_next_buffer): Handle reading from from_sb.
+ (bump_line_counters): Only increment lines if not using from_sb.
+ * config/tc-m68k.c (opt_table): Add nest.
+ (opt_nest): New static function.
+ * gasp.c: Include sb.h and macro.h. Move all sb related functions
+ and definitions to sb.h and sb.c. Move all macro related
+ functions and definitions to macro.h and macro.c.
+ * sb.h, sb.c: New files, extracted from gasp.c.
+ * macro.h, macro.c: Likewise.
+ * Makefile.in (OBJS): Add sb.o and macro.o
+ (GASPOBJS): Define.
+ (gasp.new): Depend upon $(GASPOBJS). Use $(GASPOBJS) to link.
+ (TARG_CPU_DEP_m68k): Depend upon subsegs.h.
+ (gasp.o): Depend upon sb.h and macro.h.
+ (sb.o): New target.
+ (macro.o): New target.
+ (as.o): Depend upon sb.h and macro.h.
+ (input-scrub.o): Depend upon sb.h.
+ (read.o): Depend upon sb.h and macro.h.
+
+ * cond.c (get_mri_string): New static function.
+ (s_ifc): New function.
+ * read.c (potable): Add ifc and ifnc.
+ * read.h (s_ifc): Declare.
+
+ * app.c (do_scrub_begin): In MRI mode, set lex of ' to
+ LEX_IS_STRINGQUOTE.
+
+Mon Aug 21 13:41:33 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (md_assemble): Allow @HA, @L, and @H suffixes on
+ constant expressions.
+
+Sun Aug 20 15:54:37 1995 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-arm.c (md_reloc_size): Add const to declaration.
+
+Fri Aug 18 10:58:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_include): In MRI mode, don't expect quotes around the
+ file name.
+ * listing.c (listing_title): Don't require the title to be quoted.
+
+ * gasp.c (include_print_where_line): Always subtract 1 from
+ linecount before printing it.
+ (process_file): In MRI mode, lines beginning with '*' or '!' are
+ comments.
+ (do_reg): In MRI mode, don't require parentheses.
+ (do_include): In MRI mode, don't requires quotes. If the file can
+ not be found in the include path, try opening it in the current
+ directory. Print the file name correctly in the error message.
+ (chartype_init): In MRI mode, set FIRSTBIT for '.'.
+ (main): Set comment_char to ';' when entering MRI mode.
+
+ * config/tc-m68k.c: Include subsegs.h.
+ (m68k_ip): Pass 64 rather than -1 to add_Fix in 'B' 'B' case.
+ (md_pcrel_from): If fx_pcrel_adjust is 64, use -1 instead.
+
+ * config/tc-sparc.h (tc_fix_adjustable): For OBJ_AOUT case, adjust
+ BFD_RELOC_16 and BFD_RELOC_32 relocs.
+
+Wed Aug 16 14:48:44 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * as.h (alloca): Use void* declaration on HP/UX.
+
+Wed Aug 16 12:49:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (tc_gen_reloc): If PIC, only change PCREL_S2
+ to WPLT30 for an undefined or external symbol. Don't consider
+ PC10 or PC22 to be a PC relative reloc when choosing between
+ fx_addnumber and fx_offset.
+
+ * config/tc-z8k.c (md_number_to_chars): Don't do it here, call
+ number_to_chars_bigendian.
+ * config/tc-z8k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+
+ * expr.c (operand): Add support for .startof. and .sizeof. by
+ using magic symbol names which the linker will recognize
+ specially.
+ * doc/as.texinfo: Take out note that .startof. and .sizeof. are
+ not supported.
+
+Tue Aug 15 15:08:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (md_pseudo_table): Add MRI structured control
+ directives: if, if.b, if.w, if.l, else, else.s, else.l, endi,
+ break, break.s, break.l, next, next.s, next.l, for, for.b, for.w,
+ for.l, endf, repeat, until, until.b, until.w, until.l, while,
+ while.b, while.w, while.l, endw.
+ (enum mri_control_type): Define.
+ (struct mri_control_info): Define.
+ (mri_control_stack): New static variable.
+ (mri_control_index): New static variable.
+ (mri_control_label): New static function.
+ (push_mri_control, pop_mri_control): New static functions.
+ (parse_mri_condition): New static function.
+ (parse_mri_control_operand): New static function.
+ (swap_mri_condition, reverse_mri_condition): New static functions.
+ (build_mri_control_operand): New static function.
+ (parse_mri_control_expression): New static function.
+ (s_mri_if, s_mri_else, s_mri_endi): New static functions.
+ (s_mri_break, s_mri_next): New static functions.
+ (s_mri_for, s_mri_endf): New static functions.
+ (s_mri_repeat, s_mri_until): New static functions.
+ (s_mri_while, s_mri_endw): New static functions.
+ * gasp.c (mrikinfo): Remove IF.
+ * expr.c (get_symbol_end): Accept \001 as part of a name.
+
+ * symbols.c (colon): Change parameter to const char *.
+ * symbols.h (colon): Update declaration.
+
+Mon Aug 14 20:51:56 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * write.c (write_contents): Always do it the BFD_FAST_SECTION_FILL
+ way. Reformat and reindent that code to GNU standards.
+ (BFD_FAST_SECTION_FILL): Don't define.
+
+Mon Aug 14 14:08:07 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Don't try to apply BEGIN_BRTAB
+ or END_BRTAB fixups.
+
+Mon Aug 14 15:45:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (do_align, get_any_string): Mark as static.
+ (do_assigna, do_assignc, new_file): Likewise.
+
+ * config/tc-m68k.c (s_reg): Rename local op to rop to avoid
+ confusion with macro op.
+
+ * gasp.c (strip_comments): Comment out; it's not used.
+ (do_end): Add parameter. In MRI mode, print it out.
+ (do_irp): New static function.
+ (sub_actual): Change parameter m to formal_hash, changing type
+ from macro_entryh * to hash_table *.
+ (macro_expand_body): New static function, broken out of
+ macro_expand.
+ (macro_expand): Call macro_expand_body.
+ (K_*): Fully parenthesize.
+ (K_IRP, K_IRPC): Define.
+ (mrikinfo): Add IRP and IRPC.
+ (process_pseudo_op): In MRI mode, print out END pseudo-op. Pass
+ line to do_end. Handle K_IRP and K_IRPC.
+
+ * config/tc-m68k.c (s_opt): Reset *input_line_pointer even if we
+ don't do anything with the option.
+
+Sun Aug 13 17:03:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * frags.c (frag_align): Handle absolute_section.
+ * write.c (record_alignment): Likewise.
+
+ * config/tc-mips.c (macro_build): Skip insns with an inappropriate
+ ISA level.
+
+Sun Aug 13 00:35:02 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_pseudo_table): Add entries for
+ "begin_brtab" and "end_brtab" pseudo-ops.
+ (pa_brtab): New function.
+ (tc_gen_reloc, SOM version): Handle R_BEGIN_BRTAB and R_END_BRTAB.
+ (hppa_force_relocation): Force relocations for BRTAB fixups
+ when OBJ_SOM is defined.
+
+Fri Aug 11 20:34:05 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * Makefile.in (TE_OBJS): Add empty definition.
+
+Fri Aug 11 19:16:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (change_base): Don't treat ' specially in MRI mode.
+ (process_file): Don't warn about missing END in MRI mode.
+ (do_if): New static function.
+ (get_mri_string, do_ifc): New static functions.
+ (buffer_and_nest): Treat MRI mode like alternate syntax mode.
+ (do_aendr): Change error message in MRI mode.
+ (do_arepeat): Use REPT/ENDR in MRI mode.
+ (do_formals): In MRI mode, add special NARG formal.
+ (macro_expand): Various changes for MRI mode: permit a qualifier
+ on the macro name; set special NARG formal; permit unnamed
+ positional arguments; use && to concatenate named parameters;
+ permit \d to specify an unnamed parameter; permit named parameters
+ to not start with \; use == to see if a parameter exists.
+ (getstring): In MRI mode, allow <> to quote a string.
+ (K_IFEQ, K_IFNE, K_IFLT, K_IFLE, K_IFGE, K_IFGT): Define.
+ (K_IFC, K_IFNC): Define.
+ (struct keyword): Name structure used in kinfo array.
+ (mrikinfo): New static array.
+ (process_pseudo_op): Don't require leading '.' in MRI mode.
+ Handle new MRI pseudo-op definitions.
+ (add_keyword): New static function, broken out of process_init.
+ (process_init): Use add_keyword. In MRI mode, add mrikinfo table.
+ (long_options): Add "mri".
+ (show_usage): Mention -M/--mri.
+ (main): Call process_init after processing arguments. Handle -M.
+ * doc/gasp.texi: Document -M/--mri.
+
+ * gasp.c: Include ansidecl.h. Make all local functions static.
+ Add prototypes for all static functions.
+ (mri): New global variable.
+ (sb_add_char): Change parameter c from char to int.
+ (sb_add_string): Make parameter s into a const pointer.
+ (sb_add_buffer): Likewise.
+ (checkconst): Change parameter op from char to int.
+ (exp_get_abs): Make parameter emsg into a const pointer.
+ (do_res): Change parameter type from char to int.
+ (buffer_and_nest): Make parameters from and to into const
+ pointers.
+ (do_sdata): Change parameter type from char to int.
+ (new_file): Make parameter name into a const pointer.
+ (do_define): Make parameter string into a const pointer.
+
+ * config/tc-h8300.c (md_number_to_chars): Don't do it here, call
+ number_to_chars_bigendian.
+ * config/tc-h8300.h (TARGET_BYTES_BIG_ENDIAN): Define.
+
+Fri Aug 11 13:23:56 1995 Michael Meissner <meissner@cygnus.com>
+
+ * write.h (struct fix): Add new field fx_no_overflow.
+
+ * write.c (fixup_segment): If fx_no_overflow is non-zero, don't
+ complain if the addend is too large.
+
+ * config/tc-ppc.c (md_assemble): Set fx_no_overflow if the half
+ word relocations BFD_RELOC_{LO16,HI16,HI16_S}.
+
+Thu Aug 10 20:56:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * read.c (s_mri_sect) [BFD_ASSEMBLER]: Fix typos in choosing and
+ setting section flags.
+
+Thu Aug 10 00:38:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Add documentation for MRI compatibility mode.
+ * doc/as.1: Likewise.
+
+ * config/tc-m68k.c (m68k_ip): When recognizing '#', use isbyte and
+ iword rather than expr8 and expr16. When recognizing 'M', use
+ issbyte rather than expr8. When recognizing 'Q' and 't', just
+ check for O_constant rather than using expr8.
+ * config/m68k-parse.h (expr8, expr16): Don't define.
+ * Makefile.in (m68k-parse.o): Depend upon m68k-parse.h, not
+ m68k-parse.y.
+
+ * read.c (potable): Add spc, ttl, xcom, xref.
+ (s_mri_sect): New function.
+ * read.h (s_mri_sect): Declare.
+ * config/obj-coff.c (obj_coff_section) (both versions): In MRI
+ mode, call s_mri_sect.
+ (obj_pseudo_table): Add sect.s and section.s. Move sect outside
+ of ifndef BFD_ASSEMBLER.
+ * config/obj-elf.c (elf_pseudo_table): Add section.s, sect,
+ sect.s.
+ (obj_elf_section): In MRI mode, call s_mri_sect.
+ * config/tc-m68k.c (md_pseudo_table): Add restore, save.
+ (struct save_opts): Define.
+ (save_stack): New static variable.
+ (s_save, s_restore): New static functions.
+
+ * read.c (s_set): Remove unused local ptr.
+ (hex_float): Check target_big_endian.
+ (equals): Remove unused local p.
+
+ * config/tc-a29k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-h8500.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-hppa.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-i860.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-m68k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-m88k.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-tahoe.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ * config/tc-sh.c (little): Set target_big_endian.
+ (md_begin): Likewise.
+ (md_parse_option): Likewise.
+ (build_relax): Check target_big_endian rather than shl.
+ (build_Mytes, md_atof): Likewise.
+ (md_convert_frag, md_apply_fix): Likewise.
+ (md_number_to_chars): Likewise.
+
+Wed Aug 9 10:51:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_abspcadd): New static variable.
+ (m68k_quick): New static variable.
+ (m68k_rel32): New static variable.
+ (md_pseudo_table): Add opt and reg.
+ (m68k_ip): Permit absolute symbols in 'l'/'L' recognition. Check
+ m68k_quick in 'M' and 'Q' recognition. Check m68k_abspcadd in
+ DISP handling. Check m68k_rel32 in BASE/POST/PRE handling.
+ (md_begin): In MRI mode, initialize m68k_abspcadd and m68k_rel32.
+ In MRI mode, change unsized branch aliases to be variable sized.
+ (struct opt_action): Define.
+ (opt_table): Define.
+ (s_opt): New static function.
+ (skip_to_comma): New static function.
+ (opt_chip): New static function.
+ (opt_list): New static function.
+ (opt_list_symbols): New static function.
+ (s_reg): New static function.
+ * as.h (flag_keep_locals): Change from unsigned char to int.
+ (flag_no_warnings): Likewise.
+
+ * read.c (mri_line_label): Make non-static.
+ (potable): Add nopage, page, plen.
+ (s_org): Error if in MRI mode.
+ * read.h (mri_line_label): Declare.
+ * listing.c (listing_nopage): New function.
+ * listing.h (listing_nopage): Declare.
+
+ * symbols.c (symbol_begin): Set sy_frag of abs_symbol to
+ &zero_address_frag.
+
+ * write.c (adjust_reloc_syms): Check that symbol is not NULL
+ before checking sy_mri_common.
+ (fixup_segment): Likewise.
+ * config/obj-coff.c (fixup_segment): Likewise.
+
+ * read.c (abs_section_offset): New global variable.
+ (potable): Add offset, struct.
+ (do_org): New static function; handle changing the origin in the
+ absolute section.
+ (s_org): Use do_org.
+ (s_set): Likewise.
+ (equals): Likewise.
+ (s_space): In absolute_section, just increase abs_section_offset.
+ (s_struct): New function.
+ (emit_expr): Handle absolute_section specially.
+ * read.h (abs_section_offset): Declare.
+ (s_struct): Declare.
+ * frags.c (frag_more): Warn if in absolute_section.
+ (frag_now_fix): In absolute_section, return abs_section_offset.
+ * subsegs.c (subseg_change): If switching to absolute_section,
+ just set now_seg and now_subseg.
+ (subseg_set_rest): Special handling when switching to or from
+ absolute_section.
+
+ * config/tc-m68k.c (m68k_float_copnum): New static variable.
+ (md_pseudo_table): Add fopt and mask2.
+ (m68k_ip): Use m68k_float_copnum, not COPNUM, when setting
+ coprocessor register to use. In case 'I' when checking operands,
+ correct coprocessor register numbers. In case 'I' when setting
+ operands, don't add 1.
+ (s_fopt): New static function.
+ * config/m68k-parse.h (COPNUM): Don't define.
+
+ * read.c (potable): Add ifeq, ifge, ifgt, ifle, iflt, ifne.
+ Change if to pass O_ne to s_if.
+ (read_a_source_file): Don't define an label without a colon if
+ ignore_input returns true.
+ * cond.c (s_if): Treat argument as an operatorT describing how to
+ compare the argument against zero.
+ (ignore_input): Don't require an initial dot in MRI mode, or if
+ NO_PSEUDO_DOT is defined.
+
+ * read.c (potable): Add dcb, dcb.b, dcb.d, dcb.l, dcb.s, dcb.w,
+ dcb.x, ds.d, ds.p, ds.s, ds.x, elsec, endc, fail, format, llen,
+ noformat.
+ (read_a_source_file): If pseudo-op handler is s_end, quit
+ immediately.
+ (s_end): New function.
+ (s_fail): New function.
+ (s_float_space): New function.
+ (hex_float): New static function.
+ (float_cons): Use hex_float.
+ * read.h (s_fail): Declare.
+ (s_float_space): Declare.
+ * cond.c (s_end): Remove.
+ * listing.c (listing_psize): Treat argument as indicating whether
+ a height is expected.
+
+ * read.c (mri_pending_align): New static variable.
+ (read_a_source_file): Handle mri_pending_align.
+ (cons): Set mri_pending_align if appropriate.
+
+ * configure.in: Move random special target handling before
+ possible break.
+ * configure: Rebuild.
+
+Tue Aug 8 23:41:25 1995 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * configure.in: Consistently use ${target_cpu_type} rather than
+ ${cpu_type} after the loop.
+ * configure: Rebuild.
+ * Makefile.in (targ-cpu.o): Use @target_cpu_type@ rather than
+ @cpu_type@.
+
+Tue Aug 8 17:27:17 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * expr.h (operatorT): Remove comma after last enumerator value.
+
+ * config/obj-vms.c: Some whitespace cleanup from Pat Rankin.
+
+ * as.h (alloca): If __STDC__, declare void* instead of char*.
+
+ Wed Aug 2 18:54:37 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (Flush_VMS_Object_Record_Buffer,
+ Close_VMS_Object_File): Reorganize the `#if !VMS' cross-assmebler
+ support code.
+ (Close_VMS_Object_File): Call Set_VMS_Object_File_Record to flush
+ output buffer--just in case--before closing the file.
+
+Tue Aug 8 13:07:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (archs): Add 68ec000, 68hc000, 68hc001,
+ 68ec020, 68ec030, 68ec040, and 68330.
+ (md_pseudo_table): Add chip and comline.
+ (m68k_init_after_args): Use strcasecmp when comparing default_cpu
+ against architectures.
+ (mri_chip, s_chip): New static functions.
+
+ * struc-symbol.h (struct symbol): Add sy_mri_common bit.
+ * read.h (mri_comon_symbol): Declare.
+ (s_mri_common): Declare.
+ * read.c (mri_line_label): New static variable.
+ (mri_common_symbol): New global variable.
+ (potable): Add "common" and "common.s".
+ (read_a_source_file): In MRI mode, set mri_line_label for a label
+ at the start of a line.
+ (s_mri_common): New function.
+ (s_space): Handle mri_common_symbol.
+ * symbols.c (colon): Change return value from void to symbolS *,
+ and return new symbol. If mri_common_symbol is set, attach the
+ new symbol to it.
+ (resolve_symbol_value): Handle an sy_mri_common symbol.
+ * symbols.h (colon): Change return value in declaration.
+ * subsegs.c (subseg_set_rest): Clear mri_common_symbol.
+ (subseg_set (both versions)): Likewise.
+ * frags.c (frag_more): Warn if mri_common_symbol is not NULL.
+ * write.c (adjust_reloc_syms): Skip sy_mri_common symbols.
+ (write_object_file): Discard sy_mri_common symbols.
+ (fixup_segment): Change relocations against sy_mri_common symbols
+ to be against the common symbol itself.
+ * config/obj-coff.c (yank_symbols): Discard sy_mri_common symbols.
+ (fixup_segment): Change relocations against sy_mri_common symbols
+ to be against the common symbol itself.
+ * config/obj-aout.c (obj_crawl_symbol_chain): Discard
+ sy_mri_common symbols.
+
+ * doc/c-m68k.texi: Add documentation for CPU specific options, and
+ for Motorola syntax.
+
+ * config/m68k-parse.y (motorola_operand): For (%pc), set mode to
+ DISP, not BASE.
+
+Tue Aug 8 02:31:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * write.c (relax_align): Add extra padding for linkrelax only if
+ LINKER_RELAXING_SHRINKS_ONLY is defined.
+ * config/tc-i960.h (LINKER_RELAXING_SHRINKS_ONLY): Define it.
+ * doc/internals.texi (Relaxation): Write up some stuff on linker
+ relaxing and LINKER_RELAXING_SHRINKS_ONLY.
+
+Mon Aug 7 17:18:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/m68k-parse.y: New file: bison grammar for m68k operands,
+ including support for Motorola syntax.
+ * config/m68k-parse.h: New file; definitions shared between
+ m68k-parse.y and tc-m68k.c.
+ * config/tc-m68k.c: Include m68k-parse.h.
+ (enum operand_type): Move to m68k-parse.h, where it is named
+ m68k_operand_type. Rename all uses. Rearrange somewhat. Add
+ FPREG. Rename AOFF to DISP. Rename AINDX to BASE. Rename APODX
+ to POST. Rename APRDX to PRE. Remove AMIND. Rename MSCR to
+ CONTROL. Remove DINDR.
+ (struct m68k_exp): Move to m68k-parse.h. Remove e_beg, e_end and
+ e_seg fields. Rename e_exp to exp. Rename e_siz to size, and
+ change type to enum m68k_size. Change all uses.
+ (enum _register): Move to m68k-parse.h, where it is named
+ m68k_register. Rename all uses. Add ZDATA0-7 and ZADDR0-7.
+ (struct m68k_op): Move to m68k-parse.h. Change all fields.
+ (seg): Don't define.
+ (add_exp): Remove.
+ (FAIL, OK): Remove.
+ (m68k_reg_parse): Move to m68k-parse.y, and rewrite.
+ (SKIP_WHITE, SKIP_W): Remove.
+ (try_moto_index, try_index): Remove.
+ (m68k_ip_op): Move to m68k-parse.y, and rewrite to use grammar.
+ (main): Remove obsolete test function.
+ (m68k_ip): Extensive changes to use new grammar.
+ (get_regs): Remove.
+ (crack_operand): m68k_ip_op now returns 0 on success.
+ (init_table): Add ssp, zd0-7 and za0-7.
+ (md_assemble): Make er const. Correct loop over operands when
+ looking for error message.
+ (md_begin): Set alt_notend_table for '(' and '@'.
+ (get_num): Expression is already parsed. Don't set seg.
+ * configure.in: If cpu_type is m68k, put m68k-parse.o in
+ extra-objects.
+ * configure: Rebuild.
+ * Makefile.in (DISTSTUFF): Add m68k-parse.c.
+ (BISON): Use ../bison/bison if it exists.
+ (BISONFLAGS): Define as empty.
+ (TARG_CPU_DEP_m68k): Depend upon $(srcdir)/config/m68k-parse.h.
+ (m68k-parse.c, m68k-parse.o): New targets.
+
+Mon Aug 7 02:54:20 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-sh.c (parse_reg): Handle new FP registers.
+ (get_specific): Handle new operand types.
+
+Fri Aug 4 12:29:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (op_encoding): Make non-const. Don't set '"' to
+ O_bit_not.
+ (expr_begin): Set op_encoding['"'] in MRI mode.
+
+Wed Aug 2 18:39:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c: Remove BREAK_UP_BIG_DECL stuff.
+ (struct m68k_incant): Change m_operands field to be const.
+ (struct m68k_it): Change args field to be const.
+ (m68k_ip): Change local variable s to be const.
+ (opcode_ptr): Remove.
+ (md_begin): Use m68k_numopcodes, not numopcodes. Use
+ m68k_opcodes, not removed opcode_ptr. Use m68k_numaliases, not
+ numaliases.
+
+Tue Aug 1 17:35:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (init_table): Add "control", "status", "iaddr",
+ "sfcr", and "dfcr" as synonyms for existing entries.
+ (md_begin): In MRI mode, force flag_reg_prefix_optional to 1.
+ (md_parse_option): Removed unused locals i and arch. Change type
+ of arch (another one) to unsigned long.
+ (tc_coff_sizemachdep): Add return after abort to avoid warning.
+
+ Initial support for MRI style labels and expressions.
+ * as.h (flag_mri): Declare/define.
+ * as.c (show_usage): Mention -M and its synonym --mri.
+ (parse_args): Add 'M' to std_shortopts. Add "mri" to
+ std_longopts. Set flag_mri if -M is seen.
+ (main): Call parse_args before input_scrub_begin. Call
+ expr_begin.
+ * app.c (do_scrub_begin): Don't set lex for '"' or '\'' in MRI
+ mode. Do set lex for ';', '*', and '!' in MRI mode.
+ (do_scrub_next_char): Remove MRI ifdef in LEX_IS_WHITESPACE case.
+ In MRI mode, keep spaces between labels and colons. Remove MRI
+ ifndef around LEX_IS_ONECHAR_QUOTE case. In MRI mode, don't use
+ '!' or '*' as comment characters even if they are in
+ comment_chars.
+ * read.h (lex_type): No longer const.
+ * read.c: Include libiberty.h.
+ (lex_type): No longer const.
+ (read_begin): In MRI mode, set lex_type of '?' to 3.
+ (potable): Add dc, dc.b, dc.d, dc.l, dc.s, dc.w, dc.x, ds, ds.b,
+ ds.l, ds.w, and xdef.
+ (read_a_source_file): Change LABELS_WITHOUT_COLON ifdef to check
+ for MRI mode at runtime rather than compile time. Handle the EQU
+ pseudo-op in MRI mode. Remove bogus MRI ifdef around done_pseudo.
+ Change NO_PSEUDO_DOT ifdef to also take effect for MRI mode at
+ runtime.
+ (cons): In MRI mode, always call parse_mri_cons rather than
+ TC_PARSE_CONS_EXPRESSION.
+ (parse_mri_cons): Always compile, not just when MRI is defined.
+ Call TC_PARSE_CONS_EXPRESSION, not expression, when the input is
+ not a string constant. Handle A and E modifiers.
+ (float_cons): Accept :xxxx, where the x's are hex digits.
+ * expr.h (operatorT): Add O_eq, O_ne, O_lt, O_le, O_ge, O_gt.
+ (expr_begin): Declare.
+ * expr.c (integer_constant): In MRI mode, if the base was not
+ specified, look for a suffix on the number to set the base.
+ (mri_char_constant): New static function.
+ (operand): Remove MRI ifdef. In MRI mode, do various things: Pass
+ 0 as the base when calling integer_constant if there was no
+ prefix. Check for a hex constant suffix if when a leading '0' is
+ seen. Don't accept 0x or 0b as a prefix. Check for E'chars' and
+ A'chars'. Handle MRI character constants. Treat '"' as the
+ unary bitwise not operator. Treat $ as the program counter, or as
+ the prefix for a hex constant. Treat % as the prefix for a binary
+ constant and @ as the prefix for an octal constant. Treat : as
+ the prefix for a hex constant.
+ (op_encoding): Set '"' to O_bit_not, '<' to O_lt, and '>' to O_gt.
+ (op_rank): No longer const. Change rank values.
+ (expr_begin): New function.
+ (operator): New static function.
+ (expr): Use operator. Don't bother to mention the operator in
+ warnings. Remove bogus #if 0 code. Handle new operatorT values.
+ * atof-generic.c (atof_generic): In MRI mode, accept underscores
+ around the exponent in floating point numbers.
+ * symbols.h (symbols_case_sensitive): Declare.
+ * symbols.c (symbols_case_sensitive): New global variable.
+ (symbol_create): Check symbols_case_sensitive.
+ (symbol_find_base): Likewise.
+ (resolve_symbol_value): Handle new operatorT values.
+ (print_expr_1): Likewise.
+ (S_IS_LOCAL): In MRI mode, names beginning with two '?' characters
+ are local.
+
+Tue Aug 1 11:35:18 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * tc-sh.c (md_convert_frag): Make some error messages more
+ explict.
+
+Mon Jul 31 21:40:47 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Sat Jul 29 18:55:23 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (COPY_SHORT, COPY_LONG, PUT_SHORT, PUT_LONG):
+ Make expansion be safe for use in expressions.
+ (PUT_COUNTED_STRING): Bracket expansion with `do {...} while (0)'
+ rather than just `{...}'.
+
+Mon Jul 31 18:19:26 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * gasp.c (main): Parse -I option.
+ (do_include): Look through include list.
+ * gasp.c (change_base): Don't modify numbers in strings.
+
+Mon Jul 31 12:16:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.h (SUB_SEGMENT_ALIGN): Define. From Niclas
+ Andersson <nican@ida.liu.se>.
+
+Thu Jul 27 20:47:12 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Don't do further pcrel
+ processing after converting difference of two symbols in the
+ same segment. From Jim Wilson.
+
+ * configure.in (i386-*-linuxoldld): Add as synonym for
+ i386-*-linux*aout*. From Fred Fish.
+ * configure: Regenerated.
+
+Thu Jul 27 16:14:56 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (enum ps_type {ps_TEXT,ps_DATA,ps_COMMON,
+ ps_CONST}): New constants.
+ (VMS_Psect_Spec): Use them instead of literal strings.
+ (vms_write_object_file, global_symbol_directory): Adjust callers.
+
+Wed Jul 26 18:31:35 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (const_flag): Change from char to unsigned char.
+ * config/obj-vms.h (const_flag): Ditto.
+ (struct nlist): Replace union n_un and n_un.{n_name,n_next,n_strx}
+ fields with just n_name; delete field n_value; change n_other from
+ char to unsigned char and n_desc from short to int; insert explicit
+ padding for alignment.
+
+Mon Jul 24 20:06:17 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * subsegs.h (struct seg_info_trash): Make bitfield types valid.
+
+ * config/obj-coff.c (fixup_segment): Local add_number should not
+ be declared register since its address is taken for
+ MD_APPLY_FIX3.
+
+ Fri Jul 21 15:28:18 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ Split huge vms_write_object_file routine into managable pieces.
+
+ * config/obj-vms.c (vms_fixup_text_section, synthesize_data_segment,
+ vms_fixup_data_section, global_symbol_directory, local_symbols_DST,
+ vms_build_DST): New routines.
+ (vms_write_object_file): Call them.
+ (struct vms_obj_state): New file scope variable used by the above.
+
+Mon Jul 24 14:10:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_pseudo_table): Add "uses".
+ (s_uses): New static function.
+ (sh_coff_frob_file): New function.
+ (md_convert_frag): Call subseg_change before calling fix_new.
+ (sh_handle_align): New function.
+ (SWITCH_TABLE): Define.
+ (sh_force_relocation): New function.
+ (md_apply_fix): Handle R_SH_USES, R_SH_COUNT and R_SH_ALIGN.
+ (sh_coff_reloc_mangle): Likewise. Also handle switch table
+ entries.
+ * config/tc-sh.h (HANDLE_ALIGN): Define.
+ (sh_handle_align): Declare.
+ (TC_FORCE_RELOCATION): Define.
+ (sh_force_relocation): Declare.
+ (TC_COUNT_RELOC): Simplify; rely on TC_FORCE_RELOCATION instead.
+ (tc_frob_file): Define.
+ (sh_coff_frob_file): Declare.
+ * config/obj-coff.c (write_object_file): Call tc_frob_file if it
+ is defined.
+ (fixup_mdeps): Call HANDLE_ALIGN if it is defined.
+ (TC_FORCE_RELOCATION): Define if not defined.
+ (fixup_segment): Use TC_FORCE_RELOCATION to decide whether to
+ clear the symbol fields of fixP.
+
+Fri Jul 21 22:38:00 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Add support for R_PPC_SDAREL
+ relocation.
+ (md_apply_fix3): Ditto.
+
+Thu Jul 20 13:00:56 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-m68k.c (md_convert_frag): Rename argument seg to sec,
+ since seg is a macro name in this file.
+
+ * configure.in (arm-*-riscix*): Don't set emulation.
+
+Wed Jul 19 16:08:29 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/obj-coff.h (TE_PE): Delete.
+ * config/tc-arm.h (BYTE_ORDER): Delete.
+ (TARGET_FORMAT): Provide value for OBJ_COFF and TE_PE.
+ (ARM_BI_ENDIAN): Define if OBJ_COFF and TE_PE.
+ * config/tc-arm.c (byte_order): Delete.
+ (md_number_to_chars): Reference target_big_endian, not byte_order.
+ (md_chars_to_number): Likewise.
+ (md_longopts): Add -EB/-EL if ARM_BI_ENDIAN.
+ (md_parse_options): Recognize -EB/-EL.
+ (md_show_usage): List -EB/-EL.
+
+Wed Jul 19 11:49:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp.c (process_assigns): Use toupper before comparing against
+ upper case letter.
+ (whatcond): Likewise.
+
+ * config/tc-sh.c (sh_relax): Rename from relax, and make global.
+ Renamed all uses.
+ (insert): Pass a size of 2, not 4.
+ (build_relax): Remove unused len variable.
+ (md_show_usage): Mention -little option.
+ (md_convert_frag): Add segT argument. Rewrite to generate relocs
+ rather than to generate complete instructions here.
+ (md_apply_fix): Adjust and clarify R_SH_PCRELIMM8BY4 case for
+ changes in insert and md_pcrel_from. Add cases for R_SH_PCDISP
+ and R_SH_PCDISP8BY2.
+ (md_pcrel_from): Don't subtract 1, add 2.
+ (tc_coff_fix2rtype): Remove.
+ (sh_coff_reloc_mangle): New function.
+ * config/tc-sh.h (TC_COFF_FIX2RTYPE): Just return fx_r_type.
+ (sh_relax): Declare.
+ (TC_COUNT_RELOC): If relaxing, count PC relative relocs.
+ (TC_RELOC_MANGLE): Define.
+ (sh_coff_reloc_mangle): Declare.
+ (tc_coff_sizemachdep): Declare.
+ * tc.h (md_convert_frag): Add segT parameter to non BFD_ASSEMBLER
+ declaration.
+ * write.c (cvt_frag_to_fill): Add sec argument to non
+ BFD_ASSEMBLER version. Pass it to md_convert_frag.
+ (write_object_file): Pass SEG_TEXT to cvs_frag_to_fill.
+ * config/obj-coff.c (do_relocs_for): Pass segment info to
+ TC_RELOC_MANGLE.
+ (fixup_mdeps): Pass segment type to md_convert_frag.
+ * config/tc-a29k.c (md_convert_frag): Add segT argument.
+ * config/tc-h8300.c (md_convert_frag): Likewise.
+ * config/tc-h8500.c (md_convert_frag): Likewise.
+ * config/tc-i386.c (md_convert_frag): Likewise.
+ * config/tc-i860.c (md_convert_frag): Likewise.
+ * config/tc-i960.c (md_convert_frag): Likewise.
+ * config/tc-m68k.c (md_convert_frag): Likewise.
+ * config/tc-m88k.h (md_convert_frag): Likewise.
+ * config/tc-ns32k.c (md_convert_frag): Likewise.
+ * config/tc-tahoe.c (md_convert_frag): Likewise.
+ * config/tc-vax.c (md_convert_frag): Likewise.
+ * config/tc-w65.c (md_convert_frag): Likewise.
+ * config/tc-z8k.c (md_convert_frag): Likewise.
+ * config/tc-h8300.h (TC_RELOC_MANGLE): Add segment argument.
+ * config/tc-h8500.h (TC_RELOC_MANGLE): Likewise.
+ * config/tc-w65.h (TC_RELOC_MANGLE): Likewise.
+ * config/tc-z8k.h (TC_RELOC_MANGLE): Likewise.
+
+Mon Jul 17 15:02:54 1995 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.c (Current_Routine, Text_Psect): Delete as file
+ scope variables.
+ (Define_Routine, Define_Local_Symbols): Take Current_Routine and
+ Text_Psect as arguments.
+ (VMS_DBG_Define_Routine): Delete.
+ (VMS_TBT_Block_End): Change `Size' argument from int to valueT.
+ (vms_write_object_file: text and data fixup loops): Difference
+ of two symbols has type offsetT rather than int; convert with
+ md_number_to_chars before passing to VMS_Store_Immediate_Data.
+ (vms_write_object_file: debug symbol loop): Call Define_Routine
+ instead of VMS_DBG_Define_Routine.
+
+Sat Jul 15 00:01:35 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Add @fixup so that the
+ compiler can mark which relocs not to complain about with
+ -mrelocatable.
+ (ppc_elf_validate_fix): Add .fixup to sections not to complain
+ about, and also don't complain for BFD_RELOC_CTOR relocations in
+ writable non-code segments.
+ (md_apply_fix): Treat BFD_RELOC_CTOR just like BFD_RELOC_32.
+
+Fri Jul 14 19:54:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Add support for SPARC SunOS PIC:
+ * config/tc-sparc.h (sparc_pic_code): Always declare, not just
+ when OBJ_ELF.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define when OBJ_AOUT.
+ (tc_fix_adjustable): New definition for OBJ_AOUT.
+ * config/tc-sparc.c (sparc_pic_code): Always define, not just when
+ OBJ_ELF.
+ (md_apply_fix): Adjust reloc addend for OBJ_AOUT and PIC. In
+ BFD_RELOC_32_PCREL_S2 case, don't increment val for an external
+ symbol when PIC.
+ (tc_gen_reloc): Generate different PIC relocs when OBJ_AOUT, as
+ well as when OBJ_ELF.
+ (md_shortopts): If OBJ_AOUT, include `k'.
+ (md_parse_option): If OBJ_AOUT, handle 'k'.
+ (md_show_usage): Mention -k if OBJ_AOUT, and -KPIC if OBJ_ELF.
+ (md_pcrel_from): Don't add in size for an external symbol when
+ PIC.
+
+Thu Jul 13 21:16:43 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (UNDEFINED_DIFFERENCE_OK): Define for SOM.
+ * write.c (adjust_reloc_syms): Set sy_used_in_reloc for both
+ symbols in a fixup where a defined symbol is subtracted from an
+ undefined symbol (when UNDEFINED_DIFFERENCE_OK is defined).
+ (fixup_segment): Do nothing for the difference of two symbols if
+ UNDEFINED_DIFFERENCE_OK is defined.
+
+Wed Jul 12 23:33:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Support MD_APPLY_FIX3.
+
+Wed Jul 12 01:12:12 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * write.c (fix_new): Use int, not short int, for argument type.
+ (fix_new_exp): Ditto.
+
+ * configure.in (arm-*-riscix*): Don't set emulations.
+
+ * config/tc-mips.c (NO_ECOFF_DEBUGGING): Define if ECOFF_DEBUGGING
+ wasn't previously defined.
+ (s_extern): Don't set ecoff_extern_size if NO_ECOFF_DEBUGGING.
+ (nopic_need_relax): Don't check it if NO_ECOFF_DEBUGGING.
+ (macro_build) [!USE_STDARG]: Don't use variadic prototype.
+ (mips_local_label) [NO_ECOFF_DEBUGGING]: Don't preserve potential
+ ECOFF debugging symbols.
+
+ * emul.h (struct emulation): Use unsigned, not unsigned char, for
+ bitfields.
+ * obj.h (struct format_ops): Likewise.
+
+ * config/tc-arm.c (symbol_make_empty) [BFD_ASSEMBLER]: Set
+ udata.p, not udata.
+
+Tue Jul 11 14:30:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/c-mips.texi: Document -m4010 and -mno-4010.
+
+Tue Jul 11 14:28:55 1995 Jeff Spiegel <jeffs@lsil.com>
+
+ * config/tc-mips.c (mips_4010): New static variable.
+ (interlocks): New static variable.
+ (md_begin): Check for a cpu of "r4010". Set mips_4010 correctly.
+ If mips_4650 or mips_4010, set interlocks.
+ (append_insn): Check interlocks, not mips_4650.
+ (mips_emit_delays): Likewise.
+ (mips_ip): Only permit INSN_4010 instructions if mips_4010.
+ (md_longopts): Add "m4010" and "no-m4010".
+ (md_parse_option): Accept -mcpu=r4010. Handle -m4010 and
+ -no-m4010.
+ (md_show_usage): Document -m4010 and -no-m4010.
+
+Tue Jul 11 13:22:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (struct efdr): Add new field fake.
+ (init_file): Initialize fake.
+ (add_file): Add new parameter fake. Change all callers.
+ (ecoff_build_debug): Don't warn about a missing .end for a fake
+ file.
+
+Mon Jul 10 16:01:31 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo: Split out most cpu chapters...
+ * doc/c-*.texi: ...to here.
+
+ * read.c (po_hash): Now static.
+
+Mon Jul 10 13:47:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from H.J. Lu <hjl@nynexst.com>:
+ * config/tc-i386.c (md_apply_fix3): Rename from md_apply_fix1.
+ Accept pointer to value and segment. Fix OBJ_ELF PCREL case to
+ handle global defined symbols correctly.
+ (md_apply_fix): Remove both versions.
+ * config/tc-i386.h (MD_APPLY_FIX3): Define.
+
+ * configure.in: When switching on ${cpu}, use ${cpu}, not
+ $[target_cpu}, in default case.
+ * configure: Rebuild.
+
+Sat Jul 8 13:27:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (fixup_segment): Call resolve_symbol_value on
+ sub_symbolP, in case it isn't in the symbol table.
+
+Fri Jul 7 11:17:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_lcomm): For .lcomm 1, set align to 0, not 1.
+
+ * config/obj-coff.c (coff_frob_symbol): If SF_GET_FUNCTION, set
+ BSF_FUNCTION.
+ (symbol_globalP, symbol_global_lastP): New global variables.
+ (yank_symbols): Sort defined global symbols to the end, just
+ before the undefined symbols.
+ (glue_symbols): Add two arguments, and use them instead of
+ referring directly to global variables.
+ (crawl_symbols): Call glue_symbols twice, once for defined globals
+ and once for undefined. Add corresponding know calls.
+
+ * app.c (do_scrub_next_char): Always accept \v. Don't make it
+ conditional on BACKSLASH_V.
+ * read.c (next_char_of_string): Likewise.
+ * config/obj-bout.h (BACKSLASH_V): Don't define.
+ * config/tc-mips.h (BACKSLASH_V): Don't define.
+
+ Add SPARC ELF PIC support.
+ * write.c (fixup_segment): Pass fixP to TC_RELOC_RTSYM_LOC_FIXUP,
+ not fixP->fx_r_type.
+ * config/tc-sparc.c (sparc_pic_code): New global variable.
+ (md_apply_fix): If generating PIC, adjust fx_addnumber for any non
+ PC relative reloc.
+ (tc_gen_reloc): If generating PIC, adjust various reloc types.
+ Remove fx_pcrel assert, since it is no longer true.
+ (md_parse_option): Handle -K PIC.
+ * config/tc-sparc.h (sparc_pic_code): Declare if OBJ_ELF.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Define if OBJ_ELF.
+ (tc_fix_adjustable): Don't adjust PC relative relocs if PIC.
+ * config/tc-i386.h (TC_RELOC_RTSYM_LOC_FIXUP): Take a fixp, not a
+ reloc type.
+
+ * Makefile.in (Makefile): Add dependency on conf.in, so that conf
+ is rebuilt when conf.in changes.
+
+Thu Jul 6 16:49:38 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * All files: Updated FSF address.
+
+Thu Jul 6 16:30:34 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * ecoff.c (add_file): Don't collapse multiple .file commands into
+ a single file structure.
+ (ecoff_build_lineno): Set ilineBase to sum of previous file's
+ ilineBase and cline.
+
+Thu Jul 6 12:54:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Patches from Jerry Blakely <gerry_blakley@wellfleet.com>:
+ * as.c (listing_filename): New static variable.
+ (show_usage): Mention -a=file.
+ (parse_args): Support = option of -a to set name of listing file.
+ (main): Pass listing_filename to listing_print.
+ * listing.c (list_file): New static variable.
+ (various): Replace printf with fprintf to list_file.
+ (listing_print): If name argument is not NULL, open it as
+ list_file.
+ * doc/as.texinfo, doc/as.1: Document -a=file.
+
+ * config/tc-sparc.c (s_reserve): Don't permit redefinition, even
+ if the symbol was already in bss_section. Fix warning message.
+
+ * listing.c (struct file_info_struct): Rename end_pending field to
+ at_end.
+ (file_info): Initialize at_end, not end_pending.
+ (buffer_line): If at_end set, just return immediately. Don't
+ worry about end_pending cases. Set at_end when EOF is read.
+ (print_source): Check at_end, not end_pending.
+ (listing_listing): Likewise.
+
+ * config/tc-alpha.h (alpha_do_align): Don't declare.
+ (md_do_align): Don't define.
+ (tc_frob_label): Define.
+ (alpha_define_label): Declare.
+ (md_flush_pending_output): Define.
+ (alpha_flush_pending_output): Declare.
+ * config/tc-alpha.c (insn_label): New static variable.
+ (auto_align): New static variable.
+ (md_pseudo_table): Add cases for .text, .data, .align, .byte,
+ .hword, .int, .long, .octa, .quad, .short, .word, .double, .float,
+ and .single. Change .t_floating, .s_floating, .f_floating,
+ .g_floating, and .d_floating to use s_alpha_float_cons rather than
+ float_cons.
+ (s_alpha_text, s_alpha_data): New static functions.
+ (s_rdata, s_sdata): Clear insn_label and set auto_align.
+ (s_gprel32): If auto_align, align. Clear insn_label.
+ (emit_insn): Clear insn_label.
+ (s_alpha_align): New static function.
+ (alpha_align): Make static. Take label argument.
+ (alpha_flush_pending_output): New static function.
+ (s_alpha_cons, s_alpha_float_cons): New static functions.
+ (alpha_define_label): New function.
+
+Wed Jul 5 22:49:31 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * conf.in: Regenerate with autoreconf.
+
+ Mon Jul 3 19:47:53 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (vms_resolve_symbol_redef): Use full prototype.
+ (vms_check_for_special_label, tc_frob_label): Move them to group
+ with other prototypes.
+ [WANT_VMS_OBJ_DEFS]: Only define the many OBJ_x, DBG_x, and DST_x
+ macros when this is defined.
+ * config/obj-vms.c: Fully prototype all local functions.
+ [symbolS, fragS]: Use consistently instead of their struct tags.
+ [WANT_VMS_OBJ_DEFS]: Define this.
+ (s_const): Make definition correctly match actual usage.
+ (VMS_stab_parse): Make `expected_type' arg be int rather than char.
+ (get_VMS_time_on_unix): Define as `static void'.
+ (hash_string): Make definition match actual usage; argument is
+ `char const *' rather than `unsigned char *'.
+ (VMS_Case_Hack_Symbol, VMS_Modify_Psect_Attributes, VMS_Psect_Spec,
+ VMS_Global_Symbol_Spec): Declare string args as `const char *'.
+ [IS_GXX_VTABLE]: New macro.
+ (vms_write_object_file: GSD loop): Use it.
+ (vms_write_object_file: data segment): Reorganize `fill' loop.
+
+Wed Jul 5 12:01:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_shortopts): Add "K:" if OBJ_ELF.
+ (md_parse_option): If OBJ_ELF, check for -K. Die if -K PIC, since
+ PIC code is not currently supported.
+
+ * as.c (parse_args): Change std_shortopts to be an array rather
+ than a constant string. Only include 'K' if WORKING_DOT_WORD is
+ not defined. Only check for 'K' in that case as well.
+ * as.h (flag_warn_displacement): Only declare if WORKING_DOT_WORD
+ is not defined.
+
+ * conf.in: Add undef of HAVE_SBRK.
+
+ * config/obj-coff.c (obj_coff_line): Call listing_source_line, in
+ both BFD_ASSEMBLER and non BFD_ASSEMBLER versions of the function.
+
+ * symbols.c (S_SET_EXTERNAL): Warn if symbol is weak.
+ (S_CLEAR_EXTERNAL): Likewise.
+ (S_SET_WEAK): Warn if symbol is global.
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Warn about an attempt
+ to put an undefined symbol into a set.
+
+ * Makefile.in: Remove @configure_input@; it's not needed in
+ files named Makefile.
+
+ * config/tc-m88k.c (md_pseudo_table): Add ".set" so that the
+ explicit pseudo-op works, while continuing to treat "set" as an
+ instruction.
+
+ * ecoff.c (ecoff_debugging_seen): New global variable.
+ (ecoff_directive_def): Set ecoff_debugging_seen.
+ (ecoff_stab): Likewise.
+ * ecoff.h: Make idempotent.
+ (ecoff_debugging_seen): Declare.
+ * config/tc-mips.c: Include ecoff.h.
+ (mips_debug): New static variable.
+ (s_stringer, s_mips_space): Remove unneeded declarations.
+ (md_parse_option): In case 'g', set mips_debug to debugging level.
+ (mips_local_label): New function.
+ * tc-mips.h (LOCAL_LABEL): Call mips_local_label.
+ (mips_local_label): Declare.
+
+Wed Jul 5 00:59:22 1995 Fred Fish (fnf@cygnus.com)
+
+ * as.c (main): Only use sbrk when HAVE_SBRK defined.
+ * configure.in: Add test for sbrk.
+ * configure: Regenerate using autoconf 2.4.
+
+Mon Jul 3 15:58:16 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (MAX_RELOC_EXPANSION): Bump to 6.
+ * config/tc-hppa.c (tc_gen_reloc, SOM version): Handle
+ relocations for the difference of two (possibly external)
+ symbols.
+ (hppa_fix_adjustable): For SOM, reject reductions involving
+ the difference of two symbols.
+ (hppa_force_relocation): Force relocations for expressions
+ involving the difference of two symbols.
+
+Mon Jul 3 14:22:59 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure[.in] (i386-*-win32): New host and target.
+
+Thu Jun 29 17:25:43 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Support for long filenames non-bfd coff.
+ * config/obj-coff.c (filename_list_head, filename_list_tail): New.
+ (yank_symbols): Notice and record filenames which are too long.
+ (w_strings): Write out filename strings.
+ (c_dot_file_symbols): Put long filenames onto list.
+
+Wed Jun 28 17:33:13 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): PE doesn't use
+ the strange common symbol format that other 386s formats
+ do.
+ * config/tc-i386.c (md_begin): If LEX_AT defined then
+ '@' is in the set of identifiers.
+ (i386_operand): If LEX_AT, then don't look for @goto stuff.
+ * config/te-pe.h: Define LEX_AT.
+
+Wed Jun 28 17:49:59 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * doc/as.texinfo (H8/500 Floating Point): Indicate that IEEE FP
+ numbers are for the standard emulation code.
+ (SH Floating Point): Ditto.
+ (Overview): Describe new --emulation option for MIPS.
+ * doc/*.m4: Deleted.
+
+Thu Jun 22 19:26:25 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sun May 7 11:53:41 MDT 1995 Bryan Ford <baford@cs.utah.edu>
+
+ * configure.in: Added i386-*-moss* target.
+
+Thu Jun 22 14:41:23 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * write.c (write_object_file): Cast decode_local_label_name
+ argument to char * to avoid warning.
+
+Wed Jun 21 18:07:59 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>:
+ * config/tc-m68k.c (insword): Increment the frag offsets.
+ (struct m68k_it): Add reloc[].pcrel_fix field to hold pc-rel
+ fixup.
+ (add_fix): Accept additional parameter, the pc-rel fixup. All
+ callers changed. Fix offset address if width == 'b'.
+ (m68k_ip) [case AINDX]: Allow explicit size spec. Don't make the
+ outer displacement pc-relative.
+ (md_pcrel_from): Make it relative to the first extension word of
+ the operand.
+ (opcode_ptr): Make it a macro if DO_BREAK_UP_BIG_DECL is
+ undefined.
+ (md_convert_frag_1): Don't reference fragP->fr_opcode[2..].
+ (md_estimate_size_before_relax) [case TAB (FBRANCH, SZ_UNDEF)]:
+ Turn on long bit.
+ (m68k_ip) [case 'C']: Don't set set long bit, set it in the opcode
+ table.
+ (md_estimate_size_before_relax) [case TAB (PCINDEX, SZ_UNDEF)]:
+ Variable part increases by four, not six.
+ * write.c (fixup_segment) [TC_M68K]: Don't do further pcrel
+ processing after converting difference of two symbols in the
+ same segment.
+
+ * write.c (fixup_segment): Don't conditionalize the pcrel fix on
+ TC_M68K.
+
+ * config/tc-sparc.c (sparc_ip, case 'A'): If ASI is not a "#"
+ value, don't shift it an extra time.
+
+Wed Jun 21 14:18:37 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * gasp.c (do_print, do_form, buffer_and_nest): Use case insensitive
+ string compares.
+
+Tue Jun 20 14:55:02 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Cast time() argument to
+ time_t *.
+
+Tue Jun 20 12:00:53 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Fix typo in last
+ change.
+
+Mon Jun 19 15:27:17 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_build_unwind_subspace): Zero out memory
+ from frag_more calls.
+
+Thu Jun 15 16:53:37 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/obj-coff.c: Don't use "bfd/" when including libbfd.h
+ and libcoff.h.
+ (fill_section): Call PROGRESS.
+ * Makefile.in (INCLUDES): Add bfd srcdir.
+
+ * mpw-config.in: Add bfd_gas flag and set for each config.
+ (i386-unknown-go32, m68k-unknown-coff): Recognize.
+ * mpw-make.in (HACK_O_RAMA, OBJ_COFF_OMIT_TIMESTAMP): Add to
+ config.h.
+
+Thu Jun 15 10:04:26 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.h (LOCAL_LABEL): Prepend '.' if not OBJ_AOUT.
+ (FAKE_LABEL_NAME): Likewise.
+
+Mon Jun 12 22:25:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Check for invalid register in single
+ precision fmpyadd and fmpysub instructions.
+
+Thu Jun 8 19:33:02 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (myname): Delete all references.
+ (VMS_stab_parse, Write_VMS_MHD_Records, VMS_Case_Hack_Symbol):
+ Replace printf calls with as_tsktsk.
+ (PUT_LONG, PUT_SHORT): Use COPY_LONG, COPY_SHORT.
+ (VMS_Store_Immediate_Data): Move second buffer capacity check
+ below bottom of loop; first check at top suffices for loop itself.
+ (find_file): Remove redundant pointer checks in first two loops;
+ replace third loop with pointer to last list element determined
+ in first loop.
+
+Tue Jun 6 13:53:06 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Handle defined absolute symbols as
+ ASI values.
+
+ * config/obj-vms.c (vms_write_object_file, case N_DATA): Use
+ strcmp against FAKE_LABEL_NAME instead of checking third
+ character. (Suggested by Pat Rankin.)
+
+Mon Jun 5 20:10:46 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ Add support for N_ABS and N_ABS|N_EXT type symbols.
+
+ * config/obj-vms.h (LSY_S_M_{DEF,REL}, ENV_S_M_{DEF,NESTED}):
+ New macros for local symbols (from <lsydef.h> and <envdef.h>).
+ * config/obj-vms.c (Current_Environment): New file-scope variable.
+ (VMS_Local_Environment_Setup): New routine.
+ (GBLSYM_LCL): New macro.
+ (VMS_Global_Symbol_Spec): Handle local symbols too.
+ (VMS_Psect_Spec): Set GLOBALVALUE_BIT for absolute symbols.
+ (VMS_Emit_Globalvalues): Handle local and global absolute symbols.
+ (VMS_Store_PIC_Symbol_Reference): Ditto.
+ (vms_write_object_file: GSD symbol loop): Ditto.
+
+Mon Jun 5 16:10:40 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/tc-arm.h (LOCAL_LABELS_FB): Define.
+
+Mon Jun 5 02:17:58 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * configure.in (i386-*-gnu*): Always use GNU ELF config.
+
+Wed May 31 17:49:18 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (obj_crawl_symbol_chain): Update *symbolPP
+ in `else' clause when removing a symbol. Also, revise comments
+ to match the code.
+ (vms_write_object_file (GSD symbol loop, case N_DATA)): Never
+ output symbol definitions for local numeric labels.
+
+Tue May 30 18:29:10 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * configure.in (architecture variants, cases armeb and arm*): Remove
+ spaces round assignment to endian.
+
+Tue May 30 12:31:31 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * write.c (write_object_file): Check for undefined local dollar
+ and fb labels.
+
+ * symbols.c (decode_local_label_name): Extract instance number
+ from the correct location.
+
+Sat May 27 21:28:49 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/te-dpx2.h: Include obj-format.h.
+ (COFF_MAGIC): Renamed from FILE_HEADER_MAGIC.
+
+Wed May 24 13:45:32 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure, configure.in, config/obj-coff.c, config/obj-coff.h:
+ Add support for ARM pe
+
+Tue May 23 17:00:32 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_SPARC_WDISP16
+ and BFD_RELOC_SPARC_WDISP19.
+
+Tue May 23 19:18:33 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.c (parse_args) [! USE_EMULATIONS]: Always print an error
+ message.
+
+ * doc/internals.texi: Document obj_app_file and
+ TARGET_BYTES_BIG_ENDIAN.
+
+Mon May 22 20:03:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ecoff.c (ecoff_stab): Add extra leading argument, for 4 May
+ change.
+ * ecoff.h (ecoff_stab): Fix declaration.
+ * obj.h (format_ops.process_stab): Include prototype.
+ * config/obj-elf.h (OBJ_PROCESS_STAB): Pass through seg argument.
+ * config/obj-ecoff.h (OBJ_PROCESS_STAB): Ditto.
+
+ * config/e-mipself.c (mipself): New emulation mode, doesn't change
+ endianness from configured default.
+ * config/e-mipsecoff.c (mipsecoff): Ditto.
+ * configure.in (mips ecoff/elf targets): Include them.
+ * as.c (mipself, mipsecoff): Declare.
+
+ * as.c (emulation_name): New variable.
+ (select_emulation_mode): Set emulation_name. Don't change argv.
+ (parse_args): Handle --emulation; complain if the supplied name
+ isn't what select_emulation_name came up with.
+
+Sun May 21 21:36:17 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Reverse changes from Dec. 19th which
+ changed the way unwinds were built for ELF. Rely on relocation
+ symbol reductions to avoid placing the end of function marker
+ symbols into the object file's symbol table.
+
+Sat May 20 12:31:36 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Added improved VMS support from Pat Rankin:
+
+ Fri 19 May 16:51:40 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (AOUT_STABS): Define.
+
+ * config/obj-vms.c (fpush, rpush): New routines.
+ (push): Replaced by the above.
+ (find_symbol): Slight reorganization to expose tail recursion.
+
+ Fri Mar 17 18:40:36 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * Makefile.in (VMS_OTHER_OBJS): delete this.
+ * vmsconf.sh (make-gas.com): build ../libiberty/liberty.olb
+ first if necessary; link gas against it.
+
+Fri May 19 16:37:39 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * gasp.c (istrue): Correctly test for string inequality.
+
+Thu May 18 04:25:11 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * config/tc-arm.c (CP_T_{Pre,UD,WB}): Define, bits in co-processor
+ instructions.
+ ([ls]fm_flags): Correct error in bitmasks.
+ (cp_address_required_here): Delete second parameter, FLAGS. All
+ callers changed. Remove all dead code referring to FLAGS. If
+ address is just "[Reg]" then convert into a PRE-INCREMENT UP format.
+ (do_fp_ldmstm): Handle full-descending and empty-ascending stack
+ formats explicitly.
+
+ * config/tc-arm.c (internalError): Define.
+ (ARM_{1,2,250,3,6,7,7DM,ANY,2UP,ALL,3UP,6UP,LONGMUL}): Define processor
+ variants.
+ (FPU_{CORE,FPA10,FPA11,NONE,ALL,MEMMULTI}): Define floating point
+ variants.
+ ({CPU,FPU}_DEFAULT): Define.
+ (cpu_variant): New variable.
+ (asm_flg): Change more_flags to flag_bits.
+ Add prototypes for new functions.
+ (FLAG_{S,P,B,T,ED,FD,FA,EA,IB,IA,DB,DA,L}): Delete.
+ (s_flag[], ldst_flags[], byte_flag[], cmp_flags[], ldm_flags[],
+ stm_flags[], lfm_flags[], sfm_flags[], round_flags[], except_flags[],
+ cplong_flag[]): New variables.
+ (asm_opcode, insns[]): New format, add version support.
+ (arm_flg_hsh): Delete.
+ (do_mul, do_mla): Remove "Warning" from warning messages.
+ (do_arit): Simplify.
+ (do_swap): Make error message more appropriate.
+ (md_begin): Build hash tables starting at first entry in tables.
+ (md_number_to_chars): Cope with big/little-endian selection.
+ (md_chars_to_number): New function.
+ (md_apply_fix): Rewrite to make endian independent.
+ (tc_gen_reloc): Better error messages.
+ (md_assemble): Reject opcodes forbidden by the currently selected cpu
+ variant. Rewrite handling code for instruction flags.
+ (md_shortopts): Add option "m:".
+ (md_parse_option): Get the desired cpu/fpu variant.
+
+ From: David Taylor (dtaylor@armltd.co.uk)
+ * configure.in (architecture variants): Check for "armeb" and "arm*",
+ set endianness accordingly.
+ * read.c (read_a_source_file): New hooks md_start_line_hook and
+ md_after_pass_hook.
+ * config/arm-{big,lit}.mt: New files
+ * config/tc-arm.h ({LITTLE,BIG}_ENDIAN, BYTE_ORDER): Define.
+ (TARGET_FORMAT): Select depending on endianness and emulation and
+ object format.
+ (md_after_pass_hook, md_start_line_hook): Define.
+ * config/tc-arm.c: Include subsegs.h, symbols.h and listing.h.
+ (shift[]): Add uppper case equivalents.
+ (CP_T_[XY], TRANS_BIT): Define.
+ (conds[]): Delete initial NULL entry, add "lo" entry as synonym for
+ "cc".
+ (LONGEST_FLAG, flags[]): Delete.
+ (arm_psr): New structure.
+ (psrs[]): New variable.
+ (PSR_ALL): Define.
+ (LONGEST_INST): Bump to 5.
+ (LITERAL_MASK, COND_MASK, OPCODE_MASK, DATA_OP_SHIFT): Define.
+ (OPCODE_{AND,EOR,SUB,RSB,ADD,ADC,SBC,RSC,TST,TEQ,CMP,CMN,ORR,MOV,BIC,
+ MVN}): Define.
+ (insns[]): Add smull, umull, smlal, umlal, ldfm, stfm, msr and mrs
+ instructions. Add nop and adr pseudo ops.
+ (reg_table): Add APCS register name variants.
+ (arm_psr_hsh): New hash table.
+ (md_pseudo_table): Add "ltorg", "pool", "extend", "ldouble" and
+ "packed".
+ (MAX_LITERAL_POOL_SIZE): Define.
+ (struct literalS): New structure.
+ (literals, next_literal_pool_place, lit_pool_num, current_poolP): New
+ variables.
+ (add_to_lit_pool, symbol_locate, symbol_make_empty): New functions.
+ (validate_immediate): Return FAIL on failure.
+ (s_ltorg): New function.
+ (psr_required_here, psrf_required_here): New functions.
+ (cp_address_required_here): New parameter, flag, all callers changed.
+ If flag is non-zero, restrict the legal addressing modes.
+ (do_nop, do_mrs, do_msr, do_mull): New functions.
+ (negate_data_op): New function.
+ (data_op2): accept #x,y meaning x rotated right by y, but only when
+ suitable constants. If immediate is not legal, try changing the
+ opcode.
+ (do_adr): New function.
+ (do_ldst): accept "ldr reg, =expr". Put expr in the pool if it can't
+ be done as an immediate.
+ (do_fp_ldst): Use CP_T_[XY], not immediate values.
+ (do_fp_ldmstm): New function.
+ (arm_psr_parse): New function.
+ (output_inst): Use INSN_SIZE in call to md_number_to_chars.
+ (md_assemble): Add hack so that "Label instruction" causes alignment of
+ the label.
+ (arm_after_pass_hook, arm_start_line_hook, arm_frob_symbol): New
+ functions.
+
+Wed May 17 05:25:16 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_show_usage): Add \'s at end of lines in
+ strings for non-GCC compilers.
+
+Tue May 16 19:36:00 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-ecoff.c (ecoff_pop_insert): New function.
+ (ecoff_format_ops): Use it.
+ (obj_ecoff_frob_symbol): Now static.
+
+Wed May 17 00:59:12 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
+
+ * config/tc-ppc.c (md_begin): Was assuming that an instruction was
+ bigendian and hence 16bit relocs withing instructions would
+ ALWAYS be at addresses i+2-i+3. In LE mode it is i+0-i+1.
+
+Tue May 16 16:29:58 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-multi.h (obj_frob_symbol, obj_frob_file, S_GET_SIZE,
+ S_SET_SIZE, S_GET_ALIGN, S_SET_ALIGN, obj_copy_symbol_attributes,
+ OBJ_PROCESS_STAB): New macros.
+ * config/tc-mips.c: Protect against redefining them also when
+ including obj-elf.h. Test only OBJ_ELF for including elf/mips.h.
+ (mips_init_after_args): New function. Set byte_order here.
+ (md_parse_option): Not here.
+ (byte_order): Don't bother initializing.
+ * config/tc-mips.h (mips_init_after_args): Declare.
+ (tc_init_after_args): New macro.
+
+ * read.c (s_lcomm): Do ELF/ECOFF test at run time, not compile
+ time.
+
+Fri May 12 14:17:47 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Initial support for PE object files.
+ * configure.in, configure (i386-*-pe, i386-*-*nt): Add.
+ * config/obj-coff.c (fixup_segment): Cope with PE wierdness.
+ * config/obj-coff.h (TE_PE): New target format.
+
+Thu May 11 14:58:21 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-elf.c (NEED_ECOFF_DEBUG): Define if ECOFF_DEBUGGING
+ was defined by header files. Test in preprocessor conditionals
+ instead of ECOFF_DEBUGGING.
+ (ecoff_debug_pseudo_table): Make empty if NEED_ECOFF_DEBUG is not
+ defined.
+ (obj_read_begin_hook, obj_symbol_new_hook, elf_frob_symbol,
+ elf_frob_file): Only call ecoff routines if NEED_ECOFF_DEBUG is
+ defined.
+ (elf_ecoff_set_ext, elf_get_extr, elf_set_index): Define only if
+ NEED_ECOFF_DEBUG is defined.
+ (elf_format_ops): Reference elf_ecoff_set_ext only if
+ NEED_ECOFF_DEBUG.
+
+Wed May 10 18:09:12 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (OBJS): Include @extra_objects@.
+ (obj-elf.o, obj-ecoff.o, e-mipself.o, e-mipsecoff.o): New rules
+ for building these independently.
+ * emul-target.h, config/e-mipself.c, config/e-mipsecoff.c: New
+ files.
+
+ * acconfig.h (DEFAULT_EMULATION, EMULATIONS, USE_EMULATIONS,
+ OBJ_MAYBE_*, I386COFF, M68KCOFF, M88KCOFF): New macros.
+ * aclocal.m4 (GAS_UNIQ): New macro.
+
+ * as.c (emulations, n_emulations) [USE_EMULATIONS]: New variable.
+ (select_emulation_mode, default_emul_bfd_name, common_emul_init)
+ [USE_EMULATIONS]: New functions.
+ (main) [USE_EMULATIONS]: Call select_emulation_mode before other
+ initialization.
+ * emul.h: New file.
+ * as.h [USE_EMULATIONS]: Include it.
+
+ * configure.in: Handle enable-targets option. Iterate over target
+ list, building up a list of object file formats and emulation
+ configurations. (Only supports emulations for MIPS CPU so far.)
+ If multiple formats are needed, set obj_format to multi and add
+ format config files to extra_files. If emulation modes are
+ needed, add the relevant files to extra_files.
+
+ * configure.in: Define I386COFF, M68KCOFF, M88KCOFF for those
+ configurations.
+
+ * ecoff.c (ecoff_generate_asm_lineno): Filename argument now
+ points to const.
+ * ecoff.h (ecoff_generate_asm_lineno): Updated declaration.
+
+ * obj.h (obj_read_begin_hook): Don't declare function if it's
+ already a macro.
+
+ * read.c (s_space, cons, stringer): If md_flush_pending_output is
+ defined, call it on entry.
+ * config/obj-elf.c (obj_elf_section): If md_flush_pending_output
+ is defined, call it on entry. If md_elf_section_change_hook is
+ defined, call it before returning normally.
+
+ * read.h (target_big_endian): Declare.
+
+ * obj.h (struct format_ops): Added new function pointer fields
+ ecoff_set_ext, read_begin_hook, symbol_new_hook.
+ (ecoff_format_ops, elf_format_ops): Declare.
+ * config/obj-elf.c (elf_s_get_size, elf_s_set_size,
+ elf_s_get_align, elf_s_set_align, elf_copy_symbol_attributes,
+ elf_sec_sym_ok_for_reloc): New functions.
+ (elf_format_ops): New variable.
+ (elf_frob_symbol): Now takes additional int* argument.
+ * config/obj-elf.h (elf_frob_symbol): Update declaration.
+ (elf_pop_insert): Declare.
+ (obj_pop_insert): Define to call elf_pop_insert.
+ * config/obj-ecoff.c (ecoff_sec_sym_ok_for_reloc,
+ obj_ecoff_frob_symbol): New functions.
+ (ecoff_format_ops): New variable.
+
+ * config/te-generic.h: If OBJ_HEADER is defined, use it as the
+ filename to include in place of obj-format.h.
+ * config/te-multi.h: New file, copied from te-generic.h.
+ * config/obj-elf.c (OBJ_HEADER): Define it to "obj-elf.h".
+ * config/obj-ecoff.c (OBJ_HEADER): Define it to "obj-ecoff.h".
+
+ * config/obj-elf.c (ECOFF_DEBUGGING): Default to 0.
+ (obj_read_begin_hook, obj_symbol_new_hook, elf_frob_symbol,
+ elf_frob_file): Test it at run time.
+ (obj_ecoff_set_ext, elf_get_extr, elf_set_index): Define
+ unconditionally.
+ (elf_pseudo_table): Renamed from obj_pseudo_table, now static.
+ (ecoff_debug_pseudo_table): Split off into separate table. Define
+ it unconditionally.
+ (elf_pop_insert): New function.
+ * config/obj-elf.h (elf_pop_insert): Declare.
+ (obj_pop_insert): New macro.
+ (obj_ecoff_set_ext) [!OBJ_MAYBE_ELF]: Define to elf_ecoff_set_ext.
+ * config/obj-ecoff.h (obj_ecoff_set_ext): Define to ecoff_set_ext.
+
+ * config/tc-mips.h: Protect against multiple inclusions.
+ (mips_pop_insert): Declare.
+ (md_pop_insert): Call it.
+
+ * config/tc-mips.c: If OBJ_MAYBE_ELF is defined, include
+ obj-elf.h, but preserve OUTPUT_FLAVOR and protect some other
+ macros from redefinition.
+ (ECOFF_DEBUGGING): Default to 0. All references changed to
+ run-time tests or made unconditional.
+ (s_stringer, s_mips_space, s_elf_section): Deleted.
+ (md_pseudo_table): Don't refer to them. Split table into three
+ sections, for MIPS, non-ECOFF_DEBUGGING, and ELF.
+ (mips_pop_insert): New function.
+ (mips_flush_pending_output): New function.
+ (mips_enable_auto_align): New function.
+ * config/tc-mips.h (mips_pop_insert): Declare.
+ (md_pop_insert): New macro.
+ (mips_flush_pending_output): Declare.
+ (md_flush_pending_output): New macro.
+ (mips_enable_auto_align): Declare.
+ (md_elf_section_change_hook): New macro, calls
+ mips_enable_auto_align.
+
+Tue May 9 17:07:41 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add little endian PowerPC support.
+ * configure: Rebuild with autoconf.
+ * config/ppc-big.mt: New file for big endian PowerPC systems.
+ * config/ppc-lit.mt: New file for little endian PowerPC systems.
+
+ * config/tc-ppc.h (target_big_endian): Declare.
+ (TARGET_FORMAT): Deal with little and big endian ELF variants.
+ (TARGET_BYTES_BIG_ENDIAN): Define as 1, not empty.
+
+ * config/tc-ppc.c (ppc_big_endian): Delete variable, use
+ target_big_endian instead.
+ (md_parse_option): Parse -mlittle and -mlittle-endian to use
+ little endian support. Parse -mbig and -mbig-endian to use big
+ endian support.
+ (md_show_usage): Update to reflect current switches.
+ (ppc_set_cpu): Recognize powerpcle as little endian PowerPC. Use
+ as_fatal, not abort if unknown machine.
+
+Tue May 9 10:58:41 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Cast *valp to an integer when
+ comparing against signed values.
+ (hppa_force_relocation): Make "distance" an integer.
+
+Tue May 9 00:47:03 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * obj.h (struct format_ops) [BFD_ASSEMBLER]: New type.
+ (this_format) [BFD_ASSEMBLER]: Declare new variable, if not
+ already defined as a macro.
+
+Mon May 8 21:44:13 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * subsegs.h (seg_info): Provide dummy version for
+ non-BFD_ASSEMBLER, non-MANY_SEGMENTS configuration. It should
+ never get invoked, but this is easier than conditionalizing some
+ of the uses.
+ (struct seg_info_trash): Dummy type used by above to make code
+ compile.
+
+Fri May 5 14:47:13 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Define to 1, not
+ empty.
+ * config/obj-elf.h (SEPARATE_STAB_SECTIONS): Ditto.
+ * config/obj-som.h (SEPARATE_STAB_SECTIONS): Ditto.
+
+Thu May 4 19:26:55 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * stabs.c (get_stab_string_offset): Always define. If
+ SEPARATE_STAB_SECTIONS isn't set, abort.
+ (SEPARATE_STAB_SECTIONS): Default to zero.
+ (aout_process_stab): New function, split out from s_stab_generic.
+ (OBJ_PROCESS_STAB) [AOUT_STABS]: Define to call aout_process_stab,
+ if not already defined.
+ (s_stab_generic): Test SEPARATE_STAB_SECTIONS at run time. If
+ it's not set, and OBJ_PROCESS_STAB isn't defined, abort. Always
+ pass six arguments to OBJ_PROCESS_STAB.
+ * read.h (get_stab_string_offset): Declare unconditionally.
+ * config/obj-aout.h (AOUT_STABS): Define.
+ * config/obj-bout.h (AOUT_STABS): Define.
+ * config/obj-ecoff.h (OBJ_PROCESS_STAB): Add new first argument,
+ ignored.
+ * config/obj-elf.h (OBJ_PROCESS_STAB) [ECOFF_DEBUGGING]: Ditto.
+
+ * config/obj-ecoff.h (ECOFF_DEBUGGING): Define to 1, not empty.
+ * config/obj-elf.h (ECOFF_DEBUGGING): Ditto. Test value, not
+ whether it's defined.
+
+Wed May 3 21:38:20 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.h (LOCAL_LABELS_DOLLAR, LOCAL_LABELS_FB): If not already
+ defined, define them to zero.
+ * config/tc-*.h, config/te-*.h: If defining them, define them to
+ be 1 instead of empty.
+ * expr.c (integer_constant, operand): Test them at run time
+ instead of compile time.
+ * read.c (read_a_source_file): Ditto.
+ * symbols.c (colon): Ditto.
+ (dollar_*, define_dollar_label, fb_*): Define unconditionally.
+ * symbols.h (dollar_*, define_dollar_label, fb_*): Declare
+ unconditionally.
+
+Wed May 3 13:08:53 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Do nothing for an out of range
+ PC relative call since those only occur in cases where the linker
+ can fix them up.
+ (hppa_force_relocation): Force relocations for out of range PC
+ relative calls.
+
+Tue May 2 16:34:47 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * configure (hppa*-*-lites*): Handle just like hppa*-*-*elf*.
+ * configure.in: Likewise.
+
+Tue May 2 11:22:00 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * read.c (pop_insert): New function.
+ (pop_override_ok, pop_table_name): New variables.
+ (md_pop_insert, obj_pop_insert): New macros.
+ (pobegin): Use them.
+
+ * config/tc-mips.c: Use USE_STDARG and USE_VARARGS instead of
+ NO_STDARG &c.
+
+ * read.c (target_big_endian): If TARGET_BYTES_BIG_ENDIAN is
+ defined, initialize to 1.
+ * config/tc-mips.c (mips_target_format): Changed to a function,
+ checking flavor and byte order at run time.
+ (md_parse_option, cases OPTION_EB and OPTION_EL): Set
+ target_big_endian here.
+ (md_begin): Not here.
+ * config/tc-mips.h (mips_target_format): Adjust declaration.
+ (TARGET_FORMAT): Call mips_target_format.
+
+ * config/tc-mips.h (USE_GLOBAL_POINTER_OPT): Define in terms of
+ OUTPUT_FLAVOR.
+ * config/tc-mips.c (g_switch_value, g_switch_seen): Define
+ unconditionally.
+ (md_begin, mips_ip, md_parse_option, s_change_sec, s_option,
+ s_abicalls, nopic_need_relax): Check USE_GLOBAL_POINTER_OPT at run
+ time, instead of compiling conditionally on GPOPT.
+ (GPOPT): Don't define.
+ (md_shortopts): Always include -G.
+ (RDATA_SECTION_NAME): Select at run time.
+ (md_begin): Test for ELF format at run time instead of compile time.
+ (mips_ip, s_change_sec): Ditto.
+ (md_parse_option, cases OPTION_CALL_SHARED and OPTION_NON_SHARED):
+ Ditto.
+ (OPTION_CALL_SHARED, OPTION_NON_SHARED, mips_regmask_frag): Define
+ unconditionally.
+
+Tue May 2 00:17:04 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * Makefile.in (TARG_CPU_DEP_*): New variables.
+ (targ-cpu.o): Depend on one, selected by autoconf substitution,
+ instead of TARG_CPU_DEPENDENTS.
+ * configure.in: Substitute $cpu_type, $obj_format, $atof, and
+ $emulation into Makefile.in.
+ * config/h8300.mt: Deleted.
+ * config/h8500.mt: Deleted.
+ * config/i386coff.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/m68k.mt: Deleted.
+ * config/m68kcoff.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/m88kcoff.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/mips-big.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/mips-lit.mt (TARG_CPU_DEPENDENTS): Deleted.
+ * config/sh.mt: Deleted.
+ * config/w65.mt: Deleted.
+ * config/z8k.mt: Deleted.
+
+ * config/te-dpx2.h (dpx2): Deleted unused macro.
+ * config/te-generic.h (TE_GENERIC): Ditto.
+ * config/te-go32.h (TE_GO32): Ditto.
+ * config/te-hp300.h (TE_HP300): Ditto.
+ * config/te-hppa.h (PA, _TE_PA_H): Ditto.
+ * config/te-ic960.h (TE_IC960): Ditto.
+ * config/te-nbsd532.h (TE_NETBSD532): Ditto.
+ * config/te-pc532mach.h (TE_PC532MACH): Ditto.
+ * config/te-ppcnw.h (TE_PPCNW): Ditto.
+ * config/te-sco386.h (scounix): Ditto.
+
+Mon May 1 15:59:56 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * read.c (s_app_file): If obj_app_file is defined, call it with
+ string as argument. Don't call c_dot_file_symbol or
+ elf_file_symbol.
+ * config/obj-coff.h (obj_app_file): Define as c_dot_file_symbol.
+ * config/obj-elf.h (obj_app_file): Define as elf_file_symbol.
+
+ * as.h (OUTPUT_FLAVOR): Don't define here.
+ * config/obj-aout.h (OUTPUT_FLAVOR) [BFD_ASSEMBLER]: Define.
+ * config/obj-bout.h (OUTPUT_FLAVOR): Define.
+ * config/obj-coff.h (OUTPUT_FLAVOR) [BFD_ASSEMBLER]: Define.
+ * config/obj-ecoff.h (OUTPUT_FLAVOR): Define.
+ * config/obj-elf.h (OUTPUT_FLAVOR): Define.
+
+Thu Apr 27 20:07:33 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (RUNTEST): Use one in srcdir if present.
+ (RUNTESTFLAGS): Define.
+
+Wed Apr 26 15:54:10 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Support for more portable alignment handling in assembly code,
+ based on patches from Bryan Ford <baford@schirf.cs.utah.edu>:
+ * read.c (potable): Added balign and p2align, for aligning by
+ bytes or powers of two independent of what ".align" does for a
+ given target.
+ * doc/as.texinfo: Document them.
+
+Tue Apr 25 11:12:04 1995 Rob Savoye <rob@thepub.cygnus.com>
+
+ * configure, configure.in: Look for m68k-*-vxworks* rather than
+ just m68k-wrs-vxworks so gas can be configured for
+ m68k-vxworks5.1.
+
+Fri Apr 21 15:19:06 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): If fx_r_type is zero, handle
+ fx_size of 1, and abort on unrecognized sizes.
+
+ * config/tc-m68k.c (m68k_ip): Fix bug in last change regarding
+ non-isvar case.
+
+Sun Apr 16 01:52:52 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * config/tc-m68k.h (md_relax_table, TC_GENERIC_RELAX_TABLE):
+ Missed this one in 11 Apr changes.
+
+ * config/tc-i386.h (TC_GENERIC_RELAX_TABLE): Fix typo.
+
+Thu Apr 13 18:18:08 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sh.c (md_convert_frag): Instead of aborting on large
+ displacements, print an error message. Don't invoke the code that
+ followed the abort call until it's been verified.
+
+ * config/tc-m68k.c (md_show_usage): Add 68060 to list. Split cpu
+ list into three lines.
+
+Thu Apr 13 14:34:36 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * tc-m68k.c (m68k_init_after_args): Test for m68360.
+ (md_parse_option): Likewise.
+ (md_show_usage): Mention m68360.
+ * tc-m68k.h (TARGET_WORD_SIZE): Define.
+ (TARGET_ARCH): Define.
+
+ * expr.c (integer_constant): If TARGET_WORD_SIZE is defined,
+ sign-extend appropriately.
+
+Thu Apr 13 11:20:17 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Properly use PARAMS to
+ hide prototype from non-ANSI compilers, and don't use ANSI syntax
+ for arguments.
+
+Wed Apr 12 12:20:19 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in (TDEFINES): Put empty definition into
+ makefile fragment.
+ * mpw-make.in (xmalloc.c.o): Remove.
+ (as.new): Depend on Version.r.
+ (Version.r): Generate from version info.
+
+ * mpw-make.in: Delete references to hex-value.c.
+
+ * mpw-config.in: Add mapping from configs to object file formats,
+ get VERSION from Makefile.in and add to mk.tmp.
+ (mips-idt-ecoff) [TDEFINES]: Add TARGET_BYTES_BIG_ENDIAN.
+ * mpw-make.in (VERSION, gC): Don't define.
+ (ALL_CFLAGS): Remove -d flags.
+ (config.h): Remove definition of MPW, add HAVE_STDARG_H,
+ BFD_ASSEMBLER.
+
+ * mpw-make.in (ALL_CFLAGS): Add definition of HAVE_STDARG_H,
+ include of ::libiberty:.
+ (config.h): Ifdef contents on GAS_VERSION.
+
+ * mpw-make.in (as.c): Compile with C not gC.
+ (config-stamp): Touch correctly.
+ (install-only): New target.
+ (install): Depend on all and install-only.
+
+ * mpw-config.in: Parse target and use to generate forward includes
+ to tc-, obj-, and atof- files, use te-generic.h for emulation.
+ * mpw-make.in (VERSION): Define.
+ (as.c): Compile with GCC.
+ (TARG_OBJECTS, CLIBS): Define.
+ (as.new): Use LDFLAGS, TARG_OBJECTS, CLIBS and EXTRALIBS in link
+ command.
+ (config.h, config-stamp): Build.
+
+ * mpw-make.in (C, CFLAGS): Removed definitions.
+ (ALL_CFLAGS): Define.
+ Set default rule to use {CC} instead of {C}.
+
+ * mpw-make.in (install): Moved here from mpw-build.in.
+ * mpw-build.in: Removed, functionality in mpw-make.in
+
+ * mpw-make.in (CFLAGS): Add more include paths.
+
+ * mpw-config.in (varargs.h, sys/*.h): Don't create when
+ configuring.
+ * mpw-make.in (CFLAGS): Add -w flag.
+
+ * mpw-make.in: Replace 8-bit chars with their names.
+
+ * mpw-config.in: New file, MPW version of configure.in.
+ * mpw-make.in: New file, MPW version of Makefile.in.
+
+Tue Apr 11 01:42:36 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Require at least autoconf 2.3, because earlier
+ versions lose on some AIX versions.
+ * configure: Regenerated.
+
+ * configure.in: Add m68k-*-elf.
+ * config/tc-m68k.c (comment_chars) [OBJ_ELF]: Include '#'.
+ (md_pseudo_table) [OBJ_ELF]: Ignore "swbeg".
+ (md_begin): Set alt_notend_table['&'], so svr4-style immediate
+ operands are accepted.
+ (md_apply_fix): Argument VALP should point to valueT.
+ (md_convert_frag): Argument SEC should be type segT.
+ (md_shortopts) [OBJ_ELF]: Accept 'Q' with an argument.
+ (md_parse_option): Ignore it.
+ (md_convert_frag_1): Add in frag address for the symbol in the
+ displacement calculation.
+ * config/tc-m68k.h (TARGET_FORMAT) [OBJ_ELF]: Use "elf32-m68k".
+ (TARGET_ARCH): Define.
+ (REGISTER_PREFIX_OPTIONAL) [OBJ_ELF]: Default to 0.
+ (LOCAL_LABEL, FAKE_LABEL_NAME, REGISTER_PREFIX_OPTIONAL): Handle
+ these the same way for OBJ_ELF as for M68KCOFF.
+
+ * gdbinit.in: Add breakpoint in as_abort.
+
+ * write.c (cvt_frag_to_fill): If offset is less than zero,
+ complain about it specifically, instead of reporting an assertion
+ failure.
+ (relax_segment): Complain about .org backwards, then ignore it.
+ Do generic rs_machine_dependent relaxation only if
+ TC_GENERIC_RELAX_TABLE is defined, and use its value for the base
+ of the table.
+ * tc.h (md_relax_table): Delete declaration.
+ * as.h (struct relax_type): Add forward declaration for type.
+ * config/tc-a29k.c: Deleted md_relax_table.
+ * config/tc-{alpha,arm,h8300,hppa,i860,m88k,mips,ppc,sparc,z8k}.c:
+ Ditto.
+ * config/tc-{h8500,i386,i960,ns32k,sh,tahoe,vax,w65}.h: Declare
+ md_relax_table here, and define TC_GENERIC_RELAX_TABLE to expand
+ to md_relax_table.
+ * config/tc-h8500.c (md_relax_table): No longer const.
+ * config/tc-w65.c (md_relax_table): Ditto.
+ * config/tc-sparc.c (md_short_jump_size, md_long_jump_size):
+ Deleted.
+ * doc/internals.texi: Describe TC_GENERIC_RELAX_TABLE and
+ WORKING_DOT_WORD. Mention md_*_jump_size (but description needs
+ to be fleshed out later). Note m68k PCINDEX mode has been checked
+ in.
+
+Mon Apr 10 15:57:42 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-mips.c (nopic_need_relax): New static function, split
+ out from md_estimate_size_before_relax.
+ (md_estimate_size_before_relax): Call it.
+ (load_address, macro): In NO_PIC branches, if nopic_need_relax
+ returns nonzero, don't attempt GP optimization.
+
+ * config/tc-m68k.c (PCINDEX): New macro.
+ (md_relax_table): No longer const. Add PCINDEX entries.
+ (m68k_ip): For AINDX with simple symbol operand, generate a
+ PCINDEX frag if PC is used, or do normal non-AINDX processing for
+ address register.
+ (m68k_init_after_args): If cpu is 68000 or 68010, fix
+ md_relax_table to prevent relaxation of PCINDEX/BYTE mode to
+ SHORT, since they don't support that mode.
+ (md_convert_frag_1, case PCLEA/LONG): Add 4 to offset, not 2. Add
+ support for new PCINDEX modes.
+ (md_estimate_size_before_relax): Process PCINDEX/SZ_UNDEF mode.
+
+ * config/tc-m68k.c (md_convert_frag_1, case PCLEA/SHORT): Add 2 to
+ offset.
+ (m68k_ip, case most punctuation/AOFF): If using PC, call add_frag
+ using PCLEA.
+
+ * config/tc-m68k.c: Don't explicitly include config.h. Deleted a
+ bunch of "#if 0" code and useless comments.
+ (struct m68k_cpu): New type.
+ (archs, n_archs): New variables, with single list of name/enum
+ mapping and aliases.
+ (m68k_ip): Delete the table here.
+ (m68k_init_after_args): Use the new table here instead of
+ open-coding it.
+ (md_parse_option, case 'm'): Ditto.
+
+ * doc/Makefile.in (Makefile): Fix rule for running config.status.
+ (internals.dvi, internals.ps, internals.ps4): New targets, not
+ built by default.
+
+ * doc/internals.texi: Add loud disclaimer. Refill to 79 columns,
+ specify fill-column in local-variables section. Change
+ subheadings to subsections so they can be cross-referenced.
+ Describe broken words, frags, frag chains, generic relaxation,
+ relax table, m68k relaxation, m68k addressing modes, test suite
+ code. Add a few words about various file formats.
+
+ * doc/as.texinfo (m68k): Recommend using `%' with registers as the
+ normal case, instead of the exceptional case.
+
+Thu Mar 30 14:38:47 1995 H.J. Lu (hjl@nynexst.com)
+
+ * configure.in: Change linux to default to elf. Using
+ i[345]86-*-linuxaout will defaults to a.out.
+ * configure: Rebuild.
+
+Wed Mar 29 17:16:30 1995 Torbjorn Granlund <tege@adder.cygnus.com>
+
+ * config/tc-m68k.c (md_apply_fix_2): Cast negative offsets to offsetT
+ (for hosting on 64 bit machines).
+
+Tue Mar 21 16:53:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_show_usage): Mention -mips4 and -m4650.
+
+Fri Mar 17 16:47:13 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * write.c (write_object_file): Add PROGRESS macros.
+
+Fri Mar 17 12:40:34 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_comm): Make sure to always reset the frag
+ and section for common symbols.
+
+Thu Mar 16 17:26:18 1995 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow non PC relative
+ pointers in the .ctors and .dtors section also when using the
+ -mrelocatable option.
+ (md_parse_option): Support -m403 as a PowerPC computer.
+ (md_show_usage): Ditto.
+
+Wed Mar 15 14:45:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_build_debug): The cur_scope field of a fil_ptr
+ may be NULL when given strange input. Don't core dump.
+
+Tue Mar 14 21:36:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Don't use addiu for dli of an
+ unsigned seemingly negative number. Don't bother shifting a zero
+ value.
+ (mips_ip): For case 'j', if there are more alternatives, and the
+ ISA level is at least 3, don't accept an unsigned seemingly
+ negative number.
+
+Tue Mar 14 19:16:43 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * read.c (s_app_line): Fix last patch to deal with a line number
+ of 1.
+
+Tue Mar 14 17:00:57 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Use as_warn_where, not
+ as_bad_where to give a warning instead of an error.
+
+Mon Mar 13 17:03:46 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/tc-vax.c (md_assemble): issue a warning if a constant
+ is used as an operand where an immediate value is not allowed.
+
+Fri Mar 10 19:21:19 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.c: Redo my 10 Jan change, but get it right this
+ time. :-)
+ (fixup_segment): If linkrelax is set, just return.
+ (write_object_file): Don't treat h8300 and z8k specially with
+ regard to fixups.
+ * config/tc-h8300.c (md_begin): Set linkrelax.
+ * config/tc-z8k.c (md_begin): Ditto.
+
+Thu Mar 9 18:01:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (coff_header_append): Check return value of
+ bfd_coff_swap_scnhdr_out.
+
+Thu Mar 9 13:51:30 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ Delete this patch, it breaks the h8300 assembler.
+ Tue Jan 10 13:34:14 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+ * config/obj-coff.c (write_object_file): Don't treat h8300 and z8k
+ specially with regard to fixups.
+
+Thu Mar 9 12:28:18 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (mrelocatable): Change type to boolean.
+ (md_begin): Set the EF_PPC_RELOCATABLE if -mrelocatable.
+
+Wed Mar 8 15:39:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Check for a cpu string of r8000 or
+ r10000. If mips_isa is 4, set the machine number to 8000.
+ (append_insn): If mips_isa is at least 4, don't generate nops for
+ coprocessor delays. Check INSN_READ_FPR_R when setting
+ mips_cprmask[1].
+ (mips_emit_delays): If mips_isa is at least 4, don't generate nops
+ for coprocessor delays.
+ (mips_ip): Check for INSN_ISA4 instructions. Handle new argument
+ types 'h', 'R', 'N', and 'M'.
+ (md_longopts): Accept "mips4".
+ (md_parse_option): Handle -mips4, and -mcpu=10000 and -mcpu=8000.
+ (s_mipsset): Permit .set mips4.
+
+Wed Mar 8 09:36:05 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow .stab sections to
+ have non PC relative relocations with -mrelocatable.
+
+Wed Mar 8 02:57:53 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-m68k.c (opcode_ptr): Return pointer to const.
+ (md_begin): Make hash table errors fatal. Process opcode aliases
+ after main opcode table.
+ (md_apply_fix_2, case 4): Recode setting of lower_limit to avoid
+ gcc warning.
+
+Tue Mar 7 16:07:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Add documentation for SPARC V9, from Doug Evans
+ <dje@cygnus.com>.
+
+Mon Mar 6 09:58:34 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Change all occurences of pa-89 with pa-11 to
+ be consistent with current naming conventions.
+ (md_begin): Set a default architecture and machine type.
+ (pa_ip): If the current instruction specifies a newer machine type
+ than the current machine type, then update the current machine
+ type.
+ (need_pa11_opcode): Likewise.
+
+Sun Mar 5 19:38:09 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip, case 'z'): Don't lose argument
+ relocation bits for absolute calls.
+
+Fri Mar 3 17:41:50 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-h8300.* (md_operand): Change empty function to empty
+ macro.
+
+ * config/tc-h8300.c (build_bytes): Make H8/300-H warning message
+ clearer.
+
+ * write.c (write_contents): If bfd_set_section_contents fails,
+ print a message and exit, instead of aborting.
+
+Fri Mar 3 16:26:19 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * tc.h (md_apply_fix3): If MD_APPLY_FIX3 is defined, declare
+ md_apply_fix3.
+
+ * write.c (fixup_segment): If MD_APPLY_FIX3 is defined, call
+ md_apply_fix3 with the normal 2 arguments and the current segment
+ pointer instead of md_apply_fix.
+
+ * config/tc-ppc.h (MD_APPLY_FIX3): Define.
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Warn if -mrelocatable
+ and a non PC relative relocation that isn't in the .got2 segment
+ was performed.
+ (md_apply_fix3): Rename from md_apply_fix and take segment pointer
+ as third argument. If ELF object format, call ppc_elf_validate_fix
+ for normal relocations.
+ (md_parse_option): If ELF object format, recognize the
+ -mrelocatable switch.
+
+Thu Mar 2 16:34:44 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (AOUT_MACHTYPE): Define as 100, not 0.
+
+Tue Feb 28 18:29:27 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-arm.c, config/tc-arm.h (md_operand): Replaced empty
+ function in .c file with empty macro in .h file.
+ * config/tc-h8500.*, config/tc-hppa.*, config/tc-i386.*,
+ config/tc-i860.*, config/tc-i960.*, config/tc-ns32k.*,
+ config/tc-ppc.*, config/tc-sh.*, config/tc-sparc.*,
+ config/tc-tahoe.*, config/tc-vax.*, config/tc-w65.*,
+ config/tc-z8k.*: Ditto.
+ * config/tc-m68k.*: Ditto.
+
+ * config/tc-m68k.c (mote_pseudo_table): Removed dots from opcode
+ names.
+
+ * read.c (s_app_line): Ignore non-positive line numbers.
+
+Tue Feb 28 15:34:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust PLT or
+ GOT relocs either.
+
+Mon Feb 27 13:03:41 1995 Kung Hsu <kung@mexican.cygnus.com>
+
+ * configure.in: add a29k-*-vxworks configuration.
+
+Fri Feb 24 14:41:15 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Take dbl argument to determine
+ handling of signed 32 bit values in 64 bit modes. Change all
+ callers.
+ (macro): Handle M_DLI and M_DLA_AB.
+
+Wed Feb 22 23:10:56 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Don't subtract the value of the
+ add symbol if it's a common symbol (the value of a common symbol
+ is its size, not a value in the traditional sense).
+
+Wed Feb 22 21:12:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): If listing_prev_line is called,
+ call frag_grow to make sure there is still room for a variant.
+
+Fri Feb 17 14:50:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_pseudo_table): Add 2byte, 4byte and 8byte
+ if OBJ_ELF. From gary@Intrepid.COM (Gary Funck).
+
+ * config/obj-elf.c (elf_frob_symbol): Warn if a symbol is both
+ weak and common.
+ * config/obj-aout.c (obj_aout_frob_symbol): Likewise.
+
+Fri Feb 17 12:43:47 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): Don't redefine byte under
+ ELF.
+ (ppc_elf_cons): Don't support @pcrel any more, since DIFF_EXPR_OK
+ allows the normal expressions to generate it.
+ (md_apply_fix): Convert BFD_RELOC_32 with pcrel bit set into
+ BFD_RELOC_32_PCREL. Abort if either BFD_RELOC_16 or BFD_RELOC_8
+ need PC relative relocations.
+
+ * config/tc-ppc.h (DIFF_EXPR_OK): Define to allow PC relative
+ expressions to be handled.
+
+Thu Feb 16 14:30:13 1995 Doug Evans <dje@cygnus.com>
+
+ * expr.c (operand): Move md_operand handling to default case
+ (so it works).
+
+Wed Feb 15 16:08:47 1995 Jason Molenda <crash@cygnus.com>
+
+ * config/tc-h8500.c (tc_coff_symbol_emit_hook): Add ignored
+ parameter, to match prototype.
+
+Wed Feb 15 15:07:00 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_pseudo_table): If ELF, go to ppc_elf_cons
+ instead of cons.
+ (md_show_usage): Show all of the PowerPc options.
+ (ppc_elf_suffix): New function to recognize ELF suffixes that
+ specify a relocation, such as @GOT.
+ (ppc_elf_cons): Replacement for the standard cons function that
+ knows about the ELF suffixes.
+ (ppc_fixup): Add reloc field to hold non-standard relocation.
+ (md_assemble): Handle ELF suffixes like @GOT.
+ (md_create_short_jump): Dummy in case WORKING_DOT_WORD is not
+ defined.
+ (md_create_long_jump): Ditto.
+ (md_short_jump_size): Ditto.
+ (md_long_jump_size): Ditto.
+ (md_apply_fix): Handle BFD_RELOC_32_PCREL, BFD_RELOC_LO16,
+ BFD_RELOC_HI16, BFD_RELOC_HI16_S, BFD_RELOC_PPC_TOC16, and
+ BFD_RELOC_16 relocations. If relocation can not be found, print
+ the decimal value of the relocation.
+
+Wed Feb 15 11:46:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): Accept BFD_RELOC_16, for
+ DWARF. From gary@Intrepid.COM (Gary Funck).
+
+ * config/tc-mips.c (macro): Handle M_U{L,S}D[_A] (unaligned double
+ loads and stores).
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Do adjust global
+ symbols if OBJ_AOUT.
+
+ * config/tc-mips.c (macro): Don't use the target register as a
+ base register when building the address for M_L{W,D}{L,R}_AB.
+
+Mon Feb 13 14:44:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (KT0, KT1): Define.
+ (mips_ip): Recognize $kt0 and $kt1 as register names.
+
+ * config/tc-sparc.h (tc_fix_adjustable): Define if OBJ_ELF.
+ * config/tc-sparc.c (md_apply_fix): If OBJ_ELF, subtract out the
+ value of a defined symbol; the value was added in by
+ fixup_segment. This was previously corrected, if the reloc was
+ changed to be against a section symbol, in tc_gen_reloc.
+
+Fri Feb 10 14:04:04 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Use S_IS_EXTERN
+ rather than !S_IS_LOCAL.
+
+Thu Feb 9 18:16:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Adjust conditions for changing
+ BFD_RELOC_32 to BFD_RELOC_386_GOTPC to handle a switch in frags.
+ Patch originally from Rob Ryan <robr@cmu.edu>.
+
+ * config/tc-i386.c: Include subsegs.h.
+ (tc_i386_fix_adjustable): Declare return value.
+ (i386_operand): Don't use an assignment directly as a condition.
+
+Thu Feb 9 10:37:13 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): In some cases subtract the
+ value of the add symbol from valp. Offsets braindamage in the
+ "machine independent" fixup_segment.
+
+Wed Feb 8 18:51:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * messages.c (as_abort): New function.
+ * as.h (as_abort): Declare it.
+ (abort): New macro.
+
+ Thu Jan 19 18:10:05 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/vms-conf.h (HAVE_UNISTD_H): define it unconditionally.
+ * config-gas.com: test for availability of <unistd.h>; create a
+ rudimentary one if necessary.
+
+Tue Feb 7 13:34:46 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add powerpc-*-eabi support, which is the same as
+ powerpc-*-elf.
+ (configure): Rebuild with autoconf.
+
+Mon Feb 6 03:37:00 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from Bryan Ford <baford@schirf.cs.utah.edu> for i386
+ 16-bit and msdos support:
+ * config/tc-i386.c (flag_16bit_code): New variable.
+ (set_16bit_code_flag): New function.
+ (md_pseudo_table): Added entries "code16" and "code32".
+ (md_assemble): Ensure that correct data-size prefixes get emitted,
+ based on the current mode. Ensure that 32-bit addressing will
+ always be done. Move segment-prefix handling code. (Why?) Use
+ 16-bit jumps for 16-bit code, 32-bit jumps for 32-bit code.
+ * config/tc-i386.h (MAX_PREFIXES): Bump to 5.
+ (Data16, Data32): Define.
+ * doc/as.texinfo (i386-16bit): New node.
+ * configure.in (i386-*-msdos*): New target, using a.out format.
+ * configure: Regenerated.
+
+Thu Feb 2 15:21:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-m68k.c (cpu32_control_regs): New macro.
+ (m68k_init_after_args): Use it, for cpu32 processors.
+
+ Tue Jan 31 17:20:45 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (vms_tir_stack_psect): new routine;
+ (VMS_Set_Data, VMS_Set_Psect, VMS_Store_PIC_Symbol_Reference,
+ VMS_TBT_Routine_Begin, VMS_TBT_Line_PC_Correlation): use it;
+ (VMS_Global_Symbol_Spec, VMS_Procedure_Entry_Pt): treat
+ Psect_Number as `unsigned'.
+
+ Thu Jan 26 17:06:28 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c: performance tuning.
+ (VMS_Symbol_type_list): convert from single list head to small
+ array of list heads;
+ (SYMTYP_HASH): new macro for accessing VMS_Symbol_type_list[];
+ (find_symbol, setup_basic_type, VMS_typedef_parse): use it;
+ (VMS_RSYM_Parse): move S_GET_VALUE() inside switch to avoid
+ calling it for uninteresting cases.
+
+Wed Feb 1 23:52:45 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Go ahead and call
+ hppa_field_adjust to get a new value for R_DATA_ONE_SYMBOL
+ relocations in SOM.
+ (hppa_fix_adjustable): Refine somewhat.
+
+Fri Jan 27 21:29:53 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.h (NO_STRING_ESCAPES): Don't define if we are
+ using ELF.
+
+Thu Jan 26 19:03:42 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-h8300.c (get_specific): Add parens around | inside &.
+ (skip_colonthing): Set L_8 if ":8" is specified.
+
+Thu Jan 26 18:38:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_begin): Permit mfdec to be duplicated on the
+ 601. Check that the error return from hash_insert is "exists".
+
+Thu Jan 26 11:35:33 1995 Michael Meissner <meissner@cygnus.com>
+
+ * configure: Add support for configuring powerpc-*-eabi.
+
+ * config/tc-ppc.c (GOT_symbol): Define if object format is ELF.
+
+ * config/tc-ppc.h (GLOBAL_OFFSET_TABLE_NAME): Define if object
+ format is ELF and not defined to be "_GLOBAL_OFFSET_TABLE_".
+
+Wed Jan 25 16:23:13 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * tc-sh.c (little): Add argument IGNORE to avoid compiler warnings.
+ (md_pseudo_table): Add space for consistent formatting.
+ (COND8_RANGE, COND12_RANGE): Delete unused macros.
+ (COND8_F, COND8_M, COND12_F, COND12_M, UNCOND12_F, UNCOND12_M):
+ Correct minimum and maximum branch offsets. Add comments explaining
+ why these numbers are correct.
+
+Wed Jan 25 15:32:09 1995 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * config/tc-ppc.c (md_parse_option): Accept mpwr2 as a synonym for
+ mpwrx; mppc32, m603, and m604 as synonyms for mppc; and mppc64 and
+ m620 for PowerPC64 mode.
+ (ppc_symbol_new_hook): Add T0 as synonym for TC0 suffix.
+
+Tue Jan 24 16:44:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-vax.c (vip): Introduce new ptr-to-const local variable
+ for scanning operand string.
+
+ Sat Jan 21 17:50:38 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/vax-inst.h (struct vop, fields `vop_warn', `vop_error'):
+ make them pointers to const char;
+ (struct vit, field `vit_error'): ditto.
+ * config/atof-vax.c (md_atof): rename local `littlenum_pointer'
+ to `littlenumP' to avoid shadowing file scope variable.
+ * config/tc-vax.c (vip_begin, vip_op_defaults, vip_op_1): make
+ string arguments be pointers to const char;
+ (vip): make `alloperr' const char *;
+ (vip_op): make `err' and `wrn' const char *; rename `access' to
+ `access_mode' to avoid shadowing library function.
+ * config/obj-vms.c (`symbol_name'): make it const char *;
+ (get_struct_name): cast one use of `symbol_name' to char *
+ [caller guarantees that it won't modify the pointer's target];
+ (PUT_COUNTED_STRING): use pointer to const char;
+ (VMS_typedef_parse): make `pnt2' const char *;
+ (Write_VMS_MHD_Records): make `cp' const char *;
+ (VMS_Modify_Psect_Attributes, array `Attributes'): make const,
+ and make field `Name' pointer to const char;
+
+ * as.h (`seg_name[]' declaration): pointers to const char;
+ (struct _pseudo_type, field `poc_name'): pointer to const char.
+ * subsegs.c (`seg_name[]' definition): ditto;
+ * hash.c (hash_ask): rename argument `access' to `access_type'
+ to avoid shadowing library function.
+ * write.c (variable `the_object_file'): move from file scope
+ to block scope within write_object_file(); free it after use;
+ (fixup_segment): conditionally exclude it for OBJ_VMS.
+ (cvt_frag_to_fill): rename argument `headers' to `headersP'
+ to avoid shadowing file scope variable.
+
+Mon Jan 23 21:42:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip, case 'D'): Fix typo which caused
+ miscompilation of "diag" instructions.
+
+Mon Jan 23 15:51:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure: Regenerated.
+
+ * config/tc-mips.c: Include libiberty.h.
+
+Mon Jan 23 14:07:58 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-sh.h (tc_init_after_args): Don't define.
+ * config/tc-sh.c (md_begin): Remove unused variable table.
+ (md_assemble): Remove unused variable p.
+ (md_convert_frag): Cast fr_address to unsigned long for printf.
+ (md_apply_fix): Use as_warn_where rather than as_warn.
+ (sh_init_after_args): Remove empty function.
+
+ * configure.in (i386-*-gnu*elf*): New target.
+
+Sat Jan 21 19:02:23 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * hash.c (hash_ask): If we find the slot after wrapping around,
+ break out of the loop. Fixes bug in Jan 18 change.
+
+Fri Jan 20 17:07:31 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * hash.c (hash_code): Undo last change.
+
+Thu Jan 19 14:49:47 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-alpha.c (alpha_ip): Initialize local variables to keep
+ gcc quiet.
+ (gpdisp_hi16_howto): Don't use "const" with reloc_howto_type.
+ (in_range_signed): Add parens around subtraction inside shift.
+ * gasp.c (do_data): Initialize local variable "opname".
+ (istrue): Provide a default case to set "res" and keep "gcc -Wall"
+ quiet.
+ * write.c (write_contents): Deleted unused variable.
+ (print_symbol_value_1): Declare.
+ * hash.c (hash_ask): Delete disabled non-strcmp version of the
+ code, and automatic variables used only in those sections.
+ * write.c (chain_frchains_together_1): Only define local variable
+ "prev_fix" if BFD_ASSEMBLER.
+ * flonum-konst.c (dummy1): Return void.
+ * config/tc-vax.c (md_assemble): Remove two comparisons of
+ unsigned numbers versus zero.
+ * as.h (bcopy): If neither memcpy nor bcopy is defined as a macro,
+ define to use memcpy.
+
+ * config/tc-alpha.c, config/alpha-opcode.h: Revert 2 June changes.
+ Turns out we never got the assignment done after all.
+
+ Cleanup of VAX and VMS code, from Pat Rankin:
+ * config/obj-vms.c: Changed exported function names to lower case.
+ (Changed call sites in write.c.) Declare VMS system function
+ names used, conditional on actually being on VMS. Changed many
+ functions that returned no useful value to now be declared to
+ return void. Removed many unused variables. Supply missing
+ return statements or values. Supply `default' case in switch
+ statements. Ensure local variables get initialized.
+ * config/tc-vax.c: Minor changes to silence "gcc -Wall".
+ * config/obj-vms.h, config/tc-vax.h: Added some missing
+ declarations.
+
+Wed Jan 18 13:49:26 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * atof-generic.c (flonum_print) [TRACE]: New function.
+ (atof_generic) [TRACE]: Print multiplier before multiplication,
+ and print multiplication result before and after copy.
+
+ * flonum-mult.c (flonum_multip): Avoid sign extension problems
+ around multiplication operation.
+
+ * atof-generic.c (ASSUME_DECIMAL_MARK_IS_DOT): Define.
+ (atof_generic) [ASSUME_DECIMAL_MARK_IS_DOT]: Check for '.'
+ explicitly instead of calling strchr.
+
+ * config/tc-sparc.c (sparc_ip): When scanning successive opcode
+ table entries, check names for pointer equality before doing
+ string comparisons.
+
+ * hash.c (hash_ask): Call strcmp instead of expanding it inline.
+ (hash_code): Replaced with a version from bfd.
+
+ * config/obj-coff.c (write_object_file): If COFF_FLAGS isn't
+ defined, default it to zero.
+
+Wed Jan 18 12:16:07 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * write.c (fix_new_internal): Clear fx_bsr on those targets which
+ use it.
+
+ * expr.c (operand): Parenthesize && within ||.
+ * listing.c (listing_newline): Likewise.
+ (list_symbol_table): Use %lu to print sizeof.
+ * symbols.c: Comment out unused function indent.
+ (print_symbol_value_1): Cast pointer to unsigned long for printf.
+ * config/obj-coff.c (do_relocs_for): Only declare symbol_ptr if it
+ will be used.
+ * config/tc-h8300.c (md_begin): Remove unused variable reg.
+ (get_operand): Declare type of parameter direction. Remove unused
+ variable size.
+ (get_specific): Fix comment to avoid nested comments.
+ (check_operand): Cast X_add_number to unsigned long for printf.
+ (build_bytes): Remove unused local variables output_ptr, part, and
+ high.
+ (build_bytes): Cast X_add_number to unsigned long for printf.
+ (clever_message): Remove unused variable scan.
+ (md_assemble): Remove unused variable i.
+ (tc_coff_sizemachdep): Remove unused function.
+ * tc-h8300.h (tc_reloc_mangle): Declare.
+
+Tue Jan 17 10:58:06 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (mips_4650): New static variable.
+ (md_begin): Handle a cpu string of "4650". If mips_4650 was not
+ initialized, set it to 0.
+ (append_insn): Don't insert nops around HI and LO on a 4650.
+ (mips_emit_delays): Likewise.
+ (mips_ip): Use INSN_ISA mask to check ISA of instruction. Check
+ for INSN_4650.
+ (md_longopts): Add m4650 and no-m4650.
+ (md_parse_option): Handle mips-cpu=4650. Handle -m4650 and
+ -no-m4650.
+ * doc/as.texinfo: Document new MIPS options.
+
+Sat Jan 14 23:48:13 1995 Steve Chamberlain <sac@jonny>
+
+ * config/tc-w65.c, config/tc-w65.h, config/w65.mt: Newfiles.
+ * config/obj-coff.h: Cope with w65.
+ * configure, configure.in: Recognize w65.
+
+Thu Jan 12 17:56:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * app.c (do_scrub_next_char) [__GNUC__ && __OPTIMIZE__]: If `get'
+ function is scrub_from_file, call scrub_from_file directly, and
+ get gcc's inlining capability into the act.
+
+ * Makefile.in (VMS_OTHER_OBJS): Add ../libiberty/hex.o.
+ (OBJS): Delete hex-value.o.
+ (REAL_SOURCES): Delete hex-value.c.
+ (hex-value.o): Delete dependencies.
+ * hex-value.c: Deleted.
+ * as.c (main): Call hex_init.
+ * expr.c, config/tc-mips.c: Include libiberty.h. Replace
+ hex_value array references with hex_* macros.
+
+Wed Jan 11 17:51:38 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-h8300.h (COFF_FLAGS): Don't define.
+ * config/tc-h8500.h (COFF_FLAGS), config/tc-sh.h (COFF_FLAGS),
+ config/tc-z8k.h (COFF_FLAGS): Ditto.
+
+ * config/obj-coff.c (KEEP_RELOC_INFO): Make sure it's always
+ defined.
+
+ * config/tc-m68k.c (m68k_ip, cases AOFF and AINDEX): Don't
+ generate 68020 addressing modes for a 68000 processor.
+ (md_estimate_size_before_relax, cases PCREL and PCLEA): Ditto.
+
+Tue Jan 10 13:34:14 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Don't treat h8300 and z8k
+ specially with regard to fixups.
+
+Mon Jan 9 16:22:28 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-mips.c (RELAX_RELOC1, RELAX_RELOC2): Cast values to
+ bfd_vma before subtracting.
+
+ * config/obj-coff.c (size_section): Handle rs_space like rs_fill,
+ but make sure fr_symbol is null.
+ (fill_section): Ditto.
+
+Sun Jan 8 16:14:19 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Fix handling of floating point
+ values when GPOPT is not defined.
+
+Fri Jan 6 16:59:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gasp.c: Include string.h. Put config.h before other includes.
+
+ * config/tc-alpha.c (alpha_ip): Delay calls to emit_add64 until
+ after any remaining operands are also known to match.
+
+Fri Dec 30 18:21:41 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * listing.c (list_symbol_table): Build a format string based on
+ the size of the value to be printed, as long as "unsigned long" is
+ at least as wide, after handling the special case of 4-byte
+ values.
+
+ * Makefile.in (dependencies): Make $(OBJS) depend on as.h and
+ everything it includes. Delete those files from per-file
+ dependencies.
+
+ * as.h (relax_substateT): Now defined to be unsigned int.
+ (relax_stateT): Separate typedef from enum definition.
+ (enum _relax_state): Reordered for better punctuation. Added new
+ values rs_align_code and rs_space.
+ (lineno, struct lineno_struct): Unused, deleted.
+
+ * as.h: No longer include assert.h.
+ (as_assert): Declare.
+ (assert): New definition, calls as_assert longer needed.
+ (__PRETTY_FUNCTION__): Provide default for older versions of gcc.
+ * messages.c (as_assert): New function.
+ * gdbinit.in: Put a breakpoint there.
+
+ * read.c (s_space): Rewrite to handle general expressions.
+ Generate rs_space frags for non-constant values.
+ * write.c (cvt_frag_to_fill): Treat rs_align_code and rs_space
+ like rs_align and rs_org. Verify that fr_offset is non-negative,
+ and force frag type to rs_fill only after assertion checks.
+ (relax_segment): Treat rs_align_code like rs_align. Treat
+ rs_space like rs_org in the first switch; in the second, force the
+ operand to a constant, and use it for the growth size.
+
+Wed Dec 28 20:57:37 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_subspace): For sections with the ZERO
+ attribute, set the "bss" field in the appropriate seginfo structure.
+
+Wed Dec 28 15:01:01 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * subsegs.h: Include obstack.h.
+
+Tue Dec 27 18:16:04 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.h (struct frag): Enable align* components now.
+
+Tue Dec 20 14:56:31 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * frags.c (frag_init): Call obstack_begin on `frags'.
+ * subsegs.c (subsegs_begin): Don't do it here.
+ * as.c (main): Call frag_init before subsegs_begin.
+
+ * frags.c (frag_append_1_char): New function.
+ * frags.h (frag_append_1_char): Declare it.
+ (FRAG_APPEND_1_CHAR): Call it. Old definition is commented out
+ for now.
+
+ * as.h (struct frag): Added (but commented out) new fields for
+ tracking current alignment.
+ (frag_now_fix): Changed macro to function declaration.
+ * frags.c (frag_now_fix): Define function here.
+ (frag_new): Use it instead of accessing `frags' directly.
+ * frags.h (frags): Change comment to indicate it shouldn't be
+ accessed directly.
+ * subsegs.h (struct frchain): New field frch_obstack, intended to
+ eventually replace global `frags' obstack.
+ * subsegs.c (subseg_set_rest): Use frag_now_fix instead of
+ accessing `frags' directly. Initialize fields of new frchainS
+ explicitly instead of with memset.
+ * config/obj-coff.c (obj_coff_ln) [!BFD_ASSEMBLER]: Use
+ frag_now_fix.
+ * config/tc-mips.c (s_loc), config/obj-vms.c
+ (vms_resolve_symbol_redef), symbols.c (colon): Likewise.
+
+ * config/tc-m68k.c (md_apply_fix_2): Use offsetT and addressT
+ instead of long and unsigned long.
+ (md_apply_fix): Cast value before passing it.
+
+ * config/obj-aout.h, config/obj-coff.c, config/obj-elf.h,
+ config/obj-som.h, config/tc-h8500.c, config/tc-hppa.c,
+ config/tc-hppa.h, config/tc-sh.c, config/tc-z8k.c: Don't rely on
+ use of ".." when including header files.
+
+ * config/obj-coff.c (fixup_segment): Reformat condition in an `if'
+ statement.
+
+ * Makefile.in (SUBDIR_INCLUDES): Deleted.
+
+Tue Dec 20 13:40:36 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/obj-coff.h: Include bfd/libcoff.h, not libcoff.h.
+
+Mon Dec 19 16:53:36 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (load_register): Rewrite to handle O_big 64 bit
+ constants.
+ (mips_ip): Accept O_big constants in case 'I'. Change case
+ 'i'/'j' to treat an O_big constant as an out of range value.
+
+Mon Dec 19 14:15:07 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_subspace): Make sure SEC_HAS_CONTENTS is
+ clear for a section with the "ZERO" attribute.
+
+ * Reduce useless symbols for ELF in an attempt to make smaller
+ objects and speed up the linker.
+ * config/tc-hppa.c (struct call_info): Replace end_symbol field
+ with a size field.
+ (hppa_elf_mark_end_function): Delete unneeded function.
+ (pa_build_unwind_subspace): For the 2nd unwind relocation, use
+ the function symbol + function size instead of a special symbol
+ for the end of the function.
+ (process_exit): Compute the function size here. Don't call
+ hppa_elf_mark_end_of_function anymore.
+ (pa_procend): Likewise.
+ (hppa_fix_adjustable): Only reject 32bit relocations for SOM.
+ (elf_hppa_final_processing): Simplify.
+
+Mon Dec 19 13:49:07 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Recognize mips-sony-bsd and mips-dec-bsd, but
+ reject other vendors until we can be sure we're consistent with
+ bfd.
+
+ * config/obj-vms.c (Create_VMS_Object_File): Instead of formatting
+ a buffer to pass to `error', just call `as_fatal' directly.
+ (VMS_Psect_Spec): Ditto.
+ (VMS_TBT_Module_Begin, VMS_TBT_Source_File, gen1,
+ VMS_typedef_parse, VMS_LSYM_Parse, VMS_Emit_Globalvalues): Call
+ as_tsktsk instead of printf.
+ (VMS_TBT_Module_Begin, VMS_TBT_Line_PC_Correlation,
+ VMS_TBT_Source_File, VMS_TBT_Source_Lines,
+ VMS_Store_Repeated_Data, VMS_Check_For_Main): Use explicit
+ integers rather than sizeof expressions using basic integer types,
+ in case host and target aren't the same. Use memcpy or COPY_*
+ macros instead of possibly unaligned word or longword assignment.
+
+ * config/obj-vms.h (OBJ_SYMFIELD_TYPE): New macro.
+ * config/obj-vms.c (VMS_Store_PIC_Symbol_Reference,
+ VMS_Check_For_Main, VMS_write_object_file): Use sy_obj instead of
+ forcing sy_number to hold a pointer.
+
+Fri Dec 16 14:40:16 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sh.c (md_begin): Don't fill in md_relax_table here.
+ (md_relax_table): Use static initialization.
+
+ * config/tc-h8300.c (parse_exp, get_operands, clever_message,
+ md_assemble, tc_crawl_symbol_chain, md_undefined_symbol,
+ tc_headers_hook, md_operand, md_number_to_chars): Don't use DEFUN.
+
+ * Makefile.in (CHECKFLAGS): Don't pass AS_FOR_TARGET,
+ CC_FOR_TARGET, OBJDUMP_FOR_TARGET, NM_FOR_TARGET; they're not
+ used.
+ (AS_FOR_TARGET, CC_FOR_TARGET, OBJDUMP, OBJDUMP_FOR_TARGET, NM,
+ NM_FOR_TARGET): Don't define.
+ (VMS_OTHER_OBJS): Add xmalloc.o and xexit.o from libiberty.
+ (tooldir): Use exec_prefix, not libdir.
+
+Fri Dec 16 11:07:10 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * config/obj-coff.h: Include libcoff.h, not ../bfd/libcoff.h.
+
+ * as.h: Include progress.h.
+ * as.c (main): Call START_PROGRESS and END_PROGRESS.
+ (main, perform_an_assembly_pass): Call PROGRESS.
+
+Fri Dec 16 00:46:08 1994 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * write.c (adjust_reloc_syms): Use bfd_is_und_section and
+ bfd_is_abs_section rather than comparing against &bfd_und_section
+ and &bfd_abs_section.
+
+Thu Dec 15 15:27:14 1994 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (md_begin): Use a local variable when
+ initializing md_relax_table to avoid errors about modifying a
+ const data structure.
+
+Tue Dec 13 15:42:27 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-ppc.c (tc_gen_reloc): Remove OBJ_ELF hack which
+ appears to no longer be needed.
+
+Tue Dec 13 08:04:15 1994 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Accept BFD_RELOC_PCREL* without
+ requiring that the X_op_symbol be in the text_section.
+ (macro): Change the test for a legel expression difference to
+ correspond to changes in pseudo_set in read.c.
+
+Fri Dec 9 21:04:17 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * write.c (write_relocs) [RELOC_EXPANSION_POSSIBLE]: Use
+ bfd_install_relocation.
+
+ * ecoff.c (ecoff_set_gp_prolog_size): If there is no current
+ routine, just return.
+
+ * config/tc-alpha.c (alpha_ip, case 'B', subcase 'c'): Use opcode
+ value from pattern instead of assuming jsr.
+ * config/alpha-opcode.h (jmp): Add a "1,Bc" form.
+
+Thu Dec 8 17:48:25 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (NM_FOR_TARGET): Use ../binutils/nm.new, not just
+ plain nm.
+
+ * configure.in (ns32k-pc532-mach*): Select correct emulation.
+ (mips-sony-bsd*): Use ecoff.
+ (mips-*-gnu*): New target, using aout format, from Roland McGrath.
+ * configure: Regenerated.
+
+Tue Nov 29 13:58:10 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Use libiberty version of xmalloc:
+ * Makefile.in (REAL_SOURCES): Delete xmalloc.c.
+ (OBJS): Delete xmalloc.o.
+ (xmalloc.o): Delete dependencies.
+ * as.c (main): Call xmalloc_set_program_name once program name is
+ known.
+
+ * config/tc-alpha.c (in_range_signed, in_range_unsigned): New
+ routines, split from in_range.
+ (in_range): Deleted. All calls changed to in_range_*signed.
+ (create_lita_section): Macro deleted. Single use expanded in
+ place.
+ (alpha_ip): Handle `t' and `8' operand types.
+ (md_apply_fix): Handle BFD_RELOC_12_PCREL. Print name of
+ unhandled relocation types.
+ * config/alpha-opcode.h: Added HALT and DRAINA. Disabled MOVI,
+ since it doesn't work, and isn't supported by the native
+ assembler.
+
+ * input-scrub.c: Change wording of a comment to avoid interference
+ with Cygnus source-control tools.
+
+ * as.h (errno) [NEED_DECLARATION_ERRNO]: Declare.
+
+ * config/tc-m68k.c (init_table): List buscr and pcr control
+ registers.
+ (m68k_ip, case 'J'): Handle them.
+
+ Delete signal handler code. It's been disabled since March 1993
+ without complaints.
+ * as.c: Don't include signal.h.
+ (got_sig): Unused function deleted, declaration deleted.
+ (SIGTY): Macro deleted.
+ (main): Deleted disabled code for establishing signal handler.
+
+Mon Nov 28 11:37:35 1994 Doug Evans <dje@canuck.cygnus.com>
+
+ * app.c (do_scrub_next_char): Insert missing newline at end of file
+ like warning says we do.
+
+Mon Nov 28 00:11:15 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (pa_check_eof): Declare new extern function.
+ (tc_frob_file): Define to call pa_check_eof.
+
+ * config/tc-hppa.c (pa_check_current_space_and_subspace): New
+ function to verify the current space and subspace are reasonable.
+ Call for the appropriate pseudo-ops and before instruction parsing.
+ (pa_check_eof): New function to verify enter/exit and proc/procend
+ pairs match at EOF.
+ (pa_code): Simplify.
+
+ * config/obj-som.c: Delete #if 0 code.
+
+Wed Nov 23 19:36:09 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coff.h (TARGET_FORMAT): Select between coff-shl and
+ coff-sh.
+ * config/sh.mh (TARG_CPU_DEPENDENTS): Get it right.
+ * config/tc-sh.c (little): New function.
+ (md_parse_option): Notice new option.
+ (build_relax, build_Mytes, md_atof, md_convert_frag, md_apply_fix):
+ Cope with little endian data.
+ * config/tc-sh.h (COFF_MAGIC, LISTING_HEADER): Endian dependent.
+
+Wed Nov 23 10:54:38 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (tc_gen_reloc, ELF variant): Revert last
+ change. The real bug was in bfd/elfcode.h and has been fixed.
+
+Tue Nov 22 23:31:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (tc_gen_reloc, ELF variant): Add section->vma
+ to the relocation's offset.
+
+Tue Nov 22 14:37:58 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * Makefile.in (INSTALL_XFORM): Fix typo.
+
+Tue Nov 22 10:23:25 1994 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * config/tc-alpha.c (s_alpha_set): Ignore the .set (no)move and
+ .set (no)volatile directives.
+
+Tue Nov 15 21:44:13 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_subspace): Make sure to always reset
+ current_subspace.
+ (pa_text, pa_data): Likewise.
+
+ * config/tc-hppa.c (pa_align): New function. Aligns the current
+ offset within the current subspace along with updating the
+ alignment of the subspace itself.
+ (pa_subspace): Default alignment to one byte rathern than zero
+ bytes to avoid setting alignment to log2(0).
+ (md_pseudo_table): Use pa_alignment for .align.
+
+Tue Nov 15 15:24:45 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * messages.c (as_fatal): Always put a space after "fatal error:"
+ when printing message.
+
+Tue Nov 15 11:10:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (obj_frob_symbol): Delete.
+ (tc_frob_symbol): Make definition conditional on OBJ_SOM or
+ OBJ_ELF. For ELF subtract out symbol->section->vma for non common
+ symbols.
+
+Wed Nov 9 14:53:03 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/te-delta.h: New file, derived from te-sysv32.h.
+
+Wed Nov 9 11:52:44 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-ppc.c (ppc_bf): Always set coff_line_base.
+
+Mon Nov 7 01:58:49 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (VERSION): Bump to 2.5.3.
+
+ * configure.in: Compare generic cpu name against "sparc", not
+ "sparc*", since sparc variants should be changed to "sparc".
+ * configure: Regenerated with autoconf 2.1.
+
+ * config/tc-a29k.c (octal, toHex): Variables deleted.
+ (isoctal): Macro deleted.
+ (md_begin): Don't initialize them.
+ (machine_ip, case 'P'/'A'): For absolute operand, generate an
+ error message if it's out of range.
+ (md_apply_fix, case RELOC_JUMPTARG): Check range for PC-relative
+ jumps.
+ (md_apply_fix): Delete code inside "#if 0".
+
+Thu Nov 3 20:20:40 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/go32.mh: Unused file deleted.
+
+ * read.c (get_absolute_expression): Indicate that the error may
+ merely be that the expression can't currently be reduced.
+
+Thu Nov 3 16:09:59 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * config/tc-m68k.h (TARGET_FORMAT): If TE_NetBSD define as
+ "a.out-m68k-netbsd".
+ * config/tc-sparc.h (TARGET_FORMAT): If TE_NetBSD define as
+ "a.out-sparc-netbsd".
+
+ * config/te-nbsd.h: New file, NetBSD target emulation
+ * config/te-netbsd.h: Removed.
+ * configure.in (i[345]86-*-netbsd*,m68*-*-netbsd*,sparc*-*-netbsd*):
+ Set bfd_gas. Use nbsd emulation.
+
+Thu Nov 3 17:44:47 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from net 2.5.2 release branch:
+
+ * configure.in: Put AC_DEFINE(sparcv9) on its own line, so that
+ the shell variable settings associated with it are permanent. For
+ CPUs requiring bfd_gas=yes, select it based on CPU only, not
+ individual target names. Handle m68k-hp-hpux*, not just -hpux.
+
+ * config/tc-z8k.c (tc_coff_symbol_emit_hook): Add dummy argument
+ to match prototype in obj-coff.h.
+
+ * configure.in: Skip tests for defining WANT_FOPEN_BIN and
+ IBM_COMPILER_SUX.
+ * acconfig.h: Deleted them.
+ * configure, conf.in: Rebuild with autoconf 2.0.
+ * config/go32.cfg, config/vms-conf.h: Updated.
+
+ * config/tc-m68k.c (md_apply_fix_2, md_convert_frag_1): Always use
+ IBM_COMPILER_SUX version of code, with comments indicating why.
+
+ * listing.c (file_info): Use text mode when opening file for read.
+ Use "r" directly, no macro.
+ * input-file.c (input_file_open): Don't use FOPEN_RT, just use
+ "r".
+ * read.c (s_include): Ditto.
+ * output-file.c (output_file_create): Try both "wb" and "w", don't
+ bother with FOPEN_* macros.
+ * as.h: Don't include fopen-*.h.
+
+ * config/alpha-opcode.h: Make "ret" with no operands equivalent to
+ "ret zero,(ra)", to match OSF1 and to be consistent with both
+ one-operand forms.
+
+ Patches from DJ Delorie:
+ * as.h (alloca): undef alloca before defining it just in case
+ * config/go32.cfg: new file for autoconf values
+ * config/te-go32.h: new file
+ * configure.bat: new for autoconf
+
+ * config/tc-i386.c (md_assemble): Fix typo in GOTPC check; had =
+ for ==.
+
+ * configure.in: If target_frag doesn't exist, use /dev/null.
+
+ * as.c (parse_args): For non-VMS systems, re-add `v' to
+ std_shortopts. Add "verbose" to list of long options.
+
+ * write.c (adjust_reloc_syms): When generating an absolute section
+ symbol as a placeholder, don't mark it as used in a relocation
+ entry, here.
+
+ * Makefile.in (comparison): Compare using makefile code from gcc,
+ stripped down to discard subdir stuff and adapted to give a
+ non-zero exit status if either file differs.
+
+Thu Nov 3 15:43:02 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (load_address): Fix RELAX_ENCODE arguments for
+ NO_PIC case.
+
+Tue Nov 1 16:10:59 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (s_change_sec): If not GPOPT, don't permit
+ switching to the readonly data section.
+
+ * ecoff.c (ecoff_directive_type): Fix warning message.
+
+Sun Oct 30 00:57:35 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_proc): Delete disabled code to put each
+ proc in its own subspace, we're not going to use it.
+
+Tue Oct 25 14:44:33 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (macro): Ensure that mips2 case of M_LI_DD in
+ .rdata does not become a variant frag.
+
+ * config/tc-mips.c (mips_cpu): Initialize to -1.
+ (md_begin): Don't mips_cpu if it was already set.
+ (md_parse_option): For -mipsN, don't set mips_cpu if it was
+ already set. For -mcpu=, just set mips_cpu, not mips_isa.
+
+Fri Oct 21 20:42:29 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (md_pseudo_table): If OBJ_ELF, handle .section.
+ (s_elf_section): New static function.
+ * ecoff.c (ecoff_build_symbols): Don't abort if we don't recognize
+ the section when setting the storage class; default to sc_Data.
+
+Thu Oct 20 00:43:38 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Set new_val to 8 for all
+ fixups to branch instructions (not just pc-relative ones) which
+ will generate SOM relocations.
+
+Wed Oct 19 13:41:56 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-a29k.c: Include ctype.h with angle brackets.
+ (define_some_regs): Add new special register names defined on the
+ 29040.
+ (parse_operand): Add argument opt. If non-zero, don't warn about
+ a missing operand.
+ (machine_ip): If handling argument type 'I', pass opt as non-zero
+ to parse_operand. Handle new optional operand type 'I'.
+ (md_undefined_symbol): Handle special register names (srNN).
+
+Tue Oct 18 00:45:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (renumber_sections): New static BFD_ASSEMBLER function.
+ (write_object_file): Call it after removing gas created sections.
+
+Mon Oct 17 18:06:05 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * symbols.c (symbol_create): Use udata.p, not just udata.
+ * config/obj-elf.c (obj_ecoff_set_ext): Likewise.
+ (elf_get_extr): Likewise.
+
+ * read.c (read_a_source_file): The second argument to as_where is
+ unsigned int *, not int *.
+
+Mon Oct 17 02:26:32 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Eliminate all uses of fx_addnumber.
+ (tc_gen_reloc): Simplify. It's no longer necessary to set a
+ reloc's addend field to zero for function symbols.
+ (md_apply_fix): Simplify. For fixups which will require a SOM
+ reloc, just clear out the necessary bits in the output file.
+
+Fri Oct 14 19:06:46 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (BISON): Use bison -y, not bison.
+
+Thu Oct 13 19:22:54 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (VERSION): Updated to 2.5.
+ (clean-here): Delete stamp-mk.com.
+ (distclean): Delete .gdbinit.
+ * Version 2.5 released.
+
+Wed Oct 12 20:30:51 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/te-nbsd532.h: Renamed from te-netbsd532.h.
+ * configure.in, configure: Adjusted.
+
+Wed Oct 12 16:33:38 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/cplus-dem.c: Removed. It isn't used. Even if it was,
+ it's better to use the one in libiberty.
+
+Wed Oct 12 18:48:39 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * symbols.c (resolve_symbol_value, case O_symbol): Undo last
+ change; it breaks the rs6000 support, and doesn't seem to be
+ needed.
+
+Wed Oct 12 11:56:50 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/tc-i386.h,te-netbsd532.h (TARGET_FORMAT): Changed to
+ a.out-<arch>-netbsd to match corresponding changes in BFD.
+
+Wed Oct 12 11:06:11 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Resolve symbol values
+ rather than explicitly adding the frag address.
+ * config/obj-coff.c (coff_frob_symbol): Add a zero entry to mark
+ the end of the line numbers; this replaces the zero entry which
+ used to be added by coff_add_linesym, removed Oct 7.
+ (coff_adjust_section_syms): Ignore sections with no seginfo.
+
+Wed Oct 12 01:41:37 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (bootstrap, bootstrap2, bootstrap3): Create a
+ "stage" symlink to the appropriate stage* directory, and use it
+ instead in the -B options.
+ (comparison): Revert yesterday's change.
+
+Tue Oct 11 16:48:11 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-sparc.c (tc_gen_reloc): For non-a.out relocations, if
+ pc-relative, use fx_offset only, ignore address of relocation.
+
+Tue Oct 11 15:24:00 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't use S_IS_LOCAL when checking
+ for an embedded PIC switch expression, since the definition of
+ S_IS_LOCAL was changed.
+
+Tue Oct 11 15:05:11 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * Makefile.in (comparison): When comparing as.new or gasp.new, try
+ running the binary through sed to avoid differences due to
+ "stage1" or "stage2" having been written into the binary.
+
+Sat Oct 8 01:48:04 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ ELF symbol size handling, based on code from Eric Youngdale:
+ * config/obj-elf.h (OBJ_SYMFIELD_TYPE): New macro. Adds an
+ expression pointer to the symbol structure, used for `size'
+ expressions that couldn't be reduced to constants when initially
+ processed.
+ (elf_frob_symbol): Declare.
+ (obj_frob_symbol): Call elf_frob_symbol always, rather than
+ ecoff_frob_symbol only if ECOFF_DEBUGGING defined.
+ * config/obj-elf.c (obj_symbol_new_hook): Deleted unused code.
+ Clear sy_obj field.
+ (obj_elf_size): Deleted unused code. If size is non-reducible
+ expression, allocate some storage for the sy_obj field and copy
+ the expression.
+ (elf_frob_symbol): New function. Computes sizes, calls
+ ecoff_frob_symbol if appropriate.
+
+ * write.c (fixup_segment): For i386 elf and coff (for now), don't
+ add in value of symbol from another defined section of the file.
+
+Fri Oct 7 17:54:02 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/tc-m88k.h (TC_KEEP_FX_OFFSET): Define.
+ * config/obj-coff.c (do_relocs_for): Test only TC_KEEP_FX_OFFSET,
+ rather than both it and TC_M88K.
+ (coff_adjust_section_syms): New function.
+ (coff_frob_section): For non-empty sections, create aux entry for
+ the section symbol, indicating the size.
+ (n_line_nos): New variable.
+ (add_lineno): Increment it.
+ (coff_add_linesym): Increment n_line_nos, don't call add_lineno.
+ (coff_frob_file): New function; map coff_adjust_section_syms over
+ sections.
+ (obj_coff_line): Only reset line_base for .bf symbols.
+ * config/obj-coff.h (coff_adjust_section_syms, coff_frob_file):
+ Declare.
+ (obj_frob_file): New macro.
+
+ * config/obj-coff.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Renamed from
+ obj_frob_forward_symbol, and rewritten for new parameter list.
+
+ Mon Oct 3 21:02:38 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (S_IS_LOCAL): fix obsolete flagseen[] reference.
+
+Wed Oct 5 11:49:26 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * config/obj-ecoff.c (obj_pseudo_table): Accept .esize and .etype
+ as synonyms for .size and .type.
+
+Wed Oct 5 00:08:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (coff_frob_section): Remove assert about
+ section alignment.
+ * config/tc-sparc.c (md_section_align): Use section alignment, not
+ xvec align_power_min field.
+
+Fri Sep 30 19:05:20 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * vmsconf.sh (make-gas.com): handle DCL verification to enable
+ sensible feedback to the user while gas is being built.
+
+Fri Sep 30 16:23:31 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (DISTSTUFF): New variable, listing only make-gas.com
+ for now.
+ (diststuff): New target; builds DISTSTUFF.
+ (realclean): Separate target, depend on clean and distclean, then
+ delete DISTSTUFF.
+ * make-gas.com: Deleted.
+
+ * config/tc-i386.c (i386_validate_fix) [BFD_ASSEMBLER]: New
+ function. Converts reloc for "foo-GOT" to BFD_RELOC_386_GOTOFF
+ reloc for "foo".
+ (i386_operand): Don't look up section symbol for
+ undefined_section.
+ (reloc): Always permit return of 8- and 16-bit relocation types.
+ Add a space after "pc-relative" in the error message.
+ (tc_i386_fix_adjustable) [BFD_ASSEMBLER]: Reject
+ BFD_RELOC_386_GOTOFF relocs.
+ (i386_operand): For any GOTOFF reloc, convert it to a BFD_RELOC_32
+ with a "foo-GOT" value.
+ * config/tc-i386.h (i386_validate_fix): Declare it.
+ (TC_VALIDATE_FIX): New macro -- call it.
+ (NOP_OPCODE): Cast to `char' to avoid compiler warnings.
+
+ * as.h: If __STDC__ is not defined and varargs.h is available, use
+ it rather than stdarg.h.
+
+ * write.h (struct fix): Added new bitfield fx_plt, for fixups
+ referring to PLT entries.
+ * write.c (fix_new_internal): Initialize fx_plt to zero.
+ (adjust_reloc_syms): Re-fetch `sym' after top of reduction loop.
+ Don't adjust fx_offset by frag address, since S_GET_VALUE now
+ includes the frag address.
+ (fixup_segment): Changed local var PCREL to type int, added PLT.
+ If PC-relative fixup refers to a PLT entry for a symbol in the
+ current section, don't reduce it.
+
+ * write.c (adjust_reloc_syms): Exit loop through a label. If
+ DEBUG5 is defined, print out each fixup before and after
+ processing.
+ (fixup_segment): If DEBUG5 is defined, print out each fixup before
+ and after processing.
+ (print_fixup): Added prototype. Show address on first line. Show
+ fx_offset and fx_subsy. [!BFD_ASSEMBLER]: Only show fx_r_type if
+ NEED_FX_R_TYPE is defined.
+
+ * symbols.c (print_symbol_value_1): Check S_IS_LOCAL, S_IS_EXTERN,
+ S_IS_DEBUG, S_IS_DEFINED also.
+
+Thu Sep 29 18:57:06 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (all): Depend on .gdbinit.
+ (.gdbinit): Rebuild from gdbinit.in by running config.status.
+
+ * gdbinit.in: Define new function "pf". Fix doc on "pe" and "ps".
+
+ * write.c (print_fixup): Print source location on first line.
+ Show fx_r_type and fx_addsy fields.
+
+Wed Sep 28 14:56:39 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Set bfd_gas for all sparc targets in one place,
+ instead of separately for each. Correctly handle user-supplied
+ "--enable-bfd-gas" option.
+
+ * gdbinit.in: Move "break abort" to end, in case gdb complains.
+
+ * as.h (PRINTF_WHERE_LIKE, PRINT_LIKE) [USE_STDARG, !__GNUC__]:
+ Use PARAMS macro.
+
+ * symbols.c (resolve_symbol_value, case O_symbol): Don't do any
+ processing if add_symbol is undefined or in expr_section.
+ (resolve_symbol_value, case O_add): For symbol plus
+ constant-valued symbol, convert to O_symbol and re-reduce.
+ (S_GET_VALUE): If symbol needs resolving, resolve it.
+ (indent_level): No longer static.
+ (print_symbol_value_1): Don't print frag address if it matches
+ zero_address_frag. Don't print "resolving" if already resolved.
+ Print segment name. Don't call print_expr_1 on an undefined
+ symbol.
+ (print_expr_1): Fix whitespace before printing X_add_number.
+
+ * expr.c (make_expr_symbol): No longer static. Use symbol_create,
+ not symbol_new, for symbols holding expression values.
+ * expr.h (make_expr_symbol): Move declaration here.
+ * write.c (fix_new_exp): Handle O_add by creating an
+ expression-valued symbol, and calling fix_new_exp recursively.
+ (adjust_reloc_syms): If a fixup's symbol value is a sum of an
+ undefined symbol and a constant, fold the constant into the fixup,
+ and refer to the undefined symbol directly. Then process the
+ fixup again from scratch.
+ (write_object_file): Before calling adjust_reloc_syms, make a pass
+ through the symbol list trying to resolve values.
+
+ * write.c (print_fixup): New routine, for debugging.
+ (write_relocs): Call bfd_install_relocation. Deleted various
+ hacks for working around problems with bfd_perform_relocation.
+
+ * Makefile.in (VERSION): Update to 2.4.90.
+
+Wed Sep 28 11:50:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (gasp.o): Depends upon config.h.
+
+ * config/tc-mips.c: Include subsegs.h.
+ (md_apply_fix): If an unconditional b or bal overflows, and we are
+ not assembling PIC code, replace it with a j or jal.
+
+ * config/tc-mips.c (md_apply_fix): Correct branch overflow test.
+ Use as_bad_where and as_warn_where rather than as_bad and as_warn.
+
+Mon Sep 26 17:15:59 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * write.c (write_relocs): Add file name and line number to
+ as_fatal calls. Handle bfd_reloc_overflow case specifically when
+ RELOC_EXPANSION_POSSIBLE.
+
+Fri Sep 23 16:11:28 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * as.h (USE_STDARG, USE_VARARGS): Define one or neither of these
+ here. Use them for deciding which PRINTF*LIKE macro definitions
+ to use.
+ * messages.c: Use them, instead of NO_STDARG, NO_VARARGS.
+ [!USE_STDARG && !USE_VARARGS] (va_alist, va_dcl, ...): Provide
+ default definitions matching what we were doing before.
+ (as_tsktsk): Remove the non-stdarg, non-varargs version, and
+ always use the varargs form if not using stdarg. It's safe to
+ always use vfprintf, because libiberty will provide it if the
+ native system doesn't. Also, always make format be const.
+ (as_warn, as_warn_where, as_bad, as_bad_where, as_fatal): Ditto.
+
+Fri Sep 23 14:42:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (load_register): Always use addiu when adding a
+ constant to $zero--no need to use daddiu.
+ (macro): Hack the -mips3 overflow tests to not fail when offsetT
+ is only 32 bits.
+
+ * symbols.h (copy_symbol_attributes): Declare.
+
+Thu Sep 22 21:58:24 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * listing.c: Bugfixes based in part on patches from Paul
+ Kranenburg.
+ (listing_newline): Check filename as well as line number when
+ deciding whether to record it.
+ (list_symbol_table) [S_IS_REGISTER]: Check that S_IS_REGISTER is
+ false (if defined) as well as checking for reg_section.
+ (listing_listing): Iterate fetching lines while line number is too
+ low, and we haven't run off the end of the input file.
+
+ * config/vms-conf.h: Changed HAVE_DELETE to HAVE_REMOVE.
+
+Thu Sep 22 13:39:10 1994 Kung Hsu (kung@x1.cygnus.com)
+
+ * ecoff.c (ecoff_generate_asm_lineno): check if
+ current_stabs_filename is NULL before strcmp.
+ * read.c (read_a_source_file): fix a bug in generate_asm_lineno
+ checking.
+
+Wed Sep 21 18:17:35 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * config/ho-*.h: Now-unused files deleted.
+
+ * symbols.c (copy_symbol_attributes): New function. Copies BFD
+ symbol flags and calls OBJ_COPY_SYMBOL_ATTRIBUTES.
+ (resolve_symbol_value, case O_symbol): Call it, if X_add_number is
+ zero. Don't call obj_frob_forward_symbol.
+ * read.c (pseudo_set): Call copy_symbol_attributes, but only if
+ X_add_number is zero.
+ * config/obj-elf.h (obj_frob_forward_symbol): Deleted.
+
+ * config/tc-i960.c: Lots of whitespace, comment reformatting,
+ using GNU indent.
+ (strchr): Don't declare.
+ [BFD_ASSEMBLER]: Don't compile md_convert_frag,
+ md_estimate_size_before_relax, md_ri_to_chars,
+ md_create_short_jump, md_create_long_jump.
+ (brtab_emit): Use data_section, not SEG_DATA.
+
+ Mon Sep 19 17:14:44 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/vms-conf.h: new file, manually derived from conf.in.
+ * config-gas.com: use it, and eliminate obsolete "host.h".
+
+Wed Sep 21 11:11:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-ppc.c (ppc_current_block): New static variable.
+ (ppc_stabx): Set sy_tc.within of a C_STSYM symbol to
+ ppc_current_block. Don't move around any stab symbol, just those
+ for common symbols.
+ (ppc_bs): Set ppc_current_block.
+ (ppc_es): Clear ppc_current_block.
+ (ppc_frob_symbol): Set the value of a C_STSYM symbol to the offset
+ from the csect of the enclosing block.
+
+ * config/tc-mips.c (insns_since_cache_access): Remove.
+ (append_insn): Remove setting of insns_since_cache_access, and
+ special 4600 handling; it turns out not to be required.
+
+Tue Sep 20 16:13:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (md_shortopts): Remove E.
+ (md_longopts): Add EB and EL.
+ (md_parse_option): Handle -EB and -EL as separate options, rather
+ than as a single -E option with an argument.
+
+Mon Sep 19 12:42:05 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Reject reductions
+ involving global symbols too.
+
+Mon Sep 19 12:12:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * as.h: Test NEED_DECLARATION_*, not NEED_*_DECLARATION.
+
+ * configure.in: Test for remove, not delete. Fix cross-assembler
+ test.
+ * as.h: Test HAVE_REMOVE, not HAVE_DELETE; define unlink to
+ remove, not delete.
+
+ * read.c (pseudo_set, case O_symbol): If
+ OBJ_COPY_SYMBOL_ATTRIBUTES is defined, invoke it.
+ [BFD_ASSEMBLER]: Copy BSF_FUNCTION setting too.
+ * config/obj-elf.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Define.
+
+ Wed Aug 10 19:15:30 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (DSG_S_C_UBITU, DST_K_VFLAGS_DSC, DST_K_TS_ATOM,
+ many others): new macros; values obtained from "DSTRECRDS.SDL".
+ * config/obj-vms.h (various): use them.
+ (USE_BITSTRING_DESCRIPTOR): new macro, for selecting bitfield
+ representation (only enum bitfields can avoid being bitstrings).
+ (bitfield_suffix, setup_basic_type): new routines.
+ (VMS_typedef_parse): use them. Now recognize bitfields of all
+ integral types, not just type `int'. Caveat: the representation
+ used for bitfields still does not work for objects placed in
+ registers, and gcc's optimizer sometimes puts small structs there.
+
+ Tue Jun 14 17:31:44 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * read.c (s_text) [#if OBJ_VMS]: clear the IN_DEFAULT_SECTION
+ bit from const_flag.
+ * config/obj-vms.h (IN_DEFAULT_SECTION): define this macro.
+ (tc_frob_label): define this to call vms_check_for_special_label,
+ and declare the latter.
+ * config/obj-vms.c (vax_g_doubles): declare this file-scope
+ variable.
+ (const_flag): initialize to IN_DEFAULT_SECTION instead of 0.
+ (vms_check_for_special_label): new routine (tc_frob_label).
+ (VMS_TBT_Routine_End): don't bother checking for `gcc_compiled.'
+ and `gcc2_compiled.' labels; they won't reach here any more.
+ (VMS_typedef_parse) [case 'r']: for types `double' and `complex
+ double', use `vax_g_doubles' flag to select type of double.
+ (VMS_write_object_file) [traceback setup]: don't pass symbols
+ with the IN_DEFAULT_SECTION attribute to the TBT_Routine_Begin
+ and TBT_Routine_End functions.
+
+ Mon Jun 6 20:52:20 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (VMS_TBT_Routine_End): cache the result of
+ S_GET_VALUE() to avoid many repeated function calls.
+ (VMS_Check_For_Main) [#if HACK_DEC_C_STARTUP]: capitalize
+ _C$MAIN_ARGS in advance, in case -h3 (leave symbol name as-is)
+ gets requested. [All the HACK_DEC_C_STARTUP code appears to
+ be obsolete; gcc does it automatically for vms target. It's
+ also misnamed, because it is for the "VAX C" run-time library,
+ not the newer "DEC C" one which has much different startup code.]
+ {various}: use `S_SET_xxx(symbol,new_value)' rather than
+ `S_GET_xxx(symbol) = new_value'.
+
+Mon Sep 19 12:05:03 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (c_dot_file_symbol): Use bfd_abs_section_ptr,
+ not &bfd_abs_section.
+
+Thu Sep 15 18:36:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * expr.c (clean_up_expression): Use addressT, not bfd_vma.
+
+Tue Sep 13 20:05:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * expr.c (expr): Don't reduce the difference of two symbols in the
+ same frag if the symbols are not in normal sections.
+
+ * config/obj-som.h (S_SET_OTHER, S_SET_TYPE): Delete a.out crud.
+ (S_SET_DESC, S_GET_OTHER, S_GET_TYPE, S_GET_DESC): Likewise.
+ (obj_attach_unwind_info): Do not define. Not needed anymore.
+ * config/tc-hppa.c: Delete whitespace at EOL.
+ (struct hppa_fix_struct): Delete fx_unwind field and all references.
+ (fix_new_hppa): Last arg is now a pointer to an int. Do not
+ call obj_attach_unwind_info anymore. For SOM R_ENTRY and R_EXIT
+ fixups, store 32bits of unwind information in the fx_addnumber
+ field of the fixup.
+ (md_assemble, pa_entry, process_exit, pa_procend): For SOM R_ENTRY
+ and R_EXIT fixups, pass a NULL pointer to fix_new_hppa, and a
+ pointer to 32 bits of unwind info.
+ (tc_gen_reloc): For SOM R_ENTRY and R_EXIT fixups, set the symbol
+ pointer to the dummy symbol; set the addend field to fx_addnumber.
+ (pa_comm, pa_equ, pa_type_args, pa_import): Use bfd_XXX_section_ptr
+ rather than &bfd_XXX_section.
+
+Tue Sep 13 21:15:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-i386.c (md_apply_fix_1): For GOTPC relocs, decrement
+ value by one; discard adjustments previously being made. From
+ Eric Youngdale.
+
+ VMS- and Vax-related changes from Pat Rankin:
+ * Makefile.in (VMS_OTHER_OBJS): add concat, getopt, and getopt1.
+ * vmsconf.sh: no longer have make-gas.com echo text about needing
+ to modify the gcc-vms driver when intending to use with gcc 1.x.
+ * as.c (parse_options): suppress 'v' from std_short_options and
+ eliminate VMS-specific conditional initialization;
+ [default case]: check for '-v' if md_parse_options doesn't recognize
+ an option;
+ [default case, #if VMS]: check for filename argument when '-v' seen;
+ [case 'v']: delete.
+ * config/tc-vax.c (md_assemble): don't rely on `this_add_number'
+ for O_big literal operands (double floats and long long ints);
+ [VMS, md_shortopts]: add second colon after 'v';
+ (md_parse_options) [VMS, case 'v']: check for argument, so
+ caller can handle `-v' w/o arg.
+
+Tue Sep 13 16:45:08 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coff.c (do_relocs_for): If TC_KEEP_FX_OFFSET
+ is defined, put the tx_offset into the r_offset.
+ * config/tc-sh.c (line_comment_chars): Add #
+ (tc_reloc_mangle): Deleted.
+ * config/tc-sh.h (TC_KEEP_FX_OFFSET): Define.
+ (TC_RELOC_MANGLE): Delete.
+
+Tue Sep 13 16:20:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * flonum-konst.c: Change preprocessor tests of HO_VMS to just VMS.
+ * hex-value.c: Ditto.
+ * config/obj-vms.c: Ditto.
+
+ * config/tc-sparc.c (sparc_ip): Replace as_bad/exit sequence with
+ a call to as_fatal.
+ * config/tc-i860.c (i860_ip): Ditto.
+ * config/tc-hppa.c (pa_ip): Ditto.
+ * config/tc-alpha.c (alpha_ip): Ditto.
+ * as.c (parse_args): Ditto.
+
+ * config/tc-mips.c (mips_ip): Replace as_warn/exit sequence with a
+ call to as_fatal.
+
+ * write.c (write_contents): Use EXIT_FAILURE.
+ * output-file.c (output_file_create, output_file_close,
+ output_file_create, output_file_close): Ditto.
+ * messages.c (as_fatal): Ditto.
+ * config/obj-som.c (obj_som_version, obj_som_copyright): Ditto.
+ * config/obj-ieee.c (write_object_file): Ditto.
+ * config/obj-coff.c (write_object_file): Ditto.
+ * config/tc-vax.c (main): Use EXIT_SUCCESS.
+ * config/tc-m68k.c (main): Ditto.
+
+ * hash.c (main): Pass a value to exit().
+
+ * as.h (EXIT_SUCCESS, EXIT_FAILURE): Moved here.
+ * as.c: ...from here.
+ (parse_args): Use them always.
+ (main): Use exit rather than return.
+
+ * Makefile.in (*_FOR_TARGET, INSTALL_XFORM, install, uninstall):
+ Rewrite handling of program_transform_name.
+
+ * configure.in: Test for functions unlink and delete.
+ * as.h: If unlink isn't available but delete is, define unlink to
+ be delete.
+
+ Update for autoconf 1.118:
+ * gdbinit.in: New file, created from old .gdbinit.
+ * .gdbinit: Deleted.
+ * aclocal.m4 (GAS_GDBINIT): Deleted.
+ * configure.in: Don't use it. Instead, generate .gdbinit from
+ gdbinit.in. Don't substitute cpu_type, obj_format, emulation,
+ atof. Switched order of AC_LINK_FILES arguments. Use AC_PREREQ
+ to ensure that older versions of autoconf aren't used.
+ * Makefile.in: Added @configure_input@ line.
+ (configure): Deleted rule.
+
+Tue Sep 13 12:08:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (fixup_segment): After handling the difference
+ of two symbols from the same segment, set fx_subsy to NULL, to
+ satisfy existing TC_COUNT_RELOC macros.
+
+Tue Sep 13 01:47:08 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * aclocal.m4 (GAS_GDBINIT): New macro.
+ * configure.in: Use it.
+ * configure: Regenerated.
+
+Mon Sep 12 20:56:38 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ * .gdbinit (pe, ps): Define new commands.
+ * symbols.c (indent_level): New static variable.
+ (indent, print_expr_1, print_symbol_value_1, print_symbol_value,
+ print_expr): New functions.
+
+ * Makefile.in (config-stamp): Add a "this file generated by make"
+ message to config.h.
+
+ PIC implementation for i386-linux, based on code from Eric
+ Youngdale and Paul Kranenburg, with some work of my own:
+
+ * write.c (fixup_segment): Test TC_RELOC_RTSYM_LOC_FIXUP on fixup
+ before processing same-section pcrel relocations.
+ (TC_RELOC_RTSYM_LOC_FIXUP): Default to 1.
+
+ * expr.c (make_expr_symbol): If operator is O_symbol and
+ X_add_number is zero, just return the symbol. If operator is
+ O_constant, resolve the symbol's value before returning.
+ (operand): Permit use of "[]" for grouping.
+ (clean_up_expression): For difference of two symbols in the same
+ frag, add the difference of their offsets into X_add_number.
+ (expr): Reduce difference of two symbols in same frag to their
+ difference.
+
+ * config/tc-i386.c (TC_RELOC): New macro.
+ (struct _i386_insn): New field disp_reloc.
+ (GOT_symbol): New variable.
+ (operand_special_chars): Added square-brackets and at-sign.
+ (reloc) [BFD_ASSEMBLER]: Added new argument OTHER; if it is not
+ NO_RELOC, just return it.
+ (reloc) [! BFD_ASSEMBLER]: Add third argument to dummy macro.
+ (BFD_RELOC_386_PLT32, _GOT32, _GOTOFF) [! BFD_ASSEMBLER]: More
+ dummy macros.
+ (tc_i386_fix_adjustable): New function. Returns zero if symbol in
+ fixup is not local, to prevent relocations against externals from
+ being dropped.
+ (md_assemble): Initialize disp_reloc field to NO_RELOC. Pass
+ disp_reloc field to reloc() function, and use TC_RELOC to generate
+ value to pass to fix_new_exp.
+ (md_assemble): Change 32-bit reloc against GOT_symbol into a GOTPC
+ reloc.
+ (i386_operand): Initialize disp_reloc field to NO_RELOC. Handle
+ @GOTOFF, @PLT, @GOT operands. For GOTOFF relocations with local
+ symbols, force generation of the section symbol.
+ (md_estimate_size_before_relax): If GOT_symbol exists, decide
+ we're generating PIC code, and convert relocations against
+ undefined symbols from PCREL to PLT32.
+ (md_apply_fix_1) [OBJ_ELF]: Fix up values for dynamic-linking
+ relocs.
+ (md_undefined_symbol): Notice GLOBAL_OFFSET_TABLE_NAME and set
+ and return GOT_symbol if it matches.
+ (F, MAP): Move macro definitions outside function.
+ (tc_gen_reloc): Only switch on size and pcrel if code wasn't
+ already supplied as PLT32. GOT32, GOTOFF, or GOTPC. Convert
+ BFD_RELOC_32 using GOT_symbol into GOTPC.
+ * config/tc-i386.h (TC_RELOC, tc_fix_adjustable,
+ TC_RELOC_GLOBAL_OFFSET_TABLE, TC_RELOC_RTSYM_LOC_FIXUP): New
+ macros.
+ (NEED_FX_R_TYPE): Define.
+ (LOCAL_LABEL): Accept ".X" prefix too.
+ (GLOBAL_OFFSET_TABLE_NAME): Default to "_GLOBAL_OFFSET_TABLE_".
+
+Mon Sep 12 17:51:39 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_type): Rewrite to accept syntax
+ reportedly to be used on Irix 6.
+
+ * config/tc-mips.c (md_pseudo_table): Handle .globl and .global.
+ (s_mips_globl): New static function; needed for Irix 5 support.
+ * ecoff.c (ecoff_build_symbols): If BSF_FUNCTION is set for an
+ external symbol with no type, set the type to st_Proc rather than
+ st_Global. Don't set the index of an external st_Proc or
+ st_StaticProc symbol unless it is also a local symbol.
+
+ * read.c (read_a_source_file): The second argument to as_where is
+ unsigned int *, not int *.
+
+Thu Sep 8 17:18:24 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config/obj-ecoff.h : Change names to OBJ_GENERATE_ASM_LINENO,
+ and generate_asm_lineno.
+ * config/obj-elf.h : ditto.
+ * read.h : ditto.
+ * read.c (read_a_source_file): if no file when inst is read, set
+ generate_asm_lineno to true.
+ * ecoff.h : change name to generate_asm_lineno and add function
+ ecoff_no_current_file.
+ * ecoff.c : change name to generate_asm_lineno.
+ * ecoff.c (ecoff_generate_asm_lineno) : new function, to generate
+ ecoff style line for asm file.
+
+Thu Sep 8 19:43:49 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (size_section): Do an fprintf to stderr rather
+ than a printf.
+ (fixup_segment): Use as_bad_where rather than as_bad.
+
+Wed Sep 7 17:21:12 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-{h8300,sh}.[ch] (tc_coff_symbol_emit): Function doing
+ nothing becomes macro doing nothing.
+
+Wed Sep 7 19:10:09 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (Makefile): Depend on config.status.
+ (config.status): Run config.status from . instead of srcdir.
+
+ * config/tc-i386.c (tc_gen_reloc): Use bfd_get_reloc_code_name to
+ display the name of the relocation type that couldn't be handled.
+ * config/tc-sparc.c (tc_gen_reloc): Likewise.
+ * config/tc-alpha.c (tc_gen_reloc): Likewise. Deleted abort call
+ after call to as_fatal.
+
+ * configure.in (i386-*-linux*): Don't set bfd_gas.
+
+ * Makefile.in (CC_FOR_TARGET, NM_FOR_TARGET, OBJDUMP_FOR_TARGET,
+ install, uninstall): Don't use "brokensed" hack any more, the new
+ autoconf code should never let program_transform_name be empty.
+
+ Update for autoconf beta 1.112:
+ * aclocal.m4 (GAS_CHECK_DECL_NEEDED, GAS_WORKING_ASSERT): New
+ macros.
+ * configure.in: Use them. Use AC_ARG_PROGRAM (now provided by
+ autoconf) instead of my hacked-up AC_PROGRAM_TRANSFORM_NAME. Move
+ test for CROSS_COMPILE just before AC_FUNC_ALLOCA, and emit a
+ message to try to ease confusion about autoconf's
+ "cross-compiling" message.
+ * acconfig.h (NEED_DECLARATION_MALLOC, NEED_DECLARATION_FREE,
+ NEED_DECLARATION_ERRNO): Renamed from NEED_*_DECLARATION.
+ * configure, conf.in: Regenerated.
+
+Wed Sep 7 12:49:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Check ${host} and ${target} rather than
+ ${host_canon} and ${target_canon}.
+ * configure: Likewise.
+
+Tue Sep 6 11:42:38 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (mips_cpu): New static variable.
+ (insns_since_cache_access): New static variable.
+ (md_begin): Set mips_cpu as well as mips_isa.
+ (append_insn): If mips_cpu is 4600, require four nop instructions
+ between an instruction which accesses the cache and certain CACHE
+ instructions. Keep track of the number of instructions seen since
+ an instruction which accesses the cache.
+ (md_parse_option): Set mips_cpu as well as mips_isa.
+
+Mon Sep 5 07:09:00 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * doc/Makefile.in (VPATH): Define using @srcdir@.
+ (prefix, program_transform_name, exec_prefix): Use autoconf style
+ @-substitutions.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * config/ho-riscix.h, config/tc-arm.c, config/tc-arm.h: New files
+ * configure.in: Recognize the arm.
+
+Fri Sep 2 16:05:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ecoff.c (add_file): Don't try to generate line numbers if the
+ symbol table has been frozen.
+
+Thu Sep 1 19:48:01 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * aclocal.m4 (AC_PROG_CC): Use AC_DEFUN, and omit AC_PROVIDE.
+
+ * configure.in: Handle user-specified bfd-assembler option with
+ separate variable from preferred configuration, until the two are
+ resolved. Indicate bfd_gas=preferred for linux a.out. Use
+ AC_PROGRAM_TRANSFORM_NAME, for which a patch has been sent to djm.
+ * Makefile.in (target_alias, program_transform_name): Define,
+ using autoconf @-substitutions.
+
+Wed Aug 31 17:43:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * atof-generic.c: Deleted alloca handling here.
+
+ * Makefile.in (prefix, exec_prefix): Use @-subtitutions.
+
+ * aclocal.m4 (AC_OUTPUT_LINKS): Deleted redefinition, since
+ autoconf 1.109 has this fixed.
+ * configure.in: Don't change quote characters around AC_MSG_ERROR
+ invocation. Don't use AC_HEADER_STDC, since it requires running a
+ program. Cache NEED_*_DECLARATION values.
+ * configure, conf.in: Regenerated with a modified autoconf 1.109.
+
+ * as.h (volatile): Don't test or define here; not needed.
+ (alloca): Replace alloca-conf.h inclusion with code recommended in
+ autoconf documentation. Include config.h first.
+
+Wed Aug 31 11:20:48 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.h (S_IS_DEFINED): Absolute symbols are defined
+ also.
+
+ * configure.in, configure: Initialize bfd_gas to no.
+
+Tue Aug 30 19:31:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * as.h: Include alloca-conf.h from "libiberty", not
+ "../libiberty".
+
+Mon Aug 29 16:11:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-ppc.c (md_apply_fix): Don't generate a reloc when a
+ symbol is used as an offset into a CSECT that is not a TOC. These
+ types of loads are generated by gcc -mminimal-toc.
+
+Sun Aug 28 13:22:52 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * as.h (flag_*): Added comments describing meanings of some of
+ these variables.
+ (struct frag): Add some comments about the ns32k-specific fields
+ and why they're here.
+ (SIZEOF_STRUCT_FRAG): Cast addresses to char*, not int.
+ (flag_print_statistics): Declare.
+
+ * as.c (parse_args): Set flag_print_statistics instead of
+ statistics_flag. Options array is now const. Added new option
+ "dump-config"; if specified, print TARGET_ALIAS, TARGET_CANONICAL,
+ TARGET_CPU, TARGET_OBJ_FORMAT, and TARGET_FORMAT, if defined.
+ (main): Change test to check flag_print_statistics.
+ (statistics_flag): Deleted.
+
+ * frags.c (frag_variant): Removed PCREL_ADJUST and BSR arguments.
+ Always initialize them to zero.
+ * frags.h (frag_variant): Fixed prototype.
+ * config/tc-i960.c (get_cdisp): Don't pass the extra zero args.
+ * config/tc-ns32k.c (convert_iif): Don't pass the arguments; cache
+ the value of frag_now and fill in the fields later.
+
+ * Makefile.in (distclean, realclean): Remove new
+ configure-generated files.
+
+Sat Aug 27 20:26:12 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ Conversion to autoconf:
+ * acconfig.h, aclocal.m4: New files.
+ * configure.in: Rewritten (except for some target-specific code)
+ for autoconf.
+ * conf.in, configure: New files, generated from the above.
+ * Makefile.in: Changed magic sequence indicating insertion of
+ makefile fragments.
+ (VPATH, srcdir, CC, LIBS, OBJS dependencies): Use @-substitutions
+ from configure.
+ (LINKED_HEADERS): Deleted a.out.gnu.h, a.out.h, and host.h.
+ (config.status, configure): Rewrite rules.
+ (config-stamp): Depend on conf. Skip variables that configure is
+ now substituting itself.
+ (*.o dependencies): Deleted host.h.
+ (distclean, realclean): Don't delete host.h.
+ * as.c: Don't include stdio.h, string.h, sys/types.h. Include
+ signal.h after as.h.
+ * as.h: Include alloca-conf.h first. Include ctype.h, string.h,
+ strings.h, stdlib.h, unistd.h, sys/types.h, fopen-bin.h,
+ fopen-same.h, as suggested by autoconf test results.
+ [BROKEN_ASSERT]: Don't include assert.h.
+ (strdup): Declare.
+ (volatile, const): Define if not __STDC__ and not already defined.
+ (malloc, realloc) [NEED_MALLOC_DECLARATION]: Declare.
+ (free) [NEED_FREE_DECLARATION]: Declare.
+ * gasp.c: Include config.h, stdlib.h (if HAVE_STDLIB_H). Don't
+ include host.h.
+ (malloc) [NEED_MALLOC_DECLARATION]: Declare.
+ * messages.c: Include as.h first. Include errno.h only if
+ HAVE_ERRNO_H. If HAVE_VARARGS_H and not __STDC__, undefine
+ HAVE_STDARG_H. Set NO_STDARG and NO_VARARGS as appropriate.
+ * doc/Makefile.in (srcdir, INSTALL, INSTALL_PROGRAM,
+ INSTALL_DATA): Use autoconf @-substitutions.
+
+ * input-file.c: Don't include assert.h here, 'cause as.h already
+ includes it.
+
+ * config/tc-alpha.c: Added various prototypes for static
+ functions.
+ (in_range): New function, tests whether a value can fit in an
+ N-bit field.
+ (build_mem, build_operate_n): New functions for constructing
+ opcode values.
+ (emit_sll_n, emit_ldah_num, emit_addq_r, emit_lda_n): New
+ functions for emitting single instructions, no longer requiring a
+ recursive call to md_assemble.
+ (emit_add64): New function for expanding a REG:=REG+CONST
+ operation into one or more instructions, to handle wide constants.
+ (clear_insn): New variable.
+ (md_begin): Fill it in with zeros and BFD_RELOC_NONE values.
+ (alpha_ip): Use it to initialize local variable insns.
+ (alpha_ip, label "immediate" and cases 'P', 'G'): Use emit_add64
+ for calculations.
+
+Fri Aug 26 14:46:15 1994 Ken Raeburn (raeburn@kr-laptop.cygnus.com)
+
+ * subsegs.c (section_symbol): Reverse still-wrong test of
+ EMIT_SECTION_SYMBOLS.
+
+ * write.c (BFD_FAST_SECTION_FILL): Always define.
+ (write_contents): If fill_size is 1, use memset instead of looping
+ calling memcpy.
+
+Wed Aug 24 12:46:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.h (LOCAL_LABEL): Define as 0, for compatibility
+ with native MIPS assembler.
+ * configure.in (mips-*-irix*): Don't set emulation.
+ * config/te-irix.h: Remove.
+
+ * ecoff.c (ecoff_symbol_new_hook): Don't add a new file if we
+ haven't seen any input files yet.
+ * config/tc-alpha.c (md_begin): Just call symbol_create, rather
+ than calling symbol_new and then removing the symbol from the
+ list.
+
+ * as.c (main): Move a inside the #if 0 block which uses it.
+ * ecoff.c (current_stabs_filename): Make const.
+ * frags.h (frag_align_pattern): Declare.
+ * gasp.c (new_file): Cast isp to long, and use %ld to print it.
+ * config/tc-alpha.h (md_operand): Add cast to void.
+ (alpha_do_align): Declare argument types.
+ (tc_get_register): Declare.
+ (alpha_frob_ecoff_data): Declare.
+ * config/tc-alpha.c: Include <ctype.h>.
+ (s_mask): Don't declare; does not exist.
+ (line_comment_chars): Remove /* from descriptive comment.
+ (tc_get_register): Remove unused local reg.
+ (tc_gen_reloc): Don't bother to compare unsigned to zero.
+ (s_base): Correct warning to actually print register number.
+ (md_begin): Remove unused locals retval, lose, and i.
+ (alpha_fix_adjustable): Move default case inside switch to avoid
+ warning.
+ (load_symbol_address): Remove unused locals reloc_addr, p, sym,
+ and addend.
+ (emit_byte_manip_r): Declare types for all arguments.
+ (emit_extract_r, emit_insert_r, emit_mask_r): Likewise.
+ (emit_sign_extend, emit_bis_r, s_proc): Likewise.
+ (alpha_ip): Use sprint_value to print offsetT value. Remove
+ unused local size. Remove unused label get_macro.
+ (alpha_do_align): Make fill const.
+ (md_apply_fix): Remove unused label check_zov.
+
+ * configure.in: Recognize i586 as a synonym for i[34]86.
+
+Tue Aug 23 12:32:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-coff.c (c_line_new): Change line_number argument from
+ unsigned short to int so that the type in the prototype matches
+ the promoted type in the definition.
+ (stack_delete): Comment out; not used.
+ * config/obj-coff.h (tc_coff_symbol_emit_hook): Declare if not
+ BFD_ASSEMBLER, not if BFD_ASSEMBLER. Declare argument type.
+ * config/tc-m68k.h (tc_coff_sizemachdep): Declare.
+ * config/tc-m68k.c (tc_coff_symbol_emit_hook): Add ignored
+ argument.
+
+Tue Aug 16 01:48:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/config/tc-hppa.c (pa_comm): Undo last change. Set sy_frag for
+ the common symbol to the zero address frag (the correct fix).
+
+Tue Aug 16 01:48:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/config/tc-hppa.c (pa_comm): Undo last change. Set sy_frag for
+ the common symbol to the zero address frag (the correct fix).
+
+ * config/tc-hppa.c (pa_comm): Set sy_resolved for the common
+ symbol.
+
+Fri Aug 12 17:51:48 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (md_begin): Drop "el" from the end of
+ TARGET_CPU. Check for mips64orion.
+
+Tue Aug 9 19:43:45 1994 Stu Grossman (grossman@cygnus.com)
+
+ * configure.in: Recognize ppc-*-netware.
+ * config/te-ppcnw.h: New file to support Power-PC/Netware
+ configurations. Currently, it just enables the use of backslash
+ escapes in string directives.
+
+Tue Aug 9 11:12:13 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-ppc.c (ppc_stabx): Call expression directly, rather
+ than via pseudo_set. If expression is a symbol, move stab symbol
+ to just after symbol from expression.
+
+ * ecoff.c (ecoff_build_procs): Don't force adr of first fdr to be
+ zero. Undoes change of June 4, 1993.
+
+ * config/tc-mips.c (md_parse_option): Accept -mcpu=4400, 4600, and
+ orion.
+
+Mon Aug 8 16:28:08 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * as.h: Remove FOPEN_WB patch of Aug 6.
+ * configure.in: Configure for ho-go32 correctly.
+ * config/ho-go32.h: Fix copyright.
+
+Mon Aug 8 11:59:51 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/config/tc-hppa.c (md_pseudo_table): Delete redundant
+ upper-case versions of the pseudo-ops.
+
+Mon Aug 8 13:42:16 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix): If we are going to generate a
+ non PC relative reloc, don't put the addend in the object file.
+
+Sat Aug 6 01:15:02 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * as.h: If FOPEN_WB is not defined, do the right thing in a go32
+ environment.
+
+Mon Jul 11 11:34:52 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-h8300.c (pint): New function for handling varying
+ size of int pseudo op.
+ * doc/as.texinfo: Fix typo describing .h8300h pseduop.
+
+Mon Aug 1 02:40:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (create_new_space): Initialize sd_subspaces
+ field in the space chain.
+
+ * config/tc-hppa.c (tc_gen_reloc): Cast return value from
+ hppa_gen_reloc_type.
+
+Thu Jul 28 15:45:37 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Check more carefully for
+ conflicting architectures.
+ (md_parse_option) [NO_V9]: Complain if v9 was selected.
+ (md_show_usage): Derive architecture list in usage message from
+ architecture_pname array.
+ (cypress): Macro deleted.
+ (op_hash): Don't initialize.
+ (s_common): Use bfd_und_section_ptr instead of bfd_und_section.
+
+ * config/tc-sparc.c (BSR): New function.
+ (sparc_ip): Use it for right-shift operations of 32 bits or more.
+
+ * config/tc-sparc.c (sparc_ip): Implement new operand type 'x'.
+
+Tue Jul 26 18:21:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h: Moved common includes and TARGET_FORMAT
+ definitions together.
+ (WORKING_DOT_WORD, WARN_SIGNED_OVERFLOW_WORD,
+ OBJ_COFF_OMIT_OPTIONAL_HEADER, BFD_HEADERS, BFD) [!BFD_ASSEMBLER]:
+ Moved these definitions to the start of the file, before the
+ includes.
+ (SYMBOLS_NEED_BACKPOINTERS, OBJ_COFF_MAX_AUXENTRIES): Always
+ define these.
+ (S_GET_ZEROES): Deleted.
+ (S_SET_ZEROES): Moved to obj-coff.c.
+
+ * config/obj-coff.c (obj_coff_* psuedo-op fns): Deleted
+ forward declarations.
+ (obj_pseudo_table): Moved to one version end of file,
+ conditionalized internally.
+ (stack typedef, stack_init, stack_delete, stack_push, stack_pop,
+ tag_hash, tag_init, tag_insert, tag_find, tag_find_or_make): Moved
+ to one combined version at top of file, unconditional. Deleted
+ forward declarations.
+ (s_get_name): Moved one copy of declarations to start of file.
+ (def_symbol_in_progress): Ditto. Don't initialize.
+ (S_SET_ZEROES): Moved here from obj-coff.h.
+ (write_object_file): If TC_COFF_SET_MACHINE is defined, call it on
+ the file headers.
+
+ * config/obj-coff.c (seg_info_off_by_4): Now const and static.
+ (SEG_INFO_FROM_SEG_NUMBER): Unused macro deleted.
+ (previous_file_symbol, def_symbol_in_progress, symbol_externP,
+ symbol_extern_lastP, last_functionP) [!BFD_ASSEMBLER]: Don't
+ bother explicitly initializing to zero value.
+
+ * config/obj-coff.c (fixup_segment) [TC_I960]: Use SF_GET_BALNAME
+ and SF_GET_CALLNAME instead of the TC_S_IS_ versions.
+
+ * config/tc-i960.h (TC_COFF_SET_MACHINE): New macro. Calls
+ tc_headers_hook.
+
+ * config/tc-i960.c (targ_has_iclass): Use I_CX | I_CX2 where I_CX
+ was used previously.
+ (tc_headers_hook): If I_CX2 is found, set flags to F_I960CA.
+
+ * config/tc-i960.c (po_hash): Declaration deleted.
+ (next_object_file_charP): Ditto.
+ (regnames, aregs, coj): Now const.
+ (parse_memop): Static array def_scale now const.
+ (md_begin): Cast away const when passing hash routines addresses
+ of values in regnames or aregs.
+ (md_longopts): Added "link-relax" and "no-relax" hyphenated forms.
+ Continue to accept one-word forms.
+ (struct tabentry, arch_tab): Moved to top level from inside
+ md_parse_option. Now const.
+ (md_show_usage): Use arch_tab to generate usage message. Print
+ hyphenated forms of relax options.
+
+ * config/tc-i960.h (DEFINE_I960_AOUT, TC_S_IS_*, TC_S_*_SYSPROC,
+ TC_S_FORCE_TO_*): Moved from here...
+ * config/tc-i960.c: ... to here. Changed DEFINE_I960_AOUT stuff
+ to test OBJ_AOUT and OBJ_BOUT directly.
+
+ * config/tc-i960.h (CTRL, COBR, COJ, REG, MEM*, FBRA, CALLJ,
+ M1-M3, REG_OPC, R_*, SFR, LIT, FP, OP, R, RS, RL, RSL, F,
+ {R,F}{,L}{2,4}, M, SFR_OK, LIT_OK, FP_OK, REG_ALIGN, MEMOP, I_*):
+ Macros deleted.
+
+ * config/tc-i960.c (ARCH_JX): Define.
+ (arch_tab): Include JX.
+ (targ_has_sfr, targ_has_iclass): Handle JX.
+ (tc_headers_hook): Set flags to F_I960JX for i960JX.
+
+Fri Jul 15 15:36:51 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * subsegs.c (section_symbol): Had last change backwards.
+
+Thu Jul 14 13:21:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/atof-ns32k.c: Deleted.
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Use
+ bfd_ind_section_ptr and bfd_und_section_ptr.
+
+ * subsegs.c (subseg_set_rest): Compare segT values directly,
+ without casting to int first.
+
+ * config/tc-ns32k.c (md_begin): Return value from hash_insert
+ should be pointer to const. Don't call exit explicitly after
+ calling as_fatal; it won't return.
+ (convert_iif): Make local variable j be pointer to bit_fixS, since
+ that's how it's used.
+ (encode_operand, case 'b'): Ignore sprintf return value. Don't try
+ converting freeptr to int and back.
+
+ Merged in NS32K support update from Ian Dall (dall@hfrd.dsto.gov.au):
+
+ * config/te-pc532mach.h: New file. pc532-mach target emulation.
+
+ * config/te-netbsd532.h: New file. Netbsd532 target emulation.
+
+ * config/tc-ns32k.h: Add definition of NOP_OPCODE.
+
+ * config/tc-ns32k.h: Add prototype for fix_new_ns32k_exp.
+
+ * config/tc-ns32k.h: Add BFD_ASSEMBLER support.
+
+ * config/tc-ns32k.c (tc_gen_reloc): New function for BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (fix_new_ns32k_exp): Get reloc type
+ differently for BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (md_estimate_size_before_relax): Get reloc
+ type differently for BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (md_create_long_jump): Size of opcode is one
+ not 2.
+
+ * config/tc-ns32k.c (md_convert_frag): Code for the BFD_ASSEMBLER
+ case. Also use smart md_pcrel_adjust function.
+
+ * config/tc-ns32k.c (md_apply_fix): Code for the BFD_ASSEMBLER
+ case. Also use smart md_fix_pcrel_adjust function.
+
+ * config/tc-ns32k.c (md_fix_pcrel_adjust): New function which can
+ find offset from opcode to operand even if in another frag
+ and in the presence of relaxing.
+
+ * config/tc-ns32k.c (md_pcrel_adjust): New function which can
+ find offset from opcode to operand even if in another frag
+ and in the presence of relaxing.
+
+ * config/tc-ns32k.c (md_number_to_disp): Check ranges properly.
+
+ * config/tc-ns32k.c (md_atof): use atof_ieee instead of special
+ atof_ns32k.
+
+ * config/tc-ns32k.c (reloc): New (static) function for
+ BFD_ASSEMBLER.
+
+ * config/tc-ns32k.c (convert_iif): More correct pc relative code.
+ md_relax must be able to find opcode address even if in another frag.
+
+ * config/tc-ns32k.c: More extensive comments.
+
+ * config/tc-ns32k.c (encode_operand): Support new operand classes I
+ and Z. Drop Q.
+
+ * config/tc-ns32k.c (fix_new_ns32k_exp): new function and
+ corresponding prototype.
+
+ * config/tc-ns32k.c: make 32532 default machine instead of 32032.
+
+ * config/tc-ns32k.c: include opcode/ns32k.h after as.h
+
+ * aout_gnu.h: r_disp needs to be 2 bits for TC_NS32K
+
+ * write.h: fx_im_disp needs to be 2 bits big for TC_NS32K
+
+ * write.c (relax_segment): Use TC_PCREL_ADJUST macro (if defined)
+ instead of adding pcrel_adjust.
+
+ * write.c (write_object_file): Adjust to_addr for the
+ BROKEN_DOT_WORD feature for the BFD_ASSEMBLER case.
+
+ * write.c (write_object_file): Use TC_CONS_FIX_NEW if it is defined.
+
+ * write.c (write_contents): Add code (currently if
+ BFD_FAST_SECTION_FILL is defined) to make large fills a lot faster.
+
+ * configure.in: Remove ns32k from special FP list. All the ns32k
+ series use ieee float.
+
+ * configure.in: Add ns32k-pc532-mach and ns32k-pc532-netbsd targets
+
+ * as.h: include expr.h before targ-env.h. Some target dependent file
+ want to use expr structures.
+
+Wed Jul 13 14:49:05 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): Change rp to be a const pointer.
+ (md_parse_option): Clear cpu field of current_architecture before
+ setting a new cpu type. Clear no_68881 for m68881 or m68882.
+ Clear no_68851 for m68851.
+
+Tue Jul 12 21:27:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/ho-sysv.h (realloc): Declare.
+
+ * symbols.c (symbol_create): New function, most of the guts of the
+ old symbol_new function.
+ (symbol_new): Now just checks symbol_table_frozen, calls
+ symbol_create, and enters the symbol into the symbol table.
+ * subsegs.c (section_symbol): If EMIT_SECTION_SYMBOLS is not true,
+ and the symbol table is frozen, call symbol_create instead of
+ symbol_new.
+ * symbols.h (symbol_create, symbol_table_frozen): Declare.
+
+ * symbols.c (symbol_clear_list_pointers): Always a function now.
+ * struc-symbol.h (symbol_clear_list_pointers): Deleted macro
+ version.
+
+ * symbols.c (debug_verify_symchain): New macro, defined to be
+ verify_symbol_chain or a cast to void, depending on DEBUG_SYMS.
+ (many functions): Invoke debug_verify_symchain unconditionally.
+
+Tue Jul 12 12:06:42 1994 Kung Hsu (kung@x1.cygnus.com)
+
+ * config/obj-ecoff.h: change calling interface of
+ OBJ_GENERATE_ASM_LINE_STAB.
+ * config/obj-elf.h: ditto.
+ * read.c (read_a_source_file): ditto.
+ * ecoff.h: change calling interface of
+ ecoff_generate_asm_line_stab.
+ * ecoff.c (add_file): record of filename to handle case of include
+ files, also change default built-in type from int to void for
+ asm file.
+ * ecoff.c (ecoff_generate_asm_line_stab): handle case of include
+ files.
+
+Mon Jul 11 17:20:23 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (macro): In case M_LA_AB, SVR4_PIC, large
+ constant, and case ldd_std, set mips_optimize to 2 temporarily to
+ avoid inserting an unexpected nop instruction.
+
+Sat Jul 9 00:05:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_build_lineno): Handle count correctly for last
+ line number.
+
+Fri Jul 8 15:22:07 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * gasp.c (process_pseudo_op): Pass right args to do do_aif.
+ (get_any_string): New arg 'pretend_quote'.
+ (get_and_process, do_formals, macro_expand, do_sdata,
+ process_pseudo_op): Use new arg.
+
+Fri Jul 8 12:23:44 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * config/obj-ecoff.h: define macro OBJ_GENERATE_ASM_LINE_STAB.
+ * config/obj-elf.h: ditto.
+ * read.c (read_a_source_file): generate line stabs for asm file.
+ * read.h: add extern generate_asm_line_stab.
+ * ecoff.h : add prototype for ecoff_generate_asm_line_stab().
+ * ecoff.c (add_file): if there's no filename provided, set switch
+ to generate line stabs for .s file.
+ * ecoff.c (add_procedure): add stabs symbol for .ent directive.
+ * ecoff.c (generate_ecoff_stab): creates an artificial stabs.
+ * ecoff.c (generate_asm_line_stab): generate a artifitial label
+ for each line and generate a stabn for the line.
+
+Thu Jul 7 17:04:03 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * gasp.c (get_any_string): Cope with getting a string with an
+ alternate base specifier.
+ (do_aif, do_aelse): Only enable output if expression is true and previous
+ level was on.
+ (chartype_init): Add BASEBIT chartype.
+ (process_pseudo_op): Notice nesteed AIFs.
+
+Thu Jul 7 12:30:22 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * h8300.c (do_a_fix_imm): Code for 2 bit reloc type using in trapa
+ insn. (fix pr 5165, 5174)
+
+Thu Jul 7 11:31:32 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (R_DLT_REL): If it isn't defined, then define
+ to an appropriate value to avoid losing on old hpux systems.
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Reject reductions for
+ symbols in DLT relative relocs.
+ (tc_gen_reloc): Zero out the addend field for DLT relative relocs.
+
+Wed Jul 6 01:07:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ppc.c (ppc_tc): If not OBJ_COFF, force TOC entry to
+ align to a four byte boundary.
+
+Tue Jul 5 15:42:09 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (load_expression): Handle 32-bit addends.
+ (gpdisp_hi16_howto): Now points to const.
+ (load_insn_table, alpha_ip): Fix uses of const.
+
+ * doc/internals.texi: Updates to COFF description. Added "@end
+ defmac" as needed, and some extra heading and "@bye" so it'll
+ format as a separate document.
+
+Tue Jul 5 13:54:00 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/obj-elf.h (S_GET_ALIGN, S_SET_ALIGN): Define.
+ * config/obj-elf.c (obj_elf_common): Set alignment of common
+ symbol.
+ * config/tc-sparc.c (s_common): If OBJ_ELF, set alignment of
+ common symbol.
+
+Mon Jul 4 18:29:43 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (is_complex): New macro.
+ (cons_fix_new_hppa): "Handle" complex expressions.
+
+Fri Jul 1 00:48:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (write_object_file): Set s_align field from
+ section_alignment array.
+
+Thu Jun 30 15:05:28 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (write_object_file): Use bfd_com_section_ptr.
+ * as.h (absolute_section, undefined_section): Use new BFD macros
+ bfd_abs_section_ptr and bfd_und_section_ptr.
+
+Thu Jun 30 14:36:37 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (macro): For M_LI_SS, decide how to handle it
+ based on contents of imm_expr and offset_expr, rather than
+ mips_pic. For M_LI_DD, decide how to handle it based on segment
+ name of offset_expr, rather than mips_pic.
+ (mips_ip): If g_switch_value < 4, use immediate values for 'l'.
+ If g_switch_value < 8, use .rdata rather than .lit for 'L'.
+
+Wed Jun 29 17:30:46 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (show_usage): Break long string into shorter ones.
+ (parse_args): Add -v, prints version id and continues.
+ * config/tc-mips.c (md_show_usage): Break long string.
+
+Mon Jun 27 09:47:16 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * config/tc-i386.c (md_parse_option): Handle "-V" and "-Q" if
+ OBJ_ELF is defined.
+
+Sun Jun 26 16:30:48 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (main) [HOST_SPECIAL_INIT]: New hook, for host-specific
+ initialization.
+
+Wed Jun 22 00:24:55 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (obj_frob_symbol): Define for OBJ_ELF.
+ More gas/bfd lossage exposed by the new linker code.
+
+Tue Jun 21 11:32:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * subsegs.c (subseg_change): Clear seginfo after allocating it.
+ (subseg_get): Pass actual size of seginfo to memset.
+
+ * subsegs.c (abs_seg_info, und_seg_info): Define if BFD_ASSEMBLER.
+ (subseg_change): Store seg_info for bfd_abs_section_ptr in
+ abs_seg_info, and store seg_info for bfd_und_section_ptr in
+ und_seg_info.
+ (subseg_get): Likewise. Also, don't set output_section if it is
+ already set.
+ (seg_info): Define as function.
+ * subsegs.h (seg_info): Declare as function rather than defining
+ as macro.
+ * write.c (relax_and_size_seg): Call seg_info rather than
+ bfd_get_section_userdata.
+
+Mon Jun 20 16:30:54 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in (ppc-*-elf*): New target, like -sysv4*.
+
+ * expr.c (operand): If "0f" is followed by '\0', don't do eol
+ checks.
+
+Mon Jun 20 15:17:43 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ecoff.c (ecoff_build_aux): Call swap_tir_out and swap_rndx_out
+ via backend pointer, not directly.
+
+Fri Jun 17 18:05:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (config-stamp): Make sure there is at least one
+ element in the for loop.
+
+Fri Jun 17 11:01:04 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Misc trivial changes to make gcc -Wall happy.
+
+ * config/tc-hppa.h (elf_hppa_final_processing): Declare.
+
+Wed Jun 15 20:44:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * as.c (parse_args): Cast xmalloc return value.
+
+ * Makefile.in (config-stamp): If $(defs) contains multiple words,
+ emit a #define line for each.
+ * configure.in: For sparc64 target, use sparc cpu files and add
+ sparcv9 to extra_defs. No longer treat sparc64-*-aout* specially.
+
+ * config/tc-sparc.c (membar_masks): Now static and const.
+ (md_show_usage) [!NO_V9]: Add -Av9 to usage message.
+ (current_architecture) [sparcv9]: Initialize to v9.
+ (md_begin) [sparcv9]: Don't bother changing it unconditionally
+ here.
+ (s_reserve): Don't pass unexpected argument to as_bad with
+ bad-segment message.
+
+ * as.h (bfd_alloc_by_size_t) [BFD_ASSEMBLER]: Declare.
+
+ * config/atof-ieee.c (int_to_gen): Commented out unused routine.
+
+ * config/tc-vax.c (md_assemble): Removed check of operand section.
+
+ Fri Jun 3 17:25:08 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (DBG_S_C_COMPLX4, DBG_S_C_COMPLX8): define
+ these new VMS symbol-type macros for `complex float' and
+ `complex double' support. Their values come from the existing
+ DSC$K_DTYPE_FC and DSC$K_DTYPE_DC macros in <descrip.h>.
+ (DBG_S_C_REAL8_G, DBG_S_C_COMPLX8_G): G_float versions of
+ REAL8 and COMPLX8; not used yet, because gcc outputs the same
+ .stabs for `double' regardless of whether `-mg' is used.
+ * config/obj-vms.c (VMS_typedef_parse) [case 'r']: add entries
+ for gcc2's predefined types "complex float", "complex double",
+ and "complex long double" (identical to complex double).
+
+Wed Jun 15 12:32:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (coff_frob_symbol): Use C_STAT for the .text
+ section symbol, not C_LABEL.
+
+ * config/tc-mips.c (mips_ip): Permit a modifier in 'o' case, and
+ permit non constant expressions in 'u' case. Lets ``lui
+ $8,%hi(foo); lw $8,%lo(foo)($8)'' work correctly.
+
+Mon Jun 13 12:08:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Warn about an attempt
+ to put a common symbol in a set.
+
+Sat Jun 11 16:41:21 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add weak symbols as an extension to a.out.
+ * read.c (pseudo_set): Only preserve external bit for OBJ_AOUT and
+ OBJ_BOUT if not BFD_ASSEMBLER.
+ * config/aout_gnu.h (N_WEAKU, N_WEAKA, N_WEAKT, N_WEAKD, N_WEAKB):
+ Define as in ../include/aout/aout64.h.
+ * config/obj-aout.h (OBJ_SYMFIELD_TYPE): If not BFD_ASSEMBLER,
+ define as char.
+ (S_GET_WEAK, S_SET_WEAK): Define if not BFD_ASSEMBLER.
+ * config/obj-aout.c (obj_pseudo_table): Add "weak".
+ (obj_emit_symbols): Adjust type of weak symbols.
+ (obj_aout_weak): New static function.
+
+Fri Jun 10 13:48:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Don't set any flags based on
+ the type of a special section.
+
+ * config/ho-sunos.h: Include <stdlib.h>. Don't declare malloc,
+ realloc, free, or atol.
+
+Wed Jun 8 06:28:37 1994 Bill Cox (bill@cygnus.com)
+
+ * Makefile.in (check): Delete as.new dependency, so that
+ regression test doesn't trigger an assembler build.
+
+Tue Jun 7 13:33:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (mostlyclean, realclean): New targets.
+ * doc/Makefile.in, testsuite/Makefile.in: Likewise.
+
+Mon Jun 6 13:10:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (RDATA_SECTION_NAME): Define.
+ (macro): Correct M_LI_SS SVR4_PIC/EMBEDDED_PIC case. After M_LI_D
+ or M_L_DOB or label dob, force a new frag to avoid getting
+ confused in tc_gen_reloc.
+ (mips_ip): Use RDATA_SECTION_NAME, not .rdata.
+ (s_change_sec): Likewise.
+
+Fri Jun 3 23:35:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (emit_expr): Use memset to zero out memory, rather than
+ going through md_number_to_chars. This permits handling symbolic
+ arguments when the size is larger than sizeof (valueT), if
+ TC_CONS_FIX_NEW is prepared to handle the case (as it is on MIPS).
+
+Fri Jun 3 12:50:13 1994 David J. MacKenzie (djm@rtl.cygnus.com)
+
+ * as.c (show_usage), config/tc-alpha.c (md_show_usage),
+ config/tc-mips.c (md_show_usage): Fix up messages.
+
+ * as.h: Replace flagseen with separate variables.
+ * as.c (parse_args): Set them. Don't accept -1 option, or -v
+ explicitly (it's a synonym for --version).
+ * as.c, input-scrub.c, messages.c, read.c, symbols.c, write.c,
+ config/obj-aout.c, config/obj-aout.h, config/obj-bout.c,
+ config/obj-bout.h, config/obj-coff.c, config/obj-coff.h,
+ config/obj-vms.c, config/tc-hppa.c, config/tc-i386.c,
+ config/tc-i960.c, config/tc-m68k.c, config/tc-mips.c,
+ config/tc-vax.c: Use the new flag variables instead of flagseen.
+ * config/tc-vax.c [OBJ_VMS]: Recognize -+, -1, -v, and document in
+ usage.
+
+ * as.c (show_usage): Remove target specific messages;
+ instead, call md_show_usage.
+ (parse_args): Use getopt_long_only. Take pointers to argc and
+ argv.
+ (main): Pass parse_args pointers.
+ * as.h: Remove 3 variables that are redundant with flagseen.
+ * as.c, messages.c: Change their users to use flagseen.
+ Define getopt stuff.
+ * tc.h: Update md_parse_option decl. Add md_show_usage decl.
+ * config/tc-*.c: Add md_shortopts, md_longopts,
+ md_longopts_size, md_show_usage. Change calling convention for
+ md_parse_option. Remove md_parse_long_option.
+ * config/tc-ns32k.c: Rename `struct option' to `struct ns32k_option'.
+ * config/tc-i386.h: Don't define md_parse_option.
+
+Thu Jun 2 13:54:46 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * as.c (show_usage): New function.
+ (parse_args): Code moved from main.
+ Recognize --help and --version.
+ * config/tc-ns32k.h: Define TC_NS32K.
+ * doc/as.texinfo: Document all of the target-independent command
+ line options.
+
+Thu Jun 2 12:07:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gasp.c (hash_new_table): Clear newly allocated table.
+
+ * config/tc-m68k.c (enum _register): Add 68060 control registers
+ BUSCR and PCR.
+ (last_movec_reg): New macro.
+ (m68000_control_regs, m68010_control_regs, m68020_control_regs,
+ m68040_control_regs, m68060_control_regs): New arrays.
+ (control_regs): New pointer.
+ (m68k_ip): Use control_regs instead of testing CPU every time.
+ Use last_movec_reg too. In error messages, handle 68060, and
+ print 68060 for mfloat, too.
+ (m68k_init_after_args): Handle "68060". Use m68040up for making
+ m68851 choice. Set control_regs.
+ (md_parse_option): Handle "68060".
+ * configure.in: Setting cpu_type, recognize m68060 too.
+
+ * config/obj-coff.c (fixup_segment) [!BFD_ASSEMBLER]
+ [DIFF_EXPR_OK]: Do conversion to pc-relative for difference, even
+ if pcrel is already set.
+
+ * read.c (potable): Add this_gcc_requires_the_gnu_assembler in all
+ lower-case, in case we're ignoring case of opcodes in the input
+ file.
+
+ * doc/as.texinfo (.section): Document as unavailable for a.out
+ type formats.
+
+ * config/tc-alpha.c (machine): New variable.
+ (load_insn): New macro.
+ (load_insn_table): New function.
+ (md_begin): Call load_insn_table, once for basic instructions and
+ once for appropriate PAL instruction table.
+ (md_parse_option): Set `machine' based on -m##### arguments.
+ * config/alpha-opcode.h (alpha_pal21064_opcodes): Split out from
+ alpha_opcodes.
+ (alpha_pal21164_opcodes): New table.
+ (NUM21064OPCODES, NUM21164OPCODES): New macros.
+
+ * configure.in (target i386-*-netbsd0.8): Use 386bsd emulation.
+
+ * doc/Makefile.in (install-info-gasp): Use $$dir when installing
+ file.
+
+Wed Jun 1 10:48:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Force floating point values to be
+ aligned correctly.
+
+Fri May 27 10:05:53 1994 Ken Raeburn (raeburn@cygnus.com)
+
+ Merged in changes from gas-2.3 net release:
+
+ * Makefile.in (VERSION): Updated to cygnus-2.3.1.
+
+ * config/obj-vms.c: Replaced unchecked uses of malloc with
+ xmalloc.
+
+ * listing.c (list_symbol_table): Only test BFD64, not
+ BFD_ASSEMBLER too.
+
+ * config/obj-coff.c (fixup_segment) [BFD_ASSEMBLER]
+ [DIFF_EXPR_OK]: Don't check pcrel, just convert it.
+
+ * config/obj-vms.c: Removed lots of extra semicolons after
+ compound statements.
+ (strchr): Don't declare here.
+
+ * config/ho-vax.h (realloc): Declare.
+
+ * config/ho-vms.h (strchr, strdup): Declare.
+
+ * config/tc-sparc.c (md_parse_option) [OBJ_ELF]: Accept and ignore
+ option `-q'.
+
+ Wed May 18 20:50:35 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.h (DBG_S_C_SQUAD, DBG_S_C_UQUAD): define these
+ new VMS symbol-type macros; signed and unsigned quadword integers,
+ for `long long' support. Their values come from the existing
+ DSC$K_DTYPE_QU and DSC$K_DTYPE_Q macros in <descrip.h>. The
+ VMS debugger now recognizes `long long' variables correctly.
+ * config/obj-vms.c (VMS_typedef_parse) [case 'r']: add entries
+ for gcc2's predefined types "long double" (same as double, as
+ per gcc's current state), "long long int", "long long unsigned
+ int", and final `otherwise' case (to avoid uninitialized type
+ and size fields). [caveat: predefined types "complex int",
+ "complex float", "complex double", and "complex long double" are
+ still missing.]
+
+ * config/ho-vms.h (EXIT_FAILURE): define as 0x10000002 instead
+ of 0, because the latter indicates success rather than failure
+ when passed to `exit' or return from `main' compiled by gcc2.
+
+ * config/obj-vms.c (array_suffix, generate_suffix): replace two
+ hardcoded `0xa3's with macro DBG_S_C_ADVANCED_TYPE from obj-vms.h.
+ (VMS_typedef_parse): eliminate redundant if-then-else when
+ allocating new symbol entry and linking it to VMS_Symbol_type_list.
+
+ Tue May 17 20:47:31 1994 Pat Rankin (rankin@eql.caltech.edu)
+
+ * config/obj-vms.c (Write_VMS_MHD_Records): don't try to interpret
+ the contents of the GAS_VERSION string when falling back to it for
+ language processor identification.
+
+ * make-gas.com, vmsconf.sh (ENVIRON): fix misspelling of
+ `psect_attr' in linker options.
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: update to latest makefile.in
+ * config/te-go32.h: [new] go32's environment
+
+Fri May 20 17:59:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.h: Don't declare parameters for strstr.
+
+Thu May 19 15:40:13 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (md_section_align): Don't change the size if
+ OBJ_ELF.
+
+Wed May 18 13:08:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (install): Redirect ln output to /dev/null. If ln
+ fails on gasp, install gasp.new, not gasp.
+
+Wed May 18 09:16:36 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Use R_HPPA_ABS_CALL, not R_HPPA for
+ absolute calls.
+
+Tue May 17 12:50:46 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_parse_fp_cmp_cond): Report an error
+ on a partial completer match.
+
+Mon May 16 12:03:49 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Change .hppa_unwind to .PARISC.unwind
+ throughout code.
+ (is_complex): Delete definition and support for complex relocation
+ types.
+ (tc_gen_reloc): Delete special unwind crud for ELF. Simplify and
+ rewrite ELF code based on 94-02-02 PA ELF draft spec.
+ (pa_build_unwind_subspace): Use standard PARISC_DIR32 relocs for
+ the unwind descriptors.
+
+Fri May 6 14:13:15 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/go32.mh: New makefile fragment for go32 crossing.
+ * configure.in (host==go32): Use new fragment.
+
+Fri May 6 14:35:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * gasp.c: Include libiberty.h.
+ (main): Remove unused variable i.
+
+ * config/tc-ppc.c (md_begin): When using -many, permit comparison
+ instructions to appear multiple times in the opcode table.
+
+Thu May 5 19:14:43 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (VERSION): Update to 2.2.90.
+
+ * symbols.c (symbol_new) [BFD_ASSEMBLER]: Don't permit additions
+ to the symbol table if it's already been set in the output bfd.
+ (symbol_begin) [! EMIT_SECTION_SYMBOLS] [RELOC_REQUIRES_SYMBOL]:
+ Don't use bfd_abs_section.symbol for gas absolute symbol.
+
+ * doc/Makefile.in (distclean, clean-dvi, clean-info): Delete gasp
+ files too.
+
+Thu May 5 18:12:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_emit_delays): Make call to
+ mips_no_prev_insn unconditional.
+
+Thu May 5 17:25:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff*.*: Merged coffbfd versions into coff versions,
+ with a single "#ifdef BFD_ASSEMBLER" controlling most of it for
+ now. Deleted obj-coffbfd.* files.
+ * configure.in: Always use obj-coff.* for COFF targets.
+
+Wed May 4 13:34:11 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/te-dpx2.h (TARGET_FORMAT, REGISTER_PREFIX_OPTIONAL):
+ Define.
+ * configure.in (m68k-bull-sysv3*): Enable.
+
+ * config/coff_gnu.h: Deleted.
+
+Wed May 4 11:29:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.h (TARGET_FORMAT): If not TE_SUN3, define as
+ "a.out-zero.big".
+
+ * config/obj-coffbfd.c (fixup_segment): Make common symbol and PC
+ relative adjustments when TE_LYNX is defined as well as when
+ TC_I386 is defined.
+
+Wed May 4 02:29:21 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * as.h (strstr): Restore declaration.
+ (subseg_get) [BFD_ASSEMBLER]: Declare.
+
+ * write.c (write_object_file): If obj_adjust_symtab is defined,
+ invoke it. Then call set_symtab, and finally invoke *_frob_file
+ hooks.
+ * config/obj-coff.c (coff_adjust_symtab): Renamed from
+ coff_frob_file.
+ * config/obj-coff.h (coff_adjust_symtab): Changed declaration
+ accordingly.
+ (obj_adjust_symtab): Macro also changed.
+
+ * configure.in (i386-*-gnu*): New target, handled like i386-mach.
+
+Tue May 3 21:04:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h (TARGET_FORMAT) [TC_I960]: Select little
+ endian version.
+
+ * config/obj-coffbfd.h (TARGET_FORMAT) [TC_I960]: Ditto.
+
+ * config/obj-coff.c (coff_frob_section): Round up the size of
+ every section to a multiple of the alignment, so that BFD doesn't
+ surprise us.
+
+ Eliminate many simple differences between the two COFF back ends:
+
+ * config/obj-coffbfd.c: Removed all uses of DEFUN and DEFUN_VOID.
+ Made minor stylistic changes, deleted some register declarations.
+ (stack_top): Deleted.
+ (symbol_to_chars): Use absolute_section and reg_section instead of
+ the corresponding SEG_* symbols.
+ (obj_coff_endef, tag_find_or_make, fixup_segment): Likewise.
+ (stack typedef, stack_init, stack_delete, stack_push, stack_pop):
+ Moved to just after pseudo-op table. All functions now static.
+ (stack_delete): Removed declaration.
+ (tag_init, tag_insert, tag_find_or_make, tag_find): Moved to just
+ after stack functions.
+ * config/obj-coffbfd.h: Reordered some declarations and macros.
+ (stack_init, stack_delete, stack_push, stack_pop): Don't declare.
+ (stack typedef): Deleted.
+ (SYMBOLS_NEED_BACKPOINTERS): Always undef then define; don't test.
+ (SYM_AUXENT): New macro.
+ (SA_GET_*, SA_SET_*): Define in terms of SYM_AUXENT when feasible.
+ (SF_GET_*, SF_SET_*): Define in terms of SF_GET when feasible.
+ (SA_GET_SYM_TAGNDX, SA_GET_SYM_ENDNDX, SA_SET_SYM_TAGNDX,
+ SA_SET_SYM_ENDNDX, object_headers typedef, data_section_header,
+ text_section_header): Delete non-BFD_HEADERS versions, since we
+ always define that symbol now.
+
+ * config/obj-coff.c (stack_top): Deleted.
+ (obj_coff_endef, obj_coff_dim, obj_coff_line, obj_coff_size,
+ obj_coff_scl, obj_coff_tag, obj_coff_type, obj_coff_val): Change
+ argument name from "ignored" to "ignore".
+ (obj_coff_val): Use frag_now_fix.
+ (obj_pseudo_table): Removed IGNORE_DEBUG version, since it doesn't
+ get used.
+ (stack typedef, stack_init, stack_delete, stack_push, stack_pop):
+ Moved to just after pseudo-op table. All functions now static.
+ (tag_init, tag_insert, tag_find_or_make, tag_find): Moved to just
+ after stack functions.
+ * config/obj-coff.h: Reordered some declarations and macros.
+ Protected against multiple inclusions.
+ (stack_init, stack_delete, stack_push, stack_pop): Don't declare.
+ (stack typedef): Deleted.
+ (SYMBOLS_NEED_BACKPOINTERS): Always undef then define; don't test.
+ (stdoutput): Deleted declaration.
+ (TARGET_FORMAT) [TC_I386]: Don't define if already defined.
+
+Mon May 2 17:09:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * subsegs.h (segment_info_type): Use fix_tail field even if
+ BFD_ASSEMBLER.
+ * subsegs.c (subseg_change): Initialize fix_tail field.
+ (subseg_get): Likewise.
+ * write.c (frags_chained): New static variable.
+ (fix_new_internal): If frags_chained is set, use fix_root and
+ fix_tail from seg_info (now_seg), rather than frchain_now.
+ (chain_frchains_together_1): Set fix_tail field.
+ (chain_frchains_together): Set frags_chained.
+
+Thu Apr 28 01:39:15 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/tc-mips.c (s_option): Only refer to g_switch_* variables
+ if GPOPT is defined.
+ (s_abicalls): Ditto.
+ (md_apply_fix): Cast char* to unsigned char* to avoid pointer
+ mismatch.
+
+Wed Apr 27 11:06:32 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * configure.in (i386-*-go32): Uses coff now.
+ * gasp.c (main): Now takes -D on command line.
+ (show_usage): Describe new options.
+
+Tue Apr 26 17:10:30 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * listing.c (list_symbol_table): Print "NO DEFINED SYMBOLS" and
+ "NO UNDEFINED SYMBOLS" if there aren't any, instead of displaying
+ the header with an empty list.
+
+ * config/obj-coffbfd.c (fill_section): Check COFF_NOLOAD_PROBLEM
+ also before setting STYP_NOLOAD for .bss section.
+
+ * config/tc-m68k.c (flag_reg_prefix_optional): New variable.
+ Initialized to value of REGISTER_PREFIX_OPTIONAL, if defined, or
+ zero.
+ (m68k_reg_parse): If flag_reg_prefix_optional is set, permit
+ register prefix to be absent.
+ (m68k_ip_op): Accept `&' also for immediate constants.
+ (insert_reg): Don't bother with (two!?) sanity checks of the
+ symbol table when inserting each register.
+ (m68k_parse_long_option): New function. Set
+ flag_reg_prefix_optional if "register-prefix-optional" is passed.
+ * config/tc-m68k.h (REGISTER_PREFIX): Always define if not already
+ defined.
+ (OPTIONAL_REGISTER_PREFIX): Don't define.
+ (REGISTER_PREFIX_OPTIONAL): If not already defined, define as zero
+ or one depending on M68KCOFF.
+
+ Some changes to help Apollo support, from troy@cbme.unsw.edu.au:
+ * config/tc-m68k.c (DATA, ADDR, SP, FPREG, COPNUM, BAD, BAC):
+ Define as macros instead of enumerators, since the Apollo compiler
+ can't handle "enumVal1, enumVal2 = enumVal1" when defining an enum
+ type.
+ (make_pcrel_absolute) [NO_PCREL_RELOCS]: New function.
+ (tc_coff_fix2rtype) [NO_PCREL_RELOCS]: Generate only R_RELBYTE,
+ R_DIR16, and R_DIR32 relocs.
+ * config/tc-m68k.h [TE_APOLLO] (COFF_MAGIC, COFF_AOUTHDR_MAGIC):
+ Use Apollo versions.
+ [TE_APOLLO] (OBJ_COFF_OMIT_OPTIONAL_HEADER): Undefine. That is,
+ do include the optional header for Apollo target.
+ (COFF_MAGIC): Don't define as MC68MAGIC if it's already defined.
+
+ * config/tc-m68k.h [TE_DELTA] (LEX_PCT): Define as 1, so that `%'
+ can be used within a label name.
+
+ * config/tc-m68k.h (m68k_init_after_args): Declare.
+ (tc_init_after_args): Define as m68k_init_after_args.
+ * config/tc-m68k.c (m68k_init_after_args): New function,
+ containing one-shot code from md_assemble. Added warning for
+ combination of 68040 and 68851.
+ (md_assemble): Startup-time code deleted.
+
+Mon Apr 25 16:19:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * doc/Makefile.in (clean, distclean): Remove asconfig.texi.
+
+Sun Apr 24 00:13:08 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): 13 bit immediate constant (for break
+ instruction) is unsigned.
+
+Fri Apr 22 17:58:22 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_frob_file): Use bfd_ecoff_set_gp_value
+ and bfd_ecoff_set_regmasks to set the GP value and the register
+ masks, rather than using the now obsolete fake .reginfo section.
+
+Fri Apr 22 15:17:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * listing.c (list_symbol_table): Don't print register symbols as
+ undefined.
+
+ * config/obj-coff.c (obj_symbol_new_hook): Don't need to strip
+ underscores, since symbol_new will already have done it.
+ * config/obj-coffbfd.c (obj_symbol_new_hook): Ditto.
+
+ * as.c (main): If tc_init_after_args is defined, invoke it after
+ all arguments have been processed.
+
+ Some changes to help Apollo support, from troy@cbme.unsw.edu.au:
+ * as.c (perform_an_assembly_pass) [TE_APOLLO]: Create .wtext
+ section instead of .text. Call create_target_segments.
+ * read.c (demand_copy_string): No longer static.
+
+Thu Apr 21 15:50:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (append_insn): Permit branches to be switched
+ with the preceding instruction even if .set nobopt has been seen.
+ .set nobopt actually controls whether to bring up an instruction
+ from the branch target, which gas does not currently support.
+
+Wed Apr 20 18:46:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h, config/obj-coff.c: Deleted all code used only
+ when BFD_ASSEMBLER is not defined, and all conditionals relating
+ to such code. No such targets remain.
+
+ Fixes for stabs-in-coff:
+ * config/obj-coff.c: Include subsegs.h.
+ (coff_frob_section): New function.
+ (obj_coff_init_stab_section): New function.
+ * config/obj-coff.h (obj_coff_init_stab_section,
+ coff_frob_section): Declare.
+ (obj_frob_section): New macro; uses coff_frob_section.
+ (INIT_STAB_SECTION): New macro; uses obj_coff_init_stab_section.
+
+ * config/tc-sparc.c (md_section_align): Always round up to
+ multiple of alignment power specified in bfd target vector.
+
+ * gasp.c: Include ctype.h.
+
+Mon Apr 18 21:08:01 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * doc/Makefile.in, doc/as.texinfo: Renamed asdoc-config.texi to
+ asconfig.texi.
+
+ * doc/Makefile.in (install-info-as, install-info-gasp): Get file
+ names from source directory without pathname.
+
+ * config/obj-vms.c (VMS_write_object_file): While looking for
+ register mask, skip empty fill frags caused by enabling listing
+ output.
+
+ * config/ho-sysv.h: Include string.h.
+
+ * doc/internals.texi: New (well, recently added) file. Just added
+ info on as_warn and friends.
+
+Mon Apr 18 14:28:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_parse_space_stmt): Use the built-in
+ defaults for defined, private, and spnum fields for the
+ $TEXT$ and $PRIVATE$ spaces. Do not clobber spnum. Do
+ not reset the segment if just updating a space.
+ (pa_spaces_begin): Set BFD section flags for all built-in
+ subspaces.
+
+Fri Apr 15 10:51:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (first_proc_ptr): New static variable.
+ (add_procedure): Set first_proc_ptr if it hasn't been set.
+ (ecoff_build_lineno): If the first procedure does not start at
+ address zero, insert a dummy line to compensate.
+
+ * Makefile.in (bootstrap, bootstrap2, bootstrap3): Make gasp.new
+ as well as as.new.
+
+Thu Apr 14 15:12:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * expr.c (operand): Try to parse "0f" and "0b" sequences as
+ floating point and binary numbers respectively; if it doesn't
+ work, treat them as local labels.
+
+ * Makefile.in: Make $(OBJS) depend on $(ALL_OBJ_DEPS).
+ * configure.in: Set ALL_OBJ_DEPS in output Makefile.
+
+ Based on suggestions from <BAILEY@hmivax.humgen.upenn.edu>
+ (Charles Bailey):
+ * vmsconf.sh: In generated file, get ".obj" suffix right, build
+ source files from other directories into objects in the current
+ directory, and specify PSECT attributes explicitly to linker.
+ Also added missing label.
+ * Makefile.in (stamp-mk.com): Reference new variable
+ VMS_OTHER_OBJS for list of non-local object files, instead of
+ listing them here.
+ (VMS_OTHER_OBJS): New variable, added more libiberty files.
+ * make-gas.com: Regenerated.
+
+ * config/ho-vms.h (unlink): Define as delete.
+
+ * config-gas.com: Fix quoting on TARGET_CANONICAL definition.
+ Delete files before creating them.
+
+Thu Apr 14 13:34:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (de-stage1, de-stage2, de-stage3): Use rm -f.
+
+ * config/tc-mips.h (DIFF_EXPR_OK): Define.
+ * config/tc-mips.c (macro_build): Permit BFD_RELOC_PCREL_LO16 for
+ certain cases of 'i', 'j' and 'o'. Change 'u' to take an
+ argument, the reloc type.
+ (load_register): Pass reloc type to macro_build for 'u'.
+ (macro): Likewise. For M_LA_AB permit a difference expression
+ when generating embedded PIC code between an arbitrary symbol and
+ a symbol in the .text section.
+ (mips_force_relocation): Force BFD_RELOC_PCREL_HI16_S and
+ BFD_RELOC_PCREL_LO16 to be emitted.
+ (md_apply_fix): Check that most relocs are not PC relative.
+ Handle BFD_RELOC_PCREL_HI16_S and BFD_RELOC_PCREL_LO16.
+ (tc_gen_reloc): Change #error to as_fatal. Handle
+ BFD_RELOC_PCREL_LO16 and BFD_RELOC_PCREL_HI16_S.
+
+Tue Apr 12 18:25:13 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * subsegs.c (subsegs_begin): Call memset with args in the correct
+ order.
+ (subseg_get): Clear newly allocated seginfo, set its pointer slots
+ to NULL instead of 0.
+
+Mon Apr 11 09:00:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_procend): Handle case where label was
+ defined after the .proc directive.
+
+ * config/tc-hppa.c (pa_procend): Give an error if we encounter a
+ procend for a procedure without a name.
+
+Thu Apr 7 14:28:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Pass NULL for expression argument to
+ macro_build for nori case.
+ (SWITCH_TABLE): Define.
+ (mips_force_relocation): Force a relocation for a switch table
+ entry.
+ (md_apply_fix): Write switch table entry value into file.
+ (tc_gen_reloc): Use BFD_RELOC_GPREL32 for a switch table entry,
+ and set the addend to the difference between the reloc address and
+ the subtrahend.
+
+Thu Apr 7 10:38:18 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.h (elf_tc_symbol): Delete. No longer used.
+ (elf_tc_make_sections): Likewise.
+ (hppa_tc_make_sections, hppa_tc_symbol): Delete extern decls.
+
+ * config/tc-hppa.c (hppa_tc_make_sections): Delete function.
+ (hppa_tc_symbol): Likewise.
+
+ * config/obj-elf.c (elf_frob_file): Delete elf_tc_symbol and
+ elf_tc_make_sections stuff. It was there to support PA braindamage
+ which has been fixed, and in the case of elf_tc_make_sections is
+ redundant with elf_tc_final_processing.
+
+Wed Apr 6 20:48:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-*elf*): Don't require "-hp-" for the
+ manufacturer.
+
+Tue Apr 5 15:48:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): For case 'o', when generating
+ embedded PIC code, accept the difference between two local symbols
+ as being constant.
+ (mips_force_relocation): Only force a reloc to be generated for a
+ PC relative fixup.
+ (md_apply_fix): For BFD_RELOC_32 and BFD_RELOC_LO16, put the fixup
+ value into the file if the fixup will not generate a reloc.
+
+Tue Apr 5 11:14:14 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/tc-sparc.c (s_reserve): If section passed isn't bss,
+ don't spew remainder of input file in error message.
+ (tc_gen_reloc): If bfd_reloc_type_lookup returns null, print error
+ message with reloc type and try to process remainder of file.
+
+ * doc/Makefile.in (install-info-as, install-info-gasp): New
+ targets, now explicitly checking $(srcdir) for info files.
+ (install-info): Depend on both of them; do nothing more.
+
+Mon Apr 4 17:06:04 1994 Jeffrey A. Law (law@cygnus.com)
+
+ * config/tc-hppa.c (tc_gen_reloc): Fix thinko in ELF version.
+
+Mon Apr 4 12:39:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ppc.c (ppc_insert_operand): Check PPC_OPERAND_SIGNED
+ flag rather than signedp field. Only permit extended range if
+ PPC_OPERAND_SIGNOPT flag is set and assembling in 32 bit mode.
+ Based on patch from David Edelsohn (edelsohn@npac.syr.edu).
+
+ * config/tc-ppc.c (ppc_size): New static variable.
+ (ppc_arch): Check for PPC_OPCODE_PPC before PPC_OPCODE_POWER.
+ (md_begin): If an instruction has a size specific flag set, only
+ add it if we are assembling that size.
+
+Thu Mar 31 16:51:16 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Add a gruesome hack to get
+ cross section PC relative relocs right for COFF and ELF.
+
+Mon Mar 28 14:38:23 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Always define.
+ (OBJ_PROCESS_STAB): Don't define.
+
+Mon Mar 28 12:40:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbols): Don't let BFD clobber
+ the type of symbol set symbols which happen to be in the absolute
+ or undefined section.
+
+Mon Mar 28 12:35:00 1994 David Edelsohn (edelsohn@npac.syr.edu)
+
+ * config/tc-ppc.c (md_parse_option): Add -mpwrx (POWER/2 aka
+ RIOS2), -mpwr (POWER aka RIOS1), -mppc (PowerPC aka MPC603/604),
+ and -many (all architectures).
+
+Sun Mar 27 14:04:19 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (tc_gen_reloc): Set addend for relocation
+ involving a function symbol which is not a plabel to zero.
+ (md_apply_fix): Never pass a function symbol to field_adjust.
+
+Fri Mar 25 17:35:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbol): If N_EXT is set for an
+ N_INDR symbol, set BSF_EXPORT and clear BSF_LOCAL.
+
+ * config/tc-mips.c (append_insn): If EMBEDDED_PIC, don't swap a
+ branch with an instruction that uses $at, in case the branch is
+ later expanded.
+ (macro): If EMBEDDED_PIC, case M_JAL_A may use $at.
+ (md_pcrel_from): If not OBJ_AOUT, return 4 for an undefined symbol
+ to make it pcrel_offset.
+ (tc_gen_reloc): If not OBJ_AOUT, set the reloc addend to
+ reloc->address; another gruesome hack to get gas reloc handling to
+ do the right thing.
+
+Thu Mar 24 21:29:29 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (alpha_ip): Only set GP prolog size if using
+ PV register.
+ (T12): New macro.
+ (emit_insn): New function.
+ (md_assemble): Call it.
+ (alpha_force_relocation): Handle BFD_RELOC_26, for call_pal
+ instructions.
+ (lituse_pending): New variable. Set by anything that generates a
+ LITERAL reloc, cleared by anything that generates a LITUSE reloc,
+ tested by code that might want to emit a LITUSE reloc.
+ (emit_unaligned_io): New function. Currently calls md_assemble,
+ but it should eventually be converted to generate the insn itself
+ and call emit_insn directly.
+ (emit_load_unal, emit_store_unal, emit_byte_manip_r,
+ emit_extract_r, emit_insert_r, emit_mask_r, emit_sign_extend,
+ emit_bis_r): Likewise.
+ (alpha_ip, case 'I'): Handle with BFD_RELOC_23.
+ (alpha_ip, label get_macro): Don't emit the final instruction if
+ the opcode is zero.
+ (alpha_ip, case 'B', subcase 'd'): New case, for subword and
+ unaligned memory access macros.
+ (md_apply_fix): Handle BFD_RELOC_26. Generate an error message if
+ the value can't be resolved.
+
+Wed Mar 23 16:06:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (md_parse_option): For -membedded-pic, force
+ the -G value to 0x7fffffff. For SVR4 PIC options, don't call
+ bfd_set_gp_size here, it's done in md_begin. Don't permit -G with
+ -membedded-pic.
+ (mips_force_relocation): New function.
+ (md_apply_fix): Set fixP->fx_done appropriately.
+ (s_change_sec): For EMBEDDED_PIC, change .data and .rdata to
+ .sdata.
+ * config/tc-mips.h (TC_FORCE_RELOCATION): Define.
+ (mips_force_relocation): Declare.
+ (TC_HANDLE_FX_DONE): Define.
+
+Tue Mar 22 13:58:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (enum mips_pic_level): New enum.
+ (mips_pic): Change from int to enum mips_pic_level. Change all
+ uses (0 becomes NO_PIC, 2 becomes SVR4_PIC).
+ (load_address): Handle EMBEDDED_PIC.
+ (macro): Handle EMBEDDED_PIC in all PIC cases.
+ (md_parse_option): Accept -membedded-pic to use EMBEDDED_PIC. If
+ OBJ_ELF, accept -KPIC and -call_shared to use SVR4_PIC and accept
+ -non_shared to use NO_PIC (this is how the Irix 5 assembler
+ works). Do not permit -G with SVR4_PIC.
+ (s_abicalls): Warn if -G was used, and force -G 0.
+ (tc_gen_reloc): Set reloc->addend to 0 for a PC relative reloc for
+ anything but a.out, not just for ELF. For ECOFF, don't generate a
+ BFD_RELOC_16_PCREL_S2 reloc unless using EMBEDDED_PIC.
+
+ * config/obj-ecoff.h (obj_sec_sym_ok_for_reloc): Define to be 1.
+
+Sun Mar 20 16:31:55 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (create_new_space): Use ints, not chars as
+ parameters to avoid losing when compiling with HP CC.
+ (create_new_subspace, update_subspace, fix_new_hppa): Likewise.
+
+Sun Mar 20 14:43:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (config-stamp): If `defs' is defined, emit a
+ preprocessor directive to create a macro named by this value into
+ config.new; don't explicitly go for BFD_ASSEMBLER.
+ * configure.in: Define `defs', not `BFDDEF'. Set it to
+ MANY_SEGMENTS for any obj-coffbfd target.
+ * config/obj-coffbfd.h (BFD_HEADERS, BFD): Define.
+ * config/i386coff.mt (TDEFINES): Don't define BFD, MANY_SEGMENTS,
+ or BFD_HEADERS.
+ (LOCAL_LOADLIBES): Deleted.
+ * config/m68kcoff.mt (TDEFINES): Don't define those macros.
+ * config/m88kcoff.mt (TDEFINES): Ditto.
+ * config/ebmon29k.mt: Deleted.
+ * config/h8300hds.mt: Deleted.
+ * config/ic960coff.mt: Deleted.
+ * config/sparc.mt: Deleted.
+ * config/h8300.mt (LOCAL_LOADLIBES, TDEFINES): Deleted.
+ * config/h8500.mt (LOCAL_LOADLIBES, TDEFINES): Deleted.
+ * config/sh.mt (LOCAL_LOADLIBES, TDEFINES): Deleted.
+ * config/z8k.mt (LOCAL_LOADLIBES): Deleted.
+ (TDEFINES): Don't define the coffbfd macros.
+
+ * Makefile.in: Insert makefile fragments before OBJS definition.
+ (OBJS): Add $(TE_OBJS).
+
+ * config/obj-coff.c (obj_pseudo_table): Supply "section"
+ unconditionally.
+
+ * write.c (set_symtab): Define only if BFD_ASSEMBLER.
+
+Sun Mar 20 12:06:05 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (STAGESTUFF): Add gasp.new.
+
+Fri Mar 18 20:09:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (symbol_table_frozen): New variable, to be set after
+ bfd_set_symtab is called.
+ (dump_section_relocs): Note whether a symbol is a section symbol
+ or not.
+ (adjust_reloc_syms): For now, always supply an absolute symbol for
+ fixups without symbols but not yet `done'. Use section_symbol to
+ get the symbol, instead of going directly for abs_symbol.
+ (write_relocs) [DEBUG4]: Abort if any symbol referred to by a
+ reloc is not a section symbol and is not in the symbol table.
+ (set_symtab): New function, broken out from write_object_file.
+ Counts symbol table instead of relying on an earlier count.
+ (write_object_file): Call set_symtab, but do it after potentially
+ invoking the *_frob_file macros. Don't bother counting symbols.
+ Call symbol_remove, instead of expanding it in place. Moved the
+ conditionalized `object_file_size' declaration down to
+ conditionalized block where it's used. When using the absolute
+ symbol for a fixup without a symbol, set sy_used_in_reloc.
+ (write_object_file) [BFD_ASSEMBLER]: Call section_symbol to get
+ the correct symbol for the absolute section.
+
+ * subsegs.c (section_symbol): Use symbol_new instead of
+ symbol_make, since we may want it to go into the symbol table.
+ Make the new symbol have internal linkage. If
+ obj_sec_sym_ok_for_reloc says it's okay, use the BFD section
+ symbol with the newly created GAS symbol.
+ (obj_sec_sym_ok_for_reloc): Default to always returning 0.
+ * config/obj-aout.h (obj_sec_sym_ok_for_reloc) [BFD_ASSEMBLER]:
+ New macro.
+ * config/obj-elf.h (obj_sec_sym_ok_for_reloc): New macro.
+
+ * config/tc-sparc.c: Include subsegs.h.
+ (in_signed_range): New function.
+ (sparc_ip): Use it.
+ (sparc_ip, case 'i'): Use BFD_RELOC_SPARC13, not _BASE13.
+ (sparc_ip, label "immediate"): Reject constants for pcrel
+ instructions only if the relocation type indicates a "call"
+ instruction and the offset is within range of a "jmpl %g0". If
+ it's not in range, use the absolute section symbol plus an offset.
+ (md_apply_fix): Use in_signed_range. Combined _SPARC13 and
+ _BASE13 cases.
+ (tc_gen_reloc): Permit BFD_RELOC_SPARC13.
+
+ * config/ic960coff.mt (TDEFINES): Fixed typo (MANY_SECTIONS, not
+ MANY_SEGMENTS).
+
+ * configure.in: Eliminated all targets using obj-coff but not
+ defining BFD_ASSEMBLER; I think all such targets that are
+ supported will be matched by real CPU-OS combinations earlier in
+ the case statement.
+ (targets *-*-coff*, *-sysv*, *-*-sco*, *-*-sysv32): Deleted. Made
+ some comments about the dpx2 configuration, but left it disabled,
+ since it couldn't be reached before.
+ (target a29k-amd-ebmonold): Deleted.
+
+Thu Mar 17 13:36:09 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_import): Correctly handle importing of an
+ already defined symbol.
+
+Wed Mar 16 17:11:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Only accept overly large values for
+ the 'j' operand if there are no further alternatives for this
+ instruction.
+
+ * config/obj-coffbfd.c (adjust_stab_section): Initialize
+ stabstrseg to SEG_UNKNOWN, not -1. After loop, check whether it
+ is not SEG_UNKNOWN rather than checking whether it is >= 0.
+
+ * config/tc-mips.c (mips_align): Take new argument, label, and use
+ it instead of global insn_label.
+ (s_align, s_cons, s_float_cons, s_gpword): Save insn_label before
+ call to mips_emit_delay and pass it to mips_align.
+
+Wed Mar 16 11:54:12 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_equ): Handle both .reg and .equ correctly.
+
+ * config/tc-hppa.c (pa_callinfo): Accept "millicode" as an
+ argument to a .callinfo directive. Don't loop forever on errors.
+
+ * config/tc-hppa.c (pa_equ): Use pa_parse_number so that we can
+ use pre-defined registers as arguments.
+
+Mon Mar 14 14:29:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (write_object_file): Check both S_IS_LOCAL and
+ S_IS_EXTERNAL when deciding whether to discard a symbol.
+
+ * config-gas.com: Scan Makefile.in, not version.c, for current
+ version number. Delete all versions of temp files when finished
+ with them. Create config.h.
+
+ * config/obj-vms.c (VMS_Initialized_Data_Size): Cache symbol
+ values to reduce number of lookups with S_GET_VALUE. Skip debug
+ symbols to avoid "a really nasty bug". (From Holger Teutsch,
+ holger@botbso.rhein-main.de.)
+ (VMS_write_object_file): For "__vt.*" symbols, set S_GET_OTHER
+ field. (Also from Holger Teutsch.) Watch for a would-be register
+ mask that spans frags.
+
+ * config/obj-coffbfd.c (obj_coff_line): Set symbol lnno field with
+ this_base, not line_base. (Patch from Andreas Arens,
+ ari@obelix.av.rwth-aachen.de.)
+
+ * config/obj-aout.c (obj_crawl_symbol_chain): Retain symbols that
+ look local if they're exported or undefined. Used to be done for
+ i960 only.
+
+ * read.c (s_lcomm, s_comm): Print symbol name being redefined.
+ Get it from the looked-up symbol, instead of using the string from
+ the input stream, which is no longer null-terminated.
+ (LEX_PCT): New macro, defaults to 0.
+ (lex_type): Use it for `%'.
+
+ * config/tc-vax.c (md_parse_option): Handle `-h#' option for VMS.
+ (vip_op): Now static, and returns void. Callers changed. Added
+ forward decl.
+ (vip): Ditto. Call as_fatal directly if a program bug is
+ detected.
+ (op_hash): Let default initialization suffice.
+
+ * Makefile.in (literal.o): Provide dependencies.
+
+ * configure.in: Set new makefile variable OPCODES_LIB.
+ * Makefile.in (LIBS): Use it.
+
+ * Makefile.in (make-gas.com, stamp-mk.com): New targets.
+ * vmsconf.sh: New file.
+ * make-gas.com: Regenerated from new script.
+
+ * configure.in (sparc*-*-lynxos*): Handle any version number
+ suffix after "lynxos". Set emulation to lynx.
+
+Mon Mar 14 11:30:49 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/obj-coff.c (obj_coff_section): Delete declaration.
+
+Fri Mar 11 22:25:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ppc.c (md_pcrel_from): Return 0 for undefined ELF
+ symbols.
+ (ppc_is_toc_sym): Change .toc to .got.
+ (md_apply_fix): Change handling of ELF relocs.
+ (tc_gen_reloc): Likewise.
+
+Fri Mar 11 17:42:20 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-vms.c (Close_VMS_Object_File): Add comment pointing
+ out some code that doesn't belong in this file.
+
+ * config/obj-vms.h: Include aout/stab_gnu.h.
+ (N_GSYM, ..., N_LENG): Deleted.
+ (NO_RELOC): Undefine before defining as part of enum reloc_type.
+
+ * config/tc-alpha.c: Add comment questioning need for all the
+ characters in FLT_CHARS.
+
+ * as.c (main) [OBJ_VMS]: Don't call output_file_close.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Set strict order for
+ sections with recognized names, before computing VMA values.
+
+Fri Mar 11 17:56:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Accept numbers between 0x8000 and
+ 0xffff for 'j' to be compatible with MIPS assembler. These
+ numbers are actually treated as negative.
+
+Thu Mar 10 13:36:29 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.h (LOCAL_LABEL): Local labels are .Lfoo.
+
+Tue Mar 8 21:17:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.c: Minor formatting/stylistic changes, plus:
+ (obj_coff_section): Declare.
+ (obj_pseudo_table): Make it available only if MANY_SECTIONS.
+ (obj_symbol_to_chars) [CROSS_COMPILE]: Some attemps to make this
+ work. It still doesn't. It now fails to compile, instead of
+ silently compiling to do nothing.
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Define only if
+ MANY_SECTIONS.
+ (OBJ_PROCESS_STAB) [! MANY_SECTIONS]: New macro, just emits
+ warning.
+
+ Handle Alpha load-immediate-FP pseudo-instructions:
+ * config/alpha-opcode.h (ldif, ldig, ldis, ldit): New patterns.
+ * config/tc-alpha.c (lit8_sec, lit4_sec, lit8_sym, lit4_sym): New
+ variables.
+ (create_literal_section): New function.
+ (create_lita_section): Now a macro.
+ (get_lit8_offset, get_lit4_offset): New functions.
+ (maybe_set_gp): New function.
+ (select_gp_value): Call it.
+ (load_expression): Preserve addend if symbol is a section symbol.
+ (alpha_ip): Handle new operand type `F' for floating-point
+ constants; store them in .lit{4,8} sections.
+ (alpha_ip, case 'G'): Emit LITUSE relocations for symbol exprs.
+
+ * config/tc-i386.c (smallest_imm_type): Never return Imm1.
+
+Tue Mar 8 14:18:15 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coffbfd.c (w_strings): Only copy strings out if
+ their symbols are going to be written.
+
+Tue Mar 8 11:49:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * messages.c (as_perror): Declare arguments const.
+ * as.h (as_perror): Change declaration.
+
+Mon Mar 7 16:08:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (load_address): When calling frag_grow, allow
+ for the (up to) two nops which may be inserted by append_insn if
+ mips_optimize is 0.
+ (macro): Likewise.
+
+Thu Mar 3 11:37:55 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/atof-ieee.c (make_invalid_floating_point_number):
+ Add cast to avoid warning from gcc.
+
+Wed Mar 2 10:31:01 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Add a few casts to make HP C compiler happy.
+
+ * config/obj-som.c (obj_som_version, obj_som_copyright): Be
+ prepared
+ to handle an error from bfd_som_attach_aux_hdr.
+
+ * config/tc-hppa.h: Wrap ELF specific decls inside an ifdef.
+
+Mon Feb 28 15:03:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (md_atof): Omit warning about FP values.
+ (line_comment_chars): Add ! to list.
+ (md_apply_fix): Do process 32- and 64-bit relocations.
+
+ * config/obj-coffbfd.c (obj_coff_lcomm): Put "#if 0" around the
+ unused parts (most of the function).
+ (obj_coff_init_stab_section): Cast alloca result.
+
+ * configure.in (i960-*-coff, i960-*-vxworks5.*): Use coffbfd, and
+ gas_target ic960coff.
+ * config/ic960coff.mt: New file.
+ * config/obj-coffbfd.h [TC_I960]: Include coff/i960.h.
+ (TARGET_FORMAT) [TC_I960]: Use coff-Intel-little.
+ * config/te-ic960.h (CROSS_COMPILE): Don't undef this. We'll
+ always build little-endian object files.
+ * config/tc-i960.c (md_reloc_size): Don't define at all if BFD or
+ BFD_ASSEMBLER is defined.
+ (mem_fmt): Since COFF doesn't handle callx relocations yet, treat
+ them like normal 32-bit relocations.
+ (md_apply_fix): For callx relocations, store zero.
+ (tc_bout_fix_to_chars): Store symbol index for all callx
+ relocations, regardless of link-relax setting.
+ (tc_coff_fix2rtype, tc_coff_sizemachdep): New functions.
+ (i960_handle_align) [! OBJ_BOUT]: If link-relax option is
+ selected, print an error message and clear it.
+ * config/tc-i960.h (BFD_ARCH, COFF_FLAGS, COFF_MAGIC,
+ TC_COUNT_RELOC, TC_COFF_FIX2RTYPE, TC_COFF_SIZEMACHDEP,
+ tc_fix_adjustable): New macros.
+ (tc_coff_fix2rtype, tc_coff_sizemachdep): Declare.
+
+Fri Feb 25 20:56:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_tc_symbol): Call PA ELF BFD version.
+ (hppa_tc_make_sections): Likewise.
+ (pa_build_symextn_section): Delete unused function.
+ (hppa_tc_make_symextn_section): Likewise.
+ (pa_export): Delete call to pa_build_symextn_section.
+
+ * config/tc-hppa.h (hppa_tc_symbol): Add extern decl.
+ (elf_hppa_final_processing): Delete extern decl.
+ (hppa_tc_symbol): Delete extern decl.
+
+Fri Feb 25 13:15:31 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): Correct test for whether to
+ fill a section (from Minh Tran-Le <TRANLE@intellicorp.com>).
+
+Thu Feb 24 11:30:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in: Don't require version number for i386-*-mach.
+
+ * read.c (potable): Added ".this_GCC_requires_the_GNU_assembler",
+ which is ignored by gas, but will cause other assemblers to choke.
+ Intended for use by gcc ports that require gas instead of native
+ assemblers.
+
+Thu Feb 24 07:10:31 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/ho-hppaosf.h: Fix braino in test for ANSI-C.
+
+Wed Feb 23 16:51:43 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * write.c (write_contents): Give the user a reasonable error
+ message rather than "assertion failed" if bfd_set_section_contents
+ fails.
+
+Tue Feb 22 10:07:32 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/ho-mach3.h: New file.
+
+Mon Feb 21 11:41:18 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.c (ecoff_build_debug): Don't set hdr->magic here. It is
+ now set in bfd/ecofflink.c:ecoff_write_symhdr.
+
+ * config/obj-coffbfd.c (write_object_file): use bfd_get_error (),
+ not bfd_error.
+ * config/obj-elf.c (elf_frob_file): Likewise.
+
+ * read.c (s_lcomm): Use an alignment power of 3 for 8 byte .lcomm
+ variables.
+
+ * config/ho-hpux.h (BROKEN_ASSERT): Define if not __GNUC__.
+
+ * read.c (read_a_source_file): Use correct arguments to memcpy
+ (broken 19 Jul 1993). From kjd@pescadero.stanford.edu (Kenneth
+ Duda).
+
+Sun Feb 20 18:01:54 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * config/obj-coff.h (obj_coff_section): Declare.
+ * config/obj-coff.c (obj_pseudo_table): For "section", use
+ obj_coff_section.
+ (obj_coff_section): Rewrite.
+
+Fri Feb 18 14:16:32 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in (i386-*-mach3*): New target; uses BFD.
+ * config/te-mach.h: New file.
+ * config/obj-aout.c (obj_aout_frob_file): New function.
+ * config/obj-aout.h (obj_aout_frob_file): Declare it.
+ (frob_file): New macro.
+ * config/tc-i386.c (md_apply_fix_1) [TE_Mach]: Don't adjust
+ pcrel32 relocations.
+ * config/tc-i386.h (TARGET_FORMAT) [TE_Mach]: Use a.out-mach3.
+
+ * write.c (write_object_file): Removed register declarations.
+
+Thu Feb 17 16:25:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Some support for PowerPC ELF.
+ * configure.in: If cpu is powerpc*, use ppc.
+ (ppc-*-sysv4*): Use object format elf.
+ * config/tc-ppc.h: Only declare a number of things if OBJ_COFF is
+ defined.
+ (TARGET_ARCH): Make it call ppc_arch.
+ (ppc_arch): Declare.
+ (TARGET_FORMAT): Set based on OBJ_COFF or OBJ_ELF.
+ (NO_STRING_ESCAPES): Define.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define for OBJ_ELF.
+ * config/tc-ppc.c: Only define a number of functions of OBJ_COFF
+ is defined.
+ (md_pseudo_table): Most pseudo-ops are OBJ_COFF specific. Added
+ OBJ_COFF specific "bi" and "ei".
+ (md_parse_option): Fix handling of -u. Make -m601 set
+ PPC_OPCODE_601. If OBJ_ELF, accept -V and -Q.
+ (ppc_set_cpu): New function.
+ (ppc_arch): New function.
+ (md_begin): Call ppc_set_cpu.
+ (ppc_insert_operand): For a signed operand accept an unsigned
+ value, for IBM compatibility.
+ (ppc_byte): Don't call stringer for strings; instead, treat two
+ double quotes as a single double quote.
+ (ppc_comm): Set sy_tc.output for a .lcomm symbol.
+ (ppc_biei): New function.
+ (ppc_tc): If not OBJ_COFF, ignore first argument.
+ (ppc_fix_adjustable): Call as_bad_where, not as_bad.
+ (ppc_is_toc_sym): New function.
+ (md_apply_fix): Use ppc_is_toc_sym. Handle BFD_RELOC_16 and
+ BFD_RELOC_8.
+
+Thu Feb 17 09:29:37 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * messages.c (as_perror) [BFD_ASSEMBLER]: Use bfd_get_error and
+ bfd_set_error and new error names.
+
+Tue Feb 15 20:23:20 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * configure.in: Support i960-vxworks versions > 5.0 as coff.
+ Default is still bout if no version is specified.
+
+ * atof-generic.c (atof_generic): Use switch and strcasecmp instead
+ of large number of compares when looking for inf/nan values.
+
+Fri Feb 11 13:13:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Do unaligned loads and stores
+ correctly when big endian, and give errors on overflow rather than
+ generating incorrect code.
+
+Thu Feb 10 11:24:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.c: Include libiberty.h.
+
+ * read.c (do_align): Don't define label just_record_alignment
+ unless it might be used.
+
+ * as.c (main): If md_parse_long_option is defined, call it with a
+ long option.
+ * config/tc-mips.h (md_parse_long_option): Define.
+ * config/tc-mips.c (mips_trap): New static variable.
+ (md_begin): Report an error if mips_trap is set at ISA level 1.
+ (macro): If mips_trap, use trap instructions instead of break
+ instructions for overflow and divide by zero detection.
+ (mips_parse_long_option): New function. Support --trap,
+ --no-break, --break and --no-trap.
+ * doc/as.texinfo: Document new options.
+
+ * read.c (potable): Add "zero".
+ * config/tc-i386.c (md_pseudo_table): Remove "zero".
+ * config/tc-m88k.c (md_pseudo_table): Likewise.
+
+Thu Feb 10 01:24:27 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Reject integer values for
+ pc-relative operand fields. This forces "call 0" to become "jmpl
+ %g0,%o7" with no relocations needed.
+
+Wed Feb 9 13:08:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.h (xmalloc, xrealloc): Declare using PTR rather than char *.
+ * xmalloc.c (xmalloc, xrealloc): Use PTR rather than char *.
+
+ * app.c (do_scrub_next_char): If NO_STRING_ESCAPES is defined,
+ don't treat backslash specially inside strings.
+ * read.c (next_char_of_string): Likewise.
+
+Wed Feb 9 09:42:45 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Use memset
+ instead of memcpy to zero the initial stab symbol, duh.
+ * config/obj-elf.c (obj_elf_init_stab_section): Ditto.
+ * config/obj-som.c (obj_som_init_stab_section): Ditto.
+
+Tue Feb 8 17:25:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (fixup_segment): Use as_bad_where, not as_bad.
+
+ * subsegs.c (subseg_set_rest): Call memset with the arguments in
+ the right order. Explicitly clear fix_root and fix_tail fields.
+
+Tue Feb 8 16:00:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/obj-coff.c (coff_frob_symbol): For abs_symbol, set *punt
+ and do nothing else.
+
+ * symbols.c (symbol_begin): Initialize value of abs_symbol
+ properly.
+
+ * write.c (adjust_reloc_syms): Use abs_symbol instead of calling
+ section_symbol.
+
+ * ecoff.c (ecoff_build_debug): Fix "/*" in comment to silence
+ complaint from "gcc -Wall".
+
+ * configure.in (alpha-*-netware*): New target, like alpha-*-osf*.
+
+ * config/tc-alpha.c (GP_ADJUSTMENT): Move definition to start of
+ file.
+ (tc_gen_reloc): Remove uninitialized variable `code', and code
+ that tried to use it (incorrectly). For LITERAL reloc, set addend
+ to negative of GP value.
+ (load_symbol_address): Don't adjust return value by GP_ADJUSTMENT.
+
+ * write.c (write_relocs): Print some sensible error message if
+ bfd_perform_relocation returns bfd_reloc_overflow.
+
+Mon Feb 7 15:49:24 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*elf*): New configuration for PA ELF.
+ (hppa*-*-osf*): Default object format is SOM.
+
+Mon Feb 7 16:07:35 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c (md_atof): Warn that floating-point values
+ might not assemble properly.
+
+ * configure.in (target alpha-*-osf*): Don't set "dev=yes" any
+ more.
+
+ * config/tc-alpha.c (load_expression): Parenthesize operations in
+ range checking, to avoid precedence questions.
+
+ * config/tc-alpha.c (addr32): New static variable.
+ (md_parse_option): Set it for "-32addr".
+ (load_symbol_address): If addr32 is set, use ldl instead of ldq.
+
+ * atof-generic.c (atof_generic): Calculate maximum_useful_digits
+ and more_than_enough_bits_for_digits in integer arithmetic, to
+ eliminate the only sources of dependence on floating point
+ support, which doesn't work yet on the Alpha.
+
+Mon Feb 7 03:56:05 1994 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * ecoff.c (ecoff_build_debug) [TC_ALPHA]: Specify version stamp as
+ 0x30b for Alpha for now, until ".verstamp" is handled.
+
+ * literal.c (add_to_literal_pool): Use seginfo->frchainP, which
+ actually refers to the literal pool section, rather than
+ frchain_now, which refers to whatever section the assembler was
+ in.
+
+ * write.c (fixup_segment): Only do range checking if size of fixup
+ is smaller than word size. Otherwise, we always wind up with
+ zeros.
+
+ * config/tc-alpha.c (md_section_align): Change second argument and
+ return type to valueT, to agree with tc.h.
+ (alpha_do_align): Local static array nop_pattern is now unsigned
+ char, to avoid overflow warnings.
+ * config/tc-alpha.h (md_section_align): Delete declaration.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Ensure that ecoff_data for
+ output bfd is non-null before indirecting through it.
+
+ * config/tc-alpha.c (alpha_frob_ecoff_data): Renamed from
+ alpha_frob_file.
+ * config/tc-alpha.h (tc_frob_file): Macro deleted.
+ * config/obj-ecoff.c (ecoff_frob_file) [TC_ALPHA]: Call
+ alpha_frob_ecoff_data, then fill in optional-header info with gp
+ value and register masks.
+
+Sun Feb 6 16:13:47 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hiux): Fixes from m-kasahr@sramhc.sra.co.JP.
+
+ * config/obj-som.c (obj_som_init_stab_section): Same change
+ as coffbfd and elf below. Zero the initial stab symbol after
+ allocating it.
+
+Sat Feb 5 12:30:32 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Zero the
+ initial stab symbol after allocating it.
+ * config/obj-elf.c (obj_elf_init_stab_section): Ditto.
+
+Sat Feb 5 11:53:31 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): addb[tf] should only accept
+ non-negated condition completers. Add support for addb pseudo-op
+ which accepts both negated and non-negated completers.
+
+Sat Feb 5 00:15:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (rs6000*): Use cpu_type ppc.
+ (ppc-*-aix*): New target; use coff and force bfd_gas.
+ * config/tc-ppc.h, config/tc-ppc.c: New files for PowerPC/POWER
+ (RS/6000) support. At the moment, only XCOFF is supported.
+
+ * config/obj-coff.c (SA_SET_SYM_ENDNDX): Made non-static.
+ (S_SET_DATA_TYPE): Likewise.
+ (coff_last_function): Renamed from local static last_functionP in
+ coff_frob_symbol and made externally visible.
+ (coff_frob_symbol): New local static set_end; use it to try to
+ avoid calling SA_SET_SYM_ENDNDX on a symbol that will be punted.
+ * config/obj-coff.h (S_SET_DATA_TYPE): Declare.
+ (SA_SET_SYM_ENDNDX): Declare.
+ (coff_last_function): Declare.
+
+ * expr.c (operand): If DOLLAR_DOT is defined, accept `$' as
+ equivalent to `.' to mean the current location.
+
+ * read.c (LEX_BR): If not defined, define as 0.
+ (lex_type): Use LEX_BR as the type of `{',`}',`[',`]'.
+
+ * symbols.c (symbol_new): If tc_canonicalize_symbol_name is
+ defined, call it with preserved_copy_of_name. If
+ tc_symbol_new_hook is defined, call it on the new symbol.
+ (symbol_find_base): If tc_canonicalize_symbol_name is defined,
+ call it on a copy of the name argument.
+
+ * write.c (write_object_file): Simplified usage of obj_frob_symbol
+ and tc_frob_symbol. Always call both if the symbol is going to be
+ output.
+
+ * write.c (relax_segment): Use %ld rather than %d when printing
+ fragP->fr_var, and cast it to long.
+
+ Changed relocs to be based on subsegments (when BFD_ASSEMBLER).
+ * subsegs.h (struct frchain): If BFD_ASSEMBLER, added new fields
+ fix_root and fix_tail.
+ (segment_info_type): If BFD_ASSEMBLER, don't define fix_tail
+ field.
+ * write.c (fix_new_internal): If BFD_ASSEMBLER, set fix_rootP and
+ fix_tailP based on frchain_now, not seg_info (now_seg).
+ (chain_frchains_together_1): Chain the subsegment relocs together.
+ * subsegs.c (subseg_change): Don't clear fix_tail field.
+ (subseg_get): Likewise.
+ * literal.c (add_to_literal_pool): Look through the relocs via
+ frchain_now, not seginfo.
+
+Thu Feb 3 23:07:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.h (TARGET_SYMBOL_FIELDS): Changed
+ ecoff_undefined to ecoff_extern_size.
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): Likewise.
+ * config/tc-mips.c (s_extern): Set ecoff_extern_size to the
+ external symbol size, rathern than setting the symbol value.
+ (md_estimate_size_before_relax): Check both ecoff_extern_size and
+ symbol value to see if GP referencing can be used.
+ * ecoff.c (ecoff_symbol_new_hook): Clear ecoff_extern_size, not
+ ecoff_undefined.
+ (ecoff_frob_symbol): Don't check ecoff_undefined.
+ (ecoff_build_symbols): Get size of an undefined symbol from
+ sym->ecoff_extern_size, not S_GET_VALUE (sym).
+
+Wed Feb 2 13:55:08 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in: Avoid bug in losing hpux sed.
+
+Wed Feb 2 11:40:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (file_mips_isa): New static variable.
+ (md_begin): Set it.
+ (s_mipsset): Add support for .set mipN to set the ISA level.
+
+ * gasp.c (kinfo): Fully bracket initializer.
+
+Tue Feb 1 19:28:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gasp.c (malloc): Don't declare, since host.h or system header
+ files may declare it differently.
+
+ * config/atof-ieee.c (int_to_gen): Now static.
+
+ * config/ho-i386aix.h: Include sys/types.h and stdlib.h, not
+ ho-sysv.h. Based loosely on a patch from Minh Tran-Le.
+
+Tue Feb 1 10:50:17 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * gasp.c: Include host.h.
+
+Tue Feb 1 12:13:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Make an unsupported instruction a
+ warning, not an error.
+
+ * config/obj-coff.c (dot_text_symbol, dot_data_symbol,
+ dot_bss_symbol): Don't define if BFD_ASSEMBLER.
+ (obj_symbol_to_chars): bfd_coff_swap_aux_out now takes more
+ arguments.
+ (coff_line_base): Renamed from line_base. Changed all uses.
+ (coff_add_linesym): Renamed from add_line_sym. Made non-static.
+ Changed all uses.
+ * config/obj-coff.h: If TC_PPC, include coff/rs6000.h.
+ (S_SET_STORAGE_CLASS, S_GET_STORAGE_CLASS): Declare if
+ BFD_ASSEMBLER.
+ (coff_line_base): Declare.
+ (coff_add_linesym): Declare if BFD_ASSEMBLER.
+ * config/obj-coffbfd.c (symbol_to_chars): bfd_coff_swap_aux_out
+ now takes more arguments.
+
+Mon Jan 31 17:55:14 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (statistics_flag): Renamed from quiet_flag.
+ (main): Get statistics with --statistics instead of -noquiet.
+
+Mon Jan 31 07:19:30 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * Makefile.in: Support for Gnu ASsembler Preprocessor.
+ * gasp.c: New file.
+ * read.c (s_lcomm): Align lcomm data.
+ * config/tc-z8k.c (tc_reloc_mangle): Don't allow subtraction
+ from different sections.
+
+Sun Jan 30 14:58:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (write_object_file): If tc_frob_file is defined, call it
+ just before calling obj_frob_file.
+ * config/tc-alpha.c (alpha_gp_value): Renamed from gp_value
+ (references changed), and made non-static.
+ (getExpression): Return void.
+ (select_gp_value): Abort if gp_value is non-zero. Delete call to
+ non-existent bfd_set_gp_value.
+ (alpha_validate_fix): Function deleted.
+ (alpha_frob_symbol): Function deleted.
+ (alpha_local_label): Function deleted.
+ (alpha_frob_file): Renamed from alpha_end.
+ * config/tc-alpha.h (alpha_frob_symbol, alpha_validate_fix,
+ alpha_local_label, alpha_end): Declarations deleted.
+ (alpha_gp_value, alpha_frob_file): Declare.
+ (tc_frob_symbol, TC_VALIDATE_FIX, md_end): Macros deleted.
+ (LOCAL_LABEL): Move code here from tc-alpha.c:alpha_local_label.
+ (md_convert_frag): Simplified slightly.
+ (tc_frob_file): New macro.
+
+ * read.c (do_align): New function, most of guts of s_align_*
+ functions. Look for md_do_align macro, give it a chance to bypass
+ all but recording of section alignment.
+ (s_align_bytes, s_align_ptwo): Call do_align.
+ (s_lcomm) [TC_ALPHA]: Align object to largest power of two that
+ divides object size.
+
+ * frags.c (frag_align_pattern): New function.
+ (frag_align): Rewrite for clarity.
+
+ * config/tc-vax.c (md_assemble): Handle O_constant expression.
+ (vip_begin): Returns pointer to const char. Cast hash_insert arg
+ to PTR to avoid compiler complaints about const.
+ (md_begin): Local variable errtxt must point to const.
+
+ * configure.in: Handle host vax-*-ultrix* like vax-*-bsd*. Don't
+ bother with *-*-ultrix or *-*-sysv*, except *-*-sysv, since only
+ the last has an existing host support file. Do handle vax-bsd and
+ vax-ultrix targets.
+
+Fri Jan 28 11:26:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coff.c (obj_coff_section_header_append): Do not
+ declare if BFD_ASSEMBLER.
+ (stack_pop): Correct test for stack underflow.
+ (obj_coff_endef, obj_coff_dim, obj_coff_line, obj_coff_size,
+ obj_coff_scl, obj_coff_tag, obj_coff_type, obj_coff_val): Declare
+ type of ignored argument to avoid gcc warning.
+ (align): Removed unused function.
+
+Thu Jan 27 18:14:19 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-alpha.c, config/tc-alpha.h, config/alpha-opcode.h: New
+ files, based on port of gas-1.38 contributed by CMU, using a.out
+ variant. Updated for gas-2.x and ECOFF. Floating-point constants
+ are still broken, bootstrap testing incomplete.
+
+ * literal.c: Comment changes.
+
+ * listing.c (listing_source_file): Check for null listing_tail
+ before indirecting through it.
+
+ * expr.h (struct expressionS): Added struct tag.
+
+ * as.h: If __GNUC__ and inline are both undefined, define inline
+ away.
+
+ * write.c (cvt_frag_to_fill): Don't assume that fr_var for
+ rs_align or rs_org frags will be 1.
+ (relax_segment): For rs_align, if fr_var is not 1, complain if
+ required padding is not a multiple of the size of the pad pattern.
+ (fixup_segment): Leave gp-relative relocations alone. For pcrel
+ relocations referring to the same segment, clear fx_pcrel when
+ clearing fx_addsy.
+ * as.h: Adjust comments on rs_align.
+
+ * atof-generic.c: Some reformatting.
+ (atof_generic): Be careful when mixing signed/unsigned values of
+ different sizes.
+
+ * write.c, config/obj-{aout,bout,coff*}.c, config/tc-sparc.c:
+ Query the fx_done field instead of fx_addsy to see if the fixup
+ still needs to be applied. Set fx_done and clear fx_addsy both,
+ for now. If TC_HANDLES_FX_DONE isn't defined, assume md_apply_fix
+ will only clear fx_addsy, and set fx_done accordingly after
+ returning.
+ * config/tc-sparc.h (TC_HANDLES_FX_DONE): Define.
+ * config/tc-sparc.c (md_apply_fix): Set fx_done for non-pcrel fix
+ with no fx_addsy.
+
+ * symbols.c (dot_text_symbol, dot_data_symbol, dot_bss_symbol):
+ Deleted.
+ (symbol_begin): Moved to end of file, so function inlining can
+ work better.
+ (fb_label_count, fb_label_max): Default C static initializers are
+ sufficient.
+ * symbols.h (dot_text_symbol, dot_data_symbol, dot_bss_symbol):
+ Declarations deleted.
+ * config/obj-coff.c (dot_text_symbol, dot_data_symbol,
+ dot_bss_symbol): Defined here, static.
+
+ * config/obj-aout.c [BFD_ASSEMBLER]: Undef NO_RELOC before
+ including aout/aout64.h.
+
+ * write.c (write_object_file): If EMIT_SECTION_SYMBOLS is false,
+ don't write out a section symbol even if it's used in a
+ relocation; assume relocations will handle section numbers
+ somehow. Rename "punt_it" label to "punt_it_if_unused" to reflect
+ it's true use.
+ (EMIT_SECTION_SYMBOLS): Default to 1.
+ (adjust_reloc_syms): Don't create a new symbol for an absolute
+ reference; just use the absolute section symbol.
+ (write_relocs): Make printout of reloc values dependent on flag
+ DEBUG3, not DEBUG2.
+ * config/obj-aout.h (EMIT_SECTION_SYMBOLS): Define as 0.
+ * config/obj-ecoff.h (EMIT_SECTION_SYMBOLS): Ditto.
+
+Thu Jan 27 16:43:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (lex_type): No longer make '{' a valid character for
+ symbol names.
+
+ * as.c (main): Print long values using %ld.
+
+ * messages.c (as_warn_internal): New static function.
+ (as_warn, 3 versions): Use as_warn_internal.
+ (as_warn_where, 3 versions): New function.
+ * as.h (as_warn_where): Declare.
+
+Tue Jan 25 18:30:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * as.c (quiet_flag): New flag.
+ (main): If -noquiet given, display execution time and memory used.
+
+Tue Jan 25 15:53:11 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * doc/{all.texi,as.texinfo}: Add documentation for HPPA port.
+
+Mon Jan 24 19:18:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_frob_symbol): New function. Put undefined
+ symbols of known size in the undefined section. Put small common
+ symbols in a .scommon section.
+ * ecoff.h (ecoff_frob_symbol): Declare.
+ * config/obj-ecoff.h (obj_frob_symbol): Define.
+ * config/obj-elf.c (obj_elf_write_symbol_p, obj_elf_write_symbol,
+ obj_elf_frob_symbol): Removed unused functions.
+ * config/obj-elf.h (obj_frob_symbol, obj_write_symbol): Removed
+ unused macros.
+ (obj_elf_frob_symbol, obj_elf_write_symbol): Removed declarations
+ of unused functions.
+ (obj_frob_symbol): Define if ECOFF_DEBUGGING.
+
+ * tc-mips.c (g_switch_seen): New static variable.
+ (md_parse_option): Set g_switch_seen for -G option.
+ (s_option): If creating PIC code, force the GP size to be 0. Warn
+ if -G switch used with a non-zero value.
+
+ * symbols.c (S_IS_COMMON): Use bfd_is_com_section rather than
+ comparing against bfd_com_section.
+
+Mon Jan 24 14:12:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * read.c (s_lcomm): Treat Alpha like MIPS in handling of .sbss
+ section.
+
+Thu Jan 20 13:17:58 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * expr.c (operand): For floating point operand with unusual fp
+ char from FLT_CHARS, preserve the character. Patch from Lisa
+ Repka.
+
+Wed Jan 19 23:15:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (md_pseudo_table): Add all data allocation
+ pseudo-ops: .hword, .int, .long, .octa, .quad, .short, .single.
+
+Tue Jan 18 15:51:59 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_endef): For C_EFCN, C_BLOCK and
+ C_FCN assume .val has been set to .
+
+Tue Jan 18 16:19:58 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: Disable multiple $CODE$ subspace code. It
+ confuses GDB for some unknown reason.
+ * cofnig/obj-som.c: Likewise.
+
+Tue Jan 18 19:05:32 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * literal.c (add_to_literal_pool): Handle duplicates of values
+ already written to literal pool.
+
+Tue Jan 18 17:23:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c (obj_aout_frob_symbol): Try to get symbols
+ with explicitly marked stabs through BFD: if a symbol marked
+ N_UNDF | N_EXT is in the absolute section, move it to the
+ undefined section; move a symbol marked N_INDR into
+ bfd_ind_section and set the BSF_INDIRECT flag; set the
+ BSF_WARNING flag for a symbol makred N_WARNING.
+
+Mon Jan 17 15:40:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (ecoff_set_gp_prolog_size): Declare.
+ * ecoff.c (ecoff_set_gp_prolog_size): Return type is void.
+
+Mon Jan 17 00:18:55 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Explicitly check for comma before 'u'
+ and 'f' template operand.
+
+ * config/tc-hppa.c (pa_ip): Handle 'N', 'O', 'o', '0', '1', 'u',
+ and '2' in copr and sfu instruction templates.
+
+Sun Jan 16 16:44:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * as.h (subseg_force_new): Add prototype.
+
+Sat Jan 15 09:20:55 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * app.c (do_scrub_next_char): Allow lines like " foolab :".
+
+ * read.c (emit_expr): Fix computation of mask.
+ * config/obj-elf.c (obj_elf_section): Fix loop termination test.
+
+Thu Jan 13 16:15:15 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ecoff.c (ecoff_set_gp_prolog_size): New function.
+ (current_file_idx): New static variable.
+ (add_file): Use and increment current_file_idx instead of indx
+ parameter.
+
+ * struc-symbol.h (struct symbol): Make all bitfields unsigned.
+
+ * config/tc-i960.c (i960_validate_fix): Added argument
+ add_symbolPP. Indirect through it to get "add_symbolP".
+ * config/tc-i960.h (i960_validate_fix): Supply prototype.
+ (TC_VALIDATE_FIX): Pass address of add_symbolP.
+
+ * configure.in (i386-*-netbsd*): New target, using te-netbsd.h.
+ (i386-*-netbsd0.8): New target, like 386bsd.
+
+ * configure.in: Set BFDDEF in Makefile to "define" or "undef".
+ * Makefile.in (config.h): Protect against multiple inclusions.
+ Define or undef BFD_ASSEMBLER as specified by $(BFDDEF).
+ (ALL_CFLAGS): Omit $(BFDDEF).
+ * as.h: Include config.h.
+ (struct symbol): Added forward declaration.
+ (add_to_literal_pool): Fix declaration.
+ * as.c: Don't include config.h.
+
+ * literal.c (add_to_literal_pool): Take symbol and addend as
+ arguments, instead of expression, for now. Fix calculation of
+ offset to return.
+
+ * subsegs.h (segment_info_type) [NEED_LITERAL_POOL]: Add field
+ literal_pool_size.
+
+Thu Jan 13 12:14:21 1994 Jeffrey A. Law (law@snake.cs.utah.edu
+
+ * subsegs.c (subseg_get): Accept new argument "force_new". If
+ set then a new segment is always created. All callers changed.
+ (subseg_force_new): New function. Similar to subseg_new, but
+ always force a new segment to be created.
+
+ * config/obj-som.c (som_frob_file): Call adjust_code_sections
+ for each section.
+ (adjust_code_sections): New function. Adjusts the VMA for all the
+ $CODE$ subspaces.
+
+ * config/tc-hppa.c (md_assemble): Also handle creating a fixup
+ for the unwind descriptors if a function's label follows the
+ .PROC and .ENTRY directives.
+ (pa_entry): Don't set BSF_FUNCTION for the label symbol here; it
+ is done elsewhere. Don't create a fixup for the unwind
+ descriptors if the function's label has not been defined yet.
+ (pa_proc): For SOM, place each procedure within a new $CODE$
+ subspace. Adjust the segment and frag for the associated
+ function label if it exists.
+
+Wed Jan 12 22:05:33 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_fix_struct): Add new "segment" field.
+ (hppa_fix_new): Initialize segment field.
+ (md_apply_fix): Do nothing for pc-relative fixup which involves
+ crossing a segment boundary.
+ (pa_procend): Undefine the current label after handling .PROC
+ and .PROCEND directives.
+ (dummy_symbol): Make type "symbolS *". Change references as
+ appropriate.
+
+Wed Jan 12 13:29:31 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (read_a_source_file): Cast array argument to unsigned
+ char.
+ * write.c (adjust_reloc_syms): Remove unused variable symseginfo.
+ (write_object_file): Don't define punt_it if it won't be used.
+ (fixup_segment): Don't define skip if it won't be used.
+
+ * config/tc-mips.h (TARGET_FORMAT): Define as mips_target_format.
+ (mips_target_format): Declare.
+ * config/tc-mips.c (mips_target_format): Define with appropriate
+ default definition.
+ (md_parse_option): If -EL or -EB is used, change byte_order and
+ mips_target_format as appropriate.
+
+Tue Jan 11 21:52:36 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * app.c (do_scrub_next_char): Another attempt to fix bugs
+ dealing with labels without colons (for HPPA and MRI).
+
+Tue Jan 11 17:01:06 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Truncate args to %hi/%lo to 32 bits.
+
+ * expr.c (integer_constant): Fix computation of too_many_digits.
+ Variable digit_2 renamed to start. Fix check for whether number
+ will fit in 32 bits.
+ * read.c (emit_expr): Use valueT instead of long.
+
+Tue Jan 11 13:01:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c: If TC_MIPS, include elf/mips.h.
+ (special_sections): Define.
+ (obj_elf_special_section): Get default types and attributes from
+ list of special sections.
+ * config/tc-mips.c (ELF_TC_SPECIAL_SECTIONS): Define.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Force .sdata and .sbss
+ sections to be close together.
+
+ * config/tc-mips.c (macro): Corrected $at warnings in a couple of
+ spots.
+
+ * listing.c (listing_prev_line): New function.
+ * listing.c: Include subsegs.h.
+ (listing_prev_line): New function.
+ (calc_hex): Reset byte_in_frag to zero for each new frag.
+ * config/tc-mips.c (append_insn): Call listing_prev_line after
+ emitting nop instructions.
+ * Makefile.in (listing.o): Depends upon subsegs.h.
+
+Mon Jan 10 09:52:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Put check for missing label on .PROC
+ here. Handle case where label may be defined after the .PROC.
+ (pa_proc): It is not an error if the procedure's label isn't
+ defined before the .PROC directive.
+
+Sun Jan 9 04:43:30 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/te-netbsd.h: New file.
+ * config/tc-i386.h (TARGET_FORMAT) [TE_NetBSD]: Use bfd target
+ a.out-netbsd-386 for this configuration.
+
+Fri Jan 7 17:38:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_stab): Don't clobber the ECOFF symbol information
+ with the associated stabs information.
+ (ecoff_build_symbols): Never set the type of stabs symbols to
+ st_Global. Don't update the symbol index or ifd if the gas symbol
+ is not the same as the ECOFF symbol (which is now the case for
+ stabs symbols).
+
+Fri Jan 7 11:14:07 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config/tc-mips.c (macro): Add a LOSING_COMPILER ifdef that
+ splits the function.
+ (macro2): New function, if LOSING_COMPILER defined.
+
+Fri Jan 7 09:38:25 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): Don't ever fill past the
+ end of a section. (write_object_file): Temporary fix - setup
+ stdoutput.
+
+Thu Jan 6 18:05:21 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Fix handling of addends in
+ non-pcrel_offset relocations.
+
+Thu Jan 6 01:06:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Warn about using $1 as well as $at
+ without .set noat.
+
+Wed Jan 5 14:22:22 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * literal.c: New file.
+ * Makefile.in (REAL_SOURCES, OBJS): List it.
+
+ * as.h (DEBUG): Don't define.
+ (struct expressionS, struct fix): Declare in case they're used in
+ prototypes.
+ (add_to_literal_pool) [BFD_ASSEMBLER]: Declare.
+
+ * config/tc-mips.h (TARGET_FORMAT) [OBJ_AOUT]: Fix for new names
+ in bfd.
+
+ * subsegs.c (subseg_get): New function. Creates segment if
+ needed, returns pointer, but doesn't change current segment.
+ (subseg_new): Use it.
+
+Tue Jan 4 15:12:43 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (INCLUDES): Add $(srcdir)/.. to places to search.
+ * config/obj-ecoff.c: Include files as "bfd/" instead of "../bfd/".
+ * app.c, flonum.h, hex-value.c (const): Change #if to be more
+ portable.
+
+Tue Jan 4 22:11:34 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * config/ho-vsta.h, configure.in: Add support for VSTa
+ micro-kernel.
+
+Thu Dec 30 15:27:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (write_relocs): bfd_perform_relocation now takes an
+ additional argument, to return an error string (which we ignore).
+
+Wed Dec 29 14:37:26 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.h (struct fix): Field tc_fix_data should be type PTR, not
+ void*, for compatibility with non-ANSI compilers. Added
+ single-bit field "fx_done".
+
+Sun Dec 26 14:31:47 1993 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * tc-hppa.c (pre_defined_registers): Convert to lower case.
+ Delete spurious register names "%r4L", etc.
+ (selector_table): Sort and convert to lower case.
+ (cons_fix_new_hppa): `reloc_type' => `rel_type'.
+ (pa_ip): Always use strcmp for non-text and strcasecmp for text.
+ (reg_name_search): Rewrite to call strcasecmp only once per
+ iteration.
+ (pa_chk_field_selector): Rewrite to use binary search.
+ (pa_parse_neg_add_cmpltr): Use strcasecmp for completer comparisons.
+ (pa_parse_space_stmt): $TEXT$ and $PRIVATE$ are symbols; use case
+ sensitive comparisons.
+ (pa_parse_space_stmt): Canonicalize strncasecmp arg to lower case.
+ (pa_space): "$text$" => "$TEXT$"; "$private$" => "$PRIVATE$". Use
+ case sensitive comparison for all symbolic names.
+ (pa_subspace): Canonicalize strncasecmp arg to lower case.
+ (pa_subspace_start): Use case sensitive comparison for symbolic names.
+
+Mon Dec 20 10:37:48 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * write.c (adjust_reloc_syms) [RELOC_REQUIRES_SYMBOL]: If no
+ symbol is present (i.e., relocation against absolute), create a
+ phony local symbol, and use it in the reloc.
+ (fixup_segment): When adjusting a reloc with an absolute symbol,
+ have TC_FORCE_RELOCATION control clearing add_symbolP too.
+ * config/tc-sparc.h (RELOC_REQUIRES_SYMBOL): Define, for OBJ_COFF.
+
+ * symbols.c (S_IS_EXTERNAL, S_IS_LOCAL): Don't use both BSF_EXPORT
+ and BSF_GLOBAL, since they're the same.
+
+ * as.c (main): Only invoke md_end if it's defined as a macro.
+ * tc.h (md_end): Don't declare it.
+ * config/tc-*.[ch] (md_end): Deleted, in cases where it doesn't do
+ anything.
+ * config/tc-vax.c (vip_end): Deleted null function.
+ * config/tc-mips.c (md_mips_end): Renamed from md_end.
+ * config/tc-mips.h (md_mips_end): Declare.
+ (md_end): New macro, calls md_mips_end.
+
+ * write.c (write_object_file): Don't close output file.
+ * as.c (main): Close output file (if needed) after calling
+ listing_print, which should be after calling write_object_file,
+ which sets the frag addresses.
+
+ * config/obj-coff.c (obj_coff_dim, obj_coff_endef, obj_coff_line,
+ obj_coff_scl, obj_coff_size, obj_coff_tag, obj_coff_type,
+ obj_coff_val): Add unused int argument to satisfy prototypes; goes
+ with Ian's 10 Sep changes.
+ (S_GET_DATA_TYPE, S_SET_DATA_TYPE, S_GET_STORAGE_CLASS,
+ S_SET_STORAGE_CLASS): Now function instead of macros.
+ (obj_emit_lineno) [BFD_ASSEMBLER]: Deleted.
+ (tag_insert): Local var ERROR_STRING is const. Use "const" not
+ "CONST" for argument NAME. Fixed prototype.
+ (coff_frob_symbol): Removed explicit "#if 1" directive. If
+ S_IS_EXTERNAL, set storage class to C_EXT.
+ (s_get_name): Use "const" not "CONST".
+ * config/obj-coff.h (S_GET_DATA_TYPE, S_SET_DATA_TYPE,
+ S_GET_STORAGE_CLASS, S_SET_STORAGE_CLASS): Deleted.
+ (obj_emit_lineno): Declare only for non-BFD_ASSEMBLER. For
+ BFD_ASSEMBLER, define as macro that aborts.
+ (obj_extra_stuff, tc_headers_hook): Declare only for
+ non-BFD_ASSEMBLER.
+ (coff_frob_symbol): Fix prototype.
+
+Sun Dec 19 00:37:20 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Test of pcrel_offset had sense
+ reversed.
+
+Thu Dec 16 21:13:11 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_begin): Initialize "dummy_label".
+ (tc_gen_reloc, SOM version): For relocations which have no symbol,
+ set sym_ptr_ptr to dummy_label. Avoids lossage in generic BFD code.
+
+Thu Dec 16 16:07:56 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * read.c (lex_type): No longer make '[' a valid character for
+ symbol names.
+
+ * config/tc-vax.c (tc_aout_fix_to_chars): Local variable
+ NBYTES_R_LENGTH now const.
+
+ * config/obj-*.c, config/tc-*.c: Omit superfluous "return"
+ statements at ends of functions. Don't check for null return from
+ hash_new, since it won't return at all if there's no memory
+ available. Also, check for null return from hash_insert, rather
+ than zero-length string, as success indicator.
+
+ * subsegs.c (section_symbol): New function.
+ * subsegs.h (section_symbol): Declare.
+ * write.c (adjust_reloc_syms): Use it.
+
+Wed Dec 15 15:39:53 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (RUNTEST): New variable.
+ (CHECKFLAGS): Pass it down.
+
+ * ecoff.c (ecoff_directive_frame): Permit extra trailing operands;
+ unused for now, but supplied by Alpha OSF1 compiler.
+
+ * as.h: Protect against multiple inclusions.
+ (int_to_gen): Don't declare.
+
+ * config/atof-vax.c (atof_vax): NULL is not a valid character
+ constant.
+
+Tue Dec 14 21:38:25 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-osf*): Do not consider this a developmental
+ configuration.
+
+ * config/tc-hppa.c (md_apply_fix): Handle cases where no
+ relocation will be emitted for 32bit formats.
+
+Mon Dec 13 23:33:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Do not call hppa_field_adjust
+ for any of the 'T' field selectors.
+
+Sat Dec 11 11:23:12 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-h8500.c (build_bytes): Get reloc type right for a
+ %page operation. (md_assemble): Don't modify input_line_pointer.
+ (mdcoff_sizemachdep): New function.
+ * config/tc-h8500.h (TC_COFF_SIZEMACHDEP): New macro.
+ * config/tc-z8k.c (get_operand): Delete bogus check.
+
+Wed Dec 8 16:31:51 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * write.c (number_to_chars_*): Delete bogus range check.
+
+ * output-file.c (TARGET_ARCH): No default.
+
+Tue Dec 7 16:02:53 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-sh.c (md_convert_frag): Truncate disps before calling
+ md_number_to_chars. (md_assemble): Don't modify
+ input_line_pointer.
+
+Mon Dec 6 11:49:03 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-h8300.c (md_assemble): Don't update input_line_pointer.
+
+Mon Dec 6 11:20:02 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.[ch] (obj_read_begin_hook): Remove last change.
+ Breaks with the HP compilers.
+
+ * config/tc-hppa.c (struct call_info): Remove fields which were
+ set but never used. Remove all code which sets those fields.
+ (struct subspace_dictionary_chain): Likewise.
+ (struct space_dictionary_chain): Likewise.
+ (pa_desc): Delete useless function. Delete all references.
+ (hppa_tc_make_sections): No need to count the number of symbols for
+ the symbol extension section.
+
+Sun Dec 5 17:05:29 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.c (obj_som_version): Pass version string to
+ SOM BFD backend.
+ (obj_som_copyright): New function. Much like obj_som_version.
+
+ * config/tc-hppa.c (obj_copyright): Define as appropriate for
+ SOM and ELF.
+ (pa_copyright): Just a stub now.
+
+ * config/obj-som.c (obj_read_begin_hook): Delete unused function.
+ * config/obj-som.h (obj_read_begin_hook): Provide dummy definition.
+ (TARGET_SYMBOL_FIELDS): Delete. SOM isn't making use of them.
+
+ * config/tc-hppa.c (tc_gen_reloc, SOM version): Handle relocation
+ expansion due to rounding mode selectors. Handle R_[RDSN]_MODE
+ relocations for selecting the current rounding mode.
+
+ * config/tc-hppa.c (evaluate_absolute): Support e_rrsel and
+ e_rlsel field selectors.
+
+Fri Dec 3 18:33:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.h: If ECOFF_DEBUGGING, undef
+ SEPARATE_STAB_SECTIONS and INIT_STAB_SECTION, and define
+ OBJ_PROCESS_STAB to call ecoff_stab.
+ * config/obj-elf.c: Don't compile obj_elf_init_stab_section if
+ INIT_STAB_SECTION is not defined.
+
+Fri Dec 3 10:56:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_apply_fix): Delete old wrapper function.
+ (md_apply_fix_1): Rename to md_apply_fix. Fix argument decls.
+ Fix comments in various places. Always return a value.
+ Avoid dereferencing a NULL fx_addsy.
+ (hppa_force_relocation): Avoid dereferencing a NULL fx_addsy.
+
+ Fri Dec 3 09:47:30 1993 Pete Hoogenboom (hoogen@cs.utah.edu)
+
+ * tc-hppa.c: (tc_gen_reloc): Addend for a plabel relocation should
+ be either 0 or 2 (no static link or static link required). Always
+ assume no static link.
+
+Thu Dec 2 11:52:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-sparc.c (tc_gen_reloc): Make adjustment to addend be
+ dependent on howto fields, not on format flavour.
+
+ * struc-symbol.h (struct symbol): New fields sy_obj and sy_tc,
+ defined as types OBJ_SYMFIELD_TYPE and TC_SYMFIELD_TYPE, if those
+ macros are defined.
+ * config/obj-coff.h (TC_SYMFIELD_TYPE, OBJ_SYMFIELD_TYPE): Define.
+ (TARGET_SYMBOL_FIELDS, I960_SYM_FIELDS): Don't define.
+ (sy_tc, sy_obj): Define so that the fields look like they used to,
+ until all references get changed.
+
+ * write.c (fixup_segment): Lots of variables no longer register.
+ Reordered some code for easier reading.
+ * config/obj-coff.c (obj_coff_dim): dim_index no longer register.
+ Deleted superfluous return statement.
+ (obj_coff_line, obj_coff_size, obj_coff_scl, obj_coff_type,
+ obj_coff_val, tag_init, tag_insert): Deleted superfluous return
+ statement.
+ (align, obj_coff_section): Deleted debugging printfs.
+ * config/tc-i386.c (md_assemble): Discard some register decls.
+ Use assignment rather than memcpy to copy template.
+ (op_hash, reg_hash, prefix_hash): Default C initialization of
+ statics is sufficient.
+ * config/tc-sparc.c (print_insn): Array Reloc is now const, and
+ points to const.
+
+ * config/obj-coff.h (TARGET_FORMAT): Only use coff-sparc-lynx if
+ TE_LYNX; use coff-sparc otherwise.
+ [USE_NATIVE_HEADERS]: Delete this code; it isn't used.
+
+ * write.c (fixup_segment): Call TC_VALIDATE_FIX, if defined,
+ before processing a fixup. Call TC_ADJUST_RELOC_COUNT just before
+ returning. Remove some i960-coff-specific code.
+ (TC_ADJUST_RELOC_COUNT): Default to doing nothing.
+ * config/tc-i960.h (TC_ADJUST_RELOC_COUNT) [OBJ_COFF]: Define.
+ (i960_validate_fix): Declare.
+ (TC_VALIDATE_FIX): Define.
+ * config/tc-i960.c (i960_validate_fix): New function.
+
+ * write.c (number_to_chars_littleendian): New function. Write out
+ bytes in little endian order, doing size and range checking.
+ (number_to_chars_bigendian): New function, similar.
+ * write.h: Declare them.
+ * config/tc-*.c (md_number_to_chars): Use them.
+ * config/tc-vax.c (md_apply_fix): Ditto.
+ * config/tc-i386.c (md_apply_fix): Ditto.
+
+ * config/obj-coff.c: Rearranged code for handling line number
+ data.
+ (line_fsym): Renamed from function_lineoff in BFD_ASSEMBLER case,
+ since the usage is different from non-BFD_ASSEMBLER case.
+ (in_function, clear_function, set_function): New macros, to
+ combine some of the functionality implemented in differnet ways in
+ BFD_ASSEMBLER and non-... code. Used in other functions that used
+ to check function_lineoff &c.
+ (obj_emit_lineno): Split into two copies, one for BFD_ASSEMBLER,
+ one for not. Non-BFD_ASSEMBLER version now has temporary variable
+ to contain char* pointer pointed to by char** argument. Always
+ follow CROSS_COMPILE code; easier to read that way.
+ (obj_coff_ln): Don't call add_lineno or c_line_new if appline is
+ set.
+ (obj_coff_endef) [BFD_ASSEMBLER]: Don't do anything special for
+ ".bf", it's been done elsewhere.
+ (coff_frob_symbol): If ilne number data is pending, call
+ add_linesym to flush it.
+ (coff_frob_file): Don't do that here.
+ * config/obj-coff.h (coff_frob_file): Declare.
+ (obj_frob_file): Define, to call it.
+
+ * config/tc-sparc.h (md_create_short_jump, md_create_long_jump,
+ md_estimate_size_before_relax: Define them as macros calling
+ as_fatal.
+ * config/tc-sparc.c: Don't define them as functions.
+
+ * configure.in: Handle target alpha-*-osf*. (No cpu files yet.)
+
+Wed Dec 1 23:37:14 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile (clean): Depend on clean-here.
+
+Wed Dec 1 11:35:21 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/ho-go32.h: Include fopen-bin.h.
+ * as.h: If FOPEN_WB isn't defined, include fopen-same.h.
+ * output-file.c (output_file_create): Use FOPEN_WB instead of "w".
+ * input-file.c (input_file_open): Use FOPEN_RT instead of "r".
+ * listing.c (file_info): Use FOPEN_RB instead of "rb".
+ * read.c (s_include): Use FOPEN_RT instead of "r".
+
+ * stabs.c: Include obstack.h.
+
+ * tc.h (md_create_long_jump): Don't declare if it's already
+ defined as a macro.
+ (md_create_short_jump, md_estimate_size_before_relax): Ditto.
+
+ * messages.c (as_perror) [BFD_ASSEMBLER]: Use bfd_errmsg instead
+ of strerror. Clear bfd_error.
+
+ * config/te-lynx.h (LOCAL_LABELS_FB): Define, if not already
+ defined.
+
+Wed Dec 1 10:41:56 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_elf_mark_end_of_function): New function.
+ (pa_process_exit, pa_procend): Call it for ELF objects.
+
+Wed Dec 1 12:10:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro): Subtract 8 from offset in non PIC l.d
+ case. See comment. From wilson@cygnus.com: for M_L_DAB, set
+ coproc before doing goto ld.
+
+Tue Nov 30 13:40:30 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * write.c (TC_FORCE_RELOCATION): Provide a default definition.
+ (fixup_segment): Allow the target machine to specify that a
+ relocation must be generated for a particular fixup. Remove
+ #ifndef TC_HPPA hack.
+
+ * config/tc-hppa.h (TC_FORCE_RELOCATION): Define.
+
+ * config/tc-hppa.c (md_apply_fix_1): Never change fx_addsy to
+ be NULL. Only fixup_segment is supposed to do that.
+ (hppa_force_relocation): New function.
+
+Tue Nov 30 11:21:41 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (stabs.o): Added dependencies.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Don't call bfd_set_symtab.
+
+Sun Nov 28 12:11:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * app.c (do_scrub_next_char): Output a TAB before any
+ .app* directive.
+
+ * config/tc-hppa.c (fix_new_hppa): Make sure a sub_symbol
+ exists before trying to peek at its name.
+ (pa_space): Do not call pa_align_subseg. See hppa/unsorted/align3.s
+ for testcase.
+ (pa_align_subseg): Delete unused/unwanted function.
+
+Sat Nov 27 22:49:07 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * read.c (read_a_source_file): Fix test for when to stick a colon
+ on the end of a label. Make code conditional on either MRI or
+ LABELS_WITHOUT_COLONS.
+
+ * app.c (do_scrub_next_char): If a line begins with whitespace, leave
+ the single whitespace character alone. Eat all others.
+
+ * config/tc-hppa.h (LABELS_WITHOUT_COLONS): Define.
+
+Wed Nov 24 01:22:54 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_procend): Do not call process_exit.
+ (exit_processing_complete): Delete unwanted variable and all
+ references.
+
+Wed Nov 24 02:31:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.c (ecoff_setup_ext): Renamed from ecoff_build_ext.
+ Changed to not actually build the external symbol information, as
+ that is now done by the ECOFF back end.
+ (ecoff_build_debug): Changed accordingly.
+ * ecoff.h (obj_ecoff_set_ext): Declare. obj-format.c function
+ called by ecoff_setup_ext.
+ * config/obj-ecoff.c (ecoff_frob_file): If debug_info count is 0,
+ set corresponding pointer to NULL. Don't set raw_size and
+ raw_syments.
+ (obj_ecoff_set_sym_index): Removed.
+ (obj_ecoff_set_ext): New function.
+ * config/obj-ecoff.h (obj_set_sym_index): Don't define.
+ (obj_ecoff_set_sym_index): Don't declare.
+ * config/obj-elf.c (obj_ecoff_set_ext, elf_get_extr,
+ elf_set_index): New functions used for ECOFF_DEBUGGING.
+ (elf_frob_file): Reworked ECOFF debug generation to use
+ new functions in bfd/ecofflink.c.
+
+Sun Nov 21 23:54:52 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_def_subspaces): Only create the unwind
+ subspace for ELF. In the SOM world, the linker is responsible
+ for creating the unwind subspaces.
+
+Fri Nov 19 16:25:09 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-coffbfd.c: Use PARAMS rather than EXFUN.
+ (yank_symbols): Don't call S_SET_EXTERNAL if the storage class is
+ already set. Fixes .def var; .val external_var; .scl 3; .endef.
+ (adjust_stab_section): Make static. Declare return type. Remove
+ unused variables.
+
+ * config/tc-i386.h: Declare tc_coff_fix2rtype and
+ tc_coff_sizemachdep.
+
+Fri Nov 19 04:33:59 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_object_file): Disable obj_check_file_symbols
+ hook; only back end using it wasn't using it correctly.
+ (write_object_file): Always call obj_frob_symbol and
+ tc_frob_symbol; always retain symbol if it's used by a relocation,
+ regardless of what these routines indicate.
+ * config/obj-coff.c (coff_frob_symbol): Renamed from
+ coff_check_file_symbols.
+ * config/obj-coff.h (obj_check_file_symbols): Deleted.
+ (coff_frob_symbol): Declare.
+ (obj_frob_symbol): Call it.
+
+ * config/obj-coff.c (obj_crawl_symbol_chain, obj_emit_strings,
+ obj_pre_write_hook): Don't define for BFD_ASSEMBLER.
+ (c_section_header): Ditto. Delete superfluous return at end of
+ function.
+
+ * config/obj-coff.h [TC_SPARC]: Include coff/sparc.h, and specify
+ coff-sparc-lynx.
+ (SA_GET_SYM_TAGNDX): Use BFD_HEADERS version for BFD_ASSEMBLER
+ too.
+ (c_section_header): Rewrite prototype so that it contains no
+ preprocessing directives. Don't declare it at all if
+ BFD_ASSEMBLER.
+
+ * configure.in (sparc*-*-lynxos): New target, using coff and
+ BFD_ASSEMBLER.
+
+ * stabs.c: New file.
+ * Makefile.in (REAL_SOURCES, OBJS): List it.
+ * read.c (STAB_SECTION_NAME, STAB_STRING_SECTION_NAME,
+ get_stab_string_offset, s_stab_generic, s_stab, s_xstab, s_desc):
+ Moved to new file.
+
+ * config/tc-sparc.c (tc_gen_reloc): Handle coff files like elf
+ files.
+
+Wed Nov 17 17:23:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (mips-*-irix5*): New target. Use elf and mips-big.
+ * config/obj-elf.c: If ECOFF_DEBUGGING, include ecoff.h.
+ (obj_pseudo_table): If ECOFF_DEBUGGING, define ECOFF
+ pseudo-ops.
+ (obj_read_begin_hook): If ECOFF_DEBUGGING, call
+ ecoff_read_begin_hook.
+ (obj_symbol_new_hook): If ECOFF_DEBUGGING, call
+ ecoff_symbol_new_hook.
+ (obj_elf_init_stab_section): Cast alloca result.
+ (elf_frob_file): If ECOFF_DEBUGGING, finish up ECOFF debugging
+ information and write it out into .mdebug section.
+ * config/obj-elf.h (ELF_TARGET_SYMBOL_FIELDS): New macro.
+ (TARGET_SYMBOL_FIELDS): Use ELF_TARGET_SYMBOL_FIELDS.
+ (ECOFF_DEBUGGING): Define if TC_MIPS.
+ (TARGET_SYMBOL_FIELDS): If ECOFF_DEBUGGING, override to add
+ fields required by ECOFF.
+ * config/tc-mips.c: Check ECOFF_DEBUGGING rather than
+ OBJ_ECOFF in many cases.
+ (mips_any_noreorder): New variable.
+ (mips_cprestore_offset): Initialize to -1.
+ (mips_frame_reg): New variable.
+ (RELAX_ENCODE, RELAX_OLD, RELAX_NEW, RELAX_RELOC1,
+ RELAX_RELOC2, RELAX_RELOC3, RELAX_WARN): New macros.
+ (md_pseudo_table): Handle "gpword" and "cpadd".
+ (md_begin): Initialize ok to false. If OBJ_ELF, set alignment
+ of text, data and bss sections to 4. Set alignment of
+ .reginfo section to 2. If ECOFF_DEBUGGING, create .mdebug
+ section.
+ (ALIGN_ERR, ALIGN_ERR2): Removed unused and useless alignment
+ check.
+ (append_insn, macro_build, macro_build_lui): Take place
+ argument. Changed all callers.
+ (append_insn): If appending a nop, don't emit one.
+ (macro_build): Changed assertion for 'i', 'j', 'o' case.
+ (gp_reference): Removed.
+ (load_address): New function.
+ (macro): If mips_noreorder is used, set mips_any_noreorder.
+ Extensive changes to handle GP and PIC symbols differently.
+ Build both possible code choices using a variant frag, and
+ make a final decision at the end of assembly when all
+ information is known. Added PIC support for all symbol
+ references.
+ (mips_ip): Don't permit anything but a number after $ for a
+ coprocessor register. Don't use .lit4 or .lit8 sections when
+ generating PIC code. If OBJ_ELF, set alignment of .lit4 or
+ .lit8 section to 4.
+ (md_apply_fix): Accept and ignore GOT16 and GPREL32 relocs.
+ (s_change_sec): Set alignment of ELF .rodata or .sdata section
+ to 4.
+ (s_mipsset): If .set noreorder, set mips_any_noreorder.
+ (s_cpload): Ignore .cpload if not generating PIC code. Warn
+ if .cpload is not in noreorder section.
+ (s_cprestore): Ignore .cprestore if not generating PIC code.
+ (s_gpword, s_cpadd): New functions.
+ (tc_get_register): Added frame argument; if true, set
+ mips_frame_reg to return value. Changed all callers.
+ (md_estimate_size_before_relax): Don't error out, but instead
+ determine how much a frag should grow.
+ (tc_gen_reloc): Return multiple relocs if appropriate, as
+ determined by md_estimate_size_before_relax.
+ (md_convert_frag): New function.
+ (mips_elf_final_processing): Set ELF header flags based on
+ mips_any_noreorder and mips_pic.
+ * config/tc-mips.h (RELOC_EXPANSION_POSSIBLE): Define.
+ (MAX_RELOC_EXPANSION): Define to be 3.
+ (md_relax_frag): Define to be 0.
+ (md_convert_frag): Don't define.
+ (tc_get_register): Changed declaration.
+
+ * ecoff.h, ecoff.c: New files pulled out of config/obj-ecoff.c to
+ support generating ECOFF debugging information for MIPS ELF
+ targets. Compiled only if ECOFF_DEBUGGING is defined. Changed
+ handling of external symbols: it now always generates exactly
+ those external symbols that are defined in the global symbol list.
+ * Makefile.in (REAL_SOURCES): Added ecoff.c.
+ (REAL_HEADERS): Added ecoff.h.
+ (OBJS): Added ecoff.o.
+ (ecoff.o): New target.
+ * config/obj-ecoff.c: Almost entirely moved into ecoff.c.
+ Remaining code mostly just calls ecoff.c code.
+ * config/obj-ecoff.h: Define ECOFF_DEBUGGING.
+ (TARGET_SYMBOL_FIELDS): Make ecoff_symbol a pointer to a
+ struct localsym.
+ (obj_read_begin_hook, obj_symbol_new_hook): Define to call
+ functions in ecoff.c.
+ (ecoff_stab): Don't declare (now declared in ecoff.h).
+ (obj_set_sym_index): Define.
+ (obj_ecoff_set_sym_index): Declare.
+
+ * frags.h (frag_grow): Declare.
+ * frags.c (frag_grow): Made non-static.
+
+ * write.c (is_dnrange): Do not define if md_relax_frag is defined.
+ (relax_segment): If md_relax_frag is defined, use it to handle a
+ frag of type rs_machine_dependent rather than looking through
+ md_relax_table.
+
+ * read.c (read_a_source_file): If we find a bad pseudo-op,
+ do a continue to go on to the next line rather than a break.
+ Removed duplicate bad pseudo-op code which was never executed.
+
+ * read.c (s_lcomm): Do not require a comma after the name.
+
+ * subsegs.h (segment_info_type): Changed hadone field to bitfield.
+ Added bss bitfield.
+ * as.c (perform_an_assembly_pass): Set bss flag for bss_section.
+ * read.c (s_lcomm): Set bss flag for .sbss section if used.
+ * write.c (relax_and_size_seg): Don't set SEC_HAS_CONTENTS for a
+ bss section. Set SEC_RELOC if there are any relocations, even for
+ a zero size section.
+
+ * write.c (write_relocs): In RELOC_EXPANSION_POSSIBLE case, base
+ data offset on reloc[0]->address rather than reloc[j]->address, so
+ that multiple relocs can affect different memory locations.
+
+ * write.c (chain_frchains_together, relax_and_size_seg,
+ adjust_reloc_syms, write_relocs): Make third argument PTR, not
+ char *, to match definition of bfd_map_over_sections.
+
+ * app.c (do_scrub_next_char): Don't interpret a comment character
+ as starting a CPP line directive unless it is a '#' and is the
+ very first characters on the line (i.e., do not permit leading
+ whitespace).
+
+ * messages.c (identify): Make file argument non-const, to match
+ callers.
+
+Tue Nov 16 20:38:21 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_ip): Fix thinko in 21bit range check.
+
+Sat Nov 13 18:22:48 1993 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * config/tc-sh.c (md_apply_fix): Cope with IMM16 type too.
+ * config/tc-z8k.c (build_bytes, md_apply_fix): Understand nDISP7
+ relocs.
+
+Fri Nov 12 16:51:47 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.[ch]: Fix assorted trivial indention problems.
+ * config/obj-som.c (obj_som_version): Add missing ';'.
+ (som_frob_file): Delete whitespace at EOL.
+
+Fri Nov 12 15:26:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (VERSION): Updated following 2.2 release.
+
+Fri Nov 12 14:52:17 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (hppa_fix_struct): Use a real type for the
+ field selector, rather than an int. All uses of field selectors
+ fixed.
+ (tc_gen_reloc): For SOM PLABELs, always set addend to zero for now.
+ (md_apply_fix_1): Do not call hppa_field_adjust for any PLABEL
+ field.
+
+ Thu Nov 11 15:49:08 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (pa_type_args): For .import statements,
+ silently ignore attempt to change the symbol type for a function
+ from ST_ENTRY to ST_CODE on .import.
+
+Wed Nov 10 16:19:13 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.h (fixS): Rename fx_callj field to fx_tcbit.
+ * write.c, config/obj-coff.c, config/obj-coffbfd.c,
+ config/tc-i960.c: Corresponding changes.
+
+Tue Nov 9 00:49:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (distclean): Delete config-stamp and config.h
+
+ * config/tc-hppa.c (evaluate_absolute): Avoid relying on
+ ANSI-C features.
+
+ * config/tc-hppa.c (pa_type_args): Renamed from pa_export_args.
+ Accept new argument "is_export". All callers changed. When
+ processing a .export directive for a function, do not allow
+ the user to set the type to "CODE", instead warn and set the
+ type to "ENTRY".
+
+Mon Nov 8 12:05:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip, printInsn): Handle 'k' (from Ted
+ Lemon <mellon@pepper.ncd.com>).
+ (mips_ip): Permit odd numbered floating point registers if -mips3.
+ (macro): Use BFD_RELOC_MIPS_LITERAL relocation for M_LI_SS.
+
+Mon Nov 8 07:45:01 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Remove h8300h, we have multilib now.
+
+Mon Nov 8 06:09:18 1993 D. V. Henkel-Wallace (gumby@cirdan.cygnus.com)
+
+ * configure.in: Support generic netware as being ELF format.
+ Recognise unixware if the user supplies it.
+
+Sun Nov 7 01:02:08 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * First cut at cleaning up PA instruction parsing.
+ * config/tc-hppa.c (pa_get_absolute_expression): Accept pointer to
+ insn structure as an argument, and a pointer to a string. All
+ callers changed. Always read any field selector here. Call
+ evaluate absolute to get a return value.
+ (evaluate_absolute): Addept pointer to insn structure as its
+ argument. All callers changed.
+ (INSERT_FIELD_AND_CONTINUE): New macro for inserting a bitfield
+ into an instruction and continuing the main pa_ip loop.
+ (CHECK_FIELD): New macro for simple range checking of fields.
+ (pa_ip): Delete unused variables. Use INSERT_FIELD_AND_CONTINUE
+ and CHECK_FIELD. All immediate fields now pass through
+ pa_get_absolute_expression which will also handle field selectors.
+ Delete dead code. Simplify.
+ (md_apply_fix_1): Use CHECK_FIELD to verify any fixes that are
+ applied are in range. Use bfd_put_32 rather than inserting each
+ byte of the fixed instrution into the buffer ourselves.
+
+ * write.c (fixup_segment): Delete {SEG,GLOBAL}_DIFF_ALLOWED code,
+ it was PA specific and is no longer needed (it's now handled
+ within the PA backend).
+ * config/tc-hppa.h (SEG_DIFF_ALLOWED): Delete definition.
+ * config/tc-hppa.c (fix_new_hppa): If the subtract symbol for
+ a fixup is $global$ change it to NULL as $global$ is really only
+ needed long enough to determine the base type of relocation to use.
+
+ * config/tc-hppa.c (create_new_subspace): Initialize subspace_defined.
+
+ * config/tc-hppa.c (pa-ip, case 'z'): Make field selectors work
+ for 'z' operands (target of ble branch).
+
+Sat Nov 6 22:41:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c: (update_subspace): Fix type and name of last
+ parameter. All callers fixed.
+ (md_begin, pa_chk_field_selector, pa_entry): Lint.
+
+ * config/tc-hppa.c (cons_fix_new_hppa): Reset field selector
+ to default state after it's been used.
+
+Fri Nov 5 12:08:21 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.c (obj_som_init_stab_section): Change
+ space/subspace sort keys for the stab sections so as to avoid
+ bugs in the hp linker and pxdb.
+
+Thu Nov 4 17:00:05 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * write.c (chain_frchains_together): Update pointer to last
+ frag for a segment in the seginfo structure.
+
+Thu Nov 04 09:09:35 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Changed RUNTESTFLAGS to RUNTEST_FLAGS
+
+Wed Nov 3 12:16:27 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * write.c (fixup_segment): Handle conversion of subtraction to
+ pc-relative addressing even if pc-relative flag is already set.
+
+ * config/tc-m68k.c (m68k_ip_op): Use strchr, not index. Don't
+ declare either.
+
+ * doc/Makefile.in (distclean): Delete intermediate files from dvi
+ build, but not the dvi or info files.
+ * Makefile.in (clean-here): New target; cleans up current
+ directory only.
+ (distclean): Use it instead of clean.
+
+ * read.c (s_xstab): Don't use alloca.
+
+ * messages.c (identify): New routine; print message identifying
+ following messages as coming from assembler.
+ (as_show_where, as_bad_internal, as_bad_where): Call it.
+ (as_fatal): Don't need to identify program any more.
+
+Tue Nov 2 18:04:11 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Add default case to reloc switch.
+
+ * read.c (s_lcomm): Put small objects in .sbss for MIPS ELF as
+ well as MIPS ECOFF.
+ (get_stab_string_offset): Remove unused variable aligned.
+
+Tue Nov 2 15:07:07 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * tc-hppa.c: Add %dp and %rp as synonyms for %r27 and %r2 in the
+ predefined register table.
+ (pa_parse_number): Handle %rp in common register shortcut code.
+ Consistently set return value to -1 for an error. Clean up error
+ messages and only print them when "print_errors" is true. Handle
+ empty string case like the HP assembler -- assume a value of
+ zero.
+
+ * config/ho-hpux.h: Do not include ho-sysv.h. Instead include
+ standard hpux include files to pick up various function decls.
+
+ * config/ho-hppaosf.h: Delete _IO* macros. They are defined in
+ stdio.h. Delete bogus declaration of free. Get path to
+ alloca-conf.h right.
+
+Tue Nov 2 13:57:30 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * expr.c (operand): Fix checks for characters following "0b" or
+ "0f".
+
+Mon Nov 1 21:37:04 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/obj-som.h (obj_attach_unwind_info): Define as a hook
+ so GAS can attach unwind descriptor information to a BFD symbol.
+ * config/tc-hppa.c (fix_new_hppa): If necessary attach unwind
+ descriptor information to the BFD symbol.
+ (md_apply_fix): R_HPPA_ENTRY and R_HPPA_EXIT can never be "applied",
+ they are simply markers. Make R_HPPA_UNWIND_* handling OBJ_ELF
+ dependent.
+ (pa_build_unwind_subspace): Whole function is OBJ_ELF dependent.
+ (pa_entry): Build a R_HPPA_ENTRY relocation when configured for SOM.
+ (pa_exit): Likewise, but built a R_HPPA_EXIT relocation. Do not
+ build "end-of-function" symbols for SOM, they are not needed.
+
+ * config/tc-hppa.c (process_exit): Create temporary symbols with
+ correct prefixes so they can be eliminated later.
+
+ * config/tc-hppa.c (call_info struct): Delete unused "frame" field.
+ (pa_callinfo): Insert framesize into the unwind information as
+ soon as it's available.
+ (pa_build_unwind_subspace): Do not insert framesize into the unwind
+ information here.
+
+ * Add support for marker type relocations. These mark areas
+ of interest to the linker. ENTRY/EXIT relocations for SOM are
+ an example of marker relocations.
+ * write.c (write_relocs): Instead of assuming size of a relocation
+ is 4 bytes, pick up the size from relocation itself.
+ (fixup_segment): Do not complain that a value is too small for
+ marker relocations.
+
+ * struc-symbol.h: Add new "sy_used" field to the symbol structure.
+ * expr.c (operand): Set sy_used for any symbol used as an operand.
+ (expr): Likewise for any symbol used in an expression.
+ * config/tc-hppa.h (tc_frob_symbol): Define. Punt imported
+ symbols which are never used and absolute symbols which local scope.
+
+ * config/obj-som.h (obj_frob_file): Define.
+ * config/obj-som.c (obj_som_init_stab_section): Set alignment
+ of stab sections. Make space for the special stab entry.
+ (adjust_stab_sections): Adjust the special entry in the
+ stabs section.
+ (som_frob_file): New function. Simply calls adjust_stab_sections
+ for each section.
+
+Mon Nov 1 17:54:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (PIC_CALL_REG, SP, FP): Define.
+ (mips_pic, mips_cprestore_offset): New static variables.
+ (md_pseudo_table): Handle .abicalls, .cpload, and .cprestore.
+ Ignore .bgnb and .endb.
+ (gp_reference): _gp_disp is never addressed off GP.
+ (macro_build): Ignore macros while searching for insn. For cases
+ i, j, and o, accept the reloc type as an argument rather than
+ assuming BFD_RELOC_LO16. Don't try to convert BFD_RELOC_LO16 to
+ BFD_RELOC_MIPS_GPREL. Added new case a.
+ (set_at, load_register, macro): Changed calls to macro_build to
+ pass new argument for i, j and o cases.
+ (macro): Handle M_JAL_1, M_JAL_2 and M_JAL_A. These require
+ special handling when generating SVR4 PIC code.
+ (mips_ip, tc_get_register, s_frame): Use macros FP, SP, GP and AT
+ rather than hard coded constants.
+ (md_apply_fix): Handle BFD_RELOC_MIPS_LITERAL and
+ BFD_RELOC_MIPS_CALL16.
+ (s_option): Set mips_pic based on .option picN.
+ (s_abicalls): New function; set mips_pic to 2.
+ (s_cpload): New function; handle .cpload.
+ (s_cprestore): New function; handle .cprestore.
+
+ * config/obj-ecoff.c (obj_pseudo_table): Add entries for .bgnb,
+ .endb and .verstamp, setting them to s_ignore.
+
+Sun Oct 31 00:36:40 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (subspace_dictionary_chain): Add new ssd_defined
+ field. Define SUBSPACE_DEFINED accessor macro.
+ (pa_subspace): Allow user to override subspace attributes for
+ built-in subspaces. Set ssd_defined at the end of fcn -- that
+ way the attributes can only be changed once. Pass newly allocated
+ name to is_defined_subspace, not a pointer to the input line.
+ Fix typo in space/subspace rework.
+ (is_defined_subspace): Delete unused 2nd arg. All callers changed.
+
+ * config/tc-hppa.c (pa_import): If currently in the text segment
+ and a symbol is imported without type information, set BSF_FUNCTION
+ for the symbol.
+ * write.c (relax_and_size_seg): Correct test to determine if
+ the section's size was rounded up.
+
+ * config/obj-som.h (obj_set_symbol_type): Define a hook so GAS
+ can properly set all the SOM symbol types.
+ * config/tc-hppa.c (pa_symbol_type): New enum to represent the
+ symbol types which can be set from an IMPORT/EXPORT statement.
+ (pa_export_args): Set the pa_symbol_type type based on arguments.
+ If defined, call obj_set_symbol_type to pass this information on
+ to the BFD backend.
+
+ * read.c (get_stab_string_offset): Set SEC_DEBUGGING for any
+ stab section we make.
+ (s_stab_generic): Likewise.
+
+Sat Oct 30 14:26:20 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Allow backends to override the value of the fake label.
+ * write.h (LOCAL_LABEL): Delete DOT_LABEL_PREFIX code. Instead
+ assume backends will define LOCAL_LABEL if anything other than
+ 'L' is used to denote a local label.
+ (FAKE_LABEL_NAME): New macro. Defines the default name used for
+ the "fake" label.
+ * expr.c (make_expr_symbol): Delete DOT_LABEL_PREFIX code
+ and instead simply use the string defined by FAKE_LABEL_NAME.
+ (operand): Likewise.
+ * read.c (s_stab_generic): Likewise.
+ * config/tc-hppa.h (FAKE_LABEL_NAME): Define as L$0\001 so it's
+ known to be a local label.
+ * config/tc-i386.h (DOT_LABEL_PREFIX): Delete.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define.
+ * config/tc-m68k.h (DOT_LABEL_PREFIX): Delete.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define.
+ * config/te-sco386.h (DOT_LABEL_PREFIX): Delete.
+ (LOCAL_LABEL, FAKE_LABEL_NAME): Define.
+
+ Rework space/subspace handling in PA code to fully support
+ SOM spaces/subspaces.
+ * config/tc-hppa.c (USE_ALIASES): New object-format dependent define
+ to control the use of space/subspace name aliases.
+ (update_subspace): Accept space chain entry for containing space
+ as a new parameter. All callers changed.
+ (pa_get_label): Use current_space rather than pa_segment_to_space.
+ (pa_define_label): Likewise.
+ (pa_undefine_label): Likewise.
+ (md_begin): Change into the (possibly modified) text_section.
+ (pa_parse_space_stmt): Create a new segment/space if create_flag
+ is true, and the space name is not one of the two predefined spaces.
+ (pa_subspace): Use current_space rather than a lookup via
+ pa_segment_to_space. Reset BFD section flags as required by
+ the .subspace directive. Likewise for the section alignment.
+ Pass the current space to update_subspace and create_new_subspace.
+ (pa_spaces_begin): Only use space/subspace aliases if USE_ALIASES
+ is true. When not using aliases, create a BFD section for each
+ subspace encountered. When not using aliases replace the default
+ text, data, and bss segments with new ones.
+ (create_new_subspace): When not using aliases each subspace has a
+ section/segment and subsegments are not needed, so set the subsegment
+ to zero.
+
+ * config/tc-hppa.c (pa_parse_space_stmt): If needed, call
+ obj_set_section_attributes to pass space attributes to the
+ BFD backend.
+ (create_new_space): Likewise.
+ (create_new_subspace): Likewise for subspace attributes using
+ obj_set_subsection_attributes.
+ (update_subspace): Likewise for subspace attributes using
+ obj_set_subsection_attributes.
+
+ * config/tc-hppa.c (pa_parse_space_stmt): Get segment and sort key
+ for $TEXT$ and $PRIVATE$ from the default space structure.
+
+ * config/tc-hppa.c (pa_export_args): Always set BSF_FUNCTION
+ as appropriate for the given type.
+
+ * config/tc-hppa.c (tc_gen_reloc): Preliminary stab at handling
+ SOM relocations.
+
+ * config/tc-hppa.c (pa_comm): Delete incorrect check for symbol
+ redefinition.
+
+ * config/obj-som.[ch]: New files for SOM support. Note SOM
+ support is not yet complete in GAS or BFD.
+
+ * config/ho-hppabsd.h: Delete IO* macros, they are defined in
+ stdio.h. Delete declaration of free. Include stdlib.h, unistd.h,
+ and string.h.
+
+Fri Oct 29 13:26:12 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Allow backends to override the section names used for embedded
+ stabs support. Needed for SOM.
+ * read.c (STAB_SECTION_NAME): Default the name of the stab section
+ to ".stab".
+ (STAB_STRING_SECTION_NAME): Likewise for the stab strings section.
+ (get_stab_string_offset): Is now passed the full name for the
+ stab string section rather than a name prefix. All references
+ changed.
+ (s_stab_generic): New argument for the stab string section name.
+ all references changed.
+ (s_xstab): Append "str" to the stab section name to get the
+ stab string section name.
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Append "str"
+ to stab section name to get the stab string section name. Pass
+ the full name of the stab string section to get_stab_string_offset.
+ * config/obj-elf.c (obj_elf_init_stab_section): Likewise.
+
+ * config/tc-hppa.c (md_begin): Disable "-R" option to fold
+ textand data segments. Warn user "-R" is unsupported on the
+ PA.
+
+Thu Oct 28 12:36:13 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * config/tc-hppa.c (md_pseudo_table): Default alignment is 8 for
+ .align and .ALIGN directives.
+
+ * config/tc-hppa.c (pa_space): Do not report an error for a .space
+ directive which does not define a "well-known" space and does
+ not include a space number as an argument.
+
+ * config/tc-hppa.c (pa_def_subspaces): Correct initialization of the
+ "defined", "loadable", "code_only" and "space_index" fields.
+ (pa_def_spaces): Correct initialization of the "spnum", "defined",
+ and "private" fields.
+
+ * write.h (struct fix): Add new tc_fix_data field for the various
+ backends to attach machine dependent fixup information to.
+ * write.c (fix_new_internal): Initialize new tc_fix_data field.
+ * config/tc-hppa.c (hppa_fix_struct): Delete unnecessary fix_fixP and
+ fx_next fields.
+ (hppa_find_hppa_fix): Delete unnecessary function. Fix all
+ callers to get HPPA fixup information from the tc_fix_data field
+ in the GAS fixup.
+ (hppa_fix_root): Delete unnecessary variable.
+ (fix_new_hppa): Attach HPPA fixup data to the GAS fixup.
+
+ * config/tc-hppa.c (pa_set_start_symbol); Delete unwanted
+ function. Fix all callers.
+ (subspace_dictionary_chain): Delete unused ssd_start_sym field.
+
+ * config/tc-hppa.c (hppa_fix_adjustable): New function to determine
+ if a particular fixup is adjustable.
+ * config/tc-hppa.h (tc_fix_adjustable): Call hppa_fix_adjustable to
+ perform the real work.
+
+ * config/tc-hppa.h (RELOC_EXPANSION_POSSIBLE): Move definition out
+ of OBJ_XXX conditionals.
+ (MAX_RELOC_EXPANSION): Likewise.
+
+ * config/tc-hppa.c (log2): Renamed from is_power_of_2. Fix all
+ callers. Now returns log2 (N) for positive N which are an exact
+ power of two or -1 for an error.
+
+ * config/tc-hppa.c (pa_callinfo): Range check values provided for
+ ENTRY_GR, ENTRY_FR and ENTRY_SR. Properly adjust vaues before
+ inserting them into the unwind table.
+
+ * config/tc-hppa.c (NEEDS_FIXUP): Delete definition and all references.
+ (hppa_gen_reloc_type): New object format dependent macro.
+ (pa_ip): Delete tons of code which was either OBJ_SOM or OBJ_ELF
+ conditional. The code can (and will) be shared between SOM & ELF
+ formats in the near future.
+ (cons_fix_new_hppa, md_apply_fix_1): Likewise.
+ (pa_build_unwind_subspace, process_exit, pa_exit): Likewise.
+ (tc_gen_reloc): Use hppa_gen_reloc rather than an object format
+ specific call.
+
+ * config/tc-hppa.c (pa_comm): Set the segment for a common symbol
+ to bfd_und_section.
+
+ * config/obj-elf.h (obj_elf_version): Add extern prototype.
+
+ * configure.in (hppa-*-bsd*): New configuration.
+ BFD is always used for GAS generating SOM objects.
+
+ * write.c (adjust_reloc_syms): Set sy_used_in_reloc if an
+ adjustment is rejected by the target machine.
+
+ * config/tc-hppa.c (pa_big_cons): Delete function and its
+ declaration. All callers changed to use pa_cons.
+
+ * write.c (fixup_segment): Fix indention and open/close brace
+ problem.
+
+ From Pete Hoogenboom:
+ * config/tc-hppa.c (md_atof): Return a NULL on success rather than
+ an empty string.
+
+ * config/tc-hppa.c (pa_parse_space_stmt): Advance
+ input_line_poitner when an invalid argument is encountered.
+
+Thu Oct 28 13:09:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-a29k.c (md_begin): When opcodes are mashed together in
+ the table, require that the one without bit 0x1000000 set come
+ first. Require further that it be case 'b' or 'P'. The a29k
+ opcode table already meets these constraints.
+ (machine_ip): When handling case 'i' or 'A', make sure that the
+ appropriate opcode really exists by looking at the next entry in
+ the opcode table.
+
+Wed Oct 27 11:48:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): Adjust offsets for PC relative
+ fixups. Add 6 for long 7.3 case, 2 for short 7.2 case.
+
+ * config/obj-ecoff.c (obj_ecoff_ent): Ignore an optional number
+ after a .ent directive.
+
+ * config/tc-mips.c (mips_ip): Handle '>' case (shift amount
+ between 32 and 63 for double shift instruction). Do & 0x1f rather
+ than % 32.
+ (printInsn): Handle '>'.
+
+Tue Oct 26 16:58:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-ns32k.c (tc_aout_fix_to_chars): Output the symbol
+ number in the right place. Untested. Probably does not work for
+ cross assembly. From cagney@cs.adelaide.edu.au (Andrew Cagney).
+
+ * config/tc-m68k.c (md_apply_fix_2): Error if a short branch uses
+ an illegal offset of 0 or -1.
+
+ * config/obj-elf.c (obj_elf_init_stab_section): Align .stab
+ section to a longword boundary.
+
+Tue Oct 26 10:24:31 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Makefile.in (CHECKFLAGS): Pass down RUNTESTFLAGS.
+
+ From Jeff Law:
+ * config/tc-hppa.c (tc_gen_reloc): ELF32_HPPA_R_ADDEND ->
+ HPPA_R_ADDEND.
+
+Mon Oct 25 14:06:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Fix up membar argument handling.
+
+Mon Oct 25 11:17:58 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/tc-sh.c (build_Mbytes): Write the relocs to the correct
+ address. (md_assemble): Make error handling a bit more graceful.
+ (md_apply_fix): Don't warn on non aligned displacement.
+
+ * config/tc-z8k.c (get_specific, built_bytes): Understand all the
+ aspects of lda.
+
+Mon Oct 25 10:20:31 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * doc/Makefile.in (install-info): Use "$<*" so VPATH will find
+ as.info* even if they're in $(srcdir) (e.g., for FSF
+ distributions).
+
+ * write.c (write_relocs): For relocs that are pc_relative and
+ pcrel_offset and not partial_inplace, adjust reloc->addend to
+ compensate for a bfd_perform_relocation bug.
+
+ * config/tc-sparc.h: Removed remaining non-BFD_ASSEMBLER code.
+ * config/tc-sparc.c: Ditto.
+ (tc_gen_reloc): Include fx_offset for pcrel fixups.
+
+Sun Oct 24 16:49:00 1993 Jim Wilson (wilson@x1.cygnus.com)
+
+ * tc-mips.c (md_pseudo_table): Add dword pseudo op.
+
+Fri Oct 22 20:40:56 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * messages.c: replaced all variables called Format with 'format',
+ for consistency throughout
+
+ * configure.in: handle mips*- instead of mips, mips*el for little
+ endian configurations
+
+Fri Oct 22 14:45:49 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * input-scrub.c (physical_input_file, logical_input_file,
+ physical_input_line, logical_input_line): Made static.
+ (as_where): Return current file name and line number, don't print
+ them out.
+ * messages.c (as_show_where): New static function. Other
+ functions use it instead of as_where.
+ (as_bad_internal): New static function.
+ (as_bad): Use as_bad_internal.
+ (as_bad_where): New function, like as_bad but taking a file name
+ and line number.
+ * as.h (as_bad_where): Declare.
+ (as_where): Change prototype for new arguments.
+ * write.h (fixS): Added fields fx_file and fx_line.
+ * write.c (fix_new_internal): Save file and line number in fix.
+ (fixup_segment): Use as_bad_where, not as_bad.
+ * input-file.c (f_in, file_name): Made static.
+ * cond.c (struct file_line): Just use file and line fields.
+ (s_else): Use as_where and as_bad_where, not get_file_line and
+ set_file_line.
+ (get_file_line, set_file_line): Removed.
+ * listing.c (listing_newline): Use as_where.
+ * config/obj-coffbfd.c (obj_coff_init_stab_section): Use as_where.
+ * config/obj-ecoff.c (add_file): Use as_where.
+ * config/obj-elf.c (obj_elf_init_stab_section): Use as_where.
+ * config/tc-m68k.c (md_apply_fix_2): Use as_bad_where.
+ * config/tc-mips.c (tc_gen_reloc): Use as_bad_where, not assert.
+
+Thu Oct 21 12:52:01 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.h: Don't define REGISTER_PREFIX or
+ OPTIONAL_REGISTER_PREFIX if either is already defined.
+
+ * config/tc-m68k.c (m68k_ip): Delete some code in "#if 0".
+
+ * configure.in: Set bfd_gas for all sparc targets. Added facility
+ for keeping or rejecting configurations still under development;
+ default is to assume production environment, and reject configs
+ still being worked on. Mark Elf configurations (except sparc and
+ i386) as developmental. Deleted cases matching some generic names
+ in favor of more specific names. (E.g., when we get Alpha
+ support, we'll still only support VMS for Vax.)
+
+ * config/tc-sparc.h (md_end): New macro.
+ * config/tc-sparc.c (md_end): Function deleted.
+ (BFD_RELOC_*): Delete macros that used to help keep the non-bfd
+ version compiling. All sparc targets will use bfd now.
+ * tc.h (md_end): Don't declare if it's defined as a macro.
+
+ Changes from Jeff Law and Peter Hoogenboom:
+
+ * read.c (next_char_of_string): Limit octal character constants to
+ three digits.
+
+ * config/tc-hppa.h: Major cleanup. Use GNU-style comments. Warn
+ against placing additional object-file dependent code here. Warn
+ against contaminating all of GAS with the internals of tc-hppa.c
+ through inclusion of tc-hppa.h. Delete all forward declarations
+ for functions only used within tc-hppa.c, likewise for structures,
+ variables, and #defines. Try to group OBJ_ELF and OBJ_SOM
+ conditional code in a few small places.
+
+ * config/tc-hppa.c: Major cleanup. Use GNU-style comments. Group
+ structures, global variables, forward declarations together.
+ Reduce (or in some cases eliminate) OBJ_ELF and OBJ_SOM
+ conditional code -- try to group conditional code together
+ into a few places. Make all functions and variables which
+ are only used within tc-hppa.c static. PARAMize all functions.
+ Add comments to functions. Delete unused functions, variables,
+ #defines, etc. Delete unused members within structures. Delete
+ ldil;ble hacks -- it is believed they were installed to work
+ around old gas bugs. Avoid using mixed case for local
+ functions, variables, and structures. Fix formatting problems
+ not found by GNU-indent. Add FIXME notices for things which
+ should be worked on the near future. Delete lots of old
+ useless (1.36 PA-SOM) code.
+
+ * config/tc-hppa.c: (fix_new_hppa): Initialize the fx_r_type
+ field of the fixS structure. Needed to build unwind
+ descriptors correctly.
+
+ * write.c: (fixup_segment): Allow expressions such as
+ sym1-sym2+const as long as sym2 is $global$.
+
+ * write.c (adjust_reloc_syms): Provide a hook so that a target
+ cpu configuration can reject certain relocation reductions.
+ * tc-hppa.h (tc_fix_adjustable): New macro. Only accept relocations
+ which do not involve function symbols.
+
+ * config/tc-hppa.h: Reindent with GNU-indent. Delete references
+ to OBJ_OSFROSE. Fix typos (OBJ_SOME -> OBJ_SOM). Delete unused
+ STAB_FIXUP macro.
+ * config/tc-hppa.c: Likewise.
+
+ * config/tc-hppa.c (md_apply_fix_1): Use elf_symbol_type, instead
+ of elf32_symbol_type.
+ (pa_export_args): Likewise.
+ (elf_hppa_final_processing): Likewise.
+ (pa_desc): Do not call obj_elf_desc. (Is pa_desc even needed
+ anymore?)
+ (hppa_tc_make_sections): Do not declare elf_get_symtab_map any
+ ore.
+
+ * config/tc-hppa.c: (md_section_align): Align all sections to
+ a multiple of the section alignment rather than always a
+ multiple of 8.
+
+ * config/tc-hppa.c (hppa_tc_symbol): If the argument relocation
+ bits are zero (eg they specify no relocations), then do not even
+ bother adding their entries to thesymextn section.
+
+Thu Oct 21 15:44:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-sparc.c (md_parse_option): Accept and ignore -sparc
+ option, which is used by the SunOS make default .s.o rule.
+
+Wed Oct 20 12:26:33 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip, label "immediate"): Convert relocs
+ operating on upper 32 bits of immediate constants to lower-half
+ relocs with adjusted constants.
+
+Tue Oct 19 18:13:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.h (AOUT_MACHTYPE): Define to be external variable
+ m68k_aout_machtype.
+ * config/tc-m68k.c (omagic): Remove obsolete and unused variable.
+ (m68k_aout_machtype): New variable, if OBJ_AOUT.
+ (md_assemble): Initialize m68k_aout_machtype based on
+ current_architecture, if OBJ_AOUT.
+ (md_parse_option): Remove obsolete reference to omagic.
+
+Thu Oct 14 16:51:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (md_pseudo_table): Ignore .livereg pseudo-op.
+ (s_option): Ignore .option O* and .option pic*.
+ (s_ent): Skip whitespace between symbol and optional digit.
+ (my_getSmallExpression): Handle ($xx) correctly: assume 0($xx).
+
+ * app.c (do_scrub_next_char): Always accept 'x' and 'X' as escape
+ characters in state 6.
+ * read.c (next_char_of_string): Accept \Xh* and \xh* where h* are
+ hexidecimal digits.
+
+ * config/tc-i386.c (md_apply_fix_1): Make cross segment calls work
+ for ELF by hacking around bizarre bfd_perform_relocation behaviour
+ that I don't dare change.
+
+Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org)
+
+ * config/tc-i386.c: (md_begin): Do not zero static arrays. Don't
+ call strchr for each character to see if it is a special char,
+ instead add a second loop over special_chars. Set alignment
+ of text, data and bss sections to 4.
+ (pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be
+ used again.
+ (reloc): Don't return 8 and 16 bit non-PC relative relocations on
+ ELF, since the ELF object format does not have these type of
+ relocations. Change the abort into as as_bad and return
+ BFD_RELOC_NONE to silence compiler warnings.
+ (md_assemble): Keep track of the instruction size. Allow white
+ space between the $ and the constant for compatibility with older
+ gases and other assemblers.
+ (i386_operand): Skip spaces between $ and expression.
+ (tc_gen_reloc): Don't allow anything but 32 bit relocations on
+ ELF. Convert abort into an as_bad and assert into as_fatal.
+
+Wed Oct 13 16:50:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-coffbfd.c (fixup_segment) [DIFF_EXPR_OK]: If
+ sub_symbolP is in the current segment, convert to a PC-relative
+ fixup and discard the symbol.
+
+Wed Oct 13 14:00:02 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_build_symbols): Handle st_End symbol
+ for st_StaticProc just like st_Proc.
+
+ * write.c (relax_and_size_all_segments): Moved #endif for OBJ_BOUT
+ so that OBJ_BOUT doesn't forget to adjust all the fragments in the
+ .bss section.
+
+Tue Oct 12 17:26:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c: If OBJ_ELF, include elf/mips.h.
+ (mips_regmask_frag): New static variable, if OBJ_ELF.
+ (md_begin): If OBJ_ELF, create .reginfo section and set
+ mips_regmask_frag to a frag.
+ (mips_elf_final_processing): New function, if OBJ_ELF. Set
+ mips_regmask_frag to register mask information.
+ * config/tc-mips.h (elf_tc_final_processing): New macro, defined
+ if OBJ_ELF.
+
+Tue Oct 12 03:33:26 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * messages.c (as_fatal): Use myname when printing messages.
+
+ * config/tc-i960.c (md_begin): Use null pointer, not empty string,
+ as initial "return" value in case hashing isn't needed.
+
+ * config/tc-a29k.c (md_atof): Return null, not empty string, on
+ success.
+ * config/tc-h8300.c (md_atof), config/tc-h8500.c (md_atof),
+ config/tc-hppa.c (md_atof), config/tc-i860.c (md_atof),
+ config/tc-i960.c (md_atof), config/tc-m88k.c (md_atof),
+ config/tc-ns32k.c (md_atof), config/tc-sh.c (md_atof): Ditto.
+
+Mon Oct 11 16:46:31 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ fix for pr 3571
+ * config/tc-h8300.c (get_specific): Special action if 8 bit
+ address seen. (check_operand): Don't complain if truncating top
+ bits of an 8 bit address. (build_bytes): Allow an immediate and
+ an absolute in the same insn.
+
+Mon Oct 11 17:18:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * write.c (write_contents): Don't crash if seginfo is NULL.
+
+ * config/obj-ecoff.c (ecoff_frob_file): Write out register masks
+ by modifying .reginfo section, not by directly modifying BFD
+ backend data.
+
+Mon Oct 11 14:11:32 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/ho-sunos.h: remove extern time declaration
+
+Mon Oct 11 16:14:43 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * messages.c (as_fatal): Do mention that it's the assembler that
+ got the fatal error.
+
+Fri Oct 8 14:09:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_gprmask, mips_cprmask): New variables to
+ hold register masks.
+ (md_begin): Initialize them to zero.
+ (append_insn): Update mips_gprmask and mips_cprmask. Also add
+ register variables pinfo and prev_pinfo.
+ * config/tc-mips.h (mips_gprmask, mips_cprmask): Declare.
+ * config/obj-ecoff.c (ecoff_frob_file): If TC_MIPS, set gprmask
+ and cprmask from mips_gprmask and mips_cprmask.
+
+ * config/tc-mips.h: Define TARGET_FORMAT if OBJ_ELF.
+ * config/tc-mips.c (GPOPT): Define if OBJ_ECOFF or OBJ_ELF.
+ (various): Change all references to GP references to apply if
+ GPOPT, not if OBJ_ECOFF.
+ (s_change_sec): Rearrange somewhat. If OBJ_ELF, use .rodata
+ instead of .rdata. If OBJ_ELF, set section flags for .rodata and
+ .sdata sections.
+ (s_frame, s_loc, s_mask): Comment out entire functions, rather
+ than just body. They're not used anyhow.
+ * configure.in: Set cpu_type to mips for mips*. Accept
+ mips-*-elfl* and mips-*-elf*.
+
+Thu Oct 7 18:36:29 1993 Michael Meissner (meissner@osf.org)
+
+ * config/obj-elf.c (obj_elf_common): Allow the alignment field to
+ not be specified.
+
+Wed Oct 6 13:01:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (cons_fix_new_mips): New function. Turn
+ BFD_RELOC_64 into BFD_RELOC_32.
+ * config/tc-mips.h (TC_CONS_FIX_NEW): Define.
+ (cons_fix_new_mips): Declare.
+
+ Changes to let cons handle bignums like general expressions.
+ * expr.h (expressionS): New field X_unsigned.
+ * expr.c (operand): Initialize X_unsigned to 1. Set it to 0 for
+ unary minus case.
+ (expr) Fix typo resultP to right if missing operand. Set
+ X_unsigned to 1 when building new expression.
+ * read.c (potable): Make "octa" and "quad" call cons, not
+ big_cons.
+ (cons): Handle bignums. If given an O_constant (small integer) to
+ fill a big space, turn it into a bignum.
+ (parse_bitfield_cons): Set X_unsigned field.
+ (bignum_low, bignum_limit, bignum_high, grow_bignum, big_cons):
+ Removed.
+ * read.h (big_cons): Remove prototype.
+ * symbols.c (resolve_symbol_value): Don't give a warning if a
+ symbol in expr_section can not be resolved.
+ (S_SET_VALUE): Clear X_unsigned.
+ * write.c (write_object_file): If resolve_symbol_value failed on a
+ symbol we are writing out, give a warning.
+ * config/tc-h8500.c (parse_reglist): Set X_unsigned.
+ * config/tc-hppa.c (md_pseudo_table): Change "octa" and "quad" to
+ call pa_cons, not pa_big_cons.
+ (pa_big_cons): Remove.
+ * config/tc-hppa.h (pa_big_cons): Remove declaration.
+ * config/tc-i960.c (md_pseudo_table): Change "quad" to call cons,
+ not big_cons.
+
+Tue Oct 5 10:53:36 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * doc/as.texinfo (Copying): new node, to handle the recent changes
+ in the texinfo/gpl.texinfo file
+
+Mon Oct 4 17:10:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (big_cons): Handle "0" correctly.
+
+ * config/tc-mips.c (md_begin): Set target_big_endian correctly.
+
+Mon Oct 4 15:37:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): Mode 7.3 operand using PC should
+ have pc-relative fixup.
+ (md_parse_option): Move "-k" case down near "-pic" case.
+
+ * configure.in: Alphabetize list of cpu type alternatives. Enable
+ OS values of "linux*elf*" and "linux*coff*" to select those
+ formats, with linux emulation. Don't bother checking for upper-
+ or mixed-case versions of "ose".
+
+Thu Sep 30 11:05:35 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/z8k.c (md_pseudo_table): add "unseg".
+
+Wed Sep 29 16:15:11 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/m88k-opcode.h (m88k_opcodes): correct a few mistakes
+ found while extending the dissassembler.
+
+Tue Sep 28 12:02:04 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: Split i386 LynxOS out from other coff targets,
+ add a specific Lynx emulation.
+ Add m68k LynxOS target.
+ * config/tc-i386.c: Define specific Lynx target format.
+ * config/tc-m68k.c: Define specific Lynx target format.
+ * config/te-lynx.h: New file.
+
+ * config/obj-coffbfd.h: Don't set TARGET_FORMAT to be
+ "coff-{i386,m68k}" if TARGET_FORMAT already defined.
+ (INIT_STAB_SECTION): Define.
+ * config/obj-coffbfd.c: Include <time.h>.
+ (write_object_file): Look for .stab sections and call
+ adjust_stab_section.
+ (adjust_stab_section): New function, fills in the first symbol
+ of a stab section with number of symbols and string table size.
+ (obj_coff_init_stab_section): New function, creates the initial
+ symbol for a stab section.
+
+Mon Sep 27 15:21:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/atof-vax.c (md_atof): Return null on success instead of
+ empty string.
+ * config/atof-tahoe.c (md_atof): Ditto.
+ * read.c (float_cons): Expect a null pointer for success, not an
+ empty string.
+
+ * hash.c (hash_insert, hash_jam, hash_grow): Return null pointer
+ on success, instead of empty string. All callers changed.
+
+ * config/tc-vax.c: Use PARAMS in declarations.
+ (vip_op): Use NULL instead of empty string for success in error
+ and warning fields.
+
+Sun Sep 26 23:45:29 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * expr.c (expr) [DIFF_EXPR_OK]: Permit subtraction of two symbols
+ in different defined segments.
+
+ * write.c (relax_segment): Localize "aim" variable. If
+ DIFF_EXPR_OK, don't impose checks on symbol segment types.
+ (fixup_segment) [DIFF_EXPR_OK]: If sub_symbolP is in the current
+ segment, convert to a PC-relative fixup and discard the symbol.
+
+ * config/tc-m68k.c (flag_want_pic): New variable, mostly ignored.
+ (md_parse_option) [TE_SUN3]: Set it for "-k".
+ (m68k_ip): Generate proper fixup for mode 7.3.
+ * config/tc-m68k.h (DIFF_EXPR_OK): Define.
+
+Sat Sep 25 05:08:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (struct m68k_incant, getone, gettwo): Moved
+ earlier in the file.
+ (insop, add_exp): Now defined as functions, for readability.
+ (insop): Now takes two arguments; callers changed.
+
+Fri Sep 24 12:37:59 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/tc-m88k.c (get_o6): new function.
+ (get_bf, get_cmp, get_cnd, get_cr, get_fcr, get_imm16, get_reg,
+ get_vec9, getval, get_pcr, calcop, match_name): make static and
+ prototype.
+ (s_file): remove extraneous forward decl.
+ (md_begin): add const to retval decl.
+ (calcop): cope with instructions without arguments. Handle 'o'
+ type argument, the o6 field of the prot insn.
+ (md_estimate_size_before_relax): return a dummy value.
+
+ * config/m88k-opcode.h (m88k_opcodes): comment change; o6 field is
+ in bits 10 through 7. flt.[dxs]s requires an r register in the
+ second argument. New instruction lda.x. New instruction muls
+ (alias for mul).
+
+Fri Sep 24 13:43:30 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (distclean): Recurse like clean.
+ * doc/Makefile.in (distclean): New target.
+
+ * config/tc-mips.c (md_begin): Set BFD architecture and machine
+ based on MIPS ISA level.
+
+Thu Sep 23 17:58:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * as.c (main): "exhausted", not "exhuasted".
+
+ * struc-symbol.h (struct symbol): Add sy_used_in_reloc field.
+ * write.c (adjust_reloc_syms): Set sy_used_in_reloc.
+ (write_object_file): Never strip symbols with sy_used_in_reloc
+ set.
+
+ * config/obj-elf.c (obj_elf_section): Rewrote to handle both
+ Solaris and SVR4 style .section pseudo-ops.
+ (obj_elf_ident): Set SEC_READONLY for .comment section.
+ * config/tc-sparc.c (md_apply_fix): If this is ELF, and we're
+ generating a reloc, don't apply a fix.
+
+Thu Sep 23 13:16:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-coffbfd.c (relax_align): Now static.
+
+Mon Sep 20 19:23:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (get_stab_string_offset): Make non-static. Make
+ arguments const. Don't align strings to 4 byte boundaries.
+ * read.h: Declare get_stab_string_offset.
+ * config/obj-elf.c (obj_elf_section): Set SEC_ALLOC as well as
+ SEC_LOAD for progbits section.
+ (obj_elf_init_stab_section): New function.
+ (adjust_stab_sections): Add casts to avoid warnings.
+ * config/obj-elf.h (INIT_STAB_SECTION): Call
+ obj_elf_init_stab_section.
+ (OBJ_PROCESS_STAB): Removed definition.
+
+Fri Sep 17 18:12:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.h (S_GET_SIZE): Define.
+ (obj_frob_forward_symbol): Define.
+ * config/tc-i386.c (line_comment_chars): Initialize in all cases.
+
+Thu Sep 16 14:23:08 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * tc.h: Declare tc_gen_reloc differently depending upon
+ RELOC_EXPANSION_POSSIBLE.
+ * config/obj-elf.c (obj_elf_section): Only set flags when first
+ creating the section.
+
+Wed Sep 15 12:15:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (append_insn): Don't swap a trap instruction
+ with a branch.
+
+Tue Sep 14 13:31:04 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_data, obj_elf_text): New functions;
+ set previous_section and previous_subsection and then call s_data
+ and s_text, respectively.
+ (obj_pseudo_table): Add data and text.
+ (obj_elf_section): Add SEC_LOAD to default initialization of
+ flags. Treat .rodata1 like .rodata. Set SEC_LOAD as well as
+ SEC_ALLOC for "alloc" string. Don't bother trying to find the
+ section; just use subseg_new.
+
+ * read.c (change_to_section): Removed. This is now done by
+ subseg_new.
+ (get_stab_string_offset): Rearranged somewhat. Create the section
+ using subseg_new. Store the string index in seg_info, rather than
+ in a static variable. Force the first string to be empty. Use
+ frag_more rather than FRAG_APPEND_1_CHAR.
+ (s_stab_generic): Rewrote.
+ * subsegs.h (segment_info_type): Added stabu union.
+ * subsegs.c (subseg_new): Initialize stab_string_size to 0.
+ * config/obj-aout.c: Don't include aout/stab_gnu.h.
+ (obj_aout_stab, obj_aout_desc): Removed.
+ (obj_pseudo_table): Removed desc and stabX entries.
+ * config/obj-bout.c: Same changes as config/obj-aout.c.
+ * config/obj-bout.h (S_SET_TYPE): Define.
+ (tc_bout_fix_to_chars): Declare.
+ * config/obj-coff.c (obj_coff_stab): Removed.
+ (obj_pseudo_table): Removed desc and stabX entries.
+ * config/obj-coff.h (SEPARATE_STAB_SECTIONS): Define.
+ * config/obj-coffbfd.c (current_stab_symbol): Removed.
+ * config/obj-coffbfd.h (obj_symbol_type): Removed n_strx, n_type,
+ n_other, n_desc and n_value fields.
+ (S_{S,G}ET_{OFFSET,OTHER,TYPE,DESC}): Removed.
+ (MAKE_STAB_SYMBOL): Removed.
+ * config/obj-ecoff.c (obj_ecoff_stab): Renamed to ecoff_stab.
+ Changed arguments and removed parsing code.
+ (obj_pseudo_table): Removed stabX entries.
+ * config/obj-ecoff.h (ecoff_stab): Declare.
+ (OBJ_PROCESS_STAB): Define.
+ * config/obj-elf.c: Don't include aout/stab_gnu.h.
+ (obj_elf_stab, obj_elf_xstab, obj_elf_desc,
+ elf_stab_symbol_string, elf_stab_symbol, obj_elf_stab_generic):
+ Removed.
+ (obj_pseudo_table): Removed desc, stabX and xstabs entries.
+ (obj_elf_version): Use subseg_new, not bfd_make_section. Don't
+ set SEC_LOAD for .note section.
+ (adjust_stab_sections): Get frag pointer from seg_info, rather
+ than looking through frags.
+ * config/obj-elf.h (S_{S,G}ET_{OTHER,TYPE,DESC}): Removed.
+ (SEPARATE_STAB_SECTIONS, INIT_STAB_SECTION, OBJ_PROCESS_STAB):
+ Define.
+ * config/obj-vms.c (obj_aout_stab): Removed.
+ (obj_pseudo_table): Removed stabX entries.
+ * config/obj-vms.h (S_SET_TYPE): Define.
+
+ * as.h: Declare listing.
+ * read.c: Don't declare listing.
+ (emit_expr): Cast fix_new_exp argument.
+ (parse_bitfield_cons): Correct printf format.
+ * symbols.c (symbol_new): Add cast to avoid warning.
+ * write.h: Declare text_last_frag and data_last_frag.
+ * config/obj-bout.c (obj_bout_line): Added dummy argument.
+ * config/obj-coffbfd.c: Add some casts to avoid warnings.
+ * config/tc-a29k.c: Likewise.
+ * config/tc-i960.c: Likewise. Also fully bracket structure
+ initializations, fix printf formats, and remove unused variables.
+
+Mon Sep 13 16:48:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (s_desc): Only compile and use if S_SET_DESC is defined.
+ * struc-symbol.h: Declare verify_symbol_chain and
+ verify_symbol_chain_2 even if not SYMBOLS_NEED_BACKPOINTERS.
+ * symbols.c (verify_symbol_chain): Removed useless expression.
+ * write.c (headers, the_object_file): Only use if not
+ BFD_ASSEMBLER and not BFD.
+ (fixup_segment, cvs_frag_to_fill): Only use if BFD_ASSEMBLER or
+ not BFD.
+ (merge_data_into_text): Only use if BFD_ASSEMBLER or (not BFD and
+ not OBJ_AOUT).
+ * write.h: Declare relax_segment.
+ * config/obj-coffbfd.c (stack_pop, stack_push, stack_init): Made
+ static.
+ (stack_top): Commented out, since it's not used.
+ Fixed up pseudo-op functions to take an ignored int argument.
+ (size_section): Added default BAD_CASE to switch.
+ Changed bzero calls to memset.
+ * config/obj-coffbfd.h (S_IS_LOCAL): Call strchr on S_GET_NAME
+ (s), not on s itself.
+ * config/tc-a29k.c (s_use): Take ignored int argument. Only
+ define if OBJ_COFF is not defined.
+ * config/tc-i386.c: (fits_in_signed_byte, smallest_imm_type): Make
+ argument signed again.
+ * config/tc-m68k.c (s_bss, s_even, s_proc): Take ignored int
+ argument.
+ (m68k_ip): Fully bracket initialization of archs.
+ Correct several formats for __LINE__ to be %d rather than %s.
+ (init_table): Fully bracket initialization.
+ Cast values larger than 0x7f assigned to fr_opcode to char.
+
+ * subsegs.c: Renamed non-BFD_ASSEMBLER subseg_new to subseg_set.
+ Wrote non-BFD_ASSEMBLER subseg_new. Now subseg_new always takes a
+ section name, and subseg_set always takes a segT. Changed all
+ callers as appropriate.
+ * config/obj-coffbfd.c (change_to_section): Renamed to
+ obj_coff_add_segment. Corrected. Made callers use subseg_new.
+ * config/obj-coffbfd.h (obj_segment_name, obj_add_segment):
+ Define.
+
+Mon Sep 13 13:15:03 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.h (LOCAL_LABEL): Remove test for name[0] == 'L'.
+
+Fri Sep 10 11:22:08 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.h (S_SET_SIZE): Actually set the size.
+
+ Gcc lint.
+ * Added a number of casts to function calls.
+ * app.c (do_scrub_begin), as.c (main), expr.c (integer_constant,
+ operand, expr), read.c (read_begin, HANDLE_CONDITIONAL_ASSEMBLY,
+ read_a_source_file, s_align_bytes, demand_empty_rest_of_line,
+ ignore_rest_of_line, big_cons, is_it_end_of_statement, s_ignore),
+ read.h (is_name_beginner, is_part_of_name), config/obj-elf.c
+ (obj_elf_section), config/tc-i386.c (parse_register),
+ config/tc-sparc.c (isoctal, s_proc): Cast char
+ array indices to unsigned char.
+ * app.c (process_escape): Make static. Add prototype. Change
+ argument from char to int.
+ * as.c: Include output-file.h for prototypes. Comment out unused
+ function got_sig.
+ * Makefile.in (as.o): Depend on output-file.h.
+ * as.h (BAD_CASE): Cast val argument to long, and use %ld.
+ (pseudo_typeS): Add prototype to poc_handler field.
+ (print_version_id): Add prototype.
+ (xmalloc, xrealloc): Change size arguments to unsigned long.
+ (do_scrub_next_char): Add prototypes for function arguments.
+ (had_errors, had_warnings, scrub_from_file): Remove duplicate
+ declarations.
+ * atof-generic.c (atof_generic): Make size variables unsigned.
+ * cond.c (ignore_input): Removed unused local variable ptr.
+ * expr.c (floating_constant, integer_constant): Make static. Add
+ prototypes.
+ * flonum-copy.c (flonum_copy): Make size variables unsigned.
+ * frags.h: Add prototype for frag_init.
+ * hash.h, hash.c: Change hash values from char * to PTR, make hash
+ strings const, make returned error strings const char *. Added
+ prototypes for functions.
+ * input-file.h, input-file.c (input_file_buffer_size): Return
+ unsigned int.
+ * input-scrub.c (buffer_length): Make unsigned.
+ (input_scrub_push, input_scrub_pop): Make static.
+ * listing.c (list_symbol_table): Cast sprintf argument to unsigned
+ long and use %lx. Print name of segment rather than address of
+ structure.
+ (listing_list, listing_title): Change argument to int.
+ (listing_eject, listing_flags, listing_psize): Add int argument.
+ * listing.h: Corresponding declaration changes.
+ * obj.h (obj_emit_symbols): Rename prototype argument to avoid
+ shadowing.
+ * read.h: Change get_absolute_expression prototype to return
+ offsetT. Add prototype for next_char_of_string. Various
+ prototype changes.
+ * read.c: Remove prototype for next_char_of_string.
+ (pobegin): Make errtxt const. Make new_length, tmp_len and num
+ unsigned.
+ (s_abort, s_align_ptwo, s_comm, s_data, s_app_line, s_fill,
+ s_globl, s_lsym, s_org, s_set, s_text, s_desc): Add int argument.
+ Change all callers.
+ (s_comm): Change temp from valueT to offsetT. Cast to long when
+ printing and use %ld (only for error messages anyhow).
+ (s_long, s_int): Remove unused functions.
+ (cons): Change argument to int.
+ (emit_expr): Use %lx when printing longs.
+ (get_absolute_expression): Return offsetT, not long.
+ (get_stab_string_offset): Comment out unless
+ SEPARATE_STAB_SECTIONS.
+ (s_stab_generic): Remove unused offset. Define seg_is_new only
+ if SEPARATE_STAB_SECTIONS. Use toP only in local block.
+ * struc-symbol.h (verify_symbol_chain_2): Add prototype.
+ * symbols.c: Remove nested comment.
+ (symbol_new): Rename value to valu.
+ (colon): Use %ld and cast to long in error message.
+ * symbols.h: Remove duplicate verify_symbol_chain declaration.
+ * tc.h: Remove unused md_emit_relocations declaration.
+ (tc_gen_reloc): Add declaration.
+ * write.c (cvt_frag_to_fill): Change first argument name depending
+ on BFD_ASSEMBLER.
+ (write_relocs): Remove unused offset, frags. Remove tc_gen_reloc
+ declarations. Make n unsigned.
+ (write_contents): Remove unused i, n, relocs, fixp. Rename frags
+ to f to avoid shadowing.
+ (write_object_file): Define fragP only if not BFD_ASSEMBLER or not
+ WORKING_DOT_WORD. Remove unused keep. Only declare punt and
+ punt_it if they will be used. Make i and n unsigned.
+ (fixup_segment): Cast to long and use %ld in error message.
+ * xmalloc.c (xmalloc, xrealloc): Make size argument unsigned.
+ * config/obj-aout.h: Remove nested comment. Add prototype for
+ obj_aout_frob_symbol.
+ (obj_aout_line, obj_aout_desc): Add int argument.
+ * config/obj-ecoff.c: Changed build routines to use an unsigned
+ offset.
+ (add_string): Make len unsigned long.
+ (obj_ecoff_stab): Use %lu in error message.
+ * config/obj-elf.c (obj_elf_common): Comment out unused label
+ allocate_bss.
+ (obj_elf_frob_symbol): Return 0 (currently broken).
+ (obj_elf_desc, obj_elf_version, obj_elf_size, obj_elf_type,
+ obj_elf_ident, obj_elf_weak, obj_elf_local, obj_elf_common,
+ obj_elf_line, obj_elf_previous): Add int argument.
+ (obj_elf_write_symbol_p): Make static.
+ * config/obj-elf.h (obj_elf_write_symbol): Add prototype.
+ * config/tc-hppa.h: Remove declarations of functions declared in
+ read.h.
+ * config/tc-i386.c (ENCODE_RELAX_STATE): Cast to relax_substateT.
+ (s_bss): Add int argument.
+ (fits_in_signed_byte, smallest_imm_type): Make argument unsigned.
+ (dummy): Remove unused function.
+ (md_assemble): Rename local o to op to avoid shadowing.
+ (tc_gen_reloc): Rename local reloc to rel to avoid shadowing.
+ * config/tc-m68k.c (s_data1, s_data2): Add int argument.
+ * config/tc-mips.c (mips_ip, md_apply_fix): Cast to long and use
+ %ld in error messages.
+ * config/tc-sparc.c: Remove duplicate declarations.
+ (getExpression): Rewrite condition to avoid empty conditional
+ body.
+ (s_reg, s_proc, s_reserve, s_common, s_seg, s_xword): Add int
+ argument.
+
+Thu Sep 9 17:10:00 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Changes from Jeff Law:
+
+ * config/tc-hppa.c (md_assemble): Fix typo.
+ (pa_ip): Delete unused variables and labels. Do not check for
+ unsigned values being < 0, it can't happen.
+ (is_same_frag): Return a value in recursive call case.
+ (pa_callinfo): Delete unused variables and labels.
+ (pa_comm): Likewise.
+ (pa_copyright): Likewise.
+ (pa_export): Likewise.
+ (pa_import): Likewise.
+ (pa_param): Likewise.
+ (pa_space): Likewise.
+ (pa_subspace): Likewise.
+
+Thu Sep 9 15:05:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * read.c (get_stab_string_offset, s_stab_generic): If
+ BFD_ASSEMBLER, call subseg_set rather than subseg_new.
+
+Wed Sep 8 15:09:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Set SEC_LOAD when using
+ default flag values.
+
+Tue Sep 7 10:22:52 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * read.c: (change_to_section): Don't include body if not MANY_SECTIONS.
+
+ * read.c: (s_stab, s_xstab, s_desc): New functions to parse
+ various stab-related directives.
+ * read.h: (s_stab, s_xstab, s_desc): New function prototypes.
+ * write.c: (merge_data_into_text): Fix ifdef tangle.
+ * config/obj-coffbfd.c (current_stab_symbol): Fake symbol
+ for stab reader to use.
+ * config/obj-coffbfdh.h (obj_symbol_type): Added fields for
+ stab reader, macros to access.
+
+Fri Sep 3 16:44:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.h (elf_symbol): No longer special-cased on
+ sparcv9, since elf_symbol_type is now independent of size.
+
+ * config/obj-elf.h (elf_symbol): Fixed name of elf_symbol_type.
+
+ * config/tc-hppa.h (struct default_subspace_dict, struct
+ default_space_dict): Field "sort" is now unsigned char.
+
+ * config/tc-hppa.c (pa_def_subspaces, pa_def_spaces): Align
+ columns for easier reading.
+ (bcmp, index): Deleted USG-specific definitions. Should be dealt
+ with in ho-*.h, or in libiberty. Changed mention of index to
+ strchr.
+ (label_symbolP, label_symbol_defined, callinfo_found,
+ within_entry_exit, exit_processing_complete, within_procedure,
+ pa_def_subspaces, pa_def_spaces, pa_pseudo_op_moves_pc,
+ label_symbols_rootP, pa_get_label, pa_label_is_defined,
+ pa_undefine_label): Now static.
+ (movers): Now const, in addition to pointing to const data.
+ * config/tc-hppa.h (label_symbolS_rootP, pa_get_label,
+ pa_label_is_defined, pa_undefine_label, pa_pseudo_op_moves_pc):
+ Delete declarations.
+
+ Merged more changes from Jeff Law and Pete Hoogenboom:
+
+ * config/tc-hppa.c (pa_def_subspaces, pa_def_subspaces): Remove
+ entries for .stab and .stabstr.
+
+ * config/obj-elf.c: (elf_stab_symbol_string): Set the
+ SEC_LOAD attribute for the .stabstr section.
+ (obj_elf_stab_generic): Set the SEC_LOAD attribute for the
+ .stab section.
+ (obj_elf_stab_generic): Change '#if 1' to '#if 0'.
+ (obj_elf_stab_generic): Incorrect byte count on call to
+ md_number_to_chars function.
+
+ * config/tc-hppa.c (hppa_tc_symbol): Static functions need
+ argument relocation bits too.
+
+ * config/tc-hppa.c (pa_stringer): Correctly handle escaping
+ characters which should appear unaltered in the output string (for
+ example an escaped double-quote).
+
+ * config/tc-hppa.c (pa_parse_nonneg_cmpsub_cmpltr): Always
+ initialize name.
+ (pa_parse_neg_cmpsub_cmpltr): Likewise.
+ (pa_parse_nonneg_add_cmpltr): Likewise.
+ (pa_parse_neg_add_cmpltr): Likewise.
+
+ * config/tc-hppa.h (parse_cons_expression_hppa): Remove prototype
+ for now.
+ (cons_fix_new_hppa): Likewise.
+ * config/tc-hppa.c (md_apply_fix): Fix type of valp to match
+ prototype.
+
+ * config/tc-hppa.c: Include libhppa.h.
+
+ * config/tc-hppa.h: Delete extern declarations of functions
+ found in libhppa.h.
+
+ * config/tc-hppa.c (pa_space): Rework to avoid unwanted #ifdef
+ OBJ_ELF conditionals.
+ * config/tc-hppa.h (LOCAL_LABEL): Correctly identify local labels
+ on the PA.
+
+Thu Sep 2 10:43:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (macro_build): Accept 'z', and ignore it.
+ (macro): Use "z,s,t" for div instructions to match corresponding
+ change in opcode table.
+ (mips_ip): Added 'z'--must be zero register.
+
+Wed Sep 1 15:56:42 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_relocs) [RELOC_EXPANSION_POSSIBLE]: Declare
+ tc_gen_reloc correctly.
+
+ * configure.in: Use "case" instead of "if" when possible. Rewrote
+ Makefile editing to reduce work done. Treat "hppa*" as "hppa".
+
+Wed Sep 1 12:19:07 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/obj-coffbfd.c (obj_coff_section): add 'd' as an alias for
+ section type of data. 'd' seems to be used for m88k.
+
+Wed Aug 25 22:33:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_align, s_stringer, s_cons, s_float_cons,
+ s_mips_space): Set insn_label to NULL to avoid changing it at the
+ next .align statement.
+ (append_insn): Don't swap jal with instruction that sets the
+ register that jal sets.
+
+Wed Aug 25 16:15:57 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * configure.in: recognize m88110.
+
+Wed Aug 25 13:37:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Merged changes from Pete Hoogenboom and Jeff Law at Utah:
+ * config/tc-hppa.c (pa_build_unwind_subspace): SEC_ALLOC should
+ not be on for .hppa_unwind.
+ (md_pseudo_table): .PARAM and .param are valid pseudo-ops for GAS.
+ (pa_param): New function to handle .PARAM directives.
+ (pa_ip): Pass "isbranch" argument down to pa_parse_*_compltr
+ functions. Handle '|' for movb; allow movb,n.
+ (pa_parse_nonneg_cmpsub_cmpltr): Delete old useless
+ version. Handle cases where no completer exists for
+ comb,n or addb,n.
+ (pa_parse_neg_cmpsub_cmpltr): Handle cases where no
+ completer exists for comb,n or addb,n. Make logic
+ mirror that of pa_parse_nonneg_cmpsub_cmpltr.
+ (pa_parse_nonneg_add_cmpltr): Likewise.
+ (pa_parse_neg_add_cmpltr): Likewise.
+ * tc-hppa.h (pa_param): Declare.
+
+Tue Aug 24 15:41:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-hppa.c (hppa_tc_make_symextn_section): Now static.
+ Added forward declaration.
+
+ Merged changes from Pete Hoogenboom and Jeff Law at Utah:
+
+ * config/obj-elf.c (elf_frob_file): Arguments were incorrect on
+ call to elf_tc_make_sections.
+ (obj_elf_version): A .note section shouldn't have the SEC_ALLOC
+ attribute.
+
+ * config/tc-hppa.c (hppa_tc_make_sections): Add some processing to
+ handle symbol extension sections.
+
+ * config/tc-hppa.c (pa_build_symextn_section): New function to
+ create a symbol extension section.
+ (pa_export_args): Make call to pa_build_symextn_section.
+ (hppa_tc_symbol, hppa_tc_make_sections,
+ hppa_tc_make_symextn_section): New functions.
+ * config/tc-hppa.h: Update elf_tc_symbol and elf_tc_make_sections
+ macros.
+
+ * read.c (emit_expr): Place check for TC_CONS_FIX_NEW in the
+ BFD_ASSEMBLER branch as well.
+
+ * config/tc-hppa.h: If ELF is the target object format, define
+ some ELF- and hppa-specific types and constants.
+
+ * config/tc-hppa.c (getExpression): Fix a typo.
+
+ * read.c (read_a_source_file): Use TC_EQUAL_IN_INSN to determine
+ if a `=' is part of an instruction.
+ (read_a_source_file): Handle case where end-of-line markers are
+ also used within instructions.
+ * config/tc-hppa.h (TC_EQUAL_IN_INSN, TC_EOL_IN_INSN): Define.
+
+ * config/tc-hppa.c (md_apply_fix_1): Keep relocations for
+ out-of-range branches/'calls using "bl" or calls which may need
+ argument relocation stubs. Do not need/keep relocations for
+ conditional branches.
+ (elf_hppa_final_processing): Fix calculation of function size.
+
+ * config/obj-elf.c (obj_elf_version): Mark .note section as
+ READONLY.
+
+ * config/tc-hppa.c (parse_cons_expression_hppa): Pass exp, not the
+ address of exp, to expression.
+ (pa_build_unwind_subspace): Turn SEC_HAS_CONTENTS flag on.
+ (md_apply_fix_1): Delete unwanted comments.
+ (process_exit): Symbols marking the end of a function are always
+ BSF_LOCAL.
+
+ * config/tc-hppa.c: Include elf32-hppa.h from BFD tree.
+ (pa_space): Declare and initialize gdb_section.
+
+ * config/obj-elf.c (elf_frob_file): Change
+ elf_tc_final_processing_hook to elf_tc_final_processing.
+
+ * config/tc-hppa.c (fix_new_hppa): Fix argument list to match
+ argument type declarations.
+ (getExpression): Fix typo.
+ (pa_export_args): Change elf_symbol_type to elf32_symbol_type.
+ (elf_hppa_final_processing): Likewise. Name changed from
+ elf_hppa_final_processing_hook.
+ (start_symbol_root, start_symbol_last): Deleted.
+
+ * config/tc-hppa.h (TC_PARSE_CONS_EXPRESSION): Fix typo.
+
+ * config/tc-hppa.h: Replace "symbolS" with "struct symbol" to
+ avoid changing include ordering.
+
+ * config/tc-hppa.c (pa_ip, case 'y'): Handle just like 't'.
+
+Mon Aug 23 12:47:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (set_at): Added unsignedp argument. Use
+ load_register.
+ (set_at_unsigned): Removed; changed callers to use set_at.
+ (load_register): Removed unused ip argument. Changed callers.
+ (append_insn): Don't swap branch and branch likely.
+ (macro_build): Handle 'u'.
+ (load_register): Handle 64 bit constants.
+ (macro): Added M_DABS, removed M_ABSU. Numerous changes to
+ support 64 bit constants.
+ (mips_ip): Use hex constants in range checks for clarity.
+ (md_number_to_chars): Support 8 byte values.
+
+Fri Aug 20 16:50:59 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * config/tc-m88k.h: updated copyrights.
+ (TC_CONS_RELOC): declare to be RELOC_32.
+
+Fri Aug 20 11:16:44 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_isa): New static variable.
+ (md_begin): Initialize mips_isa based on TARGET_CPU. Don't sanity
+ check macros. Set text alignment and GP size here.
+ (md_assemble): Don't set text alignment and GP size here.
+ (append_insn): Don't insert NOPs for load delays if mips_isa >= 2.
+ Use the right mask and shift for WRITE_FPR_T and WRITE_FPR_S. Add
+ a NOP after a branch likely.
+ (mips_emit_delays): Don't insert NOPS for load delays if mips_isa
+ >= 2.
+ (macro): Support r6000 and r4000 macros.
+ (mips_ip): Check insn ISA level against mips_isa before using it.
+ Added 'x' case for ignored register.
+ (md_parse_option): Handle -mipsN and -mcpu=XX.
+
+Fri Aug 20 01:26:52 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-i386.c (md_pseudo_table) [OBJ_ELF]: Handle ".zero".
+
+Thu Aug 19 12:15:18 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (s_local): Function moved and renamed...
+ * config/obj-elf.c (obj_elf_local): ...to here.
+ * config/tc-sparc.c (md_pseudo_table), config/obj-elf.c
+ (obj_pseudo_table): Move handling of ".local".
+
+ * tc.h (md_parse_option): Don't declare if defined as a macro.
+
+ * config/tc-i386.h (NO_RELOC) [BFD_ASSEMBLER]: Define as
+ BFD_RELOC_NONE.
+ (md_parse_option): New macro, converted from function.
+ * config/tc-i386.c (md_parse_option): Function deleted.
+ (comment_chars) [OBJ_ELF]: Include "/".
+ (line_comment_chars) [OBJ_ELF || TE_I386AIX]: Don't include "/".
+ (md_assemble): Cast 0xe9 to char explicitly, to avoid compiler
+ warning.
+ (md_assemble, md_estimate_size_before_relax, md_create_long_jump):
+ Call reloc for fix_new type, or use correct enumerator, instead of
+ always using NO_RELOC.
+ (i386_operand): Change "ifndef I386COFF" to "ifdef OBJ_AOUT" for
+ tests for valid section.
+ (md_convert_frag) [BFD_ASSEMBLER]: Compensate for frag start
+ address.
+ (md_apply_fix_1) [BFD_ASSEMBLER]: For pc-relative reloc with
+ symbol, compensate for location of reloc.
+ (reloc, BFD_RELOC_32, BFD_RELOC_32_PCREL) [!BFD_ASSEMBLER]: Define
+ to return zero.
+
+Wed Aug 18 16:51:29 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.c: Undef NO_RELOC before including aout/aout64.h.
+ (obj_elf_weak): New function.
+ (obj_pseudo_table): Handle ".weak".
+ (obj_elf_section): If section directive includes a string, ignore
+ it for now. Accept "progbits" flag.
+ (obj_elf_type): Accept `@' before flag name.
+
+ * write.c (relax_and_size_seg) [BFD_ASSEMBLER]: Get rid of `if(1)'
+ condition.
+ (fixup_segment) [BFD_ASSEMBLER]: Use bfd_is_com_section, rather
+ than checking for bfd_com_section directly.
+ (fixup_segment): Simplify range check.
+ (fixup_segment) [OBJ_COFF && TC_I960]: Simplify cpp condition
+ test.
+
+ * symbols.h (S_SET_WEAK): Declare.
+ * symbols.c (S_SET_WEAK): New function.
+ (S_SET_EXTERNAL, S_CLEAR_EXTERNAL): Don't bother with BSF_EXPORT,
+ it's not a separate flag any more. Clear BSF_WEAK.
+
+ * read.c (potable): Treat "string" like "asciz".
+
+Wed Aug 18 15:30:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (append_insn): Don't swap branch instructions
+ if .set nobopt or .set volatile.
+ (gp_reference): .lit8 and .lit4 are accessed via the GP register.
+ (macro): Added cases M_LI_S, M_LI_SS. Fixed M_LI_D and M_LI_DD.
+ (mips_ip): Added cases 'F', 'L', 'f', 'l' for floating point.
+ * config/obj-ecoff.c: Renamed some variables to avoid shadow
+ warnings.
+
+Mon Aug 16 14:16:02 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/obj-coff.h (S_IS_COMMON): add missing backslash
+
+ * configure.in (z8k-*-{coff,sim}): use coffbfd for this target
+
+Thu Aug 12 11:47:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Suggested by
+ davidj@ICSI.Berkeley.EDU (David Johnson): Don't accept symbolic
+ names for 'E' and 'G' argument types (coprocessor registers) and
+ don't warn if $1 is used on the coprocessor.
+ (macro): Handle M_{L,S}WC{0,2,3}_AB correctly.
+
+Mon Aug 9 12:09:14 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * read.c (emit_expr): Use BFD_RELOC_16 for 2-byte values.
+ * config/tc-sparc.c (md_apply_fix, tc_gen_reloc): Handle
+ BFD_RELOC_16.
+ * config/tc-sparc.h (WORKING_DOT_WORD): Define.
+
+Mon Aug 9 13:36:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (merge_data_into_text): Define only if BFD_ASSEMBLER is
+ defined or BFD is not.
+ (relax_and_size_all_segments): Declare local variable fragP.
+
+Fri Aug 6 15:22:53 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix, case BFD_RELOC_32): Fill in
+ bytes with real values, not zeros.
+
+Fri Aug 6 10:57:59 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (mips-*-riscos*, mips-*-sysv*): New (untested)
+ targets, using ecoff and mips-big.
+
+ * config/tc-mips.c (mips_ip): From davidj@ICSI.Berkeley.EDU (David
+ Johnson): Added case for 'C' for coprocessor instruction codes.
+
+Thu Aug 5 13:08:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix, case BFD_RELOC_64): Fill in
+ bytes with real values, not zeros.
+ (md_pseudo_table): Call cons for .uaxword.
+
+ * config/obj-elf.c (obj_pseudo_table): Handle ".8byte".
+
+ * read.c (emit_expr): Use BFD_RELOC_64 for 8-byte expressions.
+
+ * write.c (write_object_file): Test DEBUG_SYMS instead of DEBUG
+ for verifying symbol chain.
+ (merge_data_into_text, relax_and_size_all_segments): New
+ functions, split out from write_object_file.
+
+Tue Aug 3 15:43:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_stab_generic, in disabled code): If
+ debug section is new, allocate an extra 12 bytes at its start. If
+ ".stabs" type is N_SO, fill in filename symbol field of that first
+ entry. Return early if "goof", to simplify later code slightly.
+ (adjust_stab_sections): New function.
+ (elf_frob_file): Apply adjust_stab_sections to each section.
+
+ * config/obj-elf.c (obj_elf_section, obj_elf_previous): No longer
+ static.
+ * config/obj-elf.h (obj_elf_section, obj_elf_previous): Declare.
+ * config/tc-sparc.c (md_pseudo_table): Call them for "pushsection"
+ and "popsection", and call cons for "uaword" and "uahalf".
+
+ * config/obj-elf.c (obj_elf_version): Use English in error
+ messages.
+
+Tue Aug 3 11:29:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c: Updated for BFD ECOFF changes. Now gets the
+ swapping routines and external structure sizes via the
+ ecoff_backend information. No longer includes coff/mips.h.
+
+Mon Aug 2 17:35:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (get_tag): Save tag name in permanent memory
+ and in hash_ptr->string.
+
+ * app.c (do_scrub_next_char): Reset state to 0 after .appline if
+ file name is not seen.
+
+Mon Aug 2 11:51:41 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_apply_fix, case BFD_RELOC_64): New case,
+ parallel to BFD_RELOC_32.
+ (tc_gen_reloc): Accept BFD_RELOC_64.
+
+Thu Jul 29 22:21:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c: Don't use short int in a prototype.
+
+ * expr.c (operand): Make return value simply depend on contents of
+ returned expression.
+
+Thu Jul 29 18:38:37 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: sparc*-aout and sparc*-vxworks are BFD assemblers
+
+Thu Jul 29 18:38:37 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * config/ho-sunos.h: remove some old function decls that conflict
+ w/ ANSI, and which weren't needed anyway
+
+Wed Jul 28 16:34:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.h (obj_frob_symbol): Renamed from tc_frob_symbol,
+ and disabled since it breaks Ian's new symbol-value code.
+
+ * expr.c (integer_constant): Accept more digits if BFD64.
+
+Wed Jul 28 11:30:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): If we have a normal constant when we
+ expect a bignum, turn it into a bignum. Output extra zeroes
+ before a short bignum, rather than after.
+
+Tue Jul 27 15:54:27 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * symbols.c (symbol_new): Conditionalize verify_symbol_chain call
+ on DEBUG_SYMS, not DEBUG.
+ (symbol_remove): Likewise.
+ (symbol_insert): Likewise.
+
+Tue Jul 27 08:45:05 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (mips_optimize): New static variable.
+ (append_insn): If mips_optimize == 0, always insert NOP
+ instructions. If mips_optimize < 2, don't swap branches.
+ (md_parse_option): If -Ox or -gx, set mips_optimize accordingly.
+
+Mon Jul 26 18:02:43 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (clean): if testsuite does not exist, then skip it.
+
+Fri Jul 23 14:13:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-mips.c (prev_insn_unreordered,
+ prev_prev_insn_unreordered): New static variables.
+ (append_insn): Don't swap branch instruction if
+ prev_prev_insn_unreordered (see comment).
+ (mips_no_prev_insn): Clear the unreordered variables.
+ (s_mipsset): When turning on reordering, set the unreordered
+ variables.
+
+Fri Jul 23 13:09:44 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Sections ".init" and ".fini"
+ are also magic, and have special default flag settings.
+ (obj_elf_frob_symbol): Since the return value from this function
+ isn't used, don't bother calling obj_elf_write_symbol_p, since it
+ doesn't accomplish anything else.
+
+ * config/tc-sparc.c (md_section_align): Round up section size only
+ for a.out format.
+
+ * symbols.c: Don't define DEBUG by default.
+
+Thu Jul 22 12:09:41 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c (fix_new_exp): Handle a O_uminus expression.
+
+ * expr.c (expr): Don't let absolute_section override
+ undefined_section for the return value.
+
+ * read.c (read_a_source_file): In NO_PSEUDO_DOT case, if we find a
+ pseudo-op with a poc_handler field of NULL, ignore it and treat it
+ as an instruction instead.
+ * config/tc-m88k.c (md_pseudo_table): Add "set" with a NULL
+ poc_handler field.
+
+ * config/tc-h8500.c (md_begin): Use a local variable when
+ initializing md_relax_table to avoid warnings about modifying a
+ supposedly const data structure.
+
+Thu Jul 22 10:58:51 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * config/obj-aout.c: Only include aout/aout64.h if BFD_ASSEMBLER
+ is defined.
+
+Wed Jul 21 17:32:02 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * configure.in (case ${host}): Map *-*-sysv4* to gas_host=sysv.
+ * configure.in (case ${generic_target}): Add i[34]86-*-sysv4*
+ case to set obj_format=elf. Must go before i386-*-sysv* case that
+ sets obj_format=coffbsd. Add *-*-sysv4* to *-*-elf and
+ *-*-solaris case, and move to before *-sysv* case that wants to
+ set obj_format to coff.
+ * config/tc-i386.c (i386_operand): Change all 'exp.X_op' to
+ 'exp->X_op'.
+ * config/tc-i386.c (md_apply_fix): Fix valp to be 'valueT *' for
+ BFD_ASSEMBLER case.
+
+Wed Jul 21 12:47:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-aout.c: Include aout/aout64.h.
+ (obj_aout_frob_symbol): Set BSF_DEBUGGING for a constructor
+ symbol, so that BFD doesn't tamper with the type.
+
+ * read.c (read_a_source_file): If NO_PSEUDO_DOT is defined, look
+ up opcodes as pseudo-ops even if they don't start with '.'.
+ * config/tc-m88k.h (NO_PSEUDO_DOT): Define.
+ * config/tc-m88k.c (md_assemble): Removed special pseudo-op
+ handling.
+ (md_apply_fix): Set fx_offset to the upper 16 bits of the reloc.
+ Output the low 16 bits for RELOC_HI16, not the high 16 bits.
+ * config/obj-coffbfd.c (do_relocs_for): If TC_M88K, set the
+ r_offset field of the reloc to the fixup offset.
+ (fixup_segments): If TC_M88K, don't warn about fixup overflows.
+ * doc/as.texinfo: Minor updates.
+
+Tue Jul 20 19:28:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Extensive changes to permit symbols to contain any expression
+ type and to delay the computation of the expression until the
+ value is actually needed. This permits setting symbols to values
+ calculated based on object code size. Expressions were changed to
+ no longer be in a section, to stop the overloading of segment and
+ expression type that previously occurred.
+
+ * as.c (big_section, pass1_section, diff_section, absent_section):
+ Removed.
+ (expr_section): Added (used for dummy symbols which hold
+ intermediate expression values).
+ (perform_an_assembly_pass): Create expr_section, do not create the
+ sections now removed.
+ * as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and
+ SEG_DIFFERENCE. Added SEG_EXPR.
+ (SEG_NORMAL): Corresponding changes.
+ * subsegs.c (seg_name, subsegs_begin): Changed accordingly.
+ * write.c (write_object_file): Ditto.
+ * config/obj-aout.c (seg_N_TYPE): Ditto.
+ * config/obj-bout.c (seg_N_TYPE): Ditto.
+ * config/obj-coff.c (seg_N_TYPE): Ditto.
+ * config/obj-coffbfd.c (seg_N_TYPE): Ditto.
+ * config/obj-vms.c (seg_N_TYPE): Ditto.
+
+ * expr.h (operatorT): Moved in from expr.c, added some values.
+ (expressionS): Added X_op field, removed X_seg field; renamed
+ X_subtract_symbol to X_op_symbol.
+ * expr.c: Extensive changes to assign expression types rather than
+ sections and to simplify the parsing.
+ * write.c (fix_new_internal): New static function.
+ (fix_new): Removed sub_symbol argument.
+ (fix_new_exp): New function, takes expression argument.
+ * write.h: Prototype changes for fix_new and fix_new_exp.
+ * cond.c (s_if): Changed accordingly.
+ * read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons,
+ parse_repeat_cons, get_segmented_expression,
+ get_known_segmented_expression, get_absolute_expression): Ditto.
+ * symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE):
+ Ditto.
+ * write.c (write_object_file): Ditto.
+ * config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto.
+ * config/obj-coffbfd.c (obj_coff_def, obj_coff_val,
+ obj_coff_endef, yank_symbols): Ditto.
+ * config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto.
+ * config/tc-a29k.c (md_assemble, parse_operand, machine_ip,
+ print_insn, md_operand): Ditto.
+ * config/tc-h8300.c (parse_exp, colonmod24, check_operand,
+ do_a_fix_imm, build_bytes): Ditto.
+ * config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist,
+ get_specific, check, insert, md_convert_frag): Ditto.
+ * config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa,
+ md_assemble, pa_ip, getExpression, getAbsoluteExpression,
+ evaluateAbsolute, pa_build_unwind_subspace, pa_entry,
+ process_exit): Ditto.
+ * config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative,
+ is_complex): Ditto.
+ * config/tc-i386.c (pe, md_assemble, i386_operand,
+ md_estimate_size_before_relax, md_create_long_jump): Ditto.
+ * config/tc-i860.c (md_assemble, getExpression, print_insn):
+ Ditto.
+ * config/tc-i960.c (parse_expr, subs, segs, md_convert_frag,
+ get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc,
+ i960_handle_align): Ditto.
+ * config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op,
+ subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1,
+ md_estimate_size_before_relax, md_create_long_jump, get_num):
+ Ditto.
+ * config/tc-m88k.c (md_assemble, get_imm16, get_pcr,
+ md_create_short_jump, md_create_long_jump): Ditto.
+ * config/tc-mips.c (md_assemble, append_insn, gp_reference,
+ macro_build, macro, my_getExpression): Ditto. Also removed
+ get_optional_absolute_expression; just use get_absolute_expression
+ instead.
+ * config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif,
+ fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto.
+ * config/tc-ns32k.h (fix_new_ns32k prototype): Ditto.
+ * config/tc-sh.c (parse_exp, check, insert, md_convert_frag):
+ Ditto.
+ * config/tc-sparc.c (md_assemble, sparc_ip, getExpression,
+ print_insn): Ditto.
+ * config/tc-tahoe.c (struct top, md_estimate_size_before_relax,
+ tip_op, md_assemble): Ditto.
+ * config/tc-vax.c (seg_of_operand, md_assemble,
+ md_estimate_size_before_relax, md_create_long_jump): Ditto.
+ * config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
+
+Tue Jul 20 12:17:16 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: i386-lynx is the same as i386-coff
+
+Mon Jul 19 15:21:20 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_previous): New function.
+ (previous_section, previous_subsection): New vars.
+ (obj_elf_section): Save current place in case DWARF code wants us
+ to pop back to it. Handle unquoted section name as well as quoted
+ section name. Don't crash on invalid strings.
+ (obj_pseudo_table): Handle new pseudos "previous", "2byte", and
+ "4byte".
+
+ * config/obj-elf.h: Don't include struc-symbol.h.
+ (obj_elf_frob_symbol): Declare arg as struct symbol *.
+
+ * tc-sparc.h (LOCAL_LABEL) [OBJ_ELF]: Local labels can start with
+ "L" or "_.L_".
+
+ * write.c (write_relocs): New function, split off from
+ write_contents. Use memset instead of bzero.
+ (write_object_file): Apply write_relocs to each section before
+ applying write_contents.
+
+ * read.c (read_begin): Call obstack_begin with values closer to 1K
+ multiples.
+ (read_a_source_file, big_cons, float_cons): Use memcpy instead of
+ bcopy.
+
+Mon Jul 19 14:30:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip_op): Don't decrement strend when
+ calculating opP->isiz; this permits the expression size to be
+ determined as well, later on.
+
+ * expr.c (clean_up_expression): Don't cancel the subtraction of
+ undefined symbols.
+
+ * read.c (s_data), config/obj-coffbfd.c (obj_coff_data): If -R,
+ switch to text section rather than data section.
+
+Mon Jul 19 12:35:39 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip, case AINDX): Add 6 to operand
+ expression (to take the pc-rel instruction itself into account)
+ before using the expression, instead of after.
+
+Fri Jul 16 08:56:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (float_cons): Simplified parsing logic. If
+ REPEAT_CONS_EXPRESSIONS is defined, accept a repeat count.
+
+ * symbols.c (colon): Rather than a special case for TC_HPPA,
+ use new macro tc_frob_label.
+ * config/tc-hppa.h (tc_frob_label): Define.
+
+ * config/tc-mips.c: Many changes to support simple assembler
+ optimization.
+ (insn_label, prev_insn, prev_prev_insn, dummy_opcode,
+ prev_insn_valid, prev_insn_frag, prev_insn_where,
+ prev_insn_fixp, prev_insn_is_delay_slot): New static
+ variables.
+ (insn_uses_reg, mips_no_prev_insn, mips_emit_delays,
+ mips_align, s_stringer, s_mips_space): New static functions.
+ (mips_define_label): New global function.
+ (md_pseudo_table): For "ascii", "asciz", "asciiz", call
+ s_stringer. Changed argument to float_cons from 0 or 1 to 'f'
+ or 'd'. For "space" call s_mips_space.
+ (md_begin): Call mips_no_prev_insn.
+ (append_insn): Only insert necessary NOP instructions.
+ (macro): Call mips_emit_delays before setting mips_noreorder.
+ Increment and decrement mips_noreorder rather than using
+ save_reorder_condition. Don't bother to use noreorder in
+ M_L_DOB and M_L_DAB, since append_insn will not insert a NOP.
+ (md_atof): Handle floating point numbers correctly for both
+ big and little endian targets.
+ (s_align, s_cons): Call mips_align rather than frag_align.
+ (s_change_seg, s_cons): Call mips_emit_delays.
+ (s_float_cons): Let float_cons do the work.
+ (s_mipsset): Call mips_emit_delays when setting noreorder.
+ * config/tc-mips.h (tc_frob_label): Define to be
+ mips_define_label.
+
+ * config/obj-ecoff.c (ecoff_build_symbols, ecoff_build_procs,
+ ecoff_frob_files): Consistently use S_GET_VALUE rather than
+ bfd_asymbol_value. Warn if taking difference of symbols in
+ different segments.
+
+Thu Jul 15 11:51:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_frob_file): Discard all open scopes,
+ with a warning.
+
+ * config/obj-coffbfd.c (fixup_segment): If TC_M88K, don't adjust
+ by md_pcrel_from if we are relocating against a symbol (we still
+ need md_pcrel_from for a PC relative relocation within the same
+ file).
+ * config/tc-m88k.c (md_pcrel_from): Corrected return value.
+ (omagic): Removed unused variable.
+
+ * Preliminary support for m88k-coff.
+ * configure.in (m88k-*-coff*): New target. Use coffbfd and
+ m88kcoff.
+ * config/m88kcoff.mt: New file.
+ * read.c (lex_type): New macro LEX_AT to set lex type of '@'.
+ (pseudo_set): Handle difference of symbols in different fragments
+ by saving the entire expression as the value of the symbol.
+ * symbols.c (resolve_symbol_value): Resolve difference
+ expressions.
+ * config/obj-coffbfd.c (obj_pseudo_table): If TC_M88K, accept
+ "sdef" as a synonym for "def".
+ * config/obj-coffbfd.h: If TC_M88K, include coff/m88k.h and set
+ TARGET_FORMAT.
+ (S_IS_LOCAL): Any symbol which includes \001 in the name is local.
+ * config/tc-m88k.c, config/tc-m88k.h: Numerous changes to bring
+ m88k port up to date, and to add COFF support.
+
+Wed Jul 14 15:09:32 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Removed sy_forward and replaced it with an undefined expression
+ as the value of a symbol.
+ * struc-symbol.h (struct symbol): Removed sy_forward field. Added
+ sy_resolved and sy_resolving single bit fields.
+ * symbols.c (symbol_new): Don't initialize sy_forward field.
+ (resolve_symbol_value): New function to adjust symbol value by
+ fragment address, using recursion to resolve forward symbols.
+ * symbols.h: Added prototype for new function.
+ * read.c (pseudo_set): Set symbolP->sy_value to an undefined
+ expression rather than setting symbolP->sy_forward.
+ * write.c (write_object_file): Use resolve_symbol_value on
+ symbols, keeping the common case (the old behaviour) inline.
+ * config/obj-aout.c (obj_aout_frob_symbol): Removed sy_forward
+ handling (subsumed by write.c change).
+ * config/obj-coff.c, config/obj-coffbfd.c (obj_coff_val): Set
+ sy_value rather than sy_forward.
+ * config/obj-coffbfd.c (obj_coff_endef, yank_symbols): Check
+ expression segment rather than sy_forward.
+ (yank_symbols): Use resolve_symbol_value.
+ (crawl_symbols): Removed extra pass over symbols.
+ * config/obj-aout.c, config/obj-bout.c, config/obj-coff.c,
+ config/obj-vms.c (obj_crawl_symbol_chain): Removed extra pass over
+ symbols which handled sy_forward; use resolve_symbol_value
+ instead.
+ * config/obj-coff.h, config/obj-coffbfd.h (obj_frob_forward_symbol):
+ Define.
+ * config/obj-elf.c (obj_elf_stab_generic): Check expression
+ segment rather than sy_forward.
+ * config/obj-vms.c (VMS_Check_For_Main): Don't initialize
+ sy_forward; do initialize sy_resolved and sy_resolving.
+ * config/tc-hppa.h (STAB_FIXUP): Use sy_value, not sy_forward.
+
+ * Changes to keep a full expression as the value of a symbol, not
+ just a longword:
+ * struc-symbol.h: New field sy_value.
+ * as.h: Include expr.h before struc-symbol.h.
+ * expr.h: Use struct symbol rather than symbolS.
+ * symbols.c (S_GET_VALUE, S_SET_VALUE): Rewrote to retrieve value
+ of sy_value field; compile unconditionally, not just if
+ BFD_ASSEMBLER.
+ * symbols.h: Compile S_{SG}ET_VALUE prototypes unconditionally.
+ * write.c (write_object_file): Set BFD symbol value to gas symbol
+ value.
+ * config/obj-aout.h, config/obj-bout.h, config/obj-coff.h,
+ config/obj-coffbfd.h, config/obj-generic.h, config/obj-vms.h
+ (S_GET_VALUE, S_SET_VALUE): Removed macro definitions.
+ * config/obj-ieee.c (S_GET_VALUE, S_SET_VALUE): Removed.
+ * config/obj-coff.h, obj-coffbfd.h: Rewrote several macros to use
+ S_GET_VALUE rather than ost_entry.n_value.
+ * config/obj-aout.c (obj_symbol_to_chars), config/obj-bout.c
+ (obj_symbol_to_chars), config/obj-coff.c (obj_symbol_to_chars),
+ config/obj-coffbfd.c (symbol_to_chars): Get value to write out
+ using S_GET_VALUE--don't assume it is already set.
+ * config/obj-ieee.c (do_symbols): Set BFD symbol value to gas
+ symbol value.
+ * config/obj-vms.c (various): Don't assign directly to
+ S_GET_VALUE; use S_SET_VALUE instead.
+
+Wed Jul 14 09:35:23 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Make sparc64-*-aout* use bfd gas.
+
+ * configure.in: Recognize h8300h.
+
+Tue Jul 13 12:09:44 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/tc-h8500.c (line_comment_chars): Add hash.
+ (parse_exp, skip_colonthing, build_bytes): Add support for
+ R_H8500_HIGH16 relocation type.
+
+Mon Jul 12 11:15:34 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * config/obj-elf.c (obj_elf_section): Allow `@' to introduce an
+ attribute name. Handle `execinstr' attribute.
+
+Mon Jul 12 07:22:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Don't warn on 'i' or 'j' mismatch if
+ there is another alternative for the instruction.
+
+Fri Jul 9 17:31:34 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: updates for H8/300H
+
+Thu Jul 8 14:41:43 1993 Mark Eichin (eichin@cygnus.com)
+
+ * config/tc-i960.c (md_create_short_jump, md_create_long_jump,
+ md_number_to_chars, md_section_align): Adjusted to use valueT,
+ addressT, to match tc.h.
+
+Thu Jul 8 14:15:05 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (s_common): Revamp to handle both syntaxes,
+ independent of format.
+
+Thu Jul 8 07:25:25 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-h8300.h (TC_CONS_RELOC): Use R_RELLONG if h8/300h.
+
+Wed Jul 7 18:11:07 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * configure.in: define CROSS=-DCROSS_COMPILE if it is a cross
+ build; also recognize h8300-*-coff
+
+Wed Jul 7 10:21:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * symbols.c (fb_label_instance, fb_label_instance_inc): Don't dump
+ core just because somebody uses a label before it is defined.
+
+ * config/mips-opcode.h: Moved to opcode/mips.h.
+ * config/tc-mips.c: Include opcode/mips.h rather than
+ mips-opcode.h.
+ (append_insn): An extra NOP is only needed after instructions
+ which set HI or LO, not after instructions which read it.
+ (macro_build, mips_ip): Support new 'E', 'G' and 'B' arguments.
+ (macro): cfc1 and ctc1 now take "t,G" rather than "t,d".
+ * config/tc-mips.h (struct mips_opcode): Don't define.
+ * config/mips-big.mt, config/mips-lit.mt (TARG_CPU_DEPENDENTS):
+ Set to $(srcdir)/../include/opcode/mips.h.
+
+ Get the MIPS assembler up to speed with other gas changes:
+
+ * config/obj-ecoff.c (ecoff_set_vma, ecoff_frob_symbol):
+ Removed; don't change the symbol value.
+ (ecoff_build_symbols, ecoff_build_procs, ecoff_frob_file): Use
+ bfd_asymbol_value rather than S_GET_VALUE to include section
+ vma in symbol value.
+ (ecoff_frob_file): Ignore BSF_SECTION_SYM symbols, since ECOFF
+ doesn't output them. Set the vma of sections.
+ * config/obj-ecoff.h: Don't define obj_frob_symbol.
+ * config/tc-mips.c (tc_gen_reloc): Adjustment by section vma is no
+ longer necessary.
+ (various): use valueT rather than long.
+
+Wed Jul 7 08:33:30 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.h (ENV64): Define for v9.
+
+ * config/tc-sparc.c (s_xword): For numbers, call big_cons.
+ (sparc_ip, md_apply_fix, tc_gen_reloc): Handle some sparc64
+ relocation types.
+ (md_number_to_chars): Handle 8-byte value.
+
+ * config/obj-elf.h (elf_symbol): For v9, use 64-bit symbol type.
+
+ * as.h (valueT): Typedef moved here.
+ * struc-symbol.h (valueT): ...from here.
+ * write.c (write_object_file): Locals from_addr, to_addr,
+ table_addr are now addressT. Supply prototype for bfd_alloc for
+ now.
+ (fixup_segment): Local add_number is now valueT. Correct some
+ range-checking bugs.
+ (relax_align): Type `int' should be sufficient for the exponent.
+ (fix_new): Argument offset is type offsetT. Locals size and
+ newsize are type valueT.
+ * write.h (struct fix): Fields fx_offset and fx_addnumber are now
+ type valueT.
+ (fix_new): Fix prototype.
+ * symbols.c (symbol_new): Symbol value is type valueT.
+ (S_SET_VALUE, S_GET_VALUE): Likewise.
+ (S_IS_*): Specify int return type explicitly.
+ * symbols.h (symbol_new, S_GET_VALUE, S_SET_VALUE): Fixed
+ prototypes.
+ * read.c (s_comm): Values read are type valueT.
+ * expr.h (expressionS): Field X_add_number is an offsetT.
+ * tc.h (md_create_long_jump, md_create_short_jump,
+ md_section_align): Addresses are now type addressT.
+ (md_number_to_chars, md_apply_fix): Pass value as valueT.
+ * config/tc-i386.c (md_create_short_jump, md_create_long_jump,
+ md_number_to_chars, md_section_align): Adjusted.
+ * config/tc-sparc.c (sparc_ip): Initialize `len' variable to make
+ gcc shut up.
+ (md_create_short_jump, md_create_long_jump, md_number_to_chars,
+ md_section_align): Adjusted.
+
+ * config/tc-sparc.c (s_reserve): Permit use for other than a.out
+ format.
+ (s_common): Handle Solaris-2 version.
+
+ * config/ho-generic.h (free): Returns void if __STDC__.
+
+ * config/obj-elf.h (obj_elf_frob_symbol, elf_frob_file,
+ elf_file_symbol): Declare.
+
+ * expr.c (floating_constant, integer_constant): Now return void.
+
+Thu Jul 1 12:13:43 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Match on sparc*-fujitsu-none rather than
+ sparclite*-fujitsu-none.
+
+Wed Jun 30 11:12:02 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (cons): Conditionalize parsing of expression. Move
+ putting value into object file into separate function. Separate
+ out MRI and WANT_BITFIELDS cases into separate functions.
+ (emit_expr): New function to write data into object file.
+ Conditionalize on TC_CONS_FIX_NEW and TC_CONS_RELOC rather than on
+ processor types.
+ (parse_bitfield_cons): New function to parse bitfield expressions
+ as used by i960 assemblers. Only compiled if
+ BITFIELD_CONS_EXPRESSIONS is defined.
+ (parse_mri_cons): New function to parse MRI style strings. Only
+ compiled if MRI is defined.
+ (parse_repeat_cons): New function to parse repeat counts. Only
+ compiled if REPEAT_CONS_EXPRESSIONS is defined.
+ * read.h (emit_expr): Added declaration of new function.
+ * config/tc-a29k.h (TC_CONS_RELOC): Define to be RELOC_32.
+ * config/tc-h8300.h (TC_CONS_RELOC): Define to be R_RELWORD.
+ * config/tc-hppa.c (parse_cons_expression_hppa): New function to
+ parse a HPPA expression, rather than special case in cons
+ function.
+ (cons_fix_new_hppa): New function to emit an HPPA fixup, rather
+ than special case in emit_expr function.
+ * config/tc-hppa.h (TC_PARSE_CONS_EXPRESSION, TC_CONS_FIX_NEW):
+ Define to use new functions from tc-hppa.c.
+ * config/tc-i960.h (BITFIELD_CONS_EXPRESSIONS): Define.
+ (WANT_BITFIELDS): Removed; now obsolete.
+ * config/tc-mips.h (REPEAT_CONS_EXPRESSIONS): Define.
+ * config/tc-ns32k.c (cons_fix_new_ns32k): New function to emit an
+ NS32K fixup, rather than special case in emit_expr function.
+ * config/tc-ns32k.h (TC_CONS_FIX_NEW): Define to be
+ cons_fix_new_ns32k. Also use PARAMS rather than checking
+ __STDC__.
+ * config/tc-sparc.h (TC_CONS_RELOC): Define to RELOC_32.
+
+ * write.c (relax_and_size_seg, adjust_reloc_syms, write_contents):
+ Don't core dump if gas has no information about a section.
+
+Wed Jun 30 06:21:27 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (md_begin): If sparcv9 is defined, reset
+ current_architecture to v9 automatically.
+
+ * config/tc-sparc.h (TARGET_FORMAT): Use elf64-sparc for v9.
+
+ * config/tc-sparc64.h, config/tc-sparc64.c: New files.
+ * configure.in: Use sparc64 cpu files for v9, and default to elf
+ format.
+
+ * write.c (relax_and_size_seg): Always fully process a section.
+ Section size is last frag's (vm)address plus its size. If no
+ relocations are present, force SEC_RELOC flag clear.
+ (dump_section_relocs): New debugging routine.
+ (adjust_reloc_syms): New routine, broken out from write_contents.
+ Don't adjust relocs that are already relative to section symbol.
+ Look for obj_fix_adjustable macro to know what else to skip,
+ instead of obj_write_symbol. Look for section symbol stored in
+ section information.
+ (write_object_file): Map adjust_reloc_syms over all sections.
+ (write_contents): Clear SEC_RELOC flag if no relocations are
+ found.
+
+ * as.h (__PTR_TO_INT, __INT_TO_PTR): New versions for Saber, to
+ keep it quiet.
+
+ * write.c (remove_subsegs): Don't define for BFD_ASSEMBLER.
+
+Fri Jun 25 14:42:53 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (all, dvi, info, install-info, clean-info): do not
+ echo recursion lines.
+ (install-info, clean-info): collapse into the dvi and info rule.
+
+Fri Jun 25 10:47:24 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Remove support for %d/%q fp regs.
+ All fp regs are now specified as %f.
+ (priv_reg_table): fpq -> fq.
+
+Fri Jun 25 03:43:06 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * as.h (strstr): Disable declaration for now.
+ (fprint_value, sprint_value): Declare.
+
+ * subsegs.c (subseg_new_rest): Use memset to clear new frag.
+ (subseg_new) [BFD_ASSEMBLER]: Initialize all seginfo fields.
+
+ * expr.c (expr_part): Made sanity checks a.out-specific.
+ (expr): Disabled sanity checks.
+
+ * subsegs.h (segment_info_type) [BFD_ASSEMBLER]: Add field for
+ section symbol.
+ * subsegs.c (subseg_change): Initialize section symbol pointer
+ when setting up a new section.
+
+ * symbols.c (symbol_new) [BFD_ASSEMBLER]: Point BFD symbol's udata
+ field back at gas symbol structure.
+
+ * symbols.c (colon): Cast obstack_next_free value to char* before
+ doing arithmetic on it.
+ * subsegs.c (subseg_new_rest): Likewise.
+ * as.h (frag_now_fix): Likewise.
+
+ * config/obj-elf.c (elf_file_symbol): Use subseg_new instead of
+ calling bfd_make_section_old_way directly, and call subseg_set
+ instead of subseg_change. Now returns void.
+ (obj_elf_write_symbol): Only check local symbols for now.
+ (elf_stab_symbol): Now static and void, and disabled until it
+ works completely.
+ (obj_elf_size): For expression values, fail silently for now.
+ (obj_symbol_new_hook): Do nothing.
+
+ * config/tc-sparc.c (tc_gen_reloc): Handle BFD_RELOC_SPARC_WDISP22
+ relocation.
+ (s_local) [OBJ_ELF]: New function.
+ (md_pseudo_table) [OBJ_ELF]: Call it for "local".
+ (s_common): Rearrange to handle Solaris .common pseudo, which may
+ sometimes use bss space instead of common.
+ * config/obj-elf.h (TARGET_SYMBOL_FIELDS): Add new `local' field.
+
+Thu Jun 24 16:33:53 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: set host config to hpux for hppa*-hp-hpux
+
+Thu Jun 24 13:35:06 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * app.c (app_pop, app_push): Fix bug reported by Chris Arthur.
+
+Tue Jun 22 01:04:23 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * subsegs.c (subseg_new): Don't special-case a.out -R flag here.
+ * config/obj-aout.c (s_sect): Do it here.
+
+ * as.h (BAD_CASE): Don't make some lame compilers think we want
+ substitution inside strings.
+
+ * as.c (print_version_id): New function, split off from main.
+ (main): Call it.
+ * config/tc-sparc.c (md_parse_option) [OBJ_ELF]: Print version id
+ for -V. Ignore -Q and -s options for now.
+
+Mon Jun 21 17:37:59 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: make installation & builds work again for crosses
+
+Sun Jun 20 18:18:26 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * listing.c (list_symbol_table): Rewrite to print wide (>32 bits)
+ symbol values correctly.
+
+ * write.c (write_object_file): Deleted unused variables.
+ (fixup_segment): Use sprint_value.
+
+ * messages.c (sprint_value, fprint_value): New routines.
+
+ * config/obj-elf.c (elf_stab_symbol): Now returns void.
+ (obj_elf_stab_generic): Fix typo in logic.
+
+ * Makefile.in (INCLUDES): Look in ../bfd for bfd.h.
+
+ * as.h (addressT, offsetT): New types, using BFD types if
+ available.
+ (relax_addressT, struct frag): Use them.
+ * struc-symbol.h (valueT, struct broken_word): Likewise.
+
+ * as.h (subseg_new) [BFD_ASSEMBLER]: Name argument is const.
+ * subsegs.c (subseg_new) [BFD_ASSEMBLER]: Name argument is const.
+
+Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: canonicalize install.sh; for use within
+ this directory (and subdirs)
+
+Sun Jun 20 02:34:04 1993 Ashley Saulsbury (ans@sics.se)
+
+ * m88k-opcode.h : fixed tiny tiny mistake - xcr was incorrectly
+ specified, should have both S1 and S2 fields identical
+ If only finding the problem was as fast as fixing the bug !!!!
+
+Tue Jun 15 16:01:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_contents): Do write out non-loadable sections.
+ Debug sections can fall in this category.
+
+ * read.c (s_app_file): Call elf_file_symbol for ELF files.
+ * config/obj-elf.c (elf_file_symbol): New function.
+
+ * config/obj-elf.c (elf_stab_symbol_string): Renamed from pa_...,
+ added argument to specify section base name.
+ (obj_elf_stab_generic): Renamed from ..._stab. New argument
+ specifies section base name.
+ (obj_elf_stab): New function, calls obj_elf_stab_generic with
+ ".stab" as section base name.
+ (obj_elf_xstab): New function, calls obj_elf_stab_generic.
+ (obj_elf_type): Handle "object". Use bitwise-or to merge in
+ symbol flags rather than simply replacing, so global/local flags
+ are preserved.
+ (obj_elf_ident): Rewrite.
+
+Tue Jun 15 17:03:25 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: remove parentdir support; use INSTALL_XFORM
+
+Wed Jun 9 11:26:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-i386.c (md_pseudo_table): .align uses a power of two
+ for any a.out target, not just Linux and 386BSD.
+ * config/tc-i386.h (DOT_LABEL_PREFIX): Do not define for any a.out
+ target.
+
+Mon Jun 7 13:33:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m88k.c: Don't include flonum.h, md.h, m88k.h. They
+ don't exist or duplicate other inclusions.
+
+ * config/tc-vax.h (NO_RELOC): Define.
+
+Mon Jun 7 09:55:03 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Fix parsing of asi number.
+ Fix error message.
+
+Sat Jun 5 19:32:52 1993 Torbjorn Granlund (tege@nada.kth.se)
+
+ * gas/config/m88k-opcode.h (m88k_opcodes): Add 88110 instructions.
+ * gas/config/tc-m88k.c (get_reg): New arg reg_prefix. Compare first
+ char to reg_prefix instead of to 'r'.
+ (calcop): Change calls to get_reg.
+ (calcop): Handle new case 'x' to set reg_prefix.
+ (calcop): Set reg_prefix to 'r' after each call to get_reg.
+ (cmpslot): Add 88110 conditions.
+
+ * gas/config/m88k-opcode.h: Swap cases for "rot" for consistency.
+
+ * gas/config/tc-m88k.c (get_bf): Always restore input_line_pointer
+ before returning.
+
+ * gas/config/m88k-opcode.h (m88k_opcodes): Make equal mnemonics
+ adjacent; mov.s and mov.d swapped.
+ (m88k_opcodes): Fix typo `r2' -> `2'.
+
+Fri Jun 4 15:59:31 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/h8300.c: Support for H8/300-H opcodes.
+
+ * config/obj-coffbfd.c (w_strings): String table length is 4
+ bytes, no matter what the host int size is.
+
+ * configure.in (alpha-*-osf*): New.
+
+Fri Jun 4 07:51:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-*-ecoffl*): New target; use ecoff and
+ mips-lit.
+ (mips-*-ecoff*): Added trailing '*'.
+
+ * config/obj-ecoff.c (ecoff_build_procs): Force the adr of the
+ first FDR in a file to be zero.
+
+Thu Jun 3 14:09:59 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (VERSION): Jump to 2.1.4.
+
+ * config/ho-hppabsd.h: New file, from Peter Hoogenboom.
+
+ * config/tc-mips.c (md_assemble): Call bfd_set_gp_size only for
+ ECOFF format.
+
+Tue Jun 1 15:21:57 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (md_assemble): The 68040 cpu doesn't want a
+ separate '851 mmu.
+
+ * config/obj-elf.c, config/obj-elf.h: Update for new type, macro,
+ and routine names. Assuming 32 bits for now.
+
+ * config/obj-elf.c (elf_frob_file): Look for macro
+ elf_tc_final_processing_hook, instead of assuming a function
+ always exists.
+ * config/tc-hppa.c (elf_hppa_final_processing_hook): Renamed from
+ tc_final_processing_hook.
+ * config/tc-hppa.h (elf_tc_final_processing_hook): Use it.
+
+ * config/tc-hppa.h (elf_tc_symbol, elf_tc_make_sections): Macros
+ moved here from obj-elf.h.
+ * config/obj-elf.h: Don't include CPU-specific header files.
+
+Sun May 30 16:49:37 1993 Peter Hoogenboom (hoogen@fast.cs.utah.edu)
+
+ * configure.in: configurations should match on 'hppa*' not 'hppa'.
+
+ * read.c: Add support for HPPA assembly language syntax (denoted
+ with '#ifdef TC_HPPA').
+
+ * symbols.c: Add support for HPPA assembly language syntax (denoted
+ with '#ifdef TC_HPPA').
+
+ * write.c (write_contents): Add support for HPPA-style
+ relocations.
+
+ * config/obj-elf.c: Stab symbols weren't written properly.
+ (obj_elf_version):
+ (obj_elf_desc):
+ (obj_elf_write_symbol):
+ (obj_elf_write_symbol_p):
+ (obj_elf_frob_symbol):
+ (elf_stab_symbol):
+ (elf_frob_file):
+
+ * config/tc-hppa.c: Support for HPPA symbol extension sections.
+ Remove some unused code. Support for HPPA assembly language
+ syntax.
+
+ * app.c:
+
+ * symbols.c:
+
+ * config/obj-elf.h:
+ (obj_write_symbol):
+ (obj_frob_file):
+ (elf_tc_symbol):
+ (elf_tc_make_sections):
+
+ * config/tc-hppa.h:
+
+Sun May 30 21:44:45 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/obj-ecoff.c (obj_read_begin_hook, add_file): Assume
+ hash_new will have succeeded if it returns.
+ * config/tc-a29k.c (md_begin): Likewise.
+
+ * config/tc-i386.c (tc_aout_fix_to_chars): Now nbytes_r_length is
+ const.
+ (mode_from_disp_size, opcode_suffic_to_type): Now inline under
+ gcc.
+ (fits_in_{signed,unsigned}_{byte,word}): Likewise.
+
+ * expr.c: Delete register declarations; gcc ignores them anyways.
+
+Fri May 28 19:03:32 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hash.c (hash_new): Use xmalloc, since many callers don't check
+ for failure.
+
+Thu May 27 13:02:15 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * frags.c (zero_address_frag, bss_address_frag): These are
+ external.
+
+ * tc.h (md_reloc_size): This is const.
+ * config/tc-{a29k,h8300,h8500,i386,i860,i960,m68k,ns32k,z8k}.c
+ (md_reloc_size): Now const.
+
+ * config/aout_gnu.h (enum machine_type, enum reloc_type): Delete
+ trailing commas.
+ * as.h (enum _segT): Ditto.
+
+ * struc-symbol.h (N_TYPE_seg): This should be const.
+
+Thu May 27 11:43:59 1993 Michael Meissner (meissner@osf.org)
+
+ * config/obj-ecoff.c (add_file): Cast file_name to char * in
+ listing_source_file call.
+
+ * config/obj-elf.c (elf_stab_symbol_string): Cast first argument
+ of subseg_new call to eliminate const attribute.
+ (obj_elf_stab): Ditto.
+ (obj_symbol_new_hook): Cast first argument of bzero call to char *.
+
+ * read.c (s_align_bytes): Properly record alignment.
+
+ * expr.c (__): Undefine __ macro before use, since OSF/1 uses it
+ for the prototype/no prototype macro.
+
+ * as.c (got_sig): Don't do return ((SIGTY) 0), SIGTY might well be
+ void.
+
+ * as.h (relax_stateT enum): Delete trailing comma.
+
+Thu May 27 11:07:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c (do_scrub_begin): Let line_comment_chars override
+ comment_chars.
+ (do_scrub_next_char): If a line comment character is not at the
+ start of a line, treat it as a comment character if it is one.
+ For a CPP line comment use pseudo-op .appline rather than .line.
+ * input-scrub.c (logical_input_line): Make int rather than
+ unsigned.
+ (input_scrub_push, input_scrub_begin): Initialize
+ logical_input_line to -1 rather than 0.
+ (bump_line_counters): Increment logical_input_line.
+ (new_logical_line): If line_number is -2, decrement
+ logical_input_line.
+ (as_where): Use logical_input_line even if it is 0.
+ * read.h (s_app_file prototype): Now takes an int argument.
+ * read.c (potable): Make .appfile call s_app_file with 1. New
+ .appline pseudo-op calls s_app_line.
+ (s_app_file): If .appfile, call new_logical_line with -2 to
+ account for newline inserted by do_scrub_next_char. If listing,
+ call listing_source_file.
+ (s_app_line): New function to handle fake pseudo-op .appline.
+ * config/obj-coff.c (obj_pseudo_table): Make .appline call
+ obj_coff_ln.
+ (obj_coff_ln): Added argument to indicate whether .appline.
+ * config/obj-coffbfd.c (obj_pseudo_table): Make .appline call
+ obj_coff_ln.
+ (obj_coff_ln): Added argument to indicate whether .appline.
+ * config/tc-mips.c (s_file): Pass argument to s_app_file.
+
+Tue May 25 11:59:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-bout.h (S_GET_VALUE): Removed unnecessary cast.
+
+Thu May 20 19:14:24 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (md_apply_fix_2): Straighten out check for
+ invalid values.
+
+Wed May 19 07:33:17 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * config/tc-h5000.c (build_bytes): Understand @rd mode and build
+ relocations correctly.
+
+Mon May 17 15:06:26 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Leave out TEXI2DVI for now, because
+ it's wrong.
+
+ * config/tc-m68k.c (md_apply_fix_2): Apply range checks and warn
+ if value is out of range.
+
+ Patch from Minh Tran-Le:
+ * config/tc-i386.c (i386_operand): For in/out port register used
+ as base reg, include InOutPortReg in operand type.
+ (MATCH): Accept overlap value of InOutPortReg.
+
+Mon May 17 09:29:34 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c (add_file, obj_ecoff_loc, obj_ecoff_stab):
+ Add calls to listing routines to produce combined source/assembler
+ listings.
+ (obj_ecoff_stab): Create a file pointer if none used yet.
+ (ecoff_frob_file): Set symcount to correct value.
+
+Fri May 14 06:53:33 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Makefile.in (VERSION): Bump to version 2.1, in preparation for
+ release.
+
+ * config/obj-aout.h (H_GET_HEADER_SIZE, H_SET_SYMBOL_TABLE_SIZE):
+ Define in terms of constants, not C structure sizes.
+
+ * config/tc-rs6000.c, config/tc-rs6000.h: Delete empty files.
+
+Thu May 13 17:01:55 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-aout.c (obj_header_append): Don't define if it's
+ defined as a macro.
+ * config/obj-hp300.h (obj_header_append): Define it as a macro.
+ * config/obj-hp300.c (hp300_header_append): New function.
+
+ * Makefile.in (distclean): Don't bother cleaning up doc files;
+ they aren't going to be in this directory.
+
+Thu May 13 07:51:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c (ecoff_build_symbols): Handle absolute
+ symbols.
+
+ * tc.h (TC_COFF_SIZEMACHDEP): Don't define here.
+ * config/tc-sh.h (TC_COFF_SIZEMACHDEP): Define here instead.
+
+Mon May 10 06:01:12 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/obj-vms.c (VMS_Symbol_type_list): Don't bother with
+ initialization.
+
+ * configure.in (targets): Treat m68*-*-sysv* like m68k-*-coff.
+
+Wed May 5 14:00:49 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (macro): Correct floating point double word
+ loads and stores for big endian target.
+
+Wed May 5 08:39:21 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * config/tc-i386.c: Replace SEG_* with *_section, fix up subseg_*
+ calls. Deleted some unused code.
+ * config/obj-coff.c: Likewise.
+
+ ELF support, mostly contributed by Utah:
+ * config/obj-elf.c (obj_elf_section, obj_elf_stab, obj_elf_line,
+ obj_elf_type): Rewrite.
+ (obj_elf_frob_symbol, elf_stab_symbol_string, elf_stab_symbol,
+ obj_elf_desc, obj_elf_version, obj_symbol_new_hook, obj_elf_size):
+ New functions.
+ (obj_elf_ident): Dummy.
+ * config/obj-elf.h (FALSE, TRUE, S_*, tc_frob_symbol,
+ TARGET_SYMBOL_FIELDS): New macros.
+ (gdb_section): New variable decl.
+
+ * config/tc-i386.c (md_atof): Return zero, not empty string, on
+ success.
+
+ BFD_ASSEMBLER conditional changes:
+ * config/obj-coff.c (lineno_rootP, seg_N_TYPE, *_section_header):
+ Don't define these.
+ (SA_SET_SYM_ENDNDX, SA_SET_SYM_TAGNDX): New functions.
+ (fetch_coff_debug_section): Ditto.
+ (obj_coff_endef): Call fetch_coff_debug_section.
+ (struct line_no): New type.
+ (c_symbol_merge): New way for copying aux fields.
+ (c_dot_file_symbol): Put symbol in absolute section, and set flag
+ BSF_DEBUGGING.
+ (function_lineoff): New symbol.
+ (function_lineoff, text_lineno_number, our_lineno_number,
+ lineno_lastP): Don't define.
+ (c_line_new): Don't define.
+ (obj_emit_lineno, obj_coff_endef): Use abort calls as, uh,
+ placeholders, until
+ line-number recording gets implemented.
+ (obj_new_symbol_hook): New code for handling aux fields.
+ (add_lineno, add_linesym): New functions.
+ (obj_coff_ln): Call add_lineno, not c_line_new.
+ (obj_coff_endef): New code for handling symbol names. New lineno
+ code. Look for section name "*DEBUG*" for debugging section.
+ (align, coff_check_file_symbols, obj_coff_section,
+ coff_frob_file): New functions.
+ * config/obj-coff.h: Reordered some includes.
+ (BYTE_ORDERING, FILE_HEADER_MAGIC, seg_N_TYPE, N_TYPE_seg,
+ DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE, AOUTHDR, AOUTHDRSIZE): Don't
+ define these.
+ (TARGET_SYMBOL_FIELDS, I960_SYM_FIELDS): New macros.
+ (SYM_AUXENT): New macro (for non-BFD_ASSEMBLER too) for accessing
+ aux entries. Most SA_* macros now use it unconditionally.
+ (S_*): Use `bsym' field, and access BFD private data.
+ (SF_*): Use `sy_flags' symbol field for most of these.
+ (H_*, object_headers, lineno, lineno_*P, OBJ_EMIT_LINENO): Don't
+ define.
+ (*_section_header): Don't define.
+ * config/tc-i386.c (md_convert_frag, md_apply_fix): Changed
+ interface.
+ (tc_gen_reloc) [I386COFF]: New function.
+ (tc_aout_fix_to_chars, tc_coff_fix2rtype): Don't define.
+ * config/tc-i386.h (TARGET_ARCH, TARGET_BYTES_BIG_ENDIAN): New
+ macros.
+
+ * config/obj-coff.c (stack_init): Don't do assignments inside
+ conditions.
+ (obj_coff_def): Simplified handling of symbol name a bit.
+ (tag_insert): Name argument is now pointer to CONST.
+ (obj_crawl_symbol_chain): Commented out.
+
+ * config/obj-coff.h: Use PARAMS macro in prototypes.
+
+ * write.c (relax_and_size_seg) [BFD_ASSEMBLER]: Don't indirect
+ through frchainP pointer if it is null.
+
+ * configure.in: Warn if BFD mode is explicitly turned off but is
+ required by specified target.
+ (mips ecoff targets): Don't need to set bfd_gas here; it gets
+ taken care of later.
+
+ * config/obj-coffbfd.c (crawl_symbols): Don't clear sy_forward
+ field.
+ (yank_symbols): Merge symbols only if sy_forward is null.
+
+ * config/tc-m68k.h (AOUT_MACHTYPE): Don't define if already
+ defined.
+
+ * tc.h (md_convert_frag) [BFD_ASSEMBLER]: Section arg is not
+ pointer.
+ * config/tc-m68k.c (md_convert_frag) [BFD_ASSEMBLER]: Ditto.
+
+ * config/tc-sparc.h (LOCAL_LABEL) [OBJ_ELF]: Anything starting
+ with "." is a local label.
+
+ * config/te-hppa.h, config/tc-hppa.h, config/tc-hppa.c: New config
+ files.
+
+ * config/te-linux.h, config/te-386bsd.h: New config files.
+ * configure.in (i386-*-linux, i386-*-bsd): Use them.
+ * config/tc-i386.h (TARGET_FORMAT): Select format based on target
+ environment.
+ (DOT_LABEL_PREFIX): Don't define for 386bsd or Linux.
+
+Wed May 5 13:14:01 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c (init_file): Set fMerge to 0 since dbx seems
+ to want it that way.
+ (ecoff_build_symbols): Turn local st_Proc symbols into
+ st_StaticProc symbols. Set index field of external st_Proc and
+ st_staticProc symbols correctly.
+ * config/tc-mips.h (NO_LISTING): Don't define. People might want
+ listings.
+
+Tue May 4 21:22:54 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-hp300.h, config/obj-hp300.c, config/te-hp300.h: New
+ files.
+ * configure.in (m68k-*-hpux): Use them.
+
+ * config/obj-aout.c (obj_pre_write_hook): Use AOUT_VERSION if
+ defined, otherwise zero.
+
+ * config/aout_gnu.h (OMAGIC): Don't define if already defined.
+
+Mon May 3 15:59:32 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Allow any abs expression as an
+ address space number.
+
+Wed Apr 28 19:11:22 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * config/obj-aout.h (TARGET_DEFAULT): Don't default this at all.
+
+ * config/tc-a29k.c: Include ctype.h.
+ (define_some_regs): Added special-purpose registers for 29050.
+
+ * config/tc-i386.c (comment_chars) [TE_I386AIX]: Include "/".
+
+ * config/obj-coffbfd.c (fill_section): Don't set STYP_REG here.
+ (change_to_section): Set it here instead.
+
+Wed Apr 28 13:40:29 1993 Ian Lance Taylor (ian@rtl.cygnus.com)
+
+ * config/obj-ecoff.c (obj_symbol_new_hook): Make up a .file if one
+ hasn't been seen yet.
+ (add_ecoff_symbol): Don't refer to cur_file_ptr if it is NULL.
+
+Mon Apr 26 18:29:05 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-sh.ch, config/tc-sh.h: New files supporting Hitachi
+ SH.
+
+Mon Apr 26 12:28:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * expr.c (operand): Fix unary plus operator (previously was the
+ same as '~' operator!).
+
+Wed Apr 21 00:20:11 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (cvt_frag_to_fill): Define even if BFD is defined.
+ (write_object_file): Do define if BFD_ASSEMBLER. Invoke
+ obj_check_file_symbols if defined. Call verify_symbol_chain_2
+ instead of open-coding it. Fix some bugs in patching up symbol
+ chain.
+ (relax_segment): Make some code we "ought to be able to" use for
+ all targets no longer conditionalized on ns32k target; instead, do
+ it always, and if the appropriate conditions fail, abort.
+
+ * symbols.c (DEBUG): Enabled.
+ (symbol_new): Make sure bfd_make_empty_symbol works.
+ (verify_symbol_chain_2): New function; takes one symbol as
+ argument, anywhere in the chain.
+ (dollar_label*): Use default initializers.
+
+ * as.c (perform_an_assembly_pass): Call md_begin here...
+ (main): ...and not here.
+
+ * config/tc-m68k.h (TARGET_FORMAT): Use a.out-sunos-big for a.out.
+ (tc_frob_symbol): New macro: Get rid of symbols in reg_section.
+
+ * config/tc-m68k.c (omagic): Don't define for BFD_ASSEMBLER.
+ (add_fix, add_frag): Now functions instead of macros.
+ (m68k_reg_parse, m68k_ip, md_estimate_size_before_relax, get_num,
+ s_data1, s_data2, s_bss): Use new *_section names, for
+ compatibility with BFD_ASSEMBLER mode; rewrite switch statements
+ to handle non-integral segT.
+ (tc_coff_fix2rtype, tc_aout_fix_to_chars,
+ tc_coff_symbol_emit_hook): Don't define for BFD_ASSEMBLER.
+ (tc_gen_reloc): New routine for BFD_ASSEMBLER.
+ (md_apply_fix, md_apply_fix_2): Renamed old md_apply_fix to
+ md_apply_fix_2; new md_apply_fix definition varies interface
+ depending on BFD_ASSEMBLER.
+ (md_convert_frag, md_convert_frag_1): Likewise. Use new *_section
+ names.
+
+ * config/obj-vms.c: Include config.h.
+ (version_string): Delete declaration.
+ (Write_VMS_MHD_Records): Use GAS_VERSION instead.
+ (vms_resolve_symbol_redef): New function, taken from VMS code in
+ symbols.c.
+ (_doprnt): Deleted.
+ (VMS_Store_Struct, VMS_Def_Struct, VMS_Set_Struct,
+ VMS_TBT_Block_End, get_VMS_time_on_unix, generate_suffix,
+ VMS_Psect_Spec): Fixed to compile under traditional C.
+ * config/obj-vms.h: Use PARAMS macro.
+ (vms_resolve_symbol_redef): Declare.
+ (RESOLVE_SYMBOL_REDEFINITION): New macro.
+ * symbols.c (colon): Remove some VMS-specific code, look for
+ RESOLVE_SYMBOL_REDEFINITION macro instead.
+
+ * config/tc-m68k.c (m68k_ip): Don't try expanding DBcc
+ instructions.
+
+ * config/tc-i386.c: Reordered some functions so inlining might
+ work. Use PARAMS in function declarations.
+ (reloc): New routine.
+ (md_assemble): Rearrange switch statements to work with
+ non-integral segT.
+
+ * struc-symbol.h [BFD_ASSEMBLER]: Undefine
+ SYMBOLS_NEED_BACKPOINTERS before defining it.
+
+ * subsegs.c (subseg_new_rest): Now static.
+
+ * read.c (pseudo_set): Better error message for difference of
+ symbols in different frags.
+
+ * Makefile.in (check): Pass down some new variables, indicating
+ pathname or program name for cc, nm, objdump.
+
+ * as.h (OUTPUT_FLAVOR): New macro.
+ * config/tc-sparc.c (tc_gen_reloc): Use OUTPUT_FLAVOR.
+
+ * configure.in: Initialize bfd_gas properly. Warn that ELF
+ support is incomplete.
+
+Thu Apr 15 22:39:05 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c (float_cons): Accept null pointer return from md_atof.
+ * config/tc-m68k.c (md_atof): Return null for success.
+ * config/tc-sparc.c (md_atof): Ditto.
+
+Thu Apr 15 16:04:39 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: formatting and comment cleanups; show SPARC
+ alternative options in same style as other machines; simplify some
+ conditional use; include GPL as separate file (from texinfo dir)
+
+ * doc/Makefile.in: (as.info) include directory containing GPL in
+ makeinfo search path
+
+ * doc/h8.texi: new file; conditional settings for GAS manual
+ on Hitachi chips
+
+Tue Apr 13 15:31:40 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: mention SPARC architecture options.
+
+Fri Apr 9 17:43:11 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in: Rearranged whitespace in per-host/per-target
+ sections. Added hooks for dropping in HPPA support (not included
+ yet). Separate out overrides of variables based on target format
+ and bfd-gas selection from actual target-specific commands. Add
+ error message for recognized but unsupported format name.
+
+Fri Apr 9 09:05:47 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.h (ecoff_build_lineno): Make ilineMax in
+ symbolic header match cline in FDR; the native linker seems to
+ want that.
+
+Thu Apr 8 15:51:28 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * doc/Makefile.in: as.texinfo is in $(srcdir). Use
+ $(srcdir)/as.texinfo explicitly in several places
+
+Thu Apr 8 15:15:02 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/Makefile.in: update dvi, clean targets for new source
+ file structure
+
+Thu Apr 8 12:52:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/ho-decstatn.h: Define BROKEN_ASSERT if not __GNUC__,
+ rather than undefining know.
+ * configure.in: Match ultrix*, not just ultrix.
+
+Wed Apr 7 20:18:10 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * doc/as.texinfo: converted conditional markup to use new
+ Texinfo facilities, avoiding m4.
+
+ * doc/as-all.texinfo, all.m4, pretex.m4: deleted.
+
+ * doc/Makefile.in: recast doc configuration to use a link to an
+ included texinfo file.
+
+ * doc/all.texi: settings for generic form of documentation.
+
+Tue Apr 6 11:56:21 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (cons): Zero out frag when creating reloc.
+
+Mon Apr 5 09:41:58 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (gp_reference): Certain magic symbols can never
+ be referenced off the GP register.
+
+ * app.c (do_scrub_next_char): Handle states 9 and 10 correctly
+ when dealing with characters of type LEX_IS_TWOCHAR_COMMENT_1ST,
+ LEX_IS_STRINGQUOTE, and LEX_IS_ONECHAR_QUOTE.
+
+ * config/te-irix.h: New file; irix needs a different LOCAL_LABEL
+ definition from other MIPS targets.
+ * configure.in (mips-*-irix): Use emulation irix.
+
+Sun Apr 4 15:21:09 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-h8500.c: Get relax size of branch instructions right,
+ (get_operand): Parse @sp+ correctly.
+
+Fri Apr 2 15:59:49 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * subsegs.h (segment_info_type) [BFD_ASSEMBLER]: Don't include
+ COFF section header field.
+
+ * configure.in: Print error message if host or target is not
+ supported.
+
+ * configure.in: If with-bfd-assembler, use obj-coff instead of
+ obj-coffbfd.
+
+ * config/ho-generic.h: Include string.h.
+
+Fri Apr 2 08:54:57 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.h (LOCAL_LABEL): Treat any label starting with
+ '$' as local, for any object file format.
+
+ * config/tc-mips.c (macro): Optimizations to branching code and a
+ couple of bug fixes from ralphc@pyrps5.eng.pyramid.com (Ralph
+ Campbell).
+
+ * config/ho-irix.h: New file; if not gcc, define BROKEN_ASSERT.
+ * configure.in (mips-sgi-irix*): Set gas_host to irix.
+
+Wed Mar 31 17:53:54 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * subsegs.c (subseg_new): Set output_section of new section.
+ * as.c (perform_an_assemly_pass): Don't set output_section here.
+ * expr.c (expr_part, expr): Turn off section assertions for ECOFF,
+ since it has additional sections.
+ * read.c (s_lcomm): For MIPS ECOFF, put small objects in .sbss,
+ not bss_section.
+ * config/obj-ecoff.h (TARGET_SYMBOL_FIELDS): Added
+ ecoff_undefined field.
+ * config/obj-ecoff.c (obj_symbol_new_hook): Initialize
+ ecoff_undefined field.
+ (add_file): If using stabs, just output a stabs symbol rather than
+ creating a new fdr.
+ (obj_ecoff_begin, obj_ecoff_bend): Ignore line number by reading
+ it with get_absolute_expression, rather than skipping it by hand.
+ (obj_ecoff_loc): If using stabs, just output a stabs symbol rather
+ than ECOFF line number information.
+ (obj_ecoff_stab): Accept non-zero values for stabs line number.
+ (ecoff_build_symbols): Set ifilesym correctly. Set storage class
+ to small, undefined and/or readonly sections if appropriate.
+ Don't output symbol names containing \001 characters.
+ (ecoff_frob_file): Make sure at least one fdr is output.
+ * config/tc-mips.h: Define TC_MIPS.
+ * config/tc-mips.c (g_switch_value): New static variable.
+ (md_assemble): Set gp size of output BFD.
+ (gp_reference): New function; returns 1 if expression can be
+ accesssed via gp. Always returns 0 if not using ECOFF.
+ (macro_build): Convert BFD_RELOC_LO16 to BFD_RELOC_MIPS_GPREL if
+ possible.
+ (macro): Generate sequences using gp if possible.
+ (md_parse_option): Ignore -EL and -EB. Parse -G.
+ (md_apply_fix): Added BFD_RELOC_MIPS_GPREL to ignored case.
+ (s_change_sec): Handle .rdata and .sdata for ECOFF.
+ (s_extern): Mark symbol as external. Set ecoff_undefined field.
+
+Tue Mar 30 10:11:41 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * output-file.c (output_file_create): Don't call as_perror for
+ filename rejected by application.
+
+ * as.c (main) [BFD_ASSEMBLER]: If errors occur, close and unlink
+ the output file.
+
+ * doc/as.texinfo: Don't use @value in node names for the moment;
+ references don't appear to work right.
+
+ * as.h (const, volatile): Put these definitions back, and use
+ them.
+
+ * doc/as.texinfo: First pass at using new texinfo features --
+ variables, conditional tests. Far from complete.
+
+Mon Mar 29 16:05:40 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c: Temporary hack to handle some 64-bit constants. This
+ should be redone later.
+ (target_big_endian): Declare.
+ (big_cons): If it's set, reverse order of bytes being copied.
+ * config/tc-sparc.c (md_begin): Set target_big_endian.
+
+ * read.c (s_ignore): Delete declaration of is_end_of_line.
+
+ * config/obj-coffbfd.c (yank_symbols): Build list of file symbol
+ forward pointers properly.
+
+Mon Mar 29 13:47:33 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/obj-coffbfd.c (do_relocs_for): Fix bug where nrelocs
+ wasn't being stored into scnhdr.
+ * config/obj-coffbfd.h: Add prototype of s_get_segment.
+ * read.c (TC_START_LABEL): Default definition.
+ (read_a_source_file): Use TC_START_LABEL macro to work out
+ if a label has been seen.
+
+Mon Mar 29 12:56:56 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: Set BFDDEF and BFDLIB at the top of Makefile, not
+ the bottom (make expands variables in dependencies when the
+ dependencies are read, not when they are used).
+
+ * config/obj-coffbfd.c (fill_section): Don't set NOLOAD bit for
+ a29k .bss section; the mondfe program doesn't like it.
+
+Sun Mar 28 08:12:53 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/tc-m68k.c: Use PARAMS macro, and use CONST instead of
+ const.
+ (current_architecture): Don't need initializer.
+
+Fri Mar 26 08:12:48 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * doc/none.m4: Define Z8000.
+ * doc/Makefile.in (as-*.texinfo): Refer to $(srcdir). Remove the
+ texinfo file before recreating it.
+ (TEXI2DVI): Need to set TEXINPUTS if "make as.dvi" is to work in
+ this directory.
+ (srcdir): Delete second, bogus definition.
+ (as.info): Look for as-*.texinfo in current directory rather than
+ in $(srcdir).
+ (as.dvi): Ditto.
+ (dvi): New rule.
+ * doc/configure.in: Create links to all as-*.texinfo files in the
+ source directory, if that's not the current directory.
+
+ * configure.in (per-host): Accept MIPS host with BSD version
+ number.
+ (per-target): Classify i486 as i386. Use generic cpu_type instead
+ of target_cpu in selecting format etc.
+
+ * app.c (do_scrub_next_char): Use .appfile, not .app-file.
+ * read.c (potable): Change .app-file to .appfile.
+
+ * config/ho-decstatn.h: Renamed from ho-decstation.h.
+ * configure.in: Adjusted.
+
+ * config/obj-bfd-sunos.*: Unused; deleted.
+
+ * Makefile.in (version.c, vers-stamp): Deleted.
+ (config.h): Define GAS_VERSION.
+ * as.c (version_string): Deleted declaration.
+ (main): Look for GAS_VERSION instead.
+
+ * doc/as.texinfo: Updated description of -a* (listing) options,
+ and describe how to pass them through from gcc.
+
+ * config/obj-coffbfd.c (do_relocs_for): Don't allocate storage or
+ process relocs if there aren't any relocs to process. Avoids
+ malloc/free bug on SCO too.
+
+ * as.h: Move local include files below system include files, to
+ avoid some redefinition complaints on some systems.
+ (const, volatile): Don't need these conditionally defined if we
+ use CONST and VOLATILE from ansidecl.h.
+ (seg_name): Use CONST, not const.
+
+Fri Mar 26 10:22:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c: Reindented to GNU standards.
+
+Thu Mar 25 08:59:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (do_relocs_for): Remove a29k special case.
+ (fixup_segment): Add a29k special case; the linker is not prepared
+ to see a segment offset here.
+
+ * app.c (do_scrub_next_char): Added new state, 10, modifying state
+ 9 to only keep a space in between identifier characters.
+
+Wed Mar 24 02:16:22 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: add dvi target; as-$(config).texinfo might live in
+ srcdir, might be in objdir.
+
+ * doc/Makefile.in: dvi depends on as.dvi
+
+Mon Mar 22 23:59:13 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add installcheck target
+
+Mon Mar 22 16:25:57 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Add support for membar mask names.
+ Add missing colons in prefetch error messages. Add support for
+ ASI names.
+
+Mon Mar 22 10:19:00 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/tc-mips.c (macro): Use $AT for any floating point load.
+
+Sat Mar 20 12:50:51 1993 Ken Raeburn (raeburn@urth.cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): For operand type 'M', reject
+ bignums, but don't emit error message.
+
+Fri Mar 19 21:02:19 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (targ-cpu.o): Depend on config.h.
+
+Wed Mar 17 16:44:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c (do_scrub_next_char): Added new state, 9, to avoid
+ dropping a space immediately following an identifier.
+ * expr.c, write.c: Rewrote assert expressions to not use multiple
+ lines; I don't think that can be done portably.
+ * config/tc-mips.c (macro): Use $AT if target register is zero in
+ load instruction, which it can be for a floating point load.
+
+Mon Mar 15 12:17:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c (write_contents): Compute the relocs before writing out
+ the section contents.
+ * config/obj-ecoff.h, config/obj-ecoff.c: Numerous changes to get
+ symbol table and values right.
+ * config/tc-mips.h (LOCAL_LABEL): If OBJ_ECOFF, any label starting
+ with $L is local.
+ * config/tc-mips.c (tc_gen_reloc): If OBJ_ECOFF, adjust the addend
+ by the section vma.
+
+ * config/z8k.mt (TARG_CPU_DEPENDENTS): The relevant file is
+ z8k-opc.h, not z8k.h.
+
+ * config/obj-coffbfd.c (obj_coff_endef): Correct test for .bf
+ symbol.
+
+Fri Mar 12 18:33:36 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognize sparc-sun-solaris2* instead of -solaris2
+
+Fri Mar 12 12:00:07 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * expr.c, write.c: Ultrix native 4.2 cc requires assert condition
+ to be on a single line.
+
+Thu Mar 11 17:56:22 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (config.h): Create file, writing out definitions of
+ target cpu, alias, and canonical name.
+ (ALL_CFLAGS): No longer define TARGET_CPU.
+
+ * Makefile.in (check): Print a message, instead of quitting
+ silently.
+
+ * as.c (main): Don't catch any signals, for now.
+
+ * version.c: Deleted.
+ * Makefile.in: Generate it, putting in only the version number
+ itself.
+ (VERSION): New variable.
+ * as.c: Include config.h.
+ (main): Reformatted version string. Include target alias. Don't
+ print if not requested (i.e., unknown -v argument).
+
+ * as.c (stralloc): Deleted.
+ (main): Call strdup instead.
+
+ * configure.in: Handle all 68300 series chips.
+ * config/tc-m68k.c: Include config.h.
+ (md_assemble): Assume TARGET_CPU is defined. Accept some 68300
+ series cpus as defaults.
+ (md_parse_option): Accept some m68300 series CPUs as defaults.
+
+Wed Mar 10 17:41:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * as.c (EXIT_SUCCESS, EXIT_FAILURE): Define to normal values if
+ not already defined.
+ (main, got_sig): Use them.
+ * config/ho-vms.h (EXIT_SUCCESS, EXIT_FAILURE): Reverse default
+ values.
+
+Tue Mar 9 07:40:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-ecoff.c, config/obj-ecoff.h: Preliminary ECOFF
+ support.
+
+ * config/tc-mips.h (TARGET_FORMAT): Define based on OBJ_AOUT vs.
+ OBJ_ECOFF as well as TARGET_BYTES_*_ENDIAN.
+ (struct loc, struct proc, struct file): Moved to tc-mips.c within
+ #ifndef OBJ_ECOFF block, since ECOFF uses different versions.
+ * config/tc-mips.c: Rearranged for ECOFF support. Added
+ prototypes for all static functions. Moved existing minimal
+ debugging format support info #ifndef OBJ_ECOFF blocks.
+ (macro_build_lui): Eliminated sign_extend argument, because ECOFF
+ does not support a non sign extended high 16 bits reloc. Adjusted
+ all callers accordingly.
+ (tc_get_register): Renamed from get_register, and made non-static.
+
+ * config/mips-big.mt, config/mips-lit.mt: New files. Define
+ TARGET_BYTES_BIG_ENDIAN and TARGET_BYTES_LITTLE_ENDIAN,
+ respectively.
+ * configure.in (mips-*-bsd*): Use gas_target mips-lit.
+ (mips-*-ultrix*, mips-*-irix*, mips-*-ecoff): New targets, using
+ obj_format ecoff and gas_target mips-lit or mips-big.
+
+Tue Mar 9 07:43:01 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * version.c: Bump to version 2.0.1.
+
+Tue Mar 9 07:40:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c (chain_frchains_together): Check that seg_info (section)
+ is not NULL.
+ (write_object_file): Call obj_frob_file after setting the symbols,
+ not before.
+
+Tue Mar 9 00:00:00 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * Version 2.0 released.
+
+Mon Mar 8 14:57:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-i386.h (TC_COUNT_RELOC): Look for fx_addsy only.
+
+Fri Mar 5 09:05:55 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.h: Define stringer here.
+ read.c, config/obj-ieee.c, config/obj-tcm88k.c: Not any of these
+ places.
+
+Thu Mar 4 11:52:23 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * read.c (s_space): Multiply repeat count by mult, not fill.
+
+Thu Mar 4 05:20:42 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * read.c: Include ctype.h.
+
+Wed Mar 3 10:41:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ Patches from Eric Youngdale:
+ * make-gas.com: Find obstack.obj if it's not in the current
+ directory.
+ * read.c (s_ignore): Don't declare is_end_of_line. It's
+ redundant, and triggers a VMS gcc compiler bug.
+
+ * write.c (write_object_file): Macro SUB_SEGMENT_ALIGN now takes
+ current segment as an argument. (Ignored in all cases but VMS.)
+ All callers and definitions changed.
+
+Tue Mar 2 11:56:19 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * listing.c: Cleaned up a bit, added prototypes, made NO_LISTING
+ case compile again.
+
+Tue Mar 2 08:53:34 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.c (isbyte): Accept all values from -255 to +255,
+ so "~0x80" won't be rejected.
+
+ * config/obj-elf.c: No longer include elf/reloc.h.
+ (obj_elf_section): Set SEC_READONLY and SEC_CODE for text section.
+ (obj_elf_stab, obj_elf_desc): Deleted do-nothing and commented-out
+ routines.
+ (obj_elf_xstab): New routine.
+ (obj_elf_set_size): Call as_warn, not fprintf. Pass desired
+ argument to s_ignore. Put "#if 0" around unused code.
+ (obj_pseudo_table): Use s_ignore instead of do-nothing routines.
+ Call elf_xstabs for .stabs and .xstabs operators.
+
+ * config/tc-sparc.h (TARGET_FORMAT) [OBJ_ELF]: Now "elf32-sparc".
+
+ * write.c (relax_and_size_seg): Set SEC_RELOC only if fixups are
+ present.
+
+ * configure.in: mips-bsd configuration was missing format spec.
+ Should use aout.
+
+ * Makefile.in (Makefile): Depends on configure.in.
+
+ * config/tc-mips.c (append_insn): Don't check for alignment of
+ frag in memory; alignment of instructions in section is a separate
+ matter.
+
+ * config/tc-mips.c (macro_build_lui): Fix some assumptions of ANSI
+ C availability.
+
+ * listing.h: Always provide function declarations, not macros, so
+ pcc won't lose.
+
+Tue Mar 2 00:50:43 1993 John Gilmore (gnu@cygnus.com)
+
+ * CONTRIBUTORS: Update Gilmore entry.
+
+Mon Mar 1 12:03:16 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): Correctly assemble prefetch
+ instructions. Accept integer prefetch function numbers.
+
+Wed Feb 24 14:58:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (s_xword): Now call big_cons, so large
+ constants are accepted, but symbolic values are not. GCC will not
+ generate the latter currently.
+
+ * frags.c (frag_init): New function.
+ (zero_address_frag, bss_address_frag): Now initialized at run
+ time.
+ * as.c (main): Call frag_init.
+
+Wed Feb 24 10:32:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c (do_scrub_next_char): In LEX_IS_LINE_COMMENT_START case:
+ Don't unget ch2 if we didn't get it.
+
+Wed Feb 24 04:14:07 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * doc/Makefile.in (TEXIDIR): Updated for new layout.
+
+ * config/tc-sparc.c (s_common): Add support for ELF version.
+ (tc_gen_reloc) [BFD_ASSEMBLER]: New function.
+ * config/tc-sparc.h (TARGET_ARCH, TARGET_FORMAT) [BFD_ASSEMBLER]:
+ New macros.
+ (md_convert_frag): New macro.
+
+ * config/tc-m68k.c (m68k_ip): For PC-relative addressing of a
+ symbol, fix the offset so "+2" isn't required.
+
+ * config/tc-i960.c (line_comment_chars, line_separator_chars):
+ Define as common/bss.
+ (op_hash, reg_hash, areg_hash, iclasses_seen, br_cnt): Default C
+ initializers are sufficient.
+
+ * config/obj-aout.h [BFD_ASSEMBLER]: Include libaout.h from bfd.
+ (TARGET_FORMAT) [BFD_ASSEMBLER]: Default to "a.out".
+ (S_SET_*, S_GET_*, obj_frob_symbol) [BFD_ASSEMBLER]: New macros.
+ (S_SET_TYPE) [!BFD_ASSEMBLER]: New macro.
+ * config/obj-aout.c: Use PARAMS macro for declarations. Remove
+ "IGNORE_DEBUG" conditional, since both branches are identical.
+ Use S_SET_TYPE, S_GET_TYPE, and S_GET_DESC instead of directly
+ referencing symbol structure members.
+ (obj_aout_frob_symbol) [BFD_ASSEMBLER]: New function.
+
+ * as.h (struct frag): Reordered a couple of fields for better
+ packing.
+
+ * write.c (record_alignment) [BFD_ASSEMBLER]: Record it in the
+ section info.
+ (write_contents) [BFD_ASSEMBLER]: New function.
+ (write_object_file) [BFD_ASSEMBLER]: Always handle -R here. Call
+ fix_new with BFD_RELOC_NONE instead of 0 or NO_RELOC. Call
+ obj_frob_file, obj_frob_symbol, tc_frob_symbol if defined.
+ (fixup_segment): Make sure common-section symbols get treated the
+ same as undefined symbols.
+ (fix_new) [BFD_ASSEMBLER]: Argument r_type is of type
+ bfd_reloc_code_real_type. Use seg_fix_{root,tail}P derived from
+ section info.
+ * write.h (fix_new): Update prototype.
+
+ * tc.h (md_operand, md_convert_frag, tc_headers_hook,
+ md_section_align, md_undefined_symbol): Don't provide prototypes
+ if these are defined as macros.
+ (md_convert_frag) [BFD_ASSEMBLER]: BFD version needs bfd and
+ section passed.
+
+ * symbols.c (symbol_new): Argument NAME is now pointer to const.
+ Simplified STRIP_UNDERSCORE code. Remove assumptions about null
+ pointers in freshly allocated storage. [BFD_ASSEMBLER]: Get new
+ BFD symbol.
+ (colon): Display other/desc fields of redefined symbol only if
+ S_GET_OTHER and S_GET_DESC are defined.
+ (symbol_make): Argument NAME is now pointer to const.
+ (symbol_find, symbol_find_base): Likewise.
+ (S_IS_*, S_GET_*, S_SET_*) [BFD_ASSEMBLER]: New functions.
+ * symbols.h: Fix prototypes for new const arguments. Add
+ prototypes for BFD_ASSEMBLER S_* functions.
+
+ * subsegs.c (subseg_change) [BFD_ASSEMBLER]: BFD version of code
+ for changing to an existing section.
+ (subseg_new_rest) [BFD_ASSEMBLER]: Split off from subseg_new,
+ called by subseg_new and subseg_set.
+ (subseg_new) [BFD_ASSEMBLER]: Rewritten to change to new section,
+ given section name and subseg number.
+ (subseg_set) [BFD_ASSEMBLER]: New function; change to a possibly
+ new section/subsection.
+
+ * read.c: Don't include ctype.h.
+ (cons) [BFD_ASSEMBLER]: For undefined symbols, use BFD_RELOC_32
+ for now; should be machine-dependent.
+
+ * configure.in: Accept *-*-elf and *-*-solaris* as ELF format
+ targets, forcing BFD use.
+
+Wed Feb 17 18:59:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c: Use PARAMS macro for static function
+ declarations. Use BFD_RELOC_ macros everywhere, with
+ compatibility macros declared for non-BFD mode.
+ (struct sparc_it) [BFD_ASSEMBLER]: Use bfd_reloc_code_real_type
+ instead of enum reloc_type.
+ (emit_sparc_reloc): Commented-out function deleted.
+ (md_convert_frag): Deleted.
+ (tc_aout_pre_write_hook): Don't define for BFD_ASSEMBLER.
+ (md_apply_fix): Changed calling sequence (conditionally) for BFD
+ version.
+ * config/tc-sparc.h (md_convert_frag): New macro.
+
+ * config/obj-aout.c (obj_aout_stab): Refer to undefined_section,
+ not SEG_UNKNOWN. Use S_SET_TYPE, S_GET_TYPE, S_GET_DESC instead
+ of referencing fields directly.
+
+ * write.c (cvt_frag_to_fill): New function; extracted from
+ write_object_file.
+ (write_object_file) [! BFD_ASSEMBLER]: Call it.
+ (relax_and_size_seg) [BFD_ASSEMBLER]: New function; relax section
+ and set its size and flags.
+
+ * struc-symbol.h (struct symbol) [BFD_ASSEMBLER]: Replace some
+ fields with BFD equivalents. Turn on back-pointers, and add
+ target-specific fields at end.
+
+Thu Feb 11 09:20:37 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/obj-coffbfd.c (fill_section): Don't set vaddr here.
+ (write_object_file): Set it here instead, so that fixup_segment
+ can see the correct value.
+
+Mon Feb 8 13:56:17 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * write.c (write_object_file): Check for errors and warnings and
+ bail out before processing contents.
+ (chain_frchains_together_1): New function, does most of the work
+ of remove_subsegs.
+ (chain_frchains_together) [BFD_ASSEMBLER]: New function.
+ (remove_subsegs) [! BFD]: Call it.
+ (write_object_file) [BFD_ASSEMBLER]: Converted to use BFD
+ structures and routines.
+
+ * config/obj-elf.*: New files.
+
+ * config/mips.mt, config/rs6000.mt: Deleted.
+
+ * config/h8300.mt: Don't specify compiler here.
+
+ * config/z8k.mt: The z8k code depends on the z8k opcode table,
+ not the h8300 one.
+ * config/tc-z8k.h: Comment fix.
+
+ * write.c: Reordered some functions for better inlining.
+ (fixup_segment): Linkrelax code is no longer conditional on
+ TC_I960.
+
+Thu Feb 4 12:45:16 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/{h8500.mt, tc-h8500.c, tc-h8500.h, obj-coffbfd.c,
+ obj-coffbfd.h}: support for the H8/500
+
+Wed Feb 3 19:28:18 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-vms.h (SUB_SEGMENT_ALIGN): Define VMS version here.
+ * write.c (write_object_file): Not here.
+ (fix_new): Initialize fx_addnumber.
+
+ * listing.c: Don't include target-cpu.h explicitly, since as.h
+ includes it.
+
+Thu Jan 28 00:35:40 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * write.h [BFD_ASSEMBLER]: Don't declare next_object_file_charP,
+ *_fix_root, *_fix_tail, seg_fix_rootP, seg_fix_tailP.
+ (struct fix): Reordered fields for compactness and efficiency.
+ Converted some logical fields to 1-bit fields.
+
+ * config/obj-aout.h: Use PARAMS.
+ [BFD_ASSEMBLER]: Don't define/declare AOUT_MACHTYPE, seg_N_TYPE,
+ N_TYPE_seg, DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE.
+
+ * read.c: Don't include listing.h; as.h includes it. Removed
+ DONTDEF code.
+ [BFD_ASSEMBLER]: Include subsegs.h.
+ (old_buffer, new_broken_words): Default initialization is
+ sufficient.
+
+ * output-file.c [BFD_ASSEMBLER]: Include bfd.h, default TARGET_MACH
+ to 0, define stdoutput.
+ (output_file_create) [BFD_ASSEMBLER]: Call bfd_perror on failure.
+ Call bfd_set_arch_mach.
+ (output_file_close) [BFD_ASSEMBLER]: Call bfd_close, not
+ bfd_close_all_done. Call bfd_perror on failure.
+ (output_file_append) [BFD_ASSEMBLER]: Don't define.
+
+ * config/m68kcoff.mt (LOCAL_LOADLIBES): Delete definition.
+
+ * subsegs.h (segment_info_type): Always define. Omit field scnhdr
+ if not MANY_SEGMENTS. Define new field bfd_section if
+ BFD_ASSEMBLER.
+ (seg_info): New macro.
+
+ * expr.c, input-scrub.c: Use PARAMS macro. Deleted unused
+ variables, and some irrelevant comments.
+
+ * Makefile.in (ALL_CFLAGS): Include $(BFDDEF).
+ (LIBS): Include $(BFDLIB). Don't bother with $(CLIB).
+ * configure.in: Permit --with-bfd-assembler now, with a warning.
+ Variable need_bfd is now a boolean, as is new variable bfd_gas.
+ Set BFDDEF and BFDLIB in Makefile when appropriate.
+
+ * as.c: Removed "#ifdef DONTDEF" and "#ifdef comment" code.
+ (main): Refer to flag_always_generate_output instead of
+ flagseen['Z'].
+
+ * as.c (main) [BFD_ASSEMBLER]: Open output bfd.
+ (*_section) [BFD_ASSEMBLER]: Define them.
+ (perform_an_assembly_pass) [BFD_ASSEMBLER]: Initialize them, and
+ set section flags when appropriate.
+ * as.h (SEG_NORMAL) [BFD_ASSEMBLER]: Require that the specified
+ section is not absolute, undefined, or an assembler internal one.
+ (absolute_section, undefined_section): Always define.
+ * expr.c, read.c, symbols.c: Refer to *_section, not SEG_*; break
+ switch statements into if-else trees.
+ * symbols.c [MANY_SEGMENTS]: Deleted redundant definitions of
+ SEG_BSS and SEG_DATA.
+
+ * as.h (frag_now_fix): New macro.
+ * symbols.c (colon): Use it.
+
+Wed Jan 27 21:43:53 PST 1993 Ralph Campbell (ralphc@pyramid.com)
+
+ * config/tc-mips.c: Added mips support for mips-dec-bsd.
+ * config/tc-mips.h: Added mips support for mips-dec-bsd.
+ * config/ho-mipsbsd.h: Added mips support for mips-dec-bsd.
+ * config/mips-opcode.h: Added mips support for mips-dec-bsd.
+ * configure.in: Added mips support for mips-dec-bsd.
+ * atof-generic.c: Define TRUE and FALSE if not defined.
+
+Thu Jan 21 12:48:19 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * version.c: Bumped version number to 1.93.05.
+
+Wed Jan 20 17:11:53 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/obj-coff.c (obj_emit_relocations): Don't use #elif.
+ (obj_emit_lineno): Don't need return at end of void function.
+ (obj_symbol_new_hook): Ditto.
+
+ * config/tc-m68k.c: Removed some unused code.
+ (tc_aout_fix_to_chars): Array nbytes_r_length is now const.
+
+ * config/tc-m68k.h (TC_COUNT_RELOC): Don't emit reloc if only
+ offset field is set.
+
+Fri Jan 8 05:44:49 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-sparc.c (sparc_ip): For %uhi and %ulo, if not
+ ENV64, emit no reloc.
+ (md_pseudo_table): For ".xword", call s_xword.
+ (s_xword): New function.
+
+ * config/tc-sparc.c (architecture_requested, warn_on_bump,
+ md_relax_table): Use default zero initialization.
+ (s_reserve): Since SEG_E2 is equivalent to SEG_BSS, just use the
+ latter, instead of selecting with preprocessor conditionals.
+
+Thu Jan 7 08:58:21 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognise all sparclite variants
+
+Thu Jan 7 05:25:25 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c (s_data) [!BFD_ASSEMBLER]: Fix typo in 4 Jan change --
+ accidentally changed to use subseg_change where it should have
+ been subseg_new.
+
+Tue Jan 5 08:42:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * expr.c (operand): If character other than comma or newline is a
+ logical end-of-line character, use the newline case.
+ From Eric Youngdale:
+ (operand): Set X_add_number field for floating-point numbers.
+ (operand): Treat zero byte as end-of-operand.
+
+ * configure.in (per-target): Look for with_bfd_assembler option.
+ For now, only accept "no", until the merge is done.
+
+ Merged changes from Eric Youngdale (youngdale@v6550c.nrl.navy.mil):
+ * as.c, flonum-konst.c, hex-value.c, input-file.c, version.c,
+ config/obj-aout.h, config/obj-vms.c: VMS -> HO_VMS.
+ * read.c: Finish conversion to S_* macros in the VMS only
+ parts of the program. Add "const" modifier to hex_value.
+ * as.c, read.c, symbols.c, write.c: Change "ifdef VMS" to
+ "ifdef OBJ_VMS".
+ * expr.c: Add "const" modifier to hex_value.
+ * symbols.c: Finish conversion to S_* macros in the VMS only
+ parts of the program. Add "const" modifier to
+ md_[long,short]_jump_size. Remove declaration of const_flag
+ (which will be declared in obj-vms.h).
+ * write.c: Add "const" modifier to md_[long,short]_jump_size.
+ Fix arguments to VMS_write_object_file.
+ * config-gas.com: New file. Script for VMS systems to set up the
+ configuration to build gas for VMS, and create config.status.
+ * make-gas.com: Redone to work with new scheme.
+ * obj-vms.c: Patch to fix bug where we were not correctly parsing the
+ stabs directives.
+ * obj-vms.c: Define macros COPY_LONG and COPY_SHORT which
+ will swap bytes if needed on a big endian system. Use throughout
+ as needed.
+ * obj-vms.c (obj_aout_stab): Add code to generate listing file.
+ * obj-vms.c (VMS_typedef_parse): Add alias to correctly handle certain
+ types of malformed stabs. Change parsing algorithm so that we are
+ more certain of having all of the information that we need on hand.
+ * obj-vms.c (final_forward_reference): New function, used to help
+ resolve the data types of as many struct elements as possible
+ when some part of the struct is not fully defined by the compiler.
+ * obj-vms.c (VMS_LSYM_Parse): Correctly handle case of continuation
+ stabs directives.
+ * obj-vms.c (VMS_write_object_file): Define all vtable psects
+ as symbols as well in the object file. Look for external functions
+ that start with "__vt.", and turn them into variables, since the
+ g++ compiler is incapable of doing this.
+ * tc-vax.c: Add '1' option for backward compatibility with older GCC
+ versions.
+ * bignum-copy.c (bignum_copy): Fix bug where we pad with zeroes.
+ * input-scrub.c (as_where): Fix bug where as would crash if we did not
+ have the name of the source file yet.
+ * config/ho-vms.h: define HO_VMS, not HO_VAX.
+
+Mon Jan 4 05:17:26 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * read.c (s_data): Always use "data_section", since it'll map to
+ SEG_DATA or SEG_E1 if needed.
+ (s_lcomm): Likewise with bss_section.
+ (s_fill): Use memset, not bzero.
+
+Thu Dec 31 04:29:27 1992 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * read.c: Deleted some code under "#ifdef DONTDEF" that was for
+ handling GDB symbol table data.
+
+ * config/obj-aout.h (segment_name): Delete definition.
+ (seg_name): Delete declaration.
+ * config/obj-bout.h (segment_name, seg_name): Ditto.
+ * config/obj-vms.h (segment_name, seg_name): Ditto.
+ * config/obj-coff.h (segment_name): Ditto.
+ * config/obj-coffbfd.h (segment_name): Ditto.
+
+ * Changes for BFD_ASSEMBLER:
+ * obj.h (obj_crawl_symbol_chain): Declare only if not
+ BFD_ASSEMBLER.
+ (obj_header_append, obj_pre_write_hook): Ditto.
+ * as.h (stdoutput): New var, defined only if BFD_ASSEMBLER.
+ (segT) [BFD_ASSEMBLER]: New typedef for "asection *".
+ (segment_name) If BFD_ASSEMBLER, look up BFD section name;
+ otherwise, use seg_name array.
+ (seg_name): Declare only if not BFD_ASSEMBLER.
+ (section_alignment): Declare only if not BFD_ASSEMBLER.
+ (big_section, reg_section, pass1_section, diff_section,
+ absent_section, text_section, data_section, bss_section): If
+ BFD_ASSEMBLER, declare as variables; otherwise, declare as macros,
+ mapping to segT enum values.
+ (tc_aout_fix_to_chars, next_object_file_charP): Force parse errors
+ if these are used or defined, if BFD_ASSEMBLER.
+ (subseg_set, subseg_new) [BFD_ASSEMBLER]: Functionality of old
+ subseg_new split into two functions.
+ (SEG_NORMAL): For BFD_ASSEMBLER, always return true, for now.
+
+ * as.h (volatile): Don't define if already defined.
+ (had_errors, had_warnings): Provide prototypes for ANSI C even if
+ NO_STDARG.
+ (as_bad, as_fatal, as_tsktsk, as_warn): For GNU C version 2,
+ declare with format attribute for -Wformat checking.
+
+Wed Dec 30 10:18:57 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * app.c, config/tc-*.c: Don't include read.h, since it is already
+ included by as.h.
+
+ * These are based on patches from Minh Tran-le
+ <mtranle@paris.intellicorp.com>.
+ * configure.in (i[34]86-ibm-aix*): Accept i486 for host. Use
+ obj_format coffbfd and gas_target i386coff for target.
+ (i[34]86-*-isc*): New host (uses sysv).
+ * config/i386aix.mt: Removed (no longer used).
+ * config/mh-i386aix (RANLIB): Use true rather than /bin/true.
+ (MINUS_G): Removed.
+ (LDFLAGS): Added, defined as -shlib.
+ * config/te-i386aix.h (REVERSE_SORT_RELOCS): Undefine.
+ * config/te-sco386.h (LOCAL_LABEL): Don't define.
+ (DOT_LABEL_PREFIX): Define.
+ * expr.c (operand): If DOT_LABEL_PREFIX, use .L0\001 as a label
+ name rather than L0\001.
+ * read.c (s_lcomm): Make a frag in SEG_BSS rather than using
+ local_bss_counter.
+ * symbols.c, symbols.h (local_bss_counter): Removed.
+ * write.c (write_object_file): bss no longer uses
+ local_bss_counter. Pass correct data and bss size to
+ VMS_write_object_file.
+ * config/obj-vms.c (VMS_write_object_file): Accept bss size as
+ argument, rather than using local_bss_counter.
+ * config/tc-m88k.c (s_bss): Don't use local_bss_counter.
+ * config/tc-sparc.c (s_reserve): Don't use local_bss_counter.
+ * config/obj-coffbfd.c (had_lineno, had_reloc): Removed.
+ (size_section): Restored sanity check.
+ (do_relocs_for): Base section address on s_paddr rather than
+ computing it. Adjust a29k R_IHIHALF special case to account for
+ section paddr (used to require paddr to be zero). If there are no
+ reclos, set s_relptr to 0. Set relocation size in object_headers.
+ (fill_section): Always set s_vaddr here, removing
+ ZERO_BASED_SEGMENTS case. Force s_scnptr for bss to 0. Don't set
+ NOLOAD for i386 .bss, because it confuses the SVR3 native linker.
+ Set STYP_INFO for .comment.
+ (coff_header_append): Use object headers and H_{SET,GET}_* macros.
+ Make aouthdr writing depend on OBJ_COFF_OMIT_OPTIONAL_HEADER.
+ (crawl_symbols): Handle 8 character section name correctly. Use
+ H_{SET,GET}_* macros.
+ (do_linenos_for): Set lineno size in object_headers.
+ (write_object_file): Use H_{SET,GET}_* macros. Don't bother to
+ set s_vaddr here. If string_byte_count remains 4, set it back to
+ 0, and only write strings out if there are some. Call
+ fill_section before do_relocs_for and do_linenos_for.
+ (obj_coff_section): Handle optional quoted second argument giving
+ section characteristics.
+ (obj_coff_bss): Added to handle .bss.
+ (obj_coff_ident): Added to handle .ident (puts string in .comment
+ section).
+ (obj_coff_lcomm): Put common symbols in .bss, not .data.
+ (fixup_mdeps): Change to segment. Call frag_wane after
+ md_convert_frag.
+ (fixup_segment): Explicitly check S_IS_COMMON before making 386
+ adjustment (already happened only for common symbols, but this is
+ clearer).
+ * config/obj-coffbfd.h (OBJ_COFF_OMIT_OPTIONAL_HEADER): Define.
+ * config/tc-i386.c (s_bss): Don't use if I386COFF.
+ (md_pseudo_table): Ignore .optim and .noopt.
+ (tc_coff_sizemachdep): New function.
+ * config/tc-i386.h (REVERSE_SORT_RELOCS): Undef, for SVR3
+ compatibility.
+ (LOCAL_LABEL): Removed definition.
+ (DOT_LABEL_PREFIX): Defined.
+
+Mon Dec 28 10:32:05 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * app.c (app_push): Use memcpy, not bcopy.
+ (do_scrub_next_char): For \", return " not '.
+ (symbol_chars): Now const.
+
+ * expr.c (operand): If not LOCAL_LABELS_FB, don't look for "0f"
+ and "0b". If LOCAL_LABELS_DOLLAR, check for "0$".
+
+ * config/obj-coff.h: Don't use #elif.
+
+ * config/ho-sunos.h: Don't include sys/stdtypes.h; 4.0.3 doesn't
+ have it. (Reported by Noah Friedman, friedman@gnu.ai.mit.edu.)
+
+Wed Dec 16 12:12:33 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * write.c, obj-ieee.c: don't define SUB_SEGMENT_ALIGN if it is
+ already defined.
+
+Tue Dec 15 12:40:11 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * app.c (do_scrub_begin): allow single quote strings if so
+ configured.
+
+ * config/*z8k*: checkpoint
+
+Sun Dec 13 00:04:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * read.c (read_a_source_file): avoid calling xmalloc (0).
+
+Sat Dec 12 15:26:34 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * listing.c: Call xmalloc, not malloc; don't declare malloc.
+
+ * Changes to support SCO 3.2v4:
+ * read.c (s_align_bytes, s_align_ptwo): If not SEG_DATA or
+ SEG_BSS, fill with NOP_OPCODE.
+ * config/i386coff.mt: Add opcode/i386.h to TARG_CPU_DEPENDENTS.
+ * config/obj-coffbfd.c (do_relocs_for): Increment addr even if not
+ using ZERO_BASED_SEGMENTS.
+ (fill_section): If ZERO_BASED_SEGMENTS, set segment addresses, but
+ never set segment address for SEG_E2 (.bss) and don't write out
+ SEG_E2 contents. Set .init and .fini sections to STYP_TEXT.
+ (obj_coff_endef): Don't merge labels or symbols awaiting forward
+ definitions, and don't merge tags with non-tags. Check for .bf
+ rather than just checking whether the second character is b and
+ the third character is f.
+ (obj_coff_val): gcc can generate values which we don't handle
+ correctly; discard information for now, since it only affects the
+ debugging information.
+ (tag_find_or_name): Don't insert tags in the symbol table.
+ (yank_symbols): Don't merge labels.
+ (write_object_file): Don't define SUB_SEGMENT_ALIGN if it is
+ already defined. Fill subsegments with NOP_OPCODE, not 0. Don't
+ set segment address if ZERO_BASED_SEGMENTS.
+ (obj_coff_section): Accept and ignore a trailing quoted string, as
+ used in AT&T i386 syntax.
+ (fixup_segment): Take segment as argument. On the i386, adjust PC
+ relative addends by the segment vaddr.
+ * tc-i386.h: Define SUB_SEGMENT_ALIGN.
+ * tc-a29k.h: Define ZERO_BASED_SEGMENTS.
+ * tc-i386.c: (i386_operand): If I386COFF, accept any segment type.
+
+Tue Dec 8 00:06:48 1992 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config/obj-coffbfd.c: Include libcoff.h.
+
+ * version.c: Now version 1.93.
+
+Mon Dec 7 00:39:09 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-i386.c (md_pseudo_table): For 386bsd and linux, do
+ power-of-two alignment for .align.
+
+ * as.h: If BROKEN_ASSERT, just redefine `assert' to be trivial,
+ and leave everything else alone.
+
+Fri Dec 4 16:58:42 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (as.new): Don't bother saving as.old.
+
+ * write.c: Conditionalize on OBJ_VMS, not VMS.
+ (magic_number_for_object_file): Don't define if OBJ_VMS.
+
+ * config/obj-vms.c: Changes for traditional C.
+
+Thu Dec 3 01:24:07 1992 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * config/ho-generic.h (malloc, realloc): Declare.
+
+ * Lots of comment/whitespace changes.
+
+ * write.h (struct fix): Some fields reordered, narrowed.
+
+ * read.c (MASK_CHAR): Define using C types, not magic number.
+
+ * as.c, input-file.c: Deleted some unused code.
+
+ * app.c, as.h: Doc fix.
+
+ * flonum-konst.c, flonum-mult.c: Include ansidecl.h.
+
+ * as.h (xmalloc): Argument is long.
+
+ * xmalloc.c (error): Remove declaration; as.h takes care of it.
+
+ * doc/as.texinfo: Regrouped documentation of some command-line
+ options. Updated options documentation for m68k. Some minor
+ wording/punctuation changes.
+
+Mon Nov 30 11:42:11 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: Accept target OS "vms".
+
+ * symbols.c: Merged ANSI and non-ANSI function decls, using
+ PARAMS macro.
+
+ * xmalloc.c: Just include as.h, don't bother trying to figure out
+ other header files.
+
+ * strstr.c, strerror.c: Deleted.
+ * Makefile.in: Deleted references.
+
+ * config/tc-ns32k.c: Don't include header file for string
+ declarations; leave that to ho-*.h.
+
+Fri Nov 27 04:11:36 1992 Ken Raeburn (raeburn at cambridge-laptop.cygnus.com)
+
+ * config/coff_gnu.h [TC_I860]: Guesses for reloc type values,
+ imported from FSF sources.
+
+ * messages.c (strerror): Declare unconditionally.
+
+ * as.h: Delete alloca and register definitions.
+
+ * config/atof-ieee.c (mask): Now const.
+
+ * obstack.c, obstack.h: Deleted.
+
+ * as.h (flag_readonly_data_in_text): New flag.
+ * as.c (main): Set it for -R.
+
+ * as.h (flag_suppress_warnings): New flag.
+ * as.c (main): Set it for -W.
+ * messages.c (as_warn): Check it instead of flagseen['W'].
+
+ * as.h (flag_always_generate_output): New flag.
+ * as.c (main): Set it for -Z.
+
+ * config/tc-sparc.h: Define NEED_FX_R_TYPE.
+ * config/tc-a29k.h: Ditto.
+ * write.h (struct fix): Don't conditionalize fx_r_type field on TC
+ macros.
+
+ * as.h: Merged ANSI and non-ANSI function decls, using PARAMS
+ macro.
+ * bignum.h, expr.h, flonum.h, frags.h, input-file.h, listing.h,
+ obj.h, output-file.h, read.h, struc-symbol.h, symbols.h, tc.h,
+ write.h: Likewise.
+ * read.c: Likewise.
+
+ * xmalloc.c: Conditionalize on HAVE_MALLOC_H, not USG. Fold in
+ xrealloc from xrealloc.c.
+ * xrealloc.c: Deleted.
+ * Makefile.in (REAL_SOURCES, OBJS): Adjusted.
+
+ * configure.in: For host CPU a29k, rs6000, vax, consider using bsd
+ or vms ho- files.
+
+ * config/ho-sysv.h (setbuffer, HO_USG): Deleted.
+
+ * config/atof-ieee.c (atof_ieee): Exponent field isn't a pointer;
+ don't initialize it with NULL.
+
+ * config/ho-vax.h (M_VAX): Deleted; was unused.
+
+ * README-vms, config/ho-vms.h, config/obj-vms.c, config/obj-vms.h:
+ New files imported from FSF version, contributed by Eric Youngdale.
+ * README-vms-dbg, config/vms: Deleted.
+
+ * ChangeLog, config/ChangeLog: Merged.
+
+ * config/*tahoe*, configure.in: Tahoe support brought in from FSF
+ version.
+
+ * input-file.c (input_file_open): Eliminate call to setvbuf.
+ [USG] (setbuffer): Deleted macro.
+
+Mon Nov 23 11:00:16 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * all files: Whitespace changes for GNU indentation style, done by
+ GNU `indent'. Some cleanup still needed, especially of comments.
+
+ * configure.in: No te-386bsd.h file exists; don't try to use it.
+
+ * obj-coff.c (obj_coff_endef): Use as_warn, not fprintf.
+
+ * tc-m68k.c (md_assemble): Don't complain about 68000 with 68881;
+ could be doing emulation.
+
+Thu Nov 19 11:47:19 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ z8000 documentation
+ * doc/Makefile.in, doc/all.m4, doc/as-all.texinfo, doc/as.texinfo:
+ all modified.
+
+Tue Nov 10 09:49:24 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (as.o, obj-format.o): added dependency on subsegs.h.
+
+ * subsegs.h: add extern to segment_info declaration.
+
+ * read.h: added extern declarations for comment_chars,
+ line_comment_chars, and line_separator_chars.
+ read.c, app.c: removed definitions of comment_chars,
+ line_comment_chars, and line_separator_chars.
+
+ * tc-m68k.c (m68k_reg_parse): If REGISTER_PREFIX isn't defined,
+ still accept (but don't require) OPTIONAL_REGISTER_PREFIX before
+ the register name.
+ (insert_reg): put REGISTER_PREFIX before register names before
+ putting them in the symbol table.
+ * tc-m68k.h (OPTIONAL_REGISTER_PREFIX): Define to be "%", if not
+ M68KCOFF.
+
+ * obj-coffbfd.c (fill_section): set STYP_NOLOAD bit for .bss
+ section.
+
+ * atof-ieee.c, atof-ns32k.c, tc-*.c: made EXP_CHARS, FLT_CHARS,
+ comment_chars, line_comment_chars and line_seperator_chars
+ consistently const, and always initialized them. Included read.h.
+
+Thu Nov 5 17:55:41 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * tc-sparc.c (sparc_ip): Add code to flag error if an absolute
+ constant will not fit in an immediate field.
+ (md_apply_fix, RELOC_BASE13 case): Check for relocation overflow.
+
+Wed Nov 4 07:50:46 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * obj-coff.c (callj_table): Delete global variable.
+ (obj_emit_relocations): Define it locally here, and only if
+ TC_I960 is defined.
+
+ * tc-m68k.c (m68k_reg_parse): Underscore is part of a symbol name.
+ (m68k_ip): Don't warn about bignum used as float bit-pattern.
+
+ * obj-coff.c: Replaced ANSI and non-ANSI function declarations
+ with a single set using PARAMS macro.
+
+ * tc-i960.c (tc_bout_fix_to_chars): Bit-field fixups want a length
+ of 2.
+
+ * tc-i960.c: Missed a couple of 0->NO_RELOC conversions.
+
+ * tc-i960.h (N_BALNAME, N_CALLNAME): Define as char-type values,
+ so widening works consistently.
+
+Wed Oct 28 08:52:34 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * version.c: Put conditional "const" before version_string, not
+ before dummy function for VMS. Now version 1.91.03.
+
+ * app.c (do_scrub_next_char): Need double-\ before `000' to show
+ printed rep of null character.
+
+Fri Oct 23 14:40:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * obj-coffbfd.c (write_object_file): check return value of
+ bfd_close_all_done.
+
+Tue Oct 20 12:18:08 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Support for i386-sysv.
+ obj-coffbfd.c (do_relocs_for, write_object_file): set segment
+ addresses to reasonable sizes. New define ZERO_BASED_SEGMENTS can
+ be used to set them all to zero as was done before.
+ (fill_section): segment addresses now set in write_object_file.
+ (fill_section): Don't set STYP_NOLOAD for .bss section.
+ (fixup_segment): 386 uses strange common symbol format.
+ tc-i386.c (tc_coff_fix2rtype): use R_DIR32, not R_RELLONG, for
+ compatibility with SVR3.2 linker.
+ * configure.in: i386-sysv and i386-sco use coffbfd.
+
+ * app.c (do_scrub_next_char): discard whitespace after a label.
+
+Sat Oct 10 12:33:45 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: differentiate between SunOS 4 and Solaris2 for Sun4
+ hosts, use the sysv configuration for solaris2
+
+Mon Oct 5 09:28:57 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ fix i960+non-bfd coff bit rot.
+ * obj-coff.c (c_dot_file_symbol, obj_coff_ln, obj_coff_line):
+ support for C source listings. (obj_coff_endef): look in the right
+ part of the symbol for the symbol name
+
+ * tc-m68k.c (get_num): make it work for all segments, not just the
+ first three.
+
+Mon Oct 5 03:30:36 1992 Mark Eichin (eichin at tweedledumber.cygnus.com)
+
+ * configure.in: recognize i386-*-bsd emulation.
+
+Thu Oct 1 23:05:12 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: use the cpu-vendor-os triple for host and target
+
+Tue Sep 29 12:22:52 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * obj-coffbfd.c (write_object_file): don't fixup for the z8k
+ * tc-z8k.c: lots of bug fixes
+
+Tue Sep 29 10:51:55 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * tc-i960.h, tc-i960.c: avoid the ANSI preprocessor addition
+ #elif, since it is not supported by old compilers.
+ ho-rs6000.h, tc-m68k.c: the native RS/6000 compiler miscompiles a
+ couple of expressions in tc-m68k.c.
+
+Mon Sep 28 21:18:24 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * read.c (cons): If NO_RELOC is defined, use it.
+
+ * tc-i960.c (get_cdisp): Use NO_RELOC, not 0, in call to fix_new.
+
+Fri Sep 25 18:18:52 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * tc-m68k.h: if M68KCOFF, define DOT_LABEL_PREFIX (to require
+ local labels to start with a .) and set REGISTER_PREFIX to %.
+ tc-m68k.c (m68k_reg_parse): accept REGISTER_PREFIX if defined.
+
+Fri Sep 25 17:53:43 1992 John Gilmore (gnu@cygnus.com)
+
+ * messages.c: Comment changes.
+
+Fri Sep 25 14:12:58 1992 Ken Raeburn (raeburn@kyriath.cygnus.com)
+
+ * as.h: Test if __STDC__ is defined only, don't test its value.
+ * messages.c: If __STDC__ is not defined, define NO_STDARG.
+
+Thu Sep 24 12:42:32 1992 Brendan Kehoe (brendan@rtl.cygnus.com)
+
+ * listing.c (debugging_pseudo): Add stabs and stabn as things to
+ ignore.
+
+Tue Sep 22 13:02:07 1992 Sean Eric Fagan (sef@cygnus.com)
+
+ * obj-coffbfd.c (do_relocs_for,fill_section): now allocate all
+ sections starting from zero, rather than making them consecutive.
+ This makes subsequent reloc calculations easier, esp if the object
+ format doesn't understand addends. (obj_coff_lcomm): (maybe temporarily)
+ allocate lcomm in .data rather than in .bss. It seems that some
+ tools can't cope with a non-zero sized bss before linkage.
+
+Tue Sep 22 15:10:51 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * tc-m68k.c: Replace "enum m68k_architecture" with "int"
+ throughout. That enum no longer means what we thought it meant.
+
+ * tc-m68k.c (md_assemble, md_parse_option): Handle new
+ "-mno-688[58]1" options.
+
+ * tc-m68k.c: Added CPU32 support.
+
+Fri Sep 18 08:02:18 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * tc-m68k.c (m68k_ip): An(disp) is not pc relative.
+
+Tue Sep 15 17:25:05 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (as.new): Remove dependence on LOCAL_LOADLIBES.
+ Change LIBDEPS dependence to LIBS.
+
+Tue Sep 15 15:32:02 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): if $(tooldir) exists, install as in
+ $(tooldir)/bin.
+
+Sun Sep 13 20:30:10 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Added WARN_SIGNED_OVERFLOW_WORD define to give an error if any
+ .word is < -32768 or > 32767. The -J flag causes the error to be
+ ignored. This is to catch over-sized switches generated by gcc on
+ systems which don't support the broken .word hack.
+ as.c (main): permit -J if WARN_SIGNED_OVERFLOW_WORD.
+ write.c (fixup_segment): check for signed .word overflow if
+ WARN_SIGNED_OVERFLOW_WORD.
+
+ * write.c (fixup_segment): fixed missing parens in expression
+ checking for byte or word overflow.
+
+ * obj-coffbfd.h: define WARN_SIGNED_OVERFLOW_WORD.
+ obj-coffbfd.c (fixup_segment): check for signed .word overflow if
+ WARN_SIGNED_OVERFLOW_WORD.
+
+ * obj-coffbfd.c (fixup_segment): fixed missing parens in
+ expression checking for byte or word overflow.
+
+Fri Sep 11 10:21:04 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Support for i386 coff
+ * obj-coffbfd.h : added stuff
+ * tc-i386.c (tc_coff_fix2rtype): new function
+ * tc-i386.h : new coff defines
+
+Thu Sep 10 09:23:15 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * input-scrub.c (input_scrub_push): call input_file_begin, not
+ input_scrub_begin.
+ messages.c (as_perror): print ": " between the passed in error and
+ the strerror, like perror does.
+
+Wed Sep 9 11:06:25 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: use gas_target instead of modifying target_cpu.
+ From Steve Chamberlain:
+ Makefile.in: Handle m68*-*-coff*.
+ read.c, read.h: add mult argument to s_space
+
+ * tc-m68k.c (m68k_ip, m68k_ip_op, get_num, try_moto_index): merge
+ Motorola and MIT syntax; gas can now assemble either type of
+ file.
+ tc-m68kmote.c, tc-m68kmote.h: removed now superfluous files.
+ From Steve Chamberlain:
+ m68kcoff.mt: for m68k COFF.
+ obj-coffbfd.c: (fixup_mdeps) added
+ (size_section) removed bad sanity check
+ (fill_section) added rs_machine_dependent case
+ (write_object_file) call fixup_mdeps
+ (fixup_segment) set fx_subsy to 0.
+ obj-coffbfd.h: define WORKING_DOT_WORD (too hard to support) and
+ handle m68k.
+ tc-m68k.c, config/tc-m68k.h: added m68k COFF support and Motorala
+ pseudo ops.
+
+Tue Sep 8 17:10:58 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (LIBS): Include opcode library.
+
+Fri Sep 4 18:20:56 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.c (get_num, case SEG_BIG): If only small integers
+ including zero are accepted, pass +0.0.
+
+Sun Aug 30 21:24:46 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: map "as" through program_transform_name when
+ installing.
+
+ * doc/Makefile.in: map "as" through program_transform_name when
+ installing.
+
+Sat Aug 29 12:11:12 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * Makefile.in (as.new): Depend on LOCAL_LOADLIBES.
+
+Fri Aug 28 16:25:22 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * obj-bout.h, obj-bout.c (obj_header_append, obj_symbol_to_chars),
+ tc-i960.c (md_ri_to_chars): Always output bout object file in
+ little endian byte order (used to use endianness of host).
+
+Tue Aug 25 15:50:48 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * config/tc-m68k.c (init_table): Now const. Always include 68851
+ data, so that "bc" is available to 68040 cache instructions.
+ Added "tt0", "tt1", and 68ec030 variants.
+ (md_assemble): Complain if 68000 (only) and 68881 are specified.
+ (enum _register): Added TT0, TT1.
+ (m68k_ip, cases '3' and 't'): Handle new operand type codes. Pass
+ line number correctly in "internal error" messages. Don't print
+ architecture-mismatch message for operand errors.
+
+ From Colin Smith (colin@wrs.com):
+ * config/tc-m68k.c (m68k_ip, case '_'): Use addword twice rather
+ than install_operand.
+
+Tue Aug 25 15:13:48 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * listing.c (buffer_line): rewind to the start of include
+ files, they might be included twice.
+
+ * z8k.c, z8k.h, z8k.mt: z8000 support stuff
+
+Mon Aug 24 12:45:43 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: defined TARGET_CPU for C code so that it can choose
+ one element of a family.
+
+ * tc-m68k.c: use TARGET_CPU to choose default cpu type.
+
+ * te-generic.h: default to LOCAL_LABELS_DOLLAR and LOCAL_LABELS_FB
+ so that we can assemble hand-written libgcc code.
+
+Fri Aug 21 14:38:44 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * messages.c (as_warn): Use fputs, not fprintf, with a buffer that
+ has already been formatted (but may still contain %-characters).
+ (as_bad): Likewise.
+
+Wed Aug 19 11:20:59 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * tc-m68k.c, tc-m68kmote.c: the cas2 instruction is supposed to be
+ written with indirection on the last two operands, which can be
+ either data or address registers. Added a new operand type 'r'
+ which accepts either register type. Added '(' to notend stuff in
+ tc-m68kmote.c to accept (a0):(a2) in cas2 instruction.
+
+Wed Aug 19 09:25:09 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * as.h (enum _relax_state): Start off at one, not zero, to better
+ catch uninitialized-variable errors.
+ (linkrelax): Declare new variable.
+
+ * messages.c (warning_count, error_count): Default initializer is
+ sufficient.
+
+ * write.c: Merged some declarations, using PARMS macro.
+ (text_frag_root, data_frag_root, bss_frag_root, text_last_frag,
+ data_last_frag): No longer static.
+ (write_object_file, case rs_align or rs_org): If HANDLE_ALIGN is
+ defined, call it. Change segments before calling fixup_segment.
+ (relax_align): If linkrelax, provide extra padding.
+
+ * obj-bout.c (obj_emit_relocations): Emit alignment relocs despite
+ their not having symbols associated.
+
+ * tc-i960.c (norelax, instrument_branches): Default initializer is
+ sufficient.
+ (linkrelax): Delete variable definition.
+ (mem_fmt): Call fix_new with NO_RELOC.
+ (tc_bout_fix_to_chars): Handle alignment relocs.
+ (i960_handle_align): New function.
+ * tc-i960.h (linkrelax): Delete declaration.
+ (HANDLE_ALIGN): New macro; calls i960_handle_align.
+ (NEED_FX_R_TYPE, NO_RELOC): New macros.
+
+Tue Aug 18 14:59:21 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/sparc.mt: New file. Grab sparc opcode table from bfd
+ library.
+
+Tue Aug 18 14:16:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: always create installation directories. Removed
+ MINUS_G, set CFLAGS to default to -g, added FLAGS_TO_PASS, passed
+ FLAGS_TO_PASS to recursive makes.
+
+ * doc/Makefile.in: always create installation directories.
+
+Mon Aug 17 15:09:56 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * input-scrub.c (input_scrub_pop, input_scrub_push): memcpy was
+ being used with args swapped, causing occasional lossage when
+ refilling buffers after an include file.
+
+Mon Aug 17 13:18:51 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * messages.c (as_tsktsk): Use correct ANSI form for stdarg
+ version. Discard bogus DONTDEF version.
+ (as_warn, as_bad, as_fatal): Likewise.
+
+Fri Aug 14 18:31:14 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-m68k.c (m68k_ip): If instruction is invalid for the
+ selected architecture, print a message saying so and listing what
+ processors support it, rather than saying "operands mismatch".
+
+Thu Aug 13 13:53:19 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * as.h [BROKEN_ASSERT]: If defined, turn off all assertion checks.
+
+ * config/ho-rs6000.h (M_RS6000): Don't define it.
+ (free): Declare it.
+ (BROKEN_ASSERT): Define it if not __STDC__.
+
+Tue Aug 11 12:58:14 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * sparc.mt: New file.
+
+Mon Aug 10 14:37:08 1992 Per Bothner (bothner@cygnus.com)
+
+ * tc-m68k.c: ".align N" means align to N-byte boundary *only*
+ if TN_SUN3; otherwise align to 2**N-byte bounary.
+
+Thu Aug 6 12:10:39 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * read.c (s_fill): make the .fill size clamped error a warn and
+ fix bug where 0's were always placed.
+
+ * config/tc-h8300.c: if a :8 is seen after an operand, fill top
+ two bytes of any constant with 0xff:
+
+Wed Aug 5 12:02:40 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-m68k.c (md_pseudo_table): fix the .align thing
+ the right way; for just the 68k. Sun 3 .align is nbytes, not ptwo.
+
+Wed Aug 5 01:54:34 1992 John Gilmore (gnu at cygnus.com)
+
+ * tc-m68k.c (try_index): Error if index scaling specified and
+ assembling for an older CPU than a 68020.
+
+Sat Aug 1 19:10:13 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * config/tc-sparc.c (tc_aout_fix_to_chars): If pc-relative, take
+ fx_offset into account.
+
+Fri Jul 31 21:53:28 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in (mips host): Accept "ultrix" with version number.
+
+ * expr.c (floating_constant): Separate "=-" to avoid confusing
+ ancient or broken compilers.
+
+ * config/tc-m68k.c (m68k_ip): Mismatch error could also indicate
+ processor/opcode mismatch, so reword the error message.
+ (md_assemble): If no CPU has been set (even if FPU/PMMU
+ characteristics have been), default to 68020. Don't need extra
+ quotes around error string.
+
+Fri Jul 31 12:26:34 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * read.c (potable): Revert sac's incorrect change made Jul 13.
+ Align really is supposed to be ptwo not nbytes.
+
+Mon Jul 20 02:51:59 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * Makefile.in: _Do_ include libiberty. (from sef)
+
+Fri Jul 17 15:15:28 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * expr.c (integer_constant): Handle "0f" and "0b" label references
+ properly.
+
+Thu Jul 16 08:20:17 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * write.c (fixup_segment): if relaxing, don't do anything.
+ * config/obj-bout.[ch] : maintain the a_relaxable file header info
+ * config/tc-i960.c: new option -linkrelax
+
+Mon Jul 13 14:11:36 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * expr.c (expr): allow SEG_BSS in expressions
+ * read.c (potable): align should be nbytes, not ptwo!
+ * write.c (write_object_file): extra glue for new bss attributes
+ (relax_segment): SEG_BSS is ok now
+ * config/tc-m68k.c (m68k_ip_op): can now parse more @( modes
+
+Mon Jul 6 17:09:32 1992 Steve Chamberlain (sac@cygnus.com)
+
+ * obj-coffbfd.c (fill_section): mark .lit sections as STYP_LIT
+
+Mon Jun 1 16:20:22 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * configure.in: recognize m680x0 as having sun3 emulation mode for
+ vxworks environment.
+
+
+Tue Jun 30 20:25:54 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * Makefile.in: Add program_suffix (parallel to program_prefix)
+
+Wed Jun 24 10:57:54 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * app.c (process_escape): new function to handle escapes the right
+ way, (do_scrub_next_char): use new function
+ * cond.c (s_ifdef): do ifdef/ifndef right
+ * read.c (s_fill): make the , expressions optional like the doc
+ says
+ * config/tc-h8300.[ch]: better warnings
+
+Tue Jun 9 07:54:54 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * subsegs.c (subsegs_begin): create bss0_frchainP in the same was
+ as data0_frchainP
+
+ * write.c (write_object_file): various changes to handle data in
+ the BSS segment in much the same was as stuff in the DATA segment.
+
+ * tc-m68k.c (m68kip): Fix typo so that only arch's >=68020 do
+ pcrel data stuff. (md_estimate_size_before_relax): when relaxing a
+ 68010 bxx into a bra+6 jmpxx, put the bytes of the jmp opcode into
+ the right place. (s_bss): Don't put .bss stuff into SEG_DATA, put
+ it into SEG_BSS
+
+Thu Jun 4 11:59:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * expr.c(expr): allow SEG_REGISTER in expressions.
+ * read.c(pseudo_set): register expressions can be the source of a
+ set.
+ * subsegs.c (subseg_new): Now -R forces all changes to SEG_DATA to
+ goto SEG_TEXT (if a.out)
+ * write.c (write_object_file): If a.out don't use the old way for
+ -R.
+ * config/obj-a.out (s_sect): complain if the user tries to use a
+ subsegment with a value which might interfere with out -R hackery.
+ * config/tc-m68k.c (m68k_reg_parse): lookup names in symbol table
+ rather than use ugly if tree. (init_regtable): insert register
+ names into symbol table.
+
+Tue Jun 2 16:47:09 1992 Steve Chamberlain (sac@cygnus.com)
+
+ * write.c (write_object_file): keep the fix_tail clean, which
+ fixes a bug in -R where relocations were being lost.
+
+Mon Jun 1 16:20:22 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * configure.in: recognize m680x0 as having sun3 emulation mode for
+ vxworks environment.
+
+Sun May 31 05:33:00 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * configure.in: recognize m680x0 as an m68k
+
+Thu May 28 11:22:02 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * configure.in: Recognize sparclite as a sparc variant.
+
+ * tc-sparc.c: Use new ARCHITECTURES_CONFLICT_P macro. Mention new
+ -Asparclite flag.
+
+Tue May 26 16:47:56 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/tc-a29k.c: lint
+ * listing.c, expr.c: patches from Andrew Smith
+
+Thu May 14 17:22:48 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * doc/Makefile.in: use m4 rather than gm4.
+
+Mon May 4 18:56:19 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * obj-coffbfd.c: use is a synonym for section, (do_relocs_for):
+ calc the base of relocs correctly.
+ * tc-a29k.c (parse_operand): allow expressions to be in any section.
+
+Mon Apr 27 13:13:31 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * as.c, write.c: use -K rather than -k for the broken word warning
+ option.
+
+Tue Apr 21 13:35:30 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: do not print recursion lines.
+
+Wed Apr 15 21:19:31 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: the tooldir copy of gas goes directly in tooldir.
+
+Tue Apr 14 14:50:22 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * write.c (write_object_file): For b.out format, round up section
+ start addresses to match required alignment.
+
+Thu Apr 9 05:45:29 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * Makefile.in (install): Install into $(tooldir)/bin, since that's
+ where gcc looks for it.
+
+Tue Apr 7 15:12:15 1992 Sean Eric Fagan (sef@cygnus.com)
+
+ * Makefile.in: Changed some lines to be less confusing for some
+ makes.
+
+ * input-file.c: Conditionalize on _IOFBF, not VMS.
+
+ * read.c, write.c: Change a series of ifdef/elif to
+ ifdef/else/ifdef etc.
+
+Fri Mar 27 12:21:16 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * symbols.c (fb_label_init): fix sizeof to memset.
+
+Fri Mar 13 15:45:44 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: install the man page.
+
+ * Makefile.in: pass down MAKEINFO explicitly on info.
+
+ * doc/Makefile.in: use $(MAKEINFO) not makeinfo.
+
+Fri Mar 13 08:03:03 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * flonum-const.c: renamed flonum-konst.c to stop dos name
+ conflict.
+
+Thu Mar 12 04:42:38 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * tc-m68k.h, te-sun3.h: moved LOCAL_LABELS_FB definition from
+ tc-m68k.h to te-sun3.h.
+
+Wed Mar 11 23:32:42 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure.in: vxworks68 gets te-sun3.h.
+
+ * expr.c: remove limitation that local_labels_dollar or
+ local_labels_fb must be < 10.
+
+ * symbols.c: remove local_labels_dollar, replace with a function
+ interface for a sparse array. All users adjusted.
+
+ * te-sun3.h: add LOCAL_LABELS_DOLLAR.
+
+Sat Mar 7 00:06:25 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * doc/Makefile.in: commented out line for building as-all.texinfo.
+ This is temporary.
+
+ * doc/as.texinfo, doc/as-all.texinfo: added menu item hooks.
+
+Fri Mar 6 21:57:18 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added check target.
+
+Tue Mar 3 15:45:56 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: added tooldir and program_prefix.
+
+Sun Mar 1 04:43:19 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * write.{c,h} (fix_new): Make these declarations consistent.
+
+Sat Feb 29 13:59:10 1992 Michael Tiemann (tiemann@cygnus.com)
+
+ * Makefile.in (strerror.o): Add rule so that broken Sun make can
+ work in subdirs.
+
+Wed Feb 26 19:26:28 1992 Steve Chamberlain (sac at thepub.cygnus.com)
+
+ * read.c, obj-coffbfd.c : fix h8300 specific bit rot
+
+ * expr.c (operand): if can't work out what sort of operand it is,
+ then look through FLT_CHARS for a hint.
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+ * doc/Makefile.in, doc/configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Tue Feb 25 14:17:15 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * expr.c: If an expression is single comma, then return with
+ SEG_ABSENT rather than an error - since the sparc front end does
+ really strange things with things like fbge,a
+
+ * as.h: include bfd.h if using many sections
+ * expr.c: LOCAL_LABELS_FB had been changed to lower case - so
+ local labels didn't work.
+ * listing.c (list_symbol_table): don't core dump when there's no
+ symbol there.
+ * write.c, write.h: call fix_new with the right number of args on
+ the H8.
+ * config/tc-h8300.[ch] : fix bugs reported by HMSI, and make
+ errors nices
+
+Sat Feb 22 12:26:28 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * app.c: MRI compatibility - allow single quote to start a string.
+ * as.c: fix typo recently introduced.
+ * as.h : Don't include aout/reloc.h - it's not right for COFF!
+ * expr.c: Much rewriting, to accomodate MRI syntax for
+ expressions. Also easier to read now.
+ * listing.c: Put back defuns
+ * read.c: modified to accept MRI syntax, put back listing pseudo
+ ops so that an assembler built with NO_LISTING ignores list ops
+ rather than pukes.
+ * write.c, write.h: fixs - only keep a reloc type in a fix if the target
+ machine is a SPARC or a 29K.
+ * config/obj-aout.c: added s_sect pseudo op
+ * config/obj-coffbfd.c: lints, set the filehdr flags right and
+ fill in the timestamp.
+ * config/obj-coffbfd.h: Since we don't include aout/reloc.h
+ anymore, define all the relocs which the tc-<x> bit will use so we
+ can translate from them to the coff types.
+ * config/tc-a29k.c: reloc_type isn't ane enum any more
+ * config/tc-m68k.c: Added NO_RELOC definition.
+
+Fri Feb 21 06:21:07 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: put header files before C source for TAGS; remove
+ references to non-existent syscalls.h.
+
+ * read.c, write.c subsegs.c: back out the .bss changes.
+
+ * obj-aout.c: do not include stab.gnu.h if NO_LISTING.
+
+ * tc-i860.c, a.out.gnu.h: move i860 relocs to a proper place.
+
+ * a.out.h: removed.
+
+Fri Feb 21 01:08:48 1992 Minh Tran-Le (TRANLE@INTELLICORP.COM)
+
+ * symbols.c (local_label_name): symbols now start with ^A.
+
+ * read.c, subsegs.c, write.c obj-coff.c: added handling of
+ `.bss` pseudo op for unitialized data. The new gcc (1.37.9x)
+ generate these sections. .align: will use NOP_OPCODE or 0
+ for padding. This is just for being nice to the
+ disassembler.
+
+ * expr.c (operand): changed to generate local label "\001L0"
+ starting with a ^A so that it is recognized as a local label.
+
+ * as.c (perform_an_assembly_pass): zero bss_fix_root, too.
+
+ * tc-i386.c: tc-i386.c: added handling of the following opcodes:
+ i/o opcodes - inb, inw, outb and outw. string manipulation with
+ att syntax - scmp, slod, smov, ssca, ssto.
+
+ * obj-coff.c: (for aix386) Moved the symbols .text, .data and .bss
+ to just after .file .
+
+ In obj_crawl_symbol_chain() where it tries to put the external
+ symbols apart, with the condition:
+ (!S_IS_DEFINED(symbolP) &&
+ !S_IS_DEBUG(symbolP) &&
+ !SF_GET_STATICS(symbolP))
+ it was moving too many symbols out. So I switch it back to the
+ condition:
+ (S_GET_STORAGE_CLASS(symbolP) == C_EXT && !SF_GET_FUNCTION(symbolP))
+
+ In obj_emit_relocations() added the conditional on KEEP_RELOC_INFO
+ so that we don't use the F_RELFLG which make the linker complain
+ that somebody has stripped the relocation info.
+
+ Also, the AIX ld program require that the relocation table
+ is sorted by r_vaddr like the standard ATT assembler does.
+
+ [he also changed the sizeof(struct ...)'s into the coff
+ style FOOSZ macros. I'm not sure this is right, but I can't
+ remember why. xoxorich.]
+
+Fri Feb 21 01:08:48 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in, doc: use the doc. Build it, install
+ it, clean it, etc.
+
+Tue Feb 18 02:21:25 1992 K. Richard Pixley (rich at cygnus.com)
+
+ * read.c: white space and comments only.
+
+ * configure.in: use the new atof-ns32.c for ns32k.
+
+ * write.c: comment change only.
+
+ * tc-m88k.[hc]: pulled in from hack's unfinished work. These
+ aren't yet integrated.
+
+ * tc-i860.[hc]: blew off the dust. Something must still be done
+ about conflicting relocation types.
+
+ * tc-ns32k.c: Replaced previous tc_aout_fix_to_chars stub with the
+ real thing.
+
+ * tc-i960.c, tc-sparc.c: white space and comments only.
+
+ * tc-a29k.h: delete duplicate macro definition.
+
+ * new file atof-ns32k.c copied from hack's last unreleased gas.
+
+Mon Feb 17 07:51:06 1992 K. Richard Pixley (rich at cygnus.com)
+
+ * config/tc-ns32k.c: actually make tc_aout_fix_to_chars work
+ rather than abort.
+
+ * nearly everything. flush ChangeLog, package as gas-1.92.1.
+ ChangeLog's prior to this are sketchy at best. I have logs.
+ They just aren't ChangeLogs.
diff --git a/gas/ChangeLog-9697 b/gas/ChangeLog-9697
new file mode 100644
index 00000000000..dd2af824556
--- /dev/null
+++ b/gas/ChangeLog-9697
@@ -0,0 +1,5960 @@
+Wed Dec 31 12:29:47 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_relax_table): Correct branch ranges.
+
+Mon Dec 22 13:06:05 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (i386*-go32-rtems*): Fix to be the same as
+ i[3456]86-go32.
+ * configure: Rebuild.
+
+Mon Dec 22 12:54:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): The 4650 doesn't permit M_LDC1_AB,
+ M_SDC1_AB, M_L_DOB, M_L_DAB, M_S_DAB, or M_S_DOB.
+ (mips_ip): Always check for FP_D, not just for instructions that
+ are not part of the regular ISA.
+
+Thu Dec 18 16:49:28 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-d10v.c (build_insn): Make `number' a long for 64-bit hosts.
+
+Thu Dec 18 16:42:57 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (cpu_types): 21164pc/pca56 does not have CIX.
+
+Wed Dec 17 21:23:07 1997 Jeffrey A Law (law@cygnus.com)
+
+ * expr.c (integer_constant 32bit bignum): Mask off bits outside
+ the range we care about.
+
+Wed Dec 17 15:29:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (md_shortopts): Add 'n' and 'N' options.
+ (exec_type_enum): Enumeration giving all of the exec types.
+ (warn_nops): New static variable to give nop warning level.
+ ({cur,prev}_mul32_p): New static variable to keep track of whether
+ the current/previous instruction is a 32-bit multiply.
+ (Optimizing): Make static.
+ (NOP{2,_LEFT,_RIGHT}): Macros for word of nops and left/right
+ nops.
+ (d30v_insert_operand): Delete declaration of unused function.
+ (write_2_short): Make exec_type argument enum, not int.
+ (parallel_ok): Ditto.
+ (check_range): Delete unused variable(s).
+ (build_insn): Ditto.
+ (find_format): Ditto.
+ (md_apply_fix3): Ditto.
+ (md_show_usage): Document -n and -N.
+ (md_parse_option): Parse -n and -N.
+ (write_1_short): If -n, warn about adding a nop. Use
+ NOP_{LEFT,RIGHT}.
+ (write_2_short): Use enumeration values instead of hard coded
+ integers. Reset exec_type for default operations. For explicit
+ parallel operations, call parallel_ok to make sure everything is
+ ok. If writing out a parallel operation, and the previous
+ instruction was a 32-bit multiply, indicate current instruction
+ is.
+ (parallel_ok): Allow add/tx ... to be done in parallel with
+ another add/tx ... assuming the gpr registers don't overlap.
+ (md_assemble): Use exec type enumeration values, not hard coded
+ ints. Check for loads or 16-bit multiplies following in the next
+ cycle after a 32-bit multiply. Add nops if that is the case.
+ (do_assemble): Copy prev_mul32_p to cur_mul32_p, and set
+ cur_mul32_p if current instruction is a 32-bit multiply.
+ (find_format): Change spacing and layout.
+
+Tue Dec 16 16:55:45 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (tic80_relax): New static variable.
+ (md_longopts): Add new OPTION_RELAX and OPTION_NO_RELAX options.
+ (md_parse_option): Handle new relax options.
+ (md_show_usage): Document new relax options.
+ (find_opcode): Don't use short forms of PC relative branches if
+ tic80_relax is set.
+
+Tue Dec 16 15:26:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): Remove non-register bits from
+ used/set flag fields. Make flag vars unsigned long. Use
+ FLAG_A{0,1} for accumulators. Allow any 2 insns to be done in
+ parallel if they use the same conditional flag with reversed
+ meaning. Allow 2 add/sub insns that set the carry or overflow
+ flags but do not query them to be done in parallel. Don't allow 2
+ word store operations to be done in parallel with ADDppp or
+ SUBppp. Don't allow loads to be done in parallel with 16 bit
+ multiplies.
+
+Tue Dec 16 09:20:43 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c: Prevent use of interworking support for
+ non-COFF targets.
+
+Mon Dec 15 15:20:32 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/all.texi: Add M32R cpu.
+
+ * doc/as.texinfo: Add documentation of m32r processor.
+
+ * doc/c-m32r.texi: New file, documenting m32r specific features.
+
+
+Mon Dec 15 10:32:28 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (mips_ip): Correctly insert 'P' operands into
+ the instruction.
+
+Fri Dec 12 11:44:20 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Handle instructions that have
+ long (32 bit) PC relative offsets. Fix places that previously
+ misused R_MPPCR for 15 bit offsets to use the new R_MPPCR15W type.
+ (md_apply_fix): Add case to handle long PC relative offsets.
+
+Fri Dec 12 10:35:01 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-arm.texi (ARM Options): Document support for new ARM
+ processor names.
+
+ * config/tc-arm.c (md_parse_option): Add support for new ARM
+ processor names.
+
+Thu Dec 11 17:46:50 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Don't overwrite opcode table data.
+ (insop, m68k_ip): Make `opcode' const so it doesn't happen again.
+
+Fri Dec 5 11:23:59 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Fix BFD_RELOC_32 against a
+ symbol + offset.
+
+ * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Use
+ SHT_V850_{S|T|Z}COMMON to mark special common sections.
+
+Tue Dec 2 17:05:13 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Brought up to date with the branch.
+
+Mon Dec 1 20:24:18 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-sh.c (SWITCH_TABLE_CONS): Handle (fix)->fx_size == 1.
+ (SWITCH_TABLE): Handle BFD_RELOC_8.
+ (md_apply_fix): #ifndef BFD_ASSEMBLER code: Handle fixP->fx_size == 1.
+ (coff_reloc_map): Add BFD_RELOC_8_PCREL entry.
+ (sh_coff_reloc_mangle): SWITCH_TABLE case: Handle BFD_RELOC_8.
+
+Sat Nov 22 16:19:22 1997 Richard Henderson <rth@cygnus.com>
+
+ * tc-alpha.c (range_signed_16, range_signed_32): Work around an
+ apparent bug in gcc's long long support crossing from x86.
+
+Sat Nov 22 14:26:09 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c: Brought up to date with latest changes on arm
+ branch.
+
+Sat Nov 22 15:50:09 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * config-gas.com: Get version info from configure.in.
+
+ * makefile.vms: include depend.obj in OBJS.
+
+ * config/tc-alpha.c (s_alpha_section): Remove ".lcomm" handling.
+
+ * config/tc-alpha.c (alpha_basereg_clobbered): Remove variable and
+ all corresponding code.
+
+Thu Nov 20 15:06:08 1997 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/tc-arm.h (TARGET_FORMAT for generic a.out targets): Allow
+ run-time endian selection.
+
+Wed Nov 19 17:44:42 1997 Richard Henderson <rth@cygnus.com>
+
+ * tc-sh.c (parse_reg): Properly quote for fv4.
+
+Wed Nov 19 23:46:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Add missing breaks in case on
+ symbol value operator.
+
+Tue Nov 18 18:45:14 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.c (parallel_ok, find_opcode):
+ Split OPERAND_FLAG into OPERAND_FFLAG and OPERAND_CFLAG.
+
+Sun Nov 16 10:05:07 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Cast second arg of
+ md_apply_fix3 call to type "valueT *".
+
+Thu Nov 13 13:53:10 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (emulations): Make FreeBSD an aout / i386bsd
+ variant.
+ * configure: Re-generate.
+
+Thu Nov 13 11:07:14 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Use the membership field
+ for INSN_MACRO's.
+ (mips_ip): Same.
+
+Thu Nov 13 02:04:55 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.c (find_opcode): For OPCODE_FAKE, add check for
+ first argument if it's supposed to be a register.
+
+Tue Nov 11 19:25:05 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * app.c (do_scrub_chars): If d10v, re-insert a space before
+ a '#' when in state 10.
+
+Tue Nov 11 13:33:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-h8300.c: Include "subsegs.h".
+ (tc_reloc_mangle): Handle references to symbols which are not
+ being output, so that references to `.' work.
+
+Mon Nov 10 13:43:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Call add_fix when needed for '_'
+ case.
+
+ * macro.c (sub_actual): If we don't find a parameter for an &,
+ just substitute &.
+
+Fri Nov 7 21:29:32 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): In default case, call as_bad
+ instead of fprintf, to get "assembler messages:" message output
+ before instead of after.
+
+Fri Nov 7 10:36:22 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * frags.h: Handle multiple inclusion.
+
+Wed Nov 5 10:51:49 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ Based on a patch from Ian.Dall@dsto.defence.gov.au.
+ * as.h (struct frag, frag support): Moved from here.
+ * frags.h: To here.
+ (struct frag, member tc_frag_data): New member if TC_FRAG_TYPE
+ is defined.
+ (struct frag, member fr_cgen): Renamed from fr_targ.cgen.
+ * cgen.c (cgen_asm_finish_insn): Update.
+ * config/tc-m32r.c (md_estimate_size_before_relax): Update.
+ * config/tc-m32r.h (TC_FRAG_INIT): Renamed from md_init_frag.
+ (md_convert_frag): Ditto.
+ * config/tc-ns32k.h (TC_FRAG_TYPE): Define.
+ (frag_opcode_frag,frag_opcode_offset,frag_bsr): Update.
+ (TC_FRAG_INIT): Update.
+
+Tue Nov 4 16:35:57 1997 Ian Dall <Ian.Dall@dsto.defence.gov.au>
+
+ * write.c (print_fixup): Use TC_FIX_DATA_PRINT (if defined) to
+ print out MD fields of fix.
+ * frags.c (frag_var, frag_variant): Use TC_FRAG_INIT macro (if
+ defined) to initialize MD fields in frag.
+ * as.h (struct frag, ns32k support): Rename ns32k to fr_ns32k.
+ Delete pcrel_adjust. Add fr_opcode_fragP, fr_opcode_offset.
+ * config/tc-ns32k.h: Add comments. Remove obsolete
+ BFD_FAST_SECTION_FILL definition, change prototypes for
+ fix_new_ns32k and fix_new_ns32k_exp to add new arguments
+ opcode_frag and opcode_offset and remove pcrel_adjust.
+ (TC_FIX_TYPE): add opcode_fragP and opcode_offset fields.
+ (TC_FIX_DATA_PRINT): new macro to print out TC_FIX_TYPE.
+ (TC_FRAG_INIT): new macro to initialize machine dependent field in
+ frags.
+ (frag_opcode_frag, frag_opcode_offset, frag_bsr): macros to access
+ MD fields in frag structure.
+ (fix_im_disp, fix_bit_fixP, fix_opcode_frag, fix_opcode_offset,
+ fix_bsr): macros to access MD fields in fix structure.
+ * config/tc-ns32k.c: Avoid overlength lines. Align comments. Don't
+ use struct opcode_location as these fields are now in the frag
+ structure.
+ (convert_iif): Call frag_more as it is needed instead
+ of trying to allocate for the whole insn. Avoid call of frag_more
+ with negative argument.
+ (md_pcrel_adjust, md_fix_pcrel_adjust, md_apply_fix,
+ md_estimate_size_before_relax, md_pcrel_from,
+ tc_aout_fix_to_chars): use accessor macros to get md fields in fix
+ and frag structures.
+ (fix_new_ns32k, fix_new_ns32k_exp): add new arguments opcode_frag and
+ opcode_offset and remove pcrel_adjust.
+ (convert_iif, cons_fix_new_ns32k): call fix_new_ns32k,
+ fix_new_ns32k_exp with changed arguments.
+
+Mon Nov 3 13:30:17 1997 Gavin Koch <gavin@cygnus.com>
+
+ * tc-mips.c (md_begin): Reorganize setting of default values so
+ that mips_cpu depends on TARGET_CPU, and mips_opts.isa depends on
+ mips_cpu.
+ (md_parse_option): Remove all code that sets defaults; md_begin
+ handles all of this now.
+
+Sun Nov 2 14:46:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (STAGESTUFF): Change bin_PROGRAMS to
+ noinst_PROGRAMS.
+ (bootstrap, bootstrap2, bootstrap3): Likewise.
+ * Makefile.in: Rebuild.
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Don't adjust relocs in the
+ TOC section to be against the csect.
+
+Fri Oct 31 18:19:55 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-mips.c (validate_mips_insn): New function, checks
+ match versus mask bits, and also verifies that all bits to be
+ output are actually specified somewhere.
+ (md_begin): Call it for 32-bit instructions, instead of doing
+ match/mask check here. In case of failure, print a message, but
+ check the rest of the opcode table before exiting.
+
+Thu Oct 30 13:46:20 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_apply_fix3): Fix thumb ADR pseudo op. Patch
+ from Tony Thompson at ARM: athompso@arm.com
+
+Thu Oct 30 11:11:26 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d30v.c (build_insn): Allow odd registers for ld2w and
+ friends.
+
+Fri Oct 24 15:56:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_assemble): When handling @l, always sign
+ extend if the operand expects a signed value.
+
+ * config/tc-mips.h (LOCAL_LABELS_DOLLAR): Don't define; use
+ default which is to permit dollar labels.
+
+Fri Oct 24 11:19:22 1997 Jakub Jelinek <jj@sunsite.mff.cuni.cz>
+
+ * config/tc-sparc.c (sparc_memory_model): New variable.
+ (md_longopts): Add -TSO/-PSO/-RMO options.
+ (md_parse_options): Handle them.
+ (sparc_elf_final_processing): For 64 ELF, set required
+ memory ordering in e_flags. Default to RMO and let the user
+ override it through command line.
+
+ * config/tc-sparc.h (elf_tc_final_processing): Add.
+
+Wed Oct 22 17:42:12 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-sparc.c (v9a_asr_table): New variable.
+ (sparc_ip): Handle v9a asr's.
+ Patch from David Miller <davem@vger.rutgers.edu>.
+
+Wed Oct 22 17:22:59 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-sparc.h (md_do_align): New macro.
+ * config/tc-sparc.c (sparc_handle_align): Handle rs_align_code.
+ Patch from Jakub Jelinek <jj@sunsite.mff.cuni.cz>.
+
+Wed Oct 22 12:51:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_small): New variable.
+ (OPTION_SMALL): Define.
+ (md_longopts): Add "small".
+ (md_parse_option): Handle OPTION_SMALL.
+ (md_show_usage): Mention -small.
+ * config/tc-sh.h (sh_small): Declare.
+ (SUB_SEGMENT_ALIGN): Handle sh_small.
+ * config/obj-coff.h (TARGET_FORMAT): Check sh_small in TC_SH
+ case.
+
+ * config/tc-mips.c (macro): Correct handling of constant in M_LI_D
+ case in little endian mode.
+
+Tue Oct 21 10:20:11 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-sparc.c (md_apply_fix3, cases ..._H44, ..._HIX22): Leave
+ overflow signalling to linker.
+
+Mon Oct 20 14:54:06 1997 Klaus K"ampf <kkaempf@progis.de>
+
+ * makefile.vms: Fix for dec c.
+
+ * config-gas.com: Give explanation for dec c setup in error
+ message.
+
+ * config/tc-alpha.c (s_alpha_comm): Make .comm symbols separate
+ sections on openvms/alpha.
+
+ * config/obj-evax.c: support .weak pseudo-op
+
+Mon Oct 20 10:13:32 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * config/tc-sparc.c (default_arch_size): New static local.
+ (struct sparc_arch): Rename arch_size to default_arch_size.
+ New member user_option_p.
+ (sparc_arch_table): Always include v9, v9a. New entry v9-64.
+ (init_default_arch): Check whether default arch is valid.
+ Set default_arch_size in addition to sparc_arch_size.
+ (OPTION_32,OPTION_64): Define.
+ (md_longopts): New entries for -32, -64.
+ (md_parse_option): Handle them.
+ (md_show_usage): Print them. Ensure init_default_arch called.
+ * configure.in (sparc64): Set arch to v9-64.
+ * configure: Regenerated.
+
+Sun Oct 19 13:50:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (subsegs_finish): New function, broken out of
+ write_object_file.
+ (write_object_file): Some code moves into subsegs_finish.
+ * write.c (subsegs_finish): Declare.
+ * as.c (main): Call subsegs_finish.
+
+ * read.c (s_include): Check for error return from
+ demand_copy_string.
+
+Tue Oct 14 20:50:58 1997 Richard Henderson <rth@cygnus.com>
+
+ * read.c (get_line_sb): Accept any eol marker while scanning macros.
+
+Tue Oct 14 19:12:45 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.h (DIFF_EXPR_OK): Define.
+ * config/tc-i386.h (DIFF_EXPR_OK): Define.
+ * config/tc-alpha.c (md_apply_fix): Notice fx_pcrel and substitute
+ the correct relocation when it exists.
+ * config/tc-i386.c (md_apply_fix3): Likewise.
+
+ * config/tc-ppc.h: Correct typo in comment.
+ * config/tc-v850.h: Likewise.
+
+Fri Oct 10 16:09:35 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Allow parallel instruction issue
+ when second instruction is writing to first instructions inputs.
+
+Mon Oct 13 15:27:17 1997 Richard Henderson <rth@cygnus.com>
+
+ * ecoff.c (PAGE_SIZE): Double to 8k as a hack to allow some C++
+ templated programs to build with -g.
+
+Fri Oct 10 17:48:29 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_relax_table): Add support for relaxing
+ unconditional branches. This patch is courtesy of Jim Wilson.
+ (md_convert_frag): Fix relaxing of branches. This patch is
+ courtesy of Jim Wilson.
+ (md_assemble): Create different fixups for conditional and
+ unconditional branches. This patch is courtesy of Jim Wilson.
+ (md_estimate_size_before_relax): Estimate size of variable part of
+ fixup based on whether it is for a conditional or an unconditional
+ branch. This patch is courtesy of Jim Wilson.
+ (v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
+ v850_zbss, v850_rosdata, v850_rozdata, v850_bss): Add call to
+ obj_elf_section_change_hook().
+ (v850_comm): New function.
+ (md_pseudo_table): Add new pseudo ops .zcomm, .scomm and .tcomm.
+ (md_begin): Add bss flag to seg_info of bss sections.
+
+ Add support for .scommon, .tcommon and .zcommon sections.
+
+ * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Add .scommon,
+ .zcommon, .tbss, .call_table_data and .call_table_text.
+
+Fri Oct 10 15:01:14 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc): Set DEFAULT_ARCH from correct target.
+ * configure: Regenerated.
+
+Fri Oct 10 11:22:45 1997 Martin M. Hunt <hunt@cygnus.com>
+
+ * config/tc-d10v.c: Fixes to make sure the AT_WORD
+ expression is not confused with -1.
+
+Fri Oct 10 11:54:50 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Flag SP as modified for @-sp
+ operand - OPERAND_ATMINUS.
+
+Fri Oct 10 00:47:44 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Note that auto increment and
+ decrement modify the index register.
+
+Thu Oct 9 15:17:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Robin Kirkham <Robin.Kirkham@mlb.dmt.csiro.au>:
+ * config/tc-m68k.c (archs): Add 68306, 68307, 68322, 68356, 68334,
+ 68336, 68341, 68349.
+ * doc/c-m68k.texi (M68K-Opts): Add -m68ec000 -m68hc000 -m68hc001
+ -m68306, -m68307, -m68322, -m68356, -m68ec020, -m68ec030,
+ -m68ec040, -m68ec060, -m68330, -m68334, -m68336, -m68341,
+ -m68349.
+
+ * doc/Makefile.am (CPU_DOCS): Define.
+ (as.info): Depend upon $(CPU_DOCS).
+ * doc/Makefile.in: Rebuild.
+
+ * configure.in: Remove AM_PROG_INSTALL; it's called by
+ AM_INIT_AUTOMAKE.
+ * configure: Rebuild.
+
+Thu Oct 9 01:44:36 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * tc-d10v.h (TC_START_LABEL): Don't define.
+ (tc_frob_label): Define.
+
+Thu Oct 9 00:07:23 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/tc-d10v.c (write_2_short): Fix bug that wouldn't allow
+ to pair a branch and link with anything but an exe instruction.
+
+Wed Oct 8 16:28:53 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (load_expression): Disable the sym+const .got
+ optimization to reduce the alignment surprises for gcc.
+
+Wed Oct 8 16:11:15 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/obj-coff.h (TC_SPARC): Don't define TARGET_FORMAT.
+ * config/tc-sparc.c (sparc_target_format): Handle coff here.
+ (sparc_ip): Add %hix,%lox.
+ (md_apply_fix3): Call as_bad_where, not as_bad.
+ Add support for BFD_RELOC_SPARC_{HIX22,LOX10}.
+ (tc_gen_reloc): Add support for BFD_RELOC_SPARC_{HIX22,LOX10}.
+
+Wed Oct 8 12:33:32 1997 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Change alpha-*-* to alpha*-*-*; config.guess now
+ recognizes alphaev5 etc.
+ * configure: Rebuild.
+
+Wed Oct 8 00:04:05 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Replace the TARGET_CPU value
+ of mipsr3900 with mipstx39.
+
+ * config/tc-mips.c (mips_ip): Don't print the 'opcode requires
+ -mipsXX message' if the insn isn't an ISA insn.
+
+Tue Oct 7 12:48:30 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.h (TARGET_FORMAT support): Moved to tc-sparc.c.
+ Redefine TARGET_FORMAT to call sparc_target_format.
+ * config/tc-sparc.c (in_unsigned_range): New function.
+ (sparc_arch_size): Make static.
+ (sparc_target_format): New function.
+ (sparc_ip): Delete variable immediate_max. Rewrite %hi/etc reloc
+ handling. Add support for %hh,%hm,%lm,%h44,%m44,%l44.
+ (output_insn): Set `fx_no_overflow'.
+ (md_apply_fix3): Handle BFD_RELOC_SPARC_{7,H44,M44,L44}.
+ (tc_gen_reloc): Likewise.
+
+Mon Oct 6 14:04:50 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_section): Remove.
+
+ * config/obj-elf.c (obj_elf_section): Enhance error message.
+
+Fri Oct 3 15:40:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c: Undef OBJ_COPY_SYMBOL_ATTRIBUTES before
+ including obj-elf.h in OBJ_MAYBE_ELF case.
+ (mips_target_format): Return NULL after abort to avoid warning.
+
+ * ecoff.c (generate_ecoff_stab): Remove unused static function.
+
+ * expr.c (operator): Accept ==. From Anders Blomdell
+ <anders.blomdell@control.lth.se>.
+
+ * config/atof-ieee.c (gen_to_words): When generating a denormal
+ number, handle an overflow into the smallest normalized number.
+
+Mon Sep 29 15:24:52 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * as.h, input-scrub.c (new_logical_line): New return value.
+ * read.c (s_app_file): Don't note the same file several times
+ in a row.
+
+Thu Sep 25 13:08:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Remove ` operand specifier.
+
+Wed Sep 24 16:54:40 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (sh*-*-rtems*): New target, like sh-*-elf*.
+ * configure: Rebuild.
+
+Wed Sep 24 11:30:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Handle q and v operand specifiers.
+
+ * doc/c-i386.texi (i386-Float): Remove incorrect assertion that
+ fn* instructions do not insert implicit fwait. This was changed
+ Jan 29, 1996.
+
+ * config/m68k-parse.y (yylex): Permit an expression to be used for
+ the scale factor.
+
+ * Makefile.am (EXTRA_as_new_SOURCES): Set to config/m68k-parse.y,
+ not m68k-parse.y.
+ * Makefile.in: Rebuild.
+
+ * aclocal.m4: Rebuild with new libtool.
+ * configure: Rebuild.
+
+Tue Sep 23 17:48:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): Clear mri_state at end of .mri
+ pseudo-op.
+
+ * config/tc-mips.c (hilo_interlocks): Change from a static
+ variable to a macro, so that it varies with the variables upon
+ which it depends.
+ (gpr_interlocks, cop_interlocks): Likewise.
+ (md_begin): Don't initialize them.
+
+Fri Sep 19 17:08:41 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Use strcasecomp instead
+ of strcmp where appropriate.
+
+Thu Sep 18 14:11:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Cope with a zero data area
+ relocation with a constant offset.
+ (md_assemble): Produce error message when special data area
+ relocations are used on instructions which do not support them.
+ (md_assemble): Reset processor mask if defined by command line
+ switch.
+
+Thu Sep 18 11:24:01 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c: Reorganize file.
+ (parse_keyword_arg): Allow numbers in reg names.
+ (SPECIAL_CASE_NONE): New macro.
+ (md_assemble): Use it.
+ (lookup_arch,init_default_arch): New functions.
+ (default_arch,default_init_p,sparc_arch_table): New static locals.
+ (sparc_arch_size): New static local.
+ (max_architecture): Initialize in init_default_arch.
+ (md_parse_options): Call init_default_arch if necessary.
+ Rewrite -xarch/-A processing.
+ (md_show_usage): Print -A values from sparc_arch_table.
+ (md_begin): Call init_default_arch if necessary.
+ (sparc_md_end): Handle both 32 and 64 bit environments.
+ * config/tc-sparc.h (TARGET_FORMAT): Likewise.
+ * acconfig.h (SPARC_V9,SPARC_ARCH64): Delete.
+ (DEFAULT_ARCH): Add.
+ * config.in: Regenerate.
+ * configure.in (sparc): Default DEFAULT_ARCH based on target cpu.
+ (SPARC_V9,SPARC_ARCH64): Delete.
+ * configure: Regenerate.
+ * config/vms-conf.h (SPARC_V9,SPARC_ARCH64): Delete.
+
+Wed Sep 17 16:54:20 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_reloc_prefix): Recoded to use CHECK_ ()
+ macro.
+ (handle_tdaoff, handle_zdaoff, handle_sdaoff): New functions.
+
+ * config/tc-v850.c (md_assemble): Corrected typo.
+ * config/tc-v850.c Add new sections: call_table_data and
+ call_table_text.
+ (v850_reloc_prefix): Add support for ctoff() relocation prefix.
+ (handle_ctoff): New Function.
+
+ * doc/c-v850.texi (V850 Opcodes): Document call table relocations.
+
+Tue Sep 16 14:18:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_reloc_prefix): Add support for a 16 bit
+ displacement from the tiny data area pointer.
+
+Mon Sep 15 21:28:09 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (fix_new_hppa): Make declaration match
+ definition.
+
+Mon Sep 15 18:33:06 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (processor_mask): New variable.
+ (set_machine, md_parse_option): Set processor_mask.
+ (md_assemble): Check that instruction is available to target
+ processor.
+
+ * config/tc-v850.h (TARGET_PROCESSOR): New constant.
+
+Mon Sep 15 11:28:04 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merge in work from Martin Hunt:
+
+ * config/tc-d30v.c (build_insn): For mvfsys and mvtsys,
+ CR is 0 for PSWL and PSWH.
+
+ * config/tc-d30v.c (do_assemble): Don't accept
+ illegal condition codes for cmpu instruction.
+
+ * config/tc-d30v.c: Add support for BFD_RELOC_D30V_9_PCREL
+ used in d*i instructions.
+
+ * config/tc-d30v.c (check_size): New function. Check
+ relocations for overflows.
+ (md_pcrel_from_section): Fix relocations between sections.
+ (md_apply_fix3): Use new relocation types for 15 and 21
+ bit relocations in the right container. Needed because
+ the address of the instruction is not eight-byte aligned
+ but the relocations must be.
+
+ * config/tc-d30v.c (md_apply_fix3): Check for overflow.
+ (find_format): If ".s" or ".l" are used, don't try
+ to compute branch sizes.
+
+ * config/tc-d30v.c (do_assemble): Check for ".s" or
+ ".l" extensions to opcode names.
+ (find_format): Generate the correct instructions when
+ ".s" or ".l" are used.
+
+ * config/tc-d30v.c (build_insn): Check for odd registers
+ on instructions that require even registers.
+
+ * config/tc-d30v.h (md_start_line_hook): Define.
+ * config/tc-d30v.c (md_start_line_hook): New hook.
+ Checks the beginning of each line for a ".". If it
+ finds one, assume a pseudo-op and flush any unwritten
+ instructions.
+
+ * config/tc-d30v.c (md_apply_fix3): Fix problem
+ with determining when fixups were done.
+
+ * config/tc-d30v.c (build_insn): Fix bug where the numeric
+ part of a symbol (for example, "foo+8") was being written
+ into the instruction.
+ (md_pseudo_table): Change .word to be 32 bits and add
+ .hword as 16 bits.
+
+ * config/tc-d30v.c (parallel_ok): Check to see if first
+ instruction is a jump.
+
+ * config/tc-d30v.c (parallel_ok): Major code reorganization.
+
+Wed Sep 10 10:07:08 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Corrected spelling mistake.
+ * configure.in (emulations): Add v850 emulation.
+
+Tue Sep 9 17:14:33 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.am (CPU_TYPES): Add arc.
+ (TARGET_CPU_CFILES): Add tc-arc.c.
+ (TARGET_CPU_HFILES): Add tc-arc.h.
+ (dependencies): Rebuild.
+ * Makefile.in: Rebuild.
+ * configure.in: Recognize arc-*-elf*.
+ * configure: Regenerated.
+ * config/tc-arc.[ch]: New files.
+
+Tue Sep 9 10:19:37 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi (V850 Opcodes): Document hi0() reloc prefix.
+ Correct description of hi() reloc prefix.
+
+ * doc/c-v850.texi (V850 Opcodes): Document new reloc prefix.
+ * config/tc-v850.c (v850_reloc_prefix): Add hilo() reloc prefix.
+ * config/tc-v850.c (md_assemble): Add support for BFD_RELOC_32.
+
+ * doc/c-v850.texi: Document new pseudo ops and command line
+ options.
+
+ * config/tc-v850.c (set_machine): New function.
+ * config/tc-v850.c (.v850): New pseudo op.
+ * config/tc-v850.c (.v850e): New pseudo op.
+ * config/tc-v850.c (.v850ea): New pseudo op.
+
+
+Mon Sep 8 23:08:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Support -alh and -ald for DWARF 1:
+ * listing.c (struct list_info_struct): Add debugging field.
+ (listing_newline): Initialize the debugging field. If ELF, if the
+ section starts with .debug or .line, set the debugging field in
+ the listing structure.
+ (debugging_pseudo): Add list parameter. Change all callers. If
+ the debugging field is set, consider it to be a debugging pseudo.
+ If ELF, skip blank lines between debugging lines.
+ * read.c (emit_expr): If ELF, look for line numbers.
+ (stringer): If ELF, look for file names.
+
+Mon Sep 8 12:33:40 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_insert_operand): Only test for overflow
+ if there is no insert function.
+
+ * config/tc-v850.h (TARGET_MACHINE): New constant.
+
+ * config/tc-v850.c (v850_insert_operand): Add
+ -mwarn_unsigned_overflow.
+ (md_begin): Set BFD machine number based on machine variable.
+ (md_parse_option): Add -mv850, -mv850e and -mv850ea options.
+
+Mon Sep 8 11:20:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h: Don't declare alloca if it is a macro.
+ * macro.c: Likewise.
+
+Sun Sep 7 00:30:19 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (md_parse_option): Move m[] out to top level and
+ rename to cpu_types[].
+ (s_alpha_arch): New function.
+ (md_pseudo_table): Add "arch".
+
+ * config/tc-alpha.c (md_begin): Merge the two loops through the
+ opcode table.
+ (s_alpha_proc): Add initial SKIP_WHITESPACE.
+ (s_alpha_set): Likewise. Use get_symbol_end instead local while loop.
+
+Sat Sep 6 19:38:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * read.h (s_lcomm_bytes): Add prototype (for real this time).
+
+Thu Sep 4 12:10:01 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (elf_frob_symbol): Only set BSF_OBJECT for
+ symbols on Irix.
+
+Wed Sep 3 11:21:33 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Remove BFD_RELOC_V850_16_PCREL.
+
+Tue Sep 2 18:32:30 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_convert_frag): PC relative instructions arex
+ relative to the next instruction, not the current instruction.
+ (md_assemble): Similarly.
+
+Tue Sep 2 15:58:52 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi: Explanations of offsets in SDA/ZDA areas
+ correcetd.
+
+ * config/tc-v850.c: Add support for SDA/TDA/ZDA sections.
+ (v850_reloc_prefix): Duplicate code eliminated. Add code to
+ recognise special instructions.
+ (md_assemble): Calculation of the size of a fixups corrected.
+
+ * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Add SDA/TDA/ZDA
+ sections.
+
+Tue Sep 2 15:40:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Use opcode->name instead of
+ opcode->opcode as the sentinal. Zero is a valid opcode.
+
+Tue Aug 26 16:51:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Machine Dependencies): Add v850 to menu.
+ * doc/c-v850.texi: Change node name to match other chapter nodes.
+
+Tue Aug 26 09:46:22 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi (V850 Opcodes): Correct name for tiny data area
+ pointer.
+
+Tue Aug 26 12:23:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (integer_constant): If BFD64, don't make a bignum if the
+ number will fit in 64 bits.
+
+ * config/tc-alpha.c (load_expression): Check explicitly for O_big,
+ rather than calling abort.
+
+ * as.h: Don't define alloca if __GNUC__. Just declare it.
+ * macro.c: Copy alloca handling from as.h.
+
+ * config/tc-i386.c (i386_align_code): Correct 16 bit noops. From
+ Gabriel Paubert <paubert@iram.es>.
+
+ * config/tc-i386.c (md_assemble): In JumpByte case, when looking
+ for a WORD_PREFIX_OPCODE, change it to ADDR_PREFIX_OPCODE if this
+ is jcxz or a loop instruction.
+
+Mon Aug 25 16:04:14 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (pre_defined_registers): Add 'hp' as alias for
+ r2.
+ (md_begin): Set up machine architecture and type.
+
+Mon Aug 25 14:25:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Store the value back into the
+ symbol expression, to handle add or subtract simplification
+ correctly. Handle O_symbol_rva. Add default case.
+
+ * config/tc-ppc.c (ppc_change_csect): Temporarily lower the
+ chunksize while creating the new subsection.
+ * as.c (chunksize): Initialize to zero.
+ * subsegs.c (subseg_set_rest): Change 5000 to chunksize when
+ calling obstack_begin.
+
+Mon Aug 25 11:21:48 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble): Restore input_line_pointer upon
+ exit.
+
+ * config/tc-v850.c (parse_register_list): Support constant
+ expressions as register lists.
+
+Mon Aug 25 10:19:34 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/c-v850.texi: Change the major node to v850 Machine
+ Dependencies.
+
+Fri Aug 22 11:16:14 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/as.texinfo: Add inclusion of c-v850.texi
+
+ * doc/c-v850.texi: New file.
+
+ * read.c (is_end_of_line): Make NUL character be considered to be
+ a line terminator.
+
+Fri Aug 22 10:45:33 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (parse_register_list): Add support for curly
+ brace syntax.
+ (cc_names): Add "e" and "ne" conditions.
+
+Thu Aug 21 11:00:36 1997 Nick Clifton <nickc@cygnus.com>
+
+ * app.c (do_scrub_chars): Support a double dash as starting a
+ comment that extends to end of line.
+
+Thu Aug 21 10:54:27 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (v850_section, v850_bss, v850_offset): New
+ functions.
+ (md_pseudo_table): New pseudo ops: .bss, .offset, .section
+
+Thu Aug 21 00:59:53 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-m32r.c (md_estimate_size_before_relax): Update recorded
+ insn when changing to a different instruction.
+
+Wed Aug 20 00:45:20 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * tc-sh.c (parse_reg, get_specific, build_Mytes): Add SH4
+ floating point extensions.
+ (parse_reg): parse sgr and dbr.
+
+Tue Aug 19 17:07:34 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (system_register_name): Support numbers for
+ system register IDs.
+
+Tue Aug 19 08:59:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * read.c (s_lcomm_internal): Renamed from s_lcomm, added arg to
+ flag when alignment is in bytes instead of power of 2, and code to
+ use that flag to convert alignment to bytes.
+ (s_lcomm, s_lcomm_bytes): New helpers that call s_lcomm_internal.
+ * read.h (s_lcomm_bytes): Add prototype.
+ * config/obj-coff.c (write_object_file): If ALIGNMENT_IN_S_FLAGS is
+ defined, write alignment to alignment bits in section header s_flags
+ rather than the s_align field.
+ * config/obj-coff.h (ALIGNMENT_IN_S_FLAGS): Define for TC_TIC80.
+ * config/tc-tic80.c (md_pseudo_table): Use s_lcomm_bytes for bss
+ pseudo, instead of s_lcomm which wants a power of two for alignment.
+
+Mon Aug 18 20:42:23 1997 Richard Henderson <rth@cygnus.com>
+
+ * macro.c (check_macro): use alloca instead of xmalloc to plug leak.
+
+Mon Aug 18 20:33:06 1997 Richard Henderson <rth@cygnus.com>
+
+ * as.c (show_usage): Add -am.
+ * input-scrub.c (input_scrub_include_sb): Don't add leading \n
+ if we've already got one.
+ * listing.c (struct list_info_struct): Add line_contents.
+ (listing_newline): Put unused argument to work: if non-null, save it...
+ (listing_listing): ... and regurgitate during listing instead of line
+ from file.
+ * listing.h (LISTING_MACEXP): New define.
+ (LISTING_NEWLINE): Argument is NULL.
+ * read.c (read_a_source_file): If expanding macros, break up input
+ lines and pass them to listing_newline.
+ * doc/as.texinfo: Document -ac and -am.
+
+ * cond.c (s_ifc): Add missing demand_empty_rest_of_line.
+
+Mon Aug 18 11:26:36 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_apply_fix3): Add support for new 16 bit PC
+ relative reloc.
+
+Mon Aug 18 11:24:21 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Remove support_v850e flag and command line
+ option.
+
+ * configure.in (emulations): Add support for v850e target
+
+ * configure (emulations): Add support for v850e target
+
+Mon Aug 18 11:24:21 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c: Remove support_v850ea flag and command line
+ option.
+
+ * configure.in (emulations): Add support for v850ea target
+
+ * configure (emulations): Add support for v850ea target
+
+Fri Aug 15 14:00:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (check-DEJAGNU): Don't cd into testsuite until after
+ setting EXPECT and TCL_LIBRARY.
+ * Makefile.in: Rebuild.
+
+ * as.h (enum debug_info_type): Define.
+ (debug_type): Declare.
+ * as.c (debug_type): New global variable.
+ (show_usage): Add --gstabs.
+ (parse_args): Handle --gstabs.
+ * read.c (generate_asm_lineno): Remove.
+ (read_a_source_file): Output stabs debugging if appropriate.
+ Change checks of generate_asm_lineno to check debug_type. Only
+ generate ECOFF debugging if ECOFF_DEBUGGING is defined.
+ * read.h (generate_asm_lineno): Don't declare.
+ (stabs_generate_asm_lineno): Declare.
+ * stabs.c (stabs_generate_asm_lineno): New function.
+ * ecoff.c (add_file): Use debug_type, not generate_asm_lineno.
+ Don't turn off debugging.
+ (add_file): Remove old #if 0 code.
+ (ecoff_new_file): Set debug_type, not generate_asm_lineno.
+ (ecoff_directive_end): Don't generate stabs line symbols.
+ (ecoff_generate_asm_lineno): Don't check stabs_seen. Don't set
+ generate_asm_lineno.
+ (line_label_cnt): Remove.
+ (ecoff_generate_asm_line_stab): Remove.
+ * ecoff.h (ecoff_generate_asm_line_stab): Don't declare.
+ * doc/as.texinfo, doc/as.1: Document --gstabs.
+
+Wed Aug 13 18:58:56 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-v850.c (md_assemble, md_show_usage, md_parse_option):
+ Add support for v850ea instructions.
+
+ * config/tc-v850.c (md_assemble, md_show_usage, md_parse_option):
+ Add support for v850e instructions.
+
+ * config/tc-v850.c (md_assemble): Fix error recovery to reload
+ text of entire opcode.
+
+Tue Aug 12 10:27:34 1997 Richard Henderson <rth@cygnus.com>
+
+ * doc/internals.texi: Document rs_leb128.
+
+Tue Aug 12 12:17:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Give an error message for SIZE_BYTE
+ in ABSL case, rather than calling abort.
+
+Mon Aug 11 21:48:00 1997 Richard Henderson <rth@cygnus.com>
+
+ * as.h (enum _relax_state): Add rs_leb128.
+ * read.c (potable): Add sleb128 and uleb128.
+ (sizeof_*leb128, output_*leb128, emit_leb128_expr, s_leb128): New
+ functions.
+ * read.h: Update prototypes.
+ * symbols.c (resolve_symbol_value): Streamline quite a bit. Return
+ the symbol value, add a second FINALIZE argument that prevents
+ changes from being comitted. Update all callers.
+ * write.c (cvt_frag_to_fill, relax_segment): Handle rs_leb128.
+ * doc/as.texinfo: Document the new pseudos.
+
+Sun Aug 10 14:51:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (MOSTLYCLEANFILES): Add site.bak, site.exp, stage,
+ stage1, and stage2.
+ (DISTCLEANFILES): Define.
+ * doc/Makefile.am (DISTCLEANFILES): Define.
+ * Makefile.in, doc/Makefile.in: Rebuild.
+
+Wed Aug 6 00:30:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Define TARGET_BYTES_BIG_ENDIAN if endian is set.
+ Don't set targ or gas_target. Define SCO_ELF and
+ TARGET_SOLARIS_COMMENT when appropriate. Don't substitute for
+ target_frag.
+ * Makefile.am: Remove @target_frag@.
+ (INCLUDES): Remove $(INTERNAL_CFLAGS), $(CROSS), $(HDEFINES), and
+ $(TDEFINES).
+ (dep-am): Mark as phony.
+ * acconfig.h: Add TARGET_BYTES_BIG_ENDIAN, TARGET_SOLARIS_COMMENT,
+ and SCO_ELF.
+ * config/arm-big.mt, config/arm-lit.mt: Remove.
+ * config/mips-big.mt, config/mips-lit.mt: Remove.
+ * config/ppc-big.mt, config/ppc-lit.mt: Remove.
+ * config/ppc-sol.mt: Remove.
+ * config/i386coff.mt, config/m68kcoff.mt: Remove.
+ * config/m88kcoff.mt: Remove.
+ * config/sco5.mt: Remove.
+ * configure, config.in, Makefile.in: Rebuild.
+
+ * Makefile.am ($(srcdir)/config/m68k-parse.h): New target, to
+ further try to circumvent the .y.h rule.
+ * Makefile.in: Rebuild.
+
+Tue Aug 5 12:32:07 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * acinclude.m4: New file, from old aclocal.m4.
+ * configure.in: Call AM_INIT_AUTOMAKE and AM_PROG_LIBTOOL. Remove
+ shared library handling; now handled by libtool. Replace
+ AC_CONFIG_HEADER with AM_CONFIG_HEADER. Call AC_PROG_YACC,
+ AC_PROG_LEX, and AC_DECL_YYTEXT. Call AM_MAINTAINER_MODE,
+ AM_CYGWIN32, and AM_EXEEXT. Don't call CY_CYGWIN32 or CY_EXEEXT.
+ * config.in: New file, created by autoheader.
+ * conf.in: Remove.
+ * acconfig.h: Mention PACKAGE, VERSION, and USING_CGEN.
+ * stamp-h.in: New file.
+ * as.c (print_version_id): Change GAS_VERSION to VERSION.
+ (parse_args): Likewise.
+ * config/obj-vms.c: (Write_VMS_MHD_Records): Likewise.
+ * doc/Makefile.am: New file, based on old doc/Makefile.in.
+ * Makefile.in, doc/Makefile.in: Now built with automake.
+ * aclocal.m4: Now built with aclocal.
+ * configure: Rebuild.
+
+ * cond.c (s_else): If not listing false conditionals, turn listing
+ off in the false branch of the else.
+
+Mon Aug 4 11:28:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): Fix handling of a double load from a
+ symbol plus an offset.
+
+ * ecoff.c (ecoff_build_symbols): Set fMerge to 0 for an FDR which
+ has an associated external symbol.
+
+Sun Aug 3 23:23:59 1997 Richard Henderson <rth@cygnus.com>
+
+ * config/tc-alpha.c (s_alpha_ucons): New function.
+ (md_pseudo_table): Add unaligned data pseudos for DWARF.
+
+Thu Jul 31 15:13:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Ignore the rest of the current
+ line if we encounter an error.
+
+ * config/tc-v850.c (md_assemble): Sign extend constants value
+ for hi and hi0 expressions.
+ (v850_insert_operand): Enable range checking for generic 16bit
+ operands.
+
+Tue Jul 29 14:20:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Turn on fx_no_overflow for
+ LO16, HI16 and HI16_S relocs.
+
+Mon Jul 28 18:41:41 1997 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Use CYGWIN and EXEEXT autoconf macro to look for
+ win32 dependencies.
+ * configure: Regenerated with autoconf 2.12.
+ * Makefile.in: Add $(EXEEXT) to all executables.
+
+Fri Jul 25 10:54:43 1997 Jeffrey A Law (law@cygnus.com)
+
+ * tc-hppa.c (md_apply_fix): Improve warnings for out of range
+ unconditional branches.
+ (hppa_fix_adjustable): Don't adjust anything with a RR% or LR%
+ field selector.
+
+Thu Jul 24 15:21:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * tc-sparc.c (md_begin): Cast sparc_opcodes to PTR for hash_insert.
+
+Thu Jul 24 17:51:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * macro.c (define_macro): Make sure the index is in range before
+ checking for '('.
+
+Thu Jul 24 12:13:19 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Remove "extended" and replace with
+ "fx" and "fxfrag". Add "ffrag". Change code to initialize and use
+ the right f/ffrag and fx/fxfrag pairs since instruction may be split
+ across frags.
+
+Tue Jul 22 18:38:56 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * config/te-go32.h (USE_ALIGN_PTWO): Define.
+ * config/tc-i386.c (md_pseudo_table): If USE_ALIGN_PTWO is
+ defined, use s_align_ptwo for .align.
+ * configure.in (i386-*-msdosdjgpp*): New target.
+ (i386-*-go32*): Set em to go32 and targ to coffgo32.
+ * configure: Rebuild.
+
+Tue Jul 22 12:41:40 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (last_opcode): New static local.
+ (md_assemble): Don't issue "FP branch in delay slot" warning if
+ the delay slot has been annulled.
+
+Tue Jul 22 13:25:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (md_apply_fix_2): Check for PC relative reloc
+ code if BFD_ASSEMBLER.
+
+Mon Jul 21 08:57:17 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (system_registers): Fix ordering of registers.
+
+Tue Jul 15 16:29:54 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Initialize extended word to zero
+ when it will be filled in later by relocation information.
+
+Mon Jul 14 23:10:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro_build): Restore check of fmt argument.
+ (mips_ip): Fix ISA checks.
+
+Mon Jul 14 19:30:55 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (build_insn): Fix endianness problem with
+ O_big operands.
+
+Sun Jul 13 20:43:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (check_absolute_expr): Change warning to
+ error.
+
+Fri Jul 11 10:18:47 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mips.c (macro_build): Refine code to check if an
+ instruction is available on a particular cpu variant.
+ (mips_ip): Likewise.
+
+Mon Jul 7 22:53:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Change ifndef
+ OBJ_AOUT to ifdef OBJ_ELF.
+ (md_apply_fix3): When mangling 32 bit PC relative reloc for
+ BFD_ASSEMBLER, handle one ELF case for COFF as well, and add a PE
+ case.
+ * write.c (fixup_segment): Change special case for i386-coff to
+ not apply for i386-pe.
+ * config/obj-coff.c (coff_adjust_section_syms): Only count fixups
+ which were not done.
+ (coff_frob_file_after_relocs): Rename from coff_frob_file.
+ (coff_format_ops): Initialize frob_file_after_relocs field rather
+ than frob_file field.
+ * config/obj-coff.h (coff_frob_file): Don't declare.
+ (coff_frob_file_after_relocs): Declare.
+ (obj_frob_file): Don't define.
+ (obj_frob_file_after_relocs): Define.
+ * configure.in: Set bfd_gas to yes for i386-*-cygwin32.
+ * configure: Rebuild.
+
+Wed Jul 2 12:05:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Never subtract section
+ address from PC relative reloc which will be fully resolved.
+
+Tue Jul 1 15:23:07 1997 Jeffrey A Law (law@cygnus.com)
+
+ * ecoff.c (page_type): Renamed from page_t to avoid conflict
+ with hpux10 header files.
+
+Mon Jun 30 12:27:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Jason Merrill <jason@cygnus.com>:
+ * read.c (do_align): If BFD_ASSEMBLER, only use NOP_OPCODE if
+ SEC_CODE is set.
+ * config/tc-i386.h (md_maybe_text): Define.
+ (md_do_align): Use md_maybe_text.
+
+Fri Jun 27 19:15:27 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-ppc.h (tc_fix_adjustable): Only check for GOT type
+ relocations, don't check for symbol being external, weak, etc.
+
+Mon Jun 16 19:12:51 1997 Geoff Keating <geoffk@ozemail.com.au>
+
+ * config/tc-ppc.h (tc_fix_adjustable): Don't let the assembler
+ calculate relocations to any external symbol, because we might be
+ linking a shared object and the symbol might be overriden or moved
+ (for instance, moved into a static executable's .bss section).
+ (GLOBAL_OFFSET_TABLE_NAME): Delete. This is an i386 wierdness.
+
+ * config/tc-ppc.h (tc_fix_adjustable): GOT-based relocations can't
+ be calculated by the assembler.
+
+ * config/tc-ppc.c (md_apply_fix3): Handle @plt or @local branch
+ whose destination lies in the same file, by ignoring the @plt or
+ @local and aiming the branch at its destination.
+
+Mon Jun 16 13:59:18 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * symbols.c (copy_symbol_attributes): Copy BSF_OBJECT flag.
+ * config/obj-elf.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Copy size
+ expression.
+
+ * config/obj-multi.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Define instead
+ of obj_copy_symbol_attributes.
+
+Mon Jun 16 12:45:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_insert_operand): In 32 bit mode, with a
+ signed operand, sign extend a 32 bit value to the host size.
+
+ * Makefile.in (CFLAGS): Subsitute from configure script. From
+ Jeff Makey <jeff@cts.com>.
+
+ * config/tc-i386.c (i386_operand): Use alloca rather than a fixed
+ buffer size to make a copy of the symbol.
+
+ * Makefile.in (OBJS): Put @extra_objects@ on the same line as
+ macro.o.
+
+Thu Jun 12 12:16:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (write_object_file): In non BFD_ASSEMBLER code, as we
+ step through the frags calling cvt_frag_to_fill, switch to
+ SEG_DATA when we reach data_frag_root.
+
+Tue Jun 10 17:08:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Allow an empty register
+ list for instructions which use register lists.
+
+Tue Jun 10 11:18:09 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * config/tc-arm.c (md_apply_fix3): Make temp unsigned long.
+
+ * config/tc-arm.c (arm_adjust_symtab): Only set storage classes if
+ OBJ_COFF.
+
+ * config/tc-arm.c: Add prototypes for many static functions.
+ (struct asm_opcode ): Add prototypes for parms field.
+ (struct thumb_opcode ): Likewise.
+ (fp_op2): Remove unused flags parameter.
+ (output_inst): Make static.
+ (arm_after_pass_hook): Remove unused ignore parameter.
+ * config/tc-arm.h (arm_after_pass_hook): Declare.
+ (arm_start_line_hook): Declare.
+ (arm_frob_label): Declare.
+
+Mon Jun 9 12:55:45 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * depend.c (wrap_output): new prototype.
+
+Mon Jun 9 12:52:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): Check for overflow.
+
+ * config/tc-m68k.c (md_section_align): If a.out and BFD, force
+ section size to be aligned.
+
+Fri Jun 6 17:15:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.h (md_cons_align): Define.
+ (sh_cons_align): Declare.
+ * config/tc-sh.c (md_pseudo_table): Add .uaword and .ualong.
+ (sh_no_align_cons): New static variable.
+ (s_uacons): New static function.
+ (sh_cons_align): New function.
+ (sh_handle_align): Warn about misaligned data.
+ * doc/c-sh.texi: Document .uaword and .ualong.
+
+Thu Jun 5 15:38:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * macro.c (macro_expand): In MRI mode, treat single quote as a
+ separator character when checking for a positional argument.
+
+Tue Jun 3 16:15:13 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_parse_option): Merge in changes from
+ armT-970328-branch.
+
+ * config/tc-arm.h: Merge in changes from armT-970328-branch.
+
+ * configure.in (emulations): Add Thumb architecture support from
+ armT-9703-28-branch.
+
+Mon Jun 2 16:25:07 1997 Nick Clifton <nickc@cygnus.com>
+
+ * doc/all.texi: Add enabling of ARM documentation.
+
+ * doc/as.texinfo: Add ARM documentation from armT-970328-branch.
+
+Mon Jun 2 11:55:12 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c: Added r3900 support.
+
+Thu May 29 12:58:26 1997 Ben Pfaff <pfaffben@pilot.msu.edu>
+
+ * as.c: (parse_args) `-t' option requires an argument.
+
+Wed May 28 15:45:07 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_begin): Change call to
+ coff_arm_bfd_set_private_flags() to a call to
+ bfd_set_private_flags().
+
+Wed May 28 16:17:34 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild dependencies.
+
+ * config/tc-i386.c (tc_gen_reloc): Don't try to convert the type
+ of a BFD_RELOC_RVA reloc.
+
+Wed May 28 10:48:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (tc_fix_adjustable): Reject absolute calls/jumps.
+ (hppa_force_relocation): Force a relocation for an absolute
+ call/jump.
+
+Mon May 26 13:24:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Don't use @value in section names or index
+ entries; it confuses texinfo.tex.
+
+Fri May 23 00:09:35 1997 Tom Tromey <tromey@cygnus.com>
+
+ * doc/as.texinfo: Updated for -MD option.
+ * Makefile.in (CFILES): Added depend.c.
+ (OBJS): Added depend.o.
+ * as.h (start_dependencies, register_dependency,
+ print_dependencies): New declarations.
+ * depend.c: New file.
+ * as.c (parse_args): Added -MD option.
+ (main): Call print_dependencies.
+ (show_usage): Added help for -MD.
+ * read.c (s_app_file): Call register_dependency.
+ (s_include): Call register_dependency when file is found.
+ (read_a_source_file): Call register_dependency.
+
+Wed May 21 17:39:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (symbol_to_chars): If TE_PE, don't add the
+ section address to the symbol value.
+
+Tue May 20 11:23:31 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (macro_build,mips_ip): Move the INSN_ISA field
+ into the new membership field.
+
+Thu May 15 10:00:53 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (md_begin): If no cpu type is specified on the
+ command line then the ARM7 is now chosen by default when setting
+ the BFD machine and architecture.
+
+Wed May 14 09:54:53 1997 Nick Clifton <nickc@cygnus.com>
+
+ * config/tc-arm.c (global variables): Added 'uses_apcs_26' flag to
+ hold APCS selection.
+ (md_begin): Added code to generate flags to be set into the COFF
+ header and the calls to the BFD functions to do this.
+ (md_parse_option, md_show_usage): Added new command line
+ options -mapcs-32, -mapcs-26, -marmv2, -marmv2a, -marmv3,
+ -marmv3m, -marmv4, -marmv4t.
+
+ * tc-arm.h (LOCAL_LABEL): Removed the definition of this macro
+ as it is never used.
+
+Tue May 13 22:26:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_convert_frag): Prefix temporary
+ label name with ".".
+ * config/tc-mn10300.c (md_convert_frag): Likewise.
+
+Tue May 13 14:44:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (set_at): Check for bignum.
+ (check_absolute_expr, macro, mips16_macro): Likewise.
+
+Tue May 13 10:45:56 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (md_apply_fix): Check PC relative relocations
+ for overflow/underflow, only insert lower 15 bits into instruction.
+
+Mon May 12 13:33:08 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * config/tc-i386.c (pi): Check for RegMMX.
+
+Thu May 8 11:10:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (expr): When subtracting values in the same frag,
+ subtract X_add_number rather than adding it.
+
+Wed May 7 15:39:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (write_object_file): Just pass NULL to
+ md_do_align, not the address of a char holding NOP_OPCODE.
+
+ * config/tc-mips.c (macro): Handle constants for M_LI_D and
+ M_LI_DD.
+ (mips_ip): For 'F', 'L', 'f', and 'l', generate a constant rather
+ than an address if the floating point value looks sufficiently
+ simple.
+
+Tue May 6 12:18:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_section_align): If a.out and BFD, force
+ section size to be aligned.
+
+Mon May 5 17:16:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cond.c: Include "macro.h".
+ (struct conditional_frame): Add macro_nest field.
+ (initialize_cframe): Initialize macro_nest.
+ (cond_finish_check): Add nest parameter. Change all callers.
+ (cond_exit_macro): New function.
+ * as.h (cond_finish_check): Update declaration.
+ (cond_exit_macro): Declare.
+ * input-scrub.c (macro_nest): Make globally visible.
+ (input_scrub_next_buffer): Call cond_finish_check.
+ * macro.h (macro_nest): Declare.
+ * read.c (s_mexit): Call cond_exit_macro.
+
+ * config/tc-i386.h (RegMMX): Define.
+ * config/tc-i386.c (pi): Check for all register types.
+ (type_names): Add RegMMX.
+ (md_assemble): Handle RegMMX.
+
+Wed Apr 30 12:47:00 1997 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * config/obj-coff.c (c_section_symbol): Clear the LOCAL bit #ifdef
+ TE_DELTA.
+
+Tue Apr 29 20:23:10 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-mips.c (nopic_need_relax): Add new parameter
+ before_relaxing. Use it when testing ecoff_extern_size.
+ (load_address, macro, md_estimate_size_before_relax): Fix all
+ callers.
+
+Tue Apr 29 19:54:36 1997 Richard Henderson <rth@tamu.edu>
+
+ * config/obj-elf.c (elf_pseudo_table): Add "subsection".
+ (obj_elf_subsection): New static function.
+
+Tue Apr 29 19:52:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (coff_header_append): Don't reset string_size
+ each time through the loop.
+
+Fri Apr 25 14:17:46 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * Makefile.in (DISTSTUFF): Add itbl-parse.h.
+
+Fri Apr 25 12:03:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/internals.texi (Porting GAS): Correct documentation for
+ current configure handling of targ-cpu.h, et. al.
+ (CPU backend): Document listing macros.
+
+ * listing.c (data_buffer): Set size based on other listing macros,
+ rather than always using 100.
+ (data_buffer_size): Remove static variable.
+ (calc_hex): Make data_buffer_size a local variable. Don't leave
+ any slop when filling data_buffer.
+
+Mon Apr 21 15:33:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/c-mips.texi: Document .set autoextend.
+
+Sat Apr 19 23:09:25 1997 Niklas Hallqvist <niklas@petra.appli.se>
+
+ * configure.in (i386-*-openbsd*, m68k-*-openbsd*,
+ mips-dec-openbsd*, ppc-*-*bsd*, ns32k-pc532-openbsd*,
+ sparc-*-openbsd*): New targets.
+ * configure: Rebuild.
+
+Sat Apr 19 22:52:03 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/obj-elf.c (elf_frob_symbol): If TC_MIPS, set BSF_OBJECT
+ for all undefined symbols.
+
+Fri Apr 18 13:37:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_fix_adjustable): Handle zero length csects
+ correctly.
+
+Fri Apr 18 11:51:35 1997 Niklas Hallqvist <niklas@appli.se>
+
+ * configure.in (alpha*-*-openbsd*): New target.
+ * configure: Rebuild.
+
+Thu Apr 17 13:59:47 1997 Per Fogelstrom <pefo@openbsd.org>
+
+ * configure.in (mips-*-openbsd*): New target.
+ * configure: Rebuild.
+
+Wed Apr 16 12:31:24 1997 Martin Hunt <hunt@cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): Fix parallel checking
+ for instructions using conditional execution.
+
+Tue Apr 15 18:11:44 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c (insn_uses_reg): Correct test for fpr pairs.
+
+Tue Apr 15 13:04:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (srcroot): Remove.
+ (INSTALL): Set to @INSTALL@.
+ (INSTALL_XFORM, INSTALL_XFORM1): Remove.
+ (all, dvi): Don't set srcroot.
+ (install): Depend upon as.new, gasp.new, and installdirs. Use
+ $(program_transform_name) directly, rather than using
+ $(INSTALL_XFORM) and $(INSTALL_XFORM1).
+ (installdirs): New target.
+ * doc/Makefile.in (INSTALL_XFORM1): Remove.
+ (install): Depend upon installdirs. Use $(program_transform_name)
+ directly, rather than using $(INSTALL_XFORM) and
+ $(INSTALL_XFORM1).
+ (installdirs): New target.
+ (install-info-as): Run mkinstalldirs.
+ (install-info-gasp): Likewise.
+
+Mon Apr 14 11:59:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL): Change install.sh to install-sh.
+
+ * symbols.c (resolve_symbol_value): Check for division by zero.
+
+ From Thomas Graichen <graichen@rzpd.de>:
+ * Makefile.in: Always use $(SHELL) when running move-if-change.
+ * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub.
+ * configure: Rebuild.
+
+Thu Apr 10 14:40:00 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen.c (cgen_parse_operand): Renamed from cgen_asm_parse_operand.
+ New argument `want'. Update enum cgen_parse_operand_result values.
+ Initialize if CGEN_PARSE_OPERAND_INIT.
+ * config/tc-m32r.c (md_begin): Set cgen_parse_operand_fn.
+ (md_assemble): Call cgen_asm_init_parse.
+ Update call to m32r_cgen_assemble_insn, call as_bad if assembly failed.
+
+Wed Apr 9 11:49:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Handle #j.
+
+Tue Apr 8 16:37:57 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_convert_frag): Create fixup at the
+ right address for call label:32,regs,imm.
+
+Mon Apr 7 14:58:22 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (pa_subspace_start): If OBJ_ELF, then always return
+ zero.
+ * config/tc-hppa.h (tc_frob_symbol): Don't reset the value of the
+ symbol for OBJ_ELF anymore.
+
+Mon Apr 7 10:54:59 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in: Regenerate dependencies.
+ (TARG_CPU): New variable.
+ (cgen.o): Depend on cgen.h, $(TARG_CPU)-opc.h.
+ (.dep1): Delete creating of cgen-opc.h.
+ (.tcdep): Put proper contents in cgen-opc.h.
+ * configure.in (m32r): Delete setting of extra_files, extra_links.
+ (AC_OUTPUT): Create cgen-opc.h.
+ * configure: Regenerated.
+
+Sat Apr 5 13:19:12 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Update to build gasp.exe.
+
+Fri Apr 4 16:10:02 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * write.c (relax_frag): Make non-static.
+ * write.h (relax_frag): Add prototype for.
+ * config/tc-m32r.h (md_do_align): New arg `max'.
+ * config/tc-m32r.c (m32r_do_align): Likewise.
+ Update calls to frag_align, frag_align_pattern.
+ (fill_insn): Update call to m32r_do_align.
+ (m32r_scomm): Update call to frag_align.
+
+ * config/tc-m32r.[ch]: New files.
+ * cgen.c: New file.
+ * Makefile.in (CPU_TYPES): Add m32r.
+ (TARGET_CPU_CFILES): Add tc-m32r.c.
+ (TARGET_CPU_HFILES): Add tc-m32r.h.
+ (DISTCLEAN_HERE): Add cgen-opc.h.
+ (.dep1,.tcdep): Create empty cgen-opc.h.
+ (cgen.o): Add dependencies.
+ (dependencies): Regenerate.
+ * as.h (struct frag): New member fr_targ.
+ (fr_pcrel_adjust,fr_bsr): Move into union fr_targ.ns32k.
+ * conf.in (USING_CGEN): New macro.
+ * configure.in (m32r-*-*): Add entry for.
+ Add cgen.o to extra_objects.
+ * configure: Regenerate.
+ * frags.c (frag_var): fr_pcrel_adjust renamed to
+ fr_targ.ns32k.pcrel_adjust. fr_bsr renamed to fr_targ.ns32k.bsr.
+ (frag_variant): Likewise.
+ * write.c (relax_frag): Likewise.
+ * config/tc-ns32k.c (*): Likewise.
+
+Fri Apr 4 13:26:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-hppa.h (TC_EOL_IN_INSN): Check explicitly for '!',
+ rather than for any end of line character.
+
+ * config/tc-hppa.c (tc_gen_reloc): If hppa_ren_reloc_type fails,
+ call abort (i.e., as_abort) rather than crashing.
+
+ * config/tc-mips.c: Protect uses of STO_MIPS16 with an ifdef of
+ OBJ_ELF, rather than of S_GET_OTHER.
+
+ * Makefile.in (DISTCLEAN_HERE): Add site.exp and site.bak.
+
+Thu Apr 3 13:16:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (VERSION): Set to 2.8.1.
+
+ * Branched binutils 2.8.
+
+Wed Apr 2 12:24:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * COPYING: Update FSF address.
+
+ * config/tc-mips.c (mips16_macro): Handle M_DMUL and M_MUL.
+
+Tue Apr 1 18:29:47 1997 Jim Wilson <wilson@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Don't set interlocks for 4100.
+
+Tue Apr 1 16:24:28 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * config-gas.com: Update to handle both vax and alpha.
+ * makefile.vms: Update to use config-gas.
+ * conf-a-gas.com: Remove file.
+
+Tue Apr 1 16:08:21 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Remove unnecessary itbl-parse.h, ibtl-parse.c, and
+ itbl-lex.c dependencies. Remove rules for itbl-lex.o,
+ itbl-parse.o, and itbl-ops.o; just use the normal .c.o rule.
+
+Tue Apr 1 11:25:56 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/tc-tic80.c (line_comment_char): Make '#' start comments
+ at the beginning of a line for compatibility with .S files where
+ cpp leaves the filename transitions beginning with '#'.
+
+Tue Apr 1 00:07:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c: Only compile tc_coff_symbol_emit_hook and
+ tc_coff_sizemachdep if OBJ_COFF.
+
+Mon Mar 31 23:53:44 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * config/tc-ppc.c (register_name): Declare.
+
+Mon Mar 31 16:31:04 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (hppa*-*-rtems*): New target, like hppa-*-*elf*.
+ * configure: Rebuild.
+
+Mon Mar 31 14:15:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_pseudo_table): Add "stabn".
+ (mips16_mark_labels): New static function.
+ (append_insn): Call mips16_mark_labels.
+ (mips_emit_delays): Likewise.
+ (s_insn): Likewise. Don't call mips_clear_insn_labels.
+ (s_mips_stab): New static function.
+
+ * configure.in: Use ELF for mips-*-gnu*.
+ * configure: Rebuild.
+
+Mon Mar 31 14:01:40 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.h (TARGET_FORMAT): Set to "coff-m68k-sysv" if
+ TE_DELTA.
+
+Fri Mar 28 18:03:19 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * configure.in: Add AC_ARG_ENABLE for commonbfdlib. If it is set,
+ set OPCODES_LIB to empty.
+ * configure: Rebuild.
+
+Fri Mar 28 15:25:24 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * configure.in (sparc-*-linux*aout*, sparc-*-linux*): New
+ targets.
+ * configure: Rebuild.
+
+Fri Mar 28 13:08:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * itbl-parse.y (yyerror): Make static. Declare.
+
+ From Ralf Baechle <ralf@gnu.ai.mit.edu>:
+ * configure.in: Set emulations for mips-*-linux*-*.
+ * configure: Rebuild.
+
+ * config/tc-mips.c (struct mips_set_options): Define.
+ (mips_opts): New static variable.
+ (mips_isa): Remove. Now a field in mips_opts. Change all
+ references.
+ (mips16, mips16_autoextend, mips_warn_about_macros): Likewise.
+ (mips_noreorder, mips_nomove, mips_noat, mips_nobopt): Likewise.
+ (struct mips_option_stack): Define.
+ (mips_opts_stack): New static variable.
+ (s_mipsset): Add support for .set push and .set pop.
+ * doc/c-mips.texi: Document .set push and .set pop.
+
+ * config/obj-elf.c (obj_elf_section_change_hook): New function.
+ * config/obj-elf.h (obj_elf_section_change_hook): Declare it.
+ * config/tc-mips.c (s_change_sec): Call it if OBJ_ELF.
+
+Thu Mar 27 12:23:56 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (parse_args): Update copyright date in version message.
+
+ * Makefile.in (clean-here): Remove dependency files.
+
+ * read.c (s_comm): Check S_IS_COMMON as well as S_IS_DEFINED.
+ (s_mri_common): Check S_IS_COMMON unconditionally.
+ * symbols.c (colon): Check S_IS_COMMON as well as S_IS_DEFINED.
+ * config/tc-alpha.c (s_alpha_comm): Likewise.
+ * config/tc-mips.c (nopic_need_relax): Likewise.
+ * config/tc-ppc.c (ppc_elf_lcomm): Likewise.
+ (ppc_pe_comm): Likewise.
+ * config/obj-elf.c (obj_elf_common): Likewise. Set segment of
+ common symbol to bfd_com_section_ptr.
+ * config/tc-sparc.c (s_common): Likewise.
+ (tc_gen_reloc): Likewise.
+
+Thu Mar 27 00:29:46 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (md_apply_fix3): Get the relocs right.
+
+Wed Mar 26 13:35:15 1997 H.J. Lu <hjl@lucon.org>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Only define if
+ BFD_ASSEMBLER.
+
+Wed Mar 26 11:32:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * input-scrub.c (input_scrub_next_buffer): Handle very long input
+ lines correctly.
+
+ * listing.c (print_lines): Add lineno parameter. Change all
+ callers.
+ (listing_listing): Only call calc_hex for the right line.
+ (listing_list): Set the new edict based on the current edict, in
+ order to handle listing commands in macros correctly.
+
+ * config/tc-mips.c (insn_uses_reg): Map register numbers in mips16
+ instructions.
+
+ * cond.c (cond_finish_check): New function.
+ * as.h (cond_finish_check): Declare.
+ * as.c (main): Call cond_finish_check.
+
+Tue Mar 25 14:45:54 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (md_assemble): If two instructions
+ are supposed to be assembled in parallel and the first one is
+ long, print an error and stop.
+ (md_apply_fix3): Don't calculate absolute relocs. Just write
+ them out.
+
+Mon Mar 24 12:11:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.h (iclrKludge): Define.
+ * config/tc-i386.c (md_assemble): Handle iclrKludge.
+
+ * config/tc-alpha.h (tc_frob_file_before_adjust): Define if
+ OBJ_ECOFF.
+ (alpha_frob_file_before_adjust): Declare if OBJ_ECOFF.
+ * config/tc-alpha.c (alpha_debug): New static variable.
+ (md_parse_option): Set alpha_debug if -g is seen.
+ (alpha_frob_file_before_adjust): New function if OBJ_ECOFF.
+
+Sun Mar 23 18:03:31 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (build_insn): Enable range-checking code.
+ (postfix): Stop at space or comma.
+ (md_assemble): Change error message.
+
+Sat Mar 22 13:44:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Added automatic dependency building.
+ * dep-in.sed: New file.
+
+Fri Mar 21 15:42:37 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-ieee.c (segment_name): Don't define function if this
+ is a macro.
+
+ * config/obj-coff.h (DO_STRIP): Don't define.
+ * config/tc-h8300.h (DO_STRIP): Don't define.
+ * config/tc-h8500.h (DO_STRIP): Don't define.
+ * config/tc-w65.h (DO_STRIP): Don't define.
+ * config/tc-z8k.h (DO_STRIP): Don't define.
+
+ * symbols.c (colon): Call obj_frob_label if it is defined.
+ * config/obj-vms.h (obj_frob_label): Rename from tc_frob_label.
+
+ * configure.in: Don't set files and links. Don't call
+ AC_LINK_FILES. Substitute te_file. Create targ-cpu.h,
+ obj-format.h, targ-env.h, and itbl-cpu.h in AC_OUTPUT.
+ * configure: Rebuild.
+ * Makefile.in (TARG_CPU_C): New variable.
+ (TARG_CPU_O, TARG_CPU_H): New variables.
+ (OBJ_FORMAT_C, OBJ_FORMAT_O, OBJ_FORMAT_H): New variables.
+ (TARG_ENV_H, ATOF_TARG_C, ATOF_TARG_O): New variables.
+ (SOURCES): Rename from REAL_SOURCES. Delete old definition.
+ (LINKED_SOURCES): Remove.
+ (HEADERS): Rename from REAL_HEADERS. Delete old definition.
+ (LINKED_HEADERS): Remove.
+ (OBJS): Use $(TARG_CPU_O), etc., rather than targ-cpu.o, etc.
+ ($(OBJS)): Depend upon $(TARG_ENV_H), etc., rather than
+ targ-cpu.h, etc.
+ ($(TARG_CPU_O), $(OBJ_FORMAT_O) $(ATOF_TARG_O)): New targets.
+ (targ-cpu.o, obj-format.o, atof-targ.o): Remove targets.
+ (itbl-cpu.h): Remove target.
+ (DISTCLEAN_HERE): Remove targ-cpu.c, obj-format.c, atof-targ.c,
+ atof-targ.h.
+
+Thu Mar 20 19:18:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Symbol Names): Don't use obsolete @ctrl macro.
+
+Thu Mar 20 16:49:14 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (mri_chip): Replace calls to get_symbol_end by
+ open coded loop that does not require the name to start with a
+ name beginner.
+
+Thu Mar 20 13:42:01 1997 H.J. Lu <hjl@lucon.org>
+
+ * frags.c (frag_var): Change offset parameter to offsetT.
+ (frag_variant): Likewise.
+ * frags.h (frag_variant, frag_var): Update declarations.
+ * config/tc-m68k.c (struct m68k_it): Change foff field to
+ offsetT.
+ (add_frag): Change off parameter to offsetT.
+ * Several files: Add casts to calls to frag_var.
+
+ * Makefile.in (m68k-parse.c): Depend upon itbl-parse.c, to
+ serialize a parallel make.
+ (itbl-parse.h): Split target out from itbl-parse.c.
+
+Thu Mar 20 12:48:45 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/m68k-parse.y (motorola_operand): Allow (zdireg,EXPR).
+
+ * config/te-delta.h (COFF_COMMON_ADDEND): Define.
+ * config/obj-coff.c (fixup_segment): Check COFF_COMMON_ADDEND when
+ storing the value of a common symbol.
+
+Wed Mar 19 11:37:57 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/obj-coff.c (glue_symbols): Unused variable symbolP
+ removed.
+ (crawl_symbols): Do not modify symbol_rootP and symbol_lastP here;
+ that is done by symbol_remove and symbol_insert.
+
+ * config/obj-coff.h (S_IS_LOCAL): Return 0 for a debugging
+ symbol.
+
+Wed Mar 19 11:06:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): In 32 bit mode, when not
+ dealing with a 64 bit number, permit the upper 32 bits to be set
+ even if bit 31 is not set.
+
+Tue Mar 18 23:30:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (potable): Add "equiv".
+ (s_set): Handle .equiv based on argument.
+ * doc/as.texinfo (Equiv): New node to document .equiv.
+ (Err): New node to document .err.
+
+Tue Mar 18 15:50:13 1997 H.J. Lu <hjl@lucon.org>
+
+ * Many files: Add function prototypes.
+ * as.c (show_usage, parse_args): Make static.
+ * frags.h (frag_alloc): Declare.
+ * subsegs.c (subseg_set_rest): Don't declare frag_alloc.
+ * symbols.c (dollar_label_instance): Change return type to long.
+ * symbols.h (print_symbol_value): Declare.
+ (print_expr, print_expr_1, print_symbol_value_1): Declare.
+ * write.c (fix_new_exp): Don't declare make_expr_symbol.
+ (remove_subsegs, relax_frag): Make static.
+ * config/atof-vax.c (atof_vax_sizeof): Change letter to int.
+ (what_kind_of_float): Likewise.
+ (atof_vax): Make static. Change what_kind to int.
+ (md_atof): Change what_statement_type to int.
+ * config/obj-ecoff.h (obj_ecoff_set_ext): Declare.
+ * config/tc-alpha.c (vax_md_atof): Declare.
+ (md_atof): Don't declare atof_ieee and vax_md_atof.
+ * config/tc-i386.c (set_16bit_code_flag): Make static.
+ * config/tc-i386.h (tc_i386_fix_adjustable): Declare.
+ * config/tc-m68k.c (add_fix): Change width to int.
+ (insert_reg): Change regname to const.
+ (md_atof): Don't declare atof_ieee.
+ (demand_empty_rest_of_line): Don't declare.
+ * config/tc-m88k.c (md_atof): Don't declare atof_ieee.
+ * config/tc-sparc.c (cmp_reg_entry): Change args to const PTR.
+ (parse_keyword_arg): Change lookup_fn to take const arg.
+ (md_atof): Don't declare atof_ieee.
+ * config/tc-sparc.h: Add ifdef for multiple inclusion.
+ (tc_aout_pre_write_hook): Don't declare.
+
+Mon Mar 17 11:21:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h (bfd_alloc_by_size_t): Don't declare.
+ * Many files: Use xmalloc rather than bfd_alloc_by_size_t.
+
+Sun Mar 16 13:49:21 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * symbols.c (symbol_new): Don't call debug_verify_symchain.
+ (symbol_append): Set sy_next and sy_previous when adding a single
+ symbol to an empty list. Call debug_verify_symchain.
+ (verify_symbol_chain): Use assert, not know.
+
+Sat Mar 15 20:27:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * NEWS: Note BeOS support.
+ * configure.in: (ppc-*-beos): New target, use coff as object format.
+ * configure: Regenerate with autoconf.
+
+Sat Mar 15 19:14:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): Improve error message for out
+ of range branch.
+
+ * Makefile.in: Add dependencies on obstack.h where needed.
+
+Fri Mar 14 15:33:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_estimate_size_before_relax): Handle the
+ case of a symbol equated to another symbol when using SVR4_PIC.
+
+ * Makefile.in (TARG_CPU_DEP_sparc): Add opcode/sparc.h.
+
+Thu Mar 13 11:20:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): Call LISTING_NEWLINE before
+ HANDLE_CONDITIONAL_ASSEMBLY when handling an MRI line label.
+
+ * config/obj-elf.c (obj_elf_data): Call md_flush_pending_output
+ and md_elf_section_change_hook if they are defined.
+ (obj_elf_text, obj_elf_previous): Likewise.
+
+Wed Mar 12 11:40:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-multi.h (struct elf_obj_sy): Define if
+ OBJ_MAYBE_ELF.
+ (OBJ_SYMFIELD_TYPE): Define as struct elf_obj_sy if
+ OBJ_MAYBE_ELF.
+ * config/obj-elf.h (struct elf_obj_sy): Don't define if
+ OBJ_SYMFIELD_TYPE is defined.
+
+ * doc/as.texinfo (bss): Improve description of .bss section. In
+ ELF or COFF, you are permitted to switch into the section.
+ (Comm): Rewrite description of common symbols.
+ (Lcomm): Mention that some targets permit a third argument.
+
+Tue Mar 11 01:13:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_lcomm): Don't call S_CLEAR_EXTERNAL.
+
+ * symbols.c (colon): Change type of local to int. From Alan Modra
+ <alan@spri.levels.unisa.edu.au>.
+
+ * config/tc-m88k.c (m88k_do_align): Don't use a special nop
+ alignment if a zero fill pattern was explicitly specified.
+ * config/tc-sh.c (sh_do_align): Likewise.
+
+ * read.c (equals): Always permit register names to be redefined.
+
+ * config/tc-mips.c (mips_fix_adjustable): Permit a reloc against a
+ mips16 symbol to be adjusted if a symbol is being subtracted from
+ it.
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * config/obj-elf.c (obj_elf_symver): Check for duplicate or
+ illegal symbol version names.
+ (elf_frob_symbol): Check for external default versions.
+
+Sun Mar 9 23:49:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * config/obj-elf.h (struct elf_obj_sy): Define.
+ (OBJ_SYMFIELD_TYPE): Define to elf_obj_sy struct. Change all
+ users.
+ * config/obj-elf.c (obj_elf_symver): Just record the name.
+ (obj_symbol_new_hook): Initialized versioned_name field.
+ (elf_frob_symbol): If there is a versioned_name, either rename the
+ symbol, or add an alias with that name.
+
+Thu Mar 6 13:55:32 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_relax_table): Define.
+ (md_convert_frag): Implement.
+ (md_assemble): Handle relaxable operands/instructions correctly.
+ (md_estimate_size_before_relax): Implement.
+ * config/tc-mn10300.h (TC_GENERIC_RELAX_TABLE): Define.
+
+ * config/tc-mn10200.c (md_relax_table): Fix typos.
+
+ * config/tc-mn10300.c (md_assemble): Don't use any MN10300 specific
+ relocs anymore. Tweak fx_offset for pc-relative relocs.
+
+Wed Mar 5 15:46:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cond.c (s_ifc): Call mri_comment_field and mri_comment_end when
+ in MRI mode.
+
+Tue Mar 4 19:34:21 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (md_pseudo_table): Add "sect" and "section"
+ pseudo-ops.
+ * config/tc-tic80.c (md_begin): Declare external variable
+ coff_flags and insert an F_AR32WR bit into it.
+
+Tue Mar 4 10:01:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (equals): Add reassign parameter. Change all callers.
+ * read.h (equals): Update declaration.
+
+Sat Mar 1 01:04:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_extended_frag): Don't assume that we
+ can rely on the frag address to determine whether a frag is
+ earlier or later.
+
+Fri Feb 28 14:40:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.h (LOCAL_LABEL): Only define if not BFD_ASSEMBLER.
+ (S_LOCAL_NAME): Likewise.
+ (FAKE_LABEL_NAME): Define unconditionally.
+ * symbols.c (colon): Call bfd_is_local_label, not LOCAL_LABEL, if
+ BFD_ASSEMBLER.
+ (S_IS_LOCAL): Call bfd_is_local_label_name, not LOCAL_LABEL.
+ * config/tc-*.h: Only define LOCAL_LABEL if not BFD_ASSEMBLER.
+ Don't define FAKE_LABEL_NAME.
+ * config/te-ic960.h: Likewise.
+ * config/tc-mips.h (tc_frob_file_before_adjust): Define.
+ (mips_frob_file_before_adjust): Declare.
+ * config/tc-mips.c (mips_frob_file_before_adjust): New function.
+ (mips_local_label): Remove.
+
+ * config/te-sco386.h: Remove; not used.
+
+Thu Feb 27 15:39:16 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80 (md_pseudo_table): Add align pseudo op to do
+ byte alignment rather than power-of-two alignment that is the
+ GAS default.
+
+Thu Feb 27 13:29:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (md_assemble): Handle a reloc width of 'W'.
+
+ * gasp.c (hash_add_to_string_table): Correct misspelling in error
+ message, and add newline.
+ (process_file): Don't process assignments in the label if this is
+ a equ or assign pseudo-op.
+ (process_pseudo_op): Swap first argument to do_assign for K_ASSIGN
+ and K_EQU, to match documentation.
+
+Thu Feb 27 12:00:03 1997 Michael Meissner <meissner@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_section): Add 'r' section attribute
+ to denote read-only data sections.
+
+Thu Feb 27 00:26:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_common): Set BSF_OBJECT in flags.
+ * config/tc-sparc.c (s_common): Likewise, if BFD_ASSEMBLER.
+
+ * expr.c (operand): Simplify 0b handling. Don't treat 0b as a
+ binary number if the next character is '+' or '-'.
+
+Wed Feb 26 20:47:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (FLT_CHARS): Change from "dD" to "fF".
+ (find_opcode): Match operands that can be floats.
+ (build_insn): Handle O_big (float) expressions and build
+ correct opcode.
+
+Wed Feb 26 18:19:00 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.in (mips*-*-lnews*): New target, also make empty
+ emulation list for this target.
+ * configure: Update.
+ * tc-mips.c (ECOFF_LITTLE_FORMAT): Define.
+ (mips_target_format): Use.
+ * te-lnews.h: New file.
+
+Wed Feb 26 15:33:46 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (find_opcode, build_insn): Changes to match
+ operands with :m or :s modifiers and generate the right opcodes
+ for them.
+
+Wed Feb 26 11:56:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (itbl-parse.c itbl-parse.h): Use $(BISON) and
+ $(BISONFLAGS), not $(YACC) and $(YACCFLAGS).
+
+Tue Feb 25 22:02:23 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.c (instring): Useless local declaration of
+ crack_operand removed.
+ * expr.h (expressionS): Changed type of X_op field to operatorT if
+ __GNUC__.
+
+Tue Feb 25 13:17:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Robert Lipe <robertl@dgii.com>:
+ * configure.in: Add i386coff and i386elf to emulation list.
+ * configure: Rebuild.
+ * as.c (i386coff, i386elf): Declare.
+ * obj.h (coff_format_ops): Declare.
+ * config/obj-coff.c (OBJ_HEADER): Define.
+ (coff_obj_symbol_new_hook): Rename from obj_symbol_new_hook.
+ (coff_obj_read_begin_hook): Rename from obj_read_begin_hook.
+ (obj_pseudo_table): Add "version".
+ (coff_pop_insert): New static function.
+ (coff_sec_sym_ok_for_reloc): New static function.
+ (no_func): New static function.
+ (coff_format_ops): New variable.
+ * config/obj-coff.h (coff_obj_symbol_new_hook): Declare.
+ (obj_symbol_new_hook): Define.
+ (coff_obj_read_begin_hook): Declare.
+ (obj_read_begin_hook): Define.
+ * config/tc-i386.h (i386_target_format): Declare.
+ * config/tc-i386.c: Check OBJ_MAYBE_ELF as well as OBJ_ELF; check
+ OUTPUT_FLAVOR when appropriate.
+ (i386_target_format): New function.
+ * Makefile.in (obj-coff.o): New target.
+ (e-i386coff.o, e-i386elf.o): New targets.
+
+ From Stephen Williams <steve@icarus.icarus.com>:
+ * config/tc-i960.h (TC_SYMFIELD_TYPE): Define if OBJ_COFF.
+ (_tc_get_bal_of_call): Don't declare.
+ (tc_get_bal_of_call): Declare as function, don't define as macro.
+ * config/tc-i960.c (tc_set_bal_of_call): If OBJ_COFF, store balP
+ in sy_tc field, not x_balntry field.
+ (tc_get_bal_of_call): Rename from _tc_get_bal_of_call. Change
+ return type to symbolS *. If OBJ_COFF, retrieve value from sy_tc
+ field, not x_balntry field.
+
+ * config/obj-elf.c (obj_elf_section): Permit a .note section to
+ have the SHF_ALLOC attribute.
+
+ * Makefile.in ($(OBJS)): Don't depend upon $(IT_HDRS).
+ (TARG_CPU_DEP_mips): Depend upon $(srcdir)/itbl-ops.h.
+ (itbl-lex.o): Depend upon itbl-parse.h.
+
+ * itbl-parse.y (yyerror): Change return type to int. Change to
+ use old style function declaration.
+
+ * Makefile.in (itbl-lex.o): Remove -Wall.
+ (itbl-parse.o): Likewise.
+
+ * cond.c (s_ifdef): If we should omit conditionals from listings,
+ call listing_list.
+ (s_if, s_ifc, s_endif, s_else, s_ifeqs): Likewise.
+ * listing.c (list_info_struct): Add EDICT_NOLIST_NEXT.
+ (listing_listing): Handle EDICT_NOLIST_NEXT.
+ (listing_list): An argument of 2 means EDICT_NOLIST_NEXT.
+ * listing.h (LISTING_NOCOND): Define.
+ (LISTING_SKIP_COND): Define.
+ * as.c (show_usage): Mention c as a suboption of -a.
+ (parse_args): Handle c as a suboption of -a.
+ * doc/as.texinfo: Document -alc.
+
+Mon Feb 24 23:34:14 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c (md_apply_fix): Handle R_ABS type fixups.
+
+Mon Feb 24 18:27:43 1997 Eric Youngdale <eric@andante.jic.com>
+
+ * doc/as.texinfo: Document .symver.
+
+Mon Feb 24 15:19:57 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Change pre_defined_registers to
+ d10v_predefined_registers and reg_name_cnt to d10v_reg_name_cnt.
+
+Mon Feb 24 10:40:45 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/obj-coff.c: Fix typo in comment section.
+ * config/tc-tic80.c (md_pseudo_table): Add entry for bss, which takes
+ an additional alignment argument.
+ (find_opcode): Allow O_symbol relocs for any 32 bit field, not just
+ base relative ones.
+ (build_insn): Handle O_symbol relocs for any 32 bit field, not just
+ base relative ones.
+
+Mon Feb 24 02:23:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * Makefile.in: Remove dependancies on itbl-cpu.h.
+ * as.c: Define stubs for itbl_parse and itbl_init if HAVE_ITBL_CPU
+ is not defined.
+
+Mon Feb 24 02:03:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-ops.h: Include as.h.
+
+Mon Feb 24 01:04:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * as.c: Remove -t option.
+ * configure, configure.in: Move itbl-cpu.h to mips specific configure.
+ * itbl-ops.h: Include itbl-cpu.h only if HAVE_ITBL_CPU is defined.
+ * config/tc-mips.h: Define HAVE_ITBL_CPU.
+
+Sun Feb 23 18:01:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-ops.c: Don't define DEBUG.
+
+Sun Feb 23 17:49:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * Makefile.in: Update itbl-test.c to reflect its new location.
+
+Sun Feb 23 15:50:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-ops.c: Add test for itbl_have_entries.
+ * config/tc-mips.c: Remove test for itbl_have_entries.
+ * config/tc-mips.h: Define tc_init_after_args to mips_init_after_args.
+
+Sun Feb 23 18:13:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (DISTSTUFF): Remove itbl-parse.y, itbl-lex.l, and
+ itbl-ops.c. Add itbl-parse.c and itbl-lex.c.
+ (LEX, LEXFLAGS): Define.
+ * itbl-ops.c (append_insns_as_macros): Remove bogus ASSERT.
+
+Sat Feb 22 21:25:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * itbl-parse.y: Fix indentation mistakes from indent program.
+ * itbl-lex.l: Fix indentation mistakes from indent program.
+ * itbl-ops.h: Add include for ansidecl.h.
+ Add PARAMS around function arguments.
+ Add declaration for itbl_have_entries.
+ * itbl-ops.c: Add PARAMS around function arguments.
+ * Makefile.in: Add itbl build rules.
+ Add dependancies for itbl files to mips target.
+ * as.c: Add itbl support.
+ Add new option "--insttbl" for dynamically extending instruction set.
+ * as.h: Declare insttbl_file_name;
+ the name of file defining extensions to the basic instruction set
+ * configure.in, configure: Add itbl-parse.o, itbl-lex.o, and
+ itbl-ops.o to extra_objects for mips configuration.
+ Add include file link from itbl-cpu.h to
+ config/itbl-${target_cpu_type}.h.
+ * config/tc-mips.c: Allow copz instructions.
+ Add notes for future additions to the itbl support.
+ Add debug macros.
+ (macro): Call itbl_assemble to assemble itbl instructions.
+ See if an unknown register is specified in an itbl entry.
+
+Sat Feb 22 20:53:01 1997 Fred Fish <fnf@cygnus.com>
+ * doc/internals.texi (CPU backend): Fix typo in md_section_align
+ description.
+ * config/tc-tic80.h (NEED_FX_R_TYPE): Define.
+ * config/tc-tic80.c (find_opcode): Add code to support O_symbol
+ operands.
+ (build_insn): Grab a frag early so we can use the address in
+ fixups. Take one's complement of BITNUM values before insertion
+ in opcode. Add code to support O_symbol operands.
+ (md_apply_fix): Replace unimplemented warning with implementation.
+ (md_pcrel_from): Ditto.
+ (tc_coff_fix2rtype): Ditto.
+
+Fri Feb 21 14:34:31 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c (parallel_ok): New function.
+ * config/tc-d30v.h: Define TARGET_BYTES_BIG_ENDIAN.
+ * config/tc-d10v.c (md_pcrel_from_section): Return 0 if
+ relocation is in different section.
+
+Fri Feb 21 10:08:25 1997 Jim Wilson <wilson@cygnus.com>
+
+ * tc-mips.c (mips_ip): If configured for an embedded ELF system,
+ don't set the section alignment to 2**4.
+
+Fri Feb 21 11:55:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (line_comment_chars): Add '*'.
+
+ * app.c (LEX_IS_TWOCHAR_COMMENT_2ND): Don't define.
+ (do_scrub_begin): Don't set lex['*'].
+ (do_scrub_chars): When handling LEX_IS_TWOCHAR_COMMENT_1ST, don't
+ check for LEX_IS_TWOCHAR_COMMENT_2ND. Instead, just check for
+ a literal '*'.
+
+ * configure.in: Set em=svr4 for m68k-*-sysv4*.
+ * configure: Rebuild.
+ * config/te-svr4.h: New file.
+ * config/tc-m68k.c (m68k_comment_chars): Only include `#' if
+ TE_SVR4 or TE_DELTA.
+
+Thu Feb 20 22:24:39 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_convert_frag): Create a fixup for the
+ short conditional branch around a long unconditional branch.
+
+Thu Feb 20 13:56:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_ln [both versions]): Call
+ new_logical_line.
+
+ * config/tc-arm.c (fix_new_arm): Use make_expr_symbol to handle a
+ complex expression.
+
+ * symbols.c (resolve_symbol_value): If both left and right
+ operands are undefined, warn about both of them.
+
+Wed Feb 19 00:53:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from Eric Youngdale <eric@andante.jic.com>:
+ * config/obj-elf.c (elf_pseudo_table): Add "symver".
+ (obj_elf_symver): New static function.
+ * config/obj-elf.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Copy the st_other
+ field.
+
+ * write.c (relax_segment): Make type and printf format agree.
+
+ * read.c (get_line_sb): Don't end the line on a semicolon inside a
+ string.
+
+Tue Feb 18 18:42:51 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d30v.c, config/tc-d30v.h: New files.
+
+ * configure: Rebuilt.
+
+ * configure.in: Add case for d30v.
+
+Sun Feb 16 17:47:29 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-alpha.h (md_operand): Define with a null expansion,
+ like all the other targets.
+ * doc/internals.texi (CPU backend): Add missing word in
+ md_flush_pending_output description. Fix typo in md_convert_frag
+ description.
+ * config/tc-tic80: Minor comment additions/changes.
+
+Fri Feb 14 18:09:59 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.c (LOCAL_LABEL): Macro redefined if TE_DELTA.
+ (tc_canonicalize_symbol_name): Macro defined if TE_DELTA.
+ * config/obj-coff.c (obj_coff_def): Use
+ tc_canonicalize_symbol_name if defined.
+ (obj_coff_tag, obj_coff_val): Likewise.
+ * expr.c (operand): Reject '~' as operator if is_name_beginner.
+
+Fri Feb 14 17:24:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on notes from Peter Eriksson <peter@ifm.liu.se>. The target
+ does not actually work, though:
+ * configure.in (i386-sequent-bsd*): New target.
+ * configure: Rebuild.
+ * config/tc-dynix.h: New file.
+ * config/tc-i386.h: Define TARGET_FORMAT if TE_DYNIX.
+
+ * read.c (do_align): Add max parameter. Change all callers.
+ Remove useless static variables.
+ (s_align): New static function. Do common portion of
+ s_align_bytes and s_align_ptwo.
+ (s_align_bytes, s_align_ptwo): Just call s_align.
+ * frags.c (frag_align): Add max parameter. Change all callers.
+ (frag_align_pattern): Likewise.
+ * frags.h (frag_align, frag_align_pattern): Update declarations.
+ * write.c (relax_segment): Limit alignment change to fr_subtype.
+ Fix some types to be addressT.
+ * config/obj-coff.c (size_section): Likewise.
+ * config/obj-ieee.c (size_section): Likewise.
+ * config/tc-d10v.h (md_do_align): Add max parameter.
+ * config/tc-i386.h (md_do_align): Likewise.
+ * config/tc-m88k.h (md_do_align): Likewise.
+ * config/tc-m88k.c (m88k_do_align): Likewise.
+ * config/tc-sh.h (md_do_align): Likewise.
+ * config/tc-sh.c (sh_do_align): Likewise.
+ * as.h: Improve comments on rs_align and rs_align_code.
+ * doc/as.texinfo: Document new alignment arguments.
+ * doc/internals.texi (Frags): Document use of fr_subtype field for
+ rs_align and rs_align_code.
+
+Fri Feb 14 15:56:06 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c: Changed opcode parsing.
+
+Thu Feb 13 20:02:16 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/{tc-alpha.h, tc-d10v.h, tc-generic.h, tc-i960.h,
+ tc-mn10200.h, tc-mn10300.h, tc-sh.h, tc-vax.h, tc-w65.h}:
+ Add default definition of zero for TARGET_BYTES_BIG_ENDIAN.
+ * config/{tc-arm.h, tc-hppa.h, tc-i386.h, tc-mips.h, tc-ns32k.h,
+ tc-ppc.h, tc-sparc.h}: Move definition of TARGET_BYTES_BIG_ENDIAN
+ to a location consistent with the rest of the target include files.
+ * config/tc-i386.c: Remove misleading comment.
+ * doc/internals.texi (CPU backend): Add description of function
+ md_undefined_symbol.
+ * config/tc-tic80.c: Add code to insert predefined symbols into the
+ symbol table so they can be parsed by the standard expression parser.
+ Remove custom code that use to parse them.
+ * config/tc-tic80.h: Move definition of TARGET_BYTES_BIG_ENDIAN
+ to a location consistent with the rest of the target include files.
+
+Thu Feb 13 21:44:18 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * as.h: GNU c provides unlink() function.
+
+ Unify section handling on openVMS/Alpha:
+ * config/tc-alpha.c(s_alpha_link): Remove.
+ (s_alpha_section): New function.
+ Remove case-hacking of symbols
+ Add .code_address pseudo-op.
+ (BFD_RELOC_ALPHA_CODEADDR): New relocation.
+ (s_alpha_code_address): New function.
+ (alpha_ctors_section, alpha_dtors_section): New sections for C++
+ static constructors/destructors.
+ Add debug code for crash debugs, to be removed when traceback code
+ is added to object code.
+ (s_alpha_name): New function for .name pseudo-op.
+ (alpha_print_token): New function to print token expressions with
+ alpha specific extensions.
+
+ * makefile.vms: Allow compilation with current gcc snapshot.
+
+Thu Feb 13 16:29:04 1997 Fred Fish <fnf@cygnus.com>
+
+ * doc/Makefile.in (TEXI2DVI): Set to just name of program.
+ (DVIPS): Set to dvips.
+ (ps, as.ps, gasp.ps): New targets.
+ (internals.info, gasp.dvi, internals.dvi): Set both TEXINPUTS
+ and MAKEINFO env variables.
+ (internals.ps): Use DVIPS macro.
+ (clean): Remove core and backup files.
+ (distclean): Remove temporary files from building internals.
+ (clean-dvi): Ditto.
+ * doc/internals.texi (Frags): Fix typo.
+ (GAS processing): Ditto.
+ (CPU backend): Ditto.
+ * ecoff.c (init_file): Use TARGET_BYTES_BIG_ENDIAN value directly.
+ * mpw-config.in: Define TARGET_BYTES_BIG_ENDIAN as 1.
+ * read.c: Remove ugly hack that dealt with config files not
+ correctly defining TARGET_BYTES_BIG_ENDIAN.
+ (target_big_endian): Use TARGET_BYTES_BIG_ENDIAN directly.
+ * config/arm-big.mt: Define TARGET_BYTES_BIG_ENDIAN to 1.
+ * config/arm-lit.mt: Define TARGET_BYTES_BIG_ENDIAN to 0.
+ * config/mips-big.mt: Define TARGET_BYTES_BIG_ENDIAN to 1.
+ * config/mips-lit.mt: Define TARGET_BYTES_BIG_ENDIAN to 0.
+ * config/ppc-lit.mt: Define TARGET_BYTES_BIG_ENDIAN to 1.
+ * config/ppc-sol.mt: Replace TARGET_BYTES_LITTLE_ENDIAN
+ with TARGET_BYTES_BIG_ENDIAN defined to 0.
+ * config/tc-arm.h: Remove use of TARGET_BYTES_LITTLE_ENDIAN
+ and simplify. Test value of TARGET_BYTES_BIG_ENDIAN, not just
+ whether it is defined or not.
+ * config/tc-mips.h: Remove use of TARGET_BYTES_LITTLE_ENDIAN.
+ * config/tc-ppc.h: Remove use of TARGET_BYTES_LITTLE_ENDIAN
+ and simplify. Test value of TARGET_BYTES_BIG_ENDIAN, not just
+ whether it is defined or not.
+ * config/tic80.h (TARGET_FORMAT): Define to coff-tic80.
+ (TARGET_BYTES_BIG_ENDIAN): Define to 0.
+
+Thu Feb 13 14:40:16 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * write.c (write_relocs): Correct text in as_fatal error message,
+ bfd_perform_relocation -> bfd_install_relocation.
+
+Thu Feb 13 14:48:03 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * config/tc-m68k.c (LEX_TILDE): Define if TE_DELTA.
+ * read.c (LEX_TILDE): Define if not defined.
+ (lex_type): Use LEX_TILDE.
+ * expr.c (get_symbol_end): Check first char with is_name_beginner,
+ not is_part_of_name.
+
+Thu Feb 13 11:40:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_show_usage): Add missing backslash at end
+ of continued line.
+
+ * config/tc-mips.c (mips16_extended_frag): Correct base address
+ for an extended PC relative instruction.
+ (md_convert_frag): Likewise.
+
+ * config/tc-mips.c (prev_nop_frag): New static variable.
+ (prev_nop_frag_holds): New static variable.
+ (prev_nop_frag_required): New static variable.
+ (prev_nop_frag_since): New static variable.
+ (append_insn): If we aren't reordering, and prev_nop_frag is not
+ NULL, and we don't need any nops, then decrease the size of
+ prev_nop_frag. Don't insert nops because of instructions in
+ noreorder sections. Remember whether the previous instructions
+ where in noreorder sections even when not reordering.
+ (mips_no_prev_insn): Add preserver parameter. Change all
+ callers. Refer prev_nop_frag variables when appropriate.
+ (mips_emit_delays): Set up prev_nop_frag.
+ (s_mipsset): Clear prev_nop_frag if reordering.
+
+Wed Feb 12 14:36:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Remove useless code which
+ handled swapping a mips16 jump with a mips16 instruction with a
+ reloc.
+
+ * config/tc-mips.c (md_parse_option): When debugging, set
+ mips_optimize to 1, not 0.
+
+ * config/tc-mips.c (mips16_ip): Handle an extend operand.
+
+ * config/tc-mips.c (my_getExpression): In mips16 mode, if it looks
+ like the expression was based on `.', adjust the value of the
+ symbol.
+
+ * config/tc-mips.c (append_insn): Warn about an attempt to put an
+ extended instruction in a delay slot when not reordering.
+ (md_convert_frag): Warn if an extended instruction appears in a
+ delay slot.
+
+ * config/tc-mips.c (mips_pseudo_table): Add "insn".
+ (s_insn): New static function.
+ * doc/c-mips.texi: Document .insn.
+
+ * config/tc-mips.c (md_begin): Add the general registers to the
+ symbol table.
+ (mips16_ip): First parse the expression, and then see whether it
+ came up with a register, rather than trying to first see whether
+ we are looking at a register.
+
+Tue Feb 11 15:13:39 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-tic80.c: Numerous changes and additions to flesh
+ out functions that were previously just stubs, and fix some
+ problems found using the new TIc80 testsuite cases.
+
+Tue Feb 11 15:52:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_ip): Handle %gprel modifier.
+ (md_apply_fix): Handle BFD_RELOC_MIPS16_GPREL.
+
+ * config/tc-mips.c (append_insn): Output jump instruction as a
+ pair of 2 byte instructions, rather than as a single 4 byte
+ instruction.
+
+Mon Feb 10 22:06:00 1997 Dawn Perchik (dawn@cygnus.com)
+
+ * itbl-ops.c, itbl-lex.l, itbl-parse.y, itbl-ops.h,
+ config/itbl-mips.h: Add copyright message and fix indentation.
+
+Mon Feb 10 18:09:00 1997 Dawn Perchik (dawn@cygnus.com)
+
+ * itbl-ops.c: New file. Add support for dynamically read
+ instruction registers, opcodes and formats. Build internal table
+ for new instructions and provide callbacks for assembler and
+ disassembler.
+ * itbl-lex.l, itbl-parse.y: Lex and yacc parsers for instruction
+ spec table.
+ * itbl-ops.h: New file. Header file for itbl support.
+ * config/itbl-mips.h: New file. Mips specific definitions for
+ itbl support.
+
+Fri Feb 7 09:52:34 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_assemble): If a constant operand won't
+ fit into the constant field of a relaxable operand, then it does
+ not match.
+
+Thu Feb 6 20:08:12 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_estimate_size_before_relax): Treat
+ a jsr target in a different section just like a jsr to
+ an undefined target.
+
+Thu Feb 6 16:52:57 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_fix_adjustable): Don't adjust relocations
+ against any mips16 symbols, not just externally visible ones.
+ (md_apply_fix): Corresponding change.
+
+Wed Feb 5 11:11:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_ip): Accept floating point registers in
+ the operand of the exit instruction.
+
+Tue Feb 4 14:12:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): If we leave an equated symbol
+ as O_symbol, copy over the segment.
+
+Mon Feb 3 12:35:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_apply_fix): If we aren't adjusting this
+ fixup to be against the section symbol, adjust the value
+ accordingly.
+
+ * symbols.c (resolve_symbol_value): Don't change X_add_number for
+ an equated symbol.
+ * write.c (write_relocs): Avoid looping on equated symbols.
+ Adjust fx_offset by X_add_number for each symbol.
+ * config/obj-coff.c (do_relocs_for): Avoid looping on equated
+ symbols.
+ (fixup_segment): Add a loop to track down equated symbols and
+ adjust fx_offset appropriately.
+
+Fri Jan 31 15:21:02 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_relax_table): Add entries to allow
+ jmp -> bra relaxing.
+ (md_convert_frag): Handle jmp->bra relaxing.
+ (md_assemble): Handle jmp->bra relaxing.
+ (md_estimate_size_before_relax): Likewise.
+
+Fri Jan 31 13:15:05 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_align_code): Add comments explaining the
+ nop instructions.
+
+Fri Jan 31 10:46:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (enforce_aligned_data): New static variable.
+ (sparc_cons_align): Don't do anything unless enforce_aligned_data
+ is set.
+ (md_longopts): Add "enforce-aligned-data".
+ (md_show_usage): Mention --enforce-aligned-data.
+ * doc/c-sparc.texi (Sparc-Aligned-Data): New node; document
+ enforce-aligned-data.
+
+ * config/tc-ppc.c (md_pseudo_table): If OBJ_XCOFF, add "long",
+ "word", and "short".
+ (ppc_xcoff_cons): New static function.
+
+ * write.c (relax_segment): Give an error if a .space symbol is
+ common or undefined.
+
+ * read.c (read_a_source_file): Don't handle mri_pending_align if
+ the handler is s_globl or s_ignore.
+
+Thu Jan 30 11:46:59 1997 Fred Fish <fnf@cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Remove unused variable "numops".
+ * config/tc-tic80.c: Many additions to previous placeholder file.
+ * config/tc-tic80.h: Ditto.
+
+Thu Jan 30 12:28:18 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * config/tc-i386.c (i386_align_code): Improve the nop patterns.
+
+Thu Jan 30 12:08:40 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_fix_adjustable): New function.
+ * config/tc-mips.h (tc_fix_adjustable): Call mips_fix_adjustable.
+ (mips_fix_adjustable): Declare.
+
+ Ideas from Srinivas Addagarla <srinivas@cdotd.ernet.in>:
+ * read.c (read_a_source_file): After doing an mri_pending_align,
+ adjust the line_label if there is one.
+ (s_space): Set mri_pending_align if an odd number of bytes were
+ output.
+
+Wed Jan 29 15:31:12 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.h (md_do_align): Add this hook to call
+ d10v_cleanup() when a ".align" is detected.
+
+ * config/tc-d10v.c (find_opcode): Correctly calculate
+ branch displacement when .aligns are present.
+
+Wed Jan 29 09:42:11 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_relax_table): Define.
+ (md_convert_frag): Implement.
+ (md_assemble): Handle relaxable operands/instructions correctly.
+ (md_estimate_size_before_relax): Implement.
+ * config/tc-mn10200.h (TC_GENERIC_RELAX_TABLE): Define.
+
+Tue Jan 28 15:27:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Give an error for jumps to a
+ misaligned address.
+ (md_apply_fix): Make a branch to an odd address an error rather
+ than a warning.
+
+ * config/tc-mips.c (md_convert_frag): If the user explicitly
+ requested an extended opcode, pass warn as true to mips16_immed.
+
+ * config/tc-mips.c (mips16_ip): Handle a missing expression like
+ an explicit 0, so that explicitly extended instructions work
+ correctly.
+
+Mon Jan 27 17:41:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_build_symbols): Don't generate a local ECOFF
+ symbol for a common symbol.
+
+Wed Jan 22 10:39:39 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ Patch presumed to have been checked in awhile ago but wasn't.
+ Mon Nov 25 10:45:14 1996 Doug Evans <dje@seba.cygnus.com>
+ * write.c: Delete "ifndef md_relax_frag" around is_dnrange.
+ (relax_segment, case rs_org): Move code inside braces. Move locals
+ target,after inside too.
+ (relax_segment, case rs_machine_dependent): Guts moved to ...
+ (relax_frag): New function.
+ Call md_prepare_relax_scan if defined.
+
+Mon Jan 20 10:56:47 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip): Reject pc-relative addresses for the
+ 'p' operand specifier.
+
+Mon Jan 20 10:39:36 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * config/tc-m68k.c (HAVE_LONG_BRANCH): New macro, returns true for
+ m68k family cpus which support long branch addressing modes.
+ (m68k_ip, md_convert_frag_1, md_estimate_size_before_relax,
+ md_create_long_jump): Use it.
+
+Mon Jan 20 12:42:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_begin): Don't set SEC_ALLOC or SEC_LOAD for
+ the .reginfo or .MIPS.options section if configured for an
+ embedded target.
+
+ * config/tc-mips.c (md_begin): Don't set interlocks for
+ mips_4650.
+
+Wed Jan 15 13:51:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): Make sure the symbol ends with
+ whitespace before checking whether the next character is '='.
+
+Tue Jan 14 15:07:27 1997 Robert Lipe <robertl@dgii.com>
+
+ * config/tc-i386.c (sco_id): Moved from here...
+ * config/obj-elf.c (sco_id): ...to here. Adding the identifier
+ really is an SCO ELF specific thing, not just a SCO x86 specific
+ thing.
+
+Mon Jan 13 22:43:01 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (tic80-*-*): Don't require 'coff'.
+ * configure: Regenerate.
+
+Thu Jan 9 09:08:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (emit_expr): Check for overflow of a negative value
+ correctly.
+ * write.c (fixup_segment): Likewise.
+ * config/obj-coff.c (fixup_segment): Likewise.
+
+ * config/tc-m68k.c (struct label_line): Define.
+ (labels, current_label): New static variables.
+ (md_assemble): Mark current_label as text, and clear it.
+ (m68k_frob_label): New function.
+ (m68k_flush_pending_output): New function.
+ (m68k_frob_symbol): New function.
+ * config/tc-m68k.h (tc_frob_label): Define.
+ (md_flush_pending_output): Define.
+ (tc_frob_symbol): Don't warn, just call m68k_frob_symbol.
+ (tc_frob_coff_symbol): Likewise.
+
+ * read.c (read_a_source_file): When defining a macro in MRI mode,
+ don't add the symbol to the symbol table.
+
+Tue Jan 7 11:21:42 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (tc_gen_reloc): Handle sym1-sym2 fixups
+ here since fixup_segment doesn't (linkrelax is set).
+ * config/tc-mn10200.c (tc_gen_reloc): Likewise.
+
+Mon Jan 6 15:19:32 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (md_assemble): Tweak fx_offset for pc-relative
+ relocs.
+
+Fri Jan 3 16:47:08 1997 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (struct hppa_fix_struct): Tweak fx_r_field's type
+ to avoid warnings with the native HP compiler.
+ (fix_new_hppa): Similarly for the r_type argument.
+ (pa_build_unwind_subspace, hppa_elf_mark_end_of_function): Enclose
+ in an #if OBJ_ELF to keep gcc -Wall quiet.
+ (md_apply_fix): Always initialize "result".
+
+ * config/tc-mn10200.c (md_assemble): Generate relocations.
+
+Fri Jan 3 18:17:23 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (s_even): Adjust the alignment of the current
+ section.
+
+Fri Jan 3 17:10:33 1997 Richard Henderson <rth@tamu.edu>
+
+ * config/obj-elf.c (elf_file_symbol): When using ECOFF debugging,
+ pass on the new file hook.
+
+ * config/tc-alpha.c (alpha_fix_adjustable): Not quite the same as
+ !alpha_force_relocation, as local LITERALs can be adjusted to be
+ relative to the section.
+
+Fri Jan 3 12:09:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (yank_symbols): If tc_frob_coff_symbol is
+ defined, call it.
+ * config/tc-m68k.h (tc_frob_symbol): Check whether text label is
+ aligned to odd boundary.
+ (tc_frob_coff_symbol): Define.
+
+ * doc/as.texinfo (Set): Change parenthesized @xref to @pxref.
+
+ * macro.c (macro_expand_body): In MRI mode, just copy a single &.
+
+ * config/tc-m68k.c (m68k_ip): Call frag_grow before adding a
+ PCINDEX frag. From Ronald F. Guilmette <rfg@monkeys.com>.
+
+ * config/tc-m68k.c (m68k_ip): Accept 'B' as a size for an
+ immediate value.
+ (md_assemble): If the size is 'B', set fx_signed.
+ (md_apply_fix_2): Use fx_signed when checking for overflow.
+
+ * write.h (struct fix): Add fx_signed field.
+ * write.c (fix_new_internal): Initialize fx_no_overflow and
+ fx_signed fields.
+ (fixup_segment): Use fx_signed when checking for overflow.
+ * config/obj-coff.c (fixup_segment): Check fx_no_overflow and
+ fx_signed when checking for overflow.
+
+Thu Jan 2 13:37:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * NOTES, NOTES.config: Removed. These are rarely, if ever,
+ updated, and all the useful information is in doc/internals.texi.
+
+ Based on patch from Ronald F. Guilmette <rfg@monkeys.com>:
+ * read.c (read_a_source_file): Check for conditional operators
+ before doing an MRI pending alignment.
+ * config/tc-m68k.h (m68k_conditional_pseudoop): Declare.
+ (tc_conditional_pseudop): Define.
+ * config/tc-m68k.c (m68k_conditional_pseudop): New function.
+ * doc/internals.texi (CPU backend): Describe
+ tc_conditional_pseudoop.
+
+ Based on patch from Ronald F. Guilmette <rfg@monkeys.com>:
+ * config/tc-m68k.c (m68k_rel32_from_cmdline): New static
+ variable.
+ (md_begin): Check m68k_rel32_from_cmdline before setting
+ m68k_rel32.
+ (m68k_mri_mode_change): Likewise.
+ (md_longopts): Add --disp-size-default-16 and
+ --disp-size-default-32.
+ (md_parse_option): Handle new options.
+ (md_show_usage): Mention new options.
+ * doc/c-m68k.texi (M68K-Opts): Document new options.
+
+ Based on patch from Ronald F. Guilmette <rfg@monkeys.com>:
+ * config/tc-m68k.c (m68k_index_width_default): New static
+ variable.
+ (m68k_ip): Use m68k_index_width_default to set the size of a base
+ register whose size was not given.
+ (md_longopts): Add --base-size-default-16 and
+ --base-size-default-32.
+ (md_parse_option): Handle new options.
+ (md_show_usage): Mention new options.
+ * doc/c-m68k.texi (M68K-Opts): Document new options.
+
+ * doc/c-mips.texi: Mention ISA level 4, and the -mips16 option.
+
+ * configure.in: Recognize mips-*-linux* target.
+ * configure: Rebuild.
+
+ * config/tc-mips.c (load_register): Rewrite 64 bit handling to
+ work if valueT is only 32 bits.
+
+ * config/tc-mips.c: Throughout, check target_big_endian rather
+ than byte_order.
+ (byte_order): Remove.
+ (mips_init_after_args): Remove.
+ * config/tc-mips.h (LITTLE_ENDIAN, BIG_ENDIAN): Don't define.
+ (mips_init_after_args): Don't declare.
+ (tc_init_after_args): Don't define.
+
+ * config/tc-mips.h (tc_frob_after_relocs): Define if
+ OBJ_MAYBE_ELF.
+ (mips_elf_final_processing): Likewise.
+ (ELF_TC_SPECIAL_SECTIONS): Likewise.
+
+Tue Dec 31 15:12:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-v850.c (md_assemble): If this is sst.{h,w} or
+ sld.{h,w} and the operand is relocatable, adjust the adend by
+ shifting it right one bit.
+
+Tue Dec 31 12:56:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (read_a_source_file): Check mri_pending_align after
+ checking for a macro. From Ronald F. Guilmette
+ <rfg@monkeys.com>.
+
+ * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE.
+
+ * config/tc-sparc.c (md_apply_fix3): Rename from md_apply_fix, and
+ add segment argument. If OBJ_ELF, treat a relocation against a
+ symbol in a linkonce section like a relocation against an external
+ symbol.
+ * config/tc-sparc.h (MD_APPLY_FIX3): Define.
+
+Mon Dec 30 11:35:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_macro): Add case for M_ABS.
+
+Fri Dec 27 22:51:51 1996 Fred Fish <fnf@cygnus.com>
+
+ * NOTES.config (Implementation): as.h #define's "GAS" not "gas",
+ includes config.h instead of host.h, tc.h instead of tp.h, and
+ targ-env.h instead of target-environment.h.
+ Also, obj-format.h includes targ-cpu.h instead of
+ target-processor.h.
+ * configure.in (case ${generic_target}): Add tic80-*-coff entry.
+ * configure: Rebuild with autoconf.
+ * config/obj-coff.h (coff/tic80.h): Include if TC_TIC80 defined.
+ (TARGET_FORMAT): Define to "coff-tic80".
+ * config/tc-tic80.c: New file for TIc80 support.
+ * config/tc-tic80.h: New file for TIc80 support.
+
+Fri Dec 27 11:42:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (M): Mention explicitly that -M changes macro
+ handling.
+
+Thu Dec 19 12:06:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): If the fixup symbol has been
+ equated to an undefined symbol, convert the fixup to being against
+ the target symbol. Remove obsolete code handling a special case
+ for i386 PIC.
+
+Wed Dec 18 22:54:39 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Use NewFolderRecursive for installation.
+
+Wed Dec 18 16:00:42 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (do_assemble): Correct previous bug fix.
+
+Wed Dec 18 15:27:40 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Fix bug which caused
+ second instruction in a line to be case sensitize.
+
+Wed Dec 18 10:08:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (mn10200_insert_operand): Don't
+ range check operands with MN10200_OPERAND_NOCHECK set.
+ (check_operand): Likewise.
+
+Tue Dec 17 10:59:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c: Undo part of last Friday's alignment changes.
+ (md_begin): Always align the text section to a four byte
+ boundary.
+ (append_insn): Remove call to record_align.
+
+ * config/tc-mips.c (insn_label): Remove.
+ (struct insn_label_list): Define.
+ (insn_labels, free_insn_labels): New static variables.
+ (mips_clear_insn_labels): New static function.
+ (append_insn): Mark all mips16 text labels, and make them odd.
+ Handle all labels after emitting a nop, not just one. Call
+ mips_clear_insn_labels rather than just clearing insn_label.
+ (mips_emit_delays): Add insns parameter, and use it to decide
+ whether to mark mips16 labels. Handle all labels, not just one.
+ Force mips16 labels to be odd. Change all callers.
+ (mips16_immed): Don't check for an odd branch target.
+ (md_apply_fix): Don't check mips16 mode for a branch reloc.
+ (mips16_extended_frag): Ignore the low bit in a branch target.
+ (md_convert_frag): Likewise.
+ (mips_no_prev_insn): Call mips_clear_insn_labels rather than just
+ clearing insn_label.
+ (mips_align, mips_flush_pending_output, s_cons): Likewise.
+ (s_float_cons, s_gpword): Likewise.
+ (s_align): Use insn_labels rather than insn_label.
+ (s_cons, s_float_cons, s_gpword): Likewise.
+ (mips_frob_file_after_relocs): New function.
+ (mips_define_label): Rewrite to add to insn_labels list.
+ * config/tc-mips.h (tc_frob_file_after_relocs): Define.
+ * ecoff.c (ecoff_build_symbols): If the size of a function comes
+ out odd, increment it.
+
+ * config/tc-mips.c (append_insn): Only update prev_insn when not
+ reordering if place is NULL.
+
+ * config/tc-mips.c (mips16_ip): Check for a missing expression
+ when using the register indirect addressing mode.
+
+Mon Dec 16 10:08:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c (mn10200_insert_operand): Don't
+ check 24bit operands for overflow.
+ (check_operand): Likewise.
+
+Mon Dec 16 11:50:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo (Section): Document how to use the .section
+ pseudo-op for COFF and ELF.
+
+Sun Dec 15 15:26:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Fix linkonce check for ELF.
+
+Sat Dec 14 22:37:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (prev_insn_reloc_type): New static variable.
+ (RELAX_MIPS16_ENCODE): Add dslot and jal_dslot arguments, and
+ store them. Adjust other RELAX_MIPS16 macros.
+ (RELAX_MIPS16_DSLOT): Define.
+ (RELAX_MIPS16_JAL_DSLOT): Define.
+ (append_insn): Pass new arguments to RELAX_MIPS16_ENCODE. Correct
+ handling of whether previous instruction has a fixup. Set
+ prev_insn_reloc_type.
+ (mips_no_prev_insn): Clear prev_insn_reloc_type.
+ (mips16_extended_frag): Use the right base address for a PC
+ relative add or load.
+ (md_convert_frag): Likewise. If a PC relative add or load is
+ used, record the alignment for the section.
+
+Fri Dec 13 13:00:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Don't reduce a reloc against a
+ linkonce section into a reloc against the section symbol.
+
+ * config/tc-mips.c (mips16_macro): Remove nop instructions after
+ branch instructions.
+
+ * config/tc-mips.c (md_begin): If configured for an embedded ELF
+ system, don't set the section alignment to 2**4.
+ (s_change_sec): Likewise.
+ (append_insn): Call record_alignment for the section.
+ (md_section_align): Don't align the section size for an embedded
+ ELF system.
+
+Thu Dec 12 16:40:47 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Make sure that symbols are
+ resolved; expression symbols may have been skipped.
+ * config/obj-coff.c (fixup_segment): Likewise.
+
+Thu Dec 12 15:18:21 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Move @plt to
+ BFD_RELOC_24_PLT_PCREL relocation.
+ (md_apply_fix3): Support BFD_RELOC_24_PLT_PCREL.
+
+Tue Dec 10 13:51:55 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (write_2_short): Remove code that called
+ parallel_ok() when the programmer specified parallel instructions.
+
+Tue Dec 10 12:23:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Update to handle endianness
+ issues correctly.
+
+ * config/tc-mn10200.c (md_assemble): Opcode 0x0 is valid!
+ * config/tc-mn10300.c (md_assemble): Likewise.
+
+Tue Dec 10 11:37:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Make sure there is enough room
+ in a frag after a mips16 instruction to switch it with a jump
+ instruction.
+
+ * config/tc-mips.c (mips16_extended_frag): Give an error for an
+ attempt to use a non absolute symbol in an extending frag.
+
+Mon Dec 9 16:48:20 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10200.c: Flesh out assembler support for MN10200.
+ * config/tc-mn10200.h: Likewise.
+
+Mon Dec 9 17:09:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): At the end of a C comment, pass space to
+ UNGET rather than PUT. Set old_state before setting state to -2.
+
+ * config/tc-mips.c (mips16_extended_frag): Avoid an infinite loop
+ when extending because the value is exactly maxtiny + 1.
+
+ * config/tc-mips.c (RELAX_MIPS16_ENCODE): Add small and ext
+ arguments, and store them. Adjust other RELAX_MIPS16 macros.
+ (RELAX_MIPS16_USER_SMALL): Define.
+ (RELAX_MIPS16_USER_EXT): Define.
+ (mips16_small, mips16_ext): New static variables.
+ (append_insn): Pass mips16_small and mips16_ext to
+ RELAX_MIPS16_ENCODE.
+ (mips16_ip): Set mips16_small and mips16_ext.
+ (mips16_immed): Don't check mips16_autoextend.
+ (mips16_extended_frag): Check USER_SMALL and USER_EXT.
+
+ * write.c (write_relocs): Print an error for an out of range
+ fixup, rather than calling abort.
+
+ * as.c (main): Unlink the output file if there are errors while
+ generating the fixups.
+
+Fri Dec 6 18:48:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips16_extended_frag): Don't call
+ S_GET_VALUE.
+ (md_convert_frag): Call resolve_symbol_value before calling
+ S_GET_VALUE, and don't add in the frag address.
+
+ * config/tc-mips.c (mips16_immed): Add file and line parameters,
+ and use them when reporting errors. Change all callers.
+
+Fri Dec 6 15:36:32 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c: Fix various gcc -Wall warnings.
+ Remove '$' prefixing for registers.
+
+Fri Dec 6 00:55:48 1996 Martin <hunt@cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Check to see if prev_seg
+ is initialized before using it.
+ (d10v_cleanup): No longer uses its argument, so make it void.
+
+ * config/tc-d10v.h (d10v_cleanup): Change prototype.
+
+Thu Dec 5 11:03:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (fixup_segment): Don't discard the symbol for a PC
+ relative fixup to an absolute symbol.
+
+Wed Dec 4 15:42:41 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_assemble, d10v_cleanup): Fix bug
+ with multiple sections.
+
+Wed Dec 4 13:00:07 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_longopts): Rename mips-16 to mips16, and
+ no-mips-16 to no-mips16.
+ (s_mipsset): Accept .set mips16 and .set nomips16.
+
+Wed Dec 4 10:35:33 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Take expressionS pointer
+ argument, and check for +/- constant following the suffix, folding
+ it into the expression.
+ (ppc_elf_cons): Change ppc_elf_suffix calls.
+ (md_assemble): Ditto.
+ (shlib): Replace boolean mrelocatable with enumeration shlib.
+ (md_parse_option): Discriminate between PIC style shared libraries
+ and -mrelocatable.
+ (ppc_elf_validate_fix): Don't report warnings for PIC style shared
+ libraries.
+
+Tue Dec 3 23:18:29 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.h ({tc,ppc}_comment_chars): Define, so that we can
+ change the comment characters.
+
+ * config/tc-ppc.c (comment_chars): Delete in favor of
+ tc_comment_chars.
+ (ppc_{eabi,solaris}_comment_chars): Eabi and Solaris versions of
+ comment chars.
+ (ppc_comment_chars): Select appropriate comment chars by default.
+ (msolaris): New flag for -m{,no-}solaris.
+ (md_parse_option): Recognize -K pic. Add support for
+ -m{,no-}solaris.
+ (md_show_usage): Update.
+ (md_begin): Do not set ELF flags if Solaris.
+ (ppc_elf_suffix): @local sets R_PPC_LOCAL24PC relocation.
+ (md_apply_fix3): Add support for R_PPC_LOCAL24PC.
+
+Mon Dec 2 13:48:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (main): Correct handling of flag_always_generate_output.
+
+Sun Dec 1 21:46:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (tc_gen_reloc): Get the addend from
+ fx_offset, not fx_addnumber.
+
+ * config/tc-mn10300.h (tc_fix_adjustable): Don't do any
+ reloc adjustments.
+
+Sat Nov 30 17:34:48 1996 Eliot Dresselhaus <eliot@wally.edc.com>
+
+ * config/tc-i386.c: Correct misspelling: balenced to balanced.
+
+Wed Nov 27 13:25:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_section_align): Check for an alignment of
+ 4, not an alignment of 16. Corrects August 7 patch.
+
+Tue Nov 26 10:33:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, conf.in: Rebuild with autoconf 2.12.
+
+ * config/tc-ppc.c (ppc_elf_lcomm): Don't give an error if no
+ alignment is specified.
+
+ Add support for mips16 (16 bit MIPS implementation):
+ * config/tc-mips.c: Extensive additions for mips16 support, not
+ listed here.
+ (RELAX_OLD, RELAX_NEW): Use only 7 bits each.
+ (insn_uses_reg): Change last parameter to an enum.
+ * config/tc-mips.h (LOCAL_LABELS_DOLLAR): Define as 0.
+ (md_relax_frag): Define as mips_relax_frag.
+ (mips_relax_frag): Declare.
+ (struct mips_cl_insn): Add use_extend and extend fields.
+ (tc_fix_adjustable): Define.
+ * config/obj-elf.h (S_GET_OTHER): Define.
+ (S_SET_OTHER): Define.
+
+Mon Nov 25 18:02:29 1996 J.T. Conklin <jtc@beauty.cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Implement cases for new <, >, m, n,
+ o and p operand specifiers.
+
+Mon Nov 25 10:45:14 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * write.c: Delete "ifndef md_relax_frag" around is_dnrange.
+ (relax_segment, case rs_org): Move code inside braces. Move locals
+ target,after inside too.
+ (relax_segment, case rs_machine_dependent): Guts moved to ...
+ (relax_frag): New function.
+ Call md_prepare_relax_scan if defined.
+ * config/tc-m68k.h (md_prepare_relax_scan): Renamed from
+ M68K_AIM_KLUDGE.
+
+Mon Nov 25 08:49:36 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (address_registers): Use '$' as register
+ prefix instead of '%'.
+ (data_registers, other_registers, md_assemble): Likewise.
+
+ * config/tc-mn10300.c (address_registers): Use '%' prefix for regs.
+ (data_registers, other_registers, md_assemble): Likewise.
+
+ * config/tc-mn10300.c (md_assemble): Correctly determine the
+ correct location and type for each relocation.
+ (md_pcrel_from): Simplify.
+
+Fri Nov 22 15:42:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (md_convert_frag): Improve warning when branch is
+ converted into branch around branch.
+
+Thu Nov 21 11:56:11 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.h (DIFF_EXPR_OK): Don't define this.
+ (tc_fix_adjustable): Don't adjust relocs against weak symbols or
+ pc-relative relocs.
+ * config/tc-mn10300.c (md_begin): Set linkrelax.
+ (md_assemble): Create fixups as needed.
+ (md_apply_fix3): Gut. It shouldn't ever get called anymore.
+
+Tue Nov 19 17:48:06 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): When automatically converting
+ serial ops to parallel, do not consider a branch as the first
+ instruction.
+
+Tue Nov 19 13:35:22 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Handle MN10300_OPERAND_REG_LIST.
+
+Mon Nov 18 15:26:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Provide prototype
+ via PARAMS.
+ (check_operand): Likewise.
+
+Mon Nov 18 15:22:28 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Branch and link instructions
+ modify r13.
+ (write_2_short): Call parallel_ok to check whether two short
+ instructions the user requested execute in parallel, can be
+ executed that way.
+
+Thu Nov 14 11:17:49 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (write_2_short): Fix bug that wouldn't
+ allow a branch and link in parallel with an exe instruction.
+
+Fri Nov 8 13:55:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * doc/c-d10v.texi: Add info on @word modifier.
+
+Wed Nov 6 13:46:07 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): MN10300_OPERAND_SPLIT
+ operands are assumed to be 32bits. Use "bits" field to hold the
+ number of bits in the main instruction word for MN10300_OPERAND_SPLIT.
+ (mn10300_check_operand): MN10300_OPERAND_SPLIT operands are assumed
+ to be 32bits.
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Shift low part
+ of a MN10300_OPERAND_SPLIT operand by operand->shift.
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Handle
+ MN10300_OPERAND_SPLIT.
+
+Tue Nov 5 13:30:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Insert operands into
+ the extension part of the instruction if necessary.
+ (mn10300_insert_operand): Accept pointer to extension word
+ argument. Make insn a pointer argument too. Return type
+ is now void. All callers changed.
+
+Mon Nov 4 12:53:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (mn10300_insert_operand): Handle
+ repeated register operands.
+
+Fri Nov 1 10:42:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/as.texinfo: Added section on reporting bugs.
+
+ * config/tc-alpha.c: Change uses of void * to PTR. Change the
+ alpha_macro emit field to expect a const argument, and change the
+ arg field to be const. Fix some spacing to follow the GNU
+ standard.
+
+Fri Nov 1 10:32:03 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c (md_parse_option): Add knowledge of 21164pc
+ (pca56) and 21264 (ev6) cpus.
+ (md_apply_fix): Private relocation types are now negative.
+ (alpha_force_relocation): Likewise.
+ (tc_gen_reloc): Likewise.
+ (emit_insn): Likewise.
+ (emit_ldXu): Do the right thing when the hardware can do byte insns.
+ (emit_stX): Likewise.
+ (emit_sextX): Likewise.
+
+Thu Oct 31 16:33:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (do_relocs_for): Call resolve_symbol_value on
+ a symbol found in a reloc.
+
+ * symbols.c (resolve_symbol_value): Improve the error message if
+ an undefined symbol is used in an expression.
+
+Wed Oct 30 20:15:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * doc/internals.texi: Rewrite, and add a lot of documentation.
+ * doc/Makefile.in (internals.info): New target.
+
+Wed Oct 30 14:55:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.h (tc_fix_adjustable): Don't adjust relocs
+ against weak symbols.
+
+Tue Oct 29 12:28:16 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Don't lose for relaxable
+ addresses like .+6.
+
+ * config/tc-v850.c (md_convert_frag): Make sure we insert the
+ fixup at the right address within the frag.
+
+ * config/tc-v850.c (md_convert_frag): Don't set fragP->fr_fix
+ to an absolute value, instead increment it as needed.
+
+ * config/tc-v850.h (TC_GENERIC_RELAX_TABLE): Define.
+ * config/tc-v850.c: Fix some indention problems.
+ (md_relax_table): Define for D9->D99 branch displacement
+ relaxing.
+ (md_convert_frag): Do something useful instead of aborting.
+ (md_estimate_size_before_relax): Likewise.
+ (md_assemble): Note if the matching instruction has a relaxable
+ operand. If it does, allocate frag with frag_var and don't
+ do any fixups.
+
+Mon Oct 28 10:48:40 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.h (md_cleanup): New function. This is needed to
+ write out any buffered instructions when a ".end" is found.
+
+Mon Oct 28 10:43:45 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * read.c (read_a_source_file): New hook md_cleanup().
+
+Fri Oct 25 00:01:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (fix_new_exp): Use make_expr_symbol to build an
+ expression symbol for a complex fixup.
+
+Thu Oct 24 14:31:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (v850_reloc_prefix): Several disgusting
+ hacks to improve parsing of complex hi, lo, zda, etc
+ expressions.
+ (md_assemble): Don't demand and eat a trailing ')' after finding
+ a v850 relocation prefix. Sign extend the constant in a
+ BFD_RELOC_LO16 expression. Do eat a trailing ')' after a complete
+ operand.
+ (parse_cons_expression_v850): Don't eat a trailing ')' after
+ finding a v850 relocation prefix.
+
+ * config/tc-v850.h (TC_PARSE_CONS_EXPRESSION): Define.
+ (TC_CONS_FIX_NEW): Likewise.
+ * config/tc-v850.c (parse_cons_expression_v850): New function.
+ (cons_fix_new_v850): Likewise.
+
+ * config/tc-v850.h (tc_fix_adjustable): Don't adjust TDA relocs.
+
+Wed Oct 23 18:20:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Give a better warning message
+ for an unknown relocation type.
+
+Wed Oct 23 16:21:28 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_pseudo_table): Add .word; allocates
+ 4 bytes of space.
+
+Tue Oct 22 22:01:25 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Handle TDAOFF relocs
+ differently for movea & sst/sld insns.
+
+Tue Oct 22 17:09:32 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Don't allow illegal combinations
+ of instructions.
+
+Tue Oct 22 11:28:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * obj.h (struct format_ops): Add frob_file_after_relocs field.
+ * config/obj-multi.h (obj_frob_file_after_relocs): Define.
+ * config/obj-ecoff.c (ecoff_format_ops): Initialize new
+ frob_file_after_relocs field.
+ * config/obj-elf.c (elf_format_ops): Likewise.
+ * config/tc-mips.c: Undefine obj_frob_file_after_relocs before
+ including obj-elf.h.
+
+Mon Oct 21 11:38:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (cons_fix_new_mips): Only treat 8 byte reloc
+ specially if not ELF.
+ (md_apply_fix): Handle BFD_RELOC_64.
+ (tc_gen_reloc): Handle BFD_RELOC_64.
+
+ * config/tc-i386.c (md_apply_fix3): Don't increment value for a PC
+ relative reloc when BFD_ASSEMBLER and OBJ_AOUT (more ugly gas
+ reloc hacking).
+
+ * config/obj-aout.h (S_IS_DEFINE): non BFD_ASSEMBLER version:
+ Don't check S_GET_OTHER.
+
+Fri Oct 18 14:06:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Accept an odd floating point
+ register with l.s or s.s.
+
+ * config/obj-aout.c (obj_pseudo_table): Use obj_aout_type for
+ .type pseudo-op.
+ (obj_aout_type): New static function.
+
+Thu Oct 17 17:55:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(OBJS)): Depend upon libiberty.h.
+
+Wed Oct 16 11:28:31 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (v850_reloc_prefix): Recognize zdaoff, tdaoff
+ and sdaoff expressions.
+
+ * write.c (fixup_segment): Don't add symbol value to addend if
+ TC_V850 and OBJ_ELF.
+ * config/tc-v850.h (tc_fix_adjustable): Don't adjust any
+ pc-relative fixups.
+
+ * config/tc-v850.c (md_pcrel_from): Undo yesterday's changes.
+ (md_pcrel_from_section): Likewise.
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Likewise.
+
+Tue Oct 15 23:19:00 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_pcrel_from): Delete unused function.
+ (md_pcrel_from_section): New function.
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Define.
+
+Mon Oct 14 13:59:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Add cast to offsetT when using
+ a constant with &~.
+
+Mon Oct 14 11:24:28 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/obj-elf.c (elf_frob_file): Move ECOFF debug processing to ...
+ (elf_frob_file_after_relocs): ... here. New function.
+ * config/obj-elf.h (obj_from_file_after_relocs): New macro.
+ * write.c (write_object_file): Call *frob_after_relocs after the
+ call to write_relocs.
+
+ * config/tc-alpha.c: Use new BFD_RELOC_ALPHA_ELF_LITERAL reloc.
+
+ * config/tc-alpha.c (load_expression): Don't SET_VALUE on the section
+ symbol, as this messes up linking. Instead, expand the recursive call
+ inline and change up the appropriate bits to get the 0x8000 offset
+ in the reloc addend.
+
+Thu Oct 10 17:30:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.h (tc_fix_adjustable): Permit the difference of
+ two symbols in the same segment to be adjusted.
+
+ * configure.in: Don't get confused by CPU-VENDOR-linux-gnu.
+ * configure: Rebuild.
+
+Thu Oct 10 17:22:18 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_insert_operand): Change most warnings into
+ errors.
+ (ppc_elf_validate_fix): Ditto.
+ (md_assemble): Ditto.
+ (ppc_tc): Ditto.
+ (ppc_pe_section): Ditto.
+ (ppc_frob_symbol): Ditto.
+
+Thu Oct 10 12:05:45 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/mn10300.c (md_assemble): Pass an extra shift count
+ to mn10300_insert_operand based on the opcode format.
+ (mn10300_insert_operand): Accept and use extra shift count
+ parameter.
+
+ * config/tc-mn10300.c (md_assemble): Use FMT_* macros for
+ formats rather than hard-coded constants.
+
+ * config/tc-mn10300.c (md_assemble): Format D5 instructions
+ are 7 bytes long. Write out instructions in big-endian format.
+
+Tue Oct 8 14:56:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.c (md_assemble): Tweak further so
+ that all instructions are parsed correctly.
+
+Tue Oct 8 13:02:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h: Include libiberty.h.
+ (xmalloc, xrealloc): Don't declare.
+ * as.c: Don't include libiberty.h.
+ * expr.c, read.c, stabs.c, config/obj-coff.c: Likewise.
+ * config/tc-mips.c: Likewise.
+ * messages.c: Likewise.
+ (xstrerror): Don't declare.
+ * xmalloc.c: Remove.
+
+Mon Oct 7 16:53:23 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10300.h (pre_defined_registers) Remove.
+ (system_registers, cc_names): Likewise.
+ (address_registers, data_registers, other_registers): New register
+ arrays.
+ (register_name, system_register_name, cc_name): Remove.
+ (mn10300_reloc_prefix): Likewise.
+ (data_register_name): New function.
+ (address_register_name, other_register_name): Likewise.
+ (md_assemble): Rough cut at parsing operands. Remove lots of
+ unwanted code.
+ (md_apply_fix3): Disable for now.
+
+Mon Oct 7 11:38:34 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (select_control_regs): New function, extracted
+ out of m68k_init_after_args.
+ (m68k_init_after_args): Use it.
+ (mri_chip): Use it here as well to update set of allowed control
+ regs for movec.
+
+Mon Oct 7 11:24:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (elf_begin): New function.
+ (obj_elf_section): Add the section symbol to the symbol table.
+ * config/obj-elf.h (obj_begin): Define.
+ (elf_begin): Declare.
+ * as.c (perform_an_assembly_pass): Call obj_begin if it is
+ defined.
+
+Fri Oct 4 18:37:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Subtract the section address
+ from a PC relative reloc if TC_M68K.
+
+Thu Oct 3 15:15:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_pseudo_table): Make .uahalf, .uaword, and
+ .uaxword available even if not OBJ_ELF.
+ (md_atof): Remove unused local variable wordP.
+
+Thu Oct 3 00:16:50 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-mn10x00.c, config/tc-mn10x00.h: New files
+ for Matsushita MN10x00 support.
+ * configure.in: Recognize mn10x00-*-*
+ * configure: Rebuilt.
+
+Wed Oct 2 15:54:03 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * obj-evax.h: move openvms definitions from here to tc-alpha.c.
+ * tc-alpha.c: add support for vms_case_hack like in vax/vms.
+ (load_expression): track clobbering of base reg before jmp/jsr.
+ (s_alpha_file): pass case_hack flags and source filename via
+ symbol table to bfd.
+ * tc-alpha.h (TC_CONS_FIX_NEW): define
+
+Tue Oct 1 16:16:01 1996 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.in (mips-*-rtems*): New target, like mips-*-elf*.
+ * configure: Rebuild.
+
+Tue Oct 1 12:37:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_macro): Warn if a macro has the same name as a
+ pseudo-op.
+ (s_space): In m68k MRI mode, align to a word boundary.
+ * macro.c (define_macro): Add namep parameter. Change all
+ callers.
+ * macro.h (define_macro): Update declaration.
+
+ * as.c (show_usage): Print bug report address.
+ (parse_args): Change version printing to match current GNU
+ standards.
+ * gasp.c (show_usage): Print bug report address.
+ (main): Change version printing to match current GNU standards.
+
+ * config/tc-m68k.c (init_table): Correct access control unit
+ register numbers. From Ken Rose <rose@netcom.com>.
+
+ * config/tc-alpha.c: Add some static function prototypes.
+ (alpha_macros): Move to top of file. Make static.
+ (alpha_num_macros): Move to top of file.
+
+Tue Oct 1 09:36:19 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * tc-v850.h: Define LOCAL_LABEL to recognise _.L_* symbols
+ generated by DWARF.
+
+Sat Sep 28 03:38:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (list_symbol_table): Remove bogus code in BFD64 case,
+ and just call sprintf_vma.
+
+Thu Sep 26 16:04:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (expr): Change >>= to >> (fix typo). (From meissner).
+
+Tue Sep 24 19:05:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (float_cons): Call md_flush_pending_output if it is
+ defined.
+
+Tue Sep 24 12:22:18 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_operand): Created. Allows operands to
+ start with '#'.
+ * config/tc-d10v.h (md_operand): Undefined.
+
+Mon Sep 23 12:13:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (add_fix): Treat a width of '3' like 'B'.
+ (md_assemble): A fixup width of '3' means a 1 byte reloc.
+
+Thu Sep 19 12:21:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Don't adjust PC relative
+ reloc for the i960 for a reloc in the same section. This undoes
+ one of the two changes made Aug 19.
+
+Wed Sep 18 12:11:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (obj_coff_endef): Both versions: Move C_STAT
+ symbols to the position of the debugging information.
+
+Mon Sep 16 11:41:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (expr): Always use unsigned right shifts for >>.
+
+Thu Sep 12 10:25:45 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-arm.c (md_apply_fix3): Update two thumb instruction
+ slots when processing BL fixups.
+
+ * config/tc-arm.c (output_inst): Ensure Thumb BL fixup is marked
+ on the first half of the instruction.
+
+Wed Sep 11 00:09:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_stab): Create an expression symbol for a complex
+ stabs expression, rather than giving an error.
+
+ * ecoff.c (ecoff_new_file): Don't do anything if we are still in
+ the same file.
+
+Tue Sep 10 11:45:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Fill in the value for a constant
+ jump, rather than creating a reloc.
+
+Mon Sep 9 10:57:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (append_insn): Don't swap an instruction which
+ sets a condition code with an instruction which uses a condition
+ code.
+ (mips_ip): In cases 'N' and 'M', look for $fccN rather than an
+ immediate value.
+
+ * config/tc-mips.c (md_begin): Recognize r5000 for cpu.
+ (mips_ip): Give a better error message if the ISA level is wrong.
+ (md_parse_option): Recognize -mcpu=[v][r]5000.
+
+Sat Sep 7 13:25:55 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (COUNT_TOP_ZEROES): Added macro to count
+ leading zeroes.
+ (load_register): Ensure hi32 bits are not lost during lo32bit
+ processing. Fix shift offset that was overflowing into the next
+ instruction field. Add code to generate shorter sequences for
+ constants with a single contiguous seqeuence of ones.
+
+Fri Sep 6 17:07:12 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (d10v_dot_word): New function to support
+ "@word" with the word pseudo-op.
+ (md_apply_fix3): Cleanup and changes to support correct sizes
+ for 16 and 18-bit relocs.
+
+Fri Sep 6 16:00:29 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc-*-aout): Set `em'.
+ * configure: Regenerated.
+ * config/te-sparcaout.h: New file.
+ * config/tc-sparc.h (TARGET_BYTES_BIG_ENDIAN): Define.
+ Ifdef TE_SPARCOUT define TARGET_FORMAT and SPARC_BIENDIAN.
+ * config/tc-sparc.c (INSN_BIG_ENDIAN): New macro.
+ (SPECIAL_CASE_{SETSW,SETX}): Define.
+ ({NOP,OR,FMOVS,SETHI,SLLX,SRA}_INSN): Define.
+ (md_begin): Delete setting of `target_big_endian'.
+ (output_insn): New function.
+ (md_assemble): Rewrite. Add `setx' support.
+ (sparc_ip): Handle `0' operand char. Recognize setuw, setsw, setx
+ special cases.
+ (md_atof): Add little endian support.
+ (md_number_to_chars): Likewise.
+ (md_apply_fix): Likewise.
+ (md_longopts): Recognize -EL,-EB ifdef SPARC_BIENDIAN.
+ (md_parse_option): Likewise.
+ (md_show_usage): Print -EL, -EB ifdef SPARC_BIENDIAN.
+
+Thu Sep 5 13:40:29 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_new_file): New function.
+ * ecoff.h (ecoff_new_file): Declare.
+ * config/obj-ecoff.h (obj_app_file): Define.
+
+Thu Sep 5 13:39:25 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c (load_expression): Bias the .lit8 section
+ symbol by 32k so that our 16-bit signed offset can address the
+ entire chunk. Reported by <matt@lkg.dec.com>.
+
+Wed Sep 4 10:23:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (load_register): Remove unused variable tmp.
+
+Wed Sep 4 11:24:29 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (load_register): Remove unnecessary code that
+ was causing the high 32bits of 64bit constants to be lost.
+
+Tue Sep 3 13:52:56 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Added changes to support function
+ pointers and "@word" syntax.
+
+Tue Sep 3 11:57:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c: Remove commented out and #if 0'd code.
+ (v850_reloc_prefix): Provide prototype.
+ (postfix, get_reloc, build_insn): Remove prototypes for nonexistant
+ functions.
+ (md_begin, md_assemble, md_apply_fix3): Remove unused variables.
+ (md_assemble): Add default to case statement.
+
+Sat Aug 31 16:03:00 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Compute size of the instrction
+ from the opcode.
+
+ * config/tc-v850.c (md_apply_fix3): Do simple byte, short and
+ word fixups too.
+
+Fri Aug 30 23:50:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_apply_fix3): Use little endian get/put
+ routines to fetch/store the updated instruction from/to memory.
+ (v850_insert_operand): If the operand has a specialized insert
+ routine, call it.
+
+Fri Aug 30 18:35:26 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * config/tc-v850.c (reg_name_search): Align calling convention to
+ be like identical function found in tc-ppc.c.
+ (get_reloc): Removed.
+ (v850_reloc_prefix): New function, parse lo(), hi() and hi0().
+ (md_assemble): emit fixups.
+ (md_pcrel_from): renamed from md_pcrel_from_section, emit proper
+ displacement.
+ (md_apply_fix3): handle fixups/relocs.
+ * config/tc-v850.h (MD_PCREL_FROM_SECTION): Removed definition.
+
+Fri Aug 30 18:12:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Add SH ELF support.
+ * configure.in (sh-*-elf*): New target.
+ * config/tc-sh.h (TARGET_ARCH): Define.
+ (WORKING_DOT_WORD): Define.
+ (TC_COFF_FIX2RTYPE): Only define if OBJ_COFF.
+ (BFD_ARCH, COFF_MAGIC, TC_COUNT_RELOC): Likewise.
+ (TC_RELOC_MANGLE, tc_coff_symbol_emit_hook): Likewise.
+ (DO_NOT_STRIP, NEED_FX_R_TYPE, TC_KEEP_FX_OFFSET): Likewise.
+ (TC_COFF_SIZEMACHDEP, tc_frob_file): Likewise.
+ (SUB_SEGMENT_ALIGN): Likewise.
+ (RELOC_32): Don't define.
+ (tc_frob_file_before_adjust): Define if BFD_ASSEMBLER.
+ (target_big_endian): Declare if OBJ_ELF.
+ (TARGET_FORMAT): Define if OBJ_ELF.
+ * config/tc-sh.c: Use BFD reloc codes instead of SH COFF reloc
+ numbers throughout.
+ (tc_crawl_symbol_chain): Only define if OBJ_COFF.
+ (tc_headers_hook, tc_coff_sizemachdep): Likewise.
+ (struct sh_count_relocs): Define.
+ (sh_count_relocs): New static function, broken out of
+ sh_frob_file. Add BFD_ASSEMBLER code.
+ (sh_frob_section): Likewise.
+ (sh_frob_file): Call sh_frob_section.
+ (md_convert_frag): If BFD_ASSEMBLER, change type of headers, and
+ call section_symbol rather than seg_info (seg)->dot.
+ (md_section_align): Add OBJ_ELF version.
+ (SWITCH_TABLE_CONS): Define.
+ (SWITCH_TABLE): Use SWITCH_TABLE_CONS.
+ (md_apply_fix): Change parameter types if BFD_ASSEMBLER. Only
+ handle fx_r_type == 0 if not BFD_ASSEMBLER. Return 0 if
+ BFD_ASSEMBLER.
+ (struct reloc_map): Define if not BFD_ASSEMBLER.
+ (coff_reloc_map): Likewise.
+ (sh_coff_reloc_mangle): Use coff_reloc_map to convert fx_r_type.
+ (tc_gen_reloc): New function if BFD_ASSEMBLER.
+ * write.c (write_relocs): Ifdef out fx_where test which triggers
+ inappropriately for SH ELF.
+ (write_object_file): Call tc_frob_file_before_adjust and
+ obj_frob_file_before_adjust if they are defined.
+
+ * write.c (write_object_file): Use BFD_RELOC_16, not
+ BFD_RELOC_NONE, when calling fix_new_exp for a broken word.
+
+ * read.c (emit_expr): Fix conversion of byte count to BFD reloc
+ code.
+
+Fri Aug 30 14:47:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Fix problem with calculating
+ branch sizes in across sections.
+
+Fri Aug 30 00:44:13 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-850.c (md_assemble): Handle hi() correctly. Handle
+ hi0() too.
+
+Wed Aug 28 23:11:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_begin): Deal with end of opcode
+ table marker.
+
+Wed Aug 28 19:20:04 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (find_opcode): Fix a bug which could generate
+ the wrong opcode for cases like st2w where there are many forms
+ of the same instruction.
+
+Tue Aug 27 13:53:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * expr.c (operand): If md_parse_name is defined, call it before
+ calling symbol_find_or_make.
+ * config/tc-ppc.h (md_parse_name): Define.
+ (ppc_parse_name): Declare.
+ * config/tc-ppc.c (reg_name_search): Add regs and regcount
+ parameters.
+ (register_name): Update call to reg_name_search.
+ (cr_operand): New static variable.
+ (cr_names): New static const array.
+ (ppc_parse_name): New function.
+ (md_assemble): If PPC_OPERAND_CR is set in the operand flags, set
+ cr_operand before calling expression.
+
+Tue Aug 27 09:05:50 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (tc_gen_reloc): Add new argument to
+ hppa_gen_reloc_type call.
+
+Mon Aug 26 18:24:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fixed ".word". Fixed problem with range checking
+ on addresses. Improved error messages.
+ * doc/c-d10v.texi: Added docs for register pairs.
+
+Mon Aug 26 13:39:27 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (parallel_ok): Fix bug in parallel
+ checking code.
+
+Mon Aug 26 14:38:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (init_file): Initialize fMerge to 1.
+ (add_file): Restore old file merging code, but only merge files if
+ fMerge is set.
+ (ecoff_directive_loc): Clear fMerge field of current file.
+ (ecoff_generate_asm_lineno): Likewise.
+
+Fri Aug 23 11:40:47 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * doc/c-d10v.texi: Fix typo.
+
+Fri Aug 23 10:41:32 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-v850.c (md_assemble): Correct bit masking for
+ hi and lo expressions.
+
+ * config/tc-v850.c (md_assemble): Rough cut at demanding
+ "ep" or "r30" in sst and sld instructions.
+ (md_apply_fix3): Don't abort. Just warn that we don't
+ have relocs yet.
+
+ * config/tc-v850.c (CC_NAME_CNT): Define.
+ (cc_name): New function.
+ (md_assemble): Handle V850_OPERAND_CC correctly.
+
+ * config/tc-v850.c (md_assemble): Don't forget to initialize
+ "insn"!
+
+ * config/tc-v850.c (reg_name_search): Generalize to search
+ any given register table.
+ (register_name): Pass appropriate table and size to reg_name_search.
+ (system_register_name): New function.
+ (SYSREG_NAME_CNT): Define.
+ (md_assemble): Handle operands which are system registers.
+
+ * config/tc-v850.c (md_assemble): If we find a register, but the
+ opcode doesn't want a register, then we don't have a match.
+ (md_assemble): Get size of the instruction from the opcode table.
+
+Thu Aug 22 10:20:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set and substitute HLDENV.
+ * configure: Rebuild.
+ * Makefile.in (HLDENV): New variable.
+ (as.new): Use $(HLDENV).
+
+ * ecoff.c (ecoff_directive_endef): Avoid a division by zero error
+ if an array dimension is not known.
+
+Thu Aug 22 10:50:00 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fix a reloc bug caused by my last change.
+ * doc/c-d10v.texi: Cleanup.
+
+Tue Aug 20 15:15:16 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * config/tc-v850.c: New file.
+ * config/tc-v850.h: New file.
+ * configure (v850-*-elf): New target.
+ * configure.in (v850-*-elf): New target.
+
+Wed Aug 21 15:50:54 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * doc/c-d10v.texi: New file.
+ * doc/all.texi: Added D10V stuff.
+ * doc/as.texinfo: Added D10V stuff.
+
+Tue Aug 20 14:10:02 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: All references to defined symbols should
+ now use the optimal instruction. .float and .double now work.
+
+Mon Aug 19 14:41:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (fixup_segment): Adjust PC relative reloc by
+ section address for the i960 as is done for the i386.
+
+Thu Aug 15 16:37:59 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add wildcards for config matching, add mips-*-*
+ case, forward-include bfd/elf-bfd.h.
+
+Thu Aug 15 13:24:30 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Add additional information to the opcode
+ table to help determinine which instructions can be done
+ in parallel.
+
+Thu Aug 15 17:01:31 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-arm.c: Major changes to add Thumb support, with lots
+ of change input from <rearnsha@armltd.co.uk>.
+ Reverted to INSN_SIZE macro, rather than insn_size variable.
+ (insns): Added ARM "bx" instruction support.
+ (tinsns): Added Thumb instruction definition structure.
+ (arm_tops_hsh): Added hash structure for Thumb opcodes.
+ (md_pseudo_table): Added ".arm", ".thumb" and ".code" pseudo-ops.
+ (opcode_select,s_arm,s_thumb,s_code): Added.
+ (decode_shift): Allow upper-case RRX.
+ (do_ldst): Simpler halfword support.
+ (do_ldmstm): Improved.
+ (reg_list, do_bx, thumb_reg, thumb_add_sub, thumb_shift,
+ thumb_mov_compare, thumb_load_store, do_t_arit, do_t_add,
+ do_t_asr, do_t_branch, do_t_bx, do_t_compare, do_t_ldmstm,
+ do_t_ldrb, do_t_ldrh, do_t_lds, do_t_lsl, do_t_lsr, do_t_mov,
+ do_t_push_pop, do_t_str, do_t_strb, do_t_strh, do_t_sub, do_t_swi,
+ do_t_adr): Added.
+ (md_apply_fix3): Add support for BFD_RELOC_ARM_THUMB_* relocations.
+ (md_parse_option): Add support for -mthumb.
+ (md_show_usage): Updated to reflect new command line option.
+ (arm_data_in_code, arm_canonicalize_symbol_name): Added.
+ * config/tc-arm.h: Provide TC_FIX_TYPE to allow private ARM
+ fragment information to be held.
+
+Thu Aug 15 16:12:00 1996 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * tc-arm.c (md_apply_fix3): Also set fixP->fx_done if fx_addsy is
+ non-null, but is a constant.
+ (fix_new_arm): Call make_expr_symbol to make the expression symbol
+ so that error reporting will work correctly.
+
+Wed Aug 14 10:37:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (tc_i386_fix_adjustable): Don't adjust relocs
+ against weak symbols.
+
+Tue Aug 13 17:39:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.h (TC_FORCE_RELOCTION): Define if OBJ_XCOFF.
+ (ppc_force_relocation): Declare if OBJ_XCOFF.
+ * config/tc-ppc.c (ppc_force_relocation): New function if
+ OBJ_XCOFF.
+
+Mon Aug 12 16:49:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.h (BYTE_ORDER): Don't define. No longer used.
+
+Fri Aug 9 17:48:28 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fix problem with relocs.
+
+Fri Aug 9 14:16:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_do_align): If not BFD_ASSEMBLER, always align
+ with nops if not in data_section or bss_section.
+
+Thu Aug 8 12:32:56 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ Add support for openVMS/Alpha.
+ * as.h (PRINTF_LIKE): Don't define if VMS, for now.
+ * config/obj-evax.c: New file.
+ * config/obj-evax.h: New file.
+ * config/tc-alpha.c: Add support for EVAX format if OBJ_EVAX is
+ defined.
+ * config/tc-alpha.h: Add support for EVAX format if OBJ_EVAX is
+ defined. Add case for bfd_target_evax_flavour.
+ * config/vms-a-conf.h: New file.
+ * conf-a-gas.com: New file.
+ * configure.in: Add target alpha-*-*vms*.
+ * configure: Rebuild.
+ * makefile.vms: New file.
+ * read.c (s_lcomm): Align bss_seg on 8 byte boundary if OBJ_EVAX.
+ Don't call ffs on openVMS/Alpha.
+
+Wed Aug 7 14:19:03 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * configure.in: Make GAS_CHECK_DECL_NEEDED include <string.h> or
+ <strings.h> if they exist. Call GAS_CHECK_DECL_NEEDED on strstr
+ and sbrk.
+ * acconfig.h (NEED_DECLARATION_STRSTR): New macro.
+ (NEED_DECLARATION_SBRK): New macro.
+ * configure, conf.in: Rebuild.
+ * as.h: Only include <strings.h> if HAVE_STRINGS_H.
+ (strstr): Declare if NEED_DECLARATION_STRSTR.
+ * as.c: If HAVE_SBRK and NEED_DECLARATION_SBRK, declare sbrk.
+
+Wed Aug 7 11:50:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): Handle addition or subtraction
+ by a constant before entering the main switch. Reject attempts to
+ apply an arithmetic function to non-absolute symbols, except for
+ the special case of subtraction of two symbols in the same
+ section.
+
+ * config/tc-mips.c (md_section_align): Do align if OBJ_ELF, but
+ not to more than a 16 byte boundary.
+
+ * config/tc-i386.c (tc_gen_reloc): Accept all relocs; remove
+ #ifndef OBJ_ELF lines. From Eric Valette <valette@crf.canon.fr>.
+ (tc_gen_reloc): If out of memory call as_fatal rather than
+ assert. If no howto found, call as_bad_where rather than
+ as_fatal. Change the error message slightly. Set howto to a
+ non-NULL value in order to keep going.
+
+Tue Aug 6 12:58:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Added code to support 32-bit fixups for stabs.
+
+Tue Aug 6 11:15:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (get_specific): New operand "size" derived
+ from ".b", ".w" and ".l" extensions. All callers changed. If
+ the base instruction has no operands, then use the size to
+ determine which specific instruction to use.
+
+Mon Aug 5 14:21:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (mem_fmt): Call parse_expr before emit.
+
+Fri Aug 2 11:23:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_section_align): Don't change addr if
+ OBJ_ELF.
+
+Thu Aug 1 23:51:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c: Revert yesterday's changes.
+
+Wed Jul 31 14:46:11 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Disable range checking on 16-bit values.
+
+Wed Jul 31 16:27:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Set ok_arch for every instruction,
+ not just the ones that don't match.
+
+Wed Jul 31 11:45:15 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fixed bugs in short relocs and range checking.
+
+Wed Jul 31 15:41:42 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-arm.c: Changed INSN_SIZE to variable insn_size, as
+ pre-cursor to adding Thumb support. Also added cpu_variant flag
+ information to each of the asm_flg structures.
+ (md_parse_option): Updated ARM7 parsing to allow 't' for
+ thumb/halfword support, aswell as 'm' for long multiply.
+ (md_show_usage): Updated help message.
+ (md_assemble): Check that instruction flags are applicated to the
+ current cpu variant.
+ (md_apply_fix3, tc_gen_reloc): Add BFD_RELOC_ARM_OFFSET_IMM8 and
+ BFD_RELOC_ARM_HWLITERAL relocation support for new halfword and
+ signextension instructions.
+ (do_ldst): Generate halfword and signextension variants if
+ mnemonic flags match.
+ (ldst_extend): Do not allow shifts in the offset field of halfword
+ or signextension instructions.
+ (validate_offset_imm): Provide check on halfword and signextension
+ immediate range.
+ (add_to_lit_pool): Merge identical literal pool values.
+
+Tue Jul 30 14:28:23 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (selector_table): Add 'E' selector.
+ (cons_fix_new_hppa): Don't coke on e_esel.
+ (tc_gen_reloc, SOM version): Handle R_COMP2 when used
+ to help generate exception handling tables.
+ (md_apply_fix): Don't try to apply fixups with an e_esel
+ selector.
+ (hppa_fix_adjustable): Fixups with e_esel selectors
+ are not adjustable.
+
+Tue Jul 30 15:51:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (md_pseudo_table): Add 2byte, 4byte, and 8byte
+ pseudo-ops.
+
+Fri Jul 26 11:43:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Added lots of error checking. Added hacks
+ to support accumulator shifts.
+
+Fri Jul 26 11:56:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (S_SET_EXTERNAL): Let .weak override.
+ (S_CLEAR_EXTERNAL): Likewise.
+ (S_SET_WEAK): Remove error; just let .weak override.
+
+Thu Jul 25 15:22:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_assemble): Now handles multiline
+ instructions.
+
+Thu Jul 25 12:03:33 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Fix packaging bug. Added range checking.
+ Added kludge for divs instruction. Fixed minor problem with
+ multiple text sections.
+ * config/tc-d10v.h (d10v_cleanup): Change prototype.
+
+Tue Jul 23 10:49:36 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c (md_apply_fix3): Fix all instruction
+ addresses to be right-shifted by 2.
+
+Mon Jul 22 11:32:36 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: Many changes to get relocs working.
+ (register_name): No longer creates a symbol for register names.
+ (pre_defined_registers): moved to opcodes/d10v-opc.c.
+ (d10v_insert_operand): Now works correctly for either container.
+ * config/tc-d10v.h (d10v_cleanup): Declare.
+
+Mon Jul 22 14:01:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (tc_gen_reloc): BFD_RELOC_PCREL_HI16_S and
+ BFD_RELOC_PCREL_LO16 are expected to be PC relative.
+
+Mon Jul 22 12:46:55 1996 Richard Henderson <rth@tamu.edu>
+
+ * tc-alpha.c: Patches to track current minimum alignment to reduce
+ the number of fragments created with frag_align.
+ (alpha_current_align): New static variable.
+ (s_alpha_text): Reset alignment to 0.
+ (s_alpha_data, s_alpha_rdata, s_alpha_sdata): Likewise.
+ (s_alpha_stringer, s_alpha_space): New functions.
+ (s_alpha_cons, alpha_flush_pending_output): Remove functions.
+ (alpha_cons_align): New function to replace both of them.
+ (emit_insn): Only align if alpha_current_align is less than 2;
+ reset alpha_current_align to 2.
+ (s_alpha_gprel32): Likewise.
+ (s_alpha_section): New function. Basically duplicate the other
+ alpha section change hooks. Only define for ELF.
+ (s_alpha_float_cons): Simplify alignment handling.
+ (md_pseudo_table): Only define "rdata" and "sdata" if OBJ_ECOFF.
+ If OBJ_ELF, define "section", "section.s", "sect", and "sect.s".
+ Don't define the s_alpha_cons pseudo-ops. Do define
+ s_alpha_stringer and s_alpha_space pseudo-ops.
+ (alpha_align): Skip if less than current default alignment. Set
+ default alignment.
+ * tc-alpha.h (md_flush_pending_output): Remove.
+ (md_cons_align): Add.
+
+ * tc-alpha.c: Add oodles of function description comments.
+ (md_bignum_to_chars): Remove; there are no callers.
+ (md_show_usage): Mention some more variants.
+
+Thu Jul 18 15:54:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Andrew Gierth <ANDREWG@microlise.co.uk>:
+ * configure.in (sparc-*-sysv4*): New target.
+ * configure: Rebuild.
+
+ * config/tc-sparc.c (md_pseudo_table): Change uahalf, uaword, and
+ uaxword to use s_uacons.
+ (sparc_no_align_cons): New static variable.
+ (s_uacons): New static function.
+ (sparc_cons_align): If sparc_no_align_cons is set, just clear it
+ and return.
+
+ * config/tc-sparc.c (s_common): Remove unused label allocate_bss.
+
+ * configure.in: Add mips-*-irix6* target. Handle Irix 6 like Irix
+ 5 with regard to shared libraries.
+ * configure: Rebuild.
+
+ * config/tc-m68k.c (m68k_ip): Use the correct length when
+ allocating space for the unsupported architecture error message.
+
+Thu Jul 18 12:57:10 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (d10v-*-*): Allow d10v-*-*, don't require d10v-*-elf*.
+
+Wed Jul 17 14:25:13 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * config/tc-d10v.c: New file.
+ * config/tc-d10v.h: New file.
+ * configure (d10v-*-elf): New target.
+ * configure.in (d10v-*-elf): New target.
+
+Fri Jul 12 20:54:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Recognize -K PIC.
+
+Wed Jul 10 12:39:08 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-alpha.c (alpha_align): Change fill parameter
+ to a pointer. Take NULL as 0 or nop depending on section. Change
+ all callers.
+ (s_alpha_align): Rename local variables.
+
+ * doc/as.texinfo (.align): Document action of omitted
+ fill parameter.
+
+Wed Jul 10 00:23:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): Give a useful error message
+ when an unsupported PC relative reloc is seen, rather than calling
+ abort.
+
+ * app.c (do_scrub_chars): Remove not_cpp_line local variable.
+ Instead, check state when '#' comment is seen.
+
+Mon Jul 8 14:11:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_regmask_frag): Only define if OBJ_ELF or
+ OBJ_MAYBE_ELF.
+ (tc_gen_reloc): If fixup was changed to be PC relative, change
+ reloc type accordingly. Use name of reloc in error message.
+
+ * as.h: Don't define const or volatile.
+ * flonum.h: Don't define const.
+
+ * config/tc-m68k.c (tc_gen_reloc): Change the code appropriately
+ if fx_pcrel is set. Correct setting the addend case in the
+ OBJ_ELF case (from Andreas Schwab
+ <schwab@issan.informatik.uni-dortmund.de>).
+ (md_show_usage): Correct -mfc5200 to -m5200.
+
+Fri Jul 5 10:32:58 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * doc/c-m68k.texi: Document -m5200 flag.
+ * doc/as.texinfo: Likewise.
+
+ * config/tc-m68k.c (m68k_ip): The coldfire does not support 8x
+ scale factor.
+
+Fri Jul 5 11:07:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (S_SET_EXTERNAL): Change as_warn to as_bad.
+ (S_CLEAR_EXTERNAL, S_SET_WEAK): Likewise.
+
+Thu Jul 4 11:59:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (VERSION): Set to cygnus-2.7.1.
+
+ * Released binutils 2.7.
+
+Thu Jul 4 10:11:33 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (mips_ip): Only perform range check when
+ dealing with O_constant expressions.
+
+Wed Jul 3 15:02:21 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * m68k-parse.h (m68k_register): Add new coldfile control
+ registers.
+
+ * config/tc-m68k.c (mcf5200_control_regs): New variable,
+ array of control registers for the coldfire.
+ (cpu_of_arch): Added mcf5200.
+ (archs): Added mcf5200.
+ (init_table): Add new control registers.
+ (m68k_ip): Added support for new control registers.
+ (m68k_init_after_args): Likewise.
+
+ * config/tc-m68k.c (md_show_usage): Add -m5200 to usage text.
+
+Wed Jul 3 16:05:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.h (is_it_end_of_statement): Declare.
+ * read.c (is_it_end_of_statement): Remove declaration.
+
+ * config/tc-ppc.c (ppc_elf_suffix): Correct parenthesization of ||
+ within &&.
+ (md_assemble): Fix handling of @l with an unsigned constant. Add
+ default case to reloc switch.
+
+ * config/tc-i386.h (AOUT_MACHTYPE): Define as 0 if TE_386BSD.
+
+ Based on patches from Tom Quiggle <quiggle@sgi.com>:
+ * ecoff.c (last_lineno): New static variable.
+ (add_procedure): Set last_lineno.
+ (ecoff_directive_loc): Likewise.
+ (ecoff_generate_asm_lineno): Likewise.
+ (ecoff_fix_loc): New function.
+ * ecoff.h (ecoff_fix_loc): Declare.
+ * config/tc-mips.c (append_insn): When inserting nops, and using
+ ECOFF debugging, call ecoff_fix_loc.
+
+Tue Jul 2 23:02:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (build_bytes): If an operand type is
+ marked as SRC_IN_DST retrieve it from the "destination" op.
+
+Sat Jun 29 13:38:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (arm-*-riscix*): Set emulation to riscix.
+ * configure: Rebuild.
+ * config/te-riscix.h: New file to define TE_RISCIX.
+
+ * config/tc-sh.h (SUB_SEGMENT_ALIGN): Define.
+
+Fri Jun 28 15:14:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (config.status): Just run config.status as other
+ tools do.
+
+Fri Jun 28 11:09:38 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in (TARGET_OS): Add definition to conf.
+
+Thu Jun 27 20:39:40 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (append_insn): Parenthesize
+ cop_interlocks expressions.
+
+Thu Jun 27 12:18:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_print): Close the listing file if it is not
+ stdout. Close the other files opened for the listing.
+
+ * config/tc-sparc.h (md_cons_align): Define.
+ (sparc_cons_align): Declare.
+ (HANDLE_ALIGN): Define.
+ (sparc_handle_align): Declare.
+ * config/tc-sparc.c (sparc_cons_align): New function.
+ (sparc_handle_align): New function.
+ * read.c (cons_worker): Call md_cons_align if it is defined.
+
+ * as.h (struct frag): Add fr_file and fr_line fields.
+ * frags.c (frag_new): Set fr_file and fr_line.
+ (frag_var): Likewise.
+ (frag_variant): Likewise.
+
+ * as.h (struct frag): Remove unused align_mask and align_offset
+ fields.
+
+ * listing.c (calc_hex): Offset by fr_fix when examining fr_var.
+ From <uddeborg@carmen.se>.
+
+Wed Jun 26 13:21:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (mips-*-osf*): New target.
+ * configure: Rebuild.
+
+ * config/tc-m68k.c: Add 68ec060 as a synonym for 68060.
+
+Wed Jun 26 16:23:08 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c: Added cop_interlocks, to avoid NOP insertion
+ between co-processor comparisons and branches for the VR4300.
+
+Mon Jun 24 18:02:50 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ * doc/Makefile.in (bindir, libdir, datadir, mandir, infodir,
+ includedir): Use autoconf set values.
+ (docdir): Removed.
+
+Mon Jun 24 11:58:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_eject): Don't do anything if listing is 0.
+ (listing_list): Likewise.
+ (listing_source_line): Likewise.
+ (listing_title): Don't save title if listing is 0.
+ (listing_source_file): Check listing rather than listing_tail.
+
+ * configure.in: On alpha*-*-osf*, link against libbfd.a if not
+ using shared libraries.
+ * configure: Rebuild.
+
+Fri Jun 21 18:22:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): In case 'i'/'j', don't require an
+ absolute expression if a relocation type was specified.
+
+Fri Jun 21 17:40:16 1996 Joel Sherrill <joel@merlin.gcs.redstone.army.mil>
+
+ * configure.in: Add support for *-*-rtems* configurations.
+ * configure: Rebuild.
+
+Fri Jun 21 16:01:18 1996 Richard Henderson <rth@tamu.edu>
+
+ * configure.in: Add alpha-*-linuxecoff* target. Use elf for
+ alpha-*-linux* target. Force bfd_gas for alpha-*. Require
+ opcodes library for alpha.
+ * configure: Rebuild with autoconf 2.10.
+ * config/tc-alpha.c: Substantial rewrite to add ELF support and
+ use new opcode table.
+ * config/tc-alpha.h (md_undefined_symbol): Don't define.
+ (LOCAL_LABEL): Define differently if OBJ_ELF.
+ (FAKE_LABEL_NAME): Define if OBJ_ELF.
+ * config/alpha-opcode.h: Remove.
+ * config/obj-elf.h: If TC_ALPHA, define ECOFF_DEBUGGING.
+ * Makefile.in (TARG_CPU_DEP_alpha): Depend upon
+ include/opcode/alpha.h rather than config/alpha-opcode.h.
+
+Thu Jun 20 19:10:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-aout.c (obj_emit_relocations): Give an error if the
+ relocation symbol was not resolved.
+ * config/obj-coff.c (do_relocs_for): Likewise.
+
+ * write.c (adjust_reloc_syms): Refetch the symbol section after
+ calling S_GET_VALUE, since it may have changed.
+
+ * expr.c (struct expr_symbol_line): Define.
+ (expr_symbol_lines): New static variable.
+ (make_expr_symbol): Add entry to expr_symbol_lines.
+ (expr_symbol_where): New function.
+ * expr.h: Use extern on function declarations.
+ (expr_symbol_where): Declare.
+ * symbols.c (resolve_symbol_value): Try to use expr_symbol_where
+ rather than printing the meaningless name of an expression
+ symbol.
+
+Thu Jun 20 15:57:41 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-i386.c (md_number_to_chars): Deleted.
+ * config/tc-i386.h (md_number_to_chars): New macro.
+
+ * config/tc-alpha.c (build_operate_n, build_mem): Moved earlier in
+ the file.
+ (load_symbol_address, load_expression): Use build_mem.
+ (build_operate): New function.
+ (emit_addq_r): Use it.
+
+ Wed Mar 13 22:14:14 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * symbols.c (colon): #if VMS, use S_SET_OTHER to store `const_flag'.
+
+ Tue Mar 5 14:31:45 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/tc-vax.h (NOP_OPCODE): Define.
+
+ Sun Feb 4 21:01:03 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/obj-vms.h (S_IS_COMMON): Define.
+ (S_IS_LOCAL): Check for \002 as well as \001.
+ (LONGWORD_ALIGNMENT): New macro.
+ (SUB_SEGMENT_ALIGN): Use it.
+
+ Fri Jan 26 17:44:09 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * config/vms-conf.h: Reconcile with conf.in.
+
+Wed Jun 19 11:31:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (is_dnrange): Only define if TC_GENERIC_RELAX_TABLE is
+ defined.
+
+ * doc/as.texinfo: Document that any number of hex digits can
+ follow \x.
+
+ * as.c (struct defsym_list): Define.
+ (defsyms): New static variable.
+ (parse_args): Just put --defsym arguments on defsyms list, rather
+ than defining them.
+ (main): Define defsyms after output file is created.
+
+ * config/tc-m68k.c (m68k_ip): Reject PRE and POST indexing mode on
+ cpu32. From Eric Norum <Eric.Norum@usask.ca>.
+
+ * config/tc-mips.c (mips_ip): In cases 'I', 'i', and 'j', set
+ insn_error rather than calling check_absolute_expr.
+
+ * as.c (emulation_name): Remove unused static variable.
+ (default_emul_bfd_name): Add return NULL to avoid warning.
+ * ecoff.c (ecoff_stab): Remove unused variables name and
+ name_end.
+ * frags.c (frag_new): Remove unused variable tmp.
+ * hash.c (hash_grow): Parenthesize + within <<.
+ (hash_print_statistics): Use %lu, not %d, to print unsigned
+ long variables.
+ * messages.c: Include "libiberty.h".
+ (fprint_value): Add cast to avoid printf warning.
+ (sprint_value): Likewise.
+ * read.c: Include "ecoff.h".
+ (emit_expr): Add casts to avoid printf warnings.
+ * read.h: Use extern for function declarations.
+ (pop_insert): Declare.
+ * stabs.c: Include "ecoff.h".
+ * subsegs.c (subseg_set_rest): Remove unused variables tmp,
+ former_last_fragP, and new_fragP.
+ * subsegs.h (subsegs_print_statistics): Declare.
+ * symbols.c (debug_verify_symchain): Change macro to discard
+ arguments.
+ * write.c (dump_section_relocs): Likewise.
+ * write.h: Use extern for function declarations.
+ (write_print_statistics): Declare.
+ * config/e-mipsecoff.c (mipsecoff_bfd_name): Return NULL to avoid
+ warning.
+ * config/e-mipself.c (mipself_bfd_name): Likewise.
+ * config/obj-elf.h (elf_ecoff_set_ext): Declare.
+
+ * config/tc-sparc.h (TC_RELOC_RTSYM_LOC_FIXUP): If OBJ_ELF, always
+ emit relocations against external symbols.
+
+ * config/tc-alpha.c (tc_gen_reloc): Output a sensible error
+ message if bfd_reloc_type_lookup fails, rather than calling
+ assert.
+
+ * config/tc-alpha.c (alpha_force_relocation): Add
+ BFD_RELOC_12_PCREL to switch.
+
+Tue Jun 18 20:29:57 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-i386.h (LOCAL_LABEL,FAKE_LABEL_NAME): Use defaults for
+ TE_PE (Lfoo, not .Lfoo).
+
+Tue Jun 18 17:13:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_fill): Don't warn about a zero repeat count.
+
+ * config/tc-mips.c (mips_ip): Don't warn about using AT as a
+ coprocessor register.
+
+ * config/tc-i386.c (md_assemble): When checking the size of a
+ register to set the size of an instruction, do a bitwise and with
+ Reg8 and Reg16 rather than requiring the type to be exactly Reg8
+ or Reg16.
+
+Tue Jun 18 13:19:51 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/tc-h8300.c (parse_reg): Tweak error messages.
+ (build_bytes): Likewise.
+ (skip_colonthing): Handle :32 suffix.
+ (get_specific): Promote L_24 to L_32 if it makes a match.
+ Don't always promote L_8 to L_16.
+ (do_a_fix_imm): Clean up L_32 and L_24 handling.
+
+ * config/tc-h8300.c (Smode): New variable.
+ (h8300hmode): Turn off Hmode.
+ (h8300smode): New function. Turn on Smode and Hmode.
+ (md_pseudo_table): New ".h8300s" pseudo-op.
+ (parse_reg): Handle "exr" register.
+ (get_operand): Handle bizarre syntax for "stm.l" and "ldm.l".
+ Handle "mach" and "machl" operands for ldmac.
+ (get_specific): Handle "stm.l" and "ldm.l".
+ (build_bytes): Handle "stm.l" and "ldm.l"; handle MACREG operands.
+ * config/tc-h8300.h (COFF_MAGIC): Handle H8/S magic number.
+ (Smode): Declare.
+
+Mon Jun 17 15:50:53 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * doc/as.texinfo: Reorder chapter of machine dependent options so
+ that it is sorted by chip name.
+
+ * doc/as.texinfo: Use consistant spelling of Vax.
+ * doc/c-vax.texi: Likewise.
+
+Mon Jun 17 11:26:56 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/tc-hppa.c (md_pseudo_table): Add ".begin_try" and ".end_try"
+ pseudo ops.
+ (tc_gen_reloc, SOM version): Handle R_BEGIN_TRY and R_END_TRY.
+ (md_apply_fix): Likewise.
+ (pa_try): New function.
+ (hppa_force_relocation): Force relocs for BEGIN_TRY and END_TRY.
+
+Sun Jun 16 22:57:47 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * config/tc-hppa.c (md_pseudo_table): Add ".level" pseudo op.
+ (pa_level): New function.
+
+Fri Jun 14 20:06:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * listing.c (listing_newline): Don't do anything if listing is 0.
+
+Thu Jun 13 17:50:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.c (section_symbol): If symbol_table_frozen is set, call
+ symbol_create, not symbol_new.
+
+Wed Jun 12 14:10:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (adjust_reloc_syms): Don't set sy_used_in_reloc for an
+ absolute symbol unless TC_FORCE_RELOCATION returns true.
+
+ * config/obj-coff.c (previous_file_symbol): Remove BFD_ASSEMBLER
+ version.
+ (c_dot_file_symbol): BFD_ASSEMBLER version: Don't set the value of
+ the symbol to a pointer. Don't set previous_file_symbol.
+ Simplify symbol list rearrangement.
+ (coff_frob_symbol): Don't do anything with C_FILE symbols.
+ (coff_adjust_symtab): Don't check previous_file_symbol.
+
+Mon Jun 10 14:52:29 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_lcomm): New function for .lcomm
+ directive.
+ (md_pseudo_table): Add ppc_elf_lcomm.
+
+Mon Jun 10 11:45:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Accept ABSL for 'O', so that `bfextu
+ d0{24:1},d0' works without an immediate prefix on the bit numbers.
+ (md_begin): Add digits to alt_notend_table.
+ (md_parse_option): Make s a const pointer.
+
+ * config/tc-sparc.c (md_pseudo_table): Add "empty".
+ (s_empty): New static function.
+
+ * config/obj-coff.c (struct filename_list): Only define if not
+ BFD_ASSEMBLER.
+ (filename_list_head, filename_list_tail): Likewise.
+ (c_section_symbol): Remove unused BFD_ASSEMBLER version.
+ (obj_coff_endef, BFD_ASSEMBLER version): Don't set the debugging
+ flag for C_MOS, C_MOE, C_MOU, or C_EOS symbols, since they should
+ have a section of N_ABS rather than N_DEBUG. If we do a merge,
+ remove the new symbol from the list.
+ (obj_coff_endef, both versions): Call tag_insert even if there is
+ an old symbol with the same name, if the old symbol does not
+ happen to be a tag.
+ (coff_frob_symbol): Check SF_GET_TAG, C_EOF, and C_FILE outside of
+ the SF_GET_DEBUG condition. Don't call SA_SET_SYM_ENDNDX with a
+ symbol that will be moved to the end of the symbol list.
+ (coff_adjust_section_syms): Always call section_symbol for .text,
+ .data, and .bss.
+ (coff_frob_section): Likewise. Also, remove unused variable
+ strname.
+
+ * config/tc-ns32k.c (convert_iif): Call frag_grow rather than
+ manipulating frags directly.
+ (md_number_to_field): Adjust mem_ptr correctly if ENDIAN is
+ defined.
+
+ * app.c (do_scrub_chars): If '/' is LINE_COMMENT_START, check
+ whether the next character is '*' before checking whether we are
+ at the start of a line. Permit LINE_COMMENT_START to start a
+ comment in state 1 (seen some whitespace) as well, to match the
+ documentation.
+
+ * gasp.c (do_align): Permit a fill value for .align.
+
+Wed Jun 5 17:09:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (next_char_of_string): Warn if a newline is seen in the
+ middle of a string. Call bump_line_counters when appropriate.
+
+Wed Jun 5 17:08:36 1996 Richard Henderson <rth@tamu.edu>
+
+ * symbols.c (colon): Use LOCAL_LABEL.
+
+Tue Jun 4 10:55:16 1996 Tom Tromey <tromey@csk3.cygnus.com>
+
+ * Makefile.in (install): Don't check to see if tooldir exists.
+ Make $(tooldir) and $(tooldir)/bin.
+
+Tue Jun 4 10:14:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/ppc-sol.mt (TDEFINES): Don't turn on -mregnames by
+ default.
+
+Mon Jun 3 11:34:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Don't call as_warn if we are setting
+ insn_error. Don't put the string "ERROR" in insn_error. Set
+ insn_error rather than calling as_warn for an unsupported opcode.
+
+Sat Jun 1 21:51:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_parse_option): Check for a 64 bit format
+ before permitting -64.
+ * output-file.c (output_file_create): Remove duplicate
+ bfd_perror.
+
+Fri May 31 01:08:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (md_begin): If -64, create a .MIPS.options
+ section rather than a .reginfo section.
+ (mips_elf_final_processing): If -64, write out 64 bit RegInfo
+ information.
+
+ * config/tc-mips.c (load_register): If mips_isa < 3, permit a 32
+ bit value with the high bit set.
+
+Thu May 30 19:00:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_lcomm): Set section flags for .sbss section.
+
+ * config/tc-mips.c (mips_64): New static variable.
+ (mips_target_format): If mips_64, return elf64 targets rather than
+ elf32 ones.
+ (md_longopts): Add "32" and "64".
+ (md_parse_option): Handle -32 and -64.
+ (md_show_usage): Mention -32 and -64.
+ (cons_fix_new_mips): If mips_64, don't convert an 8 byte reloc to
+ a 4 byte one.
+
+Thu May 30 10:36:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (comment_chars): Make '!' a comment character
+ for Solaris compatibility.
+
+ * stabs.c (s_stab_generic): Under PowerPC Solaris, convert a
+ .stabd with 4 arguments into a .stabn.
+
+Wed May 29 16:43:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (macro): When passing X_add_number to
+ macro_build, cast it to int first.
+
+Tue May 28 13:29:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-z8k.c (md_apply_fix): Handle fx_r_type of 0, as
+ created by emit_expr.
+
+ * symbols.c (symbol_create): If bfd_make_empty_symbol fails, call
+ as_perror rather than assert.
+
+Fri May 24 18:24:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_ip): Mark sections created to hold
+ floating point information as read only.
+
+Fri May 24 12:07:54 1996 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * config/tc-ppc.c (ppc_set_cpu): Change defaults to match AIX.
+
+Thu May 23 17:34:24 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * read.c (potable): Add .skip as a synonym for .space.
+
+ * stabs.c (s_stab_generic): For PowerPC ELF, allow .stabd to take
+ 4 arguments, providing the 4th argument is 0, to allow
+ compatibility with the Solaris assembler.
+
+Thu May 16 15:51:48 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.h (struct sh_segment_info_type): Define.
+ (TC_SEGMENT_INFO_TYPE): Define.
+ (sh_frob_label): Declare.
+ (tc_frob_label): Define.
+ (sh_flush_pending_output): Declare.
+ (md_flush_pending_output): Define.
+ * config/tc-sh.c (md_assemble): If relaxing, emit a R_SH_CODE
+ reloc before the instruction if necessary.
+ (sh_frob_label): New function.
+ (sh_flush_pending_output): New function.
+ (sh_coff_frob_file): Ignore ALIGN, CODE, DATA, and LABEL relocs
+ when looking for the reloc for the target of .uses.
+ (md_convert_frag): Fix printf format (%0xlx to 0x%lx).
+ (sh_force_relocation): Force CODE, DATA, and LABEL relocs to be
+ emitted.
+ (md_apply_fix): Ignore CODE, DATA, and LABEL relocs.
+ (sh_coff_reloc_mangle): Force CODE, DATA, and LABEL relocs to use
+ the absolute symbol.
+
+ * subsegs.h (segment_info_type): Add tc_segment_info_data field if
+ TC_SEGMENT_INFO_TYPE is defined.
+
+Wed May 15 12:23:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_assemble): Make sure the opcode suffix
+ matches the register size.
+
+Wed May 15 08:33:37 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/obj-coff.c (count_entries_in_chain): Ignore Fixups with
+ fx_done set.
+ (do_relocs_for): Likewise.
+ (fixup_segment): Don't just quit if linkrelax is set. Try to
+ apply non pc-relative sym1-sym2 fixups, even if linkrelax is
+ nonzero.
+
+Fri May 10 14:16:59 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow GOT and section
+ relative relocations with -mrelocatable. Also allow unfixed
+ relocs in .ex_shared.
+
+Tue May 7 11:24:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (yank_symbols): Check that FNAME_OFFSET is
+ non-zero before assuming this is a long file name.
+ (w_strings): Likewise.
+ (c_dot_file_symbol): Set FNAME_OFFSET to 1 for a long file name.
+
+ * config/obj-coff.c (w_strings): Move declaration of i inside
+ #ifdef block which uses it.
+
+Tue May 7 00:49:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (do_a_fix_imm): Rename last argument to
+ "relaxmode". Output relocs which identify various relaxing
+ possibilities for mov.[bwl] instructions.
+ (build_bytes): Pass in a relaxing mode to do_a_fix_imm.
+
+Mon May 6 15:26:28 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.h (TC_HANDLES_FX_DONE): Define.
+ (MD_APPLY_FIX3): Define.
+ * config/tc-arm.c (my_get_expression): Only watch for bad segments
+ if OBJ_AOUT.
+ (md_apply_fix3): Renamed from md_apply_fix.
+ If pcrel reloc and symbol is in different section, undo effects
+ of md_pcrel_from.
+
+Sat May 4 12:49:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): Don't adjust
+ any reloc with an LR% or RR% field selector for SOM.
+
+Sat May 4 11:26:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Add subsegs.h to appropriate TARG_CPU_DEP_*
+ variables.
+
+Fri May 3 17:58:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c (coff_frob_symbol): Don't merge a symbol with
+ SF_GET_STATICS set.
+ (yank_symbols): Likewise.
+
+Wed May 1 13:38:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.h (segment_info_type): If MANY_SEGMENTS and not
+ BFD_ASSEMBLER, add name field.
+ * config/obj-coff.c: Include "libiberty.h".
+ (coff_header_append): Handle long section names.
+ (crawl_symbols): Just use the name field for the symbol name,
+ without worrying about null byte termination.
+ (w_strings): Handle long section names.
+ (write_object_file): Likewise. Also, use the name field, rather
+ than scnhdr.s_name.
+ (obj_coff_add_segment): Permit long section names.
+ (obj_coff_init_stab_section): Use the name field, rather than
+ scnhdr.s_name.
+ (adjust_stab_section): Likewise.
+ * config/te-pe.h (COFF_LONG_SECTION_NAMES): Define.
+
+ * config/tc-i960.c (brtab_emit): Don't set fx_im_disp field.
+ (mem_fmt): Likewise.
+ (md_apply_fix): Don't check fx_im_disp field.
+
+Thu Apr 25 11:39:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add * after sparc*-*-vxworks.
+ * configure: Rebuild.
+
+ * app.c (do_scrub_begin): If tc_comment_chars is not defined,
+ define it to comment_chars. Use tc_comment_chars rather than
+ comment_chars.
+ (do_scrub_chars): Use tc_comment_chars rather than comment_chars.
+ * config/tc-m68k.h (tc_comment_chars): Define.
+ (m68k_comment_chars): Declare.
+ * config/tc-m68k.c (m68k_comment_chars): Rename from
+ comment_chars. Change into a pointer rather than an array.
+ (md_longopts): Add "bitwise-or".
+ (md_parse_option): Handle OPTION_BITWISE_OR.
+ (md_show_usage): Mention --bitwise-or.
+ * doc/c-m68k.texi: Document --bitwise-or.
+
+Wed Apr 24 11:28:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-m68k.c (m68k_ip): Prevent attempts to use long offsets
+ in 68000 mode.
+
+ * config/obj-coff.c (obj_coff_section): BFD_ASSEMBLER version:
+ call demand_empty_rest_of_line. Non BFD_ASSEMBLER version:
+ correct handling of input line pointer, and call
+ demand_empty_rest_of_line.
+
+Mon Apr 22 18:02:37 1996 Doug Evans <dje@blues.cygnus.com>
+
+ * config/tc-sparc.c (in_bitfield_range): New static function.
+ (sparc_ip): New cases X,Y. Use SPARC_OPCODE_ARCH_V9_P.
+ (md_apply_fix, cases BFD_RELOC_32_PCREL_S2,
+ BFD_RELOC_SPARC_{WDISP16,WDISP19}): Fix undefined code.
+ (md_apply_fix): New cases BFD_RELOC_SPARC_[56].
+ (tc_gen_reloc): New cases BFD_RELOC_SPARC_[56].
+
+Thu Apr 18 18:58:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.c: BFD_ASSEMBLER:
+ (coff_last_bf): New static variable.
+ (coff_frob_symbol): Set endndx of a .bf symbol.
+ Non BFD_ASSEMBLER:
+ (obj_coff_endef): Call SF_SET_PROCESS on a .bf symbol.
+ (last_bfP): New static variable.
+ (yank_symbols): Set endndx of a .bf symbol.
+
+Thu Apr 18 11:53:58 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_parse_option): Add support for Solaris's -le
+ and -s options. Add -be for good measure.
+
+Wed Apr 17 12:31:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (s_space): Support non-constant fill value. Handle fill
+ value correctly for a size other than 1.
+
+Tue Apr 16 15:17:40 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-arm.c (my_get_float_expression): Update call to
+ gen_to_words, X_PRECISION changed from 6 to 5.
+
+Tue Apr 16 10:25:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (register_name,reg_name_search): Move register
+ name lookup from PE specific code to all targets. Add support for
+ -mregnames/-mno-regnames to control whether register names are
+ expanded or not.
+ (md_assemble): Call register_name for all platforms.
+ (md_parse_option): Add support for -mregnames/-mno-regnames.
+
+ * configure.in (powerpcle*-*-solaris): Add support.
+ (powerpc*-*-linux): Ditto.
+ * configure: Regenerate.
+
+ * config/ppc-sol.mt: New config file for PowerPC Solaris.
+
+Mon Apr 15 12:26:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-mips.c (mips_frob_file): Permit multiple %hi relocs to
+ be associated with a single %lo reloc.
+
+ * config/tc-mips.c (load_address): Cast X_add_number to valueT
+ before comparing against MAX_GPREL_OFFSET, so that negative
+ numbers are handled correctly.
+ (macro): Likewise.
+
+Thu Apr 11 12:39:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.c (last_insn): New static variable.
+ (md_assemble): Warn about putting floating point branches in a
+ delay slot. If architecture is less than v9, insert NOP
+ instructions between floating point instructions and floating
+ point branches. (The SunOS assembler does both these operations.)
+ Save the last instruction opcode.
+ (sparc_ip): Add pinsn parameter. Change caller.
+
+ * config/tc-m68k.c (md_estimate_size_before_relax): Correct check
+ for byte jump to next instruction to skip empty frags.
+
+Wed Apr 10 16:48:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-alpha.c (alpha_ip): If we are going to call emit_add64
+ for addq with a 16 bit signed value, just emit a lda instruction
+ instead.
+
+Wed Apr 10 14:34:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (do_a_fix_imm): Don't cut off high bits
+ of a 32bit operand.
+
+Mon Apr 8 14:42:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+ * configure: Rebuild.
+
+Fri Apr 5 17:01:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (get_specific): Remove some #if 0 code.
+ (build_bytes): Remove all ABSMOV related code; it's unnecessary.
+
+Fri Apr 5 15:13:10 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/atof-ieee.c: Fix handling of denormalized extended
+ precision numbers and overflow/underflow detection.
+ (MAX_PRECISION, X_PRECISION, P_PRECISION): Changed from 6 to 5, to
+ not include the 16 bit gap in the m68k extended precision format.
+
+Fri Apr 5 14:29:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add i386-*-freebsdelf* target; from John Polstra
+ <jdp@polstra.com>.
+ * configure: Rebuild.
+
+Fri Apr 5 18:39:28 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c: Allow non-zero offsets from .sdata symbols to
+ be accessed using the $gp register.
+ * config/tc-mips.h (MAX_GPREL_OFFSET): Added.
+
+Wed Apr 3 10:56:14 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * config/tc-sparc.c (sparc_md_end): Set bfd machine number to
+ bfd_mach_sparc_sparclet if current_architecture is sparclet.
+
+Mon Apr 1 16:55:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (get_line_sb): Bump line counters based on
+ input_line_pointer[-1], not *input_line_pointer. Don't bother to
+ call LISTING_NEWLINE.
+ (s_macro): Don't call demand_empty_rest_of_line.
+ * app.c (do_scrub_chars): When handling C style comments, unget
+ ch2 rather than ch.
+
+Fri Mar 29 16:15:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.h (enum linkonce_type): Define.
+ (s_linkonce): Declare.
+ * read.c (potable): Add "linkonce".
+ (s_linkonce): New function.
+ * subsegs.h (segment_info_type): Add linkonce field to
+ MANY_SEGMENTS && ! BFD_ASSEMBLER section.
+ * config/obj-coff.h (obj_handle_link_once): Define if TE_PE.
+ (obj_coff_pe_handle_link_once): Declare if TE_PE.
+ * config/obj-coff.c: If TE_PE and not BFD_ASSEMBLER, #include
+ "coff/pe.h".
+ (obj_coff_pe_handle_link_once): New function, defined if TE_PE.
+ (c_section_symbol): If TE_PE, set the x_comdat field in the aux
+ entry based on the linkonce field in segment_info.
+ * doc/as.texinfo: Document .linkonce.
+
+Fri Mar 29 11:31:27 1996 J.T. Conklin (jtc@lisa.cygnus.com)
+
+ * doc/as.1: Changed to be recognized by catman -w on Solaris.
+
+Thu Mar 28 15:27:47 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stabs.c (s_stab_generic): Call the listing functions before
+ doing the rest of the processing, which may involve freeing the
+ string. Pass string, not string + stroff, to OBJ_PROCESS_STAB in
+ SEPARATE_STAB_SECTIONS case.
+
+ * config/tc-hppa.c: Remove nested comment.
+ (tc_gen_reloc): Move label done inside the ifdef in which it is
+ used.
+ (md_apply_fix): Pass pointers to correct types to libhppa.h
+ functions. Always return a value.
+
+ * config/tc-mips.h (tc_frob_file): Define.
+ (mips_frob_file): Declare.
+ * config/tc-mips.c (struct mips_hi_fixup): Define.
+ (mips_hi_fixup_list): New static variable.
+ (imm_unmatched_hi): New static variable.
+ (md_assemble): Clear imm_reloc, imm_unmatched_hi, and
+ offset_reloc. Pass imm_unmatched_hi to append_insn.
+ (append_insn): Add unmatched_hi parameter. If it is set, add the
+ new fixup to mips_hi_fixup_list. Change all callers.
+ (mips_ip): Set imm_unmatched_hi when appropriate.
+ (mips_frob_file): New function.
+
+Thu Mar 28 11:47:59 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (sparc-*-solaris2*): Renamed from sparc*-*-solaris2*.
+ * configure: Regenerated.
+
+Tue Mar 26 18:19:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.c (main): Call bfd_set_error_program_name.
+
+Fri Mar 22 11:13:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h (strdup): Don't declare.
+ * stabs.c: Include libiberty.h
+ (get_stab_string_offset): Use xstrdup rather than strdup.
+ (s_stab_generic): Likewise.
+ * as.c (parse_args): Likewise.
+ * read.c (s_mri_sect): Likewise.
+
+ * gasp.c (change_base): Recognize \(...) construct documented to
+ pass through enclosed characters literally through to the output.
+ (process_assigns): Likewise. Also, be more careful to avoid
+ looking past the end of the buffer.
+
+Thu Mar 21 13:18:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i386.c (md_parse_option): If OBJ_ELF, ignore -k for
+ FreeBSD compatibility. From John Polstra <jdp@polstra.com>.
+
+Wed Mar 20 18:13:32 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * doc/as.texinfo, doc/c-i960.texi: Fix typos.
+
+Wed Mar 20 17:05:16 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * config/alpha-opcode.h: Added cvtst instruction.
+
+Mon Mar 18 13:12:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_stab): Don't try to make a symbol out of the stab
+ string. Extract the addend from the result of expression.
+
+Fri Mar 15 17:10:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * app.c (do_scrub_chars): If whitespace is seen in state 11, and
+ LABELS_WITHOUT_COLONS is not defined, and we are not in m68k MRI
+ mode, change the state to 3 rather than 1.
+
+Thu Mar 14 18:18:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (C_REGISTER_SECTION): Change from 20 to 50, to
+ correspond to 11 March change.
+
+Thu Mar 14 15:27:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-h8300.c (build_bytes, MEMIND case): Generate
+ an R_MEM_INDIRECT reloc rather than R_RELBYTE.
+
+Tue Mar 12 12:21:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.8.
+
+Mon Mar 11 18:57:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/atof-ieee.c (gen_to_words): Improve handling of
+ X_PRECISION numbers. Based on patches from Andreas Schwab
+ <schwab@issan.informatik.uni-dortmund.de>.
+
+Mon Mar 11 09:59:53 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * as.h (SEG_NORMAL, SEG_LIST): Bump segment limit from 10 to 40.
+ (SEG_LAST): New.
+ * subsegs.c (MANY_SEGMENTS): Increase segment limit.
+ * obj-coff.c (seg_N_TYPE, seg_info_off_by_4): Likewise.
+ (do_relocs_for, w_symbols, obj_coff_add_segment, do_linenos_for,
+ crawl_symbols, coff_header_append): Loop to SEG_LAST rather than
+ SEG_E9.
+
+Thu Mar 7 15:17:39 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Handle operand char 'O' (neg reg).
+
+Thu Mar 7 09:19:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (SUBSEG_MILLI): Define.
+ (pa_def_subspaces): Add $MILLICODE$.
+ (pa_spaces_begin): Set section flags for $MILLICODE$.
+
+Wed Mar 6 14:11:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Only SEC_LOAD if the type is
+ not SHT_NOBITS. Don't tamper with flags based on type if a
+ special section was found (revert Feb 29 change).
+
+ * config/tc-sh.c (sh_do_align): Only align using the nop pattern
+ if aligning to a longword boundary or greater.
+
+Tue Mar 5 15:10:43 1996 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (sh_do_align): Pass 1 not 2 to frag_align.
+
+Mon Mar 4 20:50:57 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i386-*-cygwin32): Don't use bfd_gas.
+ * configure: Regenerated.
+
+Mon Mar 4 10:13:06 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c: Add default definitions for R_N0SEL and
+ R_N1SEL since they're not defined for old versions of hpux.
+
+ * config/tc-hppa.c (tc_gen_reloc): Fix typo in R_COMP2 code.
+ Set "sym_ptr_ptr" and "addend" fields to dummy values for
+ R_N0SEL and R_N1SEL.
+
+Fri Mar 1 10:20:52 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * flonum-konst.c: Add two more constants for 1e+-2048 and
+ 1e+-4096, and correct the other constants.
+
+ * symbols.c (resolve_symbol_value): Handle O_logical_not.
+
+Thu Feb 29 13:58:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Allow predefined section
+ types to set the nobits type. Avoid a shadowed declaration.
+
+Wed Feb 28 15:38:56 1996 Jeffrey A Law (law@cygnus.com)
+
+ * config/tc-hppa.c (hppa_fix_adjustable): For SOM, don't
+ reduce relocs using e_nlrsel field selectors.
+
+ * write.c (fix_new_exp): Don't use #elif. Some compilers
+ don't handle it.
+
+ * config/tc-hppa.c (selector_table): Add "n", "nl", and "nlr" to
+ the selector table.
+ (pa_chk_field_selector): Handle new field selectors for SOM.
+
+Tue Feb 27 14:42:27 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in (m68k-*-linux*aout*, m68k-*-linux*): New targets.
+ * configure: Rebuild.
+ * config/te-linux.h (LOCAL_LABELS_FB): Define.
+ * config/tc-m68k.h (TARGET_FORMAT) [TE_LINUX]: Define to
+ "a.out-m68k-linux".
+ * config/tc-m68k.c (comment_chars): Don't include '#' if TE_LINUX
+ is defined.
+
+Mon Feb 26 18:58:58 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update to handle shared library support.
+
+Mon Feb 26 10:34:10 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Print all architectures that support
+ the insn on mismatch.
+
+Fri Feb 23 21:44:39 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Add support for a29-coff.
+ * configure: Rebuild.
+
+Thu Feb 22 16:39:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_coff_frob_file): Don't consider the address
+ of the section when looking for the R_SH_USES fixup, because the
+ frag addresses have not yet been adjusted.
+
+ * gdbinit.in: Set a breakpoint on as_warn_where.
+
+ * config/tc-mips.c (macro): Add missing arguments to macro_build
+ omitted in last change. From Jim Wilson <wilson@cygnus.com>.
+
+Wed Feb 21 17:00:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-h8300.c (tc_reloc_mangle): Change reloc based on size
+ if it is TC_CONS_RELOC. Set a size of 4 to R_RELLONG.
+
+Wed Feb 21 09:25:39 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (sparc_ip): Recognize %asr0 for v8.
+
+Tue Feb 20 21:48:03 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (parse_keyword_arg): Accept leading '%'.
+ (sparc_ip): Accept %asr[1..31] for v8 and %asr[%16..31] for v9.
+ Recognize [uU] format args as sparclet cpregs.
+
+Tue Feb 20 22:25:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_handle_align): Don't emit R_SH_ALIGN relocs
+ in bss_section.
+
+Mon Feb 19 14:16:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sparc.h (TC_RELOC_RTSYM_LOC_FIXUP): Check S_IS_WEAK as
+ well as S_IS_EXTERNAL.
+ (tc_fix_adjustable): Likewise.
+ * config/tc-sparc.c (md_apply_fix): In OBJ_ELF case, check for
+ S_IS_WEAK as well as S_IS_EXTERNAL when deciding whether to return
+ early.
+ (tc_gen_reloc): Check S_IS_WEAK as wel as S_IS_EXTERNAL when
+ deciding whether to convert BFD_RELOC_32_PCREL_S2 if PIC.
+
+Mon Feb 19 02:15:57 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (max_architecture): Change to sparclite for
+ 32 bit arch.
+ (default_compatible): Delete.
+ (sparc_ffs): New function.
+ (md_begin): Only call SPARC_OPCODE_CONFLICT_P once.
+ (sparc_ip): Rewrite architecture match and bump logic.
+
+Sun Feb 18 15:03:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check for 'do not mix' from native linker before
+ trying to use -rpath.
+ * configure: Rebuild.
+
+Fri Feb 16 16:53:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (SF_ADJ_LNNOPTR): Define (non BFD_ASSEMBLER).
+ (SF_GET_ADJ_LNNOPTR): Define (non BFD_ASSEMBLER).
+ (SF_SET_ADJ_LNNOPTR): Define (non BFD_ASSEMBLER).
+ * config/obj-coff.c (obj_coff_endef): Set ADJ_LNNOPTR when LNNOPTR
+ is set.
+ (w_symbols): If ADJ_LNNOPTR is set, add the section lnnoptr field
+ to the symbol lnnoptr field, to get the correct file offset.
+
+Thu Feb 15 14:48:38 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (elf_frob_symbol): On the PowerPC, force all
+ symbols that are not function, file, or section symbols to be
+ object types.
+
+Thu Feb 15 11:20:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Set and substitute RPATH_ENVVAR.
+ * configure: Rebuild.
+ * Makefile.in (RPATH_ENVVAR): New variable.
+ (check): Use $(RPATH_ENVVAR) rather than LD_LIBRARY_PATH.
+
+ * configure.in: Accept i686. From H.J. Lu <hjl@zoom.com>: i386
+ doesn't need opcodes. If configuring shared, opcodes needs bfd.
+ * configure: Rebuild.
+
+Wed Feb 14 16:33:12 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de>
+
+ * read.c (s_mri_sect): Don't return '\0' in type. Set all
+ appropriate flags in BFD section.
+
+ * configure.in (m68k-*-psos*): New target.
+ * configure: Rebuild.
+ * config/te-psos.h: New file.
+ * config/tc-m68k.c (comment_chars): Don't include '#' if TE_PSOS
+ is defined.
+
+Wed Feb 14 13:43:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ From Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in: Remove duplicate setting of cpu_type. Check
+ whether opcodes library is required for on all targets, not just
+ primary one.
+ * configure: Rebuild.
+
+ * config/tc-mips.c (mips_big_got): New static variable.
+ (s_extern): Don't declare.
+ (reg_needs_delay): New static function.
+ (macro_build): Permit GOT/CALL_HI/LO relocs.
+ (macro_build_lui): If place is not NULL, use the number in the
+ expression.
+ (load_address): Handle mips_big_got case.
+ (macro): Handle mips_big_got for M_LA_AB, M_JAL_A, and load and
+ store macros.
+ (OPTION_XGOT): Define.
+ (md_longopts): Add "xgot" if OBJ_ELF.
+ (md_parse_option): Handle -xgot.
+ (md_show_usage): Mention -xgot.
+ (md_apply_fix): Permit GOT/CALL_HI/LO relocs.
+ (tc_gen_reloc): Handle GOT/CALL_HI/LO relocs.
+
+Wed Feb 14 11:22:27 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * config/tc-m68k.c (m68k_ip) [operand kind '#']: When fixing
+ the byte relocation, point it to the low byte of the word.
+
+Tue Feb 13 15:31:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set HDLFLAGS for *-*-hpux with --enable-shared.
+ * configure: Rebuild.
+
+Mon Feb 12 15:53:46 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.in: Recognize any sparc* cpu.
+ * configure: Regenerated.
+
+Mon Feb 12 15:41:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (potable): Add "mri" and ".mri".
+ (s_mri): New function.
+ * read.h (s_mri): Declare.
+ * app.c (scrub_m68k_mri): New static variable.
+ (mri_pseudo): New static variable.
+ (do_scrub_begin): Add m68k_mri parameter. Use it rather than
+ flag_m68k_mri. Initialize scrub_m68k_mri.
+ (mri_state, mri_last_ch): New static variables.
+ (struct app_save): Add scrub_m68k_mri, mri_state, and mri_last_ch
+ fields.
+ (app_push): Save new fields.
+ (app_pop): Restore new fields.
+ (do_scrub_chars): Check scrub_m68k_mri rather than flag_mri_mri.
+ If TC_M68K, use a trivial state machine to look for occurrences of
+ the .mri pseudo-op, and change the mode appropriately.
+ * as.h (do_scrub_begin): Update prototype.
+ * input-scrub.c (input_scrub_begin): Pass flag_m68k_mri to
+ do_scrub_begin.
+ * config/tc-m68k.c (reg_prefix_optional_seen): New static
+ variable.
+ (m68k_mri_mode_change): New function.
+ (md_parse_option): Set reg_prefix_optional_seen.
+ * config/tc-m68k.h (m68k_mri_mode_change): Declare.
+ (MRI_MODE_CHANGE): Define.
+ * doc/as.texinfo: Document .mri pseudo-op.
+
+ * app.c (do_scrub_chars): In MRI mode, don't treat '#' as a
+ comment character.
+
+Mon Feb 12 15:16:29 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ Support for OBJ_ELF on m68k, mostly inside #ifdef OBJ_ELF:
+ * config/m68k-parse.h (enum pic_relocation): Define.
+ (struct m68k_exp): Add pic_reloc field.
+ * config/tc-m68k.h (TC_RELOC_RTSYM_LOC_FIXUP): Define.
+ (tc_fix_adjustable): Define to call tc_m68k_fix_adjustable.
+ (NO_RELOC): Define to BFD_RELOC_NONE if BFD_ASSEMBLER, to zero
+ otherwise.
+ * config/tc-m68k.c: Delete definition of NO_RELOC.
+ (struct m68k_it): Add pic_reloc field.
+ (add_fix): Copy over pic_reloc field.
+ (md_pseudo_table): Interpret .align parameter as byte count.
+ (mote_pseudo_table): Likewise.
+ (tc_m68k_fix_adjustable): New function.
+ (get_reloc_code): New function.
+ (md_assemble): Use it as last argument to fix_new_exp.
+ (md_apply_fix_2): For a relocation against a symbol don't put the
+ addend into the data.
+ (tc_gen_reloc): Different addend computation for OBJ_ELF.
+ (m68k_ip): Don't relax an operand that requires pic relocation.
+ (md_begin): Align .text, .data and .bss on 4 byte boundary by
+ default.
+ * write.c (fixup_segment): Don't add symbol value to addend if
+ TC_M68K and OBJ_ELF.
+ * config/m68k-parse.y (yylex): Handle @PLTPC, etc.
+ (motorola_operand): Add rule for `(zapc, EXPR)'.
+
+Mon Feb 12 10:07:33 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * ecoff.c (ecoff_directive_weakext): Fixed so that whitespace
+ *really* is permissible before the comma.
+
+Mon Feb 12 00:12:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-sh.c (sh_do_align): Align to a 2 byte boundary before
+ inserting nop instructions.
+
+Fri Feb 9 10:54:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/te-aux.h: Change include of aux.h to aux-coff.h.
+
+Thu Feb 8 20:02:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (tc_coff_symbol_emit_hook): Correct storage
+ class setting for a CALLNAME symbol in COFF.
+
+ * read.c (potable): Pass negative numbers for new .balign[wl] and
+ .p2align[wl] pseudo-ops.
+ (s_align_bytes): Treat a negative argument as specifying the fill
+ length.
+ (s_align_ptwo): Likewise.
+
+Wed Feb 7 14:12:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * read.c (potable): Add balignw, balignl, p2alignw, and p2alignl.
+ (do_align): Take new len parameter. Change all callers. Pass it
+ to md_do_align.
+ (s_align_bytes): Arg now indicates the length of the fill pattern.
+ (s_align_ptwo): Likewise.
+ * config/obj-coff.c (write_object_file): Pass length to
+ md_do_align.
+ * config/tc-i386.h (md_do_align): Take new len parameter.
+ * config/tc-m88k.h (md_do_align): Likewise.
+ * config/tc-m88k.c (m88k_do_align): Likewise.
+ * config/tc-sh.h (md_do_align): Likewise.
+ * config/tc-sh.c (sh_do_align): Likewise.
+ * doc/as.texinfo: Document new pseudo-ops.
+
+ * config/obj-coff.c (fixup_mdeps): Divide offset by fr_var, as is
+ done in cvt_frag_to_fill.
+
+ * config/tc-sh.h (sh_do_align): Declare.
+ (md_do_align): Define.
+ * config/tc-sh.c (sh_do_align): New function.
+
+ * ecoff.c (ecoff_build_lineno): Don't try to store the address
+ difference if the next address is before the current one.
+
+ * config/tc-m68k.c (struct m68k_cpu): Add alias field.
+ (archs): Initialize new field.
+ (m68k_ip): Don't list alias names when listing CPUs which support
+ an instruction.
+
+ * as.c (main): Call parse_args before read_begin.
+ * app.c (do_scrub_chars): If flag_m68k_mri, don't put a dot in
+ front of generated pseudo-ops.
+ * read.c (potable): Ignore "name".
+ (s_app_file): Permit a single quote after the string, since one
+ may appear in m68k MRI mode.
+
+ * configure.in: Check for --enable-shared. If linking against
+ shared BFD and opcodes, fix library name on SunOS, and try to set
+ -rpath reasonably.
+ * configure: Rebuild.
+
+Tue Feb 6 15:16:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * as.h (flag_m68k_mri): Declare.
+ * as.c (parse_args): If TC_M68K, set flag_m68k_mri for -M.
+ * Many files: For MRI syntax that is specific to the m68k MRI
+ assembler, check flag_m68k_mri rather than flag_mri or
+ MRI_MODE_NEEDS_PSEUDO_DOT.
+
+Mon Feb 5 16:29:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/tc-i960.c (ARCH_HX): Define.
+ (arch_tab): Add HX.
+ (targ_has_sfr): Handle ARCH_HX.
+ (targ_has_iclass): Handle ARCH_HX.
+ (tc_coff_fix2rtype): Add return 0 to avoid warning.
+ (tc_headers_hook): If the architecture was specified explicitly,
+ use it when setting the flags. Set the extern variable coff_flags
+ rather than headers->filehdr.f_flags, since the latter is set
+ unconditionally in obj-coff.c.
+ (i960_handle_align): Remove unused variable fixp.
+
+ Support for building bfd and opcodes as shared libraries, based on
+ patches from Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in: Set OPCODES and BFD to search directories.
+ Substitute OPCODES_DEP and BFDDEP. On SunOS, set HLDFLAGS.
+ * configure: Rebuild.
+ * Makefile.in (LDFLAGS, HLDFLAGS): New variables.
+ (LIBDEPS): New variable.
+ (as.new0: Depend upon $(LIBDEPS) rather than $(LIBS). Use
+ $(HLDFLAGS) in link.
+ (check): Set LD_LIBRARY_PATH in the environment.
+
+Fri Feb 2 17:41:53 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * config/tc-ppc.h (ELF_TC_SPECIAL_SECTIONS): Make .sdata2, .sbss2,
+ .PPC.EMB.sdata0, and .PPC.EMB.sbss0 sections all default to
+ read-only, not read/write.
+
+Fri Feb 2 14:09:25 1996 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * Makefile.in (INSTALL_XFORM): Remove -e.
+
+Fri Feb 2 12:32:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * write.c (write_relocs): Use S_IS_DEFINED and S_IS_COMMON rather
+ than comparing S_GET_SEGMENT to undefined_section.
+ (write_object_file): Skip symbols which were equated to an
+ undefined or common symbol.
+ * symbols.c (resolve_symbol_value): Use S_IS_DEFINED and
+ S_IS_COMMON rather than comparing S_GET_SEGMENT to
+ undefined_section.
+ (S_GET_VALUE): Likewise. Avoid recursion problems if S_IS_DEFINED
+ or S_IS_COMMON call S_GET_VALUE.
+ * config/obj-aout.h (S_IS_COMMON): Define if not BFD_ASSEMBLER.
+ * config/obj-aout.c (obj_emit_relocations): If a reloc is equated
+ to an undefined or common symbol, convert the reloc to be against
+ the target symbol.
+ (obj_crawl_symbol_chain): Skip symbols which were equated to an
+ undefined or common symbol.
+ * config/obj-bout.h (S_IS_COMMON): Define if not BFD_ASSEMBLER.
+ * config/obj-bout.c (obj_emit_relocations): If a reloc is equated
+ to an undefined or common symbol, convert the reloc to be against
+ the target symbol.
+ (obj_crawl_symbol_chain): Skip symbols which were equated to an
+ undefined or common symbol.
+ * config/obj-coff.c (do_relocs_for): Use S_IS_DEFINED and
+ S_IS_COMMON rather than comparing S_GET_SEGMENT to
+ undefined_section.
+ (yank_symbols): Skip symbols which were equated to an undefined or
+ common symbol.
+
+Thu Feb 1 15:34:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-aout.h (S_IS_LOCAL): Check for \002 as well as \001.
+ * config/obj-bout.h (S_IS_LOCAL): Likewise.
+
+ * configure.in: Make sure we only add m68k-parse.o to
+ ${extra_objects} once, no matter how many m68k targets have been
+ enabled.
+ * configure: Rebuild.
+
+Wed Jan 31 18:31:46 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i386-*-cygwin32, ppc-*-cygwin32): New.
+ * configure: Rebuild.
+
+Wed Jan 31 14:03:17 1996 Richard Henderson <rth@tamu.edu>
+
+ * config/tc-m68k.c (md_pseudo_table): Add "extend" and "ldouble".
+ * doc/c-m68k.texi: Document .extend and .ldouble.
+
+ * configure.in (m68*-apple-aux*): New target.
+ * config/te-aux.h: New file.
+ * config/obj-coff.c (compare_external_relocs): New static function
+ if TE_AUX.
+ (do_relocs_for): Sort relocs if TE_AUX.
+ (fixup_segment): If TE_AUX, store common symbol value in segment.
+ * config/tc-m68k.h (TARGET_FORMAT): Define if TE_AUX.
+
+Wed Jan 31 12:24:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-coff.h (S_IS_LOCAL): Check for \002 as well as \001.
+
+ * config/tc-mips.c (s_mips_globl): Set BSF_OBJECT if it is not
+ BSF_FUNCTION.
+ (s_cpload): Set BSF_OBJECT for _gp_disp symbol.
+ * read.c (s_lcomm): If S_SET_SIZE is defined, set the size of the
+ symbol.
+ * ecoff.c (add_procedure): Set the BSF_FUNCTION flag.
+ (ecoff_build_symbols): If S_SET_SIZE is defined, set the size of
+ an undefined symbol and the size of a function symbol.
+ * config/obj-elf.c (elf_frob_symbol): If TC_MIPS, set BSF_OBJECT
+ for all common symbols.
+
+Tue Jan 30 12:35:24 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/tc-i960.c (parse_memop): In MRI mode, don't use implicit
+ scaling of index.
+
+ * expr.c (operand): Accept 0x hex constants in MRI mode if not on
+ m68k.
+
+Mon Jan 29 12:21:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/obj-elf.c (obj_elf_type): Set BSF_OBJECT flag for a type
+ of object. From Ronald F. Guilmette <rfg@monkeys.com>.
+
+ * ecoff.c (localsym_t): Add addend field.
+ (add_ecoff_symbol): Add addend argument. Change all callers.
+ (coff_sym_value): Make static.
+ (coff_sym_addend): New static variable.
+ (ecoff_directive_def): Initialize coff_sym_addend.
+ (ecoff_directive_val): Accept symbol + constant.
+ (ecoff_directive_endef): Pass coff_sym_addend to add_ecoff_symbol.
+ (ecoff_build_symbols): Include the addend in the symbol value.
+
+Fri Jan 26 19:28:52 1996 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (md_assemble): Ignore overflow on
+ BFD_RELOC_16_GOTOFF and BFD_RELOC_PPC_TOC16.
+
+Fri Jan 26 16:14:17 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (md_apply_fix3): SDA21 relocations are now 4
+ bytes in size, so offset appropriately in big endian mode when
+ writing the bottom 2 bytes.
+
+Thu Jan 25 20:26:23 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (default_compatible): New static local.
+ (md_begin): Initialize it. Rewrite warn_on_bump handling.
+ (sparc_ip): If no architecture or -bump specified, don't mark as
+ mismatched those in default_compatible.
+
+Thu Jan 25 12:21:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ SCO ELF support from Robert Lipe <robertl@arnet.com>:
+ * configure.in (i386-*-sco*elf*): Use fmt elf, targ sco5.
+ * configure: Rebuild.
+ * config/sco5.mt: New file; set TDEFINES to -DSCO_ELF.
+ * config/tc-i386.c (sco_id): New function, if SCO_ELF.
+ * config/tc-i386.h (tc_init_after_args): Define if SCO_ELF.
+ (sco_id): Declare if SCO_ELF.
+
+Thu Jan 25 03:10:53 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.c (initial_architecture,can_bump_v9_p): Deleted.
+ ({max,warn_after}_architecture): New static locals.
+ (md_begin): Replace NUMOPCODES with sparc_num_opcodes.
+ If both architecture and -bump requested, set max_architecture to max.
+ (sparc_md_end): Simplify.
+ (sparc_ip): Replace references to can_bump_v9_p with max_architecture.
+ Rewrite code to bump architecture and check for conflicts.
+ (md_longopts): Recognize -xarch={v8plus,v8plusa} for compatibility
+ with Solaris assembler.
+ (md_parse_option): Likewise. Call sparc_opcode_lookup_arch.
+ (md_show_usage): Update.
+
+Wed Jan 24 22:11:03 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * Makefile.in (RUNTEST): Fix reference to $${srcdir}.
+
+Mon Jan 22 09:21:36 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * config/tc-sparc.h (TARGET_FORMAT): Use #ifdef SPARC_ARCH64 instead of
+ #ifdef sparcv9 when choosing value.
+ (ENV64): Delete.
+ (md_end): Define.
+ (sparc_md_end): Declare.
+ * config/tc-sparc.c (SPARC_V9): Renamed from sparcv9.
+ (initial_architecture): New static local.
+ (can_bump_v9_p): Likewise.
+ (NO_V9): Delete all occurrences.
+ (sparc_md_end): New function.
+ (sparc_ip): New local v9_arg_p. Rework fp reg number test.
+ Don't bump architecture to v9 unless can_bump_v9_p set.
+ (md_parse_option): -A<arch> passed, set can_bump_v9_p accordingly.
+ * configure.in (sparc64 target cpu): Don't set obj_format here.
+ (SPARC_V9): Renamed from sparcv9.
+ (sparc64-*-elf*): Define SPARC_ARCH64.
+ * configure: Regenerated.
+ * acconfig.h (SPARC_V9): Renamed from sparcv9.
+ (SPARC_ARCH64): Add.
+ * conf.in: Regenerated.
+ * config/vmsconf.h: Update.
+
+Mon Jan 22 17:24:47 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * config/tc-mips.c (load_register): Optimise "dli" loads.
+ (md_show_usage): add "-mcpu=vr4100" to help text.
+
+Mon Jan 22 11:53:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * symbols.c (resolve_symbol_value): If a symbol is equated to an
+ undefined symbol, preserve the X_op of O_symbol.
+ (S_GET_VALUE): Fix check to permit this case.
+ * write.c (write_relocs): If a reloc is against an undefined
+ symbol equated to another symbol, change the reloc to be against
+ the latter symbol.
+ * config/obj-coff.c (do_relocs_for): Likewise.
+
+ * config/tc-ppc.c (ppc_csect): An unnamed csect is storage class
+ XMC_PR.
+
+Mon Jan 22 10:59:48 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (elf/ppc.h): Include elf/ppc.h if target
+ computer is PowerPC.
+
+ * config/tc-ppc.c (md_apply_fix3): Add more embedded relocations.
+
+ * config/tc-ppc.h (ELF_TC_SPECIAL_SECTIONS): Add sections
+ mentioned in the eabi.
+
+Thu Jan 18 17:58:19 1996 Kim Knuttila <krk@cygnus.com>
+
+ * config/tc-ppc.c (ppc_reldata): Changed alignement on reldata_section
+ * config/tc-ppc.c (ppc_pdata): Changed the alignment on pdata_section
+
+Mon Jan 15 17:43:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (mapping): Add more relocation suffixes.
+
+Sun Jan 14 21:29:36 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_elf_validate_fix): Allow .gcc_except_table
+ as a section it is ok to have unadorned -mrelocatable pointers in.
+
+Sat Jan 13 11:09:08 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/tc-ppc.c (ppc_section*): Wrap these functions inside
+ #ifdef OBJ_ELF.
+
+Fri Jan 12 15:32:07 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/obj-elf.c (obj_elf_section): Add hooks so machine
+ dependent section attributes can be handled.
+
+ * config/tc-ppc.h: (md_elf_section_{letter,type,word,flags}): New
+ macros to add support for exclude section flag and ordered section
+ type.
+
+ * config/tc-ppc.c (ppc_elf_section_{letter,type,word,flags}): New
+ functions to add support for exclude section flag and ordered
+ section type.
+
+Fri Jan 12 12:04:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * subsegs.c (section_symbol): Don't try to look up the section
+ symbol in the hash table. It should be possible to have a symbol
+ with the same name as a section, but no connection to it.
+
+ * read.c (cons_worker): Only call mri_comment_end from flag_mri.
+ From James Carlson <carlson@xylogics.com>.
+
+ * expr.c (operand): Skip whitespace after a close parenthesis.
+ From James Carlson <carlson@xylogics.com>.
+
+Tue Jan 2 12:43:23 1996 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * config/tc-sh.c (md_apply_fix): Call as_bad_where instead of
+ as_warn_where for relocation overflow.
+ (parse_reg): Accept register name only if next character is
+ not alphanumeric.
+
+For older changes see ChangeLog-9295
diff --git a/gas/Makefile.am b/gas/Makefile.am
new file mode 100644
index 00000000000..688f21ccc69
--- /dev/null
+++ b/gas/Makefile.am
@@ -0,0 +1,1695 @@
+## Process this file with automake to generate Makefile.in
+
+## Work around apparent automake bug.
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+SUBDIRS = doc po
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi`
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi`
+
+DEP = $(srcdir)/../mkdep
+
+TARG_CPU = @target_cpu_type@
+TARG_CPU_C = $(srcdir)/config/tc-@target_cpu_type@.c
+TARG_CPU_O = tc-@target_cpu_type@.o
+TARG_CPU_H = $(srcdir)/config/tc-@target_cpu_type@.h
+OBJ_FORMAT_C = $(srcdir)/config/obj-@obj_format@.c
+OBJ_FORMAT_O = obj-@obj_format@.o
+OBJ_FORMAT_H = $(srcdir)/config/obj-@obj_format@.h
+TARG_ENV_H = $(srcdir)/config/te-@te_file@.h
+ATOF_TARG_C = $(srcdir)/config/atof-@atof@.c
+ATOF_TARG_O = atof-@atof@.o
+
+# use @target_cpu_type@ for refering to configured target name
+IT_HDRS=itbl-parse.h $(srcdir)/itbl-ops.h
+IT_SRCS=itbl-parse.c itbl-lex.c $(srcdir)/itbl-ops.c
+IT_DEPS=$(srcdir)/itbl-parse.y $(srcdir)/itbl-lex.l $(srcdir)/config/itbl-@target_cpu_type@.h
+IT_OBJS=itbl-parse.o itbl-lex.o itbl-ops.o
+
+# CPU types. This is only used for dependency information.
+
+CPU_TYPES = \
+ a29k \
+ alpha \
+ arc \
+ arm \
+ d10v \
+ d30v \
+ fr30 \
+ h8300 \
+ h8500 \
+ hppa \
+ i386 \
+ i860 \
+ i960 \
+ m32r \
+ m68k \
+ m88k \
+ mcore \
+ mips \
+ mn10200 \
+ mn10300 \
+ ns32k \
+ ppc \
+ sh \
+ sparc \
+ tahoe \
+ tic30 \
+ tic80 \
+ vax \
+ w65 \
+ v850 \
+ z8k
+
+# Object format types. This is only used for dependency information.
+# We deliberately omit som, since it does not work as a cross assembler.
+
+OBJ_FORMATS = \
+ aout \
+ bout \
+ coff \
+ ecoff \
+ elf \
+ evax \
+ hp300 \
+ ieee \
+ vms
+
+# This is an sh case which sets valid according to whether the CPU
+# type in the shell variable c and the OS type in the shell variable o
+# are supported. This helps cuts down on the amount of dependency
+# information.
+
+CPU_OBJ_VALID = \
+ valid= ; \
+ case $$o in \
+ aout) \
+ case $$c in \
+ a29k | arm | i386 | i860 | m68k | mips | ns32k | sparc | tahoe | tic30 | vax) \
+ valid=yes ;; \
+ esac ;; \
+ bout) \
+ case $$c in \
+ i960) valid=yes ;; \
+ esac ;; \
+ coff) valid=yes ;; \
+ ecoff) \
+ case $$c in \
+ mips | alpha) valid=yes ;; \
+ esac ;; \
+ elf) valid=yes ;; \
+ evax) \
+ case $$c in \
+ alpha) valid=yes ;; \
+ esac ;; \
+ hp300) \
+ case $$c in \
+ m68k) valid=yes ;; \
+ esac ;; \
+ vms) \
+ case $$c in \
+ vax) valid=yes ;; \
+ esac ;; \
+ esac;
+
+# This is like CPU_OBJ_VALID, for the obj=multi case.
+
+CPU_MULTI_VALID = \
+ valid= ; \
+ case $$c in \
+ i386 | mips) valid=yes ;; \
+ esac;
+
+# Regular source files.
+
+GAS_CFILES = \
+ app.c \
+ as.c \
+ atof-generic.c \
+ bignum-copy.c \
+ cond.c \
+ depend.c \
+ ecoff.c \
+ ehopt.c \
+ expr.c \
+ flonum-copy.c \
+ flonum-konst.c \
+ flonum-mult.c \
+ frags.c \
+ hash.c \
+ input-file.c \
+ input-scrub.c \
+ listing.c \
+ literal.c \
+ macro.c \
+ messages.c \
+ output-file.c \
+ read.c \
+ sb.c \
+ stabs.c \
+ subsegs.c \
+ symbols.c \
+ write.c
+
+CFILES = $(GAS_CFILES) gasp.c itbl-ops.c
+
+HFILES = \
+ as.h \
+ asintl.h \
+ bignum.h \
+ bit_fix.h \
+ cgen.h \
+ ecoff.h \
+ emul-target.h \
+ emul.h \
+ expr.h \
+ flonum.h \
+ frags.h \
+ hash.h \
+ input-file.h \
+ itbl-ops.h \
+ listing.h \
+ macro.h \
+ obj.h \
+ output-file.h \
+ read.h \
+ sb.h \
+ struc-symbol.h \
+ subsegs.h \
+ symbols.h \
+ tc.h \
+ write.h
+
+# CPU files in config.
+
+TARGET_CPU_CFILES = \
+ config/tc-a29k.c \
+ config/tc-alpha.c \
+ config/tc-arc.c \
+ config/tc-arm.c \
+ config/tc-d10v.c \
+ config/tc-d30v.c \
+ config/tc-h8300.c \
+ config/tc-h8500.c \
+ config/tc-hppa.c \
+ config/tc-i386.c \
+ config/tc-i860.c \
+ config/tc-i960.c \
+ config/tc-m32r.c \
+ config/tc-m68k.c \
+ config/tc-m88k.c \
+ config/tc-mcore.c \
+ config/tc-mips.c \
+ config/tc-mn10200.c \
+ config/tc-mn10300.c \
+ config/tc-ns32k.c \
+ config/tc-ppc.c \
+ config/tc-sh.c \
+ config/tc-sparc.c \
+ config/tc-tahoe.c \
+ config/tc-tic30.c \
+ config/tc-tic80.c \
+ config/tc-vax.c \
+ config/tc-w65.c \
+ config/tc-v850.c \
+ config/tc-z8k.c
+
+TARGET_CPU_HFILES = \
+ config/tc-a29k.h \
+ config/tc-alpha.h \
+ config/tc-arc.h \
+ config/tc-arm.h \
+ config/tc-d10v.h \
+ config/tc-d30v.h \
+ config/tc-h8300.h \
+ config/tc-h8500.h \
+ config/tc-hppa.h \
+ config/tc-i386.h \
+ config/tc-i860.h \
+ config/tc-i960.h \
+ config/tc-m32r.h \
+ config/tc-m68k.h \
+ config/tc-m88k.h \
+ config/tc-mcore.h \
+ config/tc-mips.h \
+ config/tc-mn10200.h \
+ config/tc-mn10300.h \
+ config/tc-ns32k.h \
+ config/tc-ppc.h \
+ config/tc-sh.h \
+ config/tc-sparc.h \
+ config/tc-tahoe.h \
+ config/tc-tic30.h \
+ config/tc-tic80.h \
+ config/tc-vax.h \
+ config/tc-w65.h \
+ config/tc-v850.h \
+ config/tc-z8k.h
+
+# OBJ files in config
+
+OBJ_FORMAT_CFILES = \
+ config/obj-aout.c \
+ config/obj-bout.c \
+ config/obj-coff.c \
+ config/obj-ecoff.c \
+ config/obj-elf.c \
+ config/obj-evax.c \
+ config/obj-hp300.c \
+ config/obj-ieee.c \
+ config/obj-som.c \
+ config/obj-vms.c
+
+OBJ_FORMAT_HFILES = \
+ config/obj-aout.h \
+ config/obj-bout.h \
+ config/obj-coff.h \
+ config/obj-ecoff.h \
+ config/obj-elf.h \
+ config/obj-evax.h \
+ config/obj-hp300.h \
+ config/obj-ieee.h \
+ config/obj-som.h \
+ config/obj-vms.h
+
+# Emulation header files in config
+
+TARG_ENV_HFILES = \
+ config/te-386bsd.h \
+ config/te-aux.h \
+ config/te-delta.h \
+ config/te-delt88.h \
+ config/te-dpx2.h \
+ config/te-dynix.h \
+ config/te-generic.h \
+ config/te-go32.h \
+ config/te-hp300.h \
+ config/te-hppa.h \
+ config/te-i386aix.h \
+ config/te-ic960.h \
+ config/te-linux.h \
+ config/te-lnews.h \
+ config/te-lynx.h \
+ config/te-mach.h \
+ config/te-macos.h \
+ config/te-multi.h \
+ config/te-nbsd.h \
+ config/te-nbsd532.h \
+ config/te-pc532mach.h \
+ config/te-pe.h \
+ config/te-ppcnw.h \
+ config/te-psos.h \
+ config/te-riscix.h \
+ config/te-sparcaout.h \
+ config/te-sun3.h \
+ config/te-svr4.h \
+ config/te-sysv32.h
+
+# Multi files in config
+
+MULTI_CFILES = \
+ config/e-i386coff.c \
+ config/e-i386elf.c \
+ config/e-mipsecoff.c \
+ config/e-mipself.c
+
+CONFIG_OBJS = \
+ $(TARG_CPU_O) \
+ $(OBJ_FORMAT_O) \
+ $(ATOF_TARG_O) \
+ $(extra_objects)
+
+GENERIC_OBJS = \
+ app.o \
+ as.o \
+ atof-generic.o \
+ bignum-copy.o \
+ cond.o \
+ depend.o \
+ ehopt.o \
+ expr.o \
+ flonum-konst.o \
+ flonum-copy.o \
+ flonum-mult.o \
+ frags.o \
+ hash.o \
+ input-file.o \
+ input-scrub.o \
+ literal.o \
+ messages.o \
+ output-file.o \
+ read.o \
+ subsegs.o \
+ symbols.o \
+ write.o \
+ listing.o \
+ ecoff.o \
+ stabs.o \
+ sb.o \
+ macro.o
+
+OBJS = $(CONFIG_OBJS) $(GENERIC_OBJS)
+
+POTFILES = $(MULTI_CFILES) $(TARGET_ENV_HFILES) $(OBJ_FORMAT_HFILES) \
+ $(OBJ_FORMAT_CFILES) $(TARGET_CPU_HFILES) $(TARGET_CPU_CFILES) \
+ $(HFILES) $(CFILES) $(GAS_CFILES)
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+noinst_PROGRAMS = as-new gasp-new
+noinst_SCRIPTS = .gdbinit
+
+$(srcdir)/make-gas.com: stamp-mk.com
+stamp-mk.com: vmsconf.sh Makefile
+ sh $(srcdir)/vmsconf.sh $(GENERIC_OBJS) > new-make.com
+ $(SHELL) $(srcdir)/../move-if-change new-make.com $(srcdir)/make-gas.com
+ touch stamp-mk.com
+
+EXTRA_DIST = make-gas.com
+
+DISTSTUFF = make-gas.com m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c
+diststuff: $(DISTSTUFF) info
+
+DISTCLEANFILES = targ-cpu.h obj-format.h targ-env.h itbl-cpu.h cgen-desc.h
+
+# Now figure out from those variables how to compile and link.
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+
+# This is the variable actually used when we compile.
+# Specify the directories to be searched for header files.
+# Both . and srcdir are used, in that order,
+# so that tm.h and config.h will be found in the compilation
+# subdirectory rather than in the source directory.
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(srcdir)/config -I$(INCDIR) -I$(srcdir)/.. -I$(BFDDIR) -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+# This should be parallel to INCLUDES, but should replace $(srcdir)
+# with $${srcdir}, and should work in a subdirectory. This is used
+# when building dependencies, because the dependency building is done
+# in a subdirectory.
+DEP_INCLUDES = -D_GNU_SOURCE -I.. -I$${srcdir} -I../../bfd -I$${srcdir}/config -I$${srcdir}/../include -I$${srcdir}/.. -I$${srcdir}/../bfd -I$${srcdir}/../intl -I../../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+# How to link with both our special library facilities
+# and the system's installed libraries.
+
+GASLIBS = @OPCODES_LIB@ @BFDLIB@ ../libiberty/libiberty.a
+
+# Files to be copied away after each stage in building.
+STAGESTUFF = *.o $(noinst_PROGRAMS)
+
+$(OBJS): @ALL_OBJ_DEPS@
+
+as_new_SOURCES = $(GAS_CFILES)
+as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLLIBS)
+as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLDEPS)
+
+# Stuff that every object file depends upon. If anything is removed
+# from this list, remove it from dep-in.sed as well.
+$(OBJS): config.h as.h $(TARG_ENV_H) $(OBJ_FORMAT_H) $(TARG_CPU_H) flonum.h \
+ expr.h struc-symbol.h write.h frags.h hash.h read.h symbols.h tc.h \
+ obj.h listing.h bignum.h bit_fix.h $(INCDIR)/libiberty.h asintl.h
+
+gasp_new_SOURCES = gasp.c macro.c sb.c hash.c
+gasp_new_LDADD = ../libiberty/libiberty.a $(INTLLIBS)
+gasp_new_DEPENDENCIES = ../libiberty/libiberty.a $(INTLDEPS)
+
+EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
+ echo $${rootme}/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
+ echo $${srcdir}/../dejagnu/runtest ; else echo runtest; \
+ fi`
+RUNTESTFLAGS=
+
+check-DEJAGNU: site.exp
+ if [ -d testsuite ]; then \
+ true; \
+ else \
+ mkdir testsuite; \
+ fi
+ rm -f testsuite/site.exp
+ cp site.exp testsuite/site.exp
+ rootme=`pwd`; export rootme; \
+ srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ cd testsuite; \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcdir}/testsuite \
+ $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+# The implicit .c.o rule doesn't work for these, perhaps because of
+# the variables, or perhaps because the sources are not on vpath.
+$(TARG_CPU_O): $(TARG_CPU_C) $(TARG_CPU_DEP_@target_cpu_type@)
+ $(COMPILE) -c $(TARG_CPU_C)
+$(ATOF_TARG_O): $(ATOF_TARG_C)
+ $(COMPILE) -c $(ATOF_TARG_C)
+
+# ecoff.c only has full dependencies when ECOFF_DEBUGGING is defined,
+# so the automatic dependency stuff doesn't work.
+ecoff.o : ecoff.c ecoff.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/symconst.h \
+ $(INCDIR)/aout/stab_gnu.h
+
+# We need all these explicit rules for the multi stuff. Because of
+# these rules, we don't need one for OBJ_FORMAT_O.
+
+obj-aout.o : $(srcdir)/config/obj-aout.c
+ $(COMPILE) -c $(srcdir)/config/obj-aout.c
+obj-bout.o : $(srcdir)/config/obj-bout.c
+ $(COMPILE) -c $(srcdir)/config/obj-bout.c
+obj-coff.o: $(srcdir)/config/obj-coff.c
+ $(COMPILE) -c $(srcdir)/config/obj-coff.c
+obj-ecoff.o : $(srcdir)/config/obj-ecoff.c
+ $(COMPILE) -c $(srcdir)/config/obj-ecoff.c
+obj-elf.o : $(srcdir)/config/obj-elf.c
+ $(COMPILE) -c $(srcdir)/config/obj-elf.c
+obj-evax.o : $(srcdir)/config/obj-evax.c
+ $(COMPILE) -c $(srcdir)/config/obj-evax.c
+obj-hp300.o : $(srcdir)/config/obj-hp300.c
+ $(COMPILE) -c $(srcdir)/config/obj-hp300.c
+obj-ieee.o : $(srcdir)/config/obj-ieee.c
+ $(COMPILE) -c $(srcdir)/config/obj-ieee.c
+obj-multi.o : $(srcdir)/config/obj-multi.c
+ $(COMPILE) -c $(srcdir)/config/obj-multi.c
+obj-som.o : $(srcdir)/config/obj-som.c
+ $(COMPILE) -c $(srcdir)/config/obj-som.c
+obj-vms.o : $(srcdir)/config/obj-vms.c
+ $(COMPILE) -c $(srcdir)/config/obj-vms.c
+
+e-mipself.o : $(srcdir)/config/e-mipself.c
+ $(COMPILE) -c $(srcdir)/config/e-mipself.c
+e-mipsecoff.o : $(srcdir)/config/e-mipsecoff.c
+ $(COMPILE) -c $(srcdir)/config/e-mipsecoff.c
+e-i386coff.o: $(srcdir)/config/e-i386coff.c
+ $(COMPILE) -c $(srcdir)/config/e-i386coff.c
+e-i386elf.o: $(srcdir)/config/e-i386elf.c
+ $(COMPILE) -c $(srcdir)/config/e-i386elf.c
+
+# The m68k operand parser.
+
+EXTRA_as_new_SOURCES = config/m68k-parse.y
+
+# If m68k-parse.y is in a different directory, then ylwrap will use an
+# absolute path when it invokes yacc, which will cause yacc to put the
+# absolute path into the generated file. That's a pain when it comes
+# to generating snapshots, because it introduces spurious diffs.
+# Since when we make the snapshots $(srcdir) = ".", we check for that
+# case and handle it differently. This means that anybody who
+# configures with $(srcdir) = "." will have to set their path in the
+# debugger if they want to debug m68k-parse.y. This is bad, but on
+# the other hand it's good that people who use the prebuilt
+# m68k-parse.c don't get a spurious absolute path.
+m68k-parse.c: $(srcdir)/config/m68k-parse.y
+ f=$(srcdir)/config/m68k-parse.y; \
+ if [ $$f = "./config/m68k-parse.y" ]; then \
+ ln -s config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ ln config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ cp config/m68k-parse.y . >/dev/null 2>/dev/null; \
+ f=m68k-parse.y; \
+ else true; fi; \
+ $(SHELL) $(YLWRAP) "$(YACC)" $$f y.tab.c m68k-parse.c --; \
+ if [ $$f = "m68k-parse.y" ]; then \
+ rm -f m68k-parse.y; \
+ else true; fi
+m68k-parse.o: m68k-parse.c $(srcdir)/config/m68k-parse.h
+
+# Don't let the .y.h rule clobber m68k-parse.h.
+m68k-parse.h: ; @true
+$(srcdir)/config/m68k-parse.h: ; @true
+
+# The instruction table specification lexical analyzer and parser.
+
+itbl-lex.c: $(srcdir)/itbl-lex.l
+itbl-lex.o: itbl-lex.c itbl-parse.h
+
+itbl-parse.o: itbl-parse.c itbl-parse.h $(srcdir)/itbl-ops.h
+
+itbl-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+
+itbl-parse.c itbl-parse.h: $(srcdir)/itbl-parse.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/itbl-parse.y y.tab.c itbl-parse.c y.tab.h itbl-parse.h -- -d
+
+# stand-alone itbl assembler & disassembler
+
+EXTRA_PROGRAMS = itbl-test
+itbl_test_SOURCES = itbl-parse.y itbl-lex.l
+itbl_test_LDADD = itbl-test-ops.o itbl-test.o $(GASLIBS) @LEXLIB@
+
+itbl-test-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+ $(COMPILE) -o itbl-test-ops.o -DSTAND_ALONE -c $(srcdir)/itbl-ops.c
+
+itbl-test.o: $(srcdir)/testsuite/gas/all/itbl-test.c $(srcdir)/itbl-ops.h
+ $(COMPILE) -c -DSTAND_ALONE $(srcdir)/testsuite/gas/all/itbl-test.c
+
+# CGEN interface.
+
+CGEN_CPU_PREFIX = @cgen_cpu_prefix@
+
+cgen.o: cgen.c cgen.h cgen-desc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-desc.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-opc.h
+
+# Remake the info files.
+
+MOSTLYCLEANFILES = $(STAGESTUFF) core stamp-mk.com \
+ testsuite/*.o testsuite/*.out testsuite/gas.log testsuite/gas.sum \
+ testsuite/site.exp site.bak site.exp stage stage1 stage2
+
+CLEANFILES = dep.sed .tcdep .objdep .dep2 .dep1 .depa .dep .depdir
+
+.PHONY: install-exec-local install-data-local
+.PHONY: install-exec-bindir install-exec-tooldir
+
+install-exec-local: install-exec-bindir @install_tooldir@
+
+install-exec-bindir: $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(bindir)
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+install-exec-tooldir: $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(tooldir)/bin
+ n=`echo as | sed '$(transform)'`; \
+ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/as$(EXEEXT)" ]; then \
+ rm -f $(tooldir)/bin/as$(EXEEXT); \
+ ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/as$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) as-new$(EXEEXT) $(tooldir)/bin/as$(EXEEXT); \
+ else \
+ true ; \
+ fi
+
+# These exist for maintenance purposes.
+
+.PHONY: bootstrap bootstrap2 bootstrap3 stage1 stage2 stage3 comparison
+
+bootstrap: as-new
+ $(MAKE) stage1
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap2:
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap3:
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+# Copy the object files from a particular stage into a subdirectory.
+stage1:
+ -mkdir stage1
+ -mv $(STAGESTUFF) stage1
+ if [ -f stage1/as-new$(EXEEXT) -a ! -f stage1/as$(EXEEXT) ] ; then (cd stage1 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage2:
+ -mkdir stage2
+ -mv $(STAGESTUFF) stage2
+ if [ -f stage2/as-new$(EXEEXT) -a ! -f stage2/as$(EXEEXT) ] ; then (cd stage2 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage3:
+ -mkdir stage3
+ -mv $(STAGESTUFF) stage3
+ if [ -f stage3/as-new$(EXEEXT) -a ! -f stage3/as$(EXEEXT) ] ; then (cd stage3 ; ln -s as-new as$(EXEEXT)) ; fi
+
+against=stage2
+
+# This rule is derived from corresponding code in the Makefile.in for gcc.
+# The "tail +16c" is to bypass headers which may include timestamps or
+# temporary assembly file names.
+comparison:
+ x=0 ; \
+ for file in *.o ; do \
+ tail +16c ./$$file > tmp-foo1; \
+ if tail +16c ${against}/$$file > tmp-foo2 2>/dev/null ; then \
+ if cmp tmp-foo1 tmp-foo2 ; then \
+ true ; \
+ else \
+ echo $$file differs ; \
+ x=1 ; \
+ fi ; \
+ else true; fi ; \
+ done ; \
+ exit $$x
+ -rm -f tmp-foo*
+
+.PHONY: de-stage1 de-stage2 de-stage3
+
+de-stage1:
+ - (cd stage1 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage1
+
+de-stage2:
+ - (cd stage2 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage2
+
+de-stage3:
+ - (cd stage3 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage3
+
+# Automatic dependency computation. This is a real pain, because the
+# dependencies change based on target_cpu_type and obj_format. We
+# currently ignore any dependencies caused by emulation files.
+
+DEP_FILE_DEPS = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \
+ $(TARGET_CPU_HFILES) $(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES)
+
+.dep: dep.sed $(DEP_FILE_DEPS) .tcdep .objdep .dep2
+ rm -f .dep1
+ srcdir=`cd $(srcdir); pwd`; \
+ $(MAKE) DEP=$(DEP) srcdir=$${srcdir} VPATH=$${srcdir} .dep1
+ rm -rf .depdir
+ sed -f dep.sed < .dep1 > .depa
+ sed -f dep.sed < .tcdep >> .depa
+ sed -f dep.sed < .objdep >> .depa
+ sed -f dep.sed < .dep2 >> .depa
+ echo '$$(OBJS): $$(DEP_@target''_cpu_type@_@obj''_format@)' >> .depa
+ echo '$$(TARG_CPU_O): $$(TCDEP_@target''_cpu_type@_@obj''_format@)' >> .depa
+ echo '$$(OBJ_FORMAT_O): $$(OBJDEP_@target''_cpu_type@_@obj''_format@)' >> .depa
+ echo '# IF YOU PUT ANYTHING HERE IT WILL GO AWAY' >> .depa
+ $(SHELL) $(srcdir)/../move-if-change .depa .dep
+
+# This rule needs a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(MULTI_CFILES)
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ echo '' > targ-cpu.h; \
+ echo '' > obj-format.h; \
+ echo '' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) $?
+ sed -e '/IF YOU PUT ANYTHING/,$$d' < .depdir/.dep > .dep1
+ rm -f .depdir/.dep
+
+# Work out the special dependencies for the tc-*.c files.
+.tcdep: $(TARGET_CPU_CFILES)
+ rm -f .tcdepa
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '#include "opcodes/'"$${c}"'-desc.h"' > cgen-desc.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/tc-$${c}.c dummy.c; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \
+ sed -e "s/dummy.o: dummy.c/TCDEP_$${c}_$${o} =/" \
+ -e '1,/DO NOT PUT ANYTHING AFTER/d' \
+ -e '/IF YOU PUT ANYTHING/,$$d' \
+ -e '/^$$/d' < .dep >> ../.tcdepa; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'TCDEP_hppa_som = $$(srcdir)/config/tc-hppa.h subsegs.h \' >> .tcdepa
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .tcdepa
+ echo ' $$(INCDIR)/opcode/hppa.h $$(BFDDIR)/som.h' >> .tcdepa
+ # We don't try to handle all multi cases.
+ for c in $(CPU_TYPES); do \
+ $(CPU_MULTI_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ o=ecoff; \
+ $(CPU_OBJ_VALID) \
+ echo 'TCDEP_'"$${c}"'_multi = \' >> .tcdepa; \
+ echo '$$(TCDEP_'"$${c}"'_coff) \' >> .tcdepa; \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(TCDEP_'"$${c}"'_ecoff) \' >> .tcdepa; \
+ else true; fi; \
+ echo '$$(TCDEP_'"$${c}"'_elf)' >> .tcdepa; \
+ else true; fi; \
+ done
+ mv -f .tcdepa .tcdep
+
+# Work out the special dependencies for the obj-*.c files.
+.objdep: $(OBJ_FORMAT_CFILES)
+ rm -f .objdepa
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/obj-$${o}.c dummy.c; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \
+ sed -e "s/dummy.o: dummy.c/OBJDEP_$${c}_$${o} =/" \
+ -e '1,/DO NOT PUT ANYTHING AFTER/d' \
+ -e '/IF YOU PUT ANYTHING/,$$d' \
+ -e '/^$$/d' < .dep >> ../.objdepa; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'OBJDEP_hppa_som = $$(srcdir)/config/obj-som.h subsegs.h \' >> .objdepa
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .objdepa
+ echo ' $$(BFDDIR)/som.h $$(INCDIR)/aout/stab_gnu.h \' >> .objdepa
+ echo ' $$(INCDIR)/aout/stab.def' >> .objdepa
+ # We don't try to handle all multi cases.
+ for c in $(CPU_TYPES); do \
+ $(CPU_MULTI_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ o=ecoff; \
+ $(CPU_OBJ_VALID) \
+ echo 'OBJDEP_'"$${c}"'_multi = \' >> .objdepa; \
+ echo '$$(OBJDEP_'"$${c}"'_coff) \' >> .objdepa; \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(OBJDEP_'"$${c}"'_ecoff) \' >> .objdepa; \
+ else true; fi; \
+ echo '$$(OBJDEP_'"$${c}"'_elf)' >> .objdepa; \
+ else true; fi; \
+ done
+ mv -f .objdepa .objdep
+
+# Work out the dependencies for each CPU/OBJ combination.
+# Note that SOM is a special case, because it only works native.
+.dep2: $(TARGET_CPU_HFILES) $(OBJ_FORMAT_HFILES)
+ rm -f .dep2a
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > dummy.c; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \
+ sed -e "s/dummy.o: dummy.c/DEP_$${c}_$${o} =/" \
+ -e '1,/DO NOT PUT ANYTHING AFTER/d' \
+ -e '/IF YOU PUT ANYTHING/,$$d' \
+ -e '/^$$/d' < .dep >> ../.dep2a; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEP_hppa_som = $$(BFDDIR)/som.h' >> .dep2a
+ # We don't try to handle all multi cases.
+ for c in $(CPU_TYPES); do \
+ $(CPU_MULTI_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ o=ecoff; \
+ $(CPU_OBJ_VALID) \
+ echo 'DEP_'"$${c}"'_multi = \' >> .dep2a; \
+ echo '$$(DEP_'"$${c}"'_coff) \' >> .dep2a; \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEP_'"$${c}"'_ecoff) \' >> .dep2a; \
+ else true; fi; \
+ echo '$$(DEP_'"$${c}"'_elf)' >> .dep2a; \
+ else true; fi; \
+ done
+ mv -f .dep2a .dep2
+
+dep.sed: dep-in.sed config.status
+ srcdir=`cd $(srcdir); pwd`; \
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e "s!@INCDIR@!$${srcdir}/../include!" \
+ -e "s!@BFDDIR@!$${srcdir}/../bfd!" \
+ -e "s!@SRCDIR@!$${srcdir}!"
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+app.o: app.c
+as.o: as.c subsegs.h $(INCDIR)/obstack.h output-file.h \
+ sb.h macro.h
+atof-generic.o: atof-generic.c
+bignum-copy.o: bignum-copy.c
+cond.o: cond.c macro.h sb.h $(INCDIR)/obstack.h
+depend.o: depend.c
+ecoff.o: ecoff.c
+ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
+expr.o: expr.c $(INCDIR)/obstack.h
+flonum-copy.o: flonum-copy.c
+flonum-konst.o: flonum-konst.c
+flonum-mult.o: flonum-mult.c
+frags.o: frags.c subsegs.h $(INCDIR)/obstack.h
+hash.o: hash.c
+input-file.o: input-file.c input-file.h
+input-scrub.o: input-scrub.c input-file.h sb.h
+listing.o: listing.c input-file.h subsegs.h
+literal.o: literal.c subsegs.h $(INCDIR)/obstack.h
+macro.o: macro.c sb.h macro.h
+messages.o: messages.c
+output-file.o: output-file.c output-file.h
+read.o: read.c subsegs.h $(INCDIR)/obstack.h sb.h macro.h \
+ ecoff.h
+sb.o: sb.c sb.h
+stabs.o: stabs.c $(INCDIR)/obstack.h subsegs.h ecoff.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+subsegs.o: subsegs.c subsegs.h $(INCDIR)/obstack.h
+symbols.o: symbols.c $(INCDIR)/obstack.h subsegs.h
+write.o: write.c subsegs.h $(INCDIR)/obstack.h output-file.h
+gasp.o: gasp.c sb.h macro.h
+e-i386coff.o: $(srcdir)/config/e-i386coff.c emul.h \
+ emul-target.h
+e-i386elf.o: $(srcdir)/config/e-i386elf.c emul.h emul-target.h
+e-mipsecoff.o: $(srcdir)/config/e-mipsecoff.c emul.h \
+ emul-target.h
+e-mipself.o: $(srcdir)/config/e-mipself.c emul.h emul-target.h
+
+TCDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h
+TCDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h
+TCDEP_a29k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h $(INCDIR)/opcode/a29k.h
+TCDEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h ecoff.h $(INCDIR)/opcode/alpha.h \
+ $(srcdir)/config/atof-vax.c
+TCDEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/alpha.h \
+ $(srcdir)/config/atof-vax.c
+TCDEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h subsegs.h \
+ $(INCDIR)/obstack.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/opcode/alpha.h $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(srcdir)/config/atof-vax.c
+TCDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h \
+ subsegs.h $(INCDIR)/obstack.h ecoff.h $(INCDIR)/opcode/alpha.h \
+ $(srcdir)/config/atof-vax.c
+TCDEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h
+TCDEP_arc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h $(INCDIR)/elf/arc.h \
+ $(INCDIR)/elf/reloc-macros.h
+TCDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h
+TCDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h
+TCDEP_arm_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
+TCDEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h
+TCDEP_d10v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h $(INCDIR)/elf/ppc.h \
+ $(INCDIR)/elf/reloc-macros.h
+TCDEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h
+TCDEP_d30v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h
+TCDEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \
+ cgen.h
+TCDEP_fr30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \
+ cgen.h
+TCDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h
+TCDEP_h8300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h
+TCDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h
+TCDEP_h8500_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h
+TCDEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/libbfd.h \
+ $(INCDIR)/opcode/hppa.h
+TCDEP_hppa_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h $(BFDDIR)/elf32-hppa.h \
+ $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h \
+ subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libbfd.h $(INCDIR)/opcode/hppa.h
+TCDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i386.h
+TCDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h
+TCDEP_i386_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h
+TCDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/i860.h
+TCDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/i860.h
+TCDEP_i860_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h $(INCDIR)/opcode/i860.h
+TCDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+TCDEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+TCDEP_i960_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i960.h
+TCDEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \
+ cgen.h
+TCDEP_m32r_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \
+ cgen.h
+TCDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+TCDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h
+TCDEP_m68k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h $(INCDIR)/obstack.h \
+ subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+TCDEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h
+TCDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h
+TCDEP_m88k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h
+TCDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h
+TCDEP_mcore_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h \
+ $(INCDIR)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h
+TCDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h
+TCDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h \
+ itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+TCDEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h \
+ itbl-ops.h
+TCDEP_mips_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h itbl-ops.h \
+ $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h ecoff.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+TCDEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h
+TCDEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h
+TCDEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h
+TCDEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h
+TCDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ns32k.h \
+ $(INCDIR)/obstack.h
+TCDEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/ns32k.h $(INCDIR)/obstack.h
+TCDEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h $(INCDIR)/opcode/ns32k.h \
+ $(INCDIR)/obstack.h
+TCDEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h
+TCDEP_ppc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h $(INCDIR)/elf/ppc.h \
+ $(INCDIR)/elf/reloc-macros.h
+TCDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h
+TCDEP_sh_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h
+TCDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h
+TCDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h
+TCDEP_sparc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h $(INCDIR)/elf/sparc.h \
+ $(INCDIR)/elf/reloc-macros.h
+TCDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/tahoe.h
+TCDEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+TCDEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/tahoe.h
+TCDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h
+TCDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h
+TCDEP_tic30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h $(INCDIR)/opcode/tic30.h
+TCDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic80.h
+TCDEP_tic80_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h $(INCDIR)/opcode/tic80.h
+TCDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+TCDEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/vax-inst.h $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+TCDEP_vax_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+TCDEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+TCDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+TCDEP_w65_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+TCDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h
+TCDEP_v850_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h
+TCDEP_z8k_coff = $(srcdir)/../opcodes/z8k-opc.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+TCDEP_z8k_elf = $(srcdir)/../opcodes/z8k-opc.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h
+TCDEP_hppa_som = $(srcdir)/config/tc-hppa.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h \
+ $(BFDDIR)/som.h
+TCDEP_i386_multi = $(TCDEP_i386_coff) $(TCDEP_i386_elf)
+TCDEP_mips_multi = $(TCDEP_mips_coff) $(TCDEP_mips_ecoff) \
+ $(TCDEP_mips_elf)
+OBJDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_a29k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(BFDDIR)/libecoff.h
+OBJDEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h subsegs.h \
+ $(INCDIR)/obstack.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+OBJDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h
+OBJDEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_arc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_arm_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_d10v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_d30v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_fr30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_h8300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_h8500_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_hppa_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h $(BFDDIR)/elf32-hppa.h \
+ $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_i386_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_i860_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/obstack.h
+OBJDEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_i960_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_m32r_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_m68k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_m68k_hp300 = $(srcdir)/config/obj-aout.c $(srcdir)/config/obj-hp300.h \
+ $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_m88k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_mcore_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(BFDDIR)/libecoff.h
+OBJDEP_mips_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h subsegs.h \
+ $(INCDIR)/obstack.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/aout/aout64.h
+OBJDEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_ppc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+OBJDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_sh_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_sparc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_tic30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_tic80_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+OBJDEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_vax_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def subsegs.h \
+ $(INCDIR)/obstack.h
+OBJDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_w65_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+OBJDEP_v850_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+OBJDEP_z8k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+OBJDEP_hppa_som = $(srcdir)/config/obj-som.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/som.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+OBJDEP_i386_multi = $(OBJDEP_i386_coff) $(OBJDEP_i386_elf)
+OBJDEP_mips_multi = $(OBJDEP_mips_coff) $(OBJDEP_mips_ecoff) \
+ $(OBJDEP_mips_elf)
+DEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_a29k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h
+DEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+DEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h
+DEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h
+DEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_arc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h
+DEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_arm_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h
+DEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_d10v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h
+DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_d30v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h
+DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_fr30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h
+DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_h8300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h
+DEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_h8500_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h
+DEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_hppa_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h $(BFDDIR)/elf32-hppa.h \
+ $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h
+DEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_i386_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h
+DEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_i860_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h
+DEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h
+DEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_i960_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h
+DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_m32r_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h
+DEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_m68k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h
+DEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_m88k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h
+DEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_mcore_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h
+DEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+DEP_mips_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h
+DEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h
+DEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h
+DEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h
+DEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_ppc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h
+DEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_sh_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h
+DEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_sparc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h
+DEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h
+DEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_tic30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h
+DEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_tic80_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h
+DEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+DEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_vax_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h
+DEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+DEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_w65_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h
+DEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+DEP_v850_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h
+DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+DEP_z8k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h
+DEP_hppa_som = $(BFDDIR)/som.h
+DEP_i386_multi = $(DEP_i386_coff) $(DEP_i386_elf)
+DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \
+ $(DEP_mips_elf)
+$(OBJS): $(DEP_@target_cpu_type@_@obj_format@)
+$(TARG_CPU_O): $(TCDEP_@target_cpu_type@_@obj_format@)
+$(OBJ_FORMAT_O): $(OBJDEP_@target_cpu_type@_@obj_format@)
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/gas/Makefile.in b/gas/Makefile.in
new file mode 100644
index 00000000000..244fff2ef31
--- /dev/null
+++ b/gas/Makefile.in
@@ -0,0 +1,2488 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+ALL_OBJ_DEPS = @ALL_OBJ_DEPS@
+AS = @AS@
+BFDLIB = @BFDLIB@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OPCODES_LIB = @OPCODES_LIB@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+atof = @atof@
+cgen_cpu_prefix = @cgen_cpu_prefix@
+extra_objects = @extra_objects@
+install_tooldir = @install_tooldir@
+l = @l@
+obj_format = @obj_format@
+target_cpu_type = @target_cpu_type@
+te_file = @te_file@
+
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+SUBDIRS = doc po
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi`
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi`
+
+DEP = $(srcdir)/../mkdep
+
+TARG_CPU = @target_cpu_type@
+TARG_CPU_C = $(srcdir)/config/tc-@target_cpu_type@.c
+TARG_CPU_O = tc-@target_cpu_type@.o
+TARG_CPU_H = $(srcdir)/config/tc-@target_cpu_type@.h
+OBJ_FORMAT_C = $(srcdir)/config/obj-@obj_format@.c
+OBJ_FORMAT_O = obj-@obj_format@.o
+OBJ_FORMAT_H = $(srcdir)/config/obj-@obj_format@.h
+TARG_ENV_H = $(srcdir)/config/te-@te_file@.h
+ATOF_TARG_C = $(srcdir)/config/atof-@atof@.c
+ATOF_TARG_O = atof-@atof@.o
+
+# use @target_cpu_type@ for refering to configured target name
+IT_HDRS = itbl-parse.h $(srcdir)/itbl-ops.h
+IT_SRCS = itbl-parse.c itbl-lex.c $(srcdir)/itbl-ops.c
+IT_DEPS = $(srcdir)/itbl-parse.y $(srcdir)/itbl-lex.l $(srcdir)/config/itbl-@target_cpu_type@.h
+IT_OBJS = itbl-parse.o itbl-lex.o itbl-ops.o
+
+# CPU types. This is only used for dependency information.
+
+CPU_TYPES = \
+ a29k \
+ alpha \
+ arc \
+ arm \
+ d10v \
+ d30v \
+ fr30 \
+ h8300 \
+ h8500 \
+ hppa \
+ i386 \
+ i860 \
+ i960 \
+ m32r \
+ m68k \
+ m88k \
+ mcore \
+ mips \
+ mn10200 \
+ mn10300 \
+ ns32k \
+ ppc \
+ sh \
+ sparc \
+ tahoe \
+ tic30 \
+ tic80 \
+ vax \
+ w65 \
+ v850 \
+ z8k
+
+
+# Object format types. This is only used for dependency information.
+# We deliberately omit som, since it does not work as a cross assembler.
+
+OBJ_FORMATS = \
+ aout \
+ bout \
+ coff \
+ ecoff \
+ elf \
+ evax \
+ hp300 \
+ ieee \
+ vms
+
+
+# This is an sh case which sets valid according to whether the CPU
+# type in the shell variable c and the OS type in the shell variable o
+# are supported. This helps cuts down on the amount of dependency
+# information.
+
+CPU_OBJ_VALID = \
+ valid= ; \
+ case $$o in \
+ aout) \
+ case $$c in \
+ a29k | arm | i386 | i860 | m68k | mips | ns32k | sparc | tahoe | tic30 | vax) \
+ valid=yes ;; \
+ esac ;; \
+ bout) \
+ case $$c in \
+ i960) valid=yes ;; \
+ esac ;; \
+ coff) valid=yes ;; \
+ ecoff) \
+ case $$c in \
+ mips | alpha) valid=yes ;; \
+ esac ;; \
+ elf) valid=yes ;; \
+ evax) \
+ case $$c in \
+ alpha) valid=yes ;; \
+ esac ;; \
+ hp300) \
+ case $$c in \
+ m68k) valid=yes ;; \
+ esac ;; \
+ vms) \
+ case $$c in \
+ vax) valid=yes ;; \
+ esac ;; \
+ esac;
+
+
+# This is like CPU_OBJ_VALID, for the obj=multi case.
+
+CPU_MULTI_VALID = \
+ valid= ; \
+ case $$c in \
+ i386 | mips) valid=yes ;; \
+ esac;
+
+
+# Regular source files.
+
+GAS_CFILES = \
+ app.c \
+ as.c \
+ atof-generic.c \
+ bignum-copy.c \
+ cond.c \
+ depend.c \
+ ecoff.c \
+ ehopt.c \
+ expr.c \
+ flonum-copy.c \
+ flonum-konst.c \
+ flonum-mult.c \
+ frags.c \
+ hash.c \
+ input-file.c \
+ input-scrub.c \
+ listing.c \
+ literal.c \
+ macro.c \
+ messages.c \
+ output-file.c \
+ read.c \
+ sb.c \
+ stabs.c \
+ subsegs.c \
+ symbols.c \
+ write.c
+
+
+CFILES = $(GAS_CFILES) gasp.c itbl-ops.c
+
+HFILES = \
+ as.h \
+ asintl.h \
+ bignum.h \
+ bit_fix.h \
+ cgen.h \
+ ecoff.h \
+ emul-target.h \
+ emul.h \
+ expr.h \
+ flonum.h \
+ frags.h \
+ hash.h \
+ input-file.h \
+ itbl-ops.h \
+ listing.h \
+ macro.h \
+ obj.h \
+ output-file.h \
+ read.h \
+ sb.h \
+ struc-symbol.h \
+ subsegs.h \
+ symbols.h \
+ tc.h \
+ write.h
+
+
+# CPU files in config.
+
+TARGET_CPU_CFILES = \
+ config/tc-a29k.c \
+ config/tc-alpha.c \
+ config/tc-arc.c \
+ config/tc-arm.c \
+ config/tc-d10v.c \
+ config/tc-d30v.c \
+ config/tc-h8300.c \
+ config/tc-h8500.c \
+ config/tc-hppa.c \
+ config/tc-i386.c \
+ config/tc-i860.c \
+ config/tc-i960.c \
+ config/tc-m32r.c \
+ config/tc-m68k.c \
+ config/tc-m88k.c \
+ config/tc-mcore.c \
+ config/tc-mips.c \
+ config/tc-mn10200.c \
+ config/tc-mn10300.c \
+ config/tc-ns32k.c \
+ config/tc-ppc.c \
+ config/tc-sh.c \
+ config/tc-sparc.c \
+ config/tc-tahoe.c \
+ config/tc-tic30.c \
+ config/tc-tic80.c \
+ config/tc-vax.c \
+ config/tc-w65.c \
+ config/tc-v850.c \
+ config/tc-z8k.c
+
+
+TARGET_CPU_HFILES = \
+ config/tc-a29k.h \
+ config/tc-alpha.h \
+ config/tc-arc.h \
+ config/tc-arm.h \
+ config/tc-d10v.h \
+ config/tc-d30v.h \
+ config/tc-h8300.h \
+ config/tc-h8500.h \
+ config/tc-hppa.h \
+ config/tc-i386.h \
+ config/tc-i860.h \
+ config/tc-i960.h \
+ config/tc-m32r.h \
+ config/tc-m68k.h \
+ config/tc-m88k.h \
+ config/tc-mcore.h \
+ config/tc-mips.h \
+ config/tc-mn10200.h \
+ config/tc-mn10300.h \
+ config/tc-ns32k.h \
+ config/tc-ppc.h \
+ config/tc-sh.h \
+ config/tc-sparc.h \
+ config/tc-tahoe.h \
+ config/tc-tic30.h \
+ config/tc-tic80.h \
+ config/tc-vax.h \
+ config/tc-w65.h \
+ config/tc-v850.h \
+ config/tc-z8k.h
+
+
+# OBJ files in config
+
+OBJ_FORMAT_CFILES = \
+ config/obj-aout.c \
+ config/obj-bout.c \
+ config/obj-coff.c \
+ config/obj-ecoff.c \
+ config/obj-elf.c \
+ config/obj-evax.c \
+ config/obj-hp300.c \
+ config/obj-ieee.c \
+ config/obj-som.c \
+ config/obj-vms.c
+
+
+OBJ_FORMAT_HFILES = \
+ config/obj-aout.h \
+ config/obj-bout.h \
+ config/obj-coff.h \
+ config/obj-ecoff.h \
+ config/obj-elf.h \
+ config/obj-evax.h \
+ config/obj-hp300.h \
+ config/obj-ieee.h \
+ config/obj-som.h \
+ config/obj-vms.h
+
+
+# Emulation header files in config
+
+TARG_ENV_HFILES = \
+ config/te-386bsd.h \
+ config/te-aux.h \
+ config/te-delta.h \
+ config/te-delt88.h \
+ config/te-dpx2.h \
+ config/te-dynix.h \
+ config/te-generic.h \
+ config/te-go32.h \
+ config/te-hp300.h \
+ config/te-hppa.h \
+ config/te-i386aix.h \
+ config/te-ic960.h \
+ config/te-linux.h \
+ config/te-lnews.h \
+ config/te-lynx.h \
+ config/te-mach.h \
+ config/te-macos.h \
+ config/te-multi.h \
+ config/te-nbsd.h \
+ config/te-nbsd532.h \
+ config/te-pc532mach.h \
+ config/te-pe.h \
+ config/te-ppcnw.h \
+ config/te-psos.h \
+ config/te-riscix.h \
+ config/te-sparcaout.h \
+ config/te-sun3.h \
+ config/te-svr4.h \
+ config/te-sysv32.h
+
+
+# Multi files in config
+
+MULTI_CFILES = \
+ config/e-i386coff.c \
+ config/e-i386elf.c \
+ config/e-mipsecoff.c \
+ config/e-mipself.c
+
+
+CONFIG_OBJS = \
+ $(TARG_CPU_O) \
+ $(OBJ_FORMAT_O) \
+ $(ATOF_TARG_O) \
+ $(extra_objects)
+
+
+GENERIC_OBJS = \
+ app.o \
+ as.o \
+ atof-generic.o \
+ bignum-copy.o \
+ cond.o \
+ depend.o \
+ ehopt.o \
+ expr.o \
+ flonum-konst.o \
+ flonum-copy.o \
+ flonum-mult.o \
+ frags.o \
+ hash.o \
+ input-file.o \
+ input-scrub.o \
+ literal.o \
+ messages.o \
+ output-file.o \
+ read.o \
+ subsegs.o \
+ symbols.o \
+ write.o \
+ listing.o \
+ ecoff.o \
+ stabs.o \
+ sb.o \
+ macro.o
+
+
+OBJS = $(CONFIG_OBJS) $(GENERIC_OBJS)
+
+POTFILES = $(MULTI_CFILES) $(TARGET_ENV_HFILES) $(OBJ_FORMAT_HFILES) \
+ $(OBJ_FORMAT_CFILES) $(TARGET_CPU_HFILES) $(TARGET_CPU_CFILES) \
+ $(HFILES) $(CFILES) $(GAS_CFILES)
+
+
+noinst_PROGRAMS = as-new gasp-new
+noinst_SCRIPTS = .gdbinit
+
+EXTRA_DIST = make-gas.com
+
+DISTSTUFF = make-gas.com m68k-parse.c itbl-parse.c itbl-parse.h itbl-lex.c
+
+DISTCLEANFILES = targ-cpu.h obj-format.h targ-env.h itbl-cpu.h cgen-desc.h
+
+# Now figure out from those variables how to compile and link.
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+
+# This is the variable actually used when we compile.
+# Specify the directories to be searched for header files.
+# Both . and srcdir are used, in that order,
+# so that tm.h and config.h will be found in the compilation
+# subdirectory rather than in the source directory.
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(srcdir)/config -I$(INCDIR) -I$(srcdir)/.. -I$(BFDDIR) -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+# This should be parallel to INCLUDES, but should replace $(srcdir)
+# with $${srcdir}, and should work in a subdirectory. This is used
+# when building dependencies, because the dependency building is done
+# in a subdirectory.
+DEP_INCLUDES = -D_GNU_SOURCE -I.. -I$${srcdir} -I../../bfd -I$${srcdir}/config -I$${srcdir}/../include -I$${srcdir}/.. -I$${srcdir}/../bfd -I$${srcdir}/../intl -I../../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+# How to link with both our special library facilities
+# and the system's installed libraries.
+
+GASLIBS = @OPCODES_LIB@ @BFDLIB@ ../libiberty/libiberty.a
+
+# Files to be copied away after each stage in building.
+STAGESTUFF = *.o $(noinst_PROGRAMS)
+
+as_new_SOURCES = $(GAS_CFILES)
+as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLLIBS)
+
+as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
+ $(extra_objects) $(GASLIBS) $(INTLDEPS)
+
+
+gasp_new_SOURCES = gasp.c macro.c sb.c hash.c
+gasp_new_LDADD = ../libiberty/libiberty.a $(INTLLIBS)
+gasp_new_DEPENDENCIES = ../libiberty/libiberty.a $(INTLDEPS)
+
+EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
+ echo $${rootme}/../expect/expect ; \
+ else echo expect ; fi`
+
+
+RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \
+ echo $${srcdir}/../dejagnu/runtest ; else echo runtest; \
+ fi`
+
+RUNTESTFLAGS =
+
+# The m68k operand parser.
+
+EXTRA_as_new_SOURCES = config/m68k-parse.y
+
+# stand-alone itbl assembler & disassembler
+
+EXTRA_PROGRAMS = itbl-test
+itbl_test_SOURCES = itbl-parse.y itbl-lex.l
+itbl_test_LDADD = itbl-test-ops.o itbl-test.o $(GASLIBS) @LEXLIB@
+
+# CGEN interface.
+
+CGEN_CPU_PREFIX = @cgen_cpu_prefix@
+
+# Remake the info files.
+
+MOSTLYCLEANFILES = $(STAGESTUFF) core stamp-mk.com \
+ testsuite/*.o testsuite/*.out testsuite/gas.log testsuite/gas.sum \
+ testsuite/site.exp site.bak site.exp stage stage1 stage2
+
+
+CLEANFILES = dep.sed .tcdep .objdep .dep2 .dep1 .depa .dep .depdir
+
+against = stage2
+
+# Automatic dependency computation. This is a real pain, because the
+# dependencies change based on target_cpu_type and obj_format. We
+# currently ignore any dependencies caused by emulation files.
+
+DEP_FILE_DEPS = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \
+ $(TARGET_CPU_HFILES) $(OBJ_FORMAT_CFILES) $(OBJ_FORMAT_HFILES)
+
+
+TCDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h
+
+TCDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/a29k.h
+
+TCDEP_a29k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h $(INCDIR)/opcode/a29k.h
+
+TCDEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h ecoff.h $(INCDIR)/opcode/alpha.h \
+ $(srcdir)/config/atof-vax.c
+
+TCDEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/alpha.h \
+ $(srcdir)/config/atof-vax.c
+
+TCDEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h subsegs.h \
+ $(INCDIR)/obstack.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/opcode/alpha.h $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(srcdir)/config/atof-vax.c
+
+TCDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h \
+ subsegs.h $(INCDIR)/obstack.h ecoff.h $(INCDIR)/opcode/alpha.h \
+ $(srcdir)/config/atof-vax.c
+
+TCDEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h \
+ $(INCDIR)/elf/arc.h $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_arc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/arc.h $(INCDIR)/elf/arc.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h
+
+TCDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h
+
+TCDEP_arm_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h \
+ $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_d10v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/d10v.h $(INCDIR)/elf/ppc.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h
+
+TCDEP_d30v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/d30v.h
+
+TCDEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \
+ cgen.h
+
+TCDEP_fr30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/fr30-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/fr30-opc.h \
+ cgen.h
+
+TCDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h
+
+TCDEP_h8300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h
+
+TCDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h
+
+TCDEP_h8500_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/h8500-opc.h
+
+TCDEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/libbfd.h \
+ $(INCDIR)/opcode/hppa.h
+
+TCDEP_hppa_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h $(BFDDIR)/elf32-hppa.h \
+ $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h \
+ subsegs.h $(INCDIR)/obstack.h $(BFDDIR)/libbfd.h $(INCDIR)/opcode/hppa.h
+
+TCDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i386.h
+
+TCDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h
+
+TCDEP_i386_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/i386.h
+
+TCDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/i860.h
+
+TCDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/i860.h
+
+TCDEP_i860_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h $(INCDIR)/opcode/i860.h
+
+TCDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+
+TCDEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h $(INCDIR)/opcode/i960.h
+
+TCDEP_i960_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/i960.h
+
+TCDEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \
+ cgen.h
+
+TCDEP_m32r_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/symcat.h $(srcdir)/../opcodes/m32r-desc.h \
+ $(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/m32r-opc.h \
+ cgen.h
+
+TCDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+
+TCDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h
+
+TCDEP_m68k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h $(INCDIR)/obstack.h \
+ subsegs.h $(INCDIR)/opcode/m68k.h $(srcdir)/config/m68k-parse.h
+
+TCDEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h $(INCDIR)/opcode/m68k.h \
+ $(srcdir)/config/m68k-parse.h
+
+TCDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h
+
+TCDEP_m88k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/config/m88k-opcode.h
+
+TCDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h
+
+TCDEP_mcore_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/mcore-opc.h \
+ $(INCDIR)/elf/mcore.h $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/mips.h itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h
+
+TCDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h \
+ itbl-ops.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+TCDEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h \
+ itbl-ops.h
+
+TCDEP_mips_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/mips.h itbl-ops.h \
+ $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h ecoff.h \
+ $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+TCDEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h
+
+TCDEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10200.h
+
+TCDEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h
+
+TCDEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/mn10300.h
+
+TCDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/ns32k.h \
+ $(INCDIR)/obstack.h
+
+TCDEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/opcode/ns32k.h $(INCDIR)/obstack.h
+
+TCDEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h $(INCDIR)/opcode/ns32k.h \
+ $(INCDIR)/obstack.h
+
+TCDEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h
+
+TCDEP_ppc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/ppc.h $(INCDIR)/elf/ppc.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h
+
+TCDEP_sh_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/sh-opc.h
+
+TCDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h
+
+TCDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h
+
+TCDEP_sparc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/sparc.h $(INCDIR)/elf/sparc.h \
+ $(INCDIR)/elf/reloc-macros.h
+
+TCDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/tahoe.h
+
+TCDEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/tahoe.h
+
+TCDEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/tahoe.h
+
+TCDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h
+
+TCDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic30.h
+
+TCDEP_tic30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h $(INCDIR)/opcode/tic30.h
+
+TCDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/opcode/tic80.h
+
+TCDEP_tic80_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h $(INCDIR)/opcode/tic80.h
+
+TCDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+
+TCDEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(srcdir)/config/vax-inst.h $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+
+TCDEP_vax_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+
+TCDEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(srcdir)/config/vax-inst.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/vax.h
+
+TCDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+
+TCDEP_w65_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h subsegs.h \
+ $(INCDIR)/obstack.h $(srcdir)/../opcodes/w65-opc.h
+
+TCDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h
+
+TCDEP_v850_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/v850.h
+
+TCDEP_z8k_coff = $(srcdir)/../opcodes/z8k-opc.h $(srcdir)/config/obj-coff.h \
+ $(srcdir)/config/tc-z8k.h $(INCDIR)/coff/internal.h \
+ $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+TCDEP_z8k_elf = $(srcdir)/../opcodes/z8k-opc.h $(srcdir)/config/obj-elf.h \
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h
+
+TCDEP_hppa_som = $(srcdir)/config/tc-hppa.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h \
+ $(BFDDIR)/som.h
+
+TCDEP_i386_multi = $(TCDEP_i386_coff) $(TCDEP_i386_elf)
+TCDEP_mips_multi = $(TCDEP_mips_coff) $(TCDEP_mips_ecoff) \
+ $(TCDEP_mips_elf)
+
+OBJDEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_a29k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(BFDDIR)/libecoff.h
+
+OBJDEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h subsegs.h \
+ $(INCDIR)/obstack.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/elf/alpha.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+
+OBJDEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h
+OBJDEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_arc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_arm_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_d10v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_d30v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_fr30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_h8300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_h8500_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_hppa_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h $(BFDDIR)/elf32-hppa.h \
+ $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h \
+ subsegs.h $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_i386_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_i860_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_i960_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_m32r_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_m68k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_m68k_hp300 = $(srcdir)/config/obj-aout.c $(srcdir)/config/obj-hp300.h \
+ $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_m88k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_mcore_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(BFDDIR)/libecoff.h
+
+OBJDEP_mips_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h subsegs.h \
+ $(INCDIR)/obstack.h ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
+ $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_ppc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h \
+ $(INCDIR)/aout/aout64.h
+
+OBJDEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_sh_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_sparc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_tic30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_tic80_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_vax_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def subsegs.h \
+ $(INCDIR)/obstack.h
+
+OBJDEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_w65_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_v850_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h subsegs.h
+
+OBJDEP_z8k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/aout/aout64.h
+
+OBJDEP_hppa_som = $(srcdir)/config/obj-som.h subsegs.h \
+ $(INCDIR)/obstack.h $(BFDDIR)/libhppa.h $(BFDDIR)/som.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+
+OBJDEP_i386_multi = $(OBJDEP_i386_coff) $(OBJDEP_i386_elf)
+OBJDEP_mips_multi = $(OBJDEP_mips_coff) $(OBJDEP_mips_ecoff) \
+ $(OBJDEP_mips_elf)
+
+DEP_a29k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-a29k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_a29k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-a29k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/a29k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_a29k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-a29k.h
+
+DEP_alpha_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-alpha.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+DEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-alpha.h
+
+DEP_alpha_evax = $(srcdir)/config/obj-evax.h $(srcdir)/config/tc-alpha.h
+DEP_arc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arc.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_arc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arc.h
+
+DEP_arm_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-arm.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_arm_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-arm.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/arm.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_arm_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-arm.h
+
+DEP_d10v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d10v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_d10v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d10v.h
+
+DEP_d30v_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-d30v.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_d30v_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-d30v.h
+
+DEP_fr30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-fr30.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_fr30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-fr30.h
+
+DEP_h8300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8300.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8300.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_h8300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h
+
+DEP_h8500_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-h8500.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/h8500.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_h8500_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8500.h
+
+DEP_hppa_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-hppa.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_hppa_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-hppa.h $(BFDDIR)/elf32-hppa.h \
+ $(BFDDIR)/libhppa.h $(INCDIR)/elf/hppa.h $(INCDIR)/elf/reloc-macros.h
+
+DEP_i386_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i386.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_i386_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i386.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i386.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_i386_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h
+
+DEP_i860_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-i860.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_i860_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i860.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_i860_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h
+
+DEP_i960_bout = $(srcdir)/config/obj-bout.h $(srcdir)/config/tc-i960.h
+DEP_i960_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-i960.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/i960.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_i960_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i960.h
+
+DEP_m32r_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m32r.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_m32r_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m32r.h
+
+DEP_m68k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-m68k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_m68k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m68k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m68k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_m68k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m68k.h
+
+DEP_m68k_hp300 = $(srcdir)/config/obj-hp300.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-m68k.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_m88k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-m88k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/m88k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_m88k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-m88k.h
+
+DEP_mcore_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mcore.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/mcore.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_mcore_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mcore.h
+
+DEP_mips_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-mips.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_mips_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mips.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_mips_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-mips.h \
+ ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
+
+DEP_mips_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mips.h
+
+DEP_mn10200_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10200.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_mn10200_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10200.h
+
+DEP_mn10300_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mn10300.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_mn10300_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mn10300.h
+
+DEP_ns32k_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-ns32k.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_ns32k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ns32k.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_ns32k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ns32k.h
+
+DEP_ppc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-ppc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/rs6000.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_ppc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-ppc.h
+
+DEP_sh_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sh.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sh.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_sh_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sh.h
+
+DEP_sparc_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-sparc.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_sparc_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-sparc.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/sparc.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_sparc_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h
+
+DEP_tahoe_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tahoe.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_tahoe_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tahoe.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_tahoe_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tahoe.h
+
+DEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic30.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_tic30_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic30.h
+
+DEP_tic80_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic80.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/tic80.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_tic80_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-tic80.h
+
+DEP_vax_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-vax.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+
+DEP_vax_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_vax_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-vax.h
+
+DEP_vax_vms = $(srcdir)/config/obj-vms.h $(srcdir)/config/tc-vax.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+
+DEP_w65_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-w65.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/w65.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_w65_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-w65.h
+
+DEP_v850_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-v850.h \
+ $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h
+
+DEP_v850_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-v850.h
+
+DEP_z8k_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-z8k.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/z8k.h $(BFDDIR)/libcoff.h \
+ $(INCDIR)/bfdlink.h
+
+DEP_z8k_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(srcdir)/config/tc-z8k.h
+
+DEP_hppa_som = $(BFDDIR)/som.h
+DEP_i386_multi = $(DEP_i386_coff) $(DEP_i386_elf)
+DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \
+ $(DEP_mips_elf)
+
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = .gdbinit
+noinst_PROGRAMS = as-new$(EXEEXT) gasp-new$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+itbl_test_OBJECTS = itbl-parse.o itbl-lex.o
+itbl_test_DEPENDENCIES = itbl-test-ops.o itbl-test.o \
+../libiberty/libiberty.a
+itbl_test_LDFLAGS =
+as_new_OBJECTS = app.o as.o atof-generic.o bignum-copy.o cond.o \
+depend.o ecoff.o ehopt.o expr.o flonum-copy.o flonum-konst.o \
+flonum-mult.o frags.o hash.o input-file.o input-scrub.o listing.o \
+literal.o macro.o messages.o output-file.o read.o sb.o stabs.o \
+subsegs.o symbols.o write.o
+as_new_LDFLAGS =
+gasp_new_OBJECTS = gasp.o macro.o sb.o hash.o
+gasp_new_LDFLAGS =
+SCRIPTS = $(noinst_SCRIPTS)
+
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LEXLIB = @LEXLIB@
+YLWRAP = $(top_srcdir)/../ylwrap
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = README ./stamp-h.in COPYING ChangeLog Makefile.am \
+Makefile.in NEWS acinclude.m4 aclocal.m4 config.in config/m68k-parse.c \
+configure configure.in gdbinit.in itbl-lex.c itbl-parse.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(itbl_test_SOURCES) $(as_new_SOURCES) $(EXTRA_as_new_SOURCES) $(gasp_new_SOURCES)
+OBJECTS = $(itbl_test_OBJECTS) $(as_new_OBJECTS) $(gasp_new_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .l .lo .o .s .y
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+.gdbinit: $(top_builddir)/config.status gdbinit.in
+ cd $(top_builddir) && CONFIG_FILES=$@:gdbinit.in CONFIG_HEADERS= $(SHELL) ./config.status
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+itbl-test$(EXEEXT): $(itbl_test_OBJECTS) $(itbl_test_DEPENDENCIES)
+ @rm -f itbl-test$(EXEEXT)
+ $(LINK) $(itbl_test_LDFLAGS) $(itbl_test_OBJECTS) $(itbl_test_LDADD) $(LIBS)
+
+as-new$(EXEEXT): $(as_new_OBJECTS) $(as_new_DEPENDENCIES)
+ @rm -f as-new$(EXEEXT)
+ $(LINK) $(as_new_LDFLAGS) $(as_new_OBJECTS) $(as_new_LDADD) $(LIBS)
+
+gasp-new$(EXEEXT): $(gasp_new_OBJECTS) $(gasp_new_DEPENDENCIES)
+ @rm -f gasp-new$(EXEEXT)
+ $(LINK) $(gasp_new_LDFLAGS) $(gasp_new_OBJECTS) $(gasp_new_LDADD) $(LIBS)
+.l.c:
+ $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
+.y.c:
+ $(SHELL) $(YLWRAP) "$(YACC)" $< y.tab.c $*.c y.tab.h $*.h -- $(AM_YFLAGS) $(YFLAGS)
+config/m68k-parse.h: config/m68k-parse.c
+itbl-parse.h: itbl-parse.c
+
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+
+DEJATOOL = $(PACKAGE)
+
+RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @test ! -f site.bak || rm -f site.bak
+ @echo '## these variables are automatically generated by make ##' > $@-t
+ @echo '# Do not edit here. If you wish to override these values' >> $@-t
+ @echo '# edit the last section' >> $@-t
+ @echo 'set tool $(DEJATOOL)' >> $@-t
+ @echo 'set srcdir $(srcdir)' >> $@-t
+ @echo 'set objdir' `pwd` >> $@-t
+ @echo 'set host_alias $(host_alias)' >> $@-t
+ @echo 'set host_triplet $(host_triplet)' >> $@-t
+ @echo 'set target_alias $(target_alias)' >> $@-t
+ @echo 'set target_triplet $(target_triplet)' >> $@-t
+ @echo 'set build_alias $(build_alias)' >> $@-t
+ @echo 'set build_triplet $(build_triplet)' >> $@-t
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t
+ @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv $@-t site.exp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-exec-local
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ -test -z "itbl-lexlconfig/m68k-parsehconfig/m68k-parsecitbl-parsehitbl-parsec" || rm -f itbl-lexl config/m68k-parseh config/m68k-parsec itbl-parseh itbl-parsec
+mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \
+ clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir check-DEJAGNU \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-info-am install-info all-recursive-am install-exec-local \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+$(srcdir)/make-gas.com: stamp-mk.com
+stamp-mk.com: vmsconf.sh Makefile
+ sh $(srcdir)/vmsconf.sh $(GENERIC_OBJS) > new-make.com
+ $(SHELL) $(srcdir)/../move-if-change new-make.com $(srcdir)/make-gas.com
+ touch stamp-mk.com
+diststuff: $(DISTSTUFF) info
+
+$(OBJS): @ALL_OBJ_DEPS@
+
+# Stuff that every object file depends upon. If anything is removed
+# from this list, remove it from dep-in.sed as well.
+$(OBJS): config.h as.h $(TARG_ENV_H) $(OBJ_FORMAT_H) $(TARG_CPU_H) flonum.h \
+ expr.h struc-symbol.h write.h frags.h hash.h read.h symbols.h tc.h \
+ obj.h listing.h bignum.h bit_fix.h $(INCDIR)/libiberty.h asintl.h
+
+check-DEJAGNU: site.exp
+ if [ -d testsuite ]; then \
+ true; \
+ else \
+ mkdir testsuite; \
+ fi
+ rm -f testsuite/site.exp
+ cp site.exp testsuite/site.exp
+ rootme=`pwd`; export rootme; \
+ srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ cd testsuite; \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcdir}/testsuite \
+ $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+# The implicit .c.o rule doesn't work for these, perhaps because of
+# the variables, or perhaps because the sources are not on vpath.
+$(TARG_CPU_O): $(TARG_CPU_C) $(TARG_CPU_DEP_@target_cpu_type@)
+ $(COMPILE) -c $(TARG_CPU_C)
+$(ATOF_TARG_O): $(ATOF_TARG_C)
+ $(COMPILE) -c $(ATOF_TARG_C)
+
+# ecoff.c only has full dependencies when ECOFF_DEBUGGING is defined,
+# so the automatic dependency stuff doesn't work.
+ecoff.o : ecoff.c ecoff.h $(INCDIR)/coff/internal.h $(INCDIR)/coff/sym.h \
+ $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/symconst.h \
+ $(INCDIR)/aout/stab_gnu.h
+
+# We need all these explicit rules for the multi stuff. Because of
+# these rules, we don't need one for OBJ_FORMAT_O.
+
+obj-aout.o : $(srcdir)/config/obj-aout.c
+ $(COMPILE) -c $(srcdir)/config/obj-aout.c
+obj-bout.o : $(srcdir)/config/obj-bout.c
+ $(COMPILE) -c $(srcdir)/config/obj-bout.c
+obj-coff.o: $(srcdir)/config/obj-coff.c
+ $(COMPILE) -c $(srcdir)/config/obj-coff.c
+obj-ecoff.o : $(srcdir)/config/obj-ecoff.c
+ $(COMPILE) -c $(srcdir)/config/obj-ecoff.c
+obj-elf.o : $(srcdir)/config/obj-elf.c
+ $(COMPILE) -c $(srcdir)/config/obj-elf.c
+obj-evax.o : $(srcdir)/config/obj-evax.c
+ $(COMPILE) -c $(srcdir)/config/obj-evax.c
+obj-hp300.o : $(srcdir)/config/obj-hp300.c
+ $(COMPILE) -c $(srcdir)/config/obj-hp300.c
+obj-ieee.o : $(srcdir)/config/obj-ieee.c
+ $(COMPILE) -c $(srcdir)/config/obj-ieee.c
+obj-multi.o : $(srcdir)/config/obj-multi.c
+ $(COMPILE) -c $(srcdir)/config/obj-multi.c
+obj-som.o : $(srcdir)/config/obj-som.c
+ $(COMPILE) -c $(srcdir)/config/obj-som.c
+obj-vms.o : $(srcdir)/config/obj-vms.c
+ $(COMPILE) -c $(srcdir)/config/obj-vms.c
+
+e-mipself.o : $(srcdir)/config/e-mipself.c
+ $(COMPILE) -c $(srcdir)/config/e-mipself.c
+e-mipsecoff.o : $(srcdir)/config/e-mipsecoff.c
+ $(COMPILE) -c $(srcdir)/config/e-mipsecoff.c
+e-i386coff.o: $(srcdir)/config/e-i386coff.c
+ $(COMPILE) -c $(srcdir)/config/e-i386coff.c
+e-i386elf.o: $(srcdir)/config/e-i386elf.c
+ $(COMPILE) -c $(srcdir)/config/e-i386elf.c
+
+# If m68k-parse.y is in a different directory, then ylwrap will use an
+# absolute path when it invokes yacc, which will cause yacc to put the
+# absolute path into the generated file. That's a pain when it comes
+# to generating snapshots, because it introduces spurious diffs.
+# Since when we make the snapshots $(srcdir) = ".", we check for that
+# case and handle it differently. This means that anybody who
+# configures with $(srcdir) = "." will have to set their path in the
+# debugger if they want to debug m68k-parse.y. This is bad, but on
+# the other hand it's good that people who use the prebuilt
+# m68k-parse.c don't get a spurious absolute path.
+m68k-parse.c: $(srcdir)/config/m68k-parse.y
+ f=$(srcdir)/config/m68k-parse.y; \
+ if [ $$f = "./config/m68k-parse.y" ]; then \
+ ln -s config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ ln config/m68k-parse.y . > /dev/null 2>/dev/null || \
+ cp config/m68k-parse.y . >/dev/null 2>/dev/null; \
+ f=m68k-parse.y; \
+ else true; fi; \
+ $(SHELL) $(YLWRAP) "$(YACC)" $$f y.tab.c m68k-parse.c --; \
+ if [ $$f = "m68k-parse.y" ]; then \
+ rm -f m68k-parse.y; \
+ else true; fi
+m68k-parse.o: m68k-parse.c $(srcdir)/config/m68k-parse.h
+
+# Don't let the .y.h rule clobber m68k-parse.h.
+m68k-parse.h: ; @true
+$(srcdir)/config/m68k-parse.h: ; @true
+
+# The instruction table specification lexical analyzer and parser.
+
+itbl-lex.c: $(srcdir)/itbl-lex.l
+itbl-lex.o: itbl-lex.c itbl-parse.h
+
+itbl-parse.o: itbl-parse.c itbl-parse.h $(srcdir)/itbl-ops.h
+
+itbl-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+
+itbl-parse.c itbl-parse.h: $(srcdir)/itbl-parse.y
+ $(SHELL) $(YLWRAP) "$(YACC)" $(srcdir)/itbl-parse.y y.tab.c itbl-parse.c y.tab.h itbl-parse.h -- -d
+
+itbl-test-ops.o: $(srcdir)/itbl-ops.c $(srcdir)/itbl-ops.h itbl-parse.h
+ $(COMPILE) -o itbl-test-ops.o -DSTAND_ALONE -c $(srcdir)/itbl-ops.c
+
+itbl-test.o: $(srcdir)/testsuite/gas/all/itbl-test.c $(srcdir)/itbl-ops.h
+ $(COMPILE) -c -DSTAND_ALONE $(srcdir)/testsuite/gas/all/itbl-test.c
+
+cgen.o: cgen.c cgen.h cgen-desc.h subsegs.h \
+ $(INCDIR)/obstack.h $(INCDIR)/opcode/cgen.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-desc.h \
+ $(srcdir)/../opcodes/$(CGEN_CPU_PREFIX)-opc.h
+
+.PHONY: install-exec-local install-data-local
+.PHONY: install-exec-bindir install-exec-tooldir
+
+install-exec-local: install-exec-bindir @install_tooldir@
+
+install-exec-bindir: $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(bindir)
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+install-exec-tooldir: $(noinst_PROGRAMS)
+ $(mkinstalldirs) $(tooldir)/bin
+ n=`echo as | sed '$(transform)'`; \
+ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/as$(EXEEXT)" ]; then \
+ rm -f $(tooldir)/bin/as$(EXEEXT); \
+ ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/as$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) as-new$(EXEEXT) $(tooldir)/bin/as$(EXEEXT); \
+ else \
+ true ; \
+ fi
+
+# These exist for maintenance purposes.
+
+.PHONY: bootstrap bootstrap2 bootstrap3 stage1 stage2 stage3 comparison
+
+bootstrap: as-new
+ $(MAKE) stage1
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap2:
+ rm -f stage && ln -s stage1 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) stage2
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+bootstrap3:
+ rm -f stage && ln -s stage2 stage
+ $(MAKE) CC="$(CC)" CFLAGS="-O -Bstage/ $(CFLAGS)" libdir=$(libdir) ALLOCA= $(noinst_PROGRAMS)
+ $(MAKE) comparison against=stage2
+
+# Copy the object files from a particular stage into a subdirectory.
+stage1:
+ -mkdir stage1
+ -mv $(STAGESTUFF) stage1
+ if [ -f stage1/as-new$(EXEEXT) -a ! -f stage1/as$(EXEEXT) ] ; then (cd stage1 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage2:
+ -mkdir stage2
+ -mv $(STAGESTUFF) stage2
+ if [ -f stage2/as-new$(EXEEXT) -a ! -f stage2/as$(EXEEXT) ] ; then (cd stage2 ; ln -s as-new$(EXEEXT) as$(EXEEXT)) ; fi
+
+stage3:
+ -mkdir stage3
+ -mv $(STAGESTUFF) stage3
+ if [ -f stage3/as-new$(EXEEXT) -a ! -f stage3/as$(EXEEXT) ] ; then (cd stage3 ; ln -s as-new as$(EXEEXT)) ; fi
+
+# This rule is derived from corresponding code in the Makefile.in for gcc.
+# The "tail +16c" is to bypass headers which may include timestamps or
+# temporary assembly file names.
+comparison:
+ x=0 ; \
+ for file in *.o ; do \
+ tail +16c ./$$file > tmp-foo1; \
+ if tail +16c ${against}/$$file > tmp-foo2 2>/dev/null ; then \
+ if cmp tmp-foo1 tmp-foo2 ; then \
+ true ; \
+ else \
+ echo $$file differs ; \
+ x=1 ; \
+ fi ; \
+ else true; fi ; \
+ done ; \
+ exit $$x
+ -rm -f tmp-foo*
+
+.PHONY: de-stage1 de-stage2 de-stage3
+
+de-stage1:
+ - (cd stage1 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage1
+
+de-stage2:
+ - (cd stage2 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage2
+
+de-stage3:
+ - (cd stage3 ; rm -f as$(EXEEXT) ; mv -f * ..)
+ - rmdir stage3
+
+.dep: dep.sed $(DEP_FILE_DEPS) .tcdep .objdep .dep2
+ rm -f .dep1
+ srcdir=`cd $(srcdir); pwd`; \
+ $(MAKE) DEP=$(DEP) srcdir=$${srcdir} VPATH=$${srcdir} .dep1
+ rm -rf .depdir
+ sed -f dep.sed < .dep1 > .depa
+ sed -f dep.sed < .tcdep >> .depa
+ sed -f dep.sed < .objdep >> .depa
+ sed -f dep.sed < .dep2 >> .depa
+ echo '$$(OBJS): $$(DEP_@target''_cpu_type@_@obj''_format@)' >> .depa
+ echo '$$(TARG_CPU_O): $$(TCDEP_@target''_cpu_type@_@obj''_format@)' >> .depa
+ echo '$$(OBJ_FORMAT_O): $$(OBJDEP_@target''_cpu_type@_@obj''_format@)' >> .depa
+ echo '# IF YOU PUT ANYTHING HERE IT WILL GO AWAY' >> .depa
+ $(SHELL) $(srcdir)/../move-if-change .depa .dep
+
+# This rule needs a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(MULTI_CFILES)
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ echo '' > targ-cpu.h; \
+ echo '' > obj-format.h; \
+ echo '' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) $?
+ sed -e '/IF YOU PUT ANYTHING/,$$d' < .depdir/.dep > .dep1
+ rm -f .depdir/.dep
+
+# Work out the special dependencies for the tc-*.c files.
+.tcdep: $(TARGET_CPU_CFILES)
+ rm -f .tcdepa
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ echo '#include "opcodes/'"$${c}"'-desc.h"' > cgen-desc.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/tc-$${c}.c dummy.c; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \
+ sed -e "s/dummy.o: dummy.c/TCDEP_$${c}_$${o} =/" \
+ -e '1,/DO NOT PUT ANYTHING AFTER/d' \
+ -e '/IF YOU PUT ANYTHING/,$$d' \
+ -e '/^$$/d' < .dep >> ../.tcdepa; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'TCDEP_hppa_som = $$(srcdir)/config/tc-hppa.h subsegs.h \' >> .tcdepa
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .tcdepa
+ echo ' $$(INCDIR)/opcode/hppa.h $$(BFDDIR)/som.h' >> .tcdepa
+ # We don't try to handle all multi cases.
+ for c in $(CPU_TYPES); do \
+ $(CPU_MULTI_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ o=ecoff; \
+ $(CPU_OBJ_VALID) \
+ echo 'TCDEP_'"$${c}"'_multi = \' >> .tcdepa; \
+ echo '$$(TCDEP_'"$${c}"'_coff) \' >> .tcdepa; \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(TCDEP_'"$${c}"'_ecoff) \' >> .tcdepa; \
+ else true; fi; \
+ echo '$$(TCDEP_'"$${c}"'_elf)' >> .tcdepa; \
+ else true; fi; \
+ done
+ mv -f .tcdepa .tcdep
+
+# Work out the special dependencies for the obj-*.c files.
+.objdep: $(OBJ_FORMAT_CFILES)
+ rm -f .objdepa
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > obj-format.h; \
+ echo '#include "te-generic.h"' > targ-env.h; \
+ echo '' > itbl-cpu.h; \
+ rm -f dummy.c; \
+ cp $${srcdir}/config/obj-$${o}.c dummy.c; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \
+ sed -e "s/dummy.o: dummy.c/OBJDEP_$${c}_$${o} =/" \
+ -e '1,/DO NOT PUT ANYTHING AFTER/d' \
+ -e '/IF YOU PUT ANYTHING/,$$d' \
+ -e '/^$$/d' < .dep >> ../.objdepa; \
+ rm -f dummy.c; \
+ else true; fi; \
+ done; \
+ done
+ echo 'OBJDEP_hppa_som = $$(srcdir)/config/obj-som.h subsegs.h \' >> .objdepa
+ echo ' $$(INCDIR)/obstack.h $$(BFDDIR)/libhppa.h \' >> .objdepa
+ echo ' $$(BFDDIR)/som.h $$(INCDIR)/aout/stab_gnu.h \' >> .objdepa
+ echo ' $$(INCDIR)/aout/stab.def' >> .objdepa
+ # We don't try to handle all multi cases.
+ for c in $(CPU_TYPES); do \
+ $(CPU_MULTI_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ o=ecoff; \
+ $(CPU_OBJ_VALID) \
+ echo 'OBJDEP_'"$${c}"'_multi = \' >> .objdepa; \
+ echo '$$(OBJDEP_'"$${c}"'_coff) \' >> .objdepa; \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(OBJDEP_'"$${c}"'_ecoff) \' >> .objdepa; \
+ else true; fi; \
+ echo '$$(OBJDEP_'"$${c}"'_elf)' >> .objdepa; \
+ else true; fi; \
+ done
+ mv -f .objdepa .objdep
+
+# Work out the dependencies for each CPU/OBJ combination.
+# Note that SOM is a special case, because it only works native.
+.dep2: $(TARGET_CPU_HFILES) $(OBJ_FORMAT_HFILES)
+ rm -f .dep2a
+ if [ -d .depdir ]; then true; else mkdir .depdir; fi
+ srcdir=`cd $(srcdir); pwd`; \
+ cd .depdir; \
+ for c in $(CPU_TYPES); do \
+ for o in $(OBJ_FORMATS); do \
+ $(CPU_OBJ_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ echo '#include "tc-'"$${c}"'.h"' > targ-cpu.h; \
+ echo '#include "obj-'"$${o}"'.h"' > dummy.c; \
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep; \
+ $(DEP) -f .dep -DBFD_ASSEMBLER -I. -I.. -I$${srcdir} -I../../bfd $(DEP_INCLUDES) dummy.c; \
+ sed -e "s/dummy.o: dummy.c/DEP_$${c}_$${o} =/" \
+ -e '1,/DO NOT PUT ANYTHING AFTER/d' \
+ -e '/IF YOU PUT ANYTHING/,$$d' \
+ -e '/^$$/d' < .dep >> ../.dep2a; \
+ else true; fi; \
+ done; \
+ done
+ echo 'DEP_hppa_som = $$(BFDDIR)/som.h' >> .dep2a
+ # We don't try to handle all multi cases.
+ for c in $(CPU_TYPES); do \
+ $(CPU_MULTI_VALID) \
+ if [ x$${valid} = xyes ]; then \
+ o=ecoff; \
+ $(CPU_OBJ_VALID) \
+ echo 'DEP_'"$${c}"'_multi = \' >> .dep2a; \
+ echo '$$(DEP_'"$${c}"'_coff) \' >> .dep2a; \
+ if [ x$${valid} = xyes ]; then \
+ echo '$$(DEP_'"$${c}"'_ecoff) \' >> .dep2a; \
+ else true; fi; \
+ echo '$$(DEP_'"$${c}"'_elf)' >> .dep2a; \
+ else true; fi; \
+ done
+ mv -f .dep2a .dep2
+
+dep.sed: dep-in.sed config.status
+ srcdir=`cd $(srcdir); pwd`; \
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e "s!@INCDIR@!$${srcdir}/../include!" \
+ -e "s!@BFDDIR@!$${srcdir}/../bfd!" \
+ -e "s!@SRCDIR@!$${srcdir}!"
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(SHELL) $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+app.o: app.c
+as.o: as.c subsegs.h $(INCDIR)/obstack.h output-file.h \
+ sb.h macro.h
+atof-generic.o: atof-generic.c
+bignum-copy.o: bignum-copy.c
+cond.o: cond.c macro.h sb.h $(INCDIR)/obstack.h
+depend.o: depend.c
+ecoff.o: ecoff.c
+ehopt.o: ehopt.c subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
+expr.o: expr.c $(INCDIR)/obstack.h
+flonum-copy.o: flonum-copy.c
+flonum-konst.o: flonum-konst.c
+flonum-mult.o: flonum-mult.c
+frags.o: frags.c subsegs.h $(INCDIR)/obstack.h
+hash.o: hash.c
+input-file.o: input-file.c input-file.h
+input-scrub.o: input-scrub.c input-file.h sb.h
+listing.o: listing.c input-file.h subsegs.h
+literal.o: literal.c subsegs.h $(INCDIR)/obstack.h
+macro.o: macro.c sb.h macro.h
+messages.o: messages.c
+output-file.o: output-file.c output-file.h
+read.o: read.c subsegs.h $(INCDIR)/obstack.h sb.h macro.h \
+ ecoff.h
+sb.o: sb.c sb.h
+stabs.o: stabs.c $(INCDIR)/obstack.h subsegs.h ecoff.h \
+ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
+subsegs.o: subsegs.c subsegs.h $(INCDIR)/obstack.h
+symbols.o: symbols.c $(INCDIR)/obstack.h subsegs.h
+write.o: write.c subsegs.h $(INCDIR)/obstack.h output-file.h
+gasp.o: gasp.c sb.h macro.h
+e-i386coff.o: $(srcdir)/config/e-i386coff.c emul.h \
+ emul-target.h
+e-i386elf.o: $(srcdir)/config/e-i386elf.c emul.h emul-target.h
+e-mipsecoff.o: $(srcdir)/config/e-mipsecoff.c emul.h \
+ emul-target.h
+e-mipself.o: $(srcdir)/config/e-mipself.c emul.h emul-target.h
+$(OBJS): $(DEP_@target_cpu_type@_@obj_format@)
+$(TARG_CPU_O): $(TCDEP_@target_cpu_type@_@obj_format@)
+$(OBJ_FORMAT_O): $(OBJDEP_@target_cpu_type@_@obj_format@)
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gas/NEWS b/gas/NEWS
new file mode 100644
index 00000000000..08440763526
--- /dev/null
+++ b/gas/NEWS
@@ -0,0 +1,287 @@
+-*- text -*-
+
+Changes in 2.10:
+
+Support for the Motorolla MCore 210 processor added.
+
+A new pseudo-op .intel_syntax has been implemented to allow gas to parse i386 assembly
+programs with intel syntax.
+
+New pseudo-ops .func,.endfunc to aid in debugging user-written assembler code.
+
+Full 16-bit mode support for i386.
+
+Greatly improved instruction operand checking for i386. This change will
+produce errors or warnings on incorrect assembly code that previous versions of
+gas accepted. If you get unexpected messages from code that worked with older
+versions of gas, please double check the code before reporting a bug.
+
+Weak symbol support added for COFF targets.
+
+Mitsubishi D30V support added.
+
+Texas Instruments c80 (tms320c80) support added.
+
+Changes in 2.9:
+
+Texas Instruments c30 (tms320c30) support added.
+
+The assembler now optimizes the exception frame information generated by egcs
+and gcc 2.8. The new --traditional-format option disables this optimization.
+
+Added --gstabs option to generate stabs debugging information.
+
+The -a option takes a new suboption, m (e.g., -alm) to expand macros in a
+listing.
+
+Added -MD option to print dependencies.
+
+Changes in 2.8:
+
+BeOS support added.
+
+MIPS16 support added.
+
+Motorola ColdFire 5200 support added (configure for m68k and use -m5200).
+
+Alpha/VMS support added.
+
+m68k options --base-size-default-16, --base-size-default-32,
+--disp-size-default-16, and --disp-size-default-32 added.
+
+The alignment directives now take an optional third argument, which is the
+maximum number of bytes to skip. If doing the alignment would require skipping
+more than the given number of bytes, the alignment is not done at all.
+
+The ELF assembler has a new pseudo-op, .symver, used for symbol versioning.
+
+The -a option takes a new suboption, c (e.g., -alc), to skip false conditionals
+in listings.
+
+Added new pseudo-op, .equiv; it's like .equ, except that it is an error if the
+symbol is already defined.
+
+Changes in 2.7:
+
+The PowerPC assembler now allows the use of symbolic register names (r0, etc.)
+if -mregnames is used. Symbolic names preceded by a '%' (%r0, etc.) can be
+used any time. PowerPC 860 move to/from SPR instructions have been added.
+
+Alpha Linux (ELF) support added.
+
+PowerPC ELF support added.
+
+m68k Linux (ELF) support added.
+
+i960 Hx/Jx support added.
+
+i386/PowerPC gnu-win32 support added.
+
+SCO ELF support added. For OpenServer 5 targets (i386-unknown-sco3.2v5) the
+default is to build COFF-only support. To get a set of tools that generate ELF
+(they'll understand both COFF and ELF), you must configure with
+target=i386-unknown-sco3.2v5elf.
+
+m88k-motorola-sysv3* support added.
+
+Changes in 2.6:
+
+Gas now directly supports macros, without requiring GASP.
+
+Gas now has an MRI assembler compatibility mode. Use -M or --mri to select MRI
+mode. The pseudo-op ``.mri 1'' will switch into the MRI mode until the ``.mri
+0'' is seen; this can be convenient for inline assembler code.
+
+Added --defsym SYM=VALUE option.
+
+Added -mips4 support to MIPS assembler.
+
+Added PIC support to Solaris and SPARC SunOS 4 assembler.
+
+Changes in 2.4:
+
+Converted this directory to use an autoconf-generated configure script.
+
+ARM support, from Richard Earnshaw.
+
+Updated VMS support, from Pat Rankin, including considerably improved debugging
+support.
+
+Support for the control registers in the 68060.
+
+Handles (ignores) a new directive ".this_GCC_requires_the_GNU_assembler", to
+provide for possible future gcc changes, for targets where gas provides some
+features not available in the native assembler. If the native assembler is
+used, it should become obvious pretty quickly what the problem is.
+
+Usage message is available with "--help".
+
+The GNU Assembler Preprocessor (gasp) is included. (Actually, it was in 2.3
+also, but didn't get into the NEWS file.)
+
+Weak symbol support for a.out.
+
+A bug in the listing code which could cause an infinite loop has been fixed.
+Bugs in listings when generating a COFF object file have also been fixed.
+
+Initial i386-svr4 PIC implementation from Eric Youngdale, based on code by Paul
+Kranenburg.
+
+Improved Alpha support. Immediate constants can have a much larger range now.
+Support for the 21164 has been contributed by Digital.
+
+Updated ns32k (pc532-mach, netbsd532) support from Ian Dall.
+
+Changes in 2.3:
+
+Mach i386 support, by David Mackenzie and Ken Raeburn.
+
+RS/6000 and PowerPC support by Ian Taylor.
+
+VMS command scripts (make-gas.com, config-gas.com) have been worked on a bit,
+based on mail received from various people. The `-h#' option should work again
+too.
+
+HP-PA work, by Jeff Law. Note, for the PA, gas-2.3 has been designed to work
+with gdb-4.12 and gcc-2.6. As gcc-2.6 has not been released yet, a special
+version of gcc-2.5.8 has been patched to work with gas-2.3. You can retrieve
+this special version of gcc-2.5.8 via anonymous ftp from jaguar.cs.utah.edu
+in the "dist" directory.
+
+Vax support in gas fixed for BSD, so it builds and seems to run a couple simple
+tests okay. I haven't put it through extensive testing. (GNU make is
+currently required for BSD 4.3 builds.)
+
+Support for the DEC Alpha, running OSF/1 (ECOFF format). The gas support is
+based on code donated by CMU, which used an a.out-based format. I'm afraid the
+alpha-a.out support is pretty badly mangled, and much of it removed; making it
+work will require rewriting it as BFD support for the format anyways.
+
+Irix 5 support.
+
+The test suites have been fixed up a bit, so that they should work with a
+couple different versions of expect and dejagnu.
+
+Symbols' values are now handled internally as expressions, permitting more
+flexibility in evaluating them in some cases. Some details of relocation
+handling have also changed, and simple constant pool management has been added,
+to make the Alpha port easier.
+
+New option "--statistics" for printing out program run times. This is intended
+to be used with the gcc "-Q" option, which prints out times spent in various
+phases of compilation. (You should be able to get all of them printed out with
+"gcc -Q -Wa,--statistics", I think.)
+
+----------------------------------------------------------------
+
+Changes in 2.2:
+
+RS/6000 AIX and MIPS SGI Irix 5 support has been added.
+
+Configurations that are still in development (and therefore are convenient to
+have listed in configure.in) still get rejected without a minor change to
+gas/Makefile.in, so people not doing development work shouldn't get the
+impression that support for such configurations is actually believed to be
+reliable.
+
+The program name (usually "as") is printed when a fatal error message is
+displayed. This should prevent some confusion about the source of occasional
+messages about "internal errors".
+
+ELF support is falling into place. Support for the 386 should be working.
+Support for SPARC Solaris is in. HPPA support from Utah is being integrated.
+
+Symbol values are maintained as expressions instead of being immediately boiled
+down to add-symbol, sub-symbol, and constant. This permits slightly more
+complex calculations involving symbols whose values are not alreadey known.
+
+DBX-style debugging info ("stabs") is now supported for COFF formats.
+If any stabs directives are seen in the source, GAS will create two new
+sections: a ".stab" and a ".stabstr" section. The format of the .stab
+section is nearly identical to the a.out symbol format, and .stabstr is
+its string table. For this to be useful, you must have configured GCC
+to generate stabs (by defining DBX_DEBUGGING_INFO), and must have a GDB
+that can use the stab sections (4.11 or later).
+
+LynxOS, on i386 and m68k platforms, is now supported. SPARC LynxOS
+support is in progress.
+
+----------------------------------------------------------------
+
+Changes in 2.1:
+
+Several small fixes for i386-aix (PS/2) support from Minh Tran-Le have been
+incorporated, but not well tested yet.
+
+Altered the opcode table split for m68k; it should require less VM to compile
+with gcc now.
+
+Some minor adjustments to add (Convergent Technologies') Miniframe support,
+suggested by Ronald Cole.
+
+HPPA support (running OSF only, not HPUX) has been contributed by Utah. This
+includes improved ELF support, which I've started adapting for SPARC Solaris
+2.x. Integration isn't completely, so it probably won't work.
+
+HP9000/300 support, donated by HP, has been merged in.
+
+Ian Taylor has finished the MIPS ECOFF (Ultrix, Irix) support.
+
+Better error messages for unsupported configurations (e.g., hppa-hpux).
+
+Test suite framework is starting to become reasonable.
+
+----------------------------------------------------------------
+
+Changes in 2.0:
+
+Mostly bug fixes.
+
+Some more merging of BFD and ELF code, but ELF still doesn't work.
+
+----------------------------------------------------------------
+
+Changes in 1.94:
+
+BFD merge is partly done. Adventurous souls may try giving configure the
+"--with-bfd-assembler" option. Currently, ELF format requires it, a.out format
+accepts it; SPARC CPU accepts it. It's the default only for OS "elf" or
+"solaris". (ELF isn't really supported yet. It needs work. I've got some
+code from Utah for HP-PA ELF, and from DG for m88k ELF, but they're not fully
+merged yet.)
+
+The 68K opcode table has been split in half. It should now compile under gcc
+without consuming ridiculous amounts of memory.
+
+A couple data structures have been reduced in size. This should result in
+saving a little bit of space at runtime.
+
+Support for MIPS, from OSF and Ralph Campbell, has been merged in. The OSF
+code provided ROSE format support, which I haven't merged in yet. (I can make
+it available, if anyone wants to try it out.) Ralph's code, for BSD 4.4,
+supports a.out format. We don't have ECOFF support in just yet; it's coming.
+
+Support for the Hitachi H8/500 has been added.
+
+VMS host and target support should be working now, thanks chiefly to Eric
+Youngdale.
+
+----------------------------------------------------------------
+
+Changes in 1.93.01:
+
+For m68k, support for more processors has been added: 68040, CPU32, 68851.
+
+For i386, .align is now power-of-two; was number-of-bytes.
+
+For m68k, "%" is now accepted before register names. For COFF format, which
+doesn't use underscore prefixes for C labels, it is required, so variable "a0"
+can be distinguished from the register.
+
+Last public release was 1.38. Lots of configuration changes since then, lots
+of new CPUs and formats, lots of bugs fixed.
+
+
+Local variables:
+fill-column: 79
+End:
diff --git a/gas/README b/gas/README
new file mode 100644
index 00000000000..4ac27db82fe
--- /dev/null
+++ b/gas/README
@@ -0,0 +1,274 @@
+ README for GAS
+
+A number of things have changed since version 1 and the wonderful world of gas
+looks very different. There's still a lot of irrelevant garbage lying around
+that will be cleaned up in time. Documentation is scarce, as are logs of the
+changes made since the last gas release. My apologies, and I'll try to get
+something useful.
+
+Unpacking and Installation - Summary
+====================================
+
+See ../binutils/README.
+
+To build just the assembler, make the target all-gas.
+
+Documentation
+=============
+
+The GAS release includes texinfo source for its manual, which can be processed
+into `info' or `dvi' forms.
+
+The DVI form is suitable for printing or displaying; the commands for doing
+this vary from system to system. On many systems, `lpr -d' will print a DVI
+file. On others, you may need to run a program such as `dvips' to convert the
+DVI file into a form your system can print.
+
+If you wish to build the DVI file, you will need to have TeX installed on your
+system. You can rebuild it by typing:
+
+ cd gas/doc
+ make as.dvi
+
+The Info form is viewable with the GNU Emacs `info' subsystem, or the
+standalone `info' program, available as part of the GNU Texinfo distribution.
+To build the info files, you will need the `makeinfo' program. Type:
+
+ cd gas/doc
+ make info
+
+Specifying names for hosts and targets
+======================================
+
+ The specifications used for hosts and targets in the `configure'
+script are based on a three-part naming scheme, but some short
+predefined aliases are also supported. The full naming scheme encodes
+three pieces of information in the following pattern:
+
+ ARCHITECTURE-VENDOR-OS
+
+ For example, you can use the alias `sun4' as a HOST argument or in a
+`--target=TARGET' option. The equivalent full name is
+`sparc-sun-sunos4'.
+
+ The `configure' script accompanying GAS does not provide any query
+facility to list all supported host and target names or aliases.
+`configure' calls the Bourne shell script `config.sub' to map
+abbreviations to full names; you can read the script, if you wish, or
+you can use it to test your guesses on abbreviations--for example:
+
+ % sh config.sub sun4
+ sparc-sun-sunos411
+ % sh config.sub sun3
+ m68k-sun-sunos411
+ % sh config.sub decstation
+ mips-dec-ultrix42
+ % sh config.sub hp300bsd
+ m68k-hp-bsd
+ % sh config.sub i386v
+ i386-unknown-sysv
+ % sh config.sub i786v
+ Invalid configuration `i786v': machine `i786v' not recognized
+
+
+`configure' options
+===================
+
+ Here is a summary of the `configure' options and arguments that are
+most often useful for building GAS. `configure' also has several other
+options not listed here.
+
+ configure [--help]
+ [--prefix=DIR]
+ [--srcdir=PATH]
+ [--host=HOST]
+ [--target=TARGET]
+ [--with-OPTION]
+ [--enable-OPTION]
+
+You may introduce options with a single `-' rather than `--' if you
+prefer; but you may abbreviate option names if you use `--'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`-prefix=DIR'
+ Configure the source to install programs and files under directory
+ `DIR'.
+
+`--srcdir=PATH'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--host=HOST'
+ Configure GAS to run on the specified HOST. Normally the
+ configure script can figure this out automatically.
+
+ There is no convenient way to generate a list of all available
+ hosts.
+
+`--target=TARGET'
+ Configure GAS for cross-assembling programs for the specified
+ TARGET. Without this option, GAS is configured to assemble .o files
+ that run on the same machine (HOST) as GAS itself.
+
+ There is no convenient way to generate a list of all available
+ targets.
+
+`--enable-OPTION'
+ These flags tell the program or library being configured to
+ configure itself differently from the default for the specified
+ host/target combination. See below for a list of `--enable'
+ options recognized in the gas distribution.
+
+`configure' accepts other options, for compatibility with configuring
+other GNU tools recursively; but these are the only options that affect
+GAS or its supporting libraries.
+
+The `--enable' options recognized by software in the gas distribution are:
+
+`--enable-targets=...'
+ This causes one or more specified configurations to be added to those for
+ which BFD support is compiled. Currently gas cannot use any format other
+ than its compiled-in default, so this option is not very useful.
+
+`--enable-bfd-assembler'
+ This causes the assembler to use the new code being merged into it to use
+ BFD data structures internally, and use BFD for writing object files.
+ For most targets, this isn't supported yet. For most targets where it has
+ been done, it's already the default. So generally you won't need to use
+ this option.
+
+Supported platforms
+===================
+
+At this point I believe gas to be ansi only code for most target cpu's. That
+is, there should be relatively few, if any host system dependencies. So
+porting (as a cross-assembler) to hosts not yet supported should be fairly
+easy. Porting to a new target shouldn't be too tough if it's a variant of one
+already supported.
+
+Native assembling should work on:
+
+ sun3
+ sun4
+ 386bsd
+ bsd/386
+ delta (m68k-sysv from Motorola)
+ delta88 (m88k-sysv from Motorola)
+ GNU/linux
+ m68k hpux 8.0 (hpux 7.0 may be a problem)
+ vax bsd, ultrix, vms
+ hp9000s300
+ decstation
+ irix 4
+ irix 5
+ miniframe (m68k-sysv from Convergent Technologies)
+ i386-aix (ps/2)
+ hppa (hpux 4.3bsd, osf1)
+ AIX
+ unixware
+ sco 3.2v4.2
+ sco openserver 5.0 (a.k.a. 3.2v5.0 )
+ sparc solaris
+ ns32k (netbsd, lites)
+
+I believe that gas as a cross-assembler can currently be targetted for
+most of the above hosts, plus
+
+ decstation-bsd (a.out format, to be used in BSD 4.4)
+ ebmon29k
+ go32 (DOS on i386, with DJGPP -- old a.out version)
+ h8/300, h8/500 (Hitachi)
+ i386-aix (ps/2)
+ i960-coff
+ mips ecoff (decstation-ultrix, iris, mips magnum, mips-idt-ecoff)
+ Mitsubishi d10v and d30v
+ nindy960
+ powerpc EABI
+ SH (Hitachi)
+ sco386
+ TI tic30 and tic80
+ vax bsd or ultrix?
+ vms
+ vxworks68k
+ vxworks960
+ z8000 (Zilog)
+
+MIPS ECOFF support has been added, but GAS will not run a C-style
+preprocessor. If you want that, rename your file to have a ".S" suffix, and
+run gcc on it. Or run "gcc -xassembler-with-cpp foo.s".
+
+Support for ELF should work now for sparc, hppa, i386, alpha, m68k,
+MIPS, powerpc.
+
+Support for sequent (ns32k), tahoe, i860, m88k may be suffering from bitrot.
+
+If you try out gas on some host or target not listed above, please let me know
+the results, so I can update the list.
+
+Compiler Support Hacks
+======================
+
+On a few targets, the assembler has been modified to support a feature
+that is potentially useful when assembling compiler output, but which
+may confuse assembly language programmers. If assembler encounters a
+.word pseudo-op of the form symbol1-symbol2 (the difference of two
+symbols), and the difference of those two symbols will not fit in 16
+bits, the assembler will create a branch around a long jump to
+symbol1, and insert this into the output directly before the next
+label: The .word will (instead of containing garbage, or giving an
+error message) contain (the address of the long jump)-symbol2. This
+allows the assembler to assemble jump tables that jump to locations
+very far away into code that works properly. If the next label is
+more than 32K away from the .word, you lose (silently); RMS claims
+this will never happen. If the -K option is given, you will get a
+warning message when this happens.
+
+
+REPORTING BUGS IN GAS
+=====================
+
+Bugs in gas should be reported to bug-gnu-utils@gnu.org. They may be
+cross-posted to bug-gcc if they affect the use of gas with gcc. They
+should not be reported just to bug-gcc, since I don't read that list,
+and therefore wouldn't see them.
+
+If you report a bug in GAS, please remember to include:
+
+A description of exactly what went wrong, and exactly what should have
+happened instead.
+
+The type of machine (VAX, 68020, etc) and operating system (BSD, SunOS, DYNIX,
+VMS, etc) GAS was running on.
+
+The configuration name(s) given to the "configure" script. The
+"config.status" file should have this information.
+
+The options given to GAS at run time.
+
+The actual input file that caused the problem.
+
+It is silly to report a bug in GAS without including an input file for GAS.
+Don't ask us to generate the file just because you made it from files you
+think we have access to.
+
+1. You might be mistaken.
+2. It might take us a lot of time to install things to regenerate that file.
+3. We might get a different file from the one you got, and might not see any
+ bug.
+
+To save us these delays and uncertainties, always send the input file for the
+program that failed. A smaller test case that demonstrates the problem is of
+course preferable, but be sure it is a complete input file, and that it really
+does demonstrate the problem; but if paring it down would cause large delays
+in filing the bug report, don't bother.
+
+If the input file is very large, and you are on the internet, you may want to
+make it avaliable for anonymous FTP instead of mailing it. If you do, include
+instructions for FTP'ing it in your bug report.
+
+If you expect to be contributing a large number of test cases, it would be
+helpful if you would look at the test suite included in the release (based on
+the Deja Gnu testing framework, available from the usual ftp sites) and write
+test cases to fit into that framework. This is certainly not required.
diff --git a/gas/README-vms b/gas/README-vms
new file mode 100644
index 00000000000..796c603b4f3
--- /dev/null
+++ b/gas/README-vms
@@ -0,0 +1,248 @@
+ This document explains a couple of things that are specific to VMS.
+There are currently two "chapters", the first deals with cross-assembly
+issues, and the second deals with the VMS debugger and GNU-CC.
+
+
+***********************************************************************
+****************** Notes for Cross Assembly with VMS ******************
+***********************************************************************
+
+ If you wish to build gas on a non-VMS system to cross-assemble,
+you should use:
+
+configure ${hosttype} -target=vms
+
+and then follow the usual procedure. The object files generated on
+Unix will be correct from a binary point of view, but the real trick is
+getting them to the VMS machine. The format of the object file is
+a variable-length record, but each record contains binary data. gas
+writes the records in the same format that VMS would expect,
+namely a two-byte count followed by that number of bytes.
+
+ If you try to copy the file to a VMS system using ftp, the ftp
+protocol will screw up the file by looking for nulls (record terminator for
+unix) and it will insert it's own record terminators at that point. This
+will obviously corrupt the file.
+
+ If you try to transfer the file with ftp in binary mode, the
+file itself will not be corrupt, but VMS will think that the file contains
+fixed-length records of 512 bytes. You can use the public-domain FILE
+utility to change this with a command like:
+
+$FILE foo.o/type=variable
+
+If you do not have this utility available, the following program can be
+used to perform this task:
+
+ #include <fab.h>
+
+ #define RME$C_SETRFM 1
+
+ struct FAB * fab;
+
+ main(int argc, char * argv[]){
+ int i, status;
+ fab = (struct FAB*) malloc(sizeof(struct FAB));
+ *fab = cc$rms_fab; /* initialize FAB*/
+ fab->fab$b_fac = FAB$M_PUT;
+ fab->fab$l_fop |= FAB$M_ESC;
+ fab->fab$l_ctx = RME$C_SETRFM;
+ fab->fab$w_ifi = 0;
+ for(i=1;i<argc;i++){
+ printf("Setting %s to variable length records.\n",argv[i]);
+ fab->fab$l_fna = argv[i];
+ fab->fab$b_fns = strlen(argv[i]);
+ status = sys$open(fab,0,0);
+ if((status & 7) != 1) lib$signal(status);
+ fab->fab$b_rfm = FAB$C_VAR;
+ status = sys$modify(fab,0,0);
+ if((status & 7) != 1) lib$signal(status);
+ status = sys$close(fab,0,0);
+ if((status & 7) != 1) lib$signal(status);
+ };
+ }
+
+ If you have NFS running on the VMS system, what you need to do
+depends upon which NFS software you are running on the VMS system. There
+are a number of different TCP/IP packages for VMS available, and only very
+limited testing has been performed. In the tests that has been done so
+far, the contents of the file will always be correct when transferring the
+file via NFS, but the record attributes may or may not be correct.
+
+ One proprietary TCP/IP/NFS package for VMS is known to
+automatically fix the record attributes of the object file if you NFS mount
+a unix disk from the VMS system, and if the file has a ".obj" extension on
+the unix system. Other TCP/IP packages might do this for you as well, but
+they have not been checked.
+
+No matter what method you use to get the file to the VMS system, it is
+always a good idea to check to make sure that it is the correct type by
+doing a "$dir/full" on the object file. The desired record attributes will
+be "None". Undesirable record attributes will be "Stream-LF" or anything
+else.
+
+Once you get the files on the VMS system, you can check their integrity
+with the "$anal/obj" command. (Naturally at some point you should rename
+the .o files to .obj). As far as the debugger is concerned, the records
+will be correct, but the debugger will not be able to find the source files,
+since it only has the file name, and not the full directory specification.
+You must give the debugger some help by telling it which directories to
+search for the individual files - once you have done this you should be
+able to proceed normally.
+
+ It is a good idea to use names for your files which will be valid
+under VMS, since otherwise you will have no way of getting the debugger to
+find the source file when deugging.
+
+The reason for this is that the object file normally contins specific
+information that the debugger can use to positively identify a file, and if
+you are assembling on a unix system this information simply does not exist
+in a meaningful way. You must help the debugger by using the "SET FILE="
+command to tell the debugger where to look for source files. The debugger
+records will be correct, except that the debugger will not be initially
+able to find the source files. You can use the "SET FILE" command to tell
+the debugger where to look for the source files.
+
+I have only tested this with a SVr4 i486 machine, and everything seems to
+work OK, with the limited testing that I have done. Other machines may
+or may not work. You should read the chapters on cross-compilers in the gcc
+manual before fooling with this. Since gas does not need to do any floating
+point arithmetic, the floating point constants that are generated here should
+be correct - the only concern is with constant folding in the main compiler.
+The range and precision of floats and doubles are similar on the 486 (with
+a builtin 80387) and the VAX, although there is a factor of 2 to 4
+difference in the range. The double, as implemented on the 486, is quite
+similar to the G_FLOAT on the VAX.
+
+***********************************************************************
+****************** Notes for using GNU CC with the VMS debugger********
+***********************************************************************
+
+
+ 1) You should be aware that GNU-C, as with any other decent compiler,
+will do things when optimization is turned on that you may not expect.
+Sometimes intermediate results are not written to variables, if they are only
+used in one place, and sometimes variables that are not used at all will not be
+written to the symbol table. Also, parameters to inline functions are often
+inaccessible. You can see the assembly code equivalent by using KP7 in the
+debugger, and from this you can tell if in fact a variable should have the
+value that you expect. You can find out if a variable lives withing a register
+by doing a 'show symbol/addr'.
+
+ 2) Overly complex data types, such as:
+
+int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5];
+
+will not be debugged properly, since the debugging record overflows an internal
+debugger buffer. gcc-as will convert these to *void as far as the debugger
+symbol table is concerned, which will avoid any problems, and the assembler
+will give you a message informing you that this has happened.
+
+ 3) You must, of course, compile and link with /debug. If you link
+without debug, you still get traceback table in the executable, but there is no
+symbol table for variables.
+
+ 4) Included in the patches to VMS.C are fixes to two bugs that are
+unrelated to the changes that I have made. One of these made it impossible to
+debug small programs sometimes, and the other caused the debugger to become
+confused about which routine it was in, and give this incorrect info in
+tracebacks.
+
+ 5) If you are using the GNU-C++ compiler, you should modify the
+compiler driver file GNU_CC:[000000]GCC.COM (or GXX.COM). If you have a
+seperate GXX.COM, then you need to change one line in GXX.COM to:
+$ if f$locate("D",p2) .ne. P2_Length then Debug = " ""-G0"""
+ Notice zero---> ^
+If you are using a GCC.COM that does both C and C++, add the following lines to
+GCC.COM:
+
+$!
+$! Use old style debugging records for VMS
+$!
+$ if (Debug.nes."" ).and. Plus then Debug = " ""-G0"""
+
+after the variables Plus and Debug are set. The reason for this, is that C++
+compiler by default generates debugging records that are more complex,
+with many new syntactical elements that allow for the new features of the
+language. The -G0 switch tells the C++ compiler to use the old style debugging
+records. Until the debugger understands C++ there is not any point to try and
+use the expanded syntax.
+
+ 6) When you have nested scopes, i.e.:
+main(){
+ int i;
+ {int i;
+ {int i;
+};};}
+and you say "EXAM i" the debugger needs to figure out which variable you
+actually want to reference. I have arranged things to define a block to the
+debugger when you use brackets to enter a new scope, so in the example above,
+the variables would be described as:
+TEST\main\i
+TEST\main\$0\i
+TEST\main\$0\$0\i
+At each level, the block name is a number with a dollar sign prefix, the
+numbers start with 0 and count upward. When you say EXAM i, the debugger looks
+at the current PC, and decides which block it is currently in. It works from
+the innermost level outward until it finds a block that has the variable "i"
+defined. You can always specify the scope explicitly.
+
+ 7) With C++, there can be a lot of inline functions, and it would be
+rather restrictive to force the user to debug the program by converting all of
+the inline functions to normal functions. What I have done is to essentially
+"add" (with the debugger) source lines from the include files that contain the
+inline functions. Thus when you step into an inline function it appears as if
+you have called the function, and you can examine variables and so forth.
+There are several *very* important differences, however. First of all, since
+there is no function call involved, you cannot step over the inline function
+call - you always step into it. Secondly, since the same source lines are used
+in many locations, there is a seperate copy of the source for *each* usage.
+Without this, breakpoints do not work, since we must have a 1-to-1 mapping
+between source lines and PC.
+ Since you cannot step over inline function calls, it can be a real pain
+if you are not really interested in what is going on for that function call.
+What I have done is to use the "-D" switch for the assembler to toggle the
+following behavior. With the "-D" switch, all inline functions are included in
+the object file, and you can debug everything. Without the "-D" switch
+(default case with VMS implementation), inline functions are included *only* if
+they did not come from system header files (i.e. from GNU_CC_INCLUDE: or
+GNU_GXX_INCLUDE:). Thus, without the switch the user only debugs his/her own
+inline functions, and not the system ones. (This is especially useful if you do
+a lot of stream I/O in C++). This probably will not provide enough granularity
+for many users, but for now this is still somewhat experimental, and I would
+like to reflect upon it and get some feedback before I go any further.
+Possible solutions include an interactive prompting, a logical name, or a new
+command line option in gcc.c (which is then passed through somehow to the guts
+of the assembler).
+ The inline functions from header files appear after the source code
+for the source file. This has the advantage that the source file itself is
+numbered with the same line numbers that you get with an editor. In addition,
+the entire header file is not included, since the assembler makes a list of
+the min and max source lines that are used, and only includes those lines from
+the first to the last actually used. (It is easy to change it to include the
+whole file).
+
+ 8) When you are debugging C++ objects, the object "this" is refered to
+as "$this". Actually, the compiler writes it as ".this", but the period is
+not good for the debugger, so I have a routine to convert it to a $. (It
+actually converts all periods to $, but only for variables, since this was
+intended to allow us to access "this".
+
+ 9) If you use the asm("...") keyword for global symbols, you will not
+be able to see that symbol with the debugger. The reason is that there are two
+records for the symbol stored in the data structures of the assembler. One
+contains the info such as psect number and offset, and the other one contains
+the information having to do with the data type of the variable. In order to
+debug as symbol, you need to be able to coorelate these records, and the only
+way to do this is by name. The record with the storage attributes will take
+the name used in the asm directive, and the record that specifies the data type
+has the actual variable name, and thus when you use the asm directive to change
+a variable name, the symbol becomes invisible.
+
+ 10) Older versions of the compiler ( GNU-C 1.37.92 and earlier) place
+global constants in the text psect. This is unfortunate, since to the linker
+this appears to be an entry point. I sent a patch to the compiler to RMS,
+which will generate a .const section for these variables, and patched the
+assembler to put these variables into a psect just like that for normal
+variables, except that they are marked NOWRT. static constants are still
+placed in the text psect, since there is no need for any external access.
diff --git a/gas/acinclude.m4 b/gas/acinclude.m4
new file mode 100644
index 00000000000..31a2c1632f1
--- /dev/null
+++ b/gas/acinclude.m4
@@ -0,0 +1,56 @@
+dnl GAS_CHECK_DECL_NEEDED(name, typedefname, typedef, headers)
+AC_DEFUN(GAS_CHECK_DECL_NEEDED,[
+AC_MSG_CHECKING(whether declaration is required for $1)
+AC_CACHE_VAL(gas_cv_decl_needed_$1,
+AC_TRY_LINK([$4],
+[
+typedef $3;
+$2 x;
+x = ($2) $1;
+], gas_cv_decl_needed_$1=no, gas_cv_decl_needed_$1=yes))dnl
+AC_MSG_RESULT($gas_cv_decl_needed_$1)
+if test $gas_cv_decl_needed_$1 = yes; then
+ AC_DEFINE([NEED_DECLARATION_]translit($1, [a-z], [A-Z]), 1,
+ [Define if $1 is not declared in system header files.])
+fi
+])dnl
+dnl
+dnl Some non-ANSI preprocessors botch requoting inside strings. That's bad
+dnl enough, but on some of those systems, the assert macro relies on requoting
+dnl working properly!
+dnl GAS_WORKING_ASSERT
+AC_DEFUN(GAS_WORKING_ASSERT,
+[AC_MSG_CHECKING([for working assert macro])
+AC_CACHE_VAL(gas_cv_assert_ok,
+AC_TRY_LINK([#include <assert.h>
+#include <stdio.h>], [
+/* check for requoting problems */
+static int a, b, c, d;
+static char *s;
+assert (!strcmp(s, "foo bar baz quux"));
+/* check for newline handling */
+assert (a == b
+ || c == d);
+], gas_cv_assert_ok=yes, gas_cv_assert_ok=no))dnl
+AC_MSG_RESULT($gas_cv_assert_ok)
+test $gas_cv_assert_ok = yes || AC_DEFINE(BROKEN_ASSERT, 1, [assert broken?])
+])dnl
+dnl
+dnl Since many Bourne shell implementations lack subroutines, use this
+dnl hack to simplify the code in configure.in.
+dnl GAS_UNIQ(listvar)
+AC_DEFUN(GAS_UNIQ,
+[_gas_uniq_list="[$]$1"
+_gas_uniq_newlist=""
+dnl Protect against empty input list.
+for _gas_uniq_i in _gas_uniq_dummy [$]_gas_uniq_list ; do
+ case [$]_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " [$]_gas_uniq_newlist " in
+ *" [$]_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="[$]_gas_uniq_newlist [$]_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+$1=[$]_gas_uniq_newlist
+])dnl
diff --git a/gas/aclocal.m4 b/gas/aclocal.m4
new file mode 100644
index 00000000000..1c6d60cb238
--- /dev/null
+++ b/gas/aclocal.m4
@@ -0,0 +1,822 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+dnl GAS_CHECK_DECL_NEEDED(name, typedefname, typedef, headers)
+AC_DEFUN(GAS_CHECK_DECL_NEEDED,[
+AC_MSG_CHECKING(whether declaration is required for $1)
+AC_CACHE_VAL(gas_cv_decl_needed_$1,
+AC_TRY_LINK([$4],
+[
+typedef $3;
+$2 x;
+x = ($2) $1;
+], gas_cv_decl_needed_$1=no, gas_cv_decl_needed_$1=yes))dnl
+AC_MSG_RESULT($gas_cv_decl_needed_$1)
+if test $gas_cv_decl_needed_$1 = yes; then
+ AC_DEFINE([NEED_DECLARATION_]translit($1, [a-z], [A-Z]), 1,
+ [Define if $1 is not declared in system header files.])
+fi
+])dnl
+dnl
+dnl Some non-ANSI preprocessors botch requoting inside strings. That's bad
+dnl enough, but on some of those systems, the assert macro relies on requoting
+dnl working properly!
+dnl GAS_WORKING_ASSERT
+AC_DEFUN(GAS_WORKING_ASSERT,
+[AC_MSG_CHECKING([for working assert macro])
+AC_CACHE_VAL(gas_cv_assert_ok,
+AC_TRY_LINK([#include <assert.h>
+#include <stdio.h>], [
+/* check for requoting problems */
+static int a, b, c, d;
+static char *s;
+assert (!strcmp(s, "foo bar baz quux"));
+/* check for newline handling */
+assert (a == b
+ || c == d);
+], gas_cv_assert_ok=yes, gas_cv_assert_ok=no))dnl
+AC_MSG_RESULT($gas_cv_assert_ok)
+test $gas_cv_assert_ok = yes || AC_DEFINE(BROKEN_ASSERT, 1, [assert broken?])
+])dnl
+dnl
+dnl Since many Bourne shell implementations lack subroutines, use this
+dnl hack to simplify the code in configure.in.
+dnl GAS_UNIQ(listvar)
+AC_DEFUN(GAS_UNIQ,
+[_gas_uniq_list="[$]$1"
+_gas_uniq_newlist=""
+dnl Protect against empty input list.
+for _gas_uniq_i in _gas_uniq_dummy [$]_gas_uniq_list ; do
+ case [$]_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " [$]_gas_uniq_newlist " in
+ *" [$]_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="[$]_gas_uniq_newlist [$]_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+$1=[$]_gas_uniq_newlist
+])dnl
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+# serial 25 AM_PROG_LIBTOOL
+AC_DEFUN(AM_PROG_LIBTOOL,
+[AC_REQUIRE([AM_ENABLE_SHARED])dnl
+AC_REQUIRE([AM_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AM_PROG_LD])dnl
+AC_REQUIRE([AM_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags=
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ CFLAGS="$CFLAGS -belf"
+ ;;
+
+*-*-cygwin*)
+ AM_SYS_LIBTOOL_CYGWIN
+ ;;
+
+esac
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+# AM_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AM_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AM_ENABLE_SHARED,
+[define([AM_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AM_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AM_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AM_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AM_DISABLE_SHARED,
+[AM_ENABLE_SHARED(no)])
+
+# AM_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AM_DISABLE_STATIC,
+[AM_ENABLE_STATIC(no)])
+
+# AM_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AM_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AM_ENABLE_STATIC,
+[define([AM_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AM_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AM_ENABLE_STATIC_DEFAULT)dnl
+])
+
+
+# AM_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AM_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:\\*)
+changequote([,])dnl
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AM_PROG_LD_GNU
+])
+
+AC_DEFUN(AM_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AM_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AM_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ else
+ ac_cv_path_NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AM_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin
+AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+
+dnl AM_PROG_LEX
+dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT
+AC_DEFUN(AM_PROG_LEX,
+[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1)
+AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex")
+AC_PROG_LEX
+AC_DECL_YYTEXT])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/gas/app.c b/gas/app.c
new file mode 100644
index 00000000000..2a8df3ace5e
--- /dev/null
+++ b/gas/app.c
@@ -0,0 +1,1255 @@
+/* This is the Assembler Pre-Processor
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 */
+/* App, the assembler pre-processor. This pre-processor strips out excess
+ spaces, turns single-quoted characters into a decimal constant, and turns
+ # <number> <filename> <garbage> into a .line <number>\n.file <filename>
+ pair. This needs better error-handling. */
+
+#include <stdio.h>
+#include "as.h" /* For BAD_CASE() only */
+
+#if (__STDC__ != 1)
+#ifndef const
+#define const /* empty */
+#endif
+#endif
+
+/* Whether we are scrubbing in m68k MRI mode. This is different from
+ flag_m68k_mri, because the two flags will be affected by the .mri
+ pseudo-op at different times. */
+static int scrub_m68k_mri;
+
+/* The pseudo-op which switches in and out of MRI mode. See the
+ comment in do_scrub_chars. */
+static const char mri_pseudo[] = ".mri 0";
+
+#if defined TC_ARM && defined OBJ_ELF
+/* The pseudo-op for which we need to special-case `@' characters.
+ See the comment in do_scrub_chars. */
+static const char symver_pseudo[] = ".symver";
+static const char * symver_state;
+#endif
+
+static char lex[256];
+static const char symbol_chars[] =
+"$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+#define LEX_IS_SYMBOL_COMPONENT 1
+#define LEX_IS_WHITESPACE 2
+#define LEX_IS_LINE_SEPARATOR 3
+#define LEX_IS_COMMENT_START 4
+#define LEX_IS_LINE_COMMENT_START 5
+#define LEX_IS_TWOCHAR_COMMENT_1ST 6
+#define LEX_IS_STRINGQUOTE 8
+#define LEX_IS_COLON 9
+#define LEX_IS_NEWLINE 10
+#define LEX_IS_ONECHAR_QUOTE 11
+#ifdef TC_V850
+#define LEX_IS_DOUBLEDASH_1ST 12
+#endif
+#ifdef TC_M32R
+#define LEX_IS_DOUBLEBAR_1ST 13
+#endif
+#define IS_SYMBOL_COMPONENT(c) (lex[c] == LEX_IS_SYMBOL_COMPONENT)
+#define IS_WHITESPACE(c) (lex[c] == LEX_IS_WHITESPACE)
+#define IS_LINE_SEPARATOR(c) (lex[c] == LEX_IS_LINE_SEPARATOR)
+#define IS_COMMENT(c) (lex[c] == LEX_IS_COMMENT_START)
+#define IS_LINE_COMMENT(c) (lex[c] == LEX_IS_LINE_COMMENT_START)
+#define IS_NEWLINE(c) (lex[c] == LEX_IS_NEWLINE)
+
+static int process_escape PARAMS ((int));
+
+/* FIXME-soon: The entire lexer/parser thingy should be
+ built statically at compile time rather than dynamically
+ each and every time the assembler is run. xoxorich. */
+
+void
+do_scrub_begin (m68k_mri)
+ int m68k_mri;
+{
+ const char *p;
+ int c;
+
+ scrub_m68k_mri = m68k_mri;
+
+ lex[' '] = LEX_IS_WHITESPACE;
+ lex['\t'] = LEX_IS_WHITESPACE;
+ lex['\r'] = LEX_IS_WHITESPACE;
+ lex['\n'] = LEX_IS_NEWLINE;
+ lex[';'] = LEX_IS_LINE_SEPARATOR;
+ lex[':'] = LEX_IS_COLON;
+
+ if (! m68k_mri)
+ {
+ lex['"'] = LEX_IS_STRINGQUOTE;
+
+#ifndef TC_HPPA
+ lex['\''] = LEX_IS_ONECHAR_QUOTE;
+#endif
+
+#ifdef SINGLE_QUOTE_STRINGS
+ lex['\''] = LEX_IS_STRINGQUOTE;
+#endif
+ }
+
+ /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop
+ in state 5 of do_scrub_chars must be changed. */
+
+ /* Note that these override the previous defaults, e.g. if ';' is a
+ comment char, then it isn't a line separator. */
+ for (p = symbol_chars; *p; ++p)
+ {
+ lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
+ } /* declare symbol characters */
+
+ for (c = 128; c < 256; ++c)
+ lex[c] = LEX_IS_SYMBOL_COMPONENT;
+
+#ifdef tc_symbol_chars
+ /* This macro permits the processor to specify all characters which
+ may appears in an operand. This will prevent the scrubber from
+ discarding meaningful whitespace in certain cases. The i386
+ backend uses this to support prefixes, which can confuse the
+ scrubber as to whether it is parsing operands or opcodes. */
+ for (p = tc_symbol_chars; *p; ++p)
+ lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
+#endif
+
+ /* The m68k backend wants to be able to change comment_chars. */
+#ifndef tc_comment_chars
+#define tc_comment_chars comment_chars
+#endif
+ for (p = tc_comment_chars; *p; p++)
+ {
+ lex[(unsigned char) *p] = LEX_IS_COMMENT_START;
+ } /* declare comment chars */
+
+ for (p = line_comment_chars; *p; p++)
+ {
+ lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
+ } /* declare line comment chars */
+
+ for (p = line_separator_chars; *p; p++)
+ {
+ lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR;
+ } /* declare line separators */
+
+ /* Only allow slash-star comments if slash is not in use.
+ FIXME: This isn't right. We should always permit them. */
+ if (lex['/'] == 0)
+ {
+ lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST;
+ }
+
+ if (m68k_mri)
+ {
+ lex['\''] = LEX_IS_STRINGQUOTE;
+ lex[';'] = LEX_IS_COMMENT_START;
+ lex['*'] = LEX_IS_LINE_COMMENT_START;
+ /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but
+ then it can't be used in an expression. */
+ lex['!'] = LEX_IS_LINE_COMMENT_START;
+ }
+
+#ifdef TC_V850
+ lex['-'] = LEX_IS_DOUBLEDASH_1ST;
+#endif
+#ifdef TC_M32R
+ lex['|'] = LEX_IS_DOUBLEBAR_1ST;
+#endif
+#ifdef TC_D30V
+ /* must do this is we want VLIW instruction with "->" or "<-" */
+ lex['-'] = LEX_IS_SYMBOL_COMPONENT;
+#endif
+} /* do_scrub_begin() */
+
+/* Saved state of the scrubber */
+static int state;
+static int old_state;
+static char *out_string;
+static char out_buf[20];
+static int add_newlines;
+static char *saved_input;
+static int saved_input_len;
+static const char *mri_state;
+static char mri_last_ch;
+
+/* Data structure for saving the state of app across #include's. Note that
+ app is called asynchronously to the parsing of the .include's, so our
+ state at the time .include is interpreted is completely unrelated.
+ That's why we have to save it all. */
+
+struct app_save
+ {
+ int state;
+ int old_state;
+ char * out_string;
+ char out_buf[sizeof (out_buf)];
+ int add_newlines;
+ char * saved_input;
+ int saved_input_len;
+ int scrub_m68k_mri;
+ const char * mri_state;
+ char mri_last_ch;
+#if defined TC_ARM && defined OBJ_ELF
+ const char * symver_state;
+#endif
+ };
+
+char *
+app_push ()
+{
+ register struct app_save *saved;
+
+ saved = (struct app_save *) xmalloc (sizeof (*saved));
+ saved->state = state;
+ saved->old_state = old_state;
+ saved->out_string = out_string;
+ memcpy (saved->out_buf, out_buf, sizeof (out_buf));
+ saved->add_newlines = add_newlines;
+ saved->saved_input = saved_input;
+ saved->saved_input_len = saved_input_len;
+ saved->scrub_m68k_mri = scrub_m68k_mri;
+ saved->mri_state = mri_state;
+ saved->mri_last_ch = mri_last_ch;
+#if defined TC_ARM && defined OBJ_ELF
+ saved->symver_state = symver_state;
+#endif
+
+ /* do_scrub_begin() is not useful, just wastes time. */
+
+ state = 0;
+ saved_input = NULL;
+
+ return (char *) saved;
+}
+
+void
+app_pop (arg)
+ char *arg;
+{
+ register struct app_save *saved = (struct app_save *) arg;
+
+ /* There is no do_scrub_end (). */
+ state = saved->state;
+ old_state = saved->old_state;
+ out_string = saved->out_string;
+ memcpy (out_buf, saved->out_buf, sizeof (out_buf));
+ add_newlines = saved->add_newlines;
+ saved_input = saved->saved_input;
+ saved_input_len = saved->saved_input_len;
+ scrub_m68k_mri = saved->scrub_m68k_mri;
+ mri_state = saved->mri_state;
+ mri_last_ch = saved->mri_last_ch;
+#if defined TC_ARM && defined OBJ_ELF
+ symver_state = saved->symver_state;
+#endif
+
+ free (arg);
+} /* app_pop() */
+
+/* @@ This assumes that \n &c are the same on host and target. This is not
+ necessarily true. */
+static int
+process_escape (ch)
+ int ch;
+{
+ switch (ch)
+ {
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case '\'':
+ return '\'';
+ case '"':
+ return '\"';
+ default:
+ return ch;
+ }
+}
+
+/* This function is called to process input characters. The GET
+ parameter is used to retrieve more input characters. GET should
+ set its parameter to point to a buffer, and return the length of
+ the buffer; it should return 0 at end of file. The scrubbed output
+ characters are put into the buffer starting at TOSTART; the TOSTART
+ buffer is TOLEN bytes in length. The function returns the number
+ of scrubbed characters put into TOSTART. This will be TOLEN unless
+ end of file was seen. This function is arranged as a state
+ machine, and saves its state so that it may return at any point.
+ This is the way the old code used to work. */
+
+int
+do_scrub_chars (get, tostart, tolen)
+ int (*get) PARAMS ((char **));
+ char *tostart;
+ int tolen;
+{
+ char *to = tostart;
+ char *toend = tostart + tolen;
+ char *from;
+ char *fromend;
+ int fromlen;
+ register int ch, ch2 = 0;
+
+ /*State 0: beginning of normal line
+ 1: After first whitespace on line (flush more white)
+ 2: After first non-white (opcode) on line (keep 1white)
+ 3: after second white on line (into operands) (flush white)
+ 4: after putting out a .line, put out digits
+ 5: parsing a string, then go to old-state
+ 6: putting out \ escape in a "d string.
+ 7: After putting out a .appfile, put out string.
+ 8: After putting out a .appfile string, flush until newline.
+ 9: After seeing symbol char in state 3 (keep 1white after symchar)
+ 10: After seeing whitespace in state 9 (keep white before symchar)
+ 11: After seeing a symbol character in state 0 (eg a label definition)
+ -1: output string in out_string and go to the state in old_state
+ -2: flush text until a '*' '/' is seen, then go to state old_state
+#ifdef TC_V850
+ 12: After seeing a dash, looking for a second dash as a start of comment.
+#endif
+#ifdef TC_M32R
+ 13: After seeing a vertical bar, looking for a second vertical bar as a parallel expression seperator.
+#endif
+ */
+
+ /* I added states 9 and 10 because the MIPS ECOFF assembler uses
+ constructs like ``.loc 1 20''. This was turning into ``.loc
+ 120''. States 9 and 10 ensure that a space is never dropped in
+ between characters which could appear in a identifier. Ian
+ Taylor, ian@cygnus.com.
+
+ I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works
+ correctly on the PA (and any other target where colons are optional).
+ Jeff Law, law@cs.utah.edu.
+
+ I added state 13 so that something like "cmp r1, r2 || trap #1" does not
+ get squashed into "cmp r1,r2||trap#1", with the all important space
+ between the 'trap' and the '#1' being eliminated. nickc@cygnus.com */
+
+ /* This macro gets the next input character. */
+
+#define GET() \
+ (from < fromend \
+ ? * (unsigned char *) (from++) \
+ : ((saved_input != NULL \
+ ? (free (saved_input), \
+ saved_input = NULL, \
+ 0) \
+ : 0), \
+ fromlen = (*get) (&from), \
+ fromend = from + fromlen, \
+ (fromlen == 0 \
+ ? EOF \
+ : * (unsigned char *) (from++))))
+
+ /* This macro pushes a character back on the input stream. */
+
+#define UNGET(uch) (*--from = (uch))
+
+ /* This macro puts a character into the output buffer. If this
+ character fills the output buffer, this macro jumps to the label
+ TOFULL. We use this rather ugly approach because we need to
+ handle two different termination conditions: EOF on the input
+ stream, and a full output buffer. It would be simpler if we
+ always read in the entire input stream before processing it, but
+ I don't want to make such a significant change to the assembler's
+ memory usage. */
+
+#define PUT(pch) \
+ do \
+ { \
+ *to++ = (pch); \
+ if (to >= toend) \
+ goto tofull; \
+ } \
+ while (0)
+
+ if (saved_input != NULL)
+ {
+ from = saved_input;
+ fromend = from + saved_input_len;
+ }
+ else
+ {
+ fromlen = (*get) (&from);
+ if (fromlen == 0)
+ return 0;
+ fromend = from + fromlen;
+ }
+
+ while (1)
+ {
+ /* The cases in this switch end with continue, in order to
+ branch back to the top of this while loop and generate the
+ next output character in the appropriate state. */
+ switch (state)
+ {
+ case -1:
+ ch = *out_string++;
+ if (*out_string == '\0')
+ {
+ state = old_state;
+ old_state = 3;
+ }
+ PUT (ch);
+ continue;
+
+ case -2:
+ for (;;)
+ {
+ do
+ {
+ ch = GET ();
+
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment"));
+ goto fromeof;
+ }
+
+ if (ch == '\n')
+ PUT ('\n');
+ }
+ while (ch != '*');
+
+ while ((ch = GET ()) == '*')
+ ;
+
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment"));
+ goto fromeof;
+ }
+
+ if (ch == '/')
+ break;
+
+ UNGET (ch);
+ }
+
+ state = old_state;
+ UNGET (' ');
+ continue;
+
+ case 4:
+ ch = GET ();
+ if (ch == EOF)
+ goto fromeof;
+ else if (ch >= '0' && ch <= '9')
+ PUT (ch);
+ else
+ {
+ while (ch != EOF && IS_WHITESPACE (ch))
+ ch = GET ();
+ if (ch == '"')
+ {
+ UNGET (ch);
+ if (scrub_m68k_mri)
+ out_string = "\n\tappfile ";
+ else
+ out_string = "\n\t.appfile ";
+ old_state = 7;
+ state = -1;
+ PUT (*out_string++);
+ }
+ else
+ {
+ while (ch != EOF && ch != '\n')
+ ch = GET ();
+ state = 0;
+ PUT (ch);
+ }
+ }
+ continue;
+
+ case 5:
+ /* We are going to copy everything up to a quote character,
+ with special handling for a backslash. We try to
+ optimize the copying in the simple case without using the
+ GET and PUT macros. */
+ {
+ char *s;
+ int len;
+
+ for (s = from; s < fromend; s++)
+ {
+ ch = *s;
+ /* This condition must be changed if the type of any
+ other character can be LEX_IS_STRINGQUOTE. */
+ if (ch == '\\'
+ || ch == '"'
+ || ch == '\''
+ || ch == '\n')
+ break;
+ }
+ len = s - from;
+ if (len > toend - to)
+ len = toend - to;
+ if (len > 0)
+ {
+ memcpy (to, from, len);
+ to += len;
+ from += len;
+ }
+ }
+
+ ch = GET ();
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in string: inserted '\"'"));
+ state = old_state;
+ UNGET ('\n');
+ PUT ('"');
+ }
+ else if (lex[ch] == LEX_IS_STRINGQUOTE)
+ {
+ state = old_state;
+ PUT (ch);
+ }
+#ifndef NO_STRING_ESCAPES
+ else if (ch == '\\')
+ {
+ state = 6;
+ PUT (ch);
+ }
+#endif
+ else if (scrub_m68k_mri && ch == '\n')
+ {
+ /* Just quietly terminate the string. This permits lines like
+ bne label loop if we haven't reach end yet
+ */
+ state = old_state;
+ UNGET (ch);
+ PUT ('\'');
+ }
+ else
+ {
+ PUT (ch);
+ }
+ continue;
+
+ case 6:
+ state = 5;
+ ch = GET ();
+ switch (ch)
+ {
+ /* Handle strings broken across lines, by turning '\n' into
+ '\\' and 'n'. */
+ case '\n':
+ UNGET ('n');
+ add_newlines++;
+ PUT ('\\');
+ continue;
+
+ case '"':
+ case '\\':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'v':
+ case 'x':
+ case 'X':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ break;
+#if defined(IGNORE_NONSTANDARD_ESCAPES) | defined(ONLY_STANDARD_ESCAPES)
+ default:
+ as_warn (_("Unknown escape '\\%c' in string: Ignored"), ch);
+ break;
+#else /* ONLY_STANDARD_ESCAPES */
+ default:
+ /* Accept \x as x for any x */
+ break;
+#endif /* ONLY_STANDARD_ESCAPES */
+
+ case EOF:
+ as_warn (_("End of file in string: '\"' inserted"));
+ PUT ('"');
+ continue;
+ }
+ PUT (ch);
+ continue;
+
+ case 7:
+ ch = GET ();
+ state = 5;
+ old_state = 8;
+ if (ch == EOF)
+ goto fromeof;
+ PUT (ch);
+ continue;
+
+ case 8:
+ do
+ ch = GET ();
+ while (ch != '\n' && ch != EOF);
+ if (ch == EOF)
+ goto fromeof;
+ state = 0;
+ PUT (ch);
+ continue;
+ }
+
+ /* OK, we are somewhere in states 0 through 4 or 9 through 11 */
+
+ /* flushchar: */
+ ch = GET ();
+
+ recycle:
+
+#if defined TC_ARM && defined OBJ_ELF
+ /* We need to watch out for .symver directives. See the comment later
+ in this function. */
+ if (symver_state == NULL)
+ {
+ if ((state == 0 || state == 1) && ch == symver_pseudo[0])
+ symver_state = symver_pseudo + 1;
+ }
+ else
+ {
+ /* We advance to the next state if we find the right
+ character. */
+ if (ch != '\0' && (*symver_state == ch))
+ ++symver_state;
+ else if (*symver_state != '\0')
+ /* We did not get the expected character, or we didn't
+ get a valid terminating character after seeing the
+ entire pseudo-op, so we must go back to the beginning. */
+ symver_state = NULL;
+ else
+ {
+ /* We've read the entire pseudo-op. If this is the end
+ of the line, go back to the beginning. */
+ if (IS_NEWLINE (ch))
+ symver_state = NULL;
+ }
+ }
+#endif /* TC_ARM && OBJ_ELF */
+
+#ifdef TC_M68K
+ /* We want to have pseudo-ops which control whether we are in
+ MRI mode or not. Unfortunately, since m68k MRI mode affects
+ the scrubber, that means that we need a special purpose
+ recognizer here. */
+ if (mri_state == NULL)
+ {
+ if ((state == 0 || state == 1)
+ && ch == mri_pseudo[0])
+ mri_state = mri_pseudo + 1;
+ }
+ else
+ {
+ /* We advance to the next state if we find the right
+ character, or if we need a space character and we get any
+ whitespace character, or if we need a '0' and we get a
+ '1' (this is so that we only need one state to handle
+ ``.mri 0'' and ``.mri 1''). */
+ if (ch != '\0'
+ && (*mri_state == ch
+ || (*mri_state == ' '
+ && lex[ch] == LEX_IS_WHITESPACE)
+ || (*mri_state == '0'
+ && ch == '1')))
+ {
+ mri_last_ch = ch;
+ ++mri_state;
+ }
+ else if (*mri_state != '\0'
+ || (lex[ch] != LEX_IS_WHITESPACE
+ && lex[ch] != LEX_IS_NEWLINE))
+ {
+ /* We did not get the expected character, or we didn't
+ get a valid terminating character after seeing the
+ entire pseudo-op, so we must go back to the
+ beginning. */
+ mri_state = NULL;
+ }
+ else
+ {
+ /* We've read the entire pseudo-op. mips_last_ch is
+ either '0' or '1' indicating whether to enter or
+ leave MRI mode. */
+ do_scrub_begin (mri_last_ch == '1');
+ mri_state = NULL;
+
+ /* We continue handling the character as usual. The
+ main gas reader must also handle the .mri pseudo-op
+ to control expression parsing and the like. */
+ }
+ }
+#endif
+
+ if (ch == EOF)
+ {
+ if (state != 0)
+ {
+ as_warn (_("end of file not at end of a line; newline inserted"));
+ state = 0;
+ PUT ('\n');
+ }
+ goto fromeof;
+ }
+
+ switch (lex[ch])
+ {
+ case LEX_IS_WHITESPACE:
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && IS_WHITESPACE (ch));
+ if (ch == EOF)
+ goto fromeof;
+
+ if (state == 0)
+ {
+ /* Preserve a single whitespace character at the
+ beginning of a line. */
+ state = 1;
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+
+ if (IS_COMMENT (ch)
+ || ch == '/'
+ || IS_LINE_SEPARATOR (ch))
+ {
+ if (scrub_m68k_mri)
+ {
+ /* In MRI mode, we keep these spaces. */
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ goto recycle;
+ }
+
+ /* If we're in state 2 or 11, we've seen a non-white
+ character followed by whitespace. If the next character
+ is ':', this is whitespace after a label name which we
+ normally must ignore. In MRI mode, though, spaces are
+ not permitted between the label and the colon. */
+ if ((state == 2 || state == 11)
+ && lex[ch] == LEX_IS_COLON
+ && ! scrub_m68k_mri)
+ {
+ state = 1;
+ PUT (ch);
+ break;
+ }
+
+ switch (state)
+ {
+ case 0:
+ state++;
+ goto recycle; /* Punted leading sp */
+ case 1:
+ /* We can arrive here if we leave a leading whitespace
+ character at the beginning of a line. */
+ goto recycle;
+ case 2:
+ state = 3;
+ if (to + 1 < toend)
+ {
+ /* Optimize common case by skipping UNGET/GET. */
+ PUT (' '); /* Sp after opco */
+ goto recycle;
+ }
+ UNGET (ch);
+ PUT (' ');
+ break;
+ case 3:
+ if (scrub_m68k_mri)
+ {
+ /* In MRI mode, we keep these spaces. */
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ goto recycle; /* Sp in operands */
+ case 9:
+ case 10:
+ if (scrub_m68k_mri)
+ {
+ /* In MRI mode, we keep these spaces. */
+ state = 3;
+ UNGET (ch);
+ PUT (' ');
+ break;
+ }
+ state = 10; /* Sp after symbol char */
+ goto recycle;
+ case 11:
+ if (flag_m68k_mri
+#ifdef LABELS_WITHOUT_COLONS
+ || 1
+#endif
+ )
+ state = 1;
+ else
+ {
+ /* We know that ch is not ':', since we tested that
+ case above. Therefore this is not a label, so it
+ must be the opcode, and we've just seen the
+ whitespace after it. */
+ state = 3;
+ }
+ UNGET (ch);
+ PUT (' '); /* Sp after label definition. */
+ break;
+ default:
+ BAD_CASE (state);
+ }
+ break;
+
+ case LEX_IS_TWOCHAR_COMMENT_1ST:
+ ch2 = GET ();
+ if (ch2 == '*')
+ {
+ for (;;)
+ {
+ do
+ {
+ ch2 = GET ();
+ if (ch2 != EOF && IS_NEWLINE (ch2))
+ add_newlines++;
+ }
+ while (ch2 != EOF && ch2 != '*');
+
+ while (ch2 == '*')
+ ch2 = GET ();
+
+ if (ch2 == EOF || ch2 == '/')
+ break;
+
+ /* This UNGET will ensure that we count newlines
+ correctly. */
+ UNGET (ch2);
+ }
+
+ if (ch2 == EOF)
+ as_warn (_("end of file in multiline comment"));
+
+ ch = ' ';
+ goto recycle;
+ }
+ else
+ {
+ if (ch2 != EOF)
+ UNGET (ch2);
+ if (state == 9 || state == 10)
+ state = 3;
+ PUT (ch);
+ }
+ break;
+
+ case LEX_IS_STRINGQUOTE:
+ if (state == 10)
+ {
+ /* Preserve the whitespace in foo "bar" */
+ UNGET (ch);
+ state = 3;
+ PUT (' ');
+
+ /* PUT didn't jump out. We could just break, but we
+ know what will happen, so optimize a bit. */
+ ch = GET ();
+ old_state = 3;
+ }
+ else if (state == 9)
+ old_state = 3;
+ else
+ old_state = state;
+ state = 5;
+ PUT (ch);
+ break;
+
+#ifndef IEEE_STYLE
+ case LEX_IS_ONECHAR_QUOTE:
+ if (state == 10)
+ {
+ /* Preserve the whitespace in foo 'b' */
+ UNGET (ch);
+ state = 3;
+ PUT (' ');
+ break;
+ }
+ ch = GET ();
+ if (ch == EOF)
+ {
+ as_warn (_("end of file after a one-character quote; \\0 inserted"));
+ ch = 0;
+ }
+ if (ch == '\\')
+ {
+ ch = GET ();
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in escape character"));
+ ch = '\\';
+ }
+ else
+ ch = process_escape (ch);
+ }
+ sprintf (out_buf, "%d", (int) (unsigned char) ch);
+
+ /* None of these 'x constants for us. We want 'x'. */
+ if ((ch = GET ()) != '\'')
+ {
+#ifdef REQUIRE_CHAR_CLOSE_QUOTE
+ as_warn (_("Missing close quote: (assumed)"));
+#else
+ if (ch != EOF)
+ UNGET (ch);
+#endif
+ }
+ if (strlen (out_buf) == 1)
+ {
+ PUT (out_buf[0]);
+ break;
+ }
+ if (state == 9)
+ old_state = 3;
+ else
+ old_state = state;
+ state = -1;
+ out_string = out_buf;
+ PUT (*out_string++);
+ break;
+#endif
+
+ case LEX_IS_COLON:
+ if (state == 9 || state == 10)
+ state = 3;
+ else if (state != 3)
+ state = 1;
+ PUT (ch);
+ break;
+
+ case LEX_IS_NEWLINE:
+ /* Roll out a bunch of newlines from inside comments, etc. */
+ if (add_newlines)
+ {
+ --add_newlines;
+ UNGET (ch);
+ }
+ /* fall thru into... */
+
+ case LEX_IS_LINE_SEPARATOR:
+ state = 0;
+ PUT (ch);
+ break;
+
+#ifdef TC_V850
+ case LEX_IS_DOUBLEDASH_1ST:
+ ch2 = GET();
+ if (ch2 != '-')
+ {
+ UNGET (ch2);
+ goto de_fault;
+ }
+ /* read and skip to end of line */
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && ch != '\n');
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment; newline inserted"));
+ }
+ state = 0;
+ PUT ('\n');
+ break;
+#endif
+#ifdef TC_M32R
+ case LEX_IS_DOUBLEBAR_1ST:
+ ch2 = GET();
+ if (ch2 != '|')
+ {
+ UNGET (ch2);
+ goto de_fault;
+ }
+ /* Reset back to state 1 and pretend that we are parsing a line from
+ just after the first white space. */
+ state = 1;
+ PUT ('|');
+ PUT ('|');
+ break;
+#endif
+ case LEX_IS_LINE_COMMENT_START:
+ /* FIXME-someday: The two character comment stuff was badly
+ thought out. On i386, we want '/' as line comment start
+ AND we want C style comments. hence this hack. The
+ whole lexical process should be reworked. xoxorich. */
+ if (ch == '/')
+ {
+ ch2 = GET ();
+ if (ch2 == '*')
+ {
+ old_state = 3;
+ state = -2;
+ break;
+ }
+ else
+ {
+ UNGET (ch2);
+ }
+ } /* bad hack */
+
+ if (state == 0 || state == 1) /* Only comment at start of line. */
+ {
+ int startch;
+
+ startch = ch;
+
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && IS_WHITESPACE (ch));
+ if (ch == EOF)
+ {
+ as_warn (_("end of file in comment; newline inserted"));
+ PUT ('\n');
+ break;
+ }
+ if (ch < '0' || ch > '9' || state != 0 || startch != '#')
+ {
+ /* Not a cpp line. */
+ while (ch != EOF && !IS_NEWLINE (ch))
+ ch = GET ();
+ if (ch == EOF)
+ as_warn (_("EOF in Comment: Newline inserted"));
+ state = 0;
+ PUT ('\n');
+ break;
+ }
+ /* Loks like `# 123 "filename"' from cpp. */
+ UNGET (ch);
+ old_state = 4;
+ state = -1;
+ if (scrub_m68k_mri)
+ out_string = "\tappline ";
+ else
+ out_string = "\t.appline ";
+ PUT (*out_string++);
+ break;
+ }
+
+#ifdef TC_D10V
+ /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true.
+ Trap is the only short insn that has a first operand that is
+ neither register nor label.
+ We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 .
+ We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is already
+ LEX_IS_LINE_COMMENT_START. However, it is the only character in
+ line_comment_chars for d10v, hence we can recognize it as such. */
+ /* An alternative approach would be to reset the state to 1 when
+ we see '||', '<'- or '->', but that seems to be overkill. */
+ if (state == 10) PUT (' ');
+#endif
+ /* We have a line comment character which is not at the
+ start of a line. If this is also a normal comment
+ character, fall through. Otherwise treat it as a default
+ character. */
+ if (strchr (tc_comment_chars, ch) == NULL
+ && (! scrub_m68k_mri
+ || (ch != '!' && ch != '*')))
+ goto de_fault;
+ if (scrub_m68k_mri
+ && (ch == '!' || ch == '*' || ch == '#')
+ && state != 1
+ && state != 10)
+ goto de_fault;
+ /* Fall through. */
+ case LEX_IS_COMMENT_START:
+#if defined TC_ARM && defined OBJ_ELF
+ /* On the ARM, `@' is the comment character.
+ Unfortunately this is also a special character in ELF .symver
+ directives (and .type, though we deal with those another way). So
+ we check if this line is such a directive, and treat the character
+ as default if so. This is a hack. */
+ if ((symver_state != NULL) && (*symver_state == 0))
+ goto de_fault;
+#endif
+ do
+ {
+ ch = GET ();
+ }
+ while (ch != EOF && !IS_NEWLINE (ch));
+ if (ch == EOF)
+ as_warn (_("end of file in comment; newline inserted"));
+ state = 0;
+ PUT ('\n');
+ break;
+
+ case LEX_IS_SYMBOL_COMPONENT:
+ if (state == 10)
+ {
+ /* This is a symbol character following another symbol
+ character, with whitespace in between. We skipped
+ the whitespace earlier, so output it now. */
+ UNGET (ch);
+ state = 3;
+ PUT (' ');
+ break;
+ }
+
+ if (state == 3)
+ state = 9;
+
+ /* This is a common case. Quickly copy CH and all the
+ following symbol component or normal characters. */
+ if (to + 1 < toend
+ && mri_state == NULL
+#if defined TC_ARM && defined OBJ_ELF
+ && symver_state == NULL
+#endif
+ )
+ {
+ char *s;
+ int len;
+
+ for (s = from; s < fromend; s++)
+ {
+ int type;
+
+ ch2 = * (unsigned char *) s;
+ type = lex[ch2];
+ if (type != 0
+ && type != LEX_IS_SYMBOL_COMPONENT)
+ break;
+ }
+ if (s > from)
+ {
+ /* Handle the last character normally, for
+ simplicity. */
+ --s;
+ }
+ len = s - from;
+ if (len > (toend - to) - 1)
+ len = (toend - to) - 1;
+ if (len > 0)
+ {
+ PUT (ch);
+ if (len > 8)
+ {
+ memcpy (to, from, len);
+ to += len;
+ from += len;
+ }
+ else
+ {
+ switch (len)
+ {
+ case 8: *to++ = *from++;
+ case 7: *to++ = *from++;
+ case 6: *to++ = *from++;
+ case 5: *to++ = *from++;
+ case 4: *to++ = *from++;
+ case 3: *to++ = *from++;
+ case 2: *to++ = *from++;
+ case 1: *to++ = *from++;
+ }
+ }
+ ch = GET ();
+ }
+ }
+
+ /* Fall through. */
+ default:
+ de_fault:
+ /* Some relatively `normal' character. */
+ if (state == 0)
+ {
+ state = 11; /* Now seeing label definition */
+ }
+ else if (state == 1)
+ {
+ state = 2; /* Ditto */
+ }
+ else if (state == 9)
+ {
+ if (lex[ch] != LEX_IS_SYMBOL_COMPONENT)
+ state = 3;
+ }
+ else if (state == 10)
+ {
+ state = 3;
+ }
+ PUT (ch);
+ break;
+ }
+ }
+
+ /*NOTREACHED*/
+
+ fromeof:
+ /* We have reached the end of the input. */
+ return to - tostart;
+
+ tofull:
+ /* The output buffer is full. Save any input we have not yet
+ processed. */
+ if (fromend > from)
+ {
+ char *save;
+
+ save = (char *) xmalloc (fromend - from);
+ memcpy (save, from, fromend - from);
+ if (saved_input != NULL)
+ free (saved_input);
+ saved_input = save;
+ saved_input_len = fromend - from;
+ }
+ else
+ {
+ if (saved_input != NULL)
+ {
+ free (saved_input);
+ saved_input = NULL;
+ }
+ }
+ return to - tostart;
+}
+
+/* end of app.c */
diff --git a/gas/as.c b/gas/as.c
new file mode 100644
index 00000000000..0cdd357dc7d
--- /dev/null
+++ b/gas/as.c
@@ -0,0 +1,1010 @@
+/* as.c - GAS main program.
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * Main program for AS; a 32-bit assembler of GNU.
+ * Understands command arguments.
+ * Has a few routines that don't fit in other modules because they
+ * are shared.
+ *
+ *
+ * bugs
+ *
+ * : initialisers
+ * Since no-one else says they will support them in future: I
+ * don't support them now.
+ *
+ */
+
+#include "ansidecl.h"
+
+#define COMMON
+
+#include "as.h"
+#include "subsegs.h"
+#include "output-file.h"
+#include "sb.h"
+#include "macro.h"
+
+#ifndef HAVE_ITBL_CPU
+#define itbl_parse(itbl_file) 1
+#define itbl_init()
+#endif
+
+#ifdef HAVE_SBRK
+#ifdef NEED_DECLARATION_SBRK
+extern PTR sbrk ();
+#endif
+#endif
+
+static void show_usage PARAMS ((FILE *));
+static void parse_args PARAMS ((int *, char ***));
+static void dump_statistics PARAMS ((void));
+static void perform_an_assembly_pass PARAMS ((int argc, char **argv));
+static int macro_expr PARAMS ((const char *, int, sb *, int *));
+
+int listing; /* true if a listing is wanted */
+
+static char *listing_filename = NULL; /* Name of listing file. */
+
+/* Type of debugging to generate. */
+
+enum debug_info_type debug_type = DEBUG_NONE;
+
+/* Maximum level of macro nesting. */
+
+int max_macro_nest = 100;
+
+char *myname; /* argv[0] */
+#ifdef BFD_ASSEMBLER
+segT reg_section, expr_section;
+segT text_section, data_section, bss_section;
+#endif
+
+/* The default obstack chunk size. If we set this to zero, the
+ obstack code will use whatever will fit in a 4096 byte block. */
+int chunksize = 0;
+
+/* To monitor memory allocation more effectively, make this non-zero.
+ Then the chunk sizes for gas and bfd will be reduced. */
+int debug_memory = 0;
+
+/* We build a list of defsyms as we read the options, and then define
+ them after we have initialized everything. */
+
+struct defsym_list
+{
+ struct defsym_list *next;
+ char *name;
+ valueT value;
+};
+
+static struct defsym_list *defsyms;
+
+/* Keep a record of the itbl files we read in. */
+
+struct itbl_file_list
+{
+ struct itbl_file_list *next;
+ char *name;
+};
+
+static struct itbl_file_list *itbl_files;
+
+void
+print_version_id ()
+{
+ static int printed;
+ if (printed)
+ return;
+ printed = 1;
+
+#ifdef BFD_ASSEMBLER
+ fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s"),
+ VERSION, TARGET_ALIAS, BFD_VERSION);
+#else
+ fprintf (stderr, _("GNU assembler version %s (%s)"), VERSION, TARGET_ALIAS);
+#endif
+ fprintf (stderr, "\n");
+}
+
+static void
+show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname);
+
+ fprintf (stream, _("\
+Options:\n\
+ -a[sub-option...] turn on listings\n\
+ Sub-options [default hls]:\n\
+ c omit false conditionals\n\
+ d omit debugging directives\n\
+ h include high-level source\n\
+ l include assembly\n\
+ m include macro expansions\n\
+ n omit forms processing\n\
+ s include symbols\n\
+ =file set listing file name (must be last sub-option)\n"));
+
+ fprintf (stream, _("\
+ -D produce assembler debugging messages\n\
+ --defsym SYM=VAL define symbol SYM to given value\n\
+ -f skip whitespace and comment preprocessing\n\
+ --gstabs generate stabs debugging information\n\
+ --help show this message and exit\n\
+ -I DIR add DIR to search list for .include directives\n\
+ -J don't warn about signed overflow\n\
+ -K warn when differences altered for long displacements\n\
+ -L,--keep-locals keep local symbols (e.g. starting with `L')\n"));
+
+ fprintf (stream, _("\
+ -M,--mri assemble in MRI compatibility mode\n\
+ --MD FILE write dependency information in FILE (default none)\n\
+ -nocpp ignored\n\
+ -o OBJFILE name the object-file output OBJFILE (default a.out)\n\
+ -R fold data section into text section\n\
+ --statistics print various measured statistics from execution\n\
+ --strip-local-absolute strip local absolute symbols\n\
+ --traditional-format Use same format as native assembler when possible\n\
+ --version print assembler version number and exit\n\
+ -W suppress warnings\n\
+ --itbl INSTTBL extend instruction set to include instructions\n\
+ matching the specifications defined in file INSTTBL\n\
+ -w ignored\n\
+ -X ignored\n\
+ -Z generate object file even after errors\n"));
+
+ fprintf (stream, _("\
+ --listing-lhs-width set the width in words of the output data column of\n\
+ the listing\n\
+ --listing-lhs-width2 set the width in words of the continuation lines\n\
+ of the output data column; ignored if smaller than\n\
+ the width of the first line\n\
+ --listing-rhs-width set the max width in characters of the lines from\n\
+ the source file\n\
+ --listing-cont-lines set the maximum number of continuation lines used\n\
+ for the output data column of the listing\n"));
+
+ md_show_usage (stream);
+
+ fprintf (stream, _("\nReport bugs to bug-gnu-utils@gnu.org\n"));
+}
+
+#ifdef USE_EMULATIONS
+#define EMULATION_ENVIRON "AS_EMULATION"
+
+extern struct emulation mipsbelf, mipslelf, mipself;
+extern struct emulation mipsbecoff, mipslecoff, mipsecoff;
+extern struct emulation i386coff, i386elf;
+
+static struct emulation *const emulations[] = { EMULATIONS };
+static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
+
+static void select_emulation_mode PARAMS ((int, char **));
+
+static void
+select_emulation_mode (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ char *p, *em = 0;
+
+ for (i = 1; i < argc; i++)
+ if (!strncmp ("--em", argv[i], 4))
+ break;
+
+ if (i == argc)
+ goto do_default;
+
+ p = strchr (argv[i], '=');
+ if (p)
+ p++;
+ else
+ p = argv[i+1];
+
+ if (!p || !*p)
+ as_fatal (_("missing emulation mode name"));
+ em = p;
+
+ do_default:
+ if (em == 0)
+ em = getenv (EMULATION_ENVIRON);
+ if (em == 0)
+ em = DEFAULT_EMULATION;
+
+ if (em)
+ {
+ for (i = 0; i < n_emulations; i++)
+ if (!strcmp (emulations[i]->name, em))
+ break;
+ if (i == n_emulations)
+ as_fatal (_("unrecognized emulation name `%s'"), em);
+ this_emulation = emulations[i];
+ }
+ else
+ this_emulation = emulations[0];
+
+ this_emulation->init ();
+}
+
+const char *
+default_emul_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+void
+common_emul_init ()
+{
+ this_format = this_emulation->format;
+
+ if (this_emulation->leading_underscore == 2)
+ this_emulation->leading_underscore = this_format->dfl_leading_underscore;
+
+ if (this_emulation->default_endian != 2)
+ target_big_endian = this_emulation->default_endian;
+
+ if (this_emulation->fake_label_name == 0)
+ {
+ if (this_emulation->leading_underscore)
+ this_emulation->fake_label_name = "L0\001";
+ else
+ /* What other parameters should we test? */
+ this_emulation->fake_label_name = ".L0\001";
+ }
+}
+#endif
+
+/*
+ * Since it is easy to do here we interpret the special arg "-"
+ * to mean "use stdin" and we set that argv[] pointing to "".
+ * After we have munged argv[], the only things left are source file
+ * name(s) and ""(s) denoting stdin. These file names are used
+ * (perhaps more than once) later.
+ *
+ * check for new machine-dep cmdline options in
+ * md_parse_option definitions in config/tc-*.c
+ */
+
+static void
+parse_args (pargc, pargv)
+ int *pargc;
+ char ***pargv;
+{
+ int old_argc, new_argc;
+ char **old_argv, **new_argv;
+
+ /* Starting the short option string with '-' is for programs that
+ expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1. */
+
+ char *shortopts;
+ extern CONST char *md_shortopts;
+ static const char std_shortopts[] =
+ {
+ '-', 'J',
+#ifndef WORKING_DOT_WORD
+ /* -K is not meaningful if .word is not being hacked. */
+ 'K',
+#endif
+ 'L', 'M', 'R', 'W', 'Z', 'f', 'a', ':', ':', 'D', 'I', ':', 'o', ':',
+#ifndef VMS
+ /* -v takes an argument on VMS, so we don't make it a generic
+ option. */
+ 'v',
+#endif
+ 'w', 'X',
+ /* New option for extending instruction set (see also --itbl below) */
+ 't', ':',
+ '\0'
+ };
+ struct option *longopts;
+ extern struct option md_longopts[];
+ extern size_t md_longopts_size;
+ static const struct option std_longopts[] = {
+#define OPTION_HELP (OPTION_STD_BASE)
+ {"help", no_argument, NULL, OPTION_HELP},
+ {"keep-locals", no_argument, NULL, 'L'},
+ {"mri", no_argument, NULL, 'M'},
+#define OPTION_NOCPP (OPTION_STD_BASE + 1)
+ {"nocpp", no_argument, NULL, OPTION_NOCPP},
+#define OPTION_STATISTICS (OPTION_STD_BASE + 2)
+ {"statistics", no_argument, NULL, OPTION_STATISTICS},
+#define OPTION_VERSION (OPTION_STD_BASE + 3)
+ {"version", no_argument, NULL, OPTION_VERSION},
+#define OPTION_DUMPCONFIG (OPTION_STD_BASE + 4)
+ {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG},
+#define OPTION_VERBOSE (OPTION_STD_BASE + 5)
+ {"verbose", no_argument, NULL, OPTION_VERBOSE},
+#define OPTION_EMULATION (OPTION_STD_BASE + 6)
+ {"emulation", required_argument, NULL, OPTION_EMULATION},
+#define OPTION_DEFSYM (OPTION_STD_BASE + 7)
+ {"defsym", required_argument, NULL, OPTION_DEFSYM},
+#define OPTION_INSTTBL (OPTION_STD_BASE + 8)
+ /* New option for extending instruction set (see also -t above).
+ The "-t file" or "--itbl file" option extends the basic set of
+ valid instructions by reading "file", a text file containing a
+ list of instruction formats. The additional opcodes and their
+ formats are added to the built-in set of instructions, and
+ mnemonics for new registers may also be defined. */
+ {"itbl", required_argument, NULL, OPTION_INSTTBL},
+#define OPTION_LISTING_LHS_WIDTH (OPTION_STD_BASE + 9)
+ {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH},
+#define OPTION_LISTING_LHS_WIDTH2 (OPTION_STD_BASE + 10)
+ {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2},
+#define OPTION_LISTING_RHS_WIDTH (OPTION_STD_BASE + 11)
+ {"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH},
+#define OPTION_LISTING_CONT_LINES (OPTION_STD_BASE + 12)
+ {"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES},
+#define OPTION_DEPFILE (OPTION_STD_BASE + 13)
+ {"MD", required_argument, NULL, OPTION_DEPFILE},
+#define OPTION_GSTABS (OPTION_STD_BASE + 14)
+ {"gstabs", no_argument, NULL, OPTION_GSTABS},
+#define OPTION_STRIP_LOCAL_ABSOLUTE (OPTION_STD_BASE + 15)
+ {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE},
+#define OPTION_TRADITIONAL_FORMAT (OPTION_STD_BASE + 16)
+ {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT}
+ };
+
+ /* Construct the option lists from the standard list and the
+ target dependent list. */
+ shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
+ longopts = (struct option *) xmalloc (sizeof (std_longopts) + md_longopts_size);
+ memcpy (longopts, std_longopts, sizeof (std_longopts));
+ memcpy ((char *) longopts + sizeof (std_longopts),
+ md_longopts, md_longopts_size);
+
+ /* Make a local copy of the old argv. */
+ old_argc = *pargc;
+ old_argv = *pargv;
+
+ /* Initialize a new argv that contains no options. */
+ new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1));
+ new_argv[0] = old_argv[0];
+ new_argc = 1;
+ new_argv[new_argc] = NULL;
+
+ while (1)
+ {
+ /* getopt_long_only is like getopt_long, but '-' as well as '--' can
+ indicate a long option. */
+ int longind;
+ int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
+ &longind);
+
+ if (optc == -1)
+ break;
+
+ switch (optc)
+ {
+ default:
+ /* md_parse_option should return 1 if it recognizes optc,
+ 0 if not. */
+ if (md_parse_option (optc, optarg) != 0)
+ break;
+ /* `-v' isn't included in the general short_opts list, so check for
+ it explicity here before deciding we've gotten a bad argument. */
+ if (optc == 'v')
+ {
+#ifdef VMS
+ /* Telling getopt to treat -v's value as optional can result
+ in it picking up a following filename argument here. The
+ VMS code in md_parse_option can return 0 in that case,
+ but it has no way of pushing the filename argument back. */
+ if (optarg && *optarg)
+ new_argv[new_argc++] = optarg, new_argv[new_argc] = NULL;
+ else
+#else
+ case 'v':
+#endif
+ case OPTION_VERBOSE:
+ print_version_id ();
+ break;
+ }
+ /*FALLTHRU*/
+
+ case '?':
+ exit (EXIT_FAILURE);
+
+ case 1: /* File name. */
+ if (!strcmp (optarg, "-"))
+ optarg = "";
+ new_argv[new_argc++] = optarg;
+ new_argv[new_argc] = NULL;
+ break;
+
+ case OPTION_HELP:
+ show_usage (stdout);
+ exit (EXIT_SUCCESS);
+
+ case OPTION_NOCPP:
+ break;
+
+ case OPTION_STATISTICS:
+ flag_print_statistics = 1;
+ break;
+
+ case OPTION_STRIP_LOCAL_ABSOLUTE:
+ flag_strip_local_absolute = 1;
+ break;
+
+ case OPTION_TRADITIONAL_FORMAT:
+ flag_traditional_format = 1;
+ break;
+
+ case OPTION_VERSION:
+ /* This output is intended to follow the GNU standards document. */
+ printf (_("GNU assembler %s\n"), VERSION);
+ printf (_("Copyright 1997 Free Software Foundation, Inc.\n"));
+ printf (_("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n"));
+ printf (_("This assembler was configured for a target of `%s'.\n"),
+ TARGET_ALIAS);
+ exit (EXIT_SUCCESS);
+
+ case OPTION_EMULATION:
+#ifdef USE_EMULATIONS
+ if (strcmp (optarg, this_emulation->name))
+ as_fatal (_("multiple emulation names specified"));
+#else
+ as_fatal (_("emulations not handled in this configuration"));
+#endif
+ break;
+
+ case OPTION_DUMPCONFIG:
+ fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS);
+ fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL);
+ fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU);
+#ifdef TARGET_OBJ_FORMAT
+ fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT);
+#endif
+#ifdef TARGET_FORMAT
+ fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT);
+#endif
+ exit (EXIT_SUCCESS);
+
+ case OPTION_DEFSYM:
+ {
+ char *s;
+ long i;
+ struct defsym_list *n;
+
+ for (s = optarg; *s != '\0' && *s != '='; s++)
+ ;
+ if (*s == '\0')
+ as_fatal (_("bad defsym; format is --defsym name=value"));
+ *s++ = '\0';
+ i = strtol (s, (char **) NULL, 0);
+ n = (struct defsym_list *) xmalloc (sizeof *n);
+ n->next = defsyms;
+ n->name = optarg;
+ n->value = i;
+ defsyms = n;
+ }
+ break;
+
+ case OPTION_INSTTBL:
+ case 't':
+ {
+ /* optarg is the name of the file containing the instruction
+ formats, opcodes, register names, etc. */
+ struct itbl_file_list *n;
+
+ if (optarg == NULL)
+ {
+ as_warn ( _("No file name following -t option\n") );
+ break;
+ }
+
+ n = (struct itbl_file_list *) xmalloc (sizeof *n);
+ n->next = itbl_files;
+ n->name = optarg;
+ itbl_files = n;
+
+ /* Parse the file and add the new instructions to our internal
+ table. If multiple instruction tables are specified, the
+ information from this table gets appended onto the existing
+ internal table. */
+ itbl_files->name = xstrdup (optarg);
+ if (itbl_parse (itbl_files->name) != 0)
+ {
+ fprintf (stderr, _("Failed to read instruction table %s\n"),
+ itbl_files->name);
+ exit (EXIT_SUCCESS);
+ }
+ }
+ break;
+
+ case OPTION_DEPFILE:
+ start_dependencies (optarg);
+ break;
+
+ case OPTION_GSTABS:
+ debug_type = DEBUG_STABS;
+ break;
+
+ case 'J':
+ flag_signed_overflow_ok = 1;
+ break;
+
+#ifndef WORKING_DOT_WORD
+ case 'K':
+ flag_warn_displacement = 1;
+ break;
+#endif
+
+ case 'L':
+ flag_keep_locals = 1;
+ break;
+
+ case OPTION_LISTING_LHS_WIDTH:
+ listing_lhs_width = atoi(optarg);
+ if (listing_lhs_width_second < listing_lhs_width)
+ listing_lhs_width_second = listing_lhs_width;
+ break;
+ case OPTION_LISTING_LHS_WIDTH2:
+ {
+ int tmp = atoi(optarg);
+ if (tmp > listing_lhs_width)
+ listing_lhs_width_second = tmp;
+ }
+ break;
+ case OPTION_LISTING_RHS_WIDTH:
+ listing_rhs_width = atoi(optarg);
+ break;
+ case OPTION_LISTING_CONT_LINES:
+ listing_lhs_cont_lines = atoi(optarg);
+ break;
+
+ case 'M':
+ flag_mri = 1;
+#ifdef TC_M68K
+ flag_m68k_mri = 1;
+#endif
+ break;
+
+ case 'R':
+ flag_readonly_data_in_text = 1;
+ break;
+
+ case 'W':
+ flag_no_warnings = 1;
+ break;
+
+ case 'Z':
+ flag_always_generate_output = 1;
+ break;
+
+ case 'a':
+ if (optarg)
+ {
+ while (*optarg)
+ {
+ switch (*optarg)
+ {
+ case 'c':
+ listing |= LISTING_NOCOND;
+ break;
+ case 'd':
+ listing |= LISTING_NODEBUG;
+ break;
+ case 'h':
+ listing |= LISTING_HLL;
+ break;
+ case 'l':
+ listing |= LISTING_LISTING;
+ break;
+ case 'm':
+ listing |= LISTING_MACEXP;
+ break;
+ case 'n':
+ listing |= LISTING_NOFORM;
+ break;
+ case 's':
+ listing |= LISTING_SYMBOLS;
+ break;
+ case '=':
+ listing_filename = xstrdup (optarg + 1);
+ optarg += strlen (listing_filename);
+ break;
+ default:
+ as_fatal (_("invalid listing option `%c'"), *optarg);
+ break;
+ }
+ optarg++;
+ }
+ }
+ if (!listing)
+ listing = LISTING_DEFAULT;
+ break;
+
+ case 'D':
+ /* DEBUG is implemented: it debugs different */
+ /* things from other people's assemblers. */
+ flag_debug = 1;
+ break;
+
+ case 'f':
+ flag_no_comments = 1;
+ break;
+
+ case 'I':
+ { /* Include file directory */
+ char *temp = xstrdup (optarg);
+ add_include_dir (temp);
+ break;
+ }
+
+ case 'o':
+ out_file_name = xstrdup (optarg);
+ break;
+
+ case 'w':
+ break;
+
+ case 'X':
+ /* -X means treat warnings as errors */
+ break;
+ }
+ }
+
+ free (shortopts);
+ free (longopts);
+
+ *pargc = new_argc;
+ *pargv = new_argv;
+}
+
+static long start_time;
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int macro_alternate;
+ int macro_strip_at;
+ int keep_it;
+
+ start_time = get_run_time ();
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ if (debug_memory)
+ {
+#ifdef BFD_ASSEMBLER
+ extern long _bfd_chunksize;
+ _bfd_chunksize = 64;
+#endif
+ chunksize = 64;
+ }
+
+#ifdef HOST_SPECIAL_INIT
+ HOST_SPECIAL_INIT (argc, argv);
+#endif
+
+ myname = argv[0];
+ xmalloc_set_program_name (myname);
+
+ START_PROGRESS (myname, 0);
+
+#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
+#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
+#endif
+
+ out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
+
+ hex_init ();
+#ifdef BFD_ASSEMBLER
+ bfd_init ();
+ bfd_set_error_program_name (myname);
+#endif
+
+#ifdef USE_EMULATIONS
+ select_emulation_mode (argc, argv);
+#endif
+
+ PROGRESS (1);
+ symbol_begin ();
+ frag_init ();
+ subsegs_begin ();
+ parse_args (&argc, &argv);
+ read_begin ();
+ input_scrub_begin ();
+ expr_begin ();
+
+ if (flag_print_statistics)
+ xatexit (dump_statistics);
+
+ macro_alternate = 0;
+ macro_strip_at = 0;
+#ifdef TC_I960
+ macro_strip_at = flag_mri;
+#endif
+#ifdef TC_A29K
+ /* For compatibility with the AMD 29K family macro assembler
+ specification. */
+ macro_alternate = 1;
+ macro_strip_at = 1;
+#endif
+
+ macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr);
+
+ PROGRESS (1);
+
+#ifdef BFD_ASSEMBLER
+ output_file_create (out_file_name);
+ assert (stdoutput != 0);
+#endif
+
+#ifdef tc_init_after_args
+ tc_init_after_args ();
+#endif
+
+ itbl_init ();
+
+ /* Now that we have fully initialized, and have created the output
+ file, define any symbols requested by --defsym command line
+ arguments. */
+ while (defsyms != NULL)
+ {
+ symbolS *sym;
+ struct defsym_list *next;
+
+ sym = symbol_new (defsyms->name, absolute_section, defsyms->value,
+ &zero_address_frag);
+ symbol_table_insert (sym);
+ next = defsyms->next;
+ free (defsyms);
+ defsyms = next;
+ }
+
+ PROGRESS (1);
+
+ perform_an_assembly_pass (argc, argv); /* Assemble it. */
+
+ cond_finish_check (-1);
+
+#ifdef md_end
+ md_end ();
+#endif
+
+ if (seen_at_least_1_file ()
+ && (flag_always_generate_output || had_errors () == 0))
+ keep_it = 1;
+ else
+ keep_it = 0;
+
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+ /* This used to be done at the start of write_object_file in
+ write.c, but that caused problems when doing listings when
+ keep_it was zero. This could probably be moved above md_end, but
+ I didn't want to risk the change. */
+ subsegs_finish ();
+#endif
+
+ if (keep_it)
+ write_object_file ();
+
+#ifndef NO_LISTING
+ listing_print (listing_filename);
+#endif
+
+#ifndef OBJ_VMS /* does its own file handling */
+#ifndef BFD_ASSEMBLER
+ if (keep_it)
+#endif
+ output_file_close (out_file_name);
+#endif
+
+ if (had_errors () > 0 && ! flag_always_generate_output)
+ keep_it = 0;
+
+ if (!keep_it)
+ unlink (out_file_name);
+
+ input_scrub_end ();
+
+ END_PROGRESS (myname);
+
+ /* Use xexit instead of return, because under VMS environments they
+ may not place the same interpretation on the value given. */
+ if (had_errors () > 0)
+ xexit (EXIT_FAILURE);
+
+ /* Only generate dependency file if assembler was successful. */
+ print_dependencies ();
+
+ xexit (EXIT_SUCCESS);
+}
+
+static void
+dump_statistics ()
+{
+#ifdef HAVE_SBRK
+ char *lim = (char *) sbrk (0);
+#endif
+ long run_time = get_run_time () - start_time;
+
+ fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"),
+ myname, run_time / 1000000, run_time % 1000000);
+#ifdef HAVE_SBRK
+ fprintf (stderr, _("%s: data size %ld\n"),
+ myname, (long) (lim - (char *) &environ));
+#endif
+
+ subsegs_print_statistics (stderr);
+ write_print_statistics (stderr);
+ symbol_print_statistics (stderr);
+ read_print_statistics (stderr);
+
+#ifdef tc_print_statistics
+ tc_print_statistics (stderr);
+#endif
+#ifdef obj_print_statistics
+ obj_print_statistics (stderr);
+#endif
+}
+
+
+/* perform_an_assembly_pass()
+ *
+ * Here to attempt 1 pass over each input file.
+ * We scan argv[*] looking for filenames or exactly "" which is
+ * shorthand for stdin. Any argv that is NULL is not a file-name.
+ * We set need_pass_2 TRUE if, after this, we still have unresolved
+ * expressions of the form (unknown value)+-(unknown value).
+ *
+ * Note the un*x semantics: there is only 1 logical input file, but it
+ * may be a catenation of many 'physical' input files.
+ */
+static void
+perform_an_assembly_pass (argc, argv)
+ int argc;
+ char **argv;
+{
+ int saw_a_file = 0;
+#ifdef BFD_ASSEMBLER
+ flagword applicable;
+#endif
+
+ need_pass_2 = 0;
+
+#ifndef BFD_ASSEMBLER
+#ifdef MANY_SEGMENTS
+ {
+ unsigned int i;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ segment_info[i].fix_root = 0;
+ }
+ /* Create the three fixed ones */
+ {
+ segT seg;
+
+#ifdef TE_APOLLO
+ seg = subseg_new (".wtext", 0);
+#else
+ seg = subseg_new (".text", 0);
+#endif
+ assert (seg == SEG_E0);
+ seg = subseg_new (".data", 0);
+ assert (seg == SEG_E1);
+ seg = subseg_new (".bss", 0);
+ assert (seg == SEG_E2);
+#ifdef TE_APOLLO
+ create_target_segments ();
+#endif
+ }
+
+#else /* not MANY_SEGMENTS */
+ text_fix_root = NULL;
+ data_fix_root = NULL;
+ bss_fix_root = NULL;
+#endif /* not MANY_SEGMENTS */
+#else /* BFD_ASSEMBLER */
+ /* Create the standard sections, and those the assembler uses
+ internally. */
+ text_section = subseg_new (TEXT_SECTION_NAME, 0);
+ data_section = subseg_new (DATA_SECTION_NAME, 0);
+ bss_section = subseg_new (BSS_SECTION_NAME, 0);
+ /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
+ to have relocs, otherwise we don't find out in time. */
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, text_section,
+ applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_CODE | SEC_READONLY));
+ /* @@ FIXME -- SEC_CODE seems to mean code only, rather than code possibly.*/
+ bfd_set_section_flags (stdoutput, data_section,
+ applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC));
+ bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
+ seg_info (bss_section)->bss = 1;
+ subseg_new (BFD_ABS_SECTION_NAME, 0);
+ subseg_new (BFD_UND_SECTION_NAME, 0);
+ reg_section = subseg_new ("*GAS `reg' section*", 0);
+ expr_section = subseg_new ("*GAS `expr' section*", 0);
+
+#endif /* BFD_ASSEMBLER */
+
+ subseg_set (text_section, 0);
+
+ /* This may add symbol table entries, which requires having an open BFD,
+ and sections already created, in BFD_ASSEMBLER mode. */
+ md_begin ();
+
+#ifdef obj_begin
+ obj_begin ();
+#endif
+
+ argv++; /* skip argv[0] */
+ argc--; /* skip argv[0] */
+ while (argc--)
+ {
+ if (*argv)
+ { /* Is it a file-name argument? */
+ PROGRESS (1);
+ saw_a_file++;
+ /* argv->"" if stdin desired, else->filename */
+ read_a_source_file (*argv);
+ }
+ argv++; /* completed that argv */
+ }
+ if (!saw_a_file)
+ read_a_source_file ("");
+} /* perform_an_assembly_pass() */
+
+/* The interface between the macro code and gas expression handling. */
+
+static int
+macro_expr (emsg, idx, in, val)
+ const char *emsg;
+ int idx;
+ sb *in;
+ int *val;
+{
+ char *hold;
+ expressionS ex;
+
+ sb_terminate (in);
+
+ hold = input_line_pointer;
+ input_line_pointer = in->ptr + idx;
+ expression (&ex);
+ idx = input_line_pointer - in->ptr;
+ input_line_pointer = hold;
+
+ if (ex.X_op != O_constant)
+ as_bad ("%s", emsg);
+
+ *val = (int) ex.X_add_number;
+
+ return idx;
+}
+
+/* end of as.c */
diff --git a/gas/as.h b/gas/as.h
new file mode 100644
index 00000000000..a72dfad28dc
--- /dev/null
+++ b/gas/as.h
@@ -0,0 +1,645 @@
+/* as.h - global header file
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef GAS
+#define GAS 1
+/*
+ * I think this stuff is largely out of date. xoxorich.
+ *
+ * CAPITALISED names are #defined.
+ * "lowercaseH" is #defined if "lowercase.h" has been #include-d.
+ * "lowercaseT" is a typedef of "lowercase" objects.
+ * "lowercaseP" is type "pointer to object of type 'lowercase'".
+ * "lowercaseS" is typedef struct ... lowercaseS.
+ *
+ * #define DEBUG to enable all the "know" assertion tests.
+ * #define SUSPECT when debugging hash code.
+ * #define COMMON as "extern" for all modules except one, where you #define
+ * COMMON as "".
+ * If TEST is #defined, then we are testing a module: #define COMMON as "".
+ */
+
+#include "config.h"
+
+/* This is the code recommended in the autoconf documentation, almost
+ verbatim. If it doesn't work for you, let me know, and notify
+ djm@gnu.ai.mit.edu as well. */
+/* Added #undef for DJ Delorie. The right fix is to ensure that as.h
+ is included first, before even any system header files, in all files
+ that use it. KR 1994.11.03 */
+/* Added void* version for STDC case. This is to be compatible with
+ the declaration in bison.simple, used for m68k operand parsing.
+ --KR 1995.08.08 */
+/* Force void* decl for hpux. This is what Bison uses. --KR 1995.08.16 */
+
+/* AIX requires this to be the first thing in the file. */
+#ifdef __GNUC__
+# ifndef alloca
+# ifdef __STDC__
+extern void *alloca ();
+# else
+extern char *alloca ();
+# endif
+# endif
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+extern char *alloca ();
+# else
+extern void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* _AIX */
+# endif /* HAVE_ALLOCA_H */
+#endif
+
+/* Now, tend to the rest of the configuration. */
+
+/* System include files first... */
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+/* for size_t, pid_t */
+#include <sys/types.h>
+#endif
+
+#include <getopt.h>
+/* The first getopt value for machine-independent long options.
+ 150 isn't special; it's just an arbitrary non-ASCII char value. */
+#define OPTION_STD_BASE 150
+/* The first getopt value for machine-dependent long options.
+ 170 gives the standard options room to grow. */
+#define OPTION_MD_BASE 170
+
+#ifdef DEBUG
+#undef NDEBUG
+#endif
+#if !defined (__GNUC__) || __GNUC_MINOR__ <= 5
+#define __PRETTY_FUNCTION__ ((char*)0)
+#endif
+#if 0
+
+/* Handle lossage with assert.h. */
+#ifndef BROKEN_ASSERT
+#include <assert.h>
+#else /* BROKEN_ASSERT */
+#ifndef NDEBUG
+#define assert(p) ((p) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0))
+#else
+#define assert(p) ((p), 0)
+#endif
+#endif /* BROKEN_ASSERT */
+
+#else
+
+#define assert(P) ((P) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0))
+#undef abort
+#define abort() as_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#endif
+
+
+/* Now GNU header files... */
+#include <ansidecl.h>
+#ifdef BFD_ASSEMBLER
+#include <bfd.h>
+#endif
+#include <libiberty.h>
+
+/* Define the standard progress macros. */
+#include <progress.h>
+
+/* This doesn't get taken care of anywhere. */
+#ifndef __MWERKS__ /* Metrowerks C chokes on the "defined (inline)" */
+#if !defined (__GNUC__) && !defined (inline)
+#define inline
+#endif
+#endif /* !__MWERKS__ */
+
+/* Other stuff from config.h. */
+#ifdef NEED_DECLARATION_STRSTR
+extern char *strstr ();
+#endif
+#ifdef NEED_DECLARATION_MALLOC
+extern PTR malloc ();
+extern PTR realloc ();
+#endif
+#ifdef NEED_DECLARATION_FREE
+extern void free ();
+#endif
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#ifdef NEED_DECLARATION_ENVIRON
+extern char **environ;
+#endif
+
+/* This is needed for VMS. */
+#if ! defined (HAVE_UNLINK) && defined (HAVE_REMOVE)
+#define unlink remove
+#endif
+
+/* Hack to make "gcc -Wall" not complain about obstack macros. */
+#if !defined (memcpy) && !defined (bcopy)
+#define bcopy(src,dest,size) memcpy(dest,src,size)
+#endif
+
+/* Make Saber happier on obstack.h. */
+#ifdef SABER
+#undef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((int)(P))
+#undef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((char *)(P))
+#endif
+
+#ifndef __LINE__
+#define __LINE__ "unknown"
+#endif /* __LINE__ */
+
+#ifndef __FILE__
+#define __FILE__ "unknown"
+#endif /* __FILE__ */
+
+#ifndef FOPEN_WB
+#ifdef GO32
+#include "fopen-bin.h"
+#else
+#include "fopen-same.h"
+#endif
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free xfree
+
+#define xfree free
+
+#include "asintl.h"
+
+#define BAD_CASE(val) \
+{ \
+ as_fatal(_("Case value %ld unexpected at line %d of file \"%s\"\n"), \
+ (long) val, __LINE__, __FILE__); \
+ }
+
+#include "flonum.h"
+
+/* These are assembler-wide concepts */
+
+#ifdef BFD_ASSEMBLER
+extern bfd *stdoutput;
+typedef bfd_vma addressT;
+typedef bfd_signed_vma offsetT;
+#else
+typedef unsigned long addressT;
+typedef long offsetT;
+#endif
+
+/* Type of symbol value, etc. For use in prototypes. */
+typedef addressT valueT;
+
+#ifndef COMMON
+#ifdef TEST
+#define COMMON /* declare our COMMONs storage here. */
+#else
+#define COMMON extern /* our commons live elswhere */
+#endif
+#endif
+/* COMMON now defined */
+
+#ifdef DEBUG
+#ifndef know
+#define know(p) assert(p) /* Verify our assumptions! */
+#endif /* not yet defined */
+#else
+#define know(p) /* know() checks are no-op.ed */
+#endif
+
+/* input_scrub.c */
+
+/*
+ * Supplies sanitised buffers to read.c.
+ * Also understands printing line-number part of error messages.
+ */
+
+
+/* subsegs.c Sub-segments. Also, segment(=expression type)s.*/
+
+#ifndef BFD_ASSEMBLER
+
+#ifdef MANY_SEGMENTS
+#include "bfd.h"
+#define N_SEGMENTS 40
+#define SEG_NORMAL(x) ((x) >= SEG_E0 && (x) <= SEG_E39)
+#define SEG_LIST SEG_E0,SEG_E1,SEG_E2,SEG_E3,SEG_E4,SEG_E5,SEG_E6,SEG_E7,SEG_E8,SEG_E9,\
+ SEG_E10,SEG_E11,SEG_E12,SEG_E13,SEG_E14,SEG_E15,SEG_E16,SEG_E17,SEG_E18,SEG_E19,\
+ SEG_E20,SEG_E21,SEG_E22,SEG_E23,SEG_E24,SEG_E25,SEG_E26,SEG_E27,SEG_E28,SEG_E29,\
+ SEG_E30,SEG_E31,SEG_E32,SEG_E33,SEG_E34,SEG_E35,SEG_E36,SEG_E37,SEG_E38,SEG_E39
+#define SEG_TEXT SEG_E0
+#define SEG_DATA SEG_E1
+#define SEG_BSS SEG_E2
+#define SEG_LAST SEG_E39
+#else
+#define N_SEGMENTS 3
+#define SEG_NORMAL(x) ((x) == SEG_TEXT || (x) == SEG_DATA || (x) == SEG_BSS)
+#define SEG_LIST SEG_TEXT,SEG_DATA,SEG_BSS
+#endif
+
+typedef enum _segT
+ {
+ SEG_ABSOLUTE = 0,
+ SEG_LIST,
+ SEG_UNKNOWN,
+ SEG_GOOF, /* Only happens if AS has a logic error. */
+ /* Invented so we don't crash printing */
+ /* error message involving weird segment. */
+ SEG_EXPR, /* Intermediate expression values. */
+ SEG_DEBUG, /* Debug segment */
+ SEG_NTV, /* Transfert vector preload segment */
+ SEG_PTV, /* Transfert vector postload segment */
+ SEG_REGISTER /* Mythical: a register-valued expression */
+ } segT;
+
+#define SEG_MAXIMUM_ORDINAL (SEG_REGISTER)
+#else
+typedef asection *segT;
+#define SEG_NORMAL(SEG) ((SEG) != absolute_section \
+ && (SEG) != undefined_section \
+ && (SEG) != reg_section \
+ && (SEG) != expr_section)
+#endif
+typedef int subsegT;
+
+/* What subseg we are accreting now? */
+COMMON subsegT now_subseg;
+
+/* Segment our instructions emit to. */
+COMMON segT now_seg;
+
+#ifdef BFD_ASSEMBLER
+#define segment_name(SEG) bfd_get_section_name (stdoutput, SEG)
+#else
+extern char const *const seg_name[];
+#define segment_name(SEG) seg_name[(int) (SEG)]
+#endif
+
+#ifndef BFD_ASSEMBLER
+extern int section_alignment[];
+#endif
+
+#ifdef BFD_ASSEMBLER
+extern segT reg_section, expr_section;
+/* Shouldn't these be eliminated someday? */
+extern segT text_section, data_section, bss_section;
+#define absolute_section bfd_abs_section_ptr
+#define undefined_section bfd_und_section_ptr
+#else
+#define reg_section SEG_REGISTER
+#define expr_section SEG_EXPR
+#define text_section SEG_TEXT
+#define data_section SEG_DATA
+#define bss_section SEG_BSS
+#define absolute_section SEG_ABSOLUTE
+#define undefined_section SEG_UNKNOWN
+#endif
+
+/* relax() */
+
+enum _relax_state
+ {
+ /* Variable chars to be repeated fr_offset times.
+ Fr_symbol unused. Used with fr_offset == 0 for a
+ constant length frag. */
+ rs_fill = 1,
+
+ /* Align. The fr_offset field holds the power of 2 to which to
+ align. The fr_var field holds the number of characters in the
+ fill pattern. The fr_subtype field holds the maximum number of
+ bytes to skip when aligning, or 0 if there is no maximum. */
+ rs_align,
+
+ /* Align code. The fr_offset field holds the power of 2 to which
+ to align. This type is only generated by machine specific
+ code, which is normally responsible for handling the fill
+ pattern. The fr_subtype field holds the maximum number of
+ bytes to skip when aligning, or 0 if there is no maximum. */
+ rs_align_code,
+
+ /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill
+ character. */
+ rs_org,
+
+#ifndef WORKING_DOT_WORD
+ /* JF: gunpoint */
+ rs_broken_word,
+#endif
+
+ /* machine-specific relaxable (or similarly alterable) instruction */
+ rs_machine_dependent,
+
+ /* .space directive with expression operand that needs to be computed
+ later. Similar to rs_org, but different.
+ fr_symbol: operand
+ 1 variable char: fill character */
+ rs_space,
+
+ /* A DWARF leb128 value; only ELF uses this. The subtype is 0 for
+ unsigned, 1 for signed. */
+ rs_leb128,
+
+ /* Exception frame information which we may be able to optimize. */
+ rs_cfa
+ };
+
+typedef enum _relax_state relax_stateT;
+
+/* This type is used in prototypes, so it can't be a type that will be
+ widened for argument passing. */
+typedef unsigned int relax_substateT;
+
+/* Enough bits for address, but still an integer type.
+ Could be a problem, cross-assembling for 64-bit machines. */
+typedef addressT relax_addressT;
+
+/* main program "as.c" (command arguments etc) */
+
+COMMON unsigned char flag_no_comments; /* -f */
+COMMON unsigned char flag_debug; /* -D */
+COMMON unsigned char flag_signed_overflow_ok; /* -J */
+#ifndef WORKING_DOT_WORD
+COMMON unsigned char flag_warn_displacement; /* -K */
+#endif
+
+/* True if local symbols should be retained. */
+COMMON int flag_keep_locals; /* -L */
+
+/* True if we are assembling in MRI mode. */
+COMMON int flag_mri;
+
+/* True if we are assembling in m68k MRI mode. */
+COMMON int flag_m68k_mri;
+
+/* Should the data section be made read-only and appended to the text
+ section? */
+COMMON unsigned char flag_readonly_data_in_text; /* -R */
+
+/* True if warnings should be inhibited. */
+COMMON int flag_no_warnings; /* -W */
+
+/* True if we should attempt to generate output even if non-fatal errors
+ are detected. */
+COMMON unsigned char flag_always_generate_output; /* -Z */
+
+/* This is true if the assembler should output time and space usage. */
+COMMON unsigned char flag_print_statistics;
+
+/* True if local absolute symbols are to be stripped. */
+COMMON int flag_strip_local_absolute;
+
+/* True if we should generate a traditional format object file. */
+COMMON int flag_traditional_format;
+
+/* name of emitted object file */
+COMMON char *out_file_name;
+
+/* name of file defining extensions to the basic instruction set */
+COMMON char *insttbl_file_name;
+
+/* TRUE if we need a second pass. */
+COMMON int need_pass_2;
+
+/* TRUE if we should do no relaxing, and
+ leave lots of padding. */
+COMMON int linkrelax;
+
+/* TRUE if we should produce a listing. */
+extern int listing;
+
+/* Type of debugging information we should generate. We currently
+ only support stabs and ECOFF. */
+
+enum debug_info_type
+ {
+ DEBUG_UNSPECIFIED,
+ DEBUG_NONE,
+ DEBUG_STABS,
+ DEBUG_ECOFF,
+ DEBUG_DWARF,
+ DEBUG_DWARF2
+ };
+
+extern enum debug_info_type debug_type;
+
+/* Maximum level of macro nesting. */
+extern int max_macro_nest;
+
+/* Obstack chunk size. Keep large for efficient space use, make small to
+ increase malloc calls for monitoring memory allocation. */
+extern int chunksize;
+
+struct _pseudo_type
+ {
+ /* assembler mnemonic, lower case, no '.' */
+ const char *poc_name;
+ /* Do the work */
+ void (*poc_handler) PARAMS ((int));
+ /* Value to pass to handler */
+ int poc_val;
+ };
+
+typedef struct _pseudo_type pseudo_typeS;
+
+/* Prefer varargs for non-ANSI compiler, since some will barf if the
+ ellipsis definition is used with a no-arguments declaration. */
+#if defined (HAVE_VARARGS_H) && !defined (__STDC__)
+#undef HAVE_STDARG_H
+#endif
+
+#if defined (HAVE_STDARG_H)
+#define USE_STDARG
+#endif
+#if !defined (USE_STDARG) && defined (HAVE_VARARGS_H)
+#define USE_VARARGS
+#endif
+
+#ifdef USE_STDARG
+#if (__GNUC__ >= 2) && !defined(VMS)
+/* for use with -Wformat */
+
+#if __GNUC_MINOR__ < 6
+/* Support for double underscores in attribute names was added in gcc
+ 2.6, so avoid them if we are using an earlier version. */
+#define __printf__ printf
+#define __format__ format
+#endif
+
+#define PRINTF_LIKE(FCN) \
+ void FCN (const char *format, ...) \
+ __attribute__ ((__format__ (__printf__, 1, 2)))
+#define PRINTF_WHERE_LIKE(FCN) \
+ void FCN (char *file, unsigned int line, const char *format, ...) \
+ __attribute__ ((__format__ (__printf__, 3, 4)))
+
+#else /* __GNUC__ < 2 || defined(VMS) */
+
+#define PRINTF_LIKE(FCN) void FCN PARAMS ((const char *format, ...))
+#define PRINTF_WHERE_LIKE(FCN) void FCN PARAMS ((char *file, \
+ unsigned int line, \
+ const char *format, ...))
+
+#endif /* __GNUC__ < 2 || defined(VMS) */
+
+#else /* ! USE_STDARG */
+
+#define PRINTF_LIKE(FCN) void FCN ()
+#define PRINTF_WHERE_LIKE(FCN) void FCN ()
+
+#endif /* ! USE_STDARG */
+
+PRINTF_LIKE (as_bad);
+PRINTF_LIKE (as_fatal);
+PRINTF_LIKE (as_tsktsk);
+PRINTF_LIKE (as_warn);
+PRINTF_WHERE_LIKE (as_bad_where);
+PRINTF_WHERE_LIKE (as_warn_where);
+
+void as_assert PARAMS ((const char *, int, const char *));
+void as_abort PARAMS ((const char *, int, const char *));
+
+void fprint_value PARAMS ((FILE *file, addressT value));
+void sprint_value PARAMS ((char *buf, addressT value));
+
+int had_errors PARAMS ((void));
+int had_warnings PARAMS ((void));
+
+void print_version_id PARAMS ((void));
+char *app_push PARAMS ((void));
+char *atof_ieee PARAMS ((char *str, int what_kind, LITTLENUM_TYPE * words));
+char *input_scrub_include_file PARAMS ((char *filename, char *position));
+char *input_scrub_new_file PARAMS ((char *filename));
+char *input_scrub_next_buffer PARAMS ((char **bufp));
+int do_scrub_chars PARAMS ((int (*get) (char **), char *to, int tolen));
+int gen_to_words PARAMS ((LITTLENUM_TYPE * words, int precision,
+ long exponent_bits));
+int had_err PARAMS ((void));
+int ignore_input PARAMS ((void));
+void cond_finish_check PARAMS ((int));
+void cond_exit_macro PARAMS ((int));
+int seen_at_least_1_file PARAMS ((void));
+void app_pop PARAMS ((char *arg));
+void as_howmuch PARAMS ((FILE * stream));
+void as_perror PARAMS ((const char *gripe, const char *filename));
+void as_where PARAMS ((char **namep, unsigned int *linep));
+void bump_line_counters PARAMS ((void));
+void do_scrub_begin PARAMS ((int));
+void input_scrub_begin PARAMS ((void));
+void input_scrub_close PARAMS ((void));
+void input_scrub_end PARAMS ((void));
+int new_logical_line PARAMS ((char *fname, int line_number));
+void subsegs_begin PARAMS ((void));
+void subseg_change PARAMS ((segT seg, int subseg));
+segT subseg_new PARAMS ((const char *name, subsegT subseg));
+segT subseg_force_new PARAMS ((const char *name, subsegT subseg));
+void subseg_set PARAMS ((segT seg, subsegT subseg));
+#ifdef BFD_ASSEMBLER
+segT subseg_get PARAMS ((const char *, int));
+#endif
+
+void start_dependencies PARAMS ((char *));
+void register_dependency PARAMS ((char *));
+void print_dependencies PARAMS ((void));
+
+struct expressionS;
+struct fix;
+struct symbol;
+struct relax_type;
+typedef struct frag fragS;
+
+#ifdef BFD_ASSEMBLER
+/* literal.c */
+valueT add_to_literal_pool PARAMS ((struct symbol *, valueT, segT, int));
+#endif
+
+int check_eh_frame PARAMS ((struct expressionS *, unsigned int *));
+int eh_frame_estimate_size_before_relax PARAMS ((fragS *));
+int eh_frame_relax_frag PARAMS ((fragS *));
+void eh_frame_convert_frag PARAMS ((fragS *));
+
+#include "expr.h" /* Before targ-*.h */
+
+/* this one starts the chain of target dependant headers */
+#include "targ-env.h"
+
+#include "struc-symbol.h"
+#include "write.h"
+#include "frags.h"
+#include "hash.h"
+#include "read.h"
+#include "symbols.h"
+
+#include "tc.h"
+#include "obj.h"
+
+#ifdef USE_EMULATIONS
+#include "emul.h"
+#endif
+#include "listing.h"
+
+#ifndef LOCAL_LABELS_DOLLAR
+#define LOCAL_LABELS_DOLLAR 0
+#endif
+
+#ifndef LOCAL_LABELS_FB
+#define LOCAL_LABELS_FB 0
+#endif
+
+#ifndef TEXT_SECTION_NAME
+#define TEXT_SECTION_NAME ".text"
+#define DATA_SECTION_NAME ".data"
+#define BSS_SECTION_NAME ".bss"
+#endif
+
+#endif /* GAS */
+
+/* end of as.h */
diff --git a/gas/asintl.h b/gas/asintl.h
new file mode 100644
index 00000000000..b733c85f0f3
--- /dev/null
+++ b/gas/asintl.h
@@ -0,0 +1,44 @@
+/* asintl.h - gas-specific header for gettext code.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+ Written by Tom Tromey <tromey@cygnus.com>
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
diff --git a/gas/atof-generic.c b/gas/atof-generic.c
new file mode 100644
index 00000000000..316f665a454
--- /dev/null
+++ b/gas/atof-generic.c
@@ -0,0 +1,636 @@
+/* atof_generic.c - turn a string of digits into a Flonum
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "as.h"
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (1)
+#endif
+
+#ifdef TRACE
+static void flonum_print PARAMS ((const FLONUM_TYPE *));
+#endif
+
+#define ASSUME_DECIMAL_MARK_IS_DOT
+
+/***********************************************************************\
+ * *
+ * Given a string of decimal digits , with optional decimal *
+ * mark and optional decimal exponent (place value) of the *
+ * lowest_order decimal digit: produce a floating point *
+ * number. The number is 'generic' floating point: our *
+ * caller will encode it for a specific machine architecture. *
+ * *
+ * Assumptions *
+ * uses base (radix) 2 *
+ * this machine uses 2's complement binary integers *
+ * target flonums use " " " " *
+ * target flonums exponents fit in a long *
+ * *
+ \***********************************************************************/
+
+/*
+
+ Syntax:
+
+ <flonum> ::= <optional-sign> <decimal-number> <optional-exponent>
+ <optional-sign> ::= '+' | '-' | {empty}
+ <decimal-number> ::= <integer>
+ | <integer> <radix-character>
+ | <integer> <radix-character> <integer>
+ | <radix-character> <integer>
+
+ <optional-exponent> ::= {empty}
+ | <exponent-character> <optional-sign> <integer>
+
+ <integer> ::= <digit> | <digit> <integer>
+ <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+ <exponent-character> ::= {one character from "string_of_decimal_exponent_marks"}
+ <radix-character> ::= {one character from "string_of_decimal_marks"}
+
+ */
+
+int
+atof_generic (address_of_string_pointer,
+ string_of_decimal_marks,
+ string_of_decimal_exponent_marks,
+ address_of_generic_floating_point_number)
+ /* return pointer to just AFTER number we read. */
+ char **address_of_string_pointer;
+ /* At most one per number. */
+ const char *string_of_decimal_marks;
+ const char *string_of_decimal_exponent_marks;
+ FLONUM_TYPE *address_of_generic_floating_point_number;
+{
+ int return_value; /* 0 means OK. */
+ char *first_digit;
+ unsigned int number_of_digits_before_decimal;
+ unsigned int number_of_digits_after_decimal;
+ long decimal_exponent;
+ unsigned int number_of_digits_available;
+ char digits_sign_char;
+
+ /*
+ * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent.
+ * It would be simpler to modify the string, but we don't; just to be nice
+ * to caller.
+ * We need to know how many digits we have, so we can allocate space for
+ * the digits' value.
+ */
+
+ char *p;
+ char c;
+ int seen_significant_digit;
+
+#ifdef ASSUME_DECIMAL_MARK_IS_DOT
+ assert (string_of_decimal_marks[0] == '.'
+ && string_of_decimal_marks[1] == 0);
+#define IS_DECIMAL_MARK(c) ((c) == '.')
+#else
+#define IS_DECIMAL_MARK(c) (0 != strchr (string_of_decimal_marks, (c)))
+#endif
+
+ first_digit = *address_of_string_pointer;
+ c = *first_digit;
+
+ if (c == '-' || c == '+')
+ {
+ digits_sign_char = c;
+ first_digit++;
+ }
+ else
+ digits_sign_char = '+';
+
+ switch (first_digit[0])
+ {
+ case 'n':
+ case 'N':
+ if (!strncasecmp ("nan", first_digit, 3))
+ {
+ address_of_generic_floating_point_number->sign = 0;
+ address_of_generic_floating_point_number->exponent = 0;
+ address_of_generic_floating_point_number->leader =
+ address_of_generic_floating_point_number->low;
+ *address_of_string_pointer = first_digit + 3;
+ return 0;
+ }
+ break;
+
+ case 'i':
+ case 'I':
+ if (!strncasecmp ("inf", first_digit, 3))
+ {
+ address_of_generic_floating_point_number->sign =
+ digits_sign_char == '+' ? 'P' : 'N';
+ address_of_generic_floating_point_number->exponent = 0;
+ address_of_generic_floating_point_number->leader =
+ address_of_generic_floating_point_number->low;
+
+ first_digit += 3;
+ if (!strncasecmp ("inity", first_digit, 5))
+ first_digit += 5;
+
+ *address_of_string_pointer = first_digit;
+
+ return 0;
+ }
+ break;
+ }
+
+ number_of_digits_before_decimal = 0;
+ number_of_digits_after_decimal = 0;
+ decimal_exponent = 0;
+ seen_significant_digit = 0;
+ for (p = first_digit;
+ (((c = *p) != '\0')
+ && (!c || !IS_DECIMAL_MARK (c))
+ && (!c || !strchr (string_of_decimal_exponent_marks, c)));
+ p++)
+ {
+ if (isdigit ((unsigned char) c))
+ {
+ if (seen_significant_digit || c > '0')
+ {
+ ++number_of_digits_before_decimal;
+ seen_significant_digit = 1;
+ }
+ else
+ {
+ first_digit++;
+ }
+ }
+ else
+ {
+ break; /* p -> char after pre-decimal digits. */
+ }
+ } /* For each digit before decimal mark. */
+
+#ifndef OLD_FLOAT_READS
+ /* Ignore trailing 0's after the decimal point. The original code here
+ * (ifdef'd out) does not do this, and numbers like
+ * 4.29496729600000000000e+09 (2**31)
+ * come out inexact for some reason related to length of the digit
+ * string.
+ */
+ if (c && IS_DECIMAL_MARK (c))
+ {
+ unsigned int zeros = 0; /* Length of current string of zeros */
+
+ for (p++; (c = *p) && isdigit ((unsigned char) c); p++)
+ {
+ if (c == '0')
+ {
+ zeros++;
+ }
+ else
+ {
+ number_of_digits_after_decimal += 1 + zeros;
+ zeros = 0;
+ }
+ }
+ }
+#else
+ if (c && IS_DECIMAL_MARK (c))
+ {
+ for (p++;
+ (((c = *p) != '\0')
+ && (!c || !strchr (string_of_decimal_exponent_marks, c)));
+ p++)
+ {
+ if (isdigit (c))
+ {
+ /* This may be retracted below. */
+ number_of_digits_after_decimal++;
+
+ if ( /* seen_significant_digit || */ c > '0')
+ {
+ seen_significant_digit = TRUE;
+ }
+ }
+ else
+ {
+ if (!seen_significant_digit)
+ {
+ number_of_digits_after_decimal = 0;
+ }
+ break;
+ }
+ } /* For each digit after decimal mark. */
+ }
+
+ while (number_of_digits_after_decimal
+ && first_digit[number_of_digits_before_decimal
+ + number_of_digits_after_decimal] == '0')
+ --number_of_digits_after_decimal;
+#endif
+
+ if (flag_m68k_mri)
+ {
+ while (c == '_')
+ c = *++p;
+ }
+ if (c && strchr (string_of_decimal_exponent_marks, c))
+ {
+ char digits_exponent_sign_char;
+
+ c = *++p;
+ if (flag_m68k_mri)
+ {
+ while (c == '_')
+ c = *++p;
+ }
+ if (c && strchr ("+-", c))
+ {
+ digits_exponent_sign_char = c;
+ c = *++p;
+ }
+ else
+ {
+ digits_exponent_sign_char = '+';
+ }
+
+ for (; (c); c = *++p)
+ {
+ if (isdigit ((unsigned char) c))
+ {
+ decimal_exponent = decimal_exponent * 10 + c - '0';
+ /*
+ * BUG! If we overflow here, we lose!
+ */
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (digits_exponent_sign_char == '-')
+ {
+ decimal_exponent = -decimal_exponent;
+ }
+ }
+
+ *address_of_string_pointer = p;
+
+
+
+ number_of_digits_available =
+ number_of_digits_before_decimal + number_of_digits_after_decimal;
+ return_value = 0;
+ if (number_of_digits_available == 0)
+ {
+ address_of_generic_floating_point_number->exponent = 0; /* Not strictly necessary */
+ address_of_generic_floating_point_number->leader
+ = -1 + address_of_generic_floating_point_number->low;
+ address_of_generic_floating_point_number->sign = digits_sign_char;
+ /* We have just concocted (+/-)0.0E0 */
+
+ }
+ else
+ {
+ int count; /* Number of useful digits left to scan. */
+
+ LITTLENUM_TYPE *digits_binary_low;
+ unsigned int precision;
+ unsigned int maximum_useful_digits;
+ unsigned int number_of_digits_to_use;
+ unsigned int more_than_enough_bits_for_digits;
+ unsigned int more_than_enough_littlenums_for_digits;
+ unsigned int size_of_digits_in_littlenums;
+ unsigned int size_of_digits_in_chars;
+ FLONUM_TYPE power_of_10_flonum;
+ FLONUM_TYPE digits_flonum;
+
+ precision = (address_of_generic_floating_point_number->high
+ - address_of_generic_floating_point_number->low
+ + 1); /* Number of destination littlenums. */
+
+ /* Includes guard bits (two littlenums worth) */
+#if 0 /* The integer version below is very close, and it doesn't
+ require floating point support (which is currently buggy on
+ the Alpha). */
+ maximum_useful_digits = (((double) (precision - 2))
+ * ((double) (LITTLENUM_NUMBER_OF_BITS))
+ / (LOG_TO_BASE_2_OF_10))
+ + 2; /* 2 :: guard digits. */
+#else
+ maximum_useful_digits = (((precision - 2))
+ * ( (LITTLENUM_NUMBER_OF_BITS))
+ * 1000000 / 3321928)
+ + 2; /* 2 :: guard digits. */
+#endif
+
+ if (number_of_digits_available > maximum_useful_digits)
+ {
+ number_of_digits_to_use = maximum_useful_digits;
+ }
+ else
+ {
+ number_of_digits_to_use = number_of_digits_available;
+ }
+
+ /* Cast these to SIGNED LONG first, otherwise, on systems with
+ LONG wider than INT (such as Alpha OSF/1), unsignedness may
+ cause unexpected results. */
+ decimal_exponent += ((long) number_of_digits_before_decimal
+ - (long) number_of_digits_to_use);
+
+#if 0
+ more_than_enough_bits_for_digits
+ = ((((double) number_of_digits_to_use) * LOG_TO_BASE_2_OF_10) + 1);
+#else
+ more_than_enough_bits_for_digits
+ = (number_of_digits_to_use * 3321928 / 1000000 + 1);
+#endif
+
+ more_than_enough_littlenums_for_digits
+ = (more_than_enough_bits_for_digits
+ / LITTLENUM_NUMBER_OF_BITS)
+ + 2;
+
+ /* Compute (digits) part. In "12.34E56" this is the "1234" part.
+ Arithmetic is exact here. If no digits are supplied then this
+ part is a 0 valued binary integer. Allocate room to build up
+ the binary number as littlenums. We want this memory to
+ disappear when we leave this function. Assume no alignment
+ problems => (room for n objects) == n * (room for 1
+ object). */
+
+ size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits;
+ size_of_digits_in_chars = size_of_digits_in_littlenums
+ * sizeof (LITTLENUM_TYPE);
+
+ digits_binary_low = (LITTLENUM_TYPE *)
+ alloca (size_of_digits_in_chars);
+
+ memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars);
+
+ /* Digits_binary_low[] is allocated and zeroed. */
+
+ /*
+ * Parse the decimal digits as if * digits_low was in the units position.
+ * Emit a binary number into digits_binary_low[].
+ *
+ * Use a large-precision version of:
+ * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit
+ */
+
+ for (p = first_digit, count = number_of_digits_to_use; count; p++, --count)
+ {
+ c = *p;
+ if (isdigit ((unsigned char) c))
+ {
+ /*
+ * Multiply by 10. Assume can never overflow.
+ * Add this digit to digits_binary_low[].
+ */
+
+ long carry;
+ LITTLENUM_TYPE *littlenum_pointer;
+ LITTLENUM_TYPE *littlenum_limit;
+
+ littlenum_limit = digits_binary_low
+ + more_than_enough_littlenums_for_digits
+ - 1;
+
+ carry = c - '0'; /* char -> binary */
+
+ for (littlenum_pointer = digits_binary_low;
+ littlenum_pointer <= littlenum_limit;
+ littlenum_pointer++)
+ {
+ long work;
+
+ work = carry + 10 * (long) (*littlenum_pointer);
+ *littlenum_pointer = work & LITTLENUM_MASK;
+ carry = work >> LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ if (carry != 0)
+ {
+ /*
+ * We have a GROSS internal error.
+ * This should never happen.
+ */
+ as_fatal (_("failed sanity check."));
+ }
+ }
+ else
+ {
+ ++count; /* '.' doesn't alter digits used count. */
+ }
+ }
+
+
+ /*
+ * Digits_binary_low[] properly encodes the value of the digits.
+ * Forget about any high-order littlenums that are 0.
+ */
+ while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0
+ && size_of_digits_in_littlenums >= 2)
+ size_of_digits_in_littlenums--;
+
+ digits_flonum.low = digits_binary_low;
+ digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1;
+ digits_flonum.leader = digits_flonum.high;
+ digits_flonum.exponent = 0;
+ /*
+ * The value of digits_flonum . sign should not be important.
+ * We have already decided the output's sign.
+ * We trust that the sign won't influence the other parts of the number!
+ * So we give it a value for these reasons:
+ * (1) courtesy to humans reading/debugging
+ * these numbers so they don't get excited about strange values
+ * (2) in future there may be more meaning attached to sign,
+ * and what was
+ * harmless noise may become disruptive, ill-conditioned (or worse)
+ * input.
+ */
+ digits_flonum.sign = '+';
+
+ {
+ /*
+ * Compute the mantssa (& exponent) of the power of 10.
+ * If sucessful, then multiply the power of 10 by the digits
+ * giving return_binary_mantissa and return_binary_exponent.
+ */
+
+ LITTLENUM_TYPE *power_binary_low;
+ int decimal_exponent_is_negative;
+ /* This refers to the "-56" in "12.34E-56". */
+ /* FALSE: decimal_exponent is positive (or 0) */
+ /* TRUE: decimal_exponent is negative */
+ FLONUM_TYPE temporary_flonum;
+ LITTLENUM_TYPE *temporary_binary_low;
+ unsigned int size_of_power_in_littlenums;
+ unsigned int size_of_power_in_chars;
+
+ size_of_power_in_littlenums = precision;
+ /* Precision has a built-in fudge factor so we get a few guard bits. */
+
+ decimal_exponent_is_negative = decimal_exponent < 0;
+ if (decimal_exponent_is_negative)
+ {
+ decimal_exponent = -decimal_exponent;
+ }
+
+ /* From now on: the decimal exponent is > 0. Its sign is separate. */
+
+ size_of_power_in_chars = size_of_power_in_littlenums
+ * sizeof (LITTLENUM_TYPE) + 2;
+
+ power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
+ temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars);
+ memset ((char *) power_binary_low, '\0', size_of_power_in_chars);
+ *power_binary_low = 1;
+ power_of_10_flonum.exponent = 0;
+ power_of_10_flonum.low = power_binary_low;
+ power_of_10_flonum.leader = power_binary_low;
+ power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1;
+ power_of_10_flonum.sign = '+';
+ temporary_flonum.low = temporary_binary_low;
+ temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1;
+ /*
+ * (power) == 1.
+ * Space for temporary_flonum allocated.
+ */
+
+ /*
+ * ...
+ *
+ * WHILE more bits
+ * DO find next bit (with place value)
+ * multiply into power mantissa
+ * OD
+ */
+ {
+ int place_number_limit;
+ /* Any 10^(2^n) whose "n" exceeds this */
+ /* value will fall off the end of */
+ /* flonum_XXXX_powers_of_ten[]. */
+ int place_number;
+ const FLONUM_TYPE *multiplicand; /* -> 10^(2^n) */
+
+ place_number_limit = table_size_of_flonum_powers_of_ten;
+
+ multiplicand = (decimal_exponent_is_negative
+ ? flonum_negative_powers_of_ten
+ : flonum_positive_powers_of_ten);
+
+ for (place_number = 1;/* Place value of this bit of exponent. */
+ decimal_exponent;/* Quit when no more 1 bits in exponent. */
+ decimal_exponent >>= 1, place_number++)
+ {
+ if (decimal_exponent & 1)
+ {
+ if (place_number > place_number_limit)
+ {
+ /* The decimal exponent has a magnitude so great
+ that our tables can't help us fragment it.
+ Although this routine is in error because it
+ can't imagine a number that big, signal an
+ error as if it is the user's fault for
+ presenting such a big number. */
+ return_value = ERROR_EXPONENT_OVERFLOW;
+ /* quit out of loop gracefully */
+ decimal_exponent = 0;
+ }
+ else
+ {
+#ifdef TRACE
+ printf ("before multiply, place_number = %d., power_of_10_flonum:\n",
+ place_number);
+
+ flonum_print (&power_of_10_flonum);
+ (void) putchar ('\n');
+#endif
+#ifdef TRACE
+ printf ("multiplier:\n");
+ flonum_print (multiplicand + place_number);
+ (void) putchar ('\n');
+#endif
+ flonum_multip (multiplicand + place_number,
+ &power_of_10_flonum, &temporary_flonum);
+#ifdef TRACE
+ printf ("after multiply:\n");
+ flonum_print (&temporary_flonum);
+ (void) putchar ('\n');
+#endif
+ flonum_copy (&temporary_flonum, &power_of_10_flonum);
+#ifdef TRACE
+ printf ("after copy:\n");
+ flonum_print (&power_of_10_flonum);
+ (void) putchar ('\n');
+#endif
+ } /* If this bit of decimal_exponent was computable.*/
+ } /* If this bit of decimal_exponent was set. */
+ } /* For each bit of binary representation of exponent */
+#ifdef TRACE
+ printf ("after computing power_of_10_flonum:\n");
+ flonum_print (&power_of_10_flonum);
+ (void) putchar ('\n');
+#endif
+ }
+
+ }
+
+ /*
+ * power_of_10_flonum is power of ten in binary (mantissa) , (exponent).
+ * It may be the number 1, in which case we don't NEED to multiply.
+ *
+ * Multiply (decimal digits) by power_of_10_flonum.
+ */
+
+ flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number);
+ /* Assert sign of the number we made is '+'. */
+ address_of_generic_floating_point_number->sign = digits_sign_char;
+
+ }
+ return return_value;
+}
+
+#ifdef TRACE
+static void
+flonum_print (f)
+ const FLONUM_TYPE *f;
+{
+ LITTLENUM_TYPE *lp;
+ char littlenum_format[10];
+ sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2);
+#define print_littlenum(LP) (printf (littlenum_format, LP))
+ printf ("flonum @%p %c e%ld", f, f->sign, f->exponent);
+ if (f->low < f->high)
+ for (lp = f->high; lp >= f->low; lp--)
+ print_littlenum (*lp);
+ else
+ for (lp = f->low; lp <= f->high; lp++)
+ print_littlenum (*lp);
+ printf ("\n");
+ fflush (stdout);
+}
+#endif
+
+/* end of atof_generic.c */
diff --git a/gas/bignum-copy.c b/gas/bignum-copy.c
new file mode 100644
index 00000000000..2bffcbfea4c
--- /dev/null
+++ b/gas/bignum-copy.c
@@ -0,0 +1,80 @@
+/* bignum_copy.c - copy a bignum
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+
+/*
+ * bignum_copy ()
+ *
+ * Copy a bignum from in to out.
+ * If the output is shorter than the input, copy lower-order littlenums.
+ * Return 0 or the number of significant littlenums dropped.
+ * Assumes littlenum arrays are densely packed: no unused chars between
+ * the littlenums. Uses memcpy() to move littlenums, and wants to
+ * know length (in chars) of the input bignum.
+ */
+
+/* void */
+int
+bignum_copy (in, in_length, out, out_length)
+ register LITTLENUM_TYPE *in;
+ register int in_length; /* in sizeof(littlenum)s */
+ register LITTLENUM_TYPE *out;
+ register int out_length; /* in sizeof(littlenum)s */
+{
+ int significant_littlenums_dropped;
+
+ if (out_length < in_length)
+ {
+ LITTLENUM_TYPE *p; /* -> most significant (non-zero) input
+ littlenum. */
+
+ memcpy ((void *) out, (void *) in,
+ (unsigned int) out_length << LITTLENUM_SHIFT);
+ for (p = in + in_length - 1; p >= in; --p)
+ {
+ if (*p)
+ break;
+ }
+ significant_littlenums_dropped = p - in - in_length + 1;
+
+ if (significant_littlenums_dropped < 0)
+ {
+ significant_littlenums_dropped = 0;
+ }
+ }
+ else
+ {
+ memcpy ((char *) out, (char *) in,
+ (unsigned int) in_length << LITTLENUM_SHIFT);
+
+ if (out_length > in_length)
+ {
+ memset ((char *) (out + in_length),
+ '\0',
+ (unsigned int) (out_length - in_length) << LITTLENUM_SHIFT);
+ }
+
+ significant_littlenums_dropped = 0;
+ }
+
+ return (significant_littlenums_dropped);
+} /* bignum_copy() */
+
+/* end of bignum-copy.c */
diff --git a/gas/bignum.h b/gas/bignum.h
new file mode 100644
index 00000000000..e3b2f167998
--- /dev/null
+++ b/gas/bignum.h
@@ -0,0 +1,52 @@
+/* bignum.h-arbitrary precision integers
+ Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/***********************************************************************\
+ * *
+ * Arbitrary-precision integer arithmetic. *
+ * For speed, we work in groups of bits, even though this *
+ * complicates algorithms. *
+ * Each group of bits is called a 'littlenum'. *
+ * A bunch of littlenums representing a (possibly large) *
+ * integer is called a 'bignum'. *
+ * Bignums are >= 0. *
+ * *
+ \***********************************************************************/
+
+#define LITTLENUM_NUMBER_OF_BITS (16)
+#define LITTLENUM_RADIX (1 << LITTLENUM_NUMBER_OF_BITS)
+#define LITTLENUM_MASK (0xFFFF)
+#define LITTLENUM_SHIFT (1)
+#define CHARS_PER_LITTLENUM (1 << LITTLENUM_SHIFT)
+#ifndef BITS_PER_CHAR
+#define BITS_PER_CHAR (8)
+#endif
+
+typedef unsigned short LITTLENUM_TYPE;
+
+/* JF truncated this to get around a problem with GCC */
+#define LOG_TO_BASE_2_OF_10 (3.3219280948873623478703194294893901758651)
+/* WARNING: I haven't checked that the trailing digits are correct! */
+
+/* lengths are in sizeof(littlenum)s */
+
+int bignum_copy PARAMS ((LITTLENUM_TYPE * in, int in_length,
+ LITTLENUM_TYPE * out, int out_length));
+
+/* end of bignum.h */
diff --git a/gas/bit_fix.h b/gas/bit_fix.h
new file mode 100644
index 00000000000..6a729a700c6
--- /dev/null
+++ b/gas/bit_fix.h
@@ -0,0 +1,51 @@
+/* write.h
+
+ Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* The bit_fix was implemented to support machines that need variables
+ to be inserted in bitfields other than 1, 2 and 4 bytes.
+ Furthermore it gives us a possibillity to mask in bits in the symbol
+ when it's fixed in the objectcode and check the symbols limits.
+
+ The or-mask is used to set the huffman bits in displacements for the
+ ns32k port.
+ The acbi, addqi, movqi, cmpqi instruction requires an assembler that
+ can handle bitfields. Ie handle an expression, evaluate it and insert
+ the result in an some bitfield. ( ex: 5 bits in a short field of a opcode)
+ */
+
+#ifndef __bit_fix_h__
+#define __bit_fix_h__
+
+struct bit_fix
+ {
+ int fx_bit_size; /* Length of bitfield */
+ int fx_bit_offset; /* Bit offset to bitfield */
+ long fx_bit_base; /* Where do we apply the bitfix.
+ If this is zero, default is assumed. */
+ long fx_bit_base_adj; /* Adjustment of base */
+ long fx_bit_max; /* Signextended max for bitfield */
+ long fx_bit_min; /* Signextended min for bitfield */
+ long fx_bit_add; /* Or mask, used for huffman prefix */
+ };
+typedef struct bit_fix bit_fixS;
+
+#endif /* __bit_fix_h__ */
+
+/* end of bit_fix.h */
diff --git a/gas/cgen.c b/gas/cgen.c
new file mode 100644
index 00000000000..3d2330e05fb
--- /dev/null
+++ b/gas/cgen.c
@@ -0,0 +1,663 @@
+/* GAS interface for targets using CGEN: Cpu tools GENerator.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <setjmp.h>
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "cgen-desc.h"
+#include "as.h"
+#include "subsegs.h"
+#include "cgen.h"
+
+/* Opcode table descriptor, must be set by md_begin. */
+
+CGEN_CPU_DESC gas_cgen_cpu_desc;
+
+/* Callback to insert a register into the symbol table.
+ A target may choose to let GAS parse the registers.
+ ??? Not currently used. */
+
+void
+cgen_asm_record_register (name, number)
+ char * name;
+ int number;
+{
+ /* Use symbol_create here instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+ symbol_table_insert (symbol_create (name, reg_section,
+ number, & zero_address_frag));
+}
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''.
+
+ This is used by cpu's with simple operands. It keeps knowledge of what
+ an `expressionS' is and what a `fixup' is out of CGEN which for the time
+ being is preferable.
+
+ OPINDEX is the index in the operand table.
+ OPINFO is something the caller chooses to help in reloc determination. */
+
+struct fixup
+{
+ int opindex;
+ int opinfo;
+ expressionS exp;
+};
+
+static struct fixup fixups [GAS_CGEN_MAX_FIXUPS];
+static int num_fixups;
+
+/* Prepare to parse an instruction.
+ ??? May wish to make this static and delete calls in md_assemble. */
+
+void
+gas_cgen_init_parse ()
+{
+ num_fixups = 0;
+}
+
+/* Queue a fixup. */
+
+static void
+queue_fixup (opindex, opinfo, expP)
+ int opindex;
+ expressionS * expP;
+{
+ /* We need to generate a fixup for this expression. */
+ if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[num_fixups].exp = * expP;
+ fixups[num_fixups].opindex = opindex;
+ fixups[num_fixups].opinfo = opinfo;
+ ++ num_fixups;
+}
+
+/* The following three functions allow a backup of the fixup chain to be made,
+ and to have this backup be swapped with the current chain. This allows
+ certain ports, eg the m32r, to swap two instructions and swap their fixups
+ at the same time. */
+/* ??? I think with cgen_asm_finish_insn (or something else) there is no
+ more need for this. */
+
+static struct fixup saved_fixups [GAS_CGEN_MAX_FIXUPS];
+static int saved_num_fixups;
+
+void
+gas_cgen_save_fixups ()
+{
+ saved_num_fixups = num_fixups;
+
+ memcpy (saved_fixups, fixups, sizeof (fixups[0]) * num_fixups);
+
+ num_fixups = 0;
+}
+
+void
+gas_cgen_restore_fixups ()
+{
+ num_fixups = saved_num_fixups;
+
+ memcpy (fixups, saved_fixups, sizeof (fixups[0]) * num_fixups);
+
+ saved_num_fixups = 0;
+}
+
+void
+gas_cgen_swap_fixups ()
+{
+ int tmp;
+ struct fixup tmp_fixup;
+
+ if (num_fixups == 0)
+ {
+ gas_cgen_restore_fixups ();
+ }
+ else if (saved_num_fixups == 0)
+ {
+ gas_cgen_save_fixups ();
+ }
+ else
+ {
+ tmp = saved_num_fixups;
+ saved_num_fixups = num_fixups;
+ num_fixups = tmp;
+
+ for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
+ {
+ tmp_fixup = saved_fixups [tmp];
+ saved_fixups [tmp] = fixups [tmp];
+ fixups [tmp] = tmp_fixup;
+ }
+ }
+}
+
+/* Default routine to record a fixup.
+ This is a cover function to fix_new.
+ It exists because we record INSN with the fixup.
+
+ FRAG and WHERE are their respective arguments to fix_new_exp.
+ LENGTH is in bits.
+ OPINFO is something the caller chooses to help in reloc determination.
+
+ At this point we do not use a bfd_reloc_code_real_type for
+ operands residing in the insn, but instead just use the
+ operand index. This lets us easily handle fixups for any
+ operand type. We pick a BFD reloc type in md_apply_fix. */
+
+fixS *
+gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offset)
+ fragS * frag;
+ int where;
+ const CGEN_INSN * insn;
+ int length;
+ const CGEN_OPERAND * operand;
+ int opinfo;
+ symbolS * symbol;
+ offsetT offset;
+{
+ fixS * fixP;
+
+ /* It may seem strange to use operand->attrs and not insn->attrs here,
+ but it is the operand that has a pc relative relocation. */
+
+ fixP = fix_new (frag, where, length / 8, symbol, offset,
+ CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
+ (bfd_reloc_code_real_type)
+ ((int) BFD_RELOC_UNUSED
+ + (int) operand->type));
+ fixP->fx_cgen.insn = insn;
+ fixP->fx_cgen.opinfo = opinfo;
+
+ return fixP;
+}
+
+/* Default routine to record a fixup given an expression.
+ This is a cover function to fix_new_exp.
+ It exists because we record INSN with the fixup.
+
+ FRAG and WHERE are their respective arguments to fix_new_exp.
+ LENGTH is in bits.
+ OPINFO is something the caller chooses to help in reloc determination.
+
+ At this point we do not use a bfd_reloc_code_real_type for
+ operands residing in the insn, but instead just use the
+ operand index. This lets us easily handle fixups for any
+ operand type. We pick a BFD reloc type in md_apply_fix. */
+
+fixS *
+gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
+ fragS * frag;
+ int where;
+ const CGEN_INSN * insn;
+ int length;
+ const CGEN_OPERAND * operand;
+ int opinfo;
+ expressionS * exp;
+{
+ fixS * fixP;
+
+ /* It may seem strange to use operand->attrs and not insn->attrs here,
+ but it is the operand that has a pc relative relocation. */
+
+ fixP = fix_new_exp (frag, where, length / 8, exp,
+ CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
+ (bfd_reloc_code_real_type)
+ ((int) BFD_RELOC_UNUSED
+ + (int) operand->type));
+ fixP->fx_cgen.insn = insn;
+ fixP->fx_cgen.opinfo = opinfo;
+
+ return fixP;
+}
+
+/* Used for communication between the next two procedures. */
+static jmp_buf expr_jmp_buf;
+
+/* Callback for cgen interface. Parse the expression at *STRP.
+ The result is an error message or NULL for success (in which case
+ *STRP is advanced past the parsed text).
+ WANT is an indication of what the caller is looking for.
+ If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
+ a table entry with the insn, reset the queued fixups counter.
+ An enum cgen_parse_operand_result is stored in RESULTP.
+ OPINDEX is the operand's table entry index.
+ OPINFO is something the caller chooses to help in reloc determination.
+ The resulting value is stored in VALUEP. */
+
+const char *
+gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
+ CGEN_CPU_DESC cd;
+ enum cgen_parse_operand_type want;
+ const char ** strP;
+ int opindex;
+ int opinfo;
+ enum cgen_parse_operand_result * resultP;
+ bfd_vma * valueP;
+{
+#ifdef __STDC__
+ /* These are volatile to survive the setjmp. */
+ char * volatile hold;
+ enum cgen_parse_operand_result * volatile resultP_1;
+#else
+ static char * hold;
+ static enum cgen_parse_operand_result * resultP_1;
+#endif
+ const char * errmsg = NULL;
+ expressionS exp;
+
+ if (want == CGEN_PARSE_OPERAND_INIT)
+ {
+ gas_cgen_init_parse ();
+ return NULL;
+ }
+
+ resultP_1 = resultP;
+ hold = input_line_pointer;
+ input_line_pointer = (char *) * strP;
+
+ /* We rely on md_operand to longjmp back to us.
+ This is done via gas_cgen_md_operand. */
+ if (setjmp (expr_jmp_buf) != 0)
+ {
+ input_line_pointer = (char *) hold;
+ * resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ return "illegal operand";
+ }
+
+ expression (& exp);
+
+ * strP = input_line_pointer;
+ input_line_pointer = hold;
+
+ /* FIXME: Need to check `want'. */
+
+ switch (exp.X_op)
+ {
+ case O_illegal :
+ errmsg = _("illegal operand");
+ * resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ break;
+ case O_absent :
+ errmsg = _("missing operand");
+ * resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ break;
+ case O_constant :
+ * valueP = exp.X_add_number;
+ * resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
+ break;
+ case O_register :
+ * valueP = exp.X_add_number;
+ * resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
+ break;
+ default :
+ queue_fixup (opindex, opinfo, & exp);
+ * valueP = 0;
+ * resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
+ break;
+ }
+
+ return errmsg;
+}
+
+/* md_operand handler to catch unrecognized expressions and halt the
+ parsing process so the next entry can be tried.
+
+ ??? This could be done differently by adding code to `expression'. */
+
+void
+gas_cgen_md_operand (expressionP)
+ expressionS * expressionP;
+{
+ longjmp (expr_jmp_buf, 1);
+}
+
+/* Finish assembling instruction INSN.
+ BUF contains what we've built up so far.
+ LENGTH is the size of the insn in bits.
+ RELAX_P is non-zero if relaxable insns should be emitted as such.
+ Otherwise they're emitted in non-relaxable forms.
+ The "result" is stored in RESULT if non-NULL. */
+
+void
+gas_cgen_finish_insn (insn, buf, length, relax_p, result)
+ const CGEN_INSN * insn;
+ CGEN_INSN_BYTES_PTR buf;
+ unsigned int length;
+ int relax_p;
+ finished_insnS * result;
+{
+ int i;
+ int relax_operand;
+ char * f;
+ unsigned int byte_len = length / 8;
+
+ /* ??? Target foo issues various warnings here, so one might want to provide
+ a hook here. However, our caller is defined in tc-foo.c so there
+ shouldn't be a need for a hook. */
+
+ /* Write out the instruction.
+ It is important to fetch enough space in one call to `frag_more'.
+ We use (f - frag_now->fr_literal) to compute where we are and we
+ don't want frag_now to change between calls.
+
+ Relaxable instructions: We need to ensure we allocate enough
+ space for the largest insn. */
+
+ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX))
+ abort (); /* These currently shouldn't get here. */
+
+ /* Is there a relaxable insn with the relaxable operand needing a fixup? */
+
+ relax_operand = -1;
+ if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
+ {
+ /* Scan the fixups for the operand affected by relaxing
+ (i.e. the branch address). */
+
+ for (i = 0; i < num_fixups; ++ i)
+ {
+ if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
+ CGEN_OPERAND_RELAX))
+ {
+ relax_operand = i;
+ break;
+ }
+ }
+ }
+
+ if (relax_operand != -1)
+ {
+ int max_len;
+ fragS * old_frag;
+
+#ifdef TC_CGEN_MAX_RELAX
+ max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
+#else
+ max_len = CGEN_MAX_INSN_SIZE;
+#endif
+ /* Ensure variable part and fixed part are in same fragment. */
+ /* FIXME: Having to do this seems like a hack. */
+ frag_grow (max_len);
+
+ /* Allocate space for the fixed part. */
+ f = frag_more (byte_len);
+
+ /* Create a relaxable fragment for this instruction. */
+ old_frag = frag_now;
+
+ frag_var (rs_machine_dependent,
+ max_len - byte_len /* max chars */,
+ 0 /* variable part already allocated */,
+ /* FIXME: When we machine generate the relax table,
+ machine generate a macro to compute subtype. */
+ 1 /* subtype */,
+ fixups[relax_operand].exp.X_add_symbol,
+ fixups[relax_operand].exp.X_add_number,
+ f);
+
+ /* Record the operand number with the fragment so md_convert_frag
+ can use gas_cgen_md_record_fixup to record the appropriate reloc. */
+ old_frag->fr_cgen.insn = insn;
+ old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
+ old_frag->fr_cgen.opinfo = fixups[relax_operand].opinfo;
+ if (result)
+ result->frag = old_frag;
+ }
+ else
+ {
+ f = frag_more (byte_len);
+ if (result)
+ result->frag = frag_now;
+ }
+
+ /* If we're recording insns as numbers (rather than a string of bytes),
+ target byte order handling is deferred until now. */
+#if CGEN_INT_INSN_P
+ cgen_put_insn_value (gas_cgen_cpu_desc, f, length, *buf);
+#else
+ memcpy (f, buf, byte_len);
+#endif
+
+ /* Create any fixups. */
+ for (i = 0; i < num_fixups; ++i)
+ {
+ fixS *fixP;
+ const CGEN_OPERAND *operand =
+ cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
+
+ /* Don't create fixups for these. That's done during relaxation.
+ We don't need to test for CGEN_INSN_RELAX as they can't get here
+ (see above). */
+ if (relax_p
+ && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
+ && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
+ continue;
+
+#ifndef md_cgen_record_fixup_exp
+#define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
+#endif
+
+ fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
+ insn, length, operand,
+ fixups[i].opinfo,
+ & fixups[i].exp);
+ if (result)
+ result->fixups[i] = fixP;
+ }
+
+ if (result)
+ {
+ result->num_fixups = num_fixups;
+ result->addr = f;
+ }
+}
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the fixup. */
+
+/* FIXME: This function handles some of the fixups and bfd_install_relocation
+ handles the rest. bfd_install_relocation (or some other bfd function)
+ should handle them all. */
+
+int
+gas_cgen_md_apply_fix3 (fixP, valueP, seg)
+ fixS * fixP;
+ valueT * valueP;
+ segT seg;
+{
+ char * where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ valueT value;
+ /* canonical name, since used a lot */
+ CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
+
+ /* FIXME FIXME FIXME: The value we are passed in *valuep includes
+ the symbol values. Since we are using BFD_ASSEMBLER, if we are
+ doing this relocation the code in write.c is going to call
+ bfd_install_relocation, which is also going to use the symbol
+ value. That means that if the reloc is fully resolved we want to
+ use *valuep since bfd_install_relocation is not being used.
+ However, if the reloc is not fully resolved we do not want to use
+ *valuep, and must use fx_offset instead. However, if the reloc
+ is PC relative, we do want to use *valuep since it includes the
+ result of md_pcrel_from. This is confusing. */
+
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ {
+ value = * valueP;
+ fixP->fx_done = 1;
+ }
+ else if (fixP->fx_pcrel)
+ value = * valueP;
+ else
+ {
+ value = fixP->fx_offset;
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixP->fx_subsy);
+ else
+ {
+ /* We don't actually support subtracting a symbol. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+ const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
+ const char *errmsg;
+ bfd_reloc_code_real_type reloc_type;
+ CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
+ const CGEN_INSN *insn = fixP->fx_cgen.insn;
+
+ /* If the reloc has been fully resolved finish the operand here. */
+ /* FIXME: This duplicates the capabilities of code in BFD. */
+ if (fixP->fx_done
+ /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
+ finish the job. Testing for pcrel is a temporary hack. */
+ || fixP->fx_pcrel)
+ {
+ CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
+ CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
+
+#if CGEN_INT_INSN_P
+ {
+ CGEN_INSN_INT insn_value =
+ cgen_get_insn_value (cd, where, CGEN_INSN_BITSIZE (insn));
+
+ /* ??? 0 is passed for `pc' */
+ errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
+ &insn_value, (bfd_vma) 0);
+ cgen_put_insn_value (cd, where, CGEN_INSN_BITSIZE (insn),
+ insn_value);
+ }
+#else
+ /* ??? 0 is passed for `pc' */
+ errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields, where,
+ (bfd_vma) 0);
+#endif
+ if (errmsg)
+ as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
+ }
+
+ if (fixP->fx_done)
+ return 1;
+
+ /* The operand isn't fully resolved. Determine a BFD reloc value
+ based on the operand information and leave it to
+ bfd_install_relocation. Note that this doesn't work when
+ partial_inplace == false. */
+
+ reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
+ if (reloc_type != BFD_RELOC_NONE)
+ {
+ fixP->fx_r_type = reloc_type;
+ }
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must be resolved"));
+ fixP->fx_done = 1;
+ return 1;
+ }
+ }
+ else if (fixP->fx_done)
+ {
+ /* We're finished with this fixup. Install it because
+ bfd_install_relocation won't be called to do it. */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ md_number_to_chars (where, value, 1);
+ break;
+ case BFD_RELOC_16:
+ md_number_to_chars (where, value, 2);
+ break;
+ case BFD_RELOC_32:
+ md_number_to_chars (where, value, 4);
+ break;
+ /* FIXME: later add support for 64 bits. */
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("internal error: can't install fix for reloc type %d (`%s')"),
+ fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
+ break;
+ }
+ }
+ else
+ {
+ /* bfd_install_relocation will be called to finish things up. */
+ }
+
+ /* Tuck `value' away for use by tc_gen_reloc.
+ See the comment describing fx_addnumber in write.h.
+ This field is misnamed (or misused :-). */
+ fixP->fx_addnumber = value;
+
+ return 1;
+}
+
+/* Translate internal representation of relocation info to BFD target format.
+
+ FIXME: To what extent can we get all relevant targets to use this? */
+
+arelent *
+gas_cgen_tc_gen_reloc (section, fixP)
+ asection * section;
+ fixS * fixP;
+{
+ arelent * reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("internal error: can't export reloc type %d (`%s')"),
+ fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
+ return NULL;
+ }
+
+ assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+
+ reloc->sym_ptr_ptr = & fixP->fx_addsy->bsym;
+
+ /* Use fx_offset for these cases */
+ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+ reloc->addend = fixP->fx_offset;
+ else
+ reloc->addend = fixP->fx_addnumber;
+
+ reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ return reloc;
+}
diff --git a/gas/cgen.h b/gas/cgen.h
new file mode 100644
index 00000000000..2bc1732247f
--- /dev/null
+++ b/gas/cgen.h
@@ -0,0 +1,94 @@
+/* GAS cgen support.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef GAS_CGEN_H
+#define GAS_CGEN_H
+
+/* Opcode table handle. */
+extern CGEN_CPU_DESC gas_cgen_cpu_desc;
+
+/* Maximum number of fixups in an insn.
+ If you need to change this, allow target to override and do so there. */
+#define GAS_CGEN_MAX_FIXUPS 3
+
+/* Struct defining result of gas_cgen_finish_insn. */
+typedef struct {
+ /* frag containing the insn */
+ fragS * frag;
+ /* Address of insn in frag. */
+ char * addr;
+ /* Number of fixups this insn has. */
+ int num_fixups;
+ /* Array of fixups. */
+ fixS * fixups[GAS_CGEN_MAX_FIXUPS];
+} finished_insnS;
+
+/* Callback for operand parsing.
+ The result is an error message or NULL for success.
+ The parsed value is stored in the bfd_vma *. */
+extern const char * gas_cgen_parse_operand
+ PARAMS ((CGEN_CPU_DESC, enum cgen_parse_operand_type,
+ const char **, int, int, enum cgen_parse_operand_result *,
+ bfd_vma *));
+
+/* Call this from md_assemble to initialize the assembler callback. */
+extern void gas_cgen_init_parse PARAMS ((void));
+
+extern void gas_cgen_save_fixups PARAMS ((void));
+extern void gas_cgen_restore_fixups PARAMS ((void));
+extern void gas_cgen_swap_fixups PARAMS ((void));
+
+/* Add a register to the assembler's hash table.
+ This makes lets GAS parse registers for us.
+ ??? This isn't currently used, but it could be in the future. */
+extern void cgen_asm_record_register PARAMS ((char *, int));
+
+/* After CGEN_SYM (assemble_insn) is done, this is called to
+ output the insn and record any fixups. */
+extern void gas_cgen_finish_insn PARAMS ((const CGEN_INSN *,
+ CGEN_INSN_BYTES_PTR, unsigned int,
+ int, finished_insnS *));
+
+/* Record a fixup. */
+extern fixS * gas_cgen_record_fixup PARAMS ((fragS *, int, const CGEN_INSN *,
+ int, const CGEN_OPERAND *, int,
+ symbolS *, offsetT));
+extern fixS * gas_cgen_record_fixup_exp PARAMS ((fragS *, int, const CGEN_INSN *,
+ int, const CGEN_OPERAND *, int,
+ expressionS *));
+
+/* md_apply_fix3 handler */
+extern int gas_cgen_md_apply_fix3 PARAMS ((fixS *, valueT *, segT));
+
+/* tc_gen_reloc handler */
+extern arelent *gas_cgen_tc_gen_reloc PARAMS ((asection *, fixS *));
+
+/* Target supplied routine to lookup a reloc. */
+extern bfd_reloc_code_real_type
+md_cgen_lookup_reloc PARAMS ((const CGEN_INSN *, const CGEN_OPERAND *,
+ fixS *));
+
+/* Optional target supplied routine to record a fixup for an expression. */
+extern fixS *
+md_cgen_record_fixup_exp PARAMS ((fragS *, int, const CGEN_INSN *, int,
+ const CGEN_OPERAND *, int,
+ expressionS *));
+
+#endif /* GAS_CGEN_H */
diff --git a/gas/cond.c b/gas/cond.c
new file mode 100644
index 00000000000..71a2a8e7d13
--- /dev/null
+++ b/gas/cond.c
@@ -0,0 +1,461 @@
+/* cond.c - conditional assembly pseudo-ops, and .include
+ Copyright (C) 1990, 91, 92, 93, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "macro.h"
+
+#include "obstack.h"
+
+/* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */
+struct obstack cond_obstack;
+
+struct file_line
+{
+ char *file;
+ unsigned int line;
+};
+
+/* We push one of these structures for each .if, and pop it at the
+ .endif. */
+
+struct conditional_frame
+{
+ /* The source file & line number of the "if". */
+ struct file_line if_file_line;
+ /* The source file & line of the "else". */
+ struct file_line else_file_line;
+ /* The previous conditional. */
+ struct conditional_frame *previous_cframe;
+ /* Have we seen an else yet? */
+ int else_seen;
+ /* Whether we are currently ignoring input. */
+ int ignoring;
+ /* Whether a conditional at a higher level is ignoring input. */
+ int dead_tree;
+ /* Macro nesting level at which this conditional was created. */
+ int macro_nest;
+};
+
+static void initialize_cframe PARAMS ((struct conditional_frame *cframe));
+static char *get_mri_string PARAMS ((int, int *));
+
+static struct conditional_frame *current_cframe = NULL;
+
+void
+s_ifdef (arg)
+ int arg;
+{
+ register char *name; /* points to name of symbol */
+ register struct symbol *symbolP; /* Points to symbol */
+ struct conditional_frame cframe;
+
+ SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
+ name = input_line_pointer;
+
+ if (!is_name_beginner (*name))
+ {
+ as_bad (_("invalid identifier for \".ifdef\""));
+ obstack_1grow (&cond_obstack, 0);
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ char c;
+
+ c = get_symbol_end ();
+ symbolP = symbol_find (name);
+ *input_line_pointer = c;
+
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe,
+ sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ demand_empty_rest_of_line ();
+ } /* if a valid identifyer name */
+} /* s_ifdef() */
+
+void
+s_if (arg)
+ int arg;
+{
+ expressionS operand;
+ struct conditional_frame cframe;
+ int t;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
+
+ if (current_cframe != NULL && current_cframe->ignoring)
+ {
+ operand.X_add_number = 0;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+ else
+ {
+ expression (&operand);
+ if (operand.X_op != O_constant)
+ as_bad (_("non-constant expression in \".if\" statement"));
+ }
+
+ switch ((operatorT) arg)
+ {
+ case O_eq: t = operand.X_add_number == 0; break;
+ case O_ne: t = operand.X_add_number != 0; break;
+ case O_lt: t = operand.X_add_number < 0; break;
+ case O_le: t = operand.X_add_number <= 0; break;
+ case O_ge: t = operand.X_add_number >= 0; break;
+ case O_gt: t = operand.X_add_number > 0; break;
+ default:
+ abort ();
+ return;
+ }
+
+ /* If the above error is signaled, this will dispatch
+ using an undefined result. No big deal. */
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || ! t;
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe, sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+} /* s_if() */
+
+/* Get a string for the MRI IFC or IFNC pseudo-ops. */
+
+static char *
+get_mri_string (terminator, len)
+ int terminator;
+ int *len;
+{
+ char *ret;
+ char *s;
+
+ SKIP_WHITESPACE ();
+ s = ret = input_line_pointer;
+ if (*input_line_pointer == '\'')
+ {
+ ++s;
+ ++input_line_pointer;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ *s++ = *input_line_pointer++;
+ if (s[-1] == '\'')
+ {
+ if (*input_line_pointer != '\'')
+ break;
+ ++input_line_pointer;
+ }
+ }
+ SKIP_WHITESPACE ();
+ }
+ else
+ {
+ while (*input_line_pointer != terminator
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ s = input_line_pointer;
+ while (s > ret && (s[-1] == ' ' || s[-1] == '\t'))
+ --s;
+ }
+
+ *len = s - ret;
+ return ret;
+}
+
+/* The MRI IFC and IFNC pseudo-ops. */
+
+void
+s_ifc (arg)
+ int arg;
+{
+ char *stop = NULL;
+ char stopc;
+ char *s1, *s2;
+ int len1, len2;
+ int res;
+ struct conditional_frame cframe;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ s1 = get_mri_string (',', &len1);
+
+ if (*input_line_pointer != ',')
+ as_bad (_("bad format for ifc or ifnc"));
+ else
+ ++input_line_pointer;
+
+ s2 = get_mri_string (';', &len2);
+
+ res = len1 == len2 && strncmp (s1, s2, len1) == 0;
+
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || ! (res ^ arg);
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe, sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_endif (arg)
+ int arg;
+{
+ struct conditional_frame *hold;
+
+ if (current_cframe == NULL)
+ {
+ as_bad (_("\".endif\" without \".if\""));
+ }
+ else
+ {
+ if (LISTING_SKIP_COND ()
+ && current_cframe->ignoring
+ && (current_cframe->previous_cframe == NULL
+ || ! current_cframe->previous_cframe->ignoring))
+ listing_list (1);
+
+ hold = current_cframe;
+ current_cframe = current_cframe->previous_cframe;
+ obstack_free (&cond_obstack, hold);
+ } /* if one pop too many */
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+} /* s_endif() */
+
+void
+s_else (arg)
+ int arg;
+{
+ if (current_cframe == NULL)
+ {
+ as_bad (_(".else without matching .if - ignored"));
+
+ }
+ else if (current_cframe->else_seen)
+ {
+ as_bad (_("duplicate \"else\" - ignored"));
+ as_bad_where (current_cframe->else_file_line.file,
+ current_cframe->else_file_line.line,
+ _("here is the previous \"else\""));
+ as_bad_where (current_cframe->if_file_line.file,
+ current_cframe->if_file_line.line,
+ _("here is the previous \"if\""));
+ }
+ else
+ {
+ as_where (&current_cframe->else_file_line.file,
+ &current_cframe->else_file_line.line);
+
+ if (!current_cframe->dead_tree)
+ {
+ current_cframe->ignoring = !current_cframe->ignoring;
+ if (LISTING_SKIP_COND ())
+ {
+ if (! current_cframe->ignoring)
+ listing_list (1);
+ else
+ listing_list (2);
+ }
+ } /* if not a dead tree */
+
+ current_cframe->else_seen = 1;
+ } /* if error else do it */
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+} /* s_else() */
+
+void
+s_ifeqs (arg)
+ int arg;
+{
+ char *s1, *s2;
+ int len1, len2;
+ int res;
+ struct conditional_frame cframe;
+
+ s1 = demand_copy_C_string (&len1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_(".ifeqs syntax error"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+
+ s2 = demand_copy_C_string (&len2);
+
+ res = len1 == len2 && strncmp (s1, s2, len1) == 0;
+
+ initialize_cframe (&cframe);
+ cframe.ignoring = cframe.dead_tree || ! (res ^ arg);
+ current_cframe = ((struct conditional_frame *)
+ obstack_copy (&cond_obstack, &cframe, sizeof (cframe)));
+
+ if (LISTING_SKIP_COND ()
+ && cframe.ignoring
+ && (cframe.previous_cframe == NULL
+ || ! cframe.previous_cframe->ignoring))
+ listing_list (2);
+
+ demand_empty_rest_of_line ();
+} /* s_ifeqs() */
+
+int
+ignore_input ()
+{
+ char *s;
+
+ s = input_line_pointer;
+
+ if (flag_m68k_mri
+#ifdef NO_PSEUDO_DOT
+ || 1
+#endif
+ )
+ {
+ if (s[-1] != '.')
+ --s;
+ }
+ else
+ {
+ if (s[-1] != '.')
+ return (current_cframe != NULL) && (current_cframe->ignoring);
+ }
+
+ /* We cannot ignore certain pseudo ops. */
+ if (((s[0] == 'i'
+ || s[0] == 'I')
+ && (!strncasecmp (s, "if", 2)
+ || !strncasecmp (s, "ifdef", 5)
+ || !strncasecmp (s, "ifndef", 6)))
+ || ((s[0] == 'e'
+ || s[0] == 'E')
+ && (!strncasecmp (s, "else", 4)
+ || !strncasecmp (s, "endif", 5)
+ || !strncasecmp (s, "endc", 4))))
+ return 0;
+
+ return (current_cframe != NULL) && (current_cframe->ignoring);
+} /* ignore_input() */
+
+static void
+initialize_cframe (cframe)
+ struct conditional_frame *cframe;
+{
+ memset (cframe, 0, sizeof (*cframe));
+ as_where (&cframe->if_file_line.file,
+ &cframe->if_file_line.line);
+ cframe->previous_cframe = current_cframe;
+ cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring;
+ cframe->macro_nest = macro_nest;
+}
+
+/* Give an error if a conditional is unterminated inside a macro or
+ the assembly as a whole. If NEST is non negative, we are being
+ called because of the end of a macro expansion. If NEST is
+ negative, we are being called at the of the input files. */
+
+void
+cond_finish_check (nest)
+ int nest;
+{
+ if (current_cframe != NULL && current_cframe->macro_nest >= nest)
+ {
+ if (nest >= 0)
+ as_bad (_("end of macro inside conditional"));
+ else
+ as_bad (_("end of file inside conditional"));
+ as_bad_where (current_cframe->if_file_line.file,
+ current_cframe->if_file_line.line,
+ _("here is the start of the unterminated conditional"));
+ if (current_cframe->else_seen)
+ as_bad_where (current_cframe->else_file_line.file,
+ current_cframe->else_file_line.line,
+ _("here is the \"else\" of the unterminated conditional"));
+ }
+}
+
+/* This function is called when we exit out of a macro. We assume
+ that any conditionals which began within the macro are correctly
+ nested, and just pop them off the stack. */
+
+void
+cond_exit_macro (nest)
+ int nest;
+{
+ while (current_cframe != NULL && current_cframe->macro_nest >= nest)
+ {
+ struct conditional_frame *hold;
+
+ hold = current_cframe;
+ current_cframe = current_cframe->previous_cframe;
+ obstack_free (&cond_obstack, hold);
+ }
+}
+
+/* end of cond.c */
diff --git a/gas/config-gas.com b/gas/config-gas.com
new file mode 100644
index 00000000000..cf5248af5da
--- /dev/null
+++ b/gas/config-gas.com
@@ -0,0 +1,186 @@
+$!config-gas.com
+$! This file sets things up to build gas on a VMS system to generate object
+$! files for a VMS system. We do not use the configure script, since we
+$! do not have /bin/sh to execute it.
+$!
+$!
+$ gas_host="vms"
+$ arch_indx = 1 + ((f$getsyi("CPU").ge.128).and.1) ! vax==1, alpha==2
+$ arch = f$element(arch_indx,"|","|VAX|Alpha|")
+$ if arch.eqs."VAX"
+$ then
+$ cpu_type="vax"
+$ obj_format="vms"
+$ atof="vax"
+$ else
+$ cpu_type="alpha"
+$ obj_format="evax"
+$ atof="ieee"
+$ endif
+$ emulation="generic"
+$!
+$ DELETE = "delete/noConfirm"
+$ ECHO = "write sys$output"
+$!
+$! Target specific information
+$ call make "targ-cpu.h" "[.config]tc-''cpu_type'.h"
+$ call make "targ-env.h" "[.config]te-''emulation'.h"
+$!
+$! Code to handle the object file format.
+$ call make "obj-format.h" "[.config]obj-''obj_format'.h"
+$!
+$! (not currently used for vax or alpha)
+$ call make "itbl-cpu.h" "[.config]itbl-''cpu_type'.h"
+$!
+$!
+$! Create the file version.opt, which helps identify the executable.
+$!
+$if f$trnlnm("IFILE$").nes."" then close/noLog ifile$
+$search CONFIGURE.IN "AM_INIT_AUTOMAKE"/Exact/Output=config-gas-tmp.tmp
+$open ifile$ config-gas-tmp.tmp
+$read ifile$ line
+$close ifile$
+$DELETE config-gas-tmp.tmp;*
+$! Discard "AM_INIT_AUTOMAKE(gas, " and ")" parts.
+$ijk=f$locate(",",line)+2
+$line=f$extract(ijk,f$length(line)-ijk,line)
+$ijk=f$locate(")",line)
+$line=f$extract(0,ijk,line)
+$!
+$ if f$search("version.opt").nes."" then DELETE version.opt;*
+$copy _NL: version.opt
+$open/Append ifile$ version.opt
+$write ifile$ "identification="+""""+line+""""
+$close ifile$
+$!
+$! Now write config.h.
+$!
+$ if f$search("config.h").nes."" then DELETE config.h;*
+$copy _NL: config.h
+$open/Append ifile$ config.h
+$write ifile$ "/* config.h. Generated by config-gas.com. */
+$write ifile$ "#ifndef VERSION"
+$write ifile$ "#define VERSION """,line,""""
+$write ifile$ "#endif"
+$write ifile$ "/*--*/"
+$if arch .eqs. "VAX"
+$then
+$append [.config]vms-conf.h ifile$:
+$else
+$ append [.config]vms-a-conf.h ifile$:
+$endif
+$close ifile$
+$ECHO "Created config.h."
+$!
+$! Check for, and possibly make, header file <unistd.h>.
+$!
+$ if f$search("tmp-chk-h.*").nes."" then DELETE tmp-chk-h.*;*
+$!can't use simple `#include HDR' with `gcc /Define="HDR=<foo.h>"'
+$!because the 2.6.[0-3] preprocessor handles it wrong (VMS-specific gcc bug)
+$ create tmp-chk-h.c
+int tmp_chk_h; /* guarantee non-empty output */
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_UNIXIO_H
+#include <unixio.h>
+#endif
+#ifdef HAVE_UNIXLIB_H
+#include <unixlib.h>
+#endif
+$ on warning then continue
+$ CHECK = "call tmp_chk_h"
+$ CHECK "HAVE_STDIO_H"
+$ if .not.$status
+$ then type sys$input:
+
+? could not compile <stdio.h>.
+
+ If you're compiling with DEC C or VAX C, create config.status as an
+ empty file and start gnu make again.
+
+ If you're compiling with GNU C, there is some setup problem and
+ gas configuration cannot proceed.
+
+$ DELETE tmp-chk-h.c;*
+$ exit %x002C
+$ endif
+$!
+$ CHECK "HAVE_UNISTD_H"
+$ if .not.$status
+$ then
+$ if f$trnlnm("HFILE$").nes."" then close/noLog hfile$
+$ CHECK "HAVE_UNIXIO_H"
+$ got_unixio = ($status .and. 1)
+$ CHECK "HAVE_UNIXLIB_H"
+$ got_unixlib = ($status .and. 1)
+$ create []unistd.h !with rudimentary contents
+/* <unistd.h> substitute for building gas */
+#ifndef UNISTD_H
+#define UNISTD_H
+
+$ open/Append hfile$ []unistd.h
+$ if got_unixio
+$ then write hfile$ "#include <unixio.h>"
+$ else append sys$input: hfile$:
+/* some of the routines normally prototyped in <unixio.h> */
+extern int creat(), open(), close(), read(), write();
+extern int access(), dup(), dup2(), fstat(), stat();
+extern long lseek();
+$ endif
+$ write hfile$ ""
+$ if got_unixlib
+$ then write hfile$ "#include <unixlib.h>"
+$ else append sys$input: hfile$:
+/* some of the routines normally prototyped in <unixlib.h> */
+extern char *sbrk(), *getcwd(), *cuserid();
+extern int brk(), chdir(), chmod(), chown(), mkdir();
+extern unsigned getuid(), umask();
+$ endif
+$ append sys$input: hfile$:
+
+#endif /*UNISTD_H*/
+$ close hfile$
+$ ECHO "Created ""[]unistd.h""."
+$ endif !gcc '#include <unistd.h>' failed
+$ DELETE tmp-chk-h.c;*
+$
+$tmp_chk_h: subroutine
+$ set noOn
+$ hname = f$edit("<" + (p1 - "HAVE_" - "_H") + ".h>","LOWERCASE")
+$ write sys$output "Checking for ''hname'."
+$ if f$search("tmp-chk-h.obj").nes."" then DELETE tmp-chk-h.obj;*
+$ define/noLog sys$error _NL: !can't use /User_Mode here due to gcc
+$ define/noLog sys$output _NL: ! driver's use of multiple image activation
+$ gcc /Include=([],[-.include]) /Define=("''p1'") tmp-chk-h.c
+$!can't just check $status; gcc 2.6.[0-3] preprocessor doesn't set it correctly
+$ ok = (($status.and.1).and.(f$search("tmp-chk-h.obj").nes."")) .or. %x10000000
+$ deassign sys$error !restore, more or less
+$ deassign sys$output
+$ if ok then DELETE tmp-chk-h.obj;*
+$ exit ok
+$ endsubroutine !tmp_chk_h
+$
+$!
+$! Done
+$!
+$ if f$search("config.status") .nes. "" then DELETE config.status;*
+$ open/write cfile []config.status
+$ write cfile "Links are now set up for use with a "+arch+" running VMS."
+$ close cfile
+$ type []config.status
+$exit
+$!
+$!
+$make: subroutine
+$ if f$search(p1).nes."" then DELETE 'p1';*
+$ create 'p1'
+$ if f$trnlnm("IFILE$").nes."" then close/noLog ifile$
+$ open/Append ifile$ 'p1'
+$ write ifile$ "#include ""''f$string(p2 - "[.config]")'"""
+$ close ifile$
+$ ECHO "Created ''p1' for ''p2'."
+$endsubroutine !make
diff --git a/gas/config.in b/gas/config.in
new file mode 100644
index 00000000000..81f2adac60b
--- /dev/null
+++ b/gas/config.in
@@ -0,0 +1,273 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the remove function. */
+#undef HAVE_REMOVE
+
+/* Define if you have the sbrk function. */
+#undef HAVE_SBRK
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the unlink function. */
+#undef HAVE_UNLINK
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Define if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if defaulting to ELF on SCO 5. */
+#undef SCO_ELF
+
+/* Use ELF stabs for MIPS, not ECOFF stabs */
+#undef MIPS_STABS_ELF
+
+/* Define if default target is PowerPC Solaris. */
+#undef TARGET_SOLARIS_COMMENT
+
+/* Define as 1 if big endian. */
+#undef TARGET_BYTES_BIG_ENDIAN
+
+/* Default architecture. */
+#undef DEFAULT_ARCH
+
+/* Using cgen code? */
+#undef USING_CGEN
+
+/* Using i386 COFF? */
+#undef I386COFF
+
+/* Using m68k COFF? */
+#undef M68KCOFF
+
+/* Using m88k COFF? */
+#undef M88KCOFF
+
+/* a.out support? */
+#undef OBJ_MAYBE_AOUT
+
+/* b.out support? */
+#undef OBJ_MAYBE_BOUT
+
+/* COFF support? */
+#undef OBJ_MAYBE_COFF
+
+/* ECOFF support? */
+#undef OBJ_MAYBE_ECOFF
+
+/* ELF support? */
+#undef OBJ_MAYBE_ELF
+
+/* generic support? */
+#undef OBJ_MAYBE_GENERIC
+
+/* HP300 support? */
+#undef OBJ_MAYBE_HP300
+
+/* IEEE support? */
+#undef OBJ_MAYBE_IEEE
+
+/* SOM support? */
+#undef OBJ_MAYBE_SOM
+
+/* VMS support? */
+#undef OBJ_MAYBE_VMS
+
+/* Use emulation support? */
+#undef USE_EMULATIONS
+
+/* Supported emulations. */
+#undef EMULATIONS
+
+/* Default emulation. */
+#undef DEFAULT_EMULATION
+
+/* old COFF support? */
+#undef MANY_SEGMENTS
+
+/* Use BFD interface? */
+#undef BFD_ASSEMBLER
+
+/* Target alias. */
+#undef TARGET_ALIAS
+
+/* Canonical target. */
+#undef TARGET_CANONICAL
+
+/* Target CPU. */
+#undef TARGET_CPU
+
+/* Target vendor. */
+#undef TARGET_VENDOR
+
+/* Target OS. */
+#undef TARGET_OS
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Compiling cross-assembler? */
+#undef CROSS_COMPILE
+
+/* assert broken? */
+#undef BROKEN_ASSERT
+
+/* Define if strstr is not declared in system header files. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Define if malloc is not declared in system header files. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Define if free is not declared in system header files. */
+#undef NEED_DECLARATION_FREE
+
+/* Define if sbrk is not declared in system header files. */
+#undef NEED_DECLARATION_SBRK
+
+/* Define if environ is not declared in system header files. */
+#undef NEED_DECLARATION_ENVIRON
+
+/* Define if errno is not declared in system header files. */
+#undef NEED_DECLARATION_ERRNO
+
diff --git a/gas/config/aout_gnu.h b/gas/config/aout_gnu.h
new file mode 100644
index 00000000000..badf9cb21c7
--- /dev/null
+++ b/gas/config/aout_gnu.h
@@ -0,0 +1,455 @@
+/* This file is aout_gnu.h
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+/* There are two main flavours of a.out, one which uses the standard
+ relocations, and one which uses extended relocations.
+
+ Today, the extended reloc uses are
+ TC_SPARC, TC_A29K
+
+ each must define the enum reloc_type
+
+*/
+
+#define USE_EXTENDED_RELOC (defined(TC_SPARC) || defined(TC_A29K))
+
+#if defined(TC_SPARC) || defined(TC_A29K)
+enum reloc_type
+ {
+ RELOC_8, RELOC_16, RELOC_32,/* simple relocations */
+ RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* pc-rel displacement */
+ RELOC_WDISP30, RELOC_WDISP22,
+ RELOC_HI22, RELOC_22,
+ RELOC_13, RELOC_LO10,
+ RELOC_SFA_BASE, RELOC_SFA_OFF13,
+ RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* P.I.C. (base-relative) */
+ RELOC_PC10, RELOC_PC22, /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_JMP_TBL, /* P.I.C. jump table */
+ RELOC_SEGOFF16, /* reputedly for shared libraries somehow */
+ RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE,
+ RELOC_10, RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22,
+ RELOC_HLO10,
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG, RELOC_CONST, RELOC_CONSTH,
+
+ RELOC_WDISP14, RELOC_WDISP21,
+
+ NO_RELOC
+ };
+
+#endif /* TC_SPARC or TC_A29K */
+
+
+#define __GNU_EXEC_MACROS__
+
+#ifndef __STRUCT_EXEC_OVERRIDE__
+
+/* This is the layout on disk of a Unix V7, Berkeley, SunOS, Vax Ultrix
+ "struct exec". Don't assume that on this machine, the "struct exec"
+ will lay out the same sizes or alignments. */
+
+struct exec_bytes
+ {
+ unsigned char a_info[4];
+ unsigned char a_text[4];
+ unsigned char a_data[4];
+ unsigned char a_bss[4];
+ unsigned char a_syms[4];
+ unsigned char a_entry[4];
+ unsigned char a_trsize[4];
+ unsigned char a_drsize[4];
+ };
+
+/* How big the "struct exec" is on disk */
+#define EXEC_BYTES_SIZE (8 * 4)
+
+/* This is the layout in memory of a "struct exec" while we process it. */
+
+struct exec
+{
+ unsigned long a_info; /* Use macros N_MAGIC, etc for access */
+ unsigned a_text; /* length of text, in bytes */
+ unsigned a_data; /* length of data, in bytes */
+ unsigned a_bss; /* length of uninitialized data area for file, in bytes */
+ unsigned a_syms; /* length of symbol table data in file, in bytes */
+ unsigned a_entry; /* start address */
+ unsigned a_trsize; /* length of relocation info for text, in bytes */
+ unsigned a_drsize; /* length of relocation info for data, in bytes */
+};
+
+#endif /* __STRUCT_EXEC_OVERRIDE__ */
+
+/* these go in the N_MACHTYPE field */
+/* These symbols could be defined by code from Suns...punt 'em */
+#undef M_UNKNOWN
+#undef M_68010
+#undef M_68020
+#undef M_SPARC
+enum machine_type
+ {
+ M_UNKNOWN = 0,
+ M_68010 = 1,
+ M_68020 = 2,
+ M_SPARC = 3,
+ /* skip a bunch so we don't run into any of sun's numbers */
+ M_386 = 100,
+ M_29K = 101,
+ M_RS6000 = 102, /* IBM RS/6000 */
+ /* HP/BSD formats */
+ M_HP200 = 200, /* hp200 (68010) BSD binary */
+ M_HP300 = 300, /* hp300 (68020+68881) BSD binary */
+ M_HPUX23 = 0x020C /* hp200/300 HPUX binary */
+ };
+
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags) \
+ ((exec).a_info = ((magic) & 0xffff) \
+ | (((int)(type) & 0xff) << 16) \
+ | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic) \
+ ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+
+#define N_SET_MACHTYPE(exec, machtype) \
+ ((exec).a_info = \
+ ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+
+#define N_SET_FLAGS(exec, flags) \
+ ((exec).a_info = \
+ ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+/* Code indicating object file or impure executable. */
+#ifndef OMAGIC
+#define OMAGIC 0407
+#endif
+/* Code indicating pure executable. */
+#define NMAGIC 0410
+/* Code indicating demand-paged executable. */
+#define ZMAGIC 0413
+
+/* Virtual Address of text segment from the a.out file. For OMAGIC,
+ (almost always "unlinked .o's" these days), should be zero.
+ For linked files, should reflect reality if we know it. */
+
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) (N_MAGIC(x)==OMAGIC? 0 : TEXT_START_ADDR)
+#endif
+
+#ifndef N_BADMAG
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+#endif
+
+/* By default, segment size is constant. But on some machines, it can
+ be a function of the a.out header (e.g. machine type). */
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+
+/* This complexity is for encapsulated COFF support */
+#ifndef _N_HDROFF
+#define _N_HDROFF(x) (N_SEGSIZE(x) - sizeof (struct exec))
+#endif
+
+#ifndef N_TXTOFF
+#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? \
+ _N_HDROFF((x)) + sizeof (struct exec) : \
+ sizeof (struct exec))
+#endif
+
+
+#ifndef N_DATOFF
+#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#endif
+
+#ifndef N_TRELOFF
+#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#endif
+
+#ifndef N_DRELOFF
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#endif
+
+#ifndef N_SYMOFF
+#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#endif
+
+#ifndef N_STROFF
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#endif
+
+/* Address of text segment in memory after it is loaded. */
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) 0
+#endif
+
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+(x).a_text-1) & ~(N_SEGSIZE(x)-1))))
+#endif
+
+/* Address of bss segment in memory after it is loaded. */
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+struct nlist
+ {
+ union
+ {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ }
+ n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+ };
+
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_COMM 0x12 /* common (visible in shared lib commons) */
+#define N_FN 0x1F /* File name of a .o file */
+
+/* Note: N_EXT can only usefully be OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1
+#define N_TYPE 036
+#define N_STAB 0340
+
+/* The following type indicates the definition of a symbol as being
+ an indirect reference to another symbol. The other symbol
+ appears as an undefined reference, immediately following this symbol.
+
+ Indirection is asymmetrical. The other symbol's value will be used
+ to satisfy requests for the indirect symbol, but not vice versa.
+ If the other symbol does not have a definition, libraries will
+ be searched to find a definition. */
+
+#define N_INDR 0xa
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ element's value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
+
+/* Weak symbols. These are a GNU extension to the a.out format. The
+ semantics are those of ELF weak symbols. Weak symbols are always
+ externally visible. The N_WEAK? values are squeezed into the
+ available slots. The value of a N_WEAKU symbol is 0. The values
+ of the other types are the definitions. */
+#define N_WEAKU 0x0d /* Weak undefined symbol. */
+#define N_WEAKA 0x0e /* Weak absolute symbol. */
+#define N_WEAKT 0x0f /* Weak text symbol. */
+#define N_WEAKD 0x10 /* Weak data symbol. */
+#define N_WEAKB 0x11 /* Weak bss symbol. */
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+/* The following enum and struct were borrowed from SunOS's
+ /usr/include/sun4/a.out.h and extended to handle
+ other machines. It is currently used on SPARC and AMD 29000.
+
+ reloc_ext_bytes is how it looks on disk. reloc_info_extended is
+ how we might process it on a native host. */
+#if USE_EXTENDED_RELOC
+
+struct reloc_ext_bytes
+ {
+ unsigned char r_address[4];
+ unsigned char r_index[3];
+ unsigned char r_bits[1];
+ unsigned char r_addend[4];
+ };
+
+
+#define RELOC_EXT_BITS_EXTERN_BIG 0x80
+#define RELOC_EXT_BITS_EXTERN_LITTLE 0x01
+
+#define RELOC_EXT_BITS_TYPE_BIG 0x1F
+#define RELOC_EXT_BITS_TYPE_SH_BIG 0
+#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+
+#define RELOC_EXT_SIZE 12 /* Bytes per relocation entry */
+
+struct reloc_info_extended
+{
+ unsigned long r_address;
+ unsigned int r_index:24;
+# define r_symbolnum r_index
+ unsigned r_extern:1;
+ unsigned:2;
+ /* RS/6000 compiler does not support enum bitfield
+ enum reloc_type r_type:5; */
+ enum reloc_type r_type;
+ long int r_addend;
+};
+
+#else
+
+/* The standard, old-fashioned, Berkeley compatible relocation struct */
+
+
+
+#ifdef TC_I860
+/* NOTE: three bits max, see struct reloc_info_i860.r_type */
+enum i860_reloc_type
+ {
+ NO_RELOC = 0, BRADDR, LOW0, LOW1, LOW2, LOW3, LOW4, SPLIT0, SPLIT1, SPLIT2, RELOC_32,
+ };
+
+typedef enum i860_reloc_type reloc_type;
+
+/* NOTE: two bits max, see reloc_info_i860.r_type */
+enum highlow_type
+ {
+ NO_SPEC = 0, PAIR, HIGH, HIGHADJ,
+ };
+
+
+struct reloc_info_i860
+{
+ unsigned long r_address;
+ /*
+ * Using bit fields here is a bad idea because the order is not portable. :-(
+ */
+ unsigned int r_symbolnum:24;
+ unsigned int r_pcrel:1;
+ unsigned int r_extern:1;
+ /* combining the two field simplifies the argument passing in "new_fix()" */
+ /* and is compatible with the existing Sparc #ifdef's */
+ /* r_type: highlow_type - bits 5,4; reloc_type - bits 3-0 */
+ unsigned int r_type:6;
+ long r_addend;
+};
+
+#endif /* TC_I860 */
+
+
+struct reloc_std_bytes
+ {
+ unsigned char r_address[4];
+ unsigned char r_index[3];
+ unsigned char r_bits[1];
+ };
+
+#define RELOC_STD_BITS_PCREL_BIG 0x80
+#define RELOC_STD_BITS_PCREL_LITTLE 0x01
+
+#define RELOC_STD_BITS_LENGTH_BIG 0x60
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5 /* To shift to units place */
+#define RELOC_STD_BITS_LENGTH_LITTLE 0x06
+#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
+
+#define RELOC_STD_BITS_EXTERN_BIG 0x10
+#define RELOC_STD_BITS_EXTERN_LITTLE 0x08
+
+#define RELOC_STD_BITS_BASEREL_BIG 0x08
+#define RELOC_STD_BITS_BASEREL_LITTLE 0x08
+
+#define RELOC_STD_BITS_JMPTABLE_BIG 0x04
+#define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04
+
+#define RELOC_STD_BITS_RELATIVE_BIG 0x02
+#define RELOC_STD_BITS_RELATIVE_LITTLE 0x02
+
+#define RELOC_STD_SIZE 8 /* Bytes per relocation entry */
+
+#endif /* USE_EXTENDED_RELOC */
+
+#ifndef CUSTOM_RELOC_FORMAT
+struct relocation_info
+{
+ /* Address (within segment) to be relocated. */
+ int r_address;
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in file's the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* The next three bits are for SunOS shared libraries, and seem to
+ be undocumented. */
+#ifdef TC_NS32K
+ unsigned int r_bsr:1;
+ unsigned int r_disp:2;
+#else
+ unsigned int r_baserel:1; /* Linkage table relative */
+ unsigned int r_jmptable:1; /* pc-relative to jump table */
+ unsigned int r_relative:1; /* "relative relocation" */
+#endif /* TC_NS32K */
+ /* unused */
+ unsigned int r_pad:1; /* Padding -- set to zero */
+};
+
+#endif /* CUSTOM_RELOC_FORMAT */
+
+#endif /* __A_OUT_GNU_H__ */
+
+/* end of aout_gnu.h */
diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c
new file mode 100644
index 00000000000..d586e3a85e3
--- /dev/null
+++ b/gas/config/atof-ieee.c
@@ -0,0 +1,696 @@
+/* atof_ieee.c - turn a Flonum into an IEEE floating point number
+ Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+/* Flonums returned here. */
+extern FLONUM_TYPE generic_floating_point_number;
+
+static int next_bits PARAMS ((int));
+static void unget_bits PARAMS ((int));
+static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
+
+extern const char EXP_CHARS[];
+/* Precision in LittleNums. */
+/* Don't count the gap in the m68k extended precision format. */
+#define MAX_PRECISION (5)
+#define F_PRECISION (2)
+#define D_PRECISION (4)
+#define X_PRECISION (5)
+#define P_PRECISION (5)
+
+/* Length in LittleNums of guard bits. */
+#define GUARD (2)
+
+static const unsigned long mask[] =
+{
+ 0x00000000,
+ 0x00000001,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000f,
+ 0x0000001f,
+ 0x0000003f,
+ 0x0000007f,
+ 0x000000ff,
+ 0x000001ff,
+ 0x000003ff,
+ 0x000007ff,
+ 0x00000fff,
+ 0x00001fff,
+ 0x00003fff,
+ 0x00007fff,
+ 0x0000ffff,
+ 0x0001ffff,
+ 0x0003ffff,
+ 0x0007ffff,
+ 0x000fffff,
+ 0x001fffff,
+ 0x003fffff,
+ 0x007fffff,
+ 0x00ffffff,
+ 0x01ffffff,
+ 0x03ffffff,
+ 0x07ffffff,
+ 0x0fffffff,
+ 0x1fffffff,
+ 0x3fffffff,
+ 0x7fffffff,
+ 0xffffffff,
+};
+
+
+static int bits_left_in_littlenum;
+static int littlenums_left;
+static LITTLENUM_TYPE *littlenum_pointer;
+
+static int
+next_bits (number_of_bits)
+ int number_of_bits;
+{
+ int return_value;
+
+ if (!littlenums_left)
+ return (0);
+ if (number_of_bits >= bits_left_in_littlenum)
+ {
+ return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
+ number_of_bits -= bits_left_in_littlenum;
+ return_value <<= number_of_bits;
+
+ if (--littlenums_left)
+ {
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
+ --littlenum_pointer;
+ return_value |= (*littlenum_pointer >> bits_left_in_littlenum) & mask[number_of_bits];
+ }
+ }
+ else
+ {
+ bits_left_in_littlenum -= number_of_bits;
+ return_value = mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum);
+ }
+ return (return_value);
+}
+
+/* Num had better be less than LITTLENUM_NUMBER_OF_BITS */
+static void
+unget_bits (num)
+ int num;
+{
+ if (!littlenums_left)
+ {
+ ++littlenum_pointer;
+ ++littlenums_left;
+ bits_left_in_littlenum = num;
+ }
+ else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS)
+ {
+ bits_left_in_littlenum = num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum);
+ ++littlenum_pointer;
+ ++littlenums_left;
+ }
+ else
+ bits_left_in_littlenum += num;
+}
+
+static void
+make_invalid_floating_point_number (words)
+ LITTLENUM_TYPE *words;
+{
+ as_bad (_("cannot create floating-point number"));
+ words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; /* Zero the leftmost bit */
+ words[1] = (LITTLENUM_TYPE) -1;
+ words[2] = (LITTLENUM_TYPE) -1;
+ words[3] = (LITTLENUM_TYPE) -1;
+ words[4] = (LITTLENUM_TYPE) -1;
+ words[5] = (LITTLENUM_TYPE) -1;
+}
+
+/************************************************************************\
+ * Warning: this returns 16-bit LITTLENUMs. It is up to the caller *
+ * to figure out any alignment problems and to conspire for the *
+ * bytes/word to be emitted in the right order. Bigendians beware! *
+ * *
+\************************************************************************/
+
+/* Note that atof-ieee always has X and P precisions enabled. it is up
+ to md_atof to filter them out if the target machine does not support
+ them. */
+
+/* Returns pointer past text consumed. */
+char *
+atof_ieee (str, what_kind, words)
+ char *str; /* Text to convert to binary. */
+ char what_kind; /* 'd', 'f', 'g', 'h' */
+ LITTLENUM_TYPE *words; /* Build the binary here. */
+{
+ /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
+ zeroed, the last contain flonum bits. */
+ static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
+ char *return_value;
+ /* Number of 16-bit words in the format. */
+ int precision;
+ long exponent_bits;
+ FLONUM_TYPE save_gen_flonum;
+
+ /* We have to save the generic_floating_point_number because it
+ contains storage allocation about the array of LITTLENUMs where
+ the value is actually stored. We will allocate our own array of
+ littlenums below, but have to restore the global one on exit. */
+ save_gen_flonum = generic_floating_point_number;
+
+ return_value = str;
+ generic_floating_point_number.low = bits + MAX_PRECISION;
+ generic_floating_point_number.high = NULL;
+ generic_floating_point_number.leader = NULL;
+ generic_floating_point_number.exponent = 0;
+ generic_floating_point_number.sign = '\0';
+
+ /* Use more LittleNums than seems necessary: the highest flonum may
+ have 15 leading 0 bits, so could be useless. */
+
+ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
+
+ switch (what_kind)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ precision = F_PRECISION;
+ exponent_bits = 8;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ precision = D_PRECISION;
+ exponent_bits = 11;
+ break;
+
+ case 'x':
+ case 'X':
+ case 'e':
+ case 'E':
+ precision = X_PRECISION;
+ exponent_bits = 15;
+ break;
+
+ case 'p':
+ case 'P':
+
+ precision = P_PRECISION;
+ exponent_bits = -1;
+ break;
+
+ default:
+ make_invalid_floating_point_number (words);
+ return (NULL);
+ }
+
+ generic_floating_point_number.high
+ = generic_floating_point_number.low + precision - 1 + GUARD;
+
+ if (atof_generic (&return_value, ".", EXP_CHARS,
+ &generic_floating_point_number))
+ {
+ make_invalid_floating_point_number (words);
+ return (NULL);
+ }
+ gen_to_words (words, precision, exponent_bits);
+
+ /* Restore the generic_floating_point_number's storage alloc (and
+ everything else). */
+ generic_floating_point_number = save_gen_flonum;
+
+ return return_value;
+}
+
+/* Turn generic_floating_point_number into a real float/double/extended. */
+int
+gen_to_words (words, precision, exponent_bits)
+ LITTLENUM_TYPE *words;
+ int precision;
+ long exponent_bits;
+{
+ int return_value = 0;
+
+ long exponent_1;
+ long exponent_2;
+ long exponent_3;
+ long exponent_4;
+ int exponent_skippage;
+ LITTLENUM_TYPE word1;
+ LITTLENUM_TYPE *lp;
+ LITTLENUM_TYPE *words_end;
+
+ words_end = words + precision;
+#ifdef TC_M68K
+ if (precision == X_PRECISION)
+ /* On the m68k the extended precision format has a gap of 16 bits
+ between the exponent and the mantissa. */
+ words_end++;
+#endif
+
+ if (generic_floating_point_number.low > generic_floating_point_number.leader)
+ {
+ /* 0.0e0 seen. */
+ if (generic_floating_point_number.sign == '+')
+ words[0] = 0x0000;
+ else
+ words[0] = 0x8000;
+ memset (&words[1], '\0',
+ (words_end - words - 1) * sizeof (LITTLENUM_TYPE));
+ return (return_value);
+ }
+
+ /* NaN: Do the right thing */
+ if (generic_floating_point_number.sign == 0)
+ {
+ if (precision == F_PRECISION)
+ {
+ words[0] = 0x7fff;
+ words[1] = 0xffff;
+ }
+ else if (precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ words[0] = 0x7fff;
+ words[1] = 0;
+ words[2] = 0xffff;
+ words[3] = 0xffff;
+ words[4] = 0xffff;
+ words[5] = 0xffff;
+#else /* ! TC_M68K */
+#ifdef TC_I386
+ words[0] = 0xffff;
+ words[1] = 0xc000;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+#else /* ! TC_I386 */
+ abort ();
+#endif /* ! TC_I386 */
+#endif /* ! TC_M68K */
+ }
+ else
+ {
+ words[0] = 0x7fff;
+ words[1] = 0xffff;
+ words[2] = 0xffff;
+ words[3] = 0xffff;
+ }
+ return return_value;
+ }
+ else if (generic_floating_point_number.sign == 'P')
+ {
+ /* +INF: Do the right thing */
+ if (precision == F_PRECISION)
+ {
+ words[0] = 0x7f80;
+ words[1] = 0;
+ }
+ else if (precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ words[0] = 0x7fff;
+ words[1] = 0;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+ words[5] = 0;
+#else /* ! TC_M68K */
+#ifdef TC_I386
+ words[0] = 0x7fff;
+ words[1] = 0x8000;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+#else /* ! TC_I386 */
+ abort ();
+#endif /* ! TC_I386 */
+#endif /* ! TC_M68K */
+ }
+ else
+ {
+ words[0] = 0x7ff0;
+ words[1] = 0;
+ words[2] = 0;
+ words[3] = 0;
+ }
+ return (return_value);
+ }
+ else if (generic_floating_point_number.sign == 'N')
+ {
+ /* Negative INF */
+ if (precision == F_PRECISION)
+ {
+ words[0] = 0xff80;
+ words[1] = 0x0;
+ }
+ else if (precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ words[0] = 0xffff;
+ words[1] = 0;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+ words[5] = 0;
+#else /* ! TC_M68K */
+#ifdef TC_I386
+ words[0] = 0xffff;
+ words[1] = 0x8000;
+ words[2] = 0;
+ words[3] = 0;
+ words[4] = 0;
+#else /* ! TC_I386 */
+ abort ();
+#endif /* ! TC_I386 */
+#endif /* ! TC_M68K */
+ }
+ else
+ {
+ words[0] = 0xfff0;
+ words[1] = 0x0;
+ words[2] = 0x0;
+ words[3] = 0x0;
+ }
+ return (return_value);
+ }
+ /*
+ * The floating point formats we support have:
+ * Bit 15 is sign bit.
+ * Bits 14:n are excess-whatever exponent.
+ * Bits n-1:0 (if any) are most significant bits of fraction.
+ * Bits 15:0 of the next word(s) are the next most significant bits.
+ *
+ * So we need: number of bits of exponent, number of bits of
+ * mantissa.
+ */
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
+ littlenum_pointer = generic_floating_point_number.leader;
+ littlenums_left = (1
+ + generic_floating_point_number.leader
+ - generic_floating_point_number.low);
+ /* Seek (and forget) 1st significant bit */
+ for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage);;
+ exponent_1 = (generic_floating_point_number.exponent
+ + generic_floating_point_number.leader
+ + 1
+ - generic_floating_point_number.low);
+ /* Radix LITTLENUM_RADIX, point just higher than
+ generic_floating_point_number.leader. */
+ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
+ /* Radix 2. */
+ exponent_3 = exponent_2 - exponent_skippage;
+ /* Forget leading zeros, forget 1st bit. */
+ exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
+ /* Offset exponent. */
+
+ lp = words;
+
+ /* Word 1. Sign, exponent and perhaps high bits. */
+ word1 = ((generic_floating_point_number.sign == '+')
+ ? 0
+ : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
+
+ /* Assume 2's complement integers. */
+ if (exponent_4 <= 0)
+ {
+ int prec_bits;
+ int num_bits;
+
+ unget_bits (1);
+ num_bits = -exponent_4;
+ prec_bits = LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits);
+#ifdef TC_I386
+ if (precision == X_PRECISION && exponent_bits == 15)
+ {
+ /* On the i386 a denormalized extended precision float is
+ shifted down by one, effectively decreasing the exponent
+ bias by one. */
+ prec_bits -= 1;
+ num_bits += 1;
+ }
+#endif
+
+ if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits)
+ {
+ /* Bigger than one littlenum */
+ num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits;
+ *lp++ = word1;
+ if (num_bits + exponent_bits + 1 >= precision * LITTLENUM_NUMBER_OF_BITS)
+ {
+ /* Exponent overflow */
+ make_invalid_floating_point_number (words);
+ return (return_value);
+ }
+#ifdef TC_M68K
+ if (precision == X_PRECISION && exponent_bits == 15)
+ *lp++ = 0;
+#endif
+ while (num_bits >= LITTLENUM_NUMBER_OF_BITS)
+ {
+ num_bits -= LITTLENUM_NUMBER_OF_BITS;
+ *lp++ = 0;
+ }
+ if (num_bits)
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits));
+ }
+ else
+ {
+ if (precision == X_PRECISION && exponent_bits == 15)
+ {
+ *lp++ = word1;
+#ifdef TC_M68K
+ *lp++ = 0;
+#endif
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits);
+ }
+ else
+ {
+ word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - (exponent_bits + num_bits));
+ *lp++ = word1;
+ }
+ }
+ while (lp < words_end)
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
+
+ /* Round the mantissa up, but don't change the number */
+ if (next_bits (1))
+ {
+ --lp;
+ if (prec_bits > LITTLENUM_NUMBER_OF_BITS)
+ {
+ int n = 0;
+ int tmp_bits;
+
+ n = 0;
+ tmp_bits = prec_bits;
+ while (tmp_bits > LITTLENUM_NUMBER_OF_BITS)
+ {
+ if (lp[n] != (LITTLENUM_TYPE) - 1)
+ break;
+ --n;
+ tmp_bits -= LITTLENUM_NUMBER_OF_BITS;
+ }
+ if (tmp_bits > LITTLENUM_NUMBER_OF_BITS || (lp[n] & mask[tmp_bits]) != mask[tmp_bits])
+ {
+ unsigned long carry;
+
+ for (carry = 1; carry && (lp >= words); lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+ }
+ else
+ {
+ /* This is an overflow of the denormal numbers. We
+ need to forget what we have produced, and instead
+ generate the smallest normalized number. */
+ lp = words;
+ word1 = ((generic_floating_point_number.sign == '+')
+ ? 0
+ : (1 << (LITTLENUM_NUMBER_OF_BITS - 1)));
+ word1 |= (1
+ << ((LITTLENUM_NUMBER_OF_BITS - 1)
+ - exponent_bits));
+ *lp++ = word1;
+ while (lp < words_end)
+ *lp++ = 0;
+ }
+ }
+ else if ((*lp & mask[prec_bits]) != mask[prec_bits])
+ *lp += 1;
+ }
+
+ return return_value;
+ }
+ else if ((unsigned long) exponent_4 >= mask[exponent_bits])
+ {
+ /*
+ * Exponent overflow. Lose immediately.
+ */
+
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ make_invalid_floating_point_number (words);
+ return return_value;
+ }
+ else
+ {
+ word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits))
+ | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits);
+ }
+
+ *lp++ = word1;
+
+ /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the
+ middle. Either way, it is then followed by a 1 bit. */
+ if (exponent_bits == 15 && precision == X_PRECISION)
+ {
+#ifdef TC_M68K
+ *lp++ = 0;
+#endif
+ *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1)
+ | next_bits (LITTLENUM_NUMBER_OF_BITS - 1));
+ }
+
+ /* The rest of the words are just mantissa bits. */
+ while (lp < words_end)
+ *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
+
+ if (next_bits (1))
+ {
+ unsigned long carry;
+ /*
+ * Since the NEXT bit is a 1, round UP the mantissa.
+ * The cunning design of these hidden-1 floats permits
+ * us to let the mantissa overflow into the exponent, and
+ * it 'does the right thing'. However, we lose if the
+ * highest-order bit of the lowest-order word flips.
+ * Is that clear?
+ */
+
+ /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+ Please allow at least 1 more bit in carry than is in a LITTLENUM.
+ We need that extra bit to hold a carry during a LITTLENUM carry
+ propagation. Another extra bit (kept 0) will assure us that we
+ don't get a sticky sign bit after shifting right, and that
+ permits us to propagate the carry without any masking of bits.
+ #endif */
+ for (carry = 1, lp--; carry && (lp >= words); lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+ if (precision == X_PRECISION && exponent_bits == 15)
+ {
+ /* Extended precision numbers have an explicit integer bit
+ that we may have to restore. */
+ if (lp == words)
+ {
+#ifdef TC_M68K
+ /* On the m68k there is a gap of 16 bits. We must
+ explicitly propagate the carry into the exponent. */
+ words[0] += words[1];
+ words[1] = 0;
+ lp++;
+#endif
+ /* Put back the integer bit. */
+ lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1);
+ }
+ }
+ if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
+ {
+ /* We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1));
+ /* make_invalid_floating_point_number (words); */
+ /* return return_value; */
+ }
+ }
+ return (return_value);
+}
+
+#if 0 /* unused */
+/* This routine is a real kludge. Someone really should do it better,
+ but I'm too lazy, and I don't understand this stuff all too well
+ anyway. (JF) */
+static void
+int_to_gen (x)
+ long x;
+{
+ char buf[20];
+ char *bufp;
+
+ sprintf (buf, "%ld", x);
+ bufp = &buf[0];
+ if (atof_generic (&bufp, ".", EXP_CHARS, &generic_floating_point_number))
+ as_bad (_("Error converting number to floating point (Exponent overflow?)"));
+}
+#endif
+
+#ifdef TEST
+char *
+print_gen (gen)
+ FLONUM_TYPE *gen;
+{
+ FLONUM_TYPE f;
+ LITTLENUM_TYPE arr[10];
+ double dv;
+ float fv;
+ static char sbuf[40];
+
+ if (gen)
+ {
+ f = generic_floating_point_number;
+ generic_floating_point_number = *gen;
+ }
+ gen_to_words (&arr[0], 4, 11);
+ memcpy (&dv, &arr[0], sizeof (double));
+ sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv);
+ gen_to_words (&arr[0], 2, 8);
+ memcpy (&fv, &arr[0], sizeof (float));
+ sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv);
+
+ if (gen)
+ {
+ generic_floating_point_number = f;
+ }
+
+ return (sbuf);
+}
+
+#endif
+
+/* end of atof-ieee.c */
diff --git a/gas/config/atof-tahoe.c b/gas/config/atof-tahoe.c
new file mode 100644
index 00000000000..760485c5fde
--- /dev/null
+++ b/gas/config/atof-tahoe.c
@@ -0,0 +1,431 @@
+
+/* atof_tahoe.c - turn a string into a Tahoe floating point number
+ Copyright (C) 1987, 1998 Free Software Foundation, Inc.
+ */
+
+/* This is really a simplified version of atof_vax.c. I glommed it wholesale
+ and then shaved it down. I don't even know how it works. (Don't you find
+ my honesty refreshing? bowen@cs.Buffalo.EDU (Devon E Bowen)
+
+ I don't allow uppercase letters in the precision descrpitors. Ie 'f' and
+ 'd' are allowed but 'F' and 'D' aren't */
+
+#include "as.h"
+
+/* Precision in LittleNums. */
+#define MAX_PRECISION (4)
+#define D_PRECISION (4)
+#define F_PRECISION (2)
+
+/* Precision in chars. */
+#define D_PRECISION_CHARS (8)
+#define F_PRECISION_CHARS (4)
+
+/* Length in LittleNums of guard bits. */
+#define GUARD (2)
+
+static const long int mask[] =
+{
+ 0x00000000,
+ 0x00000001,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000f,
+ 0x0000001f,
+ 0x0000003f,
+ 0x0000007f,
+ 0x000000ff,
+ 0x000001ff,
+ 0x000003ff,
+ 0x000007ff,
+ 0x00000fff,
+ 0x00001fff,
+ 0x00003fff,
+ 0x00007fff,
+ 0x0000ffff,
+ 0x0001ffff,
+ 0x0003ffff,
+ 0x0007ffff,
+ 0x000fffff,
+ 0x001fffff,
+ 0x003fffff,
+ 0x007fffff,
+ 0x00ffffff,
+ 0x01ffffff,
+ 0x03ffffff,
+ 0x07ffffff,
+ 0x0fffffff,
+ 0x1fffffff,
+ 0x3fffffff,
+ 0x7fffffff,
+ 0xffffffff
+};
+
+
+/* Shared between flonum_gen2tahoe and next_bits */
+static int bits_left_in_littlenum;
+static LITTLENUM_TYPE *littlenum_pointer;
+static LITTLENUM_TYPE *littlenum_end;
+
+#if __STDC__ == 1
+
+int flonum_gen2tahoe (int format_letter, FLONUM_TYPE * f, LITTLENUM_TYPE * words);
+
+#else /* not __STDC__ */
+
+int flonum_gen2tahoe ();
+
+#endif /* not __STDC__ */
+
+
+static int
+next_bits (number_of_bits)
+ int number_of_bits;
+{
+ int return_value;
+
+ if (littlenum_pointer < littlenum_end)
+ return 0;
+ if (number_of_bits >= bits_left_in_littlenum)
+ {
+ return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
+ number_of_bits -= bits_left_in_littlenum;
+ return_value <<= number_of_bits;
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
+ littlenum_pointer--;
+ if (littlenum_pointer >= littlenum_end)
+ return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) &
+ mask[number_of_bits];
+ }
+ else
+ {
+ bits_left_in_littlenum -= number_of_bits;
+ return_value = mask[number_of_bits] &
+ ((*littlenum_pointer) >> bits_left_in_littlenum);
+ }
+ return (return_value);
+}
+
+static void
+make_invalid_floating_point_number (words)
+ LITTLENUM_TYPE *words;
+{
+ *words = 0x8000; /* Floating Reserved Operand Code */
+}
+
+static int /* 0 means letter is OK. */
+what_kind_of_float (letter, precisionP, exponent_bitsP)
+ char letter; /* In: lowercase please. What kind of float? */
+ int *precisionP; /* Number of 16-bit words in the float. */
+ long int *exponent_bitsP; /* Number of exponent bits. */
+{
+ int retval; /* 0: OK. */
+
+ retval = 0;
+ switch (letter)
+ {
+ case 'f':
+ *precisionP = F_PRECISION;
+ *exponent_bitsP = 8;
+ break;
+
+ case 'd':
+ *precisionP = D_PRECISION;
+ *exponent_bitsP = 8;
+ break;
+
+ default:
+ retval = 69;
+ break;
+ }
+ return (retval);
+}
+
+/***********************************************************************\
+* *
+* Warning: this returns 16-bit LITTLENUMs, because that is *
+* what the VAX thinks in. It is up to the caller to figure *
+* out any alignment problems and to conspire for the bytes/word *
+* to be emitted in the right order. Bigendians beware! *
+* *
+\***********************************************************************/
+
+char * /* Return pointer past text consumed. */
+atof_tahoe (str, what_kind, words)
+ char *str; /* Text to convert to binary. */
+ char what_kind; /* 'd', 'f', 'g', 'h' */
+ LITTLENUM_TYPE *words; /* Build the binary here. */
+{
+ FLONUM_TYPE f;
+ LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
+ /* Extra bits for zeroed low-order bits. */
+ /* The 1st MAX_PRECISION are zeroed, */
+ /* the last contain flonum bits. */
+ char *return_value;
+ int precision; /* Number of 16-bit words in the format. */
+ long int exponent_bits;
+
+ return_value = str;
+ f.low = bits + MAX_PRECISION;
+ f.high = NULL;
+ f.leader = NULL;
+ f.exponent = NULL;
+ f.sign = '\0';
+
+ if (what_kind_of_float (what_kind, &precision, &exponent_bits))
+ {
+ return_value = NULL; /* We lost. */
+ make_invalid_floating_point_number (words);
+ }
+ if (return_value)
+ {
+ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
+
+ /* Use more LittleNums than seems */
+ /* necessary: the highest flonum may have */
+ /* 15 leading 0 bits, so could be useless. */
+ f.high = f.low + precision - 1 + GUARD;
+
+ if (atof_generic (&return_value, ".", "eE", &f))
+ {
+ make_invalid_floating_point_number (words);
+ return_value = NULL; /* we lost */
+ }
+ else
+ {
+ if (flonum_gen2tahoe (what_kind, &f, words))
+ {
+ return_value = NULL;
+ }
+ }
+ }
+ return (return_value);
+}
+
+/*
+ * In: a flonum, a Tahoe floating point format.
+ * Out: a Tahoe floating-point bit pattern.
+ */
+
+int /* 0: OK. */
+flonum_gen2tahoe (format_letter, f, words)
+ char format_letter; /* One of 'd' 'f'. */
+ FLONUM_TYPE *f;
+ LITTLENUM_TYPE *words; /* Deliver answer here. */
+{
+ LITTLENUM_TYPE *lp;
+ int precision;
+ long int exponent_bits;
+ int return_value; /* 0 == OK. */
+
+ return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
+ if (return_value != 0)
+ {
+ make_invalid_floating_point_number (words);
+ }
+ else
+ {
+ if (f->low > f->leader)
+ {
+ /* 0.0e0 seen. */
+ memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
+ }
+ else
+ {
+ long int exponent_1;
+ long int exponent_2;
+ long int exponent_3;
+ long int exponent_4;
+ int exponent_skippage;
+ LITTLENUM_TYPE word1;
+
+ /* JF: Deal with new Nan, +Inf and -Inf codes */
+ if (f->sign != '-' && f->sign != '+')
+ {
+ make_invalid_floating_point_number (words);
+ return return_value;
+ }
+ /*
+ * All tahoe floating_point formats have:
+ * Bit 15 is sign bit.
+ * Bits 14:n are excess-whatever exponent.
+ * Bits n-1:0 (if any) are most significant bits of fraction.
+ * Bits 15:0 of the next word are the next most significant bits.
+ * And so on for each other word.
+ *
+ * So we need: number of bits of exponent, number of bits of
+ * mantissa.
+ */
+
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
+ littlenum_pointer = f->leader;
+ littlenum_end = f->low;
+ /* Seek (and forget) 1st significant bit */
+ for (exponent_skippage = 0;
+ !next_bits (1);
+ exponent_skippage++)
+ {
+ }
+ exponent_1 = f->exponent + f->leader + 1 - f->low;
+ /* Radix LITTLENUM_RADIX, point just higher than f -> leader. */
+ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
+ /* Radix 2. */
+ exponent_3 = exponent_2 - exponent_skippage;
+ /* Forget leading zeros, forget 1st bit. */
+ exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
+ /* Offset exponent. */
+
+ if (exponent_4 & ~mask[exponent_bits])
+ {
+ /*
+ * Exponent overflow. Lose immediately.
+ */
+
+ make_invalid_floating_point_number (words);
+
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ else
+ {
+ lp = words;
+
+ /* Word 1. Sign, exponent and perhaps high bits. */
+ /* Assume 2's complement integers. */
+ word1 = ((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
+ | ((f->sign == '+') ? 0 : 0x8000)
+ | next_bits (15 - exponent_bits);
+ *lp++ = word1;
+
+ /* The rest of the words are just mantissa bits. */
+ for (; lp < words + precision; lp++)
+ {
+ *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
+ }
+
+ if (next_bits (1))
+ {
+ /*
+ * Since the NEXT bit is a 1, round UP the mantissa.
+ * The cunning design of these hidden-1 floats permits
+ * us to let the mantissa overflow into the exponent, and
+ * it 'does the right thing'. However, we lose if the
+ * highest-order bit of the lowest-order word flips.
+ * Is that clear?
+ */
+
+ unsigned long int carry;
+
+ /*
+ #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+ Please allow at least 1 more bit in carry than is in a LITTLENUM.
+ We need that extra bit to hold a carry during a LITTLENUM carry
+ propagation. Another extra bit (kept 0) will assure us that we
+ don't get a sticky sign bit after shifting right, and that
+ permits us to propagate the carry without any masking of bits.
+ #endif
+ */
+ for (carry = 1, lp--;
+ carry && (lp >= words);
+ lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
+ {
+ make_invalid_floating_point_number (words);
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ } /* if (we needed to round up) */
+ } /* if (exponent overflow) */
+ } /* if (0.0e0) */
+ } /* if (float_type was OK) */
+ return (return_value);
+}
+
+/*
+ * md_atof()
+ *
+ * In: input_line_pointer -> the 1st character of a floating-point
+ * number.
+ * 1 letter denoting the type of statement that wants a
+ * binary floating point number returned.
+ * Address of where to build floating point literal.
+ * Assumed to be 'big enough'.
+ * Address of where to return size of literal (in chars).
+ *
+ * Out: Input_line_pointer -> of next char after floating number.
+ * Error message, or 0.
+ * Floating point literal.
+ * Number of chars we used for the literal.
+ */
+
+char *
+md_atof (what_statement_type, literalP, sizeP)
+ char what_statement_type;
+ char *literalP;
+ int *sizeP;
+{
+ LITTLENUM_TYPE words[MAX_PRECISION];
+ register char kind_of_float;
+ register int number_of_chars;
+ register LITTLENUM_TYPE *littlenum_pointer;
+
+ switch (what_statement_type)
+ {
+ case 'f': /* .ffloat */
+ case 'd': /* .dfloat */
+ kind_of_float = what_statement_type;
+ break;
+
+ default:
+ kind_of_float = 0;
+ break;
+ };
+
+ if (kind_of_float)
+ {
+ register LITTLENUM_TYPE *limit;
+
+ input_line_pointer = atof_tahoe (input_line_pointer,
+ kind_of_float,
+ words);
+ /*
+ * The atof_tahoe() builds up 16-bit numbers.
+ * Since the assembler may not be running on
+ * a different-endian machine, be very careful about
+ * converting words to chars.
+ */
+ number_of_chars = (kind_of_float == 'f' ? F_PRECISION_CHARS :
+ (kind_of_float == 'd' ? D_PRECISION_CHARS : 0));
+ know (number_of_chars <= MAX_PRECISION * sizeof (LITTLENUM_TYPE));
+ limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
+ for (littlenum_pointer = words;
+ littlenum_pointer < limit;
+ littlenum_pointer++)
+ {
+ md_number_to_chars (literalP, *littlenum_pointer,
+ sizeof (LITTLENUM_TYPE));
+ literalP += sizeof (LITTLENUM_TYPE);
+ };
+ }
+ else
+ {
+ number_of_chars = 0;
+ };
+
+ *sizeP = number_of_chars;
+ return kind_of_float ? 0 : _("Bad call to md_atof()");
+}
+
+/* atof_tahoe.c */
diff --git a/gas/config/atof-vax.c b/gas/config/atof-vax.c
new file mode 100644
index 00000000000..45b90a8cc24
--- /dev/null
+++ b/gas/config/atof-vax.c
@@ -0,0 +1,517 @@
+/* atof_vax.c - turn a Flonum into a VAX floating point number
+ Copyright (C) 1987, 1992, 93, 95, 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+static int atof_vax_sizeof PARAMS ((int));
+static int next_bits PARAMS ((int));
+static void make_invalid_floating_point_number PARAMS ((LITTLENUM_TYPE *));
+static int what_kind_of_float PARAMS ((int, int *, long *));
+static char *atof_vax PARAMS ((char *, int, LITTLENUM_TYPE *));
+
+/* Precision in LittleNums. */
+#define MAX_PRECISION (8)
+#define H_PRECISION (8)
+#define G_PRECISION (4)
+#define D_PRECISION (4)
+#define F_PRECISION (2)
+
+/* Length in LittleNums of guard bits. */
+#define GUARD (2)
+
+int flonum_gen2vax PARAMS ((int format_letter, FLONUM_TYPE * f,
+ LITTLENUM_TYPE * words));
+
+/* Number of chars in flonum type 'letter'. */
+static int
+atof_vax_sizeof (letter)
+ int letter;
+{
+ int return_value;
+
+ /*
+ * Permitting uppercase letters is probably a bad idea.
+ * Please use only lower-cased letters in case the upper-cased
+ * ones become unsupported!
+ */
+ switch (letter)
+ {
+ case 'f':
+ case 'F':
+ return_value = 4;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'g':
+ case 'G':
+ return_value = 8;
+ break;
+
+ case 'h':
+ case 'H':
+ return_value = 16;
+ break;
+
+ default:
+ return_value = 0;
+ break;
+ }
+ return (return_value);
+} /* atof_vax_sizeof */
+
+static const long mask[] =
+{
+ 0x00000000,
+ 0x00000001,
+ 0x00000003,
+ 0x00000007,
+ 0x0000000f,
+ 0x0000001f,
+ 0x0000003f,
+ 0x0000007f,
+ 0x000000ff,
+ 0x000001ff,
+ 0x000003ff,
+ 0x000007ff,
+ 0x00000fff,
+ 0x00001fff,
+ 0x00003fff,
+ 0x00007fff,
+ 0x0000ffff,
+ 0x0001ffff,
+ 0x0003ffff,
+ 0x0007ffff,
+ 0x000fffff,
+ 0x001fffff,
+ 0x003fffff,
+ 0x007fffff,
+ 0x00ffffff,
+ 0x01ffffff,
+ 0x03ffffff,
+ 0x07ffffff,
+ 0x0fffffff,
+ 0x1fffffff,
+ 0x3fffffff,
+ 0x7fffffff,
+ 0xffffffff
+};
+
+
+/* Shared between flonum_gen2vax and next_bits */
+static int bits_left_in_littlenum;
+static LITTLENUM_TYPE *littlenum_pointer;
+static LITTLENUM_TYPE *littlenum_end;
+
+static int
+next_bits (number_of_bits)
+ int number_of_bits;
+{
+ int return_value;
+
+ if (littlenum_pointer < littlenum_end)
+ return 0;
+ if (number_of_bits >= bits_left_in_littlenum)
+ {
+ return_value = mask[bits_left_in_littlenum] & *littlenum_pointer;
+ number_of_bits -= bits_left_in_littlenum;
+ return_value <<= number_of_bits;
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
+ littlenum_pointer--;
+ if (littlenum_pointer >= littlenum_end)
+ return_value |= ((*littlenum_pointer) >> (bits_left_in_littlenum)) & mask[number_of_bits];
+ }
+ else
+ {
+ bits_left_in_littlenum -= number_of_bits;
+ return_value = mask[number_of_bits] & ((*littlenum_pointer) >> bits_left_in_littlenum);
+ }
+ return (return_value);
+}
+
+static void
+make_invalid_floating_point_number (words)
+ LITTLENUM_TYPE *words;
+{
+ *words = 0x8000; /* Floating Reserved Operand Code */
+}
+
+static int /* 0 means letter is OK. */
+what_kind_of_float (letter, precisionP, exponent_bitsP)
+ int letter; /* In: lowercase please. What kind of float? */
+ int *precisionP; /* Number of 16-bit words in the float. */
+ long *exponent_bitsP; /* Number of exponent bits. */
+{
+ int retval; /* 0: OK. */
+
+ retval = 0;
+ switch (letter)
+ {
+ case 'f':
+ *precisionP = F_PRECISION;
+ *exponent_bitsP = 8;
+ break;
+
+ case 'd':
+ *precisionP = D_PRECISION;
+ *exponent_bitsP = 8;
+ break;
+
+ case 'g':
+ *precisionP = G_PRECISION;
+ *exponent_bitsP = 11;
+ break;
+
+ case 'h':
+ *precisionP = H_PRECISION;
+ *exponent_bitsP = 15;
+ break;
+
+ default:
+ retval = 69;
+ break;
+ }
+ return (retval);
+}
+
+/***********************************************************************\
+ * *
+ * Warning: this returns 16-bit LITTLENUMs, because that is *
+ * what the VAX thinks in. It is up to the caller to figure *
+ * out any alignment problems and to conspire for the bytes/word *
+ * to be emitted in the right order. Bigendians beware! *
+ * *
+ \***********************************************************************/
+
+static char * /* Return pointer past text consumed. */
+atof_vax (str, what_kind, words)
+ char *str; /* Text to convert to binary. */
+ int what_kind; /* 'd', 'f', 'g', 'h' */
+ LITTLENUM_TYPE *words; /* Build the binary here. */
+{
+ FLONUM_TYPE f;
+ LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
+ /* Extra bits for zeroed low-order bits. */
+ /* The 1st MAX_PRECISION are zeroed, */
+ /* the last contain flonum bits. */
+ char *return_value;
+ int precision; /* Number of 16-bit words in the format. */
+ long exponent_bits;
+
+ return_value = str;
+ f.low = bits + MAX_PRECISION;
+ f.high = NULL;
+ f.leader = NULL;
+ f.exponent = 0;
+ f.sign = '\0';
+
+ if (what_kind_of_float (what_kind, &precision, &exponent_bits))
+ {
+ return_value = NULL; /* We lost. */
+ make_invalid_floating_point_number (words);
+ }
+
+ if (return_value)
+ {
+ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
+
+ /* Use more LittleNums than seems */
+ /* necessary: the highest flonum may have */
+ /* 15 leading 0 bits, so could be useless. */
+ f.high = f.low + precision - 1 + GUARD;
+
+ if (atof_generic (&return_value, ".", "eE", &f))
+ {
+ make_invalid_floating_point_number (words);
+ return_value = NULL; /* we lost */
+ }
+ else
+ {
+ if (flonum_gen2vax (what_kind, &f, words))
+ {
+ return_value = NULL;
+ }
+ }
+ }
+ return (return_value);
+} /* atof_vax() */
+
+/*
+ * In: a flonum, a vax floating point format.
+ * Out: a vax floating-point bit pattern.
+ */
+
+int /* 0: OK. */
+flonum_gen2vax (format_letter, f, words)
+ char format_letter; /* One of 'd' 'f' 'g' 'h'. */
+ FLONUM_TYPE *f;
+ LITTLENUM_TYPE *words; /* Deliver answer here. */
+{
+ LITTLENUM_TYPE *lp;
+ int precision;
+ long exponent_bits;
+ int return_value; /* 0 == OK. */
+
+ return_value = what_kind_of_float (format_letter, &precision, &exponent_bits);
+
+ if (return_value != 0)
+ {
+ make_invalid_floating_point_number (words);
+ }
+ else
+ {
+ if (f->low > f->leader)
+ {
+ /* 0.0e0 seen. */
+ memset (words, '\0', sizeof (LITTLENUM_TYPE) * precision);
+ }
+ else
+ {
+ long exponent_1;
+ long exponent_2;
+ long exponent_3;
+ long exponent_4;
+ int exponent_skippage;
+ LITTLENUM_TYPE word1;
+
+ /* JF: Deal with new Nan, +Inf and -Inf codes */
+ if (f->sign != '-' && f->sign != '+')
+ {
+ make_invalid_floating_point_number (words);
+ return return_value;
+ }
+ /*
+ * All vaxen floating_point formats (so far) have:
+ * Bit 15 is sign bit.
+ * Bits 14:n are excess-whatever exponent.
+ * Bits n-1:0 (if any) are most significant bits of fraction.
+ * Bits 15:0 of the next word are the next most significant bits.
+ * And so on for each other word.
+ *
+ * All this to be compatible with a KF11?? (Which is still faster
+ * than lots of vaxen I can think of, but it also has higher
+ * maintenance costs ... sigh).
+ *
+ * So we need: number of bits of exponent, number of bits of
+ * mantissa.
+ */
+
+#ifdef NEVER /******* This zeroing seems redundant - Dean 3may86 **********/
+ /*
+ * No matter how few bits we got back from the atof()
+ * routine, add enough zero littlenums so the rest of the
+ * code won't run out of "significant" bits in the mantissa.
+ */
+ {
+ LITTLENUM_TYPE *ltp;
+ for (ltp = f->leader + 1;
+ ltp <= f->low + precision;
+ ltp++)
+ {
+ *ltp = 0;
+ }
+ }
+#endif
+
+ bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
+ littlenum_pointer = f->leader;
+ littlenum_end = f->low;
+ /* Seek (and forget) 1st significant bit */
+ for (exponent_skippage = 0;
+ !next_bits (1);
+ exponent_skippage++);;
+
+ exponent_1 = f->exponent + f->leader + 1 - f->low;
+ /* Radix LITTLENUM_RADIX, point just higher than f->leader. */
+ exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
+ /* Radix 2. */
+ exponent_3 = exponent_2 - exponent_skippage;
+ /* Forget leading zeros, forget 1st bit. */
+ exponent_4 = exponent_3 + (1 << (exponent_bits - 1));
+ /* Offset exponent. */
+
+ if (exponent_4 & ~mask[exponent_bits])
+ {
+ /*
+ * Exponent overflow. Lose immediately.
+ */
+
+ make_invalid_floating_point_number (words);
+
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ else
+ {
+ lp = words;
+
+ /* Word 1. Sign, exponent and perhaps high bits. */
+ /* Assume 2's complement integers. */
+ word1 = (((exponent_4 & mask[exponent_bits]) << (15 - exponent_bits))
+ | ((f->sign == '+') ? 0 : 0x8000)
+ | next_bits (15 - exponent_bits));
+ *lp++ = word1;
+
+ /* The rest of the words are just mantissa bits. */
+ for (; lp < words + precision; lp++)
+ {
+ *lp = next_bits (LITTLENUM_NUMBER_OF_BITS);
+ }
+
+ if (next_bits (1))
+ {
+ /*
+ * Since the NEXT bit is a 1, round UP the mantissa.
+ * The cunning design of these hidden-1 floats permits
+ * us to let the mantissa overflow into the exponent, and
+ * it 'does the right thing'. However, we lose if the
+ * highest-order bit of the lowest-order word flips.
+ * Is that clear?
+ */
+
+ unsigned long carry;
+
+ /*
+ #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
+ Please allow at least 1 more bit in carry than is in a LITTLENUM.
+ We need that extra bit to hold a carry during a LITTLENUM carry
+ propagation. Another extra bit (kept 0) will assure us that we
+ don't get a sticky sign bit after shifting right, and that
+ permits us to propagate the carry without any masking of bits.
+ #endif
+ */
+ for (carry = 1, lp--;
+ carry && (lp >= words);
+ lp--)
+ {
+ carry = *lp + carry;
+ *lp = carry;
+ carry >>= LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)))
+ {
+ make_invalid_floating_point_number (words);
+ /*
+ * We leave return_value alone: admit we read the
+ * number, but return a floating exception
+ * because we can't encode the number.
+ */
+ }
+ } /* if (we needed to round up) */
+ } /* if (exponent overflow) */
+ } /* if (0.0e0) */
+ } /* if (float_type was OK) */
+ return (return_value);
+} /* flonum_gen2vax() */
+
+
+/* JF this used to be in vax.c but this looks like a better place for it */
+
+/*
+ * md_atof()
+ *
+ * In: input_line_pointer->the 1st character of a floating-point
+ * number.
+ * 1 letter denoting the type of statement that wants a
+ * binary floating point number returned.
+ * Address of where to build floating point literal.
+ * Assumed to be 'big enough'.
+ * Address of where to return size of literal (in chars).
+ *
+ * Out: Input_line_pointer->of next char after floating number.
+ * Error message, or 0.
+ * Floating point literal.
+ * Number of chars we used for the literal.
+ */
+
+#define MAXIMUM_NUMBER_OF_LITTLENUMS (8) /* For .hfloats. */
+
+char *
+md_atof (what_statement_type, literalP, sizeP)
+ int what_statement_type;
+ char *literalP;
+ int *sizeP;
+{
+ LITTLENUM_TYPE words[MAXIMUM_NUMBER_OF_LITTLENUMS];
+ register char kind_of_float;
+ register int number_of_chars;
+ register LITTLENUM_TYPE *littlenumP;
+
+ switch (what_statement_type)
+ {
+ case 'F': /* .float */
+ case 'f': /* .ffloat */
+ kind_of_float = 'f';
+ break;
+
+ case 'D': /* .double */
+ case 'd': /* .dfloat */
+ kind_of_float = 'd';
+ break;
+
+ case 'g': /* .gfloat */
+ kind_of_float = 'g';
+ break;
+
+ case 'h': /* .hfloat */
+ kind_of_float = 'h';
+ break;
+
+ default:
+ kind_of_float = 0;
+ break;
+ };
+
+ if (kind_of_float)
+ {
+ register LITTLENUM_TYPE *limit;
+
+ input_line_pointer = atof_vax (input_line_pointer,
+ kind_of_float,
+ words);
+ /*
+ * The atof_vax() builds up 16-bit numbers.
+ * Since the assembler may not be running on
+ * a little-endian machine, be very careful about
+ * converting words to chars.
+ */
+ number_of_chars = atof_vax_sizeof (kind_of_float);
+ know (number_of_chars <= MAXIMUM_NUMBER_OF_LITTLENUMS * sizeof (LITTLENUM_TYPE));
+ limit = words + (number_of_chars / sizeof (LITTLENUM_TYPE));
+ for (littlenumP = words; littlenumP < limit; littlenumP++)
+ {
+ md_number_to_chars (literalP, *littlenumP, sizeof (LITTLENUM_TYPE));
+ literalP += sizeof (LITTLENUM_TYPE);
+ };
+ }
+ else
+ {
+ number_of_chars = 0;
+ };
+
+ *sizeP = number_of_chars;
+ return kind_of_float ? 0 : _("Bad call to md_atof()");
+}
+
+/* end of atof-vax.c */
diff --git a/gas/config/e-i386coff.c b/gas/config/e-i386coff.c
new file mode 100644
index 00000000000..afed72886ac
--- /dev/null
+++ b/gas/config/e-i386coff.c
@@ -0,0 +1,17 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *
+i386coff_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386coff_bfd_name
+#define emul_format &coff_format_ops
+
+#define emul_name "i386coff"
+#define emul_struct_name i386coff
+#define emul_default_endian 0
+#include "emul-target.h"
diff --git a/gas/config/e-i386elf.c b/gas/config/e-i386elf.c
new file mode 100644
index 00000000000..a16701e811e
--- /dev/null
+++ b/gas/config/e-i386elf.c
@@ -0,0 +1,17 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *
+i386elf_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name i386elf_bfd_name
+#define emul_format &elf_format_ops
+
+#define emul_name "i386elf"
+#define emul_struct_name i386elf
+#define emul_default_endian 0
+#include "emul-target.h"
diff --git a/gas/config/e-mipsecoff.c b/gas/config/e-mipsecoff.c
new file mode 100644
index 00000000000..be2f71b7d46
--- /dev/null
+++ b/gas/config/e-mipsecoff.c
@@ -0,0 +1,37 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *mipsecoff_bfd_name PARAMS ((void));
+
+static const char *
+mipsecoff_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name mipsecoff_bfd_name
+#define emul_format &ecoff_format_ops
+
+#define emul_name "mipsbecoff"
+#define emul_struct_name mipsbecoff
+#define emul_default_endian 1
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipslecoff"
+#define emul_struct_name mipslecoff
+#define emul_default_endian 0
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipsecoff"
+#define emul_struct_name mipsecoff
+#define emul_default_endian 2
+#include "emul-target.h"
diff --git a/gas/config/e-mipself.c b/gas/config/e-mipself.c
new file mode 100644
index 00000000000..eea72f5165c
--- /dev/null
+++ b/gas/config/e-mipself.c
@@ -0,0 +1,37 @@
+#include "as.h"
+#include "emul.h"
+
+static const char *mipself_bfd_name PARAMS ((void));
+
+static const char *
+mipself_bfd_name ()
+{
+ abort ();
+ return NULL;
+}
+
+#define emul_bfd_name mipself_bfd_name
+#define emul_format &elf_format_ops
+
+#define emul_name "mipsbelf"
+#define emul_struct_name mipsbelf
+#define emul_default_endian 1
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipslelf"
+#define emul_struct_name mipslelf
+#define emul_default_endian 0
+#include "emul-target.h"
+
+#undef emul_name
+#undef emul_struct_name
+#undef emul_default_endian
+
+#define emul_name "mipself"
+#define emul_struct_name mipself
+#define emul_default_endian 2
+#include "emul-target.h"
diff --git a/gas/config/go32.cfg b/gas/config/go32.cfg
new file mode 100644
index 00000000000..4059395da8e
--- /dev/null
+++ b/gas/config/go32.cfg
@@ -0,0 +1,93 @@
+/* config.h for go32 */
+
+#define I386COFF 1
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Should gas use high-level BFD interfaces? */
+#undef BFD_ASSEMBLER
+
+/* If we aren't doing cross-assembling, some operations can be optimized,
+ since byte orders and value sizes don't need to be adjusted. */
+#undef CROSS_COMPILE
+
+/* Some gas code wants to know these parameters. */
+#define TARGET_ALIAS "i386"
+#define TARGET_CPU "i386"
+#define TARGET_CANONICAL "i386-i386"
+#define TARGET_OS "djgpp"
+#define TARGET_VENDOR "djgpp"
+
+/* Some operating systems, for example DOS, require the use of "wb" mode when
+ opening a binary file for writing. If only "w" is used, the file will not
+ be correct. However, some other systems reject such a mode. This indicates
+ which ../include/fopen-*.h header file we want to include, so that we can
+ get macros that'll do the right thing for this system. */
+#define WANT_FOPEN_BIN 1
+
+/* Sometimes the system header files don't declare malloc and realloc. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Sometimes the system header files don't declare free. */
+#undef NEED_DECLARATION_FREE
+
+/* Sometimes errno.h doesn't declare errno itself. */
+#undef NEED_DECLARATION_ERRNO
+
+#define MANY_SEGMENTS 1
+
+/* Needed only for sparc configuration */
+#undef sparcv9
+
+/* Define if you have the remove function. */
+#define HAVE_REMOVE 1
+
+/* Define if you have the unlink function. */
+#define HAVE_UNLINK 1
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
diff --git a/gas/config/itbl-mips.h b/gas/config/itbl-mips.h
new file mode 100644
index 00000000000..f6482bd1f75
--- /dev/null
+++ b/gas/config/itbl-mips.h
@@ -0,0 +1,47 @@
+
+/* itbl-mips.h
+
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Defines for Mips itbl cop support */
+
+#include "opcode/mips.h"
+
+/* Values for processors will be from 0 to NUMBER_OF_PROCESSORS-1 */
+#define NUMBER_OF_PROCESSORS 4
+#define MAX_BITPOS 31
+
+/* Mips specifics */
+#define MIPS_OPCODE_COP0 (0x21) /* COPz+CO, bits 31-25: 0100zz1 */
+#define MIPS_ENCODE_COP_NUM(z) ((MIPS_OPCODE_COP0|z<<1)<<25)
+#define MIPS_IS_COP_INSN(insn) ((MIPS_OPCODE_COP0&(insn>>25)) \
+ == MIPS_OPCODE_COP0)
+#define MIPS_DECODE_COP_NUM(insn) ((~MIPS_OPCODE_COP0&(insn>>25))>>1)
+#define MIPS_DECODE_COP_COFUN(insn) ((~MIPS_ENCODE_COP_NUM(3))&(insn))
+
+/* definitions required by generic code */
+#define ITBL_IS_INSN(insn) MIPS_IS_COP_INSN(insn)
+#define ITBL_DECODE_PNUM(insn) MIPS_DECODE_COP_NUM(insn)
+#define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
+
+#define ITBL_OPCODE_STRUCT mips_opcode
+#define ITBL_OPCODES mips_opcodes
+#define ITBL_NUM_OPCODES NUMOPCODES
+#define ITBL_NUM_MACROS M_NUM_MACROS
diff --git a/gas/config/m68k-parse.h b/gas/config/m68k-parse.h
new file mode 100644
index 00000000000..e13134212e4
--- /dev/null
+++ b/gas/config/m68k-parse.h
@@ -0,0 +1,283 @@
+/* m68k-parse.h -- header file for m68k assembler
+ Copyright (C) 1987, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef M68K_PARSE_H
+#define M68K_PARSE_H
+
+/* This header file defines things which are shared between the
+ operand parser in m68k.y and the m68k assembler proper in
+ tc-m68k.c. */
+
+/* The various m68k registers. */
+
+/* DATA and ADDR have to be contiguous, so that reg-DATA gives
+ 0-7==data reg, 8-15==addr reg for operands that take both types.
+
+ We don't use forms like "ADDR0 = ADDR" here because this file is
+ likely to be used on an Apollo, and the broken Apollo compiler
+ gives an `undefined variable' error if we do that, according to
+ troy@cbme.unsw.edu.au. */
+
+#define DATA DATA0
+#define ADDR ADDR0
+#define SP ADDR7
+#define BAD BAD0
+#define BAC BAC0
+
+enum m68k_register
+{
+ DATA0 = 1, /* 1- 8 == data registers 0-7 */
+ DATA1,
+ DATA2,
+ DATA3,
+ DATA4,
+ DATA5,
+ DATA6,
+ DATA7,
+
+ ADDR0,
+ ADDR1,
+ ADDR2,
+ ADDR3,
+ ADDR4,
+ ADDR5,
+ ADDR6,
+ ADDR7,
+
+ FP0, /* Eight FP registers */
+ FP1,
+ FP2,
+ FP3,
+ FP4,
+ FP5,
+ FP6,
+ FP7,
+
+ COP0, /* Co-processor #0-#7 */
+ COP1,
+ COP2,
+ COP3,
+ COP4,
+ COP5,
+ COP6,
+ COP7,
+
+ PC, /* Program counter */
+ ZPC, /* Hack for Program space, but 0 addressing */
+ SR, /* Status Reg */
+ CCR, /* Condition code Reg */
+
+ /* These have to be grouped together for the movec instruction to work. */
+ USP, /* User Stack Pointer */
+ ISP, /* Interrupt stack pointer */
+ SFC,
+ DFC,
+ CACR,
+ VBR,
+ CAAR,
+ MSP,
+ ITT0,
+ ITT1,
+ DTT0,
+ DTT1,
+ MMUSR,
+ TC,
+ SRP,
+ URP,
+ BUSCR, /* 68060 added these */
+ PCR,
+ ROMBAR, /* mcf5200 added these */
+ RAMBAR0,
+ RAMBAR1,
+ MBAR,
+#define last_movec_reg MBAR
+ /* end of movec ordering constraints */
+
+ FPI,
+ FPS,
+ FPC,
+
+ DRP, /* 68851 or 68030 MMU regs */
+ CRP,
+ CAL,
+ VAL,
+ SCC,
+ AC,
+ BAD0,
+ BAD1,
+ BAD2,
+ BAD3,
+ BAD4,
+ BAD5,
+ BAD6,
+ BAD7,
+ BAC0,
+ BAC1,
+ BAC2,
+ BAC3,
+ BAC4,
+ BAC5,
+ BAC6,
+ BAC7,
+ PSR, /* aka MMUSR on 68030 (but not MMUSR on 68040)
+ and ACUSR on 68ec030 */
+ PCSR,
+
+ IC, /* instruction cache token */
+ DC, /* data cache token */
+ NC, /* no cache token */
+ BC, /* both caches token */
+
+ TT0, /* 68030 access control unit regs */
+ TT1,
+
+ ZDATA0, /* suppressed data registers. */
+ ZDATA1,
+ ZDATA2,
+ ZDATA3,
+ ZDATA4,
+ ZDATA5,
+ ZDATA6,
+ ZDATA7,
+
+ ZADDR0, /* suppressed address registers. */
+ ZADDR1,
+ ZADDR2,
+ ZADDR3,
+ ZADDR4,
+ ZADDR5,
+ ZADDR6,
+ ZADDR7,
+};
+
+/* Size information. */
+
+enum m68k_size
+{
+ /* Unspecified. */
+ SIZE_UNSPEC,
+
+ /* Byte. */
+ SIZE_BYTE,
+
+ /* Word (2 bytes). */
+ SIZE_WORD,
+
+ /* Longword (4 bytes). */
+ SIZE_LONG
+};
+
+/* The structure used to hold information about an index register. */
+
+struct m68k_indexreg
+{
+ /* The index register itself. */
+ enum m68k_register reg;
+
+ /* The size to use. */
+ enum m68k_size size;
+
+ /* The value to scale by. */
+ int scale;
+};
+
+#ifdef OBJ_ELF
+/* The type of a PIC expression. */
+
+enum pic_relocation
+{
+ pic_none, /* not pic */
+ pic_plt_pcrel, /* @PLTPC */
+ pic_got_pcrel, /* @GOTPC */
+ pic_plt_off, /* @PLT */
+ pic_got_off /* @GOT */
+};
+#endif
+
+/* The structure used to hold information about an expression. */
+
+struct m68k_exp
+{
+ /* The size to use. */
+ enum m68k_size size;
+
+#ifdef OBJ_ELF
+ /* The type of pic relocation if any. */
+ enum pic_relocation pic_reloc;
+#endif
+
+ /* The expression itself. */
+ expressionS exp;
+};
+
+/* The operand modes. */
+
+enum m68k_operand_type
+{
+ IMMED = 1,
+ ABSL,
+ DREG,
+ AREG,
+ FPREG,
+ CONTROL,
+ AINDR,
+ AINC,
+ ADEC,
+ DISP,
+ BASE,
+ POST,
+ PRE,
+ REGLST
+};
+
+/* The structure used to hold a parsed operand. */
+
+struct m68k_op
+{
+ /* The type of operand. */
+ enum m68k_operand_type mode;
+
+ /* The main register. */
+ enum m68k_register reg;
+
+ /* The register mask for mode REGLST. */
+ unsigned long mask;
+
+ /* An error message. */
+ const char *error;
+
+ /* The index register. */
+ struct m68k_indexreg index;
+
+ /* The displacement. */
+ struct m68k_exp disp;
+
+ /* The outer displacement. */
+ struct m68k_exp odisp;
+};
+
+#endif /* ! defined (M68K_PARSE_H) */
+
+/* The parsing function. */
+
+extern int m68k_ip_op PARAMS ((char *, struct m68k_op *));
+
+/* Whether register prefixes are optional. */
+extern int flag_reg_prefix_optional;
diff --git a/gas/config/m68k-parse.y b/gas/config/m68k-parse.y
new file mode 100644
index 00000000000..70a4e4fe86e
--- /dev/null
+++ b/gas/config/m68k-parse.y
@@ -0,0 +1,1061 @@
+/* m68k.y -- bison grammar for m68k operand parsing
+ Copyright (C) 1995, 96, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This file holds a bison grammar to parse m68k operands. The m68k
+ has a complicated operand syntax, and gas supports two main
+ variations of it. Using a grammar is probably overkill, but at
+ least it makes clear exactly what we do support. */
+
+%{
+
+#include "as.h"
+#include "tc-m68k.h"
+#include "m68k-parse.h"
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
+ etc), as well as gratuitiously global symbol names If other parser
+ generators (bison, byacc, etc) produce additional global names that
+ conflict at link time, then those parser generators need to be
+ fixed instead of adding those names to this list. */
+
+#define yymaxdepth m68k_maxdepth
+#define yyparse m68k_parse
+#define yylex m68k_lex
+#define yyerror m68k_error
+#define yylval m68k_lval
+#define yychar m68k_char
+#define yydebug m68k_debug
+#define yypact m68k_pact
+#define yyr1 m68k_r1
+#define yyr2 m68k_r2
+#define yydef m68k_def
+#define yychk m68k_chk
+#define yypgo m68k_pgo
+#define yyact m68k_act
+#define yyexca m68k_exca
+#define yyerrflag m68k_errflag
+#define yynerrs m68k_nerrs
+#define yyps m68k_ps
+#define yypv m68k_pv
+#define yys m68k_s
+#define yy_yys m68k_yys
+#define yystate m68k_state
+#define yytmp m68k_tmp
+#define yyv m68k_v
+#define yy_yyv m68k_yyv
+#define yyval m68k_val
+#define yylloc m68k_lloc
+#define yyreds m68k_reds /* With YYDEBUG defined */
+#define yytoks m68k_toks /* With YYDEBUG defined */
+#define yylhs m68k_yylhs
+#define yylen m68k_yylen
+#define yydefred m68k_yydefred
+#define yydgoto m68k_yydgoto
+#define yysindex m68k_yysindex
+#define yyrindex m68k_yyrindex
+#define yygindex m68k_yygindex
+#define yytable m68k_yytable
+#define yycheck m68k_yycheck
+
+#ifndef YYDEBUG
+#define YYDEBUG 1
+#endif
+
+/* Internal functions. */
+
+static enum m68k_register m68k_reg_parse PARAMS ((char **));
+static int yylex PARAMS ((void));
+static void yyerror PARAMS ((const char *));
+
+/* The parser sets fields pointed to by this global variable. */
+static struct m68k_op *op;
+
+%}
+
+%union
+{
+ struct m68k_indexreg indexreg;
+ enum m68k_register reg;
+ struct m68k_exp exp;
+ unsigned long mask;
+ int onereg;
+}
+
+%token <reg> DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
+%token <indexreg> INDEXREG
+%token <exp> EXPR
+
+%type <indexreg> zireg zdireg
+%type <reg> zadr zdr apc zapc zpc optzapc optczapc
+%type <exp> optcexpr optexprc
+%type <mask> reglist ireglist reglistpair
+%type <onereg> reglistreg
+
+%%
+
+/* An operand. */
+
+operand:
+ generic_operand
+ | motorola_operand
+ | mit_operand
+ ;
+
+/* A generic operand. */
+
+generic_operand:
+ DR
+ {
+ op->mode = DREG;
+ op->reg = $1;
+ }
+ | AR
+ {
+ op->mode = AREG;
+ op->reg = $1;
+ }
+ | FPR
+ {
+ op->mode = FPREG;
+ op->reg = $1;
+ }
+ | FPCR
+ {
+ op->mode = CONTROL;
+ op->reg = $1;
+ }
+ | CREG
+ {
+ op->mode = CONTROL;
+ op->reg = $1;
+ }
+ | EXPR
+ {
+ op->mode = ABSL;
+ op->disp = $1;
+ }
+ | '#' EXPR
+ {
+ op->mode = IMMED;
+ op->disp = $2;
+ }
+ | '&' EXPR
+ {
+ op->mode = IMMED;
+ op->disp = $2;
+ }
+ | reglist
+ {
+ op->mode = REGLST;
+ op->mask = $1;
+ }
+ ;
+
+/* An operand in Motorola syntax. This includes MRI syntax as well,
+ which may or may not be different in that it permits commutativity
+ of index and base registers, and permits an offset expression to
+ appear inside or outside of the parentheses. */
+
+motorola_operand:
+ '(' AR ')'
+ {
+ op->mode = AINDR;
+ op->reg = $2;
+ }
+ | '(' AR ')' '+'
+ {
+ op->mode = AINC;
+ op->reg = $2;
+ }
+ | '-' '(' AR ')'
+ {
+ op->mode = ADEC;
+ op->reg = $3;
+ }
+ | '(' EXPR ',' zapc ')'
+ {
+ op->reg = $4;
+ op->disp = $2;
+ if (($4 >= ZADDR0 && $4 <= ZADDR7)
+ || $4 == ZPC)
+ op->mode = BASE;
+ else
+ op->mode = DISP;
+ }
+ | '(' zapc ',' EXPR ')'
+ {
+ op->reg = $2;
+ op->disp = $4;
+ if (($2 >= ZADDR0 && $2 <= ZADDR7)
+ || $2 == ZPC)
+ op->mode = BASE;
+ else
+ op->mode = DISP;
+ }
+ | EXPR '(' zapc ')'
+ {
+ op->reg = $3;
+ op->disp = $1;
+ if (($3 >= ZADDR0 && $3 <= ZADDR7)
+ || $3 == ZPC)
+ op->mode = BASE;
+ else
+ op->mode = DISP;
+ }
+ | '(' LPC ')'
+ {
+ op->mode = DISP;
+ op->reg = $2;
+ }
+ | '(' ZAR ')'
+ {
+ op->mode = BASE;
+ op->reg = $2;
+ }
+ | '(' LZPC ')'
+ {
+ op->mode = BASE;
+ op->reg = $2;
+ }
+ | '(' EXPR ',' zapc ',' zireg ')'
+ {
+ op->mode = BASE;
+ op->reg = $4;
+ op->disp = $2;
+ op->index = $6;
+ }
+ | '(' EXPR ',' zapc ',' zpc ')'
+ {
+ if ($4 == PC || $4 == ZPC)
+ yyerror (_("syntax error"));
+ op->mode = BASE;
+ op->reg = $6;
+ op->disp = $2;
+ op->index.reg = $4;
+ op->index.size = SIZE_UNSPEC;
+ op->index.scale = 1;
+ }
+ | '(' EXPR ',' zdireg optczapc ')'
+ {
+ op->mode = BASE;
+ op->reg = $5;
+ op->disp = $2;
+ op->index = $4;
+ }
+ | '(' zdireg ',' EXPR ')'
+ {
+ op->mode = BASE;
+ op->disp = $4;
+ op->index = $2;
+ }
+ | EXPR '(' zapc ',' zireg ')'
+ {
+ op->mode = BASE;
+ op->reg = $3;
+ op->disp = $1;
+ op->index = $5;
+ }
+ | '(' zapc ',' zireg ')'
+ {
+ op->mode = BASE;
+ op->reg = $2;
+ op->index = $4;
+ }
+ | EXPR '(' zapc ',' zpc ')'
+ {
+ if ($3 == PC || $3 == ZPC)
+ yyerror (_("syntax error"));
+ op->mode = BASE;
+ op->reg = $5;
+ op->disp = $1;
+ op->index.reg = $3;
+ op->index.size = SIZE_UNSPEC;
+ op->index.scale = 1;
+ }
+ | '(' zapc ',' zpc ')'
+ {
+ if ($2 == PC || $2 == ZPC)
+ yyerror (_("syntax error"));
+ op->mode = BASE;
+ op->reg = $4;
+ op->index.reg = $2;
+ op->index.size = SIZE_UNSPEC;
+ op->index.scale = 1;
+ }
+ | EXPR '(' zdireg optczapc ')'
+ {
+ op->mode = BASE;
+ op->reg = $4;
+ op->disp = $1;
+ op->index = $3;
+ }
+ | '(' zdireg optczapc ')'
+ {
+ op->mode = BASE;
+ op->reg = $3;
+ op->index = $2;
+ }
+ | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
+ {
+ op->mode = POST;
+ op->reg = $4;
+ op->disp = $3;
+ op->index = $7;
+ op->odisp = $8;
+ }
+ | '(' '[' EXPR optczapc ']' optcexpr ')'
+ {
+ op->mode = POST;
+ op->reg = $4;
+ op->disp = $3;
+ op->odisp = $6;
+ }
+ | '(' '[' zapc ']' ',' zireg optcexpr ')'
+ {
+ op->mode = POST;
+ op->reg = $3;
+ op->index = $6;
+ op->odisp = $7;
+ }
+ | '(' '[' zapc ']' optcexpr ')'
+ {
+ op->mode = POST;
+ op->reg = $3;
+ op->odisp = $5;
+ }
+ | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
+ {
+ op->mode = PRE;
+ op->reg = $5;
+ op->disp = $3;
+ op->index = $7;
+ op->odisp = $9;
+ }
+ | '(' '[' zapc ',' zireg ']' optcexpr ')'
+ {
+ op->mode = PRE;
+ op->reg = $3;
+ op->index = $5;
+ op->odisp = $7;
+ }
+ | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
+ {
+ if ($5 == PC || $5 == ZPC)
+ yyerror (_("syntax error"));
+ op->mode = PRE;
+ op->reg = $7;
+ op->disp = $3;
+ op->index.reg = $5;
+ op->index.size = SIZE_UNSPEC;
+ op->index.scale = 1;
+ op->odisp = $9;
+ }
+ | '(' '[' zapc ',' zpc ']' optcexpr ')'
+ {
+ if ($3 == PC || $3 == ZPC)
+ yyerror (_("syntax error"));
+ op->mode = PRE;
+ op->reg = $5;
+ op->index.reg = $3;
+ op->index.size = SIZE_UNSPEC;
+ op->index.scale = 1;
+ op->odisp = $7;
+ }
+ | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
+ {
+ op->mode = PRE;
+ op->reg = $5;
+ op->disp = $3;
+ op->index = $4;
+ op->odisp = $7;
+ }
+ ;
+
+/* An operand in MIT syntax. */
+
+mit_operand:
+ optzapc '@'
+ {
+ /* We use optzapc to avoid a shift/reduce conflict. */
+ if ($1 < ADDR0 || $1 > ADDR7)
+ yyerror (_("syntax error"));
+ op->mode = AINDR;
+ op->reg = $1;
+ }
+ | optzapc '@' '+'
+ {
+ /* We use optzapc to avoid a shift/reduce conflict. */
+ if ($1 < ADDR0 || $1 > ADDR7)
+ yyerror (_("syntax error"));
+ op->mode = AINC;
+ op->reg = $1;
+ }
+ | optzapc '@' '-'
+ {
+ /* We use optzapc to avoid a shift/reduce conflict. */
+ if ($1 < ADDR0 || $1 > ADDR7)
+ yyerror (_("syntax error"));
+ op->mode = ADEC;
+ op->reg = $1;
+ }
+ | optzapc '@' '(' EXPR ')'
+ {
+ op->reg = $1;
+ op->disp = $4;
+ if (($1 >= ZADDR0 && $1 <= ZADDR7)
+ || $1 == ZPC)
+ op->mode = BASE;
+ else
+ op->mode = DISP;
+ }
+ | optzapc '@' '(' optexprc zireg ')'
+ {
+ op->mode = BASE;
+ op->reg = $1;
+ op->disp = $4;
+ op->index = $5;
+ }
+ | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
+ {
+ op->mode = POST;
+ op->reg = $1;
+ op->disp = $4;
+ op->index = $9;
+ op->odisp = $8;
+ }
+ | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
+ {
+ op->mode = POST;
+ op->reg = $1;
+ op->disp = $4;
+ op->odisp = $8;
+ }
+ | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
+ {
+ op->mode = PRE;
+ op->reg = $1;
+ op->disp = $4;
+ op->index = $5;
+ op->odisp = $9;
+ }
+ ;
+
+/* An index register, possibly suppressed, which need not have a size
+ or scale. */
+
+zireg:
+ INDEXREG
+ | zadr
+ {
+ $$.reg = $1;
+ $$.size = SIZE_UNSPEC;
+ $$.scale = 1;
+ }
+ ;
+
+/* A register which may be an index register, but which may not be an
+ address register. This nonterminal is used to avoid ambiguity when
+ trying to parse something like (0,d5,a6) as compared to (0,a6,d5). */
+
+zdireg:
+ INDEXREG
+ | zdr
+ {
+ $$.reg = $1;
+ $$.size = SIZE_UNSPEC;
+ $$.scale = 1;
+ }
+ ;
+
+/* An address or data register, or a suppressed address or data
+ register. */
+
+zadr:
+ zdr
+ | AR
+ | ZAR
+ ;
+
+/* A data register which may be suppressed. */
+
+zdr:
+ DR
+ | ZDR
+ ;
+
+/* Either an address register or the PC. */
+
+apc:
+ AR
+ | LPC
+ ;
+
+/* Either an address register, or the PC, or a suppressed address
+ register, or a suppressed PC. */
+
+zapc:
+ apc
+ | LZPC
+ | ZAR
+ ;
+
+/* An optional zapc. */
+
+optzapc:
+ /* empty */
+ {
+ $$ = ZADDR0;
+ }
+ | zapc
+ ;
+
+/* The PC, optionally suppressed. */
+
+zpc:
+ LPC
+ | LZPC
+ ;
+
+/* ',' zapc when it may be omitted. */
+
+optczapc:
+ /* empty */
+ {
+ $$ = ZADDR0;
+ }
+ | ',' zapc
+ {
+ $$ = $2;
+ }
+ ;
+
+/* ',' EXPR when it may be omitted. */
+
+optcexpr:
+ /* empty */
+ {
+ $$.exp.X_op = O_absent;
+ $$.size = SIZE_UNSPEC;
+ }
+ | ',' EXPR
+ {
+ $$ = $2;
+ }
+ ;
+
+/* EXPR ',' when it may be omitted. */
+
+optexprc:
+ /* empty */
+ {
+ $$.exp.X_op = O_absent;
+ $$.size = SIZE_UNSPEC;
+ }
+ | EXPR ','
+ {
+ $$ = $1;
+ }
+ ;
+
+/* A register list for the movem instruction. */
+
+reglist:
+ reglistpair
+ | reglistpair '/' ireglist
+ {
+ $$ = $1 | $3;
+ }
+ | reglistreg '/' ireglist
+ {
+ $$ = (1 << $1) | $3;
+ }
+ ;
+
+/* We use ireglist when we know we are looking at a reglist, and we
+ can safely reduce a simple register to reglistreg. If we permitted
+ reglist to reduce to reglistreg, it would be ambiguous whether a
+ plain register were a DREG/AREG/FPREG or a REGLST. */
+
+ireglist:
+ reglistreg
+ {
+ $$ = 1 << $1;
+ }
+ | reglistpair
+ | reglistpair '/' ireglist
+ {
+ $$ = $1 | $3;
+ }
+ | reglistreg '/' ireglist
+ {
+ $$ = (1 << $1) | $3;
+ }
+ ;
+
+reglistpair:
+ reglistreg '-' reglistreg
+ {
+ if ($1 <= $3)
+ $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
+ else
+ $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
+ }
+ ;
+
+reglistreg:
+ DR
+ {
+ $$ = $1 - DATA0;
+ }
+ | AR
+ {
+ $$ = $1 - ADDR0 + 8;
+ }
+ | FPR
+ {
+ $$ = $1 - FP0 + 16;
+ }
+ | FPCR
+ {
+ if ($1 == FPI)
+ $$ = 24;
+ else if ($1 == FPS)
+ $$ = 25;
+ else
+ $$ = 26;
+ }
+ ;
+
+%%
+
+/* The string to parse is stored here, and modified by yylex. */
+
+static char *str;
+
+/* The original string pointer. */
+
+static char *strorig;
+
+/* If *CCP could be a register, return the register number and advance
+ *CCP. Otherwise don't change *CCP, and return 0. */
+
+static enum m68k_register
+m68k_reg_parse (ccp)
+ register char **ccp;
+{
+ char *start = *ccp;
+ char c;
+ char *p;
+ symbolS *symbolp;
+
+ if (flag_reg_prefix_optional)
+ {
+ if (*start == REGISTER_PREFIX)
+ start++;
+ p = start;
+ }
+ else
+ {
+ if (*start != REGISTER_PREFIX)
+ return 0;
+ p = start + 1;
+ }
+
+ if (! is_name_beginner (*p))
+ return 0;
+
+ p++;
+ while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
+ p++;
+
+ c = *p;
+ *p = 0;
+ symbolp = symbol_find (start);
+ *p = c;
+
+ if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
+ {
+ *ccp = p;
+ return S_GET_VALUE (symbolp);
+ }
+
+ /* In MRI mode, something like foo.bar can be equated to a register
+ name. */
+ while (flag_mri && c == '.')
+ {
+ ++p;
+ while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
+ p++;
+ c = *p;
+ *p = '\0';
+ symbolp = symbol_find (start);
+ *p = c;
+ if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
+ {
+ *ccp = p;
+ return S_GET_VALUE (symbolp);
+ }
+ }
+
+ return 0;
+}
+
+/* The lexer. */
+
+static int
+yylex ()
+{
+ enum m68k_register reg;
+ char *s;
+ int parens;
+ int c = 0;
+ int tail = 0;
+ char *hold;
+
+ if (*str == ' ')
+ ++str;
+
+ if (*str == '\0')
+ return 0;
+
+ /* Various special characters are just returned directly. */
+ switch (*str)
+ {
+ case '@':
+ /* In MRI mode, this can be the start of an octal number. */
+ if (flag_mri)
+ {
+ if (isdigit (str[1])
+ || ((str[1] == '+' || str[1] == '-')
+ && isdigit (str[2])))
+ break;
+ }
+ /* Fall through. */
+ case '#':
+ case '&':
+ case ',':
+ case ')':
+ case '/':
+ case '[':
+ case ']':
+ return *str++;
+ case '+':
+ /* It so happens that a '+' can only appear at the end of an
+ operand. If it appears anywhere else, it must be a unary
+ plus on an expression. */
+ if (str[1] == '\0')
+ return *str++;
+ break;
+ case '-':
+ /* A '-' can only appear in -(ar), rn-rn, or ar@-. If it
+ appears anywhere else, it must be a unary minus on an
+ expression. */
+ if (str[1] == '\0')
+ return *str++;
+ s = str + 1;
+ if (*s == '(')
+ ++s;
+ if (m68k_reg_parse (&s) != 0)
+ return *str++;
+ break;
+ case '(':
+ /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
+ `)('. If it appears anywhere else, it must be starting an
+ expression. */
+ if (str[1] == '['
+ || (str > strorig
+ && (str[-1] == '@'
+ || str[-1] == ')')))
+ return *str++;
+ s = str + 1;
+ if (m68k_reg_parse (&s) != 0)
+ return *str++;
+ /* Check for the case of '(expr,...' by scanning ahead. If we
+ find a comma outside of balanced parentheses, we return '('.
+ If we find an unbalanced right parenthesis, then presumably
+ the '(' really starts an expression. */
+ parens = 0;
+ for (s = str + 1; *s != '\0'; s++)
+ {
+ if (*s == '(')
+ ++parens;
+ else if (*s == ')')
+ {
+ if (parens == 0)
+ break;
+ --parens;
+ }
+ else if (*s == ',' && parens == 0)
+ {
+ /* A comma can not normally appear in an expression, so
+ this is a case of '(expr,...'. */
+ return *str++;
+ }
+ }
+ }
+
+ /* See if it's a register. */
+
+ reg = m68k_reg_parse (&str);
+ if (reg != 0)
+ {
+ int ret;
+
+ yylval.reg = reg;
+
+ if (reg >= DATA0 && reg <= DATA7)
+ ret = DR;
+ else if (reg >= ADDR0 && reg <= ADDR7)
+ ret = AR;
+ else if (reg >= FP0 && reg <= FP7)
+ return FPR;
+ else if (reg == FPI
+ || reg == FPS
+ || reg == FPC)
+ return FPCR;
+ else if (reg == PC)
+ return LPC;
+ else if (reg >= ZDATA0 && reg <= ZDATA7)
+ ret = ZDR;
+ else if (reg >= ZADDR0 && reg <= ZADDR7)
+ ret = ZAR;
+ else if (reg == ZPC)
+ return LZPC;
+ else
+ return CREG;
+
+ /* If we get here, we have a data or address register. We
+ must check for a size or scale; if we find one, we must
+ return INDEXREG. */
+
+ s = str;
+
+ if (*s != '.' && *s != ':' && *s != '*')
+ return ret;
+
+ yylval.indexreg.reg = reg;
+
+ if (*s != '.' && *s != ':')
+ yylval.indexreg.size = SIZE_UNSPEC;
+ else
+ {
+ ++s;
+ switch (*s)
+ {
+ case 'w':
+ case 'W':
+ yylval.indexreg.size = SIZE_WORD;
+ ++s;
+ break;
+ case 'l':
+ case 'L':
+ yylval.indexreg.size = SIZE_LONG;
+ ++s;
+ break;
+ default:
+ yyerror (_("illegal size specification"));
+ yylval.indexreg.size = SIZE_UNSPEC;
+ break;
+ }
+ }
+
+ yylval.indexreg.scale = 1;
+
+ if (*s == '*' || *s == ':')
+ {
+ expressionS scale;
+
+ ++s;
+
+ hold = input_line_pointer;
+ input_line_pointer = s;
+ expression (&scale);
+ s = input_line_pointer;
+ input_line_pointer = hold;
+
+ if (scale.X_op != O_constant)
+ yyerror (_("scale specification must resolve to a number"));
+ else
+ {
+ switch (scale.X_add_number)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ yylval.indexreg.scale = scale.X_add_number;
+ break;
+ default:
+ yyerror (_("invalid scale value"));
+ break;
+ }
+ }
+ }
+
+ str = s;
+
+ return INDEXREG;
+ }
+
+ /* It must be an expression. Before we call expression, we need to
+ look ahead to see if there is a size specification. We must do
+ that first, because otherwise foo.l will be treated as the symbol
+ foo.l, rather than as the symbol foo with a long size
+ specification. The grammar requires that all expressions end at
+ the end of the operand, or with ',', '(', ']', ')'. */
+
+ parens = 0;
+ for (s = str; *s != '\0'; s++)
+ {
+ if (*s == '(')
+ {
+ if (parens == 0
+ && s > str
+ && (s[-1] == ')' || isalnum ((unsigned char) s[-1])))
+ break;
+ ++parens;
+ }
+ else if (*s == ')')
+ {
+ if (parens == 0)
+ break;
+ --parens;
+ }
+ else if (parens == 0
+ && (*s == ',' || *s == ']'))
+ break;
+ }
+
+ yylval.exp.size = SIZE_UNSPEC;
+ if (s <= str + 2
+ || (s[-2] != '.' && s[-2] != ':'))
+ tail = 0;
+ else
+ {
+ switch (s[-1])
+ {
+ case 's':
+ case 'S':
+ case 'b':
+ case 'B':
+ yylval.exp.size = SIZE_BYTE;
+ break;
+ case 'w':
+ case 'W':
+ yylval.exp.size = SIZE_WORD;
+ break;
+ case 'l':
+ case 'L':
+ yylval.exp.size = SIZE_LONG;
+ break;
+ default:
+ break;
+ }
+ if (yylval.exp.size != SIZE_UNSPEC)
+ tail = 2;
+ }
+
+#ifdef OBJ_ELF
+ {
+ /* Look for @PLTPC, etc. */
+ char *cp;
+
+ yylval.exp.pic_reloc = pic_none;
+ cp = s - tail;
+ if (cp - 6 > str && cp[-6] == '@')
+ {
+ if (strncmp (cp - 6, "@PLTPC", 6) == 0)
+ {
+ yylval.exp.pic_reloc = pic_plt_pcrel;
+ tail += 6;
+ }
+ else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
+ {
+ yylval.exp.pic_reloc = pic_got_pcrel;
+ tail += 6;
+ }
+ }
+ else if (cp - 4 > str && cp[-4] == '@')
+ {
+ if (strncmp (cp - 4, "@PLT", 4) == 0)
+ {
+ yylval.exp.pic_reloc = pic_plt_off;
+ tail += 4;
+ }
+ else if (strncmp (cp - 4, "@GOT", 4) == 0)
+ {
+ yylval.exp.pic_reloc = pic_got_off;
+ tail += 4;
+ }
+ }
+ }
+#endif
+
+ if (tail != 0)
+ {
+ c = s[-tail];
+ s[-tail] = 0;
+ }
+
+ hold = input_line_pointer;
+ input_line_pointer = str;
+ expression (&yylval.exp.exp);
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ if (tail != 0)
+ {
+ s[-tail] = c;
+ str = s;
+ }
+
+ return EXPR;
+}
+
+/* Parse an m68k operand. This is the only function which is called
+ from outside this file. */
+
+int
+m68k_ip_op (s, oparg)
+ char *s;
+ struct m68k_op *oparg;
+{
+ memset (oparg, 0, sizeof *oparg);
+ oparg->error = NULL;
+ oparg->index.reg = ZDATA0;
+ oparg->index.scale = 1;
+ oparg->disp.exp.X_op = O_absent;
+ oparg->odisp.exp.X_op = O_absent;
+
+ str = strorig = s;
+ op = oparg;
+
+ return yyparse ();
+}
+
+/* The error handler. */
+
+static void
+yyerror (s)
+ const char *s;
+{
+ op->error = s;
+}
diff --git a/gas/config/m88k-opcode.h b/gas/config/m88k-opcode.h
new file mode 100644
index 00000000000..27464bc0fc9
--- /dev/null
+++ b/gas/config/m88k-opcode.h
@@ -0,0 +1,559 @@
+/* m88k-opcode.h -- Instruction information for the Motorola 88000
+ Contributed by Devon Bowen of Buffalo University
+ and Torbjorn Granlund of the Swedish Institute of Computer Science.
+ Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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 1, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+
+/*
+ Character codes for op_spec field below.
+ Reserved for self-matching: [ ] ,
+
+ d = GRF Destination register (21:5)
+ x = XRF register prefix. Makes next d, 1, or 2, match an extended register.
+ 1 = Source register 1 (16:5)
+ 2 = Source register 2 (0:5)
+ 3 = Both source registers (same value) (0:5 and 16:5)
+ I = IMM16 (0:16)
+ b = bit field spec. (0:10)
+ p = 16 bit pc displ. (0:16)
+ P = 26 bit pc displ. (0:26)
+ B = bb0/bb1 condition (21:5)
+ M = bcnd condition (21:5)
+ f = fcr (5:6)
+ c = cr (5:6)
+ V = VEC9 (0:9)
+ o = O6 field of "prot" insn (10:7)
+ ? = Give warning for this insn/operand combination
+ */
+
+/* instruction descriptor structure */
+
+struct m88k_opcode
+{
+ unsigned int opcode;
+ char *name;
+ char *op_spec;
+};
+
+/* and introducing... the Motorola 88100 and 88110 instruction sets... */
+
+/* By default, include the 88110 instructions. */
+#define MC88110
+
+#if defined (MC88110)
+#define _MC88100(OPCODE,MNEM,OP_SPEC)
+#define _MC88110(OPCODE,MNEM,OP_SPEC) {OPCODE,MNEM,OP_SPEC},
+#else
+#define _MC88100(OPCODE,MNEM,OP_SPEC) {OPCODE,MNEM,OP_SPEC},
+#define _MC88110(OPCODE,MNEM,OP_SPEC)
+#endif
+
+#define _MC88xxx(OPCODE,MNEM,OP_SPEC) {OPCODE,MNEM,OP_SPEC},
+
+/* Equal mnemonics must be adjacent.
+ More specific operand specification must go before more general.
+ For example, "d,1,2" must go before "d,1,I" as a register for s2
+ would otherwise be considered a variable name. */
+
+static struct m88k_opcode m88k_opcodes[] =
+{
+ /* Opcode Mnemonic Opspec */
+
+ _MC88xxx (0xf4007000, "add", "d,1,2")
+ _MC88xxx (0x70000000, "add", "d,1,I")
+ _MC88xxx (0xf4007200, "add.ci", "d,1,2")
+ _MC88xxx (0xf4007300, "add.cio", "d,1,2")
+ _MC88xxx (0xf4007100, "add.co", "d,1,2")
+ _MC88xxx (0xf4006000, "addu", "d,1,2")
+ _MC88xxx (0x60000000, "addu", "d,1,I")
+ _MC88xxx (0xf4006200, "addu.ci", "d,1,2")
+ _MC88xxx (0xf4006300, "addu.cio", "d,1,2")
+ _MC88xxx (0xf4006100, "addu.co", "d,1,2")
+ _MC88xxx (0xf4004000, "and", "d,1,2")
+ _MC88xxx (0x40000000, "and", "d,1,I")
+ _MC88xxx (0xf4004400, "and.c", "d,1,2")
+ _MC88xxx (0x44000000, "and.u", "d,1,I")
+ _MC88xxx (0xd0000000, "bb0", "B,1,p")
+ _MC88xxx (0xd4000000, "bb0.n", "B,1,p")
+ _MC88xxx (0xd8000000, "bb1", "B,1,p")
+ _MC88xxx (0xdc000000, "bb1.n", "B,1,p")
+ _MC88xxx (0xe8000000, "bcnd", "M,1,p")
+ _MC88xxx (0xec000000, "bcnd.n", "M,1,p")
+ _MC88xxx (0xc0000000, "br", "P")
+ _MC88xxx (0xc4000000, "br.n", "P")
+ _MC88xxx (0xc8000000, "bsr", "P")
+ _MC88xxx (0xcc000000, "bsr.n", "P")
+ _MC88xxx (0xf4008000, "clr", "d,1,2")
+ _MC88xxx (0xf0008000, "clr", "d,1,b")
+ _MC88xxx (0xf4007c00, "cmp", "d,1,2")
+ _MC88xxx (0x7c000000, "cmp", "d,1,I")
+ _MC88xxx (0xf4007800, "div", "d,1,2")
+ _MC88xxx (0x78000000, "div", "d,1,I")
+ _MC88xxx (0xf4007800, "divs", "d,1,2")
+ _MC88xxx (0x78000000, "divs", "d,1,I")
+ _MC88110 (0xf4006900, "divu.d", "d,1,2")
+ _MC88xxx (0xf4006800, "divu", "d,1,2")
+ _MC88xxx (0x68000000, "divu", "d,1,I")
+ _MC88xxx (0xf4009000, "ext", "d,1,2")
+ _MC88xxx (0xf0009000, "ext", "d,1,b")
+ _MC88xxx (0xf4009800, "extu", "d,1,2")
+ _MC88xxx (0xf0009800, "extu", "d,1,b")
+ _MC88xxx (0x84002800, "fadd.sss", "d,1,2")
+ _MC88110 (0x8400a800, "fadd.sss", "xd,x1,x2")
+ _MC88xxx (0x84002880, "fadd.ssd", "d,1,2")
+ _MC88110 (0x8400a820, "fadd.ssd", "xd,x1,x2")
+ _MC88110 (0x8400a840, "fadd.ssx", "xd,x1,x2")
+ _MC88xxx (0x84002a00, "fadd.sds", "d,1,2")
+ _MC88110 (0x8400a880, "fadd.sds", "xd,x1,x2")
+ _MC88xxx (0x84002a80, "fadd.sdd", "d,1,2")
+ _MC88110 (0x8400a8a0, "fadd.sdd", "xd,x1,x2")
+ _MC88110 (0x8400a8c0, "fadd.sdx", "xd,x1,x2")
+ _MC88110 (0x8400a900, "fadd.sxs", "xd,x1,x2")
+ _MC88110 (0x8400a920, "fadd.sxd", "xd,x1,x2")
+ _MC88110 (0x8400a940, "fadd.sxx", "xd,x1,x2")
+ _MC88xxx (0x84002820, "fadd.dss", "d,1,2")
+ _MC88110 (0x8400aa00, "fadd.dss", "xd,x1,x2")
+ _MC88xxx (0x840028a0, "fadd.dsd", "d,1,2")
+ _MC88110 (0x8400aa20, "fadd.dsd", "xd,x1,x2")
+ _MC88110 (0x8400aa40, "fadd.dsx", "xd,x1,x2")
+ _MC88xxx (0x84002a20, "fadd.dds", "d,1,2")
+ _MC88110 (0x8400aa80, "fadd.dds", "xd,x1,x2")
+ _MC88xxx (0x84002aa0, "fadd.ddd", "d,1,2")
+ _MC88110 (0x8400aaa0, "fadd.ddd", "xd,x1,x2")
+ _MC88110 (0x8400aac0, "fadd.ddx", "xd,x1,x2")
+ _MC88110 (0x8400ab00, "fadd.dxs", "xd,x1,x2")
+ _MC88110 (0x8400ab20, "fadd.dxd", "xd,x1,x2")
+ _MC88110 (0x8400ab40, "fadd.dxx", "xd,x1,x2")
+ _MC88110 (0x8400ac00, "fadd.xss", "xd,x1,x2")
+ _MC88110 (0x8400ac20, "fadd.xsd", "xd,x1,x2")
+ _MC88110 (0x8400ac40, "fadd.xsx", "xd,x1,x2")
+ _MC88110 (0x8400ac80, "fadd.xds", "xd,x1,x2")
+ _MC88110 (0x8400aca0, "fadd.xdd", "xd,x1,x2")
+ _MC88110 (0x8400acc0, "fadd.xdx", "xd,x1,x2")
+ _MC88110 (0x8400ad00, "fadd.xxs", "xd,x1,x2")
+ _MC88110 (0x8400ad20, "fadd.xxd", "xd,x1,x2")
+ _MC88110 (0x8400ad40, "fadd.xxx", "xd,x1,x2")
+ _MC88xxx (0x84003a80, "fcmp.sdd", "d,1,2")
+ _MC88110 (0x8400ba80, "fcmp.sdd", "d,x1,x2")
+ _MC88xxx (0x84003a00, "fcmp.sds", "d,1,2")
+ _MC88110 (0x8400ba00, "fcmp.sds", "d,x1,x2")
+ _MC88110 (0x8400bb00, "fcmp.sdx", "d,x1,x2")
+ _MC88xxx (0x84003880, "fcmp.ssd", "d,1,2")
+ _MC88110 (0x8400b880, "fcmp.ssd", "d,x1,x2")
+ _MC88xxx (0x84003800, "fcmp.sss", "d,1,2")
+ _MC88110 (0x8400b800, "fcmp.sss", "d,x1,x2")
+ _MC88110 (0x8400b900, "fcmp.ssx", "d,x1,x2")
+ _MC88110 (0x8400bc80, "fcmp.sxd", "d,x1,x2")
+ _MC88110 (0x8400bc00, "fcmp.sxs", "d,x1,x2")
+ _MC88110 (0x8400bd00, "fcmp.sxx", "d,x1,x2")
+ _MC88110 (0x84003aa0, "fcmpu.sdd", "d,1,2")
+ _MC88110 (0x8400baa0, "fcmpu.sdd", "d,x1,x2")
+ _MC88110 (0x84003a20, "fcmpu.sds", "d,1,2")
+ _MC88110 (0x8400ba20, "fcmpu.sds", "d,x1,x2")
+ _MC88110 (0x8400bb20, "fcmpu.sdx", "d,x1,x2")
+ _MC88110 (0x840038a0, "fcmpu.ssd", "d,1,2")
+ _MC88110 (0x8400b8a0, "fcmpu.ssd", "d,x1,x2")
+ _MC88110 (0x84003820, "fcmpu.sss", "d,1,2")
+ _MC88110 (0x8400b820, "fcmpu.sss", "d,x1,x2")
+ _MC88110 (0x8400b920, "fcmpu.ssx", "d,x1,x2")
+ _MC88110 (0x8400bca0, "fcmpu.sxd", "d,x1,x2")
+ _MC88110 (0x8400bc20, "fcmpu.sxs", "d,x1,x2")
+ _MC88110 (0x8400bd20, "fcmpu.sxx", "d,x1,x2")
+ _MC88110 (0x84000880, "fcvt.ds", "d,2")
+ _MC88110 (0x84008880, "fcvt.ds", "xd,x2")
+ _MC88110 (0x840088c0, "fcvt.dx", "xd,x2")
+ _MC88110 (0x84000820, "fcvt.sd", "d,2")
+ _MC88110 (0x84008820, "fcvt.sd", "xd,x2")
+ _MC88110 (0x84008840, "fcvt.sx", "xd,x2")
+ _MC88110 (0x84008920, "fcvt.xd", "xd,x2")
+ _MC88110 (0x84008900, "fcvt.xs", "xd,x2")
+ _MC88xxx (0x84007000, "fdiv.sss", "d,1,2")
+ _MC88110 (0x8400f000, "fdiv.sss", "xd,x1,x2")
+ _MC88xxx (0x84007080, "fdiv.ssd", "d,1,2")
+ _MC88110 (0x8400f020, "fdiv.ssd", "xd,x1,x2")
+ _MC88110 (0x8400f040, "fdiv.ssx", "xd,x1,x2")
+ _MC88xxx (0x84007200, "fdiv.sds", "d,1,2")
+ _MC88110 (0x8400f080, "fdiv.sds", "xd,x1,x2")
+ _MC88xxx (0x84007280, "fdiv.sdd", "d,1,2")
+ _MC88110 (0x8400f0a0, "fdiv.sdd", "xd,x1,x2")
+ _MC88110 (0x8400f0c0, "fdiv.sdx", "xd,x1,x2")
+ _MC88110 (0x8400f100, "fdiv.sxs", "xd,x1,x2")
+ _MC88110 (0x8400f120, "fdiv.sxd", "xd,x1,x2")
+ _MC88110 (0x8400f140, "fdiv.sxx", "xd,x1,x2")
+ _MC88xxx (0x84007020, "fdiv.dss", "d,1,2")
+ _MC88110 (0x8400f200, "fdiv.dss", "xd,x1,x2")
+ _MC88xxx (0x840070a0, "fdiv.dsd", "d,1,2")
+ _MC88110 (0x8400f220, "fdiv.dsd", "xd,x1,x2")
+ _MC88110 (0x8400f240, "fdiv.dsx", "xd,x1,x2")
+ _MC88xxx (0x84007220, "fdiv.dds", "d,1,2")
+ _MC88110 (0x8400f280, "fdiv.dds", "xd,x1,x2")
+ _MC88xxx (0x840072a0, "fdiv.ddd", "d,1,2")
+ _MC88110 (0x8400f2a0, "fdiv.ddd", "xd,x1,x2")
+ _MC88110 (0x8400f2c0, "fdiv.ddx", "xd,x1,x2")
+ _MC88110 (0x8400f300, "fdiv.dxs", "xd,x1,x2")
+ _MC88110 (0x8400f320, "fdiv.dxd", "xd,x1,x2")
+ _MC88110 (0x8400f340, "fdiv.dxx", "xd,x1,x2")
+ _MC88110 (0x8400f400, "fdiv.xss", "xd,x1,x2")
+ _MC88110 (0x8400f420, "fdiv.xsd", "xd,x1,x2")
+ _MC88110 (0x8400f440, "fdiv.xsx", "xd,x1,x2")
+ _MC88110 (0x8400f480, "fdiv.xds", "xd,x1,x2")
+ _MC88110 (0x8400f4a0, "fdiv.xdd", "xd,x1,x2")
+ _MC88110 (0x8400f4c0, "fdiv.xdx", "xd,x1,x2")
+ _MC88110 (0x8400f500, "fdiv.xxs", "xd,x1,x2")
+ _MC88110 (0x8400f520, "fdiv.xxd", "xd,x1,x2")
+ _MC88110 (0x8400f540, "fdiv.xxx", "xd,x1,x2")
+ _MC88xxx (0xf400ec00, "ff0", "d,2")
+ _MC88xxx (0xf400e800, "ff1", "d,2")
+ _MC88xxx (0x80004800, "fldcr", "d,f")
+ _MC88xxx (0x84002020, "flt.ds", "d,2")
+ _MC88110 (0x84002220, "flt.ds", "xd,2")
+ _MC88xxx (0x84002000, "flt.ss", "d,2")
+ _MC88110 (0x84002200, "flt.ss", "xd,2")
+ _MC88110 (0x84002240, "flt.xs", "xd,2")
+ _MC88xxx (0x84000000, "fmul.sss", "d,1,2")
+ _MC88110 (0x84008000, "fmul.sss", "xd,x1,x2")
+ _MC88xxx (0x84000080, "fmul.ssd", "d,1,2")
+ _MC88110 (0x84008020, "fmul.ssd", "xd,x1,x2")
+ _MC88110 (0x84008040, "fmul.ssx", "xd,x1,x2")
+ _MC88xxx (0x84000200, "fmul.sds", "d,1,2")
+ _MC88110 (0x84008080, "fmul.sds", "xd,x1,x2")
+ _MC88xxx (0x84000280, "fmul.sdd", "d,1,2")
+ _MC88110 (0x840080a0, "fmul.sdd", "xd,x1,x2")
+ _MC88110 (0x840080c0, "fmul.sdx", "xd,x1,x2")
+ _MC88110 (0x84008100, "fmul.sxs", "xd,x1,x2")
+ _MC88110 (0x84008120, "fmul.sxd", "xd,x1,x2")
+ _MC88110 (0x84008140, "fmul.sxx", "xd,x1,x2")
+ _MC88xxx (0x84000020, "fmul.dss", "d,1,2")
+ _MC88110 (0x84008200, "fmul.dss", "xd,x1,x2")
+ _MC88xxx (0x840000a0, "fmul.dsd", "d,1,2")
+ _MC88110 (0x84008220, "fmul.dsd", "xd,x1,x2")
+ _MC88110 (0x84008240, "fmul.dsx", "xd,x1,x2")
+ _MC88xxx (0x84000220, "fmul.dds", "d,1,2")
+ _MC88110 (0x84008280, "fmul.dds", "xd,x1,x2")
+ _MC88xxx (0x840002a0, "fmul.ddd", "d,1,2")
+ _MC88110 (0x840082a0, "fmul.ddd", "xd,x1,x2")
+ _MC88110 (0x840082c0, "fmul.ddx", "xd,x1,x2")
+ _MC88110 (0x84008300, "fmul.dxs", "xd,x1,x2")
+ _MC88110 (0x84008320, "fmul.dxd", "xd,x1,x2")
+ _MC88110 (0x84008340, "fmul.dxx", "xd,x1,x2")
+ _MC88110 (0x84008400, "fmul.xss", "xd,x1,x2")
+ _MC88110 (0x84008420, "fmul.xsd", "xd,x1,x2")
+ _MC88110 (0x84008440, "fmul.xsx", "xd,x1,x2")
+ _MC88110 (0x84008480, "fmul.xds", "xd,x1,x2")
+ _MC88110 (0x840084a0, "fmul.xdd", "xd,x1,x2")
+ _MC88110 (0x840084c0, "fmul.xdx", "xd,x1,x2")
+ _MC88110 (0x84008500, "fmul.xxs", "xd,x1,x2")
+ _MC88110 (0x84008520, "fmul.xxd", "xd,x1,x2")
+ _MC88110 (0x84008540, "fmul.xxx", "xd,x1,x2")
+ _MC88110 (0x840078a0, "fsqrt.dd", "d,2")
+ _MC88110 (0x8400f8a0, "fsqrt.dd", "xd,x2")
+ _MC88110 (0x84007880, "fsqrt.ds", "d,2")
+ _MC88110 (0x8400f880, "fsqrt.ds", "xd,x2")
+ _MC88110 (0x8400f8c0, "fsqrt.dx", "xd,x2")
+ _MC88110 (0x84007820, "fsqrt.sd", "d,2")
+ _MC88110 (0x8400f820, "fsqrt.sd", "xd,x2")
+ _MC88110 (0x84007800, "fsqrt.ss", "d,2")
+ _MC88110 (0x8400f800, "fsqrt.ss", "xd,x2")
+ _MC88110 (0x8400f840, "fsqrt.sx", "xd,x2")
+ _MC88110 (0x8400f920, "fsqrt.xd", "xd,x2")
+ _MC88110 (0x8400f900, "fsqrt.xs", "xd,x2")
+ _MC88110 (0x8400f940, "fsqrt.xx", "xd,x2")
+ _MC88xxx (0x80008800, "fstcr", "3,f")
+ _MC88xxx (0x84003000, "fsub.sss", "d,1,2")
+ _MC88110 (0x8400b000, "fsub.sss", "xd,x1,x2")
+ _MC88xxx (0x84003080, "fsub.ssd", "d,1,2")
+ _MC88110 (0x8400b020, "fsub.ssd", "xd,x1,x2")
+ _MC88110 (0x8400b040, "fsub.ssx", "xd,x1,x2")
+ _MC88xxx (0x84003200, "fsub.sds", "d,1,2")
+ _MC88110 (0x8400b080, "fsub.sds", "xd,x1,x2")
+ _MC88xxx (0x84003280, "fsub.sdd", "d,1,2")
+ _MC88110 (0x8400b0a0, "fsub.sdd", "xd,x1,x2")
+ _MC88110 (0x8400b0c0, "fsub.sdx", "xd,x1,x2")
+ _MC88110 (0x8400b100, "fsub.sxs", "xd,x1,x2")
+ _MC88110 (0x8400b120, "fsub.sxd", "xd,x1,x2")
+ _MC88110 (0x8400b140, "fsub.sxx", "xd,x1,x2")
+ _MC88xxx (0x84003020, "fsub.dss", "d,1,2")
+ _MC88110 (0x8400b200, "fsub.dss", "xd,x1,x2")
+ _MC88xxx (0x840030a0, "fsub.dsd", "d,1,2")
+ _MC88110 (0x8400b220, "fsub.dsd", "xd,x1,x2")
+ _MC88110 (0x8400b240, "fsub.dsx", "xd,x1,x2")
+ _MC88xxx (0x84003220, "fsub.dds", "d,1,2")
+ _MC88110 (0x8400b280, "fsub.dds", "xd,x1,x2")
+ _MC88xxx (0x840032a0, "fsub.ddd", "d,1,2")
+ _MC88110 (0x8400b2a0, "fsub.ddd", "xd,x1,x2")
+ _MC88110 (0x8400b2c0, "fsub.ddx", "xd,x1,x2")
+ _MC88110 (0x8400b300, "fsub.dxs", "xd,x1,x2")
+ _MC88110 (0x8400b320, "fsub.dxd", "xd,x1,x2")
+ _MC88110 (0x8400b340, "fsub.dxx", "xd,x1,x2")
+ _MC88110 (0x8400b400, "fsub.xss", "xd,x1,x2")
+ _MC88110 (0x8400b420, "fsub.xsd", "xd,x1,x2")
+ _MC88110 (0x8400b440, "fsub.xsx", "xd,x1,x2")
+ _MC88110 (0x8400b480, "fsub.xds", "xd,x1,x2")
+ _MC88110 (0x8400b4a0, "fsub.xdd", "xd,x1,x2")
+ _MC88110 (0x8400b4c0, "fsub.xdx", "xd,x1,x2")
+ _MC88110 (0x8400b500, "fsub.xxs", "xd,x1,x2")
+ _MC88110 (0x8400b520, "fsub.xxd", "xd,x1,x2")
+ _MC88110 (0x8400b540, "fsub.xxx", "xd,x1,x2")
+ _MC88xxx (0x8000c800, "fxcr", "d,3,f")
+ _MC88xxx (0x8400fc01, "illop1", "")
+ _MC88xxx (0x8400fc02, "illop2", "")
+ _MC88xxx (0x8400fc03, "illop3", "")
+ _MC88xxx (0x84004880, "int.sd", "d,2")
+ _MC88110 (0x8400c880, "int.sd", "d,x2")
+ _MC88xxx (0x84004800, "int.ss", "d,2")
+ _MC88110 (0x8400c800, "int.ss", "d,x2")
+ _MC88110 (0x8400c900, "int.sx", "d,x2")
+ _MC88xxx (0xf400c000, "jmp", "2")
+ _MC88xxx (0xf400c400, "jmp.n", "2")
+ _MC88xxx (0xf400c800, "jsr", "2")
+ _MC88xxx (0xf400cc00, "jsr.n", "2")
+ _MC88xxx (0xf4001400, "ld", "d,1,2")
+ _MC88xxx (0xf4001600, "ld", "d,1[2]")
+ _MC88xxx (0x14000000, "ld", "d,1,I")
+ _MC88110 (0xf0001600, "ld", "xd,1[2]")
+ _MC88110 (0xf0001400, "ld", "xd,1,2")
+ _MC88110 (0x04000000, "ld", "xd,1,I")
+ _MC88xxx (0xf4001e00, "ld.b", "d,1[2]")
+ _MC88xxx (0xf4001c00, "ld.b", "d,1,2")
+ _MC88xxx (0x1c000000, "ld.b", "d,1,I")
+ _MC88xxx (0xf4001d00, "ld.b.usr", "d,1,2")
+ _MC88xxx (0xf4001f00, "ld.b.usr", "d,1[2]")
+ _MC88xxx (0xf4000e00, "ld.bu", "d,1[2]")
+ _MC88xxx (0xf4000c00, "ld.bu", "d,1,2")
+ _MC88xxx (0x0c000000, "ld.bu", "d,1,I")
+ _MC88xxx (0xf4000d00, "ld.bu.usr", "d,1,2")
+ _MC88xxx (0xf4000f00, "ld.bu.usr", "d,1[2]")
+ _MC88xxx (0xf4001200, "ld.d", "d,1[2]")
+ _MC88xxx (0xf4001000, "ld.d", "d,1,2")
+ _MC88xxx (0x10000000, "ld.d", "d,1,I")
+ _MC88110 (0xf0001200, "ld.d", "xd,1[2]")
+ _MC88110 (0xf0001000, "ld.d", "xd,1,2")
+ _MC88110 (0x00000000, "ld.d", "xd,1,I")
+ _MC88xxx (0xf4001100, "ld.d.usr", "d,1,2")
+ _MC88xxx (0xf4001300, "ld.d.usr", "d,1[2]")
+ _MC88110 (0xf0001100, "ld.d.usr", "xd,1,2")
+ _MC88110 (0xf0001300, "ld.d.usr", "xd,1[2]")
+ _MC88xxx (0xf4001a00, "ld.h", "d,1[2]")
+ _MC88xxx (0xf4001800, "ld.h", "d,1,2")
+ _MC88xxx (0x18000000, "ld.h", "d,1,I")
+ _MC88xxx (0xf4001900, "ld.h.usr", "d,1,2")
+ _MC88xxx (0xf4001b00, "ld.h.usr", "d,1[2]")
+ _MC88xxx (0xf4000a00, "ld.hu", "d,1[2]")
+ _MC88xxx (0xf4000800, "ld.hu", "d,1,2")
+ _MC88xxx (0x08000000, "ld.hu", "d,1,I")
+ _MC88xxx (0xf4000900, "ld.hu.usr", "d,1,2")
+ _MC88xxx (0xf4000b00, "ld.hu.usr", "d,1[2]")
+ _MC88xxx (0xf4001500, "ld.usr", "d,1,2")
+ _MC88xxx (0xf4001700, "ld.usr", "d,1[2]")
+ _MC88110 (0xf0001500, "ld.usr", "xd,1,2")
+ _MC88110 (0xf0001700, "ld.usr", "xd,1[2]")
+ _MC88110 (0xf0001a00, "ld.x", "xd,1[2]")
+ _MC88110 (0xf0001800, "ld.x", "xd,1,2")
+ _MC88110 (0x3c000000, "ld.x", "xd,1,I")
+ _MC88110 (0xf0001900, "ld.x.usr", "xd,1,2")
+ _MC88110 (0xf0001b00, "ld.x.usr", "xd,1[2]")
+ _MC88xxx (0xf4003600, "lda", "d,1[2]")
+ _MC88xxx (0xf4006000, "lda", "?d,1,2") /* Output addu */
+ _MC88xxx (0x60000000, "lda", "?d,1,I") /* Output addu */
+ _MC88xxx (0xf4006000, "lda.b", "?d,1[2]") /* Output addu */
+ _MC88xxx (0xf4006000, "lda.b", "?d,1,2") /* Output addu */
+ _MC88xxx (0x60000000, "lda.b", "?d,1,I") /* Output addu */
+ _MC88xxx (0xf4003200, "lda.d", "d,1[2]")
+ _MC88xxx (0xf4006000, "lda.d", "?d,1,2") /* Output addu */
+ _MC88xxx (0x60000000, "lda.d", "?d,1,I") /* Output addu */
+ _MC88110 (0xf4003e00, "lda.x", "d,1[2]")
+ _MC88xxx (0xf4003a00, "lda.h", "d,1[2]")
+ _MC88xxx (0xf4006000, "lda.h", "?d,1,2") /* Output addu */
+ _MC88xxx (0x60000000, "lda.h", "?d,1,I") /* Output addu */
+ _MC88xxx (0x80004000, "ldcr", "d,c")
+ _MC88xxx (0xf400a000, "mak", "d,1,2")
+ _MC88xxx (0xf000a000, "mak", "d,1,b")
+ _MC88xxx (0x48000000, "mask", "d,1,I")
+ _MC88xxx (0x4c000000, "mask.u", "d,1,I")
+ _MC88110 (0x8400c000, "mov.s", "d,x2")
+ _MC88110 (0x84004200, "mov.s", "xd,2")
+ _MC88110 (0x8400c080, "mov.d", "d,x2")
+ _MC88110 (0x84004280, "mov.d", "xd,2")
+ _MC88110 (0x8400c300, "mov", "xd,x2")
+ _MC88xxx (0xf4006c00, "mul", "d,1,2")
+ _MC88xxx (0x6c000000, "mul", "d,1,I")
+ _MC88xxx (0xf4006e00, "muls", "d,1,2")
+ _MC88xxx (0x6c000000, "muls", "d,1,I")
+ _MC88xxx (0xf4006c00, "mulu", "d,1,2") /* synonym for mul */
+ _MC88xxx (0x6c000000, "mulu", "d,1,I") /* synonym for mul */
+ _MC88110 (0xf4006d00, "mulu.d", "d,1,2")
+ _MC88xxx (0x84005080, "nint.sd", "d,2")
+ _MC88110 (0x8400d080, "nint.sd", "d,x2")
+ _MC88xxx (0x84005000, "nint.ss", "d,2")
+ _MC88110 (0x8400d000, "nint.ss", "d,x2")
+ _MC88110 (0x8400d100, "nint.sx", "d,x2")
+ _MC88xxx (0xf4005800, "or", "d,1,2")
+ _MC88xxx (0x58000000, "or", "d,1,I")
+ _MC88xxx (0xf4005c00, "or.c", "d,1,2")
+ _MC88xxx (0x5c000000, "or.u", "d,1,I")
+ _MC88110 (0x88002020, "padd.b", "d,1,2")
+ _MC88110 (0x88002040, "padd.h", "d,1,2")
+ _MC88110 (0x88002060, "padd", "d,1,2")
+ _MC88110 (0x880020a0, "padds.u.b", "d,1,2")
+ _MC88110 (0x880020c0, "padds.u.h", "d,1,2")
+ _MC88110 (0x880020e0, "padds.u", "d,1,2")
+ _MC88110 (0x88002120, "padds.us.b", "d,1,2")
+ _MC88110 (0x88002140, "padds.us.h", "d,1,2")
+ _MC88110 (0x88002160, "padds.us", "d,1,2")
+ _MC88110 (0x880021a0, "padds.s.b", "d,1,2")
+ _MC88110 (0x880021c0, "padds.s.h", "d,1,2")
+ _MC88110 (0x880021e0, "padds.s", "d,1,2")
+ _MC88110 (0x88003860, "pcmp", "d,1,2")
+ _MC88110 (0x88000000, "pmul", "d,1,2")
+ _MC88110 (0x88006420, "ppack.32.b", "d,1,2")
+ _MC88110 (0x88006240, "ppack.16.h", "d,1,2")
+ _MC88110 (0x88006440, "ppack.32.h", "d,1,2")
+ _MC88110 (0x88006160, "ppack.8", "d,1,2")
+ _MC88110 (0x88006260, "ppack.16", "d,1,2")
+ _MC88110 (0x88006460, "ppack.32", "d,1,2")
+ _MC88110 (0x88007800, "prot", "d,1,2")
+ _MC88110 (0x88007000, "prot", "d,1,o")
+ _MC88110 (0x88003020, "psub.b", "d,1,2")
+ _MC88110 (0x88003040, "psub.h", "d,1,2")
+ _MC88110 (0x88003060, "psub", "d,1,2")
+ _MC88110 (0x880030a0, "psubs.u.b", "d,1,2")
+ _MC88110 (0x880030c0, "psubs.u.h", "d,1,2")
+ _MC88110 (0x880030e0, "psubs.u", "d,1,2")
+ _MC88110 (0x88003120, "psubs.us.b", "d,1,2")
+ _MC88110 (0x88003140, "psubs.us.h", "d,1,2")
+ _MC88110 (0x88003160, "psubs.us", "d,1,2")
+ _MC88110 (0x880031a0, "psubs.s.b", "d,1,2")
+ _MC88110 (0x880031c0, "psubs.s.h", "d,1,2")
+ _MC88110 (0x880031e0, "psubs.s", "d,1,2")
+ _MC88110 (0x88006800, "punpk.n", "d,1")
+ _MC88110 (0x88006820, "punpk.b", "d,1")
+ _MC88110 (0x88006840, "punpk.h", "d,1")
+ _MC88xxx (0xf400a800, "rot", "d,1,2")
+ _MC88xxx (0xf000a800, "rot", "d,1,b")
+ _MC88xxx (0xf400fc00, "rte", "")
+ _MC88xxx (0xf4008800, "set", "d,1,2")
+ _MC88xxx (0xf0008800, "set", "d,1,b")
+ _MC88xxx (0xf4002600, "st", "d,1[2]")
+ _MC88xxx (0xf4002400, "st", "d,1,2")
+ _MC88xxx (0x24000000, "st", "d,1,I")
+ _MC88110 (0xf0002600, "st", "xd,1[2]")
+ _MC88110 (0xf0002400, "st", "xd,1,2")
+ _MC88110 (0x34000000, "st", "xd,1,I")
+ _MC88xxx (0xf4002e00, "st.b", "d,1[2]")
+ _MC88xxx (0xf4002c00, "st.b", "d,1,2")
+ _MC88xxx (0x2c000000, "st.b", "d,1,I")
+ _MC88xxx (0xf4002d00, "st.b.usr", "d,1,2")
+ _MC88xxx (0xf4002f00, "st.b.usr", "d,1[2]")
+ _MC88110 (0xf4002d80, "st.b.usr.wt", "d,1,2")
+ _MC88110 (0xf4002f80, "st.b.usr.wt", "d,1[2]")
+ _MC88110 (0xf4002c80, "st.b.wt", "d,1,2")
+ _MC88110 (0xf4002e80, "st.b.wt", "d,1[2]")
+ _MC88xxx (0xf4002200, "st.d", "d,1[2]")
+ _MC88xxx (0xf4002000, "st.d", "d,1,2")
+ _MC88xxx (0x20000000, "st.d", "d,1,I")
+ _MC88110 (0xf0002200, "st.d", "xd,1[2]")
+ _MC88110 (0xf0002000, "st.d", "xd,1,2")
+ _MC88110 (0x30000000, "st.d", "xd,1,I")
+ _MC88xxx (0xf4002100, "st.d.usr", "d,1,2")
+ _MC88xxx (0xf4002300, "st.d.usr", "d,1[2]")
+ _MC88110 (0xf0002100, "st.d.usr", "xd,1,2")
+ _MC88110 (0xf0002300, "st.d.usr", "xd,1[2]")
+ _MC88110 (0xf4002180, "st.d.usr.wt", "d,1,2")
+ _MC88110 (0xf4002380, "st.d.usr.wt", "d,1[2]")
+ _MC88110 (0xf0002180, "st.d.usr.wt", "xd,1,2")
+ _MC88110 (0xf0002380, "st.d.usr.wt", "xd,1[2]")
+ _MC88110 (0xf4002080, "st.d.wt", "d,1,2")
+ _MC88110 (0xf4002280, "st.d.wt", "d,1[2]")
+ _MC88110 (0xf0002080, "st.d.wt", "xd,1,2")
+ _MC88110 (0xf0002280, "st.d.wt", "xd,1[2]")
+ _MC88xxx (0xf4002a00, "st.h", "d,1[2]")
+ _MC88xxx (0xf4002800, "st.h", "d,1,2")
+ _MC88xxx (0x28000000, "st.h", "d,1,I")
+ _MC88xxx (0xf4002900, "st.h.usr", "d,1,2")
+ _MC88xxx (0xf4002b00, "st.h.usr", "d,1[2]")
+ _MC88110 (0xf4002980, "st.h.usr.wt", "d,1,2")
+ _MC88110 (0xf4002b80, "st.h.usr.wt", "d,1[2]")
+ _MC88110 (0xf4002880, "st.h.wt", "d,1,2")
+ _MC88110 (0xf4002a80, "st.h.wt", "d,1[2]")
+ _MC88xxx (0xf4002500, "st.usr", "d,1,2")
+ _MC88xxx (0xf4002700, "st.usr", "d,1[2]")
+ _MC88110 (0xf0002500, "st.usr", "xd,1,2")
+ _MC88110 (0xf0002700, "st.usr", "xd,1[2]")
+ _MC88110 (0xf4002580, "st.usr.wt", "d,1,2")
+ _MC88110 (0xf4002780, "st.usr.wt", "d,1[2]")
+ _MC88110 (0xf0002580, "st.usr.wt", "xd,1,2")
+ _MC88110 (0xf0002780, "st.usr.wt", "xd,1[2]")
+ _MC88110 (0xf4002480, "st.wt", "d,1,2")
+ _MC88110 (0xf4002680, "st.wt", "d,1[2]")
+ _MC88110 (0xf0002480, "st.wt", "xd,1,2")
+ _MC88110 (0xf0002680, "st.wt", "xd,1[2]")
+ _MC88110 (0xf0002a00, "st.x", "xd,1[2]")
+ _MC88110 (0xf0002800, "st.x", "xd,1,2")
+ _MC88110 (0x38000000, "st.x", "xd,1,I")
+ _MC88110 (0xf0002900, "st.x.usr", "xd,1,2")
+ _MC88110 (0xf0002b00, "st.x.usr", "xd,1[2]")
+ _MC88110 (0xf0002980, "st.x.usr.wt", "xd,1,2")
+ _MC88110 (0xf0002b80, "st.x.usr.wt", "xd,1[2]")
+ _MC88110 (0xf0002880, "st.x.wt", "xd,1,2")
+ _MC88110 (0xf0002a80, "st.x.wt", "xd,1[2]")
+ _MC88xxx (0x80008000, "stcr", "3,c")
+ _MC88xxx (0xf4007400, "sub", "d,1,2")
+ _MC88xxx (0x74000000, "sub", "d,1,I")
+ _MC88xxx (0xf4007600, "sub.ci", "d,1,2")
+ _MC88xxx (0xf4007700, "sub.cio", "d,1,2")
+ _MC88xxx (0xf4007500, "sub.co", "d,1,2")
+ _MC88xxx (0xf4006400, "subu", "d,1,2")
+ _MC88xxx (0x64000000, "subu", "d,1,I")
+ _MC88xxx (0xf4006600, "subu.ci", "d,1,2")
+ _MC88xxx (0xf4006700, "subu.cio", "d,1,2")
+ _MC88xxx (0xf4006500, "subu.co", "d,1,2")
+ _MC88xxx (0xf000d000, "tb0", "B,1,V")
+ _MC88xxx (0xf000d800, "tb1", "B,1,V")
+ _MC88xxx (0xf400f800, "tbnd", "1,2")
+ _MC88xxx (0xf8000000, "tbnd", "1,I")
+ _MC88xxx (0xf000e800, "tcnd", "M,1,V")
+ _MC88xxx (0x84005880, "trnc.sd", "d,2")
+ _MC88110 (0x8400d880, "trnc.sd", "d,x2")
+ _MC88xxx (0x84005800, "trnc.ss", "d,2")
+ _MC88110 (0x8400d800, "trnc.ss", "d,x2")
+ _MC88110 (0x8400d900, "trnc.sx", "d,x2")
+ _MC88xxx (0x8000c000, "xcr", "d,3,c")
+ _MC88xxx (0xf4000600, "xmem", "d,1[2]")
+ _MC88xxx (0xf4000400, "xmem", "d,1,2")
+ _MC88100 (0x04000000, "xmem", "?d,1,I")
+ _MC88xxx (0xf4000200, "xmem.bu", "d,1[2]")
+ _MC88xxx (0xf4000000, "xmem.bu", "d,1,2")
+ _MC88100 (0x00000000, "xmem.bu", "?d,1,I")
+ _MC88xxx (0xf4000300, "xmem.bu.usr", "d,1[2]")
+ _MC88xxx (0xf4000100, "xmem.bu.usr", "d,1,2")
+ _MC88100 (0x00000100, "xmem.bu.usr", "?d,1,I")
+ _MC88xxx (0xf4000700, "xmem.usr", "d,1[2]")
+ _MC88xxx (0xf4000500, "xmem.usr", "d,1,2")
+ _MC88100 (0x04000100, "xmem.usr", "?d,1,I")
+ _MC88xxx (0xf4005000, "xor", "d,1,2")
+ _MC88xxx (0x50000000, "xor", "d,1,I")
+ _MC88xxx (0xf4005400, "xor.c", "d,1,2")
+ _MC88xxx (0x54000000, "xor.u", "d,1,I")
+ _MC88xxx (0x00000000, "", 0)
+};
+
+#define NUMOPCODES ((sizeof m88k_opcodes)/(sizeof m88k_opcodes[0]))
diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c
new file mode 100644
index 00000000000..b5193475c10
--- /dev/null
+++ b/gas/config/obj-aout.c
@@ -0,0 +1,629 @@
+/* a.out object file format
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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,
+or (at your option) any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write
+to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+#ifdef BFD_ASSEMBLER
+#undef NO_RELOC
+#include "aout/aout64.h"
+#endif
+#include "obstack.h"
+
+#ifndef BFD_ASSEMBLER
+/* in: segT out: N_TYPE bits */
+const short seg_N_TYPE[] =
+{
+ N_ABS,
+ N_TEXT,
+ N_DATA,
+ N_BSS,
+ N_UNDF, /* unknown */
+ N_UNDF, /* error */
+ N_UNDF, /* expression */
+ N_UNDF, /* debug */
+ N_UNDF, /* ntv */
+ N_UNDF, /* ptv */
+ N_REGISTER, /* register */
+};
+
+const segT N_TYPE_seg[N_TYPE + 2] =
+{ /* N_TYPE == 0x1E = 32-2 */
+ SEG_UNKNOWN, /* N_UNDF == 0 */
+ SEG_GOOF,
+ SEG_ABSOLUTE, /* N_ABS == 2 */
+ SEG_GOOF,
+ SEG_TEXT, /* N_TEXT == 4 */
+ SEG_GOOF,
+ SEG_DATA, /* N_DATA == 6 */
+ SEG_GOOF,
+ SEG_BSS, /* N_BSS == 8 */
+ SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
+ SEG_GOOF,
+};
+#endif
+
+static void obj_aout_line PARAMS ((int));
+static void obj_aout_weak PARAMS ((int));
+static void obj_aout_type PARAMS ((int));
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {"line", obj_aout_line, 0}, /* source code line number */
+ {"ln", obj_aout_line, 0}, /* coff line number that we use anyway */
+
+ {"weak", obj_aout_weak, 0}, /* mark symbol as weak. */
+
+ {"type", obj_aout_type, 0},
+
+ /* coff debug pseudos (ignored) */
+ {"def", s_ignore, 0},
+ {"dim", s_ignore, 0},
+ {"endef", s_ignore, 0},
+ {"ident", s_ignore, 0},
+ {"line", s_ignore, 0},
+ {"ln", s_ignore, 0},
+ {"scl", s_ignore, 0},
+ {"size", s_ignore, 0},
+ {"tag", s_ignore, 0},
+ {"val", s_ignore, 0},
+ {"version", s_ignore, 0},
+
+ {"optim", s_ignore, 0}, /* For sun386i cc (?) */
+
+ /* other stuff */
+ {"ABORT", s_abort, 0},
+
+ {NULL} /* end sentinel */
+}; /* obj_pseudo_table */
+
+
+#ifdef BFD_ASSEMBLER
+
+void
+obj_aout_frob_symbol (sym, punt)
+ symbolS *sym;
+ int *punt;
+{
+ flagword flags;
+ asection *sec;
+ int desc, type, other;
+
+ flags = sym->bsym->flags;
+ desc = S_GET_DESC (sym);
+ type = S_GET_TYPE (sym);
+ other = S_GET_OTHER (sym);
+ sec = sym->bsym->section;
+
+ /* Only frob simple symbols this way right now. */
+ if (! (type & ~ (N_TYPE | N_EXT)))
+ {
+ if (type == (N_UNDF | N_EXT)
+ && sec == &bfd_abs_section)
+ sym->bsym->section = sec = bfd_und_section_ptr;
+
+ if ((type & N_TYPE) != N_INDR
+ && (type & N_TYPE) != N_SETA
+ && (type & N_TYPE) != N_SETT
+ && (type & N_TYPE) != N_SETD
+ && (type & N_TYPE) != N_SETB
+ && type != N_WARNING
+ && (sec == &bfd_abs_section
+ || sec == &bfd_und_section))
+ return;
+ if (flags & BSF_EXPORT)
+ type |= N_EXT;
+
+ switch (type & N_TYPE)
+ {
+ case N_SETA:
+ case N_SETT:
+ case N_SETD:
+ case N_SETB:
+ /* Set the debugging flag for constructor symbols so that
+ BFD leaves them alone. */
+ sym->bsym->flags |= BSF_DEBUGGING;
+
+ /* You can't put a common symbol in a set. The way a set
+ element works is that the symbol has a definition and a
+ name, and the linker adds the definition to the set of
+ that name. That does not work for a common symbol,
+ because the linker can't tell which common symbol the
+ user means. FIXME: Using as_bad here may be
+ inappropriate, since the user may want to force a
+ particular type without regard to the semantics of sets;
+ on the other hand, we certainly don't want anybody to be
+ mislead into thinking that their code will work. */
+ if (S_IS_COMMON (sym))
+ as_bad (_("Attempt to put a common symbol into set %s"),
+ S_GET_NAME (sym));
+ /* Similarly, you can't put an undefined symbol in a set. */
+ else if (! S_IS_DEFINED (sym))
+ as_bad (_("Attempt to put an undefined symbol into set %s"),
+ S_GET_NAME (sym));
+
+ break;
+ case N_INDR:
+ /* Put indirect symbols in the indirect section. */
+ sym->bsym->section = bfd_ind_section_ptr;
+ sym->bsym->flags |= BSF_INDIRECT;
+ if (type & N_EXT)
+ {
+ sym->bsym->flags |= BSF_EXPORT;
+ sym->bsym->flags &=~ BSF_LOCAL;
+ }
+ break;
+ case N_WARNING:
+ /* Mark warning symbols. */
+ sym->bsym->flags |= BSF_WARNING;
+ break;
+ }
+ }
+ else
+ {
+ sym->bsym->flags |= BSF_DEBUGGING;
+ }
+
+ S_SET_TYPE (sym, type);
+
+ /* Double check weak symbols. */
+ if (sym->bsym->flags & BSF_WEAK)
+ {
+ if (S_IS_COMMON (sym))
+ as_bad (_("Symbol `%s' can not be both weak and common"),
+ S_GET_NAME (sym));
+ }
+}
+
+void
+obj_aout_frob_file ()
+{
+ /* Relocation processing may require knowing the VMAs of the sections.
+ Since writing to a section will cause the BFD back end to compute the
+ VMAs, fake it out here.... */
+ bfd_byte b = 0;
+ boolean x = true;
+ if (bfd_section_size (stdoutput, text_section) != 0)
+ {
+ x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
+ (bfd_size_type) 1);
+ }
+ else if (bfd_section_size (stdoutput, data_section) != 0)
+ {
+ x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
+ (bfd_size_type) 1);
+ }
+ assert (x == true);
+}
+
+#else
+
+/* Relocation. */
+
+/*
+ * emit_relocations()
+ *
+ * Crawl along a fixS chain. Emit the segment's relocations.
+ */
+void
+obj_emit_relocations (where, fixP, segment_address_in_file)
+ char **where;
+ fixS *fixP; /* Fixup chain for this segment. */
+ relax_addressT segment_address_in_file;
+{
+ for (; fixP; fixP = fixP->fx_next)
+ if (fixP->fx_done == 0)
+ {
+ symbolS *sym;
+
+ sym = fixP->fx_addsy;
+ while (sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ sym = sym->sy_value.X_add_symbol;
+ fixP->fx_addsy = sym;
+
+ if (! sym->sy_resolved && ! S_IS_DEFINED (sym))
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (sym, &file, &line))
+ as_bad_where (file, line, _("unresolved relocation"));
+ else
+ as_bad (_("bad relocation: symbol `%s' not in symbol table"),
+ S_GET_NAME (sym));
+ }
+
+ tc_aout_fix_to_chars (*where, fixP, segment_address_in_file);
+ *where += md_reloc_size;
+ }
+}
+
+#ifndef obj_header_append
+/* Aout file generation & utilities */
+void
+obj_header_append (where, headers)
+ char **where;
+ object_headers *headers;
+{
+ tc_headers_hook (headers);
+
+#ifdef CROSS_COMPILE
+ md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info));
+ *where += sizeof (headers->header.a_info);
+ md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
+ *where += sizeof (headers->header.a_text);
+ md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
+ *where += sizeof (headers->header.a_data);
+ md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
+ *where += sizeof (headers->header.a_bss);
+ md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
+ *where += sizeof (headers->header.a_syms);
+ md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
+ *where += sizeof (headers->header.a_entry);
+ md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
+ *where += sizeof (headers->header.a_trsize);
+ md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
+ *where += sizeof (headers->header.a_drsize);
+
+#else /* CROSS_COMPILE */
+
+ append (where, (char *) &headers->header, sizeof (headers->header));
+#endif /* CROSS_COMPILE */
+
+}
+#endif
+
+void
+obj_symbol_to_chars (where, symbolP)
+ char **where;
+ symbolS *symbolP;
+{
+ md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP)));
+ md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP)));
+ md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value));
+
+ append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
+}
+
+void
+obj_emit_symbols (where, symbol_rootP)
+ char **where;
+ symbolS *symbol_rootP;
+{
+ symbolS *symbolP;
+
+ /* Emit all symbols left in the symbol chain. */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /* Used to save the offset of the name. It is used to point
+ to the string in memory but must be a file offset. */
+ register char *temp;
+
+ temp = S_GET_NAME (symbolP);
+ S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
+
+ /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
+ if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
+ S_SET_EXTERNAL (symbolP);
+
+ /* Adjust the type of a weak symbol. */
+ if (S_GET_WEAK (symbolP))
+ {
+ switch (S_GET_TYPE (symbolP))
+ {
+ case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break;
+ case N_ABS: S_SET_TYPE (symbolP, N_WEAKA); break;
+ case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break;
+ case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break;
+ case N_BSS: S_SET_TYPE (symbolP, N_WEAKB); break;
+ default: as_bad (_("%s: bad type for weak symbol"), temp); break;
+ }
+ }
+
+ obj_symbol_to_chars (where, symbolP);
+ S_SET_NAME (symbolP, temp);
+ }
+}
+
+#endif /* ! BFD_ASSEMBLER */
+
+static void
+obj_aout_line (ignore)
+ int ignore;
+{
+ /* Assume delimiter is part of expression.
+ BSD4.2 as fails with delightful bug, so we
+ are not being incompatible here. */
+ new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
+ demand_empty_rest_of_line ();
+} /* obj_aout_line() */
+
+/* Handle .weak. This is a GNU extension. */
+
+static void
+obj_aout_weak (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_SET_WEAK (symbolP);
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+ demand_empty_rest_of_line ();
+}
+
+/* Handle .type. On {Net,Open}BSD, this is used to set the n_other field,
+ which is then apparently used when doing dynamic linking. Older
+ versions ogas ignored the .type pseudo-op, so we also ignore it if
+ we can't parse it. */
+
+static void
+obj_aout_type (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find (name);
+ *input_line_pointer = c;
+ if (sym != NULL)
+ {
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '@')
+ {
+ ++input_line_pointer;
+ if (strncmp (input_line_pointer, "object", 6) == 0)
+ S_SET_OTHER (sym, 1);
+ else if (strncmp (input_line_pointer, "function", 8) == 0)
+ S_SET_OTHER (sym, 2);
+ }
+ }
+ }
+
+ /* Ignore everything else on the line. */
+ s_ignore (0);
+}
+
+void
+obj_read_begin_hook ()
+{
+}
+
+#ifndef BFD_ASSEMBLER
+
+void
+obj_crawl_symbol_chain (headers)
+ object_headers *headers;
+{
+ symbolS *symbolP;
+ symbolS **symbolPP;
+ int symbol_number = 0;
+
+ tc_crawl_symbol_chain (headers);
+
+ symbolPP = &symbol_rootP; /*->last symbol chain link. */
+ while ((symbolP = *symbolPP) != NULL)
+ {
+ if (symbolP->sy_mri_common)
+ {
+ if (S_IS_EXTERNAL (symbolP))
+ as_bad (_("%s: global symbols not supported in common sections"),
+ S_GET_NAME (symbolP));
+ *symbolPP = symbol_next (symbolP);
+ continue;
+ }
+
+ if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
+ {
+ S_SET_SEGMENT (symbolP, SEG_TEXT);
+ } /* if pusing data into text */
+
+ resolve_symbol_value (symbolP, 1);
+
+ /* Skip symbols which were equated to undefined or common
+ symbols. */
+ if (symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
+ {
+ *symbolPP = symbol_next (symbolP);
+ continue;
+ }
+
+ /* OK, here is how we decide which symbols go out into the brave
+ new symtab. Symbols that do are:
+
+ * symbols with no name (stabd's?)
+ * symbols with debug info in their N_TYPE
+
+ Symbols that don't are:
+ * symbols that are registers
+ * symbols with \1 as their 3rd character (numeric labels)
+ * "local labels" as defined by S_LOCAL_NAME(name) if the -L
+ switch was passed to gas.
+
+ All other symbols are output. We complain if a deleted
+ symbol was marked external. */
+
+
+ if (!S_IS_REGISTER (symbolP)
+ && (!S_GET_NAME (symbolP)
+ || S_IS_DEBUG (symbolP)
+ || !S_IS_DEFINED (symbolP)
+ || S_IS_EXTERNAL (symbolP)
+ || (S_GET_NAME (symbolP)[0] != '\001'
+ && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
+ {
+ symbolP->sy_number = symbol_number++;
+
+ /* The + 1 after strlen account for the \0 at the
+ end of each string */
+ if (!S_IS_STABD (symbolP))
+ {
+ /* Ordinary case. */
+ symbolP->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
+ }
+ else /* .Stabd case. */
+ symbolP->sy_name_offset = 0;
+ symbolPP = &(symbol_next (symbolP));
+ }
+ else
+ {
+ if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
+ /* This warning should never get triggered any more.
+ Well, maybe if you're doing twisted things with
+ register names... */
+ {
+ as_bad (_("Local symbol %s never defined."), decode_local_label_name (S_GET_NAME (symbolP)));
+ } /* oops. */
+
+ /* Unhook it from the chain */
+ *symbolPP = symbol_next (symbolP);
+ } /* if this symbol should be in the output */
+ } /* for each symbol */
+
+ H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
+}
+
+/*
+ * Find strings by crawling along symbol table chain.
+ */
+
+void
+obj_emit_strings (where)
+ char **where;
+{
+ symbolS *symbolP;
+
+#ifdef CROSS_COMPILE
+ /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
+ md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
+ *where += sizeof (string_byte_count);
+#else /* CROSS_COMPILE */
+ append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
+#endif /* CROSS_COMPILE */
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ if (S_GET_NAME (symbolP))
+ append (&next_object_file_charP, S_GET_NAME (symbolP),
+ (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
+ } /* walk symbol chain */
+}
+
+#ifndef AOUT_VERSION
+#define AOUT_VERSION 0
+#endif
+
+void
+obj_pre_write_hook (headers)
+ object_headers *headers;
+{
+ H_SET_DYNAMIC (headers, 0);
+ H_SET_VERSION (headers, AOUT_VERSION);
+ H_SET_MACHTYPE (headers, AOUT_MACHTYPE);
+ tc_aout_pre_write_hook (headers);
+}
+
+void
+DEFUN_VOID (s_sect)
+{
+ /* Strip out the section name */
+ char *section_name;
+ char *section_name_end;
+ char c;
+
+ unsigned int len;
+ unsigned int exp;
+ char *save;
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+ section_name_end = input_line_pointer;
+
+ len = section_name_end - section_name;
+ input_line_pointer++;
+ save = input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if (c == ',')
+ {
+ exp = get_absolute_expression ();
+ }
+ else if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ exp = get_absolute_expression ();
+ }
+ else
+ {
+ input_line_pointer = save;
+ exp = 0;
+ }
+ if (exp >= 1000)
+ {
+ as_bad (_("subsegment index too high"));
+ }
+
+ if (strcmp (section_name, ".text") == 0)
+ {
+ subseg_set (SEG_TEXT, (subsegT) exp);
+ }
+
+ if (strcmp (section_name, ".data") == 0)
+ {
+ if (flag_readonly_data_in_text)
+ subseg_set (SEG_TEXT, (subsegT) exp + 1000);
+ else
+ subseg_set (SEG_DATA, (subsegT) exp);
+ }
+
+ *section_name_end = c;
+}
+
+#endif /* ! BFD_ASSEMBLER */
+
+/* end of obj-aout.c */
diff --git a/gas/config/obj-aout.h b/gas/config/obj-aout.h
new file mode 100644
index 00000000000..339070e093c
--- /dev/null
+++ b/gas/config/obj-aout.h
@@ -0,0 +1,239 @@
+/* obj-aout.h, a.out object file format for gas, the assembler.
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Tag to validate a.out object file format processing */
+#define OBJ_AOUT 1
+
+#include "targ-cpu.h"
+
+#ifdef BFD_ASSEMBLER
+
+#include "bfd/libaout.h"
+
+#define OUTPUT_FLAVOR bfd_target_aout_flavour
+
+#else /* ! BFD_ASSEMBLER */
+
+#ifndef VMS
+#include "aout_gnu.h" /* Needed to define struct nlist. Sigh. */
+#else
+#include "a_out.h"
+#endif
+
+#ifndef AOUT_MACHTYPE
+#define AOUT_MACHTYPE 0
+#endif /* AOUT_MACHTYPE */
+
+extern const short seg_N_TYPE[];
+extern const segT N_TYPE_seg[];
+
+#ifndef DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (OMAGIC)
+#endif /* DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE */
+
+#endif /* ! BFD_ASSEMBLER */
+
+/* SYMBOL TABLE */
+/* Symbol table entry data type */
+
+typedef struct nlist obj_symbol_type; /* Symbol table entry */
+
+/* Symbol table macros and constants */
+
+#ifdef BFD_ASSEMBLER
+
+#define S_SET_OTHER(S,V) (aout_symbol((S)->bsym)->other = (V))
+#define S_SET_TYPE(S,T) (aout_symbol((S)->bsym)->type = (T))
+#define S_SET_DESC(S,D) (aout_symbol((S)->bsym)->desc = (D))
+#define S_GET_OTHER(S) (aout_symbol((S)->bsym)->other)
+#define S_GET_TYPE(S) (aout_symbol((S)->bsym)->type)
+#define S_GET_DESC(S) (aout_symbol((S)->bsym)->desc)
+
+asection *text_section, *data_section, *bss_section;
+
+#define obj_frob_symbol(S,PUNT) obj_aout_frob_symbol (S, &PUNT)
+#define obj_frob_file() obj_aout_frob_file ()
+extern void obj_aout_frob_symbol PARAMS ((struct symbol *, int *));
+extern void obj_aout_frob_file PARAMS ((void));
+
+#define obj_sec_sym_ok_for_reloc(SEC) (1)
+
+#else
+
+/* We use the sy_obj field to record whether a symbol is weak. */
+#define OBJ_SYMFIELD_TYPE char
+
+/*
+ * Macros to extract information from a symbol table entry.
+ * This syntaxic indirection allows independence regarding a.out or coff.
+ * The argument (s) of all these macros is a pointer to a symbol table entry.
+ */
+
+/* True if the symbol is external */
+#define S_IS_EXTERNAL(s) ((s)->sy_symbol.n_type & N_EXT)
+
+/* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */
+#define S_IS_DEFINED(s) \
+ (S_GET_TYPE (s) != N_UNDF || S_GET_DESC (s) != 0)
+
+#define S_IS_COMMON(s) \
+ (S_GET_TYPE (s) == N_UNDF && S_GET_VALUE (s) != 0)
+
+#define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER)
+
+/* True if a debug special symbol entry */
+#define S_IS_DEBUG(s) ((s)->sy_symbol.n_type & N_STAB)
+/* True if a symbol is local symbol name */
+#define S_IS_LOCAL(s) \
+ ((S_GET_NAME (s) \
+ && !S_IS_DEBUG (s) \
+ && (strchr (S_GET_NAME (s), '\001') != NULL \
+ || strchr (S_GET_NAME (s), '\002') != NULL \
+ || (S_LOCAL_NAME(s) && !flag_keep_locals))) \
+ || (flag_strip_local_absolute \
+ && ! S_IS_EXTERNAL(s) \
+ && S_GET_SEGMENT (s) == absolute_section))
+/* True if a symbol is not defined in this file */
+#define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT)
+/* True if the symbol has been generated because of a .stabd directive */
+#define S_IS_STABD(s) (S_GET_NAME(s) == (char *)0)
+
+/* Accessors */
+/* The name of the symbol */
+#define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name)
+/* The pointer to the string table */
+#define S_GET_OFFSET(s) ((s)->sy_symbol.n_un.n_strx)
+/* The type of the symbol */
+#define S_GET_TYPE(s) ((s)->sy_symbol.n_type & N_TYPE)
+/* The numeric value of the segment */
+#define S_GET_SEGMENT(s) (N_TYPE_seg[S_GET_TYPE(s)])
+/* The n_other expression value */
+#define S_GET_OTHER(s) ((s)->sy_symbol.n_other)
+/* The n_desc expression value */
+#define S_GET_DESC(s) ((s)->sy_symbol.n_desc)
+/* Whether the symbol is weak. */
+#define S_GET_WEAK(s) ((s)->sy_obj)
+
+/* Modifiers */
+/* Assume that a symbol cannot be simultaneously in more than on segment */
+/* set segment */
+#define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg))
+/* The symbol is external */
+#define S_SET_EXTERNAL(s) ((s)->sy_symbol.n_type |= N_EXT)
+/* The symbol is not external */
+#define S_CLEAR_EXTERNAL(s) ((s)->sy_symbol.n_type &= ~N_EXT)
+/* Set the name of the symbol */
+#define S_SET_NAME(s,v) ((s)->sy_symbol.n_un.n_name = (v))
+/* Set the offset in the string table */
+#define S_SET_OFFSET(s,v) ((s)->sy_symbol.n_un.n_strx = (v))
+/* Set the n_type field */
+#define S_SET_TYPE(s,t) ((s)->sy_symbol.n_type = (t))
+/* Set the n_other expression value */
+#define S_SET_OTHER(s,v) ((s)->sy_symbol.n_other = (v))
+/* Set the n_desc expression value */
+#define S_SET_DESC(s,v) ((s)->sy_symbol.n_desc = (v))
+/* Mark the symbol as weak. This causes n_type to be adjusted when
+ the symbol is written out. */
+#define S_SET_WEAK(s) ((s)->sy_obj = 1)
+
+/* File header macro and type definition */
+
+#define H_GET_FILE_SIZE(h) (H_GET_HEADER_SIZE(h) \
+ + H_GET_TEXT_SIZE(h) \
+ + H_GET_DATA_SIZE(h) \
+ + H_GET_SYMBOL_TABLE_SIZE(h) \
+ + H_GET_TEXT_RELOCATION_SIZE(h) \
+ + H_GET_DATA_RELOCATION_SIZE(h) \
+ + H_GET_STRING_SIZE(h))
+
+#define H_GET_HEADER_SIZE(h) (EXEC_BYTES_SIZE)
+#define H_GET_TEXT_SIZE(h) ((h)->header.a_text)
+#define H_GET_DATA_SIZE(h) ((h)->header.a_data)
+#define H_GET_BSS_SIZE(h) ((h)->header.a_bss)
+#define H_GET_TEXT_RELOCATION_SIZE(h) ((h)->header.a_trsize)
+#define H_GET_DATA_RELOCATION_SIZE(h) ((h)->header.a_drsize)
+#define H_GET_SYMBOL_TABLE_SIZE(h) ((h)->header.a_syms)
+#define H_GET_ENTRY_POINT(h) ((h)->header.a_entry)
+#define H_GET_STRING_SIZE(h) ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h) (0)
+
+#define H_GET_DYNAMIC(h) ((h)->header.a_info >> 31)
+#define H_GET_VERSION(h) (((h)->header.a_info >> 24) & 0x7f)
+#define H_GET_MACHTYPE(h) (((h)->header.a_info >> 16) & 0xff)
+#define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info & 0xffff)
+
+#define H_SET_DYNAMIC(h,v) ((h)->header.a_info = (((v) << 31) \
+ | (H_GET_VERSION(h) << 24) \
+ | (H_GET_MACHTYPE(h) << 16) \
+ | (H_GET_MAGIC_NUMBER(h))))
+
+#define H_SET_VERSION(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \
+ | ((v) << 24) \
+ | (H_GET_MACHTYPE(h) << 16) \
+ | (H_GET_MAGIC_NUMBER(h))))
+
+#define H_SET_MACHTYPE(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \
+ | (H_GET_VERSION(h) << 24) \
+ | ((v) << 16) \
+ | (H_GET_MAGIC_NUMBER(h))))
+
+#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \
+ | (H_GET_VERSION(h) << 24) \
+ | (H_GET_MACHTYPE(h) << 16) \
+ | ((v))))
+
+#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v)))
+#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v)))
+#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = md_section_align(SEG_BSS, (v)))
+
+#define H_SET_RELOCATION_SIZE(h,t,d) (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
+ H_SET_DATA_RELOCATION_SIZE((h),(d)))
+
+#define H_SET_TEXT_RELOCATION_SIZE(h,v) ((h)->header.a_trsize = (v))
+#define H_SET_DATA_RELOCATION_SIZE(h,v) ((h)->header.a_drsize = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * 12)
+
+#define H_SET_ENTRY_POINT(h,v) ((h)->header.a_entry = (v))
+#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v))
+
+typedef struct
+ {
+ struct exec header; /* a.out header */
+ long string_table_size; /* names + '\0' + sizeof(int) */
+ }
+
+object_headers;
+
+/* line numbering stuff. */
+#define OBJ_EMIT_LINENO(a, b, c) {;}
+
+struct fix;
+void tc_aout_fix_to_chars PARAMS ((char *where, struct fix *fixP, relax_addressT segment_address));
+
+#endif
+
+#define obj_symbol_new_hook(s) {;}
+
+#define EMIT_SECTION_SYMBOLS 0
+
+#define AOUT_STABS
+
+/* end of obj-aout.h */
diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c
new file mode 100644
index 00000000000..c9b80f5733f
--- /dev/null
+++ b/gas/config/obj-bout.c
@@ -0,0 +1,348 @@
+/* b.out object file format
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write
+ to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+#include "obstack.h"
+const short /* in: segT out: N_TYPE bits */
+ seg_N_TYPE[] =
+{
+ N_ABS,
+ N_TEXT,
+ N_DATA,
+ N_BSS,
+ N_UNDF, /* unknown */
+ N_UNDF, /* error */
+ N_UNDF, /* expression */
+ N_UNDF, /* debug */
+ N_UNDF, /* ntv */
+ N_UNDF, /* ptv */
+ N_REGISTER, /* register */
+};
+
+const segT N_TYPE_seg[N_TYPE + 2] =
+{ /* N_TYPE == 0x1E = 32-2 */
+ SEG_UNKNOWN, /* N_UNDF == 0 */
+ SEG_GOOF,
+ SEG_ABSOLUTE, /* N_ABS == 2 */
+ SEG_GOOF,
+ SEG_TEXT, /* N_TEXT == 4 */
+ SEG_GOOF,
+ SEG_DATA, /* N_DATA == 6 */
+ SEG_GOOF,
+ SEG_BSS, /* N_BSS == 8 */
+ SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
+ SEG_GOOF,
+};
+
+static void obj_bout_line PARAMS ((int));
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {"line", obj_bout_line, 0}, /* source code line number */
+
+/* coff debugging directives. Currently ignored silently */
+ {"def", s_ignore, 0},
+ {"dim", s_ignore, 0},
+ {"endef", s_ignore, 0},
+ {"ln", s_ignore, 0},
+ {"scl", s_ignore, 0},
+ {"size", s_ignore, 0},
+ {"tag", s_ignore, 0},
+ {"type", s_ignore, 0},
+ {"val", s_ignore, 0},
+
+/* other stuff we don't handle */
+ {"ABORT", s_ignore, 0},
+ {"ident", s_ignore, 0},
+
+ {NULL} /* end sentinel */
+}; /* obj_pseudo_table */
+
+/* Relocation. */
+
+/*
+ * emit_relocations()
+ *
+ * Crawl along a fixS chain. Emit the segment's relocations.
+ */
+void
+obj_emit_relocations (where, fixP, segment_address_in_file)
+ char **where;
+ fixS *fixP; /* Fixup chain for this segment. */
+ relax_addressT segment_address_in_file;
+{
+ for (; fixP; fixP = fixP->fx_next)
+ {
+ if (fixP->fx_done == 0
+ || fixP->fx_r_type != NO_RELOC)
+ {
+ symbolS *sym;
+
+ sym = fixP->fx_addsy;
+ while (sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ sym = sym->sy_value.X_add_symbol;
+ fixP->fx_addsy = sym;
+
+ tc_bout_fix_to_chars (*where, fixP, segment_address_in_file);
+ *where += sizeof (struct relocation_info);
+ } /* if there's a symbol */
+ } /* for each fixup */
+
+} /* emit_relocations() */
+
+/* Aout file generation & utilities */
+
+/* Convert a lvalue to machine dependent data */
+void
+obj_header_append (where, headers)
+ char **where;
+ object_headers *headers;
+{
+ /* Always leave in host byte order */
+
+ headers->header.a_talign = section_alignment[SEG_TEXT];
+
+ if (headers->header.a_talign < 2)
+ {
+ headers->header.a_talign = 2;
+ } /* force to at least 2 */
+
+ headers->header.a_dalign = section_alignment[SEG_DATA];
+ headers->header.a_balign = section_alignment[SEG_BSS];
+
+ headers->header.a_tload = 0;
+ headers->header.a_dload = md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers));
+
+ headers->header.a_relaxable = linkrelax;
+
+#ifdef CROSS_COMPILE
+ md_number_to_chars (*where, headers->header.a_magic, sizeof (headers->header.a_magic));
+ *where += sizeof (headers->header.a_magic);
+ md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
+ *where += sizeof (headers->header.a_text);
+ md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
+ *where += sizeof (headers->header.a_data);
+ md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
+ *where += sizeof (headers->header.a_bss);
+ md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
+ *where += sizeof (headers->header.a_syms);
+ md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
+ *where += sizeof (headers->header.a_entry);
+ md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
+ *where += sizeof (headers->header.a_trsize);
+ md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
+ *where += sizeof (headers->header.a_drsize);
+ md_number_to_chars (*where, headers->header.a_tload, sizeof (headers->header.a_tload));
+ *where += sizeof (headers->header.a_tload);
+ md_number_to_chars (*where, headers->header.a_dload, sizeof (headers->header.a_dload));
+ *where += sizeof (headers->header.a_dload);
+ md_number_to_chars (*where, headers->header.a_talign, sizeof (headers->header.a_talign));
+ *where += sizeof (headers->header.a_talign);
+ md_number_to_chars (*where, headers->header.a_dalign, sizeof (headers->header.a_dalign));
+ *where += sizeof (headers->header.a_dalign);
+ md_number_to_chars (*where, headers->header.a_balign, sizeof (headers->header.a_balign));
+ *where += sizeof (headers->header.a_balign);
+ md_number_to_chars (*where, headers->header.a_relaxable, sizeof (headers->header.a_relaxable));
+ *where += sizeof (headers->header.a_relaxable);
+#else /* ! CROSS_COMPILE */
+ append (where, (char *) &headers->header, sizeof (headers->header));
+#endif /* ! CROSS_COMPILE */
+} /* a_header_append() */
+
+void
+obj_symbol_to_chars (where, symbolP)
+ char **where;
+ symbolS *symbolP;
+{
+ md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP)));
+ md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP)));
+ md_number_to_chars ((char *) &symbolP->sy_symbol.n_value, S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value));
+
+ append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
+} /* obj_symbol_to_chars() */
+
+void
+obj_emit_symbols (where, symbol_rootP)
+ char **where;
+ symbolS *symbol_rootP;
+{
+ symbolS *symbolP;
+
+ /*
+ * Emit all symbols left in the symbol chain.
+ */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /* Used to save the offset of the name. It is used to point
+ to the string in memory but must be a file offset. */
+ char *temp;
+
+ temp = S_GET_NAME (symbolP);
+ S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
+
+ /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
+ if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
+ S_SET_EXTERNAL (symbolP);
+
+ obj_symbol_to_chars (where, symbolP);
+ S_SET_NAME (symbolP, temp);
+ }
+} /* emit_symbols() */
+
+void
+obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ S_SET_OTHER (symbolP, 0);
+ S_SET_DESC (symbolP, 0);
+}
+
+static void
+obj_bout_line (ignore)
+ int ignore;
+{
+ /* Assume delimiter is part of expression. */
+ /* BSD4.2 as fails with delightful bug, so we */
+ /* are not being incompatible here. */
+ new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
+ demand_empty_rest_of_line ();
+} /* obj_bout_line() */
+
+void
+obj_read_begin_hook ()
+{
+}
+
+void
+obj_crawl_symbol_chain (headers)
+ object_headers *headers;
+{
+ symbolS **symbolPP;
+ symbolS *symbolP;
+ int symbol_number = 0;
+
+ tc_crawl_symbol_chain (headers);
+
+ symbolPP = &symbol_rootP; /*->last symbol chain link. */
+ while ((symbolP = *symbolPP) != NULL)
+ {
+ if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
+ {
+ S_SET_SEGMENT (symbolP, SEG_TEXT);
+ } /* if pusing data into text */
+
+ resolve_symbol_value (symbolP, 1);
+
+ /* Skip symbols which were equated to undefined or common
+ symbols. */
+ if (symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
+ {
+ *symbolPP = symbol_next (symbolP);
+ continue;
+ }
+
+ /* OK, here is how we decide which symbols go out into the
+ brave new symtab. Symbols that do are:
+
+ * symbols with no name (stabd's?)
+ * symbols with debug info in their N_TYPE
+
+ Symbols that don't are:
+ * symbols that are registers
+ * symbols with \1 as their 3rd character (numeric labels)
+ * "local labels" as defined by S_LOCAL_NAME(name)
+ if the -L switch was passed to gas.
+
+ All other symbols are output. We complain if a deleted
+ symbol was marked external. */
+
+
+ if (1
+ && !S_IS_REGISTER (symbolP)
+ && (!S_GET_NAME (symbolP)
+ || S_IS_DEBUG (symbolP)
+#ifdef TC_I960
+ /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */
+ || !S_IS_DEFINED (symbolP)
+ || S_IS_EXTERNAL (symbolP)
+#endif /* TC_I960 */
+ || (S_GET_NAME (symbolP)[0] != '\001' && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
+ {
+ symbolP->sy_number = symbol_number++;
+
+ /* The + 1 after strlen account for the \0 at the
+ end of each string */
+ if (!S_IS_STABD (symbolP))
+ {
+ /* Ordinary case. */
+ symbolP->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
+ }
+ else /* .Stabd case. */
+ symbolP->sy_name_offset = 0;
+ symbolPP = &(symbol_next (symbolP));
+ }
+ else
+ {
+ if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
+ {
+ as_bad (_("Local symbol %s never defined"), S_GET_NAME (symbolP));
+ } /* oops. */
+
+ /* Unhook it from the chain */
+ *symbolPP = symbol_next (symbolP);
+ } /* if this symbol should be in the output */
+ } /* for each symbol */
+
+ H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
+}
+
+/*
+ * Find strings by crawling along symbol table chain.
+ */
+
+void
+obj_emit_strings (where)
+ char **where;
+{
+ symbolS *symbolP;
+
+#ifdef CROSS_COMPILE
+ /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
+ md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
+ *where += sizeof (string_byte_count);
+#else /* CROSS_COMPILE */
+ append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
+#endif /* CROSS_COMPILE */
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ if (S_GET_NAME (symbolP))
+ append (where, S_GET_NAME (symbolP), (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
+ } /* walk symbol chain */
+}
+
+/* end of obj-bout.c */
diff --git a/gas/config/obj-bout.h b/gas/config/obj-bout.h
new file mode 100644
index 00000000000..ec539a0cf44
--- /dev/null
+++ b/gas/config/obj-bout.h
@@ -0,0 +1,316 @@
+/* b.out object file format
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write
+ to the Free Software Foundation, 59 Temple Place - Suite 330, Cambridge, MA
+ 02139, USA. */
+
+/*
+ * This file is a modified version of 'a.out.h'. It is to be used in all GNU
+ * tools modified to support the i80960 b.out format (or tools that operate on
+ * object files created by such tools).
+ *
+ * All i80960 development is done in a CROSS-DEVELOPMENT environment. I.e.,
+ * object code is generated on, and executed under the direction of a symbolic
+ * debugger running on, a host system. We do not want to be subject to the
+ * vagaries of which host it is or whether it supports COFF or a.out format, or
+ * anything else. We DO want to:
+ *
+ * o always generate the same format object files, regardless of host.
+ *
+ * o have an 'a.out' header that we can modify for our own purposes
+ * (the 80960 is typically an embedded processor and may require
+ * enhanced linker support that the normal a.out.h header can't
+ * accommodate).
+ *
+ * As for byte-ordering, the following rules apply:
+ *
+ * o Text and data that is actually downloaded to the target is always
+ * in i80960 (little-endian) order.
+ *
+ * o All other numbers (in the header, symbols, relocation directives)
+ * are in host byte-order: object files CANNOT be lifted from a
+ * little-end host and used on a big-endian (or vice versa) without
+ * modification.
+ * ==> THIS IS NO LONGER TRUE USING BFD. WE CAN GENERATE ANY BYTE ORDER
+ * FOR THE HEADER, AND READ ANY BYTE ORDER. PREFERENCE WOULD BE TO
+ * USE LITTLE-ENDIAN BYTE ORDER THROUGHOUT, REGARDLESS OF HOST. <==
+ *
+ * o The downloader ('comm960') takes care to generate a pseudo-header
+ * with correct (i80960) byte-ordering before shipping text and data
+ * off to the NINDY monitor in the target systems. Symbols and
+ * relocation info are never sent to the target.
+ */
+
+
+#define OBJ_BOUT 1
+
+#define OUTPUT_FLAVOR bfd_target_aout_flavour
+
+#include "targ-cpu.h"
+
+#define OBJ_DEFAULT_OUTPUT_FILE_NAME "b.out"
+
+extern const short seg_N_TYPE[];
+extern const segT N_TYPE_seg[];
+
+#define BMAGIC 0415
+/* We don't accept the following (see N_BADMAG macro).
+ * They're just here so GNU code will compile.
+ */
+#define OMAGIC 0407 /* old impure format */
+#define NMAGIC 0410 /* read-only text */
+#define ZMAGIC 0413 /* demand load format */
+
+#ifndef DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (BMAGIC)
+#endif /* DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE */
+
+/* FILE HEADER
+ * All 'lengths' are given as a number of bytes.
+ * All 'alignments' are for relinkable files only; an alignment of
+ * 'n' indicates the corresponding segment must begin at an
+ * address that is a multiple of (2**n).
+ */
+struct exec
+ {
+ /* Standard stuff */
+ unsigned long a_magic; /* Identifies this as a b.out file */
+ unsigned long a_text; /* Length of text */
+ unsigned long a_data; /* Length of data */
+ unsigned long a_bss; /* Length of runtime uninitialized data area */
+ unsigned long a_syms; /* Length of symbol table */
+ unsigned long a_entry; /* Runtime start address */
+ unsigned long a_trsize; /* Length of text relocation info */
+ unsigned long a_drsize; /* Length of data relocation info */
+
+ /* Added for i960 */
+ unsigned long a_tload; /* Text runtime load address */
+ unsigned long a_dload; /* Data runtime load address */
+ unsigned char a_talign; /* Alignment of text segment */
+ unsigned char a_dalign; /* Alignment of data segment */
+ unsigned char a_balign; /* Alignment of bss segment */
+ unsigned char a_relaxable; /* Contains enough info to relax */
+ };
+
+#define N_BADMAG(x) (((x).a_magic)!=BMAGIC)
+#define N_TXTOFF(x) ( sizeof(struct exec) )
+#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data )
+#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize )
+#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize )
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+
+/* A single entry in the symbol table
+ */
+struct nlist
+ {
+ union
+ {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx; /* Index into string table */
+ }
+ n_un;
+ unsigned char n_type; /* See below */
+ char n_other; /* Used in i80960 support -- see below */
+ short n_desc;
+ unsigned long n_value;
+ };
+
+typedef struct nlist obj_symbol_type;
+
+/* Legal values of n_type
+ */
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol */
+#define N_TEXT 4 /* Text symbol */
+#define N_DATA 6 /* Data symbol */
+#define N_BSS 8 /* BSS symbol */
+#define N_FN 31 /* Filename symbol */
+
+#define N_EXT 1 /* External symbol (OR'd in with one of above) */
+#define N_TYPE 036 /* Mask for all the type bits */
+#define N_STAB 0340 /* Mask for all bits used for SDB entries */
+
+#ifndef CUSTOM_RELOC_FORMAT
+struct relocation_info
+ {
+ int r_address; /* File address of item to be relocated */
+ unsigned
+ r_index:24, /* Index of symbol on which relocation is based*/
+ r_pcrel:1, /* 1 => relocate PC-relative; else absolute
+ * On i960, pc-relative implies 24-bit
+ * address, absolute implies 32-bit.
+ */
+ r_length:2, /* Number of bytes to relocate:
+ * 0 => 1 byte
+ * 1 => 2 bytes
+ * 2 => 4 bytes -- only value used for i960
+ */
+ r_extern:1, r_bsr:1, /* Something for the GNU NS32K assembler */
+ r_disp:1, /* Something for the GNU NS32K assembler */
+ r_callj:1, /* 1 if relocation target is an i960 'callj' */
+ nuthin:1; /* Unused */
+ };
+
+#endif /* CUSTOM_RELOC_FORMAT */
+
+/*
+ * Macros to extract information from a symbol table entry.
+ * This syntaxic indirection allows independence regarding a.out or coff.
+ * The argument (s) of all these macros is a pointer to a symbol table entry.
+ */
+
+/* Predicates */
+/* True if the symbol is external */
+#define S_IS_EXTERNAL(s) ((s)->sy_symbol.n_type & N_EXT)
+
+/* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */
+#define S_IS_DEFINED(s) ((S_GET_TYPE(s) != N_UNDF) || (S_GET_DESC(s) != 0))
+
+#define S_IS_COMMON(s) \
+ (S_GET_TYPE (s) == N_UNDF && S_GET_VALUE (s) != 0)
+
+#define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER)
+
+/* True if a debug special symbol entry */
+#define S_IS_DEBUG(s) ((s)->sy_symbol.n_type & N_STAB)
+/* True if a symbol is local symbol name */
+#define S_IS_LOCAL(s) \
+ ((S_GET_NAME (s) \
+ && !S_IS_DEBUG (s) \
+ && (strchr (S_GET_NAME (s), '\001') != NULL \
+ || strchr (S_GET_NAME (s), '\002') != NULL \
+ || (S_LOCAL_NAME(s) && !flag_keep_locals))) \
+ || (flag_strip_local_absolute \
+ && !S_IS_EXTERNAL(s) \
+ && S_GET_SEGMENT(s) == absolute_section))
+/* True if a symbol is not defined in this file */
+#define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT)
+/* True if the symbol has been generated because of a .stabd directive */
+#define S_IS_STABD(s) (S_GET_NAME(s) == NULL)
+
+/* Accessors */
+/* The name of the symbol */
+#define S_GET_NAME(s) ((s)->sy_symbol.n_un.n_name)
+/* The pointer to the string table */
+#define S_GET_OFFSET(s) ((s)->sy_symbol.n_un.n_strx)
+/* The type of the symbol */
+#define S_GET_TYPE(s) ((s)->sy_symbol.n_type & N_TYPE)
+/* The numeric value of the segment */
+#define S_GET_SEGMENT(s) (N_TYPE_seg[S_GET_TYPE(s)])
+/* The n_other expression value */
+#define S_GET_OTHER(s) ((s)->sy_symbol.n_other)
+/* The n_desc expression value */
+#define S_GET_DESC(s) ((s)->sy_symbol.n_desc)
+
+/* Modifiers */
+/* Assume that a symbol cannot be simultaneously in more than on segment */
+/* set segment */
+#define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg))
+/* The symbol is external */
+#define S_SET_EXTERNAL(s) ((s)->sy_symbol.n_type |= N_EXT)
+/* The symbol is not external */
+#define S_CLEAR_EXTERNAL(s) ((s)->sy_symbol.n_type &= ~N_EXT)
+/* Set the name of the symbol */
+#define S_SET_NAME(s,v) ((s)->sy_symbol.n_un.n_name = (v))
+/* Set the offset in the string table */
+#define S_SET_OFFSET(s,v) ((s)->sy_symbol.n_un.n_strx = (v))
+/* Set the n_other expression value */
+#define S_SET_OTHER(s,v) ((s)->sy_symbol.n_other = (v))
+/* Set the n_desc expression value */
+#define S_SET_DESC(s,v) ((s)->sy_symbol.n_desc = (v))
+/* Set the n_type value */
+#define S_SET_TYPE(s,v) ((s)->sy_symbol.n_type = (v))
+
+/* File header macro and type definition */
+
+#define H_GET_FILE_SIZE(h) (sizeof(struct exec) + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_SYMBOL_TABLE_SIZE(h) + \
+ H_GET_TEXT_RELOCATION_SIZE(h) + \
+ H_GET_DATA_RELOCATION_SIZE(h) + \
+ (h)->string_table_size)
+
+#define H_GET_HEADER_SIZE(h) (sizeof(struct exec))
+#define H_GET_TEXT_SIZE(h) ((h)->header.a_text)
+#define H_GET_DATA_SIZE(h) ((h)->header.a_data)
+#define H_GET_BSS_SIZE(h) ((h)->header.a_bss)
+#define H_GET_TEXT_RELOCATION_SIZE(h) ((h)->header.a_trsize)
+#define H_GET_DATA_RELOCATION_SIZE(h) ((h)->header.a_drsize)
+#define H_GET_SYMBOL_TABLE_SIZE(h) ((h)->header.a_syms)
+#define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info)
+#define H_GET_ENTRY_POINT(h) ((h)->header.a_entry)
+#define H_GET_STRING_SIZE(h) ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h) (0)
+
+#ifdef EXEC_MACHINE_TYPE
+#define H_GET_MACHINE_TYPE(h) ((h)->header.a_machtype)
+#endif /* EXEC_MACHINE_TYPE */
+#ifdef EXEC_VERSION
+#define H_GET_VERSION(h) ((h)->header.a_version)
+#endif /* EXEC_VERSION */
+
+#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = (v))
+#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = (v))
+#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = (v))
+
+#define H_SET_RELOCATION_SIZE(h,t,d) (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
+ H_SET_DATA_RELOCATION_SIZE((h),(d)))
+
+#define H_SET_TEXT_RELOCATION_SIZE(h,v) ((h)->header.a_trsize = (v))
+#define H_SET_DATA_RELOCATION_SIZE(h,v) ((h)->header.a_drsize = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * \
+ sizeof(struct nlist))
+
+#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_magic = (v))
+
+#define H_SET_ENTRY_POINT(h,v) ((h)->header.a_entry = (v))
+#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v))
+#ifdef EXEC_MACHINE_TYPE
+#define H_SET_MACHINE_TYPE(h,v) ((h)->header.a_machtype = (v))
+#endif /* EXEC_MACHINE_TYPE */
+#ifdef EXEC_VERSION
+#define H_SET_VERSION(h,v) ((h)->header.a_version = (v))
+#endif /* EXEC_VERSION */
+
+typedef struct
+ {
+ struct exec header; /* a.out header */
+ long string_table_size; /* names + '\0' + sizeof(int) */
+ }
+
+object_headers;
+
+/* unused hooks. */
+#define OBJ_EMIT_LINENO(a, b, c) {;}
+#define obj_pre_write_hook(a) {;}
+
+#if __STDC__
+struct fix;
+#endif
+extern void tc_aout_fix_to_chars PARAMS ((char *where,
+ struct fix *fixP,
+ relax_addressT segment_address));
+extern void tc_bout_fix_to_chars PARAMS ((char *where,
+ struct fix *fixP,
+ relax_addressT segment_address));
+
+#define AOUT_STABS
+
+/* end of obj-bout.h */
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
new file mode 100644
index 00000000000..5639fbed966
--- /dev/null
+++ b/gas/config/obj-coff.c
@@ -0,0 +1,4482 @@
+/* coff object file format
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-coff.h"
+
+#include "as.h"
+#include "obstack.h"
+#include "subsegs.h"
+
+/* I think this is probably always correct. */
+#ifndef KEEP_RELOC_INFO
+#define KEEP_RELOC_INFO
+#endif
+
+static void obj_coff_bss PARAMS ((int));
+const char *s_get_name PARAMS ((symbolS * s));
+static symbolS *def_symbol_in_progress;
+
+
+/* stack stuff */
+typedef struct
+ {
+ unsigned long chunk_size;
+ unsigned long element_size;
+ unsigned long size;
+ char *data;
+ unsigned long pointer;
+ }
+stack;
+
+static stack *
+stack_init (chunk_size, element_size)
+ unsigned long chunk_size;
+ unsigned long element_size;
+{
+ stack *st;
+
+ st = (stack *) malloc (sizeof (stack));
+ if (!st)
+ return 0;
+ st->data = malloc (chunk_size);
+ if (!st->data)
+ {
+ free (st);
+ return 0;
+ }
+ st->pointer = 0;
+ st->size = chunk_size;
+ st->chunk_size = chunk_size;
+ st->element_size = element_size;
+ return st;
+}
+
+#if 0
+/* Not currently used. */
+static void
+stack_delete (st)
+ stack *st;
+{
+ free (st->data);
+ free (st);
+}
+#endif
+
+static char *
+stack_push (st, element)
+ stack *st;
+ char *element;
+{
+ if (st->pointer + st->element_size >= st->size)
+ {
+ st->size += st->chunk_size;
+ if ((st->data = xrealloc (st->data, st->size)) == (char *) 0)
+ return (char *) 0;
+ }
+ memcpy (st->data + st->pointer, element, st->element_size);
+ st->pointer += st->element_size;
+ return st->data + st->pointer;
+}
+
+static char *
+stack_pop (st)
+ stack *st;
+{
+ if (st->pointer < st->element_size)
+ {
+ st->pointer = 0;
+ return (char *) 0;
+ }
+ st->pointer -= st->element_size;
+ return st->data + st->pointer;
+}
+
+/*
+ * Maintain a list of the tagnames of the structres.
+ */
+
+static struct hash_control *tag_hash;
+
+static void
+tag_init ()
+{
+ tag_hash = hash_new ();
+}
+
+static void
+tag_insert (name, symbolP)
+ const char *name;
+ symbolS *symbolP;
+{
+ const char *error_string;
+
+ if ((error_string = hash_jam (tag_hash, name, (char *) symbolP)))
+ {
+ as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
+ name, error_string);
+ }
+}
+
+static symbolS *
+tag_find (name)
+ char *name;
+{
+#ifdef STRIP_UNDERSCORE
+ if (*name == '_')
+ name++;
+#endif /* STRIP_UNDERSCORE */
+ return (symbolS *) hash_find (tag_hash, name);
+}
+
+static symbolS *
+tag_find_or_make (name)
+ char *name;
+{
+ symbolS *symbolP;
+
+ if ((symbolP = tag_find (name)) == NULL)
+ {
+ symbolP = symbol_new (name, undefined_section,
+ 0, &zero_address_frag);
+
+ tag_insert (S_GET_NAME (symbolP), symbolP);
+#ifdef BFD_ASSEMBLER
+ symbol_table_insert (symbolP);
+#endif
+ } /* not found */
+
+ return symbolP;
+}
+
+/* We accept the .bss directive to set the section for backward
+ compatibility with earlier versions of gas. */
+
+static void
+obj_coff_bss (ignore)
+ int ignore;
+{
+ if (*input_line_pointer == '\n')
+ subseg_new (".bss", get_absolute_expression ());
+ else
+ s_lcomm (0);
+}
+
+/* Handle .weak. This is a GNU extension. */
+
+static void
+obj_coff_weak (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+#ifdef BFD_ASSEMLER
+ S_SET_WEAK (symbolP);
+#endif
+
+#ifdef TE_PE
+ S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
+#else
+ S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
+#endif
+
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
+
+#ifdef BFD_ASSEMBLER
+
+static void SA_SET_SYM_TAGNDX PARAMS ((symbolS *, symbolS *));
+
+#define GET_FILENAME_STRING(X) \
+((char*)(&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1])
+
+/* @@ Ick. */
+static segT
+fetch_coff_debug_section ()
+{
+ static segT debug_section;
+ if (!debug_section)
+ {
+ CONST asymbol *s;
+ s = bfd_make_debug_symbol (stdoutput, (char *) 0, 0);
+ assert (s != 0);
+ debug_section = s->section;
+ }
+ return debug_section;
+}
+
+void
+SA_SET_SYM_ENDNDX (sym, val)
+ symbolS *sym;
+ symbolS *val;
+{
+ combined_entry_type *entry, *p;
+
+ entry = &coffsymbol (sym->bsym)->native[1];
+ p = coffsymbol (val->bsym)->native;
+ entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
+ entry->fix_end = 1;
+}
+
+static void
+SA_SET_SYM_TAGNDX (sym, val)
+ symbolS *sym;
+ symbolS *val;
+{
+ combined_entry_type *entry, *p;
+
+ entry = &coffsymbol (sym->bsym)->native[1];
+ p = coffsymbol (val->bsym)->native;
+ entry->u.auxent.x_sym.x_tagndx.p = p;
+ entry->fix_tag = 1;
+}
+
+static int
+S_GET_DATA_TYPE (sym)
+ symbolS *sym;
+{
+ return coffsymbol (sym->bsym)->native->u.syment.n_type;
+}
+
+int
+S_SET_DATA_TYPE (sym, val)
+ symbolS *sym;
+ int val;
+{
+ coffsymbol (sym->bsym)->native->u.syment.n_type = val;
+ return val;
+}
+
+int
+S_GET_STORAGE_CLASS (sym)
+ symbolS *sym;
+{
+ return coffsymbol (sym->bsym)->native->u.syment.n_sclass;
+}
+
+int
+S_SET_STORAGE_CLASS (sym, val)
+ symbolS *sym;
+ int val;
+{
+ coffsymbol (sym->bsym)->native->u.syment.n_sclass = val;
+ return val;
+}
+
+/* Merge a debug symbol containing debug information into a normal symbol. */
+
+void
+c_symbol_merge (debug, normal)
+ symbolS *debug;
+ symbolS *normal;
+{
+ S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
+ S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
+ {
+ /* take the most we have */
+ S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+ }
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > 0)
+ {
+ /* Move all the auxiliary information. */
+ memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
+ (S_GET_NUMBER_AUXILIARY (debug)
+ * sizeof (*SYM_AUXINFO (debug))));
+ }
+
+ /* Move the debug flags. */
+ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
+}
+
+void
+c_dot_file_symbol (filename)
+ char *filename;
+{
+ symbolS *symbolP;
+
+ symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag);
+
+ S_SET_STORAGE_CLASS (symbolP, C_FILE);
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ symbolP->bsym->flags = BSF_DEBUGGING;
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+ if (listing)
+ {
+ listing_source_file (filename);
+ }
+ }
+#endif
+
+ /* Make sure that the symbol is first on the symbol chain */
+ if (symbol_rootP != symbolP)
+ {
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
+ } /* if not first on the list */
+}
+
+/* Line number handling */
+
+struct line_no {
+ struct line_no *next;
+ fragS *frag;
+ alent l;
+};
+
+int coff_line_base;
+
+/* Symbol of last function, which we should hang line#s off of. */
+static symbolS *line_fsym;
+
+#define in_function() (line_fsym != 0)
+#define clear_function() (line_fsym = 0)
+#define set_function(F) (line_fsym = (F), coff_add_linesym (F))
+
+
+void
+coff_obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
+ char * s = (char *) xmalloc (sz);
+
+ memset (s, 0, sz);
+ coffsymbol (symbolP->bsym)->native = (combined_entry_type *) s;
+
+ S_SET_DATA_TYPE (symbolP, T_NULL);
+ S_SET_STORAGE_CLASS (symbolP, 0);
+ S_SET_NUMBER_AUXILIARY (symbolP, 0);
+
+ if (S_IS_STRING (symbolP))
+ SF_SET_STRING (symbolP);
+
+ if (S_IS_LOCAL (symbolP))
+ SF_SET_LOCAL (symbolP);
+}
+
+
+/*
+ * Handle .ln directives.
+ */
+
+static symbolS *current_lineno_sym;
+static struct line_no *line_nos;
+/* @@ Blindly assume all .ln directives will be in the .text section... */
+int coff_n_line_nos;
+
+static void
+add_lineno (frag, offset, num)
+ fragS *frag;
+ int offset;
+ int num;
+{
+ struct line_no *new_line =
+ (struct line_no *) xmalloc (sizeof (struct line_no));
+ if (!current_lineno_sym)
+ {
+ abort ();
+ }
+ new_line->next = line_nos;
+ new_line->frag = frag;
+ new_line->l.line_number = num;
+ new_line->l.u.offset = offset;
+ line_nos = new_line;
+ coff_n_line_nos++;
+}
+
+void
+coff_add_linesym (sym)
+ symbolS *sym;
+{
+ if (line_nos)
+ {
+ coffsymbol (current_lineno_sym->bsym)->lineno = (alent *) line_nos;
+ coff_n_line_nos++;
+ line_nos = 0;
+ }
+ current_lineno_sym = sym;
+}
+
+static void
+obj_coff_ln (appline)
+ int appline;
+{
+ int l;
+
+ if (! appline && def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ l = get_absolute_expression ();
+ if (!appline)
+ {
+ add_lineno (frag_now, frag_now_fix (), l);
+ }
+
+ if (appline)
+ new_logical_line ((char *) NULL, l - 1);
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+
+ if (listing)
+ {
+ if (! appline)
+ l += coff_line_base - 1;
+ listing_source_line (l);
+ }
+ }
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * def()
+ *
+ * Handle .def directives.
+ *
+ * One might ask : why can't we symbol_new if the symbol does not
+ * already exist and fill it with debug information. Because of
+ * the C_EFCN special symbol. It would clobber the value of the
+ * function symbol before we have a chance to notice that it is
+ * a C_EFCN. And a second reason is that the code is more clear this
+ * way. (at least I think it is :-).
+ *
+ */
+
+#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
+#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
+ *input_line_pointer == '\t') \
+ input_line_pointer++;
+
+static void
+obj_coff_def (what)
+ int what;
+{
+ char name_end; /* Char after the end of name */
+ char *symbol_name; /* Name of the debug symbol */
+ char *symbol_name_copy; /* Temporary copy of the name */
+ unsigned int symbol_name_length;
+
+ if (def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ SKIP_WHITESPACES ();
+
+ symbol_name = input_line_pointer;
+#ifdef STRIP_UNDERSCORE
+ if (symbol_name[0] == '_' && symbol_name[1] != 0)
+ symbol_name++;
+#endif /* STRIP_UNDERSCORE */
+
+ name_end = get_symbol_end ();
+ symbol_name_length = strlen (symbol_name);
+ symbol_name_copy = xmalloc (symbol_name_length + 1);
+ strcpy (symbol_name_copy, symbol_name);
+#ifdef tc_canonicalize_symbol_name
+ symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
+#endif
+
+ /* Initialize the new symbol */
+ def_symbol_in_progress = symbol_make (symbol_name_copy);
+ def_symbol_in_progress->sy_frag = &zero_address_frag;
+ S_SET_VALUE (def_symbol_in_progress, 0);
+
+ if (S_IS_STRING (def_symbol_in_progress))
+ SF_SET_STRING (def_symbol_in_progress);
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+unsigned int dim_index;
+
+static void
+obj_coff_endef (ignore)
+ int ignore;
+{
+ symbolS *symbolP;
+
+ /* DIM BUG FIX sac@cygnus.com */
+ dim_index = 0;
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ /* Set the section number according to storage class. */
+ switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
+ {
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_UNTAG:
+ SF_SET_TAG (def_symbol_in_progress);
+ /* intentional fallthrough */
+ case C_FILE:
+ case C_TPDEF:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
+ break;
+
+ case C_EFCN:
+ SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
+ /* intentional fallthrough */
+ case C_BLOCK:
+ SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
+ /* intentional fallthrough */
+ case C_FCN:
+ {
+ CONST char *name;
+ S_SET_SEGMENT (def_symbol_in_progress, text_section);
+
+ name = bfd_asymbol_name (def_symbol_in_progress->bsym);
+ if (name[1] == 'b' && name[2] == 'f')
+ {
+ if (! in_function ())
+ as_warn (_("`%s' symbol without preceding function"), name);
+/* SA_SET_SYM_LNNO (def_symbol_in_progress, 12345);*/
+ /* Will need relocating */
+ SF_SET_PROCESS (def_symbol_in_progress);
+ clear_function ();
+ }
+ }
+ break;
+
+#ifdef C_AUTOARG
+ case C_AUTOARG:
+#endif /* C_AUTOARG */
+ case C_AUTO:
+ case C_REG:
+ case C_ARG:
+ case C_REGPARM:
+ case C_FIELD:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
+ break;
+
+ case C_MOS:
+ case C_MOE:
+ case C_MOU:
+ case C_EOS:
+ S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
+ break;
+
+ case C_EXT:
+ case C_WEAKEXT:
+#ifdef TE_PE
+ case C_NT_WEAK:
+#endif
+ case C_STAT:
+ case C_LABEL:
+ /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+ break;
+
+ default:
+ case C_USTATIC:
+ case C_EXTDEF:
+ case C_ULABEL:
+ as_warn (_("unexpected storage class %d"),
+ S_GET_STORAGE_CLASS (def_symbol_in_progress));
+ break;
+ } /* switch on storage class */
+
+ /* Now that we have built a debug symbol, try to find if we should
+ merge with an existing symbol or not. If a symbol is C_EFCN or
+ SEG_ABSOLUTE or untagged SEG_DEBUG it never merges. */
+
+ /* Two cases for functions. Either debug followed by definition or
+ definition followed by debug. For definition first, we will
+ merge the debug symbol into the definition. For debug first, the
+ lineno entry MUST point to the definition function or else it
+ will point off into space when obj_crawl_symbol_chain() merges
+ the debug symbol into the real symbol. Therefor, let's presume
+ the debug symbol is a real function reference. */
+
+ /* FIXME-SOON If for some reason the definition label/symbol is
+ never seen, this will probably leave an undefined symbol at link
+ time. */
+
+ if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
+ || (!strcmp (bfd_get_section_name (stdoutput,
+ S_GET_SEGMENT (def_symbol_in_progress)),
+ "*DEBUG*")
+ && !SF_GET_TAG (def_symbol_in_progress))
+ || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
+ || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL)
+ {
+ if (def_symbol_in_progress != symbol_lastP)
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+ &symbol_lastP);
+ }
+ else
+ {
+ /* This symbol already exists, merge the newly created symbol
+ into the old one. This is not mandatory. The linker can
+ handle duplicate symbols correctly. But I guess that it save
+ a *lot* of space if the assembly file defines a lot of
+ symbols. [loic] */
+
+ /* The debug entry (def_symbol_in_progress) is merged into the
+ previous definition. */
+
+ c_symbol_merge (def_symbol_in_progress, symbolP);
+ symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+
+ def_symbol_in_progress = symbolP;
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress)
+ || SF_GET_TAG (def_symbol_in_progress)
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
+ {
+ /* For functions, and tags, and static symbols, the symbol
+ *must* be where the debug symbol appears. Move the
+ existing symbol to the current place. */
+ /* If it already is at the end of the symbol list, do nothing */
+ if (def_symbol_in_progress != symbol_lastP)
+ {
+ symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+ }
+ }
+ }
+
+ if (SF_GET_TAG (def_symbol_in_progress))
+ {
+ symbolS *oldtag;
+
+ oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
+ DO_NOT_STRIP);
+ if (oldtag == NULL || ! SF_GET_TAG (oldtag))
+ tag_insert (S_GET_NAME (def_symbol_in_progress),
+ def_symbol_in_progress);
+ }
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress))
+ {
+ know (sizeof (def_symbol_in_progress) <= sizeof (long));
+ set_function (def_symbol_in_progress);
+ SF_SET_PROCESS (def_symbol_in_progress);
+
+ if (symbolP == NULL)
+ {
+ /* That is, if this is the first time we've seen the
+ function... */
+ symbol_table_insert (def_symbol_in_progress);
+ } /* definition follows debug */
+ } /* Create the line number entry pointing to the function being defined */
+
+ def_symbol_in_progress = NULL;
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_dim (ignore)
+ int ignore;
+{
+ int dim_index;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+
+ for (dim_index = 0; dim_index < DIMNUM; dim_index++)
+ {
+ SKIP_WHITESPACES ();
+ SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
+ get_absolute_expression ());
+
+ switch (*input_line_pointer)
+ {
+ case ',':
+ input_line_pointer++;
+ break;
+
+ default:
+ as_warn (_("badly formed .dim directive ignored"));
+ /* intentional fallthrough */
+ case '\n':
+ case ';':
+ dim_index = DIMNUM;
+ break;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_line (ignore)
+ int ignore;
+{
+ int this_base;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ /* Probably stabs-style line? */
+ obj_coff_ln (0);
+ return;
+ }
+
+ this_base = get_absolute_expression ();
+ if (!strcmp (".bf", S_GET_NAME (def_symbol_in_progress)))
+ coff_line_base = this_base;
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_LNNO (def_symbol_in_progress, coff_line_base);
+
+ demand_empty_rest_of_line ();
+
+#ifndef NO_LISTING
+ if (strcmp (".bf", S_GET_NAME (def_symbol_in_progress)) == 0)
+ {
+ extern int listing;
+
+ if (listing)
+ listing_source_line ((unsigned int) coff_line_base);
+ }
+#endif
+}
+
+static void
+obj_coff_size (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_scl (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_tag (ignore)
+ int ignore;
+{
+ char *symbol_name;
+ char name_end;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
+ /* Assume that the symbol referred to by .tag is always defined.
+ This was a bad assumption. I've added find_or_make. xoxorich. */
+ SA_SET_SYM_TAGNDX (def_symbol_in_progress,
+ tag_find_or_make (symbol_name));
+ if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
+ {
+ as_warn (_("tag not found for .tag %s"), symbol_name);
+ } /* not defined */
+
+ SF_SET_TAGGED (def_symbol_in_progress);
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_type (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
+
+ if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
+ S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
+ {
+ SF_SET_FUNCTION (def_symbol_in_progress);
+ } /* is a function */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_val (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *symbol_name = input_line_pointer;
+ char name_end = get_symbol_end ();
+
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+ if (!strcmp (symbol_name, "."))
+ {
+ def_symbol_in_progress->sy_frag = frag_now;
+ S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
+ /* If the .val is != from the .def (e.g. statics) */
+ }
+ else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
+ {
+ def_symbol_in_progress->sy_value.X_op = O_symbol;
+ def_symbol_in_progress->sy_value.X_add_symbol =
+ symbol_find_or_make (symbol_name);
+ def_symbol_in_progress->sy_value.X_op_symbol = NULL;
+ def_symbol_in_progress->sy_value.X_add_number = 0;
+
+ /* If the segment is undefined when the forward reference is
+ resolved, then copy the segment id from the forward
+ symbol. */
+ SF_SET_GET_SEGMENT (def_symbol_in_progress);
+ }
+ /* Otherwise, it is the name of a non debug symbol and its value will be calculated later. */
+ *input_line_pointer = name_end;
+ }
+ else
+ {
+ S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
+ } /* if symbol based */
+
+ demand_empty_rest_of_line ();
+}
+
+void
+coff_obj_read_begin_hook ()
+{
+ /* These had better be the same. Usually 18 bytes. */
+#ifndef BFD_HEADERS
+ know (sizeof (SYMENT) == sizeof (AUXENT));
+ know (SYMESZ == AUXESZ);
+#endif
+ tag_init ();
+}
+
+
+symbolS *coff_last_function;
+static symbolS *coff_last_bf;
+
+void
+coff_frob_symbol (symp, punt)
+ symbolS *symp;
+ int *punt;
+{
+ static symbolS *last_tagP;
+ static stack *block_stack;
+ static symbolS *set_end;
+ symbolS *next_set_end = NULL;
+
+ if (symp == &abs_symbol)
+ {
+ *punt = 1;
+ return;
+ }
+
+ if (current_lineno_sym)
+ coff_add_linesym ((symbolS *) 0);
+
+ if (!block_stack)
+ block_stack = stack_init (512, sizeof (symbolS*));
+
+ if (S_IS_WEAK (symp))
+ {
+#ifdef TE_PE
+ S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
+#else
+ S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
+#endif
+ }
+
+ if (!S_IS_DEFINED (symp)
+ && !S_IS_WEAK (symp)
+ && S_GET_STORAGE_CLASS (symp) != C_STAT)
+ S_SET_STORAGE_CLASS (symp, C_EXT);
+
+ if (!SF_GET_DEBUG (symp))
+ {
+ symbolS *real;
+ if (!SF_GET_LOCAL (symp)
+ && !SF_GET_STATICS (symp)
+ && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
+ && real != symp)
+ {
+ c_symbol_merge (symp, real);
+ *punt = 1;
+ }
+ if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
+ {
+ assert (S_GET_VALUE (symp) == 0);
+ S_SET_EXTERNAL (symp);
+ }
+ else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
+ {
+ if (S_GET_SEGMENT (symp) == text_section
+ && symp != seg_info (text_section)->sym)
+ S_SET_STORAGE_CLASS (symp, C_LABEL);
+ else
+ S_SET_STORAGE_CLASS (symp, C_STAT);
+ }
+ if (SF_GET_PROCESS (symp))
+ {
+ if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
+ {
+ if (!strcmp (S_GET_NAME (symp), ".bb"))
+ stack_push (block_stack, (char *) &symp);
+ else
+ {
+ symbolS *begin;
+ begin = *(symbolS **) stack_pop (block_stack);
+ if (begin == 0)
+ as_warn (_("mismatched .eb"));
+ else
+ next_set_end = begin;
+ }
+ }
+ if (coff_last_function == 0 && SF_GET_FUNCTION (symp))
+ {
+ union internal_auxent *auxp;
+ coff_last_function = symp;
+ if (S_GET_NUMBER_AUXILIARY (symp) < 1)
+ S_SET_NUMBER_AUXILIARY (symp, 1);
+ auxp = &coffsymbol (symp->bsym)->native[1].u.auxent;
+ memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0,
+ sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen));
+ }
+ if (S_GET_STORAGE_CLASS (symp) == C_EFCN)
+ {
+ if (coff_last_function == 0)
+ as_fatal (_("C_EFCN symbol out of scope"));
+ SA_SET_SYM_FSIZE (coff_last_function,
+ (long) (S_GET_VALUE (symp)
+ - S_GET_VALUE (coff_last_function)));
+ next_set_end = coff_last_function;
+ coff_last_function = 0;
+ }
+ }
+ if (S_IS_EXTERNAL (symp))
+ S_SET_STORAGE_CLASS (symp, C_EXT);
+ else if (SF_GET_LOCAL (symp))
+ *punt = 1;
+
+ if (SF_GET_FUNCTION (symp))
+ symp->bsym->flags |= BSF_FUNCTION;
+
+ /* more ... */
+ }
+
+ if (SF_GET_TAG (symp))
+ last_tagP = symp;
+ else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
+ next_set_end = last_tagP;
+
+#ifdef OBJ_XCOFF
+ /* This is pretty horrible, but we have to set *punt correctly in
+ order to call SA_SET_SYM_ENDNDX correctly. */
+ if (! symp->sy_used_in_reloc
+ && ((symp->bsym->flags & BSF_SECTION_SYM) != 0
+ || (! S_IS_EXTERNAL (symp)
+ && ! symp->sy_tc.output
+ && S_GET_STORAGE_CLASS (symp) != C_FILE)))
+ *punt = 1;
+#endif
+
+ if (set_end != (symbolS *) NULL
+ && ! *punt
+ && ((symp->bsym->flags & BSF_NOT_AT_END) != 0
+ || (S_IS_DEFINED (symp)
+ && ! S_IS_COMMON (symp)
+ && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
+ {
+ SA_SET_SYM_ENDNDX (set_end, symp);
+ set_end = NULL;
+ }
+
+ if (next_set_end != NULL
+ && ! *punt)
+ set_end = next_set_end;
+
+ if (! *punt
+ && S_GET_STORAGE_CLASS (symp) == C_FCN
+ && strcmp (S_GET_NAME (symp), ".bf") == 0)
+ {
+ if (coff_last_bf != NULL)
+ SA_SET_SYM_ENDNDX (coff_last_bf, symp);
+ coff_last_bf = symp;
+ }
+
+ if (coffsymbol (symp->bsym)->lineno)
+ {
+ int i;
+ struct line_no *lptr;
+ alent *l;
+
+ lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
+ for (i = 0; lptr; lptr = lptr->next)
+ i++;
+ lptr = (struct line_no *) coffsymbol (symp->bsym)->lineno;
+
+ /* We need i entries for line numbers, plus 1 for the first
+ entry which BFD will override, plus 1 for the last zero
+ entry (a marker for BFD). */
+ l = (alent *) xmalloc ((i + 2) * sizeof (alent));
+ coffsymbol (symp->bsym)->lineno = l;
+ l[i + 1].line_number = 0;
+ l[i + 1].u.sym = NULL;
+ for (; i > 0; i--)
+ {
+ if (lptr->frag)
+ lptr->l.u.offset += lptr->frag->fr_address;
+ l[i] = lptr->l;
+ lptr = lptr->next;
+ }
+ }
+}
+
+void
+coff_adjust_section_syms (abfd, sec, x)
+ bfd *abfd;
+ asection *sec;
+ PTR x;
+{
+ symbolS *secsym;
+ segment_info_type *seginfo = seg_info (sec);
+ int nlnno, nrelocs = 0;
+
+ /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
+ tc-ppc.c. Do not get confused by it. */
+ if (seginfo == NULL)
+ return;
+
+ if (!strcmp (sec->name, ".text"))
+ nlnno = coff_n_line_nos;
+ else
+ nlnno = 0;
+ {
+ /* @@ Hope that none of the fixups expand to more than one reloc
+ entry... */
+ fixS *fixp = seginfo->fix_root;
+ while (fixp)
+ {
+ if (! fixp->fx_done)
+ nrelocs++;
+ fixp = fixp->fx_next;
+ }
+ }
+ if (bfd_get_section_size_before_reloc (sec) == 0
+ && nrelocs == 0
+ && nlnno == 0
+ && sec != text_section
+ && sec != data_section
+ && sec != bss_section)
+ return;
+ secsym = section_symbol (sec);
+ SA_SET_SCN_NRELOC (secsym, nrelocs);
+ SA_SET_SCN_NLINNO (secsym, nlnno);
+}
+
+void
+coff_frob_file_after_relocs ()
+{
+ bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0);
+}
+
+/*
+ * implement the .section pseudo op:
+ * .section name {, "flags"}
+ * ^ ^
+ * | +--- optional flags: 'b' for bss
+ * | 'i' for info
+ * +-- section name 'l' for lib
+ * 'n' for noload
+ * 'o' for over
+ * 'w' for data
+ * 'd' (apparently m88k for data)
+ * 'x' for text
+ * 'r' for read-only data
+ * But if the argument is not a quoted string, treat it as a
+ * subsegment number.
+ */
+
+void
+obj_coff_section (ignore)
+ int ignore;
+{
+ /* Strip out the section name */
+ char *section_name;
+ char c;
+ char *name;
+ unsigned int exp;
+ flagword flags;
+ asection *sec;
+
+ if (flag_mri)
+ {
+ char type;
+
+ s_mri_sect (&type);
+ return;
+ }
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - section_name + 1);
+ strcpy (name, section_name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ exp = 0;
+ flags = SEC_NO_FLAGS;
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ exp = get_absolute_expression ();
+ else
+ {
+ ++input_line_pointer;
+ while (*input_line_pointer != '"'
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ switch (*input_line_pointer)
+ {
+ case 'b': flags |= SEC_ALLOC; flags &=~ SEC_LOAD; break;
+ case 'n': flags &=~ SEC_LOAD; break;
+ case 'd':
+ case 'w': flags &=~ SEC_READONLY; break;
+ case 'x': flags |= SEC_CODE; break;
+ case 'r': flags |= SEC_READONLY; break;
+
+ case 'i': /* STYP_INFO */
+ case 'l': /* STYP_LIB */
+ case 'o': /* STYP_OVER */
+ as_warn (_("unsupported section attribute '%c'"),
+ *input_line_pointer);
+ break;
+
+ default:
+ as_warn(_("unknown section attribute '%c'"),
+ *input_line_pointer);
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+ }
+ }
+
+ sec = subseg_new (name, (subsegT) exp);
+
+ if (flags != SEC_NO_FLAGS)
+ {
+ flagword oldflags;
+
+ oldflags = bfd_get_section_flags (stdoutput, sec);
+ oldflags &= SEC_LINK_ONCE | SEC_LINK_DUPLICATES;
+ flags |= oldflags;
+
+ if (! bfd_set_section_flags (stdoutput, sec, flags))
+ as_warn (_("error setting flags for \"%s\": %s"),
+ bfd_section_name (stdoutput, sec),
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+coff_adjust_symtab ()
+{
+ if (symbol_rootP == NULL
+ || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
+ c_dot_file_symbol ("fake");
+}
+
+void
+coff_frob_section (sec)
+ segT sec;
+{
+ segT strsec;
+ char *p;
+ fragS *fragp;
+ bfd_vma size, n_entries, mask;
+
+ /* The COFF back end in BFD requires that all section sizes be
+ rounded up to multiples of the corresponding section alignments.
+ Seems kinda silly to me, but that's the way it is. */
+ size = bfd_get_section_size_before_reloc (sec);
+ mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1;
+ if (size & mask)
+ {
+ size = (size + mask) & ~mask;
+ bfd_set_section_size (stdoutput, sec, size);
+ }
+
+ /* If the section size is non-zero, the section symbol needs an aux
+ entry associated with it, indicating the size. We don't know
+ all the values yet; coff_frob_symbol will fill them in later. */
+ if (size != 0
+ || sec == text_section
+ || sec == data_section
+ || sec == bss_section)
+ {
+ symbolS *secsym = section_symbol (sec);
+
+ S_SET_STORAGE_CLASS (secsym, C_STAT);
+ S_SET_NUMBER_AUXILIARY (secsym, 1);
+ SF_SET_STATICS (secsym);
+ SA_SET_SCN_SCNLEN (secsym, size);
+ }
+
+ /* @@ these should be in a "stabs.h" file, or maybe as.h */
+#ifndef STAB_SECTION_NAME
+#define STAB_SECTION_NAME ".stab"
+#endif
+#ifndef STAB_STRING_SECTION_NAME
+#define STAB_STRING_SECTION_NAME ".stabstr"
+#endif
+ if (strcmp (STAB_STRING_SECTION_NAME, sec->name))
+ return;
+
+ strsec = sec;
+ sec = subseg_get (STAB_SECTION_NAME, 0);
+ /* size is already rounded up, since other section will be listed first */
+ size = bfd_get_section_size_before_reloc (strsec);
+
+ n_entries = bfd_get_section_size_before_reloc (sec) / 12 - 1;
+
+ /* Find first non-empty frag. It should be large enough. */
+ fragp = seg_info (sec)->frchainP->frch_root;
+ while (fragp && fragp->fr_fix == 0)
+ fragp = fragp->fr_next;
+ assert (fragp != 0 && fragp->fr_fix >= 12);
+
+ /* Store the values. */
+ p = fragp->fr_literal;
+ bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6);
+ bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8);
+}
+
+void
+obj_coff_init_stab_section (seg)
+ segT seg;
+{
+ char *file;
+ char *p;
+ char *stabstr_name;
+ unsigned int stroff;
+
+ /* Make space for this first symbol. */
+ p = frag_more (12);
+ /* Zero it out. */
+ memset (p, 0, 12);
+ as_where (&file, (unsigned int *) NULL);
+ stabstr_name = (char *) alloca (strlen (seg->name) + 4);
+ strcpy (stabstr_name, seg->name);
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+}
+
+#ifdef DEBUG
+/* for debugging */
+const char *
+s_get_name (s)
+ symbolS *s;
+{
+ return ((s == NULL) ? "(NULL)" : S_GET_NAME (s));
+}
+
+void
+symbol_dump ()
+{
+ symbolS *symbolP;
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ printf(_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
+ (unsigned long) symbolP,
+ S_GET_NAME(symbolP),
+ (long) S_GET_DATA_TYPE(symbolP),
+ S_GET_STORAGE_CLASS(symbolP),
+ (int) S_GET_SEGMENT(symbolP));
+ }
+}
+
+#endif /* DEBUG */
+
+#else /* not BFD_ASSEMBLER */
+
+#include "frags.h"
+/* This is needed because we include internal bfd things. */
+#include <time.h>
+
+#include "libbfd.h"
+#include "libcoff.h"
+
+#ifdef TE_PE
+#include "coff/pe.h"
+#endif
+
+/* The NOP_OPCODE is for the alignment fill value. Fill with nop so
+ that we can stick sections together without causing trouble. */
+#ifndef NOP_OPCODE
+#define NOP_OPCODE 0x00
+#endif
+
+/* The zeroes if symbol name is longer than 8 chars */
+#define S_SET_ZEROES(s,v) ((s)->sy_symbol.ost_entry.n_zeroes = (v))
+
+#define MIN(a,b) ((a) < (b)? (a) : (b))
+/* This vector is used to turn an internal segment into a section #
+ suitable for insertion into a coff symbol table
+ */
+
+const short seg_N_TYPE[] =
+{ /* in: segT out: N_TYPE bits */
+ C_ABS_SECTION,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ C_UNDEF_SECTION, /* SEG_UNKNOWN */
+ C_UNDEF_SECTION, /* SEG_GOOF */
+ C_UNDEF_SECTION, /* SEG_EXPR */
+ C_DEBUG_SECTION, /* SEG_DEBUG */
+ C_NTV_SECTION, /* SEG_NTV */
+ C_PTV_SECTION, /* SEG_PTV */
+ C_REGISTER_SECTION, /* SEG_REGISTER */
+};
+
+int function_lineoff = -1; /* Offset in line#s where the last function
+ started (the odd entry for line #0) */
+
+/* structure used to keep the filenames which
+ are too long around so that we can stick them
+ into the string table */
+struct filename_list
+{
+ char *filename;
+ struct filename_list *next;
+};
+
+static struct filename_list *filename_list_head;
+static struct filename_list *filename_list_tail;
+
+static symbolS *last_line_symbol;
+
+/* Add 4 to the real value to get the index and compensate the
+ negatives. This vector is used by S_GET_SEGMENT to turn a coff
+ section number into a segment number
+*/
+static symbolS *previous_file_symbol;
+void c_symbol_merge ();
+static int line_base;
+
+symbolS *c_section_symbol ();
+bfd *abfd;
+
+static void fixup_segment PARAMS ((segment_info_type *segP,
+ segT this_segment_type));
+
+
+static void fixup_mdeps PARAMS ((fragS *,
+ object_headers *,
+ segT));
+
+
+static void fill_section PARAMS ((bfd * abfd,
+ object_headers *,
+ unsigned long *));
+
+
+static int c_line_new PARAMS ((symbolS * symbol, long paddr,
+ int line_number,
+ fragS * frag));
+
+
+static void w_symbols PARAMS ((bfd * abfd, char *where,
+ symbolS * symbol_rootP));
+
+static void adjust_stab_section PARAMS ((bfd *abfd, segT seg));
+
+static void obj_coff_lcomm PARAMS ((int));
+static void obj_coff_text PARAMS ((int));
+static void obj_coff_data PARAMS ((int));
+static void obj_coff_ident PARAMS ((int));
+void obj_coff_section PARAMS ((int));
+
+/* Section stuff
+
+ We allow more than just the standard 3 sections, infact, we allow
+ 40 sections, (though the usual three have to be there).
+
+ This structure performs the mappings for us:
+*/
+
+
+typedef struct
+{
+ segT seg_t;
+ int i;
+} seg_info_type;
+
+static const seg_info_type seg_info_off_by_4[] =
+{
+ {SEG_PTV, },
+ {SEG_NTV, },
+ {SEG_DEBUG, },
+ {SEG_ABSOLUTE, },
+ {SEG_UNKNOWN, },
+ {SEG_E0}, {SEG_E1}, {SEG_E2}, {SEG_E3}, {SEG_E4},
+ {SEG_E5}, {SEG_E6}, {SEG_E7}, {SEG_E8}, {SEG_E9},
+ {SEG_E10},{SEG_E11},{SEG_E12},{SEG_E13},{SEG_E14},
+ {SEG_E15},{SEG_E16},{SEG_E17},{SEG_E18},{SEG_E19},
+ {SEG_E20},{SEG_E21},{SEG_E22},{SEG_E23},{SEG_E24},
+ {SEG_E25},{SEG_E26},{SEG_E27},{SEG_E28},{SEG_E29},
+ {SEG_E30},{SEG_E31},{SEG_E32},{SEG_E33},{SEG_E34},
+ {SEG_E35},{SEG_E36},{SEG_E37},{SEG_E38},{SEG_E39},
+ {(segT)40},
+ {(segT)41},
+ {(segT)42},
+ {(segT)43},
+ {(segT)44},
+ {(segT)45},
+ {(segT)0},
+ {(segT)0},
+ {(segT)0},
+ {SEG_REGISTER}
+};
+
+
+
+#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
+
+static relax_addressT
+relax_align (address, alignment)
+ relax_addressT address;
+ long alignment;
+{
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~((~0) << alignment);
+ new_address = (address + mask) & (~mask);
+ return (new_address - address);
+}
+
+
+segT
+s_get_segment (x)
+ symbolS * x;
+{
+ return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum).seg_t;
+}
+
+/* calculate the size of the frag chain and fill in the section header
+ to contain all of it, also fill in the addr of the sections */
+static unsigned int
+size_section (abfd, idx)
+ bfd * abfd;
+ unsigned int idx;
+{
+
+ unsigned int size = 0;
+ fragS *frag = segment_info[idx].frchainP->frch_root;
+ while (frag)
+ {
+ size = frag->fr_address;
+ if (frag->fr_address != size)
+ {
+ fprintf (stderr, _("Out of step\n"));
+ size = frag->fr_address;
+ }
+
+ switch (frag->fr_type)
+ {
+#ifdef TC_COFF_SIZEMACHDEP
+ case rs_machine_dependent:
+ size += TC_COFF_SIZEMACHDEP (frag);
+ break;
+#endif
+ case rs_space:
+ assert (frag->fr_symbol == 0);
+ case rs_fill:
+ case rs_org:
+ size += frag->fr_fix;
+ size += frag->fr_offset * frag->fr_var;
+ break;
+ case rs_align:
+ case rs_align_code:
+ {
+ addressT off;
+
+ size += frag->fr_fix;
+ off = relax_align (size, frag->fr_offset);
+ if (frag->fr_subtype != 0 && off > frag->fr_subtype)
+ off = 0;
+ size += off;
+ }
+ break;
+ default:
+ BAD_CASE (frag->fr_type);
+ break;
+ }
+ frag = frag->fr_next;
+ }
+ segment_info[idx].scnhdr.s_size = size;
+ return size;
+}
+
+
+static unsigned int
+count_entries_in_chain (idx)
+ unsigned int idx;
+{
+ unsigned int nrelocs;
+ fixS *fixup_ptr;
+
+ /* Count the relocations */
+ fixup_ptr = segment_info[idx].fix_root;
+ nrelocs = 0;
+ while (fixup_ptr != (fixS *) NULL)
+ {
+ if (fixup_ptr->fx_done == 0 && TC_COUNT_RELOC (fixup_ptr))
+ {
+#ifdef TC_A29K
+ if (fixup_ptr->fx_r_type == RELOC_CONSTH)
+ nrelocs += 2;
+ else
+ nrelocs++;
+#else
+ nrelocs++;
+#endif
+ }
+
+ fixup_ptr = fixup_ptr->fx_next;
+ }
+ return nrelocs;
+}
+
+#ifdef TE_AUX
+
+static int compare_external_relocs PARAMS ((const PTR, const PTR));
+
+/* AUX's ld expects relocations to be sorted */
+static int
+compare_external_relocs (x, y)
+ const PTR x;
+ const PTR y;
+{
+ struct external_reloc *a = (struct external_reloc *) x;
+ struct external_reloc *b = (struct external_reloc *) y;
+ bfd_vma aadr = bfd_getb32 (a->r_vaddr);
+ bfd_vma badr = bfd_getb32 (b->r_vaddr);
+ return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
+}
+
+#endif
+
+/* output all the relocations for a section */
+void
+do_relocs_for (abfd, h, file_cursor)
+ bfd * abfd;
+ object_headers * h;
+ unsigned long *file_cursor;
+{
+ unsigned int nrelocs;
+ unsigned int idx;
+ unsigned long reloc_start = *file_cursor;
+
+ for (idx = SEG_E0; idx < SEG_LAST; idx++)
+ {
+ if (segment_info[idx].scnhdr.s_name[0])
+ {
+ struct external_reloc *ext_ptr;
+ struct external_reloc *external_reloc_vec;
+ unsigned int external_reloc_size;
+ unsigned int base = segment_info[idx].scnhdr.s_paddr;
+ fixS *fix_ptr = segment_info[idx].fix_root;
+ nrelocs = count_entries_in_chain (idx);
+
+ if (nrelocs)
+ /* Bypass this stuff if no relocs. This also incidentally
+ avoids a SCO bug, where free(malloc(0)) tends to crash. */
+ {
+ external_reloc_size = nrelocs * RELSZ;
+ external_reloc_vec =
+ (struct external_reloc *) malloc (external_reloc_size);
+
+ ext_ptr = external_reloc_vec;
+
+ /* Fill in the internal coff style reloc struct from the
+ internal fix list. */
+ while (fix_ptr)
+ {
+ struct internal_reloc intr;
+
+ /* Only output some of the relocations */
+ if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr))
+ {
+#ifdef TC_RELOC_MANGLE
+ TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr,
+ base);
+
+#else
+ symbolS *dot;
+ symbolS *symbol_ptr = fix_ptr->fx_addsy;
+
+ intr.r_type = TC_COFF_FIX2RTYPE (fix_ptr);
+ intr.r_vaddr =
+ base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
+
+#ifdef TC_KEEP_FX_OFFSET
+ intr.r_offset = fix_ptr->fx_offset;
+#else
+ intr.r_offset = 0;
+#endif
+
+ while (symbol_ptr->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbol_ptr)
+ || S_IS_COMMON (symbol_ptr)))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur
+ with a badly written program. */
+ n = symbol_ptr->sy_value.X_add_symbol;
+ if (n == symbol_ptr)
+ break;
+ symbol_ptr = n;
+ }
+
+ /* Turn the segment of the symbol into an offset. */
+ if (symbol_ptr)
+ {
+ resolve_symbol_value (symbol_ptr, 1);
+ if (! symbol_ptr->sy_resolved)
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (symbol_ptr, &file, &line))
+ as_bad_where (file, line,
+ _("unresolved relocation"));
+ else
+ as_bad (_("bad relocation: symbol `%s' not in symbol table"),
+ S_GET_NAME (symbol_ptr));
+ }
+ dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
+ if (dot)
+ {
+ intr.r_symndx = dot->sy_number;
+ }
+ else
+ {
+ intr.r_symndx = symbol_ptr->sy_number;
+ }
+
+ }
+ else
+ {
+ intr.r_symndx = -1;
+ }
+#endif
+
+ (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
+ ext_ptr++;
+
+#if defined(TC_A29K)
+
+ /* The 29k has a special kludge for the high 16 bit
+ reloc. Two relocations are emited, R_IHIHALF,
+ and R_IHCONST. The second one doesn't contain a
+ symbol, but uses the value for offset. */
+
+ if (intr.r_type == R_IHIHALF)
+ {
+ /* now emit the second bit */
+ intr.r_type = R_IHCONST;
+ intr.r_symndx = fix_ptr->fx_addnumber;
+ (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr);
+ ext_ptr++;
+ }
+#endif
+ }
+
+ fix_ptr = fix_ptr->fx_next;
+ }
+
+#ifdef TE_AUX
+ /* Sort the reloc table */
+ qsort ((PTR) external_reloc_vec, nrelocs,
+ sizeof (struct external_reloc), compare_external_relocs);
+#endif
+
+ /* Write out the reloc table */
+ bfd_write ((PTR) external_reloc_vec, 1, external_reloc_size,
+ abfd);
+ free (external_reloc_vec);
+
+ /* Fill in section header info. */
+ segment_info[idx].scnhdr.s_relptr = *file_cursor;
+ *file_cursor += external_reloc_size;
+ segment_info[idx].scnhdr.s_nreloc = nrelocs;
+ }
+ else
+ {
+ /* No relocs */
+ segment_info[idx].scnhdr.s_relptr = 0;
+ }
+ }
+ }
+ /* Set relocation_size field in file headers */
+ H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0);
+}
+
+
+/* run through a frag chain and write out the data to go with it, fill
+ in the scnhdrs with the info on the file postions
+*/
+static void
+fill_section (abfd, h, file_cursor)
+ bfd * abfd;
+ object_headers *h;
+ unsigned long *file_cursor;
+{
+
+ unsigned int i;
+ unsigned int paddr = 0;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ unsigned int offset = 0;
+ struct internal_scnhdr *s = &(segment_info[i].scnhdr);
+
+ PROGRESS (1);
+
+ if (s->s_name[0])
+ {
+ fragS *frag = segment_info[i].frchainP->frch_root;
+ char *buffer;
+
+ if (s->s_size == 0)
+ s->s_scnptr = 0;
+ else
+ {
+ buffer = xmalloc (s->s_size);
+ s->s_scnptr = *file_cursor;
+ }
+ know (s->s_paddr == paddr);
+
+ if (strcmp (s->s_name, ".text") == 0)
+ s->s_flags |= STYP_TEXT;
+ else if (strcmp (s->s_name, ".data") == 0)
+ s->s_flags |= STYP_DATA;
+ else if (strcmp (s->s_name, ".bss") == 0)
+ {
+ s->s_scnptr = 0;
+ s->s_flags |= STYP_BSS;
+
+ /* @@ Should make the i386 and a29k coff targets define
+ COFF_NOLOAD_PROBLEM, and have only one test here. */
+#ifndef TC_I386
+#ifndef TC_A29K
+#ifndef COFF_NOLOAD_PROBLEM
+ /* Apparently the SVR3 linker (and exec syscall) and UDI
+ mondfe progrem are confused by noload sections. */
+ s->s_flags |= STYP_NOLOAD;
+#endif
+#endif
+#endif
+ }
+ else if (strcmp (s->s_name, ".lit") == 0)
+ s->s_flags = STYP_LIT | STYP_TEXT;
+ else if (strcmp (s->s_name, ".init") == 0)
+ s->s_flags |= STYP_TEXT;
+ else if (strcmp (s->s_name, ".fini") == 0)
+ s->s_flags |= STYP_TEXT;
+ else if (strncmp (s->s_name, ".comment", 8) == 0)
+ s->s_flags |= STYP_INFO;
+
+ while (frag)
+ {
+ unsigned int fill_size;
+ switch (frag->fr_type)
+ {
+ case rs_machine_dependent:
+ if (frag->fr_fix)
+ {
+ memcpy (buffer + frag->fr_address,
+ frag->fr_literal,
+ (unsigned int) frag->fr_fix);
+ offset += frag->fr_fix;
+ }
+
+ break;
+ case rs_space:
+ assert (frag->fr_symbol == 0);
+ case rs_fill:
+ case rs_align:
+ case rs_align_code:
+ case rs_org:
+ if (frag->fr_fix)
+ {
+ memcpy (buffer + frag->fr_address,
+ frag->fr_literal,
+ (unsigned int) frag->fr_fix);
+ offset += frag->fr_fix;
+ }
+
+ fill_size = frag->fr_var;
+ if (fill_size && frag->fr_offset > 0)
+ {
+ unsigned int count;
+ unsigned int off = frag->fr_fix;
+ for (count = frag->fr_offset; count; count--)
+ {
+ if (fill_size + frag->fr_address + off <= s->s_size)
+ {
+ memcpy (buffer + frag->fr_address + off,
+ frag->fr_literal + frag->fr_fix,
+ fill_size);
+ off += fill_size;
+ offset += fill_size;
+ }
+ }
+ }
+ break;
+ case rs_broken_word:
+ break;
+ default:
+ abort ();
+ }
+ frag = frag->fr_next;
+ }
+
+ if (s->s_size != 0)
+ {
+ if (s->s_scnptr != 0)
+ {
+ bfd_write (buffer, s->s_size, 1, abfd);
+ *file_cursor += s->s_size;
+ }
+ free (buffer);
+ }
+ paddr += s->s_size;
+ }
+ }
+}
+
+/* Coff file generation & utilities */
+
+static void
+coff_header_append (abfd, h)
+ bfd * abfd;
+ object_headers * h;
+{
+ unsigned int i;
+ char buffer[1000];
+ char buffero[1000];
+#ifdef COFF_LONG_SECTION_NAMES
+ unsigned long string_size = 4;
+#endif
+
+ bfd_seek (abfd, 0, 0);
+
+#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
+ H_SET_MAGIC_NUMBER (h, COFF_MAGIC);
+ H_SET_VERSION_STAMP (h, 0);
+ H_SET_ENTRY_POINT (h, 0);
+ H_SET_TEXT_START (h, segment_info[SEG_E0].frchainP->frch_root->fr_address);
+ H_SET_DATA_START (h, segment_info[SEG_E1].frchainP->frch_root->fr_address);
+ H_SET_SIZEOF_OPTIONAL_HEADER (h, bfd_coff_swap_aouthdr_out(abfd, &h->aouthdr,
+ buffero));
+#else /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
+ H_SET_SIZEOF_OPTIONAL_HEADER (h, 0);
+#endif /* defined (OBJ_COFF_OMIT_OPTIONAL_HEADER) */
+
+ i = bfd_coff_swap_filehdr_out (abfd, &h->filehdr, buffer);
+
+ bfd_write (buffer, i, 1, abfd);
+ bfd_write (buffero, H_GET_SIZEOF_OPTIONAL_HEADER (h), 1, abfd);
+
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0])
+ {
+ unsigned int size;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code
+ must coordinate with that in write_object_file and
+ w_strings. */
+ if (strlen (segment_info[i].name) > SCNNMLEN)
+ {
+ memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
+ sprintf (segment_info[i].scnhdr.s_name, "/%lu", string_size);
+ string_size += strlen (segment_info[i].name) + 1;
+ }
+#endif
+
+ size = bfd_coff_swap_scnhdr_out (abfd,
+ &(segment_info[i].scnhdr),
+ buffer);
+ if (size == 0)
+ as_bad (_("bfd_coff_swap_scnhdr_out failed"));
+ bfd_write (buffer, size, 1, abfd);
+ }
+ }
+}
+
+
+char *
+symbol_to_chars (abfd, where, symbolP)
+ bfd * abfd;
+ char *where;
+ symbolS * symbolP;
+{
+ unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
+ unsigned int i;
+ valueT val;
+
+ /* Turn any symbols with register attributes into abs symbols */
+ if (S_GET_SEGMENT (symbolP) == reg_section)
+ {
+ S_SET_SEGMENT (symbolP, absolute_section);
+ }
+ /* At the same time, relocate all symbols to their output value */
+
+#ifndef TE_PE
+ val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
+ + S_GET_VALUE (symbolP));
+#else
+ val = S_GET_VALUE (symbolP);
+#endif
+
+ S_SET_VALUE (symbolP, val);
+
+ symbolP->sy_symbol.ost_entry.n_value = val;
+
+ where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
+ where);
+
+ for (i = 0; i < numaux; i++)
+ {
+ where += bfd_coff_swap_aux_out (abfd,
+ &symbolP->sy_symbol.ost_auxent[i],
+ S_GET_DATA_TYPE (symbolP),
+ S_GET_STORAGE_CLASS (symbolP),
+ i, numaux, where);
+ }
+ return where;
+
+}
+
+void
+coff_obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ char underscore = 0; /* Symbol has leading _ */
+
+ /* Effective symbol */
+ /* Store the pointer in the offset. */
+ S_SET_ZEROES (symbolP, 0L);
+ S_SET_DATA_TYPE (symbolP, T_NULL);
+ S_SET_STORAGE_CLASS (symbolP, 0);
+ S_SET_NUMBER_AUXILIARY (symbolP, 0);
+ /* Additional information */
+ symbolP->sy_symbol.ost_flags = 0;
+ /* Auxiliary entries */
+ memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ);
+
+ if (S_IS_STRING (symbolP))
+ SF_SET_STRING (symbolP);
+ if (!underscore && S_IS_LOCAL (symbolP))
+ SF_SET_LOCAL (symbolP);
+}
+
+/*
+ * Handle .ln directives.
+ */
+
+static void
+obj_coff_ln (appline)
+ int appline;
+{
+ int l;
+
+ if (! appline && def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* wrong context */
+
+ l = get_absolute_expression ();
+ c_line_new (0, frag_now_fix (), l, frag_now);
+
+ if (appline)
+ new_logical_line ((char *) NULL, l - 1);
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+
+ if (listing)
+ {
+ if (! appline)
+ l += line_base - 1;
+ listing_source_line ((unsigned int) l);
+ }
+
+ }
+#endif
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * def()
+ *
+ * Handle .def directives.
+ *
+ * One might ask : why can't we symbol_new if the symbol does not
+ * already exist and fill it with debug information. Because of
+ * the C_EFCN special symbol. It would clobber the value of the
+ * function symbol before we have a chance to notice that it is
+ * a C_EFCN. And a second reason is that the code is more clear this
+ * way. (at least I think it is :-).
+ *
+ */
+
+#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
+#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
+ *input_line_pointer == '\t') \
+ input_line_pointer++;
+
+static void
+obj_coff_def (what)
+ int what;
+{
+ char name_end; /* Char after the end of name */
+ char *symbol_name; /* Name of the debug symbol */
+ char *symbol_name_copy; /* Temporary copy of the name */
+ unsigned int symbol_name_length;
+
+ if (def_symbol_in_progress != NULL)
+ {
+ as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ SKIP_WHITESPACES ();
+
+ def_symbol_in_progress = (symbolS *) obstack_alloc (&notes, sizeof (*def_symbol_in_progress));
+ memset (def_symbol_in_progress, 0, sizeof (*def_symbol_in_progress));
+
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end ();
+ symbol_name_length = strlen (symbol_name);
+ symbol_name_copy = xmalloc (symbol_name_length + 1);
+ strcpy (symbol_name_copy, symbol_name);
+#ifdef tc_canonicalize_symbol_name
+ symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy);
+#endif
+
+ /* Initialize the new symbol */
+#ifdef STRIP_UNDERSCORE
+ S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_'
+ ? symbol_name_copy + 1
+ : symbol_name_copy));
+#else /* STRIP_UNDERSCORE */
+ S_SET_NAME (def_symbol_in_progress, symbol_name_copy);
+#endif /* STRIP_UNDERSCORE */
+ /* free(symbol_name_copy); */
+ def_symbol_in_progress->sy_name_offset = (unsigned long) ~0;
+ def_symbol_in_progress->sy_number = ~0;
+ def_symbol_in_progress->sy_frag = &zero_address_frag;
+ S_SET_VALUE (def_symbol_in_progress, 0);
+
+ if (S_IS_STRING (def_symbol_in_progress))
+ SF_SET_STRING (def_symbol_in_progress);
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+unsigned int dim_index;
+
+
+static void
+obj_coff_endef (ignore)
+ int ignore;
+{
+ symbolS *symbolP = 0;
+ /* DIM BUG FIX sac@cygnus.com */
+ dim_index = 0;
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ /* Set the section number according to storage class. */
+ switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
+ {
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_UNTAG:
+ SF_SET_TAG (def_symbol_in_progress);
+ /* intentional fallthrough */
+ case C_FILE:
+ case C_TPDEF:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, SEG_DEBUG);
+ break;
+
+ case C_EFCN:
+ SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
+ /* intentional fallthrough */
+ case C_BLOCK:
+ SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */
+ /* intentional fallthrough */
+ case C_FCN:
+ S_SET_SEGMENT (def_symbol_in_progress, SEG_E0);
+
+ if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0)
+ { /* .bf */
+ if (function_lineoff < 0)
+ {
+ fprintf (stderr, _("`.bf' symbol without preceding function\n"));
+ } /* missing function symbol */
+ SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff;
+
+ SF_SET_PROCESS (last_line_symbol);
+ SF_SET_ADJ_LNNOPTR (last_line_symbol);
+ SF_SET_PROCESS (def_symbol_in_progress);
+ function_lineoff = -1;
+ }
+ /* Value is always set to . */
+ def_symbol_in_progress->sy_frag = frag_now;
+ S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
+ break;
+
+#ifdef C_AUTOARG
+ case C_AUTOARG:
+#endif /* C_AUTOARG */
+ case C_AUTO:
+ case C_REG:
+ case C_MOS:
+ case C_MOE:
+ case C_MOU:
+ case C_ARG:
+ case C_REGPARM:
+ case C_FIELD:
+ case C_EOS:
+ SF_SET_DEBUG (def_symbol_in_progress);
+ S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
+ break;
+
+ case C_EXT:
+ case C_WEAKEXT:
+#ifdef TE_PE
+ case C_NT_WEAK:
+#endif
+ case C_STAT:
+ case C_LABEL:
+ /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+ break;
+
+ case C_USTATIC:
+ case C_EXTDEF:
+ case C_ULABEL:
+ as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress));
+ break;
+ } /* switch on storage class */
+
+ /* Now that we have built a debug symbol, try to find if we should
+ merge with an existing symbol or not. If a symbol is C_EFCN or
+ absolute_section or untagged SEG_DEBUG it never merges. We also
+ don't merge labels, which are in a different namespace, nor
+ symbols which have not yet been defined since they are typically
+ unique, nor do we merge tags with non-tags. */
+
+ /* Two cases for functions. Either debug followed by definition or
+ definition followed by debug. For definition first, we will
+ merge the debug symbol into the definition. For debug first, the
+ lineno entry MUST point to the definition function or else it
+ will point off into space when crawl_symbols() merges the debug
+ symbol into the real symbol. Therefor, let's presume the debug
+ symbol is a real function reference. */
+
+ /* FIXME-SOON If for some reason the definition label/symbol is
+ never seen, this will probably leave an undefined symbol at link
+ time. */
+
+ if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
+ || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
+ && !SF_GET_TAG (def_symbol_in_progress))
+ || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
+ || def_symbol_in_progress->sy_value.X_op != O_constant
+ || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
+ || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
+ {
+ symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+ &symbol_lastP);
+ }
+ else
+ {
+ /* This symbol already exists, merge the newly created symbol
+ into the old one. This is not mandatory. The linker can
+ handle duplicate symbols correctly. But I guess that it save
+ a *lot* of space if the assembly file defines a lot of
+ symbols. [loic] */
+
+ /* The debug entry (def_symbol_in_progress) is merged into the
+ previous definition. */
+
+ c_symbol_merge (def_symbol_in_progress, symbolP);
+ /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
+ def_symbol_in_progress = symbolP;
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress)
+ || SF_GET_TAG (def_symbol_in_progress)
+ || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
+ {
+ /* For functions, and tags, and static symbols, the symbol
+ *must* be where the debug symbol appears. Move the
+ existing symbol to the current place. */
+ /* If it already is at the end of the symbol list, do nothing */
+ if (def_symbol_in_progress != symbol_lastP)
+ {
+ symbol_remove (def_symbol_in_progress, &symbol_rootP,
+ &symbol_lastP);
+ symbol_append (def_symbol_in_progress, symbol_lastP,
+ &symbol_rootP, &symbol_lastP);
+ } /* if not already in place */
+ } /* if function */
+ } /* normal or mergable */
+
+ if (SF_GET_TAG (def_symbol_in_progress))
+ {
+ symbolS *oldtag;
+
+ oldtag = symbol_find_base (S_GET_NAME (def_symbol_in_progress),
+ DO_NOT_STRIP);
+ if (oldtag == NULL || ! SF_GET_TAG (oldtag))
+ tag_insert (S_GET_NAME (def_symbol_in_progress),
+ def_symbol_in_progress);
+ }
+
+ if (SF_GET_FUNCTION (def_symbol_in_progress))
+ {
+ know (sizeof (def_symbol_in_progress) <= sizeof (long));
+ function_lineoff
+ = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
+
+ SF_SET_PROCESS (def_symbol_in_progress);
+
+ if (symbolP == NULL)
+ {
+ /* That is, if this is the first time we've seen the
+ function... */
+ symbol_table_insert (def_symbol_in_progress);
+ } /* definition follows debug */
+ } /* Create the line number entry pointing to the function being defined */
+
+ def_symbol_in_progress = NULL;
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_dim (ignore)
+ int ignore;
+{
+ int dim_index;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+
+ for (dim_index = 0; dim_index < DIMNUM; dim_index++)
+ {
+ SKIP_WHITESPACES ();
+ SA_SET_SYM_DIMEN (def_symbol_in_progress, dim_index,
+ get_absolute_expression ());
+
+ switch (*input_line_pointer)
+ {
+ case ',':
+ input_line_pointer++;
+ break;
+
+ default:
+ as_warn (_("badly formed .dim directive ignored"));
+ /* intentional fallthrough */
+ case '\n':
+ case ';':
+ dim_index = DIMNUM;
+ break;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_line (ignore)
+ int ignore;
+{
+ int this_base;
+ const char *name;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ obj_coff_ln (0);
+ return;
+ }
+
+ name = S_GET_NAME (def_symbol_in_progress);
+ this_base = get_absolute_expression ();
+
+ /* Only .bf symbols indicate the use of a new base line number; the
+ line numbers associated with .ef, .bb, .eb are relative to the
+ start of the containing function. */
+ if (!strcmp (".bf", name))
+ {
+#if 0 /* XXX Can we ever have line numbers going backwards? */
+ if (this_base > line_base)
+#endif
+ {
+ line_base = this_base;
+ }
+
+#ifndef NO_LISTING
+ {
+ extern int listing;
+ if (listing)
+ {
+ listing_source_line ((unsigned int) line_base);
+ }
+ }
+#endif
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_size (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".size pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_scl (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".scl pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_tag (ignore)
+ int ignore;
+{
+ char *symbol_name;
+ char name_end;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".tag pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end ();
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
+ /* Assume that the symbol referred to by .tag is always defined.
+ This was a bad assumption. I've added find_or_make. xoxorich. */
+ SA_SET_SYM_TAGNDX (def_symbol_in_progress,
+ (long) tag_find_or_make (symbol_name));
+ if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
+ {
+ as_warn (_("tag not found for .tag %s"), symbol_name);
+ } /* not defined */
+
+ SF_SET_TAGGED (def_symbol_in_progress);
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_type (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".type pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
+
+ if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) &&
+ S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
+ {
+ SF_SET_FUNCTION (def_symbol_in_progress);
+ } /* is a function */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_coff_val (ignore)
+ int ignore;
+{
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn (_(".val pseudo-op used outside of .def/.endef ignored."));
+ demand_empty_rest_of_line ();
+ return;
+ } /* if not inside .def/.endef */
+
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *symbol_name = input_line_pointer;
+ char name_end = get_symbol_end ();
+
+#ifdef tc_canonicalize_symbol_name
+ symbol_name = tc_canonicalize_symbol_name (symbol_name);
+#endif
+
+ if (!strcmp (symbol_name, "."))
+ {
+ def_symbol_in_progress->sy_frag = frag_now;
+ S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ());
+ /* If the .val is != from the .def (e.g. statics) */
+ }
+ else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
+ {
+ def_symbol_in_progress->sy_value.X_op = O_symbol;
+ def_symbol_in_progress->sy_value.X_add_symbol =
+ symbol_find_or_make (symbol_name);
+ def_symbol_in_progress->sy_value.X_op_symbol = NULL;
+ def_symbol_in_progress->sy_value.X_add_number = 0;
+
+ /* If the segment is undefined when the forward reference is
+ resolved, then copy the segment id from the forward
+ symbol. */
+ SF_SET_GET_SEGMENT (def_symbol_in_progress);
+
+ /* FIXME: gcc can generate address expressions
+ here in unusual cases (search for "obscure"
+ in sdbout.c). We just ignore the offset
+ here, thus generating incorrect debugging
+ information. We ignore the rest of the
+ line just below. */
+ }
+ /* Otherwise, it is the name of a non debug symbol and
+ its value will be calculated later. */
+ *input_line_pointer = name_end;
+
+ /* FIXME: this is to avoid an error message in the
+ FIXME case mentioned just above. */
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+ else
+ {
+ S_SET_VALUE (def_symbol_in_progress,
+ (valueT) get_absolute_expression ());
+ } /* if symbol based */
+
+ demand_empty_rest_of_line ();
+}
+
+#ifdef TE_PE
+
+/* Handle the .linkonce pseudo-op. This is parsed by s_linkonce in
+ read.c, which then calls this object file format specific routine. */
+
+void
+obj_coff_pe_handle_link_once (type)
+ enum linkonce_type type;
+{
+ seg_info (now_seg)->scnhdr.s_flags |= IMAGE_SCN_LNK_COMDAT;
+
+ /* We store the type in the seg_info structure, and use it to set up
+ the auxiliary entry for the section symbol in c_section_symbol. */
+ seg_info (now_seg)->linkonce = type;
+}
+
+#endif /* TE_PE */
+
+void
+coff_obj_read_begin_hook ()
+{
+ /* These had better be the same. Usually 18 bytes. */
+#ifndef BFD_HEADERS
+ know (sizeof (SYMENT) == sizeof (AUXENT));
+ know (SYMESZ == AUXESZ);
+#endif
+ tag_init ();
+}
+
+/* This function runs through the symbol table and puts all the
+ externals onto another chain */
+
+/* The chain of globals. */
+symbolS *symbol_globalP;
+symbolS *symbol_global_lastP;
+
+/* The chain of externals */
+symbolS *symbol_externP;
+symbolS *symbol_extern_lastP;
+
+stack *block_stack;
+symbolS *last_functionP;
+static symbolS *last_bfP;
+symbolS *last_tagP;
+
+static unsigned int
+yank_symbols ()
+{
+ symbolS *symbolP;
+ unsigned int symbol_number = 0;
+ unsigned int last_file_symno = 0;
+
+ struct filename_list *filename_list_scan = filename_list_head;
+
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbolP ? symbol_next (symbolP) : symbol_rootP)
+ {
+ if (symbolP->sy_mri_common)
+ {
+ if (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)
+ as_bad (_("%s: global symbols not supported in common sections"),
+ S_GET_NAME (symbolP));
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ continue;
+ }
+
+ if (!SF_GET_DEBUG (symbolP))
+ {
+ /* Debug symbols do not need all this rubbish */
+ symbolS *real_symbolP;
+
+ /* L* and C_EFCN symbols never merge. */
+ if (!SF_GET_LOCAL (symbolP)
+ && !SF_GET_STATICS (symbolP)
+ && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
+ && symbolP->sy_value.X_op == O_constant
+ && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
+ && real_symbolP != symbolP)
+ {
+ /* FIXME-SOON: where do dups come from?
+ Maybe tag references before definitions? xoxorich. */
+ /* Move the debug data from the debug symbol to the
+ real symbol. Do NOT do the oposite (i.e. move from
+ real symbol to debug symbol and remove real symbol from the
+ list.) Because some pointers refer to the real symbol
+ whereas no pointers refer to the debug symbol. */
+ c_symbol_merge (symbolP, real_symbolP);
+ /* Replace the current symbol by the real one */
+ /* The symbols will never be the last or the first
+ because : 1st symbol is .file and 3 last symbols are
+ .text, .data, .bss */
+ symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbolP = real_symbolP;
+ } /* if not local but dup'd */
+
+ if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
+ {
+ S_SET_SEGMENT (symbolP, SEG_E0);
+ } /* push data into text */
+
+ resolve_symbol_value (symbolP, 1);
+
+ if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
+ {
+ if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
+ {
+ S_SET_EXTERNAL (symbolP);
+ }
+ else if (S_GET_SEGMENT (symbolP) == SEG_E0)
+ {
+ S_SET_STORAGE_CLASS (symbolP, C_LABEL);
+ }
+ else
+ {
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+ }
+ }
+
+ /* Mainly to speed up if not -g */
+ if (SF_GET_PROCESS (symbolP))
+ {
+ /* Handle the nested blocks auxiliary info. */
+ if (S_GET_STORAGE_CLASS (symbolP) == C_BLOCK)
+ {
+ if (!strcmp (S_GET_NAME (symbolP), ".bb"))
+ stack_push (block_stack, (char *) &symbolP);
+ else
+ { /* .eb */
+ register symbolS *begin_symbolP;
+ begin_symbolP = *(symbolS **) stack_pop (block_stack);
+ if (begin_symbolP == (symbolS *) 0)
+ as_warn (_("mismatched .eb"));
+ else
+ SA_SET_SYM_ENDNDX (begin_symbolP, symbol_number + 2);
+ }
+ }
+ /* If we are able to identify the type of a function, and we
+ are out of a function (last_functionP == 0) then, the
+ function symbol will be associated with an auxiliary
+ entry. */
+ if (last_functionP == (symbolS *) 0 &&
+ SF_GET_FUNCTION (symbolP))
+ {
+ last_functionP = symbolP;
+
+ if (S_GET_NUMBER_AUXILIARY (symbolP) < 1)
+ {
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+ } /* make it at least 1 */
+
+ /* Clobber possible stale .dim information. */
+#if 0
+ /* Iffed out by steve - this fries the lnnoptr info too */
+ bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
+ sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
+#endif
+ }
+ if (S_GET_STORAGE_CLASS (symbolP) == C_FCN)
+ {
+ if (strcmp (S_GET_NAME (symbolP), ".bf") == 0)
+ {
+ if (last_bfP != NULL)
+ SA_SET_SYM_ENDNDX (last_bfP, symbol_number);
+ last_bfP = symbolP;
+ }
+ }
+ else if (S_GET_STORAGE_CLASS (symbolP) == C_EFCN)
+ {
+ /* I don't even know if this is needed for sdb. But
+ the standard assembler generates it, so... */
+ if (last_functionP == (symbolS *) 0)
+ as_fatal (_("C_EFCN symbol out of scope"));
+ SA_SET_SYM_FSIZE (last_functionP,
+ (long) (S_GET_VALUE (symbolP) -
+ S_GET_VALUE (last_functionP)));
+ SA_SET_SYM_ENDNDX (last_functionP, symbol_number);
+ last_functionP = (symbolS *) 0;
+ }
+ }
+ }
+ else if (SF_GET_TAG (symbolP))
+ {
+ /* First descriptor of a structure must point to
+ the first slot after the structure description. */
+ last_tagP = symbolP;
+
+ }
+ else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS)
+ {
+ /* +2 take in account the current symbol */
+ SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2);
+ }
+ else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE)
+ {
+ /* If the filename was too long to fit in the
+ auxent, put it in the string table */
+ if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
+ && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
+ {
+ SA_SET_FILE_FNAME_OFFSET (symbolP, string_byte_count);
+ string_byte_count += strlen (filename_list_scan->filename) + 1;
+ filename_list_scan = filename_list_scan->next;
+ }
+ if (S_GET_VALUE (symbolP))
+ {
+ S_SET_VALUE (symbolP, last_file_symno);
+ last_file_symno = symbol_number;
+ } /* no one points at the first .file symbol */
+ } /* if debug or tag or eos or file */
+
+#ifdef tc_frob_coff_symbol
+ tc_frob_coff_symbol (symbolP);
+#endif
+
+ /* We must put the external symbols apart. The loader
+ does not bomb if we do not. But the references in
+ the endndx field for a .bb symbol are not corrected
+ if an external symbol is removed between .bb and .be.
+ I.e in the following case :
+ [20] .bb endndx = 22
+ [21] foo external
+ [22] .be
+ ld will move the symbol 21 to the end of the list but
+ endndx will still be 22 instead of 21. */
+
+
+ if (SF_GET_LOCAL (symbolP))
+ {
+ /* remove C_EFCN and LOCAL (L...) symbols */
+ /* next pointer remains valid */
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+
+ }
+ else if (symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
+ {
+ /* Skip symbols which were equated to undefined or common
+ symbols. */
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ }
+ else if (!S_IS_DEFINED (symbolP)
+ && !S_IS_DEBUG (symbolP)
+ && !SF_GET_STATICS (symbolP)
+ && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT))
+ {
+ /* if external, Remove from the list */
+ symbolS *hold = symbol_previous (symbolP);
+
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_clear_list_pointers (symbolP);
+ symbol_append (symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
+ symbolP = hold;
+ }
+ else if (! S_IS_DEBUG (symbolP)
+ && ! SF_GET_STATICS (symbolP)
+ && ! SF_GET_FUNCTION (symbolP)
+ && (S_GET_STORAGE_CLASS (symbolP) == C_EXT
+#ifdef TE_PE
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK
+#endif
+ || S_GET_STORAGE_CLASS (symbolP) == C_NT_WEAK))
+ {
+ symbolS *hold = symbol_previous (symbolP);
+
+ /* The O'Reilly COFF book says that defined global symbols
+ come at the end of the symbol table, just before
+ undefined global symbols. */
+
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_clear_list_pointers (symbolP);
+ symbol_append (symbolP, symbol_global_lastP, &symbol_globalP,
+ &symbol_global_lastP);
+ symbolP = hold;
+ }
+ else
+ {
+ if (SF_GET_STRING (symbolP))
+ {
+ symbolP->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
+ }
+ else
+ {
+ symbolP->sy_name_offset = 0;
+ } /* fix "long" names */
+
+ symbolP->sy_number = symbol_number;
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
+ } /* if local symbol */
+ } /* traverse the symbol list */
+ return symbol_number;
+
+}
+
+
+static unsigned int
+glue_symbols (head, tail)
+ symbolS **head;
+ symbolS **tail;
+{
+ unsigned int symbol_number = 0;
+
+ while (*head != NULL)
+ {
+ symbolS *tmp = *head;
+
+ /* append */
+ symbol_remove (tmp, head, tail);
+ symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ /* and process */
+ if (SF_GET_STRING (tmp))
+ {
+ tmp->sy_name_offset = string_byte_count;
+ string_byte_count += strlen (S_GET_NAME (tmp)) + 1;
+ }
+ else
+ {
+ tmp->sy_name_offset = 0;
+ } /* fix "long" names */
+
+ tmp->sy_number = symbol_number;
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp);
+ } /* append the entire extern chain */
+
+ return symbol_number;
+}
+
+static unsigned int
+tie_tags ()
+{
+ unsigned int symbol_number = 0;
+ symbolS *symbolP;
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ symbolP->sy_number = symbol_number;
+
+ if (SF_GET_TAGGED (symbolP))
+ {
+ SA_SET_SYM_TAGNDX
+ (symbolP,
+ ((symbolS *) SA_GET_SYM_TAGNDX (symbolP))->sy_number);
+ }
+
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP);
+ }
+
+ return symbol_number;
+}
+
+static void
+crawl_symbols (h, abfd)
+ object_headers *h;
+ bfd * abfd;
+{
+ unsigned int i;
+
+ /* Initialize the stack used to keep track of the matching .bb .be */
+
+ block_stack = stack_init (512, sizeof (symbolS *));
+
+ /* The symbol list should be ordered according to the following sequence
+ * order :
+ * . .file symbol
+ * . debug entries for functions
+ * . fake symbols for the sections, including .text .data and .bss
+ * . defined symbols
+ * . undefined symbols
+ * But this is not mandatory. The only important point is to put the
+ * undefined symbols at the end of the list.
+ */
+
+ /* Is there a .file symbol ? If not insert one at the beginning. */
+ if (symbol_rootP == NULL
+ || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
+ {
+ c_dot_file_symbol ("fake");
+ }
+
+ /*
+ * Build up static symbols for the sections, they are filled in later
+ */
+
+
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ if (segment_info[i].scnhdr.s_name[0])
+ segment_info[i].dot = c_section_symbol (segment_info[i].name,
+ i - SEG_E0 + 1);
+
+ /* Take all the externals out and put them into another chain */
+ H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
+ /* Take the externals and glue them onto the end.*/
+ H_SET_SYMBOL_TABLE_SIZE (h,
+ (H_GET_SYMBOL_COUNT (h)
+ + glue_symbols (&symbol_globalP,
+ &symbol_global_lastP)
+ + glue_symbols (&symbol_externP,
+ &symbol_extern_lastP)));
+
+ H_SET_SYMBOL_TABLE_SIZE (h, tie_tags ());
+ know (symbol_globalP == NULL);
+ know (symbol_global_lastP == NULL);
+ know (symbol_externP == NULL);
+ know (symbol_extern_lastP == NULL);
+}
+
+/*
+ * Find strings by crawling along symbol table chain.
+ */
+
+void
+w_strings (where)
+ char *where;
+{
+ symbolS *symbolP;
+ struct filename_list *filename_list_scan = filename_list_head;
+
+ /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
+ md_number_to_chars (where, (valueT) string_byte_count, 4);
+ where += 4;
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code must
+ coordinate with that in coff_header_append and write_object_file. */
+ {
+ unsigned int i;
+
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0]
+ && strlen (segment_info[i].name) > SCNNMLEN)
+ {
+ unsigned int size;
+
+ size = strlen (segment_info[i].name) + 1;
+ memcpy (where, segment_info[i].name, size);
+ where += size;
+ }
+ }
+ }
+#endif /* COFF_LONG_SECTION_NAMES */
+
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbol_next (symbolP))
+ {
+ unsigned int size;
+
+ if (SF_GET_STRING (symbolP))
+ {
+ size = strlen (S_GET_NAME (symbolP)) + 1;
+ memcpy (where, S_GET_NAME (symbolP), size);
+ where += size;
+ }
+ if (S_GET_STORAGE_CLASS (symbolP) == C_FILE
+ && SA_GET_FILE_FNAME_ZEROS (symbolP) == 0
+ && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0)
+ {
+ size = strlen (filename_list_scan->filename) + 1;
+ memcpy (where, filename_list_scan->filename, size);
+ filename_list_scan = filename_list_scan ->next;
+ where += size;
+ }
+ }
+}
+
+static void
+do_linenos_for (abfd, h, file_cursor)
+ bfd * abfd;
+ object_headers * h;
+ unsigned long *file_cursor;
+{
+ unsigned int idx;
+ unsigned long start = *file_cursor;
+
+ for (idx = SEG_E0; idx < SEG_LAST; idx++)
+ {
+ segment_info_type *s = segment_info + idx;
+
+
+ if (s->scnhdr.s_nlnno != 0)
+ {
+ struct lineno_list *line_ptr;
+
+ struct external_lineno *buffer =
+ (struct external_lineno *) xmalloc (s->scnhdr.s_nlnno * LINESZ);
+
+ struct external_lineno *dst = buffer;
+
+ /* Run through the table we've built and turn it into its external
+ form, take this chance to remove duplicates */
+
+ for (line_ptr = s->lineno_list_head;
+ line_ptr != (struct lineno_list *) NULL;
+ line_ptr = line_ptr->next)
+ {
+
+ if (line_ptr->line.l_lnno == 0)
+ {
+ /* Turn a pointer to a symbol into the symbols' index */
+ line_ptr->line.l_addr.l_symndx =
+ ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number;
+ }
+ else
+ {
+ line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address;
+ }
+
+
+ (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst);
+ dst++;
+
+ }
+
+ s->scnhdr.s_lnnoptr = *file_cursor;
+
+ bfd_write (buffer, 1, s->scnhdr.s_nlnno * LINESZ, abfd);
+ free (buffer);
+
+ *file_cursor += s->scnhdr.s_nlnno * LINESZ;
+ }
+ }
+ H_SET_LINENO_SIZE (h, *file_cursor - start);
+}
+
+
+/* Now we run through the list of frag chains in a segment and
+ make all the subsegment frags appear at the end of the
+ list, as if the seg 0 was extra long */
+
+static void
+remove_subsegs ()
+{
+ unsigned int i;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ frchainS *head = segment_info[i].frchainP;
+ fragS dummy;
+ fragS *prev_frag = &dummy;
+
+ while (head && head->frch_seg == i)
+ {
+ prev_frag->fr_next = head->frch_root;
+ prev_frag = head->frch_last;
+ head = head->frch_next;
+ }
+ prev_frag->fr_next = 0;
+ }
+}
+
+unsigned long machine;
+int coff_flags;
+extern void
+write_object_file ()
+{
+ int i;
+ const char *name;
+ struct frchain *frchain_ptr;
+
+ object_headers headers;
+ unsigned long file_cursor;
+ bfd *abfd;
+ unsigned int addr;
+ abfd = bfd_openw (out_file_name, TARGET_FORMAT);
+
+
+ if (abfd == 0)
+ {
+ as_perror (_("FATAL: Can't create %s"), out_file_name);
+ exit (EXIT_FAILURE);
+ }
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, BFD_ARCH, machine);
+
+ string_byte_count = 4;
+
+ for (frchain_ptr = frchain_root;
+ frchain_ptr != (struct frchain *) NULL;
+ frchain_ptr = frchain_ptr->frch_next)
+ {
+ /* Run through all the sub-segments and align them up. Also
+ close any open frags. We tack a .fill onto the end of the
+ frag chain so that any .align's size can be worked by looking
+ at the next frag. */
+
+ subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+#ifndef SUB_SEGMENT_ALIGN
+#define SUB_SEGMENT_ALIGN(SEG) 1
+#endif
+#ifdef md_do_align
+ md_do_align (SUB_SEGMENT_ALIGN (now_seg), (char *) NULL, 0, 0,
+ alignment_done);
+#endif
+ frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0);
+#ifdef md_do_align
+ alignment_done:
+#endif
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+
+
+ remove_subsegs ();
+
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ relax_segment (segment_info[i].frchainP->frch_root, i);
+ }
+
+ H_SET_NUMBER_OF_SECTIONS (&headers, 0);
+
+ /* Find out how big the sections are, and set the addresses. */
+ addr = 0;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ long size;
+
+ segment_info[i].scnhdr.s_paddr = addr;
+ segment_info[i].scnhdr.s_vaddr = addr;
+
+ if (segment_info[i].scnhdr.s_name[0])
+ {
+ H_SET_NUMBER_OF_SECTIONS (&headers,
+ H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
+
+#ifdef COFF_LONG_SECTION_NAMES
+ /* Support long section names as found in PE. This code
+ must coordinate with that in coff_header_append and
+ w_strings. */
+ {
+ unsigned int len;
+
+ len = strlen (segment_info[i].name);
+ if (len > SCNNMLEN)
+ string_byte_count += len + 1;
+ }
+#endif /* COFF_LONG_SECTION_NAMES */
+ }
+
+ size = size_section (abfd, (unsigned int) i);
+ addr += size;
+
+ /* I think the section alignment is only used on the i960; the
+ i960 needs it, and it should do no harm on other targets. */
+#ifdef ALIGNMENT_IN_S_FLAGS
+ segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8;
+#else
+ segment_info[i].scnhdr.s_align = 1 << section_alignment[i];
+#endif
+
+ if (i == SEG_E0)
+ H_SET_TEXT_SIZE (&headers, size);
+ else if (i == SEG_E1)
+ H_SET_DATA_SIZE (&headers, size);
+ else if (i == SEG_E2)
+ H_SET_BSS_SIZE (&headers, size);
+ }
+
+ /* Turn the gas native symbol table shape into a coff symbol table */
+ crawl_symbols (&headers, abfd);
+
+ if (string_byte_count == 4)
+ string_byte_count = 0;
+
+ H_SET_STRING_SIZE (&headers, string_byte_count);
+
+#ifdef tc_frob_file
+ tc_frob_file ();
+#endif
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ fixup_mdeps (segment_info[i].frchainP->frch_root, &headers, i);
+ fixup_segment (&segment_info[i], i);
+ }
+
+ /* Look for ".stab" segments and fill in their initial symbols
+ correctly. */
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ name = segment_info[i].name;
+
+ if (name != NULL
+ && strncmp (".stab", name, 5) == 0
+ && strncmp (".stabstr", name, 8) != 0)
+ adjust_stab_section (abfd, i);
+ }
+
+ file_cursor = H_GET_TEXT_FILE_OFFSET (&headers);
+
+ bfd_seek (abfd, (file_ptr) file_cursor, 0);
+
+ /* Plant the data */
+
+ fill_section (abfd, &headers, &file_cursor);
+
+ do_relocs_for (abfd, &headers, &file_cursor);
+
+ do_linenos_for (abfd, &headers, &file_cursor);
+
+ H_SET_FILE_MAGIC_NUMBER (&headers, COFF_MAGIC);
+#ifndef OBJ_COFF_OMIT_TIMESTAMP
+ H_SET_TIME_STAMP (&headers, (long)time((time_t *)0));
+#else
+ H_SET_TIME_STAMP (&headers, 0);
+#endif
+#ifdef TC_COFF_SET_MACHINE
+ TC_COFF_SET_MACHINE (&headers);
+#endif
+
+#ifndef COFF_FLAGS
+#define COFF_FLAGS 0
+#endif
+
+#ifdef KEEP_RELOC_INFO
+ H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
+ COFF_FLAGS | coff_flags));
+#else
+ H_SET_FLAGS (&headers, ((H_GET_LINENO_SIZE(&headers) ? 0 : F_LNNO) |
+ (H_GET_RELOCATION_SIZE(&headers) ? 0 : F_RELFLG) |
+ COFF_FLAGS | coff_flags));
+#endif
+
+ {
+ unsigned int symtable_size = H_GET_SYMBOL_TABLE_SIZE (&headers);
+ char *buffer1 = xmalloc (symtable_size + string_byte_count + 1);
+
+ H_SET_SYMBOL_TABLE_POINTER (&headers, bfd_tell (abfd));
+ w_symbols (abfd, buffer1, symbol_rootP);
+ if (string_byte_count > 0)
+ w_strings (buffer1 + symtable_size);
+ bfd_write (buffer1, 1, symtable_size + string_byte_count, abfd);
+ free (buffer1);
+ }
+
+ coff_header_append (abfd, &headers);
+#if 0
+ /* Recent changes to write need this, but where it should
+ go is up to Ken.. */
+ if (bfd_close_all_done (abfd) == false)
+ as_fatal (_("Can't close %s: %s"), out_file_name,
+ bfd_errmsg (bfd_get_error ()));
+#else
+ {
+ extern bfd *stdoutput;
+ stdoutput = abfd;
+ }
+#endif
+
+}
+
+/* Add a new segment. This is called from subseg_new via the
+ obj_new_segment macro. */
+
+segT
+obj_coff_add_segment (name)
+ const char *name;
+{
+ unsigned int i;
+
+#ifndef COFF_LONG_SECTION_NAMES
+ char buf[SCNNMLEN + 1];
+
+ strncpy (buf, name, SCNNMLEN);
+ buf[SCNNMLEN] = '\0';
+ name = buf;
+#endif
+
+ for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
+ if (strcmp (name, segment_info[i].name) == 0)
+ return (segT) i;
+
+ if (i == SEG_LAST)
+ {
+ as_bad (_("Too many new sections; can't add \"%s\""), name);
+ return now_seg;
+ }
+
+ /* Add a new section. */
+ strncpy (segment_info[i].scnhdr.s_name, name,
+ sizeof (segment_info[i].scnhdr.s_name));
+ segment_info[i].scnhdr.s_flags = STYP_REG;
+ segment_info[i].name = xstrdup (name);
+
+ return (segT) i;
+}
+
+/*
+ * implement the .section pseudo op:
+ * .section name {, "flags"}
+ * ^ ^
+ * | +--- optional flags: 'b' for bss
+ * | 'i' for info
+ * +-- section name 'l' for lib
+ * 'n' for noload
+ * 'o' for over
+ * 'w' for data
+ * 'd' (apparently m88k for data)
+ * 'x' for text
+ * 'r' for read-only data
+ * But if the argument is not a quoted string, treat it as a
+ * subsegment number.
+ */
+
+void
+obj_coff_section (ignore)
+ int ignore;
+{
+ /* Strip out the section name */
+ char *section_name, *name;
+ char c;
+ unsigned int exp;
+ long flags;
+
+ if (flag_mri)
+ {
+ char type;
+
+ s_mri_sect (&type);
+ flags = 0;
+ if (type == 'C')
+ flags = STYP_TEXT;
+ else if (type == 'D')
+ flags = STYP_DATA;
+ segment_info[now_seg].scnhdr.s_flags |= flags;
+
+ return;
+ }
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - section_name + 1);
+ strcpy (name, section_name);
+
+ *input_line_pointer = c;
+
+ exp = 0;
+ flags = 0;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != '"')
+ exp = get_absolute_expression ();
+ else
+ {
+ ++input_line_pointer;
+ while (*input_line_pointer != '"'
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ switch (*input_line_pointer)
+ {
+ case 'b': flags |= STYP_BSS; break;
+ case 'i': flags |= STYP_INFO; break;
+ case 'l': flags |= STYP_LIB; break;
+ case 'n': flags |= STYP_NOLOAD; break;
+ case 'o': flags |= STYP_OVER; break;
+ case 'd':
+ case 'w': flags |= STYP_DATA; break;
+ case 'x': flags |= STYP_TEXT; break;
+ case 'r': flags |= STYP_LIT; break;
+ default:
+ as_warn(_("unknown section attribute '%c'"),
+ *input_line_pointer);
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+ }
+ }
+
+ subseg_new (name, (subsegT) exp);
+
+ segment_info[now_seg].scnhdr.s_flags |= flags;
+
+ demand_empty_rest_of_line ();
+}
+
+
+static void
+obj_coff_text (ignore)
+ int ignore;
+{
+ subseg_new (".text", get_absolute_expression ());
+}
+
+
+static void
+obj_coff_data (ignore)
+ int ignore;
+{
+ if (flag_readonly_data_in_text)
+ subseg_new (".text", get_absolute_expression () + 1000);
+ else
+ subseg_new (".data", get_absolute_expression ());
+}
+
+static void
+obj_coff_ident (ignore)
+ int ignore;
+{
+ segT current_seg = now_seg; /* save current seg */
+ subsegT current_subseg = now_subseg;
+ subseg_new (".comment", 0); /* .comment seg */
+ stringer (1); /* read string */
+ subseg_set (current_seg, current_subseg); /* restore current seg */
+}
+
+void
+c_symbol_merge (debug, normal)
+ symbolS *debug;
+ symbolS *normal;
+{
+ S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
+ S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
+ {
+ S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
+ } /* take the most we have */
+
+ if (S_GET_NUMBER_AUXILIARY (debug) > 0)
+ {
+ memcpy ((char *) &normal->sy_symbol.ost_auxent[0],
+ (char *) &debug->sy_symbol.ost_auxent[0],
+ (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ));
+ } /* Move all the auxiliary information */
+
+ /* Move the debug flags. */
+ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
+} /* c_symbol_merge() */
+
+static int
+c_line_new (symbol, paddr, line_number, frag)
+ symbolS * symbol;
+ long paddr;
+ int line_number;
+ fragS * frag;
+{
+ struct lineno_list *new_line =
+ (struct lineno_list *) xmalloc (sizeof (struct lineno_list));
+
+ segment_info_type *s = segment_info + now_seg;
+ new_line->line.l_lnno = line_number;
+
+ if (line_number == 0)
+ {
+ last_line_symbol = symbol;
+ new_line->line.l_addr.l_symndx = (long) symbol;
+ }
+ else
+ {
+ new_line->line.l_addr.l_paddr = paddr;
+ }
+
+ new_line->frag = (char *) frag;
+ new_line->next = (struct lineno_list *) NULL;
+
+
+ if (s->lineno_list_head == (struct lineno_list *) NULL)
+ {
+ s->lineno_list_head = new_line;
+ }
+ else
+ {
+ s->lineno_list_tail->next = new_line;
+ }
+ s->lineno_list_tail = new_line;
+ return LINESZ * s->scnhdr.s_nlnno++;
+}
+
+void
+c_dot_file_symbol (filename)
+ char *filename;
+{
+ symbolS *symbolP;
+
+ symbolP = symbol_new (".file",
+ SEG_DEBUG,
+ 0,
+ &zero_address_frag);
+
+ S_SET_STORAGE_CLASS (symbolP, C_FILE);
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ if (strlen (filename) > FILNMLEN)
+ {
+ /* Filename is too long to fit into an auxent,
+ we stick it into the string table instead. We keep
+ a linked list of the filenames we find so we can emit
+ them later.*/
+ struct filename_list *f = ((struct filename_list *)
+ xmalloc (sizeof (struct filename_list)));
+
+ f->filename = filename;
+ f->next = 0;
+
+ SA_SET_FILE_FNAME_ZEROS (symbolP, 0);
+ SA_SET_FILE_FNAME_OFFSET (symbolP, 1);
+
+ if (filename_list_tail)
+ filename_list_tail->next = f;
+ else
+ filename_list_head = f;
+ filename_list_tail = f;
+ }
+ else
+ {
+ SA_SET_FILE_FNAME (symbolP, filename);
+ }
+#ifndef NO_LISTING
+ {
+ extern int listing;
+ if (listing)
+ {
+ listing_source_file (filename);
+ }
+
+ }
+
+#endif
+ SF_SET_DEBUG (symbolP);
+ S_SET_VALUE (symbolP, (valueT) previous_file_symbol);
+
+ previous_file_symbol = symbolP;
+
+ /* Make sure that the symbol is first on the symbol chain */
+ if (symbol_rootP != symbolP)
+ {
+ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
+ }
+} /* c_dot_file_symbol() */
+
+/*
+ * Build a 'section static' symbol.
+ */
+
+symbolS *
+c_section_symbol (name, idx)
+ char *name;
+ int idx;
+{
+ symbolS *symbolP;
+
+ symbolP = symbol_find_base (name, DO_NOT_STRIP);
+ if (symbolP == NULL)
+ symbolP = symbol_new (name, idx, 0, &zero_address_frag);
+ else
+ {
+ /* Mmmm. I just love violating interfaces. Makes me feel...dirty. */
+ S_SET_SEGMENT (symbolP, idx);
+ symbolP->sy_frag = &zero_address_frag;
+ }
+
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+ S_SET_NUMBER_AUXILIARY (symbolP, 1);
+
+ SF_SET_STATICS (symbolP);
+
+#ifdef TE_DELTA
+ /* manfred@s-direktnet.de: section symbols *must* have the LOCAL bit cleared,
+ which is set by the new definition of LOCAL_LABEL in tc-m68k.h. */
+ SF_CLEAR_LOCAL (symbolP);
+#endif
+#ifdef TE_PE
+ /* If the .linkonce pseudo-op was used for this section, we must
+ store the information in the auxiliary entry for the section
+ symbol. */
+ if (segment_info[idx].linkonce != LINKONCE_UNSET)
+ {
+ int type;
+
+ switch (segment_info[idx].linkonce)
+ {
+ default:
+ abort ();
+ case LINKONCE_DISCARD:
+ type = IMAGE_COMDAT_SELECT_ANY;
+ break;
+ case LINKONCE_ONE_ONLY:
+ type = IMAGE_COMDAT_SELECT_NODUPLICATES;
+ break;
+ case LINKONCE_SAME_SIZE:
+ type = IMAGE_COMDAT_SELECT_SAME_SIZE;
+ break;
+ case LINKONCE_SAME_CONTENTS:
+ type = IMAGE_COMDAT_SELECT_EXACT_MATCH;
+ break;
+ }
+
+ SYM_AUXENT (symbolP)->x_scn.x_comdat = type;
+ }
+#endif /* TE_PE */
+
+ return symbolP;
+} /* c_section_symbol() */
+
+static void
+w_symbols (abfd, where, symbol_rootP)
+ bfd * abfd;
+ char *where;
+ symbolS * symbol_rootP;
+{
+ symbolS *symbolP;
+ unsigned int i;
+
+ /* First fill in those values we have only just worked out */
+ for (i = SEG_E0; i < SEG_LAST; i++)
+ {
+ symbolP = segment_info[i].dot;
+ if (symbolP)
+ {
+ SA_SET_SCN_SCNLEN (symbolP, segment_info[i].scnhdr.s_size);
+ SA_SET_SCN_NRELOC (symbolP, segment_info[i].scnhdr.s_nreloc);
+ SA_SET_SCN_NLINNO (symbolP, segment_info[i].scnhdr.s_nlnno);
+ }
+ }
+
+ /*
+ * Emit all symbols left in the symbol chain.
+ */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /* Used to save the offset of the name. It is used to point
+ to the string in memory but must be a file offset. */
+ register char *temp;
+
+ /* We can't fix the lnnoptr field in yank_symbols with the other
+ adjustments, because we have to wait until we know where they
+ go in the file. */
+ if (SF_GET_ADJ_LNNOPTR (symbolP))
+ {
+ SA_GET_SYM_LNNOPTR (symbolP) +=
+ segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr;
+ }
+
+ tc_coff_symbol_emit_hook (symbolP);
+
+ temp = S_GET_NAME (symbolP);
+ if (SF_GET_STRING (symbolP))
+ {
+ S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
+ S_SET_ZEROES (symbolP, 0);
+ }
+ else
+ {
+ memset (symbolP->sy_symbol.ost_entry.n_name, 0, SYMNMLEN);
+ strncpy (symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
+ }
+ where = symbol_to_chars (abfd, where, symbolP);
+ S_SET_NAME (symbolP, temp);
+ }
+
+} /* w_symbols() */
+
+static void
+obj_coff_lcomm (ignore)
+ int ignore;
+{
+ s_lcomm(0);
+ return;
+#if 0
+ char *name;
+ char c;
+ int temp;
+ char *p;
+
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (*input_line_pointer == '\n')
+ {
+ as_bad (_("Missing size expression"));
+ return;
+ }
+ input_line_pointer++;
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_("lcomm length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ *p = 0;
+
+ symbolP = symbol_find_or_make(name);
+
+ if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN &&
+ S_GET_VALUE(symbolP) == 0)
+ {
+ if (! need_pass_2)
+ {
+ char *p;
+ segT current_seg = now_seg; /* save current seg */
+ subsegT current_subseg = now_subseg;
+
+ subseg_set (SEG_E2, 1);
+ symbolP->sy_frag = frag_now;
+ p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP,
+ (offsetT) temp, (char *) 0);
+ *p = 0;
+ subseg_set (current_seg, current_subseg); /* restore current seg */
+ S_SET_SEGMENT(symbolP, SEG_E2);
+ S_SET_STORAGE_CLASS(symbolP, C_STAT);
+ }
+ }
+ else
+ as_bad(_("Symbol %s already defined"), name);
+
+ demand_empty_rest_of_line();
+#endif
+}
+
+static void
+fixup_mdeps (frags, h, this_segment)
+ fragS * frags;
+ object_headers * h;
+ segT this_segment;
+{
+ subseg_change (this_segment, 0);
+ while (frags)
+ {
+ switch (frags->fr_type)
+ {
+ case rs_align:
+ case rs_align_code:
+ case rs_org:
+#ifdef HANDLE_ALIGN
+ HANDLE_ALIGN (frags);
+#endif
+ frags->fr_type = rs_fill;
+ frags->fr_offset =
+ ((frags->fr_next->fr_address - frags->fr_address - frags->fr_fix)
+ / frags->fr_var);
+ break;
+ case rs_machine_dependent:
+ md_convert_frag (h, this_segment, frags);
+ frag_wane (frags);
+ break;
+ default:
+ ;
+ }
+ frags = frags->fr_next;
+ }
+}
+
+#if 1
+
+#ifndef TC_FORCE_RELOCATION
+#define TC_FORCE_RELOCATION(fix) 0
+#endif
+
+static void
+fixup_segment (segP, this_segment_type)
+ segment_info_type * segP;
+ segT this_segment_type;
+{
+ register fixS * fixP;
+ register symbolS *add_symbolP;
+ register symbolS *sub_symbolP;
+ long add_number;
+ register int size;
+ register char *place;
+ register long where;
+ register char pcrel;
+ register fragS *fragP;
+ register segT add_symbol_segment = absolute_section;
+
+ for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next)
+ {
+ fragP = fixP->fx_frag;
+ know (fragP);
+ where = fixP->fx_where;
+ place = fragP->fr_literal + where;
+ size = fixP->fx_size;
+ add_symbolP = fixP->fx_addsy;
+ sub_symbolP = fixP->fx_subsy;
+ add_number = fixP->fx_offset;
+ pcrel = fixP->fx_pcrel;
+
+ /* We want function-relative stabs to work on systems which
+ may use a relaxing linker; thus we must handle the sym1-sym2
+ fixups function-relative stabs generates.
+
+ Of course, if you actually enable relaxing in the linker, the
+ line and block scoping information is going to be incorrect
+ in some cases. The only way to really fix this is to support
+ a reloc involving the difference of two symbols. */
+ if (linkrelax
+ && (!sub_symbolP || pcrel))
+ continue;
+
+#ifdef TC_I960
+ if (fixP->fx_tcbit && SF_GET_CALLNAME (add_symbolP))
+ {
+ /* Relocation should be done via the associated 'bal' entry
+ point symbol. */
+
+ if (!SF_GET_BALNAME (tc_get_bal_of_call (add_symbolP)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("No 'bal' entry point for leafproc %s"),
+ S_GET_NAME (add_symbolP));
+ continue;
+ }
+ fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
+ }
+#endif
+
+ /* Make sure the symbols have been resolved; this may not have
+ happened if these are expression symbols. */
+ if (add_symbolP != NULL && ! add_symbolP->sy_resolved)
+ resolve_symbol_value (add_symbolP, 1);
+
+ if (add_symbolP != NULL)
+ {
+ /* If this fixup is against a symbol which has been equated
+ to another symbol, convert it to the other symbol. */
+ if (add_symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (add_symbolP)
+ || S_IS_COMMON (add_symbolP)))
+ {
+ while (add_symbolP->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (add_symbolP)
+ || S_IS_COMMON (add_symbolP)))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur with a
+ badly written program. */
+ n = add_symbolP->sy_value.X_add_symbol;
+ if (n == add_symbolP)
+ break;
+ add_number += add_symbolP->sy_value.X_add_number;
+ add_symbolP = n;
+ }
+ fixP->fx_addsy = add_symbolP;
+ fixP->fx_offset = add_number;
+ }
+ }
+
+ if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved)
+ resolve_symbol_value (sub_symbolP, 1);
+
+ if (add_symbolP != NULL
+ && add_symbolP->sy_mri_common)
+ {
+ know (add_symbolP->sy_value.X_op == O_symbol);
+ add_number += S_GET_VALUE (add_symbolP);
+ fixP->fx_offset = add_number;
+ add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
+ }
+
+ if (add_symbolP)
+ {
+ add_symbol_segment = S_GET_SEGMENT (add_symbolP);
+ } /* if there is an addend */
+
+ if (sub_symbolP)
+ {
+ if (add_symbolP == NULL || add_symbol_segment == absolute_section)
+ {
+ if (add_symbolP != NULL)
+ {
+ add_number += S_GET_VALUE (add_symbolP);
+ add_symbolP = NULL;
+ fixP->fx_addsy = NULL;
+ }
+
+ /* It's just -sym. */
+ if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
+ {
+ add_number -= S_GET_VALUE (sub_symbolP);
+ fixP->fx_subsy = 0;
+ fixP->fx_done = 1;
+ }
+ else
+ {
+#ifndef TC_M68K
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Negative of non-absolute symbol %s"),
+ S_GET_NAME (sub_symbolP));
+#endif
+ add_number -= S_GET_VALUE (sub_symbolP);
+ } /* not absolute */
+
+ /* if sub_symbol is in the same segment that add_symbol
+ and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
+ }
+ else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
+ && SEG_NORMAL (add_symbol_segment))
+ {
+ /* Difference of 2 symbols from same segment. Can't
+ make difference of 2 undefineds: 'value' means
+ something different for N_UNDF. */
+#ifdef TC_I960
+ /* Makes no sense to use the difference of 2 arbitrary symbols
+ as the target of a call instruction. */
+ if (fixP->fx_tcbit)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("callj to difference of 2 symbols"));
+ }
+#endif /* TC_I960 */
+ add_number += S_GET_VALUE (add_symbolP) -
+ S_GET_VALUE (sub_symbolP);
+ add_symbolP = NULL;
+
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ fixP->fx_subsy = NULL;
+ fixP->fx_done = 1;
+#ifdef TC_M68K /* is this right? */
+ pcrel = 0;
+ fixP->fx_pcrel = 0;
+#endif
+ }
+ }
+ else
+ {
+ /* Different segments in subtraction. */
+ know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
+
+ if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
+ {
+ add_number -= S_GET_VALUE (sub_symbolP);
+ }
+#ifdef DIFF_EXPR_OK
+ else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
+#if 0 /* Okay for 68k, at least... */
+ && !pcrel
+#endif
+ )
+ {
+ /* Make it pc-relative. */
+ add_number += (md_pcrel_from (fixP)
+ - S_GET_VALUE (sub_symbolP));
+ pcrel = 1;
+ fixP->fx_pcrel = 1;
+ sub_symbolP = 0;
+ fixP->fx_subsy = 0;
+ }
+#endif
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."),
+ segment_name (S_GET_SEGMENT (sub_symbolP)),
+ S_GET_NAME (sub_symbolP),
+ (long) (fragP->fr_address + where));
+ } /* if absolute */
+ }
+ } /* if sub_symbolP */
+
+ if (add_symbolP)
+ {
+ if (add_symbol_segment == this_segment_type && pcrel)
+ {
+ /*
+ * This fixup was made when the symbol's segment was
+ * SEG_UNKNOWN, but it is now in the local segment.
+ * So we know how to do the address without relocation.
+ */
+#ifdef TC_I960
+ /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
+ * in which cases it modifies *fixP as appropriate. In the case
+ * of a 'calls', no further work is required, and *fixP has been
+ * set up to make the rest of the code below a no-op.
+ */
+ reloc_callj (fixP);
+#endif /* TC_I960 */
+
+ add_number += S_GET_VALUE (add_symbolP);
+ add_number -= md_pcrel_from (fixP);
+
+ /* We used to do
+ add_number -= segP->scnhdr.s_vaddr;
+ if defined (TC_I386) || defined (TE_LYNX). I now
+ think that was an error propagated from the case when
+ we are going to emit the relocation. If we are not
+ going to emit the relocation, then we just want to
+ set add_number to the difference between the symbols.
+ This is a case that would only arise when there is a
+ PC relative reference from a section other than .text
+ to a symbol defined in the same section, and the
+ reference is not relaxed. Since jump instructions on
+ the i386 are relaxed, this could only arise with a
+ call instruction. */
+
+ pcrel = 0; /* Lie. Don't want further pcrel processing. */
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ }
+ }
+ else
+ {
+ switch (add_symbol_segment)
+ {
+ case absolute_section:
+#ifdef TC_I960
+ reloc_callj (fixP); /* See comment about reloc_callj() above*/
+#endif /* TC_I960 */
+ add_number += S_GET_VALUE (add_symbolP);
+ add_symbolP = NULL;
+
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ }
+ break;
+ default:
+
+
+#if defined(TC_A29K) || (defined(TE_PE) && defined(TC_I386)) || defined(TC_M88K)
+ /* This really should be handled in the linker, but
+ backward compatibility forbids. */
+ add_number += S_GET_VALUE (add_symbolP);
+#else
+ add_number += S_GET_VALUE (add_symbolP) +
+ segment_info[S_GET_SEGMENT (add_symbolP)].scnhdr.s_paddr;
+#endif
+ break;
+
+ case SEG_UNKNOWN:
+#ifdef TC_I960
+ if ((int) fixP->fx_bit_fixP == 13)
+ {
+ /* This is a COBR instruction. They have only a
+ * 13-bit displacement and are only to be used
+ * for local branches: flag as error, don't generate
+ * relocation.
+ */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("can't use COBR format with external label"));
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ continue;
+ } /* COBR */
+#endif /* TC_I960 */
+#if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND)
+ /* 386 COFF uses a peculiar format in which the
+ value of a common symbol is stored in the .text
+ segment (I've checked this on SVR3.2 and SCO
+ 3.2.2) Ian Taylor <ian@cygnus.com>. */
+ /* This is also true for 68k COFF on sysv machines
+ (Checked on Motorola sysv68 R3V6 and R3V7.1, and also on
+ UNIX System V/M68000, Release 1.0 from ATT/Bell Labs)
+ Philippe De Muyter <phdm@info.ucl.ac.be>. */
+ if (S_IS_COMMON (add_symbolP))
+ add_number += S_GET_VALUE (add_symbolP);
+#endif
+ break;
+
+
+ } /* switch on symbol seg */
+ } /* if not in local seg */
+ } /* if there was a + symbol */
+
+ if (pcrel)
+ {
+#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K)
+ /* This adjustment is not correct on the m88k, for which the
+ linker does all the computation. */
+ add_number -= md_pcrel_from (fixP);
+#endif
+ if (add_symbolP == 0)
+ {
+ fixP->fx_addsy = &abs_symbol;
+ } /* if there's an add_symbol */
+#if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K)
+ /* On the 386 we must adjust by the segment vaddr as well.
+ Ian Taylor.
+
+ I changed the i960 to work this way as well. This is
+ compatible with the current GNU linker behaviour. I do
+ not know what other i960 COFF assemblers do. This is not
+ a common case: normally, only assembler code will contain
+ a PC relative reloc, and only branches which do not
+ originate in the .text section will have a non-zero
+ address.
+
+ I changed the m68k to work this way as well. This will
+ break existing PC relative relocs from sections which do
+ not start at address 0, but it will make ld -r work.
+ Ian Taylor, 4 Oct 96. */
+
+ add_number -= segP->scnhdr.s_vaddr;
+#endif
+ } /* if pcrel */
+
+ if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow)
+ {
+#ifndef TC_M88K
+ /* The m88k uses the offset field of the reloc to get around
+ this problem. */
+ if ((size == 1
+ && ((add_number & ~0xFF)
+ || (fixP->fx_signed && (add_number & 0x80)))
+ && ((add_number & ~0xFF) != (-1 & ~0xFF)
+ || (add_number & 0x80) == 0))
+ || (size == 2
+ && ((add_number & ~0xFFFF)
+ || (fixP->fx_signed && (add_number & 0x8000)))
+ && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)
+ || (add_number & 0x8000) == 0)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Value of %ld too large for field of %d bytes at 0x%lx"),
+ (long) add_number, size,
+ (unsigned long) (fragP->fr_address + where));
+ }
+#endif
+#ifdef WARN_SIGNED_OVERFLOW_WORD
+ /* Warn if a .word value is too large when treated as a
+ signed number. We already know it is not too negative.
+ This is to catch over-large switches generated by gcc on
+ the 68k. */
+ if (!flag_signed_overflow_ok
+ && size == 2
+ && add_number > 0x7fff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
+ (long) add_number,
+ (unsigned long) (fragP->fr_address + where));
+#endif
+ } /* not a bit fix */
+ /* Once this fix has been applied, we don't have to output
+ anything nothing more need be done. */
+#ifdef MD_APPLY_FIX3
+ md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type);
+#else
+ md_apply_fix (fixP, add_number);
+#endif
+ } /* For each fixS in this segment. */
+} /* fixup_segment() */
+
+#endif
+
+/* The first entry in a .stab section is special. */
+
+void
+obj_coff_init_stab_section (seg)
+ segT seg;
+{
+ char *file;
+ char *p;
+ char *stabstr_name;
+ unsigned int stroff;
+
+ /* Make space for this first symbol. */
+ p = frag_more (12);
+ /* Zero it out. */
+ memset (p, 0, 12);
+ as_where (&file, (unsigned int *) NULL);
+ stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
+ strcpy (stabstr_name, segment_info[seg].name);
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+}
+
+/* Fill in the counts in the first entry in a .stab section. */
+
+static void
+adjust_stab_section(abfd, seg)
+ bfd *abfd;
+ segT seg;
+{
+ segT stabstrseg = SEG_UNKNOWN;
+ const char *secname, *name2;
+ char *name;
+ char *p = NULL;
+ int i, strsz = 0, nsyms;
+ fragS *frag = segment_info[seg].frchainP->frch_root;
+
+ /* Look for the associated string table section. */
+
+ secname = segment_info[seg].name;
+ name = (char *) alloca (strlen (secname) + 4);
+ strcpy (name, secname);
+ strcat (name, "str");
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ name2 = segment_info[i].name;
+ if (name2 != NULL && strncmp(name2, name, 8) == 0)
+ {
+ stabstrseg = i;
+ break;
+ }
+ }
+
+ /* If we found the section, get its size. */
+ if (stabstrseg != SEG_UNKNOWN)
+ strsz = size_section (abfd, stabstrseg);
+
+ nsyms = size_section (abfd, seg) / 12 - 1;
+
+ /* Look for the first frag of sufficient size for the initial stab
+ symbol, and collect a pointer to it. */
+ while (frag && frag->fr_fix < 12)
+ frag = frag->fr_next;
+ assert (frag != 0);
+ p = frag->fr_literal;
+ assert (p != 0);
+
+ /* Write in the number of stab symbols and the size of the string
+ table. */
+ bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
+ bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
+}
+
+#endif /* not BFD_ASSEMBLER */
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {"def", obj_coff_def, 0},
+ {"dim", obj_coff_dim, 0},
+ {"endef", obj_coff_endef, 0},
+ {"line", obj_coff_line, 0},
+ {"ln", obj_coff_ln, 0},
+ {"appline", obj_coff_ln, 1},
+ {"scl", obj_coff_scl, 0},
+ {"size", obj_coff_size, 0},
+ {"tag", obj_coff_tag, 0},
+ {"type", obj_coff_type, 0},
+ {"val", obj_coff_val, 0},
+ {"section", obj_coff_section, 0},
+ {"sect", obj_coff_section, 0},
+ /* FIXME: We ignore the MRI short attribute. */
+ {"section.s", obj_coff_section, 0},
+ {"sect.s", obj_coff_section, 0},
+ /* We accept the .bss directive for backward compatibility with
+ earlier versions of gas. */
+ {"bss", obj_coff_bss, 0},
+ {"weak", obj_coff_weak, 0},
+#ifndef BFD_ASSEMBLER
+ {"use", obj_coff_section, 0},
+ {"text", obj_coff_text, 0},
+ {"data", obj_coff_data, 0},
+ {"lcomm", obj_coff_lcomm, 0},
+ {"ident", obj_coff_ident, 0},
+#else
+ {"optim", s_ignore, 0}, /* For sun386i cc (?) */
+ {"ident", s_ignore, 0}, /* we don't yet handle this. */
+#endif
+ {"version", s_ignore, 0},
+ {"ABORT", s_abort, 0},
+#ifdef TC_M88K
+ /* The m88k uses sdef instead of def. */
+ {"sdef", obj_coff_def, 0},
+#endif
+ {NULL} /* end sentinel */
+}; /* obj_pseudo_table */
+
+#ifdef BFD_ASSEMBLER
+
+/* Support for a COFF emulation. */
+
+static void
+coff_pop_insert ()
+{
+ pop_insert (obj_pseudo_table);
+}
+
+static int
+coff_sec_sym_ok_for_reloc (sec)
+ asection *sec;
+{
+ return 0;
+}
+
+static void
+no_func ()
+{
+ abort ();
+}
+
+const struct format_ops coff_format_ops =
+{
+ bfd_target_coff_flavour,
+ 0,
+ 1,
+ coff_frob_symbol,
+ no_func,
+ coff_frob_file_after_relocs,
+ 0, 0,
+ 0, 0,
+ 0,
+#if 0
+ obj_generate_asm_lineno,
+#else
+ no_func,
+#endif
+#if 0
+ obj_stab,
+#else
+ no_func,
+#endif
+ coff_sec_sym_ok_for_reloc,
+ coff_pop_insert,
+#if 0
+ obj_set_ext,
+#else
+ no_func,
+#endif
+ coff_obj_read_begin_hook,
+ coff_obj_symbol_new_hook,
+};
+
+#endif
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
new file mode 100644
index 00000000000..465047796f6
--- /dev/null
+++ b/gas/config/obj-coff.h
@@ -0,0 +1,841 @@
+/* coff object file format
+ Copyright (C) 1989, 90, 91, 92, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef OBJ_FORMAT_H
+#define OBJ_FORMAT_H
+
+#define OBJ_COFF 1
+
+#ifndef BFD_ASSEMBLER
+
+#define WORKING_DOT_WORD
+#define WARN_SIGNED_OVERFLOW_WORD
+#define OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define BFD_HEADERS
+#define BFD
+
+#endif
+
+#include "targ-cpu.h"
+
+#include "bfd.h"
+
+/* This internal_lineno crap is to stop namespace pollution from the
+ bfd internal coff headerfile. */
+#define internal_lineno bfd_internal_lineno
+#include "coff/internal.h"
+#undef internal_lineno
+
+/* CPU-specific setup: */
+
+#ifdef TC_ARM
+#include "coff/arm.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "coff-arm"
+#endif
+#endif
+
+#ifdef TC_PPC
+#ifdef TE_PE
+#include "coff/powerpc.h"
+#else
+#include "coff/rs6000.h"
+#endif
+#endif
+
+#ifdef TC_SPARC
+#include "coff/sparc.h"
+#endif
+
+#ifdef TC_I386
+#include "coff/i386.h"
+
+#ifdef TE_PE
+#define TARGET_FORMAT "pe-i386"
+#endif
+
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "coff-i386"
+#endif
+#endif
+
+#ifdef TC_M68K
+#include "coff/m68k.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "coff-m68k"
+#endif
+#endif
+
+#ifdef TC_A29K
+#include "coff/a29k.h"
+#define TARGET_FORMAT "coff-a29k-big"
+#endif
+
+#ifdef TC_I960
+#include "coff/i960.h"
+#define TARGET_FORMAT "coff-Intel-little"
+#endif
+
+#ifdef TC_Z8K
+#include "coff/z8k.h"
+#define TARGET_FORMAT "coff-z8k"
+#endif
+
+#ifdef TC_H8300
+#include "coff/h8300.h"
+#define TARGET_FORMAT "coff-h8300"
+#endif
+
+#ifdef TC_H8500
+#include "coff/h8500.h"
+#define TARGET_FORMAT "coff-h8500"
+#endif
+
+#ifdef TC_SH
+#include "coff/sh.h"
+#define TARGET_FORMAT \
+ (shl \
+ ? (sh_small ? "coff-shl-small" : "coff-shl") \
+ : (sh_small ? "coff-sh-small" : "coff-sh"))
+#endif
+
+#ifdef TC_M88K
+#include "coff/m88k.h"
+#define TARGET_FORMAT "coff-m88kbcs"
+#endif
+
+#ifdef TC_W65
+#include "coff/w65.h"
+#define TARGET_FORMAT "coff-w65"
+#endif
+
+#ifdef TC_TIC30
+#include "coff/tic30.h"
+#define TARGET_FORMAT "coff-tic30"
+#endif
+
+#ifdef TC_TIC80
+#include "coff/tic80.h"
+#define TARGET_FORMAT "coff-tic80"
+#define ALIGNMENT_IN_S_FLAGS 1
+#endif
+
+#ifdef TC_MCORE
+#include "coff/mcore.h"
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "pe-mcore"
+#endif
+#endif
+
+/* Targets may also set this. Also, if BFD_ASSEMBLER is defined, this
+ will already have been defined. */
+#undef SYMBOLS_NEED_BACKPOINTERS
+#define SYMBOLS_NEED_BACKPOINTERS 1
+
+#ifndef OBJ_COFF_MAX_AUXENTRIES
+#define OBJ_COFF_MAX_AUXENTRIES 1
+#endif /* OBJ_COFF_MAX_AUXENTRIES */
+
+extern void coff_obj_symbol_new_hook PARAMS ((struct symbol *));
+#define obj_symbol_new_hook coff_obj_symbol_new_hook
+
+extern void coff_obj_read_begin_hook PARAMS ((void));
+#define obj_read_begin_hook coff_obj_read_begin_hook
+
+/* ***********************************************************************
+
+ This file really contains two implementations of the COFF back end.
+ They are in the process of being merged, but this is only a
+ preliminary, mechanical merging. Many definitions that are
+ identical between the two are still found in both versions.
+
+ The first version, with BFD_ASSEMBLER defined, uses high-level BFD
+ interfaces and data structures. The second version, with
+ BFD_ASSEMBLER not defined, also uses BFD, but mostly for swapping
+ data structures and for doing the actual I/O. The latter defines
+ the preprocessor symbols BFD and BFD_HEADERS. Try not to let this
+ confuse you.
+
+ These two are in the process of being merged, and eventually the
+ BFD_ASSEMBLER version should take over completely. Release timing
+ issues and namespace problems convinced me to merge the two
+ together in this fashion, a little sooner than I would have liked.
+ The real merge should be much better done by the time the next
+ release comes out.
+
+ For now, the structure of this file is:
+ <common>
+ #ifdef BFD_ASSEMBLER
+ <one version>
+ #else
+ <other version>
+ #endif
+ <common>
+ Unfortunately, the common portions are very small at the moment,
+ and many declarations or definitions are duplicated. The structure
+ of obj-coff.c is similar.
+
+ See doc/internals.texi for a brief discussion of the history, if
+ you care.
+
+ Ken Raeburn, 5 May 1994
+
+ *********************************************************************** */
+
+#ifdef BFD_ASSEMBLER
+
+#include "bfd/libcoff.h"
+
+#define OUTPUT_FLAVOR bfd_target_coff_flavour
+
+/* SYMBOL TABLE */
+
+/* Alter the field names, for now, until we've fixed up the other
+ references to use the new name. */
+#ifdef TC_I960
+#define TC_SYMFIELD_TYPE struct symbol *
+#define sy_tc bal
+#endif
+
+#define OBJ_SYMFIELD_TYPE unsigned long
+#define sy_obj sy_flags
+
+#define SYM_AUXENT(S) (&coffsymbol ((S)->bsym)->native[1].u.auxent)
+#define SYM_AUXINFO(S) (&coffsymbol ((S)->bsym)->native[1])
+
+#define DO_NOT_STRIP 0
+
+extern void obj_coff_section PARAMS ((int));
+
+/* The number of auxiliary entries */
+#define S_GET_NUMBER_AUXILIARY(s) (coffsymbol((s)->bsym)->native->u.syment.n_numaux)
+/* The number of auxiliary entries */
+#define S_SET_NUMBER_AUXILIARY(s,v) (S_GET_NUMBER_AUXILIARY (s) = (v))
+
+/* True if a symbol name is in the string table, i.e. its length is > 8. */
+#define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0)
+
+extern int S_SET_DATA_TYPE PARAMS ((struct symbol *, int));
+extern int S_SET_STORAGE_CLASS PARAMS ((struct symbol *, int));
+extern int S_GET_STORAGE_CLASS PARAMS ((struct symbol *));
+extern void SA_SET_SYM_ENDNDX PARAMS ((struct symbol *, struct symbol *));
+
+/* Auxiliary entry macros. SA_ stands for symbol auxiliary */
+/* Omit the tv related fields */
+/* Accessors */
+
+#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx.l)
+#define SA_GET_SYM_LNNO(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno)
+#define SA_GET_SYM_SIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size)
+#define SA_GET_SYM_FSIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize)
+#define SA_GET_SYM_LNNOPTR(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx)
+#define SA_GET_SYM_DIMEN(s,i) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)])
+#define SA_GET_FILE_FNAME(s) (SYM_AUXENT (s)->x_file.x_fname)
+#define SA_GET_SCN_SCNLEN(s) (SYM_AUXENT (s)->x_scn.x_scnlen)
+#define SA_GET_SCN_NRELOC(s) (SYM_AUXENT (s)->x_scn.x_nreloc)
+#define SA_GET_SCN_NLINNO(s) (SYM_AUXENT (s)->x_scn.x_nlinno)
+
+#define SA_SET_SYM_LNNO(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno=(v))
+#define SA_SET_SYM_SIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size=(v))
+#define SA_SET_SYM_FSIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize=(v))
+#define SA_SET_SYM_LNNOPTR(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr=(v))
+#define SA_SET_SYM_DIMEN(s,i,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v))
+#define SA_SET_FILE_FNAME(s,v) strncpy(SYM_AUXENT (s)->x_file.x_fname,(v),FILNMLEN)
+#define SA_SET_SCN_SCNLEN(s,v) (SYM_AUXENT (s)->x_scn.x_scnlen=(v))
+#define SA_SET_SCN_NRELOC(s,v) (SYM_AUXENT (s)->x_scn.x_nreloc=(v))
+#define SA_SET_SCN_NLINNO(s,v) (SYM_AUXENT (s)->x_scn.x_nlinno=(v))
+
+/*
+ * Internal use only definitions. SF_ stands for symbol flags.
+ *
+ * These values can be assigned to sy_symbol.ost_flags field of a symbolS.
+ *
+ * You'll break i960 if you shift the SYSPROC bits anywhere else. for
+ * more on the balname/callname hack, see tc-i960.h. b.out is done
+ * differently.
+ */
+
+#define SF_I960_MASK (0x000001ff) /* Bits 0-8 are used by the i960 port. */
+#define SF_SYSPROC (0x0000003f) /* bits 0-5 are used to store the sysproc number */
+#define SF_IS_SYSPROC (0x00000040) /* bit 6 marks symbols that are sysprocs */
+#define SF_BALNAME (0x00000080) /* bit 7 marks BALNAME symbols */
+#define SF_CALLNAME (0x00000100) /* bit 8 marks CALLNAME symbols */
+
+#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */
+
+#define SF_STATICS (0x00001000) /* Mark the .text & all symbols */
+#define SF_DEFINED (0x00002000) /* Symbol is defined in this file */
+#define SF_STRING (0x00004000) /* Symbol name length > 8 */
+#define SF_LOCAL (0x00008000) /* Symbol must not be emitted */
+
+#define SF_DEBUG_MASK (0xffff0000) /* bits 16-31 are debug info */
+
+#define SF_FUNCTION (0x00010000) /* The symbol is a function */
+#define SF_PROCESS (0x00020000) /* Process symbol before write */
+#define SF_TAGGED (0x00040000) /* Is associated with a tag */
+#define SF_TAG (0x00080000) /* Is a tag */
+#define SF_DEBUG (0x00100000) /* Is in debug or abs section */
+#define SF_GET_SEGMENT (0x00200000) /* Get the section of the forward symbol. */
+/* All other bits are unused. */
+
+/* Accessors */
+#define SF_GET(s) ((s)->sy_flags)
+#define SF_GET_DEBUG(s) ((s)->bsym->flags & BSF_DEBUGGING)
+#define SF_SET_DEBUG(s) ((s)->bsym->flags |= BSF_DEBUGGING)
+#define SF_GET_NORMAL_FIELD(s) (SF_GET (s) & SF_NORMAL_MASK)
+#define SF_GET_DEBUG_FIELD(s) (SF_GET (s) & SF_DEBUG_MASK)
+#define SF_GET_FILE(s) (SF_GET (s) & SF_FILE)
+#define SF_GET_STATICS(s) (SF_GET (s) & SF_STATICS)
+#define SF_GET_DEFINED(s) (SF_GET (s) & SF_DEFINED)
+#define SF_GET_STRING(s) (SF_GET (s) & SF_STRING)
+#define SF_GET_LOCAL(s) (SF_GET (s) & SF_LOCAL)
+#define SF_GET_FUNCTION(s) (SF_GET (s) & SF_FUNCTION)
+#define SF_GET_PROCESS(s) (SF_GET (s) & SF_PROCESS)
+#define SF_GET_TAGGED(s) (SF_GET (s) & SF_TAGGED)
+#define SF_GET_TAG(s) (SF_GET (s) & SF_TAG)
+#define SF_GET_GET_SEGMENT(s) (SF_GET (s) & SF_GET_SEGMENT)
+#define SF_GET_I960(s) (SF_GET (s) & SF_I960_MASK) /* used by i960 */
+#define SF_GET_BALNAME(s) (SF_GET (s) & SF_BALNAME) /* used by i960 */
+#define SF_GET_CALLNAME(s) (SF_GET (s) & SF_CALLNAME) /* used by i960 */
+#define SF_GET_IS_SYSPROC(s) (SF_GET (s) & SF_IS_SYSPROC) /* used by i960 */
+#define SF_GET_SYSPROC(s) (SF_GET (s) & SF_SYSPROC) /* used by i960 */
+
+/* Modifiers */
+#define SF_SET(s,v) (SF_GET (s) = (v))
+#define SF_SET_NORMAL_FIELD(s,v)(SF_GET (s) |= ((v) & SF_NORMAL_MASK))
+#define SF_SET_DEBUG_FIELD(s,v) (SF_GET (s) |= ((v) & SF_DEBUG_MASK))
+#define SF_SET_FILE(s) (SF_GET (s) |= SF_FILE)
+#define SF_SET_STATICS(s) (SF_GET (s) |= SF_STATICS)
+#define SF_SET_DEFINED(s) (SF_GET (s) |= SF_DEFINED)
+#define SF_SET_STRING(s) (SF_GET (s) |= SF_STRING)
+#define SF_SET_LOCAL(s) (SF_GET (s) |= SF_LOCAL)
+#define SF_CLEAR_LOCAL(s) (SF_GET (s) &= ~SF_LOCAL)
+#define SF_SET_FUNCTION(s) (SF_GET (s) |= SF_FUNCTION)
+#define SF_SET_PROCESS(s) (SF_GET (s) |= SF_PROCESS)
+#define SF_SET_TAGGED(s) (SF_GET (s) |= SF_TAGGED)
+#define SF_SET_TAG(s) (SF_GET (s) |= SF_TAG)
+#define SF_SET_GET_SEGMENT(s) (SF_GET (s) |= SF_GET_SEGMENT)
+#define SF_SET_I960(s,v) (SF_GET (s) |= ((v) & SF_I960_MASK)) /* used by i960 */
+#define SF_SET_BALNAME(s) (SF_GET (s) |= SF_BALNAME) /* used by i960 */
+#define SF_SET_CALLNAME(s) (SF_GET (s) |= SF_CALLNAME) /* used by i960 */
+#define SF_SET_IS_SYSPROC(s) (SF_GET (s) |= SF_IS_SYSPROC) /* used by i960 */
+#define SF_SET_SYSPROC(s,v) (SF_GET (s) |= ((v) & SF_SYSPROC)) /* used by i960 */
+
+/* -------------- Line number handling ------- */
+extern int text_lineno_number;
+extern int coff_line_base;
+extern int coff_n_line_nos;
+
+#define obj_emit_lineno(WHERE,LINE,FILE_START) abort ()
+extern void coff_add_linesym PARAMS ((struct symbol *));
+
+
+void c_dot_file_symbol PARAMS ((char *filename));
+#define obj_app_file c_dot_file_symbol
+
+extern void coff_frob_symbol PARAMS ((struct symbol *, int *));
+extern void coff_adjust_symtab PARAMS ((void));
+extern void coff_frob_section PARAMS ((segT));
+extern void coff_adjust_section_syms PARAMS ((bfd *, asection *, PTR));
+extern void coff_frob_file_after_relocs PARAMS ((void));
+#define obj_frob_symbol(S,P) coff_frob_symbol(S,&P)
+#ifndef obj_adjust_symtab
+#define obj_adjust_symtab() coff_adjust_symtab()
+#endif
+#define obj_frob_section(S) coff_frob_section (S)
+#define obj_frob_file_after_relocs() coff_frob_file_after_relocs ()
+
+extern struct symbol *coff_last_function;
+
+/* Forward the segment of a forwarded symbol, handle assignments that
+ just copy symbol values, etc. */
+#ifndef TE_I386AIX
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+ (SF_GET_GET_SEGMENT (dest) \
+ ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \
+ : 0)
+#else
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+ (SF_GET_GET_SEGMENT (dest) && S_GET_SEGMENT (dest) == SEG_UNKNOWN \
+ ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \
+ : 0)
+#endif
+
+/* sanity check */
+
+#ifdef TC_I960
+#ifndef C_LEAFSTAT
+hey ! Where is the C_LEAFSTAT definition ? i960 - coff support is depending on it.
+#endif /* no C_LEAFSTAT */
+#endif /* TC_I960 */
+
+#else /* not BFD_ASSEMBLER */
+
+#ifdef TC_A29K
+/* Allow translate from aout relocs to coff relocs */
+#define NO_RELOC 20
+#define RELOC_32 1
+#define RELOC_8 2
+#define RELOC_CONST 3
+#define RELOC_CONSTH 4
+#define RELOC_JUMPTARG 5
+#define RELOC_BASE22 6
+#define RELOC_HI22 7
+#define RELOC_LO10 8
+#define RELOC_BASE13 9
+#define RELOC_WDISP22 10
+#define RELOC_WDISP30 11
+#endif
+
+extern const segT N_TYPE_seg[];
+
+/* Magic number of paged executable. */
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 0x8300
+
+
+/* SYMBOL TABLE */
+
+/* Symbol table entry data type */
+
+typedef struct
+{
+ /* Basic symbol */
+ struct internal_syment ost_entry;
+ /* Auxiliary entry. */
+ union internal_auxent ost_auxent[OBJ_COFF_MAX_AUXENTRIES];
+ /* obj_coff internal use only flags */
+ unsigned int ost_flags;
+} obj_symbol_type;
+
+#ifndef DO_NOT_STRIP
+#define DO_NOT_STRIP 0
+#endif
+/* Symbol table macros and constants */
+
+/* Possible and usefull section number in symbol table
+ * The values of TEXT, DATA and BSS may not be portable.
+ */
+
+#define C_ABS_SECTION N_ABS
+#define C_UNDEF_SECTION N_UNDEF
+#define C_DEBUG_SECTION N_DEBUG
+#define C_NTV_SECTION N_TV
+#define C_PTV_SECTION P_TV
+#define C_REGISTER_SECTION 50
+
+/*
+ * Macros to extract information from a symbol table entry.
+ * This syntaxic indirection allows independence regarding a.out or coff.
+ * The argument (s) of all these macros is a pointer to a symbol table entry.
+ */
+
+/* Predicates */
+/* True if the symbol is external */
+#define S_IS_EXTERNAL(s) ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION)
+/* True if symbol has been defined, ie :
+ section > 0 (DATA, TEXT or BSS)
+ section == 0 and value > 0 (external bss symbol) */
+#define S_IS_DEFINED(s) \
+ ((s)->sy_symbol.ost_entry.n_scnum > C_UNDEF_SECTION \
+ || ((s)->sy_symbol.ost_entry.n_scnum == C_UNDEF_SECTION \
+ && S_GET_VALUE (s) > 0) \
+ || ((s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION))
+/* True if a debug special symbol entry */
+#define S_IS_DEBUG(s) ((s)->sy_symbol.ost_entry.n_scnum == C_DEBUG_SECTION)
+/* True if a symbol is local symbol name */
+/* A symbol name whose name includes ^A is a gas internal pseudo symbol */
+#define S_IS_LOCAL(s) \
+ ((s)->sy_symbol.ost_entry.n_scnum == C_REGISTER_SECTION \
+ || (S_LOCAL_NAME(s) && ! flag_keep_locals && ! S_IS_DEBUG (s)) \
+ || strchr (S_GET_NAME (s), '\001') != NULL \
+ || strchr (S_GET_NAME (s), '\002') != NULL \
+ || (flag_strip_local_absolute \
+ && !S_IS_EXTERNAL(s) \
+ && (s)->sy_symbol.ost_entry.n_scnum == C_ABS_SECTION))
+/* True if a symbol is not defined in this file */
+#define S_IS_EXTERN(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \
+ && S_GET_VALUE (s) == 0)
+/*
+ * True if a symbol can be multiply defined (bss symbols have this def
+ * though it is bad practice)
+ */
+#define S_IS_COMMON(s) ((s)->sy_symbol.ost_entry.n_scnum == 0 \
+ && S_GET_VALUE (s) != 0)
+/* True if a symbol name is in the string table, i.e. its length is > 8. */
+#define S_IS_STRING(s) (strlen(S_GET_NAME(s)) > 8 ? 1 : 0)
+
+/* True if a symbol is defined as weak. */
+#ifdef TE_PE
+#define S_IS_WEAK(s) \
+ ((s)->sy_symbol.ost_entry.n_sclass == C_NT_WEAK \
+ || (s)->sy_symbol.ost_entry.n_sclass == C_WEAKEXT)
+#else
+#define S_IS_WEAK(s) \
+ ((s)->sy_symbol.ost_entry.n_sclass == C_WEAKEXT)
+#endif
+
+/* Accessors */
+/* The name of the symbol */
+#define S_GET_NAME(s) ((char*)(s)->sy_symbol.ost_entry.n_offset)
+/* The pointer to the string table */
+#define S_GET_OFFSET(s) ((s)->sy_symbol.ost_entry.n_offset)
+/* The numeric value of the segment */
+#define S_GET_SEGMENT(s) s_get_segment(s)
+/* The data type */
+#define S_GET_DATA_TYPE(s) ((s)->sy_symbol.ost_entry.n_type)
+/* The storage class */
+#define S_GET_STORAGE_CLASS(s) ((s)->sy_symbol.ost_entry.n_sclass)
+/* The number of auxiliary entries */
+#define S_GET_NUMBER_AUXILIARY(s) ((s)->sy_symbol.ost_entry.n_numaux)
+
+/* Modifiers */
+/* Set the name of the symbol */
+#define S_SET_NAME(s,v) ((s)->sy_symbol.ost_entry.n_offset = (unsigned long)(v))
+/* Set the offset of the symbol */
+#define S_SET_OFFSET(s,v) ((s)->sy_symbol.ost_entry.n_offset = (v))
+/* The numeric value of the segment */
+#define S_SET_SEGMENT(s,v) ((s)->sy_symbol.ost_entry.n_scnum = SEGMENT_TO_SYMBOL_TYPE(v))
+/* The data type */
+#define S_SET_DATA_TYPE(s,v) ((s)->sy_symbol.ost_entry.n_type = (v))
+/* The storage class */
+#define S_SET_STORAGE_CLASS(s,v) ((s)->sy_symbol.ost_entry.n_sclass = (v))
+/* The number of auxiliary entries */
+#define S_SET_NUMBER_AUXILIARY(s,v) ((s)->sy_symbol.ost_entry.n_numaux = (v))
+
+/* Additional modifiers */
+/* The symbol is external (does not mean undefined) */
+#define S_SET_EXTERNAL(s) { S_SET_STORAGE_CLASS(s, C_EXT) ; SF_CLEAR_LOCAL(s); }
+
+/* Auxiliary entry macros. SA_ stands for symbol auxiliary */
+/* Omit the tv related fields */
+/* Accessors */
+#define SYM_AUXENT(S) (&(S)->sy_symbol.ost_auxent[0])
+
+#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx.l)
+#define SA_GET_SYM_LNNO(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno)
+#define SA_GET_SYM_SIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size)
+#define SA_GET_SYM_FSIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize)
+#define SA_GET_SYM_LNNOPTR(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx.l)
+#define SA_GET_SYM_DIMEN(s,i) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)])
+#define SA_GET_FILE_FNAME(s) (SYM_AUXENT (s)->x_file.x_fname)
+#define SA_GET_FILE_FNAME_OFFSET(s) (SYM_AUXENT (s)->x_file.x_n.x_offset)
+#define SA_GET_FILE_FNAME_ZEROS(s) (SYM_AUXENT (s)->x_file.x_n.x_zeroes)
+#define SA_GET_SCN_SCNLEN(s) (SYM_AUXENT (s)->x_scn.x_scnlen)
+#define SA_GET_SCN_NRELOC(s) (SYM_AUXENT (s)->x_scn.x_nreloc)
+#define SA_GET_SCN_NLINNO(s) (SYM_AUXENT (s)->x_scn.x_nlinno)
+
+/* Modifiers */
+#define SA_SET_SYM_TAGNDX(s,v) (SYM_AUXENT (s)->x_sym.x_tagndx.l=(v))
+#define SA_SET_SYM_LNNO(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno=(v))
+#define SA_SET_SYM_SIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size=(v))
+#define SA_SET_SYM_FSIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize=(v))
+#define SA_SET_SYM_LNNOPTR(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr=(v))
+#define SA_SET_SYM_ENDNDX(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx.l=(v))
+#define SA_SET_SYM_DIMEN(s,i,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]=(v))
+#define SA_SET_FILE_FNAME(s,v) strncpy(SYM_AUXENT (s)->x_file.x_fname,(v),FILNMLEN)
+#define SA_SET_FILE_FNAME_OFFSET(s,v) (SYM_AUXENT (s)->x_file.x_n.x_offset=(v))
+#define SA_SET_FILE_FNAME_ZEROS(s,v) (SYM_AUXENT (s)->x_file.x_n.x_zeroes=(v))
+#define SA_SET_SCN_SCNLEN(s,v) (SYM_AUXENT (s)->x_scn.x_scnlen=(v))
+#define SA_SET_SCN_NRELOC(s,v) (SYM_AUXENT (s)->x_scn.x_nreloc=(v))
+#define SA_SET_SCN_NLINNO(s,v) (SYM_AUXENT (s)->x_scn.x_nlinno=(v))
+
+/*
+ * Internal use only definitions. SF_ stands for symbol flags.
+ *
+ * These values can be assigned to sy_symbol.ost_flags field of a symbolS.
+ *
+ * You'll break i960 if you shift the SYSPROC bits anywhere else. for
+ * more on the balname/callname hack, see tc-i960.h. b.out is done
+ * differently.
+ */
+
+#define SF_I960_MASK (0x000001ff) /* Bits 0-8 are used by the i960 port. */
+#define SF_SYSPROC (0x0000003f) /* bits 0-5 are used to store the sysproc number */
+#define SF_IS_SYSPROC (0x00000040) /* bit 6 marks symbols that are sysprocs */
+#define SF_BALNAME (0x00000080) /* bit 7 marks BALNAME symbols */
+#define SF_CALLNAME (0x00000100) /* bit 8 marks CALLNAME symbols */
+
+#define SF_NORMAL_MASK (0x0000ffff) /* bits 12-15 are general purpose. */
+
+#define SF_STATICS (0x00001000) /* Mark the .text & all symbols */
+#define SF_DEFINED (0x00002000) /* Symbol is defined in this file */
+#define SF_STRING (0x00004000) /* Symbol name length > 8 */
+#define SF_LOCAL (0x00008000) /* Symbol must not be emitted */
+
+#define SF_DEBUG_MASK (0xffff0000) /* bits 16-31 are debug info */
+
+#define SF_FUNCTION (0x00010000) /* The symbol is a function */
+#define SF_PROCESS (0x00020000) /* Process symbol before write */
+#define SF_TAGGED (0x00040000) /* Is associated with a tag */
+#define SF_TAG (0x00080000) /* Is a tag */
+#define SF_DEBUG (0x00100000) /* Is in debug or abs section */
+#define SF_GET_SEGMENT (0x00200000) /* Get the section of the forward symbol. */
+#define SF_ADJ_LNNOPTR (0x00400000) /* Has a lnnoptr */
+/* All other bits are unused. */
+
+/* Accessors */
+#define SF_GET(s) ((s)->sy_symbol.ost_flags)
+#define SF_GET_NORMAL_FIELD(s) (SF_GET (s) & SF_NORMAL_MASK)
+#define SF_GET_DEBUG_FIELD(s) (SF_GET (s) & SF_DEBUG_MASK)
+#define SF_GET_FILE(s) (SF_GET (s) & SF_FILE)
+#define SF_GET_STATICS(s) (SF_GET (s) & SF_STATICS)
+#define SF_GET_DEFINED(s) (SF_GET (s) & SF_DEFINED)
+#define SF_GET_STRING(s) (SF_GET (s) & SF_STRING)
+#define SF_GET_LOCAL(s) (SF_GET (s) & SF_LOCAL)
+#define SF_GET_FUNCTION(s) (SF_GET (s) & SF_FUNCTION)
+#define SF_GET_PROCESS(s) (SF_GET (s) & SF_PROCESS)
+#define SF_GET_DEBUG(s) (SF_GET (s) & SF_DEBUG)
+#define SF_GET_TAGGED(s) (SF_GET (s) & SF_TAGGED)
+#define SF_GET_TAG(s) (SF_GET (s) & SF_TAG)
+#define SF_GET_GET_SEGMENT(s) (SF_GET (s) & SF_GET_SEGMENT)
+#define SF_GET_ADJ_LNNOPTR(s) (SF_GET (s) & SF_ADJ_LNNOPTR)
+#define SF_GET_I960(s) (SF_GET (s) & SF_I960_MASK) /* used by i960 */
+#define SF_GET_BALNAME(s) (SF_GET (s) & SF_BALNAME) /* used by i960 */
+#define SF_GET_CALLNAME(s) (SF_GET (s) & SF_CALLNAME) /* used by i960 */
+#define SF_GET_IS_SYSPROC(s) (SF_GET (s) & SF_IS_SYSPROC) /* used by i960 */
+#define SF_GET_SYSPROC(s) (SF_GET (s) & SF_SYSPROC) /* used by i960 */
+
+/* Modifiers */
+#define SF_SET(s,v) (SF_GET (s) = (v))
+#define SF_SET_NORMAL_FIELD(s,v)(SF_GET (s) |= ((v) & SF_NORMAL_MASK))
+#define SF_SET_DEBUG_FIELD(s,v) (SF_GET (s) |= ((v) & SF_DEBUG_MASK))
+#define SF_SET_FILE(s) (SF_GET (s) |= SF_FILE)
+#define SF_SET_STATICS(s) (SF_GET (s) |= SF_STATICS)
+#define SF_SET_DEFINED(s) (SF_GET (s) |= SF_DEFINED)
+#define SF_SET_STRING(s) (SF_GET (s) |= SF_STRING)
+#define SF_SET_LOCAL(s) (SF_GET (s) |= SF_LOCAL)
+#define SF_CLEAR_LOCAL(s) (SF_GET (s) &= ~SF_LOCAL)
+#define SF_SET_FUNCTION(s) (SF_GET (s) |= SF_FUNCTION)
+#define SF_SET_PROCESS(s) (SF_GET (s) |= SF_PROCESS)
+#define SF_SET_DEBUG(s) (SF_GET (s) |= SF_DEBUG)
+#define SF_SET_TAGGED(s) (SF_GET (s) |= SF_TAGGED)
+#define SF_SET_TAG(s) (SF_GET (s) |= SF_TAG)
+#define SF_SET_GET_SEGMENT(s) (SF_GET (s) |= SF_GET_SEGMENT)
+#define SF_SET_ADJ_LNNOPTR(s) (SF_GET (s) |= SF_ADJ_LNNOPTR)
+#define SF_SET_I960(s,v) (SF_GET (s) |= ((v) & SF_I960_MASK)) /* used by i960 */
+#define SF_SET_BALNAME(s) (SF_GET (s) |= SF_BALNAME) /* used by i960 */
+#define SF_SET_CALLNAME(s) (SF_GET (s) |= SF_CALLNAME) /* used by i960 */
+#define SF_SET_IS_SYSPROC(s) (SF_GET (s) |= SF_IS_SYSPROC) /* used by i960 */
+#define SF_SET_SYSPROC(s,v) (SF_GET (s) |= ((v) & SF_SYSPROC)) /* used by i960 */
+
+/* File header macro and type definition */
+
+/*
+ * File position calculators. Beware to use them when all the
+ * appropriate fields are set in the header.
+ */
+
+#ifdef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define OBJ_COFF_AOUTHDRSZ (0)
+#else
+#define OBJ_COFF_AOUTHDRSZ (AOUTHDRSZ)
+#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+
+#define H_GET_FILE_SIZE(h) \
+ (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h) + \
+ H_GET_SYMBOL_TABLE_SIZE(h) + \
+ (h)->string_table_size)
+#define H_GET_TEXT_FILE_OFFSET(h) \
+ (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ)
+#define H_GET_DATA_FILE_OFFSET(h) \
+ (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h))
+#define H_GET_BSS_FILE_OFFSET(h) 0
+#define H_GET_RELOCATION_FILE_OFFSET(h) \
+ (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h))
+#define H_GET_LINENO_FILE_OFFSET(h) \
+ (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_RELOCATION_SIZE(h))
+#define H_GET_SYMBOL_TABLE_FILE_OFFSET(h) \
+ (long)(FILHSZ + OBJ_COFF_AOUTHDRSZ + \
+ H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ + \
+ H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
+ H_GET_RELOCATION_SIZE(h) + H_GET_LINENO_SIZE(h))
+
+/* Accessors */
+/* aouthdr */
+#define H_GET_MAGIC_NUMBER(h) ((h)->aouthdr.magic)
+#define H_GET_VERSION_STAMP(h) ((h)->aouthdr.vstamp)
+#define H_GET_TEXT_SIZE(h) ((h)->aouthdr.tsize)
+#define H_GET_DATA_SIZE(h) ((h)->aouthdr.dsize)
+#define H_GET_BSS_SIZE(h) ((h)->aouthdr.bsize)
+#define H_GET_ENTRY_POINT(h) ((h)->aouthdr.entry)
+#define H_GET_TEXT_START(h) ((h)->aouthdr.text_start)
+#define H_GET_DATA_START(h) ((h)->aouthdr.data_start)
+/* filehdr */
+#define H_GET_FILE_MAGIC_NUMBER(h) ((h)->filehdr.f_magic)
+#define H_GET_NUMBER_OF_SECTIONS(h) ((h)->filehdr.f_nscns)
+#define H_GET_TIME_STAMP(h) ((h)->filehdr.f_timdat)
+#define H_GET_SYMBOL_TABLE_POINTER(h) ((h)->filehdr.f_symptr)
+#define H_GET_SYMBOL_COUNT(h) ((h)->filehdr.f_nsyms)
+#define H_GET_SYMBOL_TABLE_SIZE(h) (H_GET_SYMBOL_COUNT(h) * SYMESZ)
+#define H_GET_SIZEOF_OPTIONAL_HEADER(h) ((h)->filehdr.f_opthdr)
+#define H_GET_FLAGS(h) ((h)->filehdr.f_flags)
+/* Extra fields to achieve bsd a.out compatibility and for convenience */
+#define H_GET_RELOCATION_SIZE(h) ((h)->relocation_size)
+#define H_GET_STRING_SIZE(h) ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h) ((h)->lineno_size)
+
+#ifndef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#define H_GET_HEADER_SIZE(h) (sizeof(FILHDR) \
+ + sizeof(AOUTHDR)\
+ + (H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ))
+#else /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+#define H_GET_HEADER_SIZE(h) (sizeof(FILHDR) \
+ + (H_GET_NUMBER_OF_SECTIONS(h) * SCNHSZ))
+#endif /* OBJ_COFF_OMIT_OPTIONAL_HEADER */
+
+#define H_GET_TEXT_RELOCATION_SIZE(h) (text_section_header.s_nreloc * RELSZ)
+#define H_GET_DATA_RELOCATION_SIZE(h) (data_section_header.s_nreloc * RELSZ)
+
+/* Modifiers */
+/* aouthdr */
+#define H_SET_MAGIC_NUMBER(h,v) ((h)->aouthdr.magic = (v))
+#define H_SET_VERSION_STAMP(h,v) ((h)->aouthdr.vstamp = (v))
+#define H_SET_TEXT_SIZE(h,v) ((h)->aouthdr.tsize = (v))
+#define H_SET_DATA_SIZE(h,v) ((h)->aouthdr.dsize = (v))
+#define H_SET_BSS_SIZE(h,v) ((h)->aouthdr.bsize = (v))
+#define H_SET_ENTRY_POINT(h,v) ((h)->aouthdr.entry = (v))
+#define H_SET_TEXT_START(h,v) ((h)->aouthdr.text_start = (v))
+#define H_SET_DATA_START(h,v) ((h)->aouthdr.data_start = (v))
+/* filehdr */
+#define H_SET_FILE_MAGIC_NUMBER(h,v) ((h)->filehdr.f_magic = (v))
+#define H_SET_NUMBER_OF_SECTIONS(h,v) ((h)->filehdr.f_nscns = (v))
+#define H_SET_TIME_STAMP(h,v) ((h)->filehdr.f_timdat = (v))
+#define H_SET_SYMBOL_TABLE_POINTER(h,v) ((h)->filehdr.f_symptr = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->filehdr.f_nsyms = (v))
+#define H_SET_SIZEOF_OPTIONAL_HEADER(h,v) ((h)->filehdr.f_opthdr = (v))
+#define H_SET_FLAGS(h,v) ((h)->filehdr.f_flags = (v))
+/* Extra fields to achieve bsd a.out compatibility and for convinience */
+#define H_SET_RELOCATION_SIZE(h,t,d) ((h)->relocation_size = (t)+(d))
+#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v))
+#define H_SET_LINENO_SIZE(h,v) ((h)->lineno_size = (v))
+
+/* Segment flipping */
+
+typedef struct
+{
+ struct internal_aouthdr aouthdr; /* a.out header */
+ struct internal_filehdr filehdr; /* File header, not machine dep. */
+ long string_table_size; /* names + '\0' + sizeof(int) */
+ long relocation_size; /* Cumulated size of relocation
+ information for all sections in
+ bytes. */
+ long lineno_size; /* Size of the line number information
+ table in bytes */
+} object_headers;
+
+
+
+struct lineno_list
+{
+ struct bfd_internal_lineno line;
+ char *frag; /* Frag to which the line number is related */
+ struct lineno_list *next; /* Forward chain pointer */
+};
+
+
+
+
+#define obj_segment_name(i) (segment_info[(int) (i)].scnhdr.s_name)
+
+#define obj_add_segment(s) obj_coff_add_segment (s)
+
+extern segT obj_coff_add_segment PARAMS ((const char *));
+
+extern void obj_coff_section PARAMS ((int));
+
+extern void c_dot_file_symbol PARAMS ((char *filename));
+#define obj_app_file c_dot_file_symbol
+extern void obj_extra_stuff PARAMS ((object_headers * headers));
+
+extern segT s_get_segment PARAMS ((struct symbol * ptr));
+
+extern void c_section_header PARAMS ((struct internal_scnhdr * header,
+ char *name,
+ long core_address,
+ long size,
+ long data_ptr,
+ long reloc_ptr,
+ long lineno_ptr,
+ long reloc_number,
+ long lineno_number,
+ long alignment));
+
+#ifndef tc_coff_symbol_emit_hook
+void tc_coff_symbol_emit_hook PARAMS ((struct symbol *));
+#endif
+
+/* sanity check */
+
+#ifdef TC_I960
+#ifndef C_LEAFSTAT
+hey ! Where is the C_LEAFSTAT definition ? i960 - coff support is depending on it.
+#endif /* no C_LEAFSTAT */
+#endif /* TC_I960 */
+extern struct internal_scnhdr data_section_header;
+extern struct internal_scnhdr text_section_header;
+
+/* Forward the segment of a forwarded symbol. */
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest,src) \
+ (SF_GET_GET_SEGMENT (dest) \
+ ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \
+ : 0)
+
+#ifdef TE_PE
+#define obj_handle_link_once(t) obj_coff_pe_handle_link_once (t)
+extern void obj_coff_pe_handle_link_once ();
+#endif
+
+#endif /* not BFD_ASSEMBLER */
+
+/* In COFF, if a symbol is defined using .def/.val SYM/.endef, it's OK
+ to redefine the symbol later on. This can happen if C symbols use
+ a prefix, and a symbol is defined both with and without the prefix,
+ as in start/_start/__start in gcc/libgcc1-test.c. */
+#define RESOLVE_SYMBOL_REDEFINITION(sym) \
+(SF_GET_GET_SEGMENT (sym) \
+ ? (sym->sy_frag = frag_now, \
+ S_SET_VALUE (sym, frag_now_fix ()), \
+ S_SET_SEGMENT (sym, now_seg), \
+ 0) \
+ : 0)
+
+/* Stabs in a coff file go into their own section. */
+#define SEPARATE_STAB_SECTIONS 1
+
+/* We need 12 bytes at the start of the section to hold some initial
+ information. */
+extern void obj_coff_init_stab_section PARAMS ((segT));
+#define INIT_STAB_SECTION(seg) obj_coff_init_stab_section (seg)
+
+#endif /* OBJ_FORMAT_H */
diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c
new file mode 100644
index 00000000000..ec3ce8811b0
--- /dev/null
+++ b/gas/config/obj-ecoff.c
@@ -0,0 +1,309 @@
+/* ECOFF object file format.
+ Copyright (C) 1993, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ This file was put together by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-ecoff.h"
+#include "as.h"
+#include "coff/internal.h"
+#include "bfd/libcoff.h"
+#include "bfd/libecoff.h"
+
+/* Almost all of the ECOFF support is actually in ecoff.c in the main
+ gas directory. This file mostly just arranges to call that one at
+ the right times. */
+
+static int ecoff_sec_sym_ok_for_reloc PARAMS ((asection *));
+static void obj_ecoff_frob_symbol PARAMS ((symbolS *, int *));
+static void ecoff_pop_insert PARAMS ((void));
+
+/* These are the pseudo-ops we support in this file. Only those
+ relating to debugging information are supported here.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book
+ should be defined here, but are currently unsupported: .aent,
+ .bgnb, .endb, .verstamp, .vreg.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ MIPS CPU specific, and should be defined by tc-mips.c: .alias,
+ .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
+ .rdata, .sdata, .set.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ not MIPS CPU specific, but are also not ECOFF specific. I have
+ only listed the ones which are not already in read.c. It's not
+ completely clear where these should be defined, but tc-mips.c is
+ probably the most reasonable place: .asciiz, .asm0, .endr, .err,
+ .half, .lab, .repeat, .struct, .weakext. */
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ /* COFF style debugging information. .ln is not used; .loc is used
+ instead. */
+ { "def", ecoff_directive_def, 0 },
+ { "dim", ecoff_directive_dim, 0 },
+ { "endef", ecoff_directive_endef, 0 },
+ { "file", ecoff_directive_file, 0 },
+ { "scl", ecoff_directive_scl, 0 },
+ { "size", ecoff_directive_size, 0 },
+ { "esize", ecoff_directive_size, 0 },
+ { "tag", ecoff_directive_tag, 0 },
+ { "type", ecoff_directive_type, 0 },
+ { "etype", ecoff_directive_type, 0 },
+ { "val", ecoff_directive_val, 0 },
+
+ /* ECOFF specific debugging information. */
+ { "begin", ecoff_directive_begin, 0 },
+ { "bend", ecoff_directive_bend, 0 },
+ { "end", ecoff_directive_end, 0 },
+ { "ent", ecoff_directive_ent, 0 },
+ { "fmask", ecoff_directive_fmask, 0 },
+ { "frame", ecoff_directive_frame, 0 },
+ { "loc", ecoff_directive_loc, 0 },
+ { "mask", ecoff_directive_mask, 0 },
+
+ /* Other ECOFF directives. */
+ { "extern", ecoff_directive_extern, 0 },
+
+#ifndef TC_MIPS
+ /* For TC_MIPS, tc-mips.c adds this. */
+ { "weakext", ecoff_directive_weakext, 0 },
+#endif
+
+ /* These are used on Irix. I don't know how to implement them. */
+ { "bgnb", s_ignore, 0 },
+ { "endb", s_ignore, 0 },
+ { "verstamp", s_ignore, 0 },
+
+ /* Sentinel. */
+ { NULL }
+};
+
+/* Swap out the symbols and debugging information for BFD. */
+
+void
+ecoff_frob_file ()
+{
+ const struct ecoff_debug_swap * const debug_swap
+ = &ecoff_backend (stdoutput)->debug_swap;
+ bfd_vma addr;
+ asection *sec;
+ HDRR *hdr;
+ char *buf;
+ char *set;
+
+ /* Set the section VMA values. We force the .sdata and .sbss
+ sections to the end to ensure that their VMA addresses are close
+ together so that the GP register can address both of them. We
+ put the .bss section after the .sbss section.
+
+ Also, for the Alpha, we must sort the sections, to make sure they
+ appear in the output file in the correct order. (Actually, maybe
+ this is a job for BFD. But the VMAs computed would be out of
+ whack if we computed them given our initial, random ordering.
+ It's possible that that wouldn't break things; I could do some
+ experimenting sometime and find out.
+
+ This output ordering of sections is magic, on the Alpha, at
+ least. The .lita section must come before .lit8 and .lit4,
+ otherwise the OSF/1 linker may silently trash the .lit{4,8}
+ section contents. Also, .text must preceed .rdata. These differ
+ from the order described in some parts of the DEC OSF/1 Assembly
+ Language Programmer's Guide, but that order doesn't seem to work
+ with their linker.
+
+ I don't know if section ordering on the MIPS is important. */
+
+ static const char *const names[] = {
+ /* text segment */
+ ".text", ".rdata", ".init", ".fini",
+ /* data segment */
+ ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
+ /* bss segment */
+ ".sbss", ".bss",
+ };
+#define n_names (sizeof (names) / sizeof (names[0]))
+
+ addr = 0;
+ {
+ /* Sections that match names, order to be straightened out later. */
+ asection *secs[n_names];
+ /* Linked list of sections with non-matching names. Random ordering. */
+ asection *other_sections = 0;
+ /* Pointer to next section, since we're destroying the original
+ ordering. */
+ asection *next;
+
+ int i;
+
+ for (i = 0; i < n_names; i++)
+ secs[i] = 0;
+ for (sec = stdoutput->sections; sec != (asection *) NULL; sec = next)
+ {
+ next = sec->next;
+ for (i = 0; i < n_names; i++)
+ if (!strcmp (sec->name, names[i]))
+ {
+ secs[i] = sec;
+ break;
+ }
+ if (i == n_names)
+ {
+ bfd_set_section_vma (stdoutput, sec, addr);
+ addr += bfd_section_size (stdoutput, sec);
+ sec->next = other_sections;
+ other_sections = sec;
+ }
+ }
+ for (i = 0; i < n_names; i++)
+ if (secs[i])
+ {
+ sec = secs[i];
+ bfd_set_section_vma (stdoutput, sec, addr);
+ addr += bfd_section_size (stdoutput, sec);
+ }
+ for (i = n_names - 1; i >= 0; i--)
+ if (secs[i])
+ {
+ sec = secs[i];
+ sec->next = other_sections;
+ other_sections = sec;
+ }
+ stdoutput->sections = other_sections;
+ }
+
+ /* Build the ECOFF debugging information. */
+ assert (ecoff_data (stdoutput) != 0);
+ hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
+ ecoff_build_debug (hdr, &buf, debug_swap);
+
+ /* Finish up the ecoff_tdata structure. */
+ set = buf;
+#define SET(ptr, count, type, size) \
+ if (hdr->count == 0) \
+ ecoff_data (stdoutput)->debug_info.ptr = (type) NULL; \
+ else \
+ { \
+ ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
+ set += hdr->count * size; \
+ }
+
+ SET (line, cbLine, unsigned char *, sizeof (unsigned char));
+ SET (external_dnr, idnMax, PTR, debug_swap->external_dnr_size);
+ SET (external_pdr, ipdMax, PTR, debug_swap->external_pdr_size);
+ SET (external_sym, isymMax, PTR, debug_swap->external_sym_size);
+ SET (external_opt, ioptMax, PTR, debug_swap->external_opt_size);
+ SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
+ SET (ss, issMax, char *, sizeof (char));
+ SET (ssext, issExtMax, char *, sizeof (char));
+ SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size);
+ SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size);
+ SET (external_ext, iextMax, PTR, debug_swap->external_ext_size);
+
+#undef SET
+
+ /* Fill in the register masks. */
+ {
+ unsigned long gprmask = 0;
+ unsigned long fprmask = 0;
+ unsigned long *cprmask = NULL;
+
+#ifdef TC_MIPS
+ /* Fill in the MIPS register masks. It's probably not worth
+ setting up a generic interface for this. */
+ gprmask = mips_gprmask;
+ cprmask = mips_cprmask;
+#endif
+
+#ifdef TC_ALPHA
+ alpha_frob_ecoff_data ();
+
+ if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
+ as_fatal (_("Can't set GP value"));
+
+ gprmask = alpha_gprmask;
+ fprmask = alpha_fprmask;
+#endif
+
+ if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
+ as_fatal (_("Can't set register masks"));
+ }
+}
+
+/* This is called by the ECOFF code to set the external information
+ for a symbol. We just pass it on to BFD, which expects the swapped
+ information to be stored in the native field of the symbol. */
+
+void
+obj_ecoff_set_ext (sym, ext)
+ symbolS *sym;
+ EXTR *ext;
+{
+ const struct ecoff_debug_swap * const debug_swap
+ = &ecoff_backend (stdoutput)->debug_swap;
+ ecoff_symbol_type *esym;
+
+ know (bfd_asymbol_flavour (sym->bsym) == bfd_target_ecoff_flavour);
+ esym = ecoffsymbol (sym->bsym);
+ esym->local = false;
+ esym->native = xmalloc (debug_swap->external_ext_size);
+ (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
+}
+
+static int
+ecoff_sec_sym_ok_for_reloc (sec)
+ asection *sec;
+{
+ return 1;
+}
+
+static void
+obj_ecoff_frob_symbol (sym, puntp)
+ symbolS *sym;
+ int *puntp;
+{
+ ecoff_frob_symbol (sym);
+}
+
+static void
+ecoff_pop_insert ()
+{
+ pop_insert (obj_pseudo_table);
+}
+
+const struct format_ops ecoff_format_ops =
+{
+ bfd_target_ecoff_flavour,
+ 0,
+ 1,
+ obj_ecoff_frob_symbol,
+ ecoff_frob_file,
+ 0,
+ 0, 0,
+ 0, 0,
+ 0,
+ ecoff_generate_asm_lineno,
+ ecoff_stab,
+ ecoff_sec_sym_ok_for_reloc,
+ ecoff_pop_insert,
+ ecoff_set_ext,
+ ecoff_read_begin_hook,
+ ecoff_symbol_new_hook,
+};
diff --git a/gas/config/obj-ecoff.h b/gas/config/obj-ecoff.h
new file mode 100644
index 00000000000..427e619ee13
--- /dev/null
+++ b/gas/config/obj-ecoff.h
@@ -0,0 +1,67 @@
+/* ECOFF object file format header file.
+ Copyright (C) 1993, 94, 95, 96, 97, 1999 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_ECOFF 1
+
+/* Use the generic ECOFF debugging code. */
+#define ECOFF_DEBUGGING 1
+
+#define OUTPUT_FLAVOR bfd_target_ecoff_flavour
+
+#include "targ-cpu.h"
+
+#include "ecoff.h"
+
+/* For each gas symbol we keep track of which file it came from, of
+ whether we have generated an ECOFF symbol for it, and whether the
+ symbols is undefined (this last is needed to distinguish a .extern
+ symbols from a .comm symbol). */
+
+#define TARGET_SYMBOL_FIELDS \
+ struct efdr *ecoff_file; \
+ struct localsym *ecoff_symbol; \
+ valueT ecoff_extern_size;
+
+/* Modify the ECOFF symbol. */
+#define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp)
+
+/* This is used to write the symbolic data in the format that BFD
+ expects it. */
+extern void ecoff_frob_file PARAMS ((void));
+#define obj_frob_file() ecoff_frob_file ()
+
+/* We use the ECOFF functions as our hooks. */
+#define obj_read_begin_hook ecoff_read_begin_hook
+#define obj_symbol_new_hook ecoff_symbol_new_hook
+
+/* Record file switches in the ECOFF symbol table. */
+#define obj_app_file(name) ecoff_new_file (name)
+
+/* At the moment we don't want to do any stabs processing in read.c. */
+#define OBJ_PROCESS_STAB(seg, what, string, type, other, desc) \
+ ecoff_stab ((seg), (what), (string), (type), (other), (desc))
+
+#define EMIT_SECTION_SYMBOLS 0
+#define obj_sec_sym_ok_for_reloc(SEC) 1
+
+#define obj_ecoff_set_ext ecoff_set_ext
+extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *));
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
new file mode 100644
index 00000000000..f50c4b7257a
--- /dev/null
+++ b/gas/config/obj-elf.c
@@ -0,0 +1,1764 @@
+/* ELF object file format
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-elf.h"
+#include "as.h"
+#include "subsegs.h"
+#include "obstack.h"
+
+#ifndef ECOFF_DEBUGGING
+#define ECOFF_DEBUGGING 0
+#else
+#define NEED_ECOFF_DEBUG
+#endif
+
+#ifdef NEED_ECOFF_DEBUG
+#include "ecoff.h"
+#endif
+
+#ifdef TC_ALPHA
+#include "elf/alpha.h"
+#endif
+
+#ifdef TC_MIPS
+#include "elf/mips.h"
+#endif
+
+#ifdef TC_PPC
+#include "elf/ppc.h"
+#endif
+
+static bfd_vma elf_s_get_size PARAMS ((symbolS *));
+static void elf_s_set_size PARAMS ((symbolS *, bfd_vma));
+static bfd_vma elf_s_get_align PARAMS ((symbolS *));
+static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
+static void elf_copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
+static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
+static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
+
+#ifdef NEED_ECOFF_DEBUG
+static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
+static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
+#endif
+
+static void obj_elf_line PARAMS ((int));
+void obj_elf_version PARAMS ((int));
+static void obj_elf_size PARAMS ((int));
+static void obj_elf_type PARAMS ((int));
+static void obj_elf_ident PARAMS ((int));
+static void obj_elf_weak PARAMS ((int));
+static void obj_elf_local PARAMS ((int));
+static void obj_elf_common PARAMS ((int));
+static void obj_elf_symver PARAMS ((int));
+static void obj_elf_vtable_inherit PARAMS ((int));
+static void obj_elf_vtable_entry PARAMS ((int));
+static void obj_elf_data PARAMS ((int));
+static void obj_elf_text PARAMS ((int));
+static void obj_elf_subsection PARAMS ((int));
+
+static const pseudo_typeS elf_pseudo_table[] =
+{
+ {"comm", obj_elf_common, 0},
+ {"ident", obj_elf_ident, 0},
+ {"local", obj_elf_local, 0},
+ {"previous", obj_elf_previous, 0},
+ {"section", obj_elf_section, 0},
+ {"section.s", obj_elf_section, 0},
+ {"sect", obj_elf_section, 0},
+ {"sect.s", obj_elf_section, 0},
+ {"size", obj_elf_size, 0},
+ {"type", obj_elf_type, 0},
+ {"version", obj_elf_version, 0},
+ {"weak", obj_elf_weak, 0},
+
+ /* These are used for stabs-in-elf configurations. */
+ {"line", obj_elf_line, 0},
+
+ /* This is a GNU extension to handle symbol versions. */
+ {"symver", obj_elf_symver, 0},
+
+ /* A GNU extension to change subsection only. */
+ {"subsection", obj_elf_subsection, 0},
+
+ /* These are GNU extensions to aid in garbage collecting C++ vtables. */
+ {"vtable_inherit", obj_elf_vtable_inherit, 0},
+ {"vtable_entry", obj_elf_vtable_entry, 0},
+
+ /* These are used for dwarf. */
+ {"2byte", cons, 2},
+ {"4byte", cons, 4},
+ {"8byte", cons, 8},
+
+ /* We need to trap the section changing calls to handle .previous. */
+ {"data", obj_elf_data, 0},
+ {"text", obj_elf_text, 0},
+
+ /* End sentinel. */
+ {NULL},
+};
+
+static const pseudo_typeS ecoff_debug_pseudo_table[] =
+{
+#ifdef NEED_ECOFF_DEBUG
+ /* COFF style debugging information for ECOFF. .ln is not used; .loc
+ is used instead. */
+ { "def", ecoff_directive_def, 0 },
+ { "dim", ecoff_directive_dim, 0 },
+ { "endef", ecoff_directive_endef, 0 },
+ { "file", ecoff_directive_file, 0 },
+ { "scl", ecoff_directive_scl, 0 },
+ { "tag", ecoff_directive_tag, 0 },
+ { "val", ecoff_directive_val, 0 },
+
+ /* COFF debugging requires pseudo-ops .size and .type, but ELF
+ already has meanings for those. We use .esize and .etype
+ instead. These are only generated by gcc anyhow. */
+ { "esize", ecoff_directive_size, 0 },
+ { "etype", ecoff_directive_type, 0 },
+
+ /* ECOFF specific debugging information. */
+ { "begin", ecoff_directive_begin, 0 },
+ { "bend", ecoff_directive_bend, 0 },
+ { "end", ecoff_directive_end, 0 },
+ { "ent", ecoff_directive_ent, 0 },
+ { "fmask", ecoff_directive_fmask, 0 },
+ { "frame", ecoff_directive_frame, 0 },
+ { "loc", ecoff_directive_loc, 0 },
+ { "mask", ecoff_directive_mask, 0 },
+
+ /* Other ECOFF directives. */
+ { "extern", ecoff_directive_extern, 0 },
+
+ /* These are used on Irix. I don't know how to implement them. */
+ { "alias", s_ignore, 0 },
+ { "bgnb", s_ignore, 0 },
+ { "endb", s_ignore, 0 },
+ { "lab", s_ignore, 0 },
+ { "noalias", s_ignore, 0 },
+ { "verstamp", s_ignore, 0 },
+ { "vreg", s_ignore, 0 },
+#endif
+
+ {NULL} /* end sentinel */
+};
+
+#undef NO_RELOC
+#include "aout/aout64.h"
+
+/* This is called when the assembler starts. */
+
+void
+elf_begin ()
+{
+ /* Add symbols for the known sections to the symbol table. */
+ symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
+ TEXT_SECTION_NAME)));
+ symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
+ DATA_SECTION_NAME)));
+ symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
+ BSS_SECTION_NAME)));
+}
+
+void
+elf_pop_insert ()
+{
+ pop_insert (elf_pseudo_table);
+ if (ECOFF_DEBUGGING)
+ pop_insert (ecoff_debug_pseudo_table);
+}
+
+static bfd_vma
+elf_s_get_size (sym)
+ symbolS *sym;
+{
+ return S_GET_SIZE (sym);
+}
+
+static void
+elf_s_set_size (sym, sz)
+ symbolS *sym;
+ bfd_vma sz;
+{
+ S_SET_SIZE (sym, sz);
+}
+
+static bfd_vma
+elf_s_get_align (sym)
+ symbolS *sym;
+{
+ return S_GET_ALIGN (sym);
+}
+
+static void
+elf_s_set_align (sym, align)
+ symbolS *sym;
+ bfd_vma align;
+{
+ S_SET_ALIGN (sym, align);
+}
+
+static void
+elf_copy_symbol_attributes (dest, src)
+ symbolS *dest, *src;
+{
+ OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
+}
+
+static int
+elf_sec_sym_ok_for_reloc (sec)
+ asection *sec;
+{
+ return obj_sec_sym_ok_for_reloc (sec);
+}
+
+void
+elf_file_symbol (s)
+ char *s;
+{
+ symbolS *sym;
+
+ sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
+ sym->sy_frag = &zero_address_frag;
+ sym->bsym->flags |= BSF_FILE;
+
+ if (symbol_rootP != sym)
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
+#ifdef DEBUG
+ verify_symbol_chain (symbol_rootP, symbol_lastP);
+#endif
+ }
+
+#ifdef NEED_ECOFF_DEBUG
+ ecoff_new_file (s);
+#endif
+}
+
+static void
+obj_elf_common (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+ char *p;
+ int temp, size;
+ symbolS *symbolP;
+ int have_align;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++; /* skip ',' */
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ size = temp;
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (S_GET_VALUE (symbolP) != 0)
+ {
+ if (S_GET_VALUE (symbolP) != size)
+ {
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ }
+ }
+ know (symbolP->sy_frag == &zero_address_frag);
+ if (*input_line_pointer != ',')
+ have_align = 0;
+ else
+ {
+ have_align = 1;
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+ if (! have_align || *input_line_pointer != '"')
+ {
+ if (! have_align)
+ temp = 0;
+ else
+ {
+ temp = get_absolute_expression ();
+ if (temp < 0)
+ {
+ temp = 0;
+ as_warn (_("Common alignment negative; 0 assumed"));
+ }
+ }
+ if (symbolP->local)
+ {
+ segT old_sec;
+ int old_subsec;
+ char *pfrag;
+ int align;
+
+ /* allocate_bss: */
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+ if (temp)
+ {
+ /* convert to a power of 2 alignment */
+ for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
+ if (temp != 1)
+ {
+ as_bad (_("Common alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align = 0;
+ record_alignment (bss_section, align);
+ subseg_set (bss_section, 0);
+ if (align)
+ frag_align (align, 0, 0);
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ symbolP->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *pfrag = 0;
+ S_SET_SIZE (symbolP, size);
+ S_SET_SEGMENT (symbolP, bss_section);
+ S_CLEAR_EXTERNAL (symbolP);
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+ {
+ allocate_common:
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_ALIGN (symbolP, temp);
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ }
+ }
+ else
+ {
+ input_line_pointer++;
+ /* @@ Some use the dot, some don't. Can we get some consistency?? */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+ /* @@ Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4)
+ && strncmp (input_line_pointer, "data\"", 5))
+ {
+ while (*--input_line_pointer != '"')
+ ;
+ input_line_pointer--;
+ goto bad_common_segment;
+ }
+ while (*input_line_pointer++ != '"')
+ ;
+ goto allocate_common;
+ }
+
+ symbolP->bsym->flags |= BSF_OBJECT;
+
+ demand_empty_rest_of_line ();
+ return;
+
+ {
+ bad_common_segment:
+ p = input_line_pointer;
+ while (*p && *p != '\n')
+ p++;
+ c = *p;
+ *p = '\0';
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
+ *p = c;
+ input_line_pointer = p;
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+static void
+obj_elf_local (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_CLEAR_EXTERNAL (symbolP);
+ symbolP->local = 1;
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_weak (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_SET_WEAK (symbolP);
+ symbolP->local = 1;
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+ demand_empty_rest_of_line ();
+}
+
+static segT previous_section;
+static int previous_subsection;
+
+/* Handle the .section pseudo-op. This code supports two different
+ syntaxes.
+
+ The first is found on Solaris, and looks like
+ .section ".sec1",#alloc,#execinstr,#write
+ Here the names after '#' are the SHF_* flags to turn on for the
+ section. I'm not sure how it determines the SHT_* type (BFD
+ doesn't really give us control over the type, anyhow).
+
+ The second format is found on UnixWare, and probably most SVR4
+ machines, and looks like
+ .section .sec1,"a",@progbits
+ The quoted string may contain any combination of a, w, x, and
+ represents the SHF_* flags to turn on for the section. The string
+ beginning with '@' can be progbits or nobits. There should be
+ other possibilities, but I don't know what they are. In any case,
+ BFD doesn't really let us set the section type. */
+
+/* Certain named sections have particular defined types, listed on p.
+ 4-19 of the ABI. */
+struct special_section
+{
+ const char *name;
+ int type;
+ int attributes;
+};
+
+static struct special_section special_sections[] =
+{
+ { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { ".comment", SHT_PROGBITS, 0 },
+ { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { ".debug", SHT_PROGBITS, 0 },
+ { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { ".line", SHT_PROGBITS, 0 },
+ { ".note", SHT_NOTE, 0 },
+ { ".rodata", SHT_PROGBITS, SHF_ALLOC },
+ { ".rodata1", SHT_PROGBITS, SHF_ALLOC },
+ { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+
+#ifdef ELF_TC_SPECIAL_SECTIONS
+ ELF_TC_SPECIAL_SECTIONS
+#endif
+
+#if 0
+ /* The following section names are special, but they can not
+ reasonably appear in assembler code. Some of the attributes are
+ processor dependent. */
+ { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ },
+ { ".dynstr", SHT_STRTAB, SHF_ALLOC },
+ { ".dynsym", SHT_DYNSYM, SHF_ALLOC },
+ { ".got", SHT_PROGBITS, 0 },
+ { ".hash", SHT_HASH, SHF_ALLOC },
+ { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ },
+ { ".plt", SHT_PROGBITS, 0 },
+ { ".shstrtab",SHT_STRTAB, 0 },
+ { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ },
+ { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ },
+#endif
+
+ { NULL, 0, 0 }
+};
+
+void
+obj_elf_section (xxx)
+ int xxx;
+{
+ char *string;
+ int new_sec;
+ segT sec;
+ int type, attr;
+ int i;
+ flagword flags;
+ symbolS *secsym;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (flag_mri)
+ {
+ char mri_type;
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ s_mri_sect (&mri_type);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+
+ return;
+ }
+
+ /* Get name of section. */
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '"')
+ {
+ string = demand_copy_C_string (&xxx);
+ if (string == NULL)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ {
+ char *p = input_line_pointer;
+ char c;
+ while (0 == strchr ("\n\t,; ", *p))
+ p++;
+ if (p == input_line_pointer)
+ {
+ as_warn (_("Missing section name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ c = *p;
+ *p = 0;
+ string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
+ strcpy (string, input_line_pointer);
+ *p = c;
+ input_line_pointer = p;
+ }
+
+ /* Switch to the section, creating it if necessary. */
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
+ sec = subseg_new (string, 0);
+
+ /* If this section already existed, we don't bother to change the
+ flag values. */
+ if (! new_sec)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ ++input_line_pointer;
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+
+ type = SHT_NULL;
+ attr = 0;
+
+ if (*input_line_pointer == ',')
+ {
+ /* Skip the comma. */
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '"')
+ {
+ /* Pick up a string with a combination of a, w, x. */
+ ++input_line_pointer;
+ while (*input_line_pointer != '"')
+ {
+ switch (*input_line_pointer)
+ {
+ case 'a':
+ attr |= SHF_ALLOC;
+ break;
+ case 'w':
+ attr |= SHF_WRITE;
+ break;
+ case 'x':
+ attr |= SHF_EXECINSTR;
+ break;
+ default:
+ {
+ char *bad_msg = _("Bad .section directive: want a,w,x in string");
+#ifdef md_elf_section_letter
+ int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
+ if (md_attr)
+ attr |= md_attr;
+ else
+#endif
+ {
+ as_warn (bad_msg);
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ }
+ ++input_line_pointer;
+ }
+
+ /* Skip the closing quote. */
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '@' || *input_line_pointer == '%')
+ {
+ ++input_line_pointer;
+ if (strncmp (input_line_pointer, "progbits",
+ sizeof "progbits" - 1) == 0)
+ {
+ type = SHT_PROGBITS;
+ input_line_pointer += sizeof "progbits" - 1;
+ }
+ else if (strncmp (input_line_pointer, "nobits",
+ sizeof "nobits" - 1) == 0)
+ {
+ type = SHT_NOBITS;
+ input_line_pointer += sizeof "nobits" - 1;
+ }
+ else
+ {
+#ifdef md_elf_section_type
+ int md_type = md_elf_section_type (&input_line_pointer);
+ if (md_type)
+ type = md_type;
+ else
+#endif
+ {
+ as_warn (_("Unrecognized section type"));
+ ignore_rest_of_line ();
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ do
+ {
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '#')
+ {
+ as_warn (_("Bad .section directive - character following name is not '#'"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+ if (strncmp (input_line_pointer, "write",
+ sizeof "write" - 1) == 0)
+ {
+ attr |= SHF_WRITE;
+ input_line_pointer += sizeof "write" - 1;
+ }
+ else if (strncmp (input_line_pointer, "alloc",
+ sizeof "alloc" - 1) == 0)
+ {
+ attr |= SHF_ALLOC;
+ input_line_pointer += sizeof "alloc" - 1;
+ }
+ else if (strncmp (input_line_pointer, "execinstr",
+ sizeof "execinstr" - 1) == 0)
+ {
+ attr |= SHF_EXECINSTR;
+ input_line_pointer += sizeof "execinstr" - 1;
+ }
+ else
+ {
+#ifdef md_elf_section_word
+ int md_attr = md_elf_section_word (&input_line_pointer);
+ if (md_attr)
+ attr |= md_attr;
+ else
+#endif
+ {
+ as_warn (_("Unrecognized section attribute"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+ --input_line_pointer;
+ }
+ }
+
+ /* See if this is one of the special sections. */
+ for (i = 0; special_sections[i].name != NULL; i++)
+ {
+ if (string[1] == special_sections[i].name[1]
+ && strcmp (string, special_sections[i].name) == 0)
+ {
+ if (type == SHT_NULL)
+ type = special_sections[i].type;
+ else if (type != special_sections[i].type)
+ as_warn (_("Setting incorrect section type for %s"), string);
+
+ if ((attr &~ special_sections[i].attributes) != 0)
+ {
+ /* As a GNU extension, we permit a .note section to be
+ allocatable. If the linker sees an allocateable
+ .note section, it will create a PT_NOTE segment in
+ the output file. */
+ if (strcmp (string, ".note") != 0
+ || attr != SHF_ALLOC)
+ as_warn (_("Setting incorrect section attributes for %s"),
+ string);
+ }
+ attr |= special_sections[i].attributes;
+
+ break;
+ }
+ }
+
+ flags = (SEC_RELOC
+ | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
+ | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
+ | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
+ | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));
+ if (special_sections[i].name == NULL)
+ {
+ if (type == SHT_PROGBITS)
+ flags |= SEC_ALLOC | SEC_LOAD;
+ else if (type == SHT_NOBITS)
+ {
+ flags |= SEC_ALLOC;
+ flags &=~ SEC_LOAD;
+ }
+
+#ifdef md_elf_section_flags
+ flags = md_elf_section_flags (flags, attr, type);
+#endif
+ }
+
+ /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
+ if (type == SHT_NOBITS)
+ seg_info (sec)->bss = 1;
+
+ bfd_set_section_flags (stdoutput, sec, flags);
+
+ /* Add a symbol for this section to the symbol table. */
+ secsym = symbol_find (string);
+ if (secsym != NULL)
+ secsym->bsym = sec->symbol;
+ else
+ symbol_table_insert (section_symbol (sec));
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* Change to the .data section. */
+
+static void
+obj_elf_data (i)
+ int i;
+{
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ s_data (i);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+/* Change to the .text section. */
+
+static void
+obj_elf_text (i)
+ int i;
+{
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ s_text (i);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+static void
+obj_elf_subsection (ignore)
+ int ignore;
+{
+ register int temp;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ temp = get_absolute_expression ();
+ subseg_set (now_seg, (subsegT) temp);
+ demand_empty_rest_of_line ();
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+/* This can be called from the processor backends if they change
+ sections. */
+
+void
+obj_elf_section_change_hook ()
+{
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+}
+
+void
+obj_elf_previous (ignore)
+ int ignore;
+{
+ if (previous_section == 0)
+ {
+ as_bad (_(".previous without corresponding .section; ignored"));
+ return;
+ }
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ subseg_set (previous_section, previous_subsection);
+ previous_section = 0;
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
+static void
+obj_elf_line (ignore)
+ int ignore;
+{
+ /* Assume delimiter is part of expression. BSD4.2 as fails with
+ delightful bug, so we are not being incompatible here. */
+ new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
+ demand_empty_rest_of_line ();
+}
+
+/* This handles the .symver pseudo-op, which is used to specify a
+ symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
+ SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
+ pseudo-op causes the assembler to emit a symbol named SYMVERNAME
+ with the same value as the symbol NAME. */
+
+static void
+obj_elf_symver (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = c;
+
+ if (sym->sy_obj.versioned_name != NULL)
+ {
+ as_bad (_("multiple .symver directives for symbol `%s'"),
+ S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("expected comma after name in .symver"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ name = input_line_pointer;
+ while (1)
+ {
+ c = get_symbol_end ();
+ if (c != ELF_VER_CHR)
+ break;
+ *input_line_pointer++ = c;
+ }
+
+ sym->sy_obj.versioned_name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ if (strchr (sym->sy_obj.versioned_name, ELF_VER_CHR) == NULL)
+ {
+ as_bad (_("missing version name in `%s' for symbol `%s'"),
+ sym->sy_obj.versioned_name, S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* This handles the .vtable_inherit pseudo-op, which is used to indicate
+ to the linker the hierarchy in which a particular table resides. The
+ syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
+
+static void
+obj_elf_vtable_inherit (ignore)
+{
+ char *cname, *pname;
+ symbolS *csym, *psym;
+ char c, bad = 0;
+
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ cname = input_line_pointer;
+ c = get_symbol_end ();
+ csym = symbol_find (cname);
+
+ /* GCFIXME: should check that we don't have two .vtable_inherits for
+ the same child symbol. Also, we can currently only do this if the
+ child symbol is already exists and is placed in a fragment. */
+
+ if (csym == NULL || csym->sy_frag == NULL)
+ {
+ as_bad ("expected `%s' to have already been set for .vtable_inherit",
+ cname);
+ bad = 1;
+ }
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .vtable_inherit");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ if (input_line_pointer[0] == '0'
+ && (input_line_pointer[1] == '\0'
+ || isspace(input_line_pointer[1])))
+ {
+ psym = section_symbol (absolute_section);
+ ++input_line_pointer;
+ }
+ else
+ {
+ pname = input_line_pointer;
+ c = get_symbol_end ();
+ psym = symbol_find_or_make (pname);
+ *input_line_pointer = c;
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (bad)
+ return;
+
+ assert (csym->sy_value.X_op == O_constant);
+ fix_new (csym->sy_frag, csym->sy_value.X_add_number, 0, psym, 0, 0,
+ BFD_RELOC_VTABLE_INHERIT);
+}
+
+/* This handles the .vtable_entry pseudo-op, which is used to indicate
+ to the linker that a vtable slot was used. The syntax is
+ ".vtable_entry tablename, offset". */
+
+static void
+obj_elf_vtable_entry (ignore)
+{
+ char *name;
+ symbolS *sym;
+ offsetT offset;
+ char c;
+
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .vtable_entry");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ if (*input_line_pointer == '#')
+ ++input_line_pointer;
+
+ offset = get_absolute_expression ();
+
+ fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
+ BFD_RELOC_VTABLE_ENTRY);
+
+ demand_empty_rest_of_line ();
+}
+
+void
+obj_read_begin_hook ()
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ ecoff_read_begin_hook ();
+#endif
+}
+
+void
+obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ symbolP->sy_obj.size = NULL;
+ symbolP->sy_obj.versioned_name = NULL;
+
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ ecoff_symbol_new_hook (symbolP);
+#endif
+}
+
+void
+obj_elf_version (ignore)
+ int ignore;
+{
+ char *name;
+ unsigned int c;
+ char ch;
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp = (asection *) NULL;
+ int i, len;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ ++input_line_pointer; /* -> 1st char of string. */
+ name = input_line_pointer;
+
+ while (is_a_char (c = next_char_of_string ()))
+ ;
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ *(input_line_pointer - 1) = '\0';
+ *input_line_pointer = c;
+
+ /* create the .note section */
+
+ note_secp = subseg_new (".note", 0);
+ bfd_set_section_flags (stdoutput,
+ note_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ /* process the version string */
+
+ len = strlen (name);
+
+ i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
+ i_note.descsz = 0; /* no description */
+ i_note.type = NT_VERSION;
+ p = frag_more (sizeof (e_note.namesz));
+ md_number_to_chars (p, (valueT) i_note.namesz, 4);
+ p = frag_more (sizeof (e_note.descsz));
+ md_number_to_chars (p, (valueT) i_note.descsz, 4);
+ p = frag_more (sizeof (e_note.type));
+ md_number_to_chars (p, (valueT) i_note.type, 4);
+
+ for (i = 0; i < len; i++)
+ {
+ ch = *(name + i);
+ {
+ FRAG_APPEND_1_CHAR (ch);
+ }
+ }
+ frag_align (2, 0, 0);
+
+ subseg_set (seg, subseg);
+ }
+ else
+ {
+ as_bad (_("Expected quoted string"));
+ }
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_size (ignore)
+ int ignore;
+{
+ char *name = input_line_pointer;
+ char c = get_symbol_end ();
+ char *p;
+ expressionS exp;
+ symbolS *sym;
+
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("expected comma after name `%s' in .size directive"), name);
+ *p = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ expression (&exp);
+ if (exp.X_op == O_absent)
+ {
+ as_bad (_("missing expression in .size directive"));
+ exp.X_op = O_constant;
+ exp.X_add_number = 0;
+ }
+ *p = 0;
+ sym = symbol_find_or_make (name);
+ *p = c;
+ if (exp.X_op == O_constant)
+ S_SET_SIZE (sym, exp.X_add_number);
+ else
+ {
+ sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS));
+ *sym->sy_obj.size = exp;
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
+ There are four syntaxes:
+
+ The first (used on Solaris) is
+ .type SYM,#function
+ The second (used on UnixWare) is
+ .type SYM,@function
+ The third (reportedly to be used on Irix 6.0) is
+ .type SYM STT_FUNC
+ The fourth (used on NetBSD/Arm and Linux/ARM) is
+ .type SYM,%function
+ */
+
+static void
+obj_elf_type (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+ int type;
+ const char *typename;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if ( *input_line_pointer == '#'
+ || *input_line_pointer == '@'
+ || *input_line_pointer == '%')
+ ++input_line_pointer;
+
+ typename = input_line_pointer;
+ c = get_symbol_end ();
+
+ type = 0;
+ if (strcmp (typename, "function") == 0
+ || strcmp (typename, "STT_FUNC") == 0)
+ type = BSF_FUNCTION;
+ else if (strcmp (typename, "object") == 0
+ || strcmp (typename, "STT_OBJECT") == 0)
+ type = BSF_OBJECT;
+ else
+ as_bad (_("ignoring unrecognized symbol type \"%s\""), typename);
+
+ *input_line_pointer = c;
+
+ sym->bsym->flags |= type;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_ident (ignore)
+ int ignore;
+{
+ static segT comment_section;
+ segT old_section = now_seg;
+ int old_subsection = now_subseg;
+
+ if (!comment_section)
+ {
+ char *p;
+ comment_section = subseg_new (".comment", 0);
+ bfd_set_section_flags (stdoutput, comment_section,
+ SEC_READONLY | SEC_HAS_CONTENTS);
+ p = frag_more (1);
+ *p = 0;
+ }
+ else
+ subseg_set (comment_section, 0);
+ stringer (1);
+ subseg_set (old_section, old_subsection);
+}
+
+#ifdef INIT_STAB_SECTION
+
+/* The first entry in a .stabs section is special. */
+
+void
+obj_elf_init_stab_section (seg)
+ segT seg;
+{
+ char *file;
+ char *p;
+ char *stabstr_name;
+ unsigned int stroff;
+
+ /* Force the section to align to a longword boundary. Without this,
+ UnixWare ar crashes. */
+ bfd_set_section_alignment (stdoutput, seg, 2);
+
+ /* Make space for this first symbol. */
+ p = frag_more (12);
+ /* Zero it out. */
+ memset (p, 0, 12);
+ as_where (&file, (unsigned int *) NULL);
+ stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
+ strcpy (stabstr_name, segment_name (seg));
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+ seg_info (seg)->stabu.p = p;
+}
+
+#endif
+
+/* Fill in the counts in the first entry in a .stabs section. */
+
+static void
+adjust_stab_sections (abfd, sec, xxx)
+ bfd *abfd;
+ asection *sec;
+ PTR xxx;
+{
+ char *name;
+ asection *strsec;
+ char *p;
+ int strsz, nsyms;
+
+ if (strncmp (".stab", sec->name, 5))
+ return;
+ if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
+ return;
+
+ name = (char *) alloca (strlen (sec->name) + 4);
+ strcpy (name, sec->name);
+ strcat (name, "str");
+ strsec = bfd_get_section_by_name (abfd, name);
+ if (strsec)
+ strsz = bfd_section_size (abfd, strsec);
+ else
+ strsz = 0;
+ nsyms = bfd_section_size (abfd, sec) / 12 - 1;
+
+ p = seg_info (sec)->stabu.p;
+ assert (p != 0);
+
+ bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
+ bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
+}
+
+#ifdef NEED_ECOFF_DEBUG
+
+/* This function is called by the ECOFF code. It is supposed to
+ record the external symbol information so that the backend can
+ write it out correctly. The ELF backend doesn't actually handle
+ this at the moment, so we do it ourselves. We save the information
+ in the symbol. */
+
+void
+elf_ecoff_set_ext (sym, ext)
+ symbolS *sym;
+ struct ecoff_extr *ext;
+{
+ sym->bsym->udata.p = (PTR) ext;
+}
+
+/* This function is called by bfd_ecoff_debug_externals. It is
+ supposed to *EXT to the external symbol information, and return
+ whether the symbol should be used at all. */
+
+static boolean
+elf_get_extr (sym, ext)
+ asymbol *sym;
+ EXTR *ext;
+{
+ if (sym->udata.p == NULL)
+ return false;
+ *ext = *(EXTR *) sym->udata.p;
+ return true;
+}
+
+/* This function is called by bfd_ecoff_debug_externals. It has
+ nothing to do for ELF. */
+
+/*ARGSUSED*/
+static void
+elf_set_index (sym, indx)
+ asymbol *sym;
+ bfd_size_type indx;
+{
+}
+
+#endif /* NEED_ECOFF_DEBUG */
+
+void
+elf_frob_symbol (symp, puntp)
+ symbolS *symp;
+ int *puntp;
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ ecoff_frob_symbol (symp);
+#endif
+
+ if (symp->sy_obj.size != NULL)
+ {
+ switch (symp->sy_obj.size->X_op)
+ {
+ case O_subtract:
+ S_SET_SIZE (symp,
+ (S_GET_VALUE (symp->sy_obj.size->X_add_symbol)
+ + symp->sy_obj.size->X_add_number
+ - S_GET_VALUE (symp->sy_obj.size->X_op_symbol)));
+ break;
+ case O_constant:
+ S_SET_SIZE (symp,
+ (S_GET_VALUE (symp->sy_obj.size->X_add_symbol)
+ + symp->sy_obj.size->X_add_number));
+ break;
+ default:
+ as_bad (_(".size expression too complicated to fix up"));
+ break;
+ }
+ free (symp->sy_obj.size);
+ symp->sy_obj.size = NULL;
+ }
+
+ if (symp->sy_obj.versioned_name != NULL)
+ {
+ /* This symbol was given a new name with the .symver directive.
+
+ If this is an external reference, just rename the symbol to
+ include the version string. This will make the relocs be
+ against the correct versioned symbol.
+
+ If this is a definition, add an alias. FIXME: Using an alias
+ will permit the debugging information to refer to the right
+ symbol. However, it's not clear whether it is the best
+ approach. */
+
+ if (! S_IS_DEFINED (symp))
+ {
+ char *p;
+
+ /* Verify that the name isn't using the @@ syntax--this is
+ reserved for definitions of the default version to link
+ against. */
+ p = strchr (symp->sy_obj.versioned_name, ELF_VER_CHR);
+ know (p != NULL);
+ if (p[1] == ELF_VER_CHR)
+ {
+ as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
+ symp->sy_obj.versioned_name);
+ *puntp = true;
+ }
+ S_SET_NAME (symp, symp->sy_obj.versioned_name);
+ }
+ else
+ {
+ symbolS *symp2;
+
+ /* FIXME: Creating a new symbol here is risky. We're in the
+ final loop over the symbol table. We can get away with
+ it only because the symbol goes to the end of the list,
+ where the loop will still see it. It would probably be
+ better to do this in obj_frob_file_before_adjust. */
+
+ symp2 = symbol_find_or_make (symp->sy_obj.versioned_name);
+
+ /* Now we act as though we saw symp2 = sym. */
+
+ S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
+
+ /* Subtracting out the frag address here is a hack because
+ we are in the middle of the final loop. */
+ S_SET_VALUE (symp2, S_GET_VALUE (symp) - symp->sy_frag->fr_address);
+
+ symp2->sy_frag = symp->sy_frag;
+
+ /* This will copy over the size information. */
+ copy_symbol_attributes (symp2, symp);
+
+ if (S_IS_WEAK (symp))
+ S_SET_WEAK (symp2);
+
+ if (S_IS_EXTERNAL (symp))
+ S_SET_EXTERNAL (symp2);
+ }
+ }
+
+ /* Double check weak symbols. */
+ if (symp->bsym->flags & BSF_WEAK)
+ {
+ if (S_IS_COMMON (symp))
+ as_bad (_("Symbol `%s' can not be both weak and common"),
+ S_GET_NAME (symp));
+ }
+
+#ifdef TC_MIPS
+ /* The Irix 5 and 6 assemblers set the type of any common symbol and
+ any undefined non-function symbol to STT_OBJECT. We try to be
+ compatible, since newer Irix 5 and 6 linkers care. However, we
+ only set undefined symbols to be STT_OBJECT if we are on Irix,
+ because that is the only time gcc will generate the necessary
+ .global directives to mark functions. */
+
+ if (S_IS_COMMON (symp))
+ symp->bsym->flags |= BSF_OBJECT;
+
+ if (strstr (TARGET_OS, "irix") != NULL
+ && (! S_IS_DEFINED (symp) && ((symp->bsym->flags & BSF_FUNCTION) == 0)))
+ symp->bsym->flags |= BSF_OBJECT;
+#endif
+
+#ifdef TC_PPC
+ /* Frob the PowerPC, so that the symbol always has object type
+ if it is not some other type. VxWorks needs this. */
+ if ((symp->bsym->flags & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
+ && S_IS_DEFINED (symp))
+ symp->bsym->flags |= BSF_OBJECT;
+#endif
+}
+
+void
+elf_frob_file ()
+{
+ bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
+
+#ifdef elf_tc_final_processing
+ elf_tc_final_processing ();
+#endif
+}
+
+/* It is required that we let write_relocs have the opportunity to
+ optimize away fixups before output has begun, since it is possible
+ to eliminate all fixups for a section and thus we never should
+ have generated the relocation section. */
+
+void
+elf_frob_file_after_relocs ()
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (ECOFF_DEBUGGING)
+ /* Generate the ECOFF debugging information. */
+ {
+ const struct ecoff_debug_swap *debug_swap;
+ struct ecoff_debug_info debug;
+ char *buf;
+ asection *sec;
+
+ debug_swap
+ = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
+ know (debug_swap != (const struct ecoff_debug_swap *) NULL);
+ ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
+
+ /* Set up the pointers in debug. */
+#define SET(ptr, offset, type) \
+ debug.ptr = (type) (buf + debug.symbolic_header.offset)
+
+ SET (line, cbLineOffset, unsigned char *);
+ SET (external_dnr, cbDnOffset, PTR);
+ SET (external_pdr, cbPdOffset, PTR);
+ SET (external_sym, cbSymOffset, PTR);
+ SET (external_opt, cbOptOffset, PTR);
+ SET (external_aux, cbAuxOffset, union aux_ext *);
+ SET (ss, cbSsOffset, char *);
+ SET (external_fdr, cbFdOffset, PTR);
+ SET (external_rfd, cbRfdOffset, PTR);
+ /* ssext and external_ext are set up just below. */
+
+#undef SET
+
+ /* Set up the external symbols. */
+ debug.ssext = debug.ssext_end = NULL;
+ debug.external_ext = debug.external_ext_end = NULL;
+ if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
+ elf_get_extr, elf_set_index))
+ as_fatal (_("Failed to set up debugging information: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ sec = bfd_get_section_by_name (stdoutput, ".mdebug");
+ assert (sec != NULL);
+
+ know (stdoutput->output_has_begun == false);
+
+ /* We set the size of the section, call bfd_set_section_contents
+ to force the ELF backend to allocate a file position, and then
+ write out the data. FIXME: Is this really the best way to do
+ this? */
+ sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
+
+ if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
+ (file_ptr) 0, (bfd_size_type) 0))
+ as_fatal (_("Can't start writing .mdebug section: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ know (stdoutput->output_has_begun == true);
+ know (sec->filepos != 0);
+
+ if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
+ sec->filepos))
+ as_fatal (_("Could not write .mdebug section: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
+#endif /* NEED_ECOFF_DEBUG */
+}
+
+#ifdef SCO_ELF
+
+/* Heavily plagarized from obj_elf_version. The idea is to emit the
+ SCO specific identifier in the .notes section to satisfy the SCO
+ linker.
+
+ This looks more complicated than it really is. As opposed to the
+ "obvious" solution, this should handle the cross dev cases
+ correctly. (i.e, hosting on a 64 bit big endian processor, but
+ generating SCO Elf code) Efficiency isn't a concern, as there
+ should be exactly one of these sections per object module.
+
+ SCO OpenServer 5 identifies it's ELF modules with a standard ELF
+ .note section.
+
+ int_32 namesz = 4 ; Name size
+ int_32 descsz = 12 ; Descriptive information
+ int_32 type = 1 ;
+ char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
+ int_32 version = (major ver # << 16) | version of tools ;
+ int_32 source = (tool_id << 16 ) | 1 ;
+ int_32 info = 0 ; These are set by the SCO tools, but we
+ don't know enough about the source
+ environment to set them. SCO ld currently
+ ignores them, and recommends we set them
+ to zero. */
+
+#define SCO_MAJOR_VERSION 0x1
+#define SCO_MINOR_VERSION 0x1
+
+void
+sco_id ()
+{
+
+ char *name;
+ unsigned int c;
+ char ch;
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp = (asection *) NULL;
+ int i, len;
+
+ /* create the .note section */
+
+ note_secp = subseg_new (".note", 0);
+ bfd_set_section_flags (stdoutput,
+ note_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ /* process the version string */
+
+ i_note.namesz = 4;
+ i_note.descsz = 12; /* 12 descriptive bytes */
+ i_note.type = NT_VERSION; /* Contains a version string */
+
+ p = frag_more (sizeof (i_note.namesz));
+ md_number_to_chars (p, (valueT) i_note.namesz, 4);
+
+ p = frag_more (sizeof (i_note.descsz));
+ md_number_to_chars (p, (valueT) i_note.descsz, 4);
+
+ p = frag_more (sizeof (i_note.type));
+ md_number_to_chars (p, (valueT) i_note.type, 4);
+
+ p = frag_more (4);
+ strcpy (p, "SCO");
+
+ /* Note: this is the version number of the ELF we're representing */
+ p = frag_more (4);
+ md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
+
+ /* Here, we pick a magic number for ourselves (yes, I "registered"
+ it with SCO. The bottom bit shows that we are compat with the
+ SCO ABI. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
+
+ /* If we knew (or cared) what the source language options were, we'd
+ fill them in here. SCO has given us permission to ignore these
+ and just set them to zero. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0x0000, 4);
+
+ frag_align (2, 0, 0);
+
+ /* We probably can't restore the current segment, for there likely
+ isn't one yet... */
+ if (seg && subseg)
+ subseg_set (seg, subseg);
+
+}
+
+#endif /* SCO_ELF */
+
+const struct format_ops elf_format_ops =
+{
+ bfd_target_elf_flavour,
+ 0,
+ 1,
+ elf_frob_symbol,
+ elf_frob_file,
+ elf_frob_file_after_relocs,
+ elf_s_get_size, elf_s_set_size,
+ elf_s_get_align, elf_s_set_align,
+ elf_copy_symbol_attributes,
+#ifdef NEED_ECOFF_DEBUG
+ ecoff_generate_asm_lineno,
+ ecoff_stab,
+#else
+ 0,
+ 0, /* process_stab */
+#endif
+ elf_sec_sym_ok_for_reloc,
+ elf_pop_insert,
+#ifdef NEED_ECOFF_DEBUG
+ elf_ecoff_set_ext,
+#else
+ 0,
+#endif
+ obj_read_begin_hook,
+ obj_symbol_new_hook,
+};
diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h
new file mode 100644
index 00000000000..2f4bc5f977a
--- /dev/null
+++ b/gas/config/obj-elf.h
@@ -0,0 +1,194 @@
+/* ELF object file format.
+ Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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 1, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/* HP PA-RISC support was contributed by the Center for Software Science
+ at the University of Utah. */
+
+#ifndef _OBJ_ELF_H
+#define _OBJ_ELF_H
+
+#define OBJ_ELF 1
+
+#define OUTPUT_FLAVOR bfd_target_elf_flavour
+
+#include <bfd.h>
+
+#define BYTES_IN_WORD 4 /* for now */
+#include "bfd/elf-bfd.h"
+
+/* Additional information we keep for each symbol. */
+
+/* FIXME: For some reason, this structure is needed both here and in
+ obj-multi.h. */
+#ifndef OBJ_SYMFIELD_TYPE
+struct elf_obj_sy
+{
+ /* Use this to keep track of .size expressions that involve
+ differences that we can't compute yet. */
+ expressionS *size;
+
+ /* The name specified by the .symver directive. */
+ char *versioned_name;
+};
+#endif
+
+#define OBJ_SYMFIELD_TYPE struct elf_obj_sy
+
+/* Symbol fields used by the ELF back end. */
+#define ELF_TARGET_SYMBOL_FIELDS int local:1;
+
+/* Don't change this; change ELF_TARGET_SYMBOL_FIELDS instead. */
+#define TARGET_SYMBOL_FIELDS ELF_TARGET_SYMBOL_FIELDS
+
+#include "targ-cpu.h"
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+#define obj_begin() elf_begin ()
+extern void elf_begin PARAMS ((void));
+
+/* should be conditional on address size! */
+#define elf_symbol(asymbol) ((elf_symbol_type *)(&(asymbol)->the_bfd))
+
+#define S_GET_SIZE(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_size)
+#define S_SET_SIZE(S,V) \
+ (elf_symbol((S)->bsym)->internal_elf_sym.st_size = (V))
+
+#define S_GET_ALIGN(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_value)
+#define S_SET_ALIGN(S,V) \
+ (elf_symbol ((S)->bsym)->internal_elf_sym.st_value = (V))
+
+#define S_GET_OTHER(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_other)
+#define S_SET_OTHER(S,V) \
+ (elf_symbol ((S)->bsym)->internal_elf_sym.st_other = (V))
+
+extern asection *gdb_section;
+
+#define obj_frob_file elf_frob_file
+extern void elf_frob_file PARAMS ((void));
+
+#define obj_frob_file_after_relocs elf_frob_file_after_relocs
+extern void elf_frob_file_after_relocs PARAMS ((void));
+
+#define obj_app_file elf_file_symbol
+extern void elf_file_symbol PARAMS ((char *));
+
+extern void obj_elf_section_change_hook PARAMS ((void));
+
+extern void obj_elf_section PARAMS ((int));
+extern void obj_elf_previous PARAMS ((int));
+extern void obj_elf_version PARAMS ((int));
+
+/* BFD wants to write the udata field, which is a no-no for the
+ globally defined sections. */
+#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0)
+
+/* When setting one symbol equal to another, by default we probably
+ want them to have the same "size", whatever it means in the current
+ context. */
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST,SRC) \
+do \
+ { \
+ if ((SRC)->sy_obj.size) \
+ { \
+ if ((DEST)->sy_obj.size == NULL) \
+ (DEST)->sy_obj.size = \
+ (expressionS *) xmalloc (sizeof (expressionS)); \
+ *(DEST)->sy_obj.size = *(SRC)->sy_obj.size; \
+ } \
+ else \
+ { \
+ if ((DEST)->sy_obj.size != NULL) \
+ free ((DEST)->sy_obj.size); \
+ (DEST)->sy_obj.size = NULL; \
+ } \
+ S_SET_SIZE ((DEST), S_GET_SIZE (SRC)); \
+ S_SET_OTHER ((DEST), S_GET_OTHER (SRC)); \
+ } \
+while (0)
+
+/* Stabs go in a separate section. */
+#define SEPARATE_STAB_SECTIONS 1
+
+/* We need 12 bytes at the start of the section to hold some initial
+ information. */
+extern void obj_elf_init_stab_section PARAMS ((segT));
+#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg)
+
+#ifdef TC_ALPHA
+#define ECOFF_DEBUGGING alpha_flag_mdebug
+extern int alpha_flag_mdebug;
+#endif
+
+/* For now, always set ECOFF_DEBUGGING for a MIPS target. */
+#ifdef TC_MIPS
+#ifdef MIPS_STABS_ELF
+#define ECOFF_DEBUGGING 0
+#else
+#define ECOFF_DEBUGGING 1
+#endif /* MIPS_STABS_ELF */
+#endif /* TC_MIPS */
+
+#ifdef ECOFF_DEBUGGING
+/* If we are generating ECOFF debugging information, we need some
+ additional fields for each symbol. */
+#undef TARGET_SYMBOL_FIELDS
+#define TARGET_SYMBOL_FIELDS \
+ ELF_TARGET_SYMBOL_FIELDS \
+ struct efdr *ecoff_file; \
+ struct localsym *ecoff_symbol; \
+ valueT ecoff_extern_size;
+
+/* We smuggle stabs in ECOFF rather than using a separate section.
+ The Irix linker can not handle a separate stabs section. */
+
+#undef SEPARATE_STAB_SECTIONS
+#define SEPARATE_STAB_SECTIONS (!ECOFF_DEBUGGING)
+
+#undef INIT_STAB_SECTION
+#define INIT_STAB_SECTION(seg) \
+ ((void)(ECOFF_DEBUGGING ? 0 : (obj_elf_init_stab_section (seg), 0)))
+
+#define OBJ_PROCESS_STAB(seg, what, string, type, other, desc) \
+ if (ECOFF_DEBUGGING) \
+ ecoff_stab ((seg), (what), (string), (type), (other), (desc))
+#endif /* ECOFF_DEBUGGING */
+
+extern void elf_frob_symbol PARAMS ((struct symbol *, int *));
+#ifndef obj_frob_symbol
+#define obj_frob_symbol(symp, punt) elf_frob_symbol (symp, &punt)
+#endif
+
+extern void elf_pop_insert PARAMS ((void));
+#define obj_pop_insert() elf_pop_insert()
+
+#ifndef OBJ_MAYBE_ELF
+#define obj_ecoff_set_ext elf_ecoff_set_ext
+#ifdef ANSI_PROTOTYPES
+struct ecoff_extr;
+#endif
+extern void elf_ecoff_set_ext PARAMS ((struct symbol *, struct ecoff_extr *));
+#endif
+
+#endif /* _OBJ_ELF_H */
diff --git a/gas/config/obj-evax.c b/gas/config/obj-evax.c
new file mode 100644
index 00000000000..e818c83b904
--- /dev/null
+++ b/gas/config/obj-evax.c
@@ -0,0 +1,83 @@
+/* obj-evax.c - EVAX (openVMS/Alpha) object file format.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Klaus Kämpf (kkaempf@progis.de) of
+ proGIS Software, Aachen, Germany.
+
+ This file is part of GAS, the GNU Assembler
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#define OBJ_HEADER "obj-evax.h"
+
+#include "as.h"
+
+static void s_evax_weak PARAMS ((int));
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ { "weak", s_evax_weak, 0},
+ {0, 0, 0},
+}; /* obj_pseudo_table */
+
+void obj_read_begin_hook () {}
+
+/* Handle the weak specific pseudo-op. */
+
+static void
+s_evax_weak (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_SET_WEAK (symbolP);
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of obj-evax.c */
diff --git a/gas/config/obj-evax.h b/gas/config/obj-evax.h
new file mode 100644
index 00000000000..1d9db19f41b
--- /dev/null
+++ b/gas/config/obj-evax.h
@@ -0,0 +1,95 @@
+/* This file is obj-evax.h
+ Copyright (C) 1996 Free Software Foundation, Inc.
+ Contributed by Klaus Kämpf (kkaempf@progis.de) of
+ proGIS Software, Aachen, Germany.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/*
+ * This file is obj-evax.h and is intended to be a template for
+ * object format specific header files.
+ */
+
+/* define an obj specific macro off which target cpu back ends may key. */
+#define OBJ_EVAX 1
+
+/* include whatever target cpu is appropriate. */
+#include "targ-cpu.h"
+
+#ifdef BFD_ASSEMBLER
+#define OUTPUT_FLAVOR bfd_target_evax_flavour
+#endif
+
+/*
+ * SYMBOLS
+ */
+
+/*
+ * If your object format needs to reorder symbols, define this. When
+ * defined, symbols are kept on a doubly linked list and functions are
+ * made available for push, insert, append, and delete. If not defined,
+ * symbols are kept on a singly linked list, only the append and clear
+ * facilities are available, and they are macros.
+ */
+
+/* #define SYMBOLS_NEED_PACKPOINTERS */
+
+/* */
+typedef struct
+ {
+ void *nothing;
+ }
+obj_symbol_type; /* should be the format's symbol structure */
+
+typedef void *object_headers;
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */
+
+#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */
+
+#define obj_symbol_new_hook(s) {;}
+
+#define S_SET_OTHER(S,V)
+#define S_SET_TYPE(S,T)
+#define S_SET_DESC(S,D)
+#define S_GET_OTHER(S) 0
+#define S_GET_TYPE(S) 0
+#define S_GET_DESC(S) 0
+
+#define PDSC_S_K_KIND_FP_STACK 9
+#define PDSC_S_K_KIND_FP_REGISTER 10
+#define PDSC_S_K_KIND_NULL 8
+
+#define PDSC_S_K_MIN_STACK_SIZE 32
+#define PDSC_S_K_MIN_REGISTER_SIZE 24
+#define PDSC_S_K_NULL_SIZE 16
+
+#define PDSC_S_M_BASE_REG_IS_FP 0x80 /* low byte */
+#define PDSC_S_M_NATIVE 0x10 /* high byte */
+#define PDSC_S_M_NO_JACKET 0x20 /* high byte */
+
+#define LKP_S_K_SIZE 16
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of obj-evax.h */
diff --git a/gas/config/obj-generic.c b/gas/config/obj-generic.c
new file mode 100644
index 00000000000..69fc3d1dbf9
--- /dev/null
+++ b/gas/config/obj-generic.c
@@ -0,0 +1,41 @@
+/* This file is obj-generic.c and is intended to be a template for
+ object format specific source files.
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* These chars start a comment anywhere in a source file (except inside
+ another comment */
+const char comment_chars[] = "#";
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of obj-generic.c */
diff --git a/gas/config/obj-generic.h b/gas/config/obj-generic.h
new file mode 100644
index 00000000000..dc18e439703
--- /dev/null
+++ b/gas/config/obj-generic.h
@@ -0,0 +1,80 @@
+/* This file is obj-generic.h
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * This file is obj-generic.h and is intended to be a template for
+ * object format specific header files.
+ */
+
+/* define an obj specific macro off which target cpu back ends may key. */
+#define OBJ_GENERIC 1
+
+/* include whatever target cpu is appropriate. */
+#include "targ-cpu.h"
+
+/*
+ * SYMBOLS
+ */
+
+/*
+ * If your object format needs to reorder symbols, define this. When
+ * defined, symbols are kept on a doubly linked list and functions are
+ * made available for push, insert, append, and delete. If not defined,
+ * symbols are kept on a singly linked list, only the append and clear
+ * facilities are available, and they are macros.
+ */
+
+/* #define SYMBOLS_NEED_PACKPOINTERS */
+
+/* */
+typedef struct
+ {
+ void *nothing;
+ }
+
+obj_symbol_type; /* should be the format's symbol structure */
+
+typedef void *object_headers;
+
+/* symbols have names */
+#define S_GET_NAME(s) ("foo") /* get the name of a symbolP */
+#define S_SET_NAME(s,v) ;
+/* symbols have segments */
+#define S_GET_SEGMENT(s) (SEG_UNKNOWN)
+#define S_SET_SEGMENT(s,v) ;
+/* symbols may be external */
+#define S_IS_EXTERNAL(s) (0)
+#define S_SET_EXTERNAL(s) ;
+
+/* symbols may or may not be defined */
+#define S_IS_DEFINED(s) (0)
+
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */
+
+#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of obj-generic.h */
diff --git a/gas/config/obj-hp300.c b/gas/config/obj-hp300.c
new file mode 100644
index 00000000000..6e9cc53927a
--- /dev/null
+++ b/gas/config/obj-hp300.c
@@ -0,0 +1,52 @@
+/* This file is obj-hp300.h
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config/obj-aout.c"
+
+/* Aout file generation & utilities */
+void
+hp300_header_append (where, headers)
+ char **where;
+ object_headers *headers;
+{
+ tc_headers_hook (headers);
+
+#define DO(FIELD) \
+ { \
+ md_number_to_chars (*where, headers->header.FIELD, sizeof (headers->header.FIELD)); \
+ *where += sizeof (headers->header.FIELD); \
+ }
+
+ DO (a_info);
+ DO (a_spare1);
+ DO (a_spare2);
+ DO (a_text);
+ DO (a_data);
+ DO (a_bss);
+ DO (a_trsize);
+ DO (a_drsize);
+ DO (a_spare3);
+ DO (a_spare4);
+ DO (a_spare5);
+ DO (a_entry);
+ DO (a_spare6);
+ DO (a_spare7);
+ DO (a_syms);
+ DO (a_spare8);
+}
diff --git a/gas/config/obj-hp300.h b/gas/config/obj-hp300.h
new file mode 100644
index 00000000000..ff4006b6040
--- /dev/null
+++ b/gas/config/obj-hp300.h
@@ -0,0 +1,71 @@
+/* This file is obj-hp300.h
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define __STRUCT_EXEC_OVERRIDE__
+
+struct exec_bytes
+{
+ unsigned char a_info[4]; /* a_machtype/a_magic */
+ unsigned char a_spare1[4];
+ unsigned char a_spare2[4];
+ unsigned char a_text[4]; /* length of text, in bytes */
+ unsigned char a_data[4]; /* length of data, in bytes */
+ unsigned char a_bss[4]; /* length of uninitialized data area for file, in bytes */
+ unsigned char a_trsize[4]; /* length of relocation info for text, in bytes */
+ unsigned char a_drsize[4]; /* length of relocation info for data, in bytes */
+ unsigned char a_spare3[4]; /* HP = pascal interface size */
+ unsigned char a_spare4[4]; /* HP = symbol table size */
+ unsigned char a_spare5[4]; /* HP = debug name table size */
+ unsigned char a_entry[4]; /* start address */
+ unsigned char a_spare6[4]; /* HP = source line table size */
+ unsigned char a_spare7[4]; /* HP = value table size */
+ unsigned char a_syms[4]; /* length of symbol table data in file, in bytes */
+ unsigned char a_spare8[4];
+};
+
+/* How big the "struct exec" is on disk */
+#define EXEC_BYTES_SIZE (16 * 4)
+
+struct exec
+{
+ unsigned long a_info;
+ unsigned long a_spare1;
+ unsigned long a_spare2;
+ unsigned long a_text;
+ unsigned long a_data;
+ unsigned long a_bss;
+ unsigned long a_trsize;
+ unsigned long a_drsize;
+ unsigned long a_spare3;
+ unsigned long a_spare4;
+ unsigned long a_spare5;
+ unsigned long a_entry;
+ unsigned long a_spare6;
+ unsigned long a_spare7;
+ unsigned long a_syms;
+ unsigned long a_spare8;
+};
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (OMAGIC)
+#define AOUT_VERSION 0x02
+#define AOUT_MACHTYPE 0x0c
+#define OMAGIC 0x106
+
+#define obj_header_append hp300_header_append
+#include "config/obj-aout.h"
diff --git a/gas/config/obj-ieee.c b/gas/config/obj-ieee.c
new file mode 100644
index 00000000000..30a0798e295
--- /dev/null
+++ b/gas/config/obj-ieee.c
@@ -0,0 +1,627 @@
+/* obj-format for ieee-695 records.
+ Copyright (C) 1991, 92, 93, 94, 95, 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/*
+ created by
+
+ steve chamberlain steve@cygnus.com
+ */
+
+/*
+ this will hopefully become the port through which bfd and gas talk,
+ for the moment, only ieee is known to work well.
+ */
+
+#include "bfd.h"
+#include "as.h"
+#include "subsegs.h"
+#include "output-file.h"
+#include "frags.h"
+
+bfd *abfd;
+
+/* How many addresses does the .align take? */
+static relax_addressT
+relax_align (address, alignment)
+ register relax_addressT address; /* Address now. */
+ register long alignment; /* Alignment (binary). */
+{
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~((~0) << alignment);
+ new_address = (address + mask) & (~mask);
+ return (new_address - address);
+} /* relax_align() */
+
+/* calculate the size of the frag chain and create a bfd section
+ to contain all of it */
+static void
+DEFUN (size_section, (abfd, idx),
+ bfd * abfd AND
+ unsigned int idx)
+{
+ asection *sec;
+ unsigned int size = 0;
+ fragS *frag = segment_info[idx].frag_root;
+ while (frag)
+ {
+ if (frag->fr_address != size)
+ {
+ printf (_("Out of step\n"));
+ size = frag->fr_address;
+ }
+ size += frag->fr_fix;
+ switch (frag->fr_type)
+ {
+ case rs_fill:
+ case rs_org:
+ size += frag->fr_offset * frag->fr_var;
+ break;
+ case rs_align:
+ case rs_align_code:
+ {
+ addressT off;
+
+ off = relax_align (size, frag->fr_offset);
+ if (frag->fr_subtype != 0 && off > frag->fr_subtype)
+ off = 0;
+ size += off;
+ }
+ }
+ frag = frag->fr_next;
+ }
+ if (size)
+ {
+ char *name = segment_info[idx].name;
+ if (name == (char *) NULL)
+ {
+ name = ".data";
+ }
+ segment_info[idx].user_stuff = (char *) (sec = bfd_make_section (abfd, name));
+ /* Make it output through itself */
+ sec->output_section = sec;
+ sec->flags |= SEC_HAS_CONTENTS;
+ bfd_set_section_size (abfd, sec, size);
+ }
+}
+
+/* run through a frag chain and write out the data to go with it */
+static void
+DEFUN (fill_section, (abfd, idx),
+ bfd * abfd AND
+ unsigned int idx)
+{
+ asection *sec = segment_info[idx].user_stuff;
+ if (sec)
+ {
+ fragS *frag = segment_info[idx].frag_root;
+ unsigned int offset = 0;
+ while (frag)
+ {
+ unsigned int fill_size;
+ unsigned int count;
+ switch (frag->fr_type)
+ {
+ case rs_fill:
+ case rs_align:
+ case rs_org:
+ if (frag->fr_fix)
+ {
+ bfd_set_section_contents (abfd,
+ sec,
+ frag->fr_literal,
+ frag->fr_address,
+ frag->fr_fix);
+ }
+ offset += frag->fr_fix;
+ fill_size = frag->fr_var;
+ if (fill_size)
+ {
+ unsigned int off = frag->fr_fix;
+ for (count = frag->fr_offset; count; count--)
+ {
+ bfd_set_section_contents (abfd, sec,
+ frag->fr_literal +
+ frag->fr_fix,
+ frag->fr_address + off,
+ fill_size);
+ off += fill_size;
+ }
+ }
+ break;
+ default:
+ abort ();
+ }
+ frag = frag->fr_next;
+ }
+ }
+}
+
+/* Count the relocations in a chain */
+
+static unsigned int
+DEFUN (count_entries_in_chain, (idx),
+ unsigned int idx)
+{
+ unsigned int nrelocs;
+ fixS *fixup_ptr;
+
+ /* Count the relocations */
+ fixup_ptr = segment_info[idx].fix_root;
+ nrelocs = 0;
+ while (fixup_ptr != (fixS *) NULL)
+ {
+ fixup_ptr = fixup_ptr->fx_next;
+ nrelocs++;
+ }
+ return nrelocs;
+}
+
+/* output all the relocations for a section */
+void
+DEFUN (do_relocs_for, (idx),
+ unsigned int idx)
+{
+ unsigned int nrelocs;
+ arelent **reloc_ptr_vector;
+ arelent *reloc_vector;
+ asymbol **ptrs;
+ asection *section = (asection *) (segment_info[idx].user_stuff);
+ unsigned int i;
+ fixS *from;
+ if (section)
+ {
+ nrelocs = count_entries_in_chain (idx);
+
+ reloc_ptr_vector = (arelent **) malloc ((nrelocs + 1) * sizeof (arelent *));
+ reloc_vector = (arelent *) malloc (nrelocs * sizeof (arelent));
+ ptrs = (asymbol **) malloc (nrelocs * sizeof (asymbol *));
+ from = segment_info[idx].fix_root;
+ for (i = 0; i < nrelocs; i++)
+ {
+ arelent *to = reloc_vector + i;
+ asymbol *s;
+ reloc_ptr_vector[i] = to;
+ to->howto = (reloc_howto_type *) (from->fx_r_type);
+
+#if 0 /* We can't represent complicated things in a reloc yet */
+ if (from->fx_addsy == 0 || from->fx_subsy != 0) abort();
+#endif
+
+ s = &(from->fx_addsy->sy_symbol.sy);
+ to->address = ((char *) (from->fx_frag->fr_address +
+ from->fx_where))
+ - ((char *) (&(from->fx_frag->fr_literal)));
+ to->addend = from->fx_offset;
+ /* If we know the symbol which we want to relocate to, turn
+ this reloaction into a section relative.
+
+ If this relocation is pcrelative, and we know the
+ destination, we still want to keep the relocation - since
+ the linker might relax some of the bytes, but it stops
+ being pc relative and turns into an absolute relocation. */
+ if (s)
+ {
+ if ((s->flags & BSF_UNDEFINED) == 0)
+ {
+ to->section = s->section;
+
+ /* We can refer directly to the value field here,
+ rather than using S_GET_VALUE, because this is
+ only called after do_symbols, which sets up the
+ value field. */
+ to->addend += s->value;
+
+ to->sym_ptr_ptr = 0;
+ if (to->howto->pcrel_offset)
+ {
+ /* This is a pcrel relocation, the addend should be adjusted */
+ to->addend -= to->address + 1;
+ }
+ }
+ else
+ {
+ to->section = 0;
+ *ptrs = &(from->fx_addsy->sy_symbol.sy);
+ to->sym_ptr_ptr = ptrs;
+
+ if (to->howto->pcrel_offset)
+ {
+ /* This is a pcrel relocation, the addend should be adjusted */
+ to->addend -= to->address - 1;
+ }
+ }
+
+ }
+ else
+ {
+ to->section = 0;
+ }
+
+ ptrs++;
+ from = from->fx_next;
+ }
+
+ /* attatch to the section */
+ section->orelocation = reloc_ptr_vector;
+ section->reloc_count = nrelocs;
+ section->flags |= SEC_LOAD;
+ }
+}
+
+/* do the symbols.. */
+static void
+DEFUN (do_symbols, (abfd),
+ bfd * abfd)
+{
+ extern symbolS *symbol_rootP;
+ symbolS *ptr;
+ asymbol **symbol_ptr_vec;
+ asymbol *symbol_vec;
+ unsigned int count = 0;
+ unsigned int index;
+
+
+ for (ptr = symbol_rootP;
+ ptr != (symbolS *) NULL;
+ ptr = ptr->sy_next)
+ {
+ if (SEG_NORMAL (ptr->sy_symbol.seg))
+ {
+ ptr->sy_symbol.sy.section =
+ (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff);
+ S_SET_VALUE (ptr, S_GET_VALUE (ptr) + ptr->sy_frag->fr_address);
+ if (ptr->sy_symbol.sy.flags == 0)
+ {
+ ptr->sy_symbol.sy.flags = BSF_LOCAL;
+ }
+ }
+ else
+ {
+ switch (ptr->sy_symbol.seg)
+ {
+ case SEG_ABSOLUTE:
+ ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE;
+ ptr->sy_symbol.sy.section = 0;
+ break;
+ case SEG_UNKNOWN:
+ ptr->sy_symbol.sy.flags = BSF_UNDEFINED;
+ ptr->sy_symbol.sy.section = 0;
+ break;
+ default:
+ abort ();
+ }
+ }
+ ptr->sy_symbol.sy.value = S_GET_VALUE (ptr);
+ count++;
+ }
+ symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *));
+
+ index = 0;
+ for (ptr = symbol_rootP;
+ ptr != (symbolS *) NULL;
+ ptr = ptr->sy_next)
+ {
+ symbol_ptr_vec[index] = &(ptr->sy_symbol.sy);
+ index++;
+ }
+ symbol_ptr_vec[index] = 0;
+ abfd->outsymbols = symbol_ptr_vec;
+ abfd->symcount = count;
+}
+
+/* The generic as->bfd converter. Other backends may have special case
+ code */
+
+void
+DEFUN_VOID (bfd_as_write_hook)
+{
+ int i;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ size_section (abfd, i);
+ }
+
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ fill_section (abfd, i);
+
+ do_symbols (abfd);
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ do_relocs_for (i);
+
+}
+
+S_SET_SEGMENT (x, y)
+ symbolS *x;
+ int y;
+{
+ x->sy_symbol.seg = y;
+}
+
+S_IS_DEFINED (x)
+ symbolS *x;
+{
+ if (SEG_NORMAL (x->sy_symbol.seg))
+ {
+ return 1;
+ }
+ switch (x->sy_symbol.seg)
+ {
+ case SEG_UNKNOWN:
+ return 0;
+ default:
+ abort ();
+ }
+}
+
+S_IS_EXTERNAL (x)
+{
+ abort ();
+}
+
+S_GET_DESC (x)
+{
+ abort ();
+}
+
+S_GET_SEGMENT (x)
+ symbolS *x;
+{
+ return x->sy_symbol.seg;
+}
+
+S_SET_EXTERNAL (x)
+ symbolS *x;
+{
+ x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT;
+}
+
+S_SET_NAME (x, y)
+ symbolS *x;
+ char *y;
+{
+ x->sy_symbol.sy.name = y;
+}
+
+S_GET_OTHER (x)
+{
+ abort ();
+}
+
+S_IS_DEBUG (x)
+{
+ abort ();
+}
+
+#ifndef segment_name
+char *
+segment_name ()
+{
+ abort ();
+}
+#endif
+
+void
+obj_read_begin_hook ()
+{
+}
+
+static void
+obj_ieee_section (ignore)
+ int ignore;
+{
+ extern char *input_line_pointer;
+ extern char is_end_of_line[];
+ char *p = input_line_pointer;
+ char *s = p;
+ int i;
+ /* Look up the name, if it doesn't exist, make it */
+ while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p])
+ {
+ p++;
+ }
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ if (segment_info[i].hadone)
+ {
+ if (strncmp (segment_info[i].name, s, p - s) == 0)
+ {
+ goto ok;
+
+ }
+ }
+ else
+ break;
+ }
+ if (i == SEG_UNKNOWN)
+ {
+ as_bad (_("too many sections"));
+ return;
+ }
+
+ segment_info[i].hadone = 1;
+ segment_info[i].name = malloc (p - s + 1);
+ memcpy (segment_info[i].name, s, p - s);
+ segment_info[i].name[p - s] = 0;
+ok:
+ subseg_set (i, 0);
+ while (!is_end_of_line[*p])
+ p++;
+ input_line_pointer = p;
+
+}
+
+
+void cons ();
+void s_ignore ();
+
+
+void s_globl ();
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {"section", obj_ieee_section, 0},
+ {"data.b", cons, 1},
+ {"data.w", cons, 2},
+ {"data.l", cons, 4},
+ {"export", s_globl, 0},
+ {"option", s_ignore, 0},
+ {"end", s_ignore, 0},
+ {"import", s_ignore, 0},
+ {"sdata", stringer, 0},
+ 0,
+
+};
+
+
+
+void
+obj_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ symbolP->sy_symbol.sy.the_bfd = abfd;
+}
+
+
+
+
+
+#if 1
+extern void
+DEFUN_VOID (write_object_file)
+{
+ int i;
+ struct frchain *frchain_ptr;
+ struct frag *frag_ptr;
+
+ abfd = bfd_openw (out_file_name, "ieee");
+
+ if (abfd == 0)
+ {
+ as_perror (_("FATAL: Can't create %s"), out_file_name);
+ exit (EXIT_FAILURE);
+ }
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, bfd_arch_h8300, 0);
+ subseg_set (1, 0);
+ subseg_set (2, 0);
+ subseg_set (3, 0);
+ for (frchain_ptr = frchain_root;
+ frchain_ptr != (struct frchain *) NULL;
+ frchain_ptr = frchain_ptr->frch_next)
+ {
+ /* Run through all the sub-segments and align them up. Also close any
+ open frags. We tack a .fill onto the end of the frag chain so
+ that any .align's size can be worked by looking at the next
+ frag. */
+
+ subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+#ifndef SUB_SEGMENT_ALIGN
+#define SUB_SEGMENT_ALIGN(SEG) 2
+#endif
+ frag_align (SUB_SEGMENT_ALIGN (now_seg), 0, 0);
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+
+ /* Now build one big frag chain for each segment, linked through
+ fr_next. */
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+
+ fragS **prev_frag_ptr_ptr;
+ struct frchain *next_frchain_ptr;
+
+ /* struct frag **head_ptr = segment_info[i].frag_root;*/
+
+ segment_info[i].frag_root = segment_info[i].frchainP->frch_root;
+#if 0
+ /* Im not sure what this is for */
+ for (frchain_ptr = segment_info[i].frchainP->frch_root;
+ frchain_ptr != (struct frchain *) NULL;
+ frchain_ptr = frchain_ptr->frch_next)
+ {
+ *head_ptr = frchain_ptr;
+ head_ptr = &frchain_ptr->next;
+ }
+
+
+#endif
+ }
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ relax_segment (segment_info[i].frag_root, i);
+ }
+
+ /* Now the addresses of the frags are correct within the segment */
+
+ bfd_as_write_hook ();
+ bfd_close (abfd);
+}
+
+#endif
+
+H_SET_TEXT_SIZE (a, b)
+{
+ abort ();
+}
+
+H_GET_TEXT_SIZE ()
+{
+ abort ();
+}
+
+H_SET_BSS_SIZE ()
+{
+ abort ();
+}
+
+H_SET_STRING_SIZE ()
+{
+ abort ();
+}
+
+H_SET_RELOCATION_SIZE ()
+{
+ abort ();
+}
+
+H_SET_MAGIC_NUMBER ()
+{
+ abort ();
+}
+
+H_GET_FILE_SIZE ()
+{
+ abort ();
+}
+
+H_GET_TEXT_RELOCATION_SIZE ()
+{
+ abort ();
+}
+
+/* end of obj-ieee.c */
diff --git a/gas/config/obj-ieee.h b/gas/config/obj-ieee.h
new file mode 100644
index 00000000000..4a0f126ebe4
--- /dev/null
+++ b/gas/config/obj-ieee.h
@@ -0,0 +1,50 @@
+/* This file is obj-ieee.h
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define BFD 1
+
+#include <bfd.h>
+
+typedef struct
+{
+ asymbol sy;
+ int seg;
+}
+
+obj_symbol_type;
+
+#define S_GET_NAME(s) (((s)->sy_symbol.sy.name))
+
+typedef struct
+ {
+ int x;
+ }
+
+object_headers;
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE 1
+
+
+int lineno_rootP;
+
+
+#define IEEE_STYLE
+
+/* end of obj-ieee.h */
diff --git a/gas/config/obj-multi.c b/gas/config/obj-multi.c
new file mode 100644
index 00000000000..d115093aff3
--- /dev/null
+++ b/gas/config/obj-multi.c
@@ -0,0 +1,4 @@
+/* foo */
+
+#include "as.h"
+
diff --git a/gas/config/obj-multi.h b/gas/config/obj-multi.h
new file mode 100644
index 00000000000..fe8d98d0d6e
--- /dev/null
+++ b/gas/config/obj-multi.h
@@ -0,0 +1,50 @@
+/* hi */
+
+#include "emul.h"
+#include "targ-cpu.h"
+
+#define OUTPUT_FLAVOR (this_format->flavor)
+#define obj_frob_symbol(S,P) (this_format->frob_symbol)(S,&(P))
+#define obj_frob_file (this_format->frob_file)
+#define obj_frob_file_after_relocs (this_format->frob_file_after_relocs)
+#define obj_ecoff_set_ext (this_format->ecoff_set_ext)
+#define obj_pop_insert (this_format->pop_insert)
+#define obj_read_begin_hook() (this_format->read_begin_hook?this_format->read_begin_hook():(void)0)
+#define obj_symbol_new_hook (this_format->symbol_new_hook)
+#define obj_sec_sym_ok_for_reloc (this_format->sec_sym_ok_for_reloc)
+#define S_GET_SIZE (this_format->s_get_size)
+#define S_SET_SIZE (this_format->s_set_size)
+#define S_GET_ALIGN (this_format->s_get_align)
+#define S_SET_ALIGN (this_format->s_set_align)
+#define OBJ_COPY_SYMBOL_ATTRIBUTES (this_format->copy_symbol_attributes)
+#define OBJ_PROCESS_STAB (this_format->process_stab)
+
+#if defined (OBJ_MAYBE_ECOFF) || (defined (OBJ_MAYBE_ELF) && defined (TC_MIPS))
+#define ECOFF_DEBUGGING 1
+#endif
+
+/* FIXME: What's the story here? Why do we have to define
+ OBJ_SYMFIELD_TYPE both here and in obj-elf.h? */
+#ifdef OBJ_MAYBE_ELF
+struct elf_obj_sy
+{
+ expressionS *size;
+ char *versioned_name;
+};
+#define OBJ_SYMFIELD_TYPE struct elf_obj_sy
+#define ELF_TARGET_SYMBOL_FIELDS int local:1;
+#else
+#define ELF_TARGET_SYMBOL_FIELDS
+#endif
+
+#ifdef ECOFF_DEBUGGING
+struct efdr;
+struct localsym;
+#define ECOFF_DEBUG_TARGET_SYMBOL_FIELDS struct efdr *ecoff_file; struct localsym *ecoff_symbol; valueT ecoff_extern_size;
+#else
+#define ECOFF_DEBUG_TARGET_SYMBOL_FIELDS
+#endif
+
+#define TARGET_SYMBOL_FIELDS \
+ ELF_TARGET_SYMBOL_FIELDS \
+ ECOFF_DEBUG_TARGET_SYMBOL_FIELDS
diff --git a/gas/config/obj-som.c b/gas/config/obj-som.c
new file mode 100644
index 00000000000..80af18fd37b
--- /dev/null
+++ b/gas/config/obj-som.c
@@ -0,0 +1,307 @@
+/* SOM object file format.
+ Copyright (C) 1993, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support. */
+
+#include "as.h"
+#include "subsegs.h"
+#include "aout/stab_gnu.h"
+#include "obstack.h"
+
+/* SOM does not need any pseudo-ops. */
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {NULL}
+};
+
+static int version_seen = 0;
+static int copyright_seen = 0;
+static int compiler_seen = 0;
+
+/* Unused by SOM. */
+void obj_read_begin_hook () {}
+
+/* Handle a .compiler directive. This is intended to create the
+ compilation unit auxiliary header for MPE such that the linkeditor
+ can handle SOM extraction from archives. The format of the quoted
+ string is "sourcefile language version" and is delimited by blanks.*/
+
+void
+obj_som_compiler (unused)
+ int unused;
+{
+ char *buf;
+ char c;
+ char *filename;
+ char *language_name;
+ char *p;
+ char *version_id;
+
+ if (compiler_seen)
+ {
+ as_bad ("Only one .compiler pseudo-op per file!");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ buf = input_line_pointer;
+ ++input_line_pointer;
+ while (is_a_char (next_char_of_string ()))
+ ;
+ c = *input_line_pointer;
+ *input_line_pointer = '\000';
+ }
+ else
+ {
+ as_bad ("Expected quoted string");
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Parse the quoted string into its component parts. Skip the
+ quote. */
+ filename = buf + 1;
+ p = filename;
+ while (*p != ' ' && *p != '\000')
+ p++;
+ if (*p == '\000')
+ {
+ as_bad (".compiler directive missing language and version");
+ return;
+ }
+ *p = '\000';
+
+ language_name = ++p;
+ while (*p != ' ' && *p != '\000') p++;
+ if (*p == '\000')
+ {
+ as_bad (".compiler directive missing version");
+ return;
+ }
+ *p = '\000';
+
+ version_id = ++p;
+ while (*p != '\000') p++;
+ /* Remove the trailing quote. */
+ *(--p) = '\000';
+
+ compiler_seen = 1;
+ if (! bfd_som_attach_compilation_unit (stdoutput, filename, language_name,
+ "GNU Tools", version_id))
+ {
+ bfd_perror (stdoutput->filename);
+ as_fatal ("FATAL: Attaching compiler header %s", stdoutput->filename);
+ }
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .version directive. */
+
+void
+obj_som_version (unused)
+ int unused;
+{
+ char *version, c;
+
+ if (version_seen)
+ {
+ as_bad (_("Only one .version pseudo-op per file!"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ version = input_line_pointer;
+ ++input_line_pointer;
+ while (is_a_char (next_char_of_string ()))
+ ;
+ c = *input_line_pointer;
+ *input_line_pointer = '\000';
+ }
+ else
+ {
+ as_bad (_("Expected quoted string"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ version_seen = 1;
+ if (bfd_som_attach_aux_hdr (stdoutput, VERSION_AUX_ID, version) == false)
+ {
+ bfd_perror (stdoutput->filename);
+ as_perror (_("FATAL: Attaching version header %s"), stdoutput->filename);
+ exit (EXIT_FAILURE);
+ }
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .copyright directive. This probably isn't complete, but
+ it's of dubious value anyway and (IMHO) not worth the time to finish.
+ If you care about copyright strings that much, you fix it. */
+
+void
+obj_som_copyright (unused)
+ int unused;
+{
+ char *copyright, c;
+
+ if (copyright_seen)
+ {
+ as_bad (_("Only one .copyright pseudo-op per file!"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ copyright = input_line_pointer;
+ ++input_line_pointer;
+ while (is_a_char (next_char_of_string ()))
+ ;
+ c = *input_line_pointer;
+ *input_line_pointer = '\000';
+ }
+ else
+ {
+ as_bad (_("Expected quoted string"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ copyright_seen = 1;
+ if (bfd_som_attach_aux_hdr (stdoutput, COPYRIGHT_AUX_ID, copyright) == false)
+ {
+ bfd_perror (stdoutput->filename);
+ as_perror (_("FATAL: Attaching copyright header %s"), stdoutput->filename);
+ exit (EXIT_FAILURE);
+ }
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+}
+
+/* Perform any initialization necessary for stabs support.
+
+ For SOM we need to create the space which will contain the
+ two stabs subspaces. Additionally we need to set up the
+ space/subspace relationships and set space/subspace attributes
+ which BFD does not understand. */
+
+void
+obj_som_init_stab_section (seg)
+ segT seg;
+{
+ segT saved_seg = now_seg;
+ segT space;
+ subsegT saved_subseg = now_subseg;
+ char *p, *file;
+ unsigned int stroff;
+
+ /* Make the space which will contain the debug subspaces. */
+ space = bfd_make_section_old_way (stdoutput, "$GDB_DEBUG$");
+
+ /* Set SOM specific attributes for the space. In particular we set
+ the space "defined", "private", "sort_key", and "spnum" values.
+
+ Due to a bug in pxdb (called by hpux linker), the sort keys
+ of the various stabs spaces/subspaces need to be "small". We
+ reserve range 72/73 which appear to work well. */
+ obj_set_section_attributes (space, 1, 1, 72, 2);
+ bfd_set_section_alignment (stdoutput, space, 2);
+
+ /* Set the containing space for both stab sections to be $GDB_DEBUG$
+ (just created above). Also set some attributes which BFD does
+ not understand. In particular, access bits, sort keys, and load
+ quadrant. */
+ obj_set_subsection_attributes (seg, space, 0x1f, 73, 0);
+ bfd_set_section_alignment (stdoutput, seg, 2);
+
+ /* Make some space for the first special stab entry and zero the memory.
+ It contains information about the length of this file's
+ stab string and the like. Using it avoids the need to
+ relocate the stab strings.
+
+ The $GDB_STRINGS$ space will be created as a side effect of
+ the call to get_stab_string_offset. */
+ p = frag_more (12);
+ memset (p, 0, 12);
+ as_where (&file, (unsigned int *) NULL);
+ stroff = get_stab_string_offset (file, "$GDB_STRINGS$");
+ know (stroff == 1);
+ md_number_to_chars (p, stroff, 4);
+ seg_info (seg)->stabu.p = p;
+
+ /* Set the containing space for both stab sections to be $GDB_DEBUG$
+ (just created above). Also set some attributes which BFD does
+ not understand. In particular, access bits, sort keys, and load
+ quadrant. */
+ seg = bfd_get_section_by_name (stdoutput, "$GDB_STRINGS$");
+ obj_set_subsection_attributes (seg, space, 0x1f, 72, 0);
+ bfd_set_section_alignment (stdoutput, seg, 2);
+
+ subseg_set (saved_seg, saved_subseg);
+}
+
+/* Fill in the counts in the first entry in a .stabs section. */
+
+static void
+adjust_stab_sections (abfd, sec, xxx)
+ bfd *abfd;
+ asection *sec;
+ PTR xxx;
+{
+ asection *strsec;
+ char *p;
+ int strsz, nsyms;
+
+ if (strcmp ("$GDB_SYMBOLS$", sec->name))
+ return;
+
+ strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
+ if (strsec)
+ strsz = bfd_section_size (abfd, strsec);
+ else
+ strsz = 0;
+ nsyms = bfd_section_size (abfd, sec) / 12 - 1;
+
+ p = seg_info (sec)->stabu.p;
+ assert (p != 0);
+
+ bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
+ bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
+}
+
+/* Called late in the asssembly phase to adjust the special
+ stab entry and to set the starting address for each code subspace. */
+
+void
+som_frob_file ()
+{
+ bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
+}
diff --git a/gas/config/obj-som.h b/gas/config/obj-som.h
new file mode 100644
index 00000000000..62087b125f7
--- /dev/null
+++ b/gas/config/obj-som.h
@@ -0,0 +1,73 @@
+/* SOM object file format.
+ Copyright (C) 1993, 1994, 1995, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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 1, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support. */
+
+#ifndef _OBJ_SOM_H
+#define _OBJ_SOM_H
+
+#define OBJ_SOM 1
+
+#include <bfd.h>
+#include "bfd/som.h"
+#include "targ-cpu.h"
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+/* should be conditional on address size! */
+#define som_symbol(asymbol) ((som_symbol_type *)(&(asymbol)->the_bfd))
+
+extern void som_file_symbol PARAMS ((char *));
+extern void obj_som_version PARAMS ((int));
+extern void obj_som_init_stab_section PARAMS ((segT));
+extern void obj_som_copyright PARAMS ((int));
+extern void obj_som_compiler PARAMS ((int));
+
+#define obj_symbol_new_hook(s) {;}
+
+/* SOM has several attributes for spaces/subspaces which can not
+ be easily expressed in BFD. We use these macros to trigger calls
+ into the SOM BFD backend to set these attributes. */
+#define obj_set_section_attributes bfd_som_set_section_attributes
+#define obj_set_subsection_attributes bfd_som_set_subsection_attributes
+
+/* Likewise for symbol types. */
+#define obj_set_symbol_type bfd_som_set_symbol_type
+
+/* Stabs go in a separate sections. GDB expects to find them in sections
+ with the names $GDB_SYMBOLS$ and $GDB_STRINGS$ rather than .stab and
+ .stabstr. */
+#define SEPARATE_STAB_SECTIONS 1
+#define STAB_SECTION_NAME "$GDB_SYMBOLS$"
+#define STAB_STRING_SECTION_NAME "$GDB_STRINGS$"
+
+/* We use INIT_STAB_SECTION to record the space/subspace relationships
+ for the various debugging sections. */
+#define INIT_STAB_SECTION(seg) obj_som_init_stab_section (seg)
+
+/* We'll be updating the magic 1st stab entry once the entire assembly
+ fail has been processed. */
+#define obj_frob_file() som_frob_file()
+
+#endif /* _OBJ_SOM_H */
diff --git a/gas/config/obj-vms.c b/gas/config/obj-vms.c
new file mode 100644
index 00000000000..0f08f8eb3f3
--- /dev/null
+++ b/gas/config/obj-vms.c
@@ -0,0 +1,5549 @@
+/* vms.c -- Write out a VAX/VMS object file
+ Copyright (C) 1987, 88, 92, 94, 95, 97, 1998 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Written by David L. Kashtan */
+/* Modified by Eric Youngdale to write VMS debug records for program
+ variables */
+
+/* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h). */
+#define WANT_VMS_OBJ_DEFS
+
+#include "as.h"
+#include "config.h"
+#include "subsegs.h"
+#include "obstack.h"
+
+/* What we do if there is a goof. */
+#define error as_fatal
+
+#ifdef VMS /* These are of no use if we are cross assembling. */
+#include <fab.h> /* Define File Access Block */
+#include <nam.h> /* Define NAM Block */
+#include <xab.h> /* Define XAB - all different types*/
+extern int sys$open(), sys$close(), sys$asctim();
+#endif
+
+/*
+ * Version string of the compiler that produced the code we are
+ * assembling. (And this assembler, if we do not have compiler info.)
+ */
+char *compiler_version_string;
+
+extern int flag_hash_long_names; /* -+ */
+extern int flag_one; /* -1; compatibility with gcc 1.x */
+extern int flag_show_after_trunc; /* -H */
+extern int flag_no_hash_mixed_case; /* -h NUM */
+
+/* Flag that determines how we map names. This takes several values, and
+ * is set with the -h switch. A value of zero implies names should be
+ * upper case, and the presence of the -h switch inhibits the case hack.
+ * No -h switch at all sets vms_name_mapping to 0, and allows case hacking.
+ * A value of 2 (set with -h2) implies names should be
+ * all lower case, with no case hack. A value of 3 (set with -h3) implies
+ * that case should be preserved. */
+
+/* If the -+ switch is given, then the hash is appended to any name that is
+ * longer than 31 characters, regardless of the setting of the -h switch.
+ */
+
+char vms_name_mapping = 0;
+
+static symbolS *Entry_Point_Symbol = 0; /* Pointer to "_main" */
+
+/*
+ * We augment the "gas" symbol structure with this
+ */
+struct VMS_Symbol
+{
+ struct VMS_Symbol *Next;
+ symbolS *Symbol;
+ int Size;
+ int Psect_Index;
+ int Psect_Offset;
+};
+
+struct VMS_Symbol *VMS_Symbols = 0;
+struct VMS_Symbol *Ctors_Symbols = 0;
+struct VMS_Symbol *Dtors_Symbols = 0;
+
+/* We need this to keep track of the various input files, so that we can
+ * give the debugger the correct source line.
+ */
+
+struct input_file
+{
+ struct input_file *next;
+ struct input_file *same_file_fpnt;
+ int file_number;
+ int max_line;
+ int min_line;
+ int offset;
+ char flag;
+ char *name;
+ symbolS *spnt;
+};
+
+static struct input_file *file_root = (struct input_file *) NULL;
+
+
+/*
+ * Styles of PSECTS (program sections) that we generate; just shorthand
+ * to avoid lists of section attributes. Used by VMS_Psect_Spec().
+ */
+enum ps_type
+{
+ ps_TEXT, ps_DATA, ps_COMMON, ps_CONST, ps_CTORS, ps_DTORS
+};
+
+/*
+ * This enum is used to keep track of the various types of variables that
+ * may be present.
+ */
+
+enum advanced_type
+{
+ BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN
+};
+
+/*
+ * This structure contains the information from the stabs directives, and the
+ * information is filled in by VMS_typedef_parse. Everything that is needed
+ * to generate the debugging record for a given symbol is present here.
+ * This could be done more efficiently, using nested struct/unions, but for now
+ * I am happy that it works.
+ */
+struct VMS_DBG_Symbol
+{
+ struct VMS_DBG_Symbol *next;
+ /* description of what this is */
+ enum advanced_type advanced;
+ /* this record is for this type */
+ int dbx_type;
+ /* For advanced types this is the type referred to. I.e., the type
+ a pointer points to, or the type of object that makes up an
+ array. */
+ int type2;
+ /* Use this type when generating a variable def */
+ int VMS_type;
+ /* used for arrays - this will be present for all */
+ int index_min;
+ /* entries, but will be meaningless for non-arrays */
+ int index_max;
+ /* Size in bytes of the data type. For an array, this is the size
+ of one element in the array */
+ int data_size;
+ /* Number of the structure/union/enum - used for ref */
+ int struc_numb;
+};
+
+#define SYMTYPLST_SIZE (1<<4) /* 16; must be power of two */
+#define SYMTYP_HASH(x) ((unsigned)(x) & (SYMTYPLST_SIZE-1))
+struct VMS_DBG_Symbol *VMS_Symbol_type_list[SYMTYPLST_SIZE];
+
+/*
+ * We need this structure to keep track of forward references to
+ * struct/union/enum that have not been defined yet. When they are ultimately
+ * defined, then we can go back and generate the TIR commands to make a back
+ * reference.
+ */
+
+struct forward_ref
+{
+ struct forward_ref *next;
+ int dbx_type;
+ int struc_numb;
+ char resolved;
+};
+
+struct forward_ref *f_ref_root = (struct forward_ref *) NULL;
+
+/*
+ * This routine is used to compare the names of certain types to various
+ * fixed types that are known by the debugger.
+ */
+#define type_check(X) !strcmp (symbol_name, X)
+
+/*
+ * This variable is used to keep track of the name of the symbol we are
+ * working on while we are parsing the stabs directives.
+ */
+static const char *symbol_name;
+
+/* We use this counter to assign numbers to all of the structures, unions
+ * and enums that we define. When we actually declare a variable to the
+ * debugger, we can simply do it by number, rather than describing the
+ * whole thing each time.
+ */
+
+static structure_count = 0;
+
+/* This variable is used to indicate that we are making the last attempt to
+ parse the stabs, and that we should define as much as we can, and ignore
+ the rest */
+
+static int final_pass;
+
+/* This variable is used to keep track of the current structure number
+ * for a given variable. If this is < 0, that means that the structure
+ * has not yet been defined to the debugger. This is still cool, since
+ * the VMS object language has ways of fixing things up after the fact,
+ * so we just make a note of this, and generate fixups at the end.
+ */
+static int struct_number;
+
+/* This is used to distinguish between D_float and G_float for telling
+ the debugger about doubles. gcc outputs the same .stabs regardless
+ of whether -mg is used to select alternate doubles. */
+
+static int vax_g_doubles = 0;
+
+/* Local symbol references (used to handle N_ABS symbols; gcc does not
+ generate those, but they're possible with hand-coded assembler input)
+ are always made relative to some particular environment. If the current
+ input has any such symbols, then we expect this to get incremented
+ exactly once and end up having all of them be in environment #0. */
+
+static int Current_Environment = -1;
+
+/* Every object file must specify an module name, which is also used by
+ traceback records. Set in Write_VMS_MHD_Records(). */
+
+static char Module_Name[255+1];
+
+/*
+ * Variable descriptors are used tell the debugger the data types of certain
+ * more complicated variables (basically anything involving a structure,
+ * union, enum, array or pointer). Some non-pointer variables of the
+ * basic types that the debugger knows about do not require a variable
+ * descriptor.
+ *
+ * Since it is impossible to have a variable descriptor longer than 128
+ * bytes by virtue of the way that the VMS object language is set up,
+ * it makes not sense to make the arrays any longer than this, or worrying
+ * about dynamic sizing of the array.
+ *
+ * These are the arrays and counters that we use to build a variable
+ * descriptor.
+ */
+
+#define MAX_DEBUG_RECORD 128
+static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
+static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
+static int Lpnt; /* index into Local */
+static int Apoint; /* index into Asuffix */
+static char overflow; /* flag to indicate we have written too much*/
+static int total_len; /* used to calculate the total length of variable
+ descriptor plus array descriptor - used for len byte*/
+
+/* Flag if we have told user about finding global constants in the text
+ section. */
+static int gave_compiler_message = 0;
+
+
+/*
+ * Global data (Object records limited to 512 bytes by VAX-11 "C" runtime)
+ */
+static int VMS_Object_File_FD; /* File Descriptor for object file */
+static char Object_Record_Buffer[512]; /* Buffer for object file records */
+static int Object_Record_Offset;/* Offset to end of data */
+static int Current_Object_Record_Type; /* Type of record in above */
+
+/*
+ * Macros for moving data around. Must work on big-endian systems.
+ */
+#ifdef VMS /* These are more efficient for VMS->VMS systems */
+#define COPY_LONG(dest,val) ( *(long *)(dest) = (val) )
+#define COPY_SHORT(dest,val) ( *(short *)(dest) = (val) )
+#else
+#define COPY_LONG(dest,val) md_number_to_chars ((dest), (val), 4)
+#define COPY_SHORT(dest,val) md_number_to_chars ((dest), (val), 2)
+#endif
+/*
+ * Macros for placing data into the object record buffer.
+ */
+#define PUT_LONG(val) \
+ ( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \
+ Object_Record_Offset += 4 )
+
+#define PUT_SHORT(val) \
+ ( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \
+ Object_Record_Offset += 2 )
+
+#define PUT_CHAR(val) ( Object_Record_Buffer[Object_Record_Offset++] = (val) )
+
+#define PUT_COUNTED_STRING(cp) do { \
+ register const char *p = (cp); \
+ PUT_CHAR ((char) strlen (p)); \
+ while (*p) PUT_CHAR (*p++); } while (0)
+
+/*
+ * Macro for determining if a Name has psect attributes attached
+ * to it.
+ */
+#define PSECT_ATTRIBUTES_STRING "$$PsectAttributes_"
+#define PSECT_ATTRIBUTES_STRING_LENGTH 18
+
+#define HAS_PSECT_ATTRIBUTES(Name) \
+ (strncmp ((*Name == '_' ? Name + 1 : Name), \
+ PSECT_ATTRIBUTES_STRING, \
+ PSECT_ATTRIBUTES_STRING_LENGTH) == 0)
+
+
+ /* in: segT out: N_TYPE bits */
+const short seg_N_TYPE[] =
+{
+ N_ABS,
+ N_TEXT,
+ N_DATA,
+ N_BSS,
+ N_UNDF, /* unknown */
+ N_UNDF, /* error */
+ N_UNDF, /* expression */
+ N_UNDF, /* debug */
+ N_UNDF, /* ntv */
+ N_UNDF, /* ptv */
+ N_REGISTER, /* register */
+};
+
+const segT N_TYPE_seg[N_TYPE + 2] =
+{ /* N_TYPE == 0x1E = 32-2 */
+ SEG_UNKNOWN, /* N_UNDF == 0 */
+ SEG_GOOF,
+ SEG_ABSOLUTE, /* N_ABS == 2 */
+ SEG_GOOF,
+ SEG_TEXT, /* N_TEXT == 4 */
+ SEG_GOOF,
+ SEG_DATA, /* N_DATA == 6 */
+ SEG_GOOF,
+ SEG_BSS, /* N_BSS == 8 */
+ SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
+ SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
+ SEG_GOOF,
+};
+
+
+/* Local support routines which return a value. */
+
+static struct input_file *find_file PARAMS ((symbolS *));
+static struct VMS_DBG_Symbol *find_symbol PARAMS ((int));
+static symbolS *Define_Routine PARAMS ((symbolS *,int,symbolS *,int));
+
+static char *cvt_integer PARAMS ((char *,int *));
+static char *fix_name PARAMS ((char *));
+static char *get_struct_name PARAMS ((char *));
+
+static offsetT VMS_Initialized_Data_Size PARAMS ((symbolS *,unsigned));
+
+static int VMS_TBT_Source_File PARAMS ((char *,int));
+static int gen1 PARAMS ((struct VMS_DBG_Symbol *,int));
+static int forward_reference PARAMS ((char *));
+static int final_forward_reference PARAMS ((struct VMS_DBG_Symbol *));
+static int VMS_typedef_parse PARAMS ((char *));
+static int hash_string PARAMS ((const char *));
+static int VMS_Psect_Spec PARAMS ((const char *,int,enum ps_type,
+ struct VMS_Symbol *));
+
+/* Local support routines which don't directly return any value. */
+
+static void s_const PARAMS ((int));
+static void Create_VMS_Object_File PARAMS ((void));
+static void Flush_VMS_Object_Record_Buffer PARAMS ((void));
+static void Set_VMS_Object_File_Record PARAMS ((int));
+static void Close_VMS_Object_File PARAMS ((void));
+static void vms_tir_stack_psect PARAMS ((int,int,int));
+static void VMS_Store_Immediate_Data PARAMS ((const char *,int,int));
+static void VMS_Set_Data PARAMS ((int,int,int,int));
+static void VMS_Store_Struct PARAMS ((int));
+static void VMS_Def_Struct PARAMS ((int));
+static void VMS_Set_Struct PARAMS ((int));
+static void VMS_TBT_Module_Begin PARAMS ((void));
+static void VMS_TBT_Module_End PARAMS ((void));
+static void VMS_TBT_Routine_Begin PARAMS ((symbolS *,int));
+static void VMS_TBT_Routine_End PARAMS ((int,symbolS *));
+static void VMS_TBT_Block_Begin PARAMS ((symbolS *,int,char *));
+static void VMS_TBT_Block_End PARAMS ((valueT));
+static void VMS_TBT_Line_PC_Correlation PARAMS ((int,int,int,int));
+static void VMS_TBT_Source_Lines PARAMS ((int,int,int));
+static void fpush PARAMS ((int,int));
+static void rpush PARAMS ((int,int));
+static void array_suffix PARAMS ((struct VMS_DBG_Symbol *));
+static void new_forward_ref PARAMS ((int));
+static void generate_suffix PARAMS ((struct VMS_DBG_Symbol *,int));
+static void bitfield_suffix PARAMS ((struct VMS_DBG_Symbol *,int));
+static void setup_basic_type PARAMS ((struct VMS_DBG_Symbol *));
+static void VMS_DBG_record PARAMS ((struct VMS_DBG_Symbol *,int,int,char *));
+static void VMS_local_stab_Parse PARAMS ((symbolS *));
+static void VMS_stab_parse PARAMS ((symbolS *,int,int,int,int));
+static void VMS_GSYM_Parse PARAMS ((symbolS *,int));
+static void VMS_LCSYM_Parse PARAMS ((symbolS *,int));
+static void VMS_STSYM_Parse PARAMS ((symbolS *,int));
+static void VMS_RSYM_Parse PARAMS ((symbolS *,symbolS *,int));
+static void VMS_LSYM_Parse PARAMS ((void));
+static void Define_Local_Symbols PARAMS ((symbolS *,symbolS *,symbolS *,int));
+static void Write_VMS_MHD_Records PARAMS ((void));
+static void Write_VMS_EOM_Record PARAMS ((int,valueT));
+static void VMS_Case_Hack_Symbol PARAMS ((const char *,char *));
+static void VMS_Modify_Psect_Attributes PARAMS ((const char *,int *));
+static void VMS_Global_Symbol_Spec PARAMS ((const char *,int,int,int));
+static void VMS_Local_Environment_Setup PARAMS ((const char *));
+static void VMS_Emit_Globalvalues PARAMS ((unsigned,unsigned,char *));
+static void VMS_Procedure_Entry_Pt PARAMS ((char *,int,int,int));
+static void VMS_Set_Psect PARAMS ((int,int,int));
+static void VMS_Store_Repeated_Data PARAMS ((int,char *,int,int));
+static void VMS_Store_PIC_Symbol_Reference PARAMS ((symbolS *,int,
+ int,int,int,int));
+static void VMS_Fix_Indirect_Reference PARAMS ((int,int,fragS *,fragS *));
+
+/* Support code which used to be inline within vms_write_object_file. */
+static void vms_fixup_text_section PARAMS ((unsigned,struct frag *,struct frag *));
+static void synthesize_data_segment PARAMS ((unsigned,unsigned,struct frag *));
+static void vms_fixup_data_section PARAMS ((unsigned,unsigned));
+static void global_symbol_directory PARAMS ((unsigned,unsigned));
+static void local_symbols_DST PARAMS ((symbolS *,symbolS *));
+static void vms_build_DST PARAMS ((unsigned));
+static void vms_fixup_xtors_section PARAMS ((struct VMS_Symbol *, int));
+
+
+/* The following code defines the special types of pseudo-ops that we
+ use with VMS. */
+
+unsigned char const_flag = IN_DEFAULT_SECTION;
+
+static void
+s_const (arg)
+ int arg; /* 3rd field from obj_pseudo_table[]; not needed here */
+{
+ /* Since we don't need `arg', use it as our scratch variable so that
+ we won't get any "not used" warnings about it. */
+ arg = get_absolute_expression ();
+ subseg_set (SEG_DATA, (subsegT) arg);
+ const_flag = 1;
+ demand_empty_rest_of_line ();
+}
+
+const pseudo_typeS obj_pseudo_table[] =
+{
+ {"const", s_const, 0},
+ {0, 0, 0},
+}; /* obj_pseudo_table */
+
+
+/* Routine to perform RESOLVE_SYMBOL_REDEFINITION(). */
+
+int
+vms_resolve_symbol_redef (sym)
+ symbolS *sym;
+{
+ /*
+ * If the new symbol is .comm AND it has a size of zero,
+ * we ignore it (i.e. the old symbol overrides it)
+ */
+ if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)
+ && frag_now_fix () == 0)
+ {
+ as_warn (_("compiler emitted zero-size common symbol `%s' already defined"),
+ S_GET_NAME (sym));
+ return 1;
+ }
+ /*
+ * If the old symbol is .comm and it has a size of zero,
+ * we override it with the new symbol value.
+ */
+ if (S_IS_EXTERNAL (sym) && S_IS_DEFINED (sym) && S_GET_VALUE (sym) == 0)
+ {
+ as_warn (_("compiler redefined zero-size common symbol `%s'"),
+ S_GET_NAME (sym));
+ sym->sy_frag = frag_now;
+ S_SET_OTHER (sym, const_flag);
+ S_SET_VALUE (sym, frag_now_fix ());
+ /* Keep N_EXT bit. */
+ sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* `tc_frob_label' handler for colon(symbols.c), used to examine the
+ dummy label(s) gcc inserts at the beginning of each file it generates.
+ gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.7) puts "gcc2_compiled."
+ and "__gnu_language_<name>" and possibly "__vax_<type>_doubles". */
+
+void
+vms_check_for_special_label (symbolP)
+symbolS *symbolP;
+{
+ /* Special labels only occur prior to explicit section directives. */
+ if ((const_flag & IN_DEFAULT_SECTION) != 0)
+ {
+ char *sym_name = S_GET_NAME (symbolP);
+
+ if (*sym_name == '_')
+ ++sym_name;
+
+ if (!strcmp (sym_name, "__vax_g_doubles"))
+ vax_g_doubles = 1;
+#if 0 /* not necessary */
+ else if (!strcmp (sym_name, "__vax_d_doubles"))
+ vax_g_doubles = 0;
+#endif
+#if 0 /* these are potential alternatives to tc-vax.c's md_parse_options() */
+ else if (!strcmp (sym_name, "gcc_compiled."))
+ flag_one = 1;
+ else if (!strcmp (sym_name, "__gnu_language_cplusplus"))
+ flag_hash_long_names = 1;
+#endif
+ }
+ return;
+}
+
+
+void
+obj_read_begin_hook ()
+{
+ return;
+}
+
+
+void
+obj_crawl_symbol_chain (headers)
+ object_headers *headers;
+{
+ symbolS *symbolP;
+ symbolS **symbolPP;
+ int symbol_number = 0;
+
+ symbolPP = &symbol_rootP; /* -> last symbol chain link. */
+ while ((symbolP = *symbolPP) != NULL)
+ {
+ resolve_symbol_value (symbolP, 1);
+
+ /* OK, here is how we decide which symbols go out into the
+ brave new symtab. Symbols that do are:
+
+ * symbols with no name (stabd's?)
+ * symbols with debug info in their N_TYPE
+ * symbols with \1 as their 3rd character (numeric labels)
+ * "local labels" needed for PIC fixups
+
+ Symbols that don't are:
+ * symbols that are registers
+
+ All other symbols are output. We complain if a deleted
+ symbol was marked external. */
+
+ if (!S_IS_REGISTER (symbolP))
+ {
+ symbolP->sy_number = symbol_number++;
+ symbolP->sy_name_offset = 0;
+ symbolPP = &(symbol_next (symbolP));
+ }
+ else
+ {
+ if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
+ {
+ as_bad (_("Local symbol %s never defined"), S_GET_NAME (symbolP));
+ } /* oops. */
+
+ /* Unhook it from the chain. */
+ *symbolPP = symbol_next (symbolP);
+ } /* if this symbol should be in the output */
+
+ } /* for each symbol */
+
+ H_SET_STRING_SIZE (headers, string_byte_count);
+ H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
+} /* obj_crawl_symbol_chain() */
+
+
+ /****** VMS OBJECT FILE HACKING ROUTINES *******/
+
+
+/* Create the VMS object file. */
+
+static void
+Create_VMS_Object_File ()
+{
+#if defined(eunice) || !defined(VMS)
+ VMS_Object_File_FD = creat (out_file_name, 0777, "var");
+#else /* eunice */
+ VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var",
+ "ctx=bin", "mbc=16", "deq=64", "fop=tef",
+ "shr=nil");
+#endif /* eunice */
+ /* Deal with errors. */
+ if (VMS_Object_File_FD < 0)
+ as_fatal (_("Couldn't create VMS object file \"%s\""), out_file_name);
+ /* Initialize object file hacking variables. */
+ Object_Record_Offset = 0;
+ Current_Object_Record_Type = -1;
+}
+
+
+/* Flush the object record buffer to the object file. */
+
+static void
+Flush_VMS_Object_Record_Buffer ()
+{
+ /* If the buffer is empty, there's nothing to do. */
+ if (Object_Record_Offset == 0)
+ return;
+
+#ifndef VMS /* For cross-assembly purposes. */
+ {
+ char RecLen[2];
+
+ /* "Variable-length record" files have a two byte length field
+ prepended to each record. It's normally out-of-band, and native
+ VMS output will insert it automatically for this type of file.
+ When cross-assembling, we must write it explicitly. */
+ md_number_to_chars (RecLen, Object_Record_Offset, 2);
+ if (write (VMS_Object_File_FD, RecLen, 2) != 2)
+ error (_("I/O error writing VMS object file (length prefix)"));
+ /* We also need to force the actual record to be an even number of
+ bytes. For native output, that's automatic; when cross-assembling,
+ pad with a NUL byte if length is odd. Do so _after_ writing the
+ pre-padded length. Since our buffer is defined with even size,
+ an odd offset implies that it has some room left. */
+ if ((Object_Record_Offset & 1) != 0)
+ Object_Record_Buffer[Object_Record_Offset++] = '\0';
+ }
+#endif /* not VMS */
+
+ /* Write the data to the file. */
+ if (write (VMS_Object_File_FD, Object_Record_Buffer, Object_Record_Offset)
+ != Object_Record_Offset)
+ error (_("I/O error writing VMS object file"));
+
+ /* The buffer is now empty. */
+ Object_Record_Offset = 0;
+}
+
+
+/* Declare a particular type of object file record. */
+
+static void
+Set_VMS_Object_File_Record (Type)
+ int Type;
+{
+ /* If the type matches, we are done. */
+ if (Type == Current_Object_Record_Type)
+ return;
+ /* Otherwise: flush the buffer. */
+ Flush_VMS_Object_Record_Buffer ();
+ /* Remember the new type. */
+ Current_Object_Record_Type = Type;
+}
+
+
+/* Close the VMS Object file. */
+
+static void
+Close_VMS_Object_File ()
+{
+ /* Flush (should never be necessary) and reset saved record-type context. */
+ Set_VMS_Object_File_Record (-1);
+
+#ifndef VMS /* For cross-assembly purposes. */
+ {
+ char RecLen[2];
+ int minus_one = -1;
+
+ /* Write a 2 byte record-length field of -1 into the file, which
+ means end-of-block when read, hence end-of-file when occurring
+ in the file's last block. It is only needed for variable-length
+ record files transferred to VMS as fixed-length record files
+ (typical for binary FTP; NFS shouldn't need it, but it won't hurt). */
+ md_number_to_chars (RecLen, minus_one, 2);
+ write (VMS_Object_File_FD, RecLen, 2);
+ }
+#else
+ /* When written on a VMS system, the file header (cf inode) will record
+ the actual end-of-file position and no inline marker is needed. */
+#endif
+
+ close (VMS_Object_File_FD);
+}
+
+
+ /****** Text Information and Relocation routines ******/
+
+
+/* Stack Psect base followed by signed, varying-sized offset.
+ Common to several object records. */
+
+static void
+vms_tir_stack_psect (Psect_Index, Offset, Force)
+ int Psect_Index;
+ int Offset;
+ int Force;
+{
+ int psect_width, offset_width;
+
+ psect_width = ((unsigned) Psect_Index > 255) ? 2 : 1;
+ offset_width = (Force || Offset > 32767 || Offset < -32768) ? 4
+ : (Offset > 127 || Offset < -128) ? 2 : 1;
+#define Sta_P(p,o) (((o)<<1) | ((p)-1))
+ /* byte or word psect; byte, word, or longword offset */
+ switch (Sta_P(psect_width,offset_width))
+ {
+ case Sta_P(1,1): PUT_CHAR (TIR_S_C_STA_PB);
+ PUT_CHAR ((char)(unsigned char) Psect_Index);
+ PUT_CHAR ((char) Offset);
+ break;
+ case Sta_P(1,2): PUT_CHAR (TIR_S_C_STA_PW);
+ PUT_CHAR ((char)(unsigned char) Psect_Index);
+ PUT_SHORT (Offset);
+ break;
+ case Sta_P(1,4): PUT_CHAR (TIR_S_C_STA_PL);
+ PUT_CHAR ((char)(unsigned char) Psect_Index);
+ PUT_LONG (Offset);
+ break;
+ case Sta_P(2,1): PUT_CHAR (TIR_S_C_STA_WPB);
+ PUT_SHORT (Psect_Index);
+ PUT_CHAR ((char) Offset);
+ break;
+ case Sta_P(2,2): PUT_CHAR (TIR_S_C_STA_WPW);
+ PUT_SHORT (Psect_Index);
+ PUT_SHORT (Offset);
+ break;
+ case Sta_P(2,4): PUT_CHAR (TIR_S_C_STA_WPL);
+ PUT_SHORT (Psect_Index);
+ PUT_LONG (Offset);
+ break;
+ }
+#undef Sta_P
+}
+
+
+/* Store immediate data in current Psect. */
+
+static void
+VMS_Store_Immediate_Data (Pointer, Size, Record_Type)
+ const char *Pointer;
+ int Size;
+ int Record_Type;
+{
+ register int i;
+
+ Set_VMS_Object_File_Record (Record_Type);
+ /* We can only store as most 128 bytes at a time due to the way that
+ TIR commands are encoded. */
+ while (Size > 0)
+ {
+ i = (Size > 128) ? 128 : Size;
+ Size -= i;
+ /* If we cannot accommodate this record, flush the buffer. */
+ if ((Object_Record_Offset + i + 1) >= sizeof Object_Record_Buffer)
+ Flush_VMS_Object_Record_Buffer ();
+ /* If the buffer is empty we must insert record type. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (Record_Type);
+ /* Store the count. The Store Immediate TIR command is implied by
+ a negative command byte, and the length of the immediate data
+ is abs(command_byte). So, we write the negated length value. */
+ PUT_CHAR ((char) (-i & 0xff));
+ /* Now store the data. */
+ while (--i >= 0)
+ PUT_CHAR (*Pointer++);
+ }
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/* Make a data reference. */
+
+static void
+VMS_Set_Data (Psect_Index, Offset, Record_Type, Force)
+ int Psect_Index;
+ int Offset;
+ int Record_Type;
+ int Force;
+{
+ Set_VMS_Object_File_Record (Record_Type);
+ /* If the buffer is empty we must insert the record type. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (Record_Type);
+ /* Stack the Psect base with its offset. */
+ vms_tir_stack_psect (Psect_Index, Offset, Force);
+ /* Set relocation base. */
+ PUT_CHAR (TIR_S_C_STO_PIDR);
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/* Make a debugger reference to a struct, union or enum. */
+
+static void
+VMS_Store_Struct (Struct_Index)
+ int Struct_Index;
+{
+ /* We are writing a debug record. */
+ Set_VMS_Object_File_Record (OBJ_S_C_DBG);
+ /* If the buffer is empty we must insert the record type. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_DBG);
+ PUT_CHAR (TIR_S_C_STA_UW);
+ PUT_SHORT (Struct_Index);
+ PUT_CHAR (TIR_S_C_CTL_STKDL);
+ PUT_CHAR (TIR_S_C_STO_L);
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/* Make a debugger reference to partially define a struct, union or enum. */
+
+static void
+VMS_Def_Struct (Struct_Index)
+ int Struct_Index;
+{
+ /* We are writing a debug record. */
+ Set_VMS_Object_File_Record (OBJ_S_C_DBG);
+ /* If the buffer is empty we must insert the record type. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_DBG);
+ PUT_CHAR (TIR_S_C_STA_UW);
+ PUT_SHORT (Struct_Index);
+ PUT_CHAR (TIR_S_C_CTL_DFLOC);
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+static void
+VMS_Set_Struct (Struct_Index)
+ int Struct_Index;
+{ /* see previous functions for comments */
+ Set_VMS_Object_File_Record (OBJ_S_C_DBG);
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_DBG);
+ PUT_CHAR (TIR_S_C_STA_UW);
+ PUT_SHORT (Struct_Index);
+ PUT_CHAR (TIR_S_C_CTL_STLOC);
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+ /****** Traceback Information routines ******/
+
+
+/* Write the Traceback Module Begin record. */
+
+static void
+VMS_TBT_Module_Begin ()
+{
+ register char *cp, *cp1;
+ int Size;
+ char Local[256];
+
+ /* Arrange to store the data locally (leave room for size byte). */
+ cp = &Local[1];
+ /* Begin module. */
+ *cp++ = DST_S_C_MODBEG;
+ *cp++ = 0; /* flags; not used */
+ /*
+ * Language type == "C"
+ *
+ * (FIXME: this should be based on the input...)
+ */
+ COPY_LONG (cp, DST_S_C_C);
+ cp += 4;
+ /* Store the module name. */
+ *cp++ = (char) strlen (Module_Name);
+ cp1 = Module_Name;
+ while (*cp1)
+ *cp++ = *cp1++;
+ /* Now we can store the record size. */
+ Size = (cp - Local);
+ Local[0] = Size - 1;
+ /* Put it into the object record. */
+ VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
+}
+
+
+/* Write the Traceback Module End record. */
+
+static void
+VMS_TBT_Module_End ()
+{
+ char Local[2];
+
+ /* End module. */
+ Local[0] = 1;
+ Local[1] = DST_S_C_MODEND;
+ /* Put it into the object record. */
+ VMS_Store_Immediate_Data (Local, 2, OBJ_S_C_TBT);
+}
+
+
+/* Write a Traceback Routine Begin record. */
+
+static void
+VMS_TBT_Routine_Begin (symbolP, Psect)
+ symbolS *symbolP;
+ int Psect;
+{
+ register char *cp, *cp1;
+ char *Name;
+ int Offset;
+ int Size;
+ char Local[512];
+
+ /* Strip the leading "_" from the name. */
+ Name = S_GET_NAME (symbolP);
+ if (*Name == '_')
+ Name++;
+ /* Get the text psect offset. */
+ Offset = S_GET_VALUE (symbolP);
+ /* Set the record size. */
+ Size = 1 + 1 + 4 + 1 + strlen (Name);
+ Local[0] = Size;
+ /* DST type "routine begin". */
+ Local[1] = DST_S_C_RTNBEG;
+ /* Uses CallS/CallG. */
+ Local[2] = 0;
+ /* Store the data so far. */
+ VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
+ /* Make sure we are still generating a OBJ_S_C_TBT record. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_TBT);
+ /* Stack the address. */
+ vms_tir_stack_psect (Psect, Offset, 0);
+ /* Store the data reference. */
+ PUT_CHAR (TIR_S_C_STO_PIDR);
+ /* Store the counted string as data. */
+ cp = Local;
+ cp1 = Name;
+ Size = strlen (cp1) + 1;
+ *cp++ = Size - 1;
+ while (*cp1)
+ *cp++ = *cp1++;
+ VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_TBT);
+}
+
+
+/* Write a Traceback Routine End record.
+
+ We *must* search the symbol table to find the next routine, since the
+ assember has a way of reassembling the symbol table OUT OF ORDER Thus
+ the next routine in the symbol list is not necessarily the next one in
+ memory. For debugging to work correctly we must know the size of the
+ routine. */
+
+static void
+VMS_TBT_Routine_End (Max_Size, sp)
+ int Max_Size;
+ symbolS *sp;
+{
+ symbolS *symbolP;
+ int Size = 0x7fffffff;
+ char Local[16];
+ valueT sym_value, sp_value = S_GET_VALUE (sp);
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
+ {
+ if (*S_GET_NAME (symbolP) == 'L')
+ continue;
+ sym_value = S_GET_VALUE (symbolP);
+ if (sym_value > sp_value && sym_value < Size)
+ Size = sym_value;
+
+ /*
+ * Dummy labels like "gcc_compiled." should no longer reach here.
+ */
+#if 0
+ else
+ /* check if gcc_compiled. has size of zero */
+ if (sym_value == sp_value &&
+ sp != symbolP &&
+ (!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
+ !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
+ Size = sym_value;
+#endif
+ }
+ }
+ if (Size == 0x7fffffff)
+ Size = Max_Size;
+ Size -= sp_value; /* and get the size of the routine */
+ /* Record Size. */
+ Local[0] = 6;
+ /* DST type is "routine end". */
+ Local[1] = DST_S_C_RTNEND;
+ Local[2] = 0; /* unused */
+ /* Size of routine. */
+ COPY_LONG (&Local[3], Size);
+ /* Store the record. */
+ VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
+}
+
+
+/* Write a Traceback Block Begin record. */
+
+static void
+VMS_TBT_Block_Begin (symbolP, Psect, Name)
+ symbolS *symbolP;
+ int Psect;
+ char *Name;
+{
+ register char *cp, *cp1;
+ int Offset;
+ int Size;
+ char Local[512];
+
+ /* Set the record size. */
+ Size = 1 + 1 + 4 + 1 + strlen (Name);
+ Local[0] = Size;
+ /* DST type is "begin block"; we simulate with a phony routine. */
+ Local[1] = DST_S_C_BLKBEG;
+ /* Uses CallS/CallG. */
+ Local[2] = 0;
+ /* Store the data so far. */
+ VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_DBG);
+ /* Make sure we are still generating a debug record. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_DBG);
+ /* Now get the symbol address. */
+ PUT_CHAR (TIR_S_C_STA_WPL);
+ PUT_SHORT (Psect);
+ /* Get the text psect offset. */
+ Offset = S_GET_VALUE (symbolP);
+ PUT_LONG (Offset);
+ /* Store the data reference. */
+ PUT_CHAR (TIR_S_C_STO_PIDR);
+ /* Store the counted string as data. */
+ cp = Local;
+ cp1 = Name;
+ Size = strlen (cp1) + 1;
+ *cp++ = Size - 1;
+ while (*cp1)
+ *cp++ = *cp1++;
+ VMS_Store_Immediate_Data (Local, Size, OBJ_S_C_DBG);
+}
+
+
+/* Write a Traceback Block End record. */
+
+static void
+VMS_TBT_Block_End (Size)
+ valueT Size;
+{
+ char Local[16];
+
+ Local[0] = 6; /* record length */
+ /* DST type is "block end"; simulate with a phony end routine. */
+ Local[1] = DST_S_C_BLKEND;
+ Local[2] = 0; /* unused, must be zero */
+ COPY_LONG (&Local[3], Size);
+ VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_DBG);
+}
+
+
+/* Write a Line number <-> Program Counter correlation record. */
+
+static void
+VMS_TBT_Line_PC_Correlation (Line_Number, Offset, Psect, Do_Delta)
+ int Line_Number;
+ int Offset;
+ int Psect;
+ int Do_Delta;
+{
+ register char *cp;
+ char Local[64];
+
+ if (Do_Delta == 0)
+ {
+ /*
+ * If not delta, set our PC/Line number correlation.
+ */
+ cp = &Local[1]; /* Put size in Local[0] later. */
+ /* DST type is "Line Number/PC correlation". */
+ *cp++ = DST_S_C_LINE_NUM;
+ /* Set Line number. */
+ if (Line_Number - 1 <= 255)
+ {
+ *cp++ = DST_S_C_SET_LINUM_B;
+ *cp++ = (char) (Line_Number - 1);
+ }
+ else if (Line_Number - 1 <= 65535)
+ {
+ *cp++ = DST_S_C_SET_LINE_NUM;
+ COPY_SHORT (cp, Line_Number - 1), cp += 2;
+ }
+ else
+ {
+ *cp++ = DST_S_C_SET_LINUM_L;
+ COPY_LONG (cp, Line_Number - 1), cp += 4;
+ }
+ /* Set PC. */
+ *cp++ = DST_S_C_SET_ABS_PC;
+ /* Store size now that we know it, then output the data. */
+ Local[0] = cp - &Local[1];
+ /* Account for the space that TIR_S_C_STO_PIDR will use for the PC. */
+ Local[0] += 4; /* size includes length of another longword */
+ VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
+ /* Make sure we are still generating a OBJ_S_C_TBT record. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_TBT);
+ vms_tir_stack_psect (Psect, Offset, 0);
+ PUT_CHAR (TIR_S_C_STO_PIDR);
+ /* Do a PC offset of 0 to register the line number. */
+ Local[0] = 2;
+ Local[1] = DST_S_C_LINE_NUM;
+ Local[2] = 0; /* Increment PC by 0 and register line # */
+ VMS_Store_Immediate_Data (Local, 3, OBJ_S_C_TBT);
+ }
+ else
+ {
+ if (Do_Delta < 0)
+ {
+ /*
+ * When delta is negative, terminate the line numbers.
+ */
+ Local[0] = 1 + 1 + 4;
+ Local[1] = DST_S_C_LINE_NUM;
+ Local[2] = DST_S_C_TERM_L;
+ COPY_LONG (&Local[3], Offset);
+ VMS_Store_Immediate_Data (Local, 7, OBJ_S_C_TBT);
+ return;
+ }
+ /*
+ * Do a PC/Line delta.
+ */
+ cp = &Local[1];
+ *cp++ = DST_S_C_LINE_NUM;
+ if (Line_Number > 1)
+ {
+ /* We need to increment the line number. */
+ if (Line_Number - 1 <= 255)
+ {
+ *cp++ = DST_S_C_INCR_LINUM;
+ *cp++ = Line_Number - 1;
+ }
+ else if (Line_Number - 1 <= 65535)
+ {
+ *cp++ = DST_S_C_INCR_LINUM_W;
+ COPY_SHORT (cp, Line_Number - 1), cp += 2;
+ }
+ else
+ {
+ *cp++ = DST_S_C_INCR_LINUM_L;
+ COPY_LONG (cp, Line_Number - 1), cp += 4;
+ }
+ }
+ /*
+ * Increment the PC
+ */
+ if (Offset <= 128)
+ {
+ /* Small offsets are encoded as negative numbers, rather than the
+ usual non-negative type code followed by another data field. */
+ *cp++ = (char) -Offset;
+ }
+ else if (Offset <= 65535)
+ {
+ *cp++ = DST_S_C_DELTA_PC_W;
+ COPY_SHORT (cp, Offset), cp += 2;
+ }
+ else
+ {
+ *cp++ = DST_S_C_DELTA_PC_L;
+ COPY_LONG (cp, Offset), cp += 4;
+ }
+ /* Set size now that be know it, then output the data. */
+ Local[0] = cp - &Local[1];
+ VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
+ }
+}
+
+
+/* Describe a source file to the debugger. */
+
+static int
+VMS_TBT_Source_File (Filename, ID_Number)
+ char *Filename;
+ int ID_Number;
+{
+ register char *cp;
+ int len, rfo, ffb, ebk;
+ char cdt[8];
+ char Local[512];
+#ifdef VMS /* Used for native assembly */
+ unsigned Status;
+ struct FAB fab; /* RMS file access block */
+ struct NAM nam; /* file name information */
+ struct XABDAT xabdat; /* date+time fields */
+ struct XABFHC xabfhc; /* file header characteristics */
+ char resultant_string_buffer[255 + 1];
+
+ /*
+ * Set up RMS structures:
+ */
+ /* FAB -- file access block */
+ memset ((char *) &fab, 0, sizeof fab);
+ fab.fab$b_bid = FAB$C_BID;
+ fab.fab$b_bln = (unsigned char) sizeof fab;
+ fab.fab$l_fna = Filename;
+ fab.fab$b_fns = (unsigned char) strlen (Filename);
+ fab.fab$l_nam = (char *) &nam;
+ fab.fab$l_xab = (char *) &xabdat;
+ /* NAM -- file name block */
+ memset ((char *) &nam, 0, sizeof nam);
+ nam.nam$b_bid = NAM$C_BID;
+ nam.nam$b_bln = (unsigned char) sizeof nam;
+ nam.nam$l_rsa = resultant_string_buffer;
+ nam.nam$b_rss = (unsigned char) (sizeof resultant_string_buffer - 1);
+ /* XABs -- extended attributes blocks */
+ memset ((char *) &xabdat, 0, sizeof xabdat);
+ xabdat.xab$b_cod = XAB$C_DAT;
+ xabdat.xab$b_bln = (unsigned char) sizeof xabdat;
+ xabdat.xab$l_nxt = (char *) &xabfhc;
+ memset ((char *) &xabfhc, 0, sizeof xabfhc);
+ xabfhc.xab$b_cod = XAB$C_FHC;
+ xabfhc.xab$b_bln = (unsigned char) sizeof xabfhc;
+ xabfhc.xab$l_nxt = 0;
+ /*
+ * Get the file information
+ */
+ Status = sys$open (&fab);
+ if (!(Status & 1))
+ {
+ as_tsktsk (_("Couldn't find source file \"%s\", status=%%X%x"),
+ Filename, Status);
+ return 0;
+ }
+ sys$close (&fab);
+ /* Now extract fields of interest. */
+ memcpy (cdt, (char *) &xabdat.xab$q_cdt, 8); /* creation date */
+ ebk = xabfhc.xab$l_ebk; /* end-of-file block */
+ ffb = xabfhc.xab$w_ffb; /* first free byte of last block */
+ rfo = xabfhc.xab$b_rfo; /* record format */
+ len = nam.nam$b_rsl; /* length of Filename */
+ resultant_string_buffer[len] = '\0';
+ Filename = resultant_string_buffer; /* full filename */
+#else /* Cross-assembly */
+ /* [Perhaps we ought to use actual values derived from stat() here?] */
+ memset (cdt, 0, 8); /* null VMS quadword binary time */
+ ebk = ffb = rfo = 0;
+ len = strlen (Filename);
+ if (len > 255) /* a single byte is used as count prefix */
+ {
+ Filename += (len - 255); /* tail end is more significant */
+ len = 255;
+ }
+#endif /* VMS */
+
+ cp = &Local[1]; /* fill in record length later */
+ *cp++ = DST_S_C_SOURCE; /* DST type is "source file" */
+ *cp++ = DST_S_C_SRC_FORMFEED; /* formfeeds count as source records */
+ *cp++ = DST_S_C_SRC_DECLFILE; /* declare source file */
+ know (cp == &Local[4]);
+ *cp++ = 0; /* fill in this length below */
+ *cp++ = 0; /* flags; must be zero */
+ COPY_SHORT (cp, ID_Number), cp += 2; /* file ID number */
+ memcpy (cp, cdt, 8), cp += 8; /* creation date+time */
+ COPY_LONG (cp, ebk), cp += 4; /* end-of-file block */
+ COPY_SHORT (cp, ffb), cp += 2; /* first free byte of last block */
+ *cp++ = (char) rfo; /* RMS record format */
+ /* Filename. */
+ *cp++ = (char) len;
+ while (--len >= 0)
+ *cp++ = *Filename++;
+ /* Library module name (none). */
+ *cp++ = 0;
+ /* Now that size is known, fill it in and write out the record. */
+ Local[4] = cp - &Local[5]; /* source file declaration size */
+ Local[0] = cp - &Local[1]; /* TBT record size */
+ VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
+ return 1;
+}
+
+
+/* Traceback information is described in terms of lines from compiler
+ listing files, not lines from source files. We need to set up the
+ correlation between listing line numbers and source line numbers.
+ Since gcc's .stabn directives refer to the source lines, we just
+ need to describe a one-to-one correspondence. */
+
+static void
+VMS_TBT_Source_Lines (ID_Number, Starting_Line_Number, Number_Of_Lines)
+ int ID_Number;
+ int Starting_Line_Number;
+ int Number_Of_Lines;
+{
+ char *cp;
+ int chunk_limit;
+ char Local[128]; /* room enough to describe 1310700 lines... */
+
+ cp = &Local[1]; /* Put size in Local[0] later. */
+ *cp++ = DST_S_C_SOURCE; /* DST type is "source file". */
+ *cp++ = DST_S_C_SRC_SETFILE; /* Set Source File. */
+ COPY_SHORT (cp, ID_Number), cp += 2; /* File ID Number. */
+ /* Set record number and define lines. Since no longword form of
+ SRC_DEFLINES is available, we need to be able to cope with any huge
+ files a chunk at a time. It doesn't matter for tracebacks, since
+ unspecified lines are mapped one-to-one and work out right, but it
+ does matter within the debugger. Without this explicit mapping,
+ it will complain about lines not existing in the module. */
+ chunk_limit = (sizeof Local - 5) / 6;
+ if (Number_Of_Lines > 65535 * chunk_limit) /* avoid buffer overflow */
+ Number_Of_Lines = 65535 * chunk_limit;
+ while (Number_Of_Lines > 65535)
+ {
+ *cp++ = DST_S_C_SRC_SETREC_L;
+ COPY_LONG (cp, Starting_Line_Number), cp += 4;
+ *cp++ = DST_S_C_SRC_DEFLINES_W;
+ COPY_SHORT (cp, 65535), cp += 2;
+ Starting_Line_Number += 65535;
+ Number_Of_Lines -= 65535;
+ }
+ /* Set record number and define lines, normal case. */
+ if (Starting_Line_Number <= 65535)
+ {
+ *cp++ = DST_S_C_SRC_SETREC_W;
+ COPY_SHORT (cp, Starting_Line_Number), cp += 2;
+ }
+ else
+ {
+ *cp++ = DST_S_C_SRC_SETREC_L;
+ COPY_LONG (cp, Starting_Line_Number), cp += 4;
+ }
+ *cp++ = DST_S_C_SRC_DEFLINES_W;
+ COPY_SHORT (cp, Number_Of_Lines), cp += 2;
+ /* Set size now that be know it, then output the data. */
+ Local[0] = cp - &Local[1];
+ VMS_Store_Immediate_Data (Local, cp - Local, OBJ_S_C_TBT);
+}
+
+
+ /****** Debugger Information support routines ******/
+
+
+/* This routine locates a file in the list of files. If an entry does
+ not exist, one is created. For include files, a new entry is always
+ created such that inline functions can be properly debugged. */
+
+static struct input_file *
+find_file (sp)
+ symbolS *sp;
+{
+ struct input_file *same_file = 0;
+ struct input_file *fpnt, *last = 0;
+ char *sp_name;
+
+ for (fpnt = file_root; fpnt; fpnt = fpnt->next)
+ {
+ if (fpnt->spnt == sp)
+ return fpnt;
+ last = fpnt;
+ }
+ sp_name = S_GET_NAME (sp);
+ for (fpnt = file_root; fpnt; fpnt = fpnt->next)
+ {
+ if (strcmp (sp_name, fpnt->name) == 0)
+ {
+ if (fpnt->flag == 1)
+ return fpnt;
+ same_file = fpnt;
+ break;
+ }
+ }
+ fpnt = (struct input_file *) xmalloc (sizeof (struct input_file));
+ if (!file_root)
+ file_root = fpnt;
+ else
+ last->next = fpnt;
+ fpnt->next = 0;
+ fpnt->name = sp_name;
+ fpnt->min_line = 0x7fffffff;
+ fpnt->max_line = 0;
+ fpnt->offset = 0;
+ fpnt->flag = 0;
+ fpnt->file_number = 0;
+ fpnt->spnt = sp;
+ fpnt->same_file_fpnt = same_file;
+ return fpnt;
+}
+
+
+/* This routine converts a number string into an integer, and stops when
+ it sees an invalid character. The return value is the address of the
+ character just past the last character read. No error is generated. */
+
+static char *
+cvt_integer (str, rtn)
+ char *str;
+ int *rtn;
+{
+ int ival = 0, sgn = 1;
+
+ if (*str == '-')
+ sgn = -1, ++str;
+ while (*str >= '0' && *str <= '9')
+ ival = 10 * ival + *str++ - '0';
+ *rtn = sgn * ival;
+ return str;
+}
+
+
+/*
+ * The following functions and definitions are used to generate object
+ * records that will describe program variables to the VMS debugger.
+ *
+ * This file contains many of the routines needed to output debugging info
+ * into the object file that the VMS debugger needs to understand symbols.
+ * These routines are called very late in the assembly process, and thus
+ * we can be fairly lax about changing things, since the GSD and the TIR
+ * sections have already been output.
+ */
+
+
+/* This routine fixes the names that are generated by C++, ".this" is a good
+ example. The period does not work for the debugger, since it looks like
+ the syntax for a structure element, and thus it gets mightily confused.
+
+ We also use this to strip the PsectAttribute hack from the name before we
+ write a debugger record. */
+
+static char *
+fix_name (pnt)
+ char *pnt;
+{
+ char *pnt1;
+
+ /* Kill any leading "_". */
+ if (*pnt == '_')
+ pnt++;
+
+ /* Is there a Psect Attribute to skip?? */
+ if (HAS_PSECT_ATTRIBUTES (pnt))
+ {
+ /* Yes: Skip it. */
+ pnt += PSECT_ATTRIBUTES_STRING_LENGTH;
+ while (*pnt)
+ {
+ if ((pnt[0] == '$') && (pnt[1] == '$'))
+ {
+ pnt += 2;
+ break;
+ }
+ pnt++;
+ }
+ }
+
+ /* Here we fix the .this -> $this conversion. */
+ for (pnt1 = pnt; *pnt1 != 0; pnt1++)
+ if (*pnt1 == '.')
+ *pnt1 = '$';
+
+ return pnt;
+}
+
+
+/* When defining a structure, this routine is called to find the name of
+ the actual structure. It is assumed that str points to the equal sign
+ in the definition, and it moves backward until it finds the start of the
+ name. If it finds a 0, then it knows that this structure def is in the
+ outermost level, and thus symbol_name points to the symbol name. */
+
+static char *
+get_struct_name (str)
+ char *str;
+{
+ char *pnt;
+ pnt = str;
+ while ((*pnt != ':') && (*pnt != '\0'))
+ pnt--;
+ if (*pnt == '\0')
+ return (char *) symbol_name;
+ *pnt-- = '\0';
+ while ((*pnt != ';') && (*pnt != '='))
+ pnt--;
+ if (*pnt == ';')
+ return pnt + 1;
+ while ((*pnt < '0') || (*pnt > '9'))
+ pnt++;
+ while ((*pnt >= '0') && (*pnt <= '9'))
+ pnt++;
+ return pnt;
+}
+
+
+/* Search symbol list for type number dbx_type.
+ Return a pointer to struct. */
+
+static struct VMS_DBG_Symbol *
+find_symbol (dbx_type)
+ int dbx_type;
+{
+ struct VMS_DBG_Symbol *spnt;
+
+ spnt = VMS_Symbol_type_list[SYMTYP_HASH (dbx_type)];
+ while (spnt)
+ {
+ if (spnt->dbx_type == dbx_type)
+ break;
+ spnt = spnt->next;
+ }
+ if (!spnt || spnt->advanced != ALIAS)
+ return spnt;
+ return find_symbol (spnt->type2);
+}
+
+
+#if 0 /* obsolete */
+/* this routine puts info into either Local or Asuffix, depending on the sign
+ * of size. The reason is that it is easier to build the variable descriptor
+ * backwards, while the array descriptor is best built forwards. In the end
+ * they get put together, if there is not a struct/union/enum along the way
+ */
+static void
+push (value, size1)
+ int value, size1;
+{
+ if (size1 < 0)
+ {
+ size1 = -size1;
+ if (Lpnt < size1)
+ {
+ overflow = 1;
+ Lpnt = 1;
+ return;
+ }
+ Lpnt -= size1;
+ md_number_to_chars (&Local[Lpnt + 1], value, size1);
+ }
+ else
+ {
+ if (Apoint + size1 >= MAX_DEBUG_RECORD)
+ {
+ overflow = 1;
+ Apoint = MAX_DEBUG_RECORD - 1;
+ return;
+ }
+ md_number_to_chars (&Asuffix[Apoint], value, size1);
+ Apoint += size1;
+ }
+}
+#endif
+
+
+static void
+fpush (value, size)
+ int value, size;
+{
+ if (Apoint + size >= MAX_DEBUG_RECORD)
+ {
+ overflow = 1;
+ Apoint = MAX_DEBUG_RECORD - 1;
+ return;
+ }
+ if (size == 1)
+ Asuffix[Apoint++] = (char) value;
+ else
+ {
+ md_number_to_chars (&Asuffix[Apoint], value, size);
+ Apoint += size;
+ }
+}
+
+static void
+rpush (value, size)
+ int value, size;
+{
+ if (Lpnt < size)
+ {
+ overflow = 1;
+ Lpnt = 1;
+ return;
+ }
+ if (size == 1)
+ Local[Lpnt--] = (char) value;
+ else
+ {
+ Lpnt -= size;
+ md_number_to_chars (&Local[Lpnt + 1], value, size);
+ }
+}
+
+
+/* This routine generates the array descriptor for a given array. */
+
+static void
+array_suffix (spnt2)
+ struct VMS_DBG_Symbol *spnt2;
+{
+ struct VMS_DBG_Symbol *spnt;
+ struct VMS_DBG_Symbol *spnt1;
+ int rank;
+ int total_size;
+
+ rank = 0;
+ spnt = spnt2;
+ while (spnt->advanced != ARRAY)
+ {
+ spnt = find_symbol (spnt->type2);
+ if (!spnt)
+ return;
+ }
+ spnt1 = spnt;
+ total_size = 1;
+ while (spnt1->advanced == ARRAY)
+ {
+ rank++;
+ total_size *= (spnt1->index_max - spnt1->index_min + 1);
+ spnt1 = find_symbol (spnt1->type2);
+ }
+ total_size = total_size * spnt1->data_size;
+ fpush (spnt1->data_size, 2); /* element size */
+ if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
+ fpush (0, 1);
+ else
+ fpush (spnt1->VMS_type, 1); /* element type */
+ fpush (DSC_K_CLASS_A, 1); /* descriptor class */
+ fpush (0, 4); /* base address */
+ fpush (0, 1); /* scale factor -- not applicable */
+ fpush (0, 1); /* digit count -- not applicable */
+ fpush (0xc0, 1); /* flags: multiplier block & bounds present */
+ fpush (rank, 1); /* number of dimensions */
+ fpush (total_size, 4);
+ fpush (0, 4); /* pointer to element [0][0]...[0] */
+ spnt1 = spnt;
+ while (spnt1->advanced == ARRAY)
+ {
+ fpush (spnt1->index_max - spnt1->index_min + 1, 4);
+ spnt1 = find_symbol (spnt1->type2);
+ }
+ spnt1 = spnt;
+ while (spnt1->advanced == ARRAY)
+ {
+ fpush (spnt1->index_min, 4);
+ fpush (spnt1->index_max, 4);
+ spnt1 = find_symbol (spnt1->type2);
+ }
+}
+
+
+/* This routine generates the start of a variable descriptor based upon
+ a struct/union/enum that has yet to be defined. We define this spot as
+ a new location, and save four bytes for the address. When the struct is
+ finally defined, then we can go back and plug in the correct address. */
+
+static void
+new_forward_ref (dbx_type)
+ int dbx_type;
+{
+ struct forward_ref *fpnt;
+ fpnt = (struct forward_ref *) xmalloc (sizeof (struct forward_ref));
+ fpnt->next = f_ref_root;
+ f_ref_root = fpnt;
+ fpnt->dbx_type = dbx_type;
+ fpnt->struc_numb = ++structure_count;
+ fpnt->resolved = 'N';
+ rpush (DST_K_TS_IND, 1); /* indirect type specification */
+ total_len = 5;
+ rpush (total_len, 2);
+ struct_number = -fpnt->struc_numb;
+}
+
+
+/* This routine generates the variable descriptor used to describe non-basic
+ variables. It calls itself recursively until it gets to the bottom of it
+ all, and then builds the descriptor backwards. It is easiest to do it
+ this way since we must periodically write length bytes, and it is easiest
+ if we know the value when it is time to write it. */
+
+static int
+gen1 (spnt, array_suffix_len)
+ struct VMS_DBG_Symbol *spnt;
+ int array_suffix_len;
+{
+ struct VMS_DBG_Symbol *spnt1;
+ int i;
+
+ switch (spnt->advanced)
+ {
+ case VOID:
+ rpush (DBG_S_C_VOID, 1);
+ total_len += 1;
+ rpush (total_len, 2);
+ return 0;
+ case BASIC:
+ case FUNCTION:
+ if (array_suffix_len == 0)
+ {
+ rpush (spnt->VMS_type, 1);
+ rpush (DBG_S_C_BASIC, 1);
+ total_len = 2;
+ rpush (total_len, 2);
+ return 1;
+ }
+ rpush (0, 4);
+ rpush (DST_K_VFLAGS_DSC, 1);
+ rpush (DST_K_TS_DSC, 1); /* descriptor type specification */
+ total_len = -2;
+ return 1;
+ case STRUCT:
+ case UNION:
+ case ENUM:
+ struct_number = spnt->struc_numb;
+ if (struct_number < 0)
+ {
+ new_forward_ref (spnt->dbx_type);
+ return 1;
+ }
+ rpush (DBG_S_C_STRUCT, 1);
+ total_len = 5;
+ rpush (total_len, 2);
+ return 1;
+ case POINTER:
+ spnt1 = find_symbol (spnt->type2);
+ i = 1;
+ if (!spnt1)
+ new_forward_ref (spnt->type2);
+ else
+ i = gen1 (spnt1, 0);
+ if (i)
+ { /* (*void) is a special case, do not put pointer suffix */
+ rpush (DBG_S_C_POINTER, 1);
+ total_len += 3;
+ rpush (total_len, 2);
+ }
+ return 1;
+ case ARRAY:
+ spnt1 = spnt;
+ while (spnt1->advanced == ARRAY)
+ {
+ spnt1 = find_symbol (spnt1->type2);
+ if (!spnt1)
+ {
+ as_tsktsk (_("debugger forward reference error, dbx type %d"),
+ spnt->type2);
+ return 0;
+ }
+ }
+/* It is too late to generate forward references, so the user gets a message.
+ * This should only happen on a compiler error */
+ (void) gen1 (spnt1, 1);
+ i = Apoint;
+ array_suffix (spnt);
+ array_suffix_len = Apoint - i;
+ switch (spnt1->advanced)
+ {
+ case BASIC:
+ case FUNCTION:
+ break;
+ default:
+ rpush (0, 2);
+ total_len += 2;
+ rpush (total_len, 2);
+ rpush (DST_K_VFLAGS_DSC, 1);
+ rpush (1, 1); /* flags: element value spec included */
+ rpush (1, 1); /* one dimension */
+ rpush (DBG_S_C_COMPLEX_ARRAY, 1);
+ }
+ total_len += array_suffix_len + 8;
+ rpush (total_len, 2);
+ break;
+ default: /* lint suppression */
+ break;
+ }
+ return 0;
+}
+
+
+/* This generates a suffix for a variable. If it is not a defined type yet,
+ then dbx_type contains the type we are expecting so we can generate a
+ forward reference. This calls gen1 to build most of the descriptor, and
+ then it puts the icing on at the end. It then dumps whatever is needed
+ to get a complete descriptor (i.e. struct reference, array suffix). */
+
+static void
+generate_suffix (spnt, dbx_type)
+ struct VMS_DBG_Symbol *spnt;
+ int dbx_type;
+{
+ static const char pvoid[6] = {
+ 5, /* record.length == 5 */
+ DST_K_TYPSPEC, /* record.type == 1 (type specification) */
+ 0, /* name.length == 0, no name follows */
+ 1, 0, /* type.length == 1 {2 bytes, little endian} */
+ DBG_S_C_VOID /* type.type == 5 (pointer to unspecified) */
+ };
+ int i;
+
+ Apoint = 0;
+ Lpnt = MAX_DEBUG_RECORD - 1;
+ total_len = 0;
+ struct_number = 0;
+ overflow = 0;
+ if (!spnt)
+ new_forward_ref (dbx_type);
+ else
+ {
+ if (spnt->VMS_type != DBG_S_C_ADVANCED_TYPE)
+ return; /* no suffix needed */
+ gen1 (spnt, 0);
+ }
+ rpush (0, 1); /* no name (len==0) */
+ rpush (DST_K_TYPSPEC, 1);
+ total_len += 4;
+ rpush (total_len, 1);
+ /* If the variable descriptor overflows the record, output a descriptor
+ for a pointer to void. */
+ if ((total_len >= MAX_DEBUG_RECORD) || overflow)
+ {
+ as_warn (_("Variable descriptor %d too complicated. Defined as `void *'."),
+ spnt->dbx_type);
+ VMS_Store_Immediate_Data (pvoid, 6, OBJ_S_C_DBG);
+ return;
+ }
+ i = 0;
+ while (Lpnt < MAX_DEBUG_RECORD - 1)
+ Local[i++] = Local[++Lpnt];
+ Lpnt = i;
+ /* we use this for reference to structure that has already been defined */
+ if (struct_number > 0)
+ {
+ VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+ Lpnt = 0;
+ VMS_Store_Struct (struct_number);
+ }
+ /* We use this for a forward reference to a structure that has yet to
+ be defined. We store four bytes of zero to make room for the actual
+ address once it is known. */
+ if (struct_number < 0)
+ {
+ struct_number = -struct_number;
+ VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+ Lpnt = 0;
+ VMS_Def_Struct (struct_number);
+ COPY_LONG (&Local[Lpnt], 0L);
+ Lpnt += 4;
+ VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+ Lpnt = 0;
+ }
+ i = 0;
+ while (i < Apoint)
+ Local[Lpnt++] = Asuffix[i++];
+ if (Lpnt != 0)
+ VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+ Lpnt = 0;
+}
+
+
+ /* "novel length" type doesn't work for simple atomic types */
+#define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
+#undef SETUP_BASIC_TYPES
+
+/* This routine generates a type description for a bitfield. */
+
+static void
+bitfield_suffix (spnt, width)
+ struct VMS_DBG_Symbol *spnt;
+ int width;
+{
+ Local[Lpnt++] = 13; /* rec.len==13 */
+ Local[Lpnt++] = DST_K_TYPSPEC; /* a type specification record */
+ Local[Lpnt++] = 0; /* not named */
+ COPY_SHORT (&Local[Lpnt], 9); /* typ.len==9 */
+ Lpnt += 2;
+ Local[Lpnt++] = DST_K_TS_NOV_LENG; /* This type is a "novel length"
+ incarnation of some other type. */
+ COPY_LONG (&Local[Lpnt], width); /* size in bits == novel length */
+ Lpnt += 4;
+ VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+ Lpnt = 0;
+ /* assert( spnt->struc_numb > 0 ); */
+ VMS_Store_Struct (spnt->struc_numb); /* output 4 more bytes */
+}
+
+
+/* Formally define a builtin type, so that it can serve as the target of
+ an indirect reference. It makes bitfield_suffix() easier by avoiding
+ the need to use a forward reference for the first occurrence of each
+ type used in a bitfield. */
+
+static void
+setup_basic_type (spnt)
+ struct VMS_DBG_Symbol *spnt;
+{
+#ifdef SETUP_BASIC_TYPES
+ /* This would be very useful if "novel length" fields actually worked
+ with basic types like they do with enumerated types. However,
+ they do not, so this isn't worth doing just so that you can use
+ EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD. */
+ char *p;
+#ifndef SETUP_SYNONYM_TYPES
+ /* This determines whether compatible things like `int' and `long int'
+ ought to have distinct type records rather than sharing one. */
+ struct VMS_DBG_Symbol *spnt2;
+
+ /* first check whether this type has already been seen by another name */
+ for (spnt2 = VMS_Symbol_type_list[SYMTYP_HASH (spnt->VMS_type)];
+ spnt2;
+ spnt2 = spnt2->next)
+ if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type)
+ {
+ spnt->struc_numb = spnt2->struc_numb;
+ return;
+ }
+#endif
+
+ /* `structure number' doesn't really mean `structure'; it means an index
+ into a linker maintained set of saved locations which can be referenced
+ again later. */
+ spnt->struc_numb = ++structure_count;
+ VMS_Def_Struct (spnt->struc_numb); /* remember where this type lives */
+ /* define the simple scalar type */
+ Local[Lpnt++] = 6 + strlen (symbol_name) + 2; /* rec.len */
+ Local[Lpnt++] = DST_K_TYPSPEC; /* rec.typ==type specification */
+ Local[Lpnt++] = strlen (symbol_name) + 2;
+ Local[Lpnt++] = '_'; /* prefix name with "__" */
+ Local[Lpnt++] = '_';
+ for (p = symbol_name; *p; p++)
+ Local[Lpnt++] = *p == ' ' ? '_' : *p;
+ COPY_SHORT (&Local[Lpnt], 2); /* typ.len==2 */
+ Lpnt += 2;
+ Local[Lpnt++] = DST_K_TS_ATOM; /* typ.kind is simple type */
+ Local[Lpnt++] = spnt->VMS_type; /* typ.type */
+ VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+ Lpnt = 0;
+#endif /* SETUP_BASIC_TYPES */
+ return;
+}
+
+
+/* This routine generates a symbol definition for a C symbol for the debugger.
+ It takes a psect and offset for global symbols; if psect < 0, then this is
+ a local variable and the offset is relative to FP. In this case it can
+ be either a variable (Offset < 0) or a parameter (Offset > 0). */
+
+static void
+VMS_DBG_record (spnt, Psect, Offset, Name)
+ struct VMS_DBG_Symbol *spnt;
+ int Psect;
+ int Offset;
+ char *Name;
+{
+ char *Name_pnt;
+ int len;
+ int i = 0;
+
+ /* if there are bad characters in name, convert them */
+ Name_pnt = fix_name (Name);
+
+ len = strlen (Name_pnt);
+ if (Psect < 0)
+ { /* this is a local variable, referenced to SP */
+ Local[i++] = 7 + len;
+ Local[i++] = spnt->VMS_type;
+ Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM;
+ COPY_LONG (&Local[i], Offset);
+ i += 4;
+ }
+ else
+ {
+ Local[i++] = 7 + len;
+ Local[i++] = spnt->VMS_type;
+ Local[i++] = DST_K_VALKIND_ADDR;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
+ }
+ Local[i++] = len;
+ while (*Name_pnt != '\0')
+ Local[i++] = *Name_pnt++;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
+ generate_suffix (spnt, 0);
+}
+
+
+/* This routine parses the stabs entries in order to make the definition
+ for the debugger of local symbols and function parameters. */
+
+static void
+VMS_local_stab_Parse (sp)
+ symbolS *sp;
+{
+ struct VMS_DBG_Symbol *spnt;
+ char *pnt;
+ char *pnt1;
+ char *str;
+ int dbx_type;
+
+ dbx_type = 0;
+ str = S_GET_NAME (sp);
+ pnt = (char *) strchr (str, ':');
+ if (!pnt)
+ return; /* no colon present */
+ pnt1 = pnt++; /* save this for later, and skip colon */
+ if (*pnt == 'c')
+ return; /* ignore static constants */
+
+/* there is one little catch that we must be aware of. Sometimes function
+ * parameters are optimized into registers, and the compiler, in its infiite
+ * wisdom outputs stabs records for *both*. In general we want to use the
+ * register if it is present, so we must search the rest of the symbols for
+ * this function to see if this parameter is assigned to a register.
+ */
+ {
+ symbolS *sp1;
+ char *str1;
+ char *pnt2;
+
+ if (*pnt == 'p')
+ {
+ for (sp1 = symbol_next (sp); sp1; sp1 = symbol_next (sp1))
+ {
+ if (!S_IS_DEBUG (sp1))
+ continue;
+ if (S_GET_RAW_TYPE (sp1) == N_FUN)
+ {
+ pnt2 = (char *) strchr (S_GET_NAME (sp1), ':') + 1;
+ if (*pnt2 == 'F' || *pnt2 == 'f')
+ break;
+ }
+ if (S_GET_RAW_TYPE (sp1) != N_RSYM)
+ continue;
+ str1 = S_GET_NAME (sp1); /* and get the name */
+ pnt2 = str;
+ while (*pnt2 != ':')
+ {
+ if (*pnt2 != *str1)
+ break;
+ pnt2++;
+ str1++;
+ }
+ if (*str1 == ':' && *pnt2 == ':')
+ return; /* they are the same! lets skip this one */
+ } /* for */
+ pnt++; /* skip p in case no register */
+ } /* if */
+ } /* p block */
+
+ pnt = cvt_integer (pnt, &dbx_type);
+ spnt = find_symbol (dbx_type);
+ if (!spnt)
+ return; /*Dunno what this is*/
+ *pnt1 = '\0';
+ VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
+ *pnt1 = ':'; /* and restore the string */
+ return;
+}
+
+
+/* This routine parses a stabs entry to find the information required
+ to define a variable. It is used for global and static variables.
+ Basically we need to know the address of the symbol. With older
+ versions of the compiler, const symbols are treated differently, in
+ that if they are global they are written into the text psect. The
+ global symbol entry for such a const is actually written as a program
+ entry point (Yuk!!), so if we cannot find a symbol in the list of
+ psects, we must search the entry points as well. static consts are
+ even harder, since they are never assigned a memory address. The
+ compiler passes a stab to tell us the value, but I am not sure what
+ to do with it. */
+
+static void
+VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect)
+ symbolS *sp;
+ int expected_type; /* char */
+ int type1, type2, Text_Psect;
+{
+ char *pnt;
+ char *pnt1;
+ char *str;
+ symbolS *sp1;
+ struct VMS_DBG_Symbol *spnt;
+ struct VMS_Symbol *vsp;
+ int dbx_type;
+
+ dbx_type = 0;
+ str = S_GET_NAME (sp);
+ pnt = (char *) strchr (str, ':');
+ if (!pnt)
+ return; /* no colon present */
+ pnt1 = pnt; /* save this for later*/
+ pnt++;
+ if (*pnt == expected_type)
+ {
+ pnt = cvt_integer (pnt + 1, &dbx_type);
+ spnt = find_symbol (dbx_type);
+ if (!spnt)
+ return; /*Dunno what this is*/
+ /*
+ * Now we need to search the symbol table to find the psect and
+ * offset for this variable.
+ */
+ *pnt1 = '\0';
+ vsp = VMS_Symbols;
+ while (vsp)
+ {
+ pnt = S_GET_NAME (vsp->Symbol);
+ if (pnt && *pnt++ == '_'
+ /* make sure name is the same and symbol type matches */
+ && strcmp (pnt, str) == 0
+ && (S_GET_RAW_TYPE (vsp->Symbol) == type1
+ || S_GET_RAW_TYPE (vsp->Symbol) == type2))
+ break;
+ vsp = vsp->Next;
+ }
+ if (vsp)
+ {
+ VMS_DBG_record (spnt, vsp->Psect_Index, vsp->Psect_Offset, str);
+ *pnt1 = ':'; /* and restore the string */
+ return;
+ }
+ /* The symbol was not in the symbol list, but it may be an
+ "entry point" if it was a constant. */
+ for (sp1 = symbol_rootP; sp1; sp1 = symbol_next (sp1))
+ {
+ /*
+ * Dispatch on STAB type
+ */
+ if (S_IS_DEBUG (sp1) || (S_GET_TYPE (sp1) != N_TEXT))
+ continue;
+ pnt = S_GET_NAME (sp1);
+ if (*pnt == '_')
+ pnt++;
+ if (strcmp (pnt, str) == 0)
+ {
+ if (!gave_compiler_message && expected_type == 'G')
+ {
+ char *long_const_msg = _("\
+***Warning - the assembly code generated by the compiler has placed \n\
+ global constant(s) in the text psect. These will not be available to \n\
+ other modules, since this is not the correct way to handle this. You \n\
+ have two options: 1) get a patched compiler that does not put global \n\
+ constants in the text psect, or 2) remove the 'const' keyword from \n\
+ definitions of global variables in your source module(s). Don't say \n\
+ I didn't warn you! \n");
+
+ as_tsktsk (long_const_msg);
+ gave_compiler_message = 1;
+ }
+ VMS_DBG_record (spnt,
+ Text_Psect,
+ S_GET_VALUE (sp1),
+ str);
+ *pnt1 = ':';
+ /* fool assembler to not output this as a routine in the TBT */
+ pnt1 = S_GET_NAME (sp1);
+ *pnt1 = 'L';
+ S_SET_NAME (sp1, pnt1);
+ return;
+ }
+ }
+ }
+ *pnt1 = ':'; /* and restore the string */
+ return;
+}
+
+
+/* Simpler interfaces into VMS_stab_parse(). */
+
+static void
+VMS_GSYM_Parse (sp, Text_Psect)
+ symbolS *sp;
+ int Text_Psect;
+{ /* Global variables */
+ VMS_stab_parse (sp, 'G', (N_UNDF | N_EXT), (N_DATA | N_EXT), Text_Psect);
+}
+
+static void
+VMS_LCSYM_Parse (sp, Text_Psect)
+ symbolS *sp;
+ int Text_Psect;
+{ /* Static symbols - uninitialized */
+ VMS_stab_parse (sp, 'S', N_BSS, -1, Text_Psect);
+}
+
+static void
+VMS_STSYM_Parse (sp, Text_Psect)
+ symbolS *sp;
+ int Text_Psect;
+{ /* Static symbols - initialized */
+ VMS_stab_parse (sp, 'S', N_DATA, -1, Text_Psect);
+}
+
+
+/* For register symbols, we must figure out what range of addresses
+ within the psect are valid. We will use the brackets in the stab
+ directives to give us guidance as to the PC range that this variable
+ is in scope. I am still not completely comfortable with this but
+ as I learn more, I seem to get a better handle on what is going on.
+ Caveat Emptor. */
+
+static void
+VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
+ symbolS *sp, *Current_Routine;
+ int Text_Psect;
+{
+ symbolS *symbolP;
+ struct VMS_DBG_Symbol *spnt;
+ char *pnt;
+ char *pnt1;
+ char *str;
+ int dbx_type;
+ int len;
+ int i = 0;
+ int bcnt = 0;
+ int Min_Offset = -1; /* min PC of validity */
+ int Max_Offset = 0; /* max PC of validity */
+
+ for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /*
+ * Dispatch on STAB type
+ */
+ switch (S_GET_RAW_TYPE (symbolP))
+ {
+ case N_LBRAC:
+ if (bcnt++ == 0)
+ Min_Offset = S_GET_VALUE (symbolP);
+ break;
+ case N_RBRAC:
+ if (--bcnt == 0)
+ Max_Offset = S_GET_VALUE (symbolP) - 1;
+ break;
+ }
+ if ((Min_Offset != -1) && (bcnt == 0))
+ break;
+ if (S_GET_RAW_TYPE (symbolP) == N_FUN)
+ {
+ pnt = (char *) strchr (S_GET_NAME (symbolP), ':') + 1;
+ if (*pnt == 'F' || *pnt == 'f') break;
+ }
+ }
+
+ /* Check to see that the addresses were defined. If not, then there
+ were no brackets in the function, and we must try to search for
+ the next function. Since functions can be in any order, we should
+ search all of the symbol list to find the correct ending address. */
+ if (Min_Offset == -1)
+ {
+ int Max_Source_Offset;
+ int This_Offset;
+
+ Min_Offset = S_GET_VALUE (sp);
+ Max_Source_Offset = Min_Offset; /* just in case no N_SLINEs found */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ switch (S_GET_RAW_TYPE (symbolP))
+ {
+ case N_TEXT | N_EXT:
+ This_Offset = S_GET_VALUE (symbolP);
+ if (This_Offset > Min_Offset && This_Offset < Max_Offset)
+ Max_Offset = This_Offset;
+ break;
+ case N_SLINE:
+ This_Offset = S_GET_VALUE (symbolP);
+ if (This_Offset > Max_Source_Offset)
+ Max_Source_Offset = This_Offset;
+ break;
+ }
+ /* If this is the last routine, then we use the PC of the last source
+ line as a marker of the max PC for which this reg is valid. */
+ if (Max_Offset == 0x7fffffff)
+ Max_Offset = Max_Source_Offset;
+ }
+
+ dbx_type = 0;
+ str = S_GET_NAME (sp);
+ if ((pnt = (char *) strchr (str, ':')) == 0)
+ return; /* no colon present */
+ pnt1 = pnt; /* save this for later*/
+ pnt++;
+ if (*pnt != 'r')
+ return;
+ pnt = cvt_integer (pnt + 1, &dbx_type);
+ spnt = find_symbol (dbx_type);
+ if (!spnt)
+ return; /*Dunno what this is yet*/
+ *pnt1 = '\0';
+ pnt = fix_name (S_GET_NAME (sp)); /* if there are bad characters in name, convert them */
+ len = strlen (pnt);
+ Local[i++] = 25 + len;
+ Local[i++] = spnt->VMS_type;
+ Local[i++] = DST_K_VFLAGS_TVS; /* trailing value specified */
+ COPY_LONG (&Local[i], 1 + len); /* relative offset, beyond name */
+ i += 4;
+ Local[i++] = len; /* name length (ascic prefix) */
+ while (*pnt != '\0')
+ Local[i++] = *pnt++;
+ Local[i++] = DST_K_VS_FOLLOWS; /* value specification follows */
+ COPY_SHORT (&Local[i], 15); /* length of rest of record */
+ i += 2;
+ Local[i++] = DST_K_VS_ALLOC_SPLIT; /* split lifetime */
+ Local[i++] = 1; /* one binding follows */
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
+ VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
+ Local[i++] = DST_K_VALKIND_REG; /* nested value spec */
+ COPY_LONG (&Local[i], S_GET_VALUE (sp));
+ i += 4;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ *pnt1 = ':';
+ if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
+ generate_suffix (spnt, 0);
+}
+
+
+/* This function examines a structure definition, checking all of the elements
+ to make sure that all of them are fully defined. The only thing that we
+ kick out are arrays of undefined structs, since we do not know how big
+ they are. All others we can handle with a normal forward reference. */
+
+static int
+forward_reference (pnt)
+ char *pnt;
+{
+ struct VMS_DBG_Symbol *spnt, *spnt1;
+ int i;
+
+ pnt = cvt_integer (pnt + 1, &i);
+ if (*pnt == ';')
+ return 0; /* no forward references */
+ do
+ {
+ pnt = (char *) strchr (pnt, ':');
+ pnt = cvt_integer (pnt + 1, &i);
+ spnt = find_symbol (i);
+ while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
+ {
+ spnt1 = find_symbol (spnt->type2);
+ if (spnt->advanced == ARRAY && !spnt1)
+ return 1;
+ spnt = spnt1;
+ }
+ pnt = cvt_integer (pnt + 1, &i);
+ pnt = cvt_integer (pnt + 1, &i);
+ } while (*++pnt != ';');
+ return 0; /* no forward refences found */
+}
+
+
+/* Used to check a single element of a structure on the final pass. */
+
+static int
+final_forward_reference (spnt)
+ struct VMS_DBG_Symbol *spnt;
+{
+ struct VMS_DBG_Symbol *spnt1;
+
+ while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
+ {
+ spnt1 = find_symbol (spnt->type2);
+ if (spnt->advanced == ARRAY && !spnt1)
+ return 1;
+ spnt = spnt1;
+ }
+ return 0; /* no forward refences found */
+}
+
+
+/* This routine parses the stabs directives to find any definitions of dbx
+ type numbers. It makes a note of all of them, creating a structure
+ element of VMS_DBG_Symbol that describes it. This also generates the
+ info for the debugger that describes the struct/union/enum, so that
+ further references to these data types will be by number
+
+ We have to process pointers right away, since there can be references
+ to them later in the same stabs directive. We cannot have forward
+ references to pointers, (but we can have a forward reference to a
+ pointer to a structure/enum/union) and this is why we process them
+ immediately. After we process the pointer, then we search for defs
+ that are nested even deeper.
+
+ 8/15/92: We have to process arrays right away too, because there can
+ be multiple references to identical array types in one structure
+ definition, and only the first one has the definition. */
+
+static int
+VMS_typedef_parse (str)
+ char *str;
+{
+ char *pnt;
+ char *pnt1;
+ const char *pnt2;
+ int i;
+ int dtype;
+ struct forward_ref *fpnt;
+ int i1, i2, i3, len;
+ struct VMS_DBG_Symbol *spnt;
+ struct VMS_DBG_Symbol *spnt1;
+
+ /* check for any nested def's */
+ pnt = (char *) strchr (str + 1, '=');
+ if (pnt && str[1] != '*' && (str[1] != 'a' || str[2] != 'r')
+ && VMS_typedef_parse (pnt) == 1)
+ return 1;
+ /* now find dbx_type of entry */
+ pnt = str - 1;
+ if (*pnt == 'c')
+ { /* check for static constants */
+ *str = '\0'; /* for now we ignore them */
+ return 0;
+ }
+ while ((*pnt <= '9') && (*pnt >= '0'))
+ pnt--;
+ pnt++; /* and get back to the number */
+ cvt_integer (pnt, &i1);
+ spnt = find_symbol (i1);
+ /* first see if this has been defined already, due to forward reference */
+ if (!spnt)
+ {
+ i2 = SYMTYP_HASH (i1);
+ spnt = (struct VMS_DBG_Symbol *) xmalloc (sizeof (struct VMS_DBG_Symbol));
+ spnt->next = VMS_Symbol_type_list[i2];
+ VMS_Symbol_type_list[i2] = spnt;
+ spnt->dbx_type = i1; /* and save the type */
+ spnt->type2 = spnt->VMS_type = spnt->data_size = 0;
+ spnt->index_min = spnt->index_max = spnt->struc_numb = 0;
+ }
+ /*
+ * For structs and unions, do a partial parse, otherwise we sometimes get
+ * circular definitions that are impossible to resolve. We read enough
+ * info so that any reference to this type has enough info to be resolved.
+ */
+ pnt = str + 1; /* point to character past equal sign */
+ if (*pnt >= '0' && *pnt <= '9')
+ {
+ if (type_check ("void"))
+ { /* this is the void symbol */
+ *str = '\0';
+ spnt->advanced = VOID;
+ return 0;
+ }
+ if (type_check ("unknown type"))
+ {
+ *str = '\0';
+ spnt->advanced = UNKNOWN;
+ return 0;
+ }
+ pnt1 = cvt_integer (pnt, &i1);
+ if (i1 != spnt->dbx_type)
+ {
+ spnt->advanced = ALIAS;
+ spnt->type2 = i1;
+ strcpy (str, pnt1);
+ return 0;
+ }
+ as_tsktsk (_("debugginer output: %d is an unknown untyped variable."),
+ spnt->dbx_type);
+ return 1; /* do not know what this is */
+ }
+
+ pnt = str + 1; /* point to character past equal sign */
+ switch (*pnt)
+ {
+ case 'r':
+ spnt->advanced = BASIC;
+ if (type_check ("int"))
+ {
+ spnt->VMS_type = DBG_S_C_SLINT;
+ spnt->data_size = 4;
+ }
+ else if (type_check ("long int"))
+ {
+ spnt->VMS_type = DBG_S_C_SLINT;
+ spnt->data_size = 4;
+ }
+ else if (type_check ("unsigned int"))
+ {
+ spnt->VMS_type = DBG_S_C_ULINT;
+ spnt->data_size = 4;
+ }
+ else if (type_check ("long unsigned int"))
+ {
+ spnt->VMS_type = DBG_S_C_ULINT;
+ spnt->data_size = 4;
+ }
+ else if (type_check ("short int"))
+ {
+ spnt->VMS_type = DBG_S_C_SSINT;
+ spnt->data_size = 2;
+ }
+ else if (type_check ("short unsigned int"))
+ {
+ spnt->VMS_type = DBG_S_C_USINT;
+ spnt->data_size = 2;
+ }
+ else if (type_check ("char"))
+ {
+ spnt->VMS_type = DBG_S_C_SCHAR;
+ spnt->data_size = 1;
+ }
+ else if (type_check ("signed char"))
+ {
+ spnt->VMS_type = DBG_S_C_SCHAR;
+ spnt->data_size = 1;
+ }
+ else if (type_check ("unsigned char"))
+ {
+ spnt->VMS_type = DBG_S_C_UCHAR;
+ spnt->data_size = 1;
+ }
+ else if (type_check ("float"))
+ {
+ spnt->VMS_type = DBG_S_C_REAL4;
+ spnt->data_size = 4;
+ }
+ else if (type_check ("double"))
+ {
+ spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
+ spnt->data_size = 8;
+ }
+ else if (type_check ("long double"))
+ {
+ /* same as double, at least for now */
+ spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
+ spnt->data_size = 8;
+ }
+ else if (type_check ("long long int"))
+ {
+ spnt->VMS_type = DBG_S_C_SQUAD; /* signed quadword */
+ spnt->data_size = 8;
+ }
+ else if (type_check ("long long unsigned int"))
+ {
+ spnt->VMS_type = DBG_S_C_UQUAD; /* unsigned quadword */
+ spnt->data_size = 8;
+ }
+ else if (type_check ("complex float"))
+ {
+ spnt->VMS_type = DBG_S_C_COMPLX4;
+ spnt->data_size = 2 * 4;
+ }
+ else if (type_check ("complex double"))
+ {
+ spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
+ spnt->data_size = 2 * 8;
+ }
+ else if (type_check ("complex long double"))
+ {
+ /* same as complex double, at least for now */
+ spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
+ spnt->data_size = 2 * 8;
+ }
+ else
+ {
+ /* [pr]
+ * Shouldn't get here, but if we do, something
+ * more substantial ought to be done...
+ */
+ spnt->VMS_type = 0;
+ spnt->data_size = 0;
+ }
+ if (spnt->VMS_type != 0)
+ setup_basic_type (spnt);
+ pnt1 = (char *) strchr (str, ';') + 1;
+ break;
+ case 's':
+ case 'u':
+ spnt->advanced = (*pnt == 's') ? STRUCT : UNION;
+ spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
+ pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
+ if (!final_pass && forward_reference (pnt))
+ {
+ spnt->struc_numb = -1;
+ return 1;
+ }
+ spnt->struc_numb = ++structure_count;
+ pnt1--;
+ pnt = get_struct_name (str);
+ VMS_Def_Struct (spnt->struc_numb);
+ i = 0;
+ for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
+ if (fpnt->dbx_type == spnt->dbx_type)
+ {
+ fpnt->resolved = 'Y';
+ VMS_Set_Struct (fpnt->struc_numb);
+ VMS_Store_Struct (spnt->struc_numb);
+ i++;
+ }
+ if (i > 0)
+ VMS_Set_Struct (spnt->struc_numb);
+ i = 0;
+ Local[i++] = 11 + strlen (pnt);
+ Local[i++] = DBG_S_C_STRUCT_START;
+ Local[i++] = DST_K_VFLAGS_NOVAL; /* structure definition only */
+ COPY_LONG (&Local[i], 0L); /* hence value is unused */
+ i += 4;
+ Local[i++] = strlen (pnt);
+ pnt2 = pnt;
+ while (*pnt2 != '\0')
+ Local[i++] = *pnt2++;
+ i2 = spnt->data_size * 8; /* number of bits */
+ COPY_LONG (&Local[i], i2);
+ i += 4;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ if (pnt != symbol_name)
+ {
+ pnt += strlen (pnt);
+ *pnt = ':';
+ } /* replace colon for later */
+ while (*++pnt1 != ';')
+ {
+ pnt = (char *) strchr (pnt1, ':');
+ *pnt = '\0';
+ pnt2 = pnt1;
+ pnt1 = cvt_integer (pnt + 1, &dtype);
+ pnt1 = cvt_integer (pnt1 + 1, &i2);
+ pnt1 = cvt_integer (pnt1 + 1, &i3);
+ spnt1 = find_symbol (dtype);
+ len = strlen (pnt2);
+ if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM)
+ && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0)))
+ { /* bitfield */
+ if (USE_BITSTRING_DESCRIPTOR (spnt1))
+ {
+ /* This uses a type descriptor, which doesn't work if
+ the enclosing structure has been placed in a register.
+ Also, enum bitfields degenerate to simple integers. */
+ int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT
+ || spnt1->VMS_type == DBG_S_C_USINT
+ || spnt1->VMS_type == DBG_S_C_UCHAR
+ || spnt1->VMS_type == DBG_S_C_UQUAD
+ || spnt1->advanced == ENUM); /* (approximate) */
+ Apoint = 0;
+ fpush (19 + len, 1);
+ fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
+ fpush (DST_K_VFLAGS_DSC, 1); /* specified by descriptor */
+ fpush (1 + len, 4); /* relative offset to descriptor */
+ fpush (len, 1); /* length byte (ascic prefix) */
+ while (*pnt2 != '\0') /* name bytes */
+ fpush (*pnt2++, 1);
+ fpush (i3, 2); /* dsc length == size of bitfield */
+ /* dsc type == un?signed bitfield */
+ fpush (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
+ fpush (DSC_K_CLASS_UBS, 1); /* dsc class == unaligned bitstring */
+ fpush (0x00, 4); /* dsc pointer == zeroes */
+ fpush (i2, 4); /* start position */
+ VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
+ Apoint = 0;
+ }
+ else
+ {
+ /* Use a "novel length" type specification, which works
+ right for register structures and for enum bitfields
+ but results in larger object modules. */
+ Local[i++] = 7 + len;
+ Local[i++] = DBG_S_C_ADVANCED_TYPE; /* type spec follows */
+ Local[i++] = DBG_S_C_STRUCT_ITEM; /* value is a bit offset */
+ COPY_LONG (&Local[i], i2); /* bit offset */
+ i += 4;
+ Local[i++] = strlen (pnt2);
+ while (*pnt2 != '\0')
+ Local[i++] = *pnt2++;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ bitfield_suffix (spnt1, i3);
+ }
+ }
+ else
+ { /* not a bitfield */
+ /* check if this is a forward reference */
+ if (final_pass && final_forward_reference (spnt1))
+ {
+ as_tsktsk (_("debugger output: structure element `%s' has undefined type"),
+ pnt2);
+ continue;
+ }
+ Local[i++] = 7 + len;
+ Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE;
+ Local[i++] = DBG_S_C_STRUCT_ITEM;
+ COPY_LONG (&Local[i], i2); /* bit offset */
+ i += 4;
+ Local[i++] = strlen (pnt2);
+ while (*pnt2 != '\0')
+ Local[i++] = *pnt2++;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ if (!spnt1)
+ generate_suffix (spnt1, dtype);
+ else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
+ generate_suffix (spnt1, 0);
+ }
+ }
+ pnt1++;
+ Local[i++] = 0x01; /* length byte */
+ Local[i++] = DBG_S_C_STRUCT_END;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ break;
+ case 'e':
+ spnt->advanced = ENUM;
+ spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
+ spnt->struc_numb = ++structure_count;
+ spnt->data_size = 4;
+ VMS_Def_Struct (spnt->struc_numb);
+ i = 0;
+ for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
+ if (fpnt->dbx_type == spnt->dbx_type)
+ {
+ fpnt->resolved = 'Y';
+ VMS_Set_Struct (fpnt->struc_numb);
+ VMS_Store_Struct (spnt->struc_numb);
+ i++;
+ }
+ if (i > 0)
+ VMS_Set_Struct (spnt->struc_numb);
+ i = 0;
+ len = strlen (symbol_name);
+ Local[i++] = 3 + len;
+ Local[i++] = DBG_S_C_ENUM_START;
+ Local[i++] = 4 * 8; /* enum values are 32 bits */
+ Local[i++] = len;
+ pnt2 = symbol_name;
+ while (*pnt2 != '\0')
+ Local[i++] = *pnt2++;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ while (*++pnt != ';')
+ {
+ pnt1 = (char *) strchr (pnt, ':');
+ *pnt1++ = '\0';
+ pnt1 = cvt_integer (pnt1, &i1);
+ len = strlen (pnt);
+ Local[i++] = 7 + len;
+ Local[i++] = DBG_S_C_ENUM_ITEM;
+ Local[i++] = DST_K_VALKIND_LITERAL;
+ COPY_LONG (&Local[i], i1);
+ i += 4;
+ Local[i++] = len;
+ pnt2 = pnt;
+ while (*pnt != '\0')
+ Local[i++] = *pnt++;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ pnt = pnt1; /* Skip final semicolon */
+ }
+ Local[i++] = 0x01; /* len byte */
+ Local[i++] = DBG_S_C_ENUM_END;
+ VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+ i = 0;
+ pnt1 = pnt + 1;
+ break;
+ case 'a':
+ spnt->advanced = ARRAY;
+ spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
+ pnt = (char *) strchr (pnt, ';');
+ if (!pnt)
+ return 1;
+ pnt1 = cvt_integer (pnt + 1, &spnt->index_min);
+ pnt1 = cvt_integer (pnt1 + 1, &spnt->index_max);
+ pnt1 = cvt_integer (pnt1 + 1, &spnt->type2);
+ pnt = (char *) strchr (str + 1, '=');
+ if (pnt && VMS_typedef_parse (pnt) == 1)
+ return 1;
+ break;
+ case 'f':
+ spnt->advanced = FUNCTION;
+ spnt->VMS_type = DBG_S_C_FUNCTION_ADDR;
+ /* this masquerades as a basic type*/
+ spnt->data_size = 4;
+ pnt1 = cvt_integer (pnt + 1, &spnt->type2);
+ break;
+ case '*':
+ spnt->advanced = POINTER;
+ spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
+ spnt->data_size = 4;
+ pnt1 = cvt_integer (pnt + 1, &spnt->type2);
+ pnt = (char *) strchr (str + 1, '=');
+ if (pnt && VMS_typedef_parse (pnt) == 1)
+ return 1;
+ break;
+ default:
+ spnt->advanced = UNKNOWN;
+ spnt->VMS_type = 0;
+ as_tsktsk (_("debugger output: %d is an unknown type of variable."),
+ spnt->dbx_type);
+ return 1; /* unable to decipher */
+ }
+ /* This removes the evidence of the definition so that the outer levels
+ of parsing do not have to worry about it. */
+ pnt = str;
+ while (*pnt1 != '\0')
+ *pnt++ = *pnt1++;
+ *pnt = '\0';
+ return 0;
+}
+
+
+/* This is the root routine that parses the stabs entries for definitions.
+ it calls VMS_typedef_parse, which can in turn call itself. We need to
+ be careful, since sometimes there are forward references to other symbol
+ types, and these cannot be resolved until we have completed the parse.
+
+ Also check and see if we are using continuation stabs, if we are, then
+ paste together the entire contents of the stab before we pass it to
+ VMS_typedef_parse. */
+
+static void
+VMS_LSYM_Parse ()
+{
+ char *pnt;
+ char *pnt1;
+ char *pnt2;
+ char *str;
+ char *parse_buffer = 0;
+ char fixit[10];
+ int incomplete, pass, incom1;
+ struct forward_ref *fpnt;
+ symbolS *sp;
+
+ pass = 0;
+ final_pass = 0;
+ incomplete = 0;
+ do
+ {
+ incom1 = incomplete;
+ incomplete = 0;
+ for (sp = symbol_rootP; sp; sp = symbol_next (sp))
+ {
+ /*
+ * Deal with STAB symbols
+ */
+ if (S_IS_DEBUG (sp))
+ {
+ /*
+ * Dispatch on STAB type
+ */
+ switch (S_GET_RAW_TYPE (sp))
+ {
+ case N_GSYM:
+ case N_LCSYM:
+ case N_STSYM:
+ case N_PSYM:
+ case N_RSYM:
+ case N_LSYM:
+ case N_FUN: /*sometimes these contain typedefs*/
+ str = S_GET_NAME (sp);
+ symbol_name = str;
+ pnt = str + strlen (str) - 1;
+ if (*pnt == '?') /* Continuation stab. */
+ {
+ symbolS *spnext;
+ int tlen = 0;
+
+ spnext = sp;
+ do {
+ tlen += strlen (str) - 1;
+ spnext = symbol_next (spnext);
+ str = S_GET_NAME (spnext);
+ pnt = str + strlen (str) - 1;
+ } while (*pnt == '?');
+ tlen += strlen (str);
+ parse_buffer = (char *) xmalloc (tlen + 1);
+ strcpy (parse_buffer, S_GET_NAME (sp));
+ pnt2 = parse_buffer + strlen (parse_buffer) - 1;
+ *pnt2 = '\0';
+ spnext = sp;
+ do {
+ spnext = symbol_next (spnext);
+ str = S_GET_NAME (spnext);
+ strcat (pnt2, str);
+ pnt2 += strlen (str) - 1;
+ *str = '\0'; /* Erase this string */
+ /* S_SET_NAME (spnext, str); */
+ if (*pnt2 != '?') break;
+ *pnt2 = '\0';
+ } while (1);
+ str = parse_buffer;
+ symbol_name = str;
+ }
+ if ((pnt = (char *) strchr (str, ':')) != 0)
+ {
+ *pnt = '\0';
+ pnt1 = pnt + 1;
+ if ((pnt2 = (char *) strchr (pnt1, '=')) != 0)
+ incomplete += VMS_typedef_parse (pnt2);
+ if (parse_buffer)
+ {
+ /* At this point the parse buffer should just
+ contain name:nn. If it does not, then we
+ are in real trouble. Anyway, this is always
+ shorter than the original line. */
+ pnt2 = S_GET_NAME (sp);
+ strcpy (pnt2, parse_buffer);
+ /* S_SET_NAME (sp, pnt2); */
+ free (parse_buffer), parse_buffer = 0;
+ }
+ *pnt = ':'; /* put back colon to restore dbx_type */
+ }
+ break;
+ } /*switch*/
+ } /* if */
+ } /*for*/
+ pass++;
+ /*
+ * Make one last pass, if needed, and define whatever we can
+ * that is left.
+ */
+ if (final_pass == 0 && incomplete == incom1)
+ {
+ final_pass = 1;
+ incom1++; /* Force one last pass through */
+ }
+ } while (incomplete != 0 && incomplete != incom1);
+ /* repeat until all refs resolved if possible */
+/* if (pass > 1) printf (" Required %d passes\n", pass); */
+ if (incomplete != 0)
+ {
+ as_tsktsk (_("debugger output: Unable to resolve %d circular references."),
+ incomplete);
+ }
+ fpnt = f_ref_root;
+ symbol_name = "\0";
+ while (fpnt)
+ {
+ if (fpnt->resolved != 'Y')
+ {
+ if (find_symbol (fpnt->dbx_type))
+ {
+ as_tsktsk (_("debugger forward reference error, dbx type %d"),
+ fpnt->dbx_type);
+ break;
+ }
+ fixit[0] = 0;
+ sprintf (&fixit[1], "%d=s4;", fpnt->dbx_type);
+ pnt2 = (char *) strchr (&fixit[1], '=');
+ VMS_typedef_parse (pnt2);
+ }
+ fpnt = fpnt->next;
+ }
+}
+
+
+static void
+Define_Local_Symbols (s0P, s2P, Current_Routine, Text_Psect)
+ symbolS *s0P, *s2P;
+ symbolS *Current_Routine;
+ int Text_Psect;
+{
+ symbolS *s1P; /* each symbol from s0P .. s2P (exclusive) */
+
+ for (s1P = symbol_next (s0P); s1P != s2P; s1P = symbol_next (s1P))
+ {
+ if (!s1P)
+ break; /* and return */
+ if (S_GET_RAW_TYPE (s1P) == N_FUN)
+ {
+ char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1;
+ if (*pnt == 'F' || *pnt == 'f') break;
+ }
+ if (!S_IS_DEBUG (s1P))
+ continue;
+ /*
+ * Dispatch on STAB type
+ */
+ switch (S_GET_RAW_TYPE (s1P))
+ {
+ default:
+ continue; /* not left or right brace */
+
+ case N_LSYM:
+ case N_PSYM:
+ VMS_local_stab_Parse (s1P);
+ break;
+
+ case N_RSYM:
+ VMS_RSYM_Parse (s1P, Current_Routine, Text_Psect);
+ break;
+ } /*switch*/
+ } /* for */
+}
+
+
+/* This function crawls the symbol chain searching for local symbols that
+ need to be described to the debugger. When we enter a new scope with
+ a "{", it creates a new "block", which helps the debugger keep track
+ of which scope we are currently in. */
+
+static symbolS *
+Define_Routine (s0P, Level, Current_Routine, Text_Psect)
+ symbolS *s0P;
+ int Level;
+ symbolS *Current_Routine;
+ int Text_Psect;
+{
+ symbolS *s1P;
+ valueT Offset;
+ int rcount = 0;
+
+ for (s1P = symbol_next (s0P); s1P != 0; s1P = symbol_next (s1P))
+ {
+ if (S_GET_RAW_TYPE (s1P) == N_FUN)
+ {
+ char *pnt = (char *) strchr (S_GET_NAME (s1P), ':') + 1;
+ if (*pnt == 'F' || *pnt == 'f') break;
+ }
+ if (!S_IS_DEBUG (s1P))
+ continue;
+ /*
+ * Dispatch on STAB type
+ */
+ switch (S_GET_RAW_TYPE (s1P))
+ {
+ default:
+ continue; /* not left or right brace */
+
+ case N_LBRAC:
+ if (Level != 0)
+ {
+ char str[10];
+ sprintf (str, "$%d", rcount++);
+ VMS_TBT_Block_Begin (s1P, Text_Psect, str);
+ }
+ Offset = S_GET_VALUE (s1P); /* side-effect: fully resolve symbol */
+ Define_Local_Symbols (s0P, s1P, Current_Routine, Text_Psect);
+ s1P = Define_Routine (s1P, Level + 1, Current_Routine, Text_Psect);
+ if (Level != 0)
+ VMS_TBT_Block_End (S_GET_VALUE (s1P) - Offset);
+ s0P = s1P;
+ break;
+
+ case N_RBRAC:
+ return s1P;
+ } /*switch*/
+ } /* for */
+
+ /* We end up here if there were no brackets in this function.
+ Define everything. */
+ Define_Local_Symbols (s0P, (symbolS *)0, Current_Routine, Text_Psect);
+ return s1P;
+}
+
+
+#ifndef VMS
+#include <sys/types.h>
+#include <time.h>
+static void get_VMS_time_on_unix PARAMS ((char *));
+
+/* Manufacture a VMS-like time string on a Unix based system. */
+static void
+get_VMS_time_on_unix (Now)
+ char *Now;
+{
+ char *pnt;
+ time_t timeb;
+
+ time (&timeb);
+ pnt = ctime (&timeb);
+ pnt[3] = 0;
+ pnt[7] = 0;
+ pnt[10] = 0;
+ pnt[16] = 0;
+ pnt[24] = 0;
+ sprintf (Now, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
+}
+#endif /* not VMS */
+
+
+/* Write the MHD (Module Header) records. */
+
+static void
+Write_VMS_MHD_Records ()
+{
+ register const char *cp;
+ register char *cp1;
+ register int i;
+#ifdef VMS
+ struct { unsigned short len, mbz; char *ptr; } Descriptor;
+#endif
+ char Now[17+1];
+
+ /* We are writing a module header record. */
+ Set_VMS_Object_File_Record (OBJ_S_C_HDR);
+ /*
+ * ***************************
+ * *MAIN MODULE HEADER RECORD*
+ * ***************************
+ */
+ /* Store record type and header type. */
+ PUT_CHAR (OBJ_S_C_HDR);
+ PUT_CHAR (MHD_S_C_MHD);
+ /* Structure level is 0. */
+ PUT_CHAR (OBJ_S_C_STRLVL);
+ /* Maximum record size is size of the object record buffer. */
+ PUT_SHORT (sizeof (Object_Record_Buffer));
+
+ /*
+ * FIXME: module name and version should be user
+ * specifiable via `.ident' and/or `#pragma ident'.
+ */
+
+ /* Get module name (the FILENAME part of the object file). */
+ cp = out_file_name;
+ cp1 = Module_Name;
+ while (*cp)
+ {
+ if (*cp == ']' || *cp == '>' || *cp == ':' || *cp == '/')
+ {
+ cp1 = Module_Name;
+ cp++;
+ continue;
+ }
+ *cp1++ = islower (*cp) ? toupper (*cp++) : *cp++;
+ }
+ *cp1 = '\0';
+
+ /* Limit it to 31 characters and store in the object record. */
+ while (--cp1 >= Module_Name)
+ if (*cp1 == '.')
+ *cp1 = '\0';
+ if (strlen (Module_Name) > 31)
+ {
+ if (flag_hash_long_names)
+ as_tsktsk (_("Module name truncated: %s\n"), Module_Name);
+ Module_Name[31] = '\0';
+ }
+ PUT_COUNTED_STRING (Module_Name);
+ /* Module Version is "V1.0". */
+ PUT_COUNTED_STRING ("V1.0");
+ /* Creation time is "now" (17 chars of time string): "dd-MMM-yyyy hh:mm". */
+#ifndef VMS
+ get_VMS_time_on_unix (Now);
+#else /* VMS */
+ Descriptor.len = sizeof Now - 1;
+ Descriptor.mbz = 0; /* type & class unspecified */
+ Descriptor.ptr = Now;
+ (void) sys$asctim ((unsigned short *)0, &Descriptor, (long *)0, 0);
+#endif /* VMS */
+ for (i = 0; i < 17; i++)
+ PUT_CHAR (Now[i]);
+ /* Patch time is "never" (17 zeros). */
+ for (i = 0; i < 17; i++)
+ PUT_CHAR (0);
+ /* Force this to be a separate output record. */
+ Flush_VMS_Object_Record_Buffer ();
+
+ /*
+ * *************************
+ * *LANGUAGE PROCESSOR NAME*
+ * *************************
+ */
+ /* Store record type and header type. */
+ PUT_CHAR (OBJ_S_C_HDR);
+ PUT_CHAR (MHD_S_C_LNM);
+ /*
+ * Store language processor name and version (not a counted string!).
+ *
+ * This is normally supplied by the gcc driver for the command line
+ * which invokes gas. If absent, we fall back to gas's version.
+ */
+ cp = compiler_version_string;
+ if (cp == 0)
+ {
+ cp = "GNU AS V";
+ while (*cp)
+ PUT_CHAR (*cp++);
+ cp = VERSION;
+ }
+ while (*cp >= ' ')
+ PUT_CHAR (*cp++);
+ /* Force this to be a separate output record. */
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/* Write the EOM (End Of Module) record. */
+
+static void
+Write_VMS_EOM_Record (Psect, Offset)
+ int Psect;
+ valueT Offset;
+{
+ /*
+ * We are writing an end-of-module record
+ * (this assumes that the entry point will always be in a psect
+ * represented by a single byte, which is the case for code in
+ * Text_Psect==0)
+ */
+ Set_VMS_Object_File_Record (OBJ_S_C_EOM);
+ PUT_CHAR (OBJ_S_C_EOM); /* Record type. */
+ PUT_CHAR (0); /* Error severity level (we ignore it). */
+ /*
+ * Store the entry point, if it exists
+ */
+ if (Psect >= 0)
+ {
+ PUT_CHAR (Psect);
+ PUT_LONG (Offset);
+ }
+ /* Flush the record; this will be our final output. */
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
+
+static int
+hash_string (ptr)
+ const char *ptr;
+{
+ register const unsigned char *p = (unsigned char *) ptr;
+ register const unsigned char *end = p + strlen (ptr);
+ register unsigned char c;
+ register int hash = 0;
+
+ while (p != end)
+ {
+ c = *p++;
+ hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
+ }
+ return hash;
+}
+
+/*
+ * Generate a Case-Hacked VMS symbol name (limited to 31 chars)
+ */
+static void
+VMS_Case_Hack_Symbol (In, Out)
+ register const char *In;
+ register char *Out;
+{
+ long int init;
+ long int result;
+ char *pnt = 0;
+ char *new_name;
+ const char *old_name;
+ register int i;
+ int destructor = 0; /*hack to allow for case sens in a destructor*/
+ int truncate = 0;
+ int Case_Hack_Bits = 0;
+ int Saw_Dollar = 0;
+ static char Hex_Table[16] =
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+ /*
+ * Kill any leading "_"
+ */
+ if ((In[0] == '_') && ((In[1] > '9') || (In[1] < '0')))
+ In++;
+
+ new_name = Out; /* save this for later*/
+
+#if barfoo /* Dead code */
+ if ((In[0] == '_') && (In[1] == '$') && (In[2] == '_'))
+ destructor = 1;
+#endif
+
+ /* We may need to truncate the symbol, save the hash for later*/
+ result = (strlen (In) > 23) ? hash_string (In) : 0;
+ /*
+ * Is there a Psect Attribute to skip??
+ */
+ if (HAS_PSECT_ATTRIBUTES (In))
+ {
+ /*
+ * Yes: Skip it
+ */
+ In += PSECT_ATTRIBUTES_STRING_LENGTH;
+ while (*In)
+ {
+ if ((In[0] == '$') && (In[1] == '$'))
+ {
+ In += 2;
+ break;
+ }
+ In++;
+ }
+ }
+
+ old_name = In;
+/* if (strlen (In) > 31 && flag_hash_long_names)
+ as_tsktsk ("Symbol name truncated: %s\n", In); */
+ /*
+ * Do the case conversion
+ */
+ i = 23; /* Maximum of 23 chars */
+ while (*In && (--i >= 0))
+ {
+ Case_Hack_Bits <<= 1;
+ if (*In == '$')
+ Saw_Dollar = 1;
+ if ((destructor == 1) && (i == 21))
+ Saw_Dollar = 0;
+ switch (vms_name_mapping)
+ {
+ case 0:
+ if (isupper (*In)) {
+ *Out++ = *In++;
+ Case_Hack_Bits |= 1;
+ } else {
+ *Out++ = islower (*In) ? toupper (*In++) : *In++;
+ }
+ break;
+ case 3: *Out++ = *In++;
+ break;
+ case 2:
+ if (islower (*In)) {
+ *Out++ = *In++;
+ } else {
+ *Out++ = isupper (*In) ? tolower (*In++) : *In++;
+ }
+ break;
+ }
+ }
+ /*
+ * If we saw a dollar sign, we don't do case hacking
+ */
+ if (flag_no_hash_mixed_case || Saw_Dollar)
+ Case_Hack_Bits = 0;
+
+ /*
+ * If we have more than 23 characters and everything is lowercase
+ * we can insert the full 31 characters
+ */
+ if (*In)
+ {
+ /*
+ * We have more than 23 characters
+ * If we must add the case hack, then we have truncated the str
+ */
+ pnt = Out;
+ truncate = 1;
+ if (Case_Hack_Bits == 0)
+ {
+ /*
+ * And so far they are all lower case:
+ * Check up to 8 more characters
+ * and ensure that they are lowercase
+ */
+ for (i = 0; (In[i] != 0) && (i < 8); i++)
+ if (isupper (In[i]) && !Saw_Dollar && !flag_no_hash_mixed_case)
+ break;
+
+ if (In[i] == 0)
+ truncate = 0;
+
+ if ((i == 8) || (In[i] == 0))
+ {
+ /*
+ * They are: Copy up to 31 characters
+ * to the output string
+ */
+ i = 8;
+ while ((--i >= 0) && (*In))
+ switch (vms_name_mapping){
+ case 0: *Out++ = islower (*In) ? toupper (*In++) : *In++;
+ break;
+ case 3: *Out++ = *In++;
+ break;
+ case 2: *Out++ = isupper (*In) ? tolower (*In++) : *In++;
+ break;
+ }
+ }
+ }
+ }
+ /*
+ * If there were any uppercase characters in the name we
+ * take on the case hacking string
+ */
+
+ /* Old behavior for regular GNU-C compiler */
+ if (!flag_hash_long_names)
+ truncate = 0;
+ if ((Case_Hack_Bits != 0) || (truncate == 1))
+ {
+ if (truncate == 0)
+ {
+ *Out++ = '_';
+ for (i = 0; i < 6; i++)
+ {
+ *Out++ = Hex_Table[Case_Hack_Bits & 0xf];
+ Case_Hack_Bits >>= 4;
+ }
+ *Out++ = 'X';
+ }
+ else
+ {
+ Out = pnt; /*Cut back to 23 characters maximum */
+ *Out++ = '_';
+ for (i = 0; i < 7; i++)
+ {
+ init = result & 0x01f;
+ *Out++ = (init < 10) ? ('0' + init) : ('A' + init - 10);
+ result = result >> 5;
+ }
+ }
+ } /*Case Hack */
+ /*
+ * Done
+ */
+ *Out = 0;
+ if (truncate == 1 && flag_hash_long_names && flag_show_after_trunc)
+ as_tsktsk (_("Symbol %s replaced by %s\n"), old_name, new_name);
+}
+
+
+/*
+ * Scan a symbol name for a psect attribute specification
+ */
+#define GLOBALSYMBOL_BIT 0x10000
+#define GLOBALVALUE_BIT 0x20000
+
+
+static void
+VMS_Modify_Psect_Attributes (Name, Attribute_Pointer)
+ const char *Name;
+ int *Attribute_Pointer;
+{
+ register int i;
+ register const char *cp;
+ int Negate;
+ static const struct
+ {
+ const char *Name;
+ int Value;
+ } Attributes[] =
+ {
+ {"PIC", GPS_S_M_PIC},
+ {"LIB", GPS_S_M_LIB},
+ {"OVR", GPS_S_M_OVR},
+ {"REL", GPS_S_M_REL},
+ {"GBL", GPS_S_M_GBL},
+ {"SHR", GPS_S_M_SHR},
+ {"EXE", GPS_S_M_EXE},
+ {"RD", GPS_S_M_RD},
+ {"WRT", GPS_S_M_WRT},
+ {"VEC", GPS_S_M_VEC},
+ {"GLOBALSYMBOL", GLOBALSYMBOL_BIT},
+ {"GLOBALVALUE", GLOBALVALUE_BIT},
+ {0, 0}
+ };
+
+ /*
+ * Kill leading "_"
+ */
+ if (*Name == '_')
+ Name++;
+ /*
+ * Check for a PSECT attribute list
+ */
+ if (!HAS_PSECT_ATTRIBUTES (Name))
+ return; /* If not, return */
+ /*
+ * Skip the attribute list indicator
+ */
+ Name += PSECT_ATTRIBUTES_STRING_LENGTH;
+ /*
+ * Process the attributes ("_" separated, "$" terminated)
+ */
+ while (*Name != '$')
+ {
+ /*
+ * Assume not negating
+ */
+ Negate = 0;
+ /*
+ * Check for "NO"
+ */
+ if ((Name[0] == 'N') && (Name[1] == 'O'))
+ {
+ /*
+ * We are negating (and skip the NO)
+ */
+ Negate = 1;
+ Name += 2;
+ }
+ /*
+ * Find the token delimiter
+ */
+ cp = Name;
+ while (*cp && (*cp != '_') && (*cp != '$'))
+ cp++;
+ /*
+ * Look for the token in the attribute list
+ */
+ for (i = 0; Attributes[i].Name; i++)
+ {
+ /*
+ * If the strings match, set/clear the attr.
+ */
+ if (strncmp (Name, Attributes[i].Name, cp - Name) == 0)
+ {
+ /*
+ * Set or clear
+ */
+ if (Negate)
+ *Attribute_Pointer &=
+ ~Attributes[i].Value;
+ else
+ *Attribute_Pointer |=
+ Attributes[i].Value;
+ /*
+ * Done
+ */
+ break;
+ }
+ }
+ /*
+ * Now skip the attribute
+ */
+ Name = cp;
+ if (*Name == '_')
+ Name++;
+ }
+}
+
+
+#define GBLSYM_REF 0
+#define GBLSYM_DEF 1
+#define GBLSYM_VAL 2
+#define GBLSYM_LCL 4 /* not GBL after all... */
+#define GBLSYM_WEAK 8
+
+/*
+ * Define a global symbol (or possibly a local one).
+ */
+static void
+VMS_Global_Symbol_Spec (Name, Psect_Number, Psect_Offset, Flags)
+ const char *Name;
+ int Psect_Number;
+ int Psect_Offset;
+ int Flags;
+{
+ char Local[32];
+
+ /*
+ * We are writing a GSD record
+ */
+ Set_VMS_Object_File_Record (OBJ_S_C_GSD);
+ /*
+ * If the buffer is empty we must insert the GSD record type
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_GSD);
+ /*
+ * We are writing a Global (or local) symbol definition subrecord.
+ */
+ PUT_CHAR ((Flags & GBLSYM_LCL) != 0 ? GSD_S_C_LSY :
+ ((unsigned) Psect_Number <= 255) ? GSD_S_C_SYM : GSD_S_C_SYMW);
+ /*
+ * Data type is undefined
+ */
+ PUT_CHAR (0);
+ /*
+ * Switch on Definition/Reference
+ */
+ if ((Flags & GBLSYM_DEF) == 0)
+ {
+ /*
+ * Reference
+ */
+ PUT_SHORT (((Flags & GBLSYM_VAL) == 0) ? GSY_S_M_REL : 0);
+ if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
+ PUT_SHORT (Current_Environment);
+ }
+ else
+ {
+ int sym_flags;
+
+ /*
+ * Definition
+ *[ assert (LSY_S_M_DEF == GSY_S_M_DEF && LSY_S_M_REL == GSY_S_M_REL); ]
+ */
+ sym_flags = GSY_S_M_DEF;
+ if (Flags & GBLSYM_WEAK)
+ sym_flags |= GSY_S_M_WEAK;
+ if ((Flags & GBLSYM_VAL) == 0)
+ sym_flags |= GSY_S_M_REL;
+ PUT_SHORT (sym_flags);
+ if ((Flags & GBLSYM_LCL) != 0) /* local symbols have extra field */
+ PUT_SHORT (Current_Environment);
+ /*
+ * Psect Number
+ */
+ if ((Flags & GBLSYM_LCL) == 0 && (unsigned) Psect_Number <= 255)
+ PUT_CHAR (Psect_Number);
+ else
+ PUT_SHORT (Psect_Number);
+ /*
+ * Offset
+ */
+ PUT_LONG (Psect_Offset);
+ }
+ /*
+ * Finally, the global symbol name
+ */
+ VMS_Case_Hack_Symbol (Name, Local);
+ PUT_COUNTED_STRING (Local);
+ /*
+ * Flush the buffer if it is more than 75% full
+ */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+/*
+ * Define an environment to support local symbol references.
+ * This is just to mollify the linker; we don't actually do
+ * anything useful with it.
+ */
+static void
+VMS_Local_Environment_Setup (Env_Name)
+ const char *Env_Name;
+{
+ /* We are writing a GSD record. */
+ Set_VMS_Object_File_Record (OBJ_S_C_GSD);
+ /* If the buffer is empty we must insert the GSD record type. */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_GSD);
+ /* We are writing an ENV subrecord. */
+ PUT_CHAR (GSD_S_C_ENV);
+
+ ++Current_Environment; /* index of environment being defined */
+
+ /* ENV$W_FLAGS: we are defining the next environment. It's not nested. */
+ PUT_SHORT (ENV_S_M_DEF);
+ /* ENV$W_ENVINDX: index is always 0 for non-nested definitions. */
+ PUT_SHORT (0);
+
+ /* ENV$B_NAMLNG + ENV$T_NAME: environment name in ASCIC format. */
+ if (!Env_Name) Env_Name = "";
+ PUT_COUNTED_STRING ((char *)Env_Name);
+
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/*
+ * Define a psect
+ */
+static int
+VMS_Psect_Spec (Name, Size, Type, vsp)
+ const char *Name;
+ int Size;
+ enum ps_type Type;
+ struct VMS_Symbol *vsp;
+{
+ char Local[32];
+ int Psect_Attributes;
+
+ /*
+ * Generate the appropriate PSECT flags given the PSECT type
+ */
+ switch (Type)
+ {
+ case ps_TEXT:
+ /* Text psects are PIC,noOVR,REL,noGBL,SHR,EXE,RD,noWRT. */
+ Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE
+ |GPS_S_M_RD);
+ break;
+ case ps_DATA:
+ /* Data psects are PIC,noOVR,REL,noGBL,noSHR,noEXE,RD,WRT. */
+ Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT);
+ break;
+ case ps_COMMON:
+ /* Common block psects are: PIC,OVR,REL,GBL,noSHR,noEXE,RD,WRT. */
+ Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL
+ |GPS_S_M_RD|GPS_S_M_WRT);
+ break;
+ case ps_CONST:
+ /* Const data psects are: PIC,OVR,REL,GBL,noSHR,noEXE,RD,noWRT. */
+ Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL
+ |GPS_S_M_RD);
+ break;
+ case ps_CTORS:
+ /* Ctor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT. */
+ Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD);
+ break;
+ case ps_DTORS:
+ /* Dtor psects are PIC,noOVR,REL,GBL,noSHR,noEXE,RD,noWRT. */
+ Psect_Attributes = (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD);
+ break;
+ default:
+ /* impossible */
+ error (_("Unknown VMS psect type (%ld)"), (long) Type);
+ break;
+ }
+ /*
+ * Modify the psect attributes according to any attribute string
+ */
+ if (vsp && S_GET_TYPE (vsp->Symbol) == N_ABS)
+ Psect_Attributes |= GLOBALVALUE_BIT;
+ else if (HAS_PSECT_ATTRIBUTES (Name))
+ VMS_Modify_Psect_Attributes (Name, &Psect_Attributes);
+ /*
+ * Check for globalref/def/val.
+ */
+ if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
+ {
+ /*
+ * globalvalue symbols were generated before. This code
+ * prevents unsightly psect buildup, and makes sure that
+ * fixup references are emitted correctly.
+ */
+ vsp->Psect_Index = -1; /* to catch errors */
+ S_SET_TYPE (vsp->Symbol, N_UNDF); /* make refs work */
+ return 1; /* decrement psect counter */
+ }
+
+ if ((Psect_Attributes & GLOBALSYMBOL_BIT) != 0)
+ {
+ switch (S_GET_RAW_TYPE (vsp->Symbol))
+ {
+ case N_UNDF | N_EXT:
+ VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
+ vsp->Psect_Offset, GBLSYM_REF);
+ vsp->Psect_Index = -1;
+ S_SET_TYPE (vsp->Symbol, N_UNDF);
+ return 1; /* return and indicate no psect */
+ case N_DATA | N_EXT:
+ VMS_Global_Symbol_Spec (Name, vsp->Psect_Index,
+ vsp->Psect_Offset, GBLSYM_DEF);
+ /* In this case we still generate the psect */
+ break;
+ default:
+ as_fatal (_("Globalsymbol attribute for symbol %s was unexpected."),
+ Name);
+ break;
+ } /* switch */
+ }
+
+ Psect_Attributes &= 0xffff; /* clear out the globalref/def stuff */
+ /*
+ * We are writing a GSD record
+ */
+ Set_VMS_Object_File_Record (OBJ_S_C_GSD);
+ /*
+ * If the buffer is empty we must insert the GSD record type
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_GSD);
+ /*
+ * We are writing a PSECT definition subrecord
+ */
+ PUT_CHAR (GSD_S_C_PSC);
+ /*
+ * Psects are always LONGWORD aligned
+ */
+ PUT_CHAR (2);
+ /*
+ * Specify the psect attributes
+ */
+ PUT_SHORT (Psect_Attributes);
+ /*
+ * Specify the allocation
+ */
+ PUT_LONG (Size);
+ /*
+ * Finally, the psect name
+ */
+ VMS_Case_Hack_Symbol (Name, Local);
+ PUT_COUNTED_STRING (Local);
+ /*
+ * Flush the buffer if it is more than 75% full
+ */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+ return 0;
+}
+
+
+/* Given the pointer to a symbol we calculate how big the data at the
+ symbol is. We do this by looking for the next symbol (local or global)
+ which will indicate the start of another datum. */
+
+static offsetT
+VMS_Initialized_Data_Size (s0P, End_Of_Data)
+ register symbolS *s0P;
+ unsigned End_Of_Data;
+{
+ symbolS *s1P;
+ valueT s0P_val = S_GET_VALUE (s0P), s1P_val,
+ nearest_val = (valueT) End_Of_Data;
+
+ /* Find the nearest symbol what follows this one. */
+ for (s1P = symbol_rootP; s1P; s1P = symbol_next (s1P))
+ {
+ /* The data type must match. */
+ if (S_GET_TYPE (s1P) != N_DATA)
+ continue;
+ s1P_val = S_GET_VALUE (s1P);
+ if (s1P_val > s0P_val && s1P_val < nearest_val)
+ nearest_val = s1P_val;
+ }
+ /* Calculate its size. */
+ return (offsetT) (nearest_val - s0P_val);
+}
+
+
+/* Check symbol names for the Psect hack with a globalvalue, and then
+ generate globalvalues for those that have it. */
+
+static void
+VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment)
+ unsigned text_siz;
+ unsigned data_siz;
+ char *Data_Segment;
+{
+ register symbolS *sp;
+ char *stripped_name, *Name;
+ int Size;
+ int Psect_Attributes;
+ int globalvalue;
+ int typ, abstyp;
+
+ /*
+ * Scan the symbol table for globalvalues, and emit def/ref when
+ * required. These will be caught again later and converted to
+ * N_UNDF
+ */
+ for (sp = symbol_rootP; sp; sp = sp->sy_next)
+ {
+ typ = S_GET_RAW_TYPE (sp);
+ abstyp = ((typ & ~N_EXT) == N_ABS);
+ /*
+ * See if this is something we want to look at.
+ */
+ if (!abstyp &&
+ typ != (N_DATA | N_EXT) &&
+ typ != (N_UNDF | N_EXT))
+ continue;
+ /*
+ * See if this has globalvalue specification.
+ */
+ Name = S_GET_NAME (sp);
+
+ if (abstyp)
+ {
+ stripped_name = 0;
+ Psect_Attributes = GLOBALVALUE_BIT;
+ }
+ else if (HAS_PSECT_ATTRIBUTES (Name))
+ {
+ stripped_name = (char *) xmalloc (strlen (Name) + 1);
+ strcpy (stripped_name, Name);
+ Psect_Attributes = 0;
+ VMS_Modify_Psect_Attributes (stripped_name, &Psect_Attributes);
+ }
+ else
+ continue;
+
+ if ((Psect_Attributes & GLOBALVALUE_BIT) != 0)
+ {
+ switch (typ)
+ {
+ case N_ABS:
+ /* Local symbol references will want
+ to have an environment defined. */
+ if (Current_Environment < 0)
+ VMS_Local_Environment_Setup (".N_ABS");
+ VMS_Global_Symbol_Spec (Name, 0,
+ S_GET_VALUE (sp),
+ GBLSYM_DEF|GBLSYM_VAL|GBLSYM_LCL);
+ break;
+ case N_ABS | N_EXT:
+ VMS_Global_Symbol_Spec (Name, 0,
+ S_GET_VALUE (sp),
+ GBLSYM_DEF|GBLSYM_VAL);
+ break;
+ case N_UNDF | N_EXT:
+ VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
+ break;
+ case N_DATA | N_EXT:
+ Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
+ if (Size > 4)
+ error (_("Invalid data type for globalvalue"));
+ globalvalue = md_chars_to_number (Data_Segment +
+ S_GET_VALUE (sp) - text_siz , Size);
+ /* Three times for good luck. The linker seems to get confused
+ if there are fewer than three */
+ VMS_Global_Symbol_Spec (stripped_name, 0, 0, GBLSYM_VAL);
+ VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
+ GBLSYM_DEF|GBLSYM_VAL);
+ VMS_Global_Symbol_Spec (stripped_name, 0, globalvalue,
+ GBLSYM_DEF|GBLSYM_VAL);
+ break;
+ default:
+ as_warn (_("Invalid globalvalue of %s"), stripped_name);
+ break;
+ } /* switch */
+ } /* if */
+ if (stripped_name) free (stripped_name); /* clean up */
+ } /* for */
+
+}
+
+
+/*
+ * Define a procedure entry pt/mask
+ */
+static void
+VMS_Procedure_Entry_Pt (Name, Psect_Number, Psect_Offset, Entry_Mask)
+ char *Name;
+ int Psect_Number;
+ int Psect_Offset;
+ int Entry_Mask;
+{
+ char Local[32];
+
+ /*
+ * We are writing a GSD record
+ */
+ Set_VMS_Object_File_Record (OBJ_S_C_GSD);
+ /*
+ * If the buffer is empty we must insert the GSD record type
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (OBJ_S_C_GSD);
+ /*
+ * We are writing a Procedure Entry Pt/Mask subrecord
+ */
+ PUT_CHAR (((unsigned) Psect_Number <= 255) ? GSD_S_C_EPM : GSD_S_C_EPMW);
+ /*
+ * Data type is undefined
+ */
+ PUT_CHAR (0);
+ /*
+ * Flags = "RELOCATABLE" and "DEFINED"
+ */
+ PUT_SHORT (GSY_S_M_DEF | GSY_S_M_REL);
+ /*
+ * Psect Number
+ */
+ if ((unsigned) Psect_Number <= 255)
+ PUT_CHAR (Psect_Number);
+ else
+ PUT_SHORT (Psect_Number);
+ /*
+ * Offset
+ */
+ PUT_LONG (Psect_Offset);
+ /*
+ * Entry mask
+ */
+ PUT_SHORT (Entry_Mask);
+ /*
+ * Finally, the global symbol name
+ */
+ VMS_Case_Hack_Symbol (Name, Local);
+ PUT_COUNTED_STRING (Local);
+ /*
+ * Flush the buffer if it is more than 75% full
+ */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/*
+ * Set the current location counter to a particular Psect and Offset
+ */
+static void
+VMS_Set_Psect (Psect_Index, Offset, Record_Type)
+ int Psect_Index;
+ int Offset;
+ int Record_Type;
+{
+ /*
+ * We are writing a "Record_Type" record
+ */
+ Set_VMS_Object_File_Record (Record_Type);
+ /*
+ * If the buffer is empty we must insert the record type
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (Record_Type);
+ /*
+ * Stack the Psect base + Offset
+ */
+ vms_tir_stack_psect (Psect_Index, Offset, 0);
+ /*
+ * Set relocation base
+ */
+ PUT_CHAR (TIR_S_C_CTL_SETRB);
+ /*
+ * Flush the buffer if it is more than 75% full
+ */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/*
+ * Store repeated immediate data in current Psect
+ */
+static void
+VMS_Store_Repeated_Data (Repeat_Count, Pointer, Size, Record_Type)
+ int Repeat_Count;
+ register char *Pointer;
+ int Size;
+ int Record_Type;
+{
+
+ /*
+ * Ignore zero bytes/words/longwords
+ */
+ switch (Size)
+ {
+ case 4:
+ if (Pointer[3] != 0 || Pointer[2] != 0) break;
+ /* else FALLTHRU */
+ case 2:
+ if (Pointer[1] != 0) break;
+ /* else FALLTHRU */
+ case 1:
+ if (Pointer[0] != 0) break;
+ /* zero value */
+ return;
+ default:
+ break;
+ }
+ /*
+ * If the data is too big for a TIR_S_C_STO_RIVB sub-record
+ * then we do it manually
+ */
+ if (Size > 255)
+ {
+ while (--Repeat_Count >= 0)
+ VMS_Store_Immediate_Data (Pointer, Size, Record_Type);
+ return;
+ }
+ /*
+ * We are writing a "Record_Type" record
+ */
+ Set_VMS_Object_File_Record (Record_Type);
+ /*
+ * If the buffer is empty we must insert record type
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (Record_Type);
+ /*
+ * Stack the repeat count
+ */
+ PUT_CHAR (TIR_S_C_STA_LW);
+ PUT_LONG (Repeat_Count);
+ /*
+ * And now the command and its data
+ */
+ PUT_CHAR (TIR_S_C_STO_RIVB);
+ PUT_CHAR (Size);
+ while (--Size >= 0)
+ PUT_CHAR (*Pointer++);
+ /*
+ * Flush the buffer if it is more than 75% full
+ */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/*
+ * Store a Position Independent Reference
+ */
+static void
+VMS_Store_PIC_Symbol_Reference (Symbol, Offset, PC_Relative,
+ Psect, Psect_Offset, Record_Type)
+ symbolS *Symbol;
+ int Offset;
+ int PC_Relative;
+ int Psect;
+ int Psect_Offset;
+ int Record_Type;
+{
+ register struct VMS_Symbol *vsp = Symbol->sy_obj;
+ char Local[32];
+ int local_sym = 0;
+
+ /*
+ * We are writing a "Record_Type" record
+ */
+ Set_VMS_Object_File_Record (Record_Type);
+ /*
+ * If the buffer is empty we must insert record type
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (Record_Type);
+ /*
+ * Set to the appropriate offset in the Psect.
+ * For a Code reference we need to fix the operand
+ * specifier as well, so back up 1 byte;
+ * for a Data reference we just store HERE.
+ */
+ VMS_Set_Psect (Psect,
+ PC_Relative ? Psect_Offset - 1 : Psect_Offset,
+ Record_Type);
+ /*
+ * Make sure we are still generating a "Record Type" record
+ */
+ if (Object_Record_Offset == 0)
+ PUT_CHAR (Record_Type);
+ /*
+ * Dispatch on symbol type (so we can stack its value)
+ */
+ switch (S_GET_RAW_TYPE (Symbol))
+ {
+ /*
+ * Global symbol
+ */
+ case N_ABS:
+ local_sym = 1;
+ /*FALLTHRU*/
+ case N_ABS | N_EXT:
+#ifdef NOT_VAX_11_C_COMPATIBLE
+ case N_UNDF | N_EXT:
+ case N_DATA | N_EXT:
+#endif /* NOT_VAX_11_C_COMPATIBLE */
+ case N_UNDF:
+ case N_TEXT | N_EXT:
+ /*
+ * Get the symbol name (case hacked)
+ */
+ VMS_Case_Hack_Symbol (S_GET_NAME (Symbol), Local);
+ /*
+ * Stack the global symbol value
+ */
+ if (!local_sym)
+ {
+ PUT_CHAR (TIR_S_C_STA_GBL);
+ }
+ else
+ {
+ /* Local symbols have an extra field. */
+ PUT_CHAR (TIR_S_C_STA_LSY);
+ PUT_SHORT (Current_Environment);
+ }
+ PUT_COUNTED_STRING (Local);
+ if (Offset)
+ {
+ /*
+ * Stack the longword offset
+ */
+ PUT_CHAR (TIR_S_C_STA_LW);
+ PUT_LONG (Offset);
+ /*
+ * Add the two, leaving the result on the stack
+ */
+ PUT_CHAR (TIR_S_C_OPR_ADD);
+ }
+ break;
+ /*
+ * Uninitialized local data
+ */
+ case N_BSS:
+ /*
+ * Stack the Psect (+offset)
+ */
+ vms_tir_stack_psect (vsp->Psect_Index,
+ vsp->Psect_Offset + Offset,
+ 0);
+ break;
+ /*
+ * Local text
+ */
+ case N_TEXT:
+ /*
+ * Stack the Psect (+offset)
+ */
+ vms_tir_stack_psect (vsp->Psect_Index,
+ S_GET_VALUE (Symbol) + Offset,
+ 0);
+ break;
+ /*
+ * Initialized local or global data
+ */
+ case N_DATA:
+#ifndef NOT_VAX_11_C_COMPATIBLE
+ case N_UNDF | N_EXT:
+ case N_DATA | N_EXT:
+#endif /* NOT_VAX_11_C_COMPATIBLE */
+ /*
+ * Stack the Psect (+offset)
+ */
+ vms_tir_stack_psect (vsp->Psect_Index,
+ vsp->Psect_Offset + Offset,
+ 0);
+ break;
+ }
+ /*
+ * Store either a code or data reference
+ */
+ PUT_CHAR (PC_Relative ? TIR_S_C_STO_PICR : TIR_S_C_STO_PIDR);
+ /*
+ * Flush the buffer if it is more than 75% full
+ */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+}
+
+
+/*
+ * Check in the text area for an indirect pc-relative reference
+ * and fix it up with addressing mode 0xff [PC indirect]
+ *
+ * THIS SHOULD BE REPLACED BY THE USE OF TIR_S_C_STO_PIRR IN THE
+ * PIC CODE GENERATING FIXUP ROUTINE.
+ */
+static void
+VMS_Fix_Indirect_Reference (Text_Psect, Offset, fragP, text_frag_root)
+ int Text_Psect;
+ int Offset;
+ register fragS *fragP;
+ fragS *text_frag_root;
+{
+ /*
+ * The addressing mode byte is 1 byte before the address
+ */
+ Offset--;
+ /*
+ * Is it in THIS frag??
+ */
+ if ((Offset < fragP->fr_address) ||
+ (Offset >= (fragP->fr_address + fragP->fr_fix)))
+ {
+ /*
+ * We need to search for the fragment containing this
+ * Offset
+ */
+ for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ if ((Offset >= fragP->fr_address) &&
+ (Offset < (fragP->fr_address + fragP->fr_fix)))
+ break;
+ }
+ /*
+ * If we couldn't find the frag, things are BAD!!
+ */
+ if (fragP == 0)
+ error (_("Couldn't find fixup fragment when checking for indirect reference"));
+ }
+ /*
+ * Check for indirect PC relative addressing mode
+ */
+ if (fragP->fr_literal[Offset - fragP->fr_address] == (char) 0xff)
+ {
+ static char Address_Mode = (char) 0xff;
+
+ /*
+ * Yes: Store the indirect mode back into the image
+ * to fix up the damage done by STO_PICR
+ */
+ VMS_Set_Psect (Text_Psect, Offset, OBJ_S_C_TIR);
+ VMS_Store_Immediate_Data (&Address_Mode, 1, OBJ_S_C_TIR);
+ }
+}
+
+
+/*
+ * If the procedure "main()" exists we have to add the instruction
+ * "jsb c$main_args" at the beginning to be compatible with VAX-11 "C".
+ *
+ * FIXME: the macro name `HACK_DEC_C_STARTUP' should be renamed
+ * to `HACK_VAXCRTL_STARTUP' because Digital's compiler
+ * named "DEC C" uses run-time library "DECC$SHR", but this
+ * startup code is for "VAXCRTL", the library for Digital's
+ * older "VAX C". Also, this extra code isn't needed for
+ * supporting gcc because it already generates the VAXCRTL
+ * startup call when compiling main(). The reference to
+ * `flag_hash_long_names' looks very suspicious too;
+ * probably an old-style command line option was inadvertently
+ * overloaded here, then blindly converted into the new one.
+ */
+void
+vms_check_for_main ()
+{
+ register symbolS *symbolP;
+#ifdef HACK_DEC_C_STARTUP /* JF */
+ register struct frchain *frchainP;
+ register fragS *fragP;
+ register fragS **prev_fragPP;
+ register struct fix *fixP;
+ register fragS *New_Frag;
+ int i;
+#endif /* HACK_DEC_C_STARTUP */
+
+ symbolP = (symbolS *) symbol_find ("_main");
+ if (symbolP && !S_IS_DEBUG (symbolP) &&
+ S_IS_EXTERNAL (symbolP) && (S_GET_TYPE (symbolP) == N_TEXT))
+ {
+#ifdef HACK_DEC_C_STARTUP
+ if (!flag_hash_long_names)
+ {
+#endif
+ /*
+ * Remember the entry point symbol
+ */
+ Entry_Point_Symbol = symbolP;
+#ifdef HACK_DEC_C_STARTUP
+ }
+ else
+ {
+ /*
+ * Scan all the fragment chains for the one with "_main"
+ * (Actually we know the fragment from the symbol, but we need
+ * the previous fragment so we can change its pointer)
+ */
+ frchainP = frchain_root;
+ while (frchainP)
+ {
+ /*
+ * Scan all the fragments in this chain, remembering
+ * the "previous fragment"
+ */
+ prev_fragPP = &frchainP->frch_root;
+ fragP = frchainP->frch_root;
+ while (fragP && (fragP != frchainP->frch_last))
+ {
+ /*
+ * Is this the fragment?
+ */
+ if (fragP == symbolP->sy_frag)
+ {
+ /*
+ * Yes: Modify the fragment by replacing
+ * it with a new fragment.
+ */
+ New_Frag = (fragS *)
+ xmalloc (sizeof (*New_Frag) +
+ fragP->fr_fix +
+ fragP->fr_var +
+ 5);
+ /*
+ * The fragments are the same except
+ * that the "fixed" area is larger
+ */
+ *New_Frag = *fragP;
+ New_Frag->fr_fix += 6;
+ /*
+ * Copy the literal data opening a hole
+ * 2 bytes after "_main" (i.e. just after
+ * the entry mask). Into which we place
+ * the JSB instruction.
+ */
+ New_Frag->fr_literal[0] = fragP->fr_literal[0];
+ New_Frag->fr_literal[1] = fragP->fr_literal[1];
+ New_Frag->fr_literal[2] = 0x16; /* Jsb */
+ New_Frag->fr_literal[3] = 0xef;
+ New_Frag->fr_literal[4] = 0;
+ New_Frag->fr_literal[5] = 0;
+ New_Frag->fr_literal[6] = 0;
+ New_Frag->fr_literal[7] = 0;
+ for (i = 2; i < fragP->fr_fix + fragP->fr_var; i++)
+ New_Frag->fr_literal[i + 6] =
+ fragP->fr_literal[i];
+ /*
+ * Now replace the old fragment with the
+ * newly generated one.
+ */
+ *prev_fragPP = New_Frag;
+ /*
+ * Remember the entry point symbol
+ */
+ Entry_Point_Symbol = symbolP;
+ /*
+ * Scan the text area fixup structures
+ * as offsets in the fragment may have
+ * changed
+ */
+ for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
+ {
+ /*
+ * Look for references to this
+ * fragment.
+ */
+ if (fixP->fx_frag == fragP)
+ {
+ /*
+ * Change the fragment
+ * pointer
+ */
+ fixP->fx_frag = New_Frag;
+ /*
+ * If the offset is after
+ * the entry mask we need
+ * to account for the JSB
+ * instruction we just
+ * inserted.
+ */
+ if (fixP->fx_where >= 2)
+ fixP->fx_where += 6;
+ }
+ }
+ /*
+ * Scan the symbols as offsets in the
+ * fragment may have changed
+ */
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbol_next (symbolP))
+ {
+ /*
+ * Look for references to this
+ * fragment.
+ */
+ if (symbolP->sy_frag == fragP)
+ {
+ /*
+ * Change the fragment
+ * pointer
+ */
+ symbolP->sy_frag = New_Frag;
+ /*
+ * If the offset is after
+ * the entry mask we need
+ * to account for the JSB
+ * instruction we just
+ * inserted.
+ */
+ if (S_GET_VALUE (symbolP) >= 2)
+ S_SET_VALUE (symbolP,
+ S_GET_VALUE (symbolP) + 6);
+ }
+ }
+ /*
+ * Make a symbol reference to
+ * "_c$main_args" so we can get
+ * its address inserted into the
+ * JSB instruction.
+ */
+ symbolP = (symbolS *) xmalloc (sizeof (*symbolP));
+ S_SET_NAME (symbolP, "_C$MAIN_ARGS");
+ S_SET_TYPE (symbolP, N_UNDF);
+ S_SET_OTHER (symbolP, 0);
+ S_SET_DESC (symbolP, 0);
+ S_SET_VALUE (symbolP, 0);
+ symbolP->sy_name_offset = 0;
+ symbolP->sy_number = 0;
+ symbolP->sy_obj = 0;
+ symbolP->sy_frag = New_Frag;
+ symbolP->sy_resolved = 0;
+ symbolP->sy_resolving = 0;
+ /* this actually inserts at the beginning of the list */
+ symbol_append (symbol_rootP, symbolP,
+ &symbol_rootP, &symbol_lastP);
+
+ symbol_rootP = symbolP;
+ /*
+ * Generate a text fixup structure
+ * to get "_c$main_args" stored into the
+ * JSB instruction.
+ */
+ fixP = (struct fix *) xmalloc (sizeof (*fixP));
+ fixP->fx_frag = New_Frag;
+ fixP->fx_where = 4;
+ fixP->fx_addsy = symbolP;
+ fixP->fx_subsy = 0;
+ fixP->fx_offset = 0;
+ fixP->fx_size = 4;
+ fixP->fx_pcrel = 1;
+ fixP->fx_next = text_fix_root;
+ text_fix_root = fixP;
+ /*
+ * Now make sure we exit from the loop
+ */
+ frchainP = 0;
+ break;
+ }
+ /*
+ * Try the next fragment
+ */
+ prev_fragPP = &fragP->fr_next;
+ fragP = fragP->fr_next;
+ }
+ /*
+ * Try the next fragment chain
+ */
+ if (frchainP)
+ frchainP = frchainP->frch_next;
+ }
+ }
+#endif /* HACK_DEC_C_STARTUP */
+ }
+}
+
+
+/*
+ * Beginning of vms_write_object_file().
+ */
+
+static
+struct vms_obj_state {
+
+ /* Next program section index to use. */
+ int psect_number;
+
+ /* Psect index for code. Always ends up #0. */
+ int text_psect;
+
+ /* Psect index for initialized static variables. */
+ int data_psect;
+
+ /* Psect index for uninitialized static variables. */
+ int bss_psect;
+
+ /* Psect index for static constructors. */
+ int ctors_psect;
+
+ /* Psect index for static destructors. */
+ int dtors_psect;
+
+ /* Number of bytes used for local symbol data. */
+ int local_initd_data_size;
+
+ /* Dynamic buffer for initialized data. */
+ char *data_segment;
+
+} vms_obj_state;
+
+#define Psect_Number vms_obj_state.psect_number
+#define Text_Psect vms_obj_state.text_psect
+#define Data_Psect vms_obj_state.data_psect
+#define Bss_Psect vms_obj_state.bss_psect
+#define Ctors_Psect vms_obj_state.ctors_psect
+#define Dtors_Psect vms_obj_state.dtors_psect
+#define Local_Initd_Data_Size vms_obj_state.local_initd_data_size
+#define Data_Segment vms_obj_state.data_segment
+
+
+#define IS_GXX_VTABLE(symP) (strncmp (S_GET_NAME (symP), "__vt.", 5) == 0)
+#define IS_GXX_XTOR(symP) (strncmp (S_GET_NAME (symP), "__GLOBAL_.", 10) == 0)
+#define XTOR_SIZE 4
+
+
+/* Perform text segment fixups. */
+
+static void
+vms_fixup_text_section (text_siz, text_frag_root, data_frag_root)
+ unsigned text_siz;
+ struct frag *text_frag_root;
+ struct frag *data_frag_root;
+{
+ register fragS *fragP;
+ register struct fix *fixP;
+ offsetT dif;
+
+ /* Scan the text fragments. */
+ for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ /* Stop if we get to the data fragments. */
+ if (fragP == data_frag_root)
+ break;
+ /* Ignore fragments with no data. */
+ if ((fragP->fr_fix == 0) && (fragP->fr_var == 0))
+ continue;
+ /* Go the the appropriate offset in the Text Psect. */
+ VMS_Set_Psect (Text_Psect, fragP->fr_address, OBJ_S_C_TIR);
+ /* Store the "fixed" part. */
+ if (fragP->fr_fix)
+ VMS_Store_Immediate_Data (fragP->fr_literal,
+ fragP->fr_fix,
+ OBJ_S_C_TIR);
+ /* Store the "variable" part. */
+ if (fragP->fr_var && fragP->fr_offset)
+ VMS_Store_Repeated_Data (fragP->fr_offset,
+ fragP->fr_literal + fragP->fr_fix,
+ fragP->fr_var,
+ OBJ_S_C_TIR);
+ } /* text frag loop */
+
+ /*
+ * Now we go through the text segment fixups and generate
+ * TIR records to fix up addresses within the Text Psect.
+ */
+ for (fixP = text_fix_root; fixP; fixP = fixP->fx_next)
+ {
+ /* We DO handle the case of "Symbol - Symbol" as
+ long as it is in the same segment. */
+ if (fixP->fx_subsy && fixP->fx_addsy)
+ {
+ /* They need to be in the same segment. */
+ if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
+ S_GET_RAW_TYPE (fixP->fx_addsy))
+ error (_("Fixup data addsy and subsy don't have the same type"));
+ /* And they need to be in one that we can check the psect on. */
+ if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
+ (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
+ error (_("Fixup data addsy and subsy don't have an appropriate type"));
+ /* This had better not be PC relative! */
+ if (fixP->fx_pcrel)
+ error (_("Fixup data is erroneously \"pcrel\""));
+ /* Subtract their values to get the difference. */
+ dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
+ md_number_to_chars (Local, (valueT)dif, fixP->fx_size);
+ /* Now generate the fixup object records;
+ set the psect and store the data. */
+ VMS_Set_Psect (Text_Psect,
+ fixP->fx_where + fixP->fx_frag->fr_address,
+ OBJ_S_C_TIR);
+ VMS_Store_Immediate_Data (Local,
+ fixP->fx_size,
+ OBJ_S_C_TIR);
+ continue; /* done with this fixup */
+ } /* if fx_subsy && fx_addsy */
+ /* Size will HAVE to be "long". */
+ if (fixP->fx_size != 4)
+ error (_("Fixup datum is not a longword"));
+ /* Symbol must be "added" (if it is ever
+ subtracted we can fix this assumption). */
+ if (fixP->fx_addsy == 0)
+ error (_("Fixup datum is not \"fixP->fx_addsy\""));
+ /* Store the symbol value in a PIC fashion. */
+ VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
+ fixP->fx_offset,
+ fixP->fx_pcrel,
+ Text_Psect,
+ fixP->fx_where + fixP->fx_frag->fr_address,
+ OBJ_S_C_TIR);
+ /*
+ * Check for indirect address reference, which has to be fixed up
+ * (as the linker will screw it up with TIR_S_C_STO_PICR)...
+ */
+ if (fixP->fx_pcrel)
+ VMS_Fix_Indirect_Reference (Text_Psect,
+ fixP->fx_where + fixP->fx_frag->fr_address,
+ fixP->fx_frag,
+ text_frag_root);
+ } /* text fix loop */
+}
+
+
+/* Create a buffer holding the data segment. */
+
+static void
+synthesize_data_segment (data_siz, text_siz, data_frag_root)
+ unsigned data_siz, text_siz;
+ struct frag *data_frag_root;
+{
+ register fragS *fragP;
+ char *fill_literal;
+ long fill_size, count, i;
+
+ /* Allocate the data segment. */
+ Data_Segment = (char *) xmalloc (data_siz);
+ /* Run through the data fragments, filling in the segment. */
+ for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ i = fragP->fr_address - text_siz;
+ if (fragP->fr_fix)
+ memcpy (Data_Segment + i, fragP->fr_literal, fragP->fr_fix);
+ i += fragP->fr_fix;
+
+ if ((fill_size = fragP->fr_var) != 0)
+ {
+ fill_literal = fragP->fr_literal + fragP->fr_fix;
+ for (count = fragP->fr_offset; count; count--)
+ {
+ memcpy (Data_Segment + i, fill_literal, fill_size);
+ i += fill_size;
+ }
+ }
+ } /* data frag loop */
+
+ return;
+}
+
+
+/* Perform data segment fixups. */
+
+static void
+vms_fixup_data_section (data_siz, text_siz)
+ unsigned data_siz, text_siz;
+{
+ register struct VMS_Symbol *vsp;
+ register struct fix *fixP;
+ register symbolS *sp;
+ addressT fr_address;
+ offsetT dif;
+ valueT val;
+
+ /* Run through all the data symbols and store the data. */
+ for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
+ {
+ /* Ignore anything other than data symbols. */
+ if (S_GET_TYPE (vsp->Symbol) != N_DATA)
+ continue;
+ /* Set the Psect + Offset. */
+ VMS_Set_Psect (vsp->Psect_Index,
+ vsp->Psect_Offset,
+ OBJ_S_C_TIR);
+ /* Store the data. */
+ val = S_GET_VALUE (vsp->Symbol);
+ VMS_Store_Immediate_Data (Data_Segment + val - text_siz,
+ vsp->Size,
+ OBJ_S_C_TIR);
+ } /* N_DATA symbol loop */
+
+ /*
+ * Now we go through the data segment fixups and generate
+ * TIR records to fix up addresses within the Data Psects.
+ */
+ for (fixP = data_fix_root; fixP; fixP = fixP->fx_next)
+ {
+ /* Find the symbol for the containing datum. */
+ for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
+ {
+ /* Only bother with Data symbols. */
+ sp = vsp->Symbol;
+ if (S_GET_TYPE (sp) != N_DATA)
+ continue;
+ /* Ignore symbol if After fixup. */
+ val = S_GET_VALUE (sp);
+ fr_address = fixP->fx_frag->fr_address;
+ if (val > fixP->fx_where + fr_address)
+ continue;
+ /* See if the datum is here. */
+ if (val + vsp->Size <= fixP->fx_where + fr_address)
+ continue;
+ /* We DO handle the case of "Symbol - Symbol" as
+ long as it is in the same segment. */
+ if (fixP->fx_subsy && fixP->fx_addsy)
+ {
+ /* They need to be in the same segment. */
+ if (S_GET_RAW_TYPE (fixP->fx_subsy) !=
+ S_GET_RAW_TYPE (fixP->fx_addsy))
+ error (_("Fixup data addsy and subsy don't have the same type"));
+ /* And they need to be in one that we can check the psect on. */
+ if ((S_GET_TYPE (fixP->fx_addsy) != N_DATA) &&
+ (S_GET_TYPE (fixP->fx_addsy) != N_TEXT))
+ error (_("Fixup data addsy and subsy don't have an appropriate type"));
+ /* This had better not be PC relative! */
+ if (fixP->fx_pcrel)
+ error (_("Fixup data is erroneously \"pcrel\""));
+ /* Subtract their values to get the difference. */
+ dif = S_GET_VALUE (fixP->fx_addsy) - S_GET_VALUE (fixP->fx_subsy);
+ md_number_to_chars (Local, (valueT)dif, fixP->fx_size);
+ /*
+ * Now generate the fixup object records;
+ * set the psect and store the data.
+ */
+ VMS_Set_Psect (vsp->Psect_Index,
+ fr_address + fixP->fx_where
+ - val + vsp->Psect_Offset,
+ OBJ_S_C_TIR);
+ VMS_Store_Immediate_Data (Local,
+ fixP->fx_size,
+ OBJ_S_C_TIR);
+ break; /* done with this fixup */
+ }
+ /* Size will HAVE to be "long". */
+ if (fixP->fx_size != 4)
+ error (_("Fixup datum is not a longword"));
+ /* Symbol must be "added" (if it is ever
+ subtracted we can fix this assumption). */
+ if (fixP->fx_addsy == 0)
+ error (_("Fixup datum is not \"fixP->fx_addsy\""));
+ /* Store the symbol value in a PIC fashion. */
+ VMS_Store_PIC_Symbol_Reference (fixP->fx_addsy,
+ fixP->fx_offset,
+ fixP->fx_pcrel,
+ vsp->Psect_Index,
+ fr_address + fixP->fx_where
+ - val + vsp->Psect_Offset,
+ OBJ_S_C_TIR);
+ /* Done with this fixup. */
+ break;
+ } /* vms_symbol loop */
+
+ } /* data fix loop */
+}
+
+/* Perform ctors/dtors segment fixups. */
+
+static void
+vms_fixup_xtors_section (symbols, sect_no)
+ struct VMS_Symbol *symbols;
+ int sect_no;
+{
+ register struct VMS_Symbol *vsp;
+
+ /* Run through all the symbols and store the data. */
+ for (vsp = symbols; vsp; vsp = vsp->Next)
+ {
+ register symbolS *sp;
+
+ /* Set relocation base. */
+ VMS_Set_Psect (vsp->Psect_Index, vsp->Psect_Offset, OBJ_S_C_TIR);
+
+ sp = vsp->Symbol;
+ /* Stack the Psect base with its offset. */
+ VMS_Set_Data (Text_Psect, S_GET_VALUE (sp), OBJ_S_C_TIR, 0);
+ }
+ /* Flush the buffer if it is more than 75% full. */
+ if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))
+ Flush_VMS_Object_Record_Buffer ();
+
+ return;
+}
+
+
+/* Define symbols for the linker. */
+
+static void
+global_symbol_directory (text_siz, data_siz)
+ unsigned text_siz, data_siz;
+{
+ register fragS *fragP;
+ register symbolS *sp;
+ register struct VMS_Symbol *vsp;
+ int Globalref, define_as_global_symbol;
+
+#if 0
+ /* The g++ compiler does not write out external references to
+ vtables correctly. Check for this and holler if we see it
+ happening. If that compiler bug is ever fixed we can remove
+ this.
+
+ (Jun'95: gcc 2.7.0's cc1plus still exhibits this behavior.)
+
+ This was reportedly fixed as of June 2, 1998. */
+
+ for (sp = symbol_rootP; sp; sp = symbol_next (sp))
+ if (S_GET_RAW_TYPE (sp) == N_UNDF && IS_GXX_VTABLE (sp))
+ {
+ S_SET_TYPE (sp, N_UNDF | N_EXT);
+ S_SET_OTHER (sp, 1);
+ as_warn (_("g++ wrote an extern reference to `%s' as a routine.\nI will fix it, but I hope that it was note really a routine."),
+ S_GET_NAME (sp));
+ }
+#endif
+
+ /*
+ * Now scan the symbols and emit the appropriate GSD records
+ */
+ for (sp = symbol_rootP; sp; sp = symbol_next (sp))
+ {
+ define_as_global_symbol = 0;
+ vsp = 0;
+ /* Dispatch on symbol type. */
+ switch (S_GET_RAW_TYPE (sp))
+ {
+
+ /* Global uninitialized data. */
+ case N_UNDF | N_EXT:
+ /* Make a VMS data symbol entry. */
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = S_GET_VALUE (sp);
+ vsp->Psect_Index = Psect_Number++;
+ vsp->Psect_Offset = 0;
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ /* Make the psect for this data. */
+ Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
+ vsp->Size,
+ S_GET_OTHER (sp) ? ps_CONST : ps_COMMON,
+ vsp);
+ if (Globalref)
+ Psect_Number--;
+#ifdef NOT_VAX_11_C_COMPATIBLE
+ define_as_global_symbol = 1;
+#else
+ /* See if this is an external vtable. We want to help the
+ linker find these things in libraries, so we make a symbol
+ reference. This is not compatible with VAX-C usage for
+ variables, but since vtables are only used internally by
+ g++, we can get away with this hack. */
+ define_as_global_symbol = IS_GXX_VTABLE (sp);
+#endif
+ break;
+
+ /* Local uninitialized data. */
+ case N_BSS:
+ /* Make a VMS data symbol entry. */
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = 0;
+ vsp->Psect_Index = Bss_Psect;
+ vsp->Psect_Offset = S_GET_VALUE (sp) - bss_address_frag.fr_address;
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ break;
+
+ /* Global initialized data. */
+ case N_DATA | N_EXT:
+ /* Make a VMS data symbol entry. */
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
+ vsp->Psect_Index = Psect_Number++;
+ vsp->Psect_Offset = 0;
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ /* Make its psect. */
+ Globalref = VMS_Psect_Spec (S_GET_NAME (sp),
+ vsp->Size,
+ S_GET_OTHER (sp) ? ps_CONST : ps_COMMON,
+ vsp);
+ if (Globalref)
+ Psect_Number--;
+#ifdef NOT_VAX_11_C_COMPATIBLE
+ define_as_global_symbol = 1;
+#else
+ /* See N_UNDF|N_EXT above for explanation. */
+ define_as_global_symbol = IS_GXX_VTABLE (sp);
+#endif
+ break;
+
+ /* Local initialized data. */
+ case N_DATA:
+ {
+ char *sym_name = S_GET_NAME (sp);
+
+ /* Always suppress local numeric labels. */
+ if (sym_name && strcmp (sym_name, FAKE_LABEL_NAME) == 0)
+ break;
+
+ /* Make a VMS data symbol entry. */
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = VMS_Initialized_Data_Size (sp, text_siz + data_siz);
+ vsp->Psect_Index = Data_Psect;
+ vsp->Psect_Offset = Local_Initd_Data_Size;
+ Local_Initd_Data_Size += vsp->Size;
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ }
+ break;
+
+ /* Global Text definition. */
+ case N_TEXT | N_EXT:
+ {
+
+ if (IS_GXX_XTOR (sp))
+ {
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = XTOR_SIZE;
+ sp->sy_obj = vsp;
+ switch ((S_GET_NAME (sp))[10])
+ {
+ case 'I':
+ vsp->Psect_Index = Ctors_Psect;
+ vsp->Psect_Offset = (Ctors_Symbols==0)?0:(Ctors_Symbols->Psect_Offset+XTOR_SIZE);
+ vsp->Next = Ctors_Symbols;
+ Ctors_Symbols = vsp;
+ break;
+ case 'D':
+ vsp->Psect_Index = Dtors_Psect;
+ vsp->Psect_Offset = (Dtors_Symbols==0)?0:(Dtors_Symbols->Psect_Offset+XTOR_SIZE);
+ vsp->Next = Dtors_Symbols;
+ Dtors_Symbols = vsp;
+ break;
+ case 'G':
+ as_warn (_("Can't handle global xtors symbols yet."));
+ break;
+ default:
+ as_warn (_("Unknown %s"), S_GET_NAME (sp));
+ break;
+ }
+ }
+ else
+ {
+ unsigned short Entry_Mask;
+
+ /* Get the entry mask. */
+ fragP = sp->sy_frag;
+ /* First frag might be empty if we're generating listings.
+ So skip empty rs_fill frags. */
+ while (fragP && fragP->fr_type == rs_fill && fragP->fr_fix == 0)
+ fragP = fragP->fr_next;
+
+ /* If first frag doesn't contain the data, what do we do?
+ If it's possibly smaller than two bytes, that would
+ imply that the entry mask is not stored where we're
+ expecting it.
+
+ If you can find a test case that triggers this, report
+ it (and tell me what the entry mask field ought to be),
+ and I'll try to fix it. KR */
+ if (fragP->fr_fix < 2)
+ abort ();
+
+ Entry_Mask = (fragP->fr_literal[0] & 0x00ff) |
+ ((fragP->fr_literal[1] & 0x00ff) << 8);
+ /* Define the procedure entry point. */
+ VMS_Procedure_Entry_Pt (S_GET_NAME (sp),
+ Text_Psect,
+ S_GET_VALUE (sp),
+ Entry_Mask);
+ }
+ break;
+ }
+
+ /* Local Text definition. */
+ case N_TEXT:
+ /* Make a VMS data symbol entry. */
+ if (Text_Psect != -1)
+ {
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = 0;
+ vsp->Psect_Index = Text_Psect;
+ vsp->Psect_Offset = S_GET_VALUE (sp);
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ }
+ break;
+
+ /* Global Reference. */
+ case N_UNDF:
+ /* Make a GSD global symbol reference record. */
+ VMS_Global_Symbol_Spec (S_GET_NAME (sp),
+ 0,
+ 0,
+ GBLSYM_REF);
+ break;
+
+ /* Absolute symbol. */
+ case N_ABS:
+ case N_ABS | N_EXT:
+ /* gcc doesn't generate these;
+ VMS_Emit_Globalvalue handles them though. */
+ vsp = (struct VMS_Symbol *) xmalloc (sizeof *vsp);
+ vsp->Symbol = sp;
+ vsp->Size = 4; /* always assume 32 bits */
+ vsp->Psect_Index = 0;
+ vsp->Psect_Offset = S_GET_VALUE (sp);
+ vsp->Next = VMS_Symbols;
+ VMS_Symbols = vsp;
+ sp->sy_obj = vsp;
+ break;
+
+ /* Anything else. */
+ default:
+ /* Ignore STAB symbols, including .stabs emitted by g++. */
+ if (S_IS_DEBUG (sp) || (S_GET_TYPE (sp) == 22))
+ break;
+ /*
+ * Error otherwise.
+ */
+ as_tsktsk (_("unhandled stab type %d"), S_GET_TYPE (sp));
+ break;
+ }
+
+ /* Global symbols have different linkage than external variables. */
+ if (define_as_global_symbol)
+ VMS_Global_Symbol_Spec (S_GET_NAME (sp),
+ vsp->Psect_Index,
+ 0,
+ GBLSYM_DEF);
+ }
+
+ return;
+}
+
+
+/* Output debugger symbol table information for symbols which
+ are local to a specific routine. */
+
+static void
+local_symbols_DST (s0P, Current_Routine)
+ symbolS *s0P, *Current_Routine;
+{
+ symbolS *s1P;
+ char *s0P_name, *pnt0, *pnt1;
+
+ s0P_name = S_GET_NAME (s0P);
+ if (*s0P_name++ != '_')
+ return;
+
+ for (s1P = Current_Routine; s1P; s1P = symbol_next (s1P))
+ {
+#if 0 /* redundant; RAW_TYPE != N_FUN suffices */
+ if (!S_IS_DEBUG (s1P))
+ continue;
+#endif
+ if (S_GET_RAW_TYPE (s1P) != N_FUN)
+ continue;
+ pnt0 = s0P_name;
+ pnt1 = S_GET_NAME (s1P);
+ /* We assume the two strings are never exactly equal... */
+ while (*pnt0++ == *pnt1++)
+ {
+ }
+ /* Found it if s0P name is exhausted and s1P name has ":F" or ":f" next.
+ Note: both pointers have advanced one past the non-matching char. */
+ if ((*pnt1 == 'F' || *pnt1 == 'f') && *--pnt1 == ':' && *--pnt0 == '\0')
+ {
+ Define_Routine (s1P, 0, Current_Routine, Text_Psect);
+ return;
+ }
+ }
+}
+
+
+/* Construct and output the debug symbol table. */
+
+static void
+vms_build_DST (text_siz)
+ unsigned text_siz;
+{
+ register symbolS *symbolP;
+ symbolS *Current_Routine = 0;
+ struct input_file *Cur_File = 0;
+ offsetT Cur_Offset = -1;
+ int Cur_Line_Number = 0;
+ int File_Number = 0;
+ int Debugger_Offset = 0;
+ int file_available;
+ int dsc;
+ offsetT val;
+
+ /* Write the Traceback Begin Module record. */
+ VMS_TBT_Module_Begin ();
+
+ /*
+ * Output debugging info for global variables and static variables
+ * that are not specific to one routine. We also need to examine
+ * all stabs directives, to find the definitions to all of the
+ * advanced data types, and this is done by VMS_LSYM_Parse. This
+ * needs to be done before any definitions are output to the object
+ * file, since there can be forward references in the stabs
+ * directives. When through with parsing, the text of the stabs
+ * directive is altered, with the definitions removed, so that later
+ * passes will see directives as they would be written if the type
+ * were already defined.
+ *
+ * We also look for files and include files, and make a list of
+ * them. We examine the source file numbers to establish the actual
+ * lines that code was generated from, and then generate offsets.
+ */
+ VMS_LSYM_Parse ();
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /* Only deal with STAB symbols here. */
+ if (!S_IS_DEBUG (symbolP))
+ continue;
+ /*
+ * Dispatch on STAB type.
+ */
+ switch (S_GET_RAW_TYPE (symbolP))
+ {
+ case N_SLINE:
+ dsc = S_GET_DESC (symbolP);
+ if (dsc > Cur_File->max_line)
+ Cur_File->max_line = dsc;
+ if (dsc < Cur_File->min_line)
+ Cur_File->min_line = dsc;
+ break;
+ case N_SO:
+ Cur_File = find_file (symbolP);
+ Cur_File->flag = 1;
+ Cur_File->min_line = 1;
+ break;
+ case N_SOL:
+ Cur_File = find_file (symbolP);
+ break;
+ case N_GSYM:
+ VMS_GSYM_Parse (symbolP, Text_Psect);
+ break;
+ case N_LCSYM:
+ VMS_LCSYM_Parse (symbolP, Text_Psect);
+ break;
+ case N_FUN: /* For static constant symbols */
+ case N_STSYM:
+ VMS_STSYM_Parse (symbolP, Text_Psect);
+ break;
+ default:
+ break;
+ } /* switch */
+ } /* for */
+
+ /*
+ * Now we take a quick sweep through the files and assign offsets
+ * to each one. This will essentially be the starting line number to
+ * the debugger for each file. Output the info for the debugger to
+ * specify the files, and then tell it how many lines to use.
+ */
+ for (Cur_File = file_root; Cur_File; Cur_File = Cur_File->next)
+ {
+ if (Cur_File->max_line == 0)
+ continue;
+ if ((strncmp (Cur_File->name, "GNU_GXX_INCLUDE:", 16) == 0) &&
+ !flag_debug)
+ continue;
+ if ((strncmp (Cur_File->name, "GNU_CC_INCLUDE:", 15) == 0) &&
+ !flag_debug)
+ continue;
+ /* show a few extra lines at the start of the region selected */
+ if (Cur_File->min_line > 2)
+ Cur_File->min_line -= 2;
+ Cur_File->offset = Debugger_Offset - Cur_File->min_line + 1;
+ Debugger_Offset += Cur_File->max_line - Cur_File->min_line + 1;
+ if (Cur_File->same_file_fpnt)
+ {
+ Cur_File->file_number = Cur_File->same_file_fpnt->file_number;
+ }
+ else
+ {
+ Cur_File->file_number = ++File_Number;
+ file_available = VMS_TBT_Source_File (Cur_File->name,
+ Cur_File->file_number);
+ if (!file_available)
+ {
+ Cur_File->file_number = 0;
+ File_Number--;
+ continue;
+ }
+ }
+ VMS_TBT_Source_Lines (Cur_File->file_number,
+ Cur_File->min_line,
+ Cur_File->max_line - Cur_File->min_line + 1);
+ } /* for */
+ Cur_File = (struct input_file *) NULL;
+
+ /*
+ * Scan the symbols and write out the routines
+ * (this makes the assumption that symbols are in
+ * order of ascending text segment offset)
+ */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+ /*
+ * Deal with text symbols.
+ */
+ if (!S_IS_DEBUG (symbolP) && S_GET_TYPE (symbolP) == N_TEXT)
+ {
+ /*
+ * Ignore symbols starting with "L", as they are local symbols.
+ */
+ if (*S_GET_NAME (symbolP) == 'L')
+ continue;
+ /*
+ * If there is a routine start defined, terminate it.
+ */
+ if (Current_Routine)
+ VMS_TBT_Routine_End (text_siz, Current_Routine);
+
+ /*
+ * Check for & skip dummy labels like "gcc_compiled.".
+ * They're identified by the IN_DEFAULT_SECTION flag.
+ */
+ if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 &&
+ S_GET_VALUE (symbolP) == 0)
+ continue;
+ /*
+ * Store the routine begin traceback info.
+ */
+ VMS_TBT_Routine_Begin (symbolP, Text_Psect);
+ Current_Routine = symbolP;
+ /*
+ * Define symbols local to this routine.
+ */
+ local_symbols_DST (symbolP, Current_Routine);
+ /*
+ * Done
+ */
+ continue;
+
+ }
+ /*
+ * Deal with STAB symbols.
+ */
+ else if (S_IS_DEBUG (symbolP))
+ {
+ /*
+ * Dispatch on STAB type.
+ */
+ switch (S_GET_RAW_TYPE (symbolP))
+ {
+ /*
+ * Line number
+ */
+ case N_SLINE:
+ /* Offset the line into the correct portion of the file. */
+ if (Cur_File->file_number == 0)
+ break;
+ val = S_GET_VALUE (symbolP);
+ /* Sometimes the same offset gets several source lines
+ assigned to it. We should be selective about which
+ lines we allow, we should prefer lines that are in
+ the main source file when debugging inline functions. */
+ if (val == Cur_Offset && Cur_File->file_number != 1)
+ break;
+
+ /* calculate actual debugger source line */
+ dsc = S_GET_DESC (symbolP) + Cur_File->offset;
+ S_SET_DESC (symbolP, dsc);
+ /*
+ * Define PC/Line correlation.
+ */
+ if (Cur_Offset == -1)
+ {
+ /*
+ * First N_SLINE; set up initial correlation.
+ */
+ VMS_TBT_Line_PC_Correlation (dsc,
+ val,
+ Text_Psect,
+ 0);
+ }
+ else if ((dsc - Cur_Line_Number) <= 0)
+ {
+ /*
+ * Line delta is not +ve, we need to close the line and
+ * start a new PC/Line correlation.
+ */
+ VMS_TBT_Line_PC_Correlation (0,
+ val - Cur_Offset,
+ 0,
+ -1);
+ VMS_TBT_Line_PC_Correlation (dsc,
+ val,
+ Text_Psect,
+ 0);
+ }
+ else
+ {
+ /*
+ * Line delta is +ve, all is well.
+ */
+ VMS_TBT_Line_PC_Correlation (dsc - Cur_Line_Number,
+ val - Cur_Offset,
+ 0,
+ 1);
+ }
+ /* Update the current line/PC info. */
+ Cur_Line_Number = dsc;
+ Cur_Offset = val;
+ break;
+
+ /*
+ * Source file
+ */
+ case N_SO:
+ /* Remember that we had a source file and emit
+ the source file debugger record. */
+ Cur_File = find_file (symbolP);
+ break;
+
+ case N_SOL:
+ /* We need to make sure that we are really in the actual
+ source file when we compute the maximum line number.
+ Otherwise the debugger gets really confused. */
+ Cur_File = find_file (symbolP);
+ break;
+
+ default:
+ break;
+ } /* switch */
+ } /* if (IS_DEBUG) */
+ } /* for */
+
+ /*
+ * If there is a routine start defined, terminate it
+ * (and the line numbers).
+ */
+ if (Current_Routine)
+ {
+ /* Terminate the line numbers. */
+ VMS_TBT_Line_PC_Correlation (0,
+ text_siz - S_GET_VALUE (Current_Routine),
+ 0,
+ -1);
+ /* Terminate the routine. */
+ VMS_TBT_Routine_End (text_siz, Current_Routine);
+ }
+
+ /* Write the Traceback End Module TBT record. */
+ VMS_TBT_Module_End ();
+}
+
+
+/* Write a VAX/VMS object file (everything else has been done!). */
+
+void
+vms_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
+ data_frag_root)
+ unsigned text_siz;
+ unsigned data_siz;
+ unsigned bss_siz;
+ fragS *text_frag_root;
+ fragS *data_frag_root;
+{
+ register struct VMS_Symbol *vsp;
+
+ /*
+ * Initialize program section indices; values get updated later.
+ */
+ Psect_Number = 0; /* next Psect Index to use */
+ Text_Psect = -1; /* Text Psect Index */
+ Data_Psect = -2; /* Data Psect Index JF: Was -1 */
+ Bss_Psect = -3; /* Bss Psect Index JF: Was -1 */
+ Ctors_Psect = -4; /* Ctors Psect Index */
+ Dtors_Psect = -5; /* Dtors Psect Index */
+ /* Initialize other state variables. */
+ Data_Segment = 0;
+ Local_Initd_Data_Size = 0;
+
+ /*
+ * Create the actual output file and populate it with required
+ * "module header" information.
+ */
+ Create_VMS_Object_File ();
+ Write_VMS_MHD_Records ();
+
+ /*
+ * Create the Data segment:
+ *
+ * Since this is REALLY hard to do any other way,
+ * we actually manufacture the data segment and
+ * then store the appropriate values out of it.
+ * We need to generate this early, so that globalvalues
+ * can be properly emitted.
+ */
+ if (data_siz > 0)
+ synthesize_data_segment (data_siz, text_siz, data_frag_root);
+
+
+ /******* Global Symbol Directory *******/
+
+ /*
+ * Emit globalvalues now. We must do this before the text psect is
+ * defined, or we will get linker warnings about multiply defined
+ * symbols. All of the globalvalues "reference" psect 0, although
+ * it really does not have anything to do with it.
+ */
+ VMS_Emit_Globalvalues (text_siz, data_siz, Data_Segment);
+ /*
+ * Define the Text Psect
+ */
+ Text_Psect = Psect_Number++;
+ VMS_Psect_Spec ("$code", text_siz, ps_TEXT, 0);
+ /*
+ * Define the BSS Psect
+ */
+ if (bss_siz > 0)
+ {
+ Bss_Psect = Psect_Number++;
+ VMS_Psect_Spec ("$uninitialized_data", bss_siz, ps_DATA, 0);
+ }
+ /*
+ * Define symbols to the linker.
+ */
+ global_symbol_directory (text_siz, data_siz);
+ /*
+ * Define the Data Psect
+ */
+ if (data_siz > 0 && Local_Initd_Data_Size > 0)
+ {
+ Data_Psect = Psect_Number++;
+ VMS_Psect_Spec ("$data", Local_Initd_Data_Size, ps_DATA, 0);
+ /*
+ * Local initialized data (N_DATA) symbols need to be updated to the
+ * proper value of Data_Psect now that it's actually been defined.
+ * (A dummy value was used in global_symbol_directory() above.)
+ */
+ for (vsp = VMS_Symbols; vsp; vsp = vsp->Next)
+ if (vsp->Psect_Index < 0 && S_GET_RAW_TYPE (vsp->Symbol) == N_DATA)
+ vsp->Psect_Index = Data_Psect;
+ }
+
+
+ if (Ctors_Symbols != 0)
+ {
+ char *ps_name = "$ctors";
+ Ctors_Psect = Psect_Number++;
+ VMS_Psect_Spec (ps_name, Ctors_Symbols->Psect_Offset + XTOR_SIZE,
+ ps_CTORS, 0);
+ VMS_Global_Symbol_Spec (ps_name, Ctors_Psect,
+ 0, GBLSYM_DEF|GBLSYM_WEAK);
+ for (vsp = Ctors_Symbols; vsp; vsp = vsp->Next)
+ vsp->Psect_Index = Ctors_Psect;
+ }
+
+ if (Dtors_Symbols != 0)
+ {
+ char *ps_name = "$dtors";
+ Dtors_Psect = Psect_Number++;
+ VMS_Psect_Spec (ps_name, Dtors_Symbols->Psect_Offset + XTOR_SIZE,
+ ps_DTORS, 0);
+ VMS_Global_Symbol_Spec (ps_name, Dtors_Psect,
+ 0, GBLSYM_DEF|GBLSYM_WEAK);
+ for (vsp = Dtors_Symbols; vsp; vsp = vsp->Next)
+ vsp->Psect_Index = Dtors_Psect;
+ }
+
+ /******* Text Information and Relocation Records *******/
+
+ /*
+ * Write the text segment data
+ */
+ if (text_siz > 0)
+ vms_fixup_text_section (text_siz, text_frag_root, data_frag_root);
+ /*
+ * Write the data segment data, then discard it.
+ */
+ if (data_siz > 0)
+ {
+ vms_fixup_data_section (data_siz, text_siz);
+ free (Data_Segment), Data_Segment = 0;
+ }
+
+ if (Ctors_Symbols != 0)
+ {
+ vms_fixup_xtors_section (Ctors_Symbols, Ctors_Psect);
+ }
+
+ if (Dtors_Symbols != 0)
+ {
+ vms_fixup_xtors_section (Dtors_Symbols, Dtors_Psect);
+ }
+
+
+ /******* Debugger Symbol Table Records *******/
+
+ vms_build_DST (text_siz);
+
+
+ /******* Wrap things up *******/
+
+ /*
+ * Write the End Of Module record
+ */
+ if (Entry_Point_Symbol)
+ Write_VMS_EOM_Record (Text_Psect, S_GET_VALUE (Entry_Point_Symbol));
+ else
+ Write_VMS_EOM_Record (-1, (valueT) 0);
+
+ /*
+ * All done, close the object file
+ */
+ Close_VMS_Object_File ();
+}
+
+/* end of obj-vms.c */
diff --git a/gas/config/obj-vms.h b/gas/config/obj-vms.h
new file mode 100644
index 00000000000..ac0c1fb3563
--- /dev/null
+++ b/gas/config/obj-vms.h
@@ -0,0 +1,552 @@
+/* VMS object file format
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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,
+or (at your option) any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Tag to validate a.out object file format processing */
+#define OBJ_VMS 1
+
+#include "targ-cpu.h"
+
+#define LONGWORD_ALIGNMENT 2
+
+/* This macro controls subsection alignment within a section.
+ *
+ * Under VAX/VMS, the linker (and PSECT specifications)
+ * take care of correctly aligning the segments.
+ * Doing the alignment here (on initialized data) can
+ * mess up the calculation of global data PSECT sizes.
+ */
+#define SUB_SEGMENT_ALIGN(SEG) \
+ (((SEG) == data_section) ? 0 : LONGWORD_ALIGNMENT)
+
+/* This flag is used to remember whether we are in the const or the
+ data section. By and large they are identical, but we set a no-write
+ bit for psects in the const section. */
+
+extern unsigned char const_flag;
+
+/* This is overloaded onto const_flag, for convenience. It's used to flag
+ dummy labels like "gcc2_compiled." which occur before the first .text
+ or .data section directive. */
+
+#define IN_DEFAULT_SECTION 0x80
+
+/* These are defined in obj-vms.c. */
+extern const short seg_N_TYPE[];
+extern const segT N_TYPE_seg[];
+
+#undef NO_RELOC
+enum reloc_type
+ {
+ NO_RELOC, RELOC_32
+ };
+
+#define N_BADMAG(x) (0)
+#define N_TXTOFF(x) ( sizeof(struct exec) )
+#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data )
+#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize )
+#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize )
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+
+/* We use this copy of the exec header for VMS. We do not actually use it, but
+ what we actually do is let gas fill in the relevant slots, and when we get
+ around to writing an obj file, we just pick out what we need. */
+
+struct exec
+{
+ unsigned long a_text; /* length of text, in bytes */
+ unsigned long a_data; /* length of data, in bytes */
+ unsigned long a_bss; /* length of uninitialized data area for file, in bytes */
+ unsigned long a_trsize; /* length of relocation info for text, in bytes */
+ unsigned long a_drsize; /* length of relocation info for data, in bytes */
+ unsigned long a_entry; /* start address */
+ unsigned long a_syms; /* length of symbol table data in file, in bytes */
+};
+
+typedef struct
+ {
+ struct exec header; /* a.out header */
+ long string_table_size; /* names + '\0' + sizeof(int) */
+ }
+object_headers;
+
+/* A single entry in the symbol table
+ * (this started as a clone of bout.h's nlist, but much was unneeded).
+ */
+struct nlist
+ {
+ char *n_name;
+ unsigned char n_type; /* See below */
+ unsigned char n_other; /* used for const_flag and "default section" */
+ unsigned : 16; /* padding for alignment */
+ int n_desc; /* source line number for N_SLINE stabs */
+ };
+
+/* Legal values of n_type (see aout/stab.def for the majority of the codes).
+ */
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol */
+#define N_TEXT 4 /* Text symbol */
+#define N_DATA 6 /* Data symbol */
+#define N_BSS 8 /* BSS symbol */
+#define N_FN 31 /* Filename symbol */
+
+#define N_EXT 1 /* External symbol (OR'd in with one of above) */
+#define N_TYPE 036 /* Mask for all the type bits */
+
+#define N_STAB 0340 /* Mask for all bits used for SDB entries */
+
+#include "aout/stab_gnu.h"
+
+/* SYMBOL TABLE */
+/* Symbol table entry data type */
+
+typedef struct nlist obj_symbol_type; /* Symbol table entry */
+
+/* Symbol table macros and constants */
+
+#define OBJ_SYMFIELD_TYPE struct VMS_Symbol *
+
+/*
+ * Macros to extract information from a symbol table entry.
+ * This syntaxic indirection allows independence regarding a.out or coff.
+ * The argument (s) of all these macros is a pointer to a symbol table entry.
+ */
+
+/* True if the symbol is external */
+#define S_IS_EXTERNAL(s) ((s)->sy_symbol.n_type & N_EXT)
+
+/* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */
+#define S_IS_DEFINED(s) (S_GET_TYPE(s) != N_UNDF)
+
+#define S_IS_COMMON(s) (S_GET_TYPE(s) == N_UNDF && S_GET_VALUE(s) != 0)
+
+#define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER)
+
+/* True if a debug special symbol entry */
+#define S_IS_DEBUG(s) ((s)->sy_symbol.n_type & N_STAB)
+/* True if a symbol is local symbol name */
+/* A symbol name whose name begin with ^A is a gas internal pseudo symbol
+ nameless symbols come from .stab directives. */
+#define S_IS_LOCAL(s) (S_GET_NAME(s) && \
+ !S_IS_DEBUG(s) && \
+ (strchr(S_GET_NAME(s), '\001') != 0 || \
+ strchr(S_GET_NAME(s), '\002') != 0 || \
+ (S_LOCAL_NAME(s) && !flag_keep_locals)))
+/* True if a symbol is not defined in this file */
+#define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT)
+/* True if the symbol has been generated because of a .stabd directive */
+#define S_IS_STABD(s) (S_GET_NAME(s) == (char *)0)
+
+/* Accessors */
+/* The name of the symbol */
+#define S_GET_NAME(s) ((s)->sy_symbol.n_name)
+/* The pointer to the string table */
+#define S_GET_OFFSET(s) ((s)->sy_name_offset)
+/* The raw type of the symbol */
+#define S_GET_RAW_TYPE(s) ((s)->sy_symbol.n_type)
+/* The type of the symbol */
+#define S_GET_TYPE(s) ((s)->sy_symbol.n_type & N_TYPE)
+/* The numeric value of the segment */
+#define S_GET_SEGMENT(s) (N_TYPE_seg[S_GET_TYPE(s)])
+/* The n_other expression value */
+#define S_GET_OTHER(s) ((s)->sy_symbol.n_other)
+/* The n_desc expression value */
+#define S_GET_DESC(s) ((s)->sy_symbol.n_desc)
+
+/* Modifiers */
+/* Assume that a symbol cannot be simultaneously in more than on segment */
+/* set segment */
+#define S_SET_SEGMENT(s,seg) ((s)->sy_symbol.n_type &= ~N_TYPE,(s)->sy_symbol.n_type|=SEGMENT_TO_SYMBOL_TYPE(seg))
+/* The symbol is external */
+#define S_SET_EXTERNAL(s) ((s)->sy_symbol.n_type |= N_EXT)
+/* The symbol is not external */
+#define S_CLEAR_EXTERNAL(s) ((s)->sy_symbol.n_type &= ~N_EXT)
+/* Set the name of the symbol */
+#define S_SET_NAME(s,v) ((s)->sy_symbol.n_name = (v))
+/* Set the offset in the string table */
+#define S_SET_OFFSET(s,v) ((s)->sy_name_offset = (v))
+/* Set the n_other expression value */
+#define S_SET_OTHER(s,v) ((s)->sy_symbol.n_other = (v))
+/* Set the n_desc expression value */
+#define S_SET_DESC(s,v) ((s)->sy_symbol.n_desc = (v))
+/* Set the n_type expression value */
+#define S_SET_TYPE(s,v) ((s)->sy_symbol.n_type = (v))
+
+
+/* File header macro and type definition */
+
+#define H_GET_TEXT_SIZE(h) ((h)->header.a_text)
+#define H_GET_DATA_SIZE(h) ((h)->header.a_data)
+#define H_GET_BSS_SIZE(h) ((h)->header.a_bss)
+
+#define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v)))
+#define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v)))
+#define H_SET_BSS_SIZE(h,v) ((h)->header.a_bss = md_section_align(SEG_BSS, (v)))
+
+#define H_SET_STRING_SIZE(h,v) ((h)->string_table_size = (v))
+#define H_SET_SYMBOL_TABLE_SIZE(h,v) ((h)->header.a_syms = (v) * \
+ sizeof(struct nlist))
+
+/* line numbering stuff. */
+#define OBJ_EMIT_LINENO(a, b, c) {;}
+
+#define obj_symbol_new_hook(s) {;}
+
+/* Force structure tags into scope so that their use in prototypes
+ will never be their first occurance. */
+struct fix;
+struct symbol;
+struct frag;
+
+/* obj-vms routines visible to the rest of gas. */
+
+extern void tc_aout_fix_to_chars PARAMS ((char *,struct fix *,relax_addressT));
+
+extern int vms_resolve_symbol_redef PARAMS ((struct symbol *));
+#define RESOLVE_SYMBOL_REDEFINITION(X) vms_resolve_symbol_redef(X)
+
+/* Compiler-generated label "__vax_g_doubles" is used to augment .stabs. */
+extern void vms_check_for_special_label PARAMS ((struct symbol *));
+#define obj_frob_label(X) vms_check_for_special_label(X)
+
+extern void vms_check_for_main PARAMS ((void));
+
+extern void vms_write_object_file PARAMS ((unsigned,unsigned,unsigned,
+ struct frag *,struct frag *));
+
+/* VMS executables are nothing like a.out, but the VMS port of gcc uses
+ a.out format stabs which obj-vms.c then translates. */
+
+#define AOUT_STABS
+
+
+#ifdef WANT_VMS_OBJ_DEFS
+
+/* The rest of this file contains definitions for constants used within
+ the actual VMS object file. We do not use a $ in the symbols (as per
+ usual VMS convention) since System V gags on it. */
+
+#define OBJ_S_C_HDR 0
+#define OBJ_S_C_HDR_MHD 0
+#define OBJ_S_C_HDR_LNM 1
+#define OBJ_S_C_HDR_SRC 2
+#define OBJ_S_C_HDR_TTL 3
+#define OBJ_S_C_HDR_CPR 4
+#define OBJ_S_C_HDR_MTC 5
+#define OBJ_S_C_HDR_GTX 6
+#define OBJ_S_C_GSD 1
+#define OBJ_S_C_GSD_PSC 0
+#define OBJ_S_C_GSD_SYM 1
+#define OBJ_S_C_GSD_EPM 2
+#define OBJ_S_C_GSD_PRO 3
+#define OBJ_S_C_GSD_SYMW 4
+#define OBJ_S_C_GSD_EPMW 5
+#define OBJ_S_C_GSD_PROW 6
+#define OBJ_S_C_GSD_IDC 7
+#define OBJ_S_C_GSD_ENV 8
+#define OBJ_S_C_GSD_LSY 9
+#define OBJ_S_C_GSD_LEPM 10
+#define OBJ_S_C_GSD_LPRO 11
+#define OBJ_S_C_GSD_SPSC 12
+#define OBJ_S_C_TIR 2
+#define OBJ_S_C_EOM 3
+#define OBJ_S_C_DBG 4
+#define OBJ_S_C_TBT 5
+#define OBJ_S_C_LNK 6
+#define OBJ_S_C_EOMW 7
+#define OBJ_S_C_MAXRECTYP 7
+#define OBJ_S_K_SUBTYP 1
+#define OBJ_S_C_SUBTYP 1
+#define OBJ_S_C_MAXRECSIZ 2048
+#define OBJ_S_C_STRLVL 0
+#define OBJ_S_C_SYMSIZ 31
+#define OBJ_S_C_STOREPLIM -1
+#define OBJ_S_C_PSCALILIM 9
+
+#define MHD_S_C_MHD 0
+#define MHD_S_C_LNM 1
+#define MHD_S_C_SRC 2
+#define MHD_S_C_TTL 3
+#define MHD_S_C_CPR 4
+#define MHD_S_C_MTC 5
+#define MHD_S_C_GTX 6
+#define MHD_S_C_MAXHDRTYP 6
+
+#define GSD_S_K_ENTRIES 1
+#define GSD_S_C_ENTRIES 1
+#define GSD_S_C_PSC 0
+#define GSD_S_C_SYM 1
+#define GSD_S_C_EPM 2
+#define GSD_S_C_PRO 3
+#define GSD_S_C_SYMW 4
+#define GSD_S_C_EPMW 5
+#define GSD_S_C_PROW 6
+#define GSD_S_C_IDC 7
+#define GSD_S_C_ENV 8
+#define GSD_S_C_LSY 9
+#define GSD_S_C_LEPM 10
+#define GSD_S_C_LPRO 11
+#define GSD_S_C_SPSC 12
+#define GSD_S_C_SYMV 13
+#define GSD_S_C_EPMV 14
+#define GSD_S_C_PROV 15
+#define GSD_S_C_MAXRECTYP 15
+
+#define GSY_S_M_WEAK 1
+#define GSY_S_M_DEF 2
+#define GSY_S_M_UNI 4
+#define GSY_S_M_REL 8
+
+#define LSY_S_M_DEF 2
+#define LSY_S_M_REL 8
+
+#define ENV_S_M_DEF 1
+#define ENV_S_M_NESTED 2
+
+#define GPS_S_M_PIC 1
+#define GPS_S_M_LIB 2
+#define GPS_S_M_OVR 4
+#define GPS_S_M_REL 8
+#define GPS_S_M_GBL 16
+#define GPS_S_M_SHR 32
+#define GPS_S_M_EXE 64
+#define GPS_S_M_RD 128
+#define GPS_S_M_WRT 256
+#define GPS_S_M_VEC 512
+#define GPS_S_K_NAME 9
+#define GPS_S_C_NAME 9
+
+#define TIR_S_C_STA_GBL 0
+#define TIR_S_C_STA_SB 1
+#define TIR_S_C_STA_SW 2
+#define TIR_S_C_STA_LW 3
+#define TIR_S_C_STA_PB 4
+#define TIR_S_C_STA_PW 5
+#define TIR_S_C_STA_PL 6
+#define TIR_S_C_STA_UB 7
+#define TIR_S_C_STA_UW 8
+#define TIR_S_C_STA_BFI 9
+#define TIR_S_C_STA_WFI 10
+#define TIR_S_C_STA_LFI 11
+#define TIR_S_C_STA_EPM 12
+#define TIR_S_C_STA_CKARG 13
+#define TIR_S_C_STA_WPB 14
+#define TIR_S_C_STA_WPW 15
+#define TIR_S_C_STA_WPL 16
+#define TIR_S_C_STA_LSY 17
+#define TIR_S_C_STA_LIT 18
+#define TIR_S_C_STA_LEPM 19
+#define TIR_S_C_MAXSTACOD 19
+#define TIR_S_C_MINSTOCOD 20
+#define TIR_S_C_STO_SB 20
+#define TIR_S_C_STO_SW 21
+#define TIR_S_C_STO_L 22
+#define TIR_S_C_STO_BD 23
+#define TIR_S_C_STO_WD 24
+#define TIR_S_C_STO_LD 25
+#define TIR_S_C_STO_LI 26
+#define TIR_S_C_STO_PIDR 27
+#define TIR_S_C_STO_PICR 28
+#define TIR_S_C_STO_RSB 29
+#define TIR_S_C_STO_RSW 30
+#define TIR_S_C_STO_RL 31
+#define TIR_S_C_STO_VPS 32
+#define TIR_S_C_STO_USB 33
+#define TIR_S_C_STO_USW 34
+#define TIR_S_C_STO_RUB 35
+#define TIR_S_C_STO_RUW 36
+#define TIR_S_C_STO_B 37
+#define TIR_S_C_STO_W 38
+#define TIR_S_C_STO_RB 39
+#define TIR_S_C_STO_RW 40
+#define TIR_S_C_STO_RIVB 41
+#define TIR_S_C_STO_PIRR 42
+#define TIR_S_C_MAXSTOCOD 42
+#define TIR_S_C_MINOPRCOD 50
+#define TIR_S_C_OPR_NOP 50
+#define TIR_S_C_OPR_ADD 51
+#define TIR_S_C_OPR_SUB 52
+#define TIR_S_C_OPR_MUL 53
+#define TIR_S_C_OPR_DIV 54
+#define TIR_S_C_OPR_AND 55
+#define TIR_S_C_OPR_IOR 56
+#define TIR_S_C_OPR_EOR 57
+#define TIR_S_C_OPR_NEG 58
+#define TIR_S_C_OPR_COM 59
+#define TIR_S_C_OPR_INSV 60
+#define TIR_S_C_OPR_ASH 61
+#define TIR_S_C_OPR_USH 62
+#define TIR_S_C_OPR_ROT 63
+#define TIR_S_C_OPR_SEL 64
+#define TIR_S_C_OPR_REDEF 65
+#define TIR_S_C_OPR_DFLIT 66
+#define TIR_S_C_MAXOPRCOD 66
+#define TIR_S_C_MINCTLCOD 80
+#define TIR_S_C_CTL_SETRB 80
+#define TIR_S_C_CTL_AUGRB 81
+#define TIR_S_C_CTL_DFLOC 82
+#define TIR_S_C_CTL_STLOC 83
+#define TIR_S_C_CTL_STKDL 84
+#define TIR_S_C_MAXCTLCOD 84
+
+/*
+ * Debugger symbol definitions: These are done by hand, as no
+ * machine-readable version seems
+ * to be available.
+ */
+#define DST_S_C_C 7 /* Language == "C" */
+#define DST_S_C_CXX 15 /* Language == "C++" */
+#define DST_S_C_VERSION 153
+#define DST_S_C_SOURCE 155 /* Source file */
+#define DST_S_C_PROLOG 162
+#define DST_S_C_BLKBEG 176 /* Beginning of block */
+#define DST_S_C_BLKEND 177 /* End of block */
+#define DST_S_C_ENTRY 181
+#define DST_S_C_PSECT 184
+#define DST_S_C_LINE_NUM 185 /* Line Number */
+#define DST_S_C_LBLORLIT 186
+#define DST_S_C_LABEL 187
+#define DST_S_C_MODBEG 188 /* Beginning of module */
+#define DST_S_C_MODEND 189 /* End of module */
+#define DST_S_C_RTNBEG 190 /* Beginning of routine */
+#define DST_S_C_RTNEND 191 /* End of routine */
+#define DST_S_C_DELTA_PC_W 1 /* Incr PC */
+#define DST_S_C_INCR_LINUM 2 /* Incr Line # */
+#define DST_S_C_INCR_LINUM_W 3 /* Incr Line # */
+#define DST_S_C_SET_LINUM_INCR 4
+#define DST_S_C_SET_LINUM_INCR_W 5
+#define DST_S_C_RESET_LINUM_INCR 6
+#define DST_S_C_BEG_STMT_MODE 7
+#define DST_S_C_END_STMT_MODE 8
+#define DST_S_C_SET_LINE_NUM 9 /* Set Line # */
+#define DST_S_C_SET_PC 10
+#define DST_S_C_SET_PC_W 11
+#define DST_S_C_SET_PC_L 12
+#define DST_S_C_SET_STMTNUM 13
+#define DST_S_C_TERM 14 /* End of lines */
+#define DST_S_C_TERM_W 15 /* End of lines */
+#define DST_S_C_SET_ABS_PC 16 /* Set PC */
+#define DST_S_C_DELTA_PC_L 17 /* Incr PC */
+#define DST_S_C_INCR_LINUM_L 18 /* Incr Line # */
+#define DST_S_C_SET_LINUM_B 19 /* Set Line # */
+#define DST_S_C_SET_LINUM_L 20 /* Set Line # */
+#define DST_S_C_TERM_L 21 /* End of lines */
+/* these are used with DST_S_C_SOURCE */
+#define DST_S_C_SRC_DECLFILE 1 /* Declare source file */
+#define DST_S_C_SRC_SETFILE 2 /* Set source file */
+#define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value */
+#define DST_S_C_SRC_SETREC_W 4 /* Set record, word value */
+#define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter */
+#define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter */
+#define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record */
+/* the following are the codes for the various data types. Anything not on
+ * the list is included under 'advanced_type'
+ */
+#define DBG_S_C_UCHAR 0x02
+#define DBG_S_C_USINT 0x03
+#define DBG_S_C_ULINT 0x04
+#define DBG_S_C_UQUAD 0x05
+#define DBG_S_C_SCHAR 0x06
+#define DBG_S_C_SSINT 0x07
+#define DBG_S_C_SLINT 0x08
+#define DBG_S_C_SQUAD 0x09
+#define DBG_S_C_REAL4 0x0a
+#define DBG_S_C_REAL8 0x0b /* D_float double */
+#define DBG_S_C_COMPLX4 0x0c /* 2xF_float complex float */
+#define DBG_S_C_COMPLX8 0x0d /* 2xD_float complex double */
+#define DBG_S_C_REAL8_G 0x1b /* G_float double */
+#define DBG_S_C_COMPLX8_G 0x1d /* 2xG_float complex double */
+#define DBG_S_C_FUNCTION_ADDR 0x17
+#define DBG_S_C_ADVANCED_TYPE 0xa3
+/* Some of these are just for future reference. [pr]
+ */
+#define DBG_S_C_UBITA 0x01 /* unsigned, aligned bit field */
+#define DBG_S_C_UBITU 0x22 /* unsigned, unaligned bit field */
+#define DBG_S_C_SBITA 0x29 /* signed, aligned bit field */
+#define DBG_S_C_SBITU 0x2a /* signed, unaligned bit field */
+#define DBG_S_C_CSTRING 0x2e /* asciz ('\0' terminated) string */
+#define DBG_S_C_WCHAR 0x38 /* wchar_t */
+/* These are descriptor class codes.
+ */
+#define DSC_K_CLASS_S 0x01 /* static (fixed length) */
+#define DSC_K_CLASS_D 0x02 /* dynamic string (not via malloc!) */
+#define DSC_K_CLASS_A 0x04 /* array */
+#define DSC_K_CLASS_UBS 0x0d /* unaligned bit string */
+/* These are the codes that are used to generate the definitions of struct
+ * union and enum records
+ */
+#define DBG_S_C_ENUM_ITEM 0xa4
+#define DBG_S_C_ENUM_START 0xa5
+#define DBG_S_C_ENUM_END 0xa6
+#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */
+#define DBG_S_C_STRUCT_START 0xab
+#define DBG_S_C_STRUCT_END 0xac
+#define DST_K_TYPSPEC 0xaf /* type specification */
+/* These codes are used in the generation of the symbol definition records
+ */
+#define DST_K_VFLAGS_NOVAL 0x80 /* struct definition only */
+#define DST_K_VFLAGS_DSC 0xfa /* descriptor used */
+#define DST_K_VFLAGS_TVS 0xfb /* trailing value specified */
+#define DST_K_VS_FOLLOWS 0xfd /* value spec follows */
+#define DST_K_VFLAGS_BITOFFS 0xff /* value contains bit offset */
+#define DST_K_VALKIND_LITERAL 0
+#define DST_K_VALKIND_ADDR 1
+#define DST_K_VALKIND_DESC 2
+#define DST_K_VALKIND_REG 3
+#define DST_K_REG_VAX_AP 0x0c /* R12 */
+#define DST_K_REG_VAX_FP 0x0d /* R13 */
+#define DST_K_REG_VAX_SP 0x0e /* R14 */
+#define DST_V_VALKIND 0 /* offset of valkind field */
+#define DST_V_INDIRECT 2 /* offset to indirect bit */
+#define DST_V_DISP 3 /* offset to displacement bit */
+#define DST_V_REGNUM 4 /* offset to register number */
+#define DST_M_INDIRECT (1<<DST_V_INDIRECT)
+#define DST_M_DISP (1<<DST_V_DISP)
+#define DBG_C_FUNCTION_PARAM /* 0xc9 */ \
+ (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_AP<<DST_V_REGNUM))
+#define DBG_C_LOCAL_SYM /* 0xd9 */ \
+ (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_FP<<DST_V_REGNUM))
+/* Kinds of value specifications
+ */
+#define DST_K_VS_ALLOC_SPLIT 3 /* split lifetime */
+/* Kinds of type specifications
+ */
+#define DST_K_TS_ATOM 0x01 /* atomic type specification */
+#define DST_K_TS_DSC 0x02 /* descriptor type spec */
+#define DST_K_TS_IND 0x03 /* indirect type specification */
+#define DST_K_TS_TPTR 0x04 /* typed pointer type spec */
+#define DST_K_TS_PTR 0x05 /* pointer type spec */
+#define DST_K_TS_ARRAY 0x07 /* array type spec */
+#define DST_K_TS_NOV_LENG 0x0e /* novel length type spec */
+/* These are the codes that are used in the suffix records to determine the
+ * actual data type
+ */
+#define DBG_S_C_BASIC DST_K_TS_ATOM
+#define DBG_S_C_BASIC_ARRAY DST_K_TS_DSC
+#define DBG_S_C_STRUCT DST_K_TS_IND
+#define DBG_S_C_POINTER DST_K_TS_TPTR
+#define DBG_S_C_VOID DST_K_TS_PTR
+#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
+
+#endif /* WANT_VMS_OBJ_DEFS */
+
+/* end of obj-vms.h */
diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c
new file mode 100644
index 00000000000..600fec58857
--- /dev/null
+++ b/gas/config/tc-a29k.c
@@ -0,0 +1,1296 @@
+/* tc-a29k.c -- Assemble for the AMD 29000.
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* John Gilmore has reorganized this module somewhat, to make it easier
+ to convert it to new machines' assemblers as desired. There was too
+ much bloody rewriting required before. There still probably is. */
+
+#include <ctype.h>
+#include "as.h"
+
+#include "opcode/a29k.h"
+
+/* Make it easier to clone this machine desc into another one. */
+#define machine_opcode a29k_opcode
+#define machine_opcodes a29k_opcodes
+#define machine_ip a29k_ip
+#define machine_it a29k_it
+
+#define IMMEDIATE_BIT 0x01000000 /* Turns RB into Immediate */
+#define ABSOLUTE_BIT 0x01000000 /* Turns PC-relative to Absolute */
+#define CE_BIT 0x00800000 /* Coprocessor enable in LOAD */
+#define UI_BIT 0x00000080 /* Unsigned integer in CONVERT */
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+struct machine_it
+ {
+ char *error;
+ unsigned long opcode;
+ struct nlist *nlistp;
+ expressionS exp;
+ int pcrel;
+ int reloc_offset; /* Offset of reloc within insn */
+
+ int reloc;
+ }
+the_insn;
+
+static void machine_ip PARAMS ((char *str));
+/* static void print_insn PARAMS ((struct machine_it *insn)); */
+#ifndef OBJ_COFF
+static void s_data1 PARAMS ((void));
+static void s_use PARAMS ((int));
+#endif
+
+const pseudo_typeS
+md_pseudo_table[] =
+{
+ {"align", s_align_bytes, 4},
+ {"block", s_space, 0},
+ {"cputype", s_ignore, 0}, /* CPU as 29000 or 29050 */
+ {"reg", s_lsym, 0}, /* Register equate, same as equ */
+ {"space", s_ignore, 0}, /* Listing control */
+ {"sect", s_ignore, 0}, /* Creation of coff sections */
+#ifndef OBJ_COFF
+ /* We can do this right with coff. */
+ {"use", s_use, 0},
+#endif
+ {"word", cons, 4},
+ {NULL, 0, 0},
+};
+
+#if defined(BFD_HEADERS)
+#ifdef RELSZ
+const int md_reloc_size = RELSZ; /* Coff headers */
+#else
+const int md_reloc_size = 12; /* something else headers */
+#endif
+#else
+const int md_reloc_size = 12; /* Not bfdized*/
+#endif
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = ";";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments like this one will always work */
+const char line_comment_chars[] = "#";
+
+/* We needed an unused char for line separation to work around the
+ lack of macros, using sed and such. */
+const char line_separator_chars[] = "@";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c. Ideally it shouldn't have to know about it at
+ all, but nothing is ideal around here. */
+
+/*
+ * anull bit - causes the branch delay slot instructions to not be executed
+ */
+#define ANNUL (1 << 29)
+
+#ifndef OBJ_COFF
+
+static void
+s_use (ignore)
+ int ignore;
+{
+ if (strncmp (input_line_pointer, ".text", 5) == 0)
+ {
+ input_line_pointer += 5;
+ s_text (0);
+ return;
+ }
+ if (strncmp (input_line_pointer, ".data", 5) == 0)
+ {
+ input_line_pointer += 5;
+ s_data (0);
+ return;
+ }
+ if (strncmp (input_line_pointer, ".data1", 6) == 0)
+ {
+ input_line_pointer += 6;
+ s_data1 ();
+ return;
+ }
+ /* Literals can't go in the text segment because you can't read from
+ instruction memory on some 29k's. So, into initialized data. */
+ if (strncmp (input_line_pointer, ".lit", 4) == 0)
+ {
+ input_line_pointer += 4;
+ subseg_set (SEG_DATA, 200);
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ as_bad (_("Unknown segment type"));
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_data1 ()
+{
+ subseg_set (SEG_DATA, 1);
+ demand_empty_rest_of_line ();
+}
+
+#endif /* OBJ_COFF */
+
+/* Install symbol definition that maps REGNAME to REGNO.
+ FIXME-SOON: These are not recognized in mixed case. */
+
+static void
+insert_sreg (regname, regnum)
+ char *regname;
+ int regnum;
+{
+ /* FIXME-SOON, put something in these syms so they won't be output
+ to the symbol table of the resulting object file. */
+
+ /* Must be large enough to hold the names of the special registers. */
+ char buf[80];
+ int i;
+
+ symbol_table_insert (symbol_new (regname, SEG_REGISTER, (valueT) regnum,
+ &zero_address_frag));
+ for (i = 0; regname[i]; i++)
+ buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
+ buf[i] = '\0';
+
+ symbol_table_insert (symbol_new (buf, SEG_REGISTER, (valueT) regnum,
+ &zero_address_frag));
+}
+
+/* Install symbol definitions for assorted special registers.
+ See ASM29K Ref page 2-9. */
+
+void
+define_some_regs ()
+{
+#define SREG 256
+
+ /* Protected special-purpose register names */
+ insert_sreg ("vab", SREG + 0);
+ insert_sreg ("ops", SREG + 1);
+ insert_sreg ("cps", SREG + 2);
+ insert_sreg ("cfg", SREG + 3);
+ insert_sreg ("cha", SREG + 4);
+ insert_sreg ("chd", SREG + 5);
+ insert_sreg ("chc", SREG + 6);
+ insert_sreg ("rbp", SREG + 7);
+ insert_sreg ("tmc", SREG + 8);
+ insert_sreg ("tmr", SREG + 9);
+ insert_sreg ("pc0", SREG + 10);
+ insert_sreg ("pc1", SREG + 11);
+ insert_sreg ("pc2", SREG + 12);
+ insert_sreg ("mmu", SREG + 13);
+ insert_sreg ("lru", SREG + 14);
+
+ /* Additional protected special-purpose registers for the 29050 */
+ insert_sreg ("rsn", SREG + 15);
+ insert_sreg ("rma0", SREG + 16);
+ insert_sreg ("rmc0", SREG + 17);
+ insert_sreg ("rma1", SREG + 18);
+ insert_sreg ("rmc1", SREG + 19);
+ insert_sreg ("spc0", SREG + 20);
+ insert_sreg ("spc1", SREG + 21);
+ insert_sreg ("spc2", SREG + 22);
+ insert_sreg ("iba0", SREG + 23);
+ insert_sreg ("ibc0", SREG + 24);
+ insert_sreg ("iba1", SREG + 25);
+ insert_sreg ("ibc1", SREG + 26);
+
+ /* Additional registers for the 29040. */
+ insert_sreg ("dba", SREG + 27);
+ insert_sreg ("dbc", SREG + 28);
+ insert_sreg ("cir", SREG + 29);
+ insert_sreg ("cdr", SREG + 30);
+
+ /* Unprotected special-purpose register names */
+ insert_sreg ("ipc", SREG + 128);
+ insert_sreg ("ipa", SREG + 129);
+ insert_sreg ("ipb", SREG + 130);
+ insert_sreg ("q", SREG + 131);
+ insert_sreg ("alu", SREG + 132);
+ insert_sreg ("bp", SREG + 133);
+ insert_sreg ("fc", SREG + 134);
+ insert_sreg ("cr", SREG + 135);
+ insert_sreg ("fpe", SREG + 160);
+ insert_sreg ("inte", SREG + 161);
+ insert_sreg ("fps", SREG + 162);
+ /* "", SREG+163); Reserved */
+ insert_sreg ("exop", SREG + 164);
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc., that the MD part of the assembler will
+ need. */
+void
+md_begin ()
+{
+ register const char *retval = NULL;
+ int lose = 0;
+ register int skipnext = 0;
+ register unsigned int i;
+ register char *strend, *strend2;
+
+ /* Hash up all the opcodes for fast use later. */
+
+ op_hash = hash_new ();
+
+ for (i = 0; i < num_opcodes; i++)
+ {
+ const char *name = machine_opcodes[i].name;
+
+ if (skipnext)
+ {
+ skipnext = 0;
+ continue;
+ }
+
+ /* Hack to avoid multiple opcode entries. We pre-locate all the
+ variations (b/i field and P/A field) and handle them. */
+
+ if (!strcmp (name, machine_opcodes[i + 1].name))
+ {
+ if ((machine_opcodes[i].opcode & 0x01000000) != 0
+ || (machine_opcodes[i + 1].opcode & 0x01000000) == 0
+ || ((machine_opcodes[i].opcode | 0x01000000)
+ != machine_opcodes[i + 1].opcode))
+ goto bad_table;
+ strend = machine_opcodes[i].args + strlen (machine_opcodes[i].args) - 1;
+ strend2 = machine_opcodes[i + 1].args + strlen (machine_opcodes[i + 1].args) - 1;
+ switch (*strend)
+ {
+ case 'b':
+ if (*strend2 != 'i')
+ goto bad_table;
+ break;
+ case 'P':
+ if (*strend2 != 'A')
+ goto bad_table;
+ break;
+ default:
+ bad_table:
+ fprintf (stderr, "internal error: can't handle opcode %s\n",
+ name);
+ lose = 1;
+ }
+
+ /* OK, this is an i/b or A/P pair. We skip the
+ higher-valued one, and let the code for operand checking
+ handle OR-ing in the bit. */
+ skipnext = 1;
+ }
+
+ retval = hash_insert (op_hash, name, (PTR) &machine_opcodes[i]);
+ if (retval != NULL)
+ {
+ fprintf (stderr, "internal error: can't hash `%s': %s\n",
+ machine_opcodes[i].name, retval);
+ lose = 1;
+ }
+ }
+
+ if (lose)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ define_some_regs ();
+}
+
+/* Assemble a single instruction. Its label has already been handled
+ by the generic front end. We just parse opcode and operands, and
+ produce the bytes of data and relocation. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *toP;
+
+ know (str);
+ machine_ip (str);
+ toP = frag_more (4);
+ /* put out the opcode */
+ md_number_to_chars (toP, the_insn.opcode, 4);
+
+ /* put out the symbol-dependent stuff */
+ if (the_insn.reloc != NO_RELOC)
+ {
+ fix_new_exp (frag_now,
+ (toP - frag_now->fr_literal + the_insn.reloc_offset),
+ 4, /* size */
+ &the_insn.exp,
+ the_insn.pcrel,
+ the_insn.reloc);
+ }
+}
+
+char *
+parse_operand (s, operandp, opt)
+ char *s;
+ expressionS *operandp;
+ int opt;
+{
+ char *save = input_line_pointer;
+ char *new;
+
+ input_line_pointer = s;
+ expression (operandp);
+ if (operandp->X_op == O_absent && ! opt)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+/* Instruction parsing. Takes a string containing the opcode.
+ Operands are at input_line_pointer. Output is in the_insn.
+ Warnings or errors are generated. */
+
+static void
+machine_ip (str)
+ char *str;
+{
+ char *s;
+ const char *args;
+ struct machine_opcode *insn;
+ char *argsStart;
+ unsigned long opcode;
+ expressionS the_operand;
+ expressionS *operand = &the_operand;
+ unsigned int reg;
+
+ /* Must handle `div0' opcode. */
+ s = str;
+ if (isalpha (*s))
+ for (; isalnum (*s); ++s)
+ if (isupper (*s))
+ *s = tolower (*s);
+
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case ' ': /* FIXME-SOMEDAY more whitespace */
+ *s++ = '\0';
+ break;
+
+ default:
+ as_bad (_("Unknown opcode: `%s'"), str);
+ return;
+ }
+ if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
+ {
+ as_bad (_("Unknown opcode `%s'."), str);
+ return;
+ }
+ argsStart = s;
+ opcode = insn->opcode;
+ memset (&the_insn, '\0', sizeof (the_insn));
+ the_insn.reloc = NO_RELOC;
+
+ /* Build the opcode, checking as we go to make sure that the
+ operands match.
+
+ If an operand matches, we modify the_insn or opcode appropriately,
+ and do a "continue". If an operand fails to match, we "break". */
+
+ if (insn->args[0] != '\0')
+ {
+ /* Prime the pump. */
+ s = parse_operand (s, operand, insn->args[0] == 'I');
+ }
+
+ for (args = insn->args;; ++args)
+ {
+ switch (*args)
+ {
+
+ case '\0': /* end of args */
+ if (*s == '\0')
+ {
+ /* We are truly done. */
+ the_insn.opcode = opcode;
+ return;
+ }
+ as_bad (_("Too many operands: %s"), s);
+ break;
+
+ case ',': /* Must match a comma */
+ if (*s++ == ',')
+ {
+ /* Parse next operand. */
+ s = parse_operand (s, operand, args[1] == 'I');
+ continue;
+ }
+ break;
+
+ case 'v': /* Trap numbers (immediate field) */
+ if (operand->X_op == O_constant)
+ {
+ if (operand->X_add_number < 256)
+ {
+ opcode |= (operand->X_add_number << 16);
+ continue;
+ }
+ else
+ {
+ as_bad (_("Immediate value of %ld is too large"),
+ (long) operand->X_add_number);
+ continue;
+ }
+ }
+ the_insn.reloc = RELOC_8;
+ the_insn.reloc_offset = 1; /* BIG-ENDIAN Byte 1 of insn */
+ the_insn.exp = *operand;
+ continue;
+
+ case 'b': /* A general register or 8-bit immediate */
+ case 'i':
+ /* We treat the two cases identically since we mashed
+ them together in the opcode table. */
+ if (operand->X_op == O_register)
+ goto general_reg;
+
+ /* Make sure the 'i' case really exists. */
+ if ((insn->opcode | IMMEDIATE_BIT) != (insn + 1)->opcode)
+ break;
+
+ opcode |= IMMEDIATE_BIT;
+ if (operand->X_op == O_constant)
+ {
+ if (operand->X_add_number < 256)
+ {
+ opcode |= operand->X_add_number;
+ continue;
+ }
+ else
+ {
+ as_bad (_("Immediate value of %ld is too large"),
+ (long) operand->X_add_number);
+ continue;
+ }
+ }
+ the_insn.reloc = RELOC_8;
+ the_insn.reloc_offset = 3; /* BIG-ENDIAN Byte 3 of insn */
+ the_insn.exp = *operand;
+ continue;
+
+ case 'a': /* next operand must be a register */
+ case 'c':
+ general_reg:
+ /* lrNNN or grNNN or %%expr or a user-def register name */
+ if (operand->X_op != O_register)
+ break; /* Only registers */
+ know (operand->X_add_symbol == 0);
+ know (operand->X_op_symbol == 0);
+ reg = operand->X_add_number;
+ if (reg >= SREG)
+ break; /* No special registers */
+
+ /* Got the register, now figure out where it goes in the
+ opcode. */
+ switch (*args)
+ {
+ case 'a':
+ opcode |= reg << 8;
+ continue;
+
+ case 'b':
+ case 'i':
+ opcode |= reg;
+ continue;
+
+ case 'c':
+ opcode |= reg << 16;
+ continue;
+ }
+ as_fatal (_("failed sanity check."));
+ break;
+
+ case 'x': /* 16 bit constant, zero-extended */
+ case 'X': /* 16 bit constant, one-extended */
+ if (operand->X_op == O_constant)
+ {
+ opcode |= (operand->X_add_number & 0xFF) << 0 |
+ ((operand->X_add_number & 0xFF00) << 8);
+ continue;
+ }
+ the_insn.reloc = RELOC_CONST;
+ the_insn.exp = *operand;
+ continue;
+
+ case 'h':
+ if (operand->X_op == O_constant)
+ {
+ opcode |= (operand->X_add_number & 0x00FF0000) >> 16 |
+ (((unsigned long) operand->X_add_number
+ /* avoid sign ext */ & 0xFF000000) >> 8);
+ continue;
+ }
+ the_insn.reloc = RELOC_CONSTH;
+ the_insn.exp = *operand;
+ continue;
+
+ case 'P': /* PC-relative jump address */
+ case 'A': /* Absolute jump address */
+ /* These two are treated together since we folded the
+ opcode table entries together. */
+ if (operand->X_op == O_constant)
+ {
+ /* Make sure the 'A' case really exists. */
+ if ((insn->opcode | ABSOLUTE_BIT) != (insn + 1)->opcode)
+ break;
+ {
+ bfd_vma v, mask;
+ mask = 0x1ffff;
+ v = operand->X_add_number & ~ mask;
+ if (v)
+ as_bad ("call/jmp target out of range");
+ }
+ opcode |= ABSOLUTE_BIT |
+ (operand->X_add_number & 0x0003FC00) << 6 |
+ ((operand->X_add_number & 0x000003FC) >> 2);
+ continue;
+ }
+ the_insn.reloc = RELOC_JUMPTARG;
+ the_insn.exp = *operand;
+ the_insn.pcrel = 1; /* Assume PC-relative jump */
+ /* FIXME-SOON, Do we figure out whether abs later, after
+ know sym val? */
+ continue;
+
+ case 'e': /* Coprocessor enable bit for LOAD/STORE insn */
+ if (operand->X_op == O_constant)
+ {
+ if (operand->X_add_number == 0)
+ continue;
+ if (operand->X_add_number == 1)
+ {
+ opcode |= CE_BIT;
+ continue;
+ }
+ }
+ break;
+
+ case 'n': /* Control bits for LOAD/STORE instructions */
+ if (operand->X_op == O_constant &&
+ operand->X_add_number < 128)
+ {
+ opcode |= (operand->X_add_number << 16);
+ continue;
+ }
+ break;
+
+ case 's': /* Special register number */
+ if (operand->X_op != O_register)
+ break; /* Only registers */
+ if (operand->X_add_number < SREG)
+ break; /* Not a special register */
+ opcode |= (operand->X_add_number & 0xFF) << 8;
+ continue;
+
+ case 'u': /* UI bit of CONVERT */
+ if (operand->X_op == O_constant)
+ {
+ if (operand->X_add_number == 0)
+ continue;
+ if (operand->X_add_number == 1)
+ {
+ opcode |= UI_BIT;
+ continue;
+ }
+ }
+ break;
+
+ case 'r': /* RND bits of CONVERT */
+ if (operand->X_op == O_constant &&
+ operand->X_add_number < 8)
+ {
+ opcode |= operand->X_add_number << 4;
+ continue;
+ }
+ break;
+
+ case 'I': /* ID bits of INV and IRETINV. */
+ /* This operand is optional. */
+ if (operand->X_op == O_absent)
+ continue;
+ else if (operand->X_op == O_constant
+ && operand->X_add_number < 4)
+ {
+ opcode |= operand->X_add_number << 16;
+ continue;
+ }
+ break;
+
+ case 'd': /* FD bits of CONVERT */
+ if (operand->X_op == O_constant &&
+ operand->X_add_number < 4)
+ {
+ opcode |= operand->X_add_number << 2;
+ continue;
+ }
+ break;
+
+
+ case 'f': /* FS bits of CONVERT */
+ if (operand->X_op == O_constant &&
+ operand->X_add_number < 4)
+ {
+ opcode |= operand->X_add_number << 0;
+ continue;
+ }
+ break;
+
+ case 'C':
+ if (operand->X_op == O_constant &&
+ operand->X_add_number < 4)
+ {
+ opcode |= operand->X_add_number << 16;
+ continue;
+ }
+ break;
+
+ case 'F':
+ if (operand->X_op == O_constant &&
+ operand->X_add_number < 16)
+ {
+ opcode |= operand->X_add_number << 18;
+ continue;
+ }
+ break;
+
+ default:
+ BAD_CASE (*args);
+ }
+ /* Types or values of args don't match. */
+ as_bad ("Invalid operands");
+ return;
+ }
+}
+
+/* This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant
+ of type type, and store the appropriate bytes in *litP. The number
+ of LITTLENUMS emitted is stored in *sizeP . An error message is
+ returned, or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return "Bad call to MD_ATOF()";
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+/*
+ * Write out big-endian.
+ */
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ fixP->fx_addnumber = val; /* Remember value for emit_reloc */
+
+
+ know (fixP->fx_size == 4);
+ know (fixP->fx_r_type < NO_RELOC);
+
+ /* This is a hack. There should be a better way to handle this. */
+ if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy)
+ {
+ val += fixP->fx_where + fixP->fx_frag->fr_address;
+ }
+
+ switch (fixP->fx_r_type)
+ {
+
+ case RELOC_32:
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case RELOC_8:
+ buf[0] = val;
+ break;
+
+ case RELOC_WDISP30:
+ val = (val >>= 2) + 1;
+ buf[0] |= (val >> 24) & 0x3f;
+ buf[1] = (val >> 16);
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case RELOC_HI22:
+ buf[1] |= (val >> 26) & 0x3f;
+ buf[2] = val >> 18;
+ buf[3] = val >> 10;
+ break;
+
+ case RELOC_LO10:
+ buf[2] |= (val >> 8) & 0x03;
+ buf[3] = val;
+ break;
+
+ case RELOC_BASE13:
+ buf[2] |= (val >> 8) & 0x1f;
+ buf[3] = val;
+ break;
+
+ case RELOC_WDISP22:
+ val = (val >>= 2) + 1;
+ /* FALLTHROUGH */
+ case RELOC_BASE22:
+ buf[1] |= (val >> 16) & 0x3f;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case RELOC_JUMPTARG: /* 00XX00XX pattern in a word */
+ if (!fixP->fx_done)
+ {
+ /* The linker tries to support both AMD and old GNU style
+ R_IREL relocs. That means that if the addend is exactly
+ the negative of the address within the section, the
+ linker will not handle it correctly. */
+ if (fixP->fx_pcrel
+ && val != 0
+ && val == - (fixP->fx_frag->fr_address + fixP->fx_where))
+ as_bad_where
+ (fixP->fx_file, fixP->fx_line,
+ "the linker will not handle this relocation correctly");
+ }
+ else if (fixP->fx_pcrel)
+ {
+ long v = val >> 17;
+ if (v != 0 && v != -1)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "call/jmp target out of range");
+ }
+ else
+ /* this case was supposed to be handled in machine_ip */
+ abort ();
+ buf[1] = val >> 10; /* Holds bits 0003FFFC of address */
+ buf[3] = val >> 2;
+ break;
+
+ case RELOC_CONST: /* 00XX00XX pattern in a word */
+ buf[1] = val >> 8; /* Holds bits 0000XXXX */
+ buf[3] = val;
+ break;
+
+ case RELOC_CONSTH: /* 00XX00XX pattern in a word */
+ buf[1] = val >> 24; /* Holds bits XXXX0000 */
+ buf[3] = val >> 16;
+ break;
+
+ case NO_RELOC:
+ default:
+ as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type);
+ break;
+ }
+}
+
+#ifdef OBJ_COFF
+short
+tc_coff_fix2rtype (fixP)
+ fixS *fixP;
+{
+
+ switch (fixP->fx_r_type)
+ {
+ case RELOC_32:
+ return (R_WORD);
+ case RELOC_8:
+ return (R_BYTE);
+ case RELOC_CONST:
+ return (R_ILOHALF);
+ case RELOC_CONSTH:
+ return (R_IHIHALF);
+ case RELOC_JUMPTARG:
+ return (R_IREL);
+ default:
+ printf (_("need %o3\n"), fixP->fx_r_type);
+ abort ();
+ } /* switch on type */
+
+ return (0);
+}
+
+#endif /* OBJ_COFF */
+
+/* should never be called for 29k */
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ register fragS *fragP;
+{
+ as_fatal (_("a29k_convert_frag\n"));
+}
+
+/* should never be called for a29k */
+int
+md_estimate_size_before_relax (fragP, segtype)
+ register fragS *fragP;
+ segT segtype;
+{
+ as_fatal (_("a29k_estimate_size_before_relax\n"));
+ return 0;
+}
+
+#if 0
+/* for debugging only */
+static void
+print_insn (insn)
+ struct machine_it *insn;
+{
+ char *Reloc[] =
+ {
+ "RELOC_8",
+ "RELOC_16",
+ "RELOC_32",
+ "RELOC_DISP8",
+ "RELOC_DISP16",
+ "RELOC_DISP32",
+ "RELOC_WDISP30",
+ "RELOC_WDISP22",
+ "RELOC_HI22",
+ "RELOC_22",
+ "RELOC_13",
+ "RELOC_LO10",
+ "RELOC_SFA_BASE",
+ "RELOC_SFA_OFF13",
+ "RELOC_BASE10",
+ "RELOC_BASE13",
+ "RELOC_BASE22",
+ "RELOC_PC10",
+ "RELOC_PC22",
+ "RELOC_JMP_TBL",
+ "RELOC_SEGOFF16",
+ "RELOC_GLOB_DAT",
+ "RELOC_JMP_SLOT",
+ "RELOC_RELATIVE",
+ "NO_RELOC"
+ };
+
+ if (insn->error)
+ {
+ fprintf (stderr, "ERROR: %s\n");
+ }
+ fprintf (stderr, "opcode=0x%08x\n", insn->opcode);
+ fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
+ fprintf (stderr, "exp = {\n");
+ fprintf (stderr, "\t\tX_add_symbol = %s\n",
+ insn->exp.X_add_symbol ?
+ (S_GET_NAME (insn->exp.X_add_symbol) ?
+ S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
+ fprintf (stderr, "\t\tX_op_symbol = %s\n",
+ insn->exp.X_op_symbol ?
+ (S_GET_NAME (insn->exp.X_op_symbol) ?
+ S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
+ fprintf (stderr, "\t\tX_add_number = %d\n",
+ insn->exp.X_add_number);
+ fprintf (stderr, "}\n");
+}
+
+#endif
+
+/* Translate internal representation of relocation info to target format.
+
+ On sparc/29k: first 4 bytes are normal unsigned long address, next three
+ bytes are index, most sig. byte first. Byte 7 is broken up with
+ bit 7 as external, bits 6 & 5 unused, and the lower
+ five bits as relocation type. Next 4 bytes are long addend. */
+/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
+
+#ifdef OBJ_AOUT
+
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ long r_symbolnum;
+
+ know (fixP->fx_r_type < NO_RELOC);
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ where[4] = (r_symbolnum >> 16) & 0x0ff;
+ where[5] = (r_symbolnum >> 8) & 0x0ff;
+ where[6] = r_symbolnum & 0x0ff;
+ where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
+ /* Also easy */
+ md_number_to_chars (&where[8], fixP->fx_addnumber, 4);
+}
+
+#endif /* OBJ_AOUT */
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+
+/* This is called when a line is unrecognized. This is used to handle
+ definitions of a29k style local labels. */
+
+int
+a29k_unrecognized_line (c)
+ int c;
+{
+ int lab;
+ char *s;
+
+ if (c != '$'
+ || ! isdigit ((unsigned char) input_line_pointer[0]))
+ return 0;
+
+ s = input_line_pointer;
+
+ lab = 0;
+ while (isdigit ((unsigned char) *s))
+ {
+ lab = lab * 10 + *s - '0';
+ ++s;
+ }
+
+ if (*s != ':')
+ {
+ /* Not a label definition. */
+ return 0;
+ }
+
+ if (dollar_label_defined (lab))
+ {
+ as_bad (_("label \"$%d\" redefined"), lab);
+ return 0;
+ }
+
+ define_dollar_label (lab);
+ colon (dollar_label_name (lab, 0));
+ input_line_pointer = s + 1;
+
+ return 1;
+}
+
+/* Default the values of symbols known that should be "predefined". We
+ don't bother to predefine them unless you actually use one, since there
+ are a lot of them. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ long regnum;
+ char testbuf[5 + /*SLOP*/ 5];
+
+ if (name[0] == 'g' || name[0] == 'G'
+ || name[0] == 'l' || name[0] == 'L'
+ || name[0] == 's' || name[0] == 'S')
+ {
+ /* Perhaps a global or local register name */
+ if (name[1] == 'r' || name[1] == 'R')
+ {
+ long maxreg;
+
+ /* Parse the number, make sure it has no extra zeroes or
+ trailing chars. */
+ regnum = atol (&name[2]);
+
+ if (name[0] == 's' || name[0] == 'S')
+ maxreg = 255;
+ else
+ maxreg = 127;
+ if (regnum > maxreg)
+ return NULL;
+
+ sprintf (testbuf, "%ld", regnum);
+ if (strcmp (testbuf, &name[2]) != 0)
+ return NULL; /* gr007 or lr7foo or whatever */
+
+ /* We have a wiener! Define and return a new symbol for it. */
+ if (name[0] == 'l' || name[0] == 'L')
+ regnum += 128;
+ else if (name[0] == 's' || name[0] == 'S')
+ regnum += SREG;
+ return (symbol_new (name, SEG_REGISTER, (valueT) regnum,
+ &zero_address_frag));
+ }
+ }
+
+ return NULL;
+}
+
+/* Parse an operand that is machine-specific. */
+
+void
+md_operand (expressionP)
+ expressionS *expressionP;
+{
+
+ if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%')
+ {
+ /* We have a numeric register expression. No biggy. */
+ input_line_pointer += 2; /* Skip %% */
+ (void) expression (expressionP);
+ if (expressionP->X_op != O_constant
+ || expressionP->X_add_number > 255)
+ as_bad (_("Invalid expression after %%%%\n"));
+ expressionP->X_op = O_register;
+ }
+ else if (input_line_pointer[0] == '&')
+ {
+ /* We are taking the 'address' of a register...this one is not
+ in the manual, but it *is* in traps/fpsymbol.h! What they
+ seem to want is the register number, as an absolute number. */
+ input_line_pointer++; /* Skip & */
+ (void) expression (expressionP);
+ if (expressionP->X_op != O_register)
+ as_bad (_("Invalid register in & expression"));
+ else
+ expressionP->X_op = O_constant;
+ }
+ else if (input_line_pointer[0] == '$'
+ && isdigit ((unsigned char) input_line_pointer[1]))
+ {
+ long lab;
+ char *name;
+ symbolS *sym;
+
+ /* This is a local label. */
+ ++input_line_pointer;
+ lab = (long) get_absolute_expression ();
+ if (dollar_label_defined (lab))
+ {
+ name = dollar_label_name (lab, 0);
+ sym = symbol_find (name);
+ }
+ else
+ {
+ name = dollar_label_name (lab, 1);
+ sym = symbol_find_or_make (name);
+ }
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = sym;
+ expressionP->X_add_number = 0;
+ }
+ else if (input_line_pointer[0] == '$')
+ {
+ char *s;
+ char type;
+ int fieldnum, fieldlimit;
+ LITTLENUM_TYPE floatbuf[8];
+
+ /* $float(), $doubleN(), or $extendN() convert floating values
+ to integers. */
+
+ s = input_line_pointer;
+
+ ++s;
+
+ fieldnum = 0;
+ if (strncmp (s, "double", sizeof "double" - 1) == 0)
+ {
+ s += sizeof "double" - 1;
+ type = 'd';
+ fieldlimit = 2;
+ }
+ else if (strncmp (s, "float", sizeof "float" - 1) == 0)
+ {
+ s += sizeof "float" - 1;
+ type = 'f';
+ fieldlimit = 1;
+ }
+ else if (strncmp (s, "extend", sizeof "extend" - 1) == 0)
+ {
+ s += sizeof "extend" - 1;
+ type = 'x';
+ fieldlimit = 4;
+ }
+ else
+ {
+ return;
+ }
+
+ if (isdigit (*s))
+ {
+ fieldnum = *s - '0';
+ ++s;
+ }
+ if (fieldnum >= fieldlimit)
+ return;
+
+ SKIP_WHITESPACE ();
+ if (*s != '(')
+ return;
+ ++s;
+ SKIP_WHITESPACE ();
+
+ s = atof_ieee (s, type, floatbuf);
+ if (s == NULL)
+ return;
+ s = s;
+
+ SKIP_WHITESPACE ();
+ if (*s != ')')
+ return;
+ ++s;
+ SKIP_WHITESPACE ();
+
+ input_line_pointer = s;
+ expressionP->X_op = O_constant;
+ expressionP->X_unsigned = 1;
+ expressionP->X_add_number = ((floatbuf[fieldnum * 2]
+ << LITTLENUM_NUMBER_OF_BITS)
+ + floatbuf[fieldnum * 2 + 1]);
+ }
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ return size; /* Byte alignment is fine */
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the 29000, they're relative to the address of the instruction,
+ which we have set up as the address of the fixup too. */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* end of tc-a29k.c */
diff --git a/gas/config/tc-a29k.h b/gas/config/tc-a29k.h
new file mode 100644
index 00000000000..b60f6058257
--- /dev/null
+++ b/gas/config/tc-a29k.h
@@ -0,0 +1,54 @@
+/* tc-a29k.h -- Assemble for the AMD 29000.
+ Copyright (C) 1989, 90, 91, 92, 93, 95, 1998 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#define TC_A29K
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define WORKING_DOT_WORD
+
+#define LEX_DOLLAR 1
+
+#define tc_unrecognized_line(c) a29k_unrecognized_line (c)
+extern int a29k_unrecognized_line PARAMS ((int));
+
+#define tc_headers_hook(a) ; /* not used */
+#define tc_headers_hook(a) ; /* not used */
+#define tc_crawl_symbol_chain(a) ; /* not used */
+#define tc_coff_symbol_emit_hook(a) ; /* not used */
+
+#define AOUT_MACHTYPE 101
+#define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype(fix_ptr)
+#define BFD_ARCH bfd_arch_a29k
+#define COFF_MAGIC SIPFBOMAGIC
+/* Should the reloc be output ?
+ on the 29k, this is true only if there is a symbol attatched.
+ on the h8, this is allways true, since no fixup is done
+*/
+#define TC_COUNT_RELOC(x) (x->fx_addsy)
+#define TC_CONS_RELOC RELOC_32
+
+#define COFF_FLAGS F_AR32W
+#define reloc_type int
+#define NEED_FX_R_TYPE
+
+#define ZERO_BASED_SEGMENTS
+
+/* end of tc-a29k.h */
diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c
new file mode 100644
index 00000000000..568617f74e9
--- /dev/null
+++ b/gas/config/tc-alpha.c
@@ -0,0 +1,4762 @@
+/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
+ Copyright (C) 1989, 93-98, 1999 Free Software Foundation, Inc.
+ Contributed by Carnegie Mellon University, 1993.
+ Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
+ Modified by Ken Raeburn for gas-2.x and ECOFF support.
+ Modified by Richard Henderson for ELF support.
+ Modified by Klaus K"ampf for EVAX (openVMS/Alpha) support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1993 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include "as.h"
+#include "subsegs.h"
+#include "ecoff.h"
+
+#include "opcode/alpha.h"
+
+#ifdef OBJ_ELF
+#include "elf/alpha.h"
+#endif
+
+#include <ctype.h>
+
+
+/* Local types */
+
+#define MAX_INSN_FIXUPS 2
+#define MAX_INSN_ARGS 5
+
+struct alpha_fixup
+{
+ expressionS exp;
+ bfd_reloc_code_real_type reloc;
+};
+
+struct alpha_insn
+{
+ unsigned insn;
+ int nfixups;
+ struct alpha_fixup fixups[MAX_INSN_FIXUPS];
+};
+
+enum alpha_macro_arg
+{
+ MACRO_EOA = 1, MACRO_IR, MACRO_PIR, MACRO_CPIR, MACRO_FPR, MACRO_EXP
+};
+
+struct alpha_macro
+{
+ const char *name;
+ void (*emit) PARAMS ((const expressionS *, int, const PTR));
+ const PTR arg;
+ enum alpha_macro_arg argsets[16];
+};
+
+/* Two extra symbols we want to see in our input. This is a blatent
+ misuse of the expressionS.X_op field. */
+
+#define O_pregister (O_max+1) /* O_register, but in parentheses */
+#define O_cpregister (O_pregister+1) /* + a leading comma */
+
+/* Macros for extracting the type and number of encoded register tokens */
+
+#define is_ir_num(x) (((x) & 32) == 0)
+#define is_fpr_num(x) (((x) & 32) != 0)
+#define regno(x) ((x) & 31)
+
+/* Something odd inherited from the old assembler */
+
+#define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
+#define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
+
+/* Predicates for 16- and 32-bit ranges */
+/* XXX: The non-shift version appears to trigger a compiler bug when
+ cross-assembling from x86 w/ gcc 2.7.2. */
+
+#if 1
+#define range_signed_16(x) \
+ (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
+#define range_signed_32(x) \
+ (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
+#else
+#define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
+ (offsetT)(x) <= (offsetT)0x7FFF)
+#define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
+ (offsetT)(x) <= (offsetT)0x7FFFFFFF)
+#endif
+
+/* Macros for sign extending from 16- and 32-bits. */
+/* XXX: The cast macros will work on all the systems that I care about,
+ but really a predicate should be found to use the non-cast forms. */
+
+#if 1
+#define sign_extend_16(x) ((short)(x))
+#define sign_extend_32(x) ((int)(x))
+#else
+#define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
+#define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
+ ^ 0x80000000) - 0x80000000)
+#endif
+
+/* Macros to build tokens */
+
+#define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
+ (t).X_op = O_register, \
+ (t).X_add_number = (r))
+#define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
+ (t).X_op = O_pregister, \
+ (t).X_add_number = (r))
+#define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
+ (t).X_op = O_cpregister, \
+ (t).X_add_number = (r))
+#define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
+ (t).X_op = O_register, \
+ (t).X_add_number = (r)+32)
+#define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
+ (t).X_op = O_symbol, \
+ (t).X_add_symbol = (s), \
+ (t).X_add_number = (a))
+#define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
+ (t).X_op = O_constant, \
+ (t).X_add_number = (n))
+
+
+/* Prototypes for all local functions */
+
+static int tokenize_arguments PARAMS ((char *, expressionS *, int));
+static const struct alpha_opcode *find_opcode_match
+ PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
+static const struct alpha_macro *find_macro_match
+ PARAMS ((const struct alpha_macro *, const expressionS *, int *));
+static unsigned insert_operand
+ PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
+static void assemble_insn
+ PARAMS ((const struct alpha_opcode *, const expressionS *, int,
+ struct alpha_insn *));
+static void emit_insn PARAMS ((struct alpha_insn *));
+static void assemble_tokens_to_insn
+ PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
+static void assemble_tokens
+ PARAMS ((const char *, const expressionS *, int, int));
+
+static int load_expression
+ PARAMS ((int, const expressionS *, int *, expressionS *));
+
+static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
+static void emit_division PARAMS ((const expressionS *, int, const PTR));
+static void emit_lda PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
+static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
+static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
+static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
+static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
+static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
+static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
+static void emit_stX PARAMS ((const expressionS *, int, const PTR));
+static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
+static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
+static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
+
+static void s_alpha_text PARAMS ((int));
+static void s_alpha_data PARAMS ((int));
+#ifndef OBJ_ELF
+static void s_alpha_comm PARAMS ((int));
+static void s_alpha_rdata PARAMS ((int));
+#endif
+#ifdef OBJ_ECOFF
+static void s_alpha_sdata PARAMS ((int));
+#endif
+#ifdef OBJ_ELF
+static void s_alpha_section PARAMS ((int));
+static void s_alpha_ent PARAMS ((int));
+static void s_alpha_end PARAMS ((int));
+static void s_alpha_mask PARAMS ((int));
+static void s_alpha_frame PARAMS ((int));
+static void s_alpha_prologue PARAMS ((int));
+static void s_alpha_coff_wrapper PARAMS ((int));
+#endif
+#ifdef OBJ_EVAX
+static void s_alpha_section PARAMS ((int));
+#endif
+static void s_alpha_gprel32 PARAMS ((int));
+static void s_alpha_float_cons PARAMS ((int));
+static void s_alpha_proc PARAMS ((int));
+static void s_alpha_set PARAMS ((int));
+static void s_alpha_base PARAMS ((int));
+static void s_alpha_align PARAMS ((int));
+static void s_alpha_stringer PARAMS ((int));
+static void s_alpha_space PARAMS ((int));
+
+static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
+#ifndef OBJ_ELF
+static void select_gp_value PARAMS ((void));
+#endif
+static void alpha_align PARAMS ((int, char *, symbolS *, int));
+
+
+/* Generic assembler global variables which must be defined by all
+ targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+#if 0
+const char FLT_CHARS[] = "dD";
+#else
+/* XXX: Do all of these really get used on the alpha?? */
+char FLT_CHARS[] = "rRsSfFdDxXpP";
+#endif
+
+#ifdef OBJ_EVAX
+const char *md_shortopts = "Fm:g+1h:HG:";
+#else
+const char *md_shortopts = "Fm:gG:";
+#endif
+
+struct option md_longopts[] = {
+#define OPTION_32ADDR (OPTION_MD_BASE)
+ { "32addr", no_argument, NULL, OPTION_32ADDR },
+#define OPTION_RELAX (OPTION_32ADDR+1)
+ { "relax", no_argument, NULL, OPTION_RELAX },
+#ifdef OBJ_ELF
+#define OPTION_MDEBUG (OPTION_RELAX+1)
+#define OPTION_NO_MDEBUG (OPTION_MDEBUG+1)
+ { "mdebug", no_argument, NULL, OPTION_MDEBUG },
+ { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
+#endif
+ { NULL, no_argument, NULL, 0 }
+};
+
+size_t md_longopts_size = sizeof(md_longopts);
+
+
+#ifdef OBJ_EVAX
+#define AXP_REG_R0 0
+#define AXP_REG_R16 16
+#define AXP_REG_R17 17
+#undef AXP_REG_T9
+#define AXP_REG_T9 22
+#undef AXP_REG_T10
+#define AXP_REG_T10 23
+#undef AXP_REG_T11
+#define AXP_REG_T11 24
+#undef AXP_REG_T12
+#define AXP_REG_T12 25
+#define AXP_REG_AI 25
+#undef AXP_REG_FP
+#define AXP_REG_FP 29
+
+#undef AXP_REG_GP
+#define AXP_REG_GP AXP_REG_PV
+#endif /* OBJ_EVAX */
+
+/* The cpu for which we are generating code */
+static unsigned alpha_target = AXP_OPCODE_BASE;
+static const char *alpha_target_name = "<all>";
+
+/* The hash table of instruction opcodes */
+static struct hash_control *alpha_opcode_hash;
+
+/* The hash table of macro opcodes */
+static struct hash_control *alpha_macro_hash;
+
+#ifdef OBJ_ECOFF
+/* The $gp relocation symbol */
+static symbolS *alpha_gp_symbol;
+
+/* XXX: what is this, and why is it exported? */
+valueT alpha_gp_value;
+#endif
+
+/* The current $gp register */
+static int alpha_gp_register = AXP_REG_GP;
+
+/* A table of the register symbols */
+static symbolS *alpha_register_table[64];
+
+/* Constant sections, or sections of constants */
+#ifdef OBJ_ECOFF
+static segT alpha_lita_section;
+static segT alpha_lit4_section;
+#endif
+#ifdef OBJ_EVAX
+static segT alpha_link_section;
+static segT alpha_ctors_section;
+static segT alpha_dtors_section;
+#endif
+static segT alpha_lit8_section;
+
+/* Symbols referring to said sections. */
+#ifdef OBJ_ECOFF
+static symbolS *alpha_lita_symbol;
+static symbolS *alpha_lit4_symbol;
+#endif
+#ifdef OBJ_EVAX
+static symbolS *alpha_link_symbol;
+static symbolS *alpha_ctors_symbol;
+static symbolS *alpha_dtors_symbol;
+#endif
+static symbolS *alpha_lit8_symbol;
+
+/* Literal for .litX+0x8000 within .lita */
+#ifdef OBJ_ECOFF
+static offsetT alpha_lit4_literal;
+static offsetT alpha_lit8_literal;
+#endif
+
+/* The active .ent symbol. */
+#ifdef OBJ_ELF
+static symbolS *alpha_cur_ent_sym;
+#endif
+
+/* Is the assembler not allowed to use $at? */
+static int alpha_noat_on = 0;
+
+/* Are macros enabled? */
+static int alpha_macros_on = 1;
+
+/* Are floats disabled? */
+static int alpha_nofloats_on = 0;
+
+/* Are addresses 32 bit? */
+static int alpha_addr32_on = 0;
+
+/* Symbol labelling the current insn. When the Alpha gas sees
+ foo:
+ .quad 0
+ and the section happens to not be on an eight byte boundary, it
+ will align both the symbol and the .quad to an eight byte boundary. */
+static symbolS *alpha_insn_label;
+
+/* Whether we should automatically align data generation pseudo-ops.
+ .align 0 will turn this off. */
+static int alpha_auto_align_on = 1;
+
+/* The known current alignment of the current section. */
+static int alpha_current_align;
+
+/* These are exported to ECOFF code. */
+unsigned long alpha_gprmask, alpha_fprmask;
+
+/* Whether the debugging option was seen. */
+static int alpha_debug;
+
+#ifdef OBJ_ELF
+/* Whether we are emitting an mdebug section. */
+int alpha_flag_mdebug = 1;
+#endif
+
+/* Don't fully resolve relocations, allowing code movement in the linker. */
+static int alpha_flag_relax;
+
+/* What value to give to bfd_set_gp_size. */
+static int g_switch_value = 8;
+
+#ifdef OBJ_EVAX
+/* Collect information about current procedure here. */
+static struct {
+ symbolS *symbol; /* proc pdesc symbol */
+ int pdsckind;
+ int framereg; /* register for frame pointer */
+ int framesize; /* size of frame */
+ int rsa_offset;
+ int ra_save;
+ int fp_save;
+ long imask;
+ long fmask;
+ int type;
+ int prologue;
+} alpha_evax_proc;
+
+static int alpha_flag_hash_long_names = 0; /* -+ */
+static int alpha_flag_show_after_trunc = 0; /* -H */
+
+/* If the -+ switch is given, then a hash is appended to any name that is
+ * longer than 64 characters, else longer symbol names are truncated.
+ */
+
+#endif
+
+/* A table of CPU names and opcode sets. */
+
+static const struct cpu_type
+{
+ const char *name;
+ unsigned flags;
+} cpu_types[] =
+{
+ /* Ad hoc convention: cpu number gets palcode, process code doesn't.
+ This supports usage under DU 4.0b that does ".arch ev4", and
+ usage in MILO that does -m21064. Probably something more
+ specific like -m21064-pal should be used, but oh well. */
+
+ { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
+ { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
+ { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
+ { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
+ |AXP_OPCODE_MAX) },
+ { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
+ |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
+
+ { "ev4", AXP_OPCODE_BASE },
+ { "ev45", AXP_OPCODE_BASE },
+ { "lca45", AXP_OPCODE_BASE },
+ { "ev5", AXP_OPCODE_BASE },
+ { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
+ { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
+ { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
+
+ { "all", AXP_OPCODE_BASE },
+ { 0 }
+};
+
+/* The macro table */
+
+static const struct alpha_macro alpha_macros[] = {
+/* Load/Store macros */
+ { "lda", emit_lda, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldah", emit_ldah, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+
+ { "ldl", emit_ir_load, "ldl",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldl_l", emit_ir_load, "ldl_l",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldq", emit_ir_load, "ldq",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldq_l", emit_ir_load, "ldq_l",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldq_u", emit_ir_load, "ldq_u",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldf", emit_loadstore, "ldf",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldg", emit_loadstore, "ldg",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "lds", emit_loadstore, "lds",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldt", emit_loadstore, "ldt",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+
+ { "ldb", emit_ldX, (PTR)0,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldbu", emit_ldXu, (PTR)0,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldw", emit_ldX, (PTR)1,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldwu", emit_ldXu, (PTR)1,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+
+ { "uldw", emit_uldX, (PTR)1,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "uldwu", emit_uldXu, (PTR)1,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "uldl", emit_uldX, (PTR)2,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "uldlu", emit_uldXu, (PTR)2,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "uldq", emit_uldXu, (PTR)3,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+
+ { "ldgp", emit_ldgp, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
+
+ { "ldi", emit_lda, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldil", emit_ldil, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ldiq", emit_lda, NULL,
+ { MACRO_IR, MACRO_EXP, MACRO_EOA } },
+#if 0
+ { "ldif" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldid" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldig" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldis" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "ldit" emit_ldiq, NULL,
+ { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+#endif
+
+ { "stl", emit_loadstore, "stl",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "stl_c", emit_loadstore, "stl_c",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "stq", emit_loadstore, "stq",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "stq_c", emit_loadstore, "stq_c",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "stq_u", emit_loadstore, "stq_u",
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "stf", emit_loadstore, "stf",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "stg", emit_loadstore, "stg",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "sts", emit_loadstore, "sts",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+ { "stt", emit_loadstore, "stt",
+ { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_FPR, MACRO_EXP, MACRO_EOA } },
+
+ { "stb", emit_stX, (PTR)0,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "stw", emit_stX, (PTR)1,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ustw", emit_ustX, (PTR)1,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ustl", emit_ustX, (PTR)2,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+ { "ustq", emit_ustX, (PTR)3,
+ { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA } },
+
+/* Arithmetic macros */
+#if 0
+ { "absl" emit_absl, 1, { IR } },
+ { "absl" emit_absl, 2, { IR, IR } },
+ { "absl" emit_absl, 2, { EXP, IR } },
+ { "absq" emit_absq, 1, { IR } },
+ { "absq" emit_absq, 2, { IR, IR } },
+ { "absq" emit_absq, 2, { EXP, IR } },
+#endif
+
+ { "sextb", emit_sextX, (PTR)0,
+ { MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
+ { "sextw", emit_sextX, (PTR)1,
+ { MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
+
+ { "divl", emit_division, "__divl",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "divlu", emit_division, "__divlu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "divq", emit_division, "__divq",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "divqu", emit_division, "__divqu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "reml", emit_division, "__reml",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "remlu", emit_division, "__remlu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "remq", emit_division, "__remq",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+ { "remqu", emit_division, "__remqu",
+ { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_IR, MACRO_EOA,
+ /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
+
+ { "jsr", emit_jsrjmp, "jsr",
+ { MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA } },
+ { "jmp", emit_jsrjmp, "jmp",
+ { MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA } },
+ { "ret", emit_retjcr, "ret",
+ { MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA,
+ MACRO_EOA } },
+ { "jcr", emit_retjcr, "jcr",
+ { MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA,
+ MACRO_EOA } },
+ { "jsr_coroutine", emit_retjcr, "jcr",
+ { MACRO_IR, MACRO_EXP, MACRO_EOA,
+ MACRO_IR, MACRO_EOA,
+ MACRO_PIR, MACRO_EXP, MACRO_EOA,
+ MACRO_PIR, MACRO_EOA,
+ MACRO_EXP, MACRO_EOA,
+ MACRO_EOA } },
+};
+
+static const int alpha_num_macros
+ = sizeof(alpha_macros) / sizeof(*alpha_macros);
+
+/* Public interface functions */
+
+/* This function is called once, at assembler startup time. It sets
+ up all the tables, etc. that the MD part of the assembler will
+ need, that can be determined before arguments are parsed. */
+
+void
+md_begin ()
+{
+ unsigned int i;
+
+ /* Create the opcode hash table */
+
+ alpha_opcode_hash = hash_new ();
+ for (i = 0; i < alpha_num_opcodes; )
+ {
+ const char *name, *retval, *slash;
+
+ name = alpha_opcodes[i].name;
+ retval = hash_insert (alpha_opcode_hash, name, (PTR)&alpha_opcodes[i]);
+ if (retval)
+ as_fatal (_("internal error: can't hash opcode `%s': %s"), name, retval);
+
+ /* Some opcodes include modifiers of various sorts with a "/mod"
+ syntax, like the architecture manual suggests. However, for
+ use with gcc at least, we also need access to those same opcodes
+ without the "/". */
+
+ if ((slash = strchr (name, '/')) != NULL)
+ {
+ char *p = xmalloc (strlen (name));
+ memcpy (p, name, slash - name);
+ strcpy (p + (slash - name), slash + 1);
+
+ (void)hash_insert(alpha_opcode_hash, p, (PTR)&alpha_opcodes[i]);
+ /* Ignore failures -- the opcode table does duplicate some
+ variants in different forms, like "hw_stq" and "hw_st/q". */
+ }
+
+ while (++i < alpha_num_opcodes
+ && (alpha_opcodes[i].name == name
+ || !strcmp (alpha_opcodes[i].name, name)))
+ continue;
+ }
+
+ /* Create the macro hash table */
+
+ alpha_macro_hash = hash_new ();
+ for (i = 0; i < alpha_num_macros; )
+ {
+ const char *name, *retval;
+
+ name = alpha_macros[i].name;
+ retval = hash_insert (alpha_macro_hash, name, (PTR)&alpha_macros[i]);
+ if (retval)
+ as_fatal (_("internal error: can't hash macro `%s': %s"), name, retval);
+
+ while (++i < alpha_num_macros
+ && (alpha_macros[i].name == name
+ || !strcmp (alpha_macros[i].name, name)))
+ continue;
+ }
+
+ /* Construct symbols for each of the registers */
+
+ for (i = 0; i < 32; ++i)
+ {
+ char name[4];
+ sprintf(name, "$%d", i);
+ alpha_register_table[i] = symbol_create(name, reg_section, i,
+ &zero_address_frag);
+ }
+ for (; i < 64; ++i)
+ {
+ char name[5];
+ sprintf(name, "$f%d", i-32);
+ alpha_register_table[i] = symbol_create(name, reg_section, i,
+ &zero_address_frag);
+ }
+
+ /* Create the special symbols and sections we'll be using */
+
+ /* So .sbss will get used for tiny objects. */
+ bfd_set_gp_size (stdoutput, g_switch_value);
+
+#ifdef OBJ_ECOFF
+ create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
+
+ /* For handling the GP, create a symbol that won't be output in the
+ symbol table. We'll edit it out of relocs later. */
+ alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
+ &zero_address_frag);
+#endif
+
+#ifdef OBJ_EVAX
+ create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
+#endif
+
+#ifdef OBJ_ELF
+ if (ECOFF_DEBUGGING)
+ {
+ segT sec = subseg_new(".mdebug", (subsegT)0);
+ bfd_set_section_flags(stdoutput, sec, SEC_HAS_CONTENTS|SEC_READONLY);
+ bfd_set_section_alignment(stdoutput, sec, 3);
+ }
+#endif /* OBJ_ELF */
+
+ subseg_set(text_section, 0);
+}
+
+/* The public interface to the instruction assembler. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char opname[32]; /* current maximum is 13 */
+ expressionS tok[MAX_INSN_ARGS];
+ int ntok, opnamelen, trunclen;
+
+ /* split off the opcode */
+ opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/468");
+ trunclen = (opnamelen < sizeof (opname) - 1
+ ? opnamelen
+ : sizeof (opname) - 1);
+ memcpy (opname, str, trunclen);
+ opname[trunclen] = '\0';
+
+ /* tokenize the rest of the line */
+ if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
+ {
+ as_bad (_("syntax error"));
+ return;
+ }
+
+ /* finish it off */
+ assemble_tokens (opname, tok, ntok, alpha_macros_on);
+}
+
+/* Round up a section's size to the appropriate boundary. */
+
+valueT
+md_section_align (seg, size)
+ segT seg;
+ valueT size;
+{
+ int align = bfd_get_section_alignment(stdoutput, seg);
+ valueT mask = ((valueT)1 << align) - 1;
+
+ return (size + mask) & ~mask;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type type, and store the appropriate bytes in *litP. The number
+ of LITTLENUMS emitted is stored in *sizeP. An error message is
+ returned, or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+extern char *vax_md_atof PARAMS ((int, char *, int *));
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ /* VAX floats */
+ case 'G':
+ /* VAX md_atof doesn't like "G" for some reason. */
+ type = 'g';
+ case 'F':
+ case 'D':
+ return vax_md_atof (type, litP, sizeP);
+
+ /* IEEE floats */
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ for (wordP = words + prec - 1; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+/* Take care of the target-specific command-line options. */
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'F':
+ alpha_nofloats_on = 1;
+ break;
+
+ case OPTION_32ADDR:
+ alpha_addr32_on = 1;
+ break;
+
+ case 'g':
+ alpha_debug = 1;
+ break;
+
+ case 'G':
+ g_switch_value = atoi(arg);
+ break;
+
+ case 'm':
+ {
+ const struct cpu_type *p;
+ for (p = cpu_types; p->name; ++p)
+ if (strcmp(arg, p->name) == 0)
+ {
+ alpha_target_name = p->name, alpha_target = p->flags;
+ goto found;
+ }
+ as_warn(_("Unknown CPU identifier `%s'"), arg);
+ found:;
+ }
+ break;
+
+#ifdef OBJ_EVAX
+ case '+': /* For g++. Hash any name > 63 chars long. */
+ alpha_flag_hash_long_names = 1;
+ break;
+
+ case 'H': /* Show new symbol after hash truncation */
+ alpha_flag_show_after_trunc = 1;
+ break;
+
+ case 'h': /* for gnu-c/vax compatibility. */
+ break;
+#endif
+
+ case OPTION_RELAX:
+ alpha_flag_relax = 1;
+ break;
+
+#ifdef OBJ_ELF
+ case OPTION_MDEBUG:
+ alpha_flag_mdebug = 1;
+ break;
+ case OPTION_NO_MDEBUG:
+ alpha_flag_mdebug = 0;
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Print a description of the command-line options that we accept. */
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fputs(_("\
+Alpha options:\n\
+-32addr treat addresses as 32-bit values\n\
+-F lack floating point instructions support\n\
+-mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
+ specify variant of Alpha architecture\n\
+-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
+ these variants include PALcode opcodes\n"),
+ stream);
+#ifdef OBJ_EVAX
+ fputs (_("\
+VMS options:\n\
+-+ hash encode (don't truncate) names longer than 64 characters\n\
+-H show new symbol after hash truncation\n"),
+ stream);
+#endif
+}
+
+/* Decide from what point a pc-relative relocation is relative to,
+ relative to the pc-relative fixup. Er, relatively speaking. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_GPDISP:
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ return addr;
+ default:
+ return fixP->fx_size + addr;
+ }
+}
+
+/* Attempt to simplify or even eliminate a fixup. The return value is
+ ignored; perhaps it was once meaningful, but now it is historical.
+ To indicate that a fixup has been eliminated, set fixP->fx_done.
+
+ For ELF, here it is that we transform the GPDISP_HI16 reloc we used
+ internally into the GPDISP reloc used externally. We had to do
+ this so that we'd have the GPDISP_LO16 reloc as a tag to compute
+ the distance to the "lda" instruction for setting the addend to
+ GPDISP. */
+
+int
+md_apply_fix (fixP, valueP)
+ fixS *fixP;
+ valueT *valueP;
+{
+ char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
+ valueT value = *valueP;
+ unsigned image, size;
+
+ switch (fixP->fx_r_type)
+ {
+ /* The GPDISP relocations are processed internally with a symbol
+ referring to the current function; we need to drop in a value
+ which, when added to the address of the start of the function,
+ gives the desired GP. */
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ {
+ fixS *next = fixP->fx_next;
+ assert (next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
+
+ fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
+ - fixP->fx_frag->fr_address - fixP->fx_where);
+
+ value = (value - sign_extend_16 (value)) >> 16;
+ }
+#ifdef OBJ_ELF
+ fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
+#endif
+ goto do_reloc_gp;
+
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ value = sign_extend_16 (value);
+ fixP->fx_offset = 0;
+#ifdef OBJ_ELF
+ fixP->fx_done = 1;
+#endif
+
+ do_reloc_gp:
+ fixP->fx_addsy = section_symbol (absolute_section);
+ md_number_to_chars (fixpos, value, 2);
+ break;
+
+ case BFD_RELOC_16:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_16_PCREL;
+ size = 2;
+ goto do_reloc_xx;
+ case BFD_RELOC_32:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+ size = 4;
+ goto do_reloc_xx;
+ case BFD_RELOC_64:
+ if (fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_64_PCREL;
+ size = 8;
+ do_reloc_xx:
+ if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
+ {
+ md_number_to_chars (fixpos, value, size);
+ goto done;
+ }
+ return 1;
+
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_GPREL32:
+ assert (fixP->fx_subsy == alpha_gp_symbol);
+ fixP->fx_subsy = 0;
+ /* FIXME: inherited this obliviousness of `value' -- why? */
+ md_number_to_chars (fixpos, -alpha_gp_value, 4);
+ break;
+#endif
+#ifdef OBJ_ELF
+ case BFD_RELOC_GPREL32:
+ return 1;
+#endif
+
+ case BFD_RELOC_23_PCREL_S2:
+ if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
+ {
+ image = bfd_getl32(fixpos);
+ image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
+ goto write_done;
+ }
+ return 1;
+
+ case BFD_RELOC_ALPHA_HINT:
+ if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
+ {
+ image = bfd_getl32(fixpos);
+ image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
+ goto write_done;
+ }
+ return 1;
+
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_ALPHA_LITERAL:
+ md_number_to_chars (fixpos, value, 2);
+ return 1;
+
+ case BFD_RELOC_ALPHA_LITUSE:
+ return 1;
+#endif
+#ifdef OBJ_ELF
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ case BFD_RELOC_ALPHA_LITUSE:
+ return 1;
+#endif
+#ifdef OBJ_EVAX
+ case BFD_RELOC_ALPHA_LINKAGE:
+ case BFD_RELOC_ALPHA_CODEADDR:
+ return 1;
+#endif
+
+ default:
+ {
+ const struct alpha_operand *operand;
+
+ if ((int)fixP->fx_r_type >= 0)
+ as_fatal (_("unhandled relocation type %s"),
+ bfd_get_reloc_code_name (fixP->fx_r_type));
+
+ assert (-(int)fixP->fx_r_type < alpha_num_operands);
+ operand = &alpha_operands[-(int)fixP->fx_r_type];
+
+ /* The rest of these fixups only exist internally during symbol
+ resolution and have no representation in the object file.
+ Therefore they must be completely resolved as constants. */
+
+ if (fixP->fx_addsy != 0
+ && fixP->fx_addsy->bsym->section != absolute_section)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("non-absolute expression in constant field"));
+
+ image = bfd_getl32(fixpos);
+ image = insert_operand(image, operand, (offsetT)value,
+ fixP->fx_file, fixP->fx_line);
+ }
+ goto write_done;
+ }
+
+ if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
+ return 1;
+ else
+ {
+ as_warn_where(fixP->fx_file, fixP->fx_line,
+ _("type %d reloc done?\n"), (int)fixP->fx_r_type);
+ goto done;
+ }
+
+write_done:
+ md_number_to_chars(fixpos, image, 4);
+
+done:
+ fixP->fx_done = 1;
+ return 0;
+}
+
+/*
+ * Look for a register name in the given symbol.
+ */
+
+symbolS *
+md_undefined_symbol(name)
+ char *name;
+{
+ if (*name == '$')
+ {
+ int is_float = 0, num;
+
+ switch (*++name)
+ {
+ case 'f':
+ if (name[1] == 'p' && name[2] == '\0')
+ return alpha_register_table[AXP_REG_FP];
+ is_float = 32;
+ /* FALLTHRU */
+
+ case 'r':
+ if (!isdigit(*++name))
+ break;
+ /* FALLTHRU */
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (name[1] == '\0')
+ num = name[0] - '0';
+ else if (name[0] != '0' && isdigit(name[1]) && name[2] == '\0')
+ {
+ num = (name[0] - '0') * 10 + name[1] - '0';
+ if (num >= 32)
+ break;
+ }
+ else
+ break;
+
+ if (!alpha_noat_on && num == AXP_REG_AT)
+ as_warn(_("Used $at without \".set noat\""));
+ return alpha_register_table[num + is_float];
+
+ case 'a':
+ if (name[1] == 't' && name[2] == '\0')
+ {
+ if (!alpha_noat_on)
+ as_warn(_("Used $at without \".set noat\""));
+ return alpha_register_table[AXP_REG_AT];
+ }
+ break;
+
+ case 'g':
+ if (name[1] == 'p' && name[2] == '\0')
+ return alpha_register_table[alpha_gp_register];
+ break;
+
+ case 's':
+ if (name[1] == 'p' && name[2] == '\0')
+ return alpha_register_table[AXP_REG_SP];
+ break;
+ }
+ }
+ return NULL;
+}
+
+#ifdef OBJ_ECOFF
+/* @@@ Magic ECOFF bits. */
+
+void
+alpha_frob_ecoff_data ()
+{
+ select_gp_value ();
+ /* $zero and $f31 are read-only */
+ alpha_gprmask &= ~1;
+ alpha_fprmask &= ~1;
+}
+#endif
+
+/* Hook to remember a recently defined label so that the auto-align
+ code can adjust the symbol after we know what alignment will be
+ required. */
+
+void
+alpha_define_label (sym)
+ symbolS *sym;
+{
+ alpha_insn_label = sym;
+}
+
+/* Return true if we must always emit a reloc for a type and false if
+ there is some hope of resolving it a assembly time. */
+
+int
+alpha_force_relocation (f)
+ fixS *f;
+{
+ if (alpha_flag_relax)
+ return 1;
+
+ switch (f->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ case BFD_RELOC_ALPHA_GPDISP:
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_ALPHA_LITERAL:
+#endif
+#ifdef OBJ_ELF
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+#endif
+ case BFD_RELOC_ALPHA_LITUSE:
+ case BFD_RELOC_GPREL32:
+#ifdef OBJ_EVAX
+ case BFD_RELOC_ALPHA_LINKAGE:
+ case BFD_RELOC_ALPHA_CODEADDR:
+#endif
+ return 1;
+
+ case BFD_RELOC_23_PCREL_S2:
+ case BFD_RELOC_32:
+ case BFD_RELOC_64:
+ case BFD_RELOC_ALPHA_HINT:
+ return 0;
+
+ default:
+ assert((int)f->fx_r_type < 0 && -(int)f->fx_r_type < alpha_num_operands);
+ return 0;
+ }
+}
+
+/* Return true if we can partially resolve a relocation now. */
+
+int
+alpha_fix_adjustable (f)
+ fixS *f;
+{
+#ifdef OBJ_ELF
+ /* Prevent all adjustments to global symbols */
+ if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
+ return 0;
+#endif
+
+ /* Are there any relocation types for which we must generate a reloc
+ but we can adjust the values contained within it? */
+ switch (f->fx_r_type)
+ {
+ case BFD_RELOC_ALPHA_GPDISP_HI16:
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+ case BFD_RELOC_ALPHA_GPDISP:
+ return 0;
+
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_ALPHA_LITERAL:
+#endif
+#ifdef OBJ_ELF
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+#endif
+#ifdef OBJ_EVAX
+ case BFD_RELOC_ALPHA_LINKAGE:
+ case BFD_RELOC_ALPHA_CODEADDR:
+#endif
+ return 1;
+
+ case BFD_RELOC_ALPHA_LITUSE:
+ return 0;
+
+ case BFD_RELOC_GPREL32:
+ case BFD_RELOC_23_PCREL_S2:
+ case BFD_RELOC_32:
+ case BFD_RELOC_64:
+ case BFD_RELOC_ALPHA_HINT:
+ return 1;
+
+ default:
+ assert ((int)f->fx_r_type < 0
+ && - (int)f->fx_r_type < alpha_num_operands);
+ return 1;
+ }
+ /*NOTREACHED*/
+}
+
+/* Generate the BFD reloc to be stuck in the object file from the
+ fixup used internally in the assembler. */
+
+arelent *
+tc_gen_reloc (sec, fixp)
+ asection *sec;
+ fixS *fixp;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ /* Make sure none of our internal relocations make it this far.
+ They'd better have been fully resolved by this point. */
+ assert ((int)fixp->fx_r_type > 0);
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot represent `%s' relocation in object file"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ return NULL;
+ }
+
+ if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
+ {
+ as_fatal (_("internal error? cannot generate `%s' relocation"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ }
+ assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
+
+#ifdef OBJ_ECOFF
+ if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
+ {
+ /* fake out bfd_perform_relocation. sigh */
+ reloc->addend = -alpha_gp_value;
+ }
+ else
+#endif
+ {
+ reloc->addend = fixp->fx_offset;
+#ifdef OBJ_ELF
+ /*
+ * Ohhh, this is ugly. The problem is that if this is a local global
+ * symbol, the relocation will entirely be performed at link time, not
+ * at assembly time. bfd_perform_reloc doesn't know about this sort
+ * of thing, and as a result we need to fake it out here.
+ */
+ if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
+ && !S_IS_COMMON(fixp->fx_addsy))
+ reloc->addend -= fixp->fx_addsy->bsym->value;
+#endif
+ }
+
+ return reloc;
+}
+
+/* Parse a register name off of the input_line and return a register
+ number. Gets md_undefined_symbol above to do the register name
+ matching for us.
+
+ Only called as a part of processing the ECOFF .frame directive. */
+
+int
+tc_get_register (frame)
+ int frame;
+{
+ int framereg = AXP_REG_SP;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '$')
+ {
+ char *s = input_line_pointer;
+ char c = get_symbol_end ();
+ symbolS *sym = md_undefined_symbol (s);
+
+ *strchr(s, '\0') = c;
+ if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
+ goto found;
+ }
+ as_warn (_("frame reg expected, using $%d."), framereg);
+
+found:
+ note_gpreg (framereg);
+ return framereg;
+}
+
+/* This is called before the symbol table is processed. In order to
+ work with gcc when using mips-tfile, we must keep all local labels.
+ However, in other cases, we want to discard them. If we were
+ called with -g, but we didn't see any debugging information, it may
+ mean that gcc is smuggling debugging information through to
+ mips-tfile, in which case we must generate all local labels. */
+
+#ifdef OBJ_ECOFF
+
+void
+alpha_frob_file_before_adjust ()
+{
+ if (alpha_debug != 0
+ && ! ecoff_debugging_seen)
+ flag_keep_locals = 1;
+}
+
+#endif /* OBJ_ECOFF */
+
+/* Parse the arguments to an opcode. */
+
+static int
+tokenize_arguments (str, tok, ntok)
+ char *str;
+ expressionS tok[];
+ int ntok;
+{
+ expressionS *end_tok = tok + ntok;
+ char *old_input_line_pointer;
+ int saw_comma = 0, saw_arg = 0;
+
+ memset (tok, 0, sizeof (*tok) * ntok);
+
+ /* Save and restore input_line_pointer around this function */
+ old_input_line_pointer = input_line_pointer;
+ input_line_pointer = str;
+
+ while (tok < end_tok && *input_line_pointer)
+ {
+ SKIP_WHITESPACE ();
+ switch (*input_line_pointer)
+ {
+ case '\0':
+ goto fini;
+
+ case ',':
+ ++input_line_pointer;
+ if (saw_comma || !saw_arg)
+ goto err;
+ saw_comma = 1;
+ break;
+
+ case '(':
+ {
+ char *hold = input_line_pointer++;
+
+ /* First try for parenthesized register ... */
+ expression (tok);
+ if (*input_line_pointer == ')' && tok->X_op == O_register)
+ {
+ tok->X_op = (saw_comma ? O_cpregister : O_pregister);
+ saw_comma = 0;
+ saw_arg = 1;
+ ++input_line_pointer;
+ ++tok;
+ break;
+ }
+
+ /* ... then fall through to plain expression */
+ input_line_pointer = hold;
+ }
+
+ default:
+ if (saw_arg && !saw_comma)
+ goto err;
+ expression (tok);
+ if (tok->X_op == O_illegal || tok->X_op == O_absent)
+ goto err;
+
+ saw_comma = 0;
+ saw_arg = 1;
+ ++tok;
+ break;
+ }
+ }
+
+fini:
+ if (saw_comma)
+ goto err;
+ input_line_pointer = old_input_line_pointer;
+ return ntok - (end_tok - tok);
+
+err:
+ input_line_pointer = old_input_line_pointer;
+ return -1;
+}
+
+/* Search forward through all variants of an opcode looking for a
+ syntax match. */
+
+static const struct alpha_opcode *
+find_opcode_match(first_opcode, tok, pntok, pcpumatch)
+ const struct alpha_opcode *first_opcode;
+ const expressionS *tok;
+ int *pntok;
+ int *pcpumatch;
+{
+ const struct alpha_opcode *opcode = first_opcode;
+ int ntok = *pntok;
+ int got_cpu_match = 0;
+
+ do
+ {
+ const unsigned char *opidx;
+ int tokidx = 0;
+
+ /* Don't match opcodes that don't exist on this architecture */
+ if (!(opcode->flags & alpha_target))
+ goto match_failed;
+
+ got_cpu_match = 1;
+
+ for (opidx = opcode->operands; *opidx; ++opidx)
+ {
+ const struct alpha_operand *operand = &alpha_operands[*opidx];
+
+ /* only take input from real operands */
+ if (operand->flags & AXP_OPERAND_FAKE)
+ continue;
+
+ /* when we expect input, make sure we have it */
+ if (tokidx >= ntok)
+ {
+ if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
+ goto match_failed;
+ continue;
+ }
+
+ /* match operand type with expression type */
+ switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
+ {
+ case AXP_OPERAND_IR:
+ if (tok[tokidx].X_op != O_register
+ || !is_ir_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+ case AXP_OPERAND_FPR:
+ if (tok[tokidx].X_op != O_register
+ || !is_fpr_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+ case AXP_OPERAND_IR|AXP_OPERAND_PARENS:
+ if (tok[tokidx].X_op != O_pregister
+ || !is_ir_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+ case AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA:
+ if (tok[tokidx].X_op != O_cpregister
+ || !is_ir_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ break;
+
+ case AXP_OPERAND_RELATIVE:
+ case AXP_OPERAND_SIGNED:
+ case AXP_OPERAND_UNSIGNED:
+ switch (tok[tokidx].X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_register:
+ case O_pregister:
+ case O_cpregister:
+ goto match_failed;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ /* everything else should have been fake */
+ abort();
+ }
+ ++tokidx;
+ }
+
+ /* possible match -- did we use all of our input? */
+ if (tokidx == ntok)
+ {
+ *pntok = ntok;
+ return opcode;
+ }
+
+ match_failed:;
+ }
+ while (++opcode-alpha_opcodes < alpha_num_opcodes
+ && !strcmp(opcode->name, first_opcode->name));
+
+ if (*pcpumatch)
+ *pcpumatch = got_cpu_match;
+
+ return NULL;
+}
+
+/* Search forward through all variants of a macro looking for a syntax
+ match. */
+
+static const struct alpha_macro *
+find_macro_match(first_macro, tok, pntok)
+ const struct alpha_macro *first_macro;
+ const expressionS *tok;
+ int *pntok;
+{
+ const struct alpha_macro *macro = first_macro;
+ int ntok = *pntok;
+
+ do
+ {
+ const enum alpha_macro_arg *arg = macro->argsets;
+ int tokidx = 0;
+
+ while (*arg)
+ {
+ switch (*arg)
+ {
+ case MACRO_EOA:
+ if (tokidx == ntok)
+ return macro;
+ else
+ tokidx = 0;
+ break;
+
+ case MACRO_IR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_register
+ || !is_ir_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+ case MACRO_PIR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
+ || !is_ir_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+ case MACRO_CPIR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
+ || !is_ir_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+ case MACRO_FPR:
+ if (tokidx >= ntok || tok[tokidx].X_op != O_register
+ || !is_fpr_num(tok[tokidx].X_add_number))
+ goto match_failed;
+ ++tokidx;
+ break;
+
+ case MACRO_EXP:
+ if (tokidx >= ntok)
+ goto match_failed;
+ switch (tok[tokidx].X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_register:
+ case O_pregister:
+ case O_cpregister:
+ goto match_failed;
+
+ default:
+ break;
+ }
+ ++tokidx;
+ break;
+
+ match_failed:
+ while (*arg != MACRO_EOA)
+ ++arg;
+ tokidx = 0;
+ break;
+ }
+ ++arg;
+ }
+ }
+ while (++macro-alpha_macros < alpha_num_macros
+ && !strcmp(macro->name, first_macro->name));
+
+ return NULL;
+}
+
+/* Insert an operand value into an instruction. */
+
+static unsigned
+insert_operand(insn, operand, val, file, line)
+ unsigned insn;
+ const struct alpha_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned line;
+{
+ if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
+ {
+ offsetT min, max;
+
+ if (operand->flags & AXP_OPERAND_SIGNED)
+ {
+ max = (1 << (operand->bits - 1)) - 1;
+ min = -(1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ if (val < min || val > max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %d and %d)");
+ char buf[sizeof (val) * 3 + 2];
+
+ sprint_value(buf, val);
+ if (file)
+ as_warn_where(file, line, err, buf, min, max);
+ else
+ as_warn(err, buf, min, max);
+ }
+ }
+
+ if (operand->insert)
+ {
+ const char *errmsg = NULL;
+
+ insn = (*operand->insert) (insn, val, &errmsg);
+ if (errmsg)
+ as_warn (errmsg);
+ }
+ else
+ insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
+
+ return insn;
+}
+
+/*
+ * Turn an opcode description and a set of arguments into
+ * an instruction and a fixup.
+ */
+
+static void
+assemble_insn(opcode, tok, ntok, insn)
+ const struct alpha_opcode *opcode;
+ const expressionS *tok;
+ int ntok;
+ struct alpha_insn *insn;
+{
+ const unsigned char *argidx;
+ unsigned image;
+ int tokidx = 0;
+
+ memset (insn, 0, sizeof (*insn));
+ image = opcode->opcode;
+
+ for (argidx = opcode->operands; *argidx; ++argidx)
+ {
+ const struct alpha_operand *operand = &alpha_operands[*argidx];
+ const expressionS *t;
+
+ if (operand->flags & AXP_OPERAND_FAKE)
+ {
+ /* fake operands take no value and generate no fixup */
+ image = insert_operand(image, operand, 0, NULL, 0);
+ continue;
+ }
+
+ if (tokidx >= ntok)
+ {
+ switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
+ {
+ case AXP_OPERAND_DEFAULT_FIRST:
+ t = &tok[0];
+ break;
+ case AXP_OPERAND_DEFAULT_SECOND:
+ t = &tok[1];
+ break;
+ case AXP_OPERAND_DEFAULT_ZERO:
+ {
+ static const expressionS zero_exp = { 0, 0, 0, O_constant, 1 };
+ t = &zero_exp;
+ }
+ break;
+ default:
+ abort();
+ }
+ }
+ else
+ t = &tok[tokidx++];
+
+ switch (t->X_op)
+ {
+ case O_register:
+ case O_pregister:
+ case O_cpregister:
+ image = insert_operand(image, operand, regno(t->X_add_number),
+ NULL, 0);
+ break;
+
+ case O_constant:
+ image = insert_operand(image, operand, t->X_add_number, NULL, 0);
+ break;
+
+ default:
+ {
+ struct alpha_fixup *fixup;
+
+ if (insn->nfixups >= MAX_INSN_FIXUPS)
+ as_fatal(_("too many fixups"));
+
+ fixup = &insn->fixups[insn->nfixups++];
+
+ fixup->exp = *t;
+ fixup->reloc = operand->default_reloc;
+ }
+ break;
+ }
+ }
+
+ insn->insn = image;
+}
+
+/*
+ * Actually output an instruction with its fixup.
+ */
+
+static void
+emit_insn (insn)
+ struct alpha_insn *insn;
+{
+ char *f;
+ int i;
+
+ /* Take care of alignment duties */
+ if (alpha_auto_align_on && alpha_current_align < 2)
+ alpha_align (2, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > 2)
+ alpha_current_align = 2;
+ alpha_insn_label = NULL;
+
+ /* Write out the instruction. */
+ f = frag_more (4);
+ md_number_to_chars (f, insn->insn, 4);
+
+ /* Apply the fixups in order */
+ for (i = 0; i < insn->nfixups; ++i)
+ {
+ const struct alpha_operand *operand;
+ struct alpha_fixup *fixup = &insn->fixups[i];
+ int size, pcrel;
+ fixS *fixP;
+
+ /* Some fixups are only used internally and so have no howto */
+ if ((int)fixup->reloc < 0)
+ {
+ operand = &alpha_operands[-(int)fixup->reloc];
+ size = 4;
+ pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
+ }
+#ifdef OBJ_ELF
+ /* These relocation types are only used internally. */
+ else if (fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
+ || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
+ {
+ size = 2, pcrel = 0;
+ }
+#endif
+ else
+ {
+ reloc_howto_type *reloc_howto
+ = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
+ assert (reloc_howto);
+
+ size = bfd_get_reloc_size (reloc_howto);
+ pcrel = reloc_howto->pc_relative;
+ }
+ assert (size >= 1 && size <= 4);
+
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
+ &fixup->exp, pcrel, fixup->reloc);
+
+ /* Turn off complaints that the addend is too large for some fixups */
+ switch (fixup->reloc)
+ {
+ case BFD_RELOC_ALPHA_GPDISP_LO16:
+#ifdef OBJ_ECOFF
+ case BFD_RELOC_ALPHA_LITERAL:
+#endif
+#ifdef OBJ_ELF
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+#endif
+ case BFD_RELOC_GPREL32:
+ fixP->fx_no_overflow = 1;
+ break;
+
+ default:
+ if ((int)fixup->reloc < 0)
+ {
+ if (operand->flags & AXP_OPERAND_NOOVERFLOW)
+ fixP->fx_no_overflow = 1;
+ }
+ break;
+ }
+ }
+}
+
+/* Given an opcode name and a pre-tokenized set of arguments, assemble
+ the insn, but do not emit it.
+
+ Note that this implies no macros allowed, since we can't store more
+ than one insn in an insn structure. */
+
+static void
+assemble_tokens_to_insn(opname, tok, ntok, insn)
+ const char *opname;
+ const expressionS *tok;
+ int ntok;
+ struct alpha_insn *insn;
+{
+ const struct alpha_opcode *opcode;
+
+ /* search opcodes */
+ opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
+ if (opcode)
+ {
+ int cpumatch;
+ opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
+ if (opcode)
+ {
+ assemble_insn (opcode, tok, ntok, insn);
+ return;
+ }
+ else if (cpumatch)
+ as_bad (_("inappropriate arguments for opcode `%s'"), opname);
+ else
+ as_bad (_("opcode `%s' not supported for target %s"), opname,
+ alpha_target_name);
+ }
+ else
+ as_bad (_("unknown opcode `%s'"), opname);
+}
+
+/* Given an opcode name and a pre-tokenized set of arguments, take the
+ opcode all the way through emission. */
+
+static void
+assemble_tokens (opname, tok, ntok, local_macros_on)
+ const char *opname;
+ const expressionS *tok;
+ int ntok;
+ int local_macros_on;
+{
+ int found_something = 0;
+ const struct alpha_opcode *opcode;
+ const struct alpha_macro *macro;
+ int cpumatch = 1;
+
+ /* search macros */
+ if (local_macros_on)
+ {
+ macro = ((const struct alpha_macro *)
+ hash_find (alpha_macro_hash, opname));
+ if (macro)
+ {
+ found_something = 1;
+ macro = find_macro_match (macro, tok, &ntok);
+ if (macro)
+ {
+ (*macro->emit) (tok, ntok, macro->arg);
+ return;
+ }
+ }
+ }
+
+ /* search opcodes */
+ opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
+ if (opcode)
+ {
+ found_something = 1;
+ opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
+ if (opcode)
+ {
+ struct alpha_insn insn;
+ assemble_insn (opcode, tok, ntok, &insn);
+ emit_insn (&insn);
+ return;
+ }
+ }
+
+ if (found_something)
+ if (cpumatch)
+ as_bad (_("inappropriate arguments for opcode `%s'"), opname);
+ else
+ as_bad (_("opcode `%s' not supported for target %s"), opname,
+ alpha_target_name);
+ else
+ as_bad (_("unknown opcode `%s'"), opname);
+}
+
+
+/* Some instruction sets indexed by lg(size) */
+static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
+static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
+static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
+static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
+static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
+static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
+static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
+static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
+static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
+static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
+
+/* Implement the ldgp macro. */
+
+static void
+emit_ldgp (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok;
+ const PTR unused;
+{
+#ifdef OBJ_AOUT
+FIXME
+#endif
+#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
+ /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
+ with appropriate constants and relocations. */
+ struct alpha_insn insn;
+ expressionS newtok[3];
+ expressionS addend;
+
+ /* We're going to need this symbol in md_apply_fix(). */
+ (void) section_symbol (absolute_section);
+
+#ifdef OBJ_ECOFF
+ if (regno (tok[2].X_add_number) == AXP_REG_PV)
+ ecoff_set_gp_prolog_size (0);
+#endif
+
+ newtok[0] = tok[0];
+ set_tok_const (newtok[1], 0);
+ newtok[2] = tok[2];
+
+ assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
+
+ addend = tok[1];
+
+#ifdef OBJ_ECOFF
+ if (addend.X_op != O_constant)
+ as_bad (_("can not resolve expression"));
+ addend.X_op = O_symbol;
+ addend.X_add_symbol = alpha_gp_symbol;
+#endif
+
+ insn.nfixups = 1;
+ insn.fixups[0].exp = addend;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
+
+ emit_insn (&insn);
+
+ set_tok_preg (newtok[2], tok[0].X_add_number);
+
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
+
+#ifdef OBJ_ECOFF
+ addend.X_add_number += 4;
+#endif
+
+ insn.nfixups = 1;
+ insn.fixups[0].exp = addend;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
+
+ emit_insn (&insn);
+#endif /* OBJ_ECOFF || OBJ_ELF */
+}
+
+#ifdef OBJ_EVAX
+
+/* Add symbol+addend to link pool.
+ Return offset from basesym to entry in link pool.
+
+ Add new fixup only if offset isn't 16bit. */
+
+valueT
+add_to_link_pool (basesym, sym, addend)
+ symbolS *basesym;
+ symbolS *sym;
+ offsetT addend;
+{
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ valueT offset;
+ bfd_reloc_code_real_type reloc_type;
+ char *p;
+ segment_info_type *seginfo = seg_info (alpha_link_section);
+ fixS *fixp;
+
+ offset = -basesym->sy_obj;
+
+ /* @@ This assumes all entries in a given section will be of the same
+ size... Probably correct, but unwise to rely on. */
+ /* This must always be called with the same subsegment. */
+
+ if (seginfo->frchainP)
+ for (fixp = seginfo->frchainP->fix_root;
+ fixp != (fixS *) NULL;
+ fixp = fixp->fx_next, offset += 8)
+ {
+ if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
+ {
+ if (range_signed_16 (offset))
+ {
+ return offset;
+ }
+ }
+ }
+
+ /* Not found in 16bit signed range. */
+
+ subseg_set (alpha_link_section, 0);
+ p = frag_more (8);
+ memset (p, 0, 8);
+
+ fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
+ BFD_RELOC_64);
+
+ subseg_set (current_section, current_subsec);
+ seginfo->literal_pool_size += 8;
+ return offset;
+}
+
+#endif /* OBJ_EVAX */
+
+/* Load a (partial) expression into a target register.
+
+ If poffset is not null, after the call it will either contain
+ O_constant 0, or a 16-bit offset appropriate for any MEM format
+ instruction. In addition, pbasereg will be modified to point to
+ the base register to use in that MEM format instruction.
+
+ In any case, *pbasereg should contain a base register to add to the
+ expression. This will normally be either AXP_REG_ZERO or
+ alpha_gp_register. Symbol addresses will always be loaded via $gp,
+ so "foo($0)" is interpreted as adding the address of foo to $0;
+ i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
+ but this is what OSF/1 does.
+
+ Finally, the return value is true if the calling macro may emit a
+ LITUSE reloc if otherwise appropriate. */
+
+static int
+load_expression (targreg, exp, pbasereg, poffset)
+ int targreg;
+ const expressionS *exp;
+ int *pbasereg;
+ expressionS *poffset;
+{
+ int emit_lituse = 0;
+ offsetT addend = exp->X_add_number;
+ int basereg = *pbasereg;
+ struct alpha_insn insn;
+ expressionS newtok[3];
+
+ switch (exp->X_op)
+ {
+ case O_symbol:
+ {
+#ifdef OBJ_ECOFF
+ offsetT lit;
+
+ /* attempt to reduce .lit load by splitting the offset from
+ its symbol when possible, but don't create a situation in
+ which we'd fail. */
+ if (!range_signed_32 (addend) &&
+ (alpha_noat_on || targreg == AXP_REG_AT))
+ {
+ lit = add_to_literal_pool (exp->X_add_symbol, addend,
+ alpha_lita_section, 8);
+ addend = 0;
+ }
+ else
+ {
+ lit = add_to_literal_pool (exp->X_add_symbol, 0,
+ alpha_lita_section, 8);
+ }
+
+ if (lit >= 0x8000)
+ as_fatal (_("overflow in literal (.lita) table"));
+
+ /* emit "ldq r, lit(gp)" */
+
+ if (basereg != alpha_gp_register && targreg == basereg)
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+ if (targreg == AXP_REG_AT)
+ as_bad (_("macro requires $at while $at in use"));
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ }
+ else
+ set_tok_reg (newtok[0], targreg);
+ set_tok_sym (newtok[1], alpha_lita_symbol, lit);
+ set_tok_preg (newtok[2], alpha_gp_register);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups == 1);
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
+#endif /* OBJ_ECOFF */
+#ifdef OBJ_ELF
+ /* emit "ldq r, gotoff(gp)" */
+
+ if (basereg != alpha_gp_register && targreg == basereg)
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+ if (targreg == AXP_REG_AT)
+ as_bad (_("macro requires $at while $at in use"));
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ }
+ else
+ set_tok_reg (newtok[0], targreg);
+
+ /* XXX: Disable this .got minimizing optimization so that we can get
+ better instruction offset knowledge in the compiler. This happens
+ very infrequently anyway. */
+ if (1 || (!range_signed_32 (addend)
+ && (alpha_noat_on || targreg == AXP_REG_AT)))
+ {
+ newtok[1] = *exp;
+ addend = 0;
+ }
+ else
+ {
+ set_tok_sym (newtok[1], exp->X_add_symbol, 0);
+ }
+
+ set_tok_preg (newtok[2], alpha_gp_register);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups == 1);
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
+#endif /* OBJ_ELF */
+#ifdef OBJ_EVAX
+ offsetT link;
+
+ /* Find symbol or symbol pointer in link section. */
+
+ if (exp->X_add_symbol == alpha_evax_proc.symbol)
+ {
+ if (range_signed_16 (addend))
+ {
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], addend);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
+ addend = 0;
+ }
+ else
+ {
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("lda", newtok, 3, &insn);
+ }
+ }
+ else
+ {
+ if (!range_signed_32 (addend))
+ {
+ link = add_to_link_pool (alpha_evax_proc.symbol,
+ exp->X_add_symbol, addend);
+ addend = 0;
+ }
+ else
+ {
+ link = add_to_link_pool (alpha_evax_proc.symbol,
+ exp->X_add_symbol, 0);
+ }
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], link);
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+ }
+#endif /* OBJ_EVAX */
+
+ emit_insn(&insn);
+
+#ifndef OBJ_EVAX
+ emit_lituse = 1;
+
+ if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
+ {
+ /* emit "addq r, base, r" */
+
+ set_tok_reg (newtok[1], basereg);
+ set_tok_reg (newtok[2], targreg);
+ assemble_tokens ("addq", newtok, 3, 0);
+ }
+#endif
+
+ basereg = targreg;
+ }
+ break;
+
+ case O_constant:
+ break;
+
+ case O_subtract:
+ /* Assume that this difference expression will be resolved to an
+ absolute value and that that value will fit in 16 bits. */
+
+ set_tok_reg (newtok[0], targreg);
+ newtok[1] = *exp;
+ set_tok_preg (newtok[2], basereg);
+ assemble_tokens ("lda", newtok, 3, 0);
+
+ if (poffset)
+ set_tok_const (*poffset, 0);
+ return 0;
+
+ case O_big:
+ if (exp->X_add_number > 0)
+ as_bad (_("bignum invalid; zero assumed"));
+ else
+ as_bad (_("floating point number invalid; zero assumed"));
+ addend = 0;
+ break;
+
+ default:
+ as_bad (_("can't handle expression"));
+ addend = 0;
+ break;
+ }
+
+ if (!range_signed_32 (addend))
+ {
+ offsetT lit;
+
+ /* for 64-bit addends, just put it in the literal pool */
+
+#ifdef OBJ_EVAX
+ /* emit "ldq targreg, lit(basereg)" */
+ lit = add_to_link_pool (alpha_evax_proc.symbol,
+ section_symbol (absolute_section), addend);
+ set_tok_reg (newtok[0], targreg);
+ set_tok_const (newtok[1], lit);
+ set_tok_preg (newtok[2], alpha_gp_register);
+ assemble_tokens ("ldq", newtok, 3, 0);
+#else
+
+ if (alpha_lit8_section == NULL)
+ {
+ create_literal_section (".lit8",
+ &alpha_lit8_section,
+ &alpha_lit8_symbol);
+
+#ifdef OBJ_ECOFF
+ alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
+ alpha_lita_section, 8);
+ if (alpha_lit8_literal >= 0x8000)
+ as_fatal (_("overflow in literal (.lita) table"));
+#endif
+ }
+
+ lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
+ if (lit >= 0x8000)
+ as_fatal (_("overflow in literal (.lit8) table"));
+
+ /* emit "lda litreg, .lit8+0x8000" */
+
+ if (targreg == basereg)
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+ if (targreg == AXP_REG_AT)
+ as_bad (_("macro requires $at while $at in use"));
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ }
+ else
+ set_tok_reg (newtok[0], targreg);
+#ifdef OBJ_ECOFF
+ set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
+#endif
+#ifdef OBJ_ELF
+ set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
+#endif
+ set_tok_preg (newtok[2], alpha_gp_register);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups == 1);
+#ifdef OBJ_ECOFF
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
+#endif
+#ifdef OBJ_ELF
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
+#endif
+
+ emit_insn (&insn);
+
+ /* emit "ldq litreg, lit(litreg)" */
+
+ set_tok_const (newtok[1], lit);
+ set_tok_preg (newtok[2], newtok[0].X_add_number);
+
+ assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
+
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ if (insn.nfixups > 0)
+ {
+ memmove (&insn.fixups[1], &insn.fixups[0],
+ sizeof(struct alpha_fixup) * insn.nfixups);
+ }
+ insn.nfixups++;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
+ insn.fixups[0].exp.X_op = O_constant;
+ insn.fixups[0].exp.X_add_number = 1;
+ emit_lituse = 0;
+
+ emit_insn (&insn);
+
+ /* emit "addq litreg, base, target" */
+
+ if (basereg != AXP_REG_ZERO)
+ {
+ set_tok_reg (newtok[1], basereg);
+ set_tok_reg (newtok[2], targreg);
+ assemble_tokens ("addq", newtok, 3, 0);
+ }
+#endif /* !OBJ_EVAX */
+
+ if (poffset)
+ set_tok_const (*poffset, 0);
+ *pbasereg = targreg;
+ }
+ else
+ {
+ offsetT low, high, extra, tmp;
+
+ /* for 32-bit operands, break up the addend */
+
+ low = sign_extend_16 (addend);
+ tmp = addend - low;
+ high = sign_extend_16 (tmp >> 16);
+
+ if (tmp - (high << 16))
+ {
+ extra = 0x4000;
+ tmp -= 0x40000000;
+ high = sign_extend_16 (tmp >> 16);
+ }
+ else
+ extra = 0;
+
+ set_tok_reg (newtok[0], targreg);
+ set_tok_preg (newtok[2], basereg);
+
+ if (extra)
+ {
+ /* emit "ldah r, extra(r) */
+ set_tok_const (newtok[1], extra);
+ assemble_tokens ("ldah", newtok, 3, 0);
+ set_tok_preg (newtok[2], basereg = targreg);
+ }
+
+ if (high)
+ {
+ /* emit "ldah r, high(r) */
+ set_tok_const (newtok[1], high);
+ assemble_tokens ("ldah", newtok, 3, 0);
+ basereg = targreg;
+ set_tok_preg (newtok[2], basereg);
+ }
+
+ if ((low && !poffset) || (!poffset && basereg != targreg))
+ {
+ /* emit "lda r, low(base)" */
+ set_tok_const (newtok[1], low);
+ assemble_tokens ("lda", newtok, 3, 0);
+ basereg = targreg;
+ low = 0;
+ }
+
+ if (poffset)
+ set_tok_const (*poffset, low);
+ *pbasereg = basereg;
+ }
+
+ return emit_lituse;
+}
+
+/* The lda macro differs from the lda instruction in that it handles
+ most simple expressions, particualrly symbol address loads and
+ large constants. */
+
+static void
+emit_lda (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok;
+ const PTR unused;
+{
+ int basereg;
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
+}
+
+/* The ldah macro differs from the ldah instruction in that it has $31
+ as an implied base register. */
+
+static void
+emit_ldah (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok;
+ const PTR unused;
+{
+ expressionS newtok[3];
+
+ newtok[0] = tok[0];
+ newtok[1] = tok[1];
+ set_tok_preg (newtok[2], AXP_REG_ZERO);
+
+ assemble_tokens ("ldah", newtok, 3, 0);
+}
+
+/* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
+ etc. They differ from the real instructions in that they do simple
+ expressions like the lda macro. */
+
+static void
+emit_ir_load (tok, ntok, opname)
+ const expressionS *tok;
+ int ntok;
+ const PTR opname;
+{
+ int basereg, lituse;
+ expressionS newtok[3];
+ struct alpha_insn insn;
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
+ &newtok[1]);
+
+ newtok[0] = tok[0];
+ set_tok_preg (newtok[2], basereg);
+
+ assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ if (insn.nfixups > 0)
+ {
+ memmove (&insn.fixups[1], &insn.fixups[0],
+ sizeof(struct alpha_fixup) * insn.nfixups);
+ }
+ insn.nfixups++;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
+ insn.fixups[0].exp.X_op = O_constant;
+ insn.fixups[0].exp.X_add_number = 1;
+ }
+
+ emit_insn (&insn);
+}
+
+/* Handle fp register loads, and both integer and fp register stores.
+ Again, we handle simple expressions. */
+
+static void
+emit_loadstore (tok, ntok, opname)
+ const expressionS *tok;
+ int ntok;
+ const PTR opname;
+{
+ int basereg, lituse;
+ expressionS newtok[3];
+ struct alpha_insn insn;
+
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
+ if (tok[1].X_op != O_constant || !range_signed_16(tok[1].X_add_number))
+ {
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
+ }
+ else
+ {
+ newtok[1] = tok[1];
+ lituse = 0;
+ }
+
+ newtok[0] = tok[0];
+ set_tok_preg (newtok[2], basereg);
+
+ assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
+
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ if (insn.nfixups > 0)
+ {
+ memmove (&insn.fixups[1], &insn.fixups[0],
+ sizeof(struct alpha_fixup) * insn.nfixups);
+ }
+ insn.nfixups++;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
+ insn.fixups[0].exp.X_op = O_constant;
+ insn.fixups[0].exp.X_add_number = 1;
+ }
+
+ emit_insn (&insn);
+}
+
+/* Load a half-word or byte as an unsigned value. */
+
+static void
+emit_ldXu (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ if (alpha_target & AXP_OPCODE_BWX)
+ emit_ir_load (tok, ntok, ldXu_op[(long)vlgsize]);
+ else
+ {
+ expressionS newtok[3];
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ /* emit "lda $at, exp" */
+
+ memcpy (newtok, tok, sizeof (expressionS) * ntok);
+ newtok[0].X_add_number = AXP_REG_AT;
+ assemble_tokens ("lda", newtok, ntok, 1);
+
+ /* emit "ldq_u targ, 0($at)" */
+
+ newtok[0] = tok[0];
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "extXl targ, $at, targ" */
+
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ newtok[2] = newtok[0];
+ assemble_tokens (extXl_op[(long)vlgsize], newtok, 3, 1);
+ }
+}
+
+/* Load a half-word or byte as a signed value. */
+
+static void
+emit_ldX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ emit_ldXu (tok, ntok, vlgsize);
+ assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
+}
+
+/* Load an integral value from an unaligned address as an unsigned
+ value. */
+
+static void
+emit_uldXu (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ long lgsize = (long)vlgsize;
+ expressionS newtok[3];
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ /* emit "lda $at, exp" */
+
+ memcpy (newtok, tok, sizeof (expressionS) * ntok);
+ newtok[0].X_add_number = AXP_REG_AT;
+ assemble_tokens ("lda", newtok, ntok, 1);
+
+ /* emit "ldq_u $t9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "ldq_u $t10, size-1($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_const (newtok[1], (1<<lgsize)-1);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "extXl $t9, $at, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ set_tok_reg (newtok[2], AXP_REG_T9);
+ assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "extXh $t10, $at, $t10" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[2], AXP_REG_T10);
+ assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
+
+ /* emit "or $t9, $t10, targ" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ newtok[2] = tok[0];
+ assemble_tokens ("or", newtok, 3, 1);
+}
+
+/* Load an integral value from an unaligned address as a signed value.
+ Note that quads should get funneled to the unsigned load since we
+ don't have to do the sign extension. */
+
+static void
+emit_uldX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ emit_uldXu (tok, ntok, vlgsize);
+ assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
+}
+
+/* Implement the ldil macro. */
+
+static void
+emit_ldil (tok, ntok, unused)
+ const expressionS *tok;
+ int ntok;
+ const PTR unused;
+{
+ expressionS newtok[2];
+
+ memcpy (newtok, tok, sizeof(newtok));
+ newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
+
+ assemble_tokens ("lda", newtok, ntok, 1);
+}
+
+/* Store a half-word or byte. */
+
+static void
+emit_stX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ int lgsize = (int)(long)vlgsize;
+
+ if (alpha_target & AXP_OPCODE_BWX)
+ emit_loadstore (tok, ntok, stX_op[lgsize]);
+ else
+ {
+ expressionS newtok[3];
+
+ if (alpha_noat_on)
+ as_bad(_("macro requires $at register while noat in effect"));
+
+ /* emit "lda $at, exp" */
+
+ memcpy (newtok, tok, sizeof (expressionS) * ntok);
+ newtok[0].X_add_number = AXP_REG_AT;
+ assemble_tokens ("lda", newtok, ntok, 1);
+
+ /* emit "ldq_u $t9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "insXl src, $at, $t10" */
+
+ newtok[0] = tok[0];
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ set_tok_reg (newtok[2], AXP_REG_T10);
+ assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "mskXl $t9, $at, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ newtok[2] = newtok[0];
+ assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "or $t9, $t10, $t9" */
+
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ assemble_tokens ("or", newtok, 3, 1);
+
+ /* emit "stq_u $t9, 0($at) */
+
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("stq_u", newtok, 3, 1);
+ }
+}
+
+/* Store an integer to an unaligned address. */
+
+static void
+emit_ustX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ int lgsize = (int)(long)vlgsize;
+ expressionS newtok[3];
+
+ /* emit "lda $at, exp" */
+
+ memcpy (newtok, tok, sizeof (expressionS) * ntok);
+ newtok[0].X_add_number = AXP_REG_AT;
+ assemble_tokens ("lda", newtok, ntok, 1);
+
+ /* emit "ldq_u $9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "ldq_u $10, size-1($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_const (newtok[1], (1 << lgsize)-1);
+ assemble_tokens ("ldq_u", newtok, 3, 1);
+
+ /* emit "insXl src, $at, $t11" */
+
+ newtok[0] = tok[0];
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ set_tok_reg (newtok[2], AXP_REG_T11);
+ assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "insXh src, $at, $t12" */
+
+ set_tok_reg (newtok[2], AXP_REG_T12);
+ assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
+
+ /* emit "mskXl $t9, $at, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ newtok[2] = newtok[0];
+ assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
+
+ /* emit "mskXh $t10, $at, $t10" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ newtok[2] = newtok[0];
+ assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
+
+ /* emit "or $t9, $t11, $t9" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ newtok[2] = newtok[0];
+ assemble_tokens ("or", newtok, 3, 1);
+
+ /* emit "or $t10, $t12, $t10" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[1], AXP_REG_T12);
+ newtok[2] = newtok[0];
+ assemble_tokens ("or", newtok, 3, 1);
+
+ /* emit "stq_u $t9, 0($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_AT);
+ assemble_tokens ("stq_u", newtok, 3, 1);
+
+ /* emit "stq_u $t10, size-1($at)" */
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_const (newtok[1], (1 << lgsize)-1);
+ assemble_tokens ("stq_u", newtok, 3, 1);
+}
+
+/* Sign extend a half-word or byte. The 32-bit sign extend is
+ implemented as "addl $31, $r, $t" in the opcode table. */
+
+static void
+emit_sextX (tok, ntok, vlgsize)
+ const expressionS *tok;
+ int ntok;
+ const PTR vlgsize;
+{
+ long lgsize = (long)vlgsize;
+
+ if (alpha_target & AXP_OPCODE_BWX)
+ assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
+ else
+ {
+ int bitshift = 64 - 8 * (1 << lgsize);
+ expressionS newtok[3];
+
+ /* emit "sll src,bits,dst" */
+
+ newtok[0] = tok[0];
+ set_tok_const (newtok[1], bitshift);
+ newtok[2] = tok[ntok - 1];
+ assemble_tokens ("sll", newtok, 3, 1);
+
+ /* emit "sra dst,bits,dst" */
+
+ newtok[0] = newtok[2];
+ assemble_tokens ("sra", newtok, 3, 1);
+ }
+}
+
+/* Implement the division and modulus macros. */
+
+#ifdef OBJ_EVAX
+
+/* Make register usage like in normal procedure call.
+ Don't clobber PV and RA. */
+
+static void
+emit_division (tok, ntok, symname)
+ const expressionS *tok;
+ int ntok;
+ const PTR symname;
+{
+ /* DIVISION and MODULUS. Yech.
+ *
+ * Convert
+ * OP x,y,result
+ * to
+ * mov x,R16 # if x != R16
+ * mov y,R17 # if y != R17
+ * lda AT,__OP
+ * jsr AT,(AT),0
+ * mov R0,result
+ *
+ * with appropriate optimizations if R0,R16,R17 are the registers
+ * specified by the compiler.
+ */
+
+ int xr, yr, rr;
+ symbolS *sym;
+ expressionS newtok[3];
+
+ xr = regno (tok[0].X_add_number);
+ yr = regno (tok[1].X_add_number);
+
+ if (ntok < 3)
+ rr = xr;
+ else
+ rr = regno (tok[2].X_add_number);
+
+ /* Move the operands into the right place */
+ if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
+ {
+ /* They are in exactly the wrong order -- swap through AT */
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ set_tok_reg (newtok[0], AXP_REG_R16);
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_R17);
+ set_tok_reg (newtok[1], AXP_REG_R16);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_reg (newtok[1], AXP_REG_R17);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ else
+ {
+ if (yr == AXP_REG_R16)
+ {
+ set_tok_reg (newtok[0], AXP_REG_R16);
+ set_tok_reg (newtok[1], AXP_REG_R17);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (xr != AXP_REG_R16)
+ {
+ set_tok_reg (newtok[0], xr);
+ set_tok_reg (newtok[1], AXP_REG_R16);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
+ {
+ set_tok_reg (newtok[0], yr);
+ set_tok_reg (newtok[1], AXP_REG_R17);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ }
+
+ sym = symbol_find_or_make ((const char *)symname);
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_sym (newtok[1], sym, 0);
+ assemble_tokens ("lda", newtok, 2, 1);
+
+ /* Call the division routine */
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_cpreg (newtok[1], AXP_REG_AT);
+ set_tok_const (newtok[2], 0);
+ assemble_tokens ("jsr", newtok, 3, 1);
+
+ /* Move the result to the right place */
+ if (rr != AXP_REG_R0)
+ {
+ set_tok_reg (newtok[0], AXP_REG_R0);
+ set_tok_reg (newtok[1], rr);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+}
+
+#else /* !OBJ_EVAX */
+
+static void
+emit_division (tok, ntok, symname)
+ const expressionS *tok;
+ int ntok;
+ const PTR symname;
+{
+ /* DIVISION and MODULUS. Yech.
+ * Convert
+ * OP x,y,result
+ * to
+ * lda pv,__OP
+ * mov x,t10
+ * mov y,t11
+ * jsr t9,(pv),__OP
+ * mov t12,result
+ *
+ * with appropriate optimizations if t10,t11,t12 are the registers
+ * specified by the compiler.
+ */
+
+ int xr, yr, rr;
+ symbolS *sym;
+ expressionS newtok[3];
+
+ xr = regno (tok[0].X_add_number);
+ yr = regno (tok[1].X_add_number);
+
+ if (ntok < 3)
+ rr = xr;
+ else
+ rr = regno (tok[2].X_add_number);
+
+ sym = symbol_find_or_make ((const char *)symname);
+
+ /* Move the operands into the right place */
+ if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
+ {
+ /* They are in exactly the wrong order -- swap through AT */
+
+ if (alpha_noat_on)
+ as_bad (_("macro requires $at register while noat in effect"));
+
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[1], AXP_REG_AT);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_T11);
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ assemble_tokens ("mov", newtok, 2, 1);
+
+ set_tok_reg (newtok[0], AXP_REG_AT);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ else
+ {
+ if (yr == AXP_REG_T10)
+ {
+ set_tok_reg (newtok[0], AXP_REG_T10);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (xr != AXP_REG_T10)
+ {
+ set_tok_reg (newtok[0], xr);
+ set_tok_reg (newtok[1], AXP_REG_T10);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+
+ if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
+ {
+ set_tok_reg (newtok[0], yr);
+ set_tok_reg (newtok[1], AXP_REG_T11);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+ }
+
+ /* Call the division routine */
+ set_tok_reg (newtok[0], AXP_REG_T9);
+ set_tok_sym (newtok[1], sym, 0);
+ assemble_tokens ("jsr", newtok, 2, 1);
+
+ /* Reload the GP register */
+#ifdef OBJ_AOUT
+FIXME
+#endif
+#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
+ set_tok_reg (newtok[0], alpha_gp_register);
+ set_tok_const (newtok[1], 0);
+ set_tok_preg (newtok[2], AXP_REG_T9);
+ assemble_tokens ("ldgp", newtok, 3, 1);
+#endif
+
+ /* Move the result to the right place */
+ if (rr != AXP_REG_T12)
+ {
+ set_tok_reg (newtok[0], AXP_REG_T12);
+ set_tok_reg (newtok[1], rr);
+ assemble_tokens ("mov", newtok, 2, 1);
+ }
+}
+
+#endif /* !OBJ_EVAX */
+
+/* The jsr and jmp macros differ from their instruction counterparts
+ in that they can load the target address and default most
+ everything. */
+
+static void
+emit_jsrjmp (tok, ntok, vopname)
+ const expressionS *tok;
+ int ntok;
+ const PTR vopname;
+{
+ const char *opname = (const char *) vopname;
+ struct alpha_insn insn;
+ expressionS newtok[3];
+ int r, tokidx = 0, lituse = 0;
+
+ if (tokidx < ntok && tok[tokidx].X_op == O_register)
+ r = regno (tok[tokidx++].X_add_number);
+ else
+ r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
+
+ set_tok_reg (newtok[0], r);
+
+ if (tokidx < ntok &&
+ (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
+ r = regno (tok[tokidx++].X_add_number);
+#ifdef OBJ_EVAX
+ /* keep register if jsr $n.<sym> */
+#else
+ else
+ {
+ int basereg = alpha_gp_register;
+ lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
+ }
+#endif
+
+ set_tok_cpreg (newtok[1], r);
+
+#ifdef OBJ_EVAX
+ /* FIXME: Add hint relocs to BFD for evax. */
+#else
+ if (tokidx < ntok)
+ newtok[2] = tok[tokidx];
+ else
+#endif
+ set_tok_const (newtok[2], 0);
+
+ assemble_tokens_to_insn (opname, newtok, 3, &insn);
+
+ /* add the LITUSE fixup */
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ if (insn.nfixups > 0)
+ {
+ memmove (&insn.fixups[1], &insn.fixups[0],
+ sizeof(struct alpha_fixup) * insn.nfixups);
+ }
+ insn.nfixups++;
+ insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
+ insn.fixups[0].exp.X_op = O_constant;
+ insn.fixups[0].exp.X_add_number = 3;
+ }
+
+ emit_insn (&insn);
+}
+
+/* The ret and jcr instructions differ from their instruction
+ counterparts in that everything can be defaulted. */
+
+static void
+emit_retjcr (tok, ntok, vopname)
+ const expressionS *tok;
+ int ntok;
+ const PTR vopname;
+{
+ const char *opname = (const char *)vopname;
+ expressionS newtok[3];
+ int r, tokidx = 0;
+
+ if (tokidx < ntok && tok[tokidx].X_op == O_register)
+ r = regno (tok[tokidx++].X_add_number);
+ else
+ r = AXP_REG_ZERO;
+
+ set_tok_reg (newtok[0], r);
+
+ if (tokidx < ntok &&
+ (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
+ r = regno (tok[tokidx++].X_add_number);
+ else
+ r = AXP_REG_RA;
+
+ set_tok_cpreg (newtok[1], r);
+
+ if (tokidx < ntok)
+ newtok[2] = tok[tokidx];
+ else
+ set_tok_const (newtok[2], strcmp(opname, "ret") == 0);
+
+ assemble_tokens (opname, newtok, 3, 0);
+}
+
+/* Assembler directives */
+
+/* Handle the .text pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_text (i)
+ int i;
+
+{
+ s_text (i);
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+/* Handle the .data pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_data (i)
+ int i;
+{
+ s_data (i);
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+#if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
+
+/* Handle the OSF/1 and openVMS .comm pseudo quirks.
+ openVMS constructs a section for every common symbol. */
+
+static void
+s_alpha_comm (ignore)
+ int ignore;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT temp;
+ register symbolS *symbolP;
+
+#ifdef OBJ_EVAX
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ segT new_seg;
+#endif
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+
+ SKIP_WHITESPACE ();
+
+ /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+
+#ifdef OBJ_EVAX
+ /* Make a section for the common symbol. */
+ new_seg = subseg_new (xstrdup (name), 0);
+#endif
+
+ *p = c;
+
+#ifdef OBJ_EVAX
+ /* alignment might follow */
+ if (*input_line_pointer == ',')
+ {
+ offsetT align;
+
+ input_line_pointer++;
+ align = get_absolute_expression ();
+ bfd_set_section_alignment (stdoutput, new_seg, align);
+ }
+#endif
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+#ifdef OBJ_EVAX
+ if (bfd_section_size (stdoutput, new_seg) > 0)
+ {
+ if (bfd_section_size (stdoutput, new_seg) != temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) bfd_section_size (stdoutput, new_seg),
+ (long) temp);
+ }
+#else
+ if (S_GET_VALUE (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) temp);
+ }
+#endif
+ else
+ {
+#ifdef OBJ_EVAX
+ subseg_set (new_seg, 0);
+ p = frag_more (temp);
+ new_seg->flags |= SEC_IS_COMMON;
+ if (! S_IS_DEFINED (symbolP))
+ symbolP->bsym->section = new_seg;
+#else
+ S_SET_VALUE (symbolP, (valueT) temp);
+#endif
+ S_SET_EXTERNAL (symbolP);
+ }
+
+#ifdef OBJ_EVAX
+ subseg_set (current_section, current_subsec);
+#endif
+
+ know (symbolP->sy_frag == &zero_address_frag);
+
+ demand_empty_rest_of_line ();
+}
+
+#endif /* ! OBJ_ELF */
+
+#ifdef OBJ_ECOFF
+
+/* Handle the .rdata pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_rdata (ignore)
+ int ignore;
+{
+ int temp;
+
+ temp = get_absolute_expression ();
+ subseg_new (".rdata", 0);
+ demand_empty_rest_of_line ();
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+#endif
+
+#ifdef OBJ_ECOFF
+
+/* Handle the .sdata pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_sdata (ignore)
+ int ignore;
+{
+ int temp;
+
+ temp = get_absolute_expression ();
+ subseg_new (".sdata", 0);
+ demand_empty_rest_of_line ();
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+#endif
+
+#ifdef OBJ_ELF
+
+/* Handle the .section pseudo-op. This is like the usual one, but it
+ clears alpha_insn_label and restores auto alignment. */
+
+static void
+s_alpha_section (ignore)
+ int ignore;
+{
+ obj_elf_section (ignore);
+
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+static void
+s_alpha_ent (dummy)
+ int dummy;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_ent (0);
+ else
+ {
+ char *name, name_end;
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (! is_name_beginner (*name))
+ {
+ as_warn (_(".ent directive has no name"));
+ *input_line_pointer = name_end;
+ }
+ else
+ {
+ symbolS *sym;
+
+ if (alpha_cur_ent_sym)
+ as_warn (_("nested .ent directives"));
+
+ sym = symbol_find_or_make (name);
+ sym->bsym->flags |= BSF_FUNCTION;
+ alpha_cur_ent_sym = sym;
+
+ /* The .ent directive is sometimes followed by a number. Not sure
+ what it really means, but ignore it. */
+ *input_line_pointer = name_end;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+ if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
+ (void) get_absolute_expression ();
+ }
+ demand_empty_rest_of_line ();
+ }
+}
+
+static void
+s_alpha_end (dummy)
+ int dummy;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_end (0);
+ else
+ {
+ char *name, name_end;
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (! is_name_beginner (*name))
+ {
+ as_warn (_(".end directive has no name"));
+ *input_line_pointer = name_end;
+ }
+ else
+ {
+ symbolS *sym;
+
+ sym = symbol_find (name);
+ if (sym != alpha_cur_ent_sym)
+ as_warn (_(".end directive names different symbol than .ent"));
+
+ /* Create an expression to calculate the size of the function. */
+ if (sym)
+ {
+ sym->sy_obj.size = (expressionS *) xmalloc (sizeof (expressionS));
+ sym->sy_obj.size->X_op = O_subtract;
+ sym->sy_obj.size->X_add_symbol
+ = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
+ sym->sy_obj.size->X_op_symbol = sym;
+ sym->sy_obj.size->X_add_number = 0;
+ }
+
+ alpha_cur_ent_sym = NULL;
+
+ *input_line_pointer = name_end;
+ }
+ demand_empty_rest_of_line ();
+ }
+}
+
+static void
+s_alpha_mask (fp)
+ int fp;
+{
+ if (ECOFF_DEBUGGING)
+ {
+ if (fp)
+ ecoff_directive_fmask (0);
+ else
+ ecoff_directive_mask (0);
+ }
+ else
+ discard_rest_of_line ();
+}
+
+static void
+s_alpha_frame (dummy)
+ int dummy;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_frame (0);
+ else
+ discard_rest_of_line ();
+}
+
+static void
+s_alpha_prologue (ignore)
+ int ignore;
+{
+ symbolS *sym;
+ int arg;
+
+ arg = get_absolute_expression ();
+ demand_empty_rest_of_line ();
+
+ if (ECOFF_DEBUGGING)
+ sym = ecoff_get_cur_proc_sym ();
+ else
+ sym = alpha_cur_ent_sym;
+ know (sym != NULL);
+
+ switch (arg)
+ {
+ case 0: /* No PV required. */
+ S_SET_OTHER (sym, STO_ALPHA_NOPV);
+ break;
+ case 1: /* Std GP load. */
+ S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD);
+ break;
+ case 2: /* Non-std use of PV. */
+ break;
+
+ default:
+ as_bad (_("Invalid argument %d to .prologue."), arg);
+ break;
+ }
+}
+
+static void
+s_alpha_coff_wrapper (which)
+ int which;
+{
+ static void (* const fns[]) PARAMS ((int)) = {
+ ecoff_directive_begin,
+ ecoff_directive_bend,
+ ecoff_directive_def,
+ ecoff_directive_dim,
+ ecoff_directive_endef,
+ ecoff_directive_file,
+ ecoff_directive_scl,
+ ecoff_directive_tag,
+ ecoff_directive_val,
+ ecoff_directive_loc,
+ };
+
+ assert (which >= 0 && which < sizeof(fns)/sizeof(*fns));
+
+ if (ECOFF_DEBUGGING)
+ (*fns[which])(0);
+ else
+ {
+ as_bad (_("ECOFF debugging is disabled."));
+ ignore_rest_of_line ();
+ }
+}
+#endif /* OBJ_ELF */
+
+#ifdef OBJ_EVAX
+
+/* Handle the section specific pseudo-op. */
+
+static void
+s_alpha_section (secid)
+ int secid;
+{
+ int temp;
+#define EVAX_SECTION_COUNT 5
+ static char *section_name[EVAX_SECTION_COUNT+1] =
+ { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
+
+ if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
+ {
+ as_fatal (_("Unknown section directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ temp = get_absolute_expression ();
+ subseg_new (section_name[secid], 0);
+ demand_empty_rest_of_line ();
+ alpha_insn_label = NULL;
+ alpha_auto_align_on = 1;
+ alpha_current_align = 0;
+}
+
+
+/* Parse .ent directives. */
+
+static void
+s_alpha_ent (ignore)
+ int ignore;
+{
+ symbolS *symbol;
+ expressionS symexpr;
+
+ alpha_evax_proc.pdsckind = 0;
+ alpha_evax_proc.framereg = -1;
+ alpha_evax_proc.framesize = 0;
+ alpha_evax_proc.rsa_offset = 0;
+ alpha_evax_proc.ra_save = AXP_REG_RA;
+ alpha_evax_proc.fp_save = -1;
+ alpha_evax_proc.imask = 0;
+ alpha_evax_proc.fmask = 0;
+ alpha_evax_proc.prologue = 0;
+ alpha_evax_proc.type = 0;
+
+ expression (&symexpr);
+
+ if (symexpr.X_op != O_symbol)
+ {
+ as_fatal (_(".ent directive has no symbol"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ symbol = make_expr_symbol (&symexpr);
+ symbol->bsym->flags |= BSF_FUNCTION;
+ alpha_evax_proc.symbol = symbol;
+
+ demand_empty_rest_of_line ();
+ return;
+}
+
+
+/* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
+
+static void
+s_alpha_frame (ignore)
+ int ignore;
+{
+ long val;
+
+ alpha_evax_proc.framereg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .frame directive 1./2. param"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ alpha_evax_proc.framesize = val;
+
+ (void) tc_get_register (1);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ',')
+ {
+ as_warn (_("Bad .frame directive 3./4. param"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ alpha_evax_proc.rsa_offset = get_absolute_expression ();
+
+ return;
+}
+
+static void
+s_alpha_pdesc (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+ long val;
+ register char *p;
+ expressionS exp;
+ symbolS *entry_sym;
+ fixS *fixp;
+ segment_info_type *seginfo = seg_info (alpha_link_section);
+
+ if (now_seg != alpha_link_section)
+ {
+ as_bad (_(".pdesc directive not in link (.link) section"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if ((alpha_evax_proc.symbol == 0)
+ || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
+ {
+ as_fatal (_(".pdesc has no matching .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ alpha_evax_proc.symbol->sy_obj = (valueT)seginfo->literal_pool_size;
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_warn (_(".pdesc directive has no entry symbol"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ entry_sym = make_expr_symbol (&exp);
+ /* Save bfd symbol of proc desc in function symbol. */
+ alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ',')
+ {
+ as_warn (_("No comma after .pdesc <entryname>"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (strncmp(name, "stack", 5) == 0)
+ {
+ alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
+ }
+ else if (strncmp(name, "reg", 3) == 0)
+ {
+ alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
+ }
+ else if (strncmp(name, "null", 4) == 0)
+ {
+ alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
+ }
+ else
+ {
+ as_fatal (_("unknown procedure kind"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ frag_align (3, 0, 0);
+ p = frag_more (16);
+ fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
+ fixp->fx_done = 1;
+ seginfo->literal_pool_size += 16;
+
+ *p = alpha_evax_proc.pdsckind
+ | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
+ *(p+1) = PDSC_S_M_NATIVE
+ | PDSC_S_M_NO_JACKET;
+
+ switch (alpha_evax_proc.pdsckind)
+ {
+ case PDSC_S_K_KIND_NULL:
+ *(p+2) = 0;
+ *(p+3) = 0;
+ break;
+ case PDSC_S_K_KIND_FP_REGISTER:
+ *(p+2) = alpha_evax_proc.fp_save;
+ *(p+3) = alpha_evax_proc.ra_save;
+ break;
+ case PDSC_S_K_KIND_FP_STACK:
+ md_number_to_chars (p+2, (valueT)alpha_evax_proc.rsa_offset, 2);
+ break;
+ default: /* impossible */
+ break;
+ }
+
+ *(p+4) = 0;
+ *(p+5) = alpha_evax_proc.type & 0x0f;
+
+ /* Signature offset. */
+ md_number_to_chars (p+6, (valueT)0, 2);
+
+ fix_new_exp (frag_now, p-frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
+
+ if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
+ return;
+
+ /* Add dummy fix to make add_to_link_pool work. */
+ p = frag_more (8);
+ fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
+ fixp->fx_done = 1;
+ seginfo->literal_pool_size += 8;
+
+ /* pdesc+16: Size. */
+ md_number_to_chars (p, (valueT)alpha_evax_proc.framesize, 4);
+
+ md_number_to_chars (p+4, (valueT)0, 2);
+
+ /* Entry length. */
+ md_number_to_chars (p+6, alpha_evax_proc.prologue, 2);
+
+ if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
+ return;
+
+ /* Add dummy fix to make add_to_link_pool work. */
+ p = frag_more (8);
+ fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
+ fixp->fx_done = 1;
+ seginfo->literal_pool_size += 8;
+
+ /* pdesc+24: register masks. */
+
+ md_number_to_chars (p, alpha_evax_proc.imask, 4);
+ md_number_to_chars (p+4, alpha_evax_proc.fmask, 4);
+
+ return;
+}
+
+
+/* Support for crash debug on vms. */
+
+static void
+s_alpha_name (ignore)
+ int ignore;
+{
+ register char *p;
+ expressionS exp;
+ segment_info_type *seginfo = seg_info (alpha_link_section);
+
+ if (now_seg != alpha_link_section)
+ {
+ as_bad (_(".name directive not in link (.link) section"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_warn (_(".name directive has no symbol"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ demand_empty_rest_of_line ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ frag_align (3, 0, 0);
+ p = frag_more (8);
+ seginfo->literal_pool_size += 8;
+
+ fix_new_exp (frag_now, p-frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
+
+ return;
+}
+
+
+static void
+s_alpha_linkage (ignore)
+ int ignore;
+{
+ expressionS exp;
+ char *p;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_fatal (_("No symbol after .linkage"));
+ }
+ else
+ {
+ p = frag_more (LKP_S_K_SIZE);
+ memset (p, 0, LKP_S_K_SIZE);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
+ BFD_RELOC_ALPHA_LINKAGE);
+ }
+ demand_empty_rest_of_line ();
+
+ return;
+}
+
+
+static void
+s_alpha_code_address (ignore)
+ int ignore;
+{
+ expressionS exp;
+ char *p;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_fatal (_("No symbol after .code_address"));
+ }
+ else
+ {
+ p = frag_more (8);
+ memset (p, 0, 8);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
+ BFD_RELOC_ALPHA_CODEADDR);
+ }
+ demand_empty_rest_of_line ();
+
+ return;
+}
+
+
+static void
+s_alpha_fp_save (ignore)
+ int ignore;
+{
+
+ alpha_evax_proc.fp_save = tc_get_register (1);
+
+ demand_empty_rest_of_line ();
+ return;
+}
+
+
+static void
+s_alpha_mask (ignore)
+ int ignore;
+{
+ long val;
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .mask directive"));
+ --input_line_pointer;
+ }
+ else
+ {
+ alpha_evax_proc.imask = val;
+ (void)get_absolute_expression ();
+ }
+ demand_empty_rest_of_line ();
+
+ return;
+}
+
+
+static void
+s_alpha_fmask (ignore)
+ int ignore;
+{
+ long val;
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .fmask directive"));
+ --input_line_pointer;
+ }
+ else
+ {
+ alpha_evax_proc.fmask = val;
+ (void) get_absolute_expression ();
+ }
+ demand_empty_rest_of_line ();
+
+ return;
+}
+
+static void
+s_alpha_end (ignore)
+ int ignore;
+{
+ char c;
+
+ c = get_symbol_end ();
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+ alpha_evax_proc.symbol = 0;
+
+ return;
+}
+
+
+static void
+s_alpha_file (ignore)
+ int ignore;
+{
+ symbolS *s;
+ int length;
+ static char case_hack[32];
+
+ extern char *demand_copy_string PARAMS ((int *lenP));
+
+ sprintf (case_hack, "<CASE:%01d%01d>",
+ alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
+
+ s = symbol_find_or_make (case_hack);
+ s->bsym->flags |= BSF_FILE;
+
+ get_absolute_expression ();
+ s = symbol_find_or_make (demand_copy_string (&length));
+ s->bsym->flags |= BSF_FILE;
+ demand_empty_rest_of_line ();
+
+ return;
+}
+#endif /* OBJ_EVAX */
+
+/* Handle the .gprel32 pseudo op. */
+
+static void
+s_alpha_gprel32 (ignore)
+ int ignore;
+{
+ expressionS e;
+ char *p;
+
+ SKIP_WHITESPACE ();
+ expression (&e);
+
+#ifdef OBJ_ELF
+ switch (e.X_op)
+ {
+ case O_constant:
+ e.X_add_symbol = section_symbol(absolute_section);
+ e.X_op = O_symbol;
+ /* FALLTHRU */
+ case O_symbol:
+ break;
+ default:
+ abort();
+ }
+#else
+#ifdef OBJ_ECOFF
+ switch (e.X_op)
+ {
+ case O_constant:
+ e.X_add_symbol = section_symbol (absolute_section);
+ /* fall through */
+ case O_symbol:
+ e.X_op = O_subtract;
+ e.X_op_symbol = alpha_gp_symbol;
+ break;
+ default:
+ abort ();
+ }
+#endif
+#endif
+
+ if (alpha_auto_align_on && alpha_current_align < 2)
+ alpha_align (2, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > 2)
+ alpha_current_align = 2;
+ alpha_insn_label = NULL;
+
+ p = frag_more (4);
+ memset (p, 0, 4);
+ fix_new_exp (frag_now, p-frag_now->fr_literal, 4,
+ &e, 0, BFD_RELOC_GPREL32);
+}
+
+/* Handle floating point allocation pseudo-ops. This is like the
+ generic vresion, but it makes sure the current label, if any, is
+ correctly aligned. */
+
+static void
+s_alpha_float_cons (type)
+ int type;
+{
+ int log_size;
+
+ switch (type)
+ {
+ default:
+ case 'f':
+ case 'F':
+ log_size = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'G':
+ log_size = 3;
+ break;
+
+ case 'x':
+ case 'X':
+ case 'p':
+ case 'P':
+ log_size = 4;
+ break;
+ }
+
+ if (alpha_auto_align_on && alpha_current_align < log_size)
+ alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > log_size)
+ alpha_current_align = log_size;
+ alpha_insn_label = NULL;
+
+ float_cons (type);
+}
+
+/* Handle the .proc pseudo op. We don't really do much with it except
+ parse it. */
+
+static void
+s_alpha_proc (is_static)
+ int is_static;
+{
+ char *name;
+ char c;
+ char *p;
+ symbolS *symbolP;
+ int temp;
+
+ /* Takes ".proc name,nargs" */
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_warn (_("Expected comma after name \"%s\""), name);
+ *p = c;
+ temp = 0;
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ }
+ /* symbolP->sy_other = (signed char) temp; */
+ as_warn (_("unhandled: .proc %s,%d"), name, temp);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .set pseudo op. This is used to turn on and off most of
+ the assembler features. */
+
+static void
+s_alpha_set (x)
+ int x;
+{
+ char *name, ch, *s;
+ int yesno = 1;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ ch = get_symbol_end ();
+
+ s = name;
+ if (s[0] == 'n' && s[1] == 'o')
+ {
+ yesno = 0;
+ s += 2;
+ }
+ if (!strcmp ("reorder", s))
+ /* ignore */ ;
+ else if (!strcmp ("at", s))
+ alpha_noat_on = !yesno;
+ else if (!strcmp ("macro", s))
+ alpha_macros_on = yesno;
+ else if (!strcmp ("move", s))
+ /* ignore */ ;
+ else if (!strcmp ("volatile", s))
+ /* ignore */ ;
+ else
+ as_warn (_("Tried to .set unrecognized mode `%s'"), name);
+
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .base pseudo op. This changes the assembler's notion of
+ the $gp register. */
+
+static void
+s_alpha_base (ignore)
+ int ignore;
+{
+#if 0
+ if (first_32bit_quadrant)
+ {
+ /* not fatal, but it might not work in the end */
+ as_warn (_("File overrides no-base-register option."));
+ first_32bit_quadrant = 0;
+ }
+#endif
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '$')
+ { /* $rNN form */
+ input_line_pointer++;
+ if (*input_line_pointer == 'r')
+ input_line_pointer++;
+ }
+
+ alpha_gp_register = get_absolute_expression ();
+ if (alpha_gp_register < 0 || alpha_gp_register > 31)
+ {
+ alpha_gp_register = AXP_REG_GP;
+ as_warn (_("Bad base register, using $%d."), alpha_gp_register);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .align pseudo-op. This aligns to a power of two. It
+ also adjusts any current instruction label. We treat this the same
+ way the MIPS port does: .align 0 turns off auto alignment. */
+
+static void
+s_alpha_align (ignore)
+ int ignore;
+{
+ int align;
+ char fill, *pfill;
+ long max_alignment = 15;
+
+ align = get_absolute_expression ();
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_bad (_("Alignment too large: %d. assumed"), align);
+ }
+ else if (align < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed"));
+ align = 0;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ fill = get_absolute_expression ();
+ pfill = &fill;
+ }
+ else
+ pfill = NULL;
+
+ if (align != 0)
+ {
+ alpha_auto_align_on = 1;
+ alpha_align (align, pfill, alpha_insn_label, 1);
+ }
+ else
+ {
+ alpha_auto_align_on = 0;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Hook the normal string processor to reset known alignment. */
+
+static void
+s_alpha_stringer (terminate)
+ int terminate;
+{
+ alpha_current_align = 0;
+ alpha_insn_label = NULL;
+ stringer (terminate);
+}
+
+/* Hook the normal space processing to reset known alignment. */
+
+static void
+s_alpha_space (ignore)
+ int ignore;
+{
+ alpha_current_align = 0;
+ alpha_insn_label = NULL;
+ s_space (ignore);
+}
+
+/* Hook into cons for auto-alignment. */
+
+void
+alpha_cons_align (size)
+ int size;
+{
+ int log_size;
+
+ log_size = 0;
+ while ((size >>= 1) != 0)
+ ++log_size;
+
+ if (alpha_auto_align_on && alpha_current_align < log_size)
+ alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
+ if (alpha_current_align > log_size)
+ alpha_current_align = log_size;
+ alpha_insn_label = NULL;
+}
+
+/* Here come the .uword, .ulong, and .uquad explicitly unaligned
+ pseudos. We just turn off auto-alignment and call down to cons. */
+
+static void
+s_alpha_ucons (bytes)
+ int bytes;
+{
+ int hold = alpha_auto_align_on;
+ alpha_auto_align_on = 0;
+ cons (bytes);
+ alpha_auto_align_on = hold;
+}
+
+/* Switch the working cpu type. */
+
+static void
+s_alpha_arch (ignored)
+ int ignored;
+{
+ char *name, ch;
+ const struct cpu_type *p;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ ch = get_symbol_end ();
+
+ for (p = cpu_types; p->name; ++p)
+ if (strcmp(name, p->name) == 0)
+ {
+ alpha_target_name = p->name, alpha_target = p->flags;
+ goto found;
+ }
+ as_warn("Unknown CPU identifier `%s'", name);
+
+found:
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+
+
+#ifdef DEBUG1
+/* print token expression with alpha specific extension. */
+
+static void
+alpha_print_token(f, exp)
+ FILE *f;
+ const expressionS *exp;
+{
+ switch (exp->X_op)
+ {
+ case O_cpregister:
+ putc (',', f);
+ /* FALLTHRU */
+ case O_pregister:
+ putc ('(', f);
+ {
+ expressionS nexp = *exp;
+ nexp.X_op = O_register;
+ print_expr (f, &nexp);
+ }
+ putc (')', f);
+ break;
+ default:
+ print_expr (f, exp);
+ break;
+ }
+ return;
+}
+#endif
+
+/* The target specific pseudo-ops which we support. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+#ifdef OBJ_ECOFF
+ {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
+ {"rdata", s_alpha_rdata, 0},
+#endif
+ {"text", s_alpha_text, 0},
+ {"data", s_alpha_data, 0},
+#ifdef OBJ_ECOFF
+ {"sdata", s_alpha_sdata, 0},
+#endif
+#ifdef OBJ_ELF
+ {"section", s_alpha_section, 0},
+ {"section.s", s_alpha_section, 0},
+ {"sect", s_alpha_section, 0},
+ {"sect.s", s_alpha_section, 0},
+#endif
+#ifdef OBJ_EVAX
+ { "pdesc", s_alpha_pdesc, 0},
+ { "name", s_alpha_name, 0},
+ { "linkage", s_alpha_linkage, 0},
+ { "code_address", s_alpha_code_address, 0},
+ { "ent", s_alpha_ent, 0},
+ { "frame", s_alpha_frame, 0},
+ { "fp_save", s_alpha_fp_save, 0},
+ { "mask", s_alpha_mask, 0},
+ { "fmask", s_alpha_fmask, 0},
+ { "end", s_alpha_end, 0},
+ { "file", s_alpha_file, 0},
+ { "rdata", s_alpha_section, 1},
+ { "comm", s_alpha_comm, 0},
+ { "link", s_alpha_section, 3},
+ { "ctors", s_alpha_section, 4},
+ { "dtors", s_alpha_section, 5},
+#endif
+#ifdef OBJ_ELF
+ /* Frame related pseudos. */
+ {"ent", s_alpha_ent, 0},
+ {"end", s_alpha_end, 0},
+ {"mask", s_alpha_mask, 0},
+ {"fmask", s_alpha_mask, 1},
+ {"frame", s_alpha_frame, 0},
+ {"prologue", s_alpha_prologue, 0},
+ /* COFF debugging related pseudos. */
+ {"begin", s_alpha_coff_wrapper, 0},
+ {"bend", s_alpha_coff_wrapper, 1},
+ {"def", s_alpha_coff_wrapper, 2},
+ {"dim", s_alpha_coff_wrapper, 3},
+ {"endef", s_alpha_coff_wrapper, 4},
+ {"file", s_alpha_coff_wrapper, 5},
+ {"scl", s_alpha_coff_wrapper, 6},
+ {"tag", s_alpha_coff_wrapper, 7},
+ {"val", s_alpha_coff_wrapper, 8},
+ {"loc", s_alpha_coff_wrapper, 9},
+#else
+ {"prologue", s_ignore, 0},
+#endif
+ {"gprel32", s_alpha_gprel32, 0},
+ {"t_floating", s_alpha_float_cons, 'd'},
+ {"s_floating", s_alpha_float_cons, 'f'},
+ {"f_floating", s_alpha_float_cons, 'F'},
+ {"g_floating", s_alpha_float_cons, 'G'},
+ {"d_floating", s_alpha_float_cons, 'D'},
+
+ {"proc", s_alpha_proc, 0},
+ {"aproc", s_alpha_proc, 1},
+ {"set", s_alpha_set, 0},
+ {"reguse", s_ignore, 0},
+ {"livereg", s_ignore, 0},
+ {"base", s_alpha_base, 0}, /*??*/
+ {"option", s_ignore, 0},
+ {"aent", s_ignore, 0},
+ {"ugen", s_ignore, 0},
+ {"eflag", s_ignore, 0},
+
+ {"align", s_alpha_align, 0},
+ {"double", s_alpha_float_cons, 'd'},
+ {"float", s_alpha_float_cons, 'f'},
+ {"single", s_alpha_float_cons, 'f'},
+ {"ascii", s_alpha_stringer, 0},
+ {"asciz", s_alpha_stringer, 1},
+ {"string", s_alpha_stringer, 1},
+ {"space", s_alpha_space, 0},
+ {"skip", s_alpha_space, 0},
+ {"zero", s_alpha_space, 0},
+
+/* Unaligned data pseudos. */
+ {"uword", s_alpha_ucons, 2},
+ {"ulong", s_alpha_ucons, 4},
+ {"uquad", s_alpha_ucons, 8},
+
+#ifdef OBJ_ELF
+/* Dwarf wants these versions of unaligned. */
+ {"2byte", s_alpha_ucons, 2},
+ {"4byte", s_alpha_ucons, 4},
+ {"8byte", s_alpha_ucons, 8},
+#endif
+
+/* We don't do any optimizing, so we can safely ignore these. */
+ {"noalias", s_ignore, 0},
+ {"alias", s_ignore, 0},
+
+ {"arch", s_alpha_arch, 0},
+
+ {NULL, 0, 0},
+};
+
+
+/* Build a BFD section with its flags set appropriately for the .lita,
+ .lit8, or .lit4 sections. */
+
+static void
+create_literal_section (name, secp, symp)
+ const char *name;
+ segT *secp;
+ symbolS **symp;
+{
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ segT new_sec;
+
+ *secp = new_sec = subseg_new (name, 0);
+ subseg_set (current_section, current_subsec);
+ bfd_set_section_alignment (stdoutput, new_sec, 4);
+ bfd_set_section_flags (stdoutput, new_sec,
+ SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_DATA);
+
+ S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
+}
+
+#ifdef OBJ_ECOFF
+
+/* @@@ GP selection voodoo. All of this seems overly complicated and
+ unnecessary; which is the primary reason it's for ECOFF only. */
+
+static inline void
+maybe_set_gp (sec)
+ asection *sec;
+{
+ bfd_vma vma;
+ if (!sec)
+ return;
+ vma = bfd_get_section_vma (foo, sec);
+ if (vma && vma < alpha_gp_value)
+ alpha_gp_value = vma;
+}
+
+static void
+select_gp_value ()
+{
+ assert (alpha_gp_value == 0);
+
+ /* Get minus-one in whatever width... */
+ alpha_gp_value = 0; alpha_gp_value--;
+
+ /* Select the smallest VMA of these existing sections. */
+ maybe_set_gp (alpha_lita_section);
+#if 0
+ /* These were disabled before -- should we use them? */
+ maybe_set_gp (sdata);
+ maybe_set_gp (lit8_sec);
+ maybe_set_gp (lit4_sec);
+#endif
+
+/* @@ Will a simple 0x8000 work here? If not, why not? */
+#define GP_ADJUSTMENT (0x8000 - 0x10)
+
+ alpha_gp_value += GP_ADJUSTMENT;
+
+ S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
+
+#ifdef DEBUG1
+ printf (_("Chose GP value of %lx\n"), alpha_gp_value);
+#endif
+}
+#endif /* OBJ_ECOFF */
+
+/* Called internally to handle all alignment needs. This takes care
+ of eliding calls to frag_align if'n the cached current alignment
+ says we've already got it, as well as taking care of the auto-align
+ feature wrt labels. */
+
+static void
+alpha_align (n, pfill, label, force)
+ int n;
+ char *pfill;
+ symbolS *label;
+ int force;
+{
+ if (alpha_current_align >= n)
+ return;
+
+ if (pfill == NULL)
+ {
+ if (n > 2
+ && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ {
+ static char const unop[4] = { 0x00, 0x00, 0xe0, 0x2f };
+ static char const nopunop[8] = {
+ 0x1f, 0x04, 0xff, 0x47,
+ 0x00, 0x00, 0xe0, 0x2f
+ };
+
+ /* First, make sure we're on a four-byte boundary, in case
+ someone has been putting .byte values into the text
+ section. The DEC assembler silently fills with unaligned
+ no-op instructions. This will zero-fill, then nop-fill
+ with proper alignment. */
+ if (alpha_current_align < 2)
+ frag_align (2, 0, 0);
+ if (alpha_current_align < 3)
+ frag_align_pattern (3, unop, sizeof unop, 0);
+ if (n > 3)
+ frag_align_pattern (n, nopunop, sizeof nopunop, 0);
+ }
+ else
+ frag_align (n, 0, 0);
+ }
+ else
+ frag_align (n, *pfill, 0);
+
+ alpha_current_align = n;
+
+ if (label != NULL)
+ {
+ assert (S_GET_SEGMENT (label) == now_seg);
+ label->sy_frag = frag_now;
+ S_SET_VALUE (label, (valueT) frag_now_fix ());
+ }
+
+ record_alignment(now_seg, n);
+
+ /* ??? if alpha_flag_relax && force && elf, record the requested alignment
+ in a reloc for the linker to see. */
+}
+
+/* The Alpha has support for some VAX floating point types, as well as for
+ IEEE floating point. We consider IEEE to be the primary floating point
+ format, and sneak in the VAX floating point support here. */
+#define md_atof vax_md_atof
+#include "config/atof-vax.c"
diff --git a/gas/config/tc-alpha.h b/gas/config/tc-alpha.h
new file mode 100644
index 00000000000..ca6903a70a1
--- /dev/null
+++ b/gas/config/tc-alpha.h
@@ -0,0 +1,104 @@
+/* This file is tc-alpha.h
+ Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Written by Ken Raeburn <raeburn@cygnus.com>.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_ALPHA
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define WORKING_DOT_WORD
+
+#define TARGET_ARCH bfd_arch_alpha
+
+#define TARGET_FORMAT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+ ? "ecoff-littlealpha" \
+ : OUTPUT_FLAVOR == bfd_target_elf_flavour \
+ ? "elf64-alpha" \
+ : OUTPUT_FLAVOR == bfd_target_evax_flavour \
+ ? "vms-alpha" \
+ : "unknown-format")
+
+#define NEED_LITERAL_POOL
+#define TC_HANDLES_FX_DONE
+#define REPEAT_CONS_EXPRESSIONS
+
+extern int alpha_force_relocation PARAMS ((struct fix *));
+extern int alpha_fix_adjustable PARAMS ((struct fix *));
+
+extern unsigned long alpha_gprmask, alpha_fprmask;
+extern valueT alpha_gp_value;
+
+#define TC_FORCE_RELOCATION(FIXP) alpha_force_relocation (FIXP)
+#define tc_fix_adjustable(FIXP) alpha_fix_adjustable (FIXP)
+#define RELOC_REQUIRES_SYMBOL
+
+/* This expression evaluates to false if the relocation is for a local
+ object for which we still want to do the relocation at runtime.
+ True if we are willing to perform this relocation while building
+ the .o file. This is only used for pcrel relocations. */
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy)))
+
+#define md_convert_frag(b,s,f) as_fatal ("alpha convert_frag\n")
+#define md_estimate_size_before_relax(f,s) \
+ (as_fatal("estimate_size_before_relax called"),1)
+#define md_operand(x)
+
+#ifdef OBJ_EVAX
+
+/* This field keeps the symbols position in the link section. */
+#define OBJ_SYMFIELD_TYPE valueT
+
+#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) \
+ fix_new_exp (FRAG, OFF, (int)LEN, EXP, 0, \
+ LEN == 2 ? BFD_RELOC_16 \
+ : LEN == 4 ? BFD_RELOC_32 \
+ : LEN == 8 ? BFD_RELOC_64 \
+ : BFD_RELOC_ALPHA_LINKAGE);
+#endif
+
+#define md_number_to_chars number_to_chars_littleendian
+
+extern int tc_get_register PARAMS ((int frame));
+extern void alpha_frob_ecoff_data PARAMS ((void));
+
+#define tc_frob_label(sym) alpha_define_label (sym)
+extern void alpha_define_label PARAMS ((struct symbol *));
+
+#define md_cons_align(nbytes) alpha_cons_align (nbytes)
+extern void alpha_cons_align PARAMS ((int));
+
+#ifdef OBJ_ECOFF
+#define tc_frob_file_before_adjust() alpha_frob_file_before_adjust ()
+extern void alpha_frob_file_before_adjust PARAMS ((void));
+#endif
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
+#ifdef OBJ_ELF
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
+#endif
diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
new file mode 100644
index 00000000000..c07c2d791aa
--- /dev/null
+++ b/gas/config/tc-arc.c
@@ -0,0 +1,1481 @@
+/* tc-arc.c -- Assembler for the ARC
+ Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/arc.h"
+#include "elf/arc.h"
+
+extern int arc_get_mach PARAMS ((char *));
+
+static arc_insn arc_insert_operand PARAMS ((arc_insn,
+ const struct arc_operand *, int,
+ const struct arc_operand_value *,
+ offsetT, char *, unsigned int));
+static void arc_common PARAMS ((int));
+static void arc_cpu PARAMS ((int));
+/*static void arc_rename PARAMS ((int));*/
+static int get_arc_exp_reloc_type PARAMS ((int, int, expressionS *,
+ expressionS *));
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
+ { "common", arc_common, 0 },
+/*{ "hword", cons, 2 }, - already exists */
+ { "word", cons, 4 },
+/*{ "xword", cons, 8 },*/
+ { "cpu", arc_cpu, 0 },
+/*{ "rename", arc_rename, 0 },*/
+ { NULL, 0, 0 },
+};
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = "#;";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments started like this one will always
+ work if '/' isn't otherwise defined. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdD";
+
+/* Byte order. */
+extern int target_big_endian;
+const char *arc_target_format = DEFAULT_TARGET_FORMAT;
+static int byte_order = DEFAULT_BYTE_ORDER;
+
+/* One of bfd_mach_arc_xxx. */
+static int arc_mach_type = bfd_mach_arc_base;
+
+/* Non-zero if the cpu type has been explicitly specified. */
+static int mach_type_specified_p = 0;
+
+/* Non-zero if opcode tables have been initialized.
+ A .cpu command must appear before any instructions. */
+static int cpu_tables_init_p = 0;
+
+static struct hash_control *arc_suffix_hash = NULL;
+
+const char *md_shortopts = "";
+struct option md_longopts[] =
+{
+#define OPTION_EB (OPTION_MD_BASE + 0)
+ {"EB", no_argument, NULL, OPTION_EB},
+#define OPTION_EL (OPTION_MD_BASE + 1)
+ {"EL", no_argument, NULL, OPTION_EL},
+ { NULL, no_argument, NULL, 0 }
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+/*
+ * md_parse_option
+ *
+ * Invocation line includes a switch not recognized by the base assembler.
+ * See if it's a processor-specific option.
+ */
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case OPTION_EB:
+ byte_order = BIG_ENDIAN;
+ arc_target_format = "elf32-bigarc";
+ break;
+ case OPTION_EL:
+ byte_order = LITTLE_ENDIAN;
+ arc_target_format = "elf32-littlearc";
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\
+ARC options:\n\
+-EB generate big endian output\n\
+-EL generate little endian output\n"));
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need.
+ Opcode selection is defered until later because we might see a .cpu
+ command. */
+
+void
+md_begin ()
+{
+ /* The endianness can be chosen "at the factory". */
+ target_big_endian = byte_order == BIG_ENDIAN;
+
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
+ as_warn (_("could not set architecture and machine"));
+
+ /* Assume the base cpu. This call is necessary because we need to
+ initialize `arc_operand_map' which may be needed before we see the
+ first insn. */
+ arc_opcode_init_tables (arc_get_opcode_mach (bfd_mach_arc_base,
+ target_big_endian));
+}
+
+/* Initialize the various opcode and operand tables.
+ MACH is one of bfd_mach_arc_xxx. */
+
+static void
+init_opcode_tables (mach)
+ int mach;
+{
+ register unsigned int i;
+ char *last;
+
+ if ((arc_suffix_hash = hash_new ()) == NULL)
+ as_fatal (_("virtual memory exhausted"));
+
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
+ as_warn (_("could not set architecture and machine"));
+
+ /* This initializes a few things in arc-opc.c that we need.
+ This must be called before the various arc_xxx_supported fns. */
+ arc_opcode_init_tables (arc_get_opcode_mach (mach, target_big_endian));
+
+ /* Only put the first entry of each equivalently named suffix in the
+ table. */
+ last = "";
+ for (i = 0; i < arc_suffixes_count; i++)
+ {
+ if (! arc_opval_supported (&arc_suffixes[i]))
+ continue;
+ if (strcmp (arc_suffixes[i].name, last) != 0)
+ hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
+ last = arc_suffixes[i].name;
+ }
+
+ /* Since registers don't have a prefix, we put them in the symbol table so
+ they can't be used as symbols. This also simplifies argument parsing as
+ we can let gas parse registers for us. The recorded register number is
+ the index in `arc_reg_names'. */
+ for (i = 0; i < arc_reg_names_count; i++)
+ {
+ if (! arc_opval_supported (&arc_reg_names[i]))
+ continue;
+ /* Use symbol_create here instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+ symbol_table_insert (symbol_create (arc_reg_names[i].name, reg_section,
+ i, &zero_address_frag));
+ }
+
+ /* Tell `s_cpu' it's too late. */
+ cpu_tables_init_p = 1;
+}
+
+/* Insert an operand value into an instruction.
+ If REG is non-NULL, it is a register number and ignore VAL. */
+
+static arc_insn
+arc_insert_operand (insn, operand, mods, reg, val, file, line)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ offsetT val;
+ char *file;
+ unsigned int line;
+{
+ if (operand->bits != 32)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & ARC_OPERAND_SIGNED) != 0)
+ {
+ if ((operand->flags & ARC_OPERAND_SIGNOPT) != 0)
+ max = (1 << operand->bits) - 1;
+ else
+ max = (1 << (operand->bits - 1)) - 1;
+ min = - (1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ if ((operand->flags & ARC_OPERAND_NEGATIVE) != 0)
+ test = - val;
+ else
+ test = val;
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ sprint_value (buf, test);
+ if (file == (char *) NULL)
+ as_warn (err, buf, min, max);
+ else
+ as_warn_where (file, line, err, buf, min, max);
+ }
+ }
+
+ if (operand->insert)
+ {
+ const char *errmsg;
+
+ errmsg = NULL;
+ insn = (*operand->insert) (insn, operand, mods, reg, (long) val, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_warn (errmsg);
+ }
+ else
+ insn |= (((long) val & ((1 << operand->bits) - 1))
+ << operand->shift);
+
+ return insn;
+}
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''. */
+
+struct arc_fixup
+{
+ /* index into `arc_operands' */
+ int opindex;
+ expressionS exp;
+};
+
+#define MAX_FIXUPS 5
+
+#define MAX_SUFFIXES 5
+
+/* This routine is called for each instruction to be assembled. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ const struct arc_opcode *opcode;
+ char *start;
+ arc_insn insn;
+ static int init_tables_p = 0;
+
+ /* Opcode table initialization is deferred until here because we have to
+ wait for a possible .cpu command. */
+ if (!init_tables_p)
+ {
+ init_opcode_tables (arc_mach_type);
+ init_tables_p = 1;
+ }
+
+ /* Skip leading white space. */
+ while (isspace (*str))
+ str++;
+
+ /* The instructions are stored in lists hashed by the first letter (though
+ we needn't care how they're hashed). Get the first in the list. */
+
+ opcode = arc_opcode_lookup_asm (str);
+
+ /* Keep looking until we find a match. */
+
+ start = str;
+ for ( ; opcode != NULL; opcode = ARC_OPCODE_NEXT_ASM (opcode))
+ {
+ int past_opcode_p, fc, num_suffixes;
+ char *syn;
+ struct arc_fixup fixups[MAX_FIXUPS];
+ /* Used as a sanity check. If we need a limm reloc, make sure we ask
+ for an extra 4 bytes from frag_more. */
+ int limm_reloc_p;
+ const struct arc_operand_value *insn_suffixes[MAX_SUFFIXES];
+
+ /* Is this opcode supported by the selected cpu? */
+ if (! arc_opcode_supported (opcode))
+ continue;
+
+ /* Scan the syntax string. If it doesn't match, try the next one. */
+
+ arc_opcode_init_insert ();
+ insn = opcode->value;
+ fc = 0;
+ past_opcode_p = 0;
+ num_suffixes = 0;
+ limm_reloc_p = 0;
+
+ /* We don't check for (*str != '\0') here because we want to parse
+ any trailing fake arguments in the syntax string. */
+ for (str = start, syn = opcode->syntax; *syn != '\0'; )
+ {
+ int mods;
+ const struct arc_operand *operand;
+
+ /* Non operand chars must match exactly. */
+ if (*syn != '%' || *++syn == '%')
+ {
+ /* Handle '+' specially as we want to allow "ld r0,[sp-4]". */
+ /* ??? The syntax has changed to [sp,-4]. */
+ if (0 && *syn == '+' && *str == '-')
+ {
+ /* Skip over syn's +, but leave str's - alone.
+ That makes the case identical to "ld r0,[sp+-4]". */
+ ++syn;
+ }
+ else if (*str == *syn)
+ {
+ if (*syn == ' ')
+ past_opcode_p = 1;
+ ++syn;
+ ++str;
+ }
+ else
+ break;
+ continue;
+ }
+
+ /* We have an operand. Pick out any modifiers. */
+ mods = 0;
+ while (ARC_MOD_P (arc_operands[arc_operand_map[*syn]].flags))
+ {
+ mods |= arc_operands[arc_operand_map[*syn]].flags & ARC_MOD_BITS;
+ ++syn;
+ }
+ operand = arc_operands + arc_operand_map[*syn];
+ if (operand->fmt == 0)
+ as_fatal (_("unknown syntax format character `%c'"), *syn);
+
+ if (operand->flags & ARC_OPERAND_FAKE)
+ {
+ const char *errmsg = NULL;
+ if (operand->insert)
+ {
+ insn = (*operand->insert) (insn, operand, mods, NULL, 0, &errmsg);
+ /* If we get an error, go on to try the next insn. */
+ if (errmsg)
+ break;
+ }
+ ++syn;
+ }
+ /* Are we finished with suffixes? */
+ else if (!past_opcode_p)
+ {
+ int found;
+ char c;
+ char *s,*t;
+ const struct arc_operand_value *suf,*suffix,*suffix_end;
+
+ if (!(operand->flags & ARC_OPERAND_SUFFIX))
+ abort ();
+
+ /* If we're at a space in the input string, we want to skip the
+ remaining suffixes. There may be some fake ones though, so
+ just go on to try the next one. */
+ if (*str == ' ')
+ {
+ ++syn;
+ continue;
+ }
+
+ s = str;
+ if (mods & ARC_MOD_DOT)
+ {
+ if (*s != '.')
+ break;
+ ++s;
+ }
+ else
+ {
+ /* This can happen in "b.nd foo" and we're currently looking
+ for "%q" (ie: a condition code suffix). */
+ if (*s == '.')
+ {
+ ++syn;
+ continue;
+ }
+ }
+
+ /* Pick the suffix out and look it up via the hash table. */
+ for (t = s; *t && isalpha (*t); ++t)
+ continue;
+ c = *t;
+ *t = '\0';
+ suf = hash_find (arc_suffix_hash, s);
+ *t = c;
+ if (!suf)
+ {
+ /* This can happen in "blle foo" and we're currently using
+ the template "b%q%.n %j". The "bl" insn occurs later in
+ the table so "lle" isn't an illegal suffix. */
+ break;
+ }
+
+ /* Is it the right type? Note that the same character is used
+ several times, so we have to examine all of them. This is
+ relatively efficient as equivalent entries are kept
+ together. If it's not the right type, don't increment `str'
+ so we try the next one in the series. */
+ found = 0;
+ suffix_end = arc_suffixes + arc_suffixes_count;
+ for (suffix = suf;
+ suffix < suffix_end && strcmp (suffix->name, suf->name) == 0;
+ ++suffix)
+ {
+ if (arc_operands[suffix->type].fmt == *syn)
+ {
+ /* Insert the suffix's value into the insn. */
+ if (operand->insert)
+ insn = (*operand->insert) (insn, operand,
+ mods, NULL, suffix->value,
+ NULL);
+ else
+ insn |= suffix->value << operand->shift;
+
+ str = t;
+ found = 1;
+ break;
+ }
+ }
+ ++syn;
+ if (!found)
+ ; /* Wrong type. Just go on to try next insn entry. */
+ else
+ {
+ if (num_suffixes == MAX_SUFFIXES)
+ as_bad (_("too many suffixes"));
+ else
+ insn_suffixes[num_suffixes++] = suffix;
+ }
+ }
+ else
+ /* This is either a register or an expression of some kind. */
+ {
+ char c;
+ char *hold;
+ const struct arc_operand_value *reg = NULL;
+ long value = 0;
+ expressionS exp;
+
+ if (operand->flags & ARC_OPERAND_SUFFIX)
+ abort ();
+
+ /* Is there anything left to parse?
+ We don't check for this at the top because we want to parse
+ any trailing fake arguments in the syntax string. */
+ if (*str == '\0')
+ break;
+#if 0
+ /* Is this a syntax character? Eg: is there a '[' present when
+ there shouldn't be? */
+ if (!isalnum (*str)
+ /* '.' as in ".LLC0" */
+ && *str != '.'
+ /* '_' as in "_print" */
+ && *str != '_'
+ /* '-' as in "[fp,-4]" */
+ && *str != '-'
+ /* '%' as in "%ia(_func)" */
+ && *str != '%')
+ break;
+#endif
+
+ /* Parse the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+ expression (&exp);
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ if (exp.X_op == O_illegal)
+ as_bad (_("illegal operand"));
+ else if (exp.X_op == O_absent)
+ as_bad (_("missing operand"));
+ else if (exp.X_op == O_constant)
+ {
+ value = exp.X_add_number;
+ }
+ else if (exp.X_op == O_register)
+ {
+ reg = arc_reg_names + exp.X_add_number;
+ }
+ else
+ {
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = exp;
+
+ /* If this is a register constant (IE: one whose
+ register value gets stored as 61-63) then this
+ must be a limm. We don't support shimm relocs. */
+ /* ??? This bit could use some cleaning up.
+ Referencing the format chars like this goes
+ against style. */
+#define IS_REG_OPERAND(o) ((o) == 'a' || (o) == 'b' || (o) == 'c')
+ if (IS_REG_OPERAND (*syn))
+ {
+ const char *junk;
+
+ fixups[fc].opindex = arc_operand_map['L'];
+ limm_reloc_p = 1;
+ /* Tell insert_reg we need a limm. This is
+ needed because the value at this point is
+ zero, a shimm. */
+ /* ??? We need a cleaner interface than this. */
+ (*arc_operands[arc_operand_map['Q']].insert)
+ (insn, operand, mods, reg, 0L, &junk);
+ }
+ else
+ fixups[fc].opindex = arc_operand_map[*syn];
+ ++fc;
+ value = 0;
+ }
+
+ /* Insert the register or expression into the instruction. */
+ if (operand->insert)
+ {
+ const char *errmsg = NULL;
+ insn = (*operand->insert) (insn, operand, mods,
+ reg, (long) value, &errmsg);
+#if 0
+ if (errmsg != (const char *) NULL)
+ as_warn (errmsg);
+#endif
+ /* FIXME: We want to try shimm insns for limm ones. But if
+ the constant won't fit, we must go on to try the next
+ possibility. Where do we issue warnings for constants
+ that are too big then? At present, we'll flag the insn
+ as unrecognizable! Maybe have the "bad instruction"
+ error message include our `errmsg'? */
+ if (errmsg != (const char *) NULL)
+ break;
+ }
+ else
+ insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
+
+ ++syn;
+ }
+ }
+
+ /* If we're at the end of the syntax string, we're done. */
+ /* FIXME: try to move this to a separate function. */
+ if (*syn == '\0')
+ {
+ int i;
+ char *f;
+ long limm, limm_p;
+
+ /* For the moment we assume a valid `str' can only contain blanks
+ now. IE: We needn't try again with a longer version of the
+ insn and it is assumed that longer versions of insns appear
+ before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
+
+ while (isspace (*str))
+ ++str;
+
+ if (*str != '\0')
+ as_bad (_("junk at end of line: `%s'"), str);
+
+ /* Is there a limm value? */
+ limm_p = arc_opcode_limm_p (&limm);
+
+ /* Perform various error and warning tests. */
+
+ {
+ static int in_delay_slot_p = 0;
+ static int prev_insn_needs_cc_nop_p = 0;
+ /* delay slot type seen */
+ int delay_slot_type = ARC_DELAY_NONE;
+ /* conditional execution flag seen */
+ int conditional = 0;
+ /* 1 if condition codes are being set */
+ int cc_set_p = 0;
+ /* 1 if conditional branch, including `b' "branch always" */
+ int cond_branch_p = opcode->flags & ARC_OPCODE_COND_BRANCH;
+ int need_cc_nop_p = 0;
+
+ for (i = 0; i < num_suffixes; ++i)
+ {
+ switch (arc_operands[insn_suffixes[i]->type].fmt)
+ {
+ case 'n' :
+ delay_slot_type = insn_suffixes[i]->value;
+ break;
+ case 'q' :
+ conditional = insn_suffixes[i]->value;
+ break;
+ case 'f' :
+ cc_set_p = 1;
+ break;
+ }
+ }
+
+ /* Putting an insn with a limm value in a delay slot is supposed to
+ be legal, but let's warn the user anyway. Ditto for 8 byte
+ jumps with delay slots. */
+ if (in_delay_slot_p && limm_p)
+ as_warn (_("8 byte instruction in delay slot"));
+ if (delay_slot_type != ARC_DELAY_NONE && limm_p)
+ as_warn (_("8 byte jump instruction with delay slot"));
+ in_delay_slot_p = (delay_slot_type != ARC_DELAY_NONE) && !limm_p;
+
+ /* Warn when a conditional branch immediately follows a set of
+ the condition codes. Note that this needn't be done if the
+ insn that sets the condition codes uses a limm. */
+ if (cond_branch_p && conditional != 0 /* 0 = "always" */
+ && prev_insn_needs_cc_nop_p)
+ as_warn (_("conditional branch follows set of flags"));
+ prev_insn_needs_cc_nop_p = cc_set_p && !limm_p;
+ }
+
+ /* Write out the instruction.
+ It is important to fetch enough space in one call to `frag_more'.
+ We use (f - frag_now->fr_literal) to compute where we are and we
+ don't want frag_now to change between calls. */
+ if (limm_p)
+ {
+ f = frag_more (8);
+ md_number_to_chars (f, insn, 4);
+ md_number_to_chars (f + 4, limm, 4);
+ }
+ else if (limm_reloc_p)
+ {
+ /* We need a limm reloc, but the tables think we don't. */
+ abort ();
+ }
+ else
+ {
+ f = frag_more (4);
+ md_number_to_chars (f, insn, 4);
+ }
+
+ /* Create any fixups. */
+ for (i = 0; i < fc; ++i)
+ {
+ int op_type, reloc_type;
+ expressionS exptmp;
+ const struct arc_operand *operand;
+
+ /* Create a fixup for this operand.
+ At this point we do not use a bfd_reloc_code_real_type for
+ operands residing in the insn, but instead just use the
+ operand index. This lets us easily handle fixups for any
+ operand type, although that is admittedly not a very exciting
+ feature. We pick a BFD reloc type in md_apply_fix.
+
+ Limm values (4 byte immediate "constants") must be treated
+ normally because they're not part of the actual insn word
+ and thus the insertion routines don't handle them. */
+
+ if (arc_operands[fixups[i].opindex].flags & ARC_OPERAND_LIMM)
+ {
+ op_type = fixups[i].opindex;
+ /* FIXME: can we add this data to the operand table? */
+ if (op_type == arc_operand_map['L'])
+ reloc_type = BFD_RELOC_32;
+ else if (op_type == arc_operand_map['J'])
+ reloc_type = BFD_RELOC_ARC_B26;
+ else
+ abort ();
+ reloc_type = get_arc_exp_reloc_type (1, reloc_type,
+ &fixups[i].exp,
+ &exptmp);
+ }
+ else
+ {
+ op_type = get_arc_exp_reloc_type (0, fixups[i].opindex,
+ &fixups[i].exp, &exptmp);
+ reloc_type = op_type + (int) BFD_RELOC_UNUSED;
+ }
+ operand = &arc_operands[op_type];
+ fix_new_exp (frag_now,
+ ((f - frag_now->fr_literal)
+ + (operand->flags & ARC_OPERAND_LIMM ? 4 : 0)), 4,
+ &exptmp,
+ (operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0,
+ (bfd_reloc_code_real_type) reloc_type);
+ }
+
+ /* All done. */
+ return;
+ }
+
+ /* Try the next entry. */
+ }
+
+ as_bad (_("bad instruction `%s'"), start);
+}
+
+/* ??? This was copied from tc-sparc.c, I think. Is it necessary? */
+
+static void
+arc_common (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+ char *p;
+ int temp, size;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("expected comma after symbol-name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++; /* skip ',' */
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ size = temp;
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (S_GET_VALUE (symbolP) != 0)
+ {
+ if (S_GET_VALUE (symbolP) != size)
+ {
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ }
+ }
+ assert (symbolP->sy_frag == &zero_address_frag);
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("expected comma after common length"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ {
+ temp = get_absolute_expression ();
+ if (temp < 0)
+ {
+ temp = 0;
+ as_warn (_("Common alignment negative; 0 assumed"));
+ }
+ if (symbolP->local)
+ {
+ segT old_sec;
+ int old_subsec;
+ char *p;
+ int align;
+
+ allocate_bss:
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+ align = temp;
+ record_alignment (bss_section, align);
+ subseg_set (bss_section, 0);
+ if (align)
+ frag_align (align, 0, 0);
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ symbolP->sy_frag = frag_now;
+ p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *p = 0;
+ S_SET_SEGMENT (symbolP, bss_section);
+ S_CLEAR_EXTERNAL (symbolP);
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+ {
+ allocate_common:
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_ALIGN (symbolP, temp);
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ }
+ }
+ else
+ {
+ input_line_pointer++;
+ /* ??? Some say data, some say bss. */
+ if (strncmp (input_line_pointer, ".bss\"", 5)
+ && strncmp (input_line_pointer, ".data\"", 6))
+ {
+ input_line_pointer--;
+ goto bad_common_segment;
+ }
+ while (*input_line_pointer++ != '"')
+ ;
+ goto allocate_common;
+ }
+ demand_empty_rest_of_line ();
+ return;
+
+ {
+ bad_common_segment:
+ p = input_line_pointer;
+ while (*p && *p != '\n')
+ p++;
+ c = *p;
+ *p = '\0';
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
+ *p = c;
+ input_line_pointer = p;
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+/* Select the cpu we're assembling for. */
+
+static void
+arc_cpu (ignore)
+ int ignore;
+{
+ int mach;
+ char c;
+ char *cpu;
+
+ /* If an instruction has already been seen, it's too late. */
+ if (cpu_tables_init_p)
+ {
+ as_bad (_(".cpu command must appear before any instructions"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ cpu = input_line_pointer;
+ c = get_symbol_end ();
+ mach = arc_get_mach (cpu);
+ *input_line_pointer = c;
+ if (mach == -1)
+ goto bad_cpu;
+
+ demand_empty_rest_of_line ();
+
+ /* The cpu may have been selected on the command line.
+ The choices must match. */
+ /* ??? This was a command line option early on. It's gone now, but
+ leave this in. */
+ if (mach_type_specified_p && mach != arc_mach_type)
+ as_bad (_(".cpu conflicts with previous value"));
+ else
+ {
+ arc_mach_type = mach;
+ mach_type_specified_p = 1;
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
+ as_warn (_("could not set architecture and machine"));
+ }
+ return;
+
+ bad_cpu:
+ as_bad (_("bad .cpu op"));
+ ignore_rest_of_line ();
+}
+
+#if 0
+/* The .rename pseudo-op. This is used by gcc to implement
+ -mmangle-cpu-libgcc. */
+
+static void
+arc_rename (ignore)
+ int ignore;
+{
+ char *name,*new;
+ char c;
+ symbolS *sym;
+ int len;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing rename string"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ if (*name == '\0')
+ {
+ *input_line_pointer = c;
+ as_bad (_("invalid symbol to rename to"));
+ ignore_rest_of_line ();
+ return;
+ }
+ new = (char *) xmalloc (strlen (name) + 1);
+ strcpy (new, name);
+ *input_line_pointer = c;
+ sym->sy_tc.real_name = new;
+
+ demand_empty_rest_of_line ();
+}
+#endif
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP.
+ An error message is returned, or NULL on OK. */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return NULL;
+}
+
+/* Write a value out to the object file, using the appropriate
+ endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+/* We don't have any form of relaxing. */
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg;
+{
+ abort ();
+}
+
+/* Convert a machine dependent frag. We never generate these. */
+
+void
+md_convert_frag (abfd, sec, fragp)
+ bfd *abfd;
+ asection *sec;
+ fragS *fragp;
+{
+ abort ();
+}
+
+/* Parse an operand that is machine-specific.
+
+ The ARC has a special %-op to adjust addresses so they're usable in
+ branches. The "st" is short for the STatus register.
+ ??? Later expand this to take a flags value too.
+
+ ??? We can't create new expression types so we map the %-op's onto the
+ existing syntax. This means that the user could use the chosen syntax
+ to achieve the same effect. Perhaps put a special cookie in X_add_number
+ to mark the expression as special. */
+
+void
+md_operand (expressionP)
+ expressionS *expressionP;
+{
+ char *p = input_line_pointer;
+
+ if (*p == '%' && strncmp (p, "%st(", 4) == 0)
+ {
+ input_line_pointer += 4;
+ expression (expressionP);
+ if (*input_line_pointer != ')')
+ {
+ as_bad (_("missing ')' in %-op"));
+ return;
+ }
+ ++input_line_pointer;
+ if (expressionP->X_op == O_symbol
+ && expressionP->X_add_number == 0
+ /* I think this test is unnecessary but just as a sanity check... */
+ && expressionP->X_op_symbol == NULL)
+ {
+ expressionS two;
+
+ expressionP->X_op = O_right_shift;
+ two.X_op = O_constant;
+ two.X_add_symbol = two.X_op_symbol = NULL;
+ two.X_add_number = 2;
+ expressionP->X_op_symbol = make_expr_symbol (&two);
+ }
+ /* allow %st(sym1-sym2) */
+ else if (expressionP->X_op == O_subtract
+ && expressionP->X_add_symbol != NULL
+ && expressionP->X_op_symbol != NULL
+ && expressionP->X_add_number == 0)
+ {
+ expressionS two;
+
+ expressionP->X_add_symbol = make_expr_symbol (expressionP);
+ expressionP->X_op = O_right_shift;
+ two.X_op = O_constant;
+ two.X_add_symbol = two.X_op_symbol = NULL;
+ two.X_add_number = 2;
+ expressionP->X_op_symbol = make_expr_symbol (&two);
+ }
+ else
+ {
+ as_bad (_("expression too complex for %%st"));
+ return;
+ }
+ }
+}
+
+/* We have no need to default values of symbols.
+ We could catch register names here, but that is handled by inserting
+ them all in the symbol table to begin with. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Functions concerning expressions. */
+
+/* Parse a .byte, .word, etc. expression.
+
+ Values for the status register are specified with %st(label).
+ `label' will be right shifted by 2. */
+
+void
+arc_parse_cons_expression (exp, nbytes)
+ expressionS *exp;
+ int nbytes;
+{
+ expr (0, exp);
+}
+
+/* Record a fixup for a cons expression. */
+
+void
+arc_cons_fix_new (frag, where, nbytes, exp)
+ fragS *frag;
+ int where;
+ int nbytes;
+ expressionS *exp;
+{
+ if (nbytes == 4)
+ {
+ int reloc_type;
+ expressionS exptmp;
+
+ /* This may be a special ARC reloc (eg: %st()). */
+ reloc_type = get_arc_exp_reloc_type (1, BFD_RELOC_32, exp, &exptmp);
+ fix_new_exp (frag, where, nbytes, &exptmp, 0, reloc_type);
+ }
+ else
+ {
+ fix_new_exp (frag, where, nbytes, exp, 0,
+ nbytes == 2 ? BFD_RELOC_16
+ : nbytes == 8 ? BFD_RELOC_64
+ : BFD_RELOC_32);
+ }
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && ! S_IS_DEFINED (fixP->fx_addsy))
+ {
+ /* The symbol is undefined. Let the linker figure it out. */
+ return 0;
+ }
+
+ /* Return the address of the delay slot. */
+ return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
+}
+
+/* Compute the reloc type of an expression.
+ The possibly modified expression is stored in EXPNEW.
+
+ This is used to convert the expressions generated by the %-op's into
+ the appropriate operand type. It is called for both data in instructions
+ (operands) and data outside instructions (variables, debugging info, etc.).
+
+ Currently supported %-ops:
+
+ %st(symbol): represented as "symbol >> 2"
+ "st" is short for STatus as in the status register (pc)
+
+ DEFAULT_TYPE is the type to use if no special processing is required.
+
+ DATA_P is non-zero for data or limm values, zero for insn operands.
+ Remember that the opcode "insertion fns" cannot be used on data, they're
+ only for inserting operands into insns. They also can't be used for limm
+ values as the insertion routines don't handle limm values. When called for
+ insns we return fudged reloc types (real_value - BFD_RELOC_UNUSED). When
+ called for data or limm values we use real reloc types. */
+
+static int
+get_arc_exp_reloc_type (data_p, default_type, exp, expnew)
+ int data_p;
+ int default_type;
+ expressionS *exp;
+ expressionS *expnew;
+{
+ /* If the expression is "symbol >> 2" we must change it to just "symbol",
+ as fix_new_exp can't handle it. Similarily for (symbol - symbol) >> 2.
+ That's ok though. What's really going on here is that we're using
+ ">> 2" as a special syntax for specifying BFD_RELOC_ARC_B26. */
+
+ if (exp->X_op == O_right_shift
+ && exp->X_op_symbol != NULL
+ && exp->X_op_symbol->sy_value.X_op == O_constant
+ && exp->X_op_symbol->sy_value.X_add_number == 2
+ && exp->X_add_number == 0)
+ {
+ if (exp->X_add_symbol != NULL
+ && (exp->X_add_symbol->sy_value.X_op == O_constant
+ || exp->X_add_symbol->sy_value.X_op == O_symbol))
+ {
+ *expnew = *exp;
+ expnew->X_op = O_symbol;
+ expnew->X_op_symbol = NULL;
+ return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
+ }
+ else if (exp->X_add_symbol != NULL
+ && exp->X_add_symbol->sy_value.X_op == O_subtract)
+ {
+ *expnew = exp->X_add_symbol->sy_value;
+ return data_p ? BFD_RELOC_ARC_B26 : arc_operand_map['J'];
+ }
+ }
+
+ *expnew = *exp;
+ return default_type;
+}
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the fixup. */
+
+int
+md_apply_fix3 (fixP, valueP, seg)
+ fixS *fixP;
+ valueT *valueP;
+ segT seg;
+{
+ /*char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;*/
+ valueT value;
+
+ /* FIXME FIXME FIXME: The value we are passed in *valueP includes
+ the symbol values. Since we are using BFD_ASSEMBLER, if we are
+ doing this relocation the code in write.c is going to call
+ bfd_perform_relocation, which is also going to use the symbol
+ value. That means that if the reloc is fully resolved we want to
+ use *valueP since bfd_perform_relocation is not being used.
+ However, if the reloc is not fully resolved we do not want to use
+ *valueP, and must use fx_offset instead. However, if the reloc
+ is PC relative, we do want to use *valueP since it includes the
+ result of md_pcrel_from. This is confusing. */
+
+ if (fixP->fx_addsy == (symbolS *) NULL)
+ {
+ value = *valueP;
+ fixP->fx_done = 1;
+ }
+ else if (fixP->fx_pcrel)
+ {
+ value = *valueP;
+ /* ELF relocations are against symbols.
+ If this symbol is in a different section then we need to leave it for
+ the linker to deal with. Unfortunately, md_pcrel_from can't tell,
+ so we have to undo it's effects here. */
+ if (S_IS_DEFINED (fixP->fx_addsy)
+ && S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ value += md_pcrel_from (fixP);
+ }
+ else
+ {
+ value = fixP->fx_offset;
+ if (fixP->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixP->fx_subsy);
+ else
+ {
+ /* We can't actually support subtracting a symbol. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+
+ if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex;
+ const struct arc_operand *operand;
+ char *where;
+ arc_insn insn;
+
+ opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
+
+ operand = &arc_operands[opindex];
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getl32 ((unsigned char *) where);
+ insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
+ fixP->fx_file, fixP->fx_line);
+ if (target_big_endian)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+
+ if (fixP->fx_done)
+ {
+ /* Nothing else to do here. */
+ return 1;
+ }
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into relocs.
+ !!! Note that we can't handle limm values here. Since we're using
+ implicit addends the addend must be inserted into the instruction,
+ however, the opcode insertion routines currently do nothing with
+ limm values. */
+ if (operand->fmt == 'B')
+ {
+ assert ((operand->flags & ARC_OPERAND_RELATIVE_BRANCH) != 0
+ && operand->bits == 20
+ && operand->shift == 7);
+ fixP->fx_r_type = BFD_RELOC_ARC_B22_PCREL;
+ }
+ else if (0 && operand->fmt == 'J')
+ {
+ assert ((operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH) != 0
+ && operand->bits == 24
+ && operand->shift == 32);
+ fixP->fx_r_type = BFD_RELOC_ARC_B26;
+ }
+ else if (0 && operand->fmt == 'L')
+ {
+ assert ((operand->flags & ARC_OPERAND_LIMM) != 0
+ && operand->bits == 32
+ && operand->shift == 32);
+ fixP->fx_r_type = BFD_RELOC_32;
+ }
+ else
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("unresolved expression that must be resolved"));
+ fixP->fx_done = 1;
+ return 1;
+ }
+ }
+ else
+ {
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 1);
+ break;
+ case BFD_RELOC_16:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 2);
+ break;
+ case BFD_RELOC_32:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 4);
+ break;
+#if 0
+ case BFD_RELOC_64:
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 8);
+ break;
+#endif
+ case BFD_RELOC_ARC_B26:
+ /* If !fixP->fx_done then `value' is an implicit addend.
+ We must shift it right by 2 in this case as well because the
+ linker performs the relocation and then adds this in (as opposed
+ to adding this in and then shifting right by 2). */
+ value >>= 2;
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 4);
+ break;
+ default:
+ abort ();
+ }
+ }
+
+ fixP->fx_addnumber = value;
+
+ return 1;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent *
+tc_gen_reloc (section, fixP)
+ asection *section;
+ fixS *fixP;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
+ reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("internal error: can't export reloc type %d (`%s')"),
+ fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
+ return NULL;
+ }
+
+ assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+
+ reloc->addend = fixP->fx_addnumber;
+
+ return reloc;
+}
+
+/* Frobbers. */
+
+#if 0
+/* Set the real name if the .rename pseudo-op was used.
+ Return 1 if the symbol should not be included in the symbol table. */
+
+int
+arc_frob_symbol (sym)
+ symbolS *sym;
+{
+ if (sym->sy_tc.real_name != (char *) NULL)
+ S_SET_NAME (sym, sym->sy_tc.real_name);
+
+ return 0;
+}
+#endif
diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h
new file mode 100644
index 00000000000..6a95ff4b614
--- /dev/null
+++ b/gas/config/tc-arc.h
@@ -0,0 +1,71 @@
+/* tc-arc.h - Macros and type defines for the ARC.
+ Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_ARC 1
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define LOCAL_LABELS_FB 1
+
+#define TARGET_ARCH bfd_arch_arc
+
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+
+/* The endianness of the target format may change based on command
+ line arguments. */
+extern const char *arc_target_format;
+#define DEFAULT_TARGET_FORMAT "elf32-littlearc"
+#define TARGET_FORMAT arc_target_format
+#define DEFAULT_BYTE_ORDER LITTLE_ENDIAN
+
+#define WORKING_DOT_WORD
+
+#define LISTING_HEADER "ARC GAS "
+
+#define TC_HANDLES_FX_DONE
+
+#define MD_APPLY_FIX3
+
+/* The ARC needs to parse reloc specifiers in .word. */
+
+extern void arc_parse_cons_expression ();
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+arc_parse_cons_expression (EXP, NBYTES)
+
+extern void arc_cons_fix_new ();
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
+arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
+
+#if 0
+/* Extra stuff that we need to keep track of for each symbol. */
+struct arc_tc_sy
+{
+ /* The real name, if the symbol was renamed. */
+ char *real_name;
+};
+
+#define TC_SYMFIELD_TYPE struct arc_tc_sy
+
+/* Finish up the symbol. */
+extern int arc_frob_symbol PARAMS ((struct symbol *));
+#define tc_frob_symbol(sym, punt) punt = arc_frob_symbol (sym)
+#endif
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
new file mode 100644
index 00000000000..d898bf0ecd0
--- /dev/null
+++ b/gas/config/tc-arm.c
@@ -0,0 +1,6857 @@
+/* tc-arm.c -- Assemble for the ARM
+ Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+ Modified by David Taylor (dtaylor@armltd.co.uk)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <ctype.h>
+#include <string.h>
+#define NO_RELOC 0
+#include "as.h"
+
+/* need TARGET_CPU */
+#include "config.h"
+#include "subsegs.h"
+#include "obstack.h"
+#include "symbols.h"
+#include "listing.h"
+
+#ifdef OBJ_ELF
+#include "elf/arm.h"
+#endif
+
+/* Types of processor to assemble for. */
+#define ARM_1 0x00000001
+#define ARM_2 0x00000002
+#define ARM_3 0x00000004
+#define ARM_250 ARM_3
+#define ARM_6 0x00000008
+#define ARM_7 ARM_6 /* same core instruction set */
+#define ARM_8 ARM_6 /* same core instruction set */
+#define ARM_9 ARM_6 /* same core instruction set */
+#define ARM_CPU_MASK 0x0000000f
+
+/* The following bitmasks control CPU extensions (ARM7 onwards): */
+#define ARM_LONGMUL 0x00000010 /* allow long multiplies */
+#define ARM_HALFWORD 0x00000020 /* allow half word loads */
+#define ARM_THUMB 0x00000040 /* allow BX instruction */
+
+#define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
+
+/* Some useful combinations: */
+#define ARM_ANY 0x00ffffff
+#define ARM_2UP 0x00fffffe
+#define ARM_ALL ARM_2UP /* Not arm1 only */
+#define ARM_3UP 0x00fffffc
+#define ARM_6UP 0x00fffff8 /* Includes ARM7 */
+
+#define FPU_CORE 0x80000000
+#define FPU_FPA10 0x40000000
+#define FPU_FPA11 0x40000000
+#define FPU_NONE 0
+
+/* Some useful combinations */
+#define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
+#define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
+
+
+#ifndef CPU_DEFAULT
+#if defined __thumb__
+#define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
+#else
+#define CPU_DEFAULT ARM_ALL
+#endif
+#endif
+
+#ifndef FPU_DEFAULT
+#define FPU_DEFAULT FPU_ALL
+#endif
+
+#define streq(a,b) (strcmp (a, b) == 0)
+
+static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
+static int target_oabi = 0;
+
+#if defined OBJ_COFF || defined OBJ_ELF
+/* Flags stored in private area of BFD structure */
+static boolean uses_apcs_26 = false;
+static boolean support_interwork = false;
+static boolean uses_apcs_float = false;
+static boolean pic_code = false;
+#endif
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+CONST char comment_chars[] = "@";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments like this one will always work. */
+CONST char line_comment_chars[] = "#";
+
+#ifdef TE_LINUX
+CONST char line_separator_chars[] = ";";
+#else
+CONST char line_separator_chars[] = "";
+#endif
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+CONST char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+
+CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+
+/* Prefix characters that indicate the start of an immediate
+ value. */
+#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
+
+#ifdef OBJ_ELF
+symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
+#endif
+
+CONST int md_reloc_size = 8; /* Size of relocation record */
+
+static int thumb_mode = 0; /* non-zero if assembling thumb instructions */
+
+typedef struct arm_fix
+{
+ int thumb_mode;
+} arm_fix_data;
+
+struct arm_it
+{
+ CONST char * error;
+ unsigned long instruction;
+ int suffix;
+ int size;
+ struct
+ {
+ bfd_reloc_code_real_type type;
+ expressionS exp;
+ int pc_rel;
+ } reloc;
+};
+
+struct arm_it inst;
+
+struct asm_shift
+{
+ CONST char * template;
+ unsigned long value;
+};
+
+static CONST struct asm_shift shift[] =
+{
+ {"asl", 0},
+ {"lsl", 0},
+ {"lsr", 0x00000020},
+ {"asr", 0x00000040},
+ {"ror", 0x00000060},
+ {"rrx", 0x00000060},
+ {"ASL", 0},
+ {"LSL", 0},
+ {"LSR", 0x00000020},
+ {"ASR", 0x00000040},
+ {"ROR", 0x00000060},
+ {"RRX", 0x00000060}
+};
+
+#define NO_SHIFT_RESTRICT 1
+#define SHIFT_RESTRICT 0
+
+#define NUM_FLOAT_VALS 8
+
+CONST char * fp_const[] =
+{
+ "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
+};
+
+/* Number of littlenums required to hold an extended precision number */
+#define MAX_LITTLENUMS 6
+
+LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
+
+#define FAIL (-1)
+#define SUCCESS (0)
+
+#define SUFF_S 1
+#define SUFF_D 2
+#define SUFF_E 3
+#define SUFF_P 4
+
+#define CP_T_X 0x00008000
+#define CP_T_Y 0x00400000
+#define CP_T_Pre 0x01000000
+#define CP_T_UD 0x00800000
+#define CP_T_WB 0x00200000
+
+#define CONDS_BIT (0x00100000)
+#define LOAD_BIT (0x00100000)
+#define TRANS_BIT (0x00200000)
+
+struct asm_cond
+{
+ CONST char * template;
+ unsigned long value;
+};
+
+/* This is to save a hash look-up in the common case */
+#define COND_ALWAYS 0xe0000000
+
+static CONST struct asm_cond conds[] =
+{
+ {"eq", 0x00000000},
+ {"ne", 0x10000000},
+ {"cs", 0x20000000}, {"hs", 0x20000000},
+ {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
+ {"mi", 0x40000000},
+ {"pl", 0x50000000},
+ {"vs", 0x60000000},
+ {"vc", 0x70000000},
+ {"hi", 0x80000000},
+ {"ls", 0x90000000},
+ {"ge", 0xa0000000},
+ {"lt", 0xb0000000},
+ {"gt", 0xc0000000},
+ {"le", 0xd0000000},
+ {"al", 0xe0000000},
+ {"nv", 0xf0000000}
+};
+
+/* Warning: If the top bit of the set_bits is set, then the standard
+ instruction bitmask is ignored, and the new bitmask is taken from
+ the set_bits: */
+struct asm_flg
+{
+ CONST char * template; /* Basic flag string */
+ unsigned long set_bits; /* Bits to set */
+};
+
+static CONST struct asm_flg s_flag[] =
+{
+ {"s", CONDS_BIT},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg ldr_flags[] =
+{
+ {"b", 0x00400000},
+ {"t", TRANS_BIT},
+ {"bt", 0x00400000 | TRANS_BIT},
+ {"h", 0x801000b0},
+ {"sh", 0x801000f0},
+ {"sb", 0x801000d0},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg str_flags[] =
+{
+ {"b", 0x00400000},
+ {"t", TRANS_BIT},
+ {"bt", 0x00400000 | TRANS_BIT},
+ {"h", 0x800000b0},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg byte_flag[] =
+{
+ {"b", 0x00400000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg cmp_flags[] =
+{
+ {"s", CONDS_BIT},
+ {"p", 0x0010f000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg ldm_flags[] =
+{
+ {"ed", 0x01800000},
+ {"fd", 0x00800000},
+ {"ea", 0x01000000},
+ {"fa", 0x08000000},
+ {"ib", 0x01800000},
+ {"ia", 0x00800000},
+ {"db", 0x01000000},
+ {"da", 0x08000000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg stm_flags[] =
+{
+ {"ed", 0x08000000},
+ {"fd", 0x01000000},
+ {"ea", 0x00800000},
+ {"fa", 0x01800000},
+ {"ib", 0x01800000},
+ {"ia", 0x00800000},
+ {"db", 0x01000000},
+ {"da", 0x08000000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg lfm_flags[] =
+{
+ {"fd", 0x00800000},
+ {"ea", 0x01000000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg sfm_flags[] =
+{
+ {"fd", 0x01000000},
+ {"ea", 0x00800000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg round_flags[] =
+{
+ {"p", 0x00000020},
+ {"m", 0x00000040},
+ {"z", 0x00000060},
+ {NULL, 0}
+};
+
+/* The implementation of the FIX instruction is broken on some assemblers,
+ in that it accepts a precision specifier as well as a rounding specifier,
+ despite the fact that this is meaningless. To be more compatible, we
+ accept it as well, though of course it does not set any bits. */
+static CONST struct asm_flg fix_flags[] =
+{
+ {"p", 0x00000020},
+ {"m", 0x00000040},
+ {"z", 0x00000060},
+ {"sp", 0x00000020},
+ {"sm", 0x00000040},
+ {"sz", 0x00000060},
+ {"dp", 0x00000020},
+ {"dm", 0x00000040},
+ {"dz", 0x00000060},
+ {"ep", 0x00000020},
+ {"em", 0x00000040},
+ {"ez", 0x00000060},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg except_flag[] =
+{
+ {"e", 0x00400000},
+ {NULL, 0}
+};
+
+static CONST struct asm_flg cplong_flag[] =
+{
+ {"l", 0x00400000},
+ {NULL, 0}
+};
+
+struct asm_psr
+{
+ CONST char * template;
+ unsigned long number;
+};
+
+#define PSR_FIELD_MASK 0x000f0000
+
+#define PSR_FLAGS 0x00080000
+#define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
+#define PSR_ALL 0x00090000
+
+#define CPSR_ALL 0
+#define SPSR_ALL 1
+#define CPSR_FLG 2
+#define SPSR_FLG 3
+#define CPSR_CTL 4
+#define SPSR_CTL 5
+
+static CONST struct asm_psr psrs[] =
+{
+ /* Valid <psr>'s */
+ {"cpsr", CPSR_ALL},
+ {"cpsr_all", CPSR_ALL},
+ {"spsr", SPSR_ALL},
+ {"spsr_all", SPSR_ALL},
+
+ /* Valid <psrf>'s */
+ {"cpsr_flg", CPSR_FLG},
+ {"spsr_flg", SPSR_FLG},
+
+ /* Valid <psrc>'s */
+ {"cpsr_c", CPSR_CTL},
+ {"cpsr_ctl", CPSR_CTL},
+ {"spsr_c", SPSR_CTL},
+ {"spsr_ctl", SPSR_CTL}
+};
+
+/* Functions called by parser */
+/* ARM instructions */
+static void do_arit PARAMS ((char *operands, unsigned long flags));
+static void do_cmp PARAMS ((char *operands, unsigned long flags));
+static void do_mov PARAMS ((char *operands, unsigned long flags));
+static void do_ldst PARAMS ((char *operands, unsigned long flags));
+static void do_ldmstm PARAMS ((char *operands, unsigned long flags));
+static void do_branch PARAMS ((char *operands, unsigned long flags));
+static void do_swi PARAMS ((char *operands, unsigned long flags));
+/* Pseudo Op codes */
+static void do_adr PARAMS ((char *operands, unsigned long flags));
+static void do_nop PARAMS ((char *operands, unsigned long flags));
+/* ARM 2 */
+static void do_mul PARAMS ((char *operands, unsigned long flags));
+static void do_mla PARAMS ((char *operands, unsigned long flags));
+/* ARM 3 */
+static void do_swap PARAMS ((char *operands, unsigned long flags));
+/* ARM 6 */
+static void do_msr PARAMS ((char *operands, unsigned long flags));
+static void do_mrs PARAMS ((char *operands, unsigned long flags));
+/* ARM 7M */
+static void do_mull PARAMS ((char *operands, unsigned long flags));
+/* ARM THUMB */
+static void do_bx PARAMS ((char *operands, unsigned long flags));
+
+/* Coprocessor Instructions */
+static void do_cdp PARAMS ((char *operands, unsigned long flags));
+static void do_lstc PARAMS ((char *operands, unsigned long flags));
+static void do_co_reg PARAMS ((char *operands, unsigned long flags));
+static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags));
+static void do_fp_ldst PARAMS ((char *operands, unsigned long flags));
+static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags));
+static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags));
+static void do_fp_monadic PARAMS ((char *operands, unsigned long flags));
+static void do_fp_cmp PARAMS ((char *operands, unsigned long flags));
+static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags));
+static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags));
+
+static void fix_new_arm PARAMS ((fragS *frag, int where,
+ short int size, expressionS *exp,
+ int pc_rel, int reloc));
+static int arm_reg_parse PARAMS ((char **ccp));
+static int arm_psr_parse PARAMS ((char **ccp));
+static void symbol_locate PARAMS ((symbolS *, CONST char *, segT,
+ valueT, fragS *));
+static int add_to_lit_pool PARAMS ((void));
+static unsigned validate_immediate PARAMS ((unsigned));
+static int validate_offset_imm PARAMS ((int, int));
+static void opcode_select PARAMS ((int));
+static void end_of_line PARAMS ((char *));
+static int reg_required_here PARAMS ((char **, int));
+static int psr_required_here PARAMS ((char **, int, int));
+static int co_proc_number PARAMS ((char **));
+static int cp_opc_expr PARAMS ((char **, int, int));
+static int cp_reg_required_here PARAMS ((char **, int));
+static int fp_reg_required_here PARAMS ((char **, int));
+static int cp_address_offset PARAMS ((char **));
+static int cp_address_required_here PARAMS ((char **));
+static int my_get_float_expression PARAMS ((char **));
+static int skip_past_comma PARAMS ((char **));
+static int walk_no_bignums PARAMS ((symbolS *));
+static int negate_data_op PARAMS ((unsigned long *,
+ unsigned long));
+static int data_op2 PARAMS ((char **));
+static int fp_op2 PARAMS ((char **));
+static long reg_list PARAMS ((char **));
+static void thumb_load_store PARAMS ((char *, int, int));
+static int decode_shift PARAMS ((char **, int));
+static int ldst_extend PARAMS ((char **, int));
+static void thumb_add_sub PARAMS ((char *, int));
+static void insert_reg PARAMS ((int));
+static void thumb_shift PARAMS ((char *, int));
+static void thumb_mov_compare PARAMS ((char *, int));
+static void set_constant_flonums PARAMS ((void));
+static valueT md_chars_to_number PARAMS ((char *, int));
+static void insert_reg_alias PARAMS ((char *, int));
+static void output_inst PARAMS ((char *));
+#ifdef OBJ_ELF
+static bfd_reloc_code_real_type arm_parse_reloc(void);
+#endif
+
+/* ARM instructions take 4bytes in the object file, Thumb instructions
+ take 2: */
+#define INSN_SIZE 4
+
+/* LONGEST_INST is the longest basic instruction name without conditions or
+ * flags.
+ * ARM7M has 4 of length 5
+ */
+
+#define LONGEST_INST 5
+
+struct asm_opcode
+{
+ CONST char * template; /* Basic string to match */
+ unsigned long value; /* Basic instruction code */
+ CONST char * comp_suffix; /* Compulsory suffix that must follow conds */
+ CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */
+ unsigned long variants; /* Which CPU variants this exists for */
+ /* Function to call to parse args */
+ void (* parms) PARAMS ((char *, unsigned long));
+};
+
+static CONST struct asm_opcode insns[] =
+{
+/* ARM Instructions */
+ {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
+ {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
+ {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
+ {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
+ {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
+ {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
+ {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
+ {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
+ {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
+ {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
+ {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
+ {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
+ {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
+ {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
+ {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
+ {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
+ {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
+ {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
+ {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
+ {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
+ {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
+ {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
+ {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
+
+/* Pseudo ops */
+ {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
+ {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
+
+/* ARM 2 multiplies */
+ {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
+ {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
+
+/* ARM 3 - swp instructions */
+ {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
+
+/* ARM 6 Coprocessor instructions */
+ {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
+ {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
+/* ScottB: our code uses 0x0128f000 for msr.
+ NickC: but this is wrong because the bits 16 and 19 are handled
+ by the PSR_xxx defines above. */
+
+/* ARM 7M long multiplies - need signed/unsigned flags! */
+ {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
+ {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
+ {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
+ {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
+
+/* ARM THUMB interworking */
+ {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
+
+/* Floating point instructions */
+ {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
+ {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
+ {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
+ {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
+ {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
+ {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
+ {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
+ {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
+ {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
+ {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
+ {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
+ {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
+/* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
+ be an optional suffix, but part of the instruction. To be compatible,
+ we accept either. */
+ {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
+ {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
+ {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
+ {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
+
+/* Generic copressor instructions */
+ {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
+ {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
+ {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
+ {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
+ {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
+};
+
+/* defines for various bits that we will want to toggle */
+
+#define INST_IMMEDIATE 0x02000000
+#define OFFSET_REG 0x02000000
+#define HWOFFSET_IMM 0x00400000
+#define SHIFT_BY_REG 0x00000010
+#define PRE_INDEX 0x01000000
+#define INDEX_UP 0x00800000
+#define WRITE_BACK 0x00200000
+#define MULTI_SET_PSR 0x00400000
+
+#define LITERAL_MASK 0xf000f000
+#define COND_MASK 0xf0000000
+#define OPCODE_MASK 0xfe1fffff
+#define DATA_OP_SHIFT 21
+
+/* Codes to distinguish the arithmetic instructions */
+
+#define OPCODE_AND 0
+#define OPCODE_EOR 1
+#define OPCODE_SUB 2
+#define OPCODE_RSB 3
+#define OPCODE_ADD 4
+#define OPCODE_ADC 5
+#define OPCODE_SBC 6
+#define OPCODE_RSC 7
+#define OPCODE_TST 8
+#define OPCODE_TEQ 9
+#define OPCODE_CMP 10
+#define OPCODE_CMN 11
+#define OPCODE_ORR 12
+#define OPCODE_MOV 13
+#define OPCODE_BIC 14
+#define OPCODE_MVN 15
+
+static void do_t_nop PARAMS ((char *operands));
+static void do_t_arit PARAMS ((char *operands));
+static void do_t_add PARAMS ((char *operands));
+static void do_t_asr PARAMS ((char *operands));
+static void do_t_branch9 PARAMS ((char *operands));
+static void do_t_branch12 PARAMS ((char *operands));
+static void do_t_branch23 PARAMS ((char *operands));
+static void do_t_bx PARAMS ((char *operands));
+static void do_t_compare PARAMS ((char *operands));
+static void do_t_ldmstm PARAMS ((char *operands));
+static void do_t_ldr PARAMS ((char *operands));
+static void do_t_ldrb PARAMS ((char *operands));
+static void do_t_ldrh PARAMS ((char *operands));
+static void do_t_lds PARAMS ((char *operands));
+static void do_t_lsl PARAMS ((char *operands));
+static void do_t_lsr PARAMS ((char *operands));
+static void do_t_mov PARAMS ((char *operands));
+static void do_t_push_pop PARAMS ((char *operands));
+static void do_t_str PARAMS ((char *operands));
+static void do_t_strb PARAMS ((char *operands));
+static void do_t_strh PARAMS ((char *operands));
+static void do_t_sub PARAMS ((char *operands));
+static void do_t_swi PARAMS ((char *operands));
+static void do_t_adr PARAMS ((char *operands));
+
+#define T_OPCODE_MUL 0x4340
+#define T_OPCODE_TST 0x4200
+#define T_OPCODE_CMN 0x42c0
+#define T_OPCODE_NEG 0x4240
+#define T_OPCODE_MVN 0x43c0
+
+#define T_OPCODE_ADD_R3 0x1800
+#define T_OPCODE_SUB_R3 0x1a00
+#define T_OPCODE_ADD_HI 0x4400
+#define T_OPCODE_ADD_ST 0xb000
+#define T_OPCODE_SUB_ST 0xb080
+#define T_OPCODE_ADD_SP 0xa800
+#define T_OPCODE_ADD_PC 0xa000
+#define T_OPCODE_ADD_I8 0x3000
+#define T_OPCODE_SUB_I8 0x3800
+#define T_OPCODE_ADD_I3 0x1c00
+#define T_OPCODE_SUB_I3 0x1e00
+
+#define T_OPCODE_ASR_R 0x4100
+#define T_OPCODE_LSL_R 0x4080
+#define T_OPCODE_LSR_R 0x40c0
+#define T_OPCODE_ASR_I 0x1000
+#define T_OPCODE_LSL_I 0x0000
+#define T_OPCODE_LSR_I 0x0800
+
+#define T_OPCODE_MOV_I8 0x2000
+#define T_OPCODE_CMP_I8 0x2800
+#define T_OPCODE_CMP_LR 0x4280
+#define T_OPCODE_MOV_HR 0x4600
+#define T_OPCODE_CMP_HR 0x4500
+
+#define T_OPCODE_LDR_PC 0x4800
+#define T_OPCODE_LDR_SP 0x9800
+#define T_OPCODE_STR_SP 0x9000
+#define T_OPCODE_LDR_IW 0x6800
+#define T_OPCODE_STR_IW 0x6000
+#define T_OPCODE_LDR_IH 0x8800
+#define T_OPCODE_STR_IH 0x8000
+#define T_OPCODE_LDR_IB 0x7800
+#define T_OPCODE_STR_IB 0x7000
+#define T_OPCODE_LDR_RW 0x5800
+#define T_OPCODE_STR_RW 0x5000
+#define T_OPCODE_LDR_RH 0x5a00
+#define T_OPCODE_STR_RH 0x5200
+#define T_OPCODE_LDR_RB 0x5c00
+#define T_OPCODE_STR_RB 0x5400
+
+#define T_OPCODE_PUSH 0xb400
+#define T_OPCODE_POP 0xbc00
+
+#define T_OPCODE_BRANCH 0xe7fe
+
+static int thumb_reg PARAMS ((char ** str, int hi_lo));
+
+#define THUMB_SIZE 2 /* Size of thumb instruction */
+#define THUMB_REG_LO 0x1
+#define THUMB_REG_HI 0x2
+#define THUMB_REG_ANY 0x3
+
+#define THUMB_H1 0x0080
+#define THUMB_H2 0x0040
+
+#define THUMB_ASR 0
+#define THUMB_LSL 1
+#define THUMB_LSR 2
+
+#define THUMB_MOVE 0
+#define THUMB_COMPARE 1
+
+#define THUMB_LOAD 0
+#define THUMB_STORE 1
+
+#define THUMB_PP_PC_LR 0x0100
+
+/* These three are used for immediate shifts, do not alter */
+#define THUMB_WORD 2
+#define THUMB_HALFWORD 1
+#define THUMB_BYTE 0
+
+struct thumb_opcode
+{
+ CONST char * template; /* Basic string to match */
+ unsigned long value; /* Basic instruction code */
+ int size;
+ void (* parms) PARAMS ((char *)); /* Function to call to parse args */
+};
+
+static CONST struct thumb_opcode tinsns[] =
+{
+ {"adc", 0x4140, 2, do_t_arit},
+ {"add", 0x0000, 2, do_t_add},
+ {"and", 0x4000, 2, do_t_arit},
+ {"asr", 0x0000, 2, do_t_asr},
+ {"b", T_OPCODE_BRANCH, 2, do_t_branch12},
+ {"beq", 0xd0fe, 2, do_t_branch9},
+ {"bne", 0xd1fe, 2, do_t_branch9},
+ {"bcs", 0xd2fe, 2, do_t_branch9},
+ {"bhs", 0xd2fe, 2, do_t_branch9},
+ {"bcc", 0xd3fe, 2, do_t_branch9},
+ {"bul", 0xd3fe, 2, do_t_branch9},
+ {"blo", 0xd3fe, 2, do_t_branch9},
+ {"bmi", 0xd4fe, 2, do_t_branch9},
+ {"bpl", 0xd5fe, 2, do_t_branch9},
+ {"bvs", 0xd6fe, 2, do_t_branch9},
+ {"bvc", 0xd7fe, 2, do_t_branch9},
+ {"bhi", 0xd8fe, 2, do_t_branch9},
+ {"bls", 0xd9fe, 2, do_t_branch9},
+ {"bge", 0xdafe, 2, do_t_branch9},
+ {"blt", 0xdbfe, 2, do_t_branch9},
+ {"bgt", 0xdcfe, 2, do_t_branch9},
+ {"ble", 0xddfe, 2, do_t_branch9},
+ {"bic", 0x4380, 2, do_t_arit},
+ {"bl", 0xf7fffffe, 4, do_t_branch23},
+ {"bx", 0x4700, 2, do_t_bx},
+ {"cmn", T_OPCODE_CMN, 2, do_t_arit},
+ {"cmp", 0x0000, 2, do_t_compare},
+ {"eor", 0x4040, 2, do_t_arit},
+ {"ldmia", 0xc800, 2, do_t_ldmstm},
+ {"ldr", 0x0000, 2, do_t_ldr},
+ {"ldrb", 0x0000, 2, do_t_ldrb},
+ {"ldrh", 0x0000, 2, do_t_ldrh},
+ {"ldrsb", 0x5600, 2, do_t_lds},
+ {"ldrsh", 0x5e00, 2, do_t_lds},
+ {"ldsb", 0x5600, 2, do_t_lds},
+ {"ldsh", 0x5e00, 2, do_t_lds},
+ {"lsl", 0x0000, 2, do_t_lsl},
+ {"lsr", 0x0000, 2, do_t_lsr},
+ {"mov", 0x0000, 2, do_t_mov},
+ {"mul", T_OPCODE_MUL, 2, do_t_arit},
+ {"mvn", T_OPCODE_MVN, 2, do_t_arit},
+ {"neg", T_OPCODE_NEG, 2, do_t_arit},
+ {"orr", 0x4300, 2, do_t_arit},
+ {"pop", 0xbc00, 2, do_t_push_pop},
+ {"push", 0xb400, 2, do_t_push_pop},
+ {"ror", 0x41c0, 2, do_t_arit},
+ {"sbc", 0x4180, 2, do_t_arit},
+ {"stmia", 0xc000, 2, do_t_ldmstm},
+ {"str", 0x0000, 2, do_t_str},
+ {"strb", 0x0000, 2, do_t_strb},
+ {"strh", 0x0000, 2, do_t_strh},
+ {"swi", 0xdf00, 2, do_t_swi},
+ {"sub", 0x0000, 2, do_t_sub},
+ {"tst", T_OPCODE_TST, 2, do_t_arit},
+ /* Pseudo ops: */
+ {"adr", 0x0000, 2, do_t_adr},
+ {"nop", 0x46C0, 2, do_t_nop}, /* mov r8,r8 */
+};
+
+struct reg_entry
+{
+ CONST char * name;
+ int number;
+};
+
+#define int_register(reg) ((reg) >= 0 && (reg) <= 15)
+#define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
+#define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
+
+#define REG_PC 15
+#define REG_LR 14
+#define REG_SP 13
+
+/* These are the standard names; Users can add aliases with .req */
+static CONST struct reg_entry reg_table[] =
+{
+ /* Processor Register Numbers */
+ {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
+ {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
+ {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
+ {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
+ /* APCS conventions */
+ {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
+ {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
+ {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
+ {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
+ /* FP Registers */
+ {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
+ {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
+ {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
+ {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
+ {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
+ {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
+ {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
+ {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
+ {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
+ {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
+ {NULL, 0}
+};
+
+#define bad_args _("Bad arguments to instruction");
+#define bad_pc _("r15 not allowed here");
+
+static struct hash_control * arm_ops_hsh = NULL;
+static struct hash_control * arm_tops_hsh = NULL;
+static struct hash_control * arm_cond_hsh = NULL;
+static struct hash_control * arm_shift_hsh = NULL;
+static struct hash_control * arm_reg_hsh = NULL;
+static struct hash_control * arm_psr_hsh = NULL;
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+static void s_req PARAMS ((int));
+static void s_align PARAMS ((int));
+static void s_bss PARAMS ((int));
+static void s_even PARAMS ((int));
+static void s_ltorg PARAMS ((int));
+static void s_arm PARAMS ((int));
+static void s_thumb PARAMS ((int));
+static void s_code PARAMS ((int));
+static void s_force_thumb PARAMS ((int));
+static void s_thumb_func PARAMS ((int));
+#ifdef OBJ_ELF
+static void s_arm_elf_cons PARAMS ((int));
+#endif
+
+static int my_get_expression PARAMS ((expressionS *, char **));
+
+CONST pseudo_typeS md_pseudo_table[] =
+{
+ {"req", s_req, 0}, /* Never called becasue '.req' does not start line */
+ {"bss", s_bss, 0},
+ {"align", s_align, 0},
+ {"arm", s_arm, 0},
+ {"thumb", s_thumb, 0},
+ {"code", s_code, 0},
+ {"force_thumb", s_force_thumb, 0},
+ {"thumb_func", s_thumb_func, 0},
+ {"even", s_even, 0},
+ {"ltorg", s_ltorg, 0},
+ {"pool", s_ltorg, 0},
+#ifdef OBJ_ELF
+ {"word", s_arm_elf_cons, 4},
+ {"long", s_arm_elf_cons, 4},
+#else
+ {"word", cons, 4},
+#endif
+ {"extend", float_cons, 'x'},
+ {"ldouble", float_cons, 'x'},
+ {"packed", float_cons, 'p'},
+ {0, 0, 0}
+};
+
+/* Stuff needed to resolve the label ambiguity
+ As:
+ ...
+ label: <insn>
+ may differ from:
+ ...
+ label:
+ <insn>
+*/
+
+symbolS * last_label_seen;
+static int label_is_thumb_function_name = false;
+
+/* Literal stuff */
+
+#define MAX_LITERAL_POOL_SIZE 1024
+
+typedef struct literalS
+{
+ struct expressionS exp;
+ struct arm_it * inst;
+} literalT;
+
+literalT literals[MAX_LITERAL_POOL_SIZE];
+int next_literal_pool_place = 0; /* Next free entry in the pool */
+int lit_pool_num = 1; /* Next literal pool number */
+symbolS * current_poolP = NULL;
+symbolS * symbol_make_empty PARAMS ((void));
+
+static int
+add_to_lit_pool ()
+{
+ int lit_count = 0;
+
+ if (current_poolP == NULL)
+ current_poolP = symbol_make_empty ();
+
+ /* Check if this literal value is already in the pool: */
+ while (lit_count < next_literal_pool_place)
+ {
+ if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
+ && inst.reloc.exp.X_op == O_constant
+ && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
+ && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
+ break;
+ lit_count++;
+ }
+
+ if (lit_count == next_literal_pool_place) /* new entry */
+ {
+ if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
+ {
+ inst.error = _("Literal Pool Overflow");
+ return FAIL;
+ }
+
+ literals[next_literal_pool_place].exp = inst.reloc.exp;
+ lit_count = next_literal_pool_place++;
+ }
+
+ inst.reloc.exp.X_op = O_symbol;
+ inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
+ inst.reloc.exp.X_add_symbol = current_poolP;
+
+ return SUCCESS;
+}
+
+/* Can't use symbol_new here, so have to create a symbol and then at
+ a later date assign it a value. Thats what these functions do. */
+static void
+symbol_locate (symbolP, name, segment, valu, frag)
+ symbolS * symbolP;
+ CONST char * name; /* It is copied, the caller can modify */
+ segT segment; /* Segment identifier (SEG_<something>) */
+ valueT valu; /* Symbol value */
+ fragS * frag; /* Associated fragment */
+{
+ unsigned int name_length;
+ char * preserved_copy_of_name;
+
+ name_length = strlen (name) + 1; /* +1 for \0 */
+ obstack_grow (&notes, name, name_length);
+ preserved_copy_of_name = obstack_finish (&notes);
+#ifdef STRIP_UNDERSCORE
+ if (preserved_copy_of_name[0] == '_')
+ preserved_copy_of_name++;
+#endif
+
+#ifdef tc_canonicalize_symbol_name
+ preserved_copy_of_name =
+ tc_canonicalize_symbol_name (preserved_copy_of_name);
+#endif
+
+ S_SET_NAME (symbolP, preserved_copy_of_name);
+
+ S_SET_SEGMENT (symbolP, segment);
+ S_SET_VALUE (symbolP, valu);
+ symbol_clear_list_pointers(symbolP);
+
+ symbolP->sy_frag = frag;
+
+ /* Link to end of symbol chain. */
+ {
+ extern int symbol_table_frozen;
+ if (symbol_table_frozen)
+ abort ();
+ }
+
+ symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
+
+ obj_symbol_new_hook (symbolP);
+
+#ifdef tc_symbol_new_hook
+ tc_symbol_new_hook (symbolP);
+#endif
+
+#ifdef DEBUG_SYMS
+ verify_symbol_chain (symbol_rootP, symbol_lastP);
+#endif /* DEBUG_SYMS */
+}
+
+symbolS *
+symbol_make_empty ()
+{
+ symbolS * symbolP;
+
+ symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
+
+ /* symbol must be born in some fixed state. This seems as good as any. */
+ memset (symbolP, 0, sizeof (symbolS));
+
+ symbolP->bsym = bfd_make_empty_symbol (stdoutput);
+ assert (symbolP->bsym != 0);
+ symbolP->bsym->udata.p = (PTR) symbolP;
+
+ return symbolP;
+}
+
+/* Check that an immediate is valid, and if so, convert it to the right format. */
+
+static unsigned int
+validate_immediate (val)
+ unsigned int val;
+{
+ unsigned int a;
+ unsigned int i;
+
+#define rotate_left(v, n) (v << n | v >> (32 - n))
+
+ for (i = 0; i < 32; i += 2)
+ if ((a = rotate_left (val, i)) <= 0xff)
+ return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
+
+ return FAIL;
+}
+
+static int
+validate_offset_imm (val, hwse)
+ int val;
+ int hwse;
+{
+ if ((hwse && (val < -255 || val > 255))
+ || (val < -4095 || val > 4095))
+ return FAIL;
+ return val;
+}
+
+
+static void
+s_req (a)
+ int a;
+{
+ as_bad (_("Invalid syntax for .req directive."));
+}
+
+static void
+s_bss (ignore)
+ int ignore;
+{
+ /* We don't support putting frags in the BSS segment, we fake it by
+ marking in_bss, then looking at s_skip for clues?.. */
+ subseg_set (bss_section, 0);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_even (ignore)
+ int ignore;
+{
+ if (!need_pass_2) /* Never make frag if expect extra pass. */
+ frag_align (1, 0, 0);
+
+ record_alignment (now_seg, 1);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_ltorg (internal)
+ int internal;
+{
+ int lit_count = 0;
+ char sym_name[20];
+
+ if (current_poolP == NULL)
+ {
+ /* Nothing to do */
+ if (!internal)
+ as_tsktsk (_("Nothing to put in the pool\n"));
+ return;
+ }
+
+ /* Align pool as you have word accesses */
+ /* Only make a frag if we have to ... */
+ if (!need_pass_2)
+ frag_align (2, 0, 0);
+
+ record_alignment (now_seg, 2);
+
+ if (internal)
+ as_tsktsk (_("Inserting implicit pool at change of section"));
+
+ sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
+
+ symbol_locate (current_poolP, sym_name, now_seg,
+ (valueT) frag_now_fix (), frag_now);
+ symbol_table_insert (current_poolP);
+
+ ARM_SET_THUMB (current_poolP, thumb_mode);
+
+#if defined OBJ_COFF || defined OBJ_ELF
+ ARM_SET_INTERWORK (current_poolP, support_interwork);
+#endif
+
+ while (lit_count < next_literal_pool_place)
+ /* First output the expression in the instruction to the pool */
+ emit_expr (&(literals[lit_count++].exp), 4); /* .word */
+
+ next_literal_pool_place = 0;
+ current_poolP = NULL;
+}
+
+static void
+s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
+ int unused;
+{
+ register int temp;
+ register long temp_fill;
+ long max_alignment = 15;
+
+ temp = get_absolute_expression ();
+ if (temp > max_alignment)
+ as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
+ else if (temp < 0)
+ {
+ as_bad (_("Alignment negative. 0 assumed."));
+ temp = 0;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ temp_fill = get_absolute_expression ();
+ }
+ else
+ temp_fill = 0;
+
+ if (!temp)
+ temp = 2;
+
+ /* Only make a frag if we HAVE to. . . */
+ if (temp && !need_pass_2)
+ frag_align (temp, (int) temp_fill, 0);
+ demand_empty_rest_of_line ();
+
+ record_alignment (now_seg, temp);
+}
+
+static void
+s_force_thumb (ignore)
+ int ignore;
+{
+ /* If we are not already in thumb mode go into it, EVEN if
+ the target processor does not support thumb instructions.
+ This is used by gcc/config/arm/lib1funcs.asm for example
+ to compile interworking support functions even if the
+ target processor should not support interworking. */
+
+ if (! thumb_mode)
+ {
+ thumb_mode = 1;
+
+ record_alignment (now_seg, 1);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_thumb_func (ignore)
+ int ignore;
+{
+ /* The following label is the name/address of the start of a Thumb function.
+ We need to know this for the interworking support. */
+
+ label_is_thumb_function_name = true;
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+opcode_select (width)
+ int width;
+{
+ switch (width)
+ {
+ case 16:
+ if (! thumb_mode)
+ {
+ if (! (cpu_variant & ARM_THUMB))
+ as_bad (_("selected processor does not support THUMB opcodes"));
+ thumb_mode = 1;
+ /* No need to force the alignment, since we will have been
+ coming from ARM mode, which is word-aligned. */
+ record_alignment (now_seg, 1);
+ }
+ break;
+
+ case 32:
+ if (thumb_mode)
+ {
+ if ((cpu_variant & ARM_ANY) == ARM_THUMB)
+ as_bad (_("selected processor does not support ARM opcodes"));
+ thumb_mode = 0;
+ if (!need_pass_2)
+ frag_align (2, 0, 0);
+ record_alignment (now_seg, 1);
+ }
+ break;
+
+ default:
+ as_bad (_("invalid instruction size selected (%d)"), width);
+ }
+}
+
+static void
+s_arm (ignore)
+ int ignore;
+{
+ opcode_select (32);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_thumb (ignore)
+ int ignore;
+{
+ opcode_select (16);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_code (unused)
+ int unused;
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ switch (temp)
+ {
+ case 16:
+ case 32:
+ opcode_select (temp);
+ break;
+
+ default:
+ as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
+ }
+}
+
+static void
+end_of_line (str)
+ char * str;
+{
+ while (*str == ' ')
+ str++;
+
+ if (*str != '\0')
+ inst.error = _("Garbage following instruction");
+}
+
+static int
+skip_past_comma (str)
+ char ** str;
+{
+ char *p = *str, c;
+ int comma = 0;
+
+ while ((c = *p) == ' ' || c == ',')
+ {
+ p++;
+ if (c == ',' && comma++)
+ return FAIL;
+ }
+
+ if (c == '\0')
+ return FAIL;
+
+ *str = p;
+ return comma ? SUCCESS : FAIL;
+}
+
+/* A standard register must be given at this point. Shift is the place to
+ put it in the instruction. */
+
+static int
+reg_required_here (str, shift)
+ char ** str;
+ int shift;
+{
+ static char buff [128]; /* XXX */
+ int reg;
+ char * start = *str;
+
+ if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
+ {
+ if (shift >= 0)
+ inst.instruction |= reg << shift;
+ return reg;
+ }
+
+ /* Restore the start point, we may have got a reg of the wrong class. */
+ *str = start;
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden */
+ sprintf (buff, _("Register expected, not '%.100s'"), start);
+ inst.error = buff;
+
+ return FAIL;
+}
+
+static int
+psr_required_here (str, cpsr, spsr)
+ char ** str;
+ int cpsr;
+ int spsr;
+{
+ int psr;
+ char * start = *str;
+ psr = arm_psr_parse (str);
+
+ if (psr == cpsr || psr == spsr)
+ {
+ if (psr == spsr)
+ inst.instruction |= 1 << 22;
+
+ return SUCCESS;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden */
+ inst.error = _("<psr(f)> expected");
+
+ /* Restore the start point. */
+ *str = start;
+ return FAIL;
+}
+
+static int
+co_proc_number (str)
+ char **str;
+{
+ int processor, pchar;
+
+ while (**str == ' ')
+ (*str)++;
+
+ /* The data sheet seems to imply that just a number on its own is valid
+ here, but the RISC iX assembler seems to accept a prefix 'p'. We will
+ accept either. */
+ if (**str == 'p' || **str == 'P')
+ (*str)++;
+
+ pchar = *(*str)++;
+ if (pchar >= '0' && pchar <= '9')
+ {
+ processor = pchar - '0';
+ if (**str >= '0' && **str <= '9')
+ {
+ processor = processor * 10 + *(*str)++ - '0';
+ if (processor > 15)
+ {
+ inst.error = _("Illegal co-processor number");
+ return FAIL;
+ }
+ }
+ }
+ else
+ {
+ inst.error = _("Bad or missing co-processor number");
+ return FAIL;
+ }
+
+ inst.instruction |= processor << 8;
+ return SUCCESS;
+}
+
+static int
+cp_opc_expr (str, where, length)
+ char ** str;
+ int where;
+ int length;
+{
+ expressionS expr;
+
+ while (**str == ' ')
+ (*str)++;
+
+ memset (&expr, '\0', sizeof (expr));
+
+ if (my_get_expression (&expr, str))
+ return FAIL;
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("bad or missing expression");
+ return FAIL;
+ }
+
+ if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
+ {
+ inst.error = _("immediate co-processor expression too large");
+ return FAIL;
+ }
+
+ inst.instruction |= expr.X_add_number << where;
+ return SUCCESS;
+}
+
+static int
+cp_reg_required_here (str, where)
+ char ** str;
+ int where;
+{
+ int reg;
+ char * start = *str;
+
+ if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
+ {
+ reg &= 15;
+ inst.instruction |= reg << where;
+ return reg;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden */
+ inst.error = _("Co-processor register expected");
+
+ /* Restore the start point */
+ *str = start;
+ return FAIL;
+}
+
+static int
+fp_reg_required_here (str, where)
+ char ** str;
+ int where;
+{
+ int reg;
+ char * start = *str;
+
+ if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
+ {
+ reg &= 7;
+ inst.instruction |= reg << where;
+ return reg;
+ }
+
+ /* In the few cases where we might be able to accept something else
+ this error can be overridden */
+ inst.error = _("Floating point register expected");
+
+ /* Restore the start point */
+ *str = start;
+ return FAIL;
+}
+
+static int
+cp_address_offset (str)
+ char ** str;
+{
+ int offset;
+
+ while (**str == ' ')
+ (*str)++;
+
+ if (! is_immediate_prefix (**str))
+ {
+ inst.error = _("immediate expression expected");
+ return FAIL;
+ }
+
+ (*str)++;
+
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ offset = inst.reloc.exp.X_add_number;
+
+ if (offset & 3)
+ {
+ inst.error = _("co-processor address must be word aligned");
+ return FAIL;
+ }
+
+ if (offset > 1023 || offset < -1023)
+ {
+ inst.error = _("offset too large");
+ return FAIL;
+ }
+
+ if (offset >= 0)
+ inst.instruction |= INDEX_UP;
+ else
+ offset = -offset;
+
+ inst.instruction |= offset >> 2;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+
+ return SUCCESS;
+}
+
+static int
+cp_address_required_here (str)
+ char ** str;
+{
+ char * p = * str;
+ int pre_inc = 0;
+ int write_back = 0;
+
+ if (*p == '[')
+ {
+ int reg;
+
+ p++;
+ while (*p == ' ')
+ p++;
+
+ if ((reg = reg_required_here (& p, 16)) == FAIL)
+ return FAIL;
+
+ while (*p == ' ')
+ p++;
+
+ if (*p == ']')
+ {
+ p++;
+
+ if (skip_past_comma (& p) == SUCCESS)
+ {
+ /* [Rn], #expr */
+ write_back = WRITE_BACK;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used in post-increment");
+ return FAIL;
+ }
+
+ if (cp_address_offset (& p) == FAIL)
+ return FAIL;
+ }
+ else
+ pre_inc = PRE_INDEX | INDEX_UP;
+ }
+ else
+ {
+ /* '['Rn, #expr']'[!] */
+
+ if (skip_past_comma (& p) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return FAIL;
+ }
+
+ pre_inc = PRE_INDEX;
+
+ if (cp_address_offset (& p) == FAIL)
+ return FAIL;
+
+ while (*p == ' ')
+ p++;
+
+ if (*p++ != ']')
+ {
+ inst.error = _("missing ]");
+ return FAIL;
+ }
+
+ while (*p == ' ')
+ p++;
+
+ if (*p == '!')
+ {
+ if (reg == REG_PC)
+ {
+ inst.error = _("pc may not be used with write-back");
+ return FAIL;
+ }
+
+ p++;
+ write_back = WRITE_BACK;
+ }
+ }
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &p))
+ return FAIL;
+
+ inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+ inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = PRE_INDEX;
+ }
+
+ inst.instruction |= write_back | pre_inc;
+ *str = p;
+ return SUCCESS;
+}
+
+static void
+do_nop (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ /* Do nothing really */
+ inst.instruction |= flags; /* This is pointless */
+ end_of_line (str);
+ return;
+}
+
+static void
+do_mrs (str, flags)
+ char *str;
+ unsigned long flags;
+{
+ /* Only one syntax */
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 12) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL)
+ {
+ inst.error = _("<psr> expected");
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+/* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
+static void
+do_msr (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int reg;
+
+ while (*str == ' ')
+ str ++;
+
+ if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
+ {
+ inst.instruction |= PSR_ALL;
+
+ /* Sytax should be "<psr>, Rm" */
+ if (skip_past_comma (&str) == FAIL
+ || (reg = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+ }
+ else
+ {
+ if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS)
+ inst.instruction |= PSR_FLAGS;
+ else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS)
+ inst.instruction |= PSR_CONTROL;
+ else
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
+
+ if ((reg = reg_required_here (& str, 0)) != FAIL)
+ ;
+ /* Immediate expression */
+ else if (is_immediate_prefix (* str))
+ {
+ str ++;
+ inst.error = NULL;
+
+ if (my_get_expression (& inst.reloc.exp, & str))
+ {
+ inst.error = _("Register or shift expression expected");
+ return;
+ }
+
+ if (inst.reloc.exp.X_add_symbol)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.reloc.pc_rel = 0;
+ }
+ else
+ {
+ unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
+ if (value == FAIL)
+ {
+ inst.error = _("Invalid constant");
+ return;
+ }
+
+ inst.instruction |= value;
+ }
+
+ flags |= INST_IMMEDIATE;
+ }
+ else
+ {
+ inst.error = _("Error: unrecognised syntax for second argument to msr instruction");
+ return;
+ }
+ }
+
+ inst.error = NULL;
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+/* Long Multiply Parser
+ UMULL RdLo, RdHi, Rm, Rs
+ SMULL RdLo, RdHi, Rm, Rs
+ UMLAL RdLo, RdHi, Rm, Rs
+ SMLAL RdLo, RdHi, Rm, Rs
+*/
+static void
+do_mull (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int rdlo, rdhi, rm, rs;
+
+ /* only one format "rdlo, rdhi, rm, rs" */
+ while (*str == ' ')
+ str++;
+
+ if ((rdlo = reg_required_here (&str, 12)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rdhi = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ /* rdhi, rdlo and rm must all be different */
+ if (rdlo == rdhi || rdlo == rm || rdhi == rm)
+ as_tsktsk (_("rdhi, rdlo and rm must all be different"));
+
+ if (skip_past_comma (&str) == FAIL
+ || (rs = reg_required_here (&str, 8)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_mul (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int rd, rm;
+
+ /* only one format "rd, rm, rs" */
+ while (*str == ' ')
+ str++;
+
+ if ((rd = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rd == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rm == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ if (rm == rd)
+ as_tsktsk (_("rd and rm should be different in mul"));
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 8)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rm == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_mla (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int rd, rm;
+
+ /* only one format "rd, rm, rs, rn" */
+ while (*str == ' ')
+ str++;
+
+ if ((rd = reg_required_here (&str, 16)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rd == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 0)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rm == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ if (rm == rd)
+ as_tsktsk (_("rd and rm should be different in mla"));
+
+ if (skip_past_comma (&str) == FAIL
+ || (rd = reg_required_here (&str, 8)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (rm = reg_required_here (&str, 12)) == FAIL)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if (rd == REG_PC || rm == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+/* Returns the index into fp_values of a floating point number, or -1 if
+ not in the table. */
+static int
+my_get_float_expression (str)
+ char ** str;
+{
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char * save_in;
+ expressionS exp;
+ int i;
+ int j;
+
+ memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
+ /* Look for a raw floating point number */
+ if ((save_in = atof_ieee (*str, 'x', words)) != NULL
+ && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
+ {
+ for (i = 0; i < NUM_FLOAT_VALS; i++)
+ {
+ for (j = 0; j < MAX_LITTLENUMS; j++)
+ {
+ if (words[j] != fp_values[i][j])
+ break;
+ }
+
+ if (j == MAX_LITTLENUMS)
+ {
+ *str = save_in;
+ return i;
+ }
+ }
+ }
+
+ /* Try and parse a more complex expression, this will probably fail
+ unless the code uses a floating point prefix (eg "0f") */
+ save_in = input_line_pointer;
+ input_line_pointer = *str;
+ if (expression (&exp) == absolute_section
+ && exp.X_op == O_big
+ && exp.X_add_number < 0)
+ {
+ /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
+ Ditto for 15. */
+ if (gen_to_words (words, 5, (long)15) == 0)
+ {
+ for (i = 0; i < NUM_FLOAT_VALS; i++)
+ {
+ for (j = 0; j < MAX_LITTLENUMS; j++)
+ {
+ if (words[j] != fp_values[i][j])
+ break;
+ }
+
+ if (j == MAX_LITTLENUMS)
+ {
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return i;
+ }
+ }
+ }
+ }
+
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return -1;
+}
+
+/* Return true if anything in the expression is a bignum */
+static int
+walk_no_bignums (sp)
+ symbolS * sp;
+{
+ if (sp->sy_value.X_op == O_big)
+ return 1;
+
+ if (sp->sy_value.X_add_symbol)
+ {
+ return (walk_no_bignums (sp->sy_value.X_add_symbol)
+ || (sp->sy_value.X_op_symbol
+ && walk_no_bignums (sp->sy_value.X_op_symbol)));
+ }
+
+ return 0;
+}
+
+static int
+my_get_expression (ep, str)
+ expressionS * ep;
+ char ** str;
+{
+ char * save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = *str;
+ seg = expression (ep);
+
+#ifdef OBJ_AOUT
+ if (seg != absolute_section
+ && seg != text_section
+ && seg != data_section
+ && seg != bss_section
+ && seg != undefined_section)
+ {
+ inst.error = _("bad_segment");
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+#endif
+
+ /* Get rid of any bignums now, so that we don't generate an error for which
+ we can't establish a line number later on. Big numbers are never valid
+ in instructions, which is where this routine is always called. */
+ if (ep->X_op == O_big
+ || (ep->X_add_symbol
+ && (walk_no_bignums (ep->X_add_symbol)
+ || (ep->X_op_symbol
+ && walk_no_bignums (ep->X_op_symbol)))))
+ {
+ inst.error = _("Invalid constant");
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+
+ *str = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+/* unrestrict should be one if <shift> <register> is permitted for this
+ instruction */
+
+static int
+decode_shift (str, unrestrict)
+ char ** str;
+ int unrestrict;
+{
+ struct asm_shift * shft;
+ char * p;
+ char c;
+
+ while (**str == ' ')
+ (*str)++;
+
+ for (p = *str; isalpha (*p); p++)
+ ;
+
+ if (p == *str)
+ {
+ inst.error = _("Shift expression expected");
+ return FAIL;
+ }
+
+ c = *p;
+ *p = '\0';
+ shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
+ *p = c;
+ if (shft)
+ {
+ if (!strncmp (*str, "rrx", 3)
+ || !strncmp (*str, "RRX", 3))
+ {
+ *str = p;
+ inst.instruction |= shft->value;
+ return SUCCESS;
+ }
+
+ while (*p == ' ')
+ p++;
+
+ if (unrestrict && reg_required_here (&p, 8) != FAIL)
+ {
+ inst.instruction |= shft->value | SHIFT_BY_REG;
+ *str = p;
+ return SUCCESS;
+ }
+ else if (is_immediate_prefix (* p))
+ {
+ inst.error = NULL;
+ p++;
+ if (my_get_expression (&inst.reloc.exp, &p))
+ return FAIL;
+
+ /* Validate some simple #expressions */
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned num = inst.reloc.exp.X_add_number;
+
+ /* Reject operations greater than 32, or lsl #32 */
+ if (num > 32 || (num == 32 && shft->value == 0))
+ {
+ inst.error = _("Invalid immediate shift");
+ return FAIL;
+ }
+
+ /* Shifts of zero should be converted to lsl (which is zero)*/
+ if (num == 0)
+ {
+ *str = p;
+ return SUCCESS;
+ }
+
+ /* Shifts of 32 are encoded as 0, for those shifts that
+ support it. */
+ if (num == 32)
+ num = 0;
+
+ inst.instruction |= (num << 7) | shft->value;
+ *str = p;
+ return SUCCESS;
+ }
+
+ inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+ inst.reloc.pc_rel = 0;
+ inst.instruction |= shft->value;
+ *str = p;
+ return SUCCESS;
+ }
+ else
+ {
+ inst.error = unrestrict ? _("shift requires register or #expression")
+ : _("shift requires #expression");
+ *str = p;
+ return FAIL;
+ }
+ }
+
+ inst.error = _("Shift expression expected");
+ return FAIL;
+}
+
+/* Do those data_ops which can take a negative immediate constant */
+/* by altering the instuction. A bit of a hack really */
+/* MOV <-> MVN
+ AND <-> BIC
+ ADC <-> SBC
+ by inverting the second operand, and
+ ADD <-> SUB
+ CMP <-> CMN
+ by negating the second operand.
+*/
+static int
+negate_data_op (instruction, value)
+ unsigned long * instruction;
+ unsigned long value;
+{
+ int op, new_inst;
+ unsigned long negated, inverted;
+
+ negated = validate_immediate (-value);
+ inverted = validate_immediate (~value);
+
+ op = (*instruction >> DATA_OP_SHIFT) & 0xf;
+ switch (op)
+ {
+ /* First negates */
+ case OPCODE_SUB: /* ADD <-> SUB */
+ new_inst = OPCODE_ADD;
+ value = negated;
+ break;
+
+ case OPCODE_ADD:
+ new_inst = OPCODE_SUB;
+ value = negated;
+ break;
+
+ case OPCODE_CMP: /* CMP <-> CMN */
+ new_inst = OPCODE_CMN;
+ value = negated;
+ break;
+
+ case OPCODE_CMN:
+ new_inst = OPCODE_CMP;
+ value = negated;
+ break;
+
+ /* Now Inverted ops */
+ case OPCODE_MOV: /* MOV <-> MVN */
+ new_inst = OPCODE_MVN;
+ value = inverted;
+ break;
+
+ case OPCODE_MVN:
+ new_inst = OPCODE_MOV;
+ value = inverted;
+ break;
+
+ case OPCODE_AND: /* AND <-> BIC */
+ new_inst = OPCODE_BIC;
+ value = inverted;
+ break;
+
+ case OPCODE_BIC:
+ new_inst = OPCODE_AND;
+ value = inverted;
+ break;
+
+ case OPCODE_ADC: /* ADC <-> SBC */
+ new_inst = OPCODE_SBC;
+ value = inverted;
+ break;
+
+ case OPCODE_SBC:
+ new_inst = OPCODE_ADC;
+ value = inverted;
+ break;
+
+ /* We cannot do anything */
+ default:
+ return FAIL;
+ }
+
+ if (value == FAIL)
+ return FAIL;
+
+ *instruction &= OPCODE_MASK;
+ *instruction |= new_inst << DATA_OP_SHIFT;
+ return value;
+}
+
+static int
+data_op2 (str)
+ char ** str;
+{
+ int value;
+ expressionS expr;
+
+ while (**str == ' ')
+ (*str)++;
+
+ if (reg_required_here (str, 0) != FAIL)
+ {
+ if (skip_past_comma (str) == SUCCESS)
+ {
+ /* Shift operation on register */
+ return decode_shift (str, NO_SHIFT_RESTRICT);
+ }
+ return SUCCESS;
+ }
+ else
+ {
+ /* Immediate expression */
+ if (is_immediate_prefix (**str))
+ {
+ (*str)++;
+ inst.error = NULL;
+ if (my_get_expression (&inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_add_symbol)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.reloc.pc_rel = 0;
+ }
+ else
+ {
+ if (skip_past_comma (str) == SUCCESS)
+ {
+ /* #x, y -- ie explicit rotation by Y */
+ if (my_get_expression (&expr, str))
+ return FAIL;
+
+ if (expr.X_op != O_constant)
+ {
+ inst.error = _("Constant expression expected");
+ return FAIL;
+ }
+
+ /* Rotate must be a multiple of 2 */
+ if (((unsigned) expr.X_add_number) > 30
+ || (expr.X_add_number & 1) != 0
+ || ((unsigned) inst.reloc.exp.X_add_number) > 255)
+ {
+ inst.error = _("Invalid constant");
+ return FAIL;
+ }
+ inst.instruction |= INST_IMMEDIATE;
+ inst.instruction |= inst.reloc.exp.X_add_number;
+ inst.instruction |= expr.X_add_number << 7;
+ return SUCCESS;
+ }
+
+ /* Implicit rotation, select a suitable one */
+ value = validate_immediate (inst.reloc.exp.X_add_number);
+
+ if (value == FAIL)
+ {
+ /* Can't be done, perhaps the code reads something like
+ "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
+ if ((value = negate_data_op (&inst.instruction,
+ inst.reloc.exp.X_add_number))
+ == FAIL)
+ {
+ inst.error = _("Invalid constant");
+ return FAIL;
+ }
+ }
+
+ inst.instruction |= value;
+ }
+
+ inst.instruction |= INST_IMMEDIATE;
+ return SUCCESS;
+ }
+
+ (*str)++;
+ inst.error = _("Register or shift expression expected");
+ return FAIL;
+ }
+}
+
+static int
+fp_op2 (str)
+ char ** str;
+{
+ while (**str == ' ')
+ (*str)++;
+
+ if (fp_reg_required_here (str, 0) != FAIL)
+ return SUCCESS;
+ else
+ {
+ /* Immediate expression */
+ if (*((*str)++) == '#')
+ {
+ int i;
+
+ inst.error = NULL;
+ while (**str == ' ')
+ (*str)++;
+
+ /* First try and match exact strings, this is to guarantee that
+ some formats will work even for cross assembly */
+
+ for (i = 0; fp_const[i]; i++)
+ {
+ if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
+ {
+ char *start = *str;
+
+ *str += strlen (fp_const[i]);
+ if (is_end_of_line[(int)**str] || **str == '\0')
+ {
+ inst.instruction |= i + 8;
+ return SUCCESS;
+ }
+ *str = start;
+ }
+ }
+
+ /* Just because we didn't get a match doesn't mean that the
+ constant isn't valid, just that it is in a format that we
+ don't automatically recognize. Try parsing it with
+ the standard expression routines. */
+ if ((i = my_get_float_expression (str)) >= 0)
+ {
+ inst.instruction |= i + 8;
+ return SUCCESS;
+ }
+
+ inst.error = _("Invalid floating point immediate expression");
+ return FAIL;
+ }
+ inst.error = _("Floating point register or immediate expression expected");
+ return FAIL;
+ }
+}
+
+static void
+do_arit (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 16) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || data_op2 (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_adr (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ /* This is a pseudo-op of the form "adr rd, label" to be converted
+ into a relative address of the form "add rd, pc, #label-.-8" */
+
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 12) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+ /* Frag hacking will turn this into a sub instruction if the offset turns
+ out to be negative. */
+ inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_cmp (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || data_op2 (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ if ((flags & 0x0000f000) == 0)
+ inst.instruction |= CONDS_BIT;
+
+ end_of_line (str);
+ return;
+}
+
+static void
+do_mov (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || data_op2 (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static int
+ldst_extend (str, hwse)
+ char ** str;
+ int hwse;
+{
+ int add = INDEX_UP;
+
+ switch (**str)
+ {
+ case '#':
+ case '$':
+ (*str)++;
+ if (my_get_expression (& inst.reloc.exp, str))
+ return FAIL;
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ int value = inst.reloc.exp.X_add_number;
+
+ if ((hwse && (value < -255 || value > 255))
+ || (value < -4095 || value > 4095))
+ {
+ inst.error = _("address offset too large");
+ return FAIL;
+ }
+
+ if (value < 0)
+ {
+ value = -value;
+ add = 0;
+ }
+
+ /* Halfword and signextension instructions have the
+ immediate value split across bits 11..8 and bits 3..0 */
+ if (hwse)
+ inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF;
+ else
+ inst.instruction |= add | value;
+ }
+ else
+ {
+ if (hwse)
+ {
+ inst.instruction |= HWOFFSET_IMM;
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+ inst.reloc.pc_rel = 0;
+ }
+ return SUCCESS;
+
+ case '-':
+ add = 0; /* and fall through */
+ case '+':
+ (*str)++; /* and fall through */
+ default:
+ if (reg_required_here (str, 0) == FAIL)
+ return FAIL;
+
+ if (hwse)
+ inst.instruction |= add;
+ else
+ {
+ inst.instruction |= add | OFFSET_REG;
+ if (skip_past_comma (str) == SUCCESS)
+ return decode_shift (str, SHIFT_RESTRICT);
+ }
+
+ return SUCCESS;
+ }
+}
+
+static void
+do_ldst (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int halfword = 0;
+ int pre_inc = 0;
+ int conflict_reg;
+ int value;
+
+ /* This is not ideal, but it is the simplest way of dealing with the
+ ARM7T halfword instructions (since they use a different
+ encoding, but the same mnemonic): */
+ if (halfword = ((flags & 0x80000000) != 0))
+ {
+ /* This is actually a load/store of a halfword, or a
+ signed-extension load */
+ if ((cpu_variant & ARM_HALFWORD) == 0)
+ {
+ inst.error
+ = _("Processor does not support halfwords or signed bytes");
+ return;
+ }
+
+ inst.instruction = (inst.instruction & COND_MASK)
+ | (flags & ~COND_MASK);
+
+ flags = 0;
+ }
+
+ while (*str == ' ')
+ str++;
+
+ if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (& str) == FAIL)
+ {
+ inst.error = _("Address expected");
+ return;
+ }
+
+ if (*str == '[')
+ {
+ int reg;
+
+ str++;
+ while (*str == ' ')
+ str++;
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ conflict_reg = (((conflict_reg == reg)
+ && (inst.instruction & LOAD_BIT))
+ ? 1 : 0);
+
+ while (*str == ' ')
+ str++;
+
+ if (*str == ']')
+ {
+ str++;
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ /* [Rn],... (post inc) */
+ if (ldst_extend (&str, halfword) == FAIL)
+ return;
+ if (conflict_reg)
+ as_warn (_("destination register same as write-back base\n"));
+ }
+ else
+ {
+ /* [Rn] */
+ if (halfword)
+ inst.instruction |= HWOFFSET_IMM;
+
+ while (*str == ' ')
+ str++;
+
+ if (*str == '!')
+ {
+ if (conflict_reg)
+ as_warn (_("destination register same as write-back base\n"));
+ str++;
+ inst.instruction |= WRITE_BACK;
+ }
+
+ flags |= INDEX_UP;
+ if (! (flags & TRANS_BIT))
+ pre_inc = 1;
+ }
+ }
+ else
+ {
+ /* [Rn,...] */
+ if (skip_past_comma (&str) == FAIL)
+ {
+ inst.error = _("pre-indexed expression expected");
+ return;
+ }
+
+ pre_inc = 1;
+ if (ldst_extend (&str, halfword) == FAIL)
+ return;
+
+ while (*str == ' ')
+ str++;
+
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ while (*str == ' ')
+ str++;
+
+ if (*str == '!')
+ {
+ if (conflict_reg)
+ as_tsktsk (_("destination register same as write-back base\n"));
+ str++;
+ inst.instruction |= WRITE_BACK;
+ }
+ }
+ }
+ else if (*str == '=')
+ {
+ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
+ str++;
+
+ while (*str == ' ')
+ str++;
+
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ if (inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_symbol)
+ {
+ inst.error = _("Constant expression expected");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op == O_constant
+ && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
+ {
+ /* This can be done with a mov instruction */
+ inst.instruction &= LITERAL_MASK;
+ inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
+ inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
+ end_of_line(str);
+ return;
+ }
+ else
+ {
+ /* Insert into literal pool */
+ if (add_to_lit_pool () == FAIL)
+ {
+ if (!inst.error)
+ inst.error = _("literal pool insertion failed");
+ return;
+ }
+
+ /* Change the instruction exp to point to the pool */
+ if (halfword)
+ {
+ inst.instruction |= HWOFFSET_IMM;
+ inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_LITERAL;
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = 1;
+ }
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ if (halfword)
+ {
+ inst.instruction |= HWOFFSET_IMM;
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+ inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= (REG_PC << 16);
+ pre_inc = 1;
+ }
+
+ if (pre_inc && (flags & TRANS_BIT))
+ inst.error = _("Pre-increment instruction with translate");
+
+ inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
+ end_of_line (str);
+ return;
+}
+
+static long
+reg_list (strp)
+ char ** strp;
+{
+ char * str = *strp;
+ long range = 0;
+ int another_range;
+
+ /* We come back here if we get ranges concatenated by '+' or '|' */
+ do
+ {
+ another_range = 0;
+
+ if (*str == '{')
+ {
+ int in_range = 0;
+ int cur_reg = -1;
+
+ str++;
+ do
+ {
+ int reg;
+
+ while (*str == ' ')
+ str++;
+
+ if ((reg = reg_required_here (& str, -1)) == FAIL)
+ return FAIL;
+
+ if (in_range)
+ {
+ int i;
+
+ if (reg <= cur_reg)
+ {
+ inst.error = _("Bad range in register list");
+ return FAIL;
+ }
+
+ for (i = cur_reg + 1; i < reg; i++)
+ {
+ if (range & (1 << i))
+ as_tsktsk
+ (_("Warning: Duplicated register (r%d) in register list"),
+ i);
+ else
+ range |= 1 << i;
+ }
+ in_range = 0;
+ }
+
+ if (range & (1 << reg))
+ as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
+ reg);
+ else if (reg <= cur_reg)
+ as_tsktsk (_("Warning: Register range not in ascending order"));
+
+ range |= 1 << reg;
+ cur_reg = reg;
+ } while (skip_past_comma (&str) != FAIL
+ || (in_range = 1, *str++ == '-'));
+ str--;
+ while (*str == ' ')
+ str++;
+
+ if (*str++ != '}')
+ {
+ inst.error = _("Missing `}'");
+ return FAIL;
+ }
+ }
+ else
+ {
+ expressionS expr;
+
+ if (my_get_expression (&expr, &str))
+ return FAIL;
+
+ if (expr.X_op == O_constant)
+ {
+ if (expr.X_add_number
+ != (expr.X_add_number & 0x0000ffff))
+ {
+ inst.error = _("invalid register mask");
+ return FAIL;
+ }
+
+ if ((range & expr.X_add_number) != 0)
+ {
+ int regno = range & expr.X_add_number;
+
+ regno &= -regno;
+ regno = (1 << regno) - 1;
+ as_tsktsk
+ (_("Warning: Duplicated register (r%d) in register list"),
+ regno);
+ }
+
+ range |= expr.X_add_number;
+ }
+ else
+ {
+ if (inst.reloc.type != 0)
+ {
+ inst.error = _("expression too complex");
+ return FAIL;
+ }
+
+ memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
+ inst.reloc.type = BFD_RELOC_ARM_MULTI;
+ inst.reloc.pc_rel = 0;
+ }
+ }
+
+ while (*str == ' ')
+ str++;
+
+ if (*str == '|' || *str == '+')
+ {
+ str++;
+ another_range = 1;
+ }
+ } while (another_range);
+
+ *strp = str;
+ return range;
+}
+
+static void
+do_ldmstm (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int base_reg;
+ long range;
+
+ while (*str == ' ')
+ str++;
+
+ if ((base_reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ if (base_reg == REG_PC)
+ {
+ inst.error = _("r15 not allowed as base register");
+ return;
+ }
+
+ while (*str == ' ')
+ str++;
+ if (*str == '!')
+ {
+ flags |= WRITE_BACK;
+ str++;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (range = reg_list (&str)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (*str == '^')
+ {
+ str++;
+ flags |= MULTI_SET_PSR;
+ }
+
+ inst.instruction |= flags | range;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_swi (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ /* Allow optional leading '#'. */
+ if (is_immediate_prefix (*str))
+ str++;
+
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return;
+
+ inst.reloc.type = BFD_RELOC_ARM_SWI;
+ inst.reloc.pc_rel = 0;
+ inst.instruction |= flags;
+
+ end_of_line (str);
+
+ return;
+}
+
+static void
+do_swap (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int reg;
+
+ while (*str == ' ')
+ str++;
+
+ if ((reg = reg_required_here (&str, 12)) == FAIL)
+ return;
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("r15 not allowed in swap");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || (reg = reg_required_here (&str, 0)) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (reg == REG_PC)
+ {
+ inst.error = _("r15 not allowed in swap");
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || *str++ != '[')
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ while (*str == ' ')
+ str++;
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ if (reg == REG_PC)
+ {
+ inst.error = bad_pc;
+ return;
+ }
+
+ while (*str == ' ')
+ str++;
+
+ if (*str++ != ']')
+ {
+ inst.error = _("missing ]");
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_branch (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+#ifdef OBJ_ELF
+ {
+ char * save_in;
+
+ /* ScottB: February 5, 1998 */
+ /* Check to see of PLT32 reloc required for the instruction. */
+
+ /* arm_parse_reloc() works on input_line_pointer.
+ We actually want to parse the operands to the branch instruction
+ passed in 'str'. Save the input pointer and restore it later. */
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ if (inst.reloc.exp.X_op == O_symbol
+ && *str == '('
+ && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PLT32;
+ inst.reloc.pc_rel = 0;
+ /* Modify str to point to after parsed operands, otherwise
+ end_of_line() will complain about the (PLT) left in str. */
+ str = input_line_pointer;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
+ inst.reloc.pc_rel = 1;
+ }
+ input_line_pointer = save_in;
+ }
+#else
+ inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
+ inst.reloc.pc_rel = 1;
+#endif /* OBJ_ELF */
+
+ end_of_line (str);
+ return;
+}
+
+static void
+do_bx (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int reg;
+
+ while (*str == ' ')
+ str++;
+
+ if ((reg = reg_required_here (&str, 0)) == FAIL)
+ return;
+
+ if (reg == REG_PC)
+ as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
+
+ end_of_line (str);
+ return;
+}
+
+static void
+do_cdp (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ /* Co-processor data operation.
+ Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
+ while (*str == ' ')
+ str++;
+
+ if (co_proc_number (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_opc_expr (&str, 20,4) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ if (cp_opc_expr (&str, 5, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+ }
+
+ end_of_line (str);
+ return;
+}
+
+static void
+do_lstc (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ /* Co-processor register load/store.
+ Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
+
+ while (*str == ' ')
+ str++;
+
+ if (co_proc_number (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_co_reg (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ /* Co-processor register transfer.
+ Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
+
+ while (*str == ' ')
+ str++;
+
+ if (co_proc_number (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_opc_expr (&str, 21, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_reg_required_here (&str, 0) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == SUCCESS)
+ {
+ if (cp_opc_expr (&str, 5, 3) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+ }
+
+ end_of_line (str);
+ return;
+}
+
+static void
+do_fp_ctrl (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ /* FP control registers.
+ Format: <WFS|RFS|WFC|RFC>{cond} Rn */
+
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ end_of_line (str);
+ return;
+}
+
+static void
+do_fp_ldst (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ switch (inst.suffix)
+ {
+ case SUFF_S:
+ break;
+ case SUFF_D:
+ inst.instruction |= CP_T_X;
+ break;
+ case SUFF_E:
+ inst.instruction |= CP_T_Y;
+ break;
+ case SUFF_P:
+ inst.instruction |= CP_T_X | CP_T_Y;
+ break;
+ default:
+ abort ();
+ }
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str) == FAIL)
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fp_ldmstm (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ int num_regs;
+
+ while (*str == ' ')
+ str++;
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ /* Get Number of registers to transfer */
+ if (skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (! inst.error)
+ inst.error = _("constant expression expected");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op != O_constant)
+ {
+ inst.error = _("Constant value required for number of registers");
+ return;
+ }
+
+ num_regs = inst.reloc.exp.X_add_number;
+
+ if (num_regs < 1 || num_regs > 4)
+ {
+ inst.error = _("number of registers must be in the range [1:4]");
+ return;
+ }
+
+ switch (num_regs)
+ {
+ case 1:
+ inst.instruction |= CP_T_X;
+ break;
+ case 2:
+ inst.instruction |= CP_T_Y;
+ break;
+ case 3:
+ inst.instruction |= CP_T_Y | CP_T_X;
+ break;
+ case 4:
+ break;
+ default:
+ abort ();
+ }
+
+ if (flags)
+ {
+ int reg;
+ int write_back;
+ int offset;
+
+ /* The instruction specified "ea" or "fd", so we can only accept
+ [Rn]{!}. The instruction does not really support stacking or
+ unstacking, so we have to emulate these by setting appropriate
+ bits and offsets. */
+ if (skip_past_comma (&str) == FAIL
+ || *str != '[')
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ str++;
+ while (*str == ' ')
+ str++;
+
+ if ((reg = reg_required_here (&str, 16)) == FAIL)
+ return;
+
+ while (*str == ' ')
+ str++;
+
+ if (*str != ']')
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ str++;
+ if (*str == '!')
+ {
+ write_back = 1;
+ str++;
+ if (reg == REG_PC)
+ {
+ inst.error = _("R15 not allowed as base register with write-back");
+ return;
+ }
+ }
+ else
+ write_back = 0;
+
+ if (flags & CP_T_Pre)
+ {
+ /* Pre-decrement */
+ offset = 3 * num_regs;
+ if (write_back)
+ flags |= CP_T_WB;
+ }
+ else
+ {
+ /* Post-increment */
+ if (write_back)
+ {
+ flags |= CP_T_WB;
+ offset = 3 * num_regs;
+ }
+ else
+ {
+ /* No write-back, so convert this into a standard pre-increment
+ instruction -- aesthetically more pleasing. */
+ flags = CP_T_Pre | CP_T_UD;
+ offset = 0;
+ }
+ }
+
+ inst.instruction |= flags | offset;
+ }
+ else if (skip_past_comma (&str) == FAIL
+ || cp_address_required_here (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_fp_dyadic (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ switch (inst.suffix)
+ {
+ case SUFF_S:
+ break;
+ case SUFF_D:
+ inst.instruction |= 0x00000080;
+ break;
+ case SUFF_E:
+ inst.instruction |= 0x00080000;
+ break;
+ default:
+ abort ();
+ }
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_op2 (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_fp_monadic (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ switch (inst.suffix)
+ {
+ case SUFF_S:
+ break;
+ case SUFF_D:
+ inst.instruction |= 0x00000080;
+ break;
+ case SUFF_E:
+ inst.instruction |= 0x00080000;
+ break;
+ default:
+ abort ();
+ }
+
+ if (fp_reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_op2 (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_fp_cmp (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ if (fp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_op2 (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_fp_from_reg (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ switch (inst.suffix)
+ {
+ case SUFF_S:
+ break;
+ case SUFF_D:
+ inst.instruction |= 0x00000080;
+ break;
+ case SUFF_E:
+ inst.instruction |= 0x00080000;
+ break;
+ default:
+ abort ();
+ }
+
+ if (fp_reg_required_here (&str, 16) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) == FAIL
+ || reg_required_here (&str, 12) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_fp_to_reg (str, flags)
+ char * str;
+ unsigned long flags;
+{
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 12) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || fp_reg_required_here (&str, 0) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.instruction |= flags;
+ end_of_line (str);
+ return;
+}
+
+/* Thumb specific routines */
+
+/* Parse and validate that a register is of the right form, this saves
+ repeated checking of this information in many similar cases.
+ Unlike the 32-bit case we do not insert the register into the opcode
+ here, since the position is often unknown until the full instruction
+ has been parsed. */
+static int
+thumb_reg (strp, hi_lo)
+ char ** strp;
+ int hi_lo;
+{
+ int reg;
+
+ if ((reg = reg_required_here (strp, -1)) == FAIL)
+ return FAIL;
+
+ switch (hi_lo)
+ {
+ case THUMB_REG_LO:
+ if (reg > 7)
+ {
+ inst.error = _("lo register required");
+ return FAIL;
+ }
+ break;
+
+ case THUMB_REG_HI:
+ if (reg < 8)
+ {
+ inst.error = _("hi register required");
+ return FAIL;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return reg;
+}
+
+/* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
+ was SUB. */
+static void
+thumb_add_sub (str, subtract)
+ char * str;
+ int subtract;
+{
+ int Rd, Rs, Rn = FAIL;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (is_immediate_prefix (*str))
+ {
+ Rs = Rd;
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else
+ {
+ if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ /* Two operand format, shuffle the registers and pretend there
+ are 3 */
+ Rn = Rs;
+ Rs = Rd;
+ }
+ else if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+ }
+
+ /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
+ for the latter case, EXPR contains the immediate that was found. */
+ if (Rn != FAIL)
+ {
+ /* All register format. */
+ if (Rd > 7 || Rs > 7 || Rn > 7)
+ {
+ if (Rs != Rd)
+ {
+ inst.error = _("dest and source1 must be the same register");
+ return;
+ }
+
+ /* Can't do this for SUB */
+ if (subtract)
+ {
+ inst.error = _("subtract valid only on lo regs");
+ return;
+ }
+
+ inst.instruction = (T_OPCODE_ADD_HI
+ | (Rd > 7 ? THUMB_H1 : 0)
+ | (Rn > 7 ? THUMB_H2 : 0));
+ inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
+ }
+ else
+ {
+ inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
+ inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
+ }
+ }
+ else
+ {
+ /* Immediate expression, now things start to get nasty. */
+
+ /* First deal with HI regs, only very restricted cases allowed:
+ Adjusting SP, and using PC or SP to get an address. */
+ if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
+ || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
+ {
+ inst.error = _("invalid Hi register with immediate");
+ return;
+ }
+
+ if (inst.reloc.exp.X_op != O_constant)
+ {
+ /* Value isn't known yet, all we can do is store all the fragments
+ we know about in the instruction and let the reloc hacking
+ work it all out. */
+ inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ }
+ else
+ {
+ int offset = inst.reloc.exp.X_add_number;
+
+ if (subtract)
+ offset = -offset;
+
+ if (offset < 0)
+ {
+ offset = -offset;
+ subtract = 1;
+
+ /* Quick check, in case offset is MIN_INT */
+ if (offset < 0)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ }
+ else
+ subtract = 0;
+
+ if (Rd == REG_SP)
+ {
+ if (offset & ~0x1fc)
+ {
+ inst.error = _("invalid immediate value for stack adjust");
+ return;
+ }
+ inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
+ inst.instruction |= offset >> 2;
+ }
+ else if (Rs == REG_PC || Rs == REG_SP)
+ {
+ if (subtract
+ || (offset & ~0x3fc))
+ {
+ inst.error = _("invalid immediate for address calculation");
+ return;
+ }
+ inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
+ : T_OPCODE_ADD_SP);
+ inst.instruction |= (Rd << 8) | (offset >> 2);
+ }
+ else if (Rs == Rd)
+ {
+ if (offset & ~0xff)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
+ inst.instruction |= (Rd << 8) | offset;
+ }
+ else
+ {
+ if (offset & ~0x7)
+ {
+ inst.error = _("immediate value out of range");
+ return;
+ }
+ inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
+ inst.instruction |= Rd | (Rs << 3) | (offset << 6);
+ }
+ }
+ }
+ end_of_line (str);
+}
+
+static void
+thumb_shift (str, shift)
+ char * str;
+ int shift;
+{
+ int Rd, Rs, Rn = FAIL;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (is_immediate_prefix (*str))
+ {
+ /* Two operand immediate format, set Rs to Rd. */
+ Rs = Rd;
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else
+ {
+ if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL)
+ {
+ /* Two operand format, shuffle the registers and pretend there
+ are 3 */
+ Rn = Rs;
+ Rs = Rd;
+ }
+ else if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+ }
+
+ /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
+ for the latter case, EXPR contains the immediate that was found. */
+
+ if (Rn != FAIL)
+ {
+ if (Rs != Rd)
+ {
+ inst.error = _("source1 and dest must be same register");
+ return;
+ }
+
+ switch (shift)
+ {
+ case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
+ case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
+ case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
+ }
+
+ inst.instruction |= Rd | (Rn << 3);
+ }
+ else
+ {
+ switch (shift)
+ {
+ case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
+ case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
+ case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
+ }
+
+ if (inst.reloc.exp.X_op != O_constant)
+ {
+ /* Value isn't known yet, create a dummy reloc and let reloc
+ hacking fix it up */
+
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ }
+ else
+ {
+ unsigned shift_value = inst.reloc.exp.X_add_number;
+
+ if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
+ {
+ inst.error = _("Invalid immediate for shift");
+ return;
+ }
+
+ /* Shifts of zero are handled by converting to LSL */
+ if (shift_value == 0)
+ inst.instruction = T_OPCODE_LSL_I;
+
+ /* Shifts of 32 are encoded as a shift of zero */
+ if (shift_value == 32)
+ shift_value = 0;
+
+ inst.instruction |= shift_value << 6;
+ }
+
+ inst.instruction |= Rd | (Rs << 3);
+ }
+ end_of_line (str);
+}
+
+static void
+thumb_mov_compare (str, move)
+ char * str;
+ int move;
+{
+ int Rd, Rs = FAIL;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ if (Rs != FAIL)
+ {
+ if (Rs < 8 && Rd < 8)
+ {
+ if (move == THUMB_MOVE)
+ /* A move of two lowregs is encoded as ADD Rd, Rs, #0
+ since a MOV instruction produces unpredictable results */
+ inst.instruction = T_OPCODE_ADD_I3;
+ else
+ inst.instruction = T_OPCODE_CMP_LR;
+ inst.instruction |= Rd | (Rs << 3);
+ }
+ else
+ {
+ if (move == THUMB_MOVE)
+ inst.instruction = T_OPCODE_MOV_HR;
+ else
+ inst.instruction = T_OPCODE_CMP_HR;
+
+ if (Rd > 7)
+ inst.instruction |= THUMB_H1;
+
+ if (Rs > 7)
+ inst.instruction |= THUMB_H2;
+
+ inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
+ }
+ }
+ else
+ {
+ if (Rd > 7)
+ {
+ inst.error = _("only lo regs allowed with immediate");
+ return;
+ }
+
+ if (move == THUMB_MOVE)
+ inst.instruction = T_OPCODE_MOV_I8;
+ else
+ inst.instruction = T_OPCODE_CMP_I8;
+
+ inst.instruction |= Rd << 8;
+
+ if (inst.reloc.exp.X_op != O_constant)
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+ else
+ {
+ unsigned value = inst.reloc.exp.X_add_number;
+
+ if (value > 255)
+ {
+ inst.error = _("invalid immediate");
+ return;
+ }
+
+ inst.instruction |= value;
+ }
+ }
+
+ end_of_line (str);
+}
+
+static void
+thumb_load_store (str, load_store, size)
+ char * str;
+ int load_store;
+ int size;
+{
+ int Rd, Rb, Ro = FAIL;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (*str == '[')
+ {
+ str++;
+ if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) != FAIL)
+ {
+ if (is_immediate_prefix (*str))
+ {
+ str++;
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ }
+ else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+ }
+ else
+ {
+ inst.reloc.exp.X_op = O_constant;
+ inst.reloc.exp.X_add_number = 0;
+ }
+
+ if (*str != ']')
+ {
+ inst.error = _("expected ']'");
+ return;
+ }
+ str++;
+ }
+ else if (*str == '=')
+ {
+ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
+ str++;
+
+ while (*str == ' ')
+ str++;
+
+ if (my_get_expression (& inst.reloc.exp, & str))
+ return;
+
+ end_of_line (str);
+
+ if ( inst.reloc.exp.X_op != O_constant
+ && inst.reloc.exp.X_op != O_symbol)
+ {
+ inst.error = "Constant expression expected";
+ return;
+ }
+
+ if (inst.reloc.exp.X_op == O_constant
+ && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
+ {
+ /* This can be done with a mov instruction */
+
+ inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
+ inst.instruction |= inst.reloc.exp.X_add_number;
+ return;
+ }
+
+ /* Insert into literal pool */
+ if (add_to_lit_pool () == FAIL)
+ {
+ if (!inst.error)
+ inst.error = "literal pool insertion failed";
+ return;
+ }
+
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ inst.reloc.pc_rel = 1;
+ inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
+ inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
+
+ return;
+ }
+ else
+ {
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
+ inst.reloc.pc_rel = 1;
+ inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ end_of_line (str);
+ return;
+ }
+
+ if (Rb == REG_PC || Rb == REG_SP)
+ {
+ if (size != THUMB_WORD)
+ {
+ inst.error = _("byte or halfword not valid for base register");
+ return;
+ }
+ else if (Rb == REG_PC && load_store != THUMB_LOAD)
+ {
+ inst.error = _("R15 based store not allowed");
+ return;
+ }
+ else if (Ro != FAIL)
+ {
+ inst.error = _("Invalid base register for register offset");
+ return;
+ }
+
+ if (Rb == REG_PC)
+ inst.instruction = T_OPCODE_LDR_PC;
+ else if (load_store == THUMB_LOAD)
+ inst.instruction = T_OPCODE_LDR_SP;
+ else
+ inst.instruction = T_OPCODE_STR_SP;
+
+ inst.instruction |= Rd << 8;
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned offset = inst.reloc.exp.X_add_number;
+
+ if (offset & ~0x3fc)
+ {
+ inst.error = _("invalid offset");
+ return;
+ }
+
+ inst.instruction |= offset >> 2;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ }
+ else if (Rb > 7)
+ {
+ inst.error = _("invalid base register in load/store");
+ return;
+ }
+ else if (Ro == FAIL)
+ {
+ /* Immediate offset */
+ if (size == THUMB_WORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
+ else if (size == THUMB_HALFWORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
+ else
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
+
+ inst.instruction |= Rd | (Rb << 3);
+
+ if (inst.reloc.exp.X_op == O_constant)
+ {
+ unsigned offset = inst.reloc.exp.X_add_number;
+
+ if (offset & ~(0x1f << size))
+ {
+ inst.error = _("Invalid offset");
+ return;
+ }
+ inst.instruction |= (offset >> size) << 6;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ }
+ else
+ {
+ /* Register offset */
+ if (size == THUMB_WORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
+ else if (size == THUMB_HALFWORD)
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
+ else
+ inst.instruction = (load_store == THUMB_LOAD
+ ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
+
+ inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
+ }
+
+ end_of_line (str);
+}
+
+static void
+do_t_nop (str)
+ char * str;
+{
+ /* Do nothing */
+ end_of_line (str);
+ return;
+}
+
+/* Handle the Format 4 instructions that do not have equivalents in other
+ formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
+ BIC and MVN. */
+static void
+do_t_arit (str)
+ char * str;
+{
+ int Rd, Rs, Rn;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (skip_past_comma (&str) == FAIL
+ || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (skip_past_comma (&str) != FAIL)
+ {
+ /* Three operand format not allowed for TST, CMN, NEG and MVN.
+ (It isn't allowed for CMP either, but that isn't handled by this
+ function.) */
+ if (inst.instruction == T_OPCODE_TST
+ || inst.instruction == T_OPCODE_CMN
+ || inst.instruction == T_OPCODE_NEG
+ || inst.instruction == T_OPCODE_MVN)
+ {
+ inst.error = bad_args;
+ return;
+ }
+
+ if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (Rs != Rd)
+ {
+ inst.error = _("dest and source1 one must be the same register");
+ return;
+ }
+ Rs = Rn;
+ }
+
+ if (inst.instruction == T_OPCODE_MUL
+ && Rs == Rd)
+ as_tsktsk (_("Rs and Rd must be different in MUL"));
+
+ inst.instruction |= Rd | (Rs << 3);
+ end_of_line (str);
+}
+
+static void
+do_t_add (str)
+ char * str;
+{
+ thumb_add_sub (str, 0);
+}
+
+static void
+do_t_asr (str)
+ char * str;
+{
+ thumb_shift (str, THUMB_ASR);
+}
+
+static void
+do_t_branch9 (str)
+ char * str;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
+ inst.reloc.pc_rel = 1;
+ end_of_line (str);
+}
+
+static void
+do_t_branch12 (str)
+ char * str;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
+ inst.reloc.pc_rel = 1;
+ end_of_line (str);
+}
+
+/* Find the real, Thumb encoded start of a Thumb function. */
+
+static symbolS *
+find_real_start (symbolP)
+ symbolS * symbolP;
+{
+ char * real_start;
+ const char * name = S_GET_NAME (symbolP);
+ symbolS * new_target;
+
+ /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
+#define STUB_NAME ".real_start_of"
+
+ if (name == NULL)
+ abort();
+
+ /* Names that start with '.' are local labels, not function entry points.
+ The compiler may generate BL instructions to these labels because it
+ needs to perform a branch to a far away location. */
+ if (name[0] == '.')
+ return symbolP;
+
+ real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
+ sprintf (real_start, "%s%s", STUB_NAME, name);
+
+ new_target = symbol_find (real_start);
+
+ if (new_target == NULL)
+ {
+ as_warn ("Failed to find real start of function: %s\n", name);
+ new_target = symbolP;
+ }
+
+ free (real_start);
+
+ return new_target;
+}
+
+
+static void
+do_t_branch23 (str)
+ char * str;
+{
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+ inst.reloc.pc_rel = 1;
+ end_of_line (str);
+
+ /* If the destination of the branch is a defined symbol which does not have
+ the THUMB_FUNC attribute, then we must be calling a function which has
+ the (interfacearm) attribute. We look for the Thumb entry point to that
+ function and change the branch to refer to that function instead. */
+ if ( inst.reloc.exp.X_op == O_symbol
+ && inst.reloc.exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
+ && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
+ inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
+}
+
+static void
+do_t_bx (str)
+ char * str;
+{
+ int reg;
+
+ while (*str == ' ')
+ str++;
+
+ if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+ return;
+
+ /* This sets THUMB_H2 from the top bit of reg. */
+ inst.instruction |= reg << 3;
+
+ /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
+ should cause the alignment to be checked once it is known. This is
+ because BX PC only works if the instruction is word aligned. */
+
+ end_of_line (str);
+}
+
+static void
+do_t_compare (str)
+ char * str;
+{
+ thumb_mov_compare (str, THUMB_COMPARE);
+}
+
+static void
+do_t_ldmstm (str)
+ char * str;
+{
+ int Rb;
+ long range;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
+ return;
+
+ if (*str != '!')
+ as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
+ else
+ str++;
+
+ if (skip_past_comma (&str) == FAIL
+ || (range = reg_list (&str)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (inst.reloc.type != BFD_RELOC_NONE)
+ {
+ /* This really doesn't seem worth it. */
+ inst.reloc.type = BFD_RELOC_NONE;
+ inst.error = _("Expression too complex");
+ return;
+ }
+
+ if (range & ~0xff)
+ {
+ inst.error = _("only lo-regs valid in load/store multiple");
+ return;
+ }
+
+ inst.instruction |= (Rb << 8) | range;
+ end_of_line (str);
+}
+
+static void
+do_t_ldr (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
+}
+
+static void
+do_t_ldrb (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
+}
+
+static void
+do_t_ldrh (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
+}
+
+static void
+do_t_lds (str)
+ char * str;
+{
+ int Rd, Rb, Ro;
+
+ while (*str == ' ')
+ str++;
+
+ if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || *str++ != '['
+ || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || skip_past_comma (&str) == FAIL
+ || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
+ || *str++ != ']')
+ {
+ if (! inst.error)
+ inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
+ return;
+ }
+
+ inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
+ end_of_line (str);
+}
+
+static void
+do_t_lsl (str)
+ char * str;
+{
+ thumb_shift (str, THUMB_LSL);
+}
+
+static void
+do_t_lsr (str)
+ char * str;
+{
+ thumb_shift (str, THUMB_LSR);
+}
+
+static void
+do_t_mov (str)
+ char * str;
+{
+ thumb_mov_compare (str, THUMB_MOVE);
+}
+
+static void
+do_t_push_pop (str)
+ char * str;
+{
+ long range;
+
+ while (*str == ' ')
+ str++;
+
+ if ((range = reg_list (&str)) == FAIL)
+ {
+ if (! inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ if (inst.reloc.type != BFD_RELOC_NONE)
+ {
+ /* This really doesn't seem worth it. */
+ inst.reloc.type = BFD_RELOC_NONE;
+ inst.error = _("Expression too complex");
+ return;
+ }
+
+ if (range & ~0xff)
+ {
+ if ((inst.instruction == T_OPCODE_PUSH
+ && (range & ~0xff) == 1 << REG_LR)
+ || (inst.instruction == T_OPCODE_POP
+ && (range & ~0xff) == 1 << REG_PC))
+ {
+ inst.instruction |= THUMB_PP_PC_LR;
+ range &= 0xff;
+ }
+ else
+ {
+ inst.error = _("invalid register list to push/pop instruction");
+ return;
+ }
+ }
+
+ inst.instruction |= range;
+ end_of_line (str);
+}
+
+static void
+do_t_str (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_STORE, THUMB_WORD);
+}
+
+static void
+do_t_strb (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
+}
+
+static void
+do_t_strh (str)
+ char * str;
+{
+ thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
+}
+
+static void
+do_t_sub (str)
+ char * str;
+{
+ thumb_add_sub (str, 1);
+}
+
+static void
+do_t_swi (str)
+ char * str;
+{
+ while (*str == ' ')
+ str++;
+
+ if (my_get_expression (&inst.reloc.exp, &str))
+ return;
+
+ inst.reloc.type = BFD_RELOC_ARM_SWI;
+ end_of_line (str);
+ return;
+}
+
+static void
+do_t_adr (str)
+ char * str;
+{
+ /* This is a pseudo-op of the form "adr rd, label" to be converted
+ into a relative address of the form "add rd, pc, #label-.-4" */
+ while (*str == ' ')
+ str++;
+
+ if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */
+ || skip_past_comma (&str) == FAIL
+ || my_get_expression (&inst.reloc.exp, &str))
+ {
+ if (!inst.error)
+ inst.error = bad_args;
+ return;
+ }
+
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
+ inst.reloc.pc_rel = 1;
+ inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
+ end_of_line (str);
+}
+
+static void
+insert_reg (entry)
+ int entry;
+{
+ int len = strlen (reg_table[entry].name) + 2;
+ char * buf = (char *) xmalloc (len);
+ char * buf2 = (char *) xmalloc (len);
+ int i = 0;
+
+#ifdef REGISTER_PREFIX
+ buf[i++] = REGISTER_PREFIX;
+#endif
+
+ strcpy (buf + i, reg_table[entry].name);
+
+ for (i = 0; buf[i]; i++)
+ buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
+
+ buf2[i] = '\0';
+
+ hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
+ hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
+}
+
+static void
+insert_reg_alias (str, regnum)
+ char *str;
+ int regnum;
+{
+ struct reg_entry *new =
+ (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
+ char *name = xmalloc (strlen (str) + 1);
+ strcpy (name, str);
+
+ new->name = name;
+ new->number = regnum;
+
+ hash_insert (arm_reg_hsh, name, (PTR) new);
+}
+
+static void
+set_constant_flonums ()
+{
+ int i;
+
+ for (i = 0; i < NUM_FLOAT_VALS; i++)
+ if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
+ abort ();
+}
+
+void
+md_begin ()
+{
+ int i;
+
+ if ( (arm_ops_hsh = hash_new ()) == NULL
+ || (arm_tops_hsh = hash_new ()) == NULL
+ || (arm_cond_hsh = hash_new ()) == NULL
+ || (arm_shift_hsh = hash_new ()) == NULL
+ || (arm_reg_hsh = hash_new ()) == NULL
+ || (arm_psr_hsh = hash_new ()) == NULL)
+ as_fatal (_("Virtual memory exhausted"));
+
+ for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
+ hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
+ for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
+ hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
+ for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
+ hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
+ for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
+ hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
+ for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
+ hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
+
+ for (i = 0; reg_table[i].name; i++)
+ insert_reg (i);
+
+ set_constant_flonums ();
+
+#if defined OBJ_COFF || defined OBJ_ELF
+ {
+ unsigned int flags = 0;
+
+ /* Set the flags in the private structure */
+ if (uses_apcs_26) flags |= F_APCS26;
+ if (support_interwork) flags |= F_INTERWORK;
+ if (uses_apcs_float) flags |= F_APCS_FLOAT;
+ if (pic_code) flags |= F_PIC;
+
+ bfd_set_private_flags (stdoutput, flags);
+ }
+#endif
+
+ {
+ unsigned mach;
+
+ /* Record the CPU type as well */
+ switch (cpu_variant & ARM_CPU_MASK)
+ {
+ case ARM_2:
+ mach = bfd_mach_arm_2;
+ break;
+
+ case ARM_3: /* also ARM_250 */
+ mach = bfd_mach_arm_2a;
+ break;
+
+ default:
+ case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
+ mach = bfd_mach_arm_4;
+ break;
+
+ case ARM_7: /* also ARM_6 */
+ mach = bfd_mach_arm_3;
+ break;
+ }
+
+ /* Catch special cases */
+ if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
+ {
+ if (cpu_variant & ARM_THUMB)
+ mach = bfd_mach_arm_4T;
+ else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
+ mach = bfd_mach_arm_4;
+ else if (cpu_variant & ARM_LONGMUL)
+ mach = bfd_mach_arm_3M;
+ }
+
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
+ }
+}
+
+/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
+ for use in the a.out file, and stores them in the array pointed to by buf.
+ This knows about the endian-ness of the target machine and does
+ THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
+ 2 (short) and 4 (long) Floating numbers are put out as a series of
+ LITTLENUMS (shorts, here at least)
+ */
+void
+md_number_to_chars (buf, val, n)
+ char * buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+static valueT
+md_chars_to_number (buf, n)
+ char * buf;
+ int n;
+{
+ valueT result = 0;
+ unsigned char * where = (unsigned char *) buf;
+
+ if (target_big_endian)
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (*where++ & 255);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (where[n] & 255);
+ }
+ }
+
+ return result;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type TYPE, and store the appropriate bytes in *litP. The number
+ of LITTLENUMS emitted is stored in *sizeP . An error message is
+ returned, or NULL on OK.
+
+ Note that fp constants aren't represent in the normal way on the ARM.
+ In big endian mode, things are as expected. However, in little endian
+ mode fp constants are big-endian word-wise, and little-endian byte-wise
+ within the words. For example, (double) 1.1 in big endian mode is
+ the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
+ the byte sequence 99 99 f1 3f 9a 99 99 99.
+
+ ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char * litP;
+ int * sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * 2;
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+ else
+ {
+ /* For a 4 byte float the order of elements in `words' is 1 0. For an
+ 8 byte float the order is 1 0 3 2. */
+ for (i = 0; i < prec; i += 2)
+ {
+ md_number_to_chars (litP, (valueT) words[i + 1], 2);
+ md_number_to_chars (litP + 2, (valueT) words[i], 2);
+ litP += 4;
+ }
+ }
+
+ return 0;
+}
+
+/* The knowledge of the PC's pipeline offset is built into the relocs
+ for the ELF port and into the insns themselves for the COFF port. */
+long
+md_pcrel_from (fixP)
+ fixS * fixP;
+{
+ if ( fixP->fx_addsy
+ && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
+ && fixP->fx_subsy == NULL)
+ return 0;
+
+ if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
+ {
+ /* PC relative addressing on the Thumb is slightly odd
+ as the bottom two bits of the PC are forced to zero
+ for the calculation */
+ return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
+ }
+
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+#ifdef OBJ_ELF
+ /* Don't align the dwarf2 debug sections */
+ if (!strncmp (segment->name, ".debug", 5))
+ return size;
+#endif
+ /* Round all sects to multiple of 4 */
+ return (size + 3) & ~3;
+}
+
+/* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
+ we have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char * name;
+{
+#ifdef OBJ_ELF
+ if (name[0] == '_' && name[1] == 'G'
+ && streq (name, GLOBAL_OFFSET_TABLE_NAME))
+ {
+ if (!GOT_symbol)
+ {
+ if (symbol_find (name))
+ as_bad ("GOT already in the symbol table");
+
+ GOT_symbol = symbol_new (name, undefined_section,
+ (valueT)0, & zero_address_frag);
+ }
+
+ return GOT_symbol;
+ }
+#endif
+
+ return 0;
+}
+
+/* arm_reg_parse () := if it looks like a register, return its token and
+ advance the pointer. */
+
+static int
+arm_reg_parse (ccp)
+ register char ** ccp;
+{
+ char * start = * ccp;
+ char c;
+ char * p;
+ struct reg_entry * reg;
+
+#ifdef REGISTER_PREFIX
+ if (*start != REGISTER_PREFIX)
+ return FAIL;
+ p = start + 1;
+#else
+ p = start;
+#ifdef OPTIONAL_REGISTER_PREFIX
+ if (*p == OPTIONAL_REGISTER_PREFIX)
+ p++, start++;
+#endif
+#endif
+ if (!isalpha (*p) || !is_name_beginner (*p))
+ return FAIL;
+
+ c = *p++;
+ while (isalpha (c) || isdigit (c) || c == '_')
+ c = *p++;
+
+ *--p = 0;
+ reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
+ *p = c;
+
+ if (reg)
+ {
+ *ccp = p;
+ return reg->number;
+ }
+
+ return FAIL;
+}
+
+static int
+arm_psr_parse (ccp)
+ register char ** ccp;
+{
+ char * start = * ccp;
+ char c;
+ char * p;
+ CONST struct asm_psr * psr;
+
+ p = start;
+ c = *p++;
+ while (isalpha (c) || c == '_')
+ c = *p++;
+
+ *--p = 0;
+ psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
+ *p = c;
+
+ if (psr)
+ {
+ *ccp = p;
+ return psr->number;
+ }
+
+ return FAIL;
+}
+
+int
+md_apply_fix3 (fixP, val, seg)
+ fixS * fixP;
+ valueT * val;
+ segT seg;
+{
+ offsetT value = * val;
+ offsetT newval;
+ unsigned int newimm;
+ unsigned long temp;
+ int sign;
+ char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
+
+ assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+
+ /* Note whether this will delete the relocation. */
+#if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
+ if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant)
+ && !fixP->fx_pcrel)
+#else
+ if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
+#endif
+ fixP->fx_done = 1;
+
+ /* If this symbol is in a different section then we need to leave it for
+ the linker to deal with. Unfortunately, md_pcrel_from can't tell,
+ so we have to undo it's effects here. */
+ if (fixP->fx_pcrel)
+ {
+ if (fixP->fx_addsy != NULL
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ {
+ if (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
+ value = 0;
+ else
+ value += md_pcrel_from (fixP);
+ }
+ }
+
+ fixP->fx_addnumber = value; /* Remember value for emit_reloc */
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_ARM_IMMEDIATE:
+ newimm = validate_immediate (value);
+ temp = md_chars_to_number (buf, INSN_SIZE);
+
+ /* If the instruction will fail, see if we can fix things up by
+ changing the opcode. */
+ if (newimm == (unsigned int) FAIL
+ && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid constant (%x) after fixup\n"), value);
+ break;
+ }
+
+ newimm |= (temp & 0xfffff000);
+ md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_OFFSET_IMM:
+ sign = value >= 0;
+ if ((value = validate_offset_imm (value, 0)) == FAIL)
+ {
+ as_bad (_("bad immediate value for offset (%d)"), val);
+ break;
+ }
+ if (value < 0)
+ value = -value;
+
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ newval &= 0xff7ff000;
+ newval |= value | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_OFFSET_IMM8:
+ case BFD_RELOC_ARM_HWLITERAL:
+ sign = value >= 0;
+ if ((value = validate_offset_imm (value, 1)) == FAIL)
+ {
+ if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid literal constant: pool needs to be closer\n"));
+ else
+ as_bad (_("bad immediate value for offset (%d)"), value);
+ break;
+ }
+
+ if (value < 0)
+ value = -value;
+
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ newval &= 0xff7ff0f0;
+ newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_LITERAL:
+ sign = value >= 0;
+ if (value < 0)
+ value = -value;
+
+ if ((value = validate_offset_imm (value, 0)) == FAIL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid literal constant: pool needs to be closer\n"));
+ break;
+ }
+
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ newval &= 0xff7ff000;
+ newval |= value | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_SHIFT_IMM:
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ if (((unsigned long) value) > 32
+ || (value == 32
+ && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("shift expression is too large"));
+ break;
+ }
+
+ if (value == 0)
+ newval &= ~0x60; /* Shifts of zero must be done as lsl */
+ else if (value == 32)
+ value = 0;
+ newval &= 0xfffff07f;
+ newval |= (value & 0x1f) << 7;
+ md_number_to_chars (buf, newval , INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_SWI:
+ if (arm_data->thumb_mode)
+ {
+ if (((unsigned long) value) > 0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid swi expression"));
+ newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
+ newval |= value;
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ }
+ else
+ {
+ if (((unsigned long) value) > 0x00ffffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid swi expression"));
+ newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
+ newval |= value;
+ md_number_to_chars (buf, newval , INSN_SIZE);
+ }
+ break;
+
+ case BFD_RELOC_ARM_MULTI:
+ if (((unsigned long) value) > 0xffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid expression in load/store multiple"));
+ newval = value | md_chars_to_number (buf, INSN_SIZE);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_PCREL_BRANCH:
+ newval = md_chars_to_number (buf, INSN_SIZE);
+#ifdef OBJ_ELF
+ newval &= 0xff000000;
+ if (! target_oabi)
+ value = fixP->fx_offset;
+ else
+#else
+ value = (value >> 2) & 0x00ffffff;
+#endif
+ value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
+ newval = value | (newval & 0xff000000);
+ md_number_to_chars (buf, newval, INSN_SIZE);
+ break;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ {
+ addressT diff = (newval & 0xff) << 1;
+ if (diff & 0x100)
+ diff |= ~0xff;
+
+ value += diff;
+ if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch out of range"));
+ newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ {
+ addressT diff = (newval & 0x7ff) << 1;
+ if (diff & 0x800)
+ diff |= ~0x7ff;
+
+ value += diff;
+ if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch out of range"));
+ newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_THUMB_PCREL_BRANCH23:
+ {
+ offsetT newval2;
+ addressT diff;
+
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+ diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
+ if (diff & 0x400000)
+ diff |= ~0x3fffff;
+ value += diff;
+ if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch with link out of range"));
+
+ newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
+ newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+ }
+ break;
+
+ case BFD_RELOC_8:
+ if (fixP->fx_done || fixP->fx_pcrel)
+ md_number_to_chars (buf, value, 1);
+#ifdef OBJ_ELF
+ else if (!target_oabi)
+ {
+ value = fixP->fx_offset;
+ md_number_to_chars (buf, value, 1);
+ }
+#endif
+ break;
+
+ case BFD_RELOC_16:
+ if (fixP->fx_done || fixP->fx_pcrel)
+ md_number_to_chars (buf, value, 2);
+#ifdef OBJ_ELF
+ else if (!target_oabi)
+ {
+ value = fixP->fx_offset;
+ md_number_to_chars (buf, value, 2);
+ }
+#endif
+ break;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_GOT32:
+ case BFD_RELOC_ARM_GOTOFF:
+ md_number_to_chars (buf, 0, 4);
+ break;
+#endif
+
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_32:
+ if (fixP->fx_done || fixP->fx_pcrel)
+ md_number_to_chars (buf, value, 4);
+#ifdef OBJ_ELF
+ else if (!target_oabi)
+ {
+ value = fixP->fx_offset;
+ md_number_to_chars (buf, value, 4);
+ }
+#endif
+ break;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_PLT32:
+ /* It appears the instruction is fully prepared at this point. */
+ break;
+#endif
+
+ case BFD_RELOC_ARM_GOTPC:
+ md_number_to_chars (buf, value, 4);
+ break;
+
+ case BFD_RELOC_ARM_CP_OFF_IMM:
+ sign = value >= 0;
+ if (value < -1023 || value > 1023 || (value & 3))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Illegal value for co-processor offset"));
+ if (value < 0)
+ value = -value;
+ newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
+ newval |= (value >> 2) | (sign ? INDEX_UP : 0);
+ md_number_to_chars (buf, newval , INSN_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_OFFSET:
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ /* Exactly what ranges, and where the offset is inserted depends on
+ the type of instruction, we can establish this from the top 4 bits */
+ switch (newval >> 12)
+ {
+ case 4: /* PC load */
+ /* Thumb PC loads are somewhat odd, bit 1 of the PC is
+ forced to zero for these loads, so we will need to round
+ up the offset if the instruction address is not word
+ aligned (since the final address produced must be, and
+ we can only describe word-aligned immediate offsets). */
+
+ if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid offset, target not word aligned (0x%08X)"),
+ (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
+
+ if ((value + 2) & ~0x3fe)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid offset"));
+
+ /* Round up, since pc will be rounded down. */
+ newval |= (value + 2) >> 2;
+ break;
+
+ case 9: /* SP load/store */
+ if (value & ~0x3fc)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid offset"));
+ newval |= value >> 2;
+ break;
+
+ case 6: /* Word load/store */
+ if (value & ~0x7c)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid offset"));
+ newval |= value << 4; /* 6 - 2 */
+ break;
+
+ case 7: /* Byte load/store */
+ if (value & ~0x1f)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid offset"));
+ newval |= value << 6;
+ break;
+
+ case 8: /* Halfword load/store */
+ if (value & ~0x3e)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid offset"));
+ newval |= value << 5; /* 6 - 1 */
+ break;
+
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ "Unable to process relocation for thumb opcode: %x", newval);
+ break;
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_ADD:
+ /* This is a complicated relocation, since we use it for all of
+ the following immediate relocations:
+ 3bit ADD/SUB
+ 8bit ADD/SUB
+ 9bit ADD/SUB SP word-aligned
+ 10bit ADD PC/SP word-aligned
+
+ The type of instruction being processed is encoded in the
+ instruction field:
+ 0x8000 SUB
+ 0x00F0 Rd
+ 0x000F Rs
+ */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ {
+ int rd = (newval >> 4) & 0xf;
+ int rs = newval & 0xf;
+ int subtract = newval & 0x8000;
+
+ if (rd == REG_SP)
+ {
+ if (value & ~0x1fc)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid immediate for stack address calculation"));
+ newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
+ newval |= value >> 2;
+ }
+ else if (rs == REG_PC || rs == REG_SP)
+ {
+ if (subtract ||
+ value & ~0x3fc)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid immediate for address calculation (value = 0x%08X)"), value);
+ newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
+ newval |= rd << 8;
+ newval |= value >> 2;
+ }
+ else if (rs == rd)
+ {
+ if (value & ~0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid 8bit immediate"));
+ newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
+ newval |= (rd << 8) | value;
+ }
+ else
+ {
+ if (value & ~0x7)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid 3bit immediate"));
+ newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
+ newval |= rd | (rs << 3) | (value << 6);
+ }
+ }
+ md_number_to_chars (buf, newval , THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_IMM:
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ switch (newval >> 11)
+ {
+ case 0x04: /* 8bit immediate MOV */
+ case 0x05: /* 8bit immediate CMP */
+ if (value < 0 || value > 255)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid immediate: %d is too large"), value);
+ newval |= value;
+ break;
+
+ default:
+ abort ();
+ }
+ md_number_to_chars (buf, newval , THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_THUMB_SHIFT:
+ /* 5bit shift value (0..31) */
+ if (value < 0 || value > 31)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Illegal Thumb shift value: %d"), value);
+ newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
+ newval |= value << 6;
+ md_number_to_chars (buf, newval , THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return 1;
+
+ case BFD_RELOC_NONE:
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Bad relocation fixup type (%d)\n"), fixP->fx_r_type);
+ }
+
+ return 1;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+arelent *
+tc_gen_reloc (section, fixp)
+ asection * section;
+ fixS * fixp;
+{
+ arelent * reloc;
+ bfd_reloc_code_real_type code;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ /* @@ Why fx_addnumber sometimes and fx_offset other times? */
+#ifndef OBJ_ELF
+ if (fixp->fx_pcrel == 0)
+ reloc->addend = fixp->fx_offset;
+ else
+ reloc->addend = fixp->fx_offset = reloc->address;
+#else /* OBJ_ELF */
+ reloc->addend = fixp->fx_offset;
+#endif
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ if (fixp->fx_pcrel)
+ {
+ code = BFD_RELOC_8_PCREL;
+ break;
+ }
+
+ case BFD_RELOC_16:
+ if (fixp->fx_pcrel)
+ {
+ code = BFD_RELOC_16_PCREL;
+ break;
+ }
+
+ case BFD_RELOC_32:
+ if (fixp->fx_pcrel)
+ {
+ code = BFD_RELOC_32_PCREL;
+ break;
+ }
+
+ case BFD_RELOC_ARM_PCREL_BRANCH:
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_THUMB_PCREL_BRANCH9:
+ case BFD_RELOC_THUMB_PCREL_BRANCH12:
+ case BFD_RELOC_THUMB_PCREL_BRANCH23:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ code = fixp->fx_r_type;
+ break;
+
+ case BFD_RELOC_ARM_LITERAL:
+ case BFD_RELOC_ARM_HWLITERAL:
+ /* If this is called then the a literal has been referenced across
+ a section boundry - possibly due to an implicit dump */
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Literal referenced across section boundry (Implicit dump?)"));
+ return NULL;
+
+ case BFD_RELOC_ARM_GOTPC:
+ assert (fixp->fx_pcrel != 0);
+ code = fixp->fx_r_type;
+ code = BFD_RELOC_32_PCREL;
+ break;
+
+#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_GOT32:
+ case BFD_RELOC_ARM_GOTOFF:
+ case BFD_RELOC_ARM_PLT32:
+ code = fixp->fx_r_type;
+ break;
+#endif
+
+ case BFD_RELOC_ARM_IMMEDIATE:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
+ fixp->fx_r_type);
+ return NULL;
+
+ case BFD_RELOC_ARM_OFFSET_IMM:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
+ fixp->fx_r_type);
+ return NULL;
+
+ default:
+ {
+ char * type;
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
+ case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
+ case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
+ case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
+ case BFD_RELOC_ARM_SWI: type = "SWI"; break;
+ case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
+ case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
+ case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
+ case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
+ case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
+ case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
+ default: type = "<unknown>"; break;
+ }
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Can not represent %s relocation in this object file format (%d)"),
+ type, fixp->fx_pcrel);
+ return NULL;
+ }
+ }
+
+#ifdef OBJ_ELF
+ if (code == BFD_RELOC_32_PCREL
+ && GOT_symbol
+ && fixp->fx_addsy == GOT_symbol)
+ code = BFD_RELOC_ARM_GOTPC;
+#endif
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Can not represent %s relocation in this object file format"),
+ bfd_get_reloc_code_name (code));
+ return NULL;
+ }
+
+ return reloc;
+}
+
+int
+md_estimate_size_before_relax (fragP, segtype)
+ fragS * fragP;
+ segT segtype;
+{
+ as_fatal (_("md_estimate_size_before_relax\n"));
+ return 1;
+}
+
+static void
+output_inst (str)
+ char * str;
+{
+ char * to = NULL;
+
+ if (inst.error)
+ {
+ as_bad (inst.error);
+ return;
+ }
+
+ to = frag_more (inst.size);
+ if (thumb_mode && (inst.size > THUMB_SIZE))
+ {
+ assert (inst.size == (2 * THUMB_SIZE));
+ md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
+ md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
+ }
+ else
+ md_number_to_chars (to, inst.instruction, inst.size);
+
+ if (inst.reloc.type != BFD_RELOC_NONE)
+ fix_new_arm (frag_now, to - frag_now->fr_literal,
+ inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
+ inst.reloc.type);
+
+ return;
+}
+
+void
+md_assemble (str)
+ char * str;
+{
+ char c;
+ char * p;
+ char * q;
+ char * start;
+
+ /* Align the instruction.
+ This may not be the right thing to do but ... */
+ /* arm_align (2, 0); */
+ listing_prev_line (); /* Defined in listing.h */
+
+ /* Align the previous label if needed. */
+ if (last_label_seen != NULL)
+ {
+ last_label_seen->sy_frag = frag_now;
+ S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
+ S_SET_SEGMENT (last_label_seen, now_seg);
+ }
+
+ memset (&inst, '\0', sizeof (inst));
+ inst.reloc.type = BFD_RELOC_NONE;
+
+ if (*str == ' ')
+ str++; /* Skip leading white space */
+
+ /* Scan up to the end of the op-code, which must end in white space or
+ end of string. */
+ for (start = p = str; *p != '\0'; p++)
+ if (*p == ' ')
+ break;
+
+ if (p == str)
+ {
+ as_bad (_("No operator -- statement `%s'\n"), str);
+ return;
+ }
+
+ if (thumb_mode)
+ {
+ CONST struct thumb_opcode *opcode;
+
+ c = *p;
+ *p = '\0';
+ opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
+ *p = c;
+ if (opcode)
+ {
+ inst.instruction = opcode->value;
+ inst.size = opcode->size;
+ (*opcode->parms)(p);
+ output_inst (start);
+ return;
+ }
+ }
+ else
+ {
+ CONST struct asm_opcode *opcode;
+
+ inst.size = INSN_SIZE;
+ /* p now points to the end of the opcode, probably white space, but we
+ have to break the opcode up in case it contains condionals and flags;
+ keep trying with progressively smaller basic instructions until one
+ matches, or we run out of opcode. */
+ q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
+ for (; q != str; q--)
+ {
+ c = *q;
+ *q = '\0';
+ opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
+ *q = c;
+ if (opcode && opcode->template)
+ {
+ unsigned long flag_bits = 0;
+ char *r;
+
+ /* Check that this instruction is supported for this CPU */
+ if ((opcode->variants & cpu_variant) == 0)
+ goto try_shorter;
+
+ inst.instruction = opcode->value;
+ if (q == p) /* Just a simple opcode */
+ {
+ if (opcode->comp_suffix != 0)
+ as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
+ opcode->comp_suffix);
+ else
+ {
+ inst.instruction |= COND_ALWAYS;
+ (*opcode->parms)(q, 0);
+ }
+ output_inst (start);
+ return;
+ }
+
+ /* Now check for a conditional */
+ r = q;
+ if (p - r >= 2)
+ {
+ CONST struct asm_cond *cond;
+ char d = *(r + 2);
+
+ *(r + 2) = '\0';
+ cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
+ *(r + 2) = d;
+ if (cond)
+ {
+ if (cond->value == 0xf0000000)
+ as_tsktsk (
+_("Warning: Use of the 'nv' conditional is deprecated\n"));
+
+ inst.instruction |= cond->value;
+ r += 2;
+ }
+ else
+ inst.instruction |= COND_ALWAYS;
+ }
+ else
+ inst.instruction |= COND_ALWAYS;
+
+ /* if there is a compulsory suffix, it should come here, before
+ any optional flags. */
+ if (opcode->comp_suffix)
+ {
+ CONST char *s = opcode->comp_suffix;
+
+ while (*s)
+ {
+ inst.suffix++;
+ if (*r == *s)
+ break;
+ s++;
+ }
+
+ if (*s == '\0')
+ {
+ as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
+ opcode->comp_suffix);
+ return;
+ }
+
+ r++;
+ }
+
+ /* The remainder, if any should now be flags for the instruction;
+ Scan these checking each one found with the opcode. */
+ if (r != p)
+ {
+ char d;
+ CONST struct asm_flg *flag = opcode->flags;
+
+ if (flag)
+ {
+ int flagno;
+
+ d = *p;
+ *p = '\0';
+
+ for (flagno = 0; flag[flagno].template; flagno++)
+ {
+ if (streq (r, flag[flagno].template))
+ {
+ flag_bits |= flag[flagno].set_bits;
+ break;
+ }
+ }
+
+ *p = d;
+ if (! flag[flagno].template)
+ goto try_shorter;
+ }
+ else
+ goto try_shorter;
+ }
+
+ (*opcode->parms) (p, flag_bits);
+ output_inst (start);
+ return;
+ }
+
+ try_shorter:
+ ;
+ }
+ }
+
+ /* It wasn't an instruction, but it might be a register alias of the form
+ alias .req reg
+ */
+ q = p;
+ while (*q == ' ')
+ q++;
+
+ c = *p;
+ *p = '\0';
+
+ if (*q && !strncmp (q, ".req ", 4))
+ {
+ int reg;
+ char * copy_of_str = str;
+ char * r;
+
+ q += 4;
+ while (*q == ' ')
+ q++;
+
+ for (r = q; *r != '\0'; r++)
+ if (*r == ' ')
+ break;
+
+ if (r != q)
+ {
+ int regnum;
+ char d = *r;
+
+ *r = '\0';
+ regnum = arm_reg_parse (& q);
+ *r = d;
+
+ reg = arm_reg_parse (& str);
+
+ if (reg == FAIL)
+ {
+ if (regnum != FAIL)
+ {
+ insert_reg_alias (str, regnum);
+ }
+ else
+ {
+ as_warn (_("register '%s' does not exist\n"), q);
+ }
+ }
+ else if (regnum != FAIL)
+ {
+ if (reg != regnum)
+ as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
+
+ /* Do not warn abpout redefinitions to the same alias. */
+ }
+ else
+ as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
+ copy_of_str, q);
+ }
+ else
+ as_warn (_("ignoring incomplete .req pseuso op"));
+
+ *p = c;
+ return;
+ }
+
+ *p = c;
+ as_bad (_("bad instruction `%s'"), start);
+}
+
+/*
+ * md_parse_option
+ * Invocation line includes a switch not recognized by the base assembler.
+ * See if it's a processor-specific option. These are:
+ * Cpu variants, the arm part is optional:
+ * -m[arm]1 Currently not supported.
+ * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
+ * -m[arm]3 Arm 3 processor
+ * -m[arm]6[xx], Arm 6 processors
+ * -m[arm]7[xx][t][[d]m] Arm 7 processors
+ * -mstrongarm[110] Arm 8 processors
+ * -mall All (except the ARM1)
+ * FP variants:
+ * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
+ * -mfpe-old (No float load/store multiples)
+ * -mno-fpu Disable all floating point instructions
+ * Run-time endian selection:
+ * -EB big endian cpu
+ * -EL little endian cpu
+ * ARM Procedure Calling Standard:
+ * -mapcs-32 32 bit APCS
+ * -mapcs-26 26 bit APCS
+ * -mapcs-float Pass floats in float regs
+ * -mapcs-reentrant Position independent code
+ * -mthumb-interwork Code supports Arm/Thumb interworking
+ * -moabi Old ELF ABI
+ */
+
+CONST char * md_shortopts = "m:k";
+struct option md_longopts[] =
+{
+#ifdef ARM_BI_ENDIAN
+#define OPTION_EB (OPTION_MD_BASE + 0)
+ {"EB", no_argument, NULL, OPTION_EB},
+#define OPTION_EL (OPTION_MD_BASE + 1)
+ {"EL", no_argument, NULL, OPTION_EL},
+#ifdef OBJ_ELF
+#define OPTION_OABI (OPTION_MD_BASE +2)
+ {"oabi", no_argument, NULL, OPTION_OABI},
+#endif
+#endif
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ char * str = arg;
+
+ switch (c)
+ {
+#ifdef ARM_BI_ENDIAN
+ case OPTION_EB:
+ target_big_endian = 1;
+ break;
+ case OPTION_EL:
+ target_big_endian = 0;
+ break;
+#endif
+
+ case 'm':
+ switch (*str)
+ {
+ case 'f':
+ if (streq (str, "fpa10"))
+ cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
+ else if (streq (str, "fpa11"))
+ cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
+ else if (streq (str, "fpe-old"))
+ cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
+ else
+ goto bad;
+ break;
+
+ case 'n':
+ if (streq (str, "no-fpu"))
+ cpu_variant &= ~FPU_ALL;
+ break;
+
+#ifdef OBJ_ELF
+ case 'o':
+ if (streq (str, "oabi"))
+ target_oabi = true;
+ break;
+#endif
+
+ case 't':
+ /* Limit assembler to generating only Thumb instructions: */
+ if (streq (str, "thumb"))
+ {
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
+ cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
+ thumb_mode = 1;
+ }
+ else if (streq (str, "thumb-interwork"))
+ {
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4;
+#if defined OBJ_COFF || defined OBJ_ELF
+ support_interwork = true;
+#endif
+ }
+ else
+ goto bad;
+ break;
+
+ default:
+ if (streq (str, "all"))
+ {
+ cpu_variant = ARM_ALL | FPU_ALL;
+ return 1;
+ }
+#if defined OBJ_COFF || defined OBJ_ELF
+ if (! strncmp (str, "apcs-", 5))
+ {
+ /* GCC passes on all command line options starting "-mapcs-..."
+ to us, so we must parse them here. */
+
+ str += 5;
+
+ if (streq (str, "32"))
+ {
+ uses_apcs_26 = false;
+ return 1;
+ }
+ else if (streq (str, "26"))
+ {
+ uses_apcs_26 = true;
+ return 1;
+ }
+ else if (streq (str, "frame"))
+ {
+ /* Stack frames are being generated - does not affect
+ linkage of code. */
+ return 1;
+ }
+ else if (streq (str, "stack-check"))
+ {
+ /* Stack checking is being performed - does not affect
+ linkage, but does require that the functions
+ __rt_stkovf_split_small and __rt_stkovf_split_big be
+ present in the final link. */
+
+ return 1;
+ }
+ else if (streq (str, "float"))
+ {
+ /* Floating point arguments are being passed in the floating
+ point registers. This does affect linking, since this
+ version of the APCS is incompatible with the version that
+ passes floating points in the integer registers. */
+
+ uses_apcs_float = true;
+ return 1;
+ }
+ else if (streq (str, "reentrant"))
+ {
+ /* Reentrant code has been generated. This does affect
+ linking, since there is no point in linking reentrant/
+ position independent code with absolute position code. */
+ pic_code = true;
+ return 1;
+ }
+
+ as_bad (_("Unrecognised APCS switch -m%s"), arg);
+ return 0;
+ }
+#endif
+ /* Strip off optional "arm" */
+ if (! strncmp (str, "arm", 3))
+ str += 3;
+
+ switch (*str)
+ {
+ case '1':
+ if (streq (str, "1"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
+ else
+ goto bad;
+ break;
+
+ case '2':
+ if (streq (str, "2"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
+ else if (streq (str, "250"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
+ else
+ goto bad;
+ break;
+
+ case '3':
+ if (streq (str, "3"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
+ else
+ goto bad;
+ break;
+
+ case '6':
+ switch (strtol (str, NULL, 10))
+ {
+ case 6:
+ case 60:
+ case 600:
+ case 610:
+ case 620:
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
+ break;
+ default:
+ goto bad;
+ }
+ break;
+
+ case '7':
+ switch (strtol (str, & str, 10)) /* Eat the processor name */
+ {
+ case 7:
+ case 70:
+ case 700:
+ case 710:
+ case 7100:
+ case 7500:
+ break;
+ default:
+ goto bad;
+ }
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
+ for (; *str; str++)
+ {
+ switch (* str)
+ {
+ case 't':
+ cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
+ break;
+
+ case 'm':
+ cpu_variant |= ARM_LONGMUL;
+ break;
+
+ case 'f': /* fe => fp enabled cpu. */
+ if (str[1] == 'e')
+ ++ str;
+ else
+ goto bad;
+
+ case 'c': /* Left over from 710c processor name. */
+ case 'd': /* Debug */
+ case 'i': /* Embedded ICE */
+ /* Included for completeness in ARM processor naming. */
+ break;
+
+ default:
+ goto bad;
+ }
+ }
+ break;
+
+ case '8':
+ if (streq (str, "8") || streq (str, "810"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL;
+ else
+ goto bad;
+ break;
+
+ case '9':
+ if (streq (str, "9"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL;
+ else if (streq (str, "9tdmi"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB;
+ else
+ goto bad;
+ break;
+
+ case 's':
+ if (streq (str, "strongarm")
+ || streq (str, "strongarm110")
+ || streq (str, "strongarm1100"))
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL;
+ else
+ goto bad;
+ break;
+
+ case 'v':
+ /* Select variant based on architecture rather than processor */
+ switch (*++str)
+ {
+ case '2':
+ switch (*++str)
+ {
+ case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
+ case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
+ default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
+ }
+ break;
+
+ case '3':
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
+
+ switch (*++str)
+ {
+ case 'm': cpu_variant |= ARM_LONGMUL; break;
+ case 0: break;
+ default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
+ }
+ break;
+
+ case '4':
+ cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4;
+
+ switch (*++str)
+ {
+ case 't': cpu_variant |= ARM_THUMB; break;
+ case 0: break;
+ default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
+ }
+ break;
+
+ default:
+ as_bad (_("Invalid architecture variant -m%s"), arg);
+ break;
+ }
+ break;
+
+ default:
+ bad:
+ as_bad (_("Invalid processor variant -m%s"), arg);
+ return 0;
+ }
+ }
+ break;
+
+ case 'k':
+ pic_code = 1;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (fp)
+ FILE * fp;
+{
+ fprintf (fp,
+_("\
+ ARM Specific Assembler Options:\n\
+ -m[arm][<processor name>] select processor variant\n\
+ -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
+ -mthumb only allow Thumb instructions\n\
+ -mthumb-interwork mark the assembled code as supporting interworking\n\
+ -mall allow any instruction\n\
+ -mfpa10, -mfpa11 select floating point architecture\n\
+ -mfpe-old don't allow floating-point multiple instructions\n\
+ -mno-fpu don't allow any floating-point instructions.\n"));
+ fprintf (fp,
+_("\
+ -k generate PIC code.\n"));
+#if defined OBJ_COFF || defined OBJ_ELF
+ fprintf (fp,
+_("\
+ -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
+ fprintf (fp,
+_("\
+ -mapcs-float floating point args are passed in FP regs\n"));
+ fprintf (fp,
+_("\
+ -mapcs-reentrant the code is position independent/reentrant\n"));
+ #endif
+#ifdef OBJ_ELF
+ fprintf (fp,
+_("\
+ -moabi support the old ELF ABI\n"));
+#endif
+#ifdef ARM_BI_ENDIAN
+ fprintf (fp,
+_("\
+ -EB assemble code for a big endian cpu\n\
+ -EL assemble code for a little endian cpu\n"));
+#endif
+}
+
+/* We need to be able to fix up arbitrary expressions in some statements.
+ This is so that we can handle symbols that are an arbitrary distance from
+ the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
+ which returns part of an address in a form which will be valid for
+ a data instruction. We do this by pushing the expression into a symbol
+ in the expr_section, and creating a fix for that. */
+
+static void
+fix_new_arm (frag, where, size, exp, pc_rel, reloc)
+ fragS * frag;
+ int where;
+ short int size;
+ expressionS * exp;
+ int pc_rel;
+ int reloc;
+{
+ fixS * new_fix;
+ arm_fix_data * arm_data;
+
+ switch (exp->X_op)
+ {
+ case O_constant:
+ case O_symbol:
+ case O_add:
+ case O_subtract:
+ new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
+ break;
+
+ default:
+ new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
+ pc_rel, reloc);
+ break;
+ }
+
+ /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
+ arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
+ new_fix->tc_fix_data = (PTR) arm_data;
+ arm_data->thumb_mode = thumb_mode;
+
+ return;
+}
+
+
+/*
+ * This fix_new is called by cons via TC_CONS_FIX_NEW
+ *
+ * We check the expression to see if it is of the form
+ * __GLOBAL_OFFSET_TABLE + ???
+ * If it is then this is a PC relative reference to the GOT.
+ * i.e.
+ * ldr sl, L1
+ * add sl, pc, sl
+ * L2:
+ * ...
+ * L1:
+ * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
+ *
+ * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
+ * normal BFD_RELOC_{16,32,64}
+ */
+
+void
+cons_fix_new_arm (frag, where, size, exp)
+ fragS * frag;
+ int where;
+ int size;
+ expressionS * exp;
+{
+ bfd_reloc_code_real_type type;
+ int pcrel = 0;
+
+ /* Pick a reloc ...
+ *
+ * @@ Should look at CPU word size.
+ */
+ switch (size)
+ {
+ case 2:
+ type = BFD_RELOC_16;
+ break;
+ case 4:
+ default:
+ type = BFD_RELOC_32;
+ break;
+ case 8:
+ type = BFD_RELOC_64;
+ break;
+ }
+
+ /* Look for possible GOTPC reloc */
+
+ /*
+ * Look for pic assembler and 'undef symbol + expr symbol' expression
+ * and a 32 bit size.
+ */
+
+ fix_new_exp (frag, where, (int) size, exp, pcrel, type);
+}
+
+/* A good place to do this, although this was probably not intended
+ * for this kind of use. We need to dump the literal pool before
+ * references are made to a null symbol pointer. */
+void
+arm_cleanup ()
+{
+ if (current_poolP != NULL)
+ {
+ subseg_set (text_section, 0); /* Put it at the end of text section */
+ s_ltorg (0);
+ listing_prev_line ();
+ }
+}
+
+void
+arm_start_line_hook ()
+{
+ last_label_seen = NULL;
+}
+
+void
+arm_frob_label (sym)
+ symbolS * sym;
+{
+ last_label_seen = sym;
+
+ ARM_SET_THUMB (sym, thumb_mode);
+
+#if defined OBJ_COFF || defined OBJ_ELF
+ ARM_SET_INTERWORK (sym, support_interwork);
+#endif
+
+ if (label_is_thumb_function_name)
+ {
+ /* When the address of a Thumb function is taken the bottom
+ bit of that address should be set. This will allow
+ interworking between Arm and Thumb functions to work
+ correctly. */
+
+ THUMB_SET_FUNC (sym, 1);
+
+ label_is_thumb_function_name = false;
+ }
+}
+
+/* Adjust the symbol table. This marks Thumb symbols as distinct from
+ ARM ones. */
+
+void
+arm_adjust_symtab ()
+{
+#ifdef OBJ_COFF
+ symbolS * sym;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ if (ARM_IS_THUMB (sym))
+ {
+ if (THUMB_IS_FUNC (sym))
+ {
+ /* Mark the symbol as a Thumb function. */
+ if ( S_GET_STORAGE_CLASS (sym) == C_STAT
+ || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
+ S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
+
+ else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
+ S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
+ else
+ as_bad (_("%s: unexpected function type: %d"),
+ S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
+ }
+ else switch (S_GET_STORAGE_CLASS (sym))
+ {
+ case C_EXT:
+ S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
+ break;
+ case C_STAT:
+ S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
+ break;
+ case C_LABEL:
+ S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
+ break;
+ default: /* do nothing */
+ break;
+ }
+ }
+
+ if (ARM_IS_INTERWORK (sym))
+ coffsymbol(sym->bsym)->native->u.syment.n_flags = 0xFF;
+ }
+#endif
+#ifdef OBJ_ELF
+ symbolS * sym;
+ elf_symbol_type * elf_sym;
+ char bind;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ if (ARM_IS_THUMB (sym))
+ {
+ if (THUMB_IS_FUNC (sym))
+ {
+ elf_sym = elf_symbol (sym->bsym);
+ bind = ELF_ST_BIND (elf_sym);
+ elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
+ }
+ }
+ }
+#endif
+}
+
+int
+arm_data_in_code ()
+{
+ if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
+ {
+ *input_line_pointer = '/';
+ input_line_pointer += 5;
+ *input_line_pointer = 0;
+ return 1;
+ }
+
+ return 0;
+}
+
+char *
+arm_canonicalize_symbol_name (name)
+ char * name;
+{
+ int len;
+
+ if (thumb_mode && (len = strlen (name)) > 5
+ && streq (name + len - 5, "/data"))
+ {
+ *(name + len - 5) = 0;
+ }
+
+ return name;
+}
+
+boolean
+arm_validate_fix (fixP)
+ fixS * fixP;
+{
+ /* If the destination of the branch is a defined symbol which does not have
+ the THUMB_FUNC attribute, then we must be calling a function which has
+ the (interfacearm) attribute. We look for the Thumb entry point to that
+ function and change the branch to refer to that function instead. */
+ if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
+ && fixP->fx_addsy != NULL
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && ! THUMB_IS_FUNC (fixP->fx_addsy))
+ {
+ fixP->fx_addsy = find_real_start (fixP->fx_addsy);
+ return true;
+ }
+
+ return false;
+}
+
+#ifdef OBJ_ELF
+/* Relocations against Thumb function names must be left unadjusted,
+ so that the linker can use this information to correctly set the
+ bottom bit of their addresses. The MIPS version of this function
+ also prevents relocations that are mips-16 specific, but I do not
+ know why it does this.
+
+ FIXME:
+ There is one other problem that ought to be addressed here, but
+ which currently is not: Taking the address of a label (rather
+ than a function) and then later jumping to that address. Such
+ addresses also ought to have their bottom bit set (assuming that
+ they reside in Thumb code), but at the moment they will not. */
+
+boolean
+arm_fix_adjustable (fixP)
+ fixS * fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ if (THUMB_IS_FUNC (fixP->fx_addsy)
+ && fixP->fx_subsy == NULL)
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+
+const char *
+elf32_arm_target_format ()
+{
+ if (target_big_endian)
+ if (target_oabi)
+ return "elf32-bigarm-oabi";
+ else
+ return "elf32-bigarm";
+ else
+ if (target_oabi)
+ return "elf32-littlearm-oabi";
+ else
+ return "elf32-littlearm";
+}
+
+void
+armelf_frob_symbol (symp, puntp)
+ symbolS * symp;
+ int * puntp;
+{
+ elf_frob_symbol (symp, puntp);
+}
+
+int
+arm_force_relocation (fixp)
+ struct fix * fixp;
+{
+ if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
+ return 1;
+
+ return 0;
+}
+
+static bfd_reloc_code_real_type
+arm_parse_reloc ()
+{
+ char id[16];
+ char * ip;
+ int i;
+ static struct
+ {
+ char * str;
+ int len;
+ bfd_reloc_code_real_type reloc;
+ }
+ reloc_map[] =
+ {
+#define MAP(str,reloc) { str, sizeof (str)-1, reloc }
+ MAP ("(got)", BFD_RELOC_ARM_GOT32),
+ MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
+ /* ScottB: Jan 30, 1998 */
+ /* Added support for parsing "var(PLT)" branch instructions */
+ /* generated by GCC for PLT relocs */
+ MAP ("(plt)", BFD_RELOC_ARM_PLT32),
+ NULL, 0, BFD_RELOC_UNUSED
+#undef MAP
+ };
+
+ for (i = 0, ip = input_line_pointer;
+ i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
+ i++, ip++)
+ id[i] = tolower (*ip);
+
+ for (i = 0; reloc_map[i].str; i++)
+ if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
+ break;
+
+ input_line_pointer += reloc_map[i].len;
+
+ return reloc_map[i].reloc;
+}
+
+static void
+s_arm_elf_cons (nbytes)
+ int nbytes;
+{
+ expressionS exp;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+#ifdef md_cons_align
+ md_cons_align (nbytes);
+#endif
+
+ do
+ {
+ bfd_reloc_code_real_type reloc;
+
+ expression (& exp);
+
+ if (exp.X_op == O_symbol
+ && * input_line_pointer == '('
+ && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
+ int size = bfd_get_reloc_size (howto);
+
+ if (size > nbytes)
+ as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
+ else
+ {
+ register char * p = frag_more ((int) nbytes);
+ int offset = nbytes - size;
+
+ fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
+ & exp, 0, reloc);
+ }
+ }
+ else
+ emit_expr (& exp, (unsigned int) nbytes);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+}
+
+#endif /* OBJ_ELF */
+
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
new file mode 100644
index 00000000000..bf99e243b5e
--- /dev/null
+++ b/gas/config/tc-arm.h
@@ -0,0 +1,204 @@
+/* This file is tc-arm.h
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+ Modified by David Taylor (dtaylor@armltd.co.uk)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_ARM 1
+
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 0
+#endif
+
+#define WORKING_DOT_WORD
+
+#define COFF_MAGIC ARMMAGIC
+#define TARGET_ARCH bfd_arch_arm
+
+#define AOUT_MACHTYPE 0
+
+#define DIFF_EXPR_OK
+
+#ifdef LITTLE_ENDIAN
+#undef LITTLE_ENDIAN
+#endif
+
+#ifdef BIG_ENDIAN
+#undef BIG_ENDIAN
+#endif
+
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+
+#if defined OBJ_AOUT
+#if defined TE_RISCIX
+# define TARGET_FORMAT "a.out-riscix"
+#elif defined TE_LINUX
+# define ARM_BI_ENDIAN
+# define TARGET_FORMAT "a.out-arm-linux"
+#elif defined TE_NetBSD
+# define TARGET_FORMAT "a.out-arm-netbsd"
+#else
+# define ARM_BI_ENDIAN
+# define TARGET_FORMAT \
+ (target_big_endian ? "a.out-arm-big" : "a.out-arm-little")
+#endif
+#endif /* OBJ_AOUT */
+
+#ifdef OBJ_AIF
+#define TARGET_FORMAT "aif"
+#endif
+
+#if defined OBJ_COFF || defined OBJ_ELF
+# define ARM_BI_ENDIAN
+
+# define TC_VALIDATE_FIX(fixP, segType, Label) \
+ if (arm_validate_fix (fixP)) add_symbolP = fixP->fx_addsy
+ extern boolean arm_validate_fix PARAMS ((struct fix *));
+#endif
+
+#ifdef OBJ_COFF
+# if defined TE_PE
+# define TC_FORCE_RELOCATION(x) ((x)->fx_r_type == BFD_RELOC_RVA)
+# ifdef TE_EPOC
+# define TARGET_FORMAT (target_big_endian ? "epoc-pe-arm-big" : "epoc-pe-arm-little")
+# else
+# define TARGET_FORMAT (target_big_endian ? "pe-arm-big" : "pe-arm-little")
+# endif
+# else
+# define TARGET_FORMAT (target_big_endian ? "coff-arm-big" : "coff-arm-little")
+# endif
+#endif
+
+#ifdef OBJ_ELF
+# define TARGET_FORMAT elf32_arm_target_format()
+ extern const char * elf32_arm_target_format PARAMS ((void));
+
+# define TC_FORCE_RELOCATION(fixp) arm_force_relocation (fixp)
+ extern int arm_force_relocation PARAMS ((struct fix *));
+#endif
+
+#define md_convert_frag(b, s, f) {as_fatal (_("arm convert_frag\n"));}
+
+#define md_cleanup() arm_cleanup ()
+ extern void arm_cleanup PARAMS ((void));
+
+#define md_start_line_hook() arm_start_line_hook ()
+ extern void arm_start_line_hook PARAMS ((void));
+
+#define tc_frob_label(S) arm_frob_label (S)
+ extern void arm_frob_label PARAMS ((struct symbol *));
+
+/* We also need to mark assembler created symbols: */
+#define tc_frob_fake_label(S) arm_frob_label (S)
+
+/* NOTE: The fake label creation in stabs.c:s_stab_generic() has
+ deliberately not been updated to mark assembler created stabs
+ symbols as Thumb. */
+
+#ifdef OBJ_ELF
+#define obj_fix_adjustable(fixP) arm_fix_adjustable (fixP)
+#else
+#define obj_fix_adjustable(fixP) 0
+#endif
+
+/* We need to keep some local information on symbols. */
+
+#define TC_SYMFIELD_TYPE unsigned int
+#define ARM_GET_FLAG(s) ((s)->sy_tc)
+#define ARM_SET_FLAG(s,v) ((s)->sy_tc |= (v))
+#define ARM_RESET_FLAG(s,v) ((s)->sy_tc &= ~(v))
+
+#define ARM_FLAG_THUMB (1 << 0) /* The symbol is a Thumb symbol rather than an Arm symbol. */
+#define ARM_FLAG_INTERWORK (1 << 1) /* The symbol is attached to code that suppports interworking. */
+#define THUMB_FLAG_FUNC (1 << 2) /* The symbol is attached to the start of a Thumb function. */
+
+#define ARM_IS_THUMB(s) (ARM_GET_FLAG (s) & ARM_FLAG_THUMB)
+#define ARM_IS_INTERWORK(s) (ARM_GET_FLAG (s) & ARM_FLAG_INTERWORK)
+#define THUMB_IS_FUNC(s) (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC)
+
+#define ARM_SET_THUMB(s,t) ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB) : ARM_RESET_FLAG (s, ARM_FLAG_THUMB))
+#define ARM_SET_INTERWORK(s,t) ((t) ? ARM_SET_FLAG (s, ARM_FLAG_INTERWORK) : ARM_RESET_FLAG (s, ARM_FLAG_INTERWORK))
+#define THUMB_SET_FUNC(s,t) ((t) ? ARM_SET_FLAG (s, THUMB_FLAG_FUNC) : ARM_RESET_FLAG (s, THUMB_FLAG_FUNC))
+
+
+#define TC_FIX_TYPE PTR
+#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL)
+
+#define TC_START_LABEL(C,STR) \
+ (c == ':' || (c == '/' && arm_data_in_code ()))
+int arm_data_in_code PARAMS ((void));
+
+#define tc_canonicalize_symbol_name(str) \
+ arm_canonicalize_symbol_name (str);
+char * arm_canonicalize_symbol_name PARAMS ((char *));
+
+#define obj_adjust_symtab() arm_adjust_symtab ()
+ extern void arm_adjust_symtab PARAMS ((void));
+
+#ifdef OBJ_ELF
+#define obj_frob_symbol(sym, punt) armelf_frob_symbol (sym, punt)
+#endif
+
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+
+#define LISTING_HEADER "ARM GAS "
+
+#define OPTIONAL_REGISTER_PREFIX '%'
+
+#define md_operand(x)
+
+#define TC_HANDLES_FX_DONE
+
+#define MD_APPLY_FIX3
+
+#define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L'))
+#define LOCAL_LABELS_FB 1
+
+/* This expression evaluates to false if the relocation is for a local object
+ for which we still want to do the relocation at runtime. True if we
+ are willing to perform this relocation while building the .o file.
+ This is only used for pcrel relocations, so GOTOFF does not need to be
+ checked here. I am not sure if some of the others are ever used with
+ pcrel, but it is easier to be safe than sorry. */
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ( (FIX)->fx_r_type != BFD_RELOC_ARM_GOT12 \
+ && (FIX)->fx_r_type != BFD_RELOC_ARM_GOT32 \
+ && (FIX)->fx_r_type != BFD_RELOC_32)
+
+#define TC_CONS_FIX_NEW cons_fix_new_arm
+ extern void cons_fix_new_arm PARAMS ((fragS *, int, int, expressionS *));
+
+/* Don't allow symbols to be discarded on GOT related relocs,
+ nor on globals. */
+#define tc_fix_adjustable(x) (\
+ ((x)->fx_r_type == BFD_RELOC_ARM_PLT32 \
+ || (x)->fx_r_type == BFD_RELOC_ARM_GOT32 \
+ || (x)->fx_r_type == BFD_RELOC_ARM_GOTOFF \
+ || S_IS_EXTERN ((x)->fx_addsy) \
+ || S_IS_WEAK ((x)->fx_addsy)) ? 0 : 1)
+
+#ifdef OBJ_ELF
+#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+#else
+#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
+#endif
+
+/* end of tc-arm.h */
diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c
new file mode 100644
index 00000000000..cf38f3e1e71
--- /dev/null
+++ b/gas/config/tc-d10v.c
@@ -0,0 +1,1636 @@
+/* tc-d10v.c -- Assembler code for the Mitsubishi D10V
+
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/d10v.h"
+#include "elf/ppc.h"
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = "";
+const char *md_shortopts = "O";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+int Optimizing = 0;
+
+#define AT_WORD_P(X) ((X)->X_op == O_right_shift \
+ && (X)->X_op_symbol != NULL \
+ && (X)->X_op_symbol->sy_value.X_op == O_constant \
+ && (X)->X_op_symbol->sy_value.X_add_number == AT_WORD_RIGHT_SHIFT)
+#define AT_WORD_RIGHT_SHIFT 2
+
+
+/* fixups */
+#define MAX_INSN_FIXUPS (5)
+struct d10v_fixup
+{
+ expressionS exp;
+ int operand;
+ int pcrel;
+ int size;
+ bfd_reloc_code_real_type reloc;
+};
+
+typedef struct _fixups
+{
+ int fc;
+ struct d10v_fixup fix[MAX_INSN_FIXUPS];
+ struct _fixups *next;
+} Fixups;
+
+static Fixups FixUps[2];
+static Fixups *fixups;
+
+/* True if instruction swapping warnings should be inhibited. */
+static unsigned char flag_warn_suppress_instructionswap; /* --nowarnswap */
+
+/* local functions */
+static int reg_name_search PARAMS ((char *name));
+static int register_name PARAMS ((expressionS *expressionP));
+static int check_range PARAMS ((unsigned long num, int bits, int flags));
+static int postfix PARAMS ((char *p));
+static bfd_reloc_code_real_type get_reloc PARAMS ((struct d10v_operand *op));
+static int get_operands PARAMS ((expressionS exp[]));
+static struct d10v_opcode *find_opcode PARAMS ((struct d10v_opcode *opcode, expressionS ops[]));
+static unsigned long build_insn PARAMS ((struct d10v_opcode *opcode, expressionS *opers, unsigned long insn));
+static void write_long PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
+static void write_1_short PARAMS ((struct d10v_opcode *opcode, unsigned long insn, Fixups *fx));
+static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
+ struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx));
+static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
+static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
+ offsetT value, int left, fixS *fix));
+static int parallel_ok PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
+ struct d10v_opcode *opcode2, unsigned long insn2,
+ int exec_type));
+static symbolS * find_symbol_matching_register PARAMS ((expressionS *));
+
+struct option md_longopts[] =
+{
+#define OPTION_NOWARNSWAP (OPTION_MD_BASE)
+ {"nowarnswap", no_argument, NULL, OPTION_NOWARNSWAP},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+static void d10v_dot_word PARAMS ((int));
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "word", d10v_dot_word, 2 },
+ { NULL, NULL, 0 }
+};
+
+/* Opcode hash table. */
+static struct hash_control *d10v_hash;
+
+/* reg_name_search does a binary search of the d10v_predefined_registers
+ array to see if "name" is a valid regiter name. Returns the register
+ number from the array on success, or -1 on failure. */
+
+static int
+reg_name_search (name)
+ char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = d10v_reg_name_cnt() - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, d10v_predefined_registers[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return d10v_predefined_registers[middle].value;
+ }
+ while (low <= high);
+ return -1;
+}
+
+/* register_name() checks the string at input_line_pointer
+ to see if it is a valid register name */
+
+static int
+register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char c, *p = input_line_pointer;
+
+ while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
+ p++;
+
+ c = *p;
+ if (c)
+ *p++ = 0;
+
+ /* look to see if it's in the register table */
+ reg_number = reg_name_search (input_line_pointer);
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ /* temporarily store a pointer to the string here */
+ expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
+ expressionP->X_add_number = reg_number;
+ input_line_pointer = p;
+ return 1;
+ }
+ if (c)
+ *(p-1) = c;
+ return 0;
+}
+
+
+static int
+check_range (num, bits, flags)
+ unsigned long num;
+ int bits;
+ int flags;
+{
+ long min, max, bit1;
+ int retval=0;
+
+ /* don't bother checking 16-bit values */
+ if (bits == 16)
+ return 0;
+
+ if (flags & OPERAND_SHIFT)
+ {
+ /* all special shift operands are unsigned */
+ /* and <= 16. We allow 0 for now. */
+ if (num>16)
+ return 1;
+ else
+ return 0;
+ }
+
+ if (flags & OPERAND_SIGNED)
+ {
+ max = (1 << (bits - 1))-1;
+ min = - (1 << (bits - 1));
+ if (((long)num > max) || ((long)num < min))
+ retval = 1;
+ }
+ else
+ {
+ max = (1 << bits) - 1;
+ min = 0;
+ if ((num > max) || (num < min))
+ retval = 1;
+ }
+ return retval;
+}
+
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("D10V options:\n\
+-O optimize. Will do some operations in parallel.\n"));
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'O':
+ /* Optimize. Will attempt to parallelize operations */
+ Optimizing = 1;
+ break;
+ case OPTION_NOWARNSWAP:
+ flag_warn_suppress_instructionswap = 1;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+ case 'd':
+ prec = 4;
+ break;
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * 2;
+
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ return NULL;
+}
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ asection *sec;
+ fragS *fragP;
+{
+ abort ();
+}
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+
+void
+md_begin ()
+{
+ char *prev_name = "";
+ struct d10v_opcode *opcode;
+ d10v_hash = hash_new();
+
+ /* Insert unique names into hash table. The D10v instruction set
+ has many identical opcode names that have different opcodes based
+ on the operands. This hash table then provides a quick index to
+ the first opcode with a particular name in the opcode table. */
+
+ for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++)
+ {
+ if (strcmp (prev_name, opcode->name))
+ {
+ prev_name = (char *)opcode->name;
+ hash_insert (d10v_hash, opcode->name, (char *) opcode);
+ }
+ }
+
+ fixups = &FixUps[0];
+ FixUps[0].next = &FixUps[1];
+ FixUps[1].next = &FixUps[0];
+}
+
+
+/* this function removes the postincrement or postdecrement
+ operator ( '+' or '-' ) from an expression */
+
+static int postfix (p)
+ char *p;
+{
+ while (*p != '-' && *p != '+')
+ {
+ if (*p==0 || *p=='\n' || *p=='\r')
+ break;
+ p++;
+ }
+
+ if (*p == '-')
+ {
+ *p = ' ';
+ return (-1);
+ }
+ if (*p == '+')
+ {
+ *p = ' ';
+ return (1);
+ }
+
+ return (0);
+}
+
+
+static bfd_reloc_code_real_type
+get_reloc (op)
+ struct d10v_operand *op;
+{
+ int bits = op->bits;
+
+ if (bits <= 4)
+ return (0);
+
+ if (op->flags & OPERAND_ADDR)
+ {
+ if (bits == 8)
+ return (BFD_RELOC_D10V_10_PCREL_R);
+ else
+ return (BFD_RELOC_D10V_18_PCREL);
+ }
+
+ return (BFD_RELOC_16);
+}
+
+
+/* get_operands parses a string of operands and returns
+ an array of expressions */
+
+static int
+get_operands (exp)
+ expressionS exp[];
+{
+ char *p = input_line_pointer;
+ int numops = 0;
+ int post = 0;
+
+ while (*p)
+ {
+ while (*p == ' ' || *p == '\t' || *p == ',')
+ p++;
+ if (*p==0 || *p=='\n' || *p=='\r')
+ break;
+
+ if (*p == '@')
+ {
+ p++;
+ exp[numops].X_op = O_absent;
+ if (*p == '(')
+ {
+ p++;
+ exp[numops].X_add_number = OPERAND_ATPAR;
+ }
+ else if (*p == '-')
+ {
+ p++;
+ exp[numops].X_add_number = OPERAND_ATMINUS;
+ }
+ else
+ {
+ exp[numops].X_add_number = OPERAND_ATSIGN;
+ post = postfix (p);
+ }
+ numops++;
+ continue;
+ }
+
+ if (*p == ')')
+ {
+ /* just skip the trailing paren */
+ p++;
+ continue;
+ }
+
+ input_line_pointer = p;
+
+ /* check to see if it might be a register name */
+ if (!register_name (&exp[numops]))
+ {
+ /* parse as an expression */
+ expression (&exp[numops]);
+ }
+
+ if (strncasecmp (input_line_pointer, "@word", 5) == 0)
+ {
+ input_line_pointer += 5;
+ if (exp[numops].X_op == O_register)
+ {
+ /* if it looked like a register name but was followed by
+ "@word" then it was really a symbol, so change it to
+ one */
+ exp[numops].X_op = O_symbol;
+ exp[numops].X_add_symbol = symbol_find_or_make ((char *)exp[numops].X_op_symbol);
+ }
+
+ /* check for identifier@word+constant */
+ if (*input_line_pointer == '-' || *input_line_pointer == '+')
+ {
+ char *orig_line = input_line_pointer;
+ expressionS new_exp;
+ expression (&new_exp);
+ exp[numops].X_add_number = new_exp.X_add_number;
+ }
+
+ /* convert expr into a right shift by AT_WORD_RIGHT_SHIFT */
+ {
+ expressionS new_exp;
+ memset (&new_exp, 0, sizeof new_exp);
+ new_exp.X_add_number = AT_WORD_RIGHT_SHIFT;
+ new_exp.X_op = O_constant;
+ new_exp.X_unsigned = 1;
+ exp[numops].X_op_symbol = make_expr_symbol (&new_exp);
+ exp[numops].X_op = O_right_shift;
+ }
+
+ know (AT_WORD_P (&exp[numops]));
+ }
+
+ if (exp[numops].X_op == O_illegal)
+ as_bad (_("illegal operand"));
+ else if (exp[numops].X_op == O_absent)
+ as_bad (_("missing operand"));
+
+ numops++;
+ p = input_line_pointer;
+ }
+
+ switch (post)
+ {
+ case -1: /* postdecrement mode */
+ exp[numops].X_op = O_absent;
+ exp[numops++].X_add_number = OPERAND_MINUS;
+ break;
+ case 1: /* postincrement mode */
+ exp[numops].X_op = O_absent;
+ exp[numops++].X_add_number = OPERAND_PLUS;
+ break;
+ }
+
+ exp[numops].X_op = 0;
+ return (numops);
+}
+
+static unsigned long
+d10v_insert_operand (insn, op_type, value, left, fix)
+ unsigned long insn;
+ int op_type;
+ offsetT value;
+ int left;
+ fixS *fix;
+{
+ int shift, bits;
+
+ shift = d10v_operands[op_type].shift;
+ if (left)
+ shift += 15;
+
+ bits = d10v_operands[op_type].bits;
+
+ /* truncate to the proper number of bits */
+ if (check_range (value, bits, d10v_operands[op_type].flags))
+ as_bad_where (fix->fx_file, fix->fx_line, _("operand out of range: %d"), value);
+
+ value &= 0x7FFFFFFF >> (31 - bits);
+ insn |= (value << shift);
+
+ return insn;
+}
+
+
+/* build_insn takes a pointer to the opcode entry in the opcode table
+ and the array of operand expressions and returns the instruction */
+
+static unsigned long
+build_insn (opcode, opers, insn)
+ struct d10v_opcode *opcode;
+ expressionS *opers;
+ unsigned long insn;
+{
+ int i, bits, shift, flags, format;
+ unsigned long number;
+
+ /* the insn argument is only used for the DIVS kludge */
+ if (insn)
+ format = LONG_R;
+ else
+ {
+ insn = opcode->opcode;
+ format = opcode->format;
+ }
+
+ for (i=0;opcode->operands[i];i++)
+ {
+ flags = d10v_operands[opcode->operands[i]].flags;
+ bits = d10v_operands[opcode->operands[i]].bits;
+ shift = d10v_operands[opcode->operands[i]].shift;
+ number = opers[i].X_add_number;
+
+ if (flags & OPERAND_REG)
+ {
+ number &= REGISTER_MASK;
+ if (format == LONG_L)
+ shift += 15;
+ }
+
+ if (opers[i].X_op != O_register && opers[i].X_op != O_constant)
+ {
+ /* now create a fixup */
+
+ if (fixups->fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ if (AT_WORD_P (&opers[i]))
+ {
+ /* Reconize XXX>>1+N aka XXX@word+N as special (AT_WORD) */
+ fixups->fix[fixups->fc].reloc = BFD_RELOC_D10V_18;
+ opers[i].X_op = O_symbol;
+ opers[i].X_op_symbol = NULL; /* Should free it */
+ /* number is left shifted by AT_WORD_RIGHT_SHIFT so
+ that, it is aligned with the symbol's value. Later,
+ BFD_RELOC_D10V_18 will right shift (symbol_value +
+ X_add_number). */
+ number <<= AT_WORD_RIGHT_SHIFT;
+ opers[i].X_add_number = number;
+ }
+ else
+ fixups->fix[fixups->fc].reloc =
+ get_reloc((struct d10v_operand *)&d10v_operands[opcode->operands[i]]);
+
+ if (fixups->fix[fixups->fc].reloc == BFD_RELOC_16 ||
+ fixups->fix[fixups->fc].reloc == BFD_RELOC_D10V_18)
+ fixups->fix[fixups->fc].size = 2;
+ else
+ fixups->fix[fixups->fc].size = 4;
+
+ fixups->fix[fixups->fc].exp = opers[i];
+ fixups->fix[fixups->fc].operand = opcode->operands[i];
+ fixups->fix[fixups->fc].pcrel = (flags & OPERAND_ADDR) ? true : false;
+ (fixups->fc)++;
+ }
+
+ /* truncate to the proper number of bits */
+ if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
+ as_bad (_("operand out of range: %d"),number);
+ number &= 0x7FFFFFFF >> (31 - bits);
+ insn = insn | (number << shift);
+ }
+
+ /* kludge: for DIVS, we need to put the operands in twice */
+ /* on the second pass, format is changed to LONG_R to force */
+ /* the second set of operands to not be shifted over 15 */
+ if ((opcode->opcode == OPCODE_DIVS) && (format==LONG_L))
+ insn = build_insn (opcode, opers, insn);
+
+ return insn;
+}
+
+/* write out a long form instruction */
+static void
+write_long (opcode, insn, fx)
+ struct d10v_opcode *opcode;
+ unsigned long insn;
+ Fixups *fx;
+{
+ int i, where;
+ char *f = frag_more(4);
+
+ insn |= FM11;
+ number_to_chars_bigendian (f, insn, 4);
+
+ for (i=0; i < fx->fc; i++)
+ {
+ if (fx->fix[i].reloc)
+ {
+ where = f - frag_now->fr_literal;
+ if (fx->fix[i].size == 2)
+ where += 2;
+
+ if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
+ fx->fix[i].operand |= 4096;
+
+ fix_new_exp (frag_now,
+ where,
+ fx->fix[i].size,
+ &(fx->fix[i].exp),
+ fx->fix[i].pcrel,
+ fx->fix[i].operand|2048);
+ }
+ }
+ fx->fc = 0;
+}
+
+
+/* write out a short form instruction by itself */
+static void
+write_1_short (opcode, insn, fx)
+ struct d10v_opcode *opcode;
+ unsigned long insn;
+ Fixups *fx;
+{
+ char *f = frag_more(4);
+ int i, where;
+
+ if (opcode->exec_type & PARONLY)
+ as_fatal (_("Instruction must be executed in parallel with another instruction."));
+
+ /* the other container needs to be NOP */
+ /* according to 4.3.1: for FM=00, sub-instructions performed only
+ by IU cannot be encoded in L-container. */
+ if (opcode->unit == IU)
+ insn |= FM00 | (NOP << 15); /* right container */
+ else
+ insn = FM00 | (insn << 15) | NOP; /* left container */
+
+ number_to_chars_bigendian (f, insn, 4);
+ for (i=0; i < fx->fc; i++)
+ {
+ if (fx->fix[i].reloc)
+ {
+ where = f - frag_now->fr_literal;
+ if (fx->fix[i].size == 2)
+ where += 2;
+
+ if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
+ fx->fix[i].operand |= 4096;
+
+ /* if it's an R reloc, we may have to switch it to L */
+ if ( (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) )
+ fx->fix[i].operand |= 1024;
+
+ fix_new_exp (frag_now,
+ where,
+ fx->fix[i].size,
+ &(fx->fix[i].exp),
+ fx->fix[i].pcrel,
+ fx->fix[i].operand|2048);
+ }
+ }
+ fx->fc = 0;
+}
+
+/* write out a short form instruction if possible */
+/* return number of instructions not written out */
+static int
+write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
+ struct d10v_opcode *opcode1, *opcode2;
+ unsigned long insn1, insn2;
+ int exec_type;
+ Fixups *fx;
+{
+ unsigned long insn;
+ char *f;
+ int i,j, where;
+
+ if ( (exec_type != 1) && ((opcode1->exec_type & PARONLY)
+ || (opcode2->exec_type & PARONLY)))
+ as_fatal (_("Instruction must be executed in parallel"));
+
+ if ( (opcode1->format & LONG_OPCODE) || (opcode2->format & LONG_OPCODE))
+ as_fatal (_("Long instructions may not be combined."));
+
+ if(opcode1->exec_type & BRANCH_LINK && exec_type == 0)
+ {
+ /* Instructions paired with a subroutine call are executed before the
+ subroutine, so don't do these pairings unless explicitly requested. */
+ write_1_short (opcode1, insn1, fx->next);
+ return (1);
+ }
+
+ switch (exec_type)
+ {
+ case 0: /* order not specified */
+ if ( Optimizing && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
+ {
+ /* parallel */
+ if (opcode1->unit == IU)
+ insn = FM00 | (insn2 << 15) | insn1;
+ else if (opcode2->unit == MU)
+ insn = FM00 | (insn2 << 15) | insn1;
+ else
+ {
+ insn = FM00 | (insn1 << 15) | insn2;
+ fx = fx->next;
+ }
+ }
+ else if (opcode1->unit == IU)
+ {
+ /* reverse sequential */
+ insn = FM10 | (insn2 << 15) | insn1;
+ }
+ else
+ {
+ /* sequential */
+ insn = FM01 | (insn1 << 15) | insn2;
+ fx = fx->next;
+ }
+ break;
+ case 1: /* parallel */
+ if (opcode1->exec_type & SEQ || opcode2->exec_type & SEQ)
+ as_fatal (_("One of these instructions may not be executed in parallel."));
+
+ if (opcode1->unit == IU)
+ {
+ if (opcode2->unit == IU)
+ as_fatal (_("Two IU instructions may not be executed in parallel"));
+ if (!flag_warn_suppress_instructionswap)
+ as_warn (_("Swapping instruction order"));
+ insn = FM00 | (insn2 << 15) | insn1;
+ }
+ else if (opcode2->unit == MU)
+ {
+ if (opcode1->unit == MU)
+ as_fatal (_("Two MU instructions may not be executed in parallel"));
+ if (!flag_warn_suppress_instructionswap)
+ as_warn (_("Swapping instruction order"));
+ insn = FM00 | (insn2 << 15) | insn1;
+ }
+ else
+ {
+ insn = FM00 | (insn1 << 15) | insn2;
+ fx = fx->next;
+ }
+ break;
+ case 2: /* sequential */
+ if (opcode1->unit != IU)
+ insn = FM01 | (insn1 << 15) | insn2;
+ else if (opcode2->unit == MU || opcode2->unit == EITHER)
+ {
+ if (!flag_warn_suppress_instructionswap)
+ as_warn (_("Swapping instruction order"));
+ insn = FM10 | (insn2 << 15) | insn1;
+ }
+ else
+ as_fatal (_("IU instruction may not be in the left container"));
+ fx = fx->next;
+ break;
+ case 3: /* reverse sequential */
+ if (opcode2->unit != MU)
+ insn = FM10 | (insn1 << 15) | insn2;
+ else if (opcode1->unit == IU || opcode1->unit == EITHER)
+ {
+ if (!flag_warn_suppress_instructionswap)
+ as_warn (_("Swapping instruction order"));
+ insn = FM01 | (insn2 << 15) | insn1;
+ }
+ else
+ as_fatal (_("MU instruction may not be in the right container"));
+ fx = fx->next;
+ break;
+ default:
+ as_fatal (_("unknown execution type passed to write_2_short()"));
+ }
+
+ f = frag_more(4);
+ number_to_chars_bigendian (f, insn, 4);
+
+ for (j=0; j<2; j++)
+ {
+ for (i=0; i < fx->fc; i++)
+ {
+ if (fx->fix[i].reloc)
+ {
+ where = f - frag_now->fr_literal;
+ if (fx->fix[i].size == 2)
+ where += 2;
+
+ if ( (fx->fix[i].reloc == BFD_RELOC_D10V_10_PCREL_R) && (j == 0) )
+ fx->fix[i].operand |= 1024;
+
+ if (fx->fix[i].reloc == BFD_RELOC_D10V_18)
+ fx->fix[i].operand |= 4096;
+
+ fix_new_exp (frag_now,
+ where,
+ fx->fix[i].size,
+ &(fx->fix[i].exp),
+ fx->fix[i].pcrel,
+ fx->fix[i].operand|2048);
+ }
+ }
+ fx->fc = 0;
+ fx = fx->next;
+ }
+ return (0);
+}
+
+
+/* Check 2 instructions and determine if they can be safely */
+/* executed in parallel. Returns 1 if they can be. */
+static int
+parallel_ok (op1, insn1, op2, insn2, exec_type)
+ struct d10v_opcode *op1, *op2;
+ unsigned long insn1, insn2;
+ int exec_type;
+{
+ int i, j, flags, mask, shift, regno;
+ unsigned long ins, mod[2], used[2];
+ struct d10v_opcode *op;
+
+ if ((op1->exec_type & SEQ) != 0 || (op2->exec_type & SEQ) != 0
+ || (op1->exec_type & PAR) == 0 || (op2->exec_type & PAR) == 0
+ || (op1->unit == BOTH) || (op2->unit == BOTH)
+ || (op1->unit == IU && op2->unit == IU)
+ || (op1->unit == MU && op2->unit == MU))
+ return 0;
+
+ /* If the first instruction is a branch and this is auto parallazation,
+ don't combine with any second instruction. */
+ if (exec_type == 0 && (op1->exec_type & BRANCH) != 0)
+ return 0;
+
+ /* The idea here is to create two sets of bitmasks (mod and used)
+ which indicate which registers are modified or used by each
+ instruction. The operation can only be done in parallel if
+ instruction 1 and instruction 2 modify different registers, and
+ the first instruction does not modify registers that the second
+ is using (The second instruction can modify registers that the
+ first is using as they are only written back after the first
+ instruction has completed). Accesses to control registers, PSW,
+ and memory are treated as accesses to a single register. So if
+ both instructions write memory or if the first instruction writes
+ memory and the second reads, then they cannot be done in
+ parallel. Likewise, if the first instruction mucks with the psw
+ and the second reads the PSW (which includes C, F0, and F1), then
+ they cannot operate safely in parallel. */
+
+ /* the bitmasks (mod and used) look like this (bit 31 = MSB) */
+ /* r0-r15 0-15 */
+ /* a0-a1 16-17 */
+ /* cr (not psw) 18 */
+ /* psw 19 */
+ /* mem 20 */
+
+ for (j=0;j<2;j++)
+ {
+ if (j == 0)
+ {
+ op = op1;
+ ins = insn1;
+ }
+ else
+ {
+ op = op2;
+ ins = insn2;
+ }
+ mod[j] = used[j] = 0;
+ if (op->exec_type & BRANCH_LINK)
+ mod[j] |= 1 << 13;
+
+ for (i = 0; op->operands[i]; i++)
+ {
+ flags = d10v_operands[op->operands[i]].flags;
+ shift = d10v_operands[op->operands[i]].shift;
+ mask = 0x7FFFFFFF >> (31 - d10v_operands[op->operands[i]].bits);
+ if (flags & OPERAND_REG)
+ {
+ regno = (ins >> shift) & mask;
+ if (flags & (OPERAND_ACC0|OPERAND_ACC1))
+ regno += 16;
+ else if (flags & OPERAND_CONTROL) /* mvtc or mvfc */
+ {
+ if (regno == 0)
+ regno = 19;
+ else
+ regno = 18;
+ }
+ else if (flags & (OPERAND_FFLAG|OPERAND_CFLAG))
+ regno = 19;
+
+ if ( flags & OPERAND_DEST )
+ {
+ mod[j] |= 1 << regno;
+ if (flags & OPERAND_EVEN)
+ mod[j] |= 1 << (regno + 1);
+ }
+ else
+ {
+ used[j] |= 1 << regno ;
+ if (flags & OPERAND_EVEN)
+ used[j] |= 1 << (regno + 1);
+
+ /* Auto inc/dec also modifies the register. */
+ if (op->operands[i+1] != 0
+ && (d10v_operands[op->operands[i+1]].flags
+ & (OPERAND_PLUS | OPERAND_MINUS)) != 0)
+ mod[j] |= 1 << regno;
+ }
+ }
+ else if (flags & OPERAND_ATMINUS)
+ {
+ /* SP implicitly used/modified */
+ mod[j] |= 1 << 15;
+ used[j] |= 1 << 15;
+ }
+ }
+ if (op->exec_type & RMEM)
+ used[j] |= 1 << 20;
+ else if (op->exec_type & WMEM)
+ mod[j] |= 1 << 20;
+ else if (op->exec_type & RF0)
+ used[j] |= 1 << 19;
+ else if (op->exec_type & WF0)
+ mod[j] |= 1 << 19;
+ else if (op->exec_type & WCAR)
+ mod[j] |= 1 << 19;
+ }
+ if ((mod[0] & mod[1]) == 0 && (mod[0] & used[1]) == 0)
+ return 1;
+ return 0;
+}
+
+
+/* This is the main entry point for the machine-dependent assembler. str points to a
+ machine-dependent instruction. This function is supposed to emit the frags/bytes
+ it assembles to. For the D10V, it mostly handles the special VLIW parsing and packing
+ and leaves the difficult stuff to do_assemble().
+ */
+
+static unsigned long prev_insn;
+static struct d10v_opcode *prev_opcode = 0;
+static subsegT prev_subseg;
+static segT prev_seg = 0;;
+static int etype = 0; /* saved extype. used for multiline instructions */
+
+void
+md_assemble (str)
+ char *str;
+{
+ struct d10v_opcode * opcode;
+ unsigned long insn;
+ int extype = 0; /* execution type; parallel, etc */
+ char * str2;
+
+ if (etype == 0)
+ {
+ /* look for the special multiple instruction separators */
+ str2 = strstr (str, "||");
+ if (str2)
+ extype = 1;
+ else
+ {
+ str2 = strstr (str, "->");
+ if (str2)
+ extype = 2;
+ else
+ {
+ str2 = strstr (str, "<-");
+ if (str2)
+ extype = 3;
+ }
+ }
+ /* str2 points to the separator, if one */
+ if (str2)
+ {
+ *str2 = 0;
+
+ /* if two instructions are present and we already have one saved
+ then first write it out */
+ d10v_cleanup ();
+
+ /* assemble first instruction and save it */
+ prev_insn = do_assemble (str, &prev_opcode);
+ if (prev_insn == -1)
+ as_fatal (_("can't find opcode "));
+ fixups = fixups->next;
+ str = str2 + 2;
+ }
+ }
+
+ insn = do_assemble (str, &opcode);
+ if (insn == -1)
+ {
+ if (extype)
+ {
+ etype = extype;
+ return;
+ }
+ as_fatal (_("can't find opcode "));
+ }
+
+ if (etype)
+ {
+ extype = etype;
+ etype = 0;
+ }
+
+ /* if this is a long instruction, write it and any previous short instruction */
+ if (opcode->format & LONG_OPCODE)
+ {
+ if (extype)
+ as_fatal (_("Unable to mix instructions as specified"));
+ d10v_cleanup ();
+ write_long (opcode, insn, fixups);
+ prev_opcode = NULL;
+ return;
+ }
+
+ if (prev_opcode && prev_seg && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
+ d10v_cleanup();
+
+ if (prev_opcode && (write_2_short (prev_opcode, prev_insn, opcode, insn, extype, fixups) == 0))
+ {
+ /* no instructions saved */
+ prev_opcode = NULL;
+ }
+ else
+ {
+ if (extype)
+ as_fatal (_("Unable to mix instructions as specified"));
+ /* save off last instruction so it may be packed on next pass */
+ prev_opcode = opcode;
+ prev_insn = insn;
+ prev_seg = now_seg;
+ prev_subseg = now_subseg;
+ fixups = fixups->next;
+ }
+}
+
+
+/* do_assemble assembles a single instruction and returns an opcode */
+/* it returns -1 (an invalid opcode) on error */
+
+static unsigned long
+do_assemble (str, opcode)
+ char *str;
+ struct d10v_opcode **opcode;
+{
+ unsigned char *op_start, *save;
+ unsigned char *op_end;
+ char name[20];
+ int nlen = 0;
+ expressionS myops[6];
+ unsigned long insn;
+
+ /* Drop leading whitespace. */
+ while (*str == ' ')
+ str++;
+
+ /* Find the opcode end. */
+ for (op_start = op_end = (unsigned char *) (str);
+ *op_end
+ && nlen < 20
+ && !is_end_of_line[*op_end] && *op_end != ' ';
+ op_end++)
+ {
+ name[nlen] = tolower (op_start[nlen]);
+ nlen++;
+ }
+ name[nlen] = 0;
+
+ if (nlen == 0)
+ return -1;
+
+ /* Find the first opcode with the proper name. */
+ *opcode = (struct d10v_opcode *)hash_find (d10v_hash, name);
+ if (*opcode == NULL)
+ as_fatal (_("unknown opcode: %s"),name);
+
+ save = input_line_pointer;
+ input_line_pointer = op_end;
+ *opcode = find_opcode (*opcode, myops);
+ if (*opcode == 0)
+ return -1;
+ input_line_pointer = save;
+
+ insn = build_insn ((*opcode), myops, 0);
+ return (insn);
+}
+
+/* Find the symbol which has the same name as the register in the given expression. */
+static symbolS *
+find_symbol_matching_register (exp)
+ expressionS * exp;
+{
+ int i;
+
+ if (exp->X_op != O_register)
+ return NULL;
+
+ /* Find the name of the register. */
+ for (i = d10v_reg_name_cnt (); i--;)
+ if (d10v_predefined_registers [i].value == exp->X_add_number)
+ break;
+
+ if (i < 0)
+ abort ();
+
+ /* Now see if a symbol has been defined with the same name. */
+ return symbol_find (d10v_predefined_registers [i].name);
+}
+
+
+/* find_opcode() gets a pointer to an entry in the opcode table. */
+/* It must look at all opcodes with the same name and use the operands */
+/* to choose the correct opcode. */
+
+static struct d10v_opcode *
+find_opcode (opcode, myops)
+ struct d10v_opcode *opcode;
+ expressionS myops[];
+{
+ int i, match, done;
+ struct d10v_opcode *next_opcode;
+
+ /* get all the operands and save them as expressions */
+ get_operands (myops);
+
+ /* now see if the operand is a fake. If so, find the correct size */
+ /* instruction, if possible */
+ if (opcode->format == OPCODE_FAKE)
+ {
+ int opnum = opcode->operands[0];
+ int flags;
+
+ if (myops[opnum].X_op == O_register)
+ {
+ myops[opnum].X_op = O_symbol;
+ myops[opnum].X_add_symbol = symbol_find_or_make ((char *)myops[opnum].X_op_symbol);
+ myops[opnum].X_add_number = 0;
+ myops[opnum].X_op_symbol = NULL;
+ }
+
+ next_opcode=opcode+1;
+
+ /* If the first operand is supposed to be a register, make sure
+ we got a valid one. */
+ flags = d10v_operands[next_opcode->operands[0]].flags;
+ if (flags & OPERAND_REG)
+ {
+ int X_op = myops[0].X_op;
+ int num = myops[0].X_add_number;
+
+ if (X_op != O_register
+ || (num & ~flags
+ & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
+ | OPERAND_FFLAG | OPERAND_CFLAG | OPERAND_CONTROL)))
+ {
+ as_bad (_("bad opcode or operands"));
+ return 0;
+ }
+ }
+
+ if (myops[opnum].X_op == O_constant || (myops[opnum].X_op == O_symbol &&
+ S_IS_DEFINED(myops[opnum].X_add_symbol) &&
+ (S_GET_SEGMENT(myops[opnum].X_add_symbol) == now_seg)))
+ {
+ for (i=0; opcode->operands[i+1]; i++)
+ {
+ int bits = d10v_operands[next_opcode->operands[opnum]].bits;
+ int flags = d10v_operands[next_opcode->operands[opnum]].flags;
+ if (flags & OPERAND_ADDR)
+ bits += 2;
+ if (myops[opnum].X_op == O_constant)
+ {
+ if (!check_range (myops[opnum].X_add_number, bits, flags))
+ return next_opcode;
+ }
+ else
+ {
+ fragS *f;
+ long value;
+ /* calculate the current address by running through the previous frags */
+ /* and adding our current offset */
+ for (value = 0, f = frchain_now->frch_root; f; f = f->fr_next)
+ value += f->fr_fix + f->fr_offset;
+
+ if (flags & OPERAND_ADDR)
+ value = S_GET_VALUE(myops[opnum].X_add_symbol) - value -
+ (obstack_next_free(&frchain_now->frch_obstack) - frag_now->fr_literal);
+ else
+ value = S_GET_VALUE(myops[opnum].X_add_symbol);
+
+ if (AT_WORD_P (&myops[opnum]))
+ {
+ if (bits > 4)
+ {
+ bits += 2;
+ if (!check_range (value, bits, flags))
+ return next_opcode;
+ }
+ }
+ else if (!check_range (value, bits, flags))
+ return next_opcode;
+ }
+ next_opcode++;
+ }
+ as_fatal (_("value out of range"));
+ }
+ else
+ {
+ /* not a constant, so use a long instruction */
+ return opcode+2;
+ }
+ }
+ else
+ {
+ match = 0;
+ /* now search the opcode table table for one with operands */
+ /* that matches what we've got */
+ while (!match)
+ {
+ match = 1;
+ for (i = 0; opcode->operands[i]; i++)
+ {
+ int flags = d10v_operands[opcode->operands[i]].flags;
+ int X_op = myops[i].X_op;
+ int num = myops[i].X_add_number;
+
+ if (X_op == 0)
+ {
+ match = 0;
+ break;
+ }
+
+ if (flags & OPERAND_REG)
+ {
+ if ((X_op != O_register)
+ || (num & ~flags
+ & (OPERAND_GPR | OPERAND_ACC0 | OPERAND_ACC1
+ | OPERAND_FFLAG | OPERAND_CFLAG
+ | OPERAND_CONTROL)))
+ {
+ match = 0;
+ break;
+ }
+ }
+
+ if (((flags & OPERAND_MINUS) && ((X_op != O_absent) || (num != OPERAND_MINUS))) ||
+ ((flags & OPERAND_PLUS) && ((X_op != O_absent) || (num != OPERAND_PLUS))) ||
+ ((flags & OPERAND_ATMINUS) && ((X_op != O_absent) || (num != OPERAND_ATMINUS))) ||
+ ((flags & OPERAND_ATPAR) && ((X_op != O_absent) || (num != OPERAND_ATPAR))) ||
+ ((flags & OPERAND_ATSIGN) && ((X_op != O_absent) || (num != OPERAND_ATSIGN))))
+ {
+ match = 0;
+ break;
+ }
+
+ /* Unfortunatly, for the indirect operand in instructions such as
+ ``ldb r1, @(c,r14)'' this function can be passed X_op == O_register
+ (because 'c' is a valid register name). However we cannot just
+ ignore the case when X_op == O_register but flags & OPERAND_REG is
+ null, so we check to see if a symbol of the same name as the register
+ exists. If the symbol does exist, then the parser was unable to
+ distinguish the two cases and we fix things here. (Ref: PR14826) */
+
+ if (!(flags & OPERAND_REG) && (X_op == O_register))
+ {
+ symbolS * sym;
+
+ sym = find_symbol_matching_register (& myops[i]);
+
+ if (sym != NULL)
+ {
+ myops [i].X_op == X_op == O_symbol;
+ myops [i].X_add_symbol = sym;
+ }
+ else
+ as_bad
+ (_("illegal operand - register name found where none expected"));
+ }
+ }
+
+ /* We're only done if the operands matched so far AND there
+ are no more to check. */
+ if (match && myops[i].X_op == 0)
+ break;
+ else
+ match = 0;
+
+ next_opcode = opcode + 1;
+
+ if (next_opcode->opcode == 0)
+ break;
+
+ if (strcmp (next_opcode->name, opcode->name))
+ break;
+
+ opcode = next_opcode;
+ }
+ }
+
+ if (!match)
+ {
+ as_bad (_("bad opcode or operands"));
+ return (0);
+ }
+
+ /* Check that all registers that are required to be even are. */
+ /* Also, if any operands were marked as registers, but were really symbols */
+ /* fix that here. */
+ for (i=0; opcode->operands[i]; i++)
+ {
+ if ((d10v_operands[opcode->operands[i]].flags & OPERAND_EVEN) &&
+ (myops[i].X_add_number & 1))
+ as_fatal (_("Register number must be EVEN"));
+ if (myops[i].X_op == O_register)
+ {
+ if (!(d10v_operands[opcode->operands[i]].flags & OPERAND_REG))
+ {
+ myops[i].X_op = O_symbol;
+ myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
+ myops[i].X_add_number = 0;
+ myops[i].X_op_symbol = NULL;
+ }
+ }
+ }
+ return opcode;
+}
+
+/* if while processing a fixup, a reloc really needs to be created */
+/* then it is done here */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg;
+ fixS *fixp;
+{
+ arelent *reloc;
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("reloc %d not supported by object file format"), (int)fixp->fx_r_type);
+ return NULL;
+ }
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ reloc->address = fixp->fx_offset;
+
+ reloc->addend = fixp->fx_addnumber;
+
+ return reloc;
+}
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg;
+{
+ abort ();
+ return 0;
+}
+
+long
+md_pcrel_from_section (fixp, sec)
+ fixS *fixp;
+ segT sec;
+{
+ if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) ||
+ (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
+ return 0;
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+int
+md_apply_fix3 (fixp, valuep, seg)
+ fixS *fixp;
+ valueT *valuep;
+ segT seg;
+{
+ char *where;
+ unsigned long insn;
+ long value;
+ int op_type;
+ int left=0;
+
+ if (fixp->fx_addsy == (symbolS *) NULL)
+ {
+ value = *valuep;
+ fixp->fx_done = 1;
+ }
+ else if (fixp->fx_pcrel)
+ value = *valuep;
+ else
+ {
+ value = fixp->fx_offset;
+ if (fixp->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixp->fx_subsy);
+ else
+ {
+ /* We don't actually support subtracting a symbol. */
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+
+ op_type = fixp->fx_r_type;
+ if (op_type & 2048)
+ {
+ op_type -= 2048;
+ if (op_type & 1024)
+ {
+ op_type -= 1024;
+ fixp->fx_r_type = BFD_RELOC_D10V_10_PCREL_L;
+ left = 1;
+ }
+ else if (op_type & 4096)
+ {
+ op_type -= 4096;
+ fixp->fx_r_type = BFD_RELOC_D10V_18;
+ }
+ else
+ fixp->fx_r_type = get_reloc((struct d10v_operand *)&d10v_operands[op_type]);
+ }
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixp->fx_frag->fr_literal + fixp->fx_where;
+ insn = bfd_getb32 ((unsigned char *) where);
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_D10V_10_PCREL_L:
+ case BFD_RELOC_D10V_10_PCREL_R:
+ case BFD_RELOC_D10V_18_PCREL:
+ case BFD_RELOC_D10V_18:
+ /* instruction addresses are always right-shifted by 2 */
+ value >>= AT_WORD_RIGHT_SHIFT;
+ if (fixp->fx_size == 2)
+ bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
+ else
+ {
+ struct d10v_opcode *rep, *repi;
+
+ rep = (struct d10v_opcode *) hash_find (d10v_hash, "rep");
+ repi = (struct d10v_opcode *) hash_find (d10v_hash, "repi");
+ if ((insn & FM11) == FM11
+ && (repi != NULL && (insn & repi->mask) == repi->opcode
+ || rep != NULL && (insn & rep->mask) == rep->opcode)
+ && value < 4)
+ as_fatal
+ (_("line %d: rep or repi must include at least 4 instructions"),
+ fixp->fx_line);
+ insn = d10v_insert_operand (insn, op_type, (offsetT)value, left, fixp);
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ }
+ break;
+ case BFD_RELOC_32:
+ bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
+ break;
+ case BFD_RELOC_16:
+ bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixp->fx_done = 0;
+ return 1;
+
+ default:
+ as_fatal (_("line %d: unknown relocation type: 0x%x"),fixp->fx_line,fixp->fx_r_type);
+ }
+ return 0;
+}
+
+/* d10v_cleanup() is called after the assembler has finished parsing the input
+ file or after a label is defined. Because the D10V assembler sometimes saves short
+ instructions to see if it can package them with the next instruction, there may
+ be a short instruction that still needs written. */
+int
+d10v_cleanup ()
+{
+ segT seg;
+ subsegT subseg;
+
+ if (prev_opcode && etype == 0)
+ {
+ seg = now_seg;
+ subseg = now_subseg;
+ if (prev_seg)
+ subseg_set (prev_seg, prev_subseg);
+ write_1_short (prev_opcode, prev_insn, fixups->next);
+ subseg_set (seg, subseg);
+ prev_opcode = NULL;
+ }
+ return 1;
+}
+
+/* Like normal .word, except support @word */
+/* clobbers input_line_pointer, checks end-of-line. */
+static void
+d10v_dot_word (nbytes)
+ register int nbytes; /* 1=.byte, 2=.word, 4=.long */
+{
+ expressionS exp;
+ bfd_reloc_code_real_type reloc;
+ char *p;
+ int offset;
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ expression (&exp);
+ if (!strncasecmp (input_line_pointer, "@word", 5))
+ {
+ exp.X_add_number = 0;
+ input_line_pointer += 5;
+
+ p = frag_more (2);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
+ &exp, 0, BFD_RELOC_D10V_18);
+ }
+ else
+ emit_expr (&exp, 2);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+}
+
+
+/* Mitsubishi asked that we support some old syntax that apparently */
+/* had immediate operands starting with '#'. This is in some of their */
+/* sample code but is not documented (although it appears in some */
+/* examples in their assembler manual). For now, we'll solve this */
+/* compatibility problem by simply ignoring any '#' at the beginning */
+/* of an operand. */
+
+/* operands that begin with '#' should fall through to here */
+/* from expr.c */
+
+void
+md_operand (expressionP)
+ expressionS *expressionP;
+{
+ if (*input_line_pointer == '#')
+ {
+ input_line_pointer++;
+ expression (expressionP);
+ }
+}
+
+boolean
+d10v_fix_adjustable (fixP)
+ fixS *fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+
+int
+d10v_force_relocation (fixp)
+ struct fix *fixp;
+{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
diff --git a/gas/config/tc-d10v.h b/gas/config/tc-d10v.h
new file mode 100644
index 00000000000..c6ffd5c3eab
--- /dev/null
+++ b/gas/config/tc-d10v.h
@@ -0,0 +1,62 @@
+/* tc-d10v.h -- Header file for tc-d10v.c.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Written by Martin Hunt, Cygnus Support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_D10V
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifndef BFD_ASSEMBLER
+ #error D10V support requires BFD_ASSEMBLER
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_d10v
+
+#define TARGET_FORMAT "elf32-d10v"
+
+#define MD_APPLY_FIX3
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_bigendian
+
+int d10v_cleanup PARAMS ((void));
+#define md_after_pass_hook() d10v_cleanup()
+#define md_cleanup() d10v_cleanup()
+#define md_do_align(a,b,c,d,e) d10v_cleanup()
+#define tc_frob_label(sym) do {\
+ d10v_cleanup(); \
+ S_SET_VALUE (sym, (valueT) frag_now_fix ()); \
+} while (0)
+
+#define obj_fix_adjustable(fixP) d10v_fix_adjustable(fixP)
+#define TC_FORCE_RELOCATION(fixp) d10v_force_relocation(fixp)
+extern int d10v_force_relocation PARAMS ((struct fix *));
+
diff --git a/gas/config/tc-d30v.c b/gas/config/tc-d30v.c
new file mode 100644
index 00000000000..c5033ba33f9
--- /dev/null
+++ b/gas/config/tc-d30v.c
@@ -0,0 +1,2218 @@
+/* tc-d30v.c -- Assembler code for the Mitsubishi D30V
+
+ Copyright (C) 1997, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/d30v.h"
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = "";
+const char *md_shortopts = "OnNcC";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+#define NOP_MULTIPLY 1
+#define NOP_ALL 2
+static int warn_nops = 0;
+static int Optimizing = 0;
+static int warn_register_name_conflicts = 1;
+
+#define FORCE_SHORT 1
+#define FORCE_LONG 2
+
+/* EXEC types. */
+typedef enum _exec_type
+{
+ EXEC_UNKNOWN, /* no order specified */
+ EXEC_PARALLEL, /* done in parallel (FM=00) */
+ EXEC_SEQ, /* sequential (FM=01) */
+ EXEC_REVSEQ /* reverse sequential (FM=10) */
+} exec_type_enum;
+
+/* fixups */
+#define MAX_INSN_FIXUPS (5)
+struct d30v_fixup
+{
+ expressionS exp;
+ int operand;
+ int pcrel;
+ int size;
+ bfd_reloc_code_real_type reloc;
+};
+
+typedef struct _fixups
+{
+ int fc;
+ struct d30v_fixup fix[MAX_INSN_FIXUPS];
+ struct _fixups *next;
+} Fixups;
+
+static Fixups FixUps[2];
+static Fixups *fixups;
+
+/* Whether current and previous instruction are word multiply insns. */
+static int cur_mul32_p = 0;
+static int prev_mul32_p = 0;
+
+/* The flag_explicitly_parallel is true iff the instruction being assembled
+ has been explicitly written as a parallel short-instruction pair by the
+ human programmer. It is used in parallel_ok() to distinguish between
+ those dangerous parallelizations attempted by the human, which are to be
+ allowed, and those attempted by the assembler, which are not. It is set
+ from md_assemble(). */
+static int flag_explicitly_parallel = 0;
+static int flag_xp_state = 0;
+
+/* Whether current and previous left sub-instruction disables
+ execution of right sub-instruction. */
+static int cur_left_kills_right_p = 0;
+static int prev_left_kills_right_p = 0;
+
+/* The known current alignment of the current section. */
+static int d30v_current_align;
+static segT d30v_current_align_seg;
+
+/* The last seen label in the current section. This is used to auto-align
+ labels preceeding instructions. */
+static symbolS *d30v_last_label;
+
+/* Two nops */
+#define NOP_LEFT ((long long) NOP << 32)
+#define NOP_RIGHT ((long long) NOP)
+#define NOP2 (FM00 | NOP_LEFT | NOP_RIGHT)
+
+/* local functions */
+static int reg_name_search PARAMS ((char *name));
+static int register_name PARAMS ((expressionS *expressionP));
+static int check_range PARAMS ((unsigned long num, int bits, int flags));
+static int postfix PARAMS ((char *p));
+static bfd_reloc_code_real_type get_reloc PARAMS ((struct d30v_operand *op, int rel_flag));
+static int get_operands PARAMS ((expressionS exp[], int cmp_hack));
+static struct d30v_format *find_format PARAMS ((struct d30v_opcode *opcode,
+ expressionS ops[],int fsize, int cmp_hack));
+static long long build_insn PARAMS ((struct d30v_insn *opcode, expressionS *opers));
+static void write_long PARAMS ((struct d30v_insn *opcode, long long insn, Fixups *fx));
+static void write_1_short PARAMS ((struct d30v_insn *opcode, long long insn,
+ Fixups *fx, int use_sequential));
+static int write_2_short PARAMS ((struct d30v_insn *opcode1, long long insn1,
+ struct d30v_insn *opcode2, long long insn2, exec_type_enum exec_type, Fixups *fx));
+static long long do_assemble PARAMS ((char *str, struct d30v_insn *opcode,
+ int shortp, int is_parallel));
+static int parallel_ok PARAMS ((struct d30v_insn *opcode1, unsigned long insn1,
+ struct d30v_insn *opcode2, unsigned long insn2,
+ exec_type_enum exec_type));
+static void d30v_number_to_chars PARAMS ((char *buf, long long value, int nbytes));
+static void check_size PARAMS ((long value, int bits, char *file, int line));
+static void d30v_align PARAMS ((int, char *, symbolS *));
+static void s_d30v_align PARAMS ((int));
+static void s_d30v_text PARAMS ((int));
+static void s_d30v_data PARAMS ((int));
+static void s_d30v_section PARAMS ((int));
+
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "word", cons, 4 },
+ { "hword", cons, 2 },
+ { "align", s_d30v_align, 0 },
+ { "text", s_d30v_text, 0 },
+ { "data", s_d30v_data, 0 },
+ { "section", s_d30v_section, 0 },
+ { "section.s", s_d30v_section, 0 },
+ { "sect", s_d30v_section, 0 },
+ { "sect.s", s_d30v_section, 0 },
+ { NULL, NULL, 0 }
+};
+
+/* Opcode hash table. */
+static struct hash_control *d30v_hash;
+
+/* reg_name_search does a binary search of the pre_defined_registers
+ array to see if "name" is a valid regiter name. Returns the register
+ number from the array on success, or -1 on failure. */
+
+static int
+reg_name_search (name)
+ char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = reg_name_cnt () - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, pre_defined_registers[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ {
+ if (symbol_find (name) != NULL)
+ {
+ if (warn_register_name_conflicts)
+ as_warn (_("Register name %s conflicts with symbol of the same name"),
+ name);
+ }
+
+ return pre_defined_registers[middle].value;
+ }
+ }
+ while (low <= high);
+
+ return -1;
+}
+
+/* register_name() checks the string at input_line_pointer
+ to see if it is a valid register name. */
+
+static int
+register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char c, *p = input_line_pointer;
+
+ while (*p && *p!='\n' && *p!='\r' && *p !=',' && *p!=' ' && *p!=')')
+ p++;
+
+ c = *p;
+ if (c)
+ *p++ = 0;
+
+ /* look to see if it's in the register table */
+ reg_number = reg_name_search (input_line_pointer);
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ /* temporarily store a pointer to the string here */
+ expressionP->X_op_symbol = (struct symbol *)input_line_pointer;
+ expressionP->X_add_number = reg_number;
+ input_line_pointer = p;
+ return 1;
+ }
+ if (c)
+ *(p-1) = c;
+ return 0;
+}
+
+
+static int
+check_range (num, bits, flags)
+ unsigned long num;
+ int bits;
+ int flags;
+{
+ long min, max;
+ int retval=0;
+
+ /* don't bother checking 32-bit values */
+ if (bits == 32)
+ return 0;
+
+ if (flags & OPERAND_SHIFT)
+ {
+ /* We know that all shifts are right by three bits.... */
+
+ if (flags & OPERAND_SIGNED)
+ num = (unsigned long) (((/*signed*/ long) num) >> 3);
+ else
+ num >>= 3;
+ }
+
+ if (flags & OPERAND_SIGNED)
+ {
+ max = (1 << (bits - 1))-1;
+ min = - (1 << (bits - 1));
+ if (((long)num > max) || ((long)num < min))
+ retval = 1;
+ }
+ else
+ {
+ max = (1 << bits) - 1;
+ min = 0;
+ if ((num > max) || (num < min))
+ retval = 1;
+ }
+
+ return retval;
+}
+
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\nD30V options:\n\
+-O Make adjacent short instructions parallel if possible.\n\
+-n Warn about all NOPs inserted by the assembler.\n\
+-N Warn about NOPs inserted after word multiplies.\n\
+-c Warn about symbols whoes names match register names.\n\
+-C Opposite of -C. -c is the default.\n"));
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ /* Optimize. Will attempt to parallelize operations */
+ case 'O':
+ Optimizing = 1;
+ break;
+
+ /* Warn about all NOPS that the assembler inserts. */
+ case 'n':
+ warn_nops = NOP_ALL;
+ break;
+
+ /* Warn about the NOPS that the assembler inserts because of the
+ multiply hazard. */
+ case 'N':
+ warn_nops = NOP_MULTIPLY;
+ break;
+
+ case 'c':
+ warn_register_name_conflicts = 1;
+ break;
+
+ case 'C':
+ warn_register_name_conflicts = 0;
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+ case 'd':
+ prec = 4;
+ break;
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * 2;
+
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ return NULL;
+}
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ asection *sec;
+ fragS *fragP;
+{
+ abort ();
+}
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+
+void
+md_begin ()
+{
+ struct d30v_opcode * opcode;
+ d30v_hash = hash_new ();
+
+ /* Insert opcode names into a hash table. */
+ for (opcode = (struct d30v_opcode *)d30v_opcode_table; opcode->name; opcode++)
+ hash_insert (d30v_hash, opcode->name, (char *) opcode);
+
+ fixups = &FixUps[0];
+ FixUps[0].next = &FixUps[1];
+ FixUps[1].next = &FixUps[0];
+
+ d30v_current_align_seg = now_seg;
+}
+
+
+/* this function removes the postincrement or postdecrement
+ operator ( '+' or '-' ) from an expression */
+
+static int postfix (p)
+ char *p;
+{
+ while (*p != '-' && *p != '+')
+ {
+ if (*p==0 || *p=='\n' || *p=='\r' || *p==' ' || *p==',')
+ break;
+ p++;
+ }
+
+ if (*p == '-')
+ {
+ *p = ' ';
+ return (-1);
+ }
+ if (*p == '+')
+ {
+ *p = ' ';
+ return (1);
+ }
+
+ return (0);
+}
+
+
+static bfd_reloc_code_real_type
+get_reloc (op, rel_flag)
+ struct d30v_operand *op;
+ int rel_flag;
+{
+ switch (op->bits)
+ {
+ case 6:
+ if (op->flags & OPERAND_SHIFT)
+ return BFD_RELOC_D30V_9_PCREL;
+ else
+ return BFD_RELOC_D30V_6;
+ break;
+ case 12:
+ if (!(op->flags & OPERAND_SHIFT))
+ as_warn (_("unexpected 12-bit reloc type"));
+ if (rel_flag == RELOC_PCREL)
+ return BFD_RELOC_D30V_15_PCREL;
+ else
+ return BFD_RELOC_D30V_15;
+ case 18:
+ if (!(op->flags & OPERAND_SHIFT))
+ as_warn (_("unexpected 18-bit reloc type"));
+ if (rel_flag == RELOC_PCREL)
+ return BFD_RELOC_D30V_21_PCREL;
+ else
+ return BFD_RELOC_D30V_21;
+ case 32:
+ if (rel_flag == RELOC_PCREL)
+ return BFD_RELOC_D30V_32_PCREL;
+ else
+ return BFD_RELOC_D30V_32;
+ default:
+ return 0;
+ }
+}
+
+/* get_operands parses a string of operands and returns
+ an array of expressions */
+
+static int
+get_operands (exp, cmp_hack)
+ expressionS exp[];
+ int cmp_hack;
+{
+ char *p = input_line_pointer;
+ int numops = 0;
+ int post = 0;
+
+ if (cmp_hack)
+ {
+ exp[numops].X_op = O_absent;
+ exp[numops++].X_add_number = cmp_hack - 1;
+ }
+
+ while (*p)
+ {
+ while (*p == ' ' || *p == '\t' || *p == ',')
+ p++;
+ if (*p==0 || *p=='\n' || *p=='\r')
+ break;
+
+ if (*p == '@')
+ {
+ p++;
+ exp[numops].X_op = O_absent;
+ if (*p == '(')
+ {
+ p++;
+ exp[numops].X_add_number = OPERAND_ATPAR;
+ post = postfix (p);
+ }
+ else if (*p == '-')
+ {
+ p++;
+ exp[numops].X_add_number = OPERAND_ATMINUS;
+ }
+ else
+ {
+ exp[numops].X_add_number = OPERAND_ATSIGN;
+ post = postfix (p);
+ }
+ numops++;
+ continue;
+ }
+
+ if (*p == ')')
+ {
+ /* just skip the trailing paren */
+ p++;
+ continue;
+ }
+
+ input_line_pointer = p;
+
+ /* check to see if it might be a register name */
+ if (!register_name (&exp[numops]))
+ {
+ /* parse as an expression */
+ expression (&exp[numops]);
+ }
+
+ if (exp[numops].X_op == O_illegal)
+ as_bad (_("illegal operand"));
+ else if (exp[numops].X_op == O_absent)
+ as_bad (_("missing operand"));
+
+ numops++;
+ p = input_line_pointer;
+
+ switch (post)
+ {
+ case -1: /* postdecrement mode */
+ exp[numops].X_op = O_absent;
+ exp[numops++].X_add_number = OPERAND_MINUS;
+ break;
+ case 1: /* postincrement mode */
+ exp[numops].X_op = O_absent;
+ exp[numops++].X_add_number = OPERAND_PLUS;
+ break;
+ }
+ post = 0;
+ }
+
+ exp[numops].X_op = 0;
+ return (numops);
+}
+
+/* build_insn generates the instruction. It does everything */
+/* but write the FM bits. */
+
+static long long
+build_insn (opcode, opers)
+ struct d30v_insn *opcode;
+ expressionS *opers;
+{
+ int i, length, bits, shift, flags;
+ unsigned int number, id=0;
+ long long insn;
+ struct d30v_opcode *op = opcode->op;
+ struct d30v_format *form = opcode->form;
+
+ insn = opcode->ecc << 28 | op->op1 << 25 | op->op2 << 20 | form->modifier << 18;
+
+ for (i=0; form->operands[i]; i++)
+ {
+ flags = d30v_operand_table[form->operands[i]].flags;
+
+ /* must be a register or number */
+ if (!(flags & OPERAND_REG) && !(flags & OPERAND_NUM) &&
+ !(flags & OPERAND_NAME) && !(flags & OPERAND_SPECIAL))
+ continue;
+
+ bits = d30v_operand_table[form->operands[i]].bits;
+ if (flags & OPERAND_SHIFT)
+ bits += 3;
+
+ length = d30v_operand_table[form->operands[i]].length;
+ shift = 12 - d30v_operand_table[form->operands[i]].position;
+ if (opers[i].X_op != O_symbol)
+ number = opers[i].X_add_number;
+ else
+ number = 0;
+ if (flags & OPERAND_REG)
+ {
+ /* check for mvfsys or mvtsys control registers */
+ if (flags & OPERAND_CONTROL && (number & 0x7f) > MAX_CONTROL_REG)
+ {
+ /* PSWL or PSWH */
+ id = (number & 0x7f) - MAX_CONTROL_REG;
+ number = 0;
+ }
+ else if (number & OPERAND_FLAG)
+ {
+ id = 3; /* number is a flag register */
+ }
+ number &= 0x7F;
+ }
+ else if (flags & OPERAND_SPECIAL)
+ {
+ number = id;
+ }
+
+ if (opers[i].X_op != O_register && opers[i].X_op != O_constant && !(flags & OPERAND_NAME))
+ {
+ /* now create a fixup */
+
+ if (fixups->fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups->fix[fixups->fc].reloc =
+ get_reloc ((struct d30v_operand *)&d30v_operand_table[form->operands[i]], op->reloc_flag);
+ fixups->fix[fixups->fc].size = 4;
+ fixups->fix[fixups->fc].exp = opers[i];
+ fixups->fix[fixups->fc].operand = form->operands[i];
+ if (fixups->fix[fixups->fc].reloc == BFD_RELOC_D30V_9_PCREL)
+ fixups->fix[fixups->fc].pcrel = RELOC_PCREL;
+ else
+ fixups->fix[fixups->fc].pcrel = op->reloc_flag;
+ (fixups->fc)++;
+ }
+
+ /* truncate to the proper number of bits */
+ if ((opers[i].X_op == O_constant) && check_range (number, bits, flags))
+ as_bad (_("operand out of range: %d"),number);
+ if (bits < 31)
+ number &= 0x7FFFFFFF >> (31 - bits);
+ if (flags & OPERAND_SHIFT)
+ number >>= 3;
+ if (bits == 32)
+ {
+ /* it's a LONG instruction */
+ insn |= (number >> 26); /* top 6 bits */
+ insn <<= 32; /* shift the first word over */
+ insn |= ((number & 0x03FC0000) << 2); /* next 8 bits */
+ insn |= number & 0x0003FFFF; /* bottom 18 bits */
+ }
+ else
+ insn |= number << shift;
+ }
+ return insn;
+}
+
+
+/* write out a long form instruction */
+static void
+write_long (opcode, insn, fx)
+ struct d30v_insn *opcode;
+ long long insn;
+ Fixups *fx;
+{
+ int i, where;
+ char *f = frag_more (8);
+
+ insn |= FM11;
+ d30v_number_to_chars (f, insn, 8);
+
+ for (i=0; i < fx->fc; i++)
+ {
+ if (fx->fix[i].reloc)
+ {
+ where = f - frag_now->fr_literal;
+ fix_new_exp (frag_now,
+ where,
+ fx->fix[i].size,
+ &(fx->fix[i].exp),
+ fx->fix[i].pcrel,
+ fx->fix[i].reloc);
+ }
+ }
+ fx->fc = 0;
+}
+
+
+/* Write out a short form instruction by itself. */
+static void
+write_1_short (opcode, insn, fx, use_sequential)
+ struct d30v_insn *opcode;
+ long long insn;
+ Fixups *fx;
+ int use_sequential;
+{
+ char *f = frag_more (8);
+ int i, where;
+
+ if (warn_nops == NOP_ALL)
+ as_warn (_("%s NOP inserted"), use_sequential ?
+ _("sequential") : _("parallel"));
+
+ /* The other container needs to be NOP. */
+ if (use_sequential)
+ {
+ /* Use a sequential NOP rather than a parallel one,
+ as the current instruction is a FLAG_MUL32 type one
+ and the next instruction is a load. */
+
+ /* According to 4.3.1: for FM=01, sub-instructions performed
+ only by IU cannot be encoded in L-container. */
+
+ if (opcode->op->unit == IU)
+ insn |= FM10 | NOP_LEFT; /* right then left */
+ else
+ insn = FM01 | (insn << 32) | NOP_RIGHT; /* left then right */
+ }
+ else
+ {
+ /* According to 4.3.1: for FM=00, sub-instructions performed
+ only by IU cannot be encoded in L-container. */
+
+ if (opcode->op->unit == IU)
+ insn |= FM00 | NOP_LEFT; /* right container */
+ else
+ insn = FM00 | (insn << 32) | NOP_RIGHT; /* left container */
+ }
+
+ d30v_number_to_chars (f, insn, 8);
+
+ for (i=0; i < fx->fc; i++)
+ {
+ if (fx->fix[i].reloc)
+ {
+ where = f - frag_now->fr_literal;
+ fix_new_exp (frag_now,
+ where,
+ fx->fix[i].size,
+ &(fx->fix[i].exp),
+ fx->fix[i].pcrel,
+ fx->fix[i].reloc);
+ }
+ }
+ fx->fc = 0;
+}
+
+/* Write out a short form instruction if possible.
+ Return number of instructions not written out. */
+static int
+write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
+ struct d30v_insn *opcode1, *opcode2;
+ long long insn1, insn2;
+ exec_type_enum exec_type;
+ Fixups *fx;
+{
+ long long insn = NOP2;
+ char *f;
+ int i,j, where;
+
+ if (exec_type == EXEC_SEQ
+ && (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR))
+ && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
+ && ((opcode1->ecc == ECC_AL) || ! Optimizing))
+ {
+ /* Unconditional, non-delayed branches kill instructions in
+ the right bin. Conditional branches don't always but if
+ we are not optimizing, then we have been asked to produce
+ an error about such constructs. For the purposes of this
+ test, subroutine calls are considered to be branches. */
+ write_1_short (opcode1, insn1, fx->next, false);
+ return 1;
+ }
+
+ /* Note: we do not have to worry about subroutine calls occuring
+ in the right hand container. The return address is always
+ aligned to the next 64 bit boundary, be that 64 or 32 bit away. */
+
+ switch (exec_type)
+ {
+ case EXEC_UNKNOWN: /* Order not specified. */
+ if (Optimizing
+ && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)
+ && ! ( (opcode1->op->unit == EITHER_BUT_PREFER_MU
+ || opcode1->op->unit == MU)
+ &&
+ ( opcode2->op->unit == EITHER_BUT_PREFER_MU
+ || opcode2->op->unit == MU)))
+ {
+ /* parallel */
+ exec_type = EXEC_PARALLEL;
+
+ if (opcode1->op->unit == IU
+ || opcode2->op->unit == MU
+ || opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ insn = FM00 | (insn2 << 32) | insn1;
+ else
+ {
+ insn = FM00 | (insn1 << 32) | insn2;
+ fx = fx->next;
+ }
+ }
+ else if (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR)
+ && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
+ && ((opcode1->ecc == ECC_AL) || ! Optimizing))
+ {
+ /* We must emit (non-delayed) branch type instructions
+ on their own with nothing in the right container. */
+ write_1_short (opcode1, insn1, fx->next, false);
+ return 1;
+ }
+ else if (prev_left_kills_right_p)
+ {
+ /* The left instruction kils the right slot, so we
+ must leave it empty. */
+ write_1_short (opcode1, insn1, fx->next, false);
+ return 1;
+ }
+ else if (opcode1->op->unit == IU
+ || (opcode1->op->unit == EITHER
+ && opcode2->op->unit == EITHER_BUT_PREFER_MU))
+ {
+ /* reverse sequential */
+ insn = FM10 | (insn2 << 32) | insn1;
+ exec_type = EXEC_REVSEQ;
+ }
+ else
+ {
+ /* sequential */
+ insn = FM01 | (insn1 << 32) | insn2;
+ fx = fx->next;
+ exec_type = EXEC_SEQ;
+ }
+ break;
+
+ case EXEC_PARALLEL: /* parallel */
+ flag_explicitly_parallel = flag_xp_state;
+ if (! parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
+ as_bad (_("Instructions may not be executed in parallel"));
+ else if (opcode1->op->unit == IU)
+ {
+ if (opcode2->op->unit == IU)
+ as_bad (_("Two IU instructions may not be executed in parallel"));
+ as_warn (_("Swapping instruction order"));
+ insn = FM00 | (insn2 << 32) | insn1;
+ }
+ else if (opcode2->op->unit == MU)
+ {
+ if (opcode1->op->unit == MU)
+ as_bad (_("Two MU instructions may not be executed in parallel"));
+ else if (opcode1->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode1->op->name);
+ as_warn (_("Swapping instruction order"));
+ insn = FM00 | (insn2 << 32) | insn1;
+ }
+ else
+ {
+ if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode2->op->name);
+
+ insn = FM00 | (insn1 << 32) | insn2;
+ fx = fx->next;
+ }
+ flag_explicitly_parallel = 0;
+ break;
+
+ case EXEC_SEQ: /* sequential */
+ if (opcode1->op->unit == IU)
+ as_bad (_("IU instruction may not be in the left container"));
+ if (prev_left_kills_right_p)
+ as_bad (_("special left instruction `%s' kills instruction "
+ "`%s' in right container"),
+ opcode1->op->name, opcode2->op->name);
+ if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode2->op->name);
+ insn = FM01 | (insn1 << 32) | insn2;
+ fx = fx->next;
+ break;
+
+ case EXEC_REVSEQ: /* reverse sequential */
+ if (opcode2->op->unit == MU)
+ as_bad (_("MU instruction may not be in the right container"));
+ if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
+ as_warn (_("Executing %s in IU may not work"), opcode2->op->name);
+ insn = FM10 | (insn1 << 32) | insn2;
+ fx = fx->next;
+ break;
+
+ default:
+ as_fatal (_("unknown execution type passed to write_2_short()"));
+ }
+
+ /* printf ("writing out %llx\n",insn); */
+ f = frag_more (8);
+ d30v_number_to_chars (f, insn, 8);
+
+ /* If the previous instruction was a 32-bit multiply but it is put into a
+ parallel container, mark the current instruction as being a 32-bit
+ multiply. */
+ if (prev_mul32_p && exec_type == EXEC_PARALLEL)
+ cur_mul32_p = 1;
+
+ for (j=0; j<2; j++)
+ {
+ for (i=0; i < fx->fc; i++)
+ {
+ if (fx->fix[i].reloc)
+ {
+ where = (f - frag_now->fr_literal) + 4*j;
+
+ fix_new_exp (frag_now,
+ where,
+ fx->fix[i].size,
+ &(fx->fix[i].exp),
+ fx->fix[i].pcrel,
+ fx->fix[i].reloc);
+ }
+ }
+
+ fx->fc = 0;
+ fx = fx->next;
+ }
+
+ return 0;
+}
+
+
+/* Check 2 instructions and determine if they can be safely */
+/* executed in parallel. Returns 1 if they can be. */
+static int
+parallel_ok (op1, insn1, op2, insn2, exec_type)
+ struct d30v_insn *op1, *op2;
+ unsigned long insn1, insn2;
+ exec_type_enum exec_type;
+{
+ int i, j, shift, regno, bits, ecc;
+ unsigned long flags, mask, flags_set1, flags_set2, flags_used1, flags_used2;
+ unsigned long ins, mod_reg[2][3], used_reg[2][3], flag_reg[2];
+ struct d30v_format *f;
+ struct d30v_opcode *op;
+
+ /* section 4.3: both instructions must not be IU or MU only */
+ if ((op1->op->unit == IU && op2->op->unit == IU)
+ || (op1->op->unit == MU && op2->op->unit == MU))
+ return 0;
+
+ /* first instruction must not be a jump to safely optimize, unless this
+ is an explicit parallel operation. */
+ if (exec_type != EXEC_PARALLEL
+ && (op1->op->flags_used & (FLAG_JMP | FLAG_JSR)))
+ return 0;
+
+ /* If one instruction is /TX or /XT and the other is /FX or /XF respectively,
+ then it is safe to allow the two to be done as parallel ops, since only
+ one will ever be executed at a time. */
+ if ((op1->ecc == ECC_TX && op2->ecc == ECC_FX)
+ || (op1->ecc == ECC_FX && op2->ecc == ECC_TX)
+ || (op1->ecc == ECC_XT && op2->ecc == ECC_XF)
+ || (op1->ecc == ECC_XF && op2->ecc == ECC_XT))
+ return 1;
+
+ /* [0] r0-r31
+ [1] r32-r63
+ [2] a0, a1, flag registers */
+
+ for (j = 0; j < 2; j++)
+ {
+ if (j == 0)
+ {
+ f = op1->form;
+ op = op1->op;
+ ecc = op1->ecc;
+ ins = insn1;
+ }
+ else
+ {
+ f = op2->form;
+ op = op2->op;
+ ecc = op2->ecc;
+ ins = insn2;
+ }
+ flag_reg[j] = 0;
+ mod_reg[j][0] = mod_reg[j][1] = 0;
+ used_reg[j][0] = used_reg[j][1] = 0;
+
+ if (flag_explicitly_parallel)
+ {
+ /* For human specified parallel instructions we have been asked
+ to ignore the possibility that both instructions could modify
+ bits in the PSW, so we initialise the mod & used arrays to 0.
+ We have been asked, however, to refuse to allow parallel
+ instructions which explicitly set the same flag register,
+ eg "cmpne f0,r1,0x10 || cmpeq f0, r5, 0x2", so further on we test
+ for the use of a flag register and set a bit in the mod or used
+ array appropriately. */
+
+ mod_reg[j][2] = 0;
+ used_reg[j][2] = 0;
+ }
+ else
+ {
+ mod_reg[j][2] = (op->flags_set & FLAG_ALL);
+ used_reg[j][2] = (op->flags_used & FLAG_ALL);
+ }
+
+ /* BSR/JSR always sets R62 */
+ if (op->flags_used & FLAG_JSR)
+ mod_reg[j][1] = (1L << (62-32));
+
+ /* conditional execution affects the flags_used */
+ switch (ecc)
+ {
+ case ECC_TX:
+ case ECC_FX:
+ used_reg[j][2] |= flag_reg[j] = FLAG_0;
+ break;
+
+ case ECC_XT:
+ case ECC_XF:
+ used_reg[j][2] |= flag_reg[j] = FLAG_1;
+ break;
+
+ case ECC_TT:
+ case ECC_TF:
+ used_reg[j][2] |= flag_reg[j] = (FLAG_0 | FLAG_1);
+ break;
+ }
+
+ for (i = 0; f->operands[i]; i++)
+ {
+ flags = d30v_operand_table[f->operands[i]].flags;
+ shift = 12 - d30v_operand_table[f->operands[i]].position;
+ bits = d30v_operand_table[f->operands[i]].bits;
+ if (bits == 32)
+ mask = 0xffffffff;
+ else
+ mask = 0x7FFFFFFF >> (31 - bits);
+
+ if ((flags & OPERAND_PLUS) || (flags & OPERAND_MINUS))
+ {
+ /* this is a post-increment or post-decrement */
+ /* the previous register needs to be marked as modified */
+
+ shift = 12 - d30v_operand_table[f->operands[i-1]].position;
+ regno = (ins >> shift) & 0x3f;
+ if (regno >= 32)
+ mod_reg[j][1] |= 1L << (regno - 32);
+ else
+ mod_reg[j][0] |= 1L << regno;
+ }
+ else if (flags & OPERAND_REG)
+ {
+ regno = (ins >> shift) & mask;
+ /* the memory write functions don't have a destination register */
+ if ((flags & OPERAND_DEST) && !(op->flags_set & FLAG_MEM))
+ {
+ /* MODIFIED registers and flags */
+ if (flags & OPERAND_ACC)
+ {
+ if (regno == 0)
+ mod_reg[j][2] |= FLAG_A0;
+ else if (regno == 1)
+ mod_reg[j][2] |= FLAG_A1;
+ else
+ abort ();
+ }
+ else if (flags & OPERAND_FLAG)
+ mod_reg[j][2] |= 1L << regno;
+ else if (!(flags & OPERAND_CONTROL))
+ {
+ int r, z;
+
+ /* need to check if there are two destination */
+ /* registers, for example ld2w */
+ if (flags & OPERAND_2REG)
+ z = 1;
+ else
+ z = 0;
+
+ for (r = regno; r <= regno + z; r++)
+ {
+ if (r >= 32)
+ mod_reg[j][1] |= 1L << (r - 32);
+ else
+ mod_reg[j][0] |= 1L << r;
+ }
+ }
+ }
+ else
+ {
+ /* USED, but not modified registers and flags */
+ if (flags & OPERAND_ACC)
+ {
+ if (regno == 0)
+ used_reg[j][2] |= FLAG_A0;
+ else if (regno == 1)
+ used_reg[j][2] |= FLAG_A1;
+ else
+ abort ();
+ }
+ else if (flags & OPERAND_FLAG)
+ used_reg[j][2] |= 1L << regno;
+ else if (!(flags & OPERAND_CONTROL))
+ {
+ int r, z;
+
+ /* need to check if there are two source */
+ /* registers, for example st2w */
+ if (flags & OPERAND_2REG)
+ z = 1;
+ else
+ z = 0;
+
+ for (r = regno; r <= regno + z; r++)
+ {
+ if (r >= 32)
+ used_reg[j][1] |= 1L << (r - 32);
+ else
+ used_reg[j][0] |= 1L << r;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ flags_set1 = op1->op->flags_set;
+ flags_set2 = op2->op->flags_set;
+ flags_used1 = op1->op->flags_used;
+ flags_used2 = op2->op->flags_used;
+
+ /* ST2W/ST4HB combined with ADDppp/SUBppp is illegal. */
+ if (((flags_set1 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD)
+ && (flags_used2 & FLAG_ADDSUBppp) != 0)
+ || ((flags_set2 & (FLAG_MEM | FLAG_2WORD)) == (FLAG_MEM | FLAG_2WORD)
+ && (flags_used1 & FLAG_ADDSUBppp) != 0))
+ return 0;
+
+ /* Load instruction combined with half-word multiply is illegal. */
+ if (((flags_used1 & FLAG_MEM) != 0 && (flags_used2 & FLAG_MUL16))
+ || ((flags_used2 & FLAG_MEM) != 0 && (flags_used1 & FLAG_MUL16)))
+ return 0;
+
+ /* Specifically allow add || add by removing carry, overflow bits dependency.
+ This is safe, even if an addc follows since the IU takes the argument in
+ the right container, and it writes its results last.
+ However, don't paralellize add followed by addc or sub followed by
+ subb. */
+
+ if (mod_reg[0][2] == FLAG_CVVA && mod_reg[1][2] == FLAG_CVVA
+ && (used_reg[0][2] & ~flag_reg[0]) == 0
+ && (used_reg[1][2] & ~flag_reg[1]) == 0
+ && op1->op->unit == EITHER && op2->op->unit == EITHER)
+ {
+ mod_reg[0][2] = mod_reg[1][2] = 0;
+ }
+
+ for (j = 0; j < 3; j++)
+ {
+ /* If the second instruction depends on the first, we obviously
+ cannot parallelize. Note, the mod flag implies use, so
+ check that as well. */
+ /* If flag_explicitly_parallel is set, then the case of the
+ second instruction using a register the first instruction
+ modifies is assumed to be okay; we trust the human. We
+ don't trust the human if both instructions modify the same
+ register but we do trust the human if they modify the same
+ flags. */
+ /* We have now been requested not to trust the human if the
+ instructions modify the same flag registers either. */
+ if (flag_explicitly_parallel)
+ {
+ if ((mod_reg[0][j] & mod_reg[1][j]) != 0)
+ return 0;
+ }
+ else
+ if ((mod_reg[0][j] & (mod_reg[1][j] | used_reg[1][j])) != 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* This is the main entry point for the machine-dependent assembler. str points to a
+ machine-dependent instruction. This function is supposed to emit the frags/bytes
+ it assembles to. For the D30V, it mostly handles the special VLIW parsing and packing
+ and leaves the difficult stuff to do_assemble(). */
+
+static long long prev_insn = -1;
+static struct d30v_insn prev_opcode;
+static subsegT prev_subseg;
+static segT prev_seg = 0;
+
+void
+md_assemble (str)
+ char *str;
+{
+ struct d30v_insn opcode;
+ long long insn;
+ exec_type_enum extype = EXEC_UNKNOWN; /* execution type; parallel, etc */
+ static exec_type_enum etype = EXEC_UNKNOWN; /* saved extype. used for multiline instructions */
+ char *str2;
+
+ if ((prev_insn != -1) && prev_seg
+ && ((prev_seg != now_seg) || (prev_subseg != now_subseg)))
+ d30v_cleanup (false);
+
+ if (d30v_current_align < 3)
+ d30v_align (3, NULL, d30v_last_label);
+ else if (d30v_current_align > 3)
+ d30v_current_align = 3;
+ d30v_last_label = NULL;
+
+ flag_explicitly_parallel = 0;
+ flag_xp_state = 0;
+ if (etype == EXEC_UNKNOWN)
+ {
+ /* look for the special multiple instruction separators */
+ str2 = strstr (str, "||");
+ if (str2)
+ {
+ extype = EXEC_PARALLEL;
+ flag_xp_state = 1;
+ }
+ else
+ {
+ str2 = strstr (str, "->");
+ if (str2)
+ extype = EXEC_SEQ;
+ else
+ {
+ str2 = strstr (str, "<-");
+ if (str2)
+ extype = EXEC_REVSEQ;
+ }
+ }
+ /* str2 points to the separator, if one */
+ if (str2)
+ {
+ *str2 = 0;
+
+ /* if two instructions are present and we already have one saved
+ then first write it out */
+ d30v_cleanup (false);
+
+ /* Assemble first instruction and save it. */
+ prev_insn = do_assemble (str, &prev_opcode, 1, 0);
+ if (prev_insn == -1)
+ as_bad (_("Cannot assemble instruction"));
+ if (prev_opcode.form != NULL && prev_opcode.form->form >= LONG)
+ as_bad (_("First opcode is long. Unable to mix instructions as specified."));
+ fixups = fixups->next;
+ str = str2 + 2;
+ prev_seg = now_seg;
+ prev_subseg = now_subseg;
+ }
+ }
+
+ insn = do_assemble (str, &opcode,
+ (extype != EXEC_UNKNOWN || etype != EXEC_UNKNOWN),
+ extype == EXEC_PARALLEL);
+ if (insn == -1)
+ {
+ if (extype != EXEC_UNKNOWN)
+ etype = extype;
+ as_bad (_("Cannot assemble instruction"));
+ return;
+ }
+
+ if (etype != EXEC_UNKNOWN)
+ {
+ extype = etype;
+ etype = EXEC_UNKNOWN;
+ }
+
+ /* Word multiply instructions must not be followed by either a load or a
+ 16-bit multiply instruction in the next cycle. */
+ if ( (extype != EXEC_REVSEQ)
+ && prev_mul32_p
+ && (opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16)))
+ {
+ /* However, load and multiply should able to be combined in a parallel
+ operation, so check for that first. */
+ if (prev_insn != -1
+ && (opcode.op->flags_used & FLAG_MEM)
+ && opcode.form->form < LONG
+ && (extype == EXEC_PARALLEL || (Optimizing && extype == EXEC_UNKNOWN))
+ && parallel_ok (&prev_opcode, (long)prev_insn,
+ &opcode, (long)insn, extype)
+ && write_2_short (&prev_opcode, (long)prev_insn,
+ &opcode, (long)insn, extype, fixups) == 0)
+ {
+ /* no instructions saved */
+ prev_insn = -1;
+ return;
+ }
+ else
+ {
+ /* Can't parallelize, flush previous instruction and emit a word of NOPS,
+ unless the previous instruction is a NOP, in which case just flush it,
+ as this will generate a word of NOPs for us. */
+
+ if (prev_insn != -1 && (strcmp (prev_opcode.op->name, "nop") == 0))
+ d30v_cleanup (false);
+ else
+ {
+ char * f;
+
+ if (prev_insn != -1)
+ d30v_cleanup (true);
+ else
+ {
+ f = frag_more (8);
+ d30v_number_to_chars (f, NOP2, 8);
+
+ if (warn_nops == NOP_ALL || warn_nops == NOP_MULTIPLY)
+ {
+ if (opcode.op->flags_used & FLAG_MEM)
+ as_warn (_("word of NOPs added between word multiply and load"));
+ else
+ as_warn (_("word of NOPs added between word multiply and 16-bit multiply"));
+ }
+ }
+ }
+
+ extype = EXEC_UNKNOWN;
+ }
+ }
+ else if ( (extype == EXEC_REVSEQ)
+ && cur_mul32_p
+ && (prev_opcode.op->flags_used & (FLAG_MEM | FLAG_MUL16)))
+ {
+ /* Can't parallelize, flush current instruction and add a sequential NOP. */
+ write_1_short (& opcode, (long) insn, fixups->next->next, true);
+
+ /* Make the previous instruction the current one. */
+ extype = EXEC_UNKNOWN;
+ insn = prev_insn;
+ now_seg = prev_seg;
+ now_subseg = prev_subseg;
+ prev_insn = -1;
+ cur_mul32_p = prev_mul32_p;
+ prev_mul32_p = 0;
+ memcpy (&opcode, &prev_opcode, sizeof (prev_opcode));
+ }
+
+ /* If this is a long instruction, write it and any previous short instruction. */
+ if (opcode.form->form >= LONG)
+ {
+ if (extype != EXEC_UNKNOWN)
+ as_bad (_("Instruction uses long version, so it cannot be mixed as specified"));
+ d30v_cleanup (false);
+ write_long (& opcode, insn, fixups);
+ prev_insn = -1;
+ }
+ else if ((prev_insn != -1)
+ && (write_2_short
+ (& prev_opcode, (long) prev_insn, & opcode,
+ (long) insn, extype, fixups) == 0))
+ {
+ /* No instructions saved. */
+ prev_insn = -1;
+ }
+ else
+ {
+ if (extype != EXEC_UNKNOWN)
+ as_bad (_("Unable to mix instructions as specified"));
+
+ /* Save off last instruction so it may be packed on next pass. */
+ memcpy (&prev_opcode, &opcode, sizeof (prev_opcode));
+ prev_insn = insn;
+ prev_seg = now_seg;
+ prev_subseg = now_subseg;
+ fixups = fixups->next;
+ prev_mul32_p = cur_mul32_p;
+ }
+}
+
+
+/* do_assemble assembles a single instruction and returns an opcode */
+/* it returns -1 (an invalid opcode) on error */
+
+#define NAME_BUF_LEN 20
+
+static long long
+do_assemble (str, opcode, shortp, is_parallel)
+ char *str;
+ struct d30v_insn *opcode;
+ int shortp;
+ int is_parallel;
+{
+ unsigned char * op_start;
+ unsigned char * save;
+ unsigned char * op_end;
+ char name [NAME_BUF_LEN];
+ int cmp_hack;
+ int nlen = 0;
+ int fsize = (shortp ? FORCE_SHORT : 0);
+ expressionS myops [6];
+ long long insn;
+
+ /* Drop leading whitespace */
+ while (* str == ' ')
+ str ++;
+
+ /* find the opcode end */
+ for (op_start = op_end = (unsigned char *) (str);
+ * op_end
+ && nlen < (NAME_BUF_LEN - 1)
+ && * op_end != '/'
+ && !is_end_of_line[*op_end] && *op_end != ' ';
+ op_end++)
+ {
+ name[nlen] = tolower (op_start[nlen]);
+ nlen++;
+ }
+
+ if (nlen == 0)
+ return -1;
+
+ name[nlen] = 0;
+
+ /* if there is an execution condition code, handle it */
+ if (*op_end == '/')
+ {
+ int i = 0;
+ while ( (i < ECC_MAX) && strncasecmp (d30v_ecc_names[i], op_end + 1, 2))
+ i++;
+
+ if (i == ECC_MAX)
+ {
+ char tmp[4];
+ strncpy (tmp, op_end + 1, 2);
+ tmp[2] = 0;
+ as_bad (_("unknown condition code: %s"),tmp);
+ return -1;
+ }
+ /* printf ("condition code=%d\n",i); */
+ opcode->ecc = i;
+ op_end += 3;
+ }
+ else
+ opcode->ecc = ECC_AL;
+
+
+ /* CMP and CMPU change their name based on condition codes */
+ if (!strncmp (name, "cmp", 3))
+ {
+ int p,i;
+ char **str = (char **)d30v_cc_names;
+ if (name[3] == 'u')
+ p = 4;
+ else
+ p = 3;
+
+ for (i=1; *str && strncmp (*str, & name[p], 2); i++, str++)
+ ;
+
+ /* cmpu only supports some condition codes */
+ if (p == 4)
+ {
+ if (i < 3 || i > 6)
+ {
+ name[p+2]=0;
+ as_bad (_("cmpu doesn't support condition code %s"),&name[p]);
+ }
+ }
+
+ if (!*str)
+ {
+ name[p+2]=0;
+ as_bad (_("unknown condition code: %s"),&name[p]);
+ }
+
+ cmp_hack = i;
+ name[p] = 0;
+ }
+ else
+ cmp_hack = 0;
+
+ /* printf("cmp_hack=%d\n",cmp_hack); */
+
+ /* need to look for .s or .l */
+ if (name[nlen-2] == '.')
+ {
+ switch (name[nlen-1])
+ {
+ case 's':
+ fsize = FORCE_SHORT;
+ break;
+ case 'l':
+ fsize = FORCE_LONG;
+ break;
+ }
+ name[nlen-2] = 0;
+ }
+
+ /* find the first opcode with the proper name */
+ opcode->op = (struct d30v_opcode *)hash_find (d30v_hash, name);
+ if (opcode->op == NULL)
+ {
+ as_bad (_("unknown opcode: %s"),name);
+ return -1;
+ }
+
+ save = input_line_pointer;
+ input_line_pointer = op_end;
+ while (!(opcode->form = find_format (opcode->op, myops, fsize, cmp_hack)))
+ {
+ opcode->op++;
+ if (opcode->op->name == NULL || strcmp (opcode->op->name, name))
+ {
+ as_bad (_("operands for opcode `%s' do not match any valid format"), name);
+ return -1;
+ }
+ }
+ input_line_pointer = save;
+
+ insn = build_insn (opcode, myops);
+
+ /* Propigate multiply status */
+ if (insn != -1)
+ {
+ if (is_parallel && prev_mul32_p)
+ cur_mul32_p = 1;
+ else
+ {
+ prev_mul32_p = cur_mul32_p;
+ cur_mul32_p = (opcode->op->flags_used & FLAG_MUL32) != 0;
+ }
+ }
+
+ /* Propagate left_kills_right status */
+ if (insn != -1)
+ {
+ prev_left_kills_right_p = cur_left_kills_right_p;
+
+ if (opcode->op->flags_set & FLAG_LKR)
+ {
+ cur_left_kills_right_p = 1;
+
+ if (strcmp (opcode->op->name, "mvtsys") == 0)
+ {
+ /* Left kills right for only mvtsys only for PSW/PSWH/PSWL/flags target. */
+ if ((myops[0].X_op == O_register) &&
+ ((myops[0].X_add_number == OPERAND_CONTROL) || /* psw */
+ (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+2) || /* pswh */
+ (myops[0].X_add_number == OPERAND_CONTROL+MAX_CONTROL_REG+1) || /* pswl */
+ (myops[0].X_add_number == OPERAND_FLAG+0) || /* f0 */
+ (myops[0].X_add_number == OPERAND_FLAG+1) || /* f1 */
+ (myops[0].X_add_number == OPERAND_FLAG+2) || /* f2 */
+ (myops[0].X_add_number == OPERAND_FLAG+3) || /* f3 */
+ (myops[0].X_add_number == OPERAND_FLAG+4) || /* f4 */
+ (myops[0].X_add_number == OPERAND_FLAG+5) || /* f5 */
+ (myops[0].X_add_number == OPERAND_FLAG+6) || /* f6 */
+ (myops[0].X_add_number == OPERAND_FLAG+7))) /* f7 */
+ {
+ cur_left_kills_right_p = 1;
+ }
+ else
+ {
+ /* Other mvtsys target registers don't kill right instruction. */
+ cur_left_kills_right_p = 0;
+ }
+ } /* mvtsys */
+ }
+ else
+ cur_left_kills_right_p = 0;
+ }
+
+ return insn;
+}
+
+
+/* find_format() gets a pointer to an entry in the format table.
+ It must look at all formats for an opcode and use the operands
+ to choose the correct one. Returns NULL on error. */
+
+static struct d30v_format *
+find_format (opcode, myops, fsize, cmp_hack)
+ struct d30v_opcode *opcode;
+ expressionS myops[];
+ int fsize;
+ int cmp_hack;
+{
+ int numops, match, index, i=0, j, k;
+ struct d30v_format *fm;
+
+ if (opcode == NULL)
+ return NULL;
+
+ /* Get all the operands and save them as expressions. */
+ numops = get_operands (myops, cmp_hack);
+
+ while ((index = opcode->format[i++]) != 0)
+ {
+ if (fsize == FORCE_SHORT && index >= LONG)
+ continue;
+
+ if (fsize == FORCE_LONG && index < LONG)
+ continue;
+
+ fm = (struct d30v_format *)&d30v_format_table[index];
+ k = index;
+ while (fm->form == index)
+ {
+ match = 1;
+ /* Now check the operands for compatibility. */
+ for (j = 0; match && fm->operands[j]; j++)
+ {
+ int flags = d30v_operand_table[fm->operands[j]].flags;
+ int bits = d30v_operand_table[fm->operands[j]].bits;
+ int X_op = myops[j].X_op;
+ int num = myops[j].X_add_number;
+
+ if (flags & OPERAND_SPECIAL)
+ break;
+ else if (X_op == O_illegal)
+ match = 0;
+ else if (flags & OPERAND_REG)
+ {
+ if (X_op != O_register
+ || ((flags & OPERAND_ACC) && !(num & OPERAND_ACC))
+ || (!(flags & OPERAND_ACC) && (num & OPERAND_ACC))
+ || ((flags & OPERAND_FLAG) && !(num & OPERAND_FLAG))
+ || (!(flags & (OPERAND_FLAG | OPERAND_CONTROL)) && (num & OPERAND_FLAG))
+ || ((flags & OPERAND_CONTROL)
+ && !(num & (OPERAND_CONTROL | OPERAND_FLAG))))
+ {
+ match = 0;
+ }
+ }
+ else if (((flags & OPERAND_MINUS)
+ && (X_op != O_absent || num != OPERAND_MINUS))
+ || ((flags & OPERAND_PLUS)
+ && (X_op != O_absent || num != OPERAND_PLUS))
+ || ((flags & OPERAND_ATMINUS)
+ && (X_op != O_absent || num != OPERAND_ATMINUS))
+ || ((flags & OPERAND_ATPAR)
+ && (X_op != O_absent || num != OPERAND_ATPAR))
+ || ((flags & OPERAND_ATSIGN)
+ && (X_op != O_absent || num != OPERAND_ATSIGN)))
+ {
+ match=0;
+ }
+ else if (flags & OPERAND_NUM)
+ {
+ /* A number can be a constant or symbol expression. */
+
+ /* If we have found a register name, but that name also
+ matches a symbol, then re-parse the name as an expression. */
+ if (X_op == O_register
+ && symbol_find ((char *) myops[j].X_op_symbol))
+ {
+ input_line_pointer = (char *) myops[j].X_op_symbol;
+ expression (& myops[j]);
+ }
+
+ /* Turn an expression into a symbol for later resolution. */
+ if (X_op != O_absent && X_op != O_constant
+ && X_op != O_symbol && X_op != O_register
+ && X_op != O_big)
+ {
+ symbolS *sym = make_expr_symbol (&myops[j]);
+ myops[j].X_op = X_op = O_symbol;
+ myops[j].X_add_symbol = sym;
+ myops[j].X_add_number = num = 0;
+ }
+
+ if (fm->form >= LONG)
+ {
+ /* If we're testing for a LONG format, either fits. */
+ if (X_op != O_constant && X_op != O_symbol)
+ match = 0;
+ }
+ else if (fm->form < LONG
+ && ((fsize == FORCE_SHORT && X_op == O_symbol)
+ || (fm->form == SHORT_D2 && j == 0)))
+ match = 1;
+ /* This is the tricky part. Will the constant or symbol
+ fit into the space in the current format? */
+ else if (X_op == O_constant)
+ {
+ if (check_range (num, bits, flags))
+ match = 0;
+ }
+ else if (X_op == O_symbol
+ && S_IS_DEFINED (myops[j].X_add_symbol)
+ && S_GET_SEGMENT (myops[j].X_add_symbol) == now_seg
+ && opcode->reloc_flag == RELOC_PCREL)
+ {
+ /* If the symbol is defined, see if the value will fit
+ into the form we're considering. */
+ fragS *f;
+ long value;
+
+ /* Calculate the current address by running through the
+ previous frags and adding our current offset. */
+ value = 0;
+ for (f = frchain_now->frch_root; f; f = f->fr_next)
+ value += f->fr_fix + f->fr_offset;
+ value = (S_GET_VALUE (myops[j].X_add_symbol) - value
+ - (obstack_next_free (&frchain_now->frch_obstack)
+ - frag_now->fr_literal));
+ if (check_range (value, bits, flags))
+ match = 0;
+ }
+ else
+ match = 0;
+ }
+ }
+ /* printf("through the loop: match=%d\n",match); */
+ /* We're only done if the operands matched so far AND there
+ are no more to check. */
+ if (match && myops[j].X_op == 0)
+ {
+ /* Final check - issue a warning if an odd numbered register
+ is used as the first register in an instruction that reads
+ or writes 2 registers. */
+
+ for (j = 0; fm->operands[j]; j++)
+ if (myops[j].X_op == O_register
+ && (myops[j].X_add_number & 1)
+ && (d30v_operand_table[fm->operands[j]].flags & OPERAND_2REG))
+ as_warn (\
+_("Odd numbered register used as target of multi-register instruction"));
+
+ return fm;
+ }
+ fm = (struct d30v_format *)&d30v_format_table[++k];
+ }
+ /* printf("trying another format: i=%d\n",i); */
+ }
+ return NULL;
+}
+
+/* if while processing a fixup, a reloc really needs to be created */
+/* then it is done here */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg;
+ fixS *fixp;
+{
+ arelent *reloc;
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("reloc %d not supported by object file format"), (int)fixp->fx_r_type);
+ return NULL;
+ }
+ reloc->addend = fixp->fx_addnumber;
+ return reloc;
+}
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg;
+{
+ abort ();
+ return 0;
+}
+
+long
+md_pcrel_from_section (fixp, sec)
+ fixS *fixp;
+ segT sec;
+{
+ if (fixp->fx_addsy != (symbolS *)NULL && (!S_IS_DEFINED (fixp->fx_addsy) ||
+ (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
+ return 0;
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+int
+md_apply_fix3 (fixp, valuep, seg)
+ fixS * fixp;
+ valueT * valuep;
+ segT seg;
+{
+ char * where;
+ unsigned long insn, insn2;
+ long value;
+
+ if (fixp->fx_addsy == (symbolS *) NULL)
+ {
+ value = * valuep;
+ fixp->fx_done = 1;
+ }
+ else if (fixp->fx_pcrel)
+ value = * valuep;
+ else
+ {
+ value = fixp->fx_offset;
+
+ if (fixp->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixp->fx_subsy);
+ else
+ {
+ /* We don't actually support subtracting a symbol. */
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixp->fx_frag->fr_literal + fixp->fx_where;
+ insn = bfd_getb32 ((unsigned char *) where);
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8: /* Check for a bad .byte directive. */
+ if (fixp->fx_addsy != NULL)
+ as_bad (_("line %d: unable to place address of symbol '%s' into a byte"),
+ fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
+ else if (((unsigned)value) > 0xff)
+ as_bad (_("line %d: unable to place value %x into a byte"),
+ fixp->fx_line, value);
+ else
+ * (unsigned char *) where = value;
+ break;
+
+ case BFD_RELOC_16: /* Check for a bad .short directive. */
+ if (fixp->fx_addsy != NULL)
+ as_bad (_("line %d: unable to place address of symbol '%s' into a short"),
+ fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
+ else if (((unsigned)value) > 0xffff)
+ as_bad (_("line %d: unable to place value %x into a short"),
+ fixp->fx_line, value);
+ else
+ bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_64: /* Check for a bad .quad directive. */
+ if (fixp->fx_addsy != NULL)
+ as_bad (_("line %d: unable to place address of symbol '%s' into a quad"),
+ fixp->fx_line, S_GET_NAME (fixp->fx_addsy));
+ else
+ {
+ bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
+ bfd_putb32 (0, ((unsigned char *) where) + 4);
+ }
+ break;
+
+ case BFD_RELOC_D30V_6:
+ check_size (value, 6, fixp->fx_file, fixp->fx_line);
+ insn |= value & 0x3F;
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_D30V_9_PCREL:
+ if (fixp->fx_where & 0x7)
+ {
+ if (fixp->fx_done)
+ value += 4;
+ else
+ fixp->fx_r_type = BFD_RELOC_D30V_9_PCREL_R;
+ }
+ check_size (value, 9, fixp->fx_file, fixp->fx_line);
+ insn |= ((value >> 3) & 0x3F) << 12;
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_D30V_15:
+ check_size (value, 15, fixp->fx_file, fixp->fx_line);
+ insn |= (value >> 3) & 0xFFF;
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_D30V_15_PCREL:
+ if (fixp->fx_where & 0x7)
+ {
+ if (fixp->fx_done)
+ value += 4;
+ else
+ fixp->fx_r_type = BFD_RELOC_D30V_15_PCREL_R;
+ }
+ check_size (value, 15, fixp->fx_file, fixp->fx_line);
+ insn |= (value >> 3) & 0xFFF;
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_D30V_21:
+ check_size (value, 21, fixp->fx_file, fixp->fx_line);
+ insn |= (value >> 3) & 0x3FFFF;
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_D30V_21_PCREL:
+ if (fixp->fx_where & 0x7)
+ {
+ if (fixp->fx_done)
+ value += 4;
+ else
+ fixp->fx_r_type = BFD_RELOC_D30V_21_PCREL_R;
+ }
+ check_size (value, 21, fixp->fx_file, fixp->fx_line);
+ insn |= (value >> 3) & 0x3FFFF;
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ break;
+
+ case BFD_RELOC_D30V_32:
+ insn2 = bfd_getb32 ((unsigned char *) where + 4);
+ insn |= (value >> 26) & 0x3F; /* top 6 bits */
+ insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */
+ insn2 |= value & 0x0003FFFF; /* bottom 18 bits */
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
+ break;
+
+ case BFD_RELOC_D30V_32_PCREL:
+ insn2 = bfd_getb32 ((unsigned char *) where + 4);
+ insn |= (value >> 26) & 0x3F; /* top 6 bits */
+ insn2 |= ((value & 0x03FC0000) << 2); /* next 8 bits */
+ insn2 |= value & 0x0003FFFF; /* bottom 18 bits */
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ bfd_putb32 ((bfd_vma) insn2, (unsigned char *) where + 4);
+ break;
+
+ case BFD_RELOC_32:
+ bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
+ break;
+
+ default:
+ as_bad (_("line %d: unknown relocation type: 0x%x"),
+ fixp->fx_line,fixp->fx_r_type);
+ }
+
+ return 0;
+}
+
+
+/* d30v_cleanup() is called after the assembler has finished parsing the input
+ file or after a label is defined. Because the D30V assembler sometimes saves short
+ instructions to see if it can package them with the next instruction, there may
+ be a short instruction that still needs written. */
+int
+d30v_cleanup (use_sequential)
+ int use_sequential;
+{
+ segT seg;
+ subsegT subseg;
+
+ if (prev_insn != -1)
+ {
+ seg = now_seg;
+ subseg = now_subseg;
+ subseg_set (prev_seg, prev_subseg);
+ write_1_short (&prev_opcode, (long)prev_insn, fixups->next, use_sequential);
+ subseg_set (seg, subseg);
+ prev_insn = -1;
+ if (use_sequential)
+ prev_mul32_p = false;
+ }
+ return 1;
+}
+
+static void
+d30v_number_to_chars (buf, value, n)
+ char *buf; /* Return 'nbytes' of chars here. */
+ long long value; /* The value of the bits. */
+ int n; /* Number of bytes in the output. */
+{
+ while (n--)
+ {
+ buf[n] = value & 0xff;
+ value >>= 8;
+ }
+}
+
+
+/* This function is called at the start of every line. */
+/* it checks to see if the first character is a '.' */
+/* which indicates the start of a pseudo-op. If it is, */
+/* then write out any unwritten instructions */
+
+void
+d30v_start_line ()
+{
+ char *c = input_line_pointer;
+
+ while (isspace (*c))
+ c++;
+
+ if (*c == '.')
+ d30v_cleanup (false);
+}
+
+static void
+check_size (value, bits, file, line)
+ long value;
+ int bits;
+ char *file;
+ int line;
+{
+ int tmp, max;
+
+ if (value < 0)
+ tmp = ~value;
+ else
+ tmp = value;
+
+ max = (1 << (bits - 1)) - 1;
+
+ if (tmp > max)
+ as_bad_where (file, line, _("value too large to fit in %d bits"), bits);
+
+ return;
+}
+
+/* d30v_frob_label() is called when after a label is recognized. */
+
+void
+d30v_frob_label (lab)
+ symbolS *lab;
+{
+ /* Emit any pending instructions. */
+ d30v_cleanup (false);
+
+ /* Update the label's address with the current output pointer. */
+ lab->sy_frag = frag_now;
+ S_SET_VALUE (lab, (valueT) frag_now_fix ());
+
+ /* Record this label for future adjustment after we find out what
+ kind of data it references, and the required alignment therewith. */
+ d30v_last_label = lab;
+}
+
+/* Hook into cons for capturing alignment changes. */
+
+void
+d30v_cons_align (size)
+ int size;
+{
+ int log_size;
+
+ log_size = 0;
+ while ((size >>= 1) != 0)
+ ++log_size;
+
+ if (d30v_current_align < log_size)
+ d30v_align (log_size, (char *) NULL, NULL);
+ else if (d30v_current_align > log_size)
+ d30v_current_align = log_size;
+ d30v_last_label = NULL;
+}
+
+/* Called internally to handle all alignment needs. This takes care
+ of eliding calls to frag_align if'n the cached current alignment
+ says we've already got it, as well as taking care of the auto-aligning
+ labels wrt code. */
+
+static void
+d30v_align (n, pfill, label)
+ int n;
+ char *pfill;
+ symbolS *label;
+{
+ /* The front end is prone to changing segments out from under us
+ temporarily when -g is in effect. */
+ int switched_seg_p = (d30v_current_align_seg != now_seg);
+
+ /* Do not assume that if 'd30v_current_align >= n' and
+ '! switched_seg_p' that it is safe to avoid performing
+ this alignement request. The alignment of the current frag
+ can be changed under our feet, for example by a .ascii
+ directive in the source code. cf testsuite/gas/d30v/reloc.s */
+
+ d30v_cleanup (false);
+
+ if (pfill == NULL)
+ {
+ if (n > 2
+ && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ {
+ static char const nop[4] = { 0x00, 0xf0, 0x00, 0x00 };
+
+ /* First, make sure we're on a four-byte boundary, in case
+ someone has been putting .byte values the text section. */
+ if (d30v_current_align < 2 || switched_seg_p)
+ frag_align (2, 0, 0);
+ frag_align_pattern (n, nop, sizeof nop, 0);
+ }
+ else
+ frag_align (n, 0, 0);
+ }
+ else
+ frag_align (n, *pfill, 0);
+
+ if (!switched_seg_p)
+ d30v_current_align = n;
+
+ if (label != NULL)
+ {
+ symbolS * sym;
+ int label_seen = false;
+ struct frag * old_frag;
+ valueT old_value;
+ valueT new_value;
+
+ assert (S_GET_SEGMENT (label) == now_seg);
+
+ old_frag = label->sy_frag;
+ old_value = S_GET_VALUE (label);
+ new_value = (valueT) frag_now_fix ();
+
+ /* It is possible to have more than one label at a particular
+ address, especially if debugging is enabled, so we must
+ take care to adjust all the labels at this address in this
+ fragment. To save time we search from the end of the symbol
+ list, backwards, since the symbols we are interested in are
+ almost certainly the ones that were most recently added.
+ Also to save time we stop searching once we have seen at least
+ one matching label, and we encounter a label that is no longer
+ in the target fragment. Note, this search is guaranteed to
+ find at least one match when sym == label, so no special case
+ code is necessary. */
+ for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous)
+ {
+ if (sym->sy_frag == old_frag && S_GET_VALUE (sym) == old_value)
+ {
+ label_seen = true;
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, new_value);
+ }
+ else if (label_seen && sym->sy_frag != old_frag)
+ break;
+ }
+ }
+
+ record_alignment (now_seg, n);
+}
+
+/* Handle the .align pseudo-op. This aligns to a power of two. We
+ hook here to latch the current alignment. */
+
+static void
+s_d30v_align (ignore)
+ int ignore;
+{
+ int align;
+ char fill, *pfill = NULL;
+ long max_alignment = 15;
+
+ align = get_absolute_expression ();
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_warn (_("Alignment too large: %d assumed"), align);
+ }
+ else if (align < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed"));
+ align = 0;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ fill = get_absolute_expression ();
+ pfill = &fill;
+ }
+
+ d30v_last_label = NULL;
+ d30v_align (align, pfill, NULL);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .text pseudo-op. This is like the usual one, but it
+ clears the saved last label and resets known alignment. */
+
+static void
+s_d30v_text (i)
+ int i;
+
+{
+ s_text (i);
+ d30v_last_label = NULL;
+ d30v_current_align = 0;
+ d30v_current_align_seg = now_seg;
+}
+
+/* Handle the .data pseudo-op. This is like the usual one, but it
+ clears the saved last label and resets known alignment. */
+
+static void
+s_d30v_data (i)
+ int i;
+{
+ s_data (i);
+ d30v_last_label = NULL;
+ d30v_current_align = 0;
+ d30v_current_align_seg = now_seg;
+}
+
+/* Handle the .section pseudo-op. This is like the usual one, but it
+ clears the saved last label and resets known alignment. */
+
+static void
+s_d30v_section (ignore)
+ int ignore;
+{
+ obj_elf_section (ignore);
+ d30v_last_label = NULL;
+ d30v_current_align = 0;
+ d30v_current_align_seg = now_seg;
+}
diff --git a/gas/config/tc-d30v.h b/gas/config/tc-d30v.h
new file mode 100644
index 00000000000..acce285693d
--- /dev/null
+++ b/gas/config/tc-d30v.h
@@ -0,0 +1,59 @@
+/* tc-310v.h -- Header file for tc-d30v.c.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Written by Martin Hunt, Cygnus Support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TC_D30V
+
+#ifndef BFD_ASSEMBLER
+ #error D30V support requires BFD_ASSEMBLER
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_d30v
+#define TARGET_FORMAT "elf32-d30v"
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define md_operand(x)
+
+#define MD_APPLY_FIX3
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_bigendian
+
+int d30v_cleanup PARAMS ((int));
+#define md_after_pass_hook() d30v_cleanup (false)
+#define md_cleanup() d30v_cleanup (false)
+#define TC_START_LABEL(ch, ptr) (ch == ':' && d30v_cleanup (false))
+#define md_start_line_hook() d30v_start_line (false)
+
+void d30v_frob_label PARAMS ((struct symbol *));
+#define tc_frob_label(sym) d30v_frob_label(sym)
+
+void d30v_cons_align PARAMS ((int));
+#define md_cons_align(nbytes) d30v_cons_align(nbytes)
diff --git a/gas/config/tc-fr30.c b/gas/config/tc-fr30.c
new file mode 100644
index 00000000000..aa075b7322a
--- /dev/null
+++ b/gas/config/tc-fr30.c
@@ -0,0 +1,664 @@
+/* tc-fr30.c -- Assembler for the Fujitsu FR30.
+ Copyright (C) 1998, 1999 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "symcat.h"
+#include "opcodes/fr30-desc.h"
+#include "opcodes/fr30-opc.h"
+#include "cgen.h"
+
+/* Structure to hold all of the different components describing
+ an individual instruction. */
+typedef struct
+{
+ const CGEN_INSN * insn;
+ const CGEN_INSN * orig_insn;
+ CGEN_FIELDS fields;
+#if CGEN_INT_INSN_P
+ CGEN_INSN_INT buffer [1];
+#define INSN_VALUE(buf) (*(buf))
+#else
+ unsigned char buffer [CGEN_MAX_INSN_SIZE];
+#define INSN_VALUE(buf) (buf)
+#endif
+ char * addr;
+ fragS * frag;
+ int num_fixups;
+ fixS * fixups [GAS_CGEN_MAX_FIXUPS];
+ int indices [MAX_OPERAND_INSTANCES];
+}
+fr30_insn;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = "|";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+#define FR30_SHORTOPTS ""
+const char * md_shortopts = FR30_SHORTOPTS;
+
+struct option md_longopts[] =
+{
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ switch (c)
+ {
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE * stream;
+{
+ fprintf (stream, _(" FR30 specific command line options:\n"));
+}
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "word", cons, 4 },
+ { NULL, NULL, 0 }
+};
+
+
+void
+md_begin ()
+{
+ flagword applicable;
+ segT seg;
+ subsegT subseg;
+
+ /* Initialize the `cgen' interface. */
+
+ /* Set the machine number and endian. */
+ gas_cgen_cpu_desc = fr30_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
+ CGEN_CPU_OPEN_ENDIAN,
+ CGEN_ENDIAN_BIG,
+ CGEN_CPU_OPEN_END);
+ fr30_cgen_init_asm (gas_cgen_cpu_desc);
+
+ /* This is a callback from cgen to gas to parse operands. */
+ cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
+}
+
+void
+md_assemble (str)
+ char * str;
+{
+ static int last_insn_had_delay_slot = 0;
+ fr30_insn insn;
+ char * errmsg;
+ char * str2 = NULL;
+
+ /* Initialize GAS's cgen interface for a new instruction. */
+ gas_cgen_init_parse ();
+
+ insn.insn = fr30_cgen_assemble_insn
+ (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
+
+ if (!insn.insn)
+ {
+ as_bad (errmsg);
+ return;
+ }
+
+ /* Doesn't really matter what we pass for RELAX_P here. */
+ gas_cgen_finish_insn (insn.insn, insn.buffer,
+ CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
+
+ /* Warn about invalid insns in delay slots. */
+ if (last_insn_had_delay_slot
+ && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_NOT_IN_DELAY_SLOT))
+ as_warn (_("Instruction %s not allowed in a delay slot."),
+ CGEN_INSN_NAME (insn.insn));
+
+ last_insn_had_delay_slot
+ = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
+}
+
+/* The syntax in the manual says constants begin with '#'.
+ We just ignore it. */
+
+void
+md_operand (expressionP)
+ expressionS * expressionP;
+{
+ if (* input_line_pointer == '#')
+ {
+ input_line_pointer ++;
+ expression (expressionP);
+ }
+}
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char * name;
+{
+ return 0;
+}
+
+/* Interface to relax_segment. */
+
+/* FIXME: Build table by hand, get it working, then machine generate. */
+
+const relax_typeS md_relax_table[] =
+{
+/* The fields are:
+ 1) most positive reach of this state,
+ 2) most negative reach of this state,
+ 3) how many bytes this mode will add to the size of the current frag
+ 4) which index into the table to try if we can't fit into this one. */
+
+ /* The first entry must be unused because an `rlx_more' value of zero ends
+ each list. */
+ {1, 1, 0, 0},
+
+ /* The displacement used by GAS is from the end of the 2 byte insn,
+ so we subtract 2 from the following. */
+ /* 16 bit insn, 8 bit disp -> 10 bit range.
+ This doesn't handle a branch in the right slot at the border:
+ the "& -4" isn't taken into account. It's not important enough to
+ complicate things over it, so we subtract an extra 2 (or + 2 in -ve
+ case). */
+ {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
+ /* 32 bit insn, 24 bit disp -> 26 bit range. */
+ {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
+ /* Same thing, but with leading nop for alignment. */
+ {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
+};
+
+long
+fr30_relax_frag (fragP, stretch)
+ fragS * fragP;
+ long stretch;
+{
+ /* Address of branch insn. */
+ long address = fragP->fr_address + fragP->fr_fix - 2;
+ long growth = 0;
+
+ /* Keep 32 bit insns aligned on 32 bit boundaries. */
+ if (fragP->fr_subtype == 2)
+ {
+ if ((address & 3) != 0)
+ {
+ fragP->fr_subtype = 3;
+ growth = 2;
+ }
+ }
+ else if (fragP->fr_subtype == 3)
+ {
+ if ((address & 3) == 0)
+ {
+ fragP->fr_subtype = 2;
+ growth = -2;
+ }
+ }
+ else
+ {
+ growth = relax_frag (fragP, stretch);
+
+ /* Long jump on odd halfword boundary? */
+ if (fragP->fr_subtype == 2 && (address & 3) != 0)
+ {
+ fragP->fr_subtype = 3;
+ growth += 2;
+ }
+ }
+
+ return growth;
+}
+
+/* Return an initial guess of the length by which a fragment must grow to
+ hold a branch to reach its destination.
+ Also updates fr_type/fr_subtype as necessary.
+
+ Called just before doing relaxation.
+ Any symbol that is now undefined will not become defined.
+ The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ Although it may not be explicit in the frag, pretend fr_var starts with a
+ 0 value. */
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS * fragP;
+ segT segment;
+{
+ int old_fr_fix = fragP->fr_fix;
+
+ /* The only thing we have to handle here are symbols outside of the
+ current segment. They may be undefined or in a different segment in
+ which case linker scripts may place them anywhere.
+ However, we can't finish the fragment here and emit the reloc as insn
+ alignment requirements may move the insn about. */
+
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
+ {
+ /* The symbol is undefined in this segment.
+ Change the relaxation subtype to the max allowable and leave
+ all further handling to md_convert_frag. */
+ fragP->fr_subtype = 2;
+
+#if 0 /* Can't use this, but leave in for illustration. */
+ /* Change 16 bit insn to 32 bit insn. */
+ fragP->fr_opcode[0] |= 0x80;
+
+ /* Increase known (fixed) size of fragment. */
+ fragP->fr_fix += 2;
+
+ /* Create a relocation for it. */
+ fix_new (fragP, old_fr_fix, 4,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1 /* pcrel */,
+ /* FIXME: Can't use a real BFD reloc here.
+ gas_cgen_md_apply_fix3 can't handle it. */
+ BFD_RELOC_FR30_26_PCREL);
+
+ /* Mark this fragment as finished. */
+ frag_wane (fragP);
+#else
+ {
+ const CGEN_INSN * insn;
+ int i;
+
+ /* Update the recorded insn.
+ Fortunately we don't have to look very far.
+ FIXME: Change this to record in the instruction the next higher
+ relaxable insn to use. */
+ for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
+ {
+ if ((strcmp (CGEN_INSN_MNEMONIC (insn),
+ CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
+ == 0)
+ && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX))
+ break;
+ }
+ if (i == 4)
+ abort ();
+
+ fragP->fr_cgen.insn = insn;
+ return 2;
+ }
+#endif
+ }
+
+ return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
+}
+
+/* *fragP has been relaxed to its final size, and now needs to have
+ the bytes inside it modified to conform to the new size.
+
+ Called after relaxation is finished.
+ fragP->fr_type == rs_machine_dependent.
+ fragP->fr_subtype is the subtype of what the address relaxed to. */
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd * abfd;
+ segT sec;
+ fragS * fragP;
+{
+#if 0
+ char * opcode;
+ char * displacement;
+ int target_address;
+ int opcode_address;
+ int extension;
+ int addend;
+
+ opcode = fragP->fr_opcode;
+
+ /* Address opcode resides at in file space. */
+ opcode_address = fragP->fr_address + fragP->fr_fix - 2;
+
+ switch (fragP->fr_subtype)
+ {
+ case 1 :
+ extension = 0;
+ displacement = & opcode[1];
+ break;
+ case 2 :
+ opcode[0] |= 0x80;
+ extension = 2;
+ displacement = & opcode[1];
+ break;
+ case 3 :
+ opcode[2] = opcode[0] | 0x80;
+ md_number_to_chars (opcode, PAR_NOP_INSN, 2);
+ opcode_address += 2;
+ extension = 4;
+ displacement = & opcode[3];
+ break;
+ default :
+ abort ();
+ }
+
+ if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
+ {
+ /* symbol must be resolved by linker */
+ if (fragP->fr_offset & 3)
+ as_warn (_("Addend to unresolved symbol not on word boundary."));
+ addend = fragP->fr_offset >> 2;
+ }
+ else
+ {
+ /* Address we want to reach in file space. */
+ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
+ target_address += fragP->fr_symbol->sy_frag->fr_address;
+ addend = (target_address - (opcode_address & -4)) >> 2;
+ }
+
+ /* Create a relocation for symbols that must be resolved by the linker.
+ Otherwise output the completed insn. */
+
+ if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
+ {
+ assert (fragP->fr_subtype != 1);
+ assert (fragP->fr_cgen.insn != 0);
+ gas_cgen_record_fixup (fragP,
+ /* Offset of branch insn in frag. */
+ fragP->fr_fix + extension - 4,
+ fragP->fr_cgen.insn,
+ 4 /*length*/,
+ /* FIXME: quick hack */
+#if 0
+ CGEN_OPERAND_ENTRY (fragP->fr_cgen.opindex),
+#else
+ CGEN_OPERAND_ENTRY (FR30_OPERAND_DISP24),
+#endif
+ fragP->fr_cgen.opinfo,
+ fragP->fr_symbol, fragP->fr_offset);
+ }
+
+#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)
+
+ md_number_to_chars (displacement, (valueT) addend,
+ SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
+
+ fragP->fr_fix += extension;
+#endif
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixP, sec)
+ fixS * fixP;
+ segT sec;
+{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != sec))
+ {
+ /* The symbol is undefined (or is defined but not in this section).
+ Let the linker figure it out. */
+ return 0;
+ }
+
+ return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;
+}
+
+/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
+ Returns BFD_RELOC_NONE if no reloc type can be found.
+ *FIXP may be modified if desired. */
+
+bfd_reloc_code_real_type
+md_cgen_lookup_reloc (insn, operand, fixP)
+ const CGEN_INSN * insn;
+ const CGEN_OPERAND * operand;
+ fixS * fixP;
+{
+ switch (operand->type)
+ {
+ case FR30_OPERAND_LABEL9: fixP->fx_pcrel = 1; return BFD_RELOC_FR30_9_PCREL;
+ case FR30_OPERAND_LABEL12: fixP->fx_pcrel = 1; return BFD_RELOC_FR30_12_PCREL;
+ case FR30_OPERAND_DISP10: return BFD_RELOC_FR30_10_IN_8;
+ case FR30_OPERAND_DISP9: return BFD_RELOC_FR30_9_IN_8;
+ case FR30_OPERAND_DISP8: return BFD_RELOC_FR30_8_IN_8;
+ case FR30_OPERAND_UDISP6: return BFD_RELOC_FR30_6_IN_4;
+ case FR30_OPERAND_I8: return BFD_RELOC_8;
+ case FR30_OPERAND_I32: return BFD_RELOC_FR30_48;
+ case FR30_OPERAND_I20: return BFD_RELOC_FR30_20;
+ default : /* avoid -Wall warning */
+ break;
+ }
+
+ return BFD_RELOC_NONE;
+}
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+fr30_force_relocation (fix)
+ fixS * fix;
+{
+ if ( fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
+
+/* Write a value out to the object file, using the appropriate endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char * buf;
+ valueT val;
+ int n;
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+*/
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char * litP;
+ int * sizeP;
+{
+ int i;
+ int prec;
+ LITTLENUM_TYPE words [MAX_LITTLENUMS];
+ char * t;
+ char * atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ /* FIXME: Some targets allow other format chars for bigger sizes here. */
+
+ default:
+ * sizeP = 0;
+ return _("Bad call to md_atof()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ * sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+/* Worker function for fr30_is_colon_insn(). */
+static char
+restore_colon (advance_i_l_p_by)
+ int advance_i_l_p_by;
+{
+ char c;
+
+ /* Restore the colon, and advance input_line_pointer to
+ the end of the new symbol. */
+ * input_line_pointer = ':';
+ input_line_pointer += advance_i_l_p_by;
+ c = * input_line_pointer;
+ * input_line_pointer = 0;
+
+ return c;
+}
+
+/* Determines if the symbol starting at START and ending in
+ a colon that was at the location pointed to by INPUT_LINE_POINTER
+ (but which has now been replaced bu a NUL) is in fact an
+ LDI:8, LDI:20, LDI:32, CALL:D. JMP:D, RET:D or Bcc:D instruction.
+ If it is, then it restores the colon, advances INPUT_LINE_POINTER
+ to the real end of the instruction/symbol, and returns the character
+ that really terminated the symbol. Otherwise it returns 0. */
+char
+fr30_is_colon_insn (start)
+ char * start;
+{
+ char * i_l_p = input_line_pointer;
+
+ /* Check to see if the symbol parsed so far is 'ldi' */
+ if ( (start[0] != 'l' && start[0] != 'L')
+ || (start[1] != 'd' && start[1] != 'D')
+ || (start[2] != 'i' && start[2] != 'I')
+ || start[3] != 0)
+ {
+ /* Nope - check to see a 'd' follows the colon. */
+ if ( (i_l_p[1] == 'd' || i_l_p[1] == 'D')
+ && (i_l_p[2] == ' ' || i_l_p[2] == '\t' || i_l_p[2] == '\n'))
+ {
+ /* Yup - it might be delay slot instruction. */
+ int i;
+ static char * delay_insns [] =
+ {
+ "call", "jmp", "ret", "bra", "bno",
+ "beq", "bne", "bc", "bnc", "bn",
+ "bp", "bv", "bnv", "blt", "bge",
+ "ble", "bgt", "bls", "bhi"
+ };
+
+ for (i = sizeof (delay_insns) / sizeof (delay_insns[0]); i--;)
+ {
+ char * insn = delay_insns[i];
+ int len = strlen (insn);
+
+ if (start [len] != 0)
+ continue;
+
+ while (len --)
+ if (tolower (start [len]) != insn [len])
+ break;
+
+ if (len == -1)
+ return restore_colon (1);
+ }
+ }
+
+ /* Nope - it is a normal label. */
+ return 0;
+ }
+
+ /* Check to see if the text following the colon is '8' */
+ if (i_l_p[1] == '8' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
+ return restore_colon (2);
+
+ /* Check to see if the text following the colon is '20' */
+ else if (i_l_p[1] == '2' && i_l_p[2] =='0' && (i_l_p[3] == ' ' || i_l_p[3] == '\t'))
+ return restore_colon (3);
+
+ /* Check to see if the text following the colon is '32' */
+ else if (i_l_p[1] == '3' && i_l_p[2] =='2' && (i_l_p[3] == ' ' || i_l_p[3] == '\t'))
+ return restore_colon (3);
+
+ return 0;
+}
+
+boolean
+fr30_fix_adjustable (fixP)
+ fixS * fixP;
+{
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+#if 0
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+#endif
+
+ /* We need the symbol name for the VTABLE entries */
+ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
diff --git a/gas/config/tc-fr30.h b/gas/config/tc-fr30.h
new file mode 100644
index 00000000000..a672d8bab11
--- /dev/null
+++ b/gas/config/tc-fr30.h
@@ -0,0 +1,81 @@
+/* tc-fr30.h -- Header file for tc-fr30.c.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_FR30
+
+#ifndef BFD_ASSEMBLER
+/* leading space so will compile with cc */
+ #error FR30 support requires BFD_ASSEMBLER
+#endif
+
+#define LISTING_HEADER "FR30 GAS "
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_fr30
+
+#define TARGET_FORMAT "elf32-fr30"
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+long md_pcrel_from_section PARAMS ((struct fix *, segT));
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define MD_APPLY_FIX3
+#define md_apply_fix3 gas_cgen_md_apply_fix3
+
+#define obj_fix_adjustable(fixP) fr30_fix_adjustable (fixP)
+extern boolean fr30_fix_adjustable PARAMS ((struct fix *));
+
+/* When relaxing, we need to emit various relocs we otherwise wouldn't. */
+#define TC_FORCE_RELOCATION(fix) fr30_force_relocation (fix)
+extern int fr30_force_relocation PARAMS ((struct fix *));
+
+#define TC_HANDLES_FX_DONE
+
+#define tc_gen_reloc gas_cgen_tc_gen_reloc
+
+/* Call md_pcrel_from_section(), not md_pcrel_from(). */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
+/* For 8 vs 16 vs 32 bit branch selection. */
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+extern const struct relax_type md_relax_table[];
+
+/* We need a special version of the TC_START_LABEL macro so that we
+ allow the LDI:8, LDI:20, LDI:32 and delay slot instructions to be
+ parsed as such. Note - in a HORRIBLE HACK, we make use of the
+ knowledge that this marco is only ever evaluated in one place
+ (read_a_source_file in read.c) where we can access the local
+ variable 's' - the start of the symbol that was terminated by
+ 'character'. Also we need to be able to change the contents of
+ the local variable 'c' which is passed to this macro as 'character'. */
+#define TC_START_LABEL(character, i_l_p) \
+ ((character) != ':' ? 0 : (character = fr30_is_colon_insn (s)) ? 0 : ((character = ':'), 1))
+extern char fr30_is_colon_insn PARAMS ((char *));
diff --git a/gas/config/tc-generic.c b/gas/config/tc-generic.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/config/tc-generic.c
diff --git a/gas/config/tc-generic.h b/gas/config/tc-generic.h
new file mode 100644
index 00000000000..72df0203165
--- /dev/null
+++ b/gas/config/tc-generic.h
@@ -0,0 +1,39 @@
+/* This file is tc-generic.h
+
+ Copyright (C) 1987, 91, 92, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * This file is tc-generic.h and is intended to be a template for target cpu
+ * specific header files. It is my intent that this file compile. It is also
+ * my intent that this file grow into something that can be used as both a
+ * template for porting, and a stub for testing. xoxorich.
+ */
+
+#define TC_GENERIC 1
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of tc-generic.h */
diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c
new file mode 100644
index 00000000000..115ada15423
--- /dev/null
+++ b/gas/config/tc-h8300.c
@@ -0,0 +1,1595 @@
+/* tc-h8300.c -- Assemble code for the Hitachi H8/300
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/*
+ Written By Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include <stdio.h>
+#include "as.h"
+#include "subsegs.h"
+#include "bfd.h"
+#define DEFINE_TABLE
+#define h8_opcodes ops
+#include "opcode/h8300.h"
+#include <ctype.h>
+
+const char comment_chars[] =
+{';', 0};
+const char line_separator_chars[] =
+{0};
+const char line_comment_chars[] = "#";
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+void cons ();
+
+int Hmode;
+int Smode;
+#define PSIZE (Hmode ? L_32 : L_16)
+#define DMODE (L_16)
+#define DSYMMODE (Hmode ? L_24 : L_16)
+int bsize = L_8; /* default branch displacement */
+
+
+void
+h8300hmode ()
+{
+ Hmode = 1;
+ Smode = 0;
+}
+
+void
+h8300smode ()
+{
+ Smode = 1;
+ Hmode = 1;
+}
+void
+sbranch (size)
+ int size;
+{
+ bsize = size;
+}
+
+static void pint ()
+{
+ cons (Hmode ? 4 : 2);
+}
+
+const pseudo_typeS md_pseudo_table[] =
+{
+
+ {"h8300h", h8300hmode, 0},
+ {"h8300s", h8300smode, 0},
+ {"sbranch", sbranch, L_8},
+ {"lbranch", sbranch, L_16},
+
+ {"int", pint, 0},
+ {"data.b", cons, 1},
+ {"data.w", cons, 2},
+ {"data.l", cons, 4},
+ {"form", listing_psize, 0},
+ {"heading", listing_title, 0},
+ {"import", s_ignore, 0},
+ {"page", listing_eject, 0},
+ {"program", s_ignore, 0},
+ {0, 0, 0}
+};
+
+const int md_reloc_size;
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
+
+/*
+ This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs
+ */
+
+
+void
+md_begin ()
+{
+ struct h8_opcode *opcode;
+ char prev_buffer[100];
+ int idx = 0;
+
+ opcode_hash_control = hash_new ();
+ prev_buffer[0] = 0;
+
+ for (opcode = h8_opcodes; opcode->name; opcode++)
+ {
+ /* Strip off any . part when inserting the opcode and only enter
+ unique codes into the hash table
+ */
+ char *src = opcode->name;
+ unsigned int len = strlen (src);
+ char *dst = malloc (len + 1);
+ char *buffer = dst;
+
+ opcode->size = 0;
+ while (*src)
+ {
+ if (*src == '.')
+ {
+ src++;
+ opcode->size = *src;
+ break;
+ }
+ *dst++ = *src++;
+ }
+ *dst++ = 0;
+ if (strcmp (buffer, prev_buffer))
+ {
+ hash_insert (opcode_hash_control, buffer, (char *) opcode);
+ strcpy (prev_buffer, buffer);
+ idx++;
+ }
+ opcode->idx = idx;
+
+
+ /* Find the number of operands */
+ opcode->noperands = 0;
+ while (opcode->args.nib[opcode->noperands] != E)
+ opcode->noperands++;
+ /* Find the length of the opcode in bytes */
+ opcode->length = 0;
+ while (opcode->data.nib[opcode->length * 2] != E)
+ opcode->length++;
+ }
+
+ linkrelax = 1;
+}
+
+
+struct h8_exp
+{
+ char *e_beg;
+ char *e_end;
+ expressionS e_exp;
+};
+int dispreg;
+int opsize; /* Set when a register size is seen */
+
+
+struct h8_op
+{
+ op_type mode;
+ unsigned reg;
+ expressionS exp;
+};
+
+/*
+ parse operands
+ WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
+ r0l,r0h,..r7l,r7h
+ @WREG
+ @WREG+
+ @-WREG
+ #const
+ ccr
+*/
+
+/* try and parse a reg name, returns number of chars consumed */
+int
+parse_reg (src, mode, reg, direction)
+ char *src;
+ op_type *mode;
+ unsigned int *reg;
+ int direction;
+
+{
+ char *end;
+ int len;
+
+ /* Cribbed from get_symbol_end(). */
+ if (!is_name_beginner (*src) || *src == '\001')
+ return 0;
+ end = src+1;
+ while (is_part_of_name (*end) || *end == '\001')
+ end++;
+ len = end - src;
+
+ if (len == 2 && src[0] == 's' && src[1] == 'p')
+ {
+ *mode = PSIZE | REG | direction;
+ *reg = 7;
+ return len;
+ }
+ if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
+ {
+ *mode = CCR;
+ *reg = 0;
+ return len;
+ }
+ if (len == 3 && src[0] == 'e' && src[1] == 'x' && src[2] == 'r')
+ {
+ *mode = EXR;
+ *reg = 0;
+ return len;
+ }
+ if (len == 2 && src[0] == 'f' && src[1] == 'p')
+ {
+ *mode = PSIZE | REG | direction;
+ *reg = 6;
+ return len;
+ }
+ if (len == 3 && src[0] == 'e' && src[1] == 'r'
+ && src[2] >= '0' && src[2] <= '7')
+ {
+ *mode = L_32 | REG | direction;
+ *reg = src[2] - '0';
+ if (!Hmode)
+ as_warn (_("Reg not valid for H8/300"));
+ return len;
+ }
+ if (len == 2 && src[0] == 'e' && src[1] >= '0' && src[1] <= '7')
+ {
+ *mode = L_16 | REG | direction;
+ *reg = src[1] - '0' + 8;
+ if (!Hmode)
+ as_warn (_("Reg not valid for H8/300"));
+ return len;
+ }
+
+ if (src[0] == 'r')
+ {
+ if (src[1] >= '0' && src[1] <= '7')
+ {
+ if (len == 3 && src[2] == 'l')
+ {
+ *mode = L_8 | REG | direction;
+ *reg = (src[1] - '0') + 8;
+ return len;
+ }
+ if (len == 3 && src[2] == 'h')
+ {
+ *mode = L_8 | REG | direction;
+ *reg = (src[1] - '0');
+ return len;
+ }
+ if (len == 2)
+ {
+ *mode = L_16 | REG | direction;
+ *reg = (src[1] - '0');
+ return len;
+ }
+ }
+ }
+
+ return 0;
+}
+
+char *
+parse_exp (s, op)
+ char *s;
+ expressionS * op;
+{
+ char *save = input_line_pointer;
+ char *new;
+
+ input_line_pointer = s;
+ expression (op);
+ if (op->X_op == O_absent)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+static char *
+skip_colonthing (ptr, exp, mode)
+ char *ptr;
+ expressionS *exp;
+ int *mode;
+{
+ if (*ptr == ':')
+ {
+ ptr++;
+ *mode &= ~SIZE;
+ if (*ptr == '8')
+ {
+ ptr++;
+ /* ff fill any 8 bit quantity */
+ /* exp->X_add_number -= 0x100;*/
+ *mode |= L_8;
+ }
+ else
+ {
+ if (*ptr == '2')
+ {
+ *mode |= L_24;
+ }
+ else if (*ptr == '3')
+ {
+ *mode |= L_32;
+ }
+ else if (*ptr == '1')
+ {
+ *mode |= L_16;
+ }
+ while (isdigit (*ptr))
+ ptr++;
+ }
+ }
+ return ptr;
+}
+
+/* The many forms of operand:
+
+ Rn Register direct
+ @Rn Register indirect
+ @(exp[:16], Rn) Register indirect with displacement
+ @Rn+
+ @-Rn
+ @aa:8 absolute 8 bit
+ @aa:16 absolute 16 bit
+ @aa absolute 16 bit
+
+ #xx[:size] immediate data
+ @(exp:[8], pc) pc rel
+ @@aa[:8] memory indirect
+
+ */
+
+char *
+colonmod24 (op, src)
+ struct h8_op *op;
+ char *src;
+
+{
+ int mode = 0;
+ src = skip_colonthing (src, &op->exp, &mode);
+
+ if (!mode)
+ {
+ /* Choose a default mode */
+ if (op->exp.X_add_number < -32768
+ || op->exp.X_add_number > 32767)
+ {
+ if (Hmode)
+ mode = L_24;
+ else
+ mode = L_16;
+ }
+ else if (op->exp.X_add_symbol
+ || op->exp.X_op_symbol)
+ mode = DSYMMODE;
+ else
+ mode = DMODE;
+ }
+ op->mode |= mode;
+ return src;
+
+}
+
+
+static void
+get_operand (ptr, op, dst, direction)
+ char **ptr;
+ struct h8_op *op;
+ unsigned int dst;
+ int direction;
+{
+ char *src = *ptr;
+ op_type mode;
+ unsigned int num;
+ unsigned int len;
+
+ op->mode = E;
+
+ /* Gross. Gross. ldm and stm have a format not easily handled
+ by get_operand. We deal with it explicitly here. */
+ if (src[0] == 'e' && src[1] == 'r' && isdigit(src[2])
+ && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit(src[6]))
+ {
+ int low, high;
+
+ low = src[2] - '0';
+ high = src[6] - '0';
+
+ if (high < low)
+ as_bad (_("Invalid register list for ldm/stm\n"));
+
+ if (low % 2)
+ as_bad (_("Invalid register list for ldm/stm\n"));
+
+ if (high - low > 3)
+ as_bad (_("Invalid register list for ldm/stm\n"));
+
+ if (high - low != 1
+ && low % 4)
+ as_bad (_("Invalid register list for ldm/stm\n"));
+
+ /* Even sicker. We encode two registers into op->reg. One
+ for the low register to save, the other for the high
+ register to save; we also set the high bit in op->reg
+ so we know this is "very special". */
+ op->reg = 0x80000000 | (high << 8) | low;
+ op->mode = REG;
+ *ptr = src + 7;
+ return;
+ }
+
+ len = parse_reg (src, &op->mode, &op->reg, direction);
+ if (len)
+ {
+ *ptr = src + len;
+ return;
+ }
+
+ if (*src == '@')
+ {
+ src++;
+ if (*src == '@')
+ {
+ src++;
+ src = parse_exp (src, &op->exp);
+
+ src = skip_colonthing (src, &op->exp, &op->mode);
+
+ *ptr = src;
+
+ op->mode = MEMIND;
+ return;
+
+ }
+
+
+ if (*src == '-')
+ {
+ src++;
+ len = parse_reg (src, &mode, &num, direction);
+ if (len == 0)
+ {
+ /* Oops, not a reg after all, must be ordinary exp */
+ src--;
+ /* must be a symbol */
+ op->mode = ABS | PSIZE | direction;
+ *ptr = skip_colonthing (parse_exp (src, &op->exp),
+ &op->exp, &op->mode);
+
+ return;
+
+
+ }
+
+
+ if ((mode & SIZE) != PSIZE)
+ as_bad (_("Wrong size pointer register for architecture."));
+ op->mode = RDDEC;
+ op->reg = num;
+ *ptr = src + len;
+ return;
+ }
+ if (*src == '(')
+ {
+ /* Disp */
+ src++;
+
+ /* Start off assuming a 16 bit offset */
+
+
+ src = parse_exp (src, &op->exp);
+
+ src = colonmod24 (op, src);
+
+ if (*src == ')')
+ {
+ src++;
+ op->mode |= ABS | direction;
+ *ptr = src;
+ return;
+ }
+
+ if (*src != ',')
+ {
+ as_bad (_("expected @(exp, reg16)"));
+ return;
+
+ }
+ src++;
+
+ len = parse_reg (src, &mode, &op->reg, direction);
+ if (len == 0 || !(mode & REG))
+ {
+ as_bad (_("expected @(exp, reg16)"));
+ return;
+ }
+ op->mode |= DISP | direction;
+ dispreg = op->reg;
+ src += len;
+ src = skip_colonthing (src, &op->exp, &op->mode);
+
+ if (*src != ')' && '(')
+ {
+ as_bad (_("expected @(exp, reg16)"));
+ return;
+ }
+ *ptr = src + 1;
+
+ return;
+ }
+ len = parse_reg (src, &mode, &num, direction);
+
+ if (len)
+ {
+ src += len;
+ if (*src == '+')
+ {
+ src++;
+ if ((mode & SIZE) != PSIZE)
+ as_bad (_("Wrong size pointer register for architecture."));
+ op->mode = RSINC;
+ op->reg = num;
+ *ptr = src;
+ return;
+ }
+ if ((mode & SIZE) != PSIZE)
+ as_bad (_("Wrong size pointer register for architecture."));
+
+ op->mode = direction | IND | PSIZE;
+ op->reg = num;
+ *ptr = src;
+
+ return;
+ }
+ else
+ {
+ /* must be a symbol */
+
+ op->mode = ABS | direction;
+ src = parse_exp (src, &op->exp);
+
+ *ptr = colonmod24 (op, src);
+
+ return;
+ }
+ }
+
+
+ if (*src == '#')
+ {
+ src++;
+ op->mode = IMM;
+ src = parse_exp (src, &op->exp);
+ *ptr = skip_colonthing (src, &op->exp, &op->mode);
+
+ return;
+ }
+ else if (strncmp (src, "mach", 4) == 0
+ || strncmp (src, "macl", 4) == 0)
+ {
+ op->reg = src[3] == 'l';
+ op->mode = MACREG;
+ *ptr = src + 4;
+ return;
+ }
+ else
+ {
+ src = parse_exp (src, &op->exp);
+ /* Trailing ':' size ? */
+ if (*src == ':')
+ {
+ if (src[1] == '1' && src[2] == '6')
+ {
+ op->mode = PCREL | L_16;
+ src += 3;
+ }
+ else if (src[1] == '8')
+ {
+ op->mode = PCREL | L_8;
+ src += 2;
+ }
+ else
+ {
+ as_bad (_("expect :8 or :16 here"));
+ }
+ }
+ else
+ {
+ op->mode = PCREL | bsize;
+ }
+ *ptr = src;
+ }
+}
+
+
+static
+char *
+get_operands (noperands, op_end, operand)
+ unsigned int noperands;
+ char *op_end;
+ struct h8_op *operand;
+{
+ char *ptr = op_end;
+
+ switch (noperands)
+ {
+ case 0:
+ operand[0].mode = 0;
+ operand[1].mode = 0;
+ break;
+
+ case 1:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0, SRC);
+ if (*ptr == ',')
+ {
+ ptr++;
+ get_operand (&ptr, operand + 1, 1, DST);
+ }
+ else
+ {
+ operand[1].mode = 0;
+ }
+
+ break;
+ case 2:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0, SRC);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1, DST);
+ break;
+
+ default:
+ abort ();
+ }
+
+
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes, return the opcode which matches the opcodes
+ provided
+ */
+static
+struct h8_opcode *
+get_specific (opcode, operands, size)
+ struct h8_opcode *opcode;
+ struct h8_op *operands;
+ int size;
+{
+ struct h8_opcode *this_try = opcode;
+ int found = 0;
+
+ unsigned int this_index = opcode->idx;
+
+ /* There's only one ldm/stm and it's easier to just
+ get out quick for them. */
+ if (strcmp (opcode->name, "stm.l") == 0
+ || strcmp (opcode->name, "ldm.l") == 0)
+ return this_try;
+
+ while (this_index == opcode->idx && !found)
+ {
+ found = 1;
+
+ this_try = opcode++;
+ if (this_try->noperands == 0)
+ {
+ int this_size;
+
+ this_size = this_try->how & SN;
+ if (this_size != size && (this_size != SB || size != SN))
+ found = 0;
+ }
+ else
+ {
+ unsigned int i;
+
+ for (i = 0; i < this_try->noperands && found; i++)
+ {
+ op_type op = this_try->args.nib[i];
+ int x = operands[i].mode;
+
+ if ((op & (DISP | REG)) == (DISP | REG)
+ && ((x & (DISP | REG)) == (DISP | REG)))
+ {
+ dispreg = operands[i].reg;
+ }
+ else if (op & REG)
+ {
+ if (!(x & REG))
+ found = 0;
+
+ if (x & L_P)
+ x = (x & ~L_P) | (Hmode ? L_32 : L_16);
+ if (op & L_P)
+ op = (op & ~L_P) | (Hmode ? L_32 : L_16);
+
+ opsize = op & SIZE;
+
+ /* The size of the reg is v important */
+ if ((op & SIZE) != (x & SIZE))
+ found = 0;
+ }
+ else if ((op & ABSJMP) && (x & ABS))
+ {
+ operands[i].mode &= ~ABS;
+ operands[i].mode |= ABSJMP;
+ /* But it may not be 24 bits long */
+ if (!Hmode)
+ {
+ operands[i].mode &= ~SIZE;
+ operands[i].mode |= L_16;
+ }
+ }
+ else if ((op & (KBIT | DBIT)) && (x & IMM))
+ {
+ /* This is ok if the immediate value is sensible */
+ }
+ else if (op & PCREL)
+ {
+ /* The size of the displacement is important */
+ if ((op & SIZE) != (x & SIZE))
+ found = 0;
+ }
+ else if ((op & (DISP | IMM | ABS))
+ && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS)))
+ {
+ /* Promote a L_24 to L_32 if it makes us match. */
+ if ((x & L_24) && (op & L_32))
+ {
+ x &= ~L_24;
+ x |= L_32;
+ }
+ /* Promote an L8 to L_16 if it makes us match. */
+ if (op & ABS && op & L_8 && op & DISP)
+ {
+ if (x & L_16)
+ found= 1;
+ }
+ else if ((x & SIZE) != 0
+ && ((op & SIZE) != (x & SIZE)))
+ found = 0;
+ }
+ else if ((op & MACREG) != (x & MACREG))
+ {
+ found = 0;
+ }
+ else if ((op & MODE) != (x & MODE))
+ {
+ found = 0;
+ }
+ }
+ }
+ }
+ if (found)
+ return this_try;
+ else
+ return 0;
+}
+
+static void
+check_operand (operand, width, string)
+ struct h8_op *operand;
+ unsigned int width;
+ char *string;
+{
+ if (operand->exp.X_add_symbol == 0
+ && operand->exp.X_op_symbol == 0)
+ {
+
+ /* No symbol involved, let's look at offset, it's dangerous if any of
+ the high bits are not 0 or ff's, find out by oring or anding with
+ the width and seeing if the answer is 0 or all fs*/
+
+ if ((operand->exp.X_add_number & ~width) != 0 &&
+ (operand->exp.X_add_number | width) != (~0))
+ {
+ if (width == 255
+ && (operand->exp.X_add_number & 0xff00) == 0xff00)
+ {
+ /* Just ignore this one - which happens when trying to
+ fit a 16 bit address truncated into an 8 bit address
+ of something like bset. */
+ }
+ else
+ {
+ as_warn (_("operand %s0x%lx out of range."), string,
+ (unsigned long) operand->exp.X_add_number);
+ }
+ }
+ }
+
+}
+
+/* RELAXMODE has one of 3 values:
+
+ 0 Output a "normal" reloc, no relaxing possible for this insn/reloc
+
+ 1 Output a relaxable 24bit absolute mov.w address relocation
+ (may relax into a 16bit absolute address).
+
+ 2 Output a relaxable 16/24 absolute mov.b address relocation
+ (may relax into an 8bit absolute address). */
+
+static void
+do_a_fix_imm (offset, operand, relaxmode)
+ int offset;
+ struct h8_op *operand;
+ int relaxmode;
+{
+ int idx;
+ int size;
+ int where;
+
+
+ char *t = operand->mode & IMM ? "#" : "@";
+
+ if (operand->exp.X_add_symbol == 0)
+ {
+ char *bytes = frag_now->fr_literal + offset;
+ switch (operand->mode & SIZE)
+ {
+ case L_2:
+ check_operand (operand, 0x3, t);
+ bytes[0] |= (operand->exp.X_add_number) << 4;
+ break;
+ case L_3:
+ check_operand (operand, 0x7, t);
+ bytes[0] |= (operand->exp.X_add_number) << 4;
+ break;
+ case L_8:
+ check_operand (operand, 0xff, t);
+ bytes[0] = operand->exp.X_add_number;
+ break;
+ case L_16:
+ check_operand (operand, 0xffff, t);
+ bytes[0] = operand->exp.X_add_number >> 8;
+ bytes[1] = operand->exp.X_add_number >> 0;
+ break;
+ case L_24:
+ check_operand (operand, 0xffffff, t);
+ bytes[0] = operand->exp.X_add_number >> 16;
+ bytes[1] = operand->exp.X_add_number >> 8;
+ bytes[2] = operand->exp.X_add_number >> 0;
+ break;
+
+ case L_32:
+ /* This should be done with bfd */
+ bytes[0] = operand->exp.X_add_number >> 24;
+ bytes[1] = operand->exp.X_add_number >> 16;
+ bytes[2] = operand->exp.X_add_number >> 8;
+ bytes[3] = operand->exp.X_add_number >> 0;
+ break;
+ }
+
+ }
+ else
+ {
+ switch (operand->mode & SIZE)
+ {
+
+ case L_24:
+ case L_32:
+ size = 4;
+ where = (operand->mode & SIZE) == L_24 ? -1 : 0;
+ if (relaxmode == 2)
+ idx = R_MOV24B1;
+ else if (relaxmode == 1)
+ idx = R_MOVL1;
+ else
+ idx = R_RELLONG;
+ break;
+ default:
+ as_bad(_("Can't work out size of operand.\n"));
+ case L_16:
+ size = 2;
+ where = 0;
+ if (relaxmode == 2)
+ idx = R_MOV16B1;
+ else
+ idx = R_RELWORD;
+ operand->exp.X_add_number = (short)operand->exp.X_add_number;
+ break;
+ case L_8:
+ size = 1;
+ where = 0;
+ idx = R_RELBYTE;
+ /* This used to use a cast to char, but that fails if char is an
+ unsigned type. We can't use `signed char', as that isn't valid
+ K&R C. */
+ if (operand->exp.X_add_number & 0x80)
+ operand->exp.X_add_number |= ((offsetT) -1 << 8);
+ else
+ operand->exp.X_add_number &= 0xff;
+ }
+
+ fix_new_exp (frag_now,
+ offset + where,
+ size,
+ &operand->exp,
+ 0,
+ idx);
+ }
+
+}
+
+/* Now we know what sort of opcodes it is, lets build the bytes -
+ */
+static void
+build_bytes (this_try, operand)
+ struct h8_opcode *this_try;
+ struct h8_op *operand;
+{
+ unsigned int i;
+
+ char *output = frag_more (this_try->length);
+ op_type *nibble_ptr = this_try->data.nib;
+ op_type c;
+ unsigned int nibble_count = 0;
+ int absat;
+ int immat;
+ int nib;
+ int movb = 0;
+ char asnibbles[30];
+ char *p = asnibbles;
+
+ if (!(this_try->inbase || Hmode))
+ as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
+ this_try->name);
+
+ while (*nibble_ptr != E)
+ {
+ int d;
+ c = *nibble_ptr++;
+
+ d = (c & (DST | SRC_IN_DST)) != 0;
+
+ if (c < 16)
+ {
+ nib = c;
+ }
+ else
+ {
+
+ if (c & (REG | IND | INC | DEC))
+ {
+ nib = operand[d].reg;
+ }
+ else if ((c & DISPREG) == (DISPREG))
+ {
+ nib = dispreg;
+ }
+ else if (c & ABS )
+ {
+ operand[d].mode = c;
+ absat = nibble_count / 2;
+ nib = 0;
+ }
+ else if (c & (IMM | PCREL | ABS | ABSJMP | DISP))
+ {
+ operand[d].mode = c;
+ immat = nibble_count / 2;
+ nib = 0;
+ }
+ else if (c & IGNORE)
+ {
+ nib = 0;
+ }
+ else if (c & DBIT)
+ {
+ switch (operand[0].exp.X_add_number)
+ {
+ case 1:
+ nib = c;
+ break;
+ case 2:
+ nib = 0x8 | c;
+ break;
+ default:
+ as_bad (_("Need #1 or #2 here"));
+ }
+ }
+ else if (c & KBIT)
+ {
+ switch (operand[0].exp.X_add_number)
+ {
+ case 1:
+ nib = 0;
+ break;
+ case 2:
+ nib = 8;
+ break;
+ case 4:
+ if (!Hmode)
+ as_warn (_("#4 not valid on H8/300."));
+ nib = 9;
+ break;
+
+ default:
+ as_bad (_("Need #1 or #2 here"));
+ break;
+ }
+ /* stop it making a fix */
+ operand[0].mode = 0;
+ }
+
+ if (c & MEMRELAX)
+ {
+ operand[d].mode |= MEMRELAX;
+ }
+
+ if (c & B31)
+ {
+ nib |= 0x8;
+ }
+
+ if (c & MACREG)
+ {
+ nib = 2 + operand[d].reg;
+ }
+ }
+ nibble_count++;
+
+ *p++ = nib;
+ }
+
+ /* Disgusting. Why, oh why didn't someone ask us for advice
+ on the assembler format. */
+ if (strcmp (this_try->name, "stm.l") == 0
+ || strcmp (this_try->name, "ldm.l") == 0)
+ {
+ int high, low;
+ high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf;
+ low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf;
+
+ asnibbles[2] = high - low;
+ asnibbles[7] = (this_try->name[0] == 'l') ? high : low;
+ }
+
+ for (i = 0; i < this_try->length; i++)
+ {
+ output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
+ }
+
+ /* Note if this is a movb instruction -- there's a special relaxation
+ which only applies to them. */
+ if (strcmp (this_try->name, "mov.b") == 0)
+ movb = 1;
+
+ /* output any fixes */
+ for (i = 0; i < 2; i++)
+ {
+ int x = operand[i].mode;
+
+ if (x & (IMM | DISP))
+ {
+ do_a_fix_imm (output - frag_now->fr_literal + immat,
+ operand + i, x & MEMRELAX != 0);
+ }
+ else if (x & ABS)
+ {
+ do_a_fix_imm (output - frag_now->fr_literal + absat,
+ operand + i, x & MEMRELAX ? movb + 1 : 0);
+ }
+ else if (x & PCREL)
+ {
+ int size16 = x & L_16;
+ int where = size16 ? 2 : 1;
+ int size = size16 ? 2 : 1;
+ int type = size16 ? R_PCRWORD : R_PCRBYTE;
+
+ check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
+
+ if (operand[i].exp.X_add_number & 1)
+ {
+ as_warn (_("branch operand has odd offset (%lx)\n"),
+ (unsigned long) operand->exp.X_add_number);
+ }
+
+ operand[i].exp.X_add_number -= 1;
+ /* This used to use a cast to char, but that fails if char is an
+ unsigned type. We can't use `signed char', as that isn't valid
+ K&R C. */
+ if (operand[i].exp.X_add_number & 0x80)
+ operand[i].exp.X_add_number |= ((offsetT) -1 << 8);
+ else
+ operand[i].exp.X_add_number &= 0xff;
+
+ fix_new_exp (frag_now,
+ output - frag_now->fr_literal + where,
+ size,
+ &operand[i].exp,
+ 1,
+ type);
+ }
+ else if (x & MEMIND)
+ {
+
+ check_operand (operand + i, 0xff, "@@");
+ fix_new_exp (frag_now,
+ output - frag_now->fr_literal + 1,
+ 1,
+ &operand[i].exp,
+ 0,
+ R_MEM_INDIRECT);
+ }
+ else if (x & ABSJMP)
+ {
+ /* This jmp may be a jump or a branch */
+
+ check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@");
+ if (operand[i].exp.X_add_number & 1)
+ {
+ as_warn (_("branch operand has odd offset (%lx)\n"),
+ (unsigned long) operand->exp.X_add_number);
+ }
+ if (!Hmode)
+ operand[i].exp.X_add_number = (short) operand[i].exp.X_add_number;
+ fix_new_exp (frag_now,
+ output - frag_now->fr_literal,
+ 4,
+ &operand[i].exp,
+ 0,
+ R_JMPL1);
+ }
+ }
+
+}
+
+/*
+ try and give an intelligent error message for common and simple to
+ detect errors
+ */
+
+static void
+clever_message (opcode, operand)
+ struct h8_opcode *opcode;
+ struct h8_op *operand;
+{
+ /* Find out if there was more than one possible opccode */
+
+ if ((opcode + 1)->idx != opcode->idx)
+ {
+ unsigned int argn;
+
+ /* Only one opcode of this flavour, try and guess which operand
+ didn't match */
+ for (argn = 0; argn < opcode->noperands; argn++)
+ {
+ switch (opcode->args.nib[argn])
+ {
+ case RD16:
+ if (operand[argn].mode != RD16)
+ {
+ as_bad (_("destination operand must be 16 bit register"));
+ return;
+
+ }
+ break;
+
+ case RS8:
+
+ if (operand[argn].mode != RS8)
+ {
+ as_bad (_("source operand must be 8 bit register"));
+ return;
+ }
+ break;
+
+ case ABS16DST:
+ if (operand[argn].mode != ABS16DST)
+ {
+ as_bad (_("destination operand must be 16bit absolute address"));
+ return;
+ }
+ break;
+ case RD8:
+ if (operand[argn].mode != RD8)
+ {
+ as_bad (_("destination operand must be 8 bit register"));
+ return;
+ }
+ break;
+
+
+ case ABS16SRC:
+ if (operand[argn].mode != ABS16SRC)
+ {
+ as_bad (_("source operand must be 16bit absolute address"));
+ return;
+ }
+ break;
+
+ }
+ }
+ }
+ as_bad (_("invalid operands"));
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This funciton is supposed to emit
+ the frags/bytes it assembles to.
+ */
+
+
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *op_start;
+ char *op_end;
+ struct h8_op operand[2];
+ struct h8_opcode *opcode;
+ struct h8_opcode *prev_opcode;
+
+ char *dot = 0;
+ char c;
+ int size;
+
+ /* Drop leading whitespace */
+ while (*str == ' ')
+ str++;
+
+ /* find the op code end */
+ for (op_start = op_end = str;
+ *op_end != 0 && *op_end != ' ';
+ op_end++)
+ {
+ if (*op_end == '.')
+ {
+ dot = op_end + 1;
+ *op_end = 0;
+ op_end += 2;
+ break;
+ }
+ }
+
+ ;
+
+ if (op_end == op_start)
+ {
+ as_bad (_("can't find opcode "));
+ }
+ c = *op_end;
+
+ *op_end = 0;
+
+ opcode = (struct h8_opcode *) hash_find (opcode_hash_control,
+ op_start);
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ /* We use to set input_line_pointer to the result of get_operands,
+ but that is wrong. Our caller assumes we don't change it. */
+
+ (void) get_operands (opcode->noperands, op_end, operand);
+ *op_end = c;
+ prev_opcode = opcode;
+
+ size = SN;
+ if (dot)
+ {
+ switch (*dot)
+ {
+ case 'b':
+ size = SB;
+ break;
+
+ case 'w':
+ size = SW;
+ break;
+
+ case 'l':
+ size = SL;
+ break;
+ }
+ }
+ opcode = get_specific (opcode, operand, size);
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands */
+ char *where = frag_more (2);
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+ clever_message (prev_opcode, operand);
+
+ return;
+ }
+ if (opcode->size && dot)
+ {
+ if (opcode->size != *dot)
+ {
+ as_warn (_("mismatch between opcode size and operand size"));
+ }
+ }
+
+ build_bytes (opcode, operand);
+
+}
+
+void
+tc_crawl_symbol_chain (headers)
+ object_headers * headers;
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+void
+tc_headers_hook (headers)
+ object_headers * headers;
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+/* Various routines to kill one day */
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+
+void
+tc_aout_fix_to_chars ()
+{
+ printf (_("call to tc_aout_fix_to_chars \n"));
+ abort ();
+}
+
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ printf (_("call to md_convert_frag \n"));
+ abort ();
+}
+
+valueT
+md_section_align (seg, size)
+ segT seg;
+ valueT size;
+{
+ return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
+
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ switch (fixP->fx_size)
+ {
+ case 1:
+ *buf++ = val;
+ break;
+ case 2:
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ case 4:
+ *buf++ = (val >> 24);
+ *buf++ = (val >> 16);
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ default:
+ abort ();
+ }
+}
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ printf (_("call tomd_estimate_size_before_relax \n"));
+ abort ();
+}
+
+/* Put number into target byte order */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char *ptr;
+ valueT use;
+ int nbytes;
+{
+ number_to_chars_bigendian (ptr, use, nbytes);
+}
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ abort ();
+}
+
+
+void
+tc_reloc_mangle (fix_ptr, intr, base)
+ fixS *fix_ptr;
+ struct internal_reloc *intr;
+ bfd_vma base;
+
+{
+ symbolS *symbol_ptr;
+
+ symbol_ptr = fix_ptr->fx_addsy;
+
+ /* If this relocation is attached to a symbol then it's ok
+ to output it */
+ if (fix_ptr->fx_r_type == TC_CONS_RELOC)
+ {
+ /* cons likes to create reloc32's whatever the size of the reloc..
+ */
+ switch (fix_ptr->fx_size)
+ {
+ case 4:
+ intr->r_type = R_RELLONG;
+ break;
+ case 2:
+ intr->r_type = R_RELWORD;
+ break;
+ case 1:
+ intr->r_type = R_RELBYTE;
+ break;
+ default:
+ abort ();
+
+ }
+
+ }
+ else
+ {
+ intr->r_type = fix_ptr->fx_r_type;
+ }
+
+ intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
+ intr->r_offset = fix_ptr->fx_offset;
+
+ if (symbol_ptr)
+ {
+ if (symbol_ptr->sy_number != -1)
+ intr->r_symndx = symbol_ptr->sy_number;
+ else
+ {
+ symbolS *segsym;
+
+ /* This case arises when a reference is made to `.'. */
+ segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot;
+ if (segsym == NULL)
+ intr->r_symndx = -1;
+ else
+ {
+ intr->r_symndx = segsym->sy_number;
+ intr->r_offset += S_GET_VALUE (symbol_ptr);
+ }
+ }
+ }
+ else
+ intr->r_symndx = -1;
+
+
+}
+
+/* end of tc-h8300.c */
diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h
new file mode 100644
index 00000000000..2a2a7040f3c
--- /dev/null
+++ b/gas/config/tc-h8300.h
@@ -0,0 +1,58 @@
+/* This file is tc-h8300.h
+ Copyright (C) 1987-1992, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+#define TC_H8300
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#if ANSI_PROTOTYPES
+struct internal_reloc;
+#endif
+
+#define WORKING_DOT_WORD
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fixP) abort();
+
+#define BFD_ARCH bfd_arch_h8300
+#define COFF_MAGIC ( Smode ? 0x8302 : Hmode ? 0x8301 : 0x8300)
+#define TC_COUNT_RELOC(x) (1)
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define tc_coff_symbol_emit_hook(a) ; /* not used */
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
+extern void tc_reloc_mangle
+ PARAMS ((struct fix *, struct internal_reloc *, bfd_vma));
+
+#define TC_CONS_RELOC (Hmode ? R_RELLONG: R_RELWORD)
+
+#define DO_NOT_STRIP 0
+#define LISTING_HEADER "Hitachi H8/300 GAS "
+#define NEED_FX_R_TYPE 1
+#define RELOC_32 1234
+
+extern int Hmode;
+extern int Smode;
+
+#define md_operand(x)
+
+/* end of tc-h8300.h */
diff --git a/gas/config/tc-h8500.c b/gas/config/tc-h8500.c
new file mode 100644
index 00000000000..9dec3e2e6a2
--- /dev/null
+++ b/gas/config/tc-h8500.c
@@ -0,0 +1,1633 @@
+/* tc-h8500.c -- Assemble code for the Hitachi H8/500
+ Copyright (C) 1993, 94, 95, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ Written By Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include <stdio.h>
+#include "as.h"
+#include "bfd.h"
+#include "subsegs.h"
+#define DEFINE_TABLE
+#define ASSEMBLER_TABLE
+#include "opcodes/h8500-opc.h"
+#include <ctype.h>
+
+const char comment_chars[] = "!";
+const char line_separator_chars[] = ";";
+const char line_comment_chars[] = "!#";
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+void cons ();
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"int", cons, 2},
+ {"data.b", cons, 1},
+ {"data.w", cons, 2},
+ {"data.l", cons, 4},
+ {"form", listing_psize, 0},
+ {"heading", listing_title, 0},
+ {"import", s_ignore, 0},
+ {"page", listing_eject, 0},
+ {"program", s_ignore, 0},
+ {0, 0, 0}
+};
+
+const int md_reloc_size;
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+#define C(a,b) ENCODE_RELAX(a,b)
+#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+
+#define GET_WHAT(x) ((x>>2))
+
+#define BYTE_DISP 1
+#define WORD_DISP 2
+#define UNDEF_BYTE_DISP 0
+#define UNDEF_WORD_DISP 3
+
+#define BRANCH 1
+#define SCB_F 2
+#define SCB_TST 3
+#define END 4
+
+#define BYTE_F 127
+#define BYTE_B -126
+#define WORD_F 32767
+#define WORD_B 32768
+
+relax_typeS md_relax_table[C (END, 0)];
+
+static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
+
+/*
+ This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs
+ */
+
+void
+md_begin ()
+{
+ h8500_opcode_info *opcode;
+ char prev_buffer[100];
+ int idx = 0;
+ register relax_typeS *table;
+
+ opcode_hash_control = hash_new ();
+ prev_buffer[0] = 0;
+
+ /* Insert unique names into hash table */
+ for (opcode = h8500_table; opcode->name; opcode++)
+ {
+ if (idx != opcode->idx)
+ {
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ idx++;
+ }
+ }
+
+ /* Initialize the relax table. We use a local variable to avoid
+ warnings about modifying a supposedly const data structure. */
+ table = (relax_typeS *) md_relax_table;
+ table[C (BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
+ table[C (BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
+ table[C (BRANCH, BYTE_DISP)].rlx_length = 2;
+ table[C (BRANCH, BYTE_DISP)].rlx_more = C (BRANCH, WORD_DISP);
+
+ table[C (BRANCH, WORD_DISP)].rlx_forward = WORD_F;
+ table[C (BRANCH, WORD_DISP)].rlx_backward = WORD_B;
+ table[C (BRANCH, WORD_DISP)].rlx_length = 3;
+ table[C (BRANCH, WORD_DISP)].rlx_more = 0;
+
+ table[C (SCB_F, BYTE_DISP)].rlx_forward = BYTE_F;
+ table[C (SCB_F, BYTE_DISP)].rlx_backward = BYTE_B;
+ table[C (SCB_F, BYTE_DISP)].rlx_length = 3;
+ table[C (SCB_F, BYTE_DISP)].rlx_more = C (SCB_F, WORD_DISP);
+
+ table[C (SCB_F, WORD_DISP)].rlx_forward = WORD_F;
+ table[C (SCB_F, WORD_DISP)].rlx_backward = WORD_B;
+ table[C (SCB_F, WORD_DISP)].rlx_length = 8;
+ table[C (SCB_F, WORD_DISP)].rlx_more = 0;
+
+ table[C (SCB_TST, BYTE_DISP)].rlx_forward = BYTE_F;
+ table[C (SCB_TST, BYTE_DISP)].rlx_backward = BYTE_B;
+ table[C (SCB_TST, BYTE_DISP)].rlx_length = 3;
+ table[C (SCB_TST, BYTE_DISP)].rlx_more = C (SCB_TST, WORD_DISP);
+
+ table[C (SCB_TST, WORD_DISP)].rlx_forward = WORD_F;
+ table[C (SCB_TST, WORD_DISP)].rlx_backward = WORD_B;
+ table[C (SCB_TST, WORD_DISP)].rlx_length = 10;
+ table[C (SCB_TST, WORD_DISP)].rlx_more = 0;
+
+}
+
+static int rn; /* register number used by RN */
+static int rs; /* register number used by RS */
+static int rd; /* register number used by RD */
+static int crb; /* byte size cr */
+static int crw; /* word sized cr */
+static int cr; /* unknown size cr */
+
+static expressionS displacement;/* displacement expression */
+static int displacement_size; /* and size if given */
+
+static int immediate_inpage;
+static expressionS immediate; /* immediate expression */
+static int immediate_size; /* and size if given */
+
+static expressionS absolute; /* absolute expression */
+static int absolute_size; /* and size if given */
+
+typedef struct
+{
+ int type;
+ int reg;
+ expressionS exp;
+ int page;
+}
+
+h8500_operand_info;
+
+/* try and parse a reg name, returns number of chars consumed */
+static int
+parse_reg (src, mode, reg)
+ char *src;
+ int *mode;
+ int *reg;
+{
+ char *end;
+ int len;
+
+ /* Cribbed from get_symbol_end(). */
+ if (!is_name_beginner (*src) || *src == '\001')
+ return 0;
+ end = src+1;
+ while (is_part_of_name (*end) || *end == '\001')
+ end++;
+ len = end - src;
+
+ if (len == 2 && src[0] == 'r')
+ {
+ if (src[1] >= '0' && src[1] <= '7')
+ {
+ *mode = RN;
+ *reg = (src[1] - '0');
+ return len;
+ }
+ }
+ if (len == 2 && src[0] == 's' && src[1] == 'p')
+ {
+ *mode = RN;
+ *reg = 7;
+ return len;
+ }
+ if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')
+ {
+ *mode = CRB;
+ *reg = 1;
+ return len;
+ }
+ if (len == 2 && src[0] == 's' && src[1] == 'r')
+ {
+ *mode = CRW;
+ *reg = 0;
+ return len;
+ }
+ if (len == 2 && src[0] == 'b' && src[1] == 'r')
+ {
+ *mode = CRB;
+ *reg = 3;
+ return len;
+ }
+ if (len == 2 && src[0] == 'e' && src[1] == 'p')
+ {
+ *mode = CRB;
+ *reg = 4;
+ return len;
+ }
+ if (len == 2 && src[0] == 'd' && src[1] == 'p')
+ {
+ *mode = CRB;
+ *reg = 5;
+ return len;
+ }
+ if (len == 2 && src[0] == 't' && src[1] == 'p')
+ {
+ *mode = CRB;
+ *reg = 7;
+ return len;
+ }
+ if (len == 2 && src[0] == 'f' && src[1] == 'p')
+ {
+ *mode = RN;
+ *reg = 6;
+ return len;
+ }
+ return 0;
+}
+
+static
+char *
+parse_exp (s, op, page)
+ char *s;
+ expressionS *op;
+ int *page;
+{
+ char *save;
+ char *new;
+
+ save = input_line_pointer;
+
+ *page = 0;
+ if (s[0] == '%')
+ {
+ if (s[1] == 'p' && s[2] == 'a' && s[3] == 'g' && s[4] == 'e')
+ {
+ s += 5;
+ *page = 'p';
+ }
+ if (s[1] == 'h' && s[2] == 'i' && s[3] == '1' && s[4] == '6')
+ {
+ s += 5;
+ *page = 'h';
+ }
+ else if (s[1] == 'o' && s[2] == 'f' && s[3] == 'f')
+ {
+ s += 4;
+ *page = 'o';
+ }
+ }
+
+ input_line_pointer = s;
+
+ expression (op);
+ if (op->X_op == O_absent)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+typedef enum
+ {
+ exp_signed, exp_unsigned, exp_sandu
+ } sign_type;
+
+
+static char *
+skip_colonthing (sign, ptr, exp, def, size8, size16, size24)
+ sign_type sign;
+ char *ptr;
+ h8500_operand_info *exp;
+ int def;
+ int size8;
+ int size16;
+ int size24;
+{
+ ptr = parse_exp (ptr, &exp->exp, &exp->page);
+ if (*ptr == ':')
+ {
+ ptr++;
+ if (*ptr == '8')
+ {
+ ptr++;
+ exp->type = size8;
+ }
+ else if (ptr[0] == '1' & ptr[1] == '6')
+ {
+ ptr += 2;
+ exp->type = size16;
+ }
+ else if (ptr[0] == '2' & ptr[1] == '4')
+ {
+ if (!size24)
+ {
+ as_bad (_(":24 not valid for this opcode"));
+ }
+ ptr += 2;
+ exp->type = size24;
+ }
+ else
+ {
+ as_bad (_("expect :8,:16 or :24"));
+ exp->type = size16;
+ }
+ }
+ else
+ {
+ if (exp->page == 'p')
+ {
+ exp->type = IMM8;
+ }
+ else if (exp->page == 'h')
+ {
+ exp->type = IMM16;
+ }
+ else
+ {
+ /* Let's work out the size from the context */
+ int n = exp->exp.X_add_number;
+ if (size8
+ && exp->exp.X_op == O_constant
+ && ((sign == exp_signed && (n >= -128 && n <= 127))
+ || (sign == exp_unsigned && (n >= 0 && (n <= 255)))
+ || (sign == exp_sandu && (n >= -128 && (n <= 255)))))
+ {
+ exp->type = size8;
+ }
+ else
+ {
+ exp->type = def;
+ }
+ }
+ }
+ return ptr;
+}
+
+static int
+parse_reglist (src, op)
+ char *src;
+ h8500_operand_info *op;
+{
+ int mode;
+ int rn;
+ int mask = 0;
+ int rm;
+ int idx = 1; /* skip ( */
+
+ while (src[idx] && src[idx] != ')')
+ {
+ int done = parse_reg (src + idx, &mode, &rn);
+
+ if (done)
+ {
+ idx += done;
+ mask |= 1 << rn;
+ }
+ else
+ {
+ as_bad (_("syntax error in reg list"));
+ return 0;
+ }
+ if (src[idx] == '-')
+ {
+ idx++;
+ done = parse_reg (src + idx, &mode, &rm);
+ if (done)
+ {
+ idx += done;
+ while (rn <= rm)
+ {
+ mask |= 1 << rn;
+ rn++;
+ }
+ }
+ else
+ {
+ as_bad (_("missing final register in range"));
+ }
+ }
+ if (src[idx] == ',')
+ idx++;
+ }
+ idx++;
+ op->exp.X_add_symbol = 0;
+ op->exp.X_op_symbol = 0;
+ op->exp.X_add_number = mask;
+ op->exp.X_op = O_constant;
+ op->exp.X_unsigned = 1;
+ op->type = IMM8;
+ return idx;
+
+}
+
+/* The many forms of operand:
+
+ Rn Register direct
+ @Rn Register indirect
+ @(disp[:size], Rn) Register indirect with displacement
+ @Rn+
+ @-Rn
+ @aa[:size] absolute
+ #xx[:size] immediate data
+
+ */
+
+static void
+get_operand (ptr, op, ispage)
+ char **ptr;
+ h8500_operand_info *op;
+ char ispage;
+{
+ char *src = *ptr;
+ int mode;
+ unsigned int num;
+ unsigned int len;
+ op->page = 0;
+ if (src[0] == '(' && src[1] == 'r')
+ {
+ /* This is a register list */
+ *ptr = src + parse_reglist (src, op);
+ return;
+ }
+
+ len = parse_reg (src, &op->type, &op->reg);
+
+ if (len)
+ {
+ *ptr = src + len;
+ return;
+ }
+
+ if (*src == '@')
+ {
+ src++;
+ if (*src == '-')
+ {
+ src++;
+ len = parse_reg (src, &mode, &num);
+ if (len == 0)
+ {
+ /* Oops, not a reg after all, must be ordinary exp */
+ src--;
+ /* must be a symbol */
+ *ptr = skip_colonthing (exp_unsigned, src,
+ op, ABS16, ABS8, ABS16, ABS24);
+ return;
+ }
+
+ op->type = RNDEC;
+ op->reg = num;
+ *ptr = src + len;
+ return;
+ }
+ if (*src == '(')
+ {
+ /* Disp */
+ src++;
+
+ src = skip_colonthing (exp_signed, src,
+ op, RNIND_D16, RNIND_D8, RNIND_D16, 0);
+
+ if (*src != ',')
+ {
+ as_bad (_("expected @(exp, Rn)"));
+ return;
+ }
+ src++;
+ len = parse_reg (src, &mode, &op->reg);
+ if (len == 0 || mode != RN)
+ {
+ as_bad (_("expected @(exp, Rn)"));
+ return;
+ }
+ src += len;
+ if (*src != ')')
+ {
+ as_bad (_("expected @(exp, Rn)"));
+ return;
+ }
+ *ptr = src + 1;
+ return;
+ }
+ len = parse_reg (src, &mode, &num);
+
+ if (len)
+ {
+ src += len;
+ if (*src == '+')
+ {
+ src++;
+ if (mode != RN)
+ {
+ as_bad (_("@Rn+ needs word register"));
+ return;
+ }
+ op->type = RNINC;
+ op->reg = num;
+ *ptr = src;
+ return;
+ }
+ if (mode != RN)
+ {
+ as_bad (_("@Rn needs word register"));
+ return;
+ }
+ op->type = RNIND;
+ op->reg = num;
+ *ptr = src;
+ return;
+ }
+ else
+ {
+ /* must be a symbol */
+ *ptr =
+ skip_colonthing (exp_unsigned, src, op,
+ ispage ? ABS24 : ABS16, ABS8, ABS16, ABS24);
+ return;
+ }
+ }
+
+ if (*src == '#')
+ {
+ src++;
+ *ptr = skip_colonthing (exp_sandu, src, op, IMM16, IMM8, IMM16, ABS24);
+ return;
+ }
+ else
+ {
+ *ptr = skip_colonthing (exp_signed, src, op,
+ ispage ? ABS24 : PCREL8, PCREL8, PCREL16, ABS24);
+ }
+}
+
+static
+char *
+get_operands (info, args, operand)
+ h8500_opcode_info *info;
+ char *args;
+ h8500_operand_info *operand;
+
+{
+ char *ptr = args;
+
+ switch (info->nargs)
+ {
+ case 0:
+ operand[0].type = 0;
+ operand[1].type = 0;
+ break;
+
+ case 1:
+ ptr++;
+ get_operand (&ptr, operand + 0, info->name[0] == 'p');
+ operand[1].type = 0;
+ break;
+
+ case 2:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 0);
+ break;
+
+ default:
+ abort ();
+ }
+
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes, return the opcode which matches the opcodes
+ provided
+ */
+
+int pcrel8; /* Set when we've seen a pcrel operand */
+
+static
+h8500_opcode_info *
+get_specific (opcode, operands)
+ h8500_opcode_info *opcode;
+ h8500_operand_info *operands;
+{
+ h8500_opcode_info *this_try = opcode;
+ int found = 0;
+ unsigned int noperands = opcode->nargs;
+
+ unsigned int this_index = opcode->idx;
+
+ while (this_index == opcode->idx && !found)
+ {
+ unsigned int i;
+
+ this_try = opcode++;
+
+ /* look at both operands needed by the opcodes and provided by
+ the user*/
+ for (i = 0; i < noperands; i++)
+ {
+ h8500_operand_info *user = operands + i;
+
+ switch (this_try->arg_type[i])
+ {
+ case FPIND_D8:
+ /* Opcode needs (disp:8,fp) */
+ if (user->type == RNIND_D8 && user->reg == 6)
+ {
+ displacement = user->exp;
+ continue;
+ }
+ break;
+ case RDIND_D16:
+ if (user->type == RNIND_D16)
+ {
+ displacement = user->exp;
+ rd = user->reg;
+ continue;
+ }
+ break;
+ case RDIND_D8:
+ if (user->type == RNIND_D8)
+ {
+ displacement = user->exp;
+ rd = user->reg;
+ continue;
+ }
+ break;
+ case RNIND_D16:
+ case RNIND_D8:
+ if (user->type == this_try->arg_type[i])
+ {
+ displacement = user->exp;
+ rn = user->reg;
+ continue;
+ }
+ break;
+
+ case SPDEC:
+ if (user->type == RNDEC && user->reg == 7)
+ {
+ continue;
+ }
+ break;
+ case SPINC:
+ if (user->type == RNINC && user->reg == 7)
+ {
+ continue;
+ }
+ break;
+ case ABS16:
+ if (user->type == ABS16)
+ {
+ absolute = user->exp;
+ continue;
+ }
+ break;
+ case ABS8:
+ if (user->type == ABS8)
+ {
+ absolute = user->exp;
+ continue;
+ }
+ break;
+ case ABS24:
+ if (user->type == ABS24)
+ {
+ absolute = user->exp;
+ continue;
+ }
+ break;
+
+ case CRB:
+ if ((user->type == CRB || user->type == CR) && user->reg != 0)
+ {
+ crb = user->reg;
+ continue;
+ }
+ break;
+ case CRW:
+ if ((user->type == CRW || user->type == CR) && user->reg == 0)
+ {
+ crw = user->reg;
+ continue;
+ }
+ break;
+ case DISP16:
+ if (user->type == DISP16)
+ {
+ displacement = user->exp;
+ continue;
+ }
+ break;
+ case DISP8:
+ if (user->type == DISP8)
+ {
+ displacement = user->exp;
+ continue;
+ }
+ break;
+ case FP:
+ if (user->type == RN && user->reg == 6)
+ {
+ continue;
+ }
+ break;
+ case PCREL16:
+ if (user->type == PCREL16)
+ {
+ displacement = user->exp;
+ continue;
+ }
+ break;
+ case PCREL8:
+ if (user->type == PCREL8)
+ {
+ displacement = user->exp;
+ pcrel8 = 1;
+ continue;
+ }
+ break;
+
+ case IMM16:
+ if (user->type == IMM16
+ || user->type == IMM8)
+ {
+ immediate_inpage = user->page;
+ immediate = user->exp;
+ continue;
+ }
+ break;
+ case RLIST:
+ case IMM8:
+ if (user->type == IMM8)
+ {
+ immediate_inpage = user->page;
+ immediate = user->exp;
+ continue;
+ }
+ break;
+ case IMM4:
+ if (user->type == IMM8)
+ {
+ immediate_inpage = user->page;
+ immediate = user->exp;
+ continue;
+ }
+ break;
+ case QIM:
+ if (user->type == IMM8
+ && user->exp.X_op == O_constant
+ &&
+ (user->exp.X_add_number == -2
+ || user->exp.X_add_number == -1
+ || user->exp.X_add_number == 1
+ || user->exp.X_add_number == 2))
+ {
+ immediate_inpage = user->page;
+ immediate = user->exp;
+ continue;
+ }
+ break;
+ case RD:
+ if (user->type == RN)
+ {
+ rd = user->reg;
+ continue;
+ }
+ break;
+ case RS:
+ if (user->type == RN)
+ {
+ rs = user->reg;
+ continue;
+ }
+ break;
+ case RDIND:
+ if (user->type == RNIND)
+ {
+ rd = user->reg;
+ continue;
+
+ }
+ break;
+ case RNINC:
+ case RNIND:
+ case RNDEC:
+ case RN:
+
+ if (user->type == this_try->arg_type[i])
+ {
+ rn = user->reg;
+ continue;
+ }
+ break;
+ case SP:
+ if (user->type == RN && user->reg == 7)
+ {
+ continue;
+ }
+ break;
+ default:
+ printf (_("unhandled %d\n"), this_try->arg_type[i]);
+ break;
+ }
+
+ /* If we get here this didn't work out */
+ goto fail;
+ }
+ found = 1;
+ fail:;
+
+ }
+
+ if (found)
+ return this_try;
+ else
+ return 0;
+}
+
+int
+check (operand, low, high)
+ expressionS *operand;
+ int low;
+ int high;
+{
+ if (operand->X_op != O_constant
+ || operand->X_add_number < low
+ || operand->X_add_number > high)
+ {
+ as_bad (_("operand must be absolute in range %d..%d"), low, high);
+ }
+ return operand->X_add_number;
+}
+
+static
+void
+insert (output, index, exp, reloc, pcrel)
+ char *output;
+ int index;
+ expressionS *exp;
+ int reloc;
+ int pcrel;
+{
+ fix_new_exp (frag_now,
+ output - frag_now->fr_literal + index,
+ 4, /* always say size is 4, but we know better */
+ exp,
+ pcrel,
+ reloc);
+}
+
+void
+build_relaxable_instruction (opcode, operand)
+ h8500_opcode_info *opcode;
+ h8500_operand_info *operand;
+{
+ /* All relaxable instructions start life as two bytes but can become
+ three bytes long if a lonely branch and up to 9 bytes if long scb
+ */
+ char *p;
+ int len;
+ int type;
+
+ if (opcode->bytes[0].contents == 0x01)
+ {
+ type = SCB_F;
+ }
+ else if (opcode->bytes[0].contents == 0x06
+ || opcode->bytes[0].contents == 0x07)
+ {
+ type = SCB_TST;
+ }
+ else
+ {
+ type = BRANCH;
+ }
+
+ p = frag_var (rs_machine_dependent,
+ md_relax_table[C (type, WORD_DISP)].rlx_length,
+ len = md_relax_table[C (type, BYTE_DISP)].rlx_length,
+ C (type, UNDEF_BYTE_DISP),
+ displacement.X_add_symbol,
+ displacement.X_add_number,
+ 0);
+
+ p[0] = opcode->bytes[0].contents;
+ if (type != BRANCH)
+ {
+ p[1] = opcode->bytes[1].contents | rs;
+ }
+}
+
+/* Now we know what sort of opcodes it is, lets build the bytes -
+ */
+static void
+build_bytes (opcode, operand)
+ h8500_opcode_info *opcode;
+ h8500_operand_info *operand;
+
+{
+ int index;
+
+ if (pcrel8)
+ {
+ pcrel8 = 0;
+ build_relaxable_instruction (opcode, operand);
+ }
+ else
+ {
+ char *output = frag_more (opcode->length);
+
+ memset (output, 0, opcode->length);
+ for (index = 0; index < opcode->length; index++)
+ {
+ output[index] = opcode->bytes[index].contents;
+
+ switch (opcode->bytes[index].insert)
+ {
+ default:
+ printf (_("failed for %d\n"), opcode->bytes[index].insert);
+ break;
+ case 0:
+ break;
+ case RN:
+ output[index] |= rn;
+ break;
+ case RD:
+ case RDIND:
+
+ output[index] |= rd;
+ break;
+ case RS:
+ output[index] |= rs;
+ break;
+ case DISP16:
+ insert (output, index, &displacement, R_H8500_IMM16, 0);
+ index++;
+ break;
+ case DISP8:
+ case FPIND_D8:
+ insert (output, index, &displacement, R_H8500_IMM8, 0);
+ break;
+
+ case IMM16:
+ {
+ int p;
+ switch (immediate_inpage) {
+ case 'p':
+ p = R_H8500_HIGH16;
+ break;
+ case 'h':
+ p = R_H8500_HIGH16;
+ break;
+ default:
+ p = R_H8500_IMM16;
+ break;
+ }
+
+ insert (output, index, &immediate,p, 0);
+ }
+
+ index++;
+ break;
+ case RLIST:
+ case IMM8:
+ if (immediate_inpage)
+ {
+ insert (output, index, &immediate, R_H8500_HIGH8, 0);
+ }
+ else
+ {
+ insert (output, index, &immediate, R_H8500_IMM8, 0);
+ }
+ break;
+ case PCREL16:
+ insert (output, index, &displacement, R_H8500_PCREL16, 1);
+ index++;
+ break;
+ case PCREL8:
+ insert (output, index, &displacement, R_H8500_PCREL8, 1);
+ break;
+ case IMM4:
+ output[index] |= check (&immediate, 0, 15);
+ break;
+ case CR:
+
+ output[index] |= cr;
+ if (cr == 0)
+ {
+ output[0] |= 0x8;
+ }
+ else
+ {
+ output[0] &= ~0x8;
+ }
+
+ break;
+
+ case CRB:
+ output[index] |= crb;
+ output[0] &= ~0x8;
+ break;
+ case CRW:
+ output[index] |= crw;
+ output[0] |= 0x8;
+ break;
+ case ABS24:
+ insert (output, index, &absolute, R_H8500_IMM24, 0);
+ index += 2;
+ break;
+ case ABS16:
+ insert (output, index, &absolute, R_H8500_IMM16, 0);
+ index++;
+ break;
+ case ABS8:
+ insert (output, index, &absolute, R_H8500_IMM8, 0);
+ break;
+ case QIM:
+ switch (immediate.X_add_number)
+ {
+ case -2:
+ output[index] |= 0x5;
+ break;
+ case -1:
+ output[index] |= 0x4;
+ break;
+ case 1:
+ output[index] |= 0;
+ break;
+ case 2:
+ output[index] |= 1;
+ break;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This funciton is supposed to emit
+ the frags/bytes it assembles to.
+ */
+
+void
+DEFUN (md_assemble, (str),
+ char *str)
+{
+ char *op_start;
+ char *op_end;
+ h8500_operand_info operand[2];
+ h8500_opcode_info *opcode;
+ h8500_opcode_info *prev_opcode;
+ char name[11];
+
+ int nlen = 0;
+
+ /* Drop leading whitespace */
+ while (*str == ' ')
+ str++;
+
+ /* find the op code end */
+ for (op_start = op_end = str;
+ *op_end &&
+ !is_end_of_line[*op_end] && *op_end != ' ';
+ op_end++)
+ {
+ if ( /**op_end != '.'
+ && *op_end != ':'
+ && */ nlen < 10)
+ {
+ name[nlen++] = *op_end;
+ }
+ }
+ name[nlen] = 0;
+
+ if (op_end == op_start)
+ {
+ as_bad (_("can't find opcode "));
+ }
+
+ opcode = (h8500_opcode_info *) hash_find (opcode_hash_control, name);
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ get_operands (opcode, op_end, operand);
+ prev_opcode = opcode;
+
+ opcode = get_specific (opcode, operand);
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands */
+ char *where = frag_more (2);
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+ as_bad (_("invalid operands for opcode"));
+ return;
+ }
+
+ build_bytes (opcode, operand);
+
+}
+
+void
+DEFUN (tc_crawl_symbol_chain, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+symbolS *
+DEFUN (md_undefined_symbol, (name),
+ char *name)
+{
+ return 0;
+}
+
+void
+DEFUN (tc_headers_hook, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+/* Various routines to kill one day */
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+
+void
+tc_aout_fix_to_chars ()
+{
+ printf (_("call to tc_aout_fix_to_chars \n"));
+ abort ();
+}
+
+static
+void
+wordify_scb (buffer, disp_size, inst_size)
+ char *buffer;
+ int *disp_size;
+ int *inst_size;
+{
+ int rn = buffer[1] & 0x7;
+
+ switch (buffer[0])
+ {
+ case 0x0e: /* BSR */
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ case 0x2c:
+ case 0x2d:
+ case 0x2e:
+ case 0x2f:
+ buffer[0] |= 0x10;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ *disp_size = 2;
+ *inst_size = 1;
+ return;
+ default:
+ abort ();
+
+ case 0x01:
+ *inst_size = 6;
+ *disp_size = 2;
+ break;
+ case 0x06:
+ *inst_size = 8;
+ *disp_size = 2;
+
+ *buffer++ = 0x26; /* bne + 8 */
+ *buffer++ = 0x08;
+ break;
+ case 0x07:
+ *inst_size = 8;
+ *disp_size = 2;
+ *buffer++ = 0x27; /* bne + 8 */
+ *buffer++ = 0x08;
+ break;
+
+ }
+ *buffer++ = 0xa8 | rn; /* addq -1,rn */
+ *buffer++ = 0x0c;
+ *buffer++ = 0x04; /* cmp #0xff:8, rn */
+ *buffer++ = 0xff;
+ *buffer++ = 0x70 | rn;
+ *buffer++ = 0x36; /* bne ... */
+ *buffer++ = 0;
+ *buffer++ = 0;
+}
+
+/*
+called after relaxing, change the frags so they know how big they are
+*/
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ int disp_size = 0;
+ int inst_size = 0;
+ char *buffer = fragP->fr_fix + fragP->fr_literal;
+
+ switch (fragP->fr_subtype)
+ {
+ case C (BRANCH, BYTE_DISP):
+ disp_size = 1;
+ inst_size = 1;
+ break;
+
+ case C (SCB_F, BYTE_DISP):
+ case C (SCB_TST, BYTE_DISP):
+ disp_size = 1;
+ inst_size = 2;
+ break;
+
+ /* Branches to a known 16 bit displacement */
+
+ /* Turn on the 16bit bit */
+ case C (BRANCH, WORD_DISP):
+ case C (SCB_F, WORD_DISP):
+ case C (SCB_TST, WORD_DISP):
+ wordify_scb (buffer, &disp_size, &inst_size);
+ break;
+
+ case C (BRANCH, UNDEF_WORD_DISP):
+ case C (SCB_F, UNDEF_WORD_DISP):
+ case C (SCB_TST, UNDEF_WORD_DISP):
+ /* This tried to be relaxed, but didn't manage it, it now needs a
+ fix */
+ wordify_scb (buffer, &disp_size, &inst_size);
+
+ /* Make a reloc */
+ fix_new (fragP,
+ fragP->fr_fix + inst_size,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 0,
+ R_H8500_PCREL16);
+
+ fragP->fr_fix += disp_size + inst_size;
+ fragP->fr_var = 0;
+ return;
+ break;
+ default:
+ abort ();
+ }
+ if (inst_size)
+ {
+ /* Get the address of the end of the instruction */
+ int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size;
+ int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
+ fragP->fr_offset);
+ int disp = targ_addr - next_inst;
+
+ md_number_to_chars (buffer + inst_size, disp, disp_size);
+ fragP->fr_fix += disp_size + inst_size;
+ fragP->fr_var = 0;
+ }
+}
+
+valueT
+md_section_align (seg, size)
+ segT seg ;
+ valueT size;
+{
+ return ((size + (1 << section_alignment[(int) seg]) - 1)
+ & (-1 << section_alignment[(int) seg]));
+
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ if (fixP->fx_r_type == 0)
+ {
+ fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16;
+ }
+
+ switch (fixP->fx_r_type)
+ {
+
+ case R_H8500_IMM8:
+ case R_H8500_PCREL8:
+ *buf++ = val;
+ break;
+ case R_H8500_IMM16:
+ case R_H8500_LOW16:
+ case R_H8500_PCREL16:
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ case R_H8500_HIGH8:
+ *buf++ = val >> 16;
+ break;
+ case R_H8500_HIGH16:
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ break;
+ case R_H8500_IMM24:
+ *buf++ = (val >> 16);
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ case R_H8500_IMM32:
+ *buf++ = (val >> 24);
+ *buf++ = (val >> 16);
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ default:
+ abort ();
+
+ }
+}
+
+/*
+called just before address relaxation, return the length
+by which a fragment must grow to reach it's destination
+*/
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ int what = GET_WHAT (fragP->fr_subtype);
+
+ switch (fragP->fr_subtype)
+ {
+ default:
+ abort ();
+ case C (BRANCH, UNDEF_BYTE_DISP):
+ case C (SCB_F, UNDEF_BYTE_DISP):
+ case C (SCB_TST, UNDEF_BYTE_DISP):
+ /* used to be a branch to somewhere which was unknown */
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ /* Got a symbol and it's defined in this segment, become byte
+ sized - maybe it will fix up */
+ fragP->fr_subtype = C (what, BYTE_DISP);
+ fragP->fr_var = md_relax_table[C (what, BYTE_DISP)].rlx_length;
+ }
+ else
+ {
+ /* Its got a segment, but its not ours, so it will always be long */
+ fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
+ fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
+ return md_relax_table[C (what, WORD_DISP)].rlx_length;
+ }
+ }
+ return fragP->fr_var;
+}
+
+/* Put number into target byte order */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char *ptr;
+ valueT use;
+ int nbytes;
+{
+ number_to_chars_bigendian (ptr, use, nbytes);
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/*ARGSUSED*/
+void
+tc_coff_symbol_emit_hook (ignore)
+ symbolS *ignore;
+{
+}
+
+short
+tc_coff_fix2rtype (fix_ptr)
+ fixS *fix_ptr;
+{
+ if (fix_ptr->fx_r_type == RELOC_32)
+ {
+ /* cons likes to create reloc32's whatever the size of the reloc..
+ */
+ switch (fix_ptr->fx_size)
+ {
+ case 2:
+ return R_H8500_IMM16;
+ break;
+ case 1:
+ return R_H8500_IMM8;
+ break;
+ default:
+ abort ();
+ }
+ }
+ return fix_ptr->fx_r_type;
+}
+
+void
+tc_reloc_mangle (fix_ptr, intr, base)
+ fixS *fix_ptr;
+ struct internal_reloc *intr;
+ bfd_vma base;
+
+{
+ symbolS *symbol_ptr;
+
+ symbol_ptr = fix_ptr->fx_addsy;
+
+ /* If this relocation is attached to a symbol then it's ok
+ to output it */
+ if (fix_ptr->fx_r_type == RELOC_32)
+ {
+ /* cons likes to create reloc32's whatever the size of the reloc..
+ */
+ switch (fix_ptr->fx_size)
+ {
+ case 2:
+ intr->r_type = R_IMM16;
+ break;
+ case 1:
+ intr->r_type = R_IMM8;
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ intr->r_type = fix_ptr->fx_r_type;
+ }
+
+ intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
+ intr->r_offset = fix_ptr->fx_offset;
+
+ /* Turn the segment of the symbol into an offset. */
+ if (symbol_ptr)
+ {
+ symbolS *dot;
+
+ dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
+ if (dot)
+ {
+ /* intr->r_offset -=
+ segment_info[S_GET_SEGMENT(symbol_ptr)].scnhdr.s_paddr;*/
+ intr->r_offset += S_GET_VALUE (symbol_ptr);
+ intr->r_symndx = dot->sy_number;
+ }
+ else
+ {
+ intr->r_symndx = symbol_ptr->sy_number;
+ }
+
+ }
+ else
+ {
+ intr->r_symndx = -1;
+ }
+
+}
+
+
+
+int
+start_label (ptr)
+ char *ptr;
+{
+ /* Check for :s.w */
+ if (isalpha (ptr[1]) && ptr[2] == '.')
+ return 0;
+ /* Check for :s */
+ if (isalpha (ptr[1]) && !isalpha (ptr[2]))
+ return 0;
+ return 1;
+}
+
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ return md_relax_table[frag->fr_subtype].rlx_length;
+}
+
+/* end of tc-h8500.c */
+
diff --git a/gas/config/tc-h8500.h b/gas/config/tc-h8500.h
new file mode 100644
index 00000000000..2a53ec35ce2
--- /dev/null
+++ b/gas/config/tc-h8500.h
@@ -0,0 +1,57 @@
+/* This file is tc-h8500.h
+ Copyright (C) 1993, 95, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+#define TC_H8500
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#if ANSI_PROTOTYPES
+struct internal_reloc;
+#endif
+
+#define WORKING_DOT_WORD
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
+
+#define BFD_ARCH bfd_arch_h8500
+#define COFF_MAGIC 0x8500
+#define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy)
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
+extern void tc_reloc_mangle
+ PARAMS ((struct fix *, struct internal_reloc *, bfd_vma));
+
+#define DO_NOT_STRIP 0
+#define LISTING_HEADER "Hitachi H8/500 GAS "
+#define NEED_FX_R_TYPE 1
+#define RELOC_32 1234
+
+#define TC_START_LABEL(ch, ptr) (ch == ':' && start_label(ptr))
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+
+#define md_operand(x)
+
+extern struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/* end of tc-h8500.h */
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c
new file mode 100644
index 00000000000..8785de8769d
--- /dev/null
+++ b/gas/config/tc-hppa.c
@@ -0,0 +1,6716 @@
+/* tc-hppa.c -- Assemble for the PA
+ Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/* HP PA-RISC support was contributed by the Center for Software Science
+ at the University of Utah. */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "as.h"
+#include "subsegs.h"
+
+#include "bfd/libhppa.h"
+#include "bfd/libbfd.h"
+
+/* Be careful, this file includes data *declarations*. */
+#include "opcode/hppa.h"
+
+/* A "convient" place to put object file dependencies which do
+ not need to be seen outside of tc-hppa.c. */
+#ifdef OBJ_ELF
+/* Names of various debugging spaces/subspaces. */
+#define GDB_DEBUG_SPACE_NAME ".stab"
+#define GDB_STRINGS_SUBSPACE_NAME ".stabstr"
+#define GDB_SYMBOLS_SUBSPACE_NAME ".stab"
+#define UNWIND_SECTION_NAME ".PARISC.unwind"
+/* Nonzero if CODE is a fixup code needing further processing. */
+
+/* Object file formats specify relocation types. */
+typedef elf32_hppa_reloc_type reloc_type;
+
+/* Object file formats specify BFD symbol types. */
+typedef elf_symbol_type obj_symbol_type;
+
+/* How to generate a relocation. */
+#define hppa_gen_reloc_type hppa_elf_gen_reloc_type
+
+/* ELF objects can have versions, but apparently do not have anywhere
+ to store a copyright string. */
+#define obj_version obj_elf_version
+#define obj_copyright obj_elf_version
+
+/* Use space aliases. */
+#define USE_ALIASES 1
+#endif
+
+#ifdef OBJ_SOM
+/* Names of various debugging spaces/subspaces. */
+#define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$"
+#define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$"
+#define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$"
+#define UNWIND_SECTION_NAME "$UNWIND$"
+
+/* Object file formats specify relocation types. */
+typedef int reloc_type;
+
+/* SOM objects can have both a version string and a copyright string. */
+#define obj_version obj_som_version
+#define obj_copyright obj_som_copyright
+
+/* Do not use space aliases. */
+#define USE_ALIASES 0
+
+/* How to generate a relocation. */
+#define hppa_gen_reloc_type hppa_som_gen_reloc_type
+
+/* Object file formats specify BFD symbol types. */
+typedef som_symbol_type obj_symbol_type;
+
+/* This apparently isn't in older versions of hpux reloc.h. */
+#ifndef R_DLT_REL
+#define R_DLT_REL 0x78
+#endif
+#endif
+
+#ifndef R_N0SEL
+#define R_N0SEL 0xd8
+#endif
+
+#ifndef R_N1SEL
+#define R_N1SEL 0xd9
+#endif
+
+/* Various structures and types used internally in tc-hppa.c. */
+
+/* Unwind table and descriptor. FIXME: Sync this with GDB version. */
+
+struct unwind_desc
+ {
+ unsigned int cannot_unwind:1;
+ unsigned int millicode:1;
+ unsigned int millicode_save_rest:1;
+ unsigned int region_desc:2;
+ unsigned int save_sr:2;
+ unsigned int entry_fr:4;
+ unsigned int entry_gr:5;
+ unsigned int args_stored:1;
+ unsigned int call_fr:5;
+ unsigned int call_gr:5;
+ unsigned int save_sp:1;
+ unsigned int save_rp:1;
+ unsigned int save_rp_in_frame:1;
+ unsigned int extn_ptr_defined:1;
+ unsigned int cleanup_defined:1;
+
+ unsigned int hpe_interrupt_marker:1;
+ unsigned int hpux_interrupt_marker:1;
+ unsigned int reserved:3;
+ unsigned int frame_size:27;
+ };
+
+struct unwind_table
+ {
+ /* Starting and ending offsets of the region described by
+ descriptor. */
+ unsigned int start_offset;
+ unsigned int end_offset;
+ struct unwind_desc descriptor;
+ };
+
+/* This structure is used by the .callinfo, .enter, .leave pseudo-ops to
+ control the entry and exit code they generate. It is also used in
+ creation of the correct stack unwind descriptors.
+
+ NOTE: GAS does not support .enter and .leave for the generation of
+ prologues and epilogues. FIXME.
+
+ The fields in structure roughly correspond to the arguments available on the
+ .callinfo pseudo-op. */
+
+struct call_info
+ {
+ /* The unwind descriptor being built. */
+ struct unwind_table ci_unwind;
+
+ /* Name of this function. */
+ symbolS *start_symbol;
+
+ /* (temporary) symbol used to mark the end of this function. */
+ symbolS *end_symbol;
+
+ /* Next entry in the chain. */
+ struct call_info *ci_next;
+ };
+
+/* Operand formats for FP instructions. Note not all FP instructions
+ allow all four formats to be used (for example fmpysub only allows
+ SGL and DBL). */
+typedef enum
+ {
+ SGL, DBL, ILLEGAL_FMT, QUAD, W, UW, DW, UDW, QW, UQW
+ }
+fp_operand_format;
+
+/* This fully describes the symbol types which may be attached to
+ an EXPORT or IMPORT directive. Only SOM uses this formation
+ (ELF has no need for it). */
+typedef enum
+ {
+ SYMBOL_TYPE_UNKNOWN,
+ SYMBOL_TYPE_ABSOLUTE,
+ SYMBOL_TYPE_CODE,
+ SYMBOL_TYPE_DATA,
+ SYMBOL_TYPE_ENTRY,
+ SYMBOL_TYPE_MILLICODE,
+ SYMBOL_TYPE_PLABEL,
+ SYMBOL_TYPE_PRI_PROG,
+ SYMBOL_TYPE_SEC_PROG,
+ }
+pa_symbol_type;
+
+/* This structure contains information needed to assemble
+ individual instructions. */
+struct pa_it
+ {
+ /* Holds the opcode after parsing by pa_ip. */
+ unsigned long opcode;
+
+ /* Holds an expression associated with the current instruction. */
+ expressionS exp;
+
+ /* Does this instruction use PC-relative addressing. */
+ int pcrel;
+
+ /* Floating point formats for operand1 and operand2. */
+ fp_operand_format fpof1;
+ fp_operand_format fpof2;
+
+
+ /* Holds the field selector for this instruction
+ (for example L%, LR%, etc). */
+ long field_selector;
+
+ /* Holds any argument relocation bits associated with this
+ instruction. (instruction should be some sort of call). */
+ long arg_reloc;
+
+ /* The format specification for this instruction. */
+ int format;
+
+ /* The relocation (if any) associated with this instruction. */
+ reloc_type reloc;
+ };
+
+/* PA-89 floating point registers are arranged like this:
+
+
+ +--------------+--------------+
+ | 0 or 16L | 16 or 16R |
+ +--------------+--------------+
+ | 1 or 17L | 17 or 17R |
+ +--------------+--------------+
+ | | |
+
+ . . .
+ . . .
+ . . .
+
+ | | |
+ +--------------+--------------+
+ | 14 or 30L | 30 or 30R |
+ +--------------+--------------+
+ | 15 or 31L | 31 or 31R |
+ +--------------+--------------+
+
+
+ The following is a version of pa_parse_number that
+ handles the L/R notation and returns the correct
+ value to put into the instruction register field.
+ The correct value to put into the instruction is
+ encoded in the structure 'pa_11_fp_reg_struct'. */
+
+struct pa_11_fp_reg_struct
+ {
+ /* The register number. */
+ char number_part;
+
+ /* L/R selector. */
+ char l_r_select;
+ };
+
+/* Additional information needed to build argument relocation stubs. */
+struct call_desc
+ {
+ /* The argument relocation specification. */
+ unsigned int arg_reloc;
+
+ /* Number of arguments. */
+ unsigned int arg_count;
+ };
+
+/* This structure defines an entry in the subspace dictionary
+ chain. */
+
+struct subspace_dictionary_chain
+ {
+ /* Nonzero if this space has been defined by the user code. */
+ unsigned int ssd_defined;
+
+ /* Name of this subspace. */
+ char *ssd_name;
+
+ /* GAS segment and subsegment associated with this subspace. */
+ asection *ssd_seg;
+ int ssd_subseg;
+
+ /* Next space in the subspace dictionary chain. */
+ struct subspace_dictionary_chain *ssd_next;
+ };
+
+typedef struct subspace_dictionary_chain ssd_chain_struct;
+
+/* This structure defines an entry in the subspace dictionary
+ chain. */
+
+struct space_dictionary_chain
+ {
+ /* Nonzero if this space has been defined by the user code or
+ as a default space. */
+ unsigned int sd_defined;
+
+ /* Nonzero if this spaces has been defined by the user code. */
+ unsigned int sd_user_defined;
+
+ /* The space number (or index). */
+ unsigned int sd_spnum;
+
+ /* The name of this subspace. */
+ char *sd_name;
+
+ /* GAS segment to which this subspace corresponds. */
+ asection *sd_seg;
+
+ /* Current subsegment number being used. */
+ int sd_last_subseg;
+
+ /* The chain of subspaces contained within this space. */
+ ssd_chain_struct *sd_subspaces;
+
+ /* The next entry in the space dictionary chain. */
+ struct space_dictionary_chain *sd_next;
+ };
+
+typedef struct space_dictionary_chain sd_chain_struct;
+
+/* Structure for previous label tracking. Needed so that alignments,
+ callinfo declarations, etc can be easily attached to a particular
+ label. */
+typedef struct label_symbol_struct
+ {
+ struct symbol *lss_label;
+ sd_chain_struct *lss_space;
+ struct label_symbol_struct *lss_next;
+ }
+label_symbol_struct;
+
+/* This structure defines attributes of the default subspace
+ dictionary entries. */
+
+struct default_subspace_dict
+ {
+ /* Name of the subspace. */
+ char *name;
+
+ /* FIXME. Is this still needed? */
+ char defined;
+
+ /* Nonzero if this subspace is loadable. */
+ char loadable;
+
+ /* Nonzero if this subspace contains only code. */
+ char code_only;
+
+ /* Nonzero if this is a common subspace. */
+ char common;
+
+ /* Nonzero if this is a common subspace which allows symbols
+ to be multiply defined. */
+ char dup_common;
+
+ /* Nonzero if this subspace should be zero filled. */
+ char zero;
+
+ /* Sort key for this subspace. */
+ unsigned char sort;
+
+ /* Access control bits for this subspace. Can represent RWX access
+ as well as privilege level changes for gateways. */
+ int access;
+
+ /* Index of containing space. */
+ int space_index;
+
+ /* Alignment (in bytes) of this subspace. */
+ int alignment;
+
+ /* Quadrant within space where this subspace should be loaded. */
+ int quadrant;
+
+ /* An index into the default spaces array. */
+ int def_space_index;
+
+ /* An alias for this section (or NULL if no alias exists). */
+ char *alias;
+
+ /* Subsegment associated with this subspace. */
+ subsegT subsegment;
+ };
+
+/* This structure defines attributes of the default space
+ dictionary entries. */
+
+struct default_space_dict
+ {
+ /* Name of the space. */
+ char *name;
+
+ /* Space number. It is possible to identify spaces within
+ assembly code numerically! */
+ int spnum;
+
+ /* Nonzero if this space is loadable. */
+ char loadable;
+
+ /* Nonzero if this space is "defined". FIXME is still needed */
+ char defined;
+
+ /* Nonzero if this space can not be shared. */
+ char private;
+
+ /* Sort key for this space. */
+ unsigned char sort;
+
+ /* Segment associated with this space. */
+ asection *segment;
+
+ /* An alias for this section (or NULL if no alias exists). */
+ char *alias;
+ };
+
+/* Extra information needed to perform fixups (relocations) on the PA. */
+struct hppa_fix_struct
+ {
+ /* The field selector. */
+ enum hppa_reloc_field_selector_type_alt fx_r_field;
+
+ /* Type of fixup. */
+ int fx_r_type;
+
+ /* Format of fixup. */
+ int fx_r_format;
+
+ /* Argument relocation bits. */
+ long fx_arg_reloc;
+
+ /* The segment this fixup appears in. */
+ segT segment;
+ };
+
+/* Structure to hold information about predefined registers. */
+
+struct pd_reg
+ {
+ char *name;
+ int value;
+ };
+
+/* This structure defines the mapping from a FP condition string
+ to a condition number which can be recorded in an instruction. */
+struct fp_cond_map
+ {
+ char *string;
+ int cond;
+ };
+
+/* This structure defines a mapping from a field selector
+ string to a field selector type. */
+struct selector_entry
+ {
+ char *prefix;
+ int field_selector;
+ };
+
+/* Prototypes for functions local to tc-hppa.c. */
+
+static void pa_check_current_space_and_subspace PARAMS ((void));
+static fp_operand_format pa_parse_fp_format PARAMS ((char **s));
+static void pa_cons PARAMS ((int));
+static void pa_data PARAMS ((int));
+static void pa_float_cons PARAMS ((int));
+static void pa_fill PARAMS ((int));
+static void pa_lcomm PARAMS ((int));
+static void pa_lsym PARAMS ((int));
+static void pa_stringer PARAMS ((int));
+static void pa_text PARAMS ((int));
+static void pa_version PARAMS ((int));
+static int pa_parse_fp_cmp_cond PARAMS ((char **));
+static int get_expression PARAMS ((char *));
+static int pa_get_absolute_expression PARAMS ((struct pa_it *, char **));
+static int evaluate_absolute PARAMS ((struct pa_it *));
+static unsigned int pa_build_arg_reloc PARAMS ((char *));
+static unsigned int pa_align_arg_reloc PARAMS ((unsigned int, unsigned int));
+static int pa_parse_nullif PARAMS ((char **));
+static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int));
+static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int));
+static int pa_parse_neg_add_cmpltr PARAMS ((char **, int));
+static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int));
+static void pa_align PARAMS ((int));
+static void pa_block PARAMS ((int));
+static void pa_brtab PARAMS ((int));
+static void pa_try PARAMS ((int));
+static void pa_call PARAMS ((int));
+static void pa_call_args PARAMS ((struct call_desc *));
+static void pa_callinfo PARAMS ((int));
+static void pa_code PARAMS ((int));
+static void pa_comm PARAMS ((int));
+#ifdef OBJ_SOM
+static void pa_compiler PARAMS ((int));
+#endif
+static void pa_copyright PARAMS ((int));
+static void pa_end PARAMS ((int));
+static void pa_enter PARAMS ((int));
+static void pa_entry PARAMS ((int));
+static void pa_equ PARAMS ((int));
+static void pa_exit PARAMS ((int));
+static void pa_export PARAMS ((int));
+static void pa_type_args PARAMS ((symbolS *, int));
+static void pa_import PARAMS ((int));
+static void pa_label PARAMS ((int));
+static void pa_leave PARAMS ((int));
+static void pa_level PARAMS ((int));
+static void pa_origin PARAMS ((int));
+static void pa_proc PARAMS ((int));
+static void pa_procend PARAMS ((int));
+static void pa_space PARAMS ((int));
+static void pa_spnum PARAMS ((int));
+static void pa_subspace PARAMS ((int));
+static void pa_param PARAMS ((int));
+static void pa_undefine_label PARAMS ((void));
+static int need_pa11_opcode PARAMS ((struct pa_it *,
+ struct pa_11_fp_reg_struct *));
+static int pa_parse_number PARAMS ((char **, struct pa_11_fp_reg_struct *));
+static label_symbol_struct *pa_get_label PARAMS ((void));
+static sd_chain_struct *create_new_space PARAMS ((char *, int, int,
+ int, int, int,
+ asection *, int));
+static ssd_chain_struct *create_new_subspace PARAMS ((sd_chain_struct *,
+ char *, int, int,
+ int, int, int,
+ int, int, int, int,
+ int, asection *));
+static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *,
+ char *, int, int, int,
+ int, int, int, int,
+ int, int, int,
+ asection *));
+static sd_chain_struct *is_defined_space PARAMS ((char *));
+static ssd_chain_struct *is_defined_subspace PARAMS ((char *));
+static sd_chain_struct *pa_segment_to_space PARAMS ((asection *));
+static ssd_chain_struct *pa_subsegment_to_subspace PARAMS ((asection *,
+ subsegT));
+static sd_chain_struct *pa_find_space_by_number PARAMS ((int));
+static unsigned int pa_subspace_start PARAMS ((sd_chain_struct *, int));
+static void pa_ip PARAMS ((char *));
+static void fix_new_hppa PARAMS ((fragS *, int, int, symbolS *,
+ long, expressionS *, int,
+ bfd_reloc_code_real_type,
+ enum hppa_reloc_field_selector_type_alt,
+ int, long, int *));
+static int is_end_of_statement PARAMS ((void));
+static int reg_name_search PARAMS ((char *));
+static int pa_chk_field_selector PARAMS ((char **));
+static int is_same_frag PARAMS ((fragS *, fragS *));
+static void process_exit PARAMS ((void));
+static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int));
+static int log2 PARAMS ((int));
+static int pa_next_subseg PARAMS ((sd_chain_struct *));
+static unsigned int pa_stringer_aux PARAMS ((char *));
+static void pa_spaces_begin PARAMS ((void));
+
+#ifdef OBJ_ELF
+static void hppa_elf_mark_end_of_function PARAMS ((void));
+static void pa_build_unwind_subspace PARAMS ((struct call_info *));
+#endif
+
+/* File and gloally scoped variable declarations. */
+
+/* Root and final entry in the space chain. */
+static sd_chain_struct *space_dict_root;
+static sd_chain_struct *space_dict_last;
+
+/* The current space and subspace. */
+static sd_chain_struct *current_space;
+static ssd_chain_struct *current_subspace;
+
+/* Root of the call_info chain. */
+static struct call_info *call_info_root;
+
+/* The last call_info (for functions) structure
+ seen so it can be associated with fixups and
+ function labels. */
+static struct call_info *last_call_info;
+
+/* The last call description (for actual calls). */
+static struct call_desc last_call_desc;
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. */
+const char comment_chars[] = ";";
+
+/* Table of pseudo ops for the PA. FIXME -- how many of these
+ are now redundant with the overall GAS and the object file
+ dependent tables? */
+const pseudo_typeS md_pseudo_table[] =
+{
+ /* align pseudo-ops on the PA specify the actual alignment requested,
+ not the log2 of the requested alignment. */
+ {"align", pa_align, 8},
+ {"begin_brtab", pa_brtab, 1},
+ {"begin_try", pa_try, 1},
+ {"block", pa_block, 1},
+ {"blockz", pa_block, 0},
+ {"byte", pa_cons, 1},
+ {"call", pa_call, 0},
+ {"callinfo", pa_callinfo, 0},
+ {"code", pa_code, 0},
+ {"comm", pa_comm, 0},
+#ifdef OBJ_SOM
+ {"compiler", pa_compiler, 0},
+#endif
+ {"copyright", pa_copyright, 0},
+ {"data", pa_data, 0},
+ {"double", pa_float_cons, 'd'},
+ {"end", pa_end, 0},
+ {"end_brtab", pa_brtab, 0},
+ {"end_try", pa_try, 0},
+ {"enter", pa_enter, 0},
+ {"entry", pa_entry, 0},
+ {"equ", pa_equ, 0},
+ {"exit", pa_exit, 0},
+ {"export", pa_export, 0},
+ {"fill", pa_fill, 0},
+ {"float", pa_float_cons, 'f'},
+ {"half", pa_cons, 2},
+ {"import", pa_import, 0},
+ {"int", pa_cons, 4},
+ {"label", pa_label, 0},
+ {"lcomm", pa_lcomm, 0},
+ {"leave", pa_leave, 0},
+ {"level", pa_level, 0},
+ {"long", pa_cons, 4},
+ {"lsym", pa_lsym, 0},
+ {"nsubspa", pa_subspace, 1},
+ {"octa", pa_cons, 16},
+ {"org", pa_origin, 0},
+ {"origin", pa_origin, 0},
+ {"param", pa_param, 0},
+ {"proc", pa_proc, 0},
+ {"procend", pa_procend, 0},
+ {"quad", pa_cons, 8},
+ {"reg", pa_equ, 1},
+ {"short", pa_cons, 2},
+ {"single", pa_float_cons, 'f'},
+ {"space", pa_space, 0},
+ {"spnum", pa_spnum, 0},
+ {"string", pa_stringer, 0},
+ {"stringz", pa_stringer, 1},
+ {"subspa", pa_subspace, 0},
+ {"text", pa_text, 0},
+ {"version", pa_version, 0},
+ {"word", pa_cons, 4},
+ {NULL, 0, 0}
+};
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output.
+
+ Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output.
+
+ Also note that C style comments will always work. */
+const char line_comment_chars[] = "#";
+
+/* This array holds the characters which act as line separators. */
+const char line_separator_chars[] = "!";
+
+/* Chars that can be used to separate mant from exp in floating point nums. */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant.
+ As in 0f12.456 or 0d1.2345e12.
+
+ Be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c. Ideally it shouldn't hae to know abou it at
+ all, but nothing is ideal around here. */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+static struct pa_it the_insn;
+
+/* Points to the end of an expression just parsed by get_expressoin
+ and friends. FIXME. This shouldn't be handled with a file-global
+ variable. */
+static char *expr_end;
+
+/* Nonzero if a .callinfo appeared within the current procedure. */
+static int callinfo_found;
+
+/* Nonzero if the assembler is currently within a .entry/.exit pair. */
+static int within_entry_exit;
+
+/* Nonzero if the assembler is currently within a procedure definition. */
+static int within_procedure;
+
+/* Handle on strucutre which keep track of the last symbol
+ seen in each subspace. */
+static label_symbol_struct *label_symbols_rootp = NULL;
+
+/* Holds the last field selector. */
+static int hppa_field_selector;
+
+
+/* A dummy bfd symbol so that all relocations have symbols of some kind. */
+static symbolS *dummy_symbol;
+
+/* Nonzero if errors are to be printed. */
+static int print_errors = 1;
+
+/* List of registers that are pre-defined:
+
+ Each general register has one predefined name of the form
+ %r<REGNUM> which has the value <REGNUM>.
+
+ Space and control registers are handled in a similar manner,
+ but use %sr<REGNUM> and %cr<REGNUM> as their predefined names.
+
+ Likewise for the floating point registers, but of the form
+ %fr<REGNUM>. Floating point registers have additional predefined
+ names with 'L' and 'R' suffixes (e.g. %fr19L, %fr19R) which
+ again have the value <REGNUM>.
+
+ Many registers also have synonyms:
+
+ %r26 - %r23 have %arg0 - %arg3 as synonyms
+ %r28 - %r29 have %ret0 - %ret1 as synonyms
+ %r30 has %sp as a synonym
+ %r27 has %dp as a synonym
+ %r2 has %rp as a synonym
+
+ Almost every control register has a synonym; they are not listed
+ here for brevity.
+
+ The table is sorted. Suitable for searching by a binary search. */
+
+static const struct pd_reg pre_defined_registers[] =
+{
+ {"%arg0", 26},
+ {"%arg1", 25},
+ {"%arg2", 24},
+ {"%arg3", 23},
+ {"%cr0", 0},
+ {"%cr10", 10},
+ {"%cr11", 11},
+ {"%cr12", 12},
+ {"%cr13", 13},
+ {"%cr14", 14},
+ {"%cr15", 15},
+ {"%cr16", 16},
+ {"%cr17", 17},
+ {"%cr18", 18},
+ {"%cr19", 19},
+ {"%cr20", 20},
+ {"%cr21", 21},
+ {"%cr22", 22},
+ {"%cr23", 23},
+ {"%cr24", 24},
+ {"%cr25", 25},
+ {"%cr26", 26},
+ {"%cr27", 27},
+ {"%cr28", 28},
+ {"%cr29", 29},
+ {"%cr30", 30},
+ {"%cr31", 31},
+ {"%cr8", 8},
+ {"%cr9", 9},
+ {"%dp", 27},
+ {"%eiem", 15},
+ {"%eirr", 23},
+ {"%fr0", 0},
+ {"%fr0l", 0},
+ {"%fr0r", 0},
+ {"%fr1", 1},
+ {"%fr10", 10},
+ {"%fr10l", 10},
+ {"%fr10r", 10},
+ {"%fr11", 11},
+ {"%fr11l", 11},
+ {"%fr11r", 11},
+ {"%fr12", 12},
+ {"%fr12l", 12},
+ {"%fr12r", 12},
+ {"%fr13", 13},
+ {"%fr13l", 13},
+ {"%fr13r", 13},
+ {"%fr14", 14},
+ {"%fr14l", 14},
+ {"%fr14r", 14},
+ {"%fr15", 15},
+ {"%fr15l", 15},
+ {"%fr15r", 15},
+ {"%fr16", 16},
+ {"%fr16l", 16},
+ {"%fr16r", 16},
+ {"%fr17", 17},
+ {"%fr17l", 17},
+ {"%fr17r", 17},
+ {"%fr18", 18},
+ {"%fr18l", 18},
+ {"%fr18r", 18},
+ {"%fr19", 19},
+ {"%fr19l", 19},
+ {"%fr19r", 19},
+ {"%fr1l", 1},
+ {"%fr1r", 1},
+ {"%fr2", 2},
+ {"%fr20", 20},
+ {"%fr20l", 20},
+ {"%fr20r", 20},
+ {"%fr21", 21},
+ {"%fr21l", 21},
+ {"%fr21r", 21},
+ {"%fr22", 22},
+ {"%fr22l", 22},
+ {"%fr22r", 22},
+ {"%fr23", 23},
+ {"%fr23l", 23},
+ {"%fr23r", 23},
+ {"%fr24", 24},
+ {"%fr24l", 24},
+ {"%fr24r", 24},
+ {"%fr25", 25},
+ {"%fr25l", 25},
+ {"%fr25r", 25},
+ {"%fr26", 26},
+ {"%fr26l", 26},
+ {"%fr26r", 26},
+ {"%fr27", 27},
+ {"%fr27l", 27},
+ {"%fr27r", 27},
+ {"%fr28", 28},
+ {"%fr28l", 28},
+ {"%fr28r", 28},
+ {"%fr29", 29},
+ {"%fr29l", 29},
+ {"%fr29r", 29},
+ {"%fr2l", 2},
+ {"%fr2r", 2},
+ {"%fr3", 3},
+ {"%fr30", 30},
+ {"%fr30l", 30},
+ {"%fr30r", 30},
+ {"%fr31", 31},
+ {"%fr31l", 31},
+ {"%fr31r", 31},
+ {"%fr3l", 3},
+ {"%fr3r", 3},
+ {"%fr4", 4},
+ {"%fr4l", 4},
+ {"%fr4r", 4},
+ {"%fr5", 5},
+ {"%fr5l", 5},
+ {"%fr5r", 5},
+ {"%fr6", 6},
+ {"%fr6l", 6},
+ {"%fr6r", 6},
+ {"%fr7", 7},
+ {"%fr7l", 7},
+ {"%fr7r", 7},
+ {"%fr8", 8},
+ {"%fr8l", 8},
+ {"%fr8r", 8},
+ {"%fr9", 9},
+ {"%fr9l", 9},
+ {"%fr9r", 9},
+ {"%hta", 25},
+ {"%iir", 19},
+ {"%ior", 21},
+ {"%ipsw", 22},
+ {"%isr", 20},
+ {"%itmr", 16},
+ {"%iva", 14},
+ {"%pcoq", 18},
+ {"%pcsq", 17},
+ {"%pidr1", 8},
+ {"%pidr2", 9},
+ {"%pidr3", 12},
+ {"%pidr4", 13},
+ {"%ppda", 24},
+ {"%r0", 0},
+ {"%r1", 1},
+ {"%r10", 10},
+ {"%r11", 11},
+ {"%r12", 12},
+ {"%r13", 13},
+ {"%r14", 14},
+ {"%r15", 15},
+ {"%r16", 16},
+ {"%r17", 17},
+ {"%r18", 18},
+ {"%r19", 19},
+ {"%r2", 2},
+ {"%r20", 20},
+ {"%r21", 21},
+ {"%r22", 22},
+ {"%r23", 23},
+ {"%r24", 24},
+ {"%r25", 25},
+ {"%r26", 26},
+ {"%r27", 27},
+ {"%r28", 28},
+ {"%r29", 29},
+ {"%r3", 3},
+ {"%r30", 30},
+ {"%r31", 31},
+ {"%r4", 4},
+ {"%r5", 5},
+ {"%r6", 6},
+ {"%r7", 7},
+ {"%r8", 8},
+ {"%r9", 9},
+ {"%rctr", 0},
+ {"%ret0", 28},
+ {"%ret1", 29},
+ {"%rp", 2},
+ {"%sar", 11},
+ {"%sp", 30},
+ {"%sr0", 0},
+ {"%sr1", 1},
+ {"%sr2", 2},
+ {"%sr3", 3},
+ {"%sr4", 4},
+ {"%sr5", 5},
+ {"%sr6", 6},
+ {"%sr7", 7},
+ {"%tr0", 24},
+ {"%tr1", 25},
+ {"%tr2", 26},
+ {"%tr3", 27},
+ {"%tr4", 28},
+ {"%tr5", 29},
+ {"%tr6", 30},
+ {"%tr7", 31}
+};
+
+/* This table is sorted by order of the length of the string. This is
+ so we check for <> before we check for <. If we had a <> and checked
+ for < first, we would get a false match. */
+static const struct fp_cond_map fp_cond_map[] =
+{
+ {"false?", 0},
+ {"false", 1},
+ {"true?", 30},
+ {"true", 31},
+ {"!<=>", 3},
+ {"!?>=", 8},
+ {"!?<=", 16},
+ {"!<>", 7},
+ {"!>=", 11},
+ {"!?>", 12},
+ {"?<=", 14},
+ {"!<=", 19},
+ {"!?<", 20},
+ {"?>=", 22},
+ {"!?=", 24},
+ {"!=t", 27},
+ {"<=>", 29},
+ {"=t", 5},
+ {"?=", 6},
+ {"?<", 10},
+ {"<=", 13},
+ {"!>", 15},
+ {"?>", 18},
+ {">=", 21},
+ {"!<", 23},
+ {"<>", 25},
+ {"!=", 26},
+ {"!?", 28},
+ {"?", 2},
+ {"=", 4},
+ {"<", 9},
+ {">", 17}
+};
+
+static const struct selector_entry selector_table[] =
+{
+ {"f", e_fsel},
+ {"l", e_lsel},
+ {"ld", e_ldsel},
+ {"lp", e_lpsel},
+ {"lr", e_lrsel},
+ {"ls", e_lssel},
+ {"lt", e_ltsel},
+ {"n", e_nsel},
+ {"nl", e_nlsel},
+ {"nlr", e_nlrsel},
+ {"p", e_psel},
+ {"r", e_rsel},
+ {"rd", e_rdsel},
+ {"rp", e_rpsel},
+ {"rr", e_rrsel},
+ {"rs", e_rssel},
+ {"rt", e_rtsel},
+ {"t", e_tsel},
+};
+
+/* default space and subspace dictionaries */
+
+#define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME
+#define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME
+
+/* pre-defined subsegments (subspaces) for the HPPA. */
+#define SUBSEG_CODE 0
+#define SUBSEG_LIT 1
+#define SUBSEG_MILLI 2
+#define SUBSEG_DATA 0
+#define SUBSEG_BSS 2
+#define SUBSEG_UNWIND 3
+#define SUBSEG_GDB_STRINGS 0
+#define SUBSEG_GDB_SYMBOLS 1
+
+static struct default_subspace_dict pa_def_subspaces[] =
+{
+ {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE},
+ {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, ".data", SUBSEG_DATA},
+ {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT},
+ {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_MILLI},
+ {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, ".bss", SUBSEG_BSS},
+#ifdef OBJ_ELF
+ {"$UNWIND$", 1, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".PARISC.unwind", SUBSEG_UNWIND},
+#endif
+ {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
+};
+
+static struct default_space_dict pa_def_spaces[] =
+{
+ {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL, ".text"},
+ {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL, ".data"},
+ {NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL}
+};
+
+/* Misc local definitions used by the assembler. */
+
+/* Return nonzero if the string pointed to by S potentially represents
+ a right or left half of a FP register */
+#define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r')
+#define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l')
+
+/* These macros are used to maintain spaces/subspaces. */
+#define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
+#define SPACE_USER_DEFINED(space_chain) (space_chain)->sd_user_defined
+#define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
+#define SPACE_NAME(space_chain) (space_chain)->sd_name
+
+#define SUBSPACE_DEFINED(ss_chain) (ss_chain)->ssd_defined
+#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
+
+/* Insert FIELD into OPCODE starting at bit START. Continue pa_ip
+ main loop after insertion. */
+
+#define INSERT_FIELD_AND_CONTINUE(OPCODE, FIELD, START) \
+ { \
+ ((OPCODE) |= (FIELD) << (START)); \
+ continue; \
+ }
+
+/* Simple range checking for FIELD againt HIGH and LOW bounds.
+ IGNORE is used to suppress the error message. */
+
+#define CHECK_FIELD(FIELD, HIGH, LOW, IGNORE) \
+ { \
+ if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
+ { \
+ if (! IGNORE) \
+ as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
+ (int) (FIELD));\
+ break; \
+ } \
+ }
+
+#define is_DP_relative(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0)
+
+#define is_PC_relative(exp) \
+ ((exp).X_op == O_subtract \
+ && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0)
+
+/* We need some complex handling for stabs (sym1 - sym2). Luckily, we'll
+ always be able to reduce the expression to a constant, so we don't
+ need real complex handling yet. */
+#define is_complex(exp) \
+ ((exp).X_op != O_constant && (exp).X_op != O_symbol)
+
+/* Actual functions to implement the PA specific code for the assembler. */
+
+/* Called before writing the object file. Make sure entry/exit and
+ proc/procend pairs match. */
+
+void
+pa_check_eof ()
+{
+ if (within_entry_exit)
+ as_fatal (_("Missing .exit\n"));
+
+ if (within_procedure)
+ as_fatal (_("Missing .procend\n"));
+}
+
+/* Check to make sure we have a valid space and subspace. */
+
+static void
+pa_check_current_space_and_subspace ()
+{
+ if (current_space == NULL)
+ as_fatal (_("Not in a space.\n"));
+
+ if (current_subspace == NULL)
+ as_fatal (_("Not in a subspace.\n"));
+}
+
+/* Returns a pointer to the label_symbol_struct for the current space.
+ or NULL if no label_symbol_struct exists for the current space. */
+
+static label_symbol_struct *
+pa_get_label ()
+{
+ label_symbol_struct *label_chain;
+ sd_chain_struct *space_chain = current_space;
+
+ for (label_chain = label_symbols_rootp;
+ label_chain;
+ label_chain = label_chain->lss_next)
+ if (space_chain == label_chain->lss_space && label_chain->lss_label)
+ return label_chain;
+
+ return NULL;
+}
+
+/* Defines a label for the current space. If one is already defined,
+ this function will replace it with the new label. */
+
+void
+pa_define_label (symbol)
+ symbolS *symbol;
+{
+ label_symbol_struct *label_chain = pa_get_label ();
+ sd_chain_struct *space_chain = current_space;
+
+ if (label_chain)
+ label_chain->lss_label = symbol;
+ else
+ {
+ /* Create a new label entry and add it to the head of the chain. */
+ label_chain
+ = (label_symbol_struct *) xmalloc (sizeof (label_symbol_struct));
+ label_chain->lss_label = symbol;
+ label_chain->lss_space = space_chain;
+ label_chain->lss_next = NULL;
+
+ if (label_symbols_rootp)
+ label_chain->lss_next = label_symbols_rootp;
+
+ label_symbols_rootp = label_chain;
+ }
+}
+
+/* Removes a label definition for the current space.
+ If there is no label_symbol_struct entry, then no action is taken. */
+
+static void
+pa_undefine_label ()
+{
+ label_symbol_struct *label_chain;
+ label_symbol_struct *prev_label_chain = NULL;
+ sd_chain_struct *space_chain = current_space;
+
+ for (label_chain = label_symbols_rootp;
+ label_chain;
+ label_chain = label_chain->lss_next)
+ {
+ if (space_chain == label_chain->lss_space && label_chain->lss_label)
+ {
+ /* Remove the label from the chain and free its memory. */
+ if (prev_label_chain)
+ prev_label_chain->lss_next = label_chain->lss_next;
+ else
+ label_symbols_rootp = label_chain->lss_next;
+
+ free (label_chain);
+ break;
+ }
+ prev_label_chain = label_chain;
+ }
+}
+
+
+/* An HPPA-specific version of fix_new. This is required because the HPPA
+ code needs to keep track of some extra stuff. Each call to fix_new_hppa
+ results in the creation of an instance of an hppa_fix_struct. An
+ hppa_fix_struct stores the extra information along with a pointer to the
+ original fixS. This is attached to the original fixup via the
+ tc_fix_data field. */
+
+static void
+fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
+ r_type, r_field, r_format, arg_reloc, unwind_bits)
+ fragS *frag;
+ int where;
+ int size;
+ symbolS *add_symbol;
+ long offset;
+ expressionS *exp;
+ int pcrel;
+ bfd_reloc_code_real_type r_type;
+ enum hppa_reloc_field_selector_type_alt r_field;
+ int r_format;
+ long arg_reloc;
+ int* unwind_bits;
+{
+ fixS *new_fix;
+
+ struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *)
+ obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
+
+ if (exp != NULL)
+ new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
+ else
+ new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type);
+ new_fix->tc_fix_data = (void *) hppa_fix;
+ hppa_fix->fx_r_type = r_type;
+ hppa_fix->fx_r_field = r_field;
+ hppa_fix->fx_r_format = r_format;
+ hppa_fix->fx_arg_reloc = arg_reloc;
+ hppa_fix->segment = now_seg;
+#ifdef OBJ_SOM
+ if (r_type == R_ENTRY || r_type == R_EXIT)
+ new_fix->fx_offset = *unwind_bits;
+#endif
+
+ /* foo-$global$ is used to access non-automatic storage. $global$
+ is really just a marker and has served its purpose, so eliminate
+ it now so as not to confuse write.c. */
+ if (new_fix->fx_subsy
+ && !strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$"))
+ new_fix->fx_subsy = NULL;
+}
+
+/* Parse a .byte, .word, .long expression for the HPPA. Called by
+ cons via the TC_PARSE_CONS_EXPRESSION macro. */
+
+void
+parse_cons_expression_hppa (exp)
+ expressionS *exp;
+{
+ hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
+ expression (exp);
+}
+
+/* This fix_new is called by cons via TC_CONS_FIX_NEW.
+ hppa_field_selector is set by the parse_cons_expression_hppa. */
+
+void
+cons_fix_new_hppa (frag, where, size, exp)
+ fragS *frag;
+ int where;
+ int size;
+ expressionS *exp;
+{
+ unsigned int rel_type;
+
+ /* Get a base relocation type. */
+ if (is_DP_relative (*exp))
+ rel_type = R_HPPA_GOTOFF;
+ else if (is_complex (*exp))
+ rel_type = R_HPPA_COMPLEX;
+ else
+ rel_type = R_HPPA;
+
+ if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel)
+ as_warn (_("Invalid field selector. Assuming F%%."));
+
+ fix_new_hppa (frag, where, size,
+ (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
+ hppa_field_selector, 32, 0, NULL);
+
+ /* Reset field selector to its default state. */
+ hppa_field_selector = 0;
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need. */
+
+void
+md_begin ()
+{
+ const char *retval = NULL;
+ int lose = 0;
+ unsigned int i = 0;
+
+ last_call_info = NULL;
+ call_info_root = NULL;
+
+ /* Set the default machine type. */
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
+ as_warn (_("could not set architecture and machine"));
+
+ /* Folding of text and data segments fails miserably on the PA.
+ Warn user and disable "-R" option. */
+ if (flag_readonly_data_in_text)
+ {
+ as_warn (_("-R option not supported on this target."));
+ flag_readonly_data_in_text = 0;
+ }
+
+ pa_spaces_begin ();
+
+ op_hash = hash_new ();
+
+ while (i < NUMOPCODES)
+ {
+ const char *name = pa_opcodes[i].name;
+ retval = hash_insert (op_hash, name, (struct pa_opcode *) &pa_opcodes[i]);
+ if (retval != NULL && *retval != '\0')
+ {
+ as_fatal (_("Internal error: can't hash `%s': %s\n"), name, retval);
+ lose = 1;
+ }
+ do
+ {
+ if ((pa_opcodes[i].match & pa_opcodes[i].mask)
+ != pa_opcodes[i].match)
+ {
+ fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),
+ pa_opcodes[i].name, pa_opcodes[i].args);
+ lose = 1;
+ }
+ ++i;
+ }
+ while (i < NUMOPCODES && !strcmp (pa_opcodes[i].name, name));
+ }
+
+ if (lose)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ /* SOM will change text_section. To make sure we never put
+ anything into the old one switch to the new one now. */
+ subseg_set (text_section, 0);
+
+ dummy_symbol = symbol_find_or_make ("L$dummy");
+ S_SET_SEGMENT (dummy_symbol, text_section);
+}
+
+/* Assemble a single instruction storing it into a frag. */
+void
+md_assemble (str)
+ char *str;
+{
+ char *to;
+
+ /* The had better be something to assemble. */
+ assert (str);
+
+ /* If we are within a procedure definition, make sure we've
+ defined a label for the procedure; handle case where the
+ label was defined after the .PROC directive.
+
+ Note there's not need to diddle with the segment or fragment
+ for the label symbol in this case. We have already switched
+ into the new $CODE$ subspace at this point. */
+ if (within_procedure && last_call_info->start_symbol == NULL)
+ {
+ label_symbol_struct *label_symbol = pa_get_label ();
+
+ if (label_symbol)
+ {
+ if (label_symbol->lss_label)
+ {
+ last_call_info->start_symbol = label_symbol->lss_label;
+ label_symbol->lss_label->bsym->flags |= BSF_FUNCTION;
+#ifdef OBJ_SOM
+ /* Also handle allocation of a fixup to hold the unwind
+ information when the label appears after the proc/procend. */
+ if (within_entry_exit)
+ {
+ char *where = frag_more (0);
+
+ fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
+ NULL, (offsetT) 0, NULL,
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0,
+ (int *)&last_call_info->ci_unwind.descriptor);
+ }
+#endif
+ }
+ else
+ as_bad (_("Missing function name for .PROC (corrupted label chain)"));
+ }
+ else
+ as_bad (_("Missing function name for .PROC"));
+ }
+
+ /* Assemble the instruction. Results are saved into "the_insn". */
+ pa_ip (str);
+
+ /* Get somewhere to put the assembled instrution. */
+ to = frag_more (4);
+
+ /* Output the opcode. */
+ md_number_to_chars (to, the_insn.opcode, 4);
+
+ /* If necessary output more stuff. */
+ if (the_insn.reloc != R_HPPA_NONE)
+ fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,
+ (offsetT) 0, &the_insn.exp, the_insn.pcrel,
+ the_insn.reloc, the_insn.field_selector,
+ the_insn.format, the_insn.arg_reloc, NULL);
+}
+
+/* Do the real work for assembling a single instruction. Store results
+ into the global "the_insn" variable. */
+
+static void
+pa_ip (str)
+ char *str;
+{
+ char *error_message = "";
+ char *s, c, *argstart, *name, *save_s;
+ const char *args;
+ int match = FALSE;
+ int comma = 0;
+ int cmpltr, nullif, flag, cond, num;
+ unsigned long opcode;
+ struct pa_opcode *insn;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ /* Skip to something interesting. */
+ for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)
+ ;
+
+ switch (*s)
+ {
+
+ case '\0':
+ break;
+
+ case ',':
+ comma = 1;
+
+ /*FALLTHROUGH */
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ default:
+ as_fatal (_("Unknown opcode: `%s'"), str);
+ }
+
+ save_s = str;
+
+ /* Convert everything into lower case. */
+ while (*save_s)
+ {
+ if (isupper (*save_s))
+ *save_s = tolower (*save_s);
+ save_s++;
+ }
+
+ /* Look up the opcode in the has table. */
+ if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
+ {
+ as_bad ("Unknown opcode: `%s'", str);
+ return;
+ }
+
+ if (comma)
+ {
+ *--s = ',';
+ }
+
+ /* Mark the location where arguments for the instruction start, then
+ start processing them. */
+ argstart = s;
+ for (;;)
+ {
+ /* Do some initialization. */
+ opcode = insn->match;
+ memset (&the_insn, 0, sizeof (the_insn));
+
+ the_insn.reloc = R_HPPA_NONE;
+
+ /* If this instruction is specific to a particular architecture,
+ then set a new architecture. */
+ /* But do not automatically promote to pa2.0. The automatic promotion
+ crud is for compatability with HP's old assemblers only. */
+ if (insn->arch < 20
+ && bfd_get_mach (stdoutput) < insn->arch)
+ {
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))
+ as_warn (_("could not update architecture and machine"));
+ }
+ else if (bfd_get_mach (stdoutput) < insn->arch)
+ {
+ match = FALSE;
+ goto failed;
+ }
+
+ /* Build the opcode, checking as we go to make
+ sure that the operands match. */
+ for (args = insn->args;; ++args)
+ {
+ switch (*args)
+ {
+
+ /* End of arguments. */
+ case '\0':
+ if (*s == '\0')
+ match = TRUE;
+ break;
+
+ case '+':
+ if (*s == '+')
+ {
+ ++s;
+ continue;
+ }
+ if (*s == '-')
+ continue;
+ break;
+
+ /* These must match exactly. */
+ case '(':
+ case ')':
+ case ',':
+ case ' ':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ /* Handle a 5 bit register or control register field at 10. */
+ case 'b':
+ case '^':
+ num = pa_parse_number (&s, 0);
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
+
+ /* Handle a 5 bit register field at 15. */
+ case 'x':
+ num = pa_parse_number (&s, 0);
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
+
+ /* Handle a 5 bit register field at 31. */
+ case 'y':
+ case 't':
+ num = pa_parse_number (&s, 0);
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle a 5 bit field length at 31. */
+ case 'T':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 32, 1, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0);
+
+ /* Handle a 5 bit immediate at 15. */
+ case '5':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 15, -16, 0);
+ low_sign_unext (num, 5, &num);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
+
+ /* Handle a 5 bit immediate at 31. */
+ case 'V':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 15, -16, 0)
+ low_sign_unext (num, 5, &num);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle an unsigned 5 bit immediate at 31. */
+ case 'r':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle an unsigned 5 bit immediate at 15. */
+ case 'R':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
+
+ /* Handle a 2 bit space identifier at 17. */
+ case 's':
+ num = pa_parse_number (&s, 0);
+ CHECK_FIELD (num, 3, 0, 1);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 14);
+
+ /* Handle a 3 bit space identifier at 18. */
+ case 'S':
+ num = pa_parse_number (&s, 0);
+ CHECK_FIELD (num, 7, 0, 1);
+ dis_assemble_3 (num, &num);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
+
+ /* Handle a completer for an indexing load or store. */
+ case 'c':
+ {
+ int uu = 0;
+ int m = 0;
+ int i = 0;
+ while (*s == ',' && i < 2)
+ {
+ s++;
+ if (strncasecmp (s, "sm", 2) == 0)
+ {
+ uu = 1;
+ m = 1;
+ s++;
+ i++;
+ }
+ else if (strncasecmp (s, "m", 1) == 0)
+ m = 1;
+ else if (strncasecmp (s, "s", 1) == 0)
+ uu = 1;
+ else
+ as_bad (_("Invalid Indexed Load Completer."));
+ s++;
+ i++;
+ }
+ if (i > 2)
+ as_bad (_("Invalid Indexed Load Completer Syntax."));
+ opcode |= m << 5;
+ INSERT_FIELD_AND_CONTINUE (opcode, uu, 13);
+ }
+
+ /* Handle a short load/store completer. */
+ case 'C':
+ {
+ int a = 0;
+ int m = 0;
+ if (*s == ',')
+ {
+ s++;
+ if (strncasecmp (s, "ma", 2) == 0)
+ {
+ a = 0;
+ m = 1;
+ }
+ else if (strncasecmp (s, "mb", 2) == 0)
+ {
+ a = 1;
+ m = 1;
+ }
+ else
+ as_bad (_("Invalid Short Load/Store Completer."));
+ s += 2;
+ }
+
+ if (*args == 'C')
+ {
+ opcode |= m << 5;
+ INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
+ }
+ }
+
+ /* Handle a stbys completer. */
+ case 'Y':
+ {
+ int a = 0;
+ int m = 0;
+ int i = 0;
+ while (*s == ',' && i < 2)
+ {
+ s++;
+ if (strncasecmp (s, "m", 1) == 0)
+ m = 1;
+ else if (strncasecmp (s, "b", 1) == 0)
+ a = 0;
+ else if (strncasecmp (s, "e", 1) == 0)
+ a = 1;
+ else
+ as_bad (_("Invalid Store Bytes Short Completer"));
+ s++;
+ i++;
+ }
+ if (i > 2)
+ as_bad (_("Invalid Store Bytes Short Completer"));
+ opcode |= m << 5;
+ INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
+ }
+
+ /* Handle a non-negated compare/stubtract condition. */
+ case '<':
+ cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
+ if (cmpltr < 0)
+ {
+ as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
+ cmpltr = 0;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+
+ /* Handle a negated or non-negated compare/subtract condition. */
+ case '?':
+ save_s = s;
+ cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
+ if (cmpltr < 0)
+ {
+ s = save_s;
+ cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
+ if (cmpltr < 0)
+ {
+ as_bad (_("Invalid Compare/Subtract Condition."));
+ cmpltr = 0;
+ }
+ else
+ {
+ /* Negated condition requires an opcode change. */
+ opcode |= 1 << 27;
+ }
+ }
+
+ INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+
+ /* Handle non-negated add condition. */
+ case '!':
+ cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
+ if (cmpltr < 0)
+ {
+ as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
+ cmpltr = 0;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+
+ /* Handle a negated or non-negated add condition. */
+ case '@':
+ save_s = s;
+ cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
+ if (cmpltr < 0)
+ {
+ s = save_s;
+ cmpltr = pa_parse_neg_add_cmpltr (&s, 1);
+ if (cmpltr < 0)
+ {
+ as_bad (_("Invalid Compare/Subtract Condition"));
+ cmpltr = 0;
+ }
+ else
+ {
+ /* Negated condition requires an opcode change. */
+ opcode |= 1 << 27;
+ }
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+
+ /* Handle a compare/subtract condition. */
+ case 'a':
+ cmpltr = 0;
+ flag = 0;
+ if (*s == ',')
+ {
+ s++;
+ name = s;
+ while (*s != ',' && *s != ' ' && *s != '\t')
+ s += 1;
+ c = *s;
+ *s = 0x00;
+ if (strcmp (name, "=") == 0)
+ cmpltr = 1;
+ else if (strcmp (name, "<") == 0)
+ cmpltr = 2;
+ else if (strcmp (name, "<=") == 0)
+ cmpltr = 3;
+ else if (strcasecmp (name, "<<") == 0)
+ cmpltr = 4;
+ else if (strcasecmp (name, "<<=") == 0)
+ cmpltr = 5;
+ else if (strcasecmp (name, "sv") == 0)
+ cmpltr = 6;
+ else if (strcasecmp (name, "od") == 0)
+ cmpltr = 7;
+ else if (strcasecmp (name, "tr") == 0)
+ {
+ cmpltr = 0;
+ flag = 1;
+ }
+ else if (strcmp (name, "<>") == 0)
+ {
+ cmpltr = 1;
+ flag = 1;
+ }
+ else if (strcmp (name, ">=") == 0)
+ {
+ cmpltr = 2;
+ flag = 1;
+ }
+ else if (strcmp (name, ">") == 0)
+ {
+ cmpltr = 3;
+ flag = 1;
+ }
+ else if (strcasecmp (name, ">>=") == 0)
+ {
+ cmpltr = 4;
+ flag = 1;
+ }
+ else if (strcasecmp (name, ">>") == 0)
+ {
+ cmpltr = 5;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "nsv") == 0)
+ {
+ cmpltr = 6;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "ev") == 0)
+ {
+ cmpltr = 7;
+ flag = 1;
+ }
+ else
+ as_bad (_("Invalid Add Condition: %s"), name);
+ *s = c;
+ }
+ opcode |= cmpltr << 13;
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
+
+ /* Handle a non-negated add condition. */
+ case 'd':
+ cmpltr = 0;
+ flag = 0;
+ if (*s == ',')
+ {
+ s++;
+ name = s;
+ while (*s != ',' && *s != ' ' && *s != '\t')
+ s += 1;
+ c = *s;
+ *s = 0x00;
+ if (strcmp (name, "=") == 0)
+ cmpltr = 1;
+ else if (strcmp (name, "<") == 0)
+ cmpltr = 2;
+ else if (strcmp (name, "<=") == 0)
+ cmpltr = 3;
+ else if (strcasecmp (name, "nuv") == 0)
+ cmpltr = 4;
+ else if (strcasecmp (name, "znv") == 0)
+ cmpltr = 5;
+ else if (strcasecmp (name, "sv") == 0)
+ cmpltr = 6;
+ else if (strcasecmp (name, "od") == 0)
+ cmpltr = 7;
+ else if (strcasecmp (name, "tr") == 0)
+ {
+ cmpltr = 0;
+ flag = 1;
+ }
+ else if (strcmp (name, "<>") == 0)
+ {
+ cmpltr = 1;
+ flag = 1;
+ }
+ else if (strcmp (name, ">=") == 0)
+ {
+ cmpltr = 2;
+ flag = 1;
+ }
+ else if (strcmp (name, ">") == 0)
+ {
+ cmpltr = 3;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "uv") == 0)
+ {
+ cmpltr = 4;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "vnz") == 0)
+ {
+ cmpltr = 5;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "nsv") == 0)
+ {
+ cmpltr = 6;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "ev") == 0)
+ {
+ cmpltr = 7;
+ flag = 1;
+ }
+ else
+ as_bad (_("Invalid Add Condition: %s"), name);
+ *s = c;
+ }
+ opcode |= cmpltr << 13;
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
+
+ /* HANDLE a logical instruction condition. */
+ case '&':
+ cmpltr = 0;
+ flag = 0;
+ if (*s == ',')
+ {
+ s++;
+ name = s;
+ while (*s != ',' && *s != ' ' && *s != '\t')
+ s += 1;
+ c = *s;
+ *s = 0x00;
+
+
+ if (strcmp (name, "=") == 0)
+ cmpltr = 1;
+ else if (strcmp (name, "<") == 0)
+ cmpltr = 2;
+ else if (strcmp (name, "<=") == 0)
+ cmpltr = 3;
+ else if (strcasecmp (name, "od") == 0)
+ cmpltr = 7;
+ else if (strcasecmp (name, "tr") == 0)
+ {
+ cmpltr = 0;
+ flag = 1;
+ }
+ else if (strcmp (name, "<>") == 0)
+ {
+ cmpltr = 1;
+ flag = 1;
+ }
+ else if (strcmp (name, ">=") == 0)
+ {
+ cmpltr = 2;
+ flag = 1;
+ }
+ else if (strcmp (name, ">") == 0)
+ {
+ cmpltr = 3;
+ flag = 1;
+ }
+ else if (strcasecmp (name, "ev") == 0)
+ {
+ cmpltr = 7;
+ flag = 1;
+ }
+ else
+ as_bad (_("Invalid Logical Instruction Condition."));
+ *s = c;
+ }
+ opcode |= cmpltr << 13;
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
+
+ /* Handle a unit instruction condition. */
+ case 'U':
+ cmpltr = 0;
+ flag = 0;
+ if (*s == ',')
+ {
+ s++;
+
+
+ if (strncasecmp (s, "sbz", 3) == 0)
+ {
+ cmpltr = 2;
+ s += 3;
+ }
+ else if (strncasecmp (s, "shz", 3) == 0)
+ {
+ cmpltr = 3;
+ s += 3;
+ }
+ else if (strncasecmp (s, "sdc", 3) == 0)
+ {
+ cmpltr = 4;
+ s += 3;
+ }
+ else if (strncasecmp (s, "sbc", 3) == 0)
+ {
+ cmpltr = 6;
+ s += 3;
+ }
+ else if (strncasecmp (s, "shc", 3) == 0)
+ {
+ cmpltr = 7;
+ s += 3;
+ }
+ else if (strncasecmp (s, "tr", 2) == 0)
+ {
+ cmpltr = 0;
+ flag = 1;
+ s += 2;
+ }
+ else if (strncasecmp (s, "nbz", 3) == 0)
+ {
+ cmpltr = 2;
+ flag = 1;
+ s += 3;
+ }
+ else if (strncasecmp (s, "nhz", 3) == 0)
+ {
+ cmpltr = 3;
+ flag = 1;
+ s += 3;
+ }
+ else if (strncasecmp (s, "ndc", 3) == 0)
+ {
+ cmpltr = 4;
+ flag = 1;
+ s += 3;
+ }
+ else if (strncasecmp (s, "nbc", 3) == 0)
+ {
+ cmpltr = 6;
+ flag = 1;
+ s += 3;
+ }
+ else if (strncasecmp (s, "nhc", 3) == 0)
+ {
+ cmpltr = 7;
+ flag = 1;
+ s += 3;
+ }
+ else
+ as_bad (_("Invalid Logical Instruction Condition."));
+ }
+ opcode |= cmpltr << 13;
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
+
+ /* Handle a shift/extract/deposit condition. */
+ case '|':
+ case '>':
+ cmpltr = 0;
+ if (*s == ',')
+ {
+ save_s = s++;
+
+
+ name = s;
+ while (*s != ',' && *s != ' ' && *s != '\t')
+ s += 1;
+ c = *s;
+ *s = 0x00;
+ if (strcmp (name, "=") == 0)
+ cmpltr = 1;
+ else if (strcmp (name, "<") == 0)
+ cmpltr = 2;
+ else if (strcasecmp (name, "od") == 0)
+ cmpltr = 3;
+ else if (strcasecmp (name, "tr") == 0)
+ cmpltr = 4;
+ else if (strcmp (name, "<>") == 0)
+ cmpltr = 5;
+ else if (strcmp (name, ">=") == 0)
+ cmpltr = 6;
+ else if (strcasecmp (name, "ev") == 0)
+ cmpltr = 7;
+ /* Handle movb,n. Put things back the way they were.
+ This includes moving s back to where it started. */
+ else if (strcasecmp (name, "n") == 0 && *args == '|')
+ {
+ *s = c;
+ s = save_s;
+ continue;
+ }
+ else
+ as_bad (_("Invalid Shift/Extract/Deposit Condition."));
+ *s = c;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+
+ /* Handle bvb and bb conditions. */
+ case '~':
+ cmpltr = 0;
+ if (*s == ',')
+ {
+ s++;
+ if (strncmp (s, "<", 1) == 0)
+ {
+ cmpltr = 0;
+ s++;
+ }
+ else if (strncmp (s, ">=", 2) == 0)
+ {
+ cmpltr = 1;
+ s += 2;
+ }
+ else
+ as_bad (_("Invalid Bit Branch Condition: %c"), *s);
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15);
+
+ /* Handle a system control completer. */
+ case 'Z':
+ if (*s == ',' && (*(s + 1) == 'm' || *(s + 1) == 'M'))
+ {
+ flag = 1;
+ s += 2;
+ }
+ else
+ flag = 0;
+
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 5);
+
+ /* Handle a nullification completer for branch instructions. */
+ case 'n':
+ nullif = pa_parse_nullif (&s);
+ INSERT_FIELD_AND_CONTINUE (opcode, nullif, 1);
+
+ /* Handle a nullification completer for copr and spop insns. */
+ case 'N':
+ nullif = pa_parse_nullif (&s);
+ INSERT_FIELD_AND_CONTINUE (opcode, nullif, 5);
+
+
+ /* Handle a 11 bit immediate at 31. */
+ case 'i':
+ the_insn.field_selector = pa_chk_field_selector (&s);
+ get_expression (s);
+ s = expr_end;
+ if (the_insn.exp.X_op == O_constant)
+ {
+ num = evaluate_absolute (&the_insn);
+ CHECK_FIELD (num, 1023, -1024, 0);
+ low_sign_unext (num, 11, &num);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+ }
+ else
+ {
+ if (is_DP_relative (the_insn.exp))
+ the_insn.reloc = R_HPPA_GOTOFF;
+ else if (is_PC_relative (the_insn.exp))
+ the_insn.reloc = R_HPPA_PCREL_CALL;
+ else
+ the_insn.reloc = R_HPPA;
+ the_insn.format = 11;
+ continue;
+ }
+
+
+ /* Handle a 14 bit immediate at 31. */
+ case 'j':
+ the_insn.field_selector = pa_chk_field_selector (&s);
+ get_expression (s);
+ s = expr_end;
+ if (the_insn.exp.X_op == O_constant)
+ {
+ num = evaluate_absolute (&the_insn);
+ CHECK_FIELD (num, 8191, -8192, 0);
+ low_sign_unext (num, 14, &num);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+ }
+ else
+ {
+ if (is_DP_relative (the_insn.exp))
+ the_insn.reloc = R_HPPA_GOTOFF;
+ else if (is_PC_relative (the_insn.exp))
+ the_insn.reloc = R_HPPA_PCREL_CALL;
+ else
+ the_insn.reloc = R_HPPA;
+ the_insn.format = 14;
+ continue;
+ }
+
+ /* Handle a 21 bit immediate at 31. */
+ case 'k':
+ the_insn.field_selector = pa_chk_field_selector (&s);
+ get_expression (s);
+ s = expr_end;
+ if (the_insn.exp.X_op == O_constant)
+ {
+ num = evaluate_absolute (&the_insn);
+ CHECK_FIELD (num >> 11, 1048575, -1048576, 0);
+ dis_assemble_21 (num, &num);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+ }
+ else
+ {
+ if (is_DP_relative (the_insn.exp))
+ the_insn.reloc = R_HPPA_GOTOFF;
+ else if (is_PC_relative (the_insn.exp))
+ the_insn.reloc = R_HPPA_PCREL_CALL;
+ else
+ the_insn.reloc = R_HPPA;
+ the_insn.format = 21;
+ continue;
+ }
+
+ /* Handle a 12 bit branch displacement. */
+ case 'w':
+ the_insn.field_selector = pa_chk_field_selector (&s);
+ get_expression (s);
+ s = expr_end;
+ the_insn.pcrel = 1;
+ if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), "L$0\001"))
+ {
+ unsigned int w1, w, result;
+
+ num = evaluate_absolute (&the_insn);
+ if (num % 4)
+ {
+ as_bad (_("Branch to unaligned address"));
+ break;
+ }
+ CHECK_FIELD (num, 8199, -8184, 0);
+ sign_unext ((num - 8) >> 2, 12, &result);
+ dis_assemble_12 (result, &w1, &w);
+ INSERT_FIELD_AND_CONTINUE (opcode, ((w1 << 2) | w), 0);
+ }
+ else
+ {
+ the_insn.reloc = R_HPPA_PCREL_CALL;
+ the_insn.format = 12;
+ the_insn.arg_reloc = last_call_desc.arg_reloc;
+ memset (&last_call_desc, 0, sizeof (struct call_desc));
+ s = expr_end;
+ continue;
+ }
+
+ /* Handle a 17 bit branch displacement. */
+ case 'W':
+ the_insn.field_selector = pa_chk_field_selector (&s);
+ get_expression (s);
+ s = expr_end;
+ the_insn.pcrel = 1;
+ if (!the_insn.exp.X_add_symbol
+ || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
+ "L$0\001"))
+ {
+ unsigned int w2, w1, w, result;
+
+ num = evaluate_absolute (&the_insn);
+ if (num % 4)
+ {
+ as_bad (_("Branch to unaligned address"));
+ break;
+ }
+ CHECK_FIELD (num, 262143, -262144, 0);
+
+ if (the_insn.exp.X_add_symbol)
+ num -= 8;
+
+ sign_unext (num >> 2, 17, &result);
+ dis_assemble_17 (result, &w1, &w2, &w);
+ INSERT_FIELD_AND_CONTINUE (opcode,
+ ((w2 << 2) | (w1 << 16) | w), 0);
+ }
+ else
+ {
+ the_insn.reloc = R_HPPA_PCREL_CALL;
+ the_insn.format = 17;
+ the_insn.arg_reloc = last_call_desc.arg_reloc;
+ memset (&last_call_desc, 0, sizeof (struct call_desc));
+ continue;
+ }
+
+ /* Handle an absolute 17 bit branch target. */
+ case 'z':
+ the_insn.field_selector = pa_chk_field_selector (&s);
+ get_expression (s);
+ s = expr_end;
+ the_insn.pcrel = 0;
+ if (!the_insn.exp.X_add_symbol
+ || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
+ "L$0\001"))
+ {
+ unsigned int w2, w1, w, result;
+
+ num = evaluate_absolute (&the_insn);
+ if (num % 4)
+ {
+ as_bad (_("Branch to unaligned address"));
+ break;
+ }
+ CHECK_FIELD (num, 262143, -262144, 0);
+
+ if (the_insn.exp.X_add_symbol)
+ num -= 8;
+
+ sign_unext (num >> 2, 17, &result);
+ dis_assemble_17 (result, &w1, &w2, &w);
+ INSERT_FIELD_AND_CONTINUE (opcode,
+ ((w2 << 2) | (w1 << 16) | w), 0);
+ }
+ else
+ {
+ the_insn.reloc = R_HPPA_ABS_CALL;
+ the_insn.format = 17;
+ the_insn.arg_reloc = last_call_desc.arg_reloc;
+ memset (&last_call_desc, 0, sizeof (struct call_desc));
+ continue;
+ }
+
+ /* Handle a 5 bit shift count at 26. */
+ case 'p':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5);
+
+ /* Handle a 5 bit bit position at 26. */
+ case 'P':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 5);
+
+ /* Handle a 5 bit immediate at 10. */
+ case 'Q':
+
+ num = pa_get_absolute_expression (&the_insn, &s);
+ if (the_insn.exp.X_op != O_constant)
+ break;
+ s = expr_end;
+ CHECK_FIELD (num, 31, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
+
+ /* Handle a 13 bit immediate at 18. */
+ case 'A':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 8191, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
+
+ /* Handle a 26 bit immediate at 31. */
+ case 'D':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 671108864, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle a 3 bit SFU identifier at 25. */
+ case 'f':
+ if (*s++ != ',')
+ as_bad (_("Invalid SFU identifier"));
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 7, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
+
+ /* Handle a 20 bit SOP field for spop0. */
+ case 'O':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 1048575, 0, 0);
+ num = (num & 0x1f) | ((num & 0x000fffe0) << 6);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle a 15bit SOP field for spop1. */
+ case 'o':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 32767, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 11);
+
+ /* Handle a 10bit SOP field for spop3. */
+ case '0':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 1023, 0, 0);
+ num = (num & 0x1f) | ((num & 0x000003e0) << 6);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle a 15 bit SOP field for spop2. */
+ case '1':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 32767, 0, 0);
+ num = (num & 0x1f) | ((num & 0x00007fe0) << 6);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+ /* Handle a 3-bit co-processor ID field. */
+ case 'u':
+ if (*s++ != ',')
+ as_bad (_("Invalid COPR identifier"));
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 7, 0, 0);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
+
+ /* Handle a 22bit SOP field for copr. */
+ case '2':
+ num = pa_get_absolute_expression (&the_insn, &s);
+ s = expr_end;
+ CHECK_FIELD (num, 4194303, 0, 0);
+ num = (num & 0x1f) | ((num & 0x003fffe0) << 4);
+ INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+
+
+ /* Handle a source FP operand format completer. */
+ case 'F':
+ flag = pa_parse_fp_format (&s);
+ the_insn.fpof1 = flag;
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
+
+ /* Handle a destination FP operand format completer. */
+ case 'G':
+ /* pa_parse_format needs the ',' prefix. */
+ s--;
+ flag = pa_parse_fp_format (&s);
+ the_insn.fpof2 = flag;
+ INSERT_FIELD_AND_CONTINUE (opcode, flag, 13);
+
+ /* Handle FP compare conditions. */
+ case 'M':
+ cond = pa_parse_fp_cmp_cond (&s);
+ INSERT_FIELD_AND_CONTINUE (opcode, cond, 0);
+
+ /* Handle L/R register halves like 't'. */
+ case 'v':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ opcode |= result.number_part;
+
+ /* 0x30 opcodes are FP arithmetic operation opcodes
+ and need to be turned into 0x38 opcodes. This
+ is not necessary for loads/stores. */
+ if (need_pa11_opcode (&the_insn, &result)
+ && ((opcode & 0xfc000000) == 0x30000000))
+ opcode |= 1 << 27;
+
+ INSERT_FIELD_AND_CONTINUE (opcode, result.l_r_select & 1, 6);
+ }
+
+ /* Handle L/R register halves like 'b'. */
+ case 'E':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ opcode |= result.number_part << 21;
+ if (need_pa11_opcode (&the_insn, &result))
+ {
+ opcode |= (result.l_r_select & 1) << 7;
+ opcode |= 1 << 27;
+ }
+ continue;
+ }
+
+ /* Handle L/R register halves like 'b'. */
+ case '3':
+ {
+ struct pa_11_fp_reg_struct result;
+ int regnum;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ opcode |= (result.number_part & 0x1c) << 11;
+ opcode |= (result.number_part & 0x3) << 9;
+ opcode |= (result.l_r_select & 1) << 8;
+ continue;
+ }
+
+ /* Handle L/R register halves like 'x'. */
+ case 'e':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ opcode |= (result.number_part & 0x1f) << 16;
+ if (need_pa11_opcode (&the_insn, &result))
+ {
+ opcode |= (result.l_r_select & 1) << 1;
+ }
+ continue;
+ }
+
+ /* Handle L/R register halves like 'x'. */
+ case 'X':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ opcode |= (result.number_part & 0x1f) << 16;
+ if (need_pa11_opcode (&the_insn, &result))
+ {
+ opcode |= (result.l_r_select & 1) << 12;
+ opcode |= 1 << 27;
+ }
+ continue;
+ }
+
+ /* Handle a 5 bit register field at 10. */
+ case '4':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ if (the_insn.fpof1 == SGL)
+ {
+ if (result.number_part < 16)
+ {
+ as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
+ break;
+ }
+
+ result.number_part &= 0xF;
+ result.number_part |= (result.l_r_select & 1) << 4;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 21);
+ }
+
+ /* Handle a 5 bit register field at 15. */
+ case '6':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ if (the_insn.fpof1 == SGL)
+ {
+ if (result.number_part < 16)
+ {
+ as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
+ break;
+ }
+ result.number_part &= 0xF;
+ result.number_part |= (result.l_r_select & 1) << 4;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 16);
+ }
+
+ /* Handle a 5 bit register field at 31. */
+ case '7':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ if (the_insn.fpof1 == SGL)
+ {
+ if (result.number_part < 16)
+ {
+ as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
+ break;
+ }
+ result.number_part &= 0xF;
+ result.number_part |= (result.l_r_select & 1) << 4;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 0);
+ }
+
+ /* Handle a 5 bit register field at 20. */
+ case '8':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ if (the_insn.fpof1 == SGL)
+ {
+ if (result.number_part < 16)
+ {
+ as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
+ break;
+ }
+ result.number_part &= 0xF;
+ result.number_part |= (result.l_r_select & 1) << 4;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 11);
+ }
+
+ /* Handle a 5 bit register field at 25. */
+ case '9':
+ {
+ struct pa_11_fp_reg_struct result;
+
+ pa_parse_number (&s, &result);
+ CHECK_FIELD (result.number_part, 31, 0, 0);
+ if (the_insn.fpof1 == SGL)
+ {
+ if (result.number_part < 16)
+ {
+ as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
+ break;
+ }
+ result.number_part &= 0xF;
+ result.number_part |= (result.l_r_select & 1) << 4;
+ }
+ INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 6);
+ }
+
+ /* Handle a floating point operand format at 26.
+ Only allows single and double precision. */
+ case 'H':
+ flag = pa_parse_fp_format (&s);
+ switch (flag)
+ {
+ case SGL:
+ opcode |= 0x20;
+ case DBL:
+ the_insn.fpof1 = flag;
+ continue;
+
+ case QUAD:
+ case ILLEGAL_FMT:
+ default:
+ as_bad (_("Invalid Floating Point Operand Format."));
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+ }
+
+ failed:
+ /* Check if the args matched. */
+ if (match == FALSE)
+ {
+ if (&insn[1] - pa_opcodes < (int) NUMOPCODES
+ && !strcmp (insn->name, insn[1].name))
+ {
+ ++insn;
+ s = argstart;
+ continue;
+ }
+ else
+ {
+ as_bad (_("Invalid operands %s"), error_message);
+ return;
+ }
+ }
+ break;
+ }
+
+ the_insn.opcode = opcode;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message or NULL is returned. */
+
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return NULL;
+}
+
+/* Write out big-endian. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent **
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *reloc;
+ struct hppa_fix_struct *hppa_fixp;
+ bfd_reloc_code_real_type code;
+ static arelent *no_relocs = NULL;
+ arelent **relocs;
+ bfd_reloc_code_real_type **codes;
+ int n_relocs;
+ int i;
+
+ hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
+ if (fixp->fx_addsy == 0)
+ return &no_relocs;
+ assert (hppa_fixp != 0);
+ assert (section != 0);
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ codes = (bfd_reloc_code_real_type **) hppa_gen_reloc_type (stdoutput,
+ fixp->fx_r_type,
+ hppa_fixp->fx_r_format,
+ hppa_fixp->fx_r_field,
+ fixp->fx_subsy != NULL,
+ fixp->fx_addsy->bsym);
+
+ if (codes == NULL)
+ abort ();
+
+ for (n_relocs = 0; codes[n_relocs]; n_relocs++)
+ ;
+
+ relocs = (arelent **) xmalloc (sizeof (arelent *) * n_relocs + 1);
+ reloc = (arelent *) xmalloc (sizeof (arelent) * n_relocs);
+ for (i = 0; i < n_relocs; i++)
+ relocs[i] = &reloc[i];
+
+ relocs[n_relocs] = NULL;
+
+#ifdef OBJ_ELF
+ switch (fixp->fx_r_type)
+ {
+ default:
+ assert (n_relocs == 1);
+
+ code = *codes[0];
+
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->addend = 0; /* default */
+
+ assert (reloc->howto && code == reloc->howto->type);
+
+ /* Now, do any processing that is dependent on the relocation type. */
+ switch (code)
+ {
+ case R_PARISC_DLTREL21L:
+ case R_PARISC_DLTREL14R:
+ case R_PARISC_DLTREL14F:
+ case R_PARISC_PLABEL32:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL14R:
+ /* For plabel relocations, the addend of the
+ relocation should be either 0 (no static link) or 2
+ (static link required).
+
+ FIXME: We always assume no static link!
+
+ We also slam a zero addend into the DLT relative relocs;
+ it doesn't make a lot of sense to use any addend since
+ it gets you a different (eg unknown) DLT entry. */
+ reloc->addend = 0;
+ break;
+
+ case R_PARISC_PCREL21L:
+ case R_PARISC_PCREL17R:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PCREL14F:
+ /* The constant is stored in the instruction. */
+ reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0);
+ break;
+ default:
+ reloc->addend = fixp->fx_offset;
+ break;
+ }
+ break;
+ }
+#else /* OBJ_SOM */
+
+ /* Walk over reach relocation returned by the BFD backend. */
+ for (i = 0; i < n_relocs; i++)
+ {
+ code = *codes[i];
+
+ relocs[i]->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ relocs[i]->howto = bfd_reloc_type_lookup (stdoutput, code);
+ relocs[i]->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ switch (code)
+ {
+ case R_COMP2:
+ /* The only time we ever use a R_COMP2 fixup is for the difference
+ of two symbols. With that in mind we fill in all four
+ relocs now and break out of the loop. */
+ assert (i == 1);
+ relocs[0]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol;
+ relocs[0]->howto = bfd_reloc_type_lookup (stdoutput, *codes[0]);
+ relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ relocs[0]->addend = 0;
+ relocs[1]->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ relocs[1]->howto = bfd_reloc_type_lookup (stdoutput, *codes[1]);
+ relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ relocs[1]->addend = 0;
+ relocs[2]->sym_ptr_ptr = &fixp->fx_subsy->bsym;
+ relocs[2]->howto = bfd_reloc_type_lookup (stdoutput, *codes[2]);
+ relocs[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ relocs[2]->addend = 0;
+ relocs[3]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol;
+ relocs[3]->howto = bfd_reloc_type_lookup (stdoutput, *codes[3]);
+ relocs[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ relocs[3]->addend = 0;
+ relocs[4]->sym_ptr_ptr = (asymbol **) &bfd_abs_symbol;
+ relocs[4]->howto = bfd_reloc_type_lookup (stdoutput, *codes[4]);
+ relocs[4]->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ relocs[4]->addend = 0;
+ goto done;
+ case R_PCREL_CALL:
+ case R_ABS_CALL:
+ relocs[i]->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0);
+ break;
+
+ case R_DLT_REL:
+ case R_DATA_PLABEL:
+ case R_CODE_PLABEL:
+ /* For plabel relocations, the addend of the
+ relocation should be either 0 (no static link) or 2
+ (static link required).
+
+ FIXME: We always assume no static link!
+
+ We also slam a zero addend into the DLT relative relocs;
+ it doesn't make a lot of sense to use any addend since
+ it gets you a different (eg unknown) DLT entry. */
+ relocs[i]->addend = 0;
+ break;
+
+ case R_N_MODE:
+ case R_S_MODE:
+ case R_D_MODE:
+ case R_R_MODE:
+ case R_FSEL:
+ case R_LSEL:
+ case R_RSEL:
+ case R_BEGIN_BRTAB:
+ case R_END_BRTAB:
+ case R_BEGIN_TRY:
+ case R_N0SEL:
+ case R_N1SEL:
+ /* There is no symbol or addend associated with these fixups. */
+ relocs[i]->sym_ptr_ptr = &dummy_symbol->bsym;
+ relocs[i]->addend = 0;
+ break;
+
+ case R_END_TRY:
+ case R_ENTRY:
+ case R_EXIT:
+ /* There is no symbol associated with these fixups. */
+ relocs[i]->sym_ptr_ptr = &dummy_symbol->bsym;
+ relocs[i]->addend = fixp->fx_offset;
+ break;
+
+ default:
+ relocs[i]->addend = fixp->fx_offset;
+ }
+ }
+
+ done:
+#endif
+
+ return relocs;
+}
+
+/* Process any machine dependent frag types. */
+
+void
+md_convert_frag (abfd, sec, fragP)
+ register bfd *abfd;
+ register asection *sec;
+ register fragS *fragP;
+{
+ unsigned int address;
+
+ if (fragP->fr_type == rs_machine_dependent)
+ {
+ switch ((int) fragP->fr_subtype)
+ {
+ case 0:
+ fragP->fr_type = rs_fill;
+ know (fragP->fr_var == 1);
+ know (fragP->fr_next);
+ address = fragP->fr_address + fragP->fr_fix;
+ if (address % fragP->fr_offset)
+ {
+ fragP->fr_offset =
+ fragP->fr_next->fr_address
+ - fragP->fr_address
+ - fragP->fr_fix;
+ }
+ else
+ fragP->fr_offset = 0;
+ break;
+ }
+ }
+}
+
+/* Round up a section size to the appropriate boundary. */
+
+valueT
+md_section_align (segment, size)
+ asection *segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+ int align2 = (1 << align) - 1;
+
+ return (size + align2) & ~align2;
+}
+
+/* Return the approximate size of a frag before relaxation has occurred. */
+int
+md_estimate_size_before_relax (fragP, segment)
+ register fragS *fragP;
+ asection *segment;
+{
+ int size;
+
+ size = 0;
+
+ while ((fragP->fr_fix + size) % fragP->fr_offset)
+ size++;
+
+ return size;
+}
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+
+/* We have no need to default values of symbols. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Apply a fixup to an instruction. */
+
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ valueT *valp;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ struct hppa_fix_struct *hppa_fixP;
+ long new_val, result = 0;
+ unsigned int w1, w2, w, resulti;
+
+ hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
+ /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
+ never be "applied" (they are just markers). Likewise for
+ R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB. */
+#ifdef OBJ_SOM
+ if (fixP->fx_r_type == R_HPPA_ENTRY
+ || fixP->fx_r_type == R_HPPA_EXIT
+ || fixP->fx_r_type == R_HPPA_BEGIN_BRTAB
+ || fixP->fx_r_type == R_HPPA_END_BRTAB
+ || fixP->fx_r_type == R_HPPA_BEGIN_TRY)
+ return 1;
+
+ /* Disgusting. We must set fx_offset ourselves -- R_HPPA_END_TRY
+ fixups are considered not adjustable, which in turn causes
+ adjust_reloc_syms to not set fx_offset. Ugh. */
+ if (fixP->fx_r_type == R_HPPA_END_TRY)
+ {
+ fixP->fx_offset = *valp;
+ return 1;
+ }
+#endif
+
+ /* There should have been an HPPA specific fixup associated
+ with the GAS fixup. */
+ if (hppa_fixP)
+ {
+ unsigned long buf_wd = bfd_get_32 (stdoutput, buf);
+ unsigned char fmt = bfd_hppa_insn2fmt (buf_wd);
+
+ /* If there is a symbol associated with this fixup, then it's something
+ which will need a SOM relocation (except for some PC-relative relocs).
+ In such cases we should treat the "val" or "addend" as zero since it
+ will be added in as needed from fx_offset in tc_gen_reloc. */
+ if ((fixP->fx_addsy != NULL
+ || fixP->fx_r_type == R_HPPA_NONE)
+#ifdef OBJ_SOM
+ && fmt != 32
+#endif
+ )
+ new_val = ((fmt == 12 || fmt == 17) ? 8 : 0);
+#ifdef OBJ_SOM
+ /* These field selectors imply that we do not want an addend. */
+ else if (hppa_fixP->fx_r_field == e_psel
+ || hppa_fixP->fx_r_field == e_rpsel
+ || hppa_fixP->fx_r_field == e_lpsel
+ || hppa_fixP->fx_r_field == e_tsel
+ || hppa_fixP->fx_r_field == e_rtsel
+ || hppa_fixP->fx_r_field == e_ltsel)
+ new_val = ((fmt == 12 || fmt == 17) ? 8 : 0);
+ /* This is truely disgusting. The machine independent code blindly
+ adds in the value of the symbol being relocated against. Damn! */
+ else if (fmt == 32
+ && fixP->fx_addsy != NULL
+ && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
+ new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy),
+ 0, hppa_fixP->fx_r_field);
+#endif
+ else
+ new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
+
+ /* Handle pc-relative exceptions from above. */
+#define arg_reloc_stub_needed(CALLER, CALLEE) \
+ ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
+ if ((fmt == 12 || fmt == 17)
+ && fixP->fx_addsy
+ && fixP->fx_pcrel
+ && !arg_reloc_stub_needed ((long) ((obj_symbol_type *)
+ fixP->fx_addsy->bsym)->tc_data.ap.hppa_arg_reloc,
+ hppa_fixP->fx_arg_reloc)
+ && ((int)(*valp) > -262144 && (int)(*valp) < 262143)
+ && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
+ && !(fixP->fx_subsy
+ && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
+
+ new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
+#undef arg_reloc_stub_needed
+
+ switch (fmt)
+ {
+ /* Handle all opcodes with the 'j' operand type. */
+ case 14:
+ CHECK_FIELD (new_val, 8191, -8192, 0);
+
+ /* Mask off 14 bits to be changed. */
+ bfd_put_32 (stdoutput,
+ bfd_get_32 (stdoutput, buf) & 0xffffc000,
+ buf);
+ low_sign_unext (new_val, 14, &resulti);
+ result = resulti;
+ break;
+
+ /* Handle all opcodes with the 'k' operand type. */
+ case 21:
+ CHECK_FIELD (new_val, 2097152, 0, 0);
+
+ /* Mask off 21 bits to be changed. */
+ bfd_put_32 (stdoutput,
+ bfd_get_32 (stdoutput, buf) & 0xffe00000,
+ buf);
+ dis_assemble_21 (new_val, &resulti);
+ result = resulti;
+ break;
+
+ /* Handle all the opcodes with the 'i' operand type. */
+ case 11:
+ CHECK_FIELD (new_val, 1023, -1023, 0);
+
+ /* Mask off 11 bits to be changed. */
+ bfd_put_32 (stdoutput,
+ bfd_get_32 (stdoutput, buf) & 0xffff800,
+ buf);
+ low_sign_unext (new_val, 11, &resulti);
+ result = resulti;
+ break;
+
+ /* Handle all the opcodes with the 'w' operand type. */
+ case 12:
+ CHECK_FIELD (new_val, 8199, -8184, 0);
+
+ /* Mask off 11 bits to be changed. */
+ sign_unext ((new_val - 8) >> 2, 12, &resulti);
+ bfd_put_32 (stdoutput,
+ bfd_get_32 (stdoutput, buf) & 0xffffe002,
+ buf);
+
+ dis_assemble_12 (resulti, &w1, &w);
+ result = ((w1 << 2) | w);
+ break;
+
+ /* Handle some of the opcodes with the 'W' operand type. */
+ case 17:
+ {
+ int distance = *valp;
+
+ CHECK_FIELD (new_val, 262143, -262144, 0);
+
+ /* If this is an absolute branch (ie no link) with an out of
+ range target, then we want to complain. */
+ if (fixP->fx_r_type == R_HPPA_PCREL_CALL
+ && (distance > 262143 || distance < -262144)
+ && (bfd_get_32 (stdoutput, buf) & 0xffe00000) == 0xe8000000)
+ CHECK_FIELD (distance, 262143, -262144, 0);
+
+ /* Mask off 17 bits to be changed. */
+ bfd_put_32 (stdoutput,
+ bfd_get_32 (stdoutput, buf) & 0xffe0e002,
+ buf);
+ sign_unext ((new_val - 8) >> 2, 17, &resulti);
+ dis_assemble_17 (resulti, &w1, &w2, &w);
+ result = ((w2 << 2) | (w1 << 16) | w);
+ break;
+ }
+
+ case 32:
+ result = 0;
+ bfd_put_32 (stdoutput, new_val, buf);
+ break;
+
+ default:
+ as_bad (_("Unknown relocation encountered in md_apply_fix."));
+ return 0;
+ }
+
+ /* Insert the relocation. */
+ bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) | result, buf);
+ return 1;
+ }
+ else
+ {
+ printf (_("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n"),
+ (unsigned int) fixP, fixP->fx_r_type);
+ return 0;
+ }
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the PA, they're relative to the address of the offset. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* Return nonzero if the input line pointer is at the end of
+ a statement. */
+
+static int
+is_end_of_statement ()
+{
+ return ((*input_line_pointer == '\n')
+ || (*input_line_pointer == ';')
+ || (*input_line_pointer == '!'));
+}
+
+/* Read a number from S. The number might come in one of many forms,
+ the most common will be a hex or decimal constant, but it could be
+ a pre-defined register (Yuk!), or an absolute symbol.
+
+ Return a number or -1 for failure.
+
+ When parsing PA-89 FP register numbers RESULT will be
+ the address of a structure to return information about
+ L/R half of FP registers, store results there as appropriate.
+
+ pa_parse_number can not handle negative constants and will fail
+ horribly if it is passed such a constant. */
+
+static int
+pa_parse_number (s, result)
+ char **s;
+ struct pa_11_fp_reg_struct *result;
+{
+ int num;
+ char *name;
+ char c;
+ symbolS *sym;
+ int status;
+ char *p = *s;
+
+ /* Skip whitespace before the number. */
+ while (*p == ' ' || *p == '\t')
+ p = p + 1;
+
+ /* Store info in RESULT if requested by caller. */
+ if (result)
+ {
+ result->number_part = -1;
+ result->l_r_select = -1;
+ }
+ num = -1;
+
+ if (isdigit (*p))
+ {
+ /* Looks like a number. */
+ num = 0;
+
+ if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
+ {
+ /* The number is specified in hex. */
+ p += 2;
+ while (isdigit (*p) || ((*p >= 'a') && (*p <= 'f'))
+ || ((*p >= 'A') && (*p <= 'F')))
+ {
+ if (isdigit (*p))
+ num = num * 16 + *p - '0';
+ else if (*p >= 'a' && *p <= 'f')
+ num = num * 16 + *p - 'a' + 10;
+ else
+ num = num * 16 + *p - 'A' + 10;
+ ++p;
+ }
+ }
+ else
+ {
+ /* The number is specified in decimal. */
+ while (isdigit (*p))
+ {
+ num = num * 10 + *p - '0';
+ ++p;
+ }
+ }
+
+ /* Store info in RESULT if requested by the caller. */
+ if (result)
+ {
+ result->number_part = num;
+
+ if (IS_R_SELECT (p))
+ {
+ result->l_r_select = 1;
+ ++p;
+ }
+ else if (IS_L_SELECT (p))
+ {
+ result->l_r_select = 0;
+ ++p;
+ }
+ else
+ result->l_r_select = 0;
+ }
+ }
+ else if (*p == '%')
+ {
+ /* The number might be a predefined register. */
+ num = 0;
+ name = p;
+ p++;
+ c = *p;
+ /* Tege hack: Special case for general registers as the general
+ code makes a binary search with case translation, and is VERY
+ slow. */
+ if (c == 'r')
+ {
+ p++;
+ if (*p == 'e' && *(p + 1) == 't'
+ && (*(p + 2) == '0' || *(p + 2) == '1'))
+ {
+ p += 2;
+ num = *p - '0' + 28;
+ p++;
+ }
+ else if (*p == 'p')
+ {
+ num = 2;
+ p++;
+ }
+ else if (!isdigit (*p))
+ {
+ if (print_errors)
+ as_bad (_("Undefined register: '%s'."), name);
+ num = -1;
+ }
+ else
+ {
+ do
+ num = num * 10 + *p++ - '0';
+ while (isdigit (*p));
+ }
+ }
+ else
+ {
+ /* Do a normal register search. */
+ while (is_part_of_name (c))
+ {
+ p = p + 1;
+ c = *p;
+ }
+ *p = 0;
+ status = reg_name_search (name);
+ if (status >= 0)
+ num = status;
+ else
+ {
+ if (print_errors)
+ as_bad (_("Undefined register: '%s'."), name);
+ num = -1;
+ }
+ *p = c;
+ }
+
+ /* Store info in RESULT if requested by caller. */
+ if (result)
+ {
+ result->number_part = num;
+ if (IS_R_SELECT (p - 1))
+ result->l_r_select = 1;
+ else if (IS_L_SELECT (p - 1))
+ result->l_r_select = 0;
+ else
+ result->l_r_select = 0;
+ }
+ }
+ else
+ {
+ /* And finally, it could be a symbol in the absolute section which
+ is effectively a constant. */
+ num = 0;
+ name = p;
+ c = *p;
+ while (is_part_of_name (c))
+ {
+ p = p + 1;
+ c = *p;
+ }
+ *p = 0;
+ if ((sym = symbol_find (name)) != NULL)
+ {
+ if (S_GET_SEGMENT (sym) == &bfd_abs_section)
+ num = S_GET_VALUE (sym);
+ else
+ {
+ if (print_errors)
+ as_bad (_("Non-absolute symbol: '%s'."), name);
+ num = -1;
+ }
+ }
+ else
+ {
+ /* There is where we'd come for an undefined symbol
+ or for an empty string. For an empty string we
+ will return zero. That's a concession made for
+ compatability with the braindamaged HP assemblers. */
+ if (*name == 0)
+ num = 0;
+ else
+ {
+ if (print_errors)
+ as_bad (_("Undefined absolute constant: '%s'."), name);
+ num = -1;
+ }
+ }
+ *p = c;
+
+ /* Store info in RESULT if requested by caller. */
+ if (result)
+ {
+ result->number_part = num;
+ if (IS_R_SELECT (p - 1))
+ result->l_r_select = 1;
+ else if (IS_L_SELECT (p - 1))
+ result->l_r_select = 0;
+ else
+ result->l_r_select = 0;
+ }
+ }
+
+ *s = p;
+ return num;
+}
+
+#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
+
+/* Given NAME, find the register number associated with that name, return
+ the integer value associated with the given name or -1 on failure. */
+
+static int
+reg_name_search (name)
+ char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = REG_NAME_CNT - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, pre_defined_registers[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return pre_defined_registers[middle].value;
+ }
+ while (low <= high);
+
+ return -1;
+}
+
+
+/* Return nonzero if the given INSN and L/R information will require
+ a new PA-1.1 opcode. */
+
+static int
+need_pa11_opcode (insn, result)
+ struct pa_it *insn;
+ struct pa_11_fp_reg_struct *result;
+{
+ if (result->l_r_select == 1 && !(insn->fpof1 == DBL && insn->fpof2 == DBL))
+ {
+ /* If this instruction is specific to a particular architecture,
+ then set a new architecture. */
+ if (bfd_get_mach (stdoutput) < pa11)
+ {
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, pa11))
+ as_warn (_("could not update architecture and machine"));
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/* Parse a condition for a fcmp instruction. Return the numerical
+ code associated with the condition. */
+
+static int
+pa_parse_fp_cmp_cond (s)
+ char **s;
+{
+ int cond, i;
+
+ cond = 0;
+
+ for (i = 0; i < 32; i++)
+ {
+ if (strncasecmp (*s, fp_cond_map[i].string,
+ strlen (fp_cond_map[i].string)) == 0)
+ {
+ cond = fp_cond_map[i].cond;
+ *s += strlen (fp_cond_map[i].string);
+ /* If not a complete match, back up the input string and
+ report an error. */
+ if (**s != ' ' && **s != '\t')
+ {
+ *s -= strlen (fp_cond_map[i].string);
+ break;
+ }
+ while (**s == ' ' || **s == '\t')
+ *s = *s + 1;
+ return cond;
+ }
+ }
+
+ as_bad (_("Invalid FP Compare Condition: %s"), *s);
+
+ /* Advance over the bogus completer. */
+ while (**s != ',' && **s != ' ' && **s != '\t')
+ *s += 1;
+
+ return 0;
+}
+
+
+/* Parse an FP operand format completer returning the completer
+ type. */
+
+static fp_operand_format
+pa_parse_fp_format (s)
+ char **s;
+{
+ int format;
+
+ format = SGL;
+ if (**s == ',')
+ {
+ *s += 1;
+ if (strncasecmp (*s, "sgl", 3) == 0)
+ {
+ format = SGL;
+ *s += 4;
+ }
+ else if (strncasecmp (*s, "dbl", 3) == 0)
+ {
+ format = DBL;
+ *s += 4;
+ }
+ else if (strncasecmp (*s, "quad", 4) == 0)
+ {
+ format = QUAD;
+ *s += 5;
+ }
+ else
+ {
+ format = ILLEGAL_FMT;
+ as_bad (_("Invalid FP Operand Format: %3s"), *s);
+ }
+ }
+
+ return format;
+}
+
+/* Convert from a selector string into a selector type. */
+
+static int
+pa_chk_field_selector (str)
+ char **str;
+{
+ int middle, low, high;
+ int cmp;
+ char name[4];
+
+ /* Read past any whitespace. */
+ /* FIXME: should we read past newlines and formfeeds??? */
+ while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\f')
+ *str = *str + 1;
+
+ if ((*str)[1] == '\'' || (*str)[1] == '%')
+ name[0] = tolower ((*str)[0]),
+ name[1] = 0;
+ else if ((*str)[2] == '\'' || (*str)[2] == '%')
+ name[0] = tolower ((*str)[0]),
+ name[1] = tolower ((*str)[1]),
+ name[2] = 0;
+#ifdef OBJ_SOM
+ else if ((*str)[3] == '\'' || (*str)[3] == '%')
+ name[0] = tolower ((*str)[0]),
+ name[1] = tolower ((*str)[1]),
+ name[2] = tolower ((*str)[2]),
+ name[3] = 0;
+#endif
+ else
+ return e_fsel;
+
+ low = 0;
+ high = sizeof (selector_table) / sizeof (struct selector_entry) - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcmp (name, selector_table[middle].prefix);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ {
+ *str += strlen (name) + 1;
+#ifndef OBJ_SOM
+ if (selector_table[middle].field_selector == e_nsel)
+ return e_fsel;
+#endif
+ return selector_table[middle].field_selector;
+ }
+ }
+ while (low <= high);
+
+ return e_fsel;
+}
+
+/* Mark (via expr_end) the end of an expression (I think). FIXME. */
+
+static int
+get_expression (str)
+ char *str;
+{
+ char *save_in;
+ asection *seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ seg = expression (&the_insn.exp);
+ if (!(seg == absolute_section
+ || seg == undefined_section
+ || SEG_NORMAL (seg)))
+ {
+ as_warn (_("Bad segment in expression."));
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+/* Mark (via expr_end) the end of an absolute expression. FIXME. */
+static int
+pa_get_absolute_expression (insn, strp)
+ struct pa_it *insn;
+ char **strp;
+{
+ char *save_in;
+
+ insn->field_selector = pa_chk_field_selector (strp);
+ save_in = input_line_pointer;
+ input_line_pointer = *strp;
+ expression (&insn->exp);
+ /* This is not perfect, but is a huge improvement over doing nothing.
+
+ The PA assembly syntax is ambigious in a variety of ways. Consider
+ this string "4 %r5" Is that the number 4 followed by the register
+ r5, or is that 4 MOD 5?
+
+ If we get a modulo expresion When looking for an absolute, we try
+ again cutting off the input string at the first whitespace character. */
+ if (insn->exp.X_op == O_modulus)
+ {
+ char *s, c;
+ int retval;
+
+ input_line_pointer = *strp;
+ s = *strp;
+ while (*s != ',' && *s != ' ' && *s != '\t')
+ s++;
+
+ c = *s;
+ *s = 0;
+
+ retval = pa_get_absolute_expression (insn, strp);
+
+ input_line_pointer = save_in;
+ *s = c;
+ return evaluate_absolute (insn);
+ }
+ if (insn->exp.X_op != O_constant)
+ {
+ as_bad (_("Bad segment (should be absolute)."));
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return evaluate_absolute (insn);
+}
+
+/* Evaluate an absolute expression EXP which may be modified by
+ the selector FIELD_SELECTOR. Return the value of the expression. */
+static int
+evaluate_absolute (insn)
+ struct pa_it *insn;
+{
+ int value;
+ expressionS exp;
+ int field_selector = insn->field_selector;
+
+ exp = insn->exp;
+ value = exp.X_add_number;
+
+ switch (field_selector)
+ {
+ /* No change. */
+ case e_fsel:
+ break;
+
+ /* If bit 21 is on then add 0x800 and arithmetic shift right 11 bits. */
+ case e_lssel:
+ if (value & 0x00000400)
+ value += 0x800;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ /* Sign extend from bit 21. */
+ case e_rssel:
+ if (value & 0x00000400)
+ value |= 0xfffff800;
+ else
+ value &= 0x7ff;
+ break;
+
+ /* Arithmetic shift right 11 bits. */
+ case e_lsel:
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ /* Set bits 0-20 to zero. */
+ case e_rsel:
+ value = value & 0x7ff;
+ break;
+
+ /* Add 0x800 and arithmetic shift right 11 bits. */
+ case e_ldsel:
+ value += 0x800;
+ value = (value & 0xfffff800) >> 11;
+ break;
+
+ /* Set bitgs 0-21 to one. */
+ case e_rdsel:
+ value |= 0xfffff800;
+ break;
+
+#define RSEL_ROUND(c) (((c) + 0x1000) & ~0x1fff)
+ case e_rrsel:
+ value = (RSEL_ROUND (value) & 0x7ff) + (value - RSEL_ROUND (value));
+ break;
+
+ case e_lrsel:
+ value = (RSEL_ROUND (value) >> 11) & 0x1fffff;
+ break;
+#undef RSEL_ROUND
+
+ default:
+ BAD_CASE (field_selector);
+ break;
+ }
+ return value;
+}
+
+/* Given an argument location specification return the associated
+ argument location number. */
+
+static unsigned int
+pa_build_arg_reloc (type_name)
+ char *type_name;
+{
+
+ if (strncasecmp (type_name, "no", 2) == 0)
+ return 0;
+ if (strncasecmp (type_name, "gr", 2) == 0)
+ return 1;
+ else if (strncasecmp (type_name, "fr", 2) == 0)
+ return 2;
+ else if (strncasecmp (type_name, "fu", 2) == 0)
+ return 3;
+ else
+ as_bad (_("Invalid argument location: %s\n"), type_name);
+
+ return 0;
+}
+
+/* Encode and return an argument relocation specification for
+ the given register in the location specified by arg_reloc. */
+
+static unsigned int
+pa_align_arg_reloc (reg, arg_reloc)
+ unsigned int reg;
+ unsigned int arg_reloc;
+{
+ unsigned int new_reloc;
+
+ new_reloc = arg_reloc;
+ switch (reg)
+ {
+ case 0:
+ new_reloc <<= 8;
+ break;
+ case 1:
+ new_reloc <<= 6;
+ break;
+ case 2:
+ new_reloc <<= 4;
+ break;
+ case 3:
+ new_reloc <<= 2;
+ break;
+ default:
+ as_bad (_("Invalid argument description: %d"), reg);
+ }
+
+ return new_reloc;
+}
+
+/* Parse a PA nullification completer (,n). Return nonzero if the
+ completer was found; return zero if no completer was found. */
+
+static int
+pa_parse_nullif (s)
+ char **s;
+{
+ int nullif;
+
+ nullif = 0;
+ if (**s == ',')
+ {
+ *s = *s + 1;
+ if (strncasecmp (*s, "n", 1) == 0)
+ nullif = 1;
+ else
+ {
+ as_bad (_("Invalid Nullification: (%c)"), **s);
+ nullif = 0;
+ }
+ *s = *s + 1;
+ }
+
+ return nullif;
+}
+
+/* Parse a non-negated compare/subtract completer returning the
+ number (for encoding in instrutions) of the given completer.
+
+ ISBRANCH specifies whether or not this is parsing a condition
+ completer for a branch (vs a nullification completer for a
+ computational instruction. */
+
+static int
+pa_parse_nonneg_cmpsub_cmpltr (s, isbranch)
+ char **s;
+ int isbranch;
+{
+ int cmpltr;
+ char *name = *s + 1;
+ char c;
+ char *save_s = *s;
+ int nullify = 0;
+
+ cmpltr = 0;
+ if (**s == ',')
+ {
+ *s += 1;
+ while (**s != ',' && **s != ' ' && **s != '\t')
+ *s += 1;
+ c = **s;
+ **s = 0x00;
+
+
+ if (strcmp (name, "=") == 0)
+ {
+ cmpltr = 1;
+ }
+ else if (strcmp (name, "<") == 0)
+ {
+ cmpltr = 2;
+ }
+ else if (strcmp (name, "<=") == 0)
+ {
+ cmpltr = 3;
+ }
+ else if (strcmp (name, "<<") == 0)
+ {
+ cmpltr = 4;
+ }
+ else if (strcmp (name, "<<=") == 0)
+ {
+ cmpltr = 5;
+ }
+ else if (strcasecmp (name, "sv") == 0)
+ {
+ cmpltr = 6;
+ }
+ else if (strcasecmp (name, "od") == 0)
+ {
+ cmpltr = 7;
+ }
+ /* If we have something like addb,n then there is no condition
+ completer. */
+ else if (strcasecmp (name, "n") == 0 && isbranch)
+ {
+ cmpltr = 0;
+ nullify = 1;
+ }
+ else
+ {
+ cmpltr = -1;
+ }
+ **s = c;
+ }
+
+ /* Reset pointers if this was really a ,n for a branch instruction. */
+ if (nullify)
+ *s = save_s;
+
+
+ return cmpltr;
+}
+
+/* Parse a negated compare/subtract completer returning the
+ number (for encoding in instrutions) of the given completer.
+
+ ISBRANCH specifies whether or not this is parsing a condition
+ completer for a branch (vs a nullification completer for a
+ computational instruction. */
+
+static int
+pa_parse_neg_cmpsub_cmpltr (s, isbranch)
+ char **s;
+ int isbranch;
+{
+ int cmpltr;
+ char *name = *s + 1;
+ char c;
+ char *save_s = *s;
+ int nullify = 0;
+
+ cmpltr = 0;
+ if (**s == ',')
+ {
+ *s += 1;
+ while (**s != ',' && **s != ' ' && **s != '\t')
+ *s += 1;
+ c = **s;
+ **s = 0x00;
+
+
+ if (strcasecmp (name, "tr") == 0)
+ {
+ cmpltr = 0;
+ }
+ else if (strcmp (name, "<>") == 0)
+ {
+ cmpltr = 1;
+ }
+ else if (strcmp (name, ">=") == 0)
+ {
+ cmpltr = 2;
+ }
+ else if (strcmp (name, ">") == 0)
+ {
+ cmpltr = 3;
+ }
+ else if (strcmp (name, ">>=") == 0)
+ {
+ cmpltr = 4;
+ }
+ else if (strcmp (name, ">>") == 0)
+ {
+ cmpltr = 5;
+ }
+ else if (strcasecmp (name, "nsv") == 0)
+ {
+ cmpltr = 6;
+ }
+ else if (strcasecmp (name, "ev") == 0)
+ {
+ cmpltr = 7;
+ }
+ /* If we have something like addb,n then there is no condition
+ completer. */
+ else if (strcasecmp (name, "n") == 0 && isbranch)
+ {
+ cmpltr = 0;
+ nullify = 1;
+ }
+ else
+ {
+ cmpltr = -1;
+ }
+ **s = c;
+ }
+
+ /* Reset pointers if this was really a ,n for a branch instruction. */
+ if (nullify)
+ *s = save_s;
+
+
+ return cmpltr;
+}
+
+
+/* Parse a non-negated addition completer returning the number
+ (for encoding in instrutions) of the given completer.
+
+ ISBRANCH specifies whether or not this is parsing a condition
+ completer for a branch (vs a nullification completer for a
+ computational instruction. */
+
+static int
+pa_parse_nonneg_add_cmpltr (s, isbranch)
+ char **s;
+ int isbranch;
+{
+ int cmpltr;
+ char *name = *s + 1;
+ char c;
+ char *save_s = *s;
+
+ cmpltr = 0;
+ if (**s == ',')
+ {
+ *s += 1;
+ while (**s != ',' && **s != ' ' && **s != '\t')
+ *s += 1;
+ c = **s;
+ **s = 0x00;
+ if (strcmp (name, "=") == 0)
+ {
+ cmpltr = 1;
+ }
+ else if (strcmp (name, "<") == 0)
+ {
+ cmpltr = 2;
+ }
+ else if (strcmp (name, "<=") == 0)
+ {
+ cmpltr = 3;
+ }
+ else if (strcasecmp (name, "nuv") == 0)
+ {
+ cmpltr = 4;
+ }
+ else if (strcasecmp (name, "znv") == 0)
+ {
+ cmpltr = 5;
+ }
+ else if (strcasecmp (name, "sv") == 0)
+ {
+ cmpltr = 6;
+ }
+ else if (strcasecmp (name, "od") == 0)
+ {
+ cmpltr = 7;
+ }
+ /* If we have something like addb,n then there is no condition
+ completer. */
+ else if (strcasecmp (name, "n") == 0 && isbranch)
+ {
+ cmpltr = 0;
+ }
+ else
+ {
+ cmpltr = -1;
+ }
+ **s = c;
+ }
+
+ /* Reset pointers if this was really a ,n for a branch instruction. */
+ if (cmpltr == 0 && *name == 'n' && isbranch)
+ *s = save_s;
+
+ return cmpltr;
+}
+
+/* Parse a negated addition completer returning the number
+ (for encoding in instrutions) of the given completer.
+
+ ISBRANCH specifies whether or not this is parsing a condition
+ completer for a branch (vs a nullification completer for a
+ computational instruction). */
+
+static int
+pa_parse_neg_add_cmpltr (s, isbranch)
+ char **s;
+ int isbranch;
+{
+ int cmpltr;
+ char *name = *s + 1;
+ char c;
+ char *save_s = *s;
+
+ cmpltr = 0;
+ if (**s == ',')
+ {
+ *s += 1;
+ while (**s != ',' && **s != ' ' && **s != '\t')
+ *s += 1;
+ c = **s;
+ **s = 0x00;
+ if (strcasecmp (name, "tr") == 0)
+ {
+ cmpltr = 0;
+ }
+ else if (strcmp (name, "<>") == 0)
+ {
+ cmpltr = 1;
+ }
+ else if (strcmp (name, ">=") == 0)
+ {
+ cmpltr = 2;
+ }
+ else if (strcmp (name, ">") == 0)
+ {
+ cmpltr = 3;
+ }
+ else if (strcasecmp (name, "uv") == 0)
+ {
+ cmpltr = 4;
+ }
+ else if (strcasecmp (name, "vnz") == 0)
+ {
+ cmpltr = 5;
+ }
+ else if (strcasecmp (name, "nsv") == 0)
+ {
+ cmpltr = 6;
+ }
+ else if (strcasecmp (name, "ev") == 0)
+ {
+ cmpltr = 7;
+ }
+ /* If we have something like addb,n then there is no condition
+ completer. */
+ else if (strcasecmp (name, "n") == 0 && isbranch)
+ {
+ cmpltr = 0;
+ }
+ else
+ {
+ cmpltr = -1;
+ }
+ **s = c;
+ }
+
+ /* Reset pointers if this was really a ,n for a branch instruction. */
+ if (cmpltr == 0 && *name == 'n' && isbranch)
+ *s = save_s;
+
+ return cmpltr;
+}
+
+/* Handle an alignment directive. Special so that we can update the
+ alignment of the subspace if necessary. */
+static void
+pa_align (bytes)
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ /* Let the generic gas code do most of the work. */
+ s_align_bytes (bytes);
+
+ /* If bytes is a power of 2, then update the current subspace's
+ alignment if necessary. */
+ if (log2 (bytes) != -1)
+ record_alignment (current_subspace->ssd_seg, log2 (bytes));
+}
+
+/* Handle a .BLOCK type pseudo-op. */
+
+static void
+pa_block (z)
+ int z;
+{
+ char *p;
+ long int temp_fill;
+ unsigned int temp_size;
+ unsigned int i;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ temp_size = get_absolute_expression ();
+
+ /* Always fill with zeros, that's what the HP assembler does. */
+ temp_fill = 0;
+
+ p = frag_var (rs_fill, (int) temp_size, (int) temp_size,
+ (relax_substateT) 0, (symbolS *) 0, (offsetT) 1, NULL);
+ memset (p, 0, temp_size);
+
+ /* Convert 2 bytes at a time. */
+
+ for (i = 0; i < temp_size; i += 2)
+ {
+ md_number_to_chars (p + i,
+ (valueT) temp_fill,
+ (int) ((temp_size - i) > 2 ? 2 : (temp_size - i)));
+ }
+
+ pa_undefine_label ();
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .begin_brtab and .end_brtab pseudo-op. */
+
+static void
+pa_brtab (begin)
+ int begin;
+{
+
+#ifdef OBJ_SOM
+ /* The BRTAB relocations are only availble in SOM (to denote
+ the beginning and end of branch tables). */
+ char *where = frag_more (0);
+
+ fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
+ NULL, (offsetT) 0, NULL,
+ 0, begin ? R_HPPA_BEGIN_BRTAB : R_HPPA_END_BRTAB,
+ e_fsel, 0, 0, NULL);
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .begin_try and .end_try pseudo-op. */
+
+static void
+pa_try (begin)
+ int begin;
+{
+#ifdef OBJ_SOM
+ expressionS exp;
+ char *where = frag_more (0);
+
+ if (! begin)
+ expression (&exp);
+
+ /* The TRY relocations are only availble in SOM (to denote
+ the beginning and end of exception handling regions). */
+
+ fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
+ NULL, (offsetT) 0, begin ? NULL : &exp,
+ 0, begin ? R_HPPA_BEGIN_TRY : R_HPPA_END_TRY,
+ e_fsel, 0, 0, NULL);
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .CALL pseudo-op. This involves storing away information
+ about where arguments are to be found so the linker can detect
+ (and correct) argument location mismatches between caller and callee. */
+
+static void
+pa_call (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ pa_call_args (&last_call_desc);
+ demand_empty_rest_of_line ();
+}
+
+/* Do the dirty work of building a call descriptor which describes
+ where the caller placed arguments to a function call. */
+
+static void
+pa_call_args (call_desc)
+ struct call_desc *call_desc;
+{
+ char *name, c, *p;
+ unsigned int temp, arg_reloc;
+
+ while (!is_end_of_statement ())
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* Process a source argument. */
+ if ((strncasecmp (name, "argw", 4) == 0))
+ {
+ temp = atoi (name + 4);
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ arg_reloc = pa_build_arg_reloc (name);
+ call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc);
+ }
+ /* Process a return value. */
+ else if ((strncasecmp (name, "rtnval", 6) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ arg_reloc = pa_build_arg_reloc (name);
+ call_desc->arg_reloc |= (arg_reloc & 0x3);
+ }
+ else
+ {
+ as_bad (_("Invalid .CALL argument: %s"), name);
+ }
+ p = input_line_pointer;
+ *p = c;
+ if (!is_end_of_statement ())
+ input_line_pointer++;
+ }
+}
+
+/* Return TRUE if FRAG1 and FRAG2 are the same. */
+
+static int
+is_same_frag (frag1, frag2)
+ fragS *frag1;
+ fragS *frag2;
+{
+
+ if (frag1 == NULL)
+ return (FALSE);
+ else if (frag2 == NULL)
+ return (FALSE);
+ else if (frag1 == frag2)
+ return (TRUE);
+ else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0)
+ return (is_same_frag (frag1, frag2->fr_next));
+ else
+ return (FALSE);
+}
+
+#ifdef OBJ_ELF
+/* Build an entry in the UNWIND subspace from the given function
+ attributes in CALL_INFO. This is not needed for SOM as using
+ R_ENTRY and R_EXIT relocations allow the linker to handle building
+ of the unwind spaces. */
+
+static void
+pa_build_unwind_subspace (call_info)
+ struct call_info *call_info;
+{
+ char *unwind;
+ asection *seg, *save_seg;
+ subsegT subseg, save_subseg;
+ int i;
+ char c, *p;
+
+ /* Get into the right seg/subseg. This may involve creating
+ the seg the first time through. Make sure to have the
+ old seg/subseg so that we can reset things when we are done. */
+ subseg = SUBSEG_UNWIND;
+ seg = bfd_get_section_by_name (stdoutput, UNWIND_SECTION_NAME);
+ if (seg == ASEC_NULL)
+ {
+ seg = bfd_make_section_old_way (stdoutput, UNWIND_SECTION_NAME);
+ bfd_set_section_flags (stdoutput, seg,
+ SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_LOAD | SEC_RELOC);
+ }
+
+ save_seg = now_seg;
+ save_subseg = now_subseg;
+ subseg_set (seg, subseg);
+
+
+ /* Get some space to hold relocation information for the unwind
+ descriptor. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0, 4);
+
+ /* Relocation info. for start offset of the function. */
+ fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
+ call_info->start_symbol, (offsetT) 0,
+ (expressionS *) NULL, 0, R_PARISC_DIR32, e_fsel, 32, 0, NULL);
+
+ p = frag_more (4);
+ md_number_to_chars (p, 0, 4);
+
+ /* Relocation info. for end offset of the function.
+
+ Because we allow reductions of 32bit relocations for ELF, this will be
+ reduced to section_sym + offset which avoids putting the temporary
+ symbol into the symbol table. It (should) end up giving the same
+ value as call_info->start_symbol + function size once the linker is
+ finished with its work. */
+
+ fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
+ call_info->end_symbol, (offsetT) 0,
+ (expressionS *) NULL, 0, R_PARISC_DIR32, e_fsel, 32, 0, NULL);
+
+ /* Dump it. */
+ unwind = (char *) &call_info->ci_unwind;
+ for (i = 8; i < sizeof (struct unwind_table); i++)
+ {
+ c = *(unwind + i);
+ {
+ FRAG_APPEND_1_CHAR (c);
+ }
+ }
+
+ /* Return back to the original segment/subsegment. */
+ subseg_set (save_seg, save_subseg);
+}
+#endif
+
+/* Process a .CALLINFO pseudo-op. This information is used later
+ to build unwind descriptors and maybe one day to support
+ .ENTER and .LEAVE. */
+
+static void
+pa_callinfo (unused)
+ int unused;
+{
+ char *name, c, *p;
+ int temp;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ /* .CALLINFO must appear within a procedure definition. */
+ if (!within_procedure)
+ as_bad (_(".callinfo is not within a procedure definition"));
+
+ /* Mark the fact that we found the .CALLINFO for the
+ current procedure. */
+ callinfo_found = TRUE;
+
+ /* Iterate over the .CALLINFO arguments. */
+ while (!is_end_of_statement ())
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* Frame size specification. */
+ if ((strncasecmp (name, "frame", 5) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ if ((temp & 0x3) != 0)
+ {
+ as_bad (_("FRAME parameter must be a multiple of 8: %d\n"), temp);
+ temp = 0;
+ }
+
+ /* callinfo is in bytes and unwind_desc is in 8 byte units. */
+ last_call_info->ci_unwind.descriptor.frame_size = temp / 8;
+
+ }
+ /* Entry register (GR, GR and SR) specifications. */
+ else if ((strncasecmp (name, "entry_gr", 8) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ /* The HP assembler accepts 19 as the high bound for ENTRY_GR
+ even though %r19 is caller saved. I think this is a bug in
+ the HP assembler, and we are not going to emulate it. */
+ if (temp < 3 || temp > 18)
+ as_bad (_("Value for ENTRY_GR must be in the range 3..18\n"));
+ last_call_info->ci_unwind.descriptor.entry_gr = temp - 2;
+ }
+ else if ((strncasecmp (name, "entry_fr", 8) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ /* Similarly the HP assembler takes 31 as the high bound even
+ though %fr21 is the last callee saved floating point register. */
+ if (temp < 12 || temp > 21)
+ as_bad (_("Value for ENTRY_FR must be in the range 12..21\n"));
+ last_call_info->ci_unwind.descriptor.entry_fr = temp - 11;
+ }
+ else if ((strncasecmp (name, "entry_sr", 8) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ if (temp != 3)
+ as_bad (_("Value for ENTRY_SR must be 3\n"));
+ }
+ /* Note whether or not this function performs any calls. */
+ else if ((strncasecmp (name, "calls", 5) == 0) ||
+ (strncasecmp (name, "caller", 6) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ }
+ else if ((strncasecmp (name, "no_calls", 8) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ }
+ /* Should RP be saved into the stack. */
+ else if ((strncasecmp (name, "save_rp", 7) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ last_call_info->ci_unwind.descriptor.save_rp = 1;
+ }
+ /* Likewise for SP. */
+ else if ((strncasecmp (name, "save_sp", 7) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ last_call_info->ci_unwind.descriptor.save_sp = 1;
+ }
+ /* Is this an unwindable procedure. If so mark it so
+ in the unwind descriptor. */
+ else if ((strncasecmp (name, "no_unwind", 9) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ last_call_info->ci_unwind.descriptor.cannot_unwind = 1;
+ }
+ /* Is this an interrupt routine. If so mark it in the
+ unwind descriptor. */
+ else if ((strncasecmp (name, "hpux_int", 7) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1;
+ }
+ /* Is this a millicode routine. "millicode" isn't in my
+ assembler manual, but my copy is old. The HP assembler
+ accepts it, and there's a place in the unwind descriptor
+ to drop the information, so we'll accept it too. */
+ else if ((strncasecmp (name, "millicode", 9) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ last_call_info->ci_unwind.descriptor.millicode = 1;
+ }
+ else
+ {
+ as_bad (_("Invalid .CALLINFO argument: %s"), name);
+ *input_line_pointer = c;
+ }
+ if (!is_end_of_statement ())
+ input_line_pointer++;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Switch into the code subspace. */
+
+static void
+pa_code (unused)
+ int unused;
+{
+ current_space = is_defined_space ("$TEXT$");
+ current_subspace
+ = pa_subsegment_to_subspace (current_space->sd_seg, 0);
+ s_text (0);
+ pa_undefine_label ();
+}
+
+/* This is different than the standard GAS s_comm(). On HP9000/800 machines,
+ the .comm pseudo-op has the following symtax:
+
+ <label> .comm <length>
+
+ where <label> is optional and is a symbol whose address will be the start of
+ a block of memory <length> bytes long. <length> must be an absolute
+ expression. <length> bytes will be allocated in the current space
+ and subspace.
+
+ Also note the label may not even be on the same line as the .comm.
+
+ This difference in syntax means the colon function will be called
+ on the symbol before we arrive in pa_comm. colon will set a number
+ of attributes of the symbol that need to be fixed here. In particular
+ the value, section pointer, fragment pointer, flags, etc. What
+ a pain.
+
+ This also makes error detection all but impossible. */
+
+static void
+pa_comm (unused)
+ int unused;
+{
+ unsigned int size;
+ symbolS *symbol;
+ label_symbol_struct *label_symbol = pa_get_label ();
+
+ if (label_symbol)
+ symbol = label_symbol->lss_label;
+ else
+ symbol = NULL;
+
+ SKIP_WHITESPACE ();
+ size = get_absolute_expression ();
+
+ if (symbol)
+ {
+ S_SET_VALUE (symbol, size);
+ S_SET_SEGMENT (symbol, bfd_und_section_ptr);
+ S_SET_EXTERNAL (symbol);
+
+ /* colon() has already set the frag to the current location in the
+ current subspace; we need to reset the fragment to the zero address
+ fragment. We also need to reset the segment pointer. */
+ symbol->sy_frag = &zero_address_frag;
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Process a .END pseudo-op. */
+
+static void
+pa_end (unused)
+ int unused;
+{
+ demand_empty_rest_of_line ();
+}
+
+/* Process a .ENTER pseudo-op. This is not supported. */
+static void
+pa_enter (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ as_bad (_("The .ENTER pseudo-op is not supported"));
+ demand_empty_rest_of_line ();
+}
+
+/* Process a .ENTRY pseudo-op. .ENTRY marks the beginning of the
+ procesure. */
+static void
+pa_entry (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ if (!within_procedure)
+ as_bad (_("Misplaced .entry. Ignored."));
+ else
+ {
+ if (!callinfo_found)
+ as_bad (_("Missing .callinfo."));
+ }
+ demand_empty_rest_of_line ();
+ within_entry_exit = TRUE;
+
+#ifdef OBJ_SOM
+ /* SOM defers building of unwind descriptors until the link phase.
+ The assembler is responsible for creating an R_ENTRY relocation
+ to mark the beginning of a region and hold the unwind bits, and
+ for creating an R_EXIT relocation to mark the end of the region.
+
+ FIXME. ELF should be using the same conventions! The problem
+ is an unwind requires too much relocation space. Hmmm. Maybe
+ if we split the unwind bits up between the relocations which
+ denote the entry and exit points. */
+ if (last_call_info->start_symbol != NULL)
+ {
+ char *where = frag_more (0);
+
+ fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
+ NULL, (offsetT) 0, NULL,
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0,
+ (int *) &last_call_info->ci_unwind.descriptor);
+ }
+#endif
+}
+
+/* Handle a .EQU pseudo-op. */
+
+static void
+pa_equ (reg)
+ int reg;
+{
+ label_symbol_struct *label_symbol = pa_get_label ();
+ symbolS *symbol;
+
+ if (label_symbol)
+ {
+ symbol = label_symbol->lss_label;
+ if (reg)
+ S_SET_VALUE (symbol, pa_parse_number (&input_line_pointer, 0));
+ else
+ S_SET_VALUE (symbol, (unsigned int) get_absolute_expression ());
+ S_SET_SEGMENT (symbol, bfd_abs_section_ptr);
+ }
+ else
+ {
+ if (reg)
+ as_bad (_(".REG must use a label"));
+ else
+ as_bad (_(".EQU must use a label"));
+ }
+
+ pa_undefine_label ();
+ demand_empty_rest_of_line ();
+}
+
+/* Helper function. Does processing for the end of a function. This
+ usually involves creating some relocations or building special
+ symbols to mark the end of the function. */
+
+static void
+process_exit ()
+{
+ char *where;
+
+ where = frag_more (0);
+
+#ifdef OBJ_ELF
+ /* Mark the end of the function, stuff away the location of the frag
+ for the end of the function, and finally call pa_build_unwind_subspace
+ to add an entry in the unwind table. */
+ hppa_elf_mark_end_of_function ();
+ pa_build_unwind_subspace (last_call_info);
+#else
+ /* SOM defers building of unwind descriptors until the link phase.
+ The assembler is responsible for creating an R_ENTRY relocation
+ to mark the beginning of a region and hold the unwind bits, and
+ for creating an R_EXIT relocation to mark the end of the region.
+
+ FIXME. ELF should be using the same conventions! The problem
+ is an unwind requires too much relocation space. Hmmm. Maybe
+ if we split the unwind bits up between the relocations which
+ denote the entry and exit points. */
+ fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
+ NULL, (offsetT) 0,
+ NULL, 0, R_HPPA_EXIT, e_fsel, 0, 0,
+ (int *) &last_call_info->ci_unwind.descriptor + 1);
+#endif
+}
+
+/* Process a .EXIT pseudo-op. */
+
+static void
+pa_exit (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ if (!within_procedure)
+ as_bad (_(".EXIT must appear within a procedure"));
+ else
+ {
+ if (!callinfo_found)
+ as_bad (_("Missing .callinfo"));
+ else
+ {
+ if (!within_entry_exit)
+ as_bad (_("No .ENTRY for this .EXIT"));
+ else
+ {
+ within_entry_exit = FALSE;
+ process_exit ();
+ }
+ }
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Process a .EXPORT directive. This makes functions external
+ and provides information such as argument relocation entries
+ to callers. */
+
+static void
+pa_export (unused)
+ int unused;
+{
+ char *name, c, *p;
+ symbolS *symbol;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* Make sure the given symbol exists. */
+ if ((symbol = symbol_find_or_make (name)) == NULL)
+ {
+ as_bad (_("Cannot define export symbol: %s\n"), name);
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ }
+ else
+ {
+ /* OK. Set the external bits and process argument relocations. */
+ S_SET_EXTERNAL (symbol);
+ p = input_line_pointer;
+ *p = c;
+ if (!is_end_of_statement ())
+ {
+ input_line_pointer++;
+ pa_type_args (symbol, 1);
+ }
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Helper function to process arguments to a .EXPORT pseudo-op. */
+
+static void
+pa_type_args (symbolP, is_export)
+ symbolS *symbolP;
+ int is_export;
+{
+ char *name, c, *p;
+ unsigned int temp, arg_reloc;
+ pa_symbol_type type = SYMBOL_TYPE_UNKNOWN;
+ obj_symbol_type *symbol = (obj_symbol_type *) symbolP->bsym;
+
+ if (strncasecmp (input_line_pointer, "absolute", 8) == 0)
+
+ {
+ input_line_pointer += 8;
+ symbolP->bsym->flags &= ~BSF_FUNCTION;
+ S_SET_SEGMENT (symbolP, bfd_abs_section_ptr);
+ type = SYMBOL_TYPE_ABSOLUTE;
+ }
+ else if (strncasecmp (input_line_pointer, "code", 4) == 0)
+ {
+ input_line_pointer += 4;
+ /* IMPORTing/EXPORTing CODE types for functions is meaningless for SOM,
+ instead one should be IMPORTing/EXPORTing ENTRY types.
+
+ Complain if one tries to EXPORT a CODE type since that's never
+ done. Both GCC and HP C still try to IMPORT CODE types, so
+ silently fix them to be ENTRY types. */
+ if (symbolP->bsym->flags & BSF_FUNCTION)
+ {
+ if (is_export)
+ as_tsktsk (_("Using ENTRY rather than CODE in export directive for %s"), symbolP->bsym->name);
+
+ symbolP->bsym->flags |= BSF_FUNCTION;
+ type = SYMBOL_TYPE_ENTRY;
+ }
+ else
+ {
+ symbolP->bsym->flags &= ~BSF_FUNCTION;
+ type = SYMBOL_TYPE_CODE;
+ }
+ }
+ else if (strncasecmp (input_line_pointer, "data", 4) == 0)
+ {
+ input_line_pointer += 4;
+ symbolP->bsym->flags &= ~BSF_FUNCTION;
+ type = SYMBOL_TYPE_DATA;
+ }
+ else if ((strncasecmp (input_line_pointer, "entry", 5) == 0))
+ {
+ input_line_pointer += 5;
+ symbolP->bsym->flags |= BSF_FUNCTION;
+ type = SYMBOL_TYPE_ENTRY;
+ }
+ else if (strncasecmp (input_line_pointer, "millicode", 9) == 0)
+ {
+ input_line_pointer += 9;
+ symbolP->bsym->flags |= BSF_FUNCTION;
+ type = SYMBOL_TYPE_MILLICODE;
+ }
+ else if (strncasecmp (input_line_pointer, "plabel", 6) == 0)
+ {
+ input_line_pointer += 6;
+ symbolP->bsym->flags &= ~BSF_FUNCTION;
+ type = SYMBOL_TYPE_PLABEL;
+ }
+ else if (strncasecmp (input_line_pointer, "pri_prog", 8) == 0)
+ {
+ input_line_pointer += 8;
+ symbolP->bsym->flags |= BSF_FUNCTION;
+ type = SYMBOL_TYPE_PRI_PROG;
+ }
+ else if (strncasecmp (input_line_pointer, "sec_prog", 8) == 0)
+ {
+ input_line_pointer += 8;
+ symbolP->bsym->flags |= BSF_FUNCTION;
+ type = SYMBOL_TYPE_SEC_PROG;
+ }
+
+ /* SOM requires much more information about symbol types
+ than BFD understands. This is how we get this information
+ to the SOM BFD backend. */
+#ifdef obj_set_symbol_type
+ obj_set_symbol_type (symbolP->bsym, (int) type);
+#endif
+
+ /* Now that the type of the exported symbol has been handled,
+ handle any argument relocation information. */
+ while (!is_end_of_statement ())
+ {
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* Argument sources. */
+ if ((strncasecmp (name, "argw", 4) == 0))
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ temp = atoi (name + 4);
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name));
+ symbol->tc_data.ap.hppa_arg_reloc |= arg_reloc;
+ *input_line_pointer = c;
+ }
+ /* The return value. */
+ else if ((strncasecmp (name, "rtnval", 6)) == 0)
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ arg_reloc = pa_build_arg_reloc (name);
+ symbol->tc_data.ap.hppa_arg_reloc |= arg_reloc;
+ *input_line_pointer = c;
+ }
+ /* Privelege level. */
+ else if ((strncasecmp (name, "priv_lev", 8)) == 0)
+ {
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ temp = atoi (input_line_pointer);
+ symbol->tc_data.ap.hppa_priv_level = temp;
+ c = get_symbol_end ();
+ *input_line_pointer = c;
+ }
+ else
+ {
+ as_bad (_("Undefined .EXPORT/.IMPORT argument (ignored): %s"), name);
+ p = input_line_pointer;
+ *p = c;
+ }
+ if (!is_end_of_statement ())
+ input_line_pointer++;
+ }
+}
+
+/* Handle an .IMPORT pseudo-op. Any symbol referenced in a given
+ assembly file must either be defined in the assembly file, or
+ explicitly IMPORTED from another. */
+
+static void
+pa_import (unused)
+ int unused;
+{
+ char *name, c, *p;
+ symbolS *symbol;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ symbol = symbol_find (name);
+ /* Ugh. We might be importing a symbol defined earlier in the file,
+ in which case all the code below will really screw things up
+ (set the wrong segment, symbol flags & type, etc). */
+ if (symbol == NULL || !S_IS_DEFINED (symbol))
+ {
+ symbol = symbol_find_or_make (name);
+ p = input_line_pointer;
+ *p = c;
+
+ if (!is_end_of_statement ())
+ {
+ input_line_pointer++;
+ pa_type_args (symbol, 0);
+ }
+ else
+ {
+ /* Sigh. To be compatable with the HP assembler and to help
+ poorly written assembly code, we assign a type based on
+ the the current segment. Note only BSF_FUNCTION really
+ matters, we do not need to set the full SYMBOL_TYPE_* info. */
+ if (now_seg == text_section)
+ symbol->bsym->flags |= BSF_FUNCTION;
+
+ /* If the section is undefined, then the symbol is undefined
+ Since this is an import, leave the section undefined. */
+ S_SET_SEGMENT (symbol, bfd_und_section_ptr);
+ }
+ }
+ else
+ {
+ /* The symbol was already defined. Just eat everything up to
+ the end of the current statement. */
+ while (!is_end_of_statement ())
+ input_line_pointer++;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .LABEL pseudo-op. */
+
+static void
+pa_label (unused)
+ int unused;
+{
+ char *name, c, *p;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strlen (name) > 0)
+ {
+ colon (name);
+ p = input_line_pointer;
+ *p = c;
+ }
+ else
+ {
+ as_warn (_("Missing label name on .LABEL"));
+ }
+
+ if (!is_end_of_statement ())
+ {
+ as_warn (_("extra .LABEL arguments ignored."));
+ ignore_rest_of_line ();
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .LEAVE pseudo-op. This is not supported yet. */
+
+static void
+pa_leave (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ as_bad (_("The .LEAVE pseudo-op is not supported"));
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .LEVEL pseudo-op. */
+
+static void
+pa_level (unused)
+ int unused;
+{
+ char *level;
+
+ level = input_line_pointer;
+ if (strncmp (level, "1.0", 3) == 0)
+ {
+ input_line_pointer += 3;
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
+ as_warn (_("could not set architecture and machine"));
+ }
+ else if (strncmp (level, "1.1", 3) == 0)
+ {
+ input_line_pointer += 3;
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 11))
+ as_warn (_("could not set architecture and machine"));
+ }
+ else if (strncmp (level, "2.0", 3) == 0)
+ {
+ input_line_pointer += 3;
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 20))
+ as_warn (_("could not set architecture and machine"));
+ }
+ else
+ {
+ as_bad (_("Unrecognized .LEVEL argument\n"));
+ ignore_rest_of_line ();
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .ORIGIN pseudo-op. */
+
+static void
+pa_origin (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ s_org (0);
+ pa_undefine_label ();
+}
+
+/* Handle a .PARAM pseudo-op. This is much like a .EXPORT, except it
+ is for static functions. FIXME. Should share more code with .EXPORT. */
+
+static void
+pa_param (unused)
+ int unused;
+{
+ char *name, c, *p;
+ symbolS *symbol;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ if ((symbol = symbol_find_or_make (name)) == NULL)
+ {
+ as_bad (_("Cannot define static symbol: %s\n"), name);
+ p = input_line_pointer;
+ *p = c;
+ input_line_pointer++;
+ }
+ else
+ {
+ S_CLEAR_EXTERNAL (symbol);
+ p = input_line_pointer;
+ *p = c;
+ if (!is_end_of_statement ())
+ {
+ input_line_pointer++;
+ pa_type_args (symbol, 0);
+ }
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .PROC pseudo-op. It is used to mark the beginning
+ of a procedure from a syntatical point of view. */
+
+static void
+pa_proc (unused)
+ int unused;
+{
+ struct call_info *call_info;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ if (within_procedure)
+ as_fatal (_("Nested procedures"));
+
+ /* Reset global variables for new procedure. */
+ callinfo_found = FALSE;
+ within_procedure = TRUE;
+
+ /* Create another call_info structure. */
+ call_info = (struct call_info *) xmalloc (sizeof (struct call_info));
+
+ if (!call_info)
+ as_fatal (_("Cannot allocate unwind descriptor\n"));
+
+ memset (call_info, 0, sizeof (struct call_info));
+
+ call_info->ci_next = NULL;
+
+ if (call_info_root == NULL)
+ {
+ call_info_root = call_info;
+ last_call_info = call_info;
+ }
+ else
+ {
+ last_call_info->ci_next = call_info;
+ last_call_info = call_info;
+ }
+
+ /* set up defaults on call_info structure */
+
+ call_info->ci_unwind.descriptor.cannot_unwind = 0;
+ call_info->ci_unwind.descriptor.region_desc = 1;
+ call_info->ci_unwind.descriptor.hpux_interrupt_marker = 0;
+
+ /* If we got a .PROC pseudo-op, we know that the function is defined
+ locally. Make sure it gets into the symbol table. */
+ {
+ label_symbol_struct *label_symbol = pa_get_label ();
+
+ if (label_symbol)
+ {
+ if (label_symbol->lss_label)
+ {
+ last_call_info->start_symbol = label_symbol->lss_label;
+ label_symbol->lss_label->bsym->flags |= BSF_FUNCTION;
+ }
+ else
+ as_bad (_("Missing function name for .PROC (corrupted label chain)"));
+ }
+ else
+ last_call_info->start_symbol = NULL;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Process the syntatical end of a procedure. Make sure all the
+ appropriate pseudo-ops were found within the procedure. */
+
+static void
+pa_procend (unused)
+ int unused;
+{
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ /* If we are within a procedure definition, make sure we've
+ defined a label for the procedure; handle case where the
+ label was defined after the .PROC directive.
+
+ Note there's not need to diddle with the segment or fragment
+ for the label symbol in this case. We have already switched
+ into the new $CODE$ subspace at this point. */
+ if (within_procedure && last_call_info->start_symbol == NULL)
+ {
+ label_symbol_struct *label_symbol = pa_get_label ();
+
+ if (label_symbol)
+ {
+ if (label_symbol->lss_label)
+ {
+ last_call_info->start_symbol = label_symbol->lss_label;
+ label_symbol->lss_label->bsym->flags |= BSF_FUNCTION;
+#ifdef OBJ_SOM
+ /* Also handle allocation of a fixup to hold the unwind
+ information when the label appears after the proc/procend. */
+ if (within_entry_exit)
+ {
+ char *where = frag_more (0);
+
+ fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
+ NULL, (offsetT) 0, NULL,
+ 0, R_HPPA_ENTRY, e_fsel, 0, 0,
+ (int *) &last_call_info->ci_unwind.descriptor);
+ }
+#endif
+ }
+ else
+ as_bad (_("Missing function name for .PROC (corrupted label chain)"));
+ }
+ else
+ as_bad (_("Missing function name for .PROC"));
+ }
+
+ if (!within_procedure)
+ as_bad (_("misplaced .procend"));
+
+ if (!callinfo_found)
+ as_bad (_("Missing .callinfo for this procedure"));
+
+ if (within_entry_exit)
+ as_bad (_("Missing .EXIT for a .ENTRY"));
+
+#ifdef OBJ_ELF
+ /* ELF needs to mark the end of each function so that it can compute
+ the size of the function (apparently its needed in the symbol table). */
+ hppa_elf_mark_end_of_function ();
+#endif
+
+ within_procedure = FALSE;
+ demand_empty_rest_of_line ();
+ pa_undefine_label ();
+}
+
+/* Parse the parameters to a .SPACE directive; if CREATE_FLAG is nonzero,
+ then create a new space entry to hold the information specified
+ by the parameters to the .SPACE directive. */
+
+static sd_chain_struct *
+pa_parse_space_stmt (space_name, create_flag)
+ char *space_name;
+ int create_flag;
+{
+ char *name, *ptemp, c;
+ char loadable, defined, private, sort;
+ int spnum, temp;
+ asection *seg = NULL;
+ sd_chain_struct *space;
+
+ /* load default values */
+ spnum = 0;
+ sort = 0;
+ loadable = TRUE;
+ defined = TRUE;
+ private = FALSE;
+ if (strcmp (space_name, "$TEXT$") == 0)
+ {
+ seg = pa_def_spaces[0].segment;
+ defined = pa_def_spaces[0].defined;
+ private = pa_def_spaces[0].private;
+ sort = pa_def_spaces[0].sort;
+ spnum = pa_def_spaces[0].spnum;
+ }
+ else if (strcmp (space_name, "$PRIVATE$") == 0)
+ {
+ seg = pa_def_spaces[1].segment;
+ defined = pa_def_spaces[1].defined;
+ private = pa_def_spaces[1].private;
+ sort = pa_def_spaces[1].sort;
+ spnum = pa_def_spaces[1].spnum;
+ }
+
+ if (!is_end_of_statement ())
+ {
+ print_errors = FALSE;
+ ptemp = input_line_pointer + 1;
+ /* First see if the space was specified as a number rather than
+ as a name. According to the PA assembly manual the rest of
+ the line should be ignored. */
+ temp = pa_parse_number (&ptemp, 0);
+ if (temp >= 0)
+ {
+ spnum = temp;
+ input_line_pointer = ptemp;
+ }
+ else
+ {
+ while (!is_end_of_statement ())
+ {
+ input_line_pointer++;
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ if ((strncasecmp (name, "spnum", 5) == 0))
+ {
+ *input_line_pointer = c;
+ input_line_pointer++;
+ spnum = get_absolute_expression ();
+ }
+ else if ((strncasecmp (name, "sort", 4) == 0))
+ {
+ *input_line_pointer = c;
+ input_line_pointer++;
+ sort = get_absolute_expression ();
+ }
+ else if ((strncasecmp (name, "unloadable", 10) == 0))
+ {
+ *input_line_pointer = c;
+ loadable = FALSE;
+ }
+ else if ((strncasecmp (name, "notdefined", 10) == 0))
+ {
+ *input_line_pointer = c;
+ defined = FALSE;
+ }
+ else if ((strncasecmp (name, "private", 7) == 0))
+ {
+ *input_line_pointer = c;
+ private = TRUE;
+ }
+ else
+ {
+ as_bad (_("Invalid .SPACE argument"));
+ *input_line_pointer = c;
+ if (!is_end_of_statement ())
+ input_line_pointer++;
+ }
+ }
+ }
+ print_errors = TRUE;
+ }
+
+ if (create_flag && seg == NULL)
+ seg = subseg_new (space_name, 0);
+
+ /* If create_flag is nonzero, then create the new space with
+ the attributes computed above. Else set the values in
+ an already existing space -- this can only happen for
+ the first occurence of a built-in space. */
+ if (create_flag)
+ space = create_new_space (space_name, spnum, loadable, defined,
+ private, sort, seg, 1);
+ else
+ {
+ space = is_defined_space (space_name);
+ SPACE_SPNUM (space) = spnum;
+ SPACE_DEFINED (space) = defined & 1;
+ SPACE_USER_DEFINED (space) = 1;
+ }
+
+#ifdef obj_set_section_attributes
+ obj_set_section_attributes (seg, defined, private, sort, spnum);
+#endif
+
+ return space;
+}
+
+/* Handle a .SPACE pseudo-op; this switches the current space to the
+ given space, creating the new space if necessary. */
+
+static void
+pa_space (unused)
+ int unused;
+{
+ char *name, c, *space_name, *save_s;
+ int temp;
+ sd_chain_struct *sd_chain;
+
+ if (within_procedure)
+ {
+ as_bad (_("Can\'t change spaces within a procedure definition. Ignored"));
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ /* Check for some of the predefined spaces. FIXME: most of the code
+ below is repeated several times, can we extract the common parts
+ and place them into a subroutine or something similar? */
+ /* FIXME Is this (and the next IF stmt) really right?
+ What if INPUT_LINE_POINTER points to "$TEXT$FOO"? */
+ if (strncmp (input_line_pointer, "$TEXT$", 6) == 0)
+ {
+ input_line_pointer += 6;
+ sd_chain = is_defined_space ("$TEXT$");
+ if (sd_chain == NULL)
+ sd_chain = pa_parse_space_stmt ("$TEXT$", 1);
+ else if (SPACE_USER_DEFINED (sd_chain) == 0)
+ sd_chain = pa_parse_space_stmt ("$TEXT$", 0);
+
+ current_space = sd_chain;
+ subseg_set (text_section, sd_chain->sd_last_subseg);
+ current_subspace
+ = pa_subsegment_to_subspace (text_section,
+ sd_chain->sd_last_subseg);
+ demand_empty_rest_of_line ();
+ return;
+ }
+ if (strncmp (input_line_pointer, "$PRIVATE$", 9) == 0)
+ {
+ input_line_pointer += 9;
+ sd_chain = is_defined_space ("$PRIVATE$");
+ if (sd_chain == NULL)
+ sd_chain = pa_parse_space_stmt ("$PRIVATE$", 1);
+ else if (SPACE_USER_DEFINED (sd_chain) == 0)
+ sd_chain = pa_parse_space_stmt ("$PRIVATE$", 0);
+
+ current_space = sd_chain;
+ subseg_set (data_section, sd_chain->sd_last_subseg);
+ current_subspace
+ = pa_subsegment_to_subspace (data_section,
+ sd_chain->sd_last_subseg);
+ demand_empty_rest_of_line ();
+ return;
+ }
+ if (!strncasecmp (input_line_pointer,
+ GDB_DEBUG_SPACE_NAME,
+ strlen (GDB_DEBUG_SPACE_NAME)))
+ {
+ input_line_pointer += strlen (GDB_DEBUG_SPACE_NAME);
+ sd_chain = is_defined_space (GDB_DEBUG_SPACE_NAME);
+ if (sd_chain == NULL)
+ sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 1);
+ else if (SPACE_USER_DEFINED (sd_chain) == 0)
+ sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 0);
+
+ current_space = sd_chain;
+
+ {
+ asection *gdb_section
+ = bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME);
+
+ subseg_set (gdb_section, sd_chain->sd_last_subseg);
+ current_subspace
+ = pa_subsegment_to_subspace (gdb_section,
+ sd_chain->sd_last_subseg);
+ }
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* It could be a space specified by number. */
+ print_errors = 0;
+ save_s = input_line_pointer;
+ if ((temp = pa_parse_number (&input_line_pointer, 0)) >= 0)
+ {
+ if ((sd_chain = pa_find_space_by_number (temp)))
+ {
+ current_space = sd_chain;
+
+ subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
+ current_subspace
+ = pa_subsegment_to_subspace (sd_chain->sd_seg,
+ sd_chain->sd_last_subseg);
+ demand_empty_rest_of_line ();
+ return;
+ }
+ }
+
+ /* Not a number, attempt to create a new space. */
+ print_errors = 1;
+ input_line_pointer = save_s;
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ space_name = xmalloc (strlen (name) + 1);
+ strcpy (space_name, name);
+ *input_line_pointer = c;
+
+ sd_chain = pa_parse_space_stmt (space_name, 1);
+ current_space = sd_chain;
+
+ subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
+ current_subspace = pa_subsegment_to_subspace (sd_chain->sd_seg,
+ sd_chain->sd_last_subseg);
+ demand_empty_rest_of_line ();
+ }
+}
+
+/* Switch to a new space. (I think). FIXME. */
+
+static void
+pa_spnum (unused)
+ int unused;
+{
+ char *name;
+ char c;
+ char *p;
+ sd_chain_struct *space;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ space = is_defined_space (name);
+ if (space)
+ {
+ p = frag_more (4);
+ md_number_to_chars (p, SPACE_SPNUM (space), 4);
+ }
+ else
+ as_warn (_("Undefined space: '%s' Assuming space number = 0."), name);
+
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+}
+
+/* If VALUE is an exact power of two between zero and 2^31, then
+ return log2 (VALUE). Else return -1. */
+
+static int
+log2 (value)
+ int value;
+{
+ int shift = 0;
+
+ while ((1 << shift) != value && shift < 32)
+ shift++;
+
+ if (shift >= 32)
+ return -1;
+ else
+ return shift;
+}
+
+/* Handle a .SUBSPACE pseudo-op; this switches the current subspace to the
+ given subspace, creating the new subspace if necessary.
+
+ FIXME. Should mirror pa_space more closely, in particular how
+ they're broken up into subroutines. */
+
+static void
+pa_subspace (create_new)
+ int create_new;
+{
+ char *name, *ss_name, *alias, c;
+ char loadable, code_only, common, dup_common, zero, sort;
+ int i, access, space_index, alignment, quadrant, applicable, flags;
+ sd_chain_struct *space;
+ ssd_chain_struct *ssd;
+ asection *section;
+
+ if (current_space == NULL)
+ as_fatal (_("Must be in a space before changing or declaring subspaces.\n"));
+
+ if (within_procedure)
+ {
+ as_bad (_("Can\'t change subspaces within a procedure definition. Ignored"));
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ ss_name = xmalloc (strlen (name) + 1);
+ strcpy (ss_name, name);
+ *input_line_pointer = c;
+
+ /* Load default values. */
+ sort = 0;
+ access = 0x7f;
+ loadable = 1;
+ common = 0;
+ dup_common = 0;
+ code_only = 0;
+ zero = 0;
+ space_index = ~0;
+ alignment = 1;
+ quadrant = 0;
+ alias = NULL;
+
+ space = current_space;
+ if (create_new)
+ ssd = NULL;
+ else
+ ssd = is_defined_subspace (ss_name);
+ /* Allow user to override the builtin attributes of subspaces. But
+ only allow the attributes to be changed once! */
+ if (ssd && SUBSPACE_DEFINED (ssd))
+ {
+ subseg_set (ssd->ssd_seg, ssd->ssd_subseg);
+ current_subspace = ssd;
+ if (!is_end_of_statement ())
+ as_warn (_("Parameters of an existing subspace can\'t be modified"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ else
+ {
+ /* A new subspace. Load default values if it matches one of
+ the builtin subspaces. */
+ i = 0;
+ while (pa_def_subspaces[i].name)
+ {
+ if (strcasecmp (pa_def_subspaces[i].name, ss_name) == 0)
+ {
+ loadable = pa_def_subspaces[i].loadable;
+ common = pa_def_subspaces[i].common;
+ dup_common = pa_def_subspaces[i].dup_common;
+ code_only = pa_def_subspaces[i].code_only;
+ zero = pa_def_subspaces[i].zero;
+ space_index = pa_def_subspaces[i].space_index;
+ alignment = pa_def_subspaces[i].alignment;
+ quadrant = pa_def_subspaces[i].quadrant;
+ access = pa_def_subspaces[i].access;
+ sort = pa_def_subspaces[i].sort;
+ if (USE_ALIASES && pa_def_subspaces[i].alias)
+ alias = pa_def_subspaces[i].alias;
+ break;
+ }
+ i++;
+ }
+ }
+
+ /* We should be working with a new subspace now. Fill in
+ any information as specified by the user. */
+ if (!is_end_of_statement ())
+ {
+ input_line_pointer++;
+ while (!is_end_of_statement ())
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ if ((strncasecmp (name, "quad", 4) == 0))
+ {
+ *input_line_pointer = c;
+ input_line_pointer++;
+ quadrant = get_absolute_expression ();
+ }
+ else if ((strncasecmp (name, "align", 5) == 0))
+ {
+ *input_line_pointer = c;
+ input_line_pointer++;
+ alignment = get_absolute_expression ();
+ if (log2 (alignment) == -1)
+ {
+ as_bad (_("Alignment must be a power of 2"));
+ alignment = 1;
+ }
+ }
+ else if ((strncasecmp (name, "access", 6) == 0))
+ {
+ *input_line_pointer = c;
+ input_line_pointer++;
+ access = get_absolute_expression ();
+ }
+ else if ((strncasecmp (name, "sort", 4) == 0))
+ {
+ *input_line_pointer = c;
+ input_line_pointer++;
+ sort = get_absolute_expression ();
+ }
+ else if ((strncasecmp (name, "code_only", 9) == 0))
+ {
+ *input_line_pointer = c;
+ code_only = 1;
+ }
+ else if ((strncasecmp (name, "unloadable", 10) == 0))
+ {
+ *input_line_pointer = c;
+ loadable = 0;
+ }
+ else if ((strncasecmp (name, "common", 6) == 0))
+ {
+ *input_line_pointer = c;
+ common = 1;
+ }
+ else if ((strncasecmp (name, "dup_comm", 8) == 0))
+ {
+ *input_line_pointer = c;
+ dup_common = 1;
+ }
+ else if ((strncasecmp (name, "zero", 4) == 0))
+ {
+ *input_line_pointer = c;
+ zero = 1;
+ }
+ else if ((strncasecmp (name, "first", 5) == 0))
+ as_bad (_("FIRST not supported as a .SUBSPACE argument"));
+ else
+ as_bad (_("Invalid .SUBSPACE argument"));
+ if (!is_end_of_statement ())
+ input_line_pointer++;
+ }
+ }
+
+ /* Compute a reasonable set of BFD flags based on the information
+ in the .subspace directive. */
+ applicable = bfd_applicable_section_flags (stdoutput);
+ flags = 0;
+ if (loadable)
+ flags |= (SEC_ALLOC | SEC_LOAD);
+ if (code_only)
+ flags |= SEC_CODE;
+ if (common || dup_common)
+ flags |= SEC_IS_COMMON;
+
+ flags |= SEC_RELOC | SEC_HAS_CONTENTS;
+
+ /* This is a zero-filled subspace (eg BSS). */
+ if (zero)
+ flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS);
+
+ applicable &= flags;
+
+ /* If this is an existing subspace, then we want to use the
+ segment already associated with the subspace.
+
+ FIXME NOW! ELF BFD doesn't appear to be ready to deal with
+ lots of sections. It might be a problem in the PA ELF
+ code, I do not know yet. For now avoid creating anything
+ but the "standard" sections for ELF. */
+ if (create_new)
+ section = subseg_force_new (ss_name, 0);
+ else if (ssd)
+ section = ssd->ssd_seg;
+ else if (alias)
+ section = subseg_new (alias, 0);
+ else if (!alias && USE_ALIASES)
+ {
+ as_warn (_("Ignoring subspace decl due to ELF BFD bugs."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ else
+ section = subseg_new (ss_name, 0);
+
+ if (zero)
+ seg_info (section)->bss = 1;
+
+ /* Now set the flags. */
+ bfd_set_section_flags (stdoutput, section, applicable);
+
+ /* Record any alignment request for this section. */
+ record_alignment (section, log2 (alignment));
+
+ /* Set the starting offset for this section. */
+ bfd_set_section_vma (stdoutput, section,
+ pa_subspace_start (space, quadrant));
+
+ /* Now that all the flags are set, update an existing subspace,
+ or create a new one. */
+ if (ssd)
+
+ current_subspace = update_subspace (space, ss_name, loadable,
+ code_only, common, dup_common,
+ sort, zero, access, space_index,
+ alignment, quadrant,
+ section);
+ else
+ current_subspace = create_new_subspace (space, ss_name, loadable,
+ code_only, common,
+ dup_common, zero, sort,
+ access, space_index,
+ alignment, quadrant, section);
+
+ demand_empty_rest_of_line ();
+ current_subspace->ssd_seg = section;
+ subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
+ }
+ SUBSPACE_DEFINED (current_subspace) = 1;
+}
+
+
+/* Create default space and subspace dictionaries. */
+
+static void
+pa_spaces_begin ()
+{
+ int i;
+
+ space_dict_root = NULL;
+ space_dict_last = NULL;
+
+ i = 0;
+ while (pa_def_spaces[i].name)
+ {
+ char *name;
+
+ /* Pick the right name to use for the new section. */
+ if (pa_def_spaces[i].alias && USE_ALIASES)
+ name = pa_def_spaces[i].alias;
+ else
+ name = pa_def_spaces[i].name;
+
+ pa_def_spaces[i].segment = subseg_new (name, 0);
+ create_new_space (pa_def_spaces[i].name, pa_def_spaces[i].spnum,
+ pa_def_spaces[i].loadable, pa_def_spaces[i].defined,
+ pa_def_spaces[i].private, pa_def_spaces[i].sort,
+ pa_def_spaces[i].segment, 0);
+ i++;
+ }
+
+ i = 0;
+ while (pa_def_subspaces[i].name)
+ {
+ char *name;
+ int applicable, subsegment;
+ asection *segment = NULL;
+ sd_chain_struct *space;
+
+ /* Pick the right name for the new section and pick the right
+ subsegment number. */
+ if (pa_def_subspaces[i].alias && USE_ALIASES)
+ {
+ name = pa_def_subspaces[i].alias;
+ subsegment = pa_def_subspaces[i].subsegment;
+ }
+ else
+ {
+ name = pa_def_subspaces[i].name;
+ subsegment = 0;
+ }
+
+ /* Create the new section. */
+ segment = subseg_new (name, subsegment);
+
+
+ /* For SOM we want to replace the standard .text, .data, and .bss
+ sections with our own. We also want to set BFD flags for
+ all the built-in subspaces. */
+ if (!strcmp (pa_def_subspaces[i].name, "$CODE$") && !USE_ALIASES)
+ {
+ text_section = segment;
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, segment,
+ applicable & (SEC_ALLOC | SEC_LOAD
+ | SEC_RELOC | SEC_CODE
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS));
+ }
+ else if (!strcmp (pa_def_subspaces[i].name, "$DATA$") && !USE_ALIASES)
+ {
+ data_section = segment;
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, segment,
+ applicable & (SEC_ALLOC | SEC_LOAD
+ | SEC_RELOC
+ | SEC_HAS_CONTENTS));
+
+
+ }
+ else if (!strcmp (pa_def_subspaces[i].name, "$BSS$") && !USE_ALIASES)
+ {
+ bss_section = segment;
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, segment,
+ applicable & SEC_ALLOC);
+ }
+ else if (!strcmp (pa_def_subspaces[i].name, "$LIT$") && !USE_ALIASES)
+ {
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, segment,
+ applicable & (SEC_ALLOC | SEC_LOAD
+ | SEC_RELOC
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS));
+ }
+ else if (!strcmp (pa_def_subspaces[i].name, "$MILLICODE$")
+ && !USE_ALIASES)
+ {
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, segment,
+ applicable & (SEC_ALLOC | SEC_LOAD
+ | SEC_RELOC
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS));
+ }
+ else if (!strcmp (pa_def_subspaces[i].name, "$UNWIND$") && !USE_ALIASES)
+ {
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, segment,
+ applicable & (SEC_ALLOC | SEC_LOAD
+ | SEC_RELOC
+ | SEC_READONLY
+ | SEC_HAS_CONTENTS));
+ }
+
+ /* Find the space associated with this subspace. */
+ space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].
+ def_space_index].segment);
+ if (space == NULL)
+ {
+ as_fatal (_("Internal error: Unable to find containing space for %s."),
+ pa_def_subspaces[i].name);
+ }
+
+ create_new_subspace (space, name,
+ pa_def_subspaces[i].loadable,
+ pa_def_subspaces[i].code_only,
+ pa_def_subspaces[i].common,
+ pa_def_subspaces[i].dup_common,
+ pa_def_subspaces[i].zero,
+ pa_def_subspaces[i].sort,
+ pa_def_subspaces[i].access,
+ pa_def_subspaces[i].space_index,
+ pa_def_subspaces[i].alignment,
+ pa_def_subspaces[i].quadrant,
+ segment);
+ i++;
+ }
+}
+
+
+
+/* Create a new space NAME, with the appropriate flags as defined
+ by the given parameters. */
+
+static sd_chain_struct *
+create_new_space (name, spnum, loadable, defined, private,
+ sort, seg, user_defined)
+ char *name;
+ int spnum;
+ int loadable;
+ int defined;
+ int private;
+ int sort;
+ asection *seg;
+ int user_defined;
+{
+ sd_chain_struct *chain_entry;
+
+ chain_entry = (sd_chain_struct *) xmalloc (sizeof (sd_chain_struct));
+ if (!chain_entry)
+ as_fatal (_("Out of memory: could not allocate new space chain entry: %s\n"),
+ name);
+
+ SPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
+ strcpy (SPACE_NAME (chain_entry), name);
+ SPACE_DEFINED (chain_entry) = defined;
+ SPACE_USER_DEFINED (chain_entry) = user_defined;
+ SPACE_SPNUM (chain_entry) = spnum;
+
+ chain_entry->sd_seg = seg;
+ chain_entry->sd_last_subseg = -1;
+ chain_entry->sd_subspaces = NULL;
+ chain_entry->sd_next = NULL;
+
+ /* Find spot for the new space based on its sort key. */
+ if (!space_dict_last)
+ space_dict_last = chain_entry;
+
+ if (space_dict_root == NULL)
+ space_dict_root = chain_entry;
+ else
+ {
+ sd_chain_struct *chain_pointer;
+ sd_chain_struct *prev_chain_pointer;
+
+ chain_pointer = space_dict_root;
+ prev_chain_pointer = NULL;
+
+ while (chain_pointer)
+ {
+ prev_chain_pointer = chain_pointer;
+ chain_pointer = chain_pointer->sd_next;
+ }
+
+ /* At this point we've found the correct place to add the new
+ entry. So add it and update the linked lists as appropriate. */
+ if (prev_chain_pointer)
+ {
+ chain_entry->sd_next = chain_pointer;
+ prev_chain_pointer->sd_next = chain_entry;
+ }
+ else
+ {
+ space_dict_root = chain_entry;
+ chain_entry->sd_next = chain_pointer;
+ }
+
+ if (chain_entry->sd_next == NULL)
+ space_dict_last = chain_entry;
+ }
+
+ /* This is here to catch predefined spaces which do not get
+ modified by the user's input. Another call is found at
+ the bottom of pa_parse_space_stmt to handle cases where
+ the user modifies a predefined space. */
+#ifdef obj_set_section_attributes
+ obj_set_section_attributes (seg, defined, private, sort, spnum);
+#endif
+
+ return chain_entry;
+}
+
+/* Create a new subspace NAME, with the appropriate flags as defined
+ by the given parameters.
+
+ Add the new subspace to the subspace dictionary chain in numerical
+ order as defined by the SORT entries. */
+
+static ssd_chain_struct *
+create_new_subspace (space, name, loadable, code_only, common,
+ dup_common, is_zero, sort, access, space_index,
+ alignment, quadrant, seg)
+ sd_chain_struct *space;
+ char *name;
+ int loadable, code_only, common, dup_common, is_zero;
+ int sort;
+ int access;
+ int space_index;
+ int alignment;
+ int quadrant;
+ asection *seg;
+{
+ ssd_chain_struct *chain_entry;
+
+ chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
+ if (!chain_entry)
+ as_fatal (_("Out of memory: could not allocate new subspace chain entry: %s\n"), name);
+
+ SUBSPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
+ strcpy (SUBSPACE_NAME (chain_entry), name);
+
+ /* Initialize subspace_defined. When we hit a .subspace directive
+ we'll set it to 1 which "locks-in" the subspace attributes. */
+ SUBSPACE_DEFINED (chain_entry) = 0;
+
+ chain_entry->ssd_subseg = USE_ALIASES ? pa_next_subseg (space) : 0;
+ chain_entry->ssd_seg = seg;
+ chain_entry->ssd_next = NULL;
+
+ /* Find spot for the new subspace based on its sort key. */
+ if (space->sd_subspaces == NULL)
+ space->sd_subspaces = chain_entry;
+ else
+ {
+ ssd_chain_struct *chain_pointer;
+ ssd_chain_struct *prev_chain_pointer;
+
+ chain_pointer = space->sd_subspaces;
+ prev_chain_pointer = NULL;
+
+ while (chain_pointer)
+ {
+ prev_chain_pointer = chain_pointer;
+ chain_pointer = chain_pointer->ssd_next;
+ }
+
+ /* Now we have somewhere to put the new entry. Insert it and update
+ the links. */
+ if (prev_chain_pointer)
+ {
+ chain_entry->ssd_next = chain_pointer;
+ prev_chain_pointer->ssd_next = chain_entry;
+ }
+ else
+ {
+ space->sd_subspaces = chain_entry;
+ chain_entry->ssd_next = chain_pointer;
+ }
+ }
+
+#ifdef obj_set_subsection_attributes
+ obj_set_subsection_attributes (seg, space->sd_seg, access,
+ sort, quadrant);
+#endif
+
+ return chain_entry;
+}
+
+/* Update the information for the given subspace based upon the
+ various arguments. Return the modified subspace chain entry. */
+
+static ssd_chain_struct *
+update_subspace (space, name, loadable, code_only, common, dup_common, sort,
+ zero, access, space_index, alignment, quadrant, section)
+ sd_chain_struct *space;
+ char *name;
+ int loadable;
+ int code_only;
+ int common;
+ int dup_common;
+ int zero;
+ int sort;
+ int access;
+ int space_index;
+ int alignment;
+ int quadrant;
+ asection *section;
+{
+ ssd_chain_struct *chain_entry;
+
+ chain_entry = is_defined_subspace (name);
+
+#ifdef obj_set_subsection_attributes
+ obj_set_subsection_attributes (section, space->sd_seg, access,
+ sort, quadrant);
+#endif
+
+ return chain_entry;
+}
+
+/* Return the space chain entry for the space with the name NAME or
+ NULL if no such space exists. */
+
+static sd_chain_struct *
+is_defined_space (name)
+ char *name;
+{
+ sd_chain_struct *chain_pointer;
+
+ for (chain_pointer = space_dict_root;
+ chain_pointer;
+ chain_pointer = chain_pointer->sd_next)
+ {
+ if (strcmp (SPACE_NAME (chain_pointer), name) == 0)
+ return chain_pointer;
+ }
+
+ /* No mapping from segment to space was found. Return NULL. */
+ return NULL;
+}
+
+/* Find and return the space associated with the given seg. If no mapping
+ from the given seg to a space is found, then return NULL.
+
+ Unlike subspaces, the number of spaces is not expected to grow much,
+ so a linear exhaustive search is OK here. */
+
+static sd_chain_struct *
+pa_segment_to_space (seg)
+ asection *seg;
+{
+ sd_chain_struct *space_chain;
+
+ /* Walk through each space looking for the correct mapping. */
+ for (space_chain = space_dict_root;
+ space_chain;
+ space_chain = space_chain->sd_next)
+ {
+ if (space_chain->sd_seg == seg)
+ return space_chain;
+ }
+
+ /* Mapping was not found. Return NULL. */
+ return NULL;
+}
+
+/* Return the space chain entry for the subspace with the name NAME or
+ NULL if no such subspace exists.
+
+ Uses a linear search through all the spaces and subspaces, this may
+ not be appropriate if we ever being placing each function in its
+ own subspace. */
+
+static ssd_chain_struct *
+is_defined_subspace (name)
+ char *name;
+{
+ sd_chain_struct *space_chain;
+ ssd_chain_struct *subspace_chain;
+
+ /* Walk through each space. */
+ for (space_chain = space_dict_root;
+ space_chain;
+ space_chain = space_chain->sd_next)
+ {
+ /* Walk through each subspace looking for a name which matches. */
+ for (subspace_chain = space_chain->sd_subspaces;
+ subspace_chain;
+ subspace_chain = subspace_chain->ssd_next)
+ if (strcmp (SUBSPACE_NAME (subspace_chain), name) == 0)
+ return subspace_chain;
+ }
+
+ /* Subspace wasn't found. Return NULL. */
+ return NULL;
+}
+
+/* Find and return the subspace associated with the given seg. If no
+ mapping from the given seg to a subspace is found, then return NULL.
+
+ If we ever put each procedure/function within its own subspace
+ (to make life easier on the compiler and linker), then this will have
+ to become more efficient. */
+
+static ssd_chain_struct *
+pa_subsegment_to_subspace (seg, subseg)
+ asection *seg;
+ subsegT subseg;
+{
+ sd_chain_struct *space_chain;
+ ssd_chain_struct *subspace_chain;
+
+ /* Walk through each space. */
+ for (space_chain = space_dict_root;
+ space_chain;
+ space_chain = space_chain->sd_next)
+ {
+ if (space_chain->sd_seg == seg)
+ {
+ /* Walk through each subspace within each space looking for
+ the correct mapping. */
+ for (subspace_chain = space_chain->sd_subspaces;
+ subspace_chain;
+ subspace_chain = subspace_chain->ssd_next)
+ if (subspace_chain->ssd_subseg == (int) subseg)
+ return subspace_chain;
+ }
+ }
+
+ /* No mapping from subsegment to subspace found. Return NULL. */
+ return NULL;
+}
+
+/* Given a number, try and find a space with the name number.
+
+ Return a pointer to a space dictionary chain entry for the space
+ that was found or NULL on failure. */
+
+static sd_chain_struct *
+pa_find_space_by_number (number)
+ int number;
+{
+ sd_chain_struct *space_chain;
+
+ for (space_chain = space_dict_root;
+ space_chain;
+ space_chain = space_chain->sd_next)
+ {
+ if (SPACE_SPNUM (space_chain) == (unsigned int) number)
+ return space_chain;
+ }
+
+ /* No appropriate space found. Return NULL. */
+ return NULL;
+}
+
+/* Return the starting address for the given subspace. If the starting
+ address is unknown then return zero. */
+
+static unsigned int
+pa_subspace_start (space, quadrant)
+ sd_chain_struct *space;
+ int quadrant;
+{
+#ifdef OBJ_SOM
+ /* FIXME. Assumes everyone puts read/write data at 0x4000000, this
+ is not correct for the PA OSF1 port. */
+ if ((strcmp (SPACE_NAME (space), "$PRIVATE$") == 0) && quadrant == 1)
+ return 0x40000000;
+ else if (space->sd_seg == data_section && quadrant == 1)
+ return 0x40000000;
+ else
+ return 0;
+#endif
+ return 0;
+}
+
+/* FIXME. Needs documentation. */
+static int
+pa_next_subseg (space)
+ sd_chain_struct *space;
+{
+
+ space->sd_last_subseg++;
+ return space->sd_last_subseg;
+}
+
+/* Helper function for pa_stringer. Used to find the end of
+ a string. */
+
+static unsigned int
+pa_stringer_aux (s)
+ char *s;
+{
+ unsigned int c = *s & CHAR_MASK;
+
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ switch (c)
+ {
+ case '\"':
+ c = NOT_A_CHAR;
+ break;
+ default:
+ break;
+ }
+ return c;
+}
+
+/* Handle a .STRING type pseudo-op. */
+
+static void
+pa_stringer (append_zero)
+ int append_zero;
+{
+ char *s, num_buf[4];
+ unsigned int c;
+ int i;
+
+ /* Preprocess the string to handle PA-specific escape sequences.
+ For example, \xDD where DD is a hexidecimal number should be
+ changed to \OOO where OOO is an octal number. */
+
+ /* Skip the opening quote. */
+ s = input_line_pointer + 1;
+
+ while (is_a_char (c = pa_stringer_aux (s++)))
+ {
+ if (c == '\\')
+ {
+ c = *s;
+ switch (c)
+ {
+ /* Handle \x<num>. */
+ case 'x':
+ {
+ unsigned int number;
+ int num_digit;
+ char dg;
+ char *s_start = s;
+
+ /* Get pas the 'x'. */
+ s++;
+ for (num_digit = 0, number = 0, dg = *s;
+ num_digit < 2
+ && (isdigit (dg) || (dg >= 'a' && dg <= 'f')
+ || (dg >= 'A' && dg <= 'F'));
+ num_digit++)
+ {
+ if (isdigit (dg))
+ number = number * 16 + dg - '0';
+ else if (dg >= 'a' && dg <= 'f')
+ number = number * 16 + dg - 'a' + 10;
+ else
+ number = number * 16 + dg - 'A' + 10;
+
+ s++;
+ dg = *s;
+ }
+ if (num_digit > 0)
+ {
+ switch (num_digit)
+ {
+ case 1:
+ sprintf (num_buf, "%02o", number);
+ break;
+ case 2:
+ sprintf (num_buf, "%03o", number);
+ break;
+ }
+ for (i = 0; i <= num_digit; i++)
+ s_start[i] = num_buf[i];
+ }
+ break;
+ }
+ /* This might be a "\"", skip over the escaped char. */
+ default:
+ s++;
+ break;
+ }
+ }
+ }
+ stringer (append_zero);
+ pa_undefine_label ();
+}
+
+/* Handle a .VERSION pseudo-op. */
+
+static void
+pa_version (unused)
+ int unused;
+{
+ obj_version (0);
+ pa_undefine_label ();
+}
+
+#ifdef OBJ_SOM
+
+/* Handle a .COMPILER pseudo-op. */
+
+static void
+pa_compiler (unused)
+ int unused;
+{
+ obj_som_compiler (0);
+ pa_undefine_label ();
+}
+
+#endif
+
+/* Handle a .COPYRIGHT pseudo-op. */
+
+static void
+pa_copyright (unused)
+ int unused;
+{
+ obj_copyright (0);
+ pa_undefine_label ();
+}
+
+/* Just like a normal cons, but when finished we have to undefine
+ the latest space label. */
+
+static void
+pa_cons (nbytes)
+ int nbytes;
+{
+ cons (nbytes);
+ pa_undefine_label ();
+}
+
+/* Switch to the data space. As usual delete our label. */
+
+static void
+pa_data (unused)
+ int unused;
+{
+ current_space = is_defined_space ("$PRIVATE$");
+ current_subspace
+ = pa_subsegment_to_subspace (current_space->sd_seg, 0);
+ s_data (0);
+ pa_undefine_label ();
+}
+
+/* Like float_cons, but we need to undefine our label. */
+
+static void
+pa_float_cons (float_type)
+ int float_type;
+{
+ float_cons (float_type);
+ pa_undefine_label ();
+}
+
+/* Like s_fill, but delete our label when finished. */
+
+static void
+pa_fill (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ s_fill (0);
+ pa_undefine_label ();
+}
+
+/* Like lcomm, but delete our label when finished. */
+
+static void
+pa_lcomm (needs_align)
+ int needs_align;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ s_lcomm (needs_align);
+ pa_undefine_label ();
+}
+
+/* Like lsym, but delete our label when finished. */
+
+static void
+pa_lsym (unused)
+ int unused;
+{
+ /* We must have a valid space and subspace. */
+ pa_check_current_space_and_subspace ();
+
+ s_lsym (0);
+ pa_undefine_label ();
+}
+
+/* Switch to the text space. Like s_text, but delete our
+ label when finished. */
+static void
+pa_text (unused)
+ int unused;
+{
+ current_space = is_defined_space ("$TEXT$");
+ current_subspace
+ = pa_subsegment_to_subspace (current_space->sd_seg, 0);
+
+ s_text (0);
+ pa_undefine_label ();
+}
+
+/* On the PA relocations which involve function symbols must not be
+ adjusted. This so that the linker can know when/how to create argument
+ relocation stubs for indirect calls and calls to static functions.
+
+ "T" field selectors create DLT relative fixups for accessing
+ globals and statics in PIC code; each DLT relative fixup creates
+ an entry in the DLT table. The entries contain the address of
+ the final target (eg accessing "foo" would create a DLT entry
+ with the address of "foo").
+
+ Unfortunately, the HP linker doesn't take into account any addend
+ when generating the DLT; so accessing $LIT$+8 puts the address of
+ $LIT$ into the DLT rather than the address of $LIT$+8.
+
+ The end result is we can't perform relocation symbol reductions for
+ any fixup which creates entries in the DLT (eg they use "T" field
+ selectors).
+
+ Reject reductions involving symbols with external scope; such
+ reductions make life a living hell for object file editors.
+
+ FIXME. Also reject R_HPPA relocations which are 32bits wide in
+ the code space. The SOM BFD backend doesn't know how to pull the
+ right bits out of an instruction. */
+
+int
+hppa_fix_adjustable (fixp)
+ fixS *fixp;
+{
+ struct hppa_fix_struct *hppa_fix;
+
+ hppa_fix = (struct hppa_fix_struct *) fixp->tc_fix_data;
+
+#ifdef OBJ_SOM
+ /* Reject reductions of symbols in 32bit relocs. */
+ if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
+ return 0;
+
+ /* Reject reductions of symbols in sym1-sym2 expressions when
+ the fixup will occur in a CODE subspace.
+
+ XXX FIXME: Long term we probably want to reject all of these;
+ for example reducing in the debug section would lose if we ever
+ supported using the optimizing hp linker. */
+ if (fixp->fx_addsy
+ && fixp->fx_subsy
+ && (hppa_fix->segment->flags & SEC_CODE))
+ {
+ /* Apparently sy_used_in_reloc never gets set for sub symbols. */
+ fixp->fx_subsy->sy_used_in_reloc = 1;
+ return 0;
+ }
+
+ /* We can't adjust any relocs that use LR% and RR% field selectors.
+ That confuses the HP linker. */
+ if (hppa_fix->fx_r_field == e_lrsel
+ || hppa_fix->fx_r_field == e_rrsel
+ || hppa_fix->fx_r_field == e_nlrsel)
+ return 0;
+#endif
+
+ /* Reject reductions of symbols in DLT relative relocs,
+ relocations with plabels. */
+ if (hppa_fix->fx_r_field == e_tsel
+ || hppa_fix->fx_r_field == e_ltsel
+ || hppa_fix->fx_r_field == e_rtsel
+ || hppa_fix->fx_r_field == e_psel
+ || hppa_fix->fx_r_field == e_rpsel
+ || hppa_fix->fx_r_field == e_lpsel)
+ return 0;
+
+ if (fixp->fx_addsy && fixp->fx_addsy->bsym->flags & BSF_GLOBAL)
+ return 0;
+
+ /* Reject absolute calls (jumps). */
+ if (hppa_fix->fx_r_type == R_HPPA_ABS_CALL)
+ return 0;
+
+ /* Reject reductions of function symbols. */
+ if (fixp->fx_addsy == 0
+ || (fixp->fx_addsy->bsym->flags & BSF_FUNCTION) == 0)
+ return 1;
+
+ return 0;
+}
+
+/* Return nonzero if the fixup in FIXP will require a relocation,
+ even it if appears that the fixup could be completely handled
+ within GAS. */
+
+int
+hppa_force_relocation (fixp)
+ fixS *fixp;
+{
+ struct hppa_fix_struct *hppa_fixp;
+ int distance;
+
+ hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
+#ifdef OBJ_SOM
+ if (fixp->fx_r_type == R_HPPA_ENTRY || fixp->fx_r_type == R_HPPA_EXIT
+ || fixp->fx_r_type == R_HPPA_BEGIN_BRTAB
+ || fixp->fx_r_type == R_HPPA_END_BRTAB
+ || fixp->fx_r_type == R_HPPA_BEGIN_TRY
+ || fixp->fx_r_type == R_HPPA_END_TRY
+ || (fixp->fx_addsy != NULL && fixp->fx_subsy != NULL
+ && (hppa_fixp->segment->flags & SEC_CODE) != 0))
+ return 1;
+#endif
+
+#define arg_reloc_stub_needed(CALLER, CALLEE) \
+ ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
+
+ /* It is necessary to force PC-relative calls/jumps to have a relocation
+ entry if they're going to need either a argument relocation or long
+ call stub. FIXME. Can't we need the same for absolute calls? */
+ if (fixp->fx_pcrel && fixp->fx_addsy
+ && (arg_reloc_stub_needed ((long) ((obj_symbol_type *)
+ fixp->fx_addsy->bsym)->tc_data.ap.hppa_arg_reloc,
+
+ hppa_fixp->fx_arg_reloc)))
+ return 1;
+ distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy)
+ - md_pcrel_from (fixp));
+ /* Now check and see if we're going to need a long-branch stub. */
+ if (fixp->fx_r_type == R_HPPA_PCREL_CALL
+ && (distance > 262143 || distance < -262144))
+ return 1;
+
+ if (fixp->fx_r_type == R_HPPA_ABS_CALL)
+ return 1;
+#undef arg_reloc_stub_needed
+
+ /* No need (yet) to force another relocations to be emitted. */
+ return 0;
+}
+
+/* Now for some ELF specific code. FIXME. */
+#ifdef OBJ_ELF
+/* Mark the end of a function so that it's possible to compute
+ the size of the function in hppa_elf_final_processing. */
+
+static void
+hppa_elf_mark_end_of_function ()
+{
+ /* ELF does not have EXIT relocations. All we do is create a
+ temporary symbol marking the end of the function. */
+ char *name = (char *)
+ xmalloc (strlen ("L$\001end_") +
+ strlen (S_GET_NAME (last_call_info->start_symbol)) + 1);
+
+ if (name)
+ {
+ symbolS *symbolP;
+
+ strcpy (name, "L$\001end_");
+ strcat (name, S_GET_NAME (last_call_info->start_symbol));
+
+ /* If we have a .exit followed by a .procend, then the
+ symbol will have already been defined. */
+ symbolP = symbol_find (name);
+ if (symbolP)
+ {
+ /* The symbol has already been defined! This can
+ happen if we have a .exit followed by a .procend.
+
+ This is *not* an error. All we want to do is free
+ the memory we just allocated for the name and continue. */
+ xfree (name);
+ }
+ else
+ {
+ /* symbol value should be the offset of the
+ last instruction of the function */
+ symbolP = symbol_new (name, now_seg, (valueT) (frag_now_fix () - 4),
+ frag_now);
+
+ assert (symbolP);
+ symbolP->bsym->flags = BSF_LOCAL;
+ symbol_table_insert (symbolP);
+ }
+
+ if (symbolP)
+ last_call_info->end_symbol = symbolP;
+ else
+ as_bad (_("Symbol '%s' could not be created."), name);
+
+ }
+ else
+ as_bad (_("No memory for symbol name."));
+
+}
+
+/* For ELF, this function serves one purpose: to setup the st_size
+ field of STT_FUNC symbols. To do this, we need to scan the
+ call_info structure list, determining st_size in by taking the
+ difference in the address of the beginning/end marker symbols. */
+
+void
+elf_hppa_final_processing ()
+{
+ struct call_info *call_info_pointer;
+
+ for (call_info_pointer = call_info_root;
+ call_info_pointer;
+ call_info_pointer = call_info_pointer->ci_next)
+ {
+ elf_symbol_type *esym
+ = (elf_symbol_type *) call_info_pointer->start_symbol->bsym;
+ esym->internal_elf_sym.st_size =
+ S_GET_VALUE (call_info_pointer->end_symbol)
+ - S_GET_VALUE (call_info_pointer->start_symbol) + 4;
+ }
+}
+#endif
diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h
new file mode 100644
index 00000000000..c1541d9373f
--- /dev/null
+++ b/gas/config/tc-hppa.h
@@ -0,0 +1,162 @@
+/* tc-hppa.h -- Header file for the PA
+ Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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 1, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+/* HP PA-RISC support was contributed by the Center for Software Science
+ at the University of Utah. */
+
+/* Please refrain from exposing the world to the internals of tc-hppa.c
+ when this file is included. This means only declaring exported functions,
+ (please PARAMize them!) not exporting structures and data items which
+ are used solely within tc-hppa.c, etc.
+
+ Also refrain from adding any more object file dependent code, there is
+ already far too much object file format dependent code in this file.
+ In theory this file should contain only exported functions, structures
+ and data declarations common to all PA assemblers. */
+
+#ifndef _TC_HPPA_H
+#define _TC_HPPA_H
+
+#ifndef TC_HPPA
+#define TC_HPPA 1
+#endif
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define TARGET_ARCH bfd_arch_hppa
+
+#define WORKING_DOT_WORD
+
+/* FIXME. The lack of a place to put things which are both target cpu
+ and target format dependent makes hacks like this necessary. */
+#ifdef OBJ_ELF
+#include "bfd/elf32-hppa.h"
+#define TARGET_FORMAT "elf32-hppa"
+#endif
+
+#ifdef OBJ_SOM
+#include "bfd/som.h"
+#define TARGET_FORMAT "som"
+#endif
+
+/* FIXME. Why oh why aren't these defined somewhere globally? */
+#ifndef FALSE
+#define FALSE (0)
+#define TRUE (!FALSE)
+#endif
+
+#define ASEC_NULL (asection *)0
+
+/* Labels are not required to have a colon for a suffix. */
+#define LABELS_WITHOUT_COLONS
+
+/* FIXME. This should be static and declared in tc-hppa.c, but
+ pa_define_label gets used outside of tc-hppa.c via tc_frob_label.
+ Should also be PARAMized, but symbolS isn't available here. */
+extern void pa_define_label ();
+
+/* FIXME. Types not available here, so they can't be PARAMized. */
+extern void parse_cons_expression_hppa ();
+extern void cons_fix_new_hppa ();
+extern int hppa_force_relocation ();
+
+/* This gets called before writing the object file to make sure
+ things like entry/exit and proc/procend pairs match. */
+extern void pa_check_eof PARAMS ((void));
+#define tc_frob_file pa_check_eof
+
+#define tc_frob_label(sym) pa_define_label (sym)
+
+/* The PA does not need support for either of these. */
+#define tc_crawl_symbol_chain(headers) {;}
+#define tc_headers_hook(headers) {;}
+
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 6
+
+/* FIXME. More things which are both HPPA and ELF specific. There is
+ nowhere to put such things. */
+#ifdef OBJ_ELF
+#define elf_tc_final_processing elf_hppa_final_processing
+void elf_hppa_final_processing PARAMS ((void));
+#endif
+
+/* The PA needs to parse field selectors in .byte, etc. */
+
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+ parse_cons_expression_hppa (EXP)
+#define TC_CONS_FIX_NEW cons_fix_new_hppa
+
+/* On the PA, an equal sign often appears as a condition or nullification
+ completer in an instruction. This can be detected by checking the
+ previous character, if the character is a comma, then the equal is
+ being used as part of an instruction. */
+#define TC_EQUAL_IN_INSN(C, PTR) ((C) == ',')
+
+/* Similarly for an exclamation point. It is used in FP comparison
+ instructions and as an end of line marker. When used in an instruction
+ it will always follow a comma. */
+#define TC_EOL_IN_INSN(PTR) (*(PTR) == '!' && (PTR)[-1] == ',')
+
+#define tc_fix_adjustable hppa_fix_adjustable
+
+/* Because of the strange PA calling conventions, it is sometimes
+ necessary to emit a relocation for a call even though it would
+ normally appear safe to handle it completely within GAS. */
+#define TC_FORCE_RELOCATION(FIXP) hppa_force_relocation (FIXP)
+
+#ifdef OBJ_SOM
+/* If a symbol is imported, but never used, then the symbol should
+ *not* end up in the symbol table. Likewise for absolute symbols
+ with local scope. */
+#define tc_frob_symbol(sym,punt) \
+ if ((S_GET_SEGMENT (sym) == &bfd_und_section && sym->sy_used == 0) \
+ || (S_GET_SEGMENT (sym) == &bfd_abs_section \
+ && (sym->bsym->flags & BSF_EXPORT) == 0)) \
+ punt = 1
+
+/* We need to be able to make relocations involving the difference of
+ two symbols. This includes the difference of two symbols when
+ one of them is undefined (this comes up in PIC code generation).
+
+ We don't define DIFF_EXPR_OK because it does the wrong thing if
+ the add symbol is undefined and the sub symbol is a symbol in
+ the same section as the relocation. We also need some way to
+ specialize some code in adjust_reloc_syms. */
+#define UNDEFINED_DIFFERENCE_OK
+#endif
+
+#ifdef OBJ_ELF
+#define tc_frob_symbol(sym,punt) \
+ { \
+ if ((S_GET_SEGMENT (sym) == &bfd_und_section && sym->sy_used == 0) \
+ || (S_GET_SEGMENT (sym) == &bfd_abs_section \
+ && (sym->bsym->flags & BSF_EXPORT) == 0)) \
+ punt = 1; \
+ }
+#endif
+
+#define md_operand(x)
+
+#define TC_FIX_TYPE PTR
+#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL)
+
+#endif /* _TC_HPPA_H */
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
new file mode 100644
index 00000000000..7149d711b93
--- /dev/null
+++ b/gas/config/tc-i386.c
@@ -0,0 +1,4475 @@
+/* i386.c -- Assemble code for the Intel 80386
+ Copyright (C) 1989, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ Intel 80386 machine specific gas.
+ Written by Eliot Dresselhaus (eliot@mgm.mit.edu).
+ Bugs & suggestions are completely welcome. This is free software.
+ Please help us make it better.
+ */
+
+#include <ctype.h>
+
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/i386.h"
+
+#ifndef TC_RELOC
+#define TC_RELOC(X,Y) (Y)
+#endif
+
+#ifndef REGISTER_WARNINGS
+#define REGISTER_WARNINGS 1
+#endif
+
+#ifndef SCALE1_WHEN_NO_INDEX
+/* Specifying a scale factor besides 1 when there is no index is
+ futile. eg. `mov (%ebx,2),%al' does exactly the same as
+ `mov (%ebx),%al'. To slavishly follow what the programmer
+ specified, set SCALE1_WHEN_NO_INDEX to 0. */
+#define SCALE1_WHEN_NO_INDEX 1
+#endif
+
+#define true 1
+#define false 0
+
+static unsigned int mode_from_disp_size PARAMS ((unsigned int));
+static int fits_in_signed_byte PARAMS ((long));
+static int fits_in_unsigned_byte PARAMS ((long));
+static int fits_in_unsigned_word PARAMS ((long));
+static int fits_in_signed_word PARAMS ((long));
+static int smallest_imm_type PARAMS ((long));
+static int add_prefix PARAMS ((unsigned int));
+static void set_16bit_code_flag PARAMS ((int));
+static void set_intel_syntax PARAMS ((int));
+
+#ifdef BFD_ASSEMBLER
+static bfd_reloc_code_real_type reloc
+ PARAMS ((int, int, bfd_reloc_code_real_type));
+#endif
+
+/* 'md_assemble ()' gathers together information and puts it into a
+ i386_insn. */
+
+struct _i386_insn
+ {
+ /* TM holds the template for the insn were currently assembling. */
+ template tm;
+
+ /* SUFFIX holds the instruction mnemonic suffix if given.
+ (e.g. 'l' for 'movl') */
+ char suffix;
+
+ /* Operands are coded with OPERANDS, TYPES, DISPS, IMMS, and REGS. */
+
+ /* OPERANDS gives the number of given operands. */
+ unsigned int operands;
+
+ /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number
+ of given register, displacement, memory operands and immediate
+ operands. */
+ unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
+
+ /* TYPES [i] is the type (see above #defines) which tells us how to
+ search through DISPS [i] & IMMS [i] & REGS [i] for the required
+ operand. */
+ unsigned int types[MAX_OPERANDS];
+
+ /* Displacements (if given) for each operand. */
+ expressionS *disps[MAX_OPERANDS];
+
+ /* Relocation type for operand */
+#ifdef BFD_ASSEMBLER
+ enum bfd_reloc_code_real disp_reloc[MAX_OPERANDS];
+#else
+ int disp_reloc[MAX_OPERANDS];
+#endif
+
+ /* Immediate operands (if given) for each operand. */
+ expressionS *imms[MAX_OPERANDS];
+
+ /* Register operands (if given) for each operand. */
+ const reg_entry *regs[MAX_OPERANDS];
+
+ /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
+ the base index byte below. */
+ const reg_entry *base_reg;
+ const reg_entry *index_reg;
+ unsigned int log2_scale_factor;
+
+ /* SEG gives the seg_entries of this insn. They are zero unless
+ explicit segment overrides are given. */
+ const seg_entry *seg[2]; /* segments for memory operands (if given) */
+
+ /* PREFIX holds all the given prefix opcodes (usually null).
+ PREFIXES is the number of prefix opcodes. */
+ unsigned int prefixes;
+ unsigned char prefix[MAX_PREFIXES];
+
+ /* RM and SIB are the modrm byte and the sib byte where the
+ addressing modes of this insn are encoded. */
+
+ modrm_byte rm;
+ sib_byte sib;
+ };
+
+typedef struct _i386_insn i386_insn;
+
+/* List of chars besides those in app.c:symbol_chars that can start an
+ operand. Used to prevent the scrubber eating vital white-space. */
+#ifdef LEX_AT
+const char extra_symbol_chars[] = "*%-(@";
+#else
+const char extra_symbol_chars[] = "*%-(";
+#endif
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+#if defined (TE_I386AIX) || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && ! defined (TE_LINUX))
+/* Putting '/' here makes it impossible to use the divide operator.
+ However, we need it for compatibility with SVR4 systems. */
+const char comment_chars[] = "#/";
+#define PREFIX_SEPARATOR '\\'
+#else
+const char comment_chars[] = "#";
+#define PREFIX_SEPARATOR '/'
+#endif
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments started like this one will always work if
+ '/' isn't otherwise defined. */
+#if defined (TE_I386AIX) || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && ! defined (TE_LINUX))
+const char line_comment_chars[] = "";
+#else
+const char line_comment_chars[] = "/";
+#endif
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "fFdDxX";
+
+/* tables for lexical analysis */
+static char mnemonic_chars[256];
+static char register_chars[256];
+static char operand_chars[256];
+static char identifier_chars[256];
+static char digit_chars[256];
+
+/* lexical macros */
+#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x])
+#define is_operand_char(x) (operand_chars[(unsigned char) x])
+#define is_register_char(x) (register_chars[(unsigned char) x])
+#define is_space_char(x) ((x) == ' ')
+#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
+#define is_digit_char(x) (digit_chars[(unsigned char) x])
+
+/* put here all non-digit non-letter charcters that may occur in an operand */
+static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]";
+
+/* md_assemble() always leaves the strings it's passed unaltered. To
+ effect this we maintain a stack of saved characters that we've smashed
+ with '\0's (indicating end of strings for various sub-fields of the
+ assembler instruction). */
+static char save_stack[32];
+static char *save_stack_p; /* stack pointer */
+#define END_STRING_AND_SAVE(s) \
+ do { *save_stack_p++ = *(s); *(s) = '\0'; } while (0)
+#define RESTORE_END_STRING(s) \
+ do { *(s) = *--save_stack_p; } while (0)
+
+/* The instruction we're assembling. */
+static i386_insn i;
+
+/* Possible templates for current insn. */
+static const templates *current_templates;
+
+/* Per instruction expressionS buffers: 2 displacements & 2 immediate max. */
+static expressionS disp_expressions[2], im_expressions[2];
+
+static int this_operand; /* current operand we are working on */
+
+static int flag_do_long_jump; /* FIXME what does this do? */
+
+static int flag_16bit_code; /* 1 if we're writing 16-bit code, 0 if 32-bit */
+
+static int intel_syntax = 0; /* 1 for intel syntax, 0 if att syntax */
+
+static int allow_naked_reg = 0; /* 1 if register prefix % not required */
+
+/* Interface to relax_segment.
+ There are 2 relax states for 386 jump insns: one for conditional &
+ one for unconditional jumps. This is because the these two types
+ of jumps add different sizes to frags when we're figuring out what
+ sort of jump to choose to reach a given label. */
+
+/* types */
+#define COND_JUMP 1 /* conditional jump */
+#define UNCOND_JUMP 2 /* unconditional jump */
+/* sizes */
+#define CODE16 1
+#define SMALL 0
+#define SMALL16 (SMALL|CODE16)
+#define BIG 2
+#define BIG16 (BIG|CODE16)
+
+#ifndef INLINE
+#ifdef __GNUC__
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+#define ENCODE_RELAX_STATE(type,size) \
+ ((relax_substateT)((type<<2) | (size)))
+#define SIZE_FROM_RELAX_STATE(s) \
+ ( (((s) & 0x3) == BIG ? 4 : (((s) & 0x3) == BIG16 ? 2 : 1)) )
+
+/* This table is used by relax_frag to promote short jumps to long
+ ones where necessary. SMALL (short) jumps may be promoted to BIG
+ (32 bit long) ones, and SMALL16 jumps to BIG16 (16 bit long). We
+ don't allow a short jump in a 32 bit code segment to be promoted to
+ a 16 bit offset jump because it's slower (requires data size
+ prefix), and doesn't work, unless the destination is in the bottom
+ 64k of the code segment (The top 16 bits of eip are zeroed). */
+
+const relax_typeS md_relax_table[] =
+{
+/* The fields are:
+ 1) most positive reach of this state,
+ 2) most negative reach of this state,
+ 3) how many bytes this mode will add to the size of the current frag
+ 4) which index into the table to try if we can't fit into this one.
+ */
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+
+ {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
+ {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
+ /* dword conditionals adds 4 bytes to frag:
+ 1 extra opcode byte, 3 extra displacement bytes. */
+ {0, 0, 4, 0},
+ /* word conditionals add 2 bytes to frag:
+ 1 extra opcode byte, 1 extra displacement byte. */
+ {0, 0, 2, 0},
+
+ {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
+ {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
+ /* dword jmp adds 3 bytes to frag:
+ 0 extra opcode bytes, 3 extra displacement bytes. */
+ {0, 0, 3, 0},
+ /* word jmp adds 1 byte to frag:
+ 0 extra opcode bytes, 1 extra displacement byte. */
+ {0, 0, 1, 0}
+
+};
+
+
+void
+i386_align_code (fragP, count)
+ fragS *fragP;
+ int count;
+{
+ /* Various efficient no-op patterns for aligning code labels. */
+ /* Note: Don't try to assemble the instructions in the comments. */
+ /* 0L and 0w are not legal */
+ static const char f32_1[] =
+ {0x90}; /* nop */
+ static const char f32_2[] =
+ {0x89,0xf6}; /* movl %esi,%esi */
+ static const char f32_3[] =
+ {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */
+ static const char f32_4[] =
+ {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
+ static const char f32_5[] =
+ {0x90, /* nop */
+ 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
+ static const char f32_6[] =
+ {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */
+ static const char f32_7[] =
+ {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
+ static const char f32_8[] =
+ {0x90, /* nop */
+ 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
+ static const char f32_9[] =
+ {0x89,0xf6, /* movl %esi,%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_10[] =
+ {0x8d,0x76,0x00, /* leal 0(%esi),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_11[] =
+ {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_12[] =
+ {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
+ 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */
+ static const char f32_13[] =
+ {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_14[] =
+ {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */
+ 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
+ static const char f32_15[] =
+ {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
+ static const char f16_4[] =
+ {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
+ static const char f16_5[] =
+ {0x90, /* nop */
+ 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */
+ static const char f16_6[] =
+ {0x89,0xf6, /* mov %si,%si */
+ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
+ static const char f16_7[] =
+ {0x8d,0x74,0x00, /* lea 0(%si),%si */
+ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
+ static const char f16_8[] =
+ {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */
+ 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */
+ static const char *const f32_patt[] = {
+ f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
+ f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
+ };
+ static const char *const f16_patt[] = {
+ f32_1, f32_2, f32_3, f16_4, f16_5, f16_6, f16_7, f16_8,
+ f32_15, f32_15, f32_15, f32_15, f32_15, f32_15, f32_15
+ };
+
+ if (count > 0 && count <= 15)
+ {
+ if (flag_16bit_code)
+ {
+ memcpy(fragP->fr_literal + fragP->fr_fix,
+ f16_patt[count - 1], count);
+ if (count > 8) /* adjust jump offset */
+ fragP->fr_literal[fragP->fr_fix + 1] = count - 2;
+ }
+ else
+ memcpy(fragP->fr_literal + fragP->fr_fix,
+ f32_patt[count - 1], count);
+ fragP->fr_var = count;
+ }
+}
+
+static char *output_invalid PARAMS ((int c));
+static int i386_operand PARAMS ((char *operand_string));
+static int i386_intel_operand PARAMS ((char *operand_string, int got_a_float));
+static const reg_entry *parse_register PARAMS ((char *reg_string,
+ char **end_op));
+
+#ifndef I386COFF
+static void s_bss PARAMS ((int));
+#endif
+
+symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
+
+static INLINE unsigned int
+mode_from_disp_size (t)
+ unsigned int t;
+{
+ return (t & Disp8) ? 1 : (t & (Disp16|Disp32)) ? 2 : 0;
+}
+
+static INLINE int
+fits_in_signed_byte (num)
+ long num;
+{
+ return (num >= -128) && (num <= 127);
+} /* fits_in_signed_byte() */
+
+static INLINE int
+fits_in_unsigned_byte (num)
+ long num;
+{
+ return (num & 0xff) == num;
+} /* fits_in_unsigned_byte() */
+
+static INLINE int
+fits_in_unsigned_word (num)
+ long num;
+{
+ return (num & 0xffff) == num;
+} /* fits_in_unsigned_word() */
+
+static INLINE int
+fits_in_signed_word (num)
+ long num;
+{
+ return (-32768 <= num) && (num <= 32767);
+} /* fits_in_signed_word() */
+
+static int
+smallest_imm_type (num)
+ long num;
+{
+#if 0
+ /* This code is disabled because all the Imm1 forms in the opcode table
+ are slower on the i486, and they're the versions with the implicitly
+ specified single-position displacement, which has another syntax if
+ you really want to use that form. If you really prefer to have the
+ one-byte-shorter Imm1 form despite these problems, re-enable this
+ code. */
+ if (num == 1)
+ return Imm1 | Imm8 | Imm8S | Imm16 | Imm32;
+#endif
+ return (fits_in_signed_byte (num)
+ ? (Imm8S | Imm8 | Imm16 | Imm32)
+ : fits_in_unsigned_byte (num)
+ ? (Imm8 | Imm16 | Imm32)
+ : (fits_in_signed_word (num) || fits_in_unsigned_word (num))
+ ? (Imm16 | Imm32)
+ : (Imm32));
+} /* smallest_imm_type() */
+
+/* Returns 0 if attempting to add a prefix where one from the same
+ class already exists, 1 if non rep/repne added, 2 if rep/repne
+ added. */
+static int
+add_prefix (prefix)
+ unsigned int prefix;
+{
+ int ret = 1;
+ int q;
+
+ switch (prefix)
+ {
+ default:
+ abort ();
+
+ case CS_PREFIX_OPCODE:
+ case DS_PREFIX_OPCODE:
+ case ES_PREFIX_OPCODE:
+ case FS_PREFIX_OPCODE:
+ case GS_PREFIX_OPCODE:
+ case SS_PREFIX_OPCODE:
+ q = SEG_PREFIX;
+ break;
+
+ case REPNE_PREFIX_OPCODE:
+ case REPE_PREFIX_OPCODE:
+ ret = 2;
+ /* fall thru */
+ case LOCK_PREFIX_OPCODE:
+ q = LOCKREP_PREFIX;
+ break;
+
+ case FWAIT_OPCODE:
+ q = WAIT_PREFIX;
+ break;
+
+ case ADDR_PREFIX_OPCODE:
+ q = ADDR_PREFIX;
+ break;
+
+ case DATA_PREFIX_OPCODE:
+ q = DATA_PREFIX;
+ break;
+ }
+
+ if (i.prefix[q])
+ {
+ as_bad (_("same type of prefix used twice"));
+ return 0;
+ }
+
+ i.prefixes += 1;
+ i.prefix[q] = prefix;
+ return ret;
+}
+
+static void
+set_16bit_code_flag (new_16bit_code_flag)
+ int new_16bit_code_flag;
+{
+ flag_16bit_code = new_16bit_code_flag;
+}
+
+static void
+set_intel_syntax (syntax_flag)
+ int syntax_flag;
+{
+ /* Find out if register prefixing is specified. */
+ int ask_naked_reg = 0;
+
+ SKIP_WHITESPACE ();
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *string = input_line_pointer;
+ int e = get_symbol_end ();
+
+ if (strcmp(string, "prefix") == 0)
+ ask_naked_reg = 1;
+ else if (strcmp(string, "noprefix") == 0)
+ ask_naked_reg = -1;
+ else
+ as_bad (_("Bad argument to syntax directive."));
+ *input_line_pointer = e;
+ }
+ demand_empty_rest_of_line ();
+
+ intel_syntax = syntax_flag;
+
+ if (ask_naked_reg == 0)
+ {
+#ifdef BFD_ASSEMBLER
+ allow_naked_reg = (intel_syntax
+ && (bfd_get_symbol_leading_char (stdoutput) != '\0'));
+#else
+ allow_naked_reg = 0; /* conservative default */
+#endif
+ }
+ else
+ allow_naked_reg = (ask_naked_reg < 0);
+}
+
+const pseudo_typeS md_pseudo_table[] =
+{
+#ifndef I386COFF
+ {"bss", s_bss, 0},
+#endif
+#if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO)
+ {"align", s_align_bytes, 0},
+#else
+ {"align", s_align_ptwo, 0},
+#endif
+ {"ffloat", float_cons, 'f'},
+ {"dfloat", float_cons, 'd'},
+ {"tfloat", float_cons, 'x'},
+ {"value", cons, 2},
+ {"noopt", s_ignore, 0},
+ {"optim", s_ignore, 0},
+ {"code16", set_16bit_code_flag, 1},
+ {"code32", set_16bit_code_flag, 0},
+ {"intel_syntax", set_intel_syntax, 1},
+ {"att_syntax", set_intel_syntax, 0},
+ {0, 0, 0}
+};
+
+/* for interface with expression () */
+extern char *input_line_pointer;
+
+/* hash table for instruction mnemonic lookup */
+static struct hash_control *op_hash;
+/* hash table for register lookup */
+static struct hash_control *reg_hash;
+
+
+void
+md_begin ()
+{
+ const char *hash_err;
+
+ /* initialize op_hash hash table */
+ op_hash = hash_new ();
+
+ {
+ register const template *optab;
+ register templates *core_optab;
+
+ optab = i386_optab; /* setup for loop */
+ core_optab = (templates *) xmalloc (sizeof (templates));
+ core_optab->start = optab;
+
+ while (1)
+ {
+ ++optab;
+ if (optab->name == NULL
+ || strcmp (optab->name, (optab - 1)->name) != 0)
+ {
+ /* different name --> ship out current template list;
+ add to hash table; & begin anew */
+ core_optab->end = optab;
+ hash_err = hash_insert (op_hash,
+ (optab - 1)->name,
+ (PTR) core_optab);
+ if (hash_err)
+ {
+ hash_error:
+ as_fatal (_("Internal Error: Can't hash %s: %s"),
+ (optab - 1)->name,
+ hash_err);
+ }
+ if (optab->name == NULL)
+ break;
+ core_optab = (templates *) xmalloc (sizeof (templates));
+ core_optab->start = optab;
+ }
+ }
+ }
+
+ /* initialize reg_hash hash table */
+ reg_hash = hash_new ();
+ {
+ register const reg_entry *regtab;
+
+ for (regtab = i386_regtab;
+ regtab < i386_regtab + sizeof (i386_regtab) / sizeof (i386_regtab[0]);
+ regtab++)
+ {
+ hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab);
+ if (hash_err)
+ goto hash_error;
+ }
+ }
+
+ /* fill in lexical tables: mnemonic_chars, operand_chars. */
+ {
+ register int c;
+ register char *p;
+
+ for (c = 0; c < 256; c++)
+ {
+ if (isdigit (c))
+ {
+ digit_chars[c] = c;
+ mnemonic_chars[c] = c;
+ register_chars[c] = c;
+ operand_chars[c] = c;
+ }
+ else if (islower (c))
+ {
+ mnemonic_chars[c] = c;
+ register_chars[c] = c;
+ operand_chars[c] = c;
+ }
+ else if (isupper (c))
+ {
+ mnemonic_chars[c] = tolower (c);
+ register_chars[c] = mnemonic_chars[c];
+ operand_chars[c] = c;
+ }
+
+ if (isalpha (c) || isdigit (c))
+ identifier_chars[c] = c;
+ else if (c >= 128)
+ {
+ identifier_chars[c] = c;
+ operand_chars[c] = c;
+ }
+ }
+
+#ifdef LEX_AT
+ identifier_chars['@'] = '@';
+#endif
+ register_chars[')'] = ')';
+ register_chars['('] = '(';
+ digit_chars['-'] = '-';
+ identifier_chars['_'] = '_';
+ identifier_chars['.'] = '.';
+
+ for (p = operand_special_chars; *p != '\0'; p++)
+ operand_chars[(unsigned char) *p] = *p;
+ }
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ record_alignment (text_section, 2);
+ record_alignment (data_section, 2);
+ record_alignment (bss_section, 2);
+ }
+#endif
+}
+
+void
+i386_print_statistics (file)
+ FILE *file;
+{
+ hash_print_statistics (file, "i386 opcode", op_hash);
+ hash_print_statistics (file, "i386 register", reg_hash);
+}
+
+
+#ifdef DEBUG386
+
+/* debugging routines for md_assemble */
+static void pi PARAMS ((char *, i386_insn *));
+static void pte PARAMS ((template *));
+static void pt PARAMS ((unsigned int));
+static void pe PARAMS ((expressionS *));
+static void ps PARAMS ((symbolS *));
+
+static void
+pi (line, x)
+ char *line;
+ i386_insn *x;
+{
+ register template *p;
+ int i;
+
+ fprintf (stdout, "%s: template ", line);
+ pte (&x->tm);
+ fprintf (stdout, " modrm: mode %x reg %x reg/mem %x",
+ x->rm.mode, x->rm.reg, x->rm.regmem);
+ fprintf (stdout, " base %x index %x scale %x\n",
+ x->bi.base, x->bi.index, x->bi.scale);
+ for (i = 0; i < x->operands; i++)
+ {
+ fprintf (stdout, " #%d: ", i + 1);
+ pt (x->types[i]);
+ fprintf (stdout, "\n");
+ if (x->types[i]
+ & (Reg | SReg2 | SReg3 | Control | Debug | Test | RegMMX))
+ fprintf (stdout, "%s\n", x->regs[i]->reg_name);
+ if (x->types[i] & Imm)
+ pe (x->imms[i]);
+ if (x->types[i] & Disp)
+ pe (x->disps[i]);
+ }
+}
+
+static void
+pte (t)
+ template *t;
+{
+ int i;
+ fprintf (stdout, " %d operands ", t->operands);
+ fprintf (stdout, "opcode %x ",
+ t->base_opcode);
+ if (t->extension_opcode != None)
+ fprintf (stdout, "ext %x ", t->extension_opcode);
+ if (t->opcode_modifier & D)
+ fprintf (stdout, "D");
+ if (t->opcode_modifier & W)
+ fprintf (stdout, "W");
+ fprintf (stdout, "\n");
+ for (i = 0; i < t->operands; i++)
+ {
+ fprintf (stdout, " #%d type ", i + 1);
+ pt (t->operand_types[i]);
+ fprintf (stdout, "\n");
+ }
+}
+
+static void
+pe (e)
+ expressionS *e;
+{
+ fprintf (stdout, " operation %d\n", e->X_op);
+ fprintf (stdout, " add_number %d (%x)\n",
+ e->X_add_number, e->X_add_number);
+ if (e->X_add_symbol)
+ {
+ fprintf (stdout, " add_symbol ");
+ ps (e->X_add_symbol);
+ fprintf (stdout, "\n");
+ }
+ if (e->X_op_symbol)
+ {
+ fprintf (stdout, " op_symbol ");
+ ps (e->X_op_symbol);
+ fprintf (stdout, "\n");
+ }
+}
+
+static void
+ps (s)
+ symbolS *s;
+{
+ fprintf (stdout, "%s type %s%s",
+ S_GET_NAME (s),
+ S_IS_EXTERNAL (s) ? "EXTERNAL " : "",
+ segment_name (S_GET_SEGMENT (s)));
+}
+
+struct type_name
+ {
+ unsigned int mask;
+ char *tname;
+ }
+
+type_names[] =
+{
+ { Reg8, "r8" },
+ { Reg16, "r16" },
+ { Reg32, "r32" },
+ { Imm8, "i8" },
+ { Imm8S, "i8s" },
+ { Imm16, "i16" },
+ { Imm32, "i32" },
+ { Imm1, "i1" },
+ { BaseIndex, "BaseIndex" },
+ { Disp8, "d8" },
+ { Disp16, "d16" },
+ { Disp32, "d32" },
+ { InOutPortReg, "InOutPortReg" },
+ { ShiftCount, "ShiftCount" },
+ { Control, "control reg" },
+ { Test, "test reg" },
+ { Debug, "debug reg" },
+ { FloatReg, "FReg" },
+ { FloatAcc, "FAcc" },
+ { SReg2, "SReg2" },
+ { SReg3, "SReg3" },
+ { Acc, "Acc" },
+ { JumpAbsolute, "Jump Absolute" },
+ { RegMMX, "rMMX" },
+ { EsSeg, "es" },
+ { 0, "" }
+};
+
+static void
+pt (t)
+ unsigned int t;
+{
+ register struct type_name *ty;
+
+ if (t == Unknown)
+ {
+ fprintf (stdout, _("Unknown"));
+ }
+ else
+ {
+ for (ty = type_names; ty->mask; ty++)
+ if (t & ty->mask)
+ fprintf (stdout, "%s, ", ty->tname);
+ }
+ fflush (stdout);
+}
+
+#endif /* DEBUG386 */
+
+int
+tc_i386_force_relocation (fixp)
+ struct fix *fixp;
+{
+#ifdef BFD_ASSEMBLER
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+ return 0;
+#else
+ /* For COFF */
+ return fixp->fx_r_type==7;
+#endif
+}
+
+#ifdef BFD_ASSEMBLER
+static bfd_reloc_code_real_type reloc
+ PARAMS ((int, int, bfd_reloc_code_real_type));
+
+static bfd_reloc_code_real_type
+reloc (size, pcrel, other)
+ int size;
+ int pcrel;
+ bfd_reloc_code_real_type other;
+{
+ if (other != NO_RELOC) return other;
+
+ if (pcrel)
+ {
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8_PCREL;
+ case 2: return BFD_RELOC_16_PCREL;
+ case 4: return BFD_RELOC_32_PCREL;
+ }
+ as_bad (_("Can not do %d byte pc-relative relocation"), size);
+ }
+ else
+ {
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8;
+ case 2: return BFD_RELOC_16;
+ case 4: return BFD_RELOC_32;
+ }
+ as_bad (_("Can not do %d byte relocation"), size);
+ }
+
+ return BFD_RELOC_NONE;
+}
+
+/*
+ * Here we decide which fixups can be adjusted to make them relative to
+ * the beginning of the section instead of the symbol. Basically we need
+ * to make sure that the dynamic relocations are done correctly, so in
+ * some cases we force the original symbol to be used.
+ */
+int
+tc_i386_fix_adjustable(fixP)
+ fixS * fixP;
+{
+#ifdef OBJ_ELF
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+#endif
+ /* adjust_reloc_syms doesn't know about the GOT */
+ if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
+ || fixP->fx_r_type == BFD_RELOC_386_PLT32
+ || fixP->fx_r_type == BFD_RELOC_386_GOT32
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+ return 1;
+}
+#else
+#define reloc(SIZE,PCREL,OTHER) 0
+#define BFD_RELOC_16 0
+#define BFD_RELOC_32 0
+#define BFD_RELOC_16_PCREL 0
+#define BFD_RELOC_32_PCREL 0
+#define BFD_RELOC_386_PLT32 0
+#define BFD_RELOC_386_GOT32 0
+#define BFD_RELOC_386_GOTOFF 0
+#endif
+
+int
+intel_float_operand (mnemonic)
+ char *mnemonic;
+{
+ if (mnemonic[0] == 'f' && mnemonic[1] =='i')
+ return 0;
+
+ if (mnemonic[0] == 'f')
+ return 1;
+
+ return 0;
+}
+
+/* This is the guts of the machine-dependent assembler. LINE points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to. */
+
+void
+md_assemble (line)
+ char *line;
+{
+ /* Points to template once we've found it. */
+ const template *t;
+
+ /* Count the size of the instruction generated. */
+ int insn_size = 0;
+
+ int j;
+
+ char mnemonic[MAX_MNEM_SIZE];
+
+ /* Initialize globals. */
+ memset (&i, '\0', sizeof (i));
+ for (j = 0; j < MAX_OPERANDS; j++)
+ i.disp_reloc[j] = NO_RELOC;
+ memset (disp_expressions, '\0', sizeof (disp_expressions));
+ memset (im_expressions, '\0', sizeof (im_expressions));
+ save_stack_p = save_stack; /* reset stack pointer */
+
+ /* First parse an instruction mnemonic & call i386_operand for the operands.
+ We assume that the scrubber has arranged it so that line[0] is the valid
+ start of a (possibly prefixed) mnemonic. */
+ {
+ char *l = line;
+ char *token_start = l;
+ char *mnem_p;
+
+ /* Non-zero if we found a prefix only acceptable with string insns. */
+ const char *expecting_string_instruction = NULL;
+
+ while (1)
+ {
+ mnem_p = mnemonic;
+ while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
+ {
+ mnem_p++;
+ if (mnem_p >= mnemonic + sizeof (mnemonic))
+ {
+ as_bad (_("no such 386 instruction: `%s'"), token_start);
+ return;
+ }
+ l++;
+ }
+ if (!is_space_char (*l)
+ && *l != END_OF_INSN
+ && *l != PREFIX_SEPARATOR)
+ {
+ as_bad (_("invalid character %s in mnemonic"),
+ output_invalid (*l));
+ return;
+ }
+ if (token_start == l)
+ {
+ if (*l == PREFIX_SEPARATOR)
+ as_bad (_("expecting prefix; got nothing"));
+ else
+ as_bad (_("expecting mnemonic; got nothing"));
+ return;
+ }
+
+ /* Look up instruction (or prefix) via hash table. */
+ current_templates = hash_find (op_hash, mnemonic);
+
+ if (*l != END_OF_INSN
+ && (! is_space_char (*l) || l[1] != END_OF_INSN)
+ && current_templates
+ && (current_templates->start->opcode_modifier & IsPrefix))
+ {
+ /* If we are in 16-bit mode, do not allow addr16 or data16.
+ Similarly, in 32-bit mode, do not allow addr32 or data32. */
+ if ((current_templates->start->opcode_modifier & (Size16 | Size32))
+ && (((current_templates->start->opcode_modifier & Size32) != 0)
+ ^ flag_16bit_code))
+ {
+ as_bad (_("redundant %s prefix"),
+ current_templates->start->name);
+ return;
+ }
+ /* Add prefix, checking for repeated prefixes. */
+ switch (add_prefix (current_templates->start->base_opcode))
+ {
+ case 0:
+ return;
+ case 2:
+ expecting_string_instruction =
+ current_templates->start->name;
+ break;
+ }
+ /* Skip past PREFIX_SEPARATOR and reset token_start. */
+ token_start = ++l;
+ }
+ else
+ break;
+ }
+
+ if (!current_templates)
+ {
+ /* See if we can get a match by trimming off a suffix. */
+ switch (mnem_p[-1])
+ {
+ case DWORD_MNEM_SUFFIX:
+ case WORD_MNEM_SUFFIX:
+ case BYTE_MNEM_SUFFIX:
+ case SHORT_MNEM_SUFFIX:
+#if LONG_MNEM_SUFFIX != DWORD_MNEM_SUFFIX
+ case LONG_MNEM_SUFFIX:
+#endif
+ i.suffix = mnem_p[-1];
+ mnem_p[-1] = '\0';
+ current_templates = hash_find (op_hash, mnemonic);
+ break;
+
+ /* Intel Syntax */
+ case INTEL_DWORD_MNEM_SUFFIX:
+ if (intel_syntax)
+ {
+ i.suffix = mnem_p[-1];
+ mnem_p[-1] = '\0';
+ current_templates = hash_find (op_hash, mnemonic);
+ break;
+ }
+ }
+ if (!current_templates)
+ {
+ as_bad (_("no such 386 instruction: `%s'"), token_start);
+ return;
+ }
+ }
+
+ /* check for rep/repne without a string instruction */
+ if (expecting_string_instruction
+ && !(current_templates->start->opcode_modifier & IsString))
+ {
+ as_bad (_("expecting string instruction after `%s'"),
+ expecting_string_instruction);
+ return;
+ }
+
+ /* There may be operands to parse. */
+ if (*l != END_OF_INSN)
+ {
+ /* parse operands */
+
+ /* 1 if operand is pending after ','. */
+ unsigned int expecting_operand = 0;
+
+ /* Non-zero if operand parens not balanced. */
+ unsigned int paren_not_balanced;
+
+ do
+ {
+ /* skip optional white space before operand */
+ if (is_space_char (*l))
+ ++l;
+ if (!is_operand_char (*l) && *l != END_OF_INSN)
+ {
+ as_bad (_("invalid character %s before operand %d"),
+ output_invalid (*l),
+ i.operands + 1);
+ return;
+ }
+ token_start = l; /* after white space */
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *l != ',')
+ {
+ if (*l == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ if (!intel_syntax)
+ as_bad (_("unbalanced parenthesis in operand %d."),
+ i.operands + 1);
+ else
+ as_bad (_("unbalanced brackets in operand %d."),
+ i.operands + 1);
+ return;
+ }
+ else
+ break; /* we are done */
+ }
+ else if (!is_operand_char (*l) && !is_space_char (*l))
+ {
+ as_bad (_("invalid character %s in operand %d"),
+ output_invalid (*l),
+ i.operands + 1);
+ return;
+ }
+ if (!intel_syntax)
+ {
+ if (*l == '(')
+ ++paren_not_balanced;
+ if (*l == ')')
+ --paren_not_balanced;
+ }
+ else
+ {
+ if (*l == '[')
+ ++paren_not_balanced;
+ if (*l == ']')
+ --paren_not_balanced;
+ }
+ l++;
+ }
+ if (l != token_start)
+ { /* yes, we've read in another operand */
+ unsigned int operand_ok;
+ this_operand = i.operands++;
+ if (i.operands > MAX_OPERANDS)
+ {
+ as_bad (_("spurious operands; (%d operands/instruction max)"),
+ MAX_OPERANDS);
+ return;
+ }
+ /* now parse operand adding info to 'i' as we go along */
+ END_STRING_AND_SAVE (l);
+
+ if (intel_syntax)
+ operand_ok = i386_intel_operand (token_start, intel_float_operand (mnemonic));
+ else
+ operand_ok = i386_operand (token_start);
+
+ RESTORE_END_STRING (l); /* restore old contents */
+ if (!operand_ok)
+ return;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ expecting_operand_after_comma:
+ as_bad (_("expecting operand after ','; got nothing"));
+ return;
+ }
+ if (*l == ',')
+ {
+ as_bad (_("expecting operand before ','; got nothing"));
+ return;
+ }
+ }
+
+ /* now *l must be either ',' or END_OF_INSN */
+ if (*l == ',')
+ {
+ if (*++l == END_OF_INSN)
+ { /* just skip it, if it's \n complain */
+ goto expecting_operand_after_comma;
+ }
+ expecting_operand = 1;
+ }
+ }
+ while (*l != END_OF_INSN); /* until we get end of insn */
+ }
+ }
+
+ /* Now we've parsed the mnemonic into a set of templates, and have the
+ operands at hand.
+
+ Next, we find a template that matches the given insn,
+ making sure the overlap of the given operands types is consistent
+ with the template operand types. */
+
+#define MATCH(overlap, given, template) \
+ ((overlap) \
+ && ((given) & BaseIndex) == ((overlap) & BaseIndex) \
+ && ((given) & JumpAbsolute) == ((template) & JumpAbsolute))
+
+ /* If given types r0 and r1 are registers they must be of the same type
+ unless the expected operand type register overlap is null.
+ Note that Acc in a template matches every size of reg. */
+#define CONSISTENT_REGISTER_MATCH(m0, g0, t0, m1, g1, t1) \
+ ( ((g0) & Reg) == 0 || ((g1) & Reg) == 0 || \
+ ((g0) & Reg) == ((g1) & Reg) || \
+ ((((m0) & Acc) ? Reg : (t0)) & (((m1) & Acc) ? Reg : (t1)) & Reg) == 0 )
+
+ {
+ register unsigned int overlap0, overlap1;
+ expressionS *exp;
+ unsigned int overlap2;
+ unsigned int found_reverse_match;
+ int suffix_check;
+
+ /* All intel opcodes have reversed operands except for BOUND and ENTER */
+ if (intel_syntax
+ && (strcmp (mnemonic, "enter") != 0)
+ && (strcmp (mnemonic, "bound") != 0)
+ && (strncmp (mnemonic, "fsub", 4) !=0)
+ && (strncmp (mnemonic, "fdiv", 4) !=0))
+ {
+ const reg_entry *temp_reg;
+ expressionS *temp_disp;
+ expressionS *temp_imm;
+ unsigned int temp_type;
+ int xchg1, xchg2;
+
+ if (i.operands == 2)
+ {
+ xchg1 = 0;
+ xchg2 = 1;
+ }
+ else if (i.operands == 3)
+ {
+ xchg1 = 0;
+ xchg2 = 2;
+ }
+
+ if (i.operands > 1)
+ {
+ temp_type = i.types[xchg2];
+ if (temp_type & (Reg | FloatReg))
+ temp_reg = i.regs[xchg2];
+ else if (temp_type & Imm)
+ temp_imm = i.imms[xchg2];
+ else if (temp_type & Disp)
+ temp_disp = i.disps[xchg2];
+
+ i.types[xchg2] = i.types[xchg1];
+
+ if (i.types[xchg1] & (Reg | FloatReg))
+ {
+ i.regs[xchg2] = i.regs[xchg1];
+ i.regs[xchg1] = NULL;
+ }
+ else if (i.types[xchg2] & Imm)
+ {
+ i.imms[xchg2] = i.imms[xchg1];
+ i.imms[xchg1] = NULL;
+ }
+ else if (i.types[xchg2] & Disp)
+ {
+ i.disps[xchg2] = i.disps[xchg1];
+ i.disps[xchg1] = NULL;
+ }
+
+ if (temp_type & (Reg | FloatReg))
+ {
+ i.regs[xchg1] = temp_reg;
+ if (! (i.types[xchg1] & (Reg | FloatReg)))
+ i.regs[xchg2] = NULL;
+ }
+ else if (temp_type & Imm)
+ {
+ i.imms[xchg1] = temp_imm;
+ if (! (i.types[xchg1] & Imm))
+ i.imms[xchg2] = NULL;
+ }
+ else if (temp_type & Disp)
+ {
+ i.disps[xchg1] = temp_disp;
+ if (! (i.types[xchg1] & Disp))
+ i.disps[xchg2] = NULL;
+ }
+
+ i.types[xchg1] = temp_type;
+ }
+ if (!strcmp(mnemonic,"jmp")
+ || !strcmp (mnemonic, "call"))
+ if ((i.types[0] & Reg) || i.types[0] & BaseIndex)
+ i.types[0] |= JumpAbsolute;
+
+ }
+ overlap0 = 0;
+ overlap1 = 0;
+ overlap2 = 0;
+ found_reverse_match = 0;
+ suffix_check = (i.suffix == BYTE_MNEM_SUFFIX
+ ? No_bSuf
+ : (i.suffix == WORD_MNEM_SUFFIX
+ ? No_wSuf
+ : (i.suffix == SHORT_MNEM_SUFFIX
+ ? No_sSuf
+ : (i.suffix == LONG_MNEM_SUFFIX
+ ? No_lSuf
+ : (i.suffix == INTEL_DWORD_MNEM_SUFFIX
+ ? No_dSuf
+ : (i.suffix == LONG_DOUBLE_MNEM_SUFFIX ? No_xSuf : 0))))));
+
+ for (t = current_templates->start;
+ t < current_templates->end;
+ t++)
+ {
+ /* Must have right number of operands. */
+ if (i.operands != t->operands)
+ continue;
+
+ /* For some opcodes, don't check the suffix */
+ if (intel_syntax)
+ {
+ if (strcmp (t->name, "fnstcw")
+ && strcmp (t->name, "fldcw")
+ && (t->opcode_modifier & suffix_check))
+ continue;
+ }
+ /* Must not have disallowed suffix. */
+ else if ((t->opcode_modifier & suffix_check))
+ continue;
+
+ else if (!t->operands)
+ break; /* 0 operands always matches */
+
+ overlap0 = i.types[0] & t->operand_types[0];
+ switch (t->operands)
+ {
+ case 1:
+ if (!MATCH (overlap0, i.types[0], t->operand_types[0]))
+ continue;
+ break;
+ case 2:
+ case 3:
+ overlap1 = i.types[1] & t->operand_types[1];
+ if (!MATCH (overlap0, i.types[0], t->operand_types[0])
+ || !MATCH (overlap1, i.types[1], t->operand_types[1])
+ || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
+ t->operand_types[0],
+ overlap1, i.types[1],
+ t->operand_types[1]))
+ {
+
+ /* check if other direction is valid ... */
+ if ((t->opcode_modifier & (D|FloatD)) == 0)
+ continue;
+
+ /* try reversing direction of operands */
+ overlap0 = i.types[0] & t->operand_types[1];
+ overlap1 = i.types[1] & t->operand_types[0];
+ if (!MATCH (overlap0, i.types[0], t->operand_types[1])
+ || !MATCH (overlap1, i.types[1], t->operand_types[0])
+ || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0],
+ t->operand_types[1],
+ overlap1, i.types[1],
+ t->operand_types[0]))
+ {
+ /* does not match either direction */
+ continue;
+ }
+ /* found_reverse_match holds which of D or FloatDR
+ we've found. */
+ found_reverse_match = t->opcode_modifier & (D|FloatDR);
+ break;
+ }
+ /* found a forward 2 operand match here */
+ if (t->operands == 3)
+ {
+ /* Here we make use of the fact that there are no
+ reverse match 3 operand instructions, and all 3
+ operand instructions only need to be checked for
+ register consistency between operands 2 and 3. */
+ overlap2 = i.types[2] & t->operand_types[2];
+ if (!MATCH (overlap2, i.types[2], t->operand_types[2])
+ || !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1],
+ t->operand_types[1],
+ overlap2, i.types[2],
+ t->operand_types[2]))
+
+ continue;
+ }
+ /* found either forward/reverse 2 or 3 operand match here:
+ slip through to break */
+ }
+ break; /* we've found a match; break out of loop */
+ } /* for (t = ... */
+ if (t == current_templates->end)
+ { /* we found no match */
+ as_bad (_("suffix or operands invalid for `%s'"),
+ current_templates->start->name);
+ return;
+ }
+
+ if ((t->opcode_modifier & (IsPrefix|IgnoreSize)) == (IsPrefix|IgnoreSize))
+ {
+ /* Warn them that a data or address size prefix doesn't affect
+ assembly of the next line of code. */
+ as_warn (_("stand-alone `%s' prefix"), t->name);
+ }
+
+ /* Copy the template we found. */
+ i.tm = *t;
+ if (found_reverse_match)
+ {
+ i.tm.operand_types[0] = t->operand_types[1];
+ i.tm.operand_types[1] = t->operand_types[0];
+ }
+
+
+ if (i.tm.opcode_modifier & FWait)
+ if (! add_prefix (FWAIT_OPCODE))
+ return;
+
+ /* Check string instruction segment overrides */
+ if ((i.tm.opcode_modifier & IsString) != 0 && i.mem_operands != 0)
+ {
+ int mem_op = (i.types[0] & AnyMem) ? 0 : 1;
+ if ((i.tm.operand_types[mem_op] & EsSeg) != 0)
+ {
+ if (i.seg[0] != NULL && i.seg[0] != &es)
+ {
+ as_bad (_("`%s' operand %d must use `%%es' segment"),
+ i.tm.name,
+ mem_op + 1);
+ return;
+ }
+ /* There's only ever one segment override allowed per instruction.
+ This instruction possibly has a legal segment override on the
+ second operand, so copy the segment to where non-string
+ instructions store it, allowing common code. */
+ i.seg[0] = i.seg[1];
+ }
+ else if ((i.tm.operand_types[mem_op + 1] & EsSeg) != 0)
+ {
+ if (i.seg[1] != NULL && i.seg[1] != &es)
+ {
+ as_bad (_("`%s' operand %d must use `%%es' segment"),
+ i.tm.name,
+ mem_op + 2);
+ return;
+ }
+ }
+ }
+
+ /* If matched instruction specifies an explicit instruction mnemonic
+ suffix, use it. */
+ if (i.tm.opcode_modifier & (Size16 | Size32))
+ {
+ if (i.tm.opcode_modifier & Size16)
+ i.suffix = WORD_MNEM_SUFFIX;
+ else
+ i.suffix = DWORD_MNEM_SUFFIX;
+ }
+ else if (i.reg_operands)
+ {
+ /* If there's no instruction mnemonic suffix we try to invent one
+ based on register operands. */
+ if (!i.suffix)
+ {
+ /* We take i.suffix from the last register operand specified,
+ Destination register type is more significant than source
+ register type. */
+ int op;
+ for (op = i.operands; --op >= 0; )
+ if (i.types[op] & Reg)
+ {
+ i.suffix = ((i.types[op] & Reg8) ? BYTE_MNEM_SUFFIX :
+ (i.types[op] & Reg16) ? WORD_MNEM_SUFFIX :
+ DWORD_MNEM_SUFFIX);
+ break;
+ }
+ }
+ else if (i.suffix == BYTE_MNEM_SUFFIX)
+ {
+ int op;
+ for (op = i.operands; --op >= 0; )
+ {
+ /* If this is an eight bit register, it's OK. If it's
+ the 16 or 32 bit version of an eight bit register,
+ we will just use the low portion, and that's OK too. */
+ if (i.types[op] & Reg8)
+ continue;
+
+ /* movzx and movsx should not generate this warning. */
+ if (intel_syntax
+ && (i.tm.base_opcode == 0xfb7
+ || i.tm.base_opcode == 0xfb6
+ || i.tm.base_opcode == 0xfbe
+ || i.tm.base_opcode == 0xfbf))
+ continue;
+
+ if ((i.types[op] & WordReg) && i.regs[op]->reg_num < 4
+#if 0
+ /* Check that the template allows eight bit regs
+ This kills insns such as `orb $1,%edx', which
+ maybe should be allowed. */
+ && (i.tm.operand_types[op] & (Reg8|InOutPortReg))
+#endif
+ )
+ {
+#if REGISTER_WARNINGS
+ if ((i.tm.operand_types[op] & InOutPortReg) == 0)
+ as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
+ (i.regs[op] - (i.types[op] & Reg16 ? 8 : 16))->reg_name,
+ i.regs[op]->reg_name,
+ i.suffix);
+#endif
+ continue;
+ }
+ /* Any other register is bad */
+ if (i.types[op] & (Reg | RegMMX | Control | Debug | Test
+ | FloatReg | FloatAcc | SReg2 | SReg3))
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.regs[op]->reg_name,
+ i.tm.name,
+ i.suffix);
+ return;
+ }
+ }
+ }
+ else if (i.suffix == DWORD_MNEM_SUFFIX)
+ {
+ int op;
+ for (op = i.operands; --op >= 0; )
+ /* Reject eight bit registers, except where the template
+ requires them. (eg. movzb) */
+ if ((i.types[op] & Reg8) != 0
+ && (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0)
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.regs[op]->reg_name,
+ i.tm.name,
+ i.suffix);
+ return;
+ }
+#if REGISTER_WARNINGS
+ /* Warn if the e prefix on a general reg is missing. */
+ else if ((i.types[op] & Reg16) != 0
+ && (i.tm.operand_types[op] & (Reg32|Acc)) != 0)
+ {
+ as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
+ (i.regs[op] + 8)->reg_name,
+ i.regs[op]->reg_name,
+ i.suffix);
+ }
+#endif
+ }
+ else if (i.suffix == WORD_MNEM_SUFFIX)
+ {
+ int op;
+ for (op = i.operands; --op >= 0; )
+ /* Reject eight bit registers, except where the template
+ requires them. (eg. movzb) */
+ if ((i.types[op] & Reg8) != 0
+ && (i.tm.operand_types[op] & (Reg16|Reg32|Acc)) != 0)
+ {
+ as_bad (_("`%%%s' not allowed with `%s%c'"),
+ i.regs[op]->reg_name,
+ i.tm.name,
+ i.suffix);
+ return;
+ }
+#if REGISTER_WARNINGS
+ /* Warn if the e prefix on a general reg is present. */
+ else if ((i.types[op] & Reg32) != 0
+ && (i.tm.operand_types[op] & (Reg16|Acc)) != 0)
+ {
+ as_warn (_("using `%%%s' instead of `%%%s' due to `%c' suffix"),
+ (i.regs[op] - 8)->reg_name,
+ i.regs[op]->reg_name,
+ i.suffix);
+ }
+#endif
+ }
+ else
+ abort();
+ }
+
+ /* Make still unresolved immediate matches conform to size of immediate
+ given in i.suffix. Note: overlap2 cannot be an immediate! */
+ if ((overlap0 & (Imm8 | Imm8S | Imm16 | Imm32))
+ && overlap0 != Imm8 && overlap0 != Imm8S
+ && overlap0 != Imm16 && overlap0 != Imm32)
+ {
+ if (i.suffix)
+ {
+ overlap0 &= (i.suffix == BYTE_MNEM_SUFFIX ? (Imm8 | Imm8S) :
+ (i.suffix == WORD_MNEM_SUFFIX ? Imm16 : Imm32));
+ }
+ else if (overlap0 == (Imm16 | Imm32))
+ {
+ overlap0 =
+ (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0)) ? Imm16 : Imm32;
+ }
+ else
+ {
+ as_bad (_("no instruction mnemonic suffix given; can't determine immediate size"));
+ return;
+ }
+ }
+ if ((overlap1 & (Imm8 | Imm8S | Imm16 | Imm32))
+ && overlap1 != Imm8 && overlap1 != Imm8S
+ && overlap1 != Imm16 && overlap1 != Imm32)
+ {
+ if (i.suffix)
+ {
+ overlap1 &= (i.suffix == BYTE_MNEM_SUFFIX ? (Imm8 | Imm8S) :
+ (i.suffix == WORD_MNEM_SUFFIX ? Imm16 : Imm32));
+ }
+ else if (overlap1 == (Imm16 | Imm32))
+ {
+ overlap1 =
+ (flag_16bit_code ^ (i.prefix[DATA_PREFIX] != 0)) ? Imm16 : Imm32;
+ }
+ else
+ {
+ as_bad (_("no instruction mnemonic suffix given; can't determine immediate size"));
+ return;
+ }
+ }
+ assert ((overlap2 & Imm) == 0);
+
+ i.types[0] = overlap0;
+ if (overlap0 & ImplicitRegister)
+ i.reg_operands--;
+ if (overlap0 & Imm1)
+ i.imm_operands = 0; /* kludge for shift insns */
+
+ i.types[1] = overlap1;
+ if (overlap1 & ImplicitRegister)
+ i.reg_operands--;
+
+ i.types[2] = overlap2;
+ if (overlap2 & ImplicitRegister)
+ i.reg_operands--;
+
+ /* Finalize opcode. First, we change the opcode based on the operand
+ size given by i.suffix: We need not change things for byte insns. */
+
+ if (!i.suffix && (i.tm.opcode_modifier & W))
+ {
+ as_bad (_("no instruction mnemonic suffix given and no register operands; can't size instruction"));
+ return;
+ }
+
+ /* For movzx and movsx, need to check the register type */
+ if (intel_syntax
+ && (i.tm.base_opcode == 0xfb6 || i.tm.base_opcode == 0xfbe))
+ if (i.suffix && i.suffix == BYTE_MNEM_SUFFIX)
+ {
+ unsigned int prefix = DATA_PREFIX_OPCODE;
+
+ if ((i.regs[1]->reg_type & Reg16) != 0)
+ if (!add_prefix (prefix))
+ return;
+ }
+
+ if (i.suffix && i.suffix != BYTE_MNEM_SUFFIX)
+ {
+ /* It's not a byte, select word/dword operation. */
+ if (i.tm.opcode_modifier & W)
+ {
+ if (i.tm.opcode_modifier & ShortForm)
+ i.tm.base_opcode |= 8;
+ else
+ i.tm.base_opcode |= 1;
+ }
+ /* Now select between word & dword operations via the operand
+ size prefix, except for instructions that will ignore this
+ prefix anyway. */
+ if (((intel_syntax && (i.suffix == INTEL_DWORD_MNEM_SUFFIX))
+ || i.suffix == DWORD_MNEM_SUFFIX
+ || i.suffix == LONG_MNEM_SUFFIX) == flag_16bit_code
+ && !(i.tm.opcode_modifier & IgnoreSize))
+ {
+ unsigned int prefix = DATA_PREFIX_OPCODE;
+ if (i.tm.opcode_modifier & JumpByte) /* jcxz, loop */
+ prefix = ADDR_PREFIX_OPCODE;
+
+ if (! add_prefix (prefix))
+ return;
+ }
+ /* Size floating point instruction. */
+ if (i.suffix == LONG_MNEM_SUFFIX
+ || (intel_syntax && i.suffix == INTEL_DWORD_MNEM_SUFFIX))
+ {
+ if (i.tm.opcode_modifier & FloatMF)
+ i.tm.base_opcode ^= 4;
+ }
+
+ if (intel_syntax && i.suffix == LONG_DOUBLE_MNEM_SUFFIX)
+ {
+ if (i.tm.opcode_modifier & FloatMF)
+ i.tm.base_opcode ^= 2;
+ }
+ }
+
+ if (i.tm.base_opcode == AMD_3DNOW_OPCODE)
+ {
+ /* These AMD specific instructions have an opcode suffix which
+ is coded in the same place as an 8-bit immediate field
+ would be. Here we fake an 8-bit immediate operand from the
+ opcode suffix stored in tm.extension_opcode. */
+
+ expressionS *exp;
+
+ assert(i.imm_operands == 0 && i.operands <= 2);
+
+ exp = &im_expressions[i.imm_operands++];
+ i.imms[i.operands] = exp;
+ i.types[i.operands++] = Imm8;
+ exp->X_op = O_constant;
+ exp->X_add_number = i.tm.extension_opcode;
+ i.tm.extension_opcode = None;
+ }
+
+ /* For insns with operands there are more diddles to do to the opcode. */
+ if (i.operands)
+ {
+ /* Default segment register this instruction will use
+ for memory accesses. 0 means unknown.
+ This is only for optimizing out unnecessary segment overrides. */
+ const seg_entry *default_seg = 0;
+
+ /* If we found a reverse match we must alter the opcode
+ direction bit. found_reverse_match holds bits to change
+ (different for int & float insns). */
+
+ i.tm.base_opcode ^= found_reverse_match;
+
+ /* The imul $imm, %reg instruction is converted into
+ imul $imm, %reg, %reg, and the clr %reg instruction
+ is converted into xor %reg, %reg. */
+ if (i.tm.opcode_modifier & regKludge)
+ {
+ unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
+ /* Pretend we saw the extra register operand. */
+ i.regs[first_reg_op+1] = i.regs[first_reg_op];
+ i.reg_operands = 2;
+ }
+
+ if (i.tm.opcode_modifier & ShortForm)
+ {
+ /* The register or float register operand is in operand 0 or 1. */
+ unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
+ /* Register goes in low 3 bits of opcode. */
+ i.tm.base_opcode |= i.regs[op]->reg_num;
+ if ((i.tm.opcode_modifier & Ugh) != 0)
+ {
+ /* Warn about some common errors, but press on regardless.
+ The first case can be generated by gcc (<= 2.8.1). */
+ if (i.operands == 2)
+ {
+ /* reversed arguments on faddp, fsubp, etc. */
+ as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name,
+ i.regs[1]->reg_name,
+ i.regs[0]->reg_name);
+ }
+ else
+ {
+ /* extraneous `l' suffix on fp insn */
+ as_warn (_("translating to `%s %%%s'"), i.tm.name,
+ i.regs[0]->reg_name);
+ }
+ }
+ }
+ else if (i.tm.opcode_modifier & Modrm)
+ {
+ /* The opcode is completed (modulo i.tm.extension_opcode which
+ must be put into the modrm byte).
+ Now, we make the modrm & index base bytes based on all the
+ info we've collected. */
+
+ /* i.reg_operands MUST be the number of real register operands;
+ implicit registers do not count. */
+ if (i.reg_operands == 2)
+ {
+ unsigned int source, dest;
+ source = ((i.types[0]
+ & (Reg
+ | SReg2
+ | SReg3
+ | Control
+ | Debug
+ | Test
+ | RegMMX))
+ ? 0 : 1);
+ dest = source + 1;
+
+ /* Certain instructions expect the destination to be
+ in the i.rm.reg field. This is by far the
+ exceptional case. For these instructions, if the
+ source operand is a register, we must reverse the
+ i.rm.reg and i.rm.regmem fields. We accomplish
+ this by pretending that the two register operands
+ were given in the reverse order. */
+ if (i.tm.opcode_modifier & ReverseRegRegmem)
+ {
+ const reg_entry *tmp = i.regs[source];
+ i.regs[source] = i.regs[dest];
+ i.regs[dest] = tmp;
+ }
+
+ i.rm.mode = 3;
+ /* We must be careful to make sure that all
+ segment/control/test/debug/MMX registers go into
+ the i.rm.reg field (despite whether they are
+ source or destination operands). */
+ if (i.regs[dest]->reg_type
+ & (SReg2 | SReg3 | Control | Debug | Test | RegMMX))
+ {
+ i.rm.reg = i.regs[dest]->reg_num;
+ i.rm.regmem = i.regs[source]->reg_num;
+ }
+ else
+ {
+ i.rm.reg = i.regs[source]->reg_num;
+ i.rm.regmem = i.regs[dest]->reg_num;
+ }
+ }
+ else
+ { /* if it's not 2 reg operands... */
+ if (i.mem_operands)
+ {
+ unsigned int fake_zero_displacement = 0;
+ unsigned int op = ((i.types[0] & AnyMem)
+ ? 0
+ : (i.types[1] & AnyMem) ? 1 : 2);
+
+ default_seg = &ds;
+
+ if (! i.base_reg)
+ {
+ i.rm.mode = 0;
+ if (! i.disp_operands)
+ fake_zero_displacement = 1;
+ if (! i.index_reg)
+ {
+ /* Operand is just <disp> */
+ if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
+ {
+ i.rm.regmem = NO_BASE_REGISTER_16;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp16;
+ }
+ else
+ {
+ i.rm.regmem = NO_BASE_REGISTER;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp32;
+ }
+ }
+ else /* ! i.base_reg && i.index_reg */
+ {
+ i.sib.index = i.index_reg->reg_num;
+ i.sib.base = NO_BASE_REGISTER;
+ i.sib.scale = i.log2_scale_factor;
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+ i.types[op] &= ~Disp;
+ i.types[op] |= Disp32; /* Must be 32 bit */
+ }
+ }
+ else if (i.base_reg->reg_type & Reg16)
+ {
+ switch (i.base_reg->reg_num)
+ {
+ case 3: /* (%bx) */
+ if (! i.index_reg)
+ i.rm.regmem = 7;
+ else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */
+ i.rm.regmem = i.index_reg->reg_num - 6;
+ break;
+ case 5: /* (%bp) */
+ default_seg = &ss;
+ if (! i.index_reg)
+ {
+ i.rm.regmem = 6;
+ if ((i.types[op] & Disp) == 0)
+ {
+ /* fake (%bp) into 0(%bp) */
+ i.types[op] |= Disp8;
+ fake_zero_displacement = 1;
+ }
+ }
+ else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */
+ i.rm.regmem = i.index_reg->reg_num - 6 + 2;
+ break;
+ default: /* (%si) -> 4 or (%di) -> 5 */
+ i.rm.regmem = i.base_reg->reg_num - 6 + 4;
+ }
+ i.rm.mode = mode_from_disp_size (i.types[op]);
+ }
+ else /* i.base_reg and 32 bit mode */
+ {
+ i.rm.regmem = i.base_reg->reg_num;
+ i.sib.base = i.base_reg->reg_num;
+ if (i.base_reg->reg_num == EBP_REG_NUM)
+ {
+ default_seg = &ss;
+ if (i.disp_operands == 0)
+ {
+ fake_zero_displacement = 1;
+ i.types[op] |= Disp8;
+ }
+ }
+ else if (i.base_reg->reg_num == ESP_REG_NUM)
+ {
+ default_seg = &ss;
+ }
+ i.sib.scale = i.log2_scale_factor;
+ if (! i.index_reg)
+ {
+ /* <disp>(%esp) becomes two byte modrm
+ with no index register. We've already
+ stored the code for esp in i.rm.regmem
+ ie. ESCAPE_TO_TWO_BYTE_ADDRESSING. Any
+ base register besides %esp will not use
+ the extra modrm byte. */
+ i.sib.index = NO_INDEX_REGISTER;
+#if ! SCALE1_WHEN_NO_INDEX
+ /* Another case where we force the second
+ modrm byte. */
+ if (i.log2_scale_factor)
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+#endif
+ }
+ else
+ {
+ i.sib.index = i.index_reg->reg_num;
+ i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
+ }
+ i.rm.mode = mode_from_disp_size (i.types[op]);
+ }
+
+ if (fake_zero_displacement)
+ {
+ /* Fakes a zero displacement assuming that i.types[op]
+ holds the correct displacement size. */
+ exp = &disp_expressions[i.disp_operands++];
+ i.disps[op] = exp;
+ exp->X_op = O_constant;
+ exp->X_add_number = 0;
+ exp->X_add_symbol = (symbolS *) 0;
+ exp->X_op_symbol = (symbolS *) 0;
+ }
+ }
+
+ /* Fill in i.rm.reg or i.rm.regmem field with register
+ operand (if any) based on i.tm.extension_opcode.
+ Again, we must be careful to make sure that
+ segment/control/debug/test/MMX registers are coded
+ into the i.rm.reg field. */
+ if (i.reg_operands)
+ {
+ unsigned int op =
+ ((i.types[0]
+ & (Reg | SReg2 | SReg3 | Control | Debug
+ | Test | RegMMX))
+ ? 0
+ : ((i.types[1]
+ & (Reg | SReg2 | SReg3 | Control | Debug
+ | Test | RegMMX))
+ ? 1
+ : 2));
+ /* If there is an extension opcode to put here, the
+ register number must be put into the regmem field. */
+ if (i.tm.extension_opcode != None)
+ i.rm.regmem = i.regs[op]->reg_num;
+ else
+ i.rm.reg = i.regs[op]->reg_num;
+
+ /* Now, if no memory operand has set i.rm.mode = 0, 1, 2
+ we must set it to 3 to indicate this is a register
+ operand in the regmem field. */
+ if (!i.mem_operands)
+ i.rm.mode = 3;
+ }
+
+ /* Fill in i.rm.reg field with extension opcode (if any). */
+ if (i.tm.extension_opcode != None)
+ i.rm.reg = i.tm.extension_opcode;
+ }
+ }
+ else if (i.tm.opcode_modifier & (Seg2ShortForm | Seg3ShortForm))
+ {
+ if (i.tm.base_opcode == POP_SEG_SHORT && i.regs[0]->reg_num == 1)
+ {
+ as_bad (_("you can't `pop %%cs'"));
+ return;
+ }
+ i.tm.base_opcode |= (i.regs[0]->reg_num << 3);
+ }
+ else if ((i.tm.base_opcode & ~(D|W)) == MOV_AX_DISP32)
+ {
+ default_seg = &ds;
+ }
+ else if ((i.tm.opcode_modifier & IsString) != 0)
+ {
+ /* For the string instructions that allow a segment override
+ on one of their operands, the default segment is ds. */
+ default_seg = &ds;
+ }
+
+ /* If a segment was explicitly specified,
+ and the specified segment is not the default,
+ use an opcode prefix to select it.
+ If we never figured out what the default segment is,
+ then default_seg will be zero at this point,
+ and the specified segment prefix will always be used. */
+ if ((i.seg[0]) && (i.seg[0] != default_seg))
+ {
+ if (! add_prefix (i.seg[0]->seg_prefix))
+ return;
+ }
+ }
+ else if ((i.tm.opcode_modifier & Ugh) != 0)
+ {
+ /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc */
+ as_warn (_("translating to `%sp'"), i.tm.name);
+ }
+ }
+
+ /* Handle conversion of 'int $3' --> special int3 insn. */
+ if (i.tm.base_opcode == INT_OPCODE && i.imms[0]->X_add_number == 3)
+ {
+ i.tm.base_opcode = INT3_OPCODE;
+ i.imm_operands = 0;
+ }
+
+ /* We are ready to output the insn. */
+ {
+ register char *p;
+
+ /* Output jumps. */
+ if (i.tm.opcode_modifier & Jump)
+ {
+ long n = (long) i.disps[0]->X_add_number;
+ int prefix = (i.prefix[DATA_PREFIX] != 0);
+ int code16 = 0;
+
+ if (prefix)
+ {
+ i.prefixes -= 1;
+ code16 = CODE16;
+ }
+ if (flag_16bit_code)
+ code16 ^= CODE16;
+
+ if (!intel_syntax && (i.prefixes != 0))
+ as_warn (_("skipping prefixes on this instruction"));
+
+ if (i.disps[0]->X_op == O_constant)
+ {
+ if (fits_in_signed_byte (n))
+ {
+ insn_size += 2;
+ p = frag_more (2);
+ p[0] = i.tm.base_opcode;
+ p[1] = n;
+ }
+ else
+ {
+ /* Use 16-bit jumps only for 16-bit code,
+ because text segments are limited to 64K anyway;
+ Use 32-bit jumps for 32-bit code, because they're faster,
+ and a 16-bit jump will clear the top 16 bits of %eip. */
+ int jmp_size = code16 ? 2 : 4;
+ if (code16 && !fits_in_signed_word (n))
+ {
+ as_bad (_("16-bit jump out of range"));
+ return;
+ }
+
+ if (i.tm.base_opcode == JUMP_PC_RELATIVE)
+ { /* pace */
+ /* unconditional jump */
+ insn_size += prefix + 1 + jmp_size;
+ p = frag_more (prefix + 1 + jmp_size);
+ if (prefix)
+ *p++ = DATA_PREFIX_OPCODE;
+ *p++ = (char) 0xe9;
+ md_number_to_chars (p, (valueT) n, jmp_size);
+ }
+ else
+ {
+ /* conditional jump */
+ insn_size += prefix + 2 + jmp_size;
+ p = frag_more (prefix + 2 + jmp_size);
+ if (prefix)
+ *p++ = DATA_PREFIX_OPCODE;
+ *p++ = TWO_BYTE_OPCODE_ESCAPE;
+ *p++ = i.tm.base_opcode + 0x10;
+ md_number_to_chars (p, (valueT) n, jmp_size);
+ }
+ }
+ }
+ else
+ {
+ int size = code16 ? 2 : 4;
+
+ /* It's a symbol; end frag & setup for relax.
+ Make sure there are more than 6 chars left in the current frag;
+ if not we'll have to start a new one. */
+ frag_grow (prefix + 1 + 2 + size);
+ insn_size += 1 + prefix;
+ p = frag_more (1 + prefix);
+ if (prefix)
+ *p++ = DATA_PREFIX_OPCODE;
+ *p = i.tm.base_opcode;
+ frag_var (rs_machine_dependent,
+ prefix + 2 + size, /* 2 opcode/prefix + displacement */
+ 1,
+ ((unsigned char) *p == JUMP_PC_RELATIVE
+ ? ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL) | code16
+ : ENCODE_RELAX_STATE (COND_JUMP, SMALL) | code16),
+ i.disps[0]->X_add_symbol,
+ (offsetT) n, p);
+ }
+ }
+ else if (i.tm.opcode_modifier & (JumpByte | JumpDword))
+ {
+ int size = (i.tm.opcode_modifier & JumpByte) ? 1 : 4;
+ long n = (long) i.disps[0]->X_add_number;
+
+ if (size == 1) /* then this is a loop or jecxz type instruction */
+ {
+ if (i.prefix[ADDR_PREFIX])
+ {
+ insn_size += 1;
+ FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE);
+ i.prefixes -= 1;
+ }
+ }
+ else
+ {
+ int code16 = 0;
+
+ if (i.prefix[DATA_PREFIX])
+ {
+ insn_size += 1;
+ FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE);
+ i.prefixes -= 1;
+ code16 = CODE16;
+ }
+ if (flag_16bit_code)
+ code16 ^= CODE16;
+
+ if (code16)
+ size = 2;
+ }
+
+ if (!intel_syntax && (i.prefixes != 0))
+ as_warn (_("skipping prefixes on this instruction"));
+
+ if (fits_in_unsigned_byte (i.tm.base_opcode))
+ {
+ insn_size += 1 + size;
+ p = frag_more (1 + size);
+ }
+ else
+ {
+ insn_size += 2 + size; /* opcode can be at most two bytes */
+ p = frag_more (2 + size);
+ *p++ = (i.tm.base_opcode >> 8) & 0xff;
+ }
+ *p++ = i.tm.base_opcode & 0xff;
+
+ if (i.disps[0]->X_op == O_constant)
+ {
+ if (size == 1 && !fits_in_signed_byte (n))
+ {
+ as_bad (_("`%s' only takes byte displacement; %ld shortened to %d"),
+ i.tm.name, n, *p);
+ }
+ else if (size == 2 && !fits_in_signed_word (n))
+ {
+ as_bad (_("16-bit jump out of range"));
+ return;
+ }
+ md_number_to_chars (p, (valueT) n, size);
+ }
+ else
+ {
+ fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.disps[0], 1, reloc (size, 1, i.disp_reloc[0]));
+
+ }
+ }
+ else if (i.tm.opcode_modifier & JumpInterSegment)
+ {
+ int size;
+ int reloc_type;
+ int prefix = i.prefix[DATA_PREFIX] != 0;
+ int code16 = 0;
+
+ if (prefix)
+ {
+ code16 = CODE16;
+ i.prefixes -= 1;
+ }
+ if (flag_16bit_code)
+ code16 ^= CODE16;
+
+ size = 4;
+ reloc_type = BFD_RELOC_32;
+ if (code16)
+ {
+ size = 2;
+ reloc_type = BFD_RELOC_16;
+ }
+
+ if (!intel_syntax && (i.prefixes != 0))
+ as_warn (_("skipping prefixes on this instruction"));
+
+ insn_size += prefix + 1 + 2 + size; /* 1 opcode; 2 segment; offset */
+ p = frag_more (prefix + 1 + 2 + size);
+ if (prefix)
+ *p++ = DATA_PREFIX_OPCODE;
+ *p++ = i.tm.base_opcode;
+ if (i.imms[1]->X_op == O_constant)
+ {
+ long n = (long) i.imms[1]->X_add_number;
+
+ if (size == 2 && !fits_in_unsigned_word (n))
+ {
+ as_bad (_("16-bit jump out of range"));
+ return;
+ }
+ md_number_to_chars (p, (valueT) n, size);
+ }
+ else
+ fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.imms[1], 0, reloc_type);
+ if (i.imms[0]->X_op != O_constant)
+ as_bad (_("can't handle non absolute segment in `%s'"),
+ i.tm.name);
+ md_number_to_chars (p + size, (valueT) i.imms[0]->X_add_number, 2);
+ }
+ else
+ {
+ /* Output normal instructions here. */
+ unsigned char *q;
+
+ /* The prefix bytes. */
+ for (q = i.prefix;
+ q < i.prefix + sizeof (i.prefix) / sizeof (i.prefix[0]);
+ q++)
+ {
+ if (*q)
+ {
+ insn_size += 1;
+ p = frag_more (1);
+ md_number_to_chars (p, (valueT) *q, 1);
+ }
+ }
+
+ /* Now the opcode; be careful about word order here! */
+ if (fits_in_unsigned_byte (i.tm.base_opcode))
+ {
+ insn_size += 1;
+ FRAG_APPEND_1_CHAR (i.tm.base_opcode);
+ }
+ else if (fits_in_unsigned_word (i.tm.base_opcode))
+ {
+ insn_size += 2;
+ p = frag_more (2);
+ /* put out high byte first: can't use md_number_to_chars! */
+ *p++ = (i.tm.base_opcode >> 8) & 0xff;
+ *p = i.tm.base_opcode & 0xff;
+ }
+ else
+ { /* opcode is either 3 or 4 bytes */
+ if (i.tm.base_opcode & 0xff000000)
+ {
+ insn_size += 4;
+ p = frag_more (4);
+ *p++ = (i.tm.base_opcode >> 24) & 0xff;
+ }
+ else
+ {
+ insn_size += 3;
+ p = frag_more (3);
+ }
+ *p++ = (i.tm.base_opcode >> 16) & 0xff;
+ *p++ = (i.tm.base_opcode >> 8) & 0xff;
+ *p = (i.tm.base_opcode) & 0xff;
+ }
+
+ /* Now the modrm byte and sib byte (if present). */
+ if (i.tm.opcode_modifier & Modrm)
+ {
+ insn_size += 1;
+ p = frag_more (1);
+ md_number_to_chars (p,
+ (valueT) (i.rm.regmem << 0
+ | i.rm.reg << 3
+ | i.rm.mode << 6),
+ 1);
+ /* If i.rm.regmem == ESP (4)
+ && i.rm.mode != (Register mode)
+ && not 16 bit
+ ==> need second modrm byte. */
+ if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING
+ && i.rm.mode != 3
+ && !(i.base_reg && (i.base_reg->reg_type & Reg16) != 0))
+ {
+ insn_size += 1;
+ p = frag_more (1);
+ md_number_to_chars (p,
+ (valueT) (i.sib.base << 0
+ | i.sib.index << 3
+ | i.sib.scale << 6),
+ 1);
+ }
+ }
+
+ if (i.disp_operands)
+ {
+ register unsigned int n;
+
+ for (n = 0; n < i.operands; n++)
+ {
+ if (i.disps[n])
+ {
+ if (i.disps[n]->X_op == O_constant)
+ {
+ if (i.types[n] & Disp8)
+ {
+ insn_size += 1;
+ p = frag_more (1);
+ md_number_to_chars (p,
+ (valueT) i.disps[n]->X_add_number,
+ 1);
+ }
+ else if (i.types[n] & Disp16)
+ {
+ insn_size += 2;
+ p = frag_more (2);
+ md_number_to_chars (p,
+ (valueT) i.disps[n]->X_add_number,
+ 2);
+ }
+ else
+ { /* Disp32 */
+ insn_size += 4;
+ p = frag_more (4);
+ md_number_to_chars (p,
+ (valueT) i.disps[n]->X_add_number,
+ 4);
+ }
+ }
+ else if (i.types[n] & Disp32)
+ {
+ insn_size += 4;
+ p = frag_more (4);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
+ i.disps[n], 0,
+ TC_RELOC (i.disp_reloc[n], BFD_RELOC_32));
+ }
+ else
+ { /* must be Disp16 */
+ insn_size += 2;
+ p = frag_more (2);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
+ i.disps[n], 0,
+ TC_RELOC (i.disp_reloc[n], BFD_RELOC_16));
+ }
+ }
+ }
+ } /* end displacement output */
+
+ /* output immediate */
+ if (i.imm_operands)
+ {
+ register unsigned int n;
+
+ for (n = 0; n < i.operands; n++)
+ {
+ if (i.imms[n])
+ {
+ if (i.imms[n]->X_op == O_constant)
+ {
+ if (i.types[n] & (Imm8 | Imm8S))
+ {
+ insn_size += 1;
+ p = frag_more (1);
+ md_number_to_chars (p,
+ (valueT) i.imms[n]->X_add_number,
+ 1);
+ }
+ else if (i.types[n] & Imm16)
+ {
+ insn_size += 2;
+ p = frag_more (2);
+ md_number_to_chars (p,
+ (valueT) i.imms[n]->X_add_number,
+ 2);
+ }
+ else
+ {
+ insn_size += 4;
+ p = frag_more (4);
+ md_number_to_chars (p,
+ (valueT) i.imms[n]->X_add_number,
+ 4);
+ }
+ }
+ else
+ { /* not absolute_section */
+ /* Need a 32-bit fixup (don't support 8bit
+ non-absolute ims). Try to support other
+ sizes ... */
+ int r_type;
+ int size;
+ int pcrel = 0;
+
+ if (i.types[n] & (Imm8 | Imm8S))
+ size = 1;
+ else if (i.types[n] & Imm16)
+ size = 2;
+ else
+ size = 4;
+ insn_size += size;
+ p = frag_more (size);
+ r_type = reloc (size, 0, i.disp_reloc[0]);
+#ifdef BFD_ASSEMBLER
+ if (r_type == BFD_RELOC_32
+ && GOT_symbol
+ && GOT_symbol == i.imms[n]->X_add_symbol
+ && (i.imms[n]->X_op == O_symbol
+ || (i.imms[n]->X_op == O_add
+ && (i.imms[n]->X_op_symbol->sy_value.X_op
+ == O_subtract))))
+ {
+ r_type = BFD_RELOC_386_GOTPC;
+ i.imms[n]->X_add_number += 3;
+ }
+#endif
+ fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.imms[n], pcrel, r_type);
+ }
+ }
+ }
+ } /* end immediate output */
+ }
+
+#ifdef DEBUG386
+ if (flag_debug)
+ {
+ pi (line, &i);
+ }
+#endif /* DEBUG386 */
+ }
+}
+
+static int i386_is_reg PARAMS ((char *));
+
+static int
+i386_is_reg (reg_string)
+ char *reg_string;
+{
+ register char *s = reg_string;
+ register char *p;
+ char reg_name_given[MAX_REG_NAME_SIZE + 1];
+
+ if (is_space_char (*s))
+ ++s;
+
+ p = reg_name_given;
+ while ((*p++ = register_chars[(unsigned char) *s++]) != '\0')
+ if (p >= reg_name_given + MAX_REG_NAME_SIZE)
+ return 0;
+
+ if (!hash_find (reg_hash, reg_name_given))
+ return 0;
+ else
+ return 1;
+}
+
+static int i386_immediate PARAMS ((char *));
+
+static int
+i386_immediate (imm_start)
+ char *imm_start;
+{
+ char *save_input_line_pointer;
+ segT exp_seg = 0;
+ expressionS * exp;
+
+ if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
+ {
+ as_bad (_("Only 1 or 2 immediate operands are allowed"));
+ return 0;
+ }
+
+ exp = &im_expressions[i.imm_operands++];
+ i.imms[this_operand] = exp;
+
+ if (is_space_char (*imm_start))
+ ++imm_start;
+
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = imm_start;
+
+#ifndef LEX_AT
+ {
+ /*
+ * We can have operands of the form
+ * <symbol>@GOTOFF+<nnn>
+ * Take the easy way out here and copy everything
+ * into a temporary buffer...
+ */
+ register char *cp;
+
+ cp = strchr (input_line_pointer, '@');
+ if (cp != NULL)
+ {
+ char *tmpbuf;
+ int len, first;
+
+ /* GOT relocations are not supported in 16 bit mode */
+ if (flag_16bit_code)
+ as_bad (_("GOT relocations not supported in 16 bit mode"));
+
+ if (GOT_symbol == NULL)
+ GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
+
+ if (strncmp (cp + 1, "PLT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
+ len = 3;
+ }
+ else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
+ len = 6;
+ }
+ else if (strncmp (cp + 1, "GOT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
+ len = 3;
+ }
+ else
+ as_bad (_("Bad reloc specifier in expression"));
+
+ /* Replace the relocation token with ' ', so that errors like
+ foo@GOTOFF1 will be detected. */
+ first = cp - input_line_pointer;
+ tmpbuf = (char *) alloca (strlen(input_line_pointer));
+ memcpy (tmpbuf, input_line_pointer, first);
+ tmpbuf[first] = ' ';
+ strcpy (tmpbuf + first + 1, cp + 1 + len);
+ input_line_pointer = tmpbuf;
+ }
+ }
+#endif
+
+ exp_seg = expression (exp);
+
+ if (*input_line_pointer)
+ as_bad (_("Ignoring junk `%s' after expression"), input_line_pointer);
+
+ input_line_pointer = save_input_line_pointer;
+
+ if (exp->X_op == O_absent)
+ {
+ /* missing or bad expr becomes absolute 0 */
+ as_bad (_("Missing or invalid immediate expression `%s' taken as 0"),
+ imm_start);
+ exp->X_op = O_constant;
+ exp->X_add_number = 0;
+ exp->X_add_symbol = (symbolS *) 0;
+ exp->X_op_symbol = (symbolS *) 0;
+ i.types[this_operand] |= Imm;
+ }
+ else if (exp->X_op == O_constant)
+ {
+ i.types[this_operand] |=
+ smallest_imm_type ((long) exp->X_add_number);
+
+ /* If a suffix is given, this operand may be shortended. */
+ switch (i.suffix)
+ {
+ case WORD_MNEM_SUFFIX:
+ i.types[this_operand] |= Imm16;
+ break;
+ case BYTE_MNEM_SUFFIX:
+ i.types[this_operand] |= Imm16 | Imm8 | Imm8S;
+ break;
+ }
+ }
+#ifdef OBJ_AOUT
+ else if (exp_seg != text_section
+ && exp_seg != data_section
+ && exp_seg != bss_section
+ && exp_seg != undefined_section
+#ifdef BFD_ASSEMBLER
+ && !bfd_is_com_section (exp_seg)
+#endif
+ )
+ {
+ seg_unimplemented:
+ as_bad (_("Unimplemented segment type %d in operand"), exp_seg);
+ return 0;
+ }
+#endif
+ else
+ {
+ /* This is an address. The size of the address will be
+ determined later, depending on destination register,
+ suffix, or the default for the section. We exclude
+ Imm8S here so that `push $foo' and other instructions
+ with an Imm8S form will use Imm16 or Imm32. */
+ i.types[this_operand] |= (Imm8 | Imm16 | Imm32);
+ }
+
+ return 1;
+}
+
+static int i386_scale PARAMS ((char *));
+
+static int
+i386_scale (scale)
+ char *scale;
+{
+ if (!isdigit (*scale))
+ goto bad_scale;
+
+ switch (*scale)
+ {
+ case '0':
+ case '1':
+ i.log2_scale_factor = 0;
+ break;
+ case '2':
+ i.log2_scale_factor = 1;
+ break;
+ case '4':
+ i.log2_scale_factor = 2;
+ break;
+ case '8':
+ i.log2_scale_factor = 3;
+ break;
+ default:
+ bad_scale:
+ as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"),
+ scale);
+ return 0;
+ }
+ if (i.log2_scale_factor != 0 && ! i.index_reg)
+ {
+ as_warn (_("scale factor of %d without an index register"),
+ 1 << i.log2_scale_factor);
+#if SCALE1_WHEN_NO_INDEX
+ i.log2_scale_factor = 0;
+#endif
+ }
+ return 1;
+}
+
+static int i386_displacement PARAMS ((char *, char *));
+
+static int
+i386_displacement (disp_start, disp_end)
+ char *disp_start;
+ char *disp_end;
+{
+ register expressionS *exp;
+ segT exp_seg = 0;
+ char *save_input_line_pointer;
+ int bigdisp = Disp32;
+
+ /* All of the pieces of the displacement expression are handled together. */
+ if (intel_syntax && i.disp_operands != 0)
+ return 1;
+
+ if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
+ bigdisp = Disp16;
+ i.types[this_operand] |= bigdisp;
+
+ exp = &disp_expressions[i.disp_operands];
+ i.disps[this_operand] = exp;
+ i.disp_reloc[this_operand] = NO_RELOC;
+ i.disp_operands++;
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = disp_start;
+ END_STRING_AND_SAVE (disp_end);
+
+#ifndef GCC_ASM_O_HACK
+#define GCC_ASM_O_HACK 0
+#endif
+#if GCC_ASM_O_HACK
+ END_STRING_AND_SAVE (disp_end + 1);
+ if ((i.types[this_operand] & BaseIndex) != 0
+ && displacement_string_end[-1] == '+')
+ {
+ /* This hack is to avoid a warning when using the "o"
+ constraint within gcc asm statements.
+ For instance:
+
+ #define _set_tssldt_desc(n,addr,limit,type) \
+ __asm__ __volatile__ ( \
+ "movw %w2,%0\n\t" \
+ "movw %w1,2+%0\n\t" \
+ "rorl $16,%1\n\t" \
+ "movb %b1,4+%0\n\t" \
+ "movb %4,5+%0\n\t" \
+ "movb $0,6+%0\n\t" \
+ "movb %h1,7+%0\n\t" \
+ "rorl $16,%1" \
+ : "=o"(*(n)) : "q" (addr), "ri"(limit), "i"(type))
+
+ This works great except that the output assembler ends
+ up looking a bit weird if it turns out that there is
+ no offset. You end up producing code that looks like:
+
+ #APP
+ movw $235,(%eax)
+ movw %dx,2+(%eax)
+ rorl $16,%edx
+ movb %dl,4+(%eax)
+ movb $137,5+(%eax)
+ movb $0,6+(%eax)
+ movb %dh,7+(%eax)
+ rorl $16,%edx
+ #NO_APP
+
+ So here we provide the missing zero.
+ */
+
+ *displacement_string_end = '0';
+ }
+#endif
+#ifndef LEX_AT
+ {
+ /*
+ * We can have operands of the form
+ * <symbol>@GOTOFF+<nnn>
+ * Take the easy way out here and copy everything
+ * into a temporary buffer...
+ */
+ register char *cp;
+
+ cp = strchr (input_line_pointer, '@');
+ if (cp != NULL)
+ {
+ char *tmpbuf;
+ int len, first;
+
+ /* GOT relocations are not supported in 16 bit mode */
+ if (flag_16bit_code)
+ as_bad (_("GOT relocations not supported in 16 bit mode"));
+
+ if (GOT_symbol == NULL)
+ GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
+
+ if (strncmp (cp + 1, "PLT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_PLT32;
+ len = 3;
+ }
+ else if (strncmp (cp + 1, "GOTOFF", 6) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOTOFF;
+ len = 6;
+ }
+ else if (strncmp (cp + 1, "GOT", 3) == 0)
+ {
+ i.disp_reloc[this_operand] = BFD_RELOC_386_GOT32;
+ len = 3;
+ }
+ else
+ as_bad (_("Bad reloc specifier in expression"));
+
+ /* Replace the relocation token with ' ', so that errors like
+ foo@GOTOFF1 will be detected. */
+ first = cp - input_line_pointer;
+ tmpbuf = (char *) alloca (strlen(input_line_pointer));
+ memcpy (tmpbuf, input_line_pointer, first);
+ tmpbuf[first] = ' ';
+ strcpy (tmpbuf + first + 1, cp + 1 + len);
+ input_line_pointer = tmpbuf;
+ }
+ }
+#endif
+
+ exp_seg = expression (exp);
+
+#ifdef BFD_ASSEMBLER
+ /* We do this to make sure that the section symbol is in
+ the symbol table. We will ultimately change the relocation
+ to be relative to the beginning of the section */
+ if (i.disp_reloc[this_operand] == BFD_RELOC_386_GOTOFF)
+ {
+ if (S_IS_LOCAL(exp->X_add_symbol)
+ && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
+ section_symbol(exp->X_add_symbol->bsym->section);
+ assert (exp->X_op == O_symbol);
+ exp->X_op = O_subtract;
+ exp->X_op_symbol = GOT_symbol;
+ i.disp_reloc[this_operand] = BFD_RELOC_32;
+ }
+#endif
+
+ if (*input_line_pointer)
+ as_bad (_("Ignoring junk `%s' after expression"),
+ input_line_pointer);
+#if GCC_ASM_O_HACK
+ RESTORE_END_STRING (disp_end + 1);
+#endif
+ RESTORE_END_STRING (disp_end);
+ input_line_pointer = save_input_line_pointer;
+
+ if (exp->X_op == O_constant)
+ {
+ if (fits_in_signed_byte (exp->X_add_number))
+ i.types[this_operand] |= Disp8;
+ }
+#ifdef OBJ_AOUT
+ else if (exp_seg != text_section
+ && exp_seg != data_section
+ && exp_seg != bss_section
+ && exp_seg != undefined_section)
+ {
+ as_bad (_ ("Unimplemented segment type %d in operand"), exp_seg);
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+static int i386_operand_modifier PARAMS ((char **, int));
+
+static int
+i386_operand_modifier (op_string, got_a_float)
+ char **op_string;
+ int got_a_float;
+{
+ if (!strncasecmp (*op_string, "BYTE PTR", 8))
+ {
+ i.suffix = BYTE_MNEM_SUFFIX;
+ *op_string += 8;
+ return BYTE_PTR;
+
+ }
+ else if (!strncasecmp (*op_string, "WORD PTR", 8))
+ {
+ i.suffix = WORD_MNEM_SUFFIX;
+ *op_string += 8;
+ return WORD_PTR;
+ }
+
+ else if (!strncasecmp (*op_string, "DWORD PTR", 9))
+ {
+ if (got_a_float)
+ i.suffix = SHORT_MNEM_SUFFIX;
+ else
+ i.suffix = DWORD_MNEM_SUFFIX;
+ *op_string += 9;
+ return DWORD_PTR;
+ }
+
+ else if (!strncasecmp (*op_string, "QWORD PTR", 9))
+ {
+ i.suffix = INTEL_DWORD_MNEM_SUFFIX;
+ *op_string += 9;
+ return QWORD_PTR;
+ }
+
+ else if (!strncasecmp (*op_string, "XWORD PTR", 9))
+ {
+ i.suffix = LONG_DOUBLE_MNEM_SUFFIX;
+ *op_string += 9;
+ return XWORD_PTR;
+ }
+
+ else if (!strncasecmp (*op_string, "SHORT", 5))
+ {
+ *op_string += 5;
+ return SHORT;
+ }
+
+ else if (!strncasecmp (*op_string, "OFFSET FLAT:", 12))
+ {
+ *op_string += 12;
+ return OFFSET_FLAT;
+ }
+
+ else if (!strncasecmp (*op_string, "FLAT", 4))
+ {
+ *op_string += 4;
+ return FLAT;
+ }
+
+ else return NONE_FOUND;
+}
+
+static char * build_displacement_string PARAMS ((int, char *));
+
+static char *
+build_displacement_string (initial_disp, op_string)
+ int initial_disp;
+ char *op_string;
+{
+ char *temp_string = (char *) malloc (strlen (op_string) + 1);
+ char *end_of_operand_string;
+ char *tc;
+ char *temp_disp;
+
+ temp_string[0] = '\0';
+ tc = end_of_operand_string = strchr (op_string, '[');
+ if ( initial_disp && !end_of_operand_string)
+ {
+ strcpy (temp_string, op_string);
+ return (temp_string);
+ }
+
+ /* Build the whole displacement string */
+ if (initial_disp)
+ {
+ strncpy (temp_string, op_string, end_of_operand_string - op_string);
+ temp_string[end_of_operand_string - op_string] = '\0';
+ temp_disp = tc;
+ }
+ else
+ temp_disp = op_string;
+
+ while (*temp_disp != '\0')
+ {
+ int add_minus = (*temp_disp == '-');
+
+ if (*temp_disp == '+' || *temp_disp == '-' || *temp_disp == '[')
+ temp_disp++;
+
+ if (is_space_char (*temp_disp))
+ temp_disp++;
+
+ /* Don't consider registers */
+ if (*temp_disp != REGISTER_PREFIX
+ && !(allow_naked_reg && i386_is_reg (temp_disp)))
+ {
+ char *string_start = temp_disp;
+
+ while (*temp_disp != ']'
+ && *temp_disp != '+'
+ && *temp_disp != '-'
+ && *temp_disp != '*')
+ ++temp_disp;
+
+ if (add_minus)
+ strcat (temp_string, "-");
+ else
+ strcat (temp_string, "+");
+
+ strncat (temp_string, string_start, temp_disp - string_start);
+ if (*temp_disp == '+' || *temp_disp == '-')
+ --temp_disp;
+ }
+
+ while (*temp_disp != '\0'
+ && *temp_disp != '+'
+ && *temp_disp != '-')
+ ++temp_disp;
+ }
+
+ return temp_string;
+}
+
+static int i386_parse_seg PARAMS ((char *));
+
+static int
+i386_parse_seg (op_string)
+ char *op_string;
+{
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ /* Should be one of es, cs, ss, ds fs or gs */
+ switch (*op_string++)
+ {
+ case 'e':
+ i.seg[i.mem_operands] = &es;
+ break;
+ case 'c':
+ i.seg[i.mem_operands] = &cs;
+ break;
+ case 's':
+ i.seg[i.mem_operands] = &ss;
+ break;
+ case 'd':
+ i.seg[i.mem_operands] = &ds;
+ break;
+ case 'f':
+ i.seg[i.mem_operands] = &fs;
+ break;
+ case 'g':
+ i.seg[i.mem_operands] = &gs;
+ break;
+ default:
+ as_bad (_("bad segment name `%s'"), op_string);
+ return 0;
+ }
+
+ if (*op_string++ != 's')
+ {
+ as_bad (_("bad segment name `%s'"), op_string);
+ return 0;
+ }
+
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ if (*op_string != ':')
+ {
+ as_bad (_("bad segment name `%s'"), op_string);
+ return 0;
+ }
+
+ return 1;
+
+}
+
+static int i386_intel_memory_operand PARAMS ((char *));
+
+static int
+i386_intel_memory_operand (op_string)
+ char *op_string;
+{
+
+ char *end_of_operand_string;
+
+ if (is_digit_char (*op_string)
+ && strchr (op_string, '[') == 0)
+ {
+ if (!i386_immediate (op_string))
+ return 0;
+ else
+ return 1;
+ }
+
+ /* Look for displacement preceding open bracket */
+ if (*op_string != '[')
+ {
+ char *end_seg;
+ char *temp_string;
+
+ end_seg = strchr (op_string, ':');
+ if (end_seg)
+ {
+ if (!i386_parse_seg (op_string))
+ return 0;
+ op_string = end_seg + 1;
+ }
+
+ temp_string = build_displacement_string (true, op_string);
+ if (!i386_displacement (temp_string, temp_string + strlen (temp_string)))
+ return 0;
+
+ end_of_operand_string = strchr (op_string, '[');
+ if (!end_of_operand_string)
+ end_of_operand_string = op_string + strlen (op_string);
+
+ if (is_space_char (*end_of_operand_string))
+ --end_of_operand_string;
+
+ op_string = end_of_operand_string;
+ }
+
+ if (*op_string == '[')
+ {
+ ++op_string;
+
+ /* Pick off each component and figure out where it belongs */
+
+ end_of_operand_string = op_string;
+
+ while (*op_string != ']')
+ {
+
+ while (*end_of_operand_string != '+'
+ && *end_of_operand_string != '-'
+ && *end_of_operand_string != '*'
+ && *end_of_operand_string != ']')
+ end_of_operand_string++;
+
+ if (*op_string == '+')
+ {
+ char *temp_string = op_string + 1;
+ if (is_space_char (*temp_string))
+ ++temp_string;
+ if (*temp_string == REGISTER_PREFIX
+ || (allow_naked_reg && i386_is_reg (temp_string)))
+ ++op_string;
+ }
+
+ if (*op_string == REGISTER_PREFIX
+ || (allow_naked_reg && i386_is_reg (op_string)))
+ {
+ const reg_entry *temp_reg;
+ char *end_op;
+
+ END_STRING_AND_SAVE (end_of_operand_string);
+ temp_reg = parse_register (op_string, &end_op);
+ RESTORE_END_STRING (end_of_operand_string);
+
+ if (temp_reg == NULL)
+ return 0;
+
+ if (i.base_reg == NULL)
+ i.base_reg = temp_reg;
+ else
+ i.index_reg = temp_reg;
+
+ i.types[this_operand] |= BaseIndex;
+
+ }
+ else if (is_digit_char (*op_string) || *op_string == '+' || *op_string == '-')
+ {
+
+ char *temp_string = build_displacement_string (false, op_string);
+
+ if (*temp_string == '+')
+ ++temp_string;
+
+ if (!i386_displacement (temp_string, temp_string + strlen (temp_string)))
+ return 0;
+
+ ++op_string;
+ end_of_operand_string = op_string;
+ while (*end_of_operand_string != ']'
+ && *end_of_operand_string != '+'
+ && *end_of_operand_string != '-'
+ && *end_of_operand_string != '*')
+ ++end_of_operand_string;
+ }
+ else if (*op_string == '*')
+ {
+ ++op_string;
+
+ if (i.base_reg && !i.index_reg)
+ {
+ i.index_reg = i.base_reg;
+ i.base_reg = 0;
+ }
+
+ if (!i386_scale (op_string))
+ return 0;
+ }
+ op_string = end_of_operand_string;
+ ++end_of_operand_string;
+ }
+ }
+
+ return 1;
+}
+
+static int i386_intel_operand PARAMS ((char *, int));
+
+static int
+i386_intel_operand (operand_string, got_a_float)
+ char *operand_string;
+ int got_a_float;
+{
+ char *op_string = operand_string;
+
+ int operand_modifier = i386_operand_modifier (&op_string, got_a_float);
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ switch (operand_modifier)
+ {
+ case BYTE_PTR:
+ case WORD_PTR:
+ case DWORD_PTR:
+ case QWORD_PTR:
+ case XWORD_PTR:
+ if ((i.mem_operands == 1
+ && (current_templates->start->opcode_modifier & IsString) == 0)
+ || i.mem_operands == 2)
+ {
+ as_bad (_("too many memory references for `%s'"),
+ current_templates->start->name);
+ return 0;
+ }
+
+ if (!i386_intel_memory_operand (op_string))
+ return 0;
+
+ i.mem_operands++;
+ break;
+
+ case FLAT:
+
+ case OFFSET_FLAT:
+ if (!i386_immediate (op_string))
+ return 0;
+ break;
+
+ case SHORT:
+
+ case NONE_FOUND:
+ /* Should be register or immediate */
+ if (is_digit_char (*op_string)
+ && strchr (op_string, '[') == 0)
+ {
+ if (!i386_immediate (op_string))
+ return 0;
+ }
+ else if (*op_string == REGISTER_PREFIX
+ || (allow_naked_reg
+ && i386_is_reg (op_string)))
+ {
+
+ register const reg_entry * r;
+ char *end_op;
+
+ r = parse_register (op_string, &end_op);
+ if (r == NULL)
+ return 0;
+
+ /* Check for a segment override by searching for ':' after a
+ segment register. */
+ op_string = end_op;
+ if (is_space_char (*op_string))
+ ++op_string;
+ if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
+ {
+ switch (r->reg_num)
+ {
+ case 0:
+ i.seg[i.mem_operands] = &es;
+ break;
+ case 1:
+ i.seg[i.mem_operands] = &cs;
+ break;
+ case 2:
+ i.seg[i.mem_operands] = &ss;
+ break;
+ case 3:
+ i.seg[i.mem_operands] = &ds;
+ break;
+ case 4:
+ i.seg[i.mem_operands] = &fs;
+ break;
+ case 5:
+ i.seg[i.mem_operands] = &gs;
+ break;
+ }
+
+ }
+ i.types[this_operand] |= r->reg_type & ~BaseIndex;
+ i.regs[this_operand] = r;
+ i.reg_operands++;
+ }
+
+ else
+ {
+
+ if (!i386_intel_memory_operand (op_string))
+ return 0;
+
+ i.mem_operands++;
+ }
+ break;
+
+ } /* end switch */
+ /* Special case for (%dx) while doing input/output op. */
+ if (i.base_reg
+ && i.base_reg->reg_type == (Reg16 | InOutPortReg)
+ && i.index_reg == 0
+ && i.log2_scale_factor == 0
+ && i.seg[i.mem_operands] == 0
+ && (i.types[this_operand] & Disp) == 0)
+ {
+ i.types[this_operand] = InOutPortReg;
+ return 1;
+ }
+ /* Make sure the memory operand we've been dealt is valid. */
+ if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
+ {
+ if ((i.base_reg
+ && ((i.base_reg->reg_type & (Reg16|BaseIndex))
+ != (Reg16|BaseIndex)))
+ || (i.index_reg
+ && (((i.index_reg->reg_type & (Reg16|BaseIndex))
+ != (Reg16|BaseIndex))
+ || ! (i.base_reg
+ && i.base_reg->reg_num < 6
+ && i.index_reg->reg_num >= 6
+ && i.log2_scale_factor == 0))))
+ {
+ as_bad (_("`%s' is not a valid %s bit base/index expression"),
+ operand_string, "16");
+ return 0;
+ }
+ }
+ else
+ {
+ if ((i.base_reg
+ && (i.base_reg->reg_type & Reg32) == 0)
+ || (i.index_reg
+ && ((i.index_reg->reg_type & (Reg32|BaseIndex))
+ != (Reg32|BaseIndex))))
+ {
+ as_bad (_("`%s' is not a valid %s bit base/index expression"),
+ operand_string, "32");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Parse OPERAND_STRING into the i386_insn structure I. Returns non-zero
+ on error. */
+
+static int i386_operand PARAMS ((char *));
+
+static int
+i386_operand (operand_string)
+ char *operand_string;
+{
+ char *op_string = operand_string;
+
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ /* We check for an absolute prefix (differentiating,
+ for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */
+ if (*op_string == ABSOLUTE_PREFIX)
+ {
+ ++op_string;
+ if (is_space_char (*op_string))
+ ++op_string;
+ i.types[this_operand] |= JumpAbsolute;
+ }
+
+ /* Check if operand is a register. */
+ if (*op_string == REGISTER_PREFIX
+ || (allow_naked_reg && i386_is_reg (op_string)))
+ {
+ register const reg_entry *r;
+ char *end_op;
+
+ r = parse_register (op_string, &end_op);
+ if (r == NULL)
+ return 0;
+
+ /* Check for a segment override by searching for ':' after a
+ segment register. */
+ op_string = end_op;
+ if (is_space_char (*op_string))
+ ++op_string;
+ if (*op_string == ':' && (r->reg_type & (SReg2 | SReg3)))
+ {
+ switch (r->reg_num)
+ {
+ case 0:
+ i.seg[i.mem_operands] = &es;
+ break;
+ case 1:
+ i.seg[i.mem_operands] = &cs;
+ break;
+ case 2:
+ i.seg[i.mem_operands] = &ss;
+ break;
+ case 3:
+ i.seg[i.mem_operands] = &ds;
+ break;
+ case 4:
+ i.seg[i.mem_operands] = &fs;
+ break;
+ case 5:
+ i.seg[i.mem_operands] = &gs;
+ break;
+ }
+
+ /* Skip the ':' and whitespace. */
+ ++op_string;
+ if (is_space_char (*op_string))
+ ++op_string;
+
+ /* Pretend given string starts here. */
+ operand_string = op_string;
+ if (!is_digit_char (*op_string)
+ && !is_identifier_char (*op_string)
+ && *op_string != '('
+ && *op_string != ABSOLUTE_PREFIX)
+ {
+ as_bad (_("bad memory operand `%s'"), op_string);
+ return 0;
+ }
+ /* Handle case of %es:*foo. */
+ if (*op_string == ABSOLUTE_PREFIX)
+ {
+ ++op_string;
+ if (is_space_char (*op_string))
+ ++op_string;
+ i.types[this_operand] |= JumpAbsolute;
+ }
+ goto do_memory_reference;
+ }
+ if (*op_string)
+ {
+ as_bad (_("Junk `%s' after register"), op_string);
+ return 0;
+ }
+ i.types[this_operand] |= r->reg_type & ~BaseIndex;
+ i.regs[this_operand] = r;
+ i.reg_operands++;
+ }
+ else if (*op_string == IMMEDIATE_PREFIX)
+ { /* ... or an immediate */
+ ++op_string;
+ if (!i386_immediate (op_string))
+ return 0;
+ }
+ else if (is_digit_char (*op_string)
+ || is_identifier_char (*op_string)
+ || *op_string == '(' )
+ {
+ /* This is a memory reference of some sort. */
+ char *end_of_operand_string;
+ register char *base_string;
+ int found_base_index_form;
+
+ /* Start and end of displacement string expression (if found). */
+ char *displacement_string_start;
+ char *displacement_string_end;
+
+ do_memory_reference:
+
+ if ((i.mem_operands == 1
+ && (current_templates->start->opcode_modifier & IsString) == 0)
+ || i.mem_operands == 2)
+ {
+ as_bad (_("too many memory references for `%s'"),
+ current_templates->start->name);
+ return 0;
+ }
+
+ /* Check for base index form. We detect the base index form by
+ looking for an ')' at the end of the operand, searching
+ for the '(' matching it, and finding a REGISTER_PREFIX or ','
+ after the '('. */
+ found_base_index_form = 0;
+ end_of_operand_string = op_string + strlen (op_string);
+
+ --end_of_operand_string;
+ if (is_space_char (*end_of_operand_string))
+ --end_of_operand_string;
+
+ base_string = end_of_operand_string;
+
+ if (*base_string == ')')
+ {
+ unsigned int parens_balanced = 1;
+ /* We've already checked that the number of left & right ()'s are
+ equal, so this loop will not be infinite. */
+ do
+ {
+ base_string--;
+ if (*base_string == ')')
+ parens_balanced++;
+ if (*base_string == '(')
+ parens_balanced--;
+ }
+ while (parens_balanced);
+
+ /* If there is a displacement set-up for it to be parsed later. */
+ displacement_string_start = op_string;
+ displacement_string_end = base_string;
+
+ /* Skip past '(' and whitespace. */
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+
+ if (*base_string == REGISTER_PREFIX
+ || (allow_naked_reg && i386_is_reg (base_string))
+ || *base_string == ',')
+ found_base_index_form = 1;
+ }
+
+ /* If we can't parse a base index register expression, we've found
+ a pure displacement expression. We set up displacement_string_start
+ and displacement_string_end for the code below. */
+ if (!found_base_index_form)
+ {
+ displacement_string_start = op_string;
+ displacement_string_end = end_of_operand_string + 1;
+ }
+ else
+ {
+ i.types[this_operand] |= BaseIndex;
+
+ /* Find base register (if any). */
+ if (*base_string != ',')
+ {
+ char *end_op;
+
+ /* Trim off the closing ')' so that parse_register won't
+ see it. */
+ END_STRING_AND_SAVE (end_of_operand_string);
+ i.base_reg = parse_register (base_string, &end_op);
+ RESTORE_END_STRING (end_of_operand_string);
+
+ if (i.base_reg == NULL)
+ return 0;
+
+ base_string = end_op;
+ if (is_space_char (*base_string))
+ ++base_string;
+ }
+
+ /* There may be an index reg or scale factor here. */
+ if (*base_string == ',')
+ {
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+
+ if (*base_string == REGISTER_PREFIX
+ || (allow_naked_reg && i386_is_reg (base_string)))
+ {
+ char *end_op;
+
+ END_STRING_AND_SAVE (end_of_operand_string);
+ i.index_reg = parse_register (base_string, &end_op);
+ RESTORE_END_STRING (end_of_operand_string);
+
+ if (i.index_reg == NULL)
+ return 0;
+
+ base_string = end_op;
+ if (is_space_char (*base_string))
+ ++base_string;
+ if (*base_string == ',')
+ {
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+ }
+ else if (*base_string != ')' )
+ {
+ as_bad (_("expecting `,' or `)' after index register in `%s'"),
+ operand_string);
+ return 0;
+ }
+ }
+
+ /* Check for scale factor. */
+ if (isdigit ((unsigned char) *base_string))
+ {
+ if (!i386_scale (base_string))
+ return 0;
+
+ ++base_string;
+ if (is_space_char (*base_string))
+ ++base_string;
+ if (*base_string != ')')
+ {
+ as_bad (_("expecting `)' after scale factor in `%s'"),
+ operand_string);
+ return 0;
+ }
+ }
+ else if (!i.index_reg)
+ {
+ as_bad (_("expecting index register or scale factor after `,'; got '%c'"),
+ *base_string);
+ return 0;
+ }
+ }
+ else if (*base_string != ')')
+ {
+ as_bad (_("expecting `,' or `)' after base register in `%s'"),
+ operand_string);
+ return 0;
+ }
+ }
+
+ /* If there's an expression beginning the operand, parse it,
+ assuming displacement_string_start and
+ displacement_string_end are meaningful. */
+ if (displacement_string_start != displacement_string_end)
+ {
+ if (!i386_displacement (displacement_string_start,
+ displacement_string_end))
+ return 0;
+ }
+
+ /* Special case for (%dx) while doing input/output op. */
+ if (i.base_reg
+ && i.base_reg->reg_type == (Reg16 | InOutPortReg)
+ && i.index_reg == 0
+ && i.log2_scale_factor == 0
+ && i.seg[i.mem_operands] == 0
+ && (i.types[this_operand] & Disp) == 0)
+ {
+ i.types[this_operand] = InOutPortReg;
+ return 1;
+ }
+ /* Make sure the memory operand we've been dealt is valid. */
+ if (flag_16bit_code ^ (i.prefix[ADDR_PREFIX] != 0))
+ {
+ if ((i.base_reg
+ && ((i.base_reg->reg_type & (Reg16|BaseIndex))
+ != (Reg16|BaseIndex)))
+ || (i.index_reg
+ && (((i.index_reg->reg_type & (Reg16|BaseIndex))
+ != (Reg16|BaseIndex))
+ || ! (i.base_reg
+ && i.base_reg->reg_num < 6
+ && i.index_reg->reg_num >= 6
+ && i.log2_scale_factor == 0))))
+ {
+ as_bad (_("`%s' is not a valid %s bit base/index expression"),
+ operand_string, "16");
+ return 0;
+ }
+ }
+ else
+ {
+ if ((i.base_reg
+ && (i.base_reg->reg_type & Reg32) == 0)
+ || (i.index_reg
+ && ((i.index_reg->reg_type & (Reg32|BaseIndex))
+ != (Reg32|BaseIndex))))
+ {
+ as_bad (_("`%s' is not a valid %s bit base/index expression"),
+ operand_string, "32");
+ return 0;
+ }
+ }
+ i.mem_operands++;
+ }
+ else
+ { /* it's not a memory operand; argh! */
+ as_bad (_("invalid char %s beginning operand %d `%s'"),
+ output_invalid (*op_string),
+ this_operand + 1,
+ op_string);
+ return 0;
+ }
+ return 1; /* normal return */
+}
+
+/*
+ * md_estimate_size_before_relax()
+ *
+ * Called just before relax().
+ * Any symbol that is now undefined will not become defined.
+ * Return the correct fr_subtype in the frag.
+ * Return the initial "guess for fr_var" to caller.
+ * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ * Although it may not be explicit in the frag, pretend fr_var starts with a
+ * 0 value.
+ */
+int
+md_estimate_size_before_relax (fragP, segment)
+ register fragS *fragP;
+ register segT segment;
+{
+ register unsigned char *opcode;
+ register int old_fr_fix;
+
+ old_fr_fix = fragP->fr_fix;
+ opcode = (unsigned char *) fragP->fr_opcode;
+ /* We've already got fragP->fr_subtype right; all we have to do is
+ check for un-relaxable symbols. */
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
+ {
+ /* symbol is undefined in this segment */
+ int code16 = fragP->fr_subtype & CODE16;
+ int size = code16 ? 2 : 4;
+ int pcrel_reloc = code16 ? BFD_RELOC_16_PCREL : BFD_RELOC_32_PCREL;
+
+ switch (opcode[0])
+ {
+ case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */
+ opcode[0] = 0xe9; /* dword disp jmp */
+ fragP->fr_fix += size;
+ fix_new (fragP, old_fr_fix, size,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ (GOT_symbol && /* Not quite right - we should switch on
+ presence of @PLT, but I cannot see how
+ to get to that from here. We should have
+ done this in md_assemble to really
+ get it right all of the time, but I
+ think it does not matter that much, as
+ this will be right most of the time. ERY*/
+ S_GET_SEGMENT(fragP->fr_symbol) == undefined_section)
+ ? BFD_RELOC_386_PLT32 : pcrel_reloc);
+ break;
+
+ default:
+ /* This changes the byte-displacement jump 0x7N -->
+ the dword-displacement jump 0x0f8N */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE; /* two-byte escape */
+ fragP->fr_fix += 1 + size; /* we've added an opcode byte */
+ fix_new (fragP, old_fr_fix + 1, size,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ (GOT_symbol && /* Not quite right - we should switch on
+ presence of @PLT, but I cannot see how
+ to get to that from here. ERY */
+ S_GET_SEGMENT(fragP->fr_symbol) == undefined_section)
+ ? BFD_RELOC_386_PLT32 : pcrel_reloc);
+ break;
+ }
+ frag_wane (fragP);
+ }
+ return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
+} /* md_estimate_size_before_relax() */
+
+/*
+ * md_convert_frag();
+ *
+ * Called after relax() is finished.
+ * In: Address of frag.
+ * fr_type == rs_machine_dependent.
+ * fr_subtype is what the address relaxed to.
+ *
+ * Out: Any fixSs and constants are set up.
+ * Caller will turn frag into a ".space 0".
+ */
+#ifndef BFD_ASSEMBLER
+void
+md_convert_frag (headers, sec, fragP)
+ object_headers *headers;
+ segT sec;
+ register fragS *fragP;
+#else
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ register fragS *fragP;
+#endif
+{
+ register unsigned char *opcode;
+ unsigned char *where_to_put_displacement = NULL;
+ unsigned int target_address;
+ unsigned int opcode_address;
+ unsigned int extension = 0;
+ int displacement_from_opcode_start;
+
+ opcode = (unsigned char *) fragP->fr_opcode;
+
+ /* Address we want to reach in file space. */
+ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
+#ifdef BFD_ASSEMBLER /* not needed otherwise? */
+ target_address += fragP->fr_symbol->sy_frag->fr_address;
+#endif
+
+ /* Address opcode resides at in file space. */
+ opcode_address = fragP->fr_address + fragP->fr_fix;
+
+ /* Displacement from opcode start to fill into instruction. */
+ displacement_from_opcode_start = target_address - opcode_address;
+
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX_STATE (COND_JUMP, SMALL):
+ case ENCODE_RELAX_STATE (COND_JUMP, SMALL16):
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL):
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL16):
+ /* don't have to change opcode */
+ extension = 1; /* 1 opcode + 1 displacement */
+ where_to_put_displacement = &opcode[1];
+ break;
+
+ case ENCODE_RELAX_STATE (COND_JUMP, BIG):
+ extension = 5; /* 2 opcode + 4 displacement */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ where_to_put_displacement = &opcode[2];
+ break;
+
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG):
+ extension = 4; /* 1 opcode + 4 displacement */
+ opcode[0] = 0xe9;
+ where_to_put_displacement = &opcode[1];
+ break;
+
+ case ENCODE_RELAX_STATE (COND_JUMP, BIG16):
+ extension = 3; /* 2 opcode + 2 displacement */
+ opcode[1] = opcode[0] + 0x10;
+ opcode[0] = TWO_BYTE_OPCODE_ESCAPE;
+ where_to_put_displacement = &opcode[2];
+ break;
+
+ case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16):
+ extension = 2; /* 1 opcode + 2 displacement */
+ opcode[0] = 0xe9;
+ where_to_put_displacement = &opcode[1];
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+ /* now put displacement after opcode */
+ md_number_to_chars ((char *) where_to_put_displacement,
+ (valueT) (displacement_from_opcode_start - extension),
+ SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
+ fragP->fr_fix += extension;
+}
+
+
+int md_short_jump_size = 2; /* size of byte displacement jmp */
+int md_long_jump_size = 5; /* size of dword displacement jmp */
+const int md_reloc_size = 8; /* Size of relocation record */
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ long offset;
+
+ offset = to_addr - (from_addr + 2);
+ md_number_to_chars (ptr, (valueT) 0xeb, 1); /* opcode for byte-disp jump */
+ md_number_to_chars (ptr + 1, (valueT) offset, 1);
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ long offset;
+
+ if (flag_do_long_jump)
+ {
+ offset = to_addr - S_GET_VALUE (to_symbol);
+ md_number_to_chars (ptr, (valueT) 0xe9, 1);/* opcode for long jmp */
+ md_number_to_chars (ptr + 1, (valueT) offset, 4);
+ fix_new (frag, (ptr + 1) - frag->fr_literal, 4,
+ to_symbol, (offsetT) 0, 0, BFD_RELOC_32);
+ }
+ else
+ {
+ offset = to_addr - (from_addr + 5);
+ md_number_to_chars (ptr, (valueT) 0xe9, 1);
+ md_number_to_chars (ptr + 1, (valueT) offset, 4);
+ }
+}
+
+/* Apply a fixup (fixS) to segment data, once it has been determined
+ by our caller that we have all the info we need to fix it up.
+
+ On the 386, immediates, displacements, and data pointers are all in
+ the same (little-endian) format, so we don't need to care about which
+ we are handling. */
+
+int
+md_apply_fix3 (fixP, valp, seg)
+ fixS *fixP; /* The fix we're to put in. */
+ valueT *valp; /* Pointer to the value of the bits. */
+ segT seg; /* Segment fix is from. */
+{
+ register char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
+ valueT value = *valp;
+
+ if (fixP->fx_r_type == BFD_RELOC_32 && fixP->fx_pcrel)
+ fixP->fx_r_type = BFD_RELOC_32_PCREL;
+
+#if defined (BFD_ASSEMBLER) && !defined (TE_Mach)
+ /*
+ * This is a hack. There should be a better way to
+ * handle this.
+ */
+ if (fixP->fx_r_type == BFD_RELOC_32_PCREL && fixP->fx_addsy)
+ {
+#ifndef OBJ_AOUT
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+#ifdef TE_PE
+ || OUTPUT_FLAVOR == bfd_target_coff_flavour
+#endif
+ )
+ value += fixP->fx_where + fixP->fx_frag->fr_address;
+#endif
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && (S_GET_SEGMENT (fixP->fx_addsy) == seg
+ || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
+ && ! S_IS_EXTERNAL (fixP->fx_addsy)
+ && ! S_IS_WEAK (fixP->fx_addsy)
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && ! S_IS_COMMON (fixP->fx_addsy))
+ {
+ /* Yes, we add the values in twice. This is because
+ bfd_perform_relocation subtracts them out again. I think
+ bfd_perform_relocation is broken, but I don't dare change
+ it. FIXME. */
+ value += fixP->fx_where + fixP->fx_frag->fr_address;
+ }
+#endif
+#if defined (OBJ_COFF) && defined (TE_PE)
+ /* For some reason, the PE format does not store a section
+ address offset for a PC relative symbol. */
+ if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ value += md_pcrel_from (fixP);
+#endif
+ }
+
+ /* Fix a few things - the dynamic linker expects certain values here,
+ and we must not dissappoint it. */
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && fixP->fx_addsy)
+ switch (fixP->fx_r_type) {
+ case BFD_RELOC_386_PLT32:
+ /* Make the jump instruction point to the address of the operand. At
+ runtime we merely add the offset to the actual PLT entry. */
+ value = 0xfffffffc;
+ break;
+ case BFD_RELOC_386_GOTPC:
+/*
+ * This is tough to explain. We end up with this one if we have
+ * operands that look like "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal
+ * here is to obtain the absolute address of the GOT, and it is strongly
+ * preferable from a performance point of view to avoid using a runtime
+ * relocation for this. The actual sequence of instructions often look
+ * something like:
+ *
+ * call .L66
+ * .L66:
+ * popl %ebx
+ * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx
+ *
+ * The call and pop essentially return the absolute address of
+ * the label .L66 and store it in %ebx. The linker itself will
+ * ultimately change the first operand of the addl so that %ebx points to
+ * the GOT, but to keep things simple, the .o file must have this operand
+ * set so that it generates not the absolute address of .L66, but the
+ * absolute address of itself. This allows the linker itself simply
+ * treat a GOTPC relocation as asking for a pcrel offset to the GOT to be
+ * added in, and the addend of the relocation is stored in the operand
+ * field for the instruction itself.
+ *
+ * Our job here is to fix the operand so that it would add the correct
+ * offset so that %ebx would point to itself. The thing that is tricky is
+ * that .-.L66 will point to the beginning of the instruction, so we need
+ * to further modify the operand so that it will point to itself.
+ * There are other cases where you have something like:
+ *
+ * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66]
+ *
+ * and here no correction would be required. Internally in the assembler
+ * we treat operands of this form as not being pcrel since the '.' is
+ * explicitly mentioned, and I wonder whether it would simplify matters
+ * to do it this way. Who knows. In earlier versions of the PIC patches,
+ * the pcrel_adjust field was used to store the correction, but since the
+ * expression is not pcrel, I felt it would be confusing to do it this way.
+ */
+ value -= 1;
+ break;
+ case BFD_RELOC_386_GOT32:
+ value = 0; /* Fully resolved at runtime. No addend. */
+ break;
+ case BFD_RELOC_386_GOTOFF:
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return 1;
+
+ default:
+ break;
+ }
+#endif
+
+#endif
+ md_number_to_chars (p, value, fixP->fx_size);
+
+ return 1;
+}
+
+#if 0
+/* This is never used. */
+long /* Knows about the byte order in a word. */
+md_chars_to_number (con, nbytes)
+ unsigned char con[]; /* Low order byte 1st. */
+ int nbytes; /* Number of bytes in the input. */
+{
+ long retval;
+ for (retval = 0, con += nbytes - 1; nbytes--; con--)
+ {
+ retval <<= BITS_PER_CHAR;
+ retval |= *con;
+ }
+ return retval;
+}
+#endif /* 0 */
+
+
+#define MAX_LITTLENUMS 6
+
+/* Turn the string pointed to by litP into a floating point constant of type
+ type, and emit the appropriate bytes. The number of LITTLENUMS emitted
+ is stored in *sizeP . An error message is returned, or NULL on OK. */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 5;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to md_atof ()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
+ the bigendian 386. */
+ for (wordP = words + prec - 1; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+char output_invalid_buf[8];
+
+static char * output_invalid PARAMS ((int));
+
+static char *
+output_invalid (c)
+ int c;
+{
+ if (isprint (c))
+ sprintf (output_invalid_buf, "'%c'", c);
+ else
+ sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
+ return output_invalid_buf;
+}
+
+/* REG_STRING starts *before* REGISTER_PREFIX. */
+
+static const reg_entry * parse_register PARAMS ((char *, char **));
+
+static const reg_entry *
+parse_register (reg_string, end_op)
+ char *reg_string;
+ char **end_op;
+{
+ register char *s = reg_string;
+ register char *p;
+ char reg_name_given[MAX_REG_NAME_SIZE + 1];
+ const reg_entry *r;
+
+ /* Skip possible REGISTER_PREFIX and possible whitespace. */
+ if (*s == REGISTER_PREFIX)
+ ++s;
+
+ if (is_space_char (*s))
+ ++s;
+
+ p = reg_name_given;
+ while ((*p++ = register_chars[(unsigned char) *s++]) != '\0')
+ {
+ if (p >= reg_name_given + MAX_REG_NAME_SIZE)
+ {
+ if (!allow_naked_reg)
+ {
+ *p = '\0';
+ as_bad (_("bad register name `%s'"), reg_name_given);
+ }
+ return (const reg_entry *) NULL;
+ }
+ }
+
+ *end_op = s - 1;
+
+ r = (const reg_entry *) hash_find (reg_hash, reg_name_given);
+
+ if (r == NULL)
+ {
+ if (!allow_naked_reg)
+ as_bad (_("bad register name `%s'"), reg_name_given);
+ return (const reg_entry *) NULL;
+ }
+
+ return r;
+}
+
+#ifdef OBJ_ELF
+CONST char *md_shortopts = "kmVQ:";
+#else
+CONST char *md_shortopts = "m";
+#endif
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'm':
+ flag_do_long_jump = 1;
+ break;
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ /* -k: Ignore for FreeBSD compatibility. */
+ case 'k':
+ break;
+
+ /* -V: SVR4 argument to print version ID. */
+ case 'V':
+ print_version_id ();
+ break;
+
+ /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+ should be emitted or not. FIXME: Not implemented. */
+ case 'Q':
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, _("\
+-m do long jump\n"));
+}
+
+#ifdef BFD_ASSEMBLER
+#ifdef OBJ_MAYBE_ELF
+#ifdef OBJ_MAYBE_COFF
+
+/* Pick the target format to use. */
+
+const char *
+i386_target_format ()
+{
+ switch (OUTPUT_FLAVOR)
+ {
+ case bfd_target_coff_flavour:
+ return "coff-i386";
+ case bfd_target_elf_flavour:
+ return "elf32-i386";
+ default:
+ abort ();
+ return NULL;
+ }
+}
+
+#endif /* OBJ_MAYBE_COFF */
+#endif /* OBJ_MAYBE_ELF */
+#endif /* BFD_ASSEMBLER */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ if (*name == '_' && *(name+1) == 'G'
+ && strcmp(name, GLOBAL_OFFSET_TABLE_NAME) == 0)
+ {
+ if (!GOT_symbol)
+ {
+ if (symbol_find (name))
+ as_bad (_("GOT already in symbol table"));
+ GOT_symbol = symbol_new (name, undefined_section,
+ (valueT) 0, &zero_address_frag);
+ };
+ return GOT_symbol;
+ }
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+#ifdef OBJ_AOUT
+#ifdef BFD_ASSEMBLER
+ /* For a.out, force the section size to be aligned. If we don't do
+ this, BFD will align it for us, but it will not write out the
+ final bytes of the section. This may be a bug in BFD, but it is
+ easier to fix it here since that is how the other a.out targets
+ work. */
+ int align;
+
+ align = bfd_get_section_alignment (stdoutput, segment);
+ size = ((size + (1 << align) - 1) & ((valueT) -1 << align));
+#endif
+#endif
+
+ return size;
+}
+
+/* On the i386, PC-relative offsets are relative to the start of the
+ next instruction. That is, the address of the offset, plus its
+ size, since the offset is always the last part of the insn. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+#ifndef I386COFF
+
+static void
+s_bss (ignore)
+ int ignore;
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ subseg_set (bss_section, (subsegT) temp);
+ demand_empty_rest_of_line ();
+}
+
+#endif
+
+
+#ifdef BFD_ASSEMBLER
+
+void
+i386_validate_fix (fixp)
+ fixS *fixp;
+{
+ if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol)
+ {
+ fixp->fx_r_type = BFD_RELOC_386_GOTOFF;
+ fixp->fx_subsy = 0;
+ }
+}
+
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type code;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_386_PLT32:
+ case BFD_RELOC_386_GOT32:
+ case BFD_RELOC_386_GOTOFF:
+ case BFD_RELOC_386_GOTPC:
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ code = fixp->fx_r_type;
+ break;
+ default:
+ switch (F (fixp->fx_size, fixp->fx_pcrel))
+ {
+ MAP (1, 0, BFD_RELOC_8);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (4, 0, BFD_RELOC_32);
+ MAP (1, 1, BFD_RELOC_8_PCREL);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 1, BFD_RELOC_32_PCREL);
+ default:
+ if (fixp->fx_pcrel)
+ as_bad (_("Can not do %d byte pc-relative relocation"),
+ fixp->fx_size);
+ else
+ as_bad (_("Can not do %d byte relocation"), fixp->fx_size);
+ code = BFD_RELOC_32;
+ break;
+ }
+ break;
+ }
+#undef MAP
+#undef F
+
+ if (code == BFD_RELOC_32
+ && GOT_symbol
+ && fixp->fx_addsy == GOT_symbol)
+ code = BFD_RELOC_386_GOTPC;
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ /* HACK: Since i386 ELF uses Rel instead of Rela, encode the
+ vtable entry to be used in the relocation's section offset. */
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ rel->address = fixp->fx_offset;
+
+ if (fixp->fx_pcrel)
+ rel->addend = fixp->fx_addnumber;
+ else
+ rel->addend = 0;
+
+ rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (rel->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (code));
+ /* Set howto to a garbage value so that we can keep going. */
+ rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ assert (rel->howto != NULL);
+ }
+
+ return rel;
+}
+
+#else /* ! BFD_ASSEMBLER */
+
+#if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ /*
+ * In: length of relocation (or of address) in chars: 1, 2 or 4.
+ * Out: GNU LD relocation length code: 0, 1, or 2.
+ */
+
+ static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
+ long r_symbolnum;
+
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ (valueT) (fixP->fx_frag->fr_address
+ + fixP->fx_where - segment_address_in_file),
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ where[6] = (r_symbolnum >> 16) & 0x0ff;
+ where[5] = (r_symbolnum >> 8) & 0x0ff;
+ where[4] = r_symbolnum & 0x0ff;
+ where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
+ | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
+ | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
+}
+
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+#if defined (I386COFF)
+
+short
+tc_coff_fix2rtype (fixP)
+ fixS *fixP;
+{
+ if (fixP->fx_r_type == R_IMAGEBASE)
+ return R_IMAGEBASE;
+
+ return (fixP->fx_pcrel ?
+ (fixP->fx_size == 1 ? R_PCRBYTE :
+ fixP->fx_size == 2 ? R_PCRWORD :
+ R_PCRLONG) :
+ (fixP->fx_size == 1 ? R_RELBYTE :
+ fixP->fx_size == 2 ? R_RELWORD :
+ R_DIR32));
+}
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ if (frag->fr_next)
+ return (frag->fr_next->fr_address - frag->fr_address);
+ else
+ return 0;
+}
+
+#endif /* I386COFF */
+
+#endif /* BFD_ASSEMBLER? */
+
+/* end of tc-i386.c */
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
new file mode 100644
index 00000000000..d876d61b6f2
--- /dev/null
+++ b/gas/config/tc-i386.h
@@ -0,0 +1,471 @@
+/* tc-i386.h -- Header file for tc-i386.c
+ Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef TC_I386
+#define TC_I386 1
+
+#ifdef ANSI_PROTOTYPES
+struct fix;
+#endif
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifdef TE_LYNX
+#define TARGET_FORMAT "coff-i386-lynx"
+#endif
+
+#ifdef BFD_ASSEMBLER
+/* This is used to determine relocation types in tc-i386.c. The first
+ parameter is the current relocation type, the second one is the desired
+ type. The idea is that if the original type is already some kind of PIC
+ relocation, we leave it alone, otherwise we give it the desired type */
+
+#define TC_RELOC(X,Y) (((X) != BFD_RELOC_386_PLT32 && \
+ (X) != BFD_RELOC_386_GOTOFF && \
+ (X) != BFD_RELOC_386_GOT32 && \
+ (X) != BFD_RELOC_386_GOTPC) ? Y : X)
+
+#define tc_fix_adjustable(X) tc_i386_fix_adjustable(X)
+extern int tc_i386_fix_adjustable PARAMS ((struct fix *));
+
+/* This is the relocation type for direct references to GLOBAL_OFFSET_TABLE.
+ * It comes up in complicated expressions such as
+ * _GLOBAL_OFFSET_TABLE_+[.-.L284], which cannot be expressed normally with
+ * the regular expressions. The fixup specified here when used at runtime
+ * implies that we should add the address of the GOT to the specified location,
+ * and as a result we have simplified the expression into something we can use.
+ */
+#define TC_RELOC_GLOBAL_OFFSET_TABLE BFD_RELOC_386_GOTPC
+
+/* This expression evaluates to false if the relocation is for a local object
+ for which we still want to do the relocation at runtime. True if we
+ are willing to perform this relocation while building the .o file.
+ This is only used for pcrel relocations, so GOTOFF does not need to be
+ checked here. I am not sure if some of the others are ever used with
+ pcrel, but it is easier to be safe than sorry. */
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ((FIX)->fx_r_type != BFD_RELOC_386_PLT32 \
+ && (FIX)->fx_r_type != BFD_RELOC_386_GOT32 \
+ && (FIX)->fx_r_type != BFD_RELOC_386_GOTPC \
+ && ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy))))
+
+#define TARGET_ARCH bfd_arch_i386
+
+#ifdef OBJ_AOUT
+#ifdef TE_NetBSD
+#define TARGET_FORMAT "a.out-i386-netbsd"
+#endif
+#ifdef TE_386BSD
+#define TARGET_FORMAT "a.out-i386-bsd"
+#endif
+#ifdef TE_LINUX
+#define TARGET_FORMAT "a.out-i386-linux"
+#endif
+#ifdef TE_Mach
+#define TARGET_FORMAT "a.out-mach3"
+#endif
+#ifdef TE_DYNIX
+#define TARGET_FORMAT "a.out-i386-dynix"
+#endif
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "a.out-i386"
+#endif
+#endif /* OBJ_AOUT */
+
+#ifdef OBJ_ELF
+#define TARGET_FORMAT "elf32-i386"
+#endif
+
+#ifdef OBJ_MAYBE_ELF
+#ifdef OBJ_MAYBE_COFF
+extern const char *i386_target_format PARAMS ((void));
+#define TARGET_FORMAT i386_target_format ()
+#endif
+#endif
+
+#else /* ! BFD_ASSEMBLER */
+
+/* COFF STUFF */
+
+#define COFF_MAGIC I386MAGIC
+#define BFD_ARCH bfd_arch_i386
+#define COFF_FLAGS F_AR32WR
+#define TC_COUNT_RELOC(x) ((x)->fx_addsy || (x)->fx_r_type==7)
+#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
+extern short tc_coff_fix2rtype PARAMS ((struct fix *));
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+extern int tc_coff_sizemachdep PARAMS ((fragS *frag));
+#define SUB_SEGMENT_ALIGN(SEG) 2
+#define TC_RVA_RELOC 7
+/* Need this for PIC relocations */
+#define NEED_FX_R_TYPE
+
+
+#ifdef TE_386BSD
+/* The BSDI linker apparently rejects objects with a machine type of
+ M_386 (100). */
+#define AOUT_MACHTYPE 0
+#else
+#define AOUT_MACHTYPE 100
+#endif
+
+#undef REVERSE_SORT_RELOCS
+
+#endif /* ! BFD_ASSEMBLER */
+
+#define TC_FORCE_RELOCATION(fixp) tc_i386_force_relocation(fixp)
+extern int tc_i386_force_relocation PARAMS ((struct fix *));
+
+#ifdef BFD_ASSEMBLER
+#define NO_RELOC BFD_RELOC_NONE
+#else
+#define NO_RELOC 0
+#endif
+#define tc_coff_symbol_emit_hook(a) ; /* not used */
+
+#ifndef BFD_ASSEMBLER
+#ifndef OBJ_AOUT
+#ifndef TE_PE
+#ifndef TE_GO32
+/* Local labels starts with .L */
+#define LOCAL_LABEL(name) (name[0] == '.' \
+ && (name[1] == 'L' || name[1] == 'X' || name[1] == '.'))
+#endif
+#endif
+#endif
+#endif
+
+#define LOCAL_LABELS_FB 1
+
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+#define tc_crawl_symbol_chain(a) {;} /* not used */
+#define tc_headers_hook(a) {;} /* not used */
+
+extern const char extra_symbol_chars[];
+#define tc_symbol_chars extra_symbol_chars
+
+#define MAX_OPERANDS 3 /* max operands per insn */
+#define MAX_IMMEDIATE_OPERANDS 2/* max immediates per insn (lcall, ljmp) */
+#define MAX_MEMORY_OPERANDS 2 /* max memory refs per insn (string ops) */
+
+/* Prefixes will be emitted in the order defined below.
+ WAIT_PREFIX must be the first prefix since FWAIT is really is an
+ instruction, and so must come before any prefixes. */
+#define WAIT_PREFIX 0
+#define LOCKREP_PREFIX 1
+#define ADDR_PREFIX 2
+#define DATA_PREFIX 3
+#define SEG_PREFIX 4
+#define MAX_PREFIXES 5 /* max prefixes per opcode */
+
+/* we define the syntax here (modulo base,index,scale syntax) */
+#define REGISTER_PREFIX '%'
+#define IMMEDIATE_PREFIX '$'
+#define ABSOLUTE_PREFIX '*'
+
+#define TWO_BYTE_OPCODE_ESCAPE 0x0f
+#define NOP_OPCODE (char) 0x90
+
+/* register numbers */
+#define EBP_REG_NUM 5
+#define ESP_REG_NUM 4
+
+/* modrm_byte.regmem for twobyte escape */
+#define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM
+/* index_base_byte.index for no index register addressing */
+#define NO_INDEX_REGISTER ESP_REG_NUM
+/* index_base_byte.base for no base register addressing */
+#define NO_BASE_REGISTER EBP_REG_NUM
+#define NO_BASE_REGISTER_16 6
+
+/* these are the instruction mnemonic suffixes. */
+#define DWORD_MNEM_SUFFIX 'l'
+#define WORD_MNEM_SUFFIX 'w'
+#define BYTE_MNEM_SUFFIX 'b'
+#define SHORT_MNEM_SUFFIX 's'
+#define LONG_MNEM_SUFFIX 'l'
+/* Intel Syntax */
+#define LONG_DOUBLE_MNEM_SUFFIX 'x'
+/* Intel Syntax */
+#define INTEL_DWORD_MNEM_SUFFIX 'd'
+
+/* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */
+#define REGMEM_FIELD_HAS_REG 0x3/* always = 0x3 */
+#define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG)
+
+#define END_OF_INSN '\0'
+
+/* Intel Syntax */
+/* Values 0-4 map onto scale factor */
+#define BYTE_PTR 0
+#define WORD_PTR 1
+#define DWORD_PTR 2
+#define QWORD_PTR 3
+#define XWORD_PTR 4
+#define SHORT 5
+#define OFFSET_FLAT 6
+#define FLAT 7
+#define NONE_FOUND 8
+/*
+ When an operand is read in it is classified by its type. This type includes
+ all the possible ways an operand can be used. Thus, '%eax' is both 'register
+ # 0' and 'The Accumulator'. In our language this is expressed by OR'ing
+ 'Reg32' (any 32 bit register) and 'Acc' (the accumulator).
+ Operands are classified so that we can match given operand types with
+ the opcode table in opcode/i386.h.
+ */
+/* register */
+#define Reg8 0x1 /* 8 bit reg */
+#define Reg16 0x2 /* 16 bit reg */
+#define Reg32 0x4 /* 32 bit reg */
+/* immediate */
+#define Imm8 0x8 /* 8 bit immediate */
+#define Imm8S 0x10 /* 8 bit immediate sign extended */
+#define Imm16 0x20 /* 16 bit immediate */
+#define Imm32 0x40 /* 32 bit immediate */
+#define Imm1 0x80 /* 1 bit immediate */
+/* memory */
+#define BaseIndex 0x100
+/* Disp8,16,32 are used in different ways, depending on the
+ instruction. For jumps, they specify the size of the PC relative
+ displacement, for baseindex type instructions, they specify the
+ size of the offset relative to the base register, and for memory
+ offset instructions such as `mov 1234,%al' they specify the size of
+ the offset relative to the segment base. */
+#define Disp8 0x200 /* 8 bit displacement */
+#define Disp16 0x400 /* 16 bit displacement */
+#define Disp32 0x800 /* 32 bit displacement */
+/* specials */
+#define InOutPortReg 0x1000 /* register to hold in/out port addr = dx */
+#define ShiftCount 0x2000 /* register to hold shift cound = cl */
+#define Control 0x4000 /* Control register */
+#define Debug 0x8000 /* Debug register */
+#define Test 0x10000 /* Test register */
+#define FloatReg 0x20000 /* Float register */
+#define FloatAcc 0x40000 /* Float stack top %st(0) */
+#define SReg2 0x80000 /* 2 bit segment register */
+#define SReg3 0x100000 /* 3 bit segment register */
+#define Acc 0x200000 /* Accumulator %al or %ax or %eax */
+#define JumpAbsolute 0x400000
+#define RegMMX 0x800000 /* MMX register */
+#define EsSeg 0x1000000 /* String insn operand with fixed es segment */
+
+#define Reg (Reg8|Reg16|Reg32) /* gen'l register */
+#define WordReg (Reg16|Reg32)
+#define ImplicitRegister (InOutPortReg|ShiftCount|Acc|FloatAcc)
+#define Imm (Imm8|Imm8S|Imm16|Imm32) /* gen'l immediate */
+#define Disp (Disp8|Disp16|Disp32) /* General displacement */
+#define AnyMem (Disp|BaseIndex) /* General memory */
+/* The following aliases are defined because the opcode table
+ carefully specifies the allowed memory types for each instruction.
+ At the moment we can only tell a memory reference size by the
+ instruction suffix, so there's not much point in defining Mem8,
+ Mem16, Mem32 and Mem64 opcode modifiers - We might as well just use
+ the suffix directly to check memory operands. */
+#define LLongMem AnyMem /* 64 bits (or more) */
+#define LongMem AnyMem /* 32 bit memory ref */
+#define ShortMem AnyMem /* 16 bit memory ref */
+#define WordMem AnyMem /* 16 or 32 bit memory ref */
+#define ByteMem AnyMem /* 8 bit memory ref */
+
+#define SMALLEST_DISP_TYPE(num) \
+ (fits_in_signed_byte(num) ? (Disp8|Disp32) : Disp32)
+
+typedef struct
+{
+ /* instruction name sans width suffix ("mov" for movl insns) */
+ char *name;
+
+ /* how many operands */
+ unsigned int operands;
+
+ /* base_opcode is the fundamental opcode byte without optional
+ prefix(es). */
+ unsigned int base_opcode;
+
+ /* extension_opcode is the 3 bit extension for group <n> insns.
+ This field is also used to store the 8-bit opcode suffix for the
+ AMD 3DNow! instructions.
+ If this template has no extension opcode (the usual case) use None */
+ unsigned int extension_opcode;
+#define None 0xffff /* If no extension_opcode is possible. */
+
+ /* the bits in opcode_modifier are used to generate the final opcode from
+ the base_opcode. These bits also are used to detect alternate forms of
+ the same instruction */
+ unsigned int opcode_modifier;
+
+ /* opcode_modifier bits: */
+#define W 0x1 /* set if operands can be words or dwords
+ encoded the canonical way */
+#define D 0x2 /* D = 0 if Reg --> Regmem;
+ D = 1 if Regmem --> Reg: MUST BE 0x2 */
+#define Modrm 0x4
+#define ReverseRegRegmem 0x8 /* swap reg,regmem fields for 2 reg case */
+#define FloatR 0x8 /* src/dest swap for floats: MUST BE 0x8 */
+#define ShortForm 0x10 /* register is in low 3 bits of opcode */
+#define FloatMF 0x20 /* FP insn memory format bit, sized by 0x4 */
+#define Jump 0x40 /* special case for jump insns. */
+#define JumpDword 0x80 /* call and jump */
+#define JumpByte 0x100 /* loop and jecxz */
+#define JumpInterSegment 0x200 /* special case for intersegment leaps/calls */
+#define FloatD 0x400 /* direction for float insns: MUST BE 0x400 */
+#define Seg2ShortForm 0x800 /* encoding of load segment reg insns */
+#define Seg3ShortForm 0x1000 /* fs/gs segment register insns. */
+#define Size16 0x2000 /* needs size prefix if in 32-bit mode */
+#define Size32 0x4000 /* needs size prefix if in 16-bit mode */
+#define IgnoreSize 0x8000 /* instruction ignores operand size prefix */
+#define No_bSuf 0x10000 /* b suffix on instruction illegal */
+#define No_wSuf 0x20000 /* w suffix on instruction illegal */
+#define No_lSuf 0x40000 /* l suffix on instruction illegal */
+#define No_sSuf 0x80000 /* s suffix on instruction illegal */
+#define FWait 0x100000 /* instruction needs FWAIT */
+#define IsString 0x200000 /* quick test for string instructions */
+#define regKludge 0x400000 /* fake an extra reg operand for clr, imul */
+#define IsPrefix 0x800000 /* opcode is a prefix */
+#define No_dSuf 0x1000000 /* d suffix on instruction illegal */
+#define No_xSuf 0x2000000 /* x suffix on instruction illegal */
+#define Ugh 0x80000000 /* deprecated fp insn, gets a warning */
+
+ /* operand_types[i] describes the type of operand i. This is made
+ by OR'ing together all of the possible type masks. (e.g.
+ 'operand_types[i] = Reg|Imm' specifies that operand i can be
+ either a register or an immediate operand */
+ unsigned int operand_types[3];
+}
+template;
+
+/*
+ 'templates' is for grouping together 'template' structures for opcodes
+ of the same name. This is only used for storing the insns in the grand
+ ole hash table of insns.
+ The templates themselves start at START and range up to (but not including)
+ END.
+ */
+typedef struct
+ {
+ const template *start;
+ const template *end;
+ } templates;
+
+/* these are for register name --> number & type hash lookup */
+typedef struct
+ {
+ char *reg_name;
+ unsigned int reg_type;
+ unsigned int reg_num;
+ }
+reg_entry;
+
+typedef struct
+ {
+ char *seg_name;
+ unsigned int seg_prefix;
+ }
+seg_entry;
+
+/* 386 operand encoding bytes: see 386 book for details of this. */
+typedef struct
+ {
+ unsigned int regmem; /* codes register or memory operand */
+ unsigned int reg; /* codes register operand (or extended opcode) */
+ unsigned int mode; /* how to interpret regmem & reg */
+ }
+modrm_byte;
+
+/* 386 opcode byte to code indirect addressing. */
+typedef struct
+ {
+ unsigned base;
+ unsigned index;
+ unsigned scale;
+ }
+sib_byte;
+
+/* The name of the global offset table generated by the compiler. Allow
+ this to be overridden if need be. */
+#ifndef GLOBAL_OFFSET_TABLE_NAME
+#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
+#endif
+
+#ifdef BFD_ASSEMBLER
+void i386_validate_fix PARAMS ((struct fix *));
+#define TC_VALIDATE_FIX(FIXP,SEGTYPE,SKIP) i386_validate_fix(FIXP)
+#endif
+
+#endif /* TC_I386 */
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+
+extern int flag_16bit_code;
+
+#ifdef BFD_ASSEMBLER
+#define md_maybe_text() \
+ ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+#else
+#define md_maybe_text() \
+ (now_seg != data_section && now_seg != bss_section)
+#endif
+
+#define md_do_align(n, fill, len, max, around) \
+if ((n) && !need_pass_2 \
+ && (!(fill) || ((char)*(fill) == (char)0x90 && (len) == 1)) \
+ && md_maybe_text ()) \
+ { \
+ char *p; \
+ p = frag_var (rs_align_code, 15, 1, (relax_substateT) max, \
+ (symbolS *) 0, (offsetT) (n), (char *) 0); \
+ *p = 0x90; \
+ goto around; \
+ }
+
+extern void i386_align_code PARAMS ((fragS *, int));
+
+#define HANDLE_ALIGN(fragP) \
+if (fragP->fr_type == rs_align_code) \
+ i386_align_code (fragP, (fragP->fr_next->fr_address \
+ - fragP->fr_address \
+ - fragP->fr_fix));
+
+/* call md_apply_fix3 with segment instead of md_apply_fix */
+#define MD_APPLY_FIX3
+
+void i386_print_statistics PARAMS ((FILE *));
+#define tc_print_statistics i386_print_statistics
+
+#define md_number_to_chars number_to_chars_littleendian
+
+#ifdef SCO_ELF
+#define tc_init_after_args() sco_id ()
+extern void sco_id PARAMS ((void));
+#endif
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
+/* end of tc-i386.h */
diff --git a/gas/config/tc-i860.c b/gas/config/tc-i860.c
new file mode 100644
index 00000000000..f2e2b192721
--- /dev/null
+++ b/gas/config/tc-i860.c
@@ -0,0 +1,1263 @@
+/* tc-i860.c -- Assemble for the I860
+ Copyright (C) 1989, 92, 93, 94, 95, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+
+#include "opcode/i860.h"
+
+void md_begin ();
+void md_number_to_chars ();
+void md_assemble ();
+char *md_atof ();
+void md_convert_frag ();
+int md_estimate_size_before_relax ();
+void md_number_to_imm ();
+void md_number_to_disp ();
+void md_number_to_field ();
+void md_ri_to_chars ();
+static void i860_ip ();
+/* void emit_machine_reloc(); */
+
+const int md_reloc_size = sizeof (struct relocation_info);
+
+/* void (*md_emit_relocations)() = emit_machine_reloc; */
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+static void s_dual (), s_enddual ();
+static void s_atmp ();
+
+const pseudo_typeS
+ md_pseudo_table[] =
+{
+ {"dual", s_dual, 4},
+ {"enddual", s_enddual, 4},
+ {"atmp", s_atmp, 4},
+ {NULL, 0, 0},
+};
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = "!/"; /* JF removed '|' from comment_chars */
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments like this one will always work. */
+const char line_comment_chars[] = "#/";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c . Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here.
+ */
+int size_reloc_info = sizeof (struct relocation_info);
+
+static unsigned char octal[256];
+#define isoctal(c) octal[c]
+static unsigned char toHex[256];
+
+struct i860_it
+ {
+ char *error;
+ unsigned long opcode;
+ struct nlist *nlistp;
+ expressionS exp;
+ int pcrel;
+ enum expand_type expand;
+ enum highlow_type highlow;
+ enum reloc_type reloc;
+ } the_insn;
+
+#if __STDC__ == 1
+
+static void print_insn (struct i860_it *insn);
+static int getExpression (char *str);
+
+#else /* not __STDC__ */
+
+static void print_insn ();
+static int getExpression ();
+
+#endif /* not __STDC__ */
+
+static char *expr_end;
+static char last_expand; /* error if expansion after branch */
+
+enum dual
+{
+ DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
+};
+static enum dual dual_mode = DUAL_OFF; /* dual-instruction mode */
+
+static void
+s_dual () /* floating point instructions have dual set */
+{
+ dual_mode = DUAL_ON;
+}
+
+static void
+s_enddual () /* floating point instructions have dual set */
+{
+ dual_mode = DUAL_OFF;
+}
+
+static int atmp = 31; /* temporary register for pseudo's */
+
+static void
+s_atmp ()
+{
+ register int temp;
+ if (strncmp (input_line_pointer, "sp", 2) == 0)
+ {
+ input_line_pointer += 2;
+ atmp = 2;
+ }
+ else if (strncmp (input_line_pointer, "fp", 2) == 0)
+ {
+ input_line_pointer += 2;
+ atmp = 3;
+ }
+ else if (strncmp (input_line_pointer, "r", 1) == 0)
+ {
+ input_line_pointer += 1;
+ temp = get_absolute_expression ();
+ if (temp >= 0 && temp <= 31)
+ atmp = temp;
+ else
+ as_bad (_("Unknown temporary pseudo register"));
+ }
+ else
+ {
+ as_bad (_("Unknown temporary pseudo register"));
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need. */
+void
+md_begin ()
+{
+ register char *retval = NULL;
+ int lose = 0;
+ register unsigned int i = 0;
+
+ op_hash = hash_new ();
+
+ while (i < NUMOPCODES)
+ {
+ const char *name = i860_opcodes[i].name;
+ retval = hash_insert (op_hash, name, &i860_opcodes[i]);
+ if (retval != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ i860_opcodes[i].name, retval);
+ lose = 1;
+ }
+ do
+ {
+ if (i860_opcodes[i].match & i860_opcodes[i].lose)
+ {
+ fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),
+ i860_opcodes[i].name, i860_opcodes[i].args);
+ lose = 1;
+ }
+ ++i;
+ }
+ while (i < NUMOPCODES
+ && !strcmp (i860_opcodes[i].name, name));
+ }
+
+ if (lose)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ for (i = '0'; i < '8'; ++i)
+ octal[i] = 1;
+ for (i = '0'; i <= '9'; ++i)
+ toHex[i] = i - '0';
+ for (i = 'a'; i <= 'f'; ++i)
+ toHex[i] = i + 10 - 'a';
+ for (i = 'A'; i <= 'F'; ++i)
+ toHex[i] = i + 10 - 'A';
+}
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *toP;
+ int rsd;
+ int no_opcodes = 1;
+ int i;
+ struct i860_it pseudo[3];
+
+ assert (str);
+ i860_ip (str);
+
+ /* check for expandable flag to produce pseudo-instructions */
+ if (the_insn.expand != 0 && the_insn.highlow == NO_SPEC)
+ {
+ for (i = 0; i < 3; i++)
+ pseudo[i] = the_insn;
+
+ switch (the_insn.expand)
+ {
+
+ case E_DELAY:
+ no_opcodes = 1;
+ break;
+
+ case E_MOV:
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_op_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 15) &&
+ the_insn.exp.X_add_number >= -(1 << 15)))
+ break;
+ /* or l%const,r0,ireg_dest */
+ pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
+ pseudo[0].highlow = PAIR;
+ /* orh h%const,ireg_dest,ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 |
+ ((the_insn.opcode & 0x001f0000) << 5);
+ pseudo[1].highlow = HIGH;
+ no_opcodes = 2;
+ break;
+
+ case E_ADDR:
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_op_symbol == NULL)
+ break;
+ /* orh ha%addr_expr,r0,r31 */
+ pseudo[0].opcode = 0xec000000 | (atmp << 16);
+ pseudo[0].highlow = HIGHADJ;
+ pseudo[0].reloc = LOW0; /* must overwrite */
+ /* l%addr_expr(r31),ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & ~0x003e0000) | (atmp << 21);
+ pseudo[1].highlow = PAIR;
+ no_opcodes = 2;
+ break;
+
+ case E_U32: /* 2nd version emulates Intel as, not doc. */
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_op_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 16) &&
+ the_insn.exp.X_add_number >= 0))
+ break;
+ /* $(opcode)h h%const,ireg_src2,ireg_dest
+ pseudo[0].opcode = (the_insn.opcode & 0xf3ffffff) | 0x0c000000; */
+ /* $(opcode)h h%const,ireg_src2,r31 */
+ pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 |
+ (atmp << 16);
+ pseudo[0].highlow = HIGH;
+ /* $(opcode) l%const,ireg_dest,ireg_dest
+ pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
+ ((the_insn.opcode & 0x001f0000) << 5); */
+ /* $(opcode) l%const,r31,ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
+ (atmp << 21);
+ pseudo[1].highlow = PAIR;
+ no_opcodes = 2;
+ break;
+
+ case E_AND: /* 2nd version emulates Intel as, not doc. */
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_op_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 16) &&
+ the_insn.exp.X_add_number >= 0))
+ break;
+ /* andnot h%const,ireg_src2,ireg_dest
+ pseudo[0].opcode = (the_insn.opcode & 0x03ffffff) | 0xd4000000; */
+ /* andnot h%const,ireg_src2,r31 */
+ pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 |
+ (atmp << 16);
+ pseudo[0].highlow = HIGH;
+ pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number;
+ /* andnot l%const,ireg_dest,ireg_dest
+ pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
+ ((the_insn.opcode & 0x001f0000) << 5); */
+ /* andnot l%const,r31,ireg_dest */
+ pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
+ (atmp << 21);
+ pseudo[1].highlow = PAIR;
+ pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number;
+ no_opcodes = 2;
+ break;
+
+ case E_S32:
+ if (the_insn.exp.X_add_symbol == NULL &&
+ the_insn.exp.X_op_symbol == NULL &&
+ (the_insn.exp.X_add_number < (1 << 15) &&
+ the_insn.exp.X_add_number >= -(1 << 15)))
+ break;
+ /* orh h%const,r0,r31 */
+ pseudo[0].opcode = 0xec000000 | (atmp << 16);
+ pseudo[0].highlow = HIGH;
+ /* or l%const,r31,r31 */
+ pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
+ pseudo[1].highlow = PAIR;
+ /* r31,ireg_src2,ireg_dest */
+ pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
+ pseudo[2].reloc = NO_RELOC;
+ no_opcodes = 3;
+ break;
+
+ default:
+ as_fatal (_("failed sanity check."));
+ }
+
+ the_insn = pseudo[0];
+ /* check for expanded opcode after branch or in dual */
+ if (no_opcodes > 1 && last_expand == 1)
+ as_warn (_("Expanded opcode after delayed branch: `%s'"), str);
+ if (no_opcodes > 1 && dual_mode != DUAL_OFF)
+ as_warn (_("Expanded opcode in dual mode: `%s'"), str);
+ }
+
+ i = 0;
+ do
+ { /* always produce at least one opcode */
+ toP = frag_more (4);
+ /* put out the opcode */
+ md_number_to_chars (toP, the_insn.opcode, 4);
+
+ /* check for expanded opcode after branch or in dual */
+ last_expand = the_insn.pcrel;
+
+ /* put out the symbol-dependent stuff */
+ if (the_insn.reloc != NO_RELOC)
+ {
+ fix_new (frag_now, /* which frag */
+ (toP - frag_now->fr_literal), /* where */
+ 4, /* size */
+ &the_insn.exp,
+ the_insn.pcrel,
+ /* merge bit fields into one argument */
+ (int) (((the_insn.highlow & 0x3) << 4) | (the_insn.reloc & 0xf)));
+ }
+ the_insn = pseudo[++i];
+ }
+ while (--no_opcodes > 0);
+
+}
+
+static void
+i860_ip (str)
+ char *str;
+{
+ char *s;
+ const char *args;
+ char c;
+ unsigned long i;
+ struct i860_opcode *insn;
+ char *argsStart;
+ unsigned long opcode;
+ unsigned int mask;
+ int match = 0;
+ int comma = 0;
+
+
+ for (s = str; islower (*s) || *s == '.' || *s == '3'; ++s)
+ ;
+ switch (*s)
+ {
+
+ case '\0':
+ break;
+
+ case ',':
+ comma = 1;
+
+ /*FALLTHROUGH*/
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ default:
+ as_fatal (_("Unknown opcode: `%s'"), str);
+ }
+
+ if (strncmp (str, "d.", 2) == 0)
+ { /* check for d. opcode prefix */
+ if (dual_mode == DUAL_ON)
+ dual_mode = DUAL_ONDDOT;
+ else
+ dual_mode = DUAL_DDOT;
+ str += 2;
+ }
+
+ if ((insn = (struct i860_opcode *) hash_find (op_hash, str)) == NULL)
+ {
+ if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
+ str -= 2;
+ as_bad (_("Unknown opcode: `%s'"), str);
+ return;
+ }
+ if (comma)
+ {
+ *--s = ',';
+ }
+ argsStart = s;
+ for (;;)
+ {
+ opcode = insn->match;
+ memset (&the_insn, '\0', sizeof (the_insn));
+ the_insn.reloc = NO_RELOC;
+
+ /*
+ * Build the opcode, checking as we go to make
+ * sure that the operands match
+ */
+ for (args = insn->args;; ++args)
+ {
+ switch (*args)
+ {
+
+ case '\0': /* end of args */
+ if (*s == '\0')
+ {
+ match = 1;
+ }
+ break;
+
+ case '+':
+ case '(': /* these must match exactly */
+ case ')':
+ case ',':
+ case ' ':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '#': /* must be at least one digit */
+ if (isdigit (*s++))
+ {
+ while (isdigit (*s))
+ {
+ ++s;
+ }
+ continue;
+ }
+ break;
+
+ case '1': /* next operand must be a register */
+ case '2':
+ case 'd':
+ switch (*s)
+ {
+
+ case 'f': /* frame pointer */
+ s++;
+ if (*s++ == 'p')
+ {
+ mask = 0x3;
+ break;
+ }
+ goto error;
+
+ case 's': /* stack pointer */
+ s++;
+ if (*s++ == 'p')
+ {
+ mask = 0x2;
+ break;
+ }
+ goto error;
+
+ case 'r': /* any register */
+ s++;
+ if (!isdigit (c = *s++))
+ {
+ goto error;
+ }
+ if (isdigit (*s))
+ {
+ if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
+ {
+ goto error;
+ }
+ }
+ else
+ {
+ c -= '0';
+ }
+ mask = c;
+ break;
+
+ default: /* not this opcode */
+ goto error;
+ }
+ /*
+ * Got the register, now figure out where
+ * it goes in the opcode.
+ */
+ switch (*args)
+ {
+
+ case '1':
+ opcode |= mask << 11;
+ continue;
+
+ case '2':
+ opcode |= mask << 21;
+ continue;
+
+ case 'd':
+ opcode |= mask << 16;
+ continue;
+
+ }
+ break;
+
+ case 'e': /* next operand is a floating point register */
+ case 'f':
+ case 'g':
+ if (*s++ == 'f' && isdigit (*s))
+ {
+ mask = *s++;
+ if (isdigit (*s))
+ {
+ mask = 10 * (mask - '0') + (*s++ - '0');
+ if (mask >= 32)
+ {
+ break;
+ }
+ }
+ else
+ {
+ mask -= '0';
+ }
+ switch (*args)
+ {
+
+ case 'e':
+ opcode |= mask << 11;
+ continue;
+
+ case 'f':
+ opcode |= mask << 21;
+ continue;
+
+ case 'g':
+ opcode |= mask << 16;
+ if (dual_mode != DUAL_OFF)
+ opcode |= (1 << 9); /* dual mode instruction */
+ if (dual_mode == DUAL_DDOT)
+ dual_mode = DUAL_OFF;
+ if (dual_mode == DUAL_ONDDOT)
+ dual_mode = DUAL_ON;
+ if ((opcode & (1 << 10)) && (mask == ((opcode >> 11) & 0x1f)))
+ as_warn (_("Fsr1 equals fdest with Pipelining"));
+ continue;
+ }
+ }
+ break;
+
+ case 'c': /* next operand must be a control register */
+ if (strncmp (s, "fir", 3) == 0)
+ {
+ opcode |= 0x0 << 21;
+ s += 3;
+ continue;
+ }
+ if (strncmp (s, "psr", 3) == 0)
+ {
+ opcode |= 0x1 << 21;
+ s += 3;
+ continue;
+ }
+ if (strncmp (s, "dirbase", 7) == 0)
+ {
+ opcode |= 0x2 << 21;
+ s += 7;
+ continue;
+ }
+ if (strncmp (s, "db", 2) == 0)
+ {
+ opcode |= 0x3 << 21;
+ s += 2;
+ continue;
+ }
+ if (strncmp (s, "fsr", 3) == 0)
+ {
+ opcode |= 0x4 << 21;
+ s += 3;
+ continue;
+ }
+ if (strncmp (s, "epsr", 4) == 0)
+ {
+ opcode |= 0x5 << 21;
+ s += 4;
+ continue;
+ }
+ break;
+
+ case '5': /* 5 bit immediate in src1 */
+ memset (&the_insn, '\0', sizeof (the_insn));
+ if (!getExpression (s))
+ {
+ s = expr_end;
+ if (the_insn.exp.X_add_number & ~0x1f)
+ as_bad (_("5-bit immediate too large"));
+ opcode |= (the_insn.exp.X_add_number & 0x1f) << 11;
+ memset (&the_insn, '\0', sizeof (the_insn));
+ the_insn.reloc = NO_RELOC;
+ continue;
+ }
+ break;
+
+ case 'l': /* 26 bit immediate, relative branch */
+ the_insn.reloc = BRADDR;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 's': /* 16 bit immediate, split relative branch */
+ /* upper 5 bits of offset in dest field */
+ the_insn.pcrel = 1;
+ the_insn.reloc = SPLIT0;
+ goto immediate;
+
+ case 'S': /* 16 bit immediate, split (st), aligned */
+ if (opcode & (1 << 28))
+ if (opcode & 0x1)
+ the_insn.reloc = SPLIT2;
+ else
+ the_insn.reloc = SPLIT1;
+ else
+ the_insn.reloc = SPLIT0;
+ goto immediate;
+
+ case 'I': /* 16 bit immediate, aligned */
+ if (opcode & (1 << 28))
+ if (opcode & 0x1)
+ the_insn.reloc = LOW2;
+ else
+ the_insn.reloc = LOW1;
+ else
+ the_insn.reloc = LOW0;
+ goto immediate;
+
+ case 'i': /* 16 bit immediate */
+ the_insn.reloc = LOW0;
+
+ /*FALLTHROUGH*/
+
+ immediate:
+ if (*s == ' ')
+ s++;
+ if (strncmp (s, "ha%", 3) == 0)
+ {
+ the_insn.highlow = HIGHADJ;
+ s += 3;
+ }
+ else if (strncmp (s, "h%", 2) == 0)
+ {
+ the_insn.highlow = HIGH;
+ s += 2;
+ }
+ else if (strncmp (s, "l%", 2) == 0)
+ {
+ the_insn.highlow = PAIR;
+ s += 2;
+ }
+ the_insn.expand = insn->expand;
+
+ /* Note that if the getExpression() fails, we will still have
+ created U entries in the symbol table for the 'symbols'
+ in the input string. Try not to create U symbols for
+ registers, etc. */
+
+ if (!getExpression (s))
+ {
+ s = expr_end;
+ continue;
+ }
+ break;
+
+ default:
+ as_fatal (_("failed sanity check."));
+ }
+ break;
+ }
+ error:
+ if (match == 0)
+ {
+ /* Args don't match. */
+ if (&insn[1] - i860_opcodes < NUMOPCODES
+ && !strcmp (insn->name, insn[1].name))
+ {
+ ++insn;
+ s = argsStart;
+ continue;
+ }
+ else
+ {
+ as_bad (_("Illegal operands"));
+ return;
+ }
+ }
+ break;
+ }
+
+ the_insn.opcode = opcode;
+}
+
+static int
+getExpression (str)
+ char *str;
+{
+ char *save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ seg = expression (&the_insn.exp);
+ if (seg != absolute_section
+ && seg != undefined_section
+ && ! SEG_NORMAL (seg))
+ {
+ the_insn.error = _("bad segment");
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+
+/*
+ This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+/*
+ * Write out big-endian.
+ */
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+void
+md_number_to_imm (buf, val, n, fixP)
+ char *buf;
+ long val;
+ int n;
+ fixS *fixP;
+{
+ enum reloc_type reloc = fixP->fx_r_type & 0xf;
+ enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3;
+
+ assert (buf);
+ assert (n == 4); /* always on i860 */
+
+ switch (highlow)
+ {
+
+ case HIGHADJ: /* adjusts the high-order 16-bits */
+ if (val & (1 << 15))
+ val += (1 << 16);
+
+ /*FALLTHROUGH*/
+
+ case HIGH: /* selects the high-order 16-bits */
+ val >>= 16;
+ break;
+
+ case PAIR: /* selects the low-order 16-bits */
+ val = val & 0xffff;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (reloc)
+ {
+
+ case BRADDR: /* br,call,bc,bc.t,bnc,bnc.t w/26-bit immediate */
+ if (fixP->fx_pcrel != 1)
+ as_bad (_("26-bit branch w/o pc relative set: 0x%08x"), val);
+ val >>= 2; /* align pcrel offset, see manual */
+
+ if (val >= (1 << 25) || val < -(1 << 25)) /* check for overflow */
+ as_bad (_("26-bit branch offset overflow: 0x%08x"), val);
+ buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3);
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case SPLIT2: /* 16 bit immediate, 4-byte aligned */
+ if (val & 0x3)
+ as_bad (_("16-bit immediate 4-byte alignment error: 0x%08x"), val);
+ val &= ~0x3; /* 4-byte align value */
+ /*FALLTHROUGH*/
+ case SPLIT1: /* 16 bit immediate, 2-byte aligned */
+ if (val & 0x1)
+ as_bad (_("16-bit immediate 2-byte alignment error: 0x%08x"), val);
+ val &= ~0x1; /* 2-byte align value */
+ /*FALLTHROUGH*/
+ case SPLIT0: /* st,bla,bte,btne w/16-bit immediate */
+ if (fixP->fx_pcrel == 1)
+ val >>= 2; /* align pcrel offset, see manual */
+ /* check for bounds */
+ if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
+ as_bad (_("16-bit branch offset overflow: 0x%08x"), val);
+ buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f);
+ buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7);
+ buf[3] |= val; /* perserve bottom opcode bits */
+ break;
+
+ case LOW4: /* fld,pfld,pst,flush 16-byte aligned */
+ if (val & 0xf)
+ as_bad (_("16-bit immediate 16-byte alignment error: 0x%08x"), val);
+ val &= ~0xf; /* 16-byte align value */
+ /*FALLTHROUGH*/
+ case LOW3: /* fld,pfld,pst,flush 8-byte aligned */
+ if (val & 0x7)
+ as_bad (_("16-bit immediate 8-byte alignment error: 0x%08x"), val);
+ val &= ~0x7; /* 8-byte align value */
+ /*FALLTHROUGH*/
+ case LOW2: /* 16 bit immediate, 4-byte aligned */
+ if (val & 0x3)
+ as_bad (_("16-bit immediate 4-byte alignment error: 0x%08x"), val);
+ val &= ~0x3; /* 4-byte align value */
+ /*FALLTHROUGH*/
+ case LOW1: /* 16 bit immediate, 2-byte aligned */
+ if (val & 0x1)
+ as_bad (_("16-bit immediate 2-byte alignment error: 0x%08x"), val);
+ val &= ~0x1; /* 2-byte align value */
+ /*FALLTHROUGH*/
+ case LOW0: /* 16 bit immediate, byte aligned */
+ /* check for bounds */
+ if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
+ as_bad (_("16-bit immediate overflow: 0x%08x"), val);
+ buf[2] = val >> 8;
+ buf[3] |= val; /* perserve bottom opcode bits */
+ break;
+
+ case NO_RELOC:
+ default:
+ as_bad (_("bad relocation type: 0x%02x"), reloc);
+ break;
+ }
+}
+
+/* should never be called for i860 */
+void
+md_number_to_disp (buf, val, n)
+ char *buf;
+ long val;
+{
+ as_fatal (_("md_number_to_disp\n"));
+}
+
+/* should never be called for i860 */
+void
+md_number_to_field (buf, val, fix)
+ char *buf;
+ long val;
+ void *fix;
+{
+ as_fatal (_("i860_number_to_field\n"));
+}
+
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* on i860: first 4 bytes are normal unsigned long address, next three
+ bytes are index, most sig. byte first. Byte 7 is broken up with
+ bit 7 as pcrel, bit 6 as extern, and the lower six bits as
+ relocation type (highlow 5-4). Next 4 bytes are long addend. */
+/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
+void
+md_ri_to_chars (ri_p, ri)
+ struct relocation_info *ri_p, ri;
+{
+#if 0
+ unsigned char the_bytes[sizeof (*ri_p)];
+
+ /* this is easy */
+ md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
+ /* now the fun stuff */
+ the_bytes[4] = (ri.r_index >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_index >> 8) & 0x0ff;
+ the_bytes[6] = ri.r_index & 0x0ff;
+ the_bytes[7] = ((ri.r_extern << 7) & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);
+ /* Also easy */
+ md_number_to_chars (&the_bytes[8], ri.r_addend, sizeof (ri.r_addend));
+ /* now put it back where you found it, Junior... */
+ memcpy ((char *) ri_p, the_bytes, sizeof (*ri_p));
+#endif
+}
+
+/* should never be called for i860 */
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ register fragS *fragP;
+{
+ as_fatal (_("i860_convert_frag\n"));
+}
+
+/* should never be called for i860 */
+int
+md_estimate_size_before_relax (fragP, segtype)
+ register fragS *fragP;
+ segT segtype;
+{
+ as_fatal (_("i860_estimate_size_before_relax\n"));
+}
+
+/* for debugging only, must match enum reloc_type */
+static char *Reloc[] =
+{
+ "NO_RELOC",
+ "BRADDR",
+ "LOW0",
+ "LOW1",
+ "LOW2",
+ "LOW3",
+ "LOW4",
+ "SPLIT0",
+ "SPLIT1",
+ "SPLIT2",
+ "RELOC_32",
+};
+static char *Highlow[] =
+{
+ "NO_SPEC",
+ "PAIR",
+ "HIGH",
+ "HIGHADJ",
+};
+static void
+print_insn (insn)
+ struct i860_it *insn;
+{
+ if (insn->error)
+ {
+ fprintf (stderr, "ERROR: %s\n");
+ }
+ fprintf (stderr, "opcode=0x%08x\t", insn->opcode);
+ fprintf (stderr, "expand=0x%08x\t", insn->expand);
+ fprintf (stderr, "reloc = %s\t", Reloc[insn->reloc]);
+ fprintf (stderr, "highlow = %s\n", Highlow[insn->highlow]);
+ fprintf (stderr, "exp = {\n");
+ fprintf (stderr, "\t\tX_add_symbol = %s\n",
+ insn->exp.X_add_symbol ?
+ (S_GET_NAME (insn->exp.X_add_symbol) ?
+ S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0");
+ fprintf (stderr, "\t\tX_op_symbol = %s\n",
+ insn->exp.X_op_symbol ?
+ (S_GET_NAME (insn->exp.X_op_symbol) ?
+ S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0");
+ fprintf (stderr, "\t\tX_add_number = %d\n",
+ insn->exp.X_add_number);
+ fprintf (stderr, "}\n");
+}
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+
+#ifdef comment
+/*
+ * I860 relocations are completely different, so it needs
+ * this machine dependent routine to emit them.
+ */
+void
+emit_machine_reloc (fixP, segment_address_in_file)
+ register fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ struct reloc_info_i860 ri;
+ register symbolS *symbolP;
+ extern char *next_object_file_charP;
+ long add_number;
+
+ memset ((char *) &ri, '\0', sizeof (ri));
+ for (; fixP; fixP = fixP->fx_next)
+ {
+
+ if (fixP->fx_r_type & ~0x3f)
+ {
+ as_fatal ("fixP->fx_r_type = %d\n", fixP->fx_r_type);
+ }
+ ri.r_pcrel = fixP->fx_pcrel;
+ ri.r_type = fixP->fx_r_type;
+
+ if ((symbolP = fixP->fx_addsy) != NULL)
+ {
+ ri.r_address = fixP->fx_frag->fr_address +
+ fixP->fx_where - segment_address_in_file;
+ if (!S_IS_DEFINED (symbolP))
+ {
+ ri.r_extern = 1;
+ ri.r_symbolnum = symbolP->sy_number;
+ }
+ else
+ {
+ ri.r_extern = 0;
+ ri.r_symbolnum = S_GET_TYPE (symbolP);
+ }
+ if (symbolP && symbolP->sy_frag)
+ {
+ ri.r_addend = symbolP->sy_frag->fr_address;
+ }
+ ri.r_type = fixP->fx_r_type;
+ if (fixP->fx_pcrel)
+ {
+ /* preserve actual offset vs. pc + 4 */
+ ri.r_addend -= (ri.r_address + 4);
+ }
+ else
+ {
+ ri.r_addend = fixP->fx_addnumber;
+ }
+
+ md_ri_to_chars ((char *) &ri, ri);
+ append (&next_object_file_charP, (char *) &ri, sizeof (ri));
+ }
+ }
+}
+
+#endif /* comment */
+
+#ifdef OBJ_AOUT
+
+/* on i860: first 4 bytes are normal unsigned long address, next three
+ bytes are index, most sig. byte first. Byte 7 is broken up with
+ bit 7 as pcrel, bit 6 as extern, and the lower six bits as
+ relocation type (highlow 5-4). Next 4 bytes are long addend. */
+
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ long r_index;
+ long r_extern;
+ long r_addend = 0;
+ long r_address;
+
+ know (fixP->fx_addsy);
+ know (!(fixP->fx_r_type & ~0x3f));
+
+ if (!S_IS_DEFINED (fixP->fx_addsy))
+ {
+ r_extern = 1;
+ r_index = fixP->fx_addsy->sy_number;
+ }
+ else
+ {
+ r_extern = 0;
+ r_index = S_GET_TYPE (fixP->fx_addsy);
+ }
+
+ md_number_to_chars (where,
+ r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ where[4] = (r_index >> 16) & 0x0ff;
+ where[5] = (r_index >> 8) & 0x0ff;
+ where[6] = r_index & 0x0ff;
+ where[7] = (((fixP->fx_pcrel << 7) & 0x80)
+ | ((r_extern << 6) & 0x40)
+ | (fixP->fx_r_type & 0x3F));
+
+ if (fixP->fx_addsy->sy_frag)
+ {
+ r_addend = fixP->fx_addsy->sy_frag->fr_address;
+ }
+
+ if (fixP->fx_pcrel)
+ {
+ /* preserve actual offset vs. pc + 4 */
+ r_addend -= (r_address + 4);
+ }
+ else
+ {
+ r_addend = fixP->fx_addnumber;
+ }
+
+ md_number_to_chars (&where[8], r_addend, 4);
+}
+
+#endif /* OBJ_AOUT */
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ return size; /* Byte alignment is fine */
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the i860, they're relative to the address of the offset, plus
+ its size. (??? Is this right? FIXME-SOON!) */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ /* looks to me like i860 never has bit fixes. Let's see. xoxorich. */
+ know (fixP->fx_bit_fixP == NULL);
+ if (!fixP->fx_bit_fixP)
+ {
+ fixP->fx_addnumber = val;
+ md_number_to_imm (place, val, fixP->fx_size, fixP);
+ }
+ else
+ {
+ md_number_to_field (place, val, fixP->fx_bit_fixP);
+ }
+}
+
+/*
+ * Local Variables:
+ * fill-column: 131
+ * comment-column: 0
+ * End:
+ */
+
+/* end of tc-i860.c */
diff --git a/gas/config/tc-i860.h b/gas/config/tc-i860.h
new file mode 100644
index 00000000000..afb21c1b556
--- /dev/null
+++ b/gas/config/tc-i860.h
@@ -0,0 +1,39 @@
+/* tc-i860.h -- Header file for the I860
+ Copyright (C) 1991, 92, 95, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TC_I860 1
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define WORKING_DOT_WORD
+
+#define tc_headers_hook(a) {;} /* not used */
+#define tc_crawl_symbol_chain(a) {;} /* not used */
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+
+#define md_operand(x)
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of tc-i860.h */
diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c
new file mode 100644
index 00000000000..936b6621994
--- /dev/null
+++ b/gas/config/tc-i960.c
@@ -0,0 +1,3231 @@
+/* tc-i960.c - All the i80960-specific stuff
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* See comment on md_parse_option for 80960-specific invocation options. */
+
+/* There are 4 different lengths of (potentially) symbol-based displacements
+ in the 80960 instruction set, each of which could require address fix-ups
+ and (in the case of external symbols) emission of relocation directives:
+
+ 32-bit (MEMB)
+ This is a standard length for the base assembler and requires no
+ special action.
+
+ 13-bit (COBR)
+ This is a non-standard length, but the base assembler has a
+ hook for bit field address fixups: the fixS structure can
+ point to a descriptor of the field, in which case our
+ md_number_to_field() routine gets called to process it.
+
+ I made the hook a little cleaner by having fix_new() (in the base
+ assembler) return a pointer to the fixS in question. And I made it a
+ little simpler by storing the field size (in this case 13) instead of
+ of a pointer to another structure: 80960 displacements are ALWAYS
+ stored in the low-order bits of a 4-byte word.
+
+ Since the target of a COBR cannot be external, no relocation
+ directives for this size displacement have to be generated.
+ But the base assembler had to be modified to issue error
+ messages if the symbol did turn out to be external.
+
+ 24-bit (CTRL)
+ Fixups are handled as for the 13-bit case (except that 24 is stored
+ in the fixS).
+
+ The relocation directive generated is the same as that for the 32-bit
+ displacement, except that it's PC-relative (the 32-bit displacement
+ never is). The i80960 version of the linker needs a mod to
+ distinguish and handle the 24-bit case.
+
+ 12-bit (MEMA)
+ MEMA formats are always promoted to MEMB (32-bit) if the displacement
+ is based on a symbol, because it could be relocated at link time.
+ The only time we use the 12-bit format is if an absolute value of
+ less than 4096 is specified, in which case we need neither a fixup nor
+ a relocation directive. */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "as.h"
+
+#include "obstack.h"
+
+#include "opcode/i960.h"
+
+#if defined (OBJ_AOUT) || defined (OBJ_BOUT)
+
+#define TC_S_IS_SYSPROC(s) ((1<=S_GET_OTHER(s)) && (S_GET_OTHER(s)<=32))
+#define TC_S_IS_BALNAME(s) (S_GET_OTHER(s) == N_BALNAME)
+#define TC_S_IS_CALLNAME(s) (S_GET_OTHER(s) == N_CALLNAME)
+#define TC_S_IS_BADPROC(s) ((S_GET_OTHER(s) != 0) && !TC_S_IS_CALLNAME(s) && !TC_S_IS_BALNAME(s) && !TC_S_IS_SYSPROC(s))
+
+#define TC_S_SET_SYSPROC(s, p) (S_SET_OTHER((s), (p)+1))
+#define TC_S_GET_SYSPROC(s) (S_GET_OTHER(s)-1)
+
+#define TC_S_FORCE_TO_BALNAME(s) (S_SET_OTHER((s), N_BALNAME))
+#define TC_S_FORCE_TO_CALLNAME(s) (S_SET_OTHER((s), N_CALLNAME))
+#define TC_S_FORCE_TO_SYSPROC(s) {;}
+
+#else /* ! OBJ_A/BOUT */
+#ifdef OBJ_COFF
+
+#define TC_S_IS_SYSPROC(s) (S_GET_STORAGE_CLASS(s) == C_SCALL)
+#define TC_S_IS_BALNAME(s) (SF_GET_BALNAME(s))
+#define TC_S_IS_CALLNAME(s) (SF_GET_CALLNAME(s))
+#define TC_S_IS_BADPROC(s) (TC_S_IS_SYSPROC(s) && TC_S_GET_SYSPROC(s) < 0 && 31 < TC_S_GET_SYSPROC(s))
+
+#define TC_S_SET_SYSPROC(s, p) ((s)->sy_symbol.ost_auxent[1].x_sc.x_stindx = (p))
+#define TC_S_GET_SYSPROC(s) ((s)->sy_symbol.ost_auxent[1].x_sc.x_stindx)
+
+#define TC_S_FORCE_TO_BALNAME(s) (SF_SET_BALNAME(s))
+#define TC_S_FORCE_TO_CALLNAME(s) (SF_SET_CALLNAME(s))
+#define TC_S_FORCE_TO_SYSPROC(s) (S_SET_STORAGE_CLASS((s), C_SCALL))
+
+#else /* ! OBJ_COFF */
+you lose;
+#endif /* ! OBJ_COFF */
+#endif /* ! OBJ_A/BOUT */
+
+extern char *input_line_pointer;
+
+#if !defined (BFD_ASSEMBLER) && !defined (BFD)
+#ifdef OBJ_COFF
+const int md_reloc_size = sizeof (struct reloc);
+#else /* OBJ_COFF */
+const int md_reloc_size = sizeof (struct relocation_info);
+#endif /* OBJ_COFF */
+#endif
+
+/* Local i80960 routines. */
+
+static void brcnt_emit (); /* Emit branch-prediction instrumentation code */
+static char *brlab_next (); /* Return next branch local label */
+void brtab_emit (); /* Emit br-predict instrumentation table */
+static void cobr_fmt (); /* Generate COBR instruction */
+static void ctrl_fmt (); /* Generate CTRL instruction */
+static char *emit (); /* Emit (internally) binary */
+static int get_args (); /* Break arguments out of comma-separated list */
+static void get_cdisp (); /* Handle COBR or CTRL displacement */
+static char *get_ispec (); /* Find index specification string */
+static int get_regnum (); /* Translate text to register number */
+static int i_scan (); /* Lexical scan of instruction source */
+static void mem_fmt (); /* Generate MEMA or MEMB instruction */
+static void mema_to_memb (); /* Convert MEMA instruction to MEMB format */
+static void parse_expr (); /* Parse an expression */
+static int parse_ldconst (); /* Parse and replace a 'ldconst' pseudo-op */
+static void parse_memop (); /* Parse a memory operand */
+static void parse_po (); /* Parse machine-dependent pseudo-op */
+static void parse_regop (); /* Parse a register operand */
+static void reg_fmt (); /* Generate a REG format instruction */
+void reloc_callj (); /* Relocate a 'callj' instruction */
+static void relax_cobr (); /* "De-optimize" cobr into compare/branch */
+static void s_leafproc (); /* Process '.leafproc' pseudo-op */
+static void s_sysproc (); /* Process '.sysproc' pseudo-op */
+static int shift_ok (); /* Will a 'shlo' substiture for a 'ldconst'? */
+static void syntax (); /* Give syntax error */
+static int targ_has_sfr (); /* Target chip supports spec-func register? */
+static int targ_has_iclass (); /* Target chip supports instruction set? */
+
+/* See md_parse_option() for meanings of these options */
+static char norelax; /* True if -norelax switch seen */
+static char instrument_branches; /* True if -b switch seen */
+
+/* Characters that always start a comment.
+ If the pre-processor is disabled, these aren't very useful.
+ */
+const char comment_chars[] = "#";
+
+/* Characters that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output.
+
+ Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output.
+ */
+
+/* Also note that comments started like this one will always work. */
+
+const char line_comment_chars[1];
+
+const char line_separator_chars[1];
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant,
+ as in 0f12.456 or 0d1.2345e12
+ */
+const char FLT_CHARS[] = "fFdDtT";
+
+
+/* Table used by base assembler to relax addresses based on varying length
+ instructions. The fields are:
+ 1) most positive reach of this state,
+ 2) most negative reach of this state,
+ 3) how many bytes this mode will add to the size of the current frag
+ 4) which index into the table to try if we can't fit into this one.
+
+ For i80960, the only application is the (de-)optimization of cobr
+ instructions into separate compare and branch instructions when a 13-bit
+ displacement won't hack it.
+ */
+const relax_typeS md_relax_table[] =
+{
+ {0, 0, 0, 0}, /* State 0 => no more relaxation possible */
+ {4088, -4096, 0, 2}, /* State 1: conditional branch (cobr) */
+ {0x800000 - 8, -0x800000, 4, 0}, /* State 2: compare (reg) & branch (ctrl) */
+};
+
+static void s_endian PARAMS ((int));
+
+/* These are the machine dependent pseudo-ops.
+
+ This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ integer arg to pass to the function
+ */
+#define S_LEAFPROC 1
+#define S_SYSPROC 2
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"bss", s_lcomm, 1},
+ {"endian", s_endian, 0},
+ {"extended", float_cons, 't'},
+ {"leafproc", parse_po, S_LEAFPROC},
+ {"sysproc", parse_po, S_SYSPROC},
+
+ {"word", cons, 4},
+ {"quad", cons, 16},
+
+ {0, 0, 0}
+};
+
+/* Macros to extract info from an 'expressionS' structure 'e' */
+#define adds(e) e.X_add_symbol
+#define offs(e) e.X_add_number
+
+
+/* Branch-prediction bits for CTRL/COBR format opcodes */
+#define BP_MASK 0x00000002 /* Mask for branch-prediction bit */
+#define BP_TAKEN 0x00000000 /* Value to OR in to predict branch */
+#define BP_NOT_TAKEN 0x00000002 /* Value to OR in to predict no branch */
+
+
+/* Some instruction opcodes that we need explicitly */
+#define BE 0x12000000
+#define BG 0x11000000
+#define BGE 0x13000000
+#define BL 0x14000000
+#define BLE 0x16000000
+#define BNE 0x15000000
+#define BNO 0x10000000
+#define BO 0x17000000
+#define CHKBIT 0x5a002700
+#define CMPI 0x5a002080
+#define CMPO 0x5a002000
+
+#define B 0x08000000
+#define BAL 0x0b000000
+#define CALL 0x09000000
+#define CALLS 0x66003800
+#define RET 0x0a000000
+
+
+/* These masks are used to build up a set of MEMB mode bits. */
+#define A_BIT 0x0400
+#define I_BIT 0x0800
+#define MEMB_BIT 0x1000
+#define D_BIT 0x2000
+
+
+/* Mask for the only mode bit in a MEMA instruction (if set, abase reg is
+ used). */
+#define MEMA_ABASE 0x2000
+
+/* Info from which a MEMA or MEMB format instruction can be generated */
+typedef struct
+ {
+ /* (First) 32 bits of instruction */
+ long opcode;
+ /* 0-(none), 12- or, 32-bit displacement needed */
+ int disp;
+ /* The expression in the source instruction from which the
+ displacement should be determined. */
+ char *e;
+ }
+
+memS;
+
+
+/* The two pieces of info we need to generate a register operand */
+struct regop
+ {
+ int mode; /* 0 =>local/global/spec reg; 1=> literal or fp reg */
+ int special; /* 0 =>not a sfr; 1=> is a sfr (not valid w/mode=0) */
+ int n; /* Register number or literal value */
+ };
+
+
+/* Number and assembler mnemonic for all registers that can appear in
+ operands. */
+static const struct
+ {
+ char *reg_name;
+ int reg_num;
+ }
+regnames[] =
+{
+ { "pfp", 0 },
+ { "sp", 1 },
+ { "rip", 2 },
+ { "r3", 3 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "g0", 16 },
+ { "g1", 17 },
+ { "g2", 18 },
+ { "g3", 19 },
+ { "g4", 20 },
+ { "g5", 21 },
+ { "g6", 22 },
+ { "g7", 23 },
+ { "g8", 24 },
+ { "g9", 25 },
+ { "g10", 26 },
+ { "g11", 27 },
+ { "g12", 28 },
+ { "g13", 29 },
+ { "g14", 30 },
+ { "fp", 31 },
+
+ /* Numbers for special-function registers are for assembler internal
+ use only: they are scaled back to range [0-31] for binary output. */
+#define SF0 32
+
+ { "sf0", 32 },
+ { "sf1", 33 },
+ { "sf2", 34 },
+ { "sf3", 35 },
+ { "sf4", 36 },
+ { "sf5", 37 },
+ { "sf6", 38 },
+ { "sf7", 39 },
+ { "sf8", 40 },
+ { "sf9", 41 },
+ { "sf10", 42 },
+ { "sf11", 43 },
+ { "sf12", 44 },
+ { "sf13", 45 },
+ { "sf14", 46 },
+ { "sf15", 47 },
+ { "sf16", 48 },
+ { "sf17", 49 },
+ { "sf18", 50 },
+ { "sf19", 51 },
+ { "sf20", 52 },
+ { "sf21", 53 },
+ { "sf22", 54 },
+ { "sf23", 55 },
+ { "sf24", 56 },
+ { "sf25", 57 },
+ { "sf26", 58 },
+ { "sf27", 59 },
+ { "sf28", 60 },
+ { "sf29", 61 },
+ { "sf30", 62 },
+ { "sf31", 63 },
+
+ /* Numbers for floating point registers are for assembler internal
+ use only: they are scaled back to [0-3] for binary output. */
+#define FP0 64
+
+ { "fp0", 64 },
+ { "fp1", 65 },
+ { "fp2", 66 },
+ { "fp3", 67 },
+
+ { NULL, 0 }, /* END OF LIST */
+};
+
+#define IS_RG_REG(n) ((0 <= (n)) && ((n) < SF0))
+#define IS_SF_REG(n) ((SF0 <= (n)) && ((n) < FP0))
+#define IS_FP_REG(n) ((n) >= FP0)
+
+/* Number and assembler mnemonic for all registers that can appear as
+ 'abase' (indirect addressing) registers. */
+static const struct
+ {
+ char *areg_name;
+ int areg_num;
+ }
+aregs[] =
+{
+ { "(pfp)", 0 },
+ { "(sp)", 1 },
+ { "(rip)", 2 },
+ { "(r3)", 3 },
+ { "(r4)", 4 },
+ { "(r5)", 5 },
+ { "(r6)", 6 },
+ { "(r7)", 7 },
+ { "(r8)", 8 },
+ { "(r9)", 9 },
+ { "(r10)", 10 },
+ { "(r11)", 11 },
+ { "(r12)", 12 },
+ { "(r13)", 13 },
+ { "(r14)", 14 },
+ { "(r15)", 15 },
+ { "(g0)", 16 },
+ { "(g1)", 17 },
+ { "(g2)", 18 },
+ { "(g3)", 19 },
+ { "(g4)", 20 },
+ { "(g5)", 21 },
+ { "(g6)", 22 },
+ { "(g7)", 23 },
+ { "(g8)", 24 },
+ { "(g9)", 25 },
+ { "(g10)", 26 },
+ { "(g11)", 27 },
+ { "(g12)", 28 },
+ { "(g13)", 29 },
+ { "(g14)", 30 },
+ { "(fp)", 31 },
+
+#define IPREL 32
+ /* For assembler internal use only: this number never appears in binary
+ output. */
+ { "(ip)", IPREL },
+
+ { NULL, 0 }, /* END OF LIST */
+};
+
+
+/* Hash tables */
+static struct hash_control *op_hash; /* Opcode mnemonics */
+static struct hash_control *reg_hash; /* Register name hash table */
+static struct hash_control *areg_hash; /* Abase register hash table */
+
+
+/* Architecture for which we are assembling */
+#define ARCH_ANY 0 /* Default: no architecture checking done */
+#define ARCH_KA 1
+#define ARCH_KB 2
+#define ARCH_MC 3
+#define ARCH_CA 4
+#define ARCH_JX 5
+#define ARCH_HX 6
+int architecture = ARCH_ANY; /* Architecture requested on invocation line */
+int iclasses_seen; /* OR of instruction classes (I_* constants)
+ * for which we've actually assembled
+ * instructions.
+ */
+
+
+/* BRANCH-PREDICTION INSTRUMENTATION
+
+ The following supports generation of branch-prediction instrumentation
+ (turned on by -b switch). The instrumentation collects counts
+ of branches taken/not-taken for later input to a utility that will
+ set the branch prediction bits of the instructions in accordance with
+ the behavior observed. (Note that the KX series does not have
+ brach-prediction.)
+
+ The instrumentation consists of:
+
+ (1) before and after each conditional branch, a call to an external
+ routine that increments and steps over an inline counter. The
+ counter itself, initialized to 0, immediately follows the call
+ instruction. For each branch, the counter following the branch
+ is the number of times the branch was not taken, and the difference
+ between the counters is the number of times it was taken. An
+ example of an instrumented conditional branch:
+
+ call BR_CNT_FUNC
+ .word 0
+ LBRANCH23: be label
+ call BR_CNT_FUNC
+ .word 0
+
+ (2) a table of pointers to the instrumented branches, so that an
+ external postprocessing routine can locate all of the counters.
+ the table begins with a 2-word header: a pointer to the next in
+ a linked list of such tables (initialized to 0); and a count
+ of the number of entries in the table (exclusive of the header.
+
+ Note that input source code is expected to already contain calls
+ an external routine that will link the branch local table into a
+ list of such tables.
+ */
+
+/* Number of branches instrumented so far. Also used to generate
+ unique local labels for each instrumented branch. */
+static int br_cnt;
+
+#define BR_LABEL_BASE "LBRANCH"
+/* Basename of local labels on instrumented branches, to avoid
+ conflict with compiler- generated local labels. */
+
+#define BR_CNT_FUNC "__inc_branch"
+/* Name of the external routine that will increment (and step over) an
+ inline counter. */
+
+#define BR_TAB_NAME "__BRANCH_TABLE__"
+/* Name of the table of pointers to branches. A local (i.e.,
+ non-external) symbol. */
+
+/*****************************************************************************
+ md_begin: One-time initialization.
+
+ Set up hash tables.
+
+ *************************************************************************** */
+void
+md_begin ()
+{
+ int i; /* Loop counter */
+ const struct i960_opcode *oP; /* Pointer into opcode table */
+ const char *retval; /* Value returned by hash functions */
+
+ op_hash = hash_new ();
+ reg_hash = hash_new ();
+ areg_hash = hash_new ();
+
+ /* For some reason, the base assembler uses an empty string for "no
+ error message", instead of a NULL pointer. */
+ retval = 0;
+
+ for (oP = i960_opcodes; oP->name && !retval; oP++)
+ retval = hash_insert (op_hash, oP->name, (PTR) oP);
+
+ for (i = 0; regnames[i].reg_name && !retval; i++)
+ retval = hash_insert (reg_hash, regnames[i].reg_name,
+ (char *) &regnames[i].reg_num);
+
+ for (i = 0; aregs[i].areg_name && !retval; i++)
+ retval = hash_insert (areg_hash, aregs[i].areg_name,
+ (char *) &aregs[i].areg_num);
+
+ if (retval)
+ as_fatal (_("Hashing returned \"%s\"."), retval);
+}
+
+/*****************************************************************************
+ md_assemble: Assemble an instruction
+
+ Assumptions about the passed-in text:
+ - all comments, labels removed
+ - text is an instruction
+ - all white space compressed to single blanks
+ - all character constants have been replaced with decimal
+
+ *************************************************************************** */
+void
+md_assemble (textP)
+ char *textP; /* Source text of instruction */
+{
+ /* Parsed instruction text, containing NO whitespace: arg[0]->opcode
+ mnemonic arg[1-3]->operands, with char constants replaced by
+ decimal numbers. */
+ char *args[4];
+
+ int n_ops; /* Number of instruction operands */
+ /* Pointer to instruction description */
+ struct i960_opcode *oP;
+ /* TRUE iff opcode mnemonic included branch-prediction suffix (".f"
+ or ".t"). */
+ int branch_predict;
+ /* Setting of branch-prediction bit(s) to be OR'd into instruction
+ opcode of CTRL/COBR format instructions. */
+ long bp_bits;
+
+ int n; /* Offset of last character in opcode mnemonic */
+
+ const char *bp_error_msg = _("branch prediction invalid on this opcode");
+
+
+ /* Parse instruction into opcode and operands */
+ memset (args, '\0', sizeof (args));
+ n_ops = i_scan (textP, args);
+ if (n_ops == -1)
+ {
+ return; /* Error message already issued */
+ }
+
+ /* Do "macro substitution" (sort of) on 'ldconst' pseudo-instruction */
+ if (!strcmp (args[0], "ldconst"))
+ {
+ n_ops = parse_ldconst (args);
+ if (n_ops == -1)
+ {
+ return;
+ }
+ }
+
+
+
+ /* Check for branch-prediction suffix on opcode mnemonic, strip it off */
+ n = strlen (args[0]) - 1;
+ branch_predict = 0;
+ bp_bits = 0;
+ if (args[0][n - 1] == '.' && (args[0][n] == 't' || args[0][n] == 'f'))
+ {
+ /* We could check here to see if the target architecture
+ supports branch prediction, but why bother? The bit will
+ just be ignored by processors that don't use it. */
+ branch_predict = 1;
+ bp_bits = (args[0][n] == 't') ? BP_TAKEN : BP_NOT_TAKEN;
+ args[0][n - 1] = '\0'; /* Strip suffix from opcode mnemonic */
+ }
+
+ /* Look up opcode mnemonic in table and check number of operands.
+ Check that opcode is legal for the target architecture. If all
+ looks good, assemble instruction. */
+ oP = (struct i960_opcode *) hash_find (op_hash, args[0]);
+ if (!oP || !targ_has_iclass (oP->iclass))
+ {
+ as_bad (_("invalid opcode, \"%s\"."), args[0]);
+
+ }
+ else if (n_ops != oP->num_ops)
+ {
+ as_bad (_("improper number of operands. expecting %d, got %d"),
+ oP->num_ops, n_ops);
+ }
+ else
+ {
+ switch (oP->format)
+ {
+ case FBRA:
+ case CTRL:
+ ctrl_fmt (args[1], oP->opcode | bp_bits, oP->num_ops);
+ if (oP->format == FBRA)
+ {
+ /* Now generate a 'bno' to same arg */
+ ctrl_fmt (args[1], BNO | bp_bits, 1);
+ }
+ break;
+ case COBR:
+ case COJ:
+ cobr_fmt (args, oP->opcode | bp_bits, oP);
+ break;
+ case REG:
+ if (branch_predict)
+ {
+ as_warn (bp_error_msg);
+ }
+ reg_fmt (args, oP);
+ break;
+ case MEM1:
+ if (args[0][0] == 'c' && args[0][1] == 'a')
+ {
+ if (branch_predict)
+ {
+ as_warn (bp_error_msg);
+ }
+ mem_fmt (args, oP, 1);
+ break;
+ }
+ case MEM2:
+ case MEM4:
+ case MEM8:
+ case MEM12:
+ case MEM16:
+ if (branch_predict)
+ {
+ as_warn (bp_error_msg);
+ }
+ mem_fmt (args, oP, 0);
+ break;
+ case CALLJ:
+ if (branch_predict)
+ {
+ as_warn (bp_error_msg);
+ }
+ /* Output opcode & set up "fixup" (relocation); flag
+ relocation as 'callj' type. */
+ know (oP->num_ops == 1);
+ get_cdisp (args[1], "CTRL", oP->opcode, 24, 0, 1);
+ break;
+ default:
+ BAD_CASE (oP->format);
+ break;
+ }
+ }
+} /* md_assemble() */
+
+/*****************************************************************************
+ md_number_to_chars: convert a number to target byte order
+
+ *************************************************************************** */
+void
+md_number_to_chars (buf, value, n)
+ char *buf;
+ valueT value;
+ int n;
+{
+ number_to_chars_littleendian (buf, value, n);
+}
+
+/*****************************************************************************
+ md_chars_to_number: convert from target byte order to host byte order.
+
+ *************************************************************************** */
+int
+md_chars_to_number (val, n)
+ unsigned char *val; /* Value in target byte order */
+ int n; /* Number of bytes in the input */
+{
+ int retval;
+
+ for (retval = 0; n--;)
+ {
+ retval <<= 8;
+ retval |= val[n];
+ }
+ return retval;
+}
+
+
+#define MAX_LITTLENUMS 6
+#define LNUM_SIZE sizeof(LITTLENUM_TYPE)
+
+/*****************************************************************************
+ md_atof: convert ascii to floating point
+
+ Turn a string at input_line_pointer into a floating point constant of type
+ 'type', and store the appropriate bytes at *litP. The number of LITTLENUMS
+ emitted is returned at 'sizeP'. An error message is returned, or a pointer
+ to an empty message if OK.
+
+ Note we call the i386 floating point routine, rather than complicating
+ things with more files or symbolic links.
+
+ *************************************************************************** */
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ int prec;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ prec = 4;
+ break;
+
+ case 't':
+ case 'T':
+ prec = 5;
+ type = 'x'; /* That's what atof_ieee() understands */
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to md_atof()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ {
+ input_line_pointer = t;
+ }
+
+ *sizeP = prec * LNUM_SIZE;
+
+ /* Output the LITTLENUMs in REVERSE order in accord with i80960
+ word-order. (Dunno why atof_ieee doesn't do it in the right
+ order in the first place -- probably because it's a hack of
+ atof_m68k.) */
+
+ for (wordP = words + prec - 1; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP--), LNUM_SIZE);
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ md_number_to_imm
+
+ *************************************************************************** */
+void
+md_number_to_imm (buf, val, n)
+ char *buf;
+ long val;
+ int n;
+{
+ md_number_to_chars (buf, val, n);
+}
+
+
+/*****************************************************************************
+ md_number_to_disp
+
+ *************************************************************************** */
+void
+md_number_to_disp (buf, val, n)
+ char *buf;
+ long val;
+ int n;
+{
+ md_number_to_chars (buf, val, n);
+}
+
+/*****************************************************************************
+ md_number_to_field:
+
+ Stick a value (an address fixup) into a bit field of
+ previously-generated instruction.
+
+ *************************************************************************** */
+void
+md_number_to_field (instrP, val, bfixP)
+ char *instrP; /* Pointer to instruction to be fixed */
+ long val; /* Address fixup value */
+ bit_fixS *bfixP; /* Description of bit field to be fixed up */
+{
+ int numbits; /* Length of bit field to be fixed */
+ long instr; /* 32-bit instruction to be fixed-up */
+ long sign; /* 0 or -1, according to sign bit of 'val' */
+
+ /* Convert instruction back to host byte order. */
+ instr = md_chars_to_number (instrP, 4);
+
+ /* Surprise! -- we stored the number of bits to be modified rather
+ than a pointer to a structure. */
+ numbits = (int) bfixP;
+ if (numbits == 1)
+ {
+ /* This is a no-op, stuck here by reloc_callj() */
+ return;
+ }
+
+ know ((numbits == 13) || (numbits == 24));
+
+ /* Propagate sign bit of 'val' for the given number of bits. Result
+ should be all 0 or all 1. */
+ sign = val >> ((int) numbits - 1);
+ if (((val < 0) && (sign != -1))
+ || ((val > 0) && (sign != 0)))
+ {
+ as_bad (_("Fixup of %ld too large for field width of %d"),
+ val, numbits);
+ }
+ else
+ {
+ /* Put bit field into instruction and write back in target
+ * byte order.
+ */
+ val &= ~(-1 << (int) numbits); /* Clear unused sign bits */
+ instr |= val;
+ md_number_to_chars (instrP, instr, 4);
+ }
+} /* md_number_to_field() */
+
+
+/*****************************************************************************
+ md_parse_option
+ Invocation line includes a switch not recognized by the base assembler.
+ See if it's a processor-specific option. For the 960, these are:
+
+ -norelax:
+ Conditional branch instructions that require displacements
+ greater than 13 bits (or that have external targets) should
+ generate errors. The default is to replace each such
+ instruction with the corresponding compare (or chkbit) and
+ branch instructions. Note that the Intel "j" cobr directives
+ are ALWAYS "de-optimized" in this way when necessary,
+ regardless of the setting of this option.
+
+ -b:
+ Add code to collect information about branches taken, for
+ later optimization of branch prediction bits by a separate
+ tool. COBR and CNTL format instructions have branch
+ prediction bits (in the CX architecture); if "BR" represents
+ an instruction in one of these classes, the following rep-
+ resents the code generated by the assembler:
+
+ call <increment routine>
+ .word 0 # pre-counter
+ Label: BR
+ call <increment routine>
+ .word 0 # post-counter
+
+ A table of all such "Labels" is also generated.
+
+
+ -AKA, -AKB, -AKC, -ASA, -ASB, -AMC, -ACA:
+ Select the 80960 architecture. Instructions or features not
+ supported by the selected architecture cause fatal errors.
+ The default is to generate code for any instruction or feature
+ that is supported by SOME version of the 960 (even if this
+ means mixing architectures!).
+
+ ****************************************************************************/
+
+CONST char *md_shortopts = "A:b";
+struct option md_longopts[] =
+{
+#define OPTION_LINKRELAX (OPTION_MD_BASE)
+ {"linkrelax", no_argument, NULL, OPTION_LINKRELAX},
+ {"link-relax", no_argument, NULL, OPTION_LINKRELAX},
+#define OPTION_NORELAX (OPTION_MD_BASE + 1)
+ {"norelax", no_argument, NULL, OPTION_NORELAX},
+ {"no-relax", no_argument, NULL, OPTION_NORELAX},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+struct tabentry
+ {
+ char *flag;
+ int arch;
+ };
+static const struct tabentry arch_tab[] =
+{
+ {"KA", ARCH_KA},
+ {"KB", ARCH_KB},
+ {"SA", ARCH_KA}, /* Synonym for KA */
+ {"SB", ARCH_KB}, /* Synonym for KB */
+ {"KC", ARCH_MC}, /* Synonym for MC */
+ {"MC", ARCH_MC},
+ {"CA", ARCH_CA},
+ {"JX", ARCH_JX},
+ {"HX", ARCH_HX},
+ {NULL, 0}
+};
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case OPTION_LINKRELAX:
+ linkrelax = 1;
+ flag_keep_locals = 1;
+ break;
+
+ case OPTION_NORELAX:
+ norelax = 1;
+ break;
+
+ case 'b':
+ instrument_branches = 1;
+ break;
+
+ case 'A':
+ {
+ const struct tabentry *tp;
+ char *p = arg;
+
+ for (tp = arch_tab; tp->flag != NULL; tp++)
+ if (!strcmp (p, tp->flag))
+ break;
+
+ if (tp->flag == NULL)
+ {
+ as_bad (_("invalid architecture %s"), p);
+ return 0;
+ }
+ else
+ architecture = tp->arch;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ int i;
+ fprintf (stream, _("I960 options:\n"));
+ for (i = 0; arch_tab[i].flag; i++)
+ fprintf (stream, "%s-A%s", i ? " | " : "", arch_tab[i].flag);
+ fprintf (stream, _("\n\
+ specify variant of 960 architecture\n\
+-b add code to collect statistics about branches taken\n\
+-link-relax preserve individual alignment directives so linker\n\
+ can do relaxing (b.out format only)\n\
+-no-relax don't alter compare-and-branch instructions for\n\
+ long displacements\n"));
+}
+
+
+#ifndef BFD_ASSEMBLER
+/*****************************************************************************
+ md_convert_frag:
+ Called by base assembler after address relaxation is finished: modify
+ variable fragments according to how much relaxation was done.
+
+ If the fragment substate is still 1, a 13-bit displacement was enough
+ to reach the symbol in question. Set up an address fixup, but otherwise
+ leave the cobr instruction alone.
+
+ If the fragment substate is 2, a 13-bit displacement was not enough.
+ Replace the cobr with a two instructions (a compare and a branch).
+
+ *************************************************************************** */
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ fixS *fixP; /* Structure describing needed address fix */
+
+ switch (fragP->fr_subtype)
+ {
+ case 1:
+ /* LEAVE SINGLE COBR INSTRUCTION */
+ fixP = fix_new (fragP,
+ fragP->fr_opcode - fragP->fr_literal,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 1,
+ NO_RELOC);
+
+ fixP->fx_bit_fixP = (bit_fixS *) 13; /* size of bit field */
+ break;
+ case 2:
+ /* REPLACE COBR WITH COMPARE/BRANCH INSTRUCTIONS */
+ relax_cobr (fragP);
+ break;
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+}
+
+/*****************************************************************************
+ md_estimate_size_before_relax: How much does it look like *fragP will grow?
+
+ Called by base assembler just before address relaxation.
+ Return the amount by which the fragment will grow.
+
+ Any symbol that is now undefined will not become defined; cobr's
+ based on undefined symbols will have to be replaced with a compare
+ instruction and a branch instruction, and the code fragment will grow
+ by 4 bytes.
+
+ *************************************************************************** */
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ /* If symbol is undefined in this segment, go to "relaxed" state
+ (compare and branch instructions instead of cobr) right now. */
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment_type)
+ {
+ relax_cobr (fragP);
+ return 4;
+ }
+ return 0;
+} /* md_estimate_size_before_relax() */
+
+
+/*****************************************************************************
+ md_ri_to_chars:
+ This routine exists in order to overcome machine byte-order problems
+ when dealing with bit-field entries in the relocation_info struct.
+
+ But relocation info will be used on the host machine only (only
+ executable code is actually downloaded to the i80960). Therefore,
+ we leave it in host byte order.
+
+ The above comment is no longer true. This routine now really
+ does do the reordering (Ian Taylor 28 Aug 92).
+
+ *************************************************************************** */
+void
+md_ri_to_chars (where, ri)
+ char *where;
+ struct relocation_info *ri;
+{
+ md_number_to_chars (where, ri->r_address,
+ sizeof (ri->r_address));
+ where[4] = ri->r_index & 0x0ff;
+ where[5] = (ri->r_index >> 8) & 0x0ff;
+ where[6] = (ri->r_index >> 16) & 0x0ff;
+ where[7] = ((ri->r_pcrel << 0)
+ | (ri->r_length << 1)
+ | (ri->r_extern << 3)
+ | (ri->r_bsr << 4)
+ | (ri->r_disp << 5)
+ | (ri->r_callj << 6));
+}
+
+#endif /* BFD_ASSEMBLER */
+
+/* FOLLOWING ARE THE LOCAL ROUTINES, IN ALPHABETICAL ORDER */
+
+/*****************************************************************************
+ brcnt_emit: Emit code to increment inline branch counter.
+
+ See the comments above the declaration of 'br_cnt' for details on
+ branch-prediction instrumentation.
+ *************************************************************************** */
+static void
+brcnt_emit ()
+{
+ ctrl_fmt (BR_CNT_FUNC, CALL, 1); /* Emit call to "increment" routine */
+ emit (0); /* Emit inline counter to be incremented */
+}
+
+/*****************************************************************************
+ brlab_next: generate the next branch local label
+
+ See the comments above the declaration of 'br_cnt' for details on
+ branch-prediction instrumentation.
+ *************************************************************************** */
+static char *
+brlab_next ()
+{
+ static char buf[20];
+
+ sprintf (buf, "%s%d", BR_LABEL_BASE, br_cnt++);
+ return buf;
+}
+
+/*****************************************************************************
+ brtab_emit: generate the fetch-prediction branch table.
+
+ See the comments above the declaration of 'br_cnt' for details on
+ branch-prediction instrumentation.
+
+ The code emitted here would be functionally equivalent to the following
+ example assembler source.
+
+ .data
+ .align 2
+ BR_TAB_NAME:
+ .word 0 # link to next table
+ .word 3 # length of table
+ .word LBRANCH0 # 1st entry in table proper
+ .word LBRANCH1
+ .word LBRANCH2
+ **************************************************************************** */
+void
+brtab_emit ()
+{
+ int i;
+ char buf[20];
+ char *p; /* Where the binary was output to */
+ /* Pointer to description of deferred address fixup. */
+ fixS *fixP;
+
+ if (!instrument_branches)
+ {
+ return;
+ }
+
+ subseg_set (data_section, 0); /* .data */
+ frag_align (2, 0, 0); /* .align 2 */
+ record_alignment (now_seg, 2);
+ colon (BR_TAB_NAME); /* BR_TAB_NAME: */
+ emit (0); /* .word 0 #link to next table */
+ emit (br_cnt); /* .word n #length of table */
+
+ for (i = 0; i < br_cnt; i++)
+ {
+ sprintf (buf, "%s%d", BR_LABEL_BASE, i);
+ p = emit (0);
+ fixP = fix_new (frag_now,
+ p - frag_now->fr_literal,
+ 4,
+ symbol_find (buf),
+ 0,
+ 0,
+ NO_RELOC);
+ }
+}
+
+/*****************************************************************************
+ cobr_fmt: generate a COBR-format instruction
+
+ *************************************************************************** */
+static
+void
+cobr_fmt (arg, opcode, oP)
+ /* arg[0]->opcode mnemonic, arg[1-3]->operands (ascii) */
+ char *arg[];
+ /* Opcode, with branch-prediction bits already set if necessary. */
+ long opcode;
+ /* Pointer to description of instruction. */
+ struct i960_opcode *oP;
+{
+ long instr; /* 32-bit instruction */
+ struct regop regop; /* Description of register operand */
+ int n; /* Number of operands */
+ int var_frag; /* 1 if varying length code fragment should
+ * be emitted; 0 if an address fix
+ * should be emitted.
+ */
+
+ instr = opcode;
+ n = oP->num_ops;
+
+ if (n >= 1)
+ {
+ /* First operand (if any) of a COBR is always a register
+ operand. Parse it. */
+ parse_regop (&regop, arg[1], oP->operand[0]);
+ instr |= (regop.n << 19) | (regop.mode << 13);
+ }
+ if (n >= 2)
+ {
+ /* Second operand (if any) of a COBR is always a register
+ operand. Parse it. */
+ parse_regop (&regop, arg[2], oP->operand[1]);
+ instr |= (regop.n << 14) | regop.special;
+ }
+
+
+ if (n < 3)
+ {
+ emit (instr);
+
+ }
+ else
+ {
+ if (instrument_branches)
+ {
+ brcnt_emit ();
+ colon (brlab_next ());
+ }
+
+ /* A third operand to a COBR is always a displacement. Parse
+ it; if it's relaxable (a cobr "j" directive, or any cobr
+ other than bbs/bbc when the "-norelax" option is not in use)
+ set up a variable code fragment; otherwise set up an address
+ fix. */
+ var_frag = !norelax || (oP->format == COJ); /* TRUE or FALSE */
+ get_cdisp (arg[3], "COBR", instr, 13, var_frag, 0);
+
+ if (instrument_branches)
+ {
+ brcnt_emit ();
+ }
+ }
+} /* cobr_fmt() */
+
+
+/*****************************************************************************
+ ctrl_fmt: generate a CTRL-format instruction
+
+ *************************************************************************** */
+static
+void
+ctrl_fmt (targP, opcode, num_ops)
+ char *targP; /* Pointer to text of lone operand (if any) */
+ long opcode; /* Template of instruction */
+ int num_ops; /* Number of operands */
+{
+ int instrument; /* TRUE iff we should add instrumentation to track
+ * how often the branch is taken
+ */
+
+
+ if (num_ops == 0)
+ {
+ emit (opcode); /* Output opcode */
+ }
+ else
+ {
+
+ instrument = instrument_branches && (opcode != CALL)
+ && (opcode != B) && (opcode != RET) && (opcode != BAL);
+
+ if (instrument)
+ {
+ brcnt_emit ();
+ colon (brlab_next ());
+ }
+
+ /* The operand MUST be an ip-relative displacment. Parse it
+ * and set up address fix for the instruction we just output.
+ */
+ get_cdisp (targP, "CTRL", opcode, 24, 0, 0);
+
+ if (instrument)
+ {
+ brcnt_emit ();
+ }
+ }
+
+}
+
+
+/*****************************************************************************
+ emit: output instruction binary
+
+ Output instruction binary, in target byte order, 4 bytes at a time.
+ Return pointer to where it was placed.
+
+ *************************************************************************** */
+static
+char *
+emit (instr)
+ long instr; /* Word to be output, host byte order */
+{
+ char *toP; /* Where to output it */
+
+ toP = frag_more (4); /* Allocate storage */
+ md_number_to_chars (toP, instr, 4); /* Convert to target byte order */
+ return toP;
+}
+
+
+/*****************************************************************************
+ get_args: break individual arguments out of comma-separated list
+
+ Input assumptions:
+ - all comments and labels have been removed
+ - all strings of whitespace have been collapsed to a single blank.
+ - all character constants ('x') have been replaced with decimal
+
+ Output:
+ args[0] is untouched. args[1] points to first operand, etc. All args:
+ - are NULL-terminated
+ - contain no whitespace
+
+ Return value:
+ Number of operands (0,1,2, or 3) or -1 on error.
+
+ *************************************************************************** */
+static int
+get_args (p, args)
+ /* Pointer to comma-separated operands; MUCKED BY US */
+ register char *p;
+ /* Output arg: pointers to operands placed in args[1-3]. MUST
+ ACCOMMODATE 4 ENTRIES (args[0-3]). */
+ char *args[];
+{
+ register int n; /* Number of operands */
+ register char *to;
+
+ /* Skip lead white space */
+ while (*p == ' ')
+ {
+ p++;
+ }
+
+ if (*p == '\0')
+ {
+ return 0;
+ }
+
+ n = 1;
+ args[1] = p;
+
+ /* Squeze blanks out by moving non-blanks toward start of string.
+ * Isolate operands, whenever comma is found.
+ */
+ to = p;
+ while (*p != '\0')
+ {
+
+ if (*p == ' '
+ && (! isalnum ((unsigned char) p[1])
+ || ! isalnum ((unsigned char) p[-1])))
+ {
+ p++;
+
+ }
+ else if (*p == ',')
+ {
+
+ /* Start of operand */
+ if (n == 3)
+ {
+ as_bad (_("too many operands"));
+ return -1;
+ }
+ *to++ = '\0'; /* Terminate argument */
+ args[++n] = to; /* Start next argument */
+ p++;
+
+ }
+ else
+ {
+ *to++ = *p++;
+ }
+ }
+ *to = '\0';
+ return n;
+}
+
+
+/*****************************************************************************
+ get_cdisp: handle displacement for a COBR or CTRL instruction.
+
+ Parse displacement for a COBR or CTRL instruction.
+
+ If successful, output the instruction opcode and set up for it,
+ depending on the arg 'var_frag', either:
+ o an address fixup to be done when all symbol values are known, or
+ o a varying length code fragment, with address fixup info. This
+ will be done for cobr instructions that may have to be relaxed
+ in to compare/branch instructions (8 bytes) if the final
+ address displacement is greater than 13 bits.
+
+ ****************************************************************************/
+static
+void
+get_cdisp (dispP, ifmtP, instr, numbits, var_frag, callj)
+ /* displacement as specified in source instruction */
+ char *dispP;
+ /* "COBR" or "CTRL" (for use in error message) */
+ char *ifmtP;
+ /* Instruction needing the displacement */
+ long instr;
+ /* # bits of displacement (13 for COBR, 24 for CTRL) */
+ int numbits;
+ /* 1 if varying length code fragment should be emitted;
+ * 0 if an address fix should be emitted.
+ */
+ int var_frag;
+ /* 1 if callj relocation should be done; else 0 */
+ int callj;
+{
+ expressionS e; /* Parsed expression */
+ fixS *fixP; /* Structure describing needed address fix */
+ char *outP; /* Where instruction binary is output to */
+
+ fixP = NULL;
+
+ parse_expr (dispP, &e);
+ switch (e.X_op)
+ {
+ case O_illegal:
+ as_bad (_("expression syntax error"));
+
+ case O_symbol:
+ if (S_GET_SEGMENT (e.X_add_symbol) == now_seg
+ || S_GET_SEGMENT (e.X_add_symbol) == undefined_section)
+ {
+ if (var_frag)
+ {
+ outP = frag_more (8); /* Allocate worst-case storage */
+ md_number_to_chars (outP, instr, 4);
+ frag_variant (rs_machine_dependent, 4, 4, 1,
+ adds (e), offs (e), outP);
+ }
+ else
+ {
+ /* Set up a new fix structure, so address can be updated
+ * when all symbol values are known.
+ */
+ outP = emit (instr);
+ fixP = fix_new (frag_now,
+ outP - frag_now->fr_literal,
+ 4,
+ adds (e),
+ offs (e),
+ 1,
+ NO_RELOC);
+
+ fixP->fx_tcbit = callj;
+
+ /* We want to modify a bit field when the address is
+ * known. But we don't need all the garbage in the
+ * bit_fix structure. So we're going to lie and store
+ * the number of bits affected instead of a pointer.
+ */
+ fixP->fx_bit_fixP = (bit_fixS *) numbits;
+ }
+ }
+ else
+ as_bad (_("attempt to branch into different segment"));
+ break;
+
+ default:
+ as_bad (_("target of %s instruction must be a label"), ifmtP);
+ break;
+ }
+}
+
+
+/*****************************************************************************
+ get_ispec: parse a memory operand for an index specification
+
+ Here, an "index specification" is taken to be anything surrounded
+ by square brackets and NOT followed by anything else.
+
+ If it's found, detach it from the input string, remove the surrounding
+ square brackets, and return a pointer to it. Otherwise, return NULL.
+
+ *************************************************************************** */
+static
+char *
+get_ispec (textP)
+ /* Pointer to memory operand from source instruction, no white space. */
+ char *textP;
+{
+ /* Points to start of index specification. */
+ char *start;
+ /* Points to end of index specification. */
+ char *end;
+
+ /* Find opening square bracket, if any. */
+ start = strchr (textP, '[');
+
+ if (start != NULL)
+ {
+
+ /* Eliminate '[', detach from rest of operand */
+ *start++ = '\0';
+
+ end = strchr (start, ']');
+
+ if (end == NULL)
+ {
+ as_bad (_("unmatched '['"));
+
+ }
+ else
+ {
+ /* Eliminate ']' and make sure it was the last thing
+ * in the string.
+ */
+ *end = '\0';
+ if (*(end + 1) != '\0')
+ {
+ as_bad (_("garbage after index spec ignored"));
+ }
+ }
+ }
+ return start;
+}
+
+/*****************************************************************************
+ get_regnum:
+
+ Look up a (suspected) register name in the register table and return the
+ associated register number (or -1 if not found).
+
+ *************************************************************************** */
+static
+int
+get_regnum (regname)
+ char *regname; /* Suspected register name */
+{
+ int *rP;
+
+ rP = (int *) hash_find (reg_hash, regname);
+ return (rP == NULL) ? -1 : *rP;
+}
+
+
+/*****************************************************************************
+ i_scan: perform lexical scan of ascii assembler instruction.
+
+ Input assumptions:
+ - input string is an i80960 instruction (not a pseudo-op)
+ - all comments and labels have been removed
+ - all strings of whitespace have been collapsed to a single blank.
+
+ Output:
+ args[0] points to opcode, other entries point to operands. All strings:
+ - are NULL-terminated
+ - contain no whitespace
+ - have character constants ('x') replaced with a decimal number
+
+ Return value:
+ Number of operands (0,1,2, or 3) or -1 on error.
+
+ *************************************************************************** */
+static int
+i_scan (iP, args)
+ /* Pointer to ascii instruction; MUCKED BY US. */
+ register char *iP;
+ /* Output arg: pointers to opcode and operands placed here. MUST
+ ACCOMMODATE 4 ENTRIES. */
+ char *args[];
+{
+
+ /* Isolate opcode */
+ if (*(iP) == ' ')
+ {
+ iP++;
+ } /* Skip lead space, if any */
+ args[0] = iP;
+ for (; *iP != ' '; iP++)
+ {
+ if (*iP == '\0')
+ {
+ /* There are no operands */
+ if (args[0] == iP)
+ {
+ /* We never moved: there was no opcode either! */
+ as_bad (_("missing opcode"));
+ return -1;
+ }
+ return 0;
+ }
+ }
+ *iP++ = '\0'; /* Terminate opcode */
+ return (get_args (iP, args));
+} /* i_scan() */
+
+
+/*****************************************************************************
+ mem_fmt: generate a MEMA- or MEMB-format instruction
+
+ *************************************************************************** */
+static void
+mem_fmt (args, oP, callx)
+ char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */
+ struct i960_opcode *oP; /* Pointer to description of instruction */
+ int callx; /* Is this a callx opcode */
+{
+ int i; /* Loop counter */
+ struct regop regop; /* Description of register operand */
+ char opdesc; /* Operand descriptor byte */
+ memS instr; /* Description of binary to be output */
+ char *outP; /* Where the binary was output to */
+ expressionS expr; /* Parsed expression */
+ /* ->description of deferred address fixup */
+ fixS *fixP;
+
+#ifdef OBJ_COFF
+ /* COFF support isn't in place yet for callx relaxing. */
+ callx = 0;
+#endif
+
+ memset (&instr, '\0', sizeof (memS));
+ instr.opcode = oP->opcode;
+
+ /* Process operands. */
+ for (i = 1; i <= oP->num_ops; i++)
+ {
+ opdesc = oP->operand[i - 1];
+
+ if (MEMOP (opdesc))
+ {
+ parse_memop (&instr, args[i], oP->format);
+ }
+ else
+ {
+ parse_regop (&regop, args[i], opdesc);
+ instr.opcode |= regop.n << 19;
+ }
+ }
+
+ /* Parse the displacement; this must be done before emitting the
+ opcode, in case it is an expression using `.'. */
+ parse_expr (instr.e, &expr);
+
+ /* Output opcode */
+ outP = emit (instr.opcode);
+
+ if (instr.disp == 0)
+ {
+ return;
+ }
+
+ /* Process the displacement */
+ switch (expr.X_op)
+ {
+ case O_illegal:
+ as_bad (_("expression syntax error"));
+ break;
+
+ case O_constant:
+ if (instr.disp == 32)
+ {
+ (void) emit (offs (expr)); /* Output displacement */
+ }
+ else
+ {
+ /* 12-bit displacement */
+ if (offs (expr) & ~0xfff)
+ {
+ /* Won't fit in 12 bits: convert already-output
+ * instruction to MEMB format, output
+ * displacement.
+ */
+ mema_to_memb (outP);
+ (void) emit (offs (expr));
+ }
+ else
+ {
+ /* WILL fit in 12 bits: OR into opcode and
+ * overwrite the binary we already put out
+ */
+ instr.opcode |= offs (expr);
+ md_number_to_chars (outP, instr.opcode, 4);
+ }
+ }
+ break;
+
+ default:
+ if (instr.disp == 12)
+ {
+ /* Displacement is dependent on a symbol, whose value
+ * may change at link time. We HAVE to reserve 32 bits.
+ * Convert already-output opcode to MEMB format.
+ */
+ mema_to_memb (outP);
+ }
+
+ /* Output 0 displacement and set up address fixup for when
+ * this symbol's value becomes known.
+ */
+ outP = emit ((long) 0);
+ fixP = fix_new_exp (frag_now,
+ outP - frag_now->fr_literal,
+ 4,
+ &expr,
+ 0,
+ NO_RELOC);
+ /* Steve's linker relaxing hack. Mark this 32-bit relocation as
+ being in the instruction stream, specifically as part of a callx
+ instruction. */
+ fixP->fx_bsr = callx;
+ break;
+ }
+} /* memfmt() */
+
+
+/*****************************************************************************
+ mema_to_memb: convert a MEMA-format opcode to a MEMB-format opcode.
+
+ There are 2 possible MEMA formats:
+ - displacement only
+ - displacement + abase
+
+ They are distinguished by the setting of the MEMA_ABASE bit.
+
+ *************************************************************************** */
+static void
+mema_to_memb (opcodeP)
+ char *opcodeP; /* Where to find the opcode, in target byte order */
+{
+ long opcode; /* Opcode in host byte order */
+ long mode; /* Mode bits for MEMB instruction */
+
+ opcode = md_chars_to_number (opcodeP, 4);
+ know (!(opcode & MEMB_BIT));
+
+ mode = MEMB_BIT | D_BIT;
+ if (opcode & MEMA_ABASE)
+ {
+ mode |= A_BIT;
+ }
+
+ opcode &= 0xffffc000; /* Clear MEMA offset and mode bits */
+ opcode |= mode; /* Set MEMB mode bits */
+
+ md_number_to_chars (opcodeP, opcode, 4);
+} /* mema_to_memb() */
+
+
+/*****************************************************************************
+ parse_expr: parse an expression
+
+ Use base assembler's expression parser to parse an expression.
+ It, unfortunately, runs off a global which we have to save/restore
+ in order to make it work for us.
+
+ An empty expression string is treated as an absolute 0.
+
+ Sets O_illegal regardless of expression evaluation if entire input
+ string is not consumed in the evaluation -- tolerate no dangling junk!
+
+ *************************************************************************** */
+static void
+parse_expr (textP, expP)
+ char *textP; /* Text of expression to be parsed */
+ expressionS *expP; /* Where to put the results of parsing */
+{
+ char *save_in; /* Save global here */
+ symbolS *symP;
+
+ know (textP);
+
+ if (*textP == '\0')
+ {
+ /* Treat empty string as absolute 0 */
+ expP->X_add_symbol = expP->X_op_symbol = NULL;
+ expP->X_add_number = 0;
+ expP->X_op = O_constant;
+ }
+ else
+ {
+ save_in = input_line_pointer; /* Save global */
+ input_line_pointer = textP; /* Make parser work for us */
+
+ (void) expression (expP);
+ if ((size_t) (input_line_pointer - textP) != strlen (textP))
+ {
+ /* Did not consume all of the input */
+ expP->X_op = O_illegal;
+ }
+ symP = expP->X_add_symbol;
+ if (symP && (hash_find (reg_hash, S_GET_NAME (symP))))
+ {
+ /* Register name in an expression */
+ /* FIXME: this isn't much of a check any more. */
+ expP->X_op = O_illegal;
+ }
+
+ input_line_pointer = save_in; /* Restore global */
+ }
+}
+
+
+/*****************************************************************************
+ parse_ldcont:
+ Parse and replace a 'ldconst' pseudo-instruction with an appropriate
+ i80960 instruction.
+
+ Assumes the input consists of:
+ arg[0] opcode mnemonic ('ldconst')
+ arg[1] first operand (constant)
+ arg[2] name of register to be loaded
+
+ Replaces opcode and/or operands as appropriate.
+
+ Returns the new number of arguments, or -1 on failure.
+
+ *************************************************************************** */
+static
+int
+parse_ldconst (arg)
+ char *arg[]; /* See above */
+{
+ int n; /* Constant to be loaded */
+ int shift; /* Shift count for "shlo" instruction */
+ static char buf[5]; /* Literal for first operand */
+ static char buf2[5]; /* Literal for second operand */
+ expressionS e; /* Parsed expression */
+
+
+ arg[3] = NULL; /* So we can tell at the end if it got used or not */
+
+ parse_expr (arg[1], &e);
+ switch (e.X_op)
+ {
+ default:
+ /* We're dependent on one or more symbols -- use "lda" */
+ arg[0] = "lda";
+ break;
+
+ case O_constant:
+ /* Try the following mappings:
+ * ldconst 0,<reg> ->mov 0,<reg>
+ * ldconst 31,<reg> ->mov 31,<reg>
+ * ldconst 32,<reg> ->addo 1,31,<reg>
+ * ldconst 62,<reg> ->addo 31,31,<reg>
+ * ldconst 64,<reg> ->shlo 8,3,<reg>
+ * ldconst -1,<reg> ->subo 1,0,<reg>
+ * ldconst -31,<reg>->subo 31,0,<reg>
+ *
+ * anthing else becomes:
+ * lda xxx,<reg>
+ */
+ n = offs (e);
+ if ((0 <= n) && (n <= 31))
+ {
+ arg[0] = "mov";
+
+ }
+ else if ((-31 <= n) && (n <= -1))
+ {
+ arg[0] = "subo";
+ arg[3] = arg[2];
+ sprintf (buf, "%d", -n);
+ arg[1] = buf;
+ arg[2] = "0";
+
+ }
+ else if ((32 <= n) && (n <= 62))
+ {
+ arg[0] = "addo";
+ arg[3] = arg[2];
+ arg[1] = "31";
+ sprintf (buf, "%d", n - 31);
+ arg[2] = buf;
+
+ }
+ else if ((shift = shift_ok (n)) != 0)
+ {
+ arg[0] = "shlo";
+ arg[3] = arg[2];
+ sprintf (buf, "%d", shift);
+ arg[1] = buf;
+ sprintf (buf2, "%d", n >> shift);
+ arg[2] = buf2;
+
+ }
+ else
+ {
+ arg[0] = "lda";
+ }
+ break;
+
+ case O_illegal:
+ as_bad (_("invalid constant"));
+ return -1;
+ break;
+ }
+ return (arg[3] == 0) ? 2 : 3;
+}
+
+/*****************************************************************************
+ parse_memop: parse a memory operand
+
+ This routine is based on the observation that the 4 mode bits of the
+ MEMB format, taken individually, have fairly consistent meaning:
+
+ M3 (bit 13): 1 if displacement is present (D_BIT)
+ M2 (bit 12): 1 for MEMB instructions (MEMB_BIT)
+ M1 (bit 11): 1 if index is present (I_BIT)
+ M0 (bit 10): 1 if abase is present (A_BIT)
+
+ So we parse the memory operand and set bits in the mode as we find
+ things. Then at the end, if we go to MEMB format, we need only set
+ the MEMB bit (M2) and our mode is built for us.
+
+ Unfortunately, I said "fairly consistent". The exceptions:
+
+ DBIA
+ 0100 Would seem illegal, but means "abase-only".
+
+ 0101 Would seem to mean "abase-only" -- it means IP-relative.
+ Must be converted to 0100.
+
+ 0110 Would seem to mean "index-only", but is reserved.
+ We turn on the D bit and provide a 0 displacement.
+
+ The other thing to observe is that we parse from the right, peeling
+ things * off as we go: first any index spec, then any abase, then
+ the displacement.
+
+ *************************************************************************** */
+static
+void
+parse_memop (memP, argP, optype)
+ memS *memP; /* Where to put the results */
+ char *argP; /* Text of the operand to be parsed */
+ int optype; /* MEM1, MEM2, MEM4, MEM8, MEM12, or MEM16 */
+{
+ char *indexP; /* Pointer to index specification with "[]" removed */
+ char *p; /* Temp char pointer */
+ char iprel_flag; /* True if this is an IP-relative operand */
+ int regnum; /* Register number */
+ /* Scale factor: 1,2,4,8, or 16. Later converted to internal format
+ (0,1,2,3,4 respectively). */
+ int scale;
+ int mode; /* MEMB mode bits */
+ int *intP; /* Pointer to register number */
+
+ /* The following table contains the default scale factors for each
+ type of memory instruction. It is accessed using (optype-MEM1)
+ as an index -- thus it assumes the 'optype' constants are
+ assigned consecutive values, in the order they appear in this
+ table. */
+ static const int def_scale[] =
+ {
+ 1, /* MEM1 */
+ 2, /* MEM2 */
+ 4, /* MEM4 */
+ 8, /* MEM8 */
+ -1, /* MEM12 -- no valid default */
+ 16 /* MEM16 */
+ };
+
+
+ iprel_flag = mode = 0;
+
+ /* Any index present? */
+ indexP = get_ispec (argP);
+ if (indexP)
+ {
+ p = strchr (indexP, '*');
+ if (p == NULL)
+ {
+ /* No explicit scale -- use default for this instruction
+ type and assembler mode. */
+ if (flag_mri)
+ scale = 1;
+ else
+ /* GNU960 compatibility */
+ scale = def_scale[optype - MEM1];
+ }
+ else
+ {
+ *p++ = '\0'; /* Eliminate '*' */
+
+ /* Now indexP->a '\0'-terminated register name,
+ * and p->a scale factor.
+ */
+
+ if (!strcmp (p, "16"))
+ {
+ scale = 16;
+ }
+ else if (strchr ("1248", *p) && (p[1] == '\0'))
+ {
+ scale = *p - '0';
+ }
+ else
+ {
+ scale = -1;
+ }
+ }
+
+ regnum = get_regnum (indexP); /* Get index reg. # */
+ if (!IS_RG_REG (regnum))
+ {
+ as_bad (_("invalid index register"));
+ return;
+ }
+
+ /* Convert scale to its binary encoding */
+ switch (scale)
+ {
+ case 1:
+ scale = 0 << 7;
+ break;
+ case 2:
+ scale = 1 << 7;
+ break;
+ case 4:
+ scale = 2 << 7;
+ break;
+ case 8:
+ scale = 3 << 7;
+ break;
+ case 16:
+ scale = 4 << 7;
+ break;
+ default:
+ as_bad (_("invalid scale factor"));
+ return;
+ };
+
+ memP->opcode |= scale | regnum; /* Set index bits in opcode */
+ mode |= I_BIT; /* Found a valid index spec */
+ }
+
+ /* Any abase (Register Indirect) specification present? */
+ if ((p = strrchr (argP, '(')) != NULL)
+ {
+ /* "(" is there -- does it start a legal abase spec? If not, it
+ could be part of a displacement expression. */
+ intP = (int *) hash_find (areg_hash, p);
+ if (intP != NULL)
+ {
+ /* Got an abase here */
+ regnum = *intP;
+ *p = '\0'; /* discard register spec */
+ if (regnum == IPREL)
+ {
+ /* We have to specialcase ip-rel mode */
+ iprel_flag = 1;
+ }
+ else
+ {
+ memP->opcode |= regnum << 14;
+ mode |= A_BIT;
+ }
+ }
+ }
+
+ /* Any expression present? */
+ memP->e = argP;
+ if (*argP != '\0')
+ {
+ mode |= D_BIT;
+ }
+
+ /* Special-case ip-relative addressing */
+ if (iprel_flag)
+ {
+ if (mode & I_BIT)
+ {
+ syntax ();
+ }
+ else
+ {
+ memP->opcode |= 5 << 10; /* IP-relative mode */
+ memP->disp = 32;
+ }
+ return;
+ }
+
+ /* Handle all other modes */
+ switch (mode)
+ {
+ case D_BIT | A_BIT:
+ /* Go with MEMA instruction format for now (grow to MEMB later
+ if 12 bits is not enough for the displacement). MEMA format
+ has a single mode bit: set it to indicate that abase is
+ present. */
+ memP->opcode |= MEMA_ABASE;
+ memP->disp = 12;
+ break;
+
+ case D_BIT:
+ /* Go with MEMA instruction format for now (grow to MEMB later
+ if 12 bits is not enough for the displacement). */
+ memP->disp = 12;
+ break;
+
+ case A_BIT:
+ /* For some reason, the bit string for this mode is not
+ consistent: it should be 0 (exclusive of the MEMB bit), so we
+ set it "by hand" here. */
+ memP->opcode |= MEMB_BIT;
+ break;
+
+ case A_BIT | I_BIT:
+ /* set MEMB bit in mode, and OR in mode bits */
+ memP->opcode |= mode | MEMB_BIT;
+ break;
+
+ case I_BIT:
+ /* Treat missing displacement as displacement of 0. */
+ mode |= D_BIT;
+ /* Fall into next case. */
+ case D_BIT | A_BIT | I_BIT:
+ case D_BIT | I_BIT:
+ /* set MEMB bit in mode, and OR in mode bits */
+ memP->opcode |= mode | MEMB_BIT;
+ memP->disp = 32;
+ break;
+
+ default:
+ syntax ();
+ break;
+ }
+}
+
+/*****************************************************************************
+ parse_po: parse machine-dependent pseudo-op
+
+ This is a top-level routine for machine-dependent pseudo-ops. It slurps
+ up the rest of the input line, breaks out the individual arguments,
+ and dispatches them to the correct handler.
+ *************************************************************************** */
+static
+void
+parse_po (po_num)
+ int po_num; /* Pseudo-op number: currently S_LEAFPROC or S_SYSPROC */
+{
+ /* Pointers operands, with no embedded whitespace.
+ arg[0] unused, arg[1-3]->operands */
+ char *args[4];
+ int n_ops; /* Number of operands */
+ char *p; /* Pointer to beginning of unparsed argument string */
+ char eol; /* Character that indicated end of line */
+
+ extern char is_end_of_line[];
+
+ /* Advance input pointer to end of line. */
+ p = input_line_pointer;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ input_line_pointer++;
+ }
+ eol = *input_line_pointer; /* Save end-of-line char */
+ *input_line_pointer = '\0'; /* Terminate argument list */
+
+ /* Parse out operands */
+ n_ops = get_args (p, args);
+ if (n_ops == -1)
+ {
+ return;
+ }
+
+ /* Dispatch to correct handler */
+ switch (po_num)
+ {
+ case S_SYSPROC:
+ s_sysproc (n_ops, args);
+ break;
+ case S_LEAFPROC:
+ s_leafproc (n_ops, args);
+ break;
+ default:
+ BAD_CASE (po_num);
+ break;
+ }
+
+ /* Restore eol, so line numbers get updated correctly. Base
+ assembler assumes we leave input pointer pointing at char
+ following the eol. */
+ *input_line_pointer++ = eol;
+}
+
+/*****************************************************************************
+ parse_regop: parse a register operand.
+
+ In case of illegal operand, issue a message and return some valid
+ information so instruction processing can continue.
+ *************************************************************************** */
+static
+void
+parse_regop (regopP, optext, opdesc)
+ struct regop *regopP; /* Where to put description of register operand */
+ char *optext; /* Text of operand */
+ char opdesc; /* Descriptor byte: what's legal for this operand */
+{
+ int n; /* Register number */
+ expressionS e; /* Parsed expression */
+
+ /* See if operand is a register */
+ n = get_regnum (optext);
+ if (n >= 0)
+ {
+ if (IS_RG_REG (n))
+ {
+ /* global or local register */
+ if (!REG_ALIGN (opdesc, n))
+ {
+ as_bad (_("unaligned register"));
+ }
+ regopP->n = n;
+ regopP->mode = 0;
+ regopP->special = 0;
+ return;
+ }
+ else if (IS_FP_REG (n) && FP_OK (opdesc))
+ {
+ /* Floating point register, and it's allowed */
+ regopP->n = n - FP0;
+ regopP->mode = 1;
+ regopP->special = 0;
+ return;
+ }
+ else if (IS_SF_REG (n) && SFR_OK (opdesc))
+ {
+ /* Special-function register, and it's allowed */
+ regopP->n = n - SF0;
+ regopP->mode = 0;
+ regopP->special = 1;
+ if (!targ_has_sfr (regopP->n))
+ {
+ as_bad (_("no such sfr in this architecture"));
+ }
+ return;
+ }
+ }
+ else if (LIT_OK (opdesc))
+ {
+ /* How about a literal? */
+ regopP->mode = 1;
+ regopP->special = 0;
+ if (FP_OK (opdesc))
+ { /* floating point literal acceptable */
+ /* Skip over 0f, 0d, or 0e prefix */
+ if ((optext[0] == '0')
+ && (optext[1] >= 'd')
+ && (optext[1] <= 'f'))
+ {
+ optext += 2;
+ }
+
+ if (!strcmp (optext, "0.0") || !strcmp (optext, "0"))
+ {
+ regopP->n = 0x10;
+ return;
+ }
+ if (!strcmp (optext, "1.0") || !strcmp (optext, "1"))
+ {
+ regopP->n = 0x16;
+ return;
+ }
+
+ }
+ else
+ { /* fixed point literal acceptable */
+ parse_expr (optext, &e);
+ if (e.X_op != O_constant
+ || (offs (e) < 0) || (offs (e) > 31))
+ {
+ as_bad (_("illegal literal"));
+ offs (e) = 0;
+ }
+ regopP->n = offs (e);
+ return;
+ }
+ }
+
+ /* Nothing worked */
+ syntax ();
+ regopP->mode = 0; /* Register r0 is always a good one */
+ regopP->n = 0;
+ regopP->special = 0;
+} /* parse_regop() */
+
+/*****************************************************************************
+ reg_fmt: generate a REG-format instruction
+
+ *************************************************************************** */
+static void
+reg_fmt (args, oP)
+ char *args[]; /* args[0]->opcode mnemonic, args[1-3]->operands */
+ struct i960_opcode *oP; /* Pointer to description of instruction */
+{
+ long instr; /* Binary to be output */
+ struct regop regop; /* Description of register operand */
+ int n_ops; /* Number of operands */
+
+
+ instr = oP->opcode;
+ n_ops = oP->num_ops;
+
+ if (n_ops >= 1)
+ {
+ parse_regop (&regop, args[1], oP->operand[0]);
+
+ if ((n_ops == 1) && !(instr & M3))
+ {
+ /* 1-operand instruction in which the dst field should
+ * be used (instead of src1).
+ */
+ regop.n <<= 19;
+ if (regop.special)
+ {
+ regop.mode = regop.special;
+ }
+ regop.mode <<= 13;
+ regop.special = 0;
+ }
+ else
+ {
+ /* regop.n goes in bit 0, needs no shifting */
+ regop.mode <<= 11;
+ regop.special <<= 5;
+ }
+ instr |= regop.n | regop.mode | regop.special;
+ }
+
+ if (n_ops >= 2)
+ {
+ parse_regop (&regop, args[2], oP->operand[1]);
+
+ if ((n_ops == 2) && !(instr & M3))
+ {
+ /* 2-operand instruction in which the dst field should
+ * be used instead of src2).
+ */
+ regop.n <<= 19;
+ if (regop.special)
+ {
+ regop.mode = regop.special;
+ }
+ regop.mode <<= 13;
+ regop.special = 0;
+ }
+ else
+ {
+ regop.n <<= 14;
+ regop.mode <<= 12;
+ regop.special <<= 6;
+ }
+ instr |= regop.n | regop.mode | regop.special;
+ }
+ if (n_ops == 3)
+ {
+ parse_regop (&regop, args[3], oP->operand[2]);
+ if (regop.special)
+ {
+ regop.mode = regop.special;
+ }
+ instr |= (regop.n <<= 19) | (regop.mode <<= 13);
+ }
+ emit (instr);
+}
+
+
+/*****************************************************************************
+ relax_cobr:
+ Replace cobr instruction in a code fragment with equivalent branch and
+ compare instructions, so it can reach beyond a 13-bit displacement.
+ Set up an address fix/relocation for the new branch instruction.
+
+ *************************************************************************** */
+
+/* This "conditional jump" table maps cobr instructions into
+ equivalent compare and branch opcodes. */
+static const
+struct
+{
+ long compare;
+ long branch;
+}
+
+coj[] =
+{ /* COBR OPCODE: */
+ { CHKBIT, BNO }, /* 0x30 - bbc */
+ { CMPO, BG }, /* 0x31 - cmpobg */
+ { CMPO, BE }, /* 0x32 - cmpobe */
+ { CMPO, BGE }, /* 0x33 - cmpobge */
+ { CMPO, BL }, /* 0x34 - cmpobl */
+ { CMPO, BNE }, /* 0x35 - cmpobne */
+ { CMPO, BLE }, /* 0x36 - cmpoble */
+ { CHKBIT, BO }, /* 0x37 - bbs */
+ { CMPI, BNO }, /* 0x38 - cmpibno */
+ { CMPI, BG }, /* 0x39 - cmpibg */
+ { CMPI, BE }, /* 0x3a - cmpibe */
+ { CMPI, BGE }, /* 0x3b - cmpibge */
+ { CMPI, BL }, /* 0x3c - cmpibl */
+ { CMPI, BNE }, /* 0x3d - cmpibne */
+ { CMPI, BLE }, /* 0x3e - cmpible */
+ { CMPI, BO }, /* 0x3f - cmpibo */
+};
+
+static
+void
+relax_cobr (fragP)
+ register fragS *fragP; /* fragP->fr_opcode is assumed to point to
+ * the cobr instruction, which comes at the
+ * end of the code fragment.
+ */
+{
+ int opcode, src1, src2, m1, s2;
+ /* Bit fields from cobr instruction */
+ long bp_bits; /* Branch prediction bits from cobr instruction */
+ long instr; /* A single i960 instruction */
+ /* ->instruction to be replaced */
+ char *iP;
+ fixS *fixP; /* Relocation that can be done at assembly time */
+
+ /* PICK UP & PARSE COBR INSTRUCTION */
+ iP = fragP->fr_opcode;
+ instr = md_chars_to_number (iP, 4);
+ opcode = ((instr >> 24) & 0xff) - 0x30; /* "-0x30" for table index */
+ src1 = (instr >> 19) & 0x1f;
+ m1 = (instr >> 13) & 1;
+ s2 = instr & 1;
+ src2 = (instr >> 14) & 0x1f;
+ bp_bits = instr & BP_MASK;
+
+ /* GENERATE AND OUTPUT COMPARE INSTRUCTION */
+ instr = coj[opcode].compare
+ | src1 | (m1 << 11) | (s2 << 6) | (src2 << 14);
+ md_number_to_chars (iP, instr, 4);
+
+ /* OUTPUT BRANCH INSTRUCTION */
+ md_number_to_chars (iP + 4, coj[opcode].branch | bp_bits, 4);
+
+ /* SET UP ADDRESS FIXUP/RELOCATION */
+ fixP = fix_new (fragP,
+ iP + 4 - fragP->fr_literal,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 1,
+ NO_RELOC);
+
+ fixP->fx_bit_fixP = (bit_fixS *) 24; /* Store size of bit field */
+
+ fragP->fr_fix += 4;
+ frag_wane (fragP);
+}
+
+
+/*****************************************************************************
+ reloc_callj: Relocate a 'callj' instruction
+
+ This is a "non-(GNU)-standard" machine-dependent hook. The base
+ assembler calls it when it decides it can relocate an address at
+ assembly time instead of emitting a relocation directive.
+
+ Check to see if the relocation involves a 'callj' instruction to a:
+ sysproc: Replace the default 'call' instruction with a 'calls'
+ leafproc: Replace the default 'call' instruction with a 'bal'.
+ other proc: Do nothing.
+
+ See b.out.h for details on the 'n_other' field in a symbol structure.
+
+ IMPORTANT!:
+ Assumes the caller has already figured out, in the case of a leafproc,
+ to use the 'bal' entry point, and has substituted that symbol into the
+ passed fixup structure.
+
+ *************************************************************************** */
+void
+reloc_callj (fixP)
+ /* Relocation that can be done at assembly time */
+ fixS *fixP;
+{
+ /* Points to the binary for the instruction being relocated. */
+ char *where;
+
+ if (!fixP->fx_tcbit)
+ {
+ /* This wasn't a callj instruction in the first place */
+ return;
+ }
+
+ where = fixP->fx_frag->fr_literal + fixP->fx_where;
+
+ if (TC_S_IS_SYSPROC (fixP->fx_addsy))
+ {
+ /* Symbol is a .sysproc: replace 'call' with 'calls'. System
+ procedure number is (other-1). */
+ md_number_to_chars (where, CALLS | TC_S_GET_SYSPROC (fixP->fx_addsy), 4);
+
+ /* Nothing else needs to be done for this instruction. Make
+ sure 'md_number_to_field()' will perform a no-op. */
+ fixP->fx_bit_fixP = (bit_fixS *) 1;
+
+ }
+ else if (TC_S_IS_CALLNAME (fixP->fx_addsy))
+ {
+ /* Should not happen: see block comment above */
+ as_fatal (_("Trying to 'bal' to %s"), S_GET_NAME (fixP->fx_addsy));
+ }
+ else if (TC_S_IS_BALNAME (fixP->fx_addsy))
+ {
+ /* Replace 'call' with 'bal'; both instructions have the same
+ format, so calling code should complete relocation as if
+ nothing happened here. */
+ md_number_to_chars (where, BAL, 4);
+ }
+ else if (TC_S_IS_BADPROC (fixP->fx_addsy))
+ {
+ as_bad (_("Looks like a proc, but can't tell what kind.\n"));
+ } /* switch on proc type */
+
+ /* else Symbol is neither a sysproc nor a leafproc */
+}
+
+
+/*****************************************************************************
+ s_leafproc: process .leafproc pseudo-op
+
+ .leafproc takes two arguments, the second one is optional:
+ arg[1]: name of 'call' entry point to leaf procedure
+ arg[2]: name of 'bal' entry point to leaf procedure
+
+ If the two arguments are identical, or if the second one is missing,
+ the first argument is taken to be the 'bal' entry point.
+
+ If there are 2 distinct arguments, we must make sure that the 'bal'
+ entry point immediately follows the 'call' entry point in the linked
+ list of symbols.
+
+ *************************************************************************** */
+static void
+s_leafproc (n_ops, args)
+ int n_ops; /* Number of operands */
+ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */
+{
+ symbolS *callP; /* Pointer to leafproc 'call' entry point symbol */
+ symbolS *balP; /* Pointer to leafproc 'bal' entry point symbol */
+
+ if ((n_ops != 1) && (n_ops != 2))
+ {
+ as_bad (_("should have 1 or 2 operands"));
+ return;
+ } /* Check number of arguments */
+
+ /* Find or create symbol for 'call' entry point. */
+ callP = symbol_find_or_make (args[1]);
+
+ if (TC_S_IS_CALLNAME (callP))
+ {
+ as_warn (_("Redefining leafproc %s"), S_GET_NAME (callP));
+ } /* is leafproc */
+
+ /* If that was the only argument, use it as the 'bal' entry point.
+ * Otherwise, mark it as the 'call' entry point and find or create
+ * another symbol for the 'bal' entry point.
+ */
+ if ((n_ops == 1) || !strcmp (args[1], args[2]))
+ {
+ TC_S_FORCE_TO_BALNAME (callP);
+
+ }
+ else
+ {
+ TC_S_FORCE_TO_CALLNAME (callP);
+
+ balP = symbol_find_or_make (args[2]);
+ if (TC_S_IS_CALLNAME (balP))
+ {
+ as_warn (_("Redefining leafproc %s"), S_GET_NAME (balP));
+ }
+ TC_S_FORCE_TO_BALNAME (balP);
+
+ tc_set_bal_of_call (callP, balP);
+ } /* if only one arg, or the args are the same */
+}
+
+
+/*
+ s_sysproc: process .sysproc pseudo-op
+
+ .sysproc takes two arguments:
+ arg[1]: name of entry point to system procedure
+ arg[2]: 'entry_num' (index) of system procedure in the range
+ [0,31] inclusive.
+
+ For [ab].out, we store the 'entrynum' in the 'n_other' field of
+ the symbol. Since that entry is normally 0, we bias 'entrynum'
+ by adding 1 to it. It must be unbiased before it is used. */
+static void
+s_sysproc (n_ops, args)
+ int n_ops; /* Number of operands */
+ char *args[]; /* args[1]->1st operand, args[2]->2nd operand */
+{
+ expressionS exp;
+ symbolS *symP;
+
+ if (n_ops != 2)
+ {
+ as_bad (_("should have two operands"));
+ return;
+ } /* bad arg count */
+
+ /* Parse "entry_num" argument and check it for validity. */
+ parse_expr (args[2], &exp);
+ if (exp.X_op != O_constant
+ || (offs (exp) < 0)
+ || (offs (exp) > 31))
+ {
+ as_bad (_("'entry_num' must be absolute number in [0,31]"));
+ return;
+ }
+
+ /* Find/make symbol and stick entry number (biased by +1) into it */
+ symP = symbol_find_or_make (args[1]);
+
+ if (TC_S_IS_SYSPROC (symP))
+ {
+ as_warn (_("Redefining entrynum for sysproc %s"), S_GET_NAME (symP));
+ } /* redefining */
+
+ TC_S_SET_SYSPROC (symP, offs (exp)); /* encode entry number */
+ TC_S_FORCE_TO_SYSPROC (symP);
+}
+
+
+/*****************************************************************************
+ shift_ok:
+ Determine if a "shlo" instruction can be used to implement a "ldconst".
+ This means that some number X < 32 can be shifted left to produce the
+ constant of interest.
+
+ Return the shift count, or 0 if we can't do it.
+ Caller calculates X by shifting original constant right 'shift' places.
+
+ *************************************************************************** */
+static
+int
+shift_ok (n)
+ int n; /* The constant of interest */
+{
+ int shift; /* The shift count */
+
+ if (n <= 0)
+ {
+ /* Can't do it for negative numbers */
+ return 0;
+ }
+
+ /* Shift 'n' right until a 1 is about to be lost */
+ for (shift = 0; (n & 1) == 0; shift++)
+ {
+ n >>= 1;
+ }
+
+ if (n >= 32)
+ {
+ return 0;
+ }
+ return shift;
+}
+
+
+/* syntax: issue syntax error */
+
+static void
+syntax ()
+{
+ as_bad (_("syntax error"));
+} /* syntax() */
+
+
+/* targ_has_sfr:
+
+ Return TRUE iff the target architecture supports the specified
+ special-function register (sfr). */
+
+static
+int
+targ_has_sfr (n)
+ int n; /* Number (0-31) of sfr */
+{
+ switch (architecture)
+ {
+ case ARCH_KA:
+ case ARCH_KB:
+ case ARCH_MC:
+ case ARCH_JX:
+ return 0;
+ case ARCH_HX:
+ return ((0 <= n) && (n <= 4));
+ case ARCH_CA:
+ default:
+ return ((0 <= n) && (n <= 2));
+ }
+}
+
+
+/* targ_has_iclass:
+
+ Return TRUE iff the target architecture supports the indicated
+ class of instructions. */
+static
+int
+targ_has_iclass (ic)
+ /* Instruction class; one of:
+ I_BASE, I_CX, I_DEC, I_KX, I_FP, I_MIL, I_CASIM, I_CX2, I_HX, I_HX2
+ */
+ int ic;
+{
+ iclasses_seen |= ic;
+ switch (architecture)
+ {
+ case ARCH_KA:
+ return ic & (I_BASE | I_KX);
+ case ARCH_KB:
+ return ic & (I_BASE | I_KX | I_FP | I_DEC);
+ case ARCH_MC:
+ return ic & (I_BASE | I_KX | I_FP | I_DEC | I_MIL);
+ case ARCH_CA:
+ return ic & (I_BASE | I_CX | I_CX2 | I_CASIM);
+ case ARCH_JX:
+ return ic & (I_BASE | I_CX2 | I_JX);
+ case ARCH_HX:
+ return ic & (I_BASE | I_CX2 | I_JX | I_HX);
+ default:
+ if ((iclasses_seen & (I_KX | I_FP | I_DEC | I_MIL))
+ && (iclasses_seen & (I_CX | I_CX2)))
+ {
+ as_warn (_("architecture of opcode conflicts with that of earlier instruction(s)"));
+ iclasses_seen &= ~ic;
+ }
+ return 1;
+ }
+}
+
+/* Handle the MRI .endian pseudo-op. */
+
+static void
+s_endian (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (name, "little") == 0)
+ ;
+ else if (strcasecmp (name, "big") == 0)
+ as_bad (_("big endian mode is not supported"));
+ else
+ as_warn (_("ignoring unrecognized .endian type `%s'"), name);
+
+ *input_line_pointer = c;
+
+ demand_empty_rest_of_line ();
+}
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the i960, they're relative to the address of the instruction,
+ which we have set up as the address of the fixup too. */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ if (!fixP->fx_bit_fixP)
+ {
+ /* For callx, we always want to write out zero, and emit a
+ symbolic relocation. */
+ if (fixP->fx_bsr)
+ val = 0;
+
+ fixP->fx_addnumber = val;
+ md_number_to_imm (place, val, fixP->fx_size, fixP);
+ }
+ else
+ md_number_to_field (place, val, fixP->fx_bit_fixP);
+}
+
+#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
+void
+tc_bout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
+ struct relocation_info ri;
+ symbolS *symbolP;
+
+ memset ((char *) &ri, '\0', sizeof (ri));
+ symbolP = fixP->fx_addsy;
+ know (symbolP != 0 || fixP->fx_r_type != NO_RELOC);
+ ri.r_bsr = fixP->fx_bsr; /*SAC LD RELAX HACK */
+ /* These two 'cuz of NS32K */
+ ri.r_callj = fixP->fx_tcbit;
+ if (fixP->fx_bit_fixP)
+ ri.r_length = 2;
+ else
+ ri.r_length = nbytes_r_length[fixP->fx_size];
+ ri.r_pcrel = fixP->fx_pcrel;
+ ri.r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file;
+
+ if (fixP->fx_r_type != NO_RELOC)
+ {
+ switch (fixP->fx_r_type)
+ {
+ case rs_align:
+ ri.r_index = -2;
+ ri.r_pcrel = 1;
+ ri.r_length = fixP->fx_size - 1;
+ break;
+ case rs_org:
+ ri.r_index = -2;
+ ri.r_pcrel = 0;
+ break;
+ case rs_fill:
+ ri.r_index = -1;
+ break;
+ default:
+ abort ();
+ }
+ ri.r_extern = 0;
+ }
+ else if (linkrelax || !S_IS_DEFINED (symbolP) || fixP->fx_bsr)
+ {
+ ri.r_extern = 1;
+ ri.r_index = symbolP->sy_number;
+ }
+ else
+ {
+ ri.r_extern = 0;
+ ri.r_index = S_GET_TYPE (symbolP);
+ }
+
+ /* Output the relocation information in machine-dependent form. */
+ md_ri_to_chars (where, &ri);
+}
+
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+#if defined (OBJ_COFF) && defined (BFD)
+short
+tc_coff_fix2rtype (fixP)
+ fixS *fixP;
+{
+ if (fixP->fx_bsr)
+ abort ();
+
+ if (fixP->fx_pcrel == 0 && fixP->fx_size == 4)
+ return R_RELLONG;
+
+ if (fixP->fx_pcrel != 0 && fixP->fx_size == 4)
+ return R_IPRMED;
+
+ abort ();
+ return 0;
+}
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ if (frag->fr_next)
+ return frag->fr_next->fr_address - frag->fr_address;
+ else
+ return 0;
+}
+#endif
+
+/* Align an address by rounding it up to the specified boundary. */
+valueT
+md_section_align (seg, addr)
+ segT seg;
+ valueT addr; /* Address to be rounded up */
+{
+ return ((addr + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
+} /* md_section_align() */
+
+extern int coff_flags;
+
+#ifdef OBJ_COFF
+void
+tc_headers_hook (headers)
+ object_headers *headers;
+{
+ switch (architecture)
+ {
+ case ARCH_KA:
+ coff_flags |= F_I960KA;
+ break;
+
+ case ARCH_KB:
+ coff_flags |= F_I960KB;
+ break;
+
+ case ARCH_MC:
+ coff_flags |= F_I960MC;
+ break;
+
+ case ARCH_CA:
+ coff_flags |= F_I960CA;
+ break;
+
+ case ARCH_JX:
+ coff_flags |= F_I960JX;
+ break;
+
+ case ARCH_HX:
+ coff_flags |= F_I960HX;
+ break;
+
+ default:
+ if (iclasses_seen == I_BASE)
+ coff_flags |= F_I960CORE;
+ else if (iclasses_seen & I_CX)
+ coff_flags |= F_I960CA;
+ else if (iclasses_seen & I_HX)
+ coff_flags |= F_I960HX;
+ else if (iclasses_seen & I_JX)
+ coff_flags |= F_I960JX;
+ else if (iclasses_seen & I_CX2)
+ coff_flags |= F_I960CA;
+ else if (iclasses_seen & I_MIL)
+ coff_flags |= F_I960MC;
+ else if (iclasses_seen & (I_DEC | I_FP))
+ coff_flags |= F_I960KB;
+ else
+ coff_flags |= F_I960KA;
+ break;
+ }
+
+ if (flag_readonly_data_in_text)
+ {
+ headers->filehdr.f_magic = I960RWMAGIC;
+ headers->aouthdr.magic = OMAGIC;
+ }
+ else
+ {
+ headers->filehdr.f_magic = I960ROMAGIC;
+ headers->aouthdr.magic = NMAGIC;
+ } /* set magic numbers */
+}
+
+#endif /* OBJ_COFF */
+
+/* Things going on here:
+
+ For bout, We need to assure a couple of simplifying
+ assumptions about leafprocs for the linker: the leafproc
+ entry symbols will be defined in the same assembly in
+ which they're declared with the '.leafproc' directive;
+ and if a leafproc has both 'call' and 'bal' entry points
+ they are both global or both local.
+
+ For coff, the call symbol has a second aux entry that
+ contains the bal entry point. The bal symbol becomes a
+ label.
+
+ For coff representation, the call symbol has a second aux entry that
+ contains the bal entry point. The bal symbol becomes a label. */
+
+void
+tc_crawl_symbol_chain (headers)
+ object_headers *headers;
+{
+ symbolS *symbolP;
+
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
+ {
+#ifdef OBJ_COFF
+ if (TC_S_IS_SYSPROC (symbolP))
+ {
+ /* second aux entry already contains the sysproc number */
+ S_SET_NUMBER_AUXILIARY (symbolP, 2);
+ S_SET_STORAGE_CLASS (symbolP, C_SCALL);
+ S_SET_DATA_TYPE (symbolP, S_GET_DATA_TYPE (symbolP) | (DT_FCN << N_BTSHFT));
+ continue;
+ } /* rewrite sysproc */
+#endif /* OBJ_COFF */
+
+ if (!TC_S_IS_BALNAME (symbolP) && !TC_S_IS_CALLNAME (symbolP))
+ {
+ continue;
+ } /* Not a leafproc symbol */
+
+ if (!S_IS_DEFINED (symbolP))
+ {
+ as_bad (_("leafproc symbol '%s' undefined"), S_GET_NAME (symbolP));
+ } /* undefined leaf */
+
+ if (TC_S_IS_CALLNAME (symbolP))
+ {
+ symbolS *balP = tc_get_bal_of_call (symbolP);
+ if (S_IS_EXTERNAL (symbolP) != S_IS_EXTERNAL (balP))
+ {
+ S_SET_EXTERNAL (symbolP);
+ S_SET_EXTERNAL (balP);
+ as_warn (_("Warning: making leafproc entries %s and %s both global\n"),
+ S_GET_NAME (symbolP), S_GET_NAME (balP));
+ } /* externality mismatch */
+ } /* if callname */
+ } /* walk the symbol chain */
+}
+
+/* For aout or bout, the bal immediately follows the call.
+
+ For coff, we cheat and store a pointer to the bal symbol in the
+ second aux entry of the call. */
+
+#undef OBJ_ABOUT
+#ifdef OBJ_AOUT
+#define OBJ_ABOUT
+#endif
+#ifdef OBJ_BOUT
+#define OBJ_ABOUT
+#endif
+
+void
+tc_set_bal_of_call (callP, balP)
+ symbolS *callP;
+ symbolS *balP;
+{
+ know (TC_S_IS_CALLNAME (callP));
+ know (TC_S_IS_BALNAME (balP));
+
+#ifdef OBJ_COFF
+
+ callP->sy_tc = balP;
+ S_SET_NUMBER_AUXILIARY (callP, 2);
+
+#else /* ! OBJ_COFF */
+#ifdef OBJ_ABOUT
+
+ /* If the 'bal' entry doesn't immediately follow the 'call'
+ * symbol, unlink it from the symbol list and re-insert it.
+ */
+ if (symbol_next (callP) != balP)
+ {
+ symbol_remove (balP, &symbol_rootP, &symbol_lastP);
+ symbol_append (balP, callP, &symbol_rootP, &symbol_lastP);
+ } /* if not in order */
+
+#else /* ! OBJ_ABOUT */
+ (as yet unwritten.);
+#endif /* ! OBJ_ABOUT */
+#endif /* ! OBJ_COFF */
+}
+
+symbolS *
+tc_get_bal_of_call (callP)
+ symbolS *callP;
+{
+ symbolS *retval;
+
+ know (TC_S_IS_CALLNAME (callP));
+
+#ifdef OBJ_COFF
+ retval = callP->sy_tc;
+#else
+#ifdef OBJ_ABOUT
+ retval = symbol_next (callP);
+#else
+ (as yet unwritten.);
+#endif /* ! OBJ_ABOUT */
+#endif /* ! OBJ_COFF */
+
+ know (TC_S_IS_BALNAME (retval));
+ return retval;
+} /* _tc_get_bal_of_call() */
+
+void
+tc_coff_symbol_emit_hook (symbolP)
+ symbolS *symbolP;
+{
+ if (TC_S_IS_CALLNAME (symbolP))
+ {
+#ifdef OBJ_COFF
+ symbolS *balP = tc_get_bal_of_call (symbolP);
+
+#if 0
+ /* second aux entry contains the bal entry point */
+ S_SET_NUMBER_AUXILIARY (symbolP, 2);
+#endif
+ symbolP->sy_symbol.ost_auxent[1].x_bal.x_balntry = S_GET_VALUE (balP);
+ if (S_GET_STORAGE_CLASS (symbolP) == C_EXT)
+ S_SET_STORAGE_CLASS (symbolP, C_LEAFEXT);
+ else
+ S_SET_STORAGE_CLASS (symbolP, C_LEAFSTAT);
+ S_SET_DATA_TYPE (symbolP, S_GET_DATA_TYPE (symbolP) | (DT_FCN << N_BTSHFT));
+ /* fix up the bal symbol */
+ S_SET_STORAGE_CLASS (balP, C_LABEL);
+#endif /* OBJ_COFF */
+ } /* only on calls */
+}
+
+void
+i960_handle_align (fragp)
+ fragS *fragp;
+{
+ if (!linkrelax)
+ return;
+
+#ifndef OBJ_BOUT
+
+ as_bad (_("option --link-relax is only supported in b.out format"));
+ linkrelax = 0;
+ return;
+
+#else
+
+ /* The text section "ends" with another alignment reloc, to which we
+ aren't adding padding. */
+ if (fragp->fr_next == text_last_frag
+ || fragp->fr_next == data_last_frag)
+ return;
+
+ /* alignment directive */
+ fix_new (fragp, fragp->fr_fix, fragp->fr_offset, 0, 0, 0,
+ (int) fragp->fr_type);
+#endif /* OBJ_BOUT */
+}
+
+int
+i960_validate_fix (fixP, this_segment_type, add_symbolPP)
+ fixS *fixP;
+ segT this_segment_type;
+ symbolS **add_symbolPP;
+{
+#define add_symbolP (*add_symbolPP)
+ if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP))
+ {
+ /* Relocation should be done via the associated 'bal'
+ entry point symbol. */
+
+ if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
+ {
+ as_bad (_("No 'bal' entry point for leafproc %s"),
+ S_GET_NAME (add_symbolP));
+ return 1;
+ }
+ fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
+ }
+#if 0
+ /* Still have to work out other conditions for these tests. */
+ {
+ if (fixP->fx_tcbit)
+ {
+ as_bad (_("callj to difference of two symbols"));
+ return 1;
+ }
+ reloc_callj (fixP);
+ if ((int) fixP->fx_bit_fixP == 13)
+ {
+ /* This is a COBR instruction. They have only a 13-bit
+ displacement and are only to be used for local branches:
+ flag as error, don't generate relocation. */
+ as_bad (_("can't use COBR format with external label"));
+ fixP->fx_addsy = NULL; /* No relocations please. */
+ return 1;
+ }
+ }
+#endif
+#undef add_symbolP
+ return 0;
+}
+
+/* end of tc-i960.c */
diff --git a/gas/config/tc-i960.h b/gas/config/tc-i960.h
new file mode 100644
index 00000000000..f60696751f0
--- /dev/null
+++ b/gas/config/tc-i960.h
@@ -0,0 +1,171 @@
+/* tc-i960.h - Basic 80960 instruction formats.
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef TC_I960
+#define TC_I960 1
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define WORKING_DOT_WORD
+
+/*
+ * The 'COJ' instructions are actually COBR instructions with the 'b' in
+ * the mnemonic replaced by a 'j'; they are ALWAYS "de-optimized" if necessary:
+ * if the displacement will not fit in 13 bits, the assembler will replace them
+ * with the corresponding compare and branch instructions.
+ *
+ * All of the 'MEMn' instructions are the same format; the 'n' in the name
+ * indicates the default index scale factor (the size of the datum operated on).
+ *
+ * The FBRA formats are not actually an instruction format. They are the
+ * "convenience directives" for branching on floating-point comparisons,
+ * each of which generates 2 instructions (a 'bno' and one other branch).
+ *
+ * The CALLJ format is not actually an instruction format. It indicates that
+ * the instruction generated (a CTRL-format 'call') should have its relocation
+ * specially flagged for link-time replacement with a 'bal' or 'calls' if
+ * appropriate.
+ */
+
+/* tailor gas */
+#define SYMBOLS_NEED_BACKPOINTERS
+#define LOCAL_LABELS_FB 1
+#define BITFIELD_CONS_EXPRESSIONS
+
+/* tailor the coff format */
+#define BFD_ARCH bfd_arch_i960
+#define COFF_FLAGS F_AR32WR
+#define COFF_MAGIC I960ROMAGIC
+#define OBJ_COFF_SECTION_HEADER_HAS_ALIGNMENT
+#define OBJ_COFF_MAX_AUXENTRIES (2)
+#define TC_COUNT_RELOC(FIXP) (!(FIXP)->fx_done)
+#define TC_COFF_FIX2RTYPE(FIXP) tc_coff_fix2rtype(FIXP)
+#define TC_COFF_SIZEMACHDEP(FRAGP) tc_coff_sizemachdep(FRAGP)
+#define TC_COFF_SET_MACHINE(HDRS) tc_headers_hook (HDRS)
+extern void tc_headers_hook ();
+extern short tc_coff_fix2rtype ();
+extern int tc_coff_sizemachdep ();
+
+/* MEANING OF 'n_other' in the symbol record.
+ *
+ * If non-zero, the 'n_other' fields indicates either a leaf procedure or
+ * a system procedure, as follows:
+ *
+ * 1 <= n_other <= 32 :
+ * The symbol is the entry point to a system procedure.
+ * 'n_value' is the address of the entry, as for any other
+ * procedure. The system procedure number (which can be used in
+ * a 'calls' instruction) is (n_other-1). These entries come from
+ * '.sysproc' directives.
+ *
+ * n_other == N_CALLNAME
+ * the symbol is the 'call' entry point to a leaf procedure.
+ * The *next* symbol in the symbol table must be the corresponding
+ * 'bal' entry point to the procedure (see following). These
+ * entries come from '.leafproc' directives in which two different
+ * symbols are specified (the first one is represented here).
+ *
+ *
+ * n_other == N_BALNAME
+ * the symbol is the 'bal' entry point to a leaf procedure.
+ * These entries result from '.leafproc' directives in which only
+ * one symbol is specified, or in which the same symbol is
+ * specified twice.
+ *
+ * Note that an N_CALLNAME entry *must* have a corresponding N_BALNAME entry,
+ * but not every N_BALNAME entry must have an N_CALLNAME entry.
+ */
+#define N_CALLNAME ((char)-1)
+#define N_BALNAME ((char)-2)
+
+/* i960 uses a custom relocation record. */
+
+/* let obj-aout.h know */
+#define CUSTOM_RELOC_FORMAT 1
+/* let aout_gnu.h know */
+#define N_RELOCATION_INFO_DECLARED 1
+struct relocation_info
+ {
+ int r_address; /* File address of item to be relocated */
+ unsigned
+ r_index:24, /* Index of symbol on which relocation is based*/
+ r_pcrel:1, /* 1 => relocate PC-relative; else absolute
+ * On i960, pc-relative implies 24-bit
+ * address, absolute implies 32-bit.
+ */
+ r_length:2, /* Number of bytes to relocate:
+ * 0 => 1 byte
+ * 1 => 2 bytes
+ * 2 => 4 bytes -- only value used for i960
+ */
+ r_extern:1, r_bsr:1, /* Something for the GNU NS32K assembler */
+ r_disp:1, /* Something for the GNU NS32K assembler */
+ r_callj:1, /* 1 if relocation target is an i960 'callj' */
+ nuthin:1; /* Unused */
+ };
+
+#ifdef OBJ_COFF
+
+/* We store the bal information in the sy_tc field. */
+#define TC_SYMFIELD_TYPE struct symbol *
+
+#define TC_ADJUST_RELOC_COUNT(FIXP,COUNT) \
+ { fixS *tcfixp = (FIXP); \
+ for (;tcfixp;tcfixp=tcfixp->fx_next) \
+ if (tcfixp->fx_tcbit && tcfixp->fx_addsy != 0) \
+ ++(COUNT); \
+ }
+#endif
+
+extern int i960_validate_fix PARAMS ((struct fix *, segT, struct symbol **));
+#define TC_VALIDATE_FIX(FIXP,SEGTYPE,LABEL) \
+ if (i960_validate_fix (FIXP, SEGTYPE, &add_symbolP) != 0) goto LABEL
+
+#define tc_fix_adjustable(FIXP) ((FIXP)->fx_bsr == 0)
+
+extern void brtab_emit PARAMS ((void));
+#define md_end() brtab_emit ()
+
+extern void reloc_callj ();
+
+extern void tc_set_bal_of_call PARAMS ((struct symbol *, struct symbol *));
+
+extern struct symbol *tc_get_bal_of_call PARAMS ((struct symbol *));
+
+extern void i960_handle_align ();
+#define HANDLE_ALIGN(FRAG) i960_handle_align (FRAG)
+#define NEED_FX_R_TYPE
+#define NO_RELOC -1
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+#define LINKER_RELAXING_SHRINKS_ONLY
+
+#define TC_FIX_TYPE struct { unsigned bsr : 1; }
+#define fx_bsr tc_fix_data.bsr
+#define TC_INIT_FIX_DATA(F) ((F)->tc_fix_data.bsr = 0)
+
+#endif
+
+/* end of tc-i960.h */
diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c
new file mode 100644
index 00000000000..997e62316c9
--- /dev/null
+++ b/gas/config/tc-m32r.c
@@ -0,0 +1,1300 @@
+/* tc-m32r.c -- Assembler for the Mitsubishi M32R.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "symcat.h"
+#include "opcodes/m32r-desc.h"
+#include "opcodes/m32r-opc.h"
+#include "cgen.h"
+
+/* Linked list of symbols that are debugging symbols to be defined as the
+ beginning of the current instruction. */
+typedef struct sym_link
+{
+ struct sym_link *next;
+ symbolS *symbol;
+} sym_linkS;
+
+static sym_linkS *debug_sym_link = (sym_linkS *)0;
+
+/* Structure to hold all of the different components describing
+ an individual instruction. */
+typedef struct
+{
+ const CGEN_INSN * insn;
+ const CGEN_INSN * orig_insn;
+ CGEN_FIELDS fields;
+#if CGEN_INT_INSN_P
+ CGEN_INSN_INT buffer [1];
+#define INSN_VALUE(buf) (*(buf))
+#else
+ unsigned char buffer [CGEN_MAX_INSN_SIZE];
+#define INSN_VALUE(buf) (buf)
+#endif
+ char * addr;
+ fragS * frag;
+ int num_fixups;
+ fixS * fixups [GAS_CGEN_MAX_FIXUPS];
+ int indices [MAX_OPERAND_INSTANCES];
+ sym_linkS *debug_sym_link;
+}
+m32r_insn;
+
+/* prev_insn.insn is non-null if last insn was a 16 bit insn on a 32 bit
+ boundary (i.e. was the first of two 16 bit insns). */
+static m32r_insn prev_insn;
+
+/* Non-zero if we've seen a relaxable insn since the last 32 bit
+ alignment request. */
+static int seen_relaxable_p = 0;
+
+/* Non-zero if -relax specified, in which case sufficient relocs are output
+ for the linker to do relaxing.
+ We do simple forms of relaxing internally, but they are always done.
+ This flag does not apply to them. */
+static int m32r_relax;
+
+#if 0 /* not supported yet */
+/* If non-NULL, pointer to cpu description file to read.
+ This allows runtime additions to the assembler. */
+static const char * m32r_cpu_desc;
+#endif
+
+/* Non-zero if warn when a high/shigh reloc has no matching low reloc.
+ Each high/shigh reloc must be paired with it's low cousin in order to
+ properly calculate the addend in a relocatable link (since there is a
+ potential carry from the low to the high/shigh).
+ This option is off by default though for user-written assembler code it
+ might make sense to make the default be on (i.e. have gcc pass a flag
+ to turn it off). This warning must not be on for GCC created code as
+ optimization may delete the low but not the high/shigh (at least we
+ shouldn't assume or require it to). */
+static int warn_unmatched_high = 0;
+
+
+/* stuff for .scomm symbols. */
+static segT sbss_section;
+static asection scom_section;
+static asymbol scom_symbol;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "#";
+const char line_separator_chars[] = "";
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "dD";
+
+/* Relocations against symbols are done in two
+ parts, with a HI relocation and a LO relocation. Each relocation
+ has only 16 bits of space to store an addend. This means that in
+ order for the linker to handle carries correctly, it must be able
+ to locate both the HI and the LO relocation. This means that the
+ relocations must appear in order in the relocation table.
+
+ In order to implement this, we keep track of each unmatched HI
+ relocation. We then sort them so that they immediately precede the
+ corresponding LO relocation. */
+
+struct m32r_hi_fixup
+{
+ struct m32r_hi_fixup * next; /* Next HI fixup. */
+ fixS * fixp; /* This fixup. */
+ segT seg; /* The section this fixup is in. */
+
+};
+
+/* The list of unmatched HI relocs. */
+
+static struct m32r_hi_fixup * m32r_hi_fixup_list;
+
+
+
+#define M32R_SHORTOPTS ""
+const char * md_shortopts = M32R_SHORTOPTS;
+
+struct option md_longopts[] =
+{
+
+ /* Sigh. I guess all warnings must now have both variants. */
+#define OPTION_WARN_UNMATCHED (OPTION_MD_BASE + 4)
+ {"warn-unmatched-high", OPTION_WARN_UNMATCHED},
+ {"Wuh", OPTION_WARN_UNMATCHED},
+#define OPTION_NO_WARN_UNMATCHED (OPTION_MD_BASE + 5)
+ {"no-warn-unmatched-high", OPTION_WARN_UNMATCHED},
+ {"Wnuh", OPTION_WARN_UNMATCHED},
+
+#if 0 /* not supported yet */
+#define OPTION_RELAX (OPTION_MD_BASE + 6)
+ {"relax", no_argument, NULL, OPTION_RELAX},
+#define OPTION_CPU_DESC (OPTION_MD_BASE + 7)
+ {"cpu-desc", required_argument, NULL, OPTION_CPU_DESC},
+#endif
+
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ switch (c)
+ {
+
+ case OPTION_WARN_UNMATCHED:
+ warn_unmatched_high = 1;
+ break;
+
+ case OPTION_NO_WARN_UNMATCHED:
+ warn_unmatched_high = 0;
+ break;
+
+#if 0 /* not supported yet */
+ case OPTION_RELAX:
+ m32r_relax = 1;
+ break;
+ case OPTION_CPU_DESC:
+ m32r_cpu_desc = arg;
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE * stream;
+{
+ fprintf (stream, _(" M32R specific command line options:\n"));
+
+
+ fprintf (stream, _("\
+ -warn-unmatched-high warn when an (s)high reloc has no matching low reloc\n"));
+ fprintf (stream, _("\
+ -no-warn-unmatched-high do not warn about missing low relocs\n"));
+ fprintf (stream, _("\
+ -Wuh synonym for -warn-unmatched-high\n"));
+ fprintf (stream, _("\
+ -Wnuh synonym for -no-warn-unmatched-high\n"));
+
+#if 0
+ fprintf (stream, _("\
+ -relax create linker relaxable code\n"));
+ fprintf (stream, _("\
+ -cpu-desc provide runtime cpu description file\n"));
+#endif
+}
+
+static void fill_insn PARAMS ((int));
+static void m32r_scomm PARAMS ((int));
+static void debug_sym PARAMS ((int));
+static void expand_debug_syms PARAMS ((sym_linkS *, int));
+
+/* Set by md_assemble for use by m32r_fill_insn. */
+static subsegT prev_subseg;
+static segT prev_seg;
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "word", cons, 4 },
+ { "fillinsn", fill_insn, 0 },
+ { "scomm", m32r_scomm, 0 },
+ { "debugsym", debug_sym, 0 },
+ { NULL, NULL, 0 }
+};
+
+/* FIXME: Should be machine generated. */
+#define NOP_INSN 0x7000
+#define PAR_NOP_INSN 0xf000 /* can only be used in 2nd slot */
+
+/* When we align the .text section, insert the correct NOP pattern.
+ N is the power of 2 alignment. LEN is the length of pattern FILL.
+ MAX is the maximum number of characters to skip when doing the alignment,
+ or 0 if there is no maximum. */
+
+int
+m32r_do_align (n, fill, len, max)
+ int n;
+ const char * fill;
+ int len;
+ int max;
+{
+ /* Only do this if the fill pattern wasn't specified. */
+ if (fill == NULL
+ && (now_seg->flags & SEC_CODE) != 0
+ /* Only do this special handling if aligning to at least a
+ 4 byte boundary. */
+ && n > 1
+ /* Only do this special handling if we're allowed to emit at
+ least two bytes. */
+ && (max == 0 || max > 1))
+ {
+ static const unsigned char nop_pattern[] = { 0xf0, 0x00 };
+
+#if 0
+ /* First align to a 2 byte boundary, in case there is an odd .byte. */
+ /* FIXME: How much memory will cause gas to use when assembling a big
+ program? Perhaps we can avoid the frag_align call? */
+ frag_align (1, 0, 0);
+#endif
+ /* Next align to a 4 byte boundary (we know n >= 2) using a parallel
+ nop. */
+ frag_align_pattern (2, nop_pattern, sizeof nop_pattern, 0);
+ /* If doing larger alignments use a repeating sequence of appropriate
+ nops. */
+ if (n > 2)
+ {
+ static const unsigned char multi_nop_pattern[] =
+ { 0x70, 0x00, 0xf0, 0x00 };
+ frag_align_pattern (n, multi_nop_pattern, sizeof multi_nop_pattern,
+ max ? max - 2 : 0);
+ }
+
+ prev_insn.insn = NULL;
+ return 1;
+ }
+
+ return 0;
+}
+
+/* If the last instruction was the first of 2 16 bit insns,
+ output a nop to move the PC to a 32 bit boundary.
+
+ This is done via an alignment specification since branch relaxing
+ may make it unnecessary.
+
+ Internally, we need to output one of these each time a 32 bit insn is
+ seen after an insn that is relaxable. */
+
+static void
+fill_insn (ignore)
+ int ignore;
+{
+ (void) m32r_do_align (2, NULL, 0, 0);
+ prev_insn.insn = NULL;
+ seen_relaxable_p = 0;
+}
+
+/* Record the symbol so that when we output the insn, we can create
+ a symbol that is at the start of the instruction. This is used
+ to emit the label for the start of a breakpoint without causing
+ the assembler to emit a NOP if the previous instruction was a
+ 16 bit instruction. */
+
+static void
+debug_sym (ignore)
+ int ignore;
+{
+ register char *name;
+ register char delim;
+ register char *end_name;
+ register symbolS *symbolP;
+ register sym_linkS *link;
+
+ name = input_line_pointer;
+ delim = get_symbol_end ();
+ end_name = input_line_pointer;
+
+ if ((symbolP = symbol_find (name)) == NULL
+ && (symbolP = md_undefined_symbol (name)) == NULL)
+ {
+ symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+ }
+
+ symbol_table_insert (symbolP);
+ if (S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section)
+ /* xgettext:c-format */
+ as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+
+ else
+ {
+ link = (sym_linkS *) xmalloc (sizeof (sym_linkS));
+ link->symbol = symbolP;
+ link->next = debug_sym_link;
+ debug_sym_link = link;
+ symbolP->local = 1;
+ }
+
+ *end_name = delim;
+ demand_empty_rest_of_line ();
+}
+
+/* Second pass to expanding the debug symbols, go through linked
+ list of symbols and reassign the address. */
+
+static void
+expand_debug_syms (syms, align)
+ sym_linkS *syms;
+ int align;
+{
+ char *save_input_line = input_line_pointer;
+ sym_linkS *next_syms;
+
+ if (!syms)
+ return;
+
+ (void) m32r_do_align (align, NULL, 0, 0);
+ for (; syms != (sym_linkS *)0; syms = next_syms)
+ {
+ symbolS *symbolP = syms->symbol;
+ next_syms = syms->next;
+ input_line_pointer = ".\n";
+ pseudo_set (symbolP);
+ free ((char *)syms);
+ }
+
+ input_line_pointer = save_input_line;
+}
+
+/* Cover function to fill_insn called after a label and at end of assembly.
+ The result is always 1: we're called in a conditional to see if the
+ current line is a label. */
+
+int
+m32r_fill_insn (done)
+ int done;
+{
+ if (prev_seg != NULL)
+ {
+ segT seg = now_seg;
+ subsegT subseg = now_subseg;
+
+ subseg_set (prev_seg, prev_subseg);
+
+ fill_insn (0);
+
+ subseg_set (seg, subseg);
+ }
+
+ if (done && debug_sym_link)
+ {
+ expand_debug_syms (debug_sym_link, 1);
+ debug_sym_link = (sym_linkS *)0;
+ }
+
+ return 1;
+}
+
+void
+md_begin ()
+{
+ flagword applicable;
+ segT seg;
+ subsegT subseg;
+
+ /* Initialize the `cgen' interface. */
+
+ /* Set the machine number and endian. */
+ gas_cgen_cpu_desc = m32r_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
+ CGEN_CPU_OPEN_ENDIAN,
+ CGEN_ENDIAN_BIG,
+ CGEN_CPU_OPEN_END);
+ m32r_cgen_init_asm (gas_cgen_cpu_desc);
+
+ /* The operand instance table is used during optimization to determine
+ which insns can be executed in parallel. It is also used to give
+ warnings regarding operand interference in parallel insns. */
+ m32r_cgen_init_opinst_table (gas_cgen_cpu_desc);
+
+ /* This is a callback from cgen to gas to parse operands. */
+ cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
+
+#if 0 /* not supported yet */
+ /* If a runtime cpu description file was provided, parse it. */
+ if (m32r_cpu_desc != NULL)
+ {
+ const char * errmsg;
+
+ errmsg = cgen_read_cpu_file (gas_cgen_cpu_desc, m32r_cpu_desc);
+ if (errmsg != NULL)
+ as_bad ("%s: %s", m32r_cpu_desc, errmsg);
+ }
+#endif
+
+ /* Save the current subseg so we can restore it [it's the default one and
+ we don't want the initial section to be .sbss]. */
+ seg = now_seg;
+ subseg = now_subseg;
+
+ /* The sbss section is for local .scomm symbols. */
+ sbss_section = subseg_new (".sbss", 0);
+
+ /* This is copied from perform_an_assembly_pass. */
+ applicable = bfd_applicable_section_flags (stdoutput);
+ bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
+
+#if 0 /* What does this do? [see perform_an_assembly_pass] */
+ seg_info (bss_section)->bss = 1;
+#endif
+
+ subseg_set (seg, subseg);
+
+ /* We must construct a fake section similar to bfd_com_section
+ but with the name .scommon. */
+ scom_section = bfd_com_section;
+ scom_section.name = ".scommon";
+ scom_section.output_section = & scom_section;
+ scom_section.symbol = & scom_symbol;
+ scom_section.symbol_ptr_ptr = & scom_section.symbol;
+ scom_symbol = * bfd_com_section.symbol;
+ scom_symbol.name = ".scommon";
+ scom_symbol.section = & scom_section;
+
+}
+
+
+
+void
+md_assemble (str)
+ char * str;
+{
+ m32r_insn insn;
+ char * errmsg;
+ char * str2 = NULL;
+
+ /* Initialize GAS's cgen interface for a new instruction. */
+ gas_cgen_init_parse ();
+
+
+ insn.debug_sym_link = debug_sym_link;
+ debug_sym_link = (sym_linkS *)0;
+
+ insn.insn = m32r_cgen_assemble_insn
+ (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
+
+ if (!insn.insn)
+ {
+ as_bad (errmsg);
+ return;
+ }
+
+
+ if (CGEN_INSN_BITSIZE (insn.insn) == 32)
+ {
+ /* 32 bit insns must live on 32 bit boundaries. */
+ if (prev_insn.insn || seen_relaxable_p)
+ {
+ /* ??? If calling fill_insn too many times turns us into a memory
+ pig, can we call a fn to assemble a nop instead of
+ !seen_relaxable_p? */
+ fill_insn (0);
+ }
+
+ expand_debug_syms (insn.debug_sym_link, 2);
+
+ /* Doesn't really matter what we pass for RELAX_P here. */
+ gas_cgen_finish_insn (insn.insn, insn.buffer,
+ CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
+ }
+ else
+ {
+ int on_32bit_boundary_p;
+
+ if (CGEN_INSN_BITSIZE (insn.insn) != 16)
+ abort();
+
+ insn.orig_insn = insn.insn;
+
+ /* Compute whether we're on a 32 bit boundary or not.
+ prev_insn.insn is NULL when we're on a 32 bit boundary. */
+ on_32bit_boundary_p = prev_insn.insn == NULL;
+
+
+ expand_debug_syms (insn.debug_sym_link, 1);
+
+ {
+ int i;
+ finished_insnS fi;
+
+ /* Ensure each pair of 16 bit insns is in the same frag. */
+ frag_grow (4);
+
+ gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
+ CGEN_FIELDS_BITSIZE (& insn.fields),
+ 1 /*relax_p*/, &fi);
+ insn.addr = fi.addr;
+ insn.frag = fi.frag;
+ insn.num_fixups = fi.num_fixups;
+ for (i = 0; i < fi.num_fixups; ++i)
+ insn.fixups[i] = fi.fixups[i];
+ }
+
+
+ /* Keep track of whether we've seen a pair of 16 bit insns.
+ prev_insn.insn is NULL when we're on a 32 bit boundary. */
+ if (on_32bit_boundary_p)
+ prev_insn = insn;
+ else
+ prev_insn.insn = NULL;
+
+ /* If the insn needs the following one to be on a 32 bit boundary
+ (e.g. subroutine calls), fill this insn's slot. */
+ if (on_32bit_boundary_p
+ && CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_FILL_SLOT) != 0)
+ fill_insn (0);
+
+ /* If this is a relaxable insn (can be replaced with a larger version)
+ mark the fact so that we can emit an alignment directive for a
+ following 32 bit insn if we see one. */
+ if (CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_RELAXABLE) != 0)
+ seen_relaxable_p = 1;
+ }
+
+ /* Set these so m32r_fill_insn can use them. */
+ prev_seg = now_seg;
+ prev_subseg = now_subseg;
+}
+
+/* The syntax in the manual says constants begin with '#'.
+ We just ignore it. */
+
+void
+md_operand (expressionP)
+ expressionS * expressionP;
+{
+ if (* input_line_pointer == '#')
+ {
+ input_line_pointer ++;
+ expression (expressionP);
+ }
+}
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ int align = bfd_get_section_alignment (stdoutput, segment);
+ return ((size + (1 << align) - 1) & (-1 << align));
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char * name;
+{
+ return 0;
+}
+
+/* .scomm pseudo-op handler.
+
+ This is a new pseudo-op to handle putting objects in .scommon.
+ By doing this the linker won't need to do any work and more importantly
+ it removes the implicit -G arg necessary to correctly link the object file.
+*/
+
+static void
+m32r_scomm (ignore)
+ int ignore;
+{
+ register char * name;
+ register char c;
+ register char * p;
+ offsetT size;
+ register symbolS * symbolP;
+ offsetT align;
+ int align2;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ * p = c;
+ SKIP_WHITESPACE ();
+ if (* input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer ++; /* skip ',' */
+ if ((size = get_absolute_expression ()) < 0)
+ {
+ /* xgettext:c-format */
+ as_warn (_(".SCOMMon length (%ld.) <0! Ignored."), (long) size);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* The third argument to .scomm is the alignment. */
+ if (* input_line_pointer != ',')
+ align = 8;
+ else
+ {
+ ++ input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 8;
+ }
+ }
+ /* Convert to a power of 2 alignment. */
+ if (align)
+ {
+ for (align2 = 0; (align & 1) == 0; align >>= 1, ++ align2)
+ continue;
+ if (align != 1)
+ {
+ as_bad (_("Common alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align2 = 0;
+
+ * p = 0;
+ symbolP = symbol_find_or_make (name);
+ * p = c;
+
+ if (S_IS_DEFINED (symbolP))
+ {
+ /* xgettext:c-format */
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
+ {
+ /* xgettext:c-format */
+ as_bad (_("Length of .scomm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) size);
+
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (symbolP->local)
+ {
+ segT old_sec = now_seg;
+ int old_subsec = now_subseg;
+ char * pfrag;
+
+ record_alignment (sbss_section, align2);
+ subseg_set (sbss_section, 0);
+
+ if (align2)
+ frag_align (align2, 0, 0);
+
+ if (S_GET_SEGMENT (symbolP) == sbss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+
+ symbolP->sy_frag = frag_now;
+
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
+ (char *) 0);
+ * pfrag = 0;
+ S_SET_SIZE (symbolP, size);
+ S_SET_SEGMENT (symbolP, sbss_section);
+ S_CLEAR_EXTERNAL (symbolP);
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+ {
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_ALIGN (symbolP, align2);
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, & scom_section);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Interface to relax_segment. */
+
+/* FIXME: Build table by hand, get it working, then machine generate. */
+
+const relax_typeS md_relax_table[] =
+{
+/* The fields are:
+ 1) most positive reach of this state,
+ 2) most negative reach of this state,
+ 3) how many bytes this mode will add to the size of the current frag
+ 4) which index into the table to try if we can't fit into this one. */
+
+ /* The first entry must be unused because an `rlx_more' value of zero ends
+ each list. */
+ {1, 1, 0, 0},
+
+ /* The displacement used by GAS is from the end of the 2 byte insn,
+ so we subtract 2 from the following. */
+ /* 16 bit insn, 8 bit disp -> 10 bit range.
+ This doesn't handle a branch in the right slot at the border:
+ the "& -4" isn't taken into account. It's not important enough to
+ complicate things over it, so we subtract an extra 2 (or + 2 in -ve
+ case). */
+ {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
+ /* 32 bit insn, 24 bit disp -> 26 bit range. */
+ {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
+ /* Same thing, but with leading nop for alignment. */
+ {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
+};
+
+long
+m32r_relax_frag (fragP, stretch)
+ fragS * fragP;
+ long stretch;
+{
+ /* Address of branch insn. */
+ long address = fragP->fr_address + fragP->fr_fix - 2;
+ long growth = 0;
+
+ /* Keep 32 bit insns aligned on 32 bit boundaries. */
+ if (fragP->fr_subtype == 2)
+ {
+ if ((address & 3) != 0)
+ {
+ fragP->fr_subtype = 3;
+ growth = 2;
+ }
+ }
+ else if (fragP->fr_subtype == 3)
+ {
+ if ((address & 3) == 0)
+ {
+ fragP->fr_subtype = 2;
+ growth = -2;
+ }
+ }
+ else
+ {
+ growth = relax_frag (fragP, stretch);
+
+ /* Long jump on odd halfword boundary? */
+ if (fragP->fr_subtype == 2 && (address & 3) != 0)
+ {
+ fragP->fr_subtype = 3;
+ growth += 2;
+ }
+ }
+
+ return growth;
+}
+
+/* Return an initial guess of the length by which a fragment must grow to
+ hold a branch to reach its destination.
+ Also updates fr_type/fr_subtype as necessary.
+
+ Called just before doing relaxation.
+ Any symbol that is now undefined will not become defined.
+ The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ Although it may not be explicit in the frag, pretend fr_var starts with a
+ 0 value. */
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS * fragP;
+ segT segment;
+{
+ int old_fr_fix = fragP->fr_fix;
+
+ /* The only thing we have to handle here are symbols outside of the
+ current segment. They may be undefined or in a different segment in
+ which case linker scripts may place them anywhere.
+ However, we can't finish the fragment here and emit the reloc as insn
+ alignment requirements may move the insn about. */
+
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
+ {
+ /* The symbol is undefined in this segment.
+ Change the relaxation subtype to the max allowable and leave
+ all further handling to md_convert_frag. */
+ fragP->fr_subtype = 2;
+
+#if 0 /* Can't use this, but leave in for illustration. */
+ /* Change 16 bit insn to 32 bit insn. */
+ fragP->fr_opcode[0] |= 0x80;
+
+ /* Increase known (fixed) size of fragment. */
+ fragP->fr_fix += 2;
+
+ /* Create a relocation for it. */
+ fix_new (fragP, old_fr_fix, 4,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1 /* pcrel */,
+ /* FIXME: Can't use a real BFD reloc here.
+ gas_cgen_md_apply_fix3 can't handle it. */
+ BFD_RELOC_M32R_26_PCREL);
+
+ /* Mark this fragment as finished. */
+ frag_wane (fragP);
+#else
+ {
+ const CGEN_INSN * insn;
+ int i;
+
+ /* Update the recorded insn.
+ Fortunately we don't have to look very far.
+ FIXME: Change this to record in the instruction the next higher
+ relaxable insn to use. */
+ for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
+ {
+ if ((strcmp (CGEN_INSN_MNEMONIC (insn),
+ CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
+ == 0)
+ && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX))
+ break;
+ }
+ if (i == 4)
+ abort ();
+
+ fragP->fr_cgen.insn = insn;
+ return 2;
+ }
+#endif
+ }
+
+ return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
+}
+
+/* *fragP has been relaxed to its final size, and now needs to have
+ the bytes inside it modified to conform to the new size.
+
+ Called after relaxation is finished.
+ fragP->fr_type == rs_machine_dependent.
+ fragP->fr_subtype is the subtype of what the address relaxed to. */
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd * abfd;
+ segT sec;
+ fragS * fragP;
+{
+ char * opcode;
+ char * displacement;
+ int target_address;
+ int opcode_address;
+ int extension;
+ int addend;
+
+ opcode = fragP->fr_opcode;
+
+ /* Address opcode resides at in file space. */
+ opcode_address = fragP->fr_address + fragP->fr_fix - 2;
+
+ switch (fragP->fr_subtype)
+ {
+ case 1 :
+ extension = 0;
+ displacement = & opcode[1];
+ break;
+ case 2 :
+ opcode[0] |= 0x80;
+ extension = 2;
+ displacement = & opcode[1];
+ break;
+ case 3 :
+ opcode[2] = opcode[0] | 0x80;
+ md_number_to_chars (opcode, PAR_NOP_INSN, 2);
+ opcode_address += 2;
+ extension = 4;
+ displacement = & opcode[3];
+ break;
+ default :
+ abort ();
+ }
+
+ if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
+ {
+ /* symbol must be resolved by linker */
+ if (fragP->fr_offset & 3)
+ as_warn (_("Addend to unresolved symbol not on word boundary."));
+ addend = fragP->fr_offset >> 2;
+ }
+ else
+ {
+ /* Address we want to reach in file space. */
+ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
+ target_address += fragP->fr_symbol->sy_frag->fr_address;
+ addend = (target_address - (opcode_address & -4)) >> 2;
+ }
+
+ /* Create a relocation for symbols that must be resolved by the linker.
+ Otherwise output the completed insn. */
+
+ if (S_GET_SEGMENT (fragP->fr_symbol) != sec)
+ {
+ assert (fragP->fr_subtype != 1);
+ assert (fragP->fr_cgen.insn != 0);
+ gas_cgen_record_fixup (fragP,
+ /* Offset of branch insn in frag. */
+ fragP->fr_fix + extension - 4,
+ fragP->fr_cgen.insn,
+ 4 /*length*/,
+ /* FIXME: quick hack */
+#if 0
+ cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
+ fragP->fr_cgen.opindex),
+#else
+ cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
+ M32R_OPERAND_DISP24),
+#endif
+ fragP->fr_cgen.opinfo,
+ fragP->fr_symbol, fragP->fr_offset);
+ }
+
+#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)
+
+ md_number_to_chars (displacement, (valueT) addend,
+ SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
+
+ fragP->fr_fix += extension;
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixP, sec)
+ fixS * fixP;
+ segT sec;
+{
+ if (fixP->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixP->fx_addsy)
+ || S_GET_SEGMENT (fixP->fx_addsy) != sec))
+ {
+ /* The symbol is undefined (or is defined but not in this section).
+ Let the linker figure it out. */
+ return 0;
+ }
+
+ return (fixP->fx_frag->fr_address + fixP->fx_where) & -4L;
+}
+
+/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
+ Returns BFD_RELOC_NONE if no reloc type can be found.
+ *FIXP may be modified if desired. */
+
+bfd_reloc_code_real_type
+md_cgen_lookup_reloc (insn, operand, fixP)
+ const CGEN_INSN * insn;
+ const CGEN_OPERAND * operand;
+ fixS * fixP;
+{
+ switch (operand->type)
+ {
+ case M32R_OPERAND_DISP8 : return BFD_RELOC_M32R_10_PCREL;
+ case M32R_OPERAND_DISP16 : return BFD_RELOC_M32R_18_PCREL;
+ case M32R_OPERAND_DISP24 : return BFD_RELOC_M32R_26_PCREL;
+ case M32R_OPERAND_UIMM24 : return BFD_RELOC_M32R_24;
+ case M32R_OPERAND_HI16 :
+ case M32R_OPERAND_SLO16 :
+ case M32R_OPERAND_ULO16 :
+ /* If low/high/shigh/sda was used, it is recorded in `opinfo'. */
+ if (fixP->fx_cgen.opinfo != 0)
+ return fixP->fx_cgen.opinfo;
+ break;
+ default : /* avoid -Wall warning */
+ break;
+ }
+ return BFD_RELOC_NONE;
+}
+
+/* Record a HI16 reloc for later matching with its LO16 cousin. */
+
+static void
+m32r_record_hi16 (reloc_type, fixP, seg)
+ int reloc_type;
+ fixS * fixP;
+ segT seg;
+{
+ struct m32r_hi_fixup * hi_fixup;
+
+ assert (reloc_type == BFD_RELOC_M32R_HI16_SLO
+ || reloc_type == BFD_RELOC_M32R_HI16_ULO);
+
+ hi_fixup = ((struct m32r_hi_fixup *)
+ xmalloc (sizeof (struct m32r_hi_fixup)));
+ hi_fixup->fixp = fixP;
+ hi_fixup->seg = now_seg;
+ hi_fixup->next = m32r_hi_fixup_list;
+
+ m32r_hi_fixup_list = hi_fixup;
+}
+
+/* Called while parsing an instruction to create a fixup.
+ We need to check for HI16 relocs and queue them up for later sorting. */
+
+fixS *
+m32r_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
+ fragS * frag;
+ int where;
+ const CGEN_INSN * insn;
+ int length;
+ const CGEN_OPERAND * operand;
+ int opinfo;
+ expressionS * exp;
+{
+ fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
+ operand, opinfo, exp);
+
+ switch (operand->type)
+ {
+ case M32R_OPERAND_HI16 :
+ /* If low/high/shigh/sda was used, it is recorded in `opinfo'. */
+ if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO
+ || fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
+ m32r_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);
+ break;
+ default : /* avoid -Wall warning */
+ break;
+ }
+
+ return fixP;
+}
+
+/* Return BFD reloc type from opinfo field in a fixS.
+ It's tricky using fx_r_type in m32r_frob_file because the values
+ are BFD_RELOC_UNUSED + operand number. */
+#define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
+
+/* Sort any unmatched HI16 relocs so that they immediately precede
+ the corresponding LO16 reloc. This is called before md_apply_fix and
+ tc_gen_reloc. */
+
+void
+m32r_frob_file ()
+{
+ struct m32r_hi_fixup * l;
+
+ for (l = m32r_hi_fixup_list; l != NULL; l = l->next)
+ {
+ segment_info_type * seginfo;
+ int pass;
+
+ assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_SLO
+ || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_ULO);
+
+ /* Check quickly whether the next fixup happens to be a matching low. */
+ if (l->fixp->fx_next != NULL
+ && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_M32R_LO16
+ && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
+ && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
+ continue;
+
+ /* Look through the fixups for this segment for a matching `low'.
+ When we find one, move the high/shigh just in front of it. We do
+ this in two passes. In the first pass, we try to find a
+ unique `low'. In the second pass, we permit multiple high's
+ relocs for a single `low'. */
+ seginfo = seg_info (l->seg);
+ for (pass = 0; pass < 2; pass++)
+ {
+ fixS * f;
+ fixS * prev;
+
+ prev = NULL;
+ for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
+ {
+ /* Check whether this is a `low' fixup which matches l->fixp. */
+ if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_M32R_LO16
+ && f->fx_addsy == l->fixp->fx_addsy
+ && f->fx_offset == l->fixp->fx_offset
+ && (pass == 1
+ || prev == NULL
+ || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_SLO
+ && FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_ULO)
+ || prev->fx_addsy != f->fx_addsy
+ || prev->fx_offset != f->fx_offset))
+ {
+ fixS ** pf;
+
+ /* Move l->fixp before f. */
+ for (pf = &seginfo->fix_root;
+ * pf != l->fixp;
+ pf = & (* pf)->fx_next)
+ assert (* pf != NULL);
+
+ * pf = l->fixp->fx_next;
+
+ l->fixp->fx_next = f;
+ if (prev == NULL)
+ seginfo->fix_root = l->fixp;
+ else
+ prev->fx_next = l->fixp;
+
+ break;
+ }
+
+ prev = f;
+ }
+
+ if (f != NULL)
+ break;
+
+ if (pass == 1
+ && warn_unmatched_high)
+ as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
+ _("Unmatched high/shigh reloc"));
+ }
+ }
+}
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+m32r_force_relocation (fix)
+ fixS * fix;
+{
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ if (! m32r_relax)
+ return 0;
+
+ return (fix->fx_pcrel
+ || 0 /* ??? */);
+}
+
+/* Write a value out to the object file, using the appropriate endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char * buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+*/
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int i;
+ int prec;
+ LITTLENUM_TYPE words [MAX_LITTLENUMS];
+ char * t;
+ char * atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ /* FIXME: Some targets allow other format chars for bigger sizes here. */
+
+ default:
+ * sizeP = 0;
+ return _("Bad call to md_atof()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ * sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i],
+ sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+
+ return 0;
+}
+
+void
+m32r_elf_section_change_hook ()
+{
+ /* If we have reached the end of a section and we have just emitted a
+ 16 bit insn, then emit a nop to make sure that the section ends on
+ a 32 bit boundary. */
+
+ if (prev_insn.insn || seen_relaxable_p)
+ (void) m32r_fill_insn (0);
+}
+
+boolean
+m32r_fix_adjustable (fixP)
+ fixS *fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
diff --git a/gas/config/tc-m32r.h b/gas/config/tc-m32r.h
new file mode 100644
index 00000000000..ebcfca1c3f6
--- /dev/null
+++ b/gas/config/tc-m32r.h
@@ -0,0 +1,102 @@
+/* tc-m32r.h -- Header file for tc-m32r.c.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_M32R
+
+#ifndef BFD_ASSEMBLER
+/* leading space so will compile with cc */
+ #error M32R support requires BFD_ASSEMBLER
+#endif
+
+#define LISTING_HEADER "M32R GAS "
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_m32r
+
+#define TARGET_FORMAT "elf32-m32r"
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+long md_pcrel_from_section PARAMS ((struct fix *, segT));
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+/* For 8 vs 16 vs 32 bit branch selection. */
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+#if 0
+extern void m32r_prepare_relax_scan ();
+#define md_prepare_relax_scan(fragP, address, aim, this_state, this_type) \
+m32r_prepare_relax_scan (fragP, address, aim, this_state, this_type)
+#else
+extern long m32r_relax_frag PARAMS ((fragS *, long));
+#define md_relax_frag(fragP, stretch) \
+m32r_relax_frag (fragP, stretch)
+#endif
+/* Account for nop if 32 bit insn falls on odd halfword boundary. */
+#define TC_CGEN_MAX_RELAX(insn, len) (6)
+
+/* Alignments are used to ensure 32 bit insns live on 32 bit boundaries, so
+ we use a special alignment function to insert the correct nop pattern. */
+extern int m32r_do_align PARAMS ((int, const char *, int, int));
+#define md_do_align(n, fill, len, max, l) \
+if (m32r_do_align (n, fill, len, max)) goto l
+
+#define MD_APPLY_FIX3
+#define md_apply_fix3 gas_cgen_md_apply_fix3
+
+#define obj_fix_adjustable(fixP) m32r_fix_adjustable(fixP)
+
+/* After creating a fixup for an instruction operand, we need to check for
+ HI16 relocs and queue them up for later sorting. */
+#define md_cgen_record_fixup_exp m32r_cgen_record_fixup_exp
+
+#define TC_HANDLES_FX_DONE
+
+#define tc_gen_reloc gas_cgen_tc_gen_reloc
+
+#define tc_frob_file() m32r_frob_file ()
+extern void m32r_frob_file PARAMS ((void));
+
+/* When relaxing, we need to emit various relocs we otherwise wouldn't. */
+#define TC_FORCE_RELOCATION(fix) m32r_force_relocation (fix)
+extern int m32r_force_relocation ();
+
+/* Ensure insns at labels are aligned to 32 bit boundaries. */
+int m32r_fill_insn PARAMS ((int));
+#define md_after_pass_hook() m32r_fill_insn (1)
+#define TC_START_LABEL(ch, ptr) (ch == ':' && m32r_fill_insn (0))
+
+/* Add extra M32R sections. */
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+
+#define md_cleanup m32r_elf_section_change_hook
+#define md_elf_section_change_hook m32r_elf_section_change_hook
+extern void m32r_elf_section_change_hook ();
diff --git a/gas/config/tc-m68851.h b/gas/config/tc-m68851.h
new file mode 100644
index 00000000000..0f6d7413375
--- /dev/null
+++ b/gas/config/tc-m68851.h
@@ -0,0 +1,304 @@
+/* This file is tc-m68851.h
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * pmmu.h
+ */
+
+/* I suppose we have to copyright this file. Someone on the net sent it
+ to us as part of the changes for the m68851 Memory Management Unit */
+
+/* Copyright (C) 1987 Free Software Foundation, Inc.
+
+ This file is part of Gas, the GNU Assembler.
+
+ The GNU assembler is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY. No author or distributor
+ accepts responsibility to anyone for the consequences of using it
+ or for whether it serves any particular purpose or works at all,
+ unless he says so in writing. Refer to the GNU Assembler General
+ Public License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute
+ the GNU Assembler, but only under the conditions described in the
+ GNU Assembler General Public License. A copy of this license is
+ supposed to have been given to you along with the GNU Assembler
+ so you can know your rights and responsibilities. It should be
+ in a file named COPYING. Among other things, the copyright
+ notice and this notice must be preserved on all copies. */
+
+#ifdef m68851
+
+/*
+ I didn't use much imagination in choosing the
+ following codes, so many of them aren't very
+ mnemonic. -rab
+
+ P pmmu register
+ Possible values:
+ 000 TC Translation Control reg
+ 100 CAL Current Access Level
+ 101 VAL Validate Access Level
+ 110 SCC Stack Change Control
+ 111 AC Access Control
+
+ W wide pmmu registers
+ Possible values:
+ 001 DRP Dma Root Pointer
+ 010 SRP Supervisor Root Pointer
+ 011 CRP Cpu Root Pointer
+
+ f function code register
+ 0 SFC
+ 1 DFC
+
+ V VAL register only
+
+ X BADx, BACx
+ 100 BAD Breakpoint Acknowledge Data
+ 101 BAC Breakpoint Acknowledge Control
+
+ Y PSR
+ Z PCSR
+
+ | memory (modes 2-6, 7.*)
+
+ */
+
+/*
+ * these defines should be in m68k.c but
+ * i put them here to keep all the m68851 stuff
+ * together -rab
+ * JF--Make sure these #s don't clash with the ones in m68k.c
+ * That would be BAD.
+ */
+#define TC (FPS+1) /* 48 */
+#define DRP (TC+1) /* 49 */
+#define SRP (DRP+1) /* 50 */
+#define CRP (SRP+1) /* 51 */
+#define CAL (CRP+1) /* 52 */
+#define VAL (CAL+1) /* 53 */
+#define SCC (VAL+1) /* 54 */
+#define AC (SCC+1) /* 55 */
+#define BAD (AC+1) /* 56,57,58,59, 60,61,62,63 */
+#define BAC (BAD+8) /* 64,65,66,67, 68,69,70,71 */
+#define PSR (BAC+8) /* 72 */
+#define PCSR (PSR+1) /* 73 */
+
+/* name */ /* opcode */ /* match */ /* args */
+
+{"pbac", one(0xf0c7), one(0xffbf), "Bc"},
+{"pbacw", one(0xf087), one(0xffbf), "Bc"},
+{"pbas", one(0xf0c6), one(0xffbf), "Bc"},
+{"pbasw", one(0xf086), one(0xffbf), "Bc"},
+{"pbbc", one(0xf0c1), one(0xffbf), "Bc"},
+{"pbbcw", one(0xf081), one(0xffbf), "Bc"},
+{"pbbs", one(0xf0c0), one(0xffbf), "Bc"},
+{"pbbsw", one(0xf080), one(0xffbf), "Bc"},
+{"pbcc", one(0xf0cf), one(0xffbf), "Bc"},
+{"pbccw", one(0xf08f), one(0xffbf), "Bc"},
+{"pbcs", one(0xf0ce), one(0xffbf), "Bc"},
+{"pbcsw", one(0xf08e), one(0xffbf), "Bc"},
+{"pbgc", one(0xf0cd), one(0xffbf), "Bc"},
+{"pbgcw", one(0xf08d), one(0xffbf), "Bc"},
+{"pbgs", one(0xf0cc), one(0xffbf), "Bc"},
+{"pbgsw", one(0xf08c), one(0xffbf), "Bc"},
+{"pbic", one(0xf0cb), one(0xffbf), "Bc"},
+{"pbicw", one(0xf08b), one(0xffbf), "Bc"},
+{"pbis", one(0xf0ca), one(0xffbf), "Bc"},
+{"pbisw", one(0xf08a), one(0xffbf), "Bc"},
+{"pblc", one(0xf0c3), one(0xffbf), "Bc"},
+{"pblcw", one(0xf083), one(0xffbf), "Bc"},
+{"pbls", one(0xf0c2), one(0xffbf), "Bc"},
+{"pblsw", one(0xf082), one(0xffbf), "Bc"},
+{"pbsc", one(0xf0c5), one(0xffbf), "Bc"},
+{"pbscw", one(0xf085), one(0xffbf), "Bc"},
+{"pbss", one(0xf0c4), one(0xffbf), "Bc"},
+{"pbssw", one(0xf084), one(0xffbf), "Bc"},
+{"pbwc", one(0xf0c9), one(0xffbf), "Bc"},
+{"pbwcw", one(0xf089), one(0xffbf), "Bc"},
+{"pbws", one(0xf0c8), one(0xffbf), "Bc"},
+{"pbwsw", one(0xf088), one(0xffbf), "Bc"},
+
+
+{"pdbac", two(0xf048, 0x0007), two(0xfff8, 0xffff), "DsBw"},
+{"pdbas", two(0xf048, 0x0006), two(0xfff8, 0xffff), "DsBw"},
+{"pdbbc", two(0xf048, 0x0001), two(0xfff8, 0xffff), "DsBw"},
+{"pdbbs", two(0xf048, 0x0000), two(0xfff8, 0xffff), "DsBw"},
+{"pdbcc", two(0xf048, 0x000f), two(0xfff8, 0xffff), "DsBw"},
+{"pdbcs", two(0xf048, 0x000e), two(0xfff8, 0xffff), "DsBw"},
+{"pdbgc", two(0xf048, 0x000d), two(0xfff8, 0xffff), "DsBw"},
+{"pdbgs", two(0xf048, 0x000c), two(0xfff8, 0xffff), "DsBw"},
+{"pdbic", two(0xf048, 0x000b), two(0xfff8, 0xffff), "DsBw"},
+{"pdbis", two(0xf048, 0x000a), two(0xfff8, 0xffff), "DsBw"},
+{"pdblc", two(0xf048, 0x0003), two(0xfff8, 0xffff), "DsBw"},
+{"pdbls", two(0xf048, 0x0002), two(0xfff8, 0xffff), "DsBw"},
+{"pdbsc", two(0xf048, 0x0005), two(0xfff8, 0xffff), "DsBw"},
+{"pdbss", two(0xf048, 0x0004), two(0xfff8, 0xffff), "DsBw"},
+{"pdbwc", two(0xf048, 0x0009), two(0xfff8, 0xffff), "DsBw"},
+{"pdbws", two(0xf048, 0x0008), two(0xfff8, 0xffff), "DsBw"},
+
+{"pflusha", two(0xf000, 0x2400), two(0xffff, 0xffff), "" },
+
+{"pflush", two(0xf000, 0x3010), two(0xffc0, 0xfe10), "T3T9" },
+{"pflush", two(0xf000, 0x3810), two(0xffc0, 0xfe10), "T3T9&s" },
+{"pflush", two(0xf000, 0x3008), two(0xffc0, 0xfe18), "D3T9" },
+{"pflush", two(0xf000, 0x3808), two(0xffc0, 0xfe18), "D3T9&s" },
+{"pflush", two(0xf000, 0x3000), two(0xffc0, 0xfe1e), "f3T9" },
+{"pflush", two(0xf000, 0x3800), two(0xffc0, 0xfe1e), "f3T9&s" },
+
+{"pflushs", two(0xf000, 0x3410), two(0xfff8, 0xfe10), "T3T9" },
+{"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe00), "T3T9&s" },
+{"pflushs", two(0xf000, 0x3408), two(0xfff8, 0xfe18), "D3T9" },
+{"pflushs", two(0xf000, 0x3c08), two(0xfff8, 0xfe18), "D3T9&s" },
+{"pflushs", two(0xf000, 0x3400), two(0xfff8, 0xfe1e), "f3T9" },
+{"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe1e), "f3T9&s"},
+
+{"pflushr", two(0xf000, 0xa000), two(0xffc0, 0xffff), "|s" },
+
+{"ploadr", two(0xf000, 0x2210), two(0xffc0, 0xfff0), "T3&s" },
+{"ploadr", two(0xf000, 0x2208), two(0xffc0, 0xfff8), "D3&s" },
+{"ploadr", two(0xf000, 0x2200), two(0xffc0, 0xfffe), "f3&s" },
+{"ploadw", two(0xf000, 0x2010), two(0xffc0, 0xfff0), "T3&s" },
+{"ploadw", two(0xf000, 0x2008), two(0xffc0, 0xfff8), "D3&s" },
+{"ploadw", two(0xf000, 0x2000), two(0xffc0, 0xfffe), "f3&s" },
+
+ /* TC, CRP, DRP, SRP, CAL, VAL, SCC, AC */
+{"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "*sP8" },
+{"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "P8%s" },
+{"pmove", two(0xf000, 0x4000), two(0xffc0, 0xe3ff), "|sW8" },
+{"pmove", two(0xf000, 0x4200), two(0xffc0, 0xe3ff), "W8~s" },
+
+ /* BADx, BACx */
+{"pmove", two(0xf000, 0x6200), two(0xffc0, 0xe3e3), "*sX3" },
+{"pmove", two(0xf000, 0x6000), two(0xffc0, 0xe3e3), "X3%s" },
+
+ /* PSR, PCSR */
+ /* {"pmove", two(0xf000, 0x6100), two(oxffc0, oxffff), "*sZ8" }, */
+{"pmove", two(0xf000, 0x6000), two(0xffc0, 0xffff), "*sY8" },
+{"pmove", two(0xf000, 0x6200), two(0xffc0, 0xffff), "Y8%s" },
+{"pmove", two(0xf000, 0x6600), two(0xffc0, 0xffff), "Z8%s" },
+
+{"prestore", one(0xf140), one(0xffc0), "&s"},
+{"prestore", one(0xf158), one(0xfff8), "+s"},
+{"psave", one(0xf100), one(0xffc0), "&s"},
+{"psave", one(0xf100), one(0xffc0), "+s"},
+
+{"psac", two(0xf040, 0x0007), two(0xffc0, 0xffff), "@s"},
+{"psas", two(0xf040, 0x0006), two(0xffc0, 0xffff), "@s"},
+{"psbc", two(0xf040, 0x0001), two(0xffc0, 0xffff), "@s"},
+{"psbs", two(0xf040, 0x0000), two(0xffc0, 0xffff), "@s"},
+{"pscc", two(0xf040, 0x000f), two(0xffc0, 0xffff), "@s"},
+{"pscs", two(0xf040, 0x000e), two(0xffc0, 0xffff), "@s"},
+{"psgc", two(0xf040, 0x000d), two(0xffc0, 0xffff), "@s"},
+{"psgs", two(0xf040, 0x000c), two(0xffc0, 0xffff), "@s"},
+{"psic", two(0xf040, 0x000b), two(0xffc0, 0xffff), "@s"},
+{"psis", two(0xf040, 0x000a), two(0xffc0, 0xffff), "@s"},
+{"pslc", two(0xf040, 0x0003), two(0xffc0, 0xffff), "@s"},
+{"psls", two(0xf040, 0x0002), two(0xffc0, 0xffff), "@s"},
+{"pssc", two(0xf040, 0x0005), two(0xffc0, 0xffff), "@s"},
+{"psss", two(0xf040, 0x0004), two(0xffc0, 0xffff), "@s"},
+{"pswc", two(0xf040, 0x0009), two(0xffc0, 0xffff), "@s"},
+{"psws", two(0xf040, 0x0008), two(0xffc0, 0xffff), "@s"},
+
+{"ptestr", two(0xf000, 0x8210), two(0xffc0, 0xe3f0), "T3&sQ8" },
+{"ptestr", two(0xf000, 0x8310), two(0xffc0, 0xe310), "T3&sQ8A9" },
+{"ptestr", two(0xf000, 0x8208), two(0xffc0, 0xe3f8), "D3&sQ8" },
+{"ptestr", two(0xf000, 0x8308), two(0xffc0, 0xe318), "D3&sQ8A9" },
+{"ptestr", two(0xf000, 0x8200), two(0xffc0, 0xe3fe), "f3&sQ8" },
+{"ptestr", two(0xf000, 0x8300), two(0xffc0, 0xe31e), "f3&sQ8A9" },
+
+{"ptestw", two(0xf000, 0x8010), two(0xffc0, 0xe3f0), "T3&sQ8" },
+{"ptestw", two(0xf000, 0x8110), two(0xffc0, 0xe310), "T3&sQ8A9" },
+{"ptestw", two(0xf000, 0x8008), two(0xffc0, 0xe3f8), "D3&sQ8" },
+{"ptestw", two(0xf000, 0x8108), two(0xffc0, 0xe318), "D3&sQ8A9" },
+{"ptestw", two(0xf000, 0x8000), two(0xffc0, 0xe3fe), "f3&sQ8" },
+{"ptestw", two(0xf000, 0x8100), two(0xffc0, 0xe31e), "f3&sQ8A9" },
+
+{"ptrapacw", two(0xf07a, 0x0007), two(0xffff, 0xffff), "#w"},
+{"ptrapacl", two(0xf07b, 0x0007), two(0xffff, 0xffff), "#l"},
+{"ptrapac", two(0xf07c, 0x0007), two(0xffff, 0xffff), ""},
+
+{"ptrapasw", two(0xf07a, 0x0006), two(0xffff, 0xffff), "#w"},
+{"ptrapasl", two(0xf07b, 0x0006), two(0xffff, 0xffff), "#l"},
+{"ptrapas", two(0xf07c, 0x0006), two(0xffff, 0xffff), ""},
+
+{"ptrapbcw", two(0xf07a, 0x0001), two(0xffff, 0xffff), "#w"},
+{"ptrapbcl", two(0xf07b, 0x0001), two(0xffff, 0xffff), "#l"},
+{"ptrapbc", two(0xf07c, 0x0001), two(0xffff, 0xffff), ""},
+
+{"ptrapbsw", two(0xf07a, 0x0000), two(0xffff, 0xffff), "#w"},
+{"ptrapbsl", two(0xf07b, 0x0000), two(0xffff, 0xffff), "#l"},
+{"ptrapbs", two(0xf07c, 0x0000), two(0xffff, 0xffff), ""},
+
+{"ptrapccw", two(0xf07a, 0x000f), two(0xffff, 0xffff), "#w"},
+{"ptrapccl", two(0xf07b, 0x000f), two(0xffff, 0xffff), "#l"},
+{"ptrapcc", two(0xf07c, 0x000f), two(0xffff, 0xffff), ""},
+
+{"ptrapcsw", two(0xf07a, 0x000e), two(0xffff, 0xffff), "#w"},
+{"ptrapcsl", two(0xf07b, 0x000e), two(0xffff, 0xffff), "#l"},
+{"ptrapcs", two(0xf07c, 0x000e), two(0xffff, 0xffff), ""},
+
+{"ptrapgcw", two(0xf07a, 0x000d), two(0xffff, 0xffff), "#w"},
+{"ptrapgcl", two(0xf07b, 0x000d), two(0xffff, 0xffff), "#l"},
+{"ptrapgc", two(0xf07c, 0x000d), two(0xffff, 0xffff), ""},
+
+{"ptrapgsw", two(0xf07a, 0x000c), two(0xffff, 0xffff), "#w"},
+{"ptrapgsl", two(0xf07b, 0x000c), two(0xffff, 0xffff), "#l"},
+{"ptrapgs", two(0xf07c, 0x000c), two(0xffff, 0xffff), ""},
+
+{"ptrapicw", two(0xf07a, 0x000b), two(0xffff, 0xffff), "#w"},
+{"ptrapicl", two(0xf07b, 0x000b), two(0xffff, 0xffff), "#l"},
+{"ptrapic", two(0xf07c, 0x000b), two(0xffff, 0xffff), ""},
+
+{"ptrapisw", two(0xf07a, 0x000a), two(0xffff, 0xffff), "#w"},
+{"ptrapisl", two(0xf07b, 0x000a), two(0xffff, 0xffff), "#l"},
+{"ptrapis", two(0xf07c, 0x000a), two(0xffff, 0xffff), ""},
+
+{"ptraplcw", two(0xf07a, 0x0003), two(0xffff, 0xffff), "#w"},
+{"ptraplcl", two(0xf07b, 0x0003), two(0xffff, 0xffff), "#l"},
+{"ptraplc", two(0xf07c, 0x0003), two(0xffff, 0xffff), ""},
+
+{"ptraplsw", two(0xf07a, 0x0002), two(0xffff, 0xffff), "#w"},
+{"ptraplsl", two(0xf07b, 0x0002), two(0xffff, 0xffff), "#l"},
+{"ptrapls", two(0xf07c, 0x0002), two(0xffff, 0xffff), ""},
+
+{"ptrapscw", two(0xf07a, 0x0005), two(0xffff, 0xffff), "#w"},
+{"ptrapscl", two(0xf07b, 0x0005), two(0xffff, 0xffff), "#l"},
+{"ptrapsc", two(0xf07c, 0x0005), two(0xffff, 0xffff), ""},
+
+{"ptrapssw", two(0xf07a, 0x0004), two(0xffff, 0xffff), "#w"},
+{"ptrapssl", two(0xf07b, 0x0004), two(0xffff, 0xffff), "#l"},
+{"ptrapss", two(0xf07c, 0x0004), two(0xffff, 0xffff), ""},
+
+{"ptrapwcw", two(0xf07a, 0x0009), two(0xffff, 0xffff), "#w"},
+{"ptrapwcl", two(0xf07b, 0x0009), two(0xffff, 0xffff), "#l"},
+{"ptrapwc", two(0xf07c, 0x0009), two(0xffff, 0xffff), ""},
+
+{"ptrapwsw", two(0xf07a, 0x0008), two(0xffff, 0xffff), "#w"},
+{"ptrapwsl", two(0xf07b, 0x0008), two(0xffff, 0xffff), "#l"},
+{"ptrapws", two(0xf07c, 0x0008), two(0xffff, 0xffff), ""},
+
+{"pvalid", two(0xf000, 0x2800), two(0xffc0, 0xffff), "Vs&s"},
+{"pvalid", two(0xf000, 0x2c00), two(0xffc0, 0xfff8), "A3&s" },
+
+#endif /* m68851 */
+
+/* end of tc-m68851.h */
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
new file mode 100644
index 00000000000..856dd4ec264
--- /dev/null
+++ b/gas/config/tc-m68k.c
@@ -0,0 +1,7009 @@
+/* tc-m68k.c -- Assemble for the m68k family
+ Copyright (C) 1987, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <ctype.h>
+#include "as.h"
+#include "obstack.h"
+#include "subsegs.h"
+
+#include "opcode/m68k.h"
+#include "m68k-parse.h"
+
+/* This string holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. The macro
+ tc_comment_chars points to this. We use this, rather than the
+ usual comment_chars, so that the --bitwise-or option will work. */
+#if defined (TE_SVR4) || defined (TE_DELTA)
+const char *m68k_comment_chars = "|#";
+#else
+const char *m68k_comment_chars = "|";
+#endif
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments like this one will always work. */
+const char line_comment_chars[] = "#*";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+CONST char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant, as
+ in "0f12.456" or "0d1.2345e12". */
+
+CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c . Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here. */
+
+const int md_reloc_size = 8; /* Size of relocation record */
+
+/* Are we trying to generate PIC code? If so, absolute references
+ ought to be made into linkage table references or pc-relative
+ references. Not implemented. For ELF there are other means
+ to denote pic relocations. */
+int flag_want_pic;
+
+static int flag_short_refs; /* -l option */
+static int flag_long_jumps; /* -S option */
+
+#ifdef REGISTER_PREFIX_OPTIONAL
+int flag_reg_prefix_optional = REGISTER_PREFIX_OPTIONAL;
+#else
+int flag_reg_prefix_optional;
+#endif
+
+/* Whether --register-prefix-optional was used on the command line. */
+static int reg_prefix_optional_seen;
+
+/* The floating point coprocessor to use by default. */
+static enum m68k_register m68k_float_copnum = COP1;
+
+/* If this is non-zero, then references to number(%pc) will be taken
+ to refer to number, rather than to %pc + number. */
+static int m68k_abspcadd;
+
+/* If this is non-zero, then the quick forms of the move, add, and sub
+ instructions are used when possible. */
+static int m68k_quick = 1;
+
+/* If this is non-zero, then if the size is not specified for a base
+ or outer displacement, the assembler assumes that the size should
+ be 32 bits. */
+static int m68k_rel32 = 1;
+
+/* This is non-zero if m68k_rel32 was set from the command line. */
+static int m68k_rel32_from_cmdline;
+
+/* The default width to use for an index register when using a base
+ displacement. */
+static enum m68k_size m68k_index_width_default = SIZE_LONG;
+
+/* We want to warn if any text labels are misaligned. In order to get
+ the right line number, we need to record the line number for each
+ label. */
+
+struct label_line
+{
+ struct label_line *next;
+ symbolS *label;
+ char *file;
+ unsigned int line;
+ int text;
+};
+
+/* The list of labels. */
+
+static struct label_line *labels;
+
+/* The current label. */
+
+static struct label_line *current_label;
+
+/* Its an arbitrary name: This means I don't approve of it */
+/* See flames below */
+static struct obstack robyn;
+
+#define TAB(x,y) (((x)<<2)+(y))
+#define TABTYPE(xy) ((xy) >> 2)
+#define BYTE 0
+#define SHORT 1
+#define LONG 2
+#define SZ_UNDEF 3
+#undef BRANCH
+/* Case `g' except when BCC68000 is applicable. */
+#define ABRANCH 1
+/* Coprocessor branches. */
+#define FBRANCH 2
+/* Mode 7.2 -- program counter indirect with (16-bit) displacement,
+ supported on all cpus. Widens to 32-bit absolute. */
+#define PCREL 3
+/* For inserting an extra jmp instruction with long offset on 68000,
+ for expanding conditional branches. (Not bsr or bra.) Since the
+ 68000 doesn't support 32-bit displacements for conditional
+ branches, we fake it by reversing the condition and branching
+ around a jmp with an absolute long operand. */
+#define BCC68000 4
+/* For the DBcc "instructions". If the displacement requires 32 bits,
+ the branch-around-a-jump game is played here too. */
+#define DBCC 5
+/* Not currently used? */
+#define PCLEA 6
+/* Mode AINDX (apc-relative) using PC, with variable target, might fit
+ in 16 or 8 bits. */
+#define PCINDEX 7
+
+struct m68k_incant
+ {
+ const char *m_operands;
+ unsigned long m_opcode;
+ short m_opnum;
+ short m_codenum;
+ int m_arch;
+ struct m68k_incant *m_next;
+ };
+
+#define getone(x) ((((x)->m_opcode)>>16)&0xffff)
+#define gettwo(x) (((x)->m_opcode)&0xffff)
+
+static const enum m68k_register m68000_control_regs[] = { 0 };
+static const enum m68k_register m68010_control_regs[] = {
+ SFC, DFC, USP, VBR,
+ 0
+};
+static const enum m68k_register m68020_control_regs[] = {
+ SFC, DFC, USP, VBR, CACR, CAAR, MSP, ISP,
+ 0
+};
+static const enum m68k_register m68040_control_regs[] = {
+ SFC, DFC, CACR, TC, ITT0, ITT1, DTT0, DTT1,
+ USP, VBR, MSP, ISP, MMUSR, URP, SRP,
+ 0
+};
+static const enum m68k_register m68060_control_regs[] = {
+ SFC, DFC, CACR, TC, ITT0, ITT1, DTT0, DTT1, BUSCR,
+ USP, VBR, URP, SRP, PCR,
+ 0
+};
+static const enum m68k_register mcf5200_control_regs[] = {
+ CACR, TC, ITT0, ITT1, DTT0, DTT1, VBR, ROMBAR,
+ RAMBAR0, RAMBAR1, MBAR,
+ 0
+};
+#define cpu32_control_regs m68010_control_regs
+
+static const enum m68k_register *control_regs;
+
+/* internal form of a 68020 instruction */
+struct m68k_it
+{
+ const char *error;
+ const char *args; /* list of opcode info */
+ int numargs;
+
+ int numo; /* Number of shorts in opcode */
+ short opcode[11];
+
+ struct m68k_op operands[6];
+
+ int nexp; /* number of exprs in use */
+ struct m68k_exp exprs[4];
+
+ int nfrag; /* Number of frags we have to produce */
+ struct
+ {
+ int fragoff; /* Where in the current opcode the frag ends */
+ symbolS *fadd;
+ offsetT foff;
+ int fragty;
+ }
+ fragb[4];
+
+ int nrel; /* Num of reloc strucs in use */
+ struct
+ {
+ int n;
+ expressionS exp;
+ char wid;
+ char pcrel;
+ /* In a pc relative address the difference between the address
+ of the offset and the address that the offset is relative
+ to. This depends on the addressing mode. Basically this
+ is the value to put in the offset field to address the
+ first byte of the offset, without regarding the special
+ significance of some values (in the branch instruction, for
+ example). */
+ int pcrel_fix;
+#ifdef OBJ_ELF
+ /* Whether this expression needs special pic relocation, and if
+ so, which. */
+ enum pic_relocation pic_reloc;
+#endif
+ }
+ reloc[5]; /* Five is enough??? */
+};
+
+#define cpu_of_arch(x) ((x) & (m68000up|mcf5200))
+#define float_of_arch(x) ((x) & mfloat)
+#define mmu_of_arch(x) ((x) & mmmu)
+
+/* Macros for determining if cpu supports a specific addressing mode */
+#define HAVE_LONG_BRANCH(x) ((x) & (m68020|m68030|m68040|m68060|cpu32))
+
+static struct m68k_it the_ins; /* the instruction being assembled */
+
+#define op(ex) ((ex)->exp.X_op)
+#define adds(ex) ((ex)->exp.X_add_symbol)
+#define subs(ex) ((ex)->exp.X_op_symbol)
+#define offs(ex) ((ex)->exp.X_add_number)
+
+/* Macros for adding things to the m68k_it struct */
+
+#define addword(w) the_ins.opcode[the_ins.numo++]=(w)
+
+/* Static functions. */
+
+static void insop PARAMS ((int, const struct m68k_incant *));
+static void add_fix PARAMS ((int, struct m68k_exp *, int, int));
+static void add_frag PARAMS ((symbolS *, offsetT, int));
+
+/* Like addword, but goes BEFORE general operands */
+static void
+insop (w, opcode)
+ int w;
+ const struct m68k_incant *opcode;
+{
+ int z;
+ for(z=the_ins.numo;z>opcode->m_codenum;--z)
+ the_ins.opcode[z]=the_ins.opcode[z-1];
+ for(z=0;z<the_ins.nrel;z++)
+ the_ins.reloc[z].n+=2;
+ for (z = 0; z < the_ins.nfrag; z++)
+ the_ins.fragb[z].fragoff++;
+ the_ins.opcode[opcode->m_codenum]=w;
+ the_ins.numo++;
+}
+
+/* The numo+1 kludge is so we can hit the low order byte of the prev word.
+ Blecch. */
+static void
+add_fix (width, exp, pc_rel, pc_fix)
+ int width;
+ struct m68k_exp *exp;
+ int pc_rel;
+ int pc_fix;
+{
+ the_ins.reloc[the_ins.nrel].n = ((width == 'B' || width == '3')
+ ? (the_ins.numo*2-1)
+ : (((width)=='b')
+ ? (the_ins.numo*2+1)
+ : (the_ins.numo*2)));
+ the_ins.reloc[the_ins.nrel].exp = exp->exp;
+ the_ins.reloc[the_ins.nrel].wid = width;
+ the_ins.reloc[the_ins.nrel].pcrel_fix = pc_fix;
+#ifdef OBJ_ELF
+ the_ins.reloc[the_ins.nrel].pic_reloc = exp->pic_reloc;
+#endif
+ the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
+}
+
+/* Cause an extra frag to be generated here, inserting up to 10 bytes
+ (that value is chosen in the frag_var call in md_assemble). TYPE
+ is the subtype of the frag to be generated; its primary type is
+ rs_machine_dependent.
+
+ The TYPE parameter is also used by md_convert_frag_1 and
+ md_estimate_size_before_relax. The appropriate type of fixup will
+ be emitted by md_convert_frag_1.
+
+ ADD becomes the FR_SYMBOL field of the frag, and OFF the FR_OFFSET. */
+static void
+add_frag (add, off, type)
+ symbolS *add;
+ offsetT off;
+ int type;
+{
+ the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;
+ the_ins.fragb[the_ins.nfrag].fadd=add;
+ the_ins.fragb[the_ins.nfrag].foff=off;
+ the_ins.fragb[the_ins.nfrag++].fragty=type;
+}
+
+#define isvar(ex) \
+ (op (ex) != O_constant && op (ex) != O_big)
+
+static char *crack_operand PARAMS ((char *str, struct m68k_op *opP));
+static int get_num PARAMS ((struct m68k_exp *exp, int ok));
+static void m68k_ip PARAMS ((char *));
+static void insert_reg PARAMS ((const char *, int));
+static void select_control_regs PARAMS ((void));
+static void init_regtable PARAMS ((void));
+static int reverse_16_bits PARAMS ((int in));
+static int reverse_8_bits PARAMS ((int in));
+static void install_gen_operand PARAMS ((int mode, int val));
+static void install_operand PARAMS ((int mode, int val));
+static void s_bss PARAMS ((int));
+static void s_data1 PARAMS ((int));
+static void s_data2 PARAMS ((int));
+static void s_even PARAMS ((int));
+static void s_proc PARAMS ((int));
+static void mri_chip PARAMS ((void));
+static void s_chip PARAMS ((int));
+static void s_fopt PARAMS ((int));
+static void s_opt PARAMS ((int));
+static void s_reg PARAMS ((int));
+static void s_restore PARAMS ((int));
+static void s_save PARAMS ((int));
+static void s_mri_if PARAMS ((int));
+static void s_mri_else PARAMS ((int));
+static void s_mri_endi PARAMS ((int));
+static void s_mri_break PARAMS ((int));
+static void s_mri_next PARAMS ((int));
+static void s_mri_for PARAMS ((int));
+static void s_mri_endf PARAMS ((int));
+static void s_mri_repeat PARAMS ((int));
+static void s_mri_until PARAMS ((int));
+static void s_mri_while PARAMS ((int));
+static void s_mri_endw PARAMS ((int));
+static void md_apply_fix_2 PARAMS ((fixS *, offsetT));
+static void md_convert_frag_1 PARAMS ((fragS *));
+
+static int current_architecture;
+
+struct m68k_cpu {
+ unsigned long arch;
+ const char *name;
+ int alias;
+};
+
+static const struct m68k_cpu archs[] = {
+ { m68000, "68000", 0 },
+ { m68010, "68010", 0 },
+ { m68020, "68020", 0 },
+ { m68030, "68030", 0 },
+ { m68040, "68040", 0 },
+ { m68060, "68060", 0 },
+ { cpu32, "cpu32", 0 },
+ { m68881, "68881", 0 },
+ { m68851, "68851", 0 },
+ { mcf5200, "5200", 0 },
+ /* Aliases (effectively, so far as gas is concerned) for the above
+ cpus. */
+ { m68020, "68k", 1 },
+ { m68000, "68008", 1 },
+ { m68000, "68302", 1 },
+ { m68000, "68306", 1 },
+ { m68000, "68307", 1 },
+ { m68000, "68322", 1 },
+ { m68000, "68356", 1 },
+ { m68000, "68ec000", 1 },
+ { m68000, "68hc000", 1 },
+ { m68000, "68hc001", 1 },
+ { m68020, "68ec020", 1 },
+ { m68030, "68ec030", 1 },
+ { m68040, "68ec040", 1 },
+ { m68060, "68ec060", 1 },
+ { cpu32, "68330", 1 },
+ { cpu32, "68331", 1 },
+ { cpu32, "68332", 1 },
+ { cpu32, "68333", 1 },
+ { cpu32, "68334", 1 },
+ { cpu32, "68336", 1 },
+ { cpu32, "68340", 1 },
+ { cpu32, "68341", 1 },
+ { cpu32, "68349", 1 },
+ { cpu32, "68360", 1 },
+ { m68881, "68882", 1 },
+};
+
+static const int n_archs = sizeof (archs) / sizeof (archs[0]);
+
+/* BCC68000 is for patching in an extra jmp instruction for long offsets
+ on the 68000. The 68000 doesn't support long branches with branchs */
+
+/* This table desribes how you change sizes for the various types of variable
+ size expressions. This version only supports two kinds. */
+
+/* Note that calls to frag_var need to specify the maximum expansion
+ needed; this is currently 10 bytes for DBCC. */
+
+/* The fields are:
+ How far Forward this mode will reach:
+ How far Backward this mode will reach:
+ How many bytes this mode will add to the size of the frag
+ Which mode to go to if the offset won't fit in this one
+ */
+relax_typeS md_relax_table[] =
+{
+ {1, 1, 0, 0}, /* First entries aren't used */
+ {1, 1, 0, 0}, /* For no good reason except */
+ {1, 1, 0, 0}, /* that the VAX doesn't either */
+ {1, 1, 0, 0},
+
+ {(127), (-128), 0, TAB (ABRANCH, SHORT)},
+ {(32767), (-32768), 2, TAB (ABRANCH, LONG)},
+ {0, 0, 4, 0},
+ {1, 1, 0, 0},
+
+ {1, 1, 0, 0}, /* FBRANCH doesn't come BYTE */
+ {(32767), (-32768), 2, TAB (FBRANCH, LONG)},
+ {0, 0, 4, 0},
+ {1, 1, 0, 0},
+
+ {1, 1, 0, 0}, /* PCREL doesn't come BYTE */
+ {(32767), (-32768), 2, TAB (PCREL, LONG)},
+ {0, 0, 4, 0},
+ {1, 1, 0, 0},
+
+ {(127), (-128), 0, TAB (BCC68000, SHORT)},
+ {(32767), (-32768), 2, TAB (BCC68000, LONG)},
+ {0, 0, 6, 0}, /* jmp long space */
+ {1, 1, 0, 0},
+
+ {1, 1, 0, 0}, /* DBCC doesn't come BYTE */
+ {(32767), (-32768), 2, TAB (DBCC, LONG)},
+ {0, 0, 10, 0}, /* bra/jmp long space */
+ {1, 1, 0, 0},
+
+ {1, 1, 0, 0}, /* PCLEA doesn't come BYTE */
+ {32767, -32768, 2, TAB (PCLEA, LONG)},
+ {0, 0, 6, 0},
+ {1, 1, 0, 0},
+
+ /* For, e.g., jmp pcrel indexed. */
+ {125, -130, 0, TAB (PCINDEX, SHORT)},
+ {32765, -32770, 2, TAB (PCINDEX, LONG)},
+ {0, 0, 4, 0},
+ {1, 1, 0, 0},
+};
+
+/* These are the machine dependent pseudo-ops. These are included so
+ the assembler can work on the output from the SUN C compiler, which
+ generates these.
+ */
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"data1", s_data1, 0},
+ {"data2", s_data2, 0},
+ {"bss", s_bss, 0},
+ {"even", s_even, 0},
+ {"skip", s_space, 0},
+ {"proc", s_proc, 0},
+#if defined (TE_SUN3) || defined (OBJ_ELF)
+ {"align", s_align_bytes, 0},
+#endif
+#ifdef OBJ_ELF
+ {"swbeg", s_ignore, 0},
+#endif
+ {"extend", float_cons, 'x'},
+ {"ldouble", float_cons, 'x'},
+
+ /* The following pseudo-ops are supported for MRI compatibility. */
+ {"chip", s_chip, 0},
+ {"comline", s_space, 1},
+ {"fopt", s_fopt, 0},
+ {"mask2", s_ignore, 0},
+ {"opt", s_opt, 0},
+ {"reg", s_reg, 0},
+ {"restore", s_restore, 0},
+ {"save", s_save, 0},
+
+ {"if", s_mri_if, 0},
+ {"if.b", s_mri_if, 'b'},
+ {"if.w", s_mri_if, 'w'},
+ {"if.l", s_mri_if, 'l'},
+ {"else", s_mri_else, 0},
+ {"else.s", s_mri_else, 's'},
+ {"else.l", s_mri_else, 'l'},
+ {"endi", s_mri_endi, 0},
+ {"break", s_mri_break, 0},
+ {"break.s", s_mri_break, 's'},
+ {"break.l", s_mri_break, 'l'},
+ {"next", s_mri_next, 0},
+ {"next.s", s_mri_next, 's'},
+ {"next.l", s_mri_next, 'l'},
+ {"for", s_mri_for, 0},
+ {"for.b", s_mri_for, 'b'},
+ {"for.w", s_mri_for, 'w'},
+ {"for.l", s_mri_for, 'l'},
+ {"endf", s_mri_endf, 0},
+ {"repeat", s_mri_repeat, 0},
+ {"until", s_mri_until, 0},
+ {"until.b", s_mri_until, 'b'},
+ {"until.w", s_mri_until, 'w'},
+ {"until.l", s_mri_until, 'l'},
+ {"while", s_mri_while, 0},
+ {"while.b", s_mri_while, 'b'},
+ {"while.w", s_mri_while, 'w'},
+ {"while.l", s_mri_while, 'l'},
+ {"endw", s_mri_endw, 0},
+
+ {0, 0, 0}
+};
+
+
+/* The mote pseudo ops are put into the opcode table, since they
+ don't start with a . they look like opcodes to gas.
+ */
+
+#ifdef M68KCOFF
+extern void obj_coff_section PARAMS ((int));
+#endif
+
+CONST pseudo_typeS mote_pseudo_table[] =
+{
+
+ {"dcl", cons, 4},
+ {"dc", cons, 2},
+ {"dcw", cons, 2},
+ {"dcb", cons, 1},
+
+ {"dsl", s_space, 4},
+ {"ds", s_space, 2},
+ {"dsw", s_space, 2},
+ {"dsb", s_space, 1},
+
+ {"xdef", s_globl, 0},
+#ifdef OBJ_ELF
+ {"align", s_align_bytes, 0},
+#else
+ {"align", s_align_ptwo, 0},
+#endif
+#ifdef M68KCOFF
+ {"sect", obj_coff_section, 0},
+ {"section", obj_coff_section, 0},
+#endif
+ {0, 0, 0}
+};
+
+#define issbyte(x) ((x)>=-128 && (x)<=127)
+#define isubyte(x) ((x)>=0 && (x)<=255)
+#define issword(x) ((x)>=-32768 && (x)<=32767)
+#define isuword(x) ((x)>=0 && (x)<=65535)
+
+#define isbyte(x) ((x)>= -255 && (x)<=255)
+#define isword(x) ((x)>=-65536 && (x)<=65535)
+#define islong(x) (1)
+
+extern char *input_line_pointer;
+
+static char mklower_table[256];
+#define mklower(c) (mklower_table[(unsigned char)(c)])
+static char notend_table[256];
+static char alt_notend_table[256];
+#define notend(s) \
+ (! (notend_table[(unsigned char) *s] \
+ || (*s == ':' \
+ && alt_notend_table[(unsigned char) s[1]])))
+
+#if defined (M68KCOFF) && !defined (BFD_ASSEMBLER)
+
+#ifdef NO_PCREL_RELOCS
+
+int
+make_pcrel_absolute(fixP, add_number)
+ fixS *fixP;
+ long *add_number;
+{
+ register unsigned char *opcode = fixP->fx_frag->fr_opcode;
+
+ /* rewrite the PC relative instructions to absolute address ones.
+ * these are rumoured to be faster, and the apollo linker refuses
+ * to deal with the PC relative relocations.
+ */
+ if (opcode[0] == 0x60 && opcode[1] == 0xff) /* BRA -> JMP */
+ {
+ opcode[0] = 0x4e;
+ opcode[1] = 0xf9;
+ }
+ else if (opcode[0] == 0x61 && opcode[1] == 0xff) /* BSR -> JSR */
+ {
+ opcode[0] = 0x4e;
+ opcode[1] = 0xb9;
+ }
+ else
+ as_fatal (_("Unknown PC relative instruction"));
+ *add_number -= 4;
+ return 0;
+}
+
+#endif /* NO_PCREL_RELOCS */
+
+short
+tc_coff_fix2rtype (fixP)
+ fixS *fixP;
+{
+ if (fixP->fx_tcbit && fixP->fx_size == 4)
+ return R_RELLONG_NEG;
+#ifdef NO_PCREL_RELOCS
+ know (fixP->fx_pcrel == 0);
+ return (fixP->fx_size == 1 ? R_RELBYTE
+ : fixP->fx_size == 2 ? R_DIR16
+ : R_DIR32);
+#else
+ return (fixP->fx_pcrel ?
+ (fixP->fx_size == 1 ? R_PCRBYTE :
+ fixP->fx_size == 2 ? R_PCRWORD :
+ R_PCRLONG) :
+ (fixP->fx_size == 1 ? R_RELBYTE :
+ fixP->fx_size == 2 ? R_RELWORD :
+ R_RELLONG));
+#endif
+}
+
+#endif
+
+#ifdef OBJ_ELF
+
+/* Compute the relocation code for a fixup of SIZE bytes, using pc
+ relative relocation if PCREL is non-zero. PIC says whether a special
+ pic relocation was requested. */
+
+static bfd_reloc_code_real_type get_reloc_code
+ PARAMS ((int, int, enum pic_relocation));
+
+static bfd_reloc_code_real_type
+get_reloc_code (size, pcrel, pic)
+ int size;
+ int pcrel;
+ enum pic_relocation pic;
+{
+ switch (pic)
+ {
+ case pic_got_pcrel:
+ switch (size)
+ {
+ case 1:
+ return BFD_RELOC_8_GOT_PCREL;
+ case 2:
+ return BFD_RELOC_16_GOT_PCREL;
+ case 4:
+ return BFD_RELOC_32_GOT_PCREL;
+ }
+ break;
+
+ case pic_got_off:
+ switch (size)
+ {
+ case 1:
+ return BFD_RELOC_8_GOTOFF;
+ case 2:
+ return BFD_RELOC_16_GOTOFF;
+ case 4:
+ return BFD_RELOC_32_GOTOFF;
+ }
+ break;
+
+ case pic_plt_pcrel:
+ switch (size)
+ {
+ case 1:
+ return BFD_RELOC_8_PLT_PCREL;
+ case 2:
+ return BFD_RELOC_16_PLT_PCREL;
+ case 4:
+ return BFD_RELOC_32_PLT_PCREL;
+ }
+ break;
+
+ case pic_plt_off:
+ switch (size)
+ {
+ case 1:
+ return BFD_RELOC_8_PLTOFF;
+ case 2:
+ return BFD_RELOC_16_PLTOFF;
+ case 4:
+ return BFD_RELOC_32_PLTOFF;
+ }
+ break;
+
+ case pic_none:
+ if (pcrel)
+ {
+ switch (size)
+ {
+ case 1:
+ return BFD_RELOC_8_PCREL;
+ case 2:
+ return BFD_RELOC_16_PCREL;
+ case 4:
+ return BFD_RELOC_32_PCREL;
+ }
+ }
+ else
+ {
+ switch (size)
+ {
+ case 1:
+ return BFD_RELOC_8;
+ case 2:
+ return BFD_RELOC_16;
+ case 4:
+ return BFD_RELOC_32;
+ }
+ }
+ }
+
+ if (pcrel)
+ {
+ if (pic == pic_none)
+ as_bad (_("Can not do %d byte pc-relative relocation"), size);
+ else
+ as_bad (_("Can not do %d byte pc-relative pic relocation"), size);
+ }
+ else
+ {
+ if (pic == pic_none)
+ as_bad (_("Can not do %d byte relocation"), size);
+ else
+ as_bad (_("Can not do %d byte pic relocation"), size);
+ }
+
+ return BFD_RELOC_NONE;
+}
+
+/* Here we decide which fixups can be adjusted to make them relative
+ to the beginning of the section instead of the symbol. Basically
+ we need to make sure that the dynamic relocations are done
+ correctly, so in some cases we force the original symbol to be
+ used. */
+int
+tc_m68k_fix_adjustable (fixP)
+ fixS *fixP;
+{
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+
+ /* adjust_reloc_syms doesn't know about the GOT */
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_8_GOT_PCREL:
+ case BFD_RELOC_16_GOT_PCREL:
+ case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_8_GOTOFF:
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_32_GOTOFF:
+ case BFD_RELOC_8_PLT_PCREL:
+ case BFD_RELOC_16_PLT_PCREL:
+ case BFD_RELOC_32_PLT_PCREL:
+ case BFD_RELOC_8_PLTOFF:
+ case BFD_RELOC_16_PLTOFF:
+ case BFD_RELOC_32_PLTOFF:
+ return 0;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ return 0;
+
+ default:
+ return 1;
+ }
+}
+
+#else /* !OBJ_ELF */
+
+#define get_reloc_code(SIZE,PCREL,OTHER) NO_RELOC
+
+#endif /* OBJ_ELF */
+
+#ifdef BFD_ASSEMBLER
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ if (fixp->fx_tcbit)
+ abort ();
+
+ if (fixp->fx_r_type != BFD_RELOC_NONE)
+ {
+ code = fixp->fx_r_type;
+
+ /* Since DIFF_EXPR_OK is defined in tc-m68k.h, it is possible
+ that fixup_segment converted a non-PC relative reloc into a
+ PC relative reloc. In such a case, we need to convert the
+ reloc code. */
+ if (fixp->fx_pcrel)
+ {
+ switch (code)
+ {
+ case BFD_RELOC_8:
+ code = BFD_RELOC_8_PCREL;
+ break;
+ case BFD_RELOC_16:
+ code = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_32:
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_8_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_8_GOT_PCREL:
+ case BFD_RELOC_16_GOT_PCREL:
+ case BFD_RELOC_32_GOT_PCREL:
+ case BFD_RELOC_8_GOTOFF:
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_32_GOTOFF:
+ case BFD_RELOC_8_PLT_PCREL:
+ case BFD_RELOC_16_PLT_PCREL:
+ case BFD_RELOC_32_PLT_PCREL:
+ case BFD_RELOC_8_PLTOFF:
+ case BFD_RELOC_16_PLTOFF:
+ case BFD_RELOC_32_PLTOFF:
+ break;
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot make %s relocation PC relative"),
+ bfd_get_reloc_code_name (code));
+ }
+ }
+ }
+ else
+ {
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+ switch (F (fixp->fx_size, fixp->fx_pcrel))
+ {
+#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
+ MAP (1, 0, BFD_RELOC_8);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (4, 0, BFD_RELOC_32);
+ MAP (1, 1, BFD_RELOC_8_PCREL);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 1, BFD_RELOC_32_PCREL);
+ default:
+ abort ();
+ }
+ }
+#undef F
+#undef MAP
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+#ifndef OBJ_ELF
+ if (fixp->fx_pcrel)
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = 0;
+#else
+ if (!fixp->fx_pcrel)
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = (section->vma
+ + (fixp->fx_pcrel_adjust == 64
+ ? -1 : fixp->fx_pcrel_adjust)
+ + fixp->fx_addnumber
+ + md_pcrel_from (fixp));
+#endif
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ assert (reloc->howto != 0);
+
+ return reloc;
+}
+
+#endif /* BFD_ASSEMBLER */
+
+/* Return zero if the reference to SYMBOL from within the same segment may
+ be relaxed. */
+#ifdef OBJ_ELF
+
+/* On an ELF system, we can't relax an externally visible symbol,
+ because it may be overridden by a shared library. However, if
+ TARGET_OS is "elf", then we presume that we are assembling for an
+ embedded system, in which case we don't have to worry about shared
+ libraries, and we can relax anything. */
+
+#define relaxable_symbol(symbol) \
+ (strcmp (TARGET_OS, "elf") == 0 \
+ || (! S_IS_EXTERNAL (symbol) \
+ && ! S_IS_WEAK (symbol)))
+
+#else
+
+#define relaxable_symbol(symbol) 1
+
+#endif
+
+/* Handle of the OPCODE hash table. NULL means any use before
+ m68k_ip_begin() will crash. */
+static struct hash_control *op_hash;
+
+/* Assemble an m68k instruction. */
+
+static void
+m68k_ip (instring)
+ char *instring;
+{
+ register char *p;
+ register struct m68k_op *opP;
+ register const struct m68k_incant *opcode;
+ register const char *s;
+ register int tmpreg = 0, baseo = 0, outro = 0, nextword;
+ char *pdot, *pdotmove;
+ enum m68k_size siz1, siz2;
+ char c;
+ int losing;
+ int opsfound;
+ LITTLENUM_TYPE words[6];
+ LITTLENUM_TYPE *wordp;
+ unsigned long ok_arch = 0;
+
+ if (*instring == ' ')
+ instring++; /* skip leading whitespace */
+
+ /* Scan up to end of operation-code, which MUST end in end-of-string
+ or exactly 1 space. */
+ pdot = 0;
+ for (p = instring; *p != '\0'; p++)
+ {
+ if (*p == ' ')
+ break;
+ if (*p == '.')
+ pdot = p;
+ }
+
+ if (p == instring)
+ {
+ the_ins.error = _("No operator");
+ return;
+ }
+
+ /* p now points to the end of the opcode name, probably whitespace.
+ Make sure the name is null terminated by clobbering the
+ whitespace, look it up in the hash table, then fix it back.
+ Remove a dot, first, since the opcode tables have none. */
+ if (pdot != NULL)
+ {
+ for (pdotmove = pdot; pdotmove < p; pdotmove++)
+ *pdotmove = pdotmove[1];
+ p--;
+ }
+
+ c = *p;
+ *p = '\0';
+ opcode = (const struct m68k_incant *) hash_find (op_hash, instring);
+ *p = c;
+
+ if (pdot != NULL)
+ {
+ for (pdotmove = p; pdotmove > pdot; pdotmove--)
+ *pdotmove = pdotmove[-1];
+ *pdot = '.';
+ ++p;
+ }
+
+ if (opcode == NULL)
+ {
+ the_ins.error = _("Unknown operator");
+ return;
+ }
+
+ /* found a legitimate opcode, start matching operands */
+ while (*p == ' ')
+ ++p;
+
+ if (opcode->m_operands == 0)
+ {
+ char *old = input_line_pointer;
+ *old = '\n';
+ input_line_pointer = p;
+ /* Ahh - it's a motorola style psuedo op */
+ mote_pseudo_table[opcode->m_opnum].poc_handler
+ (mote_pseudo_table[opcode->m_opnum].poc_val);
+ input_line_pointer = old;
+ *old = 0;
+
+ return;
+ }
+
+ if (flag_mri && opcode->m_opnum == 0)
+ {
+ /* In MRI mode, random garbage is allowed after an instruction
+ which accepts no operands. */
+ the_ins.args = opcode->m_operands;
+ the_ins.numargs = opcode->m_opnum;
+ the_ins.numo = opcode->m_codenum;
+ the_ins.opcode[0] = getone (opcode);
+ the_ins.opcode[1] = gettwo (opcode);
+ return;
+ }
+
+ for (opP = &the_ins.operands[0]; *p; opP++)
+ {
+ p = crack_operand (p, opP);
+
+ if (opP->error)
+ {
+ the_ins.error = opP->error;
+ return;
+ }
+ }
+
+ opsfound = opP - &the_ins.operands[0];
+
+ /* This ugly hack is to support the floating pt opcodes in their
+ standard form. Essentially, we fake a first enty of type COP#1 */
+ if (opcode->m_operands[0] == 'I')
+ {
+ int n;
+
+ for (n = opsfound; n > 0; --n)
+ the_ins.operands[n] = the_ins.operands[n - 1];
+
+ memset ((char *) (&the_ins.operands[0]), '\0',
+ sizeof (the_ins.operands[0]));
+ the_ins.operands[0].mode = CONTROL;
+ the_ins.operands[0].reg = m68k_float_copnum;
+ opsfound++;
+ }
+
+ /* We've got the operands. Find an opcode that'll accept them */
+ for (losing = 0;;)
+ {
+ /* If we didn't get the right number of ops, or we have no
+ common model with this pattern then reject this pattern. */
+
+ ok_arch |= opcode->m_arch;
+ if (opsfound != opcode->m_opnum
+ || ((opcode->m_arch & current_architecture) == 0))
+ ++losing;
+ else
+ {
+ for (s = opcode->m_operands, opP = &the_ins.operands[0];
+ *s && !losing;
+ s += 2, opP++)
+ {
+ /* Warning: this switch is huge! */
+ /* I've tried to organize the cases into this order:
+ non-alpha first, then alpha by letter. Lower-case
+ goes directly before uppercase counterpart. */
+ /* Code with multiple case ...: gets sorted by the lowest
+ case ... it belongs to. I hope this makes sense. */
+ switch (*s)
+ {
+ case '!':
+ switch (opP->mode)
+ {
+ case IMMED:
+ case DREG:
+ case AREG:
+ case FPREG:
+ case CONTROL:
+ case AINC:
+ case ADEC:
+ case REGLST:
+ losing++;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case '<':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AREG:
+ case FPREG:
+ case CONTROL:
+ case IMMED:
+ case ADEC:
+ case REGLST:
+ losing++;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case '>':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AREG:
+ case FPREG:
+ case CONTROL:
+ case IMMED:
+ case AINC:
+ case REGLST:
+ losing++;
+ break;
+ case ABSL:
+ break;
+ default:
+ if (opP->reg == PC
+ || opP->reg == ZPC)
+ losing++;
+ break;
+ }
+ break;
+
+ case 'm':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AREG:
+ case AINDR:
+ case AINC:
+ case ADEC:
+ break;
+ default:
+ losing++;
+ }
+ break;
+
+ case 'n':
+ switch (opP->mode)
+ {
+ case DISP:
+ break;
+ default:
+ losing++;
+ }
+ break;
+
+ case 'o':
+ switch (opP->mode)
+ {
+ case BASE:
+ case ABSL:
+ case IMMED:
+ break;
+ default:
+ losing++;
+ }
+ break;
+
+ case 'p':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AREG:
+ case AINDR:
+ case AINC:
+ case ADEC:
+ break;
+ case DISP:
+ if (opP->reg == PC || opP->reg == ZPC)
+ losing++;
+ break;
+ default:
+ losing++;
+ }
+ break;
+
+ case 'q':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AINDR:
+ case AINC:
+ case ADEC:
+ break;
+ case DISP:
+ if (opP->reg == PC || opP->reg == ZPC)
+ losing++;
+ break;
+ default:
+ losing++;
+ break;
+ }
+ break;
+
+ case 'v':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AINDR:
+ case AINC:
+ case ADEC:
+ case ABSL:
+ break;
+ case DISP:
+ if (opP->reg == PC || opP->reg == ZPC)
+ losing++;
+ break;
+ default:
+ losing++;
+ break;
+ }
+ break;
+
+ case '#':
+ if (opP->mode != IMMED)
+ losing++;
+ else if (s[1] == 'b'
+ && ! isvar (&opP->disp)
+ && (opP->disp.exp.X_op != O_constant
+ || ! isbyte (opP->disp.exp.X_add_number)))
+ losing++;
+ else if (s[1] == 'B'
+ && ! isvar (&opP->disp)
+ && (opP->disp.exp.X_op != O_constant
+ || ! issbyte (opP->disp.exp.X_add_number)))
+ losing++;
+ else if (s[1] == 'w'
+ && ! isvar (&opP->disp)
+ && (opP->disp.exp.X_op != O_constant
+ || ! isword (opP->disp.exp.X_add_number)))
+ losing++;
+ else if (s[1] == 'W'
+ && ! isvar (&opP->disp)
+ && (opP->disp.exp.X_op != O_constant
+ || ! issword (opP->disp.exp.X_add_number)))
+ losing++;
+ break;
+
+ case '^':
+ case 'T':
+ if (opP->mode != IMMED)
+ losing++;
+ break;
+
+ case '$':
+ if (opP->mode == AREG
+ || opP->mode == CONTROL
+ || opP->mode == FPREG
+ || opP->mode == IMMED
+ || opP->mode == REGLST
+ || (opP->mode != ABSL
+ && (opP->reg == PC
+ || opP->reg == ZPC)))
+ losing++;
+ break;
+
+ case '%':
+ if (opP->mode == CONTROL
+ || opP->mode == FPREG
+ || opP->mode == REGLST
+ || opP->mode == IMMED
+ || (opP->mode != ABSL
+ && (opP->reg == PC
+ || opP->reg == ZPC)))
+ losing++;
+ break;
+
+ case '&':
+ switch (opP->mode)
+ {
+ case DREG:
+ case AREG:
+ case FPREG:
+ case CONTROL:
+ case IMMED:
+ case AINC:
+ case ADEC:
+ case REGLST:
+ losing++;
+ break;
+ case ABSL:
+ break;
+ default:
+ if (opP->reg == PC
+ || opP->reg == ZPC)
+ losing++;
+ break;
+ }
+ break;
+
+ case '*':
+ if (opP->mode == CONTROL
+ || opP->mode == FPREG
+ || opP->mode == REGLST)
+ losing++;
+ break;
+
+ case '+':
+ if (opP->mode != AINC)
+ losing++;
+ break;
+
+ case '-':
+ if (opP->mode != ADEC)
+ losing++;
+ break;
+
+ case '/':
+ switch (opP->mode)
+ {
+ case AREG:
+ case CONTROL:
+ case FPREG:
+ case AINC:
+ case ADEC:
+ case IMMED:
+ case REGLST:
+ losing++;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case ';':
+ switch (opP->mode)
+ {
+ case AREG:
+ case CONTROL:
+ case FPREG:
+ case REGLST:
+ losing++;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case '?':
+ switch (opP->mode)
+ {
+ case AREG:
+ case CONTROL:
+ case FPREG:
+ case AINC:
+ case ADEC:
+ case IMMED:
+ case REGLST:
+ losing++;
+ break;
+ case ABSL:
+ break;
+ default:
+ if (opP->reg == PC || opP->reg == ZPC)
+ losing++;
+ break;
+ }
+ break;
+
+ case '@':
+ switch (opP->mode)
+ {
+ case AREG:
+ case CONTROL:
+ case FPREG:
+ case IMMED:
+ case REGLST:
+ losing++;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case '~': /* For now! (JF FOO is this right?) */
+ switch (opP->mode)
+ {
+ case DREG:
+ case AREG:
+ case CONTROL:
+ case FPREG:
+ case IMMED:
+ case REGLST:
+ losing++;
+ break;
+ case ABSL:
+ break;
+ default:
+ if (opP->reg == PC
+ || opP->reg == ZPC)
+ losing++;
+ break;
+ }
+ break;
+
+ case '3':
+ if (opP->mode != CONTROL
+ || (opP->reg != TT0 && opP->reg != TT1))
+ losing++;
+ break;
+
+ case 'A':
+ if (opP->mode != AREG)
+ losing++;
+ break;
+
+ case 'a':
+ if (opP->mode != AINDR)
+ ++losing;
+ break;
+
+ case 'B': /* FOO */
+ if (opP->mode != ABSL
+ || (flag_long_jumps
+ && strncmp (instring, "jbsr", 4) == 0))
+ losing++;
+ break;
+
+ case 'C':
+ if (opP->mode != CONTROL || opP->reg != CCR)
+ losing++;
+ break;
+
+ case 'd':
+ if (opP->mode != DISP
+ || opP->reg < ADDR0
+ || opP->reg > ADDR7)
+ losing++;
+ break;
+
+ case 'D':
+ if (opP->mode != DREG)
+ losing++;
+ break;
+
+ case 'F':
+ if (opP->mode != FPREG)
+ losing++;
+ break;
+
+ case 'I':
+ if (opP->mode != CONTROL
+ || opP->reg < COP0
+ || opP->reg > COP7)
+ losing++;
+ break;
+
+ case 'J':
+ if (opP->mode != CONTROL
+ || opP->reg < USP
+ || opP->reg > last_movec_reg)
+ losing++;
+ else
+ {
+ const enum m68k_register *rp;
+ for (rp = control_regs; *rp; rp++)
+ if (*rp == opP->reg)
+ break;
+ if (*rp == 0)
+ losing++;
+ }
+ break;
+
+ case 'k':
+ if (opP->mode != IMMED)
+ losing++;
+ break;
+
+ case 'l':
+ case 'L':
+ if (opP->mode == DREG
+ || opP->mode == AREG
+ || opP->mode == FPREG)
+ {
+ if (s[1] == '8')
+ losing++;
+ else
+ {
+ switch (opP->mode)
+ {
+ case DREG:
+ opP->mask = 1 << (opP->reg - DATA0);
+ break;
+ case AREG:
+ opP->mask = 1 << (opP->reg - ADDR0 + 8);
+ break;
+ case FPREG:
+ opP->mask = 1 << (opP->reg - FP0 + 16);
+ break;
+ default:
+ abort ();
+ }
+ opP->mode = REGLST;
+ }
+ }
+ else if (opP->mode == CONTROL)
+ {
+ if (s[1] != '8')
+ losing++;
+ else
+ {
+ switch (opP->reg)
+ {
+ case FPI:
+ opP->mask = 1 << 24;
+ break;
+ case FPS:
+ opP->mask = 1 << 25;
+ break;
+ case FPC:
+ opP->mask = 1 << 26;
+ break;
+ default:
+ losing++;
+ break;
+ }
+ opP->mode = REGLST;
+ }
+ }
+ else if (opP->mode != REGLST)
+ losing++;
+ else if (s[1] == '8' && (opP->mask & 0x0ffffff) != 0)
+ losing++;
+ else if (s[1] == '3' && (opP->mask & 0x7000000) != 0)
+ losing++;
+ break;
+
+ case 'M':
+ if (opP->mode != IMMED)
+ losing++;
+ else if (opP->disp.exp.X_op != O_constant
+ || ! issbyte (opP->disp.exp.X_add_number))
+ losing++;
+ else if (! m68k_quick
+ && instring[3] != 'q'
+ && instring[4] != 'q')
+ losing++;
+ break;
+
+ case 'O':
+ if (opP->mode != DREG
+ && opP->mode != IMMED
+ && opP->mode != ABSL)
+ losing++;
+ break;
+
+ case 'Q':
+ if (opP->mode != IMMED)
+ losing++;
+ else if (opP->disp.exp.X_op != O_constant
+ || opP->disp.exp.X_add_number < 1
+ || opP->disp.exp.X_add_number > 8)
+ losing++;
+ else if (! m68k_quick
+ && (strncmp (instring, "add", 3) == 0
+ || strncmp (instring, "sub", 3) == 0)
+ && instring[3] != 'q')
+ losing++;
+ break;
+
+ case 'R':
+ if (opP->mode != DREG && opP->mode != AREG)
+ losing++;
+ break;
+
+ case 'r':
+ if (opP->mode != AINDR
+ && (opP->mode != BASE
+ || (opP->reg != 0
+ && opP->reg != ZADDR0)
+ || opP->disp.exp.X_op != O_absent
+ || ((opP->index.reg < DATA0
+ || opP->index.reg > DATA7)
+ && (opP->index.reg < ADDR0
+ || opP->index.reg > ADDR7))
+ || opP->index.size != SIZE_UNSPEC
+ || opP->index.scale != 1))
+ losing++;
+ break;
+
+ case 's':
+ if (opP->mode != CONTROL
+ || ! (opP->reg == FPI
+ || opP->reg == FPS
+ || opP->reg == FPC))
+ losing++;
+ break;
+
+ case 'S':
+ if (opP->mode != CONTROL || opP->reg != SR)
+ losing++;
+ break;
+
+ case 't':
+ if (opP->mode != IMMED)
+ losing++;
+ else if (opP->disp.exp.X_op != O_constant
+ || opP->disp.exp.X_add_number < 0
+ || opP->disp.exp.X_add_number > 7)
+ losing++;
+ break;
+
+ case 'U':
+ if (opP->mode != CONTROL || opP->reg != USP)
+ losing++;
+ break;
+
+ /* JF these are out of order. We could put them
+ in order if we were willing to put up with
+ bunches of #ifdef m68851s in the code.
+
+ Don't forget that you need these operands
+ to use 68030 MMU instructions. */
+#ifndef NO_68851
+ /* Memory addressing mode used by pflushr */
+ case '|':
+ if (opP->mode == CONTROL
+ || opP->mode == FPREG
+ || opP->mode == DREG
+ || opP->mode == AREG
+ || opP->mode == REGLST)
+ losing++;
+ /* We should accept immediate operands, but they
+ supposedly have to be quad word, and we don't
+ handle that. I would like to see what a Motorola
+ assembler does before doing something here. */
+ if (opP->mode == IMMED)
+ losing++;
+ break;
+
+ case 'f':
+ if (opP->mode != CONTROL
+ || (opP->reg != SFC && opP->reg != DFC))
+ losing++;
+ break;
+
+ case '0':
+ if (opP->mode != CONTROL || opP->reg != TC)
+ losing++;
+ break;
+
+ case '1':
+ if (opP->mode != CONTROL || opP->reg != AC)
+ losing++;
+ break;
+
+ case '2':
+ if (opP->mode != CONTROL
+ || (opP->reg != CAL
+ && opP->reg != VAL
+ && opP->reg != SCC))
+ losing++;
+ break;
+
+ case 'V':
+ if (opP->mode != CONTROL
+ || opP->reg != VAL)
+ losing++;
+ break;
+
+ case 'W':
+ if (opP->mode != CONTROL
+ || (opP->reg != DRP
+ && opP->reg != SRP
+ && opP->reg != CRP))
+ losing++;
+ break;
+
+ case 'X':
+ if (opP->mode != CONTROL
+ || (!(opP->reg >= BAD && opP->reg <= BAD + 7)
+ && !(opP->reg >= BAC && opP->reg <= BAC + 7)))
+ losing++;
+ break;
+
+ case 'Y':
+ if (opP->mode != CONTROL || opP->reg != PSR)
+ losing++;
+ break;
+
+ case 'Z':
+ if (opP->mode != CONTROL || opP->reg != PCSR)
+ losing++;
+ break;
+#endif
+ case 'c':
+ if (opP->mode != CONTROL
+ || (opP->reg != NC
+ && opP->reg != IC
+ && opP->reg != DC
+ && opP->reg != BC))
+ {
+ losing++;
+ } /* not a cache specifier. */
+ break;
+
+ case '_':
+ if (opP->mode != ABSL)
+ ++losing;
+ break;
+
+ default:
+ abort ();
+ } /* switch on type of operand */
+
+ if (losing)
+ break;
+ } /* for each operand */
+ } /* if immediately wrong */
+
+ if (!losing)
+ {
+ break;
+ } /* got it. */
+
+ opcode = opcode->m_next;
+
+ if (!opcode)
+ {
+ if (ok_arch
+ && !(ok_arch & current_architecture))
+ {
+ char buf[200], *cp;
+
+ strcpy (buf,
+ _("invalid instruction for this architecture; needs "));
+ cp = buf + strlen (buf);
+ switch (ok_arch)
+ {
+ case mfloat:
+ strcpy (cp, _("fpu (68040, 68060 or 68881/68882)"));
+ break;
+ case mmmu:
+ strcpy (cp, _("mmu (68030 or 68851)"));
+ break;
+ case m68020up:
+ strcpy (cp, _("68020 or higher"));
+ break;
+ case m68000up:
+ strcpy (cp, _("68000 or higher"));
+ break;
+ case m68010up:
+ strcpy (cp, _("68010 or higher"));
+ break;
+ default:
+ {
+ int got_one = 0, idx;
+ for (idx = 0; idx < sizeof (archs) / sizeof (archs[0]);
+ idx++)
+ {
+ if ((archs[idx].arch & ok_arch)
+ && ! archs[idx].alias)
+ {
+ if (got_one)
+ {
+ strcpy (cp, " or ");
+ cp += strlen (cp);
+ }
+ got_one = 1;
+ strcpy (cp, archs[idx].name);
+ cp += strlen (cp);
+ }
+ }
+ }
+ }
+ cp = xmalloc (strlen (buf) + 1);
+ strcpy (cp, buf);
+ the_ins.error = cp;
+ }
+ else
+ the_ins.error = _("operands mismatch");
+ return;
+ } /* Fell off the end */
+
+ losing = 0;
+ }
+
+ /* now assemble it */
+
+ the_ins.args = opcode->m_operands;
+ the_ins.numargs = opcode->m_opnum;
+ the_ins.numo = opcode->m_codenum;
+ the_ins.opcode[0] = getone (opcode);
+ the_ins.opcode[1] = gettwo (opcode);
+
+ for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++)
+ {
+ /* This switch is a doozy.
+ Watch the first step; its a big one! */
+ switch (s[0])
+ {
+
+ case '*':
+ case '~':
+ case '%':
+ case ';':
+ case '@':
+ case '!':
+ case '&':
+ case '$':
+ case '?':
+ case '/':
+ case '<':
+ case '>':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'v':
+#ifndef NO_68851
+ case '|':
+#endif
+ switch (opP->mode)
+ {
+ case IMMED:
+ tmpreg = 0x3c; /* 7.4 */
+ if (strchr ("bwl", s[1]))
+ nextword = get_num (&opP->disp, 80);
+ else
+ nextword = get_num (&opP->disp, 0);
+ if (isvar (&opP->disp))
+ add_fix (s[1], &opP->disp, 0, 0);
+ switch (s[1])
+ {
+ case 'b':
+ if (!isbyte (nextword))
+ opP->error = _("operand out of range");
+ addword (nextword);
+ baseo = 0;
+ break;
+ case 'w':
+ if (!isword (nextword))
+ opP->error = _("operand out of range");
+ addword (nextword);
+ baseo = 0;
+ break;
+ case 'W':
+ if (!issword (nextword))
+ opP->error = _("operand out of range");
+ addword (nextword);
+ baseo = 0;
+ break;
+ case 'l':
+ addword (nextword >> 16);
+ addword (nextword);
+ baseo = 0;
+ break;
+
+ case 'f':
+ baseo = 2;
+ outro = 8;
+ break;
+ case 'F':
+ baseo = 4;
+ outro = 11;
+ break;
+ case 'x':
+ baseo = 6;
+ outro = 15;
+ break;
+ case 'p':
+ baseo = 6;
+ outro = -1;
+ break;
+ default:
+ abort ();
+ }
+ if (!baseo)
+ break;
+
+ /* We gotta put out some float */
+ if (op (&opP->disp) != O_big)
+ {
+ valueT val;
+ int gencnt;
+
+ /* Can other cases happen here? */
+ if (op (&opP->disp) != O_constant)
+ abort ();
+
+ val = (valueT) offs (&opP->disp);
+ gencnt = 0;
+ do
+ {
+ generic_bignum[gencnt] = (LITTLENUM_TYPE) val;
+ val >>= LITTLENUM_NUMBER_OF_BITS;
+ ++gencnt;
+ }
+ while (val != 0);
+ offs (&opP->disp) = gencnt;
+ }
+ if (offs (&opP->disp) > 0)
+ {
+ if (offs (&opP->disp) > baseo)
+ {
+ as_warn (_("Bignum too big for %c format; truncated"),
+ s[1]);
+ offs (&opP->disp) = baseo;
+ }
+ baseo -= offs (&opP->disp);
+ while (baseo--)
+ addword (0);
+ for (wordp = generic_bignum + offs (&opP->disp) - 1;
+ offs (&opP->disp)--;
+ --wordp)
+ addword (*wordp);
+ break;
+ }
+ gen_to_words (words, baseo, (long) outro);
+ for (wordp = words; baseo--; wordp++)
+ addword (*wordp);
+ break;
+ case DREG:
+ tmpreg = opP->reg - DATA; /* 0.dreg */
+ break;
+ case AREG:
+ tmpreg = 0x08 + opP->reg - ADDR; /* 1.areg */
+ break;
+ case AINDR:
+ tmpreg = 0x10 + opP->reg - ADDR; /* 2.areg */
+ break;
+ case ADEC:
+ tmpreg = 0x20 + opP->reg - ADDR; /* 4.areg */
+ break;
+ case AINC:
+ tmpreg = 0x18 + opP->reg - ADDR; /* 3.areg */
+ break;
+ case DISP:
+
+ nextword = get_num (&opP->disp, 80);
+
+ if (opP->reg == PC
+ && ! isvar (&opP->disp)
+ && m68k_abspcadd)
+ {
+ opP->disp.exp.X_op = O_symbol;
+#ifndef BFD_ASSEMBLER
+ opP->disp.exp.X_add_symbol = &abs_symbol;
+#else
+ opP->disp.exp.X_add_symbol =
+ section_symbol (absolute_section);
+#endif
+ }
+
+ /* Force into index mode. Hope this works */
+
+ /* We do the first bit for 32-bit displacements, and the
+ second bit for 16 bit ones. It is possible that we
+ should make the default be WORD instead of LONG, but
+ I think that'd break GCC, so we put up with a little
+ inefficiency for the sake of working output. */
+
+ if (!issword (nextword)
+ || (isvar (&opP->disp)
+ && ((opP->disp.size == SIZE_UNSPEC
+ && flag_short_refs == 0
+ && cpu_of_arch (current_architecture) >= m68020
+ && cpu_of_arch (current_architecture) != mcf5200)
+ || opP->disp.size == SIZE_LONG)))
+ {
+ if (cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200)
+ opP->error =
+ _("displacement too large for this architecture; needs 68020 or higher");
+ if (opP->reg == PC)
+ tmpreg = 0x3B; /* 7.3 */
+ else
+ tmpreg = 0x30 + opP->reg - ADDR; /* 6.areg */
+ if (isvar (&opP->disp))
+ {
+ if (opP->reg == PC)
+ {
+ if (opP->disp.size == SIZE_LONG
+#ifdef OBJ_ELF
+ /* If the displacement needs pic
+ relocation it cannot be relaxed. */
+ || opP->disp.pic_reloc != pic_none
+#endif
+ )
+ {
+ addword (0x0170);
+ add_fix ('l', &opP->disp, 1, 2);
+ }
+ else
+ {
+ add_frag (adds (&opP->disp),
+ offs (&opP->disp),
+ TAB (PCLEA, SZ_UNDEF));
+ break;
+ }
+ }
+ else
+ {
+ addword (0x0170);
+ add_fix ('l', &opP->disp, 0, 0);
+ }
+ }
+ else
+ addword (0x0170);
+ addword (nextword >> 16);
+ }
+ else
+ {
+ if (opP->reg == PC)
+ tmpreg = 0x3A; /* 7.2 */
+ else
+ tmpreg = 0x28 + opP->reg - ADDR; /* 5.areg */
+
+ if (isvar (&opP->disp))
+ {
+ if (opP->reg == PC)
+ {
+ add_fix ('w', &opP->disp, 1, 0);
+ }
+ else
+ add_fix ('w', &opP->disp, 0, 0);
+ }
+ }
+ addword (nextword);
+ break;
+
+ case POST:
+ case PRE:
+ case BASE:
+ nextword = 0;
+ baseo = get_num (&opP->disp, 80);
+ if (opP->mode == POST || opP->mode == PRE)
+ outro = get_num (&opP->odisp, 80);
+ /* Figure out the `addressing mode'.
+ Also turn on the BASE_DISABLE bit, if needed. */
+ if (opP->reg == PC || opP->reg == ZPC)
+ {
+ tmpreg = 0x3b; /* 7.3 */
+ if (opP->reg == ZPC)
+ nextword |= 0x80;
+ }
+ else if (opP->reg == 0)
+ {
+ nextword |= 0x80;
+ tmpreg = 0x30; /* 6.garbage */
+ }
+ else if (opP->reg >= ZADDR0 && opP->reg <= ZADDR7)
+ {
+ nextword |= 0x80;
+ tmpreg = 0x30 + opP->reg - ZADDR0;
+ }
+ else
+ tmpreg = 0x30 + opP->reg - ADDR; /* 6.areg */
+
+ siz1 = opP->disp.size;
+ if (opP->mode == POST || opP->mode == PRE)
+ siz2 = opP->odisp.size;
+ else
+ siz2 = SIZE_UNSPEC;
+
+ /* Index register stuff */
+ if (opP->index.reg != 0
+ && opP->index.reg >= DATA
+ && opP->index.reg <= ADDR7)
+ {
+ nextword |= (opP->index.reg - DATA) << 12;
+
+ if (opP->index.size == SIZE_LONG
+ || (opP->index.size == SIZE_UNSPEC
+ && m68k_index_width_default == SIZE_LONG))
+ nextword |= 0x800;
+
+ if ((opP->index.scale != 1
+ && cpu_of_arch (current_architecture) < m68020)
+ || (opP->index.scale == 8
+ && current_architecture == mcf5200))
+ {
+ opP->error =
+ _("scale factor invalid on this architecture; needs cpu32 or 68020 or higher");
+ }
+
+ switch (opP->index.scale)
+ {
+ case 1:
+ break;
+ case 2:
+ nextword |= 0x200;
+ break;
+ case 4:
+ nextword |= 0x400;
+ break;
+ case 8:
+ nextword |= 0x600;
+ break;
+ default:
+ abort ();
+ }
+ /* IF its simple,
+ GET US OUT OF HERE! */
+
+ /* Must be INDEX, with an index register. Address
+ register cannot be ZERO-PC, and either :b was
+ forced, or we know it will fit. For a 68000 or
+ 68010, force this mode anyways, because the
+ larger modes aren't supported. */
+ if (opP->mode == BASE
+ && ((opP->reg >= ADDR0
+ && opP->reg <= ADDR7)
+ || opP->reg == PC))
+ {
+ if (siz1 == SIZE_BYTE
+ || cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200
+ || (siz1 == SIZE_UNSPEC
+ && ! isvar (&opP->disp)
+ && issbyte (baseo)))
+ {
+ nextword += baseo & 0xff;
+ addword (nextword);
+ if (isvar (&opP->disp))
+ {
+ /* Do a byte relocation. If it doesn't
+ fit (possible on m68000) let the
+ fixup processing complain later. */
+ if (opP->reg == PC)
+ add_fix ('B', &opP->disp, 1, 1);
+ else
+ add_fix ('B', &opP->disp, 0, 0);
+ }
+ else if (siz1 != SIZE_BYTE)
+ {
+ if (siz1 != SIZE_UNSPEC)
+ as_warn (_("Forcing byte displacement"));
+ if (! issbyte (baseo))
+ opP->error = _("byte displacement out of range");
+ }
+
+ break;
+ }
+ else if (siz1 == SIZE_UNSPEC
+ && opP->reg == PC
+ && isvar (&opP->disp)
+ && subs (&opP->disp) == NULL
+#ifdef OBJ_ELF
+ /* If the displacement needs pic
+ relocation it cannot be relaxed. */
+ && opP->disp.pic_reloc == pic_none
+#endif
+ )
+ {
+ /* The code in md_convert_frag_1 needs to be
+ able to adjust nextword. Call frag_grow
+ to ensure that we have enough space in
+ the frag obstack to make all the bytes
+ contiguous. */
+ frag_grow (14);
+ nextword += baseo & 0xff;
+ addword (nextword);
+ add_frag (adds (&opP->disp), offs (&opP->disp),
+ TAB (PCINDEX, SZ_UNDEF));
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ nextword |= 0x40; /* No index reg */
+ if (opP->index.reg >= ZDATA0
+ && opP->index.reg <= ZDATA7)
+ nextword |= (opP->index.reg - ZDATA0) << 12;
+ else if (opP->index.reg >= ZADDR0
+ || opP->index.reg <= ZADDR7)
+ nextword |= (opP->index.reg - ZADDR0 + 8) << 12;
+ }
+
+ /* It isn't simple. */
+
+ if (cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200)
+ opP->error =
+ _("invalid operand mode for this architecture; needs 68020 or higher");
+
+ nextword |= 0x100;
+ /* If the guy specified a width, we assume that it is
+ wide enough. Maybe it isn't. If so, we lose. */
+ switch (siz1)
+ {
+ case SIZE_UNSPEC:
+ if (isvar (&opP->disp)
+ ? m68k_rel32
+ : ! issword (baseo))
+ {
+ siz1 = SIZE_LONG;
+ nextword |= 0x30;
+ }
+ else if (! isvar (&opP->disp) && baseo == 0)
+ nextword |= 0x10;
+ else
+ {
+ nextword |= 0x20;
+ siz1 = SIZE_WORD;
+ }
+ break;
+ case SIZE_BYTE:
+ as_warn (_(":b not permitted; defaulting to :w"));
+ /* Fall through. */
+ case SIZE_WORD:
+ nextword |= 0x20;
+ break;
+ case SIZE_LONG:
+ nextword |= 0x30;
+ break;
+ }
+
+ /* Figure out innner displacement stuff */
+ if (opP->mode == POST || opP->mode == PRE)
+ {
+ if (cpu_of_arch (current_architecture) & cpu32)
+ opP->error = _("invalid operand mode for this architecture; needs 68020 or higher");
+ switch (siz2)
+ {
+ case SIZE_UNSPEC:
+ if (isvar (&opP->odisp)
+ ? m68k_rel32
+ : ! issword (outro))
+ {
+ siz2 = SIZE_LONG;
+ nextword |= 0x3;
+ }
+ else if (! isvar (&opP->odisp) && outro == 0)
+ nextword |= 0x1;
+ else
+ {
+ nextword |= 0x2;
+ siz2 = SIZE_WORD;
+ }
+ break;
+ case 1:
+ as_warn (_(":b not permitted; defaulting to :w"));
+ /* Fall through. */
+ case 2:
+ nextword |= 0x2;
+ break;
+ case 3:
+ nextword |= 0x3;
+ break;
+ }
+ if (opP->mode == POST
+ && (nextword & 0x40) == 0)
+ nextword |= 0x04;
+ }
+ addword (nextword);
+
+ if (siz1 != SIZE_UNSPEC && isvar (&opP->disp))
+ {
+ if (opP->reg == PC || opP->reg == ZPC)
+ add_fix (siz1 == SIZE_LONG ? 'l' : 'w', &opP->disp, 1, 2);
+ else
+ add_fix (siz1 == SIZE_LONG ? 'l' : 'w', &opP->disp, 0, 0);
+ }
+ if (siz1 == SIZE_LONG)
+ addword (baseo >> 16);
+ if (siz1 != SIZE_UNSPEC)
+ addword (baseo);
+
+ if (siz2 != SIZE_UNSPEC && isvar (&opP->odisp))
+ add_fix (siz2 == SIZE_LONG ? 'l' : 'w', &opP->odisp, 0, 0);
+ if (siz2 == SIZE_LONG)
+ addword (outro >> 16);
+ if (siz2 != SIZE_UNSPEC)
+ addword (outro);
+
+ break;
+
+ case ABSL:
+ nextword = get_num (&opP->disp, 80);
+ switch (opP->disp.size)
+ {
+ default:
+ abort ();
+ case SIZE_UNSPEC:
+ if (!isvar (&opP->disp) && issword (offs (&opP->disp)))
+ {
+ tmpreg = 0x38; /* 7.0 */
+ addword (nextword);
+ break;
+ }
+ /* Don't generate pc relative code on 68010 and
+ 68000. */
+ if (isvar (&opP->disp)
+ && !subs (&opP->disp)
+ && adds (&opP->disp)
+#ifdef OBJ_ELF
+ /* If the displacement needs pic relocation it
+ cannot be relaxed. */
+ && opP->disp.pic_reloc == pic_none
+#endif
+ && S_GET_SEGMENT (adds (&opP->disp)) == now_seg
+ && relaxable_symbol (adds (&opP->disp))
+ && HAVE_LONG_BRANCH(current_architecture)
+ && !flag_long_jumps
+ && !strchr ("~%&$?", s[0]))
+ {
+ tmpreg = 0x3A; /* 7.2 */
+ add_frag (adds (&opP->disp),
+ offs (&opP->disp),
+ TAB (PCREL, SZ_UNDEF));
+ break;
+ }
+ /* Fall through into long */
+ case SIZE_LONG:
+ if (isvar (&opP->disp))
+ add_fix ('l', &opP->disp, 0, 0);
+
+ tmpreg = 0x39;/* 7.1 mode */
+ addword (nextword >> 16);
+ addword (nextword);
+ break;
+
+ case SIZE_BYTE:
+ as_bad (_("unsupported byte value; use a different suffix"));
+ /* Fall through. */
+ case SIZE_WORD: /* Word */
+ if (isvar (&opP->disp))
+ add_fix ('w', &opP->disp, 0, 0);
+
+ tmpreg = 0x38;/* 7.0 mode */
+ addword (nextword);
+ break;
+ }
+ break;
+ case CONTROL:
+ case FPREG:
+ default:
+ as_bad (_("unknown/incorrect operand"));
+ /* abort(); */
+ }
+ install_gen_operand (s[1], tmpreg);
+ break;
+
+ case '#':
+ case '^':
+ switch (s[1])
+ { /* JF: I hate floating point! */
+ case 'j':
+ tmpreg = 70;
+ break;
+ case '8':
+ tmpreg = 20;
+ break;
+ case 'C':
+ tmpreg = 50;
+ break;
+ case '3':
+ default:
+ tmpreg = 80;
+ break;
+ }
+ tmpreg = get_num (&opP->disp, tmpreg);
+ if (isvar (&opP->disp))
+ add_fix (s[1], &opP->disp, 0, 0);
+ switch (s[1])
+ {
+ case 'b': /* Danger: These do no check for
+ certain types of overflow.
+ user beware! */
+ if (!isbyte (tmpreg))
+ opP->error = _("out of range");
+ insop (tmpreg, opcode);
+ if (isvar (&opP->disp))
+ the_ins.reloc[the_ins.nrel - 1].n =
+ (opcode->m_codenum) * 2 + 1;
+ break;
+ case 'B':
+ if (!issbyte (tmpreg))
+ opP->error = _("out of range");
+ the_ins.opcode[the_ins.numo - 1] |= tmpreg & 0xff;
+ if (isvar (&opP->disp))
+ the_ins.reloc[the_ins.nrel - 1].n = opcode->m_codenum * 2 - 1;
+ break;
+ case 'w':
+ if (!isword (tmpreg))
+ opP->error = _("out of range");
+ insop (tmpreg, opcode);
+ if (isvar (&opP->disp))
+ the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2;
+ break;
+ case 'W':
+ if (!issword (tmpreg))
+ opP->error = _("out of range");
+ insop (tmpreg, opcode);
+ if (isvar (&opP->disp))
+ the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2;
+ break;
+ case 'l':
+ /* Because of the way insop works, we put these two out
+ backwards. */
+ insop (tmpreg, opcode);
+ insop (tmpreg >> 16, opcode);
+ if (isvar (&opP->disp))
+ the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2;
+ break;
+ case '3':
+ tmpreg &= 0xFF;
+ case '8':
+ case 'C':
+ case 'j':
+ install_operand (s[1], tmpreg);
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ case '+':
+ case '-':
+ case 'A':
+ case 'a':
+ install_operand (s[1], opP->reg - ADDR);
+ break;
+
+ case 'B':
+ tmpreg = get_num (&opP->disp, 80);
+ switch (s[1])
+ {
+ case 'B':
+ /* The pc_fix argument winds up in fx_pcrel_adjust,
+ which is a char, and may therefore be unsigned. We
+ want to pass -1, but we pass 64 instead, and convert
+ back in md_pcrel_from. */
+ add_fix ('B', &opP->disp, 1, 64);
+ break;
+ case 'W':
+ add_fix ('w', &opP->disp, 1, 0);
+ addword (0);
+ break;
+ case 'L':
+ long_branch:
+ if (!HAVE_LONG_BRANCH(current_architecture))
+ as_warn (_("Can't use long branches on 68000/68010/5200"));
+ the_ins.opcode[the_ins.numo - 1] |= 0xff;
+ add_fix ('l', &opP->disp, 1, 0);
+ addword (0);
+ addword (0);
+ break;
+ case 'g':
+ if (subs (&opP->disp)) /* We can't relax it */
+ goto long_branch;
+
+#ifdef OBJ_ELF
+ /* If the displacement needs pic relocation it cannot be
+ relaxed. */
+ if (opP->disp.pic_reloc != pic_none)
+ goto long_branch;
+#endif
+
+ /* This could either be a symbol, or an absolute
+ address. No matter, the frag hacking will finger it
+ out. Not quite: it can't switch from BRANCH to
+ BCC68000 for the case where opnd is absolute (it
+ needs to use the 68000 hack since no conditional abs
+ jumps). */
+ if (( !HAVE_LONG_BRANCH(current_architecture)
+ || (0 == adds (&opP->disp)))
+ && (the_ins.opcode[0] >= 0x6200)
+ && (the_ins.opcode[0] <= 0x6f00))
+ add_frag (adds (&opP->disp), offs (&opP->disp),
+ TAB (BCC68000, SZ_UNDEF));
+ else
+ add_frag (adds (&opP->disp), offs (&opP->disp),
+ TAB (ABRANCH, SZ_UNDEF));
+ break;
+ case 'w':
+ if (isvar (&opP->disp))
+ {
+#if 1
+ /* check for DBcc instruction */
+ if ((the_ins.opcode[0] & 0xf0f8) == 0x50c8)
+ {
+ /* size varies if patch */
+ /* needed for long form */
+ add_frag (adds (&opP->disp), offs (&opP->disp),
+ TAB (DBCC, SZ_UNDEF));
+ break;
+ }
+#endif
+ add_fix ('w', &opP->disp, 1, 0);
+ }
+ addword (0);
+ break;
+ case 'C': /* Fixed size LONG coproc branches */
+ add_fix ('l', &opP->disp, 1, 0);
+ addword (0);
+ addword (0);
+ break;
+ case 'c': /* Var size Coprocesssor branches */
+ if (subs (&opP->disp))
+ {
+ add_fix ('l', &opP->disp, 1, 0);
+ add_frag ((symbolS *) 0, (offsetT) 0, TAB (FBRANCH, LONG));
+ }
+ else if (adds (&opP->disp))
+ add_frag (adds (&opP->disp), offs (&opP->disp),
+ TAB (FBRANCH, SZ_UNDEF));
+ else
+ {
+ /* add_frag ((symbolS *) 0, offs (&opP->disp),
+ TAB(FBRANCH,SHORT)); */
+ the_ins.opcode[the_ins.numo - 1] |= 0x40;
+ add_fix ('l', &opP->disp, 1, 0);
+ addword (0);
+ addword (0);
+ }
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ case 'C': /* Ignore it */
+ break;
+
+ case 'd': /* JF this is a kludge */
+ install_operand ('s', opP->reg - ADDR);
+ tmpreg = get_num (&opP->disp, 80);
+ if (!issword (tmpreg))
+ {
+ as_warn (_("Expression out of range, using 0"));
+ tmpreg = 0;
+ }
+ addword (tmpreg);
+ break;
+
+ case 'D':
+ install_operand (s[1], opP->reg - DATA);
+ break;
+
+ case 'F':
+ install_operand (s[1], opP->reg - FP0);
+ break;
+
+ case 'I':
+ tmpreg = opP->reg - COP0;
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'J': /* JF foo */
+ switch (opP->reg)
+ {
+ case SFC:
+ tmpreg = 0x000;
+ break;
+ case DFC:
+ tmpreg = 0x001;
+ break;
+ case CACR:
+ tmpreg = 0x002;
+ break;
+ case TC:
+ tmpreg = 0x003;
+ break;
+ case ITT0:
+ tmpreg = 0x004;
+ break;
+ case ITT1:
+ tmpreg = 0x005;
+ break;
+ case DTT0:
+ tmpreg = 0x006;
+ break;
+ case DTT1:
+ tmpreg = 0x007;
+ break;
+ case BUSCR:
+ tmpreg = 0x008;
+ break;
+
+ case USP:
+ tmpreg = 0x800;
+ break;
+ case VBR:
+ tmpreg = 0x801;
+ break;
+ case CAAR:
+ tmpreg = 0x802;
+ break;
+ case MSP:
+ tmpreg = 0x803;
+ break;
+ case ISP:
+ tmpreg = 0x804;
+ break;
+ case MMUSR:
+ tmpreg = 0x805;
+ break;
+ case URP:
+ tmpreg = 0x806;
+ break;
+ case SRP:
+ tmpreg = 0x807;
+ break;
+ case PCR:
+ tmpreg = 0x808;
+ break;
+ case ROMBAR:
+ tmpreg = 0xC00;
+ break;
+ case RAMBAR0:
+ tmpreg = 0xC04;
+ break;
+ case RAMBAR1:
+ tmpreg = 0xC05;
+ break;
+ case MBAR:
+ tmpreg = 0xC0F;
+ break;
+ default:
+ abort ();
+ }
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'k':
+ tmpreg = get_num (&opP->disp, 55);
+ install_operand (s[1], tmpreg & 0x7f);
+ break;
+
+ case 'l':
+ tmpreg = opP->mask;
+ if (s[1] == 'w')
+ {
+ if (tmpreg & 0x7FF0000)
+ as_bad (_("Floating point register in register list"));
+ insop (reverse_16_bits (tmpreg), opcode);
+ }
+ else
+ {
+ if (tmpreg & 0x700FFFF)
+ as_bad (_("Wrong register in floating-point reglist"));
+ install_operand (s[1], reverse_8_bits (tmpreg >> 16));
+ }
+ break;
+
+ case 'L':
+ tmpreg = opP->mask;
+ if (s[1] == 'w')
+ {
+ if (tmpreg & 0x7FF0000)
+ as_bad (_("Floating point register in register list"));
+ insop (tmpreg, opcode);
+ }
+ else if (s[1] == '8')
+ {
+ if (tmpreg & 0x0FFFFFF)
+ as_bad (_("incorrect register in reglist"));
+ install_operand (s[1], tmpreg >> 24);
+ }
+ else
+ {
+ if (tmpreg & 0x700FFFF)
+ as_bad (_("wrong register in floating-point reglist"));
+ else
+ install_operand (s[1], tmpreg >> 16);
+ }
+ break;
+
+ case 'M':
+ install_operand (s[1], get_num (&opP->disp, 60));
+ break;
+
+ case 'O':
+ tmpreg = ((opP->mode == DREG)
+ ? 0x20 + opP->reg - DATA
+ : (get_num (&opP->disp, 40) & 0x1F));
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'Q':
+ tmpreg = get_num (&opP->disp, 10);
+ if (tmpreg == 8)
+ tmpreg = 0;
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'R':
+ /* This depends on the fact that ADDR registers are eight
+ more than their corresponding DATA regs, so the result
+ will have the ADDR_REG bit set */
+ install_operand (s[1], opP->reg - DATA);
+ break;
+
+ case 'r':
+ if (opP->mode == AINDR)
+ install_operand (s[1], opP->reg - DATA);
+ else
+ install_operand (s[1], opP->index.reg - DATA);
+ break;
+
+ case 's':
+ if (opP->reg == FPI)
+ tmpreg = 0x1;
+ else if (opP->reg == FPS)
+ tmpreg = 0x2;
+ else if (opP->reg == FPC)
+ tmpreg = 0x4;
+ else
+ abort ();
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'S': /* Ignore it */
+ break;
+
+ case 'T':
+ install_operand (s[1], get_num (&opP->disp, 30));
+ break;
+
+ case 'U': /* Ignore it */
+ break;
+
+ case 'c':
+ switch (opP->reg)
+ {
+ case NC:
+ tmpreg = 0;
+ break;
+ case DC:
+ tmpreg = 1;
+ break;
+ case IC:
+ tmpreg = 2;
+ break;
+ case BC:
+ tmpreg = 3;
+ break;
+ default:
+ as_fatal (_("failed sanity check"));
+ } /* switch on cache token */
+ install_operand (s[1], tmpreg);
+ break;
+#ifndef NO_68851
+ /* JF: These are out of order, I fear. */
+ case 'f':
+ switch (opP->reg)
+ {
+ case SFC:
+ tmpreg = 0;
+ break;
+ case DFC:
+ tmpreg = 1;
+ break;
+ default:
+ abort ();
+ }
+ install_operand (s[1], tmpreg);
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ switch (opP->reg)
+ {
+ case TC:
+ tmpreg = 0;
+ break;
+ case CAL:
+ tmpreg = 4;
+ break;
+ case VAL:
+ tmpreg = 5;
+ break;
+ case SCC:
+ tmpreg = 6;
+ break;
+ case AC:
+ tmpreg = 7;
+ break;
+ default:
+ abort ();
+ }
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'V':
+ if (opP->reg == VAL)
+ break;
+ abort ();
+
+ case 'W':
+ switch (opP->reg)
+ {
+ case DRP:
+ tmpreg = 1;
+ break;
+ case SRP:
+ tmpreg = 2;
+ break;
+ case CRP:
+ tmpreg = 3;
+ break;
+ default:
+ abort ();
+ }
+ install_operand (s[1], tmpreg);
+ break;
+
+ case 'X':
+ switch (opP->reg)
+ {
+ case BAD:
+ case BAD + 1:
+ case BAD + 2:
+ case BAD + 3:
+ case BAD + 4:
+ case BAD + 5:
+ case BAD + 6:
+ case BAD + 7:
+ tmpreg = (4 << 10) | ((opP->reg - BAD) << 2);
+ break;
+
+ case BAC:
+ case BAC + 1:
+ case BAC + 2:
+ case BAC + 3:
+ case BAC + 4:
+ case BAC + 5:
+ case BAC + 6:
+ case BAC + 7:
+ tmpreg = (5 << 10) | ((opP->reg - BAC) << 2);
+ break;
+
+ default:
+ abort ();
+ }
+ install_operand (s[1], tmpreg);
+ break;
+ case 'Y':
+ know (opP->reg == PSR);
+ break;
+ case 'Z':
+ know (opP->reg == PCSR);
+ break;
+#endif /* m68851 */
+ case '3':
+ switch (opP->reg)
+ {
+ case TT0:
+ tmpreg = 2;
+ break;
+ case TT1:
+ tmpreg = 3;
+ break;
+ default:
+ abort ();
+ }
+ install_operand (s[1], tmpreg);
+ break;
+ case 't':
+ tmpreg = get_num (&opP->disp, 20);
+ install_operand (s[1], tmpreg);
+ break;
+ case '_': /* used only for move16 absolute 32-bit address */
+ if (isvar (&opP->disp))
+ add_fix ('l', &opP->disp, 0, 0);
+ tmpreg = get_num (&opP->disp, 80);
+ addword (tmpreg >> 16);
+ addword (tmpreg & 0xFFFF);
+ break;
+ default:
+ abort ();
+ }
+ }
+
+ /* By the time whe get here (FINALLY) the_ins contains the complete
+ instruction, ready to be emitted. . . */
+}
+
+static int
+reverse_16_bits (in)
+ int in;
+{
+ int out = 0;
+ int n;
+
+ static int mask[16] =
+ {
+ 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000
+ };
+ for (n = 0; n < 16; n++)
+ {
+ if (in & mask[n])
+ out |= mask[15 - n];
+ }
+ return out;
+} /* reverse_16_bits() */
+
+static int
+reverse_8_bits (in)
+ int in;
+{
+ int out = 0;
+ int n;
+
+ static int mask[8] =
+ {
+ 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ };
+
+ for (n = 0; n < 8; n++)
+ {
+ if (in & mask[n])
+ out |= mask[7 - n];
+ }
+ return out;
+} /* reverse_8_bits() */
+
+/* Cause an extra frag to be generated here, inserting up to 10 bytes
+ (that value is chosen in the frag_var call in md_assemble). TYPE
+ is the subtype of the frag to be generated; its primary type is
+ rs_machine_dependent.
+
+ The TYPE parameter is also used by md_convert_frag_1 and
+ md_estimate_size_before_relax. The appropriate type of fixup will
+ be emitted by md_convert_frag_1.
+
+ ADD becomes the FR_SYMBOL field of the frag, and OFF the FR_OFFSET. */
+static void
+install_operand (mode, val)
+ int mode;
+ int val;
+{
+ switch (mode)
+ {
+ case 's':
+ the_ins.opcode[0] |= val & 0xFF; /* JF FF is for M kludge */
+ break;
+ case 'd':
+ the_ins.opcode[0] |= val << 9;
+ break;
+ case '1':
+ the_ins.opcode[1] |= val << 12;
+ break;
+ case '2':
+ the_ins.opcode[1] |= val << 6;
+ break;
+ case '3':
+ the_ins.opcode[1] |= val;
+ break;
+ case '4':
+ the_ins.opcode[2] |= val << 12;
+ break;
+ case '5':
+ the_ins.opcode[2] |= val << 6;
+ break;
+ case '6':
+ /* DANGER! This is a hack to force cas2l and cas2w cmds to be
+ three words long! */
+ the_ins.numo++;
+ the_ins.opcode[2] |= val;
+ break;
+ case '7':
+ the_ins.opcode[1] |= val << 7;
+ break;
+ case '8':
+ the_ins.opcode[1] |= val << 10;
+ break;
+#ifndef NO_68851
+ case '9':
+ the_ins.opcode[1] |= val << 5;
+ break;
+#endif
+
+ case 't':
+ the_ins.opcode[1] |= (val << 10) | (val << 7);
+ break;
+ case 'D':
+ the_ins.opcode[1] |= (val << 12) | val;
+ break;
+ case 'g':
+ the_ins.opcode[0] |= val = 0xff;
+ break;
+ case 'i':
+ the_ins.opcode[0] |= val << 9;
+ break;
+ case 'C':
+ the_ins.opcode[1] |= val;
+ break;
+ case 'j':
+ the_ins.opcode[1] |= val;
+ the_ins.numo++; /* What a hack */
+ break;
+ case 'k':
+ the_ins.opcode[1] |= val << 4;
+ break;
+ case 'b':
+ case 'w':
+ case 'W':
+ case 'l':
+ break;
+ case 'e':
+ the_ins.opcode[0] |= (val << 6);
+ break;
+ case 'L':
+ the_ins.opcode[1] = (val >> 16);
+ the_ins.opcode[2] = val & 0xffff;
+ break;
+ case 'c':
+ default:
+ as_fatal (_("failed sanity check."));
+ }
+} /* install_operand() */
+
+static void
+install_gen_operand (mode, val)
+ int mode;
+ int val;
+{
+ switch (mode)
+ {
+ case 's':
+ the_ins.opcode[0] |= val;
+ break;
+ case 'd':
+ /* This is a kludge!!! */
+ the_ins.opcode[0] |= (val & 0x07) << 9 | (val & 0x38) << 3;
+ break;
+ case 'b':
+ case 'w':
+ case 'l':
+ case 'f':
+ case 'F':
+ case 'x':
+ case 'p':
+ the_ins.opcode[0] |= val;
+ break;
+ /* more stuff goes here */
+ default:
+ as_fatal (_("failed sanity check."));
+ }
+} /* install_gen_operand() */
+
+/*
+ * verify that we have some number of paren pairs, do m68k_ip_op(), and
+ * then deal with the bitfield hack.
+ */
+
+static char *
+crack_operand (str, opP)
+ register char *str;
+ register struct m68k_op *opP;
+{
+ register int parens;
+ register int c;
+ register char *beg_str;
+ int inquote = 0;
+
+ if (!str)
+ {
+ return str;
+ }
+ beg_str = str;
+ for (parens = 0; *str && (parens > 0 || inquote || notend (str)); str++)
+ {
+ if (! inquote)
+ {
+ if (*str == '(')
+ parens++;
+ else if (*str == ')')
+ {
+ if (!parens)
+ { /* ERROR */
+ opP->error = _("Extra )");
+ return str;
+ }
+ --parens;
+ }
+ }
+ if (flag_mri && *str == '\'')
+ inquote = ! inquote;
+ }
+ if (!*str && parens)
+ { /* ERROR */
+ opP->error = _("Missing )");
+ return str;
+ }
+ c = *str;
+ *str = '\0';
+ if (m68k_ip_op (beg_str, opP) != 0)
+ {
+ *str = c;
+ return str;
+ }
+ *str = c;
+ if (c == '}')
+ c = *++str; /* JF bitfield hack */
+ if (c)
+ {
+ c = *++str;
+ if (!c)
+ as_bad (_("Missing operand"));
+ }
+
+ /* Detect MRI REG symbols and convert them to REGLSTs. */
+ if (opP->mode == CONTROL && (int)opP->reg < 0)
+ {
+ opP->mode = REGLST;
+ opP->mask = ~(int)opP->reg;
+ opP->reg = 0;
+ }
+
+ return str;
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to.
+ */
+
+static void
+insert_reg (regname, regnum)
+ const char *regname;
+ int regnum;
+{
+ char buf[100];
+ int i;
+
+#ifdef REGISTER_PREFIX
+ if (!flag_reg_prefix_optional)
+ {
+ buf[0] = REGISTER_PREFIX;
+ strcpy (buf + 1, regname);
+ regname = buf;
+ }
+#endif
+
+ symbol_table_insert (symbol_new (regname, reg_section, regnum,
+ &zero_address_frag));
+
+ for (i = 0; regname[i]; i++)
+ buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
+ buf[i] = '\0';
+
+ symbol_table_insert (symbol_new (buf, reg_section, regnum,
+ &zero_address_frag));
+}
+
+struct init_entry
+ {
+ const char *name;
+ int number;
+ };
+
+static const struct init_entry init_table[] =
+{
+ { "d0", DATA0 },
+ { "d1", DATA1 },
+ { "d2", DATA2 },
+ { "d3", DATA3 },
+ { "d4", DATA4 },
+ { "d5", DATA5 },
+ { "d6", DATA6 },
+ { "d7", DATA7 },
+ { "a0", ADDR0 },
+ { "a1", ADDR1 },
+ { "a2", ADDR2 },
+ { "a3", ADDR3 },
+ { "a4", ADDR4 },
+ { "a5", ADDR5 },
+ { "a6", ADDR6 },
+ { "fp", ADDR6 },
+ { "a7", ADDR7 },
+ { "sp", ADDR7 },
+ { "ssp", ADDR7 },
+ { "fp0", FP0 },
+ { "fp1", FP1 },
+ { "fp2", FP2 },
+ { "fp3", FP3 },
+ { "fp4", FP4 },
+ { "fp5", FP5 },
+ { "fp6", FP6 },
+ { "fp7", FP7 },
+ { "fpi", FPI },
+ { "fpiar", FPI },
+ { "fpc", FPI },
+ { "fps", FPS },
+ { "fpsr", FPS },
+ { "fpc", FPC },
+ { "fpcr", FPC },
+ { "control", FPC },
+ { "status", FPS },
+ { "iaddr", FPI },
+
+ { "cop0", COP0 },
+ { "cop1", COP1 },
+ { "cop2", COP2 },
+ { "cop3", COP3 },
+ { "cop4", COP4 },
+ { "cop5", COP5 },
+ { "cop6", COP6 },
+ { "cop7", COP7 },
+ { "pc", PC },
+ { "zpc", ZPC },
+ { "sr", SR },
+
+ { "ccr", CCR },
+ { "cc", CCR },
+
+ /* control registers */
+ { "sfc", SFC }, /* Source Function Code */
+ { "sfcr", SFC },
+ { "dfc", DFC }, /* Destination Function Code */
+ { "dfcr", DFC },
+ { "cacr", CACR }, /* Cache Control Register */
+ { "caar", CAAR }, /* Cache Address Register */
+
+ { "usp", USP }, /* User Stack Pointer */
+ { "vbr", VBR }, /* Vector Base Register */
+ { "msp", MSP }, /* Master Stack Pointer */
+ { "isp", ISP }, /* Interrupt Stack Pointer */
+
+ { "itt0", ITT0 }, /* Instruction Transparent Translation Reg 0 */
+ { "itt1", ITT1 }, /* Instruction Transparent Translation Reg 1 */
+ { "dtt0", DTT0 }, /* Data Transparent Translation Register 0 */
+ { "dtt1", DTT1 }, /* Data Transparent Translation Register 1 */
+
+ /* 68ec040 versions of same */
+ { "iacr0", ITT0 }, /* Instruction Access Control Register 0 */
+ { "iacr1", ITT1 }, /* Instruction Access Control Register 0 */
+ { "dacr0", DTT0 }, /* Data Access Control Register 0 */
+ { "dacr1", DTT1 }, /* Data Access Control Register 0 */
+
+ /* mcf5200 versions of same. The ColdFire programmer's reference
+ manual indicated that the order is 2,3,0,1, but Ken Rose
+ <rose@netcom.com> says that 0,1,2,3 is the correct order. */
+ { "acr0", ITT0 }, /* Access Control Unit 0 */
+ { "acr1", ITT1 }, /* Access Control Unit 1 */
+ { "acr2", DTT0 }, /* Access Control Unit 2 */
+ { "acr3", DTT1 }, /* Access Control Unit 3 */
+
+ { "tc", TC }, /* MMU Translation Control Register */
+ { "tcr", TC },
+
+ { "mmusr", MMUSR }, /* MMU Status Register */
+ { "srp", SRP }, /* User Root Pointer */
+ { "urp", URP }, /* Supervisor Root Pointer */
+
+ { "buscr", BUSCR },
+ { "pcr", PCR },
+
+ { "rombar", ROMBAR }, /* ROM Base Address Register */
+ { "rambar0", RAMBAR0 }, /* ROM Base Address Register */
+ { "rambar1", RAMBAR1 }, /* ROM Base Address Register */
+ { "mbar", MBAR }, /* Module Base Address Register */
+ /* end of control registers */
+
+ { "ac", AC },
+ { "bc", BC },
+ { "cal", CAL },
+ { "crp", CRP },
+ { "drp", DRP },
+ { "pcsr", PCSR },
+ { "psr", PSR },
+ { "scc", SCC },
+ { "val", VAL },
+ { "bad0", BAD0 },
+ { "bad1", BAD1 },
+ { "bad2", BAD2 },
+ { "bad3", BAD3 },
+ { "bad4", BAD4 },
+ { "bad5", BAD5 },
+ { "bad6", BAD6 },
+ { "bad7", BAD7 },
+ { "bac0", BAC0 },
+ { "bac1", BAC1 },
+ { "bac2", BAC2 },
+ { "bac3", BAC3 },
+ { "bac4", BAC4 },
+ { "bac5", BAC5 },
+ { "bac6", BAC6 },
+ { "bac7", BAC7 },
+
+ { "ic", IC },
+ { "dc", DC },
+ { "nc", NC },
+
+ { "tt0", TT0 },
+ { "tt1", TT1 },
+ /* 68ec030 versions of same */
+ { "ac0", TT0 },
+ { "ac1", TT1 },
+ /* 68ec030 access control unit, identical to 030 MMU status reg */
+ { "acusr", PSR },
+
+ /* Suppressed data and address registers. */
+ { "zd0", ZDATA0 },
+ { "zd1", ZDATA1 },
+ { "zd2", ZDATA2 },
+ { "zd3", ZDATA3 },
+ { "zd4", ZDATA4 },
+ { "zd5", ZDATA5 },
+ { "zd6", ZDATA6 },
+ { "zd7", ZDATA7 },
+ { "za0", ZADDR0 },
+ { "za1", ZADDR1 },
+ { "za2", ZADDR2 },
+ { "za3", ZADDR3 },
+ { "za4", ZADDR4 },
+ { "za5", ZADDR5 },
+ { "za6", ZADDR6 },
+ { "za7", ZADDR7 },
+
+ { 0, 0 }
+};
+
+static void
+init_regtable ()
+{
+ int i;
+ for (i = 0; init_table[i].name; i++)
+ insert_reg (init_table[i].name, init_table[i].number);
+}
+
+static int no_68851, no_68881;
+
+#ifdef OBJ_AOUT
+/* a.out machine type. Default to 68020. */
+int m68k_aout_machtype = 2;
+#endif
+
+void
+md_assemble (str)
+ char *str;
+{
+ const char *er;
+ short *fromP;
+ char *toP = NULL;
+ int m, n = 0;
+ char *to_beg_P;
+ int shorts_this_frag;
+ fixS *fixP;
+
+ /* In MRI mode, the instruction and operands are separated by a
+ space. Anything following the operands is a comment. The label
+ has already been removed. */
+ if (flag_mri)
+ {
+ char *s;
+ int fields = 0;
+ int infield = 0;
+ int inquote = 0;
+
+ for (s = str; *s != '\0'; s++)
+ {
+ if ((*s == ' ' || *s == '\t') && ! inquote)
+ {
+ if (infield)
+ {
+ ++fields;
+ if (fields >= 2)
+ {
+ *s = '\0';
+ break;
+ }
+ infield = 0;
+ }
+ }
+ else
+ {
+ if (! infield)
+ infield = 1;
+ if (*s == '\'')
+ inquote = ! inquote;
+ }
+ }
+ }
+
+ memset ((char *) (&the_ins), '\0', sizeof (the_ins));
+ m68k_ip (str);
+ er = the_ins.error;
+ if (!er)
+ {
+ for (n = 0; n < the_ins.numargs; n++)
+ if (the_ins.operands[n].error)
+ {
+ er = the_ins.operands[n].error;
+ break;
+ }
+ }
+ if (er)
+ {
+ as_bad (_("%s -- statement `%s' ignored"), er, str);
+ return;
+ }
+
+ /* If there is a current label, record that it marks an instruction. */
+ if (current_label != NULL)
+ {
+ current_label->text = 1;
+ current_label = NULL;
+ }
+
+ if (the_ins.nfrag == 0)
+ {
+ /* No frag hacking involved; just put it out */
+ toP = frag_more (2 * the_ins.numo);
+ fromP = &the_ins.opcode[0];
+ for (m = the_ins.numo; m; --m)
+ {
+ md_number_to_chars (toP, (long) (*fromP), 2);
+ toP += 2;
+ fromP++;
+ }
+ /* put out symbol-dependent info */
+ for (m = 0; m < the_ins.nrel; m++)
+ {
+ switch (the_ins.reloc[m].wid)
+ {
+ case 'B':
+ n = 1;
+ break;
+ case 'b':
+ n = 1;
+ break;
+ case '3':
+ n = 1;
+ break;
+ case 'w':
+ case 'W':
+ n = 2;
+ break;
+ case 'l':
+ n = 4;
+ break;
+ default:
+ as_fatal (_("Don't know how to figure width of %c in md_assemble()"),
+ the_ins.reloc[m].wid);
+ }
+
+ fixP = fix_new_exp (frag_now,
+ ((toP - frag_now->fr_literal)
+ - the_ins.numo * 2 + the_ins.reloc[m].n),
+ n,
+ &the_ins.reloc[m].exp,
+ the_ins.reloc[m].pcrel,
+ get_reloc_code (n, the_ins.reloc[m].pcrel,
+ the_ins.reloc[m].pic_reloc));
+ fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
+ if (the_ins.reloc[m].wid == 'B')
+ fixP->fx_signed = 1;
+ }
+ return;
+ }
+
+ /* There's some frag hacking */
+ for (n = 0, fromP = &the_ins.opcode[0]; n < the_ins.nfrag; n++)
+ {
+ int wid;
+
+ if (n == 0)
+ wid = 2 * the_ins.fragb[n].fragoff;
+ else
+ wid = 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff);
+ toP = frag_more (wid);
+ to_beg_P = toP;
+ shorts_this_frag = 0;
+ for (m = wid / 2; m; --m)
+ {
+ md_number_to_chars (toP, (long) (*fromP), 2);
+ toP += 2;
+ fromP++;
+ shorts_this_frag++;
+ }
+ for (m = 0; m < the_ins.nrel; m++)
+ {
+ if ((the_ins.reloc[m].n) >= 2 * shorts_this_frag)
+ {
+ the_ins.reloc[m].n -= 2 * shorts_this_frag;
+ break;
+ }
+ wid = the_ins.reloc[m].wid;
+ if (wid == 0)
+ continue;
+ the_ins.reloc[m].wid = 0;
+ wid = (wid == 'b') ? 1 : (wid == 'w') ? 2 : (wid == 'l') ? 4 : 4000;
+
+ fixP = fix_new_exp (frag_now,
+ ((toP - frag_now->fr_literal)
+ - the_ins.numo * 2 + the_ins.reloc[m].n),
+ wid,
+ &the_ins.reloc[m].exp,
+ the_ins.reloc[m].pcrel,
+ get_reloc_code (wid, the_ins.reloc[m].pcrel,
+ the_ins.reloc[m].pic_reloc));
+ fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
+ }
+ (void) frag_var (rs_machine_dependent, 10, 0,
+ (relax_substateT) (the_ins.fragb[n].fragty),
+ the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
+ }
+ n = (the_ins.numo - the_ins.fragb[n - 1].fragoff);
+ shorts_this_frag = 0;
+ if (n)
+ {
+ toP = frag_more (n * sizeof (short));
+ while (n--)
+ {
+ md_number_to_chars (toP, (long) (*fromP), 2);
+ toP += 2;
+ fromP++;
+ shorts_this_frag++;
+ }
+ }
+ for (m = 0; m < the_ins.nrel; m++)
+ {
+ int wid;
+
+ wid = the_ins.reloc[m].wid;
+ if (wid == 0)
+ continue;
+ the_ins.reloc[m].wid = 0;
+ wid = (wid == 'b') ? 1 : (wid == 'w') ? 2 : (wid == 'l') ? 4 : 4000;
+
+ fixP = fix_new_exp (frag_now,
+ ((the_ins.reloc[m].n + toP - frag_now->fr_literal)
+ - shorts_this_frag * 2),
+ wid,
+ &the_ins.reloc[m].exp,
+ the_ins.reloc[m].pcrel,
+ get_reloc_code (wid, the_ins.reloc[m].pcrel,
+ the_ins.reloc[m].pic_reloc));
+ fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
+ }
+}
+
+void
+md_begin ()
+{
+ /*
+ * md_begin -- set up hash tables with 68000 instructions.
+ * similar to what the vax assembler does. ---phr
+ */
+ /* RMS claims the thing to do is take the m68k-opcode.h table, and make
+ a copy of it at runtime, adding in the information we want but isn't
+ there. I think it'd be better to have an awk script hack the table
+ at compile time. Or even just xstr the table and use it as-is. But
+ my lord ghod hath spoken, so we do it this way. Excuse the ugly var
+ names. */
+
+ register const struct m68k_opcode *ins;
+ register struct m68k_incant *hack, *slak;
+ register const char *retval = 0; /* empty string, or error msg text */
+ register unsigned int i;
+ register char c;
+
+ if (flag_mri)
+ {
+ flag_reg_prefix_optional = 1;
+ m68k_abspcadd = 1;
+ if (! m68k_rel32_from_cmdline)
+ m68k_rel32 = 0;
+ }
+
+ op_hash = hash_new ();
+
+ obstack_begin (&robyn, 4000);
+ for (i = 0; i < m68k_numopcodes; i++)
+ {
+ hack = slak = (struct m68k_incant *) obstack_alloc (&robyn, sizeof (struct m68k_incant));
+ do
+ {
+ ins = &m68k_opcodes[i];
+ /* We *could* ignore insns that don't match our arch here
+ but just leaving them out of the hash. */
+ slak->m_operands = ins->args;
+ slak->m_opnum = strlen (slak->m_operands) / 2;
+ slak->m_arch = ins->arch;
+ slak->m_opcode = ins->opcode;
+ /* This is kludgey */
+ slak->m_codenum = ((ins->match) & 0xffffL) ? 2 : 1;
+ if (i + 1 != m68k_numopcodes
+ && !strcmp (ins->name, m68k_opcodes[i + 1].name))
+ {
+ slak->m_next = (struct m68k_incant *) obstack_alloc (&robyn, sizeof (struct m68k_incant));
+ i++;
+ }
+ else
+ slak->m_next = 0;
+ slak = slak->m_next;
+ }
+ while (slak);
+
+ retval = hash_insert (op_hash, ins->name, (char *) hack);
+ if (retval)
+ as_fatal (_("Internal Error: Can't hash %s: %s"), ins->name, retval);
+ }
+
+ for (i = 0; i < m68k_numaliases; i++)
+ {
+ const char *name = m68k_opcode_aliases[i].primary;
+ const char *alias = m68k_opcode_aliases[i].alias;
+ PTR val = hash_find (op_hash, name);
+ if (!val)
+ as_fatal (_("Internal Error: Can't find %s in hash table"), name);
+ retval = hash_insert (op_hash, alias, val);
+ if (retval)
+ as_fatal (_("Internal Error: Can't hash %s: %s"), alias, retval);
+ }
+
+ /* In MRI mode, all unsized branches are variable sized. Normally,
+ they are word sized. */
+ if (flag_mri)
+ {
+ static struct m68k_opcode_alias mri_aliases[] =
+ {
+ { "bhi", "jhi", },
+ { "bls", "jls", },
+ { "bcc", "jcc", },
+ { "bcs", "jcs", },
+ { "bne", "jne", },
+ { "beq", "jeq", },
+ { "bvc", "jvc", },
+ { "bvs", "jvs", },
+ { "bpl", "jpl", },
+ { "bmi", "jmi", },
+ { "bge", "jge", },
+ { "blt", "jlt", },
+ { "bgt", "jgt", },
+ { "ble", "jle", },
+ { "bra", "jra", },
+ { "bsr", "jbsr", },
+ };
+
+ for (i = 0; i < sizeof mri_aliases / sizeof mri_aliases[0]; i++)
+ {
+ const char *name = mri_aliases[i].primary;
+ const char *alias = mri_aliases[i].alias;
+ PTR val = hash_find (op_hash, name);
+ if (!val)
+ as_fatal (_("Internal Error: Can't find %s in hash table"), name);
+ retval = hash_jam (op_hash, alias, val);
+ if (retval)
+ as_fatal (_("Internal Error: Can't hash %s: %s"), alias, retval);
+ }
+ }
+
+ for (i = 0; i < sizeof (mklower_table); i++)
+ mklower_table[i] = (isupper (c = (char) i)) ? tolower (c) : c;
+
+ for (i = 0; i < sizeof (notend_table); i++)
+ {
+ notend_table[i] = 0;
+ alt_notend_table[i] = 0;
+ }
+ notend_table[','] = 1;
+ notend_table['{'] = 1;
+ notend_table['}'] = 1;
+ alt_notend_table['a'] = 1;
+ alt_notend_table['A'] = 1;
+ alt_notend_table['d'] = 1;
+ alt_notend_table['D'] = 1;
+ alt_notend_table['#'] = 1;
+ alt_notend_table['&'] = 1;
+ alt_notend_table['f'] = 1;
+ alt_notend_table['F'] = 1;
+#ifdef REGISTER_PREFIX
+ alt_notend_table[REGISTER_PREFIX] = 1;
+#endif
+
+ /* We need to put '(' in alt_notend_table to handle
+ cas2 %d0:%d2,%d3:%d4,(%a0):(%a1)
+ */
+ alt_notend_table['('] = 1;
+
+ /* We need to put '@' in alt_notend_table to handle
+ cas2 %d0:%d2,%d3:%d4,@(%d0):@(%d1)
+ */
+ alt_notend_table['@'] = 1;
+
+ /* We need to put digits in alt_notend_table to handle
+ bfextu %d0{24:1},%d0
+ */
+ alt_notend_table['0'] = 1;
+ alt_notend_table['1'] = 1;
+ alt_notend_table['2'] = 1;
+ alt_notend_table['3'] = 1;
+ alt_notend_table['4'] = 1;
+ alt_notend_table['5'] = 1;
+ alt_notend_table['6'] = 1;
+ alt_notend_table['7'] = 1;
+ alt_notend_table['8'] = 1;
+ alt_notend_table['9'] = 1;
+
+#ifndef MIT_SYNTAX_ONLY
+ /* Insert pseudo ops, these have to go into the opcode table since
+ gas expects pseudo ops to start with a dot */
+ {
+ int n = 0;
+ while (mote_pseudo_table[n].poc_name)
+ {
+ hack = (struct m68k_incant *)
+ obstack_alloc (&robyn, sizeof (struct m68k_incant));
+ hash_insert (op_hash,
+ mote_pseudo_table[n].poc_name, (char *) hack);
+ hack->m_operands = 0;
+ hack->m_opnum = n;
+ n++;
+ }
+ }
+#endif
+
+ init_regtable ();
+
+#ifdef OBJ_ELF
+ record_alignment (text_section, 2);
+ record_alignment (data_section, 2);
+ record_alignment (bss_section, 2);
+#endif
+}
+
+static void
+select_control_regs ()
+{
+ /* Note which set of "movec" control registers is available. */
+ switch (cpu_of_arch (current_architecture))
+ {
+ case m68000:
+ control_regs = m68000_control_regs;
+ break;
+ case m68010:
+ control_regs = m68010_control_regs;
+ break;
+ case m68020:
+ case m68030:
+ control_regs = m68020_control_regs;
+ break;
+ case m68040:
+ control_regs = m68040_control_regs;
+ break;
+ case m68060:
+ control_regs = m68060_control_regs;
+ break;
+ case cpu32:
+ control_regs = cpu32_control_regs;
+ break;
+ case mcf5200:
+ control_regs = mcf5200_control_regs;
+ break;
+ default:
+ abort ();
+ }
+}
+
+void
+m68k_init_after_args ()
+{
+ if (cpu_of_arch (current_architecture) == 0)
+ {
+ int i;
+ const char *default_cpu = TARGET_CPU;
+
+ if (*default_cpu == 'm')
+ default_cpu++;
+ for (i = 0; i < n_archs; i++)
+ if (strcasecmp (default_cpu, archs[i].name) == 0)
+ break;
+ if (i == n_archs)
+ {
+ as_bad (_("unrecognized default cpu `%s' ???"), TARGET_CPU);
+ current_architecture |= m68020;
+ }
+ else
+ current_architecture |= archs[i].arch;
+ }
+ /* Permit m68881 specification with all cpus; those that can't work
+ with a coprocessor could be doing emulation. */
+ if (current_architecture & m68851)
+ {
+ if (current_architecture & m68040)
+ {
+ as_warn (_("68040 and 68851 specified; mmu instructions may assemble incorrectly"));
+ }
+ }
+ /* What other incompatibilities could we check for? */
+
+ /* Toss in some default assumptions about coprocessors. */
+ if (!no_68881
+ && (cpu_of_arch (current_architecture)
+ /* Can CPU32 have a 68881 coprocessor?? */
+ & (m68020 | m68030 | cpu32)))
+ {
+ current_architecture |= m68881;
+ }
+ if (!no_68851
+ && (cpu_of_arch (current_architecture) & m68020up) != 0
+ && (cpu_of_arch (current_architecture) & m68040up) == 0)
+ {
+ current_architecture |= m68851;
+ }
+ if (no_68881 && (current_architecture & m68881))
+ as_bad (_("options for 68881 and no-68881 both given"));
+ if (no_68851 && (current_architecture & m68851))
+ as_bad (_("options for 68851 and no-68851 both given"));
+
+#ifdef OBJ_AOUT
+ /* Work out the magic number. This isn't very general. */
+ if (current_architecture & m68000)
+ m68k_aout_machtype = 0;
+ else if (current_architecture & m68010)
+ m68k_aout_machtype = 1;
+ else if (current_architecture & m68020)
+ m68k_aout_machtype = 2;
+ else
+ m68k_aout_machtype = 2;
+#endif
+
+ /* Note which set of "movec" control registers is available. */
+ select_control_regs ();
+
+ if (cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200)
+ md_relax_table[TAB (PCINDEX, BYTE)].rlx_more = 0;
+}
+
+/* This is called when a label is defined. */
+
+void
+m68k_frob_label (sym)
+ symbolS *sym;
+{
+ struct label_line *n;
+
+ n = (struct label_line *) xmalloc (sizeof *n);
+ n->next = labels;
+ n->label = sym;
+ as_where (&n->file, &n->line);
+ n->text = 0;
+ labels = n;
+ current_label = n;
+}
+
+/* This is called when a value that is not an instruction is emitted. */
+
+void
+m68k_flush_pending_output ()
+{
+ current_label = NULL;
+}
+
+/* This is called at the end of the assembly, when the final value of
+ the label is known. We warn if this is a text symbol aligned at an
+ odd location. */
+
+void
+m68k_frob_symbol (sym)
+ symbolS *sym;
+{
+ if (S_GET_SEGMENT (sym) == reg_section
+ && (int) S_GET_VALUE (sym) < 0)
+ {
+ S_SET_SEGMENT (sym, absolute_section);
+ S_SET_VALUE (sym, ~(int)S_GET_VALUE (sym));
+ }
+ else if ((S_GET_VALUE (sym) & 1) != 0)
+ {
+ struct label_line *l;
+
+ for (l = labels; l != NULL; l = l->next)
+ {
+ if (l->label == sym)
+ {
+ if (l->text)
+ as_warn_where (l->file, l->line,
+ _("text label `%s' aligned to odd boundary"),
+ S_GET_NAME (sym));
+ break;
+ }
+ }
+ }
+}
+
+/* This is called if we go in or out of MRI mode because of the .mri
+ pseudo-op. */
+
+void
+m68k_mri_mode_change (on)
+ int on;
+{
+ if (on)
+ {
+ if (! flag_reg_prefix_optional)
+ {
+ flag_reg_prefix_optional = 1;
+#ifdef REGISTER_PREFIX
+ init_regtable ();
+#endif
+ }
+ m68k_abspcadd = 1;
+ if (! m68k_rel32_from_cmdline)
+ m68k_rel32 = 0;
+ }
+ else
+ {
+ if (! reg_prefix_optional_seen)
+ {
+#ifdef REGISTER_PREFIX_OPTIONAL
+ flag_reg_prefix_optional = REGISTER_PREFIX_OPTIONAL;
+#else
+ flag_reg_prefix_optional = 0;
+#endif
+#ifdef REGISTER_PREFIX
+ init_regtable ();
+#endif
+ }
+ m68k_abspcadd = 0;
+ if (! m68k_rel32_from_cmdline)
+ m68k_rel32 = 1;
+ }
+}
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type type, and store the appropriate bytes in *litP. The number
+ of LITTLENUMS emitted is stored in *sizeP . An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ number_to_chars_bigendian (buf, val, n);
+}
+
+static void
+md_apply_fix_2 (fixP, val)
+ fixS *fixP;
+ offsetT val;
+{
+ addressT upper_limit;
+ offsetT lower_limit;
+
+ /* This is unnecessary but it convinces the native rs6000 compiler
+ to generate the code we want. */
+ char *buf = fixP->fx_frag->fr_literal;
+ buf += fixP->fx_where;
+ /* end ibm compiler workaround */
+
+ if (val & 0x80000000)
+ val |= ~(addressT)0x7fffffff;
+ else
+ val &= 0x7fffffff;
+
+#ifdef OBJ_ELF
+ if (fixP->fx_addsy)
+ {
+ memset (buf, 0, fixP->fx_size);
+ fixP->fx_addnumber = val; /* Remember value for emit_reloc */
+
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ && !S_IS_DEFINED (fixP->fx_addsy)
+ && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ return;
+ }
+#endif
+
+#ifdef BFD_ASSEMBLER
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return;
+#endif
+
+ switch (fixP->fx_size)
+ {
+ /* The cast to offsetT below are necessary to make code correct for
+ machines where ints are smaller than offsetT */
+ case 1:
+ *buf++ = val;
+ upper_limit = 0x7f;
+ lower_limit = - (offsetT) 0x80;
+ break;
+ case 2:
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ upper_limit = 0x7fff;
+ lower_limit = - (offsetT) 0x8000;
+ break;
+ case 4:
+ *buf++ = (val >> 24);
+ *buf++ = (val >> 16);
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ upper_limit = 0x7fffffff;
+ lower_limit = - (offsetT) 0x7fffffff - 1; /* avoid constant overflow */
+ break;
+ default:
+ BAD_CASE (fixP->fx_size);
+ }
+
+ /* Fix up a negative reloc. */
+ if (fixP->fx_addsy == NULL && fixP->fx_subsy != NULL)
+ {
+ fixP->fx_addsy = fixP->fx_subsy;
+ fixP->fx_subsy = NULL;
+ fixP->fx_tcbit = 1;
+ }
+
+ /* For non-pc-relative values, it's conceivable we might get something
+ like "0xff" for a byte field. So extend the upper part of the range
+ to accept such numbers. We arbitrarily disallow "-0xff" or "0xff+0xff",
+ so that we can do any range checking at all. */
+ if (! fixP->fx_pcrel && ! fixP->fx_signed)
+ upper_limit = upper_limit * 2 + 1;
+
+ if ((addressT) val > upper_limit
+ && (val > 0 || val < lower_limit))
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("value out of range"));
+
+ /* A one byte PC-relative reloc means a short branch. We can't use
+ a short branch with a value of 0 or -1, because those indicate
+ different opcodes (branches with longer offsets). fixup_segment
+ in write.c may have clobbered fx_pcrel, so we need to examine the
+ reloc type. */
+ if ((fixP->fx_pcrel
+#ifdef BFD_ASSEMBLER
+ || fixP->fx_r_type == BFD_RELOC_8_PCREL
+#endif
+ )
+ && fixP->fx_size == 1
+ && (fixP->fx_addsy == NULL
+ || S_IS_DEFINED (fixP->fx_addsy))
+ && (val == 0 || val == -1))
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("invalid byte branch offset"));
+}
+
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ valueT *valp;
+{
+ md_apply_fix_2 (fixP, (addressT) *valp);
+ return 1;
+}
+#else
+void md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ md_apply_fix_2 (fixP, (addressT) val);
+}
+#endif
+
+/* *fragP has been relaxed to its final size, and now needs to have
+ the bytes inside it modified to conform to the new size There is UGLY
+ MAGIC here. ..
+ */
+static void
+md_convert_frag_1 (fragP)
+ register fragS *fragP;
+{
+ long disp;
+ long ext = 0;
+ fixS *fixP;
+
+ /* Address in object code of the displacement. */
+ register int object_address = fragP->fr_fix + fragP->fr_address;
+
+ /* Address in gas core of the place to store the displacement. */
+ /* This convinces the native rs6000 compiler to generate the code we
+ want. */
+ register char *buffer_address = fragP->fr_literal;
+ buffer_address += fragP->fr_fix;
+ /* end ibm compiler workaround */
+
+ /* The displacement of the address, from current location. */
+ disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
+ disp = (disp + fragP->fr_offset) - object_address;
+
+#ifdef BFD_ASSEMBLER
+ disp += fragP->fr_symbol->sy_frag->fr_address;
+#endif
+
+ switch (fragP->fr_subtype)
+ {
+ case TAB (BCC68000, BYTE):
+ case TAB (ABRANCH, BYTE):
+ know (issbyte (disp));
+ if (disp == 0)
+ as_bad (_("short branch with zero offset: use :w"));
+ fragP->fr_opcode[1] = disp;
+ ext = 0;
+ break;
+ case TAB (DBCC, SHORT):
+ know (issword (disp));
+ ext = 2;
+ break;
+ case TAB (BCC68000, SHORT):
+ case TAB (ABRANCH, SHORT):
+ know (issword (disp));
+ fragP->fr_opcode[1] = 0x00;
+ ext = 2;
+ break;
+ case TAB (ABRANCH, LONG):
+ if (!HAVE_LONG_BRANCH(current_architecture))
+ {
+ if (fragP->fr_opcode[0] == 0x61)
+ /* BSR */
+ {
+ fragP->fr_opcode[0] = 0x4E;
+ fragP->fr_opcode[1] = (char) 0xB9; /* JBSR with ABSL LONG offset */
+
+ fix_new (fragP,
+ fragP->fr_fix,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 0,
+ NO_RELOC);
+
+ fragP->fr_fix += 4;
+ ext = 0;
+ }
+ /* BRA */
+ else if (fragP->fr_opcode[0] == 0x60)
+ {
+ fragP->fr_opcode[0] = 0x4E;
+ fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG offset */
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ ext = 0;
+ }
+ else
+ {
+ as_bad (_("Long branch offset not supported."));
+ }
+ }
+ else
+ {
+ fragP->fr_opcode[1] = (char) 0xff;
+ ext = 4;
+ }
+ break;
+ case TAB (BCC68000, LONG):
+ /* only Bcc 68000 instructions can come here */
+ /* change bcc into b!cc/jmp absl long */
+ fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
+ fragP->fr_opcode[1] = 0x6;/* branch offset = 6 */
+
+ /* JF: these used to be fr_opcode[2,3], but they may be in a
+ different frag, in which case refering to them is a no-no.
+ Only fr_opcode[0,1] are guaranteed to work. */
+ *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
+ *buffer_address++ = (char) 0xf9;
+ fragP->fr_fix += 2; /* account for jmp instruction */
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ ext = 0;
+ break;
+ case TAB (DBCC, LONG):
+ /* only DBcc 68000 instructions can come here */
+ /* change dbcc into dbcc/jmp absl long */
+ /* JF: these used to be fr_opcode[2-7], but that's wrong */
+ *buffer_address++ = 0x00; /* branch offset = 4 */
+ *buffer_address++ = 0x04;
+ *buffer_address++ = 0x60; /* put in bra pc+6 */
+ *buffer_address++ = 0x06;
+ *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
+ *buffer_address++ = (char) 0xf9;
+
+ fragP->fr_fix += 6; /* account for bra/jmp instructions */
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ ext = 0;
+ break;
+ case TAB (FBRANCH, SHORT):
+ know ((fragP->fr_opcode[1] & 0x40) == 0);
+ ext = 2;
+ break;
+ case TAB (FBRANCH, LONG):
+ fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */
+ ext = 4;
+ break;
+ case TAB (PCREL, SHORT):
+ ext = 2;
+ break;
+ case TAB (PCREL, LONG):
+ /* The thing to do here is force it to ABSOLUTE LONG, since
+ PCREL is really trying to shorten an ABSOLUTE address anyway */
+ /* JF FOO This code has not been tested */
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, fragP->fr_offset,
+ 0, NO_RELOC);
+ if ((fragP->fr_opcode[1] & 0x3F) != 0x3A)
+ as_bad (_("Internal error (long PC-relative operand) for insn 0x%04x at 0x%lx"),
+ (unsigned) fragP->fr_opcode[0],
+ (unsigned long) fragP->fr_address);
+ fragP->fr_opcode[1] &= ~0x3F;
+ fragP->fr_opcode[1] |= 0x39; /* Mode 7.1 */
+ fragP->fr_fix += 4;
+ ext = 0;
+ break;
+ case TAB (PCLEA, SHORT):
+ fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ fragP->fr_opcode[1] &= ~0x3F;
+ fragP->fr_opcode[1] |= 0x3A; /* 072 - mode 7.2 */
+ ext = 2;
+ break;
+ case TAB (PCLEA, LONG):
+ fixP = fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ fixP->fx_pcrel_adjust = 2;
+ /* Already set to mode 7.3; this indicates: PC indirect with
+ suppressed index, 32-bit displacement. */
+ *buffer_address++ = 0x01;
+ *buffer_address++ = 0x70;
+ fragP->fr_fix += 2;
+ ext = 4;
+ break;
+
+ case TAB (PCINDEX, BYTE):
+ disp += 2;
+ if (!issbyte (disp))
+ {
+ as_bad (_("displacement doesn't fit in one byte"));
+ disp = 0;
+ }
+ assert (fragP->fr_fix >= 2);
+ buffer_address[-2] &= ~1;
+ buffer_address[-1] = disp;
+ ext = 0;
+ break;
+ case TAB (PCINDEX, SHORT):
+ disp += 2;
+ assert (issword (disp));
+ assert (fragP->fr_fix >= 2);
+ buffer_address[-2] |= 0x1;
+ buffer_address[-1] = 0x20;
+ fixP = fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
+ fragP->fr_offset, (fragP->fr_opcode[1] & 077) == 073,
+ NO_RELOC);
+ fixP->fx_pcrel_adjust = 2;
+ ext = 2;
+ break;
+ case TAB (PCINDEX, LONG):
+ disp += 2;
+ fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
+ fragP->fr_offset, (fragP->fr_opcode[1] & 077) == 073,
+ NO_RELOC);
+ fixP->fx_pcrel_adjust = 2;
+ assert (fragP->fr_fix >= 2);
+ buffer_address[-2] |= 0x1;
+ buffer_address[-1] = 0x30;
+ ext = 4;
+ break;
+ }
+
+ if (ext)
+ {
+ md_number_to_chars (buffer_address, (long) disp, (int) ext);
+ fragP->fr_fix += ext;
+ }
+}
+
+#ifndef BFD_ASSEMBLER
+
+void
+md_convert_frag (headers, sec, fragP)
+ object_headers *headers;
+ segT sec;
+ fragS *fragP;
+{
+ md_convert_frag_1 (fragP);
+}
+
+#else
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ fragS *fragP;
+{
+ md_convert_frag_1 (fragP);
+}
+#endif
+
+/* Force truly undefined symbols to their maximum size, and generally set up
+ the frag list to be relaxed
+ */
+int
+md_estimate_size_before_relax (fragP, segment)
+ register fragS *fragP;
+ segT segment;
+{
+ int old_fix;
+ register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
+
+ old_fix = fragP->fr_fix;
+
+ /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
+ switch (fragP->fr_subtype)
+ {
+
+ case TAB (ABRANCH, SZ_UNDEF):
+ {
+ if ((fragP->fr_symbol != NULL) /* Not absolute */
+ && S_GET_SEGMENT (fragP->fr_symbol) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ {
+ fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), BYTE);
+ break;
+ }
+ else if ((fragP->fr_symbol == 0) || !HAVE_LONG_BRANCH(current_architecture))
+ {
+ /* On 68000, or for absolute value, switch to abs long */
+ /* FIXME, we should check abs val, pick short or long */
+ if (fragP->fr_opcode[0] == 0x61)
+ {
+ fragP->fr_opcode[0] = 0x4E;
+ fragP->fr_opcode[1] = (char) 0xB9; /* JBSR with ABSL LONG offset */
+ fix_new (fragP, fragP->fr_fix, 4,
+ fragP->fr_symbol, fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ frag_wane (fragP);
+ }
+ else if (fragP->fr_opcode[0] == 0x60)
+ {
+ fragP->fr_opcode[0] = 0x4E;
+ fragP->fr_opcode[1] = (char) 0xF9; /* JMP with ABSL LONG offset */
+ fix_new (fragP, fragP->fr_fix, 4,
+ fragP->fr_symbol, fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ frag_wane (fragP);
+ }
+ else
+ {
+ as_warn (_("Long branch offset to extern symbol not supported."));
+ }
+ }
+ else
+ { /* Symbol is still undefined. Make it simple */
+ fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ fragP->fr_fix += 4;
+ fragP->fr_opcode[1] = (char) 0xff;
+ frag_wane (fragP);
+ break;
+ }
+
+ break;
+ } /* case TAB(ABRANCH,SZ_UNDEF) */
+
+ case TAB (FBRANCH, SZ_UNDEF):
+ {
+ if ((S_GET_SEGMENT (fragP->fr_symbol) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ || flag_short_refs)
+ {
+ fragP->fr_subtype = TAB (FBRANCH, SHORT);
+ fragP->fr_var += 2;
+ }
+ else
+ {
+ fix_new (fragP, (int) fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ fragP->fr_fix += 4;
+ fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */
+ frag_wane (fragP);
+ }
+ break;
+ } /* TAB(FBRANCH,SZ_UNDEF) */
+
+ case TAB (PCREL, SZ_UNDEF):
+ {
+ if ((S_GET_SEGMENT (fragP->fr_symbol) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ || flag_short_refs
+ || cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200)
+ {
+ fragP->fr_subtype = TAB (PCREL, SHORT);
+ fragP->fr_var += 2;
+ }
+ else
+ {
+ fragP->fr_subtype = TAB (PCREL, LONG);
+ fragP->fr_var += 4;
+ }
+ break;
+ } /* TAB(PCREL,SZ_UNDEF) */
+
+ case TAB (BCC68000, SZ_UNDEF):
+ {
+ if ((fragP->fr_symbol != NULL)
+ && S_GET_SEGMENT (fragP->fr_symbol) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ {
+ fragP->fr_subtype = TAB (BCC68000, BYTE);
+ break;
+ }
+ /* only Bcc 68000 instructions can come here */
+ /* change bcc into b!cc/jmp absl long */
+ fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
+ if (flag_short_refs)
+ {
+ fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */
+ /* JF: these were fr_opcode[2,3] */
+ buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
+ buffer_address[1] = (char) 0xf8;
+ fragP->fr_fix += 2; /* account for jmp instruction */
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 2;
+ }
+ else
+ {
+ fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */
+ /* JF: these were fr_opcode[2,3] */
+ buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
+ buffer_address[1] = (char) 0xf9;
+ fragP->fr_fix += 2; /* account for jmp instruction */
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ }
+ frag_wane (fragP);
+ break;
+ } /* case TAB(BCC68000,SZ_UNDEF) */
+
+ case TAB (DBCC, SZ_UNDEF):
+ {
+ if (fragP->fr_symbol != NULL
+ && S_GET_SEGMENT (fragP->fr_symbol) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ {
+ fragP->fr_subtype = TAB (DBCC, SHORT);
+ fragP->fr_var += 2;
+ break;
+ }
+ /* only DBcc 68000 instructions can come here */
+ /* change dbcc into dbcc/jmp absl long */
+ /* JF: these used to be fr_opcode[2-4], which is wrong. */
+ buffer_address[0] = 0x00; /* branch offset = 4 */
+ buffer_address[1] = 0x04;
+ buffer_address[2] = 0x60; /* put in bra pc + ... */
+
+ if (flag_short_refs)
+ {
+ /* JF: these were fr_opcode[5-7] */
+ buffer_address[3] = 0x04; /* plus 4 */
+ buffer_address[4] = 0x4e; /* Put in Jump Word */
+ buffer_address[5] = (char) 0xf8;
+ fragP->fr_fix += 6; /* account for bra/jmp instruction */
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 2;
+ }
+ else
+ {
+ /* JF: these were fr_opcode[5-7] */
+ buffer_address[3] = 0x06; /* Plus 6 */
+ buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */
+ buffer_address[5] = (char) 0xf9;
+ fragP->fr_fix += 6; /* account for bra/jmp instruction */
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 0, NO_RELOC);
+ fragP->fr_fix += 4;
+ }
+
+ frag_wane (fragP);
+ break;
+ } /* case TAB(DBCC,SZ_UNDEF) */
+
+ case TAB (PCLEA, SZ_UNDEF):
+ {
+ if (((S_GET_SEGMENT (fragP->fr_symbol)) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ || flag_short_refs
+ || cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200)
+ {
+ fragP->fr_subtype = TAB (PCLEA, SHORT);
+ fragP->fr_var += 2;
+ }
+ else
+ {
+ fragP->fr_subtype = TAB (PCLEA, LONG);
+ fragP->fr_var += 6;
+ }
+ break;
+ } /* TAB(PCLEA,SZ_UNDEF) */
+
+ case TAB (PCINDEX, SZ_UNDEF):
+ if ((S_GET_SEGMENT (fragP->fr_symbol) == segment
+ && relaxable_symbol (fragP->fr_symbol))
+ || cpu_of_arch (current_architecture) < m68020
+ || cpu_of_arch (current_architecture) == mcf5200)
+ {
+ fragP->fr_subtype = TAB (PCINDEX, BYTE);
+ }
+ else
+ {
+ fragP->fr_subtype = TAB (PCINDEX, LONG);
+ fragP->fr_var += 4;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* now that SZ_UNDEF are taken care of, check others */
+ switch (fragP->fr_subtype)
+ {
+ case TAB (BCC68000, BYTE):
+ case TAB (ABRANCH, BYTE):
+ /* We can't do a short jump to the next instruction, so in that
+ case we force word mode. At this point S_GET_VALUE should
+ return the offset of the symbol within its frag. If the
+ symbol is at the start of a frag, and it is the next frag
+ with any data in it (usually this is just the next frag, but
+ assembler listings may introduce empty frags), we must use
+ word mode. */
+ if (fragP->fr_symbol && S_GET_VALUE (fragP->fr_symbol) == 0)
+ {
+ fragS *l;
+
+ for (l = fragP->fr_next;
+ l != fragP->fr_symbol->sy_frag;
+ l = l->fr_next)
+ if (l->fr_fix + l->fr_var != 0)
+ break;
+ if (l == fragP->fr_symbol->sy_frag)
+ {
+ fragP->fr_subtype = TAB (TABTYPE (fragP->fr_subtype), SHORT);
+ fragP->fr_var += 2;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return fragP->fr_var + fragP->fr_fix - old_fix;
+}
+
+#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
+/* the bit-field entries in the relocation_info struct plays hell
+ with the byte-order problems of cross-assembly. So as a hack,
+ I added this mach. dependent ri twiddler. Ugly, but it gets
+ you there. -KWK */
+/* on m68k: first 4 bytes are normal unsigned long, next three bytes
+ are symbolnum, most sig. byte first. Last byte is broken up with
+ bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower
+ nibble as nuthin. (on Sun 3 at least) */
+/* Translate the internal relocation information into target-specific
+ format. */
+#ifdef comment
+void
+md_ri_to_chars (the_bytes, ri)
+ char *the_bytes;
+ struct reloc_info_generic *ri;
+{
+ /* this is easy */
+ md_number_to_chars (the_bytes, ri->r_address, 4);
+ /* now the fun stuff */
+ the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff;
+ the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff;
+ the_bytes[6] = ri->r_symbolnum & 0x0ff;
+ the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) |
+ ((ri->r_extern << 4) & 0x10));
+}
+
+#endif /* comment */
+
+#ifndef BFD_ASSEMBLER
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ /*
+ * In: length of relocation (or of address) in chars: 1, 2 or 4.
+ * Out: GNU LD relocation length code: 0, 1, or 2.
+ */
+
+ static CONST unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
+ long r_symbolnum;
+
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ where[4] = (r_symbolnum >> 16) & 0x0ff;
+ where[5] = (r_symbolnum >> 8) & 0x0ff;
+ where[6] = r_symbolnum & 0x0ff;
+ where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) |
+ (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10));
+}
+#endif
+
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+#ifndef WORKING_DOT_WORD
+CONST int md_short_jump_size = 4;
+CONST int md_long_jump_size = 6;
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ offset = to_addr - (from_addr + 2);
+
+ md_number_to_chars (ptr, (valueT) 0x6000, 2);
+ md_number_to_chars (ptr + 2, (valueT) offset, 2);
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ if (!HAVE_LONG_BRANCH(current_architecture))
+ {
+ offset = to_addr - S_GET_VALUE (to_symbol);
+ md_number_to_chars (ptr, (valueT) 0x4EF9, 2);
+ md_number_to_chars (ptr + 2, (valueT) offset, 4);
+ fix_new (frag, (ptr + 2) - frag->fr_literal, 4, to_symbol, (offsetT) 0,
+ 0, NO_RELOC);
+ }
+ else
+ {
+ offset = to_addr - (from_addr + 2);
+ md_number_to_chars (ptr, (valueT) 0x60ff, 2);
+ md_number_to_chars (ptr + 2, (valueT) offset, 4);
+ }
+}
+
+#endif
+
+/* Different values of OK tell what its OK to return. Things that
+ aren't OK are an error (what a shock, no?)
+
+ 0: Everything is OK
+ 10: Absolute 1:8 only
+ 20: Absolute 0:7 only
+ 30: absolute 0:15 only
+ 40: Absolute 0:31 only
+ 50: absolute 0:127 only
+ 55: absolute -64:63 only
+ 60: absolute -128:127 only
+ 70: absolute 0:4095 only
+ 80: No bignums
+
+ */
+
+static int
+get_num (exp, ok)
+ struct m68k_exp *exp;
+ int ok;
+{
+ if (exp->exp.X_op == O_absent)
+ {
+ /* Do the same thing the VAX asm does */
+ op (exp) = O_constant;
+ adds (exp) = 0;
+ subs (exp) = 0;
+ offs (exp) = 0;
+ if (ok == 10)
+ {
+ as_warn (_("expression out of range: defaulting to 1"));
+ offs (exp) = 1;
+ }
+ }
+ else if (exp->exp.X_op == O_constant)
+ {
+ switch (ok)
+ {
+ case 10:
+ if (offs (exp) < 1 || offs (exp) > 8)
+ {
+ as_warn (_("expression out of range: defaulting to 1"));
+ offs (exp) = 1;
+ }
+ break;
+ case 20:
+ if (offs (exp) < 0 || offs (exp) > 7)
+ goto outrange;
+ break;
+ case 30:
+ if (offs (exp) < 0 || offs (exp) > 15)
+ goto outrange;
+ break;
+ case 40:
+ if (offs (exp) < 0 || offs (exp) > 32)
+ goto outrange;
+ break;
+ case 50:
+ if (offs (exp) < 0 || offs (exp) > 127)
+ goto outrange;
+ break;
+ case 55:
+ if (offs (exp) < -64 || offs (exp) > 63)
+ goto outrange;
+ break;
+ case 60:
+ if (offs (exp) < -128 || offs (exp) > 127)
+ goto outrange;
+ break;
+ case 70:
+ if (offs (exp) < 0 || offs (exp) > 4095)
+ {
+ outrange:
+ as_warn (_("expression out of range: defaulting to 0"));
+ offs (exp) = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else if (exp->exp.X_op == O_big)
+ {
+ if (offs (exp) <= 0 /* flonum */
+ && (ok == 80 /* no bignums */
+ || (ok > 10 /* small-int ranges including 0 ok */
+ /* If we have a flonum zero, a zero integer should
+ do as well (e.g., in moveq). */
+ && generic_floating_point_number.exponent == 0
+ && generic_floating_point_number.low[0] == 0)))
+ {
+ /* HACK! Turn it into a long */
+ LITTLENUM_TYPE words[6];
+
+ gen_to_words (words, 2, 8L); /* These numbers are magic! */
+ op (exp) = O_constant;
+ adds (exp) = 0;
+ subs (exp) = 0;
+ offs (exp) = words[1] | (words[0] << 16);
+ }
+ else if (ok != 0)
+ {
+ op (exp) = O_constant;
+ adds (exp) = 0;
+ subs (exp) = 0;
+ offs (exp) = (ok == 10) ? 1 : 0;
+ as_warn (_("Can't deal with expression; defaulting to %ld"),
+ offs (exp));
+ }
+ }
+ else
+ {
+ if (ok >= 10 && ok <= 70)
+ {
+ op (exp) = O_constant;
+ adds (exp) = 0;
+ subs (exp) = 0;
+ offs (exp) = (ok == 10) ? 1 : 0;
+ as_warn (_("Can't deal with expression; defaulting to %ld"),
+ offs (exp));
+ }
+ }
+
+ if (exp->size != SIZE_UNSPEC)
+ {
+ switch (exp->size)
+ {
+ case SIZE_UNSPEC:
+ case SIZE_LONG:
+ break;
+ case SIZE_BYTE:
+ if (!isbyte (offs (exp)))
+ as_warn (_("expression doesn't fit in BYTE"));
+ break;
+ case SIZE_WORD:
+ if (!isword (offs (exp)))
+ as_warn (_("expression doesn't fit in WORD"));
+ break;
+ }
+ }
+
+ return offs (exp);
+}
+
+/* These are the back-ends for the various machine dependent pseudo-ops. */
+
+static void
+s_data1 (ignore)
+ int ignore;
+{
+ subseg_set (data_section, 1);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_data2 (ignore)
+ int ignore;
+{
+ subseg_set (data_section, 2);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_bss (ignore)
+ int ignore;
+{
+ /* We don't support putting frags in the BSS segment, we fake it
+ by marking in_bss, then looking at s_skip for clues. */
+
+ subseg_set (bss_section, 0);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_even (ignore)
+ int ignore;
+{
+ register int temp;
+ register long temp_fill;
+
+ temp = 1; /* JF should be 2? */
+ temp_fill = get_absolute_expression ();
+ if (!need_pass_2) /* Never make frag if expect extra pass. */
+ frag_align (temp, (int) temp_fill, 0);
+ demand_empty_rest_of_line ();
+ record_alignment (now_seg, temp);
+}
+
+static void
+s_proc (ignore)
+ int ignore;
+{
+ demand_empty_rest_of_line ();
+}
+
+/* Pseudo-ops handled for MRI compatibility. */
+
+/* This function returns non-zero if the argument is a conditional
+ pseudo-op. This is called when checking whether a pending
+ alignment is needed. */
+
+int
+m68k_conditional_pseudoop (pop)
+ pseudo_typeS *pop;
+{
+ return (pop->poc_handler == s_mri_if
+ || pop->poc_handler == s_mri_else);
+}
+
+/* Handle an MRI style chip specification. */
+
+static void
+mri_chip ()
+{
+ char *s;
+ char c;
+ int i;
+
+ s = input_line_pointer;
+ /* We can't use get_symbol_end since the processor names are not proper
+ symbols. */
+ while (is_part_of_name (c = *input_line_pointer++))
+ ;
+ *--input_line_pointer = 0;
+ for (i = 0; i < n_archs; i++)
+ if (strcasecmp (s, archs[i].name) == 0)
+ break;
+ if (i >= n_archs)
+ {
+ as_bad (_("%s: unrecognized processor name"), s);
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ *input_line_pointer = c;
+
+ if (*input_line_pointer == '/')
+ current_architecture = 0;
+ else
+ current_architecture &= m68881 | m68851;
+ current_architecture |= archs[i].arch;
+
+ while (*input_line_pointer == '/')
+ {
+ ++input_line_pointer;
+ s = input_line_pointer;
+ /* We can't use get_symbol_end since the processor names are not
+ proper symbols. */
+ while (is_part_of_name (c = *input_line_pointer++))
+ ;
+ *--input_line_pointer = 0;
+ if (strcmp (s, "68881") == 0)
+ current_architecture |= m68881;
+ else if (strcmp (s, "68851") == 0)
+ current_architecture |= m68851;
+ *input_line_pointer = c;
+ }
+
+ /* Update info about available control registers. */
+ select_control_regs ();
+}
+
+/* The MRI CHIP pseudo-op. */
+
+static void
+s_chip (ignore)
+ int ignore;
+{
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+ mri_chip ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ demand_empty_rest_of_line ();
+}
+
+/* The MRI FOPT pseudo-op. */
+
+static void
+s_fopt (ignore)
+ int ignore;
+{
+ SKIP_WHITESPACE ();
+
+ if (strncasecmp (input_line_pointer, "ID=", 3) == 0)
+ {
+ int temp;
+
+ input_line_pointer += 3;
+ temp = get_absolute_expression ();
+ if (temp < 0 || temp > 7)
+ as_bad (_("bad coprocessor id"));
+ else
+ m68k_float_copnum = COP0 + temp;
+ }
+ else
+ {
+ as_bad (_("unrecognized fopt option"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The structure used to handle the MRI OPT pseudo-op. */
+
+struct opt_action
+{
+ /* The name of the option. */
+ const char *name;
+
+ /* If this is not NULL, just call this function. The first argument
+ is the ARG field of this structure, the second argument is
+ whether the option was negated. */
+ void (*pfn) PARAMS ((int arg, int on));
+
+ /* If this is not NULL, and the PFN field is NULL, set the variable
+ this points to. Set it to the ARG field if the option was not
+ negated, and the NOTARG field otherwise. */
+ int *pvar;
+
+ /* The value to pass to PFN or to assign to *PVAR. */
+ int arg;
+
+ /* The value to assign to *PVAR if the option is negated. If PFN is
+ NULL, and PVAR is not NULL, and ARG and NOTARG are the same, then
+ the option may not be negated. */
+ int notarg;
+};
+
+/* The table used to handle the MRI OPT pseudo-op. */
+
+static void skip_to_comma PARAMS ((int, int));
+static void opt_nest PARAMS ((int, int));
+static void opt_chip PARAMS ((int, int));
+static void opt_list PARAMS ((int, int));
+static void opt_list_symbols PARAMS ((int, int));
+
+static const struct opt_action opt_table[] =
+{
+ { "abspcadd", 0, &m68k_abspcadd, 1, 0 },
+
+ /* We do relaxing, so there is little use for these options. */
+ { "b", 0, 0, 0, 0 },
+ { "brs", 0, 0, 0, 0 },
+ { "brb", 0, 0, 0, 0 },
+ { "brl", 0, 0, 0, 0 },
+ { "brw", 0, 0, 0, 0 },
+
+ { "c", 0, 0, 0, 0 },
+ { "cex", 0, 0, 0, 0 },
+ { "case", 0, &symbols_case_sensitive, 1, 0 },
+ { "cl", 0, 0, 0, 0 },
+ { "cre", 0, 0, 0, 0 },
+ { "d", 0, &flag_keep_locals, 1, 0 },
+ { "e", 0, 0, 0, 0 },
+ { "f", 0, &flag_short_refs, 1, 0 },
+ { "frs", 0, &flag_short_refs, 1, 0 },
+ { "frl", 0, &flag_short_refs, 0, 1 },
+ { "g", 0, 0, 0, 0 },
+ { "i", 0, 0, 0, 0 },
+ { "m", 0, 0, 0, 0 },
+ { "mex", 0, 0, 0, 0 },
+ { "mc", 0, 0, 0, 0 },
+ { "md", 0, 0, 0, 0 },
+ { "nest", opt_nest, 0, 0, 0 },
+ { "next", skip_to_comma, 0, 0, 0 },
+ { "o", 0, 0, 0, 0 },
+ { "old", 0, 0, 0, 0 },
+ { "op", skip_to_comma, 0, 0, 0 },
+ { "pco", 0, 0, 0, 0 },
+ { "p", opt_chip, 0, 0, 0 },
+ { "pcr", 0, 0, 0, 0 },
+ { "pcs", 0, 0, 0, 0 },
+ { "r", 0, 0, 0, 0 },
+ { "quick", 0, &m68k_quick, 1, 0 },
+ { "rel32", 0, &m68k_rel32, 1, 0 },
+ { "s", opt_list, 0, 0, 0 },
+ { "t", opt_list_symbols, 0, 0, 0 },
+ { "w", 0, &flag_no_warnings, 0, 1 },
+ { "x", 0, 0, 0, 0 }
+};
+
+#define OPTCOUNT (sizeof opt_table / sizeof opt_table[0])
+
+/* The MRI OPT pseudo-op. */
+
+static void
+s_opt (ignore)
+ int ignore;
+{
+ do
+ {
+ int t;
+ char *s;
+ char c;
+ int i;
+ const struct opt_action *o;
+
+ SKIP_WHITESPACE ();
+
+ t = 1;
+ if (*input_line_pointer == '-')
+ {
+ ++input_line_pointer;
+ t = 0;
+ }
+ else if (strncasecmp (input_line_pointer, "NO", 2) == 0)
+ {
+ input_line_pointer += 2;
+ t = 0;
+ }
+
+ s = input_line_pointer;
+ c = get_symbol_end ();
+
+ for (i = 0, o = opt_table; i < OPTCOUNT; i++, o++)
+ {
+ if (strcasecmp (s, o->name) == 0)
+ {
+ if (o->pfn)
+ {
+ /* Restore input_line_pointer now in case the option
+ takes arguments. */
+ *input_line_pointer = c;
+ (*o->pfn) (o->arg, t);
+ }
+ else if (o->pvar != NULL)
+ {
+ if (! t && o->arg == o->notarg)
+ as_bad (_("option `%s' may not be negated"), s);
+ *input_line_pointer = c;
+ *o->pvar = t ? o->arg : o->notarg;
+ }
+ else
+ *input_line_pointer = c;
+ break;
+ }
+ }
+ if (i >= OPTCOUNT)
+ {
+ as_bad (_("option `%s' not recognized"), s);
+ *input_line_pointer = c;
+ }
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* Move back to terminating character. */
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+}
+
+/* Skip ahead to a comma. This is used for OPT options which we do
+ not suppor tand which take arguments. */
+
+static void
+skip_to_comma (arg, on)
+ int arg;
+ int on;
+{
+ while (*input_line_pointer != ','
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+}
+
+/* Handle the OPT NEST=depth option. */
+
+static void
+opt_nest (arg, on)
+ int arg;
+ int on;
+{
+ if (*input_line_pointer != '=')
+ {
+ as_bad (_("bad format of OPT NEST=depth"));
+ return;
+ }
+
+ ++input_line_pointer;
+ max_macro_nest = get_absolute_expression ();
+}
+
+/* Handle the OPT P=chip option. */
+
+static void
+opt_chip (arg, on)
+ int arg;
+ int on;
+{
+ if (*input_line_pointer != '=')
+ {
+ /* This is just OPT P, which we do not support. */
+ return;
+ }
+
+ ++input_line_pointer;
+ mri_chip ();
+}
+
+/* Handle the OPT S option. */
+
+static void
+opt_list (arg, on)
+ int arg;
+ int on;
+{
+ listing_list (on);
+}
+
+/* Handle the OPT T option. */
+
+static void
+opt_list_symbols (arg, on)
+ int arg;
+ int on;
+{
+ if (on)
+ listing |= LISTING_SYMBOLS;
+ else
+ listing &=~ LISTING_SYMBOLS;
+}
+
+/* Handle the MRI REG pseudo-op. */
+
+static void
+s_reg (ignore)
+ int ignore;
+{
+ char *s;
+ int c;
+ struct m68k_op rop;
+ int mask;
+ char *stop = NULL;
+ char stopc;
+
+ if (line_label == NULL)
+ {
+ as_bad (_("missing label"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ SKIP_WHITESPACE ();
+
+ s = input_line_pointer;
+ while (isalnum ((unsigned char) *input_line_pointer)
+#ifdef REGISTER_PREFIX
+ || *input_line_pointer == REGISTER_PREFIX
+#endif
+ || *input_line_pointer == '/'
+ || *input_line_pointer == '-')
+ ++input_line_pointer;
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (m68k_ip_op (s, &rop) != 0)
+ {
+ if (rop.error == NULL)
+ as_bad (_("bad register list"));
+ else
+ as_bad (_("bad register list: %s"), rop.error);
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = c;
+
+ if (rop.mode == REGLST)
+ mask = rop.mask;
+ else if (rop.mode == DREG)
+ mask = 1 << (rop.reg - DATA0);
+ else if (rop.mode == AREG)
+ mask = 1 << (rop.reg - ADDR0 + 8);
+ else if (rop.mode == FPREG)
+ mask = 1 << (rop.reg - FP0 + 16);
+ else if (rop.mode == CONTROL
+ && rop.reg == FPI)
+ mask = 1 << 24;
+ else if (rop.mode == CONTROL
+ && rop.reg == FPS)
+ mask = 1 << 25;
+ else if (rop.mode == CONTROL
+ && rop.reg == FPC)
+ mask = 1 << 26;
+ else
+ {
+ as_bad (_("bad register list"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ S_SET_SEGMENT (line_label, reg_section);
+ S_SET_VALUE (line_label, ~mask);
+ line_label->sy_frag = &zero_address_frag;
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+}
+
+/* This structure is used for the MRI SAVE and RESTORE pseudo-ops. */
+
+struct save_opts
+{
+ struct save_opts *next;
+ int abspcadd;
+ int symbols_case_sensitive;
+ int keep_locals;
+ int short_refs;
+ int architecture;
+ int quick;
+ int rel32;
+ int listing;
+ int no_warnings;
+ /* FIXME: We don't save OPT S. */
+};
+
+/* This variable holds the stack of saved options. */
+
+static struct save_opts *save_stack;
+
+/* The MRI SAVE pseudo-op. */
+
+static void
+s_save (ignore)
+ int ignore;
+{
+ struct save_opts *s;
+
+ s = (struct save_opts *) xmalloc (sizeof (struct save_opts));
+ s->abspcadd = m68k_abspcadd;
+ s->symbols_case_sensitive = symbols_case_sensitive;
+ s->keep_locals = flag_keep_locals;
+ s->short_refs = flag_short_refs;
+ s->architecture = current_architecture;
+ s->quick = m68k_quick;
+ s->rel32 = m68k_rel32;
+ s->listing = listing;
+ s->no_warnings = flag_no_warnings;
+
+ s->next = save_stack;
+ save_stack = s;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The MRI RESTORE pseudo-op. */
+
+static void
+s_restore (ignore)
+ int ignore;
+{
+ struct save_opts *s;
+
+ if (save_stack == NULL)
+ {
+ as_bad (_("restore without save"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ s = save_stack;
+ save_stack = s->next;
+
+ m68k_abspcadd = s->abspcadd;
+ symbols_case_sensitive = s->symbols_case_sensitive;
+ flag_keep_locals = s->keep_locals;
+ flag_short_refs = s->short_refs;
+ current_architecture = s->architecture;
+ m68k_quick = s->quick;
+ m68k_rel32 = s->rel32;
+ listing = s->listing;
+ flag_no_warnings = s->no_warnings;
+
+ free (s);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Types of MRI structured control directives. */
+
+enum mri_control_type
+{
+ mri_for,
+ mri_if,
+ mri_repeat,
+ mri_while
+};
+
+/* This structure is used to stack the MRI structured control
+ directives. */
+
+struct mri_control_info
+{
+ /* The directive within which this one is enclosed. */
+ struct mri_control_info *outer;
+
+ /* The type of directive. */
+ enum mri_control_type type;
+
+ /* Whether an ELSE has been in an IF. */
+ int else_seen;
+
+ /* The add or sub statement at the end of a FOR. */
+ char *incr;
+
+ /* The label of the top of a FOR or REPEAT loop. */
+ char *top;
+
+ /* The label to jump to for the next iteration, or the else
+ expression of a conditional. */
+ char *next;
+
+ /* The label to jump to to break out of the loop, or the label past
+ the end of a conditional. */
+ char *bottom;
+};
+
+/* The stack of MRI structured control directives. */
+
+static struct mri_control_info *mri_control_stack;
+
+/* The current MRI structured control directive index number, used to
+ generate label names. */
+
+static int mri_control_index;
+
+/* Some function prototypes. */
+
+static void mri_assemble PARAMS ((char *));
+static char *mri_control_label PARAMS ((void));
+static struct mri_control_info *push_mri_control
+ PARAMS ((enum mri_control_type));
+static void pop_mri_control PARAMS ((void));
+static int parse_mri_condition PARAMS ((int *));
+static int parse_mri_control_operand
+ PARAMS ((int *, char **, char **, char **, char **));
+static int swap_mri_condition PARAMS ((int));
+static int reverse_mri_condition PARAMS ((int));
+static void build_mri_control_operand
+ PARAMS ((int, int, char *, char *, char *, char *, const char *,
+ const char *, int));
+static void parse_mri_control_expression
+ PARAMS ((char *, int, const char *, const char *, int));
+
+/* Assemble an instruction for an MRI structured control directive. */
+
+static void
+mri_assemble (str)
+ char *str;
+{
+ char *s;
+
+ /* md_assemble expects the opcode to be in lower case. */
+ for (s = str; *s != ' ' && *s != '\0'; s++)
+ {
+ if (isupper ((unsigned char) *s))
+ *s = tolower ((unsigned char) *s);
+ }
+
+ md_assemble (str);
+}
+
+/* Generate a new MRI label structured control directive label name. */
+
+static char *
+mri_control_label ()
+{
+ char *n;
+
+ n = (char *) xmalloc (20);
+ sprintf (n, "%smc%d", FAKE_LABEL_NAME, mri_control_index);
+ ++mri_control_index;
+ return n;
+}
+
+/* Create a new MRI structured control directive. */
+
+static struct mri_control_info *
+push_mri_control (type)
+ enum mri_control_type type;
+{
+ struct mri_control_info *n;
+
+ n = (struct mri_control_info *) xmalloc (sizeof (struct mri_control_info));
+
+ n->type = type;
+ n->else_seen = 0;
+ if (type == mri_if || type == mri_while)
+ n->top = NULL;
+ else
+ n->top = mri_control_label ();
+ n->next = mri_control_label ();
+ n->bottom = mri_control_label ();
+
+ n->outer = mri_control_stack;
+ mri_control_stack = n;
+
+ return n;
+}
+
+/* Pop off the stack of MRI structured control directives. */
+
+static void
+pop_mri_control ()
+{
+ struct mri_control_info *n;
+
+ n = mri_control_stack;
+ mri_control_stack = n->outer;
+ if (n->top != NULL)
+ free (n->top);
+ free (n->next);
+ free (n->bottom);
+ free (n);
+}
+
+/* Recognize a condition code in an MRI structured control expression. */
+
+static int
+parse_mri_condition (pcc)
+ int *pcc;
+{
+ char c1, c2;
+
+ know (*input_line_pointer == '<');
+
+ ++input_line_pointer;
+ c1 = *input_line_pointer++;
+ c2 = *input_line_pointer++;
+
+ if (*input_line_pointer != '>')
+ {
+ as_bad (_("syntax error in structured control directive"));
+ return 0;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ if (isupper (c1))
+ c1 = tolower (c1);
+ if (isupper (c2))
+ c2 = tolower (c2);
+
+ *pcc = (c1 << 8) | c2;
+
+ return 1;
+}
+
+/* Parse a single operand in an MRI structured control expression. */
+
+static int
+parse_mri_control_operand (pcc, leftstart, leftstop, rightstart, rightstop)
+ int *pcc;
+ char **leftstart;
+ char **leftstop;
+ char **rightstart;
+ char **rightstop;
+{
+ char *s;
+
+ SKIP_WHITESPACE ();
+
+ *pcc = -1;
+ *leftstart = NULL;
+ *leftstop = NULL;
+ *rightstart = NULL;
+ *rightstop = NULL;
+
+ if (*input_line_pointer == '<')
+ {
+ /* It's just a condition code. */
+ return parse_mri_condition (pcc);
+ }
+
+ /* Look ahead for the condition code. */
+ for (s = input_line_pointer; *s != '\0'; ++s)
+ {
+ if (*s == '<' && s[1] != '\0' && s[2] != '\0' && s[3] == '>')
+ break;
+ }
+ if (*s == '\0')
+ {
+ as_bad (_("missing condition code in structured control directive"));
+ return 0;
+ }
+
+ *leftstart = input_line_pointer;
+ *leftstop = s;
+ if (*leftstop > *leftstart
+ && ((*leftstop)[-1] == ' ' || (*leftstop)[-1] == '\t'))
+ --*leftstop;
+
+ input_line_pointer = s;
+ if (! parse_mri_condition (pcc))
+ return 0;
+
+ /* Look ahead for AND or OR or end of line. */
+ for (s = input_line_pointer; *s != '\0'; ++s)
+ {
+ if ((strncasecmp (s, "AND", 3) == 0
+ && (s[3] == '.' || ! is_part_of_name (s[3])))
+ || (strncasecmp (s, "OR", 2) == 0
+ && (s[2] == '.' || ! is_part_of_name (s[2]))))
+ break;
+ }
+
+ *rightstart = input_line_pointer;
+ *rightstop = s;
+ if (*rightstop > *rightstart
+ && ((*rightstop)[-1] == ' ' || (*rightstop)[-1] == '\t'))
+ --*rightstop;
+
+ input_line_pointer = s;
+
+ return 1;
+}
+
+#define MCC(b1, b2) (((b1) << 8) | (b2))
+
+/* Swap the sense of a condition. This changes the condition so that
+ it generates the same result when the operands are swapped. */
+
+static int
+swap_mri_condition (cc)
+ int cc;
+{
+ switch (cc)
+ {
+ case MCC ('h', 'i'): return MCC ('c', 's');
+ case MCC ('l', 's'): return MCC ('c', 'c');
+ case MCC ('c', 'c'): return MCC ('l', 's');
+ case MCC ('c', 's'): return MCC ('h', 'i');
+ case MCC ('p', 'l'): return MCC ('m', 'i');
+ case MCC ('m', 'i'): return MCC ('p', 'l');
+ case MCC ('g', 'e'): return MCC ('l', 'e');
+ case MCC ('l', 't'): return MCC ('g', 't');
+ case MCC ('g', 't'): return MCC ('l', 't');
+ case MCC ('l', 'e'): return MCC ('g', 'e');
+ }
+ return cc;
+}
+
+/* Reverse the sense of a condition. */
+
+static int
+reverse_mri_condition (cc)
+ int cc;
+{
+ switch (cc)
+ {
+ case MCC ('h', 'i'): return MCC ('l', 's');
+ case MCC ('l', 's'): return MCC ('h', 'i');
+ case MCC ('c', 'c'): return MCC ('c', 's');
+ case MCC ('c', 's'): return MCC ('c', 'c');
+ case MCC ('n', 'e'): return MCC ('e', 'q');
+ case MCC ('e', 'q'): return MCC ('n', 'e');
+ case MCC ('v', 'c'): return MCC ('v', 's');
+ case MCC ('v', 's'): return MCC ('v', 'c');
+ case MCC ('p', 'l'): return MCC ('m', 'i');
+ case MCC ('m', 'i'): return MCC ('p', 'l');
+ case MCC ('g', 'e'): return MCC ('l', 't');
+ case MCC ('l', 't'): return MCC ('g', 'e');
+ case MCC ('g', 't'): return MCC ('l', 'e');
+ case MCC ('l', 'e'): return MCC ('g', 't');
+ }
+ return cc;
+}
+
+/* Build an MRI structured control expression. This generates test
+ and branch instructions. It goes to TRUELAB if the condition is
+ true, and to FALSELAB if the condition is false. Exactly one of
+ TRUELAB and FALSELAB will be NULL, meaning to fall through. QUAL
+ is the size qualifier for the expression. EXTENT is the size to
+ use for the branch. */
+
+static void
+build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart,
+ rightstop, truelab, falselab, extent)
+ int qual;
+ int cc;
+ char *leftstart;
+ char *leftstop;
+ char *rightstart;
+ char *rightstop;
+ const char *truelab;
+ const char *falselab;
+ int extent;
+{
+ char *buf;
+ char *s;
+
+ if (leftstart != NULL)
+ {
+ struct m68k_op leftop, rightop;
+ char c;
+
+ /* Swap the compare operands, if necessary, to produce a legal
+ m68k compare instruction. Comparing a register operand with
+ a non-register operand requires the register to be on the
+ right (cmp, cmpa). Comparing an immediate value with
+ anything requires the immediate value to be on the left
+ (cmpi). */
+
+ c = *leftstop;
+ *leftstop = '\0';
+ (void) m68k_ip_op (leftstart, &leftop);
+ *leftstop = c;
+
+ c = *rightstop;
+ *rightstop = '\0';
+ (void) m68k_ip_op (rightstart, &rightop);
+ *rightstop = c;
+
+ if (rightop.mode == IMMED
+ || ((leftop.mode == DREG || leftop.mode == AREG)
+ && (rightop.mode != DREG && rightop.mode != AREG)))
+ {
+ char *temp;
+
+ cc = swap_mri_condition (cc);
+ temp = leftstart;
+ leftstart = rightstart;
+ rightstart = temp;
+ temp = leftstop;
+ leftstop = rightstop;
+ rightstop = temp;
+ }
+ }
+
+ if (truelab == NULL)
+ {
+ cc = reverse_mri_condition (cc);
+ truelab = falselab;
+ }
+
+ if (leftstart != NULL)
+ {
+ buf = (char *) xmalloc (20
+ + (leftstop - leftstart)
+ + (rightstop - rightstart));
+ s = buf;
+ *s++ = 'c';
+ *s++ = 'm';
+ *s++ = 'p';
+ if (qual != '\0')
+ *s++ = qual;
+ *s++ = ' ';
+ memcpy (s, leftstart, leftstop - leftstart);
+ s += leftstop - leftstart;
+ *s++ = ',';
+ memcpy (s, rightstart, rightstop - rightstart);
+ s += rightstop - rightstart;
+ *s = '\0';
+ mri_assemble (buf);
+ free (buf);
+ }
+
+ buf = (char *) xmalloc (20 + strlen (truelab));
+ s = buf;
+ *s++ = 'b';
+ *s++ = cc >> 8;
+ *s++ = cc & 0xff;
+ if (extent != '\0')
+ *s++ = extent;
+ *s++ = ' ';
+ strcpy (s, truelab);
+ mri_assemble (buf);
+ free (buf);
+}
+
+/* Parse an MRI structured control expression. This generates test
+ and branch instructions. STOP is where the expression ends. It
+ goes to TRUELAB if the condition is true, and to FALSELAB if the
+ condition is false. Exactly one of TRUELAB and FALSELAB will be
+ NULL, meaning to fall through. QUAL is the size qualifier for the
+ expression. EXTENT is the size to use for the branch. */
+
+static void
+parse_mri_control_expression (stop, qual, truelab, falselab, extent)
+ char *stop;
+ int qual;
+ const char *truelab;
+ const char *falselab;
+ int extent;
+{
+ int c;
+ int cc;
+ char *leftstart;
+ char *leftstop;
+ char *rightstart;
+ char *rightstop;
+
+ c = *stop;
+ *stop = '\0';
+
+ if (! parse_mri_control_operand (&cc, &leftstart, &leftstop,
+ &rightstart, &rightstop))
+ {
+ *stop = c;
+ return;
+ }
+
+ if (strncasecmp (input_line_pointer, "AND", 3) == 0)
+ {
+ const char *flab;
+
+ if (falselab != NULL)
+ flab = falselab;
+ else
+ flab = mri_control_label ();
+
+ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart,
+ rightstop, (const char *) NULL, flab, extent);
+
+ input_line_pointer += 3;
+ if (*input_line_pointer != '.'
+ || input_line_pointer[1] == '\0')
+ qual = '\0';
+ else
+ {
+ qual = input_line_pointer[1];
+ input_line_pointer += 2;
+ }
+
+ if (! parse_mri_control_operand (&cc, &leftstart, &leftstop,
+ &rightstart, &rightstop))
+ {
+ *stop = c;
+ return;
+ }
+
+ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart,
+ rightstop, truelab, falselab, extent);
+
+ if (falselab == NULL)
+ colon (flab);
+ }
+ else if (strncasecmp (input_line_pointer, "OR", 2) == 0)
+ {
+ const char *tlab;
+
+ if (truelab != NULL)
+ tlab = truelab;
+ else
+ tlab = mri_control_label ();
+
+ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart,
+ rightstop, tlab, (const char *) NULL, extent);
+
+ input_line_pointer += 2;
+ if (*input_line_pointer != '.'
+ || input_line_pointer[1] == '\0')
+ qual = '\0';
+ else
+ {
+ qual = input_line_pointer[1];
+ input_line_pointer += 2;
+ }
+
+ if (! parse_mri_control_operand (&cc, &leftstart, &leftstop,
+ &rightstart, &rightstop))
+ {
+ *stop = c;
+ return;
+ }
+
+ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart,
+ rightstop, truelab, falselab, extent);
+
+ if (truelab == NULL)
+ colon (tlab);
+ }
+ else
+ {
+ build_mri_control_operand (qual, cc, leftstart, leftstop, rightstart,
+ rightstop, truelab, falselab, extent);
+ }
+
+ *stop = c;
+ if (input_line_pointer != stop)
+ as_bad (_("syntax error in structured control directive"));
+}
+
+/* Handle the MRI IF pseudo-op. This may be a structured control
+ directive, or it may be a regular assembler conditional, depending
+ on its operands. */
+
+static void
+s_mri_if (qual)
+ int qual;
+{
+ char *s;
+ int c;
+ struct mri_control_info *n;
+
+ /* A structured control directive must end with THEN with an
+ optional qualifier. */
+ s = input_line_pointer;
+ while (! is_end_of_line[(unsigned char) *s]
+ && (! flag_mri || *s != '*'))
+ ++s;
+ --s;
+ while (s > input_line_pointer && (*s == ' ' || *s == '\t'))
+ --s;
+
+ if (s - input_line_pointer > 1
+ && s[-1] == '.')
+ s -= 2;
+
+ if (s - input_line_pointer < 3
+ || strncasecmp (s - 3, "THEN", 4) != 0)
+ {
+ if (qual != '\0')
+ {
+ as_bad (_("missing then"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* It's a conditional. */
+ s_if (O_ne);
+ return;
+ }
+
+ /* Since this might be a conditional if, this pseudo-op will be
+ called even if we are supported to be ignoring input. Double
+ check now. Clobber *input_line_pointer so that ignore_input
+ thinks that this is not a special pseudo-op. */
+ c = *input_line_pointer;
+ *input_line_pointer = 0;
+ if (ignore_input ())
+ {
+ *input_line_pointer = c;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ *input_line_pointer = c;
+
+ n = push_mri_control (mri_if);
+
+ parse_mri_control_expression (s - 3, qual, (const char *) NULL,
+ n->next, s[1] == '.' ? s[2] : '\0');
+
+ if (s[1] == '.')
+ input_line_pointer = s + 3;
+ else
+ input_line_pointer = s + 1;
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI else pseudo-op. If we are currently doing an MRI
+ structured IF, associate the ELSE with the IF. Otherwise, assume
+ it is a conditional else. */
+
+static void
+s_mri_else (qual)
+ int qual;
+{
+ int c;
+ char *buf;
+ char q[2];
+
+ if (qual == '\0'
+ && (mri_control_stack == NULL
+ || mri_control_stack->type != mri_if
+ || mri_control_stack->else_seen))
+ {
+ s_else (0);
+ return;
+ }
+
+ c = *input_line_pointer;
+ *input_line_pointer = 0;
+ if (ignore_input ())
+ {
+ *input_line_pointer = c;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ *input_line_pointer = c;
+
+ if (mri_control_stack == NULL
+ || mri_control_stack->type != mri_if
+ || mri_control_stack->else_seen)
+ {
+ as_bad (_("else without matching if"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ mri_control_stack->else_seen = 1;
+
+ buf = (char *) xmalloc (20 + strlen (mri_control_stack->bottom));
+ q[0] = qual;
+ q[1] = '\0';
+ sprintf (buf, "bra%s %s", q, mri_control_stack->bottom);
+ mri_assemble (buf);
+ free (buf);
+
+ colon (mri_control_stack->next);
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI ENDI pseudo-op. */
+
+static void
+s_mri_endi (ignore)
+ int ignore;
+{
+ if (mri_control_stack == NULL
+ || mri_control_stack->type != mri_if)
+ {
+ as_bad (_("endi without matching if"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* ignore_input will not return true for ENDI, so we don't need to
+ worry about checking it again here. */
+
+ if (! mri_control_stack->else_seen)
+ colon (mri_control_stack->next);
+ colon (mri_control_stack->bottom);
+
+ pop_mri_control ();
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI BREAK pseudo-op. */
+
+static void
+s_mri_break (extent)
+ int extent;
+{
+ struct mri_control_info *n;
+ char *buf;
+ char ex[2];
+
+ n = mri_control_stack;
+ while (n != NULL
+ && n->type != mri_for
+ && n->type != mri_repeat
+ && n->type != mri_while)
+ n = n->outer;
+ if (n == NULL)
+ {
+ as_bad (_("break outside of structured loop"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ buf = (char *) xmalloc (20 + strlen (n->bottom));
+ ex[0] = extent;
+ ex[1] = '\0';
+ sprintf (buf, "bra%s %s", ex, n->bottom);
+ mri_assemble (buf);
+ free (buf);
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI NEXT pseudo-op. */
+
+static void
+s_mri_next (extent)
+ int extent;
+{
+ struct mri_control_info *n;
+ char *buf;
+ char ex[2];
+
+ n = mri_control_stack;
+ while (n != NULL
+ && n->type != mri_for
+ && n->type != mri_repeat
+ && n->type != mri_while)
+ n = n->outer;
+ if (n == NULL)
+ {
+ as_bad (_("next outside of structured loop"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ buf = (char *) xmalloc (20 + strlen (n->next));
+ ex[0] = extent;
+ ex[1] = '\0';
+ sprintf (buf, "bra%s %s", ex, n->next);
+ mri_assemble (buf);
+ free (buf);
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI FOR pseudo-op. */
+
+static void
+s_mri_for (qual)
+ int qual;
+{
+ const char *varstart, *varstop;
+ const char *initstart, *initstop;
+ const char *endstart, *endstop;
+ const char *bystart, *bystop;
+ int up;
+ int by;
+ int extent;
+ struct mri_control_info *n;
+ char *buf;
+ char *s;
+ char ex[2];
+
+ /* The syntax is
+ FOR.q var = init { TO | DOWNTO } end [ BY by ] DO.e
+ */
+
+ SKIP_WHITESPACE ();
+ varstart = input_line_pointer;
+
+ /* Look for the '='. */
+ while (! is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != '=')
+ ++input_line_pointer;
+ if (*input_line_pointer != '=')
+ {
+ as_bad (_("missing ="));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ varstop = input_line_pointer;
+ if (varstop > varstart
+ && (varstop[-1] == ' ' || varstop[-1] == '\t'))
+ --varstop;
+
+ ++input_line_pointer;
+
+ initstart = input_line_pointer;
+
+ /* Look for TO or DOWNTO. */
+ up = 1;
+ initstop = NULL;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (strncasecmp (input_line_pointer, "TO", 2) == 0
+ && ! is_part_of_name (input_line_pointer[2]))
+ {
+ initstop = input_line_pointer;
+ input_line_pointer += 2;
+ break;
+ }
+ if (strncasecmp (input_line_pointer, "DOWNTO", 6) == 0
+ && ! is_part_of_name (input_line_pointer[6]))
+ {
+ initstop = input_line_pointer;
+ up = 0;
+ input_line_pointer += 6;
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (initstop == NULL)
+ {
+ as_bad (_("missing to or downto"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (initstop > initstart
+ && (initstop[-1] == ' ' || initstop[-1] == '\t'))
+ --initstop;
+
+ SKIP_WHITESPACE ();
+ endstart = input_line_pointer;
+
+ /* Look for BY or DO. */
+ by = 0;
+ endstop = NULL;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (strncasecmp (input_line_pointer, "BY", 2) == 0
+ && ! is_part_of_name (input_line_pointer[2]))
+ {
+ endstop = input_line_pointer;
+ by = 1;
+ input_line_pointer += 2;
+ break;
+ }
+ if (strncasecmp (input_line_pointer, "DO", 2) == 0
+ && (input_line_pointer[2] == '.'
+ || ! is_part_of_name (input_line_pointer[2])))
+ {
+ endstop = input_line_pointer;
+ input_line_pointer += 2;
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (endstop == NULL)
+ {
+ as_bad (_("missing do"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (endstop > endstart
+ && (endstop[-1] == ' ' || endstop[-1] == '\t'))
+ --endstop;
+
+ if (! by)
+ {
+ bystart = "#1";
+ bystop = bystart + 2;
+ }
+ else
+ {
+ SKIP_WHITESPACE ();
+ bystart = input_line_pointer;
+
+ /* Look for DO. */
+ bystop = NULL;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (strncasecmp (input_line_pointer, "DO", 2) == 0
+ && (input_line_pointer[2] == '.'
+ || ! is_part_of_name (input_line_pointer[2])))
+ {
+ bystop = input_line_pointer;
+ input_line_pointer += 2;
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (bystop == NULL)
+ {
+ as_bad (_("missing do"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (bystop > bystart
+ && (bystop[-1] == ' ' || bystop[-1] == '\t'))
+ --bystop;
+ }
+
+ if (*input_line_pointer != '.')
+ extent = '\0';
+ else
+ {
+ extent = input_line_pointer[1];
+ input_line_pointer += 2;
+ }
+
+ /* We have fully parsed the FOR operands. Now build the loop. */
+
+ n = push_mri_control (mri_for);
+
+ buf = (char *) xmalloc (50 + (input_line_pointer - varstart));
+
+ /* move init,var */
+ s = buf;
+ *s++ = 'm';
+ *s++ = 'o';
+ *s++ = 'v';
+ *s++ = 'e';
+ if (qual != '\0')
+ *s++ = qual;
+ *s++ = ' ';
+ memcpy (s, initstart, initstop - initstart);
+ s += initstop - initstart;
+ *s++ = ',';
+ memcpy (s, varstart, varstop - varstart);
+ s += varstop - varstart;
+ *s = '\0';
+ mri_assemble (buf);
+
+ colon (n->top);
+
+ /* cmp end,var */
+ s = buf;
+ *s++ = 'c';
+ *s++ = 'm';
+ *s++ = 'p';
+ if (qual != '\0')
+ *s++ = qual;
+ *s++ = ' ';
+ memcpy (s, endstart, endstop - endstart);
+ s += endstop - endstart;
+ *s++ = ',';
+ memcpy (s, varstart, varstop - varstart);
+ s += varstop - varstart;
+ *s = '\0';
+ mri_assemble (buf);
+
+ /* bcc bottom */
+ ex[0] = extent;
+ ex[1] = '\0';
+ if (up)
+ sprintf (buf, "blt%s %s", ex, n->bottom);
+ else
+ sprintf (buf, "bgt%s %s", ex, n->bottom);
+ mri_assemble (buf);
+
+ /* Put together the add or sub instruction used by ENDF. */
+ s = buf;
+ if (up)
+ strcpy (s, "add");
+ else
+ strcpy (s, "sub");
+ s += 3;
+ if (qual != '\0')
+ *s++ = qual;
+ *s++ = ' ';
+ memcpy (s, bystart, bystop - bystart);
+ s += bystop - bystart;
+ *s++ = ',';
+ memcpy (s, varstart, varstop - varstart);
+ s += varstop - varstart;
+ *s = '\0';
+ n->incr = buf;
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI ENDF pseudo-op. */
+
+static void
+s_mri_endf (ignore)
+ int ignore;
+{
+ if (mri_control_stack == NULL
+ || mri_control_stack->type != mri_for)
+ {
+ as_bad (_("endf without for"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ colon (mri_control_stack->next);
+
+ mri_assemble (mri_control_stack->incr);
+
+ sprintf (mri_control_stack->incr, "bra %s", mri_control_stack->top);
+ mri_assemble (mri_control_stack->incr);
+
+ free (mri_control_stack->incr);
+
+ colon (mri_control_stack->bottom);
+
+ pop_mri_control ();
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI REPEAT pseudo-op. */
+
+static void
+s_mri_repeat (ignore)
+ int ignore;
+{
+ struct mri_control_info *n;
+
+ n = push_mri_control (mri_repeat);
+ colon (n->top);
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI UNTIL pseudo-op. */
+
+static void
+s_mri_until (qual)
+ int qual;
+{
+ char *s;
+
+ if (mri_control_stack == NULL
+ || mri_control_stack->type != mri_repeat)
+ {
+ as_bad (_("until without repeat"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ colon (mri_control_stack->next);
+
+ for (s = input_line_pointer; ! is_end_of_line[(unsigned char) *s]; s++)
+ ;
+
+ parse_mri_control_expression (s, qual, (const char *) NULL,
+ mri_control_stack->top, '\0');
+
+ colon (mri_control_stack->bottom);
+
+ input_line_pointer = s;
+
+ pop_mri_control ();
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI WHILE pseudo-op. */
+
+static void
+s_mri_while (qual)
+ int qual;
+{
+ char *s;
+
+ struct mri_control_info *n;
+
+ s = input_line_pointer;
+ while (! is_end_of_line[(unsigned char) *s]
+ && (! flag_mri || *s != '*'))
+ s++;
+ --s;
+ while (*s == ' ' || *s == '\t')
+ --s;
+ if (s - input_line_pointer > 1
+ && s[-1] == '.')
+ s -= 2;
+ if (s - input_line_pointer < 2
+ || strncasecmp (s - 1, "DO", 2) != 0)
+ {
+ as_bad (_("missing do"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ n = push_mri_control (mri_while);
+
+ colon (n->next);
+
+ parse_mri_control_expression (s - 1, qual, (const char *) NULL, n->bottom,
+ s[1] == '.' ? s[2] : '\0');
+
+ input_line_pointer = s + 1;
+ if (*input_line_pointer == '.')
+ input_line_pointer += 2;
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI ENDW pseudo-op. */
+
+static void
+s_mri_endw (ignore)
+ int ignore;
+{
+ char *buf;
+
+ if (mri_control_stack == NULL
+ || mri_control_stack->type != mri_while)
+ {
+ as_bad (_("endw without while"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ buf = (char *) xmalloc (20 + strlen (mri_control_stack->next));
+ sprintf (buf, "bra %s", mri_control_stack->next);
+ mri_assemble (buf);
+ free (buf);
+
+ colon (mri_control_stack->bottom);
+
+ pop_mri_control ();
+
+ if (flag_mri)
+ {
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * md_parse_option
+ * Invocation line includes a switch not recognized by the base assembler.
+ * See if it's a processor-specific option. These are:
+ *
+ * -[A]m[c]68000, -[A]m[c]68008, -[A]m[c]68010, -[A]m[c]68020, -[A]m[c]68030, -[A]m[c]68040
+ * -[A]m[c]68881, -[A]m[c]68882, -[A]m[c]68851
+ * Select the architecture. Instructions or features not
+ * supported by the selected architecture cause fatal
+ * errors. More than one may be specified. The default is
+ * -m68020 -m68851 -m68881. Note that -m68008 is a synonym
+ * for -m68000, and -m68882 is a synonym for -m68881.
+ * -[A]m[c]no-68851, -[A]m[c]no-68881
+ * Don't accept 688?1 instructions. (The "c" is kind of silly,
+ * so don't use or document it, but that's the way the parsing
+ * works).
+ *
+ * -pic Indicates PIC.
+ * -k Indicates PIC. (Sun 3 only.)
+ *
+ * --bitwise-or
+ * Permit `|' to be used in expressions.
+ *
+ */
+
+#ifdef OBJ_ELF
+CONST char *md_shortopts = "lSA:m:kQ:V";
+#else
+CONST char *md_shortopts = "lSA:m:k";
+#endif
+
+struct option md_longopts[] = {
+#define OPTION_PIC (OPTION_MD_BASE)
+ {"pic", no_argument, NULL, OPTION_PIC},
+#define OPTION_REGISTER_PREFIX_OPTIONAL (OPTION_MD_BASE + 1)
+ {"register-prefix-optional", no_argument, NULL,
+ OPTION_REGISTER_PREFIX_OPTIONAL},
+#define OPTION_BITWISE_OR (OPTION_MD_BASE + 2)
+ {"bitwise-or", no_argument, NULL, OPTION_BITWISE_OR},
+#define OPTION_BASE_SIZE_DEFAULT_16 (OPTION_MD_BASE + 3)
+ {"base-size-default-16", no_argument, NULL, OPTION_BASE_SIZE_DEFAULT_16},
+#define OPTION_BASE_SIZE_DEFAULT_32 (OPTION_MD_BASE + 4)
+ {"base-size-default-32", no_argument, NULL, OPTION_BASE_SIZE_DEFAULT_32},
+#define OPTION_DISP_SIZE_DEFAULT_16 (OPTION_MD_BASE + 5)
+ {"disp-size-default-16", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_16},
+#define OPTION_DISP_SIZE_DEFAULT_32 (OPTION_MD_BASE + 6)
+ {"disp-size-default-32", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_32},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'l': /* -l means keep external to 2 bit offset
+ rather than 16 bit one */
+ flag_short_refs = 1;
+ break;
+
+ case 'S': /* -S means that jbsr's always turn into
+ jsr's. */
+ flag_long_jumps = 1;
+ break;
+
+ case 'A':
+ if (*arg == 'm')
+ arg++;
+ /* intentional fall-through */
+ case 'm':
+
+ if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-')
+ {
+ int i;
+ unsigned long arch;
+ const char *oarg = arg;
+
+ arg += 3;
+ if (*arg == 'm')
+ {
+ arg++;
+ if (arg[0] == 'c' && arg[1] == '6')
+ arg++;
+ }
+ for (i = 0; i < n_archs; i++)
+ if (!strcmp (arg, archs[i].name))
+ break;
+ if (i == n_archs)
+ {
+ unknown:
+ as_bad (_("unrecognized option `%s'"), oarg);
+ return 0;
+ }
+ arch = archs[i].arch;
+ if (arch == m68881)
+ no_68881 = 1;
+ else if (arch == m68851)
+ no_68851 = 1;
+ else
+ goto unknown;
+ }
+ else
+ {
+ int i;
+
+ if (arg[0] == 'c' && arg[1] == '6')
+ arg++;
+
+ for (i = 0; i < n_archs; i++)
+ if (!strcmp (arg, archs[i].name))
+ {
+ unsigned long arch = archs[i].arch;
+ if (cpu_of_arch (arch))
+ /* It's a cpu spec. */
+ {
+ current_architecture &= ~m68000up;
+ current_architecture |= arch;
+ }
+ else if (arch == m68881)
+ {
+ current_architecture |= m68881;
+ no_68881 = 0;
+ }
+ else if (arch == m68851)
+ {
+ current_architecture |= m68851;
+ no_68851 = 0;
+ }
+ else
+ /* ??? */
+ abort ();
+ break;
+ }
+ if (i == n_archs)
+ {
+ as_bad (_("unrecognized architecture specification `%s'"), arg);
+ return 0;
+ }
+ }
+ break;
+
+ case OPTION_PIC:
+ case 'k':
+ flag_want_pic = 1;
+ break; /* -pic, Position Independent Code */
+
+ case OPTION_REGISTER_PREFIX_OPTIONAL:
+ flag_reg_prefix_optional = 1;
+ reg_prefix_optional_seen = 1;
+ break;
+
+ /* -V: SVR4 argument to print version ID. */
+ case 'V':
+ print_version_id ();
+ break;
+
+ /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+ should be emitted or not. FIXME: Not implemented. */
+ case 'Q':
+ break;
+
+ case OPTION_BITWISE_OR:
+ {
+ char *n, *t;
+ const char *s;
+
+ n = (char *) xmalloc (strlen (m68k_comment_chars) + 1);
+ t = n;
+ for (s = m68k_comment_chars; *s != '\0'; s++)
+ if (*s != '|')
+ *t++ = *s;
+ *t = '\0';
+ m68k_comment_chars = n;
+ }
+ break;
+
+ case OPTION_BASE_SIZE_DEFAULT_16:
+ m68k_index_width_default = SIZE_WORD;
+ break;
+
+ case OPTION_BASE_SIZE_DEFAULT_32:
+ m68k_index_width_default = SIZE_LONG;
+ break;
+
+ case OPTION_DISP_SIZE_DEFAULT_16:
+ m68k_rel32 = 0;
+ m68k_rel32_from_cmdline = 1;
+ break;
+
+ case OPTION_DISP_SIZE_DEFAULT_32:
+ m68k_rel32 = 1;
+ m68k_rel32_from_cmdline = 1;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+680X0 options:\n\
+-l use 1 word for refs to undefined symbols [default 2]\n\
+-m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060\n\
+ | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -m68360\n\
+ | -mcpu32 | -m5200\n\
+ specify variant of 680X0 architecture [default 68020]\n\
+-m68881 | -m68882 | -mno-68881 | -mno-68882\n\
+ target has/lacks floating-point coprocessor\n\
+ [default yes for 68020, 68030, and cpu32]\n"));
+ fprintf(stream, _("\
+-m68851 | -mno-68851\n\
+ target has/lacks memory-management unit coprocessor\n\
+ [default yes for 68020 and up]\n\
+-pic, -k generate position independent code\n\
+-S turn jbsr into jsr\n\
+--register-prefix-optional\n\
+ recognize register names without prefix character\n\
+--bitwise-or do not treat `|' as a comment character\n"));
+ fprintf (stream, _("\
+--base-size-default-16 base reg without size is 16 bits\n\
+--base-size-default-32 base reg without size is 32 bits (default)\n\
+--disp-size-default-16 displacement with unknown size is 16 bits\n\
+--disp-size-default-32 displacement with unknown size is 32 bits (default)\n"));
+}
+
+#ifdef TEST2
+
+/* TEST2: Test md_assemble() */
+/* Warning, this routine probably doesn't work anymore */
+
+main ()
+{
+ struct m68k_it the_ins;
+ char buf[120];
+ char *cp;
+ int n;
+
+ m68k_ip_begin ();
+ for (;;)
+ {
+ if (!gets (buf) || !*buf)
+ break;
+ if (buf[0] == '|' || buf[1] == '.')
+ continue;
+ for (cp = buf; *cp; cp++)
+ if (*cp == '\t')
+ *cp = ' ';
+ if (is_label (buf))
+ continue;
+ memset (&the_ins, '\0', sizeof (the_ins));
+ m68k_ip (&the_ins, buf);
+ if (the_ins.error)
+ {
+ printf (_("Error %s in %s\n"), the_ins.error, buf);
+ }
+ else
+ {
+ printf (_("Opcode(%d.%s): "), the_ins.numo, the_ins.args);
+ for (n = 0; n < the_ins.numo; n++)
+ printf (" 0x%x", the_ins.opcode[n] & 0xffff);
+ printf (" ");
+ print_the_insn (&the_ins.opcode[0], stdout);
+ (void) putchar ('\n');
+ }
+ for (n = 0; n < strlen (the_ins.args) / 2; n++)
+ {
+ if (the_ins.operands[n].error)
+ {
+ printf ("op%d Error %s in %s\n", n, the_ins.operands[n].error, buf);
+ continue;
+ }
+ printf ("mode %d, reg %d, ", the_ins.operands[n].mode, the_ins.operands[n].reg);
+ if (the_ins.operands[n].b_const)
+ printf ("Constant: '%.*s', ", 1 + the_ins.operands[n].e_const - the_ins.operands[n].b_const, the_ins.operands[n].b_const);
+ printf ("ireg %d, isiz %d, imul %d, ", the_ins.operands[n].ireg, the_ins.operands[n].isiz, the_ins.operands[n].imul);
+ if (the_ins.operands[n].b_iadd)
+ printf ("Iadd: '%.*s',", 1 + the_ins.operands[n].e_iadd - the_ins.operands[n].b_iadd, the_ins.operands[n].b_iadd);
+ (void) putchar ('\n');
+ }
+ }
+ m68k_ip_end ();
+ return 0;
+}
+
+is_label (str)
+ char *str;
+{
+ while (*str == ' ')
+ str++;
+ while (*str && *str != ' ')
+ str++;
+ if (str[-1] == ':' || str[1] == '=')
+ return 1;
+ return 0;
+}
+
+#endif
+
+/* Possible states for relaxation:
+
+ 0 0 branch offset byte (bra, etc)
+ 0 1 word
+ 0 2 long
+
+ 1 0 indexed offsets byte a0@(32,d4:w:1) etc
+ 1 1 word
+ 1 2 long
+
+ 2 0 two-offset index word-word a0@(32,d4)@(45) etc
+ 2 1 word-long
+ 2 2 long-word
+ 2 3 long-long
+
+ */
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+#ifdef OBJ_AOUT
+#ifdef BFD_ASSEMBLER
+ /* For a.out, force the section size to be aligned. If we don't do
+ this, BFD will align it for us, but it will not write out the
+ final bytes of the section. This may be a bug in BFD, but it is
+ easier to fix it here since that is how the other a.out targets
+ work. */
+ int align;
+
+ align = bfd_get_section_alignment (stdoutput, segment);
+ size = ((size + (1 << align) - 1) & ((valueT) -1 << align));
+#endif
+#endif
+
+ return size;
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the 68k, it is relative to the address of the first extension
+ word. The difference between the addresses of the offset and the
+ first extension word is stored in fx_pcrel_adjust. */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ int adjust;
+
+ /* Because fx_pcrel_adjust is a char, and may be unsigned, we store
+ -1 as 64. */
+ adjust = fixP->fx_pcrel_adjust;
+ if (adjust == 64)
+ adjust = -1;
+ return fixP->fx_where + fixP->fx_frag->fr_address - adjust;
+}
+
+#ifndef BFD_ASSEMBLER
+#ifdef OBJ_COFF
+
+/*ARGSUSED*/
+void
+tc_coff_symbol_emit_hook (ignore)
+ symbolS *ignore;
+{
+}
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ switch (frag->fr_subtype & 0x3)
+ {
+ case BYTE:
+ return 1;
+ case SHORT:
+ return 2;
+ case LONG:
+ return 4;
+ default:
+ abort ();
+ return 0;
+ }
+}
+
+#endif
+#endif
+
+/* end of tc-m68k.c */
diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h
new file mode 100644
index 00000000000..bc8308abca4
--- /dev/null
+++ b/gas/config/tc-m68k.h
@@ -0,0 +1,216 @@
+/* This file is tc-m68k.h
+ Copyright (C) 1987, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_M68K 1
+
+#ifdef ANSI_PROTOTYPES
+struct symbol;
+struct fix;
+#endif
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#ifdef OBJ_AOUT
+#ifdef TE_SUN3
+#define TARGET_FORMAT "a.out-sunos-big"
+#endif
+#ifdef TE_NetBSD
+#define TARGET_FORMAT "a.out-m68k-netbsd"
+#endif
+#ifdef TE_LINUX
+#define TARGET_FORMAT "a.out-m68k-linux"
+#endif
+#ifndef TARGET_FORMAT
+#define TARGET_FORMAT "a.out-zero-big"
+#endif
+#endif
+
+#ifdef OBJ_ELF
+#define TARGET_FORMAT "elf32-m68k"
+#endif
+
+#ifdef TE_APOLLO
+#define COFF_MAGIC APOLLOM68KMAGIC
+#define COFF_AOUTHDR_MAGIC APOLLO_COFF_VERSION_NUMBER
+#undef OBJ_COFF_OMIT_OPTIONAL_HEADER
+#endif
+
+#ifdef TE_LYNX
+#define TARGET_FORMAT "coff-m68k-lynx"
+#endif
+#ifdef TE_AUX
+#define TARGET_FORMAT "coff-m68k-aux"
+#endif
+#ifdef TE_DELTA
+#define TARGET_FORMAT "coff-m68k-sysv"
+#endif
+
+#ifndef COFF_MAGIC
+#define COFF_MAGIC MC68MAGIC
+#endif
+#define BFD_ARCH bfd_arch_m68k /* for non-BFD_ASSEMBLER */
+#define TARGET_ARCH bfd_arch_m68k /* BFD_ASSEMBLER */
+#define COFF_FLAGS F_AR32W
+#define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy)
+
+#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+extern int tc_coff_sizemachdep PARAMS ((struct frag *));
+#ifdef TE_SUN3
+/* This variable contains the value to write out at the beginning of
+ the a.out file. The 2<<16 means that this is a 68020 file instead
+ of an old-style 68000 file */
+
+#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (2<<16|OMAGIC); /* Magic byte for file header */
+#endif /* TE_SUN3 */
+
+#ifndef AOUT_MACHTYPE
+#define AOUT_MACHTYPE m68k_aout_machtype
+extern int m68k_aout_machtype;
+#endif
+
+#define tc_comment_chars m68k_comment_chars
+extern const char *m68k_comment_chars;
+
+#define tc_crawl_symbol_chain(a) {;} /* not used */
+#define tc_headers_hook(a) {;} /* not used */
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+
+#define LISTING_WORD_SIZE 2 /* A word is 2 bytes */
+#define LISTING_LHS_WIDTH 2 /* One word on the first line */
+#define LISTING_LHS_WIDTH_SECOND 2 /* One word on the second line */
+#define LISTING_LHS_CONT_LINES 4/* And 4 lines max */
+#define LISTING_HEADER "68K GAS "
+
+#ifndef REGISTER_PREFIX
+#define REGISTER_PREFIX '%'
+#endif
+
+#if !defined (REGISTER_PREFIX_OPTIONAL)
+#if defined (M68KCOFF) || defined (OBJ_ELF)
+#ifndef BFD_ASSEMBLER
+#define LOCAL_LABEL(name) (name[0] == '.' \
+ && (name[1] == 'L' || name[1] == '.'))
+#endif /* ! BFD_ASSEMBLER */
+#define REGISTER_PREFIX_OPTIONAL 0
+#else /* ! (COFF || ELF) */
+#define REGISTER_PREFIX_OPTIONAL 1
+#endif /* ! (COFF || ELF) */
+#endif /* not def REGISTER_PREFIX and not def OPTIONAL_REGISTER_PREFIX */
+
+#ifdef TE_DELTA
+/* On the Delta, `%' can occur within a label name, but not as the
+ initial character. */
+#define LEX_PCT LEX_NAME
+/* On the Delta, `~' can start a label name, but is converted to '.'. */
+#define LEX_TILDE LEX_BEGIN_NAME
+#define tc_canonicalize_symbol_name(s) ((*(s) == '~' ? *(s) = '.' : '.'), s)
+/* On the Delta, dots are not required before pseudo-ops. */
+#define NO_PSEUDO_DOT
+#ifndef BFD_ASSEMBLER
+#undef LOCAL_LABEL
+#define LOCAL_LABEL(name) \
+ (name[0] == '.' || (name[0] == 'L' && name[1] == '%'))
+#endif
+#endif
+
+extern void m68k_mri_mode_change PARAMS ((int));
+#define MRI_MODE_CHANGE(i) m68k_mri_mode_change (i)
+
+extern int m68k_conditional_pseudoop PARAMS ((pseudo_typeS *));
+#define tc_conditional_pseudoop(pop) m68k_conditional_pseudoop (pop)
+
+extern void m68k_frob_label PARAMS ((struct symbol *));
+#define tc_frob_label(sym) m68k_frob_label (sym)
+
+extern void m68k_flush_pending_output PARAMS ((void));
+#define md_flush_pending_output() m68k_flush_pending_output ()
+
+extern void m68k_frob_symbol PARAMS ((struct symbol *));
+
+#ifdef BFD_ASSEMBLER
+
+#define tc_frob_symbol(sym,punt) \
+do \
+ { \
+ if (S_GET_SEGMENT (sym) == reg_section) \
+ punt = 1; \
+ m68k_frob_symbol (sym); \
+ } \
+while (0)
+
+#define NO_RELOC BFD_RELOC_NONE
+
+#ifdef OBJ_ELF
+
+/* This expression evaluates to false if the relocation is for a local object
+ for which we still want to do the relocation at runtime. True if we
+ are willing to perform this relocation while building the .o file. If
+ the reloc is against an externally visible symbol, then the assembler
+ should never do the relocation. */
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy)))
+
+#define tc_fix_adjustable(X) tc_m68k_fix_adjustable(X)
+extern int tc_m68k_fix_adjustable PARAMS ((struct fix *));
+#endif
+
+#define TC_FORCE_RELOCATION(FIX) \
+ ((FIX)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \
+ || (FIX)->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+
+#else /* ! BFD_ASSEMBLER */
+
+#define tc_frob_coff_symbol(sym) m68k_frob_symbol (sym)
+
+#define NO_RELOC 0
+
+#endif /* ! BFD_ASSEMBLER */
+
+#define DIFF_EXPR_OK
+
+extern void m68k_init_after_args PARAMS ((void));
+#define tc_init_after_args m68k_init_after_args
+
+extern int m68k_parse_long_option PARAMS ((char *));
+#define md_parse_long_option m68k_parse_long_option
+
+#define md_operand(x)
+
+#define TARGET_WORD_SIZE 32
+#define TARGET_ARCH bfd_arch_m68k
+
+extern struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/* Copied from write.c */
+/* This was formerly called M68K_AIM_KLUDGE. */
+#define md_prepare_relax_scan(fragP, address, aim, this_state, this_type) \
+ if (aim==0 && this_state== 4) { /* hard encoded from tc-m68k.c */ \
+ aim=this_type->rlx_forward+1; /* Force relaxation into word mode */ \
+ }
+
+/* end of tc-m68k.h */
diff --git a/gas/config/tc-m88k.c b/gas/config/tc-m88k.c
new file mode 100644
index 00000000000..931a496a54b
--- /dev/null
+++ b/gas/config/tc-m88k.c
@@ -0,0 +1,1452 @@
+/* m88k.c -- Assembler for the Motorola 88000
+ Contributed by Devon Bowen of Buffalo University
+ and Torbjorn Granlund of the Swedish Institute of Computer Science.
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "m88k-opcode.h"
+
+struct field_val_assoc
+{
+ char *name;
+ unsigned val;
+};
+
+struct field_val_assoc cr_regs[] =
+{
+ {"PID", 0},
+ {"PSR", 1},
+ {"EPSR", 2},
+ {"SSBR", 3},
+ {"SXIP", 4},
+ {"SNIP", 5},
+ {"SFIP", 6},
+ {"VBR", 7},
+ {"DMT0", 8},
+ {"DMD0", 9},
+ {"DMA0", 10},
+ {"DMT1", 11},
+ {"DMD1", 12},
+ {"DMA1", 13},
+ {"DMT2", 14},
+ {"DMD2", 15},
+ {"DMA2", 16},
+ {"SR0", 17},
+ {"SR1", 18},
+ {"SR2", 19},
+ {"SR3", 20},
+
+ {NULL, 0},
+};
+
+struct field_val_assoc fcr_regs[] =
+{
+ {"FPECR", 0},
+ {"FPHS1", 1},
+ {"FPLS1", 2},
+ {"FPHS2", 3},
+ {"FPLS2", 4},
+ {"FPPT", 5},
+ {"FPRH", 6},
+ {"FPRL", 7},
+ {"FPIT", 8},
+
+ {"FPSR", 62},
+ {"FPCR", 63},
+
+ {NULL, 0},
+};
+
+struct field_val_assoc cmpslot[] =
+{
+/* Integer Floating point */
+ {"nc", 0},
+ {"cp", 1},
+ {"eq", 2},
+ {"ne", 3},
+ {"gt", 4},
+ {"le", 5},
+ {"lt", 6},
+ {"ge", 7},
+ {"hi", 8}, {"ou", 8},
+ {"ls", 9}, {"ib", 9},
+ {"lo", 10}, {"in", 10},
+ {"hs", 11}, {"ob", 11},
+ {"be", 12}, {"ue", 12},
+ {"nb", 13}, {"lg", 13},
+ {"he", 14}, {"ug", 14},
+ {"nh", 15}, {"ule", 15},
+ {"ul", 16},
+ {"uge", 17},
+
+ {NULL, 0},
+};
+
+struct field_val_assoc cndmsk[] =
+{
+ {"gt0", 1},
+ {"eq0", 2},
+ {"ge0", 3},
+ {"lt0", 12},
+ {"ne0", 13},
+ {"le0", 14},
+
+ {NULL, 0},
+};
+
+struct m88k_insn
+{
+ unsigned long opcode;
+ expressionS exp;
+ enum reloc_type reloc;
+};
+
+static char *get_bf PARAMS ((char *param, unsigned *valp));
+static char *get_cmp PARAMS ((char *param, unsigned *valp));
+static char *get_cnd PARAMS ((char *param, unsigned *valp));
+static char *get_cr PARAMS ((char *param, unsigned *regnop));
+static char *get_fcr PARAMS ((char *param, unsigned *regnop));
+static char *get_imm16 PARAMS ((char *param, struct m88k_insn *insn));
+static char *get_o6 PARAMS ((char *param, unsigned *valp));
+static char *get_reg PARAMS ((char *param, unsigned *regnop, int reg_prefix));
+static char *get_vec9 PARAMS ((char *param, unsigned *valp));
+static char *getval PARAMS ((char *param, unsigned int *valp));
+
+static char *get_pcr PARAMS ((char *param, struct m88k_insn *insn,
+ enum reloc_type reloc));
+
+static int calcop PARAMS ((struct m88k_opcode *format,
+ char *param, struct m88k_insn *insn));
+
+
+extern char *myname;
+static struct hash_control *op_hash = NULL;
+
+/* These bits should be turned off in the first address of every segment */
+int md_seg_align = 7;
+
+/* These chars start a comment anywhere in a source file (except inside
+ another comment */
+const char comment_chars[] = ";";
+
+/* These chars only start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* as in 0f123.456 */
+/* or 0H1.234E-12 (see exp chars above) */
+const char FLT_CHARS[] = "dDfF";
+
+extern void float_cons (), cons (), s_globl (), s_space (),
+ s_set (), s_lcomm ();
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"align", s_align_bytes, 4},
+ {"def", s_set, 0},
+ {"dfloat", float_cons, 'd'},
+ {"ffloat", float_cons, 'f'},
+ {"global", s_globl, 0},
+ {"half", cons, 2},
+ {"bss", s_lcomm, 1},
+ {"string", stringer, 0},
+ {"word", cons, 4},
+ /* Force set to be treated as an instruction. */
+ {"set", NULL, 0},
+ {".set", s_set, 0},
+ {0}
+};
+
+void
+md_begin ()
+{
+ const char *retval = NULL;
+ unsigned int i = 0;
+
+ /* initialize hash table */
+
+ op_hash = hash_new ();
+
+ /* loop until you see the end of the list */
+
+ while (*m88k_opcodes[i].name)
+ {
+ char *name = m88k_opcodes[i].name;
+
+ /* hash each mnemonic and record its position */
+
+ retval = hash_insert (op_hash, name, &m88k_opcodes[i]);
+
+ if (retval != NULL)
+ as_fatal (_("Can't hash instruction '%s':%s"),
+ m88k_opcodes[i].name, retval);
+
+ /* skip to next unique mnemonic or end of list */
+
+ for (i++; !strcmp (m88k_opcodes[i].name, name); i++)
+ ;
+ }
+}
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+}
+
+void
+md_assemble (op)
+ char *op;
+{
+ char *param, *thisfrag;
+ char c;
+ struct m88k_opcode *format;
+ struct m88k_insn insn;
+
+ assert (op);
+
+ /* skip over instruction to find parameters */
+
+ for (param = op; *param != 0 && !isspace (*param); param++)
+ ;
+ c = *param;
+ *param++ = '\0';
+
+ /* try to find the instruction in the hash table */
+
+ if ((format = (struct m88k_opcode *) hash_find (op_hash, op)) == NULL)
+ {
+ as_bad (_("Invalid mnemonic '%s'"), op);
+ return;
+ }
+
+ /* try parsing this instruction into insn */
+
+ insn.exp.X_add_symbol = 0;
+ insn.exp.X_op_symbol = 0;
+ insn.exp.X_add_number = 0;
+ insn.exp.X_op = O_illegal;
+ insn.reloc = NO_RELOC;
+
+ while (!calcop (format, param, &insn))
+ {
+ /* if it doesn't parse try the next instruction */
+
+ if (!strcmp (format[0].name, format[1].name))
+ format++;
+ else
+ {
+ as_fatal (_("Parameter syntax error"));
+ return;
+ }
+ }
+
+ /* grow the current frag and plop in the opcode */
+
+ thisfrag = frag_more (4);
+ md_number_to_chars (thisfrag, insn.opcode, 4);
+
+ /* if this instruction requires labels mark it for later */
+
+ switch (insn.reloc)
+ {
+ case NO_RELOC:
+ break;
+
+ case RELOC_LO16:
+ case RELOC_HI16:
+ fix_new_exp (frag_now,
+ thisfrag - frag_now->fr_literal + 2,
+ 2,
+ &insn.exp,
+ 0,
+ insn.reloc);
+ break;
+
+ case RELOC_IW16:
+ fix_new_exp (frag_now,
+ thisfrag - frag_now->fr_literal,
+ 4,
+ &insn.exp,
+ 0,
+ insn.reloc);
+ break;
+
+ case RELOC_PC16:
+ fix_new_exp (frag_now,
+ thisfrag - frag_now->fr_literal + 2,
+ 2,
+ &insn.exp,
+ 1,
+ insn.reloc);
+ break;
+
+ case RELOC_PC26:
+ fix_new_exp (frag_now,
+ thisfrag - frag_now->fr_literal,
+ 4,
+ &insn.exp,
+ 1,
+ insn.reloc);
+ break;
+
+ default:
+ as_fatal (_("Unknown relocation type"));
+ break;
+ }
+}
+
+static int
+calcop (format, param, insn)
+ struct m88k_opcode *format;
+ char *param;
+ struct m88k_insn *insn;
+{
+ char *fmt = format->op_spec;
+ int f;
+ unsigned val;
+ unsigned opcode;
+ int reg_prefix = 'r';
+
+ insn->opcode = format->opcode;
+ opcode = 0;
+
+ for (;;)
+ {
+ if (param == 0)
+ return 0;
+ f = *fmt++;
+ switch (f)
+ {
+ case 0:
+ insn->opcode |= opcode;
+ return (*param == 0 || *param == '\n');
+
+ default:
+ if (f != *param++)
+ return 0;
+ break;
+
+ case 'd':
+ param = get_reg (param, &val, reg_prefix);
+ reg_prefix = 'r';
+ opcode |= val << 21;
+ break;
+
+ case 'o':
+ param = get_o6 (param, &val);
+ opcode |= ((val >> 2) << 7);
+ break;
+
+ case 'x':
+ reg_prefix = 'x';
+ break;
+
+ case '1':
+ param = get_reg (param, &val, reg_prefix);
+ reg_prefix = 'r';
+ opcode |= val << 16;
+ break;
+
+ case '2':
+ param = get_reg (param, &val, reg_prefix);
+ reg_prefix = 'r';
+ opcode |= val;
+ break;
+
+ case '3':
+ param = get_reg (param, &val, 'r');
+ opcode |= (val << 16) | val;
+ break;
+
+ case 'I':
+ param = get_imm16 (param, insn);
+ break;
+
+ case 'b':
+ param = get_bf (param, &val);
+ opcode |= val;
+ break;
+
+ case 'p':
+ param = get_pcr (param, insn, RELOC_PC16);
+ break;
+
+ case 'P':
+ param = get_pcr (param, insn, RELOC_PC26);
+ break;
+
+ case 'B':
+ param = get_cmp (param, &val);
+ opcode |= val;
+ break;
+
+ case 'M':
+ param = get_cnd (param, &val);
+ opcode |= val;
+ break;
+
+ case 'c':
+ param = get_cr (param, &val);
+ opcode |= val << 5;
+ break;
+
+ case 'f':
+ param = get_fcr (param, &val);
+ opcode |= val << 5;
+ break;
+
+ case 'V':
+ param = get_vec9 (param, &val);
+ opcode |= val;
+ break;
+
+ case '?':
+ /* Having this here repeats the warning somtimes.
+ But can't we stand that? */
+ as_warn (_("Use of obsolete instruction"));
+ break;
+ }
+ }
+}
+
+static char *
+match_name (param, assoc_tab, valp)
+ char *param;
+ struct field_val_assoc *assoc_tab;
+ unsigned *valp;
+{
+ int i;
+ char *name;
+ int name_len;
+
+ for (i = 0;; i++)
+ {
+ name = assoc_tab[i].name;
+ if (name == NULL)
+ return NULL;
+ name_len = strlen (name);
+ if (!strncmp (param, name, name_len))
+ {
+ *valp = assoc_tab[i].val;
+ return param + name_len;
+ }
+ }
+}
+
+static char *
+get_reg (param, regnop, reg_prefix)
+ char *param;
+ unsigned *regnop;
+ int reg_prefix;
+{
+ unsigned c;
+ unsigned regno;
+
+ c = *param++;
+ if (c == reg_prefix)
+ {
+ regno = *param++ - '0';
+ if (regno < 10)
+ {
+ if (regno == 0)
+ {
+ *regnop = 0;
+ return param;
+ }
+ c = *param - '0';
+ if (c < 10)
+ {
+ regno = regno * 10 + c;
+ if (c < 32)
+ {
+ *regnop = regno;
+ return param + 1;
+ }
+ }
+ else
+ {
+ *regnop = regno;
+ return param;
+ }
+ }
+ return NULL;
+ }
+ else if (c == 's' && param[0] == 'p')
+ {
+ *regnop = 31;
+ return param + 1;
+ }
+
+ return 0;
+}
+
+static char *
+get_imm16 (param, insn)
+ char *param;
+ struct m88k_insn *insn;
+{
+ enum reloc_type reloc = NO_RELOC;
+ unsigned int val;
+ char *save_ptr;
+
+ if (!strncmp (param, "hi16", 4) && !isalnum (param[4]))
+ {
+ reloc = RELOC_HI16;
+ param += 4;
+ }
+ else if (!strncmp (param, "lo16", 4) && !isalnum (param[4]))
+ {
+ reloc = RELOC_LO16;
+ param += 4;
+ }
+ else if (!strncmp (param, "iw16", 4) && !isalnum (param[4]))
+ {
+ reloc = RELOC_IW16;
+ param += 4;
+ }
+
+ save_ptr = input_line_pointer;
+ input_line_pointer = param;
+ expression (&insn->exp);
+ param = input_line_pointer;
+ input_line_pointer = save_ptr;
+
+ val = insn->exp.X_add_number;
+
+ if (insn->exp.X_op == O_constant)
+ {
+ /* Insert the value now, and reset reloc to NO_RELOC. */
+ if (reloc == NO_RELOC)
+ {
+ /* Warn about too big expressions if not surrounded by xx16. */
+ if (val > 0xffff)
+ as_warn (_("Expression truncated to 16 bits"));
+ }
+
+ if (reloc == RELOC_HI16)
+ val >>= 16;
+
+ insn->opcode |= val & 0xffff;
+ reloc = NO_RELOC;
+ }
+ else if (reloc == NO_RELOC)
+ /* We accept a symbol even without lo16, hi16, etc, and assume
+ lo16 was intended. */
+ reloc = RELOC_LO16;
+
+ insn->reloc = reloc;
+
+ return param;
+}
+
+static char *
+get_pcr (param, insn, reloc)
+ char *param;
+ struct m88k_insn *insn;
+ enum reloc_type reloc;
+{
+ char *saveptr, *saveparam;
+
+ saveptr = input_line_pointer;
+ input_line_pointer = param;
+
+ expression (&insn->exp);
+
+ saveparam = input_line_pointer;
+ input_line_pointer = saveptr;
+
+ /* Botch: We should relocate now if O_constant. */
+ insn->reloc = reloc;
+
+ return saveparam;
+}
+
+static char *
+get_cmp (param, valp)
+ char *param;
+ unsigned *valp;
+{
+ unsigned int val;
+ char *save_ptr;
+
+ save_ptr = param;
+
+ param = match_name (param, cmpslot, valp);
+ val = *valp;
+
+ if (param == NULL)
+ {
+ param = save_ptr;
+
+ save_ptr = input_line_pointer;
+ input_line_pointer = param;
+ val = get_absolute_expression ();
+ param = input_line_pointer;
+ input_line_pointer = save_ptr;
+
+ if (val >= 32)
+ {
+ as_warn (_("Expression truncated to 5 bits"));
+ val %= 32;
+ }
+ }
+
+ *valp = val << 21;
+ return param;
+}
+
+static char *
+get_cnd (param, valp)
+ char *param;
+ unsigned *valp;
+{
+ unsigned int val;
+
+ if (isdigit (*param))
+ {
+ param = getval (param, &val);
+
+ if (val >= 32)
+ {
+ as_warn (_("Expression truncated to 5 bits"));
+ val %= 32;
+ }
+ }
+ else
+ {
+ if (isupper (*param))
+ *param = tolower (*param);
+
+ if (isupper (param[1]))
+ param[1] = tolower (param[1]);
+
+ param = match_name (param, cndmsk, valp);
+
+ if (param == NULL)
+ return NULL;
+
+ val = *valp;
+ }
+
+ *valp = val << 21;
+ return param;
+}
+
+static char *
+get_bf2 (param, bc)
+ char *param;
+ int bc;
+{
+ int depth = 0;
+ int c;
+
+ for (;;)
+ {
+ c = *param;
+ if (c == 0)
+ return param;
+ else if (c == '(')
+ depth++;
+ else if (c == ')')
+ depth--;
+ else if (c == bc && depth <= 0)
+ return param;
+ param++;
+ }
+}
+
+static char *
+get_bf_offset_expression (param, offsetp)
+ char *param;
+ unsigned *offsetp;
+{
+ unsigned offset;
+
+ if (isalpha (param[0]))
+ {
+ if (isupper (param[0]))
+ param[0] = tolower (param[0]);
+ if (isupper (param[1]))
+ param[1] = tolower (param[1]);
+
+ param = match_name (param, cmpslot, offsetp);
+
+ return param;
+ }
+ else
+ {
+ input_line_pointer = param;
+ offset = get_absolute_expression ();
+ param = input_line_pointer;
+ }
+
+ *offsetp = offset;
+ return param;
+}
+
+static char *
+get_bf (param, valp)
+ char *param;
+ unsigned *valp;
+{
+ unsigned offset = 0;
+ unsigned width = 0;
+ char *xp;
+ char *save_ptr;
+
+ xp = get_bf2 (param, '<');
+
+ save_ptr = input_line_pointer;
+ input_line_pointer = param;
+ if (*xp == 0)
+ {
+ /* We did not find '<'. We have an offset (width implicitly 32). */
+ param = get_bf_offset_expression (param, &offset);
+ input_line_pointer = save_ptr;
+ if (param == NULL)
+ return NULL;
+ }
+ else
+ {
+ *xp++ = 0; /* Overwrite the '<' */
+ param = get_bf2 (xp, '>');
+ if (*param == 0)
+ return NULL;
+ *param++ = 0; /* Overwrite the '>' */
+
+ width = get_absolute_expression ();
+ xp = get_bf_offset_expression (xp, &offset);
+ input_line_pointer = save_ptr;
+
+ if (xp + 1 != param)
+ return NULL;
+ }
+
+ *valp = ((width % 32) << 5) | (offset % 32);
+
+ return param;
+}
+
+static char *
+get_cr (param, regnop)
+ char *param;
+ unsigned *regnop;
+{
+ unsigned regno;
+ unsigned c;
+
+ if (!strncmp (param, "cr", 2))
+ {
+ param += 2;
+
+ regno = *param++ - '0';
+ if (regno < 10)
+ {
+ if (regno == 0)
+ {
+ *regnop = 0;
+ return param;
+ }
+ c = *param - '0';
+ if (c < 10)
+ {
+ regno = regno * 10 + c;
+ if (c < 64)
+ {
+ *regnop = regno;
+ return param + 1;
+ }
+ }
+ else
+ {
+ *regnop = regno;
+ return param;
+ }
+ }
+ return NULL;
+ }
+
+ param = match_name (param, cr_regs, regnop);
+
+ return param;
+}
+
+static char *
+get_fcr (param, regnop)
+ char *param;
+ unsigned *regnop;
+{
+ unsigned regno;
+ unsigned c;
+
+ if (!strncmp (param, "fcr", 3))
+ {
+ param += 3;
+
+ regno = *param++ - '0';
+ if (regno < 10)
+ {
+ if (regno == 0)
+ {
+ *regnop = 0;
+ return param;
+ }
+ c = *param - '0';
+ if (c < 10)
+ {
+ regno = regno * 10 + c;
+ if (c < 64)
+ {
+ *regnop = regno;
+ return param + 1;
+ }
+ }
+ else
+ {
+ *regnop = regno;
+ return param;
+ }
+ }
+ return NULL;
+ }
+
+ param = match_name (param, fcr_regs, regnop);
+
+ return param;
+}
+
+static char *
+get_vec9 (param, valp)
+ char *param;
+ unsigned *valp;
+{
+ unsigned val;
+ char *save_ptr;
+
+ save_ptr = input_line_pointer;
+ input_line_pointer = param;
+ val = get_absolute_expression ();
+ param = input_line_pointer;
+ input_line_pointer = save_ptr;
+
+ if (val >= 1 << 9)
+ as_warn (_("Expression truncated to 9 bits"));
+
+ *valp = val % (1 << 9);
+
+ return param;
+}
+
+static char *
+get_o6 (param, valp)
+ char *param;
+ unsigned *valp;
+{
+ unsigned val;
+ char *save_ptr;
+
+ save_ptr = input_line_pointer;
+ input_line_pointer = param;
+ val = get_absolute_expression ();
+ param = input_line_pointer;
+ input_line_pointer = save_ptr;
+
+ if (val & 0x3)
+ as_warn (_("Removed lower 2 bits of expression"));
+
+ *valp = val;
+
+ return(param);
+}
+
+#define hexval(z) \
+ (isdigit (z) ? (z) - '0' : \
+ islower (z) ? (z) - 'a' + 10 : \
+ isupper (z) ? (z) - 'A' + 10 : -1)
+
+static char *
+getval (param, valp)
+ char *param;
+ unsigned int *valp;
+{
+ unsigned int val = 0;
+ unsigned int c;
+
+ c = *param++;
+ if (c == '0')
+ {
+ c = *param++;
+ if (c == 'x' || c == 'X')
+ {
+ c = *param++;
+ c = hexval (c);
+ while (c < 16)
+ {
+ val = val * 16 + c;
+ c = *param++;
+ c = hexval (c);
+ }
+ }
+ else
+ {
+ c -= '0';
+ while (c < 8)
+ {
+ val = val * 8 + c;
+ c = *param++ - '0';
+ }
+ }
+ }
+ else
+ {
+ c -= '0';
+ while (c < 10)
+ {
+ val = val * 10 + c;
+ c = *param++ - '0';
+ }
+ }
+
+ *valp = val;
+ return param - 1;
+}
+
+void
+md_number_to_chars (buf, val, nbytes)
+ char *buf;
+ valueT val;
+ int nbytes;
+{
+ number_to_chars_bigendian (buf, val, nbytes);
+}
+
+#if 0
+
+/* This routine is never called. What is it for?
+ Ian Taylor, Cygnus Support 13 Jul 1993 */
+
+void
+md_number_to_imm (buf, val, nbytes, fixP, seg_type)
+ unsigned char *buf;
+ unsigned int val;
+ int nbytes;
+ fixS *fixP;
+ int seg_type;
+{
+ if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC)
+ {
+ switch (nbytes)
+ {
+ case 4:
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ case 2:
+ *buf++ = val >> 8;
+ case 1:
+ *buf = val;
+ break;
+
+ default:
+ abort ();
+ }
+ return;
+ }
+
+ switch (fixP->fx_r_type)
+ {
+ case RELOC_IW16:
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case RELOC_LO16:
+ buf[0] = val >> 8;
+ buf[1] = val;
+ break;
+
+ case RELOC_HI16:
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ break;
+
+ case RELOC_PC16:
+ val += 4;
+ buf[0] = val >> 10;
+ buf[1] = val >> 2;
+ break;
+
+ case RELOC_PC26:
+ val += 4;
+ buf[0] |= (val >> 26) & 0x03;
+ buf[1] = val >> 18;
+ buf[2] = val >> 10;
+ buf[3] = val >> 2;
+ break;
+
+ case RELOC_32:
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ default:
+ as_fatal (_("Bad relocation type"));
+ break;
+ }
+}
+
+#endif /* 0 */
+
+void
+md_number_to_disp (buf, val, nbytes)
+ char *buf;
+ int val;
+ int nbytes;
+{
+ as_fatal (_("md_number_to_disp not defined"));
+ md_number_to_chars (buf, val, nbytes);
+}
+
+void
+md_number_to_field (buf, val, nbytes)
+ char *buf;
+ int val;
+ int nbytes;
+{
+ as_fatal (_("md_number_to_field not defined"));
+ md_number_to_chars (buf, val, nbytes);
+}
+
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+int md_short_jump_size = 4;
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ ptr[0] = (char) 0xc0;
+ ptr[1] = 0x00;
+ ptr[2] = 0x00;
+ ptr[3] = 0x00;
+ fix_new (frag,
+ ptr - frag->fr_literal,
+ 4,
+ to_symbol,
+ (offsetT) 0,
+ 0,
+ RELOC_PC26); /* Botch: Shouldn't this be RELOC_PC16? */
+}
+
+int md_long_jump_size = 4;
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ ptr[0] = (char) 0xc0;
+ ptr[1] = 0x00;
+ ptr[2] = 0x00;
+ ptr[3] = 0x00;
+ fix_new (frag,
+ ptr - frag->fr_literal,
+ 4,
+ to_symbol,
+ (offsetT) 0,
+ 0,
+ RELOC_PC26);
+}
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ fragS *fragP;
+ segT segment_type;
+{
+ as_fatal (_("Relaxation should never occur"));
+ return (-1);
+}
+
+#if 0
+
+/* As far as I can tell, this routine is never called. What is it
+ doing here?
+ Ian Taylor, Cygnus Support 13 Jul 1993 */
+
+
+/*
+ * Risc relocations are completely different, so it needs
+ * this machine dependent routine to emit them.
+ */
+void
+emit_relocations (fixP, segment_address_in_file)
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ struct reloc_info_m88k ri;
+ symbolS *symbolP;
+ extern char *next_object_file_charP;
+
+ bzero ((char *) &ri, sizeof (ri));
+ for (; fixP; fixP = fixP->fx_next)
+ {
+ if (fixP->fx_r_type >= NO_RELOC)
+ {
+ fprintf (stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
+ abort ();
+ }
+
+ if ((symbolP = fixP->fx_addsy) != NULL)
+ {
+ ri.r_address = fixP->fx_frag->fr_address +
+ fixP->fx_where - segment_address_in_file;
+ if ((symbolP->sy_type & N_TYPE) == N_UNDF)
+ {
+ ri.r_extern = 1;
+ ri.r_symbolnum = symbolP->sy_number;
+ }
+ else
+ {
+ ri.r_extern = 0;
+ ri.r_symbolnum = symbolP->sy_type & N_TYPE;
+ }
+ if (symbolP && symbolP->sy_frag)
+ {
+ ri.r_addend = symbolP->sy_frag->fr_address;
+ }
+ ri.r_type = fixP->fx_r_type;
+ if (fixP->fx_pcrel)
+ {
+ ri.r_addend -= ri.r_address;
+ }
+ else
+ {
+ ri.r_addend = fixP->fx_addnumber;
+ }
+
+ append (&next_object_file_charP, (char *) &ri, sizeof (ri));
+ }
+ }
+}
+
+#endif /* 0 */
+
+#if 0
+
+/* This routine can be subsumed by s_lcomm in read.c.
+ Ian Taylor, Cygnus Support 13 Jul 1993 */
+
+
+static void
+s_bss ()
+{
+ char *name;
+ char c;
+ char *p;
+ int temp, bss_align;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_warn (_("Expected comma after name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_("BSS length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ bss_align = get_absolute_expression ();
+ }
+ else
+ bss_align = 0;
+
+ if (!S_IS_DEFINED(symbolP)
+ || S_GET_SEGMENT(symbolP) == SEG_BSS)
+ {
+ if (! need_pass_2)
+ {
+ char *p;
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+
+ subseg_set (SEG_BSS, 1); /* switch to bss */
+
+ if (bss_align)
+ frag_align (bss_align, 0, 0);
+
+ /* detach from old frag */
+ if (symbolP->sy_type == N_BSS && symbolP->sy_frag != NULL)
+ symbolP->sy_frag->fr_symbol = NULL;
+
+ symbolP->sy_frag = frag_now;
+ p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
+ (offsetT) temp, (char *)0);
+ *p = 0;
+ S_SET_SEGMENT (symbolP, SEG_BSS);
+
+ subseg_set (current_seg, current_subseg);
+ }
+ }
+ else
+ {
+ as_warn (_("Ignoring attempt to re-define symbol %s."), name);
+ }
+
+ while (!is_end_of_line[*input_line_pointer])
+ {
+ input_line_pointer++;
+ }
+}
+
+#endif /* 0 */
+
+#ifdef M88KCOFF
+
+/* These functions are needed if we are linking with obj-coffbfd.c.
+ That file may be replaced by a more BFD oriented version at some
+ point. If that happens, these functions should be rexamined.
+
+ Ian Lance Taylor, Cygnus Support, 13 July 1993. */
+
+/* Given a fixS structure (created by a call to fix_new, above),
+ return the BFD relocation type to use for it. */
+
+short
+tc_coff_fix2rtype (fixp)
+ fixS *fixp;
+{
+ switch (fixp->fx_r_type)
+ {
+ case RELOC_LO16:
+ return R_LVRT16;
+ case RELOC_HI16:
+ return R_HVRT16;
+ case RELOC_PC16:
+ return R_PCR16L;
+ case RELOC_PC26:
+ return R_PCR26L;
+ case RELOC_32:
+ return R_VRT32;
+ case RELOC_IW16:
+ return R_VRT16;
+ default:
+ abort ();
+ }
+}
+
+/* Apply a fixS to the object file. Since COFF does not use addends
+ in relocs, the addend is actually stored directly in the object
+ file itself. */
+
+void
+md_apply_fix (fixp, val)
+ fixS *fixp;
+ long val;
+{
+ char *buf;
+
+ buf = fixp->fx_frag->fr_literal + fixp->fx_where;
+ fixp->fx_offset = 0;
+
+ switch (fixp->fx_r_type)
+ {
+ case RELOC_IW16:
+ fixp->fx_offset = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ case RELOC_LO16:
+ fixp->fx_offset = val >> 16;
+ buf[0] = val >> 8;
+ buf[1] = val;
+ break;
+
+ case RELOC_HI16:
+ fixp->fx_offset = val >> 16;
+ buf[0] = val >> 8;
+ buf[1] = val;
+ break;
+
+ case RELOC_PC16:
+ buf[0] = val >> 10;
+ buf[1] = val >> 2;
+ break;
+
+ case RELOC_PC26:
+ buf[0] |= (val >> 26) & 0x03;
+ buf[1] = val >> 18;
+ buf[2] = val >> 10;
+ buf[3] = val >> 2;
+ break;
+
+ case RELOC_32:
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Where a PC relative offset is calculated from. On the m88k they
+ are calculated from just after the instruction. */
+
+long
+md_pcrel_from (fixp)
+ fixS *fixp;
+{
+ switch (fixp->fx_r_type)
+ {
+ case RELOC_PC16:
+ return fixp->fx_frag->fr_address + fixp->fx_where - 2;
+ case RELOC_PC26:
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+ default:
+ abort ();
+ }
+ /*NOTREACHED*/
+}
+
+/* When we align the .init section, insert the correct NOP pattern. */
+
+int
+m88k_do_align (n, fill, max, len)
+ int n;
+ const char *fill;
+ int len;
+ int max;
+{
+ if (fill == NULL
+ && strcmp (obj_segment_name (now_seg), ".init") == 0)
+ {
+ static const unsigned char nop_pattern[] = { 0xf4, 0x00, 0x58, 0x00 };
+ frag_align_pattern (n, nop_pattern, sizeof (nop_pattern), max);
+ return 1;
+ }
+ return 0;
+}
+
+#endif /* M88KCOFF */
diff --git a/gas/config/tc-m88k.h b/gas/config/tc-m88k.h
new file mode 100644
index 00000000000..426b6972807
--- /dev/null
+++ b/gas/config/tc-m88k.h
@@ -0,0 +1,108 @@
+/* m88k.h -- Assembler for the Motorola 88000
+ Contributed by Devon Bowen of Buffalo University
+ and Torbjorn Granlund of the Swedish Institute of Computer Science.
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#define TC_M88K
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#ifdef M88KCOFF
+#define COFF_MAGIC MC88OMAGIC
+#define BFD_ARCH bfd_arch_m88k
+#define COFF_FLAGS F_AR32W
+#endif
+
+#define NEED_FX_R_TYPE
+#define TC_KEEP_FX_OFFSET
+#define TC_CONS_RELOC RELOC_32
+
+/* different type of relocation available in the m88k */
+
+enum reloc_type
+{
+ RELOC_LO16, /* lo16(sym) */
+ RELOC_HI16, /* hi16(sym) */
+ RELOC_PC16, /* bb0, bb1, bcnd */
+ RELOC_PC26, /* br, bsr */
+ RELOC_32, /* jump tables, etc */
+ RELOC_IW16, /* global access through linker regs 28 */
+ NO_RELOC
+};
+
+struct reloc_info_m88k
+{
+ unsigned long int r_address;
+ unsigned int r_symbolnum:24;
+ unsigned int r_extern:1;
+ unsigned int r_pad:3;
+ enum reloc_type r_type:4;
+ long int r_addend;
+};
+
+#define relocation_info reloc_info_m88k
+
+/* The m88k uses '@' to start local labels. */
+#define LEX_AT (LEX_BEGIN_NAME | LEX_NAME)
+
+#ifndef BFD_ASSEMBLER
+#define LOCAL_LABEL(name) \
+ ((name[0] =='@' && (name [1] == 'L' || name [1] == '.')) \
+ || (name[0] == 'L' && name[1] == '0' && name[2] == '\001'))
+#endif
+
+/* The m88k uses pseudo-ops with no leading period. */
+#define NO_PSEUDO_DOT
+
+/* Don't warn on word overflow; it happens on %hi relocs. */
+#undef WARN_SIGNED_OVERFLOW_WORD
+
+#define md_convert_frag(b,s,f) {as_fatal (_("m88k convert_frag\n"));}
+
+/* We don't need to do anything special for undefined symbols. */
+#define md_undefined_symbol(s) 0
+
+/* We have no special operand handling. */
+#define md_operand(e)
+
+#ifdef M88KCOFF
+
+/* Whether a reloc should be output. */
+#define TC_COUNT_RELOC(fixp) ((fixp)->fx_addsy != NULL)
+
+/* Get the BFD reloc type to use for a gas fixS structure. */
+#define TC_COFF_FIX2RTYPE(fixp) tc_coff_fix2rtype (fixp)
+
+/* No special hook needed for symbols. */
+#define tc_coff_symbol_emit_hook(s)
+
+/* Align sections to a four byte boundary. */
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#define SUB_SEGMENT_ALIGN(SEG) max (section_alignment[(int) (SEG)], 4)
+
+/* We use a special alignment function to insert the correct nop
+ pattern in .init. */
+extern int m88k_do_align PARAMS ((int, const char *, int, int));
+#define md_do_align(n,fill,len,max,l) if (m88k_do_align(n,fill,max,len)) goto l
+
+#endif /* M88KCOFF */
diff --git a/gas/config/tc-mcore.c b/gas/config/tc-mcore.c
new file mode 100644
index 00000000000..7e784354eab
--- /dev/null
+++ b/gas/config/tc-mcore.c
@@ -0,0 +1,2183 @@
+/* tc-mcore.c -- Assemble code for M*Core
+
+ Copyright (C) 1993,1994, 1999 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "as.h"
+#include "bfd.h"
+#include "subsegs.h"
+#define DEFINE_TABLE
+#include "../opcodes/mcore-opc.h"
+#include <ctype.h>
+#include <string.h>
+
+#ifdef OBJ_ELF
+#include "elf/mcore.h"
+#endif
+
+#ifndef streq
+#define streq(a,b) (strcmp (a, b) == 0)
+#endif
+
+/* Forward declarations for dumb compilers. */
+static void mcore_s_literals PARAMS ((int));
+static void mcore_cons PARAMS ((int));
+static void mcore_float_cons PARAMS ((int));
+static void mcore_stringer PARAMS ((int));
+static int log2 PARAMS ((unsigned int));
+static char * parse_reg PARAMS ((char *, unsigned *));
+static char * parse_creg PARAMS ((char *, unsigned *));
+static char * parse_exp PARAMS ((char *, expressionS *));
+static void make_name PARAMS ((char *, char *, int));
+static int enter_literal PARAMS ((expressionS *, int));
+static char * parse_rt PARAMS ((char *, char **, int, expressionS *));
+static char * parse_imm PARAMS ((char *, unsigned *, unsigned, unsigned));
+static char * parse_mem PARAMS ((char *, unsigned *, unsigned *, unsigned));
+static void dump_literals PARAMS ((int));
+static void check_literals PARAMS ((int, int));
+static void mcore_s_text PARAMS ((int));
+static void mcore_s_data PARAMS ((int));
+#ifdef OBJ_ELF
+static void mcore_s_section PARAMS ((int));
+#endif
+
+/* Several places in this file insert raw instructions into the
+ object. They should use MCORE_INST_XXX macros to get the opcodes
+ and then use these two macros to crack the MCORE_INST value into
+ the appropriate byte values. */
+#define INST_BYTE0(x) (((x) >> 8) & 0xFF)
+#define INST_BYTE1(x) ((x) & 0xFF)
+
+const char comment_chars[] = "#/";
+const char line_separator_chars[] = ";";
+const char line_comment_chars[] = "#/";
+
+const int md_reloc_size = 8;
+
+static int relax; /* set if -relax seen */
+static int do_jsri2bsr = 0; /* change here from 1 by Cruess 19 August 97 */
+static int sifilter_mode = 0;
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+#define C(what,length) (((what) << 2) + (length))
+#define GET_WHAT(x) ((x >> 2))
+
+/* These are the two types of relaxable instruction */
+#define COND_JUMP 1
+#define UNCD_JUMP 2
+
+#define UNDEF_DISP 0
+#define COND12 1
+#define COND32 2
+#define UNCD12 1
+#define UNCD32 2
+#define UNDEF_WORD_DISP 4
+#define END 5
+
+#define C12_LEN 2
+#define C32_LEN 10 /* allow for align */
+#define U12_LEN 2
+#define U32_LEN 8 /* allow for align */
+
+
+/* Initialize the relax table */
+const relax_typeS md_relax_table[] =
+{
+{ 1, 1, 0, 0 }, /* 0: unused */
+{ 1, 1, 0, 0 }, /* 1: unused */
+{ 1, 1, 0, 0 }, /* 2: unused */
+{ 1, 1, 0, 0 }, /* 3: unused */
+{ 1, 1, 0, 0 }, /* 4: unused */
+{ 2048, -2046, C12_LEN, C(COND_JUMP, COND32) }, /* 5: C(COND_JUMP, COND12) */
+{ 0, 0, C32_LEN, 0 }, /* 6: C(COND_JUMP, COND32) */
+{ 1, 1, 0, 0 }, /* 7: unused */
+{ 1, 1, 0, 0 }, /* 8: unused */
+{ 2048, -2046, U12_LEN, C(UNCD_JUMP, UNCD32) }, /* 9: C(UNCD_JUMP, UNCD12) */
+{ 0, 0, U32_LEN, 0 }, /*10: C(UNCD_JUMP, UNCD32) */
+{ 1, 1, 0, 0 }, /*11: unused */
+{ 0, 0, 0, 0 } /*12: unused */
+};
+
+/* LITERAL POOL DATA STRUCTURES */
+struct literal
+{
+ unsigned short refcnt;
+ unsigned char ispcrel;
+ unsigned char unused;
+ expressionS e;
+};
+
+#define MAX_POOL_SIZE (1024/4)
+static struct literal litpool [MAX_POOL_SIZE];
+static unsigned poolsize;
+static unsigned poolnumber;
+static unsigned long poolspan;
+
+/* SPANPANIC: the point at which we get too scared and force a dump
+ of the literal pool, and perhaps put a branch in place.
+ Calculated as:
+ 1024 span of lrw/jmpi/jsri insn (actually span+1)
+ -2 possible alignment at the insn.
+ -2 possible alignment to get the table aligned.
+ -2 an inserted branch around the table.
+ == 1018
+ at 1018, we might be in trouble.
+ -- so we have to be smaller than 1018 and since we deal with 2-byte
+ instructions, the next good choice is 1016.
+ -- Note we have a test case that fails when we've got 1018 here. */
+#define SPANPANIC (1016) /* 1024 - 1 entry - 2 byte rounding */
+#define SPANCLOSE (900)
+#define SPANEXIT (600)
+static symbolS * poolsym; /* label for current pool */
+static char poolname[8];
+static struct hash_control * opcode_hash_control; /* Opcode mnemonics */
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ Pseudo-op name without dot
+ Function to call to execute this pseudo-op
+ Integer arg to pass to the function */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "export", s_globl, 0 },
+ { "import", s_ignore, 0 },
+ { "literals", mcore_s_literals, 0 },
+ { "page", listing_eject, 0 },
+ { "bss", s_lcomm_bytes, 1 },
+
+ /* The following are to intercept the placement of data into the text
+ section (eg addresses for a switch table), so that the space they
+ occupy can be taken into account when deciding whether or not to
+ dump the current literal pool.
+ XXX - currently we do not cope with the .space and .dcb.d directives. */
+ { "ascii", mcore_stringer, 0 },
+ { "asciz", mcore_stringer, 1 },
+ { "byte", mcore_cons, 1 },
+ { "dc", mcore_cons, 2 },
+ { "dc.b", mcore_cons, 1 },
+ { "dc.d", mcore_float_cons, 'd' },
+ { "dc.l", mcore_cons, 4 },
+ { "dc.s", mcore_float_cons, 'f' },
+ { "dc.w", mcore_cons, 2 },
+ { "dc.x", mcore_float_cons, 'x' },
+ { "double", mcore_float_cons, 'd'},
+ { "float", mcore_float_cons, 'f'},
+ { "hword", mcore_cons, 2 },
+ { "int", mcore_cons, 4 },
+ { "long", mcore_cons, 4 },
+ { "octa", mcore_cons, 16 },
+ { "quad", mcore_cons, 8 },
+ { "short", mcore_cons, 2 },
+ { "single", mcore_float_cons, 'f'},
+ { "string", mcore_stringer, 1 },
+ { "word", mcore_cons, 2 },
+
+ /* Allow for the effect of section changes. */
+ { "text", mcore_s_text, 0 },
+ { "data", mcore_s_data, 0 },
+
+#ifdef OBJ_ELF
+ { "section", mcore_s_section, 0 },
+ { "section.s", mcore_s_section, 0 },
+ { "sect", mcore_s_section, 0 },
+ { "sect.s", mcore_s_section, 0 },
+#endif
+ { 0, 0, 0 }
+};
+
+static void
+mcore_s_literals (ignore)
+ int ignore;
+{
+ dump_literals (0);
+ demand_empty_rest_of_line ();
+}
+
+
+static void
+mcore_cons (nbytes)
+ int nbytes;
+{
+ if (now_seg == text_section)
+ {
+ char * ptr = input_line_pointer;
+ int commas = 1;
+
+ /* Count the number of commas on the line. */
+ while (! is_end_of_line [* ptr])
+ commas += * ptr ++ == ',';
+
+ poolspan += nbytes * commas;
+ }
+
+ cons (nbytes);
+
+ /* In theory we ought to call check_literals (2,0) here in case
+ we need to dump the literal table. We cannot do this however,
+ as the directives that we are intercepting may be being used
+ to build a switch table, and we must not interfere with its
+ contents. Instead we cross our fingers and pray... */
+}
+
+static void
+mcore_float_cons (float_type)
+ int float_type;
+{
+ if (now_seg == text_section)
+ {
+ char * ptr = input_line_pointer;
+ int commas = 1;
+
+#ifdef REPEAT_CONS_EXPRESSIONS
+#error REPEAT_CONS_EXPRESSIONS not handled
+#endif
+
+ /* Count the number of commas on the line. */
+ while (! is_end_of_line [* ptr])
+ commas += * ptr ++ == ',';
+
+ /* We would like to compute "hex_float (float_type) * commas"
+ but hex_float is not exported from read.c */
+ float_type == 'f' ? 4 : (float_type == 'd' ? 8 : 12);
+ poolspan += float_type * commas;
+ }
+
+ float_cons (float_type);
+
+ /* See the comment in mcore_cons () about calling check_literals.
+ It is unlikely that a switch table will be constructed using
+ floating point values, but it is still likely that an indexed
+ table of floating point constants is being created by these
+ directives, so again we must not interfere with their placement. */
+}
+
+static void
+mcore_stringer (append_zero)
+ int append_zero;
+{
+ if (now_seg == text_section)
+ {
+ char * ptr = input_line_pointer;
+
+ /* In theory we should compute how many bytes are going to
+ be occupied by the string(s) and add this to the poolspan.
+ To keep things simple however, we just add the number of
+ bytes left on the current line. This will be an over-
+ estimate, which is OK, and automatically allows for the
+ appending a zero byte, since the real string(s) is/are
+ required to be enclosed in double quotes. */
+ while (! is_end_of_line [* ptr])
+ ptr ++;
+
+ poolspan += ptr - input_line_pointer;
+ }
+
+ stringer (append_zero);
+
+ /* We call check_literals here in case a large number of strings are
+ being placed into the text section with a sequence of stringer
+ directives. In theory we could be upsetting something if these
+ strings are actually in an indexed table instead of referenced by
+ individual labels. Let us hope that that never happens. */
+ check_literals (2, 0);
+}
+
+static void
+mcore_s_text (ignore)
+ int ignore;
+{
+ dump_literals (0);
+
+ s_text (ignore);
+}
+
+static void
+mcore_s_data (ignore)
+ int ignore;
+{
+ dump_literals (0);
+
+ s_data (ignore);
+}
+
+/* This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs. */
+void
+md_begin ()
+{
+ mcore_opcode_info * opcode;
+ char * prev_name = "";
+
+ opcode_hash_control = hash_new ();
+
+ /* Insert unique names into hash table */
+ for (opcode = mcore_table; opcode->name; opcode ++)
+ {
+ if (streq (prev_name, opcode->name))
+ {
+ /* Make all the opcodes with the same name point to the same
+ string. */
+ opcode->name = prev_name;
+ }
+ else
+ {
+ prev_name = opcode->name;
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ }
+ }
+}
+
+static int reg_m;
+static int reg_n;
+static expressionS immediate; /* absolute expression */
+
+/* Get a log2(val). */
+static int
+log2 (val)
+ unsigned int val;
+{
+ int log = -1;
+ while (val != 0)
+ {
+ log ++;
+ val >>= 1;
+ }
+
+ return log;
+}
+
+/* Try to parse a reg name. */
+static char *
+parse_reg (s, reg)
+ char * s;
+ unsigned * reg;
+{
+ /* Strip leading whitespace. */
+ while (isspace (* s))
+ ++ s;
+
+ if (tolower (s[0]) == 'r')
+ {
+ if (s[1] == '1' && s[2] >= '0' && s[2] <= '5')
+ {
+ *reg = 10 + s[2] - '0';
+ return s + 3;
+ }
+
+ if (s[1] >= '0' && s[1] <= '9')
+ {
+ *reg = s[1] - '0';
+ return s + 2;
+ }
+ }
+ else if ( tolower (s[0]) == 's'
+ && tolower (s[1]) == 'p'
+ && (isspace (s[2]) || s[2] == ','))
+ {
+ * reg = 0;
+ return s + 2;
+ }
+
+ as_bad (_("register expected, but saw '%.6s'"), s);
+ return s;
+}
+
+static struct Cregs
+{
+ char * name;
+ unsigned int crnum;
+}
+cregs[] =
+{
+ { "psr", 0},
+ { "vbr", 1},
+ { "epsr", 2},
+ { "fpsr", 3},
+ { "epc", 4},
+ { "fpc", 5},
+ { "ss0", 6},
+ { "ss1", 7},
+ { "ss2", 8},
+ { "ss3", 9},
+ { "ss4", 10},
+ { "gcr", 11},
+ { "gsr", 12},
+ { "", 0}
+};
+
+static char *
+parse_creg (s, reg)
+ char * s;
+ unsigned * reg;
+{
+ int i;
+
+ /* Strip leading whitespace. */
+ while (isspace (* s))
+ ++s;
+
+ if ((tolower (s[0]) == 'c' && tolower (s[1]) == 'r'))
+ {
+ if (s[2] == '3' && s[3] >= '0' && s[3] <= '1')
+ {
+ *reg = 30 + s[3] - '0';
+ return s + 4;
+ }
+
+ if (s[2] == '2' && s[3] >= '0' && s[3] <= '9')
+ {
+ *reg = 20 + s[3] - '0';
+ return s + 4;
+ }
+
+ if (s[2] == '1' && s[3] >= '0' && s[3] <= '9')
+ {
+ *reg = 10 + s[3] - '0';
+ return s + 4;
+ }
+
+ if (s[2] >= '0' && s[2] <= '9')
+ {
+ *reg = s[2] - '0';
+ return s + 3;
+ }
+ }
+
+ /* Look at alternate creg names before giving error. */
+ for (i = 0; cregs[i].name[0] != '\0'; i++)
+ {
+ char buf [10];
+ int length;
+ int j;
+
+ length = strlen (cregs[i].name);
+
+ for (j = 0; j < length; j++)
+ buf[j] = tolower (s[j]);
+
+ if (strncmp (cregs[i].name, buf, length) == 0)
+ {
+ *reg = cregs[i].crnum;
+ return s + length;
+ }
+ }
+
+ as_bad (_("control register expected, but saw '%.6s'"), s);
+
+ return s;
+}
+
+static char *
+parse_exp (s, e)
+ char * s;
+ expressionS * e;
+{
+ char * save;
+ char * new;
+
+ /* Skip whitespace. */
+ while (isspace (* s))
+ ++ s;
+
+ save = input_line_pointer;
+ input_line_pointer = s;
+
+ expression (e);
+
+ if (e->X_op == O_absent)
+ as_bad (_("missing operand"));
+
+ new = input_line_pointer;
+ input_line_pointer = save;
+
+ return new;
+}
+
+static void
+make_name (s, p, n)
+ char * s;
+ char * p;
+ int n;
+{
+ static const char hex[] = "0123456789ABCDEF";
+
+ s[0] = p[0];
+ s[1] = p[1];
+ s[2] = p[2];
+ s[3] = hex[(n >> 12) & 0xF];
+ s[4] = hex[(n >> 8) & 0xF];
+ s[5] = hex[(n >> 4) & 0xF];
+ s[6] = hex[(n) & 0xF];
+ s[7] = 0;
+}
+
+static void
+dump_literals (isforce)
+ int isforce;
+{
+ int i;
+ struct literal * p;
+ struct symbol * brarsym;
+
+ if (poolsize == 0)
+ return;
+
+ /* Must we branch around the literal table? */
+ if (isforce)
+ {
+ char * output;
+ char brarname[8];
+
+ make_name (brarname, ".YP.", poolnumber);
+
+ brarsym = symbol_make (brarname);
+
+ symbol_table_insert (brarsym);
+
+ output = frag_var (rs_machine_dependent,
+ md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length,
+ C (UNCD_JUMP, 0), brarsym, 0, 0);
+ output[0] = INST_BYTE0 (MCORE_INST_BR); /* br .+xxx */
+ output[1] = INST_BYTE1 (MCORE_INST_BR);
+ }
+
+ /* Make sure that the section is sufficiently aligned and that
+ the literal table is aligned within it. */
+ record_alignment (now_seg, 2);
+ frag_align (2, 0, 0);
+
+ colon (S_GET_NAME (poolsym));
+
+ for (i = 0, p = litpool; i < poolsize; i++, p++)
+ emit_expr (& p->e, 4);
+
+ if (isforce)
+ colon (S_GET_NAME (brarsym));
+
+ poolsize = 0;
+}
+
+static void
+check_literals (kind, offset)
+ int kind;
+ int offset;
+{
+ poolspan += offset;
+
+ /* SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
+ SPANPANIC means that we must dump now.
+ kind == 0 is any old instruction.
+ kind > 0 means we just had a control transfer instruction.
+ kind == 1 means within a function
+ kind == 2 means we just left a function
+
+ The dump_literals (1) call inserts a branch around the table, so
+ we first look to see if its a situation where we won't have to
+ insert a branch (e.g., the previous instruction was an unconditional
+ branch).
+
+ SPANPANIC is the point where we must dump a single-entry pool.
+ it accounts for alignments and an inserted branch.
+ the 'poolsize*2' accounts for the scenario where we do:
+ lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
+ Note that the 'lit2' reference is 2 bytes further along
+ but the literal it references will be 4 bytes further along,
+ so we must consider the poolsize into this equation.
+ This is slightly over-cautious, but guarantees that we won't
+ panic because a relocation is too distant. */
+
+ if (poolspan > SPANCLOSE && kind > 0)
+ dump_literals (0);
+ else if (poolspan > SPANEXIT && kind > 1)
+ dump_literals (0);
+ else if (poolspan >= (SPANPANIC - poolsize * 2))
+ dump_literals (1);
+}
+
+static int
+enter_literal (e, ispcrel)
+ expressionS * e;
+ int ispcrel;
+{
+ int i;
+ struct literal * p;
+
+ if (poolsize >= MAX_POOL_SIZE - 2)
+ {
+ /* The literal pool is as full as we can handle. We have
+ to be 2 entries shy of the 1024/4=256 entries because we
+ have to allow for the branch (2 bytes) and the alignment
+ (2 bytes before the first insn referencing the pool and
+ 2 bytes before the pool itself) == 6 bytes, rounds up
+ to 2 entries. */
+ dump_literals (1);
+ }
+
+ if (poolsize == 0)
+ {
+ /* Create new literal pool. */
+ if (++ poolnumber > 0xFFFF)
+ as_fatal (_("more than 65K literal pools"));
+
+ make_name (poolname, ".XP.", poolnumber);
+ poolsym = symbol_make (poolname);
+ symbol_table_insert (poolsym);
+ poolspan = 0;
+ }
+
+ /* Search pool for value so we don't have duplicates. */
+ for (p = litpool, i = 0; i < poolsize; i++, p++)
+ {
+ if (e->X_op == p->e.X_op
+ && e->X_add_symbol == p->e.X_add_symbol
+ && e->X_add_number == p->e.X_add_number
+ && ispcrel == p->ispcrel)
+ {
+ p->refcnt ++;
+ return i;
+ }
+ }
+
+ p->refcnt = 1;
+ p->ispcrel = ispcrel;
+ p->e = * e;
+
+ poolsize ++;
+
+ return i;
+}
+
+/* Parse a literal specification. -- either new or old syntax.
+ old syntax: the user supplies the label and places the literal.
+ new syntax: we put it into the literal pool. */
+static char *
+parse_rt (s, outputp, ispcrel, ep)
+ char * s;
+ char ** outputp;
+ int ispcrel;
+ expressionS * ep;
+{
+ expressionS e;
+ int n;
+
+ if (ep)
+ /* Indicate nothing there. */
+ ep->X_op = O_absent;
+
+ if (*s == '[')
+ {
+ s = parse_exp (s + 1, & e);
+
+ if (*s == ']')
+ s++;
+ else
+ as_bad (_("missing ']'"));
+ }
+ else
+ {
+ s = parse_exp (s, & e);
+
+ n = enter_literal (& e, ispcrel);
+
+ if (ep)
+ *ep = e;
+
+ /* Create a reference to pool entry. */
+ e.X_op = O_symbol;
+ e.X_add_symbol = poolsym;
+ e.X_add_number = n << 2;
+ }
+
+ * outputp = frag_more (2);
+
+ fix_new_exp (frag_now, (*outputp) - frag_now->fr_literal, 2, & e, 1,
+ BFD_RELOC_MCORE_PCREL_IMM8BY4);
+
+ return s;
+}
+
+static char *
+parse_imm (s, val, min, max)
+ char * s;
+ unsigned * val;
+ unsigned min;
+ unsigned max;
+{
+ char * new;
+ expressionS e;
+
+ new = parse_exp (s, & e);
+
+ if (e.X_op == O_absent)
+ ; /* An error message has already been emitted. */
+ else if (e.X_op != O_constant)
+ as_bad (_("operand must be a constant"));
+ else if (e.X_add_number < min || e.X_add_number > max)
+ as_bad (_("operand must be absolute in range %d..%d, not %d"),
+ min, max, e.X_add_number);
+
+ * val = e.X_add_number;
+
+ return new;
+}
+
+static char *
+parse_mem (s, reg, off, siz)
+ char * s;
+ unsigned * reg;
+ unsigned * off;
+ unsigned siz;
+{
+ char * new;
+
+ * off = 0;
+
+ while (isspace (* s))
+ ++ s;
+
+ if (* s == '(')
+ {
+ s = parse_reg (s + 1, reg);
+
+ while (isspace (* s))
+ ++ s;
+
+ if (* s == ',')
+ {
+ s = parse_imm (s + 1, off, 0, 63);
+
+ if (siz > 1)
+ {
+ if (siz > 2)
+ {
+ if (* off & 0x3)
+ as_bad (_("operand must be a multiple of 4"));
+
+ * off >>= 2;
+ }
+ else
+ {
+ if (* off & 0x1)
+ as_bad (_("operand must be a multiple of 2"));
+
+ * off >>= 1;
+ }
+ }
+ }
+
+ while (isspace (* s))
+ ++ s;
+
+ if (* s == ')')
+ s ++;
+ }
+ else
+ as_bad (_("base register expected"));
+
+ return s;
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to. */
+
+void
+md_assemble (str)
+ char * str;
+{
+ char * op_start;
+ char * op_end;
+ mcore_opcode_info * opcode;
+ char * output;
+ int nlen = 0;
+ unsigned short inst;
+ unsigned reg;
+ unsigned off;
+ unsigned isize;
+ expressionS e;
+ char name[20];
+
+ /* Drop leading whitespace. */
+ while (isspace (* str))
+ str ++;
+
+ /* Find the op code end. */
+ for (op_start = op_end = str;
+ * op_end && nlen < 20 && !is_end_of_line [*op_end] && *op_end != ' ';
+ op_end++)
+ {
+ name[nlen] = op_start[nlen];
+ nlen++;
+ }
+
+ name [nlen] = 0;
+
+ if (nlen == 0)
+ {
+ as_bad (_("can't find opcode "));
+ return;
+ }
+
+ opcode = (mcore_opcode_info *) hash_find (opcode_hash_control, name);
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode \"%s\""), name);
+ return;
+ }
+
+ inst = opcode->inst;
+ isize = 2;
+
+ switch (opcode->opclass)
+ {
+ case O0:
+ output = frag_more (2);
+ break;
+
+ case OT:
+ op_end = parse_imm (op_end + 1, & reg, 0, 3);
+ inst |= reg;
+ output = frag_more (2);
+ break;
+
+ case O1:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+ output = frag_more (2);
+ break;
+
+ case JMP:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+ output = frag_more (2);
+ /* In a sifilter mode, we emit this insn 2 times,
+ fixes problem of an interrupt during a jmp.. */
+ if (sifilter_mode)
+ {
+ output[0] = (inst >> 8);
+ output[1] = (inst);
+ output = frag_more (2);
+ }
+ break;
+
+ case JSR:
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg == 15)
+ as_bad (_("invalid register: r15 illegal"));
+
+ inst |= reg;
+ output = frag_more (2);
+
+ if (sifilter_mode)
+ {
+ /* Replace with: bsr .+2 ; addi r15,6; jmp rx ; jmp rx */
+ inst = MCORE_INST_BSR; /* with 0 displacement */
+ output[0] = (inst >> 8);
+ output[1] = (inst);
+
+ output = frag_more (2);
+ inst = MCORE_INST_ADDI;
+ inst |= 15; /* addi r15,6 */
+ inst |= (6 - 1) << 4; /* over the jmp's */
+ output[0] = (inst >> 8);
+ output[1] = (inst);
+
+ output = frag_more (2);
+ inst = MCORE_INST_JMP | reg;
+ output[0] = (inst >> 8);
+ output[1] = (inst);
+
+ output = frag_more (2); /* 2nd emitted in fallthru */
+ }
+ break;
+
+ case OC:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (*op_end == ',')
+ {
+ op_end = parse_creg (op_end + 1, & reg);
+ inst |= reg << 4;
+ }
+
+ output = frag_more (2);
+ break;
+
+ case O2:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case X1: /* Handle both syntax-> xtrb- r1,rx OR xtrb- rx */
+ op_end = parse_reg (op_end + 1, & reg);
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',') /* xtrb- r1,rx */
+ {
+ if (reg != 1)
+ as_bad (_("destination register must be r1"));
+
+ op_end = parse_reg (op_end + 1, & reg);
+ }
+
+ inst |= reg;
+ output = frag_more (2);
+ break;
+
+ case O1R1: /* div- rx,r1 */
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_reg (op_end + 1, & reg);
+ if (reg != 1)
+ as_bad (_("source register must be r1"));
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case OI:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 32);
+ inst |= (reg - 1) << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case OB:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 0, 31);
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case OB2: /* like OB, but arg is 2^n instead of n */
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 1 << 31);
+ /* Further restrict the immediate to a power of two. */
+ if ((reg & (reg - 1)) == 0)
+ reg = log2 (reg);
+ else
+ {
+ reg = 0;
+ as_bad (_("immediate is not a power of two"));
+ }
+ inst |= (reg) << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case OBRa: /* Specific for bgeni: imm of 0->6 translate to movi. */
+ case OBRb:
+ case OBRc:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 0, 31);
+ /* immediate values of 0 -> 6 translate to movi */
+ if (reg <= 6)
+ {
+ inst = (inst & 0xF) | MCORE_INST_BGENI_ALT;
+ reg = 0x1 << reg;
+ as_warn (_("translating bgeni to movi"));
+ }
+ inst &= ~ 0x01f0;
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case OBR2: /* like OBR, but arg is 2^n instead of n */
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 1 << 31);
+
+ /* Further restrict the immediate to a power of two. */
+ if ((reg & (reg - 1)) == 0)
+ reg = log2 (reg);
+ else
+ {
+ reg = 0;
+ as_bad (_("immediate is not a power of two"));
+ }
+
+ /* Immediate values of 0 -> 6 translate to movi. */
+ if (reg <= 6)
+ {
+ inst = (inst & 0xF) | MCORE_INST_BGENI_ALT;
+ reg = 0x1 << reg;
+ as_warn (_("translating mgeni to movi"));
+ }
+
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case OMa: /* Specific for bmaski: imm 1->7 translate to movi. */
+ case OMb:
+ case OMc:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 32);
+
+ /* Immediate values of 1 -> 7 translate to movi. */
+ if (reg <= 7)
+ {
+ inst = (inst & 0xF) | MCORE_INST_BMASKI_ALT;
+ reg = (0x1 << reg) - 1;
+ inst |= reg << 4;
+
+ as_warn (_("translating bmaski to movi"));
+ }
+ else
+ {
+ inst &= ~ 0x01F0;
+ inst |= (reg & 0x1F) << 4;
+ }
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case SI:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 31);
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case I7:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 0, 0x7F);
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case LS:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg << 8;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ int size;
+
+ if ((inst & 0x6000) == 0)
+ size = 4;
+ else if ((inst & 0x6000) == 0x4000)
+ size = 2;
+ else if ((inst & 0x6000) == 0x2000)
+ size = 1;
+
+ op_end = parse_mem (op_end + 1, & reg, & off, size);
+
+ if (off > 16)
+ as_bad (_("displacement too large (%d)"), off);
+ else
+ inst |= (reg) | (off << 4);
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case LR:
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg == 0 || reg == 15)
+ as_bad (_("Invalid register: r0 and r15 illegal"));
+
+ inst |= (reg << 8);
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ /* parse_rt calls frag_more() for us. */
+ input_line_pointer = parse_rt (op_end + 1, & output, 0, 0);
+ else
+ {
+ as_bad (_("second operand missing"));
+ output = frag_more (2); /* save its space */
+ }
+ break;
+
+ case LJ:
+ input_line_pointer = parse_rt (op_end + 1, & output, 1, 0);
+ /* parse_rt() calls frag_more() for us. */
+ break;
+
+ case RM:
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg == 0 || reg == 15)
+ as_bad (_("bad starting register: r0 and r15 invalid"));
+
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == '-')
+ {
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg != 15)
+ as_bad (_("ending register must be r15"));
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+ }
+
+ if (* op_end == ',')
+ {
+ op_end ++;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == '(')
+ {
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg != 0)
+ as_bad (_("bad base register: must be r0"));
+
+ if (* op_end == ')')
+ op_end ++;
+ }
+ else
+ as_bad (_("base register expected"));
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case RQ:
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg != 4)
+ as_fatal (_("first register must be r4"));
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == '-')
+ {
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg != 7)
+ as_fatal (_("last register must be r7"));
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end ++;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == '(')
+ {
+ op_end = parse_reg (op_end + 1, & reg);
+
+ if (reg >= 4 && reg <= 7)
+ as_fatal ("base register cannot be r4, r5, r6, or r7");
+
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ')')
+ op_end ++;
+ }
+ else
+ as_bad (_("base register expected"));
+ }
+ else
+ as_bad (_("second operand missing"));
+ }
+ else
+ as_bad (_("reg-reg expected"));
+
+ output = frag_more (2);
+ break;
+
+ case BR:
+ input_line_pointer = parse_exp (op_end + 1, & e);
+
+ output = frag_more (2);
+
+ fix_new_exp (frag_now, output-frag_now->fr_literal,
+ 2, & e, 1, BFD_RELOC_MCORE_PCREL_IMM11BY2);
+ break;
+
+ case BL:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg << 4;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_exp (op_end + 1, & e);
+ output = frag_more (2);
+
+ fix_new_exp (frag_now, output-frag_now->fr_literal,
+ 2, & e, 1, BFD_RELOC_MCORE_PCREL_IMM4BY2);
+ }
+ else
+ {
+ as_bad (_("second operand missing"));
+ output = frag_more (2);
+ }
+ break;
+
+ case JC:
+ input_line_pointer = parse_exp (op_end + 1, & e);
+
+ output = frag_var (rs_machine_dependent,
+ md_relax_table[C (COND_JUMP, COND32)].rlx_length,
+ md_relax_table[C (COND_JUMP, COND12)].rlx_length,
+ C (COND_JUMP, 0), e.X_add_symbol, e.X_add_number, 0);
+ isize = C32_LEN;
+ break;
+
+ case JU:
+ input_line_pointer = parse_exp (op_end + 1, & e);
+ output = frag_var (rs_machine_dependent,
+ md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length,
+ C (UNCD_JUMP, 0), e.X_add_symbol, e.X_add_number, 0);
+ isize = U32_LEN;
+ break;
+
+ case JL:
+ inst = MCORE_INST_JSRI; /* jsri */
+ input_line_pointer = parse_rt (op_end + 1, & output, 1, & e);
+ /* parse_rt() calls frag_more for us */
+
+ /* Only do this if we know how to do it ... */
+ if (e.X_op != O_absent && do_jsri2bsr)
+ {
+ /* Look at adding the R_PCREL_JSRIMM11BY2. */
+ fix_new_exp (frag_now, output-frag_now->fr_literal,
+ 2, & e, 1, BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2);
+ }
+ break;
+
+ case RSI: /* SI, but imm becomes 32-imm */
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 31);
+
+ reg = 32 - reg;
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case DO21: /* O2, dup rd, lit must be 1 */
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+ inst |= reg << 4;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 31);
+
+ if (reg != 1)
+ as_bad (_("second operand must be 1"));
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ case SIa:
+ op_end = parse_reg (op_end + 1, & reg);
+ inst |= reg;
+
+ /* Skip whitespace. */
+ while (isspace (* op_end))
+ ++ op_end;
+
+ if (* op_end == ',')
+ {
+ op_end = parse_imm (op_end + 1, & reg, 1, 31);
+
+ if (reg == 0)
+ as_bad (_("zero used as immediate value"));
+
+ inst |= reg << 4;
+ }
+ else
+ as_bad (_("second operand missing"));
+
+ output = frag_more (2);
+ break;
+
+ default:
+ as_bad (_("unimplemented opcode \"%s\""), name);
+ }
+
+ output[0] = inst >> 8;
+ output[1] = inst;
+
+ check_literals (opcode->transfer, isize);
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char * name;
+{
+ return 0;
+}
+
+void
+md_mcore_end ()
+{
+ dump_literals (0);
+ subseg_set (text_section, 0);
+}
+
+/* Various routines to kill one day. */
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char * litP;
+ int * sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE * wordP;
+ char * t;
+ char * atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_NTOF()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+
+ return 0;
+}
+
+CONST char * md_shortopts = "";
+
+#define OPTION_RELAX (OPTION_MD_BASE)
+#define OPTION_JSRI2BSR_ON (OPTION_MD_BASE + 1)
+#define OPTION_JSRI2BSR_OFF (OPTION_MD_BASE + 2)
+#define OPTION_SIFILTER_ON (OPTION_MD_BASE + 3)
+#define OPTION_SIFILTER_OFF (OPTION_MD_BASE + 4)
+
+struct option md_longopts[] =
+{
+ { "relax", no_argument, NULL, OPTION_RELAX},
+ { "no-jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_OFF},
+ { "jsri2bsr", no_argument, NULL, OPTION_JSRI2BSR_ON},
+ { "sifilter", no_argument, NULL, OPTION_SIFILTER_ON},
+ { "no-sifilter", no_argument, NULL, OPTION_SIFILTER_OFF},
+ { NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ int i;
+ char * p;
+
+ switch (c)
+ {
+
+ case OPTION_RELAX: relax = 1; break;
+ case OPTION_JSRI2BSR_ON: do_jsri2bsr = 1; break;
+ case OPTION_JSRI2BSR_OFF: do_jsri2bsr = 0; break;
+ case OPTION_SIFILTER_ON: sifilter_mode = 1; break;
+ case OPTION_SIFILTER_OFF: sifilter_mode = 0; break;
+ default: return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE * stream;
+{
+ fprintf (stream, _("\
+MCORE specific options:\n\
+ -{no-}jsri2bsr {dis}able jsri to bsr transformation (def: off)\n\
+ -{no-}sifilter {dis}able silicon filter behavior (def: off)\n\
+ -relax alter jump instructions for long displacements\n"));
+}
+
+int md_short_jump_size;
+
+void
+md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
+ char * ptr;
+ addressT from_Nddr;
+ addressT to_Nddr;
+ fragS * frag;
+ symbolS * to_symbol;
+{
+ as_fatal (_("failed sanity check: short_jump"));
+}
+
+void
+md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
+ char * ptr;
+ addressT from_Nddr;
+ addressT to_Nddr;
+ fragS * frag;
+ symbolS * to_symbol;
+{
+ as_fatal (_("failed sanity check: long_jump"));
+}
+
+/* Called after relaxing, change the frags so they know how big they are. */
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd * abfd;
+ segT sec;
+ register fragS * fragP;
+{
+ unsigned char * buffer;
+ int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
+
+ buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+ targ_addr += fragP->fr_symbol->sy_frag->fr_address;
+
+ switch (fragP->fr_subtype)
+ {
+ case C (COND_JUMP, COND12):
+ case C (UNCD_JUMP, UNCD12):
+ {
+ /* Get the address of the end of the instruction */
+ int next_inst = fragP->fr_fix + fragP->fr_address + 2;
+ unsigned char t0;
+ int disp = targ_addr - next_inst;
+
+ if (disp & 1)
+ as_bad (_("odd displacement at %x"), next_inst - 2);
+
+ disp >>= 1;
+ t0 = buffer[0] & 0xF8;
+
+ md_number_to_chars (buffer, disp, 2);
+
+ buffer[0] = (buffer[0] & 0x07) | t0;
+ fragP->fr_fix += 2;
+ fragP->fr_var = 0;
+ }
+ break;
+
+ case C (COND_JUMP, COND32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ {
+ /* A conditional branch wont fit into 12 bits so:
+ * b!cond 1f
+ * jmpi 0f
+ * .align 2
+ * 0: .long disp
+ * 1:
+ *
+ * if the b!cond is 4 byte aligned, the literal which would
+ * go at x+4 will also be aligned.
+ */
+ int first_inst = fragP->fr_fix + fragP->fr_address;
+ int needpad = (first_inst & 3);
+
+ buffer[0] ^= 0x08; /* Toggle T/F bit */
+
+ buffer[2] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi */
+ buffer[3] = INST_BYTE1 (MCORE_INST_JMPI);
+
+ if (needpad)
+ {
+ buffer[1] = 4; /* branch over jmpi, pad, and ptr */
+ buffer[3] = 1; /* jmpi offset of 1 gets the pointer */
+ buffer[4] = 0; /* alignment/pad */
+ buffer[5] = 0;
+ buffer[6] = 0; /* space for 32 bit address */
+ buffer[7] = 0;
+ buffer[8] = 0;
+ buffer[9] = 0;
+
+ /* Make reloc for the long disp */
+ fix_new (fragP, fragP->fr_fix + 6, 4,
+ fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
+
+ fragP->fr_fix += C32_LEN;
+ }
+ else
+ {
+ /* See comment below about this given gas' limitations for
+ shrinking the fragment. '3' is the amount of code that
+ we inserted here, but '4' is right for the space we reserved
+ for this fragment. */
+ buffer[1] = 3; /* branch over jmpi, and ptr */
+ buffer[3] = 0; /* jmpi offset of 0 gets the pointer */
+ buffer[4] = 0; /* space for 32 bit address */
+ buffer[5] = 0;
+ buffer[6] = 0;
+ buffer[7] = 0;
+
+ /* Make reloc for the long disp. */
+ fix_new (fragP, fragP->fr_fix + 4, 4,
+ fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
+ fragP->fr_fix += C32_LEN;
+
+ /* frag is actually shorter (see the other side of this ifdef)
+ but gas isn't prepared for that. We have to re-adjust
+ the branch displacement so that it goes beyond the
+ full length of the fragment, not just what we actually
+ filled in. */
+ buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */
+ }
+
+ fragP->fr_var = 0;
+ }
+ break;
+
+ case C (UNCD_JUMP, UNCD32):
+ case C (UNCD_JUMP, UNDEF_WORD_DISP):
+ {
+ /* An unconditional branch will not fit in 12 bits, make code which
+ looks like:
+ jmpi 0f
+ .align 2
+ 0: .long disp
+ we need a pad if "first_inst" is 4 byte aligned.
+ [because the natural literal place is x + 2] */
+ int first_inst = fragP->fr_fix + fragP->fr_address;
+ int needpad = !(first_inst & 3);
+
+ buffer[0] = INST_BYTE0 (MCORE_INST_JMPI); /* Build jmpi */
+ buffer[1] = INST_BYTE1 (MCORE_INST_JMPI);
+
+ if (needpad)
+ {
+ buffer[1] = 1; /* jmpi offset of 1 since padded */
+ buffer[2] = 0; /* alignment */
+ buffer[3] = 0;
+ buffer[4] = 0; /* space for 32 bit address */
+ buffer[5] = 0;
+ buffer[6] = 0;
+ buffer[7] = 0;
+
+ /* Make reloc for the long disp */
+ fix_new (fragP, fragP->fr_fix + 4, 4,
+ fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
+
+ fragP->fr_fix += U32_LEN;
+ }
+ else
+ {
+ buffer[1] = 0; /* jmpi offset of 0 if no pad */
+ buffer[2] = 0; /* space for 32 bit address */
+ buffer[3] = 0;
+ buffer[4] = 0;
+ buffer[5] = 0;
+
+ /* Make reloc for the long disp */
+ fix_new (fragP, fragP->fr_fix + 2, 4,
+ fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
+ fragP->fr_fix += U32_LEN;
+ }
+
+ fragP->fr_var = 0;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Applies the desired value to the specified location.
+ Also sets up addends for 'rela' type relocations. */
+int
+md_apply_fix3 (fixP, valp, segment)
+ fixS * fixP;
+ valueT * valp;
+ segT segment;
+{
+ char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
+ const char * symname;
+ /* Note: use offsetT because it is signed, valueT is unsigned. */
+ offsetT val = (offsetT) * valp;
+
+ symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
+ /* Save this for the addend in the relocation record. */
+ fixP->fx_addnumber = val;
+
+ /* If the fix is relative to a symbol which is not defined, or not
+ in the same segment as the fix, we cannot resolve it here. */
+ if (fixP->fx_addsy != NULL
+ && ( ! S_IS_DEFINED (fixP->fx_addsy)
+ || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
+ {
+ fixP->fx_done = 0;
+#ifdef OBJ_ELF
+ /* For ELF we can just return and let the reloc that will be generated
+ take care of everything. For COFF we still have to insert 'val'
+ into the insn since the addend field will be ignored. */
+ return 0;
+#endif
+ }
+ else
+ fixP->fx_done = 1;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_MCORE_PCREL_IMM11BY2: /* second byte of 2 byte opcode */
+ if ((val & 1) != 0)
+ as_bad_where (file, fixP->fx_line,
+ _("odd distance branch (0x%x bytes)"), val);
+ val /= 2;
+ if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1))
+ as_bad_where (file, fixP->fx_line,
+ _("pcrel for branch to %s too far (0x%x)"),
+ symname, val);
+ buf[0] |= ((val >> 8) & 0x7);
+ buf[1] |= (val & 0xff);
+ break;
+
+ case BFD_RELOC_MCORE_PCREL_IMM8BY4: /* lower 8 bits of 2 byte opcode */
+ val += 3;
+ val /= 4;
+ if (val & ~0xff)
+ as_bad_where (file, fixP->fx_line,
+ _("pcrel for lrw/jmpi/jsri to %s too far (0x%x)"),
+ symname, val);
+ else
+ buf[1] |= (val & 0xff);
+ break;
+
+ case BFD_RELOC_MCORE_PCREL_IMM4BY2: /* loopt instruction */
+ if ((val < -32) || (val > -2))
+ as_bad_where (file, fixP->fx_line,
+ _("pcrel for loopt too far (0x%x)"), val);
+ val /= 2;
+ buf[1] |= (val & 0xf);
+ break;
+
+ case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2:
+ /* Conditional linker map jsri to bsr. */
+ /* If its a local target and close enough, fix it.
+ NB: >= -2k for backwards bsr; < 2k for forwards... */
+ if (fixP->fx_addsy == 0 && val >= -2048 && val < 2048)
+ {
+ long nval = (val / 2) & 0x7ff;
+ nval |= MCORE_INST_BSR;
+
+ /* REPLACE the instruction, don't just modify it. */
+ buf[0] = ((nval >> 8) & 0xff);
+ buf[1] = (nval & 0xff);
+ }
+ else
+ fixP->fx_done = 0;
+ break;
+
+ case BFD_RELOC_MCORE_PCREL_32:
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ break;
+
+ default:
+ if (fixP->fx_addsy != NULL)
+ {
+ /* If the fix is an absolute reloc based on a symbol's
+ address, then it cannot be resolved until the final link. */
+ fixP->fx_done = 0;
+ }
+#ifdef OBJ_ELF
+ else
+#endif
+ {
+ if (fixP->fx_size == 4)
+ {
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ *buf++ = val >> 8;
+ *buf = val;
+ }
+ else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
+ {
+ *buf++ = val >> 8;
+ *buf = val;
+ }
+ else if (fixP->fx_size == 1 && val >= -256 && val <= 255)
+ *buf = val;
+ else
+ abort ();
+ }
+ break;
+ }
+
+ return 0; /* Return value is ignored. */
+}
+
+void
+md_operand (expressionP)
+ expressionS * expressionP;
+{
+ /* Ignore leading hash symbol, if poresent. */
+ if (* input_line_pointer == '#')
+ {
+ input_line_pointer ++;
+ expression (expressionP);
+ }
+}
+
+int md_long_jump_size;
+
+/* Called just before address relaxation, return the length
+ by which a fragment must grow to reach it's destination. */
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS * fragP;
+ register segT segment_type;
+{
+ switch (fragP->fr_subtype)
+ {
+ case C (UNCD_JUMP, UNDEF_DISP):
+ /* Used to be a branch to somewhere which was unknown. */
+ if (!fragP->fr_symbol)
+ {
+ fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
+ fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
+ }
+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
+ fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
+ }
+ else
+ {
+ fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
+ fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
+ return md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
+ }
+ break;
+
+ default:
+ abort ();
+
+ case C (COND_JUMP, UNDEF_DISP):
+ /* Used to be a branch to somewhere which was unknown. */
+ if (fragP->fr_symbol
+ && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ /* Got a symbol and it's defined in this segment, become byte
+ sized - maybe it will fix up */
+ fragP->fr_subtype = C (COND_JUMP, COND12);
+ fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
+ }
+ else if (fragP->fr_symbol)
+ {
+ /* Its got a segment, but its not ours, so it will always be long. */
+ fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
+ fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length;
+ return md_relax_table[C (COND_JUMP, COND32)].rlx_length;
+ }
+ else
+ {
+ /* We know the abs value. */
+ fragP->fr_subtype = C (COND_JUMP, COND12);
+ fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
+ }
+
+ break;
+ }
+
+ return fragP->fr_var;
+}
+
+/* Put number into target byte order */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char * ptr;
+ valueT use;
+ int nbytes;
+{
+ switch (nbytes)
+ {
+ case 4: *ptr++ = (use >> 24) & 0xff; /* fall through */
+ case 3: *ptr++ = (use >> 16) & 0xff; /* fall through */
+ case 2: *ptr++ = (use >> 8) & 0xff; /* fall through */
+ case 1: *ptr++ = (use >> 0) & 0xff; break;
+ default: abort ();
+ }
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ return size; /* Byte alignment is fine */
+}
+
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+long
+md_pcrel_from_section (fixp, sec)
+ fixS * fixp;
+ segT sec;
+{
+#ifdef OBJ_ELF
+ /* If the symbol is undefined or defined in another section
+ we leave the add number alone for the linker to fix it later.
+ Only account for the PC pre-bump (which is 2 bytes on the MCore). */
+ if (fixp->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixp->fx_addsy)
+ || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
+
+ {
+ assert (fixp->fx_size == 2); /* must be an insn */
+ return fixp->fx_size;
+ }
+#endif
+
+ /* The case where we are going to resolve things... */
+ return fixp->fx_size + fixp->fx_where + fixp->fx_frag->fr_address;
+}
+
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+#define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection * section;
+ fixS * fixp;
+{
+ arelent * rel;
+ bfd_reloc_code_real_type code;
+ int handled = 0;
+
+ switch (fixp->fx_r_type)
+ {
+ /* These confuse the size/pcrel macro approach. */
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_MCORE_PCREL_IMM4BY2:
+ case BFD_RELOC_MCORE_PCREL_IMM8BY4:
+ case BFD_RELOC_MCORE_PCREL_IMM11BY2:
+ case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2:
+ code = fixp->fx_r_type;
+ break;
+
+ default:
+ switch (F (fixp->fx_size, fixp->fx_pcrel))
+ {
+ MAP (1, 0, BFD_RELOC_8);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (4, 0, BFD_RELOC_32);
+ MAP (1, 1, BFD_RELOC_8_PCREL);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 1, BFD_RELOC_32_PCREL);
+ default:
+ code = fixp->fx_r_type;
+ as_bad (_("Can not do %d byte %srelocation"),
+ fixp->fx_size,
+ fixp->fx_pcrel ? _("pc-relative") : "");
+ }
+ break;
+ }
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = & fixp->fx_addsy->bsym;
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ /* Always pass the addend along! */
+ rel->addend = fixp->fx_addnumber;
+
+ rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+
+ if (rel->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (code));
+
+ /* Set howto to a garbage value so that we can keep going. */
+ rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ assert (rel->howto != NULL);
+ }
+
+ return rel;
+}
+
+#ifdef OBJ_ELF
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+int
+mcore_force_relocation (fix)
+ fixS * fix;
+{
+ if ( fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
+
+/* Return true if the fix can be handled by GAS, false if it must
+ be passed through to the linker. */
+boolean
+mcore_fix_adjustable (fixP)
+ fixS * fixP;
+{
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* We need the symbol name for the VTABLE entries. */
+ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+
+/* Handle the .section pseudo-op. This is like the usual one, but it
+ dumps the literal pool before changing the section. */
+static void
+mcore_s_section (ignore)
+ int ignore;
+{
+ dump_literals (0);
+
+ obj_elf_section (ignore);
+}
+#endif /* OBJ_ELF */
diff --git a/gas/config/tc-mcore.h b/gas/config/tc-mcore.h
new file mode 100644
index 00000000000..9e487c92a3b
--- /dev/null
+++ b/gas/config/tc-mcore.h
@@ -0,0 +1,119 @@
+/* This file is tc-mcore.h
+
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef TC_MCORE
+#define TC_MCORE 1
+
+#ifndef BFD_ASSEMBLER
+ #error MCORE support requires BFD_ASSEMBLER
+#endif
+
+#define TARGET_ARCH bfd_arch_mcore
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+/* Don't write out relocs for pcrel stuff. */
+#define TC_COUNT_RELOC(x) (((x)->fx_addsy || (x)->fx_subsy) && \
+ (x)->fx_r_type < BFD_RELOC_MCORE_PCREL_IMM8BY4)
+
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle (a, b, c)
+
+/* Some pseudo-op semantic extensions. */
+#define PSEUDO_LCOMM_OPTIONAL_ALIGN
+
+#define LISTING_HEADER "M.CORE GAS Version 2.9.4"
+#define LISTING_LHS_CONT_LINES 4
+
+#define NEED_FX_R_TYPE 1
+#define COFF_FLAGS 1
+
+/* We want local label support. */
+#define LOCAL_LABELS_FB 1
+
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep (frag)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+#define md_end md_mcore_end
+
+/* Want the section information too... */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
+
+#define MD_APPLY_FIX3 /* We want the segment as well. */
+
+
+
+#ifdef OBJ_COFF
+
+#define TARGET_FORMAT (target_big_endian ? "pe-mcore-big" : "pe-mcore-little")
+
+#define TARGET_SYMBOL_FIELDS int sy_flags ;
+
+#endif /* OBJ_COFF */
+
+
+#ifdef OBJ_ELF
+
+#define TARGET_FORMAT (target_big_endian ? "elf32-mcore-big" : "elf32-mcore-little")
+
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".ctors", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
+ { ".dtors", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
+/* Other special sections not generated by the assembler: .reginfo,
+ .liblist, .conflict, .gptab, .got, .dynamic, .rel.dyn. */
+
+/* When relaxing, we need to emit various relocs we otherwise wouldn't. */
+#define TC_FORCE_RELOCATION(fix) mcore_force_relocation (fix)
+extern int mcore_force_relocation PARAMS ((struct fix *));
+
+#define obj_fix_adjustable(fixP) mcore_fix_adjustable (fixP)
+extern boolean mcore_fix_adjustable PARAMS ((struct fix *));
+
+#endif /* OBJ_ELF */
+
+#ifndef TARGET_FORMAT
+# error No target format specified.
+#endif
+
+#include "struc-symbol.h" /* For definition of symbolS */
+#include "write.h" /* For definition of fixS */
+
+extern void md_begin PARAMS ((void));
+extern void md_assemble PARAMS ((char *));
+extern symbolS * md_undefined_symbol PARAMS ((char *));
+extern void md_mcore_end PARAMS ((void));
+extern char * md_atof PARAMS ((int, char *, int *));
+extern int md_parse_option PARAMS ((int, char *));
+extern void md_show_usage PARAMS ((FILE *));
+extern void md_create_short_jump
+ PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
+extern void md_create_long_jump
+ PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
+extern void md_convert_frag PARAMS ((bfd *, segT, fragS *));
+extern int md_apply_fix3 PARAMS ((fixS *, valueT *, segT));
+extern void md_operand PARAMS ((expressionS *));
+extern int md_estimate_size_before_relax PARAMS ((fragS *, segT));
+extern void md_number_to_chars PARAMS ((char *, valueT, int));
+extern valueT md_section_align PARAMS ((segT, valueT));
+extern long md_pcrel_from_section PARAMS ((fixS *, segT));
+extern arelent * tc_gen_reloc PARAMS ((asection *, fixS *));
+
+#endif /* TC_MCORE */
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
new file mode 100644
index 00000000000..3d865fd9777
--- /dev/null
+++ b/gas/config/tc-mips.c
@@ -0,0 +1,11783 @@
+/* tc-mips.c -- assemble code for a MIPS chip.
+ Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Contributed by the OSF and Ralph Campbell.
+ Written by Keith Knowles and Ralph Campbell, working independently.
+ Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
+ Support.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "config.h"
+#include "subsegs.h"
+
+#include <ctype.h>
+
+#ifdef USE_STDARG
+#include <stdarg.h>
+#endif
+#ifdef USE_VARARGS
+#include <varargs.h>
+#endif
+
+#include "opcode/mips.h"
+#include "itbl-ops.h"
+
+#ifdef DEBUG
+#define DBG(x) printf x
+#else
+#define DBG(x)
+#endif
+
+#ifdef OBJ_MAYBE_ELF
+/* Clean up namespace so we can include obj-elf.h too. */
+static int mips_output_flavor PARAMS ((void));
+static int mips_output_flavor () { return OUTPUT_FLAVOR; }
+#undef OBJ_PROCESS_STAB
+#undef OUTPUT_FLAVOR
+#undef S_GET_ALIGN
+#undef S_GET_SIZE
+#undef S_SET_ALIGN
+#undef S_SET_SIZE
+#undef TARGET_SYMBOL_FIELDS
+#undef obj_frob_file
+#undef obj_frob_file_after_relocs
+#undef obj_frob_symbol
+#undef obj_pop_insert
+#undef obj_sec_sym_ok_for_reloc
+#undef OBJ_COPY_SYMBOL_ATTRIBUTES
+
+#include "obj-elf.h"
+/* Fix any of them that we actually care about. */
+#undef OUTPUT_FLAVOR
+#define OUTPUT_FLAVOR mips_output_flavor()
+#endif
+
+#if defined (OBJ_ELF)
+#include "elf/mips.h"
+#endif
+
+#ifndef ECOFF_DEBUGGING
+#define NO_ECOFF_DEBUGGING
+#define ECOFF_DEBUGGING 0
+#endif
+
+#include "ecoff.h"
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+static char *mips_regmask_frag;
+#endif
+
+#define AT 1
+#define TREG 24
+#define PIC_CALL_REG 25
+#define KT0 26
+#define KT1 27
+#define GP 28
+#define SP 29
+#define FP 30
+#define RA 31
+
+#define ILLEGAL_REG (32)
+
+/* Allow override of standard little-endian ECOFF format. */
+
+#ifndef ECOFF_LITTLE_FORMAT
+#define ECOFF_LITTLE_FORMAT "ecoff-littlemips"
+#endif
+
+extern int target_big_endian;
+
+/* 1 is we should use the 64 bit MIPS ELF ABI, 0 if we should use the
+ 32 bit ABI. This has no meaning for ECOFF.
+ Note that the default is always 32 bit, even if "configured" for
+ 64 bit [e.g. --target=mips64-elf]. */
+static int mips_64;
+
+/* The default target format to use. */
+const char *
+mips_target_format ()
+{
+ switch (OUTPUT_FLAVOR)
+ {
+ case bfd_target_aout_flavour:
+ return target_big_endian ? "a.out-mips-big" : "a.out-mips-little";
+ case bfd_target_ecoff_flavour:
+ return target_big_endian ? "ecoff-bigmips" : ECOFF_LITTLE_FORMAT;
+ case bfd_target_elf_flavour:
+ return (target_big_endian
+ ? (mips_64 ? "elf64-bigmips" : "elf32-bigmips")
+ : (mips_64 ? "elf64-littlemips" : "elf32-littlemips"));
+ default:
+ abort ();
+ return NULL;
+ }
+}
+
+/* The name of the readonly data section. */
+#define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
+ ? ".data" \
+ : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+ ? ".rdata" \
+ : OUTPUT_FLAVOR == bfd_target_elf_flavour \
+ ? ".rodata" \
+ : (abort (), ""))
+
+/* This is the set of options which may be modified by the .set
+ pseudo-op. We use a struct so that .set push and .set pop are more
+ reliable. */
+
+struct mips_set_options
+{
+ /* MIPS ISA (Instruction Set Architecture) level. This is set to -1
+ if it has not been initialized. Changed by `.set mipsN', and the
+ -mipsN command line option, and the default CPU. */
+ int isa;
+ /* Whether we are assembling for the mips16 processor. 0 if we are
+ not, 1 if we are, and -1 if the value has not been initialized.
+ Changed by `.set mips16' and `.set nomips16', and the -mips16 and
+ -nomips16 command line options, and the default CPU. */
+ int mips16;
+ /* Non-zero if we should not reorder instructions. Changed by `.set
+ reorder' and `.set noreorder'. */
+ int noreorder;
+ /* Non-zero if we should not permit the $at ($1) register to be used
+ in instructions. Changed by `.set at' and `.set noat'. */
+ int noat;
+ /* Non-zero if we should warn when a macro instruction expands into
+ more than one machine instruction. Changed by `.set nomacro' and
+ `.set macro'. */
+ int warn_about_macros;
+ /* Non-zero if we should not move instructions. Changed by `.set
+ move', `.set volatile', `.set nomove', and `.set novolatile'. */
+ int nomove;
+ /* Non-zero if we should not optimize branches by moving the target
+ of the branch into the delay slot. Actually, we don't perform
+ this optimization anyhow. Changed by `.set bopt' and `.set
+ nobopt'. */
+ int nobopt;
+ /* Non-zero if we should not autoextend mips16 instructions.
+ Changed by `.set autoextend' and `.set noautoextend'. */
+ int noautoextend;
+};
+
+/* This is the struct we use to hold the current set of options. Note
+ that we must set the isa and mips16 fields to -1 to indicate that
+ they have not been initialized. */
+
+static struct mips_set_options mips_opts = { -1, -1 };
+
+/* These variables are filled in with the masks of registers used.
+ The object format code reads them and puts them in the appropriate
+ place. */
+unsigned long mips_gprmask;
+unsigned long mips_cprmask[4];
+
+/* MIPS ISA we are using for this output file. */
+static int file_mips_isa;
+
+/* The CPU type as a number: 2000, 3000, 4000, 4400, etc. */
+static int mips_cpu = -1;
+
+/* The argument of the -mabi= flag. */
+static char* mips_abi_string = 0;
+
+/* Wether we should mark the file EABI64 or EABI32. */
+static int mips_eabi64 = 0;
+
+/* If they asked for mips1 or mips2 and a cpu that is
+ mips3 or greater, then mark the object file 32BITMODE. */
+static int mips_32bitmode = 0;
+
+/* Whether the processor uses hardware interlocks to protect
+ reads from the HI and LO registers, and thus does not
+ require nops to be inserted.
+
+ FIXME: GCC makes a distinction between -mcpu=FOO and -mFOO:
+ -mcpu=FOO schedules for FOO, but still produces code that meets the
+ requirements of MIPS ISA I. For example, it won't generate any
+ FOO-specific instructions, and it will still assume that any
+ scheduling hazards described in MIPS ISA I are there, even if FOO
+ has interlocks. -mFOO gives GCC permission to generate code that
+ will only run on a FOO; it will generate FOO-specific instructions,
+ and assume interlocks provided by a FOO.
+
+ However, GAS currently doesn't make this distinction; before Jan 28
+ 1999, GAS's -mcpu=FOO implied -mFOO, which violates GCC's
+ assumptions. The GCC driver passes these flags through to GAS, so
+ if GAS actually does anything that doesn't meet MIPS ISA I with
+ -mFOO, then GCC's -mcpu=FOO flag isn't going to work.
+
+ And furthermore, it did not assume that -mFOO implied -mcpu=FOO,
+ which seems senseless --- why generate code which will only run on
+ a FOO, but schedule for something else?
+
+ So now, at least, -mcpu=FOO and -mFOO are exactly equivalent.
+
+ -- Jim Blandy <jimb@cygnus.com> */
+
+#define hilo_interlocks (mips_cpu == 4010 \
+ )
+
+/* Whether the processor uses hardware interlocks to protect reads
+ from the GPRs, and thus does not require nops to be inserted. */
+#define gpr_interlocks \
+ (mips_opts.isa >= 2 \
+ || mips_cpu == 3900)
+
+/* As with other "interlocks" this is used by hardware that has FP
+ (co-processor) interlocks. */
+/* Itbl support may require additional care here. */
+#define cop_interlocks (mips_cpu == 4300 \
+ )
+
+/* MIPS PIC level. */
+
+enum mips_pic_level
+{
+ /* Do not generate PIC code. */
+ NO_PIC,
+
+ /* Generate PIC code as in Irix 4. This is not implemented, and I'm
+ not sure what it is supposed to do. */
+ IRIX4_PIC,
+
+ /* Generate PIC code as in the SVR4 MIPS ABI. */
+ SVR4_PIC,
+
+ /* Generate PIC code without using a global offset table: the data
+ segment has a maximum size of 64K, all data references are off
+ the $gp register, and all text references are PC relative. This
+ is used on some embedded systems. */
+ EMBEDDED_PIC
+};
+
+static enum mips_pic_level mips_pic;
+
+/* 1 if we should generate 32 bit offsets from the GP register in
+ SVR4_PIC mode. Currently has no meaning in other modes. */
+static int mips_big_got;
+
+/* 1 if trap instructions should used for overflow rather than break
+ instructions. */
+static int mips_trap;
+
+/* Non-zero if any .set noreorder directives were used. */
+
+static int mips_any_noreorder;
+
+/* The size of the small data section. */
+static int g_switch_value = 8;
+/* Whether the -G option was used. */
+static int g_switch_seen = 0;
+
+#define N_RMASK 0xc4
+#define N_VFP 0xd4
+
+/* If we can determine in advance that GP optimization won't be
+ possible, we can skip the relaxation stuff that tries to produce
+ GP-relative references. This makes delay slot optimization work
+ better.
+
+ This function can only provide a guess, but it seems to work for
+ gcc output. If it guesses wrong, the only loss should be in
+ efficiency; it shouldn't introduce any bugs.
+
+ I don't know if a fix is needed for the SVR4_PIC mode. I've only
+ fixed it for the non-PIC mode. KR 95/04/07 */
+static int nopic_need_relax PARAMS ((symbolS *, int));
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash = NULL;
+
+/* The opcode hash table we use for the mips16. */
+static struct hash_control *mips16_op_hash = NULL;
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = "#";
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that C style comments are always supported. */
+const char line_comment_chars[] = "#";
+
+/* This array holds machine specific line separator characters. */
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c . Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here.
+ */
+
+static char *insn_error;
+
+static int auto_align = 1;
+
+/* When outputting SVR4 PIC code, the assembler needs to know the
+ offset in the stack frame from which to restore the $gp register.
+ This is set by the .cprestore pseudo-op, and saved in this
+ variable. */
+static offsetT mips_cprestore_offset = -1;
+
+/* This is the register which holds the stack frame, as set by the
+ .frame pseudo-op. This is needed to implement .cprestore. */
+static int mips_frame_reg = SP;
+
+/* To output NOP instructions correctly, we need to keep information
+ about the previous two instructions. */
+
+/* Whether we are optimizing. The default value of 2 means to remove
+ unneeded NOPs and swap branch instructions when possible. A value
+ of 1 means to not swap branches. A value of 0 means to always
+ insert NOPs. */
+static int mips_optimize = 2;
+
+/* Debugging level. -g sets this to 2. -gN sets this to N. -g0 is
+ equivalent to seeing no -g option at all. */
+static int mips_debug = 0;
+
+/* The previous instruction. */
+static struct mips_cl_insn prev_insn;
+
+/* The instruction before prev_insn. */
+static struct mips_cl_insn prev_prev_insn;
+
+/* If we don't want information for prev_insn or prev_prev_insn, we
+ point the insn_mo field at this dummy integer. */
+static const struct mips_opcode dummy_opcode = { 0 };
+
+/* Non-zero if prev_insn is valid. */
+static int prev_insn_valid;
+
+/* The frag for the previous instruction. */
+static struct frag *prev_insn_frag;
+
+/* The offset into prev_insn_frag for the previous instruction. */
+static long prev_insn_where;
+
+/* The reloc type for the previous instruction, if any. */
+static bfd_reloc_code_real_type prev_insn_reloc_type;
+
+/* The reloc for the previous instruction, if any. */
+static fixS *prev_insn_fixp;
+
+/* Non-zero if the previous instruction was in a delay slot. */
+static int prev_insn_is_delay_slot;
+
+/* Non-zero if the previous instruction was in a .set noreorder. */
+static int prev_insn_unreordered;
+
+/* Non-zero if the previous instruction uses an extend opcode (if
+ mips16). */
+static int prev_insn_extended;
+
+/* Non-zero if the previous previous instruction was in a .set
+ noreorder. */
+static int prev_prev_insn_unreordered;
+
+/* If this is set, it points to a frag holding nop instructions which
+ were inserted before the start of a noreorder section. If those
+ nops turn out to be unnecessary, the size of the frag can be
+ decreased. */
+static fragS *prev_nop_frag;
+
+/* The number of nop instructions we created in prev_nop_frag. */
+static int prev_nop_frag_holds;
+
+/* The number of nop instructions that we know we need in
+ prev_nop_frag. */
+static int prev_nop_frag_required;
+
+/* The number of instructions we've seen since prev_nop_frag. */
+static int prev_nop_frag_since;
+
+/* For ECOFF and ELF, relocations against symbols are done in two
+ parts, with a HI relocation and a LO relocation. Each relocation
+ has only 16 bits of space to store an addend. This means that in
+ order for the linker to handle carries correctly, it must be able
+ to locate both the HI and the LO relocation. This means that the
+ relocations must appear in order in the relocation table.
+
+ In order to implement this, we keep track of each unmatched HI
+ relocation. We then sort them so that they immediately precede the
+ corresponding LO relocation. */
+
+struct mips_hi_fixup
+{
+ /* Next HI fixup. */
+ struct mips_hi_fixup *next;
+ /* This fixup. */
+ fixS *fixp;
+ /* The section this fixup is in. */
+ segT seg;
+};
+
+/* The list of unmatched HI relocs. */
+
+static struct mips_hi_fixup *mips_hi_fixup_list;
+
+/* Map normal MIPS register numbers to mips16 register numbers. */
+
+#define X ILLEGAL_REG
+static const int mips32_to_16_reg_map[] =
+{
+ X, X, 2, 3, 4, 5, 6, 7,
+ X, X, X, X, X, X, X, X,
+ 0, 1, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X
+};
+#undef X
+
+/* Map mips16 register numbers to normal MIPS register numbers. */
+
+static const int mips16_to_32_reg_map[] =
+{
+ 16, 17, 2, 3, 4, 5, 6, 7
+};
+
+/* Since the MIPS does not have multiple forms of PC relative
+ instructions, we do not have to do relaxing as is done on other
+ platforms. However, we do have to handle GP relative addressing
+ correctly, which turns out to be a similar problem.
+
+ Every macro that refers to a symbol can occur in (at least) two
+ forms, one with GP relative addressing and one without. For
+ example, loading a global variable into a register generally uses
+ a macro instruction like this:
+ lw $4,i
+ If i can be addressed off the GP register (this is true if it is in
+ the .sbss or .sdata section, or if it is known to be smaller than
+ the -G argument) this will generate the following instruction:
+ lw $4,i($gp)
+ This instruction will use a GPREL reloc. If i can not be addressed
+ off the GP register, the following instruction sequence will be used:
+ lui $at,i
+ lw $4,i($at)
+ In this case the first instruction will have a HI16 reloc, and the
+ second reloc will have a LO16 reloc. Both relocs will be against
+ the symbol i.
+
+ The issue here is that we may not know whether i is GP addressable
+ until after we see the instruction that uses it. Therefore, we
+ want to be able to choose the final instruction sequence only at
+ the end of the assembly. This is similar to the way other
+ platforms choose the size of a PC relative instruction only at the
+ end of assembly.
+
+ When generating position independent code we do not use GP
+ addressing in quite the same way, but the issue still arises as
+ external symbols and local symbols must be handled differently.
+
+ We handle these issues by actually generating both possible
+ instruction sequences. The longer one is put in a frag_var with
+ type rs_machine_dependent. We encode what to do with the frag in
+ the subtype field. We encode (1) the number of existing bytes to
+ replace, (2) the number of new bytes to use, (3) the offset from
+ the start of the existing bytes to the first reloc we must generate
+ (that is, the offset is applied from the start of the existing
+ bytes after they are replaced by the new bytes, if any), (4) the
+ offset from the start of the existing bytes to the second reloc,
+ (5) whether a third reloc is needed (the third reloc is always four
+ bytes after the second reloc), and (6) whether to warn if this
+ variant is used (this is sometimes needed if .set nomacro or .set
+ noat is in effect). All these numbers are reasonably small.
+
+ Generating two instruction sequences must be handled carefully to
+ ensure that delay slots are handled correctly. Fortunately, there
+ are a limited number of cases. When the second instruction
+ sequence is generated, append_insn is directed to maintain the
+ existing delay slot information, so it continues to apply to any
+ code after the second instruction sequence. This means that the
+ second instruction sequence must not impose any requirements not
+ required by the first instruction sequence.
+
+ These variant frags are then handled in functions called by the
+ machine independent code. md_estimate_size_before_relax returns
+ the final size of the frag. md_convert_frag sets up the final form
+ of the frag. tc_gen_reloc adjust the first reloc and adds a second
+ one if needed. */
+#define RELAX_ENCODE(old, new, reloc1, reloc2, reloc3, warn) \
+ ((relax_substateT) \
+ (((old) << 23) \
+ | ((new) << 16) \
+ | (((reloc1) + 64) << 9) \
+ | (((reloc2) + 64) << 2) \
+ | ((reloc3) ? (1 << 1) : 0) \
+ | ((warn) ? 1 : 0)))
+#define RELAX_OLD(i) (((i) >> 23) & 0x7f)
+#define RELAX_NEW(i) (((i) >> 16) & 0x7f)
+#define RELAX_RELOC1(i) ((bfd_vma)(((i) >> 9) & 0x7f) - 64)
+#define RELAX_RELOC2(i) ((bfd_vma)(((i) >> 2) & 0x7f) - 64)
+#define RELAX_RELOC3(i) (((i) >> 1) & 1)
+#define RELAX_WARN(i) ((i) & 1)
+
+/* For mips16 code, we use an entirely different form of relaxation.
+ mips16 supports two versions of most instructions which take
+ immediate values: a small one which takes some small value, and a
+ larger one which takes a 16 bit value. Since branches also follow
+ this pattern, relaxing these values is required.
+
+ We can assemble both mips16 and normal MIPS code in a single
+ object. Therefore, we need to support this type of relaxation at
+ the same time that we support the relaxation described above. We
+ use the high bit of the subtype field to distinguish these cases.
+
+ The information we store for this type of relaxation is the
+ argument code found in the opcode file for this relocation, whether
+ the user explicitly requested a small or extended form, and whether
+ the relocation is in a jump or jal delay slot. That tells us the
+ size of the value, and how it should be stored. We also store
+ whether the fragment is considered to be extended or not. We also
+ store whether this is known to be a branch to a different section,
+ whether we have tried to relax this frag yet, and whether we have
+ ever extended a PC relative fragment because of a shift count. */
+#define RELAX_MIPS16_ENCODE(type, small, ext, dslot, jal_dslot) \
+ (0x80000000 \
+ | ((type) & 0xff) \
+ | ((small) ? 0x100 : 0) \
+ | ((ext) ? 0x200 : 0) \
+ | ((dslot) ? 0x400 : 0) \
+ | ((jal_dslot) ? 0x800 : 0))
+#define RELAX_MIPS16_P(i) (((i) & 0x80000000) != 0)
+#define RELAX_MIPS16_TYPE(i) ((i) & 0xff)
+#define RELAX_MIPS16_USER_SMALL(i) (((i) & 0x100) != 0)
+#define RELAX_MIPS16_USER_EXT(i) (((i) & 0x200) != 0)
+#define RELAX_MIPS16_DSLOT(i) (((i) & 0x400) != 0)
+#define RELAX_MIPS16_JAL_DSLOT(i) (((i) & 0x800) != 0)
+#define RELAX_MIPS16_EXTENDED(i) (((i) & 0x1000) != 0)
+#define RELAX_MIPS16_MARK_EXTENDED(i) ((i) | 0x1000)
+#define RELAX_MIPS16_CLEAR_EXTENDED(i) ((i) &~ 0x1000)
+#define RELAX_MIPS16_LONG_BRANCH(i) (((i) & 0x2000) != 0)
+#define RELAX_MIPS16_MARK_LONG_BRANCH(i) ((i) | 0x2000)
+#define RELAX_MIPS16_CLEAR_LONG_BRANCH(i) ((i) &~ 0x2000)
+
+/* Prototypes for static functions. */
+
+#ifdef __STDC__
+#define internalError() \
+ as_fatal (_("internal Error, line %d, %s"), __LINE__, __FILE__)
+#else
+#define internalError() as_fatal (_("MIPS internal Error"));
+#endif
+
+enum mips_regclass { MIPS_GR_REG, MIPS_FP_REG, MIPS16_REG };
+
+static int insn_uses_reg PARAMS ((struct mips_cl_insn *ip,
+ unsigned int reg, enum mips_regclass class));
+static int reg_needs_delay PARAMS ((int));
+static void mips16_mark_labels PARAMS ((void));
+static void append_insn PARAMS ((char *place,
+ struct mips_cl_insn * ip,
+ expressionS * p,
+ bfd_reloc_code_real_type r,
+ boolean));
+static void mips_no_prev_insn PARAMS ((int));
+static void mips_emit_delays PARAMS ((boolean));
+#ifdef USE_STDARG
+static void macro_build PARAMS ((char *place, int *counter, expressionS * ep,
+ const char *name, const char *fmt,
+ ...));
+#else
+static void macro_build ();
+#endif
+static void mips16_macro_build PARAMS ((char *, int *, expressionS *,
+ const char *, const char *,
+ va_list));
+static void macro_build_lui PARAMS ((char *place, int *counter,
+ expressionS * ep, int regnum));
+static void set_at PARAMS ((int *counter, int reg, int unsignedp));
+static void check_absolute_expr PARAMS ((struct mips_cl_insn * ip,
+ expressionS *));
+static void load_register PARAMS ((int *, int, expressionS *, int));
+static void load_address PARAMS ((int *counter, int reg, expressionS *ep));
+static void macro PARAMS ((struct mips_cl_insn * ip));
+static void mips16_macro PARAMS ((struct mips_cl_insn * ip));
+#ifdef LOSING_COMPILER
+static void macro2 PARAMS ((struct mips_cl_insn * ip));
+#endif
+static void mips_ip PARAMS ((char *str, struct mips_cl_insn * ip));
+static void mips16_ip PARAMS ((char *str, struct mips_cl_insn * ip));
+static void mips16_immed PARAMS ((char *, unsigned int, int, offsetT, boolean,
+ boolean, boolean, unsigned long *,
+ boolean *, unsigned short *));
+static int my_getSmallExpression PARAMS ((expressionS * ep, char *str));
+static void my_getExpression PARAMS ((expressionS * ep, char *str));
+static symbolS *get_symbol PARAMS ((void));
+static void mips_align PARAMS ((int to, int fill, symbolS *label));
+static void s_align PARAMS ((int));
+static void s_change_sec PARAMS ((int));
+static void s_cons PARAMS ((int));
+static void s_float_cons PARAMS ((int));
+static void s_mips_globl PARAMS ((int));
+static void s_option PARAMS ((int));
+static void s_mipsset PARAMS ((int));
+static void s_abicalls PARAMS ((int));
+static void s_cpload PARAMS ((int));
+static void s_cprestore PARAMS ((int));
+static void s_gpword PARAMS ((int));
+static void s_cpadd PARAMS ((int));
+static void s_insn PARAMS ((int));
+static void md_obj_begin PARAMS ((void));
+static void md_obj_end PARAMS ((void));
+static long get_number PARAMS ((void));
+static void s_mips_ent PARAMS ((int));
+static void s_mips_end PARAMS ((int));
+static void s_mips_frame PARAMS ((int));
+static void s_mips_mask PARAMS ((int));
+static void s_mips_stab PARAMS ((int));
+static void s_mips_weakext PARAMS ((int));
+static void s_file PARAMS ((int));
+static int mips16_extended_frag PARAMS ((fragS *, asection *, long));
+
+
+static int validate_mips_insn PARAMS ((const struct mips_opcode *));
+
+/* Pseudo-op table.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book
+ should be defined here, but are currently unsupported: .alias,
+ .galive, .gjaldef, .gjrlive, .livereg, .noalias.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ specific to the type of debugging information being generated, and
+ should be defined by the object format: .aent, .begin, .bend,
+ .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,
+ .vreg.
+
+ The following pseudo-ops from the Kane and Heinrich MIPS book are
+ not MIPS CPU specific, but are also not specific to the object file
+ format. This file is probably the best place to define them, but
+ they are not currently supported: .asm0, .endr, .lab, .repeat,
+ .struct. */
+
+static const pseudo_typeS mips_pseudo_table[] =
+{
+ /* MIPS specific pseudo-ops. */
+ {"option", s_option, 0},
+ {"set", s_mipsset, 0},
+ {"rdata", s_change_sec, 'r'},
+ {"sdata", s_change_sec, 's'},
+ {"livereg", s_ignore, 0},
+ {"abicalls", s_abicalls, 0},
+ {"cpload", s_cpload, 0},
+ {"cprestore", s_cprestore, 0},
+ {"gpword", s_gpword, 0},
+ {"cpadd", s_cpadd, 0},
+ {"insn", s_insn, 0},
+
+ /* Relatively generic pseudo-ops that happen to be used on MIPS
+ chips. */
+ {"asciiz", stringer, 1},
+ {"bss", s_change_sec, 'b'},
+ {"err", s_err, 0},
+ {"half", s_cons, 1},
+ {"dword", s_cons, 3},
+ {"weakext", s_mips_weakext, 0},
+
+ /* These pseudo-ops are defined in read.c, but must be overridden
+ here for one reason or another. */
+ {"align", s_align, 0},
+ {"byte", s_cons, 0},
+ {"data", s_change_sec, 'd'},
+ {"double", s_float_cons, 'd'},
+ {"float", s_float_cons, 'f'},
+ {"globl", s_mips_globl, 0},
+ {"global", s_mips_globl, 0},
+ {"hword", s_cons, 1},
+ {"int", s_cons, 2},
+ {"long", s_cons, 2},
+ {"octa", s_cons, 4},
+ {"quad", s_cons, 3},
+ {"short", s_cons, 1},
+ {"single", s_float_cons, 'f'},
+ {"stabn", s_mips_stab, 'n'},
+ {"text", s_change_sec, 't'},
+ {"word", s_cons, 2},
+ { 0 },
+};
+
+static const pseudo_typeS mips_nonecoff_pseudo_table[] = {
+ /* These pseudo-ops should be defined by the object file format.
+ However, a.out doesn't support them, so we have versions here. */
+ {"aent", s_mips_ent, 1},
+ {"bgnb", s_ignore, 0},
+ {"end", s_mips_end, 0},
+ {"endb", s_ignore, 0},
+ {"ent", s_mips_ent, 0},
+ {"file", s_file, 0},
+ {"fmask", s_mips_mask, 'F'},
+ {"frame", s_mips_frame, 0},
+ {"loc", s_ignore, 0},
+ {"mask", s_mips_mask, 'R'},
+ {"verstamp", s_ignore, 0},
+ { 0 },
+};
+
+extern void pop_insert PARAMS ((const pseudo_typeS *));
+
+void
+mips_pop_insert ()
+{
+ pop_insert (mips_pseudo_table);
+ if (! ECOFF_DEBUGGING)
+ pop_insert (mips_nonecoff_pseudo_table);
+}
+
+/* Symbols labelling the current insn. */
+
+struct insn_label_list
+{
+ struct insn_label_list *next;
+ symbolS *label;
+};
+
+static struct insn_label_list *insn_labels;
+static struct insn_label_list *free_insn_labels;
+
+static void mips_clear_insn_labels PARAMS ((void));
+
+static inline void
+mips_clear_insn_labels ()
+{
+ register struct insn_label_list **pl;
+
+ for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)
+ ;
+ *pl = insn_labels;
+ insn_labels = NULL;
+}
+
+static char *expr_end;
+
+/* Expressions which appear in instructions. These are set by
+ mips_ip. */
+
+static expressionS imm_expr;
+static expressionS offset_expr;
+
+/* Relocs associated with imm_expr and offset_expr. */
+
+static bfd_reloc_code_real_type imm_reloc;
+static bfd_reloc_code_real_type offset_reloc;
+
+/* This is set by mips_ip if imm_reloc is an unmatched HI16_S reloc. */
+
+static boolean imm_unmatched_hi;
+
+/* These are set by mips16_ip if an explicit extension is used. */
+
+static boolean mips16_small, mips16_ext;
+
+#ifdef MIPS_STABS_ELF
+/* The pdr segment for per procedure frame/regmask info */
+
+static segT pdr_seg;
+#endif
+
+/*
+ * This function is called once, at assembler startup time. It should
+ * set up all the tables, etc. that the MD part of the assembler will need.
+ */
+void
+md_begin ()
+{
+ boolean ok = false;
+ register const char *retval = NULL;
+ register unsigned int i = 0;
+ const char *cpu;
+ char *a = NULL;
+ int broken = 0;
+ int mips_isa_from_cpu;
+
+ cpu = TARGET_CPU;
+ if (strcmp (cpu + (sizeof TARGET_CPU) - 3, "el") == 0)
+ {
+ a = xmalloc (sizeof TARGET_CPU);
+ strcpy (a, TARGET_CPU);
+ a[(sizeof TARGET_CPU) - 3] = '\0';
+ cpu = a;
+ }
+
+ if (mips_cpu < 0)
+ {
+ /* Set mips_cpu based on TARGET_CPU, unless TARGET_CPU is
+ just the generic 'mips', in which case set mips_cpu based
+ on the given ISA, if any. */
+
+ if (strcmp (cpu, "mips") == 0)
+ {
+ if (mips_opts.isa < 0)
+ mips_cpu = 3000;
+
+ else if (mips_opts.isa == 2)
+ mips_cpu = 6000;
+
+ else if (mips_opts.isa == 3)
+ mips_cpu = 4000;
+
+ else if (mips_opts.isa == 4)
+ mips_cpu = 8000;
+
+ else
+ mips_cpu = 3000;
+ }
+
+ else if (strcmp (cpu, "r3900") == 0
+ || strcmp (cpu, "mipstx39") == 0
+ )
+ mips_cpu = 3900;
+
+ else if (strcmp (cpu, "r6000") == 0
+ || strcmp (cpu, "mips2") == 0)
+ mips_cpu = 6000;
+
+ else if (strcmp (cpu, "mips64") == 0
+ || strcmp (cpu, "r4000") == 0
+ || strcmp (cpu, "mips3") == 0)
+ mips_cpu = 4000;
+
+ else if (strcmp (cpu, "r4400") == 0)
+ mips_cpu = 4400;
+
+ else if (strcmp (cpu, "mips64orion") == 0
+ || strcmp (cpu, "r4600") == 0)
+ mips_cpu = 4600;
+
+ else if (strcmp (cpu, "r4650") == 0)
+ mips_cpu = 4650;
+
+ else if (strcmp (cpu, "mips64vr4300") == 0)
+ mips_cpu = 4300;
+
+ else if (strcmp (cpu, "mips64vr4111") == 0)
+ mips_cpu = 4111;
+
+ else if (strcmp (cpu, "mips64vr4100") == 0)
+ mips_cpu = 4100;
+
+ else if (strcmp (cpu, "r4010") == 0)
+ mips_cpu = 4010;
+
+
+ else if (strcmp (cpu, "r5000") == 0
+ || strcmp (cpu, "mips64vr5000") == 0)
+ mips_cpu = 5000;
+
+
+
+ else if (strcmp (cpu, "r8000") == 0
+ || strcmp (cpu, "mips4") == 0)
+ mips_cpu = 8000;
+
+ else if (strcmp (cpu, "r10000") == 0)
+ mips_cpu = 10000;
+
+ else if (strcmp (cpu, "mips16") == 0)
+ mips_cpu = 0; /* FIXME */
+
+ else
+ mips_cpu = 3000;
+ }
+
+ if (mips_cpu == 3000
+ || mips_cpu == 3900)
+ mips_isa_from_cpu = 1;
+
+ else if (mips_cpu == 6000
+ || mips_cpu == 4010)
+ mips_isa_from_cpu = 2;
+
+ else if (mips_cpu == 4000
+ || mips_cpu == 4100
+ || mips_cpu == 4111
+ || mips_cpu == 4400
+ || mips_cpu == 4300
+ || mips_cpu == 4600
+ || mips_cpu == 4650)
+ mips_isa_from_cpu = 3;
+
+ else if (mips_cpu == 5000
+ || mips_cpu == 8000
+ || mips_cpu == 10000)
+ mips_isa_from_cpu = 4;
+
+ else
+ mips_isa_from_cpu = -1;
+
+ if (mips_opts.isa == -1)
+ {
+ if (mips_isa_from_cpu != -1)
+ mips_opts.isa = mips_isa_from_cpu;
+ else
+ mips_opts.isa = 1;
+ }
+
+ if (mips_opts.mips16 < 0)
+ {
+ if (strncmp (TARGET_CPU, "mips16", sizeof "mips16" - 1) == 0)
+ mips_opts.mips16 = 1;
+ else
+ mips_opts.mips16 = 0;
+ }
+
+ /* End of TARGET_CPU processing, get rid of malloced memory
+ if necessary. */
+ cpu = NULL;
+ if (a != NULL)
+ {
+ free (a);
+ a = NULL;
+ }
+
+ if (mips_opts.isa < 2 && mips_trap)
+ as_bad (_("trap exception not supported at ISA 1"));
+
+ /* Set the EABI kind based on the ISA before the user gets
+ to change the ISA with directives. This isn't really
+ the best, but then neither is basing the abi on the isa. */
+ if (mips_opts.isa > 2
+ && mips_abi_string
+ && 0 == strcmp (mips_abi_string,"eabi"))
+ mips_eabi64 = 1;
+
+ if (mips_cpu != 0 && mips_cpu != -1)
+ {
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_cpu);
+
+ /* If they asked for mips1 or mips2 and a cpu that is
+ mips3 or greater, then mark the object file 32BITMODE. */
+ if (mips_isa_from_cpu != -1
+ && mips_opts.isa <= 2 && mips_isa_from_cpu > 2)
+ mips_32bitmode = 1;
+ }
+ else
+ {
+ switch (mips_opts.isa)
+ {
+ case 1:
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 3000);
+ break;
+ case 2:
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 6000);
+ break;
+ case 3:
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 4000);
+ break;
+ case 4:
+ ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 8000);
+ break;
+ }
+ }
+
+ if (! ok)
+ as_warn (_("Could not set architecture and machine"));
+
+ file_mips_isa = mips_opts.isa;
+
+ op_hash = hash_new ();
+
+ for (i = 0; i < NUMOPCODES;)
+ {
+ const char *name = mips_opcodes[i].name;
+
+ retval = hash_insert (op_hash, name, (PTR) &mips_opcodes[i]);
+ if (retval != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ mips_opcodes[i].name, retval);
+ /* Probably a memory allocation problem? Give up now. */
+ as_fatal (_("Broken assembler. No assembly attempted."));
+ }
+ do
+ {
+ if (mips_opcodes[i].pinfo != INSN_MACRO)
+ {
+ if (!validate_mips_insn (&mips_opcodes[i]))
+ broken = 1;
+ }
+ ++i;
+ }
+ while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
+ }
+
+ mips16_op_hash = hash_new ();
+
+ i = 0;
+ while (i < bfd_mips16_num_opcodes)
+ {
+ const char *name = mips16_opcodes[i].name;
+
+ retval = hash_insert (mips16_op_hash, name, (PTR) &mips16_opcodes[i]);
+ if (retval != NULL)
+ as_fatal (_("internal: can't hash `%s': %s"),
+ mips16_opcodes[i].name, retval);
+ do
+ {
+ if (mips16_opcodes[i].pinfo != INSN_MACRO
+ && ((mips16_opcodes[i].match & mips16_opcodes[i].mask)
+ != mips16_opcodes[i].match))
+ {
+ fprintf (stderr, _("internal error: bad mips16 opcode: %s %s\n"),
+ mips16_opcodes[i].name, mips16_opcodes[i].args);
+ broken = 1;
+ }
+ ++i;
+ }
+ while (i < bfd_mips16_num_opcodes
+ && strcmp (mips16_opcodes[i].name, name) == 0);
+ }
+
+ if (broken)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ /* We add all the general register names to the symbol table. This
+ helps us detect invalid uses of them. */
+ for (i = 0; i < 32; i++)
+ {
+ char buf[5];
+
+ sprintf (buf, "$%d", i);
+ symbol_table_insert (symbol_new (buf, reg_section, i,
+ &zero_address_frag));
+ }
+ symbol_table_insert (symbol_new ("$fp", reg_section, FP,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$sp", reg_section, SP,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$gp", reg_section, GP,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$at", reg_section, AT,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$kt0", reg_section, KT0,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$kt1", reg_section, KT1,
+ &zero_address_frag));
+ symbol_table_insert (symbol_new ("$pc", reg_section, -1,
+ &zero_address_frag));
+
+ mips_no_prev_insn (false);
+
+ mips_gprmask = 0;
+ mips_cprmask[0] = 0;
+ mips_cprmask[1] = 0;
+ mips_cprmask[2] = 0;
+ mips_cprmask[3] = 0;
+
+ /* set the default alignment for the text section (2**2) */
+ record_alignment (text_section, 2);
+
+ if (USE_GLOBAL_POINTER_OPT)
+ bfd_set_gp_size (stdoutput, g_switch_value);
+
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ /* On a native system, sections must be aligned to 16 byte
+ boundaries. When configured for an embedded ELF target, we
+ don't bother. */
+ if (strcmp (TARGET_OS, "elf") != 0)
+ {
+ (void) bfd_set_section_alignment (stdoutput, text_section, 4);
+ (void) bfd_set_section_alignment (stdoutput, data_section, 4);
+ (void) bfd_set_section_alignment (stdoutput, bss_section, 4);
+ }
+
+ /* Create a .reginfo section for register masks and a .mdebug
+ section for debugging information. */
+ {
+ segT seg;
+ subsegT subseg;
+ flagword flags;
+ segT sec;
+
+ seg = now_seg;
+ subseg = now_subseg;
+
+ /* The ABI says this section should be loaded so that the
+ running program can access it. However, we don't load it
+ if we are configured for an embedded target */
+ flags = SEC_READONLY | SEC_DATA;
+ if (strcmp (TARGET_OS, "elf") != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+
+ if (! mips_64)
+ {
+ sec = subseg_new (".reginfo", (subsegT) 0);
+
+
+ (void) bfd_set_section_flags (stdoutput, sec, flags);
+ (void) bfd_set_section_alignment (stdoutput, sec, 2);
+
+#ifdef OBJ_ELF
+ mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
+#endif
+ }
+ else
+ {
+ /* The 64-bit ABI uses a .MIPS.options section rather than
+ .reginfo section. */
+ sec = subseg_new (".MIPS.options", (subsegT) 0);
+ (void) bfd_set_section_flags (stdoutput, sec, flags);
+ (void) bfd_set_section_alignment (stdoutput, sec, 3);
+
+#ifdef OBJ_ELF
+ /* Set up the option header. */
+ {
+ Elf_Internal_Options opthdr;
+ char *f;
+
+ opthdr.kind = ODK_REGINFO;
+ opthdr.size = (sizeof (Elf_External_Options)
+ + sizeof (Elf64_External_RegInfo));
+ opthdr.section = 0;
+ opthdr.info = 0;
+ f = frag_more (sizeof (Elf_External_Options));
+ bfd_mips_elf_swap_options_out (stdoutput, &opthdr,
+ (Elf_External_Options *) f);
+
+ mips_regmask_frag = frag_more (sizeof (Elf64_External_RegInfo));
+ }
+#endif
+ }
+
+ if (ECOFF_DEBUGGING)
+ {
+ sec = subseg_new (".mdebug", (subsegT) 0);
+ (void) bfd_set_section_flags (stdoutput, sec,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+ (void) bfd_set_section_alignment (stdoutput, sec, 2);
+ }
+
+#ifdef MIPS_STABS_ELF
+ pdr_seg = subseg_new (".pdr", (subsegT) 0);
+ (void) bfd_set_section_flags (stdoutput, pdr_seg,
+ SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+ (void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);
+#endif
+
+ subseg_set (seg, subseg);
+ }
+ }
+
+ if (! ECOFF_DEBUGGING)
+ md_obj_begin ();
+}
+
+void
+md_mips_end ()
+{
+ if (! ECOFF_DEBUGGING)
+ md_obj_end ();
+}
+
+void
+md_assemble (str)
+ char *str;
+{
+ struct mips_cl_insn insn;
+
+ imm_expr.X_op = O_absent;
+ imm_reloc = BFD_RELOC_UNUSED;
+ imm_unmatched_hi = false;
+ offset_expr.X_op = O_absent;
+ offset_reloc = BFD_RELOC_UNUSED;
+
+ if (mips_opts.mips16)
+ mips16_ip (str, &insn);
+ else
+ {
+ mips_ip (str, &insn);
+ DBG((_("returned from mips_ip(%s) insn_opcode = 0x%x\n"),
+ str, insn.insn_opcode));
+ }
+
+ if (insn_error)
+ {
+ as_bad ("%s `%s'", insn_error, str);
+ return;
+ }
+
+ if (insn.insn_mo->pinfo == INSN_MACRO)
+ {
+ if (mips_opts.mips16)
+ mips16_macro (&insn);
+ else
+ macro (&insn);
+ }
+ else
+ {
+ if (imm_expr.X_op != O_absent)
+ append_insn ((char *) NULL, &insn, &imm_expr, imm_reloc,
+ imm_unmatched_hi);
+ else if (offset_expr.X_op != O_absent)
+ append_insn ((char *) NULL, &insn, &offset_expr, offset_reloc, false);
+ else
+ append_insn ((char *) NULL, &insn, NULL, BFD_RELOC_UNUSED, false);
+ }
+}
+
+/* See whether instruction IP reads register REG. CLASS is the type
+ of register. */
+
+static int
+insn_uses_reg (ip, reg, class)
+ struct mips_cl_insn *ip;
+ unsigned int reg;
+ enum mips_regclass class;
+{
+ if (class == MIPS16_REG)
+ {
+ assert (mips_opts.mips16);
+ reg = mips16_to_32_reg_map[reg];
+ class = MIPS_GR_REG;
+ }
+
+ /* Don't report on general register 0, since it never changes. */
+ if (class == MIPS_GR_REG && reg == 0)
+ return 0;
+
+ if (class == MIPS_FP_REG)
+ {
+ assert (! mips_opts.mips16);
+ /* If we are called with either $f0 or $f1, we must check $f0.
+ This is not optimal, because it will introduce an unnecessary
+ NOP between "lwc1 $f0" and "swc1 $f1". To fix this we would
+ need to distinguish reading both $f0 and $f1 or just one of
+ them. Note that we don't have to check the other way,
+ because there is no instruction that sets both $f0 and $f1
+ and requires a delay. */
+ if ((ip->insn_mo->pinfo & INSN_READ_FPR_S)
+ && ((((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS) &~(unsigned)1)
+ == (reg &~ (unsigned) 1)))
+ return 1;
+ if ((ip->insn_mo->pinfo & INSN_READ_FPR_T)
+ && ((((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT) &~(unsigned)1)
+ == (reg &~ (unsigned) 1)))
+ return 1;
+ }
+ else if (! mips_opts.mips16)
+ {
+ if ((ip->insn_mo->pinfo & INSN_READ_GPR_S)
+ && ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS) == reg)
+ return 1;
+ if ((ip->insn_mo->pinfo & INSN_READ_GPR_T)
+ && ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT) == reg)
+ return 1;
+ }
+ else
+ {
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_X)
+ && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX)]
+ == reg))
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Y)
+ && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY)]
+ == reg))
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Z)
+ && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_MOVE32Z)
+ & MIPS16OP_MASK_MOVE32Z)]
+ == reg))
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_T) && reg == TREG)
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_SP) && reg == SP)
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_31) && reg == RA)
+ return 1;
+ if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_GPR_X)
+ && ((ip->insn_opcode >> MIPS16OP_SH_REGR32)
+ & MIPS16OP_MASK_REGR32) == reg)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* This function returns true if modifying a register requires a
+ delay. */
+
+static int
+reg_needs_delay (reg)
+ int reg;
+{
+ unsigned long prev_pinfo;
+
+ prev_pinfo = prev_insn.insn_mo->pinfo;
+ if (! mips_opts.noreorder
+ && mips_opts.isa < 4
+ && ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
+ || (! gpr_interlocks
+ && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
+ {
+ /* A load from a coprocessor or from memory. All load
+ delays delay the use of general register rt for one
+ instruction on the r3000. The r6000 and r4000 use
+ interlocks. */
+ /* Itbl support may require additional care here. */
+ know (prev_pinfo & INSN_WRITE_GPR_T);
+ if (reg == ((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Mark instruction labels in mips16 mode. This permits the linker to
+ handle them specially, such as generating jalx instructions when
+ needed. We also make them odd for the duration of the assembly, in
+ order to generate the right sort of code. We will make them even
+ in the adjust_symtab routine, while leaving them marked. This is
+ convenient for the debugger and the disassembler. The linker knows
+ to make them odd again. */
+
+static void
+mips16_mark_labels ()
+{
+ if (mips_opts.mips16)
+ {
+ struct insn_label_list *l;
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+#ifdef OBJ_ELF
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ S_SET_OTHER (l->label, STO_MIPS16);
+#endif
+ if ((l->label->sy_value.X_add_number & 1) == 0)
+ ++l->label->sy_value.X_add_number;
+ }
+ }
+}
+
+/* Output an instruction. PLACE is where to put the instruction; if
+ it is NULL, this uses frag_more to get room. IP is the instruction
+ information. ADDRESS_EXPR is an operand of the instruction to be
+ used with RELOC_TYPE. */
+
+static void
+append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
+ char *place;
+ struct mips_cl_insn *ip;
+ expressionS *address_expr;
+ bfd_reloc_code_real_type reloc_type;
+ boolean unmatched_hi;
+{
+ register unsigned long prev_pinfo, pinfo;
+ char *f;
+ fixS *fixp;
+ int nops = 0;
+
+ /* Mark instruction labels in mips16 mode. */
+ if (mips_opts.mips16)
+ mips16_mark_labels ();
+
+ prev_pinfo = prev_insn.insn_mo->pinfo;
+ pinfo = ip->insn_mo->pinfo;
+
+ if (place == NULL && (! mips_opts.noreorder || prev_nop_frag != NULL))
+ {
+ int prev_prev_nop;
+
+ /* If the previous insn required any delay slots, see if we need
+ to insert a NOP or two. There are eight kinds of possible
+ hazards, of which an instruction can have at most one type.
+ (1) a load from memory delay
+ (2) a load from a coprocessor delay
+ (3) an unconditional branch delay
+ (4) a conditional branch delay
+ (5) a move to coprocessor register delay
+ (6) a load coprocessor register from memory delay
+ (7) a coprocessor condition code delay
+ (8) a HI/LO special register delay
+
+ There are a lot of optimizations we could do that we don't.
+ In particular, we do not, in general, reorder instructions.
+ If you use gcc with optimization, it will reorder
+ instructions and generally do much more optimization then we
+ do here; repeating all that work in the assembler would only
+ benefit hand written assembly code, and does not seem worth
+ it. */
+
+ /* This is how a NOP is emitted. */
+#define emit_nop() \
+ (mips_opts.mips16 \
+ ? md_number_to_chars (frag_more (2), 0x6500, 2) \
+ : md_number_to_chars (frag_more (4), 0, 4))
+
+ /* The previous insn might require a delay slot, depending upon
+ the contents of the current insn. */
+ if (! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (((prev_pinfo & INSN_LOAD_COPROC_DELAY)
+ && ! cop_interlocks)
+ || (! gpr_interlocks
+ && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
+ {
+ /* A load from a coprocessor or from memory. All load
+ delays delay the use of general register rt for one
+ instruction on the r3000. The r6000 and r4000 use
+ interlocks. */
+ /* Itbl support may require additional care here. */
+ know (prev_pinfo & INSN_WRITE_GPR_T);
+ if (mips_optimize == 0
+ || insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT),
+ MIPS_GR_REG))
+ ++nops;
+ }
+ else if (! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (((prev_pinfo & INSN_COPROC_MOVE_DELAY)
+ && ! cop_interlocks)
+ || (mips_opts.isa < 2
+ && (prev_pinfo & INSN_COPROC_MEMORY_DELAY))))
+ {
+ /* A generic coprocessor delay. The previous instruction
+ modified a coprocessor general or control register. If
+ it modified a control register, we need to avoid any
+ coprocessor instruction (this is probably not always
+ required, but it sometimes is). If it modified a general
+ register, we avoid using that register.
+
+ On the r6000 and r4000 loading a coprocessor register
+ from memory is interlocked, and does not require a delay.
+
+ This case is not handled very well. There is no special
+ knowledge of CP0 handling, and the coprocessors other
+ than the floating point unit are not distinguished at
+ all. */
+ /* Itbl support may require additional care here. FIXME!
+ Need to modify this to include knowledge about
+ user specified delays! */
+ if (prev_pinfo & INSN_WRITE_FPR_T)
+ {
+ if (mips_optimize == 0
+ || insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_FT)
+ & OP_MASK_FT),
+ MIPS_FP_REG))
+ ++nops;
+ }
+ else if (prev_pinfo & INSN_WRITE_FPR_S)
+ {
+ if (mips_optimize == 0
+ || insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_FS)
+ & OP_MASK_FS),
+ MIPS_FP_REG))
+ ++nops;
+ }
+ else
+ {
+ /* We don't know exactly what the previous instruction
+ does. If the current instruction uses a coprocessor
+ register, we must insert a NOP. If previous
+ instruction may set the condition codes, and the
+ current instruction uses them, we must insert two
+ NOPS. */
+ /* Itbl support may require additional care here. */
+ if (mips_optimize == 0
+ || ((prev_pinfo & INSN_WRITE_COND_CODE)
+ && (pinfo & INSN_READ_COND_CODE)))
+ nops += 2;
+ else if (pinfo & INSN_COP)
+ ++nops;
+ }
+ }
+ else if (! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (prev_pinfo & INSN_WRITE_COND_CODE)
+ && ! cop_interlocks)
+ {
+ /* The previous instruction sets the coprocessor condition
+ codes, but does not require a general coprocessor delay
+ (this means it is a floating point comparison
+ instruction). If this instruction uses the condition
+ codes, we need to insert a single NOP. */
+ /* Itbl support may require additional care here. */
+ if (mips_optimize == 0
+ || (pinfo & INSN_READ_COND_CODE))
+ ++nops;
+ }
+ else if (prev_pinfo & INSN_READ_LO)
+ {
+ /* The previous instruction reads the LO register; if the
+ current instruction writes to the LO register, we must
+ insert two NOPS. Some newer processors have interlocks.
+ Also the tx39's multiply instructions can be exectuted
+ immediatly after a read from HI/LO (without the delay),
+ though the tx39's divide insns still do require the
+ delay. */
+ if (! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))
+ && (mips_optimize == 0
+ || (pinfo & INSN_WRITE_LO)))
+ nops += 2;
+ /* Most mips16 branch insns don't have a delay slot.
+ If a read from LO is immediately followed by a branch
+ to a write to LO we have a read followed by a write
+ less than 2 insns away. We assume the target of
+ a branch might be a write to LO, and insert a nop
+ between a read and an immediately following branch. */
+ else if (mips_opts.mips16
+ && (mips_optimize == 0
+ || (pinfo & MIPS16_INSN_BRANCH)))
+ nops += 1;
+ }
+ else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ {
+ /* The previous instruction reads the HI register; if the
+ current instruction writes to the HI register, we must
+ insert a NOP. Some newer processors have interlocks.
+ Also the note tx39's multiply above. */
+ if (! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))
+ && (mips_optimize == 0
+ || (pinfo & INSN_WRITE_HI)))
+ nops += 2;
+ /* Most mips16 branch insns don't have a delay slot.
+ If a read from HI is immediately followed by a branch
+ to a write to HI we have a read followed by a write
+ less than 2 insns away. We assume the target of
+ a branch might be a write to HI, and insert a nop
+ between a read and an immediately following branch. */
+ else if (mips_opts.mips16
+ && (mips_optimize == 0
+ || (pinfo & MIPS16_INSN_BRANCH)))
+ nops += 1;
+ }
+
+ /* If the previous instruction was in a noreorder section, then
+ we don't want to insert the nop after all. */
+ /* Itbl support may require additional care here. */
+ if (prev_insn_unreordered)
+ nops = 0;
+
+ /* There are two cases which require two intervening
+ instructions: 1) setting the condition codes using a move to
+ coprocessor instruction which requires a general coprocessor
+ delay and then reading the condition codes 2) reading the HI
+ or LO register and then writing to it (except on processors
+ which have interlocks). If we are not already emitting a NOP
+ instruction, we must check for these cases compared to the
+ instruction previous to the previous instruction. */
+ if ((! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
+ && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
+ && (pinfo & INSN_READ_COND_CODE)
+ && ! cop_interlocks)
+ || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
+ && (pinfo & INSN_WRITE_LO)
+ && ! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT))))
+ || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ && (pinfo & INSN_WRITE_HI)
+ && ! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))))
+ prev_prev_nop = 1;
+ else
+ prev_prev_nop = 0;
+
+ if (prev_prev_insn_unreordered)
+ prev_prev_nop = 0;
+
+ if (prev_prev_nop && nops == 0)
+ ++nops;
+
+ /* If we are being given a nop instruction, don't bother with
+ one of the nops we would otherwise output. This will only
+ happen when a nop instruction is used with mips_optimize set
+ to 0. */
+ if (nops > 0
+ && ! mips_opts.noreorder
+ && ip->insn_opcode == (mips_opts.mips16 ? 0x6500 : 0))
+ --nops;
+
+ /* Now emit the right number of NOP instructions. */
+ if (nops > 0 && ! mips_opts.noreorder)
+ {
+ fragS *old_frag;
+ unsigned long old_frag_offset;
+ int i;
+ struct insn_label_list *l;
+
+ old_frag = frag_now;
+ old_frag_offset = frag_now_fix ();
+
+ for (i = 0; i < nops; i++)
+ emit_nop ();
+
+ if (listing)
+ {
+ listing_prev_line ();
+ /* We may be at the start of a variant frag. In case we
+ are, make sure there is enough space for the frag
+ after the frags created by listing_prev_line. The
+ argument to frag_grow here must be at least as large
+ as the argument to all other calls to frag_grow in
+ this file. We don't have to worry about being in the
+ middle of a variant frag, because the variants insert
+ all needed nop instructions themselves. */
+ frag_grow (40);
+ }
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+ assert (S_GET_SEGMENT (l->label) == now_seg);
+ l->label->sy_frag = frag_now;
+ S_SET_VALUE (l->label, (valueT) frag_now_fix ());
+ /* mips16 text labels are stored as odd. */
+ if (mips_opts.mips16)
+ ++l->label->sy_value.X_add_number;
+ }
+
+#ifndef NO_ECOFF_DEBUGGING
+ if (ECOFF_DEBUGGING)
+ ecoff_fix_loc (old_frag, old_frag_offset);
+#endif
+ }
+ else if (prev_nop_frag != NULL)
+ {
+ /* We have a frag holding nops we may be able to remove. If
+ we don't need any nops, we can decrease the size of
+ prev_nop_frag by the size of one instruction. If we do
+ need some nops, we count them in prev_nops_required. */
+ if (prev_nop_frag_since == 0)
+ {
+ if (nops == 0)
+ {
+ prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;
+ --prev_nop_frag_holds;
+ }
+ else
+ prev_nop_frag_required += nops;
+ }
+ else
+ {
+ if (prev_prev_nop == 0)
+ {
+ prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;
+ --prev_nop_frag_holds;
+ }
+ else
+ ++prev_nop_frag_required;
+ }
+
+ if (prev_nop_frag_holds <= prev_nop_frag_required)
+ prev_nop_frag = NULL;
+
+ ++prev_nop_frag_since;
+
+ /* Sanity check: by the time we reach the second instruction
+ after prev_nop_frag, we should have used up all the nops
+ one way or another. */
+ assert (prev_nop_frag_since <= 1 || prev_nop_frag == NULL);
+ }
+ }
+
+ if (reloc_type > BFD_RELOC_UNUSED)
+ {
+ /* We need to set up a variant frag. */
+ assert (mips_opts.mips16 && address_expr != NULL);
+ f = frag_var (rs_machine_dependent, 4, 0,
+ RELAX_MIPS16_ENCODE (reloc_type - BFD_RELOC_UNUSED,
+ mips16_small, mips16_ext,
+ (prev_pinfo
+ & INSN_UNCOND_BRANCH_DELAY),
+ (prev_insn_reloc_type
+ == BFD_RELOC_MIPS16_JMP)),
+ make_expr_symbol (address_expr), (offsetT) 0,
+ (char *) NULL);
+ }
+ else if (place != NULL)
+ f = place;
+ else if (mips_opts.mips16
+ && ! ip->use_extend
+ && reloc_type != BFD_RELOC_MIPS16_JMP)
+ {
+ /* Make sure there is enough room to swap this instruction with
+ a following jump instruction. */
+ frag_grow (6);
+ f = frag_more (2);
+ }
+ else
+ {
+ if (mips_opts.mips16
+ && mips_opts.noreorder
+ && (prev_pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+ as_warn (_("extended instruction in delay slot"));
+
+ f = frag_more (4);
+ }
+
+ fixp = NULL;
+ if (address_expr != NULL && reloc_type < BFD_RELOC_UNUSED)
+ {
+ if (address_expr->X_op == O_constant)
+ {
+ switch (reloc_type)
+ {
+ case BFD_RELOC_32:
+ ip->insn_opcode |= address_expr->X_add_number;
+ break;
+
+ case BFD_RELOC_LO16:
+ ip->insn_opcode |= address_expr->X_add_number & 0xffff;
+ break;
+
+ case BFD_RELOC_MIPS_JMP:
+ if ((address_expr->X_add_number & 3) != 0)
+ as_bad (_("jump to misaligned address (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ ip->insn_opcode |= (address_expr->X_add_number >> 2) & 0x3ffffff;
+ break;
+
+ case BFD_RELOC_MIPS16_JMP:
+ if ((address_expr->X_add_number & 3) != 0)
+ as_bad (_("jump to misaligned address (0x%lx)"),
+ (unsigned long) address_expr->X_add_number);
+ ip->insn_opcode |=
+ (((address_expr->X_add_number & 0x7c0000) << 3)
+ | ((address_expr->X_add_number & 0xf800000) >> 7)
+ | ((address_expr->X_add_number & 0x3fffc) >> 2));
+ break;
+
+
+ case BFD_RELOC_16_PCREL_S2:
+ goto need_reloc;
+
+ default:
+ internalError ();
+ }
+ }
+ else
+ {
+ need_reloc:
+ /* Don't generate a reloc if we are writing into a variant
+ frag. */
+ if (place == NULL)
+ {
+ fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
+ address_expr,
+ reloc_type == BFD_RELOC_16_PCREL_S2,
+ reloc_type);
+ if (unmatched_hi)
+ {
+ struct mips_hi_fixup *hi_fixup;
+
+ assert (reloc_type == BFD_RELOC_HI16_S);
+ hi_fixup = ((struct mips_hi_fixup *)
+ xmalloc (sizeof (struct mips_hi_fixup)));
+ hi_fixup->fixp = fixp;
+ hi_fixup->seg = now_seg;
+ hi_fixup->next = mips_hi_fixup_list;
+ mips_hi_fixup_list = hi_fixup;
+ }
+ }
+ }
+ }
+
+ if (! mips_opts.mips16)
+ md_number_to_chars (f, ip->insn_opcode, 4);
+ else if (reloc_type == BFD_RELOC_MIPS16_JMP)
+ {
+ md_number_to_chars (f, ip->insn_opcode >> 16, 2);
+ md_number_to_chars (f + 2, ip->insn_opcode & 0xffff, 2);
+ }
+ else
+ {
+ if (ip->use_extend)
+ {
+ md_number_to_chars (f, 0xf000 | ip->extend, 2);
+ f += 2;
+ }
+ md_number_to_chars (f, ip->insn_opcode, 2);
+ }
+
+ /* Update the register mask information. */
+ if (! mips_opts.mips16)
+ {
+ if (pinfo & INSN_WRITE_GPR_D)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD);
+ if ((pinfo & (INSN_WRITE_GPR_T | INSN_READ_GPR_T)) != 0)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT);
+ if (pinfo & INSN_READ_GPR_S)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS);
+ if (pinfo & INSN_WRITE_GPR_31)
+ mips_gprmask |= 1 << 31;
+ if (pinfo & INSN_WRITE_FPR_D)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FD) & OP_MASK_FD);
+ if ((pinfo & (INSN_WRITE_FPR_S | INSN_READ_FPR_S)) != 0)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS);
+ if ((pinfo & (INSN_WRITE_FPR_T | INSN_READ_FPR_T)) != 0)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT);
+ if ((pinfo & INSN_READ_FPR_R) != 0)
+ mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FR) & OP_MASK_FR);
+ if (pinfo & INSN_COP)
+ {
+ /* We don't keep enough information to sort these cases out.
+ The itbl support does keep this information however, although
+ we currently don't support itbl fprmats as part of the cop
+ instruction. May want to add this support in the future. */
+ }
+ /* Never set the bit for $0, which is always zero. */
+ mips_gprmask &=~ 1 << 0;
+ }
+ else
+ {
+ if (pinfo & (MIPS16_INSN_WRITE_X | MIPS16_INSN_READ_X))
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX);
+ if (pinfo & (MIPS16_INSN_WRITE_Y | MIPS16_INSN_READ_Y))
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY);
+ if (pinfo & MIPS16_INSN_WRITE_Z)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RZ)
+ & MIPS16OP_MASK_RZ);
+ if (pinfo & (MIPS16_INSN_WRITE_T | MIPS16_INSN_READ_T))
+ mips_gprmask |= 1 << TREG;
+ if (pinfo & (MIPS16_INSN_WRITE_SP | MIPS16_INSN_READ_SP))
+ mips_gprmask |= 1 << SP;
+ if (pinfo & (MIPS16_INSN_WRITE_31 | MIPS16_INSN_READ_31))
+ mips_gprmask |= 1 << RA;
+ if (pinfo & MIPS16_INSN_WRITE_GPR_Y)
+ mips_gprmask |= 1 << MIPS16OP_EXTRACT_REG32R (ip->insn_opcode);
+ if (pinfo & MIPS16_INSN_READ_Z)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_MOVE32Z)
+ & MIPS16OP_MASK_MOVE32Z);
+ if (pinfo & MIPS16_INSN_READ_GPR_X)
+ mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_REGR32)
+ & MIPS16OP_MASK_REGR32);
+ }
+
+ if (place == NULL && ! mips_opts.noreorder)
+ {
+ /* Filling the branch delay slot is more complex. We try to
+ switch the branch with the previous instruction, which we can
+ do if the previous instruction does not set up a condition
+ that the branch tests and if the branch is not itself the
+ target of any branch. */
+ if ((pinfo & INSN_UNCOND_BRANCH_DELAY)
+ || (pinfo & INSN_COND_BRANCH_DELAY))
+ {
+ if (mips_optimize < 2
+ /* If we have seen .set volatile or .set nomove, don't
+ optimize. */
+ || mips_opts.nomove != 0
+ /* If we had to emit any NOP instructions, then we
+ already know we can not swap. */
+ || nops != 0
+ /* If we don't even know the previous insn, we can not
+ swap. */
+ || ! prev_insn_valid
+ /* If the previous insn is already in a branch delay
+ slot, then we can not swap. */
+ || prev_insn_is_delay_slot
+ /* If the previous previous insn was in a .set
+ noreorder, we can't swap. Actually, the MIPS
+ assembler will swap in this situation. However, gcc
+ configured -with-gnu-as will generate code like
+ .set noreorder
+ lw $4,XXX
+ .set reorder
+ INSN
+ bne $4,$0,foo
+ in which we can not swap the bne and INSN. If gcc is
+ not configured -with-gnu-as, it does not output the
+ .set pseudo-ops. We don't have to check
+ prev_insn_unreordered, because prev_insn_valid will
+ be 0 in that case. We don't want to use
+ prev_prev_insn_valid, because we do want to be able
+ to swap at the start of a function. */
+ || prev_prev_insn_unreordered
+ /* If the branch is itself the target of a branch, we
+ can not swap. We cheat on this; all we check for is
+ whether there is a label on this instruction. If
+ there are any branches to anything other than a
+ label, users must use .set noreorder. */
+ || insn_labels != NULL
+ /* If the previous instruction is in a variant frag, we
+ can not do the swap. This does not apply to the
+ mips16, which uses variant frags for different
+ purposes. */
+ || (! mips_opts.mips16
+ && prev_insn_frag->fr_type == rs_machine_dependent)
+ /* If the branch reads the condition codes, we don't
+ even try to swap, because in the sequence
+ ctc1 $X,$31
+ INSN
+ INSN
+ bc1t LABEL
+ we can not swap, and I don't feel like handling that
+ case. */
+ || (! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (pinfo & INSN_READ_COND_CODE))
+ /* We can not swap with an instruction that requires a
+ delay slot, becase the target of the branch might
+ interfere with that instruction. */
+ || (! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (prev_pinfo
+ /* Itbl support may require additional care here. */
+ & (INSN_LOAD_COPROC_DELAY
+ | INSN_COPROC_MOVE_DELAY
+ | INSN_WRITE_COND_CODE)))
+ || (! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))
+ && (prev_pinfo
+ & (INSN_READ_LO
+ | INSN_READ_HI)))
+ || (! mips_opts.mips16
+ && ! gpr_interlocks
+ && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))
+ || (! mips_opts.mips16
+ && mips_opts.isa < 2
+ /* Itbl support may require additional care here. */
+ && (prev_pinfo & INSN_COPROC_MEMORY_DELAY))
+ /* We can not swap with a branch instruction. */
+ || (prev_pinfo
+ & (INSN_UNCOND_BRANCH_DELAY
+ | INSN_COND_BRANCH_DELAY
+ | INSN_COND_BRANCH_LIKELY))
+ /* We do not swap with a trap instruction, since it
+ complicates trap handlers to have the trap
+ instruction be in a delay slot. */
+ || (prev_pinfo & INSN_TRAP)
+ /* If the branch reads a register that the previous
+ instruction sets, we can not swap. */
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_T)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT),
+ MIPS_GR_REG))
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_D)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+ || (mips_opts.mips16
+ && (((prev_pinfo & MIPS16_INSN_WRITE_X)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode
+ >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX),
+ MIPS16_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_Y)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode
+ >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY),
+ MIPS16_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_Z)
+ && insn_uses_reg (ip,
+ ((prev_insn.insn_opcode
+ >> MIPS16OP_SH_RZ)
+ & MIPS16OP_MASK_RZ),
+ MIPS16_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_T)
+ && insn_uses_reg (ip, TREG, MIPS_GR_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_31)
+ && insn_uses_reg (ip, RA, MIPS_GR_REG))
+ || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
+ && insn_uses_reg (ip,
+ MIPS16OP_EXTRACT_REG32R (prev_insn.
+ insn_opcode),
+ MIPS_GR_REG))))
+ /* If the branch writes a register that the previous
+ instruction sets, we can not swap (we know that
+ branches write only to RD or to $31). */
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_T)
+ && (((pinfo & INSN_WRITE_GPR_D)
+ && (((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT)
+ == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
+ || ((pinfo & INSN_WRITE_GPR_31)
+ && (((prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT)
+ == 31))))
+ || (! mips_opts.mips16
+ && (prev_pinfo & INSN_WRITE_GPR_D)
+ && (((pinfo & INSN_WRITE_GPR_D)
+ && (((prev_insn.insn_opcode >> OP_SH_RD) & OP_MASK_RD)
+ == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))
+ || ((pinfo & INSN_WRITE_GPR_31)
+ && (((prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD)
+ == 31))))
+ || (mips_opts.mips16
+ && (pinfo & MIPS16_INSN_WRITE_31)
+ && ((prev_pinfo & MIPS16_INSN_WRITE_31)
+ || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
+ && (MIPS16OP_EXTRACT_REG32R (prev_insn.insn_opcode)
+ == RA))))
+ /* If the branch writes a register that the previous
+ instruction reads, we can not swap (we know that
+ branches only write to RD or to $31). */
+ || (! mips_opts.mips16
+ && (pinfo & INSN_WRITE_GPR_D)
+ && insn_uses_reg (&prev_insn,
+ ((ip->insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+ || (! mips_opts.mips16
+ && (pinfo & INSN_WRITE_GPR_31)
+ && insn_uses_reg (&prev_insn, 31, MIPS_GR_REG))
+ || (mips_opts.mips16
+ && (pinfo & MIPS16_INSN_WRITE_31)
+ && insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))
+ /* If we are generating embedded PIC code, the branch
+ might be expanded into a sequence which uses $at, so
+ we can't swap with an instruction which reads it. */
+ || (mips_pic == EMBEDDED_PIC
+ && insn_uses_reg (&prev_insn, AT, MIPS_GR_REG))
+ /* If the previous previous instruction has a load
+ delay, and sets a register that the branch reads, we
+ can not swap. */
+ || (! mips_opts.mips16
+ && mips_opts.isa < 4
+ /* Itbl support may require additional care here. */
+ && ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
+ || (! gpr_interlocks
+ && (prev_prev_insn.insn_mo->pinfo
+ & INSN_LOAD_MEMORY_DELAY)))
+ && insn_uses_reg (ip,
+ ((prev_prev_insn.insn_opcode >> OP_SH_RT)
+ & OP_MASK_RT),
+ MIPS_GR_REG))
+ /* If one instruction sets a condition code and the
+ other one uses a condition code, we can not swap. */
+ || ((pinfo & INSN_READ_COND_CODE)
+ && (prev_pinfo & INSN_WRITE_COND_CODE))
+ || ((pinfo & INSN_WRITE_COND_CODE)
+ && (prev_pinfo & INSN_READ_COND_CODE))
+ /* If the previous instruction uses the PC, we can not
+ swap. */
+ || (mips_opts.mips16
+ && (prev_pinfo & MIPS16_INSN_READ_PC))
+ /* If the previous instruction was extended, we can not
+ swap. */
+ || (mips_opts.mips16 && prev_insn_extended)
+ /* If the previous instruction had a fixup in mips16
+ mode, we can not swap. This normally means that the
+ previous instruction was a 4 byte branch anyhow. */
+ || (mips_opts.mips16 && prev_insn_fixp)
+ /* If the previous instruction is a sync, sync.l, or
+ sync.p, we can not swap. */
+ || (prev_pinfo && INSN_SYNC))
+ {
+ /* We could do even better for unconditional branches to
+ portions of this object file; we could pick up the
+ instruction at the destination, put it in the delay
+ slot, and bump the destination address. */
+ emit_nop ();
+ /* Update the previous insn information. */
+ prev_prev_insn = *ip;
+ prev_insn.insn_mo = &dummy_opcode;
+ }
+ else
+ {
+ /* It looks like we can actually do the swap. */
+ if (! mips_opts.mips16)
+ {
+ char *prev_f;
+ char temp[4];
+
+ prev_f = prev_insn_frag->fr_literal + prev_insn_where;
+ memcpy (temp, prev_f, 4);
+ memcpy (prev_f, f, 4);
+ memcpy (f, temp, 4);
+ if (prev_insn_fixp)
+ {
+ prev_insn_fixp->fx_frag = frag_now;
+ prev_insn_fixp->fx_where = f - frag_now->fr_literal;
+ }
+ if (fixp)
+ {
+ fixp->fx_frag = prev_insn_frag;
+ fixp->fx_where = prev_insn_where;
+ }
+ }
+ else
+ {
+ char *prev_f;
+ char temp[2];
+
+ assert (prev_insn_fixp == NULL);
+ prev_f = prev_insn_frag->fr_literal + prev_insn_where;
+ memcpy (temp, prev_f, 2);
+ memcpy (prev_f, f, 2);
+ if (reloc_type != BFD_RELOC_MIPS16_JMP)
+ {
+ assert (reloc_type == BFD_RELOC_UNUSED);
+ memcpy (f, temp, 2);
+ }
+ else
+ {
+ memcpy (f, f + 2, 2);
+ memcpy (f + 2, temp, 2);
+ }
+ if (fixp)
+ {
+ fixp->fx_frag = prev_insn_frag;
+ fixp->fx_where = prev_insn_where;
+ }
+ }
+
+ /* Update the previous insn information; leave prev_insn
+ unchanged. */
+ prev_prev_insn = *ip;
+ }
+ prev_insn_is_delay_slot = 1;
+
+ /* If that was an unconditional branch, forget the previous
+ insn information. */
+ if (pinfo & INSN_UNCOND_BRANCH_DELAY)
+ {
+ prev_prev_insn.insn_mo = &dummy_opcode;
+ prev_insn.insn_mo = &dummy_opcode;
+ }
+
+ prev_insn_fixp = NULL;
+ prev_insn_reloc_type = BFD_RELOC_UNUSED;
+ prev_insn_extended = 0;
+ }
+ else if (pinfo & INSN_COND_BRANCH_LIKELY)
+ {
+ /* We don't yet optimize a branch likely. What we should do
+ is look at the target, copy the instruction found there
+ into the delay slot, and increment the branch to jump to
+ the next instruction. */
+ emit_nop ();
+ /* Update the previous insn information. */
+ prev_prev_insn = *ip;
+ prev_insn.insn_mo = &dummy_opcode;
+ prev_insn_fixp = NULL;
+ prev_insn_reloc_type = BFD_RELOC_UNUSED;
+ prev_insn_extended = 0;
+ }
+ else
+ {
+ /* Update the previous insn information. */
+ if (nops > 0)
+ prev_prev_insn.insn_mo = &dummy_opcode;
+ else
+ prev_prev_insn = prev_insn;
+ prev_insn = *ip;
+
+ /* Any time we see a branch, we always fill the delay slot
+ immediately; since this insn is not a branch, we know it
+ is not in a delay slot. */
+ prev_insn_is_delay_slot = 0;
+
+ prev_insn_fixp = fixp;
+ prev_insn_reloc_type = reloc_type;
+ if (mips_opts.mips16)
+ prev_insn_extended = (ip->use_extend
+ || reloc_type > BFD_RELOC_UNUSED);
+ }
+
+ prev_prev_insn_unreordered = prev_insn_unreordered;
+ prev_insn_unreordered = 0;
+ prev_insn_frag = frag_now;
+ prev_insn_where = f - frag_now->fr_literal;
+ prev_insn_valid = 1;
+ }
+ else if (place == NULL)
+ {
+ /* We need to record a bit of information even when we are not
+ reordering, in order to determine the base address for mips16
+ PC relative relocs. */
+ prev_prev_insn = prev_insn;
+ prev_insn = *ip;
+ prev_insn_reloc_type = reloc_type;
+ prev_prev_insn_unreordered = prev_insn_unreordered;
+ prev_insn_unreordered = 1;
+ }
+
+ /* We just output an insn, so the next one doesn't have a label. */
+ mips_clear_insn_labels ();
+
+ /* We must ensure that a fixup associated with an unmatched %hi
+ reloc does not become a variant frag. Otherwise, the
+ rearrangement of %hi relocs in frob_file may confuse
+ tc_gen_reloc. */
+ if (unmatched_hi)
+ {
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+}
+
+/* This function forgets that there was any previous instruction or
+ label. If PRESERVE is non-zero, it remembers enough information to
+ know whether nops are needed before a noreorder section. */
+
+static void
+mips_no_prev_insn (preserve)
+ int preserve;
+{
+ if (! preserve)
+ {
+ prev_insn.insn_mo = &dummy_opcode;
+ prev_prev_insn.insn_mo = &dummy_opcode;
+ prev_nop_frag = NULL;
+ prev_nop_frag_holds = 0;
+ prev_nop_frag_required = 0;
+ prev_nop_frag_since = 0;
+ }
+ prev_insn_valid = 0;
+ prev_insn_is_delay_slot = 0;
+ prev_insn_unreordered = 0;
+ prev_insn_extended = 0;
+ prev_insn_reloc_type = BFD_RELOC_UNUSED;
+ prev_prev_insn_unreordered = 0;
+ mips_clear_insn_labels ();
+}
+
+/* This function must be called whenever we turn on noreorder or emit
+ something other than instructions. It inserts any NOPS which might
+ be needed by the previous instruction, and clears the information
+ kept for the previous instructions. The INSNS parameter is true if
+ instructions are to follow. */
+
+static void
+mips_emit_delays (insns)
+ boolean insns;
+{
+ if (! mips_opts.noreorder)
+ {
+ int nops;
+
+ nops = 0;
+ if ((! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (! cop_interlocks
+ && (prev_insn.insn_mo->pinfo
+ & (INSN_LOAD_COPROC_DELAY
+ | INSN_COPROC_MOVE_DELAY
+ | INSN_WRITE_COND_CODE))))
+ || (! hilo_interlocks
+ && (prev_insn.insn_mo->pinfo
+ & (INSN_READ_LO
+ | INSN_READ_HI)))
+ || (! mips_opts.mips16
+ && ! gpr_interlocks
+ && (prev_insn.insn_mo->pinfo
+ & INSN_LOAD_MEMORY_DELAY))
+ || (! mips_opts.mips16
+ && mips_opts.isa < 2
+ && (prev_insn.insn_mo->pinfo
+ & INSN_COPROC_MEMORY_DELAY)))
+ {
+ /* Itbl support may require additional care here. */
+ ++nops;
+ if ((! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (! cop_interlocks
+ && prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
+ || (! hilo_interlocks
+ && ((prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ || (prev_insn.insn_mo->pinfo & INSN_READ_LO))))
+ ++nops;
+
+ if (prev_insn_unreordered)
+ nops = 0;
+ }
+ else if ((! mips_opts.mips16
+ && mips_opts.isa < 4
+ && (! cop_interlocks
+ && prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
+ || (! hilo_interlocks
+ && ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
+ || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
+ {
+ /* Itbl support may require additional care here. */
+ if (! prev_prev_insn_unreordered)
+ ++nops;
+ }
+
+ if (nops > 0)
+ {
+ struct insn_label_list *l;
+
+ if (insns)
+ {
+ /* Record the frag which holds the nop instructions, so
+ that we can remove them if we don't need them. */
+ frag_grow (mips_opts.mips16 ? nops * 2 : nops * 4);
+ prev_nop_frag = frag_now;
+ prev_nop_frag_holds = nops;
+ prev_nop_frag_required = 0;
+ prev_nop_frag_since = 0;
+ }
+
+ for (; nops > 0; --nops)
+ emit_nop ();
+
+ if (insns)
+ {
+ /* Move on to a new frag, so that it is safe to simply
+ decrease the size of prev_nop_frag. */
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+ assert (S_GET_SEGMENT (l->label) == now_seg);
+ l->label->sy_frag = frag_now;
+ S_SET_VALUE (l->label, (valueT) frag_now_fix ());
+ /* mips16 text labels are stored as odd. */
+ if (mips_opts.mips16)
+ ++l->label->sy_value.X_add_number;
+ }
+ }
+ }
+
+ /* Mark instruction labels in mips16 mode. */
+ if (mips_opts.mips16 && insns)
+ mips16_mark_labels ();
+
+ mips_no_prev_insn (insns);
+}
+
+/* Build an instruction created by a macro expansion. This is passed
+ a pointer to the count of instructions created so far, an
+ expression, the name of the instruction to build, an operand format
+ string, and corresponding arguments. */
+
+#ifdef USE_STDARG
+static void
+macro_build (char *place,
+ int *counter,
+ expressionS * ep,
+ const char *name,
+ const char *fmt,
+ ...)
+#else
+static void
+macro_build (place, counter, ep, name, fmt, va_alist)
+ char *place;
+ int *counter;
+ expressionS *ep;
+ const char *name;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type r;
+ va_list args;
+ int insn_isa;
+
+#ifdef USE_STDARG
+ va_start (args, fmt);
+#else
+ va_start (args);
+#endif
+
+ /*
+ * If the macro is about to expand into a second instruction,
+ * print a warning if needed. We need to pass ip as a parameter
+ * to generate a better warning message here...
+ */
+ if (mips_opts.warn_about_macros && place == NULL && *counter == 1)
+ as_warn (_("Macro instruction expanded into multiple instructions"));
+
+ if (place == NULL)
+ *counter += 1; /* bump instruction counter */
+
+ if (mips_opts.mips16)
+ {
+ mips16_macro_build (place, counter, ep, name, fmt, args);
+ va_end (args);
+ return;
+ }
+
+ r = BFD_RELOC_UNUSED;
+ insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
+ assert (insn.insn_mo);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+
+ /* Search until we get a match for NAME. */
+ while (1)
+ {
+ if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA1)
+ insn_isa = 1;
+ else if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA2)
+ insn_isa = 2;
+ else if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA3)
+ insn_isa = 3;
+ else if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA4)
+ insn_isa = 4;
+ else
+ insn_isa = 15;
+
+ if (strcmp (fmt, insn.insn_mo->args) == 0
+ && insn.insn_mo->pinfo != INSN_MACRO
+ && (insn_isa <= mips_opts.isa
+ || (mips_cpu == 4650
+ && (insn.insn_mo->membership & INSN_4650) != 0)
+ || (mips_cpu == 4010
+ && (insn.insn_mo->membership & INSN_4010) != 0)
+ || ((mips_cpu == 4100
+ || mips_cpu == 4111
+ )
+ && (insn.insn_mo->membership & INSN_4100) != 0)
+ || (mips_cpu == 3900
+ && (insn.insn_mo->membership & INSN_3900) != 0))
+ && (mips_cpu != 4650 || (insn.insn_mo->pinfo & FP_D) == 0))
+ break;
+
+ ++insn.insn_mo;
+ assert (insn.insn_mo->name);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+ }
+
+ insn.insn_opcode = insn.insn_mo->match;
+ for (;;)
+ {
+ switch (*fmt++)
+ {
+ case '\0':
+ break;
+
+ case ',':
+ case '(':
+ case ')':
+ continue;
+
+ case 't':
+ case 'w':
+ case 'E':
+ insn.insn_opcode |= va_arg (args, int) << 16;
+ continue;
+
+ case 'c':
+ case 'T':
+ case 'W':
+ insn.insn_opcode |= va_arg (args, int) << 16;
+ continue;
+
+ case 'd':
+ case 'G':
+ insn.insn_opcode |= va_arg (args, int) << 11;
+ continue;
+
+ case 'V':
+ case 'S':
+ insn.insn_opcode |= va_arg (args, int) << 11;
+ continue;
+
+ case 'z':
+ continue;
+
+ case '<':
+ insn.insn_opcode |= va_arg (args, int) << 6;
+ continue;
+
+ case 'D':
+ insn.insn_opcode |= va_arg (args, int) << 6;
+ continue;
+
+ case 'B':
+ insn.insn_opcode |= va_arg (args, int) << 6;
+ continue;
+
+ case 'q':
+ insn.insn_opcode |= va_arg (args, int) << 6;
+ continue;
+
+ case 'b':
+ case 's':
+ case 'r':
+ case 'v':
+ insn.insn_opcode |= va_arg (args, int) << 21;
+ continue;
+
+ case 'i':
+ case 'j':
+ case 'o':
+ r = (bfd_reloc_code_real_type) va_arg (args, int);
+ assert (r == BFD_RELOC_MIPS_GPREL
+ || r == BFD_RELOC_MIPS_LITERAL
+ || r == BFD_RELOC_LO16
+ || r == BFD_RELOC_MIPS_GOT16
+ || r == BFD_RELOC_MIPS_CALL16
+ || r == BFD_RELOC_MIPS_GOT_LO16
+ || r == BFD_RELOC_MIPS_CALL_LO16
+ || (ep->X_op == O_subtract
+ && now_seg == text_section
+ && r == BFD_RELOC_PCREL_LO16));
+ continue;
+
+ case 'u':
+ r = (bfd_reloc_code_real_type) va_arg (args, int);
+ assert (ep != NULL
+ && (ep->X_op == O_constant
+ || (ep->X_op == O_symbol
+ && (r == BFD_RELOC_HI16_S
+ || r == BFD_RELOC_HI16
+ || r == BFD_RELOC_MIPS_GOT_HI16
+ || r == BFD_RELOC_MIPS_CALL_HI16))
+ || (ep->X_op == O_subtract
+ && now_seg == text_section
+ && r == BFD_RELOC_PCREL_HI16_S)));
+ if (ep->X_op == O_constant)
+ {
+ insn.insn_opcode |= (ep->X_add_number >> 16) & 0xffff;
+ ep = NULL;
+ r = BFD_RELOC_UNUSED;
+ }
+ continue;
+
+ case 'p':
+ assert (ep != NULL);
+ /*
+ * This allows macro() to pass an immediate expression for
+ * creating short branches without creating a symbol.
+ * Note that the expression still might come from the assembly
+ * input, in which case the value is not checked for range nor
+ * is a relocation entry generated (yuck).
+ */
+ if (ep->X_op == O_constant)
+ {
+ insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff;
+ ep = NULL;
+ }
+ else
+ r = BFD_RELOC_16_PCREL_S2;
+ continue;
+
+ case 'a':
+ assert (ep != NULL);
+ r = BFD_RELOC_MIPS_JMP;
+ continue;
+
+ case 'C':
+ insn.insn_opcode |= va_arg (args, unsigned long);
+ continue;
+
+ default:
+ internalError ();
+ }
+ break;
+ }
+ va_end (args);
+ assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
+
+ append_insn (place, &insn, ep, r, false);
+}
+
+static void
+mips16_macro_build (place, counter, ep, name, fmt, args)
+ char *place;
+ int *counter;
+ expressionS *ep;
+ const char *name;
+ const char *fmt;
+ va_list args;
+{
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type r;
+
+ r = BFD_RELOC_UNUSED;
+ insn.insn_mo = (struct mips_opcode *) hash_find (mips16_op_hash, name);
+ assert (insn.insn_mo);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+
+ while (strcmp (fmt, insn.insn_mo->args) != 0
+ || insn.insn_mo->pinfo == INSN_MACRO)
+ {
+ ++insn.insn_mo;
+ assert (insn.insn_mo->name);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+ }
+
+ insn.insn_opcode = insn.insn_mo->match;
+ insn.use_extend = false;
+
+ for (;;)
+ {
+ int c;
+
+ c = *fmt++;
+ switch (c)
+ {
+ case '\0':
+ break;
+
+ case ',':
+ case '(':
+ case ')':
+ continue;
+
+ case 'y':
+ case 'w':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RY;
+ continue;
+
+ case 'x':
+ case 'v':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RX;
+ continue;
+
+ case 'z':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RZ;
+ continue;
+
+ case 'Z':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_MOVE32Z;
+ continue;
+
+ case '0':
+ case 'S':
+ case 'P':
+ case 'R':
+ continue;
+
+ case 'X':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_REGR32;
+ continue;
+
+ case 'Y':
+ {
+ int regno;
+
+ regno = va_arg (args, int);
+ regno = ((regno & 7) << 2) | ((regno & 0x18) >> 3);
+ insn.insn_opcode |= regno << MIPS16OP_SH_REG32R;
+ }
+ continue;
+
+ case '<':
+ case '>':
+ case '4':
+ case '5':
+ case 'H':
+ case 'W':
+ case 'D':
+ case 'j':
+ case '8':
+ case 'V':
+ case 'C':
+ case 'U':
+ case 'k':
+ case 'K':
+ case 'p':
+ case 'q':
+ {
+ assert (ep != NULL);
+
+ if (ep->X_op != O_constant)
+ r = BFD_RELOC_UNUSED + c;
+ else
+ {
+ mips16_immed ((char *) NULL, 0, c, ep->X_add_number, false,
+ false, false, &insn.insn_opcode,
+ &insn.use_extend, &insn.extend);
+ ep = NULL;
+ r = BFD_RELOC_UNUSED;
+ }
+ }
+ continue;
+
+ case '6':
+ insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_IMM6;
+ continue;
+ }
+
+ break;
+ }
+
+ assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
+
+ append_insn (place, &insn, ep, r, false);
+}
+
+/*
+ * Generate a "lui" instruction.
+ */
+static void
+macro_build_lui (place, counter, ep, regnum)
+ char *place;
+ int *counter;
+ expressionS *ep;
+ int regnum;
+{
+ expressionS high_expr;
+ struct mips_cl_insn insn;
+ bfd_reloc_code_real_type r;
+ CONST char *name = "lui";
+ CONST char *fmt = "t,u";
+
+ assert (! mips_opts.mips16);
+
+ if (place == NULL)
+ high_expr = *ep;
+ else
+ {
+ high_expr.X_op = O_constant;
+ high_expr.X_add_number = ep->X_add_number;
+ }
+
+ if (high_expr.X_op == O_constant)
+ {
+ /* we can compute the instruction now without a relocation entry */
+ if (high_expr.X_add_number & 0x8000)
+ high_expr.X_add_number += 0x10000;
+ high_expr.X_add_number =
+ ((unsigned long) high_expr.X_add_number >> 16) & 0xffff;
+ r = BFD_RELOC_UNUSED;
+ }
+ else
+ {
+ assert (ep->X_op == O_symbol);
+ /* _gp_disp is a special case, used from s_cpload. */
+ assert (mips_pic == NO_PIC
+ || strcmp (S_GET_NAME (ep->X_add_symbol), "_gp_disp") == 0);
+ r = BFD_RELOC_HI16_S;
+ }
+
+ /*
+ * If the macro is about to expand into a second instruction,
+ * print a warning if needed. We need to pass ip as a parameter
+ * to generate a better warning message here...
+ */
+ if (mips_opts.warn_about_macros && place == NULL && *counter == 1)
+ as_warn (_("Macro instruction expanded into multiple instructions"));
+
+ if (place == NULL)
+ *counter += 1; /* bump instruction counter */
+
+ insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);
+ assert (insn.insn_mo);
+ assert (strcmp (name, insn.insn_mo->name) == 0);
+ assert (strcmp (fmt, insn.insn_mo->args) == 0);
+
+ insn.insn_opcode = insn.insn_mo->match | (regnum << OP_SH_RT);
+ if (r == BFD_RELOC_UNUSED)
+ {
+ insn.insn_opcode |= high_expr.X_add_number;
+ append_insn (place, &insn, NULL, r, false);
+ }
+ else
+ append_insn (place, &insn, &high_expr, r, false);
+}
+
+/* set_at()
+ * Generates code to set the $at register to true (one)
+ * if reg is less than the immediate expression.
+ */
+static void
+set_at (counter, reg, unsignedp)
+ int *counter;
+ int reg;
+ int unsignedp;
+{
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ macro_build ((char *) NULL, counter, &imm_expr,
+ unsignedp ? "sltiu" : "slti",
+ "t,r,j", AT, reg, (int) BFD_RELOC_LO16);
+ else
+ {
+ load_register (counter, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, counter, NULL,
+ unsignedp ? "sltu" : "slt",
+ "d,v,t", AT, reg, AT);
+ }
+}
+
+/* Warn if an expression is not a constant. */
+
+static void
+check_absolute_expr (ip, ex)
+ struct mips_cl_insn *ip;
+ expressionS *ex;
+{
+ if (ex->X_op == O_big)
+ as_bad (_("unsupported large constant"));
+ else if (ex->X_op != O_constant)
+ as_bad (_("Instruction %s requires absolute expression"), ip->insn_mo->name);
+}
+
+/* Count the leading zeroes by performing a binary chop. This is a
+ bulky bit of source, but performance is a LOT better for the
+ majority of values than a simple loop to count the bits:
+ for (lcnt = 0; (lcnt < 32); lcnt++)
+ if ((v) & (1 << (31 - lcnt)))
+ break;
+ However it is not code size friendly, and the gain will drop a bit
+ on certain cached systems.
+*/
+#define COUNT_TOP_ZEROES(v) \
+ (((v) & ~0xffff) == 0 \
+ ? ((v) & ~0xff) == 0 \
+ ? ((v) & ~0xf) == 0 \
+ ? ((v) & ~0x3) == 0 \
+ ? ((v) & ~0x1) == 0 \
+ ? !(v) \
+ ? 32 \
+ : 31 \
+ : 30 \
+ : ((v) & ~0x7) == 0 \
+ ? 29 \
+ : 28 \
+ : ((v) & ~0x3f) == 0 \
+ ? ((v) & ~0x1f) == 0 \
+ ? 27 \
+ : 26 \
+ : ((v) & ~0x7f) == 0 \
+ ? 25 \
+ : 24 \
+ : ((v) & ~0xfff) == 0 \
+ ? ((v) & ~0x3ff) == 0 \
+ ? ((v) & ~0x1ff) == 0 \
+ ? 23 \
+ : 22 \
+ : ((v) & ~0x7ff) == 0 \
+ ? 21 \
+ : 20 \
+ : ((v) & ~0x3fff) == 0 \
+ ? ((v) & ~0x1fff) == 0 \
+ ? 19 \
+ : 18 \
+ : ((v) & ~0x7fff) == 0 \
+ ? 17 \
+ : 16 \
+ : ((v) & ~0xffffff) == 0 \
+ ? ((v) & ~0xfffff) == 0 \
+ ? ((v) & ~0x3ffff) == 0 \
+ ? ((v) & ~0x1ffff) == 0 \
+ ? 15 \
+ : 14 \
+ : ((v) & ~0x7ffff) == 0 \
+ ? 13 \
+ : 12 \
+ : ((v) & ~0x3fffff) == 0 \
+ ? ((v) & ~0x1fffff) == 0 \
+ ? 11 \
+ : 10 \
+ : ((v) & ~0x7fffff) == 0 \
+ ? 9 \
+ : 8 \
+ : ((v) & ~0xfffffff) == 0 \
+ ? ((v) & ~0x3ffffff) == 0 \
+ ? ((v) & ~0x1ffffff) == 0 \
+ ? 7 \
+ : 6 \
+ : ((v) & ~0x7ffffff) == 0 \
+ ? 5 \
+ : 4 \
+ : ((v) & ~0x3fffffff) == 0 \
+ ? ((v) & ~0x1fffffff) == 0 \
+ ? 3 \
+ : 2 \
+ : ((v) & ~0x7fffffff) == 0 \
+ ? 1 \
+ : 0)
+
+/* load_register()
+ * This routine generates the least number of instructions neccessary to load
+ * an absolute expression value into a register.
+ */
+static void
+load_register (counter, reg, ep, dbl)
+ int *counter;
+ int reg;
+ expressionS *ep;
+ int dbl;
+{
+ int freg;
+ expressionS hi32, lo32;
+
+ if (ep->X_op != O_big)
+ {
+ assert (ep->X_op == O_constant);
+ if (ep->X_add_number < 0x8000
+ && (ep->X_add_number >= 0
+ || (ep->X_add_number >= -0x8000
+ && (! dbl
+ || ! ep->X_unsigned
+ || sizeof (ep->X_add_number) > 4))))
+ {
+ /* We can handle 16 bit signed values with an addiu to
+ $zero. No need to ever use daddiu here, since $zero and
+ the result are always correct in 32 bit mode. */
+ macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,
+ (int) BFD_RELOC_LO16);
+ return;
+ }
+ else if (ep->X_add_number >= 0 && ep->X_add_number < 0x10000)
+ {
+ /* We can handle 16 bit unsigned values with an ori to
+ $zero. */
+ macro_build ((char *) NULL, counter, ep, "ori", "t,r,i", reg, 0,
+ (int) BFD_RELOC_LO16);
+ return;
+ }
+ else if ((((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0
+ || ((ep->X_add_number &~ (offsetT) 0x7fffffff)
+ == ~ (offsetT) 0x7fffffff))
+ && (! dbl
+ || ! ep->X_unsigned
+ || sizeof (ep->X_add_number) > 4
+ || (ep->X_add_number & 0x80000000) == 0))
+ || ((mips_opts.isa < 3 || ! dbl)
+ && (ep->X_add_number &~ (offsetT) 0xffffffff) == 0)
+ || (mips_opts.isa < 3
+ && ! dbl
+ && ((ep->X_add_number &~ (offsetT) 0xffffffff)
+ == ~ (offsetT) 0xffffffff)))
+ {
+ /* 32 bit values require an lui. */
+ macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
+ (int) BFD_RELOC_HI16);
+ if ((ep->X_add_number & 0xffff) != 0)
+ macro_build ((char *) NULL, counter, ep, "ori", "t,r,i", reg, reg,
+ (int) BFD_RELOC_LO16);
+ return;
+ }
+ }
+
+ /* The value is larger than 32 bits. */
+
+ if (mips_opts.isa < 3)
+ {
+ as_bad (_("Number larger than 32 bits"));
+ macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,
+ (int) BFD_RELOC_LO16);
+ return;
+ }
+
+ if (ep->X_op != O_big)
+ {
+ hi32 = *ep;
+ hi32.X_add_number = (valueT) hi32.X_add_number >> 16;
+ hi32.X_add_number = (valueT) hi32.X_add_number >> 16;
+ hi32.X_add_number &= 0xffffffff;
+ lo32 = *ep;
+ lo32.X_add_number &= 0xffffffff;
+ }
+ else
+ {
+ assert (ep->X_add_number > 2);
+ if (ep->X_add_number == 3)
+ generic_bignum[3] = 0;
+ else if (ep->X_add_number > 4)
+ as_bad (_("Number larger than 64 bits"));
+ lo32.X_op = O_constant;
+ lo32.X_add_number = generic_bignum[0] + (generic_bignum[1] << 16);
+ hi32.X_op = O_constant;
+ hi32.X_add_number = generic_bignum[2] + (generic_bignum[3] << 16);
+ }
+
+ if (hi32.X_add_number == 0)
+ freg = 0;
+ else
+ {
+ int shift, bit;
+ unsigned long hi, lo;
+
+ if (hi32.X_add_number == 0xffffffff)
+ {
+ if ((lo32.X_add_number & 0xffff8000) == 0xffff8000)
+ {
+ macro_build ((char *) NULL, counter, &lo32, "addiu", "t,r,j",
+ reg, 0, (int) BFD_RELOC_LO16);
+ return;
+ }
+ if (lo32.X_add_number & 0x80000000)
+ {
+ macro_build ((char *) NULL, counter, &lo32, "lui", "t,u", reg,
+ (int) BFD_RELOC_HI16);
+ if (lo32.X_add_number & 0xffff)
+ macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i",
+ reg, reg, (int) BFD_RELOC_LO16);
+ return;
+ }
+ }
+
+ /* Check for 16bit shifted constant. We know that hi32 is
+ non-zero, so start the mask on the first bit of the hi32
+ value. */
+ shift = 17;
+ do
+ {
+ unsigned long himask, lomask;
+
+ if (shift < 32)
+ {
+ himask = 0xffff >> (32 - shift);
+ lomask = (0xffff << shift) & 0xffffffff;
+ }
+ else
+ {
+ himask = 0xffff << (shift - 32);
+ lomask = 0;
+ }
+ if ((hi32.X_add_number & ~ (offsetT) himask) == 0
+ && (lo32.X_add_number & ~ (offsetT) lomask) == 0)
+ {
+ expressionS tmp;
+
+ tmp.X_op = O_constant;
+ if (shift < 32)
+ tmp.X_add_number = ((hi32.X_add_number << (32 - shift))
+ | (lo32.X_add_number >> shift));
+ else
+ tmp.X_add_number = hi32.X_add_number >> (shift - 32);
+ macro_build ((char *) NULL, counter, &tmp, "ori", "t,r,i", reg, 0,
+ (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, counter, NULL,
+ (shift >= 32) ? "dsll32" : "dsll",
+ "d,w,<", reg, reg,
+ (shift >= 32) ? shift - 32 : shift);
+ return;
+ }
+ shift++;
+ } while (shift <= (64 - 16));
+
+ /* Find the bit number of the lowest one bit, and store the
+ shifted value in hi/lo. */
+ hi = (unsigned long) (hi32.X_add_number & 0xffffffff);
+ lo = (unsigned long) (lo32.X_add_number & 0xffffffff);
+ if (lo != 0)
+ {
+ bit = 0;
+ while ((lo & 1) == 0)
+ {
+ lo >>= 1;
+ ++bit;
+ }
+ lo |= (hi & (((unsigned long) 1 << bit) - 1)) << (32 - bit);
+ hi >>= bit;
+ }
+ else
+ {
+ bit = 32;
+ while ((hi & 1) == 0)
+ {
+ hi >>= 1;
+ ++bit;
+ }
+ lo = hi;
+ hi = 0;
+ }
+
+ /* Optimize if the shifted value is a (power of 2) - 1. */
+ if ((hi == 0 && ((lo + 1) & lo) == 0)
+ || (lo == 0xffffffff && ((hi + 1) & hi) == 0))
+ {
+ shift = COUNT_TOP_ZEROES ((unsigned int) hi32.X_add_number);
+ if (shift != 0)
+ {
+ expressionS tmp;
+
+ /* This instruction will set the register to be all
+ ones. */
+ tmp.X_op = O_constant;
+ tmp.X_add_number = (offsetT) -1;
+ macro_build ((char *) NULL, counter, &tmp, "addiu", "t,r,j",
+ reg, 0, (int) BFD_RELOC_LO16);
+ if (bit != 0)
+ {
+ bit += shift;
+ macro_build ((char *) NULL, counter, NULL,
+ (bit >= 32) ? "dsll32" : "dsll",
+ "d,w,<", reg, reg,
+ (bit >= 32) ? bit - 32 : bit);
+ }
+ macro_build ((char *) NULL, counter, NULL,
+ (shift >= 32) ? "dsrl32" : "dsrl",
+ "d,w,<", reg, reg,
+ (shift >= 32) ? shift - 32 : shift);
+ return;
+ }
+ }
+
+ /* Sign extend hi32 before calling load_register, because we can
+ generally get better code when we load a sign extended value. */
+ if ((hi32.X_add_number & 0x80000000) != 0)
+ hi32.X_add_number |= ~ (offsetT) 0xffffffff;
+ load_register (counter, reg, &hi32, 0);
+ freg = reg;
+ }
+ if ((lo32.X_add_number & 0xffff0000) == 0)
+ {
+ if (freg != 0)
+ {
+ macro_build ((char *) NULL, counter, NULL, "dsll32", "d,w,<", reg,
+ freg, 0);
+ freg = reg;
+ }
+ }
+ else
+ {
+ expressionS mid16;
+
+ if ((freg == 0) && (lo32.X_add_number == 0xffffffff))
+ {
+ macro_build ((char *) NULL, counter, &lo32, "lui", "t,u", reg,
+ (int) BFD_RELOC_HI16);
+ macro_build ((char *) NULL, counter, NULL, "dsrl32", "d,w,<", reg,
+ reg, 0);
+ return;
+ }
+
+ if (freg != 0)
+ {
+ macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,
+ freg, 16);
+ freg = reg;
+ }
+ mid16 = lo32;
+ mid16.X_add_number >>= 16;
+ macro_build ((char *) NULL, counter, &mid16, "ori", "t,r,i", reg,
+ freg, (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,
+ reg, 16);
+ freg = reg;
+ }
+ if ((lo32.X_add_number & 0xffff) != 0)
+ macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i", reg, freg,
+ (int) BFD_RELOC_LO16);
+}
+
+/* Load an address into a register. */
+
+static void
+load_address (counter, reg, ep)
+ int *counter;
+ int reg;
+ expressionS *ep;
+{
+ char *p;
+
+ if (ep->X_op != O_constant
+ && ep->X_op != O_symbol)
+ {
+ as_bad (_("expression too complex"));
+ ep->X_op = O_constant;
+ }
+
+ if (ep->X_op == O_constant)
+ {
+ load_register (counter, reg, ep, 0);
+ return;
+ }
+
+ if (mips_pic == NO_PIC)
+ {
+ /* If this is a reference to a GP relative symbol, we want
+ addiu $reg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
+ Otherwise we want
+ lui $reg,<sym> (BFD_RELOC_HI16_S)
+ addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
+ If we have an addend, we always use the latter form. */
+ if ((valueT) ep->X_add_number >= MAX_GPREL_OFFSET
+ || nopic_need_relax (ep->X_add_symbol, 1))
+ p = NULL;
+ else
+ {
+ frag_grow (20);
+ macro_build ((char *) NULL, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
+ p = frag_var (rs_machine_dependent, 8, 0,
+ RELAX_ENCODE (4, 8, 0, 4, 0,
+ mips_opts.warn_about_macros),
+ ep->X_add_symbol, (offsetT) 0, (char *) NULL);
+ }
+ macro_build_lui (p, counter, ep, reg);
+ if (p != NULL)
+ p += 4;
+ macro_build (p, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ expressionS ex;
+
+ /* If this is a reference to an external symbol, we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ Otherwise we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
+ If there is a constant, it must be added in after. */
+ ex.X_add_number = ep->X_add_number;
+ ep->X_add_number = 0;
+ frag_grow (20);
+ macro_build ((char *) NULL, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");
+ p = frag_var (rs_machine_dependent, 4, 0,
+ RELAX_ENCODE (0, 4, -8, 0, 0, mips_opts.warn_about_macros),
+ ep->X_add_symbol, (offsetT) 0, (char *) NULL);
+ macro_build (p, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
+ if (ex.X_add_number != 0)
+ {
+ if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ ex.X_op = O_constant;
+ macro_build ((char *) NULL, counter, &ex,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
+ }
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ expressionS ex;
+ int off;
+
+ /* This is the large GOT case. If this is a reference to an
+ external symbol, we want
+ lui $reg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $reg,$reg,$gp
+ lw $reg,<sym>($reg) (BFD_RELOC_MIPS_GOT_LO16)
+ Otherwise, for a reference to a local symbol, we want
+ lw $reg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
+ If there is a constant, it must be added in after. */
+ ex.X_add_number = ep->X_add_number;
+ ep->X_add_number = 0;
+ if (reg_needs_delay (GP))
+ off = 4;
+ else
+ off = 0;
+ frag_grow (32);
+ macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
+ (int) BFD_RELOC_MIPS_GOT_HI16);
+ macro_build ((char *) NULL, counter, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", reg, reg, GP);
+ macro_build ((char *) NULL, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT_LO16, reg);
+ p = frag_var (rs_machine_dependent, 12 + off, 0,
+ RELAX_ENCODE (12, 12 + off, off, 8 + off, 0,
+ mips_opts.warn_about_macros),
+ ep->X_add_symbol, (offsetT) 0, (char *) NULL);
+ if (off > 0)
+ {
+ /* We need a nop before loading from $gp. This special
+ check is required because the lui which starts the main
+ instruction stream does not refer to $gp, and so will not
+ insert the nop which may be required. */
+ macro_build (p, counter, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ p += 4;
+ macro_build (p, counter, (expressionS *) NULL, "nop", "");
+ p += 4;
+ macro_build (p, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
+ if (ex.X_add_number != 0)
+ {
+ if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ ex.X_op = O_constant;
+ macro_build ((char *) NULL, counter, &ex,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
+ }
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* We always do
+ addiu $reg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
+ */
+ macro_build ((char *) NULL, counter, ep,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
+ }
+ else
+ abort ();
+}
+
+/*
+ * Build macros
+ * This routine implements the seemingly endless macro or synthesized
+ * instructions and addressing modes in the mips assembly language. Many
+ * of these macros are simple and are similar to each other. These could
+ * probably be handled by some kind of table or grammer aproach instead of
+ * this verbose method. Others are not simple macros but are more like
+ * optimizing code generation.
+ * One interesting optimization is when several store macros appear
+ * consecutivly that would load AT with the upper half of the same address.
+ * The ensuing load upper instructions are ommited. This implies some kind
+ * of global optimization. We currently only optimize within a single macro.
+ * For many of the load and store macros if the address is specified as a
+ * constant expression in the first 64k of memory (ie ld $2,0x4000c) we
+ * first load register 'at' with zero and use it as the base register. The
+ * mips assembler simply uses register $zero. Just one tiny optimization
+ * we're missing.
+ */
+static void
+macro (ip)
+ struct mips_cl_insn *ip;
+{
+ register int treg, sreg, dreg, breg;
+ int tempreg;
+ int mask;
+ int icnt = 0;
+ int used_at;
+ expressionS expr1;
+ const char *s;
+ const char *s2;
+ const char *fmt;
+ int likely = 0;
+ int dbl = 0;
+ int coproc = 0;
+ int lr = 0;
+ int imm = 0;
+ offsetT maxnum;
+ int off;
+ bfd_reloc_code_real_type r;
+ char *p;
+ int hold_mips_optimize;
+
+ assert (! mips_opts.mips16);
+
+ treg = (ip->insn_opcode >> 16) & 0x1f;
+ dreg = (ip->insn_opcode >> 11) & 0x1f;
+ sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
+ mask = ip->insn_mo->mask;
+
+ expr1.X_op = O_constant;
+ expr1.X_op_symbol = NULL;
+ expr1.X_add_symbol = NULL;
+ expr1.X_add_number = 1;
+
+ switch (mask)
+ {
+ case M_DABS:
+ dbl = 1;
+ case M_ABS:
+ /* bgez $a0,.+12
+ move v0,$a0
+ sub v0,$zero,$a0
+ */
+
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+
+ expr1.X_add_number = 8;
+ macro_build ((char *) NULL, &icnt, &expr1, "bgez", "s,p", sreg);
+ if (dreg == sreg)
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
+ else
+ macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, sreg, 0);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dsub" : "sub",
+ "d,v,t", dreg, 0, sreg);
+
+ --mips_opts.noreorder;
+ return;
+
+ case M_ADD_I:
+ s = "addi";
+ s2 = "add";
+ goto do_addi;
+ case M_ADDU_I:
+ s = "addiu";
+ s2 = "addu";
+ goto do_addi;
+ case M_DADD_I:
+ dbl = 1;
+ s = "daddi";
+ s2 = "dadd";
+ goto do_addi;
+ case M_DADDU_I:
+ dbl = 1;
+ s = "daddiu";
+ s2 = "daddu";
+ do_addi:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,j", treg, sreg,
+ (int) BFD_RELOC_LO16);
+ return;
+ }
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL, s2, "d,v,t", treg, sreg, AT);
+ break;
+
+ case M_AND_I:
+ s = "andi";
+ s2 = "and";
+ goto do_bit;
+ case M_OR_I:
+ s = "ori";
+ s2 = "or";
+ goto do_bit;
+ case M_NOR_I:
+ s = "";
+ s2 = "nor";
+ goto do_bit;
+ case M_XOR_I:
+ s = "xori";
+ s2 = "xor";
+ do_bit:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
+ {
+ if (mask != M_NOR_I)
+ macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,i", treg,
+ sreg, (int) BFD_RELOC_LO16);
+ else
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr, "ori", "t,r,i",
+ treg, sreg, (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, &icnt, NULL, "nor", "d,v,t",
+ treg, treg, 0);
+ }
+ return;
+ }
+
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, s2, "d,v,t", treg, sreg, AT);
+ break;
+
+ case M_BEQ_I:
+ s = "beq";
+ goto beq_i;
+ case M_BEQL_I:
+ s = "beql";
+ likely = 1;
+ goto beq_i;
+ case M_BNE_I:
+ s = "bne";
+ goto beq_i;
+ case M_BNEL_I:
+ s = "bnel";
+ likely = 1;
+ beq_i:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg,
+ 0);
+ return;
+ }
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg, AT);
+ break;
+
+ case M_BGEL:
+ likely = 1;
+ case M_BGE:
+ if (treg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bgezl" : "bgez",
+ "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "blezl" : "blez",
+ "s,p", treg);
+ return;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BGTL_I:
+ likely = 1;
+ case M_BGT_I:
+ /* check for > max integer */
+ maxnum = 0x7fffffff;
+ if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
+ {
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= maxnum
+ && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
+ {
+ do_false:
+ /* result is always false */
+ if (! likely)
+ {
+ as_warn (_("Branch %s is always false (nop)"), ip->insn_mo->name);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
+ }
+ else
+ {
+ as_warn (_("Branch likely %s is always false"), ip->insn_mo->name);
+ macro_build ((char *) NULL, &icnt, &offset_expr, "bnel",
+ "s,t,p", 0, 0);
+ }
+ return;
+ }
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number++;
+ /* FALLTHROUGH */
+ case M_BGE_I:
+ case M_BGEL_I:
+ if (mask == M_BGEL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bgezl" : "bgez",
+ "s,p", sreg);
+ return;
+ }
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bgtzl" : "bgtz",
+ "s,p", sreg);
+ return;
+ }
+ maxnum = 0x7fffffff;
+ if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
+ {
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ }
+ maxnum = - maxnum - 1;
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number <= maxnum
+ && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
+ {
+ do_true:
+ /* result is always true */
+ as_warn (_("Branch %s is always true"), ip->insn_mo->name);
+ macro_build ((char *) NULL, &icnt, &offset_expr, "b", "p");
+ return;
+ }
+ set_at (&icnt, sreg, 0);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BGEUL:
+ likely = 1;
+ case M_BGEU:
+ if (treg == 0)
+ goto do_true;
+ if (sreg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", 0, treg);
+ return;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,
+ treg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BGTUL_I:
+ likely = 1;
+ case M_BGTU_I:
+ if (sreg == 0
+ || (mips_opts.isa < 3
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == 0xffffffff))
+ goto do_false;
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number++;
+ /* FALLTHROUGH */
+ case M_BGEU_I:
+ case M_BGEUL_I:
+ if (mask == M_BGEUL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ goto do_true;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ set_at (&icnt, sreg, 1);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BGTL:
+ likely = 1;
+ case M_BGT:
+ if (treg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bgtzl" : "bgtz",
+ "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bltzl" : "bltz",
+ "s,p", treg);
+ return;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BGTUL:
+ likely = 1;
+ case M_BGTU:
+ if (treg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ if (sreg == 0)
+ goto do_false;
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,
+ sreg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BLEL:
+ likely = 1;
+ case M_BLE:
+ if (treg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "blezl" : "blez",
+ "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bgezl" : "bgez",
+ "s,p", treg);
+ return;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BLEL_I:
+ likely = 1;
+ case M_BLE_I:
+ maxnum = 0x7fffffff;
+ if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
+ {
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ maxnum <<= 16;
+ maxnum |= 0xffff;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= maxnum
+ && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
+ goto do_true;
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number++;
+ /* FALLTHROUGH */
+ case M_BLT_I:
+ case M_BLTL_I:
+ if (mask == M_BLTL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bltzl" : "bltz",
+ "s,p", sreg);
+ return;
+ }
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "blezl" : "blez",
+ "s,p", sreg);
+ return;
+ }
+ set_at (&icnt, sreg, 0);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BLEUL:
+ likely = 1;
+ case M_BLEU:
+ if (treg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ if (sreg == 0)
+ goto do_true;
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,
+ sreg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BLEUL_I:
+ likely = 1;
+ case M_BLEU_I:
+ if (sreg == 0
+ || (mips_opts.isa < 3
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == 0xffffffff))
+ goto do_true;
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number++;
+ /* FALLTHROUGH */
+ case M_BLTU_I:
+ case M_BLTUL_I:
+ if (mask == M_BLTUL_I)
+ likely = 1;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ goto do_false;
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "beql" : "beq",
+ "s,t,p", sreg, 0);
+ return;
+ }
+ set_at (&icnt, sreg, 1);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BLTL:
+ likely = 1;
+ case M_BLT:
+ if (treg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bltzl" : "bltz",
+ "s,p", sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bgtzl" : "bgtz",
+ "s,p", treg);
+ return;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_BLTUL:
+ likely = 1;
+ case M_BLTU:
+ if (treg == 0)
+ goto do_false;
+ if (sreg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", 0, treg);
+ return;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,
+ treg);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ likely ? "bnel" : "bne",
+ "s,t,p", AT, 0);
+ break;
+
+ case M_DDIV_3:
+ dbl = 1;
+ case M_DIV_3:
+ s = "mflo";
+ goto do_div3;
+ case M_DREM_3:
+ dbl = 1;
+ case M_REM_3:
+ s = "mfhi";
+ do_div3:
+ if (treg == 0)
+ {
+ as_warn (_("Divide by zero."));
+ if (mips_trap)
+ macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);
+ else
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
+ return;
+ }
+
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (mips_trap)
+ {
+ macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", treg, 0);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "ddiv" : "div",
+ "z,s,t", sreg, treg);
+ }
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "ddiv" : "div",
+ "z,s,t", sreg, treg);
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
+ }
+ expr1.X_add_number = -1;
+ macro_build ((char *) NULL, &icnt, &expr1,
+ dbl ? "daddiu" : "addiu",
+ "t,r,j", AT, 0, (int) BFD_RELOC_LO16);
+ expr1.X_add_number = mips_trap ? (dbl ? 12 : 8) : (dbl ? 20 : 16);
+ macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, AT);
+ if (dbl)
+ {
+ expr1.X_add_number = 1;
+ macro_build ((char *) NULL, &icnt, &expr1, "daddiu", "t,r,j", AT, 0,
+ (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, &icnt, NULL, "dsll32", "d,w,<", AT, AT,
+ 31);
+ }
+ else
+ {
+ expr1.X_add_number = 0x80000000;
+ macro_build ((char *) NULL, &icnt, &expr1, "lui", "t,u", AT,
+ (int) BFD_RELOC_HI16);
+ }
+ if (mips_trap)
+ {
+ macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", sreg, AT);
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+ }
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", sreg, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
+
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
+ }
+ macro_build ((char *) NULL, &icnt, NULL, s, "d", dreg);
+ break;
+
+ case M_DIV_3I:
+ s = "div";
+ s2 = "mflo";
+ goto do_divi;
+ case M_DIVU_3I:
+ s = "divu";
+ s2 = "mflo";
+ goto do_divi;
+ case M_REM_3I:
+ s = "div";
+ s2 = "mfhi";
+ goto do_divi;
+ case M_REMU_3I:
+ s = "divu";
+ s2 = "mfhi";
+ goto do_divi;
+ case M_DDIV_3I:
+ dbl = 1;
+ s = "ddiv";
+ s2 = "mflo";
+ goto do_divi;
+ case M_DDIVU_3I:
+ dbl = 1;
+ s = "ddivu";
+ s2 = "mflo";
+ goto do_divi;
+ case M_DREM_3I:
+ dbl = 1;
+ s = "ddiv";
+ s2 = "mfhi";
+ goto do_divi;
+ case M_DREMU_3I:
+ dbl = 1;
+ s = "ddivu";
+ s2 = "mfhi";
+ do_divi:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ as_warn (_("Divide by zero."));
+ if (mips_trap)
+ macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);
+ else
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
+ return;
+ }
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ {
+ if (strcmp (s2, "mflo") == 0)
+ macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg,
+ sreg);
+ else
+ macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
+ return;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == -1
+ && s[strlen (s) - 1] != 'u')
+ {
+ if (strcmp (s2, "mflo") == 0)
+ {
+ if (dbl)
+ macro_build ((char *) NULL, &icnt, NULL, "dneg", "d,w", dreg,
+ sreg);
+ else
+ macro_build ((char *) NULL, &icnt, NULL, "neg", "d,w", dreg,
+ sreg);
+ }
+ else
+ macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
+ return;
+ }
+
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, AT);
+ macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);
+ break;
+
+ case M_DIVU_3:
+ s = "divu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_REMU_3:
+ s = "divu";
+ s2 = "mfhi";
+ goto do_divu3;
+ case M_DDIVU_3:
+ s = "ddivu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_DREMU_3:
+ s = "ddivu";
+ s2 = "mfhi";
+ do_divu3:
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (mips_trap)
+ {
+ macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", treg, 0);
+ macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+ }
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);
+ macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);
+
+ /* We want to close the noreorder block as soon as possible, so
+ that later insns are available for delay slot filling. */
+ --mips_opts.noreorder;
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
+ }
+ macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);
+ return;
+
+ case M_DLA_AB:
+ dbl = 1;
+ case M_LA_AB:
+ /* Load the address of a symbol into a register. If breg is not
+ zero, we then add a base register to it. */
+
+ /* When generating embedded PIC code, we permit expressions of
+ the form
+ la $4,foo-bar
+ where bar is an address in the .text section. These are used
+ when getting the addresses of functions. We don't permit
+ X_add_number to be non-zero, because if the symbol is
+ external the relaxing code needs to know that any addend is
+ purely the offset to X_op_symbol. */
+ if (mips_pic == EMBEDDED_PIC
+ && offset_expr.X_op == O_subtract
+ && now_seg == text_section
+ && (offset_expr.X_op_symbol->sy_value.X_op == O_constant
+ ? S_GET_SEGMENT (offset_expr.X_op_symbol) == text_section
+ : (offset_expr.X_op_symbol->sy_value.X_op == O_symbol
+ && (S_GET_SEGMENT (offset_expr.X_op_symbol
+ ->sy_value.X_add_symbol)
+ == text_section)))
+ && breg == 0
+ && offset_expr.X_add_number == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
+ treg, (int) BFD_RELOC_PCREL_HI16_S);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", treg, treg, (int) BFD_RELOC_PCREL_LO16);
+ return;
+ }
+
+ if (offset_expr.X_op != O_symbol
+ && offset_expr.X_op != O_constant)
+ {
+ as_bad (_("expression too complex"));
+ offset_expr.X_op = O_constant;
+ }
+
+ if (treg == breg)
+ {
+ tempreg = AT;
+ used_at = 1;
+ }
+ else
+ {
+ tempreg = treg;
+ used_at = 0;
+ }
+
+ if (offset_expr.X_op == O_constant)
+ load_register (&icnt, tempreg, &offset_expr, dbl);
+ else if (mips_pic == NO_PIC)
+ {
+ /* If this is a reference to an GP relative symbol, we want
+ addiu $tempreg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
+ Otherwise we want
+ lui $tempreg,<sym> (BFD_RELOC_HI16_S)
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+ If we have a constant, we need two instructions anyhow,
+ so we may as well always use the latter form. */
+ if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ || nopic_need_relax (offset_expr.X_add_symbol, 1))
+ p = NULL;
+ else
+ {
+ frag_grow (20);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
+ p = frag_var (rs_machine_dependent, 8, 0,
+ RELAX_ENCODE (4, 8, 0, 4, 0,
+ mips_opts.warn_about_macros),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ macro_build_lui (p, &icnt, &offset_expr, tempreg);
+ if (p != NULL)
+ p += 4;
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ /* If this is a reference to an external symbol, and there
+ is no constant, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+
+ If we have a small constant, and this is a reference to
+ an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<constant>
+ For a local symbol, we want the same instruction
+ sequence, but we output a BFD_RELOC_LO16 reloc on the
+ addiu instruction.
+
+ If we have a large constant, and this is a reference to
+ an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant>
+ addu $tempreg,$tempreg,$at
+ For a local symbol, we want the same instruction
+ sequence, but we output a BFD_RELOC_LO16 reloc on the
+ addiu instruction. */
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ frag_grow (32);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ dbl ? "ld" : "lw",
+ "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ if (expr1.X_add_number == 0)
+ {
+ int off;
+
+ if (breg == 0)
+ off = 0;
+ else
+ {
+ /* We're going to put in an addu instruction using
+ tempreg, so we may as well insert the nop right
+ now. */
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ off = 4;
+ }
+ p = frag_var (rs_machine_dependent, 8 - off, 0,
+ RELAX_ENCODE (0, 8 - off, -4 - off, 4 - off, 0,
+ (breg == 0
+ ? mips_opts.warn_about_macros
+ : 0)),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ if (breg == 0)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+ /* FIXME: If breg == 0, and the next instruction uses
+ $tempreg, then if this variant case is used an extra
+ nop will be generated. */
+ }
+ else if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+ (void) frag_var (rs_machine_dependent, 0, 0,
+ RELAX_ENCODE (0, 0, -12, -4, 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ else
+ {
+ int off1;
+
+ /* If we are going to add in a base register, and the
+ target register and the base register are the same,
+ then we are using AT as a temporary register. Since
+ we want to load the constant into AT, we add our
+ current AT (from the global offset table) and the
+ register into the register now, and pretend we were
+ not using a base register. */
+ if (breg != treg)
+ off1 = 0;
+ else
+ {
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", treg, AT, breg);
+ breg = 0;
+ tempreg = treg;
+ off1 = -8;
+ }
+
+ /* Set mips_optimize around the lui instruction to avoid
+ inserting an unnecessary nop after the lw. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ macro_build_lui ((char *) NULL, &icnt, &expr1, AT);
+ mips_optimize = hold_mips_optimize;
+
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", AT, AT, (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, AT);
+ (void) frag_var (rs_machine_dependent, 0, 0,
+ RELAX_ENCODE (0, 0, -16 + off1, -8, 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ used_at = 1;
+ }
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ int gpdel;
+
+ /* This is the large GOT case. If this is a reference to an
+ external symbol, and there is no constant, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+
+ If we have a small constant, and this is a reference to
+ an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ nop
+ addiu $tempreg,$tempreg,<constant>
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<constant> (BFD_RELOC_LO16)
+
+ If we have a large constant, and this is a reference to
+ an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant>
+ addu $tempreg,$tempreg,$at
+ For a local symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ lui $at,<hiconstant>
+ addiu $at,$at,<loconstant> (BFD_RELOC_LO16)
+ addu $tempreg,$tempreg,$at
+ */
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ frag_grow (52);
+ if (reg_needs_delay (GP))
+ gpdel = 4;
+ else
+ gpdel = 0;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
+ tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, GP);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ dbl ? "ld" : "lw",
+ "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
+ tempreg);
+ if (expr1.X_add_number == 0)
+ {
+ int off;
+
+ if (breg == 0)
+ off = 0;
+ else
+ {
+ /* We're going to put in an addu instruction using
+ tempreg, so we may as well insert the nop right
+ now. */
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ off = 4;
+ }
+
+ p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
+ RELAX_ENCODE (12 + off, 12 + gpdel, gpdel,
+ 8 + gpdel, 0,
+ (breg == 0
+ ? mips_opts.warn_about_macros
+ : 0)),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ else if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+
+ p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
+ RELAX_ENCODE (20, 12 + gpdel, gpdel, 8 + gpdel, 0,
+ (breg == 0
+ ? mips_opts.warn_about_macros
+ : 0)),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ else
+ {
+ int adj, dreg;
+
+ /* If we are going to add in a base register, and the
+ target register and the base register are the same,
+ then we are using AT as a temporary register. Since
+ we want to load the constant into AT, we add our
+ current AT (from the global offset table) and the
+ register into the register now, and pretend we were
+ not using a base register. */
+ if (breg != treg)
+ {
+ adj = 0;
+ dreg = tempreg;
+ }
+ else
+ {
+ assert (tempreg == AT);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", treg, AT, breg);
+ dreg = treg;
+ adj = 8;
+ }
+
+ /* Set mips_optimize around the lui instruction to avoid
+ inserting an unnecessary nop after the lw. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ macro_build_lui ((char *) NULL, &icnt, &expr1, AT);
+ mips_optimize = hold_mips_optimize;
+
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", AT, AT, (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", dreg, dreg, AT);
+
+ p = frag_var (rs_machine_dependent, 16 + gpdel + adj, 0,
+ RELAX_ENCODE (24 + adj, 16 + gpdel + adj, gpdel,
+ 8 + gpdel, 0,
+ (breg == 0
+ ? mips_opts.warn_about_macros
+ : 0)),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+
+ used_at = 1;
+ }
+
+ if (gpdel > 0)
+ {
+ /* This is needed because this instruction uses $gp, but
+ the first instruction on the main stream does not. */
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, &icnt, &offset_expr,
+ dbl ? "ld" : "lw",
+ "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ p += 4;
+ if (expr1.X_add_number >= -0x8000
+ && expr1.X_add_number < 0x8000)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ macro_build (p, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+ /* FIXME: If add_number is 0, and there was no base
+ register, the external symbol case ended with a load,
+ so if the symbol turns out to not be external, and
+ the next instruction uses tempreg, an unnecessary nop
+ will be inserted. */
+ }
+ else
+ {
+ if (breg == treg)
+ {
+ /* We must add in the base register now, as in the
+ external symbol case. */
+ assert (tempreg == AT);
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ macro_build (p, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", treg, AT, breg);
+ p += 4;
+ tempreg = treg;
+ /* We set breg to 0 because we have arranged to add
+ it in in both cases. */
+ breg = 0;
+ }
+
+ macro_build_lui (p, &icnt, &expr1, AT);
+ p += 4;
+ macro_build (p, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", AT, AT, (int) BFD_RELOC_LO16);
+ p += 4;
+ macro_build (p, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, AT);
+ p += 4;
+ }
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* We use
+ addiu $tempreg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
+ */
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
+ }
+ else
+ abort ();
+
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", treg, tempreg, breg);
+
+ if (! used_at)
+ return;
+
+ break;
+
+ case M_J_A:
+ /* The j instruction may not be used in PIC code, since it
+ requires an absolute address. We convert it to a b
+ instruction. */
+ if (mips_pic == NO_PIC)
+ macro_build ((char *) NULL, &icnt, &offset_expr, "j", "a");
+ else
+ macro_build ((char *) NULL, &icnt, &offset_expr, "b", "p");
+ return;
+
+ /* The jal instructions must be handled as macros because when
+ generating PIC code they expand to multi-instruction
+ sequences. Normally they are simple instructions. */
+ case M_JAL_1:
+ dreg = RA;
+ /* Fall through. */
+ case M_JAL_2:
+ if (mips_pic == NO_PIC
+ || mips_pic == EMBEDDED_PIC)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr",
+ "d,s", dreg, sreg);
+ else if (mips_pic == SVR4_PIC)
+ {
+ if (sreg != PIC_CALL_REG)
+ as_warn (_("MIPS PIC call to register other than $25"));
+
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr",
+ "d,s", dreg, sreg);
+ if (mips_cprestore_offset < 0)
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ else
+ {
+ expr1.X_add_number = mips_cprestore_offset;
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);
+ }
+ }
+ else
+ abort ();
+
+ return;
+
+ case M_JAL_A:
+ if (mips_pic == NO_PIC)
+ macro_build ((char *) NULL, &icnt, &offset_expr, "jal", "a");
+ else if (mips_pic == SVR4_PIC)
+ {
+ /* If this is a reference to an external symbol, and we are
+ using a small GOT, we want
+ lw $25,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
+ nop
+ jalr $25
+ nop
+ lw $gp,cprestore($sp)
+ The cprestore value is set using the .cprestore
+ pseudo-op. If we are using a big GOT, we want
+ lui $25,<sym> (BFD_RELOC_MIPS_CALL_HI16)
+ addu $25,$25,$gp
+ lw $25,<sym>($25) (BFD_RELOC_MIPS_CALL_LO16)
+ nop
+ jalr $25
+ nop
+ lw $gp,cprestore($sp)
+ If the symbol is not external, we want
+ lw $25,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $25,$25,<sym> (BFD_RELOC_LO16)
+ jalr $25
+ nop
+ lw $gp,cprestore($sp) */
+ frag_grow (40);
+ if (! mips_big_got)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", PIC_CALL_REG,
+ (int) BFD_RELOC_MIPS_CALL16, GP);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ p = frag_var (rs_machine_dependent, 4, 0,
+ RELAX_ENCODE (0, 4, -8, 0, 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ else
+ {
+ int gpdel;
+
+ if (reg_needs_delay (GP))
+ gpdel = 4;
+ else
+ gpdel = 0;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
+ PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL_HI16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", PIC_CALL_REG, PIC_CALL_REG, GP);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", PIC_CALL_REG,
+ (int) BFD_RELOC_MIPS_CALL_LO16, PIC_CALL_REG);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
+ RELAX_ENCODE (16, 12 + gpdel, gpdel, 8 + gpdel,
+ 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ if (gpdel > 0)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", PIC_CALL_REG,
+ (int) BFD_RELOC_MIPS_GOT16, GP);
+ p += 4;
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", PIC_CALL_REG, PIC_CALL_REG,
+ (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "jalr", "s", PIC_CALL_REG);
+ if (mips_cprestore_offset < 0)
+ as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ else
+ {
+ if (mips_opts.noreorder)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "nop", "");
+ expr1.X_add_number = mips_cprestore_offset;
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", GP, (int) BFD_RELOC_LO16,
+ mips_frame_reg);
+ }
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, "bal", "p");
+ /* The linker may expand the call to a longer sequence which
+ uses $at, so we must break rather than return. */
+ break;
+ }
+ else
+ abort ();
+
+ return;
+
+ case M_LB_AB:
+ s = "lb";
+ goto ld;
+ case M_LBU_AB:
+ s = "lbu";
+ goto ld;
+ case M_LH_AB:
+ s = "lh";
+ goto ld;
+ case M_LHU_AB:
+ s = "lhu";
+ goto ld;
+ case M_LW_AB:
+ s = "lw";
+ goto ld;
+ case M_LWC0_AB:
+ s = "lwc0";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWC1_AB:
+ s = "lwc1";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWC2_AB:
+ s = "lwc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWC3_AB:
+ s = "lwc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LWL_AB:
+ s = "lwl";
+ lr = 1;
+ goto ld;
+ case M_LWR_AB:
+ s = "lwr";
+ lr = 1;
+ goto ld;
+ case M_LDC1_AB:
+ if (mips_cpu == 4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ s = "ldc1";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LDC2_AB:
+ s = "ldc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LDC3_AB:
+ s = "ldc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ld;
+ case M_LDL_AB:
+ s = "ldl";
+ lr = 1;
+ goto ld;
+ case M_LDR_AB:
+ s = "ldr";
+ lr = 1;
+ goto ld;
+ case M_LL_AB:
+ s = "ll";
+ goto ld;
+ case M_LLD_AB:
+ s = "lld";
+ goto ld;
+ case M_LWU_AB:
+ s = "lwu";
+ ld:
+ if (breg == treg || coproc || lr)
+ {
+ tempreg = AT;
+ used_at = 1;
+ }
+ else
+ {
+ tempreg = treg;
+ used_at = 0;
+ }
+ goto ld_st;
+ case M_SB_AB:
+ s = "sb";
+ goto st;
+ case M_SH_AB:
+ s = "sh";
+ goto st;
+ case M_SW_AB:
+ s = "sw";
+ goto st;
+ case M_SWC0_AB:
+ s = "swc0";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWC1_AB:
+ s = "swc1";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWC2_AB:
+ s = "swc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWC3_AB:
+ s = "swc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SWL_AB:
+ s = "swl";
+ goto st;
+ case M_SWR_AB:
+ s = "swr";
+ goto st;
+ case M_SC_AB:
+ s = "sc";
+ goto st;
+ case M_SCD_AB:
+ s = "scd";
+ goto st;
+ case M_SDC1_AB:
+ if (mips_cpu == 4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ s = "sdc1";
+ coproc = 1;
+ /* Itbl support may require additional care here. */
+ goto st;
+ case M_SDC2_AB:
+ s = "sdc2";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SDC3_AB:
+ s = "sdc3";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto st;
+ case M_SDL_AB:
+ s = "sdl";
+ goto st;
+ case M_SDR_AB:
+ s = "sdr";
+ st:
+ tempreg = AT;
+ used_at = 1;
+ ld_st:
+ /* Itbl support may require additional care here. */
+ if (mask == M_LWC1_AB
+ || mask == M_SWC1_AB
+ || mask == M_LDC1_AB
+ || mask == M_SDC1_AB
+ || mask == M_L_DAB
+ || mask == M_S_DAB)
+ fmt = "T,o(b)";
+ else if (coproc)
+ fmt = "E,o(b)";
+ else
+ fmt = "t,o(b)";
+
+ if (offset_expr.X_op != O_constant
+ && offset_expr.X_op != O_symbol)
+ {
+ as_bad (_("expression too complex"));
+ offset_expr.X_op = O_constant;
+ }
+
+ /* A constant expression in PIC code can be handled just as it
+ is in non PIC code. */
+ if (mips_pic == NO_PIC
+ || offset_expr.X_op == O_constant)
+ {
+ /* If this is a reference to a GP relative symbol, and there
+ is no base register, we want
+ <op> $treg,<sym>($gp) (BFD_RELOC_MIPS_GPREL)
+ Otherwise, if there is no base register, we want
+ lui $tempreg,<sym> (BFD_RELOC_HI16_S)
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+ If we have a constant, we need two instructions anyhow,
+ so we always use the latter form.
+
+ If we have a base register, and this is a reference to a
+ GP relative symbol, we want
+ addu $tempreg,$breg,$gp
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_MIPS_GPREL)
+ Otherwise we want
+ lui $tempreg,<sym> (BFD_RELOC_HI16_S)
+ addu $tempreg,$tempreg,$breg
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_LO16)
+ With a constant we always use the latter case. */
+ if (breg == 0)
+ {
+ if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ || nopic_need_relax (offset_expr.X_add_symbol, 1))
+ p = NULL;
+ else
+ {
+ frag_grow (20);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ treg, (int) BFD_RELOC_MIPS_GPREL, GP);
+ p = frag_var (rs_machine_dependent, 8, 0,
+ RELAX_ENCODE (4, 8, 0, 4, 0,
+ (mips_opts.warn_about_macros
+ || (used_at
+ && mips_opts.noat))),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ used_at = 0;
+ }
+ macro_build_lui (p, &icnt, &offset_expr, tempreg);
+ if (p != NULL)
+ p += 4;
+ macro_build (p, &icnt, &offset_expr, s, fmt, treg,
+ (int) BFD_RELOC_LO16, tempreg);
+ }
+ else
+ {
+ if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ || nopic_need_relax (offset_expr.X_add_symbol, 1))
+ p = NULL;
+ else
+ {
+ frag_grow (28);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, breg, GP);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
+ p = frag_var (rs_machine_dependent, 12, 0,
+ RELAX_ENCODE (8, 12, 0, 8, 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ macro_build_lui (p, &icnt, &offset_expr, tempreg);
+ if (p != NULL)
+ p += 4;
+ macro_build (p, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, breg);
+ if (p != NULL)
+ p += 4;
+ macro_build (p, &icnt, &offset_expr, s, fmt, treg,
+ (int) BFD_RELOC_LO16, tempreg);
+ }
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ /* If this is a reference to an external symbol, we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,0($tempreg)
+ Otherwise we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+ <op> $treg,0($tempreg)
+ If there is a base register, we add it to $tempreg before
+ the <op>. If there is a constant, we stick it in the
+ <op> instruction. We don't handle constants larger than
+ 16 bits, because we have no way to load the upper 16 bits
+ (actually, we could handle them for the subset of cases
+ in which we are not using $at). */
+ assert (offset_expr.X_op == O_symbol);
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ frag_grow (20);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
+ p = frag_var (rs_machine_dependent, 4, 0,
+ RELAX_ENCODE (0, 4, -8, 0, 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, breg);
+ macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
+ (int) BFD_RELOC_LO16, tempreg);
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ int gpdel;
+
+ /* If this is a reference to an external symbol, we want
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ <op> $treg,0($tempreg)
+ Otherwise we want
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
+ <op> $treg,0($tempreg)
+ If there is a base register, we add it to $tempreg before
+ the <op>. If there is a constant, we stick it in the
+ <op> instruction. We don't handle constants larger than
+ 16 bits, because we have no way to load the upper 16 bits
+ (actually, we could handle them for the subset of cases
+ in which we are not using $at). */
+ assert (offset_expr.X_op == O_symbol);
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ if (reg_needs_delay (GP))
+ gpdel = 4;
+ else
+ gpdel = 0;
+ frag_grow (36);
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
+ tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, GP);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
+ tempreg);
+ p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
+ RELAX_ENCODE (12, 12 + gpdel, gpdel, 8 + gpdel, 0, 0),
+ offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL);
+ if (gpdel > 0)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
+ p += 4;
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, tempreg, breg);
+ macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
+ (int) BFD_RELOC_LO16, tempreg);
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* If there is no base register, we want
+ <op> $treg,<sym>($gp) (BFD_RELOC_MIPS_GPREL)
+ If there is a base register, we want
+ addu $tempreg,$breg,$gp
+ <op> $treg,<sym>($tempreg) (BFD_RELOC_MIPS_GPREL)
+ */
+ assert (offset_expr.X_op == O_symbol);
+ if (breg == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ treg, (int) BFD_RELOC_MIPS_GPREL, GP);
+ used_at = 0;
+ }
+ else
+ {
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", tempreg, breg, GP);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
+ }
+ }
+ else
+ abort ();
+
+ if (! used_at)
+ return;
+
+ break;
+
+ case M_LI:
+ case M_LI_S:
+ load_register (&icnt, treg, &imm_expr, 0);
+ return;
+
+ case M_DLI:
+ load_register (&icnt, treg, &imm_expr, 1);
+ return;
+
+ case M_LI_SS:
+ if (imm_expr.X_op == O_constant)
+ {
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "mtc1", "t,G", AT, treg);
+ break;
+ }
+ else
+ {
+ assert (offset_expr.X_op == O_symbol
+ && strcmp (segment_name (S_GET_SEGMENT
+ (offset_expr.X_add_symbol)),
+ ".lit4") == 0
+ && offset_expr.X_add_number == 0);
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
+ treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
+ return;
+ }
+
+ case M_LI_D:
+ /* If we have a constant in IMM_EXPR, then in mips3 mode it is
+ the entire value, and in mips1 mode it is the high order 32
+ bits of the value and the low order 32 bits are either zero
+ or in offset_expr. */
+ if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
+ {
+ if (mips_opts.isa >= 3)
+ load_register (&icnt, treg, &imm_expr, 1);
+ else
+ {
+ int hreg, lreg;
+
+ if (target_big_endian)
+ {
+ hreg = treg;
+ lreg = treg + 1;
+ }
+ else
+ {
+ hreg = treg + 1;
+ lreg = treg;
+ }
+
+ if (hreg <= 31)
+ load_register (&icnt, hreg, &imm_expr, 0);
+ if (lreg <= 31)
+ {
+ if (offset_expr.X_op == O_absent)
+ macro_build ((char *) NULL, &icnt, NULL, "move", "d,s",
+ lreg, 0);
+ else
+ {
+ assert (offset_expr.X_op == O_constant);
+ load_register (&icnt, lreg, &offset_expr, 0);
+ }
+ }
+ }
+ return;
+ }
+
+ /* We know that sym is in the .rdata section. First we get the
+ upper 16 bits of the address. */
+ if (mips_pic == NO_PIC)
+ {
+ /* FIXME: This won't work for a 64 bit address. */
+ macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* For embedded PIC we pick up the entire address off $gp in
+ a single instruction. */
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", AT, GP, (int) BFD_RELOC_MIPS_GPREL);
+ offset_expr.X_op = O_constant;
+ offset_expr.X_add_number = 0;
+ }
+ else
+ abort ();
+
+ /* Now we load the register(s). */
+ if (mips_opts.isa >= 3)
+ macro_build ((char *) NULL, &icnt, &offset_expr, "ld", "t,o(b)",
+ treg, (int) BFD_RELOC_LO16, AT);
+ else
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lw", "t,o(b)",
+ treg, (int) BFD_RELOC_LO16, AT);
+ if (treg != 31)
+ {
+ /* FIXME: How in the world do we deal with the possible
+ overflow here? */
+ offset_expr.X_add_number += 4;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lw", "t,o(b)",
+ treg + 1, (int) BFD_RELOC_LO16, AT);
+ }
+ }
+
+ /* To avoid confusion in tc_gen_reloc, we must ensure that this
+ does not become a variant frag. */
+ frag_wane (frag_now);
+ frag_new (0);
+
+ break;
+
+ case M_LI_DD:
+ /* If we have a constant in IMM_EXPR, then in mips3 mode it is
+ the entire value, and in mips1 mode it is the high order 32
+ bits of the value and the low order 32 bits are either zero
+ or in offset_expr. */
+ if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
+ {
+ load_register (&icnt, AT, &imm_expr, mips_opts.isa >= 3);
+ if (mips_opts.isa >= 3)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "dmtc1", "t,S", AT, treg);
+ else
+ {
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "mtc1", "t,G", AT, treg + 1);
+ if (offset_expr.X_op == O_absent)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "mtc1", "t,G", 0, treg);
+ else
+ {
+ assert (offset_expr.X_op == O_constant);
+ load_register (&icnt, AT, &offset_expr, 0);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "mtc1", "t,G", AT, treg);
+ }
+ }
+ break;
+ }
+
+ assert (offset_expr.X_op == O_symbol
+ && offset_expr.X_add_number == 0);
+ s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
+ if (strcmp (s, ".lit8") == 0)
+ {
+ if (mips_opts.isa >= 2)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
+ "T,o(b)", treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
+ return;
+ }
+ breg = GP;
+ r = BFD_RELOC_MIPS_LITERAL;
+ goto dob;
+ }
+ else
+ {
+ assert (strcmp (s, RDATA_SECTION_NAME) == 0);
+ if (mips_pic == SVR4_PIC)
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
+ else
+ {
+ /* FIXME: This won't work for a 64 bit address. */
+ macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
+ }
+
+ if (mips_opts.isa >= 2)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
+ "T,o(b)", treg, (int) BFD_RELOC_LO16, AT);
+
+ /* To avoid confusion in tc_gen_reloc, we must ensure
+ that this does not become a variant frag. */
+ frag_wane (frag_now);
+ frag_new (0);
+
+ break;
+ }
+ breg = AT;
+ r = BFD_RELOC_LO16;
+ goto dob;
+ }
+
+ case M_L_DOB:
+ if (mips_cpu == 4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when loading from memory. */
+ r = BFD_RELOC_LO16;
+ dob:
+ assert (mips_opts.isa < 2);
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
+ target_big_endian ? treg + 1 : treg,
+ (int) r, breg);
+ /* FIXME: A possible overflow which I don't know how to deal
+ with. */
+ offset_expr.X_add_number += 4;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
+ target_big_endian ? treg : treg + 1,
+ (int) r, breg);
+
+ /* To avoid confusion in tc_gen_reloc, we must ensure that this
+ does not become a variant frag. */
+ frag_wane (frag_now);
+ frag_new (0);
+
+ if (breg != AT)
+ return;
+ break;
+
+ case M_L_DAB:
+ /*
+ * The MIPS assembler seems to check for X_add_number not
+ * being double aligned and generating:
+ * lui at,%hi(foo+1)
+ * addu at,at,v1
+ * addiu at,at,%lo(foo+1)
+ * lwc1 f2,0(at)
+ * lwc1 f3,4(at)
+ * But, the resulting address is the same after relocation so why
+ * generate the extra instruction?
+ */
+ if (mips_cpu == 4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ if (mips_opts.isa >= 2)
+ {
+ s = "ldc1";
+ goto ld;
+ }
+
+ s = "lwc1";
+ fmt = "T,o(b)";
+ goto ldd_std;
+
+ case M_S_DAB:
+ if (mips_cpu == 4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+
+ if (mips_opts.isa >= 2)
+ {
+ s = "sdc1";
+ goto st;
+ }
+
+ s = "swc1";
+ fmt = "T,o(b)";
+ /* Itbl support may require additional care here. */
+ coproc = 1;
+ goto ldd_std;
+
+ case M_LD_AB:
+ if (mips_opts.isa >= 3)
+ {
+ s = "ld";
+ goto ld;
+ }
+
+ s = "lw";
+ fmt = "t,o(b)";
+ goto ldd_std;
+
+ case M_SD_AB:
+ if (mips_opts.isa >= 3)
+ {
+ s = "sd";
+ goto st;
+ }
+
+ s = "sw";
+ fmt = "t,o(b)";
+
+ ldd_std:
+ if (offset_expr.X_op != O_symbol
+ && offset_expr.X_op != O_constant)
+ {
+ as_bad (_("expression too complex"));
+ offset_expr.X_op = O_constant;
+ }
+
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when loading from memory. We set coproc if we must
+ load $fn+1 first. */
+ /* Itbl support may require additional care here. */
+ if (! target_big_endian)
+ coproc = 0;
+
+ if (mips_pic == NO_PIC
+ || offset_expr.X_op == O_constant)
+ {
+ /* If this is a reference to a GP relative symbol, we want
+ <op> $treg,<sym>($gp) (BFD_RELOC_MIPS_GPREL)
+ <op> $treg+1,<sym>+4($gp) (BFD_RELOC_MIPS_GPREL)
+ If we have a base register, we use this
+ addu $at,$breg,$gp
+ <op> $treg,<sym>($at) (BFD_RELOC_MIPS_GPREL)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_MIPS_GPREL)
+ If this is not a GP relative symbol, we want
+ lui $at,<sym> (BFD_RELOC_HI16_S)
+ <op> $treg,<sym>($at) (BFD_RELOC_LO16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
+ If there is a base register, we add it to $at after the
+ lui instruction. If there is a constant, we always use
+ the last case. */
+ if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ || nopic_need_relax (offset_expr.X_add_symbol, 1))
+ {
+ p = NULL;
+ used_at = 1;
+ }
+ else
+ {
+ int off;
+
+ if (breg == 0)
+ {
+ frag_grow (28);
+ tempreg = GP;
+ off = 0;
+ used_at = 0;
+ }
+ else
+ {
+ frag_grow (36);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, breg, GP);
+ tempreg = AT;
+ off = 4;
+ used_at = 1;
+ }
+
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ coproc ? treg + 1 : treg,
+ (int) BFD_RELOC_MIPS_GPREL, tempreg);
+ offset_expr.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an
+ undesired nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ coproc ? treg : treg + 1,
+ (int) BFD_RELOC_MIPS_GPREL, tempreg);
+ mips_optimize = hold_mips_optimize;
+
+ p = frag_var (rs_machine_dependent, 12 + off, 0,
+ RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,
+ used_at && mips_opts.noat),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+
+ /* We just generated two relocs. When tc_gen_reloc
+ handles this case, it will skip the first reloc and
+ handle the second. The second reloc already has an
+ extra addend of 4, which we added above. We must
+ subtract it out, and then subtract another 4 to make
+ the first reloc come out right. The second reloc
+ will come out right because we are going to add 4 to
+ offset_expr when we build its instruction below.
+
+ If we have a symbol, then we don't want to include
+ the offset, because it will wind up being included
+ when we generate the reloc. */
+
+ if (offset_expr.X_op == O_constant)
+ offset_expr.X_add_number -= 8;
+ else
+ {
+ offset_expr.X_add_number = -4;
+ offset_expr.X_op = O_constant;
+ }
+ }
+ macro_build_lui (p, &icnt, &offset_expr, AT);
+ if (p != NULL)
+ p += 4;
+ if (breg != 0)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, breg, AT);
+ if (p != NULL)
+ p += 4;
+ }
+ /* Itbl support may require additional care here. */
+ macro_build (p, &icnt, &offset_expr, s, fmt,
+ coproc ? treg + 1 : treg,
+ (int) BFD_RELOC_LO16, AT);
+ if (p != NULL)
+ p += 4;
+ /* FIXME: How do we handle overflow here? */
+ offset_expr.X_add_number += 4;
+ /* Itbl support may require additional care here. */
+ macro_build (p, &icnt, &offset_expr, s, fmt,
+ coproc ? treg : treg + 1,
+ (int) BFD_RELOC_LO16, AT);
+ }
+ else if (mips_pic == SVR4_PIC && ! mips_big_got)
+ {
+ int off;
+
+ /* If this is a reference to an external symbol, we want
+ lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,0($at)
+ <op> $treg+1,4($at)
+ Otherwise we want
+ lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,<sym>($at) (BFD_RELOC_LO16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
+ If there is a base register we add it to $at before the
+ lwc1 instructions. If there is a constant we include it
+ in the lwc1 instructions. */
+ used_at = 1;
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000 - 4)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ if (breg == 0)
+ off = 0;
+ else
+ off = 4;
+ frag_grow (24 + off);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, breg, AT);
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
+ coproc ? treg + 1 : treg,
+ (int) BFD_RELOC_LO16, AT);
+ expr1.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an undesired
+ nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
+ coproc ? treg : treg + 1,
+ (int) BFD_RELOC_LO16, AT);
+ mips_optimize = hold_mips_optimize;
+
+ (void) frag_var (rs_machine_dependent, 0, 0,
+ RELAX_ENCODE (0, 0, -16 - off, -8, 1, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ int gpdel, off;
+
+ /* If this is a reference to an external symbol, we want
+ lui $at,<sym> (BFD_RELOC_MIPS_GOT_HI16)
+ addu $at,$at,$gp
+ lw $at,<sym>($at) (BFD_RELOC_MIPS_GOT_LO16)
+ nop
+ <op> $treg,0($at)
+ <op> $treg+1,4($at)
+ Otherwise we want
+ lw $at,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ nop
+ <op> $treg,<sym>($at) (BFD_RELOC_LO16)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_LO16)
+ If there is a base register we add it to $at before the
+ lwc1 instructions. If there is a constant we include it
+ in the lwc1 instructions. */
+ used_at = 1;
+ expr1.X_add_number = offset_expr.X_add_number;
+ offset_expr.X_add_number = 0;
+ if (expr1.X_add_number < -0x8000
+ || expr1.X_add_number >= 0x8000 - 4)
+ as_bad (_("PIC code offset overflow (max 16 signed bits)"));
+ if (reg_needs_delay (GP))
+ gpdel = 4;
+ else
+ gpdel = 0;
+ if (breg == 0)
+ off = 0;
+ else
+ off = 4;
+ frag_grow (56);
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
+ AT, (int) BFD_RELOC_MIPS_GOT_HI16);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, AT, GP);
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT_LO16, AT);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, breg, AT);
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
+ coproc ? treg + 1 : treg,
+ (int) BFD_RELOC_LO16, AT);
+ expr1.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an undesired
+ nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
+ coproc ? treg : treg + 1,
+ (int) BFD_RELOC_LO16, AT);
+ mips_optimize = hold_mips_optimize;
+ expr1.X_add_number -= 4;
+
+ p = frag_var (rs_machine_dependent, 16 + gpdel + off, 0,
+ RELAX_ENCODE (24 + off, 16 + gpdel + off, gpdel,
+ 8 + gpdel + off, 1, 0),
+ offset_expr.X_add_symbol, (offsetT) 0,
+ (char *) NULL);
+ if (gpdel > 0)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ }
+ macro_build (p, &icnt, &offset_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "lw" : "ld"),
+ "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
+ p += 4;
+ macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
+ p += 4;
+ if (breg != 0)
+ {
+ macro_build (p, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, breg, AT);
+ p += 4;
+ }
+ /* Itbl support may require additional care here. */
+ macro_build (p, &icnt, &expr1, s, fmt,
+ coproc ? treg + 1 : treg,
+ (int) BFD_RELOC_LO16, AT);
+ p += 4;
+ expr1.X_add_number += 4;
+
+ /* Set mips_optimize to 2 to avoid inserting an undesired
+ nop. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ /* Itbl support may require additional care here. */
+ macro_build (p, &icnt, &expr1, s, fmt,
+ coproc ? treg : treg + 1,
+ (int) BFD_RELOC_LO16, AT);
+ mips_optimize = hold_mips_optimize;
+ }
+ else if (mips_pic == EMBEDDED_PIC)
+ {
+ /* If there is no base register, we use
+ <op> $treg,<sym>($gp) (BFD_RELOC_MIPS_GPREL)
+ <op> $treg+1,<sym>+4($gp) (BFD_RELOC_MIPS_GPREL)
+ If we have a base register, we use
+ addu $at,$breg,$gp
+ <op> $treg,<sym>($at) (BFD_RELOC_MIPS_GPREL)
+ <op> $treg+1,<sym>+4($at) (BFD_RELOC_MIPS_GPREL)
+ */
+ if (breg == 0)
+ {
+ tempreg = GP;
+ used_at = 0;
+ }
+ else
+ {
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, breg, GP);
+ tempreg = AT;
+ used_at = 1;
+ }
+
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ coproc ? treg + 1 : treg,
+ (int) BFD_RELOC_MIPS_GPREL, tempreg);
+ offset_expr.X_add_number += 4;
+ /* Itbl support may require additional care here. */
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
+ coproc ? treg : treg + 1,
+ (int) BFD_RELOC_MIPS_GPREL, tempreg);
+ }
+ else
+ abort ();
+
+ if (! used_at)
+ return;
+
+ break;
+
+ case M_LD_OB:
+ s = "lw";
+ goto sd_ob;
+ case M_SD_OB:
+ s = "sw";
+ sd_ob:
+ assert (bfd_arch_bits_per_address (stdoutput) == 32 || mips_opts.isa < 3);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ offset_expr.X_add_number += 4;
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg + 1,
+ (int) BFD_RELOC_LO16, breg);
+ return;
+
+ /* New code added to support COPZ instructions.
+ This code builds table entries out of the macros in mip_opcodes.
+ R4000 uses interlocks to handle coproc delays.
+ Other chips (like the R3000) require nops to be inserted for delays.
+
+ FIXME: Currently, we require that the user handle delays.
+ In order to fill delay slots for non-interlocked chips,
+ we must have a way to specify delays based on the coprocessor.
+ Eg. 4 cycles if load coproc reg from memory, 1 if in cache, etc.
+ What are the side-effects of the cop instruction?
+ What cache support might we have and what are its effects?
+ Both coprocessor & memory require delays. how long???
+ What registers are read/set/modified?
+
+ If an itbl is provided to interpret cop instructions,
+ this knowledge can be encoded in the itbl spec. */
+
+ case M_COP0:
+ s = "c0";
+ goto copz;
+ case M_COP1:
+ s = "c1";
+ goto copz;
+ case M_COP2:
+ s = "c2";
+ goto copz;
+ case M_COP3:
+ s = "c3";
+ copz:
+ /* For now we just do C (same as Cz). The parameter will be
+ stored in insn_opcode by mips_ip. */
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, s, "C",
+ ip->insn_opcode);
+ return;
+
+#ifdef LOSING_COMPILER
+ default:
+ /* Try and see if this is a new itbl instruction.
+ This code builds table entries out of the macros in mip_opcodes.
+ FIXME: For now we just assemble the expression and pass it's
+ value along as a 32-bit immediate.
+ We may want to have the assembler assemble this value,
+ so that we gain the assembler's knowledge of delay slots,
+ symbols, etc.
+ Would it be more efficient to use mask (id) here? */
+ if (itbl_have_entries
+ && (immed_expr = itbl_assemble (ip->insn_mo->name, "")))
+ {
+ s = ip->insn_mo->name;
+ s2 = "cop3";
+ coproc = ITBL_DECODE_PNUM (immed_expr);;
+ macro_build ((char *) NULL, &icnt, &immed_expr, s, "C");
+ return;
+ }
+ macro2 (ip);
+ return;
+ }
+ if (mips_opts.noat)
+ as_warn (_("Macro used $at after \".set noat\""));
+}
+
+static void
+macro2 (ip)
+ struct mips_cl_insn *ip;
+{
+ register int treg, sreg, dreg, breg;
+ int tempreg;
+ int mask;
+ int icnt = 0;
+ int used_at;
+ expressionS expr1;
+ const char *s;
+ const char *s2;
+ const char *fmt;
+ int likely = 0;
+ int dbl = 0;
+ int coproc = 0;
+ int lr = 0;
+ int imm = 0;
+ int off;
+ offsetT maxnum;
+ bfd_reloc_code_real_type r;
+ char *p;
+
+ treg = (ip->insn_opcode >> 16) & 0x1f;
+ dreg = (ip->insn_opcode >> 11) & 0x1f;
+ sreg = breg = (ip->insn_opcode >> 21) & 0x1f;
+ mask = ip->insn_mo->mask;
+
+ expr1.X_op = O_constant;
+ expr1.X_op_symbol = NULL;
+ expr1.X_add_symbol = NULL;
+ expr1.X_add_number = 1;
+
+ switch (mask)
+ {
+#endif /* LOSING_COMPILER */
+
+ case M_DMUL:
+ dbl = 1;
+ case M_MUL:
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dmultu" : "multu",
+ "s,t", sreg, treg);
+ macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
+ return;
+
+ case M_DMUL_I:
+ dbl = 1;
+ case M_MUL_I:
+ /* The MIPS assembler some times generates shifts and adds. I'm
+ not trying to be that fancy. GCC should do this for us
+ anyway. */
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dmult" : "mult",
+ "s,t", sreg, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
+ break;
+
+ case M_DMULO_I:
+ dbl = 1;
+ case M_MULO_I:
+ imm = 1;
+ goto do_mulo;
+
+ case M_DMULO:
+ dbl = 1;
+ case M_MULO:
+ do_mulo:
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (imm)
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dmult" : "mult",
+ "s,t", sreg, imm ? AT : treg);
+ macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dsra32" : "sra",
+ "d,w,<", dreg, dreg, 31);
+ macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);
+ if (mips_trap)
+ macro_build ((char *) NULL, &icnt, NULL, "tne", "s,t", dreg, AT);
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", dreg, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
+ }
+ --mips_opts.noreorder;
+ macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
+ break;
+
+ case M_DMULOU_I:
+ dbl = 1;
+ case M_MULOU_I:
+ imm = 1;
+ goto do_mulou;
+
+ case M_DMULOU:
+ dbl = 1;
+ case M_MULOU:
+ do_mulou:
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ if (imm)
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dmultu" : "multu",
+ "s,t", sreg, imm ? AT : treg);
+ macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);
+ macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
+ if (mips_trap)
+ macro_build ((char *) NULL, &icnt, NULL, "tne", "s,t", AT, 0);
+ else
+ {
+ expr1.X_add_number = 8;
+ macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", AT, 0);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
+ macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
+ }
+ --mips_opts.noreorder;
+ break;
+
+ case M_ROL:
+ macro_build ((char *) NULL, &icnt, NULL, "subu", "d,v,t", AT, 0, treg);
+ macro_build ((char *) NULL, &icnt, NULL, "srlv", "d,t,s", AT, sreg, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "sllv", "d,t,s", dreg, sreg,
+ treg);
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_ROL_I:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("rotate count too large"));
+ macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", AT, sreg,
+ (int) (imm_expr.X_add_number & 0x1f));
+ macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", dreg, sreg,
+ (int) ((0 - imm_expr.X_add_number) & 0x1f));
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_ROR:
+ macro_build ((char *) NULL, &icnt, NULL, "subu", "d,v,t", AT, 0, treg);
+ macro_build ((char *) NULL, &icnt, NULL, "sllv", "d,t,s", AT, sreg, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "srlv", "d,t,s", dreg, sreg,
+ treg);
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_ROR_I:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("rotate count too large"));
+ macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, sreg,
+ (int) (imm_expr.X_add_number & 0x1f));
+ macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", dreg, sreg,
+ (int) ((0 - imm_expr.X_add_number) & 0x1f));
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);
+ break;
+
+ case M_S_DOB:
+ if (mips_cpu == 4650)
+ {
+ as_bad (_("opcode not supported on this processor"));
+ return;
+ }
+ assert (mips_opts.isa < 2);
+ /* Even on a big endian machine $fn comes before $fn+1. We have
+ to adjust when storing to memory. */
+ macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",
+ target_big_endian ? treg + 1 : treg,
+ (int) BFD_RELOC_LO16, breg);
+ offset_expr.X_add_number += 4;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",
+ target_big_endian ? treg : treg + 1,
+ (int) BFD_RELOC_LO16, breg);
+ return;
+
+ case M_SEQ:
+ if (sreg == 0)
+ macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
+ treg, (int) BFD_RELOC_LO16);
+ else if (treg == 0)
+ macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
+ sreg, (int) BFD_RELOC_LO16);
+ else
+ {
+ macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
+ sreg, treg);
+ macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
+ dreg, (int) BFD_RELOC_LO16);
+ }
+ return;
+
+ case M_SEQ_I:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
+ sreg, (int) BFD_RELOC_LO16);
+ return;
+ }
+ if (sreg == 0)
+ {
+ as_warn (_("Instruction %s: result is always false"),
+ ip->insn_mo->name);
+ macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
+ return;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i", dreg,
+ sreg, (int) BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number < 0)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", dreg, sreg,
+ (int) BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else
+ {
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
+ sreg, AT);
+ used_at = 1;
+ }
+ macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg, dreg,
+ (int) BFD_RELOC_LO16);
+ if (used_at)
+ break;
+ return;
+
+ case M_SGE: /* sreg >= treg <==> not (sreg < treg) */
+ s = "slt";
+ goto sge;
+ case M_SGEU:
+ s = "sltu";
+ sge:
+ macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, sreg, treg);
+ macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
+ (int) BFD_RELOC_LO16);
+ return;
+
+ case M_SGE_I: /* sreg >= I <==> not (sreg < I) */
+ case M_SGEU_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr,
+ mask == M_SGE_I ? "slti" : "sltiu",
+ "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else
+ {
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL,
+ mask == M_SGE_I ? "slt" : "sltu",
+ "d,v,t", dreg, sreg, AT);
+ used_at = 1;
+ }
+ macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
+ (int) BFD_RELOC_LO16);
+ if (used_at)
+ break;
+ return;
+
+ case M_SGT: /* sreg > treg <==> treg < sreg */
+ s = "slt";
+ goto sgt;
+ case M_SGTU:
+ s = "sltu";
+ sgt:
+ macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, treg, sreg);
+ return;
+
+ case M_SGT_I: /* sreg > I <==> I < sreg */
+ s = "slt";
+ goto sgti;
+ case M_SGTU_I:
+ s = "sltu";
+ sgti:
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, AT, sreg);
+ break;
+
+ case M_SLE: /* sreg <= treg <==> treg >= sreg <==> not (treg < sreg) */
+ s = "slt";
+ goto sle;
+ case M_SLEU:
+ s = "sltu";
+ sle:
+ macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, treg, sreg);
+ macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
+ (int) BFD_RELOC_LO16);
+ return;
+
+ case M_SLE_I: /* sreg <= I <==> I >= sreg <==> not (I < sreg) */
+ s = "slt";
+ goto slei;
+ case M_SLEU_I:
+ s = "sltu";
+ slei:
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, AT, sreg);
+ macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,
+ (int) BFD_RELOC_LO16);
+ break;
+
+ case M_SLT_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr, "slti", "t,r,j",
+ dreg, sreg, (int) BFD_RELOC_LO16);
+ return;
+ }
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_SLTU_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr, "sltiu", "t,r,j",
+ dreg, sreg, (int) BFD_RELOC_LO16);
+ return;
+ }
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, sreg,
+ AT);
+ break;
+
+ case M_SNE:
+ if (sreg == 0)
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
+ treg);
+ else if (treg == 0)
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
+ sreg);
+ else
+ {
+ macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
+ sreg, treg);
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
+ dreg);
+ }
+ return;
+
+ case M_SNE_I:
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ {
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
+ sreg);
+ return;
+ }
+ if (sreg == 0)
+ {
+ as_warn (_("Instruction %s: result is always true"),
+ ip->insn_mo->name);
+ macro_build ((char *) NULL, &icnt, &expr1,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", dreg, 0, (int) BFD_RELOC_LO16);
+ return;
+ }
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
+ {
+ macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i",
+ dreg, sreg, (int) BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number < 0)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addiu" : "daddiu"),
+ "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
+ used_at = 0;
+ }
+ else
+ {
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,
+ sreg, AT);
+ used_at = 1;
+ }
+ macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);
+ if (used_at)
+ break;
+ return;
+
+ case M_DSUB_I:
+ dbl = 1;
+ case M_SUB_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number <= 0x8000)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr,
+ dbl ? "daddi" : "addi",
+ "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
+ return;
+ }
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dsub" : "sub",
+ "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_DSUBU_I:
+ dbl = 1;
+ case M_SUBU_I:
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number <= 0x8000)
+ {
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr,
+ dbl ? "daddiu" : "addiu",
+ "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
+ return;
+ }
+ load_register (&icnt, AT, &imm_expr, dbl);
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dsubu" : "subu",
+ "d,v,t", dreg, sreg, AT);
+ break;
+
+ case M_TEQ_I:
+ s = "teq";
+ goto trap;
+ case M_TGE_I:
+ s = "tge";
+ goto trap;
+ case M_TGEU_I:
+ s = "tgeu";
+ goto trap;
+ case M_TLT_I:
+ s = "tlt";
+ goto trap;
+ case M_TLTU_I:
+ s = "tltu";
+ goto trap;
+ case M_TNE_I:
+ s = "tne";
+ trap:
+ load_register (&icnt, AT, &imm_expr, 0);
+ macro_build ((char *) NULL, &icnt, NULL, s, "s,t", sreg, AT);
+ break;
+
+ case M_TRUNCWD:
+ case M_TRUNCWS:
+ assert (mips_opts.isa < 2);
+ sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
+ dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
+
+ /*
+ * Is the double cfc1 instruction a bug in the mips assembler;
+ * or is there a reason for it?
+ */
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
+ macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "");
+ expr1.X_add_number = 3;
+ macro_build ((char *) NULL, &icnt, &expr1, "ori", "t,r,i", AT, treg,
+ (int) BFD_RELOC_LO16);
+ expr1.X_add_number = 2;
+ macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", AT, AT,
+ (int) BFD_RELOC_LO16);
+ macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", AT, 31);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "");
+ macro_build ((char *) NULL, &icnt, NULL,
+ mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg);
+ macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", treg, 31);
+ macro_build ((char *) NULL, &icnt, NULL, "nop", "");
+ --mips_opts.noreorder;
+ break;
+
+ case M_ULH:
+ s = "lb";
+ goto ulh;
+ case M_ULHU:
+ s = "lbu";
+ ulh:
+ if (offset_expr.X_add_number >= 0x7fff)
+ as_bad (_("operand overflow"));
+ /* avoid load delay */
+ if (! target_big_endian)
+ offset_expr.X_add_number += 1;
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ if (! target_big_endian)
+ offset_expr.X_add_number -= 1;
+ else
+ offset_expr.X_add_number += 1;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "lbu", "t,o(b)", AT,
+ (int) BFD_RELOC_LO16, breg);
+ macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, treg, 8);
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, treg, AT);
+ break;
+
+ case M_ULD:
+ s = "ldl";
+ s2 = "ldr";
+ off = 7;
+ goto ulw;
+ case M_ULW:
+ s = "lwl";
+ s2 = "lwr";
+ off = 3;
+ ulw:
+ if (offset_expr.X_add_number >= 0x8000 - off)
+ as_bad (_("operand overflow"));
+ if (! target_big_endian)
+ offset_expr.X_add_number += off;
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ if (! target_big_endian)
+ offset_expr.X_add_number -= off;
+ else
+ offset_expr.X_add_number += off;
+ macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ return;
+
+ case M_ULD_A:
+ s = "ldl";
+ s2 = "ldr";
+ off = 7;
+ goto ulwa;
+ case M_ULW_A:
+ s = "lwl";
+ s2 = "lwr";
+ off = 3;
+ ulwa:
+ load_address (&icnt, AT, &offset_expr);
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, AT, breg);
+ if (! target_big_endian)
+ expr1.X_add_number = off;
+ else
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ else
+ expr1.X_add_number = off;
+ macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ break;
+
+ case M_ULH_A:
+ case M_ULHU_A:
+ load_address (&icnt, AT, &offset_expr);
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, AT, breg);
+ if (target_big_endian)
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1,
+ mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ if (target_big_endian)
+ expr1.X_add_number = 1;
+ else
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
+ (int) BFD_RELOC_LO16, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
+ treg, 8);
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
+ treg, AT);
+ break;
+
+ case M_USH:
+ if (offset_expr.X_add_number >= 0x7fff)
+ as_bad (_("operand overflow"));
+ if (target_big_endian)
+ offset_expr.X_add_number += 1;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "sb", "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, treg, 8);
+ if (target_big_endian)
+ offset_expr.X_add_number -= 1;
+ else
+ offset_expr.X_add_number += 1;
+ macro_build ((char *) NULL, &icnt, &offset_expr, "sb", "t,o(b)", AT,
+ (int) BFD_RELOC_LO16, breg);
+ break;
+
+ case M_USD:
+ s = "sdl";
+ s2 = "sdr";
+ off = 7;
+ goto usw;
+ case M_USW:
+ s = "swl";
+ s2 = "swr";
+ off = 3;
+ usw:
+ if (offset_expr.X_add_number >= 0x8000 - off)
+ as_bad (_("operand overflow"));
+ if (! target_big_endian)
+ offset_expr.X_add_number += off;
+ macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ if (! target_big_endian)
+ offset_expr.X_add_number -= off;
+ else
+ offset_expr.X_add_number += off;
+ macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, breg);
+ return;
+
+ case M_USD_A:
+ s = "sdl";
+ s2 = "sdr";
+ off = 7;
+ goto uswa;
+ case M_USW_A:
+ s = "swl";
+ s2 = "swr";
+ off = 3;
+ uswa:
+ load_address (&icnt, AT, &offset_expr);
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, AT, breg);
+ if (! target_big_endian)
+ expr1.X_add_number = off;
+ else
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ else
+ expr1.X_add_number = off;
+ macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ break;
+
+ case M_USH_A:
+ load_address (&icnt, AT, &offset_expr);
+ if (breg != 0)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", AT, AT, breg);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg,
+ treg, 8);
+ if (! target_big_endian)
+ expr1.X_add_number = 1;
+ else
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,
+ (int) BFD_RELOC_LO16, AT);
+ if (! target_big_endian)
+ expr1.X_add_number = 0;
+ else
+ expr1.X_add_number = 1;
+ macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,
+ (int) BFD_RELOC_LO16, AT);
+ macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,
+ treg, 8);
+ macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,
+ treg, AT);
+ break;
+
+ default:
+ /* FIXME: Check if this is one of the itbl macros, since they
+ are added dynamically. */
+ as_bad (_("Macro %s not implemented yet"), ip->insn_mo->name);
+ break;
+ }
+ if (mips_opts.noat)
+ as_warn (_("Macro used $at after \".set noat\""));
+}
+
+/* Implement macros in mips16 mode. */
+
+static void
+mips16_macro (ip)
+ struct mips_cl_insn *ip;
+{
+ int mask;
+ int xreg, yreg, zreg, tmp;
+ int icnt;
+ expressionS expr1;
+ int dbl;
+ const char *s, *s2, *s3;
+
+ mask = ip->insn_mo->mask;
+
+ xreg = (ip->insn_opcode >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
+ yreg = (ip->insn_opcode >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY;
+ zreg = (ip->insn_opcode >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
+
+ icnt = 0;
+
+ expr1.X_op = O_constant;
+ expr1.X_op_symbol = NULL;
+ expr1.X_add_symbol = NULL;
+ expr1.X_add_number = 1;
+
+ dbl = 0;
+
+ switch (mask)
+ {
+ default:
+ internalError ();
+
+ case M_DDIV_3:
+ dbl = 1;
+ case M_DIV_3:
+ s = "mflo";
+ goto do_div3;
+ case M_DREM_3:
+ dbl = 1;
+ case M_REM_3:
+ s = "mfhi";
+ do_div3:
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "ddiv" : "div",
+ "0,x,y", xreg, yreg);
+ expr1.X_add_number = 2;
+ macro_build ((char *) NULL, &icnt, &expr1, "bnez", "x,p", yreg);
+ macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);
+
+ /* FIXME: The normal code checks for of -1 / -0x80000000 here,
+ since that causes an overflow. We should do that as well,
+ but I don't see how to do the comparisons without a temporary
+ register. */
+ --mips_opts.noreorder;
+ macro_build ((char *) NULL, &icnt, NULL, s, "x", zreg);
+ break;
+
+ case M_DIVU_3:
+ s = "divu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_REMU_3:
+ s = "divu";
+ s2 = "mfhi";
+ goto do_divu3;
+ case M_DDIVU_3:
+ s = "ddivu";
+ s2 = "mflo";
+ goto do_divu3;
+ case M_DREMU_3:
+ s = "ddivu";
+ s2 = "mfhi";
+ do_divu3:
+ mips_emit_delays (true);
+ ++mips_opts.noreorder;
+ mips_any_noreorder = 1;
+ macro_build ((char *) NULL, &icnt, NULL, s, "0,x,y", xreg, yreg);
+ expr1.X_add_number = 2;
+ macro_build ((char *) NULL, &icnt, &expr1, "bnez", "x,p", yreg);
+ macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);
+ --mips_opts.noreorder;
+ macro_build ((char *) NULL, &icnt, NULL, s2, "x", zreg);
+ break;
+
+ case M_DMUL:
+ dbl = 1;
+ case M_MUL:
+ macro_build ((char *) NULL, &icnt, NULL,
+ dbl ? "dmultu" : "multu",
+ "x,y", xreg, yreg);
+ macro_build ((char *) NULL, &icnt, NULL, "mflo", "x", zreg);
+ return;
+
+ case M_DSUBU_I:
+ dbl = 1;
+ goto do_subu;
+ case M_SUBU_I:
+ do_subu:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr,
+ dbl ? "daddiu" : "addiu",
+ "y,x,4", yreg, xreg);
+ break;
+
+ case M_SUBU_I_2:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr, "addiu",
+ "x,k", xreg);
+ break;
+
+ case M_DSUBU_I_2:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ imm_expr.X_add_number = -imm_expr.X_add_number;
+ macro_build ((char *) NULL, &icnt, &imm_expr, "daddiu",
+ "y,j", yreg);
+ break;
+
+ case M_BEQ:
+ s = "cmp";
+ s2 = "bteqz";
+ goto do_branch;
+ case M_BNE:
+ s = "cmp";
+ s2 = "btnez";
+ goto do_branch;
+ case M_BLT:
+ s = "slt";
+ s2 = "btnez";
+ goto do_branch;
+ case M_BLTU:
+ s = "sltu";
+ s2 = "btnez";
+ goto do_branch;
+ case M_BLE:
+ s = "slt";
+ s2 = "bteqz";
+ goto do_reverse_branch;
+ case M_BLEU:
+ s = "sltu";
+ s2 = "bteqz";
+ goto do_reverse_branch;
+ case M_BGE:
+ s = "slt";
+ s2 = "bteqz";
+ goto do_branch;
+ case M_BGEU:
+ s = "sltu";
+ s2 = "bteqz";
+ goto do_branch;
+ case M_BGT:
+ s = "slt";
+ s2 = "btnez";
+ goto do_reverse_branch;
+ case M_BGTU:
+ s = "sltu";
+ s2 = "btnez";
+
+ do_reverse_branch:
+ tmp = xreg;
+ xreg = yreg;
+ yreg = tmp;
+
+ do_branch:
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, s, "x,y",
+ xreg, yreg);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s2, "p");
+ break;
+
+ case M_BEQ_I:
+ s = "cmpi";
+ s2 = "bteqz";
+ s3 = "x,U";
+ goto do_branch_i;
+ case M_BNE_I:
+ s = "cmpi";
+ s2 = "btnez";
+ s3 = "x,U";
+ goto do_branch_i;
+ case M_BLT_I:
+ s = "slti";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BLTU_I:
+ s = "sltiu";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BLE_I:
+ s = "slti";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_addone_branch_i;
+ case M_BLEU_I:
+ s = "sltiu";
+ s2 = "btnez";
+ s3 = "x,8";
+ goto do_addone_branch_i;
+ case M_BGE_I:
+ s = "slti";
+ s2 = "bteqz";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BGEU_I:
+ s = "sltiu";
+ s2 = "bteqz";
+ s3 = "x,8";
+ goto do_branch_i;
+ case M_BGT_I:
+ s = "slti";
+ s2 = "bteqz";
+ s3 = "x,8";
+ goto do_addone_branch_i;
+ case M_BGTU_I:
+ s = "sltiu";
+ s2 = "bteqz";
+ s3 = "x,8";
+
+ do_addone_branch_i:
+ if (imm_expr.X_op != O_constant)
+ as_bad (_("Unsupported large constant"));
+ ++imm_expr.X_add_number;
+
+ do_branch_i:
+ macro_build ((char *) NULL, &icnt, &imm_expr, s, s3, xreg);
+ macro_build ((char *) NULL, &icnt, &offset_expr, s2, "p");
+ break;
+
+ case M_ABS:
+ expr1.X_add_number = 0;
+ macro_build ((char *) NULL, &icnt, &expr1, "slti", "x,8", yreg);
+ if (xreg != yreg)
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "move", "y,X", xreg, yreg);
+ expr1.X_add_number = 2;
+ macro_build ((char *) NULL, &icnt, &expr1, "bteqz", "p");
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "neg", "x,w", xreg, xreg);
+ }
+}
+
+/* For consistency checking, verify that all bits are specified either
+ by the match/mask part of the instruction definition, or by the
+ operand list. */
+static int
+validate_mips_insn (opc)
+ const struct mips_opcode *opc;
+{
+ const char *p = opc->args;
+ char c;
+ unsigned long used_bits = opc->mask;
+
+ if ((used_bits & opc->match) != opc->match)
+ {
+ as_bad (_("internal: bad mips opcode (mask error): %s %s"),
+ opc->name, opc->args);
+ return 0;
+ }
+#define USE_BITS(mask,shift) (used_bits |= ((mask) << (shift)))
+ while (*p)
+ switch (c = *p++)
+ {
+ case ',': break;
+ case '(': break;
+ case ')': break;
+ case '<': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case 'A': break;
+ case 'B': USE_BITS (OP_MASK_SYSCALL, OP_SH_SYSCALL); break;
+ case 'C': USE_BITS (OP_MASK_COPZ, OP_SH_COPZ); break;
+ case 'D': USE_BITS (OP_MASK_FD, OP_SH_FD); break;
+ case 'E': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'F': break;
+ case 'G': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
+ case 'I': break;
+ case 'L': break;
+ case 'M': USE_BITS (OP_MASK_CCC, OP_SH_CCC); break;
+ case 'N': USE_BITS (OP_MASK_BCC, OP_SH_BCC); break;
+ case 'R': USE_BITS (OP_MASK_FR, OP_SH_FR); break;
+ case 'S': USE_BITS (OP_MASK_FS, OP_SH_FS); break;
+ case 'T': USE_BITS (OP_MASK_FT, OP_SH_FT); break;
+ case 'V': USE_BITS (OP_MASK_FS, OP_SH_FS); break;
+ case 'W': USE_BITS (OP_MASK_FT, OP_SH_FT); break;
+ case 'a': USE_BITS (OP_MASK_TARGET, OP_SH_TARGET); break;
+ case 'b': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 'c': USE_BITS (OP_MASK_CODE, OP_SH_CODE); break;
+ case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
+ case 'f': break;
+ case 'h': USE_BITS (OP_MASK_PREFX, OP_SH_PREFX); break;
+ case 'i': USE_BITS (OP_MASK_IMMEDIATE, OP_SH_IMMEDIATE); break;
+ case 'j': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break;
+ case 'k': USE_BITS (OP_MASK_CACHE, OP_SH_CACHE); break;
+ case 'l': break;
+ case 'o': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break;
+ case 'p': USE_BITS (OP_MASK_DELTA, OP_SH_DELTA); break;
+ case 'q': USE_BITS (OP_MASK_CODE2, OP_SH_CODE2); break;
+ case 'r': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 's': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 't': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'u': USE_BITS (OP_MASK_IMMEDIATE, OP_SH_IMMEDIATE); break;
+ case 'v': USE_BITS (OP_MASK_RS, OP_SH_RS); break;
+ case 'w': USE_BITS (OP_MASK_RT, OP_SH_RT); break;
+ case 'x': break;
+ case 'z': break;
+ case 'P': USE_BITS (OP_MASK_PERFREG, OP_SH_PERFREG); break;
+ default:
+ as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),
+ c, opc->name, opc->args);
+ return 0;
+ }
+#undef USE_BITS
+ if (used_bits != 0xffffffff)
+ {
+ as_bad (_("internal: bad mips opcode (bits 0x%lx undefined): %s %s"),
+ ~used_bits & 0xffffffff, opc->name, opc->args);
+ return 0;
+ }
+ return 1;
+}
+
+/* This routine assembles an instruction into its binary format. As a
+ side effect, it sets one of the global variables imm_reloc or
+ offset_reloc to the type of relocation to do if one of the operands
+ is an address expression. */
+
+static void
+mips_ip (str, ip)
+ char *str;
+ struct mips_cl_insn *ip;
+{
+ char *s;
+ const char *args;
+ char c;
+ struct mips_opcode *insn;
+ char *argsStart;
+ unsigned int regno;
+ unsigned int lastregno = 0;
+ char *s_reset;
+ char save_c = 0;
+ int full_opcode_match = 1;
+
+ insn_error = NULL;
+
+ /* If the instruction contains a '.', we first try to match an instruction
+ including the '.'. Then we try again without the '.'. */
+ insn = NULL;
+ for (s = str; *s != '\0' && !isspace(*s); ++s)
+ continue;
+
+ /* If we stopped on whitespace, then replace the whitespace with null for
+ the call to hash_find. Save the character we replaced just in case we
+ have to re-parse the instruction. */
+ if (isspace (*s))
+ {
+ save_c = *s;
+ *s++ = '\0';
+ }
+
+ insn = (struct mips_opcode *) hash_find (op_hash, str);
+
+ /* If we didn't find the instruction in the opcode table, try again, but
+ this time with just the instruction up to, but not including the
+ first '.'. */
+ if (insn == NULL)
+ {
+ /* Restore the character we overwrite above (if any). */
+ if (save_c)
+ *(--s) = save_c;
+
+ /* Scan up to the first '.' or whitespace. */
+ for (s = str; *s != '\0' && *s != '.' && !isspace (*s); ++s)
+ continue;
+
+ /* If we did not find a '.', then we can quit now. */
+ if (*s != '.')
+ {
+ insn_error = "unrecognized opcode";
+ return;
+ }
+
+ /* Lookup the instruction in the hash table. */
+ *s++ = '\0';
+ if ((insn = (struct mips_opcode *) hash_find (op_hash, str)) == NULL)
+ {
+ insn_error = "unrecognized opcode";
+ return;
+ }
+
+ full_opcode_match = 0;
+ }
+
+ argsStart = s;
+ for (;;)
+ {
+ int insn_isa;
+ boolean ok;
+
+ assert (strcmp (insn->name, str) == 0);
+
+ if ((insn->membership & INSN_ISA) == INSN_ISA1)
+ insn_isa = 1;
+ else if ((insn->membership & INSN_ISA) == INSN_ISA2)
+ insn_isa = 2;
+ else if ((insn->membership & INSN_ISA) == INSN_ISA3)
+ insn_isa = 3;
+ else if ((insn->membership & INSN_ISA) == INSN_ISA4)
+ insn_isa = 4;
+ else
+ insn_isa = 15;
+
+ if (insn_isa <= mips_opts.isa)
+ ok = true;
+ else if (insn->pinfo == INSN_MACRO)
+ ok = false;
+ else if ((mips_cpu == 4650 && (insn->membership & INSN_4650) != 0)
+ || (mips_cpu == 4010 && (insn->membership & INSN_4010) != 0)
+ || ((mips_cpu == 4100
+ || mips_cpu == 4111
+ )
+ && (insn->membership & INSN_4100) != 0)
+ || (mips_cpu == 3900 && (insn->membership & INSN_3900) != 0))
+ ok = true;
+ else
+ ok = false;
+
+ if (insn->pinfo != INSN_MACRO)
+ {
+ if (mips_cpu == 4650 && (insn->pinfo & FP_D) != 0)
+ ok = false;
+ }
+
+ if (! ok)
+ {
+ if (insn + 1 < &mips_opcodes[NUMOPCODES]
+ && strcmp (insn->name, insn[1].name) == 0)
+ {
+ ++insn;
+ continue;
+ }
+ if (insn_isa == 15
+ || insn_isa <= mips_opts.isa)
+ insn_error = _("opcode not supported on this processor");
+ else
+ {
+ static char buf[100];
+
+ sprintf (buf, _("opcode requires -mips%d or greater"), insn_isa);
+ insn_error = buf;
+ }
+ return;
+ }
+
+ ip->insn_mo = insn;
+ ip->insn_opcode = insn->match;
+ for (args = insn->args;; ++args)
+ {
+ if (*s == ' ')
+ ++s;
+ switch (*args)
+ {
+ case '\0': /* end of args */
+ if (*s == '\0')
+ return;
+ break;
+
+ case ',':
+ if (*s++ == *args)
+ continue;
+ s--;
+ switch (*++args)
+ {
+ case 'r':
+ case 'v':
+ ip->insn_opcode |= lastregno << 21;
+ continue;
+
+ case 'w':
+ case 'W':
+ ip->insn_opcode |= lastregno << 16;
+ continue;
+
+ case 'V':
+ ip->insn_opcode |= lastregno << 11;
+ continue;
+ }
+ break;
+
+ case '(':
+ /* Handle optional base register.
+ Either the base register is omitted or
+ we must have a left paren. */
+ /* This is dependent on the next operand specifier
+ is a base register specification. */
+ assert (args[1] == 'b' || args[1] == '5'
+ || args[1] == '-' || args[1] == '4');
+ if (*s == '\0')
+ return;
+
+ case ')': /* these must match exactly */
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '<': /* must be at least one digit */
+ /*
+ * According to the manual, if the shift amount is greater
+ * than 31 or less than 0 the the shift amount should be
+ * mod 32. In reality the mips assembler issues an error.
+ * We issue a warning and mask out all but the low 5 bits.
+ */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 31)
+ {
+ as_warn (_("Improper shift amount (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number = imm_expr.X_add_number & 0x1f;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << 6;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case '>': /* shift amount minus 32 */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number < 32
+ || (unsigned long) imm_expr.X_add_number > 63)
+ break;
+ ip->insn_opcode |= (imm_expr.X_add_number - 32) << 6;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+
+ case 'k': /* cache code */
+ case 'h': /* prefx code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 31)
+ {
+ as_warn (_("Invalid value for `%s' (%lu)"),
+ ip->insn_mo->name,
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x1f;
+ }
+ if (*args == 'k')
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CACHE;
+ else
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_PREFX;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'c': /* break code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned) imm_expr.X_add_number > 1023)
+ {
+ as_warn (_("Illegal break code (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x3ff;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << 16;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'q': /* lower break code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned) imm_expr.X_add_number > 1023)
+ {
+ as_warn (_("Illegal lower break code (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x3ff;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << 6;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'B': /* syscall code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned) imm_expr.X_add_number > 0xfffff)
+ as_warn (_("Illegal syscall code (%ld)"),
+ (long) imm_expr.X_add_number);
+ ip->insn_opcode |= imm_expr.X_add_number << 6;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'C': /* Coprocessor code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number >= (1<<25))
+ {
+ as_warn (_("Coproccesor code > 25 bits (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= ((1<<25) - 1);
+ }
+ ip->insn_opcode |= imm_expr.X_add_number;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'P': /* Performance register */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if (imm_expr.X_add_number != 0 && imm_expr.X_add_number != 1)
+ {
+ as_warn (_("Invalidate performance regster (%ld)"),
+ (long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 1;
+ }
+ ip->insn_opcode |= (imm_expr.X_add_number << 1);
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'b': /* base register */
+ case 'd': /* destination register */
+ case 's': /* source register */
+ case 't': /* target register */
+ case 'r': /* both target and source */
+ case 'v': /* both dest and source */
+ case 'w': /* both dest and target */
+ case 'E': /* coprocessor target register */
+ case 'G': /* coprocessor destination register */
+ case 'x': /* ignore register name */
+ case 'z': /* must be zero register */
+ s_reset = s;
+ if (s[0] == '$')
+ {
+
+ if (isdigit (s[1]))
+ {
+ ++s;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (isdigit (*s));
+ if (regno > 31)
+ as_bad (_("Invalid register number (%d)"), regno);
+ }
+ else if (*args == 'E' || *args == 'G')
+ goto notreg;
+ else
+ {
+ if (s[1] == 'f' && s[2] == 'p')
+ {
+ s += 3;
+ regno = FP;
+ }
+ else if (s[1] == 's' && s[2] == 'p')
+ {
+ s += 3;
+ regno = SP;
+ }
+ else if (s[1] == 'g' && s[2] == 'p')
+ {
+ s += 3;
+ regno = GP;
+ }
+ else if (s[1] == 'a' && s[2] == 't')
+ {
+ s += 3;
+ regno = AT;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
+ {
+ s += 4;
+ regno = KT0;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
+ {
+ s += 4;
+ regno = KT1;
+ }
+ else if (itbl_have_entries)
+ {
+ char *p, *n;
+ int r;
+
+ p = s+1; /* advance past '$' */
+ n = itbl_get_field (&p); /* n is name */
+
+ /* See if this is a register defined in an
+ itbl entry */
+ r = itbl_get_reg_val (n);
+ if (r)
+ {
+ /* Get_field advances to the start of
+ the next field, so we need to back
+ rack to the end of the last field. */
+ if (p)
+ s = p - 1;
+ else
+ s = strchr (s,'\0');
+ regno = r;
+ }
+ else
+ goto notreg;
+ }
+ else
+ goto notreg;
+ }
+ if (regno == AT
+ && ! mips_opts.noat
+ && *args != 'E'
+ && *args != 'G')
+ as_warn (_("Used $at without \".set noat\""));
+ c = *args;
+ if (*s == ' ')
+ s++;
+ if (args[1] != *s)
+ {
+ if (c == 'r' || c == 'v' || c == 'w')
+ {
+ regno = lastregno;
+ s = s_reset;
+ args++;
+ }
+ }
+ /* 'z' only matches $0. */
+ if (c == 'z' && regno != 0)
+ break;
+
+ /* Now that we have assembled one operand, we use the args string
+ * to figure out where it goes in the instruction. */
+ switch (c)
+ {
+ case 'r':
+ case 's':
+ case 'v':
+ case 'b':
+ ip->insn_opcode |= regno << 21;
+ break;
+ case 'd':
+ case 'G':
+ ip->insn_opcode |= regno << 11;
+ break;
+ case 'w':
+ case 't':
+ case 'E':
+ ip->insn_opcode |= regno << 16;
+ break;
+ case 'x':
+ /* This case exists because on the r3000 trunc
+ expands into a macro which requires a gp
+ register. On the r6000 or r4000 it is
+ assembled into a single instruction which
+ ignores the register. Thus the insn version
+ is MIPS_ISA2 and uses 'x', and the macro
+ version is MIPS_ISA1 and uses 't'. */
+ break;
+ case 'z':
+ /* This case is for the div instruction, which
+ acts differently if the destination argument
+ is $0. This only matches $0, and is checked
+ outside the switch. */
+ break;
+ case 'D':
+ /* Itbl operand; not yet implemented. FIXME ?? */
+ break;
+ /* What about all other operands like 'i', which
+ can be specified in the opcode table? */
+ }
+ lastregno = regno;
+ continue;
+ }
+ notreg:
+ switch (*args++)
+ {
+ case 'r':
+ case 'v':
+ ip->insn_opcode |= lastregno << 21;
+ continue;
+ case 'w':
+ ip->insn_opcode |= lastregno << 16;
+ continue;
+ }
+ break;
+
+ case 'D': /* floating point destination register */
+ case 'S': /* floating point source register */
+ case 'T': /* floating point target register */
+ case 'R': /* floating point source register */
+ case 'V':
+ case 'W':
+ s_reset = s;
+ if (s[0] == '$' && s[1] == 'f' && isdigit (s[2]))
+ {
+ s += 2;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (isdigit (*s));
+
+ if (regno > 31)
+ as_bad (_("Invalid float register number (%d)"), regno);
+
+ if ((regno & 1) != 0
+ && mips_opts.isa < 3
+ && ! (strcmp (str, "mtc1") == 0
+ || strcmp (str, "mfc1") == 0
+ || strcmp (str, "lwc1") == 0
+ || strcmp (str, "swc1") == 0
+ || strcmp (str, "l.s") == 0
+ || strcmp (str, "s.s") == 0))
+ as_warn (_("Float register should be even, was %d"),
+ regno);
+
+ c = *args;
+ if (*s == ' ')
+ s++;
+ if (args[1] != *s)
+ {
+ if (c == 'V' || c == 'W')
+ {
+ regno = lastregno;
+ s = s_reset;
+ args++;
+ }
+ }
+ switch (c)
+ {
+ case 'D':
+ ip->insn_opcode |= regno << 6;
+ break;
+ case 'V':
+ case 'S':
+ ip->insn_opcode |= regno << 11;
+ break;
+ case 'W':
+ case 'T':
+ ip->insn_opcode |= regno << 16;
+ break;
+ case 'R':
+ ip->insn_opcode |= regno << 21;
+ break;
+ }
+ lastregno = regno;
+ continue;
+ }
+
+
+ switch (*args++)
+ {
+ case 'V':
+ ip->insn_opcode |= lastregno << 11;
+ continue;
+ case 'W':
+ ip->insn_opcode |= lastregno << 16;
+ continue;
+ }
+ break;
+
+ case 'I':
+ my_getExpression (&imm_expr, s);
+ if (imm_expr.X_op != O_big
+ && imm_expr.X_op != O_constant)
+ insn_error = _("absolute expression required");
+ s = expr_end;
+ continue;
+
+ case 'A':
+ my_getExpression (&offset_expr, s);
+ imm_reloc = BFD_RELOC_32;
+ s = expr_end;
+ continue;
+
+ case 'F':
+ case 'L':
+ case 'f':
+ case 'l':
+ {
+ int f64;
+ char *save_in;
+ char *err;
+ unsigned char temp[8];
+ int len;
+ unsigned int length;
+ segT seg;
+ subsegT subseg;
+ char *p;
+
+ /* These only appear as the last operand in an
+ instruction, and every instruction that accepts
+ them in any variant accepts them in all variants.
+ This means we don't have to worry about backing out
+ any changes if the instruction does not match.
+
+ The difference between them is the size of the
+ floating point constant and where it goes. For 'F'
+ and 'L' the constant is 64 bits; for 'f' and 'l' it
+ is 32 bits. Where the constant is placed is based
+ on how the MIPS assembler does things:
+ F -- .rdata
+ L -- .lit8
+ f -- immediate value
+ l -- .lit4
+
+ The .lit4 and .lit8 sections are only used if
+ permitted by the -G argument.
+
+ When generating embedded PIC code, we use the
+ .lit8 section but not the .lit4 section (we can do
+ .lit4 inline easily; we need to put .lit8
+ somewhere in the data segment, and using .lit8
+ permits the linker to eventually combine identical
+ .lit8 entries). */
+
+ f64 = *args == 'F' || *args == 'L';
+
+ save_in = input_line_pointer;
+ input_line_pointer = s;
+ err = md_atof (f64 ? 'd' : 'f', (char *) temp, &len);
+ length = len;
+ s = input_line_pointer;
+ input_line_pointer = save_in;
+ if (err != NULL && *err != '\0')
+ {
+ as_bad (_("Bad floating point constant: %s"), err);
+ memset (temp, '\0', sizeof temp);
+ length = f64 ? 8 : 4;
+ }
+
+ assert (length == (f64 ? 8 : 4));
+
+ if (*args == 'f'
+ || (*args == 'l'
+ && (! USE_GLOBAL_POINTER_OPT
+ || mips_pic == EMBEDDED_PIC
+ || g_switch_value < 4
+ || (temp[0] == 0 && temp[1] == 0)
+ || (temp[2] == 0 && temp[3] == 0))))
+ {
+ imm_expr.X_op = O_constant;
+ if (! target_big_endian)
+ imm_expr.X_add_number = bfd_getl32 (temp);
+ else
+ imm_expr.X_add_number = bfd_getb32 (temp);
+ }
+ else if (length > 4
+ && ((temp[0] == 0 && temp[1] == 0)
+ || (temp[2] == 0 && temp[3] == 0))
+ && ((temp[4] == 0 && temp[5] == 0)
+ || (temp[6] == 0 && temp[7] == 0)))
+ {
+ /* The value is simple enough to load with a
+ couple of instructions. In mips1 mode, set
+ imm_expr to the high order 32 bits and
+ offset_expr to the low order 32 bits.
+ Otherwise, set imm_expr to the entire 64 bit
+ constant. */
+ if (mips_opts.isa < 3)
+ {
+ imm_expr.X_op = O_constant;
+ offset_expr.X_op = O_constant;
+ if (! target_big_endian)
+ {
+ imm_expr.X_add_number = bfd_getl32 (temp + 4);
+ offset_expr.X_add_number = bfd_getl32 (temp);
+ }
+ else
+ {
+ imm_expr.X_add_number = bfd_getb32 (temp);
+ offset_expr.X_add_number = bfd_getb32 (temp + 4);
+ }
+ if (offset_expr.X_add_number == 0)
+ offset_expr.X_op = O_absent;
+ }
+ else if (sizeof (imm_expr.X_add_number) > 4)
+ {
+ imm_expr.X_op = O_constant;
+ if (! target_big_endian)
+ imm_expr.X_add_number = bfd_getl64 (temp);
+ else
+ imm_expr.X_add_number = bfd_getb64 (temp);
+ }
+ else
+ {
+ imm_expr.X_op = O_big;
+ imm_expr.X_add_number = 4;
+ if (! target_big_endian)
+ {
+ generic_bignum[0] = bfd_getl16 (temp);
+ generic_bignum[1] = bfd_getl16 (temp + 2);
+ generic_bignum[2] = bfd_getl16 (temp + 4);
+ generic_bignum[3] = bfd_getl16 (temp + 6);
+ }
+ else
+ {
+ generic_bignum[0] = bfd_getb16 (temp + 6);
+ generic_bignum[1] = bfd_getb16 (temp + 4);
+ generic_bignum[2] = bfd_getb16 (temp + 2);
+ generic_bignum[3] = bfd_getb16 (temp);
+ }
+ }
+ }
+ else
+ {
+ const char *newname;
+ segT new_seg;
+
+ /* Switch to the right section. */
+ seg = now_seg;
+ subseg = now_subseg;
+ switch (*args)
+ {
+ default: /* unused default case avoids warnings. */
+ case 'L':
+ newname = RDATA_SECTION_NAME;
+ if (USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
+ newname = ".lit8";
+ break;
+ case 'F':
+ newname = RDATA_SECTION_NAME;
+ break;
+ case 'l':
+ assert (!USE_GLOBAL_POINTER_OPT
+ || g_switch_value >= 4);
+ newname = ".lit4";
+ break;
+ }
+ new_seg = subseg_new (newname, (subsegT) 0);
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ bfd_set_section_flags (stdoutput, new_seg,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_READONLY
+ | SEC_DATA));
+ frag_align (*args == 'l' ? 2 : 3, 0, 0);
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && strcmp (TARGET_OS, "elf") != 0)
+ record_alignment (new_seg, 4);
+ else
+ record_alignment (new_seg, *args == 'l' ? 2 : 3);
+ if (seg == now_seg)
+ as_bad (_("Can't use floating point insn in this section"));
+
+ /* Set the argument to the current address in the
+ section. */
+ offset_expr.X_op = O_symbol;
+ offset_expr.X_add_symbol =
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (), frag_now);
+ offset_expr.X_add_number = 0;
+
+ /* Put the floating point number into the section. */
+ p = frag_more ((int) length);
+ memcpy (p, temp, length);
+
+ /* Switch back to the original section. */
+ subseg_set (seg, subseg);
+ }
+ }
+ continue;
+
+ case 'i': /* 16 bit unsigned immediate */
+ case 'j': /* 16 bit signed immediate */
+ imm_reloc = BFD_RELOC_LO16;
+ c = my_getSmallExpression (&imm_expr, s);
+ if (c != '\0')
+ {
+ if (c != 'l')
+ {
+ if (imm_expr.X_op == O_constant)
+ imm_expr.X_add_number =
+ (imm_expr.X_add_number >> 16) & 0xffff;
+ else if (c == 'h')
+ {
+ imm_reloc = BFD_RELOC_HI16_S;
+ imm_unmatched_hi = true;
+ }
+ else
+ imm_reloc = BFD_RELOC_HI16;
+ }
+ else if (imm_expr.X_op == O_constant)
+ imm_expr.X_add_number &= 0xffff;
+ }
+ if (*args == 'i')
+ {
+ if ((c == '\0' && imm_expr.X_op != O_constant)
+ || ((imm_expr.X_add_number < 0
+ || imm_expr.X_add_number >= 0x10000)
+ && imm_expr.X_op == O_constant))
+ {
+ if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
+ !strcmp (insn->name, insn[1].name))
+ break;
+ if (imm_expr.X_op != O_constant
+ && imm_expr.X_op != O_big)
+ insn_error = _("absolute expression required");
+ else
+ as_bad (_("16 bit expression not in range 0..65535"));
+ }
+ }
+ else
+ {
+ int more;
+ offsetT max;
+
+ /* The upper bound should be 0x8000, but
+ unfortunately the MIPS assembler accepts numbers
+ from 0x8000 to 0xffff and sign extends them, and
+ we want to be compatible. We only permit this
+ extended range for an instruction which does not
+ provide any further alternates, since those
+ alternates may handle other cases. People should
+ use the numbers they mean, rather than relying on
+ a mysterious sign extension. */
+ more = (insn + 1 < &mips_opcodes[NUMOPCODES] &&
+ strcmp (insn->name, insn[1].name) == 0);
+ if (more)
+ max = 0x8000;
+ else
+ max = 0x10000;
+ if ((c == '\0' && imm_expr.X_op != O_constant)
+ || ((imm_expr.X_add_number < -0x8000
+ || imm_expr.X_add_number >= max)
+ && imm_expr.X_op == O_constant)
+ || (more
+ && imm_expr.X_add_number < 0
+ && mips_opts.isa >= 3
+ && imm_expr.X_unsigned
+ && sizeof (imm_expr.X_add_number) <= 4))
+ {
+ if (more)
+ break;
+ if (imm_expr.X_op != O_constant
+ && imm_expr.X_op != O_big)
+ insn_error = _("absolute expression required");
+ else
+ as_bad (_("16 bit expression not in range -32768..32767"));
+ }
+ }
+ s = expr_end;
+ continue;
+
+ case 'o': /* 16 bit offset */
+ c = my_getSmallExpression (&offset_expr, s);
+
+ /* If this value won't fit into a 16 bit offset, then go
+ find a macro that will generate the 32 bit offset
+ code pattern. As a special hack, we accept the
+ difference of two local symbols as a constant. This
+ is required to suppose embedded PIC switches, which
+ use an instruction which looks like
+ lw $4,$L12-$LS12($4)
+ The problem with handling this in a more general
+ fashion is that the macro function doesn't expect to
+ see anything which can be handled in a single
+ constant instruction. */
+ if (c == 0
+ && (offset_expr.X_op != O_constant
+ || offset_expr.X_add_number >= 0x8000
+ || offset_expr.X_add_number < -0x8000)
+ && (mips_pic != EMBEDDED_PIC
+ || offset_expr.X_op != O_subtract
+ || now_seg != text_section
+ || (S_GET_SEGMENT (offset_expr.X_op_symbol)
+ != text_section)))
+ break;
+
+ if (c == 'h' || c == 'H')
+ {
+ if (offset_expr.X_op != O_constant)
+ break;
+ offset_expr.X_add_number =
+ (offset_expr.X_add_number >> 16) & 0xffff;
+ }
+ offset_reloc = BFD_RELOC_LO16;
+ s = expr_end;
+ continue;
+
+ case 'p': /* pc relative offset */
+ offset_reloc = BFD_RELOC_16_PCREL_S2;
+ my_getExpression (&offset_expr, s);
+ s = expr_end;
+ continue;
+
+ case 'u': /* upper 16 bits */
+ c = my_getSmallExpression (&imm_expr, s);
+ imm_reloc = BFD_RELOC_LO16;
+ if (c)
+ {
+ if (c != 'l')
+ {
+ if (imm_expr.X_op == O_constant)
+ imm_expr.X_add_number =
+ (imm_expr.X_add_number >> 16) & 0xffff;
+ else if (c == 'h')
+ {
+ imm_reloc = BFD_RELOC_HI16_S;
+ imm_unmatched_hi = true;
+ }
+ else
+ imm_reloc = BFD_RELOC_HI16;
+ }
+ else if (imm_expr.X_op == O_constant)
+ imm_expr.X_add_number &= 0xffff;
+ }
+ if (imm_expr.X_op == O_constant
+ && (imm_expr.X_add_number < 0
+ || imm_expr.X_add_number >= 0x10000))
+ as_bad (_("lui expression not in range 0..65535"));
+ s = expr_end;
+ continue;
+
+ case 'a': /* 26 bit address */
+ my_getExpression (&offset_expr, s);
+ s = expr_end;
+ offset_reloc = BFD_RELOC_MIPS_JMP;
+ continue;
+
+ case 'N': /* 3 bit branch condition code */
+ case 'M': /* 3 bit compare condition code */
+ if (strncmp (s, "$fcc", 4) != 0)
+ break;
+ s += 4;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (isdigit (*s));
+ if (regno > 7)
+ as_bad (_("invalid condition code register $fcc%d"), regno);
+ if (*args == 'N')
+ ip->insn_opcode |= regno << OP_SH_BCC;
+ else
+ ip->insn_opcode |= regno << OP_SH_CCC;
+ continue;
+
+ default:
+ as_bad (_("bad char = '%c'\n"), *args);
+ internalError ();
+ }
+ break;
+ }
+ /* Args don't match. */
+ if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
+ !strcmp (insn->name, insn[1].name))
+ {
+ ++insn;
+ s = argsStart;
+ continue;
+ }
+ insn_error = _("illegal operands");
+ return;
+ }
+}
+
+/* This routine assembles an instruction into its binary format when
+ assembling for the mips16. As a side effect, it sets one of the
+ global variables imm_reloc or offset_reloc to the type of
+ relocation to do if one of the operands is an address expression.
+ It also sets mips16_small and mips16_ext if the user explicitly
+ requested a small or extended instruction. */
+
+static void
+mips16_ip (str, ip)
+ char *str;
+ struct mips_cl_insn *ip;
+{
+ char *s;
+ const char *args;
+ struct mips_opcode *insn;
+ char *argsstart;
+ unsigned int regno;
+ unsigned int lastregno = 0;
+ char *s_reset;
+
+ insn_error = NULL;
+
+ mips16_small = false;
+ mips16_ext = false;
+
+ for (s = str; islower (*s); ++s)
+ ;
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ case '.':
+ if (s[1] == 't' && s[2] == ' ')
+ {
+ *s = '\0';
+ mips16_small = true;
+ s += 3;
+ break;
+ }
+ else if (s[1] == 'e' && s[2] == ' ')
+ {
+ *s = '\0';
+ mips16_ext = true;
+ s += 3;
+ break;
+ }
+ /* Fall through. */
+ default:
+ insn_error = _("unknown opcode");
+ return;
+ }
+
+ if (mips_opts.noautoextend && ! mips16_ext)
+ mips16_small = true;
+
+ if ((insn = (struct mips_opcode *) hash_find (mips16_op_hash, str)) == NULL)
+ {
+ insn_error = _("unrecognized opcode");
+ return;
+ }
+
+ argsstart = s;
+ for (;;)
+ {
+ assert (strcmp (insn->name, str) == 0);
+
+ ip->insn_mo = insn;
+ ip->insn_opcode = insn->match;
+ ip->use_extend = false;
+ imm_expr.X_op = O_absent;
+ imm_reloc = BFD_RELOC_UNUSED;
+ offset_expr.X_op = O_absent;
+ offset_reloc = BFD_RELOC_UNUSED;
+ for (args = insn->args; 1; ++args)
+ {
+ int c;
+
+ if (*s == ' ')
+ ++s;
+
+ /* In this switch statement we call break if we did not find
+ a match, continue if we did find a match, or return if we
+ are done. */
+
+ c = *args;
+ switch (c)
+ {
+ case '\0':
+ if (*s == '\0')
+ {
+ /* Stuff the immediate value in now, if we can. */
+ if (imm_expr.X_op == O_constant
+ && imm_reloc > BFD_RELOC_UNUSED
+ && insn->pinfo != INSN_MACRO)
+ {
+ mips16_immed ((char *) NULL, 0,
+ imm_reloc - BFD_RELOC_UNUSED,
+ imm_expr.X_add_number, true, mips16_small,
+ mips16_ext, &ip->insn_opcode,
+ &ip->use_extend, &ip->extend);
+ imm_expr.X_op = O_absent;
+ imm_reloc = BFD_RELOC_UNUSED;
+ }
+
+ return;
+ }
+ break;
+
+ case ',':
+ if (*s++ == c)
+ continue;
+ s--;
+ switch (*++args)
+ {
+ case 'v':
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;
+ continue;
+ case 'w':
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;
+ continue;
+ }
+ break;
+
+ case '(':
+ case ')':
+ if (*s++ == c)
+ continue;
+ break;
+
+ case 'v':
+ case 'w':
+ if (s[0] != '$')
+ {
+ if (c == 'v')
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;
+ else
+ ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;
+ ++args;
+ continue;
+ }
+ /* Fall through. */
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'Z':
+ case '0':
+ case 'S':
+ case 'R':
+ case 'X':
+ case 'Y':
+ if (s[0] != '$')
+ break;
+ s_reset = s;
+ if (isdigit (s[1]))
+ {
+ ++s;
+ regno = 0;
+ do
+ {
+ regno *= 10;
+ regno += *s - '0';
+ ++s;
+ }
+ while (isdigit (*s));
+ if (regno > 31)
+ {
+ as_bad (_("invalid register number (%d)"), regno);
+ regno = 2;
+ }
+ }
+ else
+ {
+ if (s[1] == 'f' && s[2] == 'p')
+ {
+ s += 3;
+ regno = FP;
+ }
+ else if (s[1] == 's' && s[2] == 'p')
+ {
+ s += 3;
+ regno = SP;
+ }
+ else if (s[1] == 'g' && s[2] == 'p')
+ {
+ s += 3;
+ regno = GP;
+ }
+ else if (s[1] == 'a' && s[2] == 't')
+ {
+ s += 3;
+ regno = AT;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
+ {
+ s += 4;
+ regno = KT0;
+ }
+ else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
+ {
+ s += 4;
+ regno = KT1;
+ }
+ else
+ break;
+ }
+
+ if (*s == ' ')
+ ++s;
+ if (args[1] != *s)
+ {
+ if (c == 'v' || c == 'w')
+ {
+ regno = mips16_to_32_reg_map[lastregno];
+ s = s_reset;
+ args++;
+ }
+ }
+
+ switch (c)
+ {
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'v':
+ case 'w':
+ case 'Z':
+ regno = mips32_to_16_reg_map[regno];
+ break;
+
+ case '0':
+ if (regno != 0)
+ regno = ILLEGAL_REG;
+ break;
+
+ case 'S':
+ if (regno != SP)
+ regno = ILLEGAL_REG;
+ break;
+
+ case 'R':
+ if (regno != RA)
+ regno = ILLEGAL_REG;
+ break;
+
+ case 'X':
+ case 'Y':
+ if (regno == AT && ! mips_opts.noat)
+ as_warn (_("used $at without \".set noat\""));
+ break;
+
+ default:
+ internalError ();
+ }
+
+ if (regno == ILLEGAL_REG)
+ break;
+
+ switch (c)
+ {
+ case 'x':
+ case 'v':
+ ip->insn_opcode |= regno << MIPS16OP_SH_RX;
+ break;
+ case 'y':
+ case 'w':
+ ip->insn_opcode |= regno << MIPS16OP_SH_RY;
+ break;
+ case 'z':
+ ip->insn_opcode |= regno << MIPS16OP_SH_RZ;
+ break;
+ case 'Z':
+ ip->insn_opcode |= regno << MIPS16OP_SH_MOVE32Z;
+ case '0':
+ case 'S':
+ case 'R':
+ break;
+ case 'X':
+ ip->insn_opcode |= regno << MIPS16OP_SH_REGR32;
+ break;
+ case 'Y':
+ regno = ((regno & 7) << 2) | ((regno & 0x18) >> 3);
+ ip->insn_opcode |= regno << MIPS16OP_SH_REG32R;
+ break;
+ default:
+ internalError ();
+ }
+
+ lastregno = regno;
+ continue;
+
+ case 'P':
+ if (strncmp (s, "$pc", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '4':
+ case '5':
+ case 'H':
+ case 'W':
+ case 'D':
+ case 'j':
+ case '8':
+ case 'V':
+ case 'C':
+ case 'U':
+ case 'k':
+ case 'K':
+ if (s[0] == '%'
+ && strncmp (s + 1, "gprel(", sizeof "gprel(" - 1) == 0)
+ {
+ /* This is %gprel(SYMBOL). We need to read SYMBOL,
+ and generate the appropriate reloc. If the text
+ inside %gprel is not a symbol name with an
+ optional offset, then we generate a normal reloc
+ and will probably fail later. */
+ my_getExpression (&imm_expr, s + sizeof "%gprel" - 1);
+ if (imm_expr.X_op == O_symbol)
+ {
+ mips16_ext = true;
+ imm_reloc = BFD_RELOC_MIPS16_GPREL;
+ s = expr_end;
+ ip->use_extend = true;
+ ip->extend = 0;
+ continue;
+ }
+ }
+ else
+ {
+ /* Just pick up a normal expression. */
+ my_getExpression (&imm_expr, s);
+ }
+
+ if (imm_expr.X_op == O_register)
+ {
+ /* What we thought was an expression turned out to
+ be a register. */
+
+ if (s[0] == '(' && args[1] == '(')
+ {
+ /* It looks like the expression was omitted
+ before a register indirection, which means
+ that the expression is implicitly zero. We
+ still set up imm_expr, so that we handle
+ explicit extensions correctly. */
+ imm_expr.X_op = O_constant;
+ imm_expr.X_add_number = 0;
+ imm_reloc = (int) BFD_RELOC_UNUSED + c;
+ continue;
+ }
+
+ break;
+ }
+
+ /* We need to relax this instruction. */
+ imm_reloc = (int) BFD_RELOC_UNUSED + c;
+ s = expr_end;
+ continue;
+
+ case 'p':
+ case 'q':
+ case 'A':
+ case 'B':
+ case 'E':
+ /* We use offset_reloc rather than imm_reloc for the PC
+ relative operands. This lets macros with both
+ immediate and address operands work correctly. */
+ my_getExpression (&offset_expr, s);
+
+ if (offset_expr.X_op == O_register)
+ break;
+
+ /* We need to relax this instruction. */
+ offset_reloc = (int) BFD_RELOC_UNUSED + c;
+ s = expr_end;
+ continue;
+
+ case '6': /* break code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 63)
+ {
+ as_warn (_("Invalid value for `%s' (%lu)"),
+ ip->insn_mo->name,
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x3f;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number << MIPS16OP_SH_IMM6;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ case 'a': /* 26 bit address */
+ my_getExpression (&offset_expr, s);
+ s = expr_end;
+ offset_reloc = BFD_RELOC_MIPS16_JMP;
+ ip->insn_opcode <<= 16;
+ continue;
+
+ case 'l': /* register list for entry macro */
+ case 'L': /* register list for exit macro */
+ {
+ int mask;
+
+ if (c == 'l')
+ mask = 0;
+ else
+ mask = 7 << 3;
+ while (*s != '\0')
+ {
+ int freg, reg1, reg2;
+
+ while (*s == ' ' || *s == ',')
+ ++s;
+ if (*s != '$')
+ {
+ as_bad (_("can't parse register list"));
+ break;
+ }
+ ++s;
+ if (*s != 'f')
+ freg = 0;
+ else
+ {
+ freg = 1;
+ ++s;
+ }
+ reg1 = 0;
+ while (isdigit (*s))
+ {
+ reg1 *= 10;
+ reg1 += *s - '0';
+ ++s;
+ }
+ if (*s == ' ')
+ ++s;
+ if (*s != '-')
+ reg2 = reg1;
+ else
+ {
+ ++s;
+ if (*s != '$')
+ break;
+ ++s;
+ if (freg)
+ {
+ if (*s == 'f')
+ ++s;
+ else
+ {
+ as_bad (_("invalid register list"));
+ break;
+ }
+ }
+ reg2 = 0;
+ while (isdigit (*s))
+ {
+ reg2 *= 10;
+ reg2 += *s - '0';
+ ++s;
+ }
+ }
+ if (freg && reg1 == 0 && reg2 == 0 && c == 'L')
+ {
+ mask &= ~ (7 << 3);
+ mask |= 5 << 3;
+ }
+ else if (freg && reg1 == 0 && reg2 == 1 && c == 'L')
+ {
+ mask &= ~ (7 << 3);
+ mask |= 6 << 3;
+ }
+ else if (reg1 == 4 && reg2 >= 4 && reg2 <= 7 && c != 'L')
+ mask |= (reg2 - 3) << 3;
+ else if (reg1 == 16 && reg2 >= 16 && reg2 <= 17)
+ mask |= (reg2 - 15) << 1;
+ else if (reg1 == 31 && reg2 == 31)
+ mask |= 1;
+ else
+ {
+ as_bad (_("invalid register list"));
+ break;
+ }
+ }
+ /* The mask is filled in in the opcode table for the
+ benefit of the disassembler. We remove it before
+ applying the actual mask. */
+ ip->insn_opcode &= ~ ((7 << 3) << MIPS16OP_SH_IMM6);
+ ip->insn_opcode |= mask << MIPS16OP_SH_IMM6;
+ }
+ continue;
+
+ case 'e': /* extend code */
+ my_getExpression (&imm_expr, s);
+ check_absolute_expr (ip, &imm_expr);
+ if ((unsigned long) imm_expr.X_add_number > 0x7ff)
+ {
+ as_warn (_("Invalid value for `%s' (%lu)"),
+ ip->insn_mo->name,
+ (unsigned long) imm_expr.X_add_number);
+ imm_expr.X_add_number &= 0x7ff;
+ }
+ ip->insn_opcode |= imm_expr.X_add_number;
+ imm_expr.X_op = O_absent;
+ s = expr_end;
+ continue;
+
+ default:
+ internalError ();
+ }
+ break;
+ }
+
+ /* Args don't match. */
+ if (insn + 1 < &mips16_opcodes[bfd_mips16_num_opcodes] &&
+ strcmp (insn->name, insn[1].name) == 0)
+ {
+ ++insn;
+ s = argsstart;
+ continue;
+ }
+
+ insn_error = _("illegal operands");
+
+ return;
+ }
+}
+
+/* This structure holds information we know about a mips16 immediate
+ argument type. */
+
+struct mips16_immed_operand
+{
+ /* The type code used in the argument string in the opcode table. */
+ int type;
+ /* The number of bits in the short form of the opcode. */
+ int nbits;
+ /* The number of bits in the extended form of the opcode. */
+ int extbits;
+ /* The amount by which the short form is shifted when it is used;
+ for example, the sw instruction has a shift count of 2. */
+ int shift;
+ /* The amount by which the short form is shifted when it is stored
+ into the instruction code. */
+ int op_shift;
+ /* Non-zero if the short form is unsigned. */
+ int unsp;
+ /* Non-zero if the extended form is unsigned. */
+ int extu;
+ /* Non-zero if the value is PC relative. */
+ int pcrel;
+};
+
+/* The mips16 immediate operand types. */
+
+static const struct mips16_immed_operand mips16_immed_operands[] =
+{
+ { '<', 3, 5, 0, MIPS16OP_SH_RZ, 1, 1, 0 },
+ { '>', 3, 5, 0, MIPS16OP_SH_RX, 1, 1, 0 },
+ { '[', 3, 6, 0, MIPS16OP_SH_RZ, 1, 1, 0 },
+ { ']', 3, 6, 0, MIPS16OP_SH_RX, 1, 1, 0 },
+ { '4', 4, 15, 0, MIPS16OP_SH_IMM4, 0, 0, 0 },
+ { '5', 5, 16, 0, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'H', 5, 16, 1, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'W', 5, 16, 2, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'D', 5, 16, 3, MIPS16OP_SH_IMM5, 1, 0, 0 },
+ { 'j', 5, 16, 0, MIPS16OP_SH_IMM5, 0, 0, 0 },
+ { '8', 8, 16, 0, MIPS16OP_SH_IMM8, 1, 0, 0 },
+ { 'V', 8, 16, 2, MIPS16OP_SH_IMM8, 1, 0, 0 },
+ { 'C', 8, 16, 3, MIPS16OP_SH_IMM8, 1, 0, 0 },
+ { 'U', 8, 16, 0, MIPS16OP_SH_IMM8, 1, 1, 0 },
+ { 'k', 8, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 0 },
+ { 'K', 8, 16, 3, MIPS16OP_SH_IMM8, 0, 0, 0 },
+ { 'p', 8, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 1 },
+ { 'q', 11, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 1 },
+ { 'A', 8, 16, 2, MIPS16OP_SH_IMM8, 1, 0, 1 },
+ { 'B', 5, 16, 3, MIPS16OP_SH_IMM5, 1, 0, 1 },
+ { 'E', 5, 16, 2, MIPS16OP_SH_IMM5, 1, 0, 1 }
+};
+
+#define MIPS16_NUM_IMMED \
+ (sizeof mips16_immed_operands / sizeof mips16_immed_operands[0])
+
+/* Handle a mips16 instruction with an immediate value. This or's the
+ small immediate value into *INSN. It sets *USE_EXTEND to indicate
+ whether an extended value is needed; if one is needed, it sets
+ *EXTEND to the value. The argument type is TYPE. The value is VAL.
+ If SMALL is true, an unextended opcode was explicitly requested.
+ If EXT is true, an extended opcode was explicitly requested. If
+ WARN is true, warn if EXT does not match reality. */
+
+static void
+mips16_immed (file, line, type, val, warn, small, ext, insn, use_extend,
+ extend)
+ char *file;
+ unsigned int line;
+ int type;
+ offsetT val;
+ boolean warn;
+ boolean small;
+ boolean ext;
+ unsigned long *insn;
+ boolean *use_extend;
+ unsigned short *extend;
+{
+ register const struct mips16_immed_operand *op;
+ int mintiny, maxtiny;
+ boolean needext;
+
+ op = mips16_immed_operands;
+ while (op->type != type)
+ {
+ ++op;
+ assert (op < mips16_immed_operands + MIPS16_NUM_IMMED);
+ }
+
+ if (op->unsp)
+ {
+ if (type == '<' || type == '>' || type == '[' || type == ']')
+ {
+ mintiny = 1;
+ maxtiny = 1 << op->nbits;
+ }
+ else
+ {
+ mintiny = 0;
+ maxtiny = (1 << op->nbits) - 1;
+ }
+ }
+ else
+ {
+ mintiny = - (1 << (op->nbits - 1));
+ maxtiny = (1 << (op->nbits - 1)) - 1;
+ }
+
+ /* Branch offsets have an implicit 0 in the lowest bit. */
+ if (type == 'p' || type == 'q')
+ val /= 2;
+
+ if ((val & ((1 << op->shift) - 1)) != 0
+ || val < (mintiny << op->shift)
+ || val > (maxtiny << op->shift))
+ needext = true;
+ else
+ needext = false;
+
+ if (warn && ext && ! needext)
+ as_warn_where (file, line, _("extended operand requested but not required"));
+ if (small && needext)
+ as_bad_where (file, line, _("invalid unextended operand value"));
+
+ if (small || (! ext && ! needext))
+ {
+ int insnval;
+
+ *use_extend = false;
+ insnval = ((val >> op->shift) & ((1 << op->nbits) - 1));
+ insnval <<= op->op_shift;
+ *insn |= insnval;
+ }
+ else
+ {
+ long minext, maxext;
+ int extval;
+
+ if (op->extu)
+ {
+ minext = 0;
+ maxext = (1 << op->extbits) - 1;
+ }
+ else
+ {
+ minext = - (1 << (op->extbits - 1));
+ maxext = (1 << (op->extbits - 1)) - 1;
+ }
+ if (val < minext || val > maxext)
+ as_bad_where (file, line,
+ _("operand value out of range for instruction"));
+
+ *use_extend = true;
+ if (op->extbits == 16)
+ {
+ extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
+ val &= 0x1f;
+ }
+ else if (op->extbits == 15)
+ {
+ extval = ((val >> 11) & 0xf) | (val & 0x7f0);
+ val &= 0xf;
+ }
+ else
+ {
+ extval = ((val & 0x1f) << 6) | (val & 0x20);
+ val = 0;
+ }
+
+ *extend = (unsigned short) extval;
+ *insn |= val;
+ }
+}
+
+#define LP '('
+#define RP ')'
+
+static int
+my_getSmallExpression (ep, str)
+ expressionS *ep;
+ char *str;
+{
+ char *sp;
+ int c = 0;
+
+ if (*str == ' ')
+ str++;
+ if (*str == LP
+ || (*str == '%' &&
+ ((str[1] == 'h' && str[2] == 'i')
+ || (str[1] == 'H' && str[2] == 'I')
+ || (str[1] == 'l' && str[2] == 'o'))
+ && str[3] == LP))
+ {
+ if (*str == LP)
+ c = 0;
+ else
+ {
+ c = str[1];
+ str += 3;
+ }
+
+ /*
+ * A small expression may be followed by a base register.
+ * Scan to the end of this operand, and then back over a possible
+ * base register. Then scan the small expression up to that
+ * point. (Based on code in sparc.c...)
+ */
+ for (sp = str; *sp && *sp != ','; sp++)
+ ;
+ if (sp - 4 >= str && sp[-1] == RP)
+ {
+ if (isdigit (sp[-2]))
+ {
+ for (sp -= 3; sp >= str && isdigit (*sp); sp--)
+ ;
+ if (*sp == '$' && sp > str && sp[-1] == LP)
+ {
+ sp--;
+ goto do_it;
+ }
+ }
+ else if (sp - 5 >= str
+ && sp[-5] == LP
+ && sp[-4] == '$'
+ && ((sp[-3] == 'f' && sp[-2] == 'p')
+ || (sp[-3] == 's' && sp[-2] == 'p')
+ || (sp[-3] == 'g' && sp[-2] == 'p')
+ || (sp[-3] == 'a' && sp[-2] == 't')))
+ {
+ sp -= 5;
+ do_it:
+ if (sp == str)
+ {
+ /* no expression means zero offset */
+ if (c)
+ {
+ /* %xx(reg) is an error */
+ ep->X_op = O_absent;
+ expr_end = str - 3;
+ }
+ else
+ {
+ ep->X_op = O_constant;
+ expr_end = sp;
+ }
+ ep->X_add_symbol = NULL;
+ ep->X_op_symbol = NULL;
+ ep->X_add_number = 0;
+ }
+ else
+ {
+ *sp = '\0';
+ my_getExpression (ep, str);
+ *sp = LP;
+ }
+ return c;
+ }
+ }
+ }
+ my_getExpression (ep, str);
+ return c; /* => %hi or %lo encountered */
+}
+
+static void
+my_getExpression (ep, str)
+ expressionS *ep;
+ char *str;
+{
+ char *save_in;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ expression (ep);
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+
+ /* If we are in mips16 mode, and this is an expression based on `.',
+ then we bump the value of the symbol by 1 since that is how other
+ text symbols are handled. We don't bother to handle complex
+ expressions, just `.' plus or minus a constant. */
+ if (mips_opts.mips16
+ && ep->X_op == O_symbol
+ && strcmp (S_GET_NAME (ep->X_add_symbol), FAKE_LABEL_NAME) == 0
+ && S_GET_SEGMENT (ep->X_add_symbol) == now_seg
+ && ep->X_add_symbol->sy_frag == frag_now
+ && ep->X_add_symbol->sy_value.X_op == O_constant
+ && ep->X_add_symbol->sy_value.X_add_number == frag_now_fix ())
+ ++ep->X_add_symbol->sy_value.X_add_number;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type type, and store the appropriate bytes in *litP. The number
+ of LITTLENUMS emitted is stored in *sizeP . An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * 2;
+
+ if (! target_big_endian)
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+ else
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+
+ return NULL;
+}
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+CONST char *md_shortopts = "O::g::G:";
+
+struct option md_longopts[] = {
+#define OPTION_MIPS1 (OPTION_MD_BASE + 1)
+ {"mips0", no_argument, NULL, OPTION_MIPS1},
+ {"mips1", no_argument, NULL, OPTION_MIPS1},
+#define OPTION_MIPS2 (OPTION_MD_BASE + 2)
+ {"mips2", no_argument, NULL, OPTION_MIPS2},
+#define OPTION_MIPS3 (OPTION_MD_BASE + 3)
+ {"mips3", no_argument, NULL, OPTION_MIPS3},
+#define OPTION_MIPS4 (OPTION_MD_BASE + 4)
+ {"mips4", no_argument, NULL, OPTION_MIPS4},
+#define OPTION_MCPU (OPTION_MD_BASE + 5)
+ {"mcpu", required_argument, NULL, OPTION_MCPU},
+#define OPTION_MEMBEDDED_PIC (OPTION_MD_BASE + 6)
+ {"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC},
+#define OPTION_TRAP (OPTION_MD_BASE + 9)
+ {"trap", no_argument, NULL, OPTION_TRAP},
+ {"no-break", no_argument, NULL, OPTION_TRAP},
+#define OPTION_BREAK (OPTION_MD_BASE + 10)
+ {"break", no_argument, NULL, OPTION_BREAK},
+ {"no-trap", no_argument, NULL, OPTION_BREAK},
+#define OPTION_EB (OPTION_MD_BASE + 11)
+ {"EB", no_argument, NULL, OPTION_EB},
+#define OPTION_EL (OPTION_MD_BASE + 12)
+ {"EL", no_argument, NULL, OPTION_EL},
+#define OPTION_M4650 (OPTION_MD_BASE + 13)
+ {"m4650", no_argument, NULL, OPTION_M4650},
+#define OPTION_NO_M4650 (OPTION_MD_BASE + 14)
+ {"no-m4650", no_argument, NULL, OPTION_NO_M4650},
+#define OPTION_M4010 (OPTION_MD_BASE + 15)
+ {"m4010", no_argument, NULL, OPTION_M4010},
+#define OPTION_NO_M4010 (OPTION_MD_BASE + 16)
+ {"no-m4010", no_argument, NULL, OPTION_NO_M4010},
+#define OPTION_M4100 (OPTION_MD_BASE + 17)
+ {"m4100", no_argument, NULL, OPTION_M4100},
+#define OPTION_NO_M4100 (OPTION_MD_BASE + 18)
+ {"no-m4100", no_argument, NULL, OPTION_NO_M4100},
+#define OPTION_MIPS16 (OPTION_MD_BASE + 22)
+ {"mips16", no_argument, NULL, OPTION_MIPS16},
+#define OPTION_NO_MIPS16 (OPTION_MD_BASE + 23)
+ {"no-mips16", no_argument, NULL, OPTION_NO_MIPS16},
+#define OPTION_M3900 (OPTION_MD_BASE + 26)
+ {"m3900", no_argument, NULL, OPTION_M3900},
+#define OPTION_NO_M3900 (OPTION_MD_BASE + 27)
+ {"no-m3900", no_argument, NULL, OPTION_NO_M3900},
+
+
+#define OPTION_MABI (OPTION_MD_BASE + 38)
+ {"mabi", required_argument, NULL, OPTION_MABI},
+
+#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
+#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
+#define OPTION_XGOT (OPTION_MD_BASE + 19)
+#define OPTION_32 (OPTION_MD_BASE + 20)
+#define OPTION_64 (OPTION_MD_BASE + 21)
+#ifdef OBJ_ELF
+ {"KPIC", no_argument, NULL, OPTION_CALL_SHARED},
+ {"xgot", no_argument, NULL, OPTION_XGOT},
+ {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
+ {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
+ {"32", no_argument, NULL, OPTION_32},
+ {"64", no_argument, NULL, OPTION_64},
+#endif
+
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case OPTION_TRAP:
+ mips_trap = 1;
+ break;
+
+ case OPTION_BREAK:
+ mips_trap = 0;
+ break;
+
+ case OPTION_EB:
+ target_big_endian = 1;
+ break;
+
+ case OPTION_EL:
+ target_big_endian = 0;
+ break;
+
+ case 'O':
+ if (arg && arg[1] == '0')
+ mips_optimize = 1;
+ else
+ mips_optimize = 2;
+ break;
+
+ case 'g':
+ if (arg == NULL)
+ mips_debug = 2;
+ else
+ mips_debug = atoi (arg);
+ /* When the MIPS assembler sees -g or -g2, it does not do
+ optimizations which limit full symbolic debugging. We take
+ that to be equivalent to -O0. */
+ if (mips_debug == 2)
+ mips_optimize = 1;
+ break;
+
+ case OPTION_MIPS1:
+ mips_opts.isa = 1;
+ break;
+
+ case OPTION_MIPS2:
+ mips_opts.isa = 2;
+ break;
+
+ case OPTION_MIPS3:
+ mips_opts.isa = 3;
+ break;
+
+ case OPTION_MIPS4:
+ mips_opts.isa = 4;
+ break;
+
+ case OPTION_MCPU:
+ {
+ char *p;
+
+ /* Identify the processor type */
+ p = arg;
+ if (strcmp (p, "default") == 0
+ || strcmp (p, "DEFAULT") == 0)
+ mips_cpu = -1;
+ else
+ {
+ int sv = 0;
+
+ /* We need to cope with the various "vr" prefixes for the 4300
+ processor. */
+ if (*p == 'v' || *p == 'V')
+ {
+ sv = 1;
+ p++;
+ }
+
+ if (*p == 'r' || *p == 'R')
+ p++;
+
+ mips_cpu = -1;
+ switch (*p)
+ {
+ case '1':
+ if (strcmp (p, "10000") == 0
+ || strcmp (p, "10k") == 0
+ || strcmp (p, "10K") == 0)
+ mips_cpu = 10000;
+ break;
+
+ case '2':
+ if (strcmp (p, "2000") == 0
+ || strcmp (p, "2k") == 0
+ || strcmp (p, "2K") == 0)
+ mips_cpu = 2000;
+ break;
+
+ case '3':
+ if (strcmp (p, "3000") == 0
+ || strcmp (p, "3k") == 0
+ || strcmp (p, "3K") == 0)
+ mips_cpu = 3000;
+ else if (strcmp (p, "3900") == 0)
+ mips_cpu = 3900;
+ break;
+
+ case '4':
+ if (strcmp (p, "4000") == 0
+ || strcmp (p, "4k") == 0
+ || strcmp (p, "4K") == 0)
+ mips_cpu = 4000;
+ else if (strcmp (p, "4100") == 0)
+ mips_cpu = 4100;
+ else if (strcmp (p, "4111") == 0)
+ mips_cpu = 4111;
+ else if (strcmp (p, "4300") == 0)
+ mips_cpu = 4300;
+ else if (strcmp (p, "4400") == 0)
+ mips_cpu = 4400;
+ else if (strcmp (p, "4600") == 0)
+ mips_cpu = 4600;
+ else if (strcmp (p, "4650") == 0)
+ mips_cpu = 4650;
+ else if (strcmp (p, "4010") == 0)
+ mips_cpu = 4010;
+ break;
+
+ case '5':
+ if (strcmp (p, "5000") == 0
+ || strcmp (p, "5k") == 0
+ || strcmp (p, "5K") == 0)
+ mips_cpu = 5000;
+ break;
+
+ case '6':
+ if (strcmp (p, "6000") == 0
+ || strcmp (p, "6k") == 0
+ || strcmp (p, "6K") == 0)
+ mips_cpu = 6000;
+ break;
+
+ case '8':
+ if (strcmp (p, "8000") == 0
+ || strcmp (p, "8k") == 0
+ || strcmp (p, "8K") == 0)
+ mips_cpu = 8000;
+ break;
+
+ case 'o':
+ if (strcmp (p, "orion") == 0)
+ mips_cpu = 4600;
+ break;
+ }
+
+ if (sv
+ && (mips_cpu != 4300
+ && mips_cpu != 4100
+ && mips_cpu != 4111
+ && mips_cpu != 5000))
+ {
+ as_bad (_("ignoring invalid leading 'v' in -mcpu=%s switch"), arg);
+ return 0;
+ }
+
+ if (mips_cpu == -1)
+ {
+ as_bad (_("invalid architecture -mcpu=%s"), arg);
+ return 0;
+ }
+ }
+ }
+ break;
+
+ case OPTION_M4650:
+ mips_cpu = 4650;
+ break;
+
+ case OPTION_NO_M4650:
+ break;
+
+ case OPTION_M4010:
+ mips_cpu = 4010;
+ break;
+
+ case OPTION_NO_M4010:
+ break;
+
+ case OPTION_M4100:
+ mips_cpu = 4100;
+ break;
+
+ case OPTION_NO_M4100:
+ break;
+
+
+ case OPTION_M3900:
+ mips_cpu = 3900;
+ break;
+
+ case OPTION_NO_M3900:
+ break;
+
+ case OPTION_MIPS16:
+ mips_opts.mips16 = 1;
+ mips_no_prev_insn (false);
+ break;
+
+ case OPTION_NO_MIPS16:
+ mips_opts.mips16 = 0;
+ mips_no_prev_insn (false);
+ break;
+
+ case OPTION_MEMBEDDED_PIC:
+ mips_pic = EMBEDDED_PIC;
+ if (USE_GLOBAL_POINTER_OPT && g_switch_seen)
+ {
+ as_bad (_("-G may not be used with embedded PIC code"));
+ return 0;
+ }
+ g_switch_value = 0x7fffffff;
+ break;
+
+ /* When generating ELF code, we permit -KPIC and -call_shared to
+ select SVR4_PIC, and -non_shared to select no PIC. This is
+ intended to be compatible with Irix 5. */
+ case OPTION_CALL_SHARED:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-call_shared is supported only for ELF format"));
+ return 0;
+ }
+ mips_pic = SVR4_PIC;
+ if (g_switch_seen && g_switch_value != 0)
+ {
+ as_bad (_("-G may not be used with SVR4 PIC code"));
+ return 0;
+ }
+ g_switch_value = 0;
+ break;
+
+ case OPTION_NON_SHARED:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ {
+ as_bad (_("-non_shared is supported only for ELF format"));
+ return 0;
+ }
+ mips_pic = NO_PIC;
+ break;
+
+ /* The -xgot option tells the assembler to use 32 offsets when
+ accessing the got in SVR4_PIC mode. It is for Irix
+ compatibility. */
+ case OPTION_XGOT:
+ mips_big_got = 1;
+ break;
+
+ case 'G':
+ if (! USE_GLOBAL_POINTER_OPT)
+ {
+ as_bad (_("-G is not supported for this configuration"));
+ return 0;
+ }
+ else if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
+ {
+ as_bad (_("-G may not be used with SVR4 or embedded PIC code"));
+ return 0;
+ }
+ else
+ g_switch_value = atoi (arg);
+ g_switch_seen = 1;
+ break;
+
+ /* The -32 and -64 options tell the assembler to output the 32
+ bit or the 64 bit MIPS ELF format. */
+ case OPTION_32:
+ mips_64 = 0;
+ break;
+
+ case OPTION_64:
+ {
+ const char **list, **l;
+
+ list = bfd_target_list ();
+ for (l = list; *l != NULL; l++)
+ if (strcmp (*l, "elf64-bigmips") == 0
+ || strcmp (*l, "elf64-littlemips") == 0)
+ break;
+ if (*l == NULL)
+ as_fatal (_("No compiled in support for 64 bit object file format"));
+ free (list);
+ mips_64 = 1;
+ }
+ break;
+
+
+ case OPTION_MABI:
+ if (strcmp (arg,"32") == 0
+ || strcmp (arg,"n32") == 0
+ || strcmp (arg,"64") == 0
+ || strcmp (arg,"o64") == 0
+ || strcmp (arg,"eabi") == 0)
+ mips_abi_string = arg;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static void
+show (stream, string, col_p, first_p)
+ FILE *stream;
+ char *string;
+ int *col_p;
+ int *first_p;
+{
+ if (*first_p)
+ {
+ fprintf (stream, "%24s", "");
+ *col_p = 24;
+ }
+ else
+ {
+ fprintf (stream, ", ");
+ *col_p += 2;
+ }
+
+ if (*col_p + strlen (string) > 72)
+ {
+ fprintf (stream, "\n%24s", "");
+ *col_p = 24;
+ }
+
+ fprintf (stream, "%s", string);
+ *col_p += strlen (string);
+
+ *first_p = 0;
+}
+
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ int column, first;
+
+ fprintf(stream, _("\
+MIPS options:\n\
+-membedded-pic generate embedded position independent code\n\
+-EB generate big endian output\n\
+-EL generate little endian output\n\
+-g, -g2 do not remove uneeded NOPs or swap branches\n\
+-G NUM allow referencing objects up to NUM bytes\n\
+ implicitly with the gp register [default 8]\n"));
+ fprintf(stream, _("\
+-mips1 generate MIPS ISA I instructions\n\
+-mips2 generate MIPS ISA II instructions\n\
+-mips3 generate MIPS ISA III instructions\n\
+-mips4 generate MIPS ISA IV instructions\n\
+-mcpu=CPU generate code for CPU, where CPU is one of:\n"));
+
+ first = 1;
+
+ show (stream, "2000", &column, &first);
+ show (stream, "3000", &column, &first);
+ show (stream, "3900", &column, &first);
+ show (stream, "4000", &column, &first);
+ show (stream, "4010", &column, &first);
+ show (stream, "4100", &column, &first);
+ show (stream, "4111", &column, &first);
+ show (stream, "4300", &column, &first);
+ show (stream, "4400", &column, &first);
+ show (stream, "4600", &column, &first);
+ show (stream, "4650", &column, &first);
+ show (stream, "5000", &column, &first);
+ show (stream, "6000", &column, &first);
+ show (stream, "8000", &column, &first);
+ show (stream, "10000", &column, &first);
+ fputc ('\n', stream);
+
+ fprintf (stream, _("\
+-mCPU equivalent to -mcpu=CPU.\n\
+-no-mCPU don't generate code specific to CPU.\n\
+ For -mCPU and -no-mCPU, CPU must be one of:\n"));
+
+ first = 1;
+
+ show (stream, "3900", &column, &first);
+ show (stream, "4010", &column, &first);
+ show (stream, "4100", &column, &first);
+ show (stream, "4650", &column, &first);
+ fputc ('\n', stream);
+
+ fprintf(stream, _("\
+-mips16 generate mips16 instructions\n\
+-no-mips16 do not generate mips16 instructions\n"));
+ fprintf(stream, _("\
+-O0 remove unneeded NOPs, do not swap branches\n\
+-O remove unneeded NOPs and swap branches\n\
+--trap, --no-break trap exception on div by 0 and mult overflow\n\
+--break, --no-trap break exception on div by 0 and mult overflow\n"));
+#ifdef OBJ_ELF
+ fprintf(stream, _("\
+-KPIC, -call_shared generate SVR4 position independent code\n\
+-non_shared do not generate position independent code\n\
+-xgot assume a 32 bit GOT\n\
+-32 create 32 bit object file (default)\n\
+-64 create 64 bit object file\n"));
+#endif
+}
+
+void
+mips_init_after_args ()
+{
+ /* initialize opcodes */
+ bfd_mips_num_opcodes = bfd_mips_num_builtin_opcodes;
+ mips_opcodes = (struct mips_opcode*) mips_builtin_opcodes;
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ if (OUTPUT_FLAVOR != bfd_target_aout_flavour
+ && fixP->fx_addsy != (symbolS *) NULL
+ && ! S_IS_DEFINED (fixP->fx_addsy))
+ {
+ /* This makes a branch to an undefined symbol be a branch to the
+ current location. */
+ return 4;
+ }
+
+ /* return the address of the delay slot */
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
+ reloc for a cons. We could use the definition there, except that
+ we want to handle 64 bit relocs specially. */
+
+void
+cons_fix_new_mips (frag, where, nbytes, exp)
+ fragS *frag;
+ int where;
+ unsigned int nbytes;
+ expressionS *exp;
+{
+#ifndef OBJ_ELF
+ /* If we are assembling in 32 bit mode, turn an 8 byte reloc into a
+ 4 byte reloc. */
+ if (nbytes == 8 && ! mips_64)
+ {
+ if (target_big_endian)
+ where += 4;
+ nbytes = 4;
+ }
+#endif
+
+ if (nbytes != 2 && nbytes != 4 && nbytes != 8)
+ as_bad (_("Unsupported reloc size %d"), nbytes);
+
+ fix_new_exp (frag_now, where, (int) nbytes, exp, 0,
+ (nbytes == 2
+ ? BFD_RELOC_16
+ : (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
+}
+
+/* This is called before the symbol table is processed. In order to
+ work with gcc when using mips-tfile, we must keep all local labels.
+ However, in other cases, we want to discard them. If we were
+ called with -g, but we didn't see any debugging information, it may
+ mean that gcc is smuggling debugging information through to
+ mips-tfile, in which case we must generate all local labels. */
+
+void
+mips_frob_file_before_adjust ()
+{
+#ifndef NO_ECOFF_DEBUGGING
+ if (ECOFF_DEBUGGING
+ && mips_debug != 0
+ && ! ecoff_debugging_seen)
+ flag_keep_locals = 1;
+#endif
+}
+
+/* Sort any unmatched HI16_S relocs so that they immediately precede
+ the corresponding LO reloc. This is called before md_apply_fix and
+ tc_gen_reloc. Unmatched HI16_S relocs can only be generated by
+ explicit use of the %hi modifier. */
+
+void
+mips_frob_file ()
+{
+ struct mips_hi_fixup *l;
+
+ for (l = mips_hi_fixup_list; l != NULL; l = l->next)
+ {
+ segment_info_type *seginfo;
+ int pass;
+
+ assert (l->fixp->fx_r_type == BFD_RELOC_HI16_S);
+
+ /* Check quickly whether the next fixup happens to be a matching
+ %lo. */
+ if (l->fixp->fx_next != NULL
+ && l->fixp->fx_next->fx_r_type == BFD_RELOC_LO16
+ && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
+ && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
+ continue;
+
+ /* Look through the fixups for this segment for a matching %lo.
+ When we find one, move the %hi just in front of it. We do
+ this in two passes. In the first pass, we try to find a
+ unique %lo. In the second pass, we permit multiple %hi
+ relocs for a single %lo (this is a GNU extension). */
+ seginfo = seg_info (l->seg);
+ for (pass = 0; pass < 2; pass++)
+ {
+ fixS *f, *prev;
+
+ prev = NULL;
+ for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
+ {
+ /* Check whether this is a %lo fixup which matches l->fixp. */
+ if (f->fx_r_type == BFD_RELOC_LO16
+ && f->fx_addsy == l->fixp->fx_addsy
+ && f->fx_offset == l->fixp->fx_offset
+ && (pass == 1
+ || prev == NULL
+ || prev->fx_r_type != BFD_RELOC_HI16_S
+ || prev->fx_addsy != f->fx_addsy
+ || prev->fx_offset != f->fx_offset))
+ {
+ fixS **pf;
+
+ /* Move l->fixp before f. */
+ for (pf = &seginfo->fix_root;
+ *pf != l->fixp;
+ pf = &(*pf)->fx_next)
+ assert (*pf != NULL);
+
+ *pf = l->fixp->fx_next;
+
+ l->fixp->fx_next = f;
+ if (prev == NULL)
+ seginfo->fix_root = l->fixp;
+ else
+ prev->fx_next = l->fixp;
+
+ break;
+ }
+
+ prev = f;
+ }
+
+ if (f != NULL)
+ break;
+
+#if 0 /* GCC code motion plus incomplete dead code elimination
+ can leave a %hi without a %lo. */
+ if (pass == 1)
+ as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
+ _("Unmatched %%hi reloc"));
+#endif
+ }
+ }
+}
+
+/* When generating embedded PIC code we need to use a special
+ relocation to represent the difference of two symbols in the .text
+ section (switch tables use a difference of this sort). See
+ include/coff/mips.h for details. This macro checks whether this
+ fixup requires the special reloc. */
+#define SWITCH_TABLE(fixp) \
+ ((fixp)->fx_r_type == BFD_RELOC_32 \
+ && (fixp)->fx_addsy != NULL \
+ && (fixp)->fx_subsy != NULL \
+ && S_GET_SEGMENT ((fixp)->fx_addsy) == text_section \
+ && S_GET_SEGMENT ((fixp)->fx_subsy) == text_section)
+
+/* When generating embedded PIC code we must keep all PC relative
+ relocations, in case the linker has to relax a call. We also need
+ to keep relocations for switch table entries. */
+
+/*ARGSUSED*/
+int
+mips_force_relocation (fixp)
+ fixS *fixp;
+{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return (mips_pic == EMBEDDED_PIC
+ && (fixp->fx_pcrel
+ || SWITCH_TABLE (fixp)
+ || fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S
+ || fixp->fx_r_type == BFD_RELOC_PCREL_LO16));
+}
+
+/* Apply a fixup to the object file. */
+
+int
+md_apply_fix (fixP, valueP)
+ fixS *fixP;
+ valueT *valueP;
+{
+ unsigned char *buf;
+ long insn, value;
+
+ assert (fixP->fx_size == 4
+ || fixP->fx_r_type == BFD_RELOC_16
+ || fixP->fx_r_type == BFD_RELOC_64
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY);
+
+ value = *valueP;
+
+ /* If we aren't adjusting this fixup to be against the section
+ symbol, we need to adjust the value. */
+#ifdef OBJ_ELF
+ if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
+ || S_IS_WEAK (fixP->fx_addsy)
+ || (fixP->fx_addsy->sy_used_in_reloc
+ && (bfd_get_section_flags (stdoutput,
+ S_GET_SEGMENT (fixP->fx_addsy))
+ & SEC_LINK_ONCE != 0)
+ || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
+ ".gnu.linkonce",
+ sizeof (".gnu.linkonce") - 1)))
+
+ {
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ if (value != 0 && ! fixP->fx_pcrel)
+ {
+ /* In this case, the bfd_install_relocation routine will
+ incorrectly add the symbol value back in. We just want
+ the addend to appear in the object file. */
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ }
+ }
+#endif
+
+
+ fixP->fx_addnumber = value; /* Remember value for tc_gen_reloc */
+
+ if (fixP->fx_addsy == NULL && ! fixP->fx_pcrel)
+ fixP->fx_done = 1;
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_MIPS_JMP:
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_S:
+ case BFD_RELOC_MIPS_GPREL:
+ case BFD_RELOC_MIPS_LITERAL:
+ case BFD_RELOC_MIPS_CALL16:
+ case BFD_RELOC_MIPS_GOT16:
+ case BFD_RELOC_MIPS_GPREL32:
+ case BFD_RELOC_MIPS_GOT_HI16:
+ case BFD_RELOC_MIPS_GOT_LO16:
+ case BFD_RELOC_MIPS_CALL_HI16:
+ case BFD_RELOC_MIPS_CALL_LO16:
+ case BFD_RELOC_MIPS16_GPREL:
+ if (fixP->fx_pcrel)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Invalid PC relative reloc"));
+ /* Nothing needed to do. The value comes from the reloc entry */
+ break;
+
+ case BFD_RELOC_MIPS16_JMP:
+ /* We currently always generate a reloc against a symbol, which
+ means that we don't want an addend even if the symbol is
+ defined. */
+ fixP->fx_addnumber = 0;
+ break;
+
+ case BFD_RELOC_PCREL_HI16_S:
+ /* The addend for this is tricky if it is internal, so we just
+ do everything here rather than in bfd_install_relocation. */
+ if ((fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0)
+ {
+ /* For an external symbol adjust by the address to make it
+ pcrel_offset. We use the address of the RELLO reloc
+ which follows this one. */
+ value += (fixP->fx_next->fx_frag->fr_address
+ + fixP->fx_next->fx_where);
+ }
+ if (value & 0x8000)
+ value += 0x10000;
+ value >>= 16;
+ buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ buf += 2;
+ md_number_to_chars (buf, value, 2);
+ break;
+
+ case BFD_RELOC_PCREL_LO16:
+ /* The addend for this is tricky if it is internal, so we just
+ do everything here rather than in bfd_install_relocation. */
+ if ((fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0)
+ value += fixP->fx_frag->fr_address + fixP->fx_where;
+ buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ buf += 2;
+ md_number_to_chars (buf, value, 2);
+ break;
+
+ case BFD_RELOC_64:
+ /* This is handled like BFD_RELOC_32, but we output a sign
+ extended value if we are only 32 bits. */
+ if (fixP->fx_done
+ || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))
+ {
+ if (8 <= sizeof (valueT))
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 8);
+ else
+ {
+ long w1, w2;
+ long hiv;
+
+ w1 = w2 = fixP->fx_where;
+ if (target_big_endian)
+ w1 += 4;
+ else
+ w2 += 4;
+ md_number_to_chars (fixP->fx_frag->fr_literal + w1, value, 4);
+ if ((value & 0x80000000) != 0)
+ hiv = 0xffffffff;
+ else
+ hiv = 0;
+ md_number_to_chars (fixP->fx_frag->fr_literal + w2, hiv, 4);
+ }
+ }
+ break;
+
+ case BFD_RELOC_32:
+ /* If we are deleting this reloc entry, we must fill in the
+ value now. This can happen if we have a .word which is not
+ resolved when it appears but is later defined. We also need
+ to fill in the value if this is an embedded PIC switch table
+ entry. */
+ if (fixP->fx_done
+ || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 4);
+ break;
+
+ case BFD_RELOC_16:
+ /* If we are deleting this reloc entry, we must fill in the
+ value now. */
+ assert (fixP->fx_size == 2);
+ if (fixP->fx_done)
+ md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
+ value, 2);
+ break;
+
+ case BFD_RELOC_LO16:
+ /* When handling an embedded PIC switch statement, we can wind
+ up deleting a LO16 reloc. See the 'o' case in mips_ip. */
+ if (fixP->fx_done)
+ {
+ if (value < -0x8000 || value > 0x7fff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
+ if (target_big_endian)
+ buf += 2;
+ md_number_to_chars (buf, value, 2);
+ }
+ break;
+
+ case BFD_RELOC_16_PCREL_S2:
+ /*
+ * We need to save the bits in the instruction since fixup_segment()
+ * might be deleting the relocation entry (i.e., a branch within
+ * the current segment).
+ */
+ if ((value & 0x3) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch to odd address (%lx)"), value);
+ value >>= 2;
+
+ /* update old instruction data */
+ buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
+ if (target_big_endian)
+ insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ else
+ insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+
+ if (value >= -0x8000 && value < 0x8000)
+ insn |= value & 0xffff;
+ else
+ {
+ /* The branch offset is too large. If this is an
+ unconditional branch, and we are not generating PIC code,
+ we can convert it to an absolute jump instruction. */
+ if (mips_pic == NO_PIC
+ && fixP->fx_done
+ && fixP->fx_frag->fr_address >= text_section->vma
+ && (fixP->fx_frag->fr_address
+ < text_section->vma + text_section->_raw_size)
+ && ((insn & 0xffff0000) == 0x10000000 /* beq $0,$0 */
+ || (insn & 0xffff0000) == 0x04010000 /* bgez $0 */
+ || (insn & 0xffff0000) == 0x04110000)) /* bgezal $0 */
+ {
+ if ((insn & 0xffff0000) == 0x04110000) /* bgezal $0 */
+ insn = 0x0c000000; /* jal */
+ else
+ insn = 0x08000000; /* j */
+ fixP->fx_r_type = BFD_RELOC_MIPS_JMP;
+ fixP->fx_done = 0;
+ fixP->fx_addsy = section_symbol (text_section);
+ fixP->fx_addnumber = (value << 2) + md_pcrel_from (fixP);
+ }
+ else
+ {
+ /* FIXME. It would be possible in principle to handle
+ conditional branches which overflow. They could be
+ transformed into a branch around a jump. This would
+ require setting up variant frags for each different
+ branch type. The native MIPS assembler attempts to
+ handle these cases, but it appears to do it
+ incorrectly. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Branch out of range"));
+ }
+ }
+
+ md_number_to_chars ((char *) buf, (valueT) insn, 4);
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ fixP->fx_done = 0;
+ if (fixP->fx_addsy
+ && !S_IS_DEFINED (fixP->fx_addsy)
+ && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ break;
+
+ default:
+ internalError ();
+ }
+
+ return 1;
+}
+
+#if 0
+void
+printInsn (oc)
+ unsigned long oc;
+{
+ const struct mips_opcode *p;
+ int treg, sreg, dreg, shamt;
+ short imm;
+ const char *args;
+ int i;
+
+ for (i = 0; i < NUMOPCODES; ++i)
+ {
+ p = &mips_opcodes[i];
+ if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))
+ {
+ printf ("%08lx %s\t", oc, p->name);
+ treg = (oc >> 16) & 0x1f;
+ sreg = (oc >> 21) & 0x1f;
+ dreg = (oc >> 11) & 0x1f;
+ shamt = (oc >> 6) & 0x1f;
+ imm = oc;
+ for (args = p->args;; ++args)
+ {
+ switch (*args)
+ {
+ case '\0':
+ printf ("\n");
+ break;
+
+ case ',':
+ case '(':
+ case ')':
+ printf ("%c", *args);
+ continue;
+
+ case 'r':
+ assert (treg == sreg);
+ printf ("$%d,$%d", treg, sreg);
+ continue;
+
+ case 'd':
+ case 'G':
+ printf ("$%d", dreg);
+ continue;
+
+ case 't':
+ case 'E':
+ printf ("$%d", treg);
+ continue;
+
+ case 'k':
+ printf ("0x%x", treg);
+ continue;
+
+ case 'b':
+ case 's':
+ printf ("$%d", sreg);
+ continue;
+
+ case 'a':
+ printf ("0x%08lx", oc & 0x1ffffff);
+ continue;
+
+ case 'i':
+ case 'j':
+ case 'o':
+ case 'u':
+ printf ("%d", imm);
+ continue;
+
+ case '<':
+ case '>':
+ printf ("$%d", shamt);
+ continue;
+
+ default:
+ internalError ();
+ }
+ break;
+ }
+ return;
+ }
+ }
+ printf (_("%08lx UNDEFINED\n"), oc);
+}
+#endif
+
+static symbolS *
+get_symbol ()
+{
+ int c;
+ char *name;
+ symbolS *p;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = (symbolS *) symbol_find_or_make (name);
+ *input_line_pointer = c;
+ return p;
+}
+
+/* Align the current frag to a given power of two. The MIPS assembler
+ also automatically adjusts any preceding label. */
+
+static void
+mips_align (to, fill, label)
+ int to;
+ int fill;
+ symbolS *label;
+{
+ mips_emit_delays (false);
+ frag_align (to, fill, 0);
+ record_alignment (now_seg, to);
+ if (label != NULL)
+ {
+ assert (S_GET_SEGMENT (label) == now_seg);
+ label->sy_frag = frag_now;
+ S_SET_VALUE (label, (valueT) frag_now_fix ());
+ }
+}
+
+/* Align to a given power of two. .align 0 turns off the automatic
+ alignment used by the data creating pseudo-ops. */
+
+static void
+s_align (x)
+ int x;
+{
+ register int temp;
+ register long temp_fill;
+ long max_alignment = 15;
+
+ /*
+
+ o Note that the assembler pulls down any immediately preceeding label
+ to the aligned address.
+ o It's not documented but auto alignment is reinstated by
+ a .align pseudo instruction.
+ o Note also that after auto alignment is turned off the mips assembler
+ issues an error on attempt to assemble an improperly aligned data item.
+ We don't.
+
+ */
+
+ temp = get_absolute_expression ();
+ if (temp > max_alignment)
+ as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
+ else if (temp < 0)
+ {
+ as_warn (_("Alignment negative: 0 assumed."));
+ temp = 0;
+ }
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ temp_fill = get_absolute_expression ();
+ }
+ else
+ temp_fill = 0;
+ if (temp)
+ {
+ auto_align = 1;
+ mips_align (temp, (int) temp_fill,
+ insn_labels != NULL ? insn_labels->label : NULL);
+ }
+ else
+ {
+ auto_align = 0;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+mips_flush_pending_output ()
+{
+ mips_emit_delays (false);
+ mips_clear_insn_labels ();
+}
+
+static void
+s_change_sec (sec)
+ int sec;
+{
+ segT seg;
+
+ /* When generating embedded PIC code, we only use the .text, .lit8,
+ .sdata and .sbss sections. We change the .data and .rdata
+ pseudo-ops to use .sdata. */
+ if (mips_pic == EMBEDDED_PIC
+ && (sec == 'd' || sec == 'r'))
+ sec = 's';
+
+#ifdef OBJ_ELF
+ /* The ELF backend needs to know that we are changing sections, so
+ that .previous works correctly. We could do something like check
+ for a obj_section_change_hook macro, but that might be confusing
+ as it would not be appropriate to use it in the section changing
+ functions in read.c, since obj-elf.c intercepts those. FIXME:
+ This should be cleaner, somehow. */
+ obj_elf_section_change_hook ();
+#endif
+
+ mips_emit_delays (false);
+ switch (sec)
+ {
+ case 't':
+ s_text (0);
+ break;
+ case 'd':
+ s_data (0);
+ break;
+ case 'b':
+ subseg_set (bss_section, (subsegT) get_absolute_expression ());
+ demand_empty_rest_of_line ();
+ break;
+
+ case 'r':
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ seg = subseg_new (RDATA_SECTION_NAME,
+ (subsegT) get_absolute_expression ());
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ bfd_set_section_flags (stdoutput, seg,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_READONLY
+ | SEC_RELOC
+ | SEC_DATA));
+ if (strcmp (TARGET_OS, "elf") != 0)
+ bfd_set_section_alignment (stdoutput, seg, 4);
+ }
+ demand_empty_rest_of_line ();
+ }
+ else
+ {
+ as_bad (_("No read only data section in this object file format"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ break;
+
+ case 's':
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ bfd_set_section_flags (stdoutput, seg,
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA);
+ if (strcmp (TARGET_OS, "elf") != 0)
+ bfd_set_section_alignment (stdoutput, seg, 4);
+ }
+ demand_empty_rest_of_line ();
+ break;
+ }
+ else
+ {
+ as_bad (_("Global pointers not supported; recompile -G 0"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ }
+
+ auto_align = 1;
+}
+
+void
+mips_enable_auto_align ()
+{
+ auto_align = 1;
+}
+
+static void
+s_cons (log_size)
+ int log_size;
+{
+ symbolS *label;
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+ mips_emit_delays (false);
+ if (log_size > 0 && auto_align)
+ mips_align (log_size, 0, label);
+ mips_clear_insn_labels ();
+ cons (1 << log_size);
+}
+
+static void
+s_float_cons (type)
+ int type;
+{
+ symbolS *label;
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+
+ mips_emit_delays (false);
+
+ if (auto_align)
+ if (type == 'd')
+ mips_align (3, 0, label);
+ else
+ mips_align (2, 0, label);
+
+ mips_clear_insn_labels ();
+
+ float_cons (type);
+}
+
+/* Handle .globl. We need to override it because on Irix 5 you are
+ permitted to say
+ .globl foo .text
+ where foo is an undefined symbol, to mean that foo should be
+ considered to be the address of a function. */
+
+static void
+s_mips_globl (x)
+ int x;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ flagword flag;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+ /* On Irix 5, every global symbol that is not explicitly labelled as
+ being a function is apparently labelled as being an object. */
+ flag = BSF_OBJECT;
+
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *secname;
+ asection *sec;
+
+ secname = input_line_pointer;
+ c = get_symbol_end ();
+ sec = bfd_get_section_by_name (stdoutput, secname);
+ if (sec == NULL)
+ as_bad (_("%s: no such section"), secname);
+ *input_line_pointer = c;
+
+ if (sec != NULL && (sec->flags & SEC_CODE) != 0)
+ flag = BSF_FUNCTION;
+ }
+
+ symbolP->bsym->flags |= flag;
+
+ S_SET_EXTERNAL (symbolP);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_option (x)
+ int x;
+{
+ char *opt;
+ char c;
+
+ opt = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (*opt == 'O')
+ {
+ /* FIXME: What does this mean? */
+ }
+ else if (strncmp (opt, "pic", 3) == 0)
+ {
+ int i;
+
+ i = atoi (opt + 3);
+ if (i == 0)
+ mips_pic = NO_PIC;
+ else if (i == 2)
+ mips_pic = SVR4_PIC;
+ else
+ as_bad (_(".option pic%d not supported"), i);
+
+ if (USE_GLOBAL_POINTER_OPT && mips_pic == SVR4_PIC)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_warn (_("-G may not be used with SVR4 PIC code"));
+ g_switch_value = 0;
+ bfd_set_gp_size (stdoutput, 0);
+ }
+ }
+ else
+ as_warn (_("Unrecognized option \"%s\""), opt);
+
+ *input_line_pointer = c;
+ demand_empty_rest_of_line ();
+}
+
+/* This structure is used to hold a stack of .set values. */
+
+struct mips_option_stack
+{
+ struct mips_option_stack *next;
+ struct mips_set_options options;
+};
+
+static struct mips_option_stack *mips_opts_stack;
+
+/* Handle the .set pseudo-op. */
+
+static void
+s_mipsset (x)
+ int x;
+{
+ char *name = input_line_pointer, ch;
+
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (strcmp (name, "reorder") == 0)
+ {
+ if (mips_opts.noreorder && prev_nop_frag != NULL)
+ {
+ /* If we still have pending nops, we can discard them. The
+ usual nop handling will insert any that are still
+ needed. */
+ prev_nop_frag->fr_fix -= (prev_nop_frag_holds
+ * (mips_opts.mips16 ? 2 : 4));
+ prev_nop_frag = NULL;
+ }
+ mips_opts.noreorder = 0;
+ }
+ else if (strcmp (name, "noreorder") == 0)
+ {
+ mips_emit_delays (true);
+ mips_opts.noreorder = 1;
+ mips_any_noreorder = 1;
+ }
+ else if (strcmp (name, "at") == 0)
+ {
+ mips_opts.noat = 0;
+ }
+ else if (strcmp (name, "noat") == 0)
+ {
+ mips_opts.noat = 1;
+ }
+ else if (strcmp (name, "macro") == 0)
+ {
+ mips_opts.warn_about_macros = 0;
+ }
+ else if (strcmp (name, "nomacro") == 0)
+ {
+ if (mips_opts.noreorder == 0)
+ as_bad (_("`noreorder' must be set before `nomacro'"));
+ mips_opts.warn_about_macros = 1;
+ }
+ else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
+ {
+ mips_opts.nomove = 0;
+ }
+ else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
+ {
+ mips_opts.nomove = 1;
+ }
+ else if (strcmp (name, "bopt") == 0)
+ {
+ mips_opts.nobopt = 0;
+ }
+ else if (strcmp (name, "nobopt") == 0)
+ {
+ mips_opts.nobopt = 1;
+ }
+ else if (strcmp (name, "mips16") == 0
+ || strcmp (name, "MIPS-16") == 0)
+ mips_opts.mips16 = 1;
+ else if (strcmp (name, "nomips16") == 0
+ || strcmp (name, "noMIPS-16") == 0)
+ mips_opts.mips16 = 0;
+ else if (strncmp (name, "mips", 4) == 0)
+ {
+ int isa;
+
+ /* Permit the user to change the ISA on the fly. Needless to
+ say, misuse can cause serious problems. */
+ isa = atoi (name + 4);
+ if (isa == 0)
+ mips_opts.isa = file_mips_isa;
+ else if (isa < 1 || isa > 4)
+ as_bad (_("unknown ISA level"));
+ else
+ mips_opts.isa = isa;
+ }
+ else if (strcmp (name, "autoextend") == 0)
+ mips_opts.noautoextend = 0;
+ else if (strcmp (name, "noautoextend") == 0)
+ mips_opts.noautoextend = 1;
+ else if (strcmp (name, "push") == 0)
+ {
+ struct mips_option_stack *s;
+
+ s = (struct mips_option_stack *) xmalloc (sizeof *s);
+ s->next = mips_opts_stack;
+ s->options = mips_opts;
+ mips_opts_stack = s;
+ }
+ else if (strcmp (name, "pop") == 0)
+ {
+ struct mips_option_stack *s;
+
+ s = mips_opts_stack;
+ if (s == NULL)
+ as_bad (_(".set pop with no .set push"));
+ else
+ {
+ /* If we're changing the reorder mode we need to handle
+ delay slots correctly. */
+ if (s->options.noreorder && ! mips_opts.noreorder)
+ mips_emit_delays (true);
+ else if (! s->options.noreorder && mips_opts.noreorder)
+ {
+ if (prev_nop_frag != NULL)
+ {
+ prev_nop_frag->fr_fix -= (prev_nop_frag_holds
+ * (mips_opts.mips16 ? 2 : 4));
+ prev_nop_frag = NULL;
+ }
+ }
+
+ mips_opts = s->options;
+ mips_opts_stack = s->next;
+ free (s);
+ }
+ }
+ else
+ {
+ as_warn (_("Tried to set unrecognized symbol: %s\n"), name);
+ }
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .abicalls pseudo-op. I believe this is equivalent to
+ .option pic2. It means to generate SVR4 PIC calls. */
+
+static void
+s_abicalls (ignore)
+ int ignore;
+{
+ mips_pic = SVR4_PIC;
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_warn (_("-G may not be used with SVR4 PIC code"));
+ g_switch_value = 0;
+ }
+ bfd_set_gp_size (stdoutput, 0);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cpload pseudo-op. This is used when generating SVR4
+ PIC code. It sets the $gp register for the function based on the
+ function address, which is in the register named in the argument.
+ This uses a relocation against _gp_disp, which is handled specially
+ by the linker. The result is:
+ lui $gp,%hi(_gp_disp)
+ addiu $gp,$gp,%lo(_gp_disp)
+ addu $gp,$gp,.cpload argument
+ The .cpload argument is normally $25 == $t9. */
+
+static void
+s_cpload (ignore)
+ int ignore;
+{
+ expressionS ex;
+ int icnt = 0;
+
+ /* If we are not generating SVR4 PIC code, .cpload is ignored. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ /* .cpload should be a in .set noreorder section. */
+ if (mips_opts.noreorder == 0)
+ as_warn (_(".cpload not in noreorder section"));
+
+ ex.X_op = O_symbol;
+ ex.X_add_symbol = symbol_find_or_make ("_gp_disp");
+ ex.X_op_symbol = NULL;
+ ex.X_add_number = 0;
+
+ /* In ELF, this symbol is implicitly an STT_OBJECT symbol. */
+ ex.X_add_symbol->bsym->flags |= BSF_OBJECT;
+
+ macro_build_lui ((char *) NULL, &icnt, &ex, GP);
+ macro_build ((char *) NULL, &icnt, &ex, "addiu", "t,r,j", GP, GP,
+ (int) BFD_RELOC_LO16);
+
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "addu", "d,v,t",
+ GP, GP, tc_get_register (0));
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cprestore pseudo-op. This stores $gp into a given
+ offset from $sp. The offset is remembered, and after making a PIC
+ call $gp is restored from that location. */
+
+static void
+s_cprestore (ignore)
+ int ignore;
+{
+ expressionS ex;
+ int icnt = 0;
+
+ /* If we are not generating SVR4 PIC code, .cprestore is ignored. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ mips_cprestore_offset = get_absolute_expression ();
+
+ ex.X_op = O_constant;
+ ex.X_add_symbol = NULL;
+ ex.X_op_symbol = NULL;
+ ex.X_add_number = mips_cprestore_offset;
+
+ macro_build ((char *) NULL, &icnt, &ex,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "sw" : "sd"),
+ "t,o(b)", GP, (int) BFD_RELOC_LO16, SP);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .gpword pseudo-op. This is used when generating PIC
+ code. It generates a 32 bit GP relative reloc. */
+
+static void
+s_gpword (ignore)
+ int ignore;
+{
+ symbolS *label;
+ expressionS ex;
+ char *p;
+
+ /* When not generating PIC code, this is treated as .word. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_cons (2);
+ return;
+ }
+
+ label = insn_labels != NULL ? insn_labels->label : NULL;
+ mips_emit_delays (true);
+ if (auto_align)
+ mips_align (2, 0, label);
+ mips_clear_insn_labels ();
+
+ expression (&ex);
+
+ if (ex.X_op != O_symbol || ex.X_add_number != 0)
+ {
+ as_bad (_("Unsupported use of .gpword"));
+ ignore_rest_of_line ();
+ }
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 0, 4);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, 0,
+ BFD_RELOC_MIPS_GPREL32);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .cpadd pseudo-op. This is used when dealing with switch
+ tables in SVR4 PIC code. */
+
+static void
+s_cpadd (ignore)
+ int ignore;
+{
+ int icnt = 0;
+ int reg;
+
+ /* This is ignored when not generating SVR4 PIC code. */
+ if (mips_pic != SVR4_PIC)
+ {
+ s_ignore (0);
+ return;
+ }
+
+ /* Add $gp to the register named as an argument. */
+ reg = tc_get_register (0);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ ((bfd_arch_bits_per_address (stdoutput) == 32
+ || mips_opts.isa < 3)
+ ? "addu" : "daddu"),
+ "d,v,t", reg, reg, GP);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .insn pseudo-op. This marks instruction labels in
+ mips16 mode. This permits the linker to handle them specially,
+ such as generating jalx instructions when needed. We also make
+ them odd for the duration of the assembly, in order to generate the
+ right sort of code. We will make them even in the adjust_symtab
+ routine, while leaving them marked. This is convenient for the
+ debugger and the disassembler. The linker knows to make them odd
+ again. */
+
+static void
+s_insn (ignore)
+ int ignore;
+{
+ if (mips_opts.mips16)
+ mips16_mark_labels ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .stabn directive. We need these in order to mark a label
+ as being a mips16 text label correctly. Sometimes the compiler
+ will emit a label, followed by a .stabn, and then switch sections.
+ If the label and .stabn are in mips16 mode, then the label is
+ really a mips16 text label. */
+
+static void
+s_mips_stab (type)
+ int type;
+{
+ if (type == 'n' && mips_opts.mips16)
+ mips16_mark_labels ();
+
+ s_stab (type);
+}
+
+/* Handle the .weakext pseudo-op as defined in Kane and Heinrich.
+ */
+
+static void
+s_mips_weakext (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ expressionS exp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ S_SET_WEAK (symbolP);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (S_IS_DEFINED (symbolP))
+ {
+ as_bad ("Ignoring attempt to redefine symbol `%s'.",
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_bad ("bad .weakext directive");
+ ignore_rest_of_line();
+ return;
+ }
+ symbolP->sy_value = exp;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse a register string into a number. Called from the ECOFF code
+ to parse .frame. The argument is non-zero if this is the frame
+ register, so that we can record it in mips_frame_reg. */
+
+int
+tc_get_register (frame)
+ int frame;
+{
+ int reg;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != '$')
+ {
+ as_warn (_("expected `$'"));
+ reg = 0;
+ }
+ else if (isdigit ((unsigned char) *input_line_pointer))
+ {
+ reg = get_absolute_expression ();
+ if (reg < 0 || reg >= 32)
+ {
+ as_warn (_("Bad register number"));
+ reg = 0;
+ }
+ }
+ else
+ {
+ if (strncmp (input_line_pointer, "fp", 2) == 0)
+ reg = FP;
+ else if (strncmp (input_line_pointer, "sp", 2) == 0)
+ reg = SP;
+ else if (strncmp (input_line_pointer, "gp", 2) == 0)
+ reg = GP;
+ else if (strncmp (input_line_pointer, "at", 2) == 0)
+ reg = AT;
+ else
+ {
+ as_warn (_("Unrecognized register name"));
+ reg = 0;
+ }
+ input_line_pointer += 2;
+ }
+ if (frame)
+ mips_frame_reg = reg != 0 ? reg : SP;
+ return reg;
+}
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+
+#ifdef OBJ_ELF
+ /* We don't need to align ELF sections to the full alignment.
+ However, Irix 5 may prefer that we align them at least to a 16
+ byte boundary. We don't bother to align the sections if we are
+ targeted for an embedded system. */
+ if (strcmp (TARGET_OS, "elf") == 0)
+ return addr;
+ if (align > 4)
+ align = 4;
+#endif
+
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+/* Utility routine, called from above as well. If called while the
+ input file is still being read, it's only an approximation. (For
+ example, a symbol may later become defined which appeared to be
+ undefined earlier.) */
+
+static int
+nopic_need_relax (sym, before_relaxing)
+ symbolS *sym;
+ int before_relaxing;
+{
+ if (sym == 0)
+ return 0;
+
+ if (USE_GLOBAL_POINTER_OPT)
+ {
+ const char *symname;
+ int change;
+
+ /* Find out whether this symbol can be referenced off the GP
+ register. It can be if it is smaller than the -G size or if
+ it is in the .sdata or .sbss section. Certain symbols can
+ not be referenced off the GP, although it appears as though
+ they can. */
+ symname = S_GET_NAME (sym);
+ if (symname != (const char *) NULL
+ && (strcmp (symname, "eprol") == 0
+ || strcmp (symname, "etext") == 0
+ || strcmp (symname, "_gp") == 0
+ || strcmp (symname, "edata") == 0
+ || strcmp (symname, "_fbss") == 0
+ || strcmp (symname, "_fdata") == 0
+ || strcmp (symname, "_ftext") == 0
+ || strcmp (symname, "end") == 0
+ || strcmp (symname, "_gp_disp") == 0))
+ change = 1;
+ else if ((! S_IS_DEFINED (sym) || S_IS_COMMON (sym))
+ && (0
+#ifndef NO_ECOFF_DEBUGGING
+ || (sym->ecoff_extern_size != 0
+ && sym->ecoff_extern_size <= g_switch_value)
+#endif
+ /* We must defer this decision until after the whole
+ file has been read, since there might be a .extern
+ after the first use of this symbol. */
+ || (before_relaxing
+#ifndef NO_ECOFF_DEBUGGING
+ && sym->ecoff_extern_size == 0
+#endif
+ && S_GET_VALUE (sym) == 0)
+ || (S_GET_VALUE (sym) != 0
+ && S_GET_VALUE (sym) <= g_switch_value)))
+ change = 0;
+ else
+ {
+ const char *segname;
+
+ segname = segment_name (S_GET_SEGMENT (sym));
+ assert (strcmp (segname, ".lit8") != 0
+ && strcmp (segname, ".lit4") != 0);
+ change = (strcmp (segname, ".sdata") != 0
+ && strcmp (segname, ".sbss") != 0);
+ }
+ return change;
+ }
+ else
+ /* We are not optimizing for the GP register. */
+ return 1;
+}
+
+/* Given a mips16 variant frag FRAGP, return non-zero if it needs an
+ extended opcode. SEC is the section the frag is in. */
+
+static int
+mips16_extended_frag (fragp, sec, stretch)
+ fragS *fragp;
+ asection *sec;
+ long stretch;
+{
+ int type;
+ register const struct mips16_immed_operand *op;
+ offsetT val;
+ int mintiny, maxtiny;
+ segT symsec;
+
+ if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype))
+ return 0;
+ if (RELAX_MIPS16_USER_EXT (fragp->fr_subtype))
+ return 1;
+
+ type = RELAX_MIPS16_TYPE (fragp->fr_subtype);
+ op = mips16_immed_operands;
+ while (op->type != type)
+ {
+ ++op;
+ assert (op < mips16_immed_operands + MIPS16_NUM_IMMED);
+ }
+
+ if (op->unsp)
+ {
+ if (type == '<' || type == '>' || type == '[' || type == ']')
+ {
+ mintiny = 1;
+ maxtiny = 1 << op->nbits;
+ }
+ else
+ {
+ mintiny = 0;
+ maxtiny = (1 << op->nbits) - 1;
+ }
+ }
+ else
+ {
+ mintiny = - (1 << (op->nbits - 1));
+ maxtiny = (1 << (op->nbits - 1)) - 1;
+ }
+
+ /* We can't call S_GET_VALUE here, because we don't want to lock in
+ a particular frag address. */
+ if (fragp->fr_symbol->sy_value.X_op == O_constant)
+ {
+ val = (fragp->fr_symbol->sy_value.X_add_number
+ + fragp->fr_symbol->sy_frag->fr_address);
+ symsec = S_GET_SEGMENT (fragp->fr_symbol);
+ }
+ else if (fragp->fr_symbol->sy_value.X_op == O_symbol
+ && (fragp->fr_symbol->sy_value.X_add_symbol->sy_value.X_op
+ == O_constant))
+ {
+ val = (fragp->fr_symbol->sy_value.X_add_symbol->sy_value.X_add_number
+ + fragp->fr_symbol->sy_value.X_add_symbol->sy_frag->fr_address
+ + fragp->fr_symbol->sy_value.X_add_number
+ + fragp->fr_symbol->sy_frag->fr_address);
+ symsec = S_GET_SEGMENT (fragp->fr_symbol->sy_value.X_add_symbol);
+ }
+ else
+ return 1;
+
+ if (op->pcrel)
+ {
+ addressT addr;
+
+ /* We won't have the section when we are called from
+ mips_relax_frag. However, we will always have been called
+ from md_estimate_size_before_relax first. If this is a
+ branch to a different section, we mark it as such. If SEC is
+ NULL, and the frag is not marked, then it must be a branch to
+ the same section. */
+ if (sec == NULL)
+ {
+ if (RELAX_MIPS16_LONG_BRANCH (fragp->fr_subtype))
+ return 1;
+ }
+ else
+ {
+ if (symsec != sec)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+
+ /* FIXME: We should support this, and let the linker
+ catch branches and loads that are out of range. */
+ as_bad_where (fragp->fr_file, fragp->fr_line,
+ _("unsupported PC relative reference to different section"));
+
+ return 1;
+ }
+ }
+
+ /* In this case, we know for sure that the symbol fragment is in
+ the same section. If the fr_address of the symbol fragment
+ is greater then the address of this fragment we want to add
+ in STRETCH in order to get a better estimate of the address.
+ This particularly matters because of the shift bits. */
+ if (stretch != 0
+ && fragp->fr_symbol->sy_frag->fr_address >= fragp->fr_address)
+ {
+ fragS *f;
+
+ /* Adjust stretch for any alignment frag. Note that if have
+ been expanding the earlier code, the symbol may be
+ defined in what appears to be an earlier frag. FIXME:
+ This doesn't handle the fr_subtype field, which specifies
+ a maximum number of bytes to skip when doing an
+ alignment. */
+ for (f = fragp;
+ f != NULL && f != fragp->fr_symbol->sy_frag;
+ f = f->fr_next)
+ {
+ if (f->fr_type == rs_align || f->fr_type == rs_align_code)
+ {
+ if (stretch < 0)
+ stretch = - ((- stretch)
+ & ~ ((1 << (int) f->fr_offset) - 1));
+ else
+ stretch &= ~ ((1 << (int) f->fr_offset) - 1);
+ if (stretch == 0)
+ break;
+ }
+ }
+ if (f != NULL)
+ val += stretch;
+ }
+
+ addr = fragp->fr_address + fragp->fr_fix;
+
+ /* The base address rules are complicated. The base address of
+ a branch is the following instruction. The base address of a
+ PC relative load or add is the instruction itself, but if it
+ is in a delay slot (in which case it can not be extended) use
+ the address of the instruction whose delay slot it is in. */
+ if (type == 'p' || type == 'q')
+ {
+ addr += 2;
+
+ /* If we are currently assuming that this frag should be
+ extended, then, the current address is two bytes
+ higher. */
+ if (RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ addr += 2;
+
+ /* Ignore the low bit in the target, since it will be set
+ for a text label. */
+ if ((val & 1) != 0)
+ --val;
+ }
+ else if (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype))
+ addr -= 4;
+ else if (RELAX_MIPS16_DSLOT (fragp->fr_subtype))
+ addr -= 2;
+
+ val -= addr & ~ ((1 << op->shift) - 1);
+
+ /* Branch offsets have an implicit 0 in the lowest bit. */
+ if (type == 'p' || type == 'q')
+ val /= 2;
+
+ /* If any of the shifted bits are set, we must use an extended
+ opcode. If the address depends on the size of this
+ instruction, this can lead to a loop, so we arrange to always
+ use an extended opcode. We only check this when we are in
+ the main relaxation loop, when SEC is NULL. */
+ if ((val & ((1 << op->shift) - 1)) != 0 && sec == NULL)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+ return 1;
+ }
+
+ /* If we are about to mark a frag as extended because the value
+ is precisely maxtiny + 1, then there is a chance of an
+ infinite loop as in the following code:
+ la $4,foo
+ .skip 1020
+ .align 2
+ foo:
+ In this case when the la is extended, foo is 0x3fc bytes
+ away, so the la can be shrunk, but then foo is 0x400 away, so
+ the la must be extended. To avoid this loop, we mark the
+ frag as extended if it was small, and is about to become
+ extended with a value of maxtiny + 1. */
+ if (val == ((maxtiny + 1) << op->shift)
+ && ! RELAX_MIPS16_EXTENDED (fragp->fr_subtype)
+ && sec == NULL)
+ {
+ fragp->fr_subtype =
+ RELAX_MIPS16_MARK_LONG_BRANCH (fragp->fr_subtype);
+ return 1;
+ }
+ }
+ else if (symsec != absolute_section && sec != NULL)
+ as_bad_where (fragp->fr_file, fragp->fr_line, _("unsupported relocation"));
+
+ if ((val & ((1 << op->shift) - 1)) != 0
+ || val < (mintiny << op->shift)
+ || val > (maxtiny << op->shift))
+ return 1;
+ else
+ return 0;
+}
+
+/* Estimate the size of a frag before relaxing. Unless this is the
+ mips16, we are not really relaxing here, and the final size is
+ encoded in the subtype information. For the mips16, we have to
+ decide whether we are using an extended opcode or not. */
+
+/*ARGSUSED*/
+int
+md_estimate_size_before_relax (fragp, segtype)
+ fragS *fragp;
+ asection *segtype;
+{
+ int change;
+
+ if (RELAX_MIPS16_P (fragp->fr_subtype))
+ {
+ if (mips16_extended_frag (fragp, segtype, 0))
+ {
+ fragp->fr_subtype = RELAX_MIPS16_MARK_EXTENDED (fragp->fr_subtype);
+ return 4;
+ }
+ else
+ {
+ fragp->fr_subtype = RELAX_MIPS16_CLEAR_EXTENDED (fragp->fr_subtype);
+ return 2;
+ }
+ }
+
+ if (mips_pic == NO_PIC)
+ {
+ change = nopic_need_relax (fragp->fr_symbol, 0);
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ symbolS *sym;
+ asection *symsec;
+
+ sym = fragp->fr_symbol;
+
+ /* Handle the case of a symbol equated to another symbol. */
+ while (sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ {
+ symbolS *n;
+
+ /* It's possible to get a loop here in a badly written
+ program. */
+ n = sym->sy_value.X_add_symbol;
+ if (n == sym)
+ break;
+ sym = n;
+ }
+
+ symsec = S_GET_SEGMENT (sym);
+
+ /* This must duplicate the test in adjust_reloc_syms. */
+ change = (symsec != &bfd_und_section
+ && symsec != &bfd_abs_section
+ && ! bfd_is_com_section (symsec));
+ }
+ else
+ abort ();
+
+ if (change)
+ {
+ /* Record the offset to the first reloc in the fr_opcode field.
+ This lets md_convert_frag and tc_gen_reloc know that the code
+ must be expanded. */
+ fragp->fr_opcode = (fragp->fr_literal
+ + fragp->fr_fix
+ - RELAX_OLD (fragp->fr_subtype)
+ + RELAX_RELOC1 (fragp->fr_subtype));
+ /* FIXME: This really needs as_warn_where. */
+ if (RELAX_WARN (fragp->fr_subtype))
+ as_warn (_("AT used after \".set noat\" or macro used after \".set nomacro\""));
+ }
+
+ if (! change)
+ return 0;
+ else
+ return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
+}
+
+/* This is called to see whether a reloc against a defined symbol
+ should be converted into a reloc against a section. Don't adjust
+ MIPS16 jump relocations, so we don't have to worry about the format
+ of the offset in the .o file. Don't adjust relocations against
+ mips16 symbols, so that the linker can find them if it needs to set
+ up a stub. */
+
+int
+mips_fix_adjustable (fixp)
+ fixS *fixp;
+{
+ if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
+ return 0;
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+ if (fixp->fx_addsy == NULL)
+ return 1;
+#ifdef OBJ_ELF
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
+ && fixp->fx_subsy == NULL)
+ return 0;
+#endif
+ return 1;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+
+arelent **
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ static arelent *retval[4];
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ reloc = retval[0] = (arelent *) xmalloc (sizeof (arelent));
+ retval[1] = NULL;
+
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ if (mips_pic == EMBEDDED_PIC
+ && SWITCH_TABLE (fixp))
+ {
+ /* For a switch table entry we use a special reloc. The addend
+ is actually the difference between the reloc address and the
+ subtrahend. */
+ reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+ if (OUTPUT_FLAVOR != bfd_target_ecoff_flavour)
+ as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc"));
+ fixp->fx_r_type = BFD_RELOC_GPREL32;
+ }
+ else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16)
+ {
+ /* We use a special addend for an internal RELLO reloc. */
+ if (fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM)
+ reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+ else
+ reloc->addend = fixp->fx_addnumber + reloc->address;
+ }
+ else if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
+ {
+ assert (fixp->fx_next != NULL
+ && fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16);
+ /* We use a special addend for an internal RELHI reloc. The
+ reloc is relative to the RELLO; adjust the addend
+ accordingly. */
+ if (fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM)
+ reloc->addend = (fixp->fx_next->fx_frag->fr_address
+ + fixp->fx_next->fx_where
+ - S_GET_VALUE (fixp->fx_subsy));
+ else
+ reloc->addend = (fixp->fx_addnumber
+ + fixp->fx_next->fx_frag->fr_address
+ + fixp->fx_next->fx_where);
+ }
+ else if (fixp->fx_pcrel == 0)
+ reloc->addend = fixp->fx_addnumber;
+ else
+ {
+ if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
+ /* A gruesome hack which is a result of the gruesome gas reloc
+ handling. */
+ reloc->addend = reloc->address;
+ else
+ reloc->addend = -reloc->address;
+ }
+
+ /* If this is a variant frag, we may need to adjust the existing
+ reloc and generate a new one. */
+ if (fixp->fx_frag->fr_opcode != NULL
+ && (fixp->fx_r_type == BFD_RELOC_MIPS_GPREL
+ || fixp->fx_r_type == BFD_RELOC_MIPS_GOT16
+ || fixp->fx_r_type == BFD_RELOC_MIPS_CALL16
+ || fixp->fx_r_type == BFD_RELOC_MIPS_GOT_HI16
+ || fixp->fx_r_type == BFD_RELOC_MIPS_GOT_LO16
+ || fixp->fx_r_type == BFD_RELOC_MIPS_CALL_HI16
+ || fixp->fx_r_type == BFD_RELOC_MIPS_CALL_LO16))
+ {
+ arelent *reloc2;
+
+ assert (! RELAX_MIPS16_P (fixp->fx_frag->fr_subtype));
+
+ /* If this is not the last reloc in this frag, then we have two
+ GPREL relocs, or a GOT_HI16/GOT_LO16 pair, or a
+ CALL_HI16/CALL_LO16, both of which are being replaced. Let
+ the second one handle all of them. */
+ if (fixp->fx_next != NULL
+ && fixp->fx_frag == fixp->fx_next->fx_frag)
+ {
+ assert ((fixp->fx_r_type == BFD_RELOC_MIPS_GPREL
+ && fixp->fx_next->fx_r_type == BFD_RELOC_MIPS_GPREL)
+ || (fixp->fx_r_type == BFD_RELOC_MIPS_GOT_HI16
+ && (fixp->fx_next->fx_r_type
+ == BFD_RELOC_MIPS_GOT_LO16))
+ || (fixp->fx_r_type == BFD_RELOC_MIPS_CALL_HI16
+ && (fixp->fx_next->fx_r_type
+ == BFD_RELOC_MIPS_CALL_LO16)));
+ retval[0] = NULL;
+ return retval;
+ }
+
+ fixp->fx_where = fixp->fx_frag->fr_opcode - fixp->fx_frag->fr_literal;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc2 = retval[1] = (arelent *) xmalloc (sizeof (arelent));
+ retval[2] = NULL;
+ reloc2->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc2->address = (reloc->address
+ + (RELAX_RELOC2 (fixp->fx_frag->fr_subtype)
+ - RELAX_RELOC1 (fixp->fx_frag->fr_subtype)));
+ reloc2->addend = fixp->fx_addnumber;
+ reloc2->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
+ assert (reloc2->howto != NULL);
+
+ if (RELAX_RELOC3 (fixp->fx_frag->fr_subtype))
+ {
+ arelent *reloc3;
+
+ reloc3 = retval[2] = (arelent *) xmalloc (sizeof (arelent));
+ retval[3] = NULL;
+ *reloc3 = *reloc2;
+ reloc3->address += 4;
+ }
+
+ if (mips_pic == NO_PIC)
+ {
+ assert (fixp->fx_r_type == BFD_RELOC_MIPS_GPREL);
+ fixp->fx_r_type = BFD_RELOC_HI16_S;
+ }
+ else if (mips_pic == SVR4_PIC)
+ {
+ switch (fixp->fx_r_type)
+ {
+ default:
+ abort ();
+ case BFD_RELOC_MIPS_GOT16:
+ break;
+ case BFD_RELOC_MIPS_CALL16:
+ case BFD_RELOC_MIPS_GOT_LO16:
+ case BFD_RELOC_MIPS_CALL_LO16:
+ fixp->fx_r_type = BFD_RELOC_MIPS_GOT16;
+ break;
+ }
+ }
+ else
+ abort ();
+ }
+
+ /* Since MIPS ELF uses Rel instead of Rela, encode the vtable entry
+ to be used in the relocation's section offset. */
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ reloc->address = reloc->addend;
+ reloc->addend = 0;
+ }
+
+ /* Since DIFF_EXPR_OK is defined in tc-mips.h, it is possible that
+ fixup_segment converted a non-PC relative reloc into a PC
+ relative reloc. In such a case, we need to convert the reloc
+ code. */
+ code = fixp->fx_r_type;
+ if (fixp->fx_pcrel)
+ {
+ switch (code)
+ {
+ case BFD_RELOC_8:
+ code = BFD_RELOC_8_PCREL;
+ break;
+ case BFD_RELOC_16:
+ code = BFD_RELOC_16_PCREL;
+ break;
+ case BFD_RELOC_32:
+ code = BFD_RELOC_32_PCREL;
+ break;
+ case BFD_RELOC_64:
+ code = BFD_RELOC_64_PCREL;
+ break;
+ case BFD_RELOC_8_PCREL:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_64_PCREL:
+ case BFD_RELOC_16_PCREL_S2:
+ case BFD_RELOC_PCREL_HI16_S:
+ case BFD_RELOC_PCREL_LO16:
+ break;
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot make %s relocation PC relative"),
+ bfd_get_reloc_code_name (code));
+ }
+ }
+
+ /* To support a PC relative reloc when generating embedded PIC code
+ for ECOFF, we use a Cygnus extension. We check for that here to
+ make sure that we don't let such a reloc escape normally. */
+ if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ && code == BFD_RELOC_16_PCREL_S2
+ && mips_pic != EMBEDDED_PIC)
+ reloc->howto = NULL;
+ else
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+
+ if (reloc->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Can not represent %s relocation in this object file format"),
+ bfd_get_reloc_code_name (code));
+ retval[0] = NULL;
+ }
+
+ return retval;
+}
+
+/* Relax a machine dependent frag. This returns the amount by which
+ the current size of the frag should change. */
+
+int
+mips_relax_frag (fragp, stretch)
+ fragS *fragp;
+ long stretch;
+{
+ if (! RELAX_MIPS16_P (fragp->fr_subtype))
+ return 0;
+
+ if (mips16_extended_frag (fragp, (asection *) NULL, stretch))
+ {
+ if (RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ return 0;
+ fragp->fr_subtype = RELAX_MIPS16_MARK_EXTENDED (fragp->fr_subtype);
+ return 2;
+ }
+ else
+ {
+ if (! RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ return 0;
+ fragp->fr_subtype = RELAX_MIPS16_CLEAR_EXTENDED (fragp->fr_subtype);
+ return -2;
+ }
+
+ return 0;
+}
+
+/* Convert a machine dependent frag. */
+
+void
+md_convert_frag (abfd, asec, fragp)
+ bfd *abfd;
+ segT asec;
+ fragS *fragp;
+{
+ int old, new;
+ char *fixptr;
+
+ if (RELAX_MIPS16_P (fragp->fr_subtype))
+ {
+ int type;
+ register const struct mips16_immed_operand *op;
+ boolean small, ext;
+ offsetT val;
+ bfd_byte *buf;
+ unsigned long insn;
+ boolean use_extend;
+ unsigned short extend;
+
+ type = RELAX_MIPS16_TYPE (fragp->fr_subtype);
+ op = mips16_immed_operands;
+ while (op->type != type)
+ ++op;
+
+ if (RELAX_MIPS16_EXTENDED (fragp->fr_subtype))
+ {
+ small = false;
+ ext = true;
+ }
+ else
+ {
+ small = true;
+ ext = false;
+ }
+
+ resolve_symbol_value (fragp->fr_symbol, 1);
+ val = S_GET_VALUE (fragp->fr_symbol);
+ if (op->pcrel)
+ {
+ addressT addr;
+
+ addr = fragp->fr_address + fragp->fr_fix;
+
+ /* The rules for the base address of a PC relative reloc are
+ complicated; see mips16_extended_frag. */
+ if (type == 'p' || type == 'q')
+ {
+ addr += 2;
+ if (ext)
+ addr += 2;
+ /* Ignore the low bit in the target, since it will be
+ set for a text label. */
+ if ((val & 1) != 0)
+ --val;
+ }
+ else if (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype))
+ addr -= 4;
+ else if (RELAX_MIPS16_DSLOT (fragp->fr_subtype))
+ addr -= 2;
+
+ addr &= ~ (addressT) ((1 << op->shift) - 1);
+ val -= addr;
+
+ /* Make sure the section winds up with the alignment we have
+ assumed. */
+ if (op->shift > 0)
+ record_alignment (asec, op->shift);
+ }
+
+ if (ext
+ && (RELAX_MIPS16_JAL_DSLOT (fragp->fr_subtype)
+ || RELAX_MIPS16_DSLOT (fragp->fr_subtype)))
+ as_warn_where (fragp->fr_file, fragp->fr_line,
+ _("extended instruction in delay slot"));
+
+ buf = (bfd_byte *) (fragp->fr_literal + fragp->fr_fix);
+
+ if (target_big_endian)
+ insn = bfd_getb16 (buf);
+ else
+ insn = bfd_getl16 (buf);
+
+ mips16_immed (fragp->fr_file, fragp->fr_line, type, val,
+ RELAX_MIPS16_USER_EXT (fragp->fr_subtype),
+ small, ext, &insn, &use_extend, &extend);
+
+ if (use_extend)
+ {
+ md_number_to_chars (buf, 0xf000 | extend, 2);
+ fragp->fr_fix += 2;
+ buf += 2;
+ }
+
+ md_number_to_chars (buf, insn, 2);
+ fragp->fr_fix += 2;
+ buf += 2;
+ }
+ else
+ {
+ if (fragp->fr_opcode == NULL)
+ return;
+
+ old = RELAX_OLD (fragp->fr_subtype);
+ new = RELAX_NEW (fragp->fr_subtype);
+ fixptr = fragp->fr_literal + fragp->fr_fix;
+
+ if (new > 0)
+ memcpy (fixptr - old, fixptr, new);
+
+ fragp->fr_fix += new - old;
+ }
+}
+
+#ifdef OBJ_ELF
+
+/* This function is called after the relocs have been generated.
+ We've been storing mips16 text labels as odd. Here we convert them
+ back to even for the convenience of the debugger. */
+
+void
+mips_frob_file_after_relocs ()
+{
+ asymbol **syms;
+ unsigned int count, i;
+
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ return;
+
+ syms = bfd_get_outsymbols (stdoutput);
+ count = bfd_get_symcount (stdoutput);
+ for (i = 0; i < count; i++, syms++)
+ {
+ if (elf_symbol (*syms)->internal_elf_sym.st_other == STO_MIPS16
+ && ((*syms)->value & 1) != 0)
+ {
+ (*syms)->value &= ~1;
+ /* If the symbol has an odd size, it was probably computed
+ incorrectly, so adjust that as well. */
+ if ((elf_symbol (*syms)->internal_elf_sym.st_size & 1) != 0)
+ ++elf_symbol (*syms)->internal_elf_sym.st_size;
+ }
+ }
+}
+
+#endif
+
+/* This function is called whenever a label is defined. It is used
+ when handling branch delays; if a branch has a label, we assume we
+ can not move it. */
+
+void
+mips_define_label (sym)
+ symbolS *sym;
+{
+ struct insn_label_list *l;
+
+ if (free_insn_labels == NULL)
+ l = (struct insn_label_list *) xmalloc (sizeof *l);
+ else
+ {
+ l = free_insn_labels;
+ free_insn_labels = l->next;
+ }
+
+ l->label = sym;
+ l->next = insn_labels;
+ insn_labels = l;
+}
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+
+/* Some special processing for a MIPS ELF file. */
+
+void
+mips_elf_final_processing ()
+{
+ /* Write out the register information. */
+ if (! mips_64)
+ {
+ Elf32_RegInfo s;
+
+ s.ri_gprmask = mips_gprmask;
+ s.ri_cprmask[0] = mips_cprmask[0];
+ s.ri_cprmask[1] = mips_cprmask[1];
+ s.ri_cprmask[2] = mips_cprmask[2];
+ s.ri_cprmask[3] = mips_cprmask[3];
+ /* The gp_value field is set by the MIPS ELF backend. */
+
+ bfd_mips_elf32_swap_reginfo_out (stdoutput, &s,
+ ((Elf32_External_RegInfo *)
+ mips_regmask_frag));
+ }
+ else
+ {
+ Elf64_Internal_RegInfo s;
+
+ s.ri_gprmask = mips_gprmask;
+ s.ri_pad = 0;
+ s.ri_cprmask[0] = mips_cprmask[0];
+ s.ri_cprmask[1] = mips_cprmask[1];
+ s.ri_cprmask[2] = mips_cprmask[2];
+ s.ri_cprmask[3] = mips_cprmask[3];
+ /* The gp_value field is set by the MIPS ELF backend. */
+
+ bfd_mips_elf64_swap_reginfo_out (stdoutput, &s,
+ ((Elf64_External_RegInfo *)
+ mips_regmask_frag));
+ }
+
+ /* Set the MIPS ELF flag bits. FIXME: There should probably be some
+ sort of BFD interface for this. */
+ if (mips_any_noreorder)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_NOREORDER;
+ if (mips_pic != NO_PIC)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_PIC;
+
+ /* Set the MIPS ELF ABI flags. */
+ if (mips_abi_string == 0)
+ ;
+ else if (strcmp (mips_abi_string,"32") == 0)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32;
+ else if (strcmp (mips_abi_string,"o64") == 0)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64;
+ else if (strcmp (mips_abi_string,"eabi") == 0)
+ {
+ if (mips_eabi64)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64;
+ else
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
+ }
+
+ if (mips_32bitmode)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
+}
+
+#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+
+typedef struct proc
+ {
+ struct symbol *isym;
+ unsigned long reg_mask;
+ unsigned long reg_offset;
+ unsigned long fpreg_mask;
+ unsigned long fpreg_offset;
+ unsigned long frame_offset;
+ unsigned long frame_reg;
+ unsigned long pc_reg;
+ }
+procS;
+
+static procS cur_proc;
+static procS *cur_proc_ptr;
+static int numprocs;
+
+static void
+md_obj_begin ()
+{
+}
+
+static void
+md_obj_end ()
+{
+ /* check for premature end, nesting errors, etc */
+ if (cur_proc_ptr)
+ as_warn (_("missing `.end' at end of assembly"));
+}
+
+static long
+get_number ()
+{
+ int negative = 0;
+ long val = 0;
+
+ if (*input_line_pointer == '-')
+ {
+ ++input_line_pointer;
+ negative = 1;
+ }
+ if (!isdigit (*input_line_pointer))
+ as_bad (_("Expected simple number."));
+ if (input_line_pointer[0] == '0')
+ {
+ if (input_line_pointer[1] == 'x')
+ {
+ input_line_pointer += 2;
+ while (isxdigit (*input_line_pointer))
+ {
+ val <<= 4;
+ val |= hex_value (*input_line_pointer++);
+ }
+ return negative ? -val : val;
+ }
+ else
+ {
+ ++input_line_pointer;
+ while (isdigit (*input_line_pointer))
+ {
+ val <<= 3;
+ val |= *input_line_pointer++ - '0';
+ }
+ return negative ? -val : val;
+ }
+ }
+ if (!isdigit (*input_line_pointer))
+ {
+ printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
+ *input_line_pointer, *input_line_pointer);
+ as_warn (_("Invalid number"));
+ return -1;
+ }
+ while (isdigit (*input_line_pointer))
+ {
+ val *= 10;
+ val += *input_line_pointer++ - '0';
+ }
+ return negative ? -val : val;
+}
+
+/* The .file directive; just like the usual .file directive, but there
+ is an initial number which is the ECOFF file index. */
+
+static void
+s_file (x)
+ int x;
+{
+ int line;
+
+ line = get_number ();
+ s_app_file (0);
+}
+
+
+/* The .end directive. */
+
+static void
+s_mips_end (x)
+ int x;
+{
+ symbolS *p;
+ int maybe_text;
+
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ p = get_symbol ();
+ demand_empty_rest_of_line ();
+ }
+ else
+ p = NULL;
+
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#else
+ if (now_seg != data_section && now_seg != bss_section)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#endif
+
+ if (!maybe_text)
+ as_warn (_(".end not in text section"));
+
+ if (!cur_proc_ptr)
+ {
+ as_warn (_(".end directive without a preceding .ent directive."));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (p != NULL)
+ {
+ assert (S_GET_NAME (p));
+ if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
+ as_warn (_(".end symbol does not match .ent symbol."));
+ }
+ else
+ as_warn (_(".end directive missing or unknown symbol"));
+
+#ifdef MIPS_STABS_ELF
+ {
+ segT saved_seg = now_seg;
+ subsegT saved_subseg = now_subseg;
+ fragS *saved_frag = frag_now;
+ valueT dot;
+ segT seg;
+ expressionS exp;
+ char *fragp;
+
+ dot = frag_now_fix ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ assert (pdr_seg);
+ subseg_set (pdr_seg, 0);
+
+ /* Write the symbol */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = p;
+ exp.X_add_number = 0;
+ emit_expr (&exp, 4);
+
+ fragp = frag_more (7*4);
+
+ md_number_to_chars (fragp, (valueT) cur_proc_ptr->reg_mask, 4);
+ md_number_to_chars (fragp + 4, (valueT) cur_proc_ptr->reg_offset, 4);
+ md_number_to_chars (fragp + 8, (valueT) cur_proc_ptr->fpreg_mask, 4);
+ md_number_to_chars (fragp +12, (valueT) cur_proc_ptr->fpreg_offset, 4);
+ md_number_to_chars (fragp +16, (valueT) cur_proc_ptr->frame_offset, 4);
+ md_number_to_chars (fragp +20, (valueT) cur_proc_ptr->frame_reg, 4);
+ md_number_to_chars (fragp +24, (valueT) cur_proc_ptr->pc_reg, 4);
+
+ subseg_set (saved_seg, saved_subseg);
+ }
+#endif
+
+ cur_proc_ptr = NULL;
+}
+
+/* The .aent and .ent directives. */
+
+static void
+s_mips_ent (aent)
+ int aent;
+{
+ int number = 0;
+ symbolS *symbolP;
+ int maybe_text;
+
+ symbolP = get_symbol ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
+ number = get_number ();
+
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#else
+ if (now_seg != data_section && now_seg != bss_section)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#endif
+
+ if (!maybe_text)
+ as_warn (_(".ent or .aent not in text section."));
+
+ if (!aent && cur_proc_ptr)
+ as_warn (_("missing `.end'"));
+
+ if (!aent)
+ {
+ cur_proc_ptr = &cur_proc;
+ memset (cur_proc_ptr, '\0', sizeof (procS));
+
+ cur_proc_ptr->isym = symbolP;
+
+ symbolP->bsym->flags |= BSF_FUNCTION;
+
+ numprocs++;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .frame directive. If the mdebug section is present (IRIX 5 native)
+ then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
+ s_mips_frame is used so that we can set the PDR information correctly.
+ We can't use the ecoff routines because they make reference to the ecoff
+ symbol table (in the mdebug section). */
+
+static void
+s_mips_frame (ignore)
+ int ignore;
+{
+#ifdef MIPS_STABS_ELF
+
+ long val;
+
+ if (cur_proc_ptr == (procS *) NULL)
+ {
+ as_warn (_(".frame outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->frame_reg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .frame directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->frame_offset = val;
+ cur_proc_ptr->pc_reg = tc_get_register (0);
+
+ demand_empty_rest_of_line ();
+#else
+ s_ignore (ignore);
+#endif /* MIPS_STABS_ELF */
+}
+
+/* The .fmask and .mask directives. If the mdebug section is present
+ (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
+ embedded targets, s_mips_mask is used so that we can set the PDR
+ information correctly. We can't use the ecoff routines because they
+ make reference to the ecoff symbol table (in the mdebug section). */
+
+static void
+s_mips_mask (reg_type)
+ char reg_type;
+{
+#ifdef MIPS_STABS_ELF
+ long mask, off;
+
+ if (cur_proc_ptr == (procS *) NULL)
+ {
+ as_warn (_(".mask/.fmask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&mask) != ',')
+ {
+ as_warn (_("Bad .mask/.fmask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ off = get_absolute_expression ();
+
+ if (reg_type == 'F')
+ {
+ cur_proc_ptr->fpreg_mask = mask;
+ cur_proc_ptr->fpreg_offset = off;
+ }
+ else
+ {
+ cur_proc_ptr->reg_mask = mask;
+ cur_proc_ptr->reg_offset = off;
+ }
+
+ demand_empty_rest_of_line ();
+#else
+ s_ignore (reg_type);
+#endif /* MIPS_STABS_ELF */
+}
+
+/* The .loc directive. */
+
+#if 0
+static void
+s_loc (x)
+ int x;
+{
+ symbolS *symbolP;
+ int lineno;
+ int addroff;
+
+ assert (now_seg == text_section);
+
+ lineno = get_number ();
+ addroff = frag_now_fix ();
+
+ symbolP = symbol_new ("", N_SLINE, addroff, frag_now);
+ S_SET_TYPE (symbolP, N_SLINE);
+ S_SET_OTHER (symbolP, 0);
+ S_SET_DESC (symbolP, lineno);
+ symbolP->sy_segment = now_seg;
+}
+#endif
+
+
+
diff --git a/gas/config/tc-mips.h b/gas/config/tc-mips.h
new file mode 100644
index 00000000000..868aedea6a5
--- /dev/null
+++ b/gas/config/tc-mips.h
@@ -0,0 +1,153 @@
+/* tc-mips.h -- header file for tc-mips.c.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by the OSF and Ralph Campbell.
+ Written by Keith Knowles and Ralph Campbell, working independently.
+ Modified for ECOFF support by Ian Lance Taylor of Cygnus Support.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef TC_MIPS
+
+#define TC_MIPS
+
+#ifdef ANSI_PROTOTYPES
+struct frag;
+struct expressionS;
+#endif
+
+/* Default to big endian. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
+
+#define TARGET_ARCH bfd_arch_mips
+
+#define ONLY_STANDARD_ESCAPES
+#define WORKING_DOT_WORD 1
+#define OLD_FLOAT_READS
+#define REPEAT_CONS_EXPRESSIONS
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 3
+#define LOCAL_LABELS_FB 1
+
+/* Maximum symbol offset that can be encoded in a BFD_RELOC_MIPS_GPREL
+ relocation: */
+#define MAX_GPREL_OFFSET (0x7FF4)
+
+#define md_relax_frag(fragp, stretch) mips_relax_frag(fragp, stretch)
+extern int mips_relax_frag PARAMS ((struct frag *, long));
+
+#define md_undefined_symbol(name) (0)
+#define md_operand(x)
+
+/* We permit PC relative difference expressions when generating
+ embedded PIC code. */
+#define DIFF_EXPR_OK
+
+/* Tell assembler that we have an itbl_mips.h header file to include. */
+#define HAVE_ITBL_CPU
+
+/* The endianness of the target format may change based on command
+ line arguments. */
+#define TARGET_FORMAT mips_target_format()
+extern const char *mips_target_format PARAMS ((void));
+
+struct mips_cl_insn
+{
+ unsigned long insn_opcode;
+ const struct mips_opcode *insn_mo;
+ /* The next two fields are used when generating mips16 code. */
+ boolean use_extend;
+ unsigned short extend;
+};
+
+extern int tc_get_register PARAMS ((int frame));
+
+#define tc_init_after_args() mips_init_after_args()
+extern void mips_init_after_args PARAMS ((void));
+
+#define md_parse_long_option(arg) mips_parse_long_option (arg)
+extern int mips_parse_long_option PARAMS ((const char *));
+
+#define tc_frob_label(sym) mips_define_label (sym)
+extern void mips_define_label PARAMS ((struct symbol *));
+
+#define tc_frob_file_before_adjust() mips_frob_file_before_adjust ()
+extern void mips_frob_file_before_adjust PARAMS ((void));
+
+#define tc_frob_file() mips_frob_file ()
+extern void mips_frob_file PARAMS ((void));
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+#define tc_frob_file_after_relocs mips_frob_file_after_relocs
+extern void mips_frob_file_after_relocs PARAMS ((void));
+#endif
+
+#define TC_CONS_FIX_NEW cons_fix_new_mips
+extern void cons_fix_new_mips
+ PARAMS ((struct frag *, int, unsigned int, struct expressionS *));
+
+#define tc_fix_adjustable(fixp) mips_fix_adjustable (fixp)
+extern int mips_fix_adjustable PARAMS ((struct fix *));
+
+/* When generating embedded PIC code we must keep PC relative
+ relocations. */
+#define TC_FORCE_RELOCATION(fixp) mips_force_relocation (fixp)
+extern int mips_force_relocation PARAMS ((struct fix *));
+
+/* md_apply_fix sets fx_done correctly. */
+#define TC_HANDLE_FX_DONE 1
+
+/* Register mask variables. These are set by the MIPS assembly code
+ and used by ECOFF and possibly other object file formats. */
+extern unsigned long mips_gprmask;
+extern unsigned long mips_cprmask[4];
+
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+
+#define elf_tc_final_processing mips_elf_final_processing
+extern void mips_elf_final_processing PARAMS ((void));
+
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, \
+ { ".lit4", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, \
+ { ".lit8", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL }, \
+ { ".ucode", SHT_MIPS_UCODE, 0 }, \
+ { ".mdebug", SHT_MIPS_DEBUG, 0 },
+/* Other special sections not generated by the assembler: .reginfo,
+ .liblist, .conflict, .gptab, .got, .dynamic, .rel.dyn. */
+
+#endif
+
+extern void md_mips_end PARAMS ((void));
+#define md_end() md_mips_end()
+
+#define USE_GLOBAL_POINTER_OPT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+
+extern void mips_pop_insert PARAMS ((void));
+#define md_pop_insert() mips_pop_insert()
+
+extern void mips_flush_pending_output PARAMS ((void));
+#define md_flush_pending_output mips_flush_pending_output
+
+extern void mips_enable_auto_align PARAMS ((void));
+#define md_elf_section_change_hook() mips_enable_auto_align()
+
+#endif /* TC_MIPS */
diff --git a/gas/config/tc-mn10200.c b/gas/config/tc-mn10200.c
new file mode 100644
index 00000000000..23809159108
--- /dev/null
+++ b/gas/config/tc-mn10200.c
@@ -0,0 +1,1414 @@
+/* tc-mn10200.c -- Assembler code for the Matsushita 10200
+
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/mn10200.h"
+
+/* Structure to hold information about predefined registers. */
+struct reg_name
+{
+ const char *name;
+ int value;
+};
+
+/* Generic assembler global variables which must be defined by all targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = ";#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+
+const relax_typeS md_relax_table[] = {
+ /* bCC relaxing */
+ {0x81, -0x7e, 2, 1},
+ {0x8004, -0x7ffb, 5, 2},
+ {0x800006, -0x7ffff9, 7, 0},
+ /* bCCx relaxing */
+ {0x81, -0x7e, 3, 4},
+ {0x8004, -0x7ffb, 6, 5},
+ {0x800006, -0x7ffff9, 8, 0},
+ /* jsr relaxing */
+ {0x8004, -0x7ffb, 3, 7},
+ {0x800006, -0x7ffff9, 5, 0},
+ /* jmp relaxing */
+ {0x81, -0x7e, 2, 9},
+ {0x8004, -0x7ffb, 3, 10},
+ {0x800006, -0x7ffff9, 5, 0},
+
+};
+/* local functions */
+static void mn10200_insert_operand PARAMS ((unsigned long *, unsigned long *,
+ const struct mn10200_operand *,
+ offsetT, char *, unsigned,
+ unsigned));
+static unsigned long check_operand PARAMS ((unsigned long,
+ const struct mn10200_operand *,
+ offsetT));
+static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
+static boolean data_register_name PARAMS ((expressionS *expressionP));
+static boolean address_register_name PARAMS ((expressionS *expressionP));
+static boolean other_register_name PARAMS ((expressionS *expressionP));
+
+
+/* fixups */
+#define MAX_INSN_FIXUPS (5)
+struct mn10200_fixup
+{
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+};
+struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
+static int fc;
+
+const char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { NULL, NULL, 0 }
+};
+
+/* Opcode hash table. */
+static struct hash_control *mn10200_hash;
+
+/* This table is sorted. Suitable for searching by a binary search. */
+static const struct reg_name data_registers[] =
+{
+ { "d0", 0 },
+ { "d1", 1 },
+ { "d2", 2 },
+ { "d3", 3 },
+};
+#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
+
+static const struct reg_name address_registers[] =
+{
+ { "a0", 0 },
+ { "a1", 1 },
+ { "a2", 2 },
+ { "a3", 3 },
+};
+#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
+
+static const struct reg_name other_registers[] =
+{
+ { "mdr", 0 },
+ { "psw", 0 },
+};
+#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
+
+/* reg_name_search does a binary search of the given register table
+ to see if "name" is a valid regiter name. Returns the register
+ number from the array on success, or -1 on failure. */
+
+static int
+reg_name_search (regs, regcount, name)
+ const struct reg_name *regs;
+ int regcount;
+ const char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+ return -1;
+}
+
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+data_register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+address_register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+other_register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("MN10200 options:\n\
+none yet\n"));
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char *litp;
+ int *sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+
+ return NULL;
+}
+
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ asection *sec;
+ fragS *fragP;
+{
+ static unsigned long label_count = 0;
+ char buf[40];
+
+ subseg_change (sec, 0);
+ if (fragP->fr_subtype == 0)
+ {
+ fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 2;
+ }
+ else if (fragP->fr_subtype == 1)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xe8:
+ opcode = 0xe9;
+ break;
+ case 0xe9:
+ opcode = 0xe8;
+ break;
+ case 0xe0:
+ opcode = 0xe2;
+ break;
+ case 0xe2:
+ opcode = 0xe0;
+ break;
+ case 0xe3:
+ opcode = 0xe1;
+ break;
+ case 0xe1:
+ opcode = 0xe3;
+ break;
+ case 0xe4:
+ opcode = 0xe6;
+ break;
+ case 0xe6:
+ opcode = 0xe4;
+ break;
+ case 0xe7:
+ opcode = 0xe5;
+ break;
+ case 0xe5:
+ opcode = 0xe7;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 1, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 2] = 0xfc;
+ fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 5;
+ }
+ else if (fragP->fr_subtype == 2)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xe8:
+ opcode = 0xe9;
+ break;
+ case 0xe9:
+ opcode = 0xe8;
+ break;
+ case 0xe0:
+ opcode = 0xe2;
+ break;
+ case 0xe2:
+ opcode = 0xe0;
+ break;
+ case 0xe3:
+ opcode = 0xe1;
+ break;
+ case 0xe1:
+ opcode = 0xe3;
+ break;
+ case 0xe4:
+ opcode = 0xe6;
+ break;
+ case 0xe6:
+ opcode = 0xe4;
+ break;
+ case 0xe7:
+ opcode = 0xe5;
+ break;
+ case 0xe5:
+ opcode = 0xe7;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 1, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 2] = 0xf4;
+ fragP->fr_literal[offset + 3] = 0xe0;
+ fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 7;
+ }
+ else if (fragP->fr_subtype == 3)
+ {
+ fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 3;
+ }
+ else if (fragP->fr_subtype == 4)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset + 1] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xfc:
+ opcode = 0xfd;
+ break;
+ case 0xfd:
+ opcode = 0xfc;
+ break;
+ case 0xfe:
+ opcode = 0xff;
+ break;
+ case 0xff:
+ opcode = 0xfe;
+ case 0xe8:
+ opcode = 0xe9;
+ break;
+ case 0xe9:
+ opcode = 0xe8;
+ break;
+ case 0xe0:
+ opcode = 0xe2;
+ break;
+ case 0xe2:
+ opcode = 0xe0;
+ break;
+ case 0xe3:
+ opcode = 0xe1;
+ break;
+ case 0xe1:
+ opcode = 0xe3;
+ break;
+ case 0xe4:
+ opcode = 0xe6;
+ break;
+ case 0xe6:
+ opcode = 0xe4;
+ break;
+ case 0xe7:
+ opcode = 0xe5;
+ break;
+ case 0xe5:
+ opcode = 0xe7;
+ break;
+ case 0xec:
+ opcode = 0xed;
+ break;
+ case 0xed:
+ opcode = 0xec;
+ break;
+ case 0xee:
+ opcode = 0xef;
+ break;
+ case 0xef:
+ opcode = 0xee;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset + 1] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 2, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 3] = 0xfc;
+ fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 6;
+ }
+ else if (fragP->fr_subtype == 5)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset + 1] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xfc:
+ opcode = 0xfd;
+ break;
+ case 0xfd:
+ opcode = 0xfc;
+ break;
+ case 0xfe:
+ opcode = 0xff;
+ break;
+ case 0xff:
+ opcode = 0xfe;
+ case 0xe8:
+ opcode = 0xe9;
+ break;
+ case 0xe9:
+ opcode = 0xe8;
+ break;
+ case 0xe0:
+ opcode = 0xe2;
+ break;
+ case 0xe2:
+ opcode = 0xe0;
+ break;
+ case 0xe3:
+ opcode = 0xe1;
+ break;
+ case 0xe1:
+ opcode = 0xe3;
+ break;
+ case 0xe4:
+ opcode = 0xe6;
+ break;
+ case 0xe6:
+ opcode = 0xe4;
+ break;
+ case 0xe7:
+ opcode = 0xe5;
+ break;
+ case 0xe5:
+ opcode = 0xe7;
+ break;
+ case 0xec:
+ opcode = 0xed;
+ break;
+ case 0xed:
+ opcode = 0xec;
+ break;
+ case 0xee:
+ opcode = 0xef;
+ break;
+ case 0xef:
+ opcode = 0xee;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset + 1] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 2, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 3] = 0xf4;
+ fragP->fr_literal[offset + 4] = 0xe0;
+ fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 8;
+ }
+ else if (fragP->fr_subtype == 6)
+ {
+ fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 3;
+ }
+ else if (fragP->fr_subtype == 7)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xf4;
+ fragP->fr_literal[offset + 1] = 0xe1;
+
+ fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 5;
+ }
+ else if (fragP->fr_subtype == 8)
+ {
+ fragP->fr_literal[fragP->fr_fix] = 0xea;
+ fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 2;
+ }
+ else if (fragP->fr_subtype == 9)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xfc;
+
+ fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 3;
+ }
+ else if (fragP->fr_subtype == 10)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xf4;
+ fragP->fr_literal[offset + 1] = 0xe0;
+
+ fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 5;
+ }
+ else
+ abort ();
+}
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+void
+md_begin ()
+{
+ char *prev_name = "";
+ register const struct mn10200_opcode *op;
+
+ mn10200_hash = hash_new();
+
+ /* Insert unique names into hash table. The MN10200 instruction set
+ has many identical opcode names that have different opcodes based
+ on the operands. This hash table then provides a quick index to
+ the first opcode with a particular name in the opcode table. */
+
+ op = mn10200_opcodes;
+ while (op->name)
+ {
+ if (strcmp (prev_name, op->name))
+ {
+ prev_name = (char *) op->name;
+ hash_insert (mn10200_hash, op->name, (char *) op);
+ }
+ op++;
+ }
+
+ /* This is both a simplification (we don't have to write md_apply_fix)
+ and support for future optimizations (branch shortening and similar
+ stuff in the linker. */
+ linkrelax = 1;
+}
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *s;
+ struct mn10200_opcode *opcode;
+ struct mn10200_opcode *next_opcode;
+ const unsigned char *opindex_ptr;
+ int next_opindex, relaxable;
+ unsigned long insn, extension, size = 0;
+ char *f;
+ int i;
+ int match;
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! isspace (*s); s++)
+ ;
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* find the first opcode with the proper name */
+ opcode = (struct mn10200_opcode *)hash_find (mn10200_hash, str);
+ if (opcode == NULL)
+ {
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ return;
+ }
+
+ str = s;
+ while (isspace (*str))
+ ++str;
+
+ input_line_pointer = str;
+
+ for(;;)
+ {
+ const char *errmsg = NULL;
+ int op_idx;
+ char *hold;
+ int extra_shift = 0;
+
+ relaxable = 0;
+ fc = 0;
+ match = 0;
+ next_opindex = 0;
+ insn = opcode->opcode;
+ extension = 0;
+ for (op_idx = 1, opindex_ptr = opcode->operands;
+ *opindex_ptr != 0;
+ opindex_ptr++, op_idx++)
+ {
+ const struct mn10200_operand *operand;
+ expressionS ex;
+
+ if (next_opindex == 0)
+ {
+ operand = &mn10200_operands[*opindex_ptr];
+ }
+ else
+ {
+ operand = &mn10200_operands[next_opindex];
+ next_opindex = 0;
+ }
+
+ errmsg = NULL;
+
+ while (*str == ' ' || *str == ',')
+ ++str;
+
+ if (operand->flags & MN10200_OPERAND_RELAX)
+ relaxable = 1;
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+ if (operand->flags & MN10200_OPERAND_PAREN)
+ {
+ if (*input_line_pointer != ')' && *input_line_pointer != '(')
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ input_line_pointer++;
+ goto keep_going;
+ }
+ /* See if we can match the operands. */
+ else if (operand->flags & MN10200_OPERAND_DREG)
+ {
+ if (!data_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ }
+ else if (operand->flags & MN10200_OPERAND_AREG)
+ {
+ if (!address_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ }
+ else if (operand->flags & MN10200_OPERAND_PSW)
+ {
+ char *start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcmp (start, "psw") != 0)
+ {
+ *input_line_pointer = c;
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ *input_line_pointer = c;
+ goto keep_going;
+ }
+ else if (operand->flags & MN10200_OPERAND_MDR)
+ {
+ char *start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcmp (start, "mdr") != 0)
+ {
+ *input_line_pointer = c;
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ *input_line_pointer = c;
+ goto keep_going;
+ }
+ else if (data_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else if (address_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else if (other_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else if (*str == ')' || *str == '(')
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else
+ {
+ expression (&ex);
+ }
+
+ switch (ex.X_op)
+ {
+ case O_illegal:
+ errmsg = _("illegal operand");
+ goto error;
+ case O_absent:
+ errmsg = _("missing operand");
+ goto error;
+ case O_register:
+ if ((operand->flags
+ & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ if (opcode->format == FMT_2 || opcode->format == FMT_5)
+ extra_shift = 8;
+ else if (opcode->format == FMT_3 || opcode->format == FMT_6
+ || opcode->format == FMT_7)
+ extra_shift = 16;
+ else
+ extra_shift = 0;
+
+ mn10200_insert_operand (&insn, &extension, operand,
+ ex.X_add_number, (char *) NULL,
+ 0, extra_shift);
+
+ break;
+
+ case O_constant:
+ /* If this operand can be promoted, and it doesn't
+ fit into the allocated bitfield for this insn,
+ then promote it (ie this opcode does not match). */
+ if (operand->flags
+ & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
+ && ! check_operand (insn, operand, ex.X_add_number))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ mn10200_insert_operand (&insn, &extension, operand,
+ ex.X_add_number, (char *) NULL,
+ 0, 0);
+ break;
+
+ default:
+ /* If this operand can be promoted, then this opcode didn't
+ match since we can't know if it needed promotion! */
+ if (operand->flags & MN10200_OPERAND_PROMOTE)
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ break;
+ }
+
+keep_going:
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ while (*str == ' ' || *str == ',')
+ ++str;
+
+ }
+
+ /* Make sure we used all the operands! */
+ if (*str != ',')
+ match = 1;
+
+ error:
+ if (match == 0)
+ {
+ next_opcode = opcode + 1;
+ if (!strcmp(next_opcode->name, opcode->name))
+ {
+ opcode = next_opcode;
+ continue;
+ }
+
+ as_bad ("%s", errmsg);
+ return;
+ }
+ break;
+ }
+
+ while (isspace (*str))
+ ++str;
+
+ if (*str != '\0')
+ as_bad (_("junk at end of line: `%s'"), str);
+
+ input_line_pointer = str;
+
+ if (opcode->format == FMT_1)
+ size = 1;
+ else if (opcode->format == FMT_2 || opcode->format == FMT_4)
+ size = 2;
+ else if (opcode->format == FMT_3 || opcode->format == FMT_5)
+ size = 3;
+ else if (opcode->format == FMT_6)
+ size = 4;
+ else if (opcode->format == FMT_7)
+ size = 5;
+ else
+ abort ();
+
+ /* Write out the instruction. */
+
+ if (relaxable && fc > 0)
+ {
+ int type;
+
+ /* bCC */
+ if (size == 2 && opcode->opcode != 0xfc0000)
+ {
+ /* Handle bra specially. Basically treat it like jmp so
+ that we automatically handle 8, 16 and 32 bit offsets
+ correctly as well as jumps to an undefined address.
+
+ It is also important to not treat it like other bCC
+ instructions since the long forms of bra is different
+ from other bCC instructions. */
+ if (opcode->opcode == 0xea00)
+ type = 8;
+ else
+ type = 0;
+ }
+ /* jsr */
+ else if (size == 3 && opcode->opcode == 0xfd0000)
+ type = 6;
+ /* jmp */
+ else if (size == 3 && opcode->opcode == 0xfc0000)
+ type = 8;
+ /* bCCx */
+ else
+ type = 3;
+
+ f = frag_var (rs_machine_dependent, 8, 8 - size, type,
+ fixups[0].exp.X_add_symbol,
+ fixups[0].exp.X_add_number,
+ (char *)fixups[0].opindex);
+ number_to_chars_bigendian (f, insn, size);
+ if (8 - size > 4)
+ {
+ number_to_chars_bigendian (f + size, 0, 4);
+ number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
+ }
+ else
+ number_to_chars_bigendian (f + size, 0, 8 - size);
+ }
+
+ else
+ {
+ f = frag_more (size);
+
+ /* Oh, what a mess. The instruction is in big endian format, but
+ 16 and 24bit immediates are little endian! */
+ if (opcode->format == FMT_3)
+ {
+ number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
+ number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
+ }
+ else if (opcode->format == FMT_6)
+ {
+ number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
+ number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
+ }
+ else if (opcode->format == FMT_7)
+ {
+ number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
+ number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
+ number_to_chars_littleendian (f + 4, extension & 0xff, 1);
+ }
+ else
+ {
+ number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
+ }
+
+ /* Create any fixups. */
+ for (i = 0; i < fc; i++)
+ {
+ const struct mn10200_operand *operand;
+
+ operand = &mn10200_operands[fixups[i].opindex];
+ if (fixups[i].reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto;
+ int size;
+ int offset;
+ fixS *fixP;
+
+ reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
+
+ if (!reloc_howto)
+ abort();
+
+ size = bfd_get_reloc_size (reloc_howto);
+
+ if (size < 1 || size > 4)
+ abort();
+
+ offset = 4 - size;
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
+ size,
+ &fixups[i].exp,
+ reloc_howto->pc_relative,
+ fixups[i].reloc);
+
+ /* PC-relative offsets are from the first byte of the next
+ instruction, not from the start of the current instruction. */
+ if (reloc_howto->pc_relative)
+ fixP->fx_offset += size;
+ }
+ else
+ {
+ int reloc, pcrel, reloc_size, offset;
+ fixS *fixP;
+
+ reloc = BFD_RELOC_NONE;
+ /* How big is the reloc? Remember SPLIT relocs are
+ implicitly 32bits. */
+ reloc_size = operand->bits;
+
+ offset = size - reloc_size / 8;
+
+ /* Is the reloc pc-relative? */
+ pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
+
+
+ /* Choose a proper BFD relocation type. */
+ if (pcrel)
+ {
+ if (reloc_size == 8)
+ reloc = BFD_RELOC_8_PCREL;
+ else if (reloc_size == 24)
+ reloc = BFD_RELOC_24_PCREL;
+ else
+ abort ();
+ }
+ else
+ {
+ if (reloc_size == 32)
+ reloc = BFD_RELOC_32;
+ else if (reloc_size == 16)
+ reloc = BFD_RELOC_16;
+ else if (reloc_size == 8)
+ reloc = BFD_RELOC_8;
+ else if (reloc_size == 24)
+ reloc = BFD_RELOC_24;
+ else
+ abort ();
+ }
+
+ /* Convert the size of the reloc into what fix_new_exp wants. */
+ reloc_size = reloc_size / 8;
+ if (reloc_size == 8)
+ reloc_size = 0;
+ else if (reloc_size == 16)
+ reloc_size = 1;
+ else if (reloc_size == 32 || reloc_size == 24)
+ reloc_size = 2;
+
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
+ reloc_size, &fixups[i].exp, pcrel,
+ ((bfd_reloc_code_real_type) reloc));
+
+ /* PC-relative offsets are from the first byte of the next
+ instruction, not from the start of the current instruction. */
+ if (pcrel)
+ fixP->fx_offset += size;
+ }
+ }
+ }
+}
+
+
+/* if while processing a fixup, a reloc really needs to be created */
+/* then it is done here */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg;
+ fixS *fixp;
+{
+ arelent *reloc;
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("reloc %d not supported by object file format"),
+ (int)fixp->fx_r_type);
+ return NULL;
+ }
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ if (fixp->fx_addsy && fixp->fx_subsy)
+ {
+ if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
+ || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "Difference of symbols in different sections is not supported");
+ return NULL;
+ }
+ reloc->sym_ptr_ptr = &bfd_abs_symbol;
+ reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
+ - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
+ }
+ else
+ {
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->addend = fixp->fx_offset;
+ }
+ return reloc;
+}
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg;
+{
+ if (fragp->fr_subtype == 0)
+ return 2;
+ if (fragp->fr_subtype == 3)
+ return 3;
+ if (fragp->fr_subtype == 6)
+ {
+ if (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol))
+ {
+ fragp->fr_subtype = 7;
+ return 5;
+ }
+ return 3;
+ }
+ if (fragp->fr_subtype == 8)
+ {
+ if (!S_IS_DEFINED (fragp->fr_symbol))
+ {
+ fragp->fr_subtype = 10;
+ return 5;
+ }
+ return 2;
+ }
+}
+
+long
+md_pcrel_from (fixp)
+ fixS *fixp;
+{
+ return fixp->fx_frag->fr_address;
+#if 0
+ if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
+ {
+ /* The symbol is undefined. Let the linker figure it out. */
+ return 0;
+ }
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+#endif
+}
+
+int
+md_apply_fix3 (fixp, valuep, seg)
+ fixS *fixp;
+ valueT *valuep;
+ segT seg;
+{
+ /* We shouldn't ever get here because linkrelax is nonzero. */
+ abort ();
+ fixp->fx_done = 1;
+ return 0;
+}
+
+/* Insert an operand value into an instruction. */
+
+static void
+mn10200_insert_operand (insnp, extensionp, operand, val, file, line, shift)
+ unsigned long *insnp;
+ unsigned long *extensionp;
+ const struct mn10200_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned int line;
+ unsigned int shift;
+{
+ /* No need to check 24 or 32bit operands for a bit. */
+ if (operand->bits < 24
+ && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
+ {
+ max = (1 << (operand->bits - 1)) - 1;
+ min = - (1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ test = val;
+
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ sprint_value (buf, test);
+ if (file == (char *) NULL)
+ as_warn (err, buf, min, max);
+ else
+ as_warn_where (file, line, err, buf, min, max);
+ }
+ }
+
+ if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
+ {
+ *insnp |= (((long) val & ((1 << operand->bits) - 1))
+ << (operand->shift + shift));
+
+ if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
+ *insnp |= (((long) val & ((1 << operand->bits) - 1))
+ << (operand->shift + shift + 2));
+ }
+ else
+ {
+ *extensionp |= (val >> 16) & 0xff;
+ *insnp |= val & 0xffff;
+ }
+}
+
+static unsigned long
+check_operand (insn, operand, val)
+ unsigned long insn;
+ const struct mn10200_operand *operand;
+ offsetT val;
+{
+ /* No need to check 24bit or 32bit operands for a bit. */
+ if (operand->bits < 24
+ && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
+ {
+ max = (1 << (operand->bits - 1)) - 1;
+ min = - (1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ test = val;
+
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ return 0;
+ else
+ return 1;
+ }
+ return 1;
+}
diff --git a/gas/config/tc-mn10200.h b/gas/config/tc-mn10200.h
new file mode 100644
index 00000000000..e53e569c098
--- /dev/null
+++ b/gas/config/tc-mn10200.h
@@ -0,0 +1,51 @@
+/* tc-mn10200.h -- Header file for tc-mn10200.c.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_MN10200
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifndef BFD_ASSEMBLER
+ #error MN10200 support requires BFD_ASSEMBLER
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_mn10200
+
+#define TARGET_FORMAT "elf32-mn10200"
+
+#define MD_APPLY_FIX3
+#define md_operand(x)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_littleendian
+
+/* Don't bother to adjust relocs. */
+#define tc_fix_adjustable(FIX) 0
+
+/* We do relaxing in the assembler as well as the linker. */
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c
new file mode 100644
index 00000000000..3f9e9cee7d2
--- /dev/null
+++ b/gas/config/tc-mn10300.c
@@ -0,0 +1,1649 @@
+/* tc-mn10300.c -- Assembler code for the Matsushita 10300
+
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/mn10300.h"
+
+/* Structure to hold information about predefined registers. */
+struct reg_name
+{
+ const char *name;
+ int value;
+};
+
+/* Generic assembler global variables which must be defined by all targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = ";#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+
+const relax_typeS md_relax_table[] = {
+ /* bCC relaxing */
+ {0x7f, -0x80, 2, 1},
+ {0x7fff, -0x8000, 5, 2},
+ {0x7fffffff, -0x80000000, 7, 0},
+
+ /* bCC relaxing (uncommon cases) */
+ {0x7f, -0x80, 3, 4},
+ {0x7fff, -0x8000, 6, 5},
+ {0x7fffffff, -0x80000000, 8, 0},
+
+ /* call relaxing */
+ {0x7fff, -0x8000, 5, 7},
+ {0x7fffffff, -0x80000000, 7, 0},
+
+ /* calls relaxing */
+ {0x7fff, -0x8000, 4, 9},
+ {0x7fffffff, -0x80000000, 6, 0},
+
+ /* jmp relaxing */
+ {0x7f, -0x80, 2, 11},
+ {0x7fff, -0x8000, 3, 12},
+ {0x7fffffff, -0x80000000, 5, 0},
+
+};
+
+/* local functions */
+static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *,
+ const struct mn10300_operand *,
+ offsetT, char *, unsigned,
+ unsigned));
+static unsigned long check_operand PARAMS ((unsigned long,
+ const struct mn10300_operand *,
+ offsetT));
+static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
+static boolean data_register_name PARAMS ((expressionS *expressionP));
+static boolean address_register_name PARAMS ((expressionS *expressionP));
+static boolean other_register_name PARAMS ((expressionS *expressionP));
+static void set_arch_mach PARAMS ((int));
+
+static int current_machine;
+
+/* fixups */
+#define MAX_INSN_FIXUPS (5)
+struct mn10300_fixup
+{
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+};
+struct mn10300_fixup fixups[MAX_INSN_FIXUPS];
+static int fc;
+
+/* We must store the value of each register operand so that we can
+ verify that certain registers do not match. */
+int mn10300_reg_operands[MN10300_MAX_OPERANDS];
+
+const char *md_shortopts = "";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "am30", set_arch_mach, 300 },
+ { "mn10300", set_arch_mach, 300 },
+ {NULL, 0, 0}
+};
+
+/* Opcode hash table. */
+static struct hash_control *mn10300_hash;
+
+/* This table is sorted. Suitable for searching by a binary search. */
+static const struct reg_name data_registers[] =
+{
+ { "d0", 0 },
+ { "d1", 1 },
+ { "d2", 2 },
+ { "d3", 3 },
+};
+#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
+
+static const struct reg_name address_registers[] =
+{
+ { "a0", 0 },
+ { "a1", 1 },
+ { "a2", 2 },
+ { "a3", 3 },
+};
+#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
+
+
+static const struct reg_name other_registers[] =
+{
+ { "mdr", 0 },
+ { "psw", 0 },
+ { "sp", 0 },
+};
+#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
+
+/* reg_name_search does a binary search of the given register table
+ to see if "name" is a valid regiter name. Returns the register
+ number from the array on success, or -1 on failure. */
+
+static int
+reg_name_search (regs, regcount, name)
+ const struct reg_name *regs;
+ int regcount;
+ const char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+ return -1;
+}
+
+
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+data_register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+address_register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+other_register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("MN10300 options:\n\
+none yet\n"));
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ return 0;
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char *litp;
+ int *sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return "bad call to md_atof";
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+
+ return NULL;
+}
+
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ asection *sec;
+ fragS *fragP;
+{
+ static unsigned long label_count = 0;
+ char buf[40];
+
+ subseg_change (sec, 0);
+ if (fragP->fr_subtype == 0)
+ {
+ fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 2;
+ }
+ else if (fragP->fr_subtype == 1)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xc8:
+ opcode = 0xc9;
+ break;
+ case 0xc9:
+ opcode = 0xc8;
+ break;
+ case 0xc0:
+ opcode = 0xc2;
+ break;
+ case 0xc2:
+ opcode = 0xc0;
+ break;
+ case 0xc3:
+ opcode = 0xc1;
+ break;
+ case 0xc1:
+ opcode = 0xc3;
+ break;
+ case 0xc4:
+ opcode = 0xc6;
+ break;
+ case 0xc6:
+ opcode = 0xc4;
+ break;
+ case 0xc7:
+ opcode = 0xc5;
+ break;
+ case 0xc5:
+ opcode = 0xc7;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 1, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 2] = 0xcc;
+ fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 5;
+ }
+ else if (fragP->fr_subtype == 2)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xc8:
+ opcode = 0xc9;
+ break;
+ case 0xc9:
+ opcode = 0xc8;
+ break;
+ case 0xc0:
+ opcode = 0xc2;
+ break;
+ case 0xc2:
+ opcode = 0xc0;
+ break;
+ case 0xc3:
+ opcode = 0xc1;
+ break;
+ case 0xc1:
+ opcode = 0xc3;
+ break;
+ case 0xc4:
+ opcode = 0xc6;
+ break;
+ case 0xc6:
+ opcode = 0xc4;
+ break;
+ case 0xc7:
+ opcode = 0xc5;
+ break;
+ case 0xc5:
+ opcode = 0xc7;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 1, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 2] = 0xdc;
+ fix_new (fragP, fragP->fr_fix + 3, 4, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 7;
+ }
+ else if (fragP->fr_subtype == 3)
+ {
+ fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
+ fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 3;
+ }
+ else if (fragP->fr_subtype == 4)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset + 1] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xe8:
+ opcode = 0xe9;
+ break;
+ case 0xe9:
+ opcode = 0xe8;
+ break;
+ case 0xea:
+ opcode = 0xeb;
+ break;
+ case 0xeb:
+ opcode = 0xea;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset + 1] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 2, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 3] = 0xcc;
+ fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 6;
+ }
+ else if (fragP->fr_subtype == 5)
+ {
+ /* Reverse the condition of the first branch. */
+ int offset = fragP->fr_fix;
+ int opcode = fragP->fr_literal[offset + 1] & 0xff;
+
+ switch (opcode)
+ {
+ case 0xe8:
+ opcode = 0xe9;
+ break;
+ case 0xea:
+ opcode = 0xeb;
+ break;
+ case 0xeb:
+ opcode = 0xea;
+ break;
+ default:
+ abort ();
+ }
+ fragP->fr_literal[offset + 1] = opcode;
+
+ /* Create a fixup for the reversed conditional branch. */
+ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
+ fix_new (fragP, fragP->fr_fix + 2, 1,
+ symbol_new (buf, sec, 0, fragP->fr_next),
+ fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
+
+ /* Now create the unconditional branch + fixup to the
+ final target. */
+ fragP->fr_literal[offset + 3] = 0xdc;
+ fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 8;
+ }
+ else if (fragP->fr_subtype == 6)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xcd;
+ fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 5;
+ }
+ else if (fragP->fr_subtype == 7)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xdd;
+ fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3];
+ fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4];
+
+ fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 7;
+ }
+ else if (fragP->fr_subtype == 8)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xfa;
+ fragP->fr_literal[offset + 1] = 0xff;
+ fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
+ fragP->fr_offset + 2, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 4;
+ }
+ else if (fragP->fr_subtype == 9)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xfc;
+ fragP->fr_literal[offset + 1] = 0xff;
+
+ fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
+ fragP->fr_offset + 2, 1, BFD_RELOC_32_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 6;
+ }
+ else if (fragP->fr_subtype == 10)
+ {
+ fragP->fr_literal[fragP->fr_fix] = 0xca;
+ fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 2;
+ }
+ else if (fragP->fr_subtype == 11)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xcc;
+
+ fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 3;
+ }
+ else if (fragP->fr_subtype == 12)
+ {
+ int offset = fragP->fr_fix;
+ fragP->fr_literal[offset] = 0xdc;
+
+ fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
+ fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 5;
+ }
+ else
+ abort ();
+}
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+void
+md_begin ()
+{
+ char *prev_name = "";
+ register const struct mn10300_opcode *op;
+
+ mn10300_hash = hash_new();
+
+ /* Insert unique names into hash table. The MN10300 instruction set
+ has many identical opcode names that have different opcodes based
+ on the operands. This hash table then provides a quick index to
+ the first opcode with a particular name in the opcode table. */
+
+ op = mn10300_opcodes;
+ while (op->name)
+ {
+ if (strcmp (prev_name, op->name))
+ {
+ prev_name = (char *) op->name;
+ hash_insert (mn10300_hash, op->name, (char *) op);
+ }
+ op++;
+ }
+
+ /* This is both a simplification (we don't have to write md_apply_fix)
+ and support for future optimizations (branch shortening and similar
+ stuff in the linker). */
+ linkrelax = 1;
+
+ /* Set the default machine type. */
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, 300))
+ as_warn (_("could not set architecture and machine"));
+
+ current_machine = 300;
+}
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *s;
+ struct mn10300_opcode *opcode;
+ struct mn10300_opcode *next_opcode;
+ const unsigned char *opindex_ptr;
+ int next_opindex, relaxable;
+ unsigned long insn, extension, size = 0;
+ char *f;
+ int i;
+ int match;
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! isspace (*s); s++)
+ ;
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* find the first opcode with the proper name */
+ opcode = (struct mn10300_opcode *)hash_find (mn10300_hash, str);
+ if (opcode == NULL)
+ {
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ return;
+ }
+
+ str = s;
+ while (isspace (*str))
+ ++str;
+
+ input_line_pointer = str;
+
+ for(;;)
+ {
+ const char *errmsg;
+ int op_idx;
+ char *hold;
+ int extra_shift = 0;
+
+
+ errmsg = _("Invalid opcode/operands");
+
+ /* Reset the array of register operands. */
+ memset (mn10300_reg_operands, -1, sizeof (mn10300_reg_operands));
+
+ relaxable = 0;
+ fc = 0;
+ match = 0;
+ next_opindex = 0;
+ insn = opcode->opcode;
+ extension = 0;
+
+ /* If the instruction is not available on the current machine
+ then it can not possibly match. */
+ if (opcode->machine
+ && (opcode->machine != current_machine))
+ goto error;
+
+ for (op_idx = 1, opindex_ptr = opcode->operands;
+ *opindex_ptr != 0;
+ opindex_ptr++, op_idx++)
+ {
+ const struct mn10300_operand *operand;
+ expressionS ex;
+
+ if (next_opindex == 0)
+ {
+ operand = &mn10300_operands[*opindex_ptr];
+ }
+ else
+ {
+ operand = &mn10300_operands[next_opindex];
+ next_opindex = 0;
+ }
+
+ while (*str == ' ' || *str == ',')
+ ++str;
+
+ if (operand->flags & MN10300_OPERAND_RELAX)
+ relaxable = 1;
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+ if (operand->flags & MN10300_OPERAND_PAREN)
+ {
+ if (*input_line_pointer != ')' && *input_line_pointer != '(')
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ input_line_pointer++;
+ goto keep_going;
+ }
+ /* See if we can match the operands. */
+ else if (operand->flags & MN10300_OPERAND_DREG)
+ {
+ if (!data_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ }
+ else if (operand->flags & MN10300_OPERAND_AREG)
+ {
+ if (!address_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ }
+ else if (operand->flags & MN10300_OPERAND_SP)
+ {
+ char *start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcasecmp (start, "sp") != 0)
+ {
+ *input_line_pointer = c;
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ *input_line_pointer = c;
+ goto keep_going;
+ }
+ else if (operand->flags & MN10300_OPERAND_PSW)
+ {
+ char *start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcasecmp (start, "psw") != 0)
+ {
+ *input_line_pointer = c;
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ *input_line_pointer = c;
+ goto keep_going;
+ }
+ else if (operand->flags & MN10300_OPERAND_MDR)
+ {
+ char *start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcasecmp (start, "mdr") != 0)
+ {
+ *input_line_pointer = c;
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ *input_line_pointer = c;
+ goto keep_going;
+ }
+ else if (operand->flags & MN10300_OPERAND_REG_LIST)
+ {
+ unsigned int value = 0;
+ if (*input_line_pointer != '[')
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ /* Eat the '['. */
+ input_line_pointer++;
+
+ /* We used to reject a null register list here; however,
+ we accept it now so the compiler can emit "call" instructions
+ for all calls to named functions.
+
+ The linker can then fill in the appropriate bits for the
+ register list and stack size or change the instruction
+ into a "calls" if using "call" is not profitable. */
+ while (*input_line_pointer != ']')
+ {
+ char *start;
+ char c;
+
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+
+ start = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strcasecmp (start, "d2") == 0)
+ {
+ value |= 0x80;
+ *input_line_pointer = c;
+ }
+ else if (strcasecmp (start, "d3") == 0)
+ {
+ value |= 0x40;
+ *input_line_pointer = c;
+ }
+ else if (strcasecmp (start, "a2") == 0)
+ {
+ value |= 0x20;
+ *input_line_pointer = c;
+ }
+ else if (strcasecmp (start, "a3") == 0)
+ {
+ value |= 0x10;
+ *input_line_pointer = c;
+ }
+ else if (strcasecmp (start, "other") == 0)
+ {
+ value |= 0x08;
+ *input_line_pointer = c;
+ }
+ else
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ }
+ input_line_pointer++;
+ mn10300_insert_operand (&insn, &extension, operand,
+ value, (char *) NULL, 0, 0);
+ goto keep_going;
+
+ }
+ else if (data_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else if (address_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else if (other_register_name (&ex))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else if (*str == ')' || *str == '(')
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+ else
+ {
+ expression (&ex);
+ }
+
+ switch (ex.X_op)
+ {
+ case O_illegal:
+ errmsg = _("illegal operand");
+ goto error;
+ case O_absent:
+ errmsg = _("missing operand");
+ goto error;
+ case O_register:
+ {
+ int mask;
+
+ mask = MN10300_OPERAND_DREG | MN10300_OPERAND_AREG;
+ if ((operand->flags & mask) == 0)
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ if (opcode->format == FMT_D1 || opcode->format == FMT_S1)
+ extra_shift = 8;
+ else if (opcode->format == FMT_D2
+ || opcode->format == FMT_D4
+ || opcode->format == FMT_S2
+ || opcode->format == FMT_S4
+ || opcode->format == FMT_S6
+ || opcode->format == FMT_D5)
+ extra_shift = 16;
+ else
+ extra_shift = 0;
+
+ mn10300_insert_operand (&insn, &extension, operand,
+ ex.X_add_number, (char *) NULL,
+ 0, extra_shift);
+
+
+ /* And note the register number in the register array. */
+ mn10300_reg_operands[op_idx - 1] = ex.X_add_number;
+ break;
+ }
+
+ case O_constant:
+ /* If this operand can be promoted, and it doesn't
+ fit into the allocated bitfield for this insn,
+ then promote it (ie this opcode does not match). */
+ if (operand->flags
+ & (MN10300_OPERAND_PROMOTE | MN10300_OPERAND_RELAX)
+ && ! check_operand (insn, operand, ex.X_add_number))
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ mn10300_insert_operand (&insn, &extension, operand,
+ ex.X_add_number, (char *) NULL,
+ 0, 0);
+ break;
+
+ default:
+ /* If this operand can be promoted, then this opcode didn't
+ match since we can't know if it needed promotion! */
+ if (operand->flags & MN10300_OPERAND_PROMOTE)
+ {
+ input_line_pointer = hold;
+ str = hold;
+ goto error;
+ }
+
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ break;
+ }
+
+keep_going:
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ while (*str == ' ' || *str == ',')
+ ++str;
+
+ }
+
+ /* Make sure we used all the operands! */
+ if (*str != ',')
+ match = 1;
+
+ /* If this instruction has registers that must not match, verify
+ that they do indeed not match. */
+ if (opcode->no_match_operands)
+ {
+ int i;
+
+ /* Look at each operand to see if it's marked. */
+ for (i = 0; i < MN10300_MAX_OPERANDS; i++)
+ {
+ if ((1 << i) & opcode->no_match_operands)
+ {
+ int j;
+
+ /* operand I is marked. Check that it does not match any
+ operands > I which are marked. */
+ for (j = i + 1; j < MN10300_MAX_OPERANDS; j++)
+ {
+ if (((1 << j) & opcode->no_match_operands)
+ && mn10300_reg_operands[i] == mn10300_reg_operands[j])
+ {
+ errmsg = _("Invalid register specification.");
+ match = 0;
+ goto error;
+ }
+ }
+ }
+ }
+ }
+
+ error:
+ if (match == 0)
+ {
+ next_opcode = opcode + 1;
+ if (!strcmp(next_opcode->name, opcode->name))
+ {
+ opcode = next_opcode;
+ continue;
+ }
+
+ as_bad ("%s", errmsg);
+ return;
+ }
+ break;
+ }
+
+ while (isspace (*str))
+ ++str;
+
+ if (*str != '\0')
+ as_bad (_("junk at end of line: `%s'"), str);
+
+ input_line_pointer = str;
+
+ /* Determine the size of the instruction. */
+ if (opcode->format == FMT_S0)
+ size = 1;
+
+ if (opcode->format == FMT_S1 || opcode->format == FMT_D0)
+ size = 2;
+
+ if (opcode->format == FMT_S2 || opcode->format == FMT_D1)
+ size = 3;
+
+
+ if (opcode->format == FMT_S4)
+ size = 5;
+
+ if (opcode->format == FMT_S6 || opcode->format == FMT_D5)
+ size = 7;
+
+ if (opcode->format == FMT_D2)
+ size = 4;
+
+ if (opcode->format == FMT_D4)
+ size = 6;
+
+ if (relaxable && fc > 0)
+ {
+ int type;
+
+ /* bCC */
+ if (size == 2)
+ {
+ /* Handle bra specially. Basically treat it like jmp so
+ that we automatically handle 8, 16 and 32 bit offsets
+ correctly as well as jumps to an undefined address.
+
+ It is also important to not treat it like other bCC
+ instructions since the long forms of bra is different
+ from other bCC instructions. */
+ if (opcode->opcode == 0xca00)
+ type = 10;
+ else
+ type = 0;
+ }
+ /* call */
+ else if (size == 5)
+ type = 6;
+ /* calls */
+ else if (size == 4)
+ type = 8;
+ /* jmp */
+ else if (size == 3 && opcode->opcode == 0xcc0000)
+ type = 10;
+ /* bCC (uncommon cases) */
+ else
+ type = 3;
+
+ f = frag_var (rs_machine_dependent, 8, 8 - size, type,
+ fixups[0].exp.X_add_symbol,
+ fixups[0].exp.X_add_number,
+ (char *)fixups[0].opindex);
+
+ /* This is pretty hokey. We basically just care about the
+ opcode, so we have to write out the first word big endian.
+
+ The exception is "call", which has two operands that we
+ care about.
+
+ The first operand (the register list) happens to be in the
+ first instruction word, and will be in the right place if
+ we output the first word in big endian mode.
+
+ The second operand (stack size) is in the extension word,
+ and we want it to appear as the first character in the extension
+ word (as it appears in memory). Luckily, writing the extension
+ word in big endian format will do what we want. */
+ number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
+ if (size > 8)
+ {
+ number_to_chars_bigendian (f + 4, extension, 4);
+ number_to_chars_bigendian (f + 8, 0, size - 8);
+ }
+ else if (size > 4)
+ number_to_chars_bigendian (f + 4, extension, size - 4);
+ }
+ else
+ {
+ /* Allocate space for the instruction. */
+ f = frag_more (size);
+
+ /* Fill in bytes for the instruction. Note that opcode fields
+ are written big-endian, 16 & 32bit immediates are written
+ little endian. Egad. */
+ if (opcode->format == FMT_S0
+ || opcode->format == FMT_S1
+ || opcode->format == FMT_D0
+ || opcode->format == FMT_D1)
+ {
+ number_to_chars_bigendian (f, insn, size);
+ }
+ else if (opcode->format == FMT_S2
+ && opcode->opcode != 0xdf0000
+ && opcode->opcode != 0xde0000)
+ {
+ /* A format S2 instruction that is _not_ "ret" and "retf". */
+ number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
+ number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
+ }
+ else if (opcode->format == FMT_S2)
+ {
+ /* This must be a ret or retf, which is written entirely in
+ big-endian format. */
+ number_to_chars_bigendian (f, insn, 3);
+ }
+ else if (opcode->format == FMT_S4
+ && opcode->opcode != 0xdc000000)
+ {
+ /* This must be a format S4 "call" instruction. What a pain. */
+ unsigned long temp = (insn >> 8) & 0xffff;
+ number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
+ number_to_chars_littleendian (f + 1, temp, 2);
+ number_to_chars_bigendian (f + 3, insn & 0xff, 1);
+ number_to_chars_bigendian (f + 4, extension & 0xff, 1);
+ }
+ else if (opcode->format == FMT_S4)
+ {
+ /* This must be a format S4 "jmp" instruction. */
+ unsigned long temp = ((insn & 0xffffff) << 8) | (extension & 0xff);
+ number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
+ number_to_chars_littleendian (f + 1, temp, 4);
+ }
+ else if (opcode->format == FMT_S6)
+ {
+ unsigned long temp = ((insn & 0xffffff) << 8)
+ | ((extension >> 16) & 0xff);
+ number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
+ number_to_chars_littleendian (f + 1, temp, 4);
+ number_to_chars_bigendian (f + 5, (extension >> 8) & 0xff, 1);
+ number_to_chars_bigendian (f + 6, extension & 0xff, 1);
+ }
+ else if (opcode->format == FMT_D2
+ && opcode->opcode != 0xfaf80000
+ && opcode->opcode != 0xfaf00000
+ && opcode->opcode != 0xfaf40000)
+ {
+ /* A format D2 instruction where the 16bit immediate is
+ really a single 16bit value, not two 8bit values. */
+ number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
+ number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
+ }
+ else if (opcode->format == FMT_D2)
+ {
+ /* A format D2 instruction where the 16bit immediate
+ is really two 8bit immediates. */
+ number_to_chars_bigendian (f, insn, 4);
+ }
+ else if (opcode->format == FMT_D4)
+ {
+ unsigned long temp = ((insn & 0xffff) << 16) | (extension & 0xffff);
+ number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
+ number_to_chars_littleendian (f + 2, temp, 4);
+ }
+ else if (opcode->format == FMT_D5)
+ {
+ unsigned long temp = ((insn & 0xffff) << 16)
+ | ((extension >> 8) & 0xffff);
+ number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
+ number_to_chars_littleendian (f + 2, temp, 4);
+ number_to_chars_bigendian (f + 6, extension & 0xff, 1);
+ }
+
+ /* Create any fixups. */
+ for (i = 0; i < fc; i++)
+ {
+ const struct mn10300_operand *operand;
+
+ operand = &mn10300_operands[fixups[i].opindex];
+ if (fixups[i].reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto;
+ int size;
+ int offset;
+ fixS *fixP;
+
+ reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
+
+ if (!reloc_howto)
+ abort();
+
+ size = bfd_get_reloc_size (reloc_howto);
+
+ if (size < 1 || size > 4)
+ abort();
+
+ offset = 4 - size;
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
+ size, &fixups[i].exp,
+ reloc_howto->pc_relative,
+ fixups[i].reloc);
+ }
+ else
+ {
+ int reloc, pcrel, reloc_size, offset;
+ fixS *fixP;
+
+ reloc = BFD_RELOC_NONE;
+ /* How big is the reloc? Remember SPLIT relocs are
+ implicitly 32bits. */
+ if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
+ reloc_size = 32;
+ else
+ reloc_size = operand->bits;
+
+ /* Is the reloc pc-relative? */
+ pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
+
+ /* Gross. This disgusting hack is to make sure we
+ get the right offset for the 16/32 bit reloc in
+ "call" instructions. Basically they're a pain
+ because the reloc isn't at the end of the instruction. */
+ if ((size == 5 || size == 7)
+ && (((insn >> 24) & 0xff) == 0xcd
+ || ((insn >> 24) & 0xff) == 0xdd))
+ size -= 2;
+
+ /* Similarly for certain bit instructions which don't
+ hav their 32bit reloc at the tail of the instruction. */
+ if (size == 7
+ && (((insn >> 16) & 0xffff) == 0xfe00
+ || ((insn >> 16) & 0xffff) == 0xfe01
+ || ((insn >> 16) & 0xffff) == 0xfe02))
+ size -= 1;
+
+ offset = size - reloc_size / 8;
+
+ /* Choose a proper BFD relocation type. */
+ if (pcrel)
+ {
+ if (reloc_size == 32)
+ reloc = BFD_RELOC_32_PCREL;
+ else if (reloc_size == 16)
+ reloc = BFD_RELOC_16_PCREL;
+ else if (reloc_size == 8)
+ reloc = BFD_RELOC_8_PCREL;
+ else
+ abort ();
+ }
+ else
+ {
+ if (reloc_size == 32)
+ reloc = BFD_RELOC_32;
+ else if (reloc_size == 16)
+ reloc = BFD_RELOC_16;
+ else if (reloc_size == 8)
+ reloc = BFD_RELOC_8;
+ else
+ abort ();
+ }
+
+ /* Convert the size of the reloc into what fix_new_exp wants. */
+ reloc_size = reloc_size / 8;
+ if (reloc_size == 8)
+ reloc_size = 0;
+ else if (reloc_size == 16)
+ reloc_size = 1;
+ else if (reloc_size == 32)
+ reloc_size = 2;
+
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
+ reloc_size, &fixups[i].exp, pcrel,
+ ((bfd_reloc_code_real_type) reloc));
+
+ if (pcrel)
+ fixP->fx_offset += offset;
+ }
+ }
+ }
+}
+
+
+/* if while processing a fixup, a reloc really needs to be created */
+/* then it is done here */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg;
+ fixS *fixp;
+{
+ arelent *reloc;
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("reloc %d not supported by object file format"),
+ (int)fixp->fx_r_type);
+ return NULL;
+ }
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ if (fixp->fx_addsy && fixp->fx_subsy)
+ {
+
+ if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
+ || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ "Difference of symbols in different sections is not supported");
+ return NULL;
+ }
+
+ reloc->sym_ptr_ptr = &bfd_abs_symbol;
+ reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
+ - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
+ }
+ else
+ {
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->addend = fixp->fx_offset;
+ }
+ return reloc;
+}
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg;
+{
+ if (fragp->fr_subtype == 0)
+ return 2;
+ if (fragp->fr_subtype == 3)
+ return 3;
+ if (fragp->fr_subtype == 6)
+ {
+ if (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol))
+ {
+ fragp->fr_subtype = 7;
+ return 7;
+ }
+ else
+ return 5;
+ }
+ if (fragp->fr_subtype == 8)
+ {
+ if (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol))
+ {
+ fragp->fr_subtype = 9;
+ return 6;
+ }
+ else
+ return 4;
+ }
+ if (fragp->fr_subtype == 10)
+ {
+ if (!S_IS_DEFINED (fragp->fr_symbol)
+ || seg != S_GET_SEGMENT (fragp->fr_symbol))
+ {
+ fragp->fr_subtype = 12;
+ return 5;
+ }
+ else
+ return 2;
+ }
+}
+
+long
+md_pcrel_from (fixp)
+ fixS *fixp;
+{
+ return fixp->fx_frag->fr_address;
+#if 0
+ if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
+ {
+ /* The symbol is undefined. Let the linker figure it out. */
+ return 0;
+ }
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+#endif
+}
+
+int
+md_apply_fix3 (fixp, valuep, seg)
+ fixS *fixp;
+ valueT *valuep;
+ segT seg;
+{
+ /* We shouldn't ever get here because linkrelax is nonzero. */
+ abort ();
+ fixp->fx_done = 1;
+ return 0;
+}
+
+/* Insert an operand value into an instruction. */
+
+static void
+mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift)
+ unsigned long *insnp;
+ unsigned long *extensionp;
+ const struct mn10300_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned int line;
+ unsigned int shift;
+{
+ /* No need to check 32bit operands for a bit. Note that
+ MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
+ if (operand->bits != 32
+ && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
+ {
+ long min, max;
+ offsetT test;
+ int bits;
+
+ bits = operand->bits;
+
+ if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
+ {
+ max = (1 << (bits - 1)) - 1;
+ min = - (1 << (bits - 1));
+ }
+ else
+ {
+ max = (1 << bits) - 1;
+ min = 0;
+ }
+
+ test = val;
+
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ sprint_value (buf, test);
+ if (file == (char *) NULL)
+ as_warn (err, buf, min, max);
+ else
+ as_warn_where (file, line, err, buf, min, max);
+ }
+ }
+
+ if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
+ {
+ *insnp |= (val >> (32 - operand->bits)) & ((1 << operand->bits) - 1);
+ *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1))
+ << operand->shift);
+ }
+ else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0)
+ {
+ *insnp |= (((long) val & ((1 << operand->bits) - 1))
+ << (operand->shift + shift));
+
+ if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
+ *insnp |= (((long) val & ((1 << operand->bits) - 1))
+ << (operand->shift + shift + operand->bits));
+ }
+ else
+ {
+ *extensionp |= (((long) val & ((1 << operand->bits) - 1))
+ << (operand->shift + shift));
+
+ if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
+ *extensionp |= (((long) val & ((1 << operand->bits) - 1))
+ << (operand->shift + shift + operand->bits));
+ }
+}
+
+static unsigned long
+check_operand (insn, operand, val)
+ unsigned long insn;
+ const struct mn10300_operand *operand;
+ offsetT val;
+{
+ /* No need to check 32bit operands for a bit. Note that
+ MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
+ if (operand->bits != 32
+ && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
+ {
+ long min, max;
+ offsetT test;
+ int bits;
+
+ bits = operand->bits;
+
+ if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
+ {
+ max = (1 << (bits - 1)) - 1;
+ min = - (1 << (bits - 1));
+ }
+ else
+ {
+ max = (1 << bits) - 1;
+ min = 0;
+ }
+
+ test = val;
+
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ return 0;
+ else
+ return 1;
+ }
+ return 1;
+}
+
+static void
+set_arch_mach (mach)
+ int mach;
+{
+ if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, mach))
+ as_warn (_("could not set architecture and machine"));
+
+ current_machine = mach;
+}
diff --git a/gas/config/tc-mn10300.h b/gas/config/tc-mn10300.h
new file mode 100644
index 00000000000..ffcb227b0e0
--- /dev/null
+++ b/gas/config/tc-mn10300.h
@@ -0,0 +1,50 @@
+/* tc-mn10300.h -- Header file for tc-mn10300.c.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_MN10300
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifndef BFD_ASSEMBLER
+ #error MN10300 support requires BFD_ASSEMBLER
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_mn10300
+
+#define TARGET_FORMAT "elf32-mn10300"
+
+#define MD_APPLY_FIX3
+#define md_operand(x)
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_littleendian
+
+/* Don't bother to adjust relocs. */
+#define tc_fix_adjustable(FIX) 0
+
+/* We do relaxing in the assembler as well as the linker. */
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
diff --git a/gas/config/tc-ns32k.c b/gas/config/tc-ns32k.c
new file mode 100644
index 00000000000..42dc5283882
--- /dev/null
+++ b/gas/config/tc-ns32k.c
@@ -0,0 +1,2328 @@
+/* ns32k.c -- Assemble on the National Semiconductor 32k series
+ Copyright (C) 1987, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*#define SHOW_NUM 1*//* uncomment for debugging */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "as.h"
+#include "opcode/ns32k.h"
+
+#include "obstack.h"
+
+/* Macros */
+#define IIF_ENTRIES 13 /* number of entries in iif */
+#define PRIVATE_SIZE 256 /* size of my garbage memory */
+#define MAX_ARGS 4
+#define DEFAULT -1 /* addr_mode returns this value when
+ plain constant or label is
+ encountered */
+
+#define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
+ iif.iifP[ptr].type= a1; \
+ iif.iifP[ptr].size= c1; \
+ iif.iifP[ptr].object= e1; \
+ iif.iifP[ptr].object_adjust= g1; \
+ iif.iifP[ptr].pcrel= i1; \
+ iif.iifP[ptr].pcrel_adjust= k1; \
+ iif.iifP[ptr].im_disp= m1; \
+ iif.iifP[ptr].relax_substate= o1; \
+ iif.iifP[ptr].bit_fixP= q1; \
+ iif.iifP[ptr].addr_mode= s1; \
+ iif.iifP[ptr].bsr= u1;
+
+#ifdef SEQUENT_COMPATABILITY
+#define LINE_COMMENT_CHARS "|"
+#define ABSOLUTE_PREFIX '@'
+#define IMMEDIATE_PREFIX '#'
+#endif
+
+#ifndef LINE_COMMENT_CHARS
+#define LINE_COMMENT_CHARS "#"
+#endif
+
+const char comment_chars[] = "#";
+const char line_comment_chars[] = LINE_COMMENT_CHARS;
+const char line_separator_chars[] = "";
+#if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
+#define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */
+#endif
+
+struct addr_mode
+ {
+ char mode; /* addressing mode of operand (0-31) */
+ char scaled_mode; /* mode combined with scaled mode */
+ char scaled_reg; /* register used in scaled+1 (1-8) */
+ char float_flag; /* set if R0..R7 was F0..F7 ie a
+ floating-point-register */
+ char am_size; /* estimated max size of general addr-mode
+ parts */
+ char im_disp; /* if im_disp==1 we have a displacement */
+ char pcrel; /* 1 if pcrel, this is really redundant info */
+ char disp_suffix[2]; /* length of displacement(s), 0=undefined */
+ char *disp[2]; /* pointer(s) at displacement(s)
+ or immediates(s) (ascii) */
+ char index_byte; /* index byte */
+ };
+typedef struct addr_mode addr_modeS;
+
+
+char *freeptr, *freeptr_static; /* points at some number of free bytes */
+struct hash_control *inst_hash_handle;
+
+struct ns32k_opcode *desc; /* pointer at description of instruction */
+addr_modeS addr_modeP;
+const char EXP_CHARS[] = "eE";
+const char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */
+
+/* UPPERCASE denotes live names when an instruction is built, IIF is
+ * used as an intermediate form to store the actual parts of the
+ * instruction. A ns32k machine instruction can be divided into a
+ * couple of sub PARTs. When an instruction is assembled the
+ * appropriate PART get an assignment. When an IIF has been completed
+ * it is converted to a FRAGment as specified in AS.H */
+
+/* internal structs */
+struct ns32k_option
+ {
+ char *pattern;
+ unsigned long or;
+ unsigned long and;
+ };
+
+typedef struct
+ {
+ int type; /* how to interpret object */
+ int size; /* Estimated max size of object */
+ unsigned long object; /* binary data */
+ int object_adjust; /* number added to object */
+ int pcrel; /* True if object is pcrel */
+ int pcrel_adjust; /* length in bytes from the
+ instruction start to the
+ displacement */
+ int im_disp; /* True if the object is a displacement */
+ relax_substateT relax_substate; /* Initial relaxsubstate */
+ bit_fixS *bit_fixP; /* Pointer at bit_fix struct */
+ int addr_mode; /* What addrmode do we associate with this
+ iif-entry */
+ char bsr; /* Sequent hack */
+ } iif_entryT; /* Internal Instruction Format */
+
+struct int_ins_form
+ {
+ int instr_size; /* Max size of instruction in bytes. */
+ iif_entryT iifP[IIF_ENTRIES + 1];
+ };
+struct int_ins_form iif;
+expressionS exprP;
+char *input_line_pointer;
+/* description of the PARTs in IIF
+ *object[n]:
+ * 0 total length in bytes of entries in iif
+ * 1 opcode
+ * 2 index_byte_a
+ * 3 index_byte_b
+ * 4 disp_a_1
+ * 5 disp_a_2
+ * 6 disp_b_1
+ * 7 disp_b_2
+ * 8 imm_a
+ * 9 imm_b
+ * 10 implied1
+ * 11 implied2
+ *
+ * For every entry there is a datalength in bytes. This is stored in size[n].
+ * 0, the objectlength is not explicitly given by the instruction
+ * and the operand is undefined. This is a case for relaxation.
+ * Reserve 4 bytes for the final object.
+ *
+ * 1, the entry contains one byte
+ * 2, the entry contains two bytes
+ * 3, the entry contains three bytes
+ * 4, the entry contains four bytes
+ * etc
+ *
+ * Furthermore, every entry has a data type identifier in type[n].
+ *
+ * 0, the entry is void, ignore it.
+ * 1, the entry is a binary number.
+ * 2, the entry is a pointer at an expression.
+ * Where expression may be as simple as a single '1',
+ * and as complicated as foo-bar+12,
+ * foo and bar may be undefined but suffixed by :{b|w|d} to
+ * control the length of the object.
+ *
+ * 3, the entry is a pointer at a bignum struct
+ *
+ *
+ * The low-order-byte coresponds to low physical memory.
+ * Obviously a FRAGment must be created for each valid disp in PART whose
+ * datalength is undefined (to bad) .
+ * The case where just the expression is undefined is less severe and is
+ * handled by fix. Here the number of bytes in the objectfile is known.
+ * With this representation we simplify the assembly and separates the
+ * machine dependent/independent parts in a more clean way (said OE)
+ */
+
+struct ns32k_option opt1[] = /* restore, exit */
+{
+ {"r0", 0x80, 0xff},
+ {"r1", 0x40, 0xff},
+ {"r2", 0x20, 0xff},
+ {"r3", 0x10, 0xff},
+ {"r4", 0x08, 0xff},
+ {"r5", 0x04, 0xff},
+ {"r6", 0x02, 0xff},
+ {"r7", 0x01, 0xff},
+ {0, 0x00, 0xff}
+};
+struct ns32k_option opt2[] = /* save, enter */
+{
+ {"r0", 0x01, 0xff},
+ {"r1", 0x02, 0xff},
+ {"r2", 0x04, 0xff},
+ {"r3", 0x08, 0xff},
+ {"r4", 0x10, 0xff},
+ {"r5", 0x20, 0xff},
+ {"r6", 0x40, 0xff},
+ {"r7", 0x80, 0xff},
+ {0, 0x00, 0xff}
+};
+struct ns32k_option opt3[] = /* setcfg */
+{
+ {"c", 0x8, 0xff},
+ {"m", 0x4, 0xff},
+ {"f", 0x2, 0xff},
+ {"i", 0x1, 0xff},
+ {0, 0x0, 0xff}
+};
+struct ns32k_option opt4[] = /* cinv */
+{
+ {"a", 0x4, 0xff},
+ {"i", 0x2, 0xff},
+ {"d", 0x1, 0xff},
+ {0, 0x0, 0xff}
+};
+struct ns32k_option opt5[] = /* string inst */
+{
+ {"b", 0x2, 0xff},
+ {"u", 0xc, 0xff},
+ {"w", 0x4, 0xff},
+ {0, 0x0, 0xff}
+};
+struct ns32k_option opt6[] = /* plain reg ext,cvtp etc */
+{
+ {"r0", 0x00, 0xff},
+ {"r1", 0x01, 0xff},
+ {"r2", 0x02, 0xff},
+ {"r3", 0x03, 0xff},
+ {"r4", 0x04, 0xff},
+ {"r5", 0x05, 0xff},
+ {"r6", 0x06, 0xff},
+ {"r7", 0x07, 0xff},
+ {0, 0x00, 0xff}
+};
+
+#if !defined(NS32032) && !defined(NS32532)
+#define NS32532
+#endif
+
+struct ns32k_option cpureg_532[] = /* lpr spr */
+{
+ {"us", 0x0, 0xff},
+ {"dcr", 0x1, 0xff},
+ {"bpc", 0x2, 0xff},
+ {"dsr", 0x3, 0xff},
+ {"car", 0x4, 0xff},
+ {"fp", 0x8, 0xff},
+ {"sp", 0x9, 0xff},
+ {"sb", 0xa, 0xff},
+ {"usp", 0xb, 0xff},
+ {"cfg", 0xc, 0xff},
+ {"psr", 0xd, 0xff},
+ {"intbase", 0xe, 0xff},
+ {"mod", 0xf, 0xff},
+ {0, 0x00, 0xff}
+};
+struct ns32k_option mmureg_532[] = /* lmr smr */
+{
+ {"mcr", 0x9, 0xff},
+ {"msr", 0xa, 0xff},
+ {"tear", 0xb, 0xff},
+ {"ptb0", 0xc, 0xff},
+ {"ptb1", 0xd, 0xff},
+ {"ivar0", 0xe, 0xff},
+ {"ivar1", 0xf, 0xff},
+ {0, 0x0, 0xff}
+};
+
+struct ns32k_option cpureg_032[] = /* lpr spr */
+{
+ {"upsr", 0x0, 0xff},
+ {"fp", 0x8, 0xff},
+ {"sp", 0x9, 0xff},
+ {"sb", 0xa, 0xff},
+ {"psr", 0xd, 0xff},
+ {"intbase", 0xe, 0xff},
+ {"mod", 0xf, 0xff},
+ {0, 0x0, 0xff}
+};
+struct ns32k_option mmureg_032[] = /* lmr smr */
+{
+ {"bpr0", 0x0, 0xff},
+ {"bpr1", 0x1, 0xff},
+ {"pf0", 0x4, 0xff},
+ {"pf1", 0x5, 0xff},
+ {"sc", 0x8, 0xff},
+ {"msr", 0xa, 0xff},
+ {"bcnt", 0xb, 0xff},
+ {"ptb0", 0xc, 0xff},
+ {"ptb1", 0xd, 0xff},
+ {"eia", 0xf, 0xff},
+ {0, 0x0, 0xff}
+};
+
+#if defined(NS32532)
+struct ns32k_option *cpureg = cpureg_532;
+struct ns32k_option *mmureg = mmureg_532;
+#else
+struct ns32k_option *cpureg = cpureg_032;
+struct ns32k_option *mmureg = mmureg_032;
+#endif
+
+
+const pseudo_typeS md_pseudo_table[] =
+{ /* so far empty */
+ {0, 0, 0}
+};
+
+#define IND(x,y) (((x)<<2)+(y))
+
+/* those are index's to relax groups in md_relax_table ie it must be
+ multiplied by 4 to point at a group start. Viz IND(x,y) Se function
+ relax_segment in write.c for more info */
+
+#define BRANCH 1
+#define PCREL 2
+
+/* those are index's to entries in a relax group */
+
+#define BYTE 0
+#define WORD 1
+#define DOUBLE 2
+#define UNDEF 3
+/* Those limits are calculated from the displacement start in memory.
+ The ns32k uses the begining of the instruction as displacement
+ base. This type of displacements could be handled here by moving
+ the limit window up or down. I choose to use an internal
+ displacement base-adjust as there are other routines that must
+ consider this. Also, as we have two various offset-adjusts in the
+ ns32k (acb versus br/brs/jsr/bcond), two set of limits would have
+ had to be used. Now we dont have to think about that. */
+
+
+const relax_typeS md_relax_table[] =
+{
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+
+ {(63), (-64), 1, IND (BRANCH, WORD)},
+ {(8192), (-8192), 2, IND (BRANCH, DOUBLE)},
+ {0, 0, 4, 0},
+ {1, 1, 0, 0}
+};
+
+/* Array used to test if mode contains displacements.
+ Value is true if mode contains displacement. */
+
+char disp_test[] =
+{0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 1, 1, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1};
+
+/* Array used to calculate max size of displacements */
+
+char disp_size[] =
+{4, 1, 2, 0, 4};
+
+static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr));
+static void md_number_to_disp PARAMS ((char *buf, long val, int n));
+static void md_number_to_imm PARAMS ((char *buf, long val, int n));
+
+/* Parses a general operand into an addressingmode struct
+
+ in: pointer at operand in ascii form
+ pointer at addr_mode struct for result
+ the level of recursion. (always 0 or 1)
+
+ out: data in addr_mode struct
+ */
+int
+addr_mode (operand, addr_modeP, recursive_level)
+ char *operand;
+ register addr_modeS *addr_modeP;
+ int recursive_level;
+{
+ register char *str;
+ register int i;
+ register int strl;
+ register int mode;
+ int j;
+ mode = DEFAULT; /* default */
+ addr_modeP->scaled_mode = 0; /* why not */
+ addr_modeP->scaled_reg = 0; /* if 0, not scaled index */
+ addr_modeP->float_flag = 0;
+ addr_modeP->am_size = 0;
+ addr_modeP->im_disp = 0;
+ addr_modeP->pcrel = 0; /* not set in this function */
+ addr_modeP->disp_suffix[0] = 0;
+ addr_modeP->disp_suffix[1] = 0;
+ addr_modeP->disp[0] = NULL;
+ addr_modeP->disp[1] = NULL;
+ str = operand;
+ if (str[0] == 0)
+ {
+ return (0);
+ } /* we don't want this */
+ strl = strlen (str);
+ switch (str[0])
+ {
+ /* the following three case statements controls the mode-chars
+ this is the place to ed if you want to change them */
+#ifdef ABSOLUTE_PREFIX
+ case ABSOLUTE_PREFIX:
+ if (str[strl - 1] == ']')
+ break;
+ addr_modeP->mode = 21; /* absolute */
+ addr_modeP->disp[0] = str + 1;
+ return (-1);
+#endif
+#ifdef IMMEDIATE_PREFIX
+ case IMMEDIATE_PREFIX:
+ if (str[strl - 1] == ']')
+ break;
+ addr_modeP->mode = 20; /* immediate */
+ addr_modeP->disp[0] = str + 1;
+ return (-1);
+#endif
+ case '.':
+ if (str[strl - 1] != ']')
+ {
+ switch (str[1])
+ {
+ case '-':
+ case '+':
+ if (str[2] != '\000')
+ {
+ addr_modeP->mode = 27; /* pc-relativ */
+ addr_modeP->disp[0] = str + 2;
+ return (-1);
+ }
+ default:
+ as_warn (_("Invalid syntax in PC-relative addressing mode"));
+ return (0);
+ }
+ }
+ break;
+ case 'e':
+ if (str[strl - 1] != ']')
+ {
+ if ((!strncmp (str, "ext(", 4)) && strl > 7)
+ { /* external */
+ addr_modeP->disp[0] = str + 4;
+ i = 0;
+ j = 2;
+ do
+ { /* disp[0]'s termination point */
+ j += 1;
+ if (str[j] == '(')
+ i++;
+ if (str[j] == ')')
+ i--;
+ }
+ while (j < strl && i != 0);
+ if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
+ {
+ as_warn (_("Invalid syntax in External addressing mode"));
+ return (0);
+ }
+ str[j] = '\000'; /* null terminate disp[0] */
+ addr_modeP->disp[1] = str + j + 2;
+ addr_modeP->mode = 22;
+ return (-1);
+ }
+ }
+ break;
+ default:;
+ }
+ strl = strlen (str);
+ switch (strl)
+ {
+ case 2:
+ switch (str[0])
+ {
+ case 'f':
+ addr_modeP->float_flag = 1;
+ case 'r':
+ if (str[1] >= '0' && str[1] < '8')
+ {
+ addr_modeP->mode = str[1] - '0';
+ return (-1);
+ }
+ }
+ case 3:
+ if (!strncmp (str, "tos", 3))
+ {
+ addr_modeP->mode = 23; /* TopOfStack */
+ return (-1);
+ }
+ default:;
+ }
+ if (strl > 4)
+ {
+ if (str[strl - 1] == ')')
+ {
+ if (str[strl - 2] == ')')
+ {
+ if (!strncmp (&str[strl - 5], "(fp", 3))
+ {
+ mode = 16; /* Memory Relative */
+ }
+ if (!strncmp (&str[strl - 5], "(sp", 3))
+ {
+ mode = 17;
+ }
+ if (!strncmp (&str[strl - 5], "(sb", 3))
+ {
+ mode = 18;
+ }
+ if (mode != DEFAULT)
+ { /* memory relative */
+ addr_modeP->mode = mode;
+ j = strl - 5; /* temp for end of disp[0] */
+ i = 0;
+ do
+ {
+ strl -= 1;
+ if (str[strl] == ')')
+ i++;
+ if (str[strl] == '(')
+ i--;
+ }
+ while (strl > -1 && i != 0);
+ if (i != 0)
+ {
+ as_warn (_("Invalid syntax in Memory Relative addressing mode"));
+ return (0);
+ }
+ addr_modeP->disp[1] = str;
+ addr_modeP->disp[0] = str + strl + 1;
+ str[j] = '\000'; /* null terminate disp[0] */
+ str[strl] = '\000'; /* null terminate disp[1] */
+ return (-1);
+ }
+ }
+ switch (str[strl - 3])
+ {
+ case 'r':
+ case 'R':
+ if (str[strl - 2] >= '0'
+ && str[strl - 2] < '8'
+ && str[strl - 4] == '(')
+ {
+ addr_modeP->mode = str[strl - 2] - '0' + 8;
+ addr_modeP->disp[0] = str;
+ str[strl - 4] = 0;
+ return (-1); /* reg rel */
+ }
+ default:
+ if (!strncmp (&str[strl - 4], "(fp", 3))
+ {
+ mode = 24;
+ }
+ if (!strncmp (&str[strl - 4], "(sp", 3))
+ {
+ mode = 25;
+ }
+ if (!strncmp (&str[strl - 4], "(sb", 3))
+ {
+ mode = 26;
+ }
+ if (!strncmp (&str[strl - 4], "(pc", 3))
+ {
+ mode = 27;
+ }
+ if (mode != DEFAULT)
+ {
+ addr_modeP->mode = mode;
+ addr_modeP->disp[0] = str;
+ str[strl - 4] = '\0';
+ return (-1); /* memory space */
+ }
+ }
+ }
+ /* no trailing ')' do we have a ']' ? */
+ if (str[strl - 1] == ']')
+ {
+ switch (str[strl - 2])
+ {
+ case 'b':
+ mode = 28;
+ break;
+ case 'w':
+ mode = 29;
+ break;
+ case 'd':
+ mode = 30;
+ break;
+ case 'q':
+ mode = 31;
+ break;
+ default:;
+ as_warn (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
+ if (str[strl - 3] != ':' || str[strl - 6] != '['
+ || str[strl - 5] == 'r' || str[strl - 4] < '0'
+ || str[strl - 4] > '7')
+ {
+ as_warn (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
+ }
+ } /* scaled index */
+ {
+ if (recursive_level > 0)
+ {
+ as_warn (_("Scaled-indexed addressing mode combined with scaled-index"));
+ return (0);
+ }
+ addr_modeP->am_size += 1; /* scaled index byte */
+ j = str[strl - 4] - '0'; /* store temporary */
+ str[strl - 6] = '\000'; /* nullterminate for recursive call */
+ i = addr_mode (str, addr_modeP, 1);
+ if (!i || addr_modeP->mode == 20)
+ {
+ as_warn (_("Invalid or illegal addressing mode combined with scaled-index"));
+ return (0);
+ }
+ addr_modeP->scaled_mode = addr_modeP->mode; /* store the inferior
+ mode */
+ addr_modeP->mode = mode;
+ addr_modeP->scaled_reg = j + 1;
+ return (-1);
+ }
+ }
+ }
+ addr_modeP->mode = DEFAULT; /* default to whatever */
+ addr_modeP->disp[0] = str;
+ return (-1);
+}
+
+/* ptr points at string addr_modeP points at struct with result This
+ routine calls addr_mode to determine the general addr.mode of the
+ operand. When this is ready it parses the displacements for size
+ specifying suffixes and determines size of immediate mode via
+ ns32k-opcode. Also builds index bytes if needed. */
+int
+get_addr_mode (ptr, addr_modeP)
+ char *ptr;
+ addr_modeS *addr_modeP;
+{
+ int tmp;
+ addr_mode (ptr, addr_modeP, 0);
+ if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
+ {
+ /* resolve ambigious operands, this shouldn't be necessary if
+ one uses standard NSC operand syntax. But the sequent
+ compiler doesn't!!! This finds a proper addressinging mode
+ if it is implicitly stated. See ns32k-opcode.h */
+ (void) evaluate_expr (&exprP, ptr); /* this call takes time Sigh! */
+ if (addr_modeP->mode == DEFAULT)
+ {
+ if (exprP.X_add_symbol || exprP.X_op_symbol)
+ {
+ addr_modeP->mode = desc->default_model; /* we have a label */
+ }
+ else
+ {
+ addr_modeP->mode = desc->default_modec; /* we have a constant */
+ }
+ }
+ else
+ {
+ if (exprP.X_add_symbol || exprP.X_op_symbol)
+ {
+ addr_modeP->scaled_mode = desc->default_model;
+ }
+ else
+ {
+ addr_modeP->scaled_mode = desc->default_modec;
+ }
+ }
+ /* must put this mess down in addr_mode to handle the scaled
+ case better */
+ }
+ /* It appears as the sequent compiler wants an absolute when we have
+ a label without @. Constants becomes immediates besides the addr
+ case. Think it does so with local labels too, not optimum, pcrel
+ is better. When I have time I will make gas check this and
+ select pcrel when possible Actually that is trivial. */
+ if (tmp = addr_modeP->scaled_reg)
+ { /* build indexbyte */
+ tmp--; /* remember regnumber comes incremented for
+ flagpurpose */
+ tmp |= addr_modeP->scaled_mode << 3;
+ addr_modeP->index_byte = (char) tmp;
+ addr_modeP->am_size += 1;
+ }
+ if (disp_test[addr_modeP->mode])
+ { /* there was a displacement, probe for length
+ specifying suffix */
+ {
+ register char c;
+ register char suffix;
+ register char suffix_sub;
+ register int i;
+ register char *toP;
+ register char *fromP;
+
+ addr_modeP->pcrel = 0;
+ if (disp_test[addr_modeP->mode])
+ { /* there is a displacement */
+ if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
+ { /* do we have pcrel. mode */
+ addr_modeP->pcrel = 1;
+ }
+ addr_modeP->im_disp = 1;
+ for (i = 0; i < 2; i++)
+ {
+ suffix_sub = suffix = 0;
+ if (toP = addr_modeP->disp[i])
+ { /* suffix of expression, the largest size
+ rules */
+ fromP = toP;
+ while (c = *fromP++)
+ {
+ *toP++ = c;
+ if (c == ':')
+ {
+ switch (*fromP)
+ {
+ case '\0':
+ as_warn (_("Premature end of suffix -- Defaulting to d"));
+ suffix = 4;
+ continue;
+ case 'b':
+ suffix_sub = 1;
+ break;
+ case 'w':
+ suffix_sub = 2;
+ break;
+ case 'd':
+ suffix_sub = 4;
+ break;
+ default:
+ as_warn (_("Bad suffix after ':' use {b|w|d} Defaulting to d"));
+ suffix = 4;
+ }
+ fromP++;
+ toP--; /* So we write over the ':' */
+ if (suffix < suffix_sub)
+ suffix = suffix_sub;
+ }
+ }
+ *toP = '\0';/* terminate properly */
+ addr_modeP->disp_suffix[i] = suffix;
+ addr_modeP->am_size += suffix ? suffix : 4;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (addr_modeP->mode == 20)
+ { /* look in ns32k_opcode for size */
+ addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
+ addr_modeP->im_disp = 0;
+ }
+ }
+ return addr_modeP->mode;
+}
+
+
+/* read an optionlist */
+void
+optlist (str, optionP, default_map)
+ char *str; /* the string to extract options from */
+ struct ns32k_option *optionP; /* how to search the string */
+ unsigned long *default_map; /* default pattern and output */
+{
+ register int i, j, k, strlen1, strlen2;
+ register char *patternP, *strP;
+ strlen1 = strlen (str);
+ if (strlen1 < 1)
+ {
+ as_fatal (_("Very short instr to option, ie you can't do it on a NULLstr"));
+ }
+ for (i = 0; optionP[i].pattern != 0; i++)
+ {
+ strlen2 = strlen (optionP[i].pattern);
+ for (j = 0; j < strlen1; j++)
+ {
+ patternP = optionP[i].pattern;
+ strP = &str[j];
+ for (k = 0; k < strlen2; k++)
+ {
+ if (*(strP++) != *(patternP++))
+ break;
+ }
+ if (k == strlen2)
+ { /* match */
+ *default_map |= optionP[i].or;
+ *default_map &= optionP[i].and;
+ }
+ }
+ }
+}
+
+/* search struct for symbols
+ This function is used to get the short integer form of reg names in
+ the instructions lmr, smr, lpr, spr return true if str is found in
+ list */
+
+int
+list_search (str, optionP, default_map)
+ char *str; /* the string to match */
+ struct ns32k_option *optionP; /* list to search */
+ unsigned long *default_map; /* default pattern and output */
+{
+ register int i;
+ for (i = 0; optionP[i].pattern != 0; i++)
+ {
+ if (!strncmp (optionP[i].pattern, str, 20))
+ { /* use strncmp to be safe */
+ *default_map |= optionP[i].or;
+ *default_map &= optionP[i].and;
+ return -1;
+ }
+ }
+ as_warn (_("No such entry in list. (cpu/mmu register)"));
+ return 0;
+}
+
+static void
+evaluate_expr (resultP, ptr)
+ expressionS *resultP;
+ char *ptr;
+{
+ register char *tmp_line;
+
+ tmp_line = input_line_pointer;
+ input_line_pointer = ptr;
+ expression (&exprP);
+ input_line_pointer = tmp_line;
+}
+
+/* Convert operands to iif-format and adds bitfields to the opcode.
+ Operands are parsed in such an order that the opcode is updated from
+ its most significant bit, that is when the operand need to alter the
+ opcode.
+ Be carefull not to put to objects in the same iif-slot.
+ */
+
+void
+encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
+ int argc;
+ char **argv;
+ char *operandsP;
+ char *suffixP;
+ char im_size;
+ char opcode_bit_ptr;
+{
+ register int i, j;
+ char d;
+ int pcrel, tmp, b, loop, pcrel_adjust;
+ for (loop = 0; loop < argc; loop++)
+ {
+ i = operandsP[loop << 1] - '1'; /* what operand are we supposed
+ to work on */
+ if (i > 3)
+ as_fatal (_("Internal consistency error. check ns32k-opcode.h"));
+ pcrel = 0;
+ pcrel_adjust = 0;
+ tmp = 0;
+ switch ((d = operandsP[(loop << 1) + 1]))
+ {
+ case 'f': /* operand of sfsr turns out to be a nasty
+ specialcase */
+ opcode_bit_ptr -= 5;
+ case 'Z': /* float not immediate */
+ case 'F': /* 32 bit float general form */
+ case 'L': /* 64 bit float */
+ case 'I': /* integer not immediate */
+ case 'B': /* byte */
+ case 'W': /* word */
+ case 'D': /* double-word */
+ case 'A': /* double-word gen-address-form ie no regs
+ allowed */
+ get_addr_mode (argv[i], &addr_modeP);
+ if((addr_modeP.mode == 20) &&
+ (d == 'I' || d == 'Z' || d == 'A')) {
+ as_fatal(d == 'A'? _("Address of immediate operand"):
+ _("Invalid immediate write operand."));
+ }
+
+ if (opcode_bit_ptr == desc->opcode_size)
+ b = 4;
+ else
+ b = 6;
+ for (j = b; j < (b + 2); j++)
+ {
+ if (addr_modeP.disp[j - b])
+ {
+ IIF (j,
+ 2,
+ addr_modeP.disp_suffix[j - b],
+ (unsigned long) addr_modeP.disp[j - b],
+ 0,
+ addr_modeP.pcrel,
+ iif.instr_size,
+ addr_modeP.im_disp,
+ IND (BRANCH, BYTE),
+ NULL,
+ (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
+ : addr_modeP.mode),
+ 0);
+ }
+ }
+ opcode_bit_ptr -= 5;
+ iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
+ if (addr_modeP.scaled_reg)
+ {
+ j = b / 2;
+ IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
+ 0, 0, 0, 0, 0, NULL, -1, 0);
+ }
+ break;
+ case 'b': /* multiple instruction disp */
+ freeptr++; /* OVE:this is an useful hack */
+ sprintf (freeptr, "((%s-1)*%d)\000", argv[i], desc->im_size);
+ argv[i] = freeptr;
+ pcrel -= 1; /* make pcrel 0 inspite of what case 'p':
+ wants */
+ /* fall thru */
+ case 'p': /* displacement - pc relative addressing */
+ pcrel += 1;
+ /* fall thru */
+ case 'd': /* displacement */
+ iif.instr_size += suffixP[i] ? suffixP[i] : 4;
+ IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
+ pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
+ break;
+ case 'H': /* sequent-hack: the linker wants a bit set
+ when bsr */
+ pcrel = 1;
+ iif.instr_size += suffixP[i] ? suffixP[i] : 4;
+ IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
+ pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
+ break;
+ case 'q': /* quick */
+ opcode_bit_ptr -= 4;
+ IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
+ bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
+ break;
+ case 'r': /* register number (3 bits) */
+ list_search (argv[i], opt6, &tmp);
+ opcode_bit_ptr -= 3;
+ iif.iifP[1].object |= tmp << opcode_bit_ptr;
+ break;
+ case 'O': /* setcfg instruction optionslist */
+ optlist (argv[i], opt3, &tmp);
+ opcode_bit_ptr -= 4;
+ iif.iifP[1].object |= tmp << 15;
+ break;
+ case 'C': /* cinv instruction optionslist */
+ optlist (argv[i], opt4, &tmp);
+ opcode_bit_ptr -= 4;
+ iif.iifP[1].object |= tmp << 15; /* insert the regtype in opcode */
+ break;
+ case 'S': /* stringinstruction optionslist */
+ optlist (argv[i], opt5, &tmp);
+ opcode_bit_ptr -= 4;
+ iif.iifP[1].object |= tmp << 15;
+ break;
+ case 'u':
+ case 'U': /* registerlist */
+ IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
+ switch (operandsP[(i << 1) + 1])
+ {
+ case 'u': /* restore, exit */
+ optlist (argv[i], opt1, &iif.iifP[10].object);
+ break;
+ case 'U': /* save,enter */
+ optlist (argv[i], opt2, &iif.iifP[10].object);
+ break;
+ }
+ iif.instr_size += 1;
+ break;
+ case 'M': /* mmu register */
+ list_search (argv[i], mmureg, &tmp);
+ opcode_bit_ptr -= 4;
+ iif.iifP[1].object |= tmp << opcode_bit_ptr;
+ break;
+ case 'P': /* cpu register */
+ list_search (argv[i], cpureg, &tmp);
+ opcode_bit_ptr -= 4;
+ iif.iifP[1].object |= tmp << opcode_bit_ptr;
+ break;
+ case 'g': /* inss exts */
+ iif.instr_size += 1; /* 1 byte is allocated after the opcode */
+ IIF (10, 2, 1,
+ (unsigned long) argv[i], /* i always 2 here */
+ 0, 0, 0, 0, 0,
+ bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* a bit_fix is targeted to
+ the byte */
+ -1, 0);
+ break;
+ case 'G':
+ IIF (11, 2, 42,
+ (unsigned long) argv[i], /* i always 3 here */
+ 0, 0, 0, 0, 0,
+ bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
+ break;
+ case 'i':
+ iif.instr_size += 1;
+ b = 2 + i; /* put the extension byte after opcode */
+ IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
+ break;
+ default:
+ as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
+ }
+ }
+}
+
+/* in: instruction line
+ out: internal structure of instruction
+ that has been prepared for direct conversion to fragment(s) and
+ fixes in a systematical fashion
+ Return-value = recursive_level
+ */
+/* build iif of one assembly text line */
+int
+parse (line, recursive_level)
+ char *line;
+ int recursive_level;
+{
+ register char *lineptr, c, suffix_separator;
+ register int i;
+ int argc, arg_type;
+ char sqr, sep;
+ char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* no more than 4 operands */
+ if (recursive_level <= 0)
+ { /* called from md_assemble */
+ for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++);
+ c = *lineptr;
+ *lineptr = '\0';
+ if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
+ {
+ as_fatal (_("No such opcode"));
+ }
+ *lineptr = c;
+ }
+ else
+ {
+ lineptr = line;
+ }
+ argc = 0;
+ if (*desc->operands)
+ {
+ if (*lineptr++ != '\0')
+ {
+ sqr = '[';
+ sep = ',';
+ while (*lineptr != '\0')
+ {
+ if (desc->operands[argc << 1])
+ {
+ suffix[argc] = 0;
+ arg_type = desc->operands[(argc << 1) + 1];
+ switch (arg_type)
+ {
+ case 'd':
+ case 'b':
+ case 'p':
+ case 'H': /* the operand is supposed to be a
+ displacement */
+ /* Hackwarning: do not forget to update the 4
+ cases above when editing ns32k-opcode.h */
+ suffix_separator = ':';
+ break;
+ default:
+ suffix_separator = '\255'; /* if this char occurs we
+ loose */
+ }
+ suffix[argc] = 0; /* 0 when no ':' is encountered */
+ argv[argc] = freeptr;
+ *freeptr = '\0';
+ while ((c = *lineptr) != '\0' && c != sep)
+ {
+ if (c == sqr)
+ {
+ if (sqr == '[')
+ {
+ sqr = ']';
+ sep = '\0';
+ }
+ else
+ {
+ sqr = '[';
+ sep = ',';
+ }
+ }
+ if (c == suffix_separator)
+ { /* ':' - label/suffix separator */
+ switch (lineptr[1])
+ {
+ case 'b':
+ suffix[argc] = 1;
+ break;
+ case 'w':
+ suffix[argc] = 2;
+ break;
+ case 'd':
+ suffix[argc] = 4;
+ break;
+ default:
+ as_warn (_("Bad suffix, defaulting to d"));
+ suffix[argc] = 4;
+ if (lineptr[1] == '\0' || lineptr[1] == sep)
+ {
+ lineptr += 1;
+ continue;
+ }
+ }
+ lineptr += 2;
+ continue;
+ }
+ *freeptr++ = c;
+ lineptr++;
+ }
+ *freeptr++ = '\0';
+ argc += 1;
+ if (*lineptr == '\0')
+ continue;
+ lineptr += 1;
+ }
+ else
+ {
+ as_fatal (_("Too many operands passed to instruction"));
+ }
+ }
+ }
+ }
+ if (argc != strlen (desc->operands) / 2)
+ {
+ if (strlen (desc->default_args))
+ { /* we can apply default, dont goof */
+ if (parse (desc->default_args, 1) != 1)
+ { /* check error in default */
+ as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
+ }
+ }
+ else
+ {
+ as_fatal (_("Wrong number of operands"));
+ }
+
+ }
+ for (i = 0; i < IIF_ENTRIES; i++)
+ {
+ iif.iifP[i].type = 0; /* mark all entries as void*/
+ }
+
+ /* build opcode iif-entry */
+ iif.instr_size = desc->opcode_size / 8;
+ IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
+
+ /* this call encodes operands to iif format */
+ if (argc)
+ {
+ encode_operand (argc,
+ argv,
+ &desc->operands[0],
+ &suffix[0],
+ desc->im_size,
+ desc->opcode_size);
+ }
+ return recursive_level;
+}
+
+
+/* Convert iif to fragments. From this point we start to dribble with
+ * functions in other files than this one.(Except hash.c) So, if it's
+ * possible to make an iif for an other CPU, you don't need to know
+ * what frags, relax, obstacks, etc is in order to port this
+ * assembler. You only need to know if it's possible to reduce your
+ * cpu-instruction to iif-format (takes some work) and adopt the other
+ * md_? parts according to given instructions Note that iif was
+ * invented for the clean ns32k`s architecure.
+ */
+
+/* GAS for the ns32k has a problem. PC relative displacements are
+ * relative to the address of the opcode, not the address of the
+ * operand. We used to keep track of the offset between the operand
+ * and the opcode in pcrel_adjust for each frag and each fix. However,
+ * we get into trouble where there are two or more pc-relative
+ * operands and the size of the first one can't be determined. Then in
+ * the relax phase, the size of the first operand will change and
+ * pcrel_adjust will no longer be correct. The current solution is
+ * keep a pointer to the frag with the opcode in it and the offset in
+ * that frag for each frag and each fix. Then, when needed, we can
+ * always figure out how far it is between the opcode and the pcrel
+ * object. See also md_pcrel_adjust and md_fix_pcrel_adjust. For
+ * objects not part of an instruction, the pointer to the opcode frag
+ * is always zero. */
+
+void
+convert_iif ()
+{
+ int i;
+ bit_fixS *j;
+ fragS *inst_frag;
+ unsigned int inst_offset;
+ char *inst_opcode;
+ char *memP;
+ int l;
+ int k;
+ char type;
+ char size = 0;
+ int size_so_far;
+
+ memP = frag_more (0);
+ inst_opcode = memP;
+ inst_offset = (memP - frag_now->fr_literal);
+ inst_frag = frag_now;
+
+ for (i = 0; i < IIF_ENTRIES; i++)
+ {
+ if (type = iif.iifP[i].type)
+ { /* the object exist, so handle it */
+ switch (size = iif.iifP[i].size)
+ {
+ case 42:
+ size = 0; /* it's a bitfix that operates on an existing
+ object*/
+ if (iif.iifP[i].bit_fixP->fx_bit_base)
+ { /* expand fx_bit_base to point at opcode */
+ iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
+ }
+ case 8: /* bignum or doublefloat */
+ case 1:
+ case 2:
+ case 3:
+ case 4: /* the final size in objectmemory is known */
+ memP = frag_more(size);
+ j = iif.iifP[i].bit_fixP;
+ switch (type)
+ {
+ case 1: /* the object is pure binary */
+ if (j || iif.iifP[i].pcrel)
+ {
+ fix_new_ns32k (frag_now,
+ (long) (memP - frag_now->fr_literal),
+ size,
+ 0,
+ iif.iifP[i].object,
+ iif.iifP[i].pcrel,
+ iif.iifP[i].im_disp,
+ j,
+ iif.iifP[i].bsr, /* sequent hack */
+ inst_frag, inst_offset);
+ }
+ else
+ { /* good, just put them bytes out */
+ switch (iif.iifP[i].im_disp)
+ {
+ case 0:
+ md_number_to_chars (memP, iif.iifP[i].object, size);
+ break;
+ case 1:
+ md_number_to_disp (memP, iif.iifP[i].object, size);
+ break;
+ default:
+ as_fatal (_("iif convert internal pcrel/binary"));
+ }
+ }
+ break;
+ case 2:
+ /* the object is a pointer at an expression, so
+ unpack it, note that bignums may result from the
+ expression */
+ evaluate_expr (&exprP, (char *) iif.iifP[i].object);
+ if (exprP.X_op == O_big || size == 8)
+ {
+ if ((k = exprP.X_add_number) > 0)
+ {
+ /* we have a bignum ie a quad. This can only
+ happens in a long suffixed instruction */
+ if (k * 2 > size)
+ as_warn (_("Bignum too big for long"));
+ if (k == 3)
+ memP += 2;
+ for (l = 0; k > 0; k--, l += 2)
+ {
+ md_number_to_chars (memP + l,
+ generic_bignum[l >> 1],
+ sizeof (LITTLENUM_TYPE));
+ }
+ }
+ else
+ { /* flonum */
+ LITTLENUM_TYPE words[4];
+
+ switch (size)
+ {
+ case 4:
+ gen_to_words (words, 2, 8);
+ md_number_to_imm (memP, (long) words[0],
+ sizeof (LITTLENUM_TYPE));
+ md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
+ (long) words[1],
+ sizeof (LITTLENUM_TYPE));
+ break;
+ case 8:
+ gen_to_words (words, 4, 11);
+ md_number_to_imm (memP, (long) words[0],
+ sizeof (LITTLENUM_TYPE));
+ md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
+ (long) words[1],
+ sizeof (LITTLENUM_TYPE));
+ md_number_to_imm ((memP + 2
+ * sizeof (LITTLENUM_TYPE)),
+ (long) words[2],
+ sizeof (LITTLENUM_TYPE));
+ md_number_to_imm ((memP + 3
+ * sizeof (LITTLENUM_TYPE)),
+ (long) words[3],
+ sizeof (LITTLENUM_TYPE));
+ break;
+ }
+ }
+ break;
+ }
+ if (j ||
+ exprP.X_add_symbol ||
+ exprP.X_op_symbol ||
+ iif.iifP[i].pcrel)
+ {
+ /* The expression was undefined due to an
+ undefined label. Create a fix so we can fix
+ the object later. */
+ exprP.X_add_number += iif.iifP[i].object_adjust;
+ fix_new_ns32k_exp (frag_now,
+ (long) (memP - frag_now->fr_literal),
+ size,
+ &exprP,
+ iif.iifP[i].pcrel,
+ iif.iifP[i].im_disp,
+ j,
+ iif.iifP[i].bsr,
+ inst_frag, inst_offset);
+ }
+ else
+ {
+ /* good, just put them bytes out */
+ switch (iif.iifP[i].im_disp)
+ {
+ case 0:
+ md_number_to_imm (memP, exprP.X_add_number, size);
+ break;
+ case 1:
+ md_number_to_disp (memP, exprP.X_add_number, size);
+ break;
+ default:
+ as_fatal (_("iif convert internal pcrel/pointer"));
+ }
+ }
+ break;
+ default:
+ as_fatal (_("Internal logic error in iif.iifP[n].type"));
+ }
+ break;
+ case 0:
+ /* To bad, the object may be undefined as far as its
+ final nsize in object memory is concerned. The size
+ of the object in objectmemory is not explicitly
+ given. If the object is defined its length can be
+ determined and a fix can replace the frag. */
+ {
+ evaluate_expr (&exprP, (char *) iif.iifP[i].object);
+ if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
+ !iif.iifP[i].pcrel)
+ {
+ /* Size is unknown until link time so have to
+ allow 4 bytes. */
+ size = 4;
+ memP = frag_more(size);
+ fix_new_ns32k_exp (frag_now,
+ (long) (memP - frag_now->fr_literal),
+ size,
+ &exprP,
+ 0, /* never iif.iifP[i].pcrel, */
+ 1, /* always iif.iifP[i].im_disp */
+ (bit_fixS *) 0, 0,
+ inst_frag,
+ inst_offset);
+ break; /* exit this absolute hack */
+ }
+
+ if (exprP.X_add_symbol || exprP.X_op_symbol)
+ { /* frag it */
+ if (exprP.X_op_symbol)
+ { /* We cant relax this case */
+ as_fatal (_("Can't relax difference"));
+ }
+ else
+ {
+
+ /* Size is not important. This gets fixed by relax,
+ * but we assume 0 in what follows
+ */
+ memP = frag_more(4); /* Max size */
+ size = 0;
+
+ {
+ fragS *old_frag = frag_now;
+ frag_variant (rs_machine_dependent,
+ 4, /* Max size */
+ 0, /* size */
+ IND (BRANCH, UNDEF), /* expecting the worst */
+ exprP.X_add_symbol,
+ exprP.X_add_number,
+ inst_opcode);
+ frag_opcode_frag(old_frag) = inst_frag;
+ frag_opcode_offset(old_frag) = inst_offset;
+ frag_bsr(old_frag) = iif.iifP[i].bsr;
+ }
+ }
+ }
+ else
+ {
+ /* This duplicates code in md_number_to_disp */
+ if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
+ {
+ size = 1;
+ }
+ else
+ {
+ if (-8192 <= exprP.X_add_number
+ && exprP.X_add_number <= 8191)
+ {
+ size = 2;
+ }
+ else
+ {
+ if (-0x20000000<=exprP.X_add_number &&
+ exprP.X_add_number<=0x1fffffff)
+ {
+ size = 4;
+ }
+ else
+ {
+ as_warn (_("Displacement to large for :d"));
+ size = 4;
+ }
+ }
+ }
+ memP = frag_more(size);
+ md_number_to_disp (memP, exprP.X_add_number, size);
+ }
+ }
+ break;
+ default:
+ as_fatal (_("Internal logic error in iif.iifP[].type"));
+ }
+ }
+ }
+}
+
+#ifdef BFD_ASSEMBLER
+/* This functionality should really be in the bfd library */
+static bfd_reloc_code_real_type
+reloc (int size, int pcrel, int type)
+{
+ int length, index;
+ bfd_reloc_code_real_type relocs[] = {
+ BFD_RELOC_NS32K_IMM_8,
+ BFD_RELOC_NS32K_IMM_16,
+ BFD_RELOC_NS32K_IMM_32,
+ BFD_RELOC_NS32K_IMM_8_PCREL,
+ BFD_RELOC_NS32K_IMM_16_PCREL,
+ BFD_RELOC_NS32K_IMM_32_PCREL,
+
+ /* ns32k displacements */
+ BFD_RELOC_NS32K_DISP_8,
+ BFD_RELOC_NS32K_DISP_16,
+ BFD_RELOC_NS32K_DISP_32,
+ BFD_RELOC_NS32K_DISP_8_PCREL,
+ BFD_RELOC_NS32K_DISP_16_PCREL,
+ BFD_RELOC_NS32K_DISP_32_PCREL,
+
+ /* Normal 2's complement */
+ BFD_RELOC_8,
+ BFD_RELOC_16,
+ BFD_RELOC_32,
+ BFD_RELOC_8_PCREL,
+ BFD_RELOC_16_PCREL,
+ BFD_RELOC_32_PCREL
+ };
+ switch (size)
+ {
+ case 1:
+ length = 0;
+ break;
+ case 2:
+ length = 1;
+ break;
+ case 4:
+ length = 2;
+ break;
+ default:
+ length = -1;
+ break;
+ }
+ index = length + 3 * pcrel + 6 * type;
+ if (index >= 0 && index < sizeof(relocs)/sizeof(relocs[0]))
+ return relocs[index];
+ if (pcrel)
+ as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
+ size, type);
+ else
+ as_bad (_("Can not do %d byte relocation for storage type %d"),
+ size, type);
+ return BFD_RELOC_NONE;
+
+}
+
+#endif
+
+void
+md_assemble (line)
+ char *line;
+{
+ freeptr = freeptr_static;
+ parse (line, 0); /* explode line to more fix form in iif */
+ convert_iif (); /* convert iif to frags, fix's etc */
+#ifdef SHOW_NUM
+ printf (" \t\t\t%s\n", line);
+#endif
+}
+
+
+void
+md_begin ()
+{
+ /* build a hashtable of the instructions */
+ const struct ns32k_opcode *ptr;
+ const char *stat;
+ inst_hash_handle = hash_new ();
+ for (ptr = ns32k_opcodes; ptr < endop; ptr++)
+ {
+ if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
+ {
+ as_fatal (_("Can't hash %s: %s"), ptr->name, stat); /*fatal*/
+ }
+ }
+ freeptr_static = (char *) malloc (PRIVATE_SIZE); /* some private space
+ please! */
+}
+
+/* Must be equal to MAX_PRECISON in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn the string pointed to by litP into a floating point constant
+ of type type, and emit the appropriate bytes. The number of
+ LITTLENUMS emitted is stored in *sizeP . An error message is
+ returned, or NULL on OK. */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words + prec; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+/* Convert number to chars in correct order */
+
+void
+md_number_to_chars (buf, value, nbytes)
+ char *buf;
+ valueT value;
+ int nbytes;
+{
+ number_to_chars_littleendian (buf, value, nbytes);
+}
+
+
+/* This is a variant of md_numbers_to_chars. The reason for its'
+ existence is the fact that ns32k uses Huffman coded
+ displacements. This implies that the bit order is reversed in
+ displacements and that they are prefixed with a size-tag.
+
+ binary: msb -> lsb
+ 0xxxxxxx byte
+ 10xxxxxx xxxxxxxx word
+ 11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx double word
+
+ This must be taken care of and we do it here! */
+static void
+md_number_to_disp (buf, val, n)
+ char *buf;
+ long val;
+ char n;
+{
+ switch (n)
+ {
+ case 1:
+ if (val < -64 || val > 63)
+ as_warn (_("Byte displacement out of range. line number not valid"));
+ val &= 0x7f;
+#ifdef SHOW_NUM
+ printf ("%x ", val & 0xff);
+#endif
+ *buf++ = val;
+ break;
+ case 2:
+ if (val < -8192 || val > 8191)
+ as_warn (_("Word displacement out of range. line number not valid"));
+ val &= 0x3fff;
+ val |= 0x8000;
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 8 & 0xff);
+#endif
+ *buf++ = (val >> 8);
+#ifdef SHOW_NUM
+ printf ("%x ", val & 0xff);
+#endif
+ *buf++ = val;
+ break;
+ case 4:
+ if (val < -0x20000000 || val >= 0x20000000)
+ as_warn (_("Double word displacement out of range"));
+ val |= 0xc0000000;
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 24 & 0xff);
+#endif
+ *buf++ = (val >> 24);
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 16 & 0xff);
+#endif
+ *buf++ = (val >> 16);
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 8 & 0xff);
+#endif
+ *buf++ = (val >> 8);
+#ifdef SHOW_NUM
+ printf ("%x ", val & 0xff);
+#endif
+ *buf++ = val;
+ break;
+ default:
+ as_fatal (_("Internal logic error. line %s, file \"%s\""),
+ __LINE__, __FILE__);
+ }
+}
+
+static void
+md_number_to_imm (buf, val, n)
+ char *buf;
+ long val;
+ char n;
+{
+ switch (n)
+ {
+ case 1:
+#ifdef SHOW_NUM
+ printf ("%x ", val & 0xff);
+#endif
+ *buf++ = val;
+ break;
+ case 2:
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 8 & 0xff);
+#endif
+ *buf++ = (val >> 8);
+#ifdef SHOW_NUM
+ printf ("%x ", val & 0xff);
+#endif
+ *buf++ = val;
+ break;
+ case 4:
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 24 & 0xff);
+#endif
+ *buf++ = (val >> 24);
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 16 & 0xff);
+#endif
+ *buf++ = (val >> 16);
+#ifdef SHOW_NUM
+ printf ("%x ", val >> 8 & 0xff);
+#endif
+ *buf++ = (val >> 8);
+#ifdef SHOW_NUM
+ printf ("%x ", val & 0xff);
+#endif
+ *buf++ = val;
+ break;
+ default:
+ as_fatal (_("Internal logic error. line %s, file \"%s\""),
+ __LINE__, __FILE__);
+ }
+}
+
+
+/* fast bitfiddling support */
+/* mask used to zero bitfield before oring in the true field */
+
+static unsigned long l_mask[] =
+{
+ 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
+ 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
+ 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
+ 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
+ 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
+ 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
+ 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
+ 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
+};
+static unsigned long r_mask[] =
+{
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+ 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+ 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+ 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+ 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+ 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+ 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+};
+#define MASK_BITS 31
+/* Insert bitfield described by field_ptr and val at buf
+ This routine is written for modification of the first 4 bytes pointed
+ to by buf, to yield speed.
+ The ifdef stuff is for selection between a ns32k-dependent routine
+ and a general version. (My advice: use the general version!)
+ */
+
+static void
+md_number_to_field (buf, val, field_ptr)
+ register char *buf;
+ register long val;
+ register bit_fixS *field_ptr;
+{
+ register unsigned long object;
+ register unsigned long mask;
+ /* define ENDIAN on a ns32k machine */
+#ifdef ENDIAN
+ register unsigned long *mem_ptr;
+#else
+ register char *mem_ptr;
+#endif
+ if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
+ {
+#ifdef ENDIAN
+ if (field_ptr->fx_bit_base)
+ { /* override buf */
+ mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
+ }
+ else
+ {
+ mem_ptr = (unsigned long *) buf;
+ }
+ mem_ptr = ((unsigned long *)
+ ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
+#else
+ if (field_ptr->fx_bit_base)
+ { /* override buf */
+ mem_ptr = (char *) field_ptr->fx_bit_base;
+ }
+ else
+ {
+ mem_ptr = buf;
+ }
+ mem_ptr += field_ptr->fx_bit_base_adj;
+#endif
+#ifdef ENDIAN /* we have a nice ns32k machine with lowbyte
+ at low-physical mem */
+ object = *mem_ptr; /* get some bytes */
+#else /* OVE Goof! the machine is a m68k or dito */
+ /* That takes more byte fiddling */
+ object = 0;
+ object |= mem_ptr[3] & 0xff;
+ object <<= 8;
+ object |= mem_ptr[2] & 0xff;
+ object <<= 8;
+ object |= mem_ptr[1] & 0xff;
+ object <<= 8;
+ object |= mem_ptr[0] & 0xff;
+#endif
+ mask = 0;
+ mask |= (r_mask[field_ptr->fx_bit_offset]);
+ mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
+ object &= mask;
+ val += field_ptr->fx_bit_add;
+ object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
+#ifdef ENDIAN
+ *mem_ptr = object;
+#else
+ mem_ptr[0] = (char) object;
+ object >>= 8;
+ mem_ptr[1] = (char) object;
+ object >>= 8;
+ mem_ptr[2] = (char) object;
+ object >>= 8;
+ mem_ptr[3] = (char) object;
+#endif
+ }
+ else
+ {
+ as_warn (_("Bit field out of range"));
+ }
+}
+
+int md_pcrel_adjust (fragS *fragP)
+{
+ fragS *opcode_frag;
+ addressT opcode_address;
+ unsigned int offset;
+ opcode_frag = frag_opcode_frag(fragP);
+ if (opcode_frag == 0)
+ return 0;
+ offset = frag_opcode_offset(fragP);
+ opcode_address = offset + opcode_frag->fr_address;
+ return fragP->fr_address + fragP->fr_fix - opcode_address;
+}
+
+int md_fix_pcrel_adjust (fixS *fixP)
+{
+ fragS *fragP = fixP->fx_frag;
+ fragS *opcode_frag;
+ addressT opcode_address;
+ unsigned int offset;
+ opcode_frag = fix_opcode_frag(fixP);
+ if (opcode_frag == 0)
+ return 0;
+ offset = fix_opcode_offset(fixP);
+ opcode_address = offset + opcode_frag->fr_address;
+ return fixP->fx_where + fixP->fx_frag->fr_address - opcode_address;
+}
+
+/* Apply a fixS (fixup of an instruction or data that we didn't have
+ enough info to complete immediately) to the data in a frag.
+
+ On the ns32k, everything is in a different format, so we have broken
+ out separate functions for each kind of thing we could be fixing.
+ They all get called from here. */
+
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ valueT *valp;
+#else
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+#endif
+{
+#ifdef BFD_ASSEMBLER
+ long val = *valp;
+#endif
+ fragS *fragP = fixP->fx_frag;
+
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ if (fix_bit_fixP(fixP))
+ { /* Bitfields to fix, sigh */
+ md_number_to_field (buf, val, fix_bit_fixP(fixP));
+ }
+ else
+ switch (fix_im_disp(fixP))
+ {
+
+ case 0: /* Immediate field */
+ md_number_to_imm (buf, val, fixP->fx_size);
+ break;
+
+ case 1: /* Displacement field */
+ /* Calculate offset */
+ {
+ md_number_to_disp (buf,
+ (fixP->fx_pcrel ? val + md_fix_pcrel_adjust(fixP)
+ : val), fixP->fx_size);
+ }
+ break;
+
+ case 2: /* Pointer in a data object */
+ md_number_to_chars (buf, val, fixP->fx_size);
+ break;
+ }
+#ifdef BSD_ASSEMBLER
+ return 1;
+#endif
+}
+
+/* Convert a relaxed displacement to ditto in final output */
+
+#ifndef BFD_ASSEMBLER
+void
+md_convert_frag (headers, sec, fragP)
+ object_headers *headers;
+ segT sec;
+ register fragS *fragP;
+#else
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ register fragS *fragP;
+#endif
+{
+ long disp;
+ long ext = 0;
+
+ /* Address in gas core of the place to store the displacement. */
+ register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
+ /* Address in object code of the displacement. */
+ int object_address;
+
+ fragS *opcode_frag;
+
+ switch (fragP->fr_subtype)
+ {
+ case IND (BRANCH, BYTE):
+ ext = 1;
+ break;
+ case IND (BRANCH, WORD):
+ ext = 2;
+ break;
+ case IND (BRANCH, DOUBLE):
+ ext = 4;
+ break;
+ }
+
+ if(ext == 0)
+ return;
+
+ know (fragP->fr_symbol);
+
+ object_address = fragP->fr_fix + fragP->fr_address;
+ /* The displacement of the address, from current location. */
+ disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
+#ifdef BFD_ASSEMBLER
+ disp += fragP->fr_symbol->sy_frag->fr_address;
+#endif
+ disp += md_pcrel_adjust(fragP);
+
+ md_number_to_disp (buffer_address, (long) disp, (int) ext);
+ fragP->fr_fix += ext;
+}
+
+/* This function returns the estimated size a variable object will occupy,
+ one can say that we tries to guess the size of the objects before we
+ actually know it */
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ register fragS *fragP;
+ segT segment;
+{
+ int old_fix;
+ old_fix = fragP->fr_fix;
+ switch (fragP->fr_subtype)
+ {
+ case IND (BRANCH, UNDEF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ {
+ /* the symbol has been assigned a value */
+ fragP->fr_subtype = IND (BRANCH, BYTE);
+ }
+ else
+ {
+ /* we don't relax symbols defined in an other segment the
+ thing to do is to assume the object will occupy 4 bytes */
+ fix_new_ns32k (fragP,
+ (int) (fragP->fr_fix),
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 1,
+ 1,
+ 0,
+ frag_bsr(fragP), /*sequent hack */
+ frag_opcode_frag(fragP),
+ frag_opcode_offset(fragP));
+ fragP->fr_fix += 4;
+ /* fragP->fr_opcode[1]=0xff; */
+ frag_wane (fragP);
+ break;
+ }
+ case IND (BRANCH, BYTE):
+ fragP->fr_var += 1;
+ break;
+ default:
+ break;
+ }
+ return fragP->fr_var + fragP->fr_fix - old_fix;
+}
+
+int md_short_jump_size = 3;
+int md_long_jump_size = 5;
+const int md_reloc_size = 8; /* Size of relocation record */
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ offset = to_addr - from_addr;
+ md_number_to_chars (ptr, (valueT) 0xEA, 1);
+ md_number_to_disp (ptr + 1, (valueT) offset, 2);
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ offset = to_addr - from_addr;
+ md_number_to_chars (ptr, (valueT) 0xEA, 1);
+ md_number_to_disp (ptr + 1, (valueT) offset, 4);
+}
+
+CONST char *md_shortopts = "m:";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'm':
+ if (!strcmp (arg, "32032"))
+ {
+ cpureg = cpureg_032;
+ mmureg = mmureg_032;
+ }
+ else if (!strcmp (arg, "32532"))
+ {
+ cpureg = cpureg_532;
+ mmureg = mmureg_532;
+ }
+ else
+ {
+ as_bad (_("invalid architecture option -m%s"), arg);
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+NS32K options:\n\
+-m32032 | -m32532 select variant of NS32K architecture\n"));
+}
+
+
+/*
+ * bit_fix_new()
+ *
+ * Create a bit_fixS in obstack 'notes'.
+ * This struct is used to profile the normal fix. If the bit_fixP is a
+ * valid pointer (not NULL) the bit_fix data will be used to format the fix.
+ */
+bit_fixS *
+bit_fix_new (size, offset, min, max, add, base_type, base_adj)
+ char size; /* Length of bitfield */
+ char offset; /* Bit offset to bitfield */
+ long min; /* Signextended min for bitfield */
+ long max; /* Signextended max for bitfield */
+ long add; /* Add mask, used for huffman prefix */
+ long base_type; /* 0 or 1, if 1 it's exploded to opcode ptr */
+ long base_adj;
+{
+ register bit_fixS *bit_fixP;
+
+ bit_fixP = (bit_fixS *) obstack_alloc (&notes, sizeof (bit_fixS));
+
+ bit_fixP->fx_bit_size = size;
+ bit_fixP->fx_bit_offset = offset;
+ bit_fixP->fx_bit_base = base_type;
+ bit_fixP->fx_bit_base_adj = base_adj;
+ bit_fixP->fx_bit_max = max;
+ bit_fixP->fx_bit_min = min;
+ bit_fixP->fx_bit_add = add;
+
+ return (bit_fixP);
+}
+
+void
+fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
+ im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
+ fragS *frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ int size; /* 1, 2 or 4 usually. */
+ symbolS *add_symbol; /* X_add_symbol. */
+ long offset; /* X_add_number. */
+ int pcrel; /* TRUE if PC-relative relocation. */
+ char im_disp; /* true if the value to write is a
+ displacement */
+ bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if
+ NULL */
+ char bsr; /* sequent-linker-hack: 1 when relocobject is
+ a bsr */
+ fragS *opcode_frag;
+ unsigned int opcode_offset;
+
+{
+ fixS *fixP = fix_new (frag, where, size, add_symbol,
+ offset, pcrel,
+#ifdef BFD_ASSEMBLER
+ bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
+#else
+ NO_RELOC
+#endif
+ );
+
+ fix_opcode_frag(fixP) = opcode_frag;
+ fix_opcode_offset(fixP) = opcode_offset;
+ fix_im_disp(fixP) = im_disp;
+ fix_bsr(fixP) = bsr;
+ fix_bit_fixP(fixP) = bit_fixP;
+} /* fix_new_ns32k() */
+
+void
+fix_new_ns32k_exp (frag, where, size, exp, pcrel,
+ im_disp, bit_fixP, bsr, opcode_frag, opcode_offset)
+ fragS *frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ int size; /* 1, 2 or 4 usually. */
+ expressionS *exp; /* Expression. */
+ int pcrel; /* TRUE if PC-relative relocation. */
+ char im_disp; /* true if the value to write is a
+ displacement */
+ bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if
+ NULL */
+ char bsr; /* sequent-linker-hack: 1 when relocobject is
+ a bsr */
+ fragS *opcode_frag;
+ unsigned int opcode_offset;
+{
+ fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
+#ifdef BFD_ASSEMBLER
+ bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
+#else
+ NO_RELOC
+#endif
+ );
+
+ fix_opcode_frag(fixP) = opcode_frag;
+ fix_opcode_offset(fixP) = opcode_offset;
+ fix_im_disp(fixP) = im_disp;
+ fix_bsr(fixP) = bsr;
+ fix_bit_fixP(fixP) = bit_fixP;
+} /* fix_new_ns32k() */
+
+/* This is TC_CONS_FIX_NEW, called by emit_expr in read.c. */
+
+void
+cons_fix_new_ns32k (frag, where, size, exp)
+ fragS *frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ int size; /* 1, 2 or 4 usually. */
+ expressionS *exp; /* Expression. */
+{
+ fix_new_ns32k_exp (frag, where, size, exp,
+ 0, 2, 0, 0, 0, 0);
+}
+
+/* We have no need to default values of symbols. */
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ return size; /* Byte alignment is fine */
+}
+
+/* Exactly what point is a PC-relative offset relative TO? On the
+ ns32k, they're relative to the start of the instruction. */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ long res;
+ res = fixP->fx_where + fixP->fx_frag->fr_address;
+#ifdef SEQUENT_COMPATABILITY
+ if (frag_bsr(fixP->fx_frag))
+ res += 0x12 /* FOO Kludge alert! */
+#endif
+ return res;
+}
+
+#ifdef BFD_ASSEMBLER
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type code;
+
+ code = reloc(fixp->fx_size, fixp->fx_pcrel, fix_im_disp(fixp));
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ if (fixp->fx_pcrel)
+ rel->addend = fixp->fx_addnumber;
+ else
+ rel->addend = 0;
+
+ rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (!rel->howto)
+ {
+ const char *name;
+
+ name = S_GET_NAME (fixp->fx_addsy);
+ if (name == NULL)
+ name = _("<unknown>");
+ as_fatal (_("Cannot find relocation type for symbol %s, code %d"),
+ name, (int) code);
+ }
+
+ return rel;
+}
+#else /* BFD_ASSEMBLER */
+
+#ifdef OBJ_AOUT
+void
+cons_fix_new_ns32k (where, fixP, segment_address_in_file)
+ char *where;
+ struct fix *fixP;
+ relax_addressT segment_address_in_file;
+{
+ /*
+ * In: length of relocation (or of address) in chars: 1, 2 or 4.
+ * Out: GNU LD relocation length code: 0, 1, or 2.
+ */
+
+ static unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
+ long r_symbolnum;
+
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ md_number_to_chars (where + 4,
+ ((long) (r_symbolnum)
+ | (long) (fixP->fx_pcrel << 24)
+ | (long) (nbytes_r_length[fixP->fx_size] << 25)
+ | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
+ | (long) (fix_bsr(fixP) << 28)
+ | (long) (fix_im_disp(fixP) << 29)),
+ 4);
+}
+
+#endif /* OBJ_AOUT */
+#endif /* BFD_ASSMEBLER */
+
+/* end of tc-ns32k.c */
diff --git a/gas/config/tc-ns32k.h b/gas/config/tc-ns32k.h
new file mode 100644
index 00000000000..4b038ebc6a0
--- /dev/null
+++ b/gas/config/tc-ns32k.h
@@ -0,0 +1,155 @@
+/* tc-ns32k.h -- Opcode table for National Semi 32k processor
+ Copyright (C) 1987, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_NS32K
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define TC_PCREL_ADJUST(F) md_pcrel_adjust(F)
+
+#ifdef BFD_ASSEMBLER
+#define NO_RELOC BFD_RELOC_NONE
+
+#define TARGET_ARCH bfd_arch_ns32k
+
+#ifndef TARGET_FORMAT /* Maybe defined in te-*.h */
+#define TARGET_FORMAT "a.out-pc532-mach"
+#endif
+#else
+#define NO_RELOC 0
+#endif
+
+#define LOCAL_LABELS_FB 1
+
+#include "bit_fix.h"
+
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+#define tc_crawl_symbol_chain(a) {;} /* not used */
+#define tc_headers_hook(a) {;} /* not used */
+
+#ifdef SEQUENT_COMPATABILITY
+#define DEF_MODEC 20
+#define DEF_MODEL 21
+#endif
+
+#ifndef DEF_MODEC
+#define DEF_MODEC 20
+#endif
+
+#ifndef DEF_MODEL
+#define DEF_MODEL 20
+#endif
+
+#define MAX_ARGS 4
+#define ARG_LEN 50
+
+#define TC_CONS_FIX_NEW cons_fix_new_ns32k
+extern void fix_new_ns32k_exp PARAMS((fragS *frag,
+ int where,
+ int size,
+ expressionS *exp,
+ int pcrel,
+ int im_disp,
+ bit_fixS *bit_fixP, /* really bit_fixS */
+ int bsr,
+ fragS *opcode_frag,
+ unsigned int opcode_offset));
+
+
+extern void fix_new_ns32k PARAMS ((fragS *frag,
+ int where,
+ int size,
+ struct symbol *add_symbol,
+ long offset,
+ int pcrel,
+ int im_disp,
+ bit_fixS *bit_fixP, /* really bit_fixS */
+ int bsr,
+ fragS *opcode_frag,
+ unsigned int opcode_offset));
+
+extern void cons_fix_new_ns32k PARAMS ((fragS *frag,
+ int where,
+ int size,
+ expressionS *exp));
+
+/* the NS32x32 has a non 0 nop instruction which should be used in aligns */
+#define NOP_OPCODE 0xa2
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+#define TC_FRAG_TYPE \
+struct { \
+ fragS *fr_opcode_fragP; \
+ unsigned int fr_opcode_offset; \
+ char fr_bsr; \
+}
+
+#define TC_FRAG_INIT(X) \
+ do \
+ { \
+ frag_opcode_frag (X) = NULL; \
+ frag_opcode_offset (X) = 0; \
+ frag_bsr (X) = 0; \
+ } \
+ while(0)
+
+/* Accessor macros for things which may move around */
+#define frag_opcode_frag(X) (X)->tc_frag_data.fr_opcode_fragP
+#define frag_opcode_offset(X) (X)->tc_frag_data.fr_opcode_offset
+#define frag_bsr(X) (X)->tc_frag_data.fr_bsr
+
+#define TC_FIX_TYPE \
+struct \
+{ \
+ fragS *opcode_fragP; \
+ unsigned int opcode_offset; \
+ unsigned int bsr : 1; \
+}
+
+/* Accessor macros for things which may move around.
+ See comments in write.h. */
+#define fix_im_disp(X) (X)->fx_im_disp
+#define fix_bit_fixP(X) (X)->fx_bit_fixP
+#define fix_opcode_frag(X) (X)->tc_fix_data.opcode_fragP
+#define fix_opcode_offset(X) (X)->tc_fix_data.opcode_offset
+#define fix_bsr(X) (X)->tc_fix_data.bsr
+
+#define TC_INIT_FIX_DATA(X) \
+ do \
+ { \
+ fix_opcode_frag(X) = NULL; \
+ fix_opcode_offset(X) = 0; \
+ fix_bsr(X) = 0; \
+ } \
+ while(0)
+
+#define TC_FIX_DATA_PRINT(FILE, FIXP) \
+ do \
+ { \
+ fprintf((FILE), "opcode_frag=%ld, operand offset=%d, bsr=%d\n", \
+ (unsigned long) fix_opcode_frag (FIXP), \
+ fix_opcode_offset (FIXP), \
+ fix_bsr (FIXP)); \
+ } \
+ while(0)
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
new file mode 100644
index 00000000000..8c31ba64153
--- /dev/null
+++ b/gas/config/tc-ppc.c
@@ -0,0 +1,5003 @@
+/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
+ Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+
+#include "opcode/ppc.h"
+
+#ifdef OBJ_ELF
+#include "elf/ppc.h"
+#endif
+
+#ifdef TE_PE
+#include "coff/pe.h"
+#endif
+
+/* This is the assembler for the PowerPC or POWER (RS/6000) chips. */
+
+/* Tell the main code what the endianness is. */
+extern int target_big_endian;
+
+/* Whether or not, we've set target_big_endian. */
+static int set_target_endian = 0;
+
+/* Whether to use user friendly register names. */
+#ifndef TARGET_REG_NAMES_P
+#ifdef TE_PE
+#define TARGET_REG_NAMES_P true
+#else
+#define TARGET_REG_NAMES_P false
+#endif
+#endif
+
+static boolean reg_names_p = TARGET_REG_NAMES_P;
+
+static boolean register_name PARAMS ((expressionS *));
+static void ppc_set_cpu PARAMS ((void));
+static unsigned long ppc_insert_operand
+ PARAMS ((unsigned long insn, const struct powerpc_operand *operand,
+ offsetT val, char *file, unsigned int line));
+static void ppc_macro PARAMS ((char *str, const struct powerpc_macro *macro));
+static void ppc_byte PARAMS ((int));
+static int ppc_is_toc_sym PARAMS ((symbolS *sym));
+static void ppc_tc PARAMS ((int));
+
+#ifdef OBJ_XCOFF
+static void ppc_comm PARAMS ((int));
+static void ppc_bb PARAMS ((int));
+static void ppc_bc PARAMS ((int));
+static void ppc_bf PARAMS ((int));
+static void ppc_biei PARAMS ((int));
+static void ppc_bs PARAMS ((int));
+static void ppc_eb PARAMS ((int));
+static void ppc_ec PARAMS ((int));
+static void ppc_ef PARAMS ((int));
+static void ppc_es PARAMS ((int));
+static void ppc_csect PARAMS ((int));
+static void ppc_change_csect PARAMS ((symbolS *));
+static void ppc_function PARAMS ((int));
+static void ppc_extern PARAMS ((int));
+static void ppc_lglobl PARAMS ((int));
+static void ppc_section PARAMS ((int));
+static void ppc_named_section PARAMS ((int));
+static void ppc_stabx PARAMS ((int));
+static void ppc_rename PARAMS ((int));
+static void ppc_toc PARAMS ((int));
+static void ppc_xcoff_cons PARAMS ((int));
+static void ppc_vbyte PARAMS ((int));
+#endif
+
+#ifdef OBJ_ELF
+static bfd_reloc_code_real_type ppc_elf_suffix PARAMS ((char **, expressionS *));
+static void ppc_elf_cons PARAMS ((int));
+static void ppc_elf_rdata PARAMS ((int));
+static void ppc_elf_lcomm PARAMS ((int));
+static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
+#endif
+
+#ifdef TE_PE
+static void ppc_set_current_section PARAMS ((segT));
+static void ppc_previous PARAMS ((int));
+static void ppc_pdata PARAMS ((int));
+static void ppc_ydata PARAMS ((int));
+static void ppc_reldata PARAMS ((int));
+static void ppc_rdata PARAMS ((int));
+static void ppc_ualong PARAMS ((int));
+static void ppc_znop PARAMS ((int));
+static void ppc_pe_comm PARAMS ((int));
+static void ppc_pe_section PARAMS ((int));
+static void ppc_pe_function PARAMS ((int));
+static void ppc_pe_tocd PARAMS ((int));
+#endif
+
+/* Generic assembler global variables which must be defined by all
+ targets. */
+
+#ifdef OBJ_ELF
+/* This string holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful. The macro
+ tc_comment_chars points to this. We use this, rather than the
+ usual comment_chars, so that we can switch for Solaris conventions. */
+static const char ppc_solaris_comment_chars[] = "#!";
+static const char ppc_eabi_comment_chars[] = "#";
+
+#ifdef TARGET_SOLARIS_COMMENT
+const char *ppc_comment_chars = ppc_solaris_comment_chars;
+#else
+const char *ppc_comment_chars = ppc_eabi_comment_chars;
+#endif
+#else
+const char comment_chars[] = "#";
+#endif
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+/* The target specific pseudo-ops which we support. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ /* Pseudo-ops which must be overridden. */
+ { "byte", ppc_byte, 0 },
+
+#ifdef OBJ_XCOFF
+ /* Pseudo-ops specific to the RS/6000 XCOFF format. Some of these
+ legitimately belong in the obj-*.c file. However, XCOFF is based
+ on COFF, and is only implemented for the RS/6000. We just use
+ obj-coff.c, and add what we need here. */
+ { "comm", ppc_comm, 0 },
+ { "lcomm", ppc_comm, 1 },
+ { "bb", ppc_bb, 0 },
+ { "bc", ppc_bc, 0 },
+ { "bf", ppc_bf, 0 },
+ { "bi", ppc_biei, 0 },
+ { "bs", ppc_bs, 0 },
+ { "csect", ppc_csect, 0 },
+ { "data", ppc_section, 'd' },
+ { "eb", ppc_eb, 0 },
+ { "ec", ppc_ec, 0 },
+ { "ef", ppc_ef, 0 },
+ { "ei", ppc_biei, 1 },
+ { "es", ppc_es, 0 },
+ { "extern", ppc_extern, 0 },
+ { "function", ppc_function, 0 },
+ { "lglobl", ppc_lglobl, 0 },
+ { "rename", ppc_rename, 0 },
+ { "section", ppc_named_section, 0 },
+ { "stabx", ppc_stabx, 0 },
+ { "text", ppc_section, 't' },
+ { "toc", ppc_toc, 0 },
+ { "long", ppc_xcoff_cons, 2 },
+ { "word", ppc_xcoff_cons, 1 },
+ { "short", ppc_xcoff_cons, 1 },
+ { "vbyte", ppc_vbyte, 0 },
+#endif
+
+#ifdef OBJ_ELF
+ { "long", ppc_elf_cons, 4 },
+ { "word", ppc_elf_cons, 2 },
+ { "short", ppc_elf_cons, 2 },
+ { "rdata", ppc_elf_rdata, 0 },
+ { "rodata", ppc_elf_rdata, 0 },
+ { "lcomm", ppc_elf_lcomm, 0 },
+#endif
+
+#ifdef TE_PE
+ /* Pseudo-ops specific to the Windows NT PowerPC PE (coff) format */
+ { "previous", ppc_previous, 0 },
+ { "pdata", ppc_pdata, 0 },
+ { "ydata", ppc_ydata, 0 },
+ { "reldata", ppc_reldata, 0 },
+ { "rdata", ppc_rdata, 0 },
+ { "ualong", ppc_ualong, 0 },
+ { "znop", ppc_znop, 0 },
+ { "comm", ppc_pe_comm, 0 },
+ { "lcomm", ppc_pe_comm, 1 },
+ { "section", ppc_pe_section, 0 },
+ { "function", ppc_pe_function,0 },
+ { "tocd", ppc_pe_tocd, 0 },
+#endif
+
+ /* This pseudo-op is used even when not generating XCOFF output. */
+ { "tc", ppc_tc, 0 },
+
+ { NULL, NULL, 0 }
+};
+
+
+/* Predefined register names if -mregnames (or default for Windows NT). */
+/* In general, there are lots of them, in an attempt to be compatible */
+/* with a number of other Windows NT assemblers. */
+
+/* Structure to hold information about predefined registers. */
+struct pd_reg
+ {
+ char *name;
+ int value;
+ };
+
+/* List of registers that are pre-defined:
+
+ Each general register has predefined names of the form:
+ 1. r<reg_num> which has the value <reg_num>.
+ 2. r.<reg_num> which has the value <reg_num>.
+
+
+ Each floating point register has predefined names of the form:
+ 1. f<reg_num> which has the value <reg_num>.
+ 2. f.<reg_num> which has the value <reg_num>.
+
+ Each condition register has predefined names of the form:
+ 1. cr<reg_num> which has the value <reg_num>.
+ 2. cr.<reg_num> which has the value <reg_num>.
+
+ There are individual registers as well:
+ sp or r.sp has the value 1
+ rtoc or r.toc has the value 2
+ fpscr has the value 0
+ xer has the value 1
+ lr has the value 8
+ ctr has the value 9
+ pmr has the value 0
+ dar has the value 19
+ dsisr has the value 18
+ dec has the value 22
+ sdr1 has the value 25
+ srr0 has the value 26
+ srr1 has the value 27
+
+ The table is sorted. Suitable for searching by a binary search. */
+
+static const struct pd_reg pre_defined_registers[] =
+{
+ { "cr.0", 0 }, /* Condition Registers */
+ { "cr.1", 1 },
+ { "cr.2", 2 },
+ { "cr.3", 3 },
+ { "cr.4", 4 },
+ { "cr.5", 5 },
+ { "cr.6", 6 },
+ { "cr.7", 7 },
+
+ { "cr0", 0 },
+ { "cr1", 1 },
+ { "cr2", 2 },
+ { "cr3", 3 },
+ { "cr4", 4 },
+ { "cr5", 5 },
+ { "cr6", 6 },
+ { "cr7", 7 },
+
+ { "ctr", 9 },
+
+ { "dar", 19 }, /* Data Access Register */
+ { "dec", 22 }, /* Decrementer */
+ { "dsisr", 18 }, /* Data Storage Interrupt Status Register */
+
+ { "f.0", 0 }, /* Floating point registers */
+ { "f.1", 1 },
+ { "f.10", 10 },
+ { "f.11", 11 },
+ { "f.12", 12 },
+ { "f.13", 13 },
+ { "f.14", 14 },
+ { "f.15", 15 },
+ { "f.16", 16 },
+ { "f.17", 17 },
+ { "f.18", 18 },
+ { "f.19", 19 },
+ { "f.2", 2 },
+ { "f.20", 20 },
+ { "f.21", 21 },
+ { "f.22", 22 },
+ { "f.23", 23 },
+ { "f.24", 24 },
+ { "f.25", 25 },
+ { "f.26", 26 },
+ { "f.27", 27 },
+ { "f.28", 28 },
+ { "f.29", 29 },
+ { "f.3", 3 },
+ { "f.30", 30 },
+ { "f.31", 31 },
+ { "f.4", 4 },
+ { "f.5", 5 },
+ { "f.6", 6 },
+ { "f.7", 7 },
+ { "f.8", 8 },
+ { "f.9", 9 },
+
+ { "f0", 0 },
+ { "f1", 1 },
+ { "f10", 10 },
+ { "f11", 11 },
+ { "f12", 12 },
+ { "f13", 13 },
+ { "f14", 14 },
+ { "f15", 15 },
+ { "f16", 16 },
+ { "f17", 17 },
+ { "f18", 18 },
+ { "f19", 19 },
+ { "f2", 2 },
+ { "f20", 20 },
+ { "f21", 21 },
+ { "f22", 22 },
+ { "f23", 23 },
+ { "f24", 24 },
+ { "f25", 25 },
+ { "f26", 26 },
+ { "f27", 27 },
+ { "f28", 28 },
+ { "f29", 29 },
+ { "f3", 3 },
+ { "f30", 30 },
+ { "f31", 31 },
+ { "f4", 4 },
+ { "f5", 5 },
+ { "f6", 6 },
+ { "f7", 7 },
+ { "f8", 8 },
+ { "f9", 9 },
+
+ { "fpscr", 0 },
+
+ { "lr", 8 }, /* Link Register */
+
+ { "pmr", 0 },
+
+ { "r.0", 0 }, /* General Purpose Registers */
+ { "r.1", 1 },
+ { "r.10", 10 },
+ { "r.11", 11 },
+ { "r.12", 12 },
+ { "r.13", 13 },
+ { "r.14", 14 },
+ { "r.15", 15 },
+ { "r.16", 16 },
+ { "r.17", 17 },
+ { "r.18", 18 },
+ { "r.19", 19 },
+ { "r.2", 2 },
+ { "r.20", 20 },
+ { "r.21", 21 },
+ { "r.22", 22 },
+ { "r.23", 23 },
+ { "r.24", 24 },
+ { "r.25", 25 },
+ { "r.26", 26 },
+ { "r.27", 27 },
+ { "r.28", 28 },
+ { "r.29", 29 },
+ { "r.3", 3 },
+ { "r.30", 30 },
+ { "r.31", 31 },
+ { "r.4", 4 },
+ { "r.5", 5 },
+ { "r.6", 6 },
+ { "r.7", 7 },
+ { "r.8", 8 },
+ { "r.9", 9 },
+
+ { "r.sp", 1 }, /* Stack Pointer */
+
+ { "r.toc", 2 }, /* Pointer to the table of contents */
+
+ { "r0", 0 }, /* More general purpose registers */
+ { "r1", 1 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "r16", 16 },
+ { "r17", 17 },
+ { "r18", 18 },
+ { "r19", 19 },
+ { "r2", 2 },
+ { "r20", 20 },
+ { "r21", 21 },
+ { "r22", 22 },
+ { "r23", 23 },
+ { "r24", 24 },
+ { "r25", 25 },
+ { "r26", 26 },
+ { "r27", 27 },
+ { "r28", 28 },
+ { "r29", 29 },
+ { "r3", 3 },
+ { "r30", 30 },
+ { "r31", 31 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+
+ { "rtoc", 2 }, /* Table of contents */
+
+ { "sdr1", 25 }, /* Storage Description Register 1 */
+
+ { "sp", 1 },
+
+ { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
+ { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
+
+ { "xer", 1 },
+
+};
+
+#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
+
+/* Given NAME, find the register number associated with that name, return
+ the integer value associated with the given name or -1 on failure. */
+
+static int reg_name_search
+ PARAMS ((const struct pd_reg *, int, const char * name));
+
+static int
+reg_name_search (regs, regcount, name)
+ const struct pd_reg *regs;
+ int regcount;
+ const char *name;
+{
+ int middle, low, high;
+ int cmp;
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+
+ return -1;
+}
+
+/*
+ * Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in its
+ * original state.
+ */
+
+static boolean
+register_name (expressionP)
+ expressionS *expressionP;
+{
+ int reg_number;
+ char *name;
+ char *start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+ if (name[0] == '%' && isalpha (name[1]))
+ name = ++input_line_pointer;
+
+ else if (!reg_names_p || !isalpha (name[0]))
+ return false;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ *input_line_pointer = c; /* put back the delimiting char */
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return false;
+ }
+}
+
+/* This function is called for each symbol seen in an expression. It
+ handles the special parsing which PowerPC assemblers are supposed
+ to use for condition codes. */
+
+/* Whether to do the special parsing. */
+static boolean cr_operand;
+
+/* Names to recognize in a condition code. This table is sorted. */
+static const struct pd_reg cr_names[] =
+{
+ { "cr0", 0 },
+ { "cr1", 1 },
+ { "cr2", 2 },
+ { "cr3", 3 },
+ { "cr4", 4 },
+ { "cr5", 5 },
+ { "cr6", 6 },
+ { "cr7", 7 },
+ { "eq", 2 },
+ { "gt", 1 },
+ { "lt", 0 },
+ { "so", 3 },
+ { "un", 3 }
+};
+
+/* Parsing function. This returns non-zero if it recognized an
+ expression. */
+
+int
+ppc_parse_name (name, expr)
+ const char *name;
+ expressionS *expr;
+{
+ int val;
+
+ if (! cr_operand)
+ return 0;
+
+ val = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0],
+ name);
+ if (val < 0)
+ return 0;
+
+ expr->X_op = O_constant;
+ expr->X_add_number = val;
+
+ return 1;
+}
+
+/* Local variables. */
+
+/* The type of processor we are assembling for. This is one or more
+ of the PPC_OPCODE flags defined in opcode/ppc.h. */
+static int ppc_cpu = 0;
+
+/* The size of the processor we are assembling for. This is either
+ PPC_OPCODE_32 or PPC_OPCODE_64. */
+static int ppc_size = PPC_OPCODE_32;
+
+/* Opcode hash table. */
+static struct hash_control *ppc_hash;
+
+/* Macro hash table. */
+static struct hash_control *ppc_macro_hash;
+
+#ifdef OBJ_ELF
+/* What type of shared library support to use */
+static enum { SHLIB_NONE, SHLIB_PIC, SHILB_MRELOCATABLE } shlib = SHLIB_NONE;
+
+/* Flags to set in the elf header */
+static flagword ppc_flags = 0;
+
+/* Whether this is Solaris or not. */
+#ifdef TARGET_SOLARIS_COMMENT
+#define SOLARIS_P true
+#else
+#define SOLARIS_P false
+#endif
+
+static boolean msolaris = SOLARIS_P;
+#endif
+
+#ifdef OBJ_XCOFF
+
+/* The RS/6000 assembler uses the .csect pseudo-op to generate code
+ using a bunch of different sections. These assembler sections,
+ however, are all encompassed within the .text or .data sections of
+ the final output file. We handle this by using different
+ subsegments within these main segments. */
+
+/* Next subsegment to allocate within the .text segment. */
+static subsegT ppc_text_subsegment = 2;
+
+/* Linked list of csects in the text section. */
+static symbolS *ppc_text_csects;
+
+/* Next subsegment to allocate within the .data segment. */
+static subsegT ppc_data_subsegment = 2;
+
+/* Linked list of csects in the data section. */
+static symbolS *ppc_data_csects;
+
+/* The current csect. */
+static symbolS *ppc_current_csect;
+
+/* The RS/6000 assembler uses a TOC which holds addresses of functions
+ and variables. Symbols are put in the TOC with the .tc pseudo-op.
+ A special relocation is used when accessing TOC entries. We handle
+ the TOC as a subsegment within the .data segment. We set it up if
+ we see a .toc pseudo-op, and save the csect symbol here. */
+static symbolS *ppc_toc_csect;
+
+/* The first frag in the TOC subsegment. */
+static fragS *ppc_toc_frag;
+
+/* The first frag in the first subsegment after the TOC in the .data
+ segment. NULL if there are no subsegments after the TOC. */
+static fragS *ppc_after_toc_frag;
+
+/* The current static block. */
+static symbolS *ppc_current_block;
+
+/* The COFF debugging section; set by md_begin. This is not the
+ .debug section, but is instead the secret BFD section which will
+ cause BFD to set the section number of a symbol to N_DEBUG. */
+static asection *ppc_coff_debug_section;
+
+#endif /* OBJ_XCOFF */
+
+#ifdef TE_PE
+
+/* Various sections that we need for PE coff support. */
+static segT ydata_section;
+static segT pdata_section;
+static segT reldata_section;
+static segT rdata_section;
+static segT tocdata_section;
+
+/* The current section and the previous section. See ppc_previous. */
+static segT ppc_previous_section;
+static segT ppc_current_section;
+
+#endif /* TE_PE */
+
+#ifdef OBJ_ELF
+symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
+#endif /* OBJ_ELF */
+
+#ifdef OBJ_ELF
+CONST char *md_shortopts = "b:l:usm:K:VQ:";
+#else
+CONST char *md_shortopts = "um:";
+#endif
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'u':
+ /* -u means that any undefined symbols should be treated as
+ external, which is the default for gas anyhow. */
+ break;
+
+#ifdef OBJ_ELF
+ case 'l':
+ /* Solaris as takes -le (presumably for little endian). For completeness
+ sake, recognize -be also. */
+ if (strcmp (arg, "e") == 0)
+ {
+ target_big_endian = 0;
+ set_target_endian = 1;
+ }
+ else
+ return 0;
+
+ break;
+
+ case 'b':
+ if (strcmp (arg, "e") == 0)
+ {
+ target_big_endian = 1;
+ set_target_endian = 1;
+ }
+ else
+ return 0;
+
+ break;
+
+ case 'K':
+ /* Recognize -K PIC */
+ if (strcmp (arg, "PIC") == 0 || strcmp (arg, "pic") == 0)
+ {
+ shlib = SHLIB_PIC;
+ ppc_flags |= EF_PPC_RELOCATABLE_LIB;
+ }
+ else
+ return 0;
+
+ break;
+#endif
+
+ case 'm':
+ /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
+ (RIOS2). */
+ if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
+ ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2;
+ /* -mpwr means to assemble for the IBM POWER (RIOS1). */
+ else if (strcmp (arg, "pwr") == 0)
+ ppc_cpu = PPC_OPCODE_POWER;
+ /* -m601 means to assemble for the Motorola PowerPC 601, which includes
+ instructions that are holdovers from the Power. */
+ else if (strcmp (arg, "601") == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_601;
+ /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
+ Motorola PowerPC 603/604. */
+ else if (strcmp (arg, "ppc") == 0
+ || strcmp (arg, "ppc32") == 0
+ || strcmp (arg, "403") == 0
+ || strcmp (arg, "603") == 0
+ || strcmp (arg, "604") == 0)
+ ppc_cpu = PPC_OPCODE_PPC;
+ /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
+ 620. */
+ else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
+ {
+ ppc_cpu = PPC_OPCODE_PPC;
+ ppc_size = PPC_OPCODE_64;
+ }
+ /* -mcom means assemble for the common intersection between Power
+ and PowerPC. At present, we just allow the union, rather
+ than the intersection. */
+ else if (strcmp (arg, "com") == 0)
+ ppc_cpu = PPC_OPCODE_COMMON;
+ /* -many means to assemble for any architecture (PWR/PWRX/PPC). */
+ else if (strcmp (arg, "any") == 0)
+ ppc_cpu = PPC_OPCODE_ANY;
+
+ else if (strcmp (arg, "regnames") == 0)
+ reg_names_p = true;
+
+ else if (strcmp (arg, "no-regnames") == 0)
+ reg_names_p = false;
+
+#ifdef OBJ_ELF
+ /* -mrelocatable/-mrelocatable-lib -- warn about initializations that require relocation */
+ else if (strcmp (arg, "relocatable") == 0)
+ {
+ shlib = SHILB_MRELOCATABLE;
+ ppc_flags |= EF_PPC_RELOCATABLE;
+ }
+
+ else if (strcmp (arg, "relocatable-lib") == 0)
+ {
+ shlib = SHILB_MRELOCATABLE;
+ ppc_flags |= EF_PPC_RELOCATABLE_LIB;
+ }
+
+ /* -memb, set embedded bit */
+ else if (strcmp (arg, "emb") == 0)
+ ppc_flags |= EF_PPC_EMB;
+
+ /* -mlittle/-mbig set the endianess */
+ else if (strcmp (arg, "little") == 0 || strcmp (arg, "little-endian") == 0)
+ {
+ target_big_endian = 0;
+ set_target_endian = 1;
+ }
+
+ else if (strcmp (arg, "big") == 0 || strcmp (arg, "big-endian") == 0)
+ {
+ target_big_endian = 1;
+ set_target_endian = 1;
+ }
+
+ else if (strcmp (arg, "solaris") == 0)
+ {
+ msolaris = true;
+ ppc_comment_chars = ppc_solaris_comment_chars;
+ }
+
+ else if (strcmp (arg, "no-solaris") == 0)
+ {
+ msolaris = false;
+ ppc_comment_chars = ppc_eabi_comment_chars;
+ }
+#endif
+ else
+ {
+ as_bad (_("invalid switch -m%s"), arg);
+ return 0;
+ }
+ break;
+
+#ifdef OBJ_ELF
+ /* -V: SVR4 argument to print version ID. */
+ case 'V':
+ print_version_id ();
+ break;
+
+ /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
+ should be emitted or not. FIXME: Not implemented. */
+ case 'Q':
+ break;
+
+ /* Solaris takes -s to specify that .stabs go in a .stabs section,
+ rather than .stabs.excl, which is ignored by the linker.
+ FIXME: Not implemented. */
+ case 's':
+ if (arg)
+ return 0;
+
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+PowerPC options:\n\
+-u ignored\n\
+-mpwrx, -mpwr2 generate code for IBM POWER/2 (RIOS2)\n\
+-mpwr generate code for IBM POWER (RIOS1)\n\
+-m601 generate code for Motorola PowerPC 601\n\
+-mppc, -mppc32, -m403, -m603, -m604\n\
+ generate code for Motorola PowerPC 603/604\n\
+-mppc64, -m620 generate code for Motorola PowerPC 620\n\
+-mcom generate code Power/PowerPC common instructions\n\
+-many generate code for any architecture (PWR/PWRX/PPC)\n\
+-mregnames Allow symbolic names for registers\n\
+-mno-regnames Do not allow symbolic names for registers\n"));
+#ifdef OBJ_ELF
+ fprintf(stream, _("\
+-mrelocatable support for GCC's -mrelocatble option\n\
+-mrelocatable-lib support for GCC's -mrelocatble-lib option\n\
+-memb set PPC_EMB bit in ELF flags\n\
+-mlittle, -mlittle-endian\n\
+ generate code for a little endian machine\n\
+-mbig, -mbig-endian generate code for a big endian machine\n\
+-msolaris generate code for Solaris\n\
+-mno-solaris do not generate code for Solaris\n\
+-V print assembler version number\n\
+-Qy, -Qn ignored\n"));
+#endif
+}
+
+/* Set ppc_cpu if it is not already set. */
+
+static void
+ppc_set_cpu ()
+{
+ const char *default_os = TARGET_OS;
+ const char *default_cpu = TARGET_CPU;
+
+ if (ppc_cpu == 0)
+ {
+ if (strncmp (default_os, "aix", 3) == 0
+ && default_os[3] >= '4' && default_os[3] <= '9')
+ ppc_cpu = PPC_OPCODE_COMMON;
+ else if (strncmp (default_os, "aix3", 4) == 0)
+ ppc_cpu = PPC_OPCODE_POWER;
+ else if (strcmp (default_cpu, "rs6000") == 0)
+ ppc_cpu = PPC_OPCODE_POWER;
+ else if (strcmp (default_cpu, "powerpc") == 0
+ || strcmp (default_cpu, "powerpcle") == 0)
+ ppc_cpu = PPC_OPCODE_PPC;
+ else
+ as_fatal (_("Unknown default cpu = %s, os = %s"), default_cpu, default_os);
+ }
+}
+
+/* Figure out the BFD architecture to use. */
+
+enum bfd_architecture
+ppc_arch ()
+{
+ const char *default_cpu = TARGET_CPU;
+ ppc_set_cpu ();
+
+ if ((ppc_cpu & PPC_OPCODE_PPC) != 0)
+ return bfd_arch_powerpc;
+ else if ((ppc_cpu & PPC_OPCODE_POWER) != 0)
+ return bfd_arch_rs6000;
+ else if ((ppc_cpu & (PPC_OPCODE_COMMON | PPC_OPCODE_ANY)) != 0)
+ {
+ if (strcmp (default_cpu, "rs6000") == 0)
+ return bfd_arch_rs6000;
+ else if (strcmp (default_cpu, "powerpc") == 0
+ || strcmp (default_cpu, "powerpcle") == 0)
+ return bfd_arch_powerpc;
+ }
+
+ as_fatal (_("Neither Power nor PowerPC opcodes were selected."));
+ return bfd_arch_unknown;
+}
+
+/* This function is called when the assembler starts up. It is called
+ after the options have been parsed and the output file has been
+ opened. */
+
+void
+md_begin ()
+{
+ register const struct powerpc_opcode *op;
+ const struct powerpc_opcode *op_end;
+ const struct powerpc_macro *macro;
+ const struct powerpc_macro *macro_end;
+ boolean dup_insn = false;
+
+ ppc_set_cpu ();
+
+#ifdef OBJ_ELF
+ /* Set the ELF flags if desired. */
+ if (ppc_flags && !msolaris)
+ bfd_set_private_flags (stdoutput, ppc_flags);
+#endif
+
+ /* Insert the opcodes into a hash table. */
+ ppc_hash = hash_new ();
+
+ op_end = powerpc_opcodes + powerpc_num_opcodes;
+ for (op = powerpc_opcodes; op < op_end; op++)
+ {
+ know ((op->opcode & op->mask) == op->opcode);
+
+ if ((op->flags & ppc_cpu) != 0
+ && ((op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0
+ || (op->flags & (PPC_OPCODE_32 | PPC_OPCODE_64)) == ppc_size))
+ {
+ const char *retval;
+
+ retval = hash_insert (ppc_hash, op->name, (PTR) op);
+ if (retval != (const char *) NULL)
+ {
+ /* Ignore Power duplicates for -m601 */
+ if ((ppc_cpu & PPC_OPCODE_601) != 0
+ && (op->flags & PPC_OPCODE_POWER) != 0)
+ continue;
+
+ as_bad (_("Internal assembler error for instruction %s"), op->name);
+ dup_insn = true;
+ }
+ }
+ }
+
+ /* Insert the macros into a hash table. */
+ ppc_macro_hash = hash_new ();
+
+ macro_end = powerpc_macros + powerpc_num_macros;
+ for (macro = powerpc_macros; macro < macro_end; macro++)
+ {
+ if ((macro->flags & ppc_cpu) != 0)
+ {
+ const char *retval;
+
+ retval = hash_insert (ppc_macro_hash, macro->name, (PTR) macro);
+ if (retval != (const char *) NULL)
+ {
+ as_bad (_("Internal assembler error for macro %s"), macro->name);
+ dup_insn = true;
+ }
+ }
+ }
+
+ if (dup_insn)
+ abort ();
+
+ /* Tell the main code what the endianness is if it is not overidden by the user. */
+ if (!set_target_endian)
+ {
+ set_target_endian = 1;
+ target_big_endian = PPC_BIG_ENDIAN;
+ }
+
+#ifdef OBJ_XCOFF
+ ppc_coff_debug_section = coff_section_from_bfd_index (stdoutput, N_DEBUG);
+
+ /* Create dummy symbols to serve as initial csects. This forces the
+ text csects to precede the data csects. These symbols will not
+ be output. */
+ ppc_text_csects = symbol_make ("dummy\001");
+ ppc_text_csects->sy_tc.within = ppc_text_csects;
+ ppc_data_csects = symbol_make ("dummy\001");
+ ppc_data_csects->sy_tc.within = ppc_data_csects;
+#endif
+
+#ifdef TE_PE
+
+ ppc_current_section = text_section;
+ ppc_previous_section = 0;
+
+#endif
+}
+
+/* Insert an operand value into an instruction. */
+
+static unsigned long
+ppc_insert_operand (insn, operand, val, file, line)
+ unsigned long insn;
+ const struct powerpc_operand *operand;
+ offsetT val;
+ char *file;
+ unsigned int line;
+{
+ if (operand->bits != 32)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ {
+ if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0
+ && ppc_size == PPC_OPCODE_32)
+ max = (1 << operand->bits) - 1;
+ else
+ max = (1 << (operand->bits - 1)) - 1;
+ min = - (1 << (operand->bits - 1));
+
+ if (ppc_size == PPC_OPCODE_32)
+ {
+ /* Some people write 32 bit hex constants with the sign
+ extension done by hand. This shouldn't really be
+ valid, but, to permit this code to assemble on a 64
+ bit host, we sign extend the 32 bit value. */
+ if (val > 0
+ && (val & 0x80000000) != 0
+ && (val & 0xffffffff) == val)
+ {
+ val -= 0x80000000;
+ val -= 0x80000000;
+ }
+ }
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+ min = 0;
+ }
+
+ if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)
+ test = - val;
+ else
+ test = val;
+
+ if (test < (offsetT) min || test > (offsetT) max)
+ {
+ const char *err =
+ _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ sprint_value (buf, test);
+ if (file == (char *) NULL)
+ as_bad (err, buf, min, max);
+ else
+ as_bad_where (file, line, err, buf, min, max);
+ }
+ }
+
+ if (operand->insert)
+ {
+ const char *errmsg;
+
+ errmsg = NULL;
+ insn = (*operand->insert) (insn, (long) val, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_bad (errmsg);
+ }
+ else
+ insn |= (((long) val & ((1 << operand->bits) - 1))
+ << operand->shift);
+
+ return insn;
+}
+
+
+#ifdef OBJ_ELF
+/* Parse @got, etc. and return the desired relocation. */
+static bfd_reloc_code_real_type
+ppc_elf_suffix (str_p, exp_p)
+ char **str_p;
+ expressionS *exp_p;
+{
+ struct map_bfd {
+ char *string;
+ int length;
+ bfd_reloc_code_real_type reloc;
+ };
+
+ char ident[20];
+ char *str = *str_p;
+ char *str2;
+ int ch;
+ int len;
+ struct map_bfd *ptr;
+
+#define MAP(str,reloc) { str, sizeof(str)-1, reloc }
+
+ static struct map_bfd mapping[] = {
+ MAP ("l", BFD_RELOC_LO16),
+ MAP ("h", BFD_RELOC_HI16),
+ MAP ("ha", BFD_RELOC_HI16_S),
+ MAP ("brtaken", BFD_RELOC_PPC_B16_BRTAKEN),
+ MAP ("brntaken", BFD_RELOC_PPC_B16_BRNTAKEN),
+ MAP ("got", BFD_RELOC_16_GOTOFF),
+ MAP ("got@l", BFD_RELOC_LO16_GOTOFF),
+ MAP ("got@h", BFD_RELOC_HI16_GOTOFF),
+ MAP ("got@ha", BFD_RELOC_HI16_S_GOTOFF),
+ MAP ("fixup", BFD_RELOC_CTOR), /* warnings with -mrelocatable */
+ MAP ("plt", BFD_RELOC_24_PLT_PCREL),
+ MAP ("pltrel24", BFD_RELOC_24_PLT_PCREL),
+ MAP ("copy", BFD_RELOC_PPC_COPY),
+ MAP ("globdat", BFD_RELOC_PPC_GLOB_DAT),
+ MAP ("local24pc", BFD_RELOC_PPC_LOCAL24PC),
+ MAP ("local", BFD_RELOC_PPC_LOCAL24PC),
+ MAP ("pltrel", BFD_RELOC_32_PLT_PCREL),
+ MAP ("plt@l", BFD_RELOC_LO16_PLTOFF),
+ MAP ("plt@h", BFD_RELOC_HI16_PLTOFF),
+ MAP ("plt@ha", BFD_RELOC_HI16_S_PLTOFF),
+ MAP ("sdarel", BFD_RELOC_GPREL16),
+ MAP ("sectoff", BFD_RELOC_32_BASEREL),
+ MAP ("sectoff@l", BFD_RELOC_LO16_BASEREL),
+ MAP ("sectoff@h", BFD_RELOC_HI16_BASEREL),
+ MAP ("sectoff@ha", BFD_RELOC_HI16_S_BASEREL),
+ MAP ("naddr", BFD_RELOC_PPC_EMB_NADDR32),
+ MAP ("naddr16", BFD_RELOC_PPC_EMB_NADDR16),
+ MAP ("naddr@l", BFD_RELOC_PPC_EMB_NADDR16_LO),
+ MAP ("naddr@h", BFD_RELOC_PPC_EMB_NADDR16_HI),
+ MAP ("naddr@ha", BFD_RELOC_PPC_EMB_NADDR16_HA),
+ MAP ("sdai16", BFD_RELOC_PPC_EMB_SDAI16),
+ MAP ("sda2rel", BFD_RELOC_PPC_EMB_SDA2REL),
+ MAP ("sda2i16", BFD_RELOC_PPC_EMB_SDA2I16),
+ MAP ("sda21", BFD_RELOC_PPC_EMB_SDA21),
+ MAP ("mrkref", BFD_RELOC_PPC_EMB_MRKREF),
+ MAP ("relsect", BFD_RELOC_PPC_EMB_RELSEC16),
+ MAP ("relsect@l", BFD_RELOC_PPC_EMB_RELST_LO),
+ MAP ("relsect@h", BFD_RELOC_PPC_EMB_RELST_HI),
+ MAP ("relsect@ha", BFD_RELOC_PPC_EMB_RELST_HA),
+ MAP ("bitfld", BFD_RELOC_PPC_EMB_BIT_FLD),
+ MAP ("relsda", BFD_RELOC_PPC_EMB_RELSDA),
+ MAP ("xgot", BFD_RELOC_PPC_TOC16),
+
+ { (char *)0, 0, BFD_RELOC_UNUSED }
+ };
+
+ if (*str++ != '@')
+ return BFD_RELOC_UNUSED;
+
+ for (ch = *str, str2 = ident;
+ (str2 < ident + sizeof (ident) - 1
+ && (isalnum (ch) || ch == '@'));
+ ch = *++str)
+ {
+ *str2++ = (islower (ch)) ? ch : tolower (ch);
+ }
+
+ *str2 = '\0';
+ len = str2 - ident;
+
+ ch = ident[0];
+ for (ptr = &mapping[0]; ptr->length > 0; ptr++)
+ if (ch == ptr->string[0]
+ && len == ptr->length
+ && memcmp (ident, ptr->string, ptr->length) == 0)
+ {
+ if (exp_p->X_add_number != 0
+ && (ptr->reloc == BFD_RELOC_16_GOTOFF
+ || ptr->reloc == BFD_RELOC_LO16_GOTOFF
+ || ptr->reloc == BFD_RELOC_HI16_GOTOFF
+ || ptr->reloc == BFD_RELOC_HI16_S_GOTOFF))
+ as_warn (_("identifier+constant@got means identifier@got+constant"));
+
+ /* Now check for identifier@suffix+constant */
+ if (*str == '-' || *str == '+')
+ {
+ char *orig_line = input_line_pointer;
+ expressionS new_exp;
+
+ input_line_pointer = str;
+ expression (&new_exp);
+ if (new_exp.X_op == O_constant)
+ {
+ exp_p->X_add_number += new_exp.X_add_number;
+ str = input_line_pointer;
+ }
+
+ if (&input_line_pointer != str_p)
+ input_line_pointer = orig_line;
+ }
+
+ *str_p = str;
+ return ptr->reloc;
+ }
+
+ return BFD_RELOC_UNUSED;
+}
+
+/* Like normal .long/.short/.word, except support @got, etc. */
+/* clobbers input_line_pointer, checks */
+/* end-of-line. */
+static void
+ppc_elf_cons (nbytes)
+ register int nbytes; /* 1=.byte, 2=.word, 4=.long */
+{
+ expressionS exp;
+ bfd_reloc_code_real_type reloc;
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ expression (&exp);
+ if (exp.X_op == O_symbol
+ && *input_line_pointer == '@'
+ && (reloc = ppc_elf_suffix (&input_line_pointer, &exp)) != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
+ int size = bfd_get_reloc_size (reloc_howto);
+
+ if (size > nbytes)
+ as_bad (_("%s relocations do not fit in %d bytes\n"), reloc_howto->name, nbytes);
+
+ else
+ {
+ register char *p = frag_more ((int) nbytes);
+ int offset = nbytes - size;
+
+ fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size, &exp, 0, reloc);
+ }
+ }
+ else
+ emit_expr (&exp, (unsigned int) nbytes);
+ }
+ while (*input_line_pointer++ == ',');
+
+ input_line_pointer--; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+}
+
+/* Solaris pseduo op to change to the .rodata section. */
+static void
+ppc_elf_rdata (xxx)
+ int xxx;
+{
+ char *save_line = input_line_pointer;
+ static char section[] = ".rodata\n";
+
+ /* Just pretend this is .section .rodata */
+ input_line_pointer = section;
+ obj_elf_section (xxx);
+
+ input_line_pointer = save_line;
+}
+
+/* Pseudo op to make file scope bss items */
+static void
+ppc_elf_lcomm(xxx)
+ int xxx;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT size;
+ register symbolS *symbolP;
+ offsetT align;
+ segT old_sec;
+ int old_subsec;
+ char *pfrag;
+ int align2;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ if ((size = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* The third argument to .lcomm is the alignment. */
+ if (*input_line_pointer != ',')
+ align = 8;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 8;
+ }
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
+ {
+ as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) size);
+
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* allocate_bss: */
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+ if (align)
+ {
+ /* convert to a power of 2 alignment */
+ for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
+ if (align != 1)
+ {
+ as_bad (_("Common alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align2 = 0;
+
+ record_alignment (bss_section, align2);
+ subseg_set (bss_section, 0);
+ if (align2)
+ frag_align (align2, 0, 0);
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ symbolP->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
+ (char *) 0);
+ *pfrag = 0;
+ S_SET_SIZE (symbolP, size);
+ S_SET_SEGMENT (symbolP, bss_section);
+ subseg_set (old_sec, old_subsec);
+ demand_empty_rest_of_line ();
+}
+
+/* Validate any relocations emitted for -mrelocatable, possibly adding
+ fixups for word relocations in writable segments, so we can adjust
+ them at runtime. */
+static void
+ppc_elf_validate_fix (fixp, seg)
+ fixS *fixp;
+ segT seg;
+{
+ if (fixp->fx_done || fixp->fx_pcrel)
+ return;
+
+ switch (shlib)
+ {
+ case SHLIB_NONE:
+ case SHLIB_PIC:
+ return;
+
+ case SHILB_MRELOCATABLE:
+ if (fixp->fx_r_type <= BFD_RELOC_UNUSED
+ && fixp->fx_r_type != BFD_RELOC_16_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
+ && fixp->fx_r_type != BFD_RELOC_32_BASEREL
+ && fixp->fx_r_type != BFD_RELOC_LO16_BASEREL
+ && fixp->fx_r_type != BFD_RELOC_HI16_BASEREL
+ && fixp->fx_r_type != BFD_RELOC_HI16_S_BASEREL
+ && strcmp (segment_name (seg), ".got2") != 0
+ && strcmp (segment_name (seg), ".dtors") != 0
+ && strcmp (segment_name (seg), ".ctors") != 0
+ && strcmp (segment_name (seg), ".fixup") != 0
+ && strcmp (segment_name (seg), ".stab") != 0
+ && strcmp (segment_name (seg), ".gcc_except_table") != 0
+ && strcmp (segment_name (seg), ".eh_frame") != 0
+ && strcmp (segment_name (seg), ".ex_shared") != 0)
+ {
+ if ((seg->flags & (SEC_READONLY | SEC_CODE)) != 0
+ || fixp->fx_r_type != BFD_RELOC_CTOR)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Relocation cannot be done when using -mrelocatable"));
+ }
+ }
+ return;
+ }
+}
+#endif /* OBJ_ELF */
+
+#ifdef TE_PE
+
+/*
+ * Summary of parse_toc_entry().
+ *
+ * in: Input_line_pointer points to the '[' in one of:
+ *
+ * [toc] [tocv] [toc32] [toc64]
+ *
+ * Anything else is an error of one kind or another.
+ *
+ * out:
+ * return value: success or failure
+ * toc_kind: kind of toc reference
+ * input_line_pointer:
+ * success: first char after the ']'
+ * failure: unchanged
+ *
+ * settings:
+ *
+ * [toc] - rv == success, toc_kind = default_toc
+ * [tocv] - rv == success, toc_kind = data_in_toc
+ * [toc32] - rv == success, toc_kind = must_be_32
+ * [toc64] - rv == success, toc_kind = must_be_64
+ *
+ */
+
+enum toc_size_qualifier
+{
+ default_toc, /* The toc cell constructed should be the system default size */
+ data_in_toc, /* This is a direct reference to a toc cell */
+ must_be_32, /* The toc cell constructed must be 32 bits wide */
+ must_be_64 /* The toc cell constructed must be 64 bits wide */
+};
+
+static int
+parse_toc_entry(toc_kind)
+ enum toc_size_qualifier *toc_kind;
+{
+ char *start;
+ char *toc_spec;
+ char c;
+ enum toc_size_qualifier t;
+
+ /* save the input_line_pointer */
+ start = input_line_pointer;
+
+ /* skip over the '[' , and whitespace */
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+
+ /* find the spelling of the operand */
+ toc_spec = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strcmp(toc_spec, "toc") == 0)
+ {
+ t = default_toc;
+ }
+ else if (strcmp(toc_spec, "tocv") == 0)
+ {
+ t = data_in_toc;
+ }
+ else if (strcmp(toc_spec, "toc32") == 0)
+ {
+ t = must_be_32;
+ }
+ else if (strcmp(toc_spec, "toc64") == 0)
+ {
+ t = must_be_64;
+ }
+ else
+ {
+ as_bad (_("syntax error: invalid toc specifier `%s'"), toc_spec);
+ *input_line_pointer = c; /* put back the delimiting char */
+ input_line_pointer = start; /* reset input_line pointer */
+ return 0;
+ }
+
+ /* now find the ']' */
+ *input_line_pointer = c; /* put back the delimiting char */
+
+ SKIP_WHITESPACE (); /* leading whitespace could be there. */
+ c = *input_line_pointer++; /* input_line_pointer->past char in c. */
+
+ if (c != ']')
+ {
+ as_bad (_("syntax error: expected `]', found `%c'"), c);
+ input_line_pointer = start; /* reset input_line pointer */
+ return 0;
+ }
+
+ *toc_kind = t; /* set return value */
+ return 1;
+}
+#endif
+
+
+/* We need to keep a list of fixups. We can't simply generate them as
+ we go, because that would require us to first create the frag, and
+ that would screw up references to ``.''. */
+
+struct ppc_fixup
+{
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+};
+
+#define MAX_INSN_FIXUPS (5)
+
+/* This routine is called for each instruction to be assembled. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *s;
+ const struct powerpc_opcode *opcode;
+ unsigned long insn;
+ const unsigned char *opindex_ptr;
+ int skip_optional;
+ int need_paren;
+ int next_opindex;
+ struct ppc_fixup fixups[MAX_INSN_FIXUPS];
+ int fc;
+ char *f;
+ int i;
+#ifdef OBJ_ELF
+ bfd_reloc_code_real_type reloc;
+#endif
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! isspace (*s); s++)
+ ;
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* Look up the opcode in the hash table. */
+ opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, str);
+ if (opcode == (const struct powerpc_opcode *) NULL)
+ {
+ const struct powerpc_macro *macro;
+
+ macro = (const struct powerpc_macro *) hash_find (ppc_macro_hash, str);
+ if (macro == (const struct powerpc_macro *) NULL)
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ else
+ ppc_macro (s, macro);
+
+ return;
+ }
+
+ insn = opcode->opcode;
+
+ str = s;
+ while (isspace (*str))
+ ++str;
+
+ /* PowerPC operands are just expressions. The only real issue is
+ that a few operand types are optional. All cases which might use
+ an optional operand separate the operands only with commas (in
+ some cases parentheses are used, as in ``lwz 1,0(1)'' but such
+ cases never have optional operands). There is never more than
+ one optional operand for an instruction. So, before we start
+ seriously parsing the operands, we check to see if we have an
+ optional operand, and, if we do, we count the number of commas to
+ see whether the operand should be omitted. */
+ skip_optional = 0;
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
+ {
+ const struct powerpc_operand *operand;
+
+ operand = &powerpc_operands[*opindex_ptr];
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
+ {
+ unsigned int opcount;
+
+ /* There is an optional operand. Count the number of
+ commas in the input line. */
+ if (*str == '\0')
+ opcount = 0;
+ else
+ {
+ opcount = 1;
+ s = str;
+ while ((s = strchr (s, ',')) != (char *) NULL)
+ {
+ ++opcount;
+ ++s;
+ }
+ }
+
+ /* If there are fewer operands in the line then are called
+ for by the instruction, we want to skip the optional
+ operand. */
+ if (opcount < strlen (opcode->operands))
+ skip_optional = 1;
+
+ break;
+ }
+ }
+
+ /* Gather the operands. */
+ need_paren = 0;
+ next_opindex = 0;
+ fc = 0;
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
+ {
+ const struct powerpc_operand *operand;
+ const char *errmsg;
+ char *hold;
+ expressionS ex;
+ char endc;
+
+ if (next_opindex == 0)
+ operand = &powerpc_operands[*opindex_ptr];
+ else
+ {
+ operand = &powerpc_operands[next_opindex];
+ next_opindex = 0;
+ }
+
+ errmsg = NULL;
+
+ /* If this is a fake operand, then we do not expect anything
+ from the input. */
+ if ((operand->flags & PPC_OPERAND_FAKE) != 0)
+ {
+ insn = (*operand->insert) (insn, 0L, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_bad (errmsg);
+ continue;
+ }
+
+ /* If this is an optional operand, and we are skipping it, just
+ insert a zero. */
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+ && skip_optional)
+ {
+ if (operand->insert)
+ {
+ insn = (*operand->insert) (insn, 0L, &errmsg);
+ if (errmsg != (const char *) NULL)
+ as_bad (errmsg);
+ }
+ if ((operand->flags & PPC_OPERAND_NEXT) != 0)
+ next_opindex = *opindex_ptr + 1;
+ continue;
+ }
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+#ifdef TE_PE
+ if (*input_line_pointer == '[')
+ {
+ /* We are expecting something like the second argument here:
+
+ lwz r4,[toc].GS.0.static_int(rtoc)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ The argument following the `]' must be a symbol name, and the
+ register must be the toc register: 'rtoc' or '2'
+
+ The effect is to 0 as the displacement field
+ in the instruction, and issue an IMAGE_REL_PPC_TOCREL16 (or
+ the appropriate variation) reloc against it based on the symbol.
+ The linker will build the toc, and insert the resolved toc offset.
+
+ Note:
+ o The size of the toc entry is currently assumed to be
+ 32 bits. This should not be assumed to be a hard coded
+ number.
+ o In an effort to cope with a change from 32 to 64 bits,
+ there are also toc entries that are specified to be
+ either 32 or 64 bits:
+ lwz r4,[toc32].GS.0.static_int(rtoc)
+ lwz r4,[toc64].GS.0.static_int(rtoc)
+ These demand toc entries of the specified size, and the
+ instruction probably requires it.
+ */
+
+ int valid_toc;
+ enum toc_size_qualifier toc_kind;
+ bfd_reloc_code_real_type toc_reloc;
+
+ /* go parse off the [tocXX] part */
+ valid_toc = parse_toc_entry(&toc_kind);
+
+ if (!valid_toc)
+ {
+ /* Note: message has already been issued. */
+ /* FIXME: what sort of recovery should we do? */
+ /* demand_rest_of_line(); return; ? */
+ }
+
+ /* Now get the symbol following the ']' */
+ expression(&ex);
+
+ switch (toc_kind)
+ {
+ case default_toc:
+ /* In this case, we may not have seen the symbol yet, since */
+ /* it is allowed to appear on a .extern or .globl or just be */
+ /* a label in the .data section. */
+ toc_reloc = BFD_RELOC_PPC_TOC16;
+ break;
+ case data_in_toc:
+ /* 1. The symbol must be defined and either in the toc */
+ /* section, or a global. */
+ /* 2. The reloc generated must have the TOCDEFN flag set in */
+ /* upper bit mess of the reloc type. */
+ /* FIXME: It's a little confusing what the tocv qualifier can */
+ /* be used for. At the very least, I've seen three */
+ /* uses, only one of which I'm sure I can explain. */
+ if (ex.X_op == O_symbol)
+ {
+ assert (ex.X_add_symbol != NULL);
+ if (ex.X_add_symbol->bsym->section != tocdata_section)
+ {
+ as_bad(_("[tocv] symbol is not a toc symbol"));
+ }
+ }
+
+ toc_reloc = BFD_RELOC_PPC_TOC16;
+ break;
+ case must_be_32:
+ /* FIXME: these next two specifically specify 32/64 bit toc */
+ /* entries. We don't support them today. Is this the */
+ /* right way to say that? */
+ toc_reloc = BFD_RELOC_UNUSED;
+ as_bad (_("Unimplemented toc32 expression modifier"));
+ break;
+ case must_be_64:
+ /* FIXME: see above */
+ toc_reloc = BFD_RELOC_UNUSED;
+ as_bad (_("Unimplemented toc64 expression modifier"));
+ break;
+ default:
+ fprintf(stderr,
+ _("Unexpected return value [%d] from parse_toc_entry!\n"),
+ toc_kind);
+ abort();
+ break;
+ }
+
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[fc].reloc = toc_reloc;
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ ++fc;
+
+ /* Ok. We've set up the fixup for the instruction. Now make it
+ look like the constant 0 was found here */
+ ex.X_unsigned = 1;
+ ex.X_op = O_constant;
+ ex.X_add_number = 0;
+ ex.X_add_symbol = NULL;
+ ex.X_op_symbol = NULL;
+ }
+
+ else
+#endif /* TE_PE */
+ {
+ if (! register_name (&ex))
+ {
+ if ((operand->flags & PPC_OPERAND_CR) != 0)
+ cr_operand = true;
+ expression (&ex);
+ cr_operand = false;
+ }
+ }
+
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ if (ex.X_op == O_illegal)
+ as_bad (_("illegal operand"));
+ else if (ex.X_op == O_absent)
+ as_bad (_("missing operand"));
+ else if (ex.X_op == O_register)
+ {
+ insn = ppc_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0);
+ }
+ else if (ex.X_op == O_constant)
+ {
+#ifdef OBJ_ELF
+ /* Allow @HA, @L, @H on constants. */
+ char *orig_str = str;
+
+ if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+ switch (reloc)
+ {
+ default:
+ str = orig_str;
+ break;
+
+ case BFD_RELOC_LO16:
+ /* X_unsigned is the default, so if the user has done
+ something which cleared it, we always produce a
+ signed value. */
+ if (ex.X_unsigned
+ && (operand->flags & PPC_OPERAND_SIGNED) == 0)
+ ex.X_add_number &= 0xffff;
+ else
+ ex.X_add_number = (((ex.X_add_number & 0xffff)
+ ^ 0x8000)
+ - 0x8000);
+ break;
+
+ case BFD_RELOC_HI16:
+ ex.X_add_number = (ex.X_add_number >> 16) & 0xffff;
+ break;
+
+ case BFD_RELOC_HI16_S:
+ ex.X_add_number = (((ex.X_add_number >> 16) & 0xffff)
+ + ((ex.X_add_number >> 15) & 1));
+ break;
+ }
+#endif
+ insn = ppc_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0);
+ }
+#ifdef OBJ_ELF
+ else if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+ {
+ /* For the absoulte forms of branchs, convert the PC relative form back into
+ the absolute. */
+ if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+ {
+ switch (reloc)
+ {
+ case BFD_RELOC_PPC_B26:
+ reloc = BFD_RELOC_PPC_BA26;
+ break;
+ case BFD_RELOC_PPC_B16:
+ reloc = BFD_RELOC_PPC_BA16;
+ break;
+ case BFD_RELOC_PPC_B16_BRTAKEN:
+ reloc = BFD_RELOC_PPC_BA16_BRTAKEN;
+ break;
+ case BFD_RELOC_PPC_B16_BRNTAKEN:
+ reloc = BFD_RELOC_PPC_BA16_BRNTAKEN;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = 0;
+ fixups[fc].reloc = reloc;
+ ++fc;
+ }
+#endif /* OBJ_ELF */
+
+ else
+ {
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ }
+
+ if (need_paren)
+ {
+ endc = ')';
+ need_paren = 0;
+ }
+ else if ((operand->flags & PPC_OPERAND_PARENS) != 0)
+ {
+ endc = '(';
+ need_paren = 1;
+ }
+ else
+ endc = ',';
+
+ /* The call to expression should have advanced str past any
+ whitespace. */
+ if (*str != endc
+ && (endc != ',' || *str != '\0'))
+ {
+ as_bad (_("syntax error; found `%c' but expected `%c'"), *str, endc);
+ break;
+ }
+
+ if (*str != '\0')
+ ++str;
+ }
+
+ while (isspace (*str))
+ ++str;
+
+ if (*str != '\0')
+ as_bad (_("junk at end of line: `%s'"), str);
+
+ /* Write out the instruction. */
+ f = frag_more (4);
+ md_number_to_chars (f, insn, 4);
+
+ /* Create any fixups. At this point we do not use a
+ bfd_reloc_code_real_type, but instead just use the
+ BFD_RELOC_UNUSED plus the operand index. This lets us easily
+ handle fixups for any operand type, although that is admittedly
+ not a very exciting feature. We pick a BFD reloc type in
+ md_apply_fix. */
+ for (i = 0; i < fc; i++)
+ {
+ const struct powerpc_operand *operand;
+
+ operand = &powerpc_operands[fixups[i].opindex];
+ if (fixups[i].reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
+ int size;
+ int offset;
+ fixS *fixP;
+
+ if (!reloc_howto)
+ abort ();
+
+ size = bfd_get_reloc_size (reloc_howto);
+ offset = target_big_endian ? (4 - size) : 0;
+
+ if (size < 1 || size > 4)
+ abort();
+
+ fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size,
+ &fixups[i].exp, reloc_howto->pc_relative,
+ fixups[i].reloc);
+
+ /* Turn off complaints that the addend is too large for things like
+ foo+100000@ha. */
+ switch (fixups[i].reloc)
+ {
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_PPC_TOC16:
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_S:
+ fixP->fx_no_overflow = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
+ &fixups[i].exp,
+ (operand->flags & PPC_OPERAND_RELATIVE) != 0,
+ ((bfd_reloc_code_real_type)
+ (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
+ }
+}
+
+/* Handle a macro. Gather all the operands, transform them as
+ described by the macro, and call md_assemble recursively. All the
+ operands are separated by commas; we don't accept parentheses
+ around operands here. */
+
+static void
+ppc_macro (str, macro)
+ char *str;
+ const struct powerpc_macro *macro;
+{
+ char *operands[10];
+ unsigned int count;
+ char *s;
+ unsigned int len;
+ const char *format;
+ int arg;
+ char *send;
+ char *complete;
+
+ /* Gather the users operands into the operands array. */
+ count = 0;
+ s = str;
+ while (1)
+ {
+ if (count >= sizeof operands / sizeof operands[0])
+ break;
+ operands[count++] = s;
+ s = strchr (s, ',');
+ if (s == (char *) NULL)
+ break;
+ *s++ = '\0';
+ }
+
+ if (count != macro->operands)
+ {
+ as_bad (_("wrong number of operands"));
+ return;
+ }
+
+ /* Work out how large the string must be (the size is unbounded
+ because it includes user input). */
+ len = 0;
+ format = macro->format;
+ while (*format != '\0')
+ {
+ if (*format != '%')
+ {
+ ++len;
+ ++format;
+ }
+ else
+ {
+ arg = strtol (format + 1, &send, 10);
+ know (send != format && arg >= 0 && arg < count);
+ len += strlen (operands[arg]);
+ format = send;
+ }
+ }
+
+ /* Put the string together. */
+ complete = s = (char *) alloca (len + 1);
+ format = macro->format;
+ while (*format != '\0')
+ {
+ if (*format != '%')
+ *s++ = *format++;
+ else
+ {
+ arg = strtol (format + 1, &send, 10);
+ strcpy (s, operands[arg]);
+ s += strlen (s);
+ format = send;
+ }
+ }
+ *s = '\0';
+
+ /* Assemble the constructed instruction. */
+ md_assemble (complete);
+}
+
+#ifdef OBJ_ELF
+/* For ELF, add support for SHF_EXCLUDE and SHT_ORDERED */
+
+int
+ppc_section_letter (letter, ptr_msg)
+ int letter;
+ char **ptr_msg;
+{
+ if (letter == 'e')
+ return SHF_EXCLUDE;
+
+ *ptr_msg = _("Bad .section directive: want a,w,x,e in string");
+ return 0;
+}
+
+int
+ppc_section_word (ptr_str)
+ char **ptr_str;
+{
+ if (strncmp (*ptr_str, "exclude", sizeof ("exclude")-1) == 0)
+ {
+ *ptr_str += sizeof ("exclude")-1;
+ return SHF_EXCLUDE;
+ }
+
+ return 0;
+}
+
+int
+ppc_section_type (ptr_str)
+ char **ptr_str;
+{
+ if (strncmp (*ptr_str, "ordered", sizeof ("ordered")-1) == 0)
+ {
+ *ptr_str += sizeof ("ordered")-1;
+ return SHT_ORDERED;
+ }
+
+ return 0;
+}
+
+int
+ppc_section_flags (flags, attr, type)
+ int flags;
+ int attr;
+ int type;
+{
+ if (type == SHT_ORDERED)
+ flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;
+
+ if (attr & SHF_EXCLUDE)
+ flags |= SEC_EXCLUDE;
+
+ return flags;
+}
+#endif /* OBJ_ELF */
+
+
+/* Pseudo-op handling. */
+
+/* The .byte pseudo-op. This is similar to the normal .byte
+ pseudo-op, but it can also take a single ASCII string. */
+
+static void
+ppc_byte (ignore)
+ int ignore;
+{
+ if (*input_line_pointer != '\"')
+ {
+ cons (1);
+ return;
+ }
+
+ /* Gather characters. A real double quote is doubled. Unusual
+ characters are not permitted. */
+ ++input_line_pointer;
+ while (1)
+ {
+ char c;
+
+ c = *input_line_pointer++;
+
+ if (c == '\"')
+ {
+ if (*input_line_pointer != '\"')
+ break;
+ ++input_line_pointer;
+ }
+
+ FRAG_APPEND_1_CHAR (c);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+#ifdef OBJ_XCOFF
+
+/* XCOFF specific pseudo-op handling. */
+
+/* This is set if we are creating a .stabx symbol, since we don't want
+ to handle symbol suffixes for such symbols. */
+static boolean ppc_stab_symbol;
+
+/* The .comm and .lcomm pseudo-ops for XCOFF. XCOFF puts common
+ symbols in the .bss segment as though they were local common
+ symbols, and uses a different smclas. */
+
+static void
+ppc_comm (lcomm)
+ int lcomm;
+{
+ asection *current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+ char *name;
+ char endc;
+ char *end_name;
+ offsetT size;
+ offsetT align;
+ symbolS *lcomm_sym = NULL;
+ symbolS *sym;
+ char *pfrag;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+ end_name = input_line_pointer;
+ *end_name = endc;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing size"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ size = get_absolute_expression ();
+ if (size < 0)
+ {
+ as_bad (_("negative size"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (! lcomm)
+ {
+ /* The third argument to .comm is the alignment. */
+ if (*input_line_pointer != ',')
+ align = 3;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 3;
+ }
+ }
+ }
+ else
+ {
+ char *lcomm_name;
+ char lcomm_endc;
+
+ if (size <= 1)
+ align = 0;
+ else if (size <= 2)
+ align = 1;
+ else if (size <= 4)
+ align = 2;
+ else
+ align = 3;
+
+ /* The third argument to .lcomm appears to be the real local
+ common symbol to create. References to the symbol named in
+ the first argument are turned into references to the third
+ argument. */
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing real symbol name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ lcomm_name = input_line_pointer;
+ lcomm_endc = get_symbol_end ();
+
+ lcomm_sym = symbol_find_or_make (lcomm_name);
+
+ *input_line_pointer = lcomm_endc;
+ }
+
+ *end_name = '\0';
+ sym = symbol_find_or_make (name);
+ *end_name = endc;
+
+ if (S_IS_DEFINED (sym)
+ || S_GET_VALUE (sym) != 0)
+ {
+ as_bad (_("attempt to redefine symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ record_alignment (bss_section, align);
+
+ if (! lcomm
+ || ! S_IS_DEFINED (lcomm_sym))
+ {
+ symbolS *def_sym;
+ offsetT def_size;
+
+ if (! lcomm)
+ {
+ def_sym = sym;
+ def_size = size;
+ S_SET_EXTERNAL (sym);
+ }
+ else
+ {
+ lcomm_sym->sy_tc.output = 1;
+ def_sym = lcomm_sym;
+ def_size = 0;
+ }
+
+ subseg_set (bss_section, 1);
+ frag_align (align, 0, 0);
+
+ def_sym->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, def_sym,
+ def_size, (char *) NULL);
+ *pfrag = 0;
+ S_SET_SEGMENT (def_sym, bss_section);
+ def_sym->sy_tc.align = align;
+ }
+ else if (lcomm)
+ {
+ /* Align the size of lcomm_sym. */
+ lcomm_sym->sy_frag->fr_offset =
+ ((lcomm_sym->sy_frag->fr_offset + (1 << align) - 1)
+ &~ ((1 << align) - 1));
+ if (align > lcomm_sym->sy_tc.align)
+ lcomm_sym->sy_tc.align = align;
+ }
+
+ if (lcomm)
+ {
+ /* Make sym an offset from lcomm_sym. */
+ S_SET_SEGMENT (sym, bss_section);
+ sym->sy_frag = lcomm_sym->sy_frag;
+ S_SET_VALUE (sym, lcomm_sym->sy_frag->fr_offset);
+ lcomm_sym->sy_frag->fr_offset += size;
+ }
+
+ subseg_set (current_seg, current_subseg);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .csect pseudo-op. This switches us into a different
+ subsegment. The first argument is a symbol whose value is the
+ start of the .csect. In COFF, csect symbols get special aux
+ entries defined by the x_csect field of union internal_auxent. The
+ optional second argument is the alignment (the default is 2). */
+
+static void
+ppc_csect (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (S_GET_NAME (sym)[0] == '\0')
+ {
+ /* An unnamed csect is assumed to be [PR]. */
+ sym->sy_tc.class = XMC_PR;
+ }
+
+ ppc_change_csect (sym);
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ sym->sy_tc.align = get_absolute_expression ();
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Change to a different csect. */
+
+static void
+ppc_change_csect (sym)
+ symbolS *sym;
+{
+ if (S_IS_DEFINED (sym))
+ subseg_set (S_GET_SEGMENT (sym), sym->sy_tc.subseg);
+ else
+ {
+ symbolS **list_ptr;
+ int after_toc;
+ int hold_chunksize;
+ symbolS *list;
+
+ /* This is a new csect. We need to look at the symbol class to
+ figure out whether it should go in the text section or the
+ data section. */
+ after_toc = 0;
+ switch (sym->sy_tc.class)
+ {
+ case XMC_PR:
+ case XMC_RO:
+ case XMC_DB:
+ case XMC_GL:
+ case XMC_XO:
+ case XMC_SV:
+ case XMC_TI:
+ case XMC_TB:
+ S_SET_SEGMENT (sym, text_section);
+ sym->sy_tc.subseg = ppc_text_subsegment;
+ ++ppc_text_subsegment;
+ list_ptr = &ppc_text_csects;
+ break;
+ case XMC_RW:
+ case XMC_TC0:
+ case XMC_TC:
+ case XMC_DS:
+ case XMC_UA:
+ case XMC_BS:
+ case XMC_UC:
+ if (ppc_toc_csect != NULL
+ && ppc_toc_csect->sy_tc.subseg + 1 == ppc_data_subsegment)
+ after_toc = 1;
+ S_SET_SEGMENT (sym, data_section);
+ sym->sy_tc.subseg = ppc_data_subsegment;
+ ++ppc_data_subsegment;
+ list_ptr = &ppc_data_csects;
+ break;
+ default:
+ abort ();
+ }
+
+ /* We set the obstack chunk size to a small value before
+ changing subsegments, so that we don't use a lot of memory
+ space for what may be a small section. */
+ hold_chunksize = chunksize;
+ chunksize = 64;
+
+ subseg_new (segment_name (S_GET_SEGMENT (sym)), sym->sy_tc.subseg);
+
+ chunksize = hold_chunksize;
+
+ if (after_toc)
+ ppc_after_toc_frag = frag_now;
+
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, (valueT) frag_now_fix ());
+
+ sym->sy_tc.align = 2;
+ sym->sy_tc.output = 1;
+ sym->sy_tc.within = sym;
+
+ for (list = *list_ptr;
+ list->sy_tc.next != (symbolS *) NULL;
+ list = list->sy_tc.next)
+ ;
+ list->sy_tc.next = sym;
+
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, list->sy_tc.within, &symbol_rootP, &symbol_lastP);
+ }
+
+ ppc_current_csect = sym;
+}
+
+/* This function handles the .text and .data pseudo-ops. These
+ pseudo-ops aren't really used by XCOFF; we implement them for the
+ convenience of people who aren't used to XCOFF. */
+
+static void
+ppc_section (type)
+ int type;
+{
+ const char *name;
+ symbolS *sym;
+
+ if (type == 't')
+ name = ".text[PR]";
+ else if (type == 'd')
+ name = ".data[RW]";
+ else
+ abort ();
+
+ sym = symbol_find_or_make (name);
+
+ ppc_change_csect (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* This function handles the .section pseudo-op. This is mostly to
+ give an error, since XCOFF only supports .text, .data and .bss, but
+ we do permit the user to name the text or data section. */
+
+static void
+ppc_named_section (ignore)
+ int ignore;
+{
+ char *user_name;
+ const char *real_name;
+ char c;
+ symbolS *sym;
+
+ user_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ if (strcmp (user_name, ".text") == 0)
+ real_name = ".text[PR]";
+ else if (strcmp (user_name, ".data") == 0)
+ real_name = ".data[RW]";
+ else
+ {
+ as_bad (_("The XCOFF file format does not support arbitrary sections"));
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ *input_line_pointer = c;
+
+ sym = symbol_find_or_make (real_name);
+
+ ppc_change_csect (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .extern pseudo-op. We create an undefined symbol. */
+
+static void
+ppc_extern (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ (void) symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .lglobl pseudo-op. Keep the symbol in the symbol table. */
+
+static void
+ppc_lglobl (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+ symbolS *sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ sym->sy_tc.output = 1;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .rename pseudo-op. The RS/6000 assembler can rename symbols,
+ although I don't know why it bothers. */
+
+static void
+ppc_rename (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+ symbolS *sym;
+ int len;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing rename string"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ sym->sy_tc.real_name = demand_copy_C_string (&len);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .stabx pseudo-op. This is similar to a normal .stabs
+ pseudo-op, but slightly different. A sample is
+ .stabx "main:F-1",.main,142,0
+ The first argument is the symbol name to create. The second is the
+ value, and the third is the storage class. The fourth seems to be
+ always zero, and I am assuming it is the type. */
+
+static void
+ppc_stabx (ignore)
+ int ignore;
+{
+ char *name;
+ int len;
+ symbolS *sym;
+ expressionS exp;
+
+ name = demand_copy_C_string (&len);
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing value"));
+ return;
+ }
+ ++input_line_pointer;
+
+ ppc_stab_symbol = true;
+ sym = symbol_make (name);
+ ppc_stab_symbol = false;
+
+ sym->sy_tc.real_name = name;
+
+ (void) expression (&exp);
+
+ switch (exp.X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_big:
+ as_bad (_("illegal .stabx expression; zero assumed"));
+ exp.X_add_number = 0;
+ /* Fall through. */
+ case O_constant:
+ S_SET_VALUE (sym, (valueT) exp.X_add_number);
+ sym->sy_frag = &zero_address_frag;
+ break;
+
+ case O_symbol:
+ if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section)
+ sym->sy_value = exp;
+ else
+ {
+ S_SET_VALUE (sym,
+ exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
+ sym->sy_frag = exp.X_add_symbol->sy_frag;
+ }
+ break;
+
+ default:
+ /* The value is some complex expression. This will probably
+ fail at some later point, but this is probably the right
+ thing to do here. */
+ sym->sy_value = exp;
+ break;
+ }
+
+ S_SET_SEGMENT (sym, ppc_coff_debug_section);
+ sym->bsym->flags |= BSF_DEBUGGING;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing class"));
+ return;
+ }
+ ++input_line_pointer;
+
+ S_SET_STORAGE_CLASS (sym, get_absolute_expression ());
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing type"));
+ return;
+ }
+ ++input_line_pointer;
+
+ S_SET_DATA_TYPE (sym, get_absolute_expression ());
+
+ sym->sy_tc.output = 1;
+
+ if (S_GET_STORAGE_CLASS (sym) == C_STSYM)
+ sym->sy_tc.within = ppc_current_block;
+
+ if (exp.X_op != O_symbol
+ || ! S_IS_EXTERNAL (exp.X_add_symbol)
+ || S_GET_SEGMENT (exp.X_add_symbol) != bss_section)
+ ppc_frob_label (sym);
+ else
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, exp.X_add_symbol, &symbol_rootP, &symbol_lastP);
+ if (ppc_current_csect->sy_tc.within == exp.X_add_symbol)
+ ppc_current_csect->sy_tc.within = sym;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .function pseudo-op. This takes several arguments. The first
+ argument seems to be the external name of the symbol. The second
+ argment seems to be the label for the start of the function. gcc
+ uses the same name for both. I have no idea what the third and
+ fourth arguments are meant to be. The optional fifth argument is
+ an expression for the size of the function. In COFF this symbol
+ gets an aux entry like that used for a csect. */
+
+static void
+ppc_function (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+ char *s;
+ symbolS *ext_sym;
+ symbolS *lab_sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ /* Ignore any [PR] suffix. */
+ name = ppc_canonicalize_symbol_name (name);
+ s = strchr (name, '[');
+ if (s != (char *) NULL
+ && strcmp (s + 1, "PR]") == 0)
+ *s = '\0';
+
+ ext_sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing symbol name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ ++input_line_pointer;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ lab_sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (ext_sym != lab_sym)
+ {
+ ext_sym->sy_value.X_op = O_symbol;
+ ext_sym->sy_value.X_add_symbol = lab_sym;
+ ext_sym->sy_value.X_op_symbol = NULL;
+ ext_sym->sy_value.X_add_number = 0;
+ }
+
+ if (ext_sym->sy_tc.class == -1)
+ ext_sym->sy_tc.class = XMC_PR;
+ ext_sym->sy_tc.output = 1;
+
+ if (*input_line_pointer == ',')
+ {
+ expressionS ignore;
+
+ /* Ignore the third argument. */
+ ++input_line_pointer;
+ expression (&ignore);
+ if (*input_line_pointer == ',')
+ {
+ /* Ignore the fourth argument. */
+ ++input_line_pointer;
+ expression (&ignore);
+ if (*input_line_pointer == ',')
+ {
+ /* The fifth argument is the function size. */
+ ++input_line_pointer;
+ ext_sym->sy_tc.size = symbol_new ("L0\001",
+ absolute_section,
+ (valueT) 0,
+ &zero_address_frag);
+ pseudo_set (ext_sym->sy_tc.size);
+ }
+ }
+ }
+
+ S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
+ SF_SET_FUNCTION (ext_sym);
+ SF_SET_PROCESS (ext_sym);
+ coff_add_linesym (ext_sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bf pseudo-op. This is just like a COFF C_FCN symbol named
+ ".bf". */
+
+static void
+ppc_bf (ignore)
+ int ignore;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".bf");
+ S_SET_SEGMENT (sym, text_section);
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_FCN);
+
+ coff_line_base = get_absolute_expression ();
+
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, coff_line_base);
+
+ sym->sy_tc.output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .ef pseudo-op. This is just like a COFF C_FCN symbol named
+ ".ef", except that the line number is absolute, not relative to the
+ most recent ".bf" symbol. */
+
+static void
+ppc_ef (ignore)
+ int ignore;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".ef");
+ S_SET_SEGMENT (sym, text_section);
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_FCN);
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, get_absolute_expression ());
+ sym->sy_tc.output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bi and .ei pseudo-ops. These take a string argument and
+ generates a C_BINCL or C_EINCL symbol, which goes at the start of
+ the symbol list. */
+
+static void
+ppc_biei (ei)
+ int ei;
+{
+ static symbolS *last_biei;
+
+ char *name;
+ int len;
+ symbolS *sym;
+ symbolS *look;
+
+ name = demand_copy_C_string (&len);
+
+ /* The value of these symbols is actually file offset. Here we set
+ the value to the index into the line number entries. In
+ ppc_frob_symbols we set the fix_line field, which will cause BFD
+ to do the right thing. */
+
+ sym = symbol_make (name);
+ /* obj-coff.c currently only handles line numbers correctly in the
+ .text section. */
+ S_SET_SEGMENT (sym, text_section);
+ S_SET_VALUE (sym, coff_n_line_nos);
+ sym->bsym->flags |= BSF_DEBUGGING;
+
+ S_SET_STORAGE_CLASS (sym, ei ? C_EINCL : C_BINCL);
+ sym->sy_tc.output = 1;
+
+ for (look = last_biei ? last_biei : symbol_rootP;
+ (look != (symbolS *) NULL
+ && (S_GET_STORAGE_CLASS (look) == C_FILE
+ || S_GET_STORAGE_CLASS (look) == C_BINCL
+ || S_GET_STORAGE_CLASS (look) == C_EINCL));
+ look = symbol_next (look))
+ ;
+ if (look != (symbolS *) NULL)
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_insert (sym, look, &symbol_rootP, &symbol_lastP);
+ last_biei = sym;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bs pseudo-op. This generates a C_BSTAT symbol named ".bs".
+ There is one argument, which is a csect symbol. The value of the
+ .bs symbol is the index of this csect symbol. */
+
+static void
+ppc_bs (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+ symbolS *csect;
+ symbolS *sym;
+
+ if (ppc_current_block != NULL)
+ as_bad (_("nested .bs blocks"));
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ csect = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ sym = symbol_make (".bs");
+ S_SET_SEGMENT (sym, now_seg);
+ S_SET_STORAGE_CLASS (sym, C_BSTAT);
+ sym->bsym->flags |= BSF_DEBUGGING;
+ sym->sy_tc.output = 1;
+
+ sym->sy_tc.within = csect;
+
+ ppc_frob_label (sym);
+
+ ppc_current_block = sym;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .es pseudo-op. Generate a C_ESTART symbol named .es. */
+
+static void
+ppc_es (ignore)
+ int ignore;
+{
+ symbolS *sym;
+
+ if (ppc_current_block == NULL)
+ as_bad (_(".es without preceding .bs"));
+
+ sym = symbol_make (".es");
+ S_SET_SEGMENT (sym, now_seg);
+ S_SET_STORAGE_CLASS (sym, C_ESTAT);
+ sym->bsym->flags |= BSF_DEBUGGING;
+ sym->sy_tc.output = 1;
+
+ ppc_frob_label (sym);
+
+ ppc_current_block = NULL;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bb pseudo-op. Generate a C_BLOCK symbol named .bb, with a
+ line number. */
+
+static void
+ppc_bb (ignore)
+ int ignore;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".bb");
+ S_SET_SEGMENT (sym, text_section);
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_BLOCK);
+
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, get_absolute_expression ());
+
+ sym->sy_tc.output = 1;
+
+ SF_SET_PROCESS (sym);
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .eb pseudo-op. Generate a C_BLOCK symbol named .eb, with a
+ line number. */
+
+static void
+ppc_eb (ignore)
+ int ignore;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".eb");
+ S_SET_SEGMENT (sym, text_section);
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, frag_now_fix ());
+ S_SET_STORAGE_CLASS (sym, C_BLOCK);
+ S_SET_NUMBER_AUXILIARY (sym, 1);
+ SA_SET_SYM_LNNO (sym, get_absolute_expression ());
+ sym->sy_tc.output = 1;
+
+ SF_SET_PROCESS (sym);
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .bc pseudo-op. This just creates a C_BCOMM symbol with a
+ specified name. */
+
+static void
+ppc_bc (ignore)
+ int ignore;
+{
+ char *name;
+ int len;
+ symbolS *sym;
+
+ name = demand_copy_C_string (&len);
+ sym = symbol_make (name);
+ S_SET_SEGMENT (sym, ppc_coff_debug_section);
+ sym->bsym->flags |= BSF_DEBUGGING;
+ S_SET_STORAGE_CLASS (sym, C_BCOMM);
+ S_SET_VALUE (sym, 0);
+ sym->sy_tc.output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .ec pseudo-op. This just creates a C_ECOMM symbol. */
+
+static void
+ppc_ec (ignore)
+ int ignore;
+{
+ symbolS *sym;
+
+ sym = symbol_make (".ec");
+ S_SET_SEGMENT (sym, ppc_coff_debug_section);
+ sym->bsym->flags |= BSF_DEBUGGING;
+ S_SET_STORAGE_CLASS (sym, C_ECOMM);
+ S_SET_VALUE (sym, 0);
+ sym->sy_tc.output = 1;
+
+ ppc_frob_label (sym);
+
+ demand_empty_rest_of_line ();
+}
+
+/* The .toc pseudo-op. Switch to the .toc subsegment. */
+
+static void
+ppc_toc (ignore)
+ int ignore;
+{
+ if (ppc_toc_csect != (symbolS *) NULL)
+ subseg_set (data_section, ppc_toc_csect->sy_tc.subseg);
+ else
+ {
+ subsegT subseg;
+ symbolS *sym;
+ symbolS *list;
+
+ subseg = ppc_data_subsegment;
+ ++ppc_data_subsegment;
+
+ subseg_new (segment_name (data_section), subseg);
+ ppc_toc_frag = frag_now;
+
+ sym = symbol_find_or_make ("TOC[TC0]");
+ sym->sy_frag = frag_now;
+ S_SET_SEGMENT (sym, data_section);
+ S_SET_VALUE (sym, (valueT) frag_now_fix ());
+ sym->sy_tc.subseg = subseg;
+ sym->sy_tc.output = 1;
+ sym->sy_tc.within = sym;
+
+ ppc_toc_csect = sym;
+
+ for (list = ppc_data_csects;
+ list->sy_tc.next != (symbolS *) NULL;
+ list = list->sy_tc.next)
+ ;
+ list->sy_tc.next = sym;
+
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, list->sy_tc.within, &symbol_rootP, &symbol_lastP);
+ }
+
+ ppc_current_csect = ppc_toc_csect;
+
+ demand_empty_rest_of_line ();
+}
+
+/* The AIX assembler automatically aligns the operands of a .long or
+ .short pseudo-op, and we want to be compatible. */
+
+static void
+ppc_xcoff_cons (log_size)
+ int log_size;
+{
+ frag_align (log_size, 0, 0);
+ record_alignment (now_seg, log_size);
+ cons (1 << log_size);
+}
+
+static void
+ppc_vbyte (dummy)
+ int dummy;
+{
+ expressionS exp;
+ int byte_count;
+
+ (void) expression (&exp);
+
+ if (exp.X_op != O_constant)
+ {
+ as_bad (_("non-constant byte count"));
+ return;
+ }
+
+ byte_count = exp.X_add_number;
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing value"));
+ return;
+ }
+
+ ++input_line_pointer;
+ cons (byte_count);
+}
+
+#endif /* OBJ_XCOFF */
+
+/* The .tc pseudo-op. This is used when generating either XCOFF or
+ ELF. This takes two or more arguments.
+
+ When generating XCOFF output, the first argument is the name to
+ give to this location in the toc; this will be a symbol with class
+ TC. The rest of the arguments are 4 byte values to actually put at
+ this location in the TOC; often there is just one more argument, a
+ relocateable symbol reference.
+
+ When not generating XCOFF output, the arguments are the same, but
+ the first argument is simply ignored. */
+
+static void
+ppc_tc (ignore)
+ int ignore;
+{
+#ifdef OBJ_XCOFF
+
+ /* Define the TOC symbol name. */
+ {
+ char *name;
+ char endc;
+ symbolS *sym;
+
+ if (ppc_toc_csect == (symbolS *) NULL
+ || ppc_toc_csect != ppc_current_csect)
+ {
+ as_bad (_(".tc not in .toc section"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ if (S_IS_DEFINED (sym))
+ {
+ symbolS *label;
+
+ label = ppc_current_csect->sy_tc.within;
+ if (label->sy_tc.class != XMC_TC0)
+ {
+ as_bad (_(".tc with no label"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ S_SET_SEGMENT (label, S_GET_SEGMENT (sym));
+ label->sy_frag = sym->sy_frag;
+ S_SET_VALUE (label, S_GET_VALUE (sym));
+
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+
+ return;
+ }
+
+ S_SET_SEGMENT (sym, now_seg);
+ sym->sy_frag = frag_now;
+ S_SET_VALUE (sym, (valueT) frag_now_fix ());
+ sym->sy_tc.class = XMC_TC;
+ sym->sy_tc.output = 1;
+
+ ppc_frob_label (sym);
+ }
+
+#else /* ! defined (OBJ_XCOFF) */
+
+ /* Skip the TOC symbol name. */
+ while (is_part_of_name (*input_line_pointer)
+ || *input_line_pointer == '['
+ || *input_line_pointer == ']'
+ || *input_line_pointer == '{'
+ || *input_line_pointer == '}')
+ ++input_line_pointer;
+
+ /* Align to a four byte boundary. */
+ frag_align (2, 0, 0);
+ record_alignment (now_seg, 2);
+
+#endif /* ! defined (OBJ_XCOFF) */
+
+ if (*input_line_pointer != ',')
+ demand_empty_rest_of_line ();
+ else
+ {
+ ++input_line_pointer;
+ cons (4);
+ }
+}
+
+#ifdef TE_PE
+
+/* Pseudo-ops specific to the Windows NT PowerPC PE (coff) format */
+
+/* Set the current section. */
+static void
+ppc_set_current_section (new)
+ segT new;
+{
+ ppc_previous_section = ppc_current_section;
+ ppc_current_section = new;
+}
+
+/* pseudo-op: .previous
+ behaviour: toggles the current section with the previous section.
+ errors: None
+ warnings: "No previous section"
+*/
+static void
+ppc_previous(ignore)
+ int ignore;
+{
+ symbolS *tmp;
+
+ if (ppc_previous_section == NULL)
+ {
+ as_warn(_("No previous section to return to. Directive ignored."));
+ return;
+ }
+
+ subseg_set(ppc_previous_section, 0);
+
+ ppc_set_current_section(ppc_previous_section);
+}
+
+/* pseudo-op: .pdata
+ behaviour: predefined read only data section
+ double word aligned
+ errors: None
+ warnings: None
+ initial: .section .pdata "adr3"
+ a - don't know -- maybe a misprint
+ d - initialized data
+ r - readable
+ 3 - double word aligned (that would be 4 byte boundary)
+
+ commentary:
+ Tag index tables (also known as the function table) for exception
+ handling, debugging, etc.
+
+*/
+static void
+ppc_pdata(ignore)
+ int ignore;
+{
+ if (pdata_section == 0)
+ {
+ pdata_section = subseg_new (".pdata", 0);
+
+ bfd_set_section_flags (stdoutput, pdata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, pdata_section, 2);
+ }
+ else
+ {
+ pdata_section = subseg_new(".pdata", 0);
+ }
+ ppc_set_current_section(pdata_section);
+}
+
+/* pseudo-op: .ydata
+ behaviour: predefined read only data section
+ double word aligned
+ errors: None
+ warnings: None
+ initial: .section .ydata "drw3"
+ a - don't know -- maybe a misprint
+ d - initialized data
+ r - readable
+ 3 - double word aligned (that would be 4 byte boundary)
+ commentary:
+ Tag tables (also known as the scope table) for exception handling,
+ debugging, etc.
+*/
+static void
+ppc_ydata(ignore)
+ int ignore;
+{
+ if (ydata_section == 0)
+ {
+ ydata_section = subseg_new (".ydata", 0);
+ bfd_set_section_flags (stdoutput, ydata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, ydata_section, 3);
+ }
+ else
+ {
+ ydata_section = subseg_new (".ydata", 0);
+ }
+ ppc_set_current_section(ydata_section);
+}
+
+/* pseudo-op: .reldata
+ behaviour: predefined read write data section
+ double word aligned (4-byte)
+ FIXME: relocation is applied to it
+ FIXME: what's the difference between this and .data?
+ errors: None
+ warnings: None
+ initial: .section .reldata "drw3"
+ d - initialized data
+ r - readable
+ w - writeable
+ 3 - double word aligned (that would be 8 byte boundary)
+
+ commentary:
+ Like .data, but intended to hold data subject to relocation, such as
+ function descriptors, etc.
+*/
+static void
+ppc_reldata(ignore)
+ int ignore;
+{
+ if (reldata_section == 0)
+ {
+ reldata_section = subseg_new (".reldata", 0);
+
+ bfd_set_section_flags (stdoutput, reldata_section,
+ ( SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, reldata_section, 2);
+ }
+ else
+ {
+ reldata_section = subseg_new (".reldata", 0);
+ }
+ ppc_set_current_section(reldata_section);
+}
+
+/* pseudo-op: .rdata
+ behaviour: predefined read only data section
+ double word aligned
+ errors: None
+ warnings: None
+ initial: .section .rdata "dr3"
+ d - initialized data
+ r - readable
+ 3 - double word aligned (that would be 4 byte boundary)
+*/
+static void
+ppc_rdata(ignore)
+ int ignore;
+{
+ if (rdata_section == 0)
+ {
+ rdata_section = subseg_new (".rdata", 0);
+ bfd_set_section_flags (stdoutput, rdata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, rdata_section, 2);
+ }
+ else
+ {
+ rdata_section = subseg_new (".rdata", 0);
+ }
+ ppc_set_current_section(rdata_section);
+}
+
+/* pseudo-op: .ualong
+ behaviour: much like .int, with the exception that no alignment is
+ performed.
+ FIXME: test the alignment statement
+ errors: None
+ warnings: None
+*/
+static void
+ppc_ualong(ignore)
+ int ignore;
+{
+ /* try for long */
+ cons ( 4 );
+}
+
+/* pseudo-op: .znop <symbol name>
+ behaviour: Issue a nop instruction
+ Issue a IMAGE_REL_PPC_IFGLUE relocation against it, using
+ the supplied symbol name.
+ errors: None
+ warnings: Missing symbol name
+*/
+static void
+ppc_znop(ignore)
+ int ignore;
+{
+ unsigned long insn;
+ const struct powerpc_opcode *opcode;
+ expressionS ex;
+ char *f;
+
+ symbolS *sym;
+
+ /* Strip out the symbol name */
+ char *symbol_name;
+ char c;
+ char *name;
+ unsigned int exp;
+ flagword flags;
+ asection *sec;
+
+ symbol_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - symbol_name + 1);
+ strcpy (name, symbol_name);
+
+ sym = symbol_find_or_make (name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ /* Look up the opcode in the hash table. */
+ opcode = (const struct powerpc_opcode *) hash_find (ppc_hash, "nop");
+
+ /* stick in the nop */
+ insn = opcode->opcode;
+
+ /* Write out the instruction. */
+ f = frag_more (4);
+ md_number_to_chars (f, insn, 4);
+ fix_new (frag_now,
+ f - frag_now->fr_literal,
+ 4,
+ sym,
+ 0,
+ 0,
+ BFD_RELOC_16_GOT_PCREL);
+
+}
+
+/* pseudo-op:
+ behaviour:
+ errors:
+ warnings:
+*/
+static void
+ppc_pe_comm(lcomm)
+ int lcomm;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT temp;
+ register symbolS *symbolP;
+ offsetT align;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++; /* skip ',' */
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (! lcomm)
+ {
+ /* The third argument to .comm is the alignment. */
+ if (*input_line_pointer != ',')
+ align = 3;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ if (align <= 0)
+ {
+ as_warn (_("ignoring bad alignment"));
+ align = 3;
+ }
+ }
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) temp);
+ }
+ else
+ {
+ S_SET_VALUE (symbolP, (valueT) temp);
+ S_SET_EXTERNAL (symbolP);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * implement the .section pseudo op:
+ * .section name {, "flags"}
+ * ^ ^
+ * | +--- optional flags: 'b' for bss
+ * | 'i' for info
+ * +-- section name 'l' for lib
+ * 'n' for noload
+ * 'o' for over
+ * 'w' for data
+ * 'd' (apparently m88k for data)
+ * 'x' for text
+ * But if the argument is not a quoted string, treat it as a
+ * subsegment number.
+ *
+ * FIXME: this is a copy of the section processing from obj-coff.c, with
+ * additions/changes for the moto-pas assembler support. There are three
+ * categories:
+ *
+ * FIXME: I just noticed this. This doesn't work at all really. It it
+ * setting bits that bfd probably neither understands or uses. The
+ * correct approach (?) will have to incorporate extra fields attached
+ * to the section to hold the system specific stuff. (krk)
+ *
+ * Section Contents:
+ * 'a' - unknown - referred to in documentation, but no definition supplied
+ * 'c' - section has code
+ * 'd' - section has initialized data
+ * 'u' - section has uninitialized data
+ * 'i' - section contains directives (info)
+ * 'n' - section can be discarded
+ * 'R' - remove section at link time
+ *
+ * Section Protection:
+ * 'r' - section is readable
+ * 'w' - section is writeable
+ * 'x' - section is executable
+ * 's' - section is sharable
+ *
+ * Section Alignment:
+ * '0' - align to byte boundary
+ * '1' - align to halfword undary
+ * '2' - align to word boundary
+ * '3' - align to doubleword boundary
+ * '4' - align to quadword boundary
+ * '5' - align to 32 byte boundary
+ * '6' - align to 64 byte boundary
+ *
+ */
+
+void
+ppc_pe_section (ignore)
+ int ignore;
+{
+ /* Strip out the section name */
+ char *section_name;
+ char c;
+ char *name;
+ unsigned int exp;
+ flagword flags;
+ segT sec;
+ int align;
+
+ section_name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xmalloc (input_line_pointer - section_name + 1);
+ strcpy (name, section_name);
+
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ exp = 0;
+ flags = SEC_NO_FLAGS;
+
+ if (strcmp (name, ".idata$2") == 0)
+ {
+ align = 0;
+ }
+ else if (strcmp (name, ".idata$3") == 0)
+ {
+ align = 0;
+ }
+ else if (strcmp (name, ".idata$4") == 0)
+ {
+ align = 2;
+ }
+ else if (strcmp (name, ".idata$5") == 0)
+ {
+ align = 2;
+ }
+ else if (strcmp (name, ".idata$6") == 0)
+ {
+ align = 1;
+ }
+ else
+ align = 4; /* default alignment to 16 byte boundary */
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ exp = get_absolute_expression ();
+ else
+ {
+ ++input_line_pointer;
+ while (*input_line_pointer != '"'
+ && ! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ switch (*input_line_pointer)
+ {
+ /* Section Contents */
+ case 'a': /* unknown */
+ as_bad (_("Unsupported section attribute -- 'a'"));
+ break;
+ case 'c': /* code section */
+ flags |= SEC_CODE;
+ break;
+ case 'd': /* section has initialized data */
+ flags |= SEC_DATA;
+ break;
+ case 'u': /* section has uninitialized data */
+ /* FIXME: This is IMAGE_SCN_CNT_UNINITIALIZED_DATA
+ in winnt.h */
+ flags |= SEC_ROM;
+ break;
+ case 'i': /* section contains directives (info) */
+ /* FIXME: This is IMAGE_SCN_LNK_INFO
+ in winnt.h */
+ flags |= SEC_HAS_CONTENTS;
+ break;
+ case 'n': /* section can be discarded */
+ flags &=~ SEC_LOAD;
+ break;
+ case 'R': /* Remove section at link time */
+ flags |= SEC_NEVER_LOAD;
+ break;
+
+ /* Section Protection */
+ case 'r': /* section is readable */
+ flags |= IMAGE_SCN_MEM_READ;
+ break;
+ case 'w': /* section is writeable */
+ flags |= IMAGE_SCN_MEM_WRITE;
+ break;
+ case 'x': /* section is executable */
+ flags |= IMAGE_SCN_MEM_EXECUTE;
+ break;
+ case 's': /* section is sharable */
+ flags |= IMAGE_SCN_MEM_SHARED;
+ break;
+
+ /* Section Alignment */
+ case '0': /* align to byte boundary */
+ flags |= IMAGE_SCN_ALIGN_1BYTES;
+ align = 0;
+ break;
+ case '1': /* align to halfword boundary */
+ flags |= IMAGE_SCN_ALIGN_2BYTES;
+ align = 1;
+ break;
+ case '2': /* align to word boundary */
+ flags |= IMAGE_SCN_ALIGN_4BYTES;
+ align = 2;
+ break;
+ case '3': /* align to doubleword boundary */
+ flags |= IMAGE_SCN_ALIGN_8BYTES;
+ align = 3;
+ break;
+ case '4': /* align to quadword boundary */
+ flags |= IMAGE_SCN_ALIGN_16BYTES;
+ align = 4;
+ break;
+ case '5': /* align to 32 byte boundary */
+ flags |= IMAGE_SCN_ALIGN_32BYTES;
+ align = 5;
+ break;
+ case '6': /* align to 64 byte boundary */
+ flags |= IMAGE_SCN_ALIGN_64BYTES;
+ align = 6;
+ break;
+
+ default:
+ as_bad(_("unknown section attribute '%c'"),
+ *input_line_pointer);
+ break;
+ }
+ ++input_line_pointer;
+ }
+ if (*input_line_pointer == '"')
+ ++input_line_pointer;
+ }
+ }
+
+ sec = subseg_new (name, (subsegT) exp);
+
+ ppc_set_current_section(sec);
+
+ if (flags != SEC_NO_FLAGS)
+ {
+ if (! bfd_set_section_flags (stdoutput, sec, flags))
+ as_bad (_("error setting flags for \"%s\": %s"),
+ bfd_section_name (stdoutput, sec),
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ bfd_set_section_alignment(stdoutput, sec, align);
+
+}
+
+static void
+ppc_pe_function (ignore)
+ int ignore;
+{
+ char *name;
+ char endc;
+ symbolS *ext_sym;
+
+ name = input_line_pointer;
+ endc = get_symbol_end ();
+
+ ext_sym = symbol_find_or_make (name);
+
+ *input_line_pointer = endc;
+
+ S_SET_DATA_TYPE (ext_sym, DT_FCN << N_BTSHFT);
+ SF_SET_FUNCTION (ext_sym);
+ SF_SET_PROCESS (ext_sym);
+ coff_add_linesym (ext_sym);
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+ppc_pe_tocd (ignore)
+ int ignore;
+{
+ if (tocdata_section == 0)
+ {
+ tocdata_section = subseg_new (".tocd", 0);
+ /* FIXME: section flags won't work */
+ bfd_set_section_flags (stdoutput, tocdata_section,
+ (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_READONLY | SEC_DATA ));
+
+ bfd_set_section_alignment (stdoutput, tocdata_section, 2);
+ }
+ else
+ {
+ rdata_section = subseg_new (".tocd", 0);
+ }
+
+ ppc_set_current_section(tocdata_section);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Don't adjust TOC relocs to use the section symbol. */
+
+int
+ppc_pe_fix_adjustable (fix)
+ fixS *fix;
+{
+ return fix->fx_r_type != BFD_RELOC_PPC_TOC16;
+}
+
+#endif
+
+#ifdef OBJ_XCOFF
+
+/* XCOFF specific symbol and file handling. */
+
+/* Canonicalize the symbol name. We use the to force the suffix, if
+ any, to use square brackets, and to be in upper case. */
+
+char *
+ppc_canonicalize_symbol_name (name)
+ char *name;
+{
+ char *s;
+
+ if (ppc_stab_symbol)
+ return name;
+
+ for (s = name; *s != '\0' && *s != '{' && *s != '['; s++)
+ ;
+ if (*s != '\0')
+ {
+ char brac;
+
+ if (*s == '[')
+ brac = ']';
+ else
+ {
+ *s = '[';
+ brac = '}';
+ }
+
+ for (s++; *s != '\0' && *s != brac; s++)
+ if (islower (*s))
+ *s = toupper (*s);
+
+ if (*s == '\0' || s[1] != '\0')
+ as_bad (_("bad symbol suffix"));
+
+ *s = ']';
+ }
+
+ return name;
+}
+
+/* Set the class of a symbol based on the suffix, if any. This is
+ called whenever a new symbol is created. */
+
+void
+ppc_symbol_new_hook (sym)
+ symbolS *sym;
+{
+ const char *s;
+
+ sym->sy_tc.next = NULL;
+ sym->sy_tc.output = 0;
+ sym->sy_tc.class = -1;
+ sym->sy_tc.real_name = NULL;
+ sym->sy_tc.subseg = 0;
+ sym->sy_tc.align = 0;
+ sym->sy_tc.size = NULL;
+ sym->sy_tc.within = NULL;
+
+ if (ppc_stab_symbol)
+ return;
+
+ s = strchr (S_GET_NAME (sym), '[');
+ if (s == (const char *) NULL)
+ {
+ /* There is no suffix. */
+ return;
+ }
+
+ ++s;
+
+ switch (s[0])
+ {
+ case 'B':
+ if (strcmp (s, "BS]") == 0)
+ sym->sy_tc.class = XMC_BS;
+ break;
+ case 'D':
+ if (strcmp (s, "DB]") == 0)
+ sym->sy_tc.class = XMC_DB;
+ else if (strcmp (s, "DS]") == 0)
+ sym->sy_tc.class = XMC_DS;
+ break;
+ case 'G':
+ if (strcmp (s, "GL]") == 0)
+ sym->sy_tc.class = XMC_GL;
+ break;
+ case 'P':
+ if (strcmp (s, "PR]") == 0)
+ sym->sy_tc.class = XMC_PR;
+ break;
+ case 'R':
+ if (strcmp (s, "RO]") == 0)
+ sym->sy_tc.class = XMC_RO;
+ else if (strcmp (s, "RW]") == 0)
+ sym->sy_tc.class = XMC_RW;
+ break;
+ case 'S':
+ if (strcmp (s, "SV]") == 0)
+ sym->sy_tc.class = XMC_SV;
+ break;
+ case 'T':
+ if (strcmp (s, "TC]") == 0)
+ sym->sy_tc.class = XMC_TC;
+ else if (strcmp (s, "TI]") == 0)
+ sym->sy_tc.class = XMC_TI;
+ else if (strcmp (s, "TB]") == 0)
+ sym->sy_tc.class = XMC_TB;
+ else if (strcmp (s, "TC0]") == 0 || strcmp (s, "T0]") == 0)
+ sym->sy_tc.class = XMC_TC0;
+ break;
+ case 'U':
+ if (strcmp (s, "UA]") == 0)
+ sym->sy_tc.class = XMC_UA;
+ else if (strcmp (s, "UC]") == 0)
+ sym->sy_tc.class = XMC_UC;
+ break;
+ case 'X':
+ if (strcmp (s, "XO]") == 0)
+ sym->sy_tc.class = XMC_XO;
+ break;
+ }
+
+ if (sym->sy_tc.class == -1)
+ as_bad (_("Unrecognized symbol suffix"));
+}
+
+/* Set the class of a label based on where it is defined. This
+ handles symbols without suffixes. Also, move the symbol so that it
+ follows the csect symbol. */
+
+void
+ppc_frob_label (sym)
+ symbolS *sym;
+{
+ if (ppc_current_csect != (symbolS *) NULL)
+ {
+ if (sym->sy_tc.class == -1)
+ sym->sy_tc.class = ppc_current_csect->sy_tc.class;
+
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_append (sym, ppc_current_csect->sy_tc.within, &symbol_rootP,
+ &symbol_lastP);
+ ppc_current_csect->sy_tc.within = sym;
+ }
+}
+
+/* This variable is set by ppc_frob_symbol if any absolute symbols are
+ seen. It tells ppc_adjust_symtab whether it needs to look through
+ the symbols. */
+
+static boolean ppc_saw_abs;
+
+/* Change the name of a symbol just before writing it out. Set the
+ real name if the .rename pseudo-op was used. Otherwise, remove any
+ class suffix. Return 1 if the symbol should not be included in the
+ symbol table. */
+
+int
+ppc_frob_symbol (sym)
+ symbolS *sym;
+{
+ static symbolS *ppc_last_function;
+ static symbolS *set_end;
+
+ /* Discard symbols that should not be included in the output symbol
+ table. */
+ if (! sym->sy_used_in_reloc
+ && ((sym->bsym->flags & BSF_SECTION_SYM) != 0
+ || (! S_IS_EXTERNAL (sym)
+ && ! sym->sy_tc.output
+ && S_GET_STORAGE_CLASS (sym) != C_FILE)))
+ return 1;
+
+ if (sym->sy_tc.real_name != (char *) NULL)
+ S_SET_NAME (sym, sym->sy_tc.real_name);
+ else
+ {
+ const char *name;
+ const char *s;
+
+ name = S_GET_NAME (sym);
+ s = strchr (name, '[');
+ if (s != (char *) NULL)
+ {
+ unsigned int len;
+ char *snew;
+
+ len = s - name;
+ snew = xmalloc (len + 1);
+ memcpy (snew, name, len);
+ snew[len] = '\0';
+
+ S_SET_NAME (sym, snew);
+ }
+ }
+
+ if (set_end != (symbolS *) NULL)
+ {
+ SA_SET_SYM_ENDNDX (set_end, sym);
+ set_end = NULL;
+ }
+
+ if (SF_GET_FUNCTION (sym))
+ {
+ if (ppc_last_function != (symbolS *) NULL)
+ as_bad (_("two .function pseudo-ops with no intervening .ef"));
+ ppc_last_function = sym;
+ if (sym->sy_tc.size != (symbolS *) NULL)
+ {
+ resolve_symbol_value (sym->sy_tc.size, 1);
+ SA_SET_SYM_FSIZE (sym, (long) S_GET_VALUE (sym->sy_tc.size));
+ }
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_FCN
+ && strcmp (S_GET_NAME (sym), ".ef") == 0)
+ {
+ if (ppc_last_function == (symbolS *) NULL)
+ as_bad (_(".ef with no preceding .function"));
+ else
+ {
+ set_end = ppc_last_function;
+ ppc_last_function = NULL;
+
+ /* We don't have a C_EFCN symbol, but we need to force the
+ COFF backend to believe that it has seen one. */
+ coff_last_function = NULL;
+ }
+ }
+
+ if (! S_IS_EXTERNAL (sym)
+ && (sym->bsym->flags & BSF_SECTION_SYM) == 0
+ && S_GET_STORAGE_CLASS (sym) != C_FILE
+ && S_GET_STORAGE_CLASS (sym) != C_FCN
+ && S_GET_STORAGE_CLASS (sym) != C_BLOCK
+ && S_GET_STORAGE_CLASS (sym) != C_BSTAT
+ && S_GET_STORAGE_CLASS (sym) != C_ESTAT
+ && S_GET_STORAGE_CLASS (sym) != C_BINCL
+ && S_GET_STORAGE_CLASS (sym) != C_EINCL
+ && S_GET_SEGMENT (sym) != ppc_coff_debug_section)
+ S_SET_STORAGE_CLASS (sym, C_HIDEXT);
+
+ if (S_GET_STORAGE_CLASS (sym) == C_EXT
+ || S_GET_STORAGE_CLASS (sym) == C_HIDEXT)
+ {
+ int i;
+ union internal_auxent *a;
+
+ /* Create a csect aux. */
+ i = S_GET_NUMBER_AUXILIARY (sym);
+ S_SET_NUMBER_AUXILIARY (sym, i + 1);
+ a = &coffsymbol (sym->bsym)->native[i + 1].u.auxent;
+ if (sym->sy_tc.class == XMC_TC0)
+ {
+ /* This is the TOC table. */
+ know (strcmp (S_GET_NAME (sym), "TOC") == 0);
+ a->x_csect.x_scnlen.l = 0;
+ a->x_csect.x_smtyp = (2 << 3) | XTY_SD;
+ }
+ else if (sym->sy_tc.subseg != 0)
+ {
+ /* This is a csect symbol. x_scnlen is the size of the
+ csect. */
+ if (sym->sy_tc.next == (symbolS *) NULL)
+ a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
+ S_GET_SEGMENT (sym))
+ - S_GET_VALUE (sym));
+ else
+ {
+ resolve_symbol_value (sym->sy_tc.next, 1);
+ a->x_csect.x_scnlen.l = (S_GET_VALUE (sym->sy_tc.next)
+ - S_GET_VALUE (sym));
+ }
+ a->x_csect.x_smtyp = (sym->sy_tc.align << 3) | XTY_SD;
+ }
+ else if (S_GET_SEGMENT (sym) == bss_section)
+ {
+ /* This is a common symbol. */
+ a->x_csect.x_scnlen.l = sym->sy_frag->fr_offset;
+ a->x_csect.x_smtyp = (sym->sy_tc.align << 3) | XTY_CM;
+ if (S_IS_EXTERNAL (sym))
+ sym->sy_tc.class = XMC_RW;
+ else
+ sym->sy_tc.class = XMC_BS;
+ }
+ else if (S_GET_SEGMENT (sym) == absolute_section)
+ {
+ /* This is an absolute symbol. The csect will be created by
+ ppc_adjust_symtab. */
+ ppc_saw_abs = true;
+ a->x_csect.x_smtyp = XTY_LD;
+ if (sym->sy_tc.class == -1)
+ sym->sy_tc.class = XMC_XO;
+ }
+ else if (! S_IS_DEFINED (sym))
+ {
+ /* This is an external symbol. */
+ a->x_csect.x_scnlen.l = 0;
+ a->x_csect.x_smtyp = XTY_ER;
+ }
+ else if (sym->sy_tc.class == XMC_TC)
+ {
+ symbolS *next;
+
+ /* This is a TOC definition. x_scnlen is the size of the
+ TOC entry. */
+ next = symbol_next (sym);
+ while (next->sy_tc.class == XMC_TC0)
+ next = symbol_next (next);
+ if (next == (symbolS *) NULL
+ || next->sy_tc.class != XMC_TC)
+ {
+ if (ppc_after_toc_frag == (fragS *) NULL)
+ a->x_csect.x_scnlen.l = (bfd_section_size (stdoutput,
+ data_section)
+ - S_GET_VALUE (sym));
+ else
+ a->x_csect.x_scnlen.l = (ppc_after_toc_frag->fr_address
+ - S_GET_VALUE (sym));
+ }
+ else
+ {
+ resolve_symbol_value (next, 1);
+ a->x_csect.x_scnlen.l = (S_GET_VALUE (next)
+ - S_GET_VALUE (sym));
+ }
+ a->x_csect.x_smtyp = (2 << 3) | XTY_SD;
+ }
+ else
+ {
+ symbolS *csect;
+
+ /* This is a normal symbol definition. x_scnlen is the
+ symbol index of the containing csect. */
+ if (S_GET_SEGMENT (sym) == text_section)
+ csect = ppc_text_csects;
+ else if (S_GET_SEGMENT (sym) == data_section)
+ csect = ppc_data_csects;
+ else
+ abort ();
+
+ /* Skip the initial dummy symbol. */
+ csect = csect->sy_tc.next;
+
+ if (csect == (symbolS *) NULL)
+ {
+ as_warn (_("warning: symbol %s has no csect"), S_GET_NAME (sym));
+ a->x_csect.x_scnlen.l = 0;
+ }
+ else
+ {
+ while (csect->sy_tc.next != (symbolS *) NULL)
+ {
+ resolve_symbol_value (csect->sy_tc.next, 1);
+ if (S_GET_VALUE (csect->sy_tc.next) > S_GET_VALUE (sym))
+ break;
+ csect = csect->sy_tc.next;
+ }
+
+ a->x_csect.x_scnlen.p = coffsymbol (csect->bsym)->native;
+ coffsymbol (sym->bsym)->native[i + 1].fix_scnlen = 1;
+ }
+ a->x_csect.x_smtyp = XTY_LD;
+ }
+
+ a->x_csect.x_parmhash = 0;
+ a->x_csect.x_snhash = 0;
+ if (sym->sy_tc.class == -1)
+ a->x_csect.x_smclas = XMC_PR;
+ else
+ a->x_csect.x_smclas = sym->sy_tc.class;
+ a->x_csect.x_stab = 0;
+ a->x_csect.x_snstab = 0;
+
+ /* Don't let the COFF backend resort these symbols. */
+ sym->bsym->flags |= BSF_NOT_AT_END;
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_BSTAT)
+ {
+ /* We want the value to be the symbol index of the referenced
+ csect symbol. BFD will do that for us if we set the right
+ flags. */
+ S_SET_VALUE (sym,
+ (valueT) coffsymbol (sym->sy_tc.within->bsym)->native);
+ coffsymbol (sym->bsym)->native->fix_value = 1;
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_STSYM)
+ {
+ symbolS *block;
+ symbolS *csect;
+
+ /* The value is the offset from the enclosing csect. */
+ block = sym->sy_tc.within;
+ csect = block->sy_tc.within;
+ resolve_symbol_value (csect, 1);
+ S_SET_VALUE (sym, S_GET_VALUE (sym) - S_GET_VALUE (csect));
+ }
+ else if (S_GET_STORAGE_CLASS (sym) == C_BINCL
+ || S_GET_STORAGE_CLASS (sym) == C_EINCL)
+ {
+ /* We want the value to be a file offset into the line numbers.
+ BFD will do that for us if we set the right flags. We have
+ already set the value correctly. */
+ coffsymbol (sym->bsym)->native->fix_line = 1;
+ }
+
+ return 0;
+}
+
+/* Adjust the symbol table. This creates csect symbols for all
+ absolute symbols. */
+
+void
+ppc_adjust_symtab ()
+{
+ symbolS *sym;
+
+ if (! ppc_saw_abs)
+ return;
+
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ {
+ symbolS *csect;
+ int i;
+ union internal_auxent *a;
+
+ if (S_GET_SEGMENT (sym) != absolute_section)
+ continue;
+
+ csect = symbol_create (".abs[XO]", absolute_section,
+ S_GET_VALUE (sym), &zero_address_frag);
+ csect->bsym->value = S_GET_VALUE (sym);
+ S_SET_STORAGE_CLASS (csect, C_HIDEXT);
+ i = S_GET_NUMBER_AUXILIARY (csect);
+ S_SET_NUMBER_AUXILIARY (csect, i + 1);
+ a = &coffsymbol (csect->bsym)->native[i + 1].u.auxent;
+ a->x_csect.x_scnlen.l = 0;
+ a->x_csect.x_smtyp = XTY_SD;
+ a->x_csect.x_parmhash = 0;
+ a->x_csect.x_snhash = 0;
+ a->x_csect.x_smclas = XMC_XO;
+ a->x_csect.x_stab = 0;
+ a->x_csect.x_snstab = 0;
+
+ symbol_insert (csect, sym, &symbol_rootP, &symbol_lastP);
+
+ i = S_GET_NUMBER_AUXILIARY (sym);
+ a = &coffsymbol (sym->bsym)->native[i].u.auxent;
+ a->x_csect.x_scnlen.p = coffsymbol (csect->bsym)->native;
+ coffsymbol (sym->bsym)->native[i].fix_scnlen = 1;
+ }
+
+ ppc_saw_abs = false;
+}
+
+/* Set the VMA for a section. This is called on all the sections in
+ turn. */
+
+void
+ppc_frob_section (sec)
+ asection *sec;
+{
+ static bfd_size_type vma = 0;
+
+ bfd_set_section_vma (stdoutput, sec, vma);
+ vma += bfd_section_size (stdoutput, sec);
+}
+
+#endif /* OBJ_XCOFF */
+
+/* Turn a string in input_line_pointer into a floating point constant
+ of type type, and store the appropriate bytes in *litp. The number
+ of LITTLENUMS emitted is stored in *sizep . An error message is
+ returned, or NULL on OK. */
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char *litp;
+ int *sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+ }
+
+ return NULL;
+}
+
+/* Write a value out to the object file, using the appropriate
+ endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Align a section (I don't know why this is machine dependent). */
+
+valueT
+md_section_align (seg, addr)
+ asection *seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+/* We don't have any form of relaxing. */
+
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS *fragp;
+ asection *seg;
+{
+ abort ();
+ return 0;
+}
+
+/* Convert a machine dependent frag. We never generate these. */
+
+void
+md_convert_frag (abfd, sec, fragp)
+ bfd *abfd;
+ asection *sec;
+ fragS *fragp;
+{
+ abort ();
+}
+
+/* We have no need to default values of symbols. */
+
+/*ARGSUSED*/
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc. */
+
+long
+md_pcrel_from_section (fixp, sec)
+ fixS *fixp;
+ segT sec;
+{
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+#ifdef OBJ_XCOFF
+
+/* This is called to see whether a fixup should be adjusted to use a
+ section symbol. We take the opportunity to change a fixup against
+ a symbol in the TOC subsegment into a reloc against the
+ corresponding .tc symbol. */
+
+int
+ppc_fix_adjustable (fix)
+ fixS *fix;
+{
+ valueT val;
+
+ resolve_symbol_value (fix->fx_addsy, 1);
+ val = S_GET_VALUE (fix->fx_addsy);
+ if (ppc_toc_csect != (symbolS *) NULL
+ && fix->fx_addsy != (symbolS *) NULL
+ && fix->fx_addsy != ppc_toc_csect
+ && S_GET_SEGMENT (fix->fx_addsy) == data_section
+ && val >= ppc_toc_frag->fr_address
+ && (ppc_after_toc_frag == (fragS *) NULL
+ || val < ppc_after_toc_frag->fr_address))
+ {
+ symbolS *sy;
+
+ for (sy = symbol_next (ppc_toc_csect);
+ sy != (symbolS *) NULL;
+ sy = symbol_next (sy))
+ {
+ if (sy->sy_tc.class == XMC_TC0)
+ continue;
+ if (sy->sy_tc.class != XMC_TC)
+ break;
+ resolve_symbol_value (sy, 1);
+ if (val == S_GET_VALUE (sy))
+ {
+ fix->fx_addsy = sy;
+ fix->fx_addnumber = val - ppc_toc_frag->fr_address;
+ return 0;
+ }
+ }
+
+ as_bad_where (fix->fx_file, fix->fx_line,
+ _("symbol in .toc does not match any .tc"));
+ }
+
+ /* Possibly adjust the reloc to be against the csect. */
+ if (fix->fx_addsy != (symbolS *) NULL
+ && fix->fx_addsy->sy_tc.subseg == 0
+ && fix->fx_addsy->sy_tc.class != XMC_TC0
+ && fix->fx_addsy->sy_tc.class != XMC_TC
+ && S_GET_SEGMENT (fix->fx_addsy) != bss_section
+ /* Don't adjust if this is a reloc in the toc section. */
+ && (S_GET_SEGMENT (fix->fx_addsy) != data_section
+ || ppc_toc_csect == NULL
+ || val < ppc_toc_frag->fr_address
+ || (ppc_after_toc_frag != NULL
+ && val >= ppc_after_toc_frag->fr_address)))
+ {
+ symbolS *csect;
+
+ if (S_GET_SEGMENT (fix->fx_addsy) == text_section)
+ csect = ppc_text_csects;
+ else if (S_GET_SEGMENT (fix->fx_addsy) == data_section)
+ csect = ppc_data_csects;
+ else
+ abort ();
+
+ /* Skip the initial dummy symbol. */
+ csect = csect->sy_tc.next;
+
+ if (csect != (symbolS *) NULL)
+ {
+ while (csect->sy_tc.next != (symbolS *) NULL
+ && (csect->sy_tc.next->sy_frag->fr_address
+ <= fix->fx_addsy->sy_frag->fr_address))
+ {
+ /* If the csect address equals the symbol value, then we
+ have to look through the full symbol table to see
+ whether this is the csect we want. Note that we will
+ only get here if the csect has zero length. */
+ if ((csect->sy_frag->fr_address
+ == fix->fx_addsy->sy_frag->fr_address)
+ && S_GET_VALUE (csect) == S_GET_VALUE (fix->fx_addsy))
+ {
+ symbolS *scan;
+
+ for (scan = csect->sy_next;
+ scan != NULL;
+ scan = scan->sy_next)
+ {
+ if (scan->sy_tc.subseg != 0)
+ break;
+ if (scan == fix->fx_addsy)
+ break;
+ }
+
+ /* If we found the symbol before the next csect
+ symbol, then this is the csect we want. */
+ if (scan == fix->fx_addsy)
+ break;
+ }
+
+ csect = csect->sy_tc.next;
+ }
+
+ fix->fx_offset += (S_GET_VALUE (fix->fx_addsy)
+ - csect->sy_frag->fr_address);
+ fix->fx_addsy = csect;
+ }
+ }
+
+ /* Adjust a reloc against a .lcomm symbol to be against the base
+ .lcomm. */
+ if (fix->fx_addsy != (symbolS *) NULL
+ && S_GET_SEGMENT (fix->fx_addsy) == bss_section
+ && ! S_IS_EXTERNAL (fix->fx_addsy))
+ {
+ resolve_symbol_value (fix->fx_addsy->sy_frag->fr_symbol, 1);
+ fix->fx_offset += (S_GET_VALUE (fix->fx_addsy)
+ - S_GET_VALUE (fix->fx_addsy->sy_frag->fr_symbol));
+ fix->fx_addsy = fix->fx_addsy->sy_frag->fr_symbol;
+ }
+
+ return 0;
+}
+
+/* A reloc from one csect to another must be kept. The assembler
+ will, of course, keep relocs between sections, and it will keep
+ absolute relocs, but we need to force it to keep PC relative relocs
+ between two csects in the same section. */
+
+int
+ppc_force_relocation (fix)
+ fixS *fix;
+{
+ /* At this point fix->fx_addsy should already have been converted to
+ a csect symbol. If the csect does not include the fragment, then
+ we need to force the relocation. */
+ if (fix->fx_pcrel
+ && fix->fx_addsy != NULL
+ && fix->fx_addsy->sy_tc.subseg != 0
+ && (fix->fx_addsy->sy_frag->fr_address > fix->fx_frag->fr_address
+ || (fix->fx_addsy->sy_tc.next != NULL
+ && (fix->fx_addsy->sy_tc.next->sy_frag->fr_address
+ <= fix->fx_frag->fr_address))))
+ return 1;
+
+ return 0;
+}
+
+#endif /* OBJ_XCOFF */
+
+/* See whether a symbol is in the TOC section. */
+
+static int
+ppc_is_toc_sym (sym)
+ symbolS *sym;
+{
+#ifdef OBJ_XCOFF
+ return sym->sy_tc.class == XMC_TC;
+#else
+ return strcmp (segment_name (S_GET_SEGMENT (sym)), ".got") == 0;
+#endif
+}
+
+/* Apply a fixup to the object code. This is called for all the
+ fixups we generated by the call to fix_new_exp, above. In the call
+ above we used a reloc code which was the largest legal reloc code
+ plus the operand index. Here we undo that to recover the operand
+ index. At this point all symbol values should be fully resolved,
+ and we attempt to completely resolve the reloc. If we can not do
+ that, we determine the correct reloc code and put it back in the
+ fixup. */
+
+int
+md_apply_fix3 (fixp, valuep, seg)
+ fixS *fixp;
+ valueT *valuep;
+ segT seg;
+{
+ valueT value;
+
+#ifdef OBJ_ELF
+ value = *valuep;
+ if (fixp->fx_addsy != NULL)
+ {
+ /* `*valuep' may contain the value of the symbol on which the reloc
+ will be based; we have to remove it. */
+ if (fixp->fx_addsy->sy_used_in_reloc
+ && S_GET_SEGMENT (fixp->fx_addsy) != absolute_section
+ && S_GET_SEGMENT (fixp->fx_addsy) != undefined_section
+ && ! bfd_is_com_section (S_GET_SEGMENT (fixp->fx_addsy)))
+ value -= S_GET_VALUE (fixp->fx_addsy);
+
+ /* FIXME: Why '+'? Better yet, what exactly is '*valuep'
+ supposed to be? I think this is related to various similar
+ FIXMEs in tc-i386.c and tc-sparc.c. */
+ if (fixp->fx_pcrel)
+ value += fixp->fx_frag->fr_address + fixp->fx_where;
+ }
+ else
+ {
+ fixp->fx_done = 1;
+ }
+#else
+ /* FIXME FIXME FIXME: The value we are passed in *valuep includes
+ the symbol values. Since we are using BFD_ASSEMBLER, if we are
+ doing this relocation the code in write.c is going to call
+ bfd_install_relocation, which is also going to use the symbol
+ value. That means that if the reloc is fully resolved we want to
+ use *valuep since bfd_install_relocation is not being used.
+ However, if the reloc is not fully resolved we do not want to use
+ *valuep, and must use fx_offset instead. However, if the reloc
+ is PC relative, we do want to use *valuep since it includes the
+ result of md_pcrel_from. This is confusing. */
+ if (fixp->fx_addsy == (symbolS *) NULL)
+ {
+ value = *valuep;
+ fixp->fx_done = 1;
+ }
+ else if (fixp->fx_pcrel)
+ value = *valuep;
+ else
+ {
+ value = fixp->fx_offset;
+ if (fixp->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixp->fx_subsy);
+ else
+ {
+ /* We can't actually support subtracting a symbol. */
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+#endif
+
+ if ((int) fixp->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex;
+ const struct powerpc_operand *operand;
+ char *where;
+ unsigned long insn;
+
+ opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
+
+ operand = &powerpc_operands[opindex];
+
+#ifdef OBJ_XCOFF
+ /* It appears that an instruction like
+ l 9,LC..1(30)
+ when LC..1 is not a TOC symbol does not generate a reloc. It
+ uses the offset of LC..1 within its csect. However, .long
+ LC..1 will generate a reloc. I can't find any documentation
+ on how these cases are to be distinguished, so this is a wild
+ guess. These cases are generated by gcc -mminimal-toc. */
+ if ((operand->flags & PPC_OPERAND_PARENS) != 0
+ && operand->bits == 16
+ && operand->shift == 0
+ && operand->insert == NULL
+ && fixp->fx_addsy != NULL
+ && fixp->fx_addsy->sy_tc.subseg != 0
+ && fixp->fx_addsy->sy_tc.class != XMC_TC
+ && fixp->fx_addsy->sy_tc.class != XMC_TC0
+ && S_GET_SEGMENT (fixp->fx_addsy) != bss_section)
+ {
+ value = fixp->fx_offset;
+ fixp->fx_done = 1;
+ }
+#endif
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixp->fx_frag->fr_literal + fixp->fx_where;
+ if (target_big_endian)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getl32 ((unsigned char *) where);
+ insn = ppc_insert_operand (insn, operand, (offsetT) value,
+ fixp->fx_file, fixp->fx_line);
+ if (target_big_endian)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+
+ if (fixp->fx_done)
+ {
+ /* Nothing else to do here. */
+ return 1;
+ }
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into
+ relocs.
+ FIXME: We need to handle the DS field at the very least.
+ FIXME: Selecting the reloc type is a bit haphazard; perhaps
+ there should be a new field in the operand table. */
+ if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bits == 26
+ && operand->shift == 0)
+ fixp->fx_r_type = BFD_RELOC_PPC_B26;
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
+ && operand->bits == 16
+ && operand->shift == 0)
+ fixp->fx_r_type = BFD_RELOC_PPC_B16;
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
+ && operand->bits == 26
+ && operand->shift == 0)
+ fixp->fx_r_type = BFD_RELOC_PPC_BA26;
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
+ && operand->bits == 16
+ && operand->shift == 0)
+ fixp->fx_r_type = BFD_RELOC_PPC_BA16;
+ else if ((operand->flags & PPC_OPERAND_PARENS) != 0
+ && operand->bits == 16
+ && operand->shift == 0
+ && operand->insert == NULL
+ && fixp->fx_addsy != NULL
+ && ppc_is_toc_sym (fixp->fx_addsy))
+ {
+ fixp->fx_size = 2;
+ if (target_big_endian)
+ fixp->fx_where += 2;
+ fixp->fx_r_type = BFD_RELOC_PPC_TOC16;
+ }
+ else
+ {
+ char *sfile;
+ unsigned int sline;
+
+ /* Use expr_symbol_where to see if this is an expression
+ symbol. */
+ if (expr_symbol_where (fixp->fx_addsy, &sfile, &sline))
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("unresolved expression that must be resolved"));
+ else
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("unsupported relocation type"));
+ fixp->fx_done = 1;
+ return 1;
+ }
+ }
+ else
+ {
+#ifdef OBJ_ELF
+ ppc_elf_validate_fix (fixp, seg);
+#endif
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ if (fixp->fx_pcrel)
+ fixp->fx_r_type = BFD_RELOC_32_PCREL;
+ /* fall through */
+
+ case BFD_RELOC_RVA:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_32_BASEREL:
+ case BFD_RELOC_PPC_EMB_NADDR32:
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
+ value, 4);
+ break;
+
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_16:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_16_GOT_PCREL:
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_LO16_GOTOFF:
+ case BFD_RELOC_HI16_GOTOFF:
+ case BFD_RELOC_HI16_S_GOTOFF:
+ case BFD_RELOC_LO16_BASEREL:
+ case BFD_RELOC_HI16_BASEREL:
+ case BFD_RELOC_HI16_S_BASEREL:
+ case BFD_RELOC_PPC_EMB_NADDR16:
+ case BFD_RELOC_PPC_EMB_NADDR16_LO:
+ case BFD_RELOC_PPC_EMB_NADDR16_HI:
+ case BFD_RELOC_PPC_EMB_NADDR16_HA:
+ case BFD_RELOC_PPC_EMB_SDAI16:
+ case BFD_RELOC_PPC_EMB_SDA2REL:
+ case BFD_RELOC_PPC_EMB_SDA2I16:
+ case BFD_RELOC_PPC_EMB_RELSEC16:
+ case BFD_RELOC_PPC_EMB_RELST_LO:
+ case BFD_RELOC_PPC_EMB_RELST_HI:
+ case BFD_RELOC_PPC_EMB_RELST_HA:
+ case BFD_RELOC_PPC_EMB_RELSDA:
+ case BFD_RELOC_PPC_TOC16:
+ if (fixp->fx_pcrel)
+ {
+ if (fixp->fx_addsy != NULL)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot emit PC relative %s relocation against %s"),
+ bfd_get_reloc_code_name (fixp->fx_r_type),
+ S_GET_NAME (fixp->fx_addsy));
+ else
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("cannot emit PC relative %s relocation"),
+ bfd_get_reloc_code_name (fixp->fx_r_type));
+ }
+
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
+ value, 2);
+ break;
+
+ /* This case happens when you write, for example,
+ lis %r3,(L1-L2)@ha
+ where L1 and L2 are defined later. */
+ case BFD_RELOC_HI16:
+ if (fixp->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
+ value >> 16, 2);
+ break;
+ case BFD_RELOC_HI16_S:
+ if (fixp->fx_pcrel)
+ abort ();
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
+ value + 0x8000 >> 16, 2);
+ break;
+
+ /* Because SDA21 modifies the register field, the size is set to 4
+ bytes, rather than 2, so offset it here appropriately */
+ case BFD_RELOC_PPC_EMB_SDA21:
+ if (fixp->fx_pcrel)
+ abort ();
+
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where
+ + ((target_big_endian) ? 2 : 0),
+ value, 2);
+ break;
+
+ case BFD_RELOC_8:
+ if (fixp->fx_pcrel)
+ abort ();
+
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
+ value, 1);
+ break;
+
+ case BFD_RELOC_24_PLT_PCREL:
+ case BFD_RELOC_PPC_LOCAL24PC:
+ if (!fixp->fx_pcrel && !fixp->fx_done)
+ abort ();
+
+ if (fixp->fx_done)
+ {
+ char *where;
+ unsigned long insn;
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again. */
+ where = fixp->fx_frag->fr_literal + fixp->fx_where;
+ if (target_big_endian)
+ insn = bfd_getb32 ((unsigned char *) where);
+ else
+ insn = bfd_getl32 ((unsigned char *) where);
+ if ((value & 3) != 0)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("must branch to an address a multiple of 4"));
+ if ((offsetT) value < -0x40000000
+ || (offsetT) value >= 0x40000000)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("@local or @plt branch destination is too far away, %ld bytes"),
+ value);
+ insn = insn | (value & 0x03fffffc);
+ if (target_big_endian)
+ bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
+ else
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+ }
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ fixp->fx_done = 0;
+ if (fixp->fx_addsy
+ && !S_IS_DEFINED (fixp->fx_addsy)
+ && !S_IS_WEAK (fixp->fx_addsy))
+ S_SET_WEAK (fixp->fx_addsy);
+ break;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixp->fx_done = 0;
+ break;
+
+ default:
+ fprintf(stderr,
+ _("Gas failure, reloc value %d\n"), fixp->fx_r_type);
+ fflush(stderr);
+ abort ();
+ }
+ }
+
+#ifdef OBJ_ELF
+ fixp->fx_addnumber = value;
+#else
+ if (fixp->fx_r_type != BFD_RELOC_PPC_TOC16)
+ fixp->fx_addnumber = 0;
+ else
+ {
+#ifdef TE_PE
+ fixp->fx_addnumber = 0;
+#else
+ /* We want to use the offset within the data segment of the
+ symbol, not the actual VMA of the symbol. */
+ fixp->fx_addnumber =
+ - bfd_get_section_vma (stdoutput, S_GET_SEGMENT (fixp->fx_addsy));
+#endif
+ }
+#endif
+
+ return 1;
+}
+
+/* Generate a reloc for a fixup. */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection *seg;
+ fixS *fixp;
+{
+ arelent *reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("reloc %d not supported by object file format"), (int)fixp->fx_r_type);
+ return NULL;
+ }
+ reloc->addend = fixp->fx_addnumber;
+
+ return reloc;
+}
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
new file mode 100644
index 00000000000..0871d130d6d
--- /dev/null
+++ b/gas/config/tc-ppc.h
@@ -0,0 +1,276 @@
+/* tc-ppc.h -- Header file for tc-ppc.c.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_PPC
+
+#ifdef ANSI_PROTOTYPES
+struct fix;
+#endif
+
+/* Set the endianness we are using. Default to big endian. */
+#ifndef TARGET_BYTES_BIG_ENDIAN
+#define TARGET_BYTES_BIG_ENDIAN 1
+#endif
+
+#ifndef BFD_ASSEMBLER
+ #error PowerPC support requires BFD_ASSEMBLER
+#endif
+
+/* If OBJ_COFF is defined, and TE_PE is not defined, we are assembling
+ XCOFF for AIX or PowerMac. If TE_PE is defined, we are assembling
+ COFF for Windows NT. */
+
+#ifdef OBJ_COFF
+#ifndef TE_PE
+#define OBJ_XCOFF
+#endif
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH (ppc_arch ())
+extern enum bfd_architecture ppc_arch PARAMS ((void));
+
+/* Whether or not the target is big endian */
+extern int target_big_endian;
+
+/* The target BFD format. */
+#ifdef OBJ_COFF
+#ifdef TE_PE
+#define TARGET_FORMAT (target_big_endian ? "pe-powerpc" : "pe-powerpcle")
+#else
+#define TARGET_FORMAT "aixcoff-rs6000"
+#endif
+#endif
+
+/* PowerMac has a BFD slightly different from AIX's. */
+#ifdef TE_POWERMAC
+#ifdef TARGET_FORMAT
+#undef TARGET_FORMAT
+#endif
+#define TARGET_FORMAT "xcoff-powermac"
+#endif
+
+#ifdef OBJ_ELF
+#define TARGET_FORMAT (target_big_endian ? "elf32-powerpc" : "elf32-powerpcle")
+#endif
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+/* $ is used to refer to the current location. */
+#define DOLLAR_DOT
+
+/* Strings do not use backslash escapes under COFF. */
+#ifdef OBJ_COFF
+#define NO_STRING_ESCAPES
+#endif
+
+#ifdef OBJ_ELF
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+#endif
+
+#if TARGET_BYTES_BIG_ENDIAN
+#define PPC_BIG_ENDIAN 1
+#else
+#define PPC_BIG_ENDIAN 0
+#endif
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+/* We set the fx_done field appropriately in md_apply_fix. */
+#define TC_HANDLES_FX_DONE
+
+#ifdef TE_PE
+
+/* Question marks are permitted in symbol names. */
+#define LEX_QM 1
+
+/* Don't adjust TOC relocs. */
+#define tc_fix_adjustable(fixp) ppc_pe_fix_adjustable (fixp)
+extern int ppc_pe_fix_adjustable PARAMS ((struct fix *));
+
+#endif
+
+#ifdef OBJ_XCOFF
+
+/* Declarations needed when generating XCOFF code. XCOFF is an
+ extension of COFF, used only on the RS/6000. Rather than create an
+ obj-xcoff, we just use obj-coff, and handle the extensions here in
+ tc-ppc. */
+
+/* We need to keep some information for symbols. */
+struct ppc_tc_sy
+{
+ /* We keep a few linked lists of symbols. */
+ struct symbol *next;
+ /* Non-zero if the symbol should be output. The RS/6000 assembler
+ only outputs symbols that are external or are mentioned in a
+ .globl or .lglobl statement. */
+ int output;
+ /* The symbol class. */
+ int class;
+ /* The real name, if the symbol was renamed. */
+ char *real_name;
+ /* For a csect symbol, the subsegment we are using. This is zero
+ for symbols that are not csects. */
+ subsegT subseg;
+ /* For a csect or common symbol, the alignment to use. */
+ int align;
+ /* For a function symbol, a symbol whose value is the size. The
+ field is NULL if there is no size. */
+ struct symbol *size;
+ /* For a csect symbol, the last symbol which has been defined in
+ this csect, or NULL if none have been defined so far. For a .bs
+ symbol, the referenced csect symbol. */
+ struct symbol *within;
+};
+
+#define TC_SYMFIELD_TYPE struct ppc_tc_sy
+
+/* We need an additional auxent for function symbols. */
+#define OBJ_COFF_MAX_AUXENTRIES 2
+
+/* Square and curly brackets are permitted in symbol names. */
+#define LEX_BR 3
+
+/* Canonicalize the symbol name. */
+#define tc_canonicalize_symbol_name(name) ppc_canonicalize_symbol_name (name)
+extern char *ppc_canonicalize_symbol_name PARAMS ((char *));
+
+/* Get the symbol class from the name. */
+#define tc_symbol_new_hook(sym) ppc_symbol_new_hook (sym)
+extern void ppc_symbol_new_hook PARAMS ((struct symbol *));
+
+/* Set the symbol class of a label based on the csect. */
+#define tc_frob_label(sym) ppc_frob_label (sym)
+extern void ppc_frob_label PARAMS ((struct symbol *));
+
+/* TOC relocs requires special handling. */
+#define tc_fix_adjustable(fixp) ppc_fix_adjustable (fixp)
+extern int ppc_fix_adjustable PARAMS ((struct fix *));
+
+/* A relocation from one csect to another must be kept. */
+#define TC_FORCE_RELOCATION(FIXP) ppc_force_relocation (FIXP)
+extern int ppc_force_relocation PARAMS ((struct fix *));
+
+/* We need to set the section VMA. */
+#define tc_frob_section(sec) ppc_frob_section (sec)
+extern void ppc_frob_section PARAMS ((asection *));
+
+/* Finish up the symbol. */
+#define tc_frob_symbol(sym, punt) punt = ppc_frob_symbol (sym)
+extern int ppc_frob_symbol PARAMS ((struct symbol *));
+
+/* Finish up the entire symtab. */
+#define tc_adjust_symtab() ppc_adjust_symtab ()
+extern void ppc_adjust_symtab PARAMS ((void));
+
+/* Niclas Andersson <nican@ida.liu.se> says this is needed. */
+#define SUB_SEGMENT_ALIGN(SEG) 2
+
+#endif /* OBJ_XCOFF */
+
+#ifdef OBJ_ELF
+
+/* Branch prediction relocations must force relocation, as must
+ the vtable description relocs. */
+#define TC_FORCE_RELOCATION(FIXP) \
+((FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRTAKEN \
+ || (FIXP)->fx_r_type == BFD_RELOC_PPC_B16_BRNTAKEN \
+ || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRTAKEN \
+ || (FIXP)->fx_r_type == BFD_RELOC_PPC_BA16_BRNTAKEN \
+ || (FIXP)->fx_r_type == BFD_RELOC_VTABLE_INHERIT \
+ || (FIXP)->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+
+#define TC_FORCE_RELOCATION_SECTION(FIXP,SEC) \
+(TC_FORCE_RELOCATION (FIXP) \
+ || ((FIXP)->fx_addsy && !(FIXP)->fx_subsy && (FIXP)->fx_addsy->bsym \
+ && (FIXP)->fx_addsy->bsym->section != SEC))
+
+/* Support for SHF_EXCLUDE and SHT_ORDERED */
+extern int ppc_section_letter PARAMS ((int, char **));
+extern int ppc_section_type PARAMS ((char **));
+extern int ppc_section_word PARAMS ((char **));
+extern int ppc_section_flags PARAMS ((int, int, int));
+
+#define md_elf_section_letter(LETTER, PTR_MSG) ppc_section_letter (LETTER, PTR_MSG)
+#define md_elf_section_type(PTR_STR) ppc_section_type (PTR_STR)
+#define md_elf_section_word(PTR_STR) ppc_section_word (PTR_STR)
+#define md_elf_section_flags(FLAGS, ATTR, TYPE) ppc_section_flags (FLAGS, ATTR, TYPE)
+
+/* Add extra PPC sections -- Note, for now, make .sbss2 and .PPC.EMB.sbss0 a
+ normal section, and not a bss section so that the linker doesn't crater
+ when trying to make more than 2 sections. */
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".tags", SHT_ORDERED, SHF_ALLOC }, \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, \
+ { ".sdata2", SHT_PROGBITS, SHF_ALLOC }, \
+ { ".sbss2", SHT_PROGBITS, SHF_ALLOC }, \
+ { ".PPC.EMB.sdata0", SHT_PROGBITS, SHF_ALLOC }, \
+ { ".PPC.EMB.sbss0", SHT_PROGBITS, SHF_ALLOC },
+
+#define tc_comment_chars ppc_comment_chars
+extern const char *ppc_comment_chars;
+
+/* Keep relocations relative to the GOT, or non-PC relative. */
+#define tc_fix_adjustable(FIX) \
+ ((FIX)->fx_r_type != BFD_RELOC_16_GOTOFF \
+ && (FIX)->fx_r_type != BFD_RELOC_LO16_GOTOFF \
+ && (FIX)->fx_r_type != BFD_RELOC_HI16_GOTOFF \
+ && (FIX)->fx_r_type != BFD_RELOC_HI16_S_GOTOFF \
+ && (FIX)->fx_r_type != BFD_RELOC_GPREL16 \
+ && (FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \
+ && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \
+ && ! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && ((FIX)->fx_pcrel \
+ || ((FIX)->fx_subsy != NULL \
+ && (S_GET_SEGMENT ((FIX)->fx_subsy) \
+ == S_GET_SEGMENT ((FIX)->fx_addsy))) \
+ || strchr (S_GET_NAME ((FIX)->fx_addsy), '\001') != NULL \
+ || strchr (S_GET_NAME ((FIX)->fx_addsy), '\002') != NULL))
+
+/* We must never ever try to resolve references to externally visible
+ symbols in the assembler, because the .o file might go into a shared
+ library, and some other shared library might override that symbol. */
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy)))
+
+#endif /* OBJ_ELF */
+
+/* call md_apply_fix3 with segment instead of md_apply_fix */
+#define MD_APPLY_FIX3
+
+/* call md_pcrel_from_section, not md_pcrel_from */
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
+extern long md_pcrel_from_section PARAMS ((struct fix *, segT));
+
+#define md_parse_name(name, exp) ppc_parse_name (name, exp)
+extern int ppc_parse_name PARAMS ((const char *, struct expressionS *));
+
+#define md_operand(x)
+
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c
new file mode 100644
index 00000000000..6d8ca816431
--- /dev/null
+++ b/gas/config/tc-sh.c
@@ -0,0 +1,2425 @@
+/* tc-sh.c -- Assemble code for the Hitachi Super-H
+ Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ Written By Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include <stdio.h>
+#include "as.h"
+#include "bfd.h"
+#include "subsegs.h"
+#define DEFINE_TABLE
+#include "opcodes/sh-opc.h"
+#include <ctype.h>
+const char comment_chars[] = "!";
+const char line_separator_chars[] = ";";
+const char line_comment_chars[] = "!#";
+
+static void s_uses PARAMS ((int));
+
+static void sh_count_relocs PARAMS ((bfd *, segT, PTR));
+static void sh_frob_section PARAMS ((bfd *, segT, PTR));
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+void cons ();
+void s_align_bytes ();
+static void s_uacons PARAMS ((int));
+
+int shl = 0;
+
+static void
+little (ignore)
+ int ignore;
+{
+ shl = 1;
+ target_big_endian = 0;
+}
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"int", cons, 4},
+ {"word", cons, 2},
+ {"form", listing_psize, 0},
+ {"little", little, 0},
+ {"heading", listing_title, 0},
+ {"import", s_ignore, 0},
+ {"page", listing_eject, 0},
+ {"program", s_ignore, 0},
+ {"uses", s_uses, 0},
+ {"uaword", s_uacons, 2},
+ {"ualong", s_uacons, 4},
+ {0, 0, 0}
+};
+
+/*int md_reloc_size; */
+
+int sh_relax; /* set if -relax seen */
+
+/* Whether -small was seen. */
+
+int sh_small;
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+#define C(a,b) ENCODE_RELAX(a,b)
+
+#define JREG 14 /* Register used as a temp when relaxing */
+#define ENCODE_RELAX(what,length) (((what) << 4) + (length))
+#define GET_WHAT(x) ((x>>4))
+
+/* These are the three types of relaxable instrction */
+#define COND_JUMP 1
+#define COND_JUMP_DELAY 2
+#define UNCOND_JUMP 3
+#define END 4
+
+#define UNDEF_DISP 0
+#define COND8 1
+#define COND12 2
+#define COND32 3
+#define UNCOND12 1
+#define UNCOND32 2
+#define UNDEF_WORD_DISP 4
+
+#define UNCOND12 1
+#define UNCOND32 2
+
+/* Branch displacements are from the address of the branch plus
+ four, thus all minimum and maximum values have 4 added to them. */
+#define COND8_F 258
+#define COND8_M -252
+#define COND8_LENGTH 2
+
+/* There is one extra instruction before the branch, so we must add
+ two more bytes to account for it. */
+#define COND12_F 4100
+#define COND12_M -4090
+#define COND12_LENGTH 6
+
+#define COND12_DELAY_LENGTH 4
+
+/* ??? The minimum and maximum values are wrong, but this does not matter
+ since this relocation type is not supported yet. */
+#define COND32_F (1<<30)
+#define COND32_M -(1<<30)
+#define COND32_LENGTH 14
+
+#define UNCOND12_F 4098
+#define UNCOND12_M -4092
+#define UNCOND12_LENGTH 2
+
+/* ??? The minimum and maximum values are wrong, but this does not matter
+ since this relocation type is not supported yet. */
+#define UNCOND32_F (1<<30)
+#define UNCOND32_M -(1<<30)
+#define UNCOND32_LENGTH 14
+
+const relax_typeS md_relax_table[C (END, 0)] = {
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 },
+ /* C (COND_JUMP, COND8) */
+ { COND8_F, COND8_M, COND8_LENGTH, C (COND_JUMP, COND12) },
+ /* C (COND_JUMP, COND12) */
+ { COND12_F, COND12_M, COND12_LENGTH, C (COND_JUMP, COND32), },
+ /* C (COND_JUMP, COND32) */
+ { COND32_F, COND32_M, COND32_LENGTH, 0, },
+ { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 },
+ /* C (COND_JUMP_DELAY, COND8) */
+ { COND8_F, COND8_M, COND8_LENGTH, C (COND_JUMP_DELAY, COND12) },
+ /* C (COND_JUMP_DELAY, COND12) */
+ { COND12_F, COND12_M, COND12_DELAY_LENGTH, C (COND_JUMP_DELAY, COND32), },
+ /* C (COND_JUMP_DELAY, COND32) */
+ { COND32_F, COND32_M, COND32_LENGTH, 0, },
+ { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 },
+ /* C (UNCOND_JUMP, UNCOND12) */
+ { UNCOND12_F, UNCOND12_M, UNCOND12_LENGTH, C (UNCOND_JUMP, UNCOND32), },
+ /* C (UNCOND_JUMP, UNCOND32) */
+ { UNCOND32_F, UNCOND32_M, UNCOND32_LENGTH, 0, },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+};
+
+static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
+
+/*
+ This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs
+ */
+
+void
+md_begin ()
+{
+ sh_opcode_info *opcode;
+ char *prev_name = "";
+
+ if (! shl)
+ target_big_endian = 1;
+
+ opcode_hash_control = hash_new ();
+
+ /* Insert unique names into hash table */
+ for (opcode = sh_table; opcode->name; opcode++)
+ {
+ if (strcmp (prev_name, opcode->name))
+ {
+ prev_name = opcode->name;
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ }
+ else
+ {
+ /* Make all the opcodes with the same name point to the same
+ string */
+ opcode->name = prev_name;
+ }
+ }
+}
+
+static int reg_m;
+static int reg_n;
+static int reg_b;
+
+static expressionS immediate; /* absolute expression */
+
+typedef struct
+ {
+ sh_arg_type type;
+ int reg;
+ }
+
+sh_operand_info;
+
+/* try and parse a reg name, returns number of chars consumed */
+static int
+parse_reg (src, mode, reg)
+ char *src;
+ int *mode;
+ int *reg;
+{
+ /* We use !isalnum for the next character after the register name, to
+ make sure that we won't accidentally recognize a symbol name such as
+ 'sram' as being a reference to the register 'sr'. */
+
+ if (src[0] == 'r')
+ {
+ if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0
+ && ! isalnum ((unsigned char) src[7]))
+ {
+ *mode = A_REG_B;
+ *reg = (src[1] - '0');
+ return 7;
+ }
+ }
+
+ if (src[0] == 'r')
+ {
+ if (src[1] == '1')
+ {
+ if (src[2] >= '0' && src[2] <= '5'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_REG_N;
+ *reg = 10 + src[2] - '0';
+ return 3;
+ }
+ }
+ if (src[1] >= '0' && src[1] <= '9'
+ && ! isalnum ((unsigned char) src[2]))
+ {
+ *mode = A_REG_N;
+ *reg = (src[1] - '0');
+ return 2;
+ }
+ }
+
+ if (src[0] == 's'
+ && src[1] == 's'
+ && src[2] == 'r' && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_SSR;
+ return 3;
+ }
+
+ if (src[0] == 's' && src[1] == 'p' && src[2] == 'c'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_SPC;
+ return 3;
+ }
+
+ if (src[0] == 's' && src[1] == 'g' && src[2] == 'r'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_SGR;
+ return 3;
+ }
+
+ if (src[0] == 'd' && src[1] == 'b' && src[2] == 'r'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_DBR;
+ return 3;
+ }
+
+ if (src[0] == 's' && src[1] == 'r' && ! isalnum ((unsigned char) src[2]))
+ {
+ *mode = A_SR;
+ return 2;
+ }
+
+ if (src[0] == 's' && src[1] == 'p' && ! isalnum ((unsigned char) src[2]))
+ {
+ *mode = A_REG_N;
+ *reg = 15;
+ return 2;
+ }
+
+ if (src[0] == 'p' && src[1] == 'r' && ! isalnum ((unsigned char) src[2]))
+ {
+ *mode = A_PR;
+ return 2;
+ }
+ if (src[0] == 'p' && src[1] == 'c' && ! isalnum ((unsigned char) src[2]))
+ {
+ *mode = A_DISP_PC;
+ return 2;
+ }
+ if (src[0] == 'g' && src[1] == 'b' && src[2] == 'r'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_GBR;
+ return 3;
+ }
+ if (src[0] == 'v' && src[1] == 'b' && src[2] == 'r'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = A_VBR;
+ return 3;
+ }
+
+ if (src[0] == 'm' && src[1] == 'a' && src[2] == 'c'
+ && ! isalnum ((unsigned char) src[4]))
+ {
+ if (src[3] == 'l')
+ {
+ *mode = A_MACL;
+ return 4;
+ }
+ if (src[3] == 'h')
+ {
+ *mode = A_MACH;
+ return 4;
+ }
+ }
+ if (src[0] == 'f' && src[1] == 'r')
+ {
+ if (src[2] == '1')
+ {
+ if (src[3] >= '0' && src[3] <= '5'
+ && ! isalnum ((unsigned char) src[4]))
+ {
+ *mode = F_REG_N;
+ *reg = 10 + src[3] - '0';
+ return 4;
+ }
+ }
+ if (src[2] >= '0' && src[2] <= '9'
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = F_REG_N;
+ *reg = (src[2] - '0');
+ return 3;
+ }
+ }
+ if (src[0] == 'd' && src[1] == 'r')
+ {
+ if (src[2] == '1')
+ {
+ if (src[3] >= '0' && src[3] <= '4' && ! ((src[3] - '0') & 1)
+ && ! isalnum ((unsigned char) src[4]))
+ {
+ *mode = D_REG_N;
+ *reg = 10 + src[3] - '0';
+ return 4;
+ }
+ }
+ if (src[2] >= '0' && src[2] <= '8' && ! ((src[2] - '0') & 1)
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = D_REG_N;
+ *reg = (src[2] - '0');
+ return 3;
+ }
+ }
+ if (src[0] == 'x' && src[1] == 'd')
+ {
+ if (src[2] == '1')
+ {
+ if (src[3] >= '0' && src[3] <= '4' && ! ((src[3] - '0') & 1)
+ && ! isalnum ((unsigned char) src[4]))
+ {
+ *mode = X_REG_N;
+ *reg = 11 + src[3] - '0';
+ return 4;
+ }
+ }
+ if (src[2] >= '0' && src[2] <= '8' && ! ((src[2] - '0') & 1)
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = X_REG_N;
+ *reg = (src[2] - '0') + 1;
+ return 3;
+ }
+ }
+ if (src[0] == 'f' && src[1] == 'v')
+ {
+ if (src[2] == '1'&& src[3] == '2' && ! isalnum ((unsigned char) src[4]))
+ {
+ *mode = V_REG_N;
+ *reg = 12;
+ return 4;
+ }
+ if ((src[2] == '0' || src[2] == '4' || src[2] == '8')
+ && ! isalnum ((unsigned char) src[3]))
+ {
+ *mode = V_REG_N;
+ *reg = (src[2] - '0');
+ return 3;
+ }
+ }
+ if (src[0] == 'f' && src[1] == 'p' && src[2] == 'u' && src[3] == 'l'
+ && ! isalnum ((unsigned char) src[4]))
+ {
+ *mode = FPUL_N;
+ return 4;
+ }
+
+ if (src[0] == 'f' && src[1] == 'p' && src[2] == 's' && src[3] == 'c'
+ && src[4] == 'r' && ! isalnum ((unsigned char) src[5]))
+ {
+ *mode = FPSCR_N;
+ return 5;
+ }
+
+ if (src[0] == 'x' && src[1] == 'm' && src[2] == 't' && src[3] == 'r'
+ && src[4] == 'x' && ! isalnum ((unsigned char) src[5]))
+ {
+ *mode = XMTRX_M4;
+ return 5;
+ }
+
+ return 0;
+}
+
+static symbolS *dot()
+{
+ const char *fake;
+
+ /* JF: '.' is pseudo symbol with value of current location
+ in current segment. */
+ fake = FAKE_LABEL_NAME;
+ return symbol_new (fake,
+ now_seg,
+ (valueT) frag_now_fix (),
+ frag_now);
+
+}
+
+
+static
+char *
+parse_exp (s)
+ char *s;
+{
+ char *save;
+ char *new;
+
+ save = input_line_pointer;
+ input_line_pointer = s;
+ expression (&immediate);
+ if (immediate.X_op == O_absent)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+
+/* The many forms of operand:
+
+ Rn Register direct
+ @Rn Register indirect
+ @Rn+ Autoincrement
+ @-Rn Autodecrement
+ @(disp:4,Rn)
+ @(disp:8,GBR)
+ @(disp:8,PC)
+
+ @(R0,Rn)
+ @(R0,GBR)
+
+ disp:8
+ disp:12
+ #imm8
+ pr, gbr, vbr, macl, mach
+
+ */
+
+static
+char *
+parse_at (src, op)
+ char *src;
+ sh_operand_info *op;
+{
+ int len;
+ int mode;
+ src++;
+ if (src[0] == '-')
+ {
+ /* Must be predecrement */
+ src++;
+
+ len = parse_reg (src, &mode, &(op->reg));
+ if (mode != A_REG_N)
+ as_bad (_("illegal register after @-"));
+
+ op->type = A_DEC_N;
+ src += len;
+ }
+ else if (src[0] == '(')
+ {
+ /* Could be @(disp, rn), @(disp, gbr), @(disp, pc), @(r0, gbr) or
+ @(r0, rn) */
+ src++;
+ len = parse_reg (src, &mode, &(op->reg));
+ if (len && mode == A_REG_N)
+ {
+ src += len;
+ if (op->reg != 0)
+ {
+ as_bad (_("must be @(r0,...)"));
+ }
+ if (src[0] == ',')
+ src++;
+ /* Now can be rn or gbr */
+ len = parse_reg (src, &mode, &(op->reg));
+ if (mode == A_GBR)
+ {
+ op->type = A_R0_GBR;
+ }
+ else if (mode == A_REG_N)
+ {
+ op->type = A_IND_R0_REG_N;
+ }
+ else
+ {
+ as_bad (_("syntax error in @(r0,...)"));
+ }
+ }
+ else
+ {
+ /* Must be an @(disp,.. thing) */
+ src = parse_exp (src);
+ if (src[0] == ',')
+ src++;
+ /* Now can be rn, gbr or pc */
+ len = parse_reg (src, &mode, &op->reg);
+ if (len)
+ {
+ if (mode == A_REG_N)
+ {
+ op->type = A_DISP_REG_N;
+ }
+ else if (mode == A_GBR)
+ {
+ op->type = A_DISP_GBR;
+ }
+ else if (mode == A_DISP_PC)
+ {
+ /* Turn a plain @(4,pc) into @(.+4,pc) */
+ if (immediate.X_op == O_constant) {
+ immediate.X_add_symbol = dot();
+ immediate.X_op = O_symbol;
+ }
+ op->type = A_DISP_PC;
+ }
+ else
+ {
+ as_bad (_("syntax error in @(disp,[Rn, gbr, pc])"));
+ }
+ }
+ else
+ {
+ as_bad (_("syntax error in @(disp,[Rn, gbr, pc])"));
+ }
+ }
+ src += len;
+ if (src[0] != ')')
+ as_bad (_("expecting )"));
+ else
+ src++;
+ }
+ else
+ {
+ src += parse_reg (src, &mode, &(op->reg));
+ if (mode != A_REG_N)
+ {
+ as_bad (_("illegal register after @"));
+ }
+ if (src[0] == '+')
+ {
+ op->type = A_INC_N;
+ src++;
+ }
+ else
+ {
+ op->type = A_IND_N;
+ }
+ }
+ return src;
+}
+
+static void
+get_operand (ptr, op)
+ char **ptr;
+ sh_operand_info *op;
+{
+ char *src = *ptr;
+ int mode = -1;
+ unsigned int len;
+
+ if (src[0] == '#')
+ {
+ src++;
+ *ptr = parse_exp (src);
+ op->type = A_IMM;
+ return;
+ }
+
+ else if (src[0] == '@')
+ {
+ *ptr = parse_at (src, op);
+ return;
+ }
+ len = parse_reg (src, &mode, &(op->reg));
+ if (len)
+ {
+ *ptr = src + len;
+ op->type = mode;
+ return;
+ }
+ else
+ {
+ /* Not a reg, the only thing left is a displacement */
+ *ptr = parse_exp (src);
+ op->type = A_DISP_PC;
+ return;
+ }
+}
+
+static
+char *
+get_operands (info, args, operand)
+ sh_opcode_info *info;
+ char *args;
+ sh_operand_info *operand;
+
+{
+ char *ptr = args;
+ if (info->arg[0])
+ {
+ ptr++;
+
+ get_operand (&ptr, operand + 0);
+ if (info->arg[1])
+ {
+ if (*ptr == ',')
+ {
+ ptr++;
+ }
+ get_operand (&ptr, operand + 1);
+ if (info->arg[2])
+ {
+ if (*ptr == ',')
+ {
+ ptr++;
+ }
+ get_operand (&ptr, operand + 2);
+ }
+ else
+ {
+ operand[2].type = 0;
+ }
+ }
+ else
+ {
+ operand[1].type = 0;
+ operand[2].type = 0;
+ }
+ }
+ else
+ {
+ operand[0].type = 0;
+ operand[1].type = 0;
+ operand[2].type = 0;
+ }
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes, return the opcode which matches the opcodes
+ provided
+ */
+
+static
+sh_opcode_info *
+get_specific (opcode, operands)
+ sh_opcode_info *opcode;
+ sh_operand_info *operands;
+{
+ sh_opcode_info *this_try = opcode;
+ char *name = opcode->name;
+ int n = 0;
+ while (opcode->name)
+ {
+ this_try = opcode++;
+ if (this_try->name != name)
+ {
+ /* We've looked so far down the table that we've run out of
+ opcodes with the same name */
+ return 0;
+ }
+ /* look at both operands needed by the opcodes and provided by
+ the user - since an arg test will often fail on the same arg
+ again and again, we'll try and test the last failing arg the
+ first on each opcode try */
+
+ for (n = 0; this_try->arg[n]; n++)
+ {
+ sh_operand_info *user = operands + n;
+ sh_arg_type arg = this_try->arg[n];
+ switch (arg)
+ {
+ case A_IMM:
+ case A_BDISP12:
+ case A_BDISP8:
+ case A_DISP_GBR:
+ case A_DISP_PC:
+ case A_MACH:
+ case A_PR:
+ case A_MACL:
+ if (user->type != arg)
+ goto fail;
+ break;
+ case A_R0:
+ /* opcode needs r0 */
+ if (user->type != A_REG_N || user->reg != 0)
+ goto fail;
+ break;
+ case A_R0_GBR:
+ if (user->type != A_R0_GBR || user->reg != 0)
+ goto fail;
+ break;
+ case F_FR0:
+ if (user->type != F_REG_N || user->reg != 0)
+ goto fail;
+ break;
+
+ case A_REG_N:
+ case A_INC_N:
+ case A_DEC_N:
+ case A_IND_N:
+ case A_IND_R0_REG_N:
+ case A_DISP_REG_N:
+ case F_REG_N:
+ case D_REG_N:
+ case X_REG_N:
+ case V_REG_N:
+ case FPUL_N:
+ case FPSCR_N:
+ /* Opcode needs rn */
+ if (user->type != arg)
+ goto fail;
+ reg_n = user->reg;
+ break;
+ case FD_REG_N:
+ if (user->type != F_REG_N && user->type != D_REG_N)
+ goto fail;
+ reg_n = user->reg;
+ break;
+ case DX_REG_N:
+ if (user->type != D_REG_N && user->type != X_REG_N)
+ goto fail;
+ reg_n = user->reg;
+ break;
+ case A_GBR:
+ case A_SR:
+ case A_VBR:
+ case A_SSR:
+ case A_SPC:
+ case A_SGR:
+ case A_DBR:
+ if (user->type != arg)
+ goto fail;
+ break;
+
+ case A_REG_B:
+ if (user->type != arg)
+ goto fail;
+ reg_b = user->reg;
+ break;
+
+ case A_REG_M:
+ case A_INC_M:
+ case A_DEC_M:
+ case A_IND_M:
+ case A_IND_R0_REG_M:
+ case A_DISP_REG_M:
+ /* Opcode needs rn */
+ if (user->type != arg - A_REG_M + A_REG_N)
+ goto fail;
+ reg_m = user->reg;
+ break;
+
+ case F_REG_M:
+ case D_REG_M:
+ case X_REG_M:
+ case V_REG_M:
+ case FPUL_M:
+ case FPSCR_M:
+ /* Opcode needs rn */
+ if (user->type != arg - F_REG_M + F_REG_N)
+ goto fail;
+ reg_m = user->reg;
+ break;
+ case DX_REG_M:
+ if (user->type != D_REG_N && user->type != X_REG_N)
+ goto fail;
+ reg_m = user->reg;
+ break;
+ case XMTRX_M4:
+ if (user->type != XMTRX_M4)
+ goto fail;
+ reg_m = 4;
+ break;
+
+ default:
+ printf (_("unhandled %d\n"), arg);
+ goto fail;
+ }
+ }
+ return this_try;
+ fail:;
+ }
+
+ return 0;
+}
+
+int
+check (operand, low, high)
+ expressionS *operand;
+ int low;
+ int high;
+{
+ if (operand->X_op != O_constant
+ || operand->X_add_number < low
+ || operand->X_add_number > high)
+ {
+ as_bad (_("operand must be absolute in range %d..%d"), low, high);
+ }
+ return operand->X_add_number;
+}
+
+
+static void
+insert (where, how, pcrel)
+ char *where;
+ int how;
+ int pcrel;
+{
+ fix_new_exp (frag_now,
+ where - frag_now->fr_literal,
+ 2,
+ &immediate,
+ pcrel,
+ how);
+}
+
+static void
+build_relax (opcode)
+ sh_opcode_info *opcode;
+{
+ int high_byte = target_big_endian ? 0 : 1;
+ char *p;
+
+ if (opcode->arg[0] == A_BDISP8)
+ {
+ int what = (opcode->nibbles[1] & 4) ? COND_JUMP_DELAY : COND_JUMP;
+ p = frag_var (rs_machine_dependent,
+ md_relax_table[C (what, COND32)].rlx_length,
+ md_relax_table[C (what, COND8)].rlx_length,
+ C (what, 0),
+ immediate.X_add_symbol,
+ immediate.X_add_number,
+ 0);
+ p[high_byte] = (opcode->nibbles[0] << 4) | (opcode->nibbles[1]);
+ }
+ else if (opcode->arg[0] == A_BDISP12)
+ {
+ p = frag_var (rs_machine_dependent,
+ md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length,
+ md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length,
+ C (UNCOND_JUMP, 0),
+ immediate.X_add_symbol,
+ immediate.X_add_number,
+ 0);
+ p[high_byte] = (opcode->nibbles[0] << 4);
+ }
+
+}
+
+/* Now we know what sort of opcodes it is, lets build the bytes -
+ */
+static void
+build_Mytes (opcode, operand)
+ sh_opcode_info *opcode;
+ sh_operand_info *operand;
+
+{
+ int index;
+ char nbuf[4];
+ char *output = frag_more (2);
+ int low_byte = target_big_endian ? 1 : 0;
+ nbuf[0] = 0;
+ nbuf[1] = 0;
+ nbuf[2] = 0;
+ nbuf[3] = 0;
+
+ for (index = 0; index < 4; index++)
+ {
+ sh_nibble_type i = opcode->nibbles[index];
+ if (i < 16)
+ {
+ nbuf[index] = i;
+ }
+ else
+ {
+ switch (i)
+ {
+ case REG_N:
+ nbuf[index] = reg_n;
+ break;
+ case REG_M:
+ nbuf[index] = reg_m;
+ break;
+ case REG_NM:
+ nbuf[index] = reg_n | (reg_m >> 2);
+ break;
+ case REG_B:
+ nbuf[index] = reg_b | 0x08;
+ break;
+ case DISP_4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4, 0);
+ break;
+ case IMM_4BY4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4BY4, 0);
+ break;
+ case IMM_4BY2:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4BY2, 0);
+ break;
+ case IMM_4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM4, 0);
+ break;
+ case IMM_8BY4:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8BY4, 0);
+ break;
+ case IMM_8BY2:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8BY2, 0);
+ break;
+ case IMM_8:
+ insert (output + low_byte, BFD_RELOC_SH_IMM8, 0);
+ break;
+ case PCRELIMM_8BY4:
+ insert (output, BFD_RELOC_SH_PCRELIMM8BY4, 1);
+ break;
+ case PCRELIMM_8BY2:
+ insert (output, BFD_RELOC_SH_PCRELIMM8BY2, 1);
+ break;
+ default:
+ printf (_("failed for %d\n"), i);
+ }
+ }
+ }
+ if (! target_big_endian) {
+ output[1] = (nbuf[0] << 4) | (nbuf[1]);
+ output[0] = (nbuf[2] << 4) | (nbuf[3]);
+ }
+ else {
+ output[0] = (nbuf[0] << 4) | (nbuf[1]);
+ output[1] = (nbuf[2] << 4) | (nbuf[3]);
+ }
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to.
+ */
+
+void
+md_assemble (str)
+ char *str;
+{
+ unsigned char *op_start;
+ unsigned char *op_end;
+ sh_operand_info operand[3];
+ sh_opcode_info *opcode;
+ char name[20];
+ int nlen = 0;
+ /* Drop leading whitespace */
+ while (*str == ' ')
+ str++;
+
+ /* find the op code end */
+ for (op_start = op_end = (unsigned char *) (str);
+ *op_end
+ && nlen < 20
+ && !is_end_of_line[*op_end] && *op_end != ' ';
+ op_end++)
+ {
+ unsigned char c = op_start[nlen];
+
+ /* The machine independent code will convert CMP/EQ into cmp/EQ
+ because it thinks the '/' is the end of the symbol. Instead of
+ hacking up the machine independent code, we just deal with it
+ here. */
+ c = isupper (c) ? tolower (c) : c;
+ name[nlen] = c;
+ nlen++;
+ }
+ name[nlen] = 0;
+
+ if (nlen == 0)
+ {
+ as_bad (_("can't find opcode "));
+ }
+
+ opcode = (sh_opcode_info *) hash_find (opcode_hash_control, name);
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ if (sh_relax
+ && ! seg_info (now_seg)->tc_segment_info_data.in_code)
+ {
+ /* Output a CODE reloc to tell the linker that the following
+ bytes are instructions, not data. */
+ fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0,
+ BFD_RELOC_SH_CODE);
+ seg_info (now_seg)->tc_segment_info_data.in_code = 1;
+ }
+
+ if (opcode->arg[0] == A_BDISP12
+ || opcode->arg[0] == A_BDISP8)
+ {
+ parse_exp (op_end + 1);
+ build_relax (opcode);
+ }
+ else
+ {
+ if (opcode->arg[0] != A_END)
+ {
+ get_operands (opcode, op_end, operand);
+ }
+ opcode = get_specific (opcode, operand);
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands */
+ char *where = frag_more (2);
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+ as_bad (_("invalid operands for opcode"));
+ return;
+ }
+
+ build_Mytes (opcode, operand);
+ }
+
+}
+
+/* This routine is called each time a label definition is seen. It
+ emits a BFD_RELOC_SH_LABEL reloc if necessary. */
+
+void
+sh_frob_label ()
+{
+ static fragS *last_label_frag;
+ static int last_label_offset;
+
+ if (sh_relax
+ && seg_info (now_seg)->tc_segment_info_data.in_code)
+ {
+ int offset;
+
+ offset = frag_now_fix ();
+ if (frag_now != last_label_frag
+ || offset != last_label_offset)
+ {
+ fix_new (frag_now, offset, 2, &abs_symbol, 0, 0, BFD_RELOC_SH_LABEL);
+ last_label_frag = frag_now;
+ last_label_offset = offset;
+ }
+ }
+}
+
+/* This routine is called when the assembler is about to output some
+ data. It emits a BFD_RELOC_SH_DATA reloc if necessary. */
+
+void
+sh_flush_pending_output ()
+{
+ if (sh_relax
+ && seg_info (now_seg)->tc_segment_info_data.in_code)
+ {
+ fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0,
+ BFD_RELOC_SH_DATA);
+ seg_info (now_seg)->tc_segment_info_data.in_code = 0;
+ }
+}
+
+symbolS *
+DEFUN (md_undefined_symbol, (name),
+ char *name)
+{
+ return 0;
+}
+
+#ifdef OBJ_COFF
+
+void
+DEFUN (tc_crawl_symbol_chain, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+void
+DEFUN (tc_headers_hook, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+#endif
+
+/* Various routines to kill one day */
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char *t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * 2;
+
+ if (! target_big_endian)
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+ else
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+
+ return NULL;
+}
+
+/* Handle the .uses pseudo-op. This pseudo-op is used just before a
+ call instruction. It refers to a label of the instruction which
+ loads the register which the call uses. We use it to generate a
+ special reloc for the linker. */
+
+static void
+s_uses (ignore)
+ int ignore;
+{
+ expressionS ex;
+
+ if (! sh_relax)
+ as_warn (_(".uses pseudo-op seen when not relaxing"));
+
+ expression (&ex);
+
+ if (ex.X_op != O_symbol || ex.X_add_number != 0)
+ {
+ as_bad (_("bad .uses format"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ fix_new_exp (frag_now, frag_now_fix (), 2, &ex, 1, BFD_RELOC_SH_USES);
+
+ demand_empty_rest_of_line ();
+}
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+
+#define OPTION_RELAX (OPTION_MD_BASE)
+#define OPTION_LITTLE (OPTION_MD_BASE + 1)
+#define OPTION_SMALL (OPTION_LITTLE + 1)
+
+ {"relax", no_argument, NULL, OPTION_RELAX},
+ {"little", no_argument, NULL, OPTION_LITTLE},
+ {"small", no_argument, NULL, OPTION_SMALL},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case OPTION_RELAX:
+ sh_relax = 1;
+ break;
+
+ case OPTION_LITTLE:
+ shl = 1;
+ target_big_endian = 0;
+ break;
+
+ case OPTION_SMALL:
+ sh_small = 1;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+SH options:\n\
+-little generate little endian code\n\
+-relax alter jump instructions for long displacements\n\
+-small align sections to 4 byte boundaries, not 16\n"));
+}
+
+void
+tc_Nout_fix_to_chars ()
+{
+ printf (_("call to tc_Nout_fix_to_chars \n"));
+ abort ();
+}
+
+/* This struct is used to pass arguments to sh_count_relocs through
+ bfd_map_over_sections. */
+
+struct sh_count_relocs
+{
+ /* Symbol we are looking for. */
+ symbolS *sym;
+ /* Count of relocs found. */
+ int count;
+};
+
+/* Count the number of fixups in a section which refer to a particular
+ symbol. When using BFD_ASSEMBLER, this is called via
+ bfd_map_over_sections. */
+
+/*ARGSUSED*/
+static void
+sh_count_relocs (abfd, sec, data)
+ bfd *abfd;
+ segT sec;
+ PTR data;
+{
+ struct sh_count_relocs *info = (struct sh_count_relocs *) data;
+ segment_info_type *seginfo;
+ symbolS *sym;
+ fixS *fix;
+
+ seginfo = seg_info (sec);
+ if (seginfo == NULL)
+ return;
+
+ sym = info->sym;
+ for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next)
+ {
+ if (fix->fx_addsy == sym)
+ {
+ ++info->count;
+ fix->fx_tcbit = 1;
+ }
+ }
+}
+
+/* Handle the count relocs for a particular section. When using
+ BFD_ASSEMBLER, this is called via bfd_map_over_sections. */
+
+/*ARGSUSED*/
+static void
+sh_frob_section (abfd, sec, ignore)
+ bfd *abfd;
+ segT sec;
+ PTR ignore;
+{
+ segment_info_type *seginfo;
+ fixS *fix;
+
+ seginfo = seg_info (sec);
+ if (seginfo == NULL)
+ return;
+
+ for (fix = seginfo->fix_root; fix != NULL; fix = fix->fx_next)
+ {
+ symbolS *sym;
+ bfd_vma val;
+ fixS *fscan;
+ struct sh_count_relocs info;
+
+ if (fix->fx_r_type != BFD_RELOC_SH_USES)
+ continue;
+
+ /* The BFD_RELOC_SH_USES reloc should refer to a defined local
+ symbol in the same section. */
+ sym = fix->fx_addsy;
+ if (sym == NULL
+ || fix->fx_subsy != NULL
+ || fix->fx_addnumber != 0
+ || S_GET_SEGMENT (sym) != sec
+#if ! defined (BFD_ASSEMBLER) && defined (OBJ_COFF)
+ || S_GET_STORAGE_CLASS (sym) == C_EXT
+#endif
+ || S_IS_EXTERNAL (sym))
+ {
+ as_warn_where (fix->fx_file, fix->fx_line,
+ _(".uses does not refer to a local symbol in the same section"));
+ continue;
+ }
+
+ /* Look through the fixups again, this time looking for one
+ at the same location as sym. */
+ val = S_GET_VALUE (sym);
+ for (fscan = seginfo->fix_root;
+ fscan != NULL;
+ fscan = fscan->fx_next)
+ if (val == fscan->fx_frag->fr_address + fscan->fx_where
+ && fscan->fx_r_type != BFD_RELOC_SH_ALIGN
+ && fscan->fx_r_type != BFD_RELOC_SH_CODE
+ && fscan->fx_r_type != BFD_RELOC_SH_DATA
+ && fscan->fx_r_type != BFD_RELOC_SH_LABEL)
+ break;
+ if (fscan == NULL)
+ {
+ as_warn_where (fix->fx_file, fix->fx_line,
+ _("can't find fixup pointed to by .uses"));
+ continue;
+ }
+
+ if (fscan->fx_tcbit)
+ {
+ /* We've already done this one. */
+ continue;
+ }
+
+ /* fscan should also be a fixup to a local symbol in the same
+ section. */
+ sym = fscan->fx_addsy;
+ if (sym == NULL
+ || fscan->fx_subsy != NULL
+ || fscan->fx_addnumber != 0
+ || S_GET_SEGMENT (sym) != sec
+#if ! defined (BFD_ASSEMBLER) && defined (OBJ_COFF)
+ || S_GET_STORAGE_CLASS (sym) == C_EXT
+#endif
+ || S_IS_EXTERNAL (sym))
+ {
+ as_warn_where (fix->fx_file, fix->fx_line,
+ _(".uses target does not refer to a local symbol in the same section"));
+ continue;
+ }
+
+ /* Now we look through all the fixups of all the sections,
+ counting the number of times we find a reference to sym. */
+ info.sym = sym;
+ info.count = 0;
+#ifdef BFD_ASSEMBLER
+ bfd_map_over_sections (stdoutput, sh_count_relocs, (PTR) &info);
+#else
+ {
+ int iscan;
+
+ for (iscan = SEG_E0; iscan < SEG_UNKNOWN; iscan++)
+ sh_count_relocs ((bfd *) NULL, iscan, (PTR) &info);
+ }
+#endif
+
+ if (info.count < 1)
+ abort ();
+
+ /* Generate a BFD_RELOC_SH_COUNT fixup at the location of sym.
+ We have already adjusted the value of sym to include the
+ fragment address, so we undo that adjustment here. */
+ subseg_change (sec, 0);
+ fix_new (sym->sy_frag, S_GET_VALUE (sym) - sym->sy_frag->fr_address,
+ 4, &abs_symbol, info.count, 0, BFD_RELOC_SH_COUNT);
+ }
+}
+
+/* This function is called after the symbol table has been completed,
+ but before the relocs or section contents have been written out.
+ If we have seen any .uses pseudo-ops, they point to an instruction
+ which loads a register with the address of a function. We look
+ through the fixups to find where the function address is being
+ loaded from. We then generate a COUNT reloc giving the number of
+ times that function address is referred to. The linker uses this
+ information when doing relaxing, to decide when it can eliminate
+ the stored function address entirely. */
+
+void
+sh_frob_file ()
+{
+ if (! sh_relax)
+ return;
+
+#ifdef BFD_ASSEMBLER
+ bfd_map_over_sections (stdoutput, sh_frob_section, (PTR) NULL);
+#else
+ {
+ int iseg;
+
+ for (iseg = SEG_E0; iseg < SEG_UNKNOWN; iseg++)
+ sh_frob_section ((bfd *) NULL, iseg, (PTR) NULL);
+ }
+#endif
+}
+
+/* Called after relaxing. Set the correct sizes of the fragments, and
+ create relocs so that md_apply_fix will fill in the correct values. */
+
+void
+md_convert_frag (headers, seg, fragP)
+#ifdef BFD_ASSEMBLER
+ bfd *headers;
+#else
+ object_headers *headers;
+#endif
+ segT seg;
+ fragS *fragP;
+{
+ int donerelax = 0;
+
+ switch (fragP->fr_subtype)
+ {
+ case C (COND_JUMP, COND8):
+ case C (COND_JUMP_DELAY, COND8):
+ subseg_change (seg, 0);
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
+ 1, BFD_RELOC_SH_PCDISP8BY2);
+ fragP->fr_fix += 2;
+ fragP->fr_var = 0;
+ break;
+
+ case C (UNCOND_JUMP, UNCOND12):
+ subseg_change (seg, 0);
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, fragP->fr_offset,
+ 1, BFD_RELOC_SH_PCDISP12BY2);
+ fragP->fr_fix += 2;
+ fragP->fr_var = 0;
+ break;
+
+ case C (UNCOND_JUMP, UNCOND32):
+ case C (UNCOND_JUMP, UNDEF_WORD_DISP):
+ if (fragP->fr_symbol == NULL)
+ as_bad (_("at 0x%lx, displacement overflows 12-bit field"),
+ (unsigned long) fragP->fr_address);
+ else if (S_IS_DEFINED (fragP->fr_symbol))
+ as_bad (_("at 0x%lx, displacement to defined symbol %s overflows 12-bit field"),
+ (unsigned long) fragP->fr_address,
+ S_GET_NAME (fragP->fr_symbol));
+ else
+ as_bad (_("at 0x%lx, displacement to undefined symbol %s overflows 12-bit field"),
+ (unsigned long) fragP->fr_address,
+ S_GET_NAME (fragP->fr_symbol));
+
+#if 0 /* This code works, but generates poor code and the compiler
+ should never produce a sequence that requires it to be used. */
+
+ /* A jump wont fit in 12 bits, make code which looks like
+ bra foo
+ mov.w @(0, PC), r14
+ .long disp
+ foo: bra @r14
+ */
+ int t = buffer[0] & 0x10;
+
+ buffer[highbyte] = 0xa0; /* branch over move and disp */
+ buffer[lowbyte] = 3;
+ buffer[highbyte+2] = 0xd0 | JREG; /* Build mov insn */
+ buffer[lowbyte+2] = 0x00;
+
+ buffer[highbyte+4] = 0; /* space for 32 bit jump disp */
+ buffer[lowbyte+4] = 0;
+ buffer[highbyte+6] = 0;
+ buffer[lowbyte+6] = 0;
+
+ buffer[highbyte+8] = 0x40 | JREG; /* Build jmp @JREG */
+ buffer[lowbyte+8] = t ? 0xb : 0x2b;
+
+ buffer[highbyte+10] = 0x20; /* build nop */
+ buffer[lowbyte+10] = 0x0b;
+
+ /* Make reloc for the long disp */
+ fix_new (fragP,
+ fragP->fr_fix + 4,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 0,
+ BFD_RELOC_32);
+ fragP->fr_fix += UNCOND32_LENGTH;
+ fragP->fr_var = 0;
+ donerelax = 1;
+#endif
+
+ break;
+
+ case C (COND_JUMP, COND12):
+ case C (COND_JUMP_DELAY, COND12):
+ /* A bcond won't fit, so turn it into a b!cond; bra disp; nop */
+ /* I found that a relax failure for gcc.c-torture/execute/930628-1.c
+ was due to gas incorrectly relaxing an out-of-range conditional
+ branch with delay slot. It turned:
+ bf.s L6 (slot mov.l r12,@(44,r0))
+ into:
+
+2c: 8f 01 a0 8b bf.s 32 <_main+32> (slot bra L6)
+30: 00 09 nop
+32: 10 cb mov.l r12,@(44,r0)
+ Therefore, branches with delay slots have to be handled
+ differently from ones without delay slots. */
+ {
+ unsigned char *buffer =
+ (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+ int highbyte = target_big_endian ? 0 : 1;
+ int lowbyte = target_big_endian ? 1 : 0;
+ int delay = fragP->fr_subtype == C (COND_JUMP_DELAY, COND12);
+
+ /* Toggle the true/false bit of the bcond. */
+ buffer[highbyte] ^= 0x2;
+
+ /* If this is a dalayed branch, we may not put the the bra in the
+ slot. So we change it to a non-delayed branch, like that:
+ b! cond slot_label; bra disp; slot_label: slot_insn
+ ??? We should try if swapping the conditional branch and
+ its delay-slot insn already makes the branch reach. */
+
+ /* Build a relocation to six / four bytes farther on. */
+ subseg_change (seg, 0);
+ fix_new (fragP, fragP->fr_fix, 2,
+#ifdef BFD_ASSEMBLER
+ section_symbol (seg),
+#else
+ seg_info (seg)->dot,
+#endif
+ fragP->fr_address + fragP->fr_fix + (delay ? 4 : 6),
+ 1, BFD_RELOC_SH_PCDISP8BY2);
+
+ /* Set up a jump instruction. */
+ buffer[highbyte + 2] = 0xa0;
+ buffer[lowbyte + 2] = 0;
+ fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_SH_PCDISP12BY2);
+
+ if (delay)
+ {
+ buffer[highbyte] &= ~0x4; /* Removes delay slot from branch. */
+ fragP->fr_fix += 4;
+ }
+ else
+ {
+ /* Fill in a NOP instruction. */
+ buffer[highbyte + 4] = 0x0;
+ buffer[lowbyte + 4] = 0x9;
+
+ fragP->fr_fix += 6;
+ }
+ fragP->fr_var = 0;
+ donerelax = 1;
+ }
+ break;
+
+ case C (COND_JUMP, COND32):
+ case C (COND_JUMP_DELAY, COND32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ case C (COND_JUMP_DELAY, UNDEF_WORD_DISP):
+ if (fragP->fr_symbol == NULL)
+ as_bad (_("at 0x%lx, displacement overflows 8-bit field"),
+ (unsigned long) fragP->fr_address);
+ else if (S_IS_DEFINED (fragP->fr_symbol))
+ as_bad (_("at 0x%lx, displacement to defined symbol %s overflows 8-bit field "),
+ (unsigned long) fragP->fr_address,
+ S_GET_NAME (fragP->fr_symbol));
+ else
+ as_bad (_("at 0x%lx, displacement to undefined symbol %s overflows 8-bit field "),
+ (unsigned long) fragP->fr_address,
+ S_GET_NAME (fragP->fr_symbol));
+
+#if 0 /* This code works, but generates poor code, and the compiler
+ should never produce a sequence that requires it to be used. */
+
+ /* A bcond won't fit and it won't go into a 12 bit
+ displacement either, the code sequence looks like:
+ b!cond foop
+ mov.w @(n, PC), r14
+ jmp @r14
+ nop
+ .long where
+ foop:
+ */
+
+ buffer[0] ^= 0x2; /* Toggle T/F bit */
+#define JREG 14
+ buffer[1] = 5; /* branch over mov, jump, nop and ptr */
+ buffer[2] = 0xd0 | JREG; /* Build mov insn */
+ buffer[3] = 0x2;
+ buffer[4] = 0x40 | JREG; /* Build jmp @JREG */
+ buffer[5] = 0x0b;
+ buffer[6] = 0x20; /* build nop */
+ buffer[7] = 0x0b;
+ buffer[8] = 0; /* space for 32 bit jump disp */
+ buffer[9] = 0;
+ buffer[10] = 0;
+ buffer[11] = 0;
+ buffer[12] = 0;
+ buffer[13] = 0;
+ /* Make reloc for the long disp */
+ fix_new (fragP,
+ fragP->fr_fix + 8,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 0,
+ BFD_RELOC_32);
+ fragP->fr_fix += COND32_LENGTH;
+ fragP->fr_var = 0;
+ donerelax = 1;
+#endif
+
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (donerelax && !sh_relax)
+ as_warn_where (fragP->fr_file, fragP->fr_line,
+ _("overflow in branch to %s; converted into longer instruction sequence"),
+ (fragP->fr_symbol != NULL
+ ? S_GET_NAME (fragP->fr_symbol)
+ : ""));
+}
+
+valueT
+DEFUN (md_section_align, (seg, size),
+ segT seg AND
+ valueT size)
+{
+#ifdef BFD_ASSEMBLER
+#ifdef OBJ_ELF
+ return size;
+#else /* ! OBJ_ELF */
+ return ((size + (1 << bfd_get_section_alignment (stdoutput, seg)) - 1)
+ & (-1 << bfd_get_section_alignment (stdoutput, seg)));
+#endif /* ! OBJ_ELF */
+#else /* ! BFD_ASSEMBLER */
+ return ((size + (1 << section_alignment[(int) seg]) - 1)
+ & (-1 << section_alignment[(int) seg]));
+#endif /* ! BFD_ASSEMBLER */
+}
+
+/* This static variable is set by s_uacons to tell sh_cons_align that
+ the expession does not need to be aligned. */
+
+static int sh_no_align_cons = 0;
+
+/* This handles the unaligned space allocation pseudo-ops, such as
+ .uaword. .uaword is just like .word, but the value does not need
+ to be aligned. */
+
+static void
+s_uacons (bytes)
+ int bytes;
+{
+ /* Tell sh_cons_align not to align this value. */
+ sh_no_align_cons = 1;
+ cons (bytes);
+}
+
+/* If a .word, et. al., pseud-op is seen, warn if the value is not
+ aligned correctly. Note that this can cause warnings to be issued
+ when assembling initialized structured which were declared with the
+ packed attribute. FIXME: Perhaps we should require an option to
+ enable this warning? */
+
+void
+sh_cons_align (nbytes)
+ int nbytes;
+{
+ int nalign;
+ char *p;
+
+ if (sh_no_align_cons)
+ {
+ /* This is an unaligned pseudo-op. */
+ sh_no_align_cons = 0;
+ return;
+ }
+
+ nalign = 0;
+ while ((nbytes & 1) == 0)
+ {
+ ++nalign;
+ nbytes >>= 1;
+ }
+
+ if (nalign == 0)
+ return;
+
+ if (now_seg == absolute_section)
+ {
+ if ((abs_section_offset & ((1 << nalign) - 1)) != 0)
+ as_warn (_("misaligned data"));
+ return;
+ }
+
+ p = frag_var (rs_align_code, 1, 1, (relax_substateT) 0,
+ (symbolS *) NULL, (offsetT) nalign, (char *) NULL);
+
+ record_alignment (now_seg, nalign);
+}
+
+/* When relaxing, we need to output a reloc for any .align directive
+ that requests alignment to a four byte boundary or larger. This is
+ also where we check for misaligned data. */
+
+void
+sh_handle_align (frag)
+ fragS *frag;
+{
+ if (sh_relax
+ && frag->fr_type == rs_align
+ && frag->fr_address + frag->fr_fix > 0
+ && frag->fr_offset > 1
+ && now_seg != bss_section)
+ fix_new (frag, frag->fr_fix, 2, &abs_symbol, frag->fr_offset, 0,
+ BFD_RELOC_SH_ALIGN);
+
+ if (frag->fr_type == rs_align_code
+ && frag->fr_next->fr_address - frag->fr_address - frag->fr_fix != 0)
+ as_warn_where (frag->fr_file, frag->fr_line, _("misaligned data"));
+}
+
+/* This macro decides whether a particular reloc is an entry in a
+ switch table. It is used when relaxing, because the linker needs
+ to know about all such entries so that it can adjust them if
+ necessary. */
+
+#ifdef BFD_ASSEMBLER
+#define SWITCH_TABLE_CONS(fix) (0)
+#else
+#define SWITCH_TABLE_CONS(fix) \
+ ((fix)->fx_r_type == 0 \
+ && ((fix)->fx_size == 2 \
+ || (fix)->fx_size == 1 \
+ || (fix)->fx_size == 4))
+#endif
+
+#define SWITCH_TABLE(fix) \
+ ((fix)->fx_addsy != NULL \
+ && (fix)->fx_subsy != NULL \
+ && S_GET_SEGMENT ((fix)->fx_addsy) == text_section \
+ && S_GET_SEGMENT ((fix)->fx_subsy) == text_section \
+ && ((fix)->fx_r_type == BFD_RELOC_32 \
+ || (fix)->fx_r_type == BFD_RELOC_16 \
+ || (fix)->fx_r_type == BFD_RELOC_8 \
+ || SWITCH_TABLE_CONS (fix)))
+
+/* See whether we need to force a relocation into the output file.
+ This is used to force out switch and PC relative relocations when
+ relaxing. */
+
+int
+sh_force_relocation (fix)
+ fixS *fix;
+{
+
+ if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ if (! sh_relax)
+ return 0;
+
+ return (fix->fx_pcrel
+ || SWITCH_TABLE (fix)
+ || fix->fx_r_type == BFD_RELOC_SH_COUNT
+ || fix->fx_r_type == BFD_RELOC_SH_ALIGN
+ || fix->fx_r_type == BFD_RELOC_SH_CODE
+ || fix->fx_r_type == BFD_RELOC_SH_DATA
+ || fix->fx_r_type == BFD_RELOC_SH_LABEL);
+}
+
+#ifdef OBJ_ELF
+boolean
+sh_fix_adjustable (fixP)
+ fixS *fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+#endif
+
+/* Apply a fixup to the object file. */
+
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ valueT *valp;
+#else
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+#endif
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ int lowbyte = target_big_endian ? 1 : 0;
+ int highbyte = target_big_endian ? 0 : 1;
+#ifdef BFD_ASSEMBLER
+ long val = *valp;
+#endif
+ long max, min;
+ int shift;
+
+#ifdef BFD_ASSEMBLER
+ /* adjust_reloc_syms won't convert a reloc against a weak symbol
+ into a reloc against a section, but bfd_install_relocation will
+ screw up if the symbol is defined, so we have to adjust val here
+ to avoid the screw up later. */
+ if (fixP->fx_addsy != NULL
+ && S_IS_WEAK (fixP->fx_addsy))
+ val -= S_GET_VALUE (fixP->fx_addsy);
+#endif
+
+#ifndef BFD_ASSEMBLER
+ if (fixP->fx_r_type == 0)
+ {
+ if (fixP->fx_size == 2)
+ fixP->fx_r_type = BFD_RELOC_16;
+ else if (fixP->fx_size == 4)
+ fixP->fx_r_type = BFD_RELOC_32;
+ else if (fixP->fx_size == 1)
+ fixP->fx_r_type = BFD_RELOC_8;
+ else
+ abort ();
+ }
+#endif
+
+ max = min = 0;
+ shift = 0;
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_SH_IMM4:
+ max = 0xf;
+ *buf = (*buf & 0xf0) | (val & 0xf);
+ break;
+
+ case BFD_RELOC_SH_IMM4BY2:
+ max = 0xf;
+ shift = 1;
+ *buf = (*buf & 0xf0) | ((val >> 1) & 0xf);
+ break;
+
+ case BFD_RELOC_SH_IMM4BY4:
+ max = 0xf;
+ shift = 2;
+ *buf = (*buf & 0xf0) | ((val >> 2) & 0xf);
+ break;
+
+ case BFD_RELOC_SH_IMM8BY2:
+ max = 0xff;
+ shift = 1;
+ *buf = val >> 1;
+ break;
+
+ case BFD_RELOC_SH_IMM8BY4:
+ max = 0xff;
+ shift = 2;
+ *buf = val >> 2;
+ break;
+
+ case BFD_RELOC_8:
+ case BFD_RELOC_SH_IMM8:
+ /* Sometimes the 8 bit value is sign extended (e.g., add) and
+ sometimes it is not (e.g., and). We permit any 8 bit value.
+ Note that adding further restrictions may invalidate
+ reasonable looking assembly code, such as ``and -0x1,r0''. */
+ max = 0xff;
+ min = - 0xff;
+ *buf++ = val;
+ break;
+
+ case BFD_RELOC_SH_PCRELIMM8BY4:
+ /* The lower two bits of the PC are cleared before the
+ displacement is added in. We can assume that the destination
+ is on a 4 byte bounday. If this instruction is also on a 4
+ byte boundary, then we want
+ (target - here) / 4
+ and target - here is a multiple of 4.
+ Otherwise, we are on a 2 byte boundary, and we want
+ (target - (here - 2)) / 4
+ and target - here is not a multiple of 4. Computing
+ (target - (here - 2)) / 4 == (target - here + 2) / 4
+ works for both cases, since in the first case the addition of
+ 2 will be removed by the division. target - here is in the
+ variable val. */
+ val = (val + 2) / 4;
+ if (val & ~0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val;
+ break;
+
+ case BFD_RELOC_SH_PCRELIMM8BY2:
+ val /= 2;
+ if (val & ~0xff)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val;
+ break;
+
+ case BFD_RELOC_SH_PCDISP8BY2:
+ val /= 2;
+ if (val < -0x80 || val > 0x7f)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val;
+ break;
+
+ case BFD_RELOC_SH_PCDISP12BY2:
+ val /= 2;
+ if (val < -0x800 || val >= 0x7ff)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
+ buf[lowbyte] = val & 0xff;
+ buf[highbyte] |= (val >> 8) & 0xf;
+ break;
+
+ case BFD_RELOC_32:
+ if (! target_big_endian)
+ {
+ *buf++ = val >> 0;
+ *buf++ = val >> 8;
+ *buf++ = val >> 16;
+ *buf++ = val >> 24;
+ }
+ else
+ {
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ *buf++ = val >> 8;
+ *buf++ = val >> 0;
+ }
+ break;
+
+ case BFD_RELOC_16:
+ if (! target_big_endian)
+ {
+ *buf++ = val >> 0;
+ *buf++ = val >> 8;
+ }
+ else
+ {
+ *buf++ = val >> 8;
+ *buf++ = val >> 0;
+ }
+ break;
+
+ case BFD_RELOC_SH_USES:
+ /* Pass the value into sh_coff_reloc_mangle. */
+ fixP->fx_addnumber = val;
+ break;
+
+ case BFD_RELOC_SH_COUNT:
+ case BFD_RELOC_SH_ALIGN:
+ case BFD_RELOC_SH_CODE:
+ case BFD_RELOC_SH_DATA:
+ case BFD_RELOC_SH_LABEL:
+ /* Nothing to do here. */
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ return;
+
+ default:
+ abort ();
+ }
+
+ if (shift != 0)
+ {
+ if ((val & ((1 << shift) - 1)) != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("misaligned offset"));
+ if (val >= 0)
+ val >>= shift;
+ else
+ val = ((val >> shift)
+ | ((long) -1 & ~ ((long) -1 >> shift)));
+ }
+ if (max != 0 && (val < min || val > max))
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
+
+#ifdef BFD_ASSEMBLER
+ return 0;
+#endif
+}
+
+/* Called just before address relaxation. Return the length
+ by which a fragment must grow to reach it's destination. */
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ switch (fragP->fr_subtype)
+ {
+ case C (UNCOND_JUMP, UNDEF_DISP):
+ /* used to be a branch to somewhere which was unknown */
+ if (!fragP->fr_symbol)
+ {
+ fragP->fr_subtype = C (UNCOND_JUMP, UNCOND12);
+ fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length;
+ }
+ else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype = C (UNCOND_JUMP, UNCOND12);
+ fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length;
+ }
+ else
+ {
+ fragP->fr_subtype = C (UNCOND_JUMP, UNDEF_WORD_DISP);
+ fragP->fr_var = md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length;
+ return md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length;
+ }
+ break;
+
+ default:
+ abort ();
+ case C (COND_JUMP, UNDEF_DISP):
+ case C (COND_JUMP_DELAY, UNDEF_DISP):
+ /* used to be a branch to somewhere which was unknown */
+ if (fragP->fr_symbol
+ && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ int what = GET_WHAT (fragP->fr_subtype);
+ /* Got a symbol and it's defined in this segment, become byte
+ sized - maybe it will fix up */
+ fragP->fr_subtype = C (what, COND8);
+ fragP->fr_var = md_relax_table[C (what, COND8)].rlx_length;
+ }
+ else if (fragP->fr_symbol)
+ {
+ int what = GET_WHAT (fragP->fr_subtype);
+ /* Its got a segment, but its not ours, so it will always be long */
+ fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
+ fragP->fr_var = md_relax_table[C (what, COND32)].rlx_length;
+ return md_relax_table[C (what, COND32)].rlx_length;
+ }
+ else
+ {
+ int what = GET_WHAT (fragP->fr_subtype);
+ /* We know the abs value */
+ fragP->fr_subtype = C (what, COND8);
+ fragP->fr_var = md_relax_table[C (what, COND8)].rlx_length;
+ }
+
+ break;
+ }
+ return fragP->fr_var;
+}
+
+/* Put number into target byte order */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char *ptr;
+ valueT use;
+ int nbytes;
+{
+ if (! target_big_endian)
+ number_to_chars_littleendian (ptr, use, nbytes);
+ else
+ number_to_chars_bigendian (ptr, use, nbytes);
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address + 2;
+}
+
+#ifdef OBJ_COFF
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ return md_relax_table[frag->fr_subtype].rlx_length;
+}
+
+#endif /* OBJ_COFF */
+
+/* When we align the .text section, insert the correct NOP pattern. */
+
+int
+sh_do_align (n, fill, len, max)
+ int n;
+ const char *fill;
+ int len;
+ int max;
+{
+ if (fill == NULL
+#ifdef BFD_ASSEMBLER
+ && (now_seg->flags & SEC_CODE) != 0
+#else
+ && now_seg != data_section
+ && now_seg != bss_section
+#endif
+ && n > 1)
+ {
+ static const unsigned char big_nop_pattern[] = { 0x00, 0x09 };
+ static const unsigned char little_nop_pattern[] = { 0x09, 0x00 };
+
+ /* First align to a 2 byte boundary, in case there is an odd
+ .byte. */
+ frag_align (1, 0, 0);
+ if (target_big_endian)
+ frag_align_pattern (n, big_nop_pattern, sizeof big_nop_pattern, max);
+ else
+ frag_align_pattern (n, little_nop_pattern, sizeof little_nop_pattern,
+ max);
+ return 1;
+ }
+
+ return 0;
+}
+
+#ifndef BFD_ASSEMBLER
+#ifdef OBJ_COFF
+
+/* Map BFD relocs to SH COFF relocs. */
+
+struct reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc;
+ int sh_reloc;
+};
+
+static const struct reloc_map coff_reloc_map[] =
+{
+ { BFD_RELOC_32, R_SH_IMM32 },
+ { BFD_RELOC_16, R_SH_IMM16 },
+ { BFD_RELOC_8, R_SH_IMM8 },
+ { BFD_RELOC_SH_PCDISP8BY2, R_SH_PCDISP8BY2 },
+ { BFD_RELOC_SH_PCDISP12BY2, R_SH_PCDISP },
+ { BFD_RELOC_SH_IMM4, R_SH_IMM4 },
+ { BFD_RELOC_SH_IMM4BY2, R_SH_IMM4BY2 },
+ { BFD_RELOC_SH_IMM4BY4, R_SH_IMM4BY4 },
+ { BFD_RELOC_SH_IMM8, R_SH_IMM8 },
+ { BFD_RELOC_SH_IMM8BY2, R_SH_IMM8BY2 },
+ { BFD_RELOC_SH_IMM8BY4, R_SH_IMM8BY4 },
+ { BFD_RELOC_SH_PCRELIMM8BY2, R_SH_PCRELIMM8BY2 },
+ { BFD_RELOC_SH_PCRELIMM8BY4, R_SH_PCRELIMM8BY4 },
+ { BFD_RELOC_8_PCREL, R_SH_SWITCH8 },
+ { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
+ { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
+ { BFD_RELOC_SH_USES, R_SH_USES },
+ { BFD_RELOC_SH_COUNT, R_SH_COUNT },
+ { BFD_RELOC_SH_ALIGN, R_SH_ALIGN },
+ { BFD_RELOC_SH_CODE, R_SH_CODE },
+ { BFD_RELOC_SH_DATA, R_SH_DATA },
+ { BFD_RELOC_SH_LABEL, R_SH_LABEL },
+ { BFD_RELOC_UNUSED, 0 }
+};
+
+/* Adjust a reloc for the SH. This is similar to the generic code,
+ but does some minor tweaking. */
+
+void
+sh_coff_reloc_mangle (seg, fix, intr, paddr)
+ segment_info_type *seg;
+ fixS *fix;
+ struct internal_reloc *intr;
+ unsigned int paddr;
+{
+ symbolS *symbol_ptr = fix->fx_addsy;
+ symbolS *dot;
+
+ intr->r_vaddr = paddr + fix->fx_frag->fr_address + fix->fx_where;
+
+ if (! SWITCH_TABLE (fix))
+ {
+ const struct reloc_map *rm;
+
+ for (rm = coff_reloc_map; rm->bfd_reloc != BFD_RELOC_UNUSED; rm++)
+ if (rm->bfd_reloc == (bfd_reloc_code_real_type) fix->fx_r_type)
+ break;
+ if (rm->bfd_reloc == BFD_RELOC_UNUSED)
+ as_bad_where (fix->fx_file, fix->fx_line,
+ _("Can not represent %s relocation in this object file format"),
+ bfd_get_reloc_code_name (fix->fx_r_type));
+ intr->r_type = rm->sh_reloc;
+ intr->r_offset = 0;
+ }
+ else
+ {
+ know (sh_relax);
+
+ if (fix->fx_r_type == BFD_RELOC_16)
+ intr->r_type = R_SH_SWITCH16;
+ else if (fix->fx_r_type == BFD_RELOC_8)
+ intr->r_type = R_SH_SWITCH8;
+ else if (fix->fx_r_type == BFD_RELOC_32)
+ intr->r_type = R_SH_SWITCH32;
+ else
+ abort ();
+
+ /* For a switch reloc, we set r_offset to the difference between
+ the reloc address and the subtrahend. When the linker is
+ doing relaxing, it can use the determine the starting and
+ ending points of the switch difference expression. */
+ intr->r_offset = intr->r_vaddr - S_GET_VALUE (fix->fx_subsy);
+ }
+
+ /* PC relative relocs are always against the current section. */
+ if (symbol_ptr == NULL)
+ {
+ switch (fix->fx_r_type)
+ {
+ case BFD_RELOC_SH_PCRELIMM8BY2:
+ case BFD_RELOC_SH_PCRELIMM8BY4:
+ case BFD_RELOC_SH_PCDISP8BY2:
+ case BFD_RELOC_SH_PCDISP12BY2:
+ case BFD_RELOC_SH_USES:
+ symbol_ptr = seg->dot;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (fix->fx_r_type == BFD_RELOC_SH_USES)
+ {
+ /* We can't store the offset in the object file, since this
+ reloc does not take up any space, so we store it in r_offset.
+ The fx_addnumber field was set in md_apply_fix. */
+ intr->r_offset = fix->fx_addnumber;
+ }
+ else if (fix->fx_r_type == BFD_RELOC_SH_COUNT)
+ {
+ /* We can't store the count in the object file, since this reloc
+ does not take up any space, so we store it in r_offset. The
+ fx_offset field was set when the fixup was created in
+ sh_coff_frob_file. */
+ intr->r_offset = fix->fx_offset;
+ /* This reloc is always absolute. */
+ symbol_ptr = NULL;
+ }
+ else if (fix->fx_r_type == BFD_RELOC_SH_ALIGN)
+ {
+ /* Store the alignment in the r_offset field. */
+ intr->r_offset = fix->fx_offset;
+ /* This reloc is always absolute. */
+ symbol_ptr = NULL;
+ }
+ else if (fix->fx_r_type == BFD_RELOC_SH_CODE
+ || fix->fx_r_type == BFD_RELOC_SH_DATA
+ || fix->fx_r_type == BFD_RELOC_SH_LABEL)
+ {
+ /* These relocs are always absolute. */
+ symbol_ptr = NULL;
+ }
+
+ /* Turn the segment of the symbol into an offset. */
+ if (symbol_ptr != NULL)
+ {
+ dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
+ if (dot != NULL)
+ intr->r_symndx = dot->sy_number;
+ else
+ intr->r_symndx = symbol_ptr->sy_number;
+ }
+ else
+ intr->r_symndx = -1;
+}
+
+#endif /* OBJ_COFF */
+#endif /* ! BFD_ASSEMBLER */
+
+#ifdef BFD_ASSEMBLER
+
+/* Create a reloc. */
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type r_type;
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ r_type = fixp->fx_r_type;
+
+ if (SWITCH_TABLE (fixp))
+ {
+ rel->addend = rel->address - S_GET_VALUE (fixp->fx_subsy);
+ if (r_type == BFD_RELOC_16)
+ r_type = BFD_RELOC_SH_SWITCH16;
+ else if (r_type == BFD_RELOC_8)
+ r_type = BFD_RELOC_8_PCREL;
+ else if (r_type == BFD_RELOC_32)
+ r_type = BFD_RELOC_SH_SWITCH32;
+ else
+ abort ();
+ }
+ else if (r_type == BFD_RELOC_SH_USES)
+ rel->addend = fixp->fx_addnumber;
+ else if (r_type == BFD_RELOC_SH_COUNT)
+ rel->addend = fixp->fx_offset;
+ else if (r_type == BFD_RELOC_SH_ALIGN)
+ rel->addend = fixp->fx_offset;
+ else if (r_type == BFD_RELOC_VTABLE_INHERIT
+ || r_type == BFD_RELOC_VTABLE_ENTRY)
+ rel->addend = fixp->fx_offset;
+ else if (fixp->fx_pcrel)
+ rel->addend = fixp->fx_addnumber;
+ else
+ rel->addend = 0;
+
+ rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
+ if (rel->howto == NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Cannot represent relocation type %s"),
+ bfd_get_reloc_code_name (r_type));
+ /* Set howto to a garbage value so that we can keep going. */
+ rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
+ assert (rel->howto != NULL);
+ }
+
+ return rel;
+}
+
+#endif /* BFD_ASSEMBLER */
diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h
new file mode 100644
index 00000000000..cc02eab72c1
--- /dev/null
+++ b/gas/config/tc-sh.h
@@ -0,0 +1,152 @@
+/* This file is tc-sh.h
+ Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#define TC_SH
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define TARGET_ARCH bfd_arch_sh
+
+#if ANSI_PROTOTYPES
+struct segment_info_struct;
+struct internal_reloc;
+#endif
+
+/* Whether in little endian mode. */
+extern int shl;
+
+/* Whether -relax was used. */
+extern int sh_relax;
+
+/* Whether -small was used. */
+extern int sh_small;
+
+/* Don't try to break words. */
+#define WORKING_DOT_WORD
+
+/* We require .long, et. al., to be aligned correctly. */
+#define md_cons_align(nbytes) sh_cons_align (nbytes)
+extern void sh_cons_align PARAMS ((int));
+
+/* When relaxing, we need to generate relocations for alignment
+ directives. */
+#define HANDLE_ALIGN(frag) sh_handle_align (frag)
+extern void sh_handle_align PARAMS ((fragS *));
+
+/* We need to force out some relocations when relaxing. */
+#define TC_FORCE_RELOCATION(fix) sh_force_relocation (fix)
+extern int sh_force_relocation ();
+
+#ifdef OBJ_ELF
+#define obj_fix_adjustable(fixP) sh_fix_adjustable(fixP)
+#endif
+
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define LISTING_HEADER (shl ? "Hitachi Super-H GAS Little Endian" : "Hitachi Super-H GAS Big Endian")
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/* We use a special alignment function to insert the correct nop
+ pattern. */
+extern int sh_do_align PARAMS ((int, const char *, int, int));
+#define md_do_align(n,fill,len,max,l) if (sh_do_align (n,fill,len,max)) goto l
+
+/* We record, for each section, whether we have most recently output a
+ CODE reloc or a DATA reloc. */
+struct sh_segment_info_type
+{
+ int in_code : 1;
+};
+#define TC_SEGMENT_INFO_TYPE struct sh_segment_info_type
+
+/* We call a routine to emit a reloc for a label, so that the linker
+ can align loads and stores without crossing a label. */
+extern void sh_frob_label PARAMS ((void));
+#define tc_frob_label(sym) sh_frob_label ()
+
+/* We call a routine to flush pending output in order to output a DATA
+ reloc when required. */
+extern void sh_flush_pending_output PARAMS ((void));
+#define md_flush_pending_output() sh_flush_pending_output ()
+
+#ifdef BFD_ASSEMBLER
+#define tc_frob_file_before_adjust sh_frob_file
+#else
+#define tc_frob_file sh_frob_file
+#endif
+extern void sh_frob_file PARAMS ((void));
+
+#ifdef OBJ_COFF
+/* COFF specific definitions. */
+
+#define DO_NOT_STRIP 0
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fix) ((fix)->fx_r_type)
+
+#define BFD_ARCH TARGET_ARCH
+
+#define COFF_MAGIC (shl ? SH_ARCH_MAGIC_LITTLE : SH_ARCH_MAGIC_BIG)
+
+/* We need to write out relocs which have not been completed. */
+#define TC_COUNT_RELOC(fix) ((fix)->fx_addsy != NULL)
+
+#define TC_RELOC_MANGLE(seg, fix, int, paddr) \
+ sh_coff_reloc_mangle ((seg), (fix), (int), (paddr))
+extern void sh_coff_reloc_mangle
+ PARAMS ((struct segment_info_struct *, struct fix *,
+ struct internal_reloc *, unsigned int));
+
+#define tc_coff_symbol_emit_hook(a) ; /* not used */
+
+#define NEED_FX_R_TYPE 1
+
+#define TC_KEEP_FX_OFFSET 1
+
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+extern int tc_coff_sizemachdep PARAMS ((fragS *));
+
+/* We align most sections to a 16 byte boundary. */
+#define SUB_SEGMENT_ALIGN(SEG) \
+ (strncmp (obj_segment_name (SEG), ".stabstr", 8) == 0 \
+ ? 0 \
+ : ((strncmp (obj_segment_name (SEG), ".stab", 5) == 0 \
+ || strcmp (obj_segment_name (SEG), ".ctors") == 0 \
+ || strcmp (obj_segment_name (SEG), ".dtors") == 0) \
+ ? 2 \
+ : (sh_small ? 2 : 4)))
+
+#endif /* OBJ_COFF */
+
+#ifdef OBJ_ELF
+/* ELF specific definitions. */
+
+/* Whether or not the target is big endian */
+extern int target_big_endian;
+
+#define TARGET_FORMAT (shl ? "elf32-shl" : "elf32-sh")
+
+#endif /* OBJ_ELF */
+
+/* end of tc-sh.h */
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
new file mode 100644
index 00000000000..1518a8a34c4
--- /dev/null
+++ b/gas/config/tc-sparc.c
@@ -0,0 +1,3551 @@
+/* tc-sparc.c -- Assemble for the SPARC
+ Copyright (C) 1989, 90-96, 97, 1998 Free Software Foundation, Inc.
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write
+ to the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "as.h"
+#include "subsegs.h"
+
+#include "opcode/sparc.h"
+
+#ifdef OBJ_ELF
+#include "elf/sparc.h"
+#endif
+
+static struct sparc_arch *lookup_arch PARAMS ((char *));
+static void init_default_arch PARAMS ((void));
+static void sparc_ip PARAMS ((char *, const struct sparc_opcode **));
+static int in_signed_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
+static int in_unsigned_range PARAMS ((bfd_vma, bfd_vma));
+static int in_bitfield_range PARAMS ((bfd_signed_vma, bfd_signed_vma));
+static int sparc_ffs PARAMS ((unsigned int));
+static bfd_vma BSR PARAMS ((bfd_vma, int));
+static int cmp_reg_entry PARAMS ((const PTR, const PTR));
+static int parse_keyword_arg PARAMS ((int (*) (const char *), char **, int *));
+static int parse_const_expr_arg PARAMS ((char **, int *));
+static int get_expression PARAMS ((char *str));
+
+/* Default architecture. */
+/* ??? The default value should be V8, but sparclite support was added
+ by making it the default. GCC now passes -Asparclite, so maybe sometime in
+ the future we can set this to V8. */
+#ifndef DEFAULT_ARCH
+#define DEFAULT_ARCH "sparclite"
+#endif
+static char *default_arch = DEFAULT_ARCH;
+
+/* Non-zero if the initial values of `max_architecture' and `sparc_arch_size'
+ have been set. */
+static int default_init_p;
+
+/* Current architecture. We don't bump up unless necessary. */
+static enum sparc_opcode_arch_val current_architecture = SPARC_OPCODE_ARCH_V6;
+
+/* The maximum architecture level we can bump up to.
+ In a 32 bit environment, don't allow bumping up to v9 by default.
+ The native assembler works this way. The user is required to pass
+ an explicit argument before we'll create v9 object files. However, if
+ we don't see any v9 insns, a v8plus object file is not created. */
+static enum sparc_opcode_arch_val max_architecture;
+
+/* Either 32 or 64, selects file format. */
+static int sparc_arch_size;
+/* Initial (default) value, recorded separately in case a user option
+ changes the value before md_show_usage is called. */
+static int default_arch_size;
+
+#ifdef OBJ_ELF
+/* The currently selected v9 memory model. Currently only used for
+ ELF. */
+static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO;
+#endif
+
+static int architecture_requested;
+static int warn_on_bump;
+
+/* If warn_on_bump and the needed architecture is higher than this
+ architecture, issue a warning. */
+static enum sparc_opcode_arch_val warn_after_architecture;
+
+/* Non-zero if we are generating PIC code. */
+int sparc_pic_code;
+
+/* Non-zero if we should give an error when misaligned data is seen. */
+static int enforce_aligned_data;
+
+extern int target_big_endian;
+
+static int target_little_endian_data;
+
+/* V9 and 86x have big and little endian data, but instructions are always big
+ endian. The sparclet has bi-endian support but both data and insns have
+ the same endianness. Global `target_big_endian' is used for data.
+ The following macro is used for instructions. */
+#ifndef INSN_BIG_ENDIAN
+#define INSN_BIG_ENDIAN (target_big_endian \
+ || default_arch_type == sparc86x \
+ || SPARC_OPCODE_ARCH_V9_P (max_architecture))
+#endif
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash;
+
+static int log2 PARAMS ((int));
+static void s_data1 PARAMS ((void));
+static void s_seg PARAMS ((int));
+static void s_proc PARAMS ((int));
+static void s_reserve PARAMS ((int));
+static void s_common PARAMS ((int));
+static void s_empty PARAMS ((int));
+static void s_uacons PARAMS ((int));
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
+ {"common", s_common, 0},
+ {"empty", s_empty, 0},
+ {"global", s_globl, 0},
+ {"half", cons, 2},
+ {"optim", s_ignore, 0},
+ {"proc", s_proc, 0},
+ {"reserve", s_reserve, 0},
+ {"seg", s_seg, 0},
+ {"skip", s_space, 0},
+ {"word", cons, 4},
+ {"xword", cons, 8},
+ {"uahalf", s_uacons, 2},
+ {"uaword", s_uacons, 4},
+ {"uaxword", s_uacons, 8},
+#ifdef OBJ_ELF
+ /* these are specific to sparc/svr4 */
+ {"pushsection", obj_elf_section, 0},
+ {"popsection", obj_elf_previous, 0},
+ {"2byte", s_uacons, 2},
+ {"4byte", s_uacons, 4},
+ {"8byte", s_uacons, 8},
+#endif
+ {NULL, 0, 0},
+};
+
+const int md_reloc_size = 12; /* Size of relocation record */
+
+/* This array holds the chars that always start a comment. If the
+ pre-processor is disabled, these aren't very useful */
+const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
+
+/* This array holds the chars that only start a comment at the beginning of
+ a line. If the line seems to have the form '# 123 filename'
+ .line and .file directives will appear in the pre-processed output */
+/* Note that input_file.c hand checks for '#' at the beginning of the
+ first line of the input file. This is because the compiler outputs
+ #NO_APP at the beginning of its output. */
+/* Also note that comments started like this one will always
+ work if '/' isn't otherwise defined. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c. Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here. */
+
+static unsigned char octal[256];
+#define isoctal(c) octal[(unsigned char) (c)]
+static unsigned char toHex[256];
+
+struct sparc_it
+ {
+ char *error;
+ unsigned long opcode;
+ struct nlist *nlistp;
+ expressionS exp;
+ int pcrel;
+ bfd_reloc_code_real_type reloc;
+ };
+
+struct sparc_it the_insn, set_insn;
+
+static void output_insn
+ PARAMS ((const struct sparc_opcode *, struct sparc_it *));
+
+/* Table of arguments to -A.
+ The sparc_opcode_arch table in sparc-opc.c is insufficient and incorrect
+ for this use. That table is for opcodes only. This table is for opcodes
+ and file formats. */
+
+enum sparc_arch_types {v6, v7, v8, sparclet, sparclite, sparc86x, v8plus,
+ v8plusa, v9, v9a, v9_64};
+
+static struct sparc_arch {
+ char *name;
+ char *opcode_arch;
+ enum sparc_arch_types arch_type;
+ /* Default word size, as specified during configuration.
+ A value of zero means can't be used to specify default architecture. */
+ int default_arch_size;
+ /* Allowable arg to -A? */
+ int user_option_p;
+} sparc_arch_table[] = {
+ { "v6", "v6", v6, 0, 1 },
+ { "v7", "v7", v7, 0, 1 },
+ { "v8", "v8", v8, 32, 1 },
+ { "sparclet", "sparclet", sparclet, 32, 1 },
+ { "sparclite", "sparclite", sparclite, 32, 1 },
+ { "sparc86x", "sparclite", sparc86x, 32, 1 },
+ { "v8plus", "v9", v9, 0, 1 },
+ { "v8plusa", "v9a", v9, 0, 1 },
+ { "v9", "v9", v9, 0, 1 },
+ { "v9a", "v9a", v9, 0, 1 },
+ /* This exists to allow configure.in/Makefile.in to pass one
+ value to specify both the default machine and default word size. */
+ { "v9-64", "v9", v9, 64, 0 },
+ { NULL, NULL, v8, 0, 0 }
+};
+
+/* Variant of default_arch */
+static enum sparc_arch_types default_arch_type;
+
+static struct sparc_arch *
+lookup_arch (name)
+ char *name;
+{
+ struct sparc_arch *sa;
+
+ for (sa = &sparc_arch_table[0]; sa->name != NULL; sa++)
+ if (strcmp (sa->name, name) == 0)
+ break;
+ if (sa->name == NULL)
+ return NULL;
+ return sa;
+}
+
+/* Initialize the default opcode arch and word size from the default
+ architecture name. */
+
+static void
+init_default_arch ()
+{
+ struct sparc_arch *sa = lookup_arch (default_arch);
+
+ if (sa == NULL
+ || sa->default_arch_size == 0)
+ as_fatal (_("Invalid default architecture, broken assembler."));
+
+ max_architecture = sparc_opcode_lookup_arch (sa->opcode_arch);
+ if (max_architecture == SPARC_OPCODE_ARCH_BAD)
+ as_fatal (_("Bad opcode table, broken assembler."));
+ default_arch_size = sparc_arch_size = sa->default_arch_size;
+ default_init_p = 1;
+ default_arch_type = sa->arch_type;
+}
+
+/* Called by TARGET_FORMAT. */
+
+const char *
+sparc_target_format ()
+{
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
+
+#ifdef OBJ_AOUT
+#ifdef TE_NetBSD
+ return "a.out-sparc-netbsd";
+#else
+#ifdef TE_SPARCAOUT
+ if (target_big_endian)
+ return "a.out-sunos-big";
+ else if (default_arch_type == sparc86x && target_little_endian_data)
+ return "a.out-sunos-big";
+ else return "a.out-sparc-little";
+#else
+ return "a.out-sunos-big";
+#endif
+#endif
+#endif
+
+#ifdef OBJ_BOUT
+ return "b.out.big";
+#endif
+
+#ifdef OBJ_COFF
+#ifdef TE_LYNX
+ return "coff-sparc-lynx";
+#else
+ return "coff-sparc";
+#endif
+#endif
+
+#ifdef OBJ_ELF
+ return sparc_arch_size == 64 ? "elf64-sparc" : "elf32-sparc";
+#endif
+
+ abort ();
+}
+
+/*
+ * md_parse_option
+ * Invocation line includes a switch not recognized by the base assembler.
+ * See if it's a processor-specific option. These are:
+ *
+ * -bump
+ * Warn on architecture bumps. See also -A.
+ *
+ * -Av6, -Av7, -Av8, -Asparclite, -Asparclet
+ * Standard 32 bit architectures.
+ * -Av8plus, -Av8plusa
+ * Sparc64 in a 32 bit world.
+ * -Av9, -Av9a
+ * Sparc64 in either a 32 or 64 bit world (-32/-64 says which).
+ * This used to only mean 64 bits, but properly specifying it
+ * complicated gcc's ASM_SPECs, so now opcode selection is
+ * specified orthogonally to word size (except when specifying
+ * the default, but that is an internal implementation detail).
+ * -xarch=v8plus, -xarch=v8plusa
+ * Same as -Av8plus{,a}, for compatibility with Sun's assembler.
+ *
+ * Select the architecture and possibly the file format.
+ * Instructions or features not supported by the selected
+ * architecture cause fatal errors.
+ *
+ * The default is to start at v6, and bump the architecture up
+ * whenever an instruction is seen at a higher level. In 32 bit
+ * environments, v9 is not bumped up to, the user must pass
+ * -Av8plus{,a}.
+ *
+ * If -bump is specified, a warning is printing when bumping to
+ * higher levels.
+ *
+ * If an architecture is specified, all instructions must match
+ * that architecture. Any higher level instructions are flagged
+ * as errors. Note that in the 32 bit environment specifying
+ * -Av8plus does not automatically create a v8plus object file, a
+ * v9 insn must be seen.
+ *
+ * If both an architecture and -bump are specified, the
+ * architecture starts at the specified level, but bumps are
+ * warnings. Note that we can't set `current_architecture' to
+ * the requested level in this case: in the 32 bit environment,
+ * we still must avoid creating v8plus object files unless v9
+ * insns are seen.
+ *
+ * Note:
+ * Bumping between incompatible architectures is always an
+ * error. For example, from sparclite to v9.
+ */
+
+#ifdef OBJ_ELF
+CONST char *md_shortopts = "A:K:VQ:sq";
+#else
+#ifdef OBJ_AOUT
+CONST char *md_shortopts = "A:k";
+#else
+CONST char *md_shortopts = "A:";
+#endif
+#endif
+struct option md_longopts[] = {
+#define OPTION_BUMP (OPTION_MD_BASE)
+ {"bump", no_argument, NULL, OPTION_BUMP},
+#define OPTION_SPARC (OPTION_MD_BASE + 1)
+ {"sparc", no_argument, NULL, OPTION_SPARC},
+#define OPTION_XARCH (OPTION_MD_BASE + 2)
+ {"xarch", required_argument, NULL, OPTION_XARCH},
+#ifdef OBJ_ELF
+#define OPTION_32 (OPTION_MD_BASE + 3)
+ {"32", no_argument, NULL, OPTION_32},
+#define OPTION_64 (OPTION_MD_BASE + 4)
+ {"64", no_argument, NULL, OPTION_64},
+#define OPTION_TSO (OPTION_MD_BASE + 5)
+ {"TSO", no_argument, NULL, OPTION_TSO},
+#define OPTION_PSO (OPTION_MD_BASE + 6)
+ {"PSO", no_argument, NULL, OPTION_PSO},
+#define OPTION_RMO (OPTION_MD_BASE + 7)
+ {"RMO", no_argument, NULL, OPTION_RMO},
+#endif
+#ifdef SPARC_BIENDIAN
+#define OPTION_LITTLE_ENDIAN (OPTION_MD_BASE + 8)
+ {"EL", no_argument, NULL, OPTION_LITTLE_ENDIAN},
+#define OPTION_BIG_ENDIAN (OPTION_MD_BASE + 9)
+ {"EB", no_argument, NULL, OPTION_BIG_ENDIAN},
+#endif
+#define OPTION_ENFORCE_ALIGNED_DATA (OPTION_MD_BASE + 10)
+ {"enforce-aligned-data", no_argument, NULL, OPTION_ENFORCE_ALIGNED_DATA},
+#define OPTION_LITTLE_ENDIAN_DATA (OPTION_MD_BASE + 11)
+ {"little-endian-data", no_argument, NULL, OPTION_LITTLE_ENDIAN_DATA},
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
+
+ switch (c)
+ {
+ case OPTION_BUMP:
+ warn_on_bump = 1;
+ warn_after_architecture = SPARC_OPCODE_ARCH_V6;
+ break;
+
+ case OPTION_XARCH:
+ /* This is for compatibility with Sun's assembler. */
+ if (strcmp (arg, "v8plus") != 0
+ && strcmp (arg, "v8plusa") != 0)
+ {
+ as_bad (_("invalid architecture -xarch=%s"), arg);
+ return 0;
+ }
+
+ /* fall through */
+
+ case 'A':
+ {
+ struct sparc_arch *sa;
+ enum sparc_opcode_arch_val opcode_arch;
+
+ sa = lookup_arch (arg);
+ if (sa == NULL
+ || ! sa->user_option_p)
+ {
+ as_bad (_("invalid architecture -A%s"), arg);
+ return 0;
+ }
+
+ opcode_arch = sparc_opcode_lookup_arch (sa->opcode_arch);
+ if (opcode_arch == SPARC_OPCODE_ARCH_BAD)
+ as_fatal (_("Bad opcode table, broken assembler."));
+
+ max_architecture = opcode_arch;
+ architecture_requested = 1;
+ }
+ break;
+
+ case OPTION_SPARC:
+ /* Ignore -sparc, used by SunOS make default .s.o rule. */
+ break;
+
+ case OPTION_ENFORCE_ALIGNED_DATA:
+ enforce_aligned_data = 1;
+ break;
+
+#ifdef SPARC_BIENDIAN
+ case OPTION_LITTLE_ENDIAN:
+ target_big_endian = 0;
+ if (default_arch_type != sparclet)
+ as_fatal ("This target does not support -EL");
+ break;
+ case OPTION_LITTLE_ENDIAN_DATA:
+ target_little_endian_data = 1;
+ target_big_endian = 0;
+ if (default_arch_type != sparc86x
+ && default_arch_type != v9)
+ as_fatal ("This target does not support --little-endian-data");
+ break;
+ case OPTION_BIG_ENDIAN:
+ target_big_endian = 1;
+ break;
+#endif
+
+#ifdef OBJ_AOUT
+ case 'k':
+ sparc_pic_code = 1;
+ break;
+#endif
+
+#ifdef OBJ_ELF
+ case OPTION_32:
+ case OPTION_64:
+ {
+ const char **list, **l;
+
+ sparc_arch_size = c == OPTION_32 ? 32 : 64;
+ list = bfd_target_list ();
+ for (l = list; *l != NULL; l++)
+ {
+ if (sparc_arch_size == 32)
+ {
+ if (strcmp (*l, "elf32-sparc") == 0)
+ break;
+ }
+ else
+ {
+ if (strcmp (*l, "elf64-sparc") == 0)
+ break;
+ }
+ }
+ if (*l == NULL)
+ as_fatal (_("No compiled in support for %d bit object file format"),
+ sparc_arch_size);
+ free (list);
+ }
+ break;
+
+ case OPTION_TSO:
+ sparc_memory_model = MM_TSO;
+ break;
+
+ case OPTION_PSO:
+ sparc_memory_model = MM_PSO;
+ break;
+
+ case OPTION_RMO:
+ sparc_memory_model = MM_RMO;
+ break;
+
+ case 'V':
+ print_version_id ();
+ break;
+
+ case 'Q':
+ /* Qy - do emit .comment
+ Qn - do not emit .comment */
+ break;
+
+ case 's':
+ /* use .stab instead of .stab.excl */
+ break;
+
+ case 'q':
+ /* quick -- native assembler does fewer checks */
+ break;
+
+ case 'K':
+ if (strcmp (arg, "PIC") != 0)
+ as_warn (_("Unrecognized option following -K"));
+ else
+ sparc_pic_code = 1;
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ const struct sparc_arch *arch;
+
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
+
+ fprintf(stream, _("SPARC options:\n"));
+ for (arch = &sparc_arch_table[0]; arch->name; arch++)
+ {
+ if (arch != &sparc_arch_table[0])
+ fprintf (stream, " | ");
+ if (arch->user_option_p)
+ fprintf (stream, "-A%s", arch->name);
+ }
+ fprintf (stream, _("\n-xarch=v8plus | -xarch=v8plusa\n"));
+ fprintf (stream, _("\
+ specify variant of SPARC architecture\n\
+-bump warn when assembler switches architectures\n\
+-sparc ignored\n\
+--enforce-aligned-data force .long, etc., to be aligned correctly\n"));
+#ifdef OBJ_AOUT
+ fprintf (stream, _("\
+-k generate PIC\n"));
+#endif
+#ifdef OBJ_ELF
+ fprintf (stream, _("\
+-32 create 32 bit object file\n\
+-64 create 64 bit object file\n"));
+ fprintf (stream, _("\
+ [default is %d]\n"), default_arch_size);
+ fprintf (stream, _("\
+-TSO use Total Store Ordering\n\
+-PSO use Partial Store Ordering\n\
+-RMO use Relaxed Memory Ordering\n"));
+ fprintf (stream, _("\
+ [default is %s]\n"), (default_arch_size == 64) ? "RMO" : "TSO");
+ fprintf (stream, _("\
+-KPIC generate PIC\n\
+-V print assembler version number\n\
+-q ignored\n\
+-Qy, -Qn ignored\n\
+-s ignored\n"));
+#endif
+#ifdef SPARC_BIENDIAN
+ fprintf (stream, _("\
+-EL generate code for a little endian machine\n\
+-EB generate code for a big endian machine\n\
+--little-endian-data generate code for a machine having big endian\n\
+ instructions and little endian data."));
+#endif
+}
+
+/* sparc64 priviledged registers */
+
+struct priv_reg_entry
+ {
+ char *name;
+ int regnum;
+ };
+
+struct priv_reg_entry priv_reg_table[] =
+{
+ {"tpc", 0},
+ {"tnpc", 1},
+ {"tstate", 2},
+ {"tt", 3},
+ {"tick", 4},
+ {"tba", 5},
+ {"pstate", 6},
+ {"tl", 7},
+ {"pil", 8},
+ {"cwp", 9},
+ {"cansave", 10},
+ {"canrestore", 11},
+ {"cleanwin", 12},
+ {"otherwin", 13},
+ {"wstate", 14},
+ {"fq", 15},
+ {"ver", 31},
+ {"", -1}, /* end marker */
+};
+
+/* v9a specific asrs */
+
+struct priv_reg_entry v9a_asr_table[] =
+{
+ {"tick_cmpr", 23},
+ {"softint", 22},
+ {"set_softint", 20},
+ {"pic", 17},
+ {"pcr", 16},
+ {"gsr", 19},
+ {"dcr", 18},
+ {"clear_softint", 21},
+ {"", -1}, /* end marker */
+};
+
+static int
+cmp_reg_entry (parg, qarg)
+ const PTR parg;
+ const PTR qarg;
+{
+ const struct priv_reg_entry *p = (const struct priv_reg_entry *) parg;
+ const struct priv_reg_entry *q = (const struct priv_reg_entry *) qarg;
+
+ return strcmp (q->name, p->name);
+}
+
+/* This function is called once, at assembler startup time. It should
+ set up all the tables, etc. that the MD part of the assembler will need. */
+
+void
+md_begin ()
+{
+ register const char *retval = NULL;
+ int lose = 0;
+ register unsigned int i = 0;
+
+ /* We don't get a chance to initialize anything before md_parse_option
+ is called, and it may not be called, so handle default initialization
+ now if not already done. */
+ if (! default_init_p)
+ init_default_arch ();
+
+ op_hash = hash_new ();
+
+ while (i < (unsigned int) sparc_num_opcodes)
+ {
+ const char *name = sparc_opcodes[i].name;
+ retval = hash_insert (op_hash, name, (PTR) &sparc_opcodes[i]);
+ if (retval != NULL)
+ {
+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
+ sparc_opcodes[i].name, retval);
+ lose = 1;
+ }
+ do
+ {
+ if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
+ {
+ fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),
+ sparc_opcodes[i].name, sparc_opcodes[i].args);
+ lose = 1;
+ }
+ ++i;
+ }
+ while (i < (unsigned int) sparc_num_opcodes
+ && !strcmp (sparc_opcodes[i].name, name));
+ }
+
+ if (lose)
+ as_fatal (_("Broken assembler. No assembly attempted."));
+
+ for (i = '0'; i < '8'; ++i)
+ octal[i] = 1;
+ for (i = '0'; i <= '9'; ++i)
+ toHex[i] = i - '0';
+ for (i = 'a'; i <= 'f'; ++i)
+ toHex[i] = i + 10 - 'a';
+ for (i = 'A'; i <= 'F'; ++i)
+ toHex[i] = i + 10 - 'A';
+
+ qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
+ sizeof (priv_reg_table[0]), cmp_reg_entry);
+
+ /* If -bump, record the architecture level at which we start issuing
+ warnings. The behaviour is different depending upon whether an
+ architecture was explicitly specified. If it wasn't, we issue warnings
+ for all upwards bumps. If it was, we don't start issuing warnings until
+ we need to bump beyond the requested architecture or when we bump between
+ conflicting architectures. */
+
+ if (warn_on_bump
+ && architecture_requested)
+ {
+ /* `max_architecture' records the requested architecture.
+ Issue warnings if we go above it. */
+ warn_after_architecture = max_architecture;
+
+ /* Find the highest architecture level that doesn't conflict with
+ the requested one. */
+ for (max_architecture = SPARC_OPCODE_ARCH_MAX;
+ max_architecture > warn_after_architecture;
+ --max_architecture)
+ if (! SPARC_OPCODE_CONFLICT_P (max_architecture,
+ warn_after_architecture))
+ break;
+ }
+}
+
+/* Called after all assembly has been done. */
+
+void
+sparc_md_end ()
+{
+ if (sparc_arch_size == 64)
+ {
+ if (current_architecture == SPARC_OPCODE_ARCH_V9A)
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v9a);
+ else
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v9);
+ }
+ else
+ {
+ if (current_architecture == SPARC_OPCODE_ARCH_V9)
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v8plus);
+ else if (current_architecture == SPARC_OPCODE_ARCH_V9A)
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v8plusa);
+ else if (current_architecture == SPARC_OPCODE_ARCH_SPARCLET)
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_sparclet);
+ else if (default_arch_type == sparc86x && target_little_endian_data)
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_sparclite_le);
+ else
+ {
+ /* The sparclite is treated like a normal sparc. Perhaps it shouldn't
+ be but for now it is (since that's the way it's always been
+ treated). */
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc);
+ }
+ }
+}
+
+/* Return non-zero if VAL is in the range -(MAX+1) to MAX. */
+
+static INLINE int
+in_signed_range (val, max)
+ bfd_signed_vma val, max;
+{
+ if (max <= 0)
+ abort ();
+ /* Sign-extend the value from the architecture word size, so that
+ 0xffffffff is always considered -1 on sparc32. */
+ if (sparc_arch_size == 32)
+ {
+ bfd_signed_vma sign = (bfd_signed_vma)1 << 31;
+ val = ((val & 0xffffffff) ^ sign) - sign;
+ }
+ if (val > max)
+ return 0;
+ if (val < ~max)
+ return 0;
+ return 1;
+}
+
+/* Return non-zero if VAL is in the range 0 to MAX. */
+
+static INLINE int
+in_unsigned_range (val, max)
+ bfd_vma val, max;
+{
+ if (val > max)
+ return 0;
+ return 1;
+}
+
+/* Return non-zero if VAL is in the range -(MAX/2+1) to MAX.
+ (e.g. -15 to +31). */
+
+static INLINE int
+in_bitfield_range (val, max)
+ bfd_signed_vma val, max;
+{
+ if (max <= 0)
+ abort ();
+ if (val > max)
+ return 0;
+ if (val < ~(max >> 1))
+ return 0;
+ return 1;
+}
+
+static int
+sparc_ffs (mask)
+ unsigned int mask;
+{
+ int i;
+
+ if (mask == 0)
+ return -1;
+
+ for (i = 0; (mask & 1) == 0; ++i)
+ mask >>= 1;
+ return i;
+}
+
+/* Implement big shift right. */
+static bfd_vma
+BSR (val, amount)
+ bfd_vma val;
+ int amount;
+{
+ if (sizeof (bfd_vma) <= 4 && amount >= 32)
+ as_fatal (_("Support for 64-bit arithmetic not compiled in."));
+ return val >> amount;
+}
+
+/* For communication between sparc_ip and get_expression. */
+static char *expr_end;
+
+/* For communication between md_assemble and sparc_ip. */
+static int special_case;
+
+/* Values for `special_case'.
+ Instructions that require wierd handling because they're longer than
+ 4 bytes. */
+#define SPECIAL_CASE_NONE 0
+#define SPECIAL_CASE_SET 1
+#define SPECIAL_CASE_SETSW 2
+#define SPECIAL_CASE_SETX 3
+/* FIXME: sparc-opc.c doesn't have necessary "S" trigger to enable this. */
+#define SPECIAL_CASE_FDIV 4
+
+/* Bit masks of various insns. */
+#define NOP_INSN 0x01000000
+#define OR_INSN 0x80100000
+#define FMOVS_INSN 0x81A00020
+#define SETHI_INSN 0x01000000
+#define SLLX_INSN 0x81281000
+#define SRA_INSN 0x81380000
+
+/* The last instruction to be assembled. */
+static const struct sparc_opcode *last_insn;
+/* The assembled opcode of `last_insn'. */
+static unsigned long last_opcode;
+
+/* Main entry point to assemble one instruction. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ const struct sparc_opcode *insn;
+
+ know (str);
+ special_case = SPECIAL_CASE_NONE;
+ sparc_ip (str, &insn);
+
+ /* We warn about attempts to put a floating point branch in a delay slot,
+ unless the delay slot has been annulled. */
+ if (insn != NULL
+ && last_insn != NULL
+ && (insn->flags & F_FBR) != 0
+ && (last_insn->flags & F_DELAYED) != 0
+ /* ??? This test isn't completely accurate. We assume anything with
+ F_{UNBR,CONDBR,FBR} set is annullable. */
+ && ((last_insn->flags & (F_UNBR | F_CONDBR | F_FBR)) == 0
+ || (last_opcode & ANNUL) == 0))
+ as_warn (_("FP branch in delay slot"));
+
+ /* SPARC before v9 requires a nop instruction between a floating
+ point instruction and a floating point branch. We insert one
+ automatically, with a warning. */
+ if (max_architecture < SPARC_OPCODE_ARCH_V9
+ && insn != NULL
+ && last_insn != NULL
+ && (insn->flags & F_FBR) != 0
+ && (last_insn->flags & F_FLOAT) != 0)
+ {
+ struct sparc_it nop_insn;
+
+ nop_insn.opcode = NOP_INSN;
+ nop_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &nop_insn);
+ as_warn (_("FP branch preceded by FP instruction; NOP inserted"));
+ }
+
+ switch (special_case)
+ {
+ case SPECIAL_CASE_NONE:
+ /* normal insn */
+ output_insn (insn, &the_insn);
+ break;
+
+ case SPECIAL_CASE_SET:
+ {
+ int need_hi22_p = 0;
+
+ /* "set" is not defined for negative numbers in v9: it doesn't yield
+ what you expect it to. */
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture)
+ && the_insn.exp.X_op == O_constant)
+ {
+ if (the_insn.exp.X_add_number < 0)
+ as_warn (_("set: used with negative number"));
+ else if (the_insn.exp.X_add_number > (offsetT) 0xffffffff)
+ as_warn (_("set: number larger than 4294967295"));
+ }
+
+ /* See if operand is absolute and small; skip sethi if so. */
+ if (the_insn.exp.X_op != O_constant
+ || the_insn.exp.X_add_number >= (1 << 12)
+ || the_insn.exp.X_add_number < -(1 << 12))
+ {
+ output_insn (insn, &the_insn);
+ need_hi22_p = 1;
+ }
+ /* See if operand has no low-order bits; skip OR if so. */
+ if (the_insn.exp.X_op != O_constant
+ || (need_hi22_p && (the_insn.exp.X_add_number & 0x3FF) != 0)
+ || ! need_hi22_p)
+ {
+ int rd = (the_insn.opcode & RD (~0)) >> 25;
+ the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (rd) : 0)
+ | RD (rd)
+ | IMMED
+ | (the_insn.exp.X_add_number
+ & (need_hi22_p ? 0x3ff : 0x1fff)));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_LO10
+ : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+ break;
+ }
+
+ case SPECIAL_CASE_SETSW:
+ {
+ /* FIXME: Not finished. */
+ break;
+ }
+
+ case SPECIAL_CASE_SETX:
+ {
+#define SIGNEXT32(x) ((((x) & 0xffffffff) ^ 0x80000000) - 0x80000000)
+ int upper32 = SIGNEXT32 (BSR (the_insn.exp.X_add_number, 32));
+ int lower32 = SIGNEXT32 (the_insn.exp.X_add_number);
+#undef SIGNEXT32
+ int tmpreg = (the_insn.opcode & RS1 (~0)) >> 14;
+ int dstreg = (the_insn.opcode & RD (~0)) >> 25;
+ /* Output directly to dst reg if lower 32 bits are all zero. */
+ int upper_dstreg = (the_insn.exp.X_op == O_constant
+ && lower32 == 0) ? dstreg : tmpreg;
+ int need_hh22_p = 0, need_hm10_p = 0, need_hi22_p = 0, need_lo10_p = 0;
+
+ /* The tmp reg should not be the dst reg. */
+ if (tmpreg == dstreg)
+ as_warn (_("setx: temporary register same as destination register"));
+
+ /* Reset X_add_number, we've extracted it as upper32/lower32.
+ Otherwise fixup_segment will complain about not being able to
+ write an 8 byte number in a 4 byte field. */
+ the_insn.exp.X_add_number = 0;
+
+ /* ??? Obviously there are other optimizations we can do
+ (e.g. sethi+shift for 0x1f0000000) and perhaps we shouldn't be
+ doing some of these. Later. If you do change things, try to
+ change all of this to be table driven as well. */
+
+ /* What to output depends on the number if it's constant.
+ Compute that first, then output what we've decided upon. */
+ if (the_insn.exp.X_op != O_constant)
+ need_hh22_p = need_hm10_p = need_hi22_p = need_lo10_p = 1;
+ else
+ {
+ /* Only need hh22 if `or' insn can't handle constant. */
+ if (upper32 < -(1 << 12) || upper32 >= (1 << 12))
+ need_hh22_p = 1;
+
+ /* Does bottom part (after sethi) have bits? */
+ if ((need_hh22_p && (upper32 & 0x3ff) != 0)
+ /* No hh22, but does upper32 still have bits we can't set
+ from lower32? */
+ || (! need_hh22_p
+ && upper32 != 0
+ && (upper32 != -1 || lower32 >= 0)))
+ need_hm10_p = 1;
+
+ /* If the lower half is all zero, we build the upper half directly
+ into the dst reg. */
+ if (lower32 != 0
+ /* Need lower half if number is zero. */
+ || (! need_hh22_p && ! need_hm10_p))
+ {
+ /* No need for sethi if `or' insn can handle constant. */
+ if (lower32 < -(1 << 12) || lower32 >= (1 << 12)
+ /* Note that we can't use a negative constant in the `or'
+ insn unless the upper 32 bits are all ones. */
+ || (lower32 < 0 && upper32 != -1))
+ need_hi22_p = 1;
+
+ /* Does bottom part (after sethi) have bits? */
+ if ((need_hi22_p && (lower32 & 0x3ff) != 0)
+ /* No sethi. */
+ || (! need_hi22_p && (lower32 & 0x1fff) != 0)
+ /* Need `or' if we didn't set anything else. */
+ || (! need_hi22_p && ! need_hh22_p && ! need_hm10_p))
+ need_lo10_p = 1;
+ }
+ }
+
+ if (need_hh22_p)
+ {
+ the_insn.opcode = (SETHI_INSN | RD (upper_dstreg)
+ | ((upper32 >> 10) & 0x3fffff));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_SPARC_HH22 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+
+ if (need_hm10_p)
+ {
+ the_insn.opcode = (OR_INSN
+ | (need_hh22_p ? RS1 (upper_dstreg) : 0)
+ | RD (upper_dstreg)
+ | IMMED
+ | (upper32
+ & (need_hh22_p ? 0x3ff : 0x1fff)));
+ the_insn.reloc = (the_insn.exp.X_op != O_constant
+ ? BFD_RELOC_SPARC_HM10 : BFD_RELOC_NONE);
+ output_insn (insn, &the_insn);
+ }
+
+ if (need_hi22_p)
+ {
+ the_insn.opcode = (SETHI_INSN | RD (dstreg)
+ | ((lower32 >> 10) & 0x3fffff));
+ the_insn.reloc = BFD_RELOC_HI22;
+ output_insn (insn, &the_insn);
+ }
+
+ if (need_lo10_p)
+ {
+ /* FIXME: One nice optimization to do here is to OR the low part
+ with the highpart if hi22 isn't needed and the low part is
+ positive. */
+ the_insn.opcode = (OR_INSN | (need_hi22_p ? RS1 (dstreg) : 0)
+ | RD (dstreg)
+ | IMMED
+ | (lower32
+ & (need_hi22_p ? 0x3ff : 0x1fff)));
+ the_insn.reloc = BFD_RELOC_LO10;
+ output_insn (insn, &the_insn);
+ }
+
+ /* If we needed to build the upper part, shift it into place. */
+ if (need_hh22_p || need_hm10_p)
+ {
+ the_insn.opcode = (SLLX_INSN | RS1 (upper_dstreg) | RD (upper_dstreg)
+ | IMMED | 32);
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ }
+
+ /* If we needed to build both upper and lower parts, OR them together. */
+ if ((need_hh22_p || need_hm10_p)
+ && (need_hi22_p || need_lo10_p))
+ {
+ the_insn.opcode = (OR_INSN | RS1 (dstreg) | RS2 (upper_dstreg)
+ | RD (dstreg));
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ }
+ /* We didn't need both regs, but we may have to sign extend lower32. */
+ else if (need_hi22_p && upper32 == -1)
+ {
+ the_insn.opcode = (SRA_INSN | RS1 (dstreg) | RD (dstreg)
+ | IMMED | 0);
+ the_insn.reloc = BFD_RELOC_NONE;
+ output_insn (insn, &the_insn);
+ }
+ break;
+ }
+
+ case SPECIAL_CASE_FDIV:
+ {
+ int rd = (the_insn.opcode >> 25) & 0x1f;
+
+ output_insn (insn, &the_insn);
+
+ /* According to information leaked from Sun, the "fdiv" instructions
+ on early SPARC machines would produce incorrect results sometimes.
+ The workaround is to add an fmovs of the destination register to
+ itself just after the instruction. This was true on machines
+ with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
+ assert (the_insn.reloc == BFD_RELOC_NONE);
+ the_insn.opcode = FMOVS_INSN | rd | RD (rd);
+ output_insn (insn, &the_insn);
+ break;
+ }
+
+ default:
+ as_fatal (_("failed special case insn sanity check"));
+ }
+}
+
+/* Subroutine of md_assemble to do the actual parsing. */
+
+static void
+sparc_ip (str, pinsn)
+ char *str;
+ const struct sparc_opcode **pinsn;
+{
+ char *error_message = "";
+ char *s;
+ const char *args;
+ char c;
+ const struct sparc_opcode *insn;
+ char *argsStart;
+ unsigned long opcode;
+ unsigned int mask = 0;
+ int match = 0;
+ int comma = 0;
+ int v9_arg_p;
+
+ s = str;
+ if (islower ((unsigned char) *s))
+ {
+ do
+ ++s;
+ while (islower ((unsigned char) *s) || isdigit ((unsigned char) *s));
+ }
+
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case ',':
+ comma = 1;
+
+ /*FALLTHROUGH */
+
+ case ' ':
+ *s++ = '\0';
+ break;
+
+ default:
+ as_fatal (_("Unknown opcode: `%s'"), str);
+ }
+ insn = (struct sparc_opcode *) hash_find (op_hash, str);
+ *pinsn = insn;
+ if (insn == NULL)
+ {
+ as_bad (_("Unknown opcode: `%s'"), str);
+ return;
+ }
+ if (comma)
+ {
+ *--s = ',';
+ }
+
+ argsStart = s;
+ for (;;)
+ {
+ opcode = insn->match;
+ memset (&the_insn, '\0', sizeof (the_insn));
+ the_insn.reloc = BFD_RELOC_NONE;
+ v9_arg_p = 0;
+
+ /*
+ * Build the opcode, checking as we go to make
+ * sure that the operands match
+ */
+ for (args = insn->args;; ++args)
+ {
+ switch (*args)
+ {
+ case 'K':
+ {
+ int kmask = 0;
+
+ /* Parse a series of masks. */
+ if (*s == '#')
+ {
+ while (*s == '#')
+ {
+ int mask;
+
+ if (! parse_keyword_arg (sparc_encode_membar, &s,
+ &mask))
+ {
+ error_message = _(": invalid membar mask name");
+ goto error;
+ }
+ kmask |= mask;
+ while (*s == ' ') { ++s; continue; }
+ if (*s == '|' || *s == '+')
+ ++s;
+ while (*s == ' ') { ++s; continue; }
+ }
+ }
+ else
+ {
+ if (! parse_const_expr_arg (&s, &kmask))
+ {
+ error_message = _(": invalid membar mask expression");
+ goto error;
+ }
+ if (kmask < 0 || kmask > 127)
+ {
+ error_message = _(": invalid membar mask number");
+ goto error;
+ }
+ }
+
+ opcode |= MEMBAR (kmask);
+ continue;
+ }
+
+ case '*':
+ {
+ int fcn = 0;
+
+ /* Parse a prefetch function. */
+ if (*s == '#')
+ {
+ if (! parse_keyword_arg (sparc_encode_prefetch, &s, &fcn))
+ {
+ error_message = _(": invalid prefetch function name");
+ goto error;
+ }
+ }
+ else
+ {
+ if (! parse_const_expr_arg (&s, &fcn))
+ {
+ error_message = _(": invalid prefetch function expression");
+ goto error;
+ }
+ if (fcn < 0 || fcn > 31)
+ {
+ error_message = _(": invalid prefetch function number");
+ goto error;
+ }
+ }
+ opcode |= RD (fcn);
+ continue;
+ }
+
+ case '!':
+ case '?':
+ /* Parse a sparc64 privileged register. */
+ if (*s == '%')
+ {
+ struct priv_reg_entry *p = priv_reg_table;
+ unsigned int len = 9999999; /* init to make gcc happy */
+
+ s += 1;
+ while (p->name[0] > s[0])
+ p++;
+ while (p->name[0] == s[0])
+ {
+ len = strlen (p->name);
+ if (strncmp (p->name, s, len) == 0)
+ break;
+ p++;
+ }
+ if (p->name[0] != s[0])
+ {
+ error_message = _(": unrecognizable privileged register");
+ goto error;
+ }
+ if (*args == '?')
+ opcode |= (p->regnum << 14);
+ else
+ opcode |= (p->regnum << 25);
+ s += len;
+ continue;
+ }
+ else
+ {
+ error_message = _(": unrecognizable privileged register");
+ goto error;
+ }
+
+ case '_':
+ case '/':
+ /* Parse a v9a ancillary state register. */
+ if (*s == '%')
+ {
+ struct priv_reg_entry *p = v9a_asr_table;
+ unsigned int len = 9999999; /* init to make gcc happy */
+
+ s += 1;
+ while (p->name[0] > s[0])
+ p++;
+ while (p->name[0] == s[0])
+ {
+ len = strlen (p->name);
+ if (strncmp (p->name, s, len) == 0)
+ break;
+ p++;
+ }
+ if (p->name[0] != s[0])
+ {
+ error_message = _(": unrecognizable v9a ancillary state register");
+ goto error;
+ }
+ if (*args == '/' && (p->regnum == 20 || p->regnum == 21))
+ {
+ error_message = _(": rd on write only ancillary state register");
+ goto error;
+ }
+ if (*args == '/')
+ opcode |= (p->regnum << 14);
+ else
+ opcode |= (p->regnum << 25);
+ s += len;
+ continue;
+ }
+ else
+ {
+ error_message = _(": unrecognizable v9a ancillary state register");
+ goto error;
+ }
+
+ case 'M':
+ case 'm':
+ if (strncmp (s, "%asr", 4) == 0)
+ {
+ s += 4;
+
+ if (isdigit ((unsigned char) *s))
+ {
+ long num = 0;
+
+ while (isdigit ((unsigned char) *s))
+ {
+ num = num * 10 + *s - '0';
+ ++s;
+ }
+
+ if (current_architecture >= SPARC_OPCODE_ARCH_V9)
+ {
+ if (num < 16 || 31 < num)
+ {
+ error_message = _(": asr number must be between 16 and 31");
+ goto error;
+ }
+ }
+ else
+ {
+ if (num < 0 || 31 < num)
+ {
+ error_message = _(": asr number must be between 0 and 31");
+ goto error;
+ }
+ }
+
+ opcode |= (*args == 'M' ? RS1 (num) : RD (num));
+ continue;
+ }
+ else
+ {
+ error_message = _(": expecting %asrN");
+ goto error;
+ }
+ } /* if %asr */
+ break;
+
+ case 'I':
+ the_insn.reloc = BFD_RELOC_SPARC_11;
+ goto immediate;
+
+ case 'j':
+ the_insn.reloc = BFD_RELOC_SPARC_10;
+ goto immediate;
+
+ case 'X':
+ /* V8 systems don't understand BFD_RELOC_SPARC_5. */
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ the_insn.reloc = BFD_RELOC_SPARC_5;
+ else
+ the_insn.reloc = BFD_RELOC_SPARC13;
+ /* These fields are unsigned, but for upward compatibility,
+ allow negative values as well. */
+ goto immediate;
+
+ case 'Y':
+ /* V8 systems don't understand BFD_RELOC_SPARC_6. */
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ the_insn.reloc = BFD_RELOC_SPARC_6;
+ else
+ the_insn.reloc = BFD_RELOC_SPARC13;
+ /* These fields are unsigned, but for upward compatibility,
+ allow negative values as well. */
+ goto immediate;
+
+ case 'k':
+ the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'G':
+ the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'N':
+ if (*s == 'p' && s[1] == 'n')
+ {
+ s += 2;
+ continue;
+ }
+ break;
+
+ case 'T':
+ if (*s == 'p' && s[1] == 't')
+ {
+ s += 2;
+ continue;
+ }
+ break;
+
+ case 'z':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%icc", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'Z':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%xcc", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case '6':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc0", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '7':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc1", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '8':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc2", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '9':
+ if (*s == ' ')
+ {
+ ++s;
+ }
+ if (strncmp (s, "%fcc3", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case 'P':
+ if (strncmp (s, "%pc", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'W':
+ if (strncmp (s, "%tick", 5) == 0)
+ {
+ s += 5;
+ continue;
+ }
+ break;
+
+ case '\0': /* end of args */
+ if (*s == '\0')
+ {
+ match = 1;
+ }
+ break;
+
+ case '+':
+ if (*s == '+')
+ {
+ ++s;
+ continue;
+ }
+ if (*s == '-')
+ {
+ continue;
+ }
+ break;
+
+ case '[': /* these must match exactly */
+ case ']':
+ case ',':
+ case ' ':
+ if (*s++ == *args)
+ continue;
+ break;
+
+ case '#': /* must be at least one digit */
+ if (isdigit ((unsigned char) *s++))
+ {
+ while (isdigit ((unsigned char) *s))
+ {
+ ++s;
+ }
+ continue;
+ }
+ break;
+
+ case 'C': /* coprocessor state register */
+ if (strncmp (s, "%csr", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'b': /* next operand is a coprocessor register */
+ case 'c':
+ case 'D':
+ if (*s++ == '%' && *s++ == 'c' && isdigit ((unsigned char) *s))
+ {
+ mask = *s++;
+ if (isdigit ((unsigned char) *s))
+ {
+ mask = 10 * (mask - '0') + (*s++ - '0');
+ if (mask >= 32)
+ {
+ break;
+ }
+ }
+ else
+ {
+ mask -= '0';
+ }
+ switch (*args)
+ {
+
+ case 'b':
+ opcode |= mask << 14;
+ continue;
+
+ case 'c':
+ opcode |= mask;
+ continue;
+
+ case 'D':
+ opcode |= mask << 25;
+ continue;
+ }
+ }
+ break;
+
+ case 'r': /* next operand must be a register */
+ case 'O':
+ case '1':
+ case '2':
+ case 'd':
+ if (*s++ == '%')
+ {
+ switch (c = *s++)
+ {
+
+ case 'f': /* frame pointer */
+ if (*s++ == 'p')
+ {
+ mask = 0x1e;
+ break;
+ }
+ goto error;
+
+ case 'g': /* global register */
+ if (isoctal (c = *s++))
+ {
+ mask = c - '0';
+ break;
+ }
+ goto error;
+
+ case 'i': /* in register */
+ if (isoctal (c = *s++))
+ {
+ mask = c - '0' + 24;
+ break;
+ }
+ goto error;
+
+ case 'l': /* local register */
+ if (isoctal (c = *s++))
+ {
+ mask = (c - '0' + 16);
+ break;
+ }
+ goto error;
+
+ case 'o': /* out register */
+ if (isoctal (c = *s++))
+ {
+ mask = (c - '0' + 8);
+ break;
+ }
+ goto error;
+
+ case 's': /* stack pointer */
+ if (*s++ == 'p')
+ {
+ mask = 0xe;
+ break;
+ }
+ goto error;
+
+ case 'r': /* any register */
+ if (!isdigit ((unsigned char) (c = *s++)))
+ {
+ goto error;
+ }
+ /* FALLTHROUGH */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (isdigit ((unsigned char) *s))
+ {
+ if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
+ {
+ goto error;
+ }
+ }
+ else
+ {
+ c -= '0';
+ }
+ mask = c;
+ break;
+
+ default:
+ goto error;
+ }
+
+ /* Got the register, now figure out where
+ it goes in the opcode. */
+ switch (*args)
+ {
+ case '1':
+ opcode |= mask << 14;
+ continue;
+
+ case '2':
+ opcode |= mask;
+ continue;
+
+ case 'd':
+ opcode |= mask << 25;
+ continue;
+
+ case 'r':
+ opcode |= (mask << 25) | (mask << 14);
+ continue;
+
+ case 'O':
+ opcode |= (mask << 25) | (mask << 0);
+ continue;
+ }
+ }
+ break;
+
+ case 'e': /* next operand is a floating point register */
+ case 'v':
+ case 'V':
+
+ case 'f':
+ case 'B':
+ case 'R':
+
+ case 'g':
+ case 'H':
+ case 'J':
+ {
+ char format;
+
+ if (*s++ == '%'
+ && ((format = *s) == 'f')
+ && isdigit ((unsigned char) *++s))
+ {
+ for (mask = 0; isdigit ((unsigned char) *s); ++s)
+ {
+ mask = 10 * mask + (*s - '0');
+ } /* read the number */
+
+ if ((*args == 'v'
+ || *args == 'B'
+ || *args == 'H')
+ && (mask & 1))
+ {
+ break;
+ } /* register must be even numbered */
+
+ if ((*args == 'V'
+ || *args == 'R'
+ || *args == 'J')
+ && (mask & 3))
+ {
+ break;
+ } /* register must be multiple of 4 */
+
+ if (mask >= 64)
+ {
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ error_message = _(": There are only 64 f registers; [0-63]");
+ else
+ error_message = _(": There are only 32 f registers; [0-31]");
+ goto error;
+ } /* on error */
+ else if (mask >= 32)
+ {
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
+ {
+ v9_arg_p = 1;
+ mask -= 31; /* wrap high bit */
+ }
+ else
+ {
+ error_message = _(": There are only 32 f registers; [0-31]");
+ goto error;
+ }
+ }
+ }
+ else
+ {
+ break;
+ } /* if not an 'f' register. */
+
+ switch (*args)
+ {
+ case 'v':
+ case 'V':
+ case 'e':
+ opcode |= RS1 (mask);
+ continue;
+
+
+ case 'f':
+ case 'B':
+ case 'R':
+ opcode |= RS2 (mask);
+ continue;
+
+ case 'g':
+ case 'H':
+ case 'J':
+ opcode |= RD (mask);
+ continue;
+ } /* pack it in. */
+
+ know (0);
+ break;
+ } /* float arg */
+
+ case 'F':
+ if (strncmp (s, "%fsr", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case '0': /* 64 bit immediate (setx insn) */
+ the_insn.reloc = BFD_RELOC_NONE; /* reloc handled elsewhere */
+ goto immediate;
+
+ case 'h': /* high 22 bits */
+ the_insn.reloc = BFD_RELOC_HI22;
+ goto immediate;
+
+ case 'l': /* 22 bit PC relative immediate */
+ the_insn.reloc = BFD_RELOC_SPARC_WDISP22;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'L': /* 30 bit immediate */
+ the_insn.reloc = BFD_RELOC_32_PCREL_S2;
+ the_insn.pcrel = 1;
+ goto immediate;
+
+ case 'n': /* 22 bit immediate */
+ the_insn.reloc = BFD_RELOC_SPARC22;
+ goto immediate;
+
+ case 'i': /* 13 bit immediate */
+ the_insn.reloc = BFD_RELOC_SPARC13;
+
+ /* fallthrough */
+
+ immediate:
+ if (*s == ' ')
+ s++;
+
+ /* Check for %hi, etc. */
+ if (*s == '%')
+ {
+ static struct ops {
+ /* The name as it appears in assembler. */
+ char *name;
+ /* strlen (name), precomputed for speed */
+ int len;
+ /* The reloc this pseudo-op translates to. */
+ int reloc;
+ /* Non-zero if for v9 only. */
+ int v9_p;
+ /* Non-zero if can be used in pc-relative contexts. */
+ int pcrel_p;/*FIXME:wip*/
+ } ops[] = {
+ /* hix/lox must appear before hi/lo so %hix won't be
+ mistaken for %hi. */
+ { "hix", 3, BFD_RELOC_SPARC_HIX22, 1, 0 },
+ { "lox", 3, BFD_RELOC_SPARC_LOX10, 1, 0 },
+ { "hi", 2, BFD_RELOC_HI22, 0, 1 },
+ { "lo", 2, BFD_RELOC_LO10, 0, 1 },
+ { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 },
+ { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 },
+ { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 },
+ { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 },
+ { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 },
+ { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 },
+ { "uhi", 3, BFD_RELOC_SPARC_HH22, 1, 0 },
+ { "ulo", 3, BFD_RELOC_SPARC_HM10, 1, 0 },
+ { NULL }
+ };
+ struct ops *o;
+
+ for (o = ops; o->name; o++)
+ if (strncmp (s + 1, o->name, o->len) == 0)
+ break;
+ if (o->name == NULL)
+ break;
+
+ the_insn.reloc = o->reloc;
+ s += o->len + 1;
+ v9_arg_p = o->v9_p;
+ }
+
+ /* Note that if the get_expression() fails, we will still
+ have created U entries in the symbol table for the
+ 'symbols' in the input string. Try not to create U
+ symbols for registers, etc. */
+ {
+ /* This stuff checks to see if the expression ends in
+ +%reg. If it does, it removes the register from
+ the expression, and re-sets 's' to point to the
+ right place. */
+
+ char *s1;
+
+ for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;
+
+ if (s1 != s && isdigit ((unsigned char) s1[-1]))
+ {
+ if (s1[-2] == '%' && s1[-3] == '+')
+ {
+ s1 -= 3;
+ *s1 = '\0';
+ (void) get_expression (s);
+ *s1 = '+';
+ s = s1;
+ continue;
+ }
+ else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
+ {
+ s1 -= 4;
+ *s1 = '\0';
+ (void) get_expression (s);
+ *s1 = '+';
+ s = s1;
+ continue;
+ }
+ }
+ }
+ (void) get_expression (s);
+ s = expr_end;
+
+ /* Check for constants that don't require emitting a reloc. */
+ if (the_insn.exp.X_op == O_constant
+ && the_insn.exp.X_add_symbol == 0
+ && the_insn.exp.X_op_symbol == 0)
+ {
+ /* For pc-relative call instructions, we reject
+ constants to get better code. */
+ if (the_insn.pcrel
+ && the_insn.reloc == BFD_RELOC_32_PCREL_S2
+ && in_signed_range (the_insn.exp.X_add_number, 0x3fff))
+ {
+ error_message = _(": PC-relative operand can't be a constant");
+ goto error;
+ }
+
+ /* Constants that won't fit are checked in md_apply_fix3
+ and bfd_install_relocation.
+ ??? It would be preferable to install the constants
+ into the insn here and save having to create a fixS
+ for each one. There already exists code to handle
+ all the various cases (e.g. in md_apply_fix3 and
+ bfd_install_relocation) so duplicating all that code
+ here isn't right. */
+ }
+
+ continue;
+
+ case 'a':
+ if (*s++ == 'a')
+ {
+ opcode |= ANNUL;
+ continue;
+ }
+ break;
+
+ case 'A':
+ {
+ int asi = 0;
+
+ /* Parse an asi. */
+ if (*s == '#')
+ {
+ if (! parse_keyword_arg (sparc_encode_asi, &s, &asi))
+ {
+ error_message = _(": invalid ASI name");
+ goto error;
+ }
+ }
+ else
+ {
+ if (! parse_const_expr_arg (&s, &asi))
+ {
+ error_message = _(": invalid ASI expression");
+ goto error;
+ }
+ if (asi < 0 || asi > 255)
+ {
+ error_message = _(": invalid ASI number");
+ goto error;
+ }
+ }
+ opcode |= ASI (asi);
+ continue;
+ } /* alternate space */
+
+ case 'p':
+ if (strncmp (s, "%psr", 4) == 0)
+ {
+ s += 4;
+ continue;
+ }
+ break;
+
+ case 'q': /* floating point queue */
+ if (strncmp (s, "%fq", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'Q': /* coprocessor queue */
+ if (strncmp (s, "%cq", 3) == 0)
+ {
+ s += 3;
+ continue;
+ }
+ break;
+
+ case 'S':
+ if (strcmp (str, "set") == 0
+ || strcmp (str, "setuw") == 0)
+ {
+ special_case = SPECIAL_CASE_SET;
+ continue;
+ }
+ else if (strcmp (str, "setsw") == 0)
+ {
+ special_case = SPECIAL_CASE_SETSW;
+ continue;
+ }
+ else if (strcmp (str, "setx") == 0)
+ {
+ special_case = SPECIAL_CASE_SETX;
+ continue;
+ }
+ else if (strncmp (str, "fdiv", 4) == 0)
+ {
+ special_case = SPECIAL_CASE_FDIV;
+ continue;
+ }
+ break;
+
+ case 'o':
+ if (strncmp (s, "%asi", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 's':
+ if (strncmp (s, "%fprs", 5) != 0)
+ break;
+ s += 5;
+ continue;
+
+ case 'E':
+ if (strncmp (s, "%ccr", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 't':
+ if (strncmp (s, "%tbr", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 'w':
+ if (strncmp (s, "%wim", 4) != 0)
+ break;
+ s += 4;
+ continue;
+
+ case 'x':
+ {
+ char *push = input_line_pointer;
+ expressionS e;
+
+ input_line_pointer = s;
+ expression (&e);
+ if (e.X_op == O_constant)
+ {
+ int n = e.X_add_number;
+ if (n != e.X_add_number || (n & ~0x1ff) != 0)
+ as_bad (_("OPF immediate operand out of range (0-0x1ff)"));
+ else
+ opcode |= e.X_add_number << 5;
+ }
+ else
+ as_bad (_("non-immediate OPF operand, ignored"));
+ s = input_line_pointer;
+ input_line_pointer = push;
+ continue;
+ }
+
+ case 'y':
+ if (strncmp (s, "%y", 2) != 0)
+ break;
+ s += 2;
+ continue;
+
+ case 'u':
+ case 'U':
+ {
+ /* Parse a sparclet cpreg. */
+ int cpreg;
+ if (! parse_keyword_arg (sparc_encode_sparclet_cpreg, &s, &cpreg))
+ {
+ error_message = _(": invalid cpreg name");
+ goto error;
+ }
+ opcode |= (*args == 'U' ? RS1 (cpreg) : RD (cpreg));
+ continue;
+ }
+
+ default:
+ as_fatal (_("failed sanity check."));
+ } /* switch on arg code */
+
+ /* Break out of for() loop. */
+ break;
+ } /* for each arg that we expect */
+
+ error:
+ if (match == 0)
+ {
+ /* Args don't match. */
+ if (&insn[1] - sparc_opcodes < sparc_num_opcodes
+ && (insn->name == insn[1].name
+ || !strcmp (insn->name, insn[1].name)))
+ {
+ ++insn;
+ s = argsStart;
+ continue;
+ }
+ else
+ {
+ as_bad (_("Illegal operands%s"), error_message);
+ return;
+ }
+ }
+ else
+ {
+ /* We have a match. Now see if the architecture is ok. */
+ int needed_arch_mask = insn->architecture;
+
+ if (v9_arg_p)
+ {
+ needed_arch_mask &= ~ ((1 << SPARC_OPCODE_ARCH_V9)
+ | (1 << SPARC_OPCODE_ARCH_V9A));
+ needed_arch_mask |= (1 << SPARC_OPCODE_ARCH_V9);
+ }
+
+ if (needed_arch_mask & SPARC_OPCODE_SUPPORTED (current_architecture))
+ ; /* ok */
+ /* Can we bump up the architecture? */
+ else if (needed_arch_mask & SPARC_OPCODE_SUPPORTED (max_architecture))
+ {
+ enum sparc_opcode_arch_val needed_architecture =
+ sparc_ffs (SPARC_OPCODE_SUPPORTED (max_architecture)
+ & needed_arch_mask);
+
+ assert (needed_architecture <= SPARC_OPCODE_ARCH_MAX);
+ if (warn_on_bump
+ && needed_architecture > warn_after_architecture)
+ {
+ as_warn (_("architecture bumped from \"%s\" to \"%s\" on \"%s\""),
+ sparc_opcode_archs[current_architecture].name,
+ sparc_opcode_archs[needed_architecture].name,
+ str);
+ warn_after_architecture = needed_architecture;
+ }
+ current_architecture = needed_architecture;
+ }
+ /* Conflict. */
+ /* ??? This seems to be a bit fragile. What if the next entry in
+ the opcode table is the one we want and it is supported?
+ It is possible to arrange the table today so that this can't
+ happen but what about tomorrow? */
+ else
+ {
+ int arch,printed_one_p = 0;
+ char *p;
+ char required_archs[SPARC_OPCODE_ARCH_MAX * 16];
+
+ /* Create a list of the architectures that support the insn. */
+ needed_arch_mask &= ~ SPARC_OPCODE_SUPPORTED (max_architecture);
+ p = required_archs;
+ arch = sparc_ffs (needed_arch_mask);
+ while ((1 << arch) <= needed_arch_mask)
+ {
+ if ((1 << arch) & needed_arch_mask)
+ {
+ if (printed_one_p)
+ *p++ = '|';
+ strcpy (p, sparc_opcode_archs[arch].name);
+ p += strlen (p);
+ printed_one_p = 1;
+ }
+ ++arch;
+ }
+
+ as_bad (_("Architecture mismatch on \"%s\"."), str);
+ as_tsktsk (_(" (Requires %s; requested architecture is %s.)"),
+ required_archs,
+ sparc_opcode_archs[max_architecture].name);
+ return;
+ }
+ } /* if no match */
+
+ break;
+ } /* forever looking for a match */
+
+ the_insn.opcode = opcode;
+}
+
+/* Parse an argument that can be expressed as a keyword.
+ (eg: #StoreStore or %ccfr).
+ The result is a boolean indicating success.
+ If successful, INPUT_POINTER is updated. */
+
+static int
+parse_keyword_arg (lookup_fn, input_pointerP, valueP)
+ int (*lookup_fn) PARAMS ((const char *));
+ char **input_pointerP;
+ int *valueP;
+{
+ int value;
+ char c, *p, *q;
+
+ p = *input_pointerP;
+ for (q = p + (*p == '#' || *p == '%');
+ isalnum ((unsigned char) *q) || *q == '_';
+ ++q)
+ continue;
+ c = *q;
+ *q = 0;
+ value = (*lookup_fn) (p);
+ *q = c;
+ if (value == -1)
+ return 0;
+ *valueP = value;
+ *input_pointerP = q;
+ return 1;
+}
+
+/* Parse an argument that is a constant expression.
+ The result is a boolean indicating success. */
+
+static int
+parse_const_expr_arg (input_pointerP, valueP)
+ char **input_pointerP;
+ int *valueP;
+{
+ char *save = input_line_pointer;
+ expressionS exp;
+
+ input_line_pointer = *input_pointerP;
+ /* The next expression may be something other than a constant
+ (say if we're not processing the right variant of the insn).
+ Don't call expression unless we're sure it will succeed as it will
+ signal an error (which we want to defer until later). */
+ /* FIXME: It might be better to define md_operand and have it recognize
+ things like %asi, etc. but continuing that route through to the end
+ is a lot of work. */
+ if (*input_line_pointer == '%')
+ {
+ input_line_pointer = save;
+ return 0;
+ }
+ expression (&exp);
+ *input_pointerP = input_line_pointer;
+ input_line_pointer = save;
+ if (exp.X_op != O_constant)
+ return 0;
+ *valueP = exp.X_add_number;
+ return 1;
+}
+
+/* Subroutine of sparc_ip to parse an expression. */
+
+static int
+get_expression (str)
+ char *str;
+{
+ char *save_in;
+ segT seg;
+
+ save_in = input_line_pointer;
+ input_line_pointer = str;
+ seg = expression (&the_insn.exp);
+ if (seg != absolute_section
+ && seg != text_section
+ && seg != data_section
+ && seg != bss_section
+ && seg != undefined_section)
+ {
+ the_insn.error = _("bad segment");
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 1;
+ }
+ expr_end = input_line_pointer;
+ input_line_pointer = save_in;
+ return 0;
+}
+
+/* Subroutine of md_assemble to output one insn. */
+
+static void
+output_insn (insn, the_insn)
+ const struct sparc_opcode *insn;
+ struct sparc_it *the_insn;
+{
+ char *toP = frag_more (4);
+
+ /* put out the opcode */
+ if (INSN_BIG_ENDIAN)
+ number_to_chars_bigendian (toP, (valueT) the_insn->opcode, 4);
+ else
+ number_to_chars_littleendian (toP, (valueT) the_insn->opcode, 4);
+
+ /* put out the symbol-dependent stuff */
+ if (the_insn->reloc != BFD_RELOC_NONE)
+ {
+ fixS *fixP = fix_new_exp (frag_now, /* which frag */
+ (toP - frag_now->fr_literal), /* where */
+ 4, /* size */
+ &the_insn->exp,
+ the_insn->pcrel,
+ the_insn->reloc);
+ /* Turn off overflow checking in fixup_segment. We'll do our
+ own overflow checking in md_apply_fix3. This is necessary because
+ the insn size is 4 and fixup_segment will signal an overflow for
+ large 8 byte quantities. */
+ fixP->fx_no_overflow = 1;
+ }
+
+ last_insn = insn;
+ last_opcode = the_insn->opcode;
+}
+
+/*
+ This is identical to the md_atof in m68k.c. I think this is right,
+ but I'm not sure.
+
+ Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int i,prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ char *t;
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ if (target_big_endian)
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+ else
+ {
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ }
+
+ return 0;
+}
+
+/* Write a value out to the object file, using the appropriate
+ endianness. */
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if (target_big_endian)
+ number_to_chars_bigendian (buf, val, n);
+ else if (target_little_endian_data
+ && ((n == 4 || n == 2) && ~now_seg->flags & SEC_ALLOC))
+ /* Output debug words, which are not in allocated sections, as big endian */
+ number_to_chars_bigendian (buf, val, n);
+ else if (target_little_endian_data || ! target_big_endian)
+ number_to_chars_littleendian (buf, val, n);
+}
+
+/* Apply a fixS to the frags, now that we know the value it ought to
+ hold. */
+
+int
+md_apply_fix3 (fixP, value, segment)
+ fixS *fixP;
+ valueT *value;
+ segT segment;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ offsetT val;
+ long insn;
+
+ val = *value;
+
+ assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+
+ fixP->fx_addnumber = val; /* Remember value for emit_reloc */
+
+#ifdef OBJ_ELF
+ /* FIXME: SPARC ELF relocations don't use an addend in the data
+ field itself. This whole approach should be somehow combined
+ with the calls to bfd_install_relocation. Also, the value passed
+ in by fixup_segment includes the value of a defined symbol. We
+ don't want to include the value of an externally visible symbol. */
+ if (fixP->fx_addsy != NULL)
+ {
+ if (fixP->fx_addsy->sy_used_in_reloc
+ && (S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy)
+ || (sparc_pic_code && ! fixP->fx_pcrel)
+ || (S_GET_SEGMENT (fixP->fx_addsy) != segment
+ && ((bfd_get_section_flags (stdoutput,
+ S_GET_SEGMENT (fixP->fx_addsy))
+ & SEC_LINK_ONCE) != 0
+ || strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
+ ".gnu.linkonce",
+ sizeof ".gnu.linkonce" - 1) == 0)))
+ && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section
+ && S_GET_SEGMENT (fixP->fx_addsy) != undefined_section
+ && ! bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)))
+ fixP->fx_addnumber -= S_GET_VALUE (fixP->fx_addsy);
+ return 1;
+ }
+#endif
+
+ /* This is a hack. There should be a better way to
+ handle this. Probably in terms of howto fields, once
+ we can look at these fixups in terms of howtos. */
+ if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
+ val += fixP->fx_where + fixP->fx_frag->fr_address;
+
+#ifdef OBJ_AOUT
+ /* FIXME: More ridiculous gas reloc hacking. If we are going to
+ generate a reloc, then we just want to let the reloc addend set
+ the value. We do not want to also stuff the addend into the
+ object file. Including the addend in the object file works when
+ doing a static link, because the linker will ignore the object
+ file contents. However, the dynamic linker does not ignore the
+ object file contents. */
+ if (fixP->fx_addsy != NULL
+ && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2)
+ val = 0;
+
+ /* When generating PIC code, we do not want an addend for a reloc
+ against a local symbol. We adjust fx_addnumber to cancel out the
+ value already included in val, and to also cancel out the
+ adjustment which bfd_install_relocation will create. */
+ if (sparc_pic_code
+ && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2
+ && fixP->fx_addsy != NULL
+ && ! S_IS_COMMON (fixP->fx_addsy)
+ && (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) == 0)
+ fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
+
+ /* When generating PIC code, we need to fiddle to get
+ bfd_install_relocation to do the right thing for a PC relative
+ reloc against a local symbol which we are going to keep. */
+ if (sparc_pic_code
+ && fixP->fx_r_type == BFD_RELOC_32_PCREL_S2
+ && fixP->fx_addsy != NULL
+ && (S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy))
+ && S_IS_DEFINED (fixP->fx_addsy)
+ && ! S_IS_COMMON (fixP->fx_addsy))
+ {
+ val = 0;
+ fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
+ }
+#endif
+
+ /* If this is a data relocation, just output VAL. */
+
+ if (fixP->fx_r_type == BFD_RELOC_16)
+ {
+ md_number_to_chars (buf, val, 2);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_32
+ || fixP->fx_r_type == BFD_RELOC_SPARC_REV32)
+ {
+ md_number_to_chars (buf, val, 4);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_64)
+ {
+ md_number_to_chars (buf, val, 8);
+ }
+ else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ fixP->fx_done = 0;
+ return 1;
+ }
+ else
+ {
+ /* It's a relocation against an instruction. */
+
+ if (INSN_BIG_ENDIAN)
+ insn = bfd_getb32 ((unsigned char *) buf);
+ else
+ insn = bfd_getl32 ((unsigned char *) buf);
+
+ switch (fixP->fx_r_type)
+ {
+ case BFD_RELOC_32_PCREL_S2:
+ val = val >> 2;
+ /* FIXME: This increment-by-one deserves a comment of why it's
+ being done! */
+ if (! sparc_pic_code
+ || fixP->fx_addsy == NULL
+ || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
+ ++val;
+ insn |= val & 0x3fffffff;
+ break;
+
+ case BFD_RELOC_SPARC_11:
+ if (! in_signed_range (val, 0x7ff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x7ff;
+ break;
+
+ case BFD_RELOC_SPARC_10:
+ if (! in_signed_range (val, 0x3ff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x3ff;
+ break;
+
+ case BFD_RELOC_SPARC_7:
+ if (! in_bitfield_range (val, 0x7f))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x7f;
+ break;
+
+ case BFD_RELOC_SPARC_6:
+ if (! in_bitfield_range (val, 0x3f))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x3f;
+ break;
+
+ case BFD_RELOC_SPARC_5:
+ if (! in_bitfield_range (val, 0x1f))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x1f;
+ break;
+
+ case BFD_RELOC_SPARC_WDISP16:
+ /* FIXME: simplify */
+ if (((val > 0) && (val & ~0x3fffc))
+ || ((val < 0) && (~(val - 1) & ~0x3fffc)))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ /* FIXME: The +1 deserves a comment. */
+ val = (val >> 2) + 1;
+ insn |= ((val & 0xc000) << 6) | (val & 0x3fff);
+ break;
+
+ case BFD_RELOC_SPARC_WDISP19:
+ /* FIXME: simplify */
+ if (((val > 0) && (val & ~0x1ffffc))
+ || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ /* FIXME: The +1 deserves a comment. */
+ val = (val >> 2) + 1;
+ insn |= val & 0x7ffff;
+ break;
+
+ case BFD_RELOC_SPARC_HH22:
+ val = BSR (val, 32);
+ /* intentional fallthrough */
+
+ case BFD_RELOC_SPARC_LM22:
+ case BFD_RELOC_HI22:
+ if (!fixP->fx_addsy)
+ {
+ insn |= (val >> 10) & 0x3fffff;
+ }
+ else
+ {
+ /* FIXME: Need comment explaining why we do this. */
+ insn &= ~0xffff;
+ }
+ break;
+
+ case BFD_RELOC_SPARC22:
+ if (val & ~0x003fffff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= (val & 0x3fffff);
+ break;
+
+ case BFD_RELOC_SPARC_HM10:
+ val = BSR (val, 32);
+ /* intentional fallthrough */
+
+ case BFD_RELOC_LO10:
+ if (!fixP->fx_addsy)
+ {
+ insn |= val & 0x3ff;
+ }
+ else
+ {
+ /* FIXME: Need comment explaining why we do this. */
+ insn &= ~0xff;
+ }
+ break;
+
+ case BFD_RELOC_SPARC13:
+ if (! in_signed_range (val, 0x1fff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("relocation overflow"));
+ insn |= val & 0x1fff;
+ break;
+
+ case BFD_RELOC_SPARC_WDISP22:
+ val = (val >> 2) + 1;
+ /* FALLTHROUGH */
+ case BFD_RELOC_SPARC_BASE22:
+ insn |= val & 0x3fffff;
+ break;
+
+ case BFD_RELOC_SPARC_H44:
+ if (!fixP->fx_addsy)
+ {
+ bfd_vma tval = val;
+ tval >>= 22;
+ insn |= tval & 0x3fffff;
+ }
+ break;
+
+ case BFD_RELOC_SPARC_M44:
+ if (!fixP->fx_addsy)
+ insn |= (val >> 12) & 0x3ff;
+ break;
+
+ case BFD_RELOC_SPARC_L44:
+ if (!fixP->fx_addsy)
+ insn |= val & 0xfff;
+ break;
+
+ case BFD_RELOC_SPARC_HIX22:
+ if (!fixP->fx_addsy)
+ {
+ val ^= ~ (offsetT) 0;
+ insn |= (val >> 10) & 0x3fffff;
+ }
+ break;
+
+ case BFD_RELOC_SPARC_LOX10:
+ if (!fixP->fx_addsy)
+ insn |= 0x1c00 | (val & 0x3ff);
+ break;
+
+ case BFD_RELOC_NONE:
+ default:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad or unhandled relocation type: 0x%02x"),
+ fixP->fx_r_type);
+ break;
+ }
+
+ if (INSN_BIG_ENDIAN)
+ bfd_putb32 (insn, (unsigned char *) buf);
+ else
+ bfd_putl32 (insn, (unsigned char *) buf);
+ }
+
+ /* Are we finished with this relocation now? */
+ if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
+ fixP->fx_done = 1;
+
+ return 1;
+}
+
+/* Translate internal representation of relocation info to BFD target
+ format. */
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_16:
+ case BFD_RELOC_32:
+ case BFD_RELOC_HI22:
+ case BFD_RELOC_LO10:
+ case BFD_RELOC_32_PCREL_S2:
+ case BFD_RELOC_SPARC13:
+ case BFD_RELOC_SPARC_BASE13:
+ case BFD_RELOC_SPARC_WDISP16:
+ case BFD_RELOC_SPARC_WDISP19:
+ case BFD_RELOC_SPARC_WDISP22:
+ case BFD_RELOC_64:
+ case BFD_RELOC_SPARC_5:
+ case BFD_RELOC_SPARC_6:
+ case BFD_RELOC_SPARC_7:
+ case BFD_RELOC_SPARC_10:
+ case BFD_RELOC_SPARC_11:
+ case BFD_RELOC_SPARC_HH22:
+ case BFD_RELOC_SPARC_HM10:
+ case BFD_RELOC_SPARC_LM22:
+ case BFD_RELOC_SPARC_PC_HH22:
+ case BFD_RELOC_SPARC_PC_HM10:
+ case BFD_RELOC_SPARC_PC_LM22:
+ case BFD_RELOC_SPARC_H44:
+ case BFD_RELOC_SPARC_M44:
+ case BFD_RELOC_SPARC_L44:
+ case BFD_RELOC_SPARC_HIX22:
+ case BFD_RELOC_SPARC_LOX10:
+ case BFD_RELOC_SPARC_REV32:
+ case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_VTABLE_INHERIT:
+ code = fixp->fx_r_type;
+ break;
+ default:
+ abort ();
+ return NULL;
+ }
+
+#if defined (OBJ_ELF) || defined (OBJ_AOUT)
+ /* If we are generating PIC code, we need to generate a different
+ set of relocs. */
+
+#ifdef OBJ_ELF
+#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
+#else
+#define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
+#endif
+
+ if (sparc_pic_code)
+ {
+ switch (code)
+ {
+ case BFD_RELOC_32_PCREL_S2:
+ if (! S_IS_DEFINED (fixp->fx_addsy)
+ || S_IS_COMMON (fixp->fx_addsy)
+ || S_IS_EXTERNAL (fixp->fx_addsy)
+ || S_IS_WEAK (fixp->fx_addsy))
+ code = BFD_RELOC_SPARC_WPLT30;
+ break;
+ case BFD_RELOC_HI22:
+ if (fixp->fx_addsy != NULL
+ && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+ code = BFD_RELOC_SPARC_PC22;
+ else
+ code = BFD_RELOC_SPARC_GOT22;
+ break;
+ case BFD_RELOC_LO10:
+ if (fixp->fx_addsy != NULL
+ && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+ code = BFD_RELOC_SPARC_PC10;
+ else
+ code = BFD_RELOC_SPARC_GOT10;
+ break;
+ case BFD_RELOC_SPARC13:
+ code = BFD_RELOC_SPARC_GOT13;
+ break;
+ default:
+ break;
+ }
+ }
+#endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (reloc->howto == 0)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal error: can't export reloc type %d (`%s')"),
+ fixp->fx_r_type, bfd_get_reloc_code_name (code));
+ return 0;
+ }
+
+ /* @@ Why fx_addnumber sometimes and fx_offset other times? */
+#ifdef OBJ_AOUT
+
+ if (reloc->howto->pc_relative == 0
+ || code == BFD_RELOC_SPARC_PC10
+ || code == BFD_RELOC_SPARC_PC22)
+ reloc->addend = fixp->fx_addnumber;
+ else if (sparc_pic_code
+ && fixp->fx_r_type == BFD_RELOC_32_PCREL_S2
+ && fixp->fx_addsy != NULL
+ && (S_IS_EXTERNAL (fixp->fx_addsy)
+ || S_IS_WEAK (fixp->fx_addsy))
+ && S_IS_DEFINED (fixp->fx_addsy)
+ && ! S_IS_COMMON (fixp->fx_addsy))
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = fixp->fx_offset - reloc->address;
+
+#else /* elf or coff */
+
+ if (reloc->howto->pc_relative == 0
+ || code == BFD_RELOC_SPARC_PC10
+ || code == BFD_RELOC_SPARC_PC22)
+ reloc->addend = fixp->fx_addnumber;
+ else if ((fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
+ reloc->addend = (section->vma
+ + fixp->fx_addnumber
+ + md_pcrel_from (fixp));
+ else
+ reloc->addend = fixp->fx_offset;
+#endif
+
+ return reloc;
+}
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+} /* md_undefined_symbol() */
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+#ifndef OBJ_ELF
+ /* This is not right for ELF; a.out wants it, and COFF will force
+ the alignment anyways. */
+ valueT align = ((valueT) 1
+ << (valueT) bfd_get_section_alignment (stdoutput, segment));
+ valueT newsize;
+ /* turn alignment value into a mask */
+ align--;
+ newsize = (size + align) & ~align;
+ return newsize;
+#else
+ return size;
+#endif
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the sparc, they're relative to the address of the offset, plus
+ its size. This gets us to the following instruction.
+ (??? Is this right? FIXME-SOON) */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ long ret;
+
+ ret = fixP->fx_where + fixP->fx_frag->fr_address;
+ if (! sparc_pic_code
+ || fixP->fx_addsy == NULL
+ || (fixP->fx_addsy->bsym->flags & BSF_SECTION_SYM) != 0)
+ ret += fixP->fx_size;
+ return ret;
+}
+
+/* Return log2 (VALUE), or -1 if VALUE is not an exact positive power
+ of two. */
+
+static int
+log2 (value)
+ int value;
+{
+ int shift;
+
+ if (value <= 0)
+ return -1;
+
+ for (shift = 0; (value & 1) == 0; value >>= 1)
+ ++shift;
+
+ return (value == 1) ? shift : -1;
+}
+
+/*
+ * sort of like s_lcomm
+ */
+
+#ifndef OBJ_ELF
+static int max_alignment = 15;
+#endif
+
+static void
+s_reserve (ignore)
+ int ignore;
+{
+ char *name;
+ char *p;
+ char c;
+ int align;
+ int size;
+ int temp;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after name"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+
+ if ((size = get_absolute_expression ()) < 0)
+ {
+ as_bad (_("BSS length (%d.) <0! Ignored."), size);
+ ignore_rest_of_line ();
+ return;
+ } /* bad length */
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
+ && strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
+ {
+ as_bad (_("bad .reserve segment -- expected BSS segment"));
+ return;
+ }
+
+ if (input_line_pointer[2] == '.')
+ input_line_pointer += 7;
+ else
+ input_line_pointer += 6;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ {
+ as_bad (_("missing alignment"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ align = (int) get_absolute_expression ();
+
+#ifndef OBJ_ELF
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_warn (_("alignment too large; assuming %d"), align);
+ }
+#endif
+
+ if (align < 0)
+ {
+ as_bad (_("negative alignment"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (align != 0)
+ {
+ temp = log2 (align);
+ if (temp < 0)
+ {
+ as_bad (_("alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ align = temp;
+ }
+
+ record_alignment (bss_section, align);
+ }
+ else
+ align = 0;
+
+ if (!S_IS_DEFINED (symbolP)
+#ifdef OBJ_AOUT
+ && S_GET_OTHER (symbolP) == 0
+ && S_GET_DESC (symbolP) == 0
+#endif
+ )
+ {
+ if (! need_pass_2)
+ {
+ char *pfrag;
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+
+ subseg_set (bss_section, 1); /* switch to bss */
+
+ if (align)
+ frag_align (align, 0, 0); /* do alignment */
+
+ /* detach from old frag */
+ if (S_GET_SEGMENT(symbolP) == bss_section)
+ symbolP->sy_frag->fr_symbol = NULL;
+
+ symbolP->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
+ (offsetT) size, (char *)0);
+ *pfrag = 0;
+
+ S_SET_SEGMENT (symbolP, bss_section);
+
+ subseg_set (current_seg, current_subseg);
+
+#ifdef OBJ_ELF
+ S_SET_SIZE (symbolP, size);
+#endif
+ }
+ }
+ else
+ {
+ as_warn("Ignoring attempt to re-define symbol %s",
+ S_GET_NAME (symbolP));
+ } /* if not redefining */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_common (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+ char *p;
+ int temp, size;
+ symbolS *symbolP;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++; /* skip ',' */
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+ size = temp;
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+ if (S_GET_VALUE (symbolP) != 0)
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) size)
+ {
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ }
+ }
+ else
+ {
+#ifndef OBJ_ELF
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_EXTERNAL (symbolP);
+#endif
+ }
+ know (symbolP->sy_frag == &zero_address_frag);
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after common length"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '"')
+ {
+ temp = get_absolute_expression ();
+
+#ifndef OBJ_ELF
+ if (temp > max_alignment)
+ {
+ temp = max_alignment;
+ as_warn (_("alignment too large; assuming %d"), temp);
+ }
+#endif
+
+ if (temp < 0)
+ {
+ as_bad (_("negative alignment"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+#ifdef OBJ_ELF
+ if (symbolP->local)
+ {
+ segT old_sec;
+ int old_subsec;
+ char *p;
+ int align;
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+
+ if (temp == 0)
+ align = 0;
+ else
+ align = log2 (temp);
+
+ if (align < 0)
+ {
+ as_bad (_("alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ record_alignment (bss_section, align);
+ subseg_set (bss_section, 0);
+ if (align)
+ frag_align (align, 0, 0);
+ if (S_GET_SEGMENT (symbolP) == bss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ symbolP->sy_frag = frag_now;
+ p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *p = 0;
+ S_SET_SEGMENT (symbolP, bss_section);
+ S_CLEAR_EXTERNAL (symbolP);
+ S_SET_SIZE (symbolP, size);
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+#endif /* OBJ_ELF */
+ {
+ allocate_common:
+ S_SET_VALUE (symbolP, (valueT) size);
+#ifdef OBJ_ELF
+ S_SET_ALIGN (symbolP, temp);
+ S_SET_SIZE (symbolP, size);
+#endif
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ }
+ }
+ else
+ {
+ input_line_pointer++;
+ /* @@ Some use the dot, some don't. Can we get some consistency?? */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+ /* @@ Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4)
+ && strncmp (input_line_pointer, "data\"", 5))
+ {
+ while (*--input_line_pointer != '"')
+ ;
+ input_line_pointer--;
+ goto bad_common_segment;
+ }
+ while (*input_line_pointer++ != '"')
+ ;
+ goto allocate_common;
+ }
+
+#ifdef BFD_ASSEMBLER
+ symbolP->bsym->flags |= BSF_OBJECT;
+#endif
+
+ demand_empty_rest_of_line ();
+ return;
+
+ {
+ bad_common_segment:
+ p = input_line_pointer;
+ while (*p && *p != '\n')
+ p++;
+ c = *p;
+ *p = '\0';
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
+ *p = c;
+ input_line_pointer = p;
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+/* Handle the .empty pseudo-op. This supresses the warnings about
+ invalid delay slot usage. */
+
+static void
+s_empty (ignore)
+ int ignore;
+{
+ /* The easy way to implement is to just forget about the last
+ instruction. */
+ last_insn = NULL;
+}
+
+static void
+s_seg (ignore)
+ int ignore;
+{
+
+ if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
+ {
+ input_line_pointer += 6;
+ s_text (0);
+ return;
+ }
+ if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
+ {
+ input_line_pointer += 6;
+ s_data (0);
+ return;
+ }
+ if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
+ {
+ input_line_pointer += 7;
+ s_data1 ();
+ return;
+ }
+ if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
+ {
+ input_line_pointer += 5;
+ /* We only support 2 segments -- text and data -- for now, so
+ things in the "bss segment" will have to go into data for now.
+ You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
+ subseg_set (data_section, 255); /* FIXME-SOMEDAY */
+ return;
+ }
+ as_bad (_("Unknown segment type"));
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_data1 ()
+{
+ subseg_set (data_section, 1);
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_proc (ignore)
+ int ignore;
+{
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ ++input_line_pointer;
+ }
+ ++input_line_pointer;
+}
+
+/* This static variable is set by s_uacons to tell sparc_cons_align
+ that the expession does not need to be aligned. */
+
+static int sparc_no_align_cons = 0;
+
+/* This handles the unaligned space allocation pseudo-ops, such as
+ .uaword. .uaword is just like .word, but the value does not need
+ to be aligned. */
+
+static void
+s_uacons (bytes)
+ int bytes;
+{
+ /* Tell sparc_cons_align not to align this value. */
+ sparc_no_align_cons = 1;
+ cons (bytes);
+}
+
+/* If the --enforce-aligned-data option is used, we require .word,
+ et. al., to be aligned correctly. We do it by setting up an
+ rs_align_code frag, and checking in HANDLE_ALIGN to make sure that
+ no unexpected alignment was introduced.
+
+ The SunOS and Solaris native assemblers enforce aligned data by
+ default. We don't want to do that, because gcc can deliberately
+ generate misaligned data if the packed attribute is used. Instead,
+ we permit misaligned data by default, and permit the user to set an
+ option to check for it. */
+
+void
+sparc_cons_align (nbytes)
+ int nbytes;
+{
+ int nalign;
+ char *p;
+
+ /* Only do this if we are enforcing aligned data. */
+ if (! enforce_aligned_data)
+ return;
+
+ if (sparc_no_align_cons)
+ {
+ /* This is an unaligned pseudo-op. */
+ sparc_no_align_cons = 0;
+ return;
+ }
+
+ nalign = log2 (nbytes);
+ if (nalign == 0)
+ return;
+
+ assert (nalign > 0);
+
+ if (now_seg == absolute_section)
+ {
+ if ((abs_section_offset & ((1 << nalign) - 1)) != 0)
+ as_bad (_("misaligned data"));
+ return;
+ }
+
+ p = frag_var (rs_align_code, 1, 1, (relax_substateT) 0,
+ (symbolS *) NULL, (offsetT) nalign, (char *) NULL);
+
+ record_alignment (now_seg, nalign);
+}
+
+/* This is where we do the unexpected alignment check.
+ This is called from HANDLE_ALIGN in tc-sparc.h. */
+
+void
+sparc_handle_align (fragp)
+ fragS *fragp;
+{
+ if (fragp->fr_type == rs_align_code && !fragp->fr_subtype
+ && fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix != 0)
+ as_bad_where (fragp->fr_file, fragp->fr_line, _("misaligned data"));
+ if (fragp->fr_type == rs_align_code && fragp->fr_subtype == 1024)
+ {
+ int count = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+
+ if (count >= 4
+ && !(count & 3)
+ && count <= 1024
+ && !((long)(fragp->fr_literal + fragp->fr_fix) & 3))
+ {
+ unsigned *p = (unsigned *)(fragp->fr_literal + fragp->fr_fix);
+ int i;
+
+ for (i = 0; i < count; i += 4, p++)
+ if (INSN_BIG_ENDIAN)
+ number_to_chars_bigendian ((char *)p, 0x01000000, 4); /* emit nops */
+ else
+ number_to_chars_littleendian ((char *)p, 0x10000000, 4);
+
+ if (SPARC_OPCODE_ARCH_V9_P (max_architecture) && count > 8)
+ {
+ char *waddr = &fragp->fr_literal[fragp->fr_fix];
+ unsigned wval = (0x30680000 | count >> 2); /* ba,a,pt %xcc, 1f */
+ if (INSN_BIG_ENDIAN)
+ number_to_chars_bigendian (waddr, wval, 4);
+ else
+ number_to_chars_littleendian (waddr, wval, 4);
+ }
+ fragp->fr_var = count;
+ }
+ }
+}
+
+#ifdef OBJ_ELF
+/* Some special processing for a Sparc ELF file. */
+
+void
+sparc_elf_final_processing ()
+{
+ /* Set the Sparc ELF flag bits. FIXME: There should probably be some
+ sort of BFD interface for this. */
+ if (sparc_arch_size == 64)
+ {
+ switch (sparc_memory_model)
+ {
+ case MM_RMO:
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARCV9_RMO;
+ break;
+ case MM_PSO:
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARCV9_PSO;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (current_architecture >= SPARC_OPCODE_ARCH_V9)
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARC_32PLUS;
+ if (current_architecture == SPARC_OPCODE_ARCH_V9A)
+ elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1;
+}
+#endif
+
+/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
+ reloc for a cons. We could use the definition there, except that
+ we want to handle little endian relocs specially. */
+
+void
+cons_fix_new_sparc (frag, where, nbytes, exp)
+ fragS *frag;
+ int where;
+ unsigned int nbytes;
+ expressionS *exp;
+{
+ bfd_reloc_code_real_type r;
+
+ r = (nbytes == 1 ? BFD_RELOC_8 :
+ (nbytes == 2 ? BFD_RELOC_16 :
+ (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
+
+ if (target_little_endian_data && nbytes == 4
+ && now_seg->flags & SEC_ALLOC)
+ r = BFD_RELOC_SPARC_REV32;
+ fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+}
+
+#ifdef OBJ_ELF
+int
+elf32_sparc_force_relocation (fixp)
+ struct fix *fixp;
+{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
+#endif
+
diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h
new file mode 100644
index 00000000000..2a057642be6
--- /dev/null
+++ b/gas/config/tc-sparc.h
@@ -0,0 +1,164 @@
+/* tc-sparc.h - Macros and type defines for the sparc.
+ Copyright (C) 1989, 90-96, 97, 98, 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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,
+ or (at your option) any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write
+ to the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef TC_SPARC
+#define TC_SPARC 1
+
+#ifdef ANSI_PROTOTYPES
+struct frag;
+#endif
+
+/* This is used to set the default value for `target_big_endian'. */
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define LOCAL_LABELS_FB 1
+
+#define TARGET_ARCH bfd_arch_sparc
+
+extern const char *sparc_target_format PARAMS ((void));
+#define TARGET_FORMAT sparc_target_format ()
+
+#if 0
+#ifdef TE_SPARCAOUT
+/* Bi-endian support may eventually be unconditional, but until things are
+ working well it's only provided for targets that need it. */
+#define SPARC_BIENDIAN
+#endif
+#endif
+/* Make it unconditional and check if -EL is valid after option parsing */
+#define SPARC_BIENDIAN
+
+#define WORKING_DOT_WORD
+
+#define md_convert_frag(b,s,f) {as_fatal (_("sparc convert_frag\n"));}
+#define md_estimate_size_before_relax(f,s) \
+ (as_fatal(_("estimate_size_before_relax called")),1)
+
+#define LISTING_HEADER "SPARC GAS "
+
+extern int sparc_pic_code;
+
+#define md_do_align(n, fill, len, max, around) \
+if ((n) && (n) <= 10 && !need_pass_2 && !(fill) \
+ && now_seg != data_section && now_seg != bss_section) \
+ { \
+ char *p; \
+ p = frag_var (rs_align_code, 1 << n, 1, (relax_substateT) 1024, \
+ (symbolS *) 0, (offsetT) (n), (char *) 0); \
+ *p = 0x00; \
+ goto around; \
+ }
+
+/* We require .word, et. al., to be aligned correctly. */
+#define md_cons_align(nbytes) sparc_cons_align (nbytes)
+extern void sparc_cons_align PARAMS ((int));
+#define HANDLE_ALIGN(fragp) sparc_handle_align (fragp)
+extern void sparc_handle_align PARAMS ((struct frag *));
+
+#if defined (OBJ_ELF) || defined (OBJ_AOUT)
+
+/* This expression evaluates to false if the relocation is for a local
+ object for which we still want to do the relocation at runtime.
+ True if we are willing to perform this relocation while building
+ the .o file.
+
+ If the reloc is against an externally visible symbol, then the
+ a.out assembler should not do the relocation if generating PIC, and
+ the ELF assembler should never do the relocation. */
+
+#ifdef OBJ_ELF
+#define obj_relocate_extern 0
+#else
+#define obj_relocate_extern (! sparc_pic_code)
+#endif
+
+#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
+ (obj_relocate_extern \
+ || (FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && S_IS_DEFINED ((FIX)->fx_addsy) \
+ && ! S_IS_COMMON ((FIX)->fx_addsy)))
+#endif
+
+/* I know that "call 0" fails in sparc-coff if this doesn't return 1. I
+ don't know about other relocation types, or other formats, yet. */
+#ifdef OBJ_COFF
+#define TC_FORCE_RELOCATION(FIXP) \
+ ((FIXP)->fx_r_type == BFD_RELOC_32_PCREL_S2 \
+ && ((FIXP)->fx_addsy == 0 \
+ || S_GET_SEGMENT ((FIXP)->fx_addsy) == absolute_section))
+#define RELOC_REQUIRES_SYMBOL
+#endif
+
+#ifdef OBJ_ELF
+#define TC_FORCE_RELOCATION(fixp) elf32_sparc_force_relocation(fixp)
+extern int elf32_sparc_force_relocation PARAMS ((struct fix *));
+#endif
+
+#define MD_APPLY_FIX3
+#define TC_HANDLES_FX_DONE
+
+#ifdef OBJ_ELF
+/* Keep relocations against global symbols. Don't turn them into
+ relocations against sections. This is required for the dynamic
+ linker to operate properly. When generating PIC, we need to keep
+ any non PC relative reloc. */
+#define tc_fix_adjustable(FIX) \
+ (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy) \
+ && (! sparc_pic_code \
+ || (FIX)->fx_pcrel \
+ || ((FIX)->fx_subsy != NULL \
+ && (S_GET_SEGMENT ((FIX)->fx_subsy) \
+ == S_GET_SEGMENT ((FIX)->fx_addsy))) \
+ || strchr (S_GET_NAME ((FIX)->fx_addsy), '\001') != NULL \
+ || strchr (S_GET_NAME ((FIX)->fx_addsy), '\002') != NULL))
+#endif
+
+#ifdef OBJ_AOUT
+/* When generating PIC code, we must not adjust any reloc which will
+ turn into a reloc against the global offset table, nor any reloc
+ which we will need if a symbol is overridden. */
+#define tc_fix_adjustable(FIX) \
+ (! sparc_pic_code \
+ || ((FIX)->fx_pcrel \
+ && ((FIX)->fx_addsy == NULL \
+ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
+ && ! S_IS_WEAK ((FIX)->fx_addsy)))) \
+ || (FIX)->fx_r_type == BFD_RELOC_16 \
+ || (FIX)->fx_r_type == BFD_RELOC_32)
+#endif
+
+#define elf_tc_final_processing sparc_elf_final_processing
+extern void sparc_elf_final_processing PARAMS ((void));
+
+#define md_operand(x)
+
+extern void sparc_md_end PARAMS ((void));
+#define md_end() sparc_md_end ()
+
+#endif
+
+#define TC_CONS_FIX_NEW cons_fix_new_sparc
+extern void cons_fix_new_sparc
+ PARAMS ((struct frag *, int, unsigned int, struct expressionS *));
+
+/* end of tc-sparc.h */
diff --git a/gas/config/tc-tahoe.c b/gas/config/tc-tahoe.c
new file mode 100644
index 00000000000..2bd63ca7b16
--- /dev/null
+++ b/gas/config/tc-tahoe.c
@@ -0,0 +1,2027 @@
+/* tc-tahoe.c
+ Not part of GAS yet. */
+
+#include "as.h"
+#include "obstack.h"
+
+/* this bit glommed from tahoe-inst.h */
+
+typedef unsigned char byte;
+typedef byte tahoe_opcodeT;
+
+/*
+ * This is part of tahoe-ins-parse.c & friends.
+ * We want to parse a tahoe instruction text into a tree defined here.
+ */
+
+#define TIT_MAX_OPERANDS (4) /* maximum number of operands in one
+ single tahoe instruction */
+
+struct top /* tahoe instruction operand */
+{
+ int top_ndx; /* -1, or index register. eg 7=[R7] */
+ int top_reg; /* -1, or register number. eg 7 = R7 or (R7) */
+ byte top_mode; /* Addressing mode byte. This byte, defines
+ which of the 11 modes opcode is. */
+
+ char top_access; /* Access type wanted for this opperand
+ 'b'branch ' 'no-instruction 'amrvw' */
+ char top_width; /* Operand width expected, one of "bwlq?-:!" */
+
+ char *top_error; /* Say if operand is inappropriate */
+
+ segT seg_of_operand; /* segment as returned by expression()*/
+
+ expressionS exp_of_operand; /* The expression as parsed by expression()*/
+
+ byte top_dispsize; /* Number of bytes in the displacement if we
+ can figure it out */
+};
+
+/* The addressing modes for an operand. These numbers are the acutal values
+ for certain modes, so be carefull if you screw with them. */
+#define TAHOE_DIRECT_REG (0x50)
+#define TAHOE_REG_DEFERRED (0x60)
+
+#define TAHOE_REG_DISP (0xE0)
+#define TAHOE_REG_DISP_DEFERRED (0xF0)
+
+#define TAHOE_IMMEDIATE (0x8F)
+#define TAHOE_IMMEDIATE_BYTE (0x88)
+#define TAHOE_IMMEDIATE_WORD (0x89)
+#define TAHOE_IMMEDIATE_LONGWORD (0x8F)
+#define TAHOE_ABSOLUTE_ADDR (0x9F)
+
+#define TAHOE_DISPLACED_RELATIVE (0xEF)
+#define TAHOE_DISP_REL_DEFERRED (0xFF)
+
+#define TAHOE_AUTO_DEC (0x7E)
+#define TAHOE_AUTO_INC (0x8E)
+#define TAHOE_AUTO_INC_DEFERRED (0x9E)
+/* INDEXED_REG is decided by the existance or lack of a [reg] */
+
+/* These are encoded into top_width when top_access=='b'
+ and it's a psuedo op.*/
+#define TAHOE_WIDTH_ALWAYS_JUMP '-'
+#define TAHOE_WIDTH_CONDITIONAL_JUMP '?'
+#define TAHOE_WIDTH_BIG_REV_JUMP '!'
+#define TAHOE_WIDTH_BIG_NON_REV_JUMP ':'
+
+/* The hex code for certain tahoe commands and modes.
+ This is just for readability. */
+#define TAHOE_JMP (0x71)
+#define TAHOE_PC_REL_LONG (0xEF)
+#define TAHOE_BRB (0x11)
+#define TAHOE_BRW (0x13)
+/* These, when 'ored' with, or added to, a register number,
+ set up the number for the displacement mode. */
+#define TAHOE_PC_OR_BYTE (0xA0)
+#define TAHOE_PC_OR_WORD (0xC0)
+#define TAHOE_PC_OR_LONG (0xE0)
+
+struct tit /* get it out of the sewer, it stands for
+ tahoe instruction tree (Geeze!) */
+{
+ tahoe_opcodeT tit_opcode; /* The opcode. */
+ byte tit_operands; /* How many operands are here. */
+ struct top tit_operand[TIT_MAX_OPERANDS]; /* Operands */
+ char *tit_error; /* "" or fatal error text */
+};
+
+/* end: tahoe-inst.h */
+
+/* tahoe.c - tahoe-specific -
+ Not part of gas yet.
+ */
+
+#include "opcode/tahoe.h"
+
+/* This is the number to put at the beginning of the a.out file */
+long omagic = OMAGIC;
+
+/* These chars start a comment anywhere in a source file (except inside
+ another comment or a quoted string. */
+const char comment_chars[] = "#;";
+
+/* These chars only start a comment at the beginning of a line. */
+const char line_comment_chars[] = "#";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant
+ as in 0f123.456
+ or 0d1.234E-12 (see exp chars above)
+ Note: The Tahoe port doesn't support floating point constants. This is
+ consistant with 'as' If it's needed, I can always add it later. */
+const char FLT_CHARS[] = "df";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c . Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here.
+ (The tahoe has plenty of room, so the change currently isn't needed.)
+ */
+
+static struct tit t; /* A tahoe instruction after decoding. */
+
+void float_cons ();
+/* A table of pseudo ops (sans .), the function called, and an integer op
+ that the function is called with. */
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"dfloat", float_cons, 'd'},
+ {"ffloat", float_cons, 'f'},
+ {0}
+};
+
+/*
+ * For Tahoe, relative addresses of "just the right length" are pretty easy.
+ * The branch displacement is always the last operand, even in
+ * synthetic instructions.
+ * For Tahoe, we encode the relax_substateTs (in e.g. fr_substate) as:
+ *
+ * 4 3 2 1 0 bit number
+ * ---/ /--+-------+-------+-------+-------+-------+
+ * | what state ? | how long ? |
+ * ---/ /--+-------+-------+-------+-------+-------+
+ *
+ * The "how long" bits are 00=byte, 01=word, 10=long.
+ * This is a Un*x convention.
+ * Not all lengths are legit for a given value of (what state).
+ * The four states are listed below.
+ * The "how long" refers merely to the displacement length.
+ * The address usually has some constant bytes in it as well.
+ *
+
+States for Tahoe address relaxing.
+1. TAHOE_WIDTH_ALWAYS_JUMP (-)
+ Format: "b-"
+ Tahoe opcodes are: (Hex)
+ jr 11
+ jbr 11
+ Simple branch.
+ Always, 1 byte opcode, then displacement/absolute.
+ If word or longword, change opcode to brw or jmp.
+
+
+2. TAHOE_WIDTH_CONDITIONAL_JUMP (?)
+ J<cond> where <cond> is a simple flag test.
+ Format: "b?"
+ Tahoe opcodes are: (Hex)
+ jneq/jnequ 21
+ jeql/jeqlu 31
+ jgtr 41
+ jleq 51
+ jgeq 81
+ jlss 91
+ jgtru a1
+ jlequ b1
+ jvc c1
+ jvs d1
+ jlssu/jcs e1
+ jgequ/jcc f1
+ Always, you complement 4th bit to reverse the condition.
+ Always, 1-byte opcode, then 1-byte displacement.
+
+3. TAHOE_WIDTH_BIG_REV_JUMP (!)
+ Jbc/Jbs where cond tests a memory bit.
+ Format: "rlvlb!"
+ Tahoe opcodes are: (Hex)
+ jbs 0e
+ jbc 1e
+ Always, you complement 4th bit to reverse the condition.
+ Always, 1-byte opcde, longword, longword-address, 1-word-displacement
+
+4. TAHOE_WIDTH_BIG_NON_REV_JUMP (:)
+ JaoblXX/Jbssi
+ Format: "rlmlb:"
+ Tahoe opcodes are: (Hex)
+ aojlss 2f
+ jaoblss 2f
+ aojleq 3f
+ jaobleq 3f
+ jbssi 5f
+ Always, we cannot reverse the sense of the branch; we have a word
+ displacement.
+
+We need to modify the opcode is for class 1, 2 and 3 instructions.
+After relax() we may complement the 4th bit of 2 or 3 to reverse sense of
+branch.
+
+We sometimes store context in the operand literal. This way we can figure out
+after relax() what the original addressing mode was. (Was is pc_rel, or
+pc_rel_disp? That sort of thing.) */
+
+/* These displacements are relative to the START address of the
+ displacement which is at the start of the displacement, not the end of
+ the instruction. The hardware pc_rel is at the end of the instructions.
+ That's why all the displacements have the length of the displacement added
+ to them. (WF + length(word))
+
+ The first letter is Byte, Word.
+ 2nd letter is Forward, Backward. */
+#define BF (1+ 127)
+#define BB (1+-128)
+#define WF (2+ 32767)
+#define WB (2+-32768)
+/* Dont need LF, LB because they always reach. [They are coded as 0.] */
+
+#define C(a,b) ENCODE_RELAX(a,b)
+/* This macro has no side-effects. */
+#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+#define RELAX_STATE(what) ((what) >> 2)
+#define RELAX_LENGTH(length) ((length) && 3)
+
+#define STATE_ALWAYS_BRANCH (1)
+#define STATE_CONDITIONAL_BRANCH (2)
+#define STATE_BIG_REV_BRANCH (3)
+#define STATE_BIG_NON_REV_BRANCH (4)
+#define STATE_PC_RELATIVE (5)
+
+#define STATE_BYTE (0)
+#define STATE_WORD (1)
+#define STATE_LONG (2)
+#define STATE_UNDF (3) /* Symbol undefined in pass1 */
+
+/* This is the table used by gas to figure out relaxing modes. The fields are
+ forward_branch reach, backward_branch reach, number of bytes it would take,
+ where the next biggest branch is. */
+const relax_typeS md_relax_table[] =
+{
+ {
+ 1, 1, 0, 0
+ }, /* error sentinel 0,0 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 0,1 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 0,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 0,3 */
+/* Unconditional branch cases "jrb"
+ The relax part is the actual displacement */
+ {
+ BF, BB, 1, C (1, 1)
+ }, /* brb B`foo 1,0 */
+ {
+ WF, WB, 2, C (1, 2)
+ }, /* brw W`foo 1,1 */
+ {
+ 0, 0, 5, 0
+ }, /* Jmp L`foo 1,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 1,3 */
+/* Reversible Conditional Branch. If the branch won't reach, reverse
+ it, and jump over a brw or a jmp that will reach. The relax part is the
+ actual address. */
+ {
+ BF, BB, 1, C (2, 1)
+ }, /* b<cond> B`foo 2,0 */
+ {
+ WF + 2, WB + 2, 4, C (2, 2)
+ }, /* brev over, brw W`foo, over: 2,1 */
+ {
+ 0, 0, 7, 0
+ }, /* brev over, jmp L`foo, over: 2,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 2,3 */
+/* Another type of reversable branch. But this only has a word
+ displacement. */
+ {
+ 1, 1, 0, 0
+ }, /* unused 3,0 */
+ {
+ WF, WB, 2, C (3, 2)
+ }, /* jbX W`foo 3,1 */
+ {
+ 0, 0, 8, 0
+ }, /* jrevX over, jmp L`foo, over: 3,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 3,3 */
+/* These are the non reversable branches, all of which have a word
+ displacement. If I can't reach, branch over a byte branch, to a
+ jump that will reach. The jumped branch jumps over the reaching
+ branch, to continue with the flow of the program. It's like playing
+ leap frog. */
+ {
+ 1, 1, 0, 0
+ }, /* unused 4,0 */
+ {
+ WF, WB, 2, C (4, 2)
+ }, /* aobl_ W`foo 4,1 */
+ {
+ 0, 0, 10, 0
+ }, /*aobl_ W`hop,br over,hop: jmp L^foo,over 4,2*/
+ {
+ 1, 1, 0, 0
+ }, /* unused 4,3 */
+/* Normal displacement mode, no jumping or anything like that.
+ The relax points to one byte before the address, thats why all
+ the numbers are up by one. */
+ {
+ BF + 1, BB + 1, 2, C (5, 1)
+ }, /* B^"foo" 5,0 */
+ {
+ WF + 1, WB + 1, 3, C (5, 2)
+ }, /* W^"foo" 5,1 */
+ {
+ 0, 0, 5, 0
+ }, /* L^"foo" 5,2 */
+ {
+ 1, 1, 0, 0
+ }, /* unused 5,3 */
+};
+
+#undef C
+#undef BF
+#undef BB
+#undef WF
+#undef WB
+/* End relax stuff */
+
+/* Handle of the OPCODE hash table. NULL means any use before
+ md_begin() will crash. */
+static struct hash_control *op_hash;
+
+/* Init function. Build the hash table. */
+void
+md_begin ()
+{
+ struct tot *tP;
+ char *errorval = 0;
+ int synthetic_too = 1; /* If 0, just use real opcodes. */
+
+ op_hash = hash_new ();
+
+ for (tP = totstrs; *tP->name && !errorval; tP++)
+ errorval = hash_insert (op_hash, tP->name, &tP->detail);
+
+ if (synthetic_too)
+ for (tP = synthetic_totstrs; *tP->name && !errorval; tP++)
+ errorval = hash_insert (op_hash, tP->name, &tP->detail);
+
+ if (errorval)
+ as_fatal (errorval);
+}
+
+CONST char *md_shortopts = "ad:STt:V";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'a':
+ as_warn (_("The -a option doesn't exist. (Despite what the man page says!"));
+ break;
+
+ case 'd':
+ as_warn (_("Displacement length %s ignored!"), arg);
+ break;
+
+ case 'S':
+ as_warn (_("SYMBOL TABLE not implemented"));
+ break;
+
+ case 'T':
+ as_warn (_("TOKEN TRACE not implemented"));
+ break;
+
+ case 't':
+ as_warn (_("I don't need or use temp. file \"%s\"."), arg);
+ break;
+
+ case 'V':
+ as_warn (_("I don't use an interpass file! -V ignored"));
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+Tahoe options:\n\
+-a ignored\n\
+-d LENGTH ignored\n\
+-J ignored\n\
+-S ignored\n\
+-t FILE ignored\n\
+-T ignored\n\
+-V ignored\n"));
+}
+
+/* The functions in this section take numbers in the machine format, and
+ munges them into Tahoe byte order.
+ They exist primarily for cross assembly purpose. */
+void /* Knows about order of bytes in address. */
+md_number_to_chars (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ valueT value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ number_to_chars_bigendian (con, value, nbytes);
+}
+
+#ifdef comment
+void /* Knows about order of bytes in address. */
+md_number_to_imm (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ md_number_to_chars (con, value, nbytes);
+}
+
+#endif /* comment */
+
+void
+tc_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ /* should never be called */
+ know (0);
+}
+
+void /* Knows about order of bytes in address. */
+md_number_to_disp (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ md_number_to_chars (con, value, nbytes);
+}
+
+void /* Knows about order of bytes in address. */
+md_number_to_field (con, value, nbytes)
+ char con[]; /* Return 'nbytes' of chars here. */
+ long int value; /* The value of the bits. */
+ int nbytes; /* Number of bytes in the output. */
+{
+ md_number_to_chars (con, value, nbytes);
+}
+
+/* Put the bits in an order that a tahoe will understand, despite the ordering
+ of the native machine.
+ On Tahoe: first 4 bytes are normal unsigned big endian long,
+ next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
+ The last byte is broken up with bit 7 as pcrel,
+ bits 6 & 5 as length,
+ bit 4 as extern and the last nibble as 'undefined'. */
+
+#if comment
+void
+md_ri_to_chars (ri_p, ri)
+ struct relocation_info *ri_p, ri;
+{
+ byte the_bytes[sizeof (struct relocation_info)];
+ /* The reason I can't just encode these directly into ri_p is that
+ ri_p may point to ri. */
+
+ /* This is easy */
+ md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
+
+ /* now the fun stuff */
+ the_bytes[4] = (ri.r_symbolnum >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
+ the_bytes[6] = ri.r_symbolnum & 0x0ff;
+ the_bytes[7] = (((ri.r_extern << 4) & 0x10) | ((ri.r_length << 5) & 0x60) |
+ ((ri.r_pcrel << 7) & 0x80)) & 0xf0;
+
+ bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info));
+}
+
+#endif /* comment */
+
+/* Put the bits in an order that a tahoe will understand, despite the ordering
+ of the native machine.
+ On Tahoe: first 4 bytes are normal unsigned big endian long,
+ next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
+ The last byte is broken up with bit 7 as pcrel,
+ bits 6 & 5 as length,
+ bit 4 as extern and the last nibble as 'undefined'. */
+
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ long r_symbolnum;
+
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ where[4] = (r_symbolnum >> 16) & 0x0ff;
+ where[5] = (r_symbolnum >> 8) & 0x0ff;
+ where[6] = r_symbolnum & 0x0ff;
+ where[7] = (((is_pcrel (fixP) << 7) & 0x80)
+ | ((((fixP->fx_type == FX_8 || fixP->fx_type == FX_PCREL8
+ ? 0
+ : (fixP->fx_type == FX_16 || fixP->fx_type == FX_PCREL16
+ ? 1
+ : (fixP->fx_type == FX_32 || fixP->fx_type == FX_PCREL32
+ ? 2
+ : 42)))) << 5) & 0x60)
+ | ((!S_IS_DEFINED (fixP->fx_addsy) << 4) & 0x10));
+}
+
+/* Relocate byte stuff */
+
+/* This is for broken word. */
+const int md_short_jump_size = 3;
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ offset = to_addr - (from_addr + 1);
+ *ptr++ = TAHOE_BRW;
+ md_number_to_chars (ptr, offset, 2);
+}
+
+const int md_long_jump_size = 6;
+const int md_reloc_size = 8; /* Size of relocation record */
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ offset = to_addr - (from_addr + 4);
+ *ptr++ = TAHOE_JMP;
+ *ptr++ = TAHOE_PC_REL_LONG;
+ md_number_to_chars (ptr, offset, 4);
+}
+
+/*
+ * md_estimate_size_before_relax()
+ *
+ * Called just before relax().
+ * Any symbol that is now undefined will not become defined, so we assumed
+ * that it will be resolved by the linker.
+ * Return the correct fr_subtype in the frag, for relax()
+ * Return the initial "guess for fr_var" to caller. (How big I think this
+ * will be.)
+ * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ * Although it may not be explicit in the frag, pretend fr_var starts with a
+ * 0 value.
+ */
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ segT segment_type; /* N_DATA or N_TEXT. */
+{
+ register char *p;
+ register int old_fr_fix;
+ /* int pc_rel; FIXME: remove this */
+
+ old_fr_fix = fragP->fr_fix;
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ /* The symbol was in the same segment as the opcode, and it's
+ a real pc_rel case so it's a relaxable case. */
+ fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
+ }
+ else
+ {
+ /* This case is still undefined, so asume it's a long word for the
+ linker to fix. */
+ p = fragP->fr_literal + old_fr_fix;
+ *p |= TAHOE_PC_OR_LONG;
+ /* We now know how big it will be, one long word. */
+ fragP->fr_fix += 1 + 4;
+ fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
+ fragP->fr_offset, FX_PCREL32, NULL);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
+ *p++ = 6;
+ *p++ = TAHOE_JMP;
+ *p++ = TAHOE_PC_REL_LONG;
+ fragP->fr_fix += 1 + 1 + 1 + 4;
+ fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol,
+ fragP->fr_offset, FX_PCREL32, NULL);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype =
+ ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
+ *p++ = 0;
+ *p++ = 6;
+ *p++ = TAHOE_JMP;
+ *p++ = TAHOE_PC_REL_LONG;
+ fragP->fr_fix += 2 + 2 + 4;
+ fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol,
+ fragP->fr_offset, FX_PCREL32, NULL);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *p++ = 2;
+ *p++ = 0;
+ *p++ = TAHOE_BRB;
+ *p++ = 6;
+ *p++ = TAHOE_JMP;
+ *p++ = TAHOE_PC_REL_LONG;
+ fragP->fr_fix += 2 + 2 + 2 + 4;
+ fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol,
+ fragP->fr_offset, FX_PCREL32, NULL);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *fragP->fr_opcode = TAHOE_JMP;
+ *p++ = TAHOE_PC_REL_LONG;
+ fragP->fr_fix += 1 + 4;
+ fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
+ fragP->fr_offset, FX_PCREL32, NULL);
+ frag_wane (fragP);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
+} /* md_estimate_size_before_relax() */
+
+/*
+ * md_convert_frag();
+ *
+ * Called after relax() is finished.
+ * In: Address of frag.
+ * fr_type == rs_machine_dependent.
+ * fr_subtype is what the address relaxed to.
+ *
+ * Out: Any fixSs and constants are set up.
+ * Caller will turn frag into a ".space 0".
+ */
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ register fragS *fragP;
+{
+ register char *addressP; /* -> _var to change. */
+ register char *opcodeP; /* -> opcode char(s) to change. */
+ register short int length_code; /* 2=long 1=word 0=byte */
+ register short int extension = 0; /* Size of relaxed address.
+ Added to fr_fix: incl. ALL var chars. */
+ register symbolS *symbolP;
+ register long int where;
+ register long int address_of_var;
+ /* Where, in file space, is _var of *fragP? */
+ register long int target_address;
+ /* Where, in file space, does addr point? */
+
+ know (fragP->fr_type == rs_machine_dependent);
+ length_code = RELAX_LENGTH (fragP->fr_subtype);
+ know (length_code >= 0 && length_code < 3);
+ where = fragP->fr_fix;
+ addressP = fragP->fr_literal + where;
+ opcodeP = fragP->fr_opcode;
+ symbolP = fragP->fr_symbol;
+ know (symbolP);
+ target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;
+ address_of_var = fragP->fr_address + where;
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
+ /* *addressP holds the registers number, plus 0x10, if it's deferred
+ mode. To set up the right mode, just OR the size of this displacement */
+ /* Byte displacement. */
+ *addressP++ |= TAHOE_PC_OR_BYTE;
+ *addressP = target_address - (address_of_var + 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
+ /* Word displacement. */
+ *addressP++ |= TAHOE_PC_OR_WORD;
+ md_number_to_chars (addressP, target_address - (address_of_var + 3), 2);
+ extension = 3;
+ break;
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
+ /* Long word displacement. */
+ *addressP++ |= TAHOE_PC_OR_LONG;
+ md_number_to_chars (addressP, target_address - (address_of_var + 5), 4);
+ extension = 5;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
+ *addressP = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
+ *opcodeP ^= 0x10; /* Reverse sense of test. */
+ *addressP++ = 3; /* Jump over word branch */
+ *addressP++ = TAHOE_BRW;
+ md_number_to_chars (addressP, target_address - (address_of_var + 4), 2);
+ extension = 4;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):
+ *opcodeP ^= 0x10; /* Reverse sense of test. */
+ *addressP++ = 6;
+ *addressP++ = TAHOE_JMP;
+ *addressP++ = TAHOE_PC_REL_LONG;
+ md_number_to_chars (addressP, target_address, 4);
+ extension = 7;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
+ *addressP = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
+ *opcodeP = TAHOE_BRW;
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
+ *opcodeP = TAHOE_JMP;
+ *addressP++ = TAHOE_PC_REL_LONG;
+ md_number_to_chars (addressP, target_address - (address_of_var + 5), 4);
+ extension = 5;
+ break;
+
+ case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD):
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_LONG):
+ *opcodeP ^= 0x10;
+ *addressP++ = 0;
+ *addressP++ = 6;
+ *addressP++ = TAHOE_JMP;
+ *addressP++ = TAHOE_PC_REL_LONG;
+ md_number_to_chars (addressP, target_address, 4);
+ extension = 8;
+ break;
+
+ case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD):
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_LONG):
+ *addressP++ = 0;
+ *addressP++ = 2;
+ *addressP++ = TAHOE_BRB;
+ *addressP++ = 6;
+ *addressP++ = TAHOE_JMP;
+ *addressP++ = TAHOE_PC_REL_LONG;
+ md_number_to_chars (addressP, target_address, 4);
+ extension = 10;
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+ fragP->fr_fix += extension;
+} /* md_convert_frag */
+
+
+/* This is the stuff for md_assemble. */
+#define FP_REG 13
+#define SP_REG 14
+#define PC_REG 15
+#define BIGGESTREG PC_REG
+
+/*
+ * Parse the string pointed to by START
+ * If it represents a valid register, point START to the character after
+ * the last valid register char, and return the register number (0-15).
+ * If invalid, leave START alone, return -1.
+ * The format has to be exact. I don't do things like eat leading zeros
+ * or the like.
+ * Note: This doesn't check for the next character in the string making
+ * this invalid. Ex: R123 would return 12, it's the callers job to check
+ * what start is point to apon return.
+ *
+ * Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15)
+ * Case doesn't matter.
+ */
+int
+tahoe_reg_parse (start)
+ char **start; /* A pointer to the string to parse. */
+{
+ register char *regpoint = *start;
+ register int regnum = -1;
+
+ switch (*regpoint++)
+ {
+ case '%': /* Registers can start with a %,
+ R or r, and then a number. */
+ case 'R':
+ case 'r':
+ if (isdigit (*regpoint))
+ {
+ /* Got the first digit. */
+ regnum = *regpoint++ - '0';
+ if ((regnum == 1) && isdigit (*regpoint))
+ {
+ /* Its a two digit number. */
+ regnum = 10 + (*regpoint++ - '0');
+ if (regnum > BIGGESTREG)
+ { /* Number too big? */
+ regnum = -1;
+ }
+ }
+ }
+ break;
+ case 'F': /* Is it the FP */
+ case 'f':
+ switch (*regpoint++)
+ {
+ case 'p':
+ case 'P':
+ regnum = FP_REG;
+ }
+ break;
+ case 's': /* How about the SP */
+ case 'S':
+ switch (*regpoint++)
+ {
+ case 'p':
+ case 'P':
+ regnum = SP_REG;
+ }
+ break;
+ case 'p': /* OR the PC even */
+ case 'P':
+ switch (*regpoint++)
+ {
+ case 'c':
+ case 'C':
+ regnum = PC_REG;
+ }
+ break;
+ }
+
+ if (regnum != -1)
+ { /* No error, so move string pointer */
+ *start = regpoint;
+ }
+ return regnum; /* Return results */
+} /* tahoe_reg_parse */
+
+/*
+ * This chops up an operand and figures out its modes and stuff.
+ * It's a little touchy about extra characters.
+ * Optex to start with one extra character so it can be overwritten for
+ * the backward part of the parsing.
+ * You can't put a bunch of extra characters in side to
+ * make the command look cute. ie: * foo ( r1 ) [ r0 ]
+ * If you like doing a lot of typing, try COBOL!
+ * Actually, this parser is a little weak all around. It's designed to be
+ * used with compliers, so I emphisise correct decoding of valid code quickly
+ * rather that catching every possable error.
+ * Note: This uses the expression function, so save input_line_pointer before
+ * calling.
+ *
+ * Sperry defines the semantics of address modes (and values)
+ * by a two-letter code, explained here.
+ *
+ * letter 1: access type
+ *
+ * a address calculation - no data access, registers forbidden
+ * b branch displacement
+ * m read - let go of bus - write back "modify"
+ * r read
+ * w write
+ * v bit field address: like 'a' but registers are OK
+ *
+ * letter 2: data type (i.e. width, alignment)
+ *
+ * b byte
+ * w word
+ * l longword
+ * q quadword (Even regs < 14 allowed) (if 12, you get a warning)
+ * - unconditional synthetic jbr operand
+ * ? simple synthetic reversable branch operand
+ * ! complex synthetic reversable branch operand
+ * : complex synthetic non-reversable branch operand
+ *
+ * The '-?!:' letter 2's are not for external consumption. They are used
+ * by GAS for psuedo ops relaxing code.
+ *
+ * After parsing topP has:
+ *
+ * top_ndx: -1, or the index register. eg 7=[R7]
+ * top_reg: -1, or register number. eg 7 = R7 or (R7)
+ * top_mode: The addressing mode byte. This byte, defines which of
+ * the 11 modes opcode is.
+ * top_access: Access type wanted for this opperand 'b'branch ' '
+ * no-instruction 'amrvw'
+ * top_width: Operand width expected, one of "bwlq?-:!"
+ * exp_of_operand: The expression as parsed by expression()
+ * top_dispsize: Number of bytes in the displacement if we can figure it
+ * out and it's relavent.
+ *
+ * Need syntax checks built.
+ */
+
+void
+tip_op (optex, topP)
+ char *optex; /* The users text input, with one leading character */
+ struct top *topP; /* The tahoe instruction with some fields already set:
+ in: access, width
+ out: ndx, reg, mode, error, dispsize */
+
+{
+ int mode = 0; /* This operand's mode. */
+ char segfault = *optex; /* To keep the back parsing from freaking. */
+ char *point = optex + 1; /* Parsing from front to back. */
+ char *end; /* Parsing from back to front. */
+ int reg = -1; /* major register, -1 means absent */
+ int imreg = -1; /* Major register in immediate mode */
+ int ndx = -1; /* index register number, -1 means absent */
+ char dec_inc = ' '; /* Is the SP auto-incremented '+' or
+ auto-decremented '-' or neither ' '. */
+ int immediate = 0; /* 1 if '$' immediate mode */
+ int call_width = 0; /* If the caller casts the displacement */
+ int abs_width = 0; /* The width of the absolute displacment */
+ int com_width = 0; /* Displacement width required by branch */
+ int deferred = 0; /* 1 if '*' deferral is used */
+ byte disp_size = 0; /* How big is this operand. 0 == don't know */
+ char *op_bad = ""; /* Bad operand error */
+
+ char *tp, *temp, c; /* Temporary holders */
+
+ char access = topP->top_access; /* Save on a deref. */
+ char width = topP->top_width;
+
+ int really_none = 0; /* Empty expressions evaluate to 0
+ but I need to know if it's there or not */
+ expressionS *expP; /* -> expression values for this operand */
+
+ /* Does this command restrict the displacement size. */
+ if (access == 'b')
+ com_width = (width == 'b' ? 1 :
+ (width == 'w' ? 2 :
+ (width == 'l' ? 4 : 0)));
+
+ *optex = '\0'; /* This is kind of a back stop for all
+ the searches to fail on if needed.*/
+ if (*point == '*')
+ { /* A dereference? */
+ deferred = 1;
+ point++;
+ }
+
+ /* Force words into a certain mode */
+ /* Bitch, Bitch, Bitch! */
+ /*
+ * Using the ^ operator is ambigous. If I have an absolute label
+ * called 'w' set to, say 2, and I have the expression 'w^1', do I get
+ * 1, forced to be in word displacement mode, or do I get the value of
+ * 'w' or'ed with 1 (3 in this case).
+ * The default is 'w' as an offset, so that's what I use.
+ * Stick with `, it does the same, and isn't ambig.
+ */
+
+ if (*point != '\0' && ((point[1] == '^') || (point[1] == '`')))
+ switch (*point)
+ {
+ case 'b':
+ case 'B':
+ case 'w':
+ case 'W':
+ case 'l':
+ case 'L':
+ if (com_width)
+ as_warn (_("Casting a branch displacement is bad form, and is ignored."));
+ else
+ {
+ c = (isupper (*point) ? tolower (*point) : *point);
+ call_width = ((c == 'b') ? 1 :
+ ((c == 'w') ? 2 : 4));
+ }
+ point += 2;
+ break;
+ }
+
+ /* Setting immediate mode */
+ if (*point == '$')
+ {
+ immediate = 1;
+ point++;
+ }
+
+ /*
+ * I've pulled off all the easy stuff off the front, move to the end and
+ * yank.
+ */
+
+ for (end = point; *end != '\0'; end++) /* Move to the end. */
+ ;
+
+ if (end != point) /* Null string? */
+ end--;
+
+ if (end > point && *end == ' ' && end[-1] != '\'')
+ end--; /* Hop white space */
+
+ /* Is this an index reg. */
+ if ((*end == ']') && (end[-1] != '\''))
+ {
+ temp = end;
+
+ /* Find opening brace. */
+ for (--end; (*end != '[' && end != point); end--)
+ ;
+
+ /* If I found the opening brace, get the index register number. */
+ if (*end == '[')
+ {
+ tp = end + 1; /* tp should point to the start of a reg. */
+ ndx = tahoe_reg_parse (&tp);
+ if (tp != temp)
+ { /* Reg. parse error. */
+ ndx = -1;
+ }
+ else
+ {
+ end--; /* Found it, move past brace. */
+ }
+ if (ndx == -1)
+ {
+ op_bad = _("Couldn't parse the [index] in this operand.");
+ end = point; /* Force all the rest of the tests to fail. */
+ }
+ }
+ else
+ {
+ op_bad = _("Couldn't find the opening '[' for the index of this operand.");
+ end = point; /* Force all the rest of the tests to fail. */
+ }
+ }
+
+ /* Post increment? */
+ if (*end == '+')
+ {
+ dec_inc = '+';
+ /* was: *end--; */
+ end--;
+ }
+
+ /* register in parens? */
+ if ((*end == ')') && (end[-1] != '\''))
+ {
+ temp = end;
+
+ /* Find opening paren. */
+ for (--end; (*end != '(' && end != point); end--)
+ ;
+
+ /* If I found the opening paren, get the register number. */
+ if (*end == '(')
+ {
+ tp = end + 1;
+ reg = tahoe_reg_parse (&tp);
+ if (tp != temp)
+ {
+ /* Not a register, but could be part of the expression. */
+ reg = -1;
+ end = temp; /* Rest the pointer back */
+ }
+ else
+ {
+ end--; /* Found the reg. move before opening paren. */
+ }
+ }
+ else
+ {
+ op_bad = _("Couldn't find the opening '(' for the deref of this operand.");
+ end = point; /* Force all the rest of the tests to fail. */
+ }
+ }
+
+ /* Pre decrement? */
+ if (*end == '-')
+ {
+ if (dec_inc != ' ')
+ {
+ op_bad = _("Operand can't be both pre-inc and post-dec.");
+ end = point;
+ }
+ else
+ {
+ dec_inc = '-';
+ /* was: *end--; */
+ end--;
+ }
+ }
+
+ /*
+ * Everything between point and end is the 'expression', unless it's
+ * a register name.
+ */
+
+ c = end[1];
+ end[1] = '\0';
+
+ tp = point;
+ imreg = tahoe_reg_parse (&point); /* Get the immediate register
+ if it is there.*/
+ if (*point != '\0')
+ {
+ /* If there is junk after point, then the it's not immediate reg. */
+ point = tp;
+ imreg = -1;
+ }
+
+ if (imreg != -1 && reg != -1)
+ op_bad = _("I parsed 2 registers in this operand.");
+
+ /*
+ * Evaluate whats left of the expression to see if it's valid.
+ * Note again: This assumes that the calling expression has saved
+ * input_line_pointer. (Nag, nag, nag!)
+ */
+
+ if (*op_bad == '\0')
+ {
+ /* statement has no syntax goofs yet: lets sniff the expression */
+ input_line_pointer = point;
+ expP = &(topP->exp_of_operand);
+ topP->seg_of_operand = expression (expP);
+ switch (expP->X_op)
+ {
+ case O_absent:
+ /* No expression. For BSD4.2 compatibility, missing expression is
+ absolute 0 */
+ expP->X_op = O_constant;
+ expP->X_add_number = 0;
+ really_none = 1;
+ case O_constant:
+ /* for SEG_ABSOLUTE, we shouldnt need to set X_op_symbol,
+ X_add_symbol to any particular value. */
+ /* But, we will program defensively. Since this situation occurs
+ rarely so it costs us little to do so. */
+ expP->X_add_symbol = NULL;
+ expP->X_op_symbol = NULL;
+ /* How many bytes are needed to express this abs value? */
+ abs_width =
+ ((((expP->X_add_number & 0xFFFFFF80) == 0) ||
+ ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 :
+ (((expP->X_add_number & 0xFFFF8000) == 0) ||
+ ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4);
+
+ case O_symbol:
+ break;
+
+ default:
+ /*
+ * Major bug. We can't handle the case of a operator
+ * expression in a synthetic opcode variable-length
+ * instruction. We don't have a frag type that is smart
+ * enough to relax a operator, and so we just force all
+ * operators to behave like SEG_PASS1s. Clearly, if there is
+ * a demand we can invent a new or modified frag type and
+ * then coding up a frag for this case will be easy.
+ */
+ need_pass_2 = 1;
+ op_bad = _("Can't relocate expression error.");
+ break;
+
+ case O_big:
+ /* This is an error. Tahoe doesn't allow any expressions
+ bigger that a 32 bit long word. Any bigger has to be referenced
+ by address. */
+ op_bad = _("Expression is too large for a 32 bits.");
+ break;
+ }
+ if (*input_line_pointer != '\0')
+ {
+ op_bad = _("Junk at end of expression.");
+ }
+ }
+
+ end[1] = c;
+
+ /* I'm done, so restore optex */
+ *optex = segfault;
+
+
+ /*
+ * At this point in the game, we (in theory) have all the components of
+ * the operand at least parsed. Now it's time to check for syntax/semantic
+ * errors, and build the mode.
+ * This is what I have:
+ * deferred = 1 if '*'
+ * call_width = 0,1,2,4
+ * abs_width = 0,1,2,4
+ * com_width = 0,1,2,4
+ * immediate = 1 if '$'
+ * ndx = -1 or reg num
+ * dec_inc = '-' or '+' or ' '
+ * reg = -1 or reg num
+ * imreg = -1 or reg num
+ * topP->exp_of_operand
+ * really_none
+ */
+ /* Is there a displacement size? */
+ disp_size = (call_width ? call_width :
+ (com_width ? com_width :
+ abs_width ? abs_width : 0));
+
+ if (*op_bad == '\0')
+ {
+ if (imreg != -1)
+ {
+ /* Rn */
+ mode = TAHOE_DIRECT_REG;
+ if (deferred || immediate || (dec_inc != ' ') ||
+ (reg != -1) || !really_none)
+ op_bad = _("Syntax error in direct register mode.");
+ else if (ndx != -1)
+ op_bad = _("You can't index a register in direct register mode.");
+ else if (imreg == SP_REG && access == 'r')
+ op_bad =
+ _("SP can't be the source operand with direct register addressing.");
+ else if (access == 'a')
+ op_bad = _("Can't take the address of a register.");
+ else if (access == 'b')
+ op_bad = _("Direct Register can't be used in a branch.");
+ else if (width == 'q' && ((imreg % 2) || (imreg > 13)))
+ op_bad = _("For quad access, the register must be even and < 14.");
+ else if (call_width)
+ op_bad = _("You can't cast a direct register.");
+
+ if (*op_bad == '\0')
+ {
+ /* No errors, check for warnings */
+ if (width == 'q' && imreg == 12)
+ as_warn (_("Using reg 14 for quadwords can tromp the FP register."));
+
+ reg = imreg;
+ }
+
+ /* We know: imm = -1 */
+ }
+ else if (dec_inc == '-')
+ {
+ /* -(SP) */
+ mode = TAHOE_AUTO_DEC;
+ if (deferred || immediate || !really_none)
+ op_bad = _("Syntax error in auto-dec mode.");
+ else if (ndx != -1)
+ op_bad = _("You can't have an index auto dec mode.");
+ else if (access == 'r')
+ op_bad = _("Auto dec mode cant be used for reading.");
+ else if (reg != SP_REG)
+ op_bad = _("Auto dec only works of the SP register.");
+ else if (access == 'b')
+ op_bad = _("Auto dec can't be used in a branch.");
+ else if (width == 'q')
+ op_bad = _("Auto dec won't work with quadwords.");
+
+ /* We know: imm = -1, dec_inc != '-' */
+ }
+ else if (dec_inc == '+')
+ {
+ if (immediate || !really_none)
+ op_bad = _("Syntax error in one of the auto-inc modes.");
+ else if (deferred)
+ {
+ /* *(SP)+ */
+ mode = TAHOE_AUTO_INC_DEFERRED;
+ if (reg != SP_REG)
+ op_bad = _("Auto inc deferred only works of the SP register.");
+ else if (ndx != -1)
+ op_bad = _("You can't have an index auto inc deferred mode.");
+ else if (access == 'b')
+ op_bad = _("Auto inc can't be used in a branch.");
+ }
+ else
+ {
+ /* (SP)+ */
+ mode = TAHOE_AUTO_INC;
+ if (access == 'm' || access == 'w')
+ op_bad = _("You can't write to an auto inc register.");
+ else if (reg != SP_REG)
+ op_bad = _("Auto inc only works of the SP register.");
+ else if (access == 'b')
+ op_bad = _("Auto inc can't be used in a branch.");
+ else if (width == 'q')
+ op_bad = _("Auto inc won't work with quadwords.");
+ else if (ndx != -1)
+ op_bad = _("You can't have an index in auto inc mode.");
+ }
+
+ /* We know: imm = -1, dec_inc == ' ' */
+ }
+ else if (reg != -1)
+ {
+ if ((ndx != -1) && (reg == SP_REG))
+ op_bad = _("You can't index the sp register.");
+ if (deferred)
+ {
+ /* *<disp>(Rn) */
+ mode = TAHOE_REG_DISP_DEFERRED;
+ if (immediate)
+ op_bad = _("Syntax error in register displaced mode.");
+ }
+ else if (really_none)
+ {
+ /* (Rn) */
+ mode = TAHOE_REG_DEFERRED;
+ /* if reg = SP then cant be indexed */
+ }
+ else
+ {
+ /* <disp>(Rn) */
+ mode = TAHOE_REG_DISP;
+ }
+
+ /* We know: imm = -1, dec_inc == ' ', Reg = -1 */
+ }
+ else
+ {
+ if (really_none)
+ op_bad = _("An offest is needed for this operand.");
+ if (deferred && immediate)
+ {
+ /* *$<ADDR> */
+ mode = TAHOE_ABSOLUTE_ADDR;
+ disp_size = 4;
+ }
+ else if (immediate)
+ {
+ /* $<disp> */
+ mode = TAHOE_IMMEDIATE;
+ if (ndx != -1)
+ op_bad = _("You can't index a register in immediate mode.");
+ if (access == 'a')
+ op_bad = _("Immediate access can't be used as an address.");
+ /* ponder the wisdom of a cast because it doesn't do any good. */
+ }
+ else if (deferred)
+ {
+ /* *<disp> */
+ mode = TAHOE_DISP_REL_DEFERRED;
+ }
+ else
+ {
+ /* <disp> */
+ mode = TAHOE_DISPLACED_RELATIVE;
+ }
+ }
+ }
+
+ /*
+ * At this point, all the errors we can do have be checked for.
+ * We can build the 'top'. */
+
+ topP->top_ndx = ndx;
+ topP->top_reg = reg;
+ topP->top_mode = mode;
+ topP->top_error = op_bad;
+ topP->top_dispsize = disp_size;
+} /* tip_op */
+
+/*
+ * t i p ( )
+ *
+ * This converts a string into a tahoe instruction.
+ * The string must be a bare single instruction in tahoe (with BSD4 frobs)
+ * format.
+ * It provides at most one fatal error message (which stops the scan)
+ * some warning messages as it finds them.
+ * The tahoe instruction is returned in exploded form.
+ *
+ * The exploded instruction is returned to a struct tit of your choice.
+ * #include "tahoe-inst.h" to know what a struct tit is.
+ *
+ */
+
+static void
+tip (titP, instring)
+ struct tit *titP; /* We build an exploded instruction here. */
+ char *instring; /* Text of a vax instruction: we modify. */
+{
+ register struct tot_wot *twP = NULL; /* How to bit-encode this opcode. */
+ register char *p; /* 1/skip whitespace.2/scan vot_how */
+ register char *q; /* */
+ register unsigned char count; /* counts number of operands seen */
+ register struct top *operandp;/* scan operands in struct tit */
+ register char *alloperr = ""; /* error over all operands */
+ register char c; /* Remember char, (we clobber it
+ with '\0' temporarily). */
+ char *save_input_line_pointer;
+
+ if (*instring == ' ')
+ ++instring; /* Skip leading whitespace. */
+ for (p = instring; *p && *p != ' '; p++)
+ ; /* MUST end in end-of-string or
+ exactly 1 space. */
+ /* Scanned up to end of operation-code. */
+ /* Operation-code is ended with whitespace. */
+ if (p == instring)
+ {
+ titP->tit_error = _("No operator");
+ count = 0;
+ titP->tit_opcode = 0;
+ }
+ else
+ {
+ c = *p;
+ *p = '\0';
+ /*
+ * Here with instring pointing to what better be an op-name, and p
+ * pointing to character just past that.
+ * We trust instring points to an op-name, with no whitespace.
+ */
+ twP = (struct tot_wot *) hash_find (op_hash, instring);
+ *p = c; /* Restore char after op-code. */
+ if (twP == 0)
+ {
+ titP->tit_error = _("Unknown operator");
+ count = 0;
+ titP->tit_opcode = 0;
+ }
+ else
+ {
+ /*
+ * We found a match! So lets pick up as many operands as the
+ * instruction wants, and even gripe if there are too many.
+ * We expect comma to seperate each operand.
+ * We let instring track the text, while p tracks a part of the
+ * struct tot.
+ */
+
+ count = 0; /* no operands seen yet */
+ instring = p + (*p != '\0'); /* point past the operation code */
+ /* tip_op() screws with the input_line_pointer, so save it before
+ I jump in */
+ save_input_line_pointer = input_line_pointer;
+ for (p = twP->args, operandp = titP->tit_operand;
+ !*alloperr && *p;
+ operandp++, p += 2)
+ {
+ /*
+ * Here to parse one operand. Leave instring pointing just
+ * past any one ',' that marks the end of this operand.
+ */
+ if (!p[1])
+ as_fatal (_("Compiler bug: ODD number of bytes in arg structure %s."),
+ twP->args);
+ else if (*instring)
+ {
+ for (q = instring; (*q != ',' && *q != '\0'); q++)
+ {
+ if (*q == '\'' && q[1] != '\0') /* Jump quoted characters */
+ q++;
+ }
+ c = *q;
+ /*
+ * Q points to ',' or '\0' that ends argument. C is that
+ * character.
+ */
+ *q = '\0';
+ operandp->top_access = p[0];
+ operandp->top_width = p[1];
+ tip_op (instring - 1, operandp);
+ *q = c; /* Restore input text. */
+ if (*(operandp->top_error))
+ {
+ alloperr = operandp->top_error;
+ }
+ instring = q + (c ? 1 : 0); /* next operand (if any) */
+ count++; /* won another argument, may have an operr */
+ }
+ else
+ alloperr = _("Not enough operands");
+ }
+ /* Restore the pointer. */
+ input_line_pointer = save_input_line_pointer;
+
+ if (!*alloperr)
+ {
+ if (*instring == ' ')
+ instring++; /* Skip whitespace. */
+ if (*instring)
+ alloperr = _("Too many operands");
+ }
+ titP->tit_error = alloperr;
+ }
+ }
+
+ titP->tit_opcode = twP->code; /* The op-code. */
+ titP->tit_operands = count;
+} /* tip */
+
+/* md_assemble() emit frags for 1 instruction */
+void
+md_assemble (instruction_string)
+ char *instruction_string; /* A string: assemble 1 instruction. */
+{
+ char *p;
+ register struct top *operandP;/* An operand. Scans all operands. */
+ /* char c_save; fixme: remove this line *//* What used to live after an expression. */
+ /* struct frag *fragP; fixme: remove this line *//* Fragment of code we just made. */
+ /* register struct top *end_operandP; fixme: remove this line *//* -> slot just after last operand
+ Limit of the for (each operand). */
+ register expressionS *expP; /* -> expression values for this operand */
+
+ /* These refer to an instruction operand expression. */
+ segT to_seg; /* Target segment of the address. */
+
+ register valueT this_add_number;
+ register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */
+
+ /* tahoe_opcodeT opcode_as_number; fixme: remove this line *//* The opcode as a number. */
+ char *opcodeP; /* Where it is in a frag. */
+ /* char *opmodeP; fixme: remove this line *//* Where opcode type is, in a frag. */
+
+ int dispsize; /* From top_dispsize: tahoe_operand_width
+ (in bytes) */
+ int is_undefined; /* 1 if operand expression's
+ segment not known yet. */
+ int pc_rel; /* Is this operand pc relative? */
+
+ /* Decode the operand. */
+ tip (&t, instruction_string);
+
+ /*
+ * Check to see if this operand decode properly.
+ * Notice that we haven't made any frags yet.
+ * If it goofed, then this instruction will wedge in any pass,
+ * and we can safely flush it, without causing interpass symbol phase
+ * errors. That is, without changing label values in different passes.
+ */
+ if (*t.tit_error)
+ {
+ as_warn (_("Ignoring statement due to \"%s\""), t.tit_error);
+ }
+ else
+ {
+ /* We saw no errors in any operands - try to make frag(s) */
+ /* Emit op-code. */
+ /* Remember where it is, in case we want to modify the op-code later. */
+ opcodeP = frag_more (1);
+ *opcodeP = t.tit_opcode;
+ /* Now do each operand. */
+ for (operandP = t.tit_operand;
+ operandP < t.tit_operand + t.tit_operands;
+ operandP++)
+ { /* for each operand */
+ expP = &(operandP->exp_of_operand);
+ if (operandP->top_ndx >= 0)
+ {
+ /* Indexed addressing byte
+ Legality of indexed mode already checked: it is OK */
+ FRAG_APPEND_1_CHAR (0x40 + operandP->top_ndx);
+ } /* if(top_ndx>=0) */
+
+ /* Here to make main operand frag(s). */
+ this_add_number = expP->X_add_number;
+ this_add_symbol = expP->X_add_symbol;
+ to_seg = operandP->seg_of_operand;
+ know (to_seg == SEG_UNKNOWN || \
+ to_seg == SEG_ABSOLUTE || \
+ to_seg == SEG_DATA || \
+ to_seg == SEG_TEXT || \
+ to_seg == SEG_BSS);
+ is_undefined = (to_seg == SEG_UNKNOWN);
+ /* Do we know how big this opperand is? */
+ dispsize = operandP->top_dispsize;
+ pc_rel = 0;
+ /* Deal with the branch possabilities. (Note, this doesn't include
+ jumps.)*/
+ if (operandP->top_access == 'b')
+ {
+ /* Branches must be expressions. A psuedo branch can also jump to
+ an absolute address. */
+ if (to_seg == now_seg || is_undefined)
+ {
+ /* If is_undefined, then it might BECOME now_seg by relax time. */
+ if (dispsize)
+ {
+ /* I know how big the branch is supposed to be (it's a normal
+ branch), so I set up the frag, and let GAS do the rest. */
+ p = frag_more (dispsize);
+ fix_new (frag_now, p - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ size_to_fx (dispsize, 1),
+ NULL);
+ }
+ else
+ {
+ /* (to_seg==now_seg || to_seg == SEG_UNKNOWN) && dispsize==0 */
+ /* If we don't know how big it is, then its a synthetic branch,
+ so we set up a simple relax state. */
+ switch (operandP->top_width)
+ {
+ case TAHOE_WIDTH_CONDITIONAL_JUMP:
+ /* Simple (conditional) jump. I may have to reverse the
+ condition of opcodeP, and then jump to my destination.
+ I set 1 byte aside for the branch off set, and could need 6
+ more bytes for the pc_rel jump */
+ frag_var (rs_machine_dependent, 7, 1,
+ ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
+ is_undefined ? STATE_UNDF : STATE_BYTE),
+ this_add_symbol, this_add_number, opcodeP);
+ break;
+ case TAHOE_WIDTH_ALWAYS_JUMP:
+ /* Simple (unconditional) jump. I may have to convert this to
+ a word branch, or an absolute jump. */
+ frag_var (rs_machine_dependent, 5, 1,
+ ENCODE_RELAX (STATE_ALWAYS_BRANCH,
+ is_undefined ? STATE_UNDF : STATE_BYTE),
+ this_add_symbol, this_add_number, opcodeP);
+ break;
+ /* The smallest size for the next 2 cases is word. */
+ case TAHOE_WIDTH_BIG_REV_JUMP:
+ frag_var (rs_machine_dependent, 8, 2,
+ ENCODE_RELAX (STATE_BIG_REV_BRANCH,
+ is_undefined ? STATE_UNDF : STATE_WORD),
+ this_add_symbol, this_add_number,
+ opcodeP);
+ break;
+ case TAHOE_WIDTH_BIG_NON_REV_JUMP:
+ frag_var (rs_machine_dependent, 10, 2,
+ ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH,
+ is_undefined ? STATE_UNDF : STATE_WORD),
+ this_add_symbol, this_add_number,
+ opcodeP);
+ break;
+ default:
+ as_fatal (_("Compliler bug: Got a case (%d) I wasn't expecting."),
+ operandP->top_width);
+ }
+ }
+ }
+ else
+ {
+ /* to_seg != now_seg && to_seg != seg_unknown (still in branch)
+ In other words, I'm jumping out of my segment so extend the
+ branches to jumps, and let GAS fix them. */
+
+ /* These are "branches" what will always be branches around a jump
+ to the correct addresss in real life.
+ If to_seg is SEG_ABSOLUTE, just encode the branch in,
+ else let GAS fix the address. */
+
+ switch (operandP->top_width)
+ {
+ /* The theory:
+ For SEG_ABSOLUTE, then mode is ABSOLUTE_ADDR, jump
+ to that addresss (not pc_rel).
+ For other segs, address is a long word PC rel jump. */
+ case TAHOE_WIDTH_CONDITIONAL_JUMP:
+ /* b<cond> */
+ /* To reverse the condition in a TAHOE branch,
+ complement bit 4 */
+ *opcodeP ^= 0x10;
+ p = frag_more (7);
+ *p++ = 6;
+ *p++ = TAHOE_JMP;
+ *p++ = (operandP->top_mode ==
+ TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
+ TAHOE_PC_REL_LONG);
+ fix_new (frag_now, p - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
+ /*
+ * Now (eg) BLEQ 1f
+ * JMP foo
+ * 1:
+ */
+ break;
+ case TAHOE_WIDTH_ALWAYS_JUMP:
+ /* br, just turn it into a jump */
+ *opcodeP = TAHOE_JMP;
+ p = frag_more (5);
+ *p++ = (operandP->top_mode ==
+ TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
+ TAHOE_PC_REL_LONG);
+ fix_new (frag_now, p - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
+ /* Now (eg) JMP foo */
+ break;
+ case TAHOE_WIDTH_BIG_REV_JUMP:
+ p = frag_more (8);
+ *opcodeP ^= 0x10;
+ *p++ = 0;
+ *p++ = 6;
+ *p++ = TAHOE_JMP;
+ *p++ = (operandP->top_mode ==
+ TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
+ TAHOE_PC_REL_LONG);
+ fix_new (frag_now, p - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
+ /*
+ * Now (eg) ACBx 1f
+ * JMP foo
+ * 1:
+ */
+ break;
+ case TAHOE_WIDTH_BIG_NON_REV_JUMP:
+ p = frag_more (10);
+ *p++ = 0;
+ *p++ = 2;
+ *p++ = TAHOE_BRB;
+ *p++ = 6;
+ *p++ = TAHOE_JMP;
+ *p++ = (operandP->top_mode ==
+ TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
+ TAHOE_PC_REL_LONG);
+ fix_new (frag_now, p - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
+ /*
+ * Now (eg) xOBxxx 1f
+ * BRB 2f
+ * 1: JMP @#foo
+ * 2:
+ */
+ break;
+ case 'b':
+ case 'w':
+ as_warn (_("Real branch displacements must be expressions."));
+ break;
+ default:
+ as_fatal (_("Complier error: I got an unknown synthetic branch :%c"),
+ operandP->top_width);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* It ain't a branch operand. */
+ switch (operandP->top_mode)
+ {
+ /* Auto-foo access, only works for one reg (SP)
+ so the only thing needed is the mode. */
+ case TAHOE_AUTO_DEC:
+ case TAHOE_AUTO_INC:
+ case TAHOE_AUTO_INC_DEFERRED:
+ FRAG_APPEND_1_CHAR (operandP->top_mode);
+ break;
+
+ /* Numbered Register only access. Only thing needed is the
+ mode + Register number */
+ case TAHOE_DIRECT_REG:
+ case TAHOE_REG_DEFERRED:
+ FRAG_APPEND_1_CHAR (operandP->top_mode + operandP->top_reg);
+ break;
+
+ /* An absolute address. It's size is always 5 bytes.
+ (mode_type + 4 byte address). */
+ case TAHOE_ABSOLUTE_ADDR:
+ know ((this_add_symbol == NULL));
+ p = frag_more (5);
+ *p = TAHOE_ABSOLUTE_ADDR;
+ md_number_to_chars (p + 1, this_add_number, 4);
+ break;
+
+ /* Immediate data. If the size isn't known, then it's an address
+ + and offset, which is 4 bytes big. */
+ case TAHOE_IMMEDIATE:
+ if (this_add_symbol != NULL)
+ {
+ p = frag_more (5);
+ *p++ = TAHOE_IMMEDIATE_LONGWORD;
+ fix_new (frag_now, p - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ FX_32, NULL);
+ }
+ else
+ {
+ /* It's a integer, and I know it's size. */
+ if ((unsigned) this_add_number < 0x40)
+ {
+ /* Will it fit in a literal? */
+ FRAG_APPEND_1_CHAR ((byte) this_add_number);
+ }
+ else
+ {
+ p = frag_more (dispsize + 1);
+ switch (dispsize)
+ {
+ case 1:
+ *p++ = TAHOE_IMMEDIATE_BYTE;
+ *p = (byte) this_add_number;
+ break;
+ case 2:
+ *p++ = TAHOE_IMMEDIATE_WORD;
+ md_number_to_chars (p, this_add_number, 2);
+ break;
+ case 4:
+ *p++ = TAHOE_IMMEDIATE_LONGWORD;
+ md_number_to_chars (p, this_add_number, 4);
+ break;
+ }
+ }
+ }
+ break;
+
+ /* Distance from the PC. If the size isn't known, we have to relax
+ into it. The difference between this and disp(sp) is that
+ this offset is pc_rel, and disp(sp) isn't.
+ Note the drop through code. */
+
+ case TAHOE_DISPLACED_RELATIVE:
+ case TAHOE_DISP_REL_DEFERRED:
+ operandP->top_reg = PC_REG;
+ pc_rel = 1;
+
+ /* Register, plus a displacement mode. Save the register number,
+ and weather its deffered or not, and relax the size if it isn't
+ known. */
+ case TAHOE_REG_DISP:
+ case TAHOE_REG_DISP_DEFERRED:
+ if (operandP->top_mode == TAHOE_DISP_REL_DEFERRED ||
+ operandP->top_mode == TAHOE_REG_DISP_DEFERRED)
+ operandP->top_reg += 0x10; /* deffered mode is always 0x10 higher
+ than it's non-deffered sibling. */
+
+ /* Is this a value out of this segment?
+ The first part of this conditional is a cludge to make gas
+ produce the same output as 'as' when there is a lable, in
+ the current segment, displaceing a register. It's strange,
+ and no one in their right mind would do it, but it's easy
+ to cludge. */
+ if ((dispsize == 0 && !pc_rel) ||
+ (to_seg != now_seg && !is_undefined && to_seg != SEG_ABSOLUTE))
+ dispsize = 4;
+
+ if (dispsize == 0)
+ {
+ /*
+ * We have a SEG_UNKNOWN symbol, or the size isn't cast.
+ * It might turn out to be in the same segment as
+ * the instruction, permitting relaxation.
+ */
+ p = frag_var (rs_machine_dependent, 5, 2,
+ ENCODE_RELAX (STATE_PC_RELATIVE,
+ is_undefined ? STATE_UNDF : STATE_BYTE),
+ this_add_symbol, this_add_number, 0);
+ *p = operandP->top_reg;
+ }
+ else
+ {
+ /* Either this is an abs, or a cast. */
+ p = frag_more (dispsize + 1);
+ switch (dispsize)
+ {
+ case 1:
+ *p = TAHOE_PC_OR_BYTE + operandP->top_reg;
+ break;
+ case 2:
+ *p = TAHOE_PC_OR_WORD + operandP->top_reg;
+ break;
+ case 4:
+ *p = TAHOE_PC_OR_LONG + operandP->top_reg;
+ break;
+ };
+ fix_new (frag_now, p + 1 - frag_now->fr_literal,
+ this_add_symbol, this_add_number,
+ size_to_fx (dispsize, pc_rel), NULL);
+ }
+ break;
+ default:
+ as_fatal (_("Barf, bad mode %x\n"), operandP->top_mode);
+ }
+ }
+ } /* for(operandP) */
+ } /* if(!need_pass_2 && !goofed) */
+} /* tahoe_assemble() */
+
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+} /* md_undefined_symbol() */
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ return ((size + 7) & ~7); /* Round all sects to multiple of 8 */
+} /* md_section_align() */
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the sparc, they're relative to the address of the offset, plus
+ its size. This gets us to the following instruction.
+ (??? Is this right? FIXME-SOON) */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return (((fixP->fx_type == FX_8
+ || fixP->fx_type == FX_PCREL8)
+ ? 1
+ : ((fixP->fx_type == FX_16
+ || fixP->fx_type == FX_PCREL16)
+ ? 2
+ : ((fixP->fx_type == FX_32
+ || fixP->fx_type == FX_PCREL32)
+ ? 4
+ : 0))) + fixP->fx_where + fixP->fx_frag->fr_address);
+} /* md_pcrel_from() */
+
+int
+tc_is_pcrel (fixP)
+ fixS *fixP;
+{
+ /* should never be called */
+ know (0);
+ return (0);
+} /* tc_is_pcrel() */
+
+/* end of tc-tahoe.c */
diff --git a/gas/config/tc-tahoe.h b/gas/config/tc-tahoe.h
new file mode 100644
index 00000000000..be8a5bea8e2
--- /dev/null
+++ b/gas/config/tc-tahoe.h
@@ -0,0 +1,43 @@
+/* This file is tc-tahoe.h
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TC_TAHOE 1
+
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define NO_LISTING
+
+#define tc_headers_hook(a) {;} /* don't need it. */
+#define tc_crawl_symbol_chain(a) {;} /* don't need it. */
+#define tc_aout_pre_write_hook(a) {;}
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of tc-tahoe.h */
diff --git a/gas/config/tc-tic30.c b/gas/config/tc-tic30.c
new file mode 100644
index 00000000000..61ed905e47a
--- /dev/null
+++ b/gas/config/tc-tic30.c
@@ -0,0 +1,1887 @@
+/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
+ Copyright (C) 1998 Free Software Foundation.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ Texas Instruments TMS320C30 machine specific gas.
+ Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
+ Bugs & suggestions are completely welcome. This is free software.
+ Please help us make it better.
+ */
+
+#include "as.h"
+#include "opcode/tic30.h"
+
+/* put here all non-digit non-letter charcters that may occur in an operand */
+static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
+static char *ordinal_names[] =
+{"first", "second", "third", "fourth", "fifth"};
+
+const int md_reloc_size = 0;
+
+const char comment_chars[] = ";";
+const char line_comment_chars[] = "*";
+const char line_separator_chars[] = "";
+
+const char *md_shortopts = "";
+struct option md_longopts[] =
+{
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof (md_longopts);
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "fFdDxX";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* tables for lexical analysis */
+static char opcode_chars[256];
+static char register_chars[256];
+static char operand_chars[256];
+static char space_chars[256];
+static char identifier_chars[256];
+static char digit_chars[256];
+
+/* lexical macros */
+#define is_opcode_char(x) (opcode_chars[(unsigned char) x])
+#define is_operand_char(x) (operand_chars[(unsigned char) x])
+#define is_register_char(x) (register_chars[(unsigned char) x])
+#define is_space_char(x) (space_chars[(unsigned char) x])
+#define is_identifier_char(x) (identifier_chars[(unsigned char) x])
+#define is_digit_char(x) (digit_chars[(unsigned char) x])
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {0, 0, 0}
+};
+
+#undef USE_STDOUT
+#define USE_STDOUT 1
+
+#ifdef USE_STDARG
+
+#include <stdarg.h>
+
+int
+debug (const char *string,...)
+{
+ if (flag_debug)
+ {
+ va_list argptr;
+ char str[100];
+
+ va_start (argptr, string);
+ vsprintf (str, string, argptr);
+ if (str[0] == '\0')
+ return (0);
+ va_end (argptr);
+ fputs (str, USE_STDOUT ? stdout : stderr);
+ return strlen (str);
+ }
+ else
+ return 0;
+}
+#else
+int
+debug (string, va_alist)
+ const char *string;
+ va_dcl
+{
+ if (flag_debug)
+ {
+ va_list argptr;
+ char str[100];
+ int cnt;
+
+ va_start (argptr, string);
+ cnt = vsprintf (str, string, argptr);
+ if (str[0] == NULL)
+ return (0);
+ va_end (argptr);
+ fputs (str, USE_STDOUT ? stdout : stderr);
+ return (cnt);
+ }
+ else
+ return 0;
+}
+#endif
+
+/* hash table for opcode lookup */
+static struct hash_control *op_hash;
+/* hash table for parallel opcode lookup */
+static struct hash_control *parop_hash;
+/* hash table for register lookup */
+static struct hash_control *reg_hash;
+/* hash table for indirect addressing lookup */
+static struct hash_control *ind_hash;
+
+void
+md_begin ()
+{
+ const char *hash_err;
+ debug ("In md_begin()\n");
+ op_hash = hash_new ();
+ {
+ const template *current_optab = tic30_optab;
+ for (; current_optab < tic30_optab_end; current_optab++)
+ {
+ hash_err = hash_insert (op_hash, current_optab->name, (char *) current_optab);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_optab->name, hash_err);
+ }
+ }
+ parop_hash = hash_new ();
+ {
+ const partemplate *current_parop = tic30_paroptab;
+ for (; current_parop < tic30_paroptab_end; current_parop++)
+ {
+ hash_err = hash_insert (parop_hash, current_parop->name, (char *) current_parop);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_parop->name, hash_err);
+ }
+ }
+ reg_hash = hash_new ();
+ {
+ const reg *current_reg = tic30_regtab;
+ for (; current_reg < tic30_regtab_end; current_reg++)
+ {
+ hash_err = hash_insert (reg_hash, current_reg->name, (char *) current_reg);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_reg->name, hash_err);
+ }
+ }
+ ind_hash = hash_new ();
+ {
+ const ind_addr_type *current_ind = tic30_indaddr_tab;
+ for (; current_ind < tic30_indaddrtab_end; current_ind++)
+ {
+ hash_err = hash_insert (ind_hash, current_ind->syntax, (char *) current_ind);
+ if (hash_err)
+ as_fatal ("Internal Error: Can't Hash %s: %s", current_ind->syntax, hash_err);
+ }
+ }
+ /* fill in lexical tables: opcode_chars, operand_chars, space_chars */
+ {
+ register int c;
+ register char *p;
+
+ for (c = 0; c < 256; c++)
+ {
+ if (islower (c) || isdigit (c))
+ {
+ opcode_chars[c] = c;
+ register_chars[c] = c;
+ }
+ else if (isupper (c))
+ {
+ opcode_chars[c] = tolower (c);
+ register_chars[c] = opcode_chars[c];
+ }
+ else if (c == ')' || c == '(')
+ {
+ register_chars[c] = c;
+ }
+ if (isupper (c) || islower (c) || isdigit (c))
+ operand_chars[c] = c;
+ if (isdigit (c) || c == '-')
+ digit_chars[c] = c;
+ if (isalpha (c) || c == '_' || c == '.' || isdigit (c))
+ identifier_chars[c] = c;
+ if (c == ' ' || c == '\t')
+ space_chars[c] = c;
+ if (c == '_')
+ opcode_chars[c] = c;
+ }
+ for (p = operand_special_chars; *p != '\0'; p++)
+ operand_chars[(unsigned char) *p] = *p;
+ }
+}
+
+/* Address Mode OR values */
+#define AM_Register 0x00000000
+#define AM_Direct 0x00200000
+#define AM_Indirect 0x00400000
+#define AM_Immediate 0x00600000
+#define AM_NotReq 0xFFFFFFFF
+
+/* PC Relative OR values */
+#define PC_Register 0x00000000
+#define PC_Relative 0x02000000
+
+typedef struct
+{
+ unsigned op_type;
+ struct
+ {
+ int resolved;
+ unsigned address;
+ char *label;
+ expressionS direct_expr;
+ }
+ direct;
+ struct
+ {
+ unsigned mod;
+ int ARnum;
+ unsigned char disp;
+ }
+ indirect;
+ struct
+ {
+ unsigned opcode;
+ }
+ reg;
+ struct
+ {
+ int resolved;
+ int decimal_found;
+ float f_number;
+ int s_number;
+ unsigned int u_number;
+ char *label;
+ expressionS imm_expr;
+ }
+ immediate;
+}
+operand;
+
+int tic30_parallel_insn PARAMS ((char *));
+operand *tic30_operand PARAMS ((char *));
+char *tic30_find_parallel_insn PARAMS ((char *, char *));
+
+template *opcode;
+
+struct tic30_insn
+ {
+ template *tm; /* Template of current instruction */
+ unsigned opcode; /* Final opcode */
+ int operands; /* Number of given operands */
+ /* Type of operand given in instruction */
+ operand *operand_type[MAX_OPERANDS];
+ unsigned addressing_mode; /* Final addressing mode of instruction */
+ };
+
+struct tic30_insn insn;
+static int found_parallel_insn;
+
+void
+md_assemble (line)
+ char *line;
+{
+ template *opcode;
+ char *current_posn;
+ char *token_start;
+ char save_char;
+ int count;
+
+ debug ("In md_assemble() with argument %s\n", line);
+ memset (&insn, '\0', sizeof (insn));
+ if (found_parallel_insn)
+ {
+ debug ("Line is second part of parallel instruction\n\n");
+ found_parallel_insn = 0;
+ return;
+ }
+ if ((current_posn = tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
+ current_posn = line;
+ else
+ found_parallel_insn = 1;
+ while (is_space_char (*current_posn))
+ current_posn++;
+ token_start = current_posn;
+ if (!is_opcode_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in opcode", output_invalid (*current_posn));
+ return;
+ }
+ /* Check if instruction is a parallel instruction by seeing if the first
+ character is a q. */
+ if (*token_start == 'q')
+ {
+ if (tic30_parallel_insn (token_start))
+ {
+ if (found_parallel_insn)
+ free (token_start);
+ return;
+ }
+ }
+ while (is_opcode_char (*current_posn))
+ current_posn++;
+ { /* Find instruction */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ opcode = (template *) hash_find (op_hash, token_start);
+ if (opcode)
+ {
+ debug ("Found instruction %s\n", opcode->name);
+ insn.tm = opcode;
+ }
+ else
+ {
+ debug ("Didn't find insn\n");
+ as_bad ("Unknown TMS320C30 instruction: %s", token_start);
+ return;
+ }
+ *current_posn = save_char;
+ }
+ if (*current_posn != END_OF_INSN)
+ { /* Find operands */
+ int paren_not_balanced;
+ int expecting_operand = 0;
+ int this_operand;
+ do
+ {
+ /* skip optional white space before operand */
+ while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
+ {
+ if (!is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s before %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return;
+ }
+ current_posn++;
+ }
+ token_start = current_posn; /* after white space */
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *current_posn != ',')
+ {
+ if (*current_posn == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ as_bad ("Unbalanced parenthesis in %s operand.",
+ ordinal_names[insn.operands]);
+ return;
+ }
+ else
+ break; /* we are done */
+ }
+ else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return;
+ }
+ if (*current_posn == '(')
+ ++paren_not_balanced;
+ if (*current_posn == ')')
+ --paren_not_balanced;
+ current_posn++;
+ }
+ if (current_posn != token_start)
+ { /* yes, we've read in another operand */
+ this_operand = insn.operands++;
+ if (insn.operands > MAX_OPERANDS)
+ {
+ as_bad ("Spurious operands; (%d operands/instruction max)",
+ MAX_OPERANDS);
+ return;
+ }
+ /* now parse operand adding info to 'insn' as we go along */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ insn.operand_type[this_operand] = tic30_operand (token_start);
+ *current_posn = save_char;
+ if (insn.operand_type[this_operand] == NULL)
+ return;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ as_bad ("Expecting operand after ','; got nothing");
+ return;
+ }
+ if (*current_posn == ',')
+ {
+ as_bad ("Expecting operand before ','; got nothing");
+ return;
+ }
+ }
+ /* now *current_posn must be either ',' or END_OF_INSN */
+ if (*current_posn == ',')
+ {
+ if (*++current_posn == END_OF_INSN)
+ { /* just skip it, if it's \n complain */
+ as_bad ("Expecting operand after ','; got nothing");
+ return;
+ }
+ expecting_operand = 1;
+ }
+ }
+ while (*current_posn != END_OF_INSN); /* until we get end of insn */
+ }
+ debug ("Number of operands found: %d\n", insn.operands);
+ /* Check that number of operands is correct */
+ if (insn.operands != insn.tm->operands)
+ {
+ int i;
+ int numops = insn.tm->operands;
+ /* If operands are not the same, then see if any of the operands are not
+ required. Then recheck with number of given operands. If they are still not
+ the same, then give an error, otherwise carry on. */
+ for (i = 0; i < insn.tm->operands; i++)
+ if (insn.tm->operand_types[i] & NotReq)
+ numops--;
+ if (insn.operands != numops)
+ {
+ as_bad ("Incorrect number of operands given");
+ return;
+ }
+ }
+ insn.addressing_mode = AM_NotReq;
+ for (count = 0; count < insn.operands; count++)
+ {
+ if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
+ {
+ debug ("Operand %d matches\n", count + 1);
+ /* If instruction has two operands and has an AddressMode modifier then set
+ addressing mode type for instruction */
+ if (insn.tm->opcode_modifier == AddressMode)
+ {
+ int addr_insn = 0;
+ /* Store instruction uses the second operand for the address mode. */
+ if ((insn.tm->operand_types[1] & (Indirect | Direct)) == (Indirect | Direct))
+ addr_insn = 1;
+ if (insn.operand_type[addr_insn]->op_type & (AllReg))
+ insn.addressing_mode = AM_Register;
+ else if (insn.operand_type[addr_insn]->op_type & Direct)
+ insn.addressing_mode = AM_Direct;
+ else if (insn.operand_type[addr_insn]->op_type & Indirect)
+ insn.addressing_mode = AM_Indirect;
+ else
+ insn.addressing_mode = AM_Immediate;
+ }
+ }
+ else
+ {
+ as_bad ("The %s operand doesn't match", ordinal_names[count]);
+ return;
+ }
+ }
+ /* Now set the addressing mode for 3 operand instructions. */
+ if ((insn.tm->operand_types[0] & op3T1) && (insn.tm->operand_types[1] & op3T2))
+ {
+ /* Set the addressing mode to the values used for 2 operand instructions in the
+ G addressing field of the opcode. */
+ char *p;
+ switch (insn.operand_type[0]->op_type)
+ {
+ case Rn:
+ case ARn:
+ case DPReg:
+ case OtherReg:
+ if (insn.operand_type[1]->op_type & (AllReg))
+ insn.addressing_mode = AM_Register;
+ else if (insn.operand_type[1]->op_type & Indirect)
+ insn.addressing_mode = AM_Direct;
+ else
+ {
+ /* Shouldn't make it to this stage */
+ as_bad ("Incompatible first and second operands in instruction");
+ return;
+ }
+ break;
+ case Indirect:
+ if (insn.operand_type[1]->op_type & (AllReg))
+ insn.addressing_mode = AM_Indirect;
+ else if (insn.operand_type[1]->op_type & Indirect)
+ insn.addressing_mode = AM_Immediate;
+ else
+ {
+ /* Shouldn't make it to this stage */
+ as_bad ("Incompatible first and second operands in instruction");
+ return;
+ }
+ break;
+ }
+ /* Now make up the opcode for the 3 operand instructions. As in parallel
+ instructions, there will be no unresolved values, so they can be fully formed
+ and added to the frag table. */
+ insn.opcode = insn.tm->base_opcode;
+ if (insn.operand_type[0]->op_type & Indirect)
+ {
+ insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
+ insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
+ }
+ else
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ if (insn.operand_type[1]->op_type & Indirect)
+ {
+ insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
+ insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
+ }
+ else
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
+ if (insn.operands == 3)
+ insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
+ insn.opcode |= insn.addressing_mode;
+ p = frag_more (INSN_SIZE);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ { /* Not a three operand instruction */
+ char *p;
+ int am_insn = -1;
+ insn.opcode = insn.tm->base_opcode;
+ /* Create frag for instruction - all instructions are 4 bytes long. */
+ p = frag_more (INSN_SIZE);
+ if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
+ {
+ insn.opcode |= insn.addressing_mode;
+ if (insn.addressing_mode == AM_Indirect)
+ {
+ /* Determine which operand gives the addressing mode */
+ if (insn.operand_type[0]->op_type & Indirect)
+ am_insn = 0;
+ if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Indirect))
+ am_insn = 1;
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
+ insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.addressing_mode == AM_Register)
+ {
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.addressing_mode == AM_Direct)
+ {
+ if (insn.operand_type[0]->op_type & Direct)
+ am_insn = 0;
+ if ((insn.operands > 1) && (insn.operand_type[1]->op_type & Direct))
+ am_insn = 1;
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
+ if (insn.operand_type[am_insn]->direct.resolved == 1)
+ {
+ /* Resolved values can be placed straight into instruction word, and output */
+ insn.opcode |= (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ { /* Unresolved direct addressing mode instruction */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[am_insn]->direct.direct_expr, 0, 0);
+ }
+ }
+ else if (insn.addressing_mode == AM_Immediate)
+ {
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ char *keeploc;
+ int size;
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ switch (insn.tm->imm_arg_type)
+ {
+ case Imm_Float:
+ debug ("Floating point first operand\n");
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ keeploc = input_line_pointer;
+ input_line_pointer = insn.operand_type[0]->immediate.label;
+ if (md_atof ('f', p + 2, &size) != 0)
+ {
+ as_bad ("invalid short form floating point immediate operand");
+ return;
+ }
+ input_line_pointer = keeploc;
+ break;
+ case Imm_UInt:
+ debug ("Unsigned int first operand\n");
+ if (insn.operand_type[0]->immediate.decimal_found)
+ as_warn ("rounding down first operand float to unsigned int");
+ if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
+ as_warn ("only lower 16-bits of first operand are used");
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ break;
+ case Imm_SInt:
+ debug ("Int first operand\n");
+ if (insn.operand_type[0]->immediate.decimal_found)
+ as_warn ("rounding down first operand float to signed int");
+ if (insn.operand_type[0]->immediate.s_number < -32768 ||
+ insn.operand_type[0]->immediate.s_number > 32767)
+ {
+ as_bad ("first operand is too large for 16-bit signed int");
+ return;
+ }
+ insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ break;
+ }
+ }
+ else
+ { /* Unresolved immediate label */
+ if (insn.operands > 1)
+ insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ }
+ }
+ }
+ else if (insn.tm->opcode_modifier == PCRel)
+ {
+ /* Conditional Branch and Call instructions */
+ if ((insn.tm->operand_types[0] & (AllReg | Disp)) == (AllReg | Disp))
+ {
+ if (insn.operand_type[0]->op_type & (AllReg))
+ {
+ insn.opcode |= (insn.operand_type[0]->reg.opcode);
+ insn.opcode |= PC_Register;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ insn.opcode |= PC_Relative;
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ insn.opcode |= (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2, &insn.operand_type[0]->immediate.imm_expr, 1, 0);
+ }
+ }
+ }
+ else if ((insn.tm->operand_types[0] & ARn) == ARn)
+ {
+ /* Decrement and Branch instructions */
+ insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
+ if (insn.operand_type[1]->op_type & (AllReg))
+ {
+ insn.opcode |= (insn.operand_type[1]->reg.opcode);
+ insn.opcode |= PC_Register;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.operand_type[1]->immediate.resolved == 1)
+ {
+ if (insn.operand_type[0]->immediate.decimal_found)
+ {
+ as_bad ("first operand is floating point");
+ return;
+ }
+ if (insn.operand_type[0]->immediate.s_number < -32768 ||
+ insn.operand_type[0]->immediate.s_number > 32767)
+ {
+ as_bad ("first operand is too large for 16-bit signed int");
+ return;
+ }
+ insn.opcode |= (insn.operand_type[1]->immediate.s_number);
+ insn.opcode |= PC_Relative;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ insn.opcode |= PC_Relative;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2, &insn.operand_type[1]->immediate.imm_expr, 1, 0);
+ }
+ }
+ }
+ else if (insn.tm->operand_types[0] == IVector)
+ {
+ /* Trap instructions */
+ if (insn.operand_type[0]->op_type & IVector)
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number);
+ else
+ { /* Shouldn't get here */
+ as_bad ("interrupt vector for trap instruction out of range");
+ return;
+ }
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.tm->opcode_modifier == StackOp || insn.tm->opcode_modifier == Rotate)
+ {
+ /* Push, Pop and Rotate instructions */
+ insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if ((insn.tm->operand_types[0] & (Abs24 | Direct)) == (Abs24 | Direct))
+ {
+ /* LDP Instruction needs to be tested for before the next section */
+ if (insn.operand_type[0]->op_type & Direct)
+ {
+ if (insn.operand_type[0]->direct.resolved == 1)
+ {
+ /* Direct addressing uses lower 8 bits of direct address */
+ insn.opcode |= (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ fixS *fix;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
+ /* Ensure that the assembler doesn't complain about fitting a 24-bit
+ address into 8 bits. */
+ fix->fx_no_overflow = 1;
+ }
+ }
+ else
+ {
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ /* Immediate addressing uses upper 8 bits of address */
+ if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+ {
+ as_bad ("LDP instruction needs a 24-bit operand");
+ return;
+ }
+ insn.opcode |= ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ fixS *fix;
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal), 1, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ fix->fx_no_overflow = 1;
+ }
+ }
+ }
+ else if (insn.tm->operand_types[0] & (Imm24))
+ {
+ /* Unconditional Branch and Call instructions */
+ if (insn.operand_type[0]->immediate.resolved == 1)
+ {
+ if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
+ as_warn ("first operand is too large for a 24-bit displacement");
+ insn.opcode |= (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else
+ {
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3, &insn.operand_type[0]->immediate.imm_expr, 0, 0);
+ }
+ }
+ else if (insn.tm->operand_types[0] & NotReq)
+ {
+ /* Check for NOP instruction without arguments. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ else if (insn.tm->operands == 0)
+ {
+ /* Check for instructions without operands. */
+ md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
+ }
+ }
+ debug ("Addressing mode: %08X\n", insn.addressing_mode);
+ {
+ int i;
+ for (i = 0; i < insn.operands; i++)
+ {
+ if (insn.operand_type[i]->immediate.label)
+ free (insn.operand_type[i]->immediate.label);
+ free (insn.operand_type[i]);
+ }
+ }
+ debug ("Final opcode: %08X\n", insn.opcode);
+ debug ("\n");
+}
+
+struct tic30_par_insn
+{
+ partemplate *tm; /* Template of current parallel instruction */
+ int operands[2]; /* Number of given operands for each insn */
+ /* Type of operand given in instruction */
+ operand *operand_type[2][MAX_OPERANDS];
+ int swap_operands; /* Whether to swap operands around. */
+ unsigned p_field; /* Value of p field in multiply add/sub instructions */
+ unsigned opcode; /* Final opcode */
+};
+
+struct tic30_par_insn p_insn;
+
+int
+tic30_parallel_insn (char *token)
+{
+ static partemplate *p_opcode;
+ char *current_posn = token;
+ char *token_start;
+ char save_char;
+
+ debug ("In tic30_parallel_insn with %s\n", token);
+ memset (&p_insn, '\0', sizeof (p_insn));
+ while (is_opcode_char (*current_posn))
+ current_posn++;
+ { /* Find instruction */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ p_opcode = (partemplate *) hash_find (parop_hash, token);
+ if (p_opcode)
+ {
+ debug ("Found instruction %s\n", p_opcode->name);
+ p_insn.tm = p_opcode;
+ }
+ else
+ {
+ char first_opcode[6] =
+ {0};
+ char second_opcode[6] =
+ {0};
+ int i;
+ int current_opcode = -1;
+ int char_ptr = 0;
+
+ for (i = 0; i < strlen (token); i++)
+ {
+ char ch = *(token + i);
+ if (ch == '_' && current_opcode == -1)
+ {
+ current_opcode = 0;
+ continue;
+ }
+ if (ch == '_' && current_opcode == 0)
+ {
+ current_opcode = 1;
+ char_ptr = 0;
+ continue;
+ }
+ switch (current_opcode)
+ {
+ case 0:
+ first_opcode[char_ptr++] = ch;
+ break;
+ case 1:
+ second_opcode[char_ptr++] = ch;
+ break;
+ }
+ }
+ debug ("first_opcode = %s\n", first_opcode);
+ debug ("second_opcode = %s\n", second_opcode);
+ sprintf (token, "q_%s_%s", second_opcode, first_opcode);
+ p_opcode = (partemplate *) hash_find (parop_hash, token);
+ if (p_opcode)
+ {
+ debug ("Found instruction %s\n", p_opcode->name);
+ p_insn.tm = p_opcode;
+ p_insn.swap_operands = 1;
+ }
+ else
+ return 0;
+ }
+ *current_posn = save_char;
+ }
+ { /* Find operands */
+ int paren_not_balanced;
+ int expecting_operand = 0;
+ int found_separator = 0;
+ do
+ {
+ /* skip optional white space before operand */
+ while (!is_operand_char (*current_posn) && *current_posn != END_OF_INSN)
+ {
+ if (!is_space_char (*current_posn) && *current_posn != PARALLEL_SEPARATOR)
+ {
+ as_bad ("Invalid character %s before %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return 1;
+ }
+ if (*current_posn == PARALLEL_SEPARATOR)
+ found_separator = 1;
+ current_posn++;
+ }
+ token_start = current_posn; /* after white space */
+ paren_not_balanced = 0;
+ while (paren_not_balanced || *current_posn != ',')
+ {
+ if (*current_posn == END_OF_INSN)
+ {
+ if (paren_not_balanced)
+ {
+ as_bad ("Unbalanced parenthesis in %s operand.",
+ ordinal_names[insn.operands]);
+ return 1;
+ }
+ else
+ break; /* we are done */
+ }
+ else if (*current_posn == PARALLEL_SEPARATOR)
+ {
+ while (is_space_char (*(current_posn - 1)))
+ current_posn--;
+ break;
+ }
+ else if (!is_operand_char (*current_posn) && !is_space_char (*current_posn))
+ {
+ as_bad ("Invalid character %s in %s operand",
+ output_invalid (*current_posn),
+ ordinal_names[insn.operands]);
+ return 1;
+ }
+ if (*current_posn == '(')
+ ++paren_not_balanced;
+ if (*current_posn == ')')
+ --paren_not_balanced;
+ current_posn++;
+ }
+ if (current_posn != token_start)
+ { /* yes, we've read in another operand */
+ p_insn.operands[found_separator]++;
+ if (p_insn.operands[found_separator] > MAX_OPERANDS)
+ {
+ as_bad ("Spurious operands; (%d operands/instruction max)",
+ MAX_OPERANDS);
+ return 1;
+ }
+ /* now parse operand adding info to 'insn' as we go along */
+ save_char = *current_posn;
+ *current_posn = '\0';
+ p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
+ tic30_operand (token_start);
+ *current_posn = save_char;
+ if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
+ return 1;
+ }
+ else
+ {
+ if (expecting_operand)
+ {
+ as_bad ("Expecting operand after ','; got nothing");
+ return 1;
+ }
+ if (*current_posn == ',')
+ {
+ as_bad ("Expecting operand before ','; got nothing");
+ return 1;
+ }
+ }
+ /* now *current_posn must be either ',' or END_OF_INSN */
+ if (*current_posn == ',')
+ {
+ if (*++current_posn == END_OF_INSN)
+ { /* just skip it, if it's \n complain */
+ as_bad ("Expecting operand after ','; got nothing");
+ return 1;
+ }
+ expecting_operand = 1;
+ }
+ }
+ while (*current_posn != END_OF_INSN); /* until we get end of insn */
+ }
+ if (p_insn.swap_operands)
+ {
+ int temp_num, i;
+ operand *temp_op;
+
+ temp_num = p_insn.operands[0];
+ p_insn.operands[0] = p_insn.operands[1];
+ p_insn.operands[1] = temp_num;
+ for (i = 0; i < MAX_OPERANDS; i++)
+ {
+ temp_op = p_insn.operand_type[0][i];
+ p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
+ p_insn.operand_type[1][i] = temp_op;
+ }
+ }
+ if (p_insn.operands[0] != p_insn.tm->operands_1)
+ {
+ as_bad ("incorrect number of operands given in the first instruction");
+ return 1;
+ }
+ if (p_insn.operands[1] != p_insn.tm->operands_2)
+ {
+ as_bad ("incorrect number of operands given in the second instruction");
+ return 1;
+ }
+ debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
+ debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
+ { /* Now check if operands are correct */
+ int count;
+ int num_rn = 0;
+ int num_ind = 0;
+ for (count = 0; count < 2; count++)
+ {
+ int i;
+ for (i = 0; i < p_insn.operands[count]; i++)
+ {
+ if ((p_insn.operand_type[count][i]->op_type &
+ p_insn.tm->operand_types[count][i]) == 0)
+ {
+ as_bad ("%s instruction, operand %d doesn't match", ordinal_names[count], i + 1);
+ return 1;
+ }
+ /* Get number of R register and indirect reference contained within the first
+ two operands of each instruction. This is required for the multiply
+ parallel instructions which require two R registers and two indirect
+ references, but not in any particular place. */
+ if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
+ num_rn++;
+ else if ((p_insn.operand_type[count][i]->op_type & Indirect) && i < 2)
+ num_ind++;
+ }
+ }
+ if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn)) == (Indirect | Rn))
+ {
+ /* Check for the multiply instructions */
+ if (num_rn != 2)
+ {
+ as_bad ("incorrect format for multiply parallel instruction");
+ return 1;
+ }
+ if (num_ind != 2)
+ { /* Shouldn't get here */
+ as_bad ("incorrect format for multiply parallel instruction");
+ return 1;
+ }
+ if ((p_insn.operand_type[0][2]->reg.opcode != 0x00) &&
+ (p_insn.operand_type[0][2]->reg.opcode != 0x01))
+ {
+ as_bad ("destination for multiply can only be R0 or R1");
+ return 1;
+ }
+ if ((p_insn.operand_type[1][2]->reg.opcode != 0x02) &&
+ (p_insn.operand_type[1][2]->reg.opcode != 0x03))
+ {
+ as_bad ("destination for add/subtract can only be R2 or R3");
+ return 1;
+ }
+ /* Now determine the P field for the instruction */
+ if (p_insn.operand_type[0][0]->op_type & Indirect)
+ {
+ if (p_insn.operand_type[0][1]->op_type & Indirect)
+ p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn */
+ else if (p_insn.operand_type[1][0]->op_type & Indirect)
+ p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn */
+ else
+ p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind */
+ }
+ else
+ {
+ if (p_insn.operand_type[0][1]->op_type & Rn)
+ p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind */
+ else if (p_insn.operand_type[1][0]->op_type & Indirect)
+ {
+ operand *temp;
+ p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn */
+ /* Need to swap the two multiply operands around so that everything is in
+ its place for the opcode makeup ie so Ind * Rn, Ind +/- Rn */
+ temp = p_insn.operand_type[0][0];
+ p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
+ p_insn.operand_type[0][1] = temp;
+ }
+ else
+ {
+ operand *temp;
+ p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind */
+ temp = p_insn.operand_type[0][0];
+ p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
+ p_insn.operand_type[0][1] = temp;
+ }
+ }
+ }
+ }
+ debug ("P field: %08X\n", p_insn.p_field);
+ /* Finalise opcode. This is easier for parallel instructions as they have to be
+ fully resolved, there are no memory addresses allowed, except through indirect
+ addressing, so there are no labels to resolve. */
+ {
+ p_insn.opcode = p_insn.tm->base_opcode;
+ switch (p_insn.tm->oporder)
+ {
+ case OO_4op1:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+ break;
+ case OO_4op2:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
+ if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
+ as_warn ("loading the same register in parallel operation");
+ break;
+ case OO_4op3:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
+ break;
+ case OO_5op1:
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+ break;
+ case OO_5op2:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+ p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
+ break;
+ case OO_PField:
+ p_insn.opcode |= p_insn.p_field;
+ if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
+ p_insn.opcode |= 0x00800000;
+ if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
+ p_insn.opcode |= 0x00400000;
+ switch (p_insn.p_field)
+ {
+ case 0x00000000:
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
+ break;
+ case 0x01000000:
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ break;
+ case 0x02000000:
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
+ break;
+ case 0x03000000:
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
+ p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
+ p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
+ p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
+ p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
+ break;
+ }
+ break;
+ }
+ } /* Opcode is finalised at this point for all parallel instructions. */
+ { /* Output opcode */
+ char *p;
+ p = frag_more (INSN_SIZE);
+ md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
+ }
+ {
+ int i, j;
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < p_insn.operands[i]; j++)
+ free (p_insn.operand_type[i][j]);
+ }
+ debug ("Final opcode: %08X\n", p_insn.opcode);
+ debug ("\n");
+ return 1;
+}
+
+operand *
+tic30_operand (token)
+ char *token;
+{
+ int count;
+ char ind_buffer[strlen (token)];
+ operand *current_op;
+
+ debug ("In tic30_operand with %s\n", token);
+ current_op = (operand *) malloc (sizeof (operand));
+ memset (current_op, '\0', sizeof (operand));
+ if (*token == DIRECT_REFERENCE)
+ {
+ char *token_posn = token + 1;
+ int direct_label = 0;
+ debug ("Found direct reference\n");
+ while (*token_posn)
+ {
+ if (!is_digit_char (*token_posn))
+ direct_label = 1;
+ token_posn++;
+ }
+ if (direct_label)
+ {
+ char *save_input_line_pointer;
+ segT retval;
+ debug ("Direct reference is a label\n");
+ current_op->direct.label = token + 1;
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = token + 1;
+ debug ("Current input_line_pointer: %s\n", input_line_pointer);
+ retval = expression (&current_op->direct.direct_expr);
+ debug ("Expression type: %d\n", current_op->direct.direct_expr.X_op);
+ debug ("Expression addnum: %d\n", current_op->direct.direct_expr.X_add_number);
+ debug ("Segment: %d\n", retval);
+ input_line_pointer = save_input_line_pointer;
+ if (current_op->direct.direct_expr.X_op == O_constant)
+ {
+ current_op->direct.address = current_op->direct.direct_expr.X_add_number;
+ current_op->direct.resolved = 1;
+ }
+ }
+ else
+ {
+ debug ("Direct reference is a number\n");
+ current_op->direct.address = atoi (token + 1);
+ current_op->direct.resolved = 1;
+ }
+ current_op->op_type = Direct;
+ }
+ else if (*token == INDIRECT_REFERENCE)
+ { /* Indirect reference operand */
+ int found_ar = 0;
+ int found_disp = 0;
+ int ar_number = -1;
+ int disp_number = 0;
+ int buffer_posn = 1;
+ ind_addr_type *ind_addr_op;
+ debug ("Found indirect reference\n");
+ ind_buffer[0] = *token;
+ for (count = 1; count < strlen (token); count++)
+ { /* Strip operand */
+ ind_buffer[buffer_posn] = tolower (*(token + count));
+ if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A') &&
+ (*(token + count) == 'r' || *(token + count) == 'R'))
+ {
+ /* AR reference is found, so get its number and remove it from the buffer
+ so it can pass through hash_find() */
+ if (found_ar)
+ {
+ as_bad ("More than one AR register found in indirect reference");
+ return NULL;
+ }
+ if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
+ {
+ as_bad ("Illegal AR register in indirect reference");
+ return NULL;
+ }
+ ar_number = *(token + count + 1) - '0';
+ found_ar = 1;
+ count++;
+ }
+ if (*(token + count) == '(')
+ {
+ /* Parenthesis found, so check if a displacement value is inside. If so, get
+ the value and remove it from the buffer. */
+ if (is_digit_char (*(token + count + 1)))
+ {
+ char disp[10];
+ int disp_posn = 0;
+
+ if (found_disp)
+ {
+ as_bad ("More than one displacement found in indirect reference");
+ return NULL;
+ }
+ count++;
+ while (*(token + count) != ')')
+ {
+ if (!is_digit_char (*(token + count)))
+ {
+ as_bad ("Invalid displacement in indirect reference");
+ return NULL;
+ }
+ disp[disp_posn++] = *(token + (count++));
+ }
+ disp[disp_posn] = '\0';
+ disp_number = atoi (disp);
+ count--;
+ found_disp = 1;
+ }
+ }
+ buffer_posn++;
+ }
+ ind_buffer[buffer_posn] = '\0';
+ if (!found_ar)
+ {
+ as_bad ("AR register not found in indirect reference");
+ return NULL;
+ }
+ ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
+ if (ind_addr_op)
+ {
+ debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
+ if (ind_addr_op->displacement == IMPLIED_DISP)
+ {
+ found_disp = 1;
+ disp_number = 1;
+ }
+ else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
+ {
+ /* Maybe an implied displacement of 1 again */
+ as_bad ("required displacement wasn't given in indirect reference");
+ return 0;
+ }
+ }
+ else
+ {
+ as_bad ("illegal indirect reference");
+ return NULL;
+ }
+ if (found_disp && (disp_number < 0 || disp_number > 255))
+ {
+ as_bad ("displacement must be an unsigned 8-bit number");
+ return NULL;
+ }
+ current_op->indirect.mod = ind_addr_op->modfield;
+ current_op->indirect.disp = disp_number;
+ current_op->indirect.ARnum = ar_number;
+ current_op->op_type = Indirect;
+ }
+ else
+ {
+ reg *regop = (reg *) hash_find (reg_hash, token);
+ if (regop)
+ {
+ debug ("Found register operand: %s\n", regop->name);
+ if (regop->regtype == REG_ARn)
+ current_op->op_type = ARn;
+ else if (regop->regtype == REG_Rn)
+ current_op->op_type = Rn;
+ else if (regop->regtype == REG_DP)
+ current_op->op_type = DPReg;
+ else
+ current_op->op_type = OtherReg;
+ current_op->reg.opcode = regop->opcode;
+ }
+ else
+ {
+ if (!is_digit_char (*token) || *(token + 1) == 'x' || strchr (token, 'h'))
+ {
+ char *save_input_line_pointer;
+ segT retval;
+ debug ("Probably a label: %s\n", token);
+ current_op->immediate.label = (char *) malloc (strlen (token) + 1);
+ strcpy (current_op->immediate.label, token);
+ current_op->immediate.label[strlen (token)] = '\0';
+ save_input_line_pointer = input_line_pointer;
+ input_line_pointer = token;
+ debug ("Current input_line_pointer: %s\n", input_line_pointer);
+ retval = expression (&current_op->immediate.imm_expr);
+ debug ("Expression type: %d\n", current_op->immediate.imm_expr.X_op);
+ debug ("Expression addnum: %d\n", current_op->immediate.imm_expr.X_add_number);
+ debug ("Segment: %d\n", retval);
+ input_line_pointer = save_input_line_pointer;
+ if (current_op->immediate.imm_expr.X_op == O_constant)
+ {
+ current_op->immediate.s_number = current_op->immediate.imm_expr.X_add_number;
+ current_op->immediate.u_number = (unsigned int) current_op->immediate.imm_expr.X_add_number;
+ current_op->immediate.resolved = 1;
+ }
+ }
+ else
+ {
+ unsigned count;
+ debug ("Found a number or displacement\n");
+ for (count = 0; count < strlen (token); count++)
+ if (*(token + count) == '.')
+ current_op->immediate.decimal_found = 1;
+ current_op->immediate.label = (char *) malloc (strlen (token) + 1);
+ strcpy (current_op->immediate.label, token);
+ current_op->immediate.label[strlen (token)] = '\0';
+ current_op->immediate.f_number = (float) atof (token);
+ current_op->immediate.s_number = (int) atoi (token);
+ current_op->immediate.u_number = (unsigned int) atoi (token);
+ current_op->immediate.resolved = 1;
+ }
+ current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
+ if (current_op->immediate.u_number >= 0 && current_op->immediate.u_number <= 31)
+ current_op->op_type |= IVector;
+ }
+ }
+ return current_op;
+}
+
+/* next_line points to the next line after the current instruction (current_line).
+ Search for the parallel bars, and if found, merge two lines into internal syntax
+ for a parallel instruction:
+ q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
+ By this stage, all comments are scrubbed, and only the bare lines are given.
+ */
+
+#define NONE 0
+#define START_OPCODE 1
+#define END_OPCODE 2
+#define START_OPERANDS 3
+#define END_OPERANDS 4
+
+char *
+tic30_find_parallel_insn (current_line, next_line)
+ char *current_line;
+ char *next_line;
+{
+ int found_parallel = 0;
+ char first_opcode[256];
+ char second_opcode[256];
+ char first_operands[256];
+ char second_operands[256];
+ char *parallel_insn;
+
+ debug ("In tic30_find_parallel_insn()\n");
+ while (!is_end_of_line[(int) *next_line])
+ {
+ if (*next_line == PARALLEL_SEPARATOR && *(next_line + 1) == PARALLEL_SEPARATOR)
+ {
+ found_parallel = 1;
+ next_line++;
+ break;
+ }
+ next_line++;
+ }
+ if (!found_parallel)
+ return NULL;
+ debug ("Found a parallel instruction\n");
+ {
+ int i;
+ char *opcode, *operands, *line;
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i == 0)
+ {
+ opcode = &first_opcode[0];
+ operands = &first_operands[0];
+ line = current_line;
+ }
+ else
+ {
+ opcode = &second_opcode[0];
+ operands = &second_operands[0];
+ line = next_line;
+ }
+ {
+ int search_status = NONE;
+ int char_ptr = 0;
+ char c;
+
+ while (!is_end_of_line[(int) (c = *line)] && *line)
+ {
+ if (is_opcode_char (c) && search_status == NONE)
+ {
+ opcode[char_ptr++] = tolower (c);
+ search_status = START_OPCODE;
+ }
+ else if (is_opcode_char (c) && search_status == START_OPCODE)
+ {
+ opcode[char_ptr++] = tolower (c);
+ }
+ else if (!is_opcode_char (c) && search_status == START_OPCODE)
+ {
+ opcode[char_ptr] = '\0';
+ char_ptr = 0;
+ search_status = END_OPCODE;
+ }
+ else if (is_operand_char (c) && search_status == START_OPERANDS)
+ {
+ operands[char_ptr++] = c;
+ }
+ if (is_operand_char (c) && search_status == END_OPCODE)
+ {
+ operands[char_ptr++] = c;
+ search_status = START_OPERANDS;
+ }
+ line++;
+ }
+ if (search_status != START_OPERANDS)
+ return NULL;
+ operands[char_ptr] = '\0';
+ }
+ }
+ }
+ parallel_insn = (char *) malloc (strlen (first_opcode) + strlen (first_operands) +
+ strlen (second_opcode) + strlen (second_operands) + 8);
+ sprintf (parallel_insn, "q_%s_%s %s | %s", first_opcode, second_opcode, first_operands, second_operands);
+ debug ("parallel insn = %s\n", parallel_insn);
+ return parallel_insn;
+}
+
+#undef NONE
+#undef START_OPCODE
+#undef END_OPCODE
+#undef START_OPERANDS
+#undef END_OPERANDS
+
+/* In order to get gas to ignore any | chars at the start of a line,
+ this function returns true if a | is found in a line. */
+
+int
+tic30_unrecognized_line (c)
+ int c;
+{
+ debug ("In tc_unrecognized_line\n");
+ return (c == PARALLEL_SEPARATOR);
+}
+
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS *fragP;
+ segT segment;
+{
+ debug ("In md_estimate_size_before_relax()\n");
+ return 0;
+}
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ register fragS *fragP;
+{
+ debug ("In md_convert_frag()\n");
+}
+
+int
+md_apply_fix (fixP, valP)
+ fixS *fixP;
+ valueT *valP;
+{
+ valueT value = *valP;
+
+ debug ("In md_apply_fix() with value = %ld\n", (long) value);
+ debug ("Values in fixP\n");
+ debug ("fx_size = %d\n", fixP->fx_size);
+ debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
+ debug ("fx_where = %d\n", fixP->fx_where);
+ debug ("fx_offset = %d\n", (int) fixP->fx_offset);
+ {
+ char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+ value /= INSN_SIZE;
+ if (fixP->fx_size == 1)
+ { /* Special fix for LDP instruction. */
+ value = (value & 0x00FF0000) >> 16;
+ }
+ debug ("new value = %ld\n", (long) value);
+ md_number_to_chars (buf, value, fixP->fx_size);
+ }
+ return 1;
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ int i;
+
+ debug ("In md_parse_option()\n");
+ for (i = 0; i < c; i++)
+ {
+ printf ("%c\n", arg[c]);
+ }
+ return 0;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ debug ("In md_show_usage()\n");
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ debug ("In md_undefined_symbol()\n");
+ return (symbolS *) 0;
+}
+
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ debug ("In md_section_align() segment = %d and size = %d\n", segment, size);
+ size = (size + 3) / 4;
+ size *= 4;
+ debug ("New size value = %d\n", size);
+ return size;
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ int offset;
+
+ debug ("In md_pcrel_from()\n");
+ debug ("fx_where = %d\n", fixP->fx_where);
+ debug ("fx_size = %d\n", fixP->fx_size);
+ /* Find the opcode that represents the current instruction in the fr_literal
+ storage area, and check bit 21. Bit 21 contains whether the current instruction
+ is a delayed one or not, and then set the offset value appropriately. */
+ if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
+ offset = 3;
+ else
+ offset = 1;
+ debug ("offset = %d\n", offset);
+ /* PC Relative instructions have a format:
+ displacement = Label - (PC + offset)
+ This function returns PC + offset where:
+ fx_where - fx_size = PC
+ INSN_SIZE * offset = offset number of instructions
+ */
+ return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
+}
+
+char *
+md_atof (what_statement_type, literalP, sizeP)
+ int what_statement_type;
+ char *literalP;
+ int *sizeP;
+{
+ int prec;
+ char *token;
+ char keepval;
+ unsigned long value;
+ /* char *atof_ieee (); */
+ float float_value;
+ debug ("In md_atof()\n");
+ debug ("precision = %c\n", what_statement_type);
+ debug ("literal = %s\n", literalP);
+ debug ("line = ");
+ token = input_line_pointer;
+ while (!is_end_of_line[(unsigned) *input_line_pointer] && (*input_line_pointer) && (*input_line_pointer != ','))
+ {
+ debug ("%c", *input_line_pointer);
+ input_line_pointer++;
+ }
+ keepval = *input_line_pointer;
+ *input_line_pointer = '\0';
+ debug ("\n");
+ float_value = (float) atof (token);
+ *input_line_pointer = keepval;
+ debug ("float_value = %f\n", float_value);
+ switch (what_statement_type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return "Bad call to MD_ATOF()";
+ }
+ if (float_value == 0.0)
+ {
+ value = (prec == 2) ? 0x00008000L : 0x80000000L;
+ }
+ else
+ {
+ unsigned long exp, sign, mant, tmsfloat;
+ tmsfloat = *((long *) &float_value);
+ sign = tmsfloat & 0x80000000;
+ mant = tmsfloat & 0x007FFFFF;
+ exp = tmsfloat & 0x7F800000;
+ exp <<= 1;
+ if (exp == 0xFF000000)
+ {
+ if (mant == 0)
+ value = 0x7F7FFFFF;
+ else if (sign == 0)
+ value = 0x7F7FFFFF;
+ else
+ value = 0x7F800000;
+ }
+ else
+ {
+ exp -= 0x7F000000;
+ if (sign)
+ {
+ mant = mant & 0x007FFFFF;
+ mant = -mant;
+ mant = mant & 0x00FFFFFF;
+ if (mant == 0)
+ {
+ mant |= 0x00800000;
+ exp = (long) exp - 0x01000000;
+ }
+ }
+ tmsfloat = exp | mant;
+ value = tmsfloat;
+ }
+ if (prec == 2)
+ {
+ long exp, mant;
+
+ if (tmsfloat == 0x80000000)
+ {
+ value = 0x8000;
+ }
+ else
+ {
+ value = 0;
+ exp = (tmsfloat & 0xFF000000);
+ exp >>= 24;
+ mant = tmsfloat & 0x007FFFFF;
+ if (tmsfloat & 0x00800000)
+ {
+ mant |= 0xFF000000;
+ mant += 0x00000800;
+ mant >>= 12;
+ mant |= 0x00000800;
+ mant &= 0x0FFF;
+ if (exp > 7)
+ value = 0x7800;
+ }
+ else
+ {
+ mant |= 0x00800000;
+ mant += 0x00000800;
+ exp += (mant >> 24);
+ mant >>= 12;
+ mant &= 0x07FF;
+ if (exp > 7)
+ value = 0x77FF;
+ }
+ if (exp < -8)
+ value = 0x8000;
+ if (value == 0)
+ {
+ mant = (exp << 12) | mant;
+ value = mant & 0xFFFF;
+ }
+ }
+ }
+ }
+ md_number_to_chars (literalP, value, prec);
+ *sizeP = prec;
+ return 0;
+}
+
+void
+md_number_to_chars (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ debug ("In md_number_to_chars()\n");
+ number_to_chars_bigendian (buf, val, n);
+ /* number_to_chars_littleendian(buf,val,n); */
+}
+
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
+
+arelent *
+tc_gen_reloc (section, fixP)
+ asection *section;
+ fixS *fixP;
+{
+ arelent *rel;
+ bfd_reloc_code_real_type code = 0;
+
+ debug ("In tc_gen_reloc()\n");
+ debug ("fixP.size = %d\n", fixP->fx_size);
+ debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
+ debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
+ switch (F (fixP->fx_size, fixP->fx_pcrel))
+ {
+ MAP (1, 0, BFD_RELOC_TIC30_LDP);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (3, 0, BFD_RELOC_24);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 0, BFD_RELOC_32);
+ default:
+ as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
+ fixP->fx_pcrel ? "pc-relative " : "");
+ }
+#undef MAP
+#undef F
+
+ rel = (arelent *) xmalloc (sizeof (arelent));
+ assert (rel != 0);
+ rel->sym_ptr_ptr = &fixP->fx_addsy->bsym;
+ rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
+ if (fixP->fx_pcrel)
+ rel->addend = fixP->fx_addnumber;
+ else
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+ if (!rel->howto)
+ {
+ const char *name;
+ name = S_GET_NAME (fixP->fx_addsy);
+ if (name == NULL)
+ name = "<unknown>";
+ as_fatal ("Cannot generate relocation type for symbol %s, code %s", name, bfd_get_reloc_code_name (code));
+ }
+ return rel;
+}
+
+void
+tc_aout_pre_write_hook ()
+{
+ debug ("In tc_aout_pre_write_hook()\n");
+}
+
+void
+md_operand (expressionP)
+ expressionS *expressionP;
+{
+ debug ("In md_operand()\n");
+}
+
+char output_invalid_buf[8];
+
+char *
+output_invalid (c)
+ char c;
+{
+ if (isprint (c))
+ sprintf (output_invalid_buf, "'%c'", c);
+ else
+ sprintf (output_invalid_buf, "(0x%x)", (unsigned) c);
+ return output_invalid_buf;
+}
diff --git a/gas/config/tc-tic30.h b/gas/config/tc-tic30.h
new file mode 100644
index 00000000000..d172d2e5c52
--- /dev/null
+++ b/gas/config/tc-tic30.h
@@ -0,0 +1,55 @@
+/* tc-tic30.h -- Header file for tc-tic30.c
+ Copyright (C) 1998 Free Software Foundation.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef _TC_TIC30_H_
+#define _TC_TIC30_H_
+
+#define TC_TIC30 1
+
+#ifdef OBJ_AOUT
+#define TARGET_FORMAT "a.out-tic30"
+#endif
+
+#define TARGET_ARCH bfd_arch_tic30
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#define WORKING_DOT_WORD
+
+char *output_invalid PARAMS ((int c));
+
+#define END_OF_INSN '\0'
+#define MAX_OPERANDS 6
+#define DIRECT_REFERENCE '@'
+#define INDIRECT_REFERENCE '*'
+#define PARALLEL_SEPARATOR '|'
+#define INSN_SIZE 4
+
+/* Define this to 1 if you want the debug output to be on stdout,
+ otherwise stderr will be used. If stderr is used, there will be a
+ better synchronisation with the as_bad outputs, but you can't
+ capture the output. */
+#define USE_STDOUT 0
+
+#define tc_unrecognized_line tic30_unrecognized_line
+
+extern int tic30_unrecognized_line PARAMS ((int));
+
+#endif
diff --git a/gas/config/tc-tic80.c b/gas/config/tc-tic80.c
new file mode 100644
index 00000000000..f31dba32f93
--- /dev/null
+++ b/gas/config/tc-tic80.c
@@ -0,0 +1,1061 @@
+/* tc-tic80.c -- Assemble for the TI TMS320C80 (MV)
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "opcode/tic80.h"
+
+#define internal_error(what) \
+ as_fatal(_("internal error:%s:%d: %s\n"),__FILE__,__LINE__,what)
+#define internal_error_a(what,arg) \
+ as_fatal(_("internal error:%s:%d: %s %d\n"),__FILE__,__LINE__,what,arg)
+
+
+/* Generic assembler global variables which must be defined by all targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = ";";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = ";*#";
+
+/* Characters which may be used to separate multiple commands on a single
+ line. The semicolon is such a character by default and should not be
+ explicitly listed. */
+const char line_separator_chars[] = "";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0f1.0. */
+const char FLT_CHARS[] = "fF";
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ integer arg to pass to the function */
+
+extern void obj_coff_section ();
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ { "align", s_align_bytes, 4 }, /* Do byte alignment, default is a 4 byte boundary */
+ { "word", cons, 4 }, /* FIXME: Should this be machine independent? */
+ { "bss", s_lcomm_bytes, 1 },
+ { "sect", obj_coff_section, 0}, /* For compatibility with TI tools */
+ { "section", obj_coff_section, 0}, /* Standard COFF .section pseudo-op */
+ { NULL, NULL, 0 }
+};
+
+/* Opcode hash table. */
+static struct hash_control *tic80_hash;
+
+static struct tic80_opcode * find_opcode PARAMS ((struct tic80_opcode *, expressionS []));
+static void build_insn PARAMS ((struct tic80_opcode *, expressionS *));
+static int get_operands PARAMS ((expressionS exp[]));
+static int const_overflow PARAMS ((unsigned long num, int bits, int flags));
+
+/* Replace short PC relative instructions with long form when necessary. Currently
+ this is off by default or when given the -no-relax option. Turning it on by using
+ the -relax option forces all PC relative instructions to use the long form, which
+ is why it is currently not the default. */
+static int tic80_relax = 0;
+
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ fragS *fragP;
+ segT segment_type;
+{
+ internal_error (_("Relaxation is a luxury we can't afford"));
+ return (-1);
+}
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+
+#define MAX_LITTLENUMS 4
+
+char *
+md_atof (type, litP, sizeP)
+ int type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("bad call to md_atof ()");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ {
+ input_line_pointer = t;
+ }
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return (NULL);
+}
+
+/* Check to see if the constant value in NUM will fit in a field of
+ width BITS if it has flags FLAGS. */
+
+static int
+const_overflow (num, bits, flags)
+ unsigned long num;
+ int bits;
+ int flags;
+{
+ long min, max;
+ int retval = 0;
+
+ /* Only need to check fields less than 32 bits wide */
+ if (bits < 32)
+ if (flags & TIC80_OPERAND_SIGNED)
+ {
+ max = (1 << (bits - 1)) - 1;
+ min = - (1 << (bits - 1));
+ retval = ((long) num > max) || ((long) num < min);
+ }
+ else
+ {
+ max = (1 << bits) - 1;
+ min = 0;
+ retval = (num > max) || (num < min);
+ }
+ return (retval);
+}
+
+/* get_operands() parses a string of operands and fills in a passed array of
+ expressions in EXP.
+
+ Note that we use O_absent expressions to record additional information
+ about the previous non-O_absent expression, such as ":m" or ":s"
+ modifiers or register numbers enclosed in parens like "(r10)".
+
+ Returns the number of expressions that were placed in EXP.
+
+ */
+
+static int
+get_operands (exp)
+ expressionS exp[];
+{
+ char *p = input_line_pointer;
+ int numexp = 0;
+ int mflag = 0;
+ int sflag = 0;
+ int parens = 0;
+
+ while (*p)
+ {
+ /* Skip leading whitespace */
+ while (*p == ' ' || *p == '\t' || *p == ',')
+ {
+ p++;
+ }
+
+ /* Check to see if we have any operands left to parse */
+ if (*p == 0 || *p == '\n' || *p == '\r')
+ {
+ break;
+ }
+
+ /* Notice scaling or direct memory operand modifiers and save them in
+ an O_absent expression after the expression that they modify. */
+
+ if (*p == ':')
+ {
+ p++;
+ exp[numexp].X_op = O_absent;
+ if (*p == 'm')
+ {
+ p++;
+ /* This is a ":m" modifier */
+ exp[numexp].X_add_number = TIC80_OPERAND_M_SI | TIC80_OPERAND_M_LI;
+ }
+ else if (*p == 's')
+ {
+ p++;
+ /* This is a ":s" modifier */
+ exp[numexp].X_add_number = TIC80_OPERAND_SCALED;
+ }
+ else
+ {
+ as_bad (_("':' not followed by 'm' or 's'"));
+ }
+ numexp++;
+ continue;
+ }
+
+ /* Handle leading '(' on operands that use them, by recording that we
+ have entered a paren nesting level and then continuing. We complain
+ about multiple nesting. */
+
+ if (*p == '(')
+ {
+ if (++parens != 1)
+ {
+ as_bad (_("paren nesting"));
+ }
+ p++;
+ continue;
+ }
+
+ /* Handle trailing ')' on operands that use them, by reducing the
+ nesting level and then continuing. We complain if there were too
+ many closures. */
+
+ if (*p == ')')
+ {
+ /* Record that we have left a paren group and continue */
+ if (--parens < 0)
+ {
+ as_bad (_("mismatched parenthesis"));
+ }
+ p++;
+ continue;
+ }
+
+ /* Begin operand parsing at the current scan point. */
+
+ input_line_pointer = p;
+ expression (&exp[numexp]);
+
+ if (exp[numexp].X_op == O_illegal)
+ {
+ as_bad (_("illegal operand"));
+ }
+ else if (exp[numexp].X_op == O_absent)
+ {
+ as_bad (_("missing operand"));
+ }
+
+ numexp++;
+ p = input_line_pointer;
+ }
+
+ if (parens)
+ {
+ exp[numexp].X_op = O_absent;
+ exp[numexp++].X_add_number = TIC80_OPERAND_PARENS;
+ }
+
+ /* Mark the end of the valid operands with an illegal expression. */
+ exp[numexp].X_op = O_illegal;
+
+ return (numexp);
+}
+
+/* find_opcode() gets a pointer to the entry in the opcode table that
+ matches the instruction being assembled, or returns NULL if no such match
+ is found.
+
+ First it parses all the operands and save them as expressions. Note that
+ we use O_absent expressions to record additional information about the
+ previous non-O_absent expression, such as ":m" or ":s" modifiers or
+ register numbers enclosed in parens like "(r10)".
+
+ It then looks at all opcodes with the same name and uses the operands to
+ choose the correct opcode. */
+
+static struct tic80_opcode *
+find_opcode (opcode, myops)
+ struct tic80_opcode *opcode;
+ expressionS myops[];
+{
+ int numexp; /* Number of expressions from parsing operands */
+ int expi; /* Index of current expression to match */
+ int opi; /* Index of current operand to match */
+ int match = 0; /* Set to 1 when an operand match is found */
+ struct tic80_opcode *opc = opcode; /* Pointer to current opcode table entry */
+ const struct tic80_opcode *end; /* Pointer to end of opcode table */
+
+ /* First parse all the operands so we only have to do it once. There may
+ be more expressions generated than there are operands. */
+
+ numexp = get_operands (myops);
+
+ /* For each opcode with the same name, try to match it against the parsed
+ operands. */
+
+ end = tic80_opcodes + tic80_num_opcodes;
+ while (!match && (opc < end) && (strcmp (opc -> name, opcode -> name) == 0))
+ {
+ /* Start off assuming a match. If we find a mismatch, then this is
+ reset and the operand/expr matching loop terminates with match
+ equal to zero, which allows us to try the next opcode. */
+
+ match = 1;
+
+ /* For each expression, try to match it against the current operand
+ for the current opcode. Upon any mismatch, we abandon further
+ matching for the current opcode table entry. */
+
+ for (expi = 0, opi = -1; (expi < numexp) && match; expi++)
+ {
+ int bits, flags, X_op, num;
+
+ X_op = myops[expi].X_op;
+ num = myops[expi].X_add_number;
+
+ /* The O_absent expressions apply to the same operand as the most
+ recent non O_absent expression. So only increment the operand
+ index when the current expression is not one of these special
+ expressions. */
+
+ if (X_op != O_absent)
+ {
+ opi++;
+ }
+
+ flags = tic80_operands[opc -> operands[opi]].flags;
+ bits = tic80_operands[opc -> operands[opi]].bits;
+
+ switch (X_op)
+ {
+ case O_register:
+ /* Also check that registers that are supposed to be even actually
+ are even. */
+ if (((flags & TIC80_OPERAND_GPR) != (num & TIC80_OPERAND_GPR)) ||
+ ((flags & TIC80_OPERAND_FPA) != (num & TIC80_OPERAND_FPA)) ||
+ ((flags & TIC80_OPERAND_CR) != (num & TIC80_OPERAND_CR)) ||
+ ((flags & TIC80_OPERAND_EVEN) && (num & 1)) ||
+ const_overflow (num & ~TIC80_OPERAND_MASK, bits, flags))
+ {
+ match = 0;
+ }
+ break;
+ case O_constant:
+ if ((flags & TIC80_OPERAND_ENDMASK) && (num == 32))
+ {
+ /* Endmask values of 0 and 32 give identical results */
+ num = 0;
+ }
+ if ((flags & (TIC80_OPERAND_FPA | TIC80_OPERAND_GPR)) ||
+ const_overflow (num, bits, flags))
+ {
+ match = 0;
+ }
+ break;
+ case O_symbol:
+ if ((bits < 32) && (flags & TIC80_OPERAND_PCREL) && !tic80_relax)
+ {
+ /* The default is to prefer the short form of PC relative relocations.
+ This is the only form that the TI assembler supports.
+ If the -relax option is given, we never use the short forms.
+ FIXME: Should be able to choose "best-fit". */
+ }
+ else if ((bits == 32) /* && (flags & TIC80_OPERAND_BASEREL) */)
+ {
+ /* The default is to prefer the long form of base relative relocations.
+ This is the only form that the TI assembler supports.
+ If the -no-relax option is given, we always use the long form of
+ PC relative relocations.
+ FIXME: Should be able to choose "best-fit". */
+ }
+ else
+ {
+ /* Symbols that don't match one of the above cases are
+ rejected as an operand. */
+ match = 0;
+ }
+ break;
+ case O_absent:
+ /* If this is an O_absent expression, then it may be an expression that
+ supplies additional information about the operand, such as ":m" or
+ ":s" modifiers. Check to see that the operand matches this requirement. */
+ if (!((num & TIC80_OPERAND_M_SI) && (flags & TIC80_OPERAND_M_SI) ||
+ (num & TIC80_OPERAND_M_LI) && (flags & TIC80_OPERAND_M_LI) ||
+ (num & TIC80_OPERAND_SCALED) && (flags & TIC80_OPERAND_SCALED)))
+ {
+ match = 0;
+ }
+ break;
+ case O_big:
+ if ((num > 0) || !(flags & TIC80_OPERAND_FLOAT))
+ {
+ match = 0;
+ }
+ break;
+ case O_illegal:
+ case O_symbol_rva:
+ case O_uminus:
+ case O_bit_not:
+ case O_logical_not:
+ case O_multiply:
+ case O_divide:
+ case O_modulus:
+ case O_left_shift:
+ case O_right_shift:
+ case O_bit_inclusive_or:
+ case O_bit_or_not:
+ case O_bit_exclusive_or:
+ case O_bit_and:
+ case O_add:
+ case O_subtract:
+ case O_eq:
+ case O_ne:
+ case O_lt:
+ case O_le:
+ case O_ge:
+ case O_gt:
+ case O_logical_and:
+ case O_logical_or:
+ case O_max:
+ default:
+ internal_error_a (_("unhandled expression type"), X_op);
+ }
+ }
+ if (!match)
+ {
+ opc++;
+ }
+ }
+
+ return (match ? opc : NULL);
+
+#if 0
+
+ /* Now search the opcode table table for one with operands that
+ matches what we've got. */
+
+ while (!match)
+ {
+ match = 1;
+ for (i = 0; opcode -> operands[i]; i++)
+ {
+ int flags = tic80_operands[opcode->operands[i]].flags;
+ int X_op = myops[i].X_op;
+ int num = myops[i].X_add_number;
+
+ if (X_op == 0)
+ {
+ match = 0;
+ break;
+ }
+
+ if (flags & (TIC80_OPERAND_GPR | TIC80_OPERAND_FPA | TIC80_OPERAND_CR))
+ {
+ if ((X_op != O_register) ||
+ ((flags & TIC80_OPERAND_GPR) != (num & TIC80_OPERAND_GPR)) ||
+ ((flags & TIC80_OPERAND_FPA) != (num & TIC80_OPERAND_FPA)) ||
+ ((flags & TIC80_OPERAND_CR) != (num & TIC80_OPERAND_CR)))
+ {
+ match=0;
+ break;
+ }
+ }
+
+ if (((flags & TIC80_OPERAND_MINUS) && ((X_op != O_absent) || (num != TIC80_OPERAND_MINUS))) ||
+ ((flags & TIC80_OPERAND_PLUS) && ((X_op != O_absent) || (num != TIC80_OPERAND_PLUS))) ||
+ ((flags & TIC80_OPERAND_ATMINUS) && ((X_op != O_absent) || (num != TIC80_OPERAND_ATMINUS))) ||
+ ((flags & TIC80_OPERAND_ATPAR) && ((X_op != O_absent) || (num != TIC80_OPERAND_ATPAR))) ||
+ ((flags & TIC80_OPERAND_ATSIGN) && ((X_op != O_absent) || (num != TIC80_OPERAND_ATSIGN))))
+ {
+ match=0;
+ break;
+ }
+ }
+ /* we're only done if the operands matched so far AND there
+ are no more to check */
+ if (match && myops[i].X_op==0)
+ break;
+ else
+ match = 0;
+
+ next_opcode = opcode+1;
+ if (next_opcode->opcode == 0)
+ break;
+ if (strcmp(next_opcode->name, opcode->name))
+ break;
+ opcode = next_opcode;
+ }
+
+ if (!match)
+ {
+ as_bad (_("bad opcode or operands"));
+ return (0);
+ }
+
+ /* Check that all registers that are required to be even are. */
+ /* Also, if any operands were marked as registers, but were really symbols */
+ /* fix that here. */
+ for (i=0; opcode->operands[i]; i++)
+ {
+ if ((tic80_operands[opcode->operands[i]].flags & TIC80_OPERAND_EVEN) &&
+ (myops[i].X_add_number & 1))
+ as_fatal (_("Register number must be EVEN"));
+ if (myops[i].X_op == O_register)
+ {
+ if (!(tic80_operands[opcode->operands[i]].flags & TIC80_OPERAND_REG))
+ {
+ myops[i].X_op = O_symbol;
+ myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
+ myops[i].X_add_number = 0;
+ myops[i].X_op_symbol = NULL;
+ }
+ }
+ }
+
+#endif
+}
+
+/* build_insn takes a pointer to the opcode entry in the opcode table
+ and the array of operand expressions and writes out the instruction.
+
+ Note that the opcode word and extended word may be written to different
+ frags, with the opcode at the end of one frag and the extension at the
+ beginning of the next. */
+
+static void
+build_insn (opcode, opers)
+ struct tic80_opcode *opcode;
+ expressionS *opers;
+{
+ int expi; /* Index of current expression to match */
+ int opi; /* Index of current operand to match */
+ unsigned long insn[2]; /* Instruction and long immediate (if any) */
+ char *f; /* Pointer to frag location for insn[0] */
+ fragS *ffrag; /* Frag containing location f */
+ char *fx = NULL; /* Pointer to frag location for insn[1] */
+ fragS *fxfrag; /* Frag containing location fx */
+
+ /* Start with the raw opcode bits from the opcode table. */
+ insn[0] = opcode -> opcode;
+
+ /* We are going to insert at least one 32 bit opcode so get the
+ frag now. */
+
+ f = frag_more (4);
+ ffrag = frag_now;
+
+ /* For each operand expression, insert the appropriate bits into the
+ instruction . */
+ for (expi = 0, opi = -1; opers[expi].X_op != O_illegal; expi++)
+ {
+ int bits, shift, flags, X_op, num;
+
+ X_op = opers[expi].X_op;
+ num = opers[expi].X_add_number;
+
+ /* The O_absent expressions apply to the same operand as the most
+ recent non O_absent expression. So only increment the operand
+ index when the current expression is not one of these special
+ expressions. */
+
+ if (X_op != O_absent)
+ {
+ opi++;
+ }
+
+ flags = tic80_operands[opcode -> operands[opi]].flags;
+ bits = tic80_operands[opcode -> operands[opi]].bits;
+ shift = tic80_operands[opcode -> operands[opi]].shift;
+
+ switch (X_op)
+ {
+ case O_register:
+ num &= ~TIC80_OPERAND_MASK;
+ insn[0] = insn[0] | (num << shift);
+ break;
+ case O_constant:
+ if ((flags & TIC80_OPERAND_ENDMASK) && (num == 32))
+ {
+ /* Endmask values of 0 and 32 give identical results */
+ num = 0;
+ }
+ else if ((flags & TIC80_OPERAND_BITNUM))
+ {
+ /* BITNUM values are stored in one's complement form */
+ num = (~num & 0x1F);
+ }
+ /* Mask off upper bits, just it case it is signed and is negative */
+ if (bits < 32)
+ {
+ num &= (1 << bits) - 1;
+ insn[0] = insn[0] | (num << shift);
+ }
+ else
+ {
+ fx = frag_more (4);
+ fxfrag = frag_now;
+ insn[1] = num;
+ }
+ break;
+ case O_symbol:
+ if (bits == 32)
+ {
+ fx = frag_more (4);
+ fxfrag = frag_now;
+ insn[1] = 0;
+ if (flags & TIC80_OPERAND_PCREL)
+ {
+ fix_new_exp (fxfrag,
+ fx - (fxfrag -> fr_literal),
+ 4,
+ &opers[expi],
+ 1,
+ R_MPPCR);
+ }
+ else
+ {
+ fix_new_exp (fxfrag,
+ fx - (fxfrag -> fr_literal),
+ 4,
+ &opers[expi],
+ 0,
+ R_RELLONGX);
+ }
+ }
+ else if (flags & TIC80_OPERAND_PCREL)
+ {
+ fix_new_exp (ffrag,
+ f - (ffrag -> fr_literal),
+ 4, /* FIXME! how is this used? */
+ &opers[expi],
+ 1,
+ R_MPPCR15W);
+ }
+ else
+ {
+ internal_error (_("symbol reloc that is not PC relative or 32 bits"));
+ }
+ break;
+ case O_absent:
+ /* Each O_absent expression can indicate exactly one possible modifier. */
+ if ((num & TIC80_OPERAND_M_SI) && (flags & TIC80_OPERAND_M_SI))
+ {
+ insn[0] = insn[0] | (1 << 17);
+ }
+ else if ((num & TIC80_OPERAND_M_LI) && (flags & TIC80_OPERAND_M_LI))
+ {
+ insn[0] = insn[0] | (1 << 15);
+ }
+ else if ((num & TIC80_OPERAND_SCALED) && (flags & TIC80_OPERAND_SCALED))
+ {
+ insn[0] = insn[0] | (1 << 11);
+ }
+ else if ((num & TIC80_OPERAND_PARENS) && (flags & TIC80_OPERAND_PARENS))
+ {
+ /* No code to generate, just accept and discard this expression */
+ }
+ else
+ {
+ internal_error_a (_("unhandled operand modifier"), opers[expi].X_add_number);
+ }
+ break;
+ case O_big:
+ fx = frag_more (4);
+ fxfrag = frag_now;
+ {
+ int precision = 2;
+ long exponent_bits = 8L;
+ LITTLENUM_TYPE words[2];
+ /* Value is still in generic_floating_point_number */
+ gen_to_words (words, precision, exponent_bits);
+ insn[1] = (words[0] << 16) | words[1];
+ }
+ break;
+ case O_illegal:
+ case O_symbol_rva:
+ case O_uminus:
+ case O_bit_not:
+ case O_logical_not:
+ case O_multiply:
+ case O_divide:
+ case O_modulus:
+ case O_left_shift:
+ case O_right_shift:
+ case O_bit_inclusive_or:
+ case O_bit_or_not:
+ case O_bit_exclusive_or:
+ case O_bit_and:
+ case O_add:
+ case O_subtract:
+ case O_eq:
+ case O_ne:
+ case O_lt:
+ case O_le:
+ case O_ge:
+ case O_gt:
+ case O_logical_and:
+ case O_logical_or:
+ case O_max:
+ default:
+ internal_error_a (_("unhandled expression"), X_op);
+ break;
+ }
+ }
+
+ /* Write out the instruction, either 4 or 8 bytes. */
+
+ md_number_to_chars (f, insn[0], 4);
+ if (fx != NULL)
+ {
+ md_number_to_chars (fx, insn[1], 4);
+ }
+}
+
+/* This is the main entry point for the machine-dependent assembler. Gas
+ calls this function for each input line which does not contain a
+ pseudoop.
+
+ STR points to a NULL terminated machine dependent instruction. This
+ function is supposed to emit the frags/bytes it assembles to. */
+
+void
+md_assemble (str)
+ char *str;
+{
+ char *scan;
+ unsigned char *input_line_save;
+ struct tic80_opcode *opcode;
+ expressionS myops[16];
+ unsigned long insn;
+
+ /* Ensure there is something there to assemble. */
+ assert (str);
+
+ /* Drop any leading whitespace. */
+ while (isspace (*str))
+ {
+ str++;
+ }
+
+ /* Isolate the mnemonic from the rest of the string by finding the first
+ whitespace character and zapping it to a null byte. */
+ for (scan = str; *scan != '\000' && !isspace (*scan); scan++) {;}
+ if (*scan != '\000')
+ {
+ *scan++ = '\000';
+ }
+
+ /* Try to find this mnemonic in the hash table */
+ if ((opcode = (struct tic80_opcode *) hash_find (tic80_hash, str)) == NULL)
+ {
+ as_bad (_("Invalid mnemonic: '%s'"), str);
+ return;
+ }
+
+ str = scan;
+ while (isspace (*scan))
+ {
+ scan++;
+ }
+
+ input_line_save = input_line_pointer;
+ input_line_pointer = str;
+
+ opcode = find_opcode (opcode, myops);
+ if (opcode == NULL)
+ {
+ as_bad (_("Invalid operands: '%s'"), input_line_save);
+ }
+
+ input_line_pointer = input_line_save;
+ build_insn (opcode, myops);
+}
+
+/* This function is called once at the start of assembly, after the command
+ line arguments have been parsed and all the machine independent
+ initializations have been completed.
+
+ It should set up all the tables, etc., that the machine dependent part of
+ the assembler will need. */
+
+void
+md_begin ()
+{
+ char *prev_name = "";
+ register const struct tic80_opcode *op;
+ register const struct tic80_opcode *op_end;
+ const struct predefined_symbol *pdsp;
+ extern int coff_flags; /* Defined in obj-coff.c */
+
+ /* Set F_AR32WR in coff_flags, which will end up in the file header
+ f_flags field. */
+
+ coff_flags |= F_AR32WR; /* TIc80 is 32 bit little endian */
+
+ /* Insert unique names into hash table. The TIc80 instruction set
+ has many identical opcode names that have different opcodes based
+ on the operands. This hash table then provides a quick index to
+ the first opcode with a particular name in the opcode table. */
+
+ tic80_hash = hash_new ();
+ op_end = tic80_opcodes + tic80_num_opcodes;
+ for (op = tic80_opcodes; op < op_end; op++)
+ {
+ if (strcmp (prev_name, op -> name) != 0)
+ {
+ prev_name = (char *) op -> name;
+ hash_insert (tic80_hash, op -> name, (char *) op);
+ }
+ }
+
+ /* Insert the predefined symbols into the symbol table. We use symbol_create
+ rather than symbol_new so that these symbols don't end up in the object
+ files' symbol table. Note that the values of the predefined symbols include
+ some upper bits that distinguish the type of the symbol (register, bitnum,
+ condition code, etc) and these bits must be masked away before actually
+ inserting the values into the instruction stream. For registers we put
+ these bits in the symbol table since we use them later and there is no
+ question that they aren't part of the register number. For constants we
+ can't do that since the constant can be any value, so they are masked off
+ before putting them into the symbol table. */
+
+ pdsp = NULL;
+ while ((pdsp = tic80_next_predefined_symbol (pdsp)) != NULL)
+ {
+ segT segment;
+ valueT valu;
+ int symtype;
+
+ symtype = PDS_VALUE (pdsp) & TIC80_OPERAND_MASK;
+ switch (symtype)
+ {
+ case TIC80_OPERAND_GPR:
+ case TIC80_OPERAND_FPA:
+ case TIC80_OPERAND_CR:
+ segment = reg_section;
+ valu = PDS_VALUE (pdsp);
+ break;
+ case TIC80_OPERAND_CC:
+ case TIC80_OPERAND_BITNUM:
+ segment = absolute_section;
+ valu = PDS_VALUE (pdsp) & ~TIC80_OPERAND_MASK;
+ break;
+ default:
+ internal_error_a (_("unhandled predefined symbol bits"), symtype);
+ break;
+ }
+ symbol_table_insert (symbol_create (PDS_NAME (pdsp), segment, valu,
+ &zero_address_frag));
+ }
+}
+
+
+
+/* The assembler adds md_shortopts to the string passed to getopt. */
+
+CONST char *md_shortopts = "";
+
+/* The assembler adds md_longopts to the machine independent long options
+ that are passed to getopt. */
+
+struct option md_longopts[] = {
+
+#define OPTION_RELAX (OPTION_MD_BASE)
+ {"relax", no_argument, NULL, OPTION_RELAX},
+
+#define OPTION_NO_RELAX (OPTION_RELAX + 1)
+ {"no-relax", no_argument, NULL, OPTION_NO_RELAX},
+
+ {NULL, no_argument, NULL, 0}
+};
+
+size_t md_longopts_size = sizeof(md_longopts);
+
+/* The md_parse_option function will be called whenever getopt returns an
+ unrecognized code, presumably indicating a special code value which
+ appears in md_longopts for machine specific command line options. */
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case OPTION_RELAX:
+ tic80_relax = 1;
+ break;
+ case OPTION_NO_RELAX:
+ tic80_relax = 0;
+ break;
+ default:
+ return (0);
+ }
+ return (1);
+}
+
+/* The md_show_usage function will be called whenever a usage message is
+ printed. It should print a description of the machine specific options
+ found in md_longopts. */
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf (stream, "\
+TIc80 options:\n\
+-relax alter PC relative branch instructions to use long form when needed\n\
+-no-relax always use short PC relative branch instructions, error on overflow\n");
+}
+
+
+/* Attempt to simplify or even eliminate a fixup. The return value is
+ ignored; perhaps it was once meaningful, but now it is historical.
+ To indicate that a fixup has been eliminated, set fixP->fx_done.
+ */
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *dest = fixP -> fx_frag -> fr_literal + fixP -> fx_where;
+ int overflow;
+
+ switch (fixP -> fx_r_type)
+ {
+ case R_RELLONGX:
+ md_number_to_chars (dest, (valueT) val, 4);
+ break;
+ case R_MPPCR:
+ val >>= 2;
+ val += 1; /* Target address computed from inst start */
+ md_number_to_chars (dest, (valueT) val, 4);
+ break;
+ case R_MPPCR15W:
+ overflow = (val < -65536L) || (val > 65532L);
+ if (overflow)
+ {
+ as_bad_where (fixP -> fx_file, fixP -> fx_line,
+ _("PC offset 0x%lx outside range 0x%lx-0x%lx"),
+ val, -65536L, 65532L);
+ }
+ else
+ {
+ val >>= 2;
+ *dest++ = val & 0xFF;
+ val >>= 8;
+ *dest = (*dest & 0x80) | (val & 0x7F);
+ }
+ break;
+ case R_ABS:
+ md_number_to_chars (dest, (valueT) val, fixP -> fx_size);
+ break;
+ default:
+ internal_error_a (_("unhandled relocation type in fixup"), fixP -> fx_r_type);
+ break;
+ }
+}
+
+
+/* Functions concerning relocs. */
+
+/* The location from which a PC relative jump should be calculated,
+ given a PC relative reloc.
+
+ For the TIc80, this is the address of the 32 bit opcode containing
+ the PC relative field. */
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return (fixP -> fx_frag -> fr_address + fixP -> fx_where) ;
+}
+
+/*
+ * Called after relax() is finished.
+ * In: Address of frag.
+ * fr_type == rs_machine_dependent.
+ * fr_subtype is what the address relaxed to.
+ *
+ * Out: Any fixSs and constants are set up.
+ * Caller will turn frag into a ".space 0".
+ */
+
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ internal_error (_("md_convert_frag() not implemented yet"));
+ abort ();
+}
+
+
+/*ARGSUSED*/
+void
+tc_coff_symbol_emit_hook (ignore)
+ symbolS *ignore;
+{
+}
+
+#if defined OBJ_COFF
+
+short
+tc_coff_fix2rtype (fixP)
+ fixS *fixP;
+{
+ return (fixP -> fx_r_type);
+}
+
+#endif /* OBJ_COFF */
+
+/* end of tc-tic80.c */
diff --git a/gas/config/tc-tic80.h b/gas/config/tc-tic80.h
new file mode 100644
index 00000000000..06ff249dd04
--- /dev/null
+++ b/gas/config/tc-tic80.h
@@ -0,0 +1,63 @@
+/* This file is tc-tic80.h
+ Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_TIC80
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define TARGET_ARCH bfd_arch_tic80
+#define TARGET_FORMAT "coff-tic80"
+#define BFD_ARCH TARGET_ARCH
+
+/* We need the extra field in the fixup struct to put the relocation in. */
+
+#define NEED_FX_R_TYPE
+
+/* Define md_number_to_chars as the appropriate standard big endian or
+ little endian function. Should we someday support endianness as a
+ runtime decision, this will need to change. */
+
+#define md_number_to_chars number_to_chars_littleendian
+
+/* Define away the call to md_operand in the expression parsing code.
+ This is called whenever the expression parser can't parse the input
+ and gives the assembler backend a chance to deal with it instead. */
+
+#define md_operand(x)
+
+#ifdef OBJ_COFF
+
+/* COFF specific definitions. */
+
+#define COFF_MAGIC TIC80_ARCH_MAGIC
+
+/* Whether a reloc should be output. */
+
+#define TC_COUNT_RELOC(fixp) ((fixp) -> fx_addsy != NULL)
+
+/* This macro translates between an internal fix and an coff reloc type */
+
+#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
+
+extern short tc_coff_fix2rtype ();
+
+#endif /* OBJ_COFF */
+
+/* end of tc-tic80.h */
diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c
new file mode 100644
index 00000000000..c8ab145adef
--- /dev/null
+++ b/gas/config/tc-v850.c
@@ -0,0 +1,2478 @@
+/* tc-v850.c -- Assembler code for the NEC V850
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "as.h"
+#include "subsegs.h"
+#include "opcode/v850.h"
+
+#define AREA_ZDA 0
+#define AREA_SDA 1
+#define AREA_TDA 2
+
+/* sign-extend a 16-bit number */
+#define SEXT16(x) ((((x) & 0xffff) ^ (~ 0x7fff)) + 0x8000)
+
+/* Temporarily holds the reloc in a cons expression. */
+static bfd_reloc_code_real_type hold_cons_reloc;
+
+/* Set to TRUE if we want to be pedantic about signed overflows. */
+static boolean warn_signed_overflows = FALSE;
+static boolean warn_unsigned_overflows = FALSE;
+
+/* Indicates the target BFD machine number. */
+static int machine = -1;
+
+/* Indicates the target processor(s) for the assemble. */
+static unsigned int processor_mask = -1;
+
+
+/* Structure to hold information about predefined registers. */
+struct reg_name
+{
+ const char * name;
+ int value;
+};
+
+/* Generic assembler global variables which must be defined by all targets. */
+
+/* Characters which always start a comment. */
+const char comment_chars[] = "#";
+
+/* Characters which start a comment at the beginning of a line. */
+const char line_comment_chars[] = ";#";
+
+/* Characters which may be used to separate multiple commands on a
+ single line. */
+const char line_separator_chars[] = ";";
+
+/* Characters which are used to indicate an exponent in a floating
+ point number. */
+const char EXP_CHARS[] = "eE";
+
+/* Characters which mean that a number is a floating point constant,
+ as in 0d1.0. */
+const char FLT_CHARS[] = "dD";
+
+
+const relax_typeS md_relax_table[] =
+{
+ /* Conditional branches. */
+ {0xff, -0x100, 2, 1},
+ {0x1fffff, -0x200000, 6, 0},
+ /* Unconditional branches. */
+ {0xff, -0x100, 2, 3},
+ {0x1fffff, -0x200000, 4, 0},
+};
+
+
+static segT sdata_section = NULL;
+static segT tdata_section = NULL;
+static segT zdata_section = NULL;
+static segT sbss_section = NULL;
+static segT tbss_section = NULL;
+static segT zbss_section = NULL;
+static segT rosdata_section = NULL;
+static segT rozdata_section = NULL;
+static segT scommon_section = NULL;
+static segT tcommon_section = NULL;
+static segT zcommon_section = NULL;
+static segT call_table_data_section = NULL;
+static segT call_table_text_section = NULL;
+
+/* fixups */
+#define MAX_INSN_FIXUPS (5)
+struct v850_fixup
+{
+ expressionS exp;
+ int opindex;
+ bfd_reloc_code_real_type reloc;
+};
+
+struct v850_fixup fixups [MAX_INSN_FIXUPS];
+static int fc;
+
+
+void
+v850_sdata (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (sdata_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_tdata (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (tdata_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_zdata (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (zdata_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_sbss (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (sbss_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_tbss (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (tbss_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_zbss (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (zbss_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_rosdata (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (rosdata_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_rozdata (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (rozdata_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_call_table_data (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (call_table_data_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_call_table_text (int ignore)
+{
+ obj_elf_section_change_hook();
+
+ subseg_set (call_table_text_section, (subsegT) get_absolute_expression ());
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_bss (int ignore)
+{
+ register int temp = get_absolute_expression ();
+
+ obj_elf_section_change_hook();
+
+ subseg_set (bss_section, (subsegT) temp);
+
+ demand_empty_rest_of_line ();
+}
+
+void
+v850_offset (int ignore)
+{
+ int temp = get_absolute_expression ();
+
+ temp -= frag_now_fix();
+
+ if (temp > 0)
+ (void) frag_more (temp);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Copied from obj_elf_common() in gas/config/obj-elf.c */
+static void
+v850_comm (area)
+ int area;
+{
+ char * name;
+ char c;
+ char * p;
+ int temp;
+ int size;
+ symbolS * symbolP;
+ int have_align;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer ++; /* skip ',' */
+
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ /* xgettext:c-format */
+ as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ size = temp;
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (S_GET_VALUE (symbolP) != 0)
+ {
+ if (S_GET_VALUE (symbolP) != size)
+ {
+ /* xgettext:c-format */
+ as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
+ S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+ }
+ }
+
+ know (symbolP->sy_frag == & zero_address_frag);
+
+ if (*input_line_pointer != ',')
+ have_align = 0;
+ else
+ {
+ have_align = 1;
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+
+ if (! have_align || *input_line_pointer != '"')
+ {
+ if (! have_align)
+ temp = 0;
+ else
+ {
+ temp = get_absolute_expression ();
+
+ if (temp < 0)
+ {
+ temp = 0;
+ as_warn (_("Common alignment negative; 0 assumed"));
+ }
+ }
+
+ if (symbolP->local)
+ {
+ segT old_sec;
+ int old_subsec;
+ char * pfrag;
+ int align;
+ flagword applicable;
+
+ old_sec = now_seg;
+ old_subsec = now_subseg;
+
+ applicable = bfd_applicable_section_flags (stdoutput);
+
+ applicable &= SEC_ALLOC;
+
+ switch (area)
+ {
+ case AREA_SDA:
+ if (sbss_section == NULL)
+ {
+ sbss_section = subseg_new (".sbss", 0);
+
+ bfd_set_section_flags (stdoutput, sbss_section, applicable);
+
+ seg_info (sbss_section)->bss = 1;
+ }
+ break;
+
+ case AREA_ZDA:
+ if (zbss_section == NULL)
+ {
+ zbss_section = subseg_new (".zbss", 0);
+
+ bfd_set_section_flags (stdoutput, sbss_section, applicable);
+
+ seg_info (zbss_section)->bss = 1;
+ }
+ break;
+
+ case AREA_TDA:
+ if (tbss_section == NULL)
+ {
+ tbss_section = subseg_new (".tbss", 0);
+
+ bfd_set_section_flags (stdoutput, tbss_section, applicable);
+
+ seg_info (tbss_section)->bss = 1;
+ }
+ break;
+ }
+
+ if (temp)
+ {
+ /* convert to a power of 2 alignment */
+ for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)
+ ;
+
+ if (temp != 1)
+ {
+ as_bad (_("Common alignment not a power of 2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align = 0;
+
+ switch (area)
+ {
+ case AREA_SDA:
+ record_alignment (sbss_section, align);
+ obj_elf_section_change_hook();
+ subseg_set (sbss_section, 0);
+ break;
+
+ case AREA_ZDA:
+ record_alignment (zbss_section, align);
+ obj_elf_section_change_hook();
+ subseg_set (zbss_section, 0);
+ break;
+
+ case AREA_TDA:
+ record_alignment (tbss_section, align);
+ obj_elf_section_change_hook();
+ subseg_set (tbss_section, 0);
+ break;
+
+ default:
+ abort();
+ }
+
+ if (align)
+ frag_align (align, 0, 0);
+
+ switch (area)
+ {
+ case AREA_SDA:
+ if (S_GET_SEGMENT (symbolP) == sbss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ break;
+
+ case AREA_ZDA:
+ if (S_GET_SEGMENT (symbolP) == zbss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ break;
+
+ case AREA_TDA:
+ if (S_GET_SEGMENT (symbolP) == tbss_section)
+ symbolP->sy_frag->fr_symbol = 0;
+ break;
+
+ default:
+ abort();
+ }
+
+ symbolP->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+ (offsetT) size, (char *) 0);
+ *pfrag = 0;
+ S_SET_SIZE (symbolP, size);
+
+ switch (area)
+ {
+ case AREA_SDA:
+ S_SET_SEGMENT (symbolP, sbss_section);
+ break;
+
+ case AREA_ZDA:
+ S_SET_SEGMENT (symbolP, zbss_section);
+ break;
+
+ case AREA_TDA:
+ S_SET_SEGMENT (symbolP, tbss_section);
+ break;
+
+ default:
+ abort();
+ }
+
+ S_CLEAR_EXTERNAL (symbolP);
+ obj_elf_section_change_hook();
+ subseg_set (old_sec, old_subsec);
+ }
+ else
+ {
+ allocate_common:
+ S_SET_VALUE (symbolP, (valueT) size);
+ S_SET_ALIGN (symbolP, temp);
+ S_SET_EXTERNAL (symbolP);
+
+ switch (area)
+ {
+ case AREA_SDA:
+ if (scommon_section == NULL)
+ {
+ flagword applicable;
+
+ applicable = bfd_applicable_section_flags (stdoutput);
+
+ scommon_section = subseg_new (".scommon", 0);
+
+ bfd_set_section_flags (stdoutput, scommon_section, applicable
+ & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS) | SEC_IS_COMMON);
+ }
+ S_SET_SEGMENT (symbolP, scommon_section);
+ break;
+
+ case AREA_ZDA:
+ if (zcommon_section == NULL)
+ {
+ flagword applicable;
+
+ applicable = bfd_applicable_section_flags (stdoutput);
+
+ zcommon_section = subseg_new (".zcommon", 0);
+
+ bfd_set_section_flags (stdoutput, zcommon_section, applicable
+ & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS) | SEC_IS_COMMON);
+ }
+ S_SET_SEGMENT (symbolP, zcommon_section);
+ break;
+
+ case AREA_TDA:
+ if (tcommon_section == NULL)
+ {
+ flagword applicable;
+
+ applicable = bfd_applicable_section_flags (stdoutput);
+
+ tcommon_section = subseg_new (".tcommon", 0);
+
+ bfd_set_section_flags (stdoutput, tcommon_section, applicable
+ & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+ | SEC_HAS_CONTENTS) | SEC_IS_COMMON);
+ }
+ S_SET_SEGMENT (symbolP, tcommon_section);
+ break;
+
+ default:
+ abort();
+ }
+ }
+ }
+ else
+ {
+ input_line_pointer++;
+ /* @@ Some use the dot, some don't. Can we get some consistency?? */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+ /* @@ Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4)
+ && strncmp (input_line_pointer, "data\"", 5))
+ {
+ while (*--input_line_pointer != '"')
+ ;
+ input_line_pointer--;
+ goto bad_common_segment;
+ }
+ while (*input_line_pointer++ != '"')
+ ;
+ goto allocate_common;
+ }
+
+ symbolP->bsym->flags |= BSF_OBJECT;
+
+ demand_empty_rest_of_line ();
+ return;
+
+ {
+ bad_common_segment:
+ p = input_line_pointer;
+ while (*p && *p != '\n')
+ p++;
+ c = *p;
+ *p = '\0';
+ as_bad (_("bad .common segment %s"), input_line_pointer + 1);
+ *p = c;
+ input_line_pointer = p;
+ ignore_rest_of_line ();
+ return;
+ }
+}
+
+void
+set_machine (int number)
+{
+ machine = number;
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
+
+ switch (machine)
+ {
+ case 0: processor_mask = PROCESSOR_V850; break;
+ case bfd_mach_v850e: processor_mask = PROCESSOR_V850E; break;
+ case bfd_mach_v850ea: processor_mask = PROCESSOR_V850EA; break;
+ }
+}
+
+/* The target specific pseudo-ops which we support. */
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"sdata", v850_sdata, 0},
+ {"tdata", v850_tdata, 0},
+ {"zdata", v850_zdata, 0},
+ {"sbss", v850_sbss, 0},
+ {"tbss", v850_tbss, 0},
+ {"zbss", v850_zbss, 0},
+ {"rosdata", v850_rosdata, 0},
+ {"rozdata", v850_rozdata, 0},
+ {"bss", v850_bss, 0},
+ {"offset", v850_offset, 0},
+ {"word", cons, 4},
+ {"zcomm", v850_comm, AREA_ZDA},
+ {"scomm", v850_comm, AREA_SDA},
+ {"tcomm", v850_comm, AREA_TDA},
+ {"v850", set_machine, 0},
+ {"call_table_data", v850_call_table_data, 0},
+ {"call_table_text", v850_call_table_text, 0},
+ {"v850e", set_machine, bfd_mach_v850e},
+ {"v850ea", set_machine, bfd_mach_v850ea},
+ { NULL, NULL, 0}
+};
+
+/* Opcode hash table. */
+static struct hash_control *v850_hash;
+
+/* This table is sorted. Suitable for searching by a binary search. */
+static const struct reg_name pre_defined_registers[] =
+{
+ { "ep", 30 }, /* ep - element ptr */
+ { "gp", 4 }, /* gp - global ptr */
+ { "hp", 2 }, /* hp - handler stack ptr */
+ { "lp", 31 }, /* lp - link ptr */
+ { "r0", 0 },
+ { "r1", 1 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "r16", 16 },
+ { "r17", 17 },
+ { "r18", 18 },
+ { "r19", 19 },
+ { "r2", 2 },
+ { "r20", 20 },
+ { "r21", 21 },
+ { "r22", 22 },
+ { "r23", 23 },
+ { "r24", 24 },
+ { "r25", 25 },
+ { "r26", 26 },
+ { "r27", 27 },
+ { "r28", 28 },
+ { "r29", 29 },
+ { "r3", 3 },
+ { "r30", 30 },
+ { "r31", 31 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+ { "sp", 3 }, /* sp - stack ptr */
+ { "tp", 5 }, /* tp - text ptr */
+ { "zero", 0 },
+};
+#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct reg_name))
+
+
+static const struct reg_name system_registers[] =
+{
+ { "ctbp", 20 },
+ { "ctpc", 16 },
+ { "ctpsw", 17 },
+ { "dbpc", 18 },
+ { "dbpsw", 19 },
+ { "ecr", 4 },
+ { "eipc", 0 },
+ { "eipsw", 1 },
+ { "fepc", 2 },
+ { "fepsw", 3 },
+ { "psw", 5 },
+};
+#define SYSREG_NAME_CNT (sizeof (system_registers) / sizeof (struct reg_name))
+
+static const struct reg_name system_list_registers[] =
+{
+ {"PS", 5 },
+ {"SR", 0 + 1}
+};
+#define SYSREGLIST_NAME_CNT (sizeof (system_list_registers) / sizeof (struct reg_name))
+
+static const struct reg_name cc_names[] =
+{
+ { "c", 0x1 },
+ { "e", 0x2 },
+ { "ge", 0xe },
+ { "gt", 0xf },
+ { "h", 0xb },
+ { "l", 0x1 },
+ { "le", 0x7 },
+ { "lt", 0x6 },
+ { "n", 0x4 },
+ { "nc", 0x9 },
+ { "ne", 0xa },
+ { "nh", 0x3 },
+ { "nl", 0x9 },
+ { "ns", 0xc },
+ { "nv", 0x8 },
+ { "nz", 0xa },
+ { "p", 0xc },
+ { "s", 0x4 },
+ { "sa", 0xd },
+ { "t", 0x5 },
+ { "v", 0x0 },
+ { "z", 0x2 },
+};
+#define CC_NAME_CNT (sizeof (cc_names) / sizeof (struct reg_name))
+
+/* reg_name_search does a binary search of the given register table
+ to see if "name" is a valid regiter name. Returns the register
+ number from the array on success, or -1 on failure. */
+
+static int
+reg_name_search (regs, regcount, name, accept_numbers)
+ const struct reg_name * regs;
+ int regcount;
+ const char * name;
+ boolean accept_numbers;
+{
+ int middle, low, high;
+ int cmp;
+ symbolS * symbolP;
+
+ /* If the register name is a symbol, then evaluate it. */
+ if ((symbolP = symbol_find (name)) != NULL)
+ {
+ /* If the symbol is an alias for another name then use that.
+ If the symbol is an alias for a number, then return the number. */
+ if (symbolP->sy_value.X_op == O_symbol)
+ {
+ name = S_GET_NAME (symbolP->sy_value.X_add_symbol);
+ }
+ else if (accept_numbers)
+ {
+ int reg = S_GET_VALUE (symbolP);
+
+ if (reg >= 0 && reg <= 31)
+ return reg;
+ }
+
+ /* Otherwise drop through and try parsing name normally. */
+ }
+
+ low = 0;
+ high = regcount - 1;
+
+ do
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, regs[middle].name);
+ if (cmp < 0)
+ high = middle - 1;
+ else if (cmp > 0)
+ low = middle + 1;
+ else
+ return regs[middle].value;
+ }
+ while (low <= high);
+ return -1;
+}
+
+
+/* Summary of register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+register_name (expressionP)
+ expressionS * expressionP;
+{
+ int reg_number;
+ char * name;
+ char * start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+
+ reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,
+ name, FALSE);
+
+ * input_line_pointer = c; /* put back the delimiting char */
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ input_line_pointer = start;
+
+ return false;
+ }
+}
+
+/* Summary of system_register_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ * expressionP points to an expression structure to be filled in.
+ * accept_numbers is true iff numerical register names may be used.
+ * accept_list_names is true iff the special names PS and SR may be
+ * accepted.
+ *
+ * out: A expressionS structure in expressionP.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+system_register_name (expressionP, accept_numbers, accept_list_names)
+ expressionS * expressionP;
+ boolean accept_numbers;
+ boolean accept_list_names;
+{
+ int reg_number;
+ char * name;
+ char * start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,
+ accept_numbers);
+
+ * input_line_pointer = c; /* put back the delimiting char */
+
+ if (reg_number < 0
+ && accept_numbers)
+ {
+ input_line_pointer = start; /* reset input_line pointer */
+
+ if (isdigit (* input_line_pointer))
+ {
+ reg_number = strtol (input_line_pointer, & input_line_pointer, 10);
+
+ /* Make sure that the register number is allowable. */
+ if ( reg_number < 0
+ || reg_number > 5
+ && reg_number < 16
+ || reg_number > 20
+ )
+ {
+ reg_number = -1;
+ }
+ }
+ else if (accept_list_names)
+ {
+ c = get_symbol_end ();
+ reg_number = reg_name_search (system_list_registers,
+ SYSREGLIST_NAME_CNT, name, FALSE);
+
+ * input_line_pointer = c; /* put back the delimiting char */
+ }
+ }
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ input_line_pointer = start;
+
+ return false;
+ }
+}
+
+/* Summary of cc_name().
+ *
+ * in: Input_line_pointer points to 1st char of operand.
+ *
+ * out: A expressionS.
+ * The operand may have been a register: in this case, X_op == O_register,
+ * X_add_number is set to the register number, and truth is returned.
+ * Input_line_pointer->(next non-blank) char after operand, or is in
+ * its original state.
+ */
+static boolean
+cc_name (expressionP)
+ expressionS * expressionP;
+{
+ int reg_number;
+ char * name;
+ char * start;
+ char c;
+
+ /* Find the spelling of the operand */
+ start = name = input_line_pointer;
+
+ c = get_symbol_end ();
+ reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE);
+
+ * input_line_pointer = c; /* put back the delimiting char */
+
+ /* look to see if it's in the register table */
+ if (reg_number >= 0)
+ {
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = reg_number;
+
+ /* make the rest nice */
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+
+ return true;
+ }
+ else
+ {
+ /* reset the line as if we had not done anything */
+ input_line_pointer = start;
+
+ return false;
+ }
+}
+
+static void
+skip_white_space (void)
+{
+ while ( * input_line_pointer == ' '
+ || * input_line_pointer == '\t')
+ ++ input_line_pointer;
+}
+
+/* Summary of parse_register_list ().
+ *
+ * in: Input_line_pointer points to 1st char of a list of registers.
+ * insn is the partially constructed instruction.
+ * operand is the operand being inserted.
+ *
+ * out: NULL if the parse completed successfully, otherwise a
+ * pointer to an error message is returned. If the parse
+ * completes the correct bit fields in the instruction
+ * will be filled in.
+ *
+ * Parses register lists with the syntax:
+ *
+ * { rX }
+ * { rX, rY }
+ * { rX - rY }
+ * { rX - rY, rZ }
+ * etc
+ *
+ * and also parses constant epxressions whoes bits indicate the
+ * registers in the lists. The LSB in the expression refers to
+ * the lowest numbered permissable register in the register list,
+ * and so on upwards. System registers are considered to be very
+ * high numbers.
+ *
+ */
+static char *
+parse_register_list
+(
+ unsigned long * insn,
+ const struct v850_operand * operand
+)
+{
+ static int type1_regs[ 32 ] = { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
+ static int type2_regs[ 32 ] = { 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
+ static int type3_regs[ 32 ] = { 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8 };
+ int * regs;
+ expressionS exp;
+
+
+ /* Select a register array to parse. */
+ switch (operand->shift)
+ {
+ case 0xffe00001: regs = type1_regs; break;
+ case 0xfff8000f: regs = type2_regs; break;
+ case 0xfff8001f: regs = type3_regs; break;
+ default:
+ as_bad (_("unknown operand shift: %x\n"), operand->shift);
+ return _("internal failure in parse_register_list");
+ }
+
+ skip_white_space ();
+
+ /* If the expression starts with a curly brace it is a register list.
+ Otherwise it is a constant expression, whoes bits indicate which
+ registers are to be included in the list. */
+
+ if (* input_line_pointer != '{')
+ {
+ int bits;
+ int reg;
+ int i;
+
+ expression (& exp);
+
+ if (exp.X_op != O_constant)
+ return _("constant expression or register list expected");
+
+ if (regs == type1_regs)
+ {
+ if (exp.X_add_number & 0xFFFFF000)
+ return _("high bits set in register list expression");
+
+ for (reg = 20; reg < 32; reg ++)
+ if (exp.X_add_number & (1 << (reg - 20)))
+ {
+ for (i = 0; i < 32; i++)
+ if (regs[i] == reg)
+ * insn |= (1 << i);
+ }
+ }
+ else if (regs == type2_regs)
+ {
+ if (exp.X_add_number & 0xFFFE0000)
+ return _("high bits set in register list expression");
+
+ for (reg = 1; reg < 16; reg ++)
+ if (exp.X_add_number & (1 << (reg - 1)))
+ {
+ for (i = 0; i < 32; i++)
+ if (regs[i] == reg)
+ * insn |= (1 << i);
+ }
+
+ if (exp.X_add_number & (1 << 15))
+ * insn |= (1 << 3);
+
+ if (exp.X_add_number & (1 << 16))
+ * insn |= (1 << 19);
+ }
+ else /* regs == type3_regs */
+ {
+ if (exp.X_add_number & 0xFFFE0000)
+ return _("high bits set in register list expression");
+
+ for (reg = 16; reg < 32; reg ++)
+ if (exp.X_add_number & (1 << (reg - 16)))
+ {
+ for (i = 0; i < 32; i++)
+ if (regs[i] == reg)
+ * insn |= (1 << i);
+ }
+
+ if (exp.X_add_number & (1 << 16))
+ * insn |= (1 << 19);
+ }
+
+ return NULL;
+ }
+
+ input_line_pointer ++;
+
+ /* Parse the register list until a terminator (closing curly brace or
+ new-line) is found. */
+ for (;;)
+ {
+ if (register_name (& exp))
+ {
+ int i;
+
+ /* Locate the given register in the list, and if it is there,
+ insert the corresponding bit into the instruction. */
+ for (i = 0; i < 32; i++)
+ {
+ if (regs[ i ] == exp.X_add_number)
+ {
+ * insn |= (1 << i);
+ break;
+ }
+ }
+
+ if (i == 32)
+ {
+ return _("illegal register included in list");
+ }
+ }
+ else if (system_register_name (& exp, true, true))
+ {
+ if (regs == type1_regs)
+ {
+ return _("system registers cannot be included in list");
+ }
+ else if (exp.X_add_number == 5)
+ {
+ if (regs == type2_regs)
+ return _("PSW cannot be included in list");
+ else
+ * insn |= 0x8;
+ }
+ else if (exp.X_add_number < 4)
+ * insn |= 0x80000;
+ else
+ return _("High value system registers cannot be included in list");
+ }
+ else if (* input_line_pointer == '}')
+ {
+ input_line_pointer ++;
+ break;
+ }
+ else if (* input_line_pointer == ',')
+ {
+ input_line_pointer ++;
+ continue;
+ }
+ else if (* input_line_pointer == '-')
+ {
+ /* We have encountered a range of registers: rX - rY */
+ int j;
+ expressionS exp2;
+
+ /* Skip the dash. */
+ ++ input_line_pointer;
+
+ /* Get the second register in the range. */
+ if (! register_name (& exp2))
+ {
+ return _("second register should follow dash in register list");
+ exp2.X_add_number = exp.X_add_number;
+ }
+
+ /* Add the rest of the registers in the range. */
+ for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)
+ {
+ int i;
+
+ /* Locate the given register in the list, and if it is there,
+ insert the corresponding bit into the instruction. */
+ for (i = 0; i < 32; i++)
+ {
+ if (regs[ i ] == j)
+ {
+ * insn |= (1 << i);
+ break;
+ }
+ }
+
+ if (i == 32)
+ return _("illegal register included in list");
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ skip_white_space ();
+ }
+
+ return NULL;
+}
+
+CONST char * md_shortopts = "m:";
+
+struct option md_longopts[] =
+{
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof md_longopts;
+
+
+void
+md_show_usage (stream)
+ FILE * stream;
+{
+ fprintf (stream, _(" V850 options:\n"));
+ fprintf (stream, _(" -mwarn-signed-overflow Warn if signed immediate values overflow\n"));
+ fprintf (stream, _(" -mwarn-unsigned-overflow Warn if unsigned immediate values overflow\n"));
+ fprintf (stream, _(" -mv850 The code is targeted at the v850\n"));
+ fprintf (stream, _(" -mv850e The code is targeted at the v850e\n"));
+ fprintf (stream, _(" -mv850ea The code is targeted at the v850ea\n"));
+ fprintf (stream, _(" -mv850any The code is generic, despite any processor specific instructions\n"));
+}
+
+int
+md_parse_option (c, arg)
+ int c;
+ char * arg;
+{
+ if (c != 'm')
+ {
+ /* xgettext:c-format */
+ fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);
+ return 0;
+ }
+
+ if (strcmp (arg, "warn-signed-overflow") == 0)
+ {
+ warn_signed_overflows = TRUE;
+ }
+ else if (strcmp (arg, "warn-unsigned-overflow") == 0)
+ {
+ warn_unsigned_overflows = TRUE;
+ }
+ else if (strcmp (arg, "v850") == 0)
+ {
+ machine = 0;
+ processor_mask = PROCESSOR_V850;
+ }
+ else if (strcmp (arg, "v850e") == 0)
+ {
+ machine = bfd_mach_v850e;
+ processor_mask = PROCESSOR_V850E;
+ }
+ else if (strcmp (arg, "v850ea") == 0)
+ {
+ machine = bfd_mach_v850ea;
+ processor_mask = PROCESSOR_V850EA;
+ }
+ else if (strcmp (arg, "v850any") == 0)
+ {
+ machine = 0; /* Tell the world that this is for any v850 chip. */
+ processor_mask = PROCESSOR_V850EA; /* But support instructions for the extended versions. */
+ }
+ else
+ {
+ /* xgettext:c-format */
+ fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);
+ return 0;
+ }
+
+ return 1;
+}
+
+symbolS *
+md_undefined_symbol (name)
+ char * name;
+{
+ return 0;
+}
+
+char *
+md_atof (type, litp, sizep)
+ int type;
+ char * litp;
+ int * sizep;
+{
+ int prec;
+ LITTLENUM_TYPE words[4];
+ char * t;
+ int i;
+
+ switch (type)
+ {
+ case 'f':
+ prec = 2;
+ break;
+
+ case 'd':
+ prec = 4;
+ break;
+
+ default:
+ *sizep = 0;
+ return _("bad call to md_atof");
+ }
+
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizep = prec * 2;
+
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litp, (valueT) words[i], 2);
+ litp += 2;
+ }
+
+ return NULL;
+}
+
+
+/* Very gross. */
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd * abfd;
+ asection * sec;
+ fragS * fragP;
+{
+ subseg_change (sec, 0);
+
+ /* In range conditional or unconditional branch. */
+ if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
+ {
+ fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 2;
+ }
+ /* Out of range conditional branch. Emit a branch around a jump. */
+ else if (fragP->fr_subtype == 1)
+ {
+ unsigned char *buffer =
+ (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+ /* Reverse the condition of the first branch. */
+ buffer[0] ^= 0x08;
+ /* Mask off all the displacement bits. */
+ buffer[0] &= 0x8f;
+ buffer[1] &= 0x07;
+ /* Now set the displacement bits so that we branch
+ around the unconditional branch. */
+ buffer[0] |= 0x30;
+
+ /* Now create the unconditional branch + fixup to the final
+ target. */
+ md_number_to_chars (buffer + 2, 0x00000780, 4);
+ fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_UNUSED +
+ (int) fragP->fr_opcode + 1);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 6;
+ }
+ /* Out of range unconditional branch. Emit a jump. */
+ else if (fragP->fr_subtype == 3)
+ {
+ md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, BFD_RELOC_UNUSED +
+ (int) fragP->fr_opcode + 1);
+ fragP->fr_var = 0;
+ fragP->fr_fix += 4;
+ }
+ else
+ abort ();
+}
+
+valueT
+md_section_align (seg, addr)
+ asection * seg;
+ valueT addr;
+{
+ int align = bfd_get_section_alignment (stdoutput, seg);
+ return ((addr + (1 << align) - 1) & (-1 << align));
+}
+
+void
+md_begin ()
+{
+ char * prev_name = "";
+ register const struct v850_opcode * op;
+ flagword applicable;
+
+ if (strncmp (TARGET_CPU, "v850ea", 6) == 0)
+ {
+ if (machine == -1)
+ machine = bfd_mach_v850ea;
+
+ if (processor_mask == -1)
+ processor_mask = PROCESSOR_V850EA;
+ }
+ else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
+ {
+ if (machine == -1)
+ machine = bfd_mach_v850e;
+
+ if (processor_mask == -1)
+ processor_mask = PROCESSOR_V850E;
+ }
+ else
+ if (strncmp (TARGET_CPU, "v850", 4) == 0)
+ {
+ if (machine == -1)
+ machine = 0;
+
+ if (processor_mask == -1)
+ processor_mask = PROCESSOR_V850;
+ }
+ else
+ /* xgettext:c-format */
+ as_bad (_("Unable to determine default target processor from string: %s"),
+ TARGET_CPU);
+
+ v850_hash = hash_new();
+
+ /* Insert unique names into hash table. The V850 instruction set
+ has many identical opcode names that have different opcodes based
+ on the operands. This hash table then provides a quick index to
+ the first opcode with a particular name in the opcode table. */
+
+ op = v850_opcodes;
+ while (op->name)
+ {
+ if (strcmp (prev_name, op->name))
+ {
+ prev_name = (char *) op->name;
+ hash_insert (v850_hash, op->name, (char *) op);
+ }
+ op++;
+ }
+
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
+
+ applicable = bfd_applicable_section_flags (stdoutput);
+
+ call_table_data_section = subseg_new (".call_table_data", 0);
+ bfd_set_section_flags (stdoutput, call_table_data_section,
+ applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+ | SEC_DATA | SEC_HAS_CONTENTS));
+
+ call_table_text_section = subseg_new (".call_table_text", 0);
+ bfd_set_section_flags (stdoutput, call_table_text_section,
+ applicable & (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_CODE));
+
+ /* Restore text section as the current default. */
+ subseg_set (text_section, 0);
+}
+
+
+static bfd_reloc_code_real_type
+handle_ctoff (const struct v850_operand * operand)
+{
+ if (operand == NULL)
+ return BFD_RELOC_V850_CALLT_16_16_OFFSET;
+
+ if ( operand->bits != 6
+ || operand->shift != 0)
+ {
+ as_bad (_("ctoff() relocation used on an instruction which does not support it"));
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
+ return BFD_RELOC_V850_CALLT_6_7_OFFSET;
+}
+
+static bfd_reloc_code_real_type
+handle_sdaoff (const struct v850_operand * operand)
+{
+ if (operand == NULL) return BFD_RELOC_V850_SDA_16_16_OFFSET;
+ if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_SDA_15_16_OFFSET;
+ if (operand->bits == -1) return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
+
+ if ( operand->bits != 16
+ || operand->shift != 16)
+ {
+ as_bad (_("sdaoff() relocation used on an instruction which does not support it"));
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
+ return BFD_RELOC_V850_SDA_16_16_OFFSET;
+}
+
+static bfd_reloc_code_real_type
+handle_zdaoff (const struct v850_operand * operand)
+{
+ if (operand == NULL) return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+ if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_ZDA_15_16_OFFSET;
+ if (operand->bits == -1) return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
+
+ if ( operand->bits != 16
+ || operand->shift != 16)
+ {
+ as_bad (_("zdaoff() relocation used on an instruction which does not support it"));
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
+ return BFD_RELOC_V850_ZDA_16_16_OFFSET;
+}
+
+static bfd_reloc_code_real_type
+handle_tdaoff (const struct v850_operand * operand)
+{
+ if (operand == NULL) return BFD_RELOC_V850_TDA_7_7_OFFSET; /* data item, not an instruction. */
+ if (operand->bits == 6 && operand->shift == 1) return BFD_RELOC_V850_TDA_6_8_OFFSET; /* sld.w/sst.w, operand: D8_6 */
+ if (operand->bits == 4 && operand->insert != NULL) return BFD_RELOC_V850_TDA_4_5_OFFSET; /* sld.hu, operand: D5-4 */
+ if (operand->bits == 4 && operand->insert == NULL) return BFD_RELOC_V850_TDA_4_4_OFFSET; /* sld.bu, operand: D4 */
+ if (operand->bits == 16 && operand->shift == 16) return BFD_RELOC_V850_TDA_16_16_OFFSET; /* set1 & chums, operands: D16 */
+
+ if (operand->bits != 7)
+ {
+ as_bad (_("tdaoff() relocation used on an instruction which does not support it"));
+ return BFD_RELOC_64; /* Used to indicate an error condition. */
+ }
+
+ return operand->insert != NULL
+ ? BFD_RELOC_V850_TDA_7_8_OFFSET /* sld.h/sst.h, operand: D8_7 */
+ : BFD_RELOC_V850_TDA_7_7_OFFSET; /* sld.b/sst.b, opreand: D7 */
+}
+
+/* Warning: The code in this function relies upon the definitions
+ in the v850_operands[] array (defined in opcodes/v850-opc.c)
+ matching the hard coded values contained herein. */
+
+static bfd_reloc_code_real_type
+v850_reloc_prefix (const struct v850_operand * operand)
+{
+ boolean paren_skipped = false;
+
+
+ /* Skip leading opening parenthesis. */
+ if (* input_line_pointer == '(')
+ {
+ ++ input_line_pointer;
+ paren_skipped = true;
+ }
+
+#define CHECK_(name, reloc) \
+ if (strncmp (input_line_pointer, name##"(", strlen (name) + 1) == 0) \
+ { \
+ input_line_pointer += strlen (name); \
+ return reloc; \
+ }
+
+ CHECK_ ("hi0", BFD_RELOC_HI16);
+ CHECK_ ("hi", BFD_RELOC_HI16_S);
+ CHECK_ ("lo", BFD_RELOC_LO16);
+ CHECK_ ("sdaoff", handle_sdaoff (operand));
+ CHECK_ ("zdaoff", handle_zdaoff (operand));
+ CHECK_ ("tdaoff", handle_tdaoff (operand));
+ CHECK_ ("hilo", BFD_RELOC_32);
+ CHECK_ ("ctoff", handle_ctoff (operand));
+
+ /* Restore skipped parenthesis. */
+ if (paren_skipped)
+ -- input_line_pointer;
+
+ return BFD_RELOC_UNUSED;
+}
+
+/* Insert an operand value into an instruction. */
+
+static unsigned long
+v850_insert_operand (insn, operand, val, file, line, str)
+ unsigned long insn;
+ const struct v850_operand * operand;
+ offsetT val;
+ char * file;
+ unsigned int line;
+ char * str;
+{
+ if (operand->insert)
+ {
+ const char * message = NULL;
+
+ insn = operand->insert (insn, val, & message);
+ if (message != NULL)
+ {
+ if ((operand->flags & V850_OPERAND_SIGNED)
+ && ! warn_signed_overflows
+ && strstr (message, "out of range") != NULL)
+ {
+ /* skip warning... */
+ }
+ else if ((operand->flags & V850_OPERAND_SIGNED) == 0
+ && ! warn_unsigned_overflows
+ && strstr (message, "out of range") != NULL)
+ {
+ /* skip warning... */
+ }
+ else if (str)
+ {
+ if (file == (char *) NULL)
+ as_warn ("%s: %s", str, message);
+ else
+ as_warn_where (file, line, "%s: %s", str, message);
+ }
+ else
+ {
+ if (file == (char *) NULL)
+ as_warn (message);
+ else
+ as_warn_where (file, line, message);
+ }
+ }
+ }
+ else
+ {
+ if (operand->bits != 32)
+ {
+ long min, max;
+ offsetT test;
+
+ if ((operand->flags & V850_OPERAND_SIGNED) != 0)
+ {
+ if (! warn_signed_overflows)
+ max = (1 << operand->bits) - 1;
+ else
+ max = (1 << (operand->bits - 1)) - 1;
+
+ min = - (1 << (operand->bits - 1));
+ }
+ else
+ {
+ max = (1 << operand->bits) - 1;
+
+ if (! warn_unsigned_overflows)
+ min = - (1 << (operand->bits - 1));
+ else
+ min = 0;
+ }
+
+ if (val < (offsetT) min || val > (offsetT) max)
+ {
+ /* xgettext:c-format */
+ const char * err = _("operand out of range (%s not between %ld and %ld)");
+ char buf[100];
+
+ /* Restore min and mix to expected values for decimal ranges. */
+ if ((operand->flags & V850_OPERAND_SIGNED)
+ && ! warn_signed_overflows)
+ max = (1 << (operand->bits - 1)) - 1;
+
+ if (! (operand->flags & V850_OPERAND_SIGNED)
+ && ! warn_unsigned_overflows)
+ min = 0;
+
+ if (str)
+ {
+ sprintf (buf, "%s: ", str);
+
+ sprint_value (buf + strlen (buf), val);
+ }
+ else
+ sprint_value (buf, val);
+
+ if (file == (char *) NULL)
+ as_warn (err, buf, min, max);
+ else
+ as_warn_where (file, line, err, buf, min, max);
+ }
+ }
+
+ insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
+ }
+
+ return insn;
+}
+
+
+static char copy_of_instruction [128];
+
+void
+md_assemble (str)
+ char * str;
+{
+ char * s;
+ char * start_of_operands;
+ struct v850_opcode * opcode;
+ struct v850_opcode * next_opcode;
+ const unsigned char * opindex_ptr;
+ int next_opindex;
+ int relaxable;
+ unsigned long insn;
+ unsigned long insn_size;
+ char * f;
+ int i;
+ int match;
+ boolean extra_data_after_insn = false;
+ unsigned extra_data_len;
+ unsigned long extra_data;
+ char * saved_input_line_pointer;
+
+
+ strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);
+
+ /* Get the opcode. */
+ for (s = str; *s != '\0' && ! isspace (*s); s++)
+ continue;
+
+ if (*s != '\0')
+ *s++ = '\0';
+
+ /* find the first opcode with the proper name */
+ opcode = (struct v850_opcode *) hash_find (v850_hash, str);
+ if (opcode == NULL)
+ {
+ /* xgettext:c-format */
+ as_bad (_("Unrecognized opcode: `%s'"), str);
+ ignore_rest_of_line ();
+ return;
+ }
+
+ str = s;
+ while (isspace (* str))
+ ++ str;
+
+ start_of_operands = str;
+
+ saved_input_line_pointer = input_line_pointer;
+
+ for (;;)
+ {
+ const char * errmsg = NULL;
+
+ match = 0;
+
+ if ((opcode->processors & processor_mask) == 0)
+ {
+ errmsg = _("Target processor does not support this instruction.");
+ goto error;
+ }
+
+ relaxable = 0;
+ fc = 0;
+ next_opindex = 0;
+ insn = opcode->opcode;
+ extra_data_after_insn = false;
+
+ input_line_pointer = str = start_of_operands;
+
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr ++)
+ {
+ const struct v850_operand * operand;
+ char * hold;
+ expressionS ex;
+ bfd_reloc_code_real_type reloc;
+
+ if (next_opindex == 0)
+ {
+ operand = & v850_operands[ * opindex_ptr ];
+ }
+ else
+ {
+ operand = & v850_operands[ next_opindex ];
+ next_opindex = 0;
+ }
+
+ errmsg = NULL;
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
+ ++ str;
+
+ if (operand->flags & V850_OPERAND_RELAX)
+ relaxable = 1;
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+ /* lo(), hi(), hi0(), etc... */
+ if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
+ {
+ /* This is a fake reloc, used to indicate an error condition. */
+ if (reloc == BFD_RELOC_64)
+ {
+ match = 1;
+ goto error;
+ }
+
+ expression (& ex);
+
+ if (ex.X_op == O_constant)
+ {
+ switch (reloc)
+ {
+ case BFD_RELOC_V850_ZDA_16_16_OFFSET:
+ /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"
+ and the like. */
+ /* Fall through. */
+
+ case BFD_RELOC_LO16:
+ {
+ /* Truncate, then sign extend the value. */
+ ex.X_add_number = SEXT16 (ex.X_add_number);
+ break;
+ }
+
+ case BFD_RELOC_HI16:
+ {
+ /* Truncate, then sign extend the value. */
+ ex.X_add_number = SEXT16 (ex.X_add_number >> 16);
+ break;
+ }
+
+ case BFD_RELOC_HI16_S:
+ {
+ /* Truncate, then sign extend the value. */
+ int temp = (ex.X_add_number >> 16) & 0xffff;
+
+ temp += (ex.X_add_number >> 15) & 1;
+
+ ex.X_add_number = SEXT16 (temp);
+ break;
+ }
+
+ case BFD_RELOC_32:
+ if ((operand->flags & V850E_IMMEDIATE32) == 0)
+ {
+ errmsg = _("immediate operand is too large");
+ goto error;
+ }
+
+ extra_data_after_insn = true;
+ extra_data_len = 4;
+ extra_data = ex.X_add_number;
+ ex.X_add_number = 0;
+ break;
+
+ default:
+ fprintf (stderr, "reloc: %d\n", reloc);
+ as_bad (_("AAARG -> unhandled constant reloc"));
+ break;
+ }
+
+ if (fc > MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[ fc ].exp = ex;
+ fixups[ fc ].opindex = * opindex_ptr;
+ fixups[ fc ].reloc = reloc;
+ fc++;
+ }
+ else
+ {
+ if (reloc == BFD_RELOC_32)
+ {
+ if ((operand->flags & V850E_IMMEDIATE32) == 0)
+ {
+ errmsg = _("immediate operand is too large");
+ goto error;
+ }
+
+ extra_data_after_insn = true;
+ extra_data_len = 4;
+ extra_data = ex.X_add_number;
+ }
+
+ if (fc > MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[ fc ].exp = ex;
+ fixups[ fc ].opindex = * opindex_ptr;
+ fixups[ fc ].reloc = reloc;
+ fc++;
+ }
+ }
+ else
+ {
+ errmsg = NULL;
+
+ if ((operand->flags & V850_OPERAND_REG) != 0)
+ {
+ if (!register_name (& ex))
+ {
+ errmsg = _("invalid register name");
+ }
+ else if ((operand->flags & V850_NOT_R0)
+ && ex.X_add_number == 0)
+ {
+ errmsg = _("register r0 cannot be used here");
+
+ /* Force an error message to be generated by
+ skipping over any following potential matches
+ for this opcode. */
+ opcode += 3;
+ }
+ }
+ else if ((operand->flags & V850_OPERAND_SRG) != 0)
+ {
+ if (!system_register_name (& ex, true, false))
+ {
+ errmsg = _("invalid system register name");
+ }
+ }
+ else if ((operand->flags & V850_OPERAND_EP) != 0)
+ {
+ char * start = input_line_pointer;
+ char c = get_symbol_end ();
+
+ if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)
+ {
+ /* Put things back the way we found them. */
+ *input_line_pointer = c;
+ input_line_pointer = start;
+ errmsg = _("expected EP register");
+ goto error;
+ }
+
+ *input_line_pointer = c;
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
+ ++ str;
+ continue;
+ }
+ else if ((operand->flags & V850_OPERAND_CC) != 0)
+ {
+ if (!cc_name (& ex))
+ {
+ errmsg = _("invalid condition code name");
+ }
+ }
+ else if (operand->flags & V850E_PUSH_POP)
+ {
+ errmsg = parse_register_list (& insn, operand);
+
+ /* The parse_register_list() function has already done
+ everything, so fake a dummy expression. */
+ ex.X_op = O_constant;
+ ex.X_add_number = 0;
+ }
+ else if (operand->flags & V850E_IMMEDIATE16)
+ {
+ expression (& ex);
+
+ if (ex.X_op != O_constant)
+ errmsg = _("constant expression expected");
+ else if (ex.X_add_number & 0xffff0000)
+ {
+ if (ex.X_add_number & 0xffff)
+ errmsg = _("constant too big to fit into instruction");
+ else if ((insn & 0x001fffc0) == 0x00130780)
+ ex.X_add_number >>= 16;
+ else
+ errmsg = _("constant too big to fit into instruction");
+ }
+
+ extra_data_after_insn = true;
+ extra_data_len = 2;
+ extra_data = ex.X_add_number;
+ ex.X_add_number = 0;
+ }
+ else if (operand->flags & V850E_IMMEDIATE32)
+ {
+ expression (& ex);
+
+ if (ex.X_op != O_constant)
+ errmsg = _("constant expression expected");
+
+ extra_data_after_insn = true;
+ extra_data_len = 4;
+ extra_data = ex.X_add_number;
+ ex.X_add_number = 0;
+ }
+ else if (register_name (& ex)
+ && (operand->flags & V850_OPERAND_REG) == 0)
+ {
+ char c;
+ int exists = 0;
+
+ /* It is possible that an alias has been defined that
+ matches a register name. For example the code may
+ include a ".set ZERO, 0" directive, which matches
+ the register name "zero". Attempt to reparse the
+ field as an expression, and only complain if we
+ cannot generate a constant. */
+
+ input_line_pointer = str;
+
+ c = get_symbol_end ();
+
+ if (symbol_find (str) != NULL)
+ exists = 1;
+
+ * input_line_pointer = c;
+ input_line_pointer = str;
+
+ expression (& ex);
+
+ if (ex.X_op != O_constant)
+ {
+ /* If this register is actually occuring too early on
+ the parsing of the instruction, (because another
+ field is missing) then report this. */
+ if (opindex_ptr[1] != 0
+ && (v850_operands [opindex_ptr [1]].flags & V850_OPERAND_REG))
+ errmsg = _("syntax error: value is missing before the register name");
+ else
+ errmsg = _("syntax error: register not expected");
+
+ /* If we created a symbol in the process of this test then
+ delete it now, so that it will not be output with the real
+ symbols... */
+ if (exists == 0
+ && ex.X_op == O_symbol)
+ symbol_remove (ex.X_add_symbol,
+ & symbol_rootP, & symbol_lastP);
+ }
+ }
+ else if (system_register_name (& ex, false, false)
+ && (operand->flags & V850_OPERAND_SRG) == 0)
+ {
+ errmsg = _("syntax error: system register not expected");
+ }
+ else if (cc_name (&ex)
+ && (operand->flags & V850_OPERAND_CC) == 0)
+ {
+ errmsg = _("syntax error: condition code not expected");
+ }
+ else
+ {
+ expression (& ex);
+ /* Special case:
+ If we are assembling a MOV instruction (or a CALLT.... :-)
+ and the immediate value does not fit into the bits
+ available then create a fake error so that the next MOV
+ instruction will be selected. This one has a 32 bit
+ immediate field. */
+
+ if (((insn & 0x07e0) == 0x0200)
+ && ex.X_op == O_constant
+ && (ex.X_add_number < (- (1 << (operand->bits - 1)))
+ || ex.X_add_number > ((1 << operand->bits) - 1)))
+ errmsg = _("immediate operand is too large");
+ }
+
+ if (errmsg)
+ goto error;
+
+/* fprintf (stderr, " insn: %x, operand %d, op: %d, add_number: %d\n",
+ insn, opindex_ptr - opcode->operands, ex.X_op, ex.X_add_number); */
+
+ switch (ex.X_op)
+ {
+ case O_illegal:
+ errmsg = _("illegal operand");
+ goto error;
+ case O_absent:
+ errmsg = _("missing operand");
+ goto error;
+ case O_register:
+ if ((operand->flags & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
+ {
+ errmsg = _("invalid operand");
+ goto error;
+ }
+ insn = v850_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0,
+ copy_of_instruction);
+ break;
+
+ case O_constant:
+ insn = v850_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0,
+ copy_of_instruction);
+ break;
+
+ default:
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ fixups[ fc ].exp = ex;
+ fixups[ fc ].opindex = * opindex_ptr;
+ fixups[ fc ].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ break;
+ }
+ }
+
+ str = input_line_pointer;
+ input_line_pointer = hold;
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'
+ || *str == ')')
+ ++str;
+ }
+ match = 1;
+
+ error:
+ if (match == 0)
+ {
+ next_opcode = opcode + 1;
+ if (next_opcode->name != NULL
+ && strcmp (next_opcode->name, opcode->name) == 0)
+ {
+ opcode = next_opcode;
+
+ /* Skip versions that are not supported by the target
+ processor. */
+ if ((opcode->processors & processor_mask) == 0)
+ goto error;
+
+ continue;
+ }
+
+ as_bad ("%s: %s", copy_of_instruction, errmsg);
+
+ if (* input_line_pointer == ']')
+ ++ input_line_pointer;
+
+ ignore_rest_of_line ();
+ input_line_pointer = saved_input_line_pointer;
+ return;
+ }
+ break;
+ }
+
+ while (isspace (*str))
+ ++str;
+
+ if (*str != '\0')
+ /* xgettext:c-format */
+ as_bad (_("junk at end of line: `%s'"), str);
+
+ input_line_pointer = str;
+
+ /* Write out the instruction. */
+
+ if (relaxable && fc > 0)
+ {
+ insn_size = 2;
+ fc = 0;
+
+ if (!strcmp (opcode->name, "br"))
+ {
+ f = frag_var (rs_machine_dependent, 4, 2, 2,
+ fixups[0].exp.X_add_symbol,
+ fixups[0].exp.X_add_number,
+ (char *)fixups[0].opindex);
+ md_number_to_chars (f, insn, insn_size);
+ md_number_to_chars (f + 2, 0, 2);
+ }
+ else
+ {
+ f = frag_var (rs_machine_dependent, 6, 4, 0,
+ fixups[0].exp.X_add_symbol,
+ fixups[0].exp.X_add_number,
+ (char *)fixups[0].opindex);
+ md_number_to_chars (f, insn, insn_size);
+ md_number_to_chars (f + 2, 0, 4);
+ }
+ }
+ else
+ {
+ /* Four byte insns have an opcode with the two high bits on. */
+ if ((insn & 0x0600) == 0x0600)
+ insn_size = 4;
+ else
+ insn_size = 2;
+
+ /* Special case: 32 bit MOV */
+ if ((insn & 0xffe0) == 0x0620)
+ insn_size = 2;
+
+ f = frag_more (insn_size);
+
+ md_number_to_chars (f, insn, insn_size);
+
+ if (extra_data_after_insn)
+ {
+ f = frag_more (extra_data_len);
+
+ md_number_to_chars (f, extra_data, extra_data_len);
+
+ extra_data_after_insn = false;
+ }
+ }
+
+ /* Create any fixups. At this point we do not use a
+ bfd_reloc_code_real_type, but instead just use the
+ BFD_RELOC_UNUSED plus the operand index. This lets us easily
+ handle fixups for any operand type, although that is admittedly
+ not a very exciting feature. We pick a BFD reloc type in
+ md_apply_fix. */
+ for (i = 0; i < fc; i++)
+ {
+ const struct v850_operand * operand;
+ bfd_reloc_code_real_type reloc;
+
+ operand = & v850_operands[ fixups[i].opindex ];
+
+ reloc = fixups[i].reloc;
+
+ if (reloc != BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type * reloc_howto = bfd_reloc_type_lookup (stdoutput,
+ reloc);
+ int size;
+ int address;
+ fixS * fixP;
+
+ if (!reloc_howto)
+ abort();
+
+ size = bfd_get_reloc_size (reloc_howto);
+
+ /* XXX This will abort on an R_V850_8 reloc -
+ is this reloc actually used ? */
+ if (size != 2 && size != 4)
+ abort ();
+
+ address = (f - frag_now->fr_literal) + insn_size - size;
+
+ if (reloc == BFD_RELOC_32)
+ {
+ address += 2;
+ }
+
+ fixP = fix_new_exp (frag_now, address, size,
+ & fixups[i].exp,
+ reloc_howto->pc_relative,
+ reloc);
+
+ switch (reloc)
+ {
+ case BFD_RELOC_LO16:
+ case BFD_RELOC_HI16:
+ case BFD_RELOC_HI16_S:
+ fixP->fx_no_overflow = 1;
+ break;
+ }
+ }
+ else
+ {
+ fix_new_exp (
+ frag_now,
+ f - frag_now->fr_literal, 4,
+ & fixups[i].exp,
+ 1 /* FIXME: V850_OPERAND_RELATIVE ??? */,
+ (bfd_reloc_code_real_type) (fixups[i].opindex
+ + (int) BFD_RELOC_UNUSED)
+ );
+ }
+ }
+
+ input_line_pointer = saved_input_line_pointer;
+}
+
+
+/* If while processing a fixup, a reloc really needs to be created */
+/* then it is done here. */
+
+arelent *
+tc_gen_reloc (seg, fixp)
+ asection * seg;
+ fixS * fixp;
+{
+ arelent * reloc;
+
+ reloc = (arelent *) xmalloc (sizeof (arelent));
+ reloc->sym_ptr_ptr = & fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+
+ if (reloc->howto == (reloc_howto_type *) NULL)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ /* xgettext:c-format */
+ _("reloc %d not supported by object file format"),
+ (int) fixp->fx_r_type);
+
+ xfree (reloc);
+
+ return NULL;
+ }
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+ reloc->addend = fixp->fx_offset;
+ else
+ reloc->addend = fixp->fx_addnumber;
+
+ return reloc;
+}
+
+/* Assume everything will fit in two bytes, then expand as necessary. */
+int
+md_estimate_size_before_relax (fragp, seg)
+ fragS * fragp;
+ asection * seg;
+{
+ if (fragp->fr_subtype == 0)
+ fragp->fr_var = 4;
+ else if (fragp->fr_subtype == 2)
+ fragp->fr_var = 2;
+ else
+ abort ();
+ return 2;
+}
+
+long
+v850_pcrel_from_section (fixp, section)
+ fixS * fixp;
+ segT section;
+{
+ /* If the symbol is undefined, or in a section other than our own,
+ then let the linker figure it out. */
+ if (fixp->fx_addsy != (symbolS *) NULL
+ && (! S_IS_DEFINED (fixp->fx_addsy)
+ || (S_GET_SEGMENT (fixp->fx_addsy) != section)))
+ {
+ /* The symbol is undefined/not in our section.
+ Let the linker figure it out. */
+ return 0;
+ }
+
+ return fixp->fx_frag->fr_address + fixp->fx_where;
+}
+
+int
+md_apply_fix3 (fixp, valuep, seg)
+ fixS * fixp;
+ valueT * valuep;
+ segT seg;
+{
+ valueT value;
+ char * where;
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ fixp->fx_done = 0;
+ return 1;
+ }
+
+ if (fixp->fx_addsy == (symbolS *) NULL)
+ {
+ value = * valuep;
+ fixp->fx_done = 1;
+ }
+ else if (fixp->fx_pcrel)
+ value = * valuep;
+ else
+ {
+ value = fixp->fx_offset;
+ if (fixp->fx_subsy != (symbolS *) NULL)
+ {
+ if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
+ value -= S_GET_VALUE (fixp->fx_subsy);
+ else
+ {
+ /* We don't actually support subtracting a symbol. */
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("expression too complex"));
+ }
+ }
+ }
+
+ if ((int) fixp->fx_r_type >= (int) BFD_RELOC_UNUSED)
+ {
+ int opindex;
+ const struct v850_operand * operand;
+ unsigned long insn;
+
+ opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
+ operand = & v850_operands[ opindex ];
+
+ /* Fetch the instruction, insert the fully resolved operand
+ value, and stuff the instruction back again.
+
+ Note the instruction has been stored in little endian
+ format! */
+ where = fixp->fx_frag->fr_literal + fixp->fx_where;
+
+ insn = bfd_getl32 ((unsigned char *) where);
+ insn = v850_insert_operand (insn, operand, (offsetT) value,
+ fixp->fx_file, fixp->fx_line, NULL);
+ bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
+
+ if (fixp->fx_done)
+ {
+ /* Nothing else to do here. */
+ return 1;
+ }
+
+ /* Determine a BFD reloc value based on the operand information.
+ We are only prepared to turn a few of the operands into relocs. */
+
+ if (operand->bits == 22)
+ fixp->fx_r_type = BFD_RELOC_V850_22_PCREL;
+ else if (operand->bits == 9)
+ fixp->fx_r_type = BFD_RELOC_V850_9_PCREL;
+ else
+ {
+ /* fprintf (stderr, "bits: %d, insn: %x\n", operand->bits, insn); */
+
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("unresolved expression that must be resolved"));
+ fixp->fx_done = 1;
+ return 1;
+ }
+ }
+ else if (fixp->fx_done)
+ {
+ /* We still have to insert the value into memory! */
+ where = fixp->fx_frag->fr_literal + fixp->fx_where;
+
+ if (fixp->fx_size == 1)
+ * where = value & 0xff;
+ else if (fixp->fx_size == 2)
+ bfd_putl16 (value & 0xffff, (unsigned char *) where);
+ else if (fixp->fx_size == 4)
+ bfd_putl32 (value, (unsigned char *) where);
+ }
+
+ fixp->fx_addnumber = value;
+ return 1;
+}
+
+
+/* Parse a cons expression. We have to handle hi(), lo(), etc
+ on the v850. */
+void
+parse_cons_expression_v850 (exp)
+ expressionS *exp;
+{
+ /* See if there's a reloc prefix like hi() we have to handle. */
+ hold_cons_reloc = v850_reloc_prefix (NULL);
+
+ /* Do normal expression parsing. */
+ expression (exp);
+}
+
+/* Create a fixup for a cons expression. If parse_cons_expression_v850
+ found a reloc prefix, then we use that reloc, else we choose an
+ appropriate one based on the size of the expression. */
+void
+cons_fix_new_v850 (frag, where, size, exp)
+ fragS *frag;
+ int where;
+ int size;
+ expressionS *exp;
+{
+ if (hold_cons_reloc == BFD_RELOC_UNUSED)
+ {
+ if (size == 4)
+ hold_cons_reloc = BFD_RELOC_32;
+ if (size == 2)
+ hold_cons_reloc = BFD_RELOC_16;
+ if (size == 1)
+ hold_cons_reloc = BFD_RELOC_8;
+ }
+
+ if (exp != NULL)
+ fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
+ else
+ fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
+}
+boolean
+v850_fix_adjustable (fixP)
+ fixS *fixP;
+{
+
+ if (fixP->fx_addsy == NULL)
+ return 1;
+
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixP->fx_addsy))
+ return 0;
+ if (S_IS_WEAK (fixP->fx_addsy))
+ return 0;
+ /* Don't adjust function names */
+ if (S_IS_FUNCTION (fixP->fx_addsy))
+ return 0;
+
+ /* We need the symbol name for the VTABLE entries */
+ if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
+}
+
+int
+v850_force_relocation (fixp)
+ struct fix *fixp;
+{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
diff --git a/gas/config/tc-v850.h b/gas/config/tc-v850.h
new file mode 100644
index 00000000000..fad4d1cf850
--- /dev/null
+++ b/gas/config/tc-v850.h
@@ -0,0 +1,85 @@
+/* tc-v850.h -- Header file for tc-v850.c.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_V850
+
+#include <elf/v850.h>
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#ifndef BFD_ASSEMBLER
+ #error V850 support requires BFD_ASSEMBLER
+#endif
+
+/* The target BFD architecture. */
+#define TARGET_ARCH bfd_arch_v850
+
+/* The target BFD format. */
+#define TARGET_FORMAT "elf32-v850"
+
+#define MD_APPLY_FIX3
+#define md_operand(x)
+
+#define obj_fix_adjustable(fixP) v850_fix_adjustable(fixP)
+#define TC_FORCE_RELOCATION(fixp) v850_force_relocation(fixp)
+extern int v850_force_relocation PARAMS ((struct fix *));
+
+/* Permit temporary numeric labels. */
+#define LOCAL_LABELS_FB 1
+
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
+/* We don't need to handle .word strangely. */
+#define WORKING_DOT_WORD
+
+#define md_number_to_chars number_to_chars_littleendian
+
+/* We need to handle lo(), hi(), etc etc in .hword, .word, etc
+ directives, so we have to parse "cons" expressions ourselves. */
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_v850 (EXP)
+#define TC_CONS_FIX_NEW cons_fix_new_v850
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+
+/* This section must be in the small data area (pointed to by GP). */
+#define SHF_V850_GPREL 0x10000000
+/* This section must be in the tiny data area (pointed to by EP). */
+#define SHF_V850_EPREL 0x20000000
+/* This section must be in the zero data area (pointed to by R0). */
+#define SHF_V850_R0REL 0x40000000
+
+#define ELF_TC_SPECIAL_SECTIONS \
+ { ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
+ { ".rosdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_GPREL }, \
+ { ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
+ { ".scommon", SHT_V850_SCOMMON, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
+ { ".tdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
+ { ".tbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
+ { ".tcommon", SHT_V850_TCOMMON, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".zdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".rozdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_R0REL }, \
+ { ".zbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".zcommon", SHT_V850_ZCOMMON, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
+ { ".call_table_data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
+ { ".call_table_text", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR },
+
+#define MD_PCREL_FROM_SECTION(fixP,section) v850_pcrel_from_section (fixP, section)
+extern long v850_pcrel_from_section ();
diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c
new file mode 100644
index 00000000000..24e4a9b229a
--- /dev/null
+++ b/gas/config/tc-vax.c
@@ -0,0 +1,3242 @@
+/* tc-vax.c - vax-specific -
+ Copyright (C) 1987, 91, 92, 93, 94, 95, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+#include "vax-inst.h"
+#include "obstack.h" /* For FRAG_APPEND_1_CHAR macro in "frags.h" */
+
+/* These chars start a comment anywhere in a source file (except inside
+ another comment */
+const char comment_chars[] = "#";
+
+/* These chars only start a comment at the beginning of a line. */
+/* Note that for the VAX the are the same as comment_chars above. */
+const char line_comment_chars[] = "#";
+
+const char line_separator_chars[] = "";
+
+/* Chars that can be used to separate mant from exp in floating point nums */
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* as in 0f123.456 */
+/* or 0H1.234E-12 (see exp chars above) */
+const char FLT_CHARS[] = "dDfFgGhH";
+
+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
+ changed in read.c . Ideally it shouldn't have to know about it at all,
+ but nothing is ideal around here. */
+
+/* Hold details of an operand expression */
+static expressionS exp_of_operand[VIT_MAX_OPERANDS];
+static segT seg_of_operand[VIT_MAX_OPERANDS];
+
+/* A vax instruction after decoding. */
+static struct vit v;
+
+/* Hold details of big operands. */
+LITTLENUM_TYPE big_operand_bits[VIT_MAX_OPERANDS][SIZE_OF_LARGE_NUMBER];
+FLONUM_TYPE float_operand[VIT_MAX_OPERANDS];
+/* Above is made to point into big_operand_bits by md_begin(). */
+
+int flag_hash_long_names; /* -+ */
+int flag_one; /* -1 */
+int flag_show_after_trunc; /* -H */
+int flag_no_hash_mixed_case; /* -h NUM */
+
+/*
+ * For VAX, relative addresses of "just the right length" are easy.
+ * The branch displacement is always the last operand, even in
+ * synthetic instructions.
+ * For VAX, we encode the relax_substateTs (in e.g. fr_substate) as:
+ *
+ * 4 3 2 1 0 bit number
+ * ---/ /--+-------+-------+-------+-------+-------+
+ * | what state ? | how long ? |
+ * ---/ /--+-------+-------+-------+-------+-------+
+ *
+ * The "how long" bits are 00=byte, 01=word, 10=long.
+ * This is a Un*x convention.
+ * Not all lengths are legit for a given value of (what state).
+ * The "how long" refers merely to the displacement length.
+ * The address usually has some constant bytes in it as well.
+ *
+
+ groups for VAX address relaxing.
+
+ 1. "foo" pc-relative.
+ length of byte, word, long
+
+ 2a. J<cond> where <cond> is a simple flag test.
+ length of byte, word, long.
+ VAX opcodes are: (Hex)
+ bneq/bnequ 12
+ beql/beqlu 13
+ bgtr 14
+ bleq 15
+ bgeq 18
+ blss 19
+ bgtru 1a
+ blequ 1b
+ bvc 1c
+ bvs 1d
+ bgequ/bcc 1e
+ blssu/bcs 1f
+ Always, you complement 0th bit to reverse condition.
+ Always, 1-byte opcode, then 1-byte displacement.
+
+ 2b. J<cond> where cond tests a memory bit.
+ length of byte, word, long.
+ Vax opcodes are: (Hex)
+ bbs e0
+ bbc e1
+ bbss e2
+ bbcs e3
+ bbsc e4
+ bbcc e5
+ bbssi e6
+ bbcci e7
+ Always, you complement 0th bit to reverse condition.
+ Always, 1-byte opcde, longword-address, byte-address, 1-byte-displacement
+
+ 2c. J<cond> where cond tests low-order memory bit
+ length of byte,word,long.
+ Vax opcodes are: (Hex)
+ blbs e8
+ blbc e9
+ Always, you complement 0th bit to reverse condition.
+ Always, 1-byte opcode, longword-address, 1-byte displacement.
+
+ 3. Jbs/Jbr.
+ length of byte,word,long.
+ Vax opcodes are: (Hex)
+ bsbb 10
+ brb 11
+ These are like (2) but there is no condition to reverse.
+ Always, 1 byte opcode, then displacement/absolute.
+
+ 4a. JacbX
+ length of word, long.
+ Vax opcodes are: (Hex)
+ acbw 3d
+ acbf 4f
+ acbd 6f
+ abcb 9d
+ acbl f1
+ acbg 4ffd
+ acbh 6ffd
+ Always, we cannot reverse the sense of the branch; we have a word
+ displacement.
+ The double-byte op-codes don't hurt: we never want to modify the
+ opcode, so we don't care how many bytes are between the opcode and
+ the operand.
+
+ 4b. JXobXXX
+ length of long, long, byte.
+ Vax opcodes are: (Hex)
+ aoblss f2
+ aobleq f3
+ sobgeq f4
+ sobgtr f5
+ Always, we cannot reverse the sense of the branch; we have a byte
+ displacement.
+
+ The only time we need to modify the opcode is for class 2 instructions.
+ After relax() we may complement the lowest order bit of such instruction
+ to reverse sense of branch.
+
+ For class 2 instructions, we store context of "where is the opcode literal".
+ We can change an opcode's lowest order bit without breaking anything else.
+
+ We sometimes store context in the operand literal. This way we can figure out
+ after relax() what the original addressing mode was.
+ */
+
+/* These displacements are relative to the start address of the
+ displacement. The first letter is Byte, Word. 2nd letter is
+ Forward, Backward. */
+#define BF (1+ 127)
+#define BB (1+-128)
+#define WF (2+ 32767)
+#define WB (2+-32768)
+/* Dont need LF, LB because they always reach. [They are coded as 0.] */
+
+
+#define C(a,b) ENCODE_RELAX(a,b)
+/* This macro has no side-effects. */
+#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+
+const relax_typeS md_relax_table[] =
+{
+ {1, 1, 0, 0}, /* error sentinel 0,0 */
+ {1, 1, 0, 0}, /* unused 0,1 */
+ {1, 1, 0, 0}, /* unused 0,2 */
+ {1, 1, 0, 0}, /* unused 0,3 */
+ {BF + 1, BB + 1, 2, C (1, 1)},/* B^"foo" 1,0 */
+ {WF + 1, WB + 1, 3, C (1, 2)},/* W^"foo" 1,1 */
+ {0, 0, 5, 0}, /* L^"foo" 1,2 */
+ {1, 1, 0, 0}, /* unused 1,3 */
+ {BF, BB, 1, C (2, 1)}, /* b<cond> B^"foo" 2,0 */
+ {WF + 2, WB + 2, 4, C (2, 2)},/* br.+? brw X 2,1 */
+ {0, 0, 7, 0}, /* br.+? jmp X 2,2 */
+ {1, 1, 0, 0}, /* unused 2,3 */
+ {BF, BB, 1, C (3, 1)}, /* brb B^foo 3,0 */
+ {WF, WB, 2, C (3, 2)}, /* brw W^foo 3,1 */
+ {0, 0, 5, 0}, /* Jmp L^foo 3,2 */
+ {1, 1, 0, 0}, /* unused 3,3 */
+ {1, 1, 0, 0}, /* unused 4,0 */
+ {WF, WB, 2, C (4, 2)}, /* acb_ ^Wfoo 4,1 */
+ {0, 0, 10, 0}, /* acb_,br,jmp L^foo4,2 */
+ {1, 1, 0, 0}, /* unused 4,3 */
+ {BF, BB, 1, C (5, 1)}, /* Xob___,,foo 5,0 */
+ {WF + 4, WB + 4, 6, C (5, 2)},/* Xob.+2,brb.+3,brw5,1 */
+ {0, 0, 9, 0}, /* Xob.+2,brb.+6,jmp5,2 */
+};
+
+#undef C
+#undef BF
+#undef BB
+#undef WF
+#undef WB
+
+void float_cons ();
+
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"dfloat", float_cons, 'd'},
+ {"ffloat", float_cons, 'f'},
+ {"gfloat", float_cons, 'g'},
+ {"hfloat", float_cons, 'h'},
+ {0},
+};
+
+#define STATE_PC_RELATIVE (1)
+#define STATE_CONDITIONAL_BRANCH (2)
+#define STATE_ALWAYS_BRANCH (3) /* includes BSB... */
+#define STATE_COMPLEX_BRANCH (4)
+#define STATE_COMPLEX_HOP (5)
+
+#define STATE_BYTE (0)
+#define STATE_WORD (1)
+#define STATE_LONG (2)
+#define STATE_UNDF (3) /* Symbol undefined in pass1 */
+
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+int flonum_gen2vax PARAMS ((char format_letter, FLONUM_TYPE * f,
+ LITTLENUM_TYPE * words));
+static const char *vip_begin PARAMS ((int, const char *, const char *,
+ const char *));
+static void vip_op_defaults PARAMS ((const char *, const char *, const char *));
+static void vip_op PARAMS ((char *, struct vop *));
+static void vip PARAMS ((struct vit *, char *));
+
+void
+md_begin ()
+{
+ const char *errtxt;
+ FLONUM_TYPE *fP;
+ int i;
+
+ if ((errtxt = vip_begin (1, "$", "*", "`")) != 0)
+ {
+ as_fatal (_("VIP_BEGIN error:%s"), errtxt);
+ }
+
+ for (i = 0, fP = float_operand;
+ fP < float_operand + VIT_MAX_OPERANDS;
+ i++, fP++)
+ {
+ fP->low = &big_operand_bits[i][0];
+ fP->high = &big_operand_bits[i][SIZE_OF_LARGE_NUMBER - 1];
+ }
+}
+
+void
+md_number_to_chars (con, value, nbytes)
+ char con[];
+ valueT value;
+ int nbytes;
+{
+ number_to_chars_littleendian (con, value, nbytes);
+}
+
+/* Fix up some data or instructions after we find out the value of a symbol
+ that they reference. */
+
+void /* Knows about order of bytes in address. */
+md_apply_fix (fixP, value)
+ fixS *fixP;
+ long value;
+{
+ number_to_chars_littleendian (fixP->fx_where + fixP->fx_frag->fr_literal,
+ (valueT) value, fixP->fx_size);
+}
+
+long
+md_chars_to_number (con, nbytes)
+ unsigned char con[]; /* Low order byte 1st. */
+ int nbytes; /* Number of bytes in the input. */
+{
+ long retval;
+ for (retval = 0, con += nbytes - 1; nbytes--; con--)
+ {
+ retval <<= BITS_PER_CHAR;
+ retval |= *con;
+ }
+ return retval;
+}
+
+/* vax:md_assemble() emit frags for 1 instruction */
+
+void
+md_assemble (instruction_string)
+ char *instruction_string; /* A string: assemble 1 instruction. */
+{
+ /* Non-zero if operand expression's segment is not known yet. */
+ int is_undefined;
+
+ int length_code;
+ char *p;
+ /* An operand. Scans all operands. */
+ struct vop *operandP;
+ char *save_input_line_pointer;
+ /* What used to live after an expression. */
+ char c_save;
+ /* 1: instruction_string bad for all passes. */
+ int goofed;
+ /* Points to slot just after last operand. */
+ struct vop *end_operandP;
+ /* Points to expression values for this operand. */
+ expressionS *expP;
+ segT *segP;
+
+ /* These refer to an instruction operand expression. */
+ /* Target segment of the address. */
+ segT to_seg;
+ valueT this_add_number;
+ /* Positive (minuend) symbol. */
+ struct symbol *this_add_symbol;
+ /* As a number. */
+ long opcode_as_number;
+ /* Least significant byte 1st. */
+ char *opcode_as_chars;
+ /* As an array of characters. */
+ /* Least significant byte 1st */
+ char *opcode_low_byteP;
+ /* length (bytes) meant by vop_short. */
+ int length;
+ /* 0, or 1 if '@' is in addressing mode. */
+ int at;
+ /* From vop_nbytes: vax_operand_width (in bytes) */
+ int nbytes;
+ FLONUM_TYPE *floatP;
+ LITTLENUM_TYPE literal_float[8];
+ /* Big enough for any floating point literal. */
+
+ vip (&v, instruction_string);
+
+ /*
+ * Now we try to find as many as_warn()s as we can. If we do any as_warn()s
+ * then goofed=1. Notice that we don't make any frags yet.
+ * Should goofed be 1, then this instruction will wedge in any pass,
+ * and we can safely flush it, without causing interpass symbol phase
+ * errors. That is, without changing label values in different passes.
+ */
+ if ((goofed = (*v.vit_error)) != 0)
+ {
+ as_warn (_("Ignoring statement due to \"%s\""), v.vit_error);
+ }
+ /*
+ * We need to use expression() and friends, which require us to diddle
+ * input_line_pointer. So we save it and restore it later.
+ */
+ save_input_line_pointer = input_line_pointer;
+ for (operandP = v.vit_operand,
+ expP = exp_of_operand,
+ segP = seg_of_operand,
+ floatP = float_operand,
+ end_operandP = v.vit_operand + v.vit_operands;
+
+ operandP < end_operandP;
+
+ operandP++, expP++, segP++, floatP++)
+ { /* for each operand */
+ if (operandP->vop_error)
+ {
+ as_warn (_("Ignoring statement because \"%s\""), operandP->vop_error);
+ goofed = 1;
+ }
+ else
+ {
+ /* statement has no syntax goofs: lets sniff the expression */
+ int can_be_short = 0; /* 1 if a bignum can be reduced to a short literal. */
+
+ input_line_pointer = operandP->vop_expr_begin;
+ c_save = operandP->vop_expr_end[1];
+ operandP->vop_expr_end[1] = '\0';
+ /* If to_seg == SEG_PASS1, expression() will have set need_pass_2 = 1. */
+ *segP = expression (expP);
+ switch (expP->X_op)
+ {
+ case O_absent:
+ /* for BSD4.2 compatibility, missing expression is absolute 0 */
+ expP->X_op = O_constant;
+ expP->X_add_number = 0;
+ /* For SEG_ABSOLUTE, we shouldn't need to set X_op_symbol,
+ X_add_symbol to any particular value. But, we will program
+ defensively. Since this situation occurs rarely so it costs
+ us little to do, and stops Dean worrying about the origin of
+ random bits in expressionS's. */
+ expP->X_add_symbol = NULL;
+ expP->X_op_symbol = NULL;
+ break;
+
+ case O_symbol:
+ case O_constant:
+ break;
+
+ default:
+ /*
+ * Major bug. We can't handle the case of a
+ * SEG_OP expression in a VIT_OPCODE_SYNTHETIC
+ * variable-length instruction.
+ * We don't have a frag type that is smart enough to
+ * relax a SEG_OP, and so we just force all
+ * SEG_OPs to behave like SEG_PASS1s.
+ * Clearly, if there is a demand we can invent a new or
+ * modified frag type and then coding up a frag for this
+ * case will be easy. SEG_OP was invented for the
+ * .words after a CASE opcode, and was never intended for
+ * instruction operands.
+ */
+ need_pass_2 = 1;
+ as_warn (_("Can't relocate expression"));
+ break;
+
+ case O_big:
+ /* Preserve the bits. */
+ if (expP->X_add_number > 0)
+ {
+ bignum_copy (generic_bignum, expP->X_add_number,
+ floatP->low, SIZE_OF_LARGE_NUMBER);
+ }
+ else
+ {
+ know (expP->X_add_number < 0);
+ flonum_copy (&generic_floating_point_number,
+ floatP);
+ if (strchr ("s i", operandP->vop_short))
+ {
+ /* Could possibly become S^# */
+ flonum_gen2vax (-expP->X_add_number, floatP, literal_float);
+ switch (-expP->X_add_number)
+ {
+ case 'f':
+ can_be_short =
+ (literal_float[0] & 0xFC0F) == 0x4000
+ && literal_float[1] == 0;
+ break;
+
+ case 'd':
+ can_be_short =
+ (literal_float[0] & 0xFC0F) == 0x4000
+ && literal_float[1] == 0
+ && literal_float[2] == 0
+ && literal_float[3] == 0;
+ break;
+
+ case 'g':
+ can_be_short =
+ (literal_float[0] & 0xFF81) == 0x4000
+ && literal_float[1] == 0
+ && literal_float[2] == 0
+ && literal_float[3] == 0;
+ break;
+
+ case 'h':
+ can_be_short = ((literal_float[0] & 0xFFF8) == 0x4000
+ && (literal_float[1] & 0xE000) == 0
+ && literal_float[2] == 0
+ && literal_float[3] == 0
+ && literal_float[4] == 0
+ && literal_float[5] == 0
+ && literal_float[6] == 0
+ && literal_float[7] == 0);
+ break;
+
+ default:
+ BAD_CASE (-expP->X_add_number);
+ break;
+ } /* switch (float type) */
+ } /* if (could want to become S^#...) */
+ } /* bignum or flonum ? */
+
+ if (operandP->vop_short == 's'
+ || operandP->vop_short == 'i'
+ || (operandP->vop_short == ' '
+ && operandP->vop_reg == 0xF
+ && (operandP->vop_mode & 0xE) == 0x8))
+ {
+ /* Saw a '#'. */
+ if (operandP->vop_short == ' ')
+ {
+ /* We must chose S^ or I^. */
+ if (expP->X_add_number > 0)
+ {
+ /* Bignum: Short literal impossible. */
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC. */
+ }
+ else
+ {
+ /* Flonum: Try to do it. */
+ if (can_be_short)
+ {
+ operandP->vop_short = 's';
+ operandP->vop_mode = 0;
+ operandP->vop_ndx = -1;
+ operandP->vop_reg = -1;
+ expP->X_op = O_constant;
+ }
+ else
+ {
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC */
+ }
+ } /* bignum or flonum ? */
+ } /* if #, but no S^ or I^ seen. */
+ /* No more ' ' case: either 's' or 'i'. */
+ if (operandP->vop_short == 's')
+ {
+ /* Wants to be a short literal. */
+ if (expP->X_add_number > 0)
+ {
+ as_warn (_("Bignum not permitted in short literal. Immediate mode assumed."));
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC. */
+ }
+ else
+ {
+ if (!can_be_short)
+ {
+ as_warn (_("Can't do flonum short literal: immediate mode used."));
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF; /* VAX PC. */
+ }
+ else
+ { /* Encode short literal now. */
+ int temp = 0;
+
+ switch (-expP->X_add_number)
+ {
+ case 'f':
+ case 'd':
+ temp = literal_float[0] >> 4;
+ break;
+
+ case 'g':
+ temp = literal_float[0] >> 1;
+ break;
+
+ case 'h':
+ temp = ((literal_float[0] << 3) & 070)
+ | ((literal_float[1] >> 13) & 07);
+ break;
+
+ default:
+ BAD_CASE (-expP->X_add_number);
+ break;
+ }
+
+ floatP->low[0] = temp & 077;
+ floatP->low[1] = 0;
+ } /* if can be short literal float */
+ } /* flonum or bignum ? */
+ }
+ else
+ { /* I^# seen: set it up if float. */
+ if (expP->X_add_number < 0)
+ {
+ memcpy (floatP->low, literal_float, sizeof (literal_float));
+ }
+ } /* if S^# seen. */
+ }
+ else
+ {
+ as_warn (_("A bignum/flonum may not be a displacement: 0x%lx used"),
+ (expP->X_add_number = 0x80000000L));
+ /* Chosen so luser gets the most offset bits to patch later. */
+ }
+ expP->X_add_number = floatP->low[0]
+ | ((LITTLENUM_MASK & (floatP->low[1])) << LITTLENUM_NUMBER_OF_BITS);
+ /*
+ * For the O_big case we have:
+ * If vop_short == 's' then a short floating literal is in the
+ * lowest 6 bits of floatP -> low [0], which is
+ * big_operand_bits [---] [0].
+ * If vop_short == 'i' then the appropriate number of elements
+ * of big_operand_bits [---] [...] are set up with the correct
+ * bits.
+ * Also, just in case width is byte word or long, we copy the lowest
+ * 32 bits of the number to X_add_number.
+ */
+ break;
+ }
+ if (input_line_pointer != operandP->vop_expr_end + 1)
+ {
+ as_warn ("Junk at end of expression \"%s\"", input_line_pointer);
+ goofed = 1;
+ }
+ operandP->vop_expr_end[1] = c_save;
+ }
+ } /* for(each operand) */
+
+ input_line_pointer = save_input_line_pointer;
+
+ if (need_pass_2 || goofed)
+ {
+ return;
+ }
+
+
+ /* Emit op-code. */
+ /* Remember where it is, in case we want to modify the op-code later. */
+ opcode_low_byteP = frag_more (v.vit_opcode_nbytes);
+ memcpy (opcode_low_byteP, v.vit_opcode, v.vit_opcode_nbytes);
+ opcode_as_number = md_chars_to_number (opcode_as_chars = v.vit_opcode, 4);
+ for (operandP = v.vit_operand,
+ expP = exp_of_operand,
+ segP = seg_of_operand,
+ floatP = float_operand,
+ end_operandP = v.vit_operand + v.vit_operands;
+
+ operandP < end_operandP;
+
+ operandP++,
+ floatP++,
+ segP++,
+ expP++)
+ {
+ if (operandP->vop_ndx >= 0)
+ {
+ /* indexed addressing byte */
+ /* Legality of indexed mode already checked: it is OK */
+ FRAG_APPEND_1_CHAR (0x40 + operandP->vop_ndx);
+ } /* if(vop_ndx>=0) */
+
+ /* Here to make main operand frag(s). */
+ this_add_number = expP->X_add_number;
+ this_add_symbol = expP->X_add_symbol;
+ to_seg = *segP;
+ is_undefined = (to_seg == SEG_UNKNOWN);
+ at = operandP->vop_mode & 1;
+ length = (operandP->vop_short == 'b'
+ ? 1 : (operandP->vop_short == 'w'
+ ? 2 : (operandP->vop_short == 'l'
+ ? 4 : 0)));
+ nbytes = operandP->vop_nbytes;
+ if (operandP->vop_access == 'b')
+ {
+ if (to_seg == now_seg || is_undefined)
+ {
+ /* If is_undefined, then it might BECOME now_seg. */
+ if (nbytes)
+ {
+ p = frag_more (nbytes);
+ fix_new (frag_now, p - frag_now->fr_literal, nbytes,
+ this_add_symbol, this_add_number, 1, NO_RELOC);
+ }
+ else
+ { /* to_seg==now_seg || to_seg == SEG_UNKNOWN */
+ /* nbytes==0 */
+ length_code = is_undefined ? STATE_UNDF : STATE_BYTE;
+ if (opcode_as_number & VIT_OPCODE_SPECIAL)
+ {
+ if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
+ {
+ /* br or jsb */
+ frag_var (rs_machine_dependent, 5, 1,
+ ENCODE_RELAX (STATE_ALWAYS_BRANCH, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ else
+ {
+ if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
+ {
+ length_code = STATE_WORD;
+ /* JF: There is no state_byte for this one! */
+ frag_var (rs_machine_dependent, 10, 2,
+ ENCODE_RELAX (STATE_COMPLEX_BRANCH, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
+ frag_var (rs_machine_dependent, 9, 1,
+ ENCODE_RELAX (STATE_COMPLEX_HOP, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ }
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);
+ frag_var (rs_machine_dependent, 7, 1,
+ ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, length_code),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ }
+ }
+ }
+ else
+ {
+ /* to_seg != now_seg && to_seg != SEG_UNKNOWN */
+ /*
+ * --- SEG FLOAT MAY APPEAR HERE ----
+ */
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ if (nbytes)
+ {
+ know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
+ p = frag_more (nbytes);
+ /* Conventional relocation. */
+ fix_new (frag_now, p - frag_now->fr_literal,
+ nbytes, &abs_symbol, this_add_number,
+ 1, NO_RELOC);
+ }
+ else
+ {
+ know (opcode_as_number & VIT_OPCODE_SYNTHETIC);
+ if (opcode_as_number & VIT_OPCODE_SPECIAL)
+ {
+ if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
+ {
+ /* br or jsb */
+ *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;
+ know (opcode_as_chars[1] == 0);
+ p = frag_more (5);
+ p[0] = VAX_ABSOLUTE_MODE; /* @#... */
+ md_number_to_chars (p + 1, this_add_number, 4);
+ /* Now (eg) JMP @#foo or JSB @#foo. */
+ }
+ else
+ {
+ if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
+ {
+ p = frag_more (10);
+ p[0] = 2;
+ p[1] = 0;
+ p[2] = VAX_BRB;
+ p[3] = 6;
+ p[4] = VAX_JMP;
+ p[5] = VAX_ABSOLUTE_MODE; /* @#... */
+ md_number_to_chars (p + 6, this_add_number, 4);
+ /*
+ * Now (eg) ACBx 1f
+ * BRB 2f
+ * 1: JMP @#foo
+ * 2:
+ */
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
+ p = frag_more (9);
+ p[0] = 2;
+ p[1] = VAX_BRB;
+ p[2] = 6;
+ p[3] = VAX_JMP;
+ p[4] = VAX_PC_RELATIVE_MODE + 1; /* @#... */
+ md_number_to_chars (p + 5, this_add_number, 4);
+ /*
+ * Now (eg) xOBxxx 1f
+ * BRB 2f
+ * 1: JMP @#foo
+ * 2:
+ */
+ }
+ }
+ }
+ else
+ {
+ /* b<cond> */
+ *opcode_low_byteP ^= 1;
+ /* To reverse the condition in a VAX branch,
+ complement the lowest order bit. */
+ p = frag_more (7);
+ p[0] = 6;
+ p[1] = VAX_JMP;
+ p[2] = VAX_ABSOLUTE_MODE; /* @#... */
+ md_number_to_chars (p + 3, this_add_number, 4);
+ /*
+ * Now (eg) BLEQ 1f
+ * JMP @#foo
+ * 1:
+ */
+ }
+ }
+ }
+ else
+ {
+ /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */
+ if (nbytes > 0)
+ {
+ /* Pc-relative. Conventional relocation. */
+ know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
+ p = frag_more (nbytes);
+ fix_new (frag_now, p - frag_now->fr_literal,
+ nbytes, &abs_symbol, this_add_number,
+ 1, NO_RELOC);
+ }
+ else
+ {
+ know (opcode_as_number & VIT_OPCODE_SYNTHETIC);
+ if (opcode_as_number & VIT_OPCODE_SPECIAL)
+ {
+ if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
+ {
+ /* br or jsb */
+ know (opcode_as_chars[1] == 0);
+ *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;
+ p = frag_more (5);
+ p[0] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now,
+ p + 1 - frag_now->fr_literal, 4,
+ this_add_symbol,
+ this_add_number, 1, NO_RELOC);
+ /* Now eg JMP foo or JSB foo. */
+ }
+ else
+ {
+ if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
+ {
+ p = frag_more (10);
+ p[0] = 0;
+ p[1] = 2;
+ p[2] = VAX_BRB;
+ p[3] = 6;
+ p[4] = VAX_JMP;
+ p[5] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now,
+ p + 6 - frag_now->fr_literal, 4,
+ this_add_symbol,
+ this_add_number, 1, NO_RELOC);
+ /*
+ * Now (eg) ACBx 1f
+ * BRB 2f
+ * 1: JMP foo
+ * 2:
+ */
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
+ p = frag_more (10);
+ p[0] = 2;
+ p[1] = VAX_BRB;
+ p[2] = 6;
+ p[3] = VAX_JMP;
+ p[4] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now,
+ p + 5 - frag_now->fr_literal,
+ 4, this_add_symbol,
+ this_add_number, 1, NO_RELOC);
+ /*
+ * Now (eg) xOBxxx 1f
+ * BRB 2f
+ * 1: JMP foo
+ * 2:
+ */
+ }
+ }
+ }
+ else
+ {
+ know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);
+ *opcode_low_byteP ^= 1; /* Reverse branch condition. */
+ p = frag_more (7);
+ p[0] = 6;
+ p[1] = VAX_JMP;
+ p[2] = VAX_PC_RELATIVE_MODE;
+ fix_new (frag_now, p + 3 - frag_now->fr_literal,
+ 4, this_add_symbol,
+ this_add_number, 1, NO_RELOC);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ know (operandP->vop_access != 'b'); /* So it is ordinary operand. */
+ know (operandP->vop_access != ' '); /* ' ' target-independent: elsewhere. */
+ know (operandP->vop_access == 'a'
+ || operandP->vop_access == 'm'
+ || operandP->vop_access == 'r'
+ || operandP->vop_access == 'v'
+ || operandP->vop_access == 'w');
+ if (operandP->vop_short == 's')
+ {
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ if (this_add_number >= 64)
+ {
+ as_warn (_("Short literal overflow(%ld.), immediate mode assumed."),
+ (long) this_add_number);
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF;
+ }
+ }
+ else
+ {
+ as_warn (_("Forced short literal to immediate mode. now_seg=%s to_seg=%s"),
+ segment_name (now_seg), segment_name (to_seg));
+ operandP->vop_short = 'i';
+ operandP->vop_mode = 8;
+ operandP->vop_reg = 0xF;
+ }
+ }
+ if (operandP->vop_reg >= 0 && (operandP->vop_mode < 8
+ || (operandP->vop_reg != 0xF && operandP->vop_mode < 10)))
+ {
+ /* One byte operand. */
+ know (operandP->vop_mode > 3);
+ FRAG_APPEND_1_CHAR (operandP->vop_mode << 4 | operandP->vop_reg);
+ /* All 1-bytes except S^# happen here. */
+ }
+ else
+ {
+ /* {@}{q^}foo{(Rn)} or S^#foo */
+ if (operandP->vop_reg == -1 && operandP->vop_short != 's')
+ {
+ /* "{@}{q^}foo" */
+ if (to_seg == now_seg)
+ {
+ if (length == 0)
+ {
+ know (operandP->vop_short == ' ');
+ p = frag_var (rs_machine_dependent, 10, 2,
+ ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE),
+ this_add_symbol, this_add_number,
+ opcode_low_byteP);
+ know (operandP->vop_mode == 10 + at);
+ *p = at << 4;
+ /* At is the only context we need to carry
+ to other side of relax() process. Must
+ be in the correct bit position of VAX
+ operand spec. byte. */
+ }
+ else
+ {
+ know (length);
+ know (operandP->vop_short != ' ');
+ p = frag_more (length + 1);
+ p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);
+ fix_new (frag_now, p + 1 - frag_now->fr_literal,
+ length, this_add_symbol,
+ this_add_number, 1, NO_RELOC);
+ }
+ }
+ else
+ { /* to_seg != now_seg */
+ if (this_add_symbol == NULL)
+ {
+ know (to_seg == SEG_ABSOLUTE);
+ /* Do @#foo: simpler relocation than foo-.(pc) anyway. */
+ p = frag_more (5);
+ p[0] = VAX_ABSOLUTE_MODE; /* @#... */
+ md_number_to_chars (p + 1, this_add_number, 4);
+ if (length && length != 4)
+ {
+ as_warn (_("Length specification ignored. Address mode 9F used"));
+ }
+ }
+ else
+ {
+ /* {@}{q^}other_seg */
+ know ((length == 0 && operandP->vop_short == ' ')
+ || (length > 0 && operandP->vop_short != ' '));
+ if (is_undefined)
+ {
+ /*
+ * We have a SEG_UNKNOWN symbol. It might
+ * turn out to be in the same segment as
+ * the instruction, permitting relaxation.
+ */
+ p = frag_var (rs_machine_dependent, 5, 2,
+ ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
+ this_add_symbol, this_add_number,
+ 0);
+ p[0] = at << 4;
+ }
+ else
+ {
+ if (length == 0)
+ {
+ know (operandP->vop_short == ' ');
+ length = 4; /* Longest possible. */
+ }
+ p = frag_more (length + 1);
+ p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);
+ md_number_to_chars (p + 1, this_add_number, length);
+ fix_new (frag_now,
+ p + 1 - frag_now->fr_literal,
+ length, this_add_symbol,
+ this_add_number, 1, NO_RELOC);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* {@}{q^}foo(Rn) or S^# or I^# or # */
+ if (operandP->vop_mode < 0xA)
+ {
+ /* # or S^# or I^# */
+ if (operandP->vop_access == 'v'
+ || operandP->vop_access == 'a')
+ {
+ if (operandP->vop_access == 'v')
+ as_warn (_("Invalid operand: immediate value used as base address."));
+ else
+ as_warn (_("Invalid operand: immediate value used as address."));
+ /* gcc 2.6.3 is known to generate these in at least
+ one case. */
+ }
+ if (length == 0
+ && to_seg == SEG_ABSOLUTE && (expP->X_op != O_big)
+ && operandP->vop_mode == 8 /* No '@'. */
+ && this_add_number < 64)
+ {
+ operandP->vop_short = 's';
+ }
+ if (operandP->vop_short == 's')
+ {
+ FRAG_APPEND_1_CHAR (this_add_number);
+ }
+ else
+ {
+ /* I^#... */
+ know (nbytes);
+ p = frag_more (nbytes + 1);
+ know (operandP->vop_reg == 0xF);
+ p[0] = (operandP->vop_mode << 4) | 0xF;
+ if ((to_seg == SEG_ABSOLUTE) && (expP->X_op != O_big))
+ {
+ /*
+ * If nbytes > 4, then we are scrod. We
+ * don't know if the high order bytes
+ * are to be 0xFF or 0x00. BSD4.2 & RMS
+ * say use 0x00. OK --- but this
+ * assembler needs ANOTHER rewrite to
+ * cope properly with this bug. */
+ md_number_to_chars (p + 1, this_add_number, min (4, nbytes));
+ if (nbytes > 4)
+ {
+ memset (p + 5, '\0', nbytes - 4);
+ }
+ }
+ else
+ {
+ if (expP->X_op == O_big)
+ {
+ /*
+ * Problem here is to get the bytes
+ * in the right order. We stored
+ * our constant as LITTLENUMs, not
+ * bytes. */
+ LITTLENUM_TYPE *lP;
+
+ lP = floatP->low;
+ if (nbytes & 1)
+ {
+ know (nbytes == 1);
+ p[1] = *lP;
+ }
+ else
+ {
+ for (p++; nbytes; nbytes -= 2, p += 2, lP++)
+ {
+ md_number_to_chars (p, *lP, 2);
+ }
+ }
+ }
+ else
+ {
+ fix_new (frag_now, p + 1 - frag_now->fr_literal,
+ nbytes, this_add_symbol,
+ this_add_number, 0, NO_RELOC);
+ }
+ }
+ }
+ }
+ else
+ { /* {@}{q^}foo(Rn) */
+ know ((length == 0 && operandP->vop_short == ' ')
+ || (length > 0 && operandP->vop_short != ' '));
+ if (length == 0)
+ {
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ long test;
+
+ test = this_add_number;
+
+ if (test < 0)
+ test = ~test;
+
+ length = test & 0xffff8000 ? 4
+ : test & 0xffffff80 ? 2
+ : 1;
+ }
+ else
+ {
+ length = 4;
+ }
+ }
+ p = frag_more (1 + length);
+ know (operandP->vop_reg >= 0);
+ p[0] = operandP->vop_reg
+ | ((at | "?\12\14?\16"[length]) << 4);
+ if (to_seg == SEG_ABSOLUTE)
+ {
+ md_number_to_chars (p + 1, this_add_number, length);
+ }
+ else
+ {
+ fix_new (frag_now, p + 1 - frag_now->fr_literal,
+ length, this_add_symbol,
+ this_add_number, 0, NO_RELOC);
+ }
+ }
+ }
+ } /* if(single-byte-operand) */
+ }
+ } /* for(operandP) */
+} /* vax_assemble() */
+
+/*
+ * md_estimate_size_before_relax()
+ *
+ * Called just before relax().
+ * Any symbol that is now undefined will not become defined.
+ * Return the correct fr_subtype in the frag.
+ * Return the initial "guess for fr_var" to caller.
+ * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
+ * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
+ * Although it may not be explicit in the frag, pretend fr_var starts with a
+ * 0 value.
+ */
+int
+md_estimate_size_before_relax (fragP, segment)
+ fragS *fragP;
+ segT segment;
+{
+ char *p;
+ int old_fr_fix;
+
+ old_fr_fix = fragP->fr_fix;
+ switch (fragP->fr_subtype)
+ {
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ { /* A relaxable case. */
+ fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */
+ fragP->fr_fix += 1 + 4;
+ fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *fragP->fr_opcode ^= 1; /* Reverse sense of branch. */
+ p[0] = 6;
+ p[1] = VAX_JMP;
+ p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
+ fragP->fr_fix += 1 + 1 + 1 + 4;
+ fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ p[0] = 2;
+ p[1] = 0;
+ p[2] = VAX_BRB;
+ p[3] = 6;
+ p[4] = VAX_JMP;
+ p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
+ fragP->fr_fix += 2 + 2 + 1 + 1 + 4;
+ fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ p[0] = 2;
+ p[1] = VAX_BRB;
+ p[2] = 6;
+ p[3] = VAX_JMP;
+ p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
+ fragP->fr_fix += 1 + 2 + 1 + 1 + 4;
+ fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ frag_wane (fragP);
+ }
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
+ {
+ fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
+ }
+ else
+ {
+ p = fragP->fr_literal + old_fr_fix;
+ *fragP->fr_opcode += VAX_WIDEN_LONG;
+ p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
+ fragP->fr_fix += 1 + 4;
+ fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, NO_RELOC);
+ frag_wane (fragP);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
+} /* md_estimate_size_before_relax() */
+
+/*
+ * md_convert_frag();
+ *
+ * Called after relax() is finished.
+ * In: Address of frag.
+ * fr_type == rs_machine_dependent.
+ * fr_subtype is what the address relaxed to.
+ *
+ * Out: Any fixSs and constants are set up.
+ * Caller will turn frag into a ".space 0".
+ */
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ char *addressP; /* -> _var to change. */
+ char *opcodeP; /* -> opcode char(s) to change. */
+ short int length_code; /* 2=long 1=word 0=byte */
+ short int extension = 0; /* Size of relaxed address. */
+ /* Added to fr_fix: incl. ALL var chars. */
+ symbolS *symbolP;
+ long where;
+ long address_of_var;
+ /* Where, in file space, is _var of *fragP? */
+ long target_address = 0;
+ /* Where, in file space, does addr point? */
+
+ know (fragP->fr_type == rs_machine_dependent);
+ length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */
+ know (length_code >= 0 && length_code < 3);
+ where = fragP->fr_fix;
+ addressP = fragP->fr_literal + where;
+ opcodeP = fragP->fr_opcode;
+ symbolP = fragP->fr_symbol;
+ know (symbolP);
+ target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;
+ address_of_var = fragP->fr_address + where;
+
+ switch (fragP->fr_subtype)
+ {
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
+ know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
+ addressP[0] |= 0xAF; /* Byte displacement. */
+ addressP[1] = target_address - (address_of_var + 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
+ know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
+ addressP[0] |= 0xCF; /* Word displacement. */
+ md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2);
+ extension = 3;
+ break;
+
+ case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
+ know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
+ addressP[0] |= 0xEF; /* Long word displacement. */
+ md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
+ extension = 5;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
+ addressP[0] = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
+ opcodeP[0] ^= 1; /* Reverse sense of test. */
+ addressP[0] = 3;
+ addressP[1] = VAX_BRB + VAX_WIDEN_WORD;
+ md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2);
+ extension = 4;
+ break;
+
+ case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):
+ opcodeP[0] ^= 1; /* Reverse sense of test. */
+ addressP[0] = 6;
+ addressP[1] = VAX_JMP;
+ addressP[2] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 3, target_address, 4);
+ extension = 7;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
+ addressP[0] = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
+ opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
+ opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */
+ addressP[0] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
+ extension = 5;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD):
+ md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
+ extension = 2;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_LONG):
+ addressP[0] = 2;
+ addressP[1] = 0;
+ addressP[2] = VAX_BRB;
+ addressP[3] = 6;
+ addressP[4] = VAX_JMP;
+ addressP[5] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 6, target_address, 4);
+ extension = 10;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE):
+ addressP[0] = target_address - (address_of_var + 1);
+ extension = 1;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_WORD):
+ addressP[0] = 2;
+ addressP[1] = VAX_BRB;
+ addressP[2] = 3;
+ addressP[3] = VAX_BRW;
+ md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2);
+ extension = 6;
+ break;
+
+ case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_LONG):
+ addressP[0] = 2;
+ addressP[1] = VAX_BRB;
+ addressP[2] = 6;
+ addressP[3] = VAX_JMP;
+ addressP[4] = VAX_PC_RELATIVE_MODE;
+ md_number_to_chars (addressP + 5, target_address, 4);
+ extension = 9;
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_subtype);
+ break;
+ }
+ fragP->fr_fix += extension;
+} /* md_convert_frag() */
+
+/* Translate internal format of relocation info into target format.
+
+ On vax: first 4 bytes are normal unsigned long, next three bytes
+ are symbolnum, least sig. byte first. Last byte is broken up with
+ the upper nibble as nuthin, bit 3 as extern, bits 2 & 1 as length, and
+ bit 0 as pcrel. */
+#ifdef comment
+void
+md_ri_to_chars (the_bytes, ri)
+ char *the_bytes;
+ struct reloc_info_generic ri;
+{
+ /* this is easy */
+ md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
+ /* now the fun stuff */
+ the_bytes[6] = (ri.r_symbolnum >> 16) & 0x0ff;
+ the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
+ the_bytes[4] = ri.r_symbolnum & 0x0ff;
+ the_bytes[7] = (((ri.r_extern << 3) & 0x08) | ((ri.r_length << 1) & 0x06) |
+ ((ri.r_pcrel << 0) & 0x01)) & 0x0F;
+}
+
+#endif /* comment */
+
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
+{
+ /*
+ * In: length of relocation (or of address) in chars: 1, 2 or 4.
+ * Out: GNU LD relocation length code: 0, 1, or 2.
+ */
+
+ static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
+ long r_symbolnum;
+
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ where[6] = (r_symbolnum >> 16) & 0x0ff;
+ where[5] = (r_symbolnum >> 8) & 0x0ff;
+ where[4] = r_symbolnum & 0x0ff;
+ where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
+ | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
+ | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
+}
+
+/*
+ * BUGS, GRIPES, APOLOGIA, etc.
+ *
+ * The opcode table 'votstrs' needs to be sorted on opcode frequency.
+ * That is, AFTER we hash it with hash_...(), we want most-used opcodes
+ * to come out of the hash table faster.
+ *
+ * I am sorry to inflict yet another VAX assembler on the world, but
+ * RMS says we must do everything from scratch, to prevent pin-heads
+ * restricting this software.
+ */
+
+/*
+ * This is a vaguely modular set of routines in C to parse VAX
+ * assembly code using DEC mnemonics. It is NOT un*x specific.
+ *
+ * The idea here is that the assembler has taken care of all:
+ * labels
+ * macros
+ * listing
+ * pseudo-ops
+ * line continuation
+ * comments
+ * condensing any whitespace down to exactly one space
+ * and all we have to do is parse 1 line into a vax instruction
+ * partially formed. We will accept a line, and deliver:
+ * an error message (hopefully empty)
+ * a skeleton VAX instruction (tree structure)
+ * textual pointers to all the operand expressions
+ * a warning message that notes a silly operand (hopefully empty)
+ */
+
+/*
+ * E D I T H I S T O R Y
+ *
+ * 17may86 Dean Elsner. Bug if line ends immediately after opcode.
+ * 30apr86 Dean Elsner. New vip_op() uses arg block so change call.
+ * 6jan86 Dean Elsner. Crock vip_begin() to call vip_op_defaults().
+ * 2jan86 Dean Elsner. Invent synthetic opcodes.
+ * Widen vax_opcodeT to 32 bits. Use a bit for VIT_OPCODE_SYNTHETIC,
+ * which means this is not a real opcode, it is like a macro; it will
+ * be relax()ed into 1 or more instructions.
+ * Use another bit for VIT_OPCODE_SPECIAL if the op-code is not optimised
+ * like a regular branch instruction. Option added to vip_begin():
+ * exclude synthetic opcodes. Invent synthetic_votstrs[].
+ * 31dec85 Dean Elsner. Invent vit_opcode_nbytes.
+ * Also make vit_opcode into a char[]. We now have n-byte vax opcodes,
+ * so caller's don't have to know the difference between a 1-byte & a
+ * 2-byte op-code. Still need vax_opcodeT concept, so we know how
+ * big an object must be to hold an op.code.
+ * 30dec85 Dean Elsner. Widen typedef vax_opcodeT in "vax-inst.h"
+ * because vax opcodes may be 16 bits. Our crufty C compiler was
+ * happily initialising 8-bit vot_codes with 16-bit numbers!
+ * (Wouldn't the 'phone company like to compress data so easily!)
+ * 29dec85 Dean Elsner. New static table vax_operand_width_size[].
+ * Invented so we know hw many bytes a "I^#42" needs in its immediate
+ * operand. Revised struct vop in "vax-inst.h": explicitly include
+ * byte length of each operand, and it's letter-code datum type.
+ * 17nov85 Dean Elsner. Name Change.
+ * Due to ar(1) truncating names, we learned the hard way that
+ * "vax-inst-parse.c" -> "vax-inst-parse." dropping the "o" off
+ * the archived object name. SO... we shortened the name of this
+ * source file, and changed the makefile.
+ */
+
+/* handle of the OPCODE hash table */
+static struct hash_control *op_hash;
+
+/*
+ * In: 1 character, from "bdfghloqpw" being the data-type of an operand
+ * of a vax instruction.
+ *
+ * Out: the length of an operand of that type, in bytes.
+ * Special branch operands types "-?!" have length 0.
+ */
+
+static const short int vax_operand_width_size[256] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 8, 0, 4, 8, 16, 0, 0, 0, 4, 0, 0,16, /* ..b.d.fgh...l..o */
+ 0, 8, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, /* .q.....w........ */
+ 0, 0, 1, 0, 8, 0, 4, 8, 16, 0, 0, 0, 4, 0, 0,16, /* ..b.d.fgh...l..o */
+ 0, 8, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, /* .q.....w........ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+/*
+ * This perversion encodes all the vax opcodes as a bunch of strings.
+ * RMS says we should build our hash-table at run-time. Hmm.
+ * Please would someone arrange these in decreasing frequency of opcode?
+ * Because of the way hash_...() works, the most frequently used opcode
+ * should be textually first and so on.
+ *
+ * Input for this table was 'vax.opcodes', awk(1)ed by 'vax.opcodes.c.awk' .
+ * So change 'vax.opcodes', then re-generate this table.
+ */
+
+#include "opcode/vax.h"
+
+/*
+ * This is a table of optional op-codes. All of them represent
+ * 'synthetic' instructions that seem popular.
+ *
+ * Here we make some pseudo op-codes. Every code has a bit set to say
+ * it is synthetic. This lets you catch them if you want to
+ * ban these opcodes. They are mnemonics for "elastic" instructions
+ * that are supposed to assemble into the fewest bytes needed to do a
+ * branch, or to do a conditional branch, or whatever.
+ *
+ * The opcode is in the usual place [low-order n*8 bits]. This means
+ * that if you mask off the bucky bits, the usual rules apply about
+ * how long the opcode is.
+ *
+ * All VAX branch displacements come at the end of the instruction.
+ * For simple branches (1-byte opcode + 1-byte displacement) the last
+ * operand is coded 'b?' where the "data type" '?' is a clue that we
+ * may reverse the sense of the branch (complement lowest order bit)
+ * and branch around a jump. This is by far the most common case.
+ * That is why the VIT_OPCODE_SYNTHETIC bit is set: it says this is
+ * a 0-byte op-code followed by 2 or more bytes of operand address.
+ *
+ * If the op-code has VIT_OPCODE_SPECIAL set, then we have a more unusual
+ * case.
+ *
+ * For JBSB & JBR the treatment is the similar, except (1) we have a 'bw'
+ * option before (2) we can directly JSB/JMP because there is no condition.
+ * These operands have 'b-' as their access/data type.
+ *
+ * That leaves a bunch of random opcodes: JACBx, JxOBxxx. In these
+ * cases, we do the same idea. JACBxxx are all marked with a 'b!'
+ * JAOBxxx & JSOBxxx are marked with a 'b:'.
+ *
+ */
+#if (VIT_OPCODE_SYNTHETIC != 0x80000000)
+You have just broken the encoding below, which assumes the sign bit
+ means 'I am an imaginary instruction'.
+#endif
+
+#if (VIT_OPCODE_SPECIAL != 0x40000000)
+ You have just broken the encoding below, which assumes the 0x40 M bit means
+ 'I am not to be "optimised" the way normal branches are'.
+#endif
+
+static const struct vot
+ synthetic_votstrs[] =
+{
+ {"jbsb", {"b-", 0xC0000010}}, /* BSD 4.2 */
+/* jsb used already */
+ {"jbr", {"b-", 0xC0000011}}, /* BSD 4.2 */
+ {"jr", {"b-", 0xC0000011}}, /* consistent */
+ {"jneq", {"b?", 0x80000012}},
+ {"jnequ", {"b?", 0x80000012}},
+ {"jeql", {"b?", 0x80000013}},
+ {"jeqlu", {"b?", 0x80000013}},
+ {"jgtr", {"b?", 0x80000014}},
+ {"jleq", {"b?", 0x80000015}},
+/* un-used opcodes here */
+ {"jgeq", {"b?", 0x80000018}},
+ {"jlss", {"b?", 0x80000019}},
+ {"jgtru", {"b?", 0x8000001a}},
+ {"jlequ", {"b?", 0x8000001b}},
+ {"jvc", {"b?", 0x8000001c}},
+ {"jvs", {"b?", 0x8000001d}},
+ {"jgequ", {"b?", 0x8000001e}},
+ {"jcc", {"b?", 0x8000001e}},
+ {"jlssu", {"b?", 0x8000001f}},
+ {"jcs", {"b?", 0x8000001f}},
+
+ {"jacbw", {"rwrwmwb!", 0xC000003d}},
+ {"jacbf", {"rfrfmfb!", 0xC000004f}},
+ {"jacbd", {"rdrdmdb!", 0xC000006f}},
+ {"jacbb", {"rbrbmbb!", 0xC000009d}},
+ {"jacbl", {"rlrlmlb!", 0xC00000f1}},
+ {"jacbg", {"rgrgmgb!", 0xC0004ffd}},
+ {"jacbh", {"rhrhmhb!", 0xC0006ffd}},
+
+ {"jbs", {"rlvbb?", 0x800000e0}},
+ {"jbc", {"rlvbb?", 0x800000e1}},
+ {"jbss", {"rlvbb?", 0x800000e2}},
+ {"jbcs", {"rlvbb?", 0x800000e3}},
+ {"jbsc", {"rlvbb?", 0x800000e4}},
+ {"jbcc", {"rlvbb?", 0x800000e5}},
+ {"jbssi", {"rlvbb?", 0x800000e6}},
+ {"jbcci", {"rlvbb?", 0x800000e7}},
+ {"jlbs", {"rlb?", 0x800000e8}},
+ {"jlbc", {"rlb?", 0x800000e9}},
+
+ {"jaoblss", {"rlmlb:", 0xC00000f2}},
+ {"jaobleq", {"rlmlb:", 0xC00000f3}},
+ {"jsobgeq", {"mlb:", 0xC00000f4}},
+ {"jsobgtr", {"mlb:", 0xC00000f5}},
+
+/* CASEx has no branch addresses in our conception of it. */
+/* You should use ".word ..." statements after the "case ...". */
+
+ {"", {"", 0}} /* empty is end sentinel */
+
+}; /* synthetic_votstrs */
+
+/*
+ * v i p _ b e g i n ( )
+ *
+ * Call me once before you decode any lines.
+ * I decode votstrs into a hash table at op_hash (which I create).
+ * I return an error text or null.
+ * If you want, I will include the 'synthetic' jXXX instructions in the
+ * instruction table.
+ * You must nominate metacharacters for eg DEC's "#", "@", "^".
+ */
+
+static const char *
+vip_begin (synthetic_too, immediate, indirect, displen)
+ int synthetic_too; /* 1 means include jXXX op-codes. */
+ const char *immediate, *indirect, *displen;
+{
+ const struct vot *vP; /* scan votstrs */
+ const char *retval = 0; /* error text */
+
+ op_hash = hash_new ();
+
+ for (vP = votstrs; *vP->vot_name && !retval; vP++)
+ retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+
+ if (synthetic_too)
+ for (vP = synthetic_votstrs; *vP->vot_name && !retval; vP++)
+ retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);
+
+#ifndef CONST_TABLE
+ vip_op_defaults (immediate, indirect, displen);
+#endif
+
+ return retval;
+}
+
+
+/*
+ * v i p ( )
+ *
+ * This converts a string into a vax instruction.
+ * The string must be a bare single instruction in dec-vax (with BSD4 frobs)
+ * format.
+ * It provides some error messages: at most one fatal error message (which
+ * stops the scan) and at most one warning message for each operand.
+ * The vax instruction is returned in exploded form, since we have no
+ * knowledge of how you parse (or evaluate) your expressions.
+ * We do however strip off and decode addressing modes and operation
+ * mnemonic.
+ *
+ * The exploded instruction is returned to a struct vit of your choice.
+ * #include "vax-inst.h" to know what a struct vit is.
+ *
+ * This function's value is a string. If it is not "" then an internal
+ * logic error was found: read this code to assign meaning to the string.
+ * No argument string should generate such an error string:
+ * it means a bug in our code, not in the user's text.
+ *
+ * You MUST have called vip_begin() once before using this function.
+ */
+
+static void
+vip (vitP, instring)
+ struct vit *vitP; /* We build an exploded instruction here. */
+ char *instring; /* Text of a vax instruction: we modify. */
+{
+ /* How to bit-encode this opcode. */
+ struct vot_wot *vwP;
+ /* 1/skip whitespace.2/scan vot_how */
+ char *p;
+ char *q;
+ /* counts number of operands seen */
+ unsigned char count;
+ /* scan operands in struct vit */
+ struct vop *operandp;
+ /* error over all operands */
+ const char *alloperr;
+ /* Remember char, (we clobber it with '\0' temporarily). */
+ char c;
+ /* Op-code of this instruction. */
+ vax_opcodeT oc;
+
+ if (*instring == ' ')
+ ++instring; /* Skip leading whitespace. */
+ for (p = instring; *p && *p != ' '; p++);; /* MUST end in end-of-string or exactly 1 space. */
+ /* Scanned up to end of operation-code. */
+ /* Operation-code is ended with whitespace. */
+ if (p - instring == 0)
+ {
+ vitP->vit_error = _("No operator");
+ count = 0;
+ memset (vitP->vit_opcode, '\0', sizeof (vitP->vit_opcode));
+ }
+ else
+ {
+ c = *p;
+ *p = '\0';
+ /*
+ * Here with instring pointing to what better be an op-name, and p
+ * pointing to character just past that.
+ * We trust instring points to an op-name, with no whitespace.
+ */
+ vwP = (struct vot_wot *) hash_find (op_hash, instring);
+ *p = c; /* Restore char after op-code. */
+ if (vwP == 0)
+ {
+ vitP->vit_error = _("Unknown operator");
+ count = 0;
+ memset (vitP->vit_opcode, '\0', sizeof (vitP->vit_opcode));
+ }
+ else
+ {
+ /*
+ * We found a match! So lets pick up as many operands as the
+ * instruction wants, and even gripe if there are too many.
+ * We expect comma to seperate each operand.
+ * We let instring track the text, while p tracks a part of the
+ * struct vot.
+ */
+ const char *howp;
+ /*
+ * The lines below know about 2-byte opcodes starting FD,FE or FF.
+ * They also understand synthetic opcodes. Note:
+ * we return 32 bits of opcode, including bucky bits, BUT
+ * an opcode length is either 8 or 16 bits for vit_opcode_nbytes.
+ */
+ oc = vwP->vot_code; /* The op-code. */
+ vitP->vit_opcode_nbytes = (oc & 0xFF) >= 0xFD ? 2 : 1;
+ md_number_to_chars (vitP->vit_opcode, oc, 4);
+ count = 0; /* no operands seen yet */
+ instring = p; /* point just past operation code */
+ alloperr = "";
+ for (howp = vwP->vot_how, operandp = vitP->vit_operand;
+ !(alloperr && *alloperr) && *howp;
+ operandp++, howp += 2)
+ {
+ /*
+ * Here to parse one operand. Leave instring pointing just
+ * past any one ',' that marks the end of this operand.
+ */
+ if (!howp[1])
+ as_fatal (_("odd number of bytes in operand description"));
+ else if (*instring)
+ {
+ for (q = instring; (c = *q) && c != ','; q++)
+ ;
+ /*
+ * Q points to ',' or '\0' that ends argument. C is that
+ * character.
+ */
+ *q = 0;
+ operandp->vop_width = howp[1];
+ operandp->vop_nbytes = vax_operand_width_size[(unsigned) howp[1]];
+ operandp->vop_access = howp[0];
+ vip_op (instring, operandp);
+ *q = c; /* Restore input text. */
+ if (operandp->vop_error)
+ alloperr = _("Bad operand");
+ instring = q + (c ? 1 : 0); /* next operand (if any) */
+ count++; /* won another argument, may have an operr */
+ }
+ else
+ alloperr = _("Not enough operands");
+ }
+ if (!*alloperr)
+ {
+ if (*instring == ' ')
+ instring++; /* Skip whitespace. */
+ if (*instring)
+ alloperr = _("Too many operands");
+ }
+ vitP->vit_error = alloperr;
+ }
+ }
+ vitP->vit_operands = count;
+}
+
+#ifdef test
+
+/*
+ * Test program for above.
+ */
+
+struct vit myvit; /* build an exploded vax instruction here */
+char answer[100]; /* human types a line of vax assembler here */
+char *mybug; /* "" or an internal logic diagnostic */
+int mycount; /* number of operands */
+struct vop *myvop; /* scan operands from myvit */
+int mysynth; /* 1 means want synthetic opcodes. */
+char my_immediate[200];
+char my_indirect[200];
+char my_displen[200];
+
+main ()
+{
+ char *p;
+
+ printf ("0 means no synthetic instructions. ");
+ printf ("Value for vip_begin? ");
+ gets (answer);
+ sscanf (answer, "%d", &mysynth);
+ printf ("Synthetic opcodes %s be included.\n", mysynth ? "will" : "will not");
+ printf ("enter immediate symbols eg enter # ");
+ gets (my_immediate);
+ printf ("enter indirect symbols eg enter @ ");
+ gets (my_indirect);
+ printf ("enter displen symbols eg enter ^ ");
+ gets (my_displen);
+ if (p = vip_begin (mysynth, my_immediate, my_indirect, my_displen))
+ {
+ error ("vip_begin=%s", p);
+ }
+ printf ("An empty input line will quit you from the vax instruction parser\n");
+ for (;;)
+ {
+ printf ("vax instruction: ");
+ fflush (stdout);
+ gets (answer);
+ if (!*answer)
+ {
+ break; /* out of for each input text loop */
+ }
+ vip (&myvit, answer);
+ if (*myvit.vit_error)
+ {
+ printf ("ERR:\"%s\"\n", myvit.vit_error);
+ }
+ printf ("opcode=");
+ for (mycount = myvit.vit_opcode_nbytes, p = myvit.vit_opcode;
+ mycount;
+ mycount--, p++
+ )
+ {
+ printf ("%02x ", *p & 0xFF);
+ }
+ printf (" operand count=%d.\n", mycount = myvit.vit_operands);
+ for (myvop = myvit.vit_operand; mycount; mycount--, myvop++)
+ {
+ printf ("mode=%xx reg=%xx ndx=%xx len='%c'=%c%c%d. expr=\"",
+ myvop->vop_mode, myvop->vop_reg, myvop->vop_ndx,
+ myvop->vop_short, myvop->vop_access, myvop->vop_width,
+ myvop->vop_nbytes);
+ for (p = myvop->vop_expr_begin; p <= myvop->vop_expr_end; p++)
+ {
+ putchar (*p);
+ }
+ printf ("\"\n");
+ if (myvop->vop_error)
+ {
+ printf (" err:\"%s\"\n", myvop->vop_error);
+ }
+ if (myvop->vop_warn)
+ {
+ printf (" wrn:\"%s\"\n", myvop->vop_warn);
+ }
+ }
+ }
+ vip_end ();
+ exit (EXIT_SUCCESS);
+}
+
+#endif /* #ifdef test */
+
+/* end of vax_ins_parse.c */
+
+/* vax_reg_parse.c - convert a VAX register name to a number */
+
+/* Copyright (C) 1987 Free Software Foundation, Inc. A part of GNU. */
+
+/*
+ * v a x _ r e g _ p a r s e ( )
+ *
+ * Take 3 char.s, the last of which may be `\0` (non-existent)
+ * and return the VAX register number that they represent.
+ *
+ * Return -1 if they don't form a register name. Good names return
+ * a number from 0:15 inclusive.
+ *
+ * Case is not important in a name.
+ *
+ * Register names understood are:
+ *
+ * R0
+ * R1
+ * R2
+ * R3
+ * R4
+ * R5
+ * R6
+ * R7
+ * R8
+ * R9
+ * R10
+ * R11
+ * R12 AP
+ * R13 FP
+ * R14 SP
+ * R15 PC
+ *
+ */
+
+#include <ctype.h>
+#define AP (12)
+#define FP (13)
+#define SP (14)
+#define PC (15)
+
+int /* return -1 or 0:15 */
+vax_reg_parse (c1, c2, c3) /* 3 chars of register name */
+ char c1, c2, c3; /* c3 == 0 if 2-character reg name */
+{
+ int retval; /* return -1:15 */
+
+ retval = -1;
+
+ if (isupper (c1))
+ c1 = tolower (c1);
+ if (isupper (c2))
+ c2 = tolower (c2);
+ if (isdigit (c2) && c1 == 'r')
+ {
+ retval = c2 - '0';
+ if (isdigit (c3))
+ {
+ retval = retval * 10 + c3 - '0';
+ retval = (retval > 15) ? -1 : retval;
+ /* clamp the register value to 1 hex digit */
+ }
+ else if (c3)
+ retval = -1; /* c3 must be '\0' or a digit */
+ }
+ else if (c3) /* There are no three letter regs */
+ retval = -1;
+ else if (c2 == 'p')
+ {
+ switch (c1)
+ {
+ case 's':
+ retval = SP;
+ break;
+ case 'f':
+ retval = FP;
+ break;
+ case 'a':
+ retval = AP;
+ break;
+ default:
+ retval = -1;
+ }
+ }
+ else if (c1 == 'p' && c2 == 'c')
+ retval = PC;
+ else
+ retval = -1;
+ return (retval);
+}
+
+/*
+ * v i p _ o p ( )
+ *
+ * Parse a vax operand in DEC assembler notation.
+ * For speed, expect a string of whitespace to be reduced to a single ' '.
+ * This is the case for GNU AS, and is easy for other DEC-compatible
+ * assemblers.
+ *
+ * Knowledge about DEC VAX assembler operand notation lives here.
+ * This doesn't even know what a register name is, except it believes
+ * all register names are 2 or 3 characters, and lets vax_reg_parse() say
+ * what number each name represents.
+ * It does, however, know that PC, SP etc are special registers so it can
+ * detect addressing modes that are silly for those registers.
+ *
+ * Where possible, it delivers 1 fatal or 1 warning message if the operand
+ * is suspect. Exactly what we test for is still evolving.
+ */
+
+/*
+ * B u g s
+ *
+ * Arg block.
+ *
+ * There were a number of 'mismatched argument type' bugs to vip_op.
+ * The most general solution is to typedef each (of many) arguments.
+ * We used instead a typedef'd argument block. This is less modular
+ * than using seperate return pointers for each result, but runs faster
+ * on most engines, and seems to keep programmers happy. It will have
+ * to be done properly if we ever want to use vip_op as a general-purpose
+ * module (it was designed to be).
+ *
+ * G^
+ *
+ * Doesn't support DEC "G^" format operands. These always take 5 bytes
+ * to express, and code as modes 8F or 9F. Reason: "G^" deprives you of
+ * optimising to (say) a "B^" if you are lucky in the way you link.
+ * When someone builds a linker smart enough to convert "G^" to "B^", "W^"
+ * whenever possible, then we should implement it.
+ * If there is some other use for "G^", feel free to code it in!
+ *
+ *
+ * speed
+ *
+ * If I nested if()s more, I could avoid testing (*err) which would save
+ * time, space and page faults. I didn't nest all those if()s for clarity
+ * and because I think the mode testing can be re-arranged 1st to test the
+ * commoner constructs 1st. Does anybody have statistics on this?
+ *
+ *
+ *
+ * error messages
+ *
+ * In future, we should be able to 'compose' error messages in a scratch area
+ * and give the user MUCH more informative error messages. Although this takes
+ * a little more code at run-time, it will make this module much more self-
+ * documenting. As an example of what sucks now: most error messages have
+ * hardwired into them the DEC VAX metacharacters "#^@" which are nothing like
+ * the Un*x characters "$`*", that most users will expect from this AS.
+ */
+
+/*
+ * The input is a string, ending with '\0'.
+ *
+ * We also require a 'hint' of what kind of operand is expected: so
+ * we can remind caller not to write into literals for instance.
+ *
+ * The output is a skeletal instruction.
+ *
+ * The algorithm has two parts.
+ * 1. extract the syntactic features (parse off all the @^#-()+[] mode crud);
+ * 2. express the @^#-()+[] as some parameters suited to further analysis.
+ *
+ * 2nd step is where we detect the googles of possible invalid combinations
+ * a human (or compiler) might write. Note that if we do a half-way
+ * decent assembler, we don't know how long to make (eg) displacement
+ * fields when we first meet them (because they may not have defined values).
+ * So we must wait until we know how many bits are needed for each address,
+ * then we can know both length and opcodes of instructions.
+ * For reason(s) above, we will pass to our caller a 'broken' instruction
+ * of these major components, from which our caller can generate instructions:
+ * - displacement length I^ S^ L^ B^ W^ unspecified
+ * - mode (many)
+ * - register R0-R15 or absent
+ * - index register R0-R15 or absent
+ * - expression text what we don't parse
+ * - error text(s) why we couldn't understand the operand
+ */
+
+/*
+ * To decode output of this, test errtxt. If errtxt[0] == '\0', then
+ * we had no errors that prevented parsing. Also, if we ever report
+ * an internal bug, errtxt[0] is set non-zero. So one test tells you
+ * if the other outputs are to be taken seriously.
+ */
+
+
+/*
+ * Because this module is useful for both VMS and UN*X style assemblers
+ * and because of the variety of UN*X assemblers we must recognise
+ * the different conventions for assembler operand notation. For example
+ * VMS says "#42" for immediate mode, while most UN*X say "$42".
+ * We permit arbitrary sets of (single) characters to represent the
+ * 3 concepts that DEC writes '#', '@', '^'.
+ */
+
+/* character tests */
+#define VIP_IMMEDIATE 01 /* Character is like DEC # */
+#define VIP_INDIRECT 02 /* Char is like DEC @ */
+#define VIP_DISPLEN 04 /* Char is like DEC ^ */
+
+#define IMMEDIATEP(c) (vip_metacharacters [(c)&0xff]&VIP_IMMEDIATE)
+#define INDIRECTP(c) (vip_metacharacters [(c)&0xff]&VIP_INDIRECT)
+#define DISPLENP(c) (vip_metacharacters [(c)&0xff]&VIP_DISPLEN)
+
+/* We assume 8 bits per byte. Use vip_op_defaults() to set these up BEFORE we
+ * are ever called.
+ */
+
+#if defined(CONST_TABLE)
+#define _ 0,
+#define I VIP_IMMEDIATE,
+#define S VIP_INDIRECT,
+#define D VIP_DISPLEN,
+static const char
+vip_metacharacters[256] =
+{
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /* ^@ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O*/
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /* ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
+ _ _ _ _ I _ _ _ _ _ S _ _ _ _ _ /* sp ! " # $ % & ' ( ) * + , - . / */
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /*0 1 2 3 4 5 6 7 8 9 : ; < = > ?*/
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /*@ A B C D E F G H I J K L M N O*/
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /*P Q R S T U V W X Y Z [ \ ] ^ _*/
+ D _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /*` a b c d e f g h i j k l m n o*/
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /*p q r s t u v w x y z { | } ~ ^?*/
+
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+};
+#undef _
+#undef I
+#undef S
+#undef D
+#else
+static char vip_metacharacters[256];
+
+static void
+vip_op_1 (bit, syms)
+ int bit;
+ const char *syms;
+{
+ unsigned char t;
+
+ while ((t = *syms++) != 0)
+ vip_metacharacters[t] |= bit;
+}
+
+/* Can be called any time. More arguments may appear in future. */
+static void
+vip_op_defaults (immediate, indirect, displen)
+ const char *immediate;
+ const char *indirect;
+ const char *displen;
+{
+ vip_op_1 (VIP_IMMEDIATE, immediate);
+ vip_op_1 (VIP_INDIRECT, indirect);
+ vip_op_1 (VIP_DISPLEN, displen);
+}
+
+#endif
+
+
+/*
+ * Dec defines the semantics of address modes (and values)
+ * by a two-letter code, explained here.
+ *
+ * letter 1: access type
+ *
+ * a address calculation - no data access, registers forbidden
+ * b branch displacement
+ * m read - let go of bus - write back "modify"
+ * r read
+ * v bit field address: like 'a' but registers are OK
+ * w write
+ * space no operator (eg ".long foo") [our convention]
+ *
+ * letter 2: data type (i.e. width, alignment)
+ *
+ * b byte
+ * d double precision floating point (D format)
+ * f single precision floating point (F format)
+ * g G format floating
+ * h H format floating
+ * l longword
+ * o octaword
+ * q quadword
+ * w word
+ * ? simple synthetic branch operand
+ * - unconditional synthetic JSB/JSR operand
+ * ! complex synthetic branch operand
+ *
+ * The '-?!' letter 2's are not for external consumption. They are used
+ * for various assemblers. Generally, all unknown widths are assumed 0.
+ * We don't limit your choice of width character.
+ *
+ * DEC operands are hard work to parse. For example, '@' as the first
+ * character means indirect (deferred) mode but elswhere it is a shift
+ * operator.
+ * The long-winded explanation of how this is supposed to work is
+ * cancelled. Read a DEC vax manual.
+ * We try hard not to parse anything that MIGHT be part of the expression
+ * buried in that syntax. For example if we see @...(Rn) we don't check
+ * for '-' before the '(' because mode @-(Rn) does not exist.
+ *
+ * After parsing we have:
+ *
+ * at 1 if leading '@' (or Un*x '*')
+ * len takes one value from " bilsw". eg B^ -> 'b'.
+ * hash 1 if leading '#' (or Un*x '$')
+ * expr_begin, expr_end the expression we did not parse
+ * even though we don't interpret it, we make use
+ * of its presence or absence.
+ * sign -1: -(Rn) 0: absent +1: (Rn)+
+ * paren 1 if () are around register
+ * reg major register number 0:15 -1 means absent
+ * ndx index register number 0:15 -1 means absent
+ *
+ * Again, I dare not explain it: just trace ALL the code!
+ */
+
+static void
+vip_op (optext, vopP)
+ /* user's input string e.g.: "@B^foo@bar(AP)[FP]:" */
+ char *optext;
+ /* Input fields: vop_access, vop_width.
+ Output fields: _ndx, _reg, _mode, _short, _warn,
+ _error _expr_begin, _expr_end, _nbytes.
+ vop_nbytes : number of bytes in a datum. */
+ struct vop *vopP;
+{
+ /* track operand text forward */
+ char *p;
+ /* track operand text backward */
+ char *q;
+ /* 1 if leading '@' ('*') seen */
+ int at;
+ /* one of " bilsw" */
+ char len;
+ /* 1 if leading '#' ('$') seen */
+ int hash;
+ /* -1, 0 or +1 */
+ int sign = 0;
+ /* 1 if () surround register */
+ int paren = 0;
+ /* register number, -1:absent */
+ int reg = 0;
+ /* index register number -1:absent */
+ int ndx = 0;
+ /* report illegal operand, ""==OK */
+ /* " " is a FAKE error: means we won */
+ /* ANY err that begins with ' ' is a fake. */
+ /* " " is converted to "" before return */
+ const char *err;
+ /* warn about weird modes pf address */
+ const char *wrn;
+ /* preserve q in case we backup */
+ char *oldq = NULL;
+ /* build up 4-bit operand mode here */
+ /* note: index mode is in ndx, this is */
+ /* the major mode of operand address */
+ int mode = 0;
+ /*
+ * Notice how we move wrong-arg-type bugs INSIDE this module: if we
+ * get the types wrong below, we lose at compile time rather than at
+ * lint or run time.
+ */
+ char access_mode; /* vop_access. */
+ char width; /* vop_width. */
+
+ access_mode = vopP->vop_access;
+ width = vopP->vop_width;
+ /* None of our code bugs (yet), no user text errors, no warnings
+ even. */
+ err = wrn = 0;
+
+ p = optext;
+
+ if (*p == ' ') /* Expect all whitespace reduced to ' '. */
+ p++; /* skip over whitespace */
+
+ if ((at = INDIRECTP (*p)) != 0)
+ { /* 1 if *p=='@'(or '*' for Un*x) */
+ p++; /* at is determined */
+ if (*p == ' ') /* Expect all whitespace reduced to ' '. */
+ p++; /* skip over whitespace */
+ }
+
+ /*
+ * This code is subtle. It tries to detect all legal (letter)'^'
+ * but it doesn't waste time explicitly testing for premature '\0' because
+ * this case is rejected as a mismatch against either (letter) or '^'.
+ */
+ {
+ char c;
+
+ c = *p;
+ if (isupper (c))
+ c = tolower (c);
+ if (DISPLENP (p[1]) && strchr ("bilws", len = c))
+ p += 2; /* skip (letter) '^' */
+ else /* no (letter) '^' seen */
+ len = ' '; /* len is determined */
+ }
+
+ if (*p == ' ') /* Expect all whitespace reduced to ' '. */
+ p++; /* skip over whitespace */
+
+ if ((hash = IMMEDIATEP (*p)) != 0) /* 1 if *p=='#' ('$' for Un*x) */
+ p++; /* hash is determined */
+
+ /*
+ * p points to what may be the beginning of an expression.
+ * We have peeled off the front all that is peelable.
+ * We know at, len, hash.
+ *
+ * Lets point q at the end of the text and parse that (backwards).
+ */
+
+ for (q = p; *q; q++)
+ ;
+ q--; /* now q points at last char of text */
+
+ if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
+ q--;
+ /* reverse over whitespace, but don't */
+ /* run back over *p */
+
+ /*
+ * As a matter of policy here, we look for [Rn], although both Rn and S^#
+ * forbid [Rn]. This is because it is easy, and because only a sick
+ * cyborg would have [...] trailing an expression in a VAX-like assembler.
+ * A meticulous parser would first check for Rn followed by '(' or '['
+ * and not parse a trailing ']' if it found another. We just ban expressions
+ * ending in ']'.
+ */
+ if (*q == ']')
+ {
+ while (q >= p && *q != '[')
+ q--;
+ /* either q<p or we got matching '[' */
+ if (q < p)
+ err = _("no '[' to match ']'");
+ else
+ {
+ /*
+ * Confusers like "[]" will eventually lose with a bad register
+ * name error. So again we don't need to check for early '\0'.
+ */
+ if (q[3] == ']')
+ ndx = vax_reg_parse (q[1], q[2], 0);
+ else if (q[4] == ']')
+ ndx = vax_reg_parse (q[1], q[2], q[3]);
+ else
+ ndx = -1;
+ /*
+ * Since we saw a ']' we will demand a register name in the [].
+ * If luser hasn't given us one: be rude.
+ */
+ if (ndx < 0)
+ err = _("bad register in []");
+ else if (ndx == PC)
+ err = _("[PC] index banned");
+ else
+ q--; /* point q just before "[...]" */
+ }
+ }
+ else
+ ndx = -1; /* no ']', so no iNDeX register */
+
+ /*
+ * If err = "..." then we lost: run away.
+ * Otherwise ndx == -1 if there was no "[...]".
+ * Otherwise, ndx is index register number, and q points before "[...]".
+ */
+
+ if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
+ q--;
+ /* reverse over whitespace, but don't */
+ /* run back over *p */
+ if (!err || !*err)
+ {
+ sign = 0; /* no ()+ or -() seen yet */
+
+ if (q > p + 3 && *q == '+' && q[-1] == ')')
+ {
+ sign = 1; /* we saw a ")+" */
+ q--; /* q points to ')' */
+ }
+
+ if (*q == ')' && q > p + 2)
+ {
+ paren = 1; /* assume we have "(...)" */
+ while (q >= p && *q != '(')
+ q--;
+ /* either q<p or we got matching '(' */
+ if (q < p)
+ err = _("no '(' to match ')'");
+ else
+ {
+ /*
+ * Confusers like "()" will eventually lose with a bad register
+ * name error. So again we don't need to check for early '\0'.
+ */
+ if (q[3] == ')')
+ reg = vax_reg_parse (q[1], q[2], 0);
+ else if (q[4] == ')')
+ reg = vax_reg_parse (q[1], q[2], q[3]);
+ else
+ reg = -1;
+ /*
+ * Since we saw a ')' we will demand a register name in the ')'.
+ * This is nasty: why can't our hypothetical assembler permit
+ * parenthesised expressions? BECAUSE I AM LAZY! That is why.
+ * Abuse luser if we didn't spy a register name.
+ */
+ if (reg < 0)
+ {
+ /* JF allow parenthasized expressions. I hope this works */
+ paren = 0;
+ while (*q != ')')
+ q++;
+ /* err = "unknown register in ()"; */
+ }
+ else
+ q--; /* point just before '(' of "(...)" */
+ /*
+ * If err == "..." then we lost. Run away.
+ * Otherwise if reg >= 0 then we saw (Rn).
+ */
+ }
+ /*
+ * If err == "..." then we lost.
+ * Otherwise paren==1 and reg = register in "()".
+ */
+ }
+ else
+ paren = 0;
+ /*
+ * If err == "..." then we lost.
+ * Otherwise, q points just before "(Rn)", if any.
+ * If there was a "(...)" then paren==1, and reg is the register.
+ */
+
+ /*
+ * We should only seek '-' of "-(...)" if:
+ * we saw "(...)" paren == 1
+ * we have no errors so far ! *err
+ * we did not see '+' of "(...)+" sign < 1
+ * We don't check len. We want a specific error message later if
+ * user tries "x^...-(Rn)". This is a feature not a bug.
+ */
+ if (!err || !*err)
+ {
+ if (paren && sign < 1)/* !sign is adequate test */
+ {
+ if (*q == '-')
+ {
+ sign = -1;
+ q--;
+ }
+ }
+ /*
+ * We have back-tracked over most
+ * of the crud at the end of an operand.
+ * Unless err, we know: sign, paren. If paren, we know reg.
+ * The last case is of an expression "Rn".
+ * This is worth hunting for if !err, !paren.
+ * We wouldn't be here if err.
+ * We remember to save q, in case we didn't want "Rn" anyway.
+ */
+ if (!paren)
+ {
+ if (*q == ' ' && q >= p) /* Expect all whitespace reduced to ' '. */
+ q--;
+ /* reverse over whitespace, but don't */
+ /* run back over *p */
+ if (q > p && q < p + 3) /* room for Rn or Rnn exactly? */
+ reg = vax_reg_parse (p[0], p[1], q < p + 2 ? 0 : p[2]);
+ else
+ reg = -1; /* always comes here if no register at all */
+ /*
+ * Here with a definitive reg value.
+ */
+ if (reg >= 0)
+ {
+ oldq = q;
+ q = p - 1;
+ }
+ }
+ }
+ }
+ /*
+ * have reg. -1:absent; else 0:15
+ */
+
+ /*
+ * We have: err, at, len, hash, ndx, sign, paren, reg.
+ * Also, any remaining expression is from *p through *q inclusive.
+ * Should there be no expression, q==p-1. So expression length = q-p+1.
+ * This completes the first part: parsing the operand text.
+ */
+
+ /*
+ * We now want to boil the data down, checking consistency on the way.
+ * We want: len, mode, reg, ndx, err, p, q, wrn, bug.
+ * We will deliver a 4-bit reg, and a 4-bit mode.
+ */
+
+ /*
+ * Case of branch operand. Different. No L^B^W^I^S^ allowed for instance.
+ *
+ * in: at ?
+ * len ?
+ * hash ?
+ * p:q ?
+ * sign ?
+ * paren ?
+ * reg ?
+ * ndx ?
+ *
+ * out: mode 0
+ * reg -1
+ * len ' '
+ * p:q whatever was input
+ * ndx -1
+ * err " " or error message, and other outputs trashed
+ */
+ /* branch operands have restricted forms */
+ if ((!err || !*err) && access_mode == 'b')
+ {
+ if (at || hash || sign || paren || ndx >= 0 || reg >= 0 || len != ' ')
+ err = _("invalid branch operand");
+ else
+ err = " ";
+ }
+
+ /* Since nobody seems to use it: comment this 'feature'(?) out for now. */
+#ifdef NEVER
+ /*
+ * Case of stand-alone operand. e.g. ".long foo"
+ *
+ * in: at ?
+ * len ?
+ * hash ?
+ * p:q ?
+ * sign ?
+ * paren ?
+ * reg ?
+ * ndx ?
+ *
+ * out: mode 0
+ * reg -1
+ * len ' '
+ * p:q whatever was input
+ * ndx -1
+ * err " " or error message, and other outputs trashed
+ */
+ if ((!err || !*err) && access_mode == ' ')
+ {
+ if (at)
+ err = _("address prohibits @");
+ else if (hash)
+ err = _("address prohibits #");
+ else if (sign)
+ {
+ if (sign < 0)
+ err = _("address prohibits -()");
+ else
+ err = _("address prohibits ()+");
+ }
+ else if (paren)
+ err = _("address prohibits ()");
+ else if (ndx >= 0)
+ err = _("address prohibits []");
+ else if (reg >= 0)
+ err = _("address prohibits register");
+ else if (len != ' ')
+ err = _("address prohibits displacement length specifier");
+ else
+ {
+ err = " "; /* succeed */
+ mode = 0;
+ }
+ }
+#endif /*#Ifdef NEVER*/
+
+ /*
+ * Case of S^#.
+ *
+ * in: at 0
+ * len 's' definition
+ * hash 1 demand
+ * p:q demand not empty
+ * sign 0 by paren==0
+ * paren 0 by "()" scan logic because "S^" seen
+ * reg -1 or nn by mistake
+ * ndx -1
+ *
+ * out: mode 0
+ * reg -1
+ * len 's'
+ * exp
+ * ndx -1
+ */
+ if ((!err || !*err) && len == 's')
+ {
+ if (!hash || paren || at || ndx >= 0)
+ err = _("invalid operand of S^#");
+ else
+ {
+ if (reg >= 0)
+ {
+ /*
+ * SHIT! we saw S^#Rnn ! put the Rnn back in
+ * expression. KLUDGE! Use oldq so we don't
+ * need to know exact length of reg name.
+ */
+ q = oldq;
+ reg = 0;
+ }
+ /*
+ * We have all the expression we will ever get.
+ */
+ if (p > q)
+ err = _("S^# needs expression");
+ else if (access_mode == 'r')
+ {
+ err = " "; /* WIN! */
+ mode = 0;
+ }
+ else
+ err = _("S^# may only read-access");
+ }
+ }
+
+ /*
+ * Case of -(Rn), which is weird case.
+ *
+ * in: at 0
+ * len '
+ * hash 0
+ * p:q q<p
+ * sign -1 by definition
+ * paren 1 by definition
+ * reg present by definition
+ * ndx optional
+ *
+ * out: mode 7
+ * reg present
+ * len ' '
+ * exp "" enforce empty expression
+ * ndx optional warn if same as reg
+ */
+ if ((!err || !*err) && sign < 0)
+ {
+ if (len != ' ' || hash || at || p <= q)
+ err = _("invalid operand of -()");
+ else
+ {
+ err = " "; /* win */
+ mode = 7;
+ if (reg == PC)
+ wrn = _("-(PC) unpredictable");
+ else if (reg == ndx)
+ wrn = _("[]index same as -()register: unpredictable");
+ }
+ }
+
+ /*
+ * We convert "(Rn)" to "@Rn" for our convenience.
+ * (I hope this is convenient: has someone got a better way to parse this?)
+ * A side-effect of this is that "@Rn" is a valid operand.
+ */
+ if (paren && !sign && !hash && !at && len == ' ' && p > q)
+ {
+ at = 1;
+ paren = 0;
+ }
+
+ /*
+ * Case of (Rn)+, which is slightly different.
+ *
+ * in: at
+ * len ' '
+ * hash 0
+ * p:q q<p
+ * sign +1 by definition
+ * paren 1 by definition
+ * reg present by definition
+ * ndx optional
+ *
+ * out: mode 8+@
+ * reg present
+ * len ' '
+ * exp "" enforce empty expression
+ * ndx optional warn if same as reg
+ */
+ if ((!err || !*err) && sign > 0)
+ {
+ if (len != ' ' || hash || p <= q)
+ err = _("invalid operand of ()+");
+ else
+ {
+ err = " "; /* win */
+ mode = 8 + (at ? 1 : 0);
+ if (reg == PC)
+ wrn = _("(PC)+ unpredictable");
+ else if (reg == ndx)
+ wrn = _("[]index same as ()+register: unpredictable");
+ }
+ }
+
+ /*
+ * Case of #, without S^.
+ *
+ * in: at
+ * len ' ' or 'i'
+ * hash 1 by definition
+ * p:q
+ * sign 0
+ * paren 0
+ * reg absent
+ * ndx optional
+ *
+ * out: mode 8+@
+ * reg PC
+ * len ' ' or 'i'
+ * exp
+ * ndx optional
+ */
+ if ((!err || !*err) && hash)
+ {
+ if (len != 'i' && len != ' ')
+ err = _("# conflicts length");
+ else if (paren)
+ err = _("# bars register");
+ else
+ {
+ if (reg >= 0)
+ {
+ /*
+ * SHIT! we saw #Rnn! Put the Rnn back into the expression.
+ * By using oldq, we don't need to know how long Rnn was.
+ * KLUDGE!
+ */
+ q = oldq;
+ reg = -1; /* no register any more */
+ }
+ err = " "; /* win */
+
+ /* JF a bugfix, I think! */
+ if (at && access_mode == 'a')
+ vopP->vop_nbytes = 4;
+
+ mode = (at ? 9 : 8);
+ reg = PC;
+ if ((access_mode == 'm' || access_mode == 'w') && !at)
+ wrn = _("writing or modifying # is unpredictable");
+ }
+ }
+ /*
+ * If !*err, then sign == 0
+ * hash == 0
+ */
+
+ /*
+ * Case of Rn. We seperate this one because it has a few special
+ * errors the remaining modes lack.
+ *
+ * in: at optional
+ * len ' '
+ * hash 0 by program logic
+ * p:q empty
+ * sign 0 by program logic
+ * paren 0 by definition
+ * reg present by definition
+ * ndx optional
+ *
+ * out: mode 5+@
+ * reg present
+ * len ' ' enforce no length
+ * exp "" enforce empty expression
+ * ndx optional warn if same as reg
+ */
+ if ((!err || !*err) && !paren && reg >= 0)
+ {
+ if (len != ' ')
+ err = _("length not needed");
+ else if (at)
+ {
+ err = " "; /* win */
+ mode = 6; /* @Rn */
+ }
+ else if (ndx >= 0)
+ err = _("can't []index a register, because it has no address");
+ else if (access_mode == 'a')
+ err = _("a register has no address");
+ else
+ {
+ /*
+ * Idea here is to detect from length of datum
+ * and from register number if we will touch PC.
+ * Warn if we do.
+ * vop_nbytes is number of bytes in operand.
+ * Compute highest byte affected, compare to PC0.
+ */
+ if ((vopP->vop_nbytes + reg * 4) > 60)
+ wrn = _("PC part of operand unpredictable");
+ err = " "; /* win */
+ mode = 5; /* Rn */
+ }
+ }
+ /*
+ * If !*err, sign == 0
+ * hash == 0
+ * paren == 1 OR reg==-1
+ */
+
+ /*
+ * Rest of cases fit into one bunch.
+ *
+ * in: at optional
+ * len ' ' or 'b' or 'w' or 'l'
+ * hash 0 by program logic
+ * p:q expected (empty is not an error)
+ * sign 0 by program logic
+ * paren optional
+ * reg optional
+ * ndx optional
+ *
+ * out: mode 10 + @ + len
+ * reg optional
+ * len ' ' or 'b' or 'w' or 'l'
+ * exp maybe empty
+ * ndx optional warn if same as reg
+ */
+ if (!err || !*err)
+ {
+ err = " "; /* win (always) */
+ mode = 10 + (at ? 1 : 0);
+ switch (len)
+ {
+ case 'l':
+ mode += 2;
+ case 'w':
+ mode += 2;
+ case ' ': /* assumed B^ until our caller changes it */
+ case 'b':
+ break;
+ }
+ }
+
+ /*
+ * here with completely specified mode
+ * len
+ * reg
+ * expression p,q
+ * ndx
+ */
+
+ if (*err == ' ')
+ err = 0; /* " " is no longer an error */
+
+ vopP->vop_mode = mode;
+ vopP->vop_reg = reg;
+ vopP->vop_short = len;
+ vopP->vop_expr_begin = p;
+ vopP->vop_expr_end = q;
+ vopP->vop_ndx = ndx;
+ vopP->vop_error = err;
+ vopP->vop_warn = wrn;
+}
+
+/*
+
+ Summary of vip_op outputs.
+
+ mode reg len ndx
+ (Rn) => @Rn
+ {@}Rn 5+@ n ' ' optional
+ branch operand 0 -1 ' ' -1
+ S^#foo 0 -1 's' -1
+ -(Rn) 7 n ' ' optional
+ {@}(Rn)+ 8+@ n ' ' optional
+ {@}#foo, no S^ 8+@ PC " i" optional
+ {@}{q^}{(Rn)} 10+@+q option " bwl" optional
+
+ */
+
+#ifdef TEST /* #Define to use this testbed. */
+
+/*
+ * Follows a test program for this function.
+ * We declare arrays non-local in case some of our tiny-minded machines
+ * default to small stacks. Also, helps with some debuggers.
+ */
+
+#include <stdio.h>
+
+char answer[100]; /* human types into here */
+char *p; /* */
+char *myerr;
+char *mywrn;
+char *mybug;
+char myaccess;
+char mywidth;
+char mymode;
+char myreg;
+char mylen;
+char *myleft;
+char *myright;
+char myndx;
+int my_operand_length;
+char my_immediate[200];
+char my_indirect[200];
+char my_displen[200];
+
+main ()
+{
+ printf ("enter immediate symbols eg enter # ");
+ gets (my_immediate);
+ printf ("enter indirect symbols eg enter @ ");
+ gets (my_indirect);
+ printf ("enter displen symbols eg enter ^ ");
+ gets (my_displen);
+ vip_op_defaults (my_immediate, my_indirect, my_displen);
+ for (;;)
+ {
+ printf ("access,width (eg 'ab' or 'wh') [empty line to quit] : ");
+ fflush (stdout);
+ gets (answer);
+ if (!answer[0])
+ exit (EXIT_SUCCESS);
+ myaccess = answer[0];
+ mywidth = answer[1];
+ switch (mywidth)
+ {
+ case 'b':
+ my_operand_length = 1;
+ break;
+ case 'd':
+ my_operand_length = 8;
+ break;
+ case 'f':
+ my_operand_length = 4;
+ break;
+ case 'g':
+ my_operand_length = 16;
+ break;
+ case 'h':
+ my_operand_length = 32;
+ break;
+ case 'l':
+ my_operand_length = 4;
+ break;
+ case 'o':
+ my_operand_length = 16;
+ break;
+ case 'q':
+ my_operand_length = 8;
+ break;
+ case 'w':
+ my_operand_length = 2;
+ break;
+ case '!':
+ case '?':
+ case '-':
+ my_operand_length = 0;
+ break;
+
+ default:
+ my_operand_length = 2;
+ printf ("I dn't understand access width %c\n", mywidth);
+ break;
+ }
+ printf ("VAX assembler instruction operand: ");
+ fflush (stdout);
+ gets (answer);
+ mybug = vip_op (answer, myaccess, mywidth, my_operand_length,
+ &mymode, &myreg, &mylen, &myleft, &myright, &myndx,
+ &myerr, &mywrn);
+ if (*myerr)
+ {
+ printf ("error: \"%s\"\n", myerr);
+ if (*mybug)
+ printf (" bug: \"%s\"\n", mybug);
+ }
+ else
+ {
+ if (*mywrn)
+ printf ("warning: \"%s\"\n", mywrn);
+ mumble ("mode", mymode);
+ mumble ("register", myreg);
+ mumble ("index", myndx);
+ printf ("width:'%c' ", mylen);
+ printf ("expression: \"");
+ while (myleft <= myright)
+ putchar (*myleft++);
+ printf ("\"\n");
+ }
+ }
+}
+
+mumble (text, value)
+ char *text;
+ int value;
+{
+ printf ("%s:", text);
+ if (value >= 0)
+ printf ("%xx", value);
+ else
+ printf ("ABSENT");
+ printf (" ");
+}
+
+#endif /* ifdef TEST */
+
+/* end: vip_op.c */
+
+const int md_short_jump_size = 3;
+const int md_long_jump_size = 6;
+const int md_reloc_size = 8; /* Size of relocation record */
+
+void
+md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ /* This former calculation was off by two:
+ offset = to_addr - (from_addr + 1);
+ We need to account for the one byte instruction and also its
+ two byte operand. */
+ offset = to_addr - (from_addr + 1 + 2);
+ *ptr++ = VAX_BRW; /* branch with word (16 bit) offset */
+ md_number_to_chars (ptr, offset, 2);
+}
+
+void
+md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
+ char *ptr;
+ addressT from_addr, to_addr;
+ fragS *frag;
+ symbolS *to_symbol;
+{
+ valueT offset;
+
+ offset = to_addr - S_GET_VALUE (to_symbol);
+ *ptr++ = VAX_JMP; /* arbitrary jump */
+ *ptr++ = VAX_ABSOLUTE_MODE;
+ md_number_to_chars (ptr, offset, 4);
+ fix_new (frag, ptr - frag->fr_literal, 4, to_symbol, (long) 0, 0, NO_RELOC);
+}
+
+#ifdef OBJ_VMS
+CONST char *md_shortopts = "d:STt:V+1h:Hv::";
+#else
+CONST char *md_shortopts = "d:STt:V";
+#endif
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'S':
+ as_warn (_("SYMBOL TABLE not implemented"));
+ break;
+
+ case 'T':
+ as_warn (_("TOKEN TRACE not implemented"));
+ break;
+
+ case 'd':
+ as_warn (_("Displacement length %s ignored!"), arg);
+ break;
+
+ case 't':
+ as_warn (_("I don't need or use temp. file \"%s\"."), arg);
+ break;
+
+ case 'V':
+ as_warn (_("I don't use an interpass file! -V ignored"));
+ break;
+
+#ifdef OBJ_VMS
+ case '+': /* For g++. Hash any name > 31 chars long. */
+ flag_hash_long_names = 1;
+ break;
+
+ case '1': /* For backward compatibility */
+ flag_one = 1;
+ break;
+
+ case 'H': /* Show new symbol after hash truncation */
+ flag_show_after_trunc = 1;
+ break;
+
+ case 'h': /* No hashing of mixed-case names */
+ {
+ extern char vms_name_mapping;
+ vms_name_mapping = atoi (arg);
+ flag_no_hash_mixed_case = 1;
+ }
+ break;
+
+ case 'v':
+ {
+ extern char *compiler_version_string;
+ if (!arg || !*arg || access (arg, 0) == 0)
+ return 0; /* have caller show the assembler version */
+ compiler_version_string = arg;
+ }
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+VAX options:\n\
+-d LENGTH ignored\n\
+-J ignored\n\
+-S ignored\n\
+-t FILE ignored\n\
+-T ignored\n\
+-V ignored\n"));
+#ifdef OBJ_VMS
+ fprintf (stream, _("\
+VMS options:\n\
+-+ hash encode names longer than 31 characters\n\
+-1 `const' handling compatible with gcc 1.x\n\
+-H show new symbol after hash truncation\n\
+-h NUM don't hash mixed-case names, and adjust case:\n\
+ 0 = upper, 2 = lower, 3 = preserve case\n\
+-v\"VERSION\" code being assembled was produced by compiler \"VERSION\"\n"));
+#endif
+}
+
+/* We have no need to default values of symbols. */
+
+/* ARGSUSED */
+symbolS *
+md_undefined_symbol (name)
+ char *name;
+{
+ return 0;
+}
+
+/* Round up a section size to the appropriate boundary. */
+valueT
+md_section_align (segment, size)
+ segT segment;
+ valueT size;
+{
+ return size; /* Byte alignment is fine */
+}
+
+/* Exactly what point is a PC-relative offset relative TO?
+ On the vax, they're relative to the address of the offset, plus
+ its size. (??? Is this right? FIXME-SOON) */
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
+}
+
+/* end of tc-vax.c */
diff --git a/gas/config/tc-vax.h b/gas/config/tc-vax.h
new file mode 100644
index 00000000000..b6791f7f583
--- /dev/null
+++ b/gas/config/tc-vax.h
@@ -0,0 +1,45 @@
+/* tc-vax.h -- Header file for tc-vax.c.
+ Copyright (C) 1987, 91, 92, 93, 95, 96, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TC_VAX 1
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#define NO_RELOC 0
+#define NOP_OPCODE 0x01
+
+#define tc_aout_pre_write_hook(x) {;} /* not used */
+#define tc_crawl_symbol_chain(a) {;} /* not used */
+#define tc_headers_hook(a) {;} /* not used */
+#define md_operand(x)
+
+long md_chars_to_number PARAMS ((unsigned char *, int));
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of tc-vax.h */
diff --git a/gas/config/tc-w65.c b/gas/config/tc-w65.c
new file mode 100644
index 00000000000..72201e7b760
--- /dev/null
+++ b/gas/config/tc-w65.c
@@ -0,0 +1,1219 @@
+/* tc-w65.c -- Assemble code for the W65816
+ Copyright (C) 1995, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ Written By Steve Chamberlain
+ sac@cygnus.com
+ */
+
+#include <stdio.h>
+#include "as.h"
+#include "bfd.h"
+#include "subsegs.h"
+#define DEFINE_TABLE
+#include "../opcodes/w65-opc.h"
+#include <ctype.h>
+
+const char comment_chars[] = "!";
+CONST char line_separator_chars[] = ";";
+const char line_comment_chars[] = "!#";
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+#define OP_BCC 0x90
+#define OP_BCS 0xB0
+#define OP_BEQ 0xF0
+#define OP_BMI 0x30
+#define OP_BNE 0xD0
+#define OP_BPL 0x10
+#define OP_BRA 0x80
+#define OP_BRL 0x82
+#define OP_BVC 0x50
+#define OP_BVS 0x70
+
+void s_longa ();
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"int", cons, 2},
+ {"word", cons, 2},
+ {"longa", s_longa, 0},
+ {"longi", s_longa, 1},
+ {0, 0, 0}
+};
+
+
+void cons ();
+void s_align_bytes ();
+
+
+/*int md_reloc_size; */
+
+static int relax; /* set if -relax seen */
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+
+
+static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
+
+int M; /* M flag */
+int X; /* X flag */
+
+
+
+
+#define C(a,b) ENCODE_RELAX(a,b)
+#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
+
+#define GET_WHAT(x) ((x>>2))
+
+#define BYTE_DISP 1
+#define WORD_DISP 2
+#define UNDEF_BYTE_DISP 0
+#define UNDEF_WORD_DISP 3
+
+#define COND_BRANCH 1
+#define UNCOND_BRANCH 2
+#define END 3
+
+#define BYTE_F 127 /* How far we can branch forwards */
+#define BYTE_B -126 /* How far we can branch backwards */
+#define WORD_F 32767
+#define WORD_B 32768
+
+relax_typeS md_relax_table[C (END, 0)];
+
+/*
+ This function is called once, at assembler startup time. This should
+ set up all the tables, etc that the MD part of the assembler needs
+ */
+
+
+void
+s_longa (xmode)
+{
+ int *p = xmode ? &X : &M;
+ while (*input_line_pointer == ' ')
+ input_line_pointer++;
+ if (strncmp (input_line_pointer, "on", 2) == 0)
+ {
+ input_line_pointer += 2;
+ *p = 0;
+ }
+ else if (strncmp (input_line_pointer, "off", 3) == 0)
+ {
+ *p = 1;
+ input_line_pointer += 3;
+ }
+ else
+ as_bad (_("need on or off."));
+ demand_empty_rest_of_line ();
+}
+void
+md_begin ()
+{
+ relax_typeS *table;
+ struct opinfo *opcode;
+ char *prev_name = "";
+
+ opcode_hash_control = hash_new ();
+
+ /* Insert unique names into hash table */
+ for (opcode = optable; opcode->name; opcode++)
+ {
+ if (strcmp (prev_name, opcode->name))
+ {
+ prev_name = opcode->name;
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ }
+ else
+ {
+ /* Make all the opcodes with the same name point to the same
+ string */
+ opcode->name = prev_name;
+ }
+ }
+
+
+ /* Initialize the relax table. We use a local variable to avoid
+ warnings about modifying a supposedly const data structure. */
+ table = (relax_typeS *) md_relax_table;
+ table[C (COND_BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
+ table[C (COND_BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
+ table[C (COND_BRANCH, BYTE_DISP)].rlx_length = 2;
+ table[C (COND_BRANCH, BYTE_DISP)].rlx_more = C (COND_BRANCH, WORD_DISP);
+
+ table[C (COND_BRANCH, WORD_DISP)].rlx_forward = WORD_F;
+ table[C (COND_BRANCH, WORD_DISP)].rlx_backward = WORD_B;
+ table[C (COND_BRANCH, WORD_DISP)].rlx_length = 5;
+ table[C (COND_BRANCH, WORD_DISP)].rlx_more = 0;
+
+ table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
+ table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
+ table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_length = 2;
+ table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_more = C (UNCOND_BRANCH, WORD_DISP);
+
+ table[C (UNCOND_BRANCH, WORD_DISP)].rlx_forward = WORD_F;
+ table[C (UNCOND_BRANCH, WORD_DISP)].rlx_backward = WORD_B;
+ table[C (UNCOND_BRANCH, WORD_DISP)].rlx_length = 3;
+ table[C (UNCOND_BRANCH, WORD_DISP)].rlx_more = 0;
+
+ flag_signed_overflow_ok = 1;
+}
+
+static expressionS immediate; /* absolute expression */
+static expressionS immediate1; /* absolute expression */
+
+
+static symbolS *
+dot ()
+{
+ const char *fake;
+
+ /* JF: '.' is pseudo symbol with value of current location
+ in current segment. */
+ fake = FAKE_LABEL_NAME;
+ return symbol_new (fake,
+ now_seg,
+ (valueT) frag_now_fix (),
+ frag_now);
+
+}
+
+int expr_size;
+int expr_shift;
+int tc_cons_reloc;
+void
+w65_expression (dest, bytes)
+ expressionS *dest;
+ unsigned int bytes;
+{
+ expr_size = 0;
+ expr_shift = 0;
+ tc_cons_reloc = 0;
+ while (*input_line_pointer == ' ')
+ input_line_pointer++;
+
+ if (*input_line_pointer == '<')
+ {
+ expr_size = 1;
+ input_line_pointer++;
+ }
+ else if (*input_line_pointer == '>')
+ {
+ expr_shift = 1;
+ input_line_pointer++;
+ }
+ else if (*input_line_pointer == '^')
+ {
+ expr_shift = 2;
+ input_line_pointer++;
+ }
+
+ expr (0, dest);
+}
+
+int amode;
+static
+char *
+parse_exp (s, bytes)
+ char *s;
+ int bytes;
+{
+ char *save;
+ char *new;
+
+ save = input_line_pointer;
+ input_line_pointer = s;
+ w65_expression (&immediate, bytes);
+ if (immediate.X_op == O_absent)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+
+static
+char *
+get_operands (info, ptr)
+ struct opinfo *info;
+ char *ptr;
+{
+ register int override_len = 0;
+ register int bytes = 0;
+ while (*ptr == ' ')
+ ptr++;
+
+ if (ptr[0] == '#')
+ {
+ ptr++;
+ switch (info->amode)
+ {
+ case ADDR_IMMTOI:
+ bytes = X ? 1 : 2;
+ amode = ADDR_IMMTOI;
+ break;
+ case ADDR_IMMTOA:
+ bytes = M ? 1 : 2;
+ amode = ADDR_IMMTOA;
+ break;
+ case ADDR_IMMCOP:
+ bytes = 1;
+ amode = ADDR_IMMCOP;
+ break;
+ case ADDR_DIR:
+ bytes = 2;
+ amode = ADDR_ABS;
+ break;
+ default:
+ abort ();
+ break;
+ }
+ ptr = parse_exp (ptr);
+ }
+ else if (ptr[0] == '!')
+ {
+ ptr = parse_exp (ptr + 1);
+ if (ptr[0] == ',')
+ {
+ if (ptr[1] == 'y')
+ {
+ amode = ADDR_ABS_IDX_Y;
+ bytes = 2;
+ ptr += 2;
+ }
+ else if (ptr[1] == 'x')
+ {
+ amode = ADDR_ABS_IDX_X;
+ bytes = 2;
+ ptr += 2;
+ }
+ else
+ {
+ as_bad (_("syntax error after <exp"));
+ }
+ }
+ else
+ {
+ amode = ADDR_ABS;
+ bytes = 2;
+ }
+ }
+ else if (ptr[0] == '>')
+ {
+ ptr = parse_exp (ptr + 1);
+ if (ptr[0] == ',' && ptr[1] == 'x')
+ {
+ amode = ADDR_ABS_LONG_IDX_X;
+ bytes = 3;
+ ptr += 2;
+ }
+ else
+ {
+ amode = ADDR_ABS_LONG;
+ bytes = 3;
+ }
+ }
+ else if (ptr[0] == '<')
+ {
+ ptr = parse_exp (ptr + 1);
+ if (ptr[0] == ',')
+ {
+ if (ptr[1] == 'y')
+ {
+ amode = ADDR_DIR_IDX_Y;
+ ptr += 2;
+ bytes = 2;
+ }
+ else if (ptr[1] == 'x')
+ {
+ amode = ADDR_DIR_IDX_X;
+ ptr += 2;
+ bytes = 2;
+ }
+ else
+ {
+ as_bad (_("syntax error after <exp"));
+ }
+ }
+ else
+ {
+ amode = ADDR_DIR;
+ bytes = 1;
+ }
+ }
+ else if (ptr[0] == 'a')
+ {
+ amode = ADDR_ACC;
+ }
+ else if (ptr[0] == '(')
+ {
+ /* Look for (exp),y
+ (<exp),y
+ (exp,x)
+ (<exp,x)
+ (exp)
+ (!exp)
+ (exp)
+ (<exp)
+ (exp,x)
+ (!exp,x)
+ (exp,s)
+ (exp,s),y */
+
+ ptr++;
+ if (ptr[0] == '<')
+ {
+ override_len = 1;
+ ptr++;
+ }
+ else if (ptr[0] == '!')
+ {
+ override_len = 2;
+ ptr++;
+ }
+ else if (ptr[0] == '>')
+ {
+ override_len = 3;
+ ptr++;
+ }
+ else
+ {
+ override_len = 0;
+ }
+ ptr = parse_exp (ptr);
+
+ if (ptr[0] == ',')
+ {
+ ptr++;
+ if (ptr[0] == 'x' && ptr[1] == ')')
+ {
+ ptr += 2;
+
+ if (override_len == 1)
+ {
+ amode = ADDR_DIR_IDX_IND_X;
+ bytes = 2;
+ }
+ else
+ {
+ amode = ADDR_ABS_IND_IDX;
+ bytes = 2;
+ }
+ }
+ else if (ptr[0] == 's' && ptr[1] == ')' && ptr[2] == ',' && ptr[3] == 'y')
+ {
+ amode = ADDR_STACK_REL_INDX_IDX;
+ bytes = 1;
+ ptr += 4;
+ }
+ }
+ else if (ptr[0] == ')')
+ {
+ if (ptr[1] == ',' && ptr[2] == 'y')
+ {
+ amode = ADDR_DIR_IND_IDX_Y;
+ ptr += 3;
+ bytes = 2;
+ }
+ else
+ {
+ if (override_len == 1)
+ {
+ amode = ADDR_DIR_IND;
+ bytes = 1;
+ }
+ else
+ {
+ amode = ADDR_ABS_IND;
+ bytes = 2;
+ }
+ ptr++;
+
+ }
+ }
+
+ }
+ else if (ptr[0] == '[')
+ {
+ ptr = parse_exp (ptr + 1);
+ if (ptr[0] == ']')
+ {
+ ptr++;
+ if (ptr[0] == ',' && ptr[1] == 'y')
+ {
+ bytes = 1;
+ amode = ADDR_DIR_IND_IDX_Y_LONG;
+ ptr += 2;
+ }
+ else
+ {
+ if (info->code == O_jmp)
+ {
+ bytes = 2;
+ amode = ADDR_ABS_IND_LONG;
+ }
+ else
+{
+ bytes = 1;
+
+ amode = ADDR_DIR_IND_LONG;
+ }
+ }
+ }
+ }
+ else
+ {
+ ptr = parse_exp (ptr, 2);
+ if (ptr[0] == ',')
+ {
+ if (ptr[1] == 'y')
+ {
+ if (override_len == 1)
+ {
+ bytes = 1;
+ amode = ADDR_DIR_IDX_Y;
+ }
+ else
+ {
+ amode = ADDR_ABS_IDX_Y;
+ bytes = 2;
+ }
+ ptr += 2;
+ }
+ else if (ptr[1] == 'x')
+ {
+ if (override_len == 1)
+ {
+ amode = ADDR_DIR_IDX_X;
+ bytes = 1;
+ }
+ else
+ {
+ amode = ADDR_ABS_IDX_X;
+ bytes = 2;
+ }
+ ptr += 2;
+ }
+ else if (ptr[1] == 's')
+ {
+ bytes = 1;
+ amode = ADDR_STACK_REL;
+ ptr += 2;
+ }
+ else
+ {
+ bytes = 1;
+ immediate1 = immediate;
+ ptr = parse_exp (ptr + 1);
+ amode = ADDR_BLOCK_MOVE;
+ }
+ }
+ else
+ {
+ switch (info->amode)
+ {
+ case ADDR_PC_REL:
+ amode = ADDR_PC_REL;
+ bytes = 1;
+ break;
+ case ADDR_PC_REL_LONG:
+ amode = ADDR_PC_REL_LONG;
+ bytes = 2;
+ break;
+ default:
+ if (override_len == 1)
+ {
+ amode = ADDR_DIR;
+ bytes = 1;
+ }
+ else if (override_len == 3)
+ {
+ bytes = 3;
+ amode = ADDR_ABS_LONG;
+ }
+ else
+ {
+ amode = ADDR_ABS;
+ bytes = 2;
+ }
+ }
+ }
+ }
+
+ switch (bytes)
+ {
+ case 1:
+ switch (expr_shift)
+ {
+ case 0:
+ if (amode == ADDR_DIR)
+ tc_cons_reloc = R_W65_DP;
+ else
+tc_cons_reloc = R_W65_ABS8;
+ break;
+ case 1:
+ tc_cons_reloc = R_W65_ABS8S8;
+ break;
+ case 2:
+ tc_cons_reloc = R_W65_ABS8S16;
+ break;
+ }
+ break;
+ case 2:
+ switch (expr_shift)
+ {
+ case 0:
+ tc_cons_reloc = R_W65_ABS16;
+ break;
+ case 1:
+ tc_cons_reloc = R_W65_ABS16S8;
+ break;
+ case 2:
+ tc_cons_reloc = R_W65_ABS16S16;
+ break;
+ }
+ }
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes, return the opcode which matches the opcodes
+ provided
+ */
+
+static
+struct opinfo *
+get_specific (opcode)
+ struct opinfo *opcode;
+{
+ int ocode = opcode->code;
+
+ for (; opcode->code == ocode; opcode++)
+ {
+ if (opcode->amode == amode)
+ return opcode;
+ }
+ return 0;
+}
+
+int
+check (operand, low, high)
+ expressionS *operand;
+ int low;
+ int high;
+{
+ if (operand->X_op != O_constant
+ || operand->X_add_number < low
+ || operand->X_add_number > high)
+ {
+ as_bad ("operand must be absolute in range %d..%d", low, high);
+ }
+ return operand->X_add_number;
+}
+
+
+static int log2[] =
+{0, 0, 1, 0, 2};
+
+/* Now we know what sort of opcodes it is, lets build the bytes -
+ */
+static void
+build_Mytes (opcode)
+ struct opinfo *opcode;
+{
+ int size;
+ int type;
+ int pcrel;
+ char *output;
+
+ if (opcode->amode == ADDR_IMPLIED)
+ {
+ output = frag_more (1);
+ }
+ else if (opcode->amode == ADDR_PC_REL)
+ {
+ int type;
+ /* This is a relaxable insn, so we do some special handling */
+ type = opcode->val == OP_BRA ? UNCOND_BRANCH : COND_BRANCH;
+ output = frag_var (rs_machine_dependent,
+ md_relax_table[C (type, WORD_DISP)].rlx_length,
+ md_relax_table[C (type, BYTE_DISP)].rlx_length,
+ C (type, UNDEF_BYTE_DISP),
+ immediate.X_add_symbol,
+ immediate.X_add_number,
+ 0);
+ }
+ else
+ {
+ switch (opcode->amode)
+ {
+ GETINFO (size, type, pcrel);
+ }
+
+ /* If something special was done in the
+ expression modify the reloc type */
+ if (tc_cons_reloc)
+ {
+ type = tc_cons_reloc;
+ }
+
+
+
+ /* 1 byte for the opcode + the bytes for the addrmode */
+ output = frag_more (size + 1);
+
+ if (opcode->amode == ADDR_BLOCK_MOVE)
+ {
+ /* Two relocs for this one */
+ fix_new_exp (frag_now,
+ output + 1 - frag_now->fr_literal,
+ 1,
+ &immediate,
+ 0,
+ R_W65_ABS8S16);
+
+ fix_new_exp (frag_now,
+ output + 2 - frag_now->fr_literal,
+ 1,
+ &immediate1,
+ 0,
+ R_W65_ABS8S16);
+ }
+ else if (type >= 0
+ && opcode->amode != ADDR_IMPLIED
+ && opcode->amode != ADDR_ACC
+ && opcode->amode != ADDR_STACK)
+ {
+ fix_new_exp (frag_now,
+ output + 1 - frag_now->fr_literal,
+ size,
+ &immediate,
+ pcrel,
+ type);
+ }
+ }
+ output[0] = opcode->val;
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This function is supposed to emit
+ the frags/bytes it assembles to.
+ */
+
+void
+md_assemble (str)
+ char *str;
+{
+ unsigned char *op_start;
+ unsigned char *op_end;
+ struct opinfo *opcode;
+ char name[20];
+ int nlen = 0;
+ char *p;
+
+ /* Drop leading whitespace */
+ while (*str == ' ')
+ str++;
+
+ /* all opcodes are three letters */
+ name[0] = str[0];
+ name[1] = str[1];
+ name[2] = str[2];
+ name[3] = 0;
+
+ tc_cons_reloc = 0;
+ str += 3;
+ opcode = (struct opinfo *) hash_find (opcode_hash_control, name);
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ if (opcode->amode != ADDR_IMPLIED
+ && opcode->amode != ADDR_STACK)
+ {
+ get_operands (opcode, str);
+ opcode = get_specific (opcode);
+ }
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands */
+
+
+ char *where = frag_more (1);
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+ as_bad (_("invalid operands for opcode"));
+ return;
+ }
+
+ build_Mytes (opcode);
+}
+
+
+void
+DEFUN (tc_crawl_symbol_chain, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+symbolS *
+DEFUN (md_undefined_symbol, (name),
+ char *name)
+{
+ return 0;
+}
+
+void
+DEFUN (tc_headers_hook, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+/* Various routines to kill one day */
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_NTOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words + prec - 1; prec--;)
+ {
+ md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+int
+md_parse_option (c,a)
+ int c;
+ char *a;
+
+{
+ return 1;
+}
+
+void
+tc_Nout_fix_to_chars ()
+{
+ printf (_("call to tc_Nout_fix_to_chars \n"));
+ abort ();
+}
+
+/*
+called after relaxing, change the frags so they know how big they are
+*/
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ int disp_size = 0;
+ int inst_size = 0;
+ unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
+ switch (fragP->fr_subtype)
+ {
+ case C (COND_BRANCH, BYTE_DISP):
+ case C (UNCOND_BRANCH, BYTE_DISP):
+ disp_size = 1;
+ inst_size = 1;
+ break;
+
+ /* cond branches to a known 16 bit displacement */
+ case C (COND_BRANCH, WORD_DISP):
+ switch (buffer[0])
+ {
+ case OP_BCC:
+ case OP_BCS:
+ case OP_BEQ:
+ case OP_BMI:
+ case OP_BNE:
+ case OP_BPL:
+ case OP_BVS:
+ case OP_BVC:
+ /* Invert the sense of the test */
+ buffer[0] ^= 0x20;
+ buffer[1] = 3; /* Jump over following brl */
+ buffer[2] = OP_BRL;
+ buffer[3] = 0;
+ buffer[4] = 0;
+ disp_size = 2;
+ inst_size = 3;
+ break;
+ default:
+ abort ();
+ }
+ break;
+ case C (UNCOND_BRANCH, WORD_DISP):
+ /* Unconditional branches to a known 16 bit displacement */
+
+ switch (buffer[0])
+ {
+ case OP_BRA:
+ buffer[0] = OP_BRL;
+ disp_size = 2;
+ inst_size = 1;
+ break;
+ default:
+ abort ();
+ }
+ break;
+ /* got to create a branch over a reloc here */
+ case C (COND_BRANCH, UNDEF_WORD_DISP):
+ buffer[0] ^= 0x20; /* invert test */
+ buffer[1] = 3;
+ buffer[2] = OP_BRL;
+ buffer[3] = 0;
+ buffer[4] = 0;
+ fix_new (fragP,
+ fragP->fr_fix + 3,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 0,
+ R_W65_PCR16);
+
+ fragP->fr_fix += disp_size + inst_size;
+ fragP->fr_var = 0;
+ break;
+ case C (UNCOND_BRANCH, UNDEF_WORD_DISP):
+ buffer[0] = OP_BRL;
+ buffer[1] = 0;
+ buffer[2] = 0;
+ fix_new (fragP,
+ fragP->fr_fix + 1,
+ 4,
+ fragP->fr_symbol,
+ fragP->fr_offset,
+ 0,
+ R_W65_PCR16);
+
+ fragP->fr_fix += disp_size + inst_size;
+ fragP->fr_var = 0;
+ break;
+ default:
+ abort ();
+ }
+ if (inst_size)
+ {
+ /* Get the address of the end of the instruction */
+ int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size;
+ int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
+ fragP->fr_offset);
+ int disp = targ_addr - next_inst;
+
+ md_number_to_chars (buffer + inst_size, disp, disp_size);
+ fragP->fr_fix += disp_size + inst_size;
+ fragP->fr_var = 0;
+ }
+}
+
+
+valueT
+DEFUN (md_section_align, (seg, size),
+ segT seg AND
+ valueT size)
+{
+ return ((size + (1 << section_alignment[(int) seg]) - 1)
+ & (-1 << section_alignment[(int) seg]));
+
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+ int addr = fixP->fx_frag->fr_address + fixP->fx_where;
+
+ if (fixP->fx_r_type == 0)
+ {
+ if (fixP->fx_size == 1)
+ fixP->fx_r_type = R_W65_ABS8;
+ else
+ fixP->fx_r_type = R_W65_ABS16;
+ }
+
+ switch (fixP->fx_r_type)
+ {
+ case R_W65_ABS8S16:
+ val >>= 8;
+ case R_W65_ABS8S8:
+ val >>= 8;
+ case R_W65_ABS8:
+ *buf++ = val;
+ break;
+ case R_W65_ABS16S16:
+ val >>= 8;
+ case R_W65_ABS16S8:
+ val >>= 8;
+ case R_W65_ABS16:
+ *buf++ = val >> 0;
+ *buf++ = val >> 8;
+ break;
+ case R_W65_ABS24:
+ *buf++ = val >> 0;
+ *buf++ = val >> 8;
+ *buf++ = val >> 16;
+ break;
+ case R_W65_PCR8:
+ *buf++ = val - addr - 1;
+ break;
+ case R_W65_PCR16:
+ val = val - addr - 1;
+ *buf++ = val;
+ *buf++ = val >> 8;
+ break;
+ case R_W65_DP:
+ *buf++ = val;
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Put number into target byte order */
+
+void
+md_number_to_chars (ptr, use, nbytes)
+ char *ptr;
+ valueT use;
+ int nbytes;
+{
+ number_to_chars_littleendian (ptr, use, nbytes);
+}
+
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ int gap = fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address - 1;
+ return gap;
+}
+
+void
+tc_coff_symbol_emit_hook (x)
+ struct symbol *x;
+{
+}
+
+short
+tc_coff_fix2rtype (fix_ptr)
+ fixS *fix_ptr;
+{
+ return fix_ptr->fx_r_type;
+}
+
+void
+tc_reloc_mangle (fix_ptr, intr, base)
+ fixS *fix_ptr;
+ struct internal_reloc *intr;
+ bfd_vma base;
+
+{
+ symbolS *symbol_ptr;
+
+ symbol_ptr = fix_ptr->fx_addsy;
+
+ /* If this relocation is attached to a symbol then it's ok
+ to output it */
+ if (fix_ptr->fx_r_type == RELOC_32)
+ {
+ /* cons likes to create reloc32's whatever the size of the reloc..
+ */
+ switch (fix_ptr->fx_size)
+ {
+ case 2:
+ intr->r_type = R_IMM16;
+ break;
+ case 1:
+ intr->r_type = R_IMM8;
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ if (fix_ptr->fx_size == 4)
+ intr->r_type = R_W65_ABS24;
+ else
+ intr->r_type = fix_ptr->fx_r_type;
+ }
+
+ intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
+ intr->r_offset = fix_ptr->fx_offset;
+
+ /* Turn the segment of the symbol into an offset. */
+ if (symbol_ptr)
+ {
+ symbolS *dot;
+
+ dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
+ if (dot)
+ {
+ intr->r_offset += S_GET_VALUE (symbol_ptr);
+ intr->r_symndx = dot->sy_number;
+ }
+ else
+ {
+ intr->r_symndx = symbol_ptr->sy_number;
+ }
+ }
+ else
+ {
+ intr->r_symndx = -1;
+ }
+}
+
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ return md_relax_table[frag->fr_subtype].rlx_length;
+}
+
+
+
+
+
+/*
+called just before address relaxation, return the length
+by which a fragment must grow to reach it's destination
+*/
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ int what = GET_WHAT (fragP->fr_subtype);
+
+ switch (fragP->fr_subtype)
+ {
+ default:
+ abort ();
+ case C (COND_BRANCH, UNDEF_BYTE_DISP):
+ case C (UNCOND_BRANCH, UNDEF_BYTE_DISP):
+ /* used to be a branch to somewhere which was unknown */
+ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
+ {
+ /* Got a symbol and it's defined in this segment, become byte
+ sized - maybe it will fix up */
+ fragP->fr_subtype = C (what, BYTE_DISP);
+ fragP->fr_var = md_relax_table[C (what, BYTE_DISP)].rlx_length;
+ }
+ else
+ {
+ /* Its got a segment, but its not ours, so it will always be long */
+ fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
+ fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
+ return md_relax_table[C (what, WORD_DISP)].rlx_length;
+ }
+ }
+ return fragP->fr_var;
+}
+
+
+
+CONST char *md_shortopts = "";
+struct option md_longopts[] = {
+#define OPTION_RELAX (OPTION_MD_BASE)
+ {NULL, no_argument, NULL, 0}
+};
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+
+}
+
+size_t md_longopts_size = sizeof(md_longopts);
diff --git a/gas/config/tc-w65.h b/gas/config/tc-w65.h
new file mode 100644
index 00000000000..9794ad2eb5c
--- /dev/null
+++ b/gas/config/tc-w65.h
@@ -0,0 +1,61 @@
+/* This file is tc-w65.h
+ Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+#define TC_W65
+
+#define TARGET_BYTES_BIG_ENDIAN 0
+
+#if ANSI_PROTOTYPES
+struct internal_reloc;
+#endif
+
+#define WORKING_DOT_WORD
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
+
+#define BFD_ARCH bfd_arch_w65
+#define COFF_MAGIC 0x6500
+
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
+extern void tc_reloc_mangle
+ PARAMS ((struct fix *, struct internal_reloc *, bfd_vma));
+
+#define DO_NOT_STRIP 0
+#define LISTING_HEADER "W65816 GAS "
+#define NEED_FX_R_TYPE 1
+#define RELOC_32 1234
+
+#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) w65_expression (EXP, NBYTES)
+#define TC_COUNT_RELOC(x) (1)
+#define TC_CONS_RELOC tc_cons_reloc
+#define DONT_OVERFLOW
+int tc_cons_reloc;
+
+#define md_operand(x)
+
+extern struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+/* end of tc-w65.h */
diff --git a/gas/config/tc-z8k.c b/gas/config/tc-z8k.c
new file mode 100644
index 00000000000..16113414f00
--- /dev/null
+++ b/gas/config/tc-z8k.c
@@ -0,0 +1,1589 @@
+/* tc-z8k.c -- Assemble code for the Zilog Z800n
+ Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ Written By Steve Chamberlain
+ sac@cygnus.com
+ */
+#define DEFINE_TABLE
+#include <stdio.h>
+
+#include "opcodes/z8k-opc.h"
+
+#include "as.h"
+#include "bfd.h"
+#include <ctype.h>
+
+const char comment_chars[] =
+{'!', 0};
+const char line_separator_chars[] =
+{';', 0};
+const char line_comment_chars[] =
+{'#', 0};
+
+extern int machine;
+extern int coff_flags;
+int segmented_mode;
+const int md_reloc_size;
+
+/* This table describes all the machine specific pseudo-ops the assembler
+ has to support. The fields are:
+ pseudo-op name without dot
+ function to call to execute this pseudo-op
+ Integer arg to pass to the function
+ */
+
+void cons ();
+
+void
+s_segm ()
+{
+ segmented_mode = 1;
+ machine = bfd_mach_z8001;
+ coff_flags = F_Z8001;
+}
+
+void
+s_unseg ()
+{
+ segmented_mode = 0;
+ machine = bfd_mach_z8002;
+ coff_flags = F_Z8002;
+}
+
+static
+void
+even ()
+{
+ frag_align (1, 0, 0);
+ record_alignment (now_seg, 1);
+}
+
+void obj_coff_section ();
+
+int
+tohex (c)
+ int c;
+{
+ if (isdigit (c))
+ return c - '0';
+ if (islower (c))
+ return c - 'a' + 10;
+ return c - 'A' + 10;
+}
+
+void
+sval ()
+{
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\'')
+ {
+ int c;
+ input_line_pointer++;
+ c = *input_line_pointer++;
+ while (c != '\'')
+ {
+ if (c == '%')
+ {
+ c = (tohex (input_line_pointer[0]) << 4)
+ | tohex (input_line_pointer[1]);
+ input_line_pointer += 2;
+ }
+ FRAG_APPEND_1_CHAR (c);
+ c = *input_line_pointer++;
+ }
+ demand_empty_rest_of_line ();
+ }
+
+}
+const pseudo_typeS md_pseudo_table[] =
+{
+ {"int", cons, 2},
+ {"data.b", cons, 1},
+ {"data.w", cons, 2},
+ {"data.l", cons, 4},
+ {"form", listing_psize, 0},
+ {"heading", listing_title, 0},
+ {"import", s_ignore, 0},
+ {"page", listing_eject, 0},
+ {"program", s_ignore, 0},
+ {"z8001", s_segm, 0},
+ {"z8002", s_unseg, 0},
+
+
+ {"segm", s_segm, 0},
+ {"unsegm", s_unseg, 0},
+ {"unseg", s_unseg, 0},
+ {"name", s_app_file, 0},
+ {"global", s_globl, 0},
+ {"wval", cons, 2},
+ {"lval", cons, 4},
+ {"bval", cons, 1},
+ {"sval", sval, 0},
+ {"rsect", obj_coff_section, 0},
+ {"sect", obj_coff_section, 0},
+ {"block", s_space, 0},
+ {"even", even, 0},
+ {0, 0, 0}
+};
+
+const char EXP_CHARS[] = "eE";
+
+/* Chars that mean this number is a floating point constant */
+/* As in 0f12.456 */
+/* or 0d1.2345e12 */
+const char FLT_CHARS[] = "rRsSfFdDxXpP";
+
+static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
+
+void
+md_begin ()
+{
+ opcode_entry_type *opcode;
+ char *prev_name = "";
+ int idx = 0;
+
+ opcode_hash_control = hash_new ();
+
+ for (opcode = z8k_table; opcode->name; opcode++)
+ {
+ /* Only enter unique codes into the table */
+ char *src = opcode->name;
+
+ if (strcmp (opcode->name, prev_name))
+ {
+ hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ idx++;
+ }
+ opcode->idx = idx;
+ prev_name = opcode->name;
+ }
+
+ /* default to z8002 */
+ s_unseg ();
+
+ /* insert the pseudo ops too */
+ for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
+ {
+ opcode_entry_type *fake_opcode;
+ fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
+ fake_opcode->name = md_pseudo_table[idx].poc_name,
+ fake_opcode->func = (void *) (md_pseudo_table + idx);
+ fake_opcode->opcode = 250;
+ hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
+ }
+
+ linkrelax = 1;
+}
+
+struct z8k_exp
+{
+ char *e_beg;
+ char *e_end;
+ expressionS e_exp;
+};
+typedef struct z8k_op
+{
+ char regsize; /* 'b','w','r','q' */
+ unsigned int reg; /* 0..15 */
+
+ int mode;
+
+ unsigned int x_reg; /* any other register associated with the mode */
+ expressionS exp; /* any expression */
+}
+
+op_type;
+
+static expressionS *da_operand;
+static expressionS *imm_operand;
+
+int reg[16];
+int the_cc;
+int the_ctrl;
+int the_flags;
+int the_interrupt;
+
+char *
+DEFUN (whatreg, (reg, src),
+ int *reg AND
+ char *src)
+{
+ if (isdigit (src[1]))
+ {
+ *reg = (src[0] - '0') * 10 + src[1] - '0';
+ return src + 2;
+ }
+ else
+ {
+ *reg = (src[0] - '0');
+ return src + 1;
+ }
+}
+
+/*
+ parse operands
+
+ rh0-rh7, rl0-rl7
+ r0-r15
+ rr0-rr14
+ rq0--rq12
+ WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
+ r0l,r0h,..r7l,r7h
+ @WREG
+ @WREG+
+ @-WREG
+ #const
+
+ */
+
+/* try and parse a reg name, returns number of chars consumed */
+char *
+DEFUN (parse_reg, (src, mode, reg),
+ char *src AND
+ int *mode AND
+ unsigned int *reg)
+{
+ char *res = 0;
+ char regno;
+
+ if (src[0] == 's' && src[1] == 'p')
+ {
+ if (segmented_mode)
+ {
+ *mode = CLASS_REG_LONG;
+ *reg = 14;
+ }
+ else
+ {
+ *mode = CLASS_REG_WORD;
+ *reg = 15;
+ }
+ return src + 2;
+ }
+ if (src[0] == 'r')
+ {
+ if (src[1] == 'r')
+ {
+ *mode = CLASS_REG_LONG;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 14)
+ as_warn (_("register rr%d, out of range."),regno);
+ }
+ else if (src[1] == 'h')
+ {
+ *mode = CLASS_REG_BYTE;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 7)
+ as_warn (_("register rh%d, out of range."),regno);
+ }
+ else if (src[1] == 'l')
+ {
+ *mode = CLASS_REG_BYTE;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 7)
+ as_warn (_("register rl%d, out of range."),regno);
+ *reg += 8;
+ }
+ else if (src[1] == 'q')
+ {
+ *mode = CLASS_REG_QUAD;
+ res = whatreg (reg, src + 2);
+ regno = *reg;
+ if (regno > 12)
+ as_warn (_("register rq%d, out of range."),regno);
+ }
+ else
+ {
+ *mode = CLASS_REG_WORD;
+ res = whatreg (reg, src + 1);
+ regno = *reg;
+ if (regno > 15)
+ as_warn (_("register r%d, out of range."),regno);
+ }
+ }
+ return res;
+
+}
+
+char *
+DEFUN (parse_exp, (s, op),
+ char *s AND
+ expressionS * op)
+{
+ char *save = input_line_pointer;
+ char *new;
+
+ input_line_pointer = s;
+ expression (op);
+ if (op->X_op == O_absent)
+ as_bad (_("missing operand"));
+ new = input_line_pointer;
+ input_line_pointer = save;
+ return new;
+}
+
+/* The many forms of operand:
+
+ <rb>
+ <r>
+ <rr>
+ <rq>
+ @r
+ #exp
+ exp
+ exp(r)
+ r(#exp)
+ r(r)
+
+
+
+ */
+
+static
+char *
+DEFUN (checkfor, (ptr, what),
+ char *ptr AND
+ char what)
+{
+ if (*ptr == what)
+ ptr++;
+ else
+ {
+ as_bad (_("expected %c"), what);
+ }
+ return ptr;
+}
+
+/* Make sure the mode supplied is the size of a word */
+static void
+DEFUN (regword, (mode, string),
+ int mode AND
+ char *string)
+{
+ int ok;
+
+ ok = CLASS_REG_WORD;
+ if (ok != mode)
+ {
+ as_bad (_("register is wrong size for a word %s"), string);
+ }
+}
+
+/* Make sure the mode supplied is the size of an address */
+static void
+DEFUN (regaddr, (mode, string),
+ int mode AND
+ char *string)
+{
+ int ok;
+
+ ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
+ if (ok != mode)
+ {
+ as_bad (_("register is wrong size for address %s"), string);
+ }
+}
+
+struct ctrl_names
+{
+ int value;
+ char *name;
+};
+
+struct ctrl_names ctrl_table[] =
+{
+ 0x2, "fcw",
+ 0X3, "refresh",
+ 0x4, "psapseg",
+ 0x5, "psapoff",
+ 0x5, "psap",
+ 0x6, "nspseg",
+ 0x7, "nspoff",
+ 0x7, "nsp",
+ 0, 0
+};
+
+static void
+DEFUN (get_ctrl_operand, (ptr, mode, dst),
+ char **ptr AND
+ struct z8k_op *mode AND
+ unsigned int dst)
+{
+ char *src = *ptr;
+ int r;
+ int i;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_CTRL;
+ for (i = 0; ctrl_table[i].name; i++)
+ {
+ int j;
+
+ for (j = 0; ctrl_table[i].name[j]; j++)
+ {
+ if (ctrl_table[i].name[j] != src[j])
+ goto fail;
+ }
+ the_ctrl = ctrl_table[i].value;
+ *ptr = src + j;
+ return;
+ fail:;
+ }
+ the_ctrl = 0;
+ return;
+}
+
+struct flag_names
+{
+ int value;
+ char *name;
+
+};
+
+struct flag_names flag_table[] =
+{
+ 0x1, "p",
+ 0x1, "v",
+ 0x2, "s",
+ 0x4, "z",
+ 0x8, "c",
+ 0x0, "+",
+ 0, 0
+};
+
+static void
+DEFUN (get_flags_operand, (ptr, mode, dst),
+ char **ptr AND
+ struct z8k_op *mode AND
+ unsigned int dst)
+{
+ char *src = *ptr;
+ int r;
+ int i;
+ int j;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_FLAGS;
+ the_flags = 0;
+ for (j = 0; j <= 9; j++)
+ {
+ if (!src[j])
+ goto done;
+ for (i = 0; flag_table[i].name; i++)
+ {
+ if (flag_table[i].name[0] == src[j])
+ {
+ the_flags = the_flags | flag_table[i].value;
+ goto match;
+ }
+ }
+ goto done;
+ match:
+ ;
+ }
+ done:
+ *ptr = src + j;
+ return;
+}
+
+
+struct interrupt_names
+{
+ int value;
+ char *name;
+
+};
+
+struct interrupt_names intr_table[] =
+{
+ 0x1, "nvi",
+ 0x2, "vi",
+ 0x3, "both",
+ 0x3, "all",
+ 0, 0
+};
+
+static void
+DEFUN (get_interrupt_operand, (ptr, mode, dst),
+ char **ptr AND
+ struct z8k_op *mode AND
+ unsigned int dst)
+{
+ char *src = *ptr;
+ int r;
+ int i;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_IMM;
+ for (i = 0; intr_table[i].name; i++)
+ {
+ int j;
+
+ for (j = 0; intr_table[i].name[j]; j++)
+ {
+ if (intr_table[i].name[j] != src[j])
+ goto fail;
+ }
+ the_interrupt = intr_table[i].value;
+ *ptr = src + j;
+ return;
+ fail:;
+ }
+ the_interrupt = 0x0;
+ return;
+}
+
+struct cc_names
+{
+ int value;
+ char *name;
+
+};
+
+struct cc_names table[] =
+{
+ 0x0, "f",
+ 0x1, "lt",
+ 0x2, "le",
+ 0x3, "ule",
+ 0x4, "ov",
+ 0x4, "pe",
+ 0x5, "mi",
+ 0x6, "eq",
+ 0x6, "z",
+ 0x7, "c",
+ 0x7, "ult",
+ 0x8, "t",
+ 0x9, "ge",
+ 0xa, "gt",
+ 0xb, "ugt",
+ 0xc, "nov",
+ 0xc, "po",
+ 0xd, "pl",
+ 0xe, "ne",
+ 0xe, "nz",
+ 0xf, "nc",
+ 0xf, "uge",
+ 0, 0
+};
+
+static void
+DEFUN (get_cc_operand, (ptr, mode, dst),
+ char **ptr AND
+ struct z8k_op *mode AND
+ unsigned int dst)
+{
+ char *src = *ptr;
+ int r;
+ int i;
+
+ while (*src == ' ')
+ src++;
+
+ mode->mode = CLASS_CC;
+ for (i = 0; table[i].name; i++)
+ {
+ int j;
+
+ for (j = 0; table[i].name[j]; j++)
+ {
+ if (table[i].name[j] != src[j])
+ goto fail;
+ }
+ the_cc = table[i].value;
+ *ptr = src + j;
+ return;
+ fail:;
+ }
+ the_cc = 0x8;
+}
+
+static void
+get_operand (ptr, mode, dst)
+ char **ptr;
+ struct z8k_op *mode;
+ unsigned int dst;
+{
+ char *src = *ptr;
+ char *end;
+ unsigned int num;
+ unsigned int len;
+ unsigned int size;
+
+ mode->mode = 0;
+
+ while (*src == ' ')
+ src++;
+ if (*src == '#')
+ {
+ mode->mode = CLASS_IMM;
+ imm_operand = &(mode->exp);
+ src = parse_exp (src + 1, &(mode->exp));
+ }
+ else if (*src == '@')
+ {
+ int d;
+
+ mode->mode = CLASS_IR;
+ src = parse_reg (src + 1, &d, &mode->reg);
+ }
+ else
+ {
+ int regn;
+
+ end = parse_reg (src, &mode->mode, &regn);
+
+ if (end)
+ {
+ int nw, nr;
+
+ src = end;
+ if (*src == '(')
+ {
+ src++;
+ end = parse_reg (src, &nw, &nr);
+ if (end)
+ {
+ /* Got Ra(Rb) */
+ src = end;
+
+ if (*src != ')')
+ {
+ as_bad (_("Missing ) in ra(rb)"));
+ }
+ else
+ {
+ src++;
+ }
+
+ regaddr (mode->mode, "ra(rb) ra");
+/* regword (mode->mode, "ra(rb) rb");*/
+ mode->mode = CLASS_BX;
+ mode->reg = regn;
+ mode->x_reg = nr;
+ reg[ARG_RX] = nr;
+ }
+ else
+ {
+ /* Got Ra(disp) */
+ if (*src == '#')
+ src++;
+ src = parse_exp (src, &(mode->exp));
+ src = checkfor (src, ')');
+ mode->mode = CLASS_BA;
+ mode->reg = regn;
+ mode->x_reg = 0;
+ imm_operand = &(mode->exp);
+ }
+ }
+ else
+ {
+ mode->reg = regn;
+ mode->x_reg = 0;
+ }
+ }
+ else
+ {
+ /* No initial reg */
+ src = parse_exp (src, &(mode->exp));
+ if (*src == '(')
+ {
+ src++;
+ end = parse_reg (src, &(mode->mode), &regn);
+ regword (mode->mode, "addr(Ra) ra");
+ mode->mode = CLASS_X;
+ mode->reg = regn;
+ mode->x_reg = 0;
+ da_operand = &(mode->exp);
+ src = checkfor (end, ')');
+ }
+ else
+ {
+ /* Just an address */
+ mode->mode = CLASS_DA;
+ mode->reg = 0;
+ mode->x_reg = 0;
+ da_operand = &(mode->exp);
+ }
+ }
+ }
+ *ptr = src;
+}
+
+static
+char *
+get_operands (opcode, op_end, operand)
+ opcode_entry_type *opcode;
+ char *op_end;
+ op_type *operand;
+{
+ char *ptr = op_end;
+char *savptr;
+ switch (opcode->noperands)
+ {
+ case 0:
+ operand[0].mode = 0;
+ operand[1].mode = 0;
+ break;
+
+ case 1:
+ ptr++;
+ if (opcode->arg_info[0] == CLASS_CC)
+ {
+ get_cc_operand (&ptr, operand + 0, 0);
+ }
+ else if (opcode->arg_info[0] == CLASS_FLAGS)
+ {
+ get_flags_operand (&ptr, operand + 0, 0);
+ }
+ else if (opcode->arg_info[0] == (CLASS_IMM +(ARG_IMM2)))
+ {
+ get_interrupt_operand (&ptr, operand + 0, 0);
+ }
+ else
+ {
+ get_operand (&ptr, operand + 0, 0);
+ }
+ operand[1].mode = 0;
+ break;
+
+ case 2:
+ ptr++;
+ savptr = ptr;
+ if (opcode->arg_info[0] == CLASS_CC)
+ {
+ get_cc_operand (&ptr, operand + 0, 0);
+ }
+ else if (opcode->arg_info[0] == CLASS_CTRL)
+ {
+ get_ctrl_operand (&ptr, operand + 0, 0);
+ if (the_ctrl == 0)
+ {
+ ptr = savptr;
+ get_operand (&ptr, operand + 0, 0);
+ if (ptr == 0)
+ return;
+ if (*ptr == ',')
+ ptr++;
+ get_ctrl_operand (&ptr, operand + 1, 1);
+ return ptr;
+ }
+ }
+ else
+ {
+ get_operand (&ptr, operand + 0, 0);
+ }
+ if (ptr == 0)
+ return;
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1);
+ break;
+
+ case 3:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 2, 2);
+ break;
+
+ case 4:
+ ptr++;
+ get_operand (&ptr, operand + 0, 0);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 1, 1);
+ if (*ptr == ',')
+ ptr++;
+ get_operand (&ptr, operand + 2, 2);
+ if (*ptr == ',')
+ ptr++;
+ get_cc_operand (&ptr, operand + 3, 3);
+ break;
+ default:
+ abort ();
+ }
+
+ return ptr;
+}
+
+/* Passed a pointer to a list of opcodes which use different
+ addressing modes, return the opcode which matches the opcodes
+ provided
+ */
+
+static
+opcode_entry_type *
+DEFUN (get_specific, (opcode, operands),
+ opcode_entry_type * opcode AND
+ op_type * operands)
+
+{
+ opcode_entry_type *this_try = opcode;
+ int found = 0;
+ unsigned int noperands = opcode->noperands;
+
+ unsigned int dispreg;
+ unsigned int this_index = opcode->idx;
+
+ while (this_index == opcode->idx && !found)
+ {
+ unsigned int i;
+
+ this_try = opcode++;
+ for (i = 0; i < noperands; i++)
+ {
+ int mode = operands[i].mode;
+
+ if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
+ {
+ /* it could be an pc rel operand, if this is a da mode and
+ we like disps, then insert it */
+
+ if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
+ {
+ /* This is the case */
+ operands[i].mode = CLASS_DISP;
+ }
+ else if (mode == CLASS_BA && this_try->arg_info[i])
+ {
+ /* Can't think of a way to turn what we've been given into
+ something that's ok */
+ goto fail;
+ }
+ else if (this_try->arg_info[i] & CLASS_PR)
+ {
+ if (mode == CLASS_REG_LONG && segmented_mode)
+ {
+ /* ok */
+ }
+ else if (mode == CLASS_REG_WORD && !segmented_mode)
+ {
+ /* ok */
+ }
+ else
+ goto fail;
+ }
+ else
+ goto fail;
+ }
+ switch (mode & CLASS_MASK)
+ {
+ default:
+ break;
+ case CLASS_X:
+ case CLASS_IR:
+ case CLASS_BA:
+ case CLASS_BX:
+ case CLASS_DISP:
+ case CLASS_REG:
+ case CLASS_REG_WORD:
+ case CLASS_REG_BYTE:
+ case CLASS_REG_QUAD:
+ case CLASS_REG_LONG:
+ case CLASS_REGN0:
+ reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
+ break;
+ }
+ }
+
+ found = 1;
+ fail:;
+ }
+ if (found)
+ return this_try;
+ else
+ return 0;
+}
+
+static void
+DEFUN (check_operand, (operand, width, string),
+ struct z8k_op *operand AND
+ unsigned int width AND
+ char *string)
+{
+ if (operand->exp.X_add_symbol == 0
+ && operand->exp.X_op_symbol == 0)
+ {
+
+ /* No symbol involved, let's look at offset, it's dangerous if any of
+ the high bits are not 0 or ff's, find out by oring or anding with
+ the width and seeing if the answer is 0 or all fs*/
+ if ((operand->exp.X_add_number & ~width) != 0 &&
+ (operand->exp.X_add_number | width) != (~0))
+ {
+ as_warn (_("operand %s0x%x out of range."), string, operand->exp.X_add_number);
+ }
+ }
+
+}
+
+static char buffer[20];
+
+static void
+DEFUN (newfix, (ptr, type, operand),
+ int ptr AND
+ int type AND
+ expressionS * operand)
+{
+ if (operand->X_add_symbol
+ || operand->X_op_symbol
+ || operand->X_add_number)
+ {
+ fix_new_exp (frag_now,
+ ptr,
+ 1,
+ operand,
+ 0,
+ type);
+ }
+}
+
+static char *
+DEFUN (apply_fix, (ptr, type, operand, size),
+ char *ptr AND
+ int type AND
+ expressionS * operand AND
+ int size)
+{
+ int n = operand->X_add_number;
+
+ operand->X_add_number = n;
+ newfix ((ptr - buffer) / 2, type, operand);
+#if 1
+ switch (size)
+ {
+ case 8: /* 8 nibbles == 32 bits */
+ *ptr++ = n >> 28;
+ *ptr++ = n >> 24;
+ *ptr++ = n >> 20;
+ *ptr++ = n >> 16;
+ case 4: /* 4 niblles == 16 bits */
+ *ptr++ = n >> 12;
+ *ptr++ = n >> 8;
+ case 2:
+ *ptr++ = n >> 4;
+ case 1:
+ *ptr++ = n >> 0;
+ break;
+ }
+#endif
+ return ptr;
+
+}
+
+/* Now we know what sort of opcodes it is, lets build the bytes -
+ */
+#define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;
+static void
+build_bytes (this_try, operand)
+ opcode_entry_type * this_try;
+ struct z8k_op *operand;
+{
+ unsigned int i;
+
+ int length;
+ char *output;
+ char *output_ptr = buffer;
+ char part;
+ int c;
+ char high;
+ int nib;
+ int nibble;
+ unsigned int *class_ptr;
+
+ frag_wane (frag_now);
+ frag_new (0);
+
+ memset (buffer, 20, 0);
+ class_ptr = this_try->byte_info;
+top:;
+
+ for (nibble = 0; c = *class_ptr++; nibble++)
+ {
+
+ switch (c & CLASS_MASK)
+ {
+ default:
+
+ abort ();
+ case CLASS_ADDRESS:
+ /* Direct address, we don't cope with the SS mode right now */
+ if (segmented_mode)
+ {
+ da_operand->X_add_number |= 0x80000000;
+ output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);
+ }
+ else
+ {
+ output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+ }
+ da_operand = 0;
+ break;
+ case CLASS_DISP8:
+ /* pc rel 8 bit */
+ output_ptr = apply_fix (output_ptr, R_JR, da_operand, 2);
+ da_operand = 0;
+ break;
+
+ case CLASS_0DISP7:
+ /* pc rel 7 bit */
+ *output_ptr = 0;
+ output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
+ da_operand = 0;
+ break;
+
+ case CLASS_1DISP7:
+ /* pc rel 7 bit */
+ *output_ptr = 0x80;
+ output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);
+ output_ptr[-2] = 0x8;
+ da_operand = 0;
+ break;
+
+ case CLASS_BIT_1OR2:
+ *output_ptr = c & 0xf;
+ if (imm_operand)
+ {
+ if (imm_operand->X_add_number == 2)
+ {
+ *output_ptr |= 2;
+ }
+ else if (imm_operand->X_add_number != 1)
+ {
+ as_bad (_("immediate must be 1 or 2"));
+ }
+ }
+ else
+ {
+ as_bad (_("immediate 1 or 2 expected"));
+ }
+ output_ptr++;
+ break;
+ case CLASS_CC:
+ *output_ptr++ = the_cc;
+ break;
+ case CLASS_0CCC:
+ *output_ptr++ = the_ctrl;
+ break;
+ case CLASS_1CCC:
+ *output_ptr++ = the_ctrl | 0x8;
+ break;
+ case CLASS_00II:
+ *output_ptr++ = (~the_interrupt & 0x3);
+ break;
+ case CLASS_01II:
+ *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
+ break;
+ case CLASS_FLAGS:
+ *output_ptr++ = the_flags;
+ break;
+ case CLASS_BIT:
+ *output_ptr++ = c & 0xf;
+ break;
+ case CLASS_REGN0:
+ if (reg[c & 0xf] == 0)
+ {
+ as_bad (_("can't use R0 here"));
+ }
+ case CLASS_REG:
+ case CLASS_REG_BYTE:
+ case CLASS_REG_WORD:
+ case CLASS_REG_LONG:
+ case CLASS_REG_QUAD:
+ /* Insert bit mattern of
+ right reg */
+ *output_ptr++ = reg[c & 0xf];
+ break;
+ case CLASS_DISP:
+ output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);
+ da_operand = 0;
+ break;
+
+ case CLASS_IMM:
+ {
+ nib = 0;
+ switch (c & ARG_MASK)
+ {
+ case ARG_IMM4:
+ output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+ break;
+ case ARG_IMM4M1:
+ imm_operand->X_add_number--;
+ output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+ break;
+ case ARG_IMMNMINUS1:
+ imm_operand->X_add_number--;
+ output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);
+ break;
+ case ARG_NIM8:
+ imm_operand->X_add_number = -imm_operand->X_add_number;
+ case ARG_IMM8:
+ output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);
+ break;
+ case ARG_IMM16:
+ output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);
+ break;
+
+ case ARG_IMM32:
+ output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ }
+ }
+
+ /* Copy from the nibble buffer into the frag */
+
+ {
+ int length = (output_ptr - buffer) / 2;
+ char *src = buffer;
+ char *fragp = frag_more (length);
+
+ while (src < output_ptr)
+ {
+ *fragp = (src[0] << 4) | src[1];
+ src += 2;
+ fragp++;
+ }
+
+ }
+
+}
+
+/* This is the guts of the machine-dependent assembler. STR points to a
+ machine dependent instruction. This funciton is supposed to emit
+ the frags/bytes it assembles to.
+ */
+
+void
+DEFUN (md_assemble, (str),
+ char *str)
+{
+ char *op_start;
+ char *op_end;
+ unsigned int i;
+ struct z8k_op operand[3];
+ opcode_entry_type *opcode;
+ opcode_entry_type *prev_opcode;
+
+ char *dot = 0;
+ char c;
+
+ /* Drop leading whitespace */
+ while (*str == ' ')
+ str++;
+
+ /* find the op code end */
+ for (op_start = op_end = str;
+ *op_end != 0 && *op_end != ' ';
+ op_end++)
+ {
+ }
+
+ ;
+
+ if (op_end == op_start)
+ {
+ as_bad (_("can't find opcode "));
+ }
+ c = *op_end;
+
+ *op_end = 0;
+
+ opcode = (opcode_entry_type *) hash_find (opcode_hash_control,
+ op_start);
+
+
+ if (opcode == NULL)
+ {
+ as_bad (_("unknown opcode"));
+ return;
+ }
+
+ if (opcode->opcode == 250)
+ {
+ /* was really a pseudo op */
+
+ pseudo_typeS *p;
+ char oc;
+
+ char *old = input_line_pointer;
+ *op_end = c;
+
+
+ input_line_pointer = op_end;
+
+ oc = *old;
+ *old = '\n';
+ while (*input_line_pointer == ' ')
+ input_line_pointer++;
+ p = (pseudo_typeS *) (opcode->func);
+
+ (p->poc_handler) (p->poc_val);
+ input_line_pointer = old;
+ *old = oc;
+ }
+ else
+ {
+ input_line_pointer = get_operands (opcode, op_end,
+ operand);
+ prev_opcode = opcode;
+
+ opcode = get_specific (opcode, operand);
+
+ if (opcode == 0)
+ {
+ /* Couldn't find an opcode which matched the operands */
+ char *where = frag_more (2);
+
+ where[0] = 0x0;
+ where[1] = 0x0;
+
+ as_bad (_("Can't find opcode to match operands"));
+ return;
+ }
+
+ build_bytes (opcode, operand);
+ }
+}
+
+void
+DEFUN (tc_crawl_symbol_chain, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_crawl_symbol_chain \n"));
+}
+
+symbolS *
+DEFUN (md_undefined_symbol, (name),
+ char *name)
+{
+ return 0;
+}
+
+void
+DEFUN (tc_headers_hook, (headers),
+ object_headers * headers)
+{
+ printf (_("call to tc_headers_hook \n"));
+}
+
+/* Various routines to kill one day */
+/* Equal to MAX_PRECISION in atof-ieee.c */
+#define MAX_LITTLENUMS 6
+
+/* Turn a string in input_line_pointer into a floating point constant of type
+ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
+ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
+ */
+char *
+md_atof (type, litP, sizeP)
+ char type;
+ char *litP;
+ int *sizeP;
+{
+ int prec;
+ LITTLENUM_TYPE words[MAX_LITTLENUMS];
+ LITTLENUM_TYPE *wordP;
+ char *t;
+ char *atof_ieee ();
+
+ switch (type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ prec = 2;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ prec = 4;
+ break;
+
+ case 'x':
+ case 'X':
+ prec = 6;
+ break;
+
+ case 'p':
+ case 'P':
+ prec = 6;
+ break;
+
+ default:
+ *sizeP = 0;
+ return _("Bad call to MD_ATOF()");
+ }
+ t = atof_ieee (input_line_pointer, type, words);
+ if (t)
+ input_line_pointer = t;
+
+ *sizeP = prec * sizeof (LITTLENUM_TYPE);
+ for (wordP = words; prec--;)
+ {
+ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
+ litP += sizeof (LITTLENUM_TYPE);
+ }
+ return 0;
+}
+
+CONST char *md_shortopts = "z:";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
+int
+md_parse_option (c, arg)
+ int c;
+ char *arg;
+{
+ switch (c)
+ {
+ case 'z':
+ if (!strcmp (arg, "8001"))
+ s_segm ();
+ else if (!strcmp (arg, "8002"))
+ s_unseg ();
+ else
+ {
+ as_bad (_("invalid architecture -z%s"), arg);
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+Z8K options:\n\
+-z8001 generate segmented code\n\
+-z8002 generate unsegmented code\n"));
+}
+
+void
+tc_aout_fix_to_chars ()
+{
+ printf (_("call to tc_aout_fix_to_chars \n"));
+ abort ();
+}
+
+void
+md_convert_frag (headers, seg, fragP)
+ object_headers *headers;
+ segT seg;
+ fragS *fragP;
+{
+ printf (_("call to md_convert_frag \n"));
+ abort ();
+}
+
+valueT
+DEFUN (md_section_align, (seg, size),
+ segT seg AND
+ valueT size)
+{
+ return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));
+
+}
+
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+
+ switch (fixP->fx_r_type)
+ {
+ case R_IMM4L:
+ buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);
+ break;
+
+ case R_JR:
+
+ *buf++ = val;
+ /* if (val != 0) abort();*/
+ break;
+
+ case R_DISP7:
+
+ *buf++ += val;
+ /* if (val != 0) abort();*/
+ break;
+
+ case R_IMM8:
+ buf[0] += val;
+ break;
+ case R_IMM16:
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+ case R_IMM32:
+ *buf++ = (val >> 24);
+ *buf++ = (val >> 16);
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+#if 0
+ case R_DA | R_SEG:
+ *buf++ = (val >> 16);
+ *buf++ = 0x00;
+ *buf++ = (val >> 8);
+ *buf++ = val;
+ break;
+#endif
+
+ case 0:
+ md_number_to_chars (buf, val, fixP->fx_size);
+ break;
+
+ default:
+ abort ();
+
+ }
+}
+
+int
+md_estimate_size_before_relax (fragP, segment_type)
+ register fragS *fragP;
+ register segT segment_type;
+{
+ printf (_("call tomd_estimate_size_before_relax \n"));
+ abort ();
+}
+
+/* Put number into target byte order */
+
+void
+DEFUN (md_number_to_chars, (ptr, use, nbytes),
+ char *ptr AND
+ valueT use AND
+ int nbytes)
+{
+ number_to_chars_bigendian (ptr, use, nbytes);
+}
+long
+md_pcrel_from (fixP)
+ fixS *fixP;
+{
+ abort ();
+}
+
+void
+tc_coff_symbol_emit_hook (s)
+ struct symbol *s;
+{
+}
+
+void
+tc_reloc_mangle (fix_ptr, intr, base)
+ fixS *fix_ptr;
+ struct internal_reloc *intr;
+ bfd_vma base;
+
+{
+ symbolS *symbol_ptr;
+
+ if (fix_ptr->fx_addsy &&
+ fix_ptr->fx_subsy)
+ {
+ symbolS *add = fix_ptr->fx_addsy;
+ symbolS *sub = fix_ptr->fx_subsy;
+ if (S_GET_SEGMENT(add) != S_GET_SEGMENT(sub))
+ {
+ as_bad(_("Can't subtract symbols in different sections %s %s"),
+ S_GET_NAME(add), S_GET_NAME(sub));
+ }
+ else {
+ int diff = S_GET_VALUE(add) - S_GET_VALUE(sub);
+ fix_ptr->fx_addsy = 0;
+ fix_ptr->fx_subsy = 0;
+ fix_ptr->fx_offset += diff;
+ }
+ }
+ symbol_ptr = fix_ptr->fx_addsy;
+
+ /* If this relocation is attached to a symbol then it's ok
+ to output it */
+ if (fix_ptr->fx_r_type == 0)
+ {
+ /* cons likes to create reloc32's whatever the size of the reloc.. */
+ switch (fix_ptr->fx_size)
+ {
+ case 2:
+ intr->r_type = R_IMM16;
+ break;
+ case 1:
+ intr->r_type = R_IMM8;
+ break;
+ case 4:
+ intr->r_type = R_IMM32;
+ break;
+ default:
+ abort ();
+ }
+
+ }
+ else
+ {
+ intr->r_type = fix_ptr->fx_r_type;
+ }
+
+ intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
+ intr->r_offset = fix_ptr->fx_offset;
+
+ if (symbol_ptr)
+ intr->r_symndx = symbol_ptr->sy_number;
+ else
+ intr->r_symndx = -1;
+}
+
diff --git a/gas/config/tc-z8k.h b/gas/config/tc-z8k.h
new file mode 100644
index 00000000000..d88b656d6ee
--- /dev/null
+++ b/gas/config/tc-z8k.h
@@ -0,0 +1,54 @@
+/* This file is tc-z8k.h
+ Copyright (C) 1987-1992, 93, 95, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+
+#define TC_Z8K
+#define TARGET_BYTES_BIG_ENDIAN 1
+
+#if ANSI_PROTOTYPES
+struct internal_reloc;
+#endif
+
+#define WORKING_DOT_WORD
+
+#ifndef BFD_ASSEMBLER
+#define LOCAL_LABEL(x) 0
+#endif
+
+/* This macro translates between an internal fix and an coff reloc type */
+#define TC_COFF_FIX2RTYPE(fixP) abort();
+
+#define BFD_ARCH bfd_arch_z8k
+#define COFF_MAGIC 0x8000
+#define TC_COUNT_RELOC(x) (1)
+#define IGNORE_NONSTANDARD_ESCAPES
+
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
+extern void tc_reloc_mangle
+ PARAMS ((struct fix *, struct internal_reloc *, bfd_vma));
+
+#define DO_NOT_STRIP 0
+#define LISTING_HEADER "Zilog Z8000 GAS "
+#define NEED_FX_R_TYPE 1
+#define RELOC_32 1234
+
+#define md_operand(x)
+
+/* end of tc-z8k.h */
diff --git a/gas/config/te-386bsd.h b/gas/config/te-386bsd.h
new file mode 100644
index 00000000000..dbff99027ea
--- /dev/null
+++ b/gas/config/te-386bsd.h
@@ -0,0 +1,31 @@
+/* te-386bsd.h -- 386BSD target environment declarations.
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TE_386BSD 1
+
+#include "obj-format.h"
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of te-sun3.h */
diff --git a/gas/config/te-aux.h b/gas/config/te-aux.h
new file mode 100644
index 00000000000..da6fa0164cf
--- /dev/null
+++ b/gas/config/te-aux.h
@@ -0,0 +1,17 @@
+#define TE_AUX
+
+/* From obj-coff.h:
+ This internal_lineno crap is to stop namespace pollution from the
+ bfd internal coff headerfile. */
+#define internal_lineno bfd_internal_lineno
+#include "coff/aux-coff.h" /* override bits in coff/internal.h */
+#undef internal_lineno
+
+#define COFF_NOLOAD_PROBLEM
+#define KEEP_RELOC_INFO
+
+#include "obj-format.h"
+
+#ifndef LOCAL_LABELS_FB
+#define LOCAL_LABELS_FB 1
+#endif
diff --git a/gas/config/te-delt88.h b/gas/config/te-delt88.h
new file mode 100644
index 00000000000..adcd6b7f7b6
--- /dev/null
+++ b/gas/config/te-delt88.h
@@ -0,0 +1,13 @@
+/* This file is te-delta88.h. */
+
+#define TE_DELTA88 1
+
+#define COFF_NOLOAD_PROBLEM 1
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/gas/config/te-delta.h b/gas/config/te-delta.h
new file mode 100644
index 00000000000..be6c62c6c1b
--- /dev/null
+++ b/gas/config/te-delta.h
@@ -0,0 +1,14 @@
+#define TE_DELTA
+
+#include "obj-format.h"
+
+#define COFF_NOLOAD_PROBLEM 1
+#define COFF_COMMON_ADDEND 1
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* end of te-delta.h */
diff --git a/gas/config/te-dpx2.h b/gas/config/te-dpx2.h
new file mode 100644
index 00000000000..45341ca5b3e
--- /dev/null
+++ b/gas/config/te-dpx2.h
@@ -0,0 +1,12 @@
+/* Machine specific defines for the dpx2 machine */
+
+/* The magic number is not the usual MC68MAGIC. */
+#define COFF_MAGIC MC68KBCSMAGIC
+
+#define REGISTER_PREFIX_OPTIONAL 1
+
+#define TARGET_FORMAT "coff-m68k-un"
+
+#include "obj-format.h"
+
+/* end of te-dpx2.h */
diff --git a/gas/config/te-dynix.h b/gas/config/te-dynix.h
new file mode 100644
index 00000000000..9e7b30f9784
--- /dev/null
+++ b/gas/config/te-dynix.h
@@ -0,0 +1,7 @@
+/* This is for i386-sequent-bsd. The assembler probably does not
+ actually work, as the support in BFD is not complete as of this
+ writing. See bfd/i386-dynix.c. */
+
+#define TE_DYNIX 1
+
+#include "obj-format.h"
diff --git a/gas/config/te-epoc-pe.h b/gas/config/te-epoc-pe.h
new file mode 100644
index 00000000000..6c5f9141d2b
--- /dev/null
+++ b/gas/config/te-epoc-pe.h
@@ -0,0 +1,8 @@
+#define TE_PE
+#define TE_EPOC
+#define LEX_AT 1 /* can have @'s inside labels */
+
+/* The PE format supports long section names. */
+#define COFF_LONG_SECTION_NAMES
+
+#include "obj-format.h"
diff --git a/gas/config/te-generic.h b/gas/config/te-generic.h
new file mode 100644
index 00000000000..b8eda4505fb
--- /dev/null
+++ b/gas/config/te-generic.h
@@ -0,0 +1,22 @@
+/*
+ * This file is te-generic.h and is intended to be a template for
+ * target environment specific header files.
+ *
+ * It is my intent that this file will evolve into a file suitable for config,
+ * compile, and copying as an aid for testing and porting. xoxorich.
+ */
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#ifdef OBJ_HEADER
+#include OBJ_HEADER
+#else
+#include "obj-format.h"
+#endif
+
+/* end of te-generic.h */
diff --git a/gas/config/te-go32.h b/gas/config/te-go32.h
new file mode 100644
index 00000000000..49fbd2e1ac0
--- /dev/null
+++ b/gas/config/te-go32.h
@@ -0,0 +1,16 @@
+/*
+ * This file is te-go32.h
+ */
+
+#define TE_GO32
+
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+#define TARGET_FORMAT "coff-go32"
+
+/* GAS should treat '.align value' as an alignment of 2**value */
+#define USE_ALIGN_PTWO
+
+/* these define interfaces */
+#include "obj-format.h"
diff --git a/gas/config/te-hp300.h b/gas/config/te-hp300.h
new file mode 100644
index 00000000000..8e94ab4167d
--- /dev/null
+++ b/gas/config/te-hp300.h
@@ -0,0 +1,25 @@
+/* te-hp300.h -- hpux 9000/300 target environment declarations.
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
+
+/* end of te-hp300.h */
diff --git a/gas/config/te-hppa.h b/gas/config/te-hppa.h
new file mode 100644
index 00000000000..8fc4fa7806c
--- /dev/null
+++ b/gas/config/te-hppa.h
@@ -0,0 +1,26 @@
+/* Machine specific defines for the PA machine
+ Copyright 1987, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ HP PA-RISC and OSF/1 support was contributed by the Center for
+ Software Science at the University of Utah.
+ */
+
+/* these define interfaces */
+#include "obj-format.h"
diff --git a/gas/config/te-i386aix.h b/gas/config/te-i386aix.h
new file mode 100644
index 00000000000..f8f0945c94e
--- /dev/null
+++ b/gas/config/te-i386aix.h
@@ -0,0 +1,29 @@
+/*
+ * This file is te-i386aix.h and is built from pieces of code from Minh Tran-Le
+ * <TRANLE@INTELLICORP.COM> by rich@cygnus.com.
+ */
+
+#define TE_I386AIX 1
+
+#include "obj-format.h"
+
+/*
+ * Undefine REVERSE_SORT_RELOCS to keep the relocation entries sorted
+ * in ascending vaddr.
+ */
+#undef REVERSE_SORT_RELOCS
+
+/*
+ * Define KEEP_RELOC_INFO so that the strip reloc info flag F_RELFLG
+ * is not used in the filehdr for COFF output.
+ */
+#define KEEP_RELOC_INFO
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 79
+ * End:
+ */
+
+/* end of te-i386aix.h */
diff --git a/gas/config/te-ic960.h b/gas/config/te-ic960.h
new file mode 100644
index 00000000000..8331fb962ea
--- /dev/null
+++ b/gas/config/te-ic960.h
@@ -0,0 +1,38 @@
+/* This file is te-ic960.h
+ Copyright (C) 1987-1992, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * This file is te-ic960.h and is intended to define ic960 environment
+ * specific differences.
+ */
+
+#define OBJ_COFF_OMIT_OPTIONAL_HEADER
+
+#ifndef BFD_ASSEMBLER
+#define LOCAL_LABEL(name) ((name[0] =='L') \
+ || (name[0] =='.' \
+ && (name[1]=='C' \
+ || name[1]=='I' \
+ || name[1]=='.')))
+#endif
+
+#include "obj-format.h"
+
+/* end of te-ic960.h */
diff --git a/gas/config/te-linux.h b/gas/config/te-linux.h
new file mode 100644
index 00000000000..c235a7ab8a8
--- /dev/null
+++ b/gas/config/te-linux.h
@@ -0,0 +1,4 @@
+#define TE_LINUX
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/gas/config/te-lnews.h b/gas/config/te-lnews.h
new file mode 100644
index 00000000000..acbcc5a6416
--- /dev/null
+++ b/gas/config/te-lnews.h
@@ -0,0 +1,5 @@
+/* te-lnews.h -- little-endian NEWS emulation. */
+
+#define ECOFF_LITTLE_FORMAT "ecoff-biglittlemips"
+
+#include "obj-format.h"
diff --git a/gas/config/te-lynx.h b/gas/config/te-lynx.h
new file mode 100644
index 00000000000..708515d0cdc
--- /dev/null
+++ b/gas/config/te-lynx.h
@@ -0,0 +1,7 @@
+#define TE_LYNX
+
+#include "obj-format.h"
+
+#ifndef LOCAL_LABELS_FB
+#define LOCAL_LABELS_FB 1
+#endif
diff --git a/gas/config/te-mach.h b/gas/config/te-mach.h
new file mode 100644
index 00000000000..b7547f8c81e
--- /dev/null
+++ b/gas/config/te-mach.h
@@ -0,0 +1,2 @@
+#define TE_Mach
+#include "obj-format.h"
diff --git a/gas/config/te-macos.h b/gas/config/te-macos.h
new file mode 100644
index 00000000000..5f48dc4478c
--- /dev/null
+++ b/gas/config/te-macos.h
@@ -0,0 +1,11 @@
+/* This file is te-macos.h. */
+
+#define TE_POWERMAC 1
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/gas/config/te-multi.h b/gas/config/te-multi.h
new file mode 100644
index 00000000000..b8eda4505fb
--- /dev/null
+++ b/gas/config/te-multi.h
@@ -0,0 +1,22 @@
+/*
+ * This file is te-generic.h and is intended to be a template for
+ * target environment specific header files.
+ *
+ * It is my intent that this file will evolve into a file suitable for config,
+ * compile, and copying as an aid for testing and porting. xoxorich.
+ */
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#ifdef OBJ_HEADER
+#include OBJ_HEADER
+#else
+#include "obj-format.h"
+#endif
+
+/* end of te-generic.h */
diff --git a/gas/config/te-nbsd.h b/gas/config/te-nbsd.h
new file mode 100644
index 00000000000..cee4600077b
--- /dev/null
+++ b/gas/config/te-nbsd.h
@@ -0,0 +1,23 @@
+/* te-nbsd.h -- NetBSD target environment declarations.
+ Copyright (C) 1987, 90, 91, 92, 94, 95, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#define TE_NetBSD 1
+#define LOCAL_LABELS_FB 1
+#include "obj-format.h"
diff --git a/gas/config/te-nbsd532.h b/gas/config/te-nbsd532.h
new file mode 100644
index 00000000000..8cf9e5fab5f
--- /dev/null
+++ b/gas/config/te-nbsd532.h
@@ -0,0 +1,19 @@
+/*
+ * This file is te-netbsd532.h
+ *
+ * Written by Ian Dall <idall@eleceng.adelaide.edu.au>
+ *
+ * 19-Jun-94
+ *
+ */
+
+#define TARGET_FORMAT "a.out-ns32k-netbsd"
+
+#include "obj-format.h"
+
+/* Maybe these should be more like TC_NS32532 and TC_NS32381 in case
+ * of conflicts. NS32381 is used in opcode/ns32k.h and that is also
+ * used by GDB. Need to check.
+ */
+#define NS32532
+#define NS32381
diff --git a/gas/config/te-pc532mach.h b/gas/config/te-pc532mach.h
new file mode 100644
index 00000000000..0ee7ff8d795
--- /dev/null
+++ b/gas/config/te-pc532mach.h
@@ -0,0 +1,19 @@
+/*
+ * This file is te-pc532.h
+ *
+ * Written by Ian Dall <idall@eleceng.adelaide.edu.au>
+ *
+ * 24-May-94
+ *
+ */
+
+#define TARGET_FORMAT "a.out-pc532-mach"
+
+#include "obj-format.h"
+
+/* Maybe these should be more like TC_NS32532 and TC_NS32381 in case
+ * of conflicts. NS32381 is used in opcode/ns32k.h and that is also
+ * used by GDB. Need to check.
+ */
+#define NS32532
+#define NS32381
diff --git a/gas/config/te-pe.h b/gas/config/te-pe.h
new file mode 100644
index 00000000000..1c1f0b27bc1
--- /dev/null
+++ b/gas/config/te-pe.h
@@ -0,0 +1,7 @@
+#define TE_PE
+#define LEX_AT 1 /* can have @'s inside labels */
+
+/* The PE format supports long section names. */
+#define COFF_LONG_SECTION_NAMES
+
+#include "obj-format.h"
diff --git a/gas/config/te-ppcnw.h b/gas/config/te-ppcnw.h
new file mode 100644
index 00000000000..2ddf050381c
--- /dev/null
+++ b/gas/config/te-ppcnw.h
@@ -0,0 +1,31 @@
+/* te-ppcnw.h -- Power PC running Netware environment declarations.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* these define interfaces */
+#include "obj-format.h"
+
+/* gcc uses escape sequences for ppc/netware */
+
+#undef NO_STRING_ESCAPES
diff --git a/gas/config/te-psos.h b/gas/config/te-psos.h
new file mode 100644
index 00000000000..2ad4153b81a
--- /dev/null
+++ b/gas/config/te-psos.h
@@ -0,0 +1,22 @@
+/*
+ * This file is te-psos.h for embedded systems running pSOS.
+ * Contributed by Martin Anantharaman (martin@mail.imech.uni-duisburg.de)
+ */
+
+#define TE_PSOS
+
+/* Added these, because if we don't know what we're targetting we may
+ need an assembler version of libgcc, and that will use local
+ labels. */
+
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* This makes GAS more versatile and blocks some ELF'isms in
+ tc-m68k.h. */
+
+#define REGISTER_PREFIX_OPTIONAL 1
+
+#include "obj-format.h"
+
+/* end of te-psos.h */
diff --git a/gas/config/te-riscix.h b/gas/config/te-riscix.h
new file mode 100644
index 00000000000..7c7253ebcbe
--- /dev/null
+++ b/gas/config/te-riscix.h
@@ -0,0 +1,6 @@
+#define TE_RISCIX
+
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/gas/config/te-sparcaout.h b/gas/config/te-sparcaout.h
new file mode 100644
index 00000000000..63101840fa4
--- /dev/null
+++ b/gas/config/te-sparcaout.h
@@ -0,0 +1,21 @@
+/* te-sparcaout.h -- embedded sparc-aout target environment declarations.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TE_SPARCAOUT 1
+#include "obj-format.h"
diff --git a/gas/config/te-sun3.h b/gas/config/te-sun3.h
new file mode 100644
index 00000000000..475d42b74f5
--- /dev/null
+++ b/gas/config/te-sun3.h
@@ -0,0 +1,48 @@
+/* te-sun3.h -- Sun-3 target environment declarations.
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This header file contains the #defines specific
+ to SUN computer SUN 3 series computers. (The only kind
+ we have around here, unfortunatly.)
+
+ Rumor has it that this file will work on the Sun-2 if the assembler
+ is called with -m68010 This is not tested. */
+
+
+#define TE_SUN3 1
+
+#define LOCAL_LABELS_DOLLAR 1
+#define LOCAL_LABELS_FB 1
+
+/* Could also be :
+ #define S_LOCAL_NAME(s) (S_GET_NAME(s)[0] == '.' &&
+ S_GET_NAME(s)[1] == 'L' ||
+ S_GET_NAME(s)[1] == '.')
+ */
+
+#include "obj-format.h"
+
+/*
+ * Local Variables:
+ * comment-column: 0
+ * fill-column: 131
+ * End:
+ */
+
+/* end of te-sun3.h */
diff --git a/gas/config/te-svr4.h b/gas/config/te-svr4.h
new file mode 100644
index 00000000000..7217ee119e6
--- /dev/null
+++ b/gas/config/te-svr4.h
@@ -0,0 +1,4 @@
+#define TE_SVR4
+#define LOCAL_LABELS_FB 1
+
+#include "obj-format.h"
diff --git a/gas/config/te-sysv32.h b/gas/config/te-sysv32.h
new file mode 100644
index 00000000000..923e6e5799f
--- /dev/null
+++ b/gas/config/te-sysv32.h
@@ -0,0 +1,6 @@
+/* Remove leading underscore from the gcc generated symbol names */
+#define STRIP_UNDERSCORE
+
+#include "obj-format.h"
+
+/* end of te-sysv32.h */
diff --git a/gas/config/vax-inst.h b/gas/config/vax-inst.h
new file mode 100644
index 00000000000..2ad8f98c18e
--- /dev/null
+++ b/gas/config/vax-inst.h
@@ -0,0 +1,77 @@
+/* vax-inst.h - GNU - Part of vax.c
+ Copyright (C) 1987, 1992, 1995 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * This is part of vax-ins-parse.c & friends.
+ * We want to parse a vax instruction text into a tree defined here.
+ */
+
+#define VIT_MAX_OPERANDS (6) /* maximum number of operands in one */
+/* single vax instruction */
+
+struct vop /* vax instruction operand */
+{
+ short int vop_ndx; /* -1, or index register. eg 7=[R7] */
+ short int vop_reg; /* -1, or register number. eg @I^#=0xF */
+ /* Helps distinguish "abs" from "abs(PC)". */
+ short int vop_mode; /* addressing mode 4 bits. eg I^#=0x9 */
+ char vop_short; /* operand displacement length as written */
+ /* ' '=none, "bilsw"=B^I^L^S^W^. */
+ char vop_access; /* 'b'branch ' 'no-instruction 'amrvw'norm */
+ char vop_width; /* Operand width, one of "bdfghloqw" */
+ const char *vop_warn; /* warning message of this operand, if any */
+ const char *vop_error; /* say if operand is inappropriate */
+ char *vop_expr_begin; /* Unparsed expression, 1st char ... */
+ char *vop_expr_end; /* ... last char. */
+ unsigned char vop_nbytes; /* number of bytes in datum */
+};
+
+
+typedef long vax_opcodeT; /* For initialising array of opcodes */
+/* Some synthetic opcodes > 16 bits! */
+
+#define VIT_OPCODE_SYNTHETIC 0x80000000 /* Not real hardware instruction. */
+#define VIT_OPCODE_SPECIAL 0x40000000 /* Not normal branch optimising. */
+/* Never set without ..._SYNTHETIC */
+
+#define VAX_WIDTH_UNCONDITIONAL_JUMP '-' /* These are encoded into */
+#define VAX_WIDTH_CONDITIONAL_JUMP '?' /* vop_width when vop_access=='b' */
+#define VAX_WIDTH_WORD_JUMP '!' /* and VIT_OPCODE_SYNTHETIC set. */
+#define VAX_WIDTH_BYTE_JUMP ':' /* */
+
+#define VAX_JMP (0x17) /* Useful for branch optimising. Jump instr*/
+#define VAX_PC_RELATIVE_MODE (0xef) /* Use it after VAX_JMP */
+#define VAX_ABSOLUTE_MODE (0x9F)/* Use as @#... */
+#define VAX_BRB (0x11) /* Canonical branch. */
+#define VAX_BRW (0x31) /* Another canonical branch */
+#define VAX_WIDEN_WORD (0x20) /* Add this to byte branch to get word br. */
+#define VAX_WIDEN_LONG (0x6) /* Add this to byte branch to get long jmp.*/
+/* Needs VAX_PC_RELATIVE_MODE byte after it*/
+
+struct vit /* vax instruction tree */
+{
+ /* vit_opcode is char[] for portability. */
+ char vit_opcode[sizeof (vax_opcodeT)];
+ unsigned char vit_opcode_nbytes; /* How long is _opcode? (chars) */
+ unsigned char vit_operands; /* */
+ struct vop vit_operand[VIT_MAX_OPERANDS]; /* operands */
+ const char *vit_error; /* "" or error text */
+};
+
+/* end of vax-inst.h */
diff --git a/gas/config/vms-a-conf.h b/gas/config/vms-a-conf.h
new file mode 100644
index 00000000000..688fc6890ca
--- /dev/null
+++ b/gas/config/vms-a-conf.h
@@ -0,0 +1,129 @@
+/* vms-alpha-conf.h. Generated manually from conf.in,
+ and used by config-gas-alpha.com when constructing config.h. */
+
+/* Define if using alloca.c. */
+#ifdef __GNUC__
+#undef C_ALLOCA
+#else
+#define C_ALLOCA
+#endif
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#ifdef __GNUC__
+#undef inline
+#else
+#define inline
+#endif
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#define STACK_DIRECTION (-1)
+
+/* Should gas use high-level BFD interfaces? */
+#define BFD_ASSEMBLER
+
+/* Some assert/preprocessor combinations are incapable of handling
+ certain kinds of constructs in the argument of assert. For example,
+ quoted strings (if requoting isn't done right) or newlines. */
+#ifdef __GNUC__
+#undef BROKEN_ASSERT
+#else
+#define BROKEN_ASSERT
+#endif
+
+/* If we aren't doing cross-assembling, some operations can be optimized,
+ since byte orders and value sizes don't need to be adjusted. */
+#undef CROSS_COMPILE
+
+/* Some gas code wants to know these parameters. */
+#define TARGET_ALIAS "alpha-vms"
+#define TARGET_CPU "alpha"
+#define TARGET_CANONICAL "alpha-dec-vms"
+#define TARGET_OS "openVMS/Alpha"
+#define TARGET_VENDOR "dec"
+
+/* Sometimes the system header files don't declare malloc and realloc. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Sometimes the system header files don't declare free. */
+#undef NEED_DECLARATION_FREE
+
+/* Sometimes errno.h doesn't declare errno itself. */
+#undef NEED_DECLARATION_ERRNO
+
+#undef MANY_SEGMENTS
+
+/* Needed only for sparc configuration */
+#undef sparcv9
+
+/* Define if you have the remove function. */
+#define HAVE_REMOVE
+
+/* Define if you have the unlink function. */
+#undef HAVE_UNLINK
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/types.h> header file. */
+#ifdef __GNUC__
+#define HAVE_SYS_TYPES_H
+#else
+#undef HAVE_SYS_TYPES_H
+#endif
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H /* config-gas.com will make one if necessary */
+
+/* Define if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
+
+/* VMS-specific: we need to set up EXIT_xxx here because the default
+ values in as.h are inappropriate for VMS, but we also want to prevent
+ as.h's inclusion of <stdlib.h> from triggering redefinition warnings.
+ <stdlib.h> guards itself against multiple inclusion, so including it
+ here turns as.h's later #include into a no-op. (We can't simply use
+ #ifndef HAVE_STDLIB_H here, because the <stdlib.h> in several older
+ gcc-vms distributions neglects to define these two required macros.) */
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if __DECC
+#undef EXIT_SUCCESS
+#undef EXIT_FAILURE
+#define EXIT_SUCCESS 1 /* SS$_NORMAL, STS$K_SUCCESS */
+#define EXIT_FAILURE 0x10000002 /* (STS$K_ERROR | STS$M_INHIB_MSG) */
+#endif
+
+#include <unixlib.h>
+#if __DECC
+extern int strcasecmp ();
+extern int strncasecmp ();
+#endif
diff --git a/gas/config/vms-conf.h b/gas/config/vms-conf.h
new file mode 100644
index 00000000000..7225cfce1bd
--- /dev/null
+++ b/gas/config/vms-conf.h
@@ -0,0 +1,179 @@
+/* vms-conf.h. Generated manually from conf.in,
+ and used by config-gas.com when constructing config.h. */
+
+/* Define if using alloca.c. */
+#ifdef __GNUC__
+#undef C_ALLOCA
+#else
+#define C_ALLOCA
+#endif
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define as __inline if that's what the C compiler calls it. */
+#ifdef __GNUC__
+#undef inline
+#else
+#define inline
+#endif
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#define STACK_DIRECTION (-1)
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Name of package. */
+#undef PACKAGE
+
+/* Version of package. */
+/* Define in by config-gas.com */
+/* #undef VERSION */
+
+/* Should gas use high-level BFD interfaces? */
+#undef BFD_ASSEMBLER
+
+/* Some assert/preprocessor combinations are incapable of handling
+ certain kinds of constructs in the argument of assert. For example,
+ quoted strings (if requoting isn't done right) or newlines. */
+#ifdef __GNUC__
+#undef BROKEN_ASSERT
+#else
+#define BROKEN_ASSERT
+#endif
+
+/* If we aren't doing cross-assembling, some operations can be optimized,
+ since byte orders and value sizes don't need to be adjusted. */
+#undef CROSS_COMPILE
+
+/* Some gas code wants to know these parameters. */
+#define TARGET_ALIAS "vms"
+#define TARGET_CPU "vax"
+#define TARGET_CANONICAL "vax-dec-vms"
+#define TARGET_OS "vms"
+#define TARGET_VENDOR "dec"
+
+/* Sometimes the system header files don't declare strstr. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Sometimes the system header files don't declare malloc and realloc. */
+#undef NEED_DECLARATION_MALLOC
+
+/* Sometimes the system header files don't declare free. */
+#undef NEED_DECLARATION_FREE
+
+/* Sometimes the system header files don't declare sbrk. */
+#undef NEED_DECLARATION_SBRK
+
+/* Sometimes errno.h doesn't declare errno itself. */
+#undef NEED_DECLARATION_ERRNO
+
+#undef MANY_SEGMENTS
+
+/* The configure script defines this for some targets based on the
+ target name used. It is not always defined. */
+#undef TARGET_BYTES_BIG_ENDIAN
+
+/* Needed only for some configurations that can produce multiple output
+ formats. */
+#undef DEFAULT_EMULATION
+#undef EMULATIONS
+#undef USE_EMULATIONS
+#undef OBJ_MAYBE_AOUT
+#undef OBJ_MAYBE_BOUT
+#undef OBJ_MAYBE_COFF
+#undef OBJ_MAYBE_ECOFF
+#undef OBJ_MAYBE_ELF
+#undef OBJ_MAYBE_GENERIC
+#undef OBJ_MAYBE_HP300
+#undef OBJ_MAYBE_IEEE
+#undef OBJ_MAYBE_SOM
+#undef OBJ_MAYBE_VMS
+
+/* Used for some of the COFF configurations, when the COFF code needs
+ to select something based on the CPU type before it knows it... */
+#undef I386COFF
+#undef M68KCOFF
+#undef M88KCOFF
+
+/* Using cgen code? */
+#undef USING_CGEN
+
+/* Needed only for sparc configuration. */
+#undef DEFAULT_ARCH
+
+/* Needed only for PowerPC Solaris. */
+#undef TARGET_SOLARIS_COMMENT
+
+/* Needed only for SCO 5. */
+#undef SCO_ELF
+
+/* Define if you have the remove function. */
+#define HAVE_REMOVE
+
+/* Define if you have the sbrk function. */
+/* sbrk() is available, but we don't want gas to use it. */
+#undef HAVE_SBRK
+
+/* Define if you have the unlink function. */
+#undef HAVE_UNLINK
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/types.h> header file. */
+#ifdef __GNUC__
+#define HAVE_SYS_TYPES_H
+#else
+#undef HAVE_SYS_TYPES_H
+#endif
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H /* config-gas.com will make one if necessary */
+
+/* Define if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
+
+/* VMS-specific: we need to set up EXIT_xxx here because the default
+ values in as.h are inappropriate for VMS, but we also want to prevent
+ as.h's inclusion of <stdlib.h> from triggering redefinition warnings.
+ <stdlib.h> guards itself against multiple inclusion, so including it
+ here turns as.h's later #include into a no-op. (We can't simply use
+ #ifndef HAVE_STDLIB_H here, because the <stdlib.h> in several older
+ gcc-vms distributions neglects to define these two required macros.) */
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#undef EXIT_SUCCESS
+#undef EXIT_FAILURE
+#endif
+#define EXIT_SUCCESS 1 /* SS$_NORMAL, STS$K_SUCCESS */
+#define EXIT_FAILURE 0x10000002 /* (STS$K_ERROR | STS$M_INHIB_MSG) */
diff --git a/gas/configure b/gas/configure
new file mode 100755
index 00000000000..b8eefe4a591
--- /dev/null
+++ b/gas/configure
@@ -0,0 +1,5750 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --enable-bfd-assembler use BFD back end for writing object files"
+ac_help="$ac_help
+ targets alternative target configurations besides the primary"
+ac_help="$ac_help
+ --enable-commonbfdlib build shared BFD/opcodes/libiberty library"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=as.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:592: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:613: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:631: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:666: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:719: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:776: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=gas
+
+VERSION=2.9.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:822: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:835: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:848: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:861: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:874: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:937: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:967: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:997: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1048: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1080: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1091 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1122: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1127: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1136: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1155: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1199: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:\\*)
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1217: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1220: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1256: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1272: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ else
+ ac_cv_path_NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1307: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags=
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1349 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1350: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ CFLAGS="$CFLAGS -belf"
+ ;;
+
+*-*-cygwin*)
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1375: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1407: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ DLLTOOL="false"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1442: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1474: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ AS="false"
+fi
+fi
+
+
+ ;;
+
+esac
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+user_bfd_gas=
+# Check whether --enable-bfd-assembler or --disable-bfd-assembler was given.
+if test "${enable_bfd_assembler+set}" = set; then
+ enableval="$enable_bfd_assembler"
+ case "${enableval}" in
+ yes) need_bfd=yes user_bfd_gas=yes ;;
+ no) user_bfd_gas=no ;;
+ *) { echo "configure: error: bad value ${enableval} given for bfd-assembler option" 1>&2; exit 1; } ;;
+esac
+fi
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+ case "${enableval}" in
+ yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; }
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi
+# Check whether --enable-commonbfdlib or --disable-commonbfdlib was given.
+if test "${enable_commonbfdlib+set}" = set; then
+ enableval="$enable_commonbfdlib"
+ case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) { echo "configure: error: bad value ${enableval} for BFD commonbfdlib option" 1>&2; exit 1; } ;;
+esac
+fi
+
+using_cgen=no
+
+# Generate a header file
+
+
+
+
+te_file=generic
+
+# Makefile target for installing gas in $(tooldir)/bin.
+install_tooldir=install-exec-tooldir
+
+canon_targets=""
+if test -n "$enable_targets" ; then
+ for t in `echo $enable_targets | sed 's/,/ /g'`; do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $t 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+# else
+# # Permit "all", etc. We don't support it yet though.
+# canon_targets="$canon_targets $t"
+ fi
+ done
+ _gas_uniq_list="$canon_targets"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+canon_targets=$_gas_uniq_newlist
+
+fi
+
+emulations=""
+
+for this_target in $target $canon_targets ; do
+
+ eval `echo $this_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/cpu=\1 vendor=\2 os=\3/'`
+
+ # check for architecture variants
+ arch=
+ endian=
+ case ${cpu} in
+ alpha*) cpu_type=alpha ;;
+ armeb) cpu_type=arm endian=big ;;
+ arm*) cpu_type=arm endian=little ;;
+ armb*) cpu_type=arm endian=little ;;
+ armv*l) cpu_type=arm endian=little ;;
+ armv*b) cpu_type=arm endian=big ;;
+ strongarm*) cpu_type=arm endian=little ;;
+ thumb*) cpu_type=arm endian=little ;;
+ hppa*) cpu_type=hppa ;;
+ i[456]86) cpu_type=i386 ;;
+ m680[012346]0) cpu_type=m68k ;;
+ m68008) cpu_type=m68k ;;
+ m683??) cpu_type=m68k ;;
+ m5200) cpu_type=m68k ;;
+ m8*) cpu_type=m88k ;;
+ mips*el) cpu_type=mips endian=little ;;
+ mips*) cpu_type=mips endian=big ;;
+ powerpcle*) cpu_type=ppc endian=little ;;
+ powerpc*) cpu_type=ppc endian=big ;;
+ rs6000*) cpu_type=ppc ;;
+ sparclite*) cpu_type=sparc arch=sparclite ;;
+ sparclet*) cpu_type=sparc arch=sparclet ;;
+ sparc64*) cpu_type=sparc arch=v9-64 ;;
+ sparc86x*) cpu_type=sparc arch=sparc86x ;;
+ sparc*) cpu_type=sparc arch=sparclite ;; # ??? See tc-sparc.c.
+ v850*) cpu_type=v850 ;;
+ *) cpu_type=${cpu} ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ target_cpu_type=${cpu_type}
+ elif test ${target_cpu_type} != ${cpu_type} ; then
+ continue
+ fi
+
+ generic_target=${cpu_type}-$vendor-$os
+ dev=no
+ bfd_gas=no
+ em=generic
+
+ # assign object format
+ case ${generic_target} in
+ a29k-*-coff) fmt=coff ;;
+ a29k-amd-udi) fmt=coff ;;
+ a29k-amd-ebmon) fmt=coff ;;
+ a29k-nyu-sym1) fmt=coff ;;
+ a29k-*-vxworks*) fmt=coff ;;
+
+ alpha*-*-*vms*) fmt=evax ;;
+ alpha*-*-netware*) fmt=ecoff ;;
+ alpha*-*-openbsd*) fmt=ecoff ;;
+ alpha*-*-osf*) fmt=ecoff ;;
+ alpha*-*-linuxecoff*) fmt=ecoff ;;
+ alpha*-*-linux-gnu*) fmt=elf em=linux ;;
+ alpha*-*-netbsd*) fmt=elf em=nbsd ;;
+
+ arc-*-elf*) fmt=elf bfd_gas=yes ;;
+
+ arm-*-aout) fmt=aout ;;
+ arm-*-coff | thumb-*-coff) fmt=coff ;;
+ arm-*-elf | thumb-*-elf) fmt=elf ;;
+ arm-*-linux*aout*) fmt=aout em=linux ;;
+ arm-*-linux* | armv*-*-linux-gnu) fmt=elf em=linux ;;
+ arm-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ arm-*-oabi | thumb-*-oabi) fmt=elf ;;
+ arm-epoc-pe | thumb-epoc-pe) fmt=coff em=epoc-pe ;;
+ arm-*-pe | thumb-*-pe) fmt=coff em=pe ;;
+ arm-*-riscix*) fmt=aout em=riscix ;;
+
+ d10v-*-*) fmt=elf bfd_gas=yes ;;
+ d30v-*-*) fmt=elf bfd_gas=yes ;;
+
+
+ fr30-*-*) fmt=elf bfd_gas=yes ;;
+
+ hppa-*-*elf*) fmt=elf em=hppa ;;
+ hppa-*-lites*) fmt=elf em=hppa ;;
+ hppa-*-osf*) fmt=som em=hppa ;;
+ hppa-*-rtems*) fmt=elf em=hppa ;;
+ hppa-*-hpux*) fmt=som em=hppa ;;
+ hppa-*-mpeix*) fmt=som em=hppa ;;
+ hppa-*-bsd*) fmt=som em=hppa ;;
+ hppa-*-hiux*) fmt=som em=hppa ;;
+
+ h8300-*-coff) fmt=coff ;;
+
+ i386-ibm-aix*) fmt=coff em=i386aix ;;
+ i386-sequent-bsd*) fmt=aout em=dynix bfd_gas=yes ;;
+ i386-*-beospe*) fmt=coff em=pe bfd_gas=yes ;;
+ i386-*-beoself* | i386-*-beos*) fmt=elf bfd_gas=yes ;;
+ i386-*-bsd*) fmt=aout em=386bsd ;;
+ i386-*-netbsd0.8) fmt=aout em=386bsd ;;
+ i386-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes;;
+ i386-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes;;
+ i386-*-linux*aout* | i386-*-linuxoldld) fmt=aout em=linux ;;
+ i386-*-linux*coff*) fmt=coff em=linux ;;
+ i386-*-linux-gnu*) fmt=elf em=linux bfd_gas=yes ;;
+ i386-*-lynxos*) fmt=coff em=lynx ;;
+ i386-*-sysv4* | i386-*-solaris* | i386-*-elf)
+ fmt=elf bfd_gas=yes ;;
+ i386-*-freebsdelf*) fmt=elf bfd_gas=yes ;;
+ i386-*-freebsd*) fmt=aout em=386bsd ;;
+ i386-*-coff | i386-*-sysv* | i386-*-sco3.2v5*coff | i386-*-isc*)
+ fmt=coff ;;
+ i386-*-sco3.2v5*) fmt=elf
+ if test ${this_target} = $target; then
+ cat >> confdefs.h <<\EOF
+#define SCO_ELF 1
+EOF
+
+ fi
+ ;;
+ i386-*-sco3.2*) fmt=coff ;;
+ i386-*-vsta) fmt=aout ;;
+ i386-*-msdosdjgpp* | i386-*-go32* | i386-go32-rtems*)
+ fmt=coff em=go32;;
+ i386-*-rtems*) fmt=coff ;;
+ i386-*-gnu*) fmt=elf ;;
+ i386-*-mach*)
+ fmt=aout em=mach bfd_gas=yes ;;
+ i386-*-msdos*) fmt=aout ;;
+ i386-*-moss*) fmt=elf ;;
+ i386-*-pe) fmt=coff em=pe ;;
+ i386-*-cygwin*) fmt=coff em=pe bfd_gas=yes ;;
+ i386-*-mingw32*) fmt=coff em=pe bfd_gas=yes ;;
+ i386-*-*nt*) fmt=coff em=pe ;;
+ i960-*-bout) fmt=bout ;;
+ i960-*-coff) fmt=coff em=ic960 ;;
+ i960-*-rtems*) fmt=coff em=ic960 ;;
+ i960-*-nindy*) fmt=bout ;;
+ i960-*-vxworks4*) fmt=bout ;;
+ i960-*-vxworks5.0) fmt=bout ;;
+ i960-*-vxworks5.*) fmt=coff em=ic960 ;;
+ i960-*-vxworks*) fmt=bout ;;
+
+ m32r-*-*) fmt=elf bfd_gas=yes ;;
+
+ m68k-*-vxworks* | m68k-ericsson-ose | m68k-*-sunos*)
+ fmt=aout em=sun3 ;;
+ m68k-motorola-sysv*) fmt=coff em=delta ;;
+ m68k-bull-sysv3*) fmt=coff em=dpx2 ;;
+ m68k-apollo-*) fmt=coff em=apollo ;;
+ m68k-*-sysv4*) # must be before -sysv*
+ fmt=elf em=svr4 ;;
+ m68k-*-elf*) fmt=elf ;;
+ m68k-*-coff | m68k-*-sysv* | m68k-*-rtems*)
+ fmt=coff ;;
+ m68k-*-hpux*) fmt=hp300 em=hp300 ;;
+ m68k-*-linux*aout*) fmt=aout em=linux ;;
+ m68k-*-linux-gnu*) fmt=elf em=linux ;;
+ m68k-*-gnu*) fmt=elf ;;
+ m68k-*-lynxos*) fmt=coff em=lynx ;;
+ m68k-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-apple-aux*) fmt=coff em=aux ;;
+ m68k-*-psos*) fmt=elf em=psos;;
+
+ m88k-motorola-sysv3*) fmt=coff em=delt88 ;;
+ m88k-*-coff*) fmt=coff ;;
+
+ mcore-*-elf) fmt=elf bfd_gas=yes ;;
+ mcore-*-pe) fmt=coff em=pe bfd_gas=yes ;;
+
+ # don't change em like *-*-bsd does
+ mips-dec-netbsd*) fmt=elf endian=little ;;
+ mips-dec-openbsd*) fmt=elf endian=little ;;
+ mips-dec-bsd*) fmt=aout endian=little ;;
+ mips-sony-bsd*) fmt=ecoff ;;
+ mips-*-bsd*) { echo "configure: error: Unknown vendor for mips-bsd configuration." 1>&2; exit 1; } ;;
+ mips-*-ultrix*) fmt=ecoff endian=little ;;
+ mips-*-osf*) fmt=ecoff endian=little ;;
+ mips-*-ecoff*) fmt=ecoff ;;
+ mips-*-ecoff*) fmt=ecoff ;;
+ mips-*-irix6*) fmt=elf ;;
+ mips-*-irix5*) fmt=elf ;;
+ mips-*-irix*) fmt=ecoff ;;
+ mips-*-lnews*) fmt=ecoff em=lnews ;;
+ mips-*-riscos*) fmt=ecoff ;;
+ mips-*-sysv*) fmt=ecoff ;;
+ mips-*-elf* | mips-*-rtems* | mips-*-linux-gnu* | mips-*-gnu* | mips-*-openbsd*)
+ fmt=elf ;;
+ mips-*-vxworks*) fmt=elf
+ cat >> confdefs.h <<\EOF
+#define MIPS_STABS_ELF 1
+EOF
+
+ ;;
+ mn10200-*-*) fmt=elf bfd_gas=yes ;;
+ mn10300-*-*) fmt=elf bfd_gas=yes ;;
+ ppc-*-pe | ppc-*-cygwin* | ppc-*-winnt*)
+ fmt=coff em=pe ;;
+ ppc-*-aix*) fmt=coff ;;
+ ppc-*-beos*) fmt=coff ;;
+ ppc-*-*bsd* | ppc-*-elf* | ppc-*-eabi* | ppc-*-sysv4*)
+ fmt=elf ;;
+ ppc-*-linux-gnu*) fmt=elf
+ case "$endian" in
+ big) ;;
+ *) { echo "configure: error: GNU/Linux must be configured big endian" 1>&2; exit 1; } ;;
+ esac
+ ;;
+ ppc-*-solaris*) fmt=elf
+ if test ${this_target} = $target; then
+ cat >> confdefs.h <<\EOF
+#define TARGET_SOLARIS_COMMENT 1
+EOF
+
+ fi
+ if test x${endian} = xbig; then
+ { echo "configure: error: Solaris must be configured little endian" 1>&2; exit 1; }
+ fi
+ ;;
+ ppc-*-rtems*) fmt=elf ;;
+ ppc-*-macos* | ppc-*-mpw*)
+ fmt=coff em=macos ;;
+ ppc-*-netware*) fmt=elf em=ppcnw ;;
+
+ sh-*-elf*) fmt=elf ;;
+ sh-*-coff*) fmt=coff ;;
+ sh-*-rtems*) fmt=coff ;;
+
+ ns32k-pc532-mach* | ns32k-pc532-ux*) fmt=aout em=pc532mach ;;
+ ns32k-pc532-netbsd* | ns32k-pc532-lites*) fmt=aout em=nbsd532 ;;
+ ns32k-pc532-openbsd*) fmt=aout em=nbsd532 ;;
+
+ sparc-*-rtems*) fmt=aout ;;
+ sparc-*-sunos4*) fmt=aout em=sun3 ;;
+ sparc-*-aout | sparc*-*-vxworks*)
+ fmt=aout em=sparcaout ;;
+ sparc-*-coff) fmt=coff ;;
+ sparc-*-linux*aout*) fmt=aout em=linux ;;
+ sparc-*-linux-gnu*) fmt=elf em=linux ;;
+ sparc-*-lynxos*) fmt=coff em=lynx ;;
+ sparc-fujitsu-none) fmt=aout ;;
+ sparc-*-elf | sparc-*-sysv4* | sparc-*-solaris*)
+ fmt=elf ;;
+ sparc-*-netbsd*) fmt=aout em=nbsd ;;
+ sparc-*-openbsd*) fmt=aout em=nbsd ;;
+
+ strongarm-*-coff) fmt=coff ;;
+ strongarm-*-elf) fmt=elf ;;
+
+ tic30-*-*aout*) fmt=aout bfd_gas=yes ;;
+ tic30-*-*coff*) fmt=coff bfd_gas=yes ;;
+ tic80-*-*) fmt=coff ;;
+
+ v850-*-*) fmt=elf bfd_gas=yes ;;
+ v850e-*-*) fmt=elf bfd_gas=yes ;;
+ v850ea-*-*) fmt=elf bfd_gas=yes ;;
+
+ vax-*-bsd* | vax-*-ultrix*)
+ fmt=aout ;;
+ vax-*-vms) fmt=vms ;;
+
+
+ z8k-*-coff | z8k-*-sim)
+ fmt=coff ;;
+
+ w65-*-*) fmt=coff ;;
+
+ *-*-aout | *-*-scout)
+ fmt=aout ;;
+ *-*-nindy*)
+ fmt=bout ;;
+ *-*-bsd*)
+ fmt=aout em=sun3 ;;
+ *-*-generic) fmt=generic ;;
+ *-*-xray | *-*-hms) fmt=coff ;;
+ *-*-sim) fmt=coff ;;
+ *-*-elf | *-*-sysv4* | *-*-solaris*)
+ echo "configure: warning: GAS support for ${generic_target} is incomplete." 1>&2
+ fmt=elf dev=yes ;;
+ *-*-vxworks) fmt=aout ;;
+ *-*-netware) fmt=elf ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ endian_def=
+ if test x${endian} = xbig; then
+ endian_def=1
+ elif test x${endian} = xlittle; then
+ endian_def=0
+ fi
+ if test x${endian_def} != x; then
+ cat >> confdefs.h <<EOF
+#define TARGET_BYTES_BIG_ENDIAN $endian_def
+EOF
+
+ fi
+ fi
+
+ case ${cpu_type}-${fmt} in
+ alpha*-*) bfd_gas=yes ;;
+ arm-*) bfd_gas=yes ;;
+ # not yet
+ # i386-aout) bfd_gas=preferred ;;
+ mips-*) bfd_gas=yes ;;
+ ns32k-*) bfd_gas=yes ;;
+ ppc-*) bfd_gas=yes ;;
+ sparc-*) bfd_gas=yes ;;
+ strongarm-*) bfd_gas=yes ;;
+ *-elf) bfd_gas=yes ;;
+ *-ecoff) bfd_gas=yes ;;
+ *-som) bfd_gas=yes ;;
+ *) ;;
+ esac
+
+# Other random stuff.
+
+ # Do we need the opcodes library?
+ case ${cpu_type} in
+ vax | i386 | tic30)
+ ;;
+
+ *)
+ need_opcodes=yes
+
+ case "${enable_shared}" in
+ yes) shared_opcodes=true ;;
+ *opcodes*) shared_opcodes=true ;;
+ *) shared_opcodes=false ;;
+ esac
+ if test "${shared_opcodes}" = "true"; then
+ # A shared libopcodes must be linked against libbfd.
+ need_bfd=yes
+ fi
+ ;;
+ esac
+
+ # Any other special object files needed ?
+ case ${cpu_type} in
+ fr30 | m32r)
+ using_cgen=yes
+ ;;
+
+ m68k)
+ case ${extra_objects} in
+ *m68k-parse.o*) ;;
+ *) extra_objects="$extra_objects m68k-parse.o" ;;
+ esac
+ ;;
+
+ mips)
+ echo ${extra_objects} | grep -s "itbl-parse.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-parse.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-lex.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-lex.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-ops.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-ops.o"
+ fi
+ ;;
+
+ sparc)
+ if test $this_target = $target ; then
+ cat >> confdefs.h <<EOF
+#define DEFAULT_ARCH "${arch}"
+EOF
+
+ fi
+ ;;
+ *)
+ ;;
+ esac
+
+ if test $using_cgen = yes ; then
+ case "x${extra_objects}" in
+ *cgen.o*) ;;
+ *) extra_objects="$extra_objects cgen.o" ;;
+ esac
+ fi
+
+# See if we really can support this configuration with the emulation code.
+
+ if test $this_target = $target ; then
+ primary_bfd_gas=$bfd_gas
+ obj_format=$fmt
+ te_file=$em
+
+ if test $bfd_gas = no ; then
+ # Can't support other configurations this way.
+ break
+ fi
+ elif test $bfd_gas = no ; then
+ # Can't support this configuration.
+ break
+ fi
+
+# From target name and format, produce a list of supported emulations.
+
+ case ${generic_target}-${fmt} in
+ mips-*-irix5*-*) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ mips-*-linux-gnu*-*) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ *) emulation="mipslelf mipsbelf mipself mipslecoff mipsbecoff mipsecoff" ;;
+ esac ;;
+ mips-*-lnews*-ecoff) ;;
+ mips-*-*-ecoff) case "$endian" in
+ big) emulation="mipsbecoff mipslecoff mipsecoff" ;;
+ *) emulation="mipslecoff mipsbecoff mipsecoff" ;;
+ esac ;;
+ mips-*-*-elf) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself" ;;
+ *) emulation="mipslelf mipsbelf mipself" ;;
+ # Uncommenting the next line will turn on support for i386 COFF
+ # in any i386 ELF configuration. This probably doesn't work
+ # correctly.
+ # i386-*-*-elf) emulation="i386coff i386elf" ;;
+ esac ;;
+ esac
+
+ emulations="$emulations $emulation"
+
+done
+
+# Assign floating point type. Most processors with FP support
+# IEEE FP. On those that don't support FP at all, usually IEEE
+# is emulated.
+case ${target_cpu} in
+ vax | tahoe ) atof=${target_cpu} ;;
+ *) atof=ieee ;;
+esac
+
+case "${obj_format}" in
+ "") { echo "configure: error: GAS does not know what format to use for target ${target}" 1>&2; exit 1; } ;;
+esac
+
+# Unfortunately the cpu in cpu-opc.h file isn't always $(TARGET_CPU).
+cgen_cpu_prefix=""
+if test $using_cgen = yes ; then
+ case ${target_cpu} in
+ *) cgen_cpu_prefix=${target_cpu} ;;
+ esac
+
+ cat >> confdefs.h <<\EOF
+#define USING_CGEN 1
+EOF
+
+fi
+
+
+if test ! -r ${srcdir}/config/tc-${target_cpu_type}.c; then
+ { echo "configure: error: GAS does not support target CPU ${target_cpu_type}" 1>&2; exit 1; }
+fi
+
+if test ! -r ${srcdir}/config/obj-${obj_format}.c; then
+ { echo "configure: error: GAS does not have support for object file format ${obj_format}" 1>&2; exit 1; }
+fi
+
+case ${user_bfd_gas}-${primary_bfd_gas} in
+ yes-yes | no-no)
+ # We didn't override user's choice.
+ ;;
+ no-yes)
+ echo "configure: warning: Use of BFD is required for ${target}; overriding config options." 1>&2
+ ;;
+ no-preferred)
+ primary_bfd_gas=no
+ ;;
+ *-preferred)
+ primary_bfd_gas=yes
+ ;;
+ yes-*)
+ primary_bfd_gas=yes
+ ;;
+ -*)
+ # User specified nothing.
+ ;;
+esac
+
+# Some COFF configurations want these random other flags set.
+case ${obj_format} in
+ coff)
+ case ${target_cpu_type} in
+ i386) cat >> confdefs.h <<\EOF
+#define I386COFF 1
+EOF
+ ;;
+ m68k) cat >> confdefs.h <<\EOF
+#define M68KCOFF 1
+EOF
+ ;;
+ m88k) cat >> confdefs.h <<\EOF
+#define M88KCOFF 1
+EOF
+ ;;
+ esac
+ ;;
+esac
+
+# Getting this done right is going to be a bitch. Each configuration specified
+# with --enable-targets=... should be checked for environment, format, cpu, and
+# bfd_gas setting.
+#
+# For each configuration, the necessary object file support code must be linked
+# in. This might be only one, it might be up to four. The necessary emulation
+# code needs to be provided, too.
+#
+# And then there's "--enable-targets=all"....
+#
+# For now, just always do it for MIPS ELF or ECOFF configurations. Sigh.
+
+formats="${obj_format}"
+emfiles=""
+EMULATIONS=""
+_gas_uniq_list="$emulations"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+emulations=$_gas_uniq_newlist
+
+for em in . $emulations ; do
+ case $em in
+ .) continue ;;
+ mipsbelf | mipslelf)
+ fmt=elf file=mipself ;;
+ mipsbecoff | mipslecoff)
+ fmt=ecoff file=mipsecoff ;;
+ i386coff)
+ fmt=coff file=i386coff ;;
+ i386elf)
+ fmt=elf file=i386elf ;;
+ esac
+ formats="$formats $fmt"
+ emfiles="$emfiles e-$file.o"
+ EMULATIONS="$EMULATIONS &$em,"
+done
+_gas_uniq_list="$formats"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+formats=$_gas_uniq_newlist
+
+_gas_uniq_list="$emfiles"
+_gas_uniq_newlist=""
+for _gas_uniq_i in _gas_uniq_dummy $_gas_uniq_list ; do
+ case $_gas_uniq_i in
+ _gas_uniq_dummy) ;;
+ *) case " $_gas_uniq_newlist " in
+ *" $_gas_uniq_i "*) ;;
+ *) _gas_uniq_newlist="$_gas_uniq_newlist $_gas_uniq_i" ;;
+ esac ;;
+ esac
+done
+emfiles=$_gas_uniq_newlist
+
+if test `set . $formats ; shift ; echo $#` -gt 1 ; then
+ for fmt in $formats ; do
+ case $fmt in
+ aout) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_AOUT 1
+EOF
+ ;;
+ bout) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_BOUT 1
+EOF
+ ;;
+ coff) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_COFF 1
+EOF
+ ;;
+ ecoff) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_ECOFF 1
+EOF
+ ;;
+ elf) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_ELF 1
+EOF
+ ;;
+ generic) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_GENERIC 1
+EOF
+ ;;
+ hp300) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_HP300 1
+EOF
+ ;;
+ ieee) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_IEEE 1
+EOF
+ ;;
+ som) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_SOM 1
+EOF
+ ;;
+ vms) cat >> confdefs.h <<\EOF
+#define OBJ_MAYBE_VMS 1
+EOF
+ ;;
+ esac
+ extra_objects="$extra_objects obj-$fmt.o"
+ done
+ obj_format=multi
+fi
+if test `set . $emfiles ; shift ; echo $#` -gt 0 ; then
+ te_file=multi
+ extra_objects="$extra_objects $emfiles"
+ DEFAULT_EMULATION=`set . $emulations ; echo $2`
+ cat >> confdefs.h <<\EOF
+#define USE_EMULATIONS 1
+EOF
+
+fi
+
+cat >> confdefs.h <<EOF
+#define EMULATIONS $EMULATIONS
+EOF
+
+cat >> confdefs.h <<EOF
+#define DEFAULT_EMULATION "$DEFAULT_EMULATION"
+EOF
+
+
+case ${primary_bfd_gas}-${target_cpu_type}-${obj_format} in
+ yes-*-coff) need_bfd=yes ;;
+ no-*-coff) need_bfd=yes
+ cat >> confdefs.h <<\EOF
+#define MANY_SEGMENTS 1
+EOF
+ ;;
+esac
+
+reject_dev_configs=yes
+
+case ${reject_dev_configs}-${dev} in
+ yes-yes) # Oops.
+ { echo "configure: error: GAS does not support the ${generic_target} configuration." 1>&2; exit 1; }
+ ;;
+esac
+
+
+
+
+
+
+
+case "${primary_bfd_gas}" in
+ yes) cat >> confdefs.h <<\EOF
+#define BFD_ASSEMBLER 1
+EOF
+
+ need_bfd=yes ;;
+esac
+
+# do we need the opcodes library?
+case "${need_opcodes}" in
+yes)
+ OPCODES_LIB=../opcodes/libopcodes.la
+ ;;
+esac
+
+case "${need_bfd}" in
+yes)
+ BFDLIB=../bfd/libbfd.la
+ ALL_OBJ_DEPS="$ALL_OBJ_DEPS ../bfd/bfd.h"
+ ;;
+esac
+
+
+
+
+
+
+cat >> confdefs.h <<EOF
+#define TARGET_ALIAS "${target_alias}"
+EOF
+
+cat >> confdefs.h <<EOF
+#define TARGET_CANONICAL "${target}"
+EOF
+
+cat >> confdefs.h <<EOF
+#define TARGET_CPU "${target_cpu}"
+EOF
+
+cat >> confdefs.h <<EOF
+#define TARGET_VENDOR "${target_vendor}"
+EOF
+
+cat >> confdefs.h <<EOF
+#define TARGET_OS "${target_os}"
+EOF
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2323: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2353: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2404: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2436: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2447 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2478: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2483: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2492: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2511: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2548: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2579: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2594 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2600: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2611 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2617: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2628 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2634: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+missing_dir=`cd $ac_aux_dir && pwd`
+for ac_prog in flex lex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2664: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=""$missing_dir/missing flex""
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2697: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:2731: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2739 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:2750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:2773: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:2794: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 2806 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+ cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+
+ALL_LINGUAS=
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:2837: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2858: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2863 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2871: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2888 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2906 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2927 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2962: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2967 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:3016: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:3037: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 3044 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:3051: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:3077: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3082 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:3110: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3115 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:3145: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3150 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:3157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:3178: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3183 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:3211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:3243: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3248 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3273: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3278 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:3328: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3336 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:3355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3380: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3385 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3390: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3419: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3424 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:3472: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3480 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:3620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3648: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3653 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3658: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3688: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3693 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3716: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3745: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3750 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:3807: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3812 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:3819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:3840: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:3860: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:3879: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3884 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3889: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:3906: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3911 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:3934: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3942 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:3953: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:3969: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3974 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4009: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4043: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4048 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4071: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4098: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4134: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 4166 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:4174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4206: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4240: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4276: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:4366: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:4394: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4399 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4404: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:4467: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:4490: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4495 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:4506: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:4523: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4528 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:4535: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:4554: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:4564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+for ac_hdr in string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h errno.h sys/types.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4589: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4594 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4599: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Put this here so that autoconf's "cross-compiling" message doesn't confuse
+# people who are not cross-compiling but are compiling cross-assemblers.
+echo $ac_n "checking whether compiling a cross-assembler""... $ac_c" 1>&6
+echo "configure:4629: checking whether compiling a cross-assembler" >&5
+if test "${host}" = "${target}"; then
+ cross_gas=no
+else
+ cross_gas=yes
+ cat >> confdefs.h <<\EOF
+#define CROSS_COMPILE 1
+EOF
+
+fi
+echo "$ac_t""$cross_gas" 1>&6
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:4644: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4649 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:4656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:4677: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4682 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:4710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:4742: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4747 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4772: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4777 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:4827: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4835 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:4854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:4876: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 4883 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:4890: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+# VMS doesn't have unlink.
+for ac_func in unlink remove
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4920: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4925 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Some systems don't have sbrk().
+for ac_func in sbrk
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4977: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4982 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Some non-ANSI preprocessors botch requoting inside strings. That's bad
+# enough, but on some of those systems, the assert macro relies on requoting
+# working properly!
+echo $ac_n "checking for working assert macro""... $ac_c" 1>&6
+echo "configure:5034: checking for working assert macro" >&5
+if eval "test \"`echo '$''{'gas_cv_assert_ok'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5039 "configure"
+#include "confdefs.h"
+#include <assert.h>
+#include <stdio.h>
+int main() {
+
+/* check for requoting problems */
+static int a, b, c, d;
+static char *s;
+assert (!strcmp(s, "foo bar baz quux"));
+/* check for newline handling */
+assert (a == b
+ || c == d);
+
+; return 0; }
+EOF
+if { (eval echo configure:5055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_assert_ok=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_assert_ok=no
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_assert_ok" 1>&6
+test $gas_cv_assert_ok = yes || cat >> confdefs.h <<\EOF
+#define BROKEN_ASSERT 1
+EOF
+
+
+
+# On some systems, the system header files may not declare malloc, realloc,
+# and free. There are places where gas needs these functions to have been
+# declared -- such as when taking their addresses.
+gas_test_headers="
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+"
+
+echo $ac_n "checking whether declaration is required for strstr""... $ac_c" 1>&6
+echo "configure:5096: checking whether declaration is required for strstr" >&5
+if eval "test \"`echo '$''{'gas_cv_decl_needed_strstr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5101 "configure"
+#include "confdefs.h"
+$gas_test_headers
+int main() {
+
+typedef char *(*f)();
+f x;
+x = (f) strstr;
+
+; return 0; }
+EOF
+if { (eval echo configure:5112: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_decl_needed_strstr=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_decl_needed_strstr=yes
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_decl_needed_strstr" 1>&6
+if test $gas_cv_decl_needed_strstr = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRSTR 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether declaration is required for malloc""... $ac_c" 1>&6
+echo "configure:5133: checking whether declaration is required for malloc" >&5
+if eval "test \"`echo '$''{'gas_cv_decl_needed_malloc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5138 "configure"
+#include "confdefs.h"
+$gas_test_headers
+int main() {
+
+typedef char *(*f)();
+f x;
+x = (f) malloc;
+
+; return 0; }
+EOF
+if { (eval echo configure:5149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_decl_needed_malloc=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_decl_needed_malloc=yes
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_decl_needed_malloc" 1>&6
+if test $gas_cv_decl_needed_malloc = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_MALLOC 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether declaration is required for free""... $ac_c" 1>&6
+echo "configure:5170: checking whether declaration is required for free" >&5
+if eval "test \"`echo '$''{'gas_cv_decl_needed_free'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5175 "configure"
+#include "confdefs.h"
+$gas_test_headers
+int main() {
+
+typedef void (*f)();
+f x;
+x = (f) free;
+
+; return 0; }
+EOF
+if { (eval echo configure:5186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_decl_needed_free=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_decl_needed_free=yes
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_decl_needed_free" 1>&6
+if test $gas_cv_decl_needed_free = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_FREE 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether declaration is required for sbrk""... $ac_c" 1>&6
+echo "configure:5207: checking whether declaration is required for sbrk" >&5
+if eval "test \"`echo '$''{'gas_cv_decl_needed_sbrk'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5212 "configure"
+#include "confdefs.h"
+$gas_test_headers
+int main() {
+
+typedef char *(*f)();
+f x;
+x = (f) sbrk;
+
+; return 0; }
+EOF
+if { (eval echo configure:5223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_decl_needed_sbrk=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_decl_needed_sbrk=yes
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_decl_needed_sbrk" 1>&6
+if test $gas_cv_decl_needed_sbrk = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_SBRK 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether declaration is required for environ""... $ac_c" 1>&6
+echo "configure:5244: checking whether declaration is required for environ" >&5
+if eval "test \"`echo '$''{'gas_cv_decl_needed_environ'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5249 "configure"
+#include "confdefs.h"
+$gas_test_headers
+int main() {
+
+typedef char **f;
+f x;
+x = (f) environ;
+
+; return 0; }
+EOF
+if { (eval echo configure:5260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_decl_needed_environ=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_decl_needed_environ=yes
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_decl_needed_environ" 1>&6
+if test $gas_cv_decl_needed_environ = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_ENVIRON 1
+EOF
+
+fi
+
+
+# Does errno.h declare errno, or do we have to add a separate declaration
+# for it?
+
+echo $ac_n "checking whether declaration is required for errno""... $ac_c" 1>&6
+echo "configure:5284: checking whether declaration is required for errno" >&5
+if eval "test \"`echo '$''{'gas_cv_decl_needed_errno'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5289 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+int main() {
+
+typedef int f;
+f x;
+x = (f) errno;
+
+; return 0; }
+EOF
+if { (eval echo configure:5304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gas_cv_decl_needed_errno=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gas_cv_decl_needed_errno=yes
+fi
+rm -f conftest*
+fi
+echo "$ac_t""$gas_cv_decl_needed_errno" 1>&6
+if test $gas_cv_decl_needed_errno = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_ERRNO 1
+EOF
+
+fi
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile doc/Makefile .gdbinit:gdbinit.in po/Makefile.in:po/Make-in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@cgen_cpu_prefix@%$cgen_cpu_prefix%g
+s%@extra_objects@%$extra_objects%g
+s%@target_cpu_type@%$target_cpu_type%g
+s%@obj_format@%$obj_format%g
+s%@te_file@%$te_file%g
+s%@install_tooldir@%$install_tooldir%g
+s%@atof@%$atof%g
+s%@BFDLIB@%$BFDLIB%g
+s%@OPCODES_LIB@%$OPCODES_LIB%g
+s%@ALL_OBJ_DEPS@%$ALL_OBJ_DEPS%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@CPP@%$CPP%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile .gdbinit:gdbinit.in po/Makefile.in:po/Make-in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+target_cpu_type=${target_cpu_type}
+ cgen_cpu_prefix=${cgen_cpu_prefix}
+ obj_format=${obj_format}
+ te_file=${te_file}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+rm -f targ-cpu.c targ-cpu.h obj-format.h obj-format.c targ-env.h atof-targ.c itbl-cpu.h
+ echo '#include "tc-'"${target_cpu_type}"'.h"' > targ-cpu.h
+ echo '#include "obj-'"${obj_format}"'.h"' > obj-format.h
+ echo '#include "te-'"${te_file}"'.h"' > targ-env.h
+ echo '#include "itbl-'"${target_cpu_type}"'.h"' > itbl-cpu.h
+ if test "x$cgen_cpu_prefix" != x ; then
+ echo '#include "opcodes/'"${cgen_cpu_prefix}"'-desc.h"' > cgen-desc.h
+ fi
+
+ sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gas/configure.bat b/gas/configure.bat
new file mode 100644
index 00000000000..1fd269fd671
--- /dev/null
+++ b/gas/configure.bat
@@ -0,0 +1,57 @@
+@echo off
+if "%1" == "h8/300" goto h8300
+
+echo Configuring gas for go32
+update config/tc-i386.c targ-cpu.c
+update config/tc-i386.h targ-cpu.h
+update config/te-go32.h targ-env.h
+update config/obj-coff.h obj-format.h
+update config/obj-coff.c obj-format.c
+update config/atof-ieee.c atof-targ.c
+goto common
+
+:h8300
+echo Configuring gas for H8/300
+copy config\ho-go32.h host.h
+copy config\tc-h8300.c targ-cpu.c
+copy config\tc-h8300.h targ-cpu.h
+copy config\te-generic.h targ-env.h
+copy config\objcoffbfd.h obj-format.h
+copy config\objcoffbfd.c obj-format.c
+copy config\atof-ieee.c atof-targ.c
+
+:common
+
+echo # Makefile generated by "configure.bat"> Makefile.2
+echo all.dos : as.new gasp.new>> Makefile.2
+
+if exist config.sed del config.sed
+
+echo "s/@srcdir@/./g ">> config.sed
+echo "s/@target_alias@/go32/ ">> config.sed
+echo "s/@prefix@// ">> config.sed
+echo "s/@CC@/gcc/g ">> config.sed
+echo "s/@OPCODES_LIB@/..\/opcodes\/libopcodes.a/g ">> config.sed
+echo "s/@BFDLIB@/..\/bfd\/libbfd.a/g ">> config.sed
+echo "s/@ALL_OBJ_DEPS@/..\/bfd\/bfd.h/g ">> config.sed
+
+echo "/^all[ ]*:/ a\ ">> config.sed
+echo "dummy: ">> config.sed
+
+echo "s/\/usr[^ ]*.h//g ">> config.sed
+
+echo "/^config.h[ ]*:/ d ">> config.sed
+echo "s/^Makefile/not-Makefile/ ">> config.sed
+
+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
+sed -f config2.sed Makefile.in >> Makefile.2
+update Makefile.2 Makefile
+del Makefile.2
+del config.sed
+del config2.sed
+
+echo #ifndef GAS_VERSION> config.new
+sed -n "/^VERSION=/p" Makefile.in | sed -e "s/VERSION=/#define GAS_VERSION \"/" -e "s/$/\"/">> config.new
+type config\go32.cfg >> config.new
+echo #endif>> config.new
+update config.new config.h
diff --git a/gas/configure.in b/gas/configure.in
new file mode 100644
index 00000000000..4d847ba9af4
--- /dev/null
+++ b/gas/configure.in
@@ -0,0 +1,766 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl And be careful when changing it! If you must add tests with square
+dnl brackets, be sure changequote invocations surround it.
+dnl
+dnl
+dnl v2.5 needed for --bindir et al
+AC_PREREQ(2.13)
+AC_INIT(as.h)
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE(gas, 2.9.4)
+
+AM_PROG_LIBTOOL
+
+user_bfd_gas=
+AC_ARG_ENABLE(bfd-assembler,
+[ --enable-bfd-assembler use BFD back end for writing object files],
+[case "${enableval}" in
+ yes) need_bfd=yes user_bfd_gas=yes ;;
+ no) user_bfd_gas=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} given for bfd-assembler option) ;;
+esac])dnl
+AC_ARG_ENABLE(targets,
+[ targets alternative target configurations besides the primary],
+[case "${enableval}" in
+ yes | "") AC_ERROR(enable-targets option must specify target names or 'all')
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac])dnl
+AC_ARG_ENABLE(commonbfdlib,
+[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library],
+[case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for BFD commonbfdlib option]) ;;
+esac])dnl
+
+using_cgen=no
+
+# Generate a header file
+AM_CONFIG_HEADER(config.h:config.in)
+
+te_file=generic
+
+# Makefile target for installing gas in $(tooldir)/bin.
+install_tooldir=install-exec-tooldir
+
+canon_targets=""
+if test -n "$enable_targets" ; then
+ for t in `echo $enable_targets | sed 's/,/ /g'`; do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $t 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+# else
+# # Permit "all", etc. We don't support it yet though.
+# canon_targets="$canon_targets $t"
+ fi
+ done
+ GAS_UNIQ(canon_targets)
+fi
+
+emulations=""
+
+for this_target in $target $canon_targets ; do
+
+changequote(,)dnl
+ eval `echo $this_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/cpu=\1 vendor=\2 os=\3/'`
+changequote([,])dnl
+
+ # check for architecture variants
+ arch=
+ endian=
+ case ${cpu} in
+ alpha*) cpu_type=alpha ;;
+ armeb) cpu_type=arm endian=big ;;
+ arm*) cpu_type=arm endian=little ;;
+ armb*) cpu_type=arm endian=little ;;
+ armv*l) cpu_type=arm endian=little ;;
+ armv*b) cpu_type=arm endian=big ;;
+ strongarm*) cpu_type=arm endian=little ;;
+ thumb*) cpu_type=arm endian=little ;;
+ hppa*) cpu_type=hppa ;;
+changequote(,)dnl
+ i[456]86) cpu_type=i386 ;;
+ m680[012346]0) cpu_type=m68k ;;
+changequote([,])dnl
+ m68008) cpu_type=m68k ;;
+ m683??) cpu_type=m68k ;;
+ m5200) cpu_type=m68k ;;
+ m8*) cpu_type=m88k ;;
+ mips*el) cpu_type=mips endian=little ;;
+ mips*) cpu_type=mips endian=big ;;
+ powerpcle*) cpu_type=ppc endian=little ;;
+ powerpc*) cpu_type=ppc endian=big ;;
+ rs6000*) cpu_type=ppc ;;
+ sparclite*) cpu_type=sparc arch=sparclite ;;
+ sparclet*) cpu_type=sparc arch=sparclet ;;
+ sparc64*) cpu_type=sparc arch=v9-64 ;;
+ sparc86x*) cpu_type=sparc arch=sparc86x ;;
+ sparc*) cpu_type=sparc arch=sparclite ;; # ??? See tc-sparc.c.
+ v850*) cpu_type=v850 ;;
+ *) cpu_type=${cpu} ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ target_cpu_type=${cpu_type}
+ elif test ${target_cpu_type} != ${cpu_type} ; then
+ continue
+ fi
+
+ generic_target=${cpu_type}-$vendor-$os
+ dev=no
+ bfd_gas=no
+ em=generic
+
+ # assign object format
+ case ${generic_target} in
+ a29k-*-coff) fmt=coff ;;
+ a29k-amd-udi) fmt=coff ;;
+ a29k-amd-ebmon) fmt=coff ;;
+ a29k-nyu-sym1) fmt=coff ;;
+ a29k-*-vxworks*) fmt=coff ;;
+
+ alpha*-*-*vms*) fmt=evax ;;
+ alpha*-*-netware*) fmt=ecoff ;;
+ alpha*-*-openbsd*) fmt=ecoff ;;
+ alpha*-*-osf*) fmt=ecoff ;;
+ alpha*-*-linuxecoff*) fmt=ecoff ;;
+ alpha*-*-linux-gnu*) fmt=elf em=linux ;;
+ alpha*-*-netbsd*) fmt=elf em=nbsd ;;
+
+ arc-*-elf*) fmt=elf bfd_gas=yes ;;
+
+ arm-*-aout) fmt=aout ;;
+ arm-*-coff | thumb-*-coff) fmt=coff ;;
+ arm-*-elf | thumb-*-elf) fmt=elf ;;
+ arm-*-linux*aout*) fmt=aout em=linux ;;
+ arm-*-linux* | armv*-*-linux-gnu) fmt=elf em=linux ;;
+ arm-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ arm-*-oabi | thumb-*-oabi) fmt=elf ;;
+ arm-epoc-pe | thumb-epoc-pe) fmt=coff em=epoc-pe ;;
+ arm-*-pe | thumb-*-pe) fmt=coff em=pe ;;
+ arm-*-riscix*) fmt=aout em=riscix ;;
+
+ d10v-*-*) fmt=elf bfd_gas=yes ;;
+ d30v-*-*) fmt=elf bfd_gas=yes ;;
+
+
+ fr30-*-*) fmt=elf bfd_gas=yes ;;
+
+ hppa-*-*elf*) fmt=elf em=hppa ;;
+ hppa-*-lites*) fmt=elf em=hppa ;;
+ hppa-*-osf*) fmt=som em=hppa ;;
+ hppa-*-rtems*) fmt=elf em=hppa ;;
+ hppa-*-hpux*) fmt=som em=hppa ;;
+ hppa-*-mpeix*) fmt=som em=hppa ;;
+ hppa-*-bsd*) fmt=som em=hppa ;;
+ hppa-*-hiux*) fmt=som em=hppa ;;
+
+ h8300-*-coff) fmt=coff ;;
+
+ i386-ibm-aix*) fmt=coff em=i386aix ;;
+ i386-sequent-bsd*) fmt=aout em=dynix bfd_gas=yes ;;
+ i386-*-beospe*) fmt=coff em=pe bfd_gas=yes ;;
+ i386-*-beoself* | i386-*-beos*) fmt=elf bfd_gas=yes ;;
+ i386-*-bsd*) fmt=aout em=386bsd ;;
+ i386-*-netbsd0.8) fmt=aout em=386bsd ;;
+ i386-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes;;
+ i386-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes;;
+ i386-*-linux*aout* | i386-*-linuxoldld) fmt=aout em=linux ;;
+ i386-*-linux*coff*) fmt=coff em=linux ;;
+ i386-*-linux-gnu*) fmt=elf em=linux bfd_gas=yes ;;
+ i386-*-lynxos*) fmt=coff em=lynx ;;
+ i386-*-sysv4* | i386-*-solaris* | i386-*-elf)
+ fmt=elf bfd_gas=yes ;;
+ i386-*-freebsdelf*) fmt=elf bfd_gas=yes ;;
+ i386-*-freebsd*) fmt=aout em=386bsd ;;
+ i386-*-coff | i386-*-sysv* | i386-*-sco3.2v5*coff | i386-*-isc*)
+ fmt=coff ;;
+ i386-*-sco3.2v5*) fmt=elf
+ if test ${this_target} = $target; then
+ AC_DEFINE(SCO_ELF, 1,
+ [Define if defaulting to ELF on SCO 5.])
+ fi
+ ;;
+ i386-*-sco3.2*) fmt=coff ;;
+ i386-*-vsta) fmt=aout ;;
+ i386-*-msdosdjgpp* | i386-*-go32* | i386-go32-rtems*)
+ fmt=coff em=go32;;
+ i386-*-rtems*) fmt=coff ;;
+ i386-*-gnu*) fmt=elf ;;
+ i386-*-mach*)
+ fmt=aout em=mach bfd_gas=yes ;;
+ i386-*-msdos*) fmt=aout ;;
+ i386-*-moss*) fmt=elf ;;
+ i386-*-pe) fmt=coff em=pe ;;
+ i386-*-cygwin*) fmt=coff em=pe bfd_gas=yes ;;
+ i386-*-mingw32*) fmt=coff em=pe bfd_gas=yes ;;
+ i386-*-*nt*) fmt=coff em=pe ;;
+ i960-*-bout) fmt=bout ;;
+ i960-*-coff) fmt=coff em=ic960 ;;
+ i960-*-rtems*) fmt=coff em=ic960 ;;
+ i960-*-nindy*) fmt=bout ;;
+ i960-*-vxworks4*) fmt=bout ;;
+ i960-*-vxworks5.0) fmt=bout ;;
+ i960-*-vxworks5.*) fmt=coff em=ic960 ;;
+ i960-*-vxworks*) fmt=bout ;;
+
+ m32r-*-*) fmt=elf bfd_gas=yes ;;
+
+ m68k-*-vxworks* | m68k-ericsson-ose | m68k-*-sunos*)
+ fmt=aout em=sun3 ;;
+ m68k-motorola-sysv*) fmt=coff em=delta ;;
+ m68k-bull-sysv3*) fmt=coff em=dpx2 ;;
+ m68k-apollo-*) fmt=coff em=apollo ;;
+ m68k-*-sysv4*) # must be before -sysv*
+ fmt=elf em=svr4 ;;
+ m68k-*-elf*) fmt=elf ;;
+ m68k-*-coff | m68k-*-sysv* | m68k-*-rtems*)
+ fmt=coff ;;
+ m68k-*-hpux*) fmt=hp300 em=hp300 ;;
+ m68k-*-linux*aout*) fmt=aout em=linux ;;
+ m68k-*-linux-gnu*) fmt=elf em=linux ;;
+ m68k-*-gnu*) fmt=elf ;;
+ m68k-*-lynxos*) fmt=coff em=lynx ;;
+ m68k-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-*-openbsd*) fmt=aout em=nbsd bfd_gas=yes ;;
+ m68k-apple-aux*) fmt=coff em=aux ;;
+ m68k-*-psos*) fmt=elf em=psos;;
+
+ m88k-motorola-sysv3*) fmt=coff em=delt88 ;;
+ m88k-*-coff*) fmt=coff ;;
+
+ mcore-*-elf) fmt=elf bfd_gas=yes ;;
+ mcore-*-pe) fmt=coff em=pe bfd_gas=yes ;;
+
+ # don't change em like *-*-bsd does
+ mips-dec-netbsd*) fmt=elf endian=little ;;
+ mips-dec-openbsd*) fmt=elf endian=little ;;
+ mips-dec-bsd*) fmt=aout endian=little ;;
+ mips-sony-bsd*) fmt=ecoff ;;
+ mips-*-bsd*) AC_MSG_ERROR(Unknown vendor for mips-bsd configuration.) ;;
+ mips-*-ultrix*) fmt=ecoff endian=little ;;
+ mips-*-osf*) fmt=ecoff endian=little ;;
+ mips-*-ecoff*) fmt=ecoff ;;
+ mips-*-ecoff*) fmt=ecoff ;;
+ mips-*-irix6*) fmt=elf ;;
+ mips-*-irix5*) fmt=elf ;;
+ mips-*-irix*) fmt=ecoff ;;
+ mips-*-lnews*) fmt=ecoff em=lnews ;;
+ mips-*-riscos*) fmt=ecoff ;;
+ mips-*-sysv*) fmt=ecoff ;;
+ mips-*-elf* | mips-*-rtems* | mips-*-linux-gnu* | mips-*-gnu* | mips-*-openbsd*)
+ fmt=elf ;;
+ mips-*-vxworks*) fmt=elf
+ AC_DEFINE(MIPS_STABS_ELF, 1,
+ [Use ELF stabs for MIPS, not ECOFF stabs])
+ ;;
+ mn10200-*-*) fmt=elf bfd_gas=yes ;;
+ mn10300-*-*) fmt=elf bfd_gas=yes ;;
+ ppc-*-pe | ppc-*-cygwin* | ppc-*-winnt*)
+ fmt=coff em=pe ;;
+ ppc-*-aix*) fmt=coff ;;
+ ppc-*-beos*) fmt=coff ;;
+ ppc-*-*bsd* | ppc-*-elf* | ppc-*-eabi* | ppc-*-sysv4*)
+ fmt=elf ;;
+ ppc-*-linux-gnu*) fmt=elf
+ case "$endian" in
+ big) ;;
+ *) AC_MSG_ERROR(GNU/Linux must be configured big endian) ;;
+ esac
+ ;;
+ ppc-*-solaris*) fmt=elf
+ if test ${this_target} = $target; then
+ AC_DEFINE(TARGET_SOLARIS_COMMENT, 1,
+ [Define if default target is PowerPC Solaris.])
+ fi
+ if test x${endian} = xbig; then
+ AC_MSG_ERROR(Solaris must be configured little endian)
+ fi
+ ;;
+ ppc-*-rtems*) fmt=elf ;;
+ ppc-*-macos* | ppc-*-mpw*)
+ fmt=coff em=macos ;;
+ ppc-*-netware*) fmt=elf em=ppcnw ;;
+
+ sh-*-elf*) fmt=elf ;;
+ sh-*-coff*) fmt=coff ;;
+ sh-*-rtems*) fmt=coff ;;
+
+ ns32k-pc532-mach* | ns32k-pc532-ux*) fmt=aout em=pc532mach ;;
+ ns32k-pc532-netbsd* | ns32k-pc532-lites*) fmt=aout em=nbsd532 ;;
+ ns32k-pc532-openbsd*) fmt=aout em=nbsd532 ;;
+
+ sparc-*-rtems*) fmt=aout ;;
+ sparc-*-sunos4*) fmt=aout em=sun3 ;;
+ sparc-*-aout | sparc*-*-vxworks*)
+ fmt=aout em=sparcaout ;;
+ sparc-*-coff) fmt=coff ;;
+ sparc-*-linux*aout*) fmt=aout em=linux ;;
+ sparc-*-linux-gnu*) fmt=elf em=linux ;;
+ sparc-*-lynxos*) fmt=coff em=lynx ;;
+ sparc-fujitsu-none) fmt=aout ;;
+ sparc-*-elf | sparc-*-sysv4* | sparc-*-solaris*)
+ fmt=elf ;;
+ sparc-*-netbsd*) fmt=aout em=nbsd ;;
+ sparc-*-openbsd*) fmt=aout em=nbsd ;;
+
+ strongarm-*-coff) fmt=coff ;;
+ strongarm-*-elf) fmt=elf ;;
+
+ tic30-*-*aout*) fmt=aout bfd_gas=yes ;;
+ tic30-*-*coff*) fmt=coff bfd_gas=yes ;;
+ tic80-*-*) fmt=coff ;;
+
+ v850-*-*) fmt=elf bfd_gas=yes ;;
+ v850e-*-*) fmt=elf bfd_gas=yes ;;
+ v850ea-*-*) fmt=elf bfd_gas=yes ;;
+
+ vax-*-bsd* | vax-*-ultrix*)
+ fmt=aout ;;
+ vax-*-vms) fmt=vms ;;
+
+
+ z8k-*-coff | z8k-*-sim)
+ fmt=coff ;;
+
+ w65-*-*) fmt=coff ;;
+
+ *-*-aout | *-*-scout)
+ fmt=aout ;;
+ *-*-nindy*)
+ fmt=bout ;;
+ *-*-bsd*)
+ fmt=aout em=sun3 ;;
+ *-*-generic) fmt=generic ;;
+ *-*-xray | *-*-hms) fmt=coff ;;
+ *-*-sim) fmt=coff ;;
+ *-*-elf | *-*-sysv4* | *-*-solaris*)
+ AC_MSG_WARN(GAS support for ${generic_target} is incomplete.)
+ fmt=elf dev=yes ;;
+ *-*-vxworks) fmt=aout ;;
+ *-*-netware) fmt=elf ;;
+ esac
+
+ if test ${this_target} = $target ; then
+ endian_def=
+ if test x${endian} = xbig; then
+ endian_def=1
+ elif test x${endian} = xlittle; then
+ endian_def=0
+ fi
+ if test x${endian_def} != x; then
+ AC_DEFINE_UNQUOTED(TARGET_BYTES_BIG_ENDIAN, $endian_def,
+ [Define as 1 if big endian.])
+ fi
+ fi
+
+ case ${cpu_type}-${fmt} in
+ alpha*-*) bfd_gas=yes ;;
+ arm-*) bfd_gas=yes ;;
+ # not yet
+ # i386-aout) bfd_gas=preferred ;;
+ mips-*) bfd_gas=yes ;;
+ ns32k-*) bfd_gas=yes ;;
+ ppc-*) bfd_gas=yes ;;
+ sparc-*) bfd_gas=yes ;;
+ strongarm-*) bfd_gas=yes ;;
+ *-elf) bfd_gas=yes ;;
+ *-ecoff) bfd_gas=yes ;;
+ *-som) bfd_gas=yes ;;
+ *) ;;
+ esac
+
+# Other random stuff.
+
+ # Do we need the opcodes library?
+ case ${cpu_type} in
+ vax | i386 | tic30)
+ ;;
+
+ *)
+ need_opcodes=yes
+
+ case "${enable_shared}" in
+ yes) shared_opcodes=true ;;
+ *opcodes*) shared_opcodes=true ;;
+ *) shared_opcodes=false ;;
+ esac
+ if test "${shared_opcodes}" = "true"; then
+ # A shared libopcodes must be linked against libbfd.
+ need_bfd=yes
+ fi
+ ;;
+ esac
+
+ # Any other special object files needed ?
+ case ${cpu_type} in
+ fr30 | m32r)
+ using_cgen=yes
+ ;;
+
+ m68k)
+ case ${extra_objects} in
+ *m68k-parse.o*) ;;
+ *) extra_objects="$extra_objects m68k-parse.o" ;;
+ esac
+ ;;
+
+ mips)
+ echo ${extra_objects} | grep -s "itbl-parse.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-parse.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-lex.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-lex.o"
+ fi
+
+ echo ${extra_objects} | grep -s "itbl-ops.o"
+ if test $? -ne 0 ; then
+ extra_objects="$extra_objects itbl-ops.o"
+ fi
+ ;;
+
+ sparc)
+ if test $this_target = $target ; then
+ AC_DEFINE_UNQUOTED(DEFAULT_ARCH, "${arch}", [Default architecture.])
+ fi
+ ;;
+ *)
+ ;;
+ esac
+
+ if test $using_cgen = yes ; then
+ case "x${extra_objects}" in
+ *cgen.o*) ;;
+ *) extra_objects="$extra_objects cgen.o" ;;
+ esac
+ fi
+
+# See if we really can support this configuration with the emulation code.
+
+ if test $this_target = $target ; then
+ primary_bfd_gas=$bfd_gas
+ obj_format=$fmt
+ te_file=$em
+
+ if test $bfd_gas = no ; then
+ # Can't support other configurations this way.
+ break
+ fi
+ elif test $bfd_gas = no ; then
+ # Can't support this configuration.
+ break
+ fi
+
+# From target name and format, produce a list of supported emulations.
+
+ case ${generic_target}-${fmt} in
+ mips-*-irix5*-*) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ mips-*-linux-gnu*-*) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself mipsbecoff mipslecoff mipsecoff" ;;
+ *) emulation="mipslelf mipsbelf mipself mipslecoff mipsbecoff mipsecoff" ;;
+ esac ;;
+ mips-*-lnews*-ecoff) ;;
+ mips-*-*-ecoff) case "$endian" in
+ big) emulation="mipsbecoff mipslecoff mipsecoff" ;;
+ *) emulation="mipslecoff mipsbecoff mipsecoff" ;;
+ esac ;;
+ mips-*-*-elf) case "$endian" in
+ big) emulation="mipsbelf mipslelf mipself" ;;
+ *) emulation="mipslelf mipsbelf mipself" ;;
+ # Uncommenting the next line will turn on support for i386 COFF
+ # in any i386 ELF configuration. This probably doesn't work
+ # correctly.
+ # i386-*-*-elf) emulation="i386coff i386elf" ;;
+ esac ;;
+ esac
+
+ emulations="$emulations $emulation"
+
+done
+
+# Assign floating point type. Most processors with FP support
+# IEEE FP. On those that don't support FP at all, usually IEEE
+# is emulated.
+case ${target_cpu} in
+ vax | tahoe ) atof=${target_cpu} ;;
+ *) atof=ieee ;;
+esac
+
+case "${obj_format}" in
+ "") AC_MSG_ERROR(GAS does not know what format to use for target ${target}) ;;
+esac
+
+# Unfortunately the cpu in cpu-opc.h file isn't always $(TARGET_CPU).
+cgen_cpu_prefix=""
+if test $using_cgen = yes ; then
+ case ${target_cpu} in
+ *) cgen_cpu_prefix=${target_cpu} ;;
+ esac
+ AC_SUBST(cgen_cpu_prefix)
+ AC_DEFINE(USING_CGEN, 1, [Using cgen code?])
+fi
+
+dnl
+dnl Make sure the desired support files exist.
+dnl
+
+if test ! -r ${srcdir}/config/tc-${target_cpu_type}.c; then
+ AC_MSG_ERROR(GAS does not support target CPU ${target_cpu_type})
+fi
+
+if test ! -r ${srcdir}/config/obj-${obj_format}.c; then
+ AC_MSG_ERROR(GAS does not have support for object file format ${obj_format})
+fi
+
+case ${user_bfd_gas}-${primary_bfd_gas} in
+ yes-yes | no-no)
+ # We didn't override user's choice.
+ ;;
+ no-yes)
+ AC_MSG_WARN(Use of BFD is required for ${target}; overriding config options.)
+ ;;
+ no-preferred)
+ primary_bfd_gas=no
+ ;;
+ *-preferred)
+ primary_bfd_gas=yes
+ ;;
+ yes-*)
+ primary_bfd_gas=yes
+ ;;
+ -*)
+ # User specified nothing.
+ ;;
+esac
+
+# Some COFF configurations want these random other flags set.
+case ${obj_format} in
+ coff)
+ case ${target_cpu_type} in
+ i386) AC_DEFINE(I386COFF, 1, [Using i386 COFF?]) ;;
+ m68k) AC_DEFINE(M68KCOFF, 1, [Using m68k COFF?]) ;;
+ m88k) AC_DEFINE(M88KCOFF, 1, [Using m88k COFF?]) ;;
+ esac
+ ;;
+esac
+
+# Getting this done right is going to be a bitch. Each configuration specified
+# with --enable-targets=... should be checked for environment, format, cpu, and
+# bfd_gas setting.
+#
+# For each configuration, the necessary object file support code must be linked
+# in. This might be only one, it might be up to four. The necessary emulation
+# code needs to be provided, too.
+#
+# And then there's "--enable-targets=all"....
+#
+# For now, just always do it for MIPS ELF or ECOFF configurations. Sigh.
+
+formats="${obj_format}"
+emfiles=""
+EMULATIONS=""
+GAS_UNIQ(emulations)
+for em in . $emulations ; do
+ case $em in
+ .) continue ;;
+ mipsbelf | mipslelf)
+ fmt=elf file=mipself ;;
+ mipsbecoff | mipslecoff)
+ fmt=ecoff file=mipsecoff ;;
+ i386coff)
+ fmt=coff file=i386coff ;;
+ i386elf)
+ fmt=elf file=i386elf ;;
+ esac
+ formats="$formats $fmt"
+ emfiles="$emfiles e-$file.o"
+ EMULATIONS="$EMULATIONS &$em,"
+done
+GAS_UNIQ(formats)
+GAS_UNIQ(emfiles)
+if test `set . $formats ; shift ; echo $#` -gt 1 ; then
+ for fmt in $formats ; do
+ case $fmt in
+ aout) AC_DEFINE(OBJ_MAYBE_AOUT, 1, [a.out support?]) ;;
+ bout) AC_DEFINE(OBJ_MAYBE_BOUT, 1, [b.out support?]) ;;
+ coff) AC_DEFINE(OBJ_MAYBE_COFF, 1, [COFF support?]) ;;
+ ecoff) AC_DEFINE(OBJ_MAYBE_ECOFF, 1, [ECOFF support?]) ;;
+ elf) AC_DEFINE(OBJ_MAYBE_ELF, 1, [ELF support?]) ;;
+ generic) AC_DEFINE(OBJ_MAYBE_GENERIC, 1, [generic support?]) ;;
+ hp300) AC_DEFINE(OBJ_MAYBE_HP300, 1, [HP300 support?]) ;;
+ ieee) AC_DEFINE(OBJ_MAYBE_IEEE, 1, [IEEE support?]) ;;
+ som) AC_DEFINE(OBJ_MAYBE_SOM, 1, [SOM support?]) ;;
+ vms) AC_DEFINE(OBJ_MAYBE_VMS, 1, [VMS support?]) ;;
+ esac
+ extra_objects="$extra_objects obj-$fmt.o"
+ done
+ obj_format=multi
+fi
+if test `set . $emfiles ; shift ; echo $#` -gt 0 ; then
+ te_file=multi
+ extra_objects="$extra_objects $emfiles"
+ DEFAULT_EMULATION=`set . $emulations ; echo $2`
+ AC_DEFINE(USE_EMULATIONS, 1, [Use emulation support?])
+fi
+AC_SUBST(extra_objects)
+AC_DEFINE_UNQUOTED(EMULATIONS, $EMULATIONS, [Supported emulations.])
+AC_DEFINE_UNQUOTED(DEFAULT_EMULATION, "$DEFAULT_EMULATION",
+ [Default emulation.])
+
+case ${primary_bfd_gas}-${target_cpu_type}-${obj_format} in
+ yes-*-coff) need_bfd=yes ;;
+ no-*-coff) need_bfd=yes
+ AC_DEFINE(MANY_SEGMENTS, 1, [old COFF support?]) ;;
+esac
+
+reject_dev_configs=yes
+
+case ${reject_dev_configs}-${dev} in
+ yes-yes) # Oops.
+ AC_MSG_ERROR(GAS does not support the ${generic_target} configuration.)
+ ;;
+esac
+
+AC_SUBST(target_cpu_type)
+AC_SUBST(obj_format)
+AC_SUBST(te_file)
+AC_SUBST(install_tooldir)
+AC_SUBST(atof)
+dnl AC_SUBST(emulation)
+
+case "${primary_bfd_gas}" in
+ yes) AC_DEFINE(BFD_ASSEMBLER, 1, [Use BFD interface?])
+ need_bfd=yes ;;
+esac
+
+# do we need the opcodes library?
+case "${need_opcodes}" in
+yes)
+ OPCODES_LIB=../opcodes/libopcodes.la
+ ;;
+esac
+
+case "${need_bfd}" in
+yes)
+ BFDLIB=../bfd/libbfd.la
+ ALL_OBJ_DEPS="$ALL_OBJ_DEPS ../bfd/bfd.h"
+ ;;
+esac
+
+AC_SUBST(BFDLIB)
+AC_SUBST(OPCODES_LIB)
+
+AC_SUBST(ALL_OBJ_DEPS)
+
+AC_DEFINE_UNQUOTED(TARGET_ALIAS, "${target_alias}", [Target alias.])
+AC_DEFINE_UNQUOTED(TARGET_CANONICAL, "${target}", [Canonical target.])
+AC_DEFINE_UNQUOTED(TARGET_CPU, "${target_cpu}", [Target CPU.])
+AC_DEFINE_UNQUOTED(TARGET_VENDOR, "${target_vendor}", [Target vendor.])
+AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.])
+
+AC_PROG_CC
+
+AC_PROG_YACC
+AM_PROG_LEX
+
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+AC_CHECK_HEADERS(string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h errno.h sys/types.h)
+
+# Put this here so that autoconf's "cross-compiling" message doesn't confuse
+# people who are not cross-compiling but are compiling cross-assemblers.
+AC_MSG_CHECKING(whether compiling a cross-assembler)
+if test "${host}" = "${target}"; then
+ cross_gas=no
+else
+ cross_gas=yes
+ AC_DEFINE(CROSS_COMPILE, 1, [Compiling cross-assembler?])
+fi
+AC_MSG_RESULT($cross_gas)
+
+dnl ansidecl.h will deal with const
+dnl AC_CONST
+AC_FUNC_ALLOCA
+AC_C_INLINE
+
+# VMS doesn't have unlink.
+AC_CHECK_FUNCS(unlink remove, break)
+
+# Some systems don't have sbrk().
+AC_CHECK_FUNCS(sbrk)
+
+# Some non-ANSI preprocessors botch requoting inside strings. That's bad
+# enough, but on some of those systems, the assert macro relies on requoting
+# working properly!
+GAS_WORKING_ASSERT
+
+# On some systems, the system header files may not declare malloc, realloc,
+# and free. There are places where gas needs these functions to have been
+# declared -- such as when taking their addresses.
+gas_test_headers="
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+"
+GAS_CHECK_DECL_NEEDED(strstr, f, char *(*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(malloc, f, char *(*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(free, f, void (*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(sbrk, f, char *(*f)(), $gas_test_headers)
+GAS_CHECK_DECL_NEEDED(environ, f, char **f, $gas_test_headers)
+
+# Does errno.h declare errno, or do we have to add a separate declaration
+# for it?
+GAS_CHECK_DECL_NEEDED(errno, f, int f, [
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+])
+
+dnl This must come last.
+
+dnl We used to make symlinks to files in the source directory, but now
+dnl we just use the right name for .c files, and create .h files in
+dnl the build directory which include the right .h file. Make sure
+dnl the old symlinks don't exist, so that a reconfigure in an existing
+dnl directory behaves reasonably.
+
+AC_OUTPUT(Makefile doc/Makefile .gdbinit:gdbinit.in po/Makefile.in:po/Make-in,
+[rm -f targ-cpu.c targ-cpu.h obj-format.h obj-format.c targ-env.h atof-targ.c itbl-cpu.h
+ echo '#include "tc-'"${target_cpu_type}"'.h"' > targ-cpu.h
+ echo '#include "obj-'"${obj_format}"'.h"' > obj-format.h
+ echo '#include "te-'"${te_file}"'.h"' > targ-env.h
+ echo '#include "itbl-'"${target_cpu_type}"'.h"' > itbl-cpu.h
+ if test "x$cgen_cpu_prefix" != x ; then
+ echo '#include "opcodes/'"${cgen_cpu_prefix}"'-desc.h"' > cgen-desc.h
+ fi
+
+ sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile],
+[target_cpu_type=${target_cpu_type}
+ cgen_cpu_prefix=${cgen_cpu_prefix}
+ obj_format=${obj_format}
+ te_file=${te_file}])
diff --git a/gas/debug.c b/gas/debug.c
new file mode 100644
index 00000000000..e99f23f32a6
--- /dev/null
+++ b/gas/debug.c
@@ -0,0 +1,104 @@
+/* This file is debug.c
+ Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Routines for debug use only. */
+
+#include "as.h"
+#include "subsegs.h"
+
+dmp_frags ()
+{
+ frchainS *chp;
+ char *p;
+
+ for (chp = frchain_root; chp; chp = chp->frch_next)
+ {
+ switch (chp->frch_seg)
+ {
+ case SEG_DATA:
+ p = "Data";
+ break;
+ case SEG_TEXT:
+ p = "Text";
+ break;
+ default:
+ p = "???";
+ break;
+ }
+ printf ("\nSEGMENT %s %d\n", p, chp->frch_subseg);
+ dmp_frag (chp->frch_root, "\t");
+ }
+}
+
+dmp_frag (fp, indent)
+ struct frag *fp;
+ char *indent;
+{
+ for (; fp; fp = fp->fr_next)
+ {
+ printf ("%sFRAGMENT @ 0x%x\n", indent, fp);
+ switch (fp->fr_type)
+ {
+ case rs_align:
+ printf ("%srs_align(%d)\n", indent, fp->fr_offset);
+ break;
+ case rs_fill:
+ printf ("%srs_fill(%d)\n", indent, fp->fr_offset);
+ printf ("%s", indent);
+ var_chars (fp, fp->fr_var + fp->fr_fix);
+ printf ("%s\t repeated %d times,",
+ indent, fp->fr_offset);
+ printf (" fixed length if # chars == 0)\n");
+ break;
+ case rs_org:
+ printf ("%srs_org(%d+sym @0x%x)\n", indent,
+ fp->fr_offset, fp->fr_symbol);
+ printf ("%sfill with ", indent);
+ var_chars (fp, 1);
+ printf ("\n");
+ break;
+ case rs_machine_dependent:
+ printf ("%smachine_dep\n", indent);
+ break;
+ default:
+ printf ("%sunknown type\n", indent);
+ break;
+ }
+ printf ("%saddr=%d(0x%x)\n", indent, fp->fr_address, fp->fr_address);
+ printf ("%sfr_fix=%d\n", indent, fp->fr_fix);
+ printf ("%sfr_var=%d\n", indent, fp->fr_var);
+ printf ("%sfr_offset=%d\n", indent, fp->fr_offset);
+ printf ("%schars @ 0x%x\n", indent, fp->fr_literal);
+ printf ("\n");
+ }
+}
+
+var_chars (fp, n)
+ struct frag *fp;
+ int n;
+{
+ unsigned char *p;
+
+ for (p = (unsigned char *) fp->fr_literal; n; n--, p++)
+ {
+ printf ("%02x ", *p);
+ }
+}
+
+/* end of debug.c */
diff --git a/gas/dep-in.sed b/gas/dep-in.sed
new file mode 100644
index 00000000000..c07f9693b0d
--- /dev/null
+++ b/gas/dep-in.sed
@@ -0,0 +1,45 @@
+:loop
+/\\$/N
+/\\$/b loop
+
+s! ../config.h!!g
+s! ../../bfd/bfd.h!!g
+s! ../itbl-parse.h!!g
+s!@INCDIR@!$(INCDIR)!g
+s!@BFDDIR@!$(BFDDIR)!g
+s!@SRCDIR@/config!$(srcdir)/config!g
+s!@SRCDIR@/../opcodes!$(srcdir)/../opcodes!g
+s!@SRCDIR@/!!g
+s! config.h!!g
+s! as.h!!g
+s! asintl.h!!g
+s! targ-env.h!!g
+s! obj-format.h!!g
+s! targ-cpu.h!!g
+s! flonum.h!!g
+s! expr.h!!g
+s! struc-symbol.h!!g
+s! write.h!!g
+s! frags.h!!g
+s! hash.h!!g
+s! read.h!!g
+s! symbols.h!!g
+s! tc.h!!g
+s! obj.h!!g
+s! listing.h!!g
+s! bignum.h!!g
+s! bit_fix.h!!g
+s! itbl-cpu.h!!g
+s! \$(srcdir)/config/te-generic.h!!g
+s! \$(INCDIR)/libiberty.h!!g
+s! \$(INCDIR)/ansidecl.h!!g
+s! \$(INCDIR)/fopen-same.h!!g
+
+s/\\\n */ /g
+
+s/ *$//
+s/ */ /g
+/:$/d
+
+s/\(.\{50\}[^ ]*\) /\1 \\\
+ /g
diff --git a/gas/depend.c b/gas/depend.c
new file mode 100644
index 00000000000..f17c7c8e3a0
--- /dev/null
+++ b/gas/depend.c
@@ -0,0 +1,208 @@
+/* depend.c - Handle dependency tracking.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+/* The file to write to, or NULL if no dependencies being kept. */
+static char *dep_file = NULL;
+
+struct dependency
+{
+ char *file;
+ struct dependency *next;
+};
+
+/* All the files we depend on. */
+static struct dependency *dep_chain = NULL;
+
+/* Current column in output file. */
+static int column = 0;
+
+static int quote_string_for_make PARAMS ((FILE *, char *));
+static void wrap_output PARAMS ((FILE *, char *, int));
+
+/* Number of columns allowable. */
+#define MAX_COLUMNS 72
+
+
+
+/* Start saving dependencies, to be written to FILENAME. If this is
+ never called, then dependency tracking is simply skipped. */
+
+void
+start_dependencies (filename)
+ char *filename;
+{
+ dep_file = filename;
+}
+
+/* Noticed a new filename, so try to register it. */
+
+void
+register_dependency (filename)
+ char *filename;
+{
+ struct dependency *dep;
+
+ if (dep_file == NULL)
+ return;
+
+ for (dep = dep_chain; dep != NULL; dep = dep->next)
+ {
+ if (! strcmp (filename, dep->file))
+ return;
+ }
+
+ dep = (struct dependency *) xmalloc (sizeof (struct dependency));
+ dep->file = xstrdup (filename);
+ dep->next = dep_chain;
+ dep_chain = dep;
+}
+
+/* Quote a file name the way `make' wants it, and print it to FILE.
+ If FILE is NULL, do no printing, but return the length of the
+ quoted string.
+
+ This code is taken from gcc with only minor changes. */
+
+static int
+quote_string_for_make (file, src)
+ FILE *file;
+ char *src;
+{
+ char *p = src;
+ int i = 0;
+ for (;;)
+ {
+ char c = *p++;
+ switch (c)
+ {
+ case '\0':
+ case ' ':
+ case '\t':
+ {
+ /* GNU make uses a weird quoting scheme for white space.
+ A space or tab preceded by 2N+1 backslashes represents
+ N backslashes followed by space; a space or tab
+ preceded by 2N backslashes represents N backslashes at
+ the end of a file name; and backslashes in other
+ contexts should not be doubled. */
+ char *q;
+ for (q = p - 1; src < q && q[-1] == '\\'; q--)
+ {
+ if (file)
+ putc ('\\', file);
+ i++;
+ }
+ }
+ if (!c)
+ return i;
+ if (file)
+ putc ('\\', file);
+ i++;
+ goto ordinary_char;
+
+ case '$':
+ if (file)
+ putc (c, file);
+ i++;
+ /* Fall through. This can mishandle things like "$(" but
+ there's no easy fix. */
+ default:
+ ordinary_char:
+ /* This can mishandle characters in the string "\0\n%*?[\\~";
+ exactly which chars are mishandled depends on the `make' version.
+ We know of no portable solution for this;
+ even GNU make 3.76.1 doesn't solve the problem entirely.
+ (Also, '\0' is mishandled due to our calling conventions.) */
+ if (file)
+ putc (c, file);
+ i++;
+ break;
+ }
+ }
+}
+
+/* Append some output to the file, keeping track of columns and doing
+ wrapping as necessary. */
+
+static void
+wrap_output (f, string, spacer)
+ FILE *f;
+ char *string;
+ int spacer;
+{
+ int len = quote_string_for_make (NULL, string);
+
+ if (len == 0)
+ return;
+
+ if (column && MAX_COLUMNS - 1 /*spacer*/ - 2 /*` \'*/ < column + len)
+ {
+ fprintf (f, " \\\n ");
+ column = 0;
+ if (spacer == ' ')
+ spacer = '\0';
+ }
+
+ if (spacer == ' ')
+ {
+ putc (spacer, f);
+ ++column;
+ }
+
+ quote_string_for_make (f, string);
+ column += len;
+
+ if (spacer == ':')
+ {
+ putc (spacer, f);
+ ++column;
+ }
+}
+
+/* Print dependency file. */
+
+void
+print_dependencies ()
+{
+ FILE *f;
+ struct dependency *dep;
+
+ if (dep_file == NULL)
+ return;
+
+ f = fopen (dep_file, "w");
+ if (f == NULL)
+ {
+ as_warn (_("Can't open `%s' for writing"), dep_file);
+ return;
+ }
+
+ column = 0;
+ wrap_output (f, out_file_name, ':');
+ for (dep = dep_chain; dep != NULL; dep = dep->next)
+ wrap_output (f, dep->file, ' ');
+
+ putc ('\n', f);
+
+ if (fclose (f))
+ as_warn (_("Can't close `%s'"), dep_file);
+}
diff --git a/gas/doc/Makefile.am b/gas/doc/Makefile.am
new file mode 100644
index 00000000000..eaf5a4ab145
--- /dev/null
+++ b/gas/doc/Makefile.am
@@ -0,0 +1,49 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+# What version of the manual you want; "all" includes everything
+CONFIG=all
+
+man_MANS = as.1
+
+info_TEXINFOS = as.texinfo gasp.texi
+
+asconfig.texi: $(CONFIG).texi
+ rm -f asconfig.texi
+ ln -s $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || ln $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || cp $(srcdir)/$(CONFIG).texi ./asconfig.texi
+
+CPU_DOCS = \
+ c-a29k.texi \
+ c-arm.texi \
+ c-d10v.texi \
+ c-h8300.texi \
+ c-h8500.texi \
+ c-hppa.texi \
+ c-i386.texi \
+ c-i960.texi \
+ c-m68k.texi \
+ c-mips.texi \
+ c-ns32k.texi \
+ c-sh.texi \
+ c-sparc.texi \
+ c-vax.texi \
+ c-v850.texi \
+ c-z8k.texi
+
+gasver.texi: Makefile
+ rm -f $@
+ echo '@set VERSION $(VERSION)' > $@
+
+as.info: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+as.dvi: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+
+# This one isn't ready for prime time yet. Not even a little bit.
+
+noinst_TEXINFOS = internals.texi
+
+DISTCLEANFILES = asconfig.texi
+
+MAINTAINERCLEANFILES = gasver.texi
diff --git a/gas/doc/Makefile.in b/gas/doc/Makefile.in
new file mode 100644
index 00000000000..5f4d1a52693
--- /dev/null
+++ b/gas/doc/Makefile.in
@@ -0,0 +1,438 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+ALL_OBJ_DEPS = @ALL_OBJ_DEPS@
+AS = @AS@
+BFDLIB = @BFDLIB@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LEX = @LEX@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+OPCODES_LIB = @OPCODES_LIB@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
+VERSION = @VERSION@
+YACC = @YACC@
+atof = @atof@
+cgen_cpu_prefix = @cgen_cpu_prefix@
+extra_objects = @extra_objects@
+install_tooldir = @install_tooldir@
+l = @l@
+obj_format = @obj_format@
+target_cpu_type = @target_cpu_type@
+te_file = @te_file@
+
+AUTOMAKE_OPTIONS = cygnus
+
+# What version of the manual you want; "all" includes everything
+CONFIG = all
+
+man_MANS = as.1
+
+info_TEXINFOS = as.texinfo gasp.texi
+
+CPU_DOCS = \
+ c-a29k.texi \
+ c-arm.texi \
+ c-d10v.texi \
+ c-h8300.texi \
+ c-h8500.texi \
+ c-hppa.texi \
+ c-i386.texi \
+ c-i960.texi \
+ c-m68k.texi \
+ c-mips.texi \
+ c-ns32k.texi \
+ c-sh.texi \
+ c-sparc.texi \
+ c-vax.texi \
+ c-v850.texi \
+ c-z8k.texi
+
+
+# This one isn't ready for prime time yet. Not even a little bit.
+
+noinst_TEXINFOS = internals.texi
+
+DISTCLEANFILES = asconfig.texi
+
+MAINTAINERCLEANFILES = gasver.texi
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi`
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+INFO_DEPS = as.info gasp.info
+DVIS = as.dvi gasp.dvi
+TEXINFOS = as.texinfo gasp.texi
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+
+NROFF = nroff
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .dvi .info .ps .texi .texinfo .txi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+as.info: as.texinfo
+as.dvi: as.texinfo
+
+
+gasp.info: gasp.texi
+gasp.dvi: gasp.texi
+
+
+DVIPS = dvips
+
+.texi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.txi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f as.aux as.cp as.cps as.dvi as.fn as.fns as.ky as.kys as.ps \
+ as.log as.pg as.toc as.tp as.tps as.vr as.vrs as.op as.tr \
+ as.cv as.cn gasp.aux gasp.cp gasp.cps gasp.dvi gasp.fn \
+ gasp.fns gasp.ky gasp.kys gasp.ps gasp.log gasp.pg gasp.toc \
+ gasp.tp gasp.tps gasp.vr gasp.vrs gasp.op gasp.tr gasp.cv \
+ gasp.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+clean-info: mostlyclean-aminfo
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+info-am: $(INFO_DEPS)
+info: info-am
+dvi-am: $(DVIS)
+dvi: dvi-am
+check-am:
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-info-am:
+install-info: install-info-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am: install-man
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-man
+uninstall: uninstall-am
+all-am: Makefile $(MANS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(mandir)/man1
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-aminfo clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-aminfo distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-aminfo maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: install-info-am uninstall-info mostlyclean-aminfo \
+distclean-aminfo clean-aminfo maintainer-clean-aminfo install-man1 \
+uninstall-man1 install-man uninstall-man tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-info-am \
+install-info install-exec-am install-exec install-data-am install-data \
+install-am install uninstall-am uninstall all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+asconfig.texi: $(CONFIG).texi
+ rm -f asconfig.texi
+ ln -s $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || ln $(srcdir)/$(CONFIG).texi ./asconfig.texi >/dev/null 2>&1 \
+ || cp $(srcdir)/$(CONFIG).texi ./asconfig.texi
+
+gasver.texi: Makefile
+ rm -f $@
+ echo '@set VERSION $(VERSION)' > $@
+
+as.info: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+as.dvi: $(srcdir)/as.texinfo asconfig.texi gasver.texi $(CPU_DOCS)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
new file mode 100644
index 00000000000..9b90c5badaf
--- /dev/null
+++ b/gas/doc/all.texi
@@ -0,0 +1,72 @@
+@c Copyright 1992, 1993 Free Software Foundation, Inc.
+@c This file is part of the documentation for the GAS manual
+
+@c Configuration settings for all-inclusive version of manual
+
+@c switches:------------------------------------------------------------
+@c Properties of the manual
+@c ========================
+@c Discuss all architectures?
+@set ALL-ARCH
+@c A generic form of manual (not tailored to specific target)?
+@set GENERIC
+@c Include text on assembler internals?
+@clear INTERNALS
+@c Many object formats supported in this config?
+@set MULTI-OBJ
+
+@c Object formats of interest
+@c ==========================
+@set AOUT
+@set BOUT
+@set COFF
+@set ELF
+@set SOM
+
+@c CPUs of interest
+@c ================
+@set A29K
+@set ARC
+@set ARM
+@set D10V
+@set D30V
+@set H8/300
+@set H8/500
+@set SH
+@set I80386
+@set I960
+@set MCORE
+@set MIPS
+@set M32R
+@set M680X0
+@set Z8000
+@set SPARC
+@set VAX
+@set VXWORKS
+@set HPPA
+@set V850
+
+@c Does this version of the assembler use the difference-table kluge?
+@set DIFF-TBL-KLUGE
+
+@c Do all machines described use IEEE floating point?
+@clear IEEEFLOAT
+
+@c Is a word 32 bits, or 16?
+@clear W32
+@set W16
+
+@c Do symbols have different characters than usual?
+@clear SPECIAL-SYMS
+
+@c strings:------------------------------------------------------------
+@c Name of the assembler:
+@set AS as
+@c Name of C compiler:
+@set GCC gcc
+@c Name of linker:
+@set LD ld
+@c Text for target machine (best not used in generic case; but just in case...)
+@set TARGET machine specific
+@c Name of object format NOT SET in generic version
+@clear OBJ-NAME
diff --git a/gas/doc/as.1 b/gas/doc/as.1
new file mode 100644
index 00000000000..adf28868eac
--- /dev/null
+++ b/gas/doc/as.1
@@ -0,0 +1,302 @@
+.\" Copyright (c) 1991, 1992, 1996, 1997, 1998 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH as 1 "29 March 1996" "cygnus support" "GNU Development Tools"
+
+.SH NAME
+GNU as \- the portable GNU assembler.
+
+.SH SYNOPSIS
+.na
+.B as
+.RB "[\|" \-a "[\|" dhlns "\|]" \c
+\&\[\|\=\c
+.I file\c
+\&\|]\|]
+.RB "[\|" \-D "\|]"
+.RB "[\|" \-\-defsym\ SYM=VAL "\|]"
+.RB "[\|" \-f "\|]"
+.RB "[\|" \-\-gstabs "\|]"
+.RB "[\|" \-I
+.I path\c
+\&\|]
+.RB "[\|" \-K "\|]"
+.RB "[\|" \-L "\|]"
+.RB "[\|" \-M\ |\ \-\-mri "\|]"
+.RB "[\|" \-o
+.I objfile\c
+\&\|]
+.RB "[\|" \-R "\|]"
+.RB "[\|" \-\-traditional\-format "\|]"
+.RB "[\|" \-v "\|]"
+.RB "[\|" \-w "\|]"
+.RB "[\|" \-\^\- "\ |\ " \c
+.I files\c
+\&\|.\|.\|.\|]
+
+.I i960-only options:
+.br
+.RB "[\|" \-ACA "\||\|" \-ACA_A "\||\|" \-ACB\c
+.RB "\||\|" \-ACC "\||\|" \-AKA "\||\|" \-AKB\c
+.RB "\||\|" \-AKC "\||\|" \-AMC "\|]"
+.RB "[\|" \-b "\|]"
+.RB "[\|" \-no-relax "\|]"
+
+.I m680x0-only options:
+.br
+.RB "[\|" \-l "\|]"
+.RB "[\|" \-mc68000 "\||\|" \-mc68010 "\||\|" \-mc68020 "\|]"
+.ad b
+
+.SH DESCRIPTION
+GNU \c
+.B as\c
+\& is really a family of assemblers.
+If you use (or have used) the GNU assembler on one architecture, you
+should find a fairly similar environment when you use it on another
+architecture. Each version has much in common with the others,
+including object file formats, most assembler directives (often called
+\c
+.I pseudo-ops)\c
+\& and assembler syntax.
+
+For information on the syntax and pseudo-ops used by GNU \c
+.B as\c
+\&, see `\|\c
+.B as\c
+\|' entry in \c
+.B info \c
+(or the manual \c
+.I
+.I
+Using as: The GNU Assembler\c
+\&).
+
+\c
+.B as\c
+\& is primarily intended to assemble the output of the GNU C
+compiler \c
+.B gcc\c
+\& for use by the linker \c
+.B ld\c
+\&. Nevertheless,
+we've tried to make \c
+.B as\c
+\& assemble correctly everything that the native
+assembler would.
+This doesn't mean \c
+.B as\c
+\& always uses the same syntax as another
+assembler for the same architecture; for example, we know of several
+incompatible versions of 680x0 assembly language syntax.
+
+Each time you run \c
+.B as\c
+\& it assembles exactly one source
+program. The source program is made up of one or more files.
+(The standard input is also a file.)
+
+If \c
+.B as\c
+\& is given no file names it attempts to read one input file
+from the \c
+.B as\c
+\& standard input, which is normally your terminal. You
+may have to type \c
+.B ctl-D\c
+\& to tell \c
+.B as\c
+\& there is no more program
+to assemble. Use `\|\c
+.B \-\^\-\c
+\|' if you need to explicitly name the standard input file
+in your command line.
+
+.B as\c
+\& may write warnings and error messages to the standard error
+file (usually your terminal). This should not happen when \c
+.B as\c
+\& is
+run automatically by a compiler. Warnings report an assumption made so
+that \c
+.B as\c
+\& could keep assembling a flawed program; errors report a
+grave problem that stops the assembly.
+
+.SH OPTIONS
+.TP
+.BR \-a
+Turn on assembly listings. There are various suboptions.
+.B d
+omits debugging directives.
+.B h
+includes the high level source code; this is only available if the
+source file can be found, and the code was compiled with
+.B \-g.
+.B l
+includes an assembly listing.
+.B n
+omits forms processing.
+.B s
+includes a symbol listing.
+.B =
+.I file
+sets the listing file name; this must be the last suboption.
+The default suboptions are
+.B hls.
+.TP
+.B \-D
+This option is accepted only for script compatibility with calls to
+other assemblers; it has no effect on \c
+.B as\c
+\&.
+.TP
+.B \-\-defsym SYM=VALUE
+Define the symbol SYM to be VALUE before assembling the input file.
+VALUE must be an integer constant. As in C, a leading 0x indicates a
+hexadecimal value, and a leading 0 indicates an octal value.
+.TP
+.B \-f
+``fast''--skip preprocessing (assume source is compiler output).
+.TP
+.BI "\-I\ " path
+Add
+.I path
+to the search list for
+.B .include
+directives.
+.TP
+.B \-\-gstabs
+Generate stabs debugging information for each assembler line. This
+may help debugging assembler code, if the debugger can handle it.
+.TP
+.B \-K
+Issue warnings when difference tables altered for long displacements.
+.TP
+.B \-L
+Keep (in symbol table) local symbols, starting with `\|\c
+.B L\c
+\|'
+.TP
+.B \-M, \-\-mri
+Assemble in MRI compatibility mode.
+.TP
+.BI "\-o\ " objfile
+Name the object-file output from \c
+.B as
+.TP
+.B \-R
+Fold data section into text section
+.TP
+.B \-\-traditional\-format
+Use same format as native assembler, when possible.
+.TP
+.B \-v
+Announce \c
+.B as\c
+\& version
+.TP
+.B \-W
+Suppress warning messages
+.TP
+.IR "\-\^\-" "\ |\ " "files\|.\|.\|."
+Source files to assemble, or standard input (\c
+.BR "\-\^\-" ")"
+.TP
+.BI \-A var
+.I
+(When configured for Intel 960.)
+Specify which variant of the 960 architecture is the target.
+.TP
+.B \-b
+.I
+(When configured for Intel 960.)
+Add code to collect statistics about branches taken.
+.TP
+.B \-no-relax
+.I
+(When configured for Intel 960.)
+Do not alter compare-and-branch instructions for long displacements;
+error if necessary.
+.TP
+.B \-l
+.I
+(When configured for Motorola 68000).
+.br
+Shorten references to undefined symbols, to one word instead of two.
+.TP
+.BR "\-mc68000" "\||\|" "\-mc68010" "\||\|" "\-mc68020"
+.I
+(When configured for Motorola 68000).
+.br
+Specify what processor in the 68000 family is the target (default 68020)
+
+.PP
+Options may be in any order, and may be
+before, after, or between file names. The order of file names is
+significant.
+
+`\|\c
+.B \-\^\-\c
+\|' (two hyphens) by itself names the standard input file
+explicitly, as one of the files for \c
+.B as\c
+\& to assemble.
+
+Except for `\|\c
+.B \-\^\-\c
+\|' any command line argument that begins with a
+hyphen (`\|\c
+.B \-\c
+\|') is an option. Each option changes the behavior of
+\c
+.B as\c
+\&. No option changes the way another option works. An
+option is a `\|\c
+.B \-\c
+\|' followed by one or more letters; the case of
+the letter is important. All options are optional.
+
+The `\|\c
+.B \-o\c
+\|' option expects exactly one file name to follow. The file
+name may either immediately follow the option's letter (compatible
+with older assemblers) or it may be the next command argument (GNU
+standard).
+
+These two command lines are equivalent:
+.br
+.B
+as\ \ \-o\ \ my\-object\-file.o\ \ mumble.s
+.br
+.B
+as\ \ \-omy\-object\-file.o\ \ mumble.s
+
+.SH "SEE ALSO"
+.RB "`\|" as "\|'"
+entry in
+.B
+info\c
+\&;
+.I
+Using as: The GNU Assembler\c
+\&;
+.BR gcc "(" 1 "),"
+.BR ld "(" 1 ")."
+
+.SH COPYING
+Copyright (c) 1991, 1992 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
new file mode 100644
index 00000000000..afe362a7fb2
--- /dev/null
+++ b/gas/doc/as.texinfo
@@ -0,0 +1,5322 @@
+\input texinfo @c -*-Texinfo-*-
+@c Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998
+@c Free Software Foundation, Inc.
+@c UPDATE!! On future updates--
+@c (1) check for new machine-dep cmdline options in
+@c md_parse_option definitions in config/tc-*.c
+@c (2) for platform-specific directives, examine md_pseudo_op
+@c in config/tc-*.c
+@c (3) for object-format specific directives, examine obj_pseudo_op
+@c in config/obj-*.c
+@c (4) portable directives in potable[] in read.c
+@c %**start of header
+@setfilename as.info
+@c ---config---
+@c defaults, config file may override:
+@set have-stabs
+@c ---
+@include asconfig.texi
+@include gasver.texi
+@c ---
+@c common OR combinations of conditions
+@ifset AOUT
+@set aout-bout
+@end ifset
+@ifset ARM/Thumb
+@set ARM
+@end ifset
+@ifset BOUT
+@set aout-bout
+@end ifset
+@ifset H8/300
+@set H8
+@end ifset
+@ifset H8/500
+@set H8
+@end ifset
+@ifset SH
+@set H8
+@end ifset
+@ifset HPPA
+@set abnormal-separator
+@end ifset
+@c ------------
+@ifset GENERIC
+@settitle Using @value{AS}
+@end ifset
+@ifclear GENERIC
+@settitle Using @value{AS} (@value{TARGET})
+@end ifclear
+@setchapternewpage odd
+@c %**end of header
+
+@c @smallbook
+@c @set SMALL
+@c WARE! Some of the machine-dependent sections contain tables of machine
+@c instructions. Except in multi-column format, these tables look silly.
+@c Unfortunately, Texinfo doesn't have a general-purpose multi-col format, so
+@c the multi-col format is faked within @example sections.
+@c
+@c Again unfortunately, the natural size that fits on a page, for these tables,
+@c is different depending on whether or not smallbook is turned on.
+@c This matters, because of order: text flow switches columns at each page
+@c break.
+@c
+@c The format faked in this source works reasonably well for smallbook,
+@c not well for the default large-page format. This manual expects that if you
+@c turn on @smallbook, you will also uncomment the "@set SMALL" to enable the
+@c tables in question. You can turn on one without the other at your
+@c discretion, of course.
+@ifinfo
+@set SMALL
+@c the insn tables look just as silly in info files regardless of smallbook,
+@c might as well show 'em anyways.
+@end ifinfo
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* As: (as). The GNU assembler.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@finalout
+@syncodeindex ky cp
+
+@ifinfo
+This file documents the GNU Assembler "@value{AS}".
+
+Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this manual
+under the conditions for verbatim copying, provided that the entire resulting
+derived work is distributed under the terms of a permission notice identical to
+this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@titlepage
+@title Using @value{AS}
+@subtitle The @sc{gnu} Assembler
+@ifclear GENERIC
+@subtitle for the @value{TARGET} family
+@end ifclear
+@sp 1
+@subtitle Version @value{VERSION}
+@sp 1
+@sp 13
+The Free Software Foundation Inc. thanks The Nice Computer
+Company of Australia for loaning Dean Elsner to write the
+first (Vax) version of @code{as} for Project @sc{gnu}.
+The proprietors, management and staff of TNCCA thank FSF for
+distracting the boss while they got some work
+done.
+@sp 3
+@author Dean Elsner, Jay Fenlason & friends
+@page
+@tex
+{\parskip=0pt
+\hfill {\it Using {\tt @value{AS}}}\par
+\hfill Edited by Cygnus Support\par
+}
+%"boxit" macro for figures:
+%Modified from Knuth's ``boxit'' macro from TeXbook (answer to exercise 21.3)
+\gdef\boxit#1#2{\vbox{\hrule\hbox{\vrule\kern3pt
+ \vbox{\parindent=0pt\parskip=0pt\hsize=#1\kern3pt\strut\hfil
+#2\hfil\strut\kern3pt}\kern3pt\vrule}\hrule}}%box with visible outline
+\gdef\ibox#1#2{\hbox to #1{#2\hfil}\kern8pt}% invisible box
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this manual
+under the conditions for verbatim copying, provided that the entire resulting
+derived work is distributed under the terms of a permission notice identical to
+this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+
+@ifinfo
+@node Top
+@top Using @value{AS}
+
+This file is a user guide to the @sc{gnu} assembler @code{@value{AS}} version
+@value{VERSION}.
+@ifclear GENERIC
+This version of the file describes @code{@value{AS}} configured to generate
+code for @value{TARGET} architectures.
+@end ifclear
+@menu
+* Overview:: Overview
+* Invoking:: Command-Line Options
+* Syntax:: Syntax
+* Sections:: Sections and Relocation
+* Symbols:: Symbols
+* Expressions:: Expressions
+* Pseudo Ops:: Assembler Directives
+* Machine Dependencies:: Machine Dependent Features
+* Reporting Bugs:: Reporting Bugs
+* Acknowledgements:: Who Did What
+* Index:: Index
+@end menu
+@end ifinfo
+
+@node Overview
+@chapter Overview
+@iftex
+This manual is a user guide to the @sc{gnu} assembler @code{@value{AS}}.
+@ifclear GENERIC
+This version of the manual describes @code{@value{AS}} configured to generate
+code for @value{TARGET} architectures.
+@end ifclear
+@end iftex
+
+@cindex invocation summary
+@cindex option summary
+@cindex summary of options
+Here is a brief summary of how to invoke @code{@value{AS}}. For details,
+@pxref{Invoking,,Comand-Line Options}.
+
+@c We don't use deffn and friends for the following because they seem
+@c to be limited to one line for the header.
+@smallexample
+@value{AS} [ -a[cdhlns][=file] ] [ -D ] [ --defsym @var{sym}=@var{val} ]
+ [ -f ] [ --gstabs ] [ --help ] [ -I @var{dir} ] [ -J ] [ -K ] [ -L ]
+ [ --keep-locals ] [ -o @var{objfile} ] [ -R ] [ --statistics ] [ -v ]
+ [ -version ] [ --version ] [ -W ] [ -w ] [ -x ] [ -Z ]
+@ifset A29K
+@c am29k has no machine-dependent assembler options
+@end ifset
+@ifset ARC
+ [ -mbig-endian | -mlittle-endian ]
+@end ifset
+@ifset ARM
+ [ -m[arm]1 | -m[arm]2 | -m[arm]250 | -m[arm]3 | -m[arm]6 | -m[arm]7[t][[d]m[i]] ]
+ [ -m[arm]v2 | -m[arm]v2a | -m[arm]v3 | -m[arm]v3m | -m[arm]v4 | -m[arm]v4t ]
+ [ -mthumb | -mall ]
+ [ -mfpa10 | -mfpa11 | -mfpe-old | -mno-fpu ]
+ [ -EB | -EL ]
+ [ -mapcs-32 | -mapcs-26 ]
+@end ifset
+@ifset D10V
+ [ -O ]
+@end ifset
+@ifset D30V
+ [ -O | -n | -N ]
+@end ifset
+@ifset H8
+@c Hitachi family chips have no machine-dependent assembler options
+@end ifset
+@ifset HPPA
+@c HPPA has no machine-dependent assembler options (yet).
+@end ifset
+@ifset SPARC
+@c The order here is important. See c-sparc.texi.
+ [ -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite
+ -Av8plus | -Av8plusa | -Av9 | -Av9a ]
+ [ -xarch=v8plus | -xarch=v8plusa ] [ -bump ] [ -32 | -64 ]
+@end ifset
+@ifset Z8000
+@c Z8000 has no machine-dependent assembler options
+@end ifset
+@ifset I960
+@c see md_parse_option in tc-i960.c
+ [ -ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC ]
+ [ -b ] [ -no-relax ]
+@end ifset
+@ifset M680X0
+ [ -l ] [ -m68000 | -m68010 | -m68020 | ... ]
+@end ifset
+@ifset MCORE
+ [ -jsri2bsr ] [ -sifilter ] [ -relax ]
+@end ifset
+@ifset MIPS
+ [ -nocpp ] [ -EL ] [ -EB ] [ -G @var{num} ] [ -mcpu=@var{CPU} ]
+ [ -mips1 ] [ -mips2 ] [ -mips3 ] [ -m4650 ] [ -no-m4650 ]
+ [ --trap ] [ --break ]
+ [ --emulation=@var{name} ]
+@end ifset
+ [ -- | @var{files} @dots{} ]
+@end smallexample
+
+@table @code
+@item -a[cdhlmns]
+Turn on listings, in any of a variety of ways:
+
+@table @code
+@item -ac
+omit false conditionals
+
+@item -ad
+omit debugging directives
+
+@item -ah
+include high-level source
+
+@item -al
+include assembly
+
+@item -am
+include macro expansions
+
+@item -an
+omit forms processing
+
+@item -as
+include symbols
+
+@item =file
+set the name of the listing file
+@end table
+
+You may combine these options; for example, use @samp{-aln} for assembly
+listing without forms processing. The @samp{=file} option, if used, must be
+the last one. By itself, @samp{-a} defaults to @samp{-ahls}.
+
+@item -D
+Ignored. This option is accepted for script compatibility with calls to
+other assemblers.
+
+@item --defsym @var{sym}=@var{value}
+Define the symbol @var{sym} to be @var{value} before assembling the input file.
+@var{value} must be an integer constant. As in C, a leading @samp{0x}
+indicates a hexadecimal value, and a leading @samp{0} indicates an octal value.
+
+@item -f
+``fast''---skip whitespace and comment preprocessing (assume source is
+compiler output).
+
+@item --gstabs
+Generate stabs debugging information for each assembler line. This
+may help debugging assembler code, if the debugger can handle it.
+
+@item --help
+Print a summary of the command line options and exit.
+
+@item -I @var{dir}
+Add directory @var{dir} to the search list for @code{.include} directives.
+
+@item -J
+Don't warn about signed overflow.
+
+@item -K
+@ifclear DIFF-TBL-KLUGE
+This option is accepted but has no effect on the @value{TARGET} family.
+@end ifclear
+@ifset DIFF-TBL-KLUGE
+Issue warnings when difference tables altered for long displacements.
+@end ifset
+
+@item -L
+@itemx --keep-locals
+Keep (in the symbol table) local symbols. On traditional a.out systems
+these start with @samp{L}, but different systems have different local
+label prefixes.
+
+@item -o @var{objfile}
+Name the object-file output from @code{@value{AS}} @var{objfile}.
+
+@item -R
+Fold the data section into the text section.
+
+@item --statistics
+Print the maximum space (in bytes) and total time (in seconds) used by
+assembly.
+
+@item --strip-local-absolute
+Remove local absolute symbols from the outgoing symbol table.
+
+@item -v
+@itemx -version
+Print the @code{as} version.
+
+@item --version
+Print the @code{as} version and exit.
+
+@item -W
+Suppress warning messages.
+
+@item -w
+Ignored.
+
+@item -x
+Ignored.
+
+@item -Z
+Generate an object file even after errors.
+
+@item -- | @var{files} @dots{}
+Standard input, or source files to assemble.
+
+@end table
+
+@ifset ARC
+The following options are available when @value{AS} is configured for
+an ARC processor.
+
+@table @code
+
+@cindex ARC endianness
+@cindex endianness, ARC
+@cindex big endian output, ARC
+@item -mbig-endian
+Generate ``big endian'' format output.
+
+@cindex little endian output, ARC
+@item -mlittle-endian
+Generate ``little endian'' format output.
+
+@end table
+@end ifset
+
+@ifset ARM
+The following options are available when @value{AS} is configured for the ARM
+processor family.
+
+@table @code
+@item -m[arm]1 | -m[arm]2 | -m[arm]250 | -m[arm]3 | -m[arm]6 | -m[arm]7[t][[d]m] | -m[arm]v2 | -m[arm]v2a | -m[arm]v3 | -m[arm]v3m | -m[arm]v4 | -m[arm]v4t
+Specify which variant of the ARM architecture is the target.
+@item -mthumb | -mall
+Enable or disable Thumb only instruction decoding.
+@item -mfpa10 | -mfpa11 | -mfpe-old | -mno-fpu
+Select which Floating Point architcture is the target.
+@item -mapcs-32 | -mapcs-26
+Select which procedure calling convention is in use.
+@item -EB | -EL
+Select either big-endian (-EB) or little-endian (-EL) output.
+@end table
+@end ifset
+
+@ifset D10V
+The following options are available when @value{AS} is configured for
+a D10V processor.
+@table @code
+@cindex D10V optimization
+@cindex optimization, D10V
+@item -O
+Optimize output by parallelizing instructions.
+@end table
+@end ifset
+
+@ifset D30V
+The following options are available when @value{AS} is configured for a D30V
+processor.
+@table @code
+@cindex D30V optimization
+@cindex optimization, D30V
+@item -O
+Optimize output by parallelizing instructions.
+
+@cindex D30V nops
+@item -n
+Warn when nops are generated.
+
+@cindex D30V nops after 32-bit multiply
+@item -N
+Warn when a nop after a 32-bit multiply instruction is generated.
+@end table
+@end ifset
+
+@ifset I960
+The following options are available when @value{AS} is configured for the
+Intel 80960 processor.
+
+@table @code
+@item -ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC
+Specify which variant of the 960 architecture is the target.
+
+@item -b
+Add code to collect statistics about branches taken.
+
+@item -no-relax
+Do not alter compare-and-branch instructions for long displacements;
+error if necessary.
+
+@end table
+@end ifset
+
+
+@ifset M680X0
+The following options are available when @value{AS} is configured for the
+Motorola 68000 series.
+
+@table @code
+
+@item -l
+Shorten references to undefined symbols, to one word instead of two.
+
+@item -m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060
+@itemx | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -mcpu32 | -m5200
+Specify what processor in the 68000 family is the target. The default
+is normally the 68020, but this can be changed at configuration time.
+
+@item -m68881 | -m68882 | -mno-68881 | -mno-68882
+The target machine does (or does not) have a floating-point coprocessor.
+The default is to assume a coprocessor for 68020, 68030, and cpu32. Although
+the basic 68000 is not compatible with the 68881, a combination of the
+two can be specified, since it's possible to do emulation of the
+coprocessor instructions with the main processor.
+
+@item -m68851 | -mno-68851
+The target machine does (or does not) have a memory-management
+unit coprocessor. The default is to assume an MMU for 68020 and up.
+
+@end table
+@end ifset
+
+@ifset SPARC
+The following options are available when @code{@value{AS}} is configured
+for the SPARC architecture:
+
+@table @code
+@item -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite
+@itemx -Av8plus | -Av8plusa | -Av9 | -Av9a
+Explicitly select a variant of the SPARC architecture.
+
+@samp{-Av8plus} and @samp{-Av8plusa} select a 32 bit environment.
+@samp{-Av9} and @samp{-Av9a} select a 64 bit environment.
+
+@samp{-Av8plusa} and @samp{-Av9a} enable the SPARC V9 instruction set with
+UltraSPARC extensions.
+
+@item -xarch=v8plus | -xarch=v8plusa
+For compatibility with the Solaris v9 assembler. These options are
+equivalent to -Av8plus and -Av8plusa, respectively.
+
+@item -bump
+Warn when the assembler switches to another architecture.
+@end table
+@end ifset
+
+@ifset MIPS
+The following options are available when @value{AS} is configured for
+a MIPS processor.
+
+@table @code
+@item -G @var{num}
+This option sets the largest size of an object that can be referenced
+implicitly with the @code{gp} register. It is only accepted for targets that
+use ECOFF format, such as a DECstation running Ultrix. The default value is 8.
+
+@cindex MIPS endianness
+@cindex endianness, MIPS
+@cindex big endian output, MIPS
+@item -EB
+Generate ``big endian'' format output.
+
+@cindex little endian output, MIPS
+@item -EL
+Generate ``little endian'' format output.
+
+@cindex MIPS ISA
+@item -mips1
+@itemx -mips2
+@itemx -mips3
+Generate code for a particular MIPS Instruction Set Architecture level.
+@samp{-mips1} corresponds to the @sc{r2000} and @sc{r3000} processors,
+@samp{-mips2} to the @sc{r6000} processor, and @samp{-mips3} to the @sc{r4000}
+processor.
+
+@item -m4650
+@itemx -no-m4650
+Generate code for the MIPS @sc{r4650} chip. This tells the assembler to accept
+the @samp{mad} and @samp{madu} instruction, and to not schedule @samp{nop}
+instructions around accesses to the @samp{HI} and @samp{LO} registers.
+@samp{-no-m4650} turns off this option.
+
+@item -mcpu=@var{CPU}
+Generate code for a particular MIPS cpu. This has little effect on the
+assembler, but it is passed by @code{@value{GCC}}.
+
+@cindex emulation
+@item --emulation=@var{name}
+This option causes @code{@value{AS}} to emulate @code{@value{AS}} configured
+for some other target, in all respects, including output format (choosing
+between ELF and ECOFF only), handling of pseudo-opcodes which may generate
+debugging information or store symbol table information, and default
+endianness. The available configuration names are: @samp{mipsecoff},
+@samp{mipself}, @samp{mipslecoff}, @samp{mipsbecoff}, @samp{mipslelf},
+@samp{mipsbelf}. The first two do not alter the default endianness from that
+of the primary target for which the assembler was configured; the others change
+the default to little- or big-endian as indicated by the @samp{b} or @samp{l}
+in the name. Using @samp{-EB} or @samp{-EL} will override the endianness
+selection in any case.
+
+This option is currently supported only when the primary target
+@code{@value{AS}} is configured for is a MIPS ELF or ECOFF target.
+Furthermore, the primary target or others specified with
+@samp{--enable-targets=@dots{}} at configuration time must include support for
+the other format, if both are to be available. For example, the Irix 5
+configuration includes support for both.
+
+Eventually, this option will support more configurations, with more
+fine-grained control over the assembler's behavior, and will be supported for
+more processors.
+
+@item -nocpp
+@code{@value{AS}} ignores this option. It is accepted for compatibility with
+the native tools.
+
+@need 900
+@item --trap
+@itemx --no-trap
+@itemx --break
+@itemx --no-break
+Control how to deal with multiplication overflow and division by zero.
+@samp{--trap} or @samp{--no-break} (which are synonyms) take a trap exception
+(and only work for Instruction Set Architecture level 2 and higher);
+@samp{--break} or @samp{--no-trap} (also synonyms, and the default) take a
+break exception.
+@end table
+@end ifset
+
+@ifset MCORE
+The following options are available when @value{AS} is configured for
+an MCore processor.
+
+@table @code
+@item -jsri2bsr
+@itemx -nojsri2bsr
+Enable or disable the JSRI to BSR transformation. By default this is enabled.
+The command line option @samp{-nojsri2bsr} can be used to disable it.
+
+@item -sifilter
+@itemx -nosifilter
+Enable or disable the silicon filter behaviour. By default this is disabled.
+The default can be overidden by the @samp{-sifilter} command line option.
+
+@item -relax
+Alter jump instructions for long displacements.
+
+
+@end table
+@end ifset
+
+@menu
+* Manual:: Structure of this Manual
+* GNU Assembler:: The GNU Assembler
+* Object Formats:: Object File Formats
+* Command Line:: Command Line
+* Input Files:: Input Files
+* Object:: Output (Object) File
+* Errors:: Error and Warning Messages
+@end menu
+
+@node Manual
+@section Structure of this Manual
+
+@cindex manual, structure and purpose
+This manual is intended to describe what you need to know to use
+@sc{gnu} @code{@value{AS}}. We cover the syntax expected in source files, including
+notation for symbols, constants, and expressions; the directives that
+@code{@value{AS}} understands; and of course how to invoke @code{@value{AS}}.
+
+@ifclear GENERIC
+We also cover special features in the @value{TARGET}
+configuration of @code{@value{AS}}, including assembler directives.
+@end ifclear
+@ifset GENERIC
+This manual also describes some of the machine-dependent features of
+various flavors of the assembler.
+@end ifset
+
+@cindex machine instructions (not covered)
+On the other hand, this manual is @emph{not} intended as an introduction
+to programming in assembly language---let alone programming in general!
+In a similar vein, we make no attempt to introduce the machine
+architecture; we do @emph{not} describe the instruction set, standard
+mnemonics, registers or addressing modes that are standard to a
+particular architecture.
+@ifset GENERIC
+You may want to consult the manufacturer's
+machine architecture manual for this information.
+@end ifset
+@ifclear GENERIC
+@ifset H8/300
+For information on the H8/300 machine instruction set, see @cite{H8/300
+Series Programming Manual} (Hitachi ADE--602--025). For the H8/300H,
+see @cite{H8/300H Series Programming Manual} (Hitachi).
+@end ifset
+@ifset H8/500
+For information on the H8/500 machine instruction set, see @cite{H8/500
+Series Programming Manual} (Hitachi M21T001).
+@end ifset
+@ifset SH
+For information on the Hitachi SH machine instruction set, see
+@cite{SH-Microcomputer User's Manual} (Hitachi Micro Systems, Inc.).
+@end ifset
+@ifset Z8000
+For information on the Z8000 machine instruction set, see @cite{Z8000 CPU Technical Manual}
+@end ifset
+@end ifclear
+
+@c I think this is premature---doc@cygnus.com, 17jan1991
+@ignore
+Throughout this manual, we assume that you are running @dfn{GNU},
+the portable operating system from the @dfn{Free Software
+Foundation, Inc.}. This restricts our attention to certain kinds of
+computer (in particular, the kinds of computers that @sc{gnu} can run on);
+once this assumption is granted examples and definitions need less
+qualification.
+
+@code{@value{AS}} is part of a team of programs that turn a high-level
+human-readable series of instructions into a low-level
+computer-readable series of instructions. Different versions of
+@code{@value{AS}} are used for different kinds of computer.
+@end ignore
+
+@c There used to be a section "Terminology" here, which defined
+@c "contents", "byte", "word", and "long". Defining "word" to any
+@c particular size is confusing when the .word directive may generate 16
+@c bits on one machine and 32 bits on another; in general, for the user
+@c version of this manual, none of these terms seem essential to define.
+@c They were used very little even in the former draft of the manual;
+@c this draft makes an effort to avoid them (except in names of
+@c directives).
+
+@node GNU Assembler
+@section The GNU Assembler
+
+@sc{gnu} @code{as} is really a family of assemblers.
+@ifclear GENERIC
+This manual describes @code{@value{AS}}, a member of that family which is
+configured for the @value{TARGET} architectures.
+@end ifclear
+If you use (or have used) the @sc{gnu} assembler on one architecture, you
+should find a fairly similar environment when you use it on another
+architecture. Each version has much in common with the others,
+including object file formats, most assembler directives (often called
+@dfn{pseudo-ops}) and assembler syntax.@refill
+
+@cindex purpose of @sc{gnu} assembler
+@code{@value{AS}} is primarily intended to assemble the output of the
+@sc{gnu} C compiler @code{@value{GCC}} for use by the linker
+@code{@value{LD}}. Nevertheless, we've tried to make @code{@value{AS}}
+assemble correctly everything that other assemblers for the same
+machine would assemble.
+@ifset VAX
+Any exceptions are documented explicitly (@pxref{Machine Dependencies}).
+@end ifset
+@ifset M680X0
+@c This remark should appear in generic version of manual; assumption
+@c here is that generic version sets M680x0.
+This doesn't mean @code{@value{AS}} always uses the same syntax as another
+assembler for the same architecture; for example, we know of several
+incompatible versions of 680x0 assembly language syntax.
+@end ifset
+
+Unlike older assemblers, @code{@value{AS}} is designed to assemble a source
+program in one pass of the source file. This has a subtle impact on the
+@kbd{.org} directive (@pxref{Org,,@code{.org}}).
+
+@node Object Formats
+@section Object File Formats
+
+@cindex object file format
+The @sc{gnu} assembler can be configured to produce several alternative
+object file formats. For the most part, this does not affect how you
+write assembly language programs; but directives for debugging symbols
+are typically different in different file formats. @xref{Symbol
+Attributes,,Symbol Attributes}.
+@ifclear GENERIC
+@ifclear MULTI-OBJ
+On the @value{TARGET}, @code{@value{AS}} is configured to produce
+@value{OBJ-NAME} format object files.
+@end ifclear
+@c The following should exhaust all configs that set MULTI-OBJ, ideally
+@ifset A29K
+On the @value{TARGET}, @code{@value{AS}} can be configured to produce either
+@code{a.out} or COFF format object files.
+@end ifset
+@ifset I960
+On the @value{TARGET}, @code{@value{AS}} can be configured to produce either
+@code{b.out} or COFF format object files.
+@end ifset
+@ifset HPPA
+On the @value{TARGET}, @code{@value{AS}} can be configured to produce either
+SOM or ELF format object files.
+@end ifset
+@end ifclear
+
+@node Command Line
+@section Command Line
+
+@cindex command line conventions
+After the program name @code{@value{AS}}, the command line may contain
+options and file names. Options may appear in any order, and may be
+before, after, or between file names. The order of file names is
+significant.
+
+@cindex standard input, as input file
+@kindex --
+@file{--} (two hyphens) by itself names the standard input file
+explicitly, as one of the files for @code{@value{AS}} to assemble.
+
+@cindex options, command line
+Except for @samp{--} any command line argument that begins with a
+hyphen (@samp{-}) is an option. Each option changes the behavior of
+@code{@value{AS}}. No option changes the way another option works. An
+option is a @samp{-} followed by one or more letters; the case of
+the letter is important. All options are optional.
+
+Some options expect exactly one file name to follow them. The file
+name may either immediately follow the option's letter (compatible
+with older assemblers) or it may be the next command argument (@sc{gnu}
+standard). These two command lines are equivalent:
+
+@smallexample
+@value{AS} -o my-object-file.o mumble.s
+@value{AS} -omy-object-file.o mumble.s
+@end smallexample
+
+@node Input Files
+@section Input Files
+
+@cindex input
+@cindex source program
+@cindex files, input
+We use the phrase @dfn{source program}, abbreviated @dfn{source}, to
+describe the program input to one run of @code{@value{AS}}. The program may
+be in one or more files; how the source is partitioned into files
+doesn't change the meaning of the source.
+
+@c I added "con" prefix to "catenation" just to prove I can overcome my
+@c APL training... doc@cygnus.com
+The source program is a concatenation of the text in all the files, in the
+order specified.
+
+Each time you run @code{@value{AS}} it assembles exactly one source
+program. The source program is made up of one or more files.
+(The standard input is also a file.)
+
+You give @code{@value{AS}} a command line that has zero or more input file
+names. The input files are read (from left file name to right). A
+command line argument (in any position) that has no special meaning
+is taken to be an input file name.
+
+If you give @code{@value{AS}} no file names it attempts to read one input file
+from the @code{@value{AS}} standard input, which is normally your terminal. You
+may have to type @key{ctl-D} to tell @code{@value{AS}} there is no more program
+to assemble.
+
+Use @samp{--} if you need to explicitly name the standard input file
+in your command line.
+
+If the source is empty, @code{@value{AS}} produces a small, empty object
+file.
+
+@subheading Filenames and Line-numbers
+
+@cindex input file linenumbers
+@cindex line numbers, in input files
+There are two ways of locating a line in the input file (or files) and
+either may be used in reporting error messages. One way refers to a line
+number in a physical file; the other refers to a line number in a
+``logical'' file. @xref{Errors, ,Error and Warning Messages}.
+
+@dfn{Physical files} are those files named in the command line given
+to @code{@value{AS}}.
+
+@dfn{Logical files} are simply names declared explicitly by assembler
+directives; they bear no relation to physical files. Logical file names help
+error messages reflect the original source file, when @code{@value{AS}} source
+is itself synthesized from other files. @code{@value{AS}} understands the
+@samp{#} directives emitted by the @code{@value{GCC}} preprocessor. See also
+@ref{File,,@code{.file}}.
+
+@node Object
+@section Output (Object) File
+
+@cindex object file
+@cindex output file
+@kindex a.out
+@kindex .o
+Every time you run @code{@value{AS}} it produces an output file, which is
+your assembly language program translated into numbers. This file
+is the object file. Its default name is
+@ifclear BOUT
+@code{a.out}.
+@end ifclear
+@ifset BOUT
+@ifset GENERIC
+@code{a.out}, or
+@end ifset
+@code{b.out} when @code{@value{AS}} is configured for the Intel 80960.
+@end ifset
+You can give it another name by using the @code{-o} option. Conventionally,
+object file names end with @file{.o}. The default name is used for historical
+reasons: older assemblers were capable of assembling self-contained programs
+directly into a runnable program. (For some formats, this isn't currently
+possible, but it can be done for the @code{a.out} format.)
+
+@cindex linker
+@kindex ld
+The object file is meant for input to the linker @code{@value{LD}}. It contains
+assembled program code, information to help @code{@value{LD}} integrate
+the assembled program into a runnable file, and (optionally) symbolic
+information for the debugger.
+
+@c link above to some info file(s) like the description of a.out.
+@c don't forget to describe @sc{gnu} info as well as Unix lossage.
+
+@node Errors
+@section Error and Warning Messages
+
+@cindex error messsages
+@cindex warning messages
+@cindex messages from assembler
+@code{@value{AS}} may write warnings and error messages to the standard error
+file (usually your terminal). This should not happen when a compiler
+runs @code{@value{AS}} automatically. Warnings report an assumption made so
+that @code{@value{AS}} could keep assembling a flawed program; errors report a
+grave problem that stops the assembly.
+
+@cindex format of warning messages
+Warning messages have the format
+
+@smallexample
+file_name:@b{NNN}:Warning Message Text
+@end smallexample
+
+@noindent
+@cindex line numbers, in warnings/errors
+(where @b{NNN} is a line number). If a logical file name has been given
+(@pxref{File,,@code{.file}}) it is used for the filename, otherwise the name of
+the current input file is used. If a logical line number was given
+@ifset GENERIC
+(@pxref{Line,,@code{.line}})
+@end ifset
+@ifclear GENERIC
+@ifclear A29K
+(@pxref{Line,,@code{.line}})
+@end ifclear
+@ifset A29K
+(@pxref{Ln,,@code{.ln}})
+@end ifset
+@end ifclear
+then it is used to calculate the number printed,
+otherwise the actual line in the current source file is printed. The
+message text is intended to be self explanatory (in the grand Unix
+tradition).
+
+@cindex format of error messages
+Error messages have the format
+@smallexample
+file_name:@b{NNN}:FATAL:Error Message Text
+@end smallexample
+The file name and line number are derived as for warning
+messages. The actual message text may be rather less explanatory
+because many of them aren't supposed to happen.
+
+@node Invoking
+@chapter Command-Line Options
+
+@cindex options, all versions of assembler
+This chapter describes command-line options available in @emph{all}
+versions of the @sc{gnu} assembler; @pxref{Machine Dependencies}, for options specific
+@ifclear GENERIC
+to the @value{TARGET}.
+@end ifclear
+@ifset GENERIC
+to particular machine architectures.
+@end ifset
+
+If you are invoking @code{@value{AS}} via the @sc{gnu} C compiler (version 2),
+you can use the @samp{-Wa} option to pass arguments through to the assembler.
+The assembler arguments must be separated from each other (and the @samp{-Wa})
+by commas. For example:
+
+@smallexample
+gcc -c -g -O -Wa,-alh,-L file.c
+@end smallexample
+
+@noindent
+This passes two options to the assembler: @samp{-alh} (emit a listing to
+standard output with with high-level and assembly source) and @samp{-L} (retain
+local symbols in the symbol table).
+
+Usually you do not need to use this @samp{-Wa} mechanism, since many compiler
+command-line options are automatically passed to the assembler by the compiler.
+(You can call the @sc{gnu} compiler driver with the @samp{-v} option to see
+precisely what options it passes to each compilation pass, including the
+assembler.)
+
+@menu
+* a:: -a[cdhlns] enable listings
+* D:: -D for compatibility
+* f:: -f to work faster
+* I:: -I for .include search path
+@ifclear DIFF-TBL-KLUGE
+* K:: -K for compatibility
+@end ifclear
+@ifset DIFF-TBL-KLUGE
+* K:: -K for difference tables
+@end ifset
+
+* L:: -L to retain local labels
+* M:: -M or --mri to assemble in MRI compatibility mode
+* MD:: --MD for dependency tracking
+* o:: -o to name the object file
+* R:: -R to join data and text sections
+* statistics:: --statistics to see statistics about assembly
+* traditional-format:: --traditional-format for compatible output
+* v:: -v to announce version
+* W:: -W to suppress warnings
+* Z:: -Z to make object file even after errors
+@end menu
+
+@node a
+@section Enable Listings: @code{-a[cdhlns]}
+
+@kindex -a
+@kindex -ac
+@kindex -ad
+@kindex -ah
+@kindex -al
+@kindex -an
+@kindex -as
+@cindex listings, enabling
+@cindex assembly listings, enabling
+
+These options enable listing output from the assembler. By itself,
+@samp{-a} requests high-level, assembly, and symbols listing.
+You can use other letters to select specific options for the list:
+@samp{-ah} requests a high-level language listing,
+@samp{-al} requests an output-program assembly listing, and
+@samp{-as} requests a symbol table listing.
+High-level listings require that a compiler debugging option like
+@samp{-g} be used, and that assembly listings (@samp{-al}) be requested
+also.
+
+Use the @samp{-ac} option to omit false conditionals from a listing. Any lines
+which are not assembled because of a false @code{.if} (or @code{.ifdef}, or any
+other conditional), or a true @code{.if} followed by an @code{.else}, will be
+omitted from the listing.
+
+Use the @samp{-ad} option to omit debugging directives from the
+listing.
+
+Once you have specified one of these options, you can further control
+listing output and its appearance using the directives @code{.list},
+@code{.nolist}, @code{.psize}, @code{.eject}, @code{.title}, and
+@code{.sbttl}.
+The @samp{-an} option turns off all forms processing.
+If you do not request listing output with one of the @samp{-a} options, the
+listing-control directives have no effect.
+
+The letters after @samp{-a} may be combined into one option,
+@emph{e.g.}, @samp{-aln}.
+
+@node D
+@section @code{-D}
+
+@kindex -D
+This option has no effect whatsoever, but it is accepted to make it more
+likely that scripts written for other assemblers also work with
+@code{@value{AS}}.
+
+@node f
+@section Work Faster: @code{-f}
+
+@kindex -f
+@cindex trusted compiler
+@cindex faster processing (@code{-f})
+@samp{-f} should only be used when assembling programs written by a
+(trusted) compiler. @samp{-f} stops the assembler from doing whitespace
+and comment preprocessing on
+the input file(s) before assembling them. @xref{Preprocessing,
+,Preprocessing}.
+
+@quotation
+@emph{Warning:} if you use @samp{-f} when the files actually need to be
+preprocessed (if they contain comments, for example), @code{@value{AS}} does
+not work correctly.
+@end quotation
+
+@node I
+@section @code{.include} search path: @code{-I} @var{path}
+
+@kindex -I @var{path}
+@cindex paths for @code{.include}
+@cindex search path for @code{.include}
+@cindex @code{include} directive search path
+Use this option to add a @var{path} to the list of directories
+@code{@value{AS}} searches for files specified in @code{.include}
+directives (@pxref{Include,,@code{.include}}). You may use @code{-I} as
+many times as necessary to include a variety of paths. The current
+working directory is always searched first; after that, @code{@value{AS}}
+searches any @samp{-I} directories in the same order as they were
+specified (left to right) on the command line.
+
+@node K
+@section Difference Tables: @code{-K}
+
+@kindex -K
+@ifclear DIFF-TBL-KLUGE
+On the @value{TARGET} family, this option is allowed, but has no effect. It is
+permitted for compatibility with the @sc{gnu} assembler on other platforms,
+where it can be used to warn when the assembler alters the machine code
+generated for @samp{.word} directives in difference tables. The @value{TARGET}
+family does not have the addressing limitations that sometimes lead to this
+alteration on other platforms.
+@end ifclear
+
+@ifset DIFF-TBL-KLUGE
+@cindex difference tables, warning
+@cindex warning for altered difference tables
+@code{@value{AS}} sometimes alters the code emitted for directives of the form
+@samp{.word @var{sym1}-@var{sym2}}; @pxref{Word,,@code{.word}}.
+You can use the @samp{-K} option if you want a warning issued when this
+is done.
+@end ifset
+
+@node L
+@section Include Local Labels: @code{-L}
+
+@kindex -L
+@cindex local labels, retaining in output
+Labels beginning with @samp{L} (upper case only) are called @dfn{local
+labels}. @xref{Symbol Names}. Normally you do not see such labels when
+debugging, because they are intended for the use of programs (like
+compilers) that compose assembler programs, not for your notice.
+Normally both @code{@value{AS}} and @code{@value{LD}} discard such labels, so you do not
+normally debug with them.
+
+This option tells @code{@value{AS}} to retain those @samp{L@dots{}} symbols
+in the object file. Usually if you do this you also tell the linker
+@code{@value{LD}} to preserve symbols whose names begin with @samp{L}.
+
+By default, a local label is any label beginning with @samp{L}, but each
+target is allowed to redefine the local label prefix.
+@ifset HPPA
+On the HPPA local labels begin with @samp{L$}.
+@end ifset
+@ifset ARM
+@samp{;} for the ARM family;
+@end ifset
+
+@node M
+@section Assemble in MRI Compatibility Mode: @code{-M}
+
+@kindex -M
+@cindex MRI compatibility mode
+The @code{-M} or @code{--mri} option selects MRI compatibility mode. This
+changes the syntax and pseudo-op handling of @code{@value{AS}} to make it
+compatible with the @code{ASM68K} or the @code{ASM960} (depending upon the
+configured target) assembler from Microtec Research. The exact nature of the
+MRI syntax will not be documented here; see the MRI manuals for more
+information. Note in particular that the handling of macros and macro
+arguments is somewhat different. The purpose of this option is to permit
+assembling existing MRI assembler code using @code{@value{AS}}.
+
+The MRI compatibility is not complete. Certain operations of the MRI assembler
+depend upon its object file format, and can not be supported using other object
+file formats. Supporting these would require enhancing each object file format
+individually. These are:
+
+@itemize @bullet
+@item global symbols in common section
+
+The m68k MRI assembler supports common sections which are merged by the linker.
+Other object file formats do not support this. @code{@value{AS}} handles
+common sections by treating them as a single common symbol. It permits local
+symbols to be defined within a common section, but it can not support global
+symbols, since it has no way to describe them.
+
+@item complex relocations
+
+The MRI assemblers support relocations against a negated section address, and
+relocations which combine the start addresses of two or more sections. These
+are not support by other object file formats.
+
+@item @code{END} pseudo-op specifying start address
+
+The MRI @code{END} pseudo-op permits the specification of a start address.
+This is not supported by other object file formats. The start address may
+instead be specified using the @code{-e} option to the linker, or in a linker
+script.
+
+@item @code{IDNT}, @code{.ident} and @code{NAME} pseudo-ops
+
+The MRI @code{IDNT}, @code{.ident} and @code{NAME} pseudo-ops assign a module
+name to the output file. This is not supported by other object file formats.
+
+@item @code{ORG} pseudo-op
+
+The m68k MRI @code{ORG} pseudo-op begins an absolute section at a given
+address. This differs from the usual @code{@value{AS}} @code{.org} pseudo-op,
+which changes the location within the current section. Absolute sections are
+not supported by other object file formats. The address of a section may be
+assigned within a linker script.
+@end itemize
+
+There are some other features of the MRI assembler which are not supported by
+@code{@value{AS}}, typically either because they are difficult or because they
+seem of little consequence. Some of these may be supported in future releases.
+
+@itemize @bullet
+
+@item EBCDIC strings
+
+EBCDIC strings are not supported.
+
+@item packed binary coded decimal
+
+Packed binary coded decimal is not supported. This means that the @code{DC.P}
+and @code{DCB.P} pseudo-ops are not supported.
+
+@item @code{FEQU} pseudo-op
+
+The m68k @code{FEQU} pseudo-op is not supported.
+
+@item @code{NOOBJ} pseudo-op
+
+The m68k @code{NOOBJ} pseudo-op is not supported.
+
+@item @code{OPT} branch control options
+
+The m68k @code{OPT} branch control options---@code{B}, @code{BRS}, @code{BRB},
+@code{BRL}, and @code{BRW}---are ignored. @code{@value{AS}} automatically
+relaxes all branches, whether forward or backward, to an appropriate size, so
+these options serve no purpose.
+
+@item @code{OPT} list control options
+
+The following m68k @code{OPT} list control options are ignored: @code{C},
+@code{CEX}, @code{CL}, @code{CRE}, @code{E}, @code{G}, @code{I}, @code{M},
+@code{MEX}, @code{MC}, @code{MD}, @code{X}.
+
+@item other @code{OPT} options
+
+The following m68k @code{OPT} options are ignored: @code{NEST}, @code{O},
+@code{OLD}, @code{OP}, @code{P}, @code{PCO}, @code{PCR}, @code{PCS}, @code{R}.
+
+@item @code{OPT} @code{D} option is default
+
+The m68k @code{OPT} @code{D} option is the default, unlike the MRI assembler.
+@code{OPT NOD} may be used to turn it off.
+
+@item @code{XREF} pseudo-op.
+
+The m68k @code{XREF} pseudo-op is ignored.
+
+@item @code{.debug} pseudo-op
+
+The i960 @code{.debug} pseudo-op is not supported.
+
+@item @code{.extended} pseudo-op
+
+The i960 @code{.extended} pseudo-op is not supported.
+
+@item @code{.list} pseudo-op.
+
+The various options of the i960 @code{.list} pseudo-op are not supported.
+
+@item @code{.optimize} pseudo-op
+
+The i960 @code{.optimize} pseudo-op is not supported.
+
+@item @code{.output} pseudo-op
+
+The i960 @code{.output} pseudo-op is not supported.
+
+@item @code{.setreal} pseudo-op
+
+The i960 @code{.setreal} pseudo-op is not supported.
+
+@end itemize
+
+@node MD
+@section Dependency tracking: @code{--MD}
+
+@kindex --MD
+@cindex dependency tracking
+@cindex make rules
+
+@code{@value{AS}} can generate a dependency file for the file it creates. This
+file consists of a single rule suitable for @code{make} describing the
+dependencies of the main source file.
+
+The rule is written to the file named in its argument.
+
+This feature is used in the automatic updating of makefiles.
+
+@node o
+@section Name the Object File: @code{-o}
+
+@kindex -o
+@cindex naming object file
+@cindex object file name
+There is always one object file output when you run @code{@value{AS}}. By
+default it has the name
+@ifset GENERIC
+@ifset I960
+@file{a.out} (or @file{b.out}, for Intel 960 targets only).
+@end ifset
+@ifclear I960
+@file{a.out}.
+@end ifclear
+@end ifset
+@ifclear GENERIC
+@ifset I960
+@file{b.out}.
+@end ifset
+@ifclear I960
+@file{a.out}.
+@end ifclear
+@end ifclear
+You use this option (which takes exactly one filename) to give the
+object file a different name.
+
+Whatever the object file is called, @code{@value{AS}} overwrites any
+existing file of the same name.
+
+@node R
+@section Join Data and Text Sections: @code{-R}
+
+@kindex -R
+@cindex data and text sections, joining
+@cindex text and data sections, joining
+@cindex joining text and data sections
+@cindex merging text and data sections
+@code{-R} tells @code{@value{AS}} to write the object file as if all
+data-section data lives in the text section. This is only done at
+the very last moment: your binary data are the same, but data
+section parts are relocated differently. The data section part of
+your object file is zero bytes long because all its bytes are
+appended to the text section. (@xref{Sections,,Sections and Relocation}.)
+
+When you specify @code{-R} it would be possible to generate shorter
+address displacements (because we do not have to cross between text and
+data section). We refrain from doing this simply for compatibility with
+older versions of @code{@value{AS}}. In future, @code{-R} may work this way.
+
+@ifset COFF
+When @code{@value{AS}} is configured for COFF output,
+this option is only useful if you use sections named @samp{.text} and
+@samp{.data}.
+@end ifset
+
+@ifset HPPA
+@code{-R} is not supported for any of the HPPA targets. Using
+@code{-R} generates a warning from @code{@value{AS}}.
+@end ifset
+
+@node statistics
+@section Display Assembly Statistics: @code{--statistics}
+
+@kindex --statistics
+@cindex statistics, about assembly
+@cindex time, total for assembly
+@cindex space used, maximum for assembly
+Use @samp{--statistics} to display two statistics about the resources used by
+@code{@value{AS}}: the maximum amount of space allocated during the assembly
+(in bytes), and the total execution time taken for the assembly (in @sc{cpu}
+seconds).
+
+@node traditional-format
+@section Compatible output: @code{--traditional-format}
+
+@kindex --traditional-format
+For some targets, the output of @code{@value{AS}} is different in some ways
+from the output of some existing assembler. This switch requests
+@code{@value{AS}} to use the traditional format instead.
+
+For example, it disables the exception frame optimizations which
+@code{@value{AS}} normally does by default on @code{@value{GCC}} output.
+
+@node v
+@section Announce Version: @code{-v}
+
+@kindex -v
+@kindex -version
+@cindex assembler version
+@cindex version of assembler
+You can find out what version of as is running by including the
+option @samp{-v} (which you can also spell as @samp{-version}) on the
+command line.
+
+@node W
+@section Suppress Warnings: @code{-W}
+
+@kindex -W
+@cindex suppressing warnings
+@cindex warnings, suppressing
+@code{@value{AS}} should never give a warning or error message when
+assembling compiler output. But programs written by people often
+cause @code{@value{AS}} to give a warning that a particular assumption was
+made. All such warnings are directed to the standard error file.
+If you use this option, no warnings are issued. This option only
+affects the warning messages: it does not change any particular of how
+@code{@value{AS}} assembles your file. Errors, which stop the assembly, are
+still reported.
+
+@node Z
+@section Generate Object File in Spite of Errors: @code{-Z}
+@cindex object file, after errors
+@cindex errors, continuing after
+After an error message, @code{@value{AS}} normally produces no output. If for
+some reason you are interested in object file output even after
+@code{@value{AS}} gives an error message on your program, use the @samp{-Z}
+option. If there are any errors, @code{@value{AS}} continues anyways, and
+writes an object file after a final warning message of the form @samp{@var{n}
+errors, @var{m} warnings, generating bad object file.}
+
+@node Syntax
+@chapter Syntax
+
+@cindex machine-independent syntax
+@cindex syntax, machine-independent
+This chapter describes the machine-independent syntax allowed in a
+source file. @code{@value{AS}} syntax is similar to what many other
+assemblers use; it is inspired by the BSD 4.2
+@ifclear VAX
+assembler.
+@end ifclear
+@ifset VAX
+assembler, except that @code{@value{AS}} does not assemble Vax bit-fields.
+@end ifset
+
+@menu
+* Preprocessing:: Preprocessing
+* Whitespace:: Whitespace
+* Comments:: Comments
+* Symbol Intro:: Symbols
+* Statements:: Statements
+* Constants:: Constants
+@end menu
+
+@node Preprocessing
+@section Preprocessing
+
+@cindex preprocessing
+The @code{@value{AS}} internal preprocessor:
+@itemize @bullet
+@cindex whitespace, removed by preprocessor
+@item
+adjusts and removes extra whitespace. It leaves one space or tab before
+the keywords on a line, and turns any other whitespace on the line into
+a single space.
+
+@cindex comments, removed by preprocessor
+@item
+removes all comments, replacing them with a single space, or an
+appropriate number of newlines.
+
+@cindex constants, converted by preprocessor
+@item
+converts character constants into the appropriate numeric values.
+@end itemize
+
+It does not do macro processing, include file handling, or
+anything else you may get from your C compiler's preprocessor. You can
+do include file processing with the @code{.include} directive
+(@pxref{Include,,@code{.include}}). You can use the @sc{gnu} C compiler driver
+to get other ``CPP'' style preprocessing, by giving the input file a
+@samp{.S} suffix. @xref{Overall Options,, Options Controlling the Kind of
+Output, gcc.info, Using GNU CC}.
+
+Excess whitespace, comments, and character constants
+cannot be used in the portions of the input text that are not
+preprocessed.
+
+@cindex turning preprocessing on and off
+@cindex preprocessing, turning on and off
+@kindex #NO_APP
+@kindex #APP
+If the first line of an input file is @code{#NO_APP} or if you use the
+@samp{-f} option, whitespace and comments are not removed from the input file.
+Within an input file, you can ask for whitespace and comment removal in
+specific portions of the by putting a line that says @code{#APP} before the
+text that may contain whitespace or comments, and putting a line that says
+@code{#NO_APP} after this text. This feature is mainly intend to support
+@code{asm} statements in compilers whose output is otherwise free of comments
+and whitespace.
+
+@node Whitespace
+@section Whitespace
+
+@cindex whitespace
+@dfn{Whitespace} is one or more blanks or tabs, in any order.
+Whitespace is used to separate symbols, and to make programs neater for
+people to read. Unless within character constants
+(@pxref{Characters,,Character Constants}), any whitespace means the same
+as exactly one space.
+
+@node Comments
+@section Comments
+
+@cindex comments
+There are two ways of rendering comments to @code{@value{AS}}. In both
+cases the comment is equivalent to one space.
+
+Anything from @samp{/*} through the next @samp{*/} is a comment.
+This means you may not nest these comments.
+
+@smallexample
+/*
+ The only way to include a newline ('\n') in a comment
+ is to use this sort of comment.
+*/
+
+/* This sort of comment does not nest. */
+@end smallexample
+
+@cindex line comment character
+Anything from the @dfn{line comment} character to the next newline
+is considered a comment and is ignored. The line comment character is
+@ifset A29K
+@samp{;} for the AMD 29K family;
+@end ifset
+@ifset ARC
+@samp{;} on the ARC;
+@end ifset
+@ifset H8/300
+@samp{;} for the H8/300 family;
+@end ifset
+@ifset H8/500
+@samp{!} for the H8/500 family;
+@end ifset
+@ifset HPPA
+@samp{;} for the HPPA;
+@end ifset
+@ifset I960
+@samp{#} on the i960;
+@end ifset
+@ifset SH
+@samp{!} for the Hitachi SH;
+@end ifset
+@ifset SPARC
+@samp{!} on the SPARC;
+@end ifset
+@ifset M32R
+@samp{#} on the m32r;
+@end ifset
+@ifset M680X0
+@samp{|} on the 680x0;
+@end ifset
+@ifset VAX
+@samp{#} on the Vax;
+@end ifset
+@ifset Z8000
+@samp{!} for the Z8000;
+@end ifset
+@ifset V850
+@samp{#} on the V850;
+@end ifset
+see @ref{Machine Dependencies}. @refill
+@c FIXME What about i386, m88k, i860?
+
+@ifset GENERIC
+On some machines there are two different line comment characters. One
+character only begins a comment if it is the first non-whitespace character on
+a line, while the other always begins a comment.
+@end ifset
+
+@ifset V850
+The V850 assembler also supports a double dash as starting a comment that
+extends to the end of the line.
+
+@samp{--};
+@end ifset
+
+@kindex #
+@cindex lines starting with @code{#}
+@cindex logical line numbers
+To be compatible with past assemblers, lines that begin with @samp{#} have a
+special interpretation. Following the @samp{#} should be an absolute
+expression (@pxref{Expressions}): the logical line number of the @emph{next}
+line. Then a string (@pxref{Strings,, Strings}) is allowed: if present it is a
+new logical file name. The rest of the line, if any, should be whitespace.
+
+If the first non-whitespace characters on the line are not numeric,
+the line is ignored. (Just like a comment.)
+
+@smallexample
+ # This is an ordinary comment.
+# 42-6 "new_file_name" # New logical file name
+ # This is logical line # 36.
+@end smallexample
+This feature is deprecated, and may disappear from future versions
+of @code{@value{AS}}.
+
+@node Symbol Intro
+@section Symbols
+
+@cindex characters used in symbols
+@ifclear SPECIAL-SYMS
+A @dfn{symbol} is one or more characters chosen from the set of all
+letters (both upper and lower case), digits and the three characters
+@samp{_.$}.
+@end ifclear
+@ifset SPECIAL-SYMS
+@ifclear GENERIC
+@ifset H8
+A @dfn{symbol} is one or more characters chosen from the set of all
+letters (both upper and lower case), digits and the three characters
+@samp{._$}. (Save that, on the H8/300 only, you may not use @samp{$} in
+symbol names.)
+@end ifset
+@end ifclear
+@end ifset
+@ifset GENERIC
+On most machines, you can also use @code{$} in symbol names; exceptions
+are noted in @ref{Machine Dependencies}.
+@end ifset
+No symbol may begin with a digit. Case is significant.
+There is no length limit: all characters are significant. Symbols are
+delimited by characters not in that set, or by the beginning of a file
+(since the source program must end with a newline, the end of a file is
+not a possible symbol delimiter). @xref{Symbols}.
+@cindex length of symbols
+
+@node Statements
+@section Statements
+
+@cindex statements, structure of
+@cindex line separator character
+@cindex statement separator character
+@ifclear GENERIC
+@ifclear abnormal-separator
+A @dfn{statement} ends at a newline character (@samp{\n}) or at a
+semicolon (@samp{;}). The newline or semicolon is considered part of
+the preceding statement. Newlines and semicolons within character
+constants are an exception: they do not end statements.
+@end ifclear
+@ifset abnormal-separator
+@ifset A29K
+A @dfn{statement} ends at a newline character (@samp{\n}) or an ``at''
+sign (@samp{@@}). The newline or at sign is considered part of the
+preceding statement. Newlines and at signs within character constants
+are an exception: they do not end statements.
+@end ifset
+@ifset HPPA
+A @dfn{statement} ends at a newline character (@samp{\n}) or an exclamation
+point (@samp{!}). The newline or exclamation point is considered part of the
+preceding statement. Newlines and exclamation points within character
+constants are an exception: they do not end statements.
+@end ifset
+@ifset H8
+A @dfn{statement} ends at a newline character (@samp{\n}); or (for the
+H8/300) a dollar sign (@samp{$}); or (for the
+Hitachi-SH or the
+H8/500) a semicolon
+(@samp{;}). The newline or separator character is considered part of
+the preceding statement. Newlines and separators within character
+constants are an exception: they do not end statements.
+@end ifset
+@end ifset
+@end ifclear
+@ifset GENERIC
+A @dfn{statement} ends at a newline character (@samp{\n}) or line
+separator character. (The line separator is usually @samp{;}, unless
+this conflicts with the comment character; @pxref{Machine Dependencies}.) The
+newline or separator character is considered part of the preceding
+statement. Newlines and separators within character constants are an
+exception: they do not end statements.
+@end ifset
+
+@cindex newline, required at file end
+@cindex EOF, newline must precede
+It is an error to end any statement with end-of-file: the last
+character of any input file should be a newline.@refill
+
+An empty statement is allowed, and may include whitespace. It is ignored.
+
+@cindex instructions and directives
+@cindex directives and instructions
+@c "key symbol" is not used elsewhere in the document; seems pedantic to
+@c @defn{} it in that case, as was done previously... doc@cygnus.com,
+@c 13feb91.
+A statement begins with zero or more labels, optionally followed by a
+key symbol which determines what kind of statement it is. The key
+symbol determines the syntax of the rest of the statement. If the
+symbol begins with a dot @samp{.} then the statement is an assembler
+directive: typically valid for any computer. If the symbol begins with
+a letter the statement is an assembly language @dfn{instruction}: it
+assembles into a machine language instruction.
+@ifset GENERIC
+Different versions of @code{@value{AS}} for different computers
+recognize different instructions. In fact, the same symbol may
+represent a different instruction in a different computer's assembly
+language.@refill
+@end ifset
+
+@cindex @code{:} (label)
+@cindex label (@code{:})
+A label is a symbol immediately followed by a colon (@code{:}).
+Whitespace before a label or after a colon is permitted, but you may not
+have whitespace between a label's symbol and its colon. @xref{Labels}.
+
+@ifset HPPA
+For HPPA targets, labels need not be immediately followed by a colon, but
+the definition of a label must begin in column zero. This also implies that
+only one label may be defined on each line.
+@end ifset
+
+@smallexample
+label: .directive followed by something
+another_label: # This is an empty statement.
+ instruction operand_1, operand_2, @dots{}
+@end smallexample
+
+@node Constants
+@section Constants
+
+@cindex constants
+A constant is a number, written so that its value is known by
+inspection, without knowing any context. Like this:
+@smallexample
+@group
+.byte 74, 0112, 092, 0x4A, 0X4a, 'J, '\J # All the same value.
+.ascii "Ring the bell\7" # A string constant.
+.octa 0x123456789abcdef0123456789ABCDEF0 # A bignum.
+.float 0f-314159265358979323846264338327\
+95028841971.693993751E-40 # - pi, a flonum.
+@end group
+@end smallexample
+
+@menu
+* Characters:: Character Constants
+* Numbers:: Number Constants
+@end menu
+
+@node Characters
+@subsection Character Constants
+
+@cindex character constants
+@cindex constants, character
+There are two kinds of character constants. A @dfn{character} stands
+for one character in one byte and its value may be used in
+numeric expressions. String constants (properly called string
+@emph{literals}) are potentially many bytes and their values may not be
+used in arithmetic expressions.
+
+@menu
+* Strings:: Strings
+* Chars:: Characters
+@end menu
+
+@node Strings
+@subsubsection Strings
+
+@cindex string constants
+@cindex constants, string
+A @dfn{string} is written between double-quotes. It may contain
+double-quotes or null characters. The way to get special characters
+into a string is to @dfn{escape} these characters: precede them with
+a backslash @samp{\} character. For example @samp{\\} represents
+one backslash: the first @code{\} is an escape which tells
+@code{@value{AS}} to interpret the second character literally as a backslash
+(which prevents @code{@value{AS}} from recognizing the second @code{\} as an
+escape character). The complete list of escapes follows.
+
+@cindex escape codes, character
+@cindex character escape codes
+@table @kbd
+@c @item \a
+@c Mnemonic for ACKnowledge; for ASCII this is octal code 007.
+@c
+@cindex @code{\b} (backspace character)
+@cindex backspace (@code{\b})
+@item \b
+Mnemonic for backspace; for ASCII this is octal code 010.
+
+@c @item \e
+@c Mnemonic for EOText; for ASCII this is octal code 004.
+@c
+@cindex @code{\f} (formfeed character)
+@cindex formfeed (@code{\f})
+@item \f
+Mnemonic for FormFeed; for ASCII this is octal code 014.
+
+@cindex @code{\n} (newline character)
+@cindex newline (@code{\n})
+@item \n
+Mnemonic for newline; for ASCII this is octal code 012.
+
+@c @item \p
+@c Mnemonic for prefix; for ASCII this is octal code 033, usually known as @code{escape}.
+@c
+@cindex @code{\r} (carriage return character)
+@cindex carriage return (@code{\r})
+@item \r
+Mnemonic for carriage-Return; for ASCII this is octal code 015.
+
+@c @item \s
+@c Mnemonic for space; for ASCII this is octal code 040. Included for compliance with
+@c other assemblers.
+@c
+@cindex @code{\t} (tab)
+@cindex tab (@code{\t})
+@item \t
+Mnemonic for horizontal Tab; for ASCII this is octal code 011.
+
+@c @item \v
+@c Mnemonic for Vertical tab; for ASCII this is octal code 013.
+@c @item \x @var{digit} @var{digit} @var{digit}
+@c A hexadecimal character code. The numeric code is 3 hexadecimal digits.
+@c
+@cindex @code{\@var{ddd}} (octal character code)
+@cindex octal character code (@code{\@var{ddd}})
+@item \ @var{digit} @var{digit} @var{digit}
+An octal character code. The numeric code is 3 octal digits.
+For compatibility with other Unix systems, 8 and 9 are accepted as digits:
+for example, @code{\008} has the value 010, and @code{\009} the value 011.
+
+@cindex @code{\@var{xd...}} (hex character code)
+@cindex hex character code (@code{\@var{xd...}})
+@item \@code{x} @var{hex-digits...}
+A hex character code. All trailing hex digits are combined. Either upper or
+lower case @code{x} works.
+
+@cindex @code{\\} (@samp{\} character)
+@cindex backslash (@code{\\})
+@item \\
+Represents one @samp{\} character.
+
+@c @item \'
+@c Represents one @samp{'} (accent acute) character.
+@c This is needed in single character literals
+@c (@xref{Characters,,Character Constants}.) to represent
+@c a @samp{'}.
+@c
+@cindex @code{\"} (doublequote character)
+@cindex doublequote (@code{\"})
+@item \"
+Represents one @samp{"} character. Needed in strings to represent
+this character, because an unescaped @samp{"} would end the string.
+
+@item \ @var{anything-else}
+Any other character when escaped by @kbd{\} gives a warning, but
+assembles as if the @samp{\} was not present. The idea is that if
+you used an escape sequence you clearly didn't want the literal
+interpretation of the following character. However @code{@value{AS}} has no
+other interpretation, so @code{@value{AS}} knows it is giving you the wrong
+code and warns you of the fact.
+@end table
+
+Which characters are escapable, and what those escapes represent,
+varies widely among assemblers. The current set is what we think
+the BSD 4.2 assembler recognizes, and is a subset of what most C
+compilers recognize. If you are in doubt, do not use an escape
+sequence.
+
+@node Chars
+@subsubsection Characters
+
+@cindex single character constant
+@cindex character, single
+@cindex constant, single character
+A single character may be written as a single quote immediately
+followed by that character. The same escapes apply to characters as
+to strings. So if you want to write the character backslash, you
+must write @kbd{'\\} where the first @code{\} escapes the second
+@code{\}. As you can see, the quote is an acute accent, not a
+grave accent. A newline
+@ifclear GENERIC
+@ifclear abnormal-separator
+(or semicolon @samp{;})
+@end ifclear
+@ifset abnormal-separator
+@ifset A29K
+(or at sign @samp{@@})
+@end ifset
+@ifset H8
+(or dollar sign @samp{$}, for the H8/300; or semicolon @samp{;} for the
+Hitachi SH or
+H8/500)
+@end ifset
+@end ifset
+@end ifclear
+immediately following an acute accent is taken as a literal character
+and does not count as the end of a statement. The value of a character
+constant in a numeric expression is the machine's byte-wide code for
+that character. @code{@value{AS}} assumes your character code is ASCII:
+@kbd{'A} means 65, @kbd{'B} means 66, and so on. @refill
+
+@node Numbers
+@subsection Number Constants
+
+@cindex constants, number
+@cindex number constants
+@code{@value{AS}} distinguishes three kinds of numbers according to how they
+are stored in the target machine. @emph{Integers} are numbers that
+would fit into an @code{int} in the C language. @emph{Bignums} are
+integers, but they are stored in more than 32 bits. @emph{Flonums}
+are floating point numbers, described below.
+
+@menu
+* Integers:: Integers
+* Bignums:: Bignums
+* Flonums:: Flonums
+@ifclear GENERIC
+@ifset I960
+* Bit Fields:: Bit Fields
+@end ifset
+@end ifclear
+@end menu
+
+@node Integers
+@subsubsection Integers
+@cindex integers
+@cindex constants, integer
+
+@cindex binary integers
+@cindex integers, binary
+A binary integer is @samp{0b} or @samp{0B} followed by zero or more of
+the binary digits @samp{01}.
+
+@cindex octal integers
+@cindex integers, octal
+An octal integer is @samp{0} followed by zero or more of the octal
+digits (@samp{01234567}).
+
+@cindex decimal integers
+@cindex integers, decimal
+A decimal integer starts with a non-zero digit followed by zero or
+more digits (@samp{0123456789}).
+
+@cindex hexadecimal integers
+@cindex integers, hexadecimal
+A hexadecimal integer is @samp{0x} or @samp{0X} followed by one or
+more hexadecimal digits chosen from @samp{0123456789abcdefABCDEF}.
+
+Integers have the usual values. To denote a negative integer, use
+the prefix operator @samp{-} discussed under expressions
+(@pxref{Prefix Ops,,Prefix Operators}).
+
+@node Bignums
+@subsubsection Bignums
+
+@cindex bignums
+@cindex constants, bignum
+A @dfn{bignum} has the same syntax and semantics as an integer
+except that the number (or its negative) takes more than 32 bits to
+represent in binary. The distinction is made because in some places
+integers are permitted while bignums are not.
+
+@node Flonums
+@subsubsection Flonums
+@cindex flonums
+@cindex floating point numbers
+@cindex constants, floating point
+
+@cindex precision, floating point
+A @dfn{flonum} represents a floating point number. The translation is
+indirect: a decimal floating point number from the text is converted by
+@code{@value{AS}} to a generic binary floating point number of more than
+sufficient precision. This generic floating point number is converted
+to a particular computer's floating point format (or formats) by a
+portion of @code{@value{AS}} specialized to that computer.
+
+A flonum is written by writing (in order)
+@itemize @bullet
+@item
+The digit @samp{0}.
+@ifset HPPA
+(@samp{0} is optional on the HPPA.)
+@end ifset
+
+@item
+A letter, to tell @code{@value{AS}} the rest of the number is a flonum.
+@ifset GENERIC
+@kbd{e} is recommended. Case is not important.
+@ignore
+@c FIXME: verify if flonum syntax really this vague for most cases
+(Any otherwise illegal letter works here, but that might be changed. Vax BSD
+4.2 assembler seems to allow any of @samp{defghDEFGH}.)
+@end ignore
+
+On the H8/300, H8/500,
+Hitachi SH,
+and AMD 29K architectures, the letter must be
+one of the letters @samp{DFPRSX} (in upper or lower case).
+
+On the ARC, the letter must be one of the letters @samp{DFRS}
+(in upper or lower case).
+
+On the Intel 960 architecture, the letter must be
+one of the letters @samp{DFT} (in upper or lower case).
+
+On the HPPA architecture, the letter must be @samp{E} (upper case only).
+@end ifset
+@ifclear GENERIC
+@ifset A29K
+One of the letters @samp{DFPRSX} (in upper or lower case).
+@end ifset
+@ifset ARC
+One of the letters @samp{DFRS} (in upper or lower case).
+@end ifset
+@ifset H8
+One of the letters @samp{DFPRSX} (in upper or lower case).
+@end ifset
+@ifset HPPA
+The letter @samp{E} (upper case only).
+@end ifset
+@ifset I960
+One of the letters @samp{DFT} (in upper or lower case).
+@end ifset
+@end ifclear
+
+@item
+An optional sign: either @samp{+} or @samp{-}.
+
+@item
+An optional @dfn{integer part}: zero or more decimal digits.
+
+@item
+An optional @dfn{fractional part}: @samp{.} followed by zero
+or more decimal digits.
+
+@item
+An optional exponent, consisting of:
+
+@itemize @bullet
+@item
+An @samp{E} or @samp{e}.
+@c I can't find a config where "EXP_CHARS" is other than 'eE', but in
+@c principle this can perfectly well be different on different targets.
+@item
+Optional sign: either @samp{+} or @samp{-}.
+@item
+One or more decimal digits.
+@end itemize
+
+@end itemize
+
+At least one of the integer part or the fractional part must be
+present. The floating point number has the usual base-10 value.
+
+@code{@value{AS}} does all processing using integers. Flonums are computed
+independently of any floating point hardware in the computer running
+@code{@value{AS}}.
+
+@ifclear GENERIC
+@ifset I960
+@c Bit fields are written as a general facility but are also controlled
+@c by a conditional-compilation flag---which is as of now (21mar91)
+@c turned on only by the i960 config of GAS.
+@node Bit Fields
+@subsubsection Bit Fields
+
+@cindex bit fields
+@cindex constants, bit field
+You can also define numeric constants as @dfn{bit fields}.
+specify two numbers separated by a colon---
+@example
+@var{mask}:@var{value}
+@end example
+@noindent
+@code{@value{AS}} applies a bitwise @sc{and} between @var{mask} and
+@var{value}.
+
+The resulting number is then packed
+@ifset GENERIC
+@c this conditional paren in case bit fields turned on elsewhere than 960
+(in host-dependent byte order)
+@end ifset
+into a field whose width depends on which assembler directive has the
+bit-field as its argument. Overflow (a result from the bitwise and
+requiring more binary digits to represent) is not an error; instead,
+more constants are generated, of the specified width, beginning with the
+least significant digits.@refill
+
+The directives @code{.byte}, @code{.hword}, @code{.int}, @code{.long},
+@code{.short}, and @code{.word} accept bit-field arguments.
+@end ifset
+@end ifclear
+
+@node Sections
+@chapter Sections and Relocation
+@cindex sections
+@cindex relocation
+
+@menu
+* Secs Background:: Background
+* Ld Sections:: Linker Sections
+* As Sections:: Assembler Internal Sections
+* Sub-Sections:: Sub-Sections
+* bss:: bss Section
+@end menu
+
+@node Secs Background
+@section Background
+
+Roughly, a section is a range of addresses, with no gaps; all data
+``in'' those addresses is treated the same for some particular purpose.
+For example there may be a ``read only'' section.
+
+@cindex linker, and assembler
+@cindex assembler, and linker
+The linker @code{@value{LD}} reads many object files (partial programs) and
+combines their contents to form a runnable program. When @code{@value{AS}}
+emits an object file, the partial program is assumed to start at address 0.
+@code{@value{LD}} assigns the final addresses for the partial program, so that
+different partial programs do not overlap. This is actually an
+oversimplification, but it suffices to explain how @code{@value{AS}} uses
+sections.
+
+@code{@value{LD}} moves blocks of bytes of your program to their run-time
+addresses. These blocks slide to their run-time addresses as rigid
+units; their length does not change and neither does the order of bytes
+within them. Such a rigid unit is called a @emph{section}. Assigning
+run-time addresses to sections is called @dfn{relocation}. It includes
+the task of adjusting mentions of object-file addresses so they refer to
+the proper run-time addresses.
+@ifset H8
+For the H8/300 and H8/500,
+and for the Hitachi SH,
+@code{@value{AS}} pads sections if needed to
+ensure they end on a word (sixteen bit) boundary.
+@end ifset
+
+@cindex standard assembler sections
+An object file written by @code{@value{AS}} has at least three sections, any
+of which may be empty. These are named @dfn{text}, @dfn{data} and
+@dfn{bss} sections.
+
+@ifset COFF
+@ifset GENERIC
+When it generates COFF output,
+@end ifset
+@code{@value{AS}} can also generate whatever other named sections you specify
+using the @samp{.section} directive (@pxref{Section,,@code{.section}}).
+If you do not use any directives that place output in the @samp{.text}
+or @samp{.data} sections, these sections still exist, but are empty.
+@end ifset
+
+@ifset HPPA
+@ifset GENERIC
+When @code{@value{AS}} generates SOM or ELF output for the HPPA,
+@end ifset
+@code{@value{AS}} can also generate whatever other named sections you
+specify using the @samp{.space} and @samp{.subspace} directives. See
+@cite{HP9000 Series 800 Assembly Language Reference Manual}
+(HP 92432-90001) for details on the @samp{.space} and @samp{.subspace}
+assembler directives.
+
+@ifset SOM
+Additionally, @code{@value{AS}} uses different names for the standard
+text, data, and bss sections when generating SOM output. Program text
+is placed into the @samp{$CODE$} section, data into @samp{$DATA$}, and
+BSS into @samp{$BSS$}.
+@end ifset
+@end ifset
+
+Within the object file, the text section starts at address @code{0}, the
+data section follows, and the bss section follows the data section.
+
+@ifset HPPA
+When generating either SOM or ELF output files on the HPPA, the text
+section starts at address @code{0}, the data section at address
+@code{0x4000000}, and the bss section follows the data section.
+@end ifset
+
+To let @code{@value{LD}} know which data changes when the sections are
+relocated, and how to change that data, @code{@value{AS}} also writes to the
+object file details of the relocation needed. To perform relocation
+@code{@value{LD}} must know, each time an address in the object
+file is mentioned:
+@itemize @bullet
+@item
+Where in the object file is the beginning of this reference to
+an address?
+@item
+How long (in bytes) is this reference?
+@item
+Which section does the address refer to? What is the numeric value of
+@display
+(@var{address}) @minus{} (@var{start-address of section})?
+@end display
+@item
+Is the reference to an address ``Program-Counter relative''?
+@end itemize
+
+@cindex addresses, format of
+@cindex section-relative addressing
+In fact, every address @code{@value{AS}} ever uses is expressed as
+@display
+(@var{section}) + (@var{offset into section})
+@end display
+@noindent
+Further, most expressions @code{@value{AS}} computes have this section-relative
+nature.
+@ifset SOM
+(For some object formats, such as SOM for the HPPA, some expressions are
+symbol-relative instead.)
+@end ifset
+
+In this manual we use the notation @{@var{secname} @var{N}@} to mean ``offset
+@var{N} into section @var{secname}.''
+
+Apart from text, data and bss sections you need to know about the
+@dfn{absolute} section. When @code{@value{LD}} mixes partial programs,
+addresses in the absolute section remain unchanged. For example, address
+@code{@{absolute 0@}} is ``relocated'' to run-time address 0 by
+@code{@value{LD}}. Although the linker never arranges two partial programs'
+data sections with overlapping addresses after linking, @emph{by definition}
+their absolute sections must overlap. Address @code{@{absolute@ 239@}} in one
+part of a program is always the same address when the program is running as
+address @code{@{absolute@ 239@}} in any other part of the program.
+
+The idea of sections is extended to the @dfn{undefined} section. Any
+address whose section is unknown at assembly time is by definition
+rendered @{undefined @var{U}@}---where @var{U} is filled in later.
+Since numbers are always defined, the only way to generate an undefined
+address is to mention an undefined symbol. A reference to a named
+common block would be such a symbol: its value is unknown at assembly
+time so it has section @emph{undefined}.
+
+By analogy the word @emph{section} is used to describe groups of sections in
+the linked program. @code{@value{LD}} puts all partial programs' text
+sections in contiguous addresses in the linked program. It is
+customary to refer to the @emph{text section} of a program, meaning all
+the addresses of all partial programs' text sections. Likewise for
+data and bss sections.
+
+Some sections are manipulated by @code{@value{LD}}; others are invented for
+use of @code{@value{AS}} and have no meaning except during assembly.
+
+@node Ld Sections
+@section Linker Sections
+@code{@value{LD}} deals with just four kinds of sections, summarized below.
+
+@table @strong
+
+@ifset COFF
+@cindex named sections
+@cindex sections, named
+@item named sections
+@end ifset
+@ifset aout-bout
+@cindex text section
+@cindex data section
+@itemx text section
+@itemx data section
+@end ifset
+These sections hold your program. @code{@value{AS}} and @code{@value{LD}} treat them as
+separate but equal sections. Anything you can say of one section is
+true another.
+@ifset aout-bout
+When the program is running, however, it is
+customary for the text section to be unalterable. The
+text section is often shared among processes: it contains
+instructions, constants and the like. The data section of a running
+program is usually alterable: for example, C variables would be stored
+in the data section.
+@end ifset
+
+@cindex bss section
+@item bss section
+This section contains zeroed bytes when your program begins running. It
+is used to hold unitialized variables or common storage. The length of
+each partial program's bss section is important, but because it starts
+out containing zeroed bytes there is no need to store explicit zero
+bytes in the object file. The bss section was invented to eliminate
+those explicit zeros from object files.
+
+@cindex absolute section
+@item absolute section
+Address 0 of this section is always ``relocated'' to runtime address 0.
+This is useful if you want to refer to an address that @code{@value{LD}} must
+not change when relocating. In this sense we speak of absolute
+addresses being ``unrelocatable'': they do not change during relocation.
+
+@cindex undefined section
+@item undefined section
+This ``section'' is a catch-all for address references to objects not in
+the preceding sections.
+@c FIXME: ref to some other doc on obj-file formats could go here.
+@end table
+
+@cindex relocation example
+An idealized example of three relocatable sections follows.
+@ifset COFF
+The example uses the traditional section names @samp{.text} and @samp{.data}.
+@end ifset
+Memory addresses are on the horizontal axis.
+
+@c TEXI2ROFF-KILL
+@ifinfo
+@c END TEXI2ROFF-KILL
+@smallexample
+ +-----+----+--+
+partial program # 1: |ttttt|dddd|00|
+ +-----+----+--+
+
+ text data bss
+ seg. seg. seg.
+
+ +---+---+---+
+partial program # 2: |TTT|DDD|000|
+ +---+---+---+
+
+ +--+---+-----+--+----+---+-----+~~
+linked program: | |TTT|ttttt| |dddd|DDD|00000|
+ +--+---+-----+--+----+---+-----+~~
+
+ addresses: 0 @dots{}
+@end smallexample
+@c TEXI2ROFF-KILL
+@end ifinfo
+@need 5000
+@tex
+
+\line{\it Partial program \#1: \hfil}
+\line{\ibox{2.5cm}{\tt text}\ibox{2cm}{\tt data}\ibox{1cm}{\tt bss}\hfil}
+\line{\boxit{2.5cm}{\tt ttttt}\boxit{2cm}{\tt dddd}\boxit{1cm}{\tt 00}\hfil}
+
+\line{\it Partial program \#2: \hfil}
+\line{\ibox{1cm}{\tt text}\ibox{1.5cm}{\tt data}\ibox{1cm}{\tt bss}\hfil}
+\line{\boxit{1cm}{\tt TTT}\boxit{1.5cm}{\tt DDDD}\boxit{1cm}{\tt 000}\hfil}
+
+\line{\it linked program: \hfil}
+\line{\ibox{.5cm}{}\ibox{1cm}{\tt text}\ibox{2.5cm}{}\ibox{.75cm}{}\ibox{2cm}{\tt data}\ibox{1.5cm}{}\ibox{2cm}{\tt bss}\hfil}
+\line{\boxit{.5cm}{}\boxit{1cm}{\tt TTT}\boxit{2.5cm}{\tt
+ttttt}\boxit{.75cm}{}\boxit{2cm}{\tt dddd}\boxit{1.5cm}{\tt
+DDDD}\boxit{2cm}{\tt 00000}\ \dots\hfil}
+
+\line{\it addresses: \hfil}
+\line{0\dots\hfil}
+
+@end tex
+@c END TEXI2ROFF-KILL
+
+@node As Sections
+@section Assembler Internal Sections
+
+@cindex internal assembler sections
+@cindex sections in messages, internal
+These sections are meant only for the internal use of @code{@value{AS}}. They
+have no meaning at run-time. You do not really need to know about these
+sections for most purposes; but they can be mentioned in @code{@value{AS}}
+warning messages, so it might be helpful to have an idea of their
+meanings to @code{@value{AS}}. These sections are used to permit the
+value of every expression in your assembly language program to be a
+section-relative address.
+
+@table @b
+@cindex assembler internal logic error
+@item ASSEMBLER-INTERNAL-LOGIC-ERROR!
+An internal assembler logic error has been found. This means there is a
+bug in the assembler.
+
+@cindex expr (internal section)
+@item expr section
+The assembler stores complex expression internally as combinations of
+symbols. When it needs to represent an expression as a symbol, it puts
+it in the expr section.
+@c FIXME item debug
+@c FIXME item transfer[t] vector preload
+@c FIXME item transfer[t] vector postload
+@c FIXME item register
+@end table
+
+@node Sub-Sections
+@section Sub-Sections
+
+@cindex numbered subsections
+@cindex grouping data
+@ifset aout-bout
+Assembled bytes
+@ifset COFF
+conventionally
+@end ifset
+fall into two sections: text and data.
+@end ifset
+You may have separate groups of
+@ifset GENERIC
+data in named sections
+@end ifset
+@ifclear GENERIC
+@ifclear aout-bout
+data in named sections
+@end ifclear
+@ifset aout-bout
+text or data
+@end ifset
+@end ifclear
+that you want to end up near to each other in the object file, even though they
+are not contiguous in the assembler source. @code{@value{AS}} allows you to
+use @dfn{subsections} for this purpose. Within each section, there can be
+numbered subsections with values from 0 to 8192. Objects assembled into the
+same subsection go into the object file together with other objects in the same
+subsection. For example, a compiler might want to store constants in the text
+section, but might not want to have them interspersed with the program being
+assembled. In this case, the compiler could issue a @samp{.text 0} before each
+section of code being output, and a @samp{.text 1} before each group of
+constants being output.
+
+Subsections are optional. If you do not use subsections, everything
+goes in subsection number zero.
+
+@ifset GENERIC
+Each subsection is zero-padded up to a multiple of four bytes.
+(Subsections may be padded a different amount on different flavors
+of @code{@value{AS}}.)
+@end ifset
+@ifclear GENERIC
+@ifset H8
+On the H8/300 and H8/500 platforms, each subsection is zero-padded to a word
+boundary (two bytes).
+The same is true on the Hitachi SH.
+@end ifset
+@ifset I960
+@c FIXME section padding (alignment)?
+@c Rich Pixley says padding here depends on target obj code format; that
+@c doesn't seem particularly useful to say without further elaboration,
+@c so for now I say nothing about it. If this is a generic BFD issue,
+@c these paragraphs might need to vanish from this manual, and be
+@c discussed in BFD chapter of binutils (or some such).
+@end ifset
+@ifset A29K
+On the AMD 29K family, no particular padding is added to section or
+subsection sizes; @value{AS} forces no alignment on this platform.
+@end ifset
+@end ifclear
+
+Subsections appear in your object file in numeric order, lowest numbered
+to highest. (All this to be compatible with other people's assemblers.)
+The object file contains no representation of subsections; @code{@value{LD}} and
+other programs that manipulate object files see no trace of them.
+They just see all your text subsections as a text section, and all your
+data subsections as a data section.
+
+To specify which subsection you want subsequent statements assembled
+into, use a numeric argument to specify it, in a @samp{.text
+@var{expression}} or a @samp{.data @var{expression}} statement.
+@ifset COFF
+@ifset GENERIC
+When generating COFF output, you
+@end ifset
+@ifclear GENERIC
+You
+@end ifclear
+can also use an extra subsection
+argument with arbitrary named sections: @samp{.section @var{name},
+@var{expression}}.
+@end ifset
+@var{Expression} should be an absolute expression.
+(@xref{Expressions}.) If you just say @samp{.text} then @samp{.text 0}
+is assumed. Likewise @samp{.data} means @samp{.data 0}. Assembly
+begins in @code{text 0}. For instance:
+@smallexample
+.text 0 # The default subsection is text 0 anyway.
+.ascii "This lives in the first text subsection. *"
+.text 1
+.ascii "But this lives in the second text subsection."
+.data 0
+.ascii "This lives in the data section,"
+.ascii "in the first data subsection."
+.text 0
+.ascii "This lives in the first text section,"
+.ascii "immediately following the asterisk (*)."
+@end smallexample
+
+Each section has a @dfn{location counter} incremented by one for every byte
+assembled into that section. Because subsections are merely a convenience
+restricted to @code{@value{AS}} there is no concept of a subsection location
+counter. There is no way to directly manipulate a location counter---but the
+@code{.align} directive changes it, and any label definition captures its
+current value. The location counter of the section where statements are being
+assembled is said to be the @dfn{active} location counter.
+
+@node bss
+@section bss Section
+
+@cindex bss section
+@cindex common variable storage
+The bss section is used for local common variable storage.
+You may allocate address space in the bss section, but you may
+not dictate data to load into it before your program executes. When
+your program starts running, all the contents of the bss
+section are zeroed bytes.
+
+The @code{.lcomm} pseudo-op defines a symbol in the bss section; see
+@ref{Lcomm,,@code{.lcomm}}.
+
+The @code{.comm} pseudo-op may be used to declare a common symbol, which is
+another form of uninitialized symbol; see @xref{Comm,,@code{.comm}}.
+
+@ifset GENERIC
+When assembling for a target which supports multiple sections, such as ELF or
+COFF, you may switch into the @code{.bss} section and define symbols as usual;
+see @ref{Section,,@code{.section}}. You may only assemble zero values into the
+section. Typically the section will only contain symbol definitions and
+@code{.skip} directives (@pxref{Skip,,@code{.skip}}).
+@end ifset
+
+@node Symbols
+@chapter Symbols
+
+@cindex symbols
+Symbols are a central concept: the programmer uses symbols to name
+things, the linker uses symbols to link, and the debugger uses symbols
+to debug.
+
+@quotation
+@cindex debuggers, and symbol order
+@emph{Warning:} @code{@value{AS}} does not place symbols in the object file in
+the same order they were declared. This may break some debuggers.
+@end quotation
+
+@menu
+* Labels:: Labels
+* Setting Symbols:: Giving Symbols Other Values
+* Symbol Names:: Symbol Names
+* Dot:: The Special Dot Symbol
+* Symbol Attributes:: Symbol Attributes
+@end menu
+
+@node Labels
+@section Labels
+
+@cindex labels
+A @dfn{label} is written as a symbol immediately followed by a colon
+@samp{:}. The symbol then represents the current value of the
+active location counter, and is, for example, a suitable instruction
+operand. You are warned if you use the same symbol to represent two
+different locations: the first definition overrides any other
+definitions.
+
+@ifset HPPA
+On the HPPA, the usual form for a label need not be immediately followed by a
+colon, but instead must start in column zero. Only one label may be defined on
+a single line. To work around this, the HPPA version of @code{@value{AS}} also
+provides a special directive @code{.label} for defining labels more flexibly.
+@end ifset
+
+@node Setting Symbols
+@section Giving Symbols Other Values
+
+@cindex assigning values to symbols
+@cindex symbol values, assigning
+A symbol can be given an arbitrary value by writing a symbol, followed
+by an equals sign @samp{=}, followed by an expression
+(@pxref{Expressions}). This is equivalent to using the @code{.set}
+directive. @xref{Set,,@code{.set}}.
+
+@node Symbol Names
+@section Symbol Names
+
+@cindex symbol names
+@cindex names, symbol
+@ifclear SPECIAL-SYMS
+Symbol names begin with a letter or with one of @samp{._}. On most
+machines, you can also use @code{$} in symbol names; exceptions are
+noted in @ref{Machine Dependencies}. That character may be followed by any
+string of digits, letters, dollar signs (unless otherwise noted in
+@ref{Machine Dependencies}), and underscores.
+@end ifclear
+@ifset A29K
+For the AMD 29K family, @samp{?} is also allowed in the
+body of a symbol name, though not at its beginning.
+@end ifset
+
+@ifset SPECIAL-SYMS
+@ifset H8
+Symbol names begin with a letter or with one of @samp{._}. On the
+Hitachi SH or the
+H8/500, you can also use @code{$} in symbol names. That character may
+be followed by any string of digits, letters, dollar signs (save on the
+H8/300), and underscores.
+@end ifset
+@end ifset
+
+Case of letters is significant: @code{foo} is a different symbol name
+than @code{Foo}.
+
+Each symbol has exactly one name. Each name in an assembly language program
+refers to exactly one symbol. You may use that symbol name any number of times
+in a program.
+
+@subheading Local Symbol Names
+
+@cindex local symbol names
+@cindex symbol names, local
+@cindex temporary symbol names
+@cindex symbol names, temporary
+Local symbols help compilers and programmers use names temporarily.
+There are ten local symbol names, which are re-used throughout the
+program. You may refer to them using the names @samp{0} @samp{1}
+@dots{} @samp{9}. To define a local symbol, write a label of the form
+@samp{@b{N}:} (where @b{N} represents any digit). To refer to the most
+recent previous definition of that symbol write @samp{@b{N}b}, using the
+same digit as when you defined the label. To refer to the next
+definition of a local label, write @samp{@b{N}f}---where @b{N} gives you
+a choice of 10 forward references. The @samp{b} stands for
+``backwards'' and the @samp{f} stands for ``forwards''.
+
+Local symbols are not emitted by the current @sc{gnu} C compiler.
+
+There is no restriction on how you can use these labels, but
+remember that at any point in the assembly you can refer to at most
+10 prior local labels and to at most 10 forward local labels.
+
+Local symbol names are only a notation device. They are immediately
+transformed into more conventional symbol names before the assembler
+uses them. The symbol names stored in the symbol table, appearing in
+error messages and optionally emitted to the object file have these
+parts:
+
+@table @code
+@item L
+All local labels begin with @samp{L}. Normally both @code{@value{AS}} and
+@code{@value{LD}} forget symbols that start with @samp{L}. These labels are
+used for symbols you are never intended to see. If you use the
+@samp{-L} option then @code{@value{AS}} retains these symbols in the
+object file. If you also instruct @code{@value{LD}} to retain these symbols,
+you may use them in debugging.
+
+@item @var{digit}
+If the label is written @samp{0:} then the digit is @samp{0}.
+If the label is written @samp{1:} then the digit is @samp{1}.
+And so on up through @samp{9:}.
+
+@item @kbd{C-A}
+This unusual character is included so you do not accidentally invent
+a symbol of the same name. The character has ASCII value
+@samp{\001}.
+
+@item @emph{ordinal number}
+This is a serial number to keep the labels distinct. The first
+@samp{0:} gets the number @samp{1}; The 15th @samp{0:} gets the
+number @samp{15}; @emph{etc.}. Likewise for the other labels @samp{1:}
+through @samp{9:}.
+@end table
+
+For instance, the first @code{1:} is named @code{L1@kbd{C-A}1}, the 44th
+@code{3:} is named @code{L3@kbd{C-A}44}.
+
+@node Dot
+@section The Special Dot Symbol
+
+@cindex dot (symbol)
+@cindex @code{.} (symbol)
+@cindex current address
+@cindex location counter
+The special symbol @samp{.} refers to the current address that
+@code{@value{AS}} is assembling into. Thus, the expression @samp{melvin:
+.long .} defines @code{melvin} to contain its own address.
+Assigning a value to @code{.} is treated the same as a @code{.org}
+directive. Thus, the expression @samp{.=.+4} is the same as saying
+@ifclear no-space-dir
+@samp{.space 4}.
+@end ifclear
+@ifset no-space-dir
+@ifset A29K
+@samp{.block 4}.
+@end ifset
+@end ifset
+
+@node Symbol Attributes
+@section Symbol Attributes
+
+@cindex symbol attributes
+@cindex attributes, symbol
+Every symbol has, as well as its name, the attributes ``Value'' and
+``Type''. Depending on output format, symbols can also have auxiliary
+attributes.
+@ifset INTERNALS
+The detailed definitions are in @file{a.out.h}.
+@end ifset
+
+If you use a symbol without defining it, @code{@value{AS}} assumes zero for
+all these attributes, and probably won't warn you. This makes the
+symbol an externally defined symbol, which is generally what you
+would want.
+
+@menu
+* Symbol Value:: Value
+* Symbol Type:: Type
+@ifset aout-bout
+@ifset GENERIC
+* a.out Symbols:: Symbol Attributes: @code{a.out}
+@end ifset
+@ifclear GENERIC
+@ifclear BOUT
+* a.out Symbols:: Symbol Attributes: @code{a.out}
+@end ifclear
+@ifset BOUT
+* a.out Symbols:: Symbol Attributes: @code{a.out}, @code{b.out}
+@end ifset
+@end ifclear
+@end ifset
+@ifset COFF
+* COFF Symbols:: Symbol Attributes for COFF
+@end ifset
+@ifset SOM
+* SOM Symbols:: Symbol Attributes for SOM
+@end ifset
+@end menu
+
+@node Symbol Value
+@subsection Value
+
+@cindex value of a symbol
+@cindex symbol value
+The value of a symbol is (usually) 32 bits. For a symbol which labels a
+location in the text, data, bss or absolute sections the value is the
+number of addresses from the start of that section to the label.
+Naturally for text, data and bss sections the value of a symbol changes
+as @code{@value{LD}} changes section base addresses during linking. Absolute
+symbols' values do not change during linking: that is why they are
+called absolute.
+
+The value of an undefined symbol is treated in a special way. If it is
+0 then the symbol is not defined in this assembler source file, and
+@code{@value{LD}} tries to determine its value from other files linked into the
+same program. You make this kind of symbol simply by mentioning a symbol
+name without defining it. A non-zero value represents a @code{.comm}
+common declaration. The value is how much common storage to reserve, in
+bytes (addresses). The symbol refers to the first address of the
+allocated storage.
+
+@node Symbol Type
+@subsection Type
+
+@cindex type of a symbol
+@cindex symbol type
+The type attribute of a symbol contains relocation (section)
+information, any flag settings indicating that a symbol is external, and
+(optionally), other information for linkers and debuggers. The exact
+format depends on the object-code output format in use.
+
+@ifset aout-bout
+@ifclear GENERIC
+@ifset BOUT
+@c The following avoids a "widow" subsection title. @group would be
+@c better if it were available outside examples.
+@need 1000
+@node a.out Symbols
+@subsection Symbol Attributes: @code{a.out}, @code{b.out}
+
+@cindex @code{b.out} symbol attributes
+@cindex symbol attributes, @code{b.out}
+These symbol attributes appear only when @code{@value{AS}} is configured for
+one of the Berkeley-descended object output formats---@code{a.out} or
+@code{b.out}.
+
+@end ifset
+@ifclear BOUT
+@node a.out Symbols
+@subsection Symbol Attributes: @code{a.out}
+
+@cindex @code{a.out} symbol attributes
+@cindex symbol attributes, @code{a.out}
+
+@end ifclear
+@end ifclear
+@ifset GENERIC
+@node a.out Symbols
+@subsection Symbol Attributes: @code{a.out}
+
+@cindex @code{a.out} symbol attributes
+@cindex symbol attributes, @code{a.out}
+
+@end ifset
+@menu
+* Symbol Desc:: Descriptor
+* Symbol Other:: Other
+@end menu
+
+@node Symbol Desc
+@subsubsection Descriptor
+
+@cindex descriptor, of @code{a.out} symbol
+This is an arbitrary 16-bit value. You may establish a symbol's
+descriptor value by using a @code{.desc} statement
+(@pxref{Desc,,@code{.desc}}). A descriptor value means nothing to
+@code{@value{AS}}.
+
+@node Symbol Other
+@subsubsection Other
+
+@cindex other attribute, of @code{a.out} symbol
+This is an arbitrary 8-bit value. It means nothing to @code{@value{AS}}.
+@end ifset
+
+@ifset COFF
+@node COFF Symbols
+@subsection Symbol Attributes for COFF
+
+@cindex COFF symbol attributes
+@cindex symbol attributes, COFF
+
+The COFF format supports a multitude of auxiliary symbol attributes;
+like the primary symbol attributes, they are set between @code{.def} and
+@code{.endef} directives.
+
+@subsubsection Primary Attributes
+
+@cindex primary attributes, COFF symbols
+The symbol name is set with @code{.def}; the value and type,
+respectively, with @code{.val} and @code{.type}.
+
+@subsubsection Auxiliary Attributes
+
+@cindex auxiliary attributes, COFF symbols
+The @code{@value{AS}} directives @code{.dim}, @code{.line}, @code{.scl},
+@code{.size}, and @code{.tag} can generate auxiliary symbol table
+information for COFF.
+@end ifset
+
+@ifset SOM
+@node SOM Symbols
+@subsection Symbol Attributes for SOM
+
+@cindex SOM symbol attributes
+@cindex symbol attributes, SOM
+
+The SOM format for the HPPA supports a multitude of symbol attributes set with
+the @code{.EXPORT} and @code{.IMPORT} directives.
+
+The attributes are described in @cite{HP9000 Series 800 Assembly
+Language Reference Manual} (HP 92432-90001) under the @code{IMPORT} and
+@code{EXPORT} assembler directive documentation.
+@end ifset
+
+@node Expressions
+@chapter Expressions
+
+@cindex expressions
+@cindex addresses
+@cindex numeric values
+An @dfn{expression} specifies an address or numeric value.
+Whitespace may precede and/or follow an expression.
+
+The result of an expression must be an absolute number, or else an offset into
+a particular section. If an expression is not absolute, and there is not
+enough information when @code{@value{AS}} sees the expression to know its
+section, a second pass over the source program might be necessary to interpret
+the expression---but the second pass is currently not implemented.
+@code{@value{AS}} aborts with an error message in this situation.
+
+@menu
+* Empty Exprs:: Empty Expressions
+* Integer Exprs:: Integer Expressions
+@end menu
+
+@node Empty Exprs
+@section Empty Expressions
+
+@cindex empty expressions
+@cindex expressions, empty
+An empty expression has no value: it is just whitespace or null.
+Wherever an absolute expression is required, you may omit the
+expression, and @code{@value{AS}} assumes a value of (absolute) 0. This
+is compatible with other assemblers.
+
+@node Integer Exprs
+@section Integer Expressions
+
+@cindex integer expressions
+@cindex expressions, integer
+An @dfn{integer expression} is one or more @emph{arguments} delimited
+by @emph{operators}.
+
+@menu
+* Arguments:: Arguments
+* Operators:: Operators
+* Prefix Ops:: Prefix Operators
+* Infix Ops:: Infix Operators
+@end menu
+
+@node Arguments
+@subsection Arguments
+
+@cindex expression arguments
+@cindex arguments in expressions
+@cindex operands in expressions
+@cindex arithmetic operands
+@dfn{Arguments} are symbols, numbers or subexpressions. In other
+contexts arguments are sometimes called ``arithmetic operands''. In
+this manual, to avoid confusing them with the ``instruction operands'' of
+the machine language, we use the term ``argument'' to refer to parts of
+expressions only, reserving the word ``operand'' to refer only to machine
+instruction operands.
+
+Symbols are evaluated to yield @{@var{section} @var{NNN}@} where
+@var{section} is one of text, data, bss, absolute,
+or undefined. @var{NNN} is a signed, 2's complement 32 bit
+integer.
+
+Numbers are usually integers.
+
+A number can be a flonum or bignum. In this case, you are warned
+that only the low order 32 bits are used, and @code{@value{AS}} pretends
+these 32 bits are an integer. You may write integer-manipulating
+instructions that act on exotic constants, compatible with other
+assemblers.
+
+@cindex subexpressions
+Subexpressions are a left parenthesis @samp{(} followed by an integer
+expression, followed by a right parenthesis @samp{)}; or a prefix
+operator followed by an argument.
+
+@node Operators
+@subsection Operators
+
+@cindex operators, in expressions
+@cindex arithmetic functions
+@cindex functions, in expressions
+@dfn{Operators} are arithmetic functions, like @code{+} or @code{%}. Prefix
+operators are followed by an argument. Infix operators appear
+between their arguments. Operators may be preceded and/or followed by
+whitespace.
+
+@node Prefix Ops
+@subsection Prefix Operator
+
+@cindex prefix operators
+@code{@value{AS}} has the following @dfn{prefix operators}. They each take
+one argument, which must be absolute.
+
+@c the tex/end tex stuff surrounding this small table is meant to make
+@c it align, on the printed page, with the similar table in the next
+@c section (which is inside an enumerate).
+@tex
+\global\advance\leftskip by \itemindent
+@end tex
+
+@table @code
+@item -
+@dfn{Negation}. Two's complement negation.
+@item ~
+@dfn{Complementation}. Bitwise not.
+@end table
+
+@tex
+\global\advance\leftskip by -\itemindent
+@end tex
+
+@node Infix Ops
+@subsection Infix Operators
+
+@cindex infix operators
+@cindex operators, permitted arguments
+@dfn{Infix operators} take two arguments, one on either side. Operators
+have precedence, but operations with equal precedence are performed left
+to right. Apart from @code{+} or @code{-}, both arguments must be
+absolute, and the result is absolute.
+
+@enumerate
+@cindex operator precedence
+@cindex precedence of operators
+
+@item
+Highest Precedence
+
+@table @code
+@item *
+@dfn{Multiplication}.
+
+@item /
+@dfn{Division}. Truncation is the same as the C operator @samp{/}
+
+@item %
+@dfn{Remainder}.
+
+@item <
+@itemx <<
+@dfn{Shift Left}. Same as the C operator @samp{<<}.
+
+@item >
+@itemx >>
+@dfn{Shift Right}. Same as the C operator @samp{>>}.
+@end table
+
+@item
+Intermediate precedence
+
+@table @code
+@item |
+
+@dfn{Bitwise Inclusive Or}.
+
+@item &
+@dfn{Bitwise And}.
+
+@item ^
+@dfn{Bitwise Exclusive Or}.
+
+@item !
+@dfn{Bitwise Or Not}.
+@end table
+
+@item
+Lowest Precedence
+
+@table @code
+@cindex addition, permitted arguments
+@cindex plus, permitted arguments
+@cindex arguments for addition
+@item +
+@dfn{Addition}. If either argument is absolute, the result has the section of
+the other argument. You may not add together arguments from different
+sections.
+
+@cindex subtraction, permitted arguments
+@cindex minus, permitted arguments
+@cindex arguments for subtraction
+@item -
+@dfn{Subtraction}. If the right argument is absolute, the
+result has the section of the left argument.
+If both arguments are in the same section, the result is absolute.
+You may not subtract arguments from different sections.
+@c FIXME is there still something useful to say about undefined - undefined ?
+@end table
+@end enumerate
+
+In short, it's only meaningful to add or subtract the @emph{offsets} in an
+address; you can only have a defined section in one of the two arguments.
+
+@node Pseudo Ops
+@chapter Assembler Directives
+
+@cindex directives, machine independent
+@cindex pseudo-ops, machine independent
+@cindex machine independent directives
+All assembler directives have names that begin with a period (@samp{.}).
+The rest of the name is letters, usually in lower case.
+
+This chapter discusses directives that are available regardless of the
+target machine configuration for the @sc{gnu} assembler.
+@ifset GENERIC
+Some machine configurations provide additional directives.
+@xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset machine-directives
+@xref{Machine Dependencies} for additional directives.
+@end ifset
+@end ifclear
+
+@menu
+* Abort:: @code{.abort}
+@ifset COFF
+* ABORT:: @code{.ABORT}
+@end ifset
+
+* Align:: @code{.align @var{abs-expr} , @var{abs-expr}}
+* Ascii:: @code{.ascii "@var{string}"}@dots{}
+* Asciz:: @code{.asciz "@var{string}"}@dots{}
+* Balign:: @code{.balign @var{abs-expr} , @var{abs-expr}}
+* Byte:: @code{.byte @var{expressions}}
+* Comm:: @code{.comm @var{symbol} , @var{length} }
+* Data:: @code{.data @var{subsection}}
+@ifset COFF
+* Def:: @code{.def @var{name}}
+@end ifset
+@ifset aout-bout
+* Desc:: @code{.desc @var{symbol}, @var{abs-expression}}
+@end ifset
+@ifset COFF
+* Dim:: @code{.dim}
+@end ifset
+
+* Double:: @code{.double @var{flonums}}
+* Eject:: @code{.eject}
+* Else:: @code{.else}
+* End:: @code{.end}
+@ifset COFF
+* Endef:: @code{.endef}
+@end ifset
+
+* Endfunc:: @code{.endfunc}
+* Endif:: @code{.endif}
+* Equ:: @code{.equ @var{symbol}, @var{expression}}
+* Equiv:: @code{.equiv @var{symbol}, @var{expression}}
+* Err:: @code{.err}
+* Exitm:: @code{.exitm}
+* Extern:: @code{.extern}
+* Fail:: @code{.fail}
+@ifclear no-file-dir
+* File:: @code{.file @var{string}}
+@end ifclear
+
+* Fill:: @code{.fill @var{repeat} , @var{size} , @var{value}}
+* Float:: @code{.float @var{flonums}}
+* Func:: @code{.func}
+* Global:: @code{.global @var{symbol}}, @code{.globl @var{symbol}}
+* hword:: @code{.hword @var{expressions}}
+* Ident:: @code{.ident}
+* If:: @code{.if @var{absolute expression}}
+* Include:: @code{.include "@var{file}"}
+* Int:: @code{.int @var{expressions}}
+* Irp:: @code{.irp @var{symbol},@var{values}}@dots{}
+* Irpc:: @code{.irpc @var{symbol},@var{values}}@dots{}
+* Lcomm:: @code{.lcomm @var{symbol} , @var{length}}
+* Lflags:: @code{.lflags}
+@ifclear no-line-dir
+* Line:: @code{.line @var{line-number}}
+@end ifclear
+
+* Ln:: @code{.ln @var{line-number}}
+* Linkonce:: @code{.linkonce [@var{type}]}
+* List:: @code{.list}
+* Long:: @code{.long @var{expressions}}
+@ignore
+* Lsym:: @code{.lsym @var{symbol}, @var{expression}}
+@end ignore
+
+* Macro:: @code{.macro @var{name} @var{args}}@dots{}
+* MRI:: @code{.mri @var{val}}
+
+* Nolist:: @code{.nolist}
+* Octa:: @code{.octa @var{bignums}}
+* Org:: @code{.org @var{new-lc} , @var{fill}}
+* P2align:: @code{.p2align @var{abs-expr} , @var{abs-expr}}
+* Print:: @code{.print @var{string}}
+* Psize:: @code{.psize @var{lines}, @var{columns}}
+* Purgem:: @code{.purgem @var{name}}
+* Quad:: @code{.quad @var{bignums}}
+* Rept:: @code{.rept @var{count}}
+* Sbttl:: @code{.sbttl "@var{subheading}"}
+@ifset COFF
+* Scl:: @code{.scl @var{class}}
+* Section:: @code{.section @var{name}, @var{subsection}}
+@end ifset
+
+* Set:: @code{.set @var{symbol}, @var{expression}}
+* Short:: @code{.short @var{expressions}}
+* Single:: @code{.single @var{flonums}}
+@ifset COFF
+* Size:: @code{.size}
+@end ifset
+
+* Skip:: @code{.skip @var{size} , @var{fill}}
+* Sleb128:: @code{.sleb128 @var{expressions}}
+* Space:: @code{.space @var{size} , @var{fill}}
+@ifset have-stabs
+* Stab:: @code{.stabd, .stabn, .stabs}
+@end ifset
+
+* String:: @code{.string "@var{str}"}
+* Struct:: @code{.struct @var{expression}}
+@ifset ELF
+* Symver:: @code{.symver @var{name},@var{name2@@nodename}}
+@end ifset
+@ifset COFF
+* Tag:: @code{.tag @var{structname}}
+@end ifset
+
+* Text:: @code{.text @var{subsection}}
+* Title:: @code{.title "@var{heading}"}
+@ifset COFF
+* Type:: @code{.type @var{int}}
+* Val:: @code{.val @var{addr}}
+@end ifset
+
+* Uleb128:: @code{.uleb128 @var{expressions}}
+* Word:: @code{.word @var{expressions}}
+* Deprecated:: Deprecated Directives
+@end menu
+
+@node Abort
+@section @code{.abort}
+
+@cindex @code{abort} directive
+@cindex stopping the assembly
+This directive stops the assembly immediately. It is for
+compatibility with other assemblers. The original idea was that the
+assembly language source would be piped into the assembler. If the sender
+of the source quit, it could use this directive tells @code{@value{AS}} to
+quit also. One day @code{.abort} will not be supported.
+
+@ifset COFF
+@node ABORT
+@section @code{.ABORT}
+
+@cindex @code{ABORT} directive
+When producing COFF output, @code{@value{AS}} accepts this directive as a
+synonym for @samp{.abort}.
+
+@ifset BOUT
+When producing @code{b.out} output, @code{@value{AS}} accepts this directive,
+but ignores it.
+@end ifset
+@end ifset
+
+@node Align
+@section @code{.align @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
+
+@cindex padding the location counter
+@cindex @code{align} directive
+Pad the location counter (in the current subsection) to a particular storage
+boundary. The first expression (which must be absolute) is the alignment
+required, as described below.
+
+The second expression (also absolute) gives the fill value to be stored in the
+padding bytes. It (and the comma) may be omitted. If it is omitted, the
+padding bytes are normally zero. However, on some systems, if the section is
+marked as containing code and the fill value is omitted, the space is filled
+with no-op instructions.
+
+The third expression is also absolute, and is also optional. If it is present,
+it is the maximum number of bytes that should be skipped by this alignment
+directive. If doing the alignment would require skipping more bytes than the
+specified maximum, then the alignment is not done at all. You can omit the
+fill value (the second argument) entirely by simply using two commas after the
+required alignment; this can be useful if you want the alignment to be filled
+with no-op instructions when appropriate.
+
+The way the required alignment is specified varies from system to system.
+For the a29k, hppa, m68k, m88k, w65, sparc, and Hitachi SH, and i386 using ELF
+format,
+the first expression is the
+alignment request in bytes. For example @samp{.align 8} advances
+the location counter until it is a multiple of 8. If the location counter
+is already a multiple of 8, no change is needed.
+
+For other systems, including the i386 using a.out format, it is the
+number of low-order zero bits the location counter must have after
+advancement. For example @samp{.align 3} advances the location
+counter until it a multiple of 8. If the location counter is already a
+multiple of 8, no change is needed.
+
+This inconsistency is due to the different behaviors of the various
+native assemblers for these systems which GAS must emulate.
+GAS also provides @code{.balign} and @code{.p2align} directives,
+described later, which have a consistent behavior across all
+architectures (but are specific to GAS).
+
+@node Ascii
+@section @code{.ascii "@var{string}"}@dots{}
+
+@cindex @code{ascii} directive
+@cindex string literals
+@code{.ascii} expects zero or more string literals (@pxref{Strings})
+separated by commas. It assembles each string (with no automatic
+trailing zero byte) into consecutive addresses.
+
+@node Asciz
+@section @code{.asciz "@var{string}"}@dots{}
+
+@cindex @code{asciz} directive
+@cindex zero-terminated strings
+@cindex null-terminated strings
+@code{.asciz} is just like @code{.ascii}, but each string is followed by
+a zero byte. The ``z'' in @samp{.asciz} stands for ``zero''.
+
+@node Balign
+@section @code{.balign[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
+
+@cindex padding the location counter given number of bytes
+@cindex @code{balign} directive
+Pad the location counter (in the current subsection) to a particular
+storage boundary. The first expression (which must be absolute) is the
+alignment request in bytes. For example @samp{.balign 8} advances
+the location counter until it is a multiple of 8. If the location counter
+is already a multiple of 8, no change is needed.
+
+The second expression (also absolute) gives the fill value to be stored in the
+padding bytes. It (and the comma) may be omitted. If it is omitted, the
+padding bytes are normally zero. However, on some systems, if the section is
+marked as containing code and the fill value is omitted, the space is filled
+with no-op instructions.
+
+The third expression is also absolute, and is also optional. If it is present,
+it is the maximum number of bytes that should be skipped by this alignment
+directive. If doing the alignment would require skipping more bytes than the
+specified maximum, then the alignment is not done at all. You can omit the
+fill value (the second argument) entirely by simply using two commas after the
+required alignment; this can be useful if you want the alignment to be filled
+with no-op instructions when appropriate.
+
+@cindex @code{balignw} directive
+@cindex @code{balignl} directive
+The @code{.balignw} and @code{.balignl} directives are variants of the
+@code{.balign} directive. The @code{.balignw} directive treats the fill
+pattern as a two byte word value. The @code{.balignl} directives treats the
+fill pattern as a four byte longword value. For example, @code{.balignw
+4,0x368d} will align to a multiple of 4. If it skips two bytes, they will be
+filled in with the value 0x368d (the exact placement of the bytes depends upon
+the endianness of the processor). If it skips 1 or 3 bytes, the fill value is
+undefined.
+
+@node Byte
+@section @code{.byte @var{expressions}}
+
+@cindex @code{byte} directive
+@cindex integers, one byte
+@code{.byte} expects zero or more expressions, separated by commas.
+Each expression is assembled into the next byte.
+
+@node Comm
+@section @code{.comm @var{symbol} , @var{length} }
+
+@cindex @code{comm} directive
+@cindex symbol, common
+@code{.comm} declares a common symbol named @var{symbol}. When linking, a
+common symbol in one object file may be merged with a defined or common symbol
+of the same name in another object file. If @code{@value{LD}} does not see a
+definition for the symbol--just one or more common symbols--then it will
+allocate @var{length} bytes of uninitialized memory. @var{length} must be an
+absolute expression. If @code{@value{LD}} sees multiple common symbols with
+the same name, and they do not all have the same size, it will allocate space
+using the largest size.
+
+@ifset ELF
+When using ELF, the @code{.comm} directive takes an optional third argument.
+This is the desired alignment of the symbol, specified as a byte boundary (for
+example, an alignment of 16 means that the least significant 4 bits of the
+address should be zero). The alignment must be an absolute expression, and it
+must be a power of two. If @code{@value{LD}} allocates uninitialized memory
+for the common symbol, it will use the alignment when placing the symbol. If
+no alignment is specified, @code{@value{AS}} will set the alignment to the
+largest power of two less than or equal to the size of the symbol, up to a
+maximum of 16.
+@end ifset
+
+@ifset HPPA
+The syntax for @code{.comm} differs slightly on the HPPA. The syntax is
+@samp{@var{symbol} .comm, @var{length}}; @var{symbol} is optional.
+@end ifset
+
+@node Data
+@section @code{.data @var{subsection}}
+
+@cindex @code{data} directive
+@code{.data} tells @code{@value{AS}} to assemble the following statements onto the
+end of the data subsection numbered @var{subsection} (which is an
+absolute expression). If @var{subsection} is omitted, it defaults
+to zero.
+
+@ifset COFF
+@node Def
+@section @code{.def @var{name}}
+
+@cindex @code{def} directive
+@cindex COFF symbols, debugging
+@cindex debugging COFF symbols
+Begin defining debugging information for a symbol @var{name}; the
+definition extends until the @code{.endef} directive is encountered.
+@ifset BOUT
+
+This directive is only observed when @code{@value{AS}} is configured for COFF
+format output; when producing @code{b.out}, @samp{.def} is recognized,
+but ignored.
+@end ifset
+@end ifset
+
+@ifset aout-bout
+@node Desc
+@section @code{.desc @var{symbol}, @var{abs-expression}}
+
+@cindex @code{desc} directive
+@cindex COFF symbol descriptor
+@cindex symbol descriptor, COFF
+This directive sets the descriptor of the symbol (@pxref{Symbol Attributes})
+to the low 16 bits of an absolute expression.
+
+@ifset COFF
+The @samp{.desc} directive is not available when @code{@value{AS}} is
+configured for COFF output; it is only for @code{a.out} or @code{b.out}
+object format. For the sake of compatibility, @code{@value{AS}} accepts
+it, but produces no output, when configured for COFF.
+@end ifset
+@end ifset
+
+@ifset COFF
+@node Dim
+@section @code{.dim}
+
+@cindex @code{dim} directive
+@cindex COFF auxiliary symbol information
+@cindex auxiliary symbol information, COFF
+This directive is generated by compilers to include auxiliary debugging
+information in the symbol table. It is only permitted inside
+@code{.def}/@code{.endef} pairs.
+@ifset BOUT
+
+@samp{.dim} is only meaningful when generating COFF format output; when
+@code{@value{AS}} is generating @code{b.out}, it accepts this directive but
+ignores it.
+@end ifset
+@end ifset
+
+@node Double
+@section @code{.double @var{flonums}}
+
+@cindex @code{double} directive
+@cindex floating point numbers (double)
+@code{.double} expects zero or more flonums, separated by commas. It
+assembles floating point numbers.
+@ifset GENERIC
+The exact kind of floating point numbers emitted depends on how
+@code{@value{AS}} is configured. @xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset IEEEFLOAT
+On the @value{TARGET} family @samp{.double} emits 64-bit floating-point numbers
+in @sc{ieee} format.
+@end ifset
+@end ifclear
+
+@node Eject
+@section @code{.eject}
+
+@cindex @code{eject} directive
+@cindex new page, in listings
+@cindex page, in listings
+@cindex listing control: new page
+Force a page break at this point, when generating assembly listings.
+
+@node Else
+@section @code{.else}
+
+@cindex @code{else} directive
+@code{.else} is part of the @code{@value{AS}} support for conditional
+assembly; @pxref{If,,@code{.if}}. It marks the beginning of a section
+of code to be assembled if the condition for the preceding @code{.if}
+was false.
+
+@node End
+@section @code{.end}
+
+@cindex @code{end} directive
+@code{.end} marks the end of the assembly file. @code{@value{AS}} does not
+process anything in the file past the @code{.end} directive.
+
+@ifset COFF
+@node Endef
+@section @code{.endef}
+
+@cindex @code{endef} directive
+This directive flags the end of a symbol definition begun with
+@code{.def}.
+@ifset BOUT
+
+@samp{.endef} is only meaningful when generating COFF format output; if
+@code{@value{AS}} is configured to generate @code{b.out}, it accepts this
+directive but ignores it.
+@end ifset
+@end ifset
+
+@node Endfunc
+@section @code{.endfunc}
+@cindex @code{endfunc} directive
+@code{.endfunc} marks the end of a function specified with @code{.func}.
+
+@node Endif
+@section @code{.endif}
+
+@cindex @code{endif} directive
+@code{.endif} is part of the @code{@value{AS}} support for conditional assembly;
+it marks the end of a block of code that is only assembled
+conditionally. @xref{If,,@code{.if}}.
+
+@node Equ
+@section @code{.equ @var{symbol}, @var{expression}}
+
+@cindex @code{equ} directive
+@cindex assigning values to symbols
+@cindex symbols, assigning values to
+This directive sets the value of @var{symbol} to @var{expression}.
+It is synonymous with @samp{.set}; @pxref{Set,,@code{.set}}.
+
+@ifset HPPA
+The syntax for @code{equ} on the HPPA is
+@samp{@var{symbol} .equ @var{expression}}.
+@end ifset
+
+@node Equiv
+@section @code{.equiv @var{symbol}, @var{expression}}
+@cindex @code{equiv} directive
+The @code{.equiv} directive is like @code{.equ} and @code{.set}, except that
+the assembler will signal an error if @var{symbol} is already defined.
+
+Except for the contents of the error message, this is roughly equivalent to
+@smallexample
+.ifdef SYM
+.err
+.endif
+.equ SYM,VAL
+@end smallexample
+
+@node Err
+@section @code{.err}
+@cindex @code{err} directive
+If @code{@value{AS}} assembles a @code{.err} directive, it will print an error
+message and, unless the @code{-Z} option was used, it will not generate an
+object file. This can be used to signal error an conditionally compiled code.
+
+@node Exitm
+@section @code{.exitm}
+Exit early from the current macro definition. @xref{Macro}.
+
+@node Extern
+@section @code{.extern}
+
+@cindex @code{extern} directive
+@code{.extern} is accepted in the source program---for compatibility
+with other assemblers---but it is ignored. @code{@value{AS}} treats
+all undefined symbols as external.
+
+@node Fail
+@section @code{.fail @var{expression}}
+
+@cindex @code{fail} directive
+Generates an error or a warning. If the value of the @var{expression} is 500
+or more, @code{@value{AS}} will print a warning message. If the value is less
+than 500, @code{@value{AS}} will print an error message. The message will
+include the value of @var{expression}. This can occasionally be useful inside
+complex nested macros or conditional assembly.
+
+@ifclear no-file-dir
+@node File
+@section @code{.file @var{string}}
+
+@cindex @code{file} directive
+@cindex logical file name
+@cindex file name, logical
+@code{.file} tells @code{@value{AS}} that we are about to start a new logical
+file. @var{string} is the new file name. In general, the filename is
+recognized whether or not it is surrounded by quotes @samp{"}; but if you wish
+to specify an empty file name, you must give the quotes--@code{""}. This
+statement may go away in future: it is only recognized to be compatible with
+old @code{@value{AS}} programs.
+@ifset A29K
+In some configurations of @code{@value{AS}}, @code{.file} has already been
+removed to avoid conflicts with other assemblers. @xref{Machine Dependencies}.
+@end ifset
+@end ifclear
+
+@node Fill
+@section @code{.fill @var{repeat} , @var{size} , @var{value}}
+
+@cindex @code{fill} directive
+@cindex writing patterns in memory
+@cindex patterns, writing in memory
+@var{result}, @var{size} and @var{value} are absolute expressions.
+This emits @var{repeat} copies of @var{size} bytes. @var{Repeat}
+may be zero or more. @var{Size} may be zero or more, but if it is
+more than 8, then it is deemed to have the value 8, compatible with
+other people's assemblers. The contents of each @var{repeat} bytes
+is taken from an 8-byte number. The highest order 4 bytes are
+zero. The lowest order 4 bytes are @var{value} rendered in the
+byte-order of an integer on the computer @code{@value{AS}} is assembling for.
+Each @var{size} bytes in a repetition is taken from the lowest order
+@var{size} bytes of this number. Again, this bizarre behavior is
+compatible with other people's assemblers.
+
+@var{size} and @var{value} are optional.
+If the second comma and @var{value} are absent, @var{value} is
+assumed zero. If the first comma and following tokens are absent,
+@var{size} is assumed to be 1.
+
+@node Float
+@section @code{.float @var{flonums}}
+
+@cindex floating point numbers (single)
+@cindex @code{float} directive
+This directive assembles zero or more flonums, separated by commas. It
+has the same effect as @code{.single}.
+@ifset GENERIC
+The exact kind of floating point numbers emitted depends on how
+@code{@value{AS}} is configured.
+@xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset IEEEFLOAT
+On the @value{TARGET} family, @code{.float} emits 32-bit floating point numbers
+in @sc{ieee} format.
+@end ifset
+@end ifclear
+
+@node Func
+@section @code{.func @var{name}[,@var{label}]}
+@cindex @code{func} directive
+@code{.func} emits debugging information to denote function @var{name}, and
+is ignored unless the file is assembled with debugging enabled.
+Only @samp{--gstabs} is currently supported.
+@var{label} is the entry point of the function and if omitted @var{name}
+prepended with the @samp{leading char} is used.
+@samp{leading char} is usually @code{_} or nothing, depending on the target.
+All functions are currently defined to have @code{void} return type.
+The function must be terminated with @code{.endfunc}.
+
+@node Global
+@section @code{.global @var{symbol}}, @code{.globl @var{symbol}}
+
+@cindex @code{global} directive
+@cindex symbol, making visible to linker
+@code{.global} makes the symbol visible to @code{@value{LD}}. If you define
+@var{symbol} in your partial program, its value is made available to
+other partial programs that are linked with it. Otherwise,
+@var{symbol} takes its attributes from a symbol of the same name
+from another file linked into the same program.
+
+Both spellings (@samp{.globl} and @samp{.global}) are accepted, for
+compatibility with other assemblers.
+
+@ifset HPPA
+On the HPPA, @code{.global} is not always enough to make it accessible to other
+partial programs. You may need the HPPA-only @code{.EXPORT} directive as well.
+@xref{HPPA Directives,, HPPA Assembler Directives}.
+@end ifset
+
+@node hword
+@section @code{.hword @var{expressions}}
+
+@cindex @code{hword} directive
+@cindex integers, 16-bit
+@cindex numbers, 16-bit
+@cindex sixteen bit integers
+This expects zero or more @var{expressions}, and emits
+a 16 bit number for each.
+
+@ifset GENERIC
+This directive is a synonym for @samp{.short}; depending on the target
+architecture, it may also be a synonym for @samp{.word}.
+@end ifset
+@ifclear GENERIC
+@ifset W32
+This directive is a synonym for @samp{.short}.
+@end ifset
+@ifset W16
+This directive is a synonym for both @samp{.short} and @samp{.word}.
+@end ifset
+@end ifclear
+
+@node Ident
+@section @code{.ident}
+
+@cindex @code{ident} directive
+This directive is used by some assemblers to place tags in object files.
+@code{@value{AS}} simply accepts the directive for source-file
+compatibility with such assemblers, but does not actually emit anything
+for it.
+
+@node If
+@section @code{.if @var{absolute expression}}
+
+@cindex conditional assembly
+@cindex @code{if} directive
+@code{.if} marks the beginning of a section of code which is only
+considered part of the source program being assembled if the argument
+(which must be an @var{absolute expression}) is non-zero. The end of
+the conditional section of code must be marked by @code{.endif}
+(@pxref{Endif,,@code{.endif}}); optionally, you may include code for the
+alternative condition, flagged by @code{.else} (@pxref{Else,,@code{.else}}).
+
+The following variants of @code{.if} are also supported:
+@table @code
+@cindex @code{ifdef} directive
+@item .ifdef @var{symbol}
+Assembles the following section of code if the specified @var{symbol}
+has been defined.
+
+@cindex @code{ifc} directive
+@item .ifc @var{string1},@var{string2}
+Assembles the following section of code if the two strings are the same. The
+strings may be optionally quoted with single quotes. If they are not quoted,
+the first string stops at the first comma, and the second string stops at the
+end of the line. Strings which contain whitespace should be quoted. The
+string comparison is case sensitive.
+
+@cindex @code{ifeq} directive
+@item .ifeq @var{absolute expression}
+Assembles the following section of code if the argument is zero.
+
+@cindex @code{ifeqs} directive
+@item .ifeqs @var{string1},@var{string2}
+Another form of @code{.ifc}. The strings must be quoted using double quotes.
+
+@cindex @code{ifge} directive
+@item .ifge @var{absolute expression}
+Assembles the following section of code if the argument is greater than or
+equal to zero.
+
+@cindex @code{ifgt} directive
+@item .ifgt @var{absolute expression}
+Assembles the following section of code if the argument is greater than zero.
+
+@cindex @code{ifle} directive
+@item .ifle @var{absolute expression}
+Assembles the following section of code if the argument is less than or equal
+to zero.
+
+@cindex @code{iflt} directive
+@item .iflt @var{absolute expression}
+Assembles the following section of code if the argument is less than zero.
+
+@cindex @code{ifnc} directive
+@item .ifnc @var{string1},@var{string2}.
+Like @code{.ifc}, but the sense of the test is reversed: this assembles the
+following section of code if the two strings are not the same.
+
+@cindex @code{ifndef} directive
+@cindex @code{ifnotdef} directive
+@item .ifndef @var{symbol}
+@itemx .ifnotdef @var{symbol}
+Assembles the following section of code if the specified @var{symbol}
+has not been defined. Both spelling variants are equivalent.
+
+@cindex @code{ifne} directive
+@item .ifne @var{absolute expression}
+Assembles the following section of code if the argument is not equal to zero
+(in other words, this is equivalent to @code{.if}).
+
+@cindex @code{ifnes} directive
+@item .ifnes @var{string1},@var{string2}
+Like @code{.ifeqs}, but the sense of the test is reversed: this assembles the
+following section of code if the two strings are not the same.
+@end table
+
+@node Include
+@section @code{.include "@var{file}"}
+
+@cindex @code{include} directive
+@cindex supporting files, including
+@cindex files, including
+This directive provides a way to include supporting files at specified
+points in your source program. The code from @var{file} is assembled as
+if it followed the point of the @code{.include}; when the end of the
+included file is reached, assembly of the original file continues. You
+can control the search paths used with the @samp{-I} command-line option
+(@pxref{Invoking,,Command-Line Options}). Quotation marks are required
+around @var{file}.
+
+@node Int
+@section @code{.int @var{expressions}}
+
+@cindex @code{int} directive
+@cindex integers, 32-bit
+Expect zero or more @var{expressions}, of any section, separated by commas.
+For each expression, emit a number that, at run time, is the value of that
+expression. The byte order and bit size of the number depends on what kind
+of target the assembly is for.
+
+@ifclear GENERIC
+@ifset H8
+On the H8/500 and most forms of the H8/300, @code{.int} emits 16-bit
+integers. On the H8/300H and the Hitachi SH, however, @code{.int} emits
+32-bit integers.
+@end ifset
+@end ifclear
+
+@node Irp
+@section @code{.irp @var{symbol},@var{values}}@dots{}
+
+@cindex @code{irp} directive
+Evaluate a sequence of statements assigning different values to @var{symbol}.
+The sequence of statements starts at the @code{.irp} directive, and is
+terminated by an @code{.endr} directive. For each @var{value}, @var{symbol} is
+set to @var{value}, and the sequence of statements is assembled. If no
+@var{value} is listed, the sequence of statements is assembled once, with
+@var{symbol} set to the null string. To refer to @var{symbol} within the
+sequence of statements, use @var{\symbol}.
+
+For example, assembling
+
+@example
+ .irp param,1,2,3
+ move d\param,sp@@-
+ .endr
+@end example
+
+is equivalent to assembling
+
+@example
+ move d1,sp@@-
+ move d2,sp@@-
+ move d3,sp@@-
+@end example
+
+@node Irpc
+@section @code{.irpc @var{symbol},@var{values}}@dots{}
+
+@cindex @code{irpc} directive
+Evaluate a sequence of statements assigning different values to @var{symbol}.
+The sequence of statements starts at the @code{.irpc} directive, and is
+terminated by an @code{.endr} directive. For each character in @var{value},
+@var{symbol} is set to the character, and the sequence of statements is
+assembled. If no @var{value} is listed, the sequence of statements is
+assembled once, with @var{symbol} set to the null string. To refer to
+@var{symbol} within the sequence of statements, use @var{\symbol}.
+
+For example, assembling
+
+@example
+ .irpc param,123
+ move d\param,sp@@-
+ .endr
+@end example
+
+is equivalent to assembling
+
+@example
+ move d1,sp@@-
+ move d2,sp@@-
+ move d3,sp@@-
+@end example
+
+@node Lcomm
+@section @code{.lcomm @var{symbol} , @var{length}}
+
+@cindex @code{lcomm} directive
+@cindex local common symbols
+@cindex symbols, local common
+Reserve @var{length} (an absolute expression) bytes for a local common
+denoted by @var{symbol}. The section and value of @var{symbol} are
+those of the new local common. The addresses are allocated in the bss
+section, so that at run-time the bytes start off zeroed. @var{Symbol}
+is not declared global (@pxref{Global,,@code{.global}}), so is normally
+not visible to @code{@value{LD}}.
+
+@ifset GENERIC
+Some targets permit a third argument to be used with @code{.lcomm}. This
+argument specifies the desired alignment of the symbol in the bss section.
+@end ifset
+
+@ifset HPPA
+The syntax for @code{.lcomm} differs slightly on the HPPA. The syntax is
+@samp{@var{symbol} .lcomm, @var{length}}; @var{symbol} is optional.
+@end ifset
+
+@node Lflags
+@section @code{.lflags}
+
+@cindex @code{lflags} directive (ignored)
+@code{@value{AS}} accepts this directive, for compatibility with other
+assemblers, but ignores it.
+
+@ifclear no-line-dir
+@node Line
+@section @code{.line @var{line-number}}
+
+@cindex @code{line} directive
+@end ifclear
+@ifset no-line-dir
+@node Ln
+@section @code{.ln @var{line-number}}
+
+@cindex @code{ln} directive
+@end ifset
+@cindex logical line number
+@ifset aout-bout
+Change the logical line number. @var{line-number} must be an absolute
+expression. The next line has that logical line number. Therefore any other
+statements on the current line (after a statement separator character) are
+reported as on logical line number @var{line-number} @minus{} 1. One day
+@code{@value{AS}} will no longer support this directive: it is recognized only
+for compatibility with existing assembler programs.
+
+@ifset GENERIC
+@ifset A29K
+@emph{Warning:} In the AMD29K configuration of @value{AS}, this command is
+not available; use the synonym @code{.ln} in that context.
+@end ifset
+@end ifset
+@end ifset
+
+@ifclear no-line-dir
+Even though this is a directive associated with the @code{a.out} or
+@code{b.out} object-code formats, @code{@value{AS}} still recognizes it
+when producing COFF output, and treats @samp{.line} as though it
+were the COFF @samp{.ln} @emph{if} it is found outside a
+@code{.def}/@code{.endef} pair.
+
+Inside a @code{.def}, @samp{.line} is, instead, one of the directives
+used by compilers to generate auxiliary symbol information for
+debugging.
+@end ifclear
+
+@node Linkonce
+@section @code{.linkonce [@var{type}]}
+@cindex COMDAT
+@cindex @code{linkonce} directive
+@cindex common sections
+Mark the current section so that the linker only includes a single copy of it.
+This may be used to include the same section in several different object files,
+but ensure that the linker will only include it once in the final output file.
+The @code{.linkonce} pseudo-op must be used for each instance of the section.
+Duplicate sections are detected based on the section name, so it should be
+unique.
+
+This directive is only supported by a few object file formats; as of this
+writing, the only object file format which supports it is the Portable
+Executable format used on Windows NT.
+
+The @var{type} argument is optional. If specified, it must be one of the
+following strings. For example:
+@smallexample
+.linkonce same_size
+@end smallexample
+Not all types may be supported on all object file formats.
+
+@table @code
+@item discard
+Silently discard duplicate sections. This is the default.
+
+@item one_only
+Warn if there are duplicate sections, but still keep only one copy.
+
+@item same_size
+Warn if any of the duplicates have different sizes.
+
+@item same_contents
+Warn if any of the duplicates do not have exactly the same contents.
+@end table
+
+@node Ln
+@section @code{.ln @var{line-number}}
+
+@cindex @code{ln} directive
+@ifclear no-line-dir
+@samp{.ln} is a synonym for @samp{.line}.
+@end ifclear
+@ifset no-line-dir
+Tell @code{@value{AS}} to change the logical line number. @var{line-number}
+must be an absolute expression. The next line has that logical
+line number, so any other statements on the current line (after a
+statement separator character @code{;}) are reported as on logical
+line number @var{line-number} @minus{} 1.
+@ifset BOUT
+
+This directive is accepted, but ignored, when @code{@value{AS}} is
+configured for @code{b.out}; its effect is only associated with COFF
+output format.
+@end ifset
+@end ifset
+
+@node MRI
+@section @code{.mri @var{val}}
+
+@cindex @code{mri} directive
+@cindex MRI mode, temporarily
+If @var{val} is non-zero, this tells @code{@value{AS}} to enter MRI mode. If
+@var{val} is zero, this tells @code{@value{AS}} to exit MRI mode. This change
+affects code assembled until the next @code{.mri} directive, or until the end
+of the file. @xref{M, MRI mode, MRI mode}.
+
+@node List
+@section @code{.list}
+
+@cindex @code{list} directive
+@cindex listing control, turning on
+Control (in conjunction with the @code{.nolist} directive) whether or
+not assembly listings are generated. These two directives maintain an
+internal counter (which is zero initially). @code{.list} increments the
+counter, and @code{.nolist} decrements it. Assembly listings are
+generated whenever the counter is greater than zero.
+
+By default, listings are disabled. When you enable them (with the
+@samp{-a} command line option; @pxref{Invoking,,Command-Line Options}),
+the initial value of the listing counter is one.
+
+@node Long
+@section @code{.long @var{expressions}}
+
+@cindex @code{long} directive
+@code{.long} is the same as @samp{.int}, @pxref{Int,,@code{.int}}.
+
+@ignore
+@c no one seems to know what this is for or whether this description is
+@c what it really ought to do
+@node Lsym
+@section @code{.lsym @var{symbol}, @var{expression}}
+
+@cindex @code{lsym} directive
+@cindex symbol, not referenced in assembly
+@code{.lsym} creates a new symbol named @var{symbol}, but does not put it in
+the hash table, ensuring it cannot be referenced by name during the
+rest of the assembly. This sets the attributes of the symbol to be
+the same as the expression value:
+@smallexample
+@var{other} = @var{descriptor} = 0
+@var{type} = @r{(section of @var{expression})}
+@var{value} = @var{expression}
+@end smallexample
+@noindent
+The new symbol is not flagged as external.
+@end ignore
+
+@node Macro
+@section @code{.macro}
+
+@cindex macros
+The commands @code{.macro} and @code{.endm} allow you to define macros that
+generate assembly output. For example, this definition specifies a macro
+@code{sum} that puts a sequence of numbers into memory:
+
+@example
+ .macro sum from=0, to=5
+ .long \from
+ .if \to-\from
+ sum "(\from+1)",\to
+ .endif
+ .endm
+@end example
+
+@noindent
+With that definition, @samp{SUM 0,5} is equivalent to this assembly input:
+
+@example
+ .long 0
+ .long 1
+ .long 2
+ .long 3
+ .long 4
+ .long 5
+@end example
+
+@ftable @code
+@item .macro @var{macname}
+@itemx .macro @var{macname} @var{macargs} @dots{}
+@cindex @code{macro} directive
+Begin the definition of a macro called @var{macname}. If your macro
+definition requires arguments, specify their names after the macro name,
+separated by commas or spaces. You can supply a default value for any
+macro argument by following the name with @samp{=@var{deflt}}. For
+example, these are all valid @code{.macro} statements:
+
+@table @code
+@item .macro comm
+Begin the definition of a macro called @code{comm}, which takes no
+arguments.
+
+@item .macro plus1 p, p1
+@itemx .macro plus1 p p1
+Either statement begins the definition of a macro called @code{plus1},
+which takes two arguments; within the macro definition, write
+@samp{\p} or @samp{\p1} to evaluate the arguments.
+
+@item .macro reserve_str p1=0 p2
+Begin the definition of a macro called @code{reserve_str}, with two
+arguments. The first argument has a default value, but not the second.
+After the definition is complete, you can call the macro either as
+@samp{reserve_str @var{a},@var{b}} (with @samp{\p1} evaluating to
+@var{a} and @samp{\p2} evaluating to @var{b}), or as @samp{reserve_str
+,@var{b}} (with @samp{\p1} evaluating as the default, in this case
+@samp{0}, and @samp{\p2} evaluating to @var{b}).
+@end table
+
+When you call a macro, you can specify the argument values either by
+position, or by keyword. For example, @samp{sum 9,17} is equivalent to
+@samp{sum to=17, from=9}.
+
+@item .endm
+@cindex @code{endm} directive
+Mark the end of a macro definition.
+
+@item .exitm
+@cindex @code{exitm} directive
+Exit early from the current macro definition.
+
+@cindex number of macros executed
+@cindex macros, count executed
+@item \@@
+@code{@value{AS}} maintains a counter of how many macros it has
+executed in this pseudo-variable; you can copy that number to your
+output with @samp{\@@}, but @emph{only within a macro definition}.
+
+@ignore
+@item LOCAL @var{name} [ , @dots{} ]
+@emph{Warning: @code{LOCAL} is only available if you select ``alternate
+macro syntax'' with @samp{-a} or @samp{--alternate}.} @xref{Alternate,,
+Alternate macro syntax}.
+
+Generate a string replacement for each of the @var{name} arguments, and
+replace any instances of @var{name} in each macro expansion. The
+replacement string is unique in the assembly, and different for each
+separate macro expansion. @code{LOCAL} allows you to write macros that
+define symbols, without fear of conflict between separate macro expansions.
+@end ignore
+@end ftable
+
+@node Nolist
+@section @code{.nolist}
+
+@cindex @code{nolist} directive
+@cindex listing control, turning off
+Control (in conjunction with the @code{.list} directive) whether or
+not assembly listings are generated. These two directives maintain an
+internal counter (which is zero initially). @code{.list} increments the
+counter, and @code{.nolist} decrements it. Assembly listings are
+generated whenever the counter is greater than zero.
+
+@node Octa
+@section @code{.octa @var{bignums}}
+
+@c FIXME: double size emitted for "octa" on i960, others? Or warn?
+@cindex @code{octa} directive
+@cindex integer, 16-byte
+@cindex sixteen byte integer
+This directive expects zero or more bignums, separated by commas. For each
+bignum, it emits a 16-byte integer.
+
+The term ``octa'' comes from contexts in which a ``word'' is two bytes;
+hence @emph{octa}-word for 16 bytes.
+
+@node Org
+@section @code{.org @var{new-lc} , @var{fill}}
+
+@cindex @code{org} directive
+@cindex location counter, advancing
+@cindex advancing location counter
+@cindex current address, advancing
+Advance the location counter of the current section to
+@var{new-lc}. @var{new-lc} is either an absolute expression or an
+expression with the same section as the current subsection. That is,
+you can't use @code{.org} to cross sections: if @var{new-lc} has the
+wrong section, the @code{.org} directive is ignored. To be compatible
+with former assemblers, if the section of @var{new-lc} is absolute,
+@code{@value{AS}} issues a warning, then pretends the section of @var{new-lc}
+is the same as the current subsection.
+
+@code{.org} may only increase the location counter, or leave it
+unchanged; you cannot use @code{.org} to move the location counter
+backwards.
+
+@c double negative used below "not undefined" because this is a specific
+@c reference to "undefined" (as SEG_UNKNOWN is called in this manual)
+@c section. doc@cygnus.com 18feb91
+Because @code{@value{AS}} tries to assemble programs in one pass, @var{new-lc}
+may not be undefined. If you really detest this restriction we eagerly await
+a chance to share your improved assembler.
+
+Beware that the origin is relative to the start of the section, not
+to the start of the subsection. This is compatible with other
+people's assemblers.
+
+When the location counter (of the current subsection) is advanced, the
+intervening bytes are filled with @var{fill} which should be an
+absolute expression. If the comma and @var{fill} are omitted,
+@var{fill} defaults to zero.
+
+@node P2align
+@section @code{.p2align[wl] @var{abs-expr}, @var{abs-expr}, @var{abs-expr}}
+
+@cindex padding the location counter given a power of two
+@cindex @code{p2align} directive
+Pad the location counter (in the current subsection) to a particular
+storage boundary. The first expression (which must be absolute) is the
+number of low-order zero bits the location counter must have after
+advancement. For example @samp{.p2align 3} advances the location
+counter until it a multiple of 8. If the location counter is already a
+multiple of 8, no change is needed.
+
+The second expression (also absolute) gives the fill value to be stored in the
+padding bytes. It (and the comma) may be omitted. If it is omitted, the
+padding bytes are normally zero. However, on some systems, if the section is
+marked as containing code and the fill value is omitted, the space is filled
+with no-op instructions.
+
+The third expression is also absolute, and is also optional. If it is present,
+it is the maximum number of bytes that should be skipped by this alignment
+directive. If doing the alignment would require skipping more bytes than the
+specified maximum, then the alignment is not done at all. You can omit the
+fill value (the second argument) entirely by simply using two commas after the
+required alignment; this can be useful if you want the alignment to be filled
+with no-op instructions when appropriate.
+
+@cindex @code{p2alignw} directive
+@cindex @code{p2alignl} directive
+The @code{.p2alignw} and @code{.p2alignl} directives are variants of the
+@code{.p2align} directive. The @code{.p2alignw} directive treats the fill
+pattern as a two byte word value. The @code{.p2alignl} directives treats the
+fill pattern as a four byte longword value. For example, @code{.p2alignw
+2,0x368d} will align to a multiple of 4. If it skips two bytes, they will be
+filled in with the value 0x368d (the exact placement of the bytes depends upon
+the endianness of the processor). If it skips 1 or 3 bytes, the fill value is
+undefined.
+
+@node Print
+@section @code{.print @var{string}}
+
+@cindex @code{print} directive
+@code{@value{AS}} will print @var{string} on the standard output during
+assembly. You must put @var{string} in double quotes.
+
+@node Psize
+@section @code{.psize @var{lines} , @var{columns}}
+
+@cindex @code{psize} directive
+@cindex listing control: paper size
+@cindex paper size, for listings
+Use this directive to declare the number of lines---and, optionally, the
+number of columns---to use for each page, when generating listings.
+
+If you do not use @code{.psize}, listings use a default line-count
+of 60. You may omit the comma and @var{columns} specification; the
+default width is 200 columns.
+
+@code{@value{AS}} generates formfeeds whenever the specified number of
+lines is exceeded (or whenever you explicitly request one, using
+@code{.eject}).
+
+If you specify @var{lines} as @code{0}, no formfeeds are generated save
+those explicitly specified with @code{.eject}.
+
+@node Purgem
+@section @code{.purgem @var{name}}
+
+@cindex @code{purgem} directive
+Undefine the macro @var{name}, so that later uses of the string will not be
+expanded. @xref{Macro}.
+
+@node Quad
+@section @code{.quad @var{bignums}}
+
+@cindex @code{quad} directive
+@code{.quad} expects zero or more bignums, separated by commas. For
+each bignum, it emits
+@ifclear bignum-16
+an 8-byte integer. If the bignum won't fit in 8 bytes, it prints a
+warning message; and just takes the lowest order 8 bytes of the bignum.
+@cindex eight-byte integer
+@cindex integer, 8-byte
+
+The term ``quad'' comes from contexts in which a ``word'' is two bytes;
+hence @emph{quad}-word for 8 bytes.
+@end ifclear
+@ifset bignum-16
+a 16-byte integer. If the bignum won't fit in 16 bytes, it prints a
+warning message; and just takes the lowest order 16 bytes of the bignum.
+@cindex sixteen-byte integer
+@cindex integer, 16-byte
+@end ifset
+
+@node Rept
+@section @code{.rept @var{count}}
+
+@cindex @code{rept} directive
+Repeat the sequence of lines between the @code{.rept} directive and the next
+@code{.endr} directive @var{count} times.
+
+For example, assembling
+
+@example
+ .rept 3
+ .long 0
+ .endr
+@end example
+
+is equivalent to assembling
+
+@example
+ .long 0
+ .long 0
+ .long 0
+@end example
+
+@node Sbttl
+@section @code{.sbttl "@var{subheading}"}
+
+@cindex @code{sbttl} directive
+@cindex subtitles for listings
+@cindex listing control: subtitle
+Use @var{subheading} as the title (third line, immediately after the
+title line) when generating assembly listings.
+
+This directive affects subsequent pages, as well as the current page if
+it appears within ten lines of the top of a page.
+
+@ifset COFF
+@node Scl
+@section @code{.scl @var{class}}
+
+@cindex @code{scl} directive
+@cindex symbol storage class (COFF)
+@cindex COFF symbol storage class
+Set the storage-class value for a symbol. This directive may only be
+used inside a @code{.def}/@code{.endef} pair. Storage class may flag
+whether a symbol is static or external, or it may record further
+symbolic debugging information.
+@ifset BOUT
+
+The @samp{.scl} directive is primarily associated with COFF output; when
+configured to generate @code{b.out} output format, @code{@value{AS}}
+accepts this directive but ignores it.
+@end ifset
+@end ifset
+
+@node Section
+@section @code{.section @var{name}}
+
+@cindex @code{section} directive
+@cindex named section
+Use the @code{.section} directive to assemble the following code into a section
+named @var{name}.
+
+This directive is only supported for targets that actually support arbitrarily
+named sections; on @code{a.out} targets, for example, it is not accepted, even
+with a standard @code{a.out} section name.
+
+@ifset COFF
+For COFF targets, the @code{.section} directive is used in one of the following
+ways:
+@smallexample
+.section @var{name}[, "@var{flags}"]
+.section @var{name}[, @var{subsegment}]
+@end smallexample
+
+If the optional argument is quoted, it is taken as flags to use for the
+section. Each flag is a single character. The following flags are recognized:
+@table @code
+@item b
+bss section (uninitialized data)
+@item n
+section is not loaded
+@item w
+writable section
+@item d
+data section
+@item r
+read-only section
+@item x
+executable section
+@end table
+
+If no flags are specified, the default flags depend upon the section name. If
+the section name is not recognized, the default will be for the section to be
+loaded and writable.
+
+If the optional argument to the @code{.section} directive is not quoted, it is
+taken as a subsegment number (@pxref{Sub-Sections}).
+@end ifset
+
+@ifset ELF
+For ELF targets, the @code{.section} directive is used like this:
+@smallexample
+.section @var{name}[, "@var{flags}"[, @@@var{type}]]
+@end smallexample
+The optional @var{flags} argument is a quoted string which may contain any
+combintion of the following characters:
+@table @code
+@item a
+section is allocatable
+@item w
+section is writable
+@item x
+section is executable
+@end table
+
+The optional @var{type} argument may contain one of the following constants:
+@table @code
+@item @@progbits
+section contains data
+@item @@nobits
+section does not contain data (i.e., section only occupies space)
+@end table
+
+If no flags are specified, the default flags depend upon the section name. If
+the section name is not recognized, the default will be for the section to have
+none of the above flags: it will not be allocated in memory, nor writable, nor
+executable. The section will contain data.
+
+For ELF targets, the assembler supports another type of @code{.section}
+directive for compatibility with the Solaris assembler:
+@smallexample
+.section "@var{name}"[, @var{flags}...]
+@end smallexample
+Note that the section name is quoted. There may be a sequence of comma
+separated flags:
+@table @code
+@item #alloc
+section is allocatable
+@item #write
+section is writable
+@item #execinstr
+section is executable
+@end table
+@end ifset
+
+@node Set
+@section @code{.set @var{symbol}, @var{expression}}
+
+@cindex @code{set} directive
+@cindex symbol value, setting
+Set the value of @var{symbol} to @var{expression}. This
+changes @var{symbol}'s value and type to conform to
+@var{expression}. If @var{symbol} was flagged as external, it remains
+flagged (@pxref{Symbol Attributes}).
+
+You may @code{.set} a symbol many times in the same assembly.
+
+If you @code{.set} a global symbol, the value stored in the object
+file is the last value stored into it.
+
+@ifset HPPA
+The syntax for @code{set} on the HPPA is
+@samp{@var{symbol} .set @var{expression}}.
+@end ifset
+
+@node Short
+@section @code{.short @var{expressions}}
+
+@cindex @code{short} directive
+@ifset GENERIC
+@code{.short} is normally the same as @samp{.word}.
+@xref{Word,,@code{.word}}.
+
+In some configurations, however, @code{.short} and @code{.word} generate
+numbers of different lengths; @pxref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset W16
+@code{.short} is the same as @samp{.word}. @xref{Word,,@code{.word}}.
+@end ifset
+@ifset W32
+This expects zero or more @var{expressions}, and emits
+a 16 bit number for each.
+@end ifset
+@end ifclear
+
+@node Single
+@section @code{.single @var{flonums}}
+
+@cindex @code{single} directive
+@cindex floating point numbers (single)
+This directive assembles zero or more flonums, separated by commas. It
+has the same effect as @code{.float}.
+@ifset GENERIC
+The exact kind of floating point numbers emitted depends on how
+@code{@value{AS}} is configured. @xref{Machine Dependencies}.
+@end ifset
+@ifclear GENERIC
+@ifset IEEEFLOAT
+On the @value{TARGET} family, @code{.single} emits 32-bit floating point
+numbers in @sc{ieee} format.
+@end ifset
+@end ifclear
+
+@ifset COFF
+@node Size
+@section @code{.size}
+
+@cindex @code{size} directive
+This directive is generated by compilers to include auxiliary debugging
+information in the symbol table. It is only permitted inside
+@code{.def}/@code{.endef} pairs.
+@ifset BOUT
+
+@samp{.size} is only meaningful when generating COFF format output; when
+@code{@value{AS}} is generating @code{b.out}, it accepts this directive but
+ignores it.
+@end ifset
+@end ifset
+
+@node Sleb128
+@section @code{.sleb128 @var{expressions}}
+
+@cindex @code{sleb128} directive
+@var{sleb128} stands for ``signed little endian base 128.'' This is a
+compact, variable length representation of numbers used by the DWARF
+symbolic debugging format. @xref{Uleb128,@code{.uleb128}}.
+
+@ifclear no-space-dir
+@node Skip
+@section @code{.skip @var{size} , @var{fill}}
+
+@cindex @code{skip} directive
+@cindex filling memory
+This directive emits @var{size} bytes, each of value @var{fill}. Both
+@var{size} and @var{fill} are absolute expressions. If the comma and
+@var{fill} are omitted, @var{fill} is assumed to be zero. This is the same as
+@samp{.space}.
+
+@node Space
+@section @code{.space @var{size} , @var{fill}}
+
+@cindex @code{space} directive
+@cindex filling memory
+This directive emits @var{size} bytes, each of value @var{fill}. Both
+@var{size} and @var{fill} are absolute expressions. If the comma
+and @var{fill} are omitted, @var{fill} is assumed to be zero. This is the same
+as @samp{.skip}.
+
+@ifset HPPA
+@quotation
+@emph{Warning:} @code{.space} has a completely different meaning for HPPA
+targets; use @code{.block} as a substitute. See @cite{HP9000 Series 800
+Assembly Language Reference Manual} (HP 92432-90001) for the meaning of the
+@code{.space} directive. @xref{HPPA Directives,,HPPA Assembler Directives},
+for a summary.
+@end quotation
+@end ifset
+@end ifclear
+
+@ifset A29K
+@ifclear GENERIC
+@node Space
+@section @code{.space}
+@cindex @code{space} directive
+@end ifclear
+On the AMD 29K, this directive is ignored; it is accepted for
+compatibility with other AMD 29K assemblers.
+
+@quotation
+@emph{Warning:} In most versions of the @sc{gnu} assembler, the directive
+@code{.space} has the effect of @code{.block} @xref{Machine Dependencies}.
+@end quotation
+@end ifset
+
+@ifset have-stabs
+@node Stab
+@section @code{.stabd, .stabn, .stabs}
+
+@cindex symbolic debuggers, information for
+@cindex @code{stab@var{x}} directives
+There are three directives that begin @samp{.stab}.
+All emit symbols (@pxref{Symbols}), for use by symbolic debuggers.
+The symbols are not entered in the @code{@value{AS}} hash table: they
+cannot be referenced elsewhere in the source file.
+Up to five fields are required:
+
+@table @var
+@item string
+This is the symbol's name. It may contain any character except
+@samp{\000}, so is more general than ordinary symbol names. Some
+debuggers used to code arbitrarily complex structures into symbol names
+using this field.
+
+@item type
+An absolute expression. The symbol's type is set to the low 8 bits of
+this expression. Any bit pattern is permitted, but @code{@value{LD}}
+and debuggers choke on silly bit patterns.
+
+@item other
+An absolute expression. The symbol's ``other'' attribute is set to the
+low 8 bits of this expression.
+
+@item desc
+An absolute expression. The symbol's descriptor is set to the low 16
+bits of this expression.
+
+@item value
+An absolute expression which becomes the symbol's value.
+@end table
+
+If a warning is detected while reading a @code{.stabd}, @code{.stabn},
+or @code{.stabs} statement, the symbol has probably already been created;
+you get a half-formed symbol in your object file. This is
+compatible with earlier assemblers!
+
+@table @code
+@cindex @code{stabd} directive
+@item .stabd @var{type} , @var{other} , @var{desc}
+
+The ``name'' of the symbol generated is not even an empty string.
+It is a null pointer, for compatibility. Older assemblers used a
+null pointer so they didn't waste space in object files with empty
+strings.
+
+The symbol's value is set to the location counter,
+relocatably. When your program is linked, the value of this symbol
+is the address of the location counter when the @code{.stabd} was
+assembled.
+
+@cindex @code{stabn} directive
+@item .stabn @var{type} , @var{other} , @var{desc} , @var{value}
+The name of the symbol is set to the empty string @code{""}.
+
+@cindex @code{stabs} directive
+@item .stabs @var{string} , @var{type} , @var{other} , @var{desc} , @var{value}
+All five fields are specified.
+@end table
+@end ifset
+@c end have-stabs
+
+@node String
+@section @code{.string} "@var{str}"
+
+@cindex string, copying to object file
+@cindex @code{string} directive
+
+Copy the characters in @var{str} to the object file. You may specify more than
+one string to copy, separated by commas. Unless otherwise specified for a
+particular machine, the assembler marks the end of each string with a 0 byte.
+You can use any of the escape sequences described in @ref{Strings,,Strings}.
+
+@node Struct
+@section @code{.struct @var{expression}}
+
+@cindex @code{struct} directive
+Switch to the absolute section, and set the section offset to @var{expression},
+which must be an absolute expression. You might use this as follows:
+@smallexample
+ .struct 0
+field1:
+ .struct field1 + 4
+field2:
+ .struct field2 + 4
+field3:
+@end smallexample
+This would define the symbol @code{field1} to have the value 0, the symbol
+@code{field2} to have the value 4, and the symbol @code{field3} to have the
+value 8. Assembly would be left in the absolute section, and you would need to
+use a @code{.section} directive of some sort to change to some other section
+before further assembly.
+
+@ifset ELF
+@node Symver
+@section @code{.symver}
+@cindex @code{symver} directive
+@cindex symbol versioning
+@cindex versions of symbols
+Use the @code{.symver} directive to bind symbols to specific version nodes
+within a source file. This is only supported on ELF platforms, and is
+typically used when assembling files to be linked into a shared library.
+There are cases where it may make sense to use this in objects to be bound
+into an application itself so as to override a versioned symbol from a
+shared library.
+
+For ELF targets, the @code{.symver} directive is used like this:
+@smallexample
+.symver @var{name}, @var{name2@@nodename}
+@end smallexample
+In this case, the symbol @var{name} must exist and be defined within the file
+being assembled. The @code{.versym} directive effectively creates a symbol
+alias with the name @var{name2@@nodename}, and in fact the main reason that we
+just don't try and create a regular alias is that the @var{@@} character isn't
+permitted in symbol names. The @var{name2} part of the name is the actual name
+of the symbol by which it will be externally referenced. The name @var{name}
+itself is merely a name of convenience that is used so that it is possible to
+have definitions for multiple versions of a function within a single source
+file, and so that the compiler can unambiguously know which version of a
+function is being mentioned. The @var{nodename} portion of the alias should be
+the name of a node specified in the version script supplied to the linker when
+building a shared library. If you are attempting to override a versioned
+symbol from a shared library, then @var{nodename} should correspond to the
+nodename of the symbol you are trying to override.
+@end ifset
+
+@ifset COFF
+@node Tag
+@section @code{.tag @var{structname}}
+
+@cindex COFF structure debugging
+@cindex structure debugging, COFF
+@cindex @code{tag} directive
+This directive is generated by compilers to include auxiliary debugging
+information in the symbol table. It is only permitted inside
+@code{.def}/@code{.endef} pairs. Tags are used to link structure
+definitions in the symbol table with instances of those structures.
+@ifset BOUT
+
+@samp{.tag} is only used when generating COFF format output; when
+@code{@value{AS}} is generating @code{b.out}, it accepts this directive but
+ignores it.
+@end ifset
+@end ifset
+
+@node Text
+@section @code{.text @var{subsection}}
+
+@cindex @code{text} directive
+Tells @code{@value{AS}} to assemble the following statements onto the end of
+the text subsection numbered @var{subsection}, which is an absolute
+expression. If @var{subsection} is omitted, subsection number zero
+is used.
+
+@node Title
+@section @code{.title "@var{heading}"}
+
+@cindex @code{title} directive
+@cindex listing control: title line
+Use @var{heading} as the title (second line, immediately after the
+source file name and pagenumber) when generating assembly listings.
+
+This directive affects subsequent pages, as well as the current page if
+it appears within ten lines of the top of a page.
+
+@ifset COFF
+@node Type
+@section @code{.type @var{int}}
+
+@cindex COFF symbol type
+@cindex symbol type, COFF
+@cindex @code{type} directive
+This directive, permitted only within @code{.def}/@code{.endef} pairs,
+records the integer @var{int} as the type attribute of a symbol table entry.
+@ifset BOUT
+
+@samp{.type} is associated only with COFF format output; when
+@code{@value{AS}} is configured for @code{b.out} output, it accepts this
+directive but ignores it.
+@end ifset
+@end ifset
+
+@ifset COFF
+@node Val
+@section @code{.val @var{addr}}
+
+@cindex @code{val} directive
+@cindex COFF value attribute
+@cindex value attribute, COFF
+This directive, permitted only within @code{.def}/@code{.endef} pairs,
+records the address @var{addr} as the value attribute of a symbol table
+entry.
+@ifset BOUT
+
+@samp{.val} is used only for COFF output; when @code{@value{AS}} is
+configured for @code{b.out}, it accepts this directive but ignores it.
+@end ifset
+@end ifset
+
+@node Uleb128
+@section @code{.uleb128 @var{expressions}}
+
+@cindex @code{uleb128} directive
+@var{uleb128} stands for ``unsigned little endian base 128.'' This is a
+compact, variable length representation of numbers used by the DWARF
+symbolic debugging format. @xref{Sleb128,@code{.sleb128}}.
+
+@node Word
+@section @code{.word @var{expressions}}
+
+@cindex @code{word} directive
+This directive expects zero or more @var{expressions}, of any section,
+separated by commas.
+@ifclear GENERIC
+@ifset W32
+For each expression, @code{@value{AS}} emits a 32-bit number.
+@end ifset
+@ifset W16
+For each expression, @code{@value{AS}} emits a 16-bit number.
+@end ifset
+@end ifclear
+@ifset GENERIC
+
+The size of the number emitted, and its byte order,
+depend on what target computer the assembly is for.
+@end ifset
+
+@c on amd29k, i960, sparc the "special treatment to support compilers" doesn't
+@c happen---32-bit addressability, period; no long/short jumps.
+@ifset DIFF-TBL-KLUGE
+@cindex difference tables altered
+@cindex altered difference tables
+@quotation
+@emph{Warning: Special Treatment to support Compilers}
+@end quotation
+
+@ifset GENERIC
+Machines with a 32-bit address space, but that do less than 32-bit
+addressing, require the following special treatment. If the machine of
+interest to you does 32-bit addressing (or doesn't require it;
+@pxref{Machine Dependencies}), you can ignore this issue.
+
+@end ifset
+In order to assemble compiler output into something that works,
+@code{@value{AS}} occasionlly does strange things to @samp{.word} directives.
+Directives of the form @samp{.word sym1-sym2} are often emitted by
+compilers as part of jump tables. Therefore, when @code{@value{AS}} assembles a
+directive of the form @samp{.word sym1-sym2}, and the difference between
+@code{sym1} and @code{sym2} does not fit in 16 bits, @code{@value{AS}}
+creates a @dfn{secondary jump table}, immediately before the next label.
+This secondary jump table is preceded by a short-jump to the
+first byte after the secondary table. This short-jump prevents the flow
+of control from accidentally falling into the new table. Inside the
+table is a long-jump to @code{sym2}. The original @samp{.word}
+contains @code{sym1} minus the address of the long-jump to
+@code{sym2}.
+
+If there were several occurrences of @samp{.word sym1-sym2} before the
+secondary jump table, all of them are adjusted. If there was a
+@samp{.word sym3-sym4}, that also did not fit in sixteen bits, a
+long-jump to @code{sym4} is included in the secondary jump table,
+and the @code{.word} directives are adjusted to contain @code{sym3}
+minus the address of the long-jump to @code{sym4}; and so on, for as many
+entries in the original jump table as necessary.
+
+@ifset INTERNALS
+@emph{This feature may be disabled by compiling @code{@value{AS}} with the
+@samp{-DWORKING_DOT_WORD} option.} This feature is likely to confuse
+assembly language programmers.
+@end ifset
+@end ifset
+@c end DIFF-TBL-KLUGE
+
+@node Deprecated
+@section Deprecated Directives
+
+@cindex deprecated directives
+@cindex obsolescent directives
+One day these directives won't work.
+They are included for compatibility with older assemblers.
+@table @t
+@item .abort
+@item .line
+@end table
+
+@ifset GENERIC
+@node Machine Dependencies
+@chapter Machine Dependent Features
+
+@cindex machine dependencies
+The machine instruction sets are (almost by definition) different on
+each machine where @code{@value{AS}} runs. Floating point representations
+vary as well, and @code{@value{AS}} often supports a few additional
+directives or command-line options for compatibility with other
+assemblers on a particular platform. Finally, some versions of
+@code{@value{AS}} support special pseudo-instructions for branch
+optimization.
+
+This chapter discusses most of these differences, though it does not
+include details on any machine's instruction set. For details on that
+subject, see the hardware manufacturer's manual.
+
+@menu
+@ifset A29K
+* AMD29K-Dependent:: AMD 29K Dependent Features
+@end ifset
+@ifset ARC
+* ARC-Dependent:: ARC Dependent Features
+@end ifset
+@ifset ARM
+* ARM-Dependent:: ARM Dependent Features
+@end ifset
+@ifset D10V
+* D10V-Dependent:: D10V Dependent Features
+@end ifset
+@ifset D30V
+* D30V-Dependent:: D30V Dependent Features
+@end ifset
+@ifset H8/300
+* H8/300-Dependent:: Hitachi H8/300 Dependent Features
+@end ifset
+@ifset H8/500
+* H8/500-Dependent:: Hitachi H8/500 Dependent Features
+@end ifset
+@ifset HPPA
+* HPPA-Dependent:: HPPA Dependent Features
+@end ifset
+@ifset I80386
+* i386-Dependent:: Intel 80386 Dependent Features
+@end ifset
+@ifset I960
+* i960-Dependent:: Intel 80960 Dependent Features
+@end ifset
+@ifset M680X0
+* M68K-Dependent:: M680x0 Dependent Features
+@end ifset
+@ifset MIPS
+* MIPS-Dependent:: MIPS Dependent Features
+@end ifset
+@ifset SH
+* SH-Dependent:: Hitachi SH Dependent Features
+@end ifset
+@ifset SPARC
+* Sparc-Dependent:: SPARC Dependent Features
+@end ifset
+@ifset V850
+* V850-Dependent:: V850 Dependent Features
+@end ifset
+@ifset Z8000
+* Z8000-Dependent:: Z8000 Dependent Features
+@end ifset
+@ifset VAX
+* Vax-Dependent:: VAX Dependent Features
+@end ifset
+@end menu
+
+@lowersections
+@end ifset
+
+@c The following major nodes are *sections* in the GENERIC version, *chapters*
+@c in single-cpu versions. This is mainly achieved by @lowersections. There is a
+@c peculiarity: to preserve cross-references, there must be a node called
+@c "Machine Dependencies". Hence the conditional nodenames in each
+@c major node below. Node defaulting in makeinfo requires adjacency of
+@c node and sectioning commands; hence the repetition of @chapter BLAH
+@c in both conditional blocks.
+
+@ifset ARC
+@ifset GENERIC
+@page
+@node ARC-Dependent
+@chapter ARC Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter ARC Dependent Features
+@end ifclear
+
+@cindex ARC support
+@menu
+* ARC-Opts:: Options
+* ARC-Float:: Floating Point
+* ARC-Directives:: Sparc Machine Directives
+@end menu
+
+@node ARC-Opts
+@section Options
+
+@cindex options for ARC
+@cindex ARC options
+@cindex architectures, ARC
+@cindex ARC architectures
+The ARC chip family includes several successive levels (or other
+variants) of chip, using the same core instruction set, but including
+a few additional instructions at each level.
+
+By default, @code{@value{AS}} assumes the core instruction set (ARC
+base). The @code{.cpu} pseudo-op is intended to be used to select
+the variant.
+
+@table @code
+@cindex @code{-mbig-endian} option (ARC)
+@cindex @code{-mlittle-endian} option (ARC)
+@cindex ARC big-endian output
+@cindex ARC little-endian output
+@cindex big-endian output, ARC
+@cindex little-endian output, ARC
+@item -mbig-endian
+@itemx -mlittle-endian
+Any @sc{arc} configuration of @code{@value{AS}} can select big-endian or
+little-endian output at run time (unlike most other @sc{gnu} development
+tools, which must be configured for one or the other). Use
+@samp{-mbig-endian} to select big-endian output, and @samp{-mlittle-endian}
+for little-endian.
+@end table
+
+@node ARC-Float
+@section Floating Point
+
+@cindex floating point, ARC (@sc{ieee})
+@cindex ARC floating point (@sc{ieee})
+The ARC cpu family currently does not have hardware floating point
+support. Software floating point support is provided by @code{GCC}
+and uses @sc{ieee} floating-point numbers.
+
+@node ARC-Directives
+@section ARC Machine Directives
+
+@cindex ARC machine directives
+@cindex machine directives, ARC
+The ARC version of @code{@value{AS}} supports the following additional
+machine directives:
+
+@table @code
+@item .cpu
+@cindex @code{cpu} directive, SPARC
+This must be followed by the desired cpu.
+The ARC is intended to be customizable, @code{.cpu} is used to
+select the desired variant [though currently there are none].
+
+@end table
+
+@end ifset
+
+@ifset A29K
+@include c-a29k.texi
+@end ifset
+
+@ifset ARM
+@include c-arm.texi
+@end ifset
+
+@ifset Hitachi-all
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Machine Dependent Features
+
+The machine instruction sets are different on each Hitachi chip family,
+and there are also some syntax differences among the families. This
+chapter describes the specific @code{@value{AS}} features for each
+family.
+
+@menu
+* H8/300-Dependent:: Hitachi H8/300 Dependent Features
+* H8/500-Dependent:: Hitachi H8/500 Dependent Features
+* SH-Dependent:: Hitachi SH Dependent Features
+@end menu
+@lowersections
+@end ifclear
+@end ifset
+
+@ifset D10V
+@include c-d10v.texi
+@end ifset
+
+@ifset D30V
+@include c-d30v.texi
+@end ifset
+
+@ifset H8/300
+@include c-h8300.texi
+@end ifset
+
+@ifset H8/500
+@include c-h8500.texi
+@end ifset
+
+@ifset HPPA
+@include c-hppa.texi
+@end ifset
+
+@ifset I80386
+@include c-i386.texi
+@end ifset
+
+@ifset I960
+@include c-i960.texi
+@end ifset
+
+
+@ifset M680X0
+@include c-m68k.texi
+@end ifset
+
+@ifset MIPS
+@include c-mips.texi
+@end ifset
+
+@ifset NS32K
+@include c-ns32k.texi
+@end ifset
+
+@ifset SH
+@include c-sh.texi
+@end ifset
+
+@ifset SPARC
+@include c-sparc.texi
+@end ifset
+
+@ifset Z8000
+@include c-z8k.texi
+@end ifset
+
+@ifset VAX
+@include c-vax.texi
+@end ifset
+
+@ifset V850
+@include c-v850.texi
+@end ifset
+
+@ifset GENERIC
+@c reverse effect of @down at top of generic Machine-Dep chapter
+@raisesections
+@end ifset
+
+@node Reporting Bugs
+@chapter Reporting Bugs
+@cindex bugs in assembler
+@cindex reporting bugs in assembler
+
+Your bug reports play an essential role in making @code{@value{AS}} reliable.
+
+Reporting a bug may help you by bringing a solution to your problem, or it may
+not. But in any case the principal function of a bug report is to help the
+entire community by making the next version of @code{@value{AS}} work better.
+Bug reports are your contribution to the maintenance of @code{@value{AS}}.
+
+In order for a bug report to serve its purpose, you must include the
+information that enables us to fix the bug.
+
+@menu
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+@end menu
+
+@node Bug Criteria
+@section Have you found a bug?
+@cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+@itemize @bullet
+@cindex fatal signal
+@cindex assembler crash
+@cindex crash of assembler
+@item
+If the assembler gets a fatal signal, for any input whatever, that is a
+@code{@value{AS}} bug. Reliable assemblers never crash.
+
+@cindex error on valid input
+@item
+If @code{@value{AS}} produces an error message for valid input, that is a bug.
+
+@cindex invalid input
+@item
+If @code{@value{AS}} does not produce an error message for invalid input, that
+is a bug. However, you should note that your idea of ``invalid input'' might
+be our idea of ``an extension'' or ``support for traditional practice''.
+
+@item
+If you are an experienced user of assemblers, your suggestions for improvement
+of @code{@value{AS}} are welcome in any case.
+@end itemize
+
+@node Bug Reporting
+@section How to report bugs
+@cindex bug reports
+@cindex assembler bugs, reporting
+
+A number of companies and individuals offer support for @sc{gnu} products. If
+you obtained @code{@value{AS}} from a support organization, we recommend you
+contact that organization first.
+
+You can find contact information for many support companies and
+individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
+distribution.
+
+In any event, we also recommend that you send bug reports for @code{@value{AS}}
+to @samp{bug-gnu-utils@@gnu.org}.
+
+The fundamental principle of reporting bugs usefully is this:
+@strong{report all the facts}. If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the problem
+and assume that some details do not matter. Thus, you might assume that the
+name of a symbol you use in an example does not matter. Well, probably it does
+not, but one cannot be sure. Perhaps the bug is a stray memory reference which
+happens to fetch from the location where that name is stored in memory;
+perhaps, if the name were different, the contents of that location would fool
+the assembler into doing the right thing despite the bug. Play it safe and
+give a specific, complete example. That is the easiest thing for you to do,
+and the most helpful.
+
+Keep in mind that the purpose of a bug report is to enable us to fix the bug if
+it is new to us. Therefore, always write your bug reports on the assumption
+that the bug has not been reported previously.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?'' Those bug reports are useless, and we urge everyone to
+@emph{refuse to respond to them} except to chide the sender to report
+bugs properly.
+
+To enable us to fix the bug, you should include all these things:
+
+@itemize @bullet
+@item
+The version of @code{@value{AS}}. @code{@value{AS}} announces it if you start
+it with the @samp{--version} argument.
+
+Without this, we will not know whether there is any point in looking for
+the bug in the current version of @code{@value{AS}}.
+
+@item
+Any patches you may have applied to the @code{@value{AS}} source.
+
+@item
+The type of machine you are using, and the operating system name and
+version number.
+
+@item
+What compiler (and its version) was used to compile @code{@value{AS}}---e.g.
+``@code{gcc-2.7}''.
+
+@item
+The command arguments you gave the assembler to assemble your example and
+observe the bug. To guarantee you will not omit something important, list them
+all. A copy of the Makefile (or the output from make) is sufficient.
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we might not encounter the bug.
+
+@item
+A complete input file that will reproduce the bug. If the bug is observed when
+the assembler is invoked via a compiler, send the assembler source, not the
+high level language source. Most compilers will produce the assembler source
+when run with the @samp{-S} option. If you are using @code{@value{GCC}}, use
+the options @samp{-v --save-temps}; this will save the assembler source in a
+file with an extension of @file{.s}, and also show you exactly how
+@code{@value{AS}} is being run.
+
+@item
+A description of what behavior you observe that you believe is
+incorrect. For example, ``It gets a fatal signal.''
+
+Of course, if the bug is that @code{@value{AS}} gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might not
+notice unless it is glaringly wrong. You might as well not give us a chance to
+make a mistake.
+
+Even if the problem you experience is a fatal signal, you should still say so
+explicitly. Suppose something strange is going on, such as, your copy of
+@code{@value{AS}} is out of synch, or you have encountered a bug in the C
+library on your system. (This has happened!) Your copy might crash and ours
+would not. If you told us to expect a crash, then when ours fails to crash, we
+would know that the bug was not happening for us. If you had not told us to
+expect a crash, then we would not be able to draw any conclusion from our
+observations.
+
+@item
+If you wish to suggest changes to the @code{@value{AS}} source, send us context
+diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or @samp{-p}
+option. Always send diffs from the old file to the new file. If you even
+discuss something in the @code{@value{AS}} source, refer to it by context, not
+by line number.
+
+The line numbers in our development sources will not match those in your
+sources. Your line numbers would convey no useful information to us.
+@end itemize
+
+Here are some things that are not necessary:
+
+@itemize @bullet
+@item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating
+which changes to the input file will make the bug go away and which
+changes will not affect it.
+
+This is often time consuming and not very useful, because the way we
+will find the bug is by running a single example under the debugger
+with breakpoints, not by pure deduction from a series of examples.
+We recommend that you save your time for something else.
+
+Of course, if you can find a simpler example to report @emph{instead}
+of the original one, that is a convenience for us. Errors in the
+output will be easier to spot, running under the debugger will take
+less time, and so on.
+
+However, simplification is not vital; if you do not want to do this,
+report the bug anyway and send us the entire test case you used.
+
+@item
+A patch for the bug.
+
+A patch for the bug does help us if it is a good one. But do not omit
+the necessary information, such as the test case, on the assumption that
+a patch is all we need. We might see problems with your patch and decide
+to fix the problem another way, or we might not understand it at all.
+
+Sometimes with a program as complicated as @code{@value{AS}} it is very hard to
+construct an example that will make the program follow a certain path through
+the code. If you do not send us the example, we will not be able to construct
+one, so we will not be able to verify that the bug is fixed.
+
+And if we cannot understand what bug you are trying to fix, or why your
+patch should be an improvement, we will not install it. A test case will
+help us to understand.
+
+@item
+A guess about what the bug is or what it depends on.
+
+Such guesses are usually wrong. Even we cannot guess right about such
+things without first using the debugger to find the facts.
+@end itemize
+
+@node Acknowledgements
+@chapter Acknowledgements
+
+If you have contributed to @code{@value{AS}} and your name isn't listed here,
+it is not meant as a slight. We just don't know about it. Send mail to the
+maintainer, and we'll correct the situation. Currently
+@c (January 1994),
+the maintainer is Ken Raeburn (email address @code{raeburn@@cygnus.com}).
+
+Dean Elsner wrote the original @sc{gnu} assembler for the VAX.@footnote{Any
+more details?}
+
+Jay Fenlason maintained GAS for a while, adding support for GDB-specific debug
+information and the 68k series machines, most of the preprocessing pass, and
+extensive changes in @file{messages.c}, @file{input-file.c}, @file{write.c}.
+
+K. Richard Pixley maintained GAS for a while, adding various enhancements and
+many bug fixes, including merging support for several processors, breaking GAS
+up to handle multiple object file format back ends (including heavy rewrite,
+testing, an integration of the coff and b.out back ends), adding configuration
+including heavy testing and verification of cross assemblers and file splits
+and renaming, converted GAS to strictly ANSI C including full prototypes, added
+support for m680[34]0 and cpu32, did considerable work on i960 including a COFF
+port (including considerable amounts of reverse engineering), a SPARC opcode
+file rewrite, DECstation, rs6000, and hp300hpux host ports, updated ``know''
+assertions and made them work, much other reorganization, cleanup, and lint.
+
+Ken Raeburn wrote the high-level BFD interface code to replace most of the code
+in format-specific I/O modules.
+
+The original VMS support was contributed by David L. Kashtan. Eric Youngdale
+has done much work with it since.
+
+The Intel 80386 machine description was written by Eliot Dresselhaus.
+
+Minh Tran-Le at IntelliCorp contributed some AIX 386 support.
+
+The Motorola 88k machine description was contributed by Devon Bowen of Buffalo
+University and Torbjorn Granlund of the Swedish Institute of Computer Science.
+
+Keith Knowles at the Open Software Foundation wrote the original MIPS back end
+(@file{tc-mips.c}, @file{tc-mips.h}), and contributed Rose format support
+(which hasn't been merged in yet). Ralph Campbell worked with the MIPS code to
+support a.out format.
+
+Support for the Zilog Z8k and Hitachi H8/300 and H8/500 processors (tc-z8k,
+tc-h8300, tc-h8500), and IEEE 695 object file format (obj-ieee), was written by
+Steve Chamberlain of Cygnus Support. Steve also modified the COFF back end to
+use BFD for some low-level operations, for use with the H8/300 and AMD 29k
+targets.
+
+John Gilmore built the AMD 29000 support, added @code{.include} support, and
+simplified the configuration of which versions accept which directives. He
+updated the 68k machine description so that Motorola's opcodes always produced
+fixed-size instructions (e.g. @code{jsr}), while synthetic instructions
+remained shrinkable (@code{jbsr}). John fixed many bugs, including true tested
+cross-compilation support, and one bug in relaxation that took a week and
+required the proverbial one-bit fix.
+
+Ian Lance Taylor of Cygnus Support merged the Motorola and MIT syntax for the
+68k, completed support for some COFF targets (68k, i386 SVR3, and SCO Unix),
+added support for MIPS ECOFF and ELF targets, wrote the initial RS/6000 and
+PowerPC assembler, and made a few other minor patches.
+
+Steve Chamberlain made @code{@value{AS}} able to generate listings.
+
+Hewlett-Packard contributed support for the HP9000/300.
+
+Jeff Law wrote GAS and BFD support for the native HPPA object format (SOM)
+along with a fairly extensive HPPA testsuite (for both SOM and ELF object
+formats). This work was supported by both the Center for Software Science at
+the University of Utah and Cygnus Support.
+
+Support for ELF format files has been worked on by Mark Eichin of Cygnus
+Support (original, incomplete implementation for SPARC), Pete Hoogenboom and
+Jeff Law at the University of Utah (HPPA mainly), Michael Meissner of the Open
+Software Foundation (i386 mainly), and Ken Raeburn of Cygnus Support (sparc,
+and some initial 64-bit support).
+
+Richard Henderson rewrote the Alpha assembler. Klaus Kaempf wrote GAS and BFD
+support for openVMS/Alpha.
+
+Several engineers at Cygnus Support have also provided many small bug fixes and
+configuration enhancements.
+
+Many others have contributed large or small bugfixes and enhancements. If
+you have contributed significant work and are not mentioned on this list, and
+want to be, let us know. Some of the history has been lost; we are not
+intentionally leaving anyone out.
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
+@c Local Variables:
+@c fill-column: 79
+@c End:
diff --git a/gas/doc/c-a29k.texi b/gas/doc/c-a29k.texi
new file mode 100644
index 00000000000..4d115d807f6
--- /dev/null
+++ b/gas/doc/c-a29k.texi
@@ -0,0 +1,182 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node AMD29K-Dependent
+@chapter AMD 29K Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter AMD 29K Dependent Features
+@end ifclear
+
+@cindex AMD 29K support
+@cindex 29K support
+@menu
+* AMD29K Options:: Options
+* AMD29K Syntax:: Syntax
+* AMD29K Floating Point:: Floating Point
+* AMD29K Directives:: AMD 29K Machine Directives
+* AMD29K Opcodes:: Opcodes
+@end menu
+
+@node AMD29K Options
+@section Options
+@cindex AMD 29K options (none)
+@cindex options for AMD29K (none)
+@code{@value{AS}} has no additional command-line options for the AMD
+29K family.
+
+@node AMD29K Syntax
+@section Syntax
+@menu
+* AMD29K-Macros:: Macros
+* AMD29K-Chars:: Special Characters
+* AMD29K-Regs:: Register Names
+@end menu
+
+@node AMD29K-Macros
+@subsection Macros
+
+@cindex Macros, AMD 29K
+@cindex AMD 29K macros
+The macro syntax used on the AMD 29K is like that described in the AMD
+29K Family Macro Assembler Specification. Normal @code{@value{AS}}
+macros should still work.
+
+@node AMD29K-Chars
+@subsection Special Characters
+
+@cindex line comment character, AMD 29K
+@cindex AMD 29K line comment character
+@samp{;} is the line comment character.
+
+@cindex identifiers, AMD 29K
+@cindex AMD 29K identifiers
+The character @samp{?} is permitted in identifiers (but may not begin
+an identifier).
+
+@node AMD29K-Regs
+@subsection Register Names
+
+@cindex AMD 29K register names
+@cindex register names, AMD 29K
+General-purpose registers are represented by predefined symbols of the
+form @samp{GR@var{nnn}} (for global registers) or @samp{LR@var{nnn}}
+(for local registers), where @var{nnn} represents a number between
+@code{0} and @code{127}, written with no leading zeros. The leading
+letters may be in either upper or lower case; for example, @samp{gr13}
+and @samp{LR7} are both valid register names.
+
+You may also refer to general-purpose registers by specifying the
+register number as the result of an expression (prefixed with @samp{%%}
+to flag the expression as a register number):
+@smallexample
+%%@var{expression}
+@end smallexample
+@noindent
+---where @var{expression} must be an absolute expression evaluating to a
+number between @code{0} and @code{255}. The range [0, 127] refers to
+global registers, and the range [128, 255] to local registers.
+
+@cindex special purpose registers, AMD 29K
+@cindex AMD 29K special purpose registers
+@cindex protected registers, AMD 29K
+@cindex AMD 29K protected registers
+In addition, @code{@value{AS}} understands the following protected
+special-purpose register names for the AMD 29K family:
+
+@smallexample
+ vab chd pc0
+ ops chc pc1
+ cps rbp pc2
+ cfg tmc mmu
+ cha tmr lru
+@end smallexample
+
+These unprotected special-purpose register names are also recognized:
+@smallexample
+ ipc alu fpe
+ ipa bp inte
+ ipb fc fps
+ q cr exop
+@end smallexample
+
+@node AMD29K Floating Point
+@section Floating Point
+
+@cindex floating point, AMD 29K (@sc{ieee})
+@cindex AMD 29K floating point (@sc{ieee})
+The AMD 29K family uses @sc{ieee} floating-point numbers.
+
+@node AMD29K Directives
+@section AMD 29K Machine Directives
+
+@cindex machine directives, AMD 29K
+@cindex AMD 29K machine directives
+@table @code
+@cindex @code{block} directive, AMD 29K
+@item .block @var{size} , @var{fill}
+This directive emits @var{size} bytes, each of value @var{fill}. Both
+@var{size} and @var{fill} are absolute expressions. If the comma
+and @var{fill} are omitted, @var{fill} is assumed to be zero.
+
+In other versions of the @sc{gnu} assembler, this directive is called
+@samp{.space}.
+@end table
+
+@table @code
+@cindex @code{cputype} directive, AMD 29K
+@item .cputype
+This directive is ignored; it is accepted for compatibility with other
+AMD 29K assemblers.
+
+@cindex @code{file} directive, AMD 29K
+@item .file
+This directive is ignored; it is accepted for compatibility with other
+AMD 29K assemblers.
+
+@quotation
+@emph{Warning:} in other versions of the @sc{gnu} assembler, @code{.file} is
+used for the directive called @code{.app-file} in the AMD 29K support.
+@end quotation
+
+@cindex @code{line} directive, AMD 29K
+@item .line
+This directive is ignored; it is accepted for compatibility with other
+AMD 29K assemblers.
+
+@ignore
+@c since we're ignoring .lsym...
+@cindex @code{reg} directive, AMD 29K
+@item .reg @var{symbol}, @var{expression}
+@code{.reg} has the same effect as @code{.lsym}; @pxref{Lsym,,@code{.lsym}}.
+@end ignore
+
+@cindex @code{sect} directive, AMD 29K
+@item .sect
+This directive is ignored; it is accepted for compatibility with other
+AMD 29K assemblers.
+
+@cindex @code{use} directive, AMD 29K
+@item .use @var{section name}
+Establishes the section and subsection for the following code;
+@var{section name} may be one of @code{.text}, @code{.data},
+@code{.data1}, or @code{.lit}. With one of the first three @var{section
+name} options, @samp{.use} is equivalent to the machine directive
+@var{section name}; the remaining case, @samp{.use .lit}, is the same as
+@samp{.data 200}.
+@end table
+
+@node AMD29K Opcodes
+@section Opcodes
+
+@cindex AMD 29K opcodes
+@cindex opcodes for AMD 29K
+@code{@value{AS}} implements all the standard AMD 29K opcodes. No
+additional pseudo-instructions are needed on this family.
+
+For information on the 29K machine instruction set, see @cite{Am29000
+User's Manual}, Advanced Micro Devices, Inc.
+
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
new file mode 100644
index 00000000000..b94fb2a12f9
--- /dev/null
+++ b/gas/doc/c-arm.texi
@@ -0,0 +1,207 @@
+@c Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ifset GENERIC
+@page
+@node ARM-Dependent
+@chapter ARM Dependent Features
+@end ifset
+
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter ARM Dependent Features
+@end ifclear
+
+@cindex ARM support
+@cindex Thumb support
+@menu
+* ARM Options:: Options
+* ARM Syntax:: Syntax
+* ARM Floating Point:: Floating Point
+* ARM Directives:: ARM Machine Directives
+* ARM Opcodes:: Opcodes
+@end menu
+
+@node ARM Options
+@section Options
+@cindex ARM options (none)
+@cindex options for ARM (none)
+@table @code
+@cindex @code{-marm} command line option, ARM
+@item -marm @var{[2|250|3|6|60|600|610|620|7|7m|7d|7dm|7di|7dmi|70|700|700i|710|710c|7100|7500|7500fe|7tdmi|8|810|9|9tdmistrongarm|strongarm110|strongarm1100]}
+This option specifies the target processor. The assembler will issue an
+error message if an attempt is made to assemble an instruction which
+will not execute on the target processor.
+@cindex @code{-marmv} command line option, ARM
+@item -marmv @var{[2|2a|3|3m|4|4t]}
+This option specifies the target architecture. The assembler will issue
+an error message if an attempt is made to assemble an instruction which
+will not execute on the target architecture.
+@cindex @code{-mthumb} command line option, ARM
+@item -mthumb
+This option specifies that only Thumb instructions should be assembled.
+@cindex @code{-mall} command line option, ARM
+@item -mall
+This option specifies that any Arm or Thumb instruction should be assembled.
+@cindex @code{-mfpa} command line option, ARM
+@item -mfpa @var{[10|11]}
+This option specifies the floating point architecture in use on the
+target processor.
+@cindex @code{-mfpe-old} command line option, ARM
+@item -mfpe-old
+Do not allow the assemble of floating point multiple instructions.
+@cindex @code{-mno-fpu} command line option, ARM
+@item -mno-fpu
+Do not allow the assembly of any floating point instructions.
+@cindex @code{-mthumb-interwork} command line option, ARM
+@item -mthumb-interwork
+This option specifies that the output generated by the assembler should
+be marked as supporting interworking.
+@cindex @code{-mapcs} command line option, ARM
+@item -mapcs @var{[26|32]}
+This option specifies that the output generated by the assembler should
+be marked as supporting the indicated version of the Arm Procedure.
+Calling Standard.
+@item -mapcs-float
+This indicates the the floating point variant of the APCS should be
+used. In this variant floating point arguments are passed in FP
+registers ratehr than integer registers.
+@item -mapcs-reentrant
+This indicates that the reentrant variant of the APCS should be used.
+This variant supports position independent code.
+@cindex @code{-EB} command line option, ARM
+@item -EB
+This option specifies that the output generated by the assembler should
+be marked as being encoded for a big-endian processor.
+@cindex @code{-EL} command line option, ARM
+@item -EL
+This option specifies that the output generated by the assembler should
+be marked as being encoded for a little-endian processor.
+@cindex @code{-k} command line option, ARM
+@cindex PIC code generation for ARM
+@item -k
+This option enables the generation of PIC (position independent code).
+@item -moabi
+This indicates that the code should be assembled using the old ARM ELF
+conventions, based on a beta release release of the ARM-ELF
+specifications, rather than the default conventions which are based on
+the final release of the ARM-ELF specifications.
+@end table
+
+
+@node ARM Syntax
+@section Syntax
+@menu
+* ARM-Chars:: Special Characters
+* ARM-Regs:: Register Names
+@end menu
+
+@node ARM-Chars
+@subsection Special Characters
+
+@cindex line comment character, ARM
+@cindex ARM line comment character
+The presence of a @samp{#} and @samp{@@} on a line indicates the start of
+a comment that extends to the end of the current line.
+
+@cindex identifiers, ARM
+@cindex ARM identifiers
+*TODO* Explain about /data modifier on symbols.
+
+@node ARM-Regs
+@subsection Register Names
+
+@cindex ARM register names
+@cindex register names, ARM
+*TODO* Explain about ARM register naming, and the predefined names.
+
+@node ARM Floating Point
+@section Floating Point
+
+@cindex floating point, ARM (@sc{ieee})
+@cindex ARM floating point (@sc{ieee})
+The ARM family uses @sc{ieee} floating-point numbers.
+
+
+
+@node ARM Directives
+@section ARM Machine Directives
+
+@cindex machine directives, ARM
+@cindex ARM machine directives
+@table @code
+
+@cindex @code{req} directive, ARM
+@item @var{name} .req @var{register name}
+This creates an alias for @var{register name} called @var{name}. For
+example:
+
+@smallexample
+ foo .req r0
+@end smallexample
+
+@cindex @code{code} directive, ARM
+@item .code @var{[16|32]}
+This directive selects the instruction set being generated. The value 16
+selects Thumb, with the value 32 selecting ARM.
+
+@cindex @code{thumb} directive, ARM
+@item .thumb
+This performs the same action as @var{.code 16}.
+
+@cindex @code{arm} directive, ARM
+@item .arm
+This performs the same action as @var{.code 32}.
+
+@cindex @code{force_thumb} directive, ARM
+@item .force_thumb
+This directive forces the selection of Thumb instructions, even if the
+target processor does not support those instructions
+
+@cindex @code{thumb_func} directive, ARM
+@item .thumb_func
+This directive specifies that the following symbol is the name of a
+Thumb encoded function. This information is necessary in order to allow
+the assembler and linker to generate correct code for interworking
+between Arm and Thumb instructions and should be used even if
+interworking is not going to be performed.
+
+@cindex @code{.ltorg} directive, ARM
+@item .ltorg
+This directive causes the current contents of the literal pool to be
+dumped into the current section (which is assumed to be the .text
+section) at the current location (aligned to a word boundary).
+
+@cindex @code{.pool} directive, ARM
+@item .pool
+This is a synonym for .ltorg.
+
+@end table
+
+@node ARM Opcodes
+@section Opcodes
+
+@cindex ARM opcodes
+@cindex opcodes for ARM
+@code{@value{AS}} implements all the standard ARM opcodes.
+
+*TODO* Document the pseudo-ops (adr, nop)
+
+GAS for the ARM supports a synthetic register load instruction whoes
+syntax is:
+
+@smallexample
+ ldr <register> , = <expression>
+@end smallexample
+
+If expression evaluates to a numeric constant then a MOV or MVN
+instruction will be used in place of the LDR instruction, if the
+constant can be generated by either of these instructions. Otherwise
+the constant will be placed into the nearest literal pool (if it not
+already there) and a PC relative LDR instruction will be generated.
+
+For information on the ARM or Thumb instruction sets, see @cite{ARM
+Software Development Toolkit Reference Manual}, Advanced RISC Machines
+Ltd.
+
diff --git a/gas/doc/c-d10v.texi b/gas/doc/c-d10v.texi
new file mode 100644
index 00000000000..8d7bf88c99d
--- /dev/null
+++ b/gas/doc/c-d10v.texi
@@ -0,0 +1,250 @@
+@c Copyright (C) 1996 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node D10V-Dependent
+@chapter D10V Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter D10V Dependent Features
+@end ifclear
+
+@cindex D10V support
+@menu
+* D10V-Opts:: D10V Options
+* D10V-Syntax:: Syntax
+* D10V-Float:: Floating Point
+* D10V-Opcodes:: Opcodes
+@end menu
+
+@node D10V-Opts
+@section D10V Options
+@cindex options, D10V
+@cindex D10V options
+The Mitsubishi D10V version of @code{@value{AS}} has a few machine
+dependent options.
+
+@table @samp
+@item -O
+The D10V can often execute two sub-instructions in parallel. When this option
+is used, @code{@value{AS}} will attempt to optimize its output by detecting when
+instructions can be executed in parallel.
+@item --nowarnswap
+To optimize execution performance, @code{@value{AS}} will sometimes swap the
+order of instructions. Normally this generates a warning. When this option
+is used, no warning will be generated when instructions are swapped.
+@end table
+
+@node D10V-Syntax
+@section Syntax
+@cindex D10V syntax
+@cindex syntax, D10V
+
+The D10V syntax is based on the syntax in Mitsubishi's D10V architecture manual.
+The differences are detailed below.
+
+@menu
+* D10V-Size:: Size Modifiers
+* D10V-Subs:: Sub-Instructions
+* D10V-Chars:: Special Characters
+* D10V-Regs:: Register Names
+* D10V-Addressing:: Addressing Modes
+* D10V-Word:: @@WORD Modifier
+@end menu
+
+
+@node D10V-Size
+@subsection Size Modifiers
+@cindex D10V size modifiers
+@cindex size modifiers, D10V
+The D10V version of @code{@value{AS}} uses the instruction names in the D10V
+Architecture Manual. However, the names in the manual are sometimes ambiguous.
+There are instruction names that can assemble to a short or long form opcode.
+How does the assembler pick the correct form? @code{@value{AS}} will always pick the
+smallest form if it can. When dealing with a symbol that is not defined yet when a
+line is being assembled, it will always use the long form. If you need to force the
+assembler to use either the short or long form of the instruction, you can append
+either @samp{.s} (short) or @samp{.l} (long) to it. For example, if you are writing
+an assembly program and you want to do a branch to a symbol that is defined later
+in your program, you can write @samp{bra.s foo}.
+Objdump and GDB will always append @samp{.s} or @samp{.l} to instructions which
+have both short and long forms.
+
+@node D10V-Subs
+@subsection Sub-Instructions
+@cindex D10V sub-instructions
+@cindex sub-instructions, D10V
+The D10V assembler takes as input a series of instructions, either one-per-line,
+or in the special two-per-line format described in the next section. Some of these
+instructions will be short-form or sub-instructions. These sub-instructions can be packed
+into a single instruction. The assembler will do this automatically. It will also detect
+when it should not pack instructions. For example, when a label is defined, the next
+instruction will never be packaged with the previous one. Whenever a branch and link
+instruction is called, it will not be packaged with the next instruction so the return
+address will be valid. Nops are automatically inserted when necessary.
+
+If you do not want the assembler automatically making these decisions, you can control
+the packaging and execution type (parallel or sequential) with the special execution
+symbols described in the next section.
+
+@node D10V-Chars
+@subsection Special Characters
+@cindex line comment character, D10V
+@cindex D10V line comment character
+@samp{;} and @samp{#} are the line comment characters.
+@cindex sub-instruction ordering, D10V
+@cindex D10V sub-instruction ordering
+Sub-instructions may be executed in order, in reverse-order, or in parallel.
+Instructions listed in the standard one-per-line format will be executed sequentially.
+To specify the executing order, use the following symbols:
+@table @samp
+@item ->
+Sequential with instruction on the left first.
+@item <-
+Sequential with instruction on the right first.
+@item ||
+Parallel
+@end table
+The D10V syntax allows either one instruction per line, one instruction per line with
+the execution symbol, or two instructions per line. For example
+@table @code
+@item abs a1 -> abs r0
+Execute these sequentially. The instruction on the right is in the right
+container and is executed second.
+@item abs r0 <- abs a1
+Execute these reverse-sequentially. The instruction on the right is in the right
+container, and is executed first.
+@item ld2w r2,@@r8+ || mac a0,r0,r7
+Execute these in parallel.
+@item ld2w r2,@@r8+ ||
+@itemx mac a0,r0,r7
+Two-line format. Execute these in parallel.
+@item ld2w r2,@@r8+
+@itemx mac a0,r0,r7
+Two-line format. Execute these sequentially. Assembler will
+put them in the proper containers.
+@item ld2w r2,@@r8+ ->
+@itemx mac a0,r0,r7
+Two-line format. Execute these sequentially. Same as above but
+second instruction will always go into right container.
+@end table
+@cindex symbol names, @samp{$} in
+@cindex @code{$} in symbol names
+Since @samp{$} has no special meaning, you may use it in symbol names.
+
+@node D10V-Regs
+@subsection Register Names
+@cindex D10V registers
+@cindex registers, D10V
+You can use the predefined symbols @samp{r0} through @samp{r15} to refer to the D10V
+registers. You can also use @samp{sp} as an alias for @samp{r15}. The accumulators
+are @samp{a0} and @samp{a1}. There are special register-pair names that may
+optionally be used in opcodes that require even-numbered registers. Register names are
+not case sensitive.
+
+Register Pairs
+@table @code
+@item r0-r1
+@item r2-r3
+@item r4-r5
+@item r6-r7
+@item r8-r9
+@item r10-r11
+@item r12-r13
+@item r14-r15
+@end table
+
+The D10V also has predefined symbols for these control registers and status bits:
+@table @code
+@item psw
+Processor Status Word
+@item bpsw
+Backup Processor Status Word
+@item pc
+Program Counter
+@item bpc
+Backup Program Counter
+@item rpt_c
+Repeat Count
+@item rpt_s
+Repeat Start address
+@item rpt_e
+Repeat End address
+@item mod_s
+Modulo Start address
+@item mod_e
+Modulo End address
+@item iba
+Instruction Break Address
+@item f0
+Flag 0
+@item f1
+Flag 1
+@item c
+Carry flag
+@end table
+
+@node D10V-Addressing
+@subsection Addressing Modes
+@cindex addressing modes, D10V
+@cindex D10V addressing modes
+@code{@value{AS}} understands the following addressing modes for the D10V.
+@code{R@var{n}} in the following refers to any of the numbered
+registers, but @emph{not} the control registers.
+@table @code
+@item R@var{n}
+Register direct
+@item @@R@var{n}
+Register indirect
+@item @@R@var{n}+
+Register indirect with post-increment
+@item @@R@var{n}-
+Register indirect with post-decrement
+@item @@-SP
+Register indirect with pre-decrement
+@item @@(@var{disp}, R@var{n})
+Register indirect with displacement
+@item @var{addr}
+PC relative address (for branch or rep).
+@item #@var{imm}
+Immediate data (the @samp{#} is optional and ignored)
+@end table
+
+@node D10V-Word
+@subsection @@WORD Modifier
+@cindex D10V @@word modifier
+@cindex @@word modifier, D10V
+Any symbol followed by @code{@@word} will be replaced by the symbol's value
+shifted right by 2. This is used in situations such as loading a register
+with the address of a function (or any other code fragment). For example, if
+you want to load a register with the location of the function @code{main} then
+jump to that function, you could do it as follws:
+@smallexample
+@group
+ldi r2, main@@word
+jmp r2
+@end group
+@end smallexample
+
+@node D10V-Float
+@section Floating Point
+@cindex floating point, D10V
+@cindex D10V floating point
+The D10V has no hardware floating point, but the @code{.float} and @code{.double}
+directives generates @sc{ieee} floating-point numbers for compatibility
+with other development tools.
+
+@node D10V-Opcodes
+@section Opcodes
+@cindex D10V opcode summary
+@cindex opcode summary, D10V
+@cindex mnemonics, D10V
+@cindex instruction summary, D10V
+For detailed information on the D10V machine instruction set, see
+@cite{D10V Architecture: A VLIW Microprocessor for Multimedia Applications}
+(Mitsubishi Electric Corp.).
+@code{@value{AS}} implements all the standard D10V opcodes. The only changes are those
+described in the section on size modifiers
+
diff --git a/gas/doc/c-d30v.texi b/gas/doc/c-d30v.texi
new file mode 100644
index 00000000000..731b3441e0f
--- /dev/null
+++ b/gas/doc/c-d30v.texi
@@ -0,0 +1,292 @@
+@c Copyright (C) 1997 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node D30V-Dependent
+@chapter D30V Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter D30V Dependent Features
+@end ifclear
+
+@cindex D30V support
+@menu
+* D30V-Opts:: D30V Options
+* D30V-Syntax:: Syntax
+* D30V-Float:: Floating Point
+* D30V-Opcodes:: Opcodes
+@end menu
+
+@node D30V-Opts
+@section D30V Options
+@cindex options, D30V
+@cindex D30V options
+The Mitsubishi D30V version of @code{@value{AS}} has a few machine
+dependent options.
+
+@table @samp
+@item -O
+The D30V can often execute two sub-instructions in parallel. When this option
+is used, @code{@value{AS}} will attempt to optimize its output by detecting when
+instructions can be executed in parallel.
+
+@item -n
+When this option is used, @code{@value{AS}} will issue a warning every
+time it adds a nop instruction.
+
+@item -N
+When this option is used, @code{@value{AS}} will issue a warning if it
+needs to insert a nop after a 32-bit multiply before a load or 16-bit
+multiply instruction.
+@end table
+
+@node D30V-Syntax
+@section Syntax
+@cindex D30V syntax
+@cindex syntax, D30V
+
+The D30V syntax is based on the syntax in Mitsubishi's D30V architecture manual.
+The differences are detailed below.
+
+@menu
+* D30V-Size:: Size Modifiers
+* D30V-Subs:: Sub-Instructions
+* D30V-Chars:: Special Characters
+* D30V-Guarded:: Guarded Execution
+* D30V-Regs:: Register Names
+* D30V-Addressing:: Addressing Modes
+@end menu
+
+
+@node D30V-Size
+@subsection Size Modifiers
+@cindex D30V size modifiers
+@cindex size modifiers, D30V
+The D30V version of @code{@value{AS}} uses the instruction names in the D30V
+Architecture Manual. However, the names in the manual are sometimes ambiguous.
+There are instruction names that can assemble to a short or long form opcode.
+How does the assembler pick the correct form? @code{@value{AS}} will always pick the
+smallest form if it can. When dealing with a symbol that is not defined yet when a
+line is being assembled, it will always use the long form. If you need to force the
+assembler to use either the short or long form of the instruction, you can append
+either @samp{.s} (short) or @samp{.l} (long) to it. For example, if you are writing
+an assembly program and you want to do a branch to a symbol that is defined later
+in your program, you can write @samp{bra.s foo}.
+Objdump and GDB will always append @samp{.s} or @samp{.l} to instructions which
+have both short and long forms.
+
+@node D30V-Subs
+@subsection Sub-Instructions
+@cindex D30V sub-instructions
+@cindex sub-instructions, D30V
+The D30V assembler takes as input a series of instructions, either one-per-line,
+or in the special two-per-line format described in the next section. Some of these
+instructions will be short-form or sub-instructions. These sub-instructions can be packed
+into a single instruction. The assembler will do this automatically. It will also detect
+when it should not pack instructions. For example, when a label is defined, the next
+instruction will never be packaged with the previous one. Whenever a branch and link
+instruction is called, it will not be packaged with the next instruction so the return
+address will be valid. Nops are automatically inserted when necessary.
+
+If you do not want the assembler automatically making these decisions, you can control
+the packaging and execution type (parallel or sequential) with the special execution
+symbols described in the next section.
+
+@node D30V-Chars
+@subsection Special Characters
+@cindex line comment character, D30V
+@cindex D30V line comment character
+@samp{;} and @samp{#} are the line comment characters.
+@cindex sub-instruction ordering, D30V
+@cindex D30V sub-instruction ordering
+Sub-instructions may be executed in order, in reverse-order, or in parallel.
+Instructions listed in the standard one-per-line format will be executed
+sequentially unless you use the @samp{-O} option.
+
+To specify the executing order, use the following symbols:
+@table @samp
+@item ->
+Sequential with instruction on the left first.
+
+@item <-
+Sequential with instruction on the right first.
+
+@item ||
+Parallel
+@end table
+
+The D30V syntax allows either one instruction per line, one instruction per line with
+the execution symbol, or two instructions per line. For example
+@table @code
+@item abs r2,r3 -> abs r4,r5
+Execute these sequentially. The instruction on the right is in the right
+container and is executed second.
+
+@item abs r2,r3 <- abs r4,r5
+Execute these reverse-sequentially. The instruction on the right is in the right
+container, and is executed first.
+
+@item abs r2,r3 || abs r4,r5
+Execute these in parallel.
+
+@item ldw r2,@@(r3,r4) ||
+@itemx mulx r6,r8,r9
+Two-line format. Execute these in parallel.
+
+@item mulx a0,r8,r9
+@itemx stw r2,@@(r3,r4)
+Two-line format. Execute these sequentially unless @samp{-O} option is
+used. If the @samp{-O} option is used, the assembler will determine if
+the instructions could be done in parallel (the above two instructions
+can be done in parallel), and if so, emit them as parallel instructions.
+The assembler will put them in the proper containers. In the above
+example, the assembler will put the @samp{stw} instruction in left
+container and the @samp{mulx} instruction in the right container.
+
+@item stw r2,@@(r3,r4) ->
+@itemx mulx a0,r8,r9
+Two-line format. Execute the @samp{stw} instruction followed by the
+@samp{mulx} instruction sequentially. The first instruction goes in the
+left container and the second instruction goes into right container.
+The assembler will give an error if the machine ordering constraints are
+violated.
+
+@item stw r2,@@(r3,r4) <-
+@itemx mulx a0,r8,r9
+Same as previous example, except that the @samp{mulx} instruction is
+executed before the @samp{stw} instruction.
+@end table
+
+@cindex symbol names, @samp{$} in
+@cindex @code{$} in symbol names
+Since @samp{$} has no special meaning, you may use it in symbol names.
+
+@node D30V-Guarded
+@subsection Guarded Execution
+@cindex D30V Guarded Execution
+@code{@value{AS}} supports the full range of guarded execution
+directives for each instruction. Just append the directive after the
+instruction proper. The directives are:
+
+@table @samp
+@item /tx
+Execute the instruction if flag f0 is true.
+@item /fx
+Execute the instruction if flag f0 is false.
+@item /xt
+Execute the instruction if flag f1 is true.
+@item /xf
+Execute the instruction if flag f1 is false.
+@item /tt
+Execute the instruction if both flags f0 and f1 are true.
+@item /tf
+Execute the instruction if flag f0 is true and flag f1 is false.
+@end table
+
+@node D30V-Regs
+@subsection Register Names
+@cindex D30V registers
+@cindex registers, D30V
+You can use the predefined symbols @samp{r0} through @samp{r63} to refer
+to the D30V registers. You can also use @samp{sp} as an alias for
+@samp{r63} and @samp{link} as an alias for @samp{r62}. The accumulators
+are @samp{a0} and @samp{a1}.
+
+The D30V also has predefined symbols for these control registers and status bits:
+@table @code
+@item psw
+Processor Status Word
+@item bpsw
+Backup Processor Status Word
+@item pc
+Program Counter
+@item bpc
+Backup Program Counter
+@item rpt_c
+Repeat Count
+@item rpt_s
+Repeat Start address
+@item rpt_e
+Repeat End address
+@item mod_s
+Modulo Start address
+@item mod_e
+Modulo End address
+@item iba
+Instruction Break Address
+@item f0
+Flag 0
+@item f1
+Flag 1
+@item f2
+Flag 2
+@item f3
+Flag 3
+@item f4
+Flag 4
+@item f5
+Flag 5
+@item f6
+Flag 6
+@item f7
+Flag 7
+@item s
+Same as flag 4 (saturation flag)
+@item v
+Same as flag 5 (overflow flag)
+@item va
+Same as flag 6 (sticky overflow flag)
+@item c
+Same as flag 7 (carry/borrow flag)
+@item b
+Same as flag 7 (carry/borrow flag)
+@end table
+
+@node D30V-Addressing
+@subsection Addressing Modes
+@cindex addressing modes, D30V
+@cindex D30V addressing modes
+@code{@value{AS}} understands the following addressing modes for the D30V.
+@code{R@var{n}} in the following refers to any of the numbered
+registers, but @emph{not} the control registers.
+@table @code
+@item R@var{n}
+Register direct
+@item @@R@var{n}
+Register indirect
+@item @@R@var{n}+
+Register indirect with post-increment
+@item @@R@var{n}-
+Register indirect with post-decrement
+@item @@-SP
+Register indirect with pre-decrement
+@item @@(@var{disp}, R@var{n})
+Register indirect with displacement
+@item @var{addr}
+PC relative address (for branch or rep).
+@item #@var{imm}
+Immediate data (the @samp{#} is optional and ignored)
+@end table
+
+@node D30V-Float
+@section Floating Point
+@cindex floating point, D30V
+@cindex D30V floating point
+The D30V has no hardware floating point, but the @code{.float} and @code{.double}
+directives generates @sc{ieee} floating-point numbers for compatibility
+with other development tools.
+
+@node D30V-Opcodes
+@section Opcodes
+@cindex D30V opcode summary
+@cindex opcode summary, D30V
+@cindex mnemonics, D30V
+@cindex instruction summary, D30V
+For detailed information on the D30V machine instruction set, see
+@cite{D30V Architecture: A VLIW Microprocessor for Multimedia Applications}
+(Mitsubishi Electric Corp.).
+@code{@value{AS}} implements all the standard D30V opcodes. The only changes are those
+described in the section on size modifiers
+
diff --git a/gas/doc/c-h8300.texi b/gas/doc/c-h8300.texi
new file mode 100644
index 00000000000..a270918f92a
--- /dev/null
+++ b/gas/doc/c-h8300.texi
@@ -0,0 +1,342 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@end ifset
+@node H8/300-Dependent
+@chapter H8/300 Dependent Features
+
+@cindex H8/300 support
+@menu
+* H8/300 Options:: Options
+* H8/300 Syntax:: Syntax
+* H8/300 Floating Point:: Floating Point
+* H8/300 Directives:: H8/300 Machine Directives
+* H8/300 Opcodes:: Opcodes
+@end menu
+
+@node H8/300 Options
+@section Options
+
+@cindex H8/300 options (none)
+@cindex options, H8/300 (none)
+@code{@value{AS}} has no additional command-line options for the Hitachi
+H8/300 family.
+
+@node H8/300 Syntax
+@section Syntax
+@menu
+* H8/300-Chars:: Special Characters
+* H8/300-Regs:: Register Names
+* H8/300-Addressing:: Addressing Modes
+@end menu
+
+@node H8/300-Chars
+@subsection Special Characters
+
+@cindex line comment character, H8/300
+@cindex H8/300 line comment character
+@samp{;} is the line comment character.
+
+@cindex line separator, H8/300
+@cindex statement separator, H8/300
+@cindex H8/300 line separator
+@samp{$} can be used instead of a newline to separate statements.
+Therefore @emph{you may not use @samp{$} in symbol names} on the H8/300.
+
+@node H8/300-Regs
+@subsection Register Names
+
+@cindex H8/300 registers
+@cindex register names, H8/300
+You can use predefined symbols of the form @samp{r@var{n}h} and
+@samp{r@var{n}l} to refer to the H8/300 registers as sixteen 8-bit
+general-purpose registers. @var{n} is a digit from @samp{0} to
+@samp{7}); for instance, both @samp{r0h} and @samp{r7l} are valid
+register names.
+
+You can also use the eight predefined symbols @samp{r@var{n}} to refer
+to the H8/300 registers as 16-bit registers (you must use this form for
+addressing).
+
+On the H8/300H, you can also use the eight predefined symbols
+@samp{er@var{n}} (@samp{er0} @dots{} @samp{er7}) to refer to the 32-bit
+general purpose registers.
+
+The two control registers are called @code{pc} (program counter; a
+16-bit register, except on the H8/300H where it is 24 bits) and
+@code{ccr} (condition code register; an 8-bit register). @code{r7} is
+used as the stack pointer, and can also be called @code{sp}.
+
+@node H8/300-Addressing
+@subsection Addressing Modes
+
+@cindex addressing modes, H8/300
+@cindex H8/300 addressing modes
+@value{AS} understands the following addressing modes for the H8/300:
+@table @code
+@item r@var{n}
+Register direct
+
+@item @@r@var{n}
+Register indirect
+
+@need 1200
+@item @@(@var{d}, r@var{n})
+@itemx @@(@var{d}:16, r@var{n})
+@itemx @@(@var{d}:24, r@var{n})
+Register indirect: 16-bit or 24-bit displacement @var{d} from register
+@var{n}. (24-bit displacements are only meaningful on the H8/300H.)
+
+@item @@r@var{n}+
+Register indirect with post-increment
+
+@item @@-r@var{n}
+Register indirect with pre-decrement
+
+@item @code{@@}@var{aa}
+@itemx @code{@@}@var{aa}:8
+@itemx @code{@@}@var{aa}:16
+@itemx @code{@@}@var{aa}:24
+Absolute address @code{aa}. (The address size @samp{:24} only makes
+sense on the H8/300H.)
+
+@item #@var{xx}
+@itemx #@var{xx}:8
+@itemx #@var{xx}:16
+@itemx #@var{xx}:32
+Immediate data @var{xx}. You may specify the @samp{:8}, @samp{:16}, or
+@samp{:32} for clarity, if you wish; but @code{@value{AS}} neither
+requires this nor uses it---the data size required is taken from
+context.
+
+@item @code{@@}@code{@@}@var{aa}
+@itemx @code{@@}@code{@@}@var{aa}:8
+Memory indirect. You may specify the @samp{:8} for clarity, if you
+wish; but @code{@value{AS}} neither requires this nor uses it.
+@end table
+
+@node H8/300 Floating Point
+@section Floating Point
+
+@cindex floating point, H8/300 (@sc{ieee})
+@cindex H8/300 floating point (@sc{ieee})
+The H8/300 family has no hardware floating point, but the @code{.float}
+directive generates @sc{ieee} floating-point numbers for compatibility
+with other development tools.
+
+@page
+@node H8/300 Directives
+@section H8/300 Machine Directives
+
+@cindex H8/300 machine directives (none)
+@cindex machine directives, H8/300 (none)
+@cindex @code{word} directive, H8/300
+@cindex @code{int} directive, H8/300
+@code{@value{AS}} has only one machine-dependent directive for the
+H8/300:
+
+@table @code
+@cindex H8/300H, assembling for
+@item .h8300h
+Recognize and emit additional instructions for the H8/300H variant, and
+also make @code{.int} emit 32-bit numbers rather than the usual (16-bit)
+for the H8/300 family.
+@end table
+
+On the H8/300 family (including the H8/300H) @samp{.word} directives
+generate 16-bit numbers.
+
+@node H8/300 Opcodes
+@section Opcodes
+
+@cindex H8/300 opcode summary
+@cindex opcode summary, H8/300
+@cindex mnemonics, H8/300
+@cindex instruction summary, H8/300
+For detailed information on the H8/300 machine instruction set, see
+@cite{H8/300 Series Programming Manual} (Hitachi ADE--602--025). For
+information specific to the H8/300H, see @cite{H8/300H Series
+Programming Manual} (Hitachi).
+
+@code{@value{AS}} implements all the standard H8/300 opcodes. No additional
+pseudo-instructions are needed on this family.
+
+@ifset SMALL
+@c this table, due to the multi-col faking and hardcoded order, looks silly
+@c except in smallbook. See comments below "@set SMALL" near top of this file.
+
+The following table summarizes the H8/300 opcodes, and their arguments.
+Entries marked @samp{*} are opcodes used only on the H8/300H.
+
+@smallexample
+@c Using @group seems to use the normal baselineskip, not the smallexample
+@c baselineskip; looks approx doublespaced.
+ @i{Legend:}
+ Rs @r{source register}
+ Rd @r{destination register}
+ abs @r{absolute address}
+ imm @r{immediate data}
+ disp:N @r{N-bit displacement from a register}
+ pcrel:N @r{N-bit displacement relative to program counter}
+
+ add.b #imm,rd * andc #imm,ccr
+ add.b rs,rd band #imm,rd
+ add.w rs,rd band #imm,@@rd
+* add.w #imm,rd band #imm,@@abs:8
+* add.l rs,rd bra pcrel:8
+* add.l #imm,rd * bra pcrel:16
+ adds #imm,rd bt pcrel:8
+ addx #imm,rd * bt pcrel:16
+ addx rs,rd brn pcrel:8
+ and.b #imm,rd * brn pcrel:16
+ and.b rs,rd bf pcrel:8
+* and.w rs,rd * bf pcrel:16
+* and.w #imm,rd bhi pcrel:8
+* and.l #imm,rd * bhi pcrel:16
+* and.l rs,rd bls pcrel:8
+@page
+* bls pcrel:16 bld #imm,rd
+ bcc pcrel:8 bld #imm,@@rd
+* bcc pcrel:16 bld #imm,@@abs:8
+ bhs pcrel:8 bnot #imm,rd
+* bhs pcrel:16 bnot #imm,@@rd
+ bcs pcrel:8 bnot #imm,@@abs:8
+* bcs pcrel:16 bnot rs,rd
+ blo pcrel:8 bnot rs,@@rd
+* blo pcrel:16 bnot rs,@@abs:8
+ bne pcrel:8 bor #imm,rd
+* bne pcrel:16 bor #imm,@@rd
+ beq pcrel:8 bor #imm,@@abs:8
+* beq pcrel:16 bset #imm,rd
+ bvc pcrel:8 bset #imm,@@rd
+* bvc pcrel:16 bset #imm,@@abs:8
+ bvs pcrel:8 bset rs,rd
+* bvs pcrel:16 bset rs,@@rd
+ bpl pcrel:8 bset rs,@@abs:8
+* bpl pcrel:16 bsr pcrel:8
+ bmi pcrel:8 bsr pcrel:16
+* bmi pcrel:16 bst #imm,rd
+ bge pcrel:8 bst #imm,@@rd
+* bge pcrel:16 bst #imm,@@abs:8
+ blt pcrel:8 btst #imm,rd
+* blt pcrel:16 btst #imm,@@rd
+ bgt pcrel:8 btst #imm,@@abs:8
+* bgt pcrel:16 btst rs,rd
+ ble pcrel:8 btst rs,@@rd
+* ble pcrel:16 btst rs,@@abs:8
+ bclr #imm,rd bxor #imm,rd
+ bclr #imm,@@rd bxor #imm,@@rd
+ bclr #imm,@@abs:8 bxor #imm,@@abs:8
+ bclr rs,rd cmp.b #imm,rd
+ bclr rs,@@rd cmp.b rs,rd
+ bclr rs,@@abs:8 cmp.w rs,rd
+ biand #imm,rd cmp.w rs,rd
+ biand #imm,@@rd * cmp.w #imm,rd
+ biand #imm,@@abs:8 * cmp.l #imm,rd
+ bild #imm,rd * cmp.l rs,rd
+ bild #imm,@@rd daa rs
+ bild #imm,@@abs:8 das rs
+ bior #imm,rd dec.b rs
+ bior #imm,@@rd * dec.w #imm,rd
+ bior #imm,@@abs:8 * dec.l #imm,rd
+ bist #imm,rd divxu.b rs,rd
+ bist #imm,@@rd * divxu.w rs,rd
+ bist #imm,@@abs:8 * divxs.b rs,rd
+ bixor #imm,rd * divxs.w rs,rd
+ bixor #imm,@@rd eepmov
+ bixor #imm,@@abs:8 * eepmovw
+@page
+* exts.w rd mov.w rs,@@abs:16
+* exts.l rd * mov.l #imm,rd
+* extu.w rd * mov.l rs,rd
+* extu.l rd * mov.l @@rs,rd
+ inc rs * mov.l @@(disp:16,rs),rd
+* inc.w #imm,rd * mov.l @@(disp:24,rs),rd
+* inc.l #imm,rd * mov.l @@rs+,rd
+ jmp @@rs * mov.l @@abs:16,rd
+ jmp abs * mov.l @@abs:24,rd
+ jmp @@@@abs:8 * mov.l rs,@@rd
+ jsr @@rs * mov.l rs,@@(disp:16,rd)
+ jsr abs * mov.l rs,@@(disp:24,rd)
+ jsr @@@@abs:8 * mov.l rs,@@-rd
+ ldc #imm,ccr * mov.l rs,@@abs:16
+ ldc rs,ccr * mov.l rs,@@abs:24
+* ldc @@abs:16,ccr movfpe @@abs:16,rd
+* ldc @@abs:24,ccr movtpe rs,@@abs:16
+* ldc @@(disp:16,rs),ccr mulxu.b rs,rd
+* ldc @@(disp:24,rs),ccr * mulxu.w rs,rd
+* ldc @@rs+,ccr * mulxs.b rs,rd
+* ldc @@rs,ccr * mulxs.w rs,rd
+* mov.b @@(disp:24,rs),rd neg.b rs
+* mov.b rs,@@(disp:24,rd) * neg.w rs
+ mov.b @@abs:16,rd * neg.l rs
+ mov.b rs,rd nop
+ mov.b @@abs:8,rd not.b rs
+ mov.b rs,@@abs:8 * not.w rs
+ mov.b rs,rd * not.l rs
+ mov.b #imm,rd or.b #imm,rd
+ mov.b @@rs,rd or.b rs,rd
+ mov.b @@(disp:16,rs),rd * or.w #imm,rd
+ mov.b @@rs+,rd * or.w rs,rd
+ mov.b @@abs:8,rd * or.l #imm,rd
+ mov.b rs,@@rd * or.l rs,rd
+ mov.b rs,@@(disp:16,rd) orc #imm,ccr
+ mov.b rs,@@-rd pop.w rs
+ mov.b rs,@@abs:8 * pop.l rs
+ mov.w rs,@@rd push.w rs
+* mov.w @@(disp:24,rs),rd * push.l rs
+* mov.w rs,@@(disp:24,rd) rotl.b rs
+* mov.w @@abs:24,rd * rotl.w rs
+* mov.w rs,@@abs:24 * rotl.l rs
+ mov.w rs,rd rotr.b rs
+ mov.w #imm,rd * rotr.w rs
+ mov.w @@rs,rd * rotr.l rs
+ mov.w @@(disp:16,rs),rd rotxl.b rs
+ mov.w @@rs+,rd * rotxl.w rs
+ mov.w @@abs:16,rd * rotxl.l rs
+ mov.w rs,@@(disp:16,rd) rotxr.b rs
+ mov.w rs,@@-rd * rotxr.w rs
+@page
+* rotxr.l rs * stc ccr,@@(disp:24,rd)
+ bpt * stc ccr,@@-rd
+ rte * stc ccr,@@abs:16
+ rts * stc ccr,@@abs:24
+ shal.b rs sub.b rs,rd
+* shal.w rs sub.w rs,rd
+* shal.l rs * sub.w #imm,rd
+ shar.b rs * sub.l rs,rd
+* shar.w rs * sub.l #imm,rd
+* shar.l rs subs #imm,rd
+ shll.b rs subx #imm,rd
+* shll.w rs subx rs,rd
+* shll.l rs * trapa #imm
+ shlr.b rs xor #imm,rd
+* shlr.w rs xor rs,rd
+* shlr.l rs * xor.w #imm,rd
+ sleep * xor.w rs,rd
+ stc ccr,rd * xor.l #imm,rd
+* stc ccr,@@rs * xor.l rs,rd
+* stc ccr,@@(disp:16,rd) xorc #imm,ccr
+@end smallexample
+@end ifset
+
+@cindex size suffixes, H8/300
+@cindex H8/300 size suffixes
+Four H8/300 instructions (@code{add}, @code{cmp}, @code{mov},
+@code{sub}) are defined with variants using the suffixes @samp{.b},
+@samp{.w}, and @samp{.l} to specify the size of a memory operand.
+@code{@value{AS}} supports these suffixes, but does not require them;
+since one of the operands is always a register, @code{@value{AS}} can
+deduce the correct size.
+
+For example, since @code{r0} refers to a 16-bit register,
+@example
+mov r0,@@foo
+@exdent is equivalent to
+mov.w r0,@@foo
+@end example
+
+If you use the size suffixes, @code{@value{AS}} issues a warning when
+the suffix and the register size do not match.
diff --git a/gas/doc/c-h8500.texi b/gas/doc/c-h8500.texi
new file mode 100644
index 00000000000..10f0e641538
--- /dev/null
+++ b/gas/doc/c-h8500.texi
@@ -0,0 +1,272 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@page
+@node H8/500-Dependent
+@chapter H8/500 Dependent Features
+
+@cindex H8/500 support
+@menu
+* H8/500 Options:: Options
+* H8/500 Syntax:: Syntax
+* H8/500 Floating Point:: Floating Point
+* H8/500 Directives:: H8/500 Machine Directives
+* H8/500 Opcodes:: Opcodes
+@end menu
+
+@node H8/500 Options
+@section Options
+
+@cindex H8/500 options (none)
+@cindex options, H8/500 (none)
+@code{@value{AS}} has no additional command-line options for the Hitachi
+H8/500 family.
+
+@node H8/500 Syntax
+@section Syntax
+
+@menu
+* H8/500-Chars:: Special Characters
+* H8/500-Regs:: Register Names
+* H8/500-Addressing:: Addressing Modes
+@end menu
+
+@node H8/500-Chars
+@subsection Special Characters
+
+@cindex line comment character, H8/500
+@cindex H8/500 line comment character
+@samp{!} is the line comment character.
+
+@cindex line separator, H8/500
+@cindex statement separator, H8/500
+@cindex H8/500 line separator
+@samp{;} can be used instead of a newline to separate statements.
+
+@cindex symbol names, @samp{$} in
+@cindex @code{$} in symbol names
+Since @samp{$} has no special meaning, you may use it in symbol names.
+
+@node H8/500-Regs
+@subsection Register Names
+
+@cindex H8/500 registers
+@cindex registers, H8/500
+You can use the predefined symbols @samp{r0}, @samp{r1}, @samp{r2},
+@samp{r3}, @samp{r4}, @samp{r5}, @samp{r6}, and @samp{r7} to refer to
+the H8/500 registers.
+
+The H8/500 also has these control registers:
+
+@table @code
+@item cp
+code pointer
+
+@item dp
+data pointer
+
+@item bp
+base pointer
+
+@item tp
+stack top pointer
+
+@item ep
+extra pointer
+
+@item sr
+status register
+
+@item ccr
+condition code register
+@end table
+
+All registers are 16 bits long. To represent 32 bit numbers, use two
+adjacent registers; for distant memory addresses, use one of the segment
+pointers (@code{cp} for the program counter; @code{dp} for
+@code{r0}--@code{r3}; @code{ep} for @code{r4} and @code{r5}; and
+@code{tp} for @code{r6} and @code{r7}.
+
+@node H8/500-Addressing
+@subsection Addressing Modes
+
+@cindex addressing modes, H8/500
+@cindex H8/500 addressing modes
+@value{AS} understands the following addressing modes for the H8/500:
+@table @code
+@item R@var{n}
+Register direct
+
+@item @@R@var{n}
+Register indirect
+
+@item @@(d:8, R@var{n})
+Register indirect with 8 bit signed displacement
+
+@item @@(d:16, R@var{n})
+Register indirect with 16 bit signed displacement
+
+@item @@-R@var{n}
+Register indirect with pre-decrement
+
+@item @@R@var{n}+
+Register indirect with post-increment
+
+@item @@@var{aa}:8
+8 bit absolute address
+
+@item @@@var{aa}:16
+16 bit absolute address
+
+@item #@var{xx}:8
+8 bit immediate
+
+@item #@var{xx}:16
+16 bit immediate
+@end table
+
+@node H8/500 Floating Point
+@section Floating Point
+
+@cindex floating point, H8/500 (@sc{ieee})
+@cindex H8/500 floating point (@sc{ieee})
+The H8/500 family has no hardware floating point, but the @code{.float}
+directive generates @sc{ieee} floating-point numbers for compatibility
+with other development tools.
+
+@node H8/500 Directives
+@section H8/500 Machine Directives
+
+@cindex H8/500 machine directives (none)
+@cindex machine directives, H8/500 (none)
+@cindex @code{word} directive, H8/500
+@cindex @code{int} directive, H8/500
+@code{@value{AS}} has no machine-dependent directives for the H8/500.
+However, on this platform the @samp{.int} and @samp{.word} directives
+generate 16-bit numbers.
+
+@node H8/500 Opcodes
+@section Opcodes
+
+@cindex H8/500 opcode summary
+@cindex opcode summary, H8/500
+@cindex mnemonics, H8/500
+@cindex instruction summary, H8/500
+For detailed information on the H8/500 machine instruction set, see
+@cite{H8/500 Series Programming Manual} (Hitachi M21T001).
+
+@code{@value{AS}} implements all the standard H8/500 opcodes. No additional
+pseudo-instructions are needed on this family.
+
+@ifset SMALL
+@c this table, due to the multi-col faking and hardcoded order, looks silly
+@c except in smallbook. See comments below "@set SMALL" near top of this file.
+
+The following table summarizes H8/500 opcodes and their operands:
+
+@c Use @group if it ever works, instead of @page
+@page
+@smallexample
+@i{Legend:}
+abs8 @r{8-bit absolute address}
+abs16 @r{16-bit absolute address}
+abs24 @r{24-bit absolute address}
+crb @r{@code{ccr}, @code{br}, @code{ep}, @code{dp}, @code{tp}, @code{dp}}
+disp8 @r{8-bit displacement}
+ea @r{@code{rn}, @code{@@rn}, @code{@@(d:8, rn)}, @code{@@(d:16, rn)},}
+ @r{@code{@@-rn}, @code{@@rn+}, @code{@@aa:8}, @code{@@aa:16},}
+ @r{@code{#xx:8}, @code{#xx:16}}
+ea_mem @r{@code{@@rn}, @code{@@(d:8, rn)}, @code{@@(d:16, rn)},}
+ @r{@code{@@-rn}, @code{@@rn+}, @code{@@aa:8}, @code{@@aa:16}}
+ea_noimm @r{@code{rn}, @code{@@rn}, @code{@@(d:8, rn)}, @code{@@(d:16, rn)},}
+ @r{@code{@@-rn}, @code{@@rn+}, @code{@@aa:8}, @code{@@aa:16}}
+fp r6
+imm4 @r{4-bit immediate data}
+imm8 @r{8-bit immediate data}
+imm16 @r{16-bit immediate data}
+pcrel8 @r{8-bit offset from program counter}
+pcrel16 @r{16-bit offset from program counter}
+qim @r{@code{-2}, @code{-1}, @code{1}, @code{2}}
+rd @r{any register}
+rs @r{a register distinct from rd}
+rlist @r{comma-separated list of registers in parentheses;}
+ @r{register ranges @code{rd-rs} are allowed}
+sp @r{stack pointer (@code{r7})}
+sr @r{status register}
+sz @r{size; @samp{.b} or @samp{.w}. If omitted, default @samp{.w}}
+
+ldc[.b] ea,crb bcc[.w] pcrel16
+ldc[.w] ea,sr bcc[.b] pcrel8
+add[:q] sz qim,ea_noimm bhs[.w] pcrel16
+add[:g] sz ea,rd bhs[.b] pcrel8
+adds sz ea,rd bcs[.w] pcrel16
+addx sz ea,rd bcs[.b] pcrel8
+and sz ea,rd blo[.w] pcrel16
+andc[.b] imm8,crb blo[.b] pcrel8
+andc[.w] imm16,sr bne[.w] pcrel16
+bpt bne[.b] pcrel8
+bra[.w] pcrel16 beq[.w] pcrel16
+bra[.b] pcrel8 beq[.b] pcrel8
+bt[.w] pcrel16 bvc[.w] pcrel16
+bt[.b] pcrel8 bvc[.b] pcrel8
+brn[.w] pcrel16 bvs[.w] pcrel16
+brn[.b] pcrel8 bvs[.b] pcrel8
+bf[.w] pcrel16 bpl[.w] pcrel16
+bf[.b] pcrel8 bpl[.b] pcrel8
+bhi[.w] pcrel16 bmi[.w] pcrel16
+bhi[.b] pcrel8 bmi[.b] pcrel8
+bls[.w] pcrel16 bge[.w] pcrel16
+bls[.b] pcrel8 bge[.b] pcrel8
+@page
+blt[.w] pcrel16 mov[:g][.b] imm8,ea_mem
+blt[.b] pcrel8 mov[:g][.w] imm16,ea_mem
+bgt[.w] pcrel16 movfpe[.b] ea,rd
+bgt[.b] pcrel8 movtpe[.b] rs,ea_noimm
+ble[.w] pcrel16 mulxu sz ea,rd
+ble[.b] pcrel8 neg sz ea
+bclr sz imm4,ea_noimm nop
+bclr sz rs,ea_noimm not sz ea
+bnot sz imm4,ea_noimm or sz ea,rd
+bnot sz rs,ea_noimm orc[.b] imm8,crb
+bset sz imm4,ea_noimm orc[.w] imm16,sr
+bset sz rs,ea_noimm pjmp abs24
+bsr[.b] pcrel8 pjmp @@rd
+bsr[.w] pcrel16 pjsr abs24
+btst sz imm4,ea_noimm pjsr @@rd
+btst sz rs,ea_noimm prtd imm8
+clr sz ea prtd imm16
+cmp[:e][.b] imm8,rd prts
+cmp[:i][.w] imm16,rd rotl sz ea
+cmp[:g].b imm8,ea_noimm rotr sz ea
+cmp[:g][.w] imm16,ea_noimm rotxl sz ea
+Cmp[:g] sz ea,rd rotxr sz ea
+dadd rs,rd rtd imm8
+divxu sz ea,rd rtd imm16
+dsub rs,rd rts
+exts[.b] rd scb/f rs,pcrel8
+extu[.b] rd scb/ne rs,pcrel8
+jmp @@rd scb/eq rs,pcrel8
+jmp @@(imm8,rd) shal sz ea
+jmp @@(imm16,rd) shar sz ea
+jmp abs16 shll sz ea
+jsr @@rd shlr sz ea
+jsr @@(imm8,rd) sleep
+jsr @@(imm16,rd) stc[.b] crb,ea_noimm
+jsr abs16 stc[.w] sr,ea_noimm
+ldm @@sp+,(rlist) stm (rlist),@@-sp
+link fp,imm8 sub sz ea,rd
+link fp,imm16 subs sz ea,rd
+mov[:e][.b] imm8,rd subx sz ea,rd
+mov[:i][.w] imm16,rd swap[.b] rd
+mov[:l][.w] abs8,rd tas[.b] ea
+mov[:l].b abs8,rd trapa imm4
+mov[:s][.w] rs,abs8 trap/vs
+mov[:s].b rs,abs8 tst sz ea
+mov[:f][.w] @@(disp8,fp),rd unlk fp
+mov[:f][.w] rs,@@(disp8,fp) xch[.w] rs,rd
+mov[:f].b @@(disp8,fp),rd xor sz ea,rd
+mov[:f].b rs,@@(disp8,fp) xorc.b imm8,crb
+mov[:g] sz rs,ea_mem xorc.w imm16,sr
+mov[:g] sz ea,rd
+@end smallexample
+@end ifset
diff --git a/gas/doc/c-hppa.texi b/gas/doc/c-hppa.texi
new file mode 100644
index 00000000000..5fa535fd783
--- /dev/null
+++ b/gas/doc/c-hppa.texi
@@ -0,0 +1,263 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@page
+@node HPPA-Dependent
+@chapter HPPA Dependent Features
+
+@cindex support
+@menu
+* HPPA Notes:: Notes
+* HPPA Options:: Options
+* HPPA Syntax:: Syntax
+* HPPA Floating Point:: Floating Point
+* HPPA Directives:: HPPA Machine Directives
+* HPPA Opcodes:: Opcodes
+@end menu
+
+@node HPPA Notes
+@section Notes
+As a back end for @sc{gnu} @sc{cc} @code{@value{AS}} has been throughly tested and should
+work extremely well. We have tested it only minimally on hand written assembly
+code and no one has tested it much on the assembly output from the HP
+compilers.
+
+The format of the debugging sections has changed since the original
+@code{@value{AS}} port (version 1.3X) was released; therefore,
+you must rebuild all HPPA objects and libraries with the new
+assembler so that you can debug the final executable.
+
+The HPPA @code{@value{AS}} port generates a small subset of the relocations
+available in the SOM and ELF object file formats. Additional relocation
+support will be added as it becomes necessary.
+
+@node HPPA Options
+@section Options
+@code{@value{AS}} has no machine-dependent command-line options for the HPPA.
+
+@cindex HPPA Syntax
+@node HPPA Syntax
+@section Syntax
+The assembler syntax closely follows the HPPA instruction set
+reference manual; assembler directives and general syntax closely follow the
+HPPA assembly language reference manual, with a few noteworthy differences.
+
+First, a colon may immediately follow a label definition. This is
+simply for compatibility with how most assembly language programmers
+write code.
+
+Some obscure expression parsing problems may affect hand written code which
+uses the @code{spop} instructions, or code which makes significant
+use of the @code{!} line separator.
+
+@code{@value{AS}} is much less forgiving about missing arguments and other
+similar oversights than the HP assembler. @code{@value{AS}} notifies you
+of missing arguments as syntax errors; this is regarded as a feature, not a
+bug.
+
+Finally, @code{@value{AS}} allows you to use an external symbol without
+explicitly importing the symbol. @emph{Warning:} in the future this will be
+an error for HPPA targets.
+
+Special characters for HPPA targets include:
+
+@samp{;} is the line comment character.
+
+@samp{!} can be used instead of a newline to separate statements.
+
+Since @samp{$} has no special meaning, you may use it in symbol names.
+
+@node HPPA Floating Point
+@section Floating Point
+@cindex floating point, HPPA (@sc{ieee})
+@cindex HPPA floating point (@sc{ieee})
+The HPPA family uses @sc{ieee} floating-point numbers.
+
+@node HPPA Directives
+@section HPPA Assembler Directives
+
+@code{@value{AS}} for the HPPA supports many additional directives for
+compatibility with the native assembler. This section describes them only
+briefly. For detailed information on HPPA-specific assembler directives, see
+@cite{HP9000 Series 800 Assembly Language Reference Manual} (HP 92432-90001).
+
+@cindex HPPA directives not supported
+@code{@value{AS}} does @emph{not} support the following assembler directives
+described in the HP manual:
+
+@example
+.endm .liston
+.enter .locct
+.leave .macro
+.listoff
+@end example
+
+@cindex @code{.param} on HPPA
+Beyond those implemented for compatibility, @code{@value{AS}} supports one
+additional assembler directive for the HPPA: @code{.param}. It conveys
+register argument locations for static functions. Its syntax closely follows
+the @code{.export} directive.
+
+@cindex HPPA-only directives
+These are the additional directives in @code{@value{AS}} for the HPPA:
+
+@table @code
+@item .block @var{n}
+@itemx .blockz @var{n}
+Reserve @var{n} bytes of storage, and initialize them to zero.
+
+@item .call
+Mark the beginning of a procedure call. Only the special case with @emph{no
+arguments} is allowed.
+
+@item .callinfo [ @var{param}=@var{value}, @dots{} ] [ @var{flag}, @dots{} ]
+Specify a number of parameters and flags that define the environment for a
+procedure.
+
+@var{param} may be any of @samp{frame} (frame size), @samp{entry_gr} (end of
+general register range), @samp{entry_fr} (end of float register range),
+@samp{entry_sr} (end of space register range).
+
+The values for @var{flag} are @samp{calls} or @samp{caller} (proc has
+subroutines), @samp{no_calls} (proc does not call subroutines), @samp{save_rp}
+(preserve return pointer), @samp{save_sp} (proc preserves stack pointer),
+@samp{no_unwind} (do not unwind this proc), @samp{hpux_int} (proc is interrupt
+routine).
+
+@item .code
+Assemble into the standard section called @samp{$TEXT$}, subsection
+@samp{$CODE$}.
+
+@ifset SOM
+@item .copyright "@var{string}"
+In the SOM object format, insert @var{string} into the object code, marked as a
+copyright string.
+@end ifset
+
+@ifset ELF
+@item .copyright "@var{string}"
+In the ELF object format, insert @var{string} into the object code, marked as a
+version string.
+@end ifset
+
+@item .enter
+Not yet supported; the assembler rejects programs containing this directive.
+
+@item .entry
+Mark the beginning of a procedure.
+
+@item .exit
+Mark the end of a procedure.
+
+@item .export @var{name} [ ,@var{typ} ] [ ,@var{param}=@var{r} ]
+Make a procedure @var{name} available to callers. @var{typ}, if present, must
+be one of @samp{absolute}, @samp{code} (ELF only, not SOM), @samp{data},
+@samp{entry}, @samp{data}, @samp{entry}, @samp{millicode}, @samp{plabel},
+@samp{pri_prog}, or @samp{sec_prog}.
+
+@var{param}, if present, provides either relocation information for the
+procedure arguments and result, or a privilege level. @var{param} may be
+@samp{argw@var{n}} (where @var{n} ranges from @code{0} to @code{3}, and
+indicates one of four one-word arguments); @samp{rtnval} (the procedure's
+result); or @samp{priv_lev} (privilege level). For arguments or the result,
+@var{r} specifies how to relocate, and must be one of @samp{no} (not
+relocatable), @samp{gr} (argument is in general register), @samp{fr} (in
+floating point register), or @samp{fu} (upper half of float register).
+For @samp{priv_lev}, @var{r} is an integer.
+
+@item .half @var{n}
+Define a two-byte integer constant @var{n}; synonym for the portable
+@code{@value{AS}} directive @code{.short}.
+
+@item .import @var{name} [ ,@var{typ} ]
+Converse of @code{.export}; make a procedure available to call. The arguments
+use the same conventions as the first two arguments for @code{.export}.
+
+@item .label @var{name}
+Define @var{name} as a label for the current assembly location.
+
+@item .leave
+Not yet supported; the assembler rejects programs containing this directive.
+
+@item .origin @var{lc}
+Advance location counter to @var{lc}. Synonym for the @code{@value{as}}
+portable directive @code{.org}.
+
+@item .param @var{name} [ ,@var{typ} ] [ ,@var{param}=@var{r} ]
+@c Not in HP manual; @sc{gnu} HPPA extension
+Similar to @code{.export}, but used for static procedures.
+
+@item .proc
+Use preceding the first statement of a procedure.
+
+@item .procend
+Use following the last statement of a procedure.
+
+@item @var{label} .reg @var{expr}
+@c ?? Not in HP manual (Jan 1988 vn)
+Synonym for @code{.equ}; define @var{label} with the absolute expression
+@var{expr} as its value.
+
+@item .space @var{secname} [ ,@var{params} ]
+Switch to section @var{secname}, creating a new section by that name if
+necessary. You may only use @var{params} when creating a new section, not
+when switching to an existing one. @var{secname} may identify a section by
+number rather than by name.
+
+If specified, the list @var{params} declares attributes of the section,
+identified by keywords. The keywords recognized are @samp{spnum=@var{exp}}
+(identify this section by the number @var{exp}, an absolute expression),
+@samp{sort=@var{exp}} (order sections according to this sort key when linking;
+@var{exp} is an absolute expression), @samp{unloadable} (section contains no
+loadable data), @samp{notdefined} (this section defined elsewhere), and
+@samp{private} (data in this section not available to other programs).
+
+@item .spnum @var{secnam}
+@c ?? Not in HP manual (Jan 1988)
+Allocate four bytes of storage, and initialize them with the section number of
+the section named @var{secnam}. (You can define the section number with the
+HPPA @code{.space} directive.)
+
+@cindex @code{string} directive on HPPA
+@item .string "@var{str}"
+Copy the characters in the string @var{str} to the object file.
+@xref{Strings,,Strings}, for information on escape sequences you can use in
+@code{@value{AS}} strings.
+
+@emph{Warning!} The HPPA version of @code{.string} differs from the
+usual @code{@value{AS}} definition: it does @emph{not} write a zero byte
+after copying @var{str}.
+
+@item .stringz "@var{str}"
+Like @code{.string}, but appends a zero byte after copying @var{str} to object
+file.
+
+@item .subspa @var{name} [ ,@var{params} ]
+@itemx .nsubspa @var{name} [ ,@var{params} ]
+Similar to @code{.space}, but selects a subsection @var{name} within the
+current section. You may only specify @var{params} when you create a
+subsection (in the first instance of @code{.subspa} for this @var{name}).
+
+If specified, the list @var{params} declares attributes of the subsection,
+identified by keywords. The keywords recognized are @samp{quad=@var{expr}}
+(``quadrant'' for this subsection), @samp{align=@var{expr}} (alignment for
+beginning of this subsection; a power of two), @samp{access=@var{expr}} (value
+for ``access rights'' field), @samp{sort=@var{expr}} (sorting order for this
+subspace in link), @samp{code_only} (subsection contains only code),
+@samp{unloadable} (subsection cannot be loaded into memory), @samp{common}
+(subsection is common block), @samp{dup_comm} (initialized data may have
+duplicate names), or @samp{zero} (subsection is all zeros, do not write in
+object file).
+
+@code{.nsubspa} always creates a new subspace with the given name, even
+if one with the same name already exists.
+
+@item .version "@var{str}"
+Write @var{str} as version identifier in object code.
+@end table
+
+@node HPPA Opcodes
+@section Opcodes
+For detailed information on the HPPA machine instruction set, see
+@cite{PA-RISC Architecture and Instruction Set Reference Manual}
+(HP 09740-90039).
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
new file mode 100644
index 00000000000..e27893b892e
--- /dev/null
+++ b/gas/doc/c-i386.texi
@@ -0,0 +1,518 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node i386-Dependent
+@chapter 80386 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter 80386 Dependent Features
+@end ifclear
+
+@cindex i386 support
+@cindex i80306 support
+@menu
+* i386-Options:: Options
+* i386-Syntax:: AT&T Syntax versus Intel Syntax
+* i386-Mnemonics:: Instruction Naming
+* i386-Regs:: Register Naming
+* i386-Prefixes:: Instruction Prefixes
+* i386-Memory:: Memory References
+* i386-jumps:: Handling of Jump Instructions
+* i386-Float:: Floating Point
+* i386-SIMD:: Intel's MMX and AMD's 3DNow! SIMD Operations
+* i386-16bit:: Writing 16-bit Code
+* i386-Bugs:: AT&T Syntax bugs
+* i386-Notes:: Notes
+@end menu
+
+@node i386-Options
+@section Options
+
+@cindex options for i386 (none)
+@cindex i386 options (none)
+The 80386 has no machine dependent options.
+
+@node i386-Syntax
+@section AT&T Syntax versus Intel Syntax
+
+@cindex i386 syntax compatibility
+@cindex syntax compatibility, i386
+In order to maintain compatibility with the output of @code{@value{GCC}},
+@code{@value{AS}} supports AT&T System V/386 assembler syntax. This is quite
+different from Intel syntax. We mention these differences because
+almost all 80386 documents use Intel syntax. Notable differences
+between the two syntaxes are:
+
+@cindex immediate operands, i386
+@cindex i386 immediate operands
+@cindex register operands, i386
+@cindex i386 register operands
+@cindex jump/call operands, i386
+@cindex i386 jump/call operands
+@cindex operand delimiters, i386
+@itemize @bullet
+@item
+AT&T immediate operands are preceded by @samp{$}; Intel immediate
+operands are undelimited (Intel @samp{push 4} is AT&T @samp{pushl $4}).
+AT&T register operands are preceded by @samp{%}; Intel register operands
+are undelimited. AT&T absolute (as opposed to PC relative) jump/call
+operands are prefixed by @samp{*}; they are undelimited in Intel syntax.
+
+@cindex i386 source, destination operands
+@cindex source, destination operands; i386
+@item
+AT&T and Intel syntax use the opposite order for source and destination
+operands. Intel @samp{add eax, 4} is @samp{addl $4, %eax}. The
+@samp{source, dest} convention is maintained for compatibility with
+previous Unix assemblers. Note that instructions with more than one
+source operand, such as the @samp{enter} instruction, do @emph{not} have
+reversed order. @ref{i386-Bugs}.
+
+@cindex mnemonic suffixes, i386
+@cindex sizes operands, i386
+@cindex i386 size suffixes
+@item
+In AT&T syntax the size of memory operands is determined from the last
+character of the instruction mnemonic. Mnemonic suffixes of @samp{b},
+@samp{w}, and @samp{l} specify byte (8-bit), word (16-bit), and long
+(32-bit) memory references. Intel syntax accomplishes this by prefixing
+memory operands (@emph{not} the instruction mnemonics) with @samp{byte
+ptr}, @samp{word ptr}, and @samp{dword ptr}. Thus, Intel @samp{mov al,
+byte ptr @var{foo}} is @samp{movb @var{foo}, %al} in AT&T syntax.
+
+@cindex return instructions, i386
+@cindex i386 jump, call, return
+@item
+Immediate form long jumps and calls are
+@samp{lcall/ljmp $@var{section}, $@var{offset}} in AT&T syntax; the
+Intel syntax is
+@samp{call/jmp far @var{section}:@var{offset}}. Also, the far return
+instruction
+is @samp{lret $@var{stack-adjust}} in AT&T syntax; Intel syntax is
+@samp{ret far @var{stack-adjust}}.
+
+@cindex sections, i386
+@cindex i386 sections
+@item
+The AT&T assembler does not provide support for multiple section
+programs. Unix style systems expect all programs to be single sections.
+@end itemize
+
+@node i386-Mnemonics
+@section Instruction Naming
+
+@cindex i386 instruction naming
+@cindex instruction naming, i386
+Instruction mnemonics are suffixed with one character modifiers which
+specify the size of operands. The letters @samp{b}, @samp{w}, and
+@samp{l} specify byte, word, and long operands. If no suffix is
+specified by an instruction then @code{@value{AS}} tries to fill in the
+missing suffix based on the destination register operand (the last one
+by convention). Thus, @samp{mov %ax, %bx} is equivalent to @samp{movw
+%ax, %bx}; also, @samp{mov $1, %bx} is equivalent to @samp{movw $1,
+%bx}. Note that this is incompatible with the AT&T Unix assembler which
+assumes that a missing mnemonic suffix implies long operand size. (This
+incompatibility does not affect compiler output since compilers always
+explicitly specify the mnemonic suffix.)
+
+Almost all instructions have the same names in AT&T and Intel format.
+There are a few exceptions. The sign extend and zero extend
+instructions need two sizes to specify them. They need a size to
+sign/zero extend @emph{from} and a size to zero extend @emph{to}. This
+is accomplished by using two instruction mnemonic suffixes in AT&T
+syntax. Base names for sign extend and zero extend are
+@samp{movs@dots{}} and @samp{movz@dots{}} in AT&T syntax (@samp{movsx}
+and @samp{movzx} in Intel syntax). The instruction mnemonic suffixes
+are tacked on to this base name, the @emph{from} suffix before the
+@emph{to} suffix. Thus, @samp{movsbl %al, %edx} is AT&T syntax for
+``move sign extend @emph{from} %al @emph{to} %edx.'' Possible suffixes,
+thus, are @samp{bl} (from byte to long), @samp{bw} (from byte to word),
+and @samp{wl} (from word to long).
+
+@cindex conversion instructions, i386
+@cindex i386 conversion instructions
+The Intel-syntax conversion instructions
+
+@itemize @bullet
+@item
+@samp{cbw} --- sign-extend byte in @samp{%al} to word in @samp{%ax},
+
+@item
+@samp{cwde} --- sign-extend word in @samp{%ax} to long in @samp{%eax},
+
+@item
+@samp{cwd} --- sign-extend word in @samp{%ax} to long in @samp{%dx:%ax},
+
+@item
+@samp{cdq} --- sign-extend dword in @samp{%eax} to quad in @samp{%edx:%eax},
+@end itemize
+
+@noindent
+are called @samp{cbtw}, @samp{cwtl}, @samp{cwtd}, and @samp{cltd} in
+AT&T naming. @code{@value{AS}} accepts either naming for these instructions.
+
+@cindex jump instructions, i386
+@cindex call instructions, i386
+Far call/jump instructions are @samp{lcall} and @samp{ljmp} in
+AT&T syntax, but are @samp{call far} and @samp{jump far} in Intel
+convention.
+
+@node i386-Regs
+@section Register Naming
+
+@cindex i386 registers
+@cindex registers, i386
+Register operands are always prefixed with @samp{%}. The 80386 registers
+consist of
+
+@itemize @bullet
+@item
+the 8 32-bit registers @samp{%eax} (the accumulator), @samp{%ebx},
+@samp{%ecx}, @samp{%edx}, @samp{%edi}, @samp{%esi}, @samp{%ebp} (the
+frame pointer), and @samp{%esp} (the stack pointer).
+
+@item
+the 8 16-bit low-ends of these: @samp{%ax}, @samp{%bx}, @samp{%cx},
+@samp{%dx}, @samp{%di}, @samp{%si}, @samp{%bp}, and @samp{%sp}.
+
+@item
+the 8 8-bit registers: @samp{%ah}, @samp{%al}, @samp{%bh},
+@samp{%bl}, @samp{%ch}, @samp{%cl}, @samp{%dh}, and @samp{%dl} (These
+are the high-bytes and low-bytes of @samp{%ax}, @samp{%bx},
+@samp{%cx}, and @samp{%dx})
+
+@item
+the 6 section registers @samp{%cs} (code section), @samp{%ds}
+(data section), @samp{%ss} (stack section), @samp{%es}, @samp{%fs},
+and @samp{%gs}.
+
+@item
+the 3 processor control registers @samp{%cr0}, @samp{%cr2}, and
+@samp{%cr3}.
+
+@item
+the 6 debug registers @samp{%db0}, @samp{%db1}, @samp{%db2},
+@samp{%db3}, @samp{%db6}, and @samp{%db7}.
+
+@item
+the 2 test registers @samp{%tr6} and @samp{%tr7}.
+
+@item
+the 8 floating point register stack @samp{%st} or equivalently
+@samp{%st(0)}, @samp{%st(1)}, @samp{%st(2)}, @samp{%st(3)},
+@samp{%st(4)}, @samp{%st(5)}, @samp{%st(6)}, and @samp{%st(7)}.
+@end itemize
+
+@node i386-Prefixes
+@section Instruction Prefixes
+
+@cindex i386 instruction prefixes
+@cindex instruction prefixes, i386
+@cindex prefixes, i386
+Instruction prefixes are used to modify the following instruction. They
+are used to repeat string instructions, to provide section overrides, to
+perform bus lock operations, and to change operand and address sizes.
+(Most instructions that normally operate on 32-bit operands will use
+16-bit operands if the instruction has an ``operand size'' prefix.)
+Instruction prefixes are best written on the same line as the instruction
+they act upon. For example, the @samp{scas} (scan string) instruction is
+repeated with:
+
+@smallexample
+ repne scas %es:(%edi),%al
+@end smallexample
+
+You may also place prefixes on the lines immediately preceding the
+instruction, but this circumvents checks that @code{@value{AS}} does
+with prefixes, and will not work with all prefixes.
+
+Here is a list of instruction prefixes:
+
+@cindex section override prefixes, i386
+@itemize @bullet
+@item
+Section override prefixes @samp{cs}, @samp{ds}, @samp{ss}, @samp{es},
+@samp{fs}, @samp{gs}. These are automatically added by specifying
+using the @var{section}:@var{memory-operand} form for memory references.
+
+@cindex size prefixes, i386
+@item
+Operand/Address size prefixes @samp{data16} and @samp{addr16}
+change 32-bit operands/addresses into 16-bit operands/addresses,
+while @samp{data32} and @samp{addr32} change 16-bit ones (in a
+@code{.code16} section) into 32-bit operands/addresses. These prefixes
+@emph{must} appear on the same line of code as the instruction they
+modify. For example, in a 16-bit @code{.code16} section, you might
+write:
+
+@smallexample
+ addr32 jmpl *(%ebx)
+@end smallexample
+
+@cindex bus lock prefixes, i386
+@cindex inhibiting interrupts, i386
+@item
+The bus lock prefix @samp{lock} inhibits interrupts during execution of
+the instruction it precedes. (This is only valid with certain
+instructions; see a 80386 manual for details).
+
+@cindex coprocessor wait, i386
+@item
+The wait for coprocessor prefix @samp{wait} waits for the coprocessor to
+complete the current instruction. This should never be needed for the
+80386/80387 combination.
+
+@cindex repeat prefixes, i386
+@item
+The @samp{rep}, @samp{repe}, and @samp{repne} prefixes are added
+to string instructions to make them repeat @samp{%ecx} times (@samp{%cx}
+times if the current address size is 16-bits).
+@end itemize
+
+@node i386-Memory
+@section Memory References
+
+@cindex i386 memory references
+@cindex memory references, i386
+An Intel syntax indirect memory reference of the form
+
+@smallexample
+@var{section}:[@var{base} + @var{index}*@var{scale} + @var{disp}]
+@end smallexample
+
+@noindent
+is translated into the AT&T syntax
+
+@smallexample
+@var{section}:@var{disp}(@var{base}, @var{index}, @var{scale})
+@end smallexample
+
+@noindent
+where @var{base} and @var{index} are the optional 32-bit base and
+index registers, @var{disp} is the optional displacement, and
+@var{scale}, taking the values 1, 2, 4, and 8, multiplies @var{index}
+to calculate the address of the operand. If no @var{scale} is
+specified, @var{scale} is taken to be 1. @var{section} specifies the
+optional section register for the memory operand, and may override the
+default section register (see a 80386 manual for section register
+defaults). Note that section overrides in AT&T syntax @emph{must}
+be preceded by a @samp{%}. If you specify a section override which
+coincides with the default section register, @code{@value{AS}} does @emph{not}
+output any section register override prefixes to assemble the given
+instruction. Thus, section overrides can be specified to emphasize which
+section register is used for a given memory operand.
+
+Here are some examples of Intel and AT&T style memory references:
+
+@table @asis
+@item AT&T: @samp{-4(%ebp)}, Intel: @samp{[ebp - 4]}
+@var{base} is @samp{%ebp}; @var{disp} is @samp{-4}. @var{section} is
+missing, and the default section is used (@samp{%ss} for addressing with
+@samp{%ebp} as the base register). @var{index}, @var{scale} are both missing.
+
+@item AT&T: @samp{foo(,%eax,4)}, Intel: @samp{[foo + eax*4]}
+@var{index} is @samp{%eax} (scaled by a @var{scale} 4); @var{disp} is
+@samp{foo}. All other fields are missing. The section register here
+defaults to @samp{%ds}.
+
+@item AT&T: @samp{foo(,1)}; Intel @samp{[foo]}
+This uses the value pointed to by @samp{foo} as a memory operand.
+Note that @var{base} and @var{index} are both missing, but there is only
+@emph{one} @samp{,}. This is a syntactic exception.
+
+@item AT&T: @samp{%gs:foo}; Intel @samp{gs:foo}
+This selects the contents of the variable @samp{foo} with section
+register @var{section} being @samp{%gs}.
+@end table
+
+Absolute (as opposed to PC relative) call and jump operands must be
+prefixed with @samp{*}. If no @samp{*} is specified, @code{@value{AS}}
+always chooses PC relative addressing for jump/call labels.
+
+Any instruction that has a memory operand, but no register operand,
+@emph{must} specify its size (byte, word, or long) with an instruction
+mnemonic suffix (@samp{b}, @samp{w}, or @samp{l}, respectively).
+
+@node i386-jumps
+@section Handling of Jump Instructions
+
+@cindex jump optimization, i386
+@cindex i386 jump optimization
+Jump instructions are always optimized to use the smallest possible
+displacements. This is accomplished by using byte (8-bit) displacement
+jumps whenever the target is sufficiently close. If a byte displacement
+is insufficient a long (32-bit) displacement is used. We do not support
+word (16-bit) displacement jumps in 32-bit mode (i.e. prefixing the jump
+instruction with the @samp{data16} instruction prefix), since the 80386
+insists upon masking @samp{%eip} to 16 bits after the word displacement
+is added.
+
+Note that the @samp{jcxz}, @samp{jecxz}, @samp{loop}, @samp{loopz},
+@samp{loope}, @samp{loopnz} and @samp{loopne} instructions only come in byte
+displacements, so that if you use these instructions (@code{@value{GCC}} does
+not use them) you may get an error message (and incorrect code). The AT&T
+80386 assembler tries to get around this problem by expanding @samp{jcxz foo}
+to
+
+@smallexample
+ jcxz cx_zero
+ jmp cx_nonzero
+cx_zero: jmp foo
+cx_nonzero:
+@end smallexample
+
+@node i386-Float
+@section Floating Point
+
+@cindex i386 floating point
+@cindex floating point, i386
+All 80387 floating point types except packed BCD are supported.
+(BCD support may be added without much difficulty). These data
+types are 16-, 32-, and 64- bit integers, and single (32-bit),
+double (64-bit), and extended (80-bit) precision floating point.
+Each supported type has an instruction mnemonic suffix and a constructor
+associated with it. Instruction mnemonic suffixes specify the operand's
+data type. Constructors build these data types into memory.
+
+@cindex @code{float} directive, i386
+@cindex @code{single} directive, i386
+@cindex @code{double} directive, i386
+@cindex @code{tfloat} directive, i386
+@itemize @bullet
+@item
+Floating point constructors are @samp{.float} or @samp{.single},
+@samp{.double}, and @samp{.tfloat} for 32-, 64-, and 80-bit formats.
+These correspond to instruction mnemonic suffixes @samp{s}, @samp{l},
+and @samp{t}. @samp{t} stands for 80-bit (ten byte) real. The 80387
+only supports this format via the @samp{fldt} (load 80-bit real to stack
+top) and @samp{fstpt} (store 80-bit real and pop stack) instructions.
+
+@cindex @code{word} directive, i386
+@cindex @code{long} directive, i386
+@cindex @code{int} directive, i386
+@cindex @code{quad} directive, i386
+@item
+Integer constructors are @samp{.word}, @samp{.long} or @samp{.int}, and
+@samp{.quad} for the 16-, 32-, and 64-bit integer formats. The
+corresponding instruction mnemonic suffixes are @samp{s} (single),
+@samp{l} (long), and @samp{q} (quad). As with the 80-bit real format,
+the 64-bit @samp{q} format is only present in the @samp{fildq} (load
+quad integer to stack top) and @samp{fistpq} (store quad integer and pop
+stack) instructions.
+@end itemize
+
+Register to register operations should not use instruction mnemonic suffixes.
+@samp{fstl %st, %st(1)} will give a warning, and be assembled as if you
+wrote @samp{fst %st, %st(1)}, since all register to register operations
+use 80-bit floating point operands. (Contrast this with @samp{fstl %st, mem},
+which converts @samp{%st} from 80-bit to 64-bit floating point format,
+then stores the result in the 4 byte location @samp{mem})
+
+@node i386-SIMD
+@section Intel's MMX and AMD's 3DNow! SIMD Operations
+
+@cindex MMX, i386
+@cindex 3DNow!, i386
+@cindex SIMD, i386
+
+@code{@value{AS}} supports Intel's MMX instruction set (SIMD
+instructions for integer data), available on Intel's Pentium MMX
+processors and Pentium II processors, AMD's K6 and K6-2 processors,
+Cyrix' M2 processor, and probably others. It also supports AMD's 3DNow!
+instruction set (SIMD instructions for 32-bit floating point data)
+available on AMD's K6-2 processor and possibly others in the future.
+
+Currently, @code{@value{AS}} does not support Intel's floating point
+SIMD, Katmai (KNI).
+
+The eight 64-bit MMX operands, also used by 3DNow!, are called @samp{%mm0},
+@samp{%mm1}, ... @samp{%mm7}. They contain eight 8-bit integers, four
+16-bit integers, two 32-bit integers, one 64-bit integer, or two 32-bit
+floating point values. The MMX registers cannot be used at the same time
+as the floating point stack.
+
+See Intel and AMD documentation, keeping in mind that the operand order in
+instructions is reversed from the Intel syntax.
+
+@node i386-16bit
+@section Writing 16-bit Code
+
+@cindex i386 16-bit code
+@cindex 16-bit code, i386
+@cindex real-mode code, i386
+@cindex @code{code16} directive, i386
+@cindex @code{code32} directive, i386
+While @code{@value{AS}} normally writes only ``pure'' 32-bit i386 code,
+it also supports writing code to run in real mode or in 16-bit protected
+mode code segments. To do this, put a @samp{.code16} directive before
+the assembly language instructions to be run in 16-bit mode. You can
+switch @code{@value{AS}} back to writing normal 32-bit code with the
+@samp{.code32} directive.
+
+The code which @code{@value{AS}} generates in 16-bit mode will not
+necessarily run on a 16-bit pre-80386 processor. To write code that
+runs on such a processor, you must refrain from using @emph{any} 32-bit
+constructs which require @code{@value{AS}} to output address or operand
+size prefixes.
+
+Note that writing 16-bit code instructions by explicitly specifying a
+prefix or an instruction mnemonic suffix within a 32-bit code section
+generates different machine instructions than those generated for a
+16-bit code segment. In a 32-bit code section, the following code
+generates the machine opcode bytes @samp{66 6a 04}, which pushes the
+value @samp{4} onto the stack, decrementing @samp{%esp} by 2.
+
+@smallexample
+ pushw $4
+@end smallexample
+
+The same code in a 16-bit code section would generate the machine
+opcode bytes @samp{6a 04} (ie. without the operand size prefix), which
+is correct since the processor default operand size is assumed to be 16
+bits in a 16-bit code section.
+
+@node i386-Bugs
+@section AT&T Syntax bugs
+
+The UnixWare assembler, and probably other AT&T derived ix86 Unix
+assemblers, generate floating point instructions with reversed source
+and destination registers in certain cases. Unfortunately, gcc and
+possibly many other programs use this reversed syntax, so we're stuck
+with it.
+
+For example
+
+@smallexample
+ fsub %st,%st(3)
+@end smallexample
+@noindent
+results in @samp{%st(3)} being updated to @samp{%st - %st(3)} rather
+than the expected @samp{%st(3) - %st}. This happens with all the
+non-commutative arithmetic floating point operations with two register
+operands where the source register is @samp{%st} and the destination
+register is @samp{%st(i)}.
+
+@node i386-Notes
+@section Notes
+
+@cindex i386 @code{mul}, @code{imul} instructions
+@cindex @code{mul} instruction, i386
+@cindex @code{imul} instruction, i386
+There is some trickery concerning the @samp{mul} and @samp{imul}
+instructions that deserves mention. The 16-, 32-, and 64-bit expanding
+multiplies (base opcode @samp{0xf6}; extension 4 for @samp{mul} and 5
+for @samp{imul}) can be output only in the one operand form. Thus,
+@samp{imul %ebx, %eax} does @emph{not} select the expanding multiply;
+the expanding multiply would clobber the @samp{%edx} register, and this
+would confuse @code{@value{GCC}} output. Use @samp{imul %ebx} to get the
+64-bit product in @samp{%edx:%eax}.
+
+We have added a two operand form of @samp{imul} when the first operand
+is an immediate mode expression and the second operand is a register.
+This is just a shorthand, so that, multiplying @samp{%eax} by 69, for
+example, can be done with @samp{imul $69, %eax} rather than @samp{imul
+$69, %eax, %eax}.
+
diff --git a/gas/doc/c-i960.texi b/gas/doc/c-i960.texi
new file mode 100644
index 00000000000..177030ab0be
--- /dev/null
+++ b/gas/doc/c-i960.texi
@@ -0,0 +1,298 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node i960-Dependent
+@chapter Intel 80960 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Intel 80960 Dependent Features
+@end ifclear
+
+@cindex i960 support
+@menu
+* Options-i960:: i960 Command-line Options
+* Floating Point-i960:: Floating Point
+* Directives-i960:: i960 Machine Directives
+* Opcodes for i960:: i960 Opcodes
+@end menu
+
+@c FIXME! Add Syntax sec with discussion of bitfields here, at least so
+@c long as they're not turned on for other machines than 960.
+
+@node Options-i960
+
+@section i960 Command-line Options
+
+@cindex i960 options
+@cindex options, i960
+@table @code
+
+@cindex i960 architecture options
+@cindex architecture options, i960
+@cindex @code{-A} options, i960
+@item -ACA | -ACA_A | -ACB | -ACC | -AKA | -AKB | -AKC | -AMC
+Select the 80960 architecture. Instructions or features not supported
+by the selected architecture cause fatal errors.
+
+@samp{-ACA} is equivalent to @samp{-ACA_A}; @samp{-AKC} is equivalent to
+@samp{-AMC}. Synonyms are provided for compatibility with other tools.
+
+If you do not specify any of these options, @code{@value{AS}} generates code
+for any instruction or feature that is supported by @emph{some} version of the
+960 (even if this means mixing architectures!). In principle,
+@code{@value{AS}} attempts to deduce the minimal sufficient processor type if
+none is specified; depending on the object code format, the processor type may
+be recorded in the object file. If it is critical that the @code{@value{AS}}
+output match a specific architecture, specify that architecture explicitly.
+
+@cindex @code{-b} option, i960
+@cindex branch recording, i960
+@cindex i960 branch recording
+@item -b
+Add code to collect information about conditional branches taken, for
+later optimization using branch prediction bits. (The conditional branch
+instructions have branch prediction bits in the CA, CB, and CC
+architectures.) If @var{BR} represents a conditional branch instruction,
+the following represents the code generated by the assembler when
+@samp{-b} is specified:
+
+@smallexample
+ call @var{increment routine}
+ .word 0 # pre-counter
+Label: @var{BR}
+ call @var{increment routine}
+ .word 0 # post-counter
+@end smallexample
+
+The counter following a branch records the number of times that branch
+was @emph{not} taken; the differenc between the two counters is the
+number of times the branch @emph{was} taken.
+
+@cindex @code{gbr960}, i960 postprocessor
+@cindex branch statistics table, i960
+A table of every such @code{Label} is also generated, so that the
+external postprocessor @code{gbr960} (supplied by Intel) can locate all
+the counters. This table is always labelled @samp{__BRANCH_TABLE__};
+this is a local symbol to permit collecting statistics for many separate
+object files. The table is word aligned, and begins with a two-word
+header. The first word, initialized to 0, is used in maintaining linked
+lists of branch tables. The second word is a count of the number of
+entries in the table, which follow immediately: each is a word, pointing
+to one of the labels illustrated above.
+
+@c TEXI2ROFF-KILL
+@ifinfo
+@c END TEXI2ROFF-KILL
+@example
+ +------------+------------+------------+ ... +------------+
+ | | | | | |
+ | *NEXT | COUNT: N | *BRLAB 1 | | *BRLAB N |
+ | | | | | |
+ +------------+------------+------------+ ... +------------+
+
+ __BRANCH_TABLE__ layout
+@end example
+@c TEXI2ROFF-KILL
+@end ifinfo
+@need 2000
+@tex
+\vskip 1pc
+\line{\leftskip=0pt\hskip\tableindent
+\boxit{2cm}{\tt *NEXT}\boxit{2cm}{\tt COUNT: \it N}\boxit{2cm}{\tt
+*BRLAB 1}\ibox{1cm}{\quad\dots}\boxit{2cm}{\tt *BRLAB \it N}\hfil}
+\centerline{\it {\tt \_\_BRANCH\_TABLE\_\_} layout}
+@end tex
+@c END TEXI2ROFF-KILL
+
+The first word of the header is used to locate multiple branch tables,
+since each object file may contain one. Normally the links are
+maintained with a call to an initialization routine, placed at the
+beginning of each function in the file. The @sc{gnu} C compiler
+generates these calls automatically when you give it a @samp{-b} option.
+For further details, see the documentation of @samp{gbr960}.
+
+@cindex @code{-no-relax} option, i960
+@item -no-relax
+Normally, Compare-and-Branch instructions with targets that require
+displacements greater than 13 bits (or that have external targets) are
+replaced with the corresponding compare (or @samp{chkbit}) and branch
+instructions. You can use the @samp{-no-relax} option to specify that
+@code{@value{AS}} should generate errors instead, if the target displacement
+is larger than 13 bits.
+
+This option does not affect the Compare-and-Jump instructions; the code
+emitted for them is @emph{always} adjusted when necessary (depending on
+displacement size), regardless of whether you use @samp{-no-relax}.
+@end table
+
+@node Floating Point-i960
+@section Floating Point
+
+@cindex floating point, i960 (@sc{ieee})
+@cindex i960 floating point (@sc{ieee})
+@code{@value{AS}} generates @sc{ieee} floating-point numbers for the directives
+@samp{.float}, @samp{.double}, @samp{.extended}, and @samp{.single}.
+
+@node Directives-i960
+@section i960 Machine Directives
+
+@cindex machine directives, i960
+@cindex i960 machine directives
+
+@table @code
+@cindex @code{bss} directive, i960
+@item .bss @var{symbol}, @var{length}, @var{align}
+Reserve @var{length} bytes in the bss section for a local @var{symbol},
+aligned to the power of two specified by @var{align}. @var{length} and
+@var{align} must be positive absolute expressions. This directive
+differs from @samp{.lcomm} only in that it permits you to specify
+an alignment. @xref{Lcomm,,@code{.lcomm}}.
+@end table
+
+@table @code
+@cindex @code{extended} directive, i960
+@item .extended @var{flonums}
+@code{.extended} expects zero or more flonums, separated by commas; for
+each flonum, @samp{.extended} emits an @sc{ieee} extended-format (80-bit)
+floating-point number.
+
+@cindex @code{leafproc} directive, i960
+@item .leafproc @var{call-lab}, @var{bal-lab}
+You can use the @samp{.leafproc} directive in conjunction with the
+optimized @code{callj} instruction to enable faster calls of leaf
+procedures. If a procedure is known to call no other procedures, you
+may define an entry point that skips procedure prolog code (and that does
+not depend on system-supplied saved context), and declare it as the
+@var{bal-lab} using @samp{.leafproc}. If the procedure also has an
+entry point that goes through the normal prolog, you can specify that
+entry point as @var{call-lab}.
+
+A @samp{.leafproc} declaration is meant for use in conjunction with the
+optimized call instruction @samp{callj}; the directive records the data
+needed later to choose between converting the @samp{callj} into a
+@code{bal} or a @code{call}.
+
+@var{call-lab} is optional; if only one argument is present, or if the
+two arguments are identical, the single argument is assumed to be the
+@code{bal} entry point.
+
+@cindex @code{sysproc} directive, i960
+@item .sysproc @var{name}, @var{index}
+The @samp{.sysproc} directive defines a name for a system procedure.
+After you define it using @samp{.sysproc}, you can use @var{name} to
+refer to the system procedure identified by @var{index} when calling
+procedures with the optimized call instruction @samp{callj}.
+
+Both arguments are required; @var{index} must be between 0 and 31
+(inclusive).
+@end table
+
+@node Opcodes for i960
+@section i960 Opcodes
+
+@cindex opcodes, i960
+@cindex i960 opcodes
+All Intel 960 machine instructions are supported;
+@pxref{Options-i960,,i960 Command-line Options} for a discussion of
+selecting the instruction subset for a particular 960
+architecture.@refill
+
+Some opcodes are processed beyond simply emitting a single corresponding
+instruction: @samp{callj}, and Compare-and-Branch or Compare-and-Jump
+instructions with target displacements larger than 13 bits.
+
+@menu
+* callj-i960:: @code{callj}
+* Compare-and-branch-i960:: Compare-and-Branch
+@end menu
+
+@node callj-i960
+@subsection @code{callj}
+
+@cindex @code{callj}, i960 pseudo-opcode
+@cindex i960 @code{callj} pseudo-opcode
+You can write @code{callj} to have the assembler or the linker determine
+the most appropriate form of subroutine call: @samp{call},
+@samp{bal}, or @samp{calls}. If the assembly source contains
+enough information---a @samp{.leafproc} or @samp{.sysproc} directive
+defining the operand---then @code{@value{AS}} translates the
+@code{callj}; if not, it simply emits the @code{callj}, leaving it
+for the linker to resolve.
+
+@node Compare-and-branch-i960
+@subsection Compare-and-Branch
+
+@cindex i960 compare/branch instructions
+@cindex compare/branch instructions, i960
+The 960 architectures provide combined Compare-and-Branch instructions
+that permit you to store the branch target in the lower 13 bits of the
+instruction word itself. However, if you specify a branch target far
+enough away that its address won't fit in 13 bits, the assembler can
+either issue an error, or convert your Compare-and-Branch instruction
+into separate instructions to do the compare and the branch.
+
+@cindex compare and jump expansions, i960
+@cindex i960 compare and jump expansions
+Whether @code{@value{AS}} gives an error or expands the instruction depends
+on two choices you can make: whether you use the @samp{-no-relax} option,
+and whether you use a ``Compare and Branch'' instruction or a ``Compare
+and Jump'' instruction. The ``Jump'' instructions are @emph{always}
+expanded if necessary; the ``Branch'' instructions are expanded when
+necessary @emph{unless} you specify @code{-no-relax}---in which case
+@code{@value{AS}} gives an error instead.
+
+These are the Compare-and-Branch instructions, their ``Jump'' variants,
+and the instruction pairs they may expand into:
+
+@c TEXI2ROFF-KILL
+@ifinfo
+@c END TEXI2ROFF-KILL
+@example
+ Compare and
+ Branch Jump Expanded to
+ ------ ------ ------------
+ bbc chkbit; bno
+ bbs chkbit; bo
+ cmpibe cmpije cmpi; be
+ cmpibg cmpijg cmpi; bg
+ cmpibge cmpijge cmpi; bge
+ cmpibl cmpijl cmpi; bl
+ cmpible cmpijle cmpi; ble
+ cmpibno cmpijno cmpi; bno
+ cmpibne cmpijne cmpi; bne
+ cmpibo cmpijo cmpi; bo
+ cmpobe cmpoje cmpo; be
+ cmpobg cmpojg cmpo; bg
+ cmpobge cmpojge cmpo; bge
+ cmpobl cmpojl cmpo; bl
+ cmpoble cmpojle cmpo; ble
+ cmpobne cmpojne cmpo; bne
+@end example
+@c TEXI2ROFF-KILL
+@end ifinfo
+@tex
+\hskip\tableindent
+\halign{\hfil {\tt #}\quad&\hfil {\tt #}\qquad&{\tt #}\hfil\cr
+\omit{\hfil\it Compare and\hfil}\span\omit&\cr
+{\it Branch}&{\it Jump}&{\it Expanded to}\cr
+ bbc& & chkbit; bno\cr
+ bbs& & chkbit; bo\cr
+ cmpibe& cmpije& cmpi; be\cr
+ cmpibg& cmpijg& cmpi; bg\cr
+ cmpibge& cmpijge& cmpi; bge\cr
+ cmpibl& cmpijl& cmpi; bl\cr
+ cmpible& cmpijle& cmpi; ble\cr
+ cmpibno& cmpijno& cmpi; bno\cr
+ cmpibne& cmpijne& cmpi; bne\cr
+ cmpibo& cmpijo& cmpi; bo\cr
+ cmpobe& cmpoje& cmpo; be\cr
+ cmpobg& cmpojg& cmpo; bg\cr
+ cmpobge& cmpojge& cmpo; bge\cr
+ cmpobl& cmpojl& cmpo; bl\cr
+ cmpoble& cmpojle& cmpo; ble\cr
+ cmpobne& cmpojne& cmpo; bne\cr}
+@end tex
+@c END TEXI2ROFF-KILL
diff --git a/gas/doc/c-m32r.texi b/gas/doc/c-m32r.texi
new file mode 100644
index 00000000000..f121ede4814
--- /dev/null
+++ b/gas/doc/c-m32r.texi
@@ -0,0 +1,13 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node M32R-Dependent
+@chapter M32R Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter M32R Dependent Features
+@end ifclear
+
diff --git a/gas/doc/c-m68k.texi b/gas/doc/c-m68k.texi
new file mode 100644
index 00000000000..16f857f3a7c
--- /dev/null
+++ b/gas/doc/c-m68k.texi
@@ -0,0 +1,503 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node M68K-Dependent
+@chapter M680x0 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter M680x0 Dependent Features
+@end ifclear
+
+@cindex M680x0 support
+@menu
+* M68K-Opts:: M680x0 Options
+* M68K-Syntax:: Syntax
+* M68K-Moto-Syntax:: Motorola Syntax
+* M68K-Float:: Floating Point
+* M68K-Directives:: 680x0 Machine Directives
+* M68K-opcodes:: Opcodes
+@end menu
+
+@node M68K-Opts
+@section M680x0 Options
+
+@cindex options, M680x0
+@cindex M680x0 options
+The Motorola 680x0 version of @code{@value{AS}} has a few machine
+dependent options.
+
+@cindex @samp{-l} option, M680x0
+You can use the @samp{-l} option to shorten the size of references to undefined
+symbols. If you do not use the @samp{-l} option, references to undefined
+symbols are wide enough for a full @code{long} (32 bits). (Since
+@code{@value{AS}} cannot know where these symbols end up, @code{@value{AS}} can
+only allocate space for the linker to fill in later. Since @code{@value{AS}}
+does not know how far away these symbols are, it allocates as much space as it
+can.) If you use this option, the references are only one word wide (16 bits).
+This may be useful if you want the object file to be as small as possible, and
+you know that the relevant symbols are always less than 17 bits away.
+
+@cindex @samp{--register-prefix-optional} option, M680x0
+For some configurations, especially those where the compiler normally
+does not prepend an underscore to the names of user variables, the
+assembler requires a @samp{%} before any use of a register name. This
+is intended to let the assembler distinguish between C variables and
+functions named @samp{a0} through @samp{a7}, and so on. The @samp{%} is
+always accepted, but is not required for certain configurations, notably
+@samp{sun3}. The @samp{--register-prefix-optional} option may be used
+to permit omitting the @samp{%} even for configurations for which it is
+normally required. If this is done, it will generally be impossible to
+refer to C variables and functions with the same names as register
+names.
+
+@cindex @samp{--bitwise-or} option, M680x0
+Normally the character @samp{|} is treated as a comment character, which
+means that it can not be used in expressions. The @samp{--bitwise-or}
+option turns @samp{|} into a normal character. In this mode, you must
+either use C style comments, or start comments with a @samp{#} character
+at the beginning of a line.
+
+@cindex @samp{--base-size-default-16}
+@cindex @samp{--base-size-default-32}
+If you use an addressing mode with a base register without specifying
+the size, @code{@value{AS}} will normally use the full 32 bit value.
+For example, the addressing mode @samp{%a0@@(%d0)} is equivalent to
+@samp{%a0@@(%d0:l)}. You may use the @samp{--base-size-default-16}
+option to tell @code{@value{AS}} to default to using the 16 bit value.
+In this case, @samp{%a0@@(%d0)} is equivalent to @samp{%a0@@(%d0:w)}.
+You may use the @samp{--base-size-default-32} option to restore the
+default behaviour.
+
+@cindex @samp{--disp-size-default-16}
+@cindex @samp{--disp-size-default-32}
+If you use an addressing mode with a displacement, and the value of the
+displacement is not known, @code{@value{AS}} will normally assume that
+the value is 32 bits. For example, if the symbol @samp{disp} has not
+been defined, @code{@value{AS}} will assemble the addressing mode
+@samp{%a0@@(disp,%d0)} as though @samp{disp} is a 32 bit value. You may
+use the @samp{--disp-size-default-16} option to tell @code{@value{AS}}
+to instead assume that the displacement is 16 bits. In this case,
+@code{@value{AS}} will assemble @samp{%a0@@(disp,%d0)} as though
+@samp{disp} is a 16 bit value. You may use the
+@samp{--disp-size-default-32} option to restore the default behaviour.
+
+@cindex @samp{-m68000} and related options
+@cindex architecture options, M680x0
+@cindex M680x0 architecture options
+@code{@value{AS}} can assemble code for several different members of the
+Motorola 680x0 family. The default depends upon how @code{@value{AS}}
+was configured when it was built; normally, the default is to assemble
+code for the 68020 microprocessor. The following options may be used to
+change the default. These options control which instructions and
+addressing modes are permitted. The members of the 680x0 family are
+very similar. For detailed information about the differences, see the
+Motorola manuals.
+
+@table @samp
+@item -m68000
+@itemx -m68ec000
+@itemx -m68hc000
+@itemx -m68hc001
+@itemx -m68008
+@itemx -m68302
+@itemx -m68306
+@itemx -m68307
+@itemx -m68322
+@itemx -m68356
+Assemble for the 68000. @samp{-m68008}, @samp{-m68302}, and so on are synonyms
+for @samp{-m68000}, since the chips are the same from the point of view
+of the assembler.
+
+@item -m68010
+Assemble for the 68010.
+
+@item -m68020
+@itemx -m68ec020
+Assemble for the 68020. This is normally the default.
+
+@item -m68030
+@itemx -m68ec030
+Assemble for the 68030.
+
+@item -m68040
+@itemx -m68ec040
+Assemble for the 68040.
+
+@item -m68060
+@itemx -m68ec060
+Assemble for the 68060.
+
+@item -mcpu32
+@itemx -m68330
+@itemx -m68331
+@itemx -m68332
+@itemx -m68333
+@itemx -m68334
+@itemx -m68336
+@itemx -m68340
+@itemx -m68341
+@itemx -m68349
+@itemx -m68360
+Assemble for the CPU32 family of chips.
+
+@item -m5200
+Assemble for the ColdFire family of chips.
+
+@item -m68881
+@itemx -m68882
+Assemble 68881 floating point instructions. This is the default for the
+68020, 68030, and the CPU32. The 68040 and 68060 always support
+floating point instructions.
+
+@item -mno-68881
+Do not assemble 68881 floating point instructions. This is the default
+for 68000 and the 68010. The 68040 and 68060 always support floating
+point instructions, even if this option is used.
+
+@item -m68851
+Assemble 68851 MMU instructions. This is the default for the 68020,
+68030, and 68060. The 68040 accepts a somewhat different set of MMU
+instructions; @samp{-m68851} and @samp{-m68040} should not be used
+together.
+
+@item -mno-68851
+Do not assemble 68851 MMU instructions. This is the default for the
+68000, 68010, and the CPU32. The 68040 accepts a somewhat different set
+of MMU instructions.
+@end table
+
+@node M68K-Syntax
+@section Syntax
+
+@cindex @sc{mit}
+This syntax for the Motorola 680x0 was developed at @sc{mit}.
+
+@cindex M680x0 syntax
+@cindex syntax, M680x0
+@cindex M680x0 size modifiers
+@cindex size modifiers, M680x0
+The 680x0 version of @code{@value{AS}} uses instructions names and
+syntax compatible with the Sun assembler. Intervening periods are
+ignored; for example, @samp{movl} is equivalent to @samp{mov.l}.
+
+In the following table @var{apc} stands for any of the address registers
+(@samp{%a0} through @samp{%a7}), the program counter (@samp{%pc}), the
+zero-address relative to the program counter (@samp{%zpc}), a suppressed
+address register (@samp{%za0} through @samp{%za7}), or it may be omitted
+entirely. The use of @var{size} means one of @samp{w} or @samp{l}, and
+it may be omitted, along with the leading colon, unless a scale is also
+specified. The use of @var{scale} means one of @samp{1}, @samp{2},
+@samp{4}, or @samp{8}, and it may always be omitted along with the
+leading colon.
+
+@cindex M680x0 addressing modes
+@cindex addressing modes, M680x0
+The following addressing modes are understood:
+@table @dfn
+@item Immediate
+@samp{#@var{number}}
+
+@item Data Register
+@samp{%d0} through @samp{%d7}
+
+@item Address Register
+@samp{%a0} through @samp{%a7}@*
+@samp{%a7} is also known as @samp{%sp}, i.e. the Stack Pointer. @code{%a6}
+is also known as @samp{%fp}, the Frame Pointer.
+
+@item Address Register Indirect
+@samp{%a0@@} through @samp{%a7@@}
+
+@item Address Register Postincrement
+@samp{%a0@@+} through @samp{%a7@@+}
+
+@item Address Register Predecrement
+@samp{%a0@@-} through @samp{%a7@@-}
+
+@item Indirect Plus Offset
+@samp{@var{apc}@@(@var{number})}
+
+@item Index
+@samp{@var{apc}@@(@var{number},@var{register}:@var{size}:@var{scale})}
+
+The @var{number} may be omitted.
+
+@item Postindex
+@samp{@var{apc}@@(@var{number})@@(@var{onumber},@var{register}:@var{size}:@var{scale})}
+
+The @var{onumber} or the @var{register}, but not both, may be omitted.
+
+@item Preindex
+@samp{@var{apc}@@(@var{number},@var{register}:@var{size}:@var{scale})@@(@var{onumber})}
+
+The @var{number} may be omitted. Omitting the @var{register} produces
+the Postindex addressing mode.
+
+@item Absolute
+@samp{@var{symbol}}, or @samp{@var{digits}}, optionally followed by
+@samp{:b}, @samp{:w}, or @samp{:l}.
+@end table
+
+@node M68K-Moto-Syntax
+@section Motorola Syntax
+
+@cindex Motorola syntax for the 680x0
+@cindex alternate syntax for the 680x0
+
+The standard Motorola syntax for this chip differs from the syntax
+already discussed (@pxref{M68K-Syntax,,Syntax}). @code{@value{AS}} can
+accept Motorola syntax for operands, even if @sc{mit} syntax is used for
+other operands in the same instruction. The two kinds of syntax are
+fully compatible.
+
+In the following table @var{apc} stands for any of the address registers
+(@samp{%a0} through @samp{%a7}), the program counter (@samp{%pc}), the
+zero-address relative to the program counter (@samp{%zpc}), or a
+suppressed address register (@samp{%za0} through @samp{%za7}). The use
+of @var{size} means one of @samp{w} or @samp{l}, and it may always be
+omitted along with the leading dot. The use of @var{scale} means one of
+@samp{1}, @samp{2}, @samp{4}, or @samp{8}, and it may always be omitted
+along with the leading asterisk.
+
+The following additional addressing modes are understood:
+
+@table @dfn
+@item Address Register Indirect
+@samp{(%a0)} through @samp{(%a7)}@*
+@samp{%a7} is also known as @samp{%sp}, i.e. the Stack Pointer. @code{%a6}
+is also known as @samp{%fp}, the Frame Pointer.
+
+@item Address Register Postincrement
+@samp{(%a0)+} through @samp{(%a7)+}
+
+@item Address Register Predecrement
+@samp{-(%a0)} through @samp{-(%a7)}
+
+@item Indirect Plus Offset
+@samp{@var{number}(@var{%a0})} through @samp{@var{number}(@var{%a7})},
+or @samp{@var{number}(@var{%pc})}.
+
+The @var{number} may also appear within the parentheses, as in
+@samp{(@var{number},@var{%a0})}. When used with the @var{pc}, the
+@var{number} may be omitted (with an address register, omitting the
+@var{number} produces Address Register Indirect mode).
+
+@item Index
+@samp{@var{number}(@var{apc},@var{register}.@var{size}*@var{scale})}
+
+The @var{number} may be omitted, or it may appear within the
+parentheses. The @var{apc} may be omitted. The @var{register} and the
+@var{apc} may appear in either order. If both @var{apc} and
+@var{register} are address registers, and the @var{size} and @var{scale}
+are omitted, then the first register is taken as the base register, and
+the second as the index register.
+
+@item Postindex
+@samp{([@var{number},@var{apc}],@var{register}.@var{size}*@var{scale},@var{onumber})}
+
+The @var{onumber}, or the @var{register}, or both, may be omitted.
+Either the @var{number} or the @var{apc} may be omitted, but not both.
+
+@item Preindex
+@samp{([@var{number},@var{apc},@var{register}.@var{size}*@var{scale}],@var{onumber})}
+
+The @var{number}, or the @var{apc}, or the @var{register}, or any two of
+them, may be omitted. The @var{onumber} may be omitted. The
+@var{register} and the @var{apc} may appear in either order. If both
+@var{apc} and @var{register} are address registers, and the @var{size}
+and @var{scale} are omitted, then the first register is taken as the
+base register, and the second as the index register.
+@end table
+
+@node M68K-Float
+@section Floating Point
+
+@cindex floating point, M680x0
+@cindex M680x0 floating point
+Packed decimal (P) format floating literals are not supported.
+Feel free to add the code!
+
+The floating point formats generated by directives are these.
+
+@table @code
+@cindex @code{float} directive, M680x0
+@item .float
+@code{Single} precision floating point constants.
+
+@cindex @code{double} directive, M680x0
+@item .double
+@code{Double} precision floating point constants.
+
+@cindex @code{extend} directive M680x0
+@cindex @code{ldouble} directive M680x0
+@item .extend
+@itemx .ldouble
+@code{Extended} precision (@code{long double}) floating point constants.
+@end table
+
+@node M68K-Directives
+@section 680x0 Machine Directives
+
+@cindex M680x0 directives
+@cindex directives, M680x0
+In order to be compatible with the Sun assembler the 680x0 assembler
+understands the following directives.
+
+@table @code
+@cindex @code{data1} directive, M680x0
+@item .data1
+This directive is identical to a @code{.data 1} directive.
+
+@cindex @code{data2} directive, M680x0
+@item .data2
+This directive is identical to a @code{.data 2} directive.
+
+@cindex @code{even} directive, M680x0
+@item .even
+This directive is a special case of the @code{.align} directive; it
+aligns the output to an even byte boundary.
+
+@cindex @code{skip} directive, M680x0
+@item .skip
+This directive is identical to a @code{.space} directive.
+@end table
+
+@need 2000
+@node M68K-opcodes
+@section Opcodes
+
+@cindex M680x0 opcodes
+@cindex opcodes, M680x0
+@cindex instruction set, M680x0
+@c doc@cygnus.com: I don't see any point in the following
+@c paragraph. Bugs are bugs; how does saying this
+@c help anyone?
+@ignore
+Danger: Several bugs have been found in the opcode table (and
+fixed). More bugs may exist. Be careful when using obscure
+instructions.
+@end ignore
+
+@menu
+* M68K-Branch:: Branch Improvement
+* M68K-Chars:: Special Characters
+@end menu
+
+@node M68K-Branch
+@subsection Branch Improvement
+
+@cindex pseudo-opcodes, M680x0
+@cindex M680x0 pseudo-opcodes
+@cindex branch improvement, M680x0
+@cindex M680x0 branch improvement
+Certain pseudo opcodes are permitted for branch instructions.
+They expand to the shortest branch instruction that reach the
+target. Generally these mnemonics are made by substituting @samp{j} for
+@samp{b} at the start of a Motorola mnemonic.
+
+The following table summarizes the pseudo-operations. A @code{*} flags
+cases that are more fully described after the table:
+
+@smallexample
+ Displacement
+ +-------------------------------------------------
+ | 68020 68000/10
+Pseudo-Op |BYTE WORD LONG LONG non-PC relative
+ +-------------------------------------------------
+ jbsr |bsrs bsr bsrl jsr jsr
+ jra |bras bra bral jmp jmp
+* jXX |bXXs bXX bXXl bNXs;jmpl bNXs;jmp
+* dbXX |dbXX dbXX dbXX; bra; jmpl
+* fjXX |fbXXw fbXXw fbXXl fbNXw;jmp
+
+XX: condition
+NX: negative of condition XX
+
+@end smallexample
+@center @code{*}---see full description below
+
+@table @code
+@item jbsr
+@itemx jra
+These are the simplest jump pseudo-operations; they always map to one
+particular machine instruction, depending on the displacement to the
+branch target.
+
+@item j@var{XX}
+Here, @samp{j@var{XX}} stands for an entire family of pseudo-operations,
+where @var{XX} is a conditional branch or condition-code test. The full
+list of pseudo-ops in this family is:
+@smallexample
+ jhi jls jcc jcs jne jeq jvc
+ jvs jpl jmi jge jlt jgt jle
+@end smallexample
+
+For the cases of non-PC relative displacements and long displacements on
+the 68000 or 68010, @code{@value{AS}} issues a longer code fragment in terms of
+@var{NX}, the opposite condition to @var{XX}. For example, for the
+non-PC relative case:
+@smallexample
+ j@var{XX} foo
+@end smallexample
+gives
+@smallexample
+ b@var{NX}s oof
+ jmp foo
+ oof:
+@end smallexample
+
+@item db@var{XX}
+The full family of pseudo-operations covered here is
+@smallexample
+ dbhi dbls dbcc dbcs dbne dbeq dbvc
+ dbvs dbpl dbmi dbge dblt dbgt dble
+ dbf dbra dbt
+@end smallexample
+
+Other than for word and byte displacements, when the source reads
+@samp{db@var{XX} foo}, @code{@value{AS}} emits
+@smallexample
+ db@var{XX} oo1
+ bra oo2
+ oo1:jmpl foo
+ oo2:
+@end smallexample
+
+@item fj@var{XX}
+This family includes
+@smallexample
+ fjne fjeq fjge fjlt fjgt fjle fjf
+ fjt fjgl fjgle fjnge fjngl fjngle fjngt
+ fjnle fjnlt fjoge fjogl fjogt fjole fjolt
+ fjor fjseq fjsf fjsne fjst fjueq fjuge
+ fjugt fjule fjult fjun
+@end smallexample
+
+For branch targets that are not PC relative, @code{@value{AS}} emits
+@smallexample
+ fb@var{NX} oof
+ jmp foo
+ oof:
+@end smallexample
+when it encounters @samp{fj@var{XX} foo}.
+
+@end table
+
+@node M68K-Chars
+@subsection Special Characters
+
+@cindex special characters, M680x0
+@cindex M680x0 immediate character
+@cindex immediate character, M680x0
+@cindex M680x0 line comment character
+@cindex line comment character, M680x0
+@cindex comments, M680x0
+The immediate character is @samp{#} for Sun compatibility. The
+line-comment character is @samp{|} (unless the @samp{--bitwise-or}
+option is used). If a @samp{#} appears at the beginning of a line, it
+is treated as a comment unless it looks like @samp{# line file}, in
+which case it is treated normally.
+
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
new file mode 100644
index 00000000000..523dda3799f
--- /dev/null
+++ b/gas/doc/c-mips.texi
@@ -0,0 +1,257 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node MIPS-Dependent
+@chapter MIPS Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter MIPS Dependent Features
+@end ifclear
+
+@cindex MIPS processor
+@sc{gnu} @code{@value{AS}} for @sc{mips} architectures supports several
+different @sc{mips} processors, and MIPS ISA levels I through IV. For
+information about the @sc{mips} instruction set, see @cite{MIPS RISC
+Architecture}, by Kane and Heindrich (Prentice-Hall). For an overview
+of @sc{mips} assembly conventions, see ``Appendix D: Assembly Language
+Programming'' in the same work.
+
+@menu
+* MIPS Opts:: Assembler options
+* MIPS Object:: ECOFF object code
+* MIPS Stabs:: Directives for debugging information
+* MIPS ISA:: Directives to override the ISA level
+* MIPS autoextend:: Directives for extending MIPS 16 bit instructions
+* MIPS insn:: Directive to mark data as an instruction
+* MIPS option stack:: Directives to save and restore options
+@end menu
+
+@node MIPS Opts
+@section Assembler options
+
+The @sc{mips} configurations of @sc{gnu} @code{@value{AS}} support these
+special options:
+
+@table @code
+@cindex @code{-G} option (MIPS)
+@item -G @var{num}
+This option sets the largest size of an object that can be referenced
+implicitly with the @code{gp} register. It is only accepted for targets
+that use @sc{ecoff} format. The default value is 8.
+
+@cindex @code{-EB} option (MIPS)
+@cindex @code{-EL} option (MIPS)
+@cindex MIPS big-endian output
+@cindex MIPS little-endian output
+@cindex big-endian output, MIPS
+@cindex little-endian output, MIPS
+@item -EB
+@itemx -EL
+Any @sc{mips} configuration of @code{@value{AS}} can select big-endian or
+little-endian output at run time (unlike the other @sc{gnu} development
+tools, which must be configured for one or the other). Use @samp{-EB}
+to select big-endian output, and @samp{-EL} for little-endian.
+
+@cindex MIPS architecture options
+@item -mips1
+@itemx -mips2
+@itemx -mips3
+@itemx -mips4
+Generate code for a particular MIPS Instruction Set Architecture level.
+@samp{-mips1} corresponds to the @sc{r2000} and @sc{r3000} processors,
+@samp{-mips2} to the @sc{r6000} processor, @samp{-mips3} to the
+@sc{r4000} processor, and @samp{-mips4} to the @sc{r8000} and
+@sc{r10000} processors. You can also switch instruction sets during the
+assembly; see @ref{MIPS ISA,, Directives to override the ISA level}.
+
+@item -mips16
+@itemx -no-mips16
+Generate code for the MIPS 16 processor. This is equivalent to putting
+@samp{.set mips16} at the start of the assembly file. @samp{-no-mips16}
+turns off this option.
+
+@item -m4010
+@itemx -no-m4010
+Generate code for the LSI @sc{r4010} chip. This tells the assembler to
+accept the @sc{r4010} specific instructions (@samp{addciu}, @samp{ffc},
+etc.), and to not schedule @samp{nop} instructions around accesses to
+the @samp{HI} and @samp{LO} registers. @samp{-no-m4010} turns off this
+option.
+
+@item -m4650
+@itemx -no-m4650
+Generate code for the MIPS @sc{r4650} chip. This tells the assembler to accept
+the @samp{mad} and @samp{madu} instruction, and to not schedule @samp{nop}
+instructions around accesses to the @samp{HI} and @samp{LO} registers.
+@samp{-no-m4650} turns off this option.
+
+@itemx -m3900
+@itemx -no-m3900
+@itemx -m4100
+@itemx -no-m4100
+For each option @samp{-m@var{nnnn}}, generate code for the MIPS
+@sc{r@var{nnnn}} chip. This tells the assembler to accept instructions
+specific to that chip, and to schedule for that chip's hazards.
+
+@item -mcpu=@var{cpu}
+Generate code for a particular MIPS cpu. It is exactly equivalent to
+@samp{-m@var{cpu}}, except that there are more value of @var{cpu}
+understood. Valid @var{cpu} value are:
+
+@quotation
+2000,
+3000,
+3900,
+4000,
+4010,
+4100,
+4111,
+4300,
+4400,
+4600,
+4650,
+5000,
+6000,
+8000,
+10000
+@end quotation
+
+
+@cindex @code{-nocpp} ignored (MIPS)
+@item -nocpp
+This option is ignored. It is accepted for command-line compatibility with
+other assemblers, which use it to turn off C style preprocessing. With
+@sc{gnu} @code{@value{AS}}, there is no need for @samp{-nocpp}, because the
+@sc{gnu} assembler itself never runs the C preprocessor.
+
+@item --trap
+@itemx --no-break
+@c FIXME! (1) reflect these options (next item too) in option summaries;
+@c (2) stop teasing, say _which_ instructions expanded _how_.
+@code{@value{AS}} automatically macro expands certain division and
+multiplication instructions to check for overflow and division by zero. This
+option causes @code{@value{AS}} to generate code to take a trap exception
+rather than a break exception when an error is detected. The trap instructions
+are only supported at Instruction Set Architecture level 2 and higher.
+
+@item --break
+@itemx --no-trap
+Generate code to take a break exception rather than a trap exception when an
+error is detected. This is the default.
+@end table
+
+@node MIPS Object
+@section MIPS ECOFF object code
+
+@cindex ECOFF sections
+@cindex MIPS ECOFF sections
+Assembling for a @sc{mips} @sc{ecoff} target supports some additional sections
+besides the usual @code{.text}, @code{.data} and @code{.bss}. The
+additional sections are @code{.rdata}, used for read-only data,
+@code{.sdata}, used for small data, and @code{.sbss}, used for small
+common objects.
+
+@cindex small objects, MIPS ECOFF
+@cindex @code{gp} register, MIPS
+When assembling for @sc{ecoff}, the assembler uses the @code{$gp} (@code{$28})
+register to form the address of a ``small object''. Any object in the
+@code{.sdata} or @code{.sbss} sections is considered ``small'' in this sense.
+For external objects, or for objects in the @code{.bss} section, you can use
+the @code{@value{GCC}} @samp{-G} option to control the size of objects addressed via
+@code{$gp}; the default value is 8, meaning that a reference to any object
+eight bytes or smaller uses @code{$gp}. Passing @samp{-G 0} to
+@code{@value{AS}} prevents it from using the @code{$gp} register on the basis
+of object size (but the assembler uses @code{$gp} for objects in @code{.sdata}
+or @code{sbss} in any case). The size of an object in the @code{.bss} section
+is set by the @code{.comm} or @code{.lcomm} directive that defines it. The
+size of an external object may be set with the @code{.extern} directive. For
+example, @samp{.extern sym,4} declares that the object at @code{sym} is 4 bytes
+in length, whie leaving @code{sym} otherwise undefined.
+
+Using small @sc{ecoff} objects requires linker support, and assumes that the
+@code{$gp} register is correctly initialized (normally done automatically by
+the startup code). @sc{mips} @sc{ecoff} assembly code must not modify the
+@code{$gp} register.
+
+@node MIPS Stabs
+@section Directives for debugging information
+
+@cindex MIPS debugging directives
+@sc{mips} @sc{ecoff} @code{@value{AS}} supports several directives used for
+generating debugging information which are not support by traditional @sc{mips}
+assemblers. These are @code{.def}, @code{.endef}, @code{.dim}, @code{.file},
+@code{.scl}, @code{.size}, @code{.tag}, @code{.type}, @code{.val},
+@code{.stabd}, @code{.stabn}, and @code{.stabs}. The debugging information
+generated by the three @code{.stab} directives can only be read by @sc{gdb},
+not by traditional @sc{mips} debuggers (this enhancement is required to fully
+support C++ debugging). These directives are primarily used by compilers, not
+assembly language programmers!
+
+@node MIPS ISA
+@section Directives to override the ISA level
+
+@cindex MIPS ISA override
+@kindex @code{.set mips@var{n}}
+@sc{gnu} @code{@value{AS}} supports an additional directive to change
+the @sc{mips} Instruction Set Architecture level on the fly: @code{.set
+mips@var{n}}. @var{n} should be a number from 0 to 4. A value from 1
+to 4 makes the assembler accept instructions for the corresponding
+@sc{isa} level, from that point on in the assembly. @code{.set
+mips@var{n}} affects not only which instructions are permitted, but also
+how certain macros are expanded. @code{.set mips0} restores the
+@sc{isa} level to its original level: either the level you selected with
+command line options, or the default for your configuration. You can
+use this feature to permit specific @sc{r4000} instructions while
+assembling in 32 bit mode. Use this directive with care!
+
+The directive @samp{.set mips16} puts the assembler into MIPS 16 mode,
+in which it will assemble instructions for the MIPS 16 processor. Use
+@samp{.set nomips16} to return to normal 32 bit mode.
+
+Traditional @sc{mips} assemblers do not support this directive.
+
+@node MIPS autoextend
+@section Directives for extending MIPS 16 bit instructions
+
+@kindex @code{.set autoextend}
+@kindex @code{.set noautoextend}
+By default, MIPS 16 instructions are automatically extended to 32 bits
+when necessary. The directive @samp{.set noautoextend} will turn this
+off. When @samp{.set noautoextend} is in effect, any 32 bit instruction
+must be explicitly extended with the @samp{.e} modifier (e.g.,
+@samp{li.e $4,1000}). The directive @samp{.set autoextend} may be used
+to once again automatically extend instructions when necessary.
+
+This directive is only meaningful when in MIPS 16 mode. Traditional
+@sc{mips} assemblers do not support this directive.
+
+@node MIPS insn
+@section Directive to mark data as an instruction
+
+@kindex @code{.insn}
+The @code{.insn} directive tells @code{@value{AS}} that the following
+data is actually instructions. This makes a difference in MIPS 16 mode:
+when loading the address of a label which precedes instructions,
+@code{@value{AS}} automatically adds 1 to the value, so that jumping to
+the loaded address will do the right thing.
+
+@node MIPS option stack
+@section Directives to save and restore options
+
+@cindex MIPS option stack
+@kindex @code{.set push}
+@kindex @code{.set pop}
+The directives @code{.set push} and @code{.set pop} may be used to save
+and restore the current settings for all the options which are
+controlled by @code{.set}. The @code{.set push} directive saves the
+current settings on a stack. The @code{.set pop} directive pops the
+stack and restores the settings.
+
+These directives can be useful inside an macro which must change an
+option such as the ISA level or instruction reordering but does not want
+to change the state of the code which invoked the macro.
+
+Traditional @sc{mips} assemblers do not support these directives.
diff --git a/gas/doc/c-ns32k.texi b/gas/doc/c-ns32k.texi
new file mode 100644
index 00000000000..29c61d94785
--- /dev/null
+++ b/gas/doc/c-ns32k.texi
@@ -0,0 +1,30 @@
+@c Copyright (c) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@ignore
+@c FIXME! Stop ignoring when filled in.
+@node 32x32
+@chapter 32x32
+
+@section Options
+The 32x32 version of @code{@value{AS}} accepts a @samp{-m32032} option to
+specify thiat it is compiling for a 32032 processor, or a
+@samp{-m32532} to specify that it is compiling for a 32532 option.
+The default (if neither is specified) is chosen when the assembler
+is compiled.
+
+@section Syntax
+I don't know anything about the 32x32 syntax assembled by
+@code{@value{AS}}. Someone who undersands the processor (I've never seen
+one) and the possible syntaxes should write this section.
+
+@section Floating Point
+The 32x32 uses @sc{ieee} floating point numbers, but @code{@value{AS}}
+only creates single or double precision values. I don't know if the
+32x32 understands extended precision numbers.
+
+@section 32x32 Machine Directives
+The 32x32 has no machine dependent directives.
+
+@end ignore
diff --git a/gas/doc/c-sh.texi b/gas/doc/c-sh.texi
new file mode 100644
index 00000000000..e20f5543788
--- /dev/null
+++ b/gas/doc/c-sh.texi
@@ -0,0 +1,272 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@page
+@node SH-Dependent
+@chapter Hitachi SH Dependent Features
+
+@cindex SH support
+@menu
+* SH Options:: Options
+* SH Syntax:: Syntax
+* SH Floating Point:: Floating Point
+* SH Directives:: SH Machine Directives
+* SH Opcodes:: Opcodes
+@end menu
+
+@node SH Options
+@section Options
+
+@cindex SH options (none)
+@cindex options, SH (none)
+@code{@value{AS}} has no additional command-line options for the Hitachi
+SH family.
+
+@node SH Syntax
+@section Syntax
+
+@menu
+* SH-Chars:: Special Characters
+* SH-Regs:: Register Names
+* SH-Addressing:: Addressing Modes
+@end menu
+
+@node SH-Chars
+@subsection Special Characters
+
+@cindex line comment character, SH
+@cindex SH line comment character
+@samp{!} is the line comment character.
+
+@cindex line separator, SH
+@cindex statement separator, SH
+@cindex SH line separator
+You can use @samp{;} instead of a newline to separate statements.
+
+@cindex symbol names, @samp{$} in
+@cindex @code{$} in symbol names
+Since @samp{$} has no special meaning, you may use it in symbol names.
+
+@node SH-Regs
+@subsection Register Names
+
+@cindex SH registers
+@cindex registers, SH
+You can use the predefined symbols @samp{r0}, @samp{r1}, @samp{r2},
+@samp{r3}, @samp{r4}, @samp{r5}, @samp{r6}, @samp{r7}, @samp{r8},
+@samp{r9}, @samp{r10}, @samp{r11}, @samp{r12}, @samp{r13}, @samp{r14},
+and @samp{r15} to refer to the SH registers.
+
+The SH also has these control registers:
+
+@table @code
+@item pr
+procedure register (holds return address)
+
+@item pc
+program counter
+
+@item mach
+@itemx macl
+high and low multiply accumulator registers
+
+@item sr
+status register
+
+@item gbr
+global base register
+
+@item vbr
+vector base register (for interrupt vectors)
+@end table
+
+@node SH-Addressing
+@subsection Addressing Modes
+
+@cindex addressing modes, SH
+@cindex SH addressing modes
+@code{@value{AS}} understands the following addressing modes for the SH.
+@code{R@var{n}} in the following refers to any of the numbered
+registers, but @emph{not} the control registers.
+
+@table @code
+@item R@var{n}
+Register direct
+
+@item @@R@var{n}
+Register indirect
+
+@item @@-R@var{n}
+Register indirect with pre-decrement
+
+@item @@R@var{n}+
+Register indirect with post-increment
+
+@item @@(@var{disp}, R@var{n})
+Register indirect with displacement
+
+@item @@(R0, R@var{n})
+Register indexed
+
+@item @@(@var{disp}, GBR)
+@code{GBR} offset
+
+@item @@(R0, GBR)
+GBR indexed
+
+@item @var{addr}
+@itemx @@(@var{disp}, PC)
+PC relative address (for branch or for addressing memory). The
+@code{@value{AS}} implementation allows you to use the simpler form
+@var{addr} anywhere a PC relative address is called for; the alternate
+form is supported for compatibility with other assemblers.
+
+@item #@var{imm}
+Immediate data
+@end table
+
+@node SH Floating Point
+@section Floating Point
+
+@cindex floating point, SH (@sc{ieee})
+@cindex SH floating point (@sc{ieee})
+The SH family has no hardware floating point, but the @code{.float}
+directive generates @sc{ieee} floating-point numbers for compatibility
+with other development tools.
+
+@node SH Directives
+@section SH Machine Directives
+
+@cindex SH machine directives
+@cindex machine directives, SH
+@cindex @code{uaword} directive, SH
+@cindex @code{ualong} directive, SH
+
+@table @code
+@item uaword
+@itemx ualong
+@code{@value{AS}} will issue a warning when a misaligned @code{.word} or
+@code{.long} directive is used. You may use @code{.uaword} or
+@code{.ualong} to indicate that the value is intentionally misaligned.
+@end table
+
+@node SH Opcodes
+@section Opcodes
+
+@cindex SH opcode summary
+@cindex opcode summary, SH
+@cindex mnemonics, SH
+@cindex instruction summary, SH
+For detailed information on the SH machine instruction set, see
+@cite{SH-Microcomputer User's Manual} (Hitachi Micro Systems, Inc.).
+
+@code{@value{AS}} implements all the standard SH opcodes. No additional
+pseudo-instructions are needed on this family. Note, however, that
+because @code{@value{AS}} supports a simpler form of PC-relative
+addressing, you may simply write (for example)
+
+@example
+mov.l bar,r0
+@end example
+
+@noindent
+where other assemblers might require an explicit displacement to
+@code{bar} from the program counter:
+
+@example
+mov.l @@(@var{disp}, PC)
+@end example
+
+@ifset SMALL
+@c this table, due to the multi-col faking and hardcoded order, looks silly
+@c except in smallbook. See comments below "@set SMALL" near top of this file.
+
+Here is a summary of SH opcodes:
+
+@page
+@smallexample
+@i{Legend:}
+Rn @r{a numbered register}
+Rm @r{another numbered register}
+#imm @r{immediate data}
+disp @r{displacement}
+disp8 @r{8-bit displacement}
+disp12 @r{12-bit displacement}
+
+add #imm,Rn lds.l @@Rn+,PR
+add Rm,Rn mac.w @@Rm+,@@Rn+
+addc Rm,Rn mov #imm,Rn
+addv Rm,Rn mov Rm,Rn
+and #imm,R0 mov.b Rm,@@(R0,Rn)
+and Rm,Rn mov.b Rm,@@-Rn
+and.b #imm,@@(R0,GBR) mov.b Rm,@@Rn
+bf disp8 mov.b @@(disp,Rm),R0
+bra disp12 mov.b @@(disp,GBR),R0
+bsr disp12 mov.b @@(R0,Rm),Rn
+bt disp8 mov.b @@Rm+,Rn
+clrmac mov.b @@Rm,Rn
+clrt mov.b R0,@@(disp,Rm)
+cmp/eq #imm,R0 mov.b R0,@@(disp,GBR)
+cmp/eq Rm,Rn mov.l Rm,@@(disp,Rn)
+cmp/ge Rm,Rn mov.l Rm,@@(R0,Rn)
+cmp/gt Rm,Rn mov.l Rm,@@-Rn
+cmp/hi Rm,Rn mov.l Rm,@@Rn
+cmp/hs Rm,Rn mov.l @@(disp,Rn),Rm
+cmp/pl Rn mov.l @@(disp,GBR),R0
+cmp/pz Rn mov.l @@(disp,PC),Rn
+cmp/str Rm,Rn mov.l @@(R0,Rm),Rn
+div0s Rm,Rn mov.l @@Rm+,Rn
+div0u mov.l @@Rm,Rn
+div1 Rm,Rn mov.l R0,@@(disp,GBR)
+exts.b Rm,Rn mov.w Rm,@@(R0,Rn)
+exts.w Rm,Rn mov.w Rm,@@-Rn
+extu.b Rm,Rn mov.w Rm,@@Rn
+extu.w Rm,Rn mov.w @@(disp,Rm),R0
+jmp @@Rn mov.w @@(disp,GBR),R0
+jsr @@Rn mov.w @@(disp,PC),Rn
+ldc Rn,GBR mov.w @@(R0,Rm),Rn
+ldc Rn,SR mov.w @@Rm+,Rn
+ldc Rn,VBR mov.w @@Rm,Rn
+ldc.l @@Rn+,GBR mov.w R0,@@(disp,Rm)
+ldc.l @@Rn+,SR mov.w R0,@@(disp,GBR)
+ldc.l @@Rn+,VBR mova @@(disp,PC),R0
+lds Rn,MACH movt Rn
+lds Rn,MACL muls Rm,Rn
+lds Rn,PR mulu Rm,Rn
+lds.l @@Rn+,MACH neg Rm,Rn
+lds.l @@Rn+,MACL negc Rm,Rn
+@page
+nop stc VBR,Rn
+not Rm,Rn stc.l GBR,@@-Rn
+or #imm,R0 stc.l SR,@@-Rn
+or Rm,Rn stc.l VBR,@@-Rn
+or.b #imm,@@(R0,GBR) sts MACH,Rn
+rotcl Rn sts MACL,Rn
+rotcr Rn sts PR,Rn
+rotl Rn sts.l MACH,@@-Rn
+rotr Rn sts.l MACL,@@-Rn
+rte sts.l PR,@@-Rn
+rts sub Rm,Rn
+sett subc Rm,Rn
+shal Rn subv Rm,Rn
+shar Rn swap.b Rm,Rn
+shll Rn swap.w Rm,Rn
+shll16 Rn tas.b @@Rn
+shll2 Rn trapa #imm
+shll8 Rn tst #imm,R0
+shlr Rn tst Rm,Rn
+shlr16 Rn tst.b #imm,@@(R0,GBR)
+shlr2 Rn xor #imm,R0
+shlr8 Rn xor Rm,Rn
+sleep xor.b #imm,@@(R0,GBR)
+stc GBR,Rn xtrct Rm,Rn
+stc SR,Rn
+@end smallexample
+@end ifset
+
+@ifset Hitachi-all
+@ifclear GENERIC
+@raisesections
+@end ifclear
+@end ifset
+
diff --git a/gas/doc/c-sparc.texi b/gas/doc/c-sparc.texi
new file mode 100644
index 00000000000..f871c82b05e
--- /dev/null
+++ b/gas/doc/c-sparc.texi
@@ -0,0 +1,179 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node Sparc-Dependent
+@chapter SPARC Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter SPARC Dependent Features
+@end ifclear
+
+@cindex SPARC support
+@menu
+* Sparc-Opts:: Options
+* Sparc-Aligned-Data:: Option to enforce aligned data
+* Sparc-Float:: Floating Point
+* Sparc-Directives:: Sparc Machine Directives
+@end menu
+
+@node Sparc-Opts
+@section Options
+
+@cindex options for SPARC
+@cindex SPARC options
+@cindex architectures, SPARC
+@cindex SPARC architectures
+The SPARC chip family includes several successive levels, using the same
+core instruction set, but including a few additional instructions at
+each level. There are exceptions to this however. For details on what
+instructions each variant supports, please see the chip's architecture
+reference manual.
+
+By default, @code{@value{AS}} assumes the core instruction set (SPARC
+v6), but ``bumps'' the architecture level as needed: it switches to
+successively higher architectures as it encounters instructions that
+only exist in the higher levels.
+
+If not configured for SPARC v9 (@code{sparc64-*-*}) GAS will not bump
+passed sparclite by default, an option must be passed to enable the
+v9 instructions.
+
+GAS treats sparclite as being compatible with v8, unless an architecture
+is explicitly requested. SPARC v9 is always incompatible with sparclite.
+
+@c The order here is the same as the order of enum sparc_opcode_arch_val
+@c to give the user a sense of the order of the "bumping".
+
+@table @code
+@kindex -Av6
+@kindex Av7
+@kindex -Av8
+@kindex -Asparclet
+@kindex -Asparclite
+@kindex -Av9
+@kindex -Av9a
+@item -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite
+@itemx -Av8plus | -Av8plusa | -Av9 | -Av9a
+Use one of the @samp{-A} options to select one of the SPARC
+architectures explicitly. If you select an architecture explicitly,
+@code{@value{AS}} reports a fatal error if it encounters an instruction
+or feature requiring an incompatible or higher level.
+
+@samp{-Av8plus} and @samp{-Av8plusa} select a 32 bit environment.
+
+@samp{-Av9} and @samp{-Av9a} select a 64 bit environment and are not
+available unless GAS is explicitly configured with 64 bit environment
+support.
+
+@samp{-Av8plusa} and @samp{-Av9a} enable the SPARC V9 instruction set with
+UltraSPARC extensions.
+
+@item -xarch=v8plus | -xarch=v8plusa
+For compatibility with the Solaris v9 assembler. These options are
+equivalent to -Av8plus and -Av8plusa, respectively.
+
+@item -bump
+Warn whenever it is necessary to switch to another level.
+If an architecture level is explicitly requested, GAS will not issue
+warnings until that level is reached, and will then bump the level
+as required (except between incompatible levels).
+
+@item -32 | -64
+Select the word size, either 32 bits or 64 bits.
+These options are only available with the ELF object file format,
+and require that the necessary BFD support has been included.
+@end table
+
+@node Sparc-Aligned-Data
+@section Enforcing aligned data
+
+@cindex data alignment on SPARC
+@cindex SPARC data alignment
+SPARC GAS normally permits data to be misaligned. For example, it
+permits the @code{.long} pseudo-op to be used on a byte boundary.
+However, the native SunOS and Solaris assemblers issue an error when
+they see misaligned data.
+
+@kindex --enforce-aligned-data
+You can use the @code{--enforce-aligned-data} option to make SPARC GAS
+also issue an error about misaligned data, just as the SunOS and Solaris
+assemblers do.
+
+The @code{--enforce-aligned-data} option is not the default because gcc
+issues misaligned data pseudo-ops when it initializes certain packed
+data structures (structures defined using the @code{packed} attribute).
+You may have to assemble with GAS in order to initialize packed data
+structures in your own code.
+
+@ignore
+@c FIXME: (sparc) Fill in "syntax" section!
+@c subsection syntax
+I don't know anything about Sparc syntax. Someone who does
+will have to write this section.
+@end ignore
+
+@node Sparc-Float
+@section Floating Point
+
+@cindex floating point, SPARC (@sc{ieee})
+@cindex SPARC floating point (@sc{ieee})
+The Sparc uses @sc{ieee} floating-point numbers.
+
+@node Sparc-Directives
+@section Sparc Machine Directives
+
+@cindex SPARC machine directives
+@cindex machine directives, SPARC
+The Sparc version of @code{@value{AS}} supports the following additional
+machine directives:
+
+@table @code
+@cindex @code{align} directive, SPARC
+@item .align
+This must be followed by the desired alignment in bytes.
+
+@cindex @code{common} directive, SPARC
+@item .common
+This must be followed by a symbol name, a positive number, and
+@code{"bss"}. This behaves somewhat like @code{.comm}, but the
+syntax is different.
+
+@cindex @code{half} directive, SPARC
+@item .half
+This is functionally identical to @code{.short}.
+
+@cindex @code{proc} directive, SPARC
+@item .proc
+This directive is ignored. Any text following it on the same
+line is also ignored.
+
+@cindex @code{reserve} directive, SPARC
+@item .reserve
+This must be followed by a symbol name, a positive number, and
+@code{"bss"}. This behaves somewhat like @code{.lcomm}, but the
+syntax is different.
+
+@cindex @code{seg} directive, SPARC
+@item .seg
+This must be followed by @code{"text"}, @code{"data"}, or
+@code{"data1"}. It behaves like @code{.text}, @code{.data}, or
+@code{.data 1}.
+
+@cindex @code{skip} directive, SPARC
+@item .skip
+This is functionally identical to the @code{.space} directive.
+
+@cindex @code{word} directive, SPARC
+@item .word
+On the Sparc, the @code{.word} directive produces 32 bit values,
+instead of the 16 bit values it produces on many other machines.
+
+@cindex @code{xword} directive, SPARC
+@item .xword
+On the Sparc V9 processor, the @code{.xword} directive produces
+64 bit values.
+@end table
+
diff --git a/gas/doc/c-v850.texi b/gas/doc/c-v850.texi
new file mode 100644
index 00000000000..5416e0f1b8f
--- /dev/null
+++ b/gas/doc/c-v850.texi
@@ -0,0 +1,363 @@
+@c Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@node V850-Dependent
+@chapter v850 Dependent Features
+
+@cindex V850 support
+@menu
+* V850 Options:: Options
+* V850 Syntax:: Syntax
+* V850 Floating Point:: Floating Point
+* V850 Directives:: V850 Machine Directives
+* V850 Opcodes:: Opcodes
+@end menu
+
+@node V850 Options
+@section Options
+@cindex V850 options (none)
+@cindex options for V850 (none)
+@code{@value{AS}} supports the following additional command-line options
+for the V850 processor family:
+
+@cindex command line options, V850
+@cindex V850 command line options
+@table @code
+
+@cindex @code{-wsigned_overflow} command line option, V850
+@item -wsigned_overflow
+Causes warnings to be produced when signed immediate values overflow the
+space available for then within their opcodes. By default this option
+is disabled as it is possible to receive spurious warnings due to using
+exact bit patterns as immediate constants.
+
+@cindex @code{-wunsigned_overflow} command line option, V850
+@item -wunsigned_overflow
+Causes warnings to be produced when unsigned immediate values overflow
+the space available for then within their opcodes. By default this
+option is disabled as it is possible to receive spurious warnings due to
+using exact bit patterns as immediate constants.
+
+@cindex @code{-mv850} command line option, V850
+@item -mv850
+Specifies that the assembled code should be marked as being targeted at
+the V850 processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{-mv850e} command line option, V850
+@item -mv850e
+Specifies that the assembled code should be marked as being targeted at
+the V850E processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{-mv850any} command line option, V850
+@item -mv850any
+Specifies that the assembled code should be marked as being targeted at
+the V850 processor but support instructions that are specific to the
+extended variants of the process. This allows the production of
+binaries that contain target specific code, but which are also intended
+to be used in a generic fashion. For example libgcc.a contains generic
+routines used by the code produced by GCC for all versions of the v850
+architecture, together with support routines only used by the V850E
+architecture.
+
+@end table
+
+
+@node V850 Syntax
+@section Syntax
+@menu
+* V850-Chars:: Special Characters
+* V850-Regs:: Register Names
+@end menu
+
+@node V850-Chars
+@subsection Special Characters
+
+@cindex line comment character, V850
+@cindex V850 line comment character
+@samp{#} is the line comment character.
+@node V850-Regs
+@subsection Register Names
+
+@cindex V850 register names
+@cindex register names, V850
+@code{@value{AS}} supports the following names for registers:
+@table @code
+@cindex @code{zero} register, V850
+@item general register 0
+r0, zero
+@item general register 1
+r1
+@item general register 2
+r2, hp
+@cindex @code{sp} register, V850
+@item general register 3
+r3, sp
+@cindex @code{gp} register, V850
+@item general register 4
+r4, gp
+@cindex @code{tp} register, V850
+@item general register 5
+r5, tp
+@item general register 6
+r6
+@item general register 7
+r7
+@item general register 8
+r8
+@item general register 9
+r9
+@item general register 10
+r10
+@item general register 11
+r11
+@item general register 12
+r12
+@item general register 13
+r13
+@item general register 14
+r14
+@item general register 15
+r15
+@item general register 16
+r16
+@item general register 17
+r17
+@item general register 18
+r18
+@item general register 19
+r19
+@item general register 20
+r20
+@item general register 21
+r21
+@item general register 22
+r22
+@item general register 23
+r23
+@item general register 24
+r24
+@item general register 25
+r25
+@item general register 26
+r26
+@item general register 27
+r27
+@item general register 28
+r28
+@item general register 29
+r29
+@cindex @code{ep} register, V850
+@item general register 30
+r30, ep
+@cindex @code{lp} register, V850
+@item general register 31
+r31, lp
+@cindex @code{eipc} register, V850
+@item system register 0
+eipc
+@cindex @code{eipsw} register, V850
+@item system register 1
+eipsw
+@cindex @code{fepc} register, V850
+@item system register 2
+fepc
+@cindex @code{fepsw} register, V850
+@item system register 3
+fepsw
+@cindex @code{ecr} register, V850
+@item system register 4
+ecr
+@cindex @code{psw} register, V850
+@item system register 5
+psw
+@cindex @code{ctpc} register, V850
+@item system register 16
+ctpc
+@cindex @code{ctpsw} register, V850
+@item system register 17
+ctpsw
+@cindex @code{dbpc} register, V850
+@item system register 18
+dbpc
+@cindex @code{dbpsw} register, V850
+@item system register 19
+dbpsw
+@cindex @code{ctbp} register, V850
+@item system register 20
+ctbp
+@end table
+
+@node V850 Floating Point
+@section Floating Point
+
+@cindex floating point, V850 (@sc{ieee})
+@cindex V850 floating point (@sc{ieee})
+The V850 family uses @sc{ieee} floating-point numbers.
+
+@node V850 Directives
+@section V850 Machine Directives
+
+@cindex machine directives, V850
+@cindex V850 machine directives
+@table @code
+@cindex @code{offset} directive, V850
+@item .offset @var{<expression>}
+Moves the offset into the current section to the specified amount.
+
+@cindex @code{section} directive, V850
+@item .section "name", <type>
+This is an extension to the standard .section directive. It sets the
+current section to be <type> and creates an alias for this section
+called "name".
+
+@cindex @code{.v850} directive, V850
+@item .v850
+Specifies that the assembled code should be marked as being targeted at
+the V850 processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@cindex @code{.v850e} directive, V850
+@item .v850e
+Specifies that the assembled code should be marked as being targeted at
+the V850E processor. This allows the linker to detect attempts to link
+such code with code assembled for other processors.
+
+@end table
+
+@node V850 Opcodes
+@section Opcodes
+
+@cindex V850 opcodes
+@cindex opcodes for V850
+@code{@value{AS}} implements all the standard V850 opcodes.
+
+@code{@value{AS}} also implements the following pseudo ops:
+
+@table @code
+
+@cindex @code{hi0} pseudo-op, V850
+@item hi0()
+Computes the higher 16 bits of the given expression and stores it into
+the immediate operand field of the given instruction. For example:
+
+ @samp{mulhi hi0(here - there), r5, r6}
+
+computes the difference between the address of labels 'here' and
+'there', takes the upper 16 bits of this difference, shifts it down 16
+bits and then mutliplies it by the lower 16 bits in register 5, putting
+the result into register 6.
+
+@cindex @code{lo} pseudo-op, V850
+@item lo()
+Computes the lower 16 bits of the given expression and stores it into
+the immediate operand field of the given instruction. For example:
+
+ @samp{addi lo(here - there), r5, r6}
+
+computes the difference between the address of labels 'here' and
+'there', takes the lower 16 bits of this difference and adds it to
+register 5, putting the result into register 6.
+
+@cindex @code{hi} pseudo-op, V850
+@item hi()
+Computes the higher 16 bits of the given expression and then adds the
+value of the most significant bit of the lower 16 bits of the expression
+and stores the result into the immediate operand field of the given
+instruction. For example the following code can be used to compute the
+address of the label 'here' and store it into register 6:
+
+ @samp{movhi hi(here), r0, r6}
+ @samp{movea lo(here), r6, r6}
+
+The reason for this special behaviour is that movea performs a sign
+extention on its immediate operand. So for example if the address of
+'here' was 0xFFFFFFFF then without the special behaviour of the hi()
+pseudo-op the movhi instruction would put 0xFFFF0000 into r6, then the
+movea instruction would takes its immediate operand, 0xFFFF, sign extend
+it to 32 bits, 0xFFFFFFFF, and then add it into r6 giving 0xFFFEFFFF
+which is wrong (the fifth nibble is E). With the hi() pseudo op adding
+in the top bit of the lo() pseudo op, the movhi instruction actually
+stores 0 into r6 (0xFFFF + 1 = 0x0000), so that the movea instruction
+stores 0xFFFFFFFF into r6 - the right value.
+
+@cindex @code{hilo} pseudo-op, V850
+@item hilo()
+Computes the 32 bit value of the given expression and stores it into
+the immediate operand field of the given instruction (which must be a
+mov instruction). For example:
+
+ @samp{mov hilo(here), r6}
+
+computes the absolute address of label 'here' and puts the result into
+register 6.
+
+@cindex @code{sdaoff} pseudo-op, V850
+@item sdaoff()
+Computes the offset of the named variable from the start of the Small
+Data Area (whoes address is held in register 4, the GP register) and
+stores the result as a 16 bit signed value in the immediate operand
+field of the given instruction. For example:
+
+ @samp{ld.w sdaoff(_a_variable)[gp],r6}
+
+loads the contents of the location pointed to by the label '_a_variable'
+into register 6, provided that the label is located somewhere within +/-
+32K of the address held in the GP register. [Note the linker assumes
+that the GP register contains a fixed address set to the address of the
+label called '__gp'. This can either be set up automatically by the
+linker, or specifically set by using the @samp{--defsym __gp=<value>}
+command line option].
+
+@cindex @code{tdaoff} pseudo-op, V850
+@item tdaoff()
+Computes the offset of the named variable from the start of the Tiny
+Data Area (whoes address is held in register 30, the EP register) and
+stores the result as a 4,5, 7 or 8 bit unsigned value in the immediate
+operand field of the given instruction. For example:
+
+ @samp{sld.w tdaoff(_a_variable)[ep],r6}
+
+loads the contents of the location pointed to by the label '_a_variable'
+into register 6, provided that the label is located somewhere within +256
+bytes of the address held in the EP register. [Note the linker assumes
+that the EP register contains a fixed address set to the address of the
+label called '__ep'. This can either be set up automatically by the
+linker, or specifically set by using the @samp{--defsym __ep=<value>}
+command line option].
+
+@cindex @code{zdaoff} pseudo-op, V850
+@item zdaoff()
+Computes the offset of the named variable from address 0 and stores the
+result as a 16 bit signed value in the immediate operand field of the
+given instruction. For example:
+
+ @samp{movea zdaoff(_a_variable),zero,r6}
+
+puts the address of the label '_a_variable' into register 6, assuming
+that the label is somewhere within the first 32K of memory. (Strictly
+speaking it also possible to access the last 32K of memory as well, as
+the offsets are signed).
+
+@cindex @code{ctoff} pseudo-op, V850
+@item ctoff()
+Computes the offset of the named variable from the start of the Call
+Table Area (whoes address is helg in system register 20, the CTBP
+register) and stores the result a 6 or 16 bit unsigned value in the
+immediate field of then given instruction or piece of data. For
+example:
+
+ @samp{callt ctoff(table_func1)}
+
+will put the call the function whoes address is held in the call table
+at the location labeled 'table_func1'.
+
+@end table
+
+
+For information on the V850 instruction set, see @cite{V850
+Family 32-/16-Bit single-Chip Microcontroller Architecture Manual} from NEC.
+Ltd.
+
diff --git a/gas/doc/c-vax.texi b/gas/doc/c-vax.texi
new file mode 100644
index 00000000000..b13d7e5a493
--- /dev/null
+++ b/gas/doc/c-vax.texi
@@ -0,0 +1,357 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@c VAX/VMS description exhanced and corrected by Klaus K"aempf, kkaempf@progis.de
+@ifset GENERIC
+@node Vax-Dependent
+@chapter VAX Dependent Features
+@cindex VAX support
+
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter VAX Dependent Features
+@cindex VAX support
+
+@end ifclear
+
+@menu
+* VAX-Opts:: VAX Command-Line Options
+* VAX-float:: VAX Floating Point
+* VAX-directives:: Vax Machine Directives
+* VAX-opcodes:: VAX Opcodes
+* VAX-branch:: VAX Branch Improvement
+* VAX-operands:: VAX Operands
+* VAX-no:: Not Supported on VAX
+@end menu
+
+
+@node VAX-Opts
+@section VAX Command-Line Options
+
+@cindex command-line options ignored, VAX
+@cindex VAX command-line options ignored
+The Vax version of @code{@value{AS}} accepts any of the following options,
+gives a warning message that the option was ignored and proceeds.
+These options are for compatibility with scripts designed for other
+people's assemblers.
+
+@table @code
+@cindex @code{-D}, ignored on VAX
+@cindex @code{-S}, ignored on VAX
+@cindex @code{-T}, ignored on VAX
+@item @code{-D} (Debug)
+@itemx @code{-S} (Symbol Table)
+@itemx @code{-T} (Token Trace)
+These are obsolete options used to debug old assemblers.
+
+@cindex @code{-d}, VAX option
+@item @code{-d} (Displacement size for JUMPs)
+This option expects a number following the @samp{-d}. Like options
+that expect filenames, the number may immediately follow the
+@samp{-d} (old standard) or constitute the whole of the command line
+argument that follows @samp{-d} (@sc{gnu} standard).
+
+@cindex @code{-V}, redundant on VAX
+@item @code{-V} (Virtualize Interpass Temporary File)
+Some other assemblers use a temporary file. This option
+commanded them to keep the information in active memory rather
+than in a disk file. @code{@value{AS}} always does this, so this
+option is redundant.
+
+@cindex @code{-J}, ignored on VAX
+@item @code{-J} (JUMPify Longer Branches)
+Many 32-bit computers permit a variety of branch instructions
+to do the same job. Some of these instructions are short (and
+fast) but have a limited range; others are long (and slow) but
+can branch anywhere in virtual memory. Often there are 3
+flavors of branch: short, medium and long. Some other
+assemblers would emit short and medium branches, unless told by
+this option to emit short and long branches.
+
+@cindex @code{-t}, ignored on VAX
+@item @code{-t} (Temporary File Directory)
+Some other assemblers may use a temporary file, and this option
+takes a filename being the directory to site the temporary
+file. Since @code{@value{AS}} does not use a temporary disk file, this
+option makes no difference. @samp{-t} needs exactly one
+filename.
+@end table
+
+@cindex VMS (VAX) options
+@cindex options for VAX/VMS
+@cindex VAX/VMS options
+@cindex Vax-11 C compatibility
+@cindex symbols with uppercase, VAX/VMS
+The Vax version of the assembler accepts additional options when
+compiled for VMS:
+
+@table @samp
+@cindex @samp{-h} option, VAX/VMS
+@item -h @var{n}
+External symbol or section (used for global variables) names are not
+case sensitive on VAX/VMS and always mapped to upper case. This is
+contrary to the C language definition which explicitly distinguishes
+upper and lower case. To implement a standard conforming C compiler,
+names must be changed (mapped) to preserve the case information. The
+default mapping is to convert all lower case characters to uppercase and
+adding an underscore followed by a 6 digit hex value, representing a 24
+digit binary value. The one digits in the binary value represent which
+characters are uppercase in the original symbol name.
+
+The @samp{-h @var{n}} option determines how we map names. This takes
+several values. No @samp{-h} switch at all allows case hacking as
+described above. A value of zero (@samp{-h0}) implies names should be
+upper case, and inhibits the case hack. A value of 2 (@samp{-h2})
+implies names should be all lower case, with no case hack. A value of 3
+(@samp{-h3}) implies that case should be preserved. The value 1 is
+unused. The @code{-H} option directs @code{@value{AS}} to display
+every mapped symbol during assembly.
+
+Symbols whose names include a dollar sign @samp{$} are exceptions to the
+general name mapping. These symbols are normally only used to reference
+VMS library names. Such symbols are always mapped to upper case.
+
+@cindex @samp{-+} option, VAX/VMS
+@item -+
+The @samp{-+} option causes @code{@value{AS}} to truncate any symbol
+name larger than 31 characters. The @samp{-+} option also prevents some
+code following the @samp{_main} symbol normally added to make the object
+file compatible with Vax-11 "C".
+
+@cindex @samp{-1} option, VAX/VMS
+@item -1
+This option is ignored for backward compatibility with @code{@value{AS}}
+version 1.x.
+
+@cindex @samp{-H} option, VAX/VMS
+@item -H
+The @samp{-H} option causes @code{@value{AS}} to print every symbol
+which was changed by case mapping.
+@end table
+
+@node VAX-float
+@section VAX Floating Point
+
+@cindex VAX floating point
+@cindex floating point, VAX
+Conversion of flonums to floating point is correct, and
+compatible with previous assemblers. Rounding is
+towards zero if the remainder is exactly half the least significant bit.
+
+@code{D}, @code{F}, @code{G} and @code{H} floating point formats
+are understood.
+
+Immediate floating literals (@emph{e.g.} @samp{S`$6.9})
+are rendered correctly. Again, rounding is towards zero in the
+boundary case.
+
+@cindex @code{float} directive, VAX
+@cindex @code{double} directive, VAX
+The @code{.float} directive produces @code{f} format numbers.
+The @code{.double} directive produces @code{d} format numbers.
+
+@node VAX-directives
+@section Vax Machine Directives
+
+@cindex machine directives, VAX
+@cindex VAX machine directives
+The Vax version of the assembler supports four directives for
+generating Vax floating point constants. They are described in the
+table below.
+
+@cindex wide floating point directives, VAX
+@table @code
+@cindex @code{dfloat} directive, VAX
+@item .dfloat
+This expects zero or more flonums, separated by commas, and
+assembles Vax @code{d} format 64-bit floating point constants.
+
+@cindex @code{ffloat} directive, VAX
+@item .ffloat
+This expects zero or more flonums, separated by commas, and
+assembles Vax @code{f} format 32-bit floating point constants.
+
+@cindex @code{gfloat} directive, VAX
+@item .gfloat
+This expects zero or more flonums, separated by commas, and
+assembles Vax @code{g} format 64-bit floating point constants.
+
+@cindex @code{hfloat} directive, VAX
+@item .hfloat
+This expects zero or more flonums, separated by commas, and
+assembles Vax @code{h} format 128-bit floating point constants.
+
+@end table
+
+@node VAX-opcodes
+@section VAX Opcodes
+
+@cindex VAX opcode mnemonics
+@cindex opcode mnemonics, VAX
+@cindex mnemonics for opcodes, VAX
+All DEC mnemonics are supported. Beware that @code{case@dots{}}
+instructions have exactly 3 operands. The dispatch table that
+follows the @code{case@dots{}} instruction should be made with
+@code{.word} statements. This is compatible with all unix
+assemblers we know of.
+
+@node VAX-branch
+@section VAX Branch Improvement
+
+@cindex VAX branch improvement
+@cindex branch improvement, VAX
+@cindex pseudo-ops for branch, VAX
+Certain pseudo opcodes are permitted. They are for branch
+instructions. They expand to the shortest branch instruction that
+reaches the target. Generally these mnemonics are made by
+substituting @samp{j} for @samp{b} at the start of a DEC mnemonic.
+This feature is included both for compatibility and to help
+compilers. If you do not need this feature, avoid these
+opcodes. Here are the mnemonics, and the code they can expand into.
+
+@table @code
+@item jbsb
+@samp{Jsb} is already an instruction mnemonic, so we chose @samp{jbsb}.
+@table @asis
+@item (byte displacement)
+@kbd{bsbb @dots{}}
+@item (word displacement)
+@kbd{bsbw @dots{}}
+@item (long displacement)
+@kbd{jsb @dots{}}
+@end table
+@item jbr
+@itemx jr
+Unconditional branch.
+@table @asis
+@item (byte displacement)
+@kbd{brb @dots{}}
+@item (word displacement)
+@kbd{brw @dots{}}
+@item (long displacement)
+@kbd{jmp @dots{}}
+@end table
+@item j@var{COND}
+@var{COND} may be any one of the conditional branches
+@code{neq}, @code{nequ}, @code{eql}, @code{eqlu}, @code{gtr},
+@code{geq}, @code{lss}, @code{gtru}, @code{lequ}, @code{vc}, @code{vs},
+@code{gequ}, @code{cc}, @code{lssu}, @code{cs}.
+@var{COND} may also be one of the bit tests
+@code{bs}, @code{bc}, @code{bss}, @code{bcs}, @code{bsc}, @code{bcc},
+@code{bssi}, @code{bcci}, @code{lbs}, @code{lbc}.
+@var{NOTCOND} is the opposite condition to @var{COND}.
+@table @asis
+@item (byte displacement)
+@kbd{b@var{COND} @dots{}}
+@item (word displacement)
+@kbd{b@var{NOTCOND} foo ; brw @dots{} ; foo:}
+@item (long displacement)
+@kbd{b@var{NOTCOND} foo ; jmp @dots{} ; foo:}
+@end table
+@item jacb@var{X}
+@var{X} may be one of @code{b d f g h l w}.
+@table @asis
+@item (word displacement)
+@kbd{@var{OPCODE} @dots{}}
+@item (long displacement)
+@example
+@var{OPCODE} @dots{}, foo ;
+brb bar ;
+foo: jmp @dots{} ;
+bar:
+@end example
+@end table
+@item jaob@var{YYY}
+@var{YYY} may be one of @code{lss leq}.
+@item jsob@var{ZZZ}
+@var{ZZZ} may be one of @code{geq gtr}.
+@table @asis
+@item (byte displacement)
+@kbd{@var{OPCODE} @dots{}}
+@item (word displacement)
+@example
+@var{OPCODE} @dots{}, foo ;
+brb bar ;
+foo: brw @var{destination} ;
+bar:
+@end example
+@item (long displacement)
+@example
+@var{OPCODE} @dots{}, foo ;
+brb bar ;
+foo: jmp @var{destination} ;
+bar:
+@end example
+@end table
+@item aobleq
+@itemx aoblss
+@itemx sobgeq
+@itemx sobgtr
+@table @asis
+@item (byte displacement)
+@kbd{@var{OPCODE} @dots{}}
+@item (word displacement)
+@example
+@var{OPCODE} @dots{}, foo ;
+brb bar ;
+foo: brw @var{destination} ;
+bar:
+@end example
+@item (long displacement)
+@example
+@var{OPCODE} @dots{}, foo ;
+brb bar ;
+foo: jmp @var{destination} ;
+bar:
+@end example
+@end table
+@end table
+
+@node VAX-operands
+@section VAX Operands
+
+@cindex VAX operand notation
+@cindex operand notation, VAX
+@cindex immediate character, VAX
+@cindex VAX immediate character
+The immediate character is @samp{$} for Unix compatibility, not
+@samp{#} as DEC writes it.
+
+@cindex indirect character, VAX
+@cindex VAX indirect character
+The indirect character is @samp{*} for Unix compatibility, not
+@samp{@@} as DEC writes it.
+
+@cindex displacement sizing character, VAX
+@cindex VAX displacement sizing character
+The displacement sizing character is @samp{`} (an accent grave) for
+Unix compatibility, not @samp{^} as DEC writes it. The letter
+preceding @samp{`} may have either case. @samp{G} is not
+understood, but all other letters (@code{b i l s w}) are understood.
+
+@cindex register names, VAX
+@cindex VAX register names
+Register names understood are @code{r0 r1 r2 @dots{} r15 ap fp sp
+pc}. Upper and lower case letters are equivalent.
+
+For instance
+@smallexample
+tstb *w`$4(r5)
+@end smallexample
+
+Any expression is permitted in an operand. Operands are comma
+separated.
+
+@c There is some bug to do with recognizing expressions
+@c in operands, but I forget what it is. It is
+@c a syntax clash because () is used as an address mode
+@c and to encapsulate sub-expressions.
+
+@node VAX-no
+@section Not Supported on VAX
+
+@cindex VAX bitfields not supported
+@cindex bitfields, not supported on VAX
+Vax bit fields can not be assembled with @code{@value{AS}}. Someone
+can add the required code if they really need it.
diff --git a/gas/doc/c-z8k.texi b/gas/doc/c-z8k.texi
new file mode 100644
index 00000000000..1fb10e3b2ca
--- /dev/null
+++ b/gas/doc/c-z8k.texi
@@ -0,0 +1,380 @@
+@c Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node Z8000-Dependent
+@chapter Z8000 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter Z8000 Dependent Features
+@end ifclear
+
+@cindex Z8000 support
+The Z8000 @value{AS} supports both members of the Z8000 family: the
+unsegmented Z8002, with 16 bit addresses, and the segmented Z8001 with
+24 bit addresses.
+
+When the assembler is in unsegmented mode (specified with the
+@code{unsegm} directive), an address takes up one word (16 bit)
+sized register. When the assembler is in segmented mode (specified with
+the @code{segm} directive), a 24-bit address takes up a long (32 bit)
+register. @xref{Z8000 Directives,,Assembler Directives for the Z8000},
+for a list of other Z8000 specific assembler directives.
+
+@menu
+* Z8000 Options:: No special command-line options for Z8000
+* Z8000 Syntax:: Assembler syntax for the Z8000
+* Z8000 Directives:: Special directives for the Z8000
+* Z8000 Opcodes:: Opcodes
+@end menu
+
+@node Z8000 Options
+@section Options
+
+@cindex Z8000 options
+@cindex options, Z8000
+@code{@value{AS}} has no additional command-line options for the Zilog
+Z8000 family.
+
+@node Z8000 Syntax
+@section Syntax
+@menu
+* Z8000-Chars:: Special Characters
+* Z8000-Regs:: Register Names
+* Z8000-Addressing:: Addressing Modes
+@end menu
+
+@node Z8000-Chars
+@subsection Special Characters
+
+@cindex line comment character, Z8000
+@cindex Z8000 line comment character
+@samp{!} is the line comment character.
+
+@cindex line separator, Z8000
+@cindex statement separator, Z8000
+@cindex Z8000 line separator
+You can use @samp{;} instead of a newline to separate statements.
+
+@node Z8000-Regs
+@subsection Register Names
+
+@cindex Z8000 registers
+@cindex registers, Z8000
+The Z8000 has sixteen 16 bit registers, numbered 0 to 15. You can refer
+to different sized groups of registers by register number, with the
+prefix @samp{r} for 16 bit registers, @samp{rr} for 32 bit registers and
+@samp{rq} for 64 bit registers. You can also refer to the contents of
+the first eight (of the sixteen 16 bit registers) by bytes. They are
+named @samp{r@var{n}h} and @samp{r@var{n}l}.
+
+@smallexample
+@exdent @emph{byte registers}
+r0l r0h r1h r1l r2h r2l r3h r3l
+r4h r4l r5h r5l r6h r6l r7h r7l
+
+@exdent @emph{word registers}
+r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15
+
+@exdent @emph{long word registers}
+rr0 rr2 rr4 rr6 rr8 rr10 rr12 rr14
+
+@exdent @emph{quad word registers}
+rq0 rq4 rq8 rq12
+@end smallexample
+
+@node Z8000-Addressing
+@subsection Addressing Modes
+
+@cindex addressing modes, Z8000
+@cindex Z800 addressing modes
+@value{AS} understands the following addressing modes for the Z8000:
+
+@table @code
+@item r@var{n}
+Register direct
+
+@item @@r@var{n}
+Indirect register
+
+@item @var{addr}
+Direct: the 16 bit or 24 bit address (depending on whether the assembler
+is in segmented or unsegmented mode) of the operand is in the instruction.
+
+@item address(r@var{n})
+Indexed: the 16 or 24 bit address is added to the 16 bit register to produce
+the final address in memory of the operand.
+
+@item r@var{n}(#@var{imm})
+Base Address: the 16 or 24 bit register is added to the 16 bit sign
+extended immediate displacement to produce the final address in memory
+of the operand.
+
+@item r@var{n}(r@var{m})
+Base Index: the 16 or 24 bit register r@var{n} is added to the sign
+extended 16 bit index register r@var{m} to produce the final address in
+memory of the operand.
+
+@item #@var{xx}
+Immediate data @var{xx}.
+@end table
+
+@node Z8000 Directives
+@section Assembler Directives for the Z8000
+
+@cindex Z8000 directives
+@cindex directives, Z8000
+The Z8000 port of @value{AS} includes these additional assembler directives,
+for compatibility with other Z8000 assemblers. As shown, these do not
+begin with @samp{.} (unlike the ordinary @value{AS} directives).
+
+@table @code
+@kindex segm
+@item segm
+Generates code for the segmented Z8001.
+
+@kindex unsegm
+@item unsegm
+Generates code for the unsegmented Z8002.
+
+@kindex name
+@item name
+Synonym for @code{.file}
+
+@kindex global
+@item global
+Synonym for @code{.global}
+
+@kindex wval
+@item wval
+Synonym for @code{.word}
+
+@kindex lval
+@item lval
+Synonym for @code{.long}
+
+@kindex bval
+@item bval
+Synonym for @code{.byte}
+
+@kindex sval
+@item sval
+Assemble a string. @code{sval} expects one string literal, delimited by
+single quotes. It assembles each byte of the string into consecutive
+addresses. You can use the escape sequence @samp{%@var{xx}} (where
+@var{xx} represents a two-digit hexadecimal number) to represent the
+character whose @sc{ascii} value is @var{xx}. Use this feature to
+describe single quote and other characters that may not appear in string
+literals as themselves. For example, the C statement @w{@samp{char *a =
+"he said \"it's 50% off\"";}} is represented in Z8000 assembly language
+(shown with the assembler output in hex at the left) as
+
+@iftex
+@begingroup
+@let@nonarrowing=@comment
+@end iftex
+@smallexample
+68652073 sval 'he said %22it%27s 50%25 off%22%00'
+61696420
+22697427
+73203530
+25206F66
+662200
+@end smallexample
+@iftex
+@endgroup
+@end iftex
+
+@kindex rsect
+@item rsect
+synonym for @code{.section}
+
+@kindex block
+@item block
+synonym for @code{.space}
+
+@kindex even
+@item even
+special case of @code{.align}; aligns output to even byte boundary.
+@end table
+
+@node Z8000 Opcodes
+@section Opcodes
+
+@cindex Z8000 opcode summary
+@cindex opcode summary, Z8000
+@cindex mnemonics, Z8000
+@cindex instruction summary, Z8000
+For detailed information on the Z8000 machine instruction set, see
+@cite{Z8000 Technical Manual}.
+
+@ifset SMALL
+@c this table, due to the multi-col faking and hardcoded order, looks silly
+@c except in smallbook. See comments below "@set SMALL" near top of this file.
+
+The following table summarizes the opcodes and their arguments:
+@iftex
+@begingroup
+@let@nonarrowing=@comment
+@end iftex
+@smallexample
+
+ rs @r{16 bit source register}
+ rd @r{16 bit destination register}
+ rbs @r{8 bit source register}
+ rbd @r{8 bit destination register}
+ rrs @r{32 bit source register}
+ rrd @r{32 bit destination register}
+ rqs @r{64 bit source register}
+ rqd @r{64 bit destination register}
+ addr @r{16/24 bit address}
+ imm @r{immediate data}
+
+adc rd,rs clrb addr cpsir @@rd,@@rs,rr,cc
+adcb rbd,rbs clrb addr(rd) cpsirb @@rd,@@rs,rr,cc
+add rd,@@rs clrb rbd dab rbd
+add rd,addr com @@rd dbjnz rbd,disp7
+add rd,addr(rs) com addr dec @@rd,imm4m1
+add rd,imm16 com addr(rd) dec addr(rd),imm4m1
+add rd,rs com rd dec addr,imm4m1
+addb rbd,@@rs comb @@rd dec rd,imm4m1
+addb rbd,addr comb addr decb @@rd,imm4m1
+addb rbd,addr(rs) comb addr(rd) decb addr(rd),imm4m1
+addb rbd,imm8 comb rbd decb addr,imm4m1
+addb rbd,rbs comflg flags decb rbd,imm4m1
+addl rrd,@@rs cp @@rd,imm16 di i2
+addl rrd,addr cp addr(rd),imm16 div rrd,@@rs
+addl rrd,addr(rs) cp addr,imm16 div rrd,addr
+addl rrd,imm32 cp rd,@@rs div rrd,addr(rs)
+addl rrd,rrs cp rd,addr div rrd,imm16
+and rd,@@rs cp rd,addr(rs) div rrd,rs
+and rd,addr cp rd,imm16 divl rqd,@@rs
+and rd,addr(rs) cp rd,rs divl rqd,addr
+and rd,imm16 cpb @@rd,imm8 divl rqd,addr(rs)
+and rd,rs cpb addr(rd),imm8 divl rqd,imm32
+andb rbd,@@rs cpb addr,imm8 divl rqd,rrs
+andb rbd,addr cpb rbd,@@rs djnz rd,disp7
+andb rbd,addr(rs) cpb rbd,addr ei i2
+andb rbd,imm8 cpb rbd,addr(rs) ex rd,@@rs
+andb rbd,rbs cpb rbd,imm8 ex rd,addr
+bit @@rd,imm4 cpb rbd,rbs ex rd,addr(rs)
+bit addr(rd),imm4 cpd rd,@@rs,rr,cc ex rd,rs
+bit addr,imm4 cpdb rbd,@@rs,rr,cc exb rbd,@@rs
+bit rd,imm4 cpdr rd,@@rs,rr,cc exb rbd,addr
+bit rd,rs cpdrb rbd,@@rs,rr,cc exb rbd,addr(rs)
+bitb @@rd,imm4 cpi rd,@@rs,rr,cc exb rbd,rbs
+bitb addr(rd),imm4 cpib rbd,@@rs,rr,cc ext0e imm8
+bitb addr,imm4 cpir rd,@@rs,rr,cc ext0f imm8
+bitb rbd,imm4 cpirb rbd,@@rs,rr,cc ext8e imm8
+bitb rbd,rs cpl rrd,@@rs ext8f imm8
+bpt cpl rrd,addr exts rrd
+call @@rd cpl rrd,addr(rs) extsb rd
+call addr cpl rrd,imm32 extsl rqd
+call addr(rd) cpl rrd,rrs halt
+calr disp12 cpsd @@rd,@@rs,rr,cc in rd,@@rs
+clr @@rd cpsdb @@rd,@@rs,rr,cc in rd,imm16
+clr addr cpsdr @@rd,@@rs,rr,cc inb rbd,@@rs
+clr addr(rd) cpsdrb @@rd,@@rs,rr,cc inb rbd,imm16
+clr rd cpsi @@rd,@@rs,rr,cc inc @@rd,imm4m1
+clrb @@rd cpsib @@rd,@@rs,rr,cc inc addr(rd),imm4m1
+inc addr,imm4m1 ldb rbd,rs(rx) mult rrd,addr(rs)
+inc rd,imm4m1 ldb rd(imm16),rbs mult rrd,imm16
+incb @@rd,imm4m1 ldb rd(rx),rbs mult rrd,rs
+incb addr(rd),imm4m1 ldctl ctrl,rs multl rqd,@@rs
+incb addr,imm4m1 ldctl rd,ctrl multl rqd,addr
+incb rbd,imm4m1 ldd @@rs,@@rd,rr multl rqd,addr(rs)
+ind @@rd,@@rs,ra lddb @@rs,@@rd,rr multl rqd,imm32
+indb @@rd,@@rs,rba lddr @@rs,@@rd,rr multl rqd,rrs
+inib @@rd,@@rs,ra lddrb @@rs,@@rd,rr neg @@rd
+inibr @@rd,@@rs,ra ldi @@rd,@@rs,rr neg addr
+iret ldib @@rd,@@rs,rr neg addr(rd)
+jp cc,@@rd ldir @@rd,@@rs,rr neg rd
+jp cc,addr ldirb @@rd,@@rs,rr negb @@rd
+jp cc,addr(rd) ldk rd,imm4 negb addr
+jr cc,disp8 ldl @@rd,rrs negb addr(rd)
+ld @@rd,imm16 ldl addr(rd),rrs negb rbd
+ld @@rd,rs ldl addr,rrs nop
+ld addr(rd),imm16 ldl rd(imm16),rrs or rd,@@rs
+ld addr(rd),rs ldl rd(rx),rrs or rd,addr
+ld addr,imm16 ldl rrd,@@rs or rd,addr(rs)
+ld addr,rs ldl rrd,addr or rd,imm16
+ld rd(imm16),rs ldl rrd,addr(rs) or rd,rs
+ld rd(rx),rs ldl rrd,imm32 orb rbd,@@rs
+ld rd,@@rs ldl rrd,rrs orb rbd,addr
+ld rd,addr ldl rrd,rs(imm16) orb rbd,addr(rs)
+ld rd,addr(rs) ldl rrd,rs(rx) orb rbd,imm8
+ld rd,imm16 ldm @@rd,rs,n orb rbd,rbs
+ld rd,rs ldm addr(rd),rs,n out @@rd,rs
+ld rd,rs(imm16) ldm addr,rs,n out imm16,rs
+ld rd,rs(rx) ldm rd,@@rs,n outb @@rd,rbs
+lda rd,addr ldm rd,addr(rs),n outb imm16,rbs
+lda rd,addr(rs) ldm rd,addr,n outd @@rd,@@rs,ra
+lda rd,rs(imm16) ldps @@rs outdb @@rd,@@rs,rba
+lda rd,rs(rx) ldps addr outib @@rd,@@rs,ra
+ldar rd,disp16 ldps addr(rs) outibr @@rd,@@rs,ra
+ldb @@rd,imm8 ldr disp16,rs pop @@rd,@@rs
+ldb @@rd,rbs ldr rd,disp16 pop addr(rd),@@rs
+ldb addr(rd),imm8 ldrb disp16,rbs pop addr,@@rs
+ldb addr(rd),rbs ldrb rbd,disp16 pop rd,@@rs
+ldb addr,imm8 ldrl disp16,rrs popl @@rd,@@rs
+ldb addr,rbs ldrl rrd,disp16 popl addr(rd),@@rs
+ldb rbd,@@rs mbit popl addr,@@rs
+ldb rbd,addr mreq rd popl rrd,@@rs
+ldb rbd,addr(rs) mres push @@rd,@@rs
+ldb rbd,imm8 mset push @@rd,addr
+ldb rbd,rbs mult rrd,@@rs push @@rd,addr(rs)
+ldb rbd,rs(imm16) mult rrd,addr push @@rd,imm16
+push @@rd,rs set addr,imm4 subl rrd,imm32
+pushl @@rd,@@rs set rd,imm4 subl rrd,rrs
+pushl @@rd,addr set rd,rs tcc cc,rd
+pushl @@rd,addr(rs) setb @@rd,imm4 tccb cc,rbd
+pushl @@rd,rrs setb addr(rd),imm4 test @@rd
+res @@rd,imm4 setb addr,imm4 test addr
+res addr(rd),imm4 setb rbd,imm4 test addr(rd)
+res addr,imm4 setb rbd,rs test rd
+res rd,imm4 setflg imm4 testb @@rd
+res rd,rs sinb rbd,imm16 testb addr
+resb @@rd,imm4 sinb rd,imm16 testb addr(rd)
+resb addr(rd),imm4 sind @@rd,@@rs,ra testb rbd
+resb addr,imm4 sindb @@rd,@@rs,rba testl @@rd
+resb rbd,imm4 sinib @@rd,@@rs,ra testl addr
+resb rbd,rs sinibr @@rd,@@rs,ra testl addr(rd)
+resflg imm4 sla rd,imm8 testl rrd
+ret cc slab rbd,imm8 trdb @@rd,@@rs,rba
+rl rd,imm1or2 slal rrd,imm8 trdrb @@rd,@@rs,rba
+rlb rbd,imm1or2 sll rd,imm8 trib @@rd,@@rs,rbr
+rlc rd,imm1or2 sllb rbd,imm8 trirb @@rd,@@rs,rbr
+rlcb rbd,imm1or2 slll rrd,imm8 trtdrb @@ra,@@rb,rbr
+rldb rbb,rba sout imm16,rs trtib @@ra,@@rb,rr
+rr rd,imm1or2 soutb imm16,rbs trtirb @@ra,@@rb,rbr
+rrb rbd,imm1or2 soutd @@rd,@@rs,ra trtrb @@ra,@@rb,rbr
+rrc rd,imm1or2 soutdb @@rd,@@rs,rba tset @@rd
+rrcb rbd,imm1or2 soutib @@rd,@@rs,ra tset addr
+rrdb rbb,rba soutibr @@rd,@@rs,ra tset addr(rd)
+rsvd36 sra rd,imm8 tset rd
+rsvd38 srab rbd,imm8 tsetb @@rd
+rsvd78 sral rrd,imm8 tsetb addr
+rsvd7e srl rd,imm8 tsetb addr(rd)
+rsvd9d srlb rbd,imm8 tsetb rbd
+rsvd9f srll rrd,imm8 xor rd,@@rs
+rsvdb9 sub rd,@@rs xor rd,addr
+rsvdbf sub rd,addr xor rd,addr(rs)
+sbc rd,rs sub rd,addr(rs) xor rd,imm16
+sbcb rbd,rbs sub rd,imm16 xor rd,rs
+sc imm8 sub rd,rs xorb rbd,@@rs
+sda rd,rs subb rbd,@@rs xorb rbd,addr
+sdab rbd,rs subb rbd,addr xorb rbd,addr(rs)
+sdal rrd,rs subb rbd,addr(rs) xorb rbd,imm8
+sdl rd,rs subb rbd,imm8 xorb rbd,rbs
+sdlb rbd,rs subb rbd,rbs xorb rbd,rbs
+sdll rrd,rs subl rrd,@@rs
+set @@rd,imm4 subl rrd,addr
+set addr(rd),imm4 subl rrd,addr(rs)
+@end smallexample
+@iftex
+@endgroup
+@end iftex
+@end ifset
+
diff --git a/gas/doc/gasp.texi b/gas/doc/gasp.texi
new file mode 100644
index 00000000000..64cd6f44b17
--- /dev/null
+++ b/gas/doc/gasp.texi
@@ -0,0 +1,1086 @@
+\input texinfo @c -*- Texinfo -*-
+@setfilename gasp.info
+@c
+@c This file documents the assembly preprocessor "GASP"
+@c
+@c Copyright (c) 1994 Free Software Foundation, Inc.
+@c
+@c This text may be freely distributed under the terms of the GNU
+@c General Public License.
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* gasp: (gasp). The GNU Assembler Preprocessor
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@syncodeindex ky cp
+@syncodeindex fn cp
+
+@finalout
+@setchapternewpage odd
+@settitle GASP
+@titlepage
+@c FIXME boring title
+@title GASP, an assembly preprocessor
+@subtitle for GASP version 1
+@sp 1
+@subtitle March 1994
+@author Roland Pesch
+@page
+
+@tex
+{\parskip=0pt \hfill Cygnus Support\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1994, 1995 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+
+@ifinfo
+Copyright @copyright{} 1994, 1995 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+
+@node Top
+@top GASP
+
+GASP is a preprocessor for assembly programs.
+
+This file describes version 1 of GASP.
+
+Steve Chamberlain wrote GASP; Roland Pesch wrote this manual.
+
+@menu
+* Overview:: What is GASP?
+* Invoking GASP:: Command line options.
+* Commands:: Preprocessor commands.
+* Index:: Index.
+@end menu
+@end ifinfo
+
+@node Overview
+@chapter What is GASP?
+
+The primary purpose of the @sc{gnu} assembler is to assemble the output of
+other programs---notably compilers. When you have to hand-code
+specialized routines in assembly, that means the @sc{gnu} assembler is
+an unfriendly processor: it has no directives for macros, conditionals,
+or many other conveniences that you might expect.
+
+In some cases you can simply use the C preprocessor, or a generalized
+preprocessor like @sc{m4}; but this can be awkward, since none of these
+things are designed with assembly in mind.
+
+@sc{gasp} fills this need. It is expressly designed to provide the
+facilities you need with hand-coded assembly code. Implementing it as a
+preprocessor, rather than part of the assembler, allows the maximum
+flexibility: you can use it with hand-coded assembly, without paying a
+penalty of added complexity in the assembler you use for compiler
+output.
+
+Here is a small example to give the flavor of @sc{gasp}. This input to
+@sc{gasp}
+
+@cartouche
+@example
+ .MACRO saveregs from=8 to=14
+count .ASSIGNA \from
+ ! save r\from..r\to
+ .AWHILE \&count LE \to
+ mov r\&count,@@-sp
+count .ASSIGNA \&count + 1
+ .AENDW
+ .ENDM
+
+ saveregs from=12
+
+bar: mov #H'dead+10,r0
+foo .SDATAC "hello"<10>
+ .END
+@end example
+@end cartouche
+
+@noindent
+generates this assembly program:
+
+@cartouche
+@example
+ ! save r12..r14
+ mov r12,@@-sp
+ mov r13,@@-sp
+ mov r14,@@-sp
+
+bar: mov #57005+10,r0
+foo: .byte 6,104,101,108,108,111,10
+@end example
+@end cartouche
+
+@node Invoking GASP
+@chapter Command Line Options
+
+@c FIXME! Or is there a simpler way, calling from GAS option?
+The simplest way to use @sc{gasp} is to run it as a filter and assemble
+its output. In Unix and its ilk, you can do this, for example:
+
+@c FIXME! GASP filename suffix convention?
+@example
+$ gasp prog.asm | as -o prog.o
+@end example
+
+Naturally, there are also a few command-line options to allow you to
+request variations on this basic theme. Here is the full set of
+possibilities for the @sc{gasp} command line.
+
+@example
+gasp [ -a | --alternate ]
+ [ -c @var{char} | --commentchar @var{char} ]
+ [ -d | --debug ] [ -h | --help ] [ -M | --mri ]
+ [ -o @var{outfile} | --output @var{outfile} ]
+ [ -p | --print ] [ -s | --copysource ]
+ [ -u | --unreasonable ] [ -v | --version ]
+ @var{infile} @dots{}
+@end example
+
+@ftable @code
+@item @var{infile} @dots{}
+@c FIXME! Why not stdin as default infile?
+The input file names. You must specify at least one input file; if you
+specify more, @sc{gasp} preprocesses them all, concatenating the output
+in the order you list the @var{infile} arguments.
+
+Mark the end of each input file with the preprocessor command
+@code{.END}. @xref{Other Commands,, Miscellaneous commands}.
+
+@item -a
+@itemx --alternate
+Use alternative macro syntax. @xref{Alternate,, Alternate macro
+syntax}, for a discussion of how this syntax differs from the default
+@sc{gasp} syntax.
+
+@cindex comment character, changing
+@cindex semicolon, as comment
+@cindex exclamation mark, as comment
+@cindex shriek, as comment
+@cindex bang, as comment
+@cindex @code{!} default comment char
+@cindex @code{;} as comment char
+@item -c '@var{char}'
+@itemx --commentchar '@var{char}'
+Use @var{char} as the comment character. The default comment character
+is @samp{!}. For example, to use a semicolon as the comment character,
+specify @w{@samp{-c ';'}} on the @sc{gasp} command line. Since
+assembler command characters often have special significance to command
+shells, it is a good idea to quote or escape @var{char} when you specify
+a comment character.
+
+For the sake of simplicity, all examples in this manual use the default
+comment character @samp{!}.
+
+@item -d
+@itemx --debug
+Show debugging statistics. In this version of @sc{gasp}, this option
+produces statistics about the string buffers that @sc{gasp} allocates
+internally. For each defined buffersize @var{s}, @sc{gasp} shows the
+number of strings @var{n} that it allocated, with a line like this:
+
+@example
+strings size @var{s} : @var{n}
+@end example
+
+@noindent
+@sc{gasp} displays these statistics on the standard error stream, when
+done preprocessing.
+
+@item -h
+@itemx --help
+Display a summary of the @sc{gasp} command line options.
+
+@item -M
+@itemx --mri
+Use MRI compatibility mode. Using this option causes @sc{gasp} to
+accept the syntax and pseudo-ops used by the Microtec Research
+@code{ASM68K} assembler.
+
+@item -o @var{outfile}
+@itemx --output @var{outfile}
+Write the output in a file called @var{outfile}. If you do not use the
+@samp{-o} option, @sc{gasp} writes its output on the standard output
+stream.
+
+@item -p
+@itemx --print
+Print line numbers. @sc{gasp} obeys this option @emph{only} if you also
+specify @samp{-s} to copy source lines to its output. With @samp{-s
+-p}, @sc{gasp} displays the line number of each source line copied
+(immediately after the comment character at the beginning of the line).
+
+@item -s
+@itemx --copysource
+Copy the source lines to the output file. Use this option
+to see the effect of each preprocessor line on the @sc{gasp} output.
+@sc{gasp} places a comment character (@samp{!} by default) at
+the beginning of each source line it copies, so that you can use this
+option and still assemble the result.
+
+@item -u
+@itemx --unreasonable
+Bypass ``unreasonable expansion'' limit. Since you can define @sc{gasp}
+macros inside other macro definitions, the preprocessor normally
+includes a sanity check. If your program requires more than 1,000
+nested expansions, @sc{gasp} normally exits with an error message. Use
+this option to turn off this check, allowing unlimited nested
+expansions.
+
+@item -v
+@itemx --version
+Display the @sc{gasp} version number.
+@end ftable
+
+@node Commands
+@chapter Preprocessor Commands
+
+@sc{gasp} commands have a straightforward syntax that fits in well with
+assembly conventions. In general, a command extends for a line, and may
+have up to three fields: an optional label, the command itself, and
+optional arguments to the command. You can write commands in upper or
+lower case, though this manual shows them in upper case. @xref{Syntax
+Details,, Details of the GASP syntax}, for more information.
+
+@menu
+* Conditionals::
+* Loops::
+* Variables::
+* Macros::
+* Data::
+* Listings::
+* Other Commands::
+* Syntax Details::
+* Alternate::
+@end menu
+
+@node Conditionals
+@section Conditional assembly
+
+The conditional-assembly directives allow you to include or exclude
+portions of an assembly depending on how a pair of expressions, or a
+pair of strings, compare.
+
+The overall structure of conditionals is familiar from many other
+contexts. @code{.AIF} marks the start of a conditional, and precedes
+assembly for the case when the condition is true. An optional
+@code{.AELSE} precedes assembly for the converse case, and an
+@code{.AENDI} marks the end of the condition.
+
+@c FIXME! Why doesn't -u turn off this check?
+You may nest conditionals up to a depth of 100; @sc{gasp} rejects
+nesting beyond that, because it may indicate a bug in your macro
+structure.
+
+@c FIXME! Why isn't there something like cpp's -D option? Conditionals
+@c would be much more useful if there were.
+Conditionals are primarily useful inside macro definitions, where you
+often need different effects depending on argument values.
+@xref{Macros,, Defining your own directives}, for details about defining
+macros.
+
+@ftable @code
+@item .AIF @var{expra} @var{cmp} @var{exprb}
+@itemx .AIF "@var{stra}" @var{cmp} "@var{strb}"
+
+The governing condition goes on the same line as the @code{.AIF}
+preprocessor command. You may compare either two strings, or two
+expressions.
+
+When you compare strings, only two conditional @var{cmp} comparison
+operators are available: @samp{EQ} (true if @var{stra} and @var{strb}
+are identical), and @samp{NE} (the opposite).
+
+When you compare two expressions, @emph{both expressions must be
+absolute} (@pxref{Expressions,, Arithmetic expressions in GASP}). You
+can use these @var{cmp} comparison operators with expressions:
+
+@ftable @code
+@item EQ
+Are @var{expra} and @var{exprb} equal? (For strings, are @var{stra} and
+@var{strb} identical?)
+
+@item NE
+Are @var{expra} and @var{exprb} different? (For strings, are @var{stra}
+and @var{strb} different?
+
+@item LT
+Is @var{expra} less than @var{exprb}? (Not allowed for strings.)
+
+@item LE
+Is @var{expra} less than or equal to @var{exprb}? (Not allowed for strings.)
+
+@item GT
+Is @var{expra} greater than @var{exprb}? (Not allowed for strings.)
+
+@item GE
+Is @var{expra} greater than or equal to @var{exprb}? (Not allowed for
+strings.)
+@end ftable
+
+@item .AELSE
+Marks the start of assembly code to be included if the condition fails.
+Optional, and only allowed within a conditional (between @code{.AIF} and
+@code{.AENDI}).
+
+@item .AENDI
+Marks the end of a conditional assembly.
+@end ftable
+
+@node Loops
+@section Repetitive sections of assembly
+
+Two preprocessor directives allow you to repeatedly issue copies of the
+same block of assembly code.
+
+@ftable @code
+@item .AREPEAT @var{aexp}
+@itemx .AENDR
+If you simply need to repeat the same block of assembly over and over a
+fixed number of times, sandwich one instance of the repeated block
+between @code{.AREPEAT} and @code{.AENDR}. Specify the number of
+copies as @var{aexp} (which must be an absolute expression). For
+example, this repeats two assembly statements three times in succession:
+
+@cartouche
+@example
+ .AREPEAT 3
+ rotcl r2
+ div1 r0,r1
+ .AENDR
+@end example
+@end cartouche
+
+@item .AWHILE @var{expra} @var{cmp} @var{exprb}
+@itemx .AENDW
+@itemx .AWHILE @var{stra} @var{cmp} @var{strb}
+@itemx .AENDW
+To repeat a block of assembly depending on a conditional test, rather
+than repeating it for a specific number of times, use @code{.AWHILE}.
+@code{.AENDW} marks the end of the repeated block. The conditional
+comparison works exactly the same way as for @code{.AIF}, with the same
+comparison operators (@pxref{Conditionals,, Conditional assembly}).
+
+Since the terms of the comparison must be absolute expression,
+@code{.AWHILE} is primarily useful within macros. @xref{Macros,,
+Defining your own directives}.
+@end ftable
+
+@cindex loops, breaking out of
+@cindex breaking out of loops
+You can use the @code{.EXITM} preprocessor directive to break out of
+loops early (as well as to break out of macros). @xref{Macros,,
+Defining your own directives}.
+
+@node Variables
+@section Preprocessor variables
+
+You can use variables in @sc{gasp} to represent strings, registers, or
+the results of expressions.
+
+You must distinguish two kinds of variables:
+@enumerate
+@item
+Variables defined with @code{.EQU} or @code{.ASSIGN}. To evaluate this
+kind of variable in your assembly output, simply mention its name. For
+example, these two lines define and use a variable @samp{eg}:
+
+@cartouche
+@example
+eg .EQU FLIP-64
+ @dots{}
+ mov.l eg,r0
+@end example
+@end cartouche
+
+@emph{Do not use} this kind of variable in conditional expressions or
+while loops; @sc{gasp} only evaluates these variables when writing
+assembly output.
+
+@item
+Variables for use during preprocessing. You can define these
+with @code{.ASSIGNC} or @code{.ASSIGNA}. To evaluate this
+kind of variable, write @samp{\&} before the variable name; for example,
+
+@cartouche
+@example
+opcit .ASSIGNA 47
+ @dots{}
+ .AWHILE \&opcit GT 0
+ @dots{}
+ .AENDW
+@end example
+@end cartouche
+
+@sc{gasp} treats macro arguments almost the same way, but to evaluate
+them you use the prefix @samp{\} rather than @samp{\&}.
+@xref{Macros,, Defining your own directives}.
+@end enumerate
+
+@ftable @code
+@item @var{pvar} .EQU @var{expr}
+@c FIXME! Anything to beware of re GAS directive of same name?
+Assign preprocessor variable @var{pvar} the value of the expression
+@var{expr}. There are no restrictions on redefinition; use @samp{.EQU}
+with the same @var{pvar} as often as you find it convenient.
+
+@item @var{pvar} .ASSIGN @var{expr}
+Almost the same as @code{.EQU}, save that you may not redefine
+@var{pvar} using @code{.ASSIGN} once it has a value.
+@c FIXME!! Supposed to work this way, apparently, but on 9feb94 works
+@c just like .EQU
+
+@item @var{pvar} .ASSIGNA @var{aexpr}
+Define a variable with a numeric value, for use during preprocessing.
+@var{aexpr} must be an absolute expression. You can redefine variables
+with @code{.ASSIGNA} at any time.
+
+@item @var{pvar} .ASSIGNC "@var{str}"
+Define a variable with a string value, for use during preprocessing.
+You can redefine variables with @code{.ASSIGNC} at any time.
+
+@item @var{pvar} .REG (@var{register})
+Use @code{.REG} to define a variable that represents a register. In
+particular, @var{register} is @emph{not evaluated} as an expression.
+You may use @code{.REG} at will to redefine register variables.
+@end ftable
+
+All these directives accept the variable name in the ``label'' position,
+that is at the left margin. You may specify a colon after the variable
+name if you wish; the first example above could have started @samp{eg:}
+with the same effect.
+
+@c pagebreak makes for better aesthetics---ensures macro and expansion together
+@page
+@node Macros
+@section Defining your own directives
+
+The commands @code{.MACRO} and @code{.ENDM} allow you to define macros
+that generate assembly output. You can use these macros with a syntax
+similar to built-in @sc{gasp} or assembler directives. For example,
+this definition specifies a macro @code{SUM} that adds together a range of
+consecutive registers:
+
+@cartouche
+@example
+ .MACRO SUM FROM=0, TO=9
+ ! \FROM \TO
+ mov r\FROM,r10
+COUNT .ASSIGNA \FROM+1
+ .AWHILE \&COUNT LE \TO
+ add r\&COUNT,r10
+COUNT .ASSIGNA \&COUNT+1
+ .AENDW
+ .ENDM
+@end example
+@end cartouche
+
+@noindent
+With that definition, @samp{SUM 0,5} generates this assembly output:
+
+@cartouche
+@example
+ ! 0 5
+ mov r0,r10
+ add r1,r10
+ add r2,r10
+ add r3,r10
+ add r4,r10
+ add r5,r10
+@end example
+@end cartouche
+
+@ftable @code
+@item .MACRO @var{macname}
+@itemx .MACRO @var{macname} @var{macargs} @dots{}
+Begin the definition of a macro called @var{macname}. If your macro
+definition requires arguments, specify their names after the macro name,
+separated by commas or spaces. You can supply a default value for any
+macro argument by following the name with @samp{=@var{deflt}}. For
+example, these are all valid @code{.MACRO} statements:
+
+@table @code
+@item .MACRO COMM
+Begin the definition of a macro called @code{COMM}, which takes no
+arguments.
+
+@item .MACRO PLUS1 P, P1
+@itemx .MACRO PLUS1 P P1
+Either statement begins the definition of a macro called @code{PLUS1},
+which takes two arguments; within the macro definition, write
+@samp{\P} or @samp{\P1} to evaluate the arguments.
+
+@item .MACRO RESERVE_STR P1=0 P2
+Begin the definition of a macro called @code{RESERVE_STR}, with two
+arguments. The first argument has a default value, but not the second.
+After the definition is complete, you can call the macro either as
+@samp{RESERVE_STR @var{a},@var{b}} (with @samp{\P1} evaluating to
+@var{a} and @samp{\P2} evaluating to @var{b}), or as @samp{RESERVE_STR
+,@var{b}} (with @samp{\P1} evaluating as the default, in this case
+@samp{0}, and @samp{\P2} evaluating to @var{b}).
+@end table
+
+When you call a macro, you can specify the argument values either by
+position, or by keyword. For example, @samp{SUM 9,17} is equivalent to
+@samp{SUM TO=17, FROM=9}. Macro arguments are preprocessor variables
+similar to the variables you define with @samp{.ASSIGNA} or
+@samp{.ASSIGNC}; in particular, you can use them in conditionals or for
+loop control. (The only difference is the prefix you write to evaluate
+the variable: for a macro argument, write @samp{\@var{argname}}, but for
+a preprocessor variable, write @samp{\&@var{varname}}.)
+
+@item @var{name} .MACRO
+@itemx @var{name} .MACRO ( @var{macargs} @dots{} )
+@c FIXME check: I think no error _and_ no args recognized if I use form
+@c NAME .MACRO ARG ARG
+An alternative form of introducing a macro definition: specify the macro
+name in the label position, and the arguments (if any) between
+parentheses after the name. Defaulting rules and usage work the same
+way as for the other macro definition syntax.
+
+@item .ENDM
+Mark the end of a macro definition.
+
+@item .EXITM
+Exit early from the current macro definition, @code{.AREPEAT} loop, or
+@code{.AWHILE} loop.
+
+@cindex number of macros executed
+@cindex macros, count executed
+@item \@@
+@sc{gasp} maintains a counter of how many macros it has
+executed in this pseudo-variable; you can copy that number to your
+output with @samp{\@@}, but @emph{only within a macro definition}.
+
+@item LOCAL @var{name} [ , @dots{} ]
+@emph{Warning: @code{LOCAL} is only available if you select ``alternate
+macro syntax'' with @samp{-a} or @samp{--alternate}.} @xref{Alternate,,
+Alternate macro syntax}.
+
+Generate a string replacement for each of the @var{name} arguments, and
+replace any instances of @var{name} in each macro expansion. The
+replacement string is unique in the assembly, and different for each
+separate macro expansion. @code{LOCAL} allows you to write macros that
+define symbols, without fear of conflict between separate macro expansions.
+@end ftable
+
+@node Data
+@section Data output
+
+In assembly code, you often need to specify working areas of memory;
+depending on the application, you may want to initialize such memory or
+not. @sc{gasp} provides preprocessor directives to help you avoid
+repetitive coding for both purposes.
+
+You can use labels as usual to mark the data areas.
+
+@menu
+* Initialized::
+* Uninitialized::
+@end menu
+
+@node Initialized
+@subsection Initialized data
+
+These are the @sc{gasp} directives for initialized data, and the standard
+@sc{gnu} assembler directives they expand to:
+
+@ftable @code
+@item .DATA @var{expr}, @var{expr}, @dots{}
+@itemx .DATA.B @var{expr}, @var{expr}, @dots{}
+@itemx .DATA.W @var{expr}, @var{expr}, @dots{}
+@itemx .DATA.L @var{expr}, @var{expr}, @dots{}
+Evaluate arithmetic expressions @var{expr}, and emit the corresponding
+@code{as} directive (labelled with @var{lab}). The unqualified
+@code{.DATA} emits @samp{.long}; @code{.DATA.B} emits @samp{.byte};
+@code{.DATA.W} emits @samp{.short}; and @code{.DATA.L} emits
+@samp{.long}.
+
+For example, @samp{foo .DATA 1,2,3} emits @samp{foo: .long 1,2,3}.
+
+@item .DATAB @var{repeat}, @var{expr}
+@itemx .DATAB.B @var{repeat}, @var{expr}
+@itemx .DATAB.W @var{repeat}, @var{expr}
+@itemx .DATAB.L @var{repeat}, @var{expr}
+@c FIXME! Looks like gasp accepts and ignores args after 2nd.
+Make @code{as} emit @var{repeat} copies of the value of the expression
+@var{expr} (using the @code{as} directive @code{.fill}).
+@samp{.DATAB.B} repeats one-byte values; @samp{.DATAB.W} repeats
+two-byte values; and @samp{.DATAB.L} repeats four-byte values.
+@samp{.DATAB} without a suffix repeats four-byte values, just like
+@samp{.DATAB.L}.
+
+@c FIXME! Allowing zero might be useful for edge conditions in macros.
+@var{repeat} must be an absolute expression with a positive value.
+
+@item .SDATA "@var{str}" @dots{}
+String data. Emits a concatenation of bytes, precisely as you specify
+them (in particular, @emph{nothing is added to mark the end} of the
+string). @xref{Constants,, String and numeric constants}, for details
+about how to write strings. @code{.SDATA} concatenates multiple
+arguments, making it easy to switch between string representations. You
+can use commas to separate the individual arguments for clarity, if you
+choose.
+
+@item .SDATAB @var{repeat}, "@var{str}" @dots{}
+Repeated string data. The first argument specifies how many copies of
+the string to emit; the remaining arguments specify the string, in the
+same way as the arguments to @code{.SDATA}.
+
+@item .SDATAZ "@var{str}" @dots{}
+Zero-terminated string data. Just like @code{.SDATA}, except that
+@code{.SDATAZ} writes a zero byte at the end of the string.
+
+@item .SDATAC "@var{str}" @dots{}
+Count-prefixed string data. Just like @code{.SDATA}, except that
+@sc{gasp} precedes the string with a leading one-byte count. For
+example, @samp{.SDATAC "HI"} generates @samp{.byte 2,72,73}. Since the
+count field is only one byte, you can only use @code{.SDATAC} for
+strings less than 256 bytes in length.
+@end ftable
+
+@node Uninitialized
+@subsection Uninitialized data
+
+@c FIXME! .space different on some platforms, notably HPPA. Config?
+Use the @code{.RES}, @code{.SRES}, @code{.SRESC}, and @code{.SRESZ}
+directives to reserve memory and leave it uninitialized. @sc{gasp}
+resolves these directives to appropriate calls of the @sc{gnu}
+@code{as} @code{.space} directive.
+
+@ftable @code
+@item .RES @var{count}
+@itemx .RES.B @var{count}
+@itemx .RES.W @var{count}
+@itemx .RES.L @var{count}
+Reserve room for @var{count} uninitialized elements of data. The
+suffix specifies the size of each element: @code{.RES.B} reserves
+@var{count} bytes, @code{.RES.W} reserves @var{count} pairs of bytes,
+and @code{.RES.L} reserves @var{count} quartets. @code{.RES} without a
+suffix is equivalent to @code{.RES.L}.
+
+@item .SRES @var{count}
+@itemx .SRES.B @var{count}
+@itemx .SRES.W @var{count}
+@itemx .SRES.L @var{count}
+@c FIXME! This is boring. Shouldn't it at least have a different
+@c default size? (e.g. the "S" suggests "string", for which .B
+@c would be more appropriate)
+@code{.SRES} is a synonym for @samp{.RES}.
+
+@item .SRESC @var{count}
+@itemx .SRESC.B @var{count}
+@itemx .SRESC.W @var{count}
+@itemx .SRESC.L @var{count}
+Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
+
+@item .SRESZ @var{count}
+@itemx .SRESZ.B @var{count}
+@itemx .SRESZ.W @var{count}
+@itemx .SRESZ.L @var{count}
+Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
+@end ftable
+
+@node Listings
+@section Assembly listing control
+
+The @sc{gasp} listing-control directives correspond to
+related @sc{gnu} @code{as} directives.
+
+@ftable @code
+@item .PRINT LIST
+@itemx .PRINT NOLIST
+Print control. This directive emits the @sc{gnu} @code{as} directive
+@code{.list} or @code{.nolist}, according to its argument. @xref{List,,
+@code{.list}, as.info, Using as}, for details on how these directives
+interact.
+
+@item .FORM LIN=@var{ln}
+@itemx .FORM COL=@var{cols}
+@itemx .FORM LIN=@var{ln} COL=@var{cols}
+Specify the page size for assembly listings: @var{ln} represents the
+number of lines, and @var{cols} the number of columns. You may specify
+either page dimension independently, or both together. If you do not
+specify the number of lines, @sc{gasp} assumes 60 lines; if you do not
+specify the number of columns, @sc{gasp} assumes 132 columns.
+(Any values you may have specified in previous instances of @code{.FORM}
+do @emph{not} carry over as defaults.) Emits the @code{.psize}
+assembler directive.
+
+@item .HEADING @var{string}
+Specify @var{string} as the title of your assembly listings. Emits
+@samp{.title "@var{string}"}.
+
+@item .PAGE
+Force a new page in assembly listings. Emits @samp{.eject}.
+@end ftable
+
+@node Other Commands
+@section Miscellaneous commands
+
+@ftable @code
+@item .ALTERNATE
+Use the alternate macro syntax henceforth in the assembly.
+@xref{Alternate,, Alternate macro syntax}.
+
+@item .ORG
+@c FIXME! This is very strange, since _GAS_ understands .org
+This command is recognized, but not yet implemented. @sc{gasp}
+generates an error message for programs that use @code{.ORG}.
+
+@item .RADIX @var{s}
+@c FIXME no test cases in testsuite/gasp
+@sc{gasp} understands numbers in any of base two, eight, ten, or
+sixteen. You can encode the base explicitly in any numeric constant
+(@pxref{Constants,, String and numeric constants}). If you write
+numbers without an explicit indication of the base, the most recent
+@samp{.RADIX @var{s}} command determines how they are interpreted.
+@var{s} is a single letter, one of the following:
+
+@table @code
+@item .RADIX B
+Base 2.
+
+@item .RADIX Q
+Base 8.
+
+@item .RADIX D
+Base 10. This is the original default radix.
+
+@item .RADIX H
+Base 16.
+@end table
+
+You may specify the argument @var{s} in lower case (any of @samp{bqdh})
+with the same effects.
+
+@item .EXPORT @var{name}
+@itemx .GLOBAL @var{name}
+@c FIXME! No test cases in testsuite/gasp
+Declare @var{name} global (emits @samp{.global @var{name}}). The two
+directives are synonymous.
+
+@item .PROGRAM
+No effect: @sc{gasp} accepts this directive, and silently ignores it.
+
+@item .END
+Mark end of each preprocessor file. @sc{gasp} issues a warning if it
+reaches end of file without seeing this command.
+
+@item .INCLUDE "@var{str}"
+Preprocess the file named by @var{str}, as if its contents appeared
+where the @code{.INCLUDE} directive does. @sc{gasp} imposes a maximum
+limit of 30 stacked include files, as a sanity check.
+@c FIXME! Why is include depth not affected by -u?
+
+@item .ALIGN @var{size}
+@c FIXME! Why is this not utterly pointless?
+Evaluate the absolute expression @var{size}, and emit the assembly
+instruction @samp{.align @var{size}} using the result.
+@end ftable
+
+@node Syntax Details
+@section Details of the GASP syntax
+
+Since @sc{gasp} is meant to work with assembly code, its statement
+syntax has no surprises for the assembly programmer.
+
+@cindex whitespace
+@emph{Whitespace} (blanks or tabs; @emph{not} newline) is partially
+significant, in that it delimits up to three fields in a line. The
+amount of whitespace does not matter; you may line up fields in separate
+lines if you wish, but @sc{gasp} does not require that.
+
+@cindex fields of @sc{gasp} source line
+@cindex label field
+The @emph{first field}, an optional @dfn{label}, must be flush left in a
+line (with no leading whitespace) if it appears at all. You may use a
+colon after the label if you wish; @sc{gasp} neither requires the colon
+nor objects to it (but will not include it as part of the label name).
+
+@cindex directive field
+The @emph{second field}, which must appear after some whitespace,
+contains a @sc{gasp} or assembly @dfn{directive}.
+
+@cindex argument fields
+Any @emph{further fields} on a line are @dfn{arguments} to the
+directive; you can separate them from one another using either commas or
+whitespace.
+
+@menu
+* Markers::
+* Constants::
+* Symbols::
+* Expressions::
+* String Builtins::
+@end menu
+
+@node Markers
+@subsection Special syntactic markers
+
+@sc{gasp} recognizes a few special markers: to delimit comments, to
+continue a statement on the next line, to separate symbols from other
+characters, and to copy text to the output literally. (One other
+special marker, @samp{\@@}, works only within macro definitions;
+@pxref{Macros,, Defining your own directives}.)
+
+@cindex comments
+The trailing part of any @sc{gasp} source line may be a @dfn{comment}.
+A comment begins with the first unquoted comment character (@samp{!} by
+default), or an escaped or doubled comment character (@samp{\!} or
+@samp{!!} by default), and extends to the end of a line. You can
+specify what comment character to use with the @samp{-c} option
+(@pxref{Invoking GASP,, Command Line Options}). The two kinds of
+comment markers lead to slightly different treatment:
+
+@table @code
+@item !
+A single, un-escaped comment character generates an assembly comment in
+the @sc{gasp} output. @sc{gasp} evaluates any preprocessor variables
+(macro arguments, or variables defined with @code{.ASSIGNA} or
+@code{.ASSIGNC}) present. For example, a macro that begins like this
+
+@example
+ .MACRO SUM FROM=0, TO=9
+ ! \FROM \TO
+@end example
+
+@noindent
+issues as the first line of output a comment that records the
+values you used to call the macro.
+
+@c comments, preprocessor-only
+@c preprocessor-only comments
+@c GASP-only comments
+@item \!
+@itemx !!
+Either an escaped comment character, or a double comment character,
+marks a @sc{gasp} source comment. @sc{gasp} does not copy such comments
+to the assembly output.
+@end table
+
+@cindex continuation character
+@kindex +
+To @emph{continue a statement} on the next line of the file, begin the
+second line with the character @samp{+}.
+
+@cindex literal copy to output
+@cindex copying literally to output
+@cindex preprocessing, avoiding
+@cindex avoiding preprocessing
+Occasionally you may want to prevent @sc{gasp} from preprocessing some
+particular bit of text. To @emph{copy literally} from the @sc{gasp}
+source to its output, place @samp{\(} before the string to copy, and
+@samp{)} at the end. For example, write @samp{\(\!)} if you need the
+characters @samp{\!} in your assembly output.
+
+@cindex symbol separator
+@cindex text, separating from symbols
+@cindex symbols, separating from text
+To @emph{separate a preprocessor variable} from text to appear
+immediately after its value, write a single quote (@code{'}). For
+example, @samp{.SDATA "\P'1"} writes a string built by concatenating the
+value of @code{P} and the digit @samp{1}. (You cannot achieve this by
+writing just @samp{\P1}, since @samp{P1} is itself a valid name for a
+preprocessor variable.)
+
+@node Constants
+@subsection String and numeric constants
+
+There are two ways of writing @dfn{string constants} in @sc{gasp}: as
+literal text, and by numeric byte value. Specify a string literal
+between double quotes (@code{"@var{str}"}). Specify an individual
+numeric byte value as an absolute expression between angle brackets
+(@code{<@var{expr}>}. Directives that output strings allow you to
+specify any number of either kind of value, in whatever order is
+convenient, and concatenate the result. (Alternate syntax mode
+introduces a number of alternative string notations; @pxref{Alternate,,
+Alternate macro syntax}.)
+
+@c Details of numeric notation, e.g. base prefixes
+You can write @dfn{numeric constants} either in a specific base, or in
+whatever base is currently selected (either 10, or selected by the most
+recent @code{.RADIX}).
+
+To write a number in a @emph{specific base}, use the pattern
+@code{@var{s}'@var{ddd}}: a base specifier character @var{s}, followed
+by a single quote followed by digits @var{ddd}. The base specifier
+character matches those you can specify with @code{.RADIX}: @samp{B} for
+base 2, @samp{Q} for base 8, @samp{D} for base 10, and @samp{H} for base
+16. (You can write this character in lower case if you prefer.)
+
+@c FIXME! What are rules for recognizing number in deflt base? Whatever
+@c is left over after parsing other things??
+
+@node Symbols
+@subsection Symbols
+
+@sc{gasp} recognizes symbol names that start with any alphabetic character,
+@samp{_}, or @samp{$}, and continue with any of the same characters or
+with digits. Label names follow the same rules.
+
+@node Expressions
+@subsection Arithmetic expressions in GASP
+
+@cindex absolute expressions
+@cindex relocatable expressions
+There are two kinds of expressions, depending on their result:
+@dfn{absolute} expressions, which resolve to a constant (that is, they
+do not involve any values unknown to @sc{gasp}), and @dfn{relocatable}
+expressions, which must reduce to the form
+
+@example
+@var{addsym}+@var{const}-@var{subsym}
+@end example
+
+@noindent
+where @var{addsym} and @var{subsym} are assembly symbols of unknown
+value, and @var{const} is a constant.
+
+Arithmetic for @sc{gasp} expressions follows very similar rules to C.
+You can use parentheses to change precedence; otherwise, arithmetic
+primitives have decreasing precedence in the order of the following
+list.
+
+@enumerate
+@item
+Single-argument @code{+} (identity), @code{-} (arithmetic opposite), or
+@code{~} (bitwise negation). @emph{The argument must be an absolute
+expression.}
+
+@item
+@code{*} (multiplication) and @code{/} (division). @emph{Both arguments
+must be absolute expressions.}
+
+@item
+@code{+} (addition) and @code{-} (subtraction). @emph{At least one argument
+must be absolute.}
+@c FIXME! Actually, subtraction doesn't check for this.
+
+@item
+@code{&} (bitwise and). @emph{Both arguments must be absolute.}
+
+@item
+@c FIXME! I agree ~ is a better notation than ^ for xor, but is the
+@c improvement worth differing from C?
+@code{|} (bitwise or) and @code{~} (bitwise exclusive or; @code{^} in
+C). @emph{Both arguments must be absolute.}
+@end enumerate
+
+@node String Builtins
+@subsection String primitives
+
+You can use these primitives to manipulate strings (in the argument
+field of @sc{gasp} statements):
+
+@ftable @code
+@item .LEN("@var{str}")
+Calculate the length of string @code{"@var{str}"}, as an absolute
+expression. For example, @samp{.RES.B .LEN("sample")} reserves six
+bytes of memory.
+
+@item .INSTR("@var{string}", "@var{seg}", @var{ix})
+Search for the first occurrence of @var{seg} after position @var{ix} of
+@var{string}. For example, @samp{.INSTR("ABCDEFG", "CDE", 0)} evaluates
+to the absolute result @code{2}.
+
+The result is @code{-1} if @var{seg} does not occur in @var{string}
+after position @var{ix}.
+
+@item .SUBSTR("@var{string}",@var{start},@var{len})
+The substring of @var{string} beginning at byte number @var{start} and
+extending for @var{len} bytes.
+@end ftable
+
+@node Alternate
+@section Alternate macro syntax
+
+If you specify @samp{-a} or @samp{--alternate} on the @sc{gasp} command
+line, the preprocessor uses somewhat different syntax. This syntax is
+reminiscent of the syntax of Phar Lap macro assembler, but it
+is @emph{not} meant to be a full emulation of Phar Lap or similar
+assemblers. In particular, @sc{gasp} does not support directives such
+as @code{DB} and @code{IRP}, even in alternate syntax mode.
+
+In particular, @samp{-a} (or @samp{--alternate}) elicits these
+differences:
+
+@table @emph
+@item Preprocessor directives
+You can use @sc{gasp} preprocessor directives without a leading @samp{.}
+dot. For example, you can write @samp{SDATA} with the same effect as
+@samp{.SDATA}.
+
+@item LOCAL
+One additional directive, @code{LOCAL}, is available. @xref{Macros,,
+Defining your own directives}, for an explanation of how to use
+@code{LOCAL}.
+
+@need 2000
+@item String delimiters
+You can write strings delimited in these other ways besides
+@code{"@var{string}"}:
+
+@table @code
+@item '@var{string}'
+You can delimit strings with single-quote charaters.
+
+@item <@var{string}>
+You can delimit strings with matching angle brackets.
+@end table
+
+@item single-character string escape
+To include any single character literally in a string (even if the
+character would otherwise have some special meaning), you can prefix the
+character with @samp{!} (an exclamation mark). For example, you can
+write @samp{<4.3 !> 5.4!!>} to get the literal text @samp{4.3 > 5.4!}.
+
+@item Expression results as strings
+You can write @samp{%@var{expr}} to evaluate the expression @var{expr}
+and use the result as a string.
+@end table
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/gas/doc/h8.texi b/gas/doc/h8.texi
new file mode 100644
index 00000000000..0df17144bfc
--- /dev/null
+++ b/gas/doc/h8.texi
@@ -0,0 +1,26 @@
+@clear ALL-ARCH
+@clear GENERIC
+@clear INTERNALS
+@clear MULTI-OBJ
+@clear AOUT
+@clear BOUT
+@set COFF
+@clear ELF
+@set Hitachi-all
+@set H8/300
+@set H8/500
+@set SH
+@clear DIFF-TBL-KLUGE
+@set IEEEFLOAT
+@clear W32
+@set W16
+@set SPECIAL-SYMS
+@set AS as
+@set GCC gcc
+@set LD ld
+@set TARGET H8/300 and H8/500
+@set TARGET H8/300, H8/500, and Hitachi SH
+@set OBJ-NAME COFF
+@c
+@clear have-stabs
+@set abnormal-separator
diff --git a/gas/doc/internals.texi b/gas/doc/internals.texi
new file mode 100644
index 00000000000..dd3b4ab15eb
--- /dev/null
+++ b/gas/doc/internals.texi
@@ -0,0 +1,1557 @@
+\input texinfo
+@setfilename internals.info
+@node Top
+@top Assembler Internals
+@raisesections
+@cindex internals
+
+This chapter describes the internals of the assembler. It is incomplete, but
+it may help a bit.
+
+This chapter was last modified on $Date$. It is not updated regularly, and it
+may be out of date.
+
+@menu
+* GAS versions:: GAS versions
+* Data types:: Data types
+* GAS processing:: What GAS does when it runs
+* Porting GAS:: Porting GAS
+* Relaxation:: Relaxation
+* Broken words:: Broken words
+* Internal functions:: Internal functions
+* Test suite:: Test suite
+@end menu
+
+@node GAS versions
+@section GAS versions
+
+GAS has acquired layers of code over time. The original GAS only supported the
+a.out object file format, with three sections. Support for multiple sections
+has been added in two different ways.
+
+The preferred approach is to use the version of GAS created when the symbol
+@code{BFD_ASSEMBLER} is defined. The other versions of GAS are documented for
+historical purposes, and to help anybody who has to debug code written for
+them.
+
+The type @code{segT} is used to represent a section in code which must work
+with all versions of GAS.
+
+@menu
+* Original GAS:: Original GAS version
+* MANY_SEGMENTS:: MANY_SEGMENTS gas version
+* BFD_ASSEMBLER:: BFD_ASSEMBLER gas version
+@end menu
+
+@node Original GAS
+@subsection Original GAS
+
+The original GAS only supported the a.out object file format with three
+sections: @samp{.text}, @samp{.data}, and @samp{.bss}. This is the version of
+GAS that is compiled if neither @code{BFD_ASSEMBLER} nor @code{MANY_SEGMENTS}
+is defined. This version of GAS is still used for the m68k-aout target, and
+perhaps others.
+
+This version of GAS should not be used for any new development.
+
+There is still code that is specific to this version of GAS, notably in
+@file{write.c}. There is no way for this code to loop through all the
+sections; it simply looks at global variables like @code{text_frag_root} and
+@code{data_frag_root}.
+
+The type @code{segT} is an enum.
+
+@node MANY_SEGMENTS
+@subsection MANY_SEGMENTS gas version
+@cindex MANY_SEGMENTS
+
+The @code{MANY_SEGMENTS} version of gas is only used for COFF. It uses the BFD
+library, but it writes out all the data itself using @code{bfd_write}. This
+version of gas supports up to 40 normal sections. The section names are stored
+in the @code{seg_name} array. Other information is stored in the
+@code{segment_info} array.
+
+The type @code{segT} is an enum. Code that wants to examine all the sections
+can use a @code{segT} variable as loop index from @code{SEG_E0} up to but not
+including @code{SEG_UNKNOWN}.
+
+Most of the code specific to this version of GAS is in the file
+@file{config/obj-coff.c}, in the portion of that file that is compiled when
+@code{BFD_ASSEMBLER} is not defined.
+
+This version of GAS is still used for several COFF targets.
+
+@node BFD_ASSEMBLER
+@subsection BFD_ASSEMBLER gas version
+@cindex BFD_ASSEMBLER
+
+The preferred version of GAS is the @code{BFD_ASSEMBLER} version. In this
+version of GAS, the output file is a normal BFD, and the BFD routines are used
+to generate the output.
+
+@code{BFD_ASSEMBLER} will automatically be used for certain targets, including
+those that use the ELF, ECOFF, and SOM object file formats, and also all Alpha,
+MIPS, PowerPC, and SPARC targets. You can force the use of
+@code{BFD_ASSEMBLER} for other targets with the configure option
+@samp{--enable-bfd-assembler}; however, it has not been tested for many
+targets, and can not be assumed to work.
+
+@node Data types
+@section Data types
+@cindex internals, data types
+
+This section describes some fundamental GAS data types.
+
+@menu
+* Symbols:: The symbolS structure
+* Expressions:: The expressionS structure
+* Fixups:: The fixS structure
+* Frags:: The fragS structure
+@end menu
+
+@node Symbols
+@subsection Symbols
+@cindex internals, symbols
+@cindex symbols, internal
+@cindex symbolS structure
+
+The definition for @code{struct symbol}, also known as @code{symbolS}, is
+located in @file{struc-symbol.h}. Symbol structures contain the following
+fields:
+
+@table @code
+@item sy_value
+This is an @code{expressionS} that describes the value of the symbol. It might
+refer to one or more other symbols; if so, its true value may not be known
+until @code{resolve_symbol_value} is called in @code{write_object_file}.
+
+The expression is often simply a constant. Before @code{resolve_symbol_value}
+is called, the value is the offset from the frag (@pxref{Frags}). Afterward,
+the frag address has been added in.
+
+@item sy_resolved
+This field is non-zero if the symbol's value has been completely resolved. It
+is used during the final pass over the symbol table.
+
+@item sy_resolving
+This field is used to detect loops while resolving the symbol's value.
+
+@item sy_used_in_reloc
+This field is non-zero if the symbol is used by a relocation entry. If a local
+symbol is used in a relocation entry, it must be possible to redirect those
+relocations to other symbols, or this symbol cannot be removed from the final
+symbol list.
+
+@item sy_next
+@itemx sy_previous
+These pointers to other @code{symbolS} structures describe a singly or doubly
+linked list. (If @code{SYMBOLS_NEED_BACKPOINTERS} is not defined, the
+@code{sy_previous} field will be omitted; @code{SYMBOLS_NEED_BACKPOINTERS} is
+always defined if @code{BFD_ASSEMBLER}.) These fields should be accessed with
+the @code{symbol_next} and @code{symbol_previous} macros.
+
+@item sy_frag
+This points to the frag (@pxref{Frags}) that this symbol is attached to.
+
+@item sy_used
+Whether the symbol is used as an operand or in an expression. Note: Not all of
+the backends keep this information accurate; backends which use this bit are
+responsible for setting it when a symbol is used in backend routines.
+
+@item sy_mri_common
+Whether the symbol is an MRI common symbol created by the @code{COMMON}
+pseudo-op when assembling in MRI mode.
+
+@item bsym
+If @code{BFD_ASSEMBLER} is defined, this points to the BFD @code{asymbol} that
+will be used in writing the object file.
+
+@item sy_name_offset
+(Only used if @code{BFD_ASSEMBLER} is not defined.) This is the position of
+the symbol's name in the string table of the object file. On some formats,
+this will start at position 4, with position 0 reserved for unnamed symbols.
+This field is not used until @code{write_object_file} is called.
+
+@item sy_symbol
+(Only used if @code{BFD_ASSEMBLER} is not defined.) This is the
+format-specific symbol structure, as it would be written into the object file.
+
+@item sy_number
+(Only used if @code{BFD_ASSEMBLER} is not defined.) This is a 24-bit symbol
+number, for use in constructing relocation table entries.
+
+@item sy_obj
+This format-specific data is of type @code{OBJ_SYMFIELD_TYPE}. If no macro by
+that name is defined in @file{obj-format.h}, this field is not defined.
+
+@item sy_tc
+This processor-specific data is of type @code{TC_SYMFIELD_TYPE}. If no macro
+by that name is defined in @file{targ-cpu.h}, this field is not defined.
+
+@item TARGET_SYMBOL_FIELDS
+If this macro is defined, it defines additional fields in the symbol structure.
+This macro is obsolete, and should be replaced when possible by uses of
+@code{OBJ_SYMFIELD_TYPE} and @code{TC_SYMFIELD_TYPE}.
+@end table
+
+There are a number of access routines used to extract the fields of a
+@code{symbolS} structure. When possible, these routines should be used rather
+than referring to the fields directly. These routines will work for any GAS
+version.
+
+@table @code
+@item S_SET_VALUE
+@cindex S_SET_VALUE
+Set the symbol's value.
+
+@item S_GET_VALUE
+@cindex S_GET_VALUE
+Get the symbol's value. This will cause @code{resolve_symbol_value} to be
+called if necessary, so @code{S_GET_VALUE} should only be called when it is
+safe to resolve symbols (i.e., after the entire input file has been read and
+all symbols have been defined).
+
+@item S_SET_SEGMENT
+@cindex S_SET_SEGMENT
+Set the section of the symbol.
+
+@item S_GET_SEGMENT
+@cindex S_GET_SEGMENT
+Get the symbol's section.
+
+@item S_GET_NAME
+@cindex S_GET_NAME
+Get the name of the symbol.
+
+@item S_SET_NAME
+@cindex S_SET_NAME
+Set the name of the symbol.
+
+@item S_IS_EXTERNAL
+@cindex S_IS_EXTERNAL
+Return non-zero if the symbol is externally visible.
+
+@item S_IS_EXTERN
+@cindex S_IS_EXTERN
+A synonym for @code{S_IS_EXTERNAL}. Don't use it.
+
+@item S_IS_WEAK
+@cindex S_IS_WEAK
+Return non-zero if the symbol is weak.
+
+@item S_IS_COMMON
+@cindex S_IS_COMMON
+Return non-zero if this is a common symbol. Common symbols are sometimes
+represented as undefined symbols with a value, in which case this function will
+not be reliable.
+
+@item S_IS_DEFINED
+@cindex S_IS_DEFINED
+Return non-zero if this symbol is defined. This function is not reliable when
+called on a common symbol.
+
+@item S_IS_DEBUG
+@cindex S_IS_DEBUG
+Return non-zero if this is a debugging symbol.
+
+@item S_IS_LOCAL
+@cindex S_IS_LOCAL
+Return non-zero if this is a local assembler symbol which should not be
+included in the final symbol table. Note that this is not the opposite of
+@code{S_IS_EXTERNAL}. The @samp{-L} assembler option affects the return value
+of this function.
+
+@item S_SET_EXTERNAL
+@cindex S_SET_EXTERNAL
+Mark the symbol as externally visible.
+
+@item S_CLEAR_EXTERNAL
+@cindex S_CLEAR_EXTERNAL
+Mark the symbol as not externally visible.
+
+@item S_SET_WEAK
+@cindex S_SET_WEAK
+Mark the symbol as weak.
+
+@item S_GET_TYPE
+@item S_GET_DESC
+@item S_GET_OTHER
+@cindex S_GET_TYPE
+@cindex S_GET_DESC
+@cindex S_GET_OTHER
+Get the @code{type}, @code{desc}, and @code{other} fields of the symbol. These
+are only defined for object file formats for which they make sense (primarily
+a.out).
+
+@item S_SET_TYPE
+@item S_SET_DESC
+@item S_SET_OTHER
+@cindex S_SET_TYPE
+@cindex S_SET_DESC
+@cindex S_SET_OTHER
+Set the @code{type}, @code{desc}, and @code{other} fields of the symbol. These
+are only defined for object file formats for which they make sense (primarily
+a.out).
+
+@item S_GET_SIZE
+@cindex S_GET_SIZE
+Get the size of a symbol. This is only defined for object file formats for
+which it makes sense (primarily ELF).
+
+@item S_SET_SIZE
+@cindex S_SET_SIZE
+Set the size of a symbol. This is only defined for object file formats for
+which it makes sense (primarily ELF).
+@end table
+
+@node Expressions
+@subsection Expressions
+@cindex internals, expressions
+@cindex expressions, internal
+@cindex expressionS structure
+
+Expressions are stored in an @code{expressionS} structure. The structure is
+defined in @file{expr.h}.
+
+@cindex expression
+The macro @code{expression} will create an @code{expressionS} structure based
+on the text found at the global variable @code{input_line_pointer}.
+
+@cindex make_expr_symbol
+@cindex expr_symbol_where
+A single @code{expressionS} structure can represent a single operation.
+Complex expressions are formed by creating @dfn{expression symbols} and
+combining them in @code{expressionS} structures. An expression symbol is
+created by calling @code{make_expr_symbol}. An expression symbol should
+naturally never appear in a symbol table, and the implementation of
+@code{S_IS_LOCAL} (@pxref{Symbols}) reflects that. The function
+@code{expr_symbol_where} returns non-zero if a symbol is an expression symbol,
+and also returns the file and line for the expression which caused it to be
+created.
+
+The @code{expressionS} structure has two symbol fields, a number field, an
+operator field, and a field indicating whether the number is unsigned.
+
+The operator field is of type @code{operatorT}, and describes how to interpret
+the other fields; see the definition in @file{expr.h} for the possibilities.
+
+An @code{operatorT} value of @code{O_big} indicates either a floating point
+number, stored in the global variable @code{generic_floating_point_number}, or
+an integer to large to store in an @code{offsetT} type, stored in the global
+array @code{generic_bignum}. This rather inflexible approach makes it
+impossible to use floating point numbers or large expressions in complex
+expressions.
+
+@node Fixups
+@subsection Fixups
+@cindex internals, fixups
+@cindex fixups
+@cindex fixS structure
+
+A @dfn{fixup} is basically anything which can not be resolved in the first
+pass. Sometimes a fixup can be resolved by the end of the assembly; if not,
+the fixup becomes a relocation entry in the object file.
+
+@cindex fix_new
+@cindex fix_new_exp
+A fixup is created by a call to @code{fix_new} or @code{fix_new_exp}. Both
+take a frag (@pxref{Frags}), a position within the frag, a size, an indication
+of whether the fixup is PC relative, and a type. In a @code{BFD_ASSEMBLER}
+GAS, the type is nominally a @code{bfd_reloc_code_real_type}, but several
+targets use other type codes to represent fixups that can not be described as
+relocations.
+
+The @code{fixS} structure has a number of fields, several of which are obsolete
+or are only used by a particular target. The important fields are:
+
+@table @code
+@item fx_frag
+The frag (@pxref{Frags}) this fixup is in.
+
+@item fx_where
+The location within the frag where the fixup occurs.
+
+@item fx_addsy
+The symbol this fixup is against. Typically, the value of this symbol is added
+into the object contents. This may be NULL.
+
+@item fx_subsy
+The value of this symbol is subtracted from the object contents. This is
+normally NULL.
+
+@item fx_offset
+A number which is added into the fixup.
+
+@item fx_addnumber
+Some CPU backends use this field to convey information between
+@code{md_apply_fix} and @code{tc_gen_reloc}. The machine independent code does
+not use it.
+
+@item fx_next
+The next fixup in the section.
+
+@item fx_r_type
+The type of the fixup. This field is only defined if @code{BFD_ASSEMBLER}, or
+if the target defines @code{NEED_FX_R_TYPE}.
+
+@item fx_size
+The size of the fixup. This is mostly used for error checking.
+
+@item fx_pcrel
+Whether the fixup is PC relative.
+
+@item fx_done
+Non-zero if the fixup has been applied, and no relocation entry needs to be
+generated.
+
+@item fx_file
+@itemx fx_line
+The file and line where the fixup was created.
+
+@item tc_fix_data
+This has the type @code{TC_FIX_TYPE}, and is only defined if the target defines
+that macro.
+@end table
+
+@node Frags
+@subsection Frags
+@cindex internals, frags
+@cindex frags
+@cindex fragS structure.
+
+The @code{fragS} structure is defined in @file{as.h}. Each frag represents a
+portion of the final object file. As GAS reads the source file, it creates
+frags to hold the data that it reads. At the end of the assembly the frags and
+fixups are processed to produce the final contents.
+
+@table @code
+@item fr_address
+The address of the frag. This is not set until the assembler rescans the list
+of all frags after the entire input file is parsed. The function
+@code{relax_segment} fills in this field.
+
+@item fr_next
+Pointer to the next frag in this (sub)section.
+
+@item fr_fix
+Fixed number of characters we know we're going to emit to the output file. May
+be zero.
+
+@item fr_var
+Variable number of characters we may output, after the initial @code{fr_fix}
+characters. May be zero.
+
+@item fr_offset
+The interpretation of this field is controlled by @code{fr_type}. Generally,
+if @code{fr_var} is non-zero, this is a repeat count: the @code{fr_var}
+characters are output @code{fr_offset} times.
+
+@item line
+Holds line number info when an assembler listing was requested.
+
+@item fr_type
+Relaxation state. This field indicates the interpretation of @code{fr_offset},
+@code{fr_symbol} and the variable-length tail of the frag, as well as the
+treatment it gets in various phases of processing. It does not affect the
+initial @code{fr_fix} characters; they are always supposed to be output
+verbatim (fixups aside). See below for specific values this field can have.
+
+@item fr_subtype
+Relaxation substate. If the macro @code{md_relax_frag} isn't defined, this is
+assumed to be an index into @code{TC_GENERIC_RELAX_TABLE} for the generic
+relaxation code to process (@pxref{Relaxation}). If @code{md_relax_frag} is
+defined, this field is available for any use by the CPU-specific code.
+
+@item fr_symbol
+This normally indicates the symbol to use when relaxing the frag according to
+@code{fr_type}.
+
+@item fr_opcode
+Points to the lowest-addressed byte of the opcode, for use in relaxation.
+
+@item tc_frag_data
+Target specific fragment data of type TC_FRAG_TYPE.
+Only present if @code{TC_FRAG_TYPE} is defined.
+
+@item fr_file
+@itemx fr_line
+The file and line where this frag was last modified.
+
+@item fr_literal
+Declared as a one-character array, this last field grows arbitrarily large to
+hold the actual contents of the frag.
+@end table
+
+These are the possible relaxation states, provided in the enumeration type
+@code{relax_stateT}, and the interpretations they represent for the other
+fields:
+
+@table @code
+@item rs_align
+@itemx rs_align_code
+The start of the following frag should be aligned on some boundary. In this
+frag, @code{fr_offset} is the logarithm (base 2) of the alignment in bytes.
+(For example, if alignment on an 8-byte boundary were desired, @code{fr_offset}
+would have a value of 3.) The variable characters indicate the fill pattern to
+be used. The @code{fr_subtype} field holds the maximum number of bytes to skip
+when doing this alignment. If more bytes are needed, the alignment is not
+done. An @code{fr_subtype} value of 0 means no maximum, which is the normal
+case. Target backends can use @code{rs_align_code} to handle certain types of
+alignment differently.
+
+@item rs_broken_word
+This indicates that ``broken word'' processing should be done (@pxref{Broken
+words}). If broken word processing is not necessary on the target machine,
+this enumerator value will not be defined.
+
+@item rs_cfa
+This state is used to implement exception frame optimizations. The
+@code{fr_symbol} is an expression symbol for the subtraction which may be
+relaxed. The @code{fr_opcode} field holds the frag for the preceding command
+byte. The @code{fr_offset} field holds the offset within that frag. The
+@code{fr_subtype} field is used during relaxation to hold the current size of
+the frag.
+
+@item rs_fill
+The variable characters are to be repeated @code{fr_offset} times. If
+@code{fr_offset} is 0, this frag has a length of @code{fr_fix}. Most frags
+have this type.
+
+@item rs_leb128
+This state is used to implement the DWARF ``little endian base 128''
+variable length number format. The @code{fr_symbol} is always an expression
+symbol, as constant expressions are emitted directly. The @code{fr_offset}
+field is used during relaxation to hold the previous size of the number so
+that we can determine if the fragment changed size.
+
+@item rs_machine_dependent
+Displacement relaxation is to be done on this frag. The target is indicated by
+@code{fr_symbol} and @code{fr_offset}, and @code{fr_subtype} indicates the
+particular machine-specific addressing mode desired. @xref{Relaxation}.
+
+@item rs_org
+The start of the following frag should be pushed back to some specific offset
+within the section. (Some assemblers use the value as an absolute address; GAS
+does not handle final absolute addresses, but rather requires that the linker
+set them.) The offset is given by @code{fr_symbol} and @code{fr_offset}; one
+character from the variable-length tail is used as the fill character.
+@end table
+
+@cindex frchainS structure
+A chain of frags is built up for each subsection. The data structure
+describing a chain is called a @code{frchainS}, and contains the following
+fields:
+
+@table @code
+@item frch_root
+Points to the first frag in the chain. May be NULL if there are no frags in
+this chain.
+@item frch_last
+Points to the last frag in the chain, or NULL if there are none.
+@item frch_next
+Next in the list of @code{frchainS} structures.
+@item frch_seg
+Indicates the section this frag chain belongs to.
+@item frch_subseg
+Subsection (subsegment) number of this frag chain.
+@item fix_root, fix_tail
+(Defined only if @code{BFD_ASSEMBLER} is defined). Point to first and last
+@code{fixS} structures associated with this subsection.
+@item frch_obstack
+Not currently used. Intended to be used for frag allocation for this
+subsection. This should reduce frag generation caused by switching sections.
+@item frch_frag_now
+The current frag for this subsegment.
+@end table
+
+A @code{frchainS} corresponds to a subsection; each section has a list of
+@code{frchainS} records associated with it. In most cases, only one subsection
+of each section is used, so the list will only be one element long, but any
+processing of frag chains should be prepared to deal with multiple chains per
+section.
+
+After the input files have been completely processed, and no more frags are to
+be generated, the frag chains are joined into one per section for further
+processing. After this point, it is safe to operate on one chain per section.
+
+The assembler always has a current frag, named @code{frag_now}. More space is
+allocated for the current frag using the @code{frag_more} function; this
+returns a pointer to the amount of requested space. Relaxing is done using
+variant frags allocated by @code{frag_var} or @code{frag_variant}
+(@pxref{Relaxation}).
+
+@node GAS processing
+@section What GAS does when it runs
+@cindex internals, overview
+
+This is a quick look at what an assembler run looks like.
+
+@itemize @bullet
+@item
+The assembler initializes itself by calling various init routines.
+
+@item
+For each source file, the @code{read_a_source_file} function reads in the file
+and parses it. The global variable @code{input_line_pointer} points to the
+current text; it is guaranteed to be correct up to the end of the line, but not
+farther.
+
+@item
+For each line, the assembler passes labels to the @code{colon} function, and
+isolates the first word. If it looks like a pseudo-op, the word is looked up
+in the pseudo-op hash table @code{po_hash} and dispatched to a pseudo-op
+routine. Otherwise, the target dependent @code{md_assemble} routine is called
+to parse the instruction.
+
+@item
+When pseudo-ops or instructions output data, they add it to a frag, calling
+@code{frag_more} to get space to store it in.
+
+@item
+Pseudo-ops and instructions can also output fixups created by @code{fix_new} or
+@code{fix_new_exp}.
+
+@item
+For certain targets, instructions can create variant frags which are used to
+store relaxation information (@pxref{Relaxation}).
+
+@item
+When the input file is finished, the @code{write_object_file} routine is
+called. It assigns addresses to all the frags (@code{relax_segment}), resolves
+all the fixups (@code{fixup_segment}), resolves all the symbol values (using
+@code{resolve_symbol_value}), and finally writes out the file (in the
+@code{BFD_ASSEMBLER} case, this is done by simply calling @code{bfd_close}).
+@end itemize
+
+@node Porting GAS
+@section Porting GAS
+@cindex porting
+
+Each GAS target specifies two main things: the CPU file and the object format
+file. Two main switches in the @file{configure.in} file handle this. The
+first switches on CPU type to set the shell variable @code{cpu_type}. The
+second switches on the entire target to set the shell variable @code{fmt}.
+
+The configure script uses the value of @code{cpu_type} to select two files in
+the @file{config} directory: @file{tc-@var{CPU}.c} and @file{tc-@var{CPU}.h}.
+The configuration process will create a file named @file{targ-cpu.h} in the
+build directory which includes @file{tc-@var{CPU}.h}.
+
+The configure script also uses the value of @code{fmt} to select two files:
+@file{obj-@var{fmt}.c} and @file{obj-@var{fmt}.h}. The configuration process
+will create a file named @file{obj-format.h} in the build directory which
+includes @file{obj-@var{fmt}.h}.
+
+You can also set the emulation in the configure script by setting the @code{em}
+variable. Normally the default value of @samp{generic} is fine. The
+configuration process will create a file named @file{targ-env.h} in the build
+directory which includes @file{te-@var{em}.h}.
+
+Porting GAS to a new CPU requires writing the @file{tc-@var{CPU}} files.
+Porting GAS to a new object file format requires writing the
+@file{obj-@var{fmt}} files. There is sometimes some interaction between these
+two files, but it is normally minimal.
+
+The best approach is, of course, to copy existing files. The documentation
+below assumes that you are looking at existing files to see usage details.
+
+These interfaces have grown over time, and have never been carefully thought
+out or designed. Nothing about the interfaces described here is cast in stone.
+It is possible that they will change from one version of the assembler to the
+next. Also, new macros are added all the time as they are needed.
+
+@menu
+* CPU backend:: Writing a CPU backend
+* Object format backend:: Writing an object format backend
+* Emulations:: Writing emulation files
+@end menu
+
+@node CPU backend
+@subsection Writing a CPU backend
+@cindex CPU backend
+@cindex @file{tc-@var{CPU}}
+
+The CPU backend files are the heart of the assembler. They are the only parts
+of the assembler which actually know anything about the instruction set of the
+processor.
+
+You must define a reasonably small list of macros and functions in the CPU
+backend files. You may define a large number of additional macros in the CPU
+backend files, not all of which are documented here. You must, of course,
+define macros in the @file{.h} file, which is included by every assembler
+source file. You may define the functions as macros in the @file{.h} file, or
+as functions in the @file{.c} file.
+
+@table @code
+@item TC_@var{CPU}
+@cindex TC_@var{CPU}
+By convention, you should define this macro in the @file{.h} file. For
+example, @file{tc-m68k.h} defines @code{TC_M68K}. You might have to use this
+if it is necessary to add CPU specific code to the object format file.
+
+@item TARGET_FORMAT
+This macro is the BFD target name to use when creating the output file. This
+will normally depend upon the @code{OBJ_@var{FMT}} macro.
+
+@item TARGET_ARCH
+This macro is the BFD architecture to pass to @code{bfd_set_arch_mach}.
+
+@item TARGET_MACH
+This macro is the BFD machine number to pass to @code{bfd_set_arch_mach}. If
+it is not defined, GAS will use 0.
+
+@item TARGET_BYTES_BIG_ENDIAN
+You should define this macro to be non-zero if the target is big endian, and
+zero if the target is little endian.
+
+@item md_shortopts
+@itemx md_longopts
+@itemx md_longopts_size
+@itemx md_parse_option
+@itemx md_show_usage
+@cindex md_shortopts
+@cindex md_longopts
+@cindex md_longopts_size
+@cindex md_parse_option
+@cindex md_show_usage
+GAS uses these variables and functions during option processing.
+@code{md_shortopts} is a @code{const char *} which GAS adds to the machine
+independent string passed to @code{getopt}. @code{md_longopts} is a
+@code{struct option []} which GAS adds to the machine independent long options
+passed to @code{getopt}; you may use @code{OPTION_MD_BASE}, defined in
+@file{as.h}, as the start of a set of long option indices, if necessary.
+@code{md_longopts_size} is a @code{size_t} holding the size @code{md_longopts}.
+GAS will call @code{md_parse_option} whenever @code{getopt} returns an
+unrecognized code, presumably indicating a special code value which appears in
+@code{md_longopts}. GAS will call @code{md_show_usage} when a usage message is
+printed; it should print a description of the machine specific options.
+
+@item md_begin
+@cindex md_begin
+GAS will call this function at the start of the assembly, after the command
+line arguments have been parsed and all the machine independent initializations
+have been completed.
+
+@item md_cleanup
+@cindex md_cleanup
+If you define this macro, GAS will call it at the end of each input file.
+
+@item md_assemble
+@cindex md_assemble
+GAS will call this function for each input line which does not contain a
+pseudo-op. The argument is a null terminated string. The function should
+assemble the string as an instruction with operands. Normally
+@code{md_assemble} will do this by calling @code{frag_more} and writing out
+some bytes (@pxref{Frags}). @code{md_assemble} will call @code{fix_new} to
+create fixups as needed (@pxref{Fixups}). Targets which need to do special
+purpose relaxation will call @code{frag_var}.
+
+@item md_pseudo_table
+@cindex md_pseudo_table
+This is a const array of type @code{pseudo_typeS}. It is a mapping from
+pseudo-op names to functions. You should use this table to implement
+pseudo-ops which are specific to the CPU.
+
+@item tc_conditional_pseudoop
+@cindex tc_conditional_pseudoop
+If this macro is defined, GAS will call it with a @code{pseudo_typeS} argument.
+It should return non-zero if the pseudo-op is a conditional which controls
+whether code is assembled, such as @samp{.if}. GAS knows about the normal
+conditional pseudo-ops,and you should normally not have to define this macro.
+
+@item comment_chars
+@cindex comment_chars
+This is a null terminated @code{const char} array of characters which start a
+comment.
+
+@item tc_comment_chars
+@cindex tc_comment_chars
+If this macro is defined, GAS will use it instead of @code{comment_chars}.
+
+@item tc_symbol_chars
+@cindex tc_symbol_chars
+If this macro is defined, it is a pointer to a null terminated list of
+characters which may appear in an operand. GAS already assumes that all
+alphanumberic characters, and @samp{$}, @samp{.}, and @samp{_} may appear in an
+operand (see @samp{symbol_chars} in @file{app.c}). This macro may be defined
+to treat additional characters as appearing in an operand. This affects the
+way in which GAS removes whitespace before passing the string to
+@samp{md_assemble}.
+
+@item line_comment_chars
+@cindex line_comment_chars
+This is a null terminated @code{const char} array of characters which start a
+comment when they appear at the start of a line.
+
+@item line_separator_chars
+@cindex line_separator_chars
+This is a null terminated @code{const char} array of characters which separate
+lines (semicolon and newline are such characters by default, and need not be
+listed in this array).
+
+@item EXP_CHARS
+@cindex EXP_CHARS
+This is a null terminated @code{const char} array of characters which may be
+used as the exponent character in a floating point number. This is normally
+@code{"eE"}.
+
+@item FLT_CHARS
+@cindex FLT_CHARS
+This is a null terminated @code{const char} array of characters which may be
+used to indicate a floating point constant. A zero followed by one of these
+characters is assumed to be followed by a floating point number; thus they
+operate the way that @code{0x} is used to indicate a hexadecimal constant.
+Usually this includes @samp{r} and @samp{f}.
+
+@item LEX_AT
+@cindex LEX_AT
+You may define this macro to the lexical type of the @kbd{@}} character. The
+default is zero.
+
+Lexical types are a combination of @code{LEX_NAME} and @code{LEX_BEGIN_NAME},
+both defined in @file{read.h}. @code{LEX_NAME} indicates that the character
+may appear in a name. @code{LEX_BEGIN_NAME} indicates that the character may
+appear at the beginning of a nem.
+
+@item LEX_BR
+@cindex LEX_BR
+You may define this macro to the lexical type of the brace characters @kbd{@{},
+@kbd{@}}, @kbd{[}, and @kbd{]}. The default value is zero.
+
+@item LEX_PCT
+@cindex LEX_PCT
+You may define this macro to the lexical type of the @kbd{%} character. The
+default value is zero.
+
+@item LEX_QM
+@cindex LEX_QM
+You may define this macro to the lexical type of the @kbd{?} character. The
+default value it zero.
+
+@item LEX_DOLLAR
+@cindex LEX_DOLLAR
+You may define this macro to the lexical type of the @kbd{$} character. The
+default value is @code{LEX_NAME | LEX_BEGIN_NAME}.
+
+@item SINGLE_QUOTE_STRINGS
+@cindex SINGLE_QUOTE_STRINGS
+If you define this macro, GAS will treat single quotes as string delimiters.
+Normally only double quotes are accepted as string delimiters.
+
+@item NO_STRING_ESCAPES
+@cindex NO_STRING_ESCAPES
+If you define this macro, GAS will not permit escape sequences in a string.
+
+@item ONLY_STANDARD_ESCAPES
+@cindex ONLY_STANDARD_ESCAPES
+If you define this macro, GAS will warn about the use of nonstandard escape
+sequences in a string.
+
+@item md_start_line_hook
+@cindex md_start_line_hook
+If you define this macro, GAS will call it at the start of each line.
+
+@item LABELS_WITHOUT_COLONS
+@cindex LABELS_WITHOUT_COLONS
+If you define this macro, GAS will assume that any text at the start of a line
+is a label, even if it does not have a colon.
+
+@item TC_START_LABEL
+@cindex TC_START_LABEL
+You may define this macro to control what GAS considers to be a label. The
+default definition is to accept any name followed by a colon character.
+
+@item NO_PSEUDO_DOT
+@cindex NO_PSEUDO_DOT
+If you define this macro, GAS will not require pseudo-ops to start with a
+@kbd{.} character.
+
+@item TC_EQUAL_IN_INSN
+@cindex TC_EQUAL_IN_INSN
+If you define this macro, it should return nonzero if the instruction is
+permitted to contain an @kbd{=} character. GAS will use this to decide if a
+@kbd{=} is an assignment or an instruction.
+
+@item TC_EOL_IN_INSN
+@cindex TC_EOL_IN_INSN
+If you define this macro, it should return nonzero if the current input line
+pointer should be treated as the end of a line.
+
+@item md_parse_name
+@cindex md_parse_name
+If this macro is defined, GAS will call it for any symbol found in an
+expression. You can define this to handle special symbols in a special way.
+If a symbol always has a certain value, you should normally enter it in the
+symbol table, perhaps using @code{reg_section}.
+
+@item md_undefined_symbol
+@cindex md_undefined_symbol
+GAS will call this function when a symbol table lookup fails, before it
+creates a new symbol. Typically this would be used to supply symbols whose
+name or value changes dynamically, possibly in a context sensitive way.
+Predefined symbols with fixed values, such as register names or condition
+codes, are typically entered directly into the symbol table when @code{md_begin}
+is called.
+
+@item md_operand
+@cindex md_operand
+GAS will call this function for any expression that can not be recognized.
+When the function is called, @code{input_line_pointer} will point to the start
+of the expression.
+
+@item tc_unrecognized_line
+@cindex tc_unrecognized_line
+If you define this macro, GAS will call it when it finds a line that it can not
+parse.
+
+@item md_do_align
+@cindex md_do_align
+You may define this macro to handle an alignment directive. GAS will call it
+when the directive is seen in the input file. For example, the i386 backend
+uses this to generate efficient nop instructions of varying lengths, depending
+upon the number of bytes that the alignment will skip.
+
+@item HANDLE_ALIGN
+@cindex HANDLE_ALIGN
+You may define this macro to do special handling for an alignment directive.
+GAS will call it at the end of the assembly.
+
+@item md_flush_pending_output
+@cindex md_flush_pending_output
+If you define this macro, GAS will call it each time it skips any space because of a
+space filling or alignment or data allocation pseudo-op.
+
+@item TC_PARSE_CONS_EXPRESSION
+@cindex TC_PARSE_CONS_EXPRESSION
+You may define this macro to parse an expression used in a data allocation
+pseudo-op such as @code{.word}. You can use this to recognize relocation
+directives that may appear in such directives.
+
+@item BITFIELD_CONS_EXPRESSION
+@cindex BITFIELD_CONS_EXPRESSION
+If you define this macro, GAS will recognize bitfield instructions in data
+allocation pseudo-ops, as used on the i960.
+
+@item REPEAT_CONS_EXPRESSION
+@cindex REPEAT_CONS_EXPRESSION
+If you define this macro, GAS will recognize repeat counts in data allocation
+pseudo-ops, as used on the MIPS.
+
+@item md_cons_align
+@cindex md_cons_align
+You may define this macro to do any special alignment before a data allocation
+pseudo-op.
+
+@item TC_CONS_FIX_NEW
+@cindex TC_CONS_FIX_NEW
+You may define this macro to generate a fixup for a data allocation pseudo-op.
+
+@item TC_INIT_FIX_DATA (@var{fixp})
+@cindex TC_INIT_FIX_DATA
+A C statement to initialize the target specific fields of fixup @var{fixp}.
+These fields are defined with the @code{TC_FIX_TYPE} macro.
+
+@item TC_FIX_DATA_PRINT (@var{stream}, @var{fixp})
+@cindex TC_FIX_DATA_PRINT
+A C statement to output target specific debugging information for
+fixup @var{fixp} to @var{stream}. This macro is called by @code{print_fixup}.
+
+@item TC_FRAG_INIT (@var{fragp})
+@cindex TC_FRAG_INIT
+A C statement to initialize the target specific fields of frag @var{fragp}.
+These fields are defined with the @code{TC_FRAG_TYPE} macro.
+
+@item md_number_to_chars
+@cindex md_number_to_chars
+This should just call either @code{number_to_chars_bigendian} or
+@code{number_to_chars_littleendian}, whichever is appropriate. On targets like
+the MIPS which support options to change the endianness, which function to call
+is a runtime decision. On other targets, @code{md_number_to_chars} can be a
+simple macro.
+
+@item md_reloc_size
+@cindex md_reloc_size
+This variable is only used in the original version of gas (not
+@code{BFD_ASSEMBLER} and not @code{MANY_SEGMENTS}). It holds the size of a
+relocation entry.
+
+@item WORKING_DOT_WORD
+@itemx md_short_jump_size
+@itemx md_long_jump_size
+@itemx md_create_short_jump
+@itemx md_create_long_jump
+@cindex WORKING_DOT_WORD
+@cindex md_short_jump_size
+@cindex md_long_jump_size
+@cindex md_create_short_jump
+@cindex md_create_long_jump
+If @code{WORKING_DOT_WORD} is defined, GAS will not do broken word processing
+(@pxref{Broken words}). Otherwise, you should set @code{md_short_jump_size} to
+the size of a short jump (a jump that is just long enough to jump around a long
+jmp) and @code{md_long_jump_size} to the size of a long jump (a jump that can
+go anywhere in the function), You should define @code{md_create_short_jump} to
+create a short jump around a long jump, and define @code{md_create_long_jump}
+to create a long jump.
+
+@item md_estimate_size_before_relax
+@cindex md_estimate_size_before_relax
+This function returns an estimate of the size of a @code{rs_machine_dependent}
+frag before any relaxing is done. It may also create any necessary
+relocations.
+
+@item md_relax_frag
+@cindex md_relax_frag
+This macro may be defined to relax a frag. GAS will call this with the frag
+and the change in size of all previous frags; @code{md_relax_frag} should
+return the change in size of the frag. @xref{Relaxation}.
+
+@item TC_GENERIC_RELAX_TABLE
+@cindex TC_GENERIC_RELAX_TABLE
+If you do not define @code{md_relax_frag}, you may define
+@code{TC_GENERIC_RELAX_TABLE} as a table of @code{relax_typeS} structures. The
+machine independent code knows how to use such a table to relax PC relative
+references. See @file{tc-m68k.c} for an example. @xref{Relaxation}.
+
+@item md_prepare_relax_scan
+@cindex md_prepare_relax_scan
+If defined, it is a C statement that is invoked prior to scanning
+the relax table.
+
+@item LINKER_RELAXING_SHRINKS_ONLY
+@cindex LINKER_RELAXING_SHRINKS_ONLY
+If you define this macro, and the global variable @samp{linkrelax} is set
+(because of a command line option, or unconditionally in @code{md_begin}), a
+@samp{.align} directive will cause extra space to be allocated. The linker can
+then discard this space when relaxing the section.
+
+@item md_convert_frag
+@cindex md_convert_frag
+GAS will call this for each rs_machine_dependent fragment.
+The instruction is completed using the data from the relaxation pass.
+It may also create any necessary relocations.
+@xref{Relaxation}.
+
+@item md_apply_fix
+@cindex md_apply_fix
+GAS will call this for each fixup. It should store the correct value in the
+object file.
+
+@item TC_HANDLES_FX_DONE
+@cindex TC_HANDLES_FX_DONE
+If this macro is defined, it means that @code{md_apply_fix} correctly sets the
+@code{fx_done} field in the fixup.
+
+@item tc_gen_reloc
+@cindex tc_gen_reloc
+A @code{BFD_ASSEMBLER} GAS will call this to generate a reloc. GAS will pass
+the resulting reloc to @code{bfd_install_relocation}. This currently works
+poorly, as @code{bfd_install_relocation} often does the wrong thing, and
+instances of @code{tc_gen_reloc} have been written to work around the problems,
+which in turns makes it difficult to fix @code{bfd_install_relocation}.
+
+@item RELOC_EXPANSION_POSSIBLE
+@cindex RELOC_EXPANSION_POSSIBLE
+If you define this macro, it means that @code{tc_gen_reloc} may return multiple
+relocation entries for a single fixup. In this case, the return value of
+@code{tc_gen_reloc} is a pointer to a null terminated array.
+
+@item MAX_RELOC_EXPANSION
+@cindex MAX_RELOC_EXPANSION
+You must define this if @code{RELOC_EXPANSION_POSSIBLE} is defined; it
+indicates the largest number of relocs which @code{tc_gen_reloc} may return for
+a single fixup.
+
+@item tc_fix_adjustable
+@cindex tc_fix_adjustable
+You may define this macro to indicate whether a fixup against a locally defined
+symbol should be adjusted to be against the section symbol. It should return a
+non-zero value if the adjustment is acceptable.
+
+@item MD_PCREL_FROM_SECTION
+@cindex MD_PCREL_FROM_SECTION
+If you define this macro, it should return the offset between the address of a
+PC relative fixup and the position from which the PC relative adjustment should
+be made. On many processors, the base of a PC relative instruction is the next
+instruction, so this macro would return the length of an instruction.
+
+@item md_pcrel_from
+@cindex md_pcrel_from
+This is the default value of @code{MD_PCREL_FROM_SECTION}. The difference is
+that @code{md_pcrel_from} does not take a section argument.
+
+@item tc_frob_label
+@cindex tc_frob_label
+If you define this macro, GAS will call it each time a label is defined.
+
+@item md_section_align
+@cindex md_section_align
+GAS will call this function for each section at the end of the assembly, to
+permit the CPU backend to adjust the alignment of a section.
+
+@item tc_frob_section
+@cindex tc_frob_section
+If you define this macro, a @code{BFD_ASSEMBLER} GAS will call it for each
+section at the end of the assembly.
+
+@item tc_frob_file_before_adjust
+@cindex tc_frob_file_before_adjust
+If you define this macro, GAS will call it after the symbol values are
+resolved, but before the fixups have been changed from local symbols to section
+symbols.
+
+@item tc_frob_symbol
+@cindex tc_frob_symbol
+If you define this macro, GAS will call it for each symbol. You can indicate
+that the symbol should not be included in the object file by definining this
+macro to set its second argument to a non-zero value.
+
+@item tc_frob_file
+@cindex tc_frob_file
+If you define this macro, GAS will call it after the symbol table has been
+completed, but before the relocations have been generated.
+
+@item tc_frob_file_after_relocs
+If you define this macro, GAS will call it after the relocs have been
+generated.
+
+@item LISTING_HEADER
+A string to use on the header line of a listing. The default value is simply
+@code{"GAS LISTING"}.
+
+@item LISTING_WORD_SIZE
+The number of bytes to put into a word in a listing. This affects the way the
+bytes are clumped together in the listing. For example, a value of 2 might
+print @samp{1234 5678} where a value of 1 would print @samp{12 34 56 78}. The
+default value is 4.
+
+@item LISTING_LHS_WIDTH
+The number of words of data to print on the first line of a listing for a
+particular source line, where each word is @code{LISTING_WORD_SIZE} bytes. The
+default value is 1.
+
+@item LISTING_LHS_WIDTH_SECOND
+Like @code{LISTING_LHS_WIDTH}, but applying to the second and subsequent line
+of the data printed for a particular source line. The default value is 1.
+
+@item LISTING_LHS_CONT_LINES
+The maximum number of continuation lines to print in a listing for a particular
+source line. The default value is 4.
+
+@item LISTING_RHS_WIDTH
+The maximum number of characters to print from one line of the input file. The
+default value is 100.
+@end table
+
+@node Object format backend
+@subsection Writing an object format backend
+@cindex object format backend
+@cindex @file{obj-@var{fmt}}
+
+As with the CPU backend, the object format backend must define a few things,
+and may define some other things. The interface to the object format backend
+is generally simpler; most of the support for an object file format consists of
+defining a number of pseudo-ops.
+
+The object format @file{.h} file must include @file{targ-cpu.h}.
+
+This section will only define the @code{BFD_ASSEMBLER} version of GAS. It is
+impossible to support a new object file format using any other version anyhow,
+as the original GAS version only supports a.out, and the @code{MANY_SEGMENTS}
+GAS version only supports COFF.
+
+@table @code
+@item OBJ_@var{format}
+@cindex OBJ_@var{format}
+By convention, you should define this macro in the @file{.h} file. For
+example, @file{obj-elf.h} defines @code{OBJ_ELF}. You might have to use this
+if it is necessary to add object file format specific code to the CPU file.
+
+@item obj_begin
+If you define this macro, GAS will call it at the start of the assembly, after
+the command line arguments have been parsed and all the machine independent
+initializations have been completed.
+
+@item obj_app_file
+@cindex obj_app_file
+If you define this macro, GAS will invoke it when it sees a @code{.file}
+pseudo-op or a @samp{#} line as used by the C preprocessor.
+
+@item OBJ_COPY_SYMBOL_ATTRIBUTES
+@cindex OBJ_COPY_SYMBOL_ATTRIBUTES
+You should define this macro to copy object format specific information from
+one symbol to another. GAS will call it when one symbol is equated to
+another.
+
+@item obj_fix_adjustable
+@cindex obj_fix_adjustable
+You may define this macro to indicate whether a fixup against a locally defined
+symbol should be adjusted to be against the section symbol. It should return a
+non-zero value if the adjustment is acceptable.
+
+@item obj_sec_sym_ok_for_reloc
+@cindex obj_sec_sym_ok_for_reloc
+You may define this macro to indicate that it is OK to use a section symbol in
+a relocateion entry. If it is not, GAS will define a new symbol at the start
+of a section.
+
+@item EMIT_SECTION_SYMBOLS
+@cindex EMIT_SECTION_SYMBOLS
+You should define this macro with a zero value if you do not want to include
+section symbols in the output symbol table. The default value for this macro
+is one.
+
+@item obj_adjust_symtab
+@cindex obj_adjust_symtab
+If you define this macro, GAS will invoke it just before setting the symbol
+table of the output BFD. For example, the COFF support uses this macro to
+generate a @code{.file} symbol if none was generated previously.
+
+@item SEPARATE_STAB_SECTIONS
+@cindex SEPARATE_STAB_SECTIONS
+You may define this macro to indicate that stabs should be placed in separate
+sections, as in ELF.
+
+@item INIT_STAB_SECTION
+@cindex INIT_STAB_SECTION
+You may define this macro to initialize the stabs section in the output file.
+
+@item OBJ_PROCESS_STAB
+@cindex OBJ_PROCESS_STAB
+You may define this macro to do specific processing on a stabs entry.
+
+@item obj_frob_section
+@cindex obj_frob_section
+If you define this macro, GAS will call it for each section at the end of the
+assembly.
+
+@item obj_frob_file_before_adjust
+@cindex obj_frob_file_before_adjust
+If you define this macro, GAS will call it after the symbol values are
+resolved, but before the fixups have been changed from local symbols to section
+symbols.
+
+@item obj_frob_symbol
+@cindex obj_frob_symbol
+If you define this macro, GAS will call it for each symbol. You can indicate
+that the symbol should not be included in the object file by definining this
+macro to set its second argument to a non-zero value.
+
+@item obj_frob_file
+@cindex obj_frob_file
+If you define this macro, GAS will call it after the symbol table has been
+completed, but before the relocations have been generated.
+
+@item obj_frob_file_after_relocs
+If you define this macro, GAS will call it after the relocs have been
+generated.
+@end table
+
+@node Emulations
+@subsection Writing emulation files
+
+Normally you do not have to write an emulation file. You can just use
+@file{te-generic.h}.
+
+If you do write your own emulation file, it must include @file{obj-format.h}.
+
+An emulation file will often define @code{TE_@var{EM}}; this may then be used
+in other files to change the output.
+
+@node Relaxation
+@section Relaxation
+@cindex relaxation
+
+@dfn{Relaxation} is a generic term used when the size of some instruction or
+data depends upon the value of some symbol or other data.
+
+GAS knows to relax a particular type of PC relative relocation using a table.
+You can also define arbitrarily complex forms of relaxation yourself.
+
+@menu
+* Relaxing with a table:: Relaxing with a table
+* General relaxing:: General relaxing
+@end menu
+
+@node Relaxing with a table
+@subsection Relaxing with a table
+
+If you do not define @code{md_relax_frag}, and you do define
+@code{TC_GENERIC_RELAX_TABLE}, GAS will relax @code{rs_machine_dependent} frags
+based on the frag subtype and the displacement to some specified target
+address. The basic idea is that several machines have different addressing
+modes for instructions that can specify different ranges of values, with
+successive modes able to access wider ranges, including the entirety of the
+previous range. Smaller ranges are assumed to be more desirable (perhaps the
+instruction requires one word instead of two or three); if this is not the
+case, don't describe the smaller-range, inferior mode.
+
+The @code{fr_subtype} field of a frag is an index into a CPU-specific
+relaxation table. That table entry indicates the range of values that can be
+stored, the number of bytes that will have to be added to the frag to
+accomodate the addressing mode, and the index of the next entry to examine if
+the value to be stored is outside the range accessible by the current
+addressing mode. The @code{fr_symbol} field of the frag indicates what symbol
+is to be accessed; the @code{fr_offset} field is added in.
+
+If the @code{TC_PCREL_ADJUST} macro is defined, which currently should only happen
+for the NS32k family, the @code{TC_PCREL_ADJUST} macro is called on the frag to
+compute an adjustment to be made to the displacement.
+
+The value fitted by the relaxation code is always assumed to be a displacement
+from the current frag. (More specifically, from @code{fr_fix} bytes into the
+frag.)
+@ignore
+This seems kinda silly. What about fitting small absolute values? I suppose
+@code{md_assemble} is supposed to take care of that, but if the operand is a
+difference between symbols, it might not be able to, if the difference was not
+computable yet.
+@end ignore
+
+The end of the relaxation sequence is indicated by a ``next'' value of 0. This
+means that the first entry in the table can't be used.
+
+For some configurations, the linker can do relaxing within a section of an
+object file. If call instructions of various sizes exist, the linker can
+determine which should be used in each instance, when a symbol's value is
+resolved. In order for the linker to avoid wasting space and having to insert
+no-op instructions, it must be able to expand or shrink the section contents
+while still preserving intra-section references and meeting alignment
+requirements.
+
+For the i960 using b.out format, no expansion is done; instead, each
+@samp{.align} directive causes extra space to be allocated, enough that when
+the linker is relaxing a section and removing unneeded space, it can discard
+some or all of this extra padding and cause the following data to be correctly
+aligned.
+
+For the H8/300, I think the linker expands calls that can't reach, and doesn't
+worry about alignment issues; the cpu probably never needs any significant
+alignment beyond the instruction size.
+
+The relaxation table type contains these fields:
+
+@table @code
+@item long rlx_forward
+Forward reach, must be non-negative.
+@item long rlx_backward
+Backward reach, must be zero or negative.
+@item rlx_length
+Length in bytes of this addressing mode.
+@item rlx_more
+Index of the next-longer relax state, or zero if there is no next relax state.
+@end table
+
+The relaxation is done in @code{relax_segment} in @file{write.c}. The
+difference in the length fields between the original mode and the one finally
+chosen by the relaxing code is taken as the size by which the current frag will
+be increased in size. For example, if the initial relaxing mode has a length
+of 2 bytes, and because of the size of the displacement, it gets upgraded to a
+mode with a size of 6 bytes, it is assumed that the frag will grow by 4 bytes.
+(The initial two bytes should have been part of the fixed portion of the frag,
+since it is already known that they will be output.) This growth must be
+effected by @code{md_convert_frag}; it should increase the @code{fr_fix} field
+by the appropriate size, and fill in the appropriate bytes of the frag.
+(Enough space for the maximum growth should have been allocated in the call to
+frag_var as the second argument.)
+
+If relocation records are needed, they should be emitted by
+@code{md_estimate_size_before_relax}. This function should examine the target
+symbol of the supplied frag and correct the @code{fr_subtype} of the frag if
+needed. When this function is called, if the symbol has not yet been defined,
+it will not become defined later; however, its value may still change if the
+section it is in gets relaxed.
+
+Usually, if the symbol is in the same section as the frag (given by the
+@var{sec} argument), the narrowest likely relaxation mode is stored in
+@code{fr_subtype}, and that's that.
+
+If the symbol is undefined, or in a different section (and therefore moveable
+to an arbitrarily large distance), the largest available relaxation mode is
+specified, @code{fix_new} is called to produce the relocation record,
+@code{fr_fix} is increased to include the relocated field (remember, this
+storage was allocated when @code{frag_var} was called), and @code{frag_wane} is
+called to convert the frag to an @code{rs_fill} frag with no variant part.
+Sometimes changing addressing modes may also require rewriting the instruction.
+It can be accessed via @code{fr_opcode} or @code{fr_fix}.
+
+Sometimes @code{fr_var} is increased instead, and @code{frag_wane} is not
+called. I'm not sure, but I think this is to keep @code{fr_fix} referring to
+an earlier byte, and @code{fr_subtype} set to @code{rs_machine_dependent} so
+that @code{md_convert_frag} will get called.
+
+@node General relaxing
+@subsection General relaxing
+
+If using a simple table is not suitable, you may implement arbitrarily complex
+relaxation semantics yourself. For example, the MIPS backend uses this to emit
+different instruction sequences depending upon the size of the symbol being
+accessed.
+
+When you assemble an instruction that may need relaxation, you should allocate
+a frag using @code{frag_var} or @code{frag_variant} with a type of
+@code{rs_machine_dependent}. You should store some sort of information in the
+@code{fr_subtype} field so that you can figure out what to do with the frag
+later.
+
+When GAS reaches the end of the input file, it will look through the frags and
+work out their final sizes.
+
+GAS will first call @code{md_estimate_size_before_relax} on each
+@code{rs_machine_dependent} frag. This function must return an estimated size
+for the frag.
+
+GAS will then loop over the frags, calling @code{md_relax_frag} on each
+@code{rs_machine_dependent} frag. This function should return the change in
+size of the frag. GAS will keep looping over the frags until none of the frags
+changes size.
+
+@node Broken words
+@section Broken words
+@cindex internals, broken words
+@cindex broken words
+
+Some compilers, including GCC, will sometimes emit switch tables specifying
+16-bit @code{.word} displacements to branch targets, and branch instructions
+that load entries from that table to compute the target address. If this is
+done on a 32-bit machine, there is a chance (at least with really large
+functions) that the displacement will not fit in 16 bits. The assembler
+handles this using a concept called @dfn{broken words}. This idea is well
+named, since there is an implied promise that the 16-bit field will in fact
+hold the specified displacement.
+
+If broken word processing is enabled, and a situation like this is encountered,
+the assembler will insert a jump instruction into the instruction stream, close
+enough to be reached with the 16-bit displacement. This jump instruction will
+transfer to the real desired target address. Thus, as long as the @code{.word}
+value really is used as a displacement to compute an address to jump to, the
+net effect will be correct (minus a very small efficiency cost). If
+@code{.word} directives with label differences for values are used for other
+purposes, however, things may not work properly. For targets which use broken
+words, the @samp{-K} option will warn when a broken word is discovered.
+
+The broken word code is turned off by the @code{WORKING_DOT_WORD} macro. It
+isn't needed if @code{.word} emits a value large enough to contain an address
+(or, more correctly, any possible difference between two addresses).
+
+@node Internal functions
+@section Internal functions
+
+This section describes basic internal functions used by GAS.
+
+@menu
+* Warning and error messages:: Warning and error messages
+* Hash tables:: Hash tables
+@end menu
+
+@node Warning and error messages
+@subsection Warning and error messages
+
+@deftypefun @{@} int had_warnings (void)
+@deftypefunx @{@} int had_errors (void)
+Returns non-zero if any warnings or errors, respectively, have been printed
+during this invocation.
+@end deftypefun
+
+@deftypefun @{@} void as_perror (const char *@var{gripe}, const char *@var{filename})
+Displays a BFD or system error, then clears the error status.
+@end deftypefun
+
+@deftypefun @{@} void as_tsktsk (const char *@var{format}, ...)
+@deftypefunx @{@} void as_warn (const char *@var{format}, ...)
+@deftypefunx @{@} void as_bad (const char *@var{format}, ...)
+@deftypefunx @{@} void as_fatal (const char *@var{format}, ...)
+These functions display messages about something amiss with the input file, or
+internal problems in the assembler itself. The current file name and line
+number are printed, followed by the supplied message, formatted using
+@code{vfprintf}, and a final newline.
+
+An error indicated by @code{as_bad} will result in a non-zero exit status when
+the assembler has finished. Calling @code{as_fatal} will result in immediate
+termination of the assembler process.
+@end deftypefun
+
+@deftypefun @{@} void as_warn_where (char *@var{file}, unsigned int @var{line}, const char *@var{format}, ...)
+@deftypefunx @{@} void as_bad_where (char *@var{file}, unsigned int @var{line}, const char *@var{format}, ...)
+These variants permit specification of the file name and line number, and are
+used when problems are detected when reprocessing information saved away when
+processing some earlier part of the file. For example, fixups are processed
+after all input has been read, but messages about fixups should refer to the
+original filename and line number that they are applicable to.
+@end deftypefun
+
+@deftypefun @{@} void fprint_value (FILE *@var{file}, valueT @var{val})
+@deftypefunx @{@} void sprint_value (char *@var{buf}, valueT @var{val})
+These functions are helpful for converting a @code{valueT} value into printable
+format, in case it's wider than modes that @code{*printf} can handle. If the
+type is narrow enough, a decimal number will be produced; otherwise, it will be
+in hexadecimal. The value itself is not examined to make this determination.
+@end deftypefun
+
+@node Hash tables
+@subsection Hash tables
+@cindex hash tables
+
+@deftypefun @{@} @{struct hash_control *@} hash_new (void)
+Creates the hash table control structure.
+@end deftypefun
+
+@deftypefun @{@} void hash_die (struct hash_control *)
+Destroy a hash table.
+@end deftypefun
+
+@deftypefun @{@} PTR hash_delete (struct hash_control *, const char *)
+Deletes entry from the hash table, returns the value it had.
+@end deftypefun
+
+@deftypefun @{@} PTR hash_replace (struct hash_control *, const char *, PTR)
+Updates the value for an entry already in the table, returning the old value.
+If no entry was found, just returns NULL.
+@end deftypefun
+
+@deftypefun @{@} @{const char *@} hash_insert (struct hash_control *, const char *, PTR)
+Inserting a value already in the table is an error.
+Returns an error message or NULL.
+@end deftypefun
+
+@deftypefun @{@} @{const char *@} hash_jam (struct hash_control *, const char *, PTR)
+Inserts if the value isn't already present, updates it if it is.
+@end deftypefun
+
+@node Test suite
+@section Test suite
+@cindex test suite
+
+The test suite is kind of lame for most processors. Often it only checks to
+see if a couple of files can be assembled without the assembler reporting any
+errors. For more complete testing, write a test which either examines the
+assembler listing, or runs @code{objdump} and examines its output. For the
+latter, the TCL procedure @code{run_dump_test} may come in handy. It takes the
+base name of a file, and looks for @file{@var{file}.d}. This file should
+contain as its initial lines a set of variable settings in @samp{#} comments,
+in the form:
+
+@example
+ #@var{varname}: @var{value}
+@end example
+
+The @var{varname} may be @code{objdump}, @code{nm}, or @code{as}, in which case
+it specifies the options to be passed to the specified programs. Exactly one
+of @code{objdump} or @code{nm} must be specified, as that also specifies which
+program to run after the assembler has finished. If @var{varname} is
+@code{source}, it specifies the name of the source file; otherwise,
+@file{@var{file}.s} is used. If @var{varname} is @code{name}, it specifies the
+name of the test to be used in the @code{pass} or @code{fail} messages.
+
+The non-commented parts of the file are interpreted as regular expressions, one
+per line. Blank lines in the @code{objdump} or @code{nm} output are skipped,
+as are blank lines in the @code{.d} file; the other lines are tested to see if
+the regular expression matches the program output. If it does not, the test
+fails.
+
+Note that this means the tests must be modified if the @code{objdump} output
+style is changed.
+
+@bye
+@c Local Variables:
+@c fill-column: 79
+@c End:
diff --git a/gas/ecoff.c b/gas/ecoff.c
new file mode 100644
index 00000000000..c3c9375527a
--- /dev/null
+++ b/gas/ecoff.c
@@ -0,0 +1,5308 @@
+/* ECOFF debugging support.
+ Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ This file was put together by Ian Lance Taylor <ian@cygnus.com>. A
+ good deal of it comes directly from mips-tfile.c, by Michael
+ Meissner <meissner@osf.org>.
+
+ This file is part of GAS.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+/* This file is compiled conditionally for those targets which use
+ ECOFF debugging information (e.g., MIPS ECOFF, MIPS ELF, Alpha
+ ECOFF). */
+
+#ifdef ECOFF_DEBUGGING
+
+#include "coff/internal.h"
+#include "coff/symconst.h"
+#include "ecoff.h"
+#include "aout/stab_gnu.h"
+
+#include <ctype.h>
+
+/* Why isn't this in coff/sym.h? */
+#define ST_RFDESCAPE 0xfff
+
+/* This file constructs the information used by the ECOFF debugging
+ format. It just builds a large block of data.
+
+ We support both ECOFF style debugging and stabs debugging (the
+ stabs symbols are encapsulated in ECOFF symbols). This should let
+ us handle anything the compiler might throw at us. */
+
+/* Here is a brief description of the MIPS ECOFF symbol table, by
+ Michael Meissner. The MIPS symbol table has the following pieces:
+
+ Symbolic Header
+ |
+ +-- Auxiliary Symbols
+ |
+ +-- Dense number table
+ |
+ +-- Optimizer Symbols
+ |
+ +-- External Strings
+ |
+ +-- External Symbols
+ |
+ +-- Relative file descriptors
+ |
+ +-- File table
+ |
+ +-- Procedure table
+ |
+ +-- Line number table
+ |
+ +-- Local Strings
+ |
+ +-- Local Symbols
+
+ The symbolic header points to each of the other tables, and also
+ contains the number of entries. It also contains a magic number
+ and MIPS compiler version number, such as 2.0.
+
+ The auxiliary table is a series of 32 bit integers, that are
+ referenced as needed from the local symbol table. Unlike standard
+ COFF, the aux. information does not follow the symbol that uses
+ it, but rather is a separate table. In theory, this would allow
+ the MIPS compilers to collapse duplicate aux. entries, but I've not
+ noticed this happening with the 1.31 compiler suite. The different
+ types of aux. entries are:
+
+ 1) dnLow: Low bound on array dimension.
+
+ 2) dnHigh: High bound on array dimension.
+
+ 3) isym: Index to the local symbol which is the start of the
+ function for the end of function first aux. entry.
+
+ 4) width: Width of structures and bitfields.
+
+ 5) count: Count of ranges for variant part.
+
+ 6) rndx: A relative index into the symbol table. The relative
+ index field has two parts: rfd which is a pointer into the
+ relative file index table or ST_RFDESCAPE which says the next
+ aux. entry is the file number, and index: which is the pointer
+ into the local symbol within a given file table. This is for
+ things like references to types defined in another file.
+
+ 7) Type information: This is like the COFF type bits, except it
+ is 32 bits instead of 16; they still have room to add new
+ basic types; and they can handle more than 6 levels of array,
+ pointer, function, etc. Each type information field contains
+ the following structure members:
+
+ a) fBitfield: a bit that says this is a bitfield, and the
+ size in bits follows as the next aux. entry.
+
+ b) continued: a bit that says the next aux. entry is a
+ continuation of the current type information (in case
+ there are more than 6 levels of array/ptr/function).
+
+ c) bt: an integer containing the base type before adding
+ array, pointer, function, etc. qualifiers. The
+ current base types that I have documentation for are:
+
+ btNil -- undefined
+ btAdr -- address - integer same size as ptr
+ btChar -- character
+ btUChar -- unsigned character
+ btShort -- short
+ btUShort -- unsigned short
+ btInt -- int
+ btUInt -- unsigned int
+ btLong -- long
+ btULong -- unsigned long
+ btFloat -- float (real)
+ btDouble -- Double (real)
+ btStruct -- Structure (Record)
+ btUnion -- Union (variant)
+ btEnum -- Enumerated
+ btTypedef -- defined via a typedef isymRef
+ btRange -- subrange of int
+ btSet -- pascal sets
+ btComplex -- fortran complex
+ btDComplex -- fortran double complex
+ btIndirect -- forward or unnamed typedef
+ btFixedDec -- Fixed Decimal
+ btFloatDec -- Float Decimal
+ btString -- Varying Length Character String
+ btBit -- Aligned Bit String
+ btPicture -- Picture
+ btVoid -- Void (MIPS cc revision >= 2.00)
+
+ d) tq0 - tq5: type qualifier fields as needed. The
+ current type qualifier fields I have documentation for
+ are:
+
+ tqNil -- no more qualifiers
+ tqPtr -- pointer
+ tqProc -- procedure
+ tqArray -- array
+ tqFar -- 8086 far pointers
+ tqVol -- volatile
+
+
+ The dense number table is used in the front ends, and disappears by
+ the time the .o is created.
+
+ With the 1.31 compiler suite, the optimization symbols don't seem
+ to be used as far as I can tell.
+
+ The linker is the first entity that creates the relative file
+ descriptor table, and I believe it is used so that the individual
+ file table pointers don't have to be rewritten when the objects are
+ merged together into the program file.
+
+ Unlike COFF, the basic symbol & string tables are split into
+ external and local symbols/strings. The relocation information
+ only goes off of the external symbol table, and the debug
+ information only goes off of the internal symbol table. The
+ external symbols can have links to an appropriate file index and
+ symbol within the file to give it the appropriate type information.
+ Because of this, the external symbols are actually larger than the
+ internal symbols (to contain the link information), and contain the
+ local symbol structure as a member, though this member is not the
+ first member of the external symbol structure (!). I suspect this
+ split is to make strip easier to deal with.
+
+ Each file table has offsets for where the line numbers, local
+ strings, local symbols, and procedure table starts from within the
+ global tables, and the indexs are reset to 0 for each of those
+ tables for the file.
+
+ The procedure table contains the binary equivalents of the .ent
+ (start of the function address), .frame (what register is the
+ virtual frame pointer, constant offset from the register to obtain
+ the VFP, and what register holds the return address), .mask/.fmask
+ (bitmask of saved registers, and where the first register is stored
+ relative to the VFP) assembler directives. It also contains the
+ low and high bounds of the line numbers if debugging is turned on.
+
+ The line number table is a compressed form of the normal COFF line
+ table. Each line number entry is either 1 or 3 bytes long, and
+ contains a signed delta from the previous line, and an unsigned
+ count of the number of instructions this statement takes.
+
+ The local symbol table contains the following fields:
+
+ 1) iss: index to the local string table giving the name of the
+ symbol.
+
+ 2) value: value of the symbol (address, register number, etc.).
+
+ 3) st: symbol type. The current symbol types are:
+
+ stNil -- Nuthin' special
+ stGlobal -- external symbol
+ stStatic -- static
+ stParam -- procedure argument
+ stLocal -- local variable
+ stLabel -- label
+ stProc -- External Procedure
+ stBlock -- beginning of block
+ stEnd -- end (of anything)
+ stMember -- member (of anything)
+ stTypedef -- type definition
+ stFile -- file name
+ stRegReloc -- register relocation
+ stForward -- forwarding address
+ stStaticProc -- Static procedure
+ stConstant -- const
+
+ 4) sc: storage class. The current storage classes are:
+
+ scText -- text symbol
+ scData -- initialized data symbol
+ scBss -- un-initialized data symbol
+ scRegister -- value of symbol is register number
+ scAbs -- value of symbol is absolute
+ scUndefined -- who knows?
+ scCdbLocal -- variable's value is IN se->va.??
+ scBits -- this is a bit field
+ scCdbSystem -- value is IN debugger's address space
+ scRegImage -- register value saved on stack
+ scInfo -- symbol contains debugger information
+ scUserStruct -- addr in struct user for current process
+ scSData -- load time only small data
+ scSBss -- load time only small common
+ scRData -- load time only read only data
+ scVar -- Var parameter (fortranpascal)
+ scCommon -- common variable
+ scSCommon -- small common
+ scVarRegister -- Var parameter in a register
+ scVariant -- Variant record
+ scSUndefined -- small undefined(external) data
+ scInit -- .init section symbol
+
+ 5) index: pointer to a local symbol or aux. entry.
+
+
+
+ For the following program:
+
+ #include <stdio.h>
+
+ main(){
+ printf("Hello World!\n");
+ return 0;
+ }
+
+ Mips-tdump produces the following information:
+
+ Global file header:
+ magic number 0x162
+ # sections 2
+ timestamp 645311799, Wed Jun 13 17:16:39 1990
+ symbolic header offset 284
+ symbolic header size 96
+ optional header 56
+ flags 0x0
+
+ Symbolic header, magic number = 0x7009, vstamp = 1.31:
+
+ Info Offset Number Bytes
+ ==== ====== ====== =====
+
+ Line numbers 380 4 4 [13]
+ Dense numbers 0 0 0
+ Procedures Tables 384 1 52
+ Local Symbols 436 16 192
+ Optimization Symbols 0 0 0
+ Auxiliary Symbols 628 39 156
+ Local Strings 784 80 80
+ External Strings 864 144 144
+ File Tables 1008 2 144
+ Relative Files 0 0 0
+ External Symbols 1152 20 320
+
+ File #0, "hello2.c"
+
+ Name index = 1 Readin = No
+ Merge = No Endian = LITTLE
+ Debug level = G2 Language = C
+ Adr = 0x00000000
+
+ Info Start Number Size Offset
+ ==== ===== ====== ==== ======
+ Local strings 0 15 15 784
+ Local symbols 0 6 72 436
+ Line numbers 0 13 13 380
+ Optimization symbols 0 0 0 0
+ Procedures 0 1 52 384
+ Auxiliary symbols 0 14 56 628
+ Relative Files 0 0 0 0
+
+ There are 6 local symbols, starting at 436
+
+ Symbol# 0: "hello2.c"
+ End+1 symbol = 6
+ String index = 1
+ Storage class = Text Index = 6
+ Symbol type = File Value = 0
+
+ Symbol# 1: "main"
+ End+1 symbol = 5
+ Type = int
+ String index = 10
+ Storage class = Text Index = 12
+ Symbol type = Proc Value = 0
+
+ Symbol# 2: ""
+ End+1 symbol = 4
+ String index = 0
+ Storage class = Text Index = 4
+ Symbol type = Block Value = 8
+
+ Symbol# 3: ""
+ First symbol = 2
+ String index = 0
+ Storage class = Text Index = 2
+ Symbol type = End Value = 28
+
+ Symbol# 4: "main"
+ First symbol = 1
+ String index = 10
+ Storage class = Text Index = 1
+ Symbol type = End Value = 52
+
+ Symbol# 5: "hello2.c"
+ First symbol = 0
+ String index = 1
+ Storage class = Text Index = 0
+ Symbol type = End Value = 0
+
+ There are 14 auxiliary table entries, starting at 628.
+
+ * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
+ * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
+ * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
+ * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
+ * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
+ * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
+ * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
+ * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
+ * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
+ * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
+ * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
+ #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
+ #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
+
+ There are 1 procedure descriptor entries, starting at 0.
+
+ Procedure descriptor 0:
+ Name index = 10 Name = "main"
+ .mask 0x80000000,-4 .fmask 0x00000000,0
+ .frame $29,24,$31
+ Opt. start = -1 Symbols start = 1
+ First line # = 3 Last line # = 6
+ Line Offset = 0 Address = 0x00000000
+
+ There are 4 bytes holding line numbers, starting at 380.
+ Line 3, delta 0, count 2
+ Line 4, delta 1, count 3
+ Line 5, delta 1, count 2
+ Line 6, delta 1, count 6
+
+ File #1, "/usr/include/stdio.h"
+
+ Name index = 1 Readin = No
+ Merge = Yes Endian = LITTLE
+ Debug level = G2 Language = C
+ Adr = 0x00000000
+
+ Info Start Number Size Offset
+ ==== ===== ====== ==== ======
+ Local strings 15 65 65 799
+ Local symbols 6 10 120 508
+ Line numbers 0 0 0 380
+ Optimization symbols 0 0 0 0
+ Procedures 1 0 0 436
+ Auxiliary symbols 14 25 100 684
+ Relative Files 0 0 0 0
+
+ There are 10 local symbols, starting at 442
+
+ Symbol# 0: "/usr/include/stdio.h"
+ End+1 symbol = 10
+ String index = 1
+ Storage class = Text Index = 10
+ Symbol type = File Value = 0
+
+ Symbol# 1: "_iobuf"
+ End+1 symbol = 9
+ String index = 22
+ Storage class = Info Index = 9
+ Symbol type = Block Value = 20
+
+ Symbol# 2: "_cnt"
+ Type = int
+ String index = 29
+ Storage class = Info Index = 4
+ Symbol type = Member Value = 0
+
+ Symbol# 3: "_ptr"
+ Type = ptr to char
+ String index = 34
+ Storage class = Info Index = 15
+ Symbol type = Member Value = 32
+
+ Symbol# 4: "_base"
+ Type = ptr to char
+ String index = 39
+ Storage class = Info Index = 16
+ Symbol type = Member Value = 64
+
+ Symbol# 5: "_bufsiz"
+ Type = int
+ String index = 45
+ Storage class = Info Index = 4
+ Symbol type = Member Value = 96
+
+ Symbol# 6: "_flag"
+ Type = short
+ String index = 53
+ Storage class = Info Index = 3
+ Symbol type = Member Value = 128
+
+ Symbol# 7: "_file"
+ Type = char
+ String index = 59
+ Storage class = Info Index = 2
+ Symbol type = Member Value = 144
+
+ Symbol# 8: ""
+ First symbol = 1
+ String index = 0
+ Storage class = Info Index = 1
+ Symbol type = End Value = 0
+
+ Symbol# 9: "/usr/include/stdio.h"
+ First symbol = 0
+ String index = 1
+ Storage class = Text Index = 0
+ Symbol type = End Value = 0
+
+ There are 25 auxiliary table entries, starting at 642.
+
+ * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
+ #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
+ #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
+ * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
+ * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
+ * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
+ * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
+ * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
+ * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
+ * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
+ * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+ * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
+
+ There are 0 procedure descriptor entries, starting at 1.
+
+ There are 20 external symbols, starting at 1152
+
+ Symbol# 0: "_iob"
+ Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
+ String index = 0 Ifd = 1
+ Storage class = Nil Index = 17
+ Symbol type = Global Value = 60
+
+ Symbol# 1: "fopen"
+ String index = 5 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 2: "fdopen"
+ String index = 11 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 3: "freopen"
+ String index = 18 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 4: "popen"
+ String index = 26 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 5: "tmpfile"
+ String index = 32 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 6: "ftell"
+ String index = 40 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 7: "rewind"
+ String index = 46 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 8: "setbuf"
+ String index = 53 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 9: "setbuffer"
+ String index = 60 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 10: "setlinebuf"
+ String index = 70 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 11: "fgets"
+ String index = 81 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 12: "gets"
+ String index = 87 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 13: "ctermid"
+ String index = 92 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 14: "cuserid"
+ String index = 100 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 15: "tempnam"
+ String index = 108 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 16: "tmpnam"
+ String index = 116 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 17: "sprintf"
+ String index = 123 Ifd = 1
+ Storage class = Nil Index = 1048575
+ Symbol type = Proc Value = 0
+
+ Symbol# 18: "main"
+ Type = int
+ String index = 131 Ifd = 0
+ Storage class = Text Index = 1
+ Symbol type = Proc Value = 0
+
+ Symbol# 19: "printf"
+ String index = 136 Ifd = 0
+ Storage class = Undefined Index = 1048575
+ Symbol type = Proc Value = 0
+
+ The following auxiliary table entries were unused:
+
+ #0 0 0x00000000 void
+ #2 8 0x00000008 char
+ #3 16 0x00000010 short
+ #4 24 0x00000018 int
+ #5 32 0x00000020 long
+ #6 40 0x00000028 float
+ #7 44 0x0000002c double
+ #8 12 0x0000000c unsigned char
+ #9 20 0x00000014 unsigned short
+ #10 28 0x0000001c unsigned int
+ #11 36 0x00000024 unsigned long
+ #14 0 0x00000000 void
+ #15 24 0x00000018 int
+ #19 32 0x00000020 long
+ #20 40 0x00000028 float
+ #21 44 0x0000002c double
+ #22 12 0x0000000c unsigned char
+ #23 20 0x00000014 unsigned short
+ #24 28 0x0000001c unsigned int
+ #25 36 0x00000024 unsigned long
+ #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
+*/
+
+/* Redefinition of of storage classes as an enumeration for better
+ debugging. */
+
+typedef enum sc {
+ sc_Nil = scNil, /* no storage class */
+ sc_Text = scText, /* text symbol */
+ sc_Data = scData, /* initialized data symbol */
+ sc_Bss = scBss, /* un-initialized data symbol */
+ sc_Register = scRegister, /* value of symbol is register number */
+ sc_Abs = scAbs, /* value of symbol is absolute */
+ sc_Undefined = scUndefined, /* who knows? */
+ sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
+ sc_Bits = scBits, /* this is a bit field */
+ sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
+ sc_RegImage = scRegImage, /* register value saved on stack */
+ sc_Info = scInfo, /* symbol contains debugger information */
+ sc_UserStruct = scUserStruct, /* addr in struct user for current process */
+ sc_SData = scSData, /* load time only small data */
+ sc_SBss = scSBss, /* load time only small common */
+ sc_RData = scRData, /* load time only read only data */
+ sc_Var = scVar, /* Var parameter (fortran,pascal) */
+ sc_Common = scCommon, /* common variable */
+ sc_SCommon = scSCommon, /* small common */
+ sc_VarRegister = scVarRegister, /* Var parameter in a register */
+ sc_Variant = scVariant, /* Variant record */
+ sc_SUndefined = scSUndefined, /* small undefined(external) data */
+ sc_Init = scInit, /* .init section symbol */
+ sc_Max = scMax /* Max storage class+1 */
+} sc_t;
+
+/* Redefinition of symbol type. */
+
+typedef enum st {
+ st_Nil = stNil, /* Nuthin' special */
+ st_Global = stGlobal, /* external symbol */
+ st_Static = stStatic, /* static */
+ st_Param = stParam, /* procedure argument */
+ st_Local = stLocal, /* local variable */
+ st_Label = stLabel, /* label */
+ st_Proc = stProc, /* " " Procedure */
+ st_Block = stBlock, /* beginning of block */
+ st_End = stEnd, /* end (of anything) */
+ st_Member = stMember, /* member (of anything - struct/union/enum */
+ st_Typedef = stTypedef, /* type definition */
+ st_File = stFile, /* file name */
+ st_RegReloc = stRegReloc, /* register relocation */
+ st_Forward = stForward, /* forwarding address */
+ st_StaticProc = stStaticProc, /* load time only static procs */
+ st_Constant = stConstant, /* const */
+ st_Str = stStr, /* string */
+ st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
+ st_Expr = stExpr, /* 2+2 vs. 4 */
+ st_Type = stType, /* post-coercion SER */
+ st_Max = stMax /* max type+1 */
+} st_t;
+
+/* Redefinition of type qualifiers. */
+
+typedef enum tq {
+ tq_Nil = tqNil, /* bt is what you see */
+ tq_Ptr = tqPtr, /* pointer */
+ tq_Proc = tqProc, /* procedure */
+ tq_Array = tqArray, /* duh */
+ tq_Far = tqFar, /* longer addressing - 8086/8 land */
+ tq_Vol = tqVol, /* volatile */
+ tq_Max = tqMax /* Max type qualifier+1 */
+} tq_t;
+
+/* Redefinition of basic types. */
+
+typedef enum bt {
+ bt_Nil = btNil, /* undefined */
+ bt_Adr = btAdr, /* address - integer same size as pointer */
+ bt_Char = btChar, /* character */
+ bt_UChar = btUChar, /* unsigned character */
+ bt_Short = btShort, /* short */
+ bt_UShort = btUShort, /* unsigned short */
+ bt_Int = btInt, /* int */
+ bt_UInt = btUInt, /* unsigned int */
+ bt_Long = btLong, /* long */
+ bt_ULong = btULong, /* unsigned long */
+ bt_Float = btFloat, /* float (real) */
+ bt_Double = btDouble, /* Double (real) */
+ bt_Struct = btStruct, /* Structure (Record) */
+ bt_Union = btUnion, /* Union (variant) */
+ bt_Enum = btEnum, /* Enumerated */
+ bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
+ bt_Range = btRange, /* subrange of int */
+ bt_Set = btSet, /* pascal sets */
+ bt_Complex = btComplex, /* fortran complex */
+ bt_DComplex = btDComplex, /* fortran double complex */
+ bt_Indirect = btIndirect, /* forward or unnamed typedef */
+ bt_FixedDec = btFixedDec, /* Fixed Decimal */
+ bt_FloatDec = btFloatDec, /* Float Decimal */
+ bt_String = btString, /* Varying Length Character String */
+ bt_Bit = btBit, /* Aligned Bit String */
+ bt_Picture = btPicture, /* Picture */
+ bt_Void = btVoid, /* Void */
+ bt_Max = btMax /* Max basic type+1 */
+} bt_t;
+
+#define N_TQ itqMax
+
+/* States for whether to hash type or not. */
+typedef enum hash_state {
+ hash_no = 0, /* don't hash type */
+ hash_yes = 1, /* ok to hash type, or use previous hash */
+ hash_record = 2 /* ok to record hash, but don't use prev. */
+} hash_state_t;
+
+/* Types of different sized allocation requests. */
+enum alloc_type {
+ alloc_type_none, /* dummy value */
+ alloc_type_scope, /* nested scopes linked list */
+ alloc_type_vlinks, /* glue linking pages in varray */
+ alloc_type_shash, /* string hash element */
+ alloc_type_thash, /* type hash element */
+ alloc_type_tag, /* struct/union/tag element */
+ alloc_type_forward, /* element to hold unknown tag */
+ alloc_type_thead, /* head of type hash list */
+ alloc_type_varray, /* general varray allocation */
+ alloc_type_lineno, /* line number list */
+ alloc_type_last /* last+1 element for array bounds */
+};
+
+/* Types of auxiliary type information. */
+enum aux_type {
+ aux_tir, /* TIR type information */
+ aux_rndx, /* relative index into symbol table */
+ aux_dnLow, /* low dimension */
+ aux_dnHigh, /* high dimension */
+ aux_isym, /* symbol table index (end of proc) */
+ aux_iss, /* index into string space (not used) */
+ aux_width, /* width for non-default sized struc fields */
+ aux_count /* count of ranges for variant arm */
+};
+
+/* Structures to provide n-number of virtual arrays, each of which can
+ grow linearly, and which are written in the object file as
+ sequential pages. On systems with a BSD malloc, the
+ MAX_CLUSTER_PAGES should be 1 less than a power of two, since
+ malloc adds it's overhead, and rounds up to the next power of 2.
+ Pages are linked together via a linked list.
+
+ If PAGE_SIZE is > 4096, the string length in the shash_t structure
+ can't be represented (assuming there are strings > 4096 bytes). */
+
+/* FIXME: Yes, there can be such strings while emitting C++ class debug
+ info. Templates are the offender here, the test case in question
+ having a mangled class name of
+
+ t7rb_tree4Z4xkeyZt4pair2ZC4xkeyZt7xsocket1Z4UserZt9select1st2Zt4pair\
+ 2ZC4xkeyZt7xsocket1Z4UserZ4xkeyZt4less1Z4xkey
+
+ Repeat that a couple dozen times while listing the class members and
+ you've got strings over 4k. Hack around this for now by increasing
+ the page size. A proper solution would abandon this structure scheme
+ certainly for very large strings, and possibly entirely. */
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (8*1024) /* size of varray pages */
+#endif
+
+#define PAGE_USIZE ((unsigned long) PAGE_SIZE)
+
+#ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
+#define MAX_CLUSTER_PAGES 63
+#endif
+
+/* Linked list connecting separate page allocations. */
+typedef struct vlinks {
+ struct vlinks *prev; /* previous set of pages */
+ struct vlinks *next; /* next set of pages */
+ union page *datum; /* start of page */
+ unsigned long start_index; /* starting index # of page */
+} vlinks_t;
+
+
+/* Virtual array header. */
+typedef struct varray {
+ vlinks_t *first; /* first page link */
+ vlinks_t *last; /* last page link */
+ unsigned long num_allocated; /* # objects allocated */
+ unsigned short object_size; /* size in bytes of each object */
+ unsigned short objects_per_page; /* # objects that can fit on a page */
+ unsigned short objects_last_page; /* # objects allocated on last page */
+} varray_t;
+
+#ifndef MALLOC_CHECK
+#define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
+#else
+#define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
+#endif
+
+#define INIT_VARRAY(type) { /* macro to initialize a varray */ \
+ (vlinks_t *)0, /* first */ \
+ (vlinks_t *)0, /* last */ \
+ 0, /* num_allocated */ \
+ sizeof (type), /* object_size */ \
+ OBJECTS_PER_PAGE (type), /* objects_per_page */ \
+ OBJECTS_PER_PAGE (type), /* objects_last_page */ \
+}
+
+
+/* Master type for indexes within the symbol table. */
+typedef unsigned long symint_t;
+
+
+/* Linked list support for nested scopes (file, block, structure, etc.). */
+typedef struct scope {
+ struct scope *prev; /* previous scope level */
+ struct scope *free; /* free list pointer */
+ struct localsym *lsym; /* pointer to local symbol node */
+ st_t type; /* type of the node */
+} scope_t;
+
+
+/* For a local symbol we store a gas symbol as well as the debugging
+ information we generate. The gas symbol will be NULL if this is
+ only a debugging symbol. */
+typedef struct localsym {
+ const char *name; /* symbol name */
+ symbolS *as_sym; /* symbol as seen by gas */
+ bfd_vma addend; /* addend to as_sym value */
+ struct efdr *file_ptr; /* file pointer */
+ struct ecoff_proc *proc_ptr; /* proc pointer */
+ struct localsym *begin_ptr; /* symbol at start of block */
+ struct ecoff_aux *index_ptr; /* index value to be filled in */
+ struct forward *forward_ref; /* forward references to this symbol */
+ long sym_index; /* final symbol index */
+ EXTR ecoff_sym; /* ECOFF debugging symbol */
+} localsym_t;
+
+
+/* For aux information we keep the type and the data. */
+typedef struct ecoff_aux {
+ enum aux_type type; /* aux type */
+ AUXU data; /* aux data */
+} aux_t;
+
+/* For a procedure we store the gas symbol as well as the PDR
+ debugging information. */
+typedef struct ecoff_proc {
+ localsym_t *sym; /* associated symbol */
+ PDR pdr; /* ECOFF debugging info */
+} proc_t;
+
+/* Number of proc_t structures allocated. */
+static unsigned long proc_cnt;
+
+
+/* Forward reference list for tags referenced, but not yet defined. */
+typedef struct forward {
+ struct forward *next; /* next forward reference */
+ struct forward *free; /* free list pointer */
+ aux_t *ifd_ptr; /* pointer to store file index */
+ aux_t *index_ptr; /* pointer to store symbol index */
+} forward_t;
+
+
+/* Linked list support for tags. The first tag in the list is always
+ the current tag for that block. */
+typedef struct tag {
+ struct tag *free; /* free list pointer */
+ struct shash *hash_ptr; /* pointer to the hash table head */
+ struct tag *same_name; /* tag with same name in outer scope */
+ struct tag *same_block; /* next tag defined in the same block. */
+ struct forward *forward_ref; /* list of forward references */
+ bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
+ symint_t ifd; /* file # tag defined in */
+ localsym_t *sym; /* file's local symbols */
+} tag_t;
+
+
+/* Head of a block's linked list of tags. */
+typedef struct thead {
+ struct thead *prev; /* previous block */
+ struct thead *free; /* free list pointer */
+ struct tag *first_tag; /* first tag in block defined */
+} thead_t;
+
+
+/* Union containing pointers to each the small structures which are freed up. */
+typedef union small_free {
+ scope_t *f_scope; /* scope structure */
+ thead_t *f_thead; /* tag head structure */
+ tag_t *f_tag; /* tag element structure */
+ forward_t *f_forward; /* forward tag reference */
+} small_free_t;
+
+
+/* String hash table entry. */
+
+typedef struct shash {
+ char *string; /* string we are hashing */
+ symint_t indx; /* index within string table */
+ EXTR *esym_ptr; /* global symbol pointer */
+ localsym_t *sym_ptr; /* local symbol pointer */
+ localsym_t *end_ptr; /* symbol pointer to end block */
+ tag_t *tag_ptr; /* tag pointer */
+ proc_t *proc_ptr; /* procedure descriptor pointer */
+} shash_t;
+
+
+/* Type hash table support. The size of the hash table must fit
+ within a page with the other extended file descriptor information.
+ Because unique types which are hashed are fewer in number than
+ strings, we use a smaller hash value. */
+
+#define HASHBITS 30
+
+#ifndef THASH_SIZE
+#define THASH_SIZE 113
+#endif
+
+typedef struct thash {
+ struct thash *next; /* next hash value */
+ AUXU type; /* type we are hashing */
+ symint_t indx; /* index within string table */
+} thash_t;
+
+
+/* Extended file descriptor that contains all of the support necessary
+ to add things to each file separately. */
+typedef struct efdr {
+ FDR fdr; /* File header to be written out */
+ FDR *orig_fdr; /* original file header */
+ char *name; /* filename */
+ int fake; /* whether this is faked .file */
+ symint_t void_type; /* aux. pointer to 'void' type */
+ symint_t int_type; /* aux. pointer to 'int' type */
+ scope_t *cur_scope; /* current nested scopes */
+ symint_t file_index; /* current file number */
+ int nested_scopes; /* # nested scopes */
+ varray_t strings; /* local strings */
+ varray_t symbols; /* local symbols */
+ varray_t procs; /* procedures */
+ varray_t aux_syms; /* auxiliary symbols */
+ struct efdr *next_file; /* next file descriptor */
+ /* string/type hash tables */
+ struct hash_control *str_hash; /* string hash table */
+ thash_t *thash_head[THASH_SIZE];
+} efdr_t;
+
+/* Pre-initialized extended file structure. */
+static const efdr_t init_file =
+{
+ { /* FDR structure */
+ 0, /* adr: memory address of beginning of file */
+ 0, /* rss: file name (of source, if known) */
+ 0, /* issBase: file's string space */
+ 0, /* cbSs: number of bytes in the ss */
+ 0, /* isymBase: beginning of symbols */
+ 0, /* csym: count file's of symbols */
+ 0, /* ilineBase: file's line symbols */
+ 0, /* cline: count of file's line symbols */
+ 0, /* ioptBase: file's optimization entries */
+ 0, /* copt: count of file's optimization entries */
+ 0, /* ipdFirst: start of procedures for this file */
+ 0, /* cpd: count of procedures for this file */
+ 0, /* iauxBase: file's auxiliary entries */
+ 0, /* caux: count of file's auxiliary entries */
+ 0, /* rfdBase: index into the file indirect table */
+ 0, /* crfd: count file indirect entries */
+ langC, /* lang: language for this file */
+ 1, /* fMerge: whether this file can be merged */
+ 0, /* fReadin: true if read in (not just created) */
+ TARGET_BYTES_BIG_ENDIAN, /* fBigendian: if 1, compiled on big endian machine */
+ GLEVEL_2, /* glevel: level this file was compiled with */
+ 0, /* reserved: reserved for future use */
+ 0, /* cbLineOffset: byte offset from header for this file ln's */
+ 0, /* cbLine: size of lines for this file */
+ },
+
+ (FDR *)0, /* orig_fdr: original file header pointer */
+ (char *)0, /* name: pointer to filename */
+ 0, /* fake: whether this is a faked .file */
+ 0, /* void_type: ptr to aux node for void type */
+ 0, /* int_type: ptr to aux node for int type */
+ (scope_t *)0, /* cur_scope: current scope being processed */
+ 0, /* file_index: current file # */
+ 0, /* nested_scopes: # nested scopes */
+ INIT_VARRAY (char), /* strings: local string varray */
+ INIT_VARRAY (localsym_t), /* symbols: local symbols varray */
+ INIT_VARRAY (proc_t), /* procs: procedure varray */
+ INIT_VARRAY (aux_t), /* aux_syms: auxiliary symbols varray */
+
+ (struct efdr *)0, /* next_file: next file structure */
+
+ (struct hash_control *)0, /* str_hash: string hash table */
+ { 0 }, /* thash_head: type hash table */
+};
+
+
+static efdr_t *first_file; /* first file descriptor */
+static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
+
+
+/* Line number information is kept in a list until the assembly is
+ finished. */
+typedef struct lineno_list {
+ struct lineno_list *next; /* next element in list */
+ efdr_t *file; /* file this line is in */
+ proc_t *proc; /* procedure this line is in */
+ fragS *frag; /* fragment this line number is in */
+ unsigned long paddr; /* offset within fragment */
+ long lineno; /* actual line number */
+} lineno_list_t;
+
+static lineno_list_t *first_lineno;
+static lineno_list_t *last_lineno;
+static lineno_list_t **last_lineno_ptr = &first_lineno;
+
+/* Sometimes there will be some .loc statements before a .ent. We
+ keep them in this list so that we can fill in the procedure pointer
+ after we see the .ent. */
+static lineno_list_t *noproc_lineno;
+
+/* Union of various things that are held in pages. */
+typedef union page {
+ char byte [ PAGE_SIZE ];
+ unsigned char ubyte [ PAGE_SIZE ];
+ efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
+ FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
+ proc_t proc [ PAGE_SIZE / sizeof (proc_t) ];
+ localsym_t sym [ PAGE_SIZE / sizeof (localsym_t) ];
+ aux_t aux [ PAGE_SIZE / sizeof (aux_t) ];
+ DNR dense [ PAGE_SIZE / sizeof (DNR) ];
+ scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
+ vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
+ shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
+ thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
+ tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
+ forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
+ thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
+ lineno_list_t lineno [ PAGE_SIZE / sizeof (lineno_list_t) ];
+} page_type;
+
+
+/* Structure holding allocation information for small sized structures. */
+typedef struct alloc_info {
+ char *alloc_name; /* name of this allocation type (must be first) */
+ page_type *cur_page; /* current page being allocated from */
+ small_free_t free_list; /* current free list if any */
+ int unallocated; /* number of elements unallocated on page */
+ int total_alloc; /* total number of allocations */
+ int total_free; /* total number of frees */
+ int total_pages; /* total number of pages allocated */
+} alloc_info_t;
+
+
+/* Type information collected together. */
+typedef struct type_info {
+ bt_t basic_type; /* basic type */
+ int orig_type; /* original COFF-based type */
+ int num_tq; /* # type qualifiers */
+ int num_dims; /* # dimensions */
+ int num_sizes; /* # sizes */
+ int extra_sizes; /* # extra sizes not tied with dims */
+ tag_t * tag_ptr; /* tag pointer */
+ int bitfield; /* symbol is a bitfield */
+ tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
+ symint_t dimensions [N_TQ]; /* dimensions for each array */
+ symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
+ struct/union/enum + bitfield size */
+} type_info_t;
+
+/* Pre-initialized type_info struct. */
+static const type_info_t type_info_init = {
+ bt_Nil, /* basic type */
+ T_NULL, /* original COFF-based type */
+ 0, /* # type qualifiers */
+ 0, /* # dimensions */
+ 0, /* # sizes */
+ 0, /* sizes not tied with dims */
+ NULL, /* ptr to tag */
+ 0, /* bitfield */
+ { /* type qualifiers */
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ tq_Nil,
+ },
+ { /* dimensions */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+ { /* sizes */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+};
+
+/* Global hash table for the tags table and global table for file
+ descriptors. */
+
+static varray_t file_desc = INIT_VARRAY (efdr_t);
+
+static struct hash_control *tag_hash;
+
+/* Static types for int and void. Also, remember the last function's
+ type (which is set up when we encounter the declaration for the
+ function, and used when the end block for the function is emitted. */
+
+static type_info_t int_type_info;
+static type_info_t void_type_info;
+static type_info_t last_func_type_info;
+static symbolS *last_func_sym_value;
+
+
+/* Convert COFF basic type to ECOFF basic type. The T_NULL type
+ really should use bt_Void, but this causes the current ecoff GDB to
+ issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
+ 2.0) doesn't understand it, even though the compiler generates it.
+ Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
+ suite, but for now go with what works.
+
+ It would make sense for the .type and .scl directives to use the
+ ECOFF numbers directly, rather than using the COFF numbers and
+ mapping them. Unfortunately, this is historically what mips-tfile
+ expects, and changing gcc now would be a considerable pain (the
+ native compiler generates debugging information internally, rather
+ than via the assembler, so it will never use .type or .scl). */
+
+static const bt_t map_coff_types[] = {
+ bt_Nil, /* T_NULL */
+ bt_Nil, /* T_ARG */
+ bt_Char, /* T_CHAR */
+ bt_Short, /* T_SHORT */
+ bt_Int, /* T_INT */
+ bt_Long, /* T_LONG */
+ bt_Float, /* T_FLOAT */
+ bt_Double, /* T_DOUBLE */
+ bt_Struct, /* T_STRUCT */
+ bt_Union, /* T_UNION */
+ bt_Enum, /* T_ENUM */
+ bt_Enum, /* T_MOE */
+ bt_UChar, /* T_UCHAR */
+ bt_UShort, /* T_USHORT */
+ bt_UInt, /* T_UINT */
+ bt_ULong /* T_ULONG */
+};
+
+/* Convert COFF storage class to ECOFF storage class. */
+static const sc_t map_coff_storage[] = {
+ sc_Nil, /* 0: C_NULL */
+ sc_Abs, /* 1: C_AUTO auto var */
+ sc_Undefined, /* 2: C_EXT external */
+ sc_Data, /* 3: C_STAT static */
+ sc_Register, /* 4: C_REG register */
+ sc_Undefined, /* 5: C_EXTDEF ??? */
+ sc_Text, /* 6: C_LABEL label */
+ sc_Text, /* 7: C_ULABEL user label */
+ sc_Info, /* 8: C_MOS member of struct */
+ sc_Abs, /* 9: C_ARG argument */
+ sc_Info, /* 10: C_STRTAG struct tag */
+ sc_Info, /* 11: C_MOU member of union */
+ sc_Info, /* 12: C_UNTAG union tag */
+ sc_Info, /* 13: C_TPDEF typedef */
+ sc_Data, /* 14: C_USTATIC ??? */
+ sc_Info, /* 15: C_ENTAG enum tag */
+ sc_Info, /* 16: C_MOE member of enum */
+ sc_Register, /* 17: C_REGPARM register parameter */
+ sc_Bits, /* 18; C_FIELD bitfield */
+ sc_Nil, /* 19 */
+ sc_Nil, /* 20 */
+ sc_Nil, /* 21 */
+ sc_Nil, /* 22 */
+ sc_Nil, /* 23 */
+ sc_Nil, /* 24 */
+ sc_Nil, /* 25 */
+ sc_Nil, /* 26 */
+ sc_Nil, /* 27 */
+ sc_Nil, /* 28 */
+ sc_Nil, /* 29 */
+ sc_Nil, /* 30 */
+ sc_Nil, /* 31 */
+ sc_Nil, /* 32 */
+ sc_Nil, /* 33 */
+ sc_Nil, /* 34 */
+ sc_Nil, /* 35 */
+ sc_Nil, /* 36 */
+ sc_Nil, /* 37 */
+ sc_Nil, /* 38 */
+ sc_Nil, /* 39 */
+ sc_Nil, /* 40 */
+ sc_Nil, /* 41 */
+ sc_Nil, /* 42 */
+ sc_Nil, /* 43 */
+ sc_Nil, /* 44 */
+ sc_Nil, /* 45 */
+ sc_Nil, /* 46 */
+ sc_Nil, /* 47 */
+ sc_Nil, /* 48 */
+ sc_Nil, /* 49 */
+ sc_Nil, /* 50 */
+ sc_Nil, /* 51 */
+ sc_Nil, /* 52 */
+ sc_Nil, /* 53 */
+ sc_Nil, /* 54 */
+ sc_Nil, /* 55 */
+ sc_Nil, /* 56 */
+ sc_Nil, /* 57 */
+ sc_Nil, /* 58 */
+ sc_Nil, /* 59 */
+ sc_Nil, /* 60 */
+ sc_Nil, /* 61 */
+ sc_Nil, /* 62 */
+ sc_Nil, /* 63 */
+ sc_Nil, /* 64 */
+ sc_Nil, /* 65 */
+ sc_Nil, /* 66 */
+ sc_Nil, /* 67 */
+ sc_Nil, /* 68 */
+ sc_Nil, /* 69 */
+ sc_Nil, /* 70 */
+ sc_Nil, /* 71 */
+ sc_Nil, /* 72 */
+ sc_Nil, /* 73 */
+ sc_Nil, /* 74 */
+ sc_Nil, /* 75 */
+ sc_Nil, /* 76 */
+ sc_Nil, /* 77 */
+ sc_Nil, /* 78 */
+ sc_Nil, /* 79 */
+ sc_Nil, /* 80 */
+ sc_Nil, /* 81 */
+ sc_Nil, /* 82 */
+ sc_Nil, /* 83 */
+ sc_Nil, /* 84 */
+ sc_Nil, /* 85 */
+ sc_Nil, /* 86 */
+ sc_Nil, /* 87 */
+ sc_Nil, /* 88 */
+ sc_Nil, /* 89 */
+ sc_Nil, /* 90 */
+ sc_Nil, /* 91 */
+ sc_Nil, /* 92 */
+ sc_Nil, /* 93 */
+ sc_Nil, /* 94 */
+ sc_Nil, /* 95 */
+ sc_Nil, /* 96 */
+ sc_Nil, /* 97 */
+ sc_Nil, /* 98 */
+ sc_Nil, /* 99 */
+ sc_Text, /* 100: C_BLOCK block start/end */
+ sc_Text, /* 101: C_FCN function start/end */
+ sc_Info, /* 102: C_EOS end of struct/union/enum */
+ sc_Nil, /* 103: C_FILE file start */
+ sc_Nil, /* 104: C_LINE line number */
+ sc_Nil, /* 105: C_ALIAS combined type info */
+ sc_Nil, /* 106: C_HIDDEN ??? */
+};
+
+/* Convert COFF storage class to ECOFF symbol type. */
+static const st_t map_coff_sym_type[] = {
+ st_Nil, /* 0: C_NULL */
+ st_Local, /* 1: C_AUTO auto var */
+ st_Global, /* 2: C_EXT external */
+ st_Static, /* 3: C_STAT static */
+ st_Local, /* 4: C_REG register */
+ st_Global, /* 5: C_EXTDEF ??? */
+ st_Label, /* 6: C_LABEL label */
+ st_Label, /* 7: C_ULABEL user label */
+ st_Member, /* 8: C_MOS member of struct */
+ st_Param, /* 9: C_ARG argument */
+ st_Block, /* 10: C_STRTAG struct tag */
+ st_Member, /* 11: C_MOU member of union */
+ st_Block, /* 12: C_UNTAG union tag */
+ st_Typedef, /* 13: C_TPDEF typedef */
+ st_Static, /* 14: C_USTATIC ??? */
+ st_Block, /* 15: C_ENTAG enum tag */
+ st_Member, /* 16: C_MOE member of enum */
+ st_Param, /* 17: C_REGPARM register parameter */
+ st_Member, /* 18; C_FIELD bitfield */
+ st_Nil, /* 19 */
+ st_Nil, /* 20 */
+ st_Nil, /* 21 */
+ st_Nil, /* 22 */
+ st_Nil, /* 23 */
+ st_Nil, /* 24 */
+ st_Nil, /* 25 */
+ st_Nil, /* 26 */
+ st_Nil, /* 27 */
+ st_Nil, /* 28 */
+ st_Nil, /* 29 */
+ st_Nil, /* 30 */
+ st_Nil, /* 31 */
+ st_Nil, /* 32 */
+ st_Nil, /* 33 */
+ st_Nil, /* 34 */
+ st_Nil, /* 35 */
+ st_Nil, /* 36 */
+ st_Nil, /* 37 */
+ st_Nil, /* 38 */
+ st_Nil, /* 39 */
+ st_Nil, /* 40 */
+ st_Nil, /* 41 */
+ st_Nil, /* 42 */
+ st_Nil, /* 43 */
+ st_Nil, /* 44 */
+ st_Nil, /* 45 */
+ st_Nil, /* 46 */
+ st_Nil, /* 47 */
+ st_Nil, /* 48 */
+ st_Nil, /* 49 */
+ st_Nil, /* 50 */
+ st_Nil, /* 51 */
+ st_Nil, /* 52 */
+ st_Nil, /* 53 */
+ st_Nil, /* 54 */
+ st_Nil, /* 55 */
+ st_Nil, /* 56 */
+ st_Nil, /* 57 */
+ st_Nil, /* 58 */
+ st_Nil, /* 59 */
+ st_Nil, /* 60 */
+ st_Nil, /* 61 */
+ st_Nil, /* 62 */
+ st_Nil, /* 63 */
+ st_Nil, /* 64 */
+ st_Nil, /* 65 */
+ st_Nil, /* 66 */
+ st_Nil, /* 67 */
+ st_Nil, /* 68 */
+ st_Nil, /* 69 */
+ st_Nil, /* 70 */
+ st_Nil, /* 71 */
+ st_Nil, /* 72 */
+ st_Nil, /* 73 */
+ st_Nil, /* 74 */
+ st_Nil, /* 75 */
+ st_Nil, /* 76 */
+ st_Nil, /* 77 */
+ st_Nil, /* 78 */
+ st_Nil, /* 79 */
+ st_Nil, /* 80 */
+ st_Nil, /* 81 */
+ st_Nil, /* 82 */
+ st_Nil, /* 83 */
+ st_Nil, /* 84 */
+ st_Nil, /* 85 */
+ st_Nil, /* 86 */
+ st_Nil, /* 87 */
+ st_Nil, /* 88 */
+ st_Nil, /* 89 */
+ st_Nil, /* 90 */
+ st_Nil, /* 91 */
+ st_Nil, /* 92 */
+ st_Nil, /* 93 */
+ st_Nil, /* 94 */
+ st_Nil, /* 95 */
+ st_Nil, /* 96 */
+ st_Nil, /* 97 */
+ st_Nil, /* 98 */
+ st_Nil, /* 99 */
+ st_Block, /* 100: C_BLOCK block start/end */
+ st_Proc, /* 101: C_FCN function start/end */
+ st_End, /* 102: C_EOS end of struct/union/enum */
+ st_File, /* 103: C_FILE file start */
+ st_Nil, /* 104: C_LINE line number */
+ st_Nil, /* 105: C_ALIAS combined type info */
+ st_Nil, /* 106: C_HIDDEN ??? */
+};
+
+
+/* Keep track of different sized allocation requests. */
+static alloc_info_t alloc_counts[ (int)alloc_type_last ];
+
+/* Record whether we have seen any debugging information. */
+int ecoff_debugging_seen = 0;
+
+/* Various statics. */
+static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
+static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */
+static proc_t *first_proc_ptr = (proc_t *) 0; /* first procedure header */
+static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */
+static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */
+#ifdef ECOFF_DEBUG
+static int debug = 0; /* trace functions */
+#endif
+static int stabs_seen = 0; /* != 0 if stabs have been seen */
+
+static int current_file_idx;
+static const char *current_stabs_filename;
+
+/* Pseudo symbol to use when putting stabs into the symbol table. */
+#ifndef STABS_SYMBOL
+#define STABS_SYMBOL "@stabs"
+#endif
+
+static char stabs_symbol[] = STABS_SYMBOL;
+
+/* Prototypes for functions defined in this file. */
+
+static void add_varray_page PARAMS ((varray_t *vp));
+static symint_t add_string PARAMS ((varray_t *vp,
+ struct hash_control *hash_tbl,
+ const char *str,
+ shash_t **ret_hash));
+static localsym_t *add_ecoff_symbol PARAMS ((const char *str, st_t type,
+ sc_t storage, symbolS *sym,
+ bfd_vma addend, symint_t value,
+ symint_t indx));
+static symint_t add_aux_sym_symint PARAMS ((symint_t aux_word));
+static symint_t add_aux_sym_rndx PARAMS ((int file_index,
+ symint_t sym_index));
+static symint_t add_aux_sym_tir PARAMS ((type_info_t *t,
+ hash_state_t state,
+ thash_t **hash_tbl));
+static tag_t *get_tag PARAMS ((const char *tag, localsym_t *sym,
+ bt_t basic_type));
+static void add_unknown_tag PARAMS ((tag_t *ptag));
+static void add_procedure PARAMS ((char *func));
+static void add_file PARAMS ((const char *file_name, int indx, int fake));
+#ifdef ECOFF_DEBUG
+static char *sc_to_string PARAMS ((sc_t storage_class));
+static char *st_to_string PARAMS ((st_t symbol_type));
+#endif
+static void mark_stabs PARAMS ((int));
+static char *ecoff_add_bytes PARAMS ((char **buf, char **bufend,
+ char *bufptr, unsigned long need));
+static unsigned long ecoff_padding_adjust
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset, char **bufptrptr));
+static unsigned long ecoff_build_lineno
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset, long *linecntptr));
+static unsigned long ecoff_build_symbols
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset));
+static unsigned long ecoff_build_procs
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset));
+static unsigned long ecoff_build_aux
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset));
+static unsigned long ecoff_build_strings PARAMS ((char **buf, char **bufend,
+ unsigned long offset,
+ varray_t *vp));
+static unsigned long ecoff_build_ss
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset));
+static unsigned long ecoff_build_fdr
+ PARAMS ((const struct ecoff_debug_swap *backend, char **buf, char **bufend,
+ unsigned long offset));
+static void ecoff_setup_ext PARAMS ((void));
+static page_type *allocate_cluster PARAMS ((unsigned long npages));
+static page_type *allocate_page PARAMS ((void));
+static scope_t *allocate_scope PARAMS ((void));
+static void free_scope PARAMS ((scope_t *ptr));
+static vlinks_t *allocate_vlinks PARAMS ((void));
+static shash_t *allocate_shash PARAMS ((void));
+static thash_t *allocate_thash PARAMS ((void));
+static tag_t *allocate_tag PARAMS ((void));
+static void free_tag PARAMS ((tag_t *ptr));
+static forward_t *allocate_forward PARAMS ((void));
+static thead_t *allocate_thead PARAMS ((void));
+static void free_thead PARAMS ((thead_t *ptr));
+static lineno_list_t *allocate_lineno_list PARAMS ((void));
+
+/* This function should be called when the assembler starts up. */
+
+void
+ecoff_read_begin_hook ()
+{
+ tag_hash = hash_new ();
+ top_tag_head = allocate_thead ();
+ top_tag_head->first_tag = (tag_t *) NULL;
+ top_tag_head->free = (thead_t *) NULL;
+ top_tag_head->prev = cur_tag_head;
+ cur_tag_head = top_tag_head;
+}
+
+/* This function should be called when a symbol is created. */
+
+void
+ecoff_symbol_new_hook (symbolP)
+ symbolS *symbolP;
+{
+ /* Make sure that we have a file pointer, but only if we have seen a
+ file. If we haven't seen a file, then this is a probably special
+ symbol created by md_begin which may required special handling at
+ some point. Creating a dummy file with a dummy name is certainly
+ wrong. */
+ if (cur_file_ptr == (efdr_t *) NULL
+ && seen_at_least_1_file ())
+ add_file ((const char *) NULL, 0, 1);
+ symbolP->ecoff_file = cur_file_ptr;
+ symbolP->ecoff_symbol = NULL;
+ symbolP->ecoff_extern_size = 0;
+}
+
+/* Add a page to a varray object. */
+
+static void
+add_varray_page (vp)
+ varray_t *vp; /* varray to add page to */
+{
+ vlinks_t *new_links = allocate_vlinks ();
+
+#ifdef MALLOC_CHECK
+ if (vp->object_size > 1)
+ new_links->datum = (page_type *) xcalloc (1, vp->object_size);
+ else
+#endif
+ new_links->datum = allocate_page ();
+
+ alloc_counts[(int)alloc_type_varray].total_alloc++;
+ alloc_counts[(int)alloc_type_varray].total_pages++;
+
+ new_links->start_index = vp->num_allocated;
+ vp->objects_last_page = 0;
+
+ if (vp->first == (vlinks_t *) NULL) /* first allocation? */
+ vp->first = vp->last = new_links;
+ else
+ { /* 2nd or greater allocation */
+ new_links->prev = vp->last;
+ vp->last->next = new_links;
+ vp->last = new_links;
+ }
+}
+
+/* Add a string (and null pad) to one of the string tables. */
+
+static symint_t
+add_string (vp, hash_tbl, str, ret_hash)
+ varray_t *vp; /* string obstack */
+ struct hash_control *hash_tbl; /* ptr to hash table */
+ const char *str; /* string */
+ shash_t **ret_hash; /* return hash pointer */
+{
+ register unsigned long len = strlen (str);
+ register shash_t *hash_ptr;
+
+ if (len >= PAGE_USIZE)
+ as_fatal (_("String too big (%lu bytes)"), len);
+
+ hash_ptr = (shash_t *) hash_find (hash_tbl, str);
+ if (hash_ptr == (shash_t *) NULL)
+ {
+ register const char *err;
+
+ if (vp->objects_last_page + len >= PAGE_USIZE)
+ {
+ vp->num_allocated =
+ ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
+ add_varray_page (vp);
+ }
+
+ hash_ptr = allocate_shash ();
+ hash_ptr->indx = vp->num_allocated;
+
+ hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page];
+
+ vp->objects_last_page += len + 1;
+ vp->num_allocated += len + 1;
+
+ strcpy (hash_ptr->string, str);
+
+ err = hash_insert (hash_tbl, str, (char *) hash_ptr);
+ if (err)
+ as_fatal (_("Inserting \"%s\" into string hash table: %s"),
+ str, err);
+ }
+
+ if (ret_hash != (shash_t **) NULL)
+ *ret_hash = hash_ptr;
+
+ return hash_ptr->indx;
+}
+
+/* Add debugging information for a symbol. */
+
+static localsym_t *
+add_ecoff_symbol (str, type, storage, sym_value, addend, value, indx)
+ const char *str; /* symbol name */
+ st_t type; /* symbol type */
+ sc_t storage; /* storage class */
+ symbolS *sym_value; /* associated symbol. */
+ bfd_vma addend; /* addend to sym_value. */
+ symint_t value; /* value of symbol */
+ symint_t indx; /* index to local/aux. syms */
+{
+ localsym_t *psym;
+ register scope_t *pscope;
+ register thead_t *ptag_head;
+ register tag_t *ptag;
+ register tag_t *ptag_next;
+ register varray_t *vp;
+ register int scope_delta = 0;
+ shash_t *hash_ptr = (shash_t *) NULL;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->symbols;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
+
+ if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
+ psym->name = S_GET_NAME (sym_value);
+ else
+ psym->name = str;
+ psym->as_sym = sym_value;
+ if (sym_value != (symbolS *) NULL)
+ sym_value->ecoff_symbol = psym;
+ psym->addend = addend;
+ psym->file_ptr = cur_file_ptr;
+ psym->proc_ptr = cur_proc_ptr;
+ psym->begin_ptr = (localsym_t *) NULL;
+ psym->index_ptr = (aux_t *) NULL;
+ psym->forward_ref = (forward_t *) NULL;
+ psym->sym_index = -1;
+ memset (&psym->ecoff_sym, 0, sizeof (EXTR));
+ psym->ecoff_sym.asym.value = value;
+ psym->ecoff_sym.asym.st = (unsigned) type;
+ psym->ecoff_sym.asym.sc = (unsigned) storage;
+ psym->ecoff_sym.asym.index = indx;
+
+ /* If there is an associated symbol, we wait until the end of the
+ assembly before deciding where to put the name (it may be just an
+ external symbol). Otherwise, this is just a debugging symbol and
+ the name should go with the current file. */
+ if (sym_value == (symbolS *) NULL)
+ psym->ecoff_sym.asym.iss = ((str == (const char *) NULL)
+ ? 0
+ : add_string (&cur_file_ptr->strings,
+ cur_file_ptr->str_hash,
+ str,
+ &hash_ptr));
+
+ ++vp->num_allocated;
+
+ if (ECOFF_IS_STAB (&psym->ecoff_sym.asym))
+ return psym;
+
+ /* Save the symbol within the hash table if this is a static
+ item, and it has a name. */
+ if (hash_ptr != (shash_t *) NULL
+ && (type == st_Global || type == st_Static || type == st_Label
+ || type == st_Proc || type == st_StaticProc))
+ hash_ptr->sym_ptr = psym;
+
+ /* push or pop a scope if appropriate. */
+ switch (type)
+ {
+ default:
+ break;
+
+ case st_File: /* beginning of file */
+ case st_Proc: /* procedure */
+ case st_StaticProc: /* static procedure */
+ case st_Block: /* begin scope */
+ pscope = allocate_scope ();
+ pscope->prev = cur_file_ptr->cur_scope;
+ pscope->lsym = psym;
+ pscope->type = type;
+ cur_file_ptr->cur_scope = pscope;
+
+ if (type != st_File)
+ scope_delta = 1;
+
+ /* For every block type except file, struct, union, or
+ enumeration blocks, push a level on the tag stack. We omit
+ file types, so that tags can span file boundaries. */
+ if (type != st_File && storage != sc_Info)
+ {
+ ptag_head = allocate_thead ();
+ ptag_head->first_tag = 0;
+ ptag_head->prev = cur_tag_head;
+ cur_tag_head = ptag_head;
+ }
+ break;
+
+ case st_End:
+ pscope = cur_file_ptr->cur_scope;
+ if (pscope == (scope_t *) NULL)
+ as_fatal (_("too many st_End's"));
+ else
+ {
+ st_t begin_type = (st_t) pscope->lsym->ecoff_sym.asym.st;
+
+ psym->begin_ptr = pscope->lsym;
+
+ if (begin_type != st_File)
+ scope_delta = -1;
+
+ /* Except for file, structure, union, or enumeration end
+ blocks remove all tags created within this scope. */
+ if (begin_type != st_File && storage != sc_Info)
+ {
+ ptag_head = cur_tag_head;
+ cur_tag_head = ptag_head->prev;
+
+ for (ptag = ptag_head->first_tag;
+ ptag != (tag_t *) NULL;
+ ptag = ptag_next)
+ {
+ if (ptag->forward_ref != (forward_t *) NULL)
+ add_unknown_tag (ptag);
+
+ ptag_next = ptag->same_block;
+ ptag->hash_ptr->tag_ptr = ptag->same_name;
+ free_tag (ptag);
+ }
+
+ free_thead (ptag_head);
+ }
+
+ cur_file_ptr->cur_scope = pscope->prev;
+
+ /* block begin gets next sym #. This is set when we know
+ the symbol index value. */
+
+ /* Functions push two or more aux words as follows:
+ 1st word: index+1 of the end symbol (filled in later).
+ 2nd word: type of the function (plus any aux words needed).
+ Also, tie the external pointer back to the function begin symbol. */
+ if (begin_type != st_File && begin_type != st_Block)
+ {
+ symint_t ty;
+ varray_t *svp = &cur_file_ptr->aux_syms;
+
+ pscope->lsym->ecoff_sym.asym.index = add_aux_sym_symint (0);
+ pscope->lsym->index_ptr =
+ &svp->last->datum->aux[svp->objects_last_page - 1];
+ ty = add_aux_sym_tir (&last_func_type_info,
+ hash_no,
+ &cur_file_ptr->thash_head[0]);
+
+/* This seems to be unnecessary. I'm not even sure what it is
+ * intended to do. It's from mips-tfile.
+ * if (last_func_sym_value != (symbolS *) NULL)
+ * {
+ * last_func_sym_value->ifd = cur_file_ptr->file_index;
+ * last_func_sym_value->index = ty;
+ * }
+ */
+ }
+
+ free_scope (pscope);
+ }
+ }
+
+ cur_file_ptr->nested_scopes += scope_delta;
+
+#ifdef ECOFF_DEBUG
+ if (debug && type != st_File
+ && (debug > 2 || type == st_Block || type == st_End
+ || type == st_Proc || type == st_StaticProc))
+ {
+ char *sc_str = sc_to_string (storage);
+ char *st_str = st_to_string (type);
+ int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
+
+ fprintf (stderr,
+ "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
+ value, depth, sc_str);
+
+ if (str_start && str_end_p1 - str_start > 0)
+ fprintf (stderr, " st= %-11s name= %.*s\n", st_str, str_end_p1 - str_start, str_start);
+ else
+ {
+ unsigned long len = strlen (st_str);
+ fprintf (stderr, " st= %.*s\n", len-1, st_str);
+ }
+ }
+#endif
+
+ return psym;
+}
+
+/* Add an auxiliary symbol (passing a symint). This is actually used
+ for integral aux types, not just symints. */
+
+static symint_t
+add_aux_sym_symint (aux_word)
+ symint_t aux_word; /* auxiliary information word */
+{
+ register varray_t *vp;
+ register aux_t *aux_ptr;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->aux_syms;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
+ aux_ptr->type = aux_isym;
+ aux_ptr->data.isym = aux_word;
+
+ return vp->num_allocated++;
+}
+
+
+/* Add an auxiliary symbol (passing a file/symbol index combo). */
+
+static symint_t
+add_aux_sym_rndx (file_index, sym_index)
+ int file_index;
+ symint_t sym_index;
+{
+ register varray_t *vp;
+ register aux_t *aux_ptr;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->aux_syms;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
+ aux_ptr->type = aux_rndx;
+ aux_ptr->data.rndx.rfd = file_index;
+ aux_ptr->data.rndx.index = sym_index;
+
+ return vp->num_allocated++;
+}
+
+/* Add an auxiliary symbol (passing the basic type and possibly
+ type qualifiers). */
+
+static symint_t
+add_aux_sym_tir (t, state, hash_tbl)
+ type_info_t *t; /* current type information */
+ hash_state_t state; /* whether to hash type or not */
+ thash_t **hash_tbl; /* pointer to hash table to use */
+{
+ register varray_t *vp;
+ register aux_t *aux_ptr;
+ static AUXU init_aux;
+ symint_t ret;
+ int i;
+ AUXU aux;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->aux_syms;
+
+ aux = init_aux;
+ aux.ti.bt = (int) t->basic_type;
+ aux.ti.continued = 0;
+ aux.ti.fBitfield = t->bitfield;
+
+ aux.ti.tq0 = (int) t->type_qualifiers[0];
+ aux.ti.tq1 = (int) t->type_qualifiers[1];
+ aux.ti.tq2 = (int) t->type_qualifiers[2];
+ aux.ti.tq3 = (int) t->type_qualifiers[3];
+ aux.ti.tq4 = (int) t->type_qualifiers[4];
+ aux.ti.tq5 = (int) t->type_qualifiers[5];
+
+
+ /* For anything that adds additional information, we must not hash,
+ so check here, and reset our state. */
+
+ if (state != hash_no
+ && (t->type_qualifiers[0] == tq_Array
+ || t->type_qualifiers[1] == tq_Array
+ || t->type_qualifiers[2] == tq_Array
+ || t->type_qualifiers[3] == tq_Array
+ || t->type_qualifiers[4] == tq_Array
+ || t->type_qualifiers[5] == tq_Array
+ || t->basic_type == bt_Struct
+ || t->basic_type == bt_Union
+ || t->basic_type == bt_Enum
+ || t->bitfield
+ || t->num_dims > 0))
+ state = hash_no;
+
+ /* See if we can hash this type, and save some space, but some types
+ can't be hashed (because they contain arrays or continuations),
+ and others can be put into the hash list, but cannot use existing
+ types because other aux entries precede this one. */
+
+ if (state != hash_no)
+ {
+ register thash_t *hash_ptr;
+ register symint_t hi;
+
+ hi = aux.isym & ((1 << HASHBITS) - 1);
+ hi %= THASH_SIZE;
+
+ for (hash_ptr = hash_tbl[hi];
+ hash_ptr != (thash_t *)0;
+ hash_ptr = hash_ptr->next)
+ {
+ if (aux.isym == hash_ptr->type.isym)
+ break;
+ }
+
+ if (hash_ptr != (thash_t *) NULL && state == hash_yes)
+ return hash_ptr->indx;
+
+ if (hash_ptr == (thash_t *) NULL)
+ {
+ hash_ptr = allocate_thash ();
+ hash_ptr->next = hash_tbl[hi];
+ hash_ptr->type = aux;
+ hash_ptr->indx = vp->num_allocated;
+ hash_tbl[hi] = hash_ptr;
+ }
+ }
+
+ /* Everything is set up, add the aux symbol. */
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
+ aux_ptr->type = aux_tir;
+ aux_ptr->data = aux;
+
+ ret = vp->num_allocated++;
+
+ /* Add bitfield length if it exists.
+
+ NOTE: Mips documentation claims bitfield goes at the end of the
+ AUX record, but the DECstation compiler emits it here.
+ (This would only make a difference for enum bitfields.)
+
+ Also note: We use the last size given since gcc may emit 2
+ for an enum bitfield. */
+
+ if (t->bitfield)
+ (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]);
+
+
+ /* Add tag information if needed. Structure, union, and enum
+ references add 2 aux symbols: a [file index, symbol index]
+ pointer to the structure type, and the current file index. */
+
+ if (t->basic_type == bt_Struct
+ || t->basic_type == bt_Union
+ || t->basic_type == bt_Enum)
+ {
+ register symint_t file_index = t->tag_ptr->ifd;
+ register localsym_t *sym = t->tag_ptr->sym;
+ register forward_t *forward_ref = allocate_forward ();
+
+ if (sym != (localsym_t *) NULL)
+ {
+ forward_ref->next = sym->forward_ref;
+ sym->forward_ref = forward_ref;
+ }
+ else
+ {
+ forward_ref->next = t->tag_ptr->forward_ref;
+ t->tag_ptr->forward_ref = forward_ref;
+ }
+
+ (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil);
+ forward_ref->index_ptr
+ = &vp->last->datum->aux[ vp->objects_last_page - 1];
+
+ (void) add_aux_sym_symint (file_index);
+ forward_ref->ifd_ptr
+ = &vp->last->datum->aux[ vp->objects_last_page - 1];
+ }
+
+ /* Add information about array bounds if they exist. */
+ for (i = 0; i < t->num_dims; i++)
+ {
+ (void) add_aux_sym_rndx (ST_RFDESCAPE,
+ cur_file_ptr->int_type);
+
+ (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
+ (void) add_aux_sym_symint ((symint_t) 0); /* low bound */
+ (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
+ (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
+ ? 0
+ : (t->sizes[i] * 8) / t->dimensions[i]);
+ };
+
+ /* NOTE: Mips documentation claims that the bitfield width goes here.
+ But it needs to be emitted earlier. */
+
+ return ret;
+}
+
+/* Add a tag to the tag table (unless it already exists). */
+
+static tag_t *
+get_tag (tag, sym, basic_type)
+ const char *tag; /* tag name */
+ localsym_t *sym; /* tag start block */
+ bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
+{
+ shash_t *hash_ptr;
+ const char *err;
+ tag_t *tag_ptr;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ hash_ptr = (shash_t *) hash_find (tag_hash, tag);
+
+ if (hash_ptr != (shash_t *) NULL
+ && hash_ptr->tag_ptr != (tag_t *) NULL)
+ {
+ tag_ptr = hash_ptr->tag_ptr;
+ if (sym != (localsym_t *) NULL)
+ {
+ tag_ptr->basic_type = basic_type;
+ tag_ptr->ifd = cur_file_ptr->file_index;
+ tag_ptr->sym = sym;
+ }
+ return tag_ptr;
+ }
+
+ if (hash_ptr == (shash_t *) NULL)
+ {
+ char *perm;
+
+ perm = xmalloc ((unsigned long) (strlen (tag) + 1));
+ strcpy (perm, tag);
+ hash_ptr = allocate_shash ();
+ err = hash_insert (tag_hash, perm, (char *) hash_ptr);
+ if (err)
+ as_fatal (_("Inserting \"%s\" into tag hash table: %s"),
+ tag, err);
+ hash_ptr->string = perm;
+ }
+
+ tag_ptr = allocate_tag ();
+ tag_ptr->forward_ref = (forward_t *) NULL;
+ tag_ptr->hash_ptr = hash_ptr;
+ tag_ptr->same_name = hash_ptr->tag_ptr;
+ tag_ptr->basic_type = basic_type;
+ tag_ptr->sym = sym;
+ tag_ptr->ifd = ((sym == (localsym_t *) NULL)
+ ? (symint_t) -1
+ : cur_file_ptr->file_index);
+ tag_ptr->same_block = cur_tag_head->first_tag;
+
+ cur_tag_head->first_tag = tag_ptr;
+ hash_ptr->tag_ptr = tag_ptr;
+
+ return tag_ptr;
+}
+
+/* Add an unknown {struct, union, enum} tag. */
+
+static void
+add_unknown_tag (ptag)
+ tag_t *ptag; /* pointer to tag information */
+{
+ shash_t *hash_ptr = ptag->hash_ptr;
+ char *name = hash_ptr->string;
+ localsym_t *sym;
+ forward_t **pf;
+
+#ifdef ECOFF_DEBUG
+ if (debug > 1)
+ {
+ char *agg_type = "{unknown aggregate type}";
+ switch (ptag->basic_type)
+ {
+ case bt_Struct: agg_type = "struct"; break;
+ case bt_Union: agg_type = "union"; break;
+ case bt_Enum: agg_type = "enum"; break;
+ default: break;
+ }
+
+ fprintf (stderr, "unknown %s %.*s found\n", agg_type,
+ hash_ptr->len, name_start);
+ }
+#endif
+
+ sym = add_ecoff_symbol (name,
+ st_Block,
+ sc_Info,
+ (symbolS *) NULL,
+ (bfd_vma) 0,
+ (symint_t) 0,
+ (symint_t) 0);
+
+ (void) add_ecoff_symbol (name,
+ st_End,
+ sc_Info,
+ (symbolS *) NULL,
+ (bfd_vma) 0,
+ (symint_t) 0,
+ (symint_t) 0);
+
+ for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next)
+ ;
+ *pf = ptag->forward_ref;
+}
+
+/* Add a procedure to the current file's list of procedures, and record
+ this is the current procedure. */
+
+static void
+add_procedure (func)
+ char *func; /* func name */
+{
+ register varray_t *vp;
+ register proc_t *new_proc_ptr;
+ symbolS *sym;
+
+#ifdef ECOFF_DEBUG
+ if (debug)
+ fputc ('\n', stderr);
+#endif
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ as_fatal (_("no current file pointer"));
+
+ vp = &cur_file_ptr->procs;
+
+ if (vp->objects_last_page == vp->objects_per_page)
+ add_varray_page (vp);
+
+ cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++];
+
+ if (first_proc_ptr == (proc_t *) NULL)
+ first_proc_ptr = new_proc_ptr;
+
+ vp->num_allocated++;
+
+ new_proc_ptr->pdr.isym = -1;
+ new_proc_ptr->pdr.iline = -1;
+ new_proc_ptr->pdr.lnLow = -1;
+ new_proc_ptr->pdr.lnHigh = -1;
+
+ /* Set the BSF_FUNCTION flag for the symbol. */
+ sym = symbol_find_or_make (func);
+ sym->bsym->flags |= BSF_FUNCTION;
+
+ /* Push the start of the function. */
+ new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
+ sym, (bfd_vma) 0, (symint_t) 0,
+ (symint_t) 0);
+
+ ++proc_cnt;
+
+ /* Fill in the linenos preceding the .ent, if any. */
+ if (noproc_lineno != (lineno_list_t *) NULL)
+ {
+ lineno_list_t *l;
+
+ for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next)
+ l->proc = new_proc_ptr;
+ *last_lineno_ptr = noproc_lineno;
+ while (*last_lineno_ptr != NULL)
+ {
+ last_lineno = *last_lineno_ptr;
+ last_lineno_ptr = &last_lineno->next;
+ }
+ noproc_lineno = (lineno_list_t *) NULL;
+ }
+}
+
+symbolS *
+ecoff_get_cur_proc_sym ()
+{
+ return (cur_proc_ptr ? cur_proc_ptr->sym->as_sym : NULL);
+}
+
+/* Add a new filename, and set up all of the file relative
+ virtual arrays (strings, symbols, aux syms, etc.). Record
+ where the current file structure lives. */
+
+static void
+add_file (file_name, indx, fake)
+ const char *file_name; /* file name */
+ int indx;
+ int fake;
+{
+ register int first_ch;
+ register efdr_t *fil_ptr;
+
+#ifdef ECOFF_DEBUG
+ if (debug)
+ fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
+#endif
+
+ /* If the file name is NULL, then no .file symbol appeared, and we
+ want to use the actual file name. */
+ if (file_name == (const char *) NULL)
+ {
+ char *file;
+
+ if (first_file != (efdr_t *) NULL)
+ as_fatal (_("fake .file after real one"));
+ as_where (&file, (unsigned int *) NULL);
+ file_name = (const char *) file;
+
+ /* Automatically generate ECOFF debugging information, since I
+ think that's what other ECOFF assemblers do. We don't do
+ this if we see a .file directive with a string, since that
+ implies that some sort of debugging information is being
+ provided. */
+ if (! symbol_table_frozen && debug_type == DEBUG_NONE)
+ debug_type = DEBUG_ECOFF;
+ }
+
+#ifndef NO_LISTING
+ if (listing)
+ listing_source_file (file_name);
+#endif
+
+ current_stabs_filename = file_name;
+
+ /* If we're creating stabs, then we don't actually make a new FDR.
+ Instead, we just create a stabs symbol. */
+ if (stabs_seen)
+ {
+ (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (),
+ frag_now),
+ (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SOL));
+ return;
+ }
+
+ first_ch = *file_name;
+
+ /* FIXME: We can't safely merge files which have line number
+ information (fMerge will be zero in this case). Otherwise, we
+ get incorrect line number debugging info. See for instance
+ ecoff_build_lineno, which will end up setting all file->fdr.*
+ fields multiple times, resulting in incorrect debug info. In
+ order to make this work right, all line number and symbol info
+ for the same source file has to be adjacent in the object file,
+ so that a single file descriptor can be used to point to them.
+ This would require maintaining file specific lists of line
+ numbers and symbols for each file, so that they can be merged
+ together (or output together) when two .file pseudo-ops are
+ merged into one file descriptor. */
+
+ /* See if the file has already been created. */
+ for (fil_ptr = first_file;
+ fil_ptr != (efdr_t *) NULL;
+ fil_ptr = fil_ptr->next_file)
+ {
+ if (first_ch == fil_ptr->name[0]
+ && strcmp (file_name, fil_ptr->name) == 0
+ && fil_ptr->fdr.fMerge)
+ {
+ cur_file_ptr = fil_ptr;
+ if (! fake)
+ cur_file_ptr->fake = 0;
+ break;
+ }
+ }
+
+ /* If this is a new file, create it. */
+ if (fil_ptr == (efdr_t *) NULL)
+ {
+ if (file_desc.objects_last_page == file_desc.objects_per_page)
+ add_varray_page (&file_desc);
+
+ fil_ptr = cur_file_ptr =
+ &file_desc.last->datum->file[file_desc.objects_last_page++];
+ *fil_ptr = init_file;
+
+ fil_ptr->file_index = current_file_idx++;
+ ++file_desc.num_allocated;
+
+ fil_ptr->fake = fake;
+
+ /* Allocate the string hash table. */
+ fil_ptr->str_hash = hash_new ();
+
+ /* Make sure 0 byte in string table is null */
+ add_string (&fil_ptr->strings,
+ fil_ptr->str_hash,
+ "",
+ (shash_t **)0);
+
+ if (strlen (file_name) > PAGE_USIZE - 2)
+ as_fatal (_("Filename goes over one page boundary."));
+
+ /* Push the start of the filename. We assume that the filename
+ will be stored at string offset 1. */
+ (void) add_ecoff_symbol (file_name, st_File, sc_Text,
+ (symbolS *) NULL, (bfd_vma) 0,
+ (symint_t) 0, (symint_t) 0);
+ fil_ptr->fdr.rss = 1;
+ fil_ptr->name = &fil_ptr->strings.last->datum->byte[1];
+
+ /* Update the linked list of file descriptors. */
+ *last_file_ptr = fil_ptr;
+ last_file_ptr = &fil_ptr->next_file;
+
+ /* Add void & int types to the file (void should be first to catch
+ errant 0's within the index fields). */
+ fil_ptr->void_type = add_aux_sym_tir (&void_type_info,
+ hash_yes,
+ &cur_file_ptr->thash_head[0]);
+
+ fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
+ hash_yes,
+ &cur_file_ptr->thash_head[0]);
+ }
+}
+
+/* This function is called when the assembler notices a preprocessor
+ directive switching to a new file. This will not happen in
+ compiler output, only in hand coded assembler. */
+
+void
+ecoff_new_file (name)
+ const char *name;
+{
+ if (cur_file_ptr != NULL && strcmp (cur_file_ptr->name, name) == 0)
+ return;
+ add_file (name, 0, 0);
+
+ /* This is a hand coded assembler file, so automatically turn on
+ debugging information. */
+ if (debug_type == DEBUG_NONE)
+ debug_type = DEBUG_ECOFF;
+}
+
+#ifdef ECOFF_DEBUG
+
+/* Convert storage class to string. */
+
+static char *
+sc_to_string(storage_class)
+ sc_t storage_class;
+{
+ switch(storage_class)
+ {
+ case sc_Nil: return "Nil,";
+ case sc_Text: return "Text,";
+ case sc_Data: return "Data,";
+ case sc_Bss: return "Bss,";
+ case sc_Register: return "Register,";
+ case sc_Abs: return "Abs,";
+ case sc_Undefined: return "Undefined,";
+ case sc_CdbLocal: return "CdbLocal,";
+ case sc_Bits: return "Bits,";
+ case sc_CdbSystem: return "CdbSystem,";
+ case sc_RegImage: return "RegImage,";
+ case sc_Info: return "Info,";
+ case sc_UserStruct: return "UserStruct,";
+ case sc_SData: return "SData,";
+ case sc_SBss: return "SBss,";
+ case sc_RData: return "RData,";
+ case sc_Var: return "Var,";
+ case sc_Common: return "Common,";
+ case sc_SCommon: return "SCommon,";
+ case sc_VarRegister: return "VarRegister,";
+ case sc_Variant: return "Variant,";
+ case sc_SUndefined: return "SUndefined,";
+ case sc_Init: return "Init,";
+ case sc_Max: return "Max,";
+ }
+
+ return "???,";
+}
+
+#endif /* DEBUG */
+
+#ifdef ECOFF_DEBUG
+
+/* Convert symbol type to string. */
+
+static char *
+st_to_string(symbol_type)
+ st_t symbol_type;
+{
+ switch(symbol_type)
+ {
+ case st_Nil: return "Nil,";
+ case st_Global: return "Global,";
+ case st_Static: return "Static,";
+ case st_Param: return "Param,";
+ case st_Local: return "Local,";
+ case st_Label: return "Label,";
+ case st_Proc: return "Proc,";
+ case st_Block: return "Block,";
+ case st_End: return "End,";
+ case st_Member: return "Member,";
+ case st_Typedef: return "Typedef,";
+ case st_File: return "File,";
+ case st_RegReloc: return "RegReloc,";
+ case st_Forward: return "Forward,";
+ case st_StaticProc: return "StaticProc,";
+ case st_Constant: return "Constant,";
+ case st_Str: return "String,";
+ case st_Number: return "Number,";
+ case st_Expr: return "Expr,";
+ case st_Type: return "Type,";
+ case st_Max: return "Max,";
+ }
+
+ return "???,";
+}
+
+#endif /* DEBUG */
+
+/* Parse .begin directives which have a label as the first argument
+ which gives the location of the start of the block. */
+
+void
+ecoff_directive_begin (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".begin directive without a preceding .file directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".begin directive without a preceding .ent directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text,
+ symbol_find_or_make (name),
+ (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
+
+ *input_line_pointer = name_end;
+
+ /* The line number follows, but we don't use it. */
+ (void) get_absolute_expression ();
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .bend directives which have a label as the first argument
+ which gives the location of the end of the block. */
+
+void
+ecoff_directive_bend (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+ symbolS *endsym;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".bend directive without a preceding .file directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".bend directive without a preceding .ent directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ /* The value is the distance between the .bend directive and the
+ corresponding symbol. We fill in the offset when we write out
+ the symbol. */
+ endsym = symbol_find (name);
+ if (endsym == (symbolS *) NULL)
+ as_warn (_(".bend directive names unknown symbol"));
+ else
+ (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
+ (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
+
+ *input_line_pointer = name_end;
+
+ /* The line number follows, but we don't use it. */
+ (void) get_absolute_expression ();
+ demand_empty_rest_of_line ();
+}
+
+/* COFF debugging information is provided as a series of directives
+ (.def, .scl, etc.). We build up information as we read the
+ directives in the following static variables, and file it away when
+ we reach the .endef directive. */
+static char *coff_sym_name;
+static type_info_t coff_type;
+static sc_t coff_storage_class;
+static st_t coff_symbol_typ;
+static int coff_is_function;
+static char *coff_tag;
+static valueT coff_value;
+static symbolS *coff_sym_value;
+static bfd_vma coff_sym_addend;
+static int coff_inside_enumeration;
+
+/* Handle a .def directive: start defining a symbol. */
+
+void
+ecoff_directive_def (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+
+ ecoff_debugging_seen = 1;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ if (coff_sym_name != (char *) NULL)
+ as_warn (_(".def pseudo-op used inside of .def/.endef; ignored"));
+ else if (*name == '\0')
+ as_warn (_("Empty symbol name in .def; ignored"));
+ else
+ {
+ if (coff_sym_name != (char *) NULL)
+ free (coff_sym_name);
+ if (coff_tag != (char *) NULL)
+ free (coff_tag);
+ coff_sym_name = (char *) xmalloc ((unsigned long) (strlen (name) + 1));
+ strcpy (coff_sym_name, name);
+ coff_type = type_info_init;
+ coff_storage_class = sc_Nil;
+ coff_symbol_typ = st_Nil;
+ coff_is_function = 0;
+ coff_tag = (char *) NULL;
+ coff_value = 0;
+ coff_sym_value = (symbolS *) NULL;
+ coff_sym_addend = 0;
+ }
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .dim directive, used to give dimensions for an array. The
+ arguments are comma separated numbers. mips-tfile assumes that
+ there will not be more than 6 dimensions, and gdb won't read any
+ more than that anyhow, so I will also make that assumption. */
+
+void
+ecoff_directive_dim (ignore)
+ int ignore;
+{
+ int dimens[N_TQ];
+ int i;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".dim pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ for (i = 0; i < N_TQ; i++)
+ {
+ SKIP_WHITESPACE ();
+ dimens[i] = get_absolute_expression ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ else
+ {
+ if (*input_line_pointer != '\n'
+ && *input_line_pointer != ';')
+ as_warn (_("Badly formed .dim directive"));
+ break;
+ }
+ }
+
+ if (i == N_TQ)
+ --i;
+
+ /* The dimensions are stored away in reverse order. */
+ for (; i >= 0; i--)
+ {
+ if (coff_type.num_dims >= N_TQ)
+ {
+ as_warn (_("Too many .dim entries"));
+ break;
+ }
+ coff_type.dimensions[coff_type.num_dims] = dimens[i];
+ ++coff_type.num_dims;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .scl directive, which sets the COFF storage class of the
+ symbol. */
+
+void
+ecoff_directive_scl (ignore)
+ int ignore;
+{
+ long val;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".scl pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ val = get_absolute_expression ();
+
+ coff_symbol_typ = map_coff_sym_type[val];
+ coff_storage_class = map_coff_storage[val];
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle a .size directive. For some reason mips-tfile.c thinks that
+ .size can have multiple arguments. We humor it, although gcc will
+ never generate more than one argument. */
+
+void
+ecoff_directive_size (ignore)
+ int ignore;
+{
+ int sizes[N_TQ];
+ int i;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".size pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ for (i = 0; i < N_TQ; i++)
+ {
+ SKIP_WHITESPACE ();
+ sizes[i] = get_absolute_expression ();
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ else
+ {
+ if (*input_line_pointer != '\n'
+ && *input_line_pointer != ';')
+ as_warn (_("Badly formed .size directive"));
+ break;
+ }
+ }
+
+ if (i == N_TQ)
+ --i;
+
+ /* The sizes are stored away in reverse order. */
+ for (; i >= 0; i--)
+ {
+ if (coff_type.num_sizes >= N_TQ)
+ {
+ as_warn (_("Too many .size entries"));
+ break;
+ }
+ coff_type.sizes[coff_type.num_sizes] = sizes[i];
+ ++coff_type.num_sizes;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .type directive, which gives the COFF type of the
+ symbol. */
+
+void
+ecoff_directive_type (ignore)
+ int ignore;
+{
+ long val;
+ tq_t *tq_ptr;
+ tq_t *tq_shft;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".type pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ val = get_absolute_expression ();
+
+ coff_type.orig_type = BTYPE (val);
+ coff_type.basic_type = map_coff_types[coff_type.orig_type];
+
+ tq_ptr = &coff_type.type_qualifiers[N_TQ];
+ while (val &~ N_BTMASK)
+ {
+ if (tq_ptr == &coff_type.type_qualifiers[0])
+ {
+ /* FIXME: We could handle this by setting the continued bit.
+ There would still be a limit: the .type argument can not
+ be infinite. */
+ as_warn (_("The type of %s is too complex; it will be simplified"),
+ coff_sym_name);
+ break;
+ }
+ if (ISPTR (val))
+ *--tq_ptr = tq_Ptr;
+ else if (ISFCN (val))
+ *--tq_ptr = tq_Proc;
+ else if (ISARY (val))
+ *--tq_ptr = tq_Array;
+ else
+ as_fatal (_("Unrecognized .type argument"));
+
+ val = DECREF (val);
+ }
+
+ tq_shft = &coff_type.type_qualifiers[0];
+ while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
+ *tq_shft++ = *tq_ptr++;
+
+ if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
+ {
+ /* If this is a function, ignore it, so that we don't get two
+ entries (one from the .ent, and one for the .def that
+ precedes it). Save the type information so that the end
+ block can properly add it after the begin block index. For
+ MIPS knows what reason, we must strip off the function type
+ at this point. */
+ coff_is_function = 1;
+ tq_shft[-1] = tq_Nil;
+ }
+
+ while (tq_shft != &coff_type.type_qualifiers[N_TQ])
+ *tq_shft++ = tq_Nil;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .tag directive, which gives the name of a structure,
+ union or enum. */
+
+void
+ecoff_directive_tag (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".tag pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ coff_tag = (char *) xmalloc ((unsigned long) (strlen (name) + 1));
+ strcpy (coff_tag, name);
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .val directive, which gives the value of the symbol. It
+ may be the name of a static or global symbol. */
+
+void
+ecoff_directive_val (ignore)
+ int ignore;
+{
+ expressionS exp;
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".val pseudo-op used outside of .def/.endef; ignored"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ expression (&exp);
+ if (exp.X_op != O_constant && exp.X_op != O_symbol)
+ {
+ as_bad (_(".val expression is too copmlex"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (exp.X_op == O_constant)
+ coff_value = exp.X_add_number;
+ else
+ {
+ coff_sym_value = exp.X_add_symbol;
+ coff_sym_addend = exp.X_add_number;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .endef directive, which terminates processing of COFF
+ debugging information for a symbol. */
+
+void
+ecoff_directive_endef (ignore)
+ int ignore;
+{
+ char *name;
+ symint_t indx;
+ localsym_t *sym;
+
+ demand_empty_rest_of_line ();
+
+ if (coff_sym_name == (char *) NULL)
+ {
+ as_warn (_(".endef pseudo-op used before .def; ignored"));
+ return;
+ }
+
+ name = coff_sym_name;
+ coff_sym_name = (char *) NULL;
+
+ /* If the symbol is a static or external, we have already gotten the
+ appropriate type and class, so make sure we don't override those
+ values. This is needed because there are some type and classes
+ that are not in COFF, such as short data, etc. */
+ if (coff_sym_value != (symbolS *) NULL)
+ {
+ coff_symbol_typ = st_Nil;
+ coff_storage_class = sc_Nil;
+ }
+
+ coff_type.extra_sizes = coff_tag != (char *) NULL;
+ if (coff_type.num_dims > 0)
+ {
+ int diff = coff_type.num_dims - coff_type.num_sizes;
+ int i = coff_type.num_dims - 1;
+ int j;
+
+ if (coff_type.num_sizes != 1 || diff < 0)
+ {
+ as_warn (_("Bad COFF debugging info"));
+ return;
+ }
+
+ /* If this is an array, make sure the same number of dimensions
+ and sizes were passed, creating extra sizes for multiply
+ dimensioned arrays if not passed. */
+ coff_type.extra_sizes = 0;
+ if (diff)
+ {
+ j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1;
+ while (j >= 0)
+ {
+ coff_type.sizes[j] = (((j - diff) >= 0)
+ ? coff_type.sizes[j - diff]
+ : 0);
+ j--;
+ }
+
+ coff_type.num_sizes = i + 1;
+ for (i--; i >= 0; i--)
+ coff_type.sizes[i] = (coff_type.dimensions[i + 1] == 0
+ ? 0
+ : (coff_type.sizes[i + 1]
+ / coff_type.dimensions[i + 1]));
+ }
+ }
+ else if (coff_symbol_typ == st_Member
+ && coff_type.num_sizes - coff_type.extra_sizes == 1)
+ {
+ /* Is this a bitfield? This is indicated by a structure memeber
+ having a size field that isn't an array. */
+ coff_type.bitfield = 1;
+ }
+
+ /* Except for enumeration members & begin/ending of scopes, put the
+ type word in the aux. symbol table. */
+ if (coff_symbol_typ == st_Block || coff_symbol_typ == st_End)
+ indx = 0;
+ else if (coff_inside_enumeration)
+ indx = cur_file_ptr->void_type;
+ else
+ {
+ if (coff_type.basic_type == bt_Struct
+ || coff_type.basic_type == bt_Union
+ || coff_type.basic_type == bt_Enum)
+ {
+ if (coff_tag == (char *) NULL)
+ {
+ as_warn (_("No tag specified for %s"), name);
+ return;
+ }
+
+ coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL,
+ coff_type.basic_type);
+ }
+
+ if (coff_is_function)
+ {
+ last_func_type_info = coff_type;
+ last_func_sym_value = coff_sym_value;
+ return;
+ }
+
+ indx = add_aux_sym_tir (&coff_type,
+ hash_yes,
+ &cur_file_ptr->thash_head[0]);
+ }
+
+ /* Do any last minute adjustments that are necessary. */
+ switch (coff_symbol_typ)
+ {
+ default:
+ break;
+
+ /* For the beginning of structs, unions, and enumerations, the
+ size info needs to be passed in the value field. */
+ case st_Block:
+ if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes
+ != 1)
+ {
+ as_warn (_("Bad COFF debugging information"));
+ return;
+ }
+ else
+ coff_value = coff_type.sizes[0];
+
+ coff_inside_enumeration = (coff_type.orig_type == T_ENUM);
+ break;
+
+ /* For the end of structs, unions, and enumerations, omit the
+ name which is always ".eos". This needs to be done last, so
+ that any error reporting above gives the correct name. */
+ case st_End:
+ free (name);
+ name = (char *) NULL;
+ coff_value = 0;
+ coff_inside_enumeration = 0;
+ break;
+
+ /* Members of structures and unions that aren't bitfields, need
+ to adjust the value from a byte offset to a bit offset.
+ Members of enumerations do not have the value adjusted, and
+ can be distinguished by indx == indexNil. For enumerations,
+ update the maximum enumeration value. */
+ case st_Member:
+ if (! coff_type.bitfield && ! coff_inside_enumeration)
+ coff_value *= 8;
+
+ break;
+ }
+
+ /* Add the symbol. */
+ sym = add_ecoff_symbol (name,
+ coff_symbol_typ,
+ coff_storage_class,
+ coff_sym_value,
+ coff_sym_addend,
+ (symint_t) coff_value,
+ indx);
+
+ /* deal with struct, union, and enum tags. */
+ if (coff_symbol_typ == st_Block)
+ {
+ /* Create or update the tag information. */
+ tag_t *tag_ptr = get_tag (name,
+ sym,
+ coff_type.basic_type);
+ forward_t **pf;
+
+ /* Remember any forward references. */
+ for (pf = &sym->forward_ref;
+ *pf != (forward_t *) NULL;
+ pf = &(*pf)->next)
+ ;
+ *pf = tag_ptr->forward_ref;
+ tag_ptr->forward_ref = (forward_t *) NULL;
+ }
+}
+
+/* Parse .end directives. */
+
+void
+ecoff_directive_end (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+ register int ch;
+ symbolS *ent;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".end directive without a preceding .file directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".end directive without a preceding .ent directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ ch = *name;
+ if (! is_name_beginner (ch))
+ {
+ as_warn (_(".end directive has no name"));
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* The value is the distance between the .end directive and the
+ corresponding symbol. We create a fake symbol to hold the
+ current location, and put in the offset when we write out the
+ symbol. */
+ ent = symbol_find (name);
+ if (ent == (symbolS *) NULL)
+ as_warn (_(".end directive names unknown symbol"));
+ else
+ (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (),
+ frag_now),
+ (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
+
+ cur_proc_ptr = (proc_t *) NULL;
+
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .ent directives. */
+
+void
+ecoff_directive_ent (ignore)
+ int ignore;
+{
+ char *name;
+ char name_end;
+ register int ch;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ add_file ((const char *) NULL, 0, 1);
+
+ if (cur_proc_ptr != (proc_t *) NULL)
+ {
+ as_warn (_("second .ent directive found before .end directive"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ ch = *name;
+ if (! is_name_beginner (ch))
+ {
+ as_warn (_(".ent directive has no name"));
+ *input_line_pointer = name_end;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ add_procedure (name);
+
+ *input_line_pointer = name_end;
+
+ /* The .ent directive is sometimes followed by a number. I'm not
+ really sure what the number means. I don't see any way to store
+ the information in the PDR. The Irix 4 assembler seems to ignore
+ the information. */
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+ if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
+ (void) get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .extern directives. */
+
+void
+ecoff_directive_extern (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolp;
+ valueT size;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolp = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ S_SET_EXTERNAL (symbolp);
+
+ if (*input_line_pointer == ',')
+ ++input_line_pointer;
+ size = get_absolute_expression ();
+
+ symbolp->ecoff_extern_size = size;
+}
+
+/* Parse .file directives. */
+
+void
+ecoff_directive_file (ignore)
+ int ignore;
+{
+ int indx;
+ char *name;
+ int len;
+
+ if (cur_proc_ptr != (proc_t *) NULL)
+ {
+ as_warn (_("No way to handle .file within .ent/.end section"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ indx = (int) get_absolute_expression ();
+
+ /* FIXME: we don't have to save the name here. */
+ name = demand_copy_C_string (&len);
+
+ add_file (name, indx - 1, 0);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .fmask directives. */
+
+void
+ecoff_directive_fmask (ignore)
+ int ignore;
+{
+ long val;
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".fmask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .fmask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.fregmask = val;
+ cur_proc_ptr->pdr.fregoffset = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .frame directives. */
+
+void
+ecoff_directive_frame (ignore)
+ int ignore;
+{
+ long val;
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".frame outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.framereg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .frame directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.frameoffset = val;
+
+ cur_proc_ptr->pdr.pcreg = tc_get_register (0);
+
+#if 0 /* Alpha-OSF1 adds "the offset of saved $a0 from $sp", according
+ to Sandro. I don't yet know where this value should be stored, if
+ anywhere. */
+ demand_empty_rest_of_line ();
+#else
+ s_ignore (42);
+#endif
+}
+
+/* Parse .mask directives. */
+
+void
+ecoff_directive_mask (ignore)
+ int ignore;
+{
+ long val;
+
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ as_warn (_(".mask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .mask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->pdr.regmask = val;
+ cur_proc_ptr->pdr.regoffset = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+/* Parse .loc directives. */
+
+void
+ecoff_directive_loc (ignore)
+ int ignore;
+{
+ lineno_list_t *list;
+ symint_t lineno;
+
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ as_warn (_(".loc before .file"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (now_seg != text_section)
+ {
+ as_warn (_(".loc outside of .text"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ /* Skip the file number. */
+ SKIP_WHITESPACE ();
+ get_absolute_expression ();
+ SKIP_WHITESPACE ();
+
+ lineno = get_absolute_expression ();
+
+#ifndef NO_LISTING
+ if (listing)
+ listing_source_line (lineno);
+#endif
+
+ /* If we're building stabs, then output a special label rather than
+ ECOFF line number info. */
+ if (stabs_seen)
+ {
+ (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text,
+ symbol_new ("L0\001", now_seg,
+ (valueT) frag_now_fix (),
+ frag_now),
+ (bfd_vma) 0, 0, lineno);
+ return;
+ }
+
+ list = allocate_lineno_list ();
+
+ list->next = (lineno_list_t *) NULL;
+ list->file = cur_file_ptr;
+ list->proc = cur_proc_ptr;
+ list->frag = frag_now;
+ list->paddr = frag_now_fix ();
+ list->lineno = lineno;
+
+ /* We don't want to merge files which have line numbers. */
+ cur_file_ptr->fdr.fMerge = 0;
+
+ /* A .loc directive will sometimes appear before a .ent directive,
+ which means that cur_proc_ptr will be NULL here. Arrange to
+ patch this up. */
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ lineno_list_t **pl;
+
+ pl = &noproc_lineno;
+ while (*pl != (lineno_list_t *) NULL)
+ pl = &(*pl)->next;
+ *pl = list;
+ }
+ else
+ {
+ last_lineno = list;
+ *last_lineno_ptr = list;
+ last_lineno_ptr = &list->next;
+ }
+}
+
+/* The MIPS assembler sometimes inserts nop instructions in the
+ instruction stream. When this happens, we must patch up the .loc
+ information so that it points to the instruction after the nop. */
+
+void
+ecoff_fix_loc (old_frag, old_frag_offset)
+ fragS *old_frag;
+ unsigned long old_frag_offset;
+{
+ if (last_lineno != NULL
+ && last_lineno->frag == old_frag
+ && last_lineno->paddr == old_frag_offset)
+ {
+ last_lineno->frag = frag_now;
+ last_lineno->paddr = frag_now_fix ();
+ }
+}
+
+/* Make sure the @stabs symbol is emitted. */
+
+static void
+mark_stabs (ignore)
+ int ignore;
+{
+ if (! stabs_seen)
+ {
+ /* Add a dummy @stabs dymbol. */
+ stabs_seen = 1;
+ (void) add_ecoff_symbol (stabs_symbol, stNil, scInfo,
+ (symbolS *) NULL,
+ (bfd_vma) 0, (symint_t) -1,
+ ECOFF_MARK_STAB (0));
+ }
+}
+
+/* Parse .weakext directives. */
+#ifndef TC_MIPS
+/* For TC_MIPS use the version in tc-mips.c. */
+void
+ecoff_directive_weakext (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ expressionS exp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == ',')
+ {
+ if (S_IS_DEFINED (symbolP))
+ {
+ as_bad (_("Ignoring attempt to redefine symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ expression (&exp);
+ if (exp.X_op != O_symbol)
+ {
+ as_bad (_("bad .weakext directive"));
+ ignore_rest_of_line();
+ return;
+ }
+ symbolP->sy_value = exp;
+ }
+ }
+
+ S_SET_WEAK (symbolP);
+
+ demand_empty_rest_of_line ();
+}
+#endif /* not TC_MIPS */
+
+/* Handle .stabs directives. The actual parsing routine is done by a
+ generic routine. This routine is called via OBJ_PROCESS_STAB.
+ When this is called, input_line_pointer will be pointing at the
+ value field of the stab.
+
+ .stabs directives have five fields:
+ "string" a string, encoding the type information.
+ code a numeric code, defined in <stab.h>
+ 0 a zero
+ desc a zero or line number
+ value a numeric value or an address.
+
+ If the value is relocatable, we transform this into:
+ iss points as an index into string space
+ value value from lookup of the name
+ st st from lookup of the name
+ sc sc from lookup of the name
+ index code|CODE_MASK
+
+ If the value is not relocatable, we transform this into:
+ iss points as an index into string space
+ value value
+ st st_Nil
+ sc sc_Nil
+ index code|CODE_MASK
+
+ .stabn directives have four fields (string is null):
+ code a numeric code, defined in <stab.h>
+ 0 a zero
+ desc a zero or a line number
+ value a numeric value or an address. */
+
+void
+ecoff_stab (sec, what, string, type, other, desc)
+ segT sec;
+ int what;
+ const char *string;
+ int type;
+ int other;
+ int desc;
+{
+ efdr_t *save_file_ptr = cur_file_ptr;
+ symbolS *sym;
+ symint_t value;
+ bfd_vma addend;
+ st_t st;
+ sc_t sc;
+ symint_t indx;
+ localsym_t *hold = NULL;
+
+ ecoff_debugging_seen = 1;
+
+ /* We don't handle .stabd. */
+ if (what != 's' && what != 'n')
+ {
+ as_bad (_(".stab%c is not supported"), what);
+ return;
+ }
+
+ /* A .stabn uses a null name, not an empty string. */
+ if (what == 'n')
+ string = NULL;
+
+ /* We ignore the other field. */
+ if (other != 0)
+ as_warn (_(".stab%c: ignoring non-zero other field"), what);
+
+ /* Make sure we have a current file. */
+ if (cur_file_ptr == (efdr_t *) NULL)
+ {
+ add_file ((const char *) NULL, 0, 1);
+ save_file_ptr = cur_file_ptr;
+ }
+
+ /* For stabs in ECOFF, the first symbol must be @stabs. This is a
+ signal to gdb. */
+ if (stabs_seen == 0)
+ mark_stabs (0);
+
+ /* Line number stabs are handled differently, since they have two
+ values, the line number and the address of the label. We use the
+ index field (aka desc) to hold the line number, and the value
+ field to hold the address. The symbol type is st_Label, which
+ should be different from the other stabs, so that gdb can
+ recognize it. */
+ if (type == N_SLINE)
+ {
+ SYMR dummy_symr;
+ char *name;
+ char name_end;
+
+#ifndef NO_LISTING
+ if (listing)
+ listing_source_line ((unsigned int) desc);
+#endif
+
+ dummy_symr.index = desc;
+ if (dummy_symr.index != desc)
+ {
+ as_warn (_("Line number (%d) for .stab%c directive cannot fit in index field (20 bits)"),
+ desc, what);
+ return;
+ }
+
+ name = input_line_pointer;
+ name_end = get_symbol_end ();
+
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = name_end;
+
+ value = 0;
+ addend = 0;
+ st = st_Label;
+ sc = sc_Text;
+ indx = desc;
+ }
+ else
+ {
+#ifndef NO_LISTING
+ if (listing && (type == N_SO || type == N_SOL))
+ listing_source_file (string);
+#endif
+
+ if (isdigit (*input_line_pointer)
+ || *input_line_pointer == '-'
+ || *input_line_pointer == '+')
+ {
+ st = st_Nil;
+ sc = sc_Nil;
+ sym = (symbolS *) NULL;
+ value = get_absolute_expression ();
+ addend = 0;
+ }
+ else if (! is_name_beginner ((unsigned char) *input_line_pointer))
+ {
+ as_warn (_("Illegal .stab%c directive, bad character"), what);
+ return;
+ }
+ else
+ {
+ expressionS exp;
+
+ sc = sc_Nil;
+ st = st_Nil;
+
+ expression (&exp);
+ if (exp.X_op == O_constant)
+ {
+ sym = NULL;
+ value = exp.X_add_number;
+ addend = 0;
+ }
+ else if (exp.X_op == O_symbol)
+ {
+ sym = exp.X_add_symbol;
+ value = 0;
+ addend = exp.X_add_number;
+ }
+ else
+ {
+ sym = make_expr_symbol (&exp);
+ value = 0;
+ addend = 0;
+ }
+ }
+
+ indx = ECOFF_MARK_STAB (type);
+ }
+
+ /* Don't store the stabs symbol we are creating as the type of the
+ ECOFF symbol. We want to compute the type of the ECOFF symbol
+ independently. */
+ if (sym != (symbolS *) NULL)
+ hold = sym->ecoff_symbol;
+
+ (void) add_ecoff_symbol (string, st, sc, sym, addend, value, indx);
+
+ if (sym != (symbolS *) NULL)
+ sym->ecoff_symbol = hold;
+
+ /* Restore normal file type. */
+ cur_file_ptr = save_file_ptr;
+}
+
+/* Frob an ECOFF symbol. Small common symbols go into a special
+ .scommon section rather than bfd_com_section. */
+
+void
+ecoff_frob_symbol (sym)
+ symbolS *sym;
+{
+ if (S_IS_COMMON (sym)
+ && S_GET_VALUE (sym) > 0
+ && S_GET_VALUE (sym) <= bfd_get_gp_size (stdoutput))
+ {
+ static asection scom_section;
+ static asymbol scom_symbol;
+
+ /* We must construct a fake section similar to bfd_com_section
+ but with the name .scommon. */
+ if (scom_section.name == NULL)
+ {
+ scom_section = bfd_com_section;
+ scom_section.name = ".scommon";
+ scom_section.output_section = &scom_section;
+ scom_section.symbol = &scom_symbol;
+ scom_section.symbol_ptr_ptr = &scom_section.symbol;
+ scom_symbol = *bfd_com_section.symbol;
+ scom_symbol.name = ".scommon";
+ scom_symbol.section = &scom_section;
+ }
+ S_SET_SEGMENT (sym, &scom_section);
+ }
+
+ /* Double check weak symbols. */
+ if (sym->bsym->flags & BSF_WEAK)
+ {
+ if (S_IS_COMMON (sym))
+ as_bad (_("Symbol `%s' can not be both weak and common"),
+ S_GET_NAME (sym));
+ }
+}
+
+/* Add bytes to the symbolic information buffer. */
+
+static char *
+ecoff_add_bytes (buf, bufend, bufptr, need)
+ char **buf;
+ char **bufend;
+ char *bufptr;
+ unsigned long need;
+{
+ unsigned long at;
+ unsigned long want;
+
+ at = bufptr - *buf;
+ need -= *bufend - bufptr;
+ if (need < PAGE_SIZE)
+ need = PAGE_SIZE;
+ want = (*bufend - *buf) + need;
+ *buf = xrealloc (*buf, want);
+ *bufend = *buf + want;
+ return *buf + at;
+}
+
+/* Adjust the symbolic information buffer to the alignment required
+ for the ECOFF target debugging information. */
+
+static unsigned long
+ecoff_padding_adjust (backend, buf, bufend, offset, bufptrptr)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+ char **bufptrptr;
+{
+ bfd_size_type align;
+
+ align = backend->debug_align;
+ if ((offset & (align - 1)) != 0)
+ {
+ unsigned long add;
+
+ add = align - (offset & (align - 1));
+ if (*bufend - (*buf + offset) < add)
+ (void) ecoff_add_bytes (buf, bufend, *buf + offset, add);
+ memset (*buf + offset, 0, add);
+ offset += add;
+ if (bufptrptr != (char **) NULL)
+ *bufptrptr = *buf + offset;
+ }
+
+ return offset;
+}
+
+/* Build the line number information. */
+
+static unsigned long
+ecoff_build_lineno (backend, buf, bufend, offset, linecntptr)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+ long *linecntptr;
+{
+ char *bufptr;
+ register lineno_list_t *l;
+ lineno_list_t *last;
+ efdr_t *file;
+ proc_t *proc;
+ unsigned long c;
+ long iline;
+ long totcount;
+ lineno_list_t first;
+ lineno_list_t *local_first_lineno = first_lineno;
+
+ if (linecntptr != (long *) NULL)
+ *linecntptr = 0;
+
+ bufptr = *buf + offset;
+
+ file = (efdr_t *) NULL;
+ proc = (proc_t *) NULL;
+ last = (lineno_list_t *) NULL;
+ c = offset;
+ iline = 0;
+ totcount = 0;
+
+ /* For some reason the address of the first procedure is ignored
+ when reading line numbers. This doesn't matter if the address of
+ the first procedure is 0, but when gcc is generating MIPS
+ embedded PIC code, it will put strings in the .text section
+ before the first procedure. We cope by inserting a dummy line if
+ the address of the first procedure is not 0. Hopefully this
+ won't screw things up too badly.
+
+ Don't do this for ECOFF assembly source line numbers. They work
+ without this extra attention. */
+ if (debug_type != DEBUG_ECOFF
+ && first_proc_ptr != (proc_t *) NULL
+ && local_first_lineno != (lineno_list_t *) NULL
+ && ((S_GET_VALUE (first_proc_ptr->sym->as_sym)
+ + bfd_get_section_vma (stdoutput,
+ S_GET_SEGMENT (first_proc_ptr->sym->as_sym)))
+ != 0))
+ {
+ first.file = local_first_lineno->file;
+ first.proc = local_first_lineno->proc;
+ first.frag = &zero_address_frag;
+ first.paddr = 0;
+ first.lineno = 0;
+
+ first.next = local_first_lineno;
+ local_first_lineno = &first;
+ }
+
+ for (l = local_first_lineno; l != (lineno_list_t *) NULL; l = l->next)
+ {
+ long count;
+ long delta;
+
+ /* Get the offset to the memory address of the next line number
+ (in words). Do this first, so that we can skip ahead to the
+ next useful line number entry. */
+ if (l->next == (lineno_list_t *) NULL)
+ {
+ /* We want a count of zero, but it will be decremented
+ before it is used. */
+ count = 1;
+ }
+ else if (l->next->frag->fr_address + l->next->paddr
+ > l->frag->fr_address + l->paddr)
+ {
+ count = ((l->next->frag->fr_address + l->next->paddr
+ - (l->frag->fr_address + l->paddr))
+ >> 2);
+ }
+ else
+ {
+ /* Don't change last, so we still get the right delta. */
+ continue;
+ }
+
+ if (l->file != file || l->proc != proc)
+ {
+ if (l->proc != proc && proc != (proc_t *) NULL)
+ proc->pdr.lnHigh = last->lineno;
+ if (l->file != file && file != (efdr_t *) NULL)
+ {
+ file->fdr.cbLine = c - file->fdr.cbLineOffset;
+ file->fdr.cline = totcount + count;
+ if (linecntptr != (long *) NULL)
+ *linecntptr += totcount + count;
+ totcount = 0;
+ }
+
+ if (l->file != file)
+ {
+ efdr_t *last_file = file;
+
+ file = l->file;
+ if (last_file != (efdr_t *) NULL)
+ file->fdr.ilineBase
+ = last_file->fdr.ilineBase + last_file->fdr.cline;
+ else
+ file->fdr.ilineBase = 0;
+ file->fdr.cbLineOffset = c;
+ }
+ if (l->proc != proc)
+ {
+ proc = l->proc;
+ if (proc != (proc_t *) NULL)
+ {
+ proc->pdr.lnLow = l->lineno;
+ proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset;
+ proc->pdr.iline = totcount;
+ }
+ }
+
+ last = (lineno_list_t *) NULL;
+ }
+
+ totcount += count;
+
+ /* Get the offset to this line number. */
+ if (last == (lineno_list_t *) NULL)
+ delta = 0;
+ else
+ delta = l->lineno - last->lineno;
+
+ /* Put in the offset to this line number. */
+ while (delta != 0)
+ {
+ int setcount;
+
+ /* 1 is added to each count read. */
+ --count;
+ /* We can only adjust the word count by up to 15 words at a
+ time. */
+ if (count <= 0x0f)
+ {
+ setcount = count;
+ count = 0;
+ }
+ else
+ {
+ setcount = 0x0f;
+ count -= 0x0f;
+ }
+ if (delta >= -7 && delta <= 7)
+ {
+ if (bufptr >= *bufend)
+ bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
+ *bufptr++ = setcount + (delta << 4);
+ delta = 0;
+ ++c;
+ }
+ else
+ {
+ int set;
+
+ if (*bufend - bufptr < 3)
+ bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3);
+ *bufptr++ = setcount + (8 << 4);
+ if (delta < -0x8000)
+ {
+ set = -0x8000;
+ delta += 0x8000;
+ }
+ else if (delta > 0x7fff)
+ {
+ set = 0x7fff;
+ delta -= 0x7fff;
+ }
+ else
+ {
+ set = delta;
+ delta = 0;
+ }
+ *bufptr++ = set >> 8;
+ *bufptr++ = set & 0xffff;
+ c += 3;
+ }
+ }
+
+ /* Finish adjusting the count. */
+ while (count > 0)
+ {
+ if (bufptr >= *bufend)
+ bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
+ /* 1 is added to each count read. */
+ --count;
+ if (count > 0x0f)
+ {
+ *bufptr++ = 0x0f;
+ count -= 0x0f;
+ }
+ else
+ {
+ *bufptr++ = count;
+ count = 0;
+ }
+ ++c;
+ }
+
+ ++iline;
+ last = l;
+ }
+
+ if (proc != (proc_t *) NULL)
+ proc->pdr.lnHigh = last->lineno;
+ if (file != (efdr_t *) NULL)
+ {
+ file->fdr.cbLine = c - file->fdr.cbLineOffset;
+ file->fdr.cline = totcount;
+ }
+
+ if (linecntptr != (long *) NULL)
+ *linecntptr += totcount;
+
+ c = ecoff_padding_adjust (backend, buf, bufend, c, &bufptr);
+
+ return c;
+}
+
+/* Build and swap out the symbols. */
+
+static unsigned long
+ecoff_build_symbols (backend, buf, bufend, offset)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+{
+ const bfd_size_type external_sym_size = backend->external_sym_size;
+ void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
+ = backend->swap_sym_out;
+ char *sym_out;
+ long isym;
+ vlinks_t *file_link;
+
+ sym_out = *buf + offset;
+
+ isym = 0;
+
+ /* The symbols are stored by file. */
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int ifilesym;
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ vlinks_t *sym_link;
+
+ fil_ptr->fdr.isymBase = isym;
+ ifilesym = isym;
+ for (sym_link = fil_ptr->symbols.first;
+ sym_link != (vlinks_t *) NULL;
+ sym_link = sym_link->next)
+ {
+ int sym_cnt;
+ localsym_t *sym_ptr;
+ localsym_t *sym_end;
+
+ if (sym_link->next == (vlinks_t *) NULL)
+ sym_cnt = fil_ptr->symbols.objects_last_page;
+ else
+ sym_cnt = fil_ptr->symbols.objects_per_page;
+ sym_ptr = sym_link->datum->sym;
+ sym_end = sym_ptr + sym_cnt;
+ for (; sym_ptr < sym_end; sym_ptr++)
+ {
+ int local;
+ symbolS *as_sym;
+ forward_t *f;
+
+ know (sym_ptr->file_ptr == fil_ptr);
+
+ /* If there is no associated gas symbol, then this
+ is a pure debugging symbol. We have already
+ added the name (if any) to fil_ptr->strings.
+ Otherwise we must decide whether this is an
+ external or a local symbol (actually, it may be
+ both if the local provides additional debugging
+ information for the external). */
+ local = 1;
+ as_sym = sym_ptr->as_sym;
+ if (as_sym != (symbolS *) NULL)
+ {
+ symint_t indx;
+
+ /* The value of a block start symbol is the
+ offset from the start of the procedure. For
+ other symbols we just use the gas value (but
+ we must offset it by the vma of the section,
+ just as BFD does, because BFD will not see
+ this value). */
+ if (sym_ptr->ecoff_sym.asym.st == (int) st_Block
+ && sym_ptr->ecoff_sym.asym.sc == (int) sc_Text)
+ {
+ symbolS *begin_sym;
+
+ know (sym_ptr->proc_ptr != (proc_t *) NULL);
+ begin_sym = sym_ptr->proc_ptr->sym->as_sym;
+ if (S_GET_SEGMENT (as_sym)
+ != S_GET_SEGMENT (begin_sym))
+ as_warn (_(".begin/.bend in different segments"));
+ sym_ptr->ecoff_sym.asym.value =
+ S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
+ }
+ else
+ sym_ptr->ecoff_sym.asym.value =
+ (S_GET_VALUE (as_sym)
+ + bfd_get_section_vma (stdoutput,
+ S_GET_SEGMENT (as_sym))
+ + sym_ptr->addend);
+
+ sym_ptr->ecoff_sym.weakext = S_IS_WEAK (as_sym);
+
+ /* Set st_Proc to st_StaticProc for local
+ functions. */
+ if (sym_ptr->ecoff_sym.asym.st == st_Proc
+ && S_IS_DEFINED (as_sym)
+ && ! S_IS_EXTERNAL (as_sym)
+ && ! S_IS_WEAK (as_sym))
+ sym_ptr->ecoff_sym.asym.st = st_StaticProc;
+
+ /* Get the type and storage class based on where
+ the symbol actually wound up. Traditionally,
+ N_LBRAC and N_RBRAC are *not* relocated. */
+ indx = sym_ptr->ecoff_sym.asym.index;
+ if (sym_ptr->ecoff_sym.asym.st == st_Nil
+ && sym_ptr->ecoff_sym.asym.sc == sc_Nil
+ && (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
+ || ((ECOFF_UNMARK_STAB (indx) != N_LBRAC)
+ && (ECOFF_UNMARK_STAB (indx) != N_RBRAC))))
+ {
+ segT seg;
+ const char *segname;
+ st_t st;
+ sc_t sc;
+
+ seg = S_GET_SEGMENT (as_sym);
+ segname = segment_name (seg);
+
+ if (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
+ && (S_IS_EXTERNAL (as_sym)
+ || S_IS_WEAK (as_sym)
+ || ! S_IS_DEFINED (as_sym)))
+ {
+ if ((as_sym->bsym->flags & BSF_FUNCTION) != 0)
+ st = st_Proc;
+ else
+ st = st_Global;
+ }
+ else if (seg == text_section)
+ st = st_Label;
+ else
+ st = st_Static;
+
+ if (! S_IS_DEFINED (as_sym))
+ {
+ if (as_sym->ecoff_extern_size == 0
+ || (as_sym->ecoff_extern_size
+ > bfd_get_gp_size (stdoutput)))
+ sc = sc_Undefined;
+ else
+ {
+ sc = sc_SUndefined;
+ sym_ptr->ecoff_sym.asym.value =
+ as_sym->ecoff_extern_size;
+ }
+#ifdef S_SET_SIZE
+ S_SET_SIZE (as_sym, as_sym->ecoff_extern_size);
+#endif
+ }
+ else if (S_IS_COMMON (as_sym))
+ {
+ if (S_GET_VALUE (as_sym) > 0
+ && (S_GET_VALUE (as_sym)
+ <= bfd_get_gp_size (stdoutput)))
+ sc = sc_SCommon;
+ else
+ sc = sc_Common;
+ }
+ else if (seg == text_section)
+ sc = sc_Text;
+ else if (seg == data_section)
+ sc = sc_Data;
+ else if (strcmp (segname, ".rdata") == 0
+ || strcmp (segname, ".rodata") == 0)
+ sc = sc_RData;
+ else if (strcmp (segname, ".sdata") == 0)
+ sc = sc_SData;
+ else if (seg == bss_section)
+ sc = sc_Bss;
+ else if (strcmp (segname, ".sbss") == 0)
+ sc = sc_SBss;
+ else if (seg == &bfd_abs_section)
+ sc = sc_Abs;
+ else
+ {
+ /* This must be a user named section.
+ This is not possible in ECOFF, but it
+ is in ELF. */
+ sc = sc_Data;
+ }
+
+ sym_ptr->ecoff_sym.asym.st = (int) st;
+ sym_ptr->ecoff_sym.asym.sc = (int) sc;
+ }
+
+ /* This is just an external symbol if it is
+ outside a procedure and it has a type.
+ FIXME: g++ will generate symbols which have
+ different names in the debugging information
+ than the actual symbol. Should we handle
+ them here? */
+ if ((S_IS_EXTERNAL (as_sym)
+ || S_IS_WEAK (as_sym)
+ || ! S_IS_DEFINED (as_sym))
+ && sym_ptr->proc_ptr == (proc_t *) NULL
+ && sym_ptr->ecoff_sym.asym.st != (int) st_Nil
+ && ! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym))
+ local = 0;
+
+ /* This is just an external symbol if it is a
+ common symbol. */
+ if (S_IS_COMMON (as_sym))
+ local = 0;
+
+ /* If an st_end symbol has an associated gas
+ symbol, then it is a local label created for
+ a .bend or .end directive. Stabs line
+ numbers will have \001 in the names. */
+ if (local
+ && sym_ptr->ecoff_sym.asym.st != st_End
+ && strchr (sym_ptr->name, '\001') == 0)
+ sym_ptr->ecoff_sym.asym.iss =
+ add_string (&fil_ptr->strings,
+ fil_ptr->str_hash,
+ sym_ptr->name,
+ (shash_t **) NULL);
+ }
+
+ /* We now know the index of this symbol; fill in
+ locations that have been waiting for that
+ information. */
+ if (sym_ptr->begin_ptr != (localsym_t *) NULL)
+ {
+ localsym_t *begin_ptr;
+ st_t begin_type;
+
+ know (local);
+ begin_ptr = sym_ptr->begin_ptr;
+ know (begin_ptr->sym_index != -1);
+ sym_ptr->ecoff_sym.asym.index = begin_ptr->sym_index;
+ if (sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
+ sym_ptr->ecoff_sym.asym.iss =
+ begin_ptr->ecoff_sym.asym.iss;
+
+ begin_type = begin_ptr->ecoff_sym.asym.st;
+ if (begin_type == st_File
+ || begin_type == st_Block)
+ {
+ begin_ptr->ecoff_sym.asym.index =
+ isym - ifilesym + 1;
+ (*swap_sym_out) (stdoutput,
+ &begin_ptr->ecoff_sym.asym,
+ (*buf
+ + offset
+ + (begin_ptr->sym_index
+ * external_sym_size)));
+ }
+ else
+ {
+ know (begin_ptr->index_ptr != (aux_t *) NULL);
+ begin_ptr->index_ptr->data.isym =
+ isym - ifilesym + 1;
+ }
+
+ /* The value of the symbol marking the end of a
+ procedure is the size of the procedure. The
+ value of the symbol marking the end of a
+ block is the offset from the start of the
+ procedure to the block. */
+ if (begin_type == st_Proc
+ || begin_type == st_StaticProc)
+ {
+ know (as_sym != (symbolS *) NULL);
+ know (begin_ptr->as_sym != (symbolS *) NULL);
+ if (S_GET_SEGMENT (as_sym)
+ != S_GET_SEGMENT (begin_ptr->as_sym))
+ as_warn (_(".begin/.bend in different segments"));
+ sym_ptr->ecoff_sym.asym.value =
+ (S_GET_VALUE (as_sym)
+ - S_GET_VALUE (begin_ptr->as_sym));
+
+ /* If the size is odd, this is probably a
+ mips16 function; force it to be even. */
+ if ((sym_ptr->ecoff_sym.asym.value & 1) != 0)
+ ++sym_ptr->ecoff_sym.asym.value;
+
+#ifdef S_SET_SIZE
+ S_SET_SIZE (begin_ptr->as_sym,
+ sym_ptr->ecoff_sym.asym.value);
+#endif
+ }
+ else if (begin_type == st_Block
+ && sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
+ {
+ symbolS *begin_sym;
+
+ know (as_sym != (symbolS *) NULL);
+ know (sym_ptr->proc_ptr != (proc_t *) NULL);
+ begin_sym = sym_ptr->proc_ptr->sym->as_sym;
+ if (S_GET_SEGMENT (as_sym)
+ != S_GET_SEGMENT (begin_sym))
+ as_warn (_(".begin/.bend in different segments"));
+ sym_ptr->ecoff_sym.asym.value =
+ S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
+ }
+ }
+
+ for (f = sym_ptr->forward_ref;
+ f != (forward_t *) NULL;
+ f = f->next)
+ {
+ know (local);
+ f->ifd_ptr->data.isym = fil_ptr->file_index;
+ f->index_ptr->data.rndx.index = isym - ifilesym;
+ }
+
+ if (local)
+ {
+ if (*bufend - sym_out < external_sym_size)
+ sym_out = ecoff_add_bytes (buf, bufend,
+ sym_out,
+ external_sym_size);
+ (*swap_sym_out) (stdoutput, &sym_ptr->ecoff_sym.asym,
+ sym_out);
+ sym_out += external_sym_size;
+
+ sym_ptr->sym_index = isym;
+
+ if (sym_ptr->proc_ptr != (proc_t *) NULL
+ && sym_ptr->proc_ptr->sym == sym_ptr)
+ sym_ptr->proc_ptr->pdr.isym = isym - ifilesym;
+
+ ++isym;
+ }
+
+ /* Record the local symbol index and file number in
+ case this is an external symbol. Note that this
+ destroys the asym.index field. */
+ if (as_sym != (symbolS *) NULL
+ && as_sym->ecoff_symbol == sym_ptr)
+ {
+ if ((sym_ptr->ecoff_sym.asym.st == st_Proc
+ || sym_ptr->ecoff_sym.asym.st == st_StaticProc)
+ && local)
+ sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1;
+ sym_ptr->ecoff_sym.ifd = fil_ptr->file_index;
+
+ /* Don't try to merge an FDR which has an
+ external symbol attached to it. */
+ if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym))
+ fil_ptr->fdr.fMerge = 0;
+ }
+ }
+ }
+ fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase;
+ }
+ }
+
+ return offset + isym * external_sym_size;
+}
+
+/* Swap out the procedure information. */
+
+static unsigned long
+ecoff_build_procs (backend, buf, bufend, offset)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+{
+ const bfd_size_type external_pdr_size = backend->external_pdr_size;
+ void (* const swap_pdr_out) PARAMS ((bfd *, const PDR *, PTR))
+ = backend->swap_pdr_out;
+ char *pdr_out;
+ long iproc;
+ vlinks_t *file_link;
+
+ pdr_out = *buf + offset;
+
+ iproc = 0;
+
+ /* The procedures are stored by file. */
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ vlinks_t *proc_link;
+ int first;
+
+ fil_ptr->fdr.ipdFirst = iproc;
+ first = 1;
+ for (proc_link = fil_ptr->procs.first;
+ proc_link != (vlinks_t *) NULL;
+ proc_link = proc_link->next)
+ {
+ int prc_cnt;
+ proc_t *proc_ptr;
+ proc_t *proc_end;
+
+ if (proc_link->next == (vlinks_t *) NULL)
+ prc_cnt = fil_ptr->procs.objects_last_page;
+ else
+ prc_cnt = fil_ptr->procs.objects_per_page;
+ proc_ptr = proc_link->datum->proc;
+ proc_end = proc_ptr + prc_cnt;
+ for (; proc_ptr < proc_end; proc_ptr++)
+ {
+ symbolS *adr_sym;
+ unsigned long adr;
+
+ adr_sym = proc_ptr->sym->as_sym;
+ adr = (S_GET_VALUE (adr_sym)
+ + bfd_get_section_vma (stdoutput,
+ S_GET_SEGMENT (adr_sym)));
+ if (first)
+ {
+ /* This code used to force the adr of the very
+ first fdr to be 0. However, the native tools
+ don't do that, and I can't remember why it
+ used to work that way, so I took it out. */
+ fil_ptr->fdr.adr = adr;
+ first = 0;
+ }
+ proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr;
+ if (*bufend - pdr_out < external_pdr_size)
+ pdr_out = ecoff_add_bytes (buf, bufend,
+ pdr_out,
+ external_pdr_size);
+ (*swap_pdr_out) (stdoutput, &proc_ptr->pdr, pdr_out);
+ pdr_out += external_pdr_size;
+ ++iproc;
+ }
+ }
+ fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst;
+ }
+ }
+
+ return offset + iproc * external_pdr_size;
+}
+
+/* Swap out the aux information. */
+
+static unsigned long
+ecoff_build_aux (backend, buf, bufend, offset)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+{
+ int bigendian;
+ union aux_ext *aux_out;
+ long iaux;
+ vlinks_t *file_link;
+
+ bigendian = bfd_big_endian (stdoutput);
+
+ aux_out = (union aux_ext *) (*buf + offset);
+
+ iaux = 0;
+
+ /* The aux entries are stored by file. */
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ vlinks_t *aux_link;
+
+ fil_ptr->fdr.fBigendian = bigendian;
+ fil_ptr->fdr.iauxBase = iaux;
+ for (aux_link = fil_ptr->aux_syms.first;
+ aux_link != (vlinks_t *) NULL;
+ aux_link = aux_link->next)
+ {
+ int aux_cnt;
+ aux_t *aux_ptr;
+ aux_t *aux_end;
+
+ if (aux_link->next == (vlinks_t *) NULL)
+ aux_cnt = fil_ptr->aux_syms.objects_last_page;
+ else
+ aux_cnt = fil_ptr->aux_syms.objects_per_page;
+ aux_ptr = aux_link->datum->aux;
+ aux_end = aux_ptr + aux_cnt;
+ for (; aux_ptr < aux_end; aux_ptr++)
+ {
+ if (*bufend - (char *) aux_out < sizeof (union aux_ext))
+ aux_out = ((union aux_ext *)
+ ecoff_add_bytes (buf, bufend,
+ (char *) aux_out,
+ sizeof (union aux_ext)));
+ switch (aux_ptr->type)
+ {
+ case aux_tir:
+ (*backend->swap_tir_out) (bigendian,
+ &aux_ptr->data.ti,
+ &aux_out->a_ti);
+ break;
+ case aux_rndx:
+ (*backend->swap_rndx_out) (bigendian,
+ &aux_ptr->data.rndx,
+ &aux_out->a_rndx);
+ break;
+ case aux_dnLow:
+ AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow,
+ aux_out);
+ break;
+ case aux_dnHigh:
+ AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh,
+ aux_out);
+ break;
+ case aux_isym:
+ AUX_PUT_ISYM (bigendian, aux_ptr->data.isym,
+ aux_out);
+ break;
+ case aux_iss:
+ AUX_PUT_ISS (bigendian, aux_ptr->data.iss,
+ aux_out);
+ break;
+ case aux_width:
+ AUX_PUT_WIDTH (bigendian, aux_ptr->data.width,
+ aux_out);
+ break;
+ case aux_count:
+ AUX_PUT_COUNT (bigendian, aux_ptr->data.count,
+ aux_out);
+ break;
+ }
+
+ ++aux_out;
+ ++iaux;
+ }
+ }
+ fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase;
+ }
+ }
+
+ return ecoff_padding_adjust (backend, buf, bufend,
+ offset + iaux * sizeof (union aux_ext),
+ (char **) NULL);
+}
+
+/* Copy out the strings from a varray_t. This returns the number of
+ bytes copied, rather than the new offset. */
+
+static unsigned long
+ecoff_build_strings (buf, bufend, offset, vp)
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+ varray_t *vp;
+{
+ unsigned long istr;
+ char *str_out;
+ vlinks_t *str_link;
+
+ str_out = *buf + offset;
+
+ istr = 0;
+
+ for (str_link = vp->first;
+ str_link != (vlinks_t *) NULL;
+ str_link = str_link->next)
+ {
+ unsigned long str_cnt;
+
+ if (str_link->next == (vlinks_t *) NULL)
+ str_cnt = vp->objects_last_page;
+ else
+ str_cnt = vp->objects_per_page;
+
+ if (*bufend - str_out < str_cnt)
+ str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt);
+
+ memcpy (str_out, str_link->datum->byte, str_cnt);
+ str_out += str_cnt;
+ istr += str_cnt;
+ }
+
+ return istr;
+}
+
+/* Dump out the local strings. */
+
+static unsigned long
+ecoff_build_ss (backend, buf, bufend, offset)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+{
+ long iss;
+ vlinks_t *file_link;
+
+ iss = 0;
+
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ long ss_cnt;
+
+ fil_ptr->fdr.issBase = iss;
+ ss_cnt = ecoff_build_strings (buf, bufend, offset + iss,
+ &fil_ptr->strings);
+ fil_ptr->fdr.cbSs = ss_cnt;
+ iss += ss_cnt;
+ }
+ }
+
+ return ecoff_padding_adjust (backend, buf, bufend, offset + iss,
+ (char **) NULL);
+}
+
+/* Swap out the file descriptors. */
+
+static unsigned long
+ecoff_build_fdr (backend, buf, bufend, offset)
+ const struct ecoff_debug_swap *backend;
+ char **buf;
+ char **bufend;
+ unsigned long offset;
+{
+ const bfd_size_type external_fdr_size = backend->external_fdr_size;
+ void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
+ = backend->swap_fdr_out;
+ long ifile;
+ char *fdr_out;
+ vlinks_t *file_link;
+
+ ifile = 0;
+
+ fdr_out = *buf + offset;
+
+ for (file_link = file_desc.first;
+ file_link != (vlinks_t *) NULL;
+ file_link = file_link->next)
+ {
+ int fil_cnt;
+ efdr_t *fil_ptr;
+ efdr_t *fil_end;
+
+ if (file_link->next == (vlinks_t *) NULL)
+ fil_cnt = file_desc.objects_last_page;
+ else
+ fil_cnt = file_desc.objects_per_page;
+ fil_ptr = file_link->datum->file;
+ fil_end = fil_ptr + fil_cnt;
+ for (; fil_ptr < fil_end; fil_ptr++)
+ {
+ if (*bufend - fdr_out < external_fdr_size)
+ fdr_out = ecoff_add_bytes (buf, bufend, fdr_out,
+ external_fdr_size);
+ (*swap_fdr_out) (stdoutput, &fil_ptr->fdr, fdr_out);
+ fdr_out += external_fdr_size;
+ ++ifile;
+ }
+ }
+
+ return offset + ifile * external_fdr_size;
+}
+
+/* Set up the external symbols. These are supposed to be handled by
+ the backend. This routine just gets the right information and
+ calls a backend function to deal with it. */
+
+static void
+ecoff_setup_ext ()
+{
+ register symbolS *sym;
+
+ for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
+ {
+ if (sym->ecoff_symbol == NULL)
+ continue;
+
+ /* If this is a local symbol, then force the fields to zero. */
+ if (! S_IS_EXTERNAL (sym)
+ && ! S_IS_WEAK (sym)
+ && S_IS_DEFINED (sym))
+ {
+ sym->ecoff_symbol->ecoff_sym.asym.value = 0;
+ sym->ecoff_symbol->ecoff_sym.asym.st = (int) st_Nil;
+ sym->ecoff_symbol->ecoff_sym.asym.sc = (int) sc_Nil;
+ sym->ecoff_symbol->ecoff_sym.asym.index = indexNil;
+ }
+
+ obj_ecoff_set_ext (sym, &sym->ecoff_symbol->ecoff_sym);
+ }
+}
+
+/* Build the ECOFF debugging information. */
+
+unsigned long
+ecoff_build_debug (hdr, bufp, backend)
+ HDRR *hdr;
+ char **bufp;
+ const struct ecoff_debug_swap *backend;
+{
+ const bfd_size_type external_pdr_size = backend->external_pdr_size;
+ tag_t *ptag;
+ tag_t *ptag_next;
+ efdr_t *fil_ptr;
+ int end_warning;
+ efdr_t *hold_file_ptr;
+ proc_t * hold_proc_ptr;
+ symbolS *sym;
+ char *buf;
+ char *bufend;
+ unsigned long offset;
+
+ /* Make sure we have a file. */
+ if (first_file == (efdr_t *) NULL)
+ add_file ((const char *) NULL, 0, 1);
+
+ /* Handle any top level tags. */
+ for (ptag = top_tag_head->first_tag;
+ ptag != (tag_t *) NULL;
+ ptag = ptag_next)
+ {
+ if (ptag->forward_ref != (forward_t *) NULL)
+ add_unknown_tag (ptag);
+
+ ptag_next = ptag->same_block;
+ ptag->hash_ptr->tag_ptr = ptag->same_name;
+ free_tag (ptag);
+ }
+
+ free_thead (top_tag_head);
+
+ /* Look through the symbols. Add debugging information for each
+ symbol that has not already received it. */
+ hold_file_ptr = cur_file_ptr;
+ hold_proc_ptr = cur_proc_ptr;
+ cur_proc_ptr = (proc_t *) NULL;
+ for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
+ {
+ if (sym->ecoff_symbol != NULL
+ || sym->ecoff_file == (efdr_t *) NULL
+ || (sym->bsym->flags & BSF_SECTION_SYM) != 0)
+ continue;
+
+ cur_file_ptr = sym->ecoff_file;
+ add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
+ (bfd_vma) 0, S_GET_VALUE (sym), indexNil);
+ }
+ cur_proc_ptr = hold_proc_ptr;
+ cur_file_ptr = hold_file_ptr;
+
+ /* Output an ending symbol for all the files. We have to do this
+ here for the last file, so we may as well do it for all of the
+ files. */
+ end_warning = 0;
+ for (fil_ptr = first_file;
+ fil_ptr != (efdr_t *) NULL;
+ fil_ptr = fil_ptr->next_file)
+ {
+ cur_file_ptr = fil_ptr;
+ while (cur_file_ptr->cur_scope != (scope_t *) NULL
+ && cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
+ {
+ cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev;
+ if (! end_warning && ! cur_file_ptr->fake)
+ {
+ as_warn (_("Missing .end or .bend at end of file"));
+ end_warning = 1;
+ }
+ }
+ if (cur_file_ptr->cur_scope != (scope_t *) NULL)
+ (void) add_ecoff_symbol ((const char *) NULL,
+ st_End, sc_Text,
+ (symbolS *) NULL,
+ (bfd_vma) 0,
+ (symint_t) 0,
+ (symint_t) 0);
+ }
+
+ /* Build the symbolic information. */
+ offset = 0;
+ buf = xmalloc (PAGE_SIZE);
+ bufend = buf + PAGE_SIZE;
+
+ /* Build the line number information. */
+ hdr->cbLineOffset = offset;
+ offset = ecoff_build_lineno (backend, &buf, &bufend, offset,
+ &hdr->ilineMax);
+ hdr->cbLine = offset - hdr->cbLineOffset;
+
+ /* We don't use dense numbers at all. */
+ hdr->idnMax = 0;
+ hdr->cbDnOffset = 0;
+
+ /* We can't build the PDR table until we have built the symbols,
+ because a PDR contains a symbol index. However, we set aside
+ space at this point. */
+ hdr->ipdMax = proc_cnt;
+ hdr->cbPdOffset = offset;
+ if (bufend - (buf + offset) < proc_cnt * external_pdr_size)
+ (void) ecoff_add_bytes (&buf, &bufend, buf + offset,
+ proc_cnt * external_pdr_size);
+ offset += proc_cnt * external_pdr_size;
+
+ /* Build the local symbols. */
+ hdr->cbSymOffset = offset;
+ offset = ecoff_build_symbols (backend, &buf, &bufend, offset);
+ hdr->isymMax = (offset - hdr->cbSymOffset) / backend->external_sym_size;
+
+ /* Building the symbols initializes the symbol index in the PDR's.
+ Now we can swap out the PDR's. */
+ (void) ecoff_build_procs (backend, &buf, &bufend, hdr->cbPdOffset);
+
+ /* We don't use optimization symbols. */
+ hdr->ioptMax = 0;
+ hdr->cbOptOffset = 0;
+
+ /* Swap out the auxiliary type information. */
+ hdr->cbAuxOffset = offset;
+ offset = ecoff_build_aux (backend, &buf, &bufend, offset);
+ hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext);
+
+ /* Copy out the local strings. */
+ hdr->cbSsOffset = offset;
+ offset = ecoff_build_ss (backend, &buf, &bufend, offset);
+ hdr->issMax = offset - hdr->cbSsOffset;
+
+ /* We don't use relative file descriptors. */
+ hdr->crfd = 0;
+ hdr->cbRfdOffset = 0;
+
+ /* Swap out the file descriptors. */
+ hdr->cbFdOffset = offset;
+ offset = ecoff_build_fdr (backend, &buf, &bufend, offset);
+ hdr->ifdMax = (offset - hdr->cbFdOffset) / backend->external_fdr_size;
+
+ /* Set up the external symbols, which are handled by the BFD back
+ end. */
+ hdr->issExtMax = 0;
+ hdr->cbSsExtOffset = 0;
+ hdr->iextMax = 0;
+ hdr->cbExtOffset = 0;
+ ecoff_setup_ext ();
+
+ know ((offset & (backend->debug_align - 1)) == 0);
+
+ /* FIXME: This value should be determined from the .verstamp directive,
+ with reasonable defaults in config files. */
+#ifdef TC_ALPHA
+ hdr->vstamp = 0x030b;
+#else
+ hdr->vstamp = 0x020b;
+#endif
+
+ *bufp = buf;
+ return offset;
+}
+
+/* Allocate a cluster of pages. */
+
+#ifndef MALLOC_CHECK
+
+static page_type *
+allocate_cluster (npages)
+ unsigned long npages;
+{
+ register page_type *value = (page_type *) xmalloc (npages * PAGE_USIZE);
+
+#ifdef ECOFF_DEBUG
+ if (debug > 3)
+ fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
+#endif
+
+ memset (value, 0, npages * PAGE_USIZE);
+
+ return value;
+}
+
+
+static page_type *cluster_ptr = NULL;
+static unsigned long pages_left = 0;
+
+#endif /* MALLOC_CHECK */
+
+/* Allocate one page (which is initialized to 0). */
+
+static page_type *
+allocate_page ()
+{
+#ifndef MALLOC_CHECK
+
+ if (pages_left == 0)
+ {
+ pages_left = MAX_CLUSTER_PAGES;
+ cluster_ptr = allocate_cluster (pages_left);
+ }
+
+ pages_left--;
+ return cluster_ptr++;
+
+#else /* MALLOC_CHECK */
+
+ page_type *ptr;
+
+ ptr = xmalloc (PAGE_USIZE);
+ memset (ptr, 0, PAGE_USIZE);
+ return ptr;
+
+#endif /* MALLOC_CHECK */
+}
+
+/* Allocate scoping information. */
+
+static scope_t *
+allocate_scope ()
+{
+ register scope_t *ptr;
+ static scope_t initial_scope;
+
+#ifndef MALLOC_CHECK
+
+ ptr = alloc_counts[(int)alloc_type_scope].free_list.f_scope;
+ if (ptr != (scope_t *) NULL)
+ alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free;
+ else
+ {
+ register int unallocated = alloc_counts[(int)alloc_type_scope].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_scope].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (scope_t);
+ alloc_counts[(int)alloc_type_scope].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_scope].total_pages++;
+ }
+
+ ptr = &cur_page->scope[--unallocated];
+ alloc_counts[(int)alloc_type_scope].unallocated = unallocated;
+ }
+
+#else
+
+ ptr = (scope_t *) xmalloc (sizeof (scope_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_scope].total_alloc++;
+ *ptr = initial_scope;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+static void
+free_scope (ptr)
+ scope_t *ptr;
+{
+ alloc_counts[(int)alloc_type_scope].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[(int)alloc_type_scope].free_list.f_scope;
+ alloc_counts[(int)alloc_type_scope].free_list.f_scope = ptr;
+#else
+ free ((PTR) ptr);
+#endif
+}
+
+/* Allocate links for pages in a virtual array. */
+
+static vlinks_t *
+allocate_vlinks ()
+{
+ register vlinks_t *ptr;
+ static vlinks_t initial_vlinks;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int)alloc_type_vlinks].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_vlinks].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (vlinks_t);
+ alloc_counts[(int)alloc_type_vlinks].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_vlinks].total_pages++;
+ }
+
+ ptr = &cur_page->vlinks[--unallocated];
+ alloc_counts[(int)alloc_type_vlinks].unallocated = unallocated;
+
+#else
+
+ ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_vlinks].total_alloc++;
+ *ptr = initial_vlinks;
+ return ptr;
+}
+
+/* Allocate string hash buckets. */
+
+static shash_t *
+allocate_shash ()
+{
+ register shash_t *ptr;
+ static shash_t initial_shash;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int)alloc_type_shash].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_shash].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (shash_t);
+ alloc_counts[(int)alloc_type_shash].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_shash].total_pages++;
+ }
+
+ ptr = &cur_page->shash[--unallocated];
+ alloc_counts[(int)alloc_type_shash].unallocated = unallocated;
+
+#else
+
+ ptr = (shash_t *) xmalloc (sizeof (shash_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_shash].total_alloc++;
+ *ptr = initial_shash;
+ return ptr;
+}
+
+/* Allocate type hash buckets. */
+
+static thash_t *
+allocate_thash ()
+{
+ register thash_t *ptr;
+ static thash_t initial_thash;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int)alloc_type_thash].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_thash].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (thash_t);
+ alloc_counts[(int)alloc_type_thash].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_thash].total_pages++;
+ }
+
+ ptr = &cur_page->thash[--unallocated];
+ alloc_counts[(int)alloc_type_thash].unallocated = unallocated;
+
+#else
+
+ ptr = (thash_t *) xmalloc (sizeof (thash_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_thash].total_alloc++;
+ *ptr = initial_thash;
+ return ptr;
+}
+
+/* Allocate structure, union, or enum tag information. */
+
+static tag_t *
+allocate_tag ()
+{
+ register tag_t *ptr;
+ static tag_t initial_tag;
+
+#ifndef MALLOC_CHECK
+
+ ptr = alloc_counts[(int)alloc_type_tag].free_list.f_tag;
+ if (ptr != (tag_t *) NULL)
+ alloc_counts[(int)alloc_type_tag].free_list.f_tag = ptr->free;
+ else
+ {
+ register int unallocated = alloc_counts[(int)alloc_type_tag].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_tag].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (tag_t);
+ alloc_counts[(int)alloc_type_tag].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_tag].total_pages++;
+ }
+
+ ptr = &cur_page->tag[--unallocated];
+ alloc_counts[(int)alloc_type_tag].unallocated = unallocated;
+ }
+
+#else
+
+ ptr = (tag_t *) xmalloc (sizeof (tag_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_tag].total_alloc++;
+ *ptr = initial_tag;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+static void
+free_tag (ptr)
+ tag_t *ptr;
+{
+ alloc_counts[(int)alloc_type_tag].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = alloc_counts[(int)alloc_type_tag].free_list.f_tag;
+ alloc_counts[(int)alloc_type_tag].free_list.f_tag = ptr;
+#else
+ free ((PTR_T) ptr);
+#endif
+}
+
+/* Allocate forward reference to a yet unknown tag. */
+
+static forward_t *
+allocate_forward ()
+{
+ register forward_t *ptr;
+ static forward_t initial_forward;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int)alloc_type_forward].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_forward].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (forward_t);
+ alloc_counts[(int)alloc_type_forward].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_forward].total_pages++;
+ }
+
+ ptr = &cur_page->forward[--unallocated];
+ alloc_counts[(int)alloc_type_forward].unallocated = unallocated;
+
+#else
+
+ ptr = (forward_t *) xmalloc (sizeof (forward_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_forward].total_alloc++;
+ *ptr = initial_forward;
+ return ptr;
+}
+
+/* Allocate head of type hash list. */
+
+static thead_t *
+allocate_thead ()
+{
+ register thead_t *ptr;
+ static thead_t initial_thead;
+
+#ifndef MALLOC_CHECK
+
+ ptr = alloc_counts[(int)alloc_type_thead].free_list.f_thead;
+ if (ptr != (thead_t *) NULL)
+ alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free;
+ else
+ {
+ register int unallocated = alloc_counts[(int)alloc_type_thead].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_thead].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (thead_t);
+ alloc_counts[(int)alloc_type_thead].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_thead].total_pages++;
+ }
+
+ ptr = &cur_page->thead[--unallocated];
+ alloc_counts[(int)alloc_type_thead].unallocated = unallocated;
+ }
+
+#else
+
+ ptr = (thead_t *) xmalloc (sizeof (thead_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_thead].total_alloc++;
+ *ptr = initial_thead;
+ return ptr;
+}
+
+/* Free scoping information. */
+
+static void
+free_thead (ptr)
+ thead_t *ptr;
+{
+ alloc_counts[(int)alloc_type_thead].total_free++;
+
+#ifndef MALLOC_CHECK
+ ptr->free = (thead_t *) alloc_counts[(int)alloc_type_thead].free_list.f_thead;
+ alloc_counts[(int)alloc_type_thead].free_list.f_thead = ptr;
+#else
+ free ((PTR_T) ptr);
+#endif
+}
+
+static lineno_list_t *
+allocate_lineno_list ()
+{
+ register lineno_list_t *ptr;
+ static lineno_list_t initial_lineno_list;
+
+#ifndef MALLOC_CHECK
+
+ register int unallocated = alloc_counts[(int)alloc_type_lineno].unallocated;
+ register page_type *cur_page = alloc_counts[(int)alloc_type_lineno].cur_page;
+
+ if (unallocated == 0)
+ {
+ unallocated = PAGE_SIZE / sizeof (lineno_list_t);
+ alloc_counts[(int)alloc_type_lineno].cur_page = cur_page = allocate_page ();
+ alloc_counts[(int)alloc_type_lineno].total_pages++;
+ }
+
+ ptr = &cur_page->lineno[--unallocated];
+ alloc_counts[(int)alloc_type_lineno].unallocated = unallocated;
+
+#else
+
+ ptr = (lineno_list_t *) xmalloc (sizeof (lineno_list_t));
+
+#endif
+
+ alloc_counts[(int)alloc_type_lineno].total_alloc++;
+ *ptr = initial_lineno_list;
+ return ptr;
+}
+
+void
+ecoff_set_gp_prolog_size (sz)
+ int sz;
+{
+ if (cur_proc_ptr == 0)
+ return;
+
+ cur_proc_ptr->pdr.gp_prologue = sz;
+ if (cur_proc_ptr->pdr.gp_prologue != sz)
+ {
+ as_warn (_("GP prologue size exceeds field size, using 0 instead"));
+ cur_proc_ptr->pdr.gp_prologue = 0;
+ }
+
+ cur_proc_ptr->pdr.gp_used = 1;
+}
+
+int
+ecoff_no_current_file ()
+{
+ return cur_file_ptr == (efdr_t *) NULL;
+}
+
+void
+ecoff_generate_asm_lineno ()
+{
+ unsigned int lineno;
+ char *filename;
+ lineno_list_t *list;
+
+ as_where (&filename, &lineno);
+
+ if (current_stabs_filename == (char *)NULL
+ || strcmp (current_stabs_filename, filename))
+ add_file (filename, 0, 1);
+
+ list = allocate_lineno_list ();
+
+ list->next = (lineno_list_t *) NULL;
+ list->file = cur_file_ptr;
+ list->proc = cur_proc_ptr;
+ list->frag = frag_now;
+ list->paddr = frag_now_fix ();
+ list->lineno = lineno;
+
+ /* We don't want to merge files which have line numbers. */
+ cur_file_ptr->fdr.fMerge = 0;
+
+ /* A .loc directive will sometimes appear before a .ent directive,
+ which means that cur_proc_ptr will be NULL here. Arrange to
+ patch this up. */
+ if (cur_proc_ptr == (proc_t *) NULL)
+ {
+ lineno_list_t **pl;
+
+ pl = &noproc_lineno;
+ while (*pl != (lineno_list_t *) NULL)
+ pl = &(*pl)->next;
+ *pl = list;
+ }
+ else
+ {
+ last_lineno = list;
+ *last_lineno_ptr = list;
+ last_lineno_ptr = &list->next;
+ }
+}
+
+#else
+
+void
+ecoff_generate_asm_lineno ()
+{
+}
+
+#endif /* ECOFF_DEBUGGING */
diff --git a/gas/ecoff.h b/gas/ecoff.h
new file mode 100644
index 00000000000..1a9b6fcdd3a
--- /dev/null
+++ b/gas/ecoff.h
@@ -0,0 +1,110 @@
+/* ecoff.h -- header file for ECOFF debugging support
+ Copyright (C) 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Put together by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef GAS_ECOFF_H
+#define GAS_ECOFF_H
+
+#ifdef ECOFF_DEBUGGING
+
+#include "coff/sym.h"
+#include "coff/ecoff.h"
+
+/* Whether we have seen any ECOFF debugging information. */
+extern int ecoff_debugging_seen;
+
+/* This function should be called at the start of assembly, by
+ obj_read_begin_hook. */
+extern void ecoff_read_begin_hook PARAMS ((void));
+
+/* This function should be called when the assembler switches to a new
+ file. */
+extern void ecoff_new_file PARAMS ((const char *));
+
+/* This function should be called when a new symbol is created, by
+ obj_symbol_new_hook. */
+extern void ecoff_symbol_new_hook PARAMS ((struct symbol *));
+
+/* This function should be called by the obj_frob_symbol hook. */
+extern void ecoff_frob_symbol PARAMS ((struct symbol *));
+
+/* Build the ECOFF debugging information. This should be called by
+ obj_frob_file. This fills in the counts in *HDR; the offsets are
+ filled in relative to the start of the *BUFP. It sets *BUFP to a
+ block of memory holding the debugging information. It returns the
+ length of *BUFP. */
+extern unsigned long ecoff_build_debug
+ PARAMS ((HDRR *hdr, char **bufp, const struct ecoff_debug_swap *));
+
+/* Functions to handle the ECOFF debugging directives. */
+extern void ecoff_directive_begin PARAMS ((int));
+extern void ecoff_directive_bend PARAMS ((int));
+extern void ecoff_directive_end PARAMS ((int));
+extern void ecoff_directive_ent PARAMS ((int));
+extern void ecoff_directive_fmask PARAMS ((int));
+extern void ecoff_directive_frame PARAMS ((int));
+extern void ecoff_directive_loc PARAMS ((int));
+extern void ecoff_directive_mask PARAMS ((int));
+
+/* Other ECOFF directives. */
+extern void ecoff_directive_extern PARAMS ((int));
+extern void ecoff_directive_weakext PARAMS ((int));
+
+/* Functions to handle the COFF debugging directives. */
+extern void ecoff_directive_def PARAMS ((int));
+extern void ecoff_directive_dim PARAMS ((int));
+extern void ecoff_directive_endef PARAMS ((int));
+extern void ecoff_directive_file PARAMS ((int));
+extern void ecoff_directive_scl PARAMS ((int));
+extern void ecoff_directive_size PARAMS ((int));
+extern void ecoff_directive_tag PARAMS ((int));
+extern void ecoff_directive_type PARAMS ((int));
+extern void ecoff_directive_val PARAMS ((int));
+
+/* Handle stabs. */
+extern void ecoff_stab PARAMS ((segT sec, int what, const char *string,
+ int type, int other, int desc));
+
+/* Set the GP prologue size. */
+extern void ecoff_set_gp_prolog_size PARAMS ((int sz));
+
+/* This routine is called from the ECOFF code to set the external
+ information for a symbol. */
+#ifndef obj_ecoff_set_ext
+extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *));
+#endif
+
+/* This routine is used to patch up a line number directive when
+ instructions are moved around. */
+extern void ecoff_fix_loc PARAMS ((fragS *, unsigned long));
+
+/* This function is called from read.c to peek at cur_file_ptr. */
+extern int ecoff_no_current_file PARAMS ((void));
+
+/* This function returns the symbol associated with the current proc. */
+extern struct symbol *ecoff_get_cur_proc_sym PARAMS ((void));
+
+#endif /* ECOFF_DEBUGGING */
+
+/* This routine is called from read.c to generate line number for .s file. */
+extern void ecoff_generate_asm_lineno PARAMS ((void));
+
+#endif /* ! GAS_ECOFF_H */
diff --git a/gas/ehopt.c b/gas/ehopt.c
new file mode 100644
index 00000000000..a0a5f62f4d7
--- /dev/null
+++ b/gas/ehopt.c
@@ -0,0 +1,469 @@
+/* ehopt.c--optimize gcc exception frame information.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "as.h"
+#include "subsegs.h"
+
+/* We include this ELF file, even though we may not be assembling for
+ ELF, since the exception frame information is always in a format
+ derived from DWARF. */
+
+#include "elf/dwarf2.h"
+
+/* Try to optimize gcc 2.8 exception frame information.
+
+ Exception frame information is emitted for every function in the
+ .eh_frame section. Simple information for a function with no
+ exceptions looks like this:
+
+__FRAME_BEGIN__:
+ .4byte .LLCIE1 / Length of Common Information Entry
+.LSCIE1:
+ .4byte 0x0 / CIE Identifier Tag
+ .byte 0x1 / CIE Version
+ .byte 0x0 / CIE Augmentation (none)
+ .byte 0x1 / ULEB128 0x1 (CIE Code Alignment Factor)
+ .byte 0x7c / SLEB128 -4 (CIE Data Alignment Factor)
+ .byte 0x8 / CIE RA Column
+ .byte 0xc / DW_CFA_def_cfa
+ .byte 0x4 / ULEB128 0x4
+ .byte 0x4 / ULEB128 0x4
+ .byte 0x88 / DW_CFA_offset, column 0x8
+ .byte 0x1 / ULEB128 0x1
+ .align 4
+.LECIE1:
+ .set .LLCIE1,.LECIE1-.LSCIE1 / CIE Length Symbol
+ .4byte .LLFDE1 / FDE Length
+.LSFDE1:
+ .4byte .LSFDE1-__FRAME_BEGIN__ / FDE CIE offset
+ .4byte .LFB1 / FDE initial location
+ .4byte .LFE1-.LFB1 / FDE address range
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI0-.LFB1
+ .byte 0xe / DW_CFA_def_cfa_offset
+ .byte 0x8 / ULEB128 0x8
+ .byte 0x85 / DW_CFA_offset, column 0x5
+ .byte 0x2 / ULEB128 0x2
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI1-.LCFI0
+ .byte 0xd / DW_CFA_def_cfa_register
+ .byte 0x5 / ULEB128 0x5
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI2-.LCFI1
+ .byte 0x2e / DW_CFA_GNU_args_size
+ .byte 0x4 / ULEB128 0x4
+ .byte 0x4 / DW_CFA_advance_loc4
+ .4byte .LCFI3-.LCFI2
+ .byte 0x2e / DW_CFA_GNU_args_size
+ .byte 0x0 / ULEB128 0x0
+ .align 4
+.LEFDE1:
+ .set .LLFDE1,.LEFDE1-.LSFDE1 / FDE Length Symbol
+
+ The immediate issue we can address in the assembler is the
+ DW_CFA_advance_loc4 followed by a four byte value. The value is
+ the difference of two addresses in the function. Since gcc does
+ not know this value, it always uses four bytes. We will know the
+ value at the end of assembly, so we can do better. */
+
+static int eh_frame_code_alignment PARAMS ((void));
+
+/* Get the code alignment factor from the CIE. */
+
+static int
+eh_frame_code_alignment ()
+{
+ static int code_alignment;
+ segT current_seg;
+ subsegT current_subseg;
+ fragS *f;
+ fixS *fix;
+ int offset;
+ char augmentation[10];
+ int iaug;
+
+ if (code_alignment != 0)
+ return code_alignment;
+
+ /* We should find the CIE at the start of the .eh_frame section. */
+
+ current_seg = now_seg;
+ current_subseg = now_subseg;
+ subseg_new (".eh_frame", 0);
+#if defined (BFD_ASSEMBLER) || defined (MANY_SEGMENTS)
+ f = seg_info (now_seg)->frchainP->frch_root;
+#else
+ f = frchain_now->frch_root;
+#endif
+#ifdef BFD_ASSEMBLER
+ fix = seg_info (now_seg)->frchainP->fix_root;
+#else
+ fix = *seg_fix_rootP;
+#endif
+ subseg_set (current_seg, current_subseg);
+
+ /* Look through the frags of the section to find the code alignment. */
+
+ /* First make sure that the CIE Identifier Tag is 0. */
+
+ offset = 4;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL
+ || f->fr_fix - offset < 4
+ || f->fr_literal[offset] != 0
+ || f->fr_literal[offset + 1] != 0
+ || f->fr_literal[offset + 2] != 0
+ || f->fr_literal[offset + 3] != 0)
+ {
+ code_alignment = -1;
+ return -1;
+ }
+
+ /* Next make sure the CIE version number is 1. */
+
+ offset += 4;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL
+ || f->fr_fix - offset < 1
+ || f->fr_literal[offset] != 1)
+ {
+ code_alignment = -1;
+ return -1;
+ }
+
+ /* Skip the augmentation (a null terminated string). */
+
+ iaug = 0;
+ ++offset;
+ while (1)
+ {
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL)
+ {
+ code_alignment = -1;
+ return -1;
+ }
+ while (offset < f->fr_fix && f->fr_literal[offset] != '\0')
+ {
+ if ((size_t) iaug < (sizeof augmentation) - 1)
+ {
+ augmentation[iaug] = f->fr_literal[offset];
+ ++iaug;
+ }
+ ++offset;
+ }
+ if (offset < f->fr_fix)
+ break;
+ }
+ ++offset;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL)
+ {
+ code_alignment = -1;
+ return -1;
+ }
+
+ augmentation[iaug] = '\0';
+ if (augmentation[0] == '\0')
+ {
+ /* No augmentation. */
+ }
+ else if (strcmp (augmentation, "eh") == 0)
+ {
+ /* We have to skip a pointer. Unfortunately, we don't know how
+ large it is. We find out by looking for a matching fixup. */
+ while (fix != NULL
+ && (fix->fx_frag != f || fix->fx_where != offset))
+ fix = fix->fx_next;
+ if (fix == NULL)
+ offset += 4;
+ else
+ offset += fix->fx_size;
+ while (f != NULL && offset >= f->fr_fix)
+ {
+ offset -= f->fr_fix;
+ f = f->fr_next;
+ }
+ if (f == NULL)
+ {
+ code_alignment = -1;
+ return -1;
+ }
+ }
+ else
+ {
+ code_alignment = -1;
+ return -1;
+ }
+
+ /* We're now at the code alignment factor, which is a ULEB128. If
+ it isn't a single byte, forget it. */
+
+ code_alignment = f->fr_literal[offset] & 0xff;
+ if ((code_alignment & 0x80) != 0 || code_alignment == 0)
+ {
+ code_alignment = -1;
+ return -1;
+ }
+
+ return code_alignment;
+}
+
+/* This function is called from emit_expr. It looks for cases which
+ we can optimize.
+
+ Rather than try to parse all this information as we read it, we
+ look for a single byte DW_CFA_advance_loc4 followed by a 4 byte
+ difference. We turn that into a rs_cfa_advance frag, and handle
+ those frags at the end of the assembly. If the gcc output changes
+ somewhat, this optimization may stop working.
+
+ This function returns non-zero if it handled the expression and
+ emit_expr should not do anything, or zero otherwise. It can also
+ change *EXP and *PNBYTES. */
+
+int
+check_eh_frame (exp, pnbytes)
+ expressionS *exp;
+ unsigned int *pnbytes;
+{
+ static int saw_size;
+ static symbolS *size_end_sym;
+ static int saw_advance_loc4;
+ static fragS *loc4_frag;
+ static int loc4_fix;
+
+ if (saw_size
+ && S_IS_DEFINED (size_end_sym))
+ {
+ /* We have come to the end of the CIE or FDE. See below where
+ we set saw_size. We must check this first because we may now
+ be looking at the next size. */
+ saw_size = 0;
+ saw_advance_loc4 = 0;
+ }
+
+ if (flag_traditional_format)
+ {
+ /* Don't optimize. */
+ }
+ else if (strcmp (segment_name (now_seg), ".eh_frame") != 0)
+ {
+ saw_size = 0;
+ saw_advance_loc4 = 0;
+ }
+ else if (! saw_size
+ && *pnbytes == 4)
+ {
+ /* This might be the size of the CIE or FDE. We want to know
+ the size so that we don't accidentally optimize across an FDE
+ boundary. We recognize the size in one of two forms: a
+ symbol which will later be defined as a difference, or a
+ subtraction of two symbols. Either way, we can tell when we
+ are at the end of the FDE because the symbol becomes defined
+ (in the case of a subtraction, the end symbol, from which the
+ start symbol is being subtracted). Other ways of describing
+ the size will not be optimized. */
+ if ((exp->X_op == O_symbol || exp->X_op == O_subtract)
+ && ! S_IS_DEFINED (exp->X_add_symbol))
+ {
+ saw_size = 1;
+ size_end_sym = exp->X_add_symbol;
+ }
+ }
+ else if (saw_size
+ && *pnbytes == 1
+ && exp->X_op == O_constant
+ && exp->X_add_number == DW_CFA_advance_loc4)
+ {
+ /* This might be a DW_CFA_advance_loc4. Record the frag and the
+ position within the frag, so that we can change it later. */
+ saw_advance_loc4 = 1;
+ frag_grow (1);
+ loc4_frag = frag_now;
+ loc4_fix = frag_now_fix ();
+ }
+ else if (saw_advance_loc4
+ && *pnbytes == 4
+ && exp->X_op == O_constant)
+ {
+ int ca;
+
+ /* This is a case which we can optimize. The two symbols being
+ subtracted were in the same frag and the expression was
+ reduced to a constant. We can do the optimization entirely
+ in this function. */
+
+ saw_advance_loc4 = 0;
+
+ ca = eh_frame_code_alignment ();
+ if (ca < 0)
+ {
+ /* Don't optimize. */
+ }
+ else if (exp->X_add_number % ca == 0
+ && exp->X_add_number / ca < 0x40)
+ {
+ loc4_frag->fr_literal[loc4_fix]
+ = DW_CFA_advance_loc | (exp->X_add_number / ca);
+ /* No more bytes needed. */
+ return 1;
+ }
+ else if (exp->X_add_number < 0x100)
+ {
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
+ *pnbytes = 1;
+ }
+ else if (exp->X_add_number < 0x10000)
+ {
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
+ *pnbytes = 2;
+ }
+ }
+ else if (saw_advance_loc4
+ && *pnbytes == 4
+ && exp->X_op == O_subtract)
+ {
+
+ /* This is a case we can optimize. The expression was not
+ reduced, so we can not finish the optimization until the end
+ of the assembly. We set up a variant frag which we handle
+ later. */
+
+ saw_advance_loc4 = 0;
+
+ frag_var (rs_cfa, 4, 0, 0, make_expr_symbol (exp),
+ loc4_fix, (char *) loc4_frag);
+
+ return 1;
+ }
+ else
+ saw_advance_loc4 = 0;
+
+ return 0;
+}
+
+/* The function estimates the size of a rs_cfa variant frag based on
+ the current values of the symbols. It is called before the
+ relaxation loop. We set fr_subtype to the expected length. */
+
+int
+eh_frame_estimate_size_before_relax (frag)
+ fragS *frag;
+{
+ int ca;
+ offsetT diff;
+ int ret;
+
+ ca = eh_frame_code_alignment ();
+ diff = resolve_symbol_value (frag->fr_symbol, 0);
+
+ if (ca < 0)
+ ret = 4;
+ else if (diff % ca == 0 && diff / ca < 0x40)
+ ret = 0;
+ else if (diff < 0x100)
+ ret = 1;
+ else if (diff < 0x10000)
+ ret = 2;
+ else
+ ret = 4;
+
+ frag->fr_subtype = ret;
+
+ return ret;
+}
+
+/* This function relaxes a rs_cfa variant frag based on the current
+ values of the symbols. fr_subtype is the current length of the
+ frag. This returns the change in frag length. */
+
+int
+eh_frame_relax_frag (frag)
+ fragS *frag;
+{
+ int oldsize, newsize;
+
+ oldsize = frag->fr_subtype;
+ newsize = eh_frame_estimate_size_before_relax (frag);
+ return newsize - oldsize;
+}
+
+/* This function converts a rs_cfa variant frag into a normal fill
+ frag. This is called after all relaxation has been done.
+ fr_subtype will be the desired length of the frag. */
+
+void
+eh_frame_convert_frag (frag)
+ fragS *frag;
+{
+ offsetT diff;
+ fragS *loc4_frag;
+ int loc4_fix;
+
+ loc4_frag = (fragS *) frag->fr_opcode;
+ loc4_fix = (int) frag->fr_offset;
+
+ diff = resolve_symbol_value (frag->fr_symbol, 1);
+
+ if (frag->fr_subtype == 0)
+ {
+ int ca;
+
+ ca = eh_frame_code_alignment ();
+ assert (ca > 0 && diff % ca == 0 && diff / ca < 0x40);
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | (diff / ca);
+ }
+ else if (frag->fr_subtype == 1)
+ {
+ assert (diff < 0x100);
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1;
+ frag->fr_literal[frag->fr_fix] = diff;
+ }
+ else if (frag->fr_subtype == 2)
+ {
+ assert (diff < 0x10000);
+ loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2;
+ md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2);
+ }
+ else
+ md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4);
+
+ frag->fr_fix += frag->fr_subtype;
+ frag->fr_type = rs_fill;
+ frag->fr_offset = 0;
+}
diff --git a/gas/emul-target.h b/gas/emul-target.h
new file mode 100644
index 00000000000..3704050e914
--- /dev/null
+++ b/gas/emul-target.h
@@ -0,0 +1,43 @@
+#ifndef emul_init
+#define emul_init common_emul_init
+#endif
+
+#ifndef emul_bfd_name
+#define emul_bfd_name default_emul_bfd_name
+#endif
+
+#ifndef emul_local_labels_fb
+#define emul_local_labels_fb 0
+#endif
+
+#ifndef emul_local_labels_dollar
+#define emul_local_labels_dollar 0
+#endif
+
+#ifndef emul_leading_underscore
+#define emul_leading_underscore 2
+#endif
+
+#ifndef emul_strip_underscore
+#define emul_strip_underscore 0
+#endif
+
+#ifndef emul_default_endian
+#define emul_default_endian 2
+#endif
+
+#ifndef emul_fake_label_name
+#define emul_fake_label_name 0
+#endif
+
+struct emulation emul_struct_name = {
+ 0,
+ emul_name,
+ emul_init,
+ emul_bfd_name,
+ emul_local_labels_fb, emul_local_labels_dollar,
+ emul_leading_underscore, emul_strip_underscore,
+ emul_default_endian,
+ emul_fake_label_name,
+ emul_format,
+};
diff --git a/gas/emul.h b/gas/emul.h
new file mode 100644
index 00000000000..97c46d8b2a5
--- /dev/null
+++ b/gas/emul.h
@@ -0,0 +1,23 @@
+#ifndef EMUL_DEFS
+#define EMUL_DEFS
+
+struct emulation {
+ void (*match) PARAMS ((const char *));
+ const char *name;
+ void (*init) PARAMS ((void));
+ const char *(*bfd_name) PARAMS ((void));
+ unsigned local_labels_fb : 1;
+ unsigned local_labels_dollar : 1;
+ unsigned leading_underscore : 2;
+ unsigned strip_underscore : 1;
+ unsigned default_endian : 2;
+ const char *fake_label_name;
+ const struct format_ops *format;
+};
+
+COMMON struct emulation *this_emulation;
+
+extern const char *default_emul_bfd_name PARAMS ((void));
+extern void common_emul_init PARAMS ((void));
+
+#endif
diff --git a/gas/expr.c b/gas/expr.c
new file mode 100644
index 00000000000..d5d55fd3e6e
--- /dev/null
+++ b/gas/expr.c
@@ -0,0 +1,1859 @@
+/* expr.c -operands, expressions-
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * This is really a branch office of as-read.c. I split it out to clearly
+ * distinguish the world of expressions from the world of statements.
+ * (It also gives smaller files to re-compile.)
+ * Here, "operand"s are of expressions, not instructions.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#include "as.h"
+#include "obstack.h"
+
+static void floating_constant PARAMS ((expressionS * expressionP));
+static void integer_constant PARAMS ((int radix, expressionS * expressionP));
+static void mri_char_constant PARAMS ((expressionS *));
+static void current_location PARAMS ((expressionS *));
+static void clean_up_expression PARAMS ((expressionS * expressionP));
+static segT operand PARAMS ((expressionS *));
+static operatorT operator PARAMS ((void));
+
+extern const char EXP_CHARS[], FLT_CHARS[];
+
+/* We keep a mapping of expression symbols to file positions, so that
+ we can provide better error messages. */
+
+struct expr_symbol_line
+{
+ struct expr_symbol_line *next;
+ symbolS *sym;
+ char *file;
+ unsigned int line;
+};
+
+static struct expr_symbol_line *expr_symbol_lines;
+
+/* Build a dummy symbol to hold a complex expression. This is how we
+ build expressions up out of other expressions. The symbol is put
+ into the fake section expr_section. */
+
+symbolS *
+make_expr_symbol (expressionP)
+ expressionS *expressionP;
+{
+ expressionS zero;
+ const char *fake;
+ symbolS *symbolP;
+ struct expr_symbol_line *n;
+
+ if (expressionP->X_op == O_symbol
+ && expressionP->X_add_number == 0)
+ return expressionP->X_add_symbol;
+
+ if (expressionP->X_op == O_big)
+ {
+ /* This won't work, because the actual value is stored in
+ generic_floating_point_number or generic_bignum, and we are
+ going to lose it if we haven't already. */
+ if (expressionP->X_add_number > 0)
+ as_bad (_("bignum invalid; zero assumed"));
+ else
+ as_bad (_("floating point number invalid; zero assumed"));
+ zero.X_op = O_constant;
+ zero.X_add_number = 0;
+ zero.X_unsigned = 0;
+ clean_up_expression (&zero);
+ expressionP = &zero;
+ }
+
+ fake = FAKE_LABEL_NAME;
+
+ /* Putting constant symbols in absolute_section rather than
+ expr_section is convenient for the old a.out code, for which
+ S_GET_SEGMENT does not always retrieve the value put in by
+ S_SET_SEGMENT. */
+ symbolP = symbol_create (fake,
+ (expressionP->X_op == O_constant
+ ? absolute_section
+ : expr_section),
+ 0, &zero_address_frag);
+ symbolP->sy_value = *expressionP;
+
+ if (expressionP->X_op == O_constant)
+ resolve_symbol_value (symbolP, 1);
+
+ n = (struct expr_symbol_line *) xmalloc (sizeof *n);
+ n->sym = symbolP;
+ as_where (&n->file, &n->line);
+ n->next = expr_symbol_lines;
+ expr_symbol_lines = n;
+
+ return symbolP;
+}
+
+/* Return the file and line number for an expr symbol. Return
+ non-zero if something was found, 0 if no information is known for
+ the symbol. */
+
+int
+expr_symbol_where (sym, pfile, pline)
+ symbolS *sym;
+ char **pfile;
+ unsigned int *pline;
+{
+ register struct expr_symbol_line *l;
+
+ for (l = expr_symbol_lines; l != NULL; l = l->next)
+ {
+ if (l->sym == sym)
+ {
+ *pfile = l->file;
+ *pline = l->line;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Utilities for building expressions.
+ Since complex expressions are recorded as symbols for use in other
+ expressions these return a symbolS * and not an expressionS *.
+ These explicitly do not take an "add_number" argument. */
+/* ??? For completeness' sake one might want expr_build_symbol.
+ It would just return its argument. */
+
+/* Build an expression for an unsigned constant.
+ The corresponding one for signed constants is missing because
+ there's currently no need for it. One could add an unsigned_p flag
+ but that seems more clumsy. */
+
+symbolS *
+expr_build_uconstant (value)
+ offsetT value;
+{
+ expressionS e;
+
+ e.X_op = O_constant;
+ e.X_add_number = value;
+ e.X_unsigned = 1;
+ return make_expr_symbol (&e);
+}
+
+/* Build an expression for OP s1. */
+
+symbolS *
+expr_build_unary (op, s1)
+ operatorT op;
+ symbolS *s1;
+{
+ expressionS e;
+
+ e.X_op = op;
+ e.X_add_symbol = s1;
+ e.X_add_number = 0;
+ return make_expr_symbol (&e);
+}
+
+/* Build an expression for s1 OP s2. */
+
+symbolS *
+expr_build_binary (op, s1, s2)
+ operatorT op;
+ symbolS *s1;
+ symbolS *s2;
+{
+ expressionS e;
+
+ e.X_op = op;
+ e.X_add_symbol = s1;
+ e.X_op_symbol = s2;
+ e.X_add_number = 0;
+ return make_expr_symbol (&e);
+}
+
+/* Build an expression for the current location ('.'). */
+
+symbolS *
+expr_build_dot ()
+{
+ expressionS e;
+
+ current_location (&e);
+ return make_expr_symbol (&e);
+}
+
+/*
+ * Build any floating-point literal here.
+ * Also build any bignum literal here.
+ */
+
+/* Seems atof_machine can backscan through generic_bignum and hit whatever
+ happens to be loaded before it in memory. And its way too complicated
+ for me to fix right. Thus a hack. JF: Just make generic_bignum bigger,
+ and never write into the early words, thus they'll always be zero.
+ I hate Dean's floating-point code. Bleh. */
+LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
+FLONUM_TYPE generic_floating_point_number =
+{
+ &generic_bignum[6], /* low (JF: Was 0) */
+ &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */
+ 0, /* leader */
+ 0, /* exponent */
+ 0 /* sign */
+};
+/* If nonzero, we've been asked to assemble nan, +inf or -inf */
+int generic_floating_point_magic;
+
+static void
+floating_constant (expressionP)
+ expressionS *expressionP;
+{
+ /* input_line_pointer->*/
+ /* floating-point constant. */
+ int error_code;
+
+ error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
+ &generic_floating_point_number);
+
+ if (error_code)
+ {
+ if (error_code == ERROR_EXPONENT_OVERFLOW)
+ {
+ as_bad (_("bad floating-point constant: exponent overflow, probably assembling junk"));
+ }
+ else
+ {
+ as_bad (_("bad floating-point constant: unknown error code=%d."), error_code);
+ }
+ }
+ expressionP->X_op = O_big;
+ /* input_line_pointer->just after constant, */
+ /* which may point to whitespace. */
+ expressionP->X_add_number = -1;
+}
+
+static valueT
+generic_bignum_to_int32 ()
+{
+ valueT number =
+ ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
+ | (generic_bignum[0] & LITTLENUM_MASK);
+ number &= 0xffffffff;
+ return number;
+}
+
+#ifdef BFD64
+static valueT
+generic_bignum_to_int64 ()
+{
+ valueT number =
+ ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((valueT) generic_bignum[2] & LITTLENUM_MASK))
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((valueT) generic_bignum[1] & LITTLENUM_MASK))
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
+ return number;
+}
+#endif
+
+static void
+integer_constant (radix, expressionP)
+ int radix;
+ expressionS *expressionP;
+{
+ char *start; /* start of number. */
+ char *suffix = NULL;
+ char c;
+ valueT number; /* offset or (absolute) value */
+ short int digit; /* value of next digit in current radix */
+ short int maxdig = 0;/* highest permitted digit value. */
+ int too_many_digits = 0; /* if we see >= this number of */
+ char *name; /* points to name of symbol */
+ symbolS *symbolP; /* points to symbol */
+
+ int small; /* true if fits in 32 bits. */
+
+ /* May be bignum, or may fit in 32 bits. */
+ /* Most numbers fit into 32 bits, and we want this case to be fast.
+ so we pretend it will fit into 32 bits. If, after making up a 32
+ bit number, we realise that we have scanned more digits than
+ comfortably fit into 32 bits, we re-scan the digits coding them
+ into a bignum. For decimal and octal numbers we are
+ conservative: Some numbers may be assumed bignums when in fact
+ they do fit into 32 bits. Numbers of any radix can have excess
+ leading zeros: We strive to recognise this and cast them back
+ into 32 bits. We must check that the bignum really is more than
+ 32 bits, and change it back to a 32-bit number if it fits. The
+ number we are looking for is expected to be positive, but if it
+ fits into 32 bits as an unsigned number, we let it be a 32-bit
+ number. The cavalier approach is for speed in ordinary cases. */
+ /* This has been extended for 64 bits. We blindly assume that if
+ you're compiling in 64-bit mode, the target is a 64-bit machine.
+ This should be cleaned up. */
+
+#ifdef BFD64
+#define valuesize 64
+#else /* includes non-bfd case, mostly */
+#define valuesize 32
+#endif
+
+ if (flag_m68k_mri && radix == 0)
+ {
+ int flt = 0;
+
+ /* In MRI mode, the number may have a suffix indicating the
+ radix. For that matter, it might actually be a floating
+ point constant. */
+ for (suffix = input_line_pointer;
+ isalnum ((unsigned char) *suffix);
+ suffix++)
+ {
+ if (*suffix == 'e' || *suffix == 'E')
+ flt = 1;
+ }
+
+ if (suffix == input_line_pointer)
+ {
+ radix = 10;
+ suffix = NULL;
+ }
+ else
+ {
+ c = *--suffix;
+ if (islower ((unsigned char) c))
+ c = toupper (c);
+ if (c == 'B')
+ radix = 2;
+ else if (c == 'D')
+ radix = 10;
+ else if (c == 'O' || c == 'Q')
+ radix = 8;
+ else if (c == 'H')
+ radix = 16;
+ else if (suffix[1] == '.' || c == 'E' || flt)
+ {
+ floating_constant (expressionP);
+ return;
+ }
+ else
+ {
+ radix = 10;
+ suffix = NULL;
+ }
+ }
+ }
+
+ switch (radix)
+ {
+ case 2:
+ maxdig = 2;
+ too_many_digits = valuesize + 1;
+ break;
+ case 8:
+ maxdig = radix = 8;
+ too_many_digits = (valuesize + 2) / 3 + 1;
+ break;
+ case 16:
+ maxdig = radix = 16;
+ too_many_digits = (valuesize + 3) / 4 + 1;
+ break;
+ case 10:
+ maxdig = radix = 10;
+ too_many_digits = (valuesize + 12) / 4; /* very rough */
+ }
+#undef valuesize
+ start = input_line_pointer;
+ c = *input_line_pointer++;
+ for (number = 0;
+ (digit = hex_value (c)) < maxdig;
+ c = *input_line_pointer++)
+ {
+ number = number * radix + digit;
+ }
+ /* c contains character after number. */
+ /* input_line_pointer->char after c. */
+ small = (input_line_pointer - start - 1) < too_many_digits;
+
+ if (radix == 16 && c == '_')
+ {
+ /* This is literal of the form 0x333_0_12345678_1.
+ This example is equivalent to 0x00000333000000001234567800000001. */
+
+ int num_little_digits = 0;
+ int i;
+ input_line_pointer = start; /*->1st digit. */
+
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+
+ for (c = '_'; c == '_'; num_little_digits+=2)
+ {
+
+ /* Convert one 64-bit word. */
+ int ndigit = 0;
+ number = 0;
+ for (c = *input_line_pointer++;
+ (digit = hex_value (c)) < maxdig;
+ c = *(input_line_pointer++))
+ {
+ number = number * radix + digit;
+ ndigit++;
+ }
+
+ /* Check for 8 digit per word max. */
+ if (ndigit > 8)
+ as_bad (_("A bignum with underscores may not have more than 8 hex digits in any word."));
+
+ /* Add this chunk to the bignum. Shift things down 2 little digits.*/
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+ for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1); i >= 2; i--)
+ generic_bignum[i] = generic_bignum[i-2];
+
+ /* Add the new digits as the least significant new ones. */
+ generic_bignum[0] = number & 0xffffffff;
+ generic_bignum[1] = number >> 16;
+ }
+
+ /* Again, c is char after number, input_line_pointer->after c. */
+
+ if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1)
+ num_little_digits = SIZE_OF_LARGE_NUMBER - 1;
+
+ assert (num_little_digits >= 4);
+
+ if (num_little_digits != 8)
+ as_bad (_("A bignum with underscores must have exactly 4 words."));
+
+ /* We might have some leading zeros. These can be trimmed to give
+ * us a change to fit this constant into a small number.
+ */
+ while (generic_bignum[num_little_digits-1] == 0 && num_little_digits > 1)
+ num_little_digits--;
+
+ if (num_little_digits <= 2)
+ {
+ /* will fit into 32 bits. */
+ number = generic_bignum_to_int32 ();
+ small = 1;
+ }
+#ifdef BFD64
+ else if (num_little_digits <= 4)
+ {
+ /* Will fit into 64 bits. */
+ number = generic_bignum_to_int64 ();
+ small = 1;
+ }
+#endif
+ else
+ {
+ small = 0;
+ number = num_little_digits; /* number of littlenums in the bignum. */
+ }
+ }
+ else if (!small)
+ {
+ /*
+ * we saw a lot of digits. manufacture a bignum the hard way.
+ */
+ LITTLENUM_TYPE *leader; /*->high order littlenum of the bignum. */
+ LITTLENUM_TYPE *pointer; /*->littlenum we are frobbing now. */
+ long carry;
+
+ leader = generic_bignum;
+ generic_bignum[0] = 0;
+ generic_bignum[1] = 0;
+ generic_bignum[2] = 0;
+ generic_bignum[3] = 0;
+ input_line_pointer = start; /*->1st digit. */
+ c = *input_line_pointer++;
+ for (;
+ (carry = hex_value (c)) < maxdig;
+ c = *input_line_pointer++)
+ {
+ for (pointer = generic_bignum;
+ pointer <= leader;
+ pointer++)
+ {
+ long work;
+
+ work = carry + radix * *pointer;
+ *pointer = work & LITTLENUM_MASK;
+ carry = work >> LITTLENUM_NUMBER_OF_BITS;
+ }
+ if (carry)
+ {
+ if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
+ {
+ /* room to grow a longer bignum. */
+ *++leader = carry;
+ }
+ }
+ }
+ /* again, c is char after number, */
+ /* input_line_pointer->after c. */
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+ if (leader < generic_bignum + 2)
+ {
+ /* will fit into 32 bits. */
+ number = generic_bignum_to_int32 ();
+ small = 1;
+ }
+#ifdef BFD64
+ else if (leader < generic_bignum + 4)
+ {
+ /* Will fit into 64 bits. */
+ number = generic_bignum_to_int64 ();
+ small = 1;
+ }
+#endif
+ else
+ {
+ number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */
+ }
+ }
+
+ if (flag_m68k_mri && suffix != NULL && input_line_pointer - 1 == suffix)
+ c = *input_line_pointer++;
+
+ if (small)
+ {
+ /*
+ * here with number, in correct radix. c is the next char.
+ * note that unlike un*x, we allow "011f" "0x9f" to
+ * both mean the same as the (conventional) "9f". this is simply easier
+ * than checking for strict canonical form. syntax sux!
+ */
+
+ if (LOCAL_LABELS_FB && c == 'b')
+ {
+ /*
+ * backward ref to local label.
+ * because it is backward, expect it to be defined.
+ */
+ /* Construct a local label. */
+ name = fb_label_name ((int) number, 0);
+
+ /* seen before, or symbol is defined: ok */
+ symbolP = symbol_find (name);
+ if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
+ {
+ /* local labels are never absolute. don't waste time
+ checking absoluteness. */
+ know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ }
+ else
+ {
+ /* either not seen or not defined. */
+ /* @@ Should print out the original string instead of
+ the parsed number. */
+ as_bad (_("backw. ref to unknown label \"%d:\", 0 assumed."),
+ (int) number);
+ expressionP->X_op = O_constant;
+ }
+
+ expressionP->X_add_number = 0;
+ } /* case 'b' */
+ else if (LOCAL_LABELS_FB && c == 'f')
+ {
+ /*
+ * forward reference. expect symbol to be undefined or
+ * unknown. undefined: seen it before. unknown: never seen
+ * it before.
+ * construct a local label name, then an undefined symbol.
+ * don't create a xseg frag for it: caller may do that.
+ * just return it as never seen before.
+ */
+ name = fb_label_name ((int) number, 1);
+ symbolP = symbol_find_or_make (name);
+ /* we have no need to check symbol properties. */
+#ifndef many_segments
+ /* since "know" puts its arg into a "string", we
+ can't have newlines in the argument. */
+ know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
+#endif
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ } /* case 'f' */
+ else if (LOCAL_LABELS_DOLLAR && c == '$')
+ {
+ /* If the dollar label is *currently* defined, then this is just
+ another reference to it. If it is not *currently* defined,
+ then this is a fresh instantiation of that number, so create
+ it. */
+
+ if (dollar_label_defined ((long) number))
+ {
+ name = dollar_label_name ((long) number, 0);
+ symbolP = symbol_find (name);
+ know (symbolP != NULL);
+ }
+ else
+ {
+ name = dollar_label_name ((long) number, 1);
+ symbolP = symbol_find_or_make (name);
+ }
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ } /* case '$' */
+ else
+ {
+ expressionP->X_op = O_constant;
+#ifdef TARGET_WORD_SIZE
+ /* Sign extend NUMBER. */
+ number |= (-(number >> (TARGET_WORD_SIZE - 1))) << (TARGET_WORD_SIZE - 1);
+#endif
+ expressionP->X_add_number = number;
+ input_line_pointer--; /* restore following character. */
+ } /* really just a number */
+ }
+ else
+ {
+ /* not a small number */
+ expressionP->X_op = O_big;
+ expressionP->X_add_number = number; /* number of littlenums */
+ input_line_pointer--; /*->char following number. */
+ }
+}
+
+/* Parse an MRI multi character constant. */
+
+static void
+mri_char_constant (expressionP)
+ expressionS *expressionP;
+{
+ int i;
+
+ if (*input_line_pointer == '\''
+ && input_line_pointer[1] != '\'')
+ {
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = 0;
+ return;
+ }
+
+ /* In order to get the correct byte ordering, we must build the
+ number in reverse. */
+ for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--)
+ {
+ int j;
+
+ generic_bignum[i] = 0;
+ for (j = 0; j < CHARS_PER_LITTLENUM; j++)
+ {
+ if (*input_line_pointer == '\'')
+ {
+ if (input_line_pointer[1] != '\'')
+ break;
+ ++input_line_pointer;
+ }
+ generic_bignum[i] <<= 8;
+ generic_bignum[i] += *input_line_pointer;
+ ++input_line_pointer;
+ }
+
+ if (i < SIZE_OF_LARGE_NUMBER - 1)
+ {
+ /* If there is more than one littlenum, left justify the
+ last one to make it match the earlier ones. If there is
+ only one, we can just use the value directly. */
+ for (; j < CHARS_PER_LITTLENUM; j++)
+ generic_bignum[i] <<= 8;
+ }
+
+ if (*input_line_pointer == '\''
+ && input_line_pointer[1] != '\'')
+ break;
+ }
+
+ if (i < 0)
+ {
+ as_bad (_("Character constant too large"));
+ i = 0;
+ }
+
+ if (i > 0)
+ {
+ int c;
+ int j;
+
+ c = SIZE_OF_LARGE_NUMBER - i;
+ for (j = 0; j < c; j++)
+ generic_bignum[j] = generic_bignum[i + j];
+ i = c;
+ }
+
+ know (LITTLENUM_NUMBER_OF_BITS == 16);
+ if (i > 2)
+ {
+ expressionP->X_op = O_big;
+ expressionP->X_add_number = i;
+ }
+ else
+ {
+ expressionP->X_op = O_constant;
+ if (i < 2)
+ expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK;
+ else
+ expressionP->X_add_number =
+ (((generic_bignum[1] & LITTLENUM_MASK)
+ << LITTLENUM_NUMBER_OF_BITS)
+ | (generic_bignum[0] & LITTLENUM_MASK));
+ }
+
+ /* Skip the final closing quote. */
+ ++input_line_pointer;
+}
+
+/* Return an expression representing the current location. This
+ handles the magic symbol `.'. */
+
+static void
+current_location (expressionp)
+ expressionS *expressionp;
+{
+ if (now_seg == absolute_section)
+ {
+ expressionp->X_op = O_constant;
+ expressionp->X_add_number = abs_section_offset;
+ }
+ else
+ {
+ symbolS *symbolp;
+
+ symbolp = symbol_new (FAKE_LABEL_NAME, now_seg,
+ (valueT) frag_now_fix (),
+ frag_now);
+ expressionp->X_op = O_symbol;
+ expressionp->X_add_symbol = symbolp;
+ expressionp->X_add_number = 0;
+ }
+}
+
+/*
+ * Summary of operand().
+ *
+ * in: Input_line_pointer points to 1st char of operand, which may
+ * be a space.
+ *
+ * out: A expressionS.
+ * The operand may have been empty: in this case X_op == O_absent.
+ * Input_line_pointer->(next non-blank) char after operand.
+ */
+
+static segT
+operand (expressionP)
+ expressionS *expressionP;
+{
+ char c;
+ symbolS *symbolP; /* points to symbol */
+ char *name; /* points to name of symbol */
+ segT segment;
+
+ /* All integers are regarded as unsigned unless they are negated.
+ This is because the only thing which cares whether a number is
+ unsigned is the code in emit_expr which extends constants into
+ bignums. It should only sign extend negative numbers, so that
+ something like ``.quad 0x80000000'' is not sign extended even
+ though it appears negative if valueT is 32 bits. */
+ expressionP->X_unsigned = 1;
+
+ /* digits, assume it is a bignum. */
+
+ SKIP_WHITESPACE (); /* leading whitespace is part of operand. */
+ c = *input_line_pointer++; /* input_line_pointer->past char in c. */
+
+ switch (c)
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ input_line_pointer--;
+
+ integer_constant (flag_m68k_mri ? 0 : 10, expressionP);
+ break;
+
+ case '0':
+ /* non-decimal radix */
+
+ if (flag_m68k_mri)
+ {
+ char *s;
+
+ /* Check for a hex constant. */
+ for (s = input_line_pointer; hex_p (*s); s++)
+ ;
+ if (*s == 'h' || *s == 'H')
+ {
+ --input_line_pointer;
+ integer_constant (0, expressionP);
+ break;
+ }
+ }
+
+ c = *input_line_pointer;
+ switch (c)
+ {
+ case 'o':
+ case 'O':
+ case 'q':
+ case 'Q':
+ case '8':
+ case '9':
+ if (flag_m68k_mri)
+ {
+ integer_constant (0, expressionP);
+ break;
+ }
+ /* Fall through. */
+ default:
+ default_case:
+ if (c && strchr (FLT_CHARS, c))
+ {
+ input_line_pointer++;
+ floating_constant (expressionP);
+ expressionP->X_add_number =
+ - (isupper ((unsigned char) c) ? tolower (c) : c);
+ }
+ else
+ {
+ /* The string was only zero */
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = 0;
+ }
+
+ break;
+
+ case 'x':
+ case 'X':
+ if (flag_m68k_mri)
+ goto default_case;
+ input_line_pointer++;
+ integer_constant (16, expressionP);
+ break;
+
+ case 'b':
+ if (LOCAL_LABELS_FB && ! flag_m68k_mri)
+ {
+ /* This code used to check for '+' and '-' here, and, in
+ some conditions, fall through to call
+ integer_constant. However, that didn't make sense,
+ as integer_constant only accepts digits. */
+ /* Some of our code elsewhere does permit digits greater
+ than the expected base; for consistency, do the same
+ here. */
+ if (input_line_pointer[1] < '0'
+ || input_line_pointer[1] > '9')
+ {
+ /* Parse this as a back reference to label 0. */
+ input_line_pointer--;
+ integer_constant (10, expressionP);
+ break;
+ }
+ /* Otherwise, parse this as a binary number. */
+ }
+ /* Fall through. */
+ case 'B':
+ input_line_pointer++;
+ if (flag_m68k_mri)
+ goto default_case;
+ integer_constant (2, expressionP);
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ integer_constant (flag_m68k_mri ? 0 : 8, expressionP);
+ break;
+
+ case 'f':
+ if (LOCAL_LABELS_FB)
+ {
+ /* If it says "0f" and it could possibly be a floating point
+ number, make it one. Otherwise, make it a local label,
+ and try to deal with parsing the rest later. */
+ if (!input_line_pointer[1]
+ || (is_end_of_line[0xff & input_line_pointer[1]]))
+ goto is_0f_label;
+ {
+ char *cp = input_line_pointer + 1;
+ int r = atof_generic (&cp, ".", EXP_CHARS,
+ &generic_floating_point_number);
+ switch (r)
+ {
+ case 0:
+ case ERROR_EXPONENT_OVERFLOW:
+ if (*cp == 'f' || *cp == 'b')
+ /* looks like a difference expression */
+ goto is_0f_label;
+ else if (cp == input_line_pointer + 1)
+ /* No characters has been accepted -- looks like
+ end of operand. */
+ goto is_0f_label;
+ else
+ goto is_0f_float;
+ default:
+ as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
+ r);
+ }
+ }
+
+ /* Okay, now we've sorted it out. We resume at one of these
+ two labels, depending on what we've decided we're probably
+ looking at. */
+ is_0f_label:
+ input_line_pointer--;
+ integer_constant (10, expressionP);
+ break;
+
+ is_0f_float:
+ /* fall through */
+ ;
+ }
+
+ case 'd':
+ case 'D':
+ if (flag_m68k_mri)
+ {
+ integer_constant (0, expressionP);
+ break;
+ }
+ /* Fall through. */
+ case 'F':
+ case 'r':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ input_line_pointer++;
+ floating_constant (expressionP);
+ expressionP->X_add_number =
+ - (isupper ((unsigned char) c) ? tolower (c) : c);
+ break;
+
+ case '$':
+ if (LOCAL_LABELS_DOLLAR)
+ {
+ integer_constant (10, expressionP);
+ break;
+ }
+ else
+ goto default_case;
+ }
+
+ break;
+
+ case '(':
+ case '[':
+ /* didn't begin with digit & not a name */
+ segment = expression (expressionP);
+ /* Expression() will pass trailing whitespace */
+ if ((c == '(' && *input_line_pointer++ != ')')
+ || (c == '[' && *input_line_pointer++ != ']'))
+ {
+ as_bad (_("Missing ')' assumed"));
+ input_line_pointer--;
+ }
+ SKIP_WHITESPACE ();
+ /* here with input_line_pointer->char after "(...)" */
+ return segment;
+
+ case 'E':
+ if (! flag_m68k_mri || *input_line_pointer != '\'')
+ goto de_fault;
+ as_bad (_("EBCDIC constants are not supported"));
+ /* Fall through. */
+ case 'A':
+ if (! flag_m68k_mri || *input_line_pointer != '\'')
+ goto de_fault;
+ ++input_line_pointer;
+ /* Fall through. */
+ case '\'':
+ if (! flag_m68k_mri)
+ {
+ /* Warning: to conform to other people's assemblers NO
+ ESCAPEMENT is permitted for a single quote. The next
+ character, parity errors and all, is taken as the value
+ of the operand. VERY KINKY. */
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = *input_line_pointer++;
+ break;
+ }
+
+ mri_char_constant (expressionP);
+ break;
+
+ case '+':
+ (void) operand (expressionP);
+ break;
+
+ case '"':
+ /* Double quote is the bitwise not operator in MRI mode. */
+ if (! flag_m68k_mri)
+ goto de_fault;
+ /* Fall through. */
+ case '~':
+ /* ~ is permitted to start a label on the Delta. */
+ if (is_name_beginner (c))
+ goto isname;
+ case '!':
+ case '-':
+ {
+ operand (expressionP);
+ if (expressionP->X_op == O_constant)
+ {
+ /* input_line_pointer -> char after operand */
+ if (c == '-')
+ {
+ expressionP->X_add_number = - expressionP->X_add_number;
+ /* Notice: '-' may overflow: no warning is given. This is
+ compatible with other people's assemblers. Sigh. */
+ expressionP->X_unsigned = 0;
+ }
+ else if (c == '~' || c == '"')
+ expressionP->X_add_number = ~ expressionP->X_add_number;
+ else
+ expressionP->X_add_number = ! expressionP->X_add_number;
+ }
+ else if (expressionP->X_op != O_illegal
+ && expressionP->X_op != O_absent)
+ {
+ expressionP->X_add_symbol = make_expr_symbol (expressionP);
+ if (c == '-')
+ expressionP->X_op = O_uminus;
+ else if (c == '~' || c == '"')
+ expressionP->X_op = O_bit_not;
+ else
+ expressionP->X_op = O_logical_not;
+ expressionP->X_add_number = 0;
+ }
+ else
+ as_warn (_("Unary operator %c ignored because bad operand follows"),
+ c);
+ }
+ break;
+
+ case '$':
+ /* $ is the program counter when in MRI mode, or when DOLLAR_DOT
+ is defined. */
+#ifndef DOLLAR_DOT
+ if (! flag_m68k_mri)
+ goto de_fault;
+#endif
+ if (flag_m68k_mri && hex_p (*input_line_pointer))
+ {
+ /* In MRI mode, $ is also used as the prefix for a
+ hexadecimal constant. */
+ integer_constant (16, expressionP);
+ break;
+ }
+
+ if (is_part_of_name (*input_line_pointer))
+ goto isname;
+
+ current_location (expressionP);
+ break;
+
+ case '.':
+ if (!is_part_of_name (*input_line_pointer))
+ {
+ current_location (expressionP);
+ break;
+ }
+ else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
+ && ! is_part_of_name (input_line_pointer[8]))
+ || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
+ && ! is_part_of_name (input_line_pointer[7])))
+ {
+ int start;
+
+ start = (input_line_pointer[1] == 't'
+ || input_line_pointer[1] == 'T');
+ input_line_pointer += start ? 8 : 7;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '(')
+ as_bad (_("syntax error in .startof. or .sizeof."));
+ else
+ {
+ char *buf;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ buf = (char *) xmalloc (strlen (name) + 10);
+ if (start)
+ sprintf (buf, ".startof.%s", name);
+ else
+ sprintf (buf, ".sizeof.%s", name);
+ symbolP = symbol_make (buf);
+ free (buf);
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ')')
+ as_bad (_("syntax error in .startof. or .sizeof."));
+ else
+ ++input_line_pointer;
+ }
+ break;
+ }
+ else
+ {
+ goto isname;
+ }
+ case ',':
+ case '\n':
+ case '\0':
+ eol:
+ /* can't imagine any other kind of operand */
+ expressionP->X_op = O_absent;
+ input_line_pointer--;
+ break;
+
+ case '%':
+ if (! flag_m68k_mri)
+ goto de_fault;
+ integer_constant (2, expressionP);
+ break;
+
+ case '@':
+ if (! flag_m68k_mri)
+ goto de_fault;
+ integer_constant (8, expressionP);
+ break;
+
+ case ':':
+ if (! flag_m68k_mri)
+ goto de_fault;
+
+ /* In MRI mode, this is a floating point constant represented
+ using hexadecimal digits. */
+
+ ++input_line_pointer;
+ integer_constant (16, expressionP);
+ break;
+
+ case '*':
+ if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
+ goto de_fault;
+
+ current_location (expressionP);
+ break;
+
+ default:
+ de_fault:
+ if (is_end_of_line[(unsigned char) c])
+ goto eol;
+ if (is_name_beginner (c)) /* here if did not begin with a digit */
+ {
+ /*
+ * Identifier begins here.
+ * This is kludged for speed, so code is repeated.
+ */
+ isname:
+ name = --input_line_pointer;
+ c = get_symbol_end ();
+
+#ifdef md_parse_name
+ /* This is a hook for the backend to parse certain names
+ specially in certain contexts. If a name always has a
+ specific value, it can often be handled by simply
+ entering it in the symbol table. */
+ if (md_parse_name (name, expressionP))
+ {
+ *input_line_pointer = c;
+ break;
+ }
+#endif
+
+#ifdef TC_I960
+ /* The MRI i960 assembler permits
+ lda sizeof code,g13
+ FIXME: This should use md_parse_name. */
+ if (flag_mri
+ && (strcasecmp (name, "sizeof") == 0
+ || strcasecmp (name, "startof") == 0))
+ {
+ int start;
+ char *buf;
+
+ start = (name[1] == 't'
+ || name[1] == 'T');
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ buf = (char *) xmalloc (strlen (name) + 10);
+ if (start)
+ sprintf (buf, ".startof.%s", name);
+ else
+ sprintf (buf, ".sizeof.%s", name);
+ symbolP = symbol_make (buf);
+ free (buf);
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+
+ break;
+ }
+#endif
+
+ symbolP = symbol_find_or_make (name);
+
+ /* If we have an absolute symbol or a reg, then we know its
+ value now. */
+ segment = S_GET_SEGMENT (symbolP);
+ if (segment == absolute_section)
+ {
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = S_GET_VALUE (symbolP);
+ }
+ else if (segment == reg_section)
+ {
+ expressionP->X_op = O_register;
+ expressionP->X_add_number = S_GET_VALUE (symbolP);
+ }
+ else
+ {
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ }
+ *input_line_pointer = c;
+ }
+ else
+ {
+ /* Let the target try to parse it. Success is indicated by changing
+ the X_op field to something other than O_absent and pointing
+ input_line_pointer passed the expression. If it can't parse the
+ expression, X_op and input_line_pointer should be unchanged. */
+ expressionP->X_op = O_absent;
+ --input_line_pointer;
+ md_operand (expressionP);
+ if (expressionP->X_op == O_absent)
+ {
+ ++input_line_pointer;
+ as_bad (_("Bad expression"));
+ expressionP->X_op = O_constant;
+ expressionP->X_add_number = 0;
+ }
+ }
+ break;
+ }
+
+ /*
+ * It is more 'efficient' to clean up the expressionS when they are created.
+ * Doing it here saves lines of code.
+ */
+ clean_up_expression (expressionP);
+ SKIP_WHITESPACE (); /*->1st char after operand. */
+ know (*input_line_pointer != ' ');
+
+ /* The PA port needs this information. */
+ if (expressionP->X_add_symbol)
+ expressionP->X_add_symbol->sy_used = 1;
+
+ switch (expressionP->X_op)
+ {
+ default:
+ return absolute_section;
+ case O_symbol:
+ return S_GET_SEGMENT (expressionP->X_add_symbol);
+ case O_register:
+ return reg_section;
+ }
+} /* operand() */
+
+/* Internal. Simplify a struct expression for use by expr() */
+
+/*
+ * In: address of a expressionS.
+ * The X_op field of the expressionS may only take certain values.
+ * Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
+ * Out: expressionS may have been modified:
+ * 'foo-foo' symbol references cancelled to 0,
+ * which changes X_op from O_subtract to O_constant.
+ * Unused fields zeroed to help expr().
+ */
+
+static void
+clean_up_expression (expressionP)
+ expressionS *expressionP;
+{
+ switch (expressionP->X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ expressionP->X_add_number = 0;
+ /* Fall through. */
+ case O_big:
+ case O_constant:
+ case O_register:
+ expressionP->X_add_symbol = NULL;
+ /* Fall through. */
+ case O_symbol:
+ case O_uminus:
+ case O_bit_not:
+ expressionP->X_op_symbol = NULL;
+ break;
+ case O_subtract:
+ if (expressionP->X_op_symbol == expressionP->X_add_symbol
+ || ((expressionP->X_op_symbol->sy_frag
+ == expressionP->X_add_symbol->sy_frag)
+ && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol))
+ && (S_GET_VALUE (expressionP->X_op_symbol)
+ == S_GET_VALUE (expressionP->X_add_symbol))))
+ {
+ addressT diff = (S_GET_VALUE (expressionP->X_add_symbol)
+ - S_GET_VALUE (expressionP->X_op_symbol));
+
+ expressionP->X_op = O_constant;
+ expressionP->X_add_symbol = NULL;
+ expressionP->X_op_symbol = NULL;
+ expressionP->X_add_number += diff;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/* Expression parser. */
+
+/*
+ * We allow an empty expression, and just assume (absolute,0) silently.
+ * Unary operators and parenthetical expressions are treated as operands.
+ * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
+ *
+ * We used to do a aho/ullman shift-reduce parser, but the logic got so
+ * warped that I flushed it and wrote a recursive-descent parser instead.
+ * Now things are stable, would anybody like to write a fast parser?
+ * Most expressions are either register (which does not even reach here)
+ * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
+ * So I guess it doesn't really matter how inefficient more complex expressions
+ * are parsed.
+ *
+ * After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
+ * Also, we have consumed any leading or trailing spaces (operand does that)
+ * and done all intervening operators.
+ *
+ * This returns the segment of the result, which will be
+ * absolute_section or the segment of a symbol.
+ */
+
+#undef __
+#define __ O_illegal
+
+static const operatorT op_encoding[256] =
+{ /* maps ASCII->operators */
+
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+
+ __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
+ __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, O_lt, __, O_gt, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, O_bit_exclusive_or, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __,
+ __, __, __, __, O_bit_inclusive_or, __, __, __,
+
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
+};
+
+
+/*
+ * Rank Examples
+ * 0 operand, (expression)
+ * 1 ||
+ * 2 &&
+ * 3 = <> < <= >= >
+ * 4 + -
+ * 5 used for * / % in MRI mode
+ * 6 & ^ ! |
+ * 7 * / % << >>
+ * 8 unary - unary ~
+ */
+static operator_rankT op_rank[] =
+{
+ 0, /* O_illegal */
+ 0, /* O_absent */
+ 0, /* O_constant */
+ 0, /* O_symbol */
+ 0, /* O_symbol_rva */
+ 0, /* O_register */
+ 0, /* O_bit */
+ 8, /* O_uminus */
+ 8, /* O_bit_not */
+ 8, /* O_logical_not */
+ 7, /* O_multiply */
+ 7, /* O_divide */
+ 7, /* O_modulus */
+ 7, /* O_left_shift */
+ 7, /* O_right_shift */
+ 6, /* O_bit_inclusive_or */
+ 6, /* O_bit_or_not */
+ 6, /* O_bit_exclusive_or */
+ 6, /* O_bit_and */
+ 4, /* O_add */
+ 4, /* O_subtract */
+ 3, /* O_eq */
+ 3, /* O_ne */
+ 3, /* O_lt */
+ 3, /* O_le */
+ 3, /* O_ge */
+ 3, /* O_gt */
+ 2, /* O_logical_and */
+ 1 /* O_logical_or */
+};
+
+/* Unfortunately, in MRI mode for the m68k, multiplication and
+ division have lower precedence than the bit wise operators. This
+ function sets the operator precedences correctly for the current
+ mode. Also, MRI uses a different bit_not operator, and this fixes
+ that as well. */
+
+#define STANDARD_MUL_PRECEDENCE (7)
+#define MRI_MUL_PRECEDENCE (5)
+
+void
+expr_set_precedence ()
+{
+ if (flag_m68k_mri)
+ {
+ op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
+ op_rank[O_divide] = MRI_MUL_PRECEDENCE;
+ op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
+ }
+ else
+ {
+ op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
+ op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
+ op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
+ }
+}
+
+/* Initialize the expression parser. */
+
+void
+expr_begin ()
+{
+ expr_set_precedence ();
+
+ /* Verify that X_op field is wide enough. */
+ {
+ expressionS e;
+ e.X_op = O_max;
+ assert (e.X_op == O_max);
+ }
+}
+
+/* Return the encoding for the operator at INPUT_LINE_POINTER.
+ Advance INPUT_LINE_POINTER to the last character in the operator
+ (i.e., don't change it for a single character operator). */
+
+static inline operatorT
+operator ()
+{
+ int c;
+ operatorT ret;
+
+ c = *input_line_pointer & 0xff;
+
+ switch (c)
+ {
+ default:
+ return op_encoding[c];
+
+ case '<':
+ switch (input_line_pointer[1])
+ {
+ default:
+ return op_encoding[c];
+ case '<':
+ ret = O_left_shift;
+ break;
+ case '>':
+ ret = O_ne;
+ break;
+ case '=':
+ ret = O_le;
+ break;
+ }
+ ++input_line_pointer;
+ return ret;
+
+ case '=':
+ if (input_line_pointer[1] != '=')
+ return op_encoding[c];
+
+ ++input_line_pointer;
+ return O_eq;
+
+ case '>':
+ switch (input_line_pointer[1])
+ {
+ default:
+ return op_encoding[c];
+ case '>':
+ ret = O_right_shift;
+ break;
+ case '=':
+ ret = O_ge;
+ break;
+ }
+ ++input_line_pointer;
+ return ret;
+
+ case '!':
+ /* We accept !! as equivalent to ^ for MRI compatibility. */
+ if (input_line_pointer[1] != '!')
+ {
+ if (flag_m68k_mri)
+ return O_bit_inclusive_or;
+ return op_encoding[c];
+ }
+ ++input_line_pointer;
+ return O_bit_exclusive_or;
+
+ case '|':
+ if (input_line_pointer[1] != '|')
+ return op_encoding[c];
+
+ ++input_line_pointer;
+ return O_logical_or;
+
+ case '&':
+ if (input_line_pointer[1] != '&')
+ return op_encoding[c];
+
+ ++input_line_pointer;
+ return O_logical_and;
+ }
+
+ /*NOTREACHED*/
+}
+
+/* Parse an expression. */
+
+segT
+expr (rank, resultP)
+ operator_rankT rank; /* Larger # is higher rank. */
+ expressionS *resultP; /* Deliver result here. */
+{
+ segT retval;
+ expressionS right;
+ operatorT op_left;
+ operatorT op_right;
+
+ know (rank >= 0);
+
+ retval = operand (resultP);
+
+ know (*input_line_pointer != ' '); /* Operand() gobbles spaces. */
+
+ op_left = operator ();
+ while (op_left != O_illegal && op_rank[(int) op_left] > rank)
+ {
+ segT rightseg;
+
+ input_line_pointer++; /*->after 1st character of operator. */
+
+ rightseg = expr (op_rank[(int) op_left], &right);
+ if (right.X_op == O_absent)
+ {
+ as_warn (_("missing operand; zero assumed"));
+ right.X_op = O_constant;
+ right.X_add_number = 0;
+ right.X_add_symbol = NULL;
+ right.X_op_symbol = NULL;
+ }
+
+ know (*input_line_pointer != ' ');
+
+ if (retval == undefined_section)
+ {
+ if (SEG_NORMAL (rightseg))
+ retval = rightseg;
+ }
+ else if (! SEG_NORMAL (retval))
+ retval = rightseg;
+ else if (SEG_NORMAL (rightseg)
+ && retval != rightseg
+#ifdef DIFF_EXPR_OK
+ && op_left != O_subtract
+#endif
+ )
+ as_bad (_("operation combines symbols in different segments"));
+
+ op_right = operator ();
+
+ know (op_right == O_illegal || op_rank[(int) op_right] <= op_rank[(int) op_left]);
+ know ((int) op_left >= (int) O_multiply
+ && (int) op_left <= (int) O_logical_or);
+
+ /* input_line_pointer->after right-hand quantity. */
+ /* left-hand quantity in resultP */
+ /* right-hand quantity in right. */
+ /* operator in op_left. */
+
+ if (resultP->X_op == O_big)
+ {
+ if (resultP->X_add_number > 0)
+ as_warn (_("left operand is a bignum; integer 0 assumed"));
+ else
+ as_warn (_("left operand is a float; integer 0 assumed"));
+ resultP->X_op = O_constant;
+ resultP->X_add_number = 0;
+ resultP->X_add_symbol = NULL;
+ resultP->X_op_symbol = NULL;
+ }
+ if (right.X_op == O_big)
+ {
+ if (right.X_add_number > 0)
+ as_warn (_("right operand is a bignum; integer 0 assumed"));
+ else
+ as_warn (_("right operand is a float; integer 0 assumed"));
+ right.X_op = O_constant;
+ right.X_add_number = 0;
+ right.X_add_symbol = NULL;
+ right.X_op_symbol = NULL;
+ }
+
+ /* Optimize common cases. */
+ if (op_left == O_add && right.X_op == O_constant)
+ {
+ /* X + constant. */
+ resultP->X_add_number += right.X_add_number;
+ }
+ /* This case comes up in PIC code. */
+ else if (op_left == O_subtract
+ && right.X_op == O_symbol
+ && resultP->X_op == O_symbol
+ && (right.X_add_symbol->sy_frag
+ == resultP->X_add_symbol->sy_frag)
+ && SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol)))
+
+ {
+ resultP->X_add_number -= right.X_add_number;
+ resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
+ - S_GET_VALUE (right.X_add_symbol));
+ resultP->X_op = O_constant;
+ resultP->X_add_symbol = 0;
+ }
+ else if (op_left == O_subtract && right.X_op == O_constant)
+ {
+ /* X - constant. */
+ resultP->X_add_number -= right.X_add_number;
+ }
+ else if (op_left == O_add && resultP->X_op == O_constant)
+ {
+ /* Constant + X. */
+ resultP->X_op = right.X_op;
+ resultP->X_add_symbol = right.X_add_symbol;
+ resultP->X_op_symbol = right.X_op_symbol;
+ resultP->X_add_number += right.X_add_number;
+ retval = rightseg;
+ }
+ else if (resultP->X_op == O_constant && right.X_op == O_constant)
+ {
+ /* Constant OP constant. */
+ offsetT v = right.X_add_number;
+ if (v == 0 && (op_left == O_divide || op_left == O_modulus))
+ {
+ as_warn (_("division by zero"));
+ v = 1;
+ }
+ switch (op_left)
+ {
+ default: abort ();
+ case O_multiply: resultP->X_add_number *= v; break;
+ case O_divide: resultP->X_add_number /= v; break;
+ case O_modulus: resultP->X_add_number %= v; break;
+ case O_left_shift: resultP->X_add_number <<= v; break;
+ case O_right_shift:
+ /* We always use unsigned shifts, to avoid relying on
+ characteristics of the compiler used to compile gas. */
+ resultP->X_add_number =
+ (offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
+ break;
+ case O_bit_inclusive_or: resultP->X_add_number |= v; break;
+ case O_bit_or_not: resultP->X_add_number |= ~v; break;
+ case O_bit_exclusive_or: resultP->X_add_number ^= v; break;
+ case O_bit_and: resultP->X_add_number &= v; break;
+ case O_add: resultP->X_add_number += v; break;
+ case O_subtract: resultP->X_add_number -= v; break;
+ case O_eq:
+ resultP->X_add_number =
+ resultP->X_add_number == v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_ne:
+ resultP->X_add_number =
+ resultP->X_add_number != v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_lt:
+ resultP->X_add_number =
+ resultP->X_add_number < v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_le:
+ resultP->X_add_number =
+ resultP->X_add_number <= v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_ge:
+ resultP->X_add_number =
+ resultP->X_add_number >= v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_gt:
+ resultP->X_add_number =
+ resultP->X_add_number > v ? ~ (offsetT) 0 : 0;
+ break;
+ case O_logical_and:
+ resultP->X_add_number = resultP->X_add_number && v;
+ break;
+ case O_logical_or:
+ resultP->X_add_number = resultP->X_add_number || v;
+ break;
+ }
+ }
+ else if (resultP->X_op == O_symbol
+ && right.X_op == O_symbol
+ && (op_left == O_add
+ || op_left == O_subtract
+ || (resultP->X_add_number == 0
+ && right.X_add_number == 0)))
+ {
+ /* Symbol OP symbol. */
+ resultP->X_op = op_left;
+ resultP->X_op_symbol = right.X_add_symbol;
+ if (op_left == O_add)
+ resultP->X_add_number += right.X_add_number;
+ else if (op_left == O_subtract)
+ resultP->X_add_number -= right.X_add_number;
+ }
+ else
+ {
+ /* The general case. */
+ resultP->X_add_symbol = make_expr_symbol (resultP);
+ resultP->X_op_symbol = make_expr_symbol (&right);
+ resultP->X_op = op_left;
+ resultP->X_add_number = 0;
+ resultP->X_unsigned = 1;
+ }
+
+ op_left = op_right;
+ } /* While next operator is >= this rank. */
+
+ /* The PA port needs this information. */
+ if (resultP->X_add_symbol)
+ resultP->X_add_symbol->sy_used = 1;
+
+ return resultP->X_op == O_constant ? absolute_section : retval;
+}
+
+/*
+ * get_symbol_end()
+ *
+ * This lives here because it belongs equally in expr.c & read.c.
+ * Expr.c is just a branch office read.c anyway, and putting it
+ * here lessens the crowd at read.c.
+ *
+ * Assume input_line_pointer is at start of symbol name.
+ * Advance input_line_pointer past symbol name.
+ * Turn that character into a '\0', returning its former value.
+ * This allows a string compare (RMS wants symbol names to be strings)
+ * of the symbol name.
+ * There will always be a char following symbol name, because all good
+ * lines end in end-of-line.
+ */
+char
+get_symbol_end ()
+{
+ char c;
+
+ /* We accept \001 in a name in case this is being called with a
+ constructed string. */
+ if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
+ while (is_part_of_name (c = *input_line_pointer++)
+ || c == '\001')
+ ;
+ *--input_line_pointer = 0;
+ return (c);
+}
+
+
+unsigned int
+get_single_number ()
+{
+ expressionS exp;
+ operand (&exp);
+ return exp.X_add_number;
+
+}
+
+/* end of expr.c */
diff --git a/gas/expr.h b/gas/expr.h
new file mode 100644
index 00000000000..da9074389f2
--- /dev/null
+++ b/gas/expr.h
@@ -0,0 +1,162 @@
+/* expr.h -> header file for expr.c
+ Copyright (C) 1987, 92-97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * By popular demand, we define a struct to represent an expression.
+ * This will no doubt mutate as expressions become baroque.
+ *
+ * Currently, we support expressions like "foo OP bar + 42". In other
+ * words we permit a (possibly undefined) symbol, a (possibly
+ * undefined) symbol and the operation used to combine the symbols,
+ * and an (absolute) augend. RMS says this is so we can have 1-pass
+ * assembly for any compiler emissions, and a 'case' statement might
+ * emit 'undefined1 - undefined2'.
+ *
+ * The type of an expression used to be stored as a segment. That got
+ * confusing because it overloaded the concept of a segment. I added
+ * an operator field, instead.
+ */
+
+/* This is the type of an expression. The operator types are also
+ used while parsing an expression.
+
+ NOTE: This enumeration must match the op_rank array in expr.c. */
+
+typedef enum
+{
+ /* An illegal expression. */
+ O_illegal,
+ /* A nonexistent expression. */
+ O_absent,
+ /* X_add_number (a constant expression). */
+ O_constant,
+ /* X_add_symbol + X_add_number. */
+ O_symbol,
+ /* X_add_symbol + X_add_number - the base address of the image. */
+ O_symbol_rva,
+ /* A register (X_add_number is register number). */
+ O_register,
+ /* A big value. If X_add_number is negative or 0, the value is in
+ generic_floating_point_number. Otherwise the value is in
+ generic_bignum, and X_add_number is the number of LITTLENUMs in
+ the value. */
+ O_big,
+ /* (- X_add_symbol) + X_add_number. */
+ O_uminus,
+ /* (~ X_add_symbol) + X_add_number. */
+ O_bit_not,
+ /* (! X_add_symbol) + X_add_number. */
+ O_logical_not,
+ /* (X_add_symbol * X_op_symbol) + X_add_number. */
+ O_multiply,
+ /* (X_add_symbol / X_op_symbol) + X_add_number. */
+ O_divide,
+ /* X_add_symbol % X_op_symbol) + X_add_number. */
+ O_modulus,
+ /* X_add_symbol << X_op_symbol) + X_add_number. */
+ O_left_shift,
+ /* X_add_symbol >> X_op_symbol) + X_add_number. */
+ O_right_shift,
+ /* X_add_symbol | X_op_symbol) + X_add_number. */
+ O_bit_inclusive_or,
+ /* X_add_symbol |~ X_op_symbol) + X_add_number. */
+ O_bit_or_not,
+ /* X_add_symbol ^ X_op_symbol) + X_add_number. */
+ O_bit_exclusive_or,
+ /* X_add_symbol & X_op_symbol) + X_add_number. */
+ O_bit_and,
+ /* X_add_symbol + X_op_symbol) + X_add_number. */
+ O_add,
+ /* X_add_symbol - X_op_symbol) + X_add_number. */
+ O_subtract,
+ /* (X_add_symbol == X_op_symbol) + X_add_number. */
+ O_eq,
+ /* (X_add_symbol != X_op_symbol) + X_add_number. */
+ O_ne,
+ /* (X_add_symbol < X_op_symbol) + X_add_number. */
+ O_lt,
+ /* (X_add_symbol <= X_op_symbol) + X_add_number. */
+ O_le,
+ /* (X_add_symbol >= X_op_symbol) + X_add_number. */
+ O_ge,
+ /* (X_add_symbol > X_op_symbol) + X_add_number. */
+ O_gt,
+ /* (X_add_symbol && X_op_symbol) + X_add_number. */
+ O_logical_and,
+ /* (X_add_symbol || X_op_symbol) + X_add_number. */
+ O_logical_or,
+ /* this must be the largest value */
+ O_max
+} operatorT;
+
+typedef struct expressionS
+{
+ /* The main symbol. */
+ struct symbol *X_add_symbol;
+ /* The second symbol, if needed. */
+ struct symbol *X_op_symbol;
+ /* A number to add. */
+ offsetT X_add_number;
+ /* The type of the expression. We can't assume that an arbitrary
+ compiler can handle a bitfield of enum type. FIXME: We could
+ check this using autoconf. */
+#ifdef __GNUC__
+ operatorT X_op : 5;
+#else
+ unsigned X_op : 5;
+#endif
+ /* Non-zero if X_add_number should be regarded as unsigned. This is
+ only valid for O_constant expressions. It is only used when an
+ O_constant must be extended into a bignum (i.e., it is not used
+ when performing arithmetic on these values).
+ FIXME: This field is not set very reliably. */
+ unsigned int X_unsigned : 1;
+} expressionS;
+
+/* "result" should be type (expressionS *). */
+#define expression(result) expr (0, result)
+
+/* If an expression is O_big, look here for its value. These common
+ data may be clobbered whenever expr() is called. */
+/* Flonums returned here. Big enough to hold most precise flonum. */
+extern FLONUM_TYPE generic_floating_point_number;
+/* Bignums returned here. */
+extern LITTLENUM_TYPE generic_bignum[];
+/* Number of littlenums in above. */
+#define SIZE_OF_LARGE_NUMBER (20)
+
+typedef char operator_rankT;
+
+extern char get_symbol_end PARAMS ((void));
+extern void expr_begin PARAMS ((void));
+extern void expr_set_precedence PARAMS ((void));
+extern segT expr PARAMS ((int rank, expressionS * resultP));
+extern unsigned int get_single_number PARAMS ((void));
+extern struct symbol *make_expr_symbol PARAMS ((expressionS * expressionP));
+extern int expr_symbol_where
+ PARAMS ((struct symbol *, char **, unsigned int *));
+
+extern struct symbol * expr_build_uconstant PARAMS ((offsetT));
+extern struct symbol * expr_build_unary PARAMS ((operatorT, struct symbol *));
+extern struct symbol * expr_build_binary
+ PARAMS ((operatorT, struct symbol *, struct symbol *));
+extern struct symbol * expr_build_dot PARAMS ((void));
+
+/* end of expr.h */
diff --git a/gas/flonum-copy.c b/gas/flonum-copy.c
new file mode 100644
index 00000000000..5bcc5cce7e2
--- /dev/null
+++ b/gas/flonum-copy.c
@@ -0,0 +1,73 @@
+/* flonum_copy.c - copy a flonum
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "as.h"
+
+void
+flonum_copy (in, out)
+ FLONUM_TYPE *in;
+ FLONUM_TYPE *out;
+{
+ unsigned int in_length; /* 0 origin */
+ unsigned int out_length; /* 0 origin */
+
+ out->sign = in->sign;
+ in_length = in->leader - in->low;
+
+ if (in->leader < in->low)
+ {
+ out->leader = out->low - 1; /* 0.0 case */
+ }
+ else
+ {
+ out_length = out->high - out->low;
+ /*
+ * Assume no GAPS in packing of littlenums.
+ * I.e. sizeof(array) == sizeof(element) * number_of_elements.
+ */
+ if (in_length <= out_length)
+ {
+ {
+ /*
+ * For defensive programming, zero any high-order littlenums we don't need.
+ * This is destroying evidence and wasting time, so why bother???
+ */
+ if (in_length < out_length)
+ {
+ memset ((char *) (out->low + in_length + 1), '\0', out_length - in_length);
+ }
+ }
+ memcpy ((void *) (out->low), (void *) (in->low), ((in_length + 1) * sizeof (LITTLENUM_TYPE)));
+ out->exponent = in->exponent;
+ out->leader = in->leader - in->low + out->low;
+ }
+ else
+ {
+ int shorten; /* 1-origin. Number of littlenums we drop. */
+
+ shorten = in_length - out_length;
+ /* Assume out_length >= 0 ! */
+ memcpy ((void *) (out->low), (void *) (in->low + shorten), ((out_length + 1) * sizeof (LITTLENUM_TYPE)));
+ out->leader = out->high;
+ out->exponent = in->exponent + shorten;
+ }
+ } /* if any significant bits */
+} /* flonum_copy() */
+
+/* end of flonum_copy.c */
diff --git a/gas/flonum-konst.c b/gas/flonum-konst.c
new file mode 100644
index 00000000000..22bba05974b
--- /dev/null
+++ b/gas/flonum-konst.c
@@ -0,0 +1,209 @@
+/* flonum_const.c - Useful Flonum constants
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 1996
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <ansidecl.h>
+#include "flonum.h"
+/* JF: I added the last entry to this table, and I'm not
+ sure if its right or not. Could go either way. I wish
+ I really understood this stuff. */
+
+
+const int table_size_of_flonum_powers_of_ten = 13;
+
+static const LITTLENUM_TYPE zero[] =
+{1};
+
+/***********************************************************************\
+ * *
+ * Warning: the low order bits may be WRONG here. *
+ * I took this from a suspect bc(1) script. *
+ * "minus_X"[] is supposed to be 10^(2^-X) expressed in base 2^16. *
+ * The radix point is just AFTER the highest element of the [] *
+ * *
+ * Because bc rounds DOWN for printing (I think), the lowest *
+ * significance littlenums should probably have 1 added to them. *
+ * *
+ \***********************************************************************/
+
+/* JF: If this equals 6553/(2^16)+39321/(2^32)+... it approaches .1 */
+static const LITTLENUM_TYPE minus_1[] =
+{
+ 39322, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321,
+ 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 6553};
+static const LITTLENUM_TYPE plus_1[] =
+{10};
+
+/* JF: If this equals 655/(2^16) + 23592/(2^32) + ... it approaches .01 */
+static const LITTLENUM_TYPE minus_2[] =
+{
+ 10486, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 49807,
+ 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 655};
+static const LITTLENUM_TYPE plus_2[] =
+{100};
+
+/* This approaches .0001 */
+static const LITTLENUM_TYPE minus_3[] =
+{
+ 52534, 20027, 37329, 65116, 64067, 60397, 14784, 18979, 33659, 19503,
+ 2726, 9542, 629, 2202, 40475, 10590, 4299, 47815, 36280, 6};
+static const LITTLENUM_TYPE plus_3[] =
+{10000};
+
+/* JF: this approaches 1e-8 */
+static const LITTLENUM_TYPE minus_4[] =
+{
+ 22517, 49501, 54293, 19424, 60699, 6716, 24348, 22618, 23904, 21327,
+ 3919, 44703, 19149, 28803, 48959, 6259, 50273, 62237, 42};
+/* This equals 1525 * 2^16 + 57600 */
+static const LITTLENUM_TYPE plus_4[] =
+{57600, 1525};
+
+/* This approaches 1e-16 */
+static const LITTLENUM_TYPE minus_5[] =
+{
+ 22199, 45957, 17005, 26266, 10526, 16260, 55017, 35680, 40443, 19789,
+ 17356, 30195, 55905, 28426, 63010, 44197, 1844};
+static const LITTLENUM_TYPE plus_5[] =
+{28609, 34546, 35};
+
+static const LITTLENUM_TYPE minus_6[] =
+{
+ 30926, 26518, 13110, 43018, 54982, 48258, 24658, 15209, 63366, 11929,
+ 20069, 43857, 60487, 51};
+static const LITTLENUM_TYPE plus_6[] =
+{61313, 34220, 16731, 11629, 1262};
+
+static const LITTLENUM_TYPE minus_7[] =
+{
+ 29819, 14733, 21490, 40602, 31315, 65186, 2695};
+static const LITTLENUM_TYPE plus_7[] =
+{
+ 7937, 49002, 60772, 28216, 38893, 55975, 63988, 59711, 20227, 24};
+
+static const LITTLENUM_TYPE minus_8[] =
+{
+ 27579, 64807, 12543, 794, 13907, 61297, 12013, 64360, 15961, 20566,
+ 24178, 15922, 59427, 110};
+static const LITTLENUM_TYPE plus_8[] =
+{
+ 15873, 11925, 39177, 991, 14589, 3861, 58415, 9076, 62956, 54223,
+ 56328, 50180, 45274, 48333, 32537, 42547, 9731, 59679, 590};
+
+static const LITTLENUM_TYPE minus_9[] =
+{
+ 11042, 8464, 58971, 63429, 6022, 63485, 5500, 53464, 47545, 50068,
+ 56988, 22819, 49708, 54493, 9920, 47667, 40409, 35764, 10383, 54466,
+ 32702, 17493, 32420, 34382, 22750, 20681, 12300};
+static const LITTLENUM_TYPE plus_9[] =
+{
+ 20678, 27614, 28272, 53066, 55311, 54677, 29038, 9906, 26288, 44486,
+ 13860, 7445, 54106, 15426, 21518, 25599, 29632, 52309, 61207, 26105,
+ 10482, 21948, 51191, 32988, 60892, 62574, 61390, 24540, 21495, 5};
+
+static const LITTLENUM_TYPE minus_10[] =
+{
+ 6214, 48771, 23471, 30163, 31763, 38013, 57001, 11770, 18263, 36366,
+ 20742, 45086, 56969, 53231, 37856, 55814, 38057, 15692, 46761, 8713,
+ 6102, 20083, 8269, 11839, 11571, 50963, 15649, 11698, 40675, 2308};
+static const LITTLENUM_TYPE plus_10[] =
+{
+ 63839, 36576, 45712, 44516, 37803, 29482, 4966, 30556, 37961, 23310,
+ 27070, 44972, 29507, 48257, 45209, 7494, 17831, 38728, 41577, 29443,
+ 36016, 7955, 35339, 35479, 36011, 14553, 49618, 5588, 25396, 28};
+
+static const LITTLENUM_TYPE minus_11[] =
+{
+ 16663, 56882, 61983, 7804, 36555, 32060, 34502, 1000, 14356, 21681,
+ 6605, 34767, 51411, 59048, 53614, 39850, 30079, 6496, 6846, 26841,
+ 40778, 19578, 59899, 44085, 54016, 24259, 11232, 21229, 21313, 81};
+static const LITTLENUM_TYPE plus_11[] =
+{
+ 92, 9054, 62707, 17993, 7821, 56838, 13992, 21321, 29637, 48426,
+ 42982, 38668, 49574, 28820, 18200, 18927, 53979, 16219, 37484, 2516,
+ 44642, 14665, 11587, 41926, 13556, 23956, 54320, 6661, 55766, 805};
+
+static const LITTLENUM_TYPE minus_12[] =
+{
+ 33202, 45969, 58804, 56734, 16482, 26007, 44984, 49334, 31007, 32944,
+ 44517, 63329, 47131, 15291, 59465, 2264, 23218, 11829, 59771, 38798,
+ 31051, 28748, 23129, 40541, 41562, 35108, 50620, 59014, 51817, 6613};
+static const LITTLENUM_TYPE plus_12[] =
+{
+ 10098, 37922, 58070, 7432, 10470, 63465, 23718, 62190, 47420, 7009,
+ 38443, 4587, 45596, 38472, 52129, 52779, 29012, 13559, 48688, 31678,
+ 41753, 58662, 10668, 36067, 29906, 56906, 21461, 46556, 59571, 9};
+
+static const LITTLENUM_TYPE minus_13[] =
+{
+ 45309, 27592, 37144, 34637, 34328, 41671, 34620, 24135, 53401, 22112,
+ 21576, 45147, 39310, 44051, 48572, 3676, 46544, 59768, 33350, 2323,
+ 49524, 61568, 3903, 36487, 36356, 30903, 14975, 9035, 29715, 667};
+static const LITTLENUM_TYPE plus_13[] =
+{
+ 18788, 16960, 6318, 45685, 55400, 46230, 35794, 25588, 7253, 55541,
+ 49716, 59760, 63592, 8191, 63765, 58530, 44667, 13294, 10001, 55586,
+ 47887, 18738, 9509, 40896, 42506, 52580, 4171, 325, 12329, 98};
+
+/* Shut up complaints about differing pointer types. They only differ
+ in the const attribute, but there isn't any easy way to do this
+ */
+#define X (LITTLENUM_TYPE *)
+
+const FLONUM_TYPE flonum_negative_powers_of_ten[] =
+{
+ {X zero, X zero, X zero, 0, '+'},
+ {X minus_1, X minus_1 + 19, X minus_1 + 19, -20, '+'},
+ {X minus_2, X minus_2 + 19, X minus_2 + 19, -20, '+'},
+ {X minus_3, X minus_3 + 19, X minus_3 + 19, -20, '+'},
+ {X minus_4, X minus_4 + 18, X minus_4 + 18, -20, '+'},
+ {X minus_5, X minus_5 + 16, X minus_5 + 16, -20, '+'},
+ {X minus_6, X minus_6 + 13, X minus_6 + 13, -20, '+'},
+ {X minus_7, X minus_7 + 6, X minus_7 + 6, -20, '+'},
+ {X minus_8, X minus_8 + 13, X minus_8 + 13, -40, '+'},
+ {X minus_9, X minus_9 + 26, X minus_9 + 26, -80, '+'},
+ {X minus_10, X minus_10 + 29, X minus_10 + 29, -136, '+'},
+ {X minus_11, X minus_11 + 29, X minus_11 + 29, -242, '+'},
+ {X minus_12, X minus_12 + 29, X minus_12 + 29, -455, '+'},
+ {X minus_13, X minus_13 + 29, X minus_13 + 29, -880, '+'},
+};
+
+const FLONUM_TYPE flonum_positive_powers_of_ten[] =
+{
+ {X zero, X zero, X zero, 0, '+'},
+ {X plus_1, X plus_1 + 0, X plus_1 + 0, 0, '+'},
+ {X plus_2, X plus_2 + 0, X plus_2 + 0, 0, '+'},
+ {X plus_3, X plus_3 + 0, X plus_3 + 0, 0, '+'},
+ {X plus_4, X plus_4 + 1, X plus_4 + 1, 0, '+'},
+ {X plus_5, X plus_5 + 2, X plus_5 + 2, 1, '+'},
+ {X plus_6, X plus_6 + 4, X plus_6 + 4, 2, '+'},
+ {X plus_7, X plus_7 + 9, X plus_7 + 9, 4, '+'},
+ {X plus_8, X plus_8 + 18, X plus_8 + 18, 8, '+'},
+ {X plus_9, X plus_9 + 29, X plus_9 + 29, 24, '+'},
+ {X plus_10, X plus_10 + 29, X plus_10 + 29, 77, '+'},
+ {X plus_11, X plus_11 + 29, X plus_11 + 29, 183, '+'},
+ {X plus_12, X plus_12 + 29, X plus_12 + 29, 396, '+'},
+ {X plus_13, X plus_13 + 29, X plus_13 + 29, 821, '+'},
+};
+
+#ifdef VMS
+void dummy1 () { }
+#endif
+/* end of flonum_const.c */
diff --git a/gas/flonum-mult.c b/gas/flonum-mult.c
new file mode 100644
index 00000000000..434a73b0411
--- /dev/null
+++ b/gas/flonum-mult.c
@@ -0,0 +1,200 @@
+/* flonum_mult.c - multiply two flonums
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of Gas, the GNU Assembler.
+
+ The GNU assembler is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY. No author or distributor
+ accepts responsibility to anyone for the consequences of using it
+ or for whether it serves any particular purpose or works at all,
+ unless he says so in writing. Refer to the GNU Assembler General
+ Public License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute
+ the GNU Assembler, but only under the conditions described in the
+ GNU Assembler General Public License. A copy of this license is
+ supposed to have been given to you along with the GNU Assembler
+ so you can know your rights and responsibilities. It should be
+ in a file named COPYING. Among other things, the copyright
+ notice and this notice must be preserved on all copies. */
+
+#include <ansidecl.h>
+#include "flonum.h"
+
+/* plan for a . b => p(roduct)
+
+
+ +-------+-------+-/ /-+-------+-------+
+ | a | a | ... | a | a |
+ | A | A-1 | | 1 | 0 |
+ +-------+-------+-/ /-+-------+-------+
+
+
+ +-------+-------+-/ /-+-------+-------+
+ | b | b | ... | b | b |
+ | B | B-1 | | 1 | 0 |
+ +-------+-------+-/ /-+-------+-------+
+
+
+ +-------+-------+-/ /-+-------+-/ /-+-------+-------+
+ | p | p | ... | p | ... | p | p |
+ | A+B+1| A+B | | N | | 1 | 0 |
+ +-------+-------+-/ /-+-------+-/ /-+-------+-------+
+
+ /^\
+ (carry) a .b ... | ... a .b a .b
+ A B | 0 1 0 0
+ |
+ ... | ... a .b
+ | 1 0
+ |
+ | ...
+ |
+ |
+ |
+ | ___
+ | \
+ +----- P = > a .b
+ N /__ i j
+
+ N = 0 ... A+B
+
+ for all i,j where i+j=N
+ [i,j integers > 0]
+
+ a[], b[], p[] may not intersect.
+ Zero length factors signify 0 significant bits: treat as 0.0.
+ 0.0 factors do the right thing.
+ Zero length product OK.
+
+ I chose the ForTran accent "foo[bar]" instead of the C accent "*garply"
+ because I felt the ForTran way was more intuitive. The C way would
+ probably yield better code on most C compilers. Dean Elsner.
+ (C style also gives deeper insight [to me] ... oh well ...)
+ */
+
+void
+flonum_multip (a, b, product)
+ const FLONUM_TYPE *a;
+ const FLONUM_TYPE *b;
+ FLONUM_TYPE *product;
+{
+ int size_of_a; /* 0 origin */
+ int size_of_b; /* 0 origin */
+ int size_of_product; /* 0 origin */
+ int size_of_sum; /* 0 origin */
+ int extra_product_positions; /* 1 origin */
+ unsigned long work;
+ unsigned long carry;
+ long exponent;
+ LITTLENUM_TYPE *q;
+ long significant; /* TRUE when we emit a non-0 littlenum */
+ /* ForTran accent follows. */
+ int P; /* Scan product low-order -> high. */
+ int N; /* As in sum above. */
+ int A; /* Which [] of a? */
+ int B; /* Which [] of b? */
+
+ if ((a->sign != '-' && a->sign != '+') || (b->sign != '-' && b->sign != '+'))
+ {
+ /* ...
+ Got to fail somehow. Any suggestions? */
+ product->sign = 0;
+ return;
+ }
+ product->sign = (a->sign == b->sign) ? '+' : '-';
+ size_of_a = a->leader - a->low;
+ size_of_b = b->leader - b->low;
+ exponent = a->exponent + b->exponent;
+ size_of_product = product->high - product->low;
+ size_of_sum = size_of_a + size_of_b;
+ extra_product_positions = size_of_product - size_of_sum;
+ if (extra_product_positions < 0)
+ {
+ P = extra_product_positions; /* P < 0 */
+ exponent -= extra_product_positions; /* Increases exponent. */
+ }
+ else
+ {
+ P = 0;
+ }
+ carry = 0;
+ significant = 0;
+ for (N = 0; N <= size_of_sum; N++)
+ {
+ work = carry;
+ carry = 0;
+ for (A = 0; A <= N; A++)
+ {
+ B = N - A;
+ if (A <= size_of_a && B <= size_of_b && B >= 0)
+ {
+#ifdef TRACE
+ printf ("a:low[%d.]=%04x b:low[%d.]=%04x work_before=%08x\n", A, a->low[A], B, b->low[B], work);
+#endif
+ /* Watch out for sign extension! Without the casts, on
+ the DEC Alpha, the multiplication result is *signed*
+ int, which gets sign-extended to convert to the
+ unsigned long! */
+ work += (unsigned long) a->low[A] * (unsigned long) b->low[B];
+ carry += work >> LITTLENUM_NUMBER_OF_BITS;
+ work &= LITTLENUM_MASK;
+#ifdef TRACE
+ printf ("work=%08x carry=%04x\n", work, carry);
+#endif
+ }
+ }
+ significant |= work;
+ if (significant || P < 0)
+ {
+ if (P >= 0)
+ {
+ product->low[P] = work;
+#ifdef TRACE
+ printf ("P=%d. work[p]:=%04x\n", P, work);
+#endif
+ }
+ P++;
+ }
+ else
+ {
+ extra_product_positions++;
+ exponent++;
+ }
+ }
+ /*
+ * [P]-> position # size_of_sum + 1.
+ * This is where 'carry' should go.
+ */
+#ifdef TRACE
+ printf ("final carry =%04x\n", carry);
+#endif
+ if (carry)
+ {
+ if (extra_product_positions > 0)
+ {
+ product->low[P] = carry;
+ }
+ else
+ {
+ /* No room at high order for carry littlenum. */
+ /* Shift right 1 to make room for most significant littlenum. */
+ exponent++;
+ P--;
+ for (q = product->low + P; q >= product->low; q--)
+ {
+ work = *q;
+ *q = carry;
+ carry = work;
+ }
+ }
+ }
+ else
+ {
+ P--;
+ }
+ product->leader = product->low + P;
+ product->exponent = exponent;
+}
+
+/* end of flonum_mult.c */
diff --git a/gas/flonum.h b/gas/flonum.h
new file mode 100644
index 00000000000..6684f496c2c
--- /dev/null
+++ b/gas/flonum.h
@@ -0,0 +1,110 @@
+/* flonum.h - Floating point package
+
+ Copyright (C) 1987, 90, 91, 92, 94, 95, 1996 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/***********************************************************************\
+ * *
+ * Arbitrary-precision floating point arithmetic. *
+ * *
+ * *
+ * Notation: a floating point number is expressed as *
+ * MANTISSA * (2 ** EXPONENT). *
+ * *
+ * If this offends more traditional mathematicians, then *
+ * please tell me your nomenclature for flonums! *
+ * *
+ \***********************************************************************/
+
+#include "bignum.h"
+
+/***********************************************************************\
+ * *
+ * Variable precision floating point numbers. *
+ * *
+ * Exponent is the place value of the low littlenum. E.g.: *
+ * If 0: low points to the units littlenum. *
+ * If 1: low points to the LITTLENUM_RADIX littlenum. *
+ * If -1: low points to the 1/LITTLENUM_RADIX littlenum. *
+ * *
+ \***********************************************************************/
+
+/* JF: A sign value of 0 means we have been asked to assemble NaN
+ A sign value of 'P' means we've been asked to assemble +Inf
+ A sign value of 'N' means we've been asked to assemble -Inf
+ */
+struct FLONUM_STRUCT
+{
+ LITTLENUM_TYPE *low; /* low order littlenum of a bignum */
+ LITTLENUM_TYPE *high; /* high order littlenum of a bignum */
+ LITTLENUM_TYPE *leader; /* -> 1st non-zero littlenum */
+ /* If flonum is 0.0, leader==low-1 */
+ long exponent; /* base LITTLENUM_RADIX */
+ char sign; /* '+' or '-' */
+};
+
+typedef struct FLONUM_STRUCT FLONUM_TYPE;
+
+
+/***********************************************************************\
+ * *
+ * Since we can (& do) meet with exponents like 10^5000, it *
+ * is silly to make a table of ~ 10,000 entries, one for each *
+ * power of 10. We keep a table where item [n] is a struct *
+ * FLONUM_FLOATING_POINT representing 10^(2^n). We then *
+ * multiply appropriate entries from this table to get any *
+ * particular power of 10. For the example of 10^5000, a table *
+ * of just 25 entries suffices: 10^(2^-12)...10^(2^+12). *
+ * *
+ \***********************************************************************/
+
+
+extern const FLONUM_TYPE flonum_positive_powers_of_ten[];
+extern const FLONUM_TYPE flonum_negative_powers_of_ten[];
+extern const int table_size_of_flonum_powers_of_ten;
+/* Flonum_XXX_powers_of_ten[] table has */
+/* legal indices from 0 to */
+/* + this number inclusive. */
+
+
+
+/***********************************************************************\
+ * *
+ * Declare worker functions. *
+ * *
+ \***********************************************************************/
+
+int atof_generic PARAMS ((char **address_of_string_pointer,
+ const char *string_of_decimal_marks,
+ const char *string_of_decimal_exponent_marks,
+ FLONUM_TYPE * address_of_generic_floating_point_number));
+
+void flonum_copy PARAMS ((FLONUM_TYPE * in, FLONUM_TYPE * out));
+void flonum_multip PARAMS ((const FLONUM_TYPE * a, const FLONUM_TYPE * b,
+ FLONUM_TYPE * product));
+
+/***********************************************************************\
+ * *
+ * Declare error codes. *
+ * *
+ \***********************************************************************/
+
+#define ERROR_EXPONENT_OVERFLOW (2)
+
+/* end of flonum.h */
diff --git a/gas/frags.c b/gas/frags.c
new file mode 100644
index 00000000000..240b2ee63a0
--- /dev/null
+++ b/gas/frags.c
@@ -0,0 +1,359 @@
+/* frags.c - manage frags -
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+#include "subsegs.h"
+#include "obstack.h"
+
+extern fragS zero_address_frag;
+extern fragS bss_address_frag;
+
+/* Initialization for frag routines. */
+void
+frag_init ()
+{
+ zero_address_frag.fr_type = rs_fill;
+ bss_address_frag.fr_type = rs_fill;
+}
+
+/* Allocate a frag on the specified obstack.
+ Call this routine from everywhere else, so that all the weird alignment
+ hackery can be done in just one place. */
+fragS *
+frag_alloc (ob)
+ struct obstack *ob;
+{
+ fragS *ptr;
+ int oalign;
+
+ (void) obstack_alloc (ob, 0);
+ oalign = obstack_alignment_mask (ob);
+ obstack_alignment_mask (ob) = 0;
+ ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG);
+ obstack_alignment_mask (ob) = oalign;
+ memset (ptr, 0, SIZEOF_STRUCT_FRAG);
+ return ptr;
+}
+
+/*
+ * frag_grow()
+ *
+ * Try to augment current frag by nchars chars.
+ * If there is no room, close of the current frag with a ".fill 0"
+ * and begin a new frag. Unless the new frag has nchars chars available
+ * do not return. Do not set up any fields of *now_frag.
+ */
+void
+frag_grow (nchars)
+ unsigned int nchars;
+{
+ if (obstack_room (&frchain_now->frch_obstack) < nchars)
+ {
+ unsigned int n;
+ long oldc;
+
+ frag_wane (frag_now);
+ frag_new (0);
+ oldc = frchain_now->frch_obstack.chunk_size;
+ frchain_now->frch_obstack.chunk_size = 2 * nchars + SIZEOF_STRUCT_FRAG;
+ while ((n = obstack_room (&frchain_now->frch_obstack)) < nchars)
+ {
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+ frchain_now->frch_obstack.chunk_size = oldc;
+ }
+ if (obstack_room (&frchain_now->frch_obstack) < nchars)
+ as_fatal (_("Can't extend frag %d. chars"), nchars);
+}
+
+/*
+ * frag_new()
+ *
+ * Call this to close off a completed frag, and start up a new (empty)
+ * frag, in the same subsegment as the old frag.
+ * [frchain_now remains the same but frag_now is updated.]
+ * Because this calculates the correct value of fr_fix by
+ * looking at the obstack 'frags', it needs to know how many
+ * characters at the end of the old frag belong to (the maximal)
+ * fr_var: the rest must belong to fr_fix.
+ * It doesn't actually set up the old frag's fr_var: you may have
+ * set fr_var == 1, but allocated 10 chars to the end of the frag:
+ * in this case you pass old_frags_var_max_size == 10.
+ *
+ * Make a new frag, initialising some components. Link new frag at end
+ * of frchain_now.
+ */
+void
+frag_new (old_frags_var_max_size)
+ /* Number of chars (already allocated on obstack frags) in
+ variable_length part of frag. */
+ int old_frags_var_max_size;
+{
+ fragS *former_last_fragP;
+ frchainS *frchP;
+
+ assert (frchain_now->frch_last == frag_now);
+
+ /* Fix up old frag's fr_fix. */
+ frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size;
+ /* Make sure its type is valid. */
+ assert (frag_now->fr_type != 0);
+
+ /* This will align the obstack so the next struct we allocate on it
+ will begin at a correct boundary. */
+ obstack_finish (&frchain_now->frch_obstack);
+ frchP = frchain_now;
+ know (frchP);
+ former_last_fragP = frchP->frch_last;
+ assert (former_last_fragP != 0);
+ assert (former_last_fragP == frag_now);
+ frag_now = frag_alloc (&frchP->frch_obstack);
+
+ as_where (&frag_now->fr_file, &frag_now->fr_line);
+
+ /* Generally, frag_now->points to an address rounded up to next
+ alignment. However, characters will add to obstack frags
+ IMMEDIATELY after the struct frag, even if they are not starting
+ at an alignment address. */
+ former_last_fragP->fr_next = frag_now;
+ frchP->frch_last = frag_now;
+
+#ifndef NO_LISTING
+ {
+ extern struct list_info_struct *listing_tail;
+ frag_now->line = listing_tail;
+ }
+#endif
+
+ assert (frchain_now->frch_last == frag_now);
+
+ frag_now->fr_next = NULL;
+} /* frag_new() */
+
+/*
+ * frag_more()
+ *
+ * Start a new frag unless we have n more chars of room in the current frag.
+ * Close off the old frag with a .fill 0.
+ *
+ * Return the address of the 1st char to write into. Advance
+ * frag_now_growth past the new chars.
+ */
+
+char *
+frag_more (nchars)
+ int nchars;
+{
+ register char *retval;
+
+ if (now_seg == absolute_section)
+ {
+ as_bad (_("attempt to allocate data in absolute section"));
+ subseg_set (text_section, 0);
+ }
+
+ if (mri_common_symbol != NULL)
+ {
+ as_bad (_("attempt to allocate data in common section"));
+ mri_common_symbol = NULL;
+ }
+
+ frag_grow (nchars);
+ retval = obstack_next_free (&frchain_now->frch_obstack);
+ obstack_blank_fast (&frchain_now->frch_obstack, nchars);
+ return (retval);
+} /* frag_more() */
+
+/*
+ * frag_var()
+ *
+ * Start a new frag unless we have max_chars more chars of room in the current frag.
+ * Close off the old frag with a .fill 0.
+ *
+ * Set up a machine_dependent relaxable frag, then start a new frag.
+ * Return the address of the 1st char of the var part of the old frag
+ * to write into.
+ */
+
+char *
+frag_var (type, max_chars, var, subtype, symbol, offset, opcode)
+ relax_stateT type;
+ int max_chars;
+ int var;
+ relax_substateT subtype;
+ symbolS *symbol;
+ offsetT offset;
+ char *opcode;
+{
+ register char *retval;
+
+ frag_grow (max_chars);
+ retval = obstack_next_free (&frchain_now->frch_obstack);
+ obstack_blank_fast (&frchain_now->frch_obstack, max_chars);
+ frag_now->fr_var = var;
+ frag_now->fr_type = type;
+ frag_now->fr_subtype = subtype;
+ frag_now->fr_symbol = symbol;
+ frag_now->fr_offset = offset;
+ frag_now->fr_opcode = opcode;
+#ifdef USING_CGEN
+ frag_now->fr_cgen.insn = 0;
+ frag_now->fr_cgen.opindex = 0;
+ frag_now->fr_cgen.opinfo = 0;
+#endif
+#ifdef TC_FRAG_INIT
+ TC_FRAG_INIT (frag_now);
+#endif
+ as_where (&frag_now->fr_file, &frag_now->fr_line);
+ frag_new (max_chars);
+ return (retval);
+}
+
+/*
+ * frag_variant()
+ *
+ * OVE: This variant of frag_var assumes that space for the tail has been
+ * allocated by caller.
+ * No call to frag_grow is done.
+ */
+
+char *
+frag_variant (type, max_chars, var, subtype, symbol, offset, opcode)
+ relax_stateT type;
+ int max_chars;
+ int var;
+ relax_substateT subtype;
+ symbolS *symbol;
+ offsetT offset;
+ char *opcode;
+{
+ register char *retval;
+
+ retval = obstack_next_free (&frchain_now->frch_obstack);
+ frag_now->fr_var = var;
+ frag_now->fr_type = type;
+ frag_now->fr_subtype = subtype;
+ frag_now->fr_symbol = symbol;
+ frag_now->fr_offset = offset;
+ frag_now->fr_opcode = opcode;
+#ifdef USING_CGEN
+ frag_now->fr_cgen.insn = 0;
+ frag_now->fr_cgen.opindex = 0;
+ frag_now->fr_cgen.opinfo = 0;
+#endif
+#ifdef TC_FRAG_INIT
+ TC_FRAG_INIT (frag_now);
+#endif
+ as_where (&frag_now->fr_file, &frag_now->fr_line);
+ frag_new (max_chars);
+ return (retval);
+} /* frag_variant() */
+
+/*
+ * frag_wane()
+ *
+ * Reduce the variable end of a frag to a harmless state.
+ */
+void
+frag_wane (fragP)
+ register fragS *fragP;
+{
+ fragP->fr_type = rs_fill;
+ fragP->fr_offset = 0;
+ fragP->fr_var = 0;
+}
+
+/* Make an alignment frag. The size of this frag will be adjusted to
+ force the next frag to have the appropriate alignment. ALIGNMENT
+ is the power of two to which to align. FILL_CHARACTER is the
+ character to use to fill in any bytes which are skipped. MAX is
+ the maximum number of characters to skip when doing the alignment,
+ or 0 if there is no maximum. */
+
+void
+frag_align (alignment, fill_character, max)
+ int alignment;
+ int fill_character;
+ int max;
+{
+ if (now_seg == absolute_section)
+ {
+ addressT new_off;
+
+ new_off = ((abs_section_offset + alignment - 1)
+ &~ ((1 << alignment) - 1));
+ if (max == 0 || new_off - abs_section_offset <= (addressT) max)
+ abs_section_offset = new_off;
+ }
+ else
+ {
+ char *p;
+
+ p = frag_var (rs_align, 1, 1, (relax_substateT) max,
+ (symbolS *) 0, (offsetT) alignment, (char *) 0);
+ *p = fill_character;
+ }
+}
+
+/* Make an alignment frag like frag_align, but fill with a repeating
+ pattern rather than a single byte. ALIGNMENT is the power of two
+ to which to align. FILL_PATTERN is the fill pattern to repeat in
+ the bytes which are skipped. N_FILL is the number of bytes in
+ FILL_PATTERN. MAX is the maximum number of characters to skip when
+ doing the alignment, or 0 if there is no maximum. */
+
+void
+frag_align_pattern (alignment, fill_pattern, n_fill, max)
+ int alignment;
+ const char *fill_pattern;
+ int n_fill;
+ int max;
+{
+ char *p;
+
+ p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max,
+ (symbolS *) 0, (offsetT) alignment, (char *) 0);
+ memcpy (p, fill_pattern, n_fill);
+}
+
+addressT
+frag_now_fix ()
+{
+ if (now_seg == absolute_section)
+ return abs_section_offset;
+ return (addressT) ((char*) obstack_next_free (&frchain_now->frch_obstack)
+ - frag_now->fr_literal);
+}
+
+void
+frag_append_1_char (datum)
+ int datum;
+{
+ if (obstack_room (&frchain_now->frch_obstack) <= 1)
+ {
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+ obstack_1grow (&frchain_now->frch_obstack, datum);
+}
+
+/* end of frags.c */
diff --git a/gas/frags.h b/gas/frags.h
new file mode 100644
index 00000000000..9590292a4da
--- /dev/null
+++ b/gas/frags.h
@@ -0,0 +1,158 @@
+/* frags.h - Header file for the frag concept.
+ Copyright (C) 1987, 92, 93, 94, 95, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef FRAGS_H
+#define FRAGS_H
+
+#ifdef ANSI_PROTOTYPES
+struct obstack;
+#endif
+
+/*
+ * A code fragment (frag) is some known number of chars, followed by some
+ * unknown number of chars. Typically the unknown number of chars is an
+ * instruction address whose size is yet unknown. We always know the greatest
+ * possible size the unknown number of chars may become, and reserve that
+ * much room at the end of the frag.
+ * Once created, frags do not change address during assembly.
+ * We chain the frags in (a) forward-linked list(s). The object-file address
+ * of the 1st char of a frag is generally not known until after relax().
+ * Many things at assembly time describe an address by {object-file-address
+ * of a particular frag}+offset.
+
+ BUG: it may be smarter to have a single pointer off to various different
+ notes for different frag kinds. See how code pans
+ */
+
+struct frag
+{
+ /* Object file address. */
+ addressT fr_address;
+ /* Chain forward; ascending address order. Rooted in frch_root. */
+ struct frag *fr_next;
+
+ /* (Fixed) number of chars we know we have. May be 0. */
+ offsetT fr_fix;
+ /* (Variable) number of chars after above. May be 0. */
+ offsetT fr_var;
+ /* For variable-length tail. */
+ struct symbol *fr_symbol;
+ /* For variable-length tail. */
+ offsetT fr_offset;
+ /* Points to opcode low addr byte, for relaxation. */
+ char *fr_opcode;
+
+#ifndef NO_LISTING
+ struct list_info_struct *line;
+#endif
+
+ /* What state is my tail in? */
+ relax_stateT fr_type;
+ relax_substateT fr_subtype;
+
+#ifdef USING_CGEN
+ /* Don't include this unless using CGEN to keep frag size down. */
+ struct {
+ /* CGEN_INSN entry for this instruction. */
+ const struct cgen_insn *insn;
+ /* Index into operand table. */
+ int opindex;
+ /* Target specific data, usually reloc number. */
+ int opinfo;
+ } fr_cgen;
+#endif
+
+#ifdef TC_FRAG_TYPE
+ TC_FRAG_TYPE tc_frag_data;
+#endif
+
+ /* Where the frag was created, or where it became a variant frag. */
+ char *fr_file;
+ unsigned int fr_line;
+
+ /* Data begins here. */
+ char fr_literal[1];
+};
+
+#define SIZEOF_STRUCT_FRAG \
+((char *)zero_address_frag.fr_literal-(char *)&zero_address_frag)
+/* We want to say fr_literal[0] above. */
+
+/* Current frag we are building. This frag is incomplete. It is,
+ however, included in frchain_now. The fr_fix field is bogus;
+ instead, use frag_now_fix (). */
+COMMON fragS *frag_now;
+extern addressT frag_now_fix PARAMS ((void));
+
+/* For foreign-segment symbol fixups. */
+COMMON fragS zero_address_frag;
+/* For local common (N_BSS segment) fixups. */
+COMMON fragS bss_address_frag;
+
+#if 0
+/*
+ * A macro to speed up appending exactly 1 char
+ * to current frag.
+ */
+/* JF changed < 1 to <= 1 to avoid a race conditon */
+#define FRAG_APPEND_1_CHAR(datum) \
+{ \
+ if (obstack_room( &frags ) <= 1) {\
+ frag_wane (frag_now); \
+ frag_new (0); \
+ } \
+ obstack_1grow( &frags, datum ); \
+}
+#else
+extern void frag_append_1_char PARAMS ((int));
+#define FRAG_APPEND_1_CHAR(X) frag_append_1_char (X)
+#endif
+
+
+void frag_init PARAMS ((void));
+fragS *frag_alloc PARAMS ((struct obstack *));
+void frag_grow PARAMS ((unsigned int nchars));
+char *frag_more PARAMS ((int nchars));
+void frag_align PARAMS ((int alignment, int fill_character, int max));
+void frag_align_pattern PARAMS ((int alignment,
+ const char *fill_pattern,
+ int n_fill,
+ int max));
+void frag_new PARAMS ((int old_frags_var_max_size));
+void frag_wane PARAMS ((fragS * fragP));
+
+char *frag_variant PARAMS ((relax_stateT type,
+ int max_chars,
+ int var,
+ relax_substateT subtype,
+ symbolS * symbol,
+ offsetT offset,
+ char *opcode));
+
+char *frag_var PARAMS ((relax_stateT type,
+ int max_chars,
+ int var,
+ relax_substateT subtype,
+ symbolS * symbol,
+ offsetT offset,
+ char *opcode));
+
+#endif /* FRAGS_H */
diff --git a/gas/gasp.c b/gas/gasp.c
new file mode 100644
index 00000000000..fbb65e31b43
--- /dev/null
+++ b/gas/gasp.c
@@ -0,0 +1,3745 @@
+/* gasp.c - Gnu assembler preprocessor main program.
+ Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GASP, the GNU Assembler Preprocessor.
+
+ GASP 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, or (at your option)
+ any later version.
+
+ GASP 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 GASP; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+
+This program translates the input macros and stuff into a form
+suitable for gas to consume.
+
+
+ gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
+
+ -s copy source to output
+ -c <char> comments are started with <char> instead of !
+ -u allow unreasonable stuff
+ -p print line numbers
+ -d print debugging stats
+ -s semi colons start comments
+ -a use alternate syntax
+ Pseudo ops can start with or without a .
+ Labels have to be in first column.
+ -I specify include dir
+ Macro arg parameters subsituted by name, don't need the &.
+ String can start with ' too.
+ Strings can be surrounded by <..>
+ A %<exp> in a string evaluates the expression
+ Literal char in a string with !
+
+
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <ctype.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_MALLOC_DECLARATION
+extern char *malloc ();
+#endif
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "sb.h"
+#include "macro.h"
+#include "asintl.h"
+
+char *program_version = "1.2";
+
+/* This is normally declared in as.h, but we don't include that. We
+ need the function because other files linked with gasp.c might call
+ it. */
+extern void as_abort PARAMS ((const char *, int, const char *));
+
+#define MAX_INCLUDES 30 /* Maximum include depth */
+#define MAX_REASONABLE 1000 /* Maximum number of expansions */
+
+int unreasonable; /* -u on command line */
+int stats; /* -d on command line */
+int print_line_number; /* -p flag on command line */
+int copysource; /* -c flag on command line */
+int warnings; /* Number of WARNINGs generated so far. */
+int errors; /* Number of ERRORs generated so far. */
+int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */
+int alternate = 0; /* -a on command line */
+int mri = 0; /* -M on command line */
+char comment_char = '!';
+int radix = 10; /* Default radix */
+
+int had_end; /* Seen .END */
+
+/* The output stream */
+FILE *outfile;
+
+/* the attributes of each character are stored as a bit pattern
+ chartype, which gives us quick tests. */
+
+
+#define FIRSTBIT 1
+#define NEXTBIT 2
+#define SEPBIT 4
+#define WHITEBIT 8
+#define COMMENTBIT 16
+#define BASEBIT 32
+#define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
+#define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
+#define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
+#define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
+#define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
+#define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
+static char chartype[256];
+
+
+/* Conditional assembly uses the `ifstack'. Each aif pushes another
+ entry onto the stack, and sets the on flag if it should. The aelse
+ sets hadelse, and toggles on. An aend pops a level. We limit to
+ 100 levels of nesting, not because we're facists pigs with read
+ only minds, but because more than 100 levels of nesting is probably
+ a bug in the user's macro structure. */
+
+#define IFNESTING 100
+struct
+ {
+ int on; /* is the level being output */
+ int hadelse; /* has an aelse been seen */
+ }
+ifstack[IFNESTING];
+int ifi;
+
+/* The final and intermediate results of expression evaluation are kept in
+ exp_t's. Note that a symbol is not an sb, but a pointer into the input
+ line. It must be coped somewhere safe before the next line is read in. */
+
+typedef struct
+ {
+ char *name;
+ int len;
+ }
+symbol;
+
+typedef struct
+ {
+ int value; /* constant part */
+ symbol add_symbol; /* name part */
+ symbol sub_symbol; /* name part */
+ }
+exp_t;
+
+
+/* Hashing is done in a pretty standard way. A hash_table has a
+ pointer to a vector of pointers to hash_entrys, and the size of the
+ vector. A hash_entry contains a union of all the info we like to
+ store in hash table. If there is a hash collision, hash_entries
+ with the same hash are kept in a chain. */
+
+/* What the data in a hash_entry means */
+typedef enum
+ {
+ hash_integer, /* name->integer mapping */
+ hash_string, /* name->string mapping */
+ hash_macro, /* name is a macro */
+ hash_formal /* name is a formal argument */
+ } hash_type;
+
+typedef struct hs
+ {
+ sb key; /* symbol name */
+ hash_type type; /* symbol meaning */
+ union
+ {
+ sb s;
+ int i;
+ struct macro_struct *m;
+ struct formal_struct *f;
+ } value;
+ struct hs *next; /* next hash_entry with same hash key */
+ } hash_entry;
+
+typedef struct
+ {
+ hash_entry **table;
+ int size;
+ } hash_table;
+
+
+/* Structures used to store macros.
+
+ Each macro knows its name and included text. It gets built with a
+ list of formal arguments, and also keeps a hash table which points
+ into the list to speed up formal search. Each formal knows its
+ name and its default value. Each time the macro is expanded, the
+ formals get the actual values attatched to them. */
+
+/* describe the formal arguments to a macro */
+
+typedef struct formal_struct
+ {
+ struct formal_struct *next; /* next formal in list */
+ sb name; /* name of the formal */
+ sb def; /* the default value */
+ sb actual; /* the actual argument (changed on each expansion) */
+ int index; /* the index of the formal 0..formal_count-1 */
+ }
+formal_entry;
+
+/* describe the macro. */
+
+typedef struct macro_struct
+ {
+ sb sub; /* substitution text. */
+ int formal_count; /* number of formal args. */
+ formal_entry *formals; /* pointer to list of formal_structs */
+ hash_table formal_hash; /* hash table of formals. */
+ }
+macro_entry;
+
+/* how we nest files and expand macros etc.
+
+ we keep a stack of of include_stack structs. each include file
+ pushes a new level onto the stack. we keep an sb with a pushback
+ too. unget chars are pushed onto the pushback sb, getchars first
+ checks the pushback sb before reading from the input stream.
+
+ small things are expanded by adding the text of the item onto the
+ pushback sb. larger items are grown by pushing a new level and
+ allocating the entire pushback buf for the item. each time
+ something like a macro is expanded, the stack index is changed. we
+ can then perform an exitm by popping all entries off the stack with
+ the same stack index. if we're being reasonable, we can detect
+ recusive expansion by checking the index is reasonably small.
+ */
+
+typedef enum
+ {
+ include_file, include_repeat, include_while, include_macro
+ } include_type;
+
+struct include_stack
+ {
+ sb pushback; /* current pushback stream */
+ int pushback_index; /* next char to read from stream */
+ FILE *handle; /* open file */
+ sb name; /* name of file */
+ int linecount; /* number of lines read so far */
+ include_type type;
+ int index; /* index of this layer */
+ }
+include_stack[MAX_INCLUDES];
+
+struct include_stack *sp;
+#define isp (sp - include_stack)
+
+/* Include file list */
+
+typedef struct include_path
+{
+ struct include_path *next;
+ sb path;
+} include_path;
+
+include_path *paths_head;
+include_path *paths_tail;
+
+
+static void quit PARAMS ((void));
+static void hash_new_table PARAMS ((int, hash_table *));
+static int hash PARAMS ((sb *));
+static hash_entry *hash_create PARAMS ((hash_table *, sb *));
+static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
+static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
+static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
+static void checkconst PARAMS ((int, exp_t *));
+static int sb_strtol PARAMS ((int, sb *, int, int *));
+static int level_0 PARAMS ((int, sb *, exp_t *));
+static int level_1 PARAMS ((int, sb *, exp_t *));
+static int level_2 PARAMS ((int, sb *, exp_t *));
+static int level_3 PARAMS ((int, sb *, exp_t *));
+static int level_4 PARAMS ((int, sb *, exp_t *));
+static int level_5 PARAMS ((int, sb *, exp_t *));
+static int exp_parse PARAMS ((int, sb *, exp_t *));
+static void exp_string PARAMS ((exp_t *, sb *));
+static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
+#if 0
+static void strip_comments PARAMS ((sb *));
+#endif
+static void unget PARAMS ((int));
+static void include_buf PARAMS ((sb *, sb *, include_type, int));
+static void include_print_where_line PARAMS ((FILE *));
+static void include_print_line PARAMS ((FILE *));
+static int get_line PARAMS ((sb *));
+static int grab_label PARAMS ((sb *, sb *));
+static void change_base PARAMS ((int, sb *, sb *));
+static void do_end PARAMS ((sb *));
+static void do_assign PARAMS ((int, int, sb *));
+static void do_radix PARAMS ((sb *));
+static int get_opsize PARAMS ((int, sb *, int *));
+static int eol PARAMS ((int, sb *));
+static void do_data PARAMS ((int, sb *, int));
+static void do_datab PARAMS ((int, sb *));
+static void do_align PARAMS ((int, sb *));
+static void do_res PARAMS ((int, sb *, int));
+static void do_export PARAMS ((sb *));
+static void do_print PARAMS ((int, sb *));
+static void do_heading PARAMS ((int, sb *));
+static void do_page PARAMS ((void));
+static void do_form PARAMS ((int, sb *));
+static int get_any_string PARAMS ((int, sb *, sb *, int, int));
+static int skip_openp PARAMS ((int, sb *));
+static int skip_closep PARAMS ((int, sb *));
+static int dolen PARAMS ((int, sb *, sb *));
+static int doinstr PARAMS ((int, sb *, sb *));
+static int dosubstr PARAMS ((int, sb *, sb *));
+static void process_assigns PARAMS ((int, sb *, sb *));
+static int get_and_process PARAMS ((int, sb *, sb *));
+static void process_file PARAMS ((void));
+static void free_old_entry PARAMS ((hash_entry *));
+static void do_assigna PARAMS ((int, sb *));
+static void do_assignc PARAMS ((int, sb *));
+static void do_reg PARAMS ((int, sb *));
+static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
+static int whatcond PARAMS ((int, sb *, int *));
+static int istrue PARAMS ((int, sb *));
+static void do_aif PARAMS ((int, sb *));
+static void do_aelse PARAMS ((void));
+static void do_aendi PARAMS ((void));
+static int condass_on PARAMS ((void));
+static void do_if PARAMS ((int, sb *, int));
+static int get_mri_string PARAMS ((int, sb *, sb *, int));
+static void do_ifc PARAMS ((int, sb *, int));
+static void do_aendr PARAMS ((void));
+static void do_awhile PARAMS ((int, sb *));
+static void do_aendw PARAMS ((void));
+static void do_exitm PARAMS ((void));
+static void do_arepeat PARAMS ((int, sb *));
+static void do_endm PARAMS ((void));
+static void do_irp PARAMS ((int, sb *, int));
+static void do_local PARAMS ((int, sb *));
+static void do_macro PARAMS ((int, sb *));
+static int macro_op PARAMS ((int, sb *));
+static int getstring PARAMS ((int, sb *, sb *));
+static void do_sdata PARAMS ((int, sb *, int));
+static void do_sdatab PARAMS ((int, sb *));
+static int new_file PARAMS ((const char *));
+static void do_include PARAMS ((int, sb *));
+static void include_pop PARAMS ((void));
+static int get PARAMS ((void));
+static int linecount PARAMS ((void));
+static int include_next_index PARAMS ((void));
+static void chartype_init PARAMS ((void));
+static int process_pseudo_op PARAMS ((int, sb *, sb *));
+static void add_keyword PARAMS ((const char *, int));
+static void process_init PARAMS ((void));
+static void do_define PARAMS ((const char *));
+static void show_usage PARAMS ((FILE *, int));
+static void show_help PARAMS ((void));
+
+#define FATAL(x) \
+ do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0)
+#define ERROR(x) \
+ do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
+#define WARNING(x) \
+ do { include_print_where_line (stderr); fprintf x; warnings++;} while(0)
+
+
+
+/* exit the program and return the right ERROR code. */
+static void
+quit ()
+{
+ int exitcode;
+ if (fatals + errors)
+ exitcode = 1;
+ else
+ exitcode = 0;
+
+ if (stats)
+ {
+ int i;
+ for (i = 0; i < sb_max_power_two; i++)
+ {
+ fprintf (stderr, "strings size %8d : %d\n", 1<<i, string_count[i]);
+ }
+ }
+ exit (exitcode);
+}
+
+/* hash table maintenance. */
+
+/* build a new hash table with size buckets, and fill in the info at ptr. */
+
+static void
+hash_new_table (size, ptr)
+ int size;
+ hash_table *ptr;
+{
+ int i;
+ ptr->size = size;
+ ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
+ /* Fill with null-pointer, not zero-bit-pattern. */
+ for (i = 0; i < size; i++)
+ ptr->table[i] = 0;
+}
+
+/* calculate and return the hash value of the sb at key. */
+
+static int
+hash (key)
+ sb *key;
+{
+ int k = 0x1234;
+ int i;
+ char *p = key->ptr;
+ for (i = 0; i < key->len; i++)
+ {
+ k ^= (k << 2) ^ *p;
+ p++;
+ }
+ return k & 0xf0fff;
+}
+
+/* lookup key in hash_table tab, if present, then return it, otherwise
+ build a new one and fill it with hash_integer. */
+
+static
+hash_entry *
+hash_create (tab, key)
+ hash_table *tab;
+ sb *key;
+{
+ int k = hash (key) % tab->size;
+ hash_entry *p;
+ hash_entry **table = tab->table;
+
+ p = table[k];
+
+ while (1)
+ {
+ if (!p)
+ {
+ hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
+ n->next = table[k];
+ sb_new (&n->key);
+ sb_add_sb (&n->key, key);
+ table[k] = n;
+ n->type = hash_integer;
+ return n;
+ }
+ if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
+ {
+ return p;
+ }
+ p = p->next;
+ }
+}
+
+/* add sb name with key into hash_table tab. if replacing old value
+ and again, then ERROR. */
+
+static
+void
+hash_add_to_string_table (tab, key, name, again)
+ hash_table *tab;
+ sb *key;
+ sb *name;
+ int again;
+{
+ hash_entry *ptr = hash_create (tab, key);
+ if (ptr->type == hash_integer)
+ {
+ sb_new (&ptr->value.s);
+ }
+ if (ptr->value.s.len)
+ {
+ if (!again)
+ ERROR ((stderr, _("redefinition not allowed\n")));
+ }
+
+ ptr->type = hash_string;
+ sb_reset (&ptr->value.s);
+
+ sb_add_sb (&ptr->value.s, name);
+}
+
+/* add integer name to hash_table tab with sb key. */
+
+static
+void
+hash_add_to_int_table (tab, key, name)
+ hash_table *tab;
+ sb *key;
+ int name;
+{
+ hash_entry *ptr = hash_create (tab, key);
+ ptr->value.i = name;
+}
+
+/* lookup sb key in hash_table tab. if found return hash_entry result,
+ else 0. */
+
+static
+hash_entry *
+hash_lookup (tab, key)
+ hash_table *tab;
+ sb *key;
+{
+ int k = hash (key) % tab->size;
+ hash_entry **table = tab->table;
+ hash_entry *p = table[k];
+ while (p)
+ {
+ if (p->key.len == key->len
+ && strncmp (p->key.ptr, key->ptr, key->len) == 0)
+ return p;
+ p = p->next;
+ }
+ return 0;
+}
+
+
+/* expressions
+
+ are handled in a really simple recursive decent way. each bit of
+ the machine takes an index into an sb and a pointer to an exp_t,
+ modifies the *exp_t and returns the index of the first character
+ past the part of the expression parsed.
+
+ expression precedence:
+ ( )
+ unary + - ~
+ * /
+ + -
+ &
+ | ~
+
+*/
+
+
+/* make sure that the exp_t at term is constant, if not the give the op ERROR. */
+
+static
+void
+checkconst (op, term)
+ int op;
+ exp_t *term;
+{
+ if (term->add_symbol.len
+ || term->sub_symbol.len)
+ {
+ ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op));
+ }
+}
+
+/* turn the number in string at idx into a number of base,
+ fill in ptr and return the index of the first character not in the
+ number. */
+
+static
+int
+sb_strtol (idx, string, base, ptr)
+ int idx;
+ sb *string;
+ int base;
+ int *ptr;
+{
+ int value = 0;
+ idx = sb_skip_white (idx, string);
+
+ while (idx < string->len)
+ {
+ int ch = string->ptr[idx];
+ int dig = 0;
+ if (isdigit (ch))
+ dig = ch - '0';
+ else if (ch >= 'a' && ch <= 'f')
+ dig = ch - 'a' + 10;
+ else if (ch >= 'A' && ch <= 'F')
+ dig = ch - 'A' + 10;
+ else
+ break;
+
+ if (dig >= base)
+ break;
+
+ value = value * base + dig;
+ idx++;
+ }
+ *ptr = value;
+ return idx;
+}
+
+static int
+level_0 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ lhs->add_symbol.len = 0;
+ lhs->add_symbol.name = 0;
+
+ lhs->sub_symbol.len = 0;
+ lhs->sub_symbol.name = 0;
+
+ idx = sb_skip_white (idx, string);
+
+ lhs->value = 0;
+
+ if (isdigit ((unsigned char) string->ptr[idx]))
+ {
+ idx = sb_strtol (idx, string, 10, &lhs->value);
+ }
+ else if (ISFIRSTCHAR (string->ptr[idx]))
+ {
+ int len = 0;
+ lhs->add_symbol.name = string->ptr + idx;
+ while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
+ {
+ idx++;
+ len++;
+ }
+ lhs->add_symbol.len = len;
+ }
+ else if (string->ptr[idx] == '"')
+ {
+ sb acc;
+ sb_new (&acc);
+ ERROR ((stderr, _("string where expression expected.\n")));
+ idx = getstring (idx, string, &acc);
+ sb_kill (&acc);
+ }
+ else
+ {
+ ERROR ((stderr, _("can't find primary in expression.\n")));
+ idx++;
+ }
+ return sb_skip_white (idx, string);
+}
+
+
+
+static int
+level_1 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ idx = sb_skip_white (idx, string);
+
+ switch (string->ptr[idx])
+ {
+ case '+':
+ idx = level_1 (idx + 1, string, lhs);
+ break;
+ case '~':
+ idx = level_1 (idx + 1, string, lhs);
+ checkconst ('~', lhs);
+ lhs->value = ~lhs->value;
+ break;
+ case '-':
+ {
+ symbol t;
+ idx = level_1 (idx + 1, string, lhs);
+ lhs->value = -lhs->value;
+ t = lhs->add_symbol;
+ lhs->add_symbol = lhs->sub_symbol;
+ lhs->sub_symbol = t;
+ break;
+ }
+ case '(':
+ idx++;
+ idx = level_5 (sb_skip_white (idx, string), string, lhs);
+ if (string->ptr[idx] != ')')
+ ERROR ((stderr, _("misplaced closing parens.\n")));
+ else
+ idx++;
+ break;
+ default:
+ idx = level_0 (idx, string, lhs);
+ break;
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_2 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_1 (idx, string, lhs);
+
+ while (idx < string->len && (string->ptr[idx] == '*'
+ || string->ptr[idx] == '/'))
+ {
+ char op = string->ptr[idx++];
+ idx = level_1 (idx, string, &rhs);
+ switch (op)
+ {
+ case '*':
+ checkconst ('*', lhs);
+ checkconst ('*', &rhs);
+ lhs->value *= rhs.value;
+ break;
+ case '/':
+ checkconst ('/', lhs);
+ checkconst ('/', &rhs);
+ if (rhs.value == 0)
+ ERROR ((stderr, _("attempt to divide by zero.\n")));
+ else
+ lhs->value /= rhs.value;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+
+static int
+level_3 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_2 (idx, string, lhs);
+
+ while (idx < string->len
+ && (string->ptr[idx] == '+'
+ || string->ptr[idx] == '-'))
+ {
+ char op = string->ptr[idx++];
+ idx = level_2 (idx, string, &rhs);
+ switch (op)
+ {
+ case '+':
+ lhs->value += rhs.value;
+ if (lhs->add_symbol.name && rhs.add_symbol.name)
+ {
+ ERROR ((stderr, _("can't add two relocatable expressions\n")));
+ }
+ /* change nn+symbol to symbol + nn */
+ if (rhs.add_symbol.name)
+ {
+ lhs->add_symbol = rhs.add_symbol;
+ }
+ break;
+ case '-':
+ lhs->value -= rhs.value;
+ lhs->sub_symbol = rhs.add_symbol;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_4 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_3 (idx, string, lhs);
+
+ while (idx < string->len &&
+ string->ptr[idx] == '&')
+ {
+ char op = string->ptr[idx++];
+ idx = level_3 (idx, string, &rhs);
+ switch (op)
+ {
+ case '&':
+ checkconst ('&', lhs);
+ checkconst ('&', &rhs);
+ lhs->value &= rhs.value;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+static int
+level_5 (idx, string, lhs)
+ int idx;
+ sb *string;
+ exp_t *lhs;
+{
+ exp_t rhs;
+
+ idx = level_4 (idx, string, lhs);
+
+ while (idx < string->len
+ && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
+ {
+ char op = string->ptr[idx++];
+ idx = level_4 (idx, string, &rhs);
+ switch (op)
+ {
+ case '|':
+ checkconst ('|', lhs);
+ checkconst ('|', &rhs);
+ lhs->value |= rhs.value;
+ break;
+ case '~':
+ checkconst ('~', lhs);
+ checkconst ('~', &rhs);
+ lhs->value ^= rhs.value;
+ break;
+ }
+ }
+ return sb_skip_white (idx, string);
+}
+
+
+/* parse the expression at offset idx into string, fill up res with
+ the result. return the index of the first char past the expression.
+ */
+
+static int
+exp_parse (idx, string, res)
+ int idx;
+ sb *string;
+ exp_t *res;
+{
+ return level_5 (sb_skip_white (idx, string), string, res);
+}
+
+
+/* turn the expression at exp into text and glue it onto the end of
+ string. */
+
+static void
+exp_string (exp, string)
+ exp_t *exp;
+ sb *string;
+{
+ int np = 0;
+ int ad = 0;
+ sb_reset (string);
+
+ if (exp->add_symbol.len)
+ {
+ sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
+ np = 1;
+ ad = 1;
+ }
+ if (exp->value)
+ {
+ char buf[20];
+ if (np)
+ sb_add_char (string, '+');
+ sprintf (buf, "%d", exp->value);
+ sb_add_string (string, buf);
+ np = 1;
+ ad = 1;
+ }
+ if (exp->sub_symbol.len)
+ {
+ sb_add_char (string, '-');
+ sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
+ np = 0;
+ ad = 1;
+ }
+
+ if (!ad)
+ sb_add_char (string, '0');
+}
+
+
+/* parse the expression at offset idx into sb in, return the value in val.
+ if the expression is not constant, give ERROR emsg. returns the index
+ of the first character past the end of the expression. */
+
+static int
+exp_get_abs (emsg, idx, in, val)
+ const char *emsg;
+ int idx;
+ sb *in;
+ int *val;
+{
+ exp_t res;
+ idx = exp_parse (idx, in, &res);
+ if (res.add_symbol.len || res.sub_symbol.len)
+ ERROR ((stderr, emsg));
+ *val = res.value;
+ return idx;
+}
+
+
+sb label; /* current label parsed from line */
+hash_table assign_hash_table; /* hash table for all assigned variables */
+hash_table keyword_hash_table; /* hash table for keyword */
+hash_table vars; /* hash table for eq variables */
+
+#define in_comment ';'
+
+#if 0
+static void
+strip_comments (out)
+ sb *out;
+{
+ char *s = out->ptr;
+ int i = 0;
+ for (i = 0; i < out->len; i++)
+ {
+ if (ISCOMMENTCHAR(s[i]))
+ {
+ out->len = i;
+ return;
+ }
+ }
+}
+#endif
+
+/* push back character ch so that it can be read again. */
+
+static void
+unget (ch)
+ int ch;
+{
+ if (ch == '\n')
+ {
+ sp->linecount--;
+ }
+ if (sp->pushback_index)
+ sp->pushback_index--;
+ else
+ sb_add_char (&sp->pushback, ch);
+}
+
+/* push the sb ptr onto the include stack, with the given name, type and index. */
+
+static
+void
+include_buf (name, ptr, type, index)
+ sb *name;
+ sb *ptr;
+ include_type type;
+ int index;
+{
+ sp++;
+ if (sp - include_stack >= MAX_INCLUDES)
+ FATAL ((stderr, _("unreasonable nesting.\n")));
+ sb_new (&sp->name);
+ sb_add_sb (&sp->name, name);
+ sp->handle = 0;
+ sp->linecount = 1;
+ sp->pushback_index = 0;
+ sp->type = type;
+ sp->index = index;
+ sb_new (&sp->pushback);
+ sb_add_sb (&sp->pushback, ptr);
+}
+
+
+/* used in ERROR messages, print info on where the include stack is onto file. */
+static
+void
+include_print_where_line (file)
+ FILE *file;
+{
+ struct include_stack *p = include_stack + 1;
+
+ while (p <= sp)
+ {
+ fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
+ p++;
+ }
+}
+
+/* used in listings, print the line number onto file. */
+static void
+include_print_line (file)
+ FILE *file;
+{
+ int n;
+ struct include_stack *p = include_stack + 1;
+
+ n = fprintf (file, "%4d", p->linecount);
+ p++;
+ while (p <= sp)
+ {
+ n += fprintf (file, ".%d", p->linecount);
+ p++;
+ }
+ while (n < 8 * 3)
+ {
+ fprintf (file, " ");
+ n++;
+ }
+}
+
+
+/* read a line from the top of the include stack into sb in. */
+
+static int
+get_line (in)
+ sb *in;
+{
+ int online = 0;
+ int more = 1;
+
+ if (copysource)
+ {
+ putc (comment_char, outfile);
+ if (print_line_number)
+ include_print_line (outfile);
+ }
+
+ while (1)
+ {
+ int ch = get ();
+
+ while (ch == '\r')
+ ch = get ();
+
+ if (ch == EOF)
+ {
+ if (online)
+ {
+ WARNING ((stderr, _("End of file not at start of line.\n")));
+ if (copysource)
+ putc ('\n', outfile);
+ ch = '\n';
+ }
+ else
+ more = 0;
+ break;
+ }
+
+ if (copysource)
+ {
+ putc (ch, outfile);
+ }
+
+ if (ch == '\n')
+ {
+ ch = get ();
+ online = 0;
+ if (ch == '+')
+ {
+ /* continued line */
+ if (copysource)
+ {
+ putc (comment_char, outfile);
+ putc ('+', outfile);
+ }
+ ch = get ();
+ }
+ else
+ {
+ if (ch != EOF)
+ unget (ch);
+ break;
+ }
+ }
+ else
+ {
+ sb_add_char (in, ch);
+ }
+ online++;
+ }
+
+ return more;
+}
+
+/* find a label from sb in and put it in out. */
+
+static int
+grab_label (in, out)
+ sb *in;
+ sb *out;
+{
+ int i = 0;
+ sb_reset (out);
+ if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')
+ {
+ sb_add_char (out, in->ptr[i]);
+ i++;
+ while ((ISNEXTCHAR (in->ptr[i])
+ || in->ptr[i] == '\\'
+ || in->ptr[i] == '&')
+ && i < in->len)
+ {
+ sb_add_char (out, in->ptr[i]);
+ i++;
+ }
+ }
+ return i;
+}
+
+/* find all strange base stuff and turn into decimal. also
+ find all the other numbers and convert them from the default radix */
+
+static void
+change_base (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ char buffer[20];
+
+ while (idx < in->len)
+ {
+ if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '(')
+ {
+ idx += 2;
+ while (idx < in->len
+ && in->ptr[idx] != ')')
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ if (idx < in->len)
+ idx++;
+ }
+ else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
+ {
+ int base;
+ int value;
+ switch (in->ptr[idx])
+ {
+ case 'b':
+ case 'B':
+ base = 2;
+ break;
+ case 'q':
+ case 'Q':
+ base = 8;
+ break;
+ case 'h':
+ case 'H':
+ base = 16;
+ break;
+ case 'd':
+ case 'D':
+ base = 10;
+ break;
+ default:
+ ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));
+ base = 10;
+ break;
+ }
+
+ idx = sb_strtol (idx + 2, in, base, &value);
+ sprintf (buffer, "%d", value);
+ sb_add_string (out, buffer);
+ }
+ else if (ISFIRSTCHAR (in->ptr[idx]))
+ {
+ /* copy entire names through quickly */
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+ else if (isdigit ((unsigned char) in->ptr[idx]))
+ {
+ int value;
+ /* all numbers must start with a digit, let's chew it and
+ spit out decimal */
+ idx = sb_strtol (idx, in, radix, &value);
+ sprintf (buffer, "%d", value);
+ sb_add_string (out, buffer);
+
+ /* skip all undigsested letters */
+ while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ /* copy entire names through quickly */
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ while (idx < in->len && in->ptr[idx] != tchar)
+ {
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+ else
+ {
+ /* nothing special, just pass it through */
+ sb_add_char (out, in->ptr[idx]);
+ idx++;
+ }
+ }
+
+}
+
+/* .end */
+static void
+do_end (in)
+ sb *in;
+{
+ had_end = 1;
+ if (mri)
+ fprintf (outfile, "%s\n", sb_name (in));
+}
+
+/* .assign */
+
+static void
+do_assign (again, idx, in)
+ int again;
+ int idx;
+ sb *in;
+{
+ /* stick label in symbol table with following value */
+ exp_t e;
+ sb acc;
+
+ sb_new (&acc);
+ idx = exp_parse (idx, in, &e);
+ exp_string (&e, &acc);
+ hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
+ sb_kill (&acc);
+}
+
+
+/* .radix [b|q|d|h] */
+
+static
+void
+do_radix (ptr)
+ sb *ptr;
+{
+ int idx = sb_skip_white (0, ptr);
+ switch (ptr->ptr[idx])
+ {
+ case 'B':
+ case 'b':
+ radix = 2;
+ break;
+ case 'q':
+ case 'Q':
+ radix = 8;
+ break;
+ case 'd':
+ case 'D':
+ radix = 10;
+ break;
+ case 'h':
+ case 'H':
+ radix = 16;
+ break;
+ default:
+ ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));
+ }
+}
+
+
+/* Parse off a .b, .w or .l */
+
+static int
+get_opsize (idx, in, size)
+ int idx;
+ sb *in;
+ int *size;
+{
+ *size = 4;
+ if (in->ptr[idx] == '.')
+ {
+ idx++;
+ }
+ switch (in->ptr[idx])
+ {
+ case 'b':
+ case 'B':
+ *size = 1;
+ break;
+ case 'w':
+ case 'W':
+ *size = 2;
+ break;
+ case 'l':
+ case 'L':
+ *size = 4;
+ break;
+ case ' ':
+ case '\t':
+ break;
+ default:
+ ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx]));
+ break;
+ }
+ idx++;
+
+ return idx;
+}
+
+static
+int eol(idx, line)
+ int idx;
+ sb *line;
+{
+ idx = sb_skip_white (idx, line);
+ if (idx < line->len
+ && ISCOMMENTCHAR(line->ptr[idx]))
+ return 1;
+ if (idx >= line->len)
+ return 1;
+ return 0;
+}
+
+/* .data [.b|.w|.l] <data>*
+ or d[bwl] <data>* */
+
+static void
+do_data (idx, in, size)
+ int idx;
+ sb *in;
+ int size;
+{
+ int opsize = 4;
+ char *opname = ".yikes!";
+ sb acc;
+ sb_new (&acc);
+
+ if (!size)
+ {
+ idx = get_opsize (idx, in, &opsize);
+ }
+ else {
+ opsize = size;
+ }
+ switch (opsize)
+ {
+ case 4:
+ opname = ".long";
+ break;
+ case 2:
+ opname = ".short";
+ break;
+ case 1:
+ opname = ".byte";
+ break;
+ }
+
+
+ fprintf (outfile, "%s\t", opname);
+
+ idx = sb_skip_white (idx, in);
+
+ if (alternate
+ && idx < in->len
+ && in->ptr[idx] == '"')
+ {
+ int i;
+ idx = getstring (idx, in, &acc);
+ for (i = 0; i < acc.len; i++)
+ {
+ if (i)
+ fprintf(outfile,",");
+ fprintf (outfile, "%d", acc.ptr[i]);
+ }
+ }
+ else
+ {
+ while (!eol (idx, in))
+ {
+ exp_t e;
+ idx = exp_parse (idx, in, &e);
+ exp_string (&e, &acc);
+ sb_add_char (&acc, 0);
+ fprintf (outfile, acc.ptr);
+ if (idx < in->len && in->ptr[idx] == ',')
+ {
+ fprintf (outfile, ",");
+ idx++;
+ }
+ }
+ }
+ sb_kill (&acc);
+ sb_print_at (outfile, idx, in);
+ fprintf (outfile, "\n");
+}
+
+/* .datab [.b|.w|.l] <repeat>,<fill> */
+
+static void
+do_datab (idx, in)
+ int idx;
+ sb *in;
+{
+ int opsize;
+ int repeat;
+ int fill;
+
+ idx = get_opsize (idx, in, &opsize);
+
+ idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat);
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill);
+
+ fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
+}
+
+/* .align <size> */
+
+static void
+do_align (idx, in)
+ int idx;
+ sb *in;
+{
+ int al, have_fill, fill;
+
+ idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al);
+ idx = sb_skip_white (idx, in);
+ have_fill = 0;
+ fill = 0;
+ if (! eol (idx, in))
+ {
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in,
+ &fill);
+ have_fill = 1;
+ }
+
+ if (al != 1
+ && al != 2
+ && al != 4)
+ WARNING ((stderr, _("alignment must be one of 1, 2 or 4.\n")));
+
+ fprintf (outfile, ".align %d", al);
+ if (have_fill)
+ fprintf (outfile, ",%d", fill);
+ fprintf (outfile, "\n");
+}
+
+/* .res[.b|.w|.l] <size> */
+
+static void
+do_res (idx, in, type)
+ int idx;
+ sb *in;
+ int type;
+{
+ int size = 4;
+ int count = 0;
+
+ idx = get_opsize (idx, in, &size);
+ while (!eol(idx, in))
+ {
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] == ',')
+ idx++;
+ idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count);
+
+ if (type == 'c' || type == 'z')
+ count++;
+
+ fprintf (outfile, ".space %d\n", count * size);
+ }
+}
+
+
+/* .export */
+
+static void
+do_export (in)
+ sb *in;
+{
+ fprintf (outfile, ".global %s\n", sb_name (in));
+}
+
+/* .print [list] [nolist] */
+
+static void
+do_print (idx, in)
+ int idx;
+ sb *in;
+{
+ idx = sb_skip_white (idx, in);
+ while (idx < in->len)
+ {
+ if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
+ {
+ fprintf (outfile, ".list\n");
+ idx += 4;
+ }
+ else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
+ {
+ fprintf (outfile, ".nolist\n");
+ idx += 6;
+ }
+ idx++;
+ }
+}
+
+/* .head */
+static void
+do_heading (idx, in)
+ int idx;
+ sb *in;
+{
+ sb head;
+ sb_new (&head);
+ idx = getstring (idx, in, &head);
+ fprintf (outfile, ".title \"%s\"\n", sb_name (&head));
+ sb_kill (&head);
+}
+
+/* .page */
+
+static void
+do_page ()
+{
+ fprintf (outfile, ".eject\n");
+}
+
+/* .form [lin=<value>] [col=<value>] */
+static void
+do_form (idx, in)
+ int idx;
+ sb *in;
+{
+ int lines = 60;
+ int columns = 132;
+ idx = sb_skip_white (idx, in);
+
+ while (idx < in->len)
+ {
+
+ if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
+ {
+ idx += 4;
+ idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines);
+ }
+
+ if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0)
+ {
+ idx += 4;
+ idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns);
+ }
+
+ idx++;
+ }
+ fprintf (outfile, ".psize %d,%d\n", lines, columns);
+
+}
+
+
+/* Fetch string from the input stream,
+ rules:
+ 'Bxyx<whitespace> -> return 'Bxyza
+ %<char> -> return string of decimal value of x
+ "<string>" -> return string
+ xyx<whitespace> -> return xyz
+*/
+static int
+get_any_string (idx, in, out, expand, pretend_quoted)
+ int idx;
+ sb *in;
+ sb *out;
+ int expand;
+ int pretend_quoted;
+{
+ sb_reset (out);
+ idx = sb_skip_white (idx, in);
+
+ if (idx < in->len)
+ {
+ if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
+ {
+ while (!ISSEP (in->ptr[idx]))
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ else if (in->ptr[idx] == '%'
+ && alternate
+ && expand)
+ {
+ int val;
+ char buf[20];
+ /* Turns the next expression into a string */
+ idx = exp_get_abs (_("% operator needs absolute expression"),
+ idx + 1,
+ in,
+ &val);
+ sprintf(buf, "%d", val);
+ sb_add_string (out, buf);
+ }
+ else if (in->ptr[idx] == '"'
+ || in->ptr[idx] == '<'
+ || (alternate && in->ptr[idx] == '\''))
+ {
+ if (alternate && expand)
+ {
+ /* Keep the quotes */
+ sb_add_char (out, '\"');
+
+ idx = getstring (idx, in, out);
+ sb_add_char (out, '\"');
+
+ }
+ else {
+ idx = getstring (idx, in, out);
+ }
+ }
+ else
+ {
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\''
+ || pretend_quoted
+ || !ISSEP (in->ptr[idx])))
+ {
+ if (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ sb_add_char (out, in->ptr[idx++]);
+ while (idx < in->len
+ && in->ptr[idx] != tchar)
+ sb_add_char (out, in->ptr[idx++]);
+ if (idx == in->len)
+ return idx;
+ }
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ }
+ }
+
+ return idx;
+}
+
+
+/* skip along sb in starting at idx, suck off whitespace a ( and more
+ whitespace. return the idx of the next char */
+
+static int
+skip_openp (idx, in)
+ int idx;
+ sb *in;
+{
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] != '(')
+ ERROR ((stderr, _("misplaced ( .\n")));
+ idx = sb_skip_white (idx + 1, in);
+ return idx;
+}
+
+/* skip along sb in starting at idx, suck off whitespace a ) and more
+ whitespace. return the idx of the next char */
+
+static int
+skip_closep (idx, in)
+ int idx;
+ sb *in;
+{
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] != ')')
+ ERROR ((stderr, _("misplaced ).\n")));
+ idx = sb_skip_white (idx + 1, in);
+ return idx;
+}
+
+/* .len */
+
+static int
+dolen (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+
+ sb stringout;
+ char buffer[10];
+
+ sb_new (&stringout);
+ idx = skip_openp (idx, in);
+ idx = get_and_process (idx, in, &stringout);
+ idx = skip_closep (idx, in);
+ sprintf (buffer, "%d", stringout.len);
+ sb_add_string (out, buffer);
+
+ sb_kill (&stringout);
+ return idx;
+}
+
+
+/* .instr */
+
+static
+int
+doinstr (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ sb string;
+ sb search;
+ int i;
+ int start;
+ int res;
+ char buffer[10];
+
+ sb_new (&string);
+ sb_new (&search);
+ idx = skip_openp (idx, in);
+ idx = get_and_process (idx, in, &string);
+ idx = sb_skip_comma (idx, in);
+ idx = get_and_process (idx, in, &search);
+ idx = sb_skip_comma (idx, in);
+ if (isdigit ((unsigned char) in->ptr[idx]))
+ {
+ idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start);
+ }
+ else
+ {
+ start = 0;
+ }
+ idx = skip_closep (idx, in);
+ res = -1;
+ for (i = start; i < string.len; i++)
+ {
+ if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
+ {
+ res = i;
+ break;
+ }
+ }
+ sprintf (buffer, "%d", res);
+ sb_add_string (out, buffer);
+ sb_kill (&string);
+ sb_kill (&search);
+ return idx;
+}
+
+
+static int
+dosubstr (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ sb string;
+ int pos;
+ int len;
+ sb_new (&string);
+
+ idx = skip_openp (idx, in);
+ idx = get_and_process (idx, in, &string);
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos);
+ idx = sb_skip_comma (idx, in);
+ idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len);
+ idx = skip_closep (idx, in);
+
+
+ if (len < 0 || pos < 0 ||
+ pos > string.len
+ || pos + len > string.len)
+ {
+ sb_add_string (out, " ");
+ }
+ else
+ {
+ sb_add_char (out, '"');
+ while (len > 0)
+ {
+ sb_add_char (out, string.ptr[pos++]);
+ len--;
+ }
+ sb_add_char (out, '"');
+ }
+ sb_kill(&string);
+ return idx;
+}
+
+/* scan line, change tokens in the hash table to their replacements */
+static void
+process_assigns (idx, in, buf)
+ int idx;
+ sb *in;
+ sb *buf;
+{
+ while (idx < in->len)
+ {
+ hash_entry *ptr;
+ if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '(')
+ {
+ do
+ {
+ sb_add_char (buf, in->ptr[idx]);
+ idx++;
+ }
+ while (idx < in->len && in->ptr[idx - 1] != ')');
+ }
+ else if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '&')
+ {
+ idx = condass_lookup_name (in, idx + 2, buf, 1);
+ }
+ else if (in->ptr[idx] == '\\'
+ && idx + 1 < in->len
+ && in->ptr[idx + 1] == '$')
+ {
+ idx = condass_lookup_name (in, idx + 2, buf, 0);
+ }
+ else if (idx + 3 < in->len
+ && in->ptr[idx] == '.'
+ && toupper ((unsigned char) in->ptr[idx + 1]) == 'L'
+ && toupper ((unsigned char) in->ptr[idx + 2]) == 'E'
+ && toupper ((unsigned char) in->ptr[idx + 3]) == 'N')
+ idx = dolen (idx + 4, in, buf);
+ else if (idx + 6 < in->len
+ && in->ptr[idx] == '.'
+ && toupper ((unsigned char) in->ptr[idx + 1]) == 'I'
+ && toupper ((unsigned char) in->ptr[idx + 2]) == 'N'
+ && toupper ((unsigned char) in->ptr[idx + 3]) == 'S'
+ && toupper ((unsigned char) in->ptr[idx + 4]) == 'T'
+ && toupper ((unsigned char) in->ptr[idx + 5]) == 'R')
+ idx = doinstr (idx + 6, in, buf);
+ else if (idx + 7 < in->len
+ && in->ptr[idx] == '.'
+ && toupper ((unsigned char) in->ptr[idx + 1]) == 'S'
+ && toupper ((unsigned char) in->ptr[idx + 2]) == 'U'
+ && toupper ((unsigned char) in->ptr[idx + 3]) == 'B'
+ && toupper ((unsigned char) in->ptr[idx + 4]) == 'S'
+ && toupper ((unsigned char) in->ptr[idx + 5]) == 'T'
+ && toupper ((unsigned char) in->ptr[idx + 6]) == 'R')
+ idx = dosubstr (idx + 7, in, buf);
+ else if (ISFIRSTCHAR (in->ptr[idx]))
+ {
+ /* may be a simple name subsitution, see if we have a word */
+ sb acc;
+ int cur = idx + 1;
+ while (cur < in->len
+ && (ISNEXTCHAR (in->ptr[cur])))
+ cur++;
+
+ sb_new (&acc);
+ sb_add_buffer (&acc, in->ptr + idx, cur - idx);
+ ptr = hash_lookup (&assign_hash_table, &acc);
+ if (ptr)
+ {
+ /* Found a definition for it */
+ sb_add_sb (buf, &ptr->value.s);
+ }
+ else
+ {
+ /* No definition, just copy the word */
+ sb_add_sb (buf, &acc);
+ }
+ sb_kill (&acc);
+ idx = cur;
+ }
+ else
+ {
+ sb_add_char (buf, in->ptr[idx++]);
+ }
+ }
+}
+
+static int
+get_and_process (idx, in, out)
+ int idx;
+ sb *in;
+ sb *out;
+{
+ sb t;
+ sb_new (&t);
+ idx = get_any_string (idx, in, &t, 1, 0);
+ process_assigns (0, &t, out);
+ sb_kill (&t);
+ return idx;
+}
+
+static
+void
+process_file ()
+{
+ sb line;
+ sb t1, t2;
+ sb acc;
+ sb label_in;
+ int more;
+
+ sb_new (&line);
+ sb_new (&t1);
+ sb_new (&t2);
+ sb_new(&acc);
+ sb_new (&label_in);
+ sb_reset (&line);
+ more = get_line (&line);
+ while (more)
+ {
+ /* Find any label and pseudo op that we're intested in */
+ int l;
+ if (line.len == 0)
+ {
+ if (condass_on ())
+ fprintf (outfile, "\n");
+ }
+ else if (mri
+ && (line.ptr[0] == '*'
+ || line.ptr[0] == '!'))
+ {
+ /* MRI line comment. */
+ fprintf (outfile, sb_name (&line));
+ }
+ else
+ {
+ l = grab_label (&line, &label_in);
+ sb_reset (&label);
+
+ if (line.ptr[l] == ':')
+ l++;
+ while (ISWHITE (line.ptr[l]) && l < line.len)
+ l++;
+
+ if (label_in.len)
+ {
+ int do_assigns;
+
+ /* Munge the label, unless this is EQU or ASSIGN. */
+ do_assigns = 1;
+ if (l < line.len
+ && (line.ptr[l] == '.' || alternate || mri))
+ {
+ int lx = l;
+
+ if (line.ptr[lx] == '.')
+ ++lx;
+ if (lx + 3 <= line.len
+ && strncasecmp ("EQU", line.ptr + lx, 3) == 0
+ && (lx + 3 == line.len
+ || ! ISFIRSTCHAR (line.ptr[lx + 3])))
+ do_assigns = 0;
+ else if (lx + 6 <= line.len
+ && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0
+ && (lx + 6 == line.len
+ || ! ISFIRSTCHAR (line.ptr[lx + 6])))
+ do_assigns = 0;
+ }
+
+ if (do_assigns)
+ process_assigns (0, &label_in, &label);
+ else
+ sb_add_sb (&label, &label_in);
+ }
+
+ if (l < line.len)
+ {
+ if (process_pseudo_op (l, &line, &acc))
+ {
+
+
+
+ }
+ else if (condass_on ())
+ {
+ if (macro_op (l, &line))
+ {
+
+
+ }
+ else
+ {
+ {
+ if (label.len)
+ {
+ fprintf (outfile, "%s:\t", sb_name (&label));
+ }
+ else
+ fprintf (outfile, "\t");
+ sb_reset(&t1);
+ process_assigns (l, &line, &t1);
+ sb_reset (&t2);
+ change_base (0, &t1, &t2);
+ fprintf (outfile, "%s\n", sb_name (&t2));
+ }
+ }
+ }
+ }
+ else {
+ /* Only a label on this line */
+ if (label.len && condass_on())
+ {
+ fprintf (outfile, "%s:\n", sb_name (&label));
+ }
+ }
+ }
+
+ if (had_end)
+ break;
+ sb_reset (&line);
+ more = get_line (&line);
+ }
+
+ if (!had_end && !mri)
+ WARNING ((stderr, _("END missing from end of file.\n")));
+}
+
+
+
+
+
+static void
+free_old_entry (ptr)
+ hash_entry *ptr;
+{
+ if (ptr)
+ {
+ if (ptr->type == hash_string)
+ sb_kill(&ptr->value.s);
+ }
+}
+
+/* name: .ASSIGNA <value> */
+
+static void
+do_assigna (idx, in)
+ int idx;
+ sb *in;
+{
+ sb tmp;
+ int val;
+ sb_new (&tmp);
+
+ process_assigns (idx, in, &tmp);
+ idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val);
+
+ if (!label.len)
+ {
+ ERROR ((stderr, _(".ASSIGNA without label.\n")));
+ }
+ else
+ {
+ hash_entry *ptr = hash_create (&vars, &label);
+ free_old_entry (ptr);
+ ptr->type = hash_integer;
+ ptr->value.i = val;
+ }
+ sb_kill (&tmp);
+}
+
+/* name: .ASSIGNC <string> */
+
+static void
+do_assignc (idx, in)
+ int idx;
+ sb *in;
+{
+ sb acc;
+ sb_new (&acc);
+ idx = getstring (idx, in, &acc);
+
+ if (!label.len)
+ {
+ ERROR ((stderr, _(".ASSIGNS without label.\n")));
+ }
+ else
+ {
+ hash_entry *ptr = hash_create (&vars, &label);
+ free_old_entry (ptr);
+ ptr->type = hash_string;
+ sb_new (&ptr->value.s);
+ sb_add_sb (&ptr->value.s, &acc);
+ }
+ sb_kill (&acc);
+}
+
+
+/* name: .REG (reg) */
+
+static void
+do_reg (idx, in)
+ int idx;
+ sb *in;
+{
+ /* remove reg stuff from inside parens */
+ sb what;
+ if (!mri)
+ idx = skip_openp (idx, in);
+ else
+ idx = sb_skip_white (idx, in);
+ sb_new (&what);
+ while (idx < in->len
+ && (mri
+ ? ! eol (idx, in)
+ : in->ptr[idx] != ')'))
+ {
+ sb_add_char (&what, in->ptr[idx]);
+ idx++;
+ }
+ hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
+ sb_kill (&what);
+}
+
+
+static int
+condass_lookup_name (inbuf, idx, out, warn)
+ sb *inbuf;
+ int idx;
+ sb *out;
+ int warn;
+{
+ hash_entry *ptr;
+ sb condass_acc;
+ sb_new (&condass_acc);
+
+ while (idx < inbuf->len
+ && ISNEXTCHAR (inbuf->ptr[idx]))
+ {
+ sb_add_char (&condass_acc, inbuf->ptr[idx++]);
+ }
+
+ if (inbuf->ptr[idx] == '\'')
+ idx++;
+ ptr = hash_lookup (&vars, &condass_acc);
+
+
+ if (!ptr)
+ {
+ if (warn)
+ {
+ WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc)));
+ }
+ else
+ {
+ sb_add_string (out, "0");
+ }
+ }
+ else
+ {
+ if (ptr->type == hash_integer)
+ {
+ char buffer[30];
+ sprintf (buffer, "%d", ptr->value.i);
+ sb_add_string (out, buffer);
+ }
+ else
+ {
+ sb_add_sb (out, &ptr->value.s);
+ }
+ }
+ sb_kill (&condass_acc);
+ return idx;
+}
+
+#define EQ 1
+#define NE 2
+#define GE 3
+#define LT 4
+#define LE 5
+#define GT 6
+#define NEVER 7
+
+static int
+whatcond (idx, in, val)
+ int idx;
+ sb *in;
+ int *val;
+{
+ int cond;
+
+ idx = sb_skip_white (idx, in);
+ cond = NEVER;
+ if (idx + 1 < in->len)
+ {
+ char *p;
+ char a, b;
+
+ p = in->ptr + idx;
+ a = toupper ((unsigned char) p[0]);
+ b = toupper ((unsigned char) p[1]);
+ if (a == 'E' && b == 'Q')
+ cond = EQ;
+ else if (a == 'N' && b == 'E')
+ cond = NE;
+ else if (a == 'L' && b == 'T')
+ cond = LT;
+ else if (a == 'L' && b == 'E')
+ cond = LE;
+ else if (a == 'G' && b == 'T')
+ cond = GT;
+ else if (a == 'G' && b == 'E')
+ cond = GE;
+ }
+ if (cond == NEVER)
+ {
+ ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
+ cond = NEVER;
+ }
+ idx = sb_skip_white (idx + 2, in);
+ *val = cond;
+ return idx;
+}
+
+static int
+istrue (idx, in)
+ int idx;
+ sb *in;
+{
+ int res;
+ sb acc_a;
+ sb cond;
+ sb acc_b;
+ sb_new (&acc_a);
+ sb_new (&cond);
+ sb_new (&acc_b);
+ idx = sb_skip_white (idx, in);
+
+ if (in->ptr[idx] == '"')
+ {
+ int cond;
+ int same;
+ /* This is a string comparision */
+ idx = getstring (idx, in, &acc_a);
+ idx = whatcond (idx, in, &cond);
+ idx = getstring (idx, in, &acc_b);
+ same = acc_a.len == acc_b.len && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);
+
+ if (cond != EQ && cond != NE)
+ {
+ ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n")));
+ res = 0;
+ }
+ else
+ res = (cond != EQ) ^ same;
+ }
+ else
+ /* This is a numeric expression */
+ {
+ int vala;
+ int valb;
+ int cond;
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala);
+ idx = whatcond (idx, in, &cond);
+ idx = sb_skip_white (idx, in);
+ if (in->ptr[idx] == '"')
+ {
+ WARNING ((stderr, _("String compared against expression.\n")));
+ res = 0;
+ }
+ else
+ {
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb);
+ switch (cond)
+ {
+ default:
+ res = 42;
+ break;
+ case EQ:
+ res = vala == valb;
+ break;
+ case NE:
+ res = vala != valb;
+ break;
+ case LT:
+ res = vala < valb;
+ break;
+ case LE:
+ res = vala <= valb;
+ break;
+ case GT:
+ res = vala > valb;
+ break;
+ case GE:
+ res = vala >= valb;
+ break;
+ case NEVER:
+ res = 0;
+ break;
+ }
+ }
+ }
+
+ sb_kill (&acc_a);
+ sb_kill (&cond);
+ sb_kill (&acc_b);
+ return res;
+}
+
+/* .AIF */
+static void
+do_aif (idx, in)
+ int idx;
+ sb *in;
+{
+ if (ifi >= IFNESTING)
+ {
+ FATAL ((stderr, _("AIF nesting unreasonable.\n")));
+ }
+ ifi++;
+ ifstack[ifi].on = ifstack[ifi-1].on ? istrue (idx, in) : 0;
+ ifstack[ifi].hadelse = 0;
+}
+
+
+/* .AELSE */
+static void
+do_aelse ()
+{
+ ifstack[ifi].on = ifstack[ifi-1].on ? !ifstack[ifi].on : 0;
+ if (ifstack[ifi].hadelse)
+ {
+ ERROR ((stderr, _("Multiple AELSEs in AIF.\n")));
+ }
+ ifstack[ifi].hadelse = 1;
+}
+
+
+/* .AENDI */
+static void
+do_aendi ()
+{
+ if (ifi != 0)
+ {
+ ifi--;
+ }
+ else
+ {
+ ERROR ((stderr, _("AENDI without AIF.\n")));
+ }
+}
+
+static int
+condass_on ()
+{
+ return ifstack[ifi].on;
+}
+
+/* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
+
+static void
+do_if (idx, in, cond)
+ int idx;
+ sb *in;
+ int cond;
+{
+ int val;
+ int res;
+
+ if (ifi >= IFNESTING)
+ {
+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
+ }
+
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
+ idx, in, &val);
+ switch (cond)
+ {
+ default:
+ case EQ: res = val == 0; break;
+ case NE: res = val != 0; break;
+ case LT: res = val < 0; break;
+ case LE: res = val <= 0; break;
+ case GE: res = val >= 0; break;
+ case GT: res = val > 0; break;
+ }
+
+ ifi++;
+ ifstack[ifi].on = ifstack[ifi-1].on ? res: 0;
+ ifstack[ifi].hadelse = 0;
+}
+
+/* Get a string for the MRI IFC or IFNC pseudo-ops. */
+
+static int
+get_mri_string (idx, in, val, terminator)
+ int idx;
+ sb *in;
+ sb *val;
+ int terminator;
+{
+ idx = sb_skip_white (idx, in);
+
+ if (idx < in->len
+ && in->ptr[idx] == '\'')
+ {
+ sb_add_char (val, '\'');
+ for (++idx; idx < in->len; ++idx)
+ {
+ sb_add_char (val, in->ptr[idx]);
+ if (in->ptr[idx] == '\'')
+ {
+ ++idx;
+ if (idx >= in->len
+ || in->ptr[idx] != '\'')
+ break;
+ }
+ }
+ idx = sb_skip_white (idx, in);
+ }
+ else
+ {
+ int i;
+
+ while (idx < in->len
+ && in->ptr[idx] != terminator)
+ {
+ sb_add_char (val, in->ptr[idx]);
+ ++idx;
+ }
+ i = val->len - 1;
+ while (i >= 0 && ISWHITE (val->ptr[i]))
+ --i;
+ val->len = i + 1;
+ }
+
+ return idx;
+}
+
+/* MRI IFC, IFNC. */
+
+static void
+do_ifc (idx, in, ifnc)
+ int idx;
+ sb *in;
+ int ifnc;
+{
+ sb first;
+ sb second;
+ int res;
+
+ if (ifi >= IFNESTING)
+ {
+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
+ }
+
+ sb_new (&first);
+ sb_new (&second);
+
+ idx = get_mri_string (idx, in, &first, ',');
+
+ if (idx >= in->len || in->ptr[idx] != ',')
+ {
+ ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
+ return;
+ }
+
+ idx = get_mri_string (idx + 1, in, &second, ';');
+
+ res = (first.len == second.len
+ && strncmp (first.ptr, second.ptr, first.len) == 0);
+ res ^= ifnc;
+
+ ifi++;
+ ifstack[ifi].on = ifstack[ifi-1].on ? res : 0;
+ ifstack[ifi].hadelse = 0;
+}
+
+/* .ENDR */
+static void
+do_aendr ()
+{
+ if (!mri)
+ ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
+ else
+ ERROR ((stderr, _("ENDR without a REPT.\n")));
+}
+
+/* .AWHILE */
+
+static
+void
+do_awhile (idx, in)
+ int idx;
+ sb *in;
+{
+ int line = linecount ();
+ sb exp;
+ sb sub;
+ int doit;
+
+ sb_new (&sub);
+ sb_new (&exp);
+
+ process_assigns (idx, in, &exp);
+ doit = istrue (0, &exp);
+
+ if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
+ FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1));
+
+ /* Turn
+ .AWHILE exp
+ foo
+ .AENDW
+ into
+ foo
+ .AWHILE exp
+ foo
+ .ENDW
+ */
+
+ if (doit)
+ {
+ int index = include_next_index ();
+
+ sb copy;
+ sb_new (&copy);
+ sb_add_sb (&copy, &sub);
+ sb_add_sb (&copy, in);
+ sb_add_string (&copy, "\n");
+ sb_add_sb (&copy, &sub);
+ sb_add_string (&copy, "\t.AENDW\n");
+ /* Push another WHILE */
+ include_buf (&exp, &copy, include_while, index);
+ sb_kill (&copy);
+ }
+ sb_kill (&exp);
+ sb_kill (&sub);
+}
+
+
+/* .AENDW */
+
+static void
+do_aendw ()
+{
+ ERROR ((stderr, _("AENDW without a AENDW.\n")));
+}
+
+
+/* .EXITM
+
+ Pop things off the include stack until the type and index changes */
+
+static void
+do_exitm ()
+{
+ include_type type = sp->type;
+ if (type == include_repeat
+ || type == include_while
+ || type == include_macro)
+ {
+ int index = sp->index;
+ include_pop ();
+ while (sp->index == index
+ && sp->type == type)
+ {
+ include_pop ();
+ }
+ }
+}
+
+/* .AREPEAT */
+
+static void
+do_arepeat (idx, in)
+ int idx;
+ sb *in;
+{
+ int line = linecount ();
+ sb exp; /* buffer with expression in it */
+ sb copy; /* expanded repeat block */
+ sb sub; /* contents of AREPEAT */
+ int rc;
+ int ret;
+ char buffer[30];
+
+ sb_new (&exp);
+ sb_new (&copy);
+ sb_new (&sub);
+ process_assigns (idx, in, &exp);
+ idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
+ if (!mri)
+ ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
+ else
+ ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
+ if (! ret)
+ FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1));
+ if (rc > 0)
+ {
+ /* Push back the text following the repeat, and another repeat block
+ so
+ .AREPEAT 20
+ foo
+ .AENDR
+ gets turned into
+ foo
+ .AREPEAT 19
+ foo
+ .AENDR
+ */
+ int index = include_next_index ();
+ sb_add_sb (&copy, &sub);
+ if (rc > 1)
+ {
+ if (!mri)
+ sprintf (buffer, "\t.AREPEAT %d\n", rc - 1);
+ else
+ sprintf (buffer, "\tREPT %d\n", rc - 1);
+ sb_add_string (&copy, buffer);
+ sb_add_sb (&copy, &sub);
+ if (!mri)
+ sb_add_string (&copy, " .AENDR\n");
+ else
+ sb_add_string (&copy, " ENDR\n");
+ }
+
+ include_buf (&exp, &copy, include_repeat, index);
+ }
+ sb_kill (&exp);
+ sb_kill (&sub);
+ sb_kill (&copy);
+}
+
+/* .ENDM */
+
+static void
+do_endm ()
+{
+ ERROR ((stderr, _(".ENDM without a matching .MACRO.\n")));
+}
+
+/* MRI IRP pseudo-op. */
+
+static void
+do_irp (idx, in, irpc)
+ int idx;
+ sb *in;
+ int irpc;
+{
+ const char *err;
+ sb out;
+
+ sb_new (&out);
+
+ err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
+ if (err != NULL)
+ ERROR ((stderr, "%s\n", err));
+
+ fprintf (outfile, "%s", sb_terminate (&out));
+
+ sb_kill (&out);
+}
+
+/* MACRO PROCESSING */
+
+/* Parse off LOCAL n1, n2,... Invent a label name for it */
+static
+void
+do_local (idx, line)
+ int idx;
+ sb *line;
+{
+ ERROR ((stderr, _("LOCAL outside of MACRO")));
+}
+
+static void
+do_macro (idx, in)
+ int idx;
+ sb *in;
+{
+ const char *err;
+ int line = linecount ();
+
+ err = define_macro (idx, in, &label, get_line, (const char **) NULL);
+ if (err != NULL)
+ ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err));
+}
+
+static int
+macro_op (idx, in)
+ int idx;
+ sb *in;
+{
+ const char *err;
+ sb out;
+ sb name;
+
+ if (! macro_defined)
+ return 0;
+
+ sb_terminate (in);
+ if (! check_macro (in->ptr + idx, &out, comment_char, &err))
+ return 0;
+
+ if (err != NULL)
+ ERROR ((stderr, "%s\n", err));
+
+ sb_new (&name);
+ sb_add_string (&name, _("macro expansion"));
+
+ include_buf (&name, &out, include_macro, include_next_index ());
+
+ sb_kill (&name);
+ sb_kill (&out);
+
+ return 1;
+}
+
+/* STRING HANDLING */
+
+static int
+getstring (idx, in, acc)
+ int idx;
+ sb *in;
+ sb *acc;
+{
+ idx = sb_skip_white (idx, in);
+
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || in->ptr[idx] == '<'
+ || (in->ptr[idx] == '\'' && alternate)))
+ {
+ if (in->ptr[idx] == '<')
+ {
+ if (alternate || mri)
+ {
+ int nest = 0;
+ idx++;
+ while ((in->ptr[idx] != '>' || nest)
+ && idx < in->len)
+ {
+ if (in->ptr[idx] == '!')
+ {
+ idx++ ;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else {
+ if (in->ptr[idx] == '>')
+ nest--;
+ if (in->ptr[idx] == '<')
+ nest++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ }
+ idx++;
+ }
+ else {
+ int code;
+ idx++;
+ idx = exp_get_abs (_("Character code in string must be absolute expression.\n"),
+ idx, in, &code);
+ sb_add_char (acc, code);
+
+ if (in->ptr[idx] != '>')
+ ERROR ((stderr, _("Missing > for character code.\n")));
+ idx++;
+ }
+ }
+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ idx++;
+ while (idx < in->len)
+ {
+ if (alternate && in->ptr[idx] == '!')
+ {
+ idx++ ;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else {
+ if (in->ptr[idx] == tchar)
+ {
+ idx++;
+ if (idx >= in->len || in->ptr[idx] != tchar)
+ break;
+ }
+ sb_add_char (acc, in->ptr[idx]);
+ idx++;
+ }
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* .SDATA[C|Z] <string> */
+
+static
+void
+do_sdata (idx, in, type)
+ int idx;
+ sb *in;
+ int type;
+{
+ int nc = 0;
+ int pidx = -1;
+ sb acc;
+ sb_new (&acc);
+ fprintf (outfile, ".byte\t");
+
+ while (!eol (idx, in))
+ {
+ int i;
+ sb_reset (&acc);
+ idx = sb_skip_white (idx, in);
+ while (!eol (idx, in))
+ {
+ pidx = idx = get_any_string (idx, in, &acc, 0, 1);
+ if (type == 'c')
+ {
+ if (acc.len > 255)
+ {
+ ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len));
+ }
+ fprintf (outfile, "%d", acc.len);
+ nc = 1;
+ }
+
+ for (i = 0; i < acc.len; i++)
+ {
+ if (nc)
+ {
+ fprintf (outfile, ",");
+ }
+ fprintf (outfile, "%d", acc.ptr[i]);
+ nc = 1;
+ }
+
+ if (type == 'z')
+ {
+ if (nc)
+ fprintf (outfile, ",");
+ fprintf (outfile, "0");
+ }
+ idx = sb_skip_comma (idx, in);
+ if (idx == pidx) break;
+ }
+ if (!alternate && in->ptr[idx] != ',' && idx != in->len)
+ {
+ fprintf (outfile, "\n");
+ ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"), in->ptr[idx]));
+ break;
+ }
+ idx++;
+ }
+ sb_kill (&acc);
+ fprintf (outfile, "\n");
+}
+
+/* .SDATAB <count> <string> */
+
+static void
+do_sdatab (idx, in)
+ int idx;
+ sb *in;
+{
+ int repeat;
+ int i;
+ sb acc;
+ sb_new (&acc);
+
+ idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat);
+ if (repeat <= 0)
+ {
+ ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat));
+ repeat = 1;
+ }
+
+ idx = sb_skip_comma (idx, in);
+ idx = getstring (idx, in, &acc);
+
+ for (i = 0; i < repeat; i++)
+ {
+ if (i)
+ fprintf (outfile, "\t");
+ fprintf (outfile, ".byte\t");
+ sb_print (outfile, &acc);
+ fprintf (outfile, "\n");
+ }
+ sb_kill (&acc);
+
+}
+
+static int
+new_file (name)
+ const char *name;
+{
+ FILE *newone = fopen (name, "r");
+ if (!newone)
+ return 0;
+
+ if (isp == MAX_INCLUDES)
+ FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp));
+
+ sp++;
+ sp->handle = newone;
+
+ sb_new (&sp->name);
+ sb_add_string (&sp->name, name);
+
+ sp->linecount = 1;
+ sp->pushback_index = 0;
+ sp->type = include_file;
+ sp->index = 0;
+ sb_new (&sp->pushback);
+ return 1;
+}
+
+static void
+do_include (idx, in)
+ int idx;
+ sb *in;
+{
+ sb t;
+ sb cat;
+ include_path *includes;
+
+ sb_new (&t);
+ sb_new (&cat);
+
+ if (! mri)
+ idx = getstring (idx, in, &t);
+ else
+ {
+ idx = sb_skip_white (idx, in);
+ while (idx < in->len && ! ISWHITE (in->ptr[idx]))
+ {
+ sb_add_char (&t, in->ptr[idx]);
+ ++idx;
+ }
+ }
+
+ for (includes = paths_head; includes; includes = includes->next)
+ {
+ sb_reset (&cat);
+ sb_add_sb (&cat, &includes->path);
+ sb_add_char (&cat, '/');
+ sb_add_sb (&cat, &t);
+ if (new_file (sb_name (&cat)))
+ {
+ break;
+ }
+ }
+ if (!includes)
+ {
+ if (! new_file (sb_name (&t)))
+ FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t)));
+ }
+ sb_kill (&cat);
+ sb_kill (&t);
+}
+
+static void
+include_pop ()
+{
+ if (sp != include_stack)
+ {
+ if (sp->handle)
+ fclose (sp->handle);
+ sp--;
+ }
+}
+
+/* Get the next character from the include stack. If there's anything
+ in the pushback buffer, take that first. If we're at eof, pop from
+ the stack and try again. Keep the linecount up to date. */
+
+static int
+get ()
+{
+ int r;
+
+ if (sp->pushback.len != sp->pushback_index)
+ {
+ r = (char) (sp->pushback.ptr[sp->pushback_index++]);
+ /* When they've all gone, reset the pointer */
+ if (sp->pushback_index == sp->pushback.len)
+ {
+ sp->pushback.len = 0;
+ sp->pushback_index = 0;
+ }
+ }
+ else if (sp->handle)
+ {
+ r = getc (sp->handle);
+ }
+ else
+ r = EOF;
+
+ if (r == EOF && isp)
+ {
+ include_pop ();
+ r = get ();
+ while (r == EOF && isp)
+ {
+ include_pop ();
+ r = get ();
+ }
+ return r;
+ }
+ if (r == '\n')
+ {
+ sp->linecount++;
+ }
+
+ return r;
+}
+
+static int
+linecount ()
+{
+ return sp->linecount;
+}
+
+static int
+include_next_index ()
+{
+ static int index;
+ if (!unreasonable
+ && index > MAX_REASONABLE)
+ FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n")));
+ return ++index;
+}
+
+
+/* Initialize the chartype vector. */
+
+static void
+chartype_init ()
+{
+ int x;
+ for (x = 0; x < 256; x++)
+ {
+ if (isalpha (x) || x == '_' || x == '$')
+ chartype[x] |= FIRSTBIT;
+
+ if (mri && x == '.')
+ chartype[x] |= FIRSTBIT;
+
+ if (isdigit (x) || isalpha (x) || x == '_' || x == '$')
+ chartype[x] |= NEXTBIT;
+
+ if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
+ || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
+ chartype[x] |= SEPBIT;
+
+ if (x == 'b' || x == 'B'
+ || x == 'q' || x == 'Q'
+ || x == 'h' || x == 'H'
+ || x == 'd' || x == 'D')
+ chartype [x] |= BASEBIT;
+
+ if (x == ' ' || x == '\t')
+ chartype[x] |= WHITEBIT;
+
+ if (x == comment_char)
+ chartype[x] |= COMMENTBIT;
+ }
+}
+
+
+
+/* What to do with all the keywords */
+#define PROCESS 0x1000 /* Run substitution over the line */
+#define LAB 0x2000 /* Spit out the label */
+
+#define K_EQU (PROCESS|1)
+#define K_ASSIGN (PROCESS|2)
+#define K_REG (PROCESS|3)
+#define K_ORG (PROCESS|4)
+#define K_RADIX (PROCESS|5)
+#define K_DATA (LAB|PROCESS|6)
+#define K_DATAB (LAB|PROCESS|7)
+#define K_SDATA (LAB|PROCESS|8)
+#define K_SDATAB (LAB|PROCESS|9)
+#define K_SDATAC (LAB|PROCESS|10)
+#define K_SDATAZ (LAB|PROCESS|11)
+#define K_RES (LAB|PROCESS|12)
+#define K_SRES (LAB|PROCESS|13)
+#define K_SRESC (LAB|PROCESS|14)
+#define K_SRESZ (LAB|PROCESS|15)
+#define K_EXPORT (LAB|PROCESS|16)
+#define K_GLOBAL (LAB|PROCESS|17)
+#define K_PRINT (LAB|PROCESS|19)
+#define K_FORM (LAB|PROCESS|20)
+#define K_HEADING (LAB|PROCESS|21)
+#define K_PAGE (LAB|PROCESS|22)
+#define K_IMPORT (LAB|PROCESS|23)
+#define K_PROGRAM (LAB|PROCESS|24)
+#define K_END (PROCESS|25)
+#define K_INCLUDE (PROCESS|26)
+#define K_IGNORED (PROCESS|27)
+#define K_ASSIGNA (PROCESS|28)
+#define K_ASSIGNC (29)
+#define K_AIF (PROCESS|30)
+#define K_AELSE (PROCESS|31)
+#define K_AENDI (PROCESS|32)
+#define K_AREPEAT (PROCESS|33)
+#define K_AENDR (PROCESS|34)
+#define K_AWHILE (35)
+#define K_AENDW (PROCESS|36)
+#define K_EXITM (37)
+#define K_MACRO (PROCESS|38)
+#define K_ENDM (39)
+#define K_ALIGN (PROCESS|LAB|40)
+#define K_ALTERNATE (41)
+#define K_DB (LAB|PROCESS|42)
+#define K_DW (LAB|PROCESS|43)
+#define K_DL (LAB|PROCESS|44)
+#define K_LOCAL (45)
+#define K_IFEQ (PROCESS|46)
+#define K_IFNE (PROCESS|47)
+#define K_IFLT (PROCESS|48)
+#define K_IFLE (PROCESS|49)
+#define K_IFGE (PROCESS|50)
+#define K_IFGT (PROCESS|51)
+#define K_IFC (PROCESS|52)
+#define K_IFNC (PROCESS|53)
+#define K_IRP (PROCESS|54)
+#define K_IRPC (PROCESS|55)
+
+
+struct keyword
+{
+ char *name;
+ int code;
+ int extra;
+};
+
+static struct keyword kinfo[] =
+{
+ { "EQU", K_EQU, 0 },
+ { "ALTERNATE", K_ALTERNATE, 0 },
+ { "ASSIGN", K_ASSIGN, 0 },
+ { "REG", K_REG, 0 },
+ { "ORG", K_ORG, 0 },
+ { "RADIX", K_RADIX, 0 },
+ { "DATA", K_DATA, 0 },
+ { "DB", K_DB, 0 },
+ { "DW", K_DW, 0 },
+ { "DL", K_DL, 0 },
+ { "DATAB", K_DATAB, 0 },
+ { "SDATA", K_SDATA, 0 },
+ { "SDATAB", K_SDATAB, 0 },
+ { "SDATAZ", K_SDATAZ, 0 },
+ { "SDATAC", K_SDATAC, 0 },
+ { "RES", K_RES, 0 },
+ { "SRES", K_SRES, 0 },
+ { "SRESC", K_SRESC, 0 },
+ { "SRESZ", K_SRESZ, 0 },
+ { "EXPORT", K_EXPORT, 0 },
+ { "GLOBAL", K_GLOBAL, 0 },
+ { "PRINT", K_PRINT, 0 },
+ { "FORM", K_FORM, 0 },
+ { "HEADING", K_HEADING, 0 },
+ { "PAGE", K_PAGE, 0 },
+ { "PROGRAM", K_IGNORED, 0 },
+ { "END", K_END, 0 },
+ { "INCLUDE", K_INCLUDE, 0 },
+ { "ASSIGNA", K_ASSIGNA, 0 },
+ { "ASSIGNC", K_ASSIGNC, 0 },
+ { "AIF", K_AIF, 0 },
+ { "AELSE", K_AELSE, 0 },
+ { "AENDI", K_AENDI, 0 },
+ { "AREPEAT", K_AREPEAT, 0 },
+ { "AENDR", K_AENDR, 0 },
+ { "EXITM", K_EXITM, 0 },
+ { "MACRO", K_MACRO, 0 },
+ { "ENDM", K_ENDM, 0 },
+ { "AWHILE", K_AWHILE, 0 },
+ { "ALIGN", K_ALIGN, 0 },
+ { "AENDW", K_AENDW, 0 },
+ { "ALTERNATE", K_ALTERNATE, 0 },
+ { "LOCAL", K_LOCAL, 0 },
+ { NULL, 0, 0 }
+};
+
+/* Although the conditional operators are handled by gas, we need to
+ handle them here as well, in case they are used in a recursive
+ macro to end the recursion. */
+
+static struct keyword mrikinfo[] =
+{
+ { "IFEQ", K_IFEQ, 0 },
+ { "IFNE", K_IFNE, 0 },
+ { "IFLT", K_IFLT, 0 },
+ { "IFLE", K_IFLE, 0 },
+ { "IFGE", K_IFGE, 0 },
+ { "IFGT", K_IFGT, 0 },
+ { "IFC", K_IFC, 0 },
+ { "IFNC", K_IFNC, 0 },
+ { "ELSEC", K_AELSE, 0 },
+ { "ENDC", K_AENDI, 0 },
+ { "MEXIT", K_EXITM, 0 },
+ { "REPT", K_AREPEAT, 0 },
+ { "IRP", K_IRP, 0 },
+ { "IRPC", K_IRPC, 0 },
+ { "ENDR", K_AENDR, 0 },
+ { NULL, 0, 0 }
+};
+
+/* Look for a pseudo op on the line. If one's there then call
+ its handler. */
+
+static int
+process_pseudo_op (idx, line, acc)
+ int idx;
+ sb *line;
+ sb *acc;
+{
+ int oidx = idx;
+
+ if (line->ptr[idx] == '.' || alternate || mri)
+ {
+ /* Scan forward and find pseudo name */
+ char *in;
+ hash_entry *ptr;
+
+ char *s;
+ char *e;
+ if (line->ptr[idx] == '.')
+ idx++;
+ in = line->ptr + idx;
+ s = in;
+ e = s;
+ sb_reset (acc);
+
+ while (idx < line->len && *e && ISFIRSTCHAR (*e))
+ {
+ sb_add_char (acc, *e);
+ e++;
+ idx++;
+ }
+
+ ptr = hash_lookup (&keyword_hash_table, acc);
+
+ if (!ptr)
+ {
+#if 0
+ /* This one causes lots of pain when trying to preprocess
+ ordinary code */
+ WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"), sb_name (acc)));
+#endif
+ return 0;
+ }
+ if (ptr->value.i & LAB)
+ { /* output the label */
+ if (label.len)
+ {
+ fprintf (outfile, "%s:\t", sb_name (&label));
+ }
+ else
+ fprintf (outfile, "\t");
+ }
+
+ if (mri && ptr->value.i == K_END)
+ {
+ sb t;
+
+ sb_new (&t);
+ sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
+ fprintf (outfile, "\t%s", sb_name (&t));
+ sb_kill (&t);
+ }
+
+ if (ptr->value.i & PROCESS)
+ {
+ /* Polish the rest of the line before handling the pseudo op */
+#if 0
+ strip_comments(line);
+#endif
+ sb_reset (acc);
+ process_assigns (idx, line, acc);
+ sb_reset(line);
+ change_base (0, acc, line);
+ idx = 0;
+ }
+ if (!condass_on ())
+ {
+ switch (ptr->value.i)
+ {
+ case K_AIF:
+ do_aif (idx, line);
+ break;
+ case K_AELSE:
+ do_aelse ();
+ break;
+ case K_AENDI:
+ do_aendi ();
+ break;
+ }
+ return 1;
+ }
+ else
+ {
+ switch (ptr->value.i)
+ {
+ case K_ALTERNATE:
+ alternate = 1;
+ macro_init (1, mri, 0, exp_get_abs);
+ return 1;
+ case K_AELSE:
+ do_aelse ();
+ return 1;
+ case K_AENDI:
+ do_aendi ();
+ return 1;
+ case K_ORG:
+ ERROR ((stderr, _("ORG command not allowed.\n")));
+ break;
+ case K_RADIX:
+ do_radix (line);
+ return 1;
+ case K_DB:
+ do_data (idx, line, 1);
+ return 1;
+ case K_DW:
+ do_data (idx, line, 2);
+ return 1;
+ case K_DL:
+ do_data (idx, line, 4);
+ return 1;
+ case K_DATA:
+ do_data (idx, line, 0);
+ return 1;
+ case K_DATAB:
+ do_datab (idx, line);
+ return 1;
+ case K_SDATA:
+ do_sdata (idx, line, 0);
+ return 1;
+ case K_SDATAB:
+ do_sdatab (idx, line);
+ return 1;
+ case K_SDATAC:
+ do_sdata (idx, line, 'c');
+ return 1;
+ case K_SDATAZ:
+ do_sdata (idx, line, 'z');
+ return 1;
+ case K_ASSIGN:
+ do_assign (0, 0, line);
+ return 1;
+ case K_AIF:
+ do_aif (idx, line);
+ return 1;
+ case K_AREPEAT:
+ do_arepeat (idx, line);
+ return 1;
+ case K_AENDW:
+ do_aendw ();
+ return 1;
+ case K_AWHILE:
+ do_awhile (idx, line);
+ return 1;
+ case K_AENDR:
+ do_aendr ();
+ return 1;
+ case K_EQU:
+ do_assign (1, idx, line);
+ return 1;
+ case K_ALIGN:
+ do_align (idx, line);
+ return 1;
+ case K_RES:
+ do_res (idx, line, 0);
+ return 1;
+ case K_SRES:
+ do_res (idx, line, 's');
+ return 1;
+ case K_INCLUDE:
+ do_include (idx, line);
+ return 1;
+ case K_LOCAL:
+ do_local (idx, line);
+ return 1;
+ case K_MACRO:
+ do_macro (idx, line);
+ return 1;
+ case K_ENDM:
+ do_endm ();
+ return 1;
+ case K_SRESC:
+ do_res (idx, line, 'c');
+ return 1;
+ case K_PRINT:
+ do_print (idx, line);
+ return 1;
+ case K_FORM:
+ do_form (idx, line);
+ return 1;
+ case K_HEADING:
+ do_heading (idx, line);
+ return 1;
+ case K_PAGE:
+ do_page ();
+ return 1;
+ case K_GLOBAL:
+ case K_EXPORT:
+ do_export (line);
+ return 1;
+ case K_IMPORT:
+ return 1;
+ case K_SRESZ:
+ do_res (idx, line, 'z');
+ return 1;
+ case K_IGNORED:
+ return 1;
+ case K_END:
+ do_end (line);
+ return 1;
+ case K_ASSIGNA:
+ do_assigna (idx, line);
+ return 1;
+ case K_ASSIGNC:
+ do_assignc (idx, line);
+ return 1;
+ case K_EXITM:
+ do_exitm ();
+ return 1;
+ case K_REG:
+ do_reg (idx, line);
+ return 1;
+ case K_IFEQ:
+ do_if (idx, line, EQ);
+ return 1;
+ case K_IFNE:
+ do_if (idx, line, NE);
+ return 1;
+ case K_IFLT:
+ do_if (idx, line, LT);
+ return 1;
+ case K_IFLE:
+ do_if (idx, line, LE);
+ return 1;
+ case K_IFGE:
+ do_if (idx, line, GE);
+ return 1;
+ case K_IFGT:
+ do_if (idx, line, GT);
+ return 1;
+ case K_IFC:
+ do_ifc (idx, line, 0);
+ return 1;
+ case K_IFNC:
+ do_ifc (idx, line, 1);
+ return 1;
+ case K_IRP:
+ do_irp (idx, line, 0);
+ return 1;
+ case K_IRPC:
+ do_irp (idx, line, 1);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+
+/* Add a keyword to the hash table. */
+
+static void
+add_keyword (name, code)
+ const char *name;
+ int code;
+{
+ sb label;
+ int j;
+
+ sb_new (&label);
+ sb_add_string (&label, name);
+
+ hash_add_to_int_table (&keyword_hash_table, &label, code);
+
+ sb_reset (&label);
+ for (j = 0; name[j]; j++)
+ sb_add_char (&label, name[j] - 'A' + 'a');
+ hash_add_to_int_table (&keyword_hash_table, &label, code);
+
+ sb_kill (&label);
+}
+
+/* Build the keyword hash table - put each keyword in the table twice,
+ once upper and once lower case.*/
+
+static void
+process_init ()
+{
+ int i;
+
+ for (i = 0; kinfo[i].name; i++)
+ add_keyword (kinfo[i].name, kinfo[i].code);
+
+ if (mri)
+ {
+ for (i = 0; mrikinfo[i].name; i++)
+ add_keyword (mrikinfo[i].name, mrikinfo[i].code);
+ }
+}
+
+
+static void
+do_define (string)
+ const char *string;
+{
+ sb label;
+ int res = 1;
+ hash_entry *ptr;
+ sb_new (&label);
+
+
+ while (*string)
+ {
+ if (*string == '=')
+ {
+ sb value;
+ sb_new (&value);
+ string++;
+ while (*string)
+ {
+ sb_add_char (&value, *string);
+ string++;
+ }
+ exp_get_abs (_("Invalid expression on command line.\n"), 0, &value, &res);
+ sb_kill (&value);
+ break;
+ }
+ sb_add_char (&label, *string);
+
+ string ++;
+ }
+
+ ptr = hash_create (&vars, &label);
+ free_old_entry (ptr);
+ ptr->type = hash_integer;
+ ptr->value.i = res;
+ sb_kill (&label);
+}
+char *program_name;
+
+/* The list of long options. */
+static struct option long_options[] =
+{
+ { "alternate", no_argument, 0, 'a' },
+ { "include", required_argument, 0, 'I' },
+ { "commentchar", required_argument, 0, 'c' },
+ { "copysource", no_argument, 0, 's' },
+ { "debug", no_argument, 0, 'd' },
+ { "help", no_argument, 0, 'h' },
+ { "mri", no_argument, 0, 'M' },
+ { "output", required_argument, 0, 'o' },
+ { "print", no_argument, 0, 'p' },
+ { "unreasonable", no_argument, 0, 'u' },
+ { "version", no_argument, 0, 'v' },
+ { "define", required_argument, 0, 'd' },
+ { NULL, no_argument, 0, 0 }
+};
+
+/* Show a usage message and exit. */
+static void
+show_usage (file, status)
+ FILE *file;
+ int status;
+{
+ fprintf (file, _("\
+Usage: %s \n\
+ [-a] [--alternate] enter alternate macro mode\n\
+ [-c char] [--commentchar char] change the comment character from !\n\
+ [-d] [--debug] print some debugging info\n\
+ [-h] [--help] print this message\n\
+ [-M] [--mri] enter MRI compatibility mode\n\
+ [-o out] [--output out] set the output file\n\
+ [-p] [--print] print line numbers\n"), program_name);
+ fprintf (file, _("\
+ [-s] [--copysource] copy source through as comments \n\
+ [-u] [--unreasonable] allow unreasonable nesting\n\
+ [-v] [--version] print the program version\n\
+ [-Dname=value] create preprocessor variable called name, with value\n\
+ [-Ipath] add to include path list\n\
+ [in-file]\n"));
+ if (status == 0)
+ printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n"));
+ exit (status);
+}
+
+/* Display a help message and exit. */
+static void
+show_help ()
+{
+ printf (_("%s: Gnu Assembler Macro Preprocessor\n"),
+ program_name);
+ show_usage (stdout, 0);
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int opt;
+ char *out_name = 0;
+ sp = include_stack;
+
+ ifstack[0].on = 1;
+ ifi = 0;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ hash_new_table (101, &keyword_hash_table);
+ hash_new_table (101, &assign_hash_table);
+ hash_new_table (101, &vars);
+
+ sb_new (&label);
+
+ while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
+ (int *) NULL))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'o':
+ out_name = optarg;
+ break;
+ case 'u':
+ unreasonable = 1;
+ break;
+ case 'I':
+ {
+ include_path *p = (include_path *) xmalloc (sizeof (include_path));
+ p->next = NULL;
+ sb_new (&p->path);
+ sb_add_string (&p->path, optarg);
+ if (paths_tail)
+ paths_tail->next = p;
+ else
+ paths_head = p;
+ paths_tail = p;
+ }
+ break;
+ case 'p':
+ print_line_number = 1;
+ break;
+ case 'c':
+ comment_char = optarg[0];
+ break;
+ case 'a':
+ alternate = 1;
+ break;
+ case 's':
+ copysource = 1;
+ break;
+ case 'd':
+ stats = 1;
+ break;
+ case 'D':
+ do_define (optarg);
+ break;
+ case 'M':
+ mri = 1;
+ comment_char = ';';
+ break;
+ case 'h':
+ show_help ();
+ /*NOTREACHED*/
+ case 'v':
+ /* This output is intended to follow the GNU standards document. */
+ printf (_("GNU assembler pre-processor %s\n"), program_version);
+ printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
+ printf (_("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n"));
+ exit (0);
+ /*NOTREACHED*/
+ case 0:
+ break;
+ default:
+ show_usage (stderr, 1);
+ /*NOTREACHED*/
+ }
+ }
+
+ process_init ();
+
+ macro_init (alternate, mri, 0, exp_get_abs);
+
+ if (out_name) {
+ outfile = fopen (out_name, "w");
+ if (!outfile)
+ {
+ fprintf (stderr, _("%s: Can't open output file `%s'.\n"),
+ program_name, out_name);
+ exit (1);
+ }
+ }
+ else {
+ outfile = stdout;
+ }
+
+ chartype_init ();
+ if (!outfile)
+ outfile = stdout;
+
+ /* Process all the input files */
+
+ while (optind < argc)
+ {
+ if (new_file (argv[optind]))
+ {
+ process_file ();
+ }
+ else
+ {
+ fprintf (stderr, _("%s: Can't open input file `%s'.\n"),
+ program_name, argv[optind]);
+ exit (1);
+ }
+ optind++;
+ }
+
+ quit ();
+ return 0;
+}
+
+/* This function is used because an abort in some of the other files
+ may be compiled into as_abort because they include as.h. */
+
+void
+as_abort (file, line, fn)
+ const char *file, *fn;
+ int line;
+{
+ fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line);
+ if (fn)
+ fprintf (stderr, " in %s", fn);
+ fprintf (stderr, _("\nPlease report this bug.\n"));
+ exit (1);
+}
diff --git a/gas/gdbinit.in b/gas/gdbinit.in
new file mode 100644
index 00000000000..e946726ec67
--- /dev/null
+++ b/gas/gdbinit.in
@@ -0,0 +1,39 @@
+dir @srcdir@
+dir .
+
+break as_warn
+break as_warn_where
+break as_bad
+break as_bad_where
+break as_fatal
+break as_perror
+break as_assert
+break as_abort
+
+define pe
+call print_expr ($)
+end
+
+document pe
+Print *$ as an expressionS, expanding parameters.
+end
+
+define ps
+call print_symbol_value ($)
+end
+
+document ps
+Print *$ as a symbolS, including expression value.
+end
+
+define pf
+call print_fixup ($)
+end
+
+document pf
+Print *$ as a fixS, including symbol value.
+end
+
+# Put this last, in case it fails.
+
+break abort
diff --git a/gas/hash.c b/gas/hash.c
new file mode 100644
index 00000000000..dccd660754c
--- /dev/null
+++ b/gas/hash.c
@@ -0,0 +1,1028 @@
+/* hash.c - hash table lookup strings -
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * BUGS, GRIPES, APOLOGIA etc.
+ *
+ * A typical user doesn't need ALL this: I intend to make a library out
+ * of it one day - Dean Elsner.
+ * Also, I want to change the definition of a symbol to (address,length)
+ * so I can put arbitrary binary in the names stored. [see hsh.c for that]
+ *
+ * This slime is common coupled inside the module. Com-coupling (and other
+ * vandalism) was done to speed running time. The interfaces at the
+ * module's edges are adequately clean.
+ *
+ * There is no way to (a) run a test script through this heap and (b)
+ * compare results with previous scripts, to see if we have broken any
+ * code. Use GNU (f)utilities to do this. A few commands assist test.
+ * The testing is awkward: it tries to be both batch & interactive.
+ * For now, interactive rules!
+ */
+
+/*
+ * The idea is to implement a symbol table. A test jig is here.
+ * Symbols are arbitrary strings; they can't contain '\0'.
+ * [See hsh.c for a more general symbol flavour.]
+ * Each symbol is associated with a char*, which can point to anything
+ * you want, allowing an arbitrary property list for each symbol.
+ *
+ * The basic operations are:
+ *
+ * new creates symbol table, returns handle
+ * find (symbol) returns char*
+ * insert (symbol,char*) error if symbol already in table
+ * delete (symbol) returns char* if symbol was in table
+ * apply so you can delete all symbols before die()
+ * die destroy symbol table (free up memory)
+ *
+ * Supplementary functions include:
+ *
+ * say how big? what % full?
+ * replace (symbol,newval) report previous value
+ * jam (symbol,value) assert symbol:=value
+ *
+ * You, the caller, have control over errors: this just reports them.
+ *
+ * This package requires malloc(), free().
+ * Malloc(size) returns NULL or address of char[size].
+ * Free(address) frees same.
+ */
+
+/*
+ * The code and its structures are re-enterent.
+ *
+ * Before you do anything else, you must call hash_new() which will
+ * return the address of a hash-table-control-block. You then use
+ * this address as a handle of the symbol table by passing it to all
+ * the other hash_...() functions. The only approved way to recover
+ * the memory used by the symbol table is to call hash_die() with the
+ * handle of the symbol table.
+ *
+ * Before you call hash_die() you normally delete anything pointed to
+ * by individual symbols. After hash_die() you can't use that symbol
+ * table again.
+ *
+ * The char* you associate with a symbol may not be NULL (0) because
+ * NULL is returned whenever a symbol is not in the table. Any other
+ * value is OK, except DELETED, #defined below.
+ *
+ * When you supply a symbol string for insertion, YOU MUST PRESERVE THE
+ * STRING until that symbol is deleted from the table. The reason is that
+ * only the address you supply, NOT the symbol string itself, is stored
+ * in the symbol table.
+ *
+ * You may delete and add symbols arbitrarily.
+ * Any or all symbols may have the same 'value' (char *). In fact, these
+ * routines don't do anything with your symbol values.
+ *
+ * You have no right to know where the symbol:char* mapping is stored,
+ * because it moves around in memory; also because we may change how it
+ * works and we don't want to break your code do we? However the handle
+ * (address of struct hash_control) is never changed in
+ * the life of the symbol table.
+ *
+ * What you CAN find out about a symbol table is:
+ * how many slots are in the hash table?
+ * how many slots are filled with symbols?
+ * (total hashes,collisions) for (reads,writes) (*)
+ * All of the above values vary in time.
+ * (*) some of these numbers will not be meaningful if we change the
+ * internals. */
+
+/*
+ * I N T E R N A L
+ *
+ * Hash table is an array of hash_entries; each entry is a pointer to a
+ * a string and a user-supplied value 1 char* wide.
+ *
+ * The array always has 2 ** n elements, n>0, n integer.
+ * There is also a 'wall' entry after the array, which is always empty
+ * and acts as a sentinel to stop running off the end of the array.
+ * When the array gets too full, we create a new array twice as large
+ * and re-hash the symbols into the new array, then forget the old array.
+ * (Of course, we copy the values into the new array before we junk the
+ * old array!)
+ *
+ */
+
+#include <stdio.h>
+
+#ifndef FALSE
+#define FALSE (0)
+#define TRUE (!FALSE)
+#endif /* no FALSE yet */
+
+#include <ctype.h>
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#include "as.h"
+
+#define error as_fatal
+
+static char _deleted_[1];
+#define DELETED ((PTR)_deleted_) /* guarenteed unique address */
+#define START_POWER (10) /* power of two: size of new hash table */
+
+/* TRUE if a symbol is in entry @ ptr. */
+#define islive(ptr) (ptr->hash_string && ptr->hash_string!=DELETED)
+
+enum stat_enum {
+ /* Number of slots in hash table. The wall does not count here.
+ We expect this is always a power of 2. */
+ STAT_SIZE = 0,
+ /* Number of hash_ask calls. */
+ STAT_ACCESS,
+ STAT_ACCESS_w,
+ /* Number of collisions (total). This may exceed STAT_ACCESS if we
+ have lots of collisions/access. */
+ STAT_COLLIDE,
+ STAT_COLLIDE_w,
+ /* Slots used right now. */
+ STAT_USED,
+ /* How many string compares? */
+ STAT_STRCMP,
+ STAT_STRCMP_w,
+ /* Size of statistics block... this must be last. */
+ STATLENGTH
+};
+#define STAT__READ (0) /* reading */
+#define STAT__WRITE (1) /* writing */
+
+/* When we grow a hash table, by what power of two do we increase it? */
+#define GROW_FACTOR 1
+/* When should we grow it? */
+#define FULL_VALUE(N) ((N) / 2)
+
+/* #define SUSPECT to do runtime checks */
+/* #define TEST to be a test jig for hash...() */
+
+#ifdef TEST
+/* TEST: use smaller hash table */
+#undef START_POWER
+#define START_POWER (3)
+#undef START_SIZE
+#define START_SIZE (8)
+#undef START_FULL
+#define START_FULL (4)
+#endif
+
+struct hash_entry
+{
+ const char *hash_string; /* points to where the symbol string is */
+ /* NULL means slot is not used */
+ /* DELETED means slot was deleted */
+ PTR hash_value; /* user's datum, associated with symbol */
+ unsigned long h;
+};
+
+struct hash_control {
+ struct hash_entry *hash_where;/* address of hash table */
+ int hash_sizelog; /* Log of ( hash_mask + 1 ) */
+ int hash_mask; /* masks a hash into index into table */
+ int hash_full; /* when hash_stat[STAT_USED] exceeds this, */
+ /* grow table */
+ struct hash_entry *hash_wall; /* point just after last (usable) entry */
+ /* here we have some statistics */
+ int hash_stat[STATLENGTH]; /* lies & statistics */
+};
+
+/*------------------ plan ---------------------------------- i = internal
+
+ struct hash_control * c;
+ struct hash_entry * e; i
+ int b[z]; buffer for statistics
+ z size of b
+ char * s; symbol string (address) [ key ]
+ char * v; value string (address) [datum]
+ boolean f; TRUE if we found s in hash table i
+ char * t; error string; 0 means OK
+ int a; access type [0...n) i
+
+ c=hash_new () create new hash_control
+
+ hash_die (c) destroy hash_control (and hash table)
+ table should be empty.
+ doesn't check if table is empty.
+ c has no meaning after this.
+
+ hash_say (c,b,z) report statistics of hash_control.
+ also report number of available statistics.
+
+ v=hash_delete (c,s) delete symbol, return old value if any.
+ ask() NULL means no old value.
+ f
+
+ v=hash_replace (c,s,v) replace old value of s with v.
+ ask() NULL means no old value: no table change.
+ f
+
+ t=hash_insert (c,s,v) insert (s,v) in c.
+ ask() return error string.
+ f it is an error to insert if s is already
+ in table.
+ if any error, c is unchanged.
+
+ t=hash_jam (c,s,v) assert that new value of s will be v. i
+ ask() it may decide to GROW the table. i
+ f i
+ grow() i
+ t=hash_grow (c) grow the hash table. i
+ jam() will invoke JAM. i
+
+ ?=hash_apply (c,y) apply y() to every symbol in c.
+ y evtries visited in 'unspecified' order.
+
+ v=hash_find (c,s) return value of s, or NULL if s not in c.
+ ask()
+ f
+
+ f,e=hash_ask() (c,s,a) return slot where s SHOULD live. i
+ code() maintain collision stats in c. i
+
+ .=hash_code (c,s) compute hash-code for s, i
+ from parameters of c. i
+
+ */
+
+/* Returned by hash_ask() to stop extra testing. hash_ask() wants to
+ return both a slot and a status. This is the status. TRUE: found
+ symbol FALSE: absent: empty or deleted slot Also returned by
+ hash_jam(). TRUE: we replaced a value FALSE: we inserted a value. */
+static char hash_found;
+
+static struct hash_entry *hash_ask PARAMS ((struct hash_control *,
+ const char *, int));
+static int hash_code PARAMS ((struct hash_control *, const char *));
+static const char *hash_grow PARAMS ((struct hash_control *));
+
+/* Create a new hash table. Return NULL if failed; otherwise return handle
+ (address of struct hash). */
+struct hash_control *
+hash_new ()
+{
+ struct hash_control *retval;
+ struct hash_entry *room; /* points to hash table */
+ struct hash_entry *wall;
+ struct hash_entry *entry;
+ int *ip; /* scan stats block of struct hash_control */
+ int *nd; /* limit of stats block */
+
+ room = (struct hash_entry *) xmalloc (sizeof (struct hash_entry)
+ /* +1 for the wall entry */
+ * ((1 << START_POWER) + 1));
+ retval = (struct hash_control *) xmalloc (sizeof (struct hash_control));
+
+ nd = retval->hash_stat + STATLENGTH;
+ for (ip = retval->hash_stat; ip < nd; ip++)
+ *ip = 0;
+
+ retval->hash_stat[STAT_SIZE] = 1 << START_POWER;
+ retval->hash_mask = (1 << START_POWER) - 1;
+ retval->hash_sizelog = START_POWER;
+ /* works for 1's compl ok */
+ retval->hash_where = room;
+ retval->hash_wall =
+ wall = room + (1 << START_POWER);
+ retval->hash_full = FULL_VALUE (1 << START_POWER);
+ for (entry = room; entry <= wall; entry++)
+ entry->hash_string = NULL;
+ return retval;
+}
+
+/*
+ * h a s h _ d i e ( )
+ *
+ * Table should be empty, but this is not checked.
+ * To empty the table, try hash_apply()ing a symbol deleter.
+ * Return to free memory both the hash table and it's control
+ * block.
+ * 'handle' has no meaning after this function.
+ * No errors are recoverable.
+ */
+void
+hash_die (handle)
+ struct hash_control *handle;
+{
+ free ((char *) handle->hash_where);
+ free ((char *) handle);
+}
+
+#ifdef TEST
+/*
+ * h a s h _ s a y ( )
+ *
+ * Return the size of the statistics table, and as many statistics as
+ * we can until either (a) we have run out of statistics or (b) caller
+ * has run out of buffer.
+ * NOTE: hash_say treats all statistics alike.
+ * These numbers may change with time, due to insertions, deletions
+ * and expansions of the table.
+ * The first "statistic" returned is the length of hash_stat[].
+ * Then contents of hash_stat[] are read out (in ascending order)
+ * until your buffer or hash_stat[] is exausted.
+ */
+static void
+hash_say (handle, buffer, bufsiz)
+ struct hash_control *handle;
+ int buffer[ /*bufsiz*/ ];
+ int bufsiz;
+{
+ int *nd; /* limit of statistics block */
+ int *ip; /* scan statistics */
+
+ ip = handle->hash_stat;
+ nd = ip + min (bufsiz - 1, STATLENGTH);
+ if (bufsiz > 0) /* trust nothing! bufsiz<=0 is dangerous */
+ {
+ *buffer++ = STATLENGTH;
+ for (; ip < nd; ip++, buffer++)
+ {
+ *buffer = *ip;
+ }
+ }
+}
+#endif
+
+/*
+ * h a s h _ d e l e t e ( )
+ *
+ * Try to delete a symbol from the table.
+ * If it was there, return its value (and adjust STAT_USED).
+ * Otherwise, return NULL.
+ * Anyway, the symbol is not present after this function.
+ *
+ */
+PTR /* NULL if string not in table, else */
+/* returns value of deleted symbol */
+hash_delete (handle, string)
+ struct hash_control *handle;
+ const char *string;
+{
+ PTR retval;
+ struct hash_entry *entry;
+
+ entry = hash_ask (handle, string, STAT__WRITE);
+ if (hash_found)
+ {
+ retval = entry->hash_value;
+ entry->hash_string = DELETED;
+ handle->hash_stat[STAT_USED] -= 1;
+#ifdef SUSPECT
+ if (handle->hash_stat[STAT_USED] < 0)
+ {
+ error ("hash_delete");
+ }
+#endif /* def SUSPECT */
+ }
+ else
+ {
+ retval = NULL;
+ }
+ return (retval);
+}
+
+/*
+ * h a s h _ r e p l a c e ( )
+ *
+ * Try to replace the old value of a symbol with a new value.
+ * Normally return the old value.
+ * Return NULL and don't change the table if the symbol is not already
+ * in the table.
+ */
+PTR
+hash_replace (handle, string, value)
+ struct hash_control *handle;
+ const char *string;
+ PTR value;
+{
+ struct hash_entry *entry;
+ char *retval;
+
+ entry = hash_ask (handle, string, STAT__WRITE);
+ if (hash_found)
+ {
+ retval = entry->hash_value;
+ entry->hash_value = value;
+ }
+ else
+ {
+ retval = NULL;
+ }
+ ;
+ return retval;
+}
+
+/*
+ * h a s h _ i n s e r t ( )
+ *
+ * Insert a (symbol-string, value) into the hash table.
+ * Return an error string, 0 means OK.
+ * It is an 'error' to insert an existing symbol.
+ */
+
+const char * /* return error string */
+hash_insert (handle, string, value)
+ struct hash_control *handle;
+ const char *string;
+ PTR value;
+{
+ struct hash_entry *entry;
+ const char *retval;
+
+ retval = 0;
+ if (handle->hash_stat[STAT_USED] > handle->hash_full)
+ {
+ retval = hash_grow (handle);
+ }
+ if (!retval)
+ {
+ entry = hash_ask (handle, string, STAT__WRITE);
+ if (hash_found)
+ {
+ retval = "exists";
+ }
+ else
+ {
+ entry->hash_value = value;
+ entry->hash_string = string;
+ handle->hash_stat[STAT_USED] += 1;
+ }
+ }
+ return retval;
+}
+
+/*
+ * h a s h _ j a m ( )
+ *
+ * Regardless of what was in the symbol table before, after hash_jam()
+ * the named symbol has the given value. The symbol is either inserted or
+ * (its value is) replaced.
+ * An error message string is returned, 0 means OK.
+ *
+ * WARNING: this may decide to grow the hashed symbol table.
+ * To do this, we call hash_grow(), WHICH WILL recursively CALL US.
+ *
+ * We report status internally: hash_found is TRUE if we replaced, but
+ * false if we inserted.
+ */
+const char *
+hash_jam (handle, string, value)
+ struct hash_control *handle;
+ const char *string;
+ PTR value;
+{
+ const char *retval;
+ struct hash_entry *entry;
+
+ retval = 0;
+ if (handle->hash_stat[STAT_USED] > handle->hash_full)
+ {
+ retval = hash_grow (handle);
+ }
+ if (!retval)
+ {
+ entry = hash_ask (handle, string, STAT__WRITE);
+ if (!hash_found)
+ {
+ entry->hash_string = string;
+ handle->hash_stat[STAT_USED] += 1;
+ }
+ entry->hash_value = value;
+ }
+ return retval;
+}
+
+/*
+ * h a s h _ g r o w ( )
+ *
+ * Grow a new (bigger) hash table from the old one.
+ * We choose to double the hash table's size.
+ * Return a human-scrutible error string: 0 if OK.
+ * Warning! This uses hash_jam(), which had better not recurse
+ * back here! Hash_jam() conditionally calls us, but we ALWAYS
+ * call hash_jam()!
+ * Internal.
+ */
+static const char *
+hash_grow (handle) /* make a hash table grow */
+ struct hash_control *handle;
+{
+ struct hash_entry *newwall;
+ struct hash_entry *newwhere;
+ struct hash_entry *newtrack;
+ struct hash_entry *oldtrack;
+ struct hash_entry *oldwhere;
+ struct hash_entry *oldwall;
+ int temp;
+ int newsize;
+ const char *string;
+ const char *retval;
+#ifdef SUSPECT
+ int oldused;
+#endif
+
+ /*
+ * capture info about old hash table
+ */
+ oldwhere = handle->hash_where;
+ oldwall = handle->hash_wall;
+#ifdef SUSPECT
+ oldused = handle->hash_stat[STAT_USED];
+#endif
+ /*
+ * attempt to get enough room for a hash table twice as big
+ */
+ temp = handle->hash_stat[STAT_SIZE];
+ newwhere = ((struct hash_entry *)
+ xmalloc ((unsigned long) ((temp << (GROW_FACTOR + 1))
+ /* +1 for wall slot */
+ * sizeof (struct hash_entry))));
+ if (newwhere == NULL)
+ return "no_room";
+
+ /*
+ * have enough room: now we do all the work.
+ * double the size of everything in handle.
+ */
+ handle->hash_mask = ((handle->hash_mask + 1) << GROW_FACTOR) - 1;
+ handle->hash_stat[STAT_SIZE] <<= GROW_FACTOR;
+ newsize = handle->hash_stat[STAT_SIZE];
+ handle->hash_where = newwhere;
+ handle->hash_full <<= GROW_FACTOR;
+ handle->hash_sizelog += GROW_FACTOR;
+ handle->hash_wall = newwall = newwhere + newsize;
+ /* Set all those pesky new slots to vacant. */
+ for (newtrack = newwhere; newtrack <= newwall; newtrack++)
+ newtrack->hash_string = NULL;
+ /* We will do a scan of the old table, the hard way, using the
+ * new control block to re-insert the data into new hash table. */
+ handle->hash_stat[STAT_USED] = 0;
+ for (oldtrack = oldwhere; oldtrack < oldwall; oldtrack++)
+ if (((string = oldtrack->hash_string) != NULL) && string != DELETED)
+ if ((retval = hash_jam (handle, string, oldtrack->hash_value)))
+ return retval;
+
+#ifdef SUSPECT
+ if (handle->hash_stat[STAT_USED] != oldused)
+ return "hash_used";
+#endif
+
+ /* We have a completely faked up control block.
+ Return the old hash table. */
+ free ((char *) oldwhere);
+
+ return 0;
+}
+
+#ifdef TEST
+/*
+ * h a s h _ a p p l y ( )
+ *
+ * Use this to scan each entry in symbol table.
+ * For each symbol, this calls (applys) a nominated function supplying the
+ * symbol's value (and the symbol's name).
+ * The idea is you use this to destroy whatever is associted with
+ * any values in the table BEFORE you destroy the table with hash_die.
+ * Of course, you can use it for other jobs; whenever you need to
+ * visit all extant symbols in the table.
+ *
+ * We choose to have a call-you-back idea for two reasons:
+ * asthetic: it is a neater idea to use apply than an explicit loop
+ * sensible: if we ever had to grow the symbol table (due to insertions)
+ * then we would lose our place in the table when we re-hashed
+ * symbols into the new table in a different order.
+ *
+ * The order symbols are visited depends entirely on the hashing function.
+ * Whenever you insert a (symbol, value) you risk expanding the table. If
+ * you do expand the table, then the hashing function WILL change, so you
+ * MIGHT get a different order of symbols visited. In other words, if you
+ * want the same order of visiting symbols as the last time you used
+ * hash_apply() then you better not have done any hash_insert()s or
+ * hash_jam()s since the last time you used hash_apply().
+ *
+ * In future we may use the value returned by your nominated function.
+ * One idea is to abort the scan if, after applying the function to a
+ * certain node, the function returns a certain code.
+ *
+ * The function you supply should be of the form:
+ * void myfunct(string,value)
+ * char * string; |* the symbol's name *|
+ * char * value; |* the symbol's value *|
+ * {
+ * |* ... *|
+ * }
+ *
+ */
+void
+hash_apply (handle, function)
+ struct hash_control *handle;
+ void (*function) ();
+{
+ struct hash_entry *entry;
+ struct hash_entry *wall;
+
+ wall = handle->hash_wall;
+ for (entry = handle->hash_where; entry < wall; entry++)
+ {
+ if (islive (entry)) /* silly code: tests entry->string twice! */
+ {
+ (*function) (entry->hash_string, entry->hash_value);
+ }
+ }
+}
+#endif
+
+/*
+ * h a s h _ f i n d ( )
+ *
+ * Given symbol string, find value (if any).
+ * Return found value or NULL.
+ */
+PTR
+hash_find (handle, string)
+ struct hash_control *handle;
+ const char *string;
+{
+ struct hash_entry *entry;
+
+ entry = hash_ask (handle, string, STAT__READ);
+ if (hash_found)
+ return entry->hash_value;
+ else
+ return NULL;
+}
+
+/*
+ * h a s h _ a s k ( )
+ *
+ * Searches for given symbol string.
+ * Return the slot where it OUGHT to live. It may be there.
+ * Return hash_found: TRUE only if symbol is in that slot.
+ * Access argument is to help keep statistics in control block.
+ * Internal.
+ */
+static struct hash_entry * /* string slot, may be empty or deleted */
+hash_ask (handle, string, access_type)
+ struct hash_control *handle;
+ const char *string;
+ int access_type;
+{
+ const char *s;
+ struct hash_entry *slot;
+ int collision; /* count collisions */
+ int strcmps;
+ int hcode;
+
+ /* start looking here */
+ hcode = hash_code (handle, string);
+ slot = handle->hash_where + (hcode & handle->hash_mask);
+
+ handle->hash_stat[STAT_ACCESS + access_type] += 1;
+ collision = strcmps = 0;
+ hash_found = FALSE;
+ while (((s = slot->hash_string) != NULL) && s != DELETED)
+ {
+ if (string == s)
+ {
+ hash_found = TRUE;
+ break;
+ }
+ if (slot->h == (unsigned long) hcode)
+ {
+ if (!strcmp (string, s))
+ {
+ hash_found = TRUE;
+ break;
+ }
+ strcmps++;
+ }
+ collision++;
+ slot++;
+ }
+ /*
+ * slot: return:
+ * in use: we found string slot
+ * at empty:
+ * at wall: we fell off: wrap round ????
+ * in table: dig here slot
+ * at DELETED: dig here slot
+ */
+ if (slot == handle->hash_wall)
+ {
+ slot = handle->hash_where;/* now look again */
+ while (((s = slot->hash_string) != NULL) && s != DELETED)
+ {
+ if (string == s)
+ {
+ hash_found = TRUE;
+ break;
+ }
+ if (slot->h == (unsigned long) hcode)
+ {
+ if (!strcmp (string, s))
+ {
+ hash_found = TRUE;
+ break;
+ }
+ strcmps++;
+ }
+ collision++;
+ slot++;
+ }
+ /*
+ * slot: return:
+ * in use: we found it slot
+ * empty: wall: ERROR IMPOSSIBLE !!!!
+ * in table: dig here slot
+ * DELETED:dig here slot
+ */
+ }
+ handle->hash_stat[STAT_COLLIDE + access_type] += collision;
+ handle->hash_stat[STAT_STRCMP + access_type] += strcmps;
+ if (!hash_found)
+ slot->h = hcode;
+ return slot; /* also return hash_found */
+}
+
+/*
+ * h a s h _ c o d e
+ *
+ * Does hashing of symbol string to hash number.
+ * Internal.
+ */
+static int
+hash_code (handle, string)
+ struct hash_control *handle;
+ const char *string;
+{
+#if 1 /* There seems to be some interesting property of this function
+ that prevents the bfd version below from being an adequate
+ substitute. @@ Figure out what this property is! */
+ long h; /* hash code built here */
+ long c; /* each character lands here */
+ int n; /* Amount to shift h by */
+
+ n = (handle->hash_sizelog - 3);
+ h = 0;
+ while ((c = *string++) != 0)
+ {
+ h += c;
+ h = (h << 3) + (h >> n) + c;
+ }
+ return h;
+#else
+ /* from bfd */
+ unsigned long h = 0;
+ unsigned int len = 0;
+ unsigned int c;
+
+ while ((c = *string++) != 0)
+ {
+ h += c + (c << 17);
+ h ^= h >> 2;
+ ++len;
+ }
+ h += len + (len << 17);
+ h ^= h >> 2;
+ return h;
+#endif
+}
+
+void
+hash_print_statistics (file, name, h)
+ FILE *file;
+ const char *name;
+ struct hash_control *h;
+{
+ unsigned long sz, used, pct;
+
+ if (h == 0)
+ return;
+
+ sz = h->hash_stat[STAT_SIZE];
+ used = h->hash_stat[STAT_USED];
+ pct = (used * 100 + sz / 2) / sz;
+
+ fprintf (file, "%s hash statistics:\n\t%lu/%lu slots used (%lu%%)\n",
+ name, used, sz, pct);
+
+#define P(name, off) \
+ fprintf (file, "\t%-16s %6dr + %6dw = %7d\n", name, \
+ h->hash_stat[off+STAT__READ], \
+ h->hash_stat[off+STAT__WRITE], \
+ h->hash_stat[off+STAT__READ] + h->hash_stat[off+STAT__WRITE])
+
+ P ("accesses:", STAT_ACCESS);
+ P ("collisions:", STAT_COLLIDE);
+ P ("string compares:", STAT_STRCMP);
+
+#undef P
+}
+
+/*
+ * Here is a test program to exercise above.
+ */
+#ifdef TEST
+
+#define TABLES (6) /* number of hash tables to maintain */
+/* (at once) in any testing */
+#define STATBUFSIZE (12) /* we can have 12 statistics */
+
+int statbuf[STATBUFSIZE]; /* display statistics here */
+char answer[100]; /* human farts here */
+char *hashtable[TABLES]; /* we test many hash tables at once */
+char *h; /* points to curent hash_control */
+char **pp;
+char *p;
+char *name;
+char *value;
+int size;
+int used;
+char command;
+int number; /* number 0:TABLES-1 of current hashed */
+/* symbol table */
+
+main ()
+{
+ void applicatee ();
+ void destroy ();
+ char *what ();
+ int *ip;
+
+ number = 0;
+ h = 0;
+ printf ("type h <RETURN> for help\n");
+ for (;;)
+ {
+ printf ("hash_test command: ");
+ gets (answer);
+ command = answer[0];
+ if (isupper (command))
+ command = tolower (command); /* ecch! */
+ switch (command)
+ {
+ case '#':
+ printf ("old hash table #=%d.\n", number);
+ whattable ();
+ break;
+ case '?':
+ for (pp = hashtable; pp < hashtable + TABLES; pp++)
+ {
+ printf ("address of hash table #%d control block is %xx\n"
+ ,pp - hashtable, *pp);
+ }
+ break;
+ case 'a':
+ hash_apply (h, applicatee);
+ break;
+ case 'd':
+ hash_apply (h, destroy);
+ hash_die (h);
+ break;
+ case 'f':
+ p = hash_find (h, name = what ("symbol"));
+ printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT");
+ break;
+ case 'h':
+ printf ("# show old, select new default hash table number\n");
+ printf ("? display all hashtable control block addresses\n");
+ printf ("a apply a simple display-er to each symbol in table\n");
+ printf ("d die: destroy hashtable\n");
+ printf ("f find value of nominated symbol\n");
+ printf ("h this help\n");
+ printf ("i insert value into symbol\n");
+ printf ("j jam value into symbol\n");
+ printf ("n new hashtable\n");
+ printf ("r replace a value with another\n");
+ printf ("s say what %% of table is used\n");
+ printf ("q exit this program\n");
+ printf ("x delete a symbol from table, report its value\n");
+ break;
+ case 'i':
+ p = hash_insert (h, name = what ("symbol"), value = what ("value"));
+ if (p)
+ {
+ printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value,
+ p);
+ }
+ break;
+ case 'j':
+ p = hash_jam (h, name = what ("symbol"), value = what ("value"));
+ if (p)
+ {
+ printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p);
+ }
+ break;
+ case 'n':
+ h = hashtable[number] = (char *) hash_new ();
+ break;
+ case 'q':
+ exit (EXIT_SUCCESS);
+ case 'r':
+ p = hash_replace (h, name = what ("symbol"), value = what ("value"));
+ printf ("old value was \"%s\"\n", p ? p : "{}");
+ break;
+ case 's':
+ hash_say (h, statbuf, STATBUFSIZE);
+ for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++)
+ {
+ printf ("%d ", *ip);
+ }
+ printf ("\n");
+ break;
+ case 'x':
+ p = hash_delete (h, name = what ("symbol"));
+ printf ("old value was \"%s\"\n", p ? p : "{}");
+ break;
+ default:
+ printf ("I can't understand command \"%c\"\n", command);
+ break;
+ }
+ }
+}
+
+char *
+what (description)
+ char *description;
+{
+ char *retval;
+ char *malloc ();
+
+ printf (" %s : ", description);
+ gets (answer);
+ /* will one day clean up answer here */
+ retval = malloc (strlen (answer) + 1);
+ if (!retval)
+ {
+ error ("room");
+ }
+ (void) strcpy (retval, answer);
+ return (retval);
+}
+
+void
+destroy (string, value)
+ char *string;
+ char *value;
+{
+ free (string);
+ free (value);
+}
+
+
+void
+applicatee (string, value)
+ char *string;
+ char *value;
+{
+ printf ("%.20s-%.20s\n", string, value);
+}
+
+whattable () /* determine number: what hash table to use */
+ /* also determine h: points to hash_control */
+{
+
+ for (;;)
+ {
+ printf (" what hash table (%d:%d) ? ", 0, TABLES - 1);
+ gets (answer);
+ sscanf (answer, "%d", &number);
+ if (number >= 0 && number < TABLES)
+ {
+ h = hashtable[number];
+ if (!h)
+ {
+ printf ("warning: current hash-table-#%d. has no hash-control\n", number);
+ }
+ return;
+ }
+ else
+ {
+ printf ("invalid hash table number: %d\n", number);
+ }
+ }
+}
+
+
+
+#endif /* #ifdef TEST */
+
+/* end of hash.c */
diff --git a/gas/hash.h b/gas/hash.h
new file mode 100644
index 00000000000..fb229c8086a
--- /dev/null
+++ b/gas/hash.h
@@ -0,0 +1,45 @@
+/* hash.h - for hash.c
+ Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef hashH
+#define hashH
+
+struct hash_control;
+
+/* returns control block */
+struct hash_control *hash_new PARAMS ((void));
+void hash_die PARAMS ((struct hash_control *));
+/* returns previous value */
+PTR hash_delete PARAMS ((struct hash_control *, const char *str));
+/* returns previous value */
+PTR hash_replace PARAMS ((struct hash_control *, const char *str, PTR val));
+/* returns error string or null */
+const char *hash_insert PARAMS ((struct hash_control *, const char *str,
+ PTR val));
+/* returns value */
+PTR hash_find PARAMS ((struct hash_control *, const char *str));
+/* returns error text or null (internal) */
+const char *hash_jam PARAMS ((struct hash_control *, const char *str,
+ PTR val));
+
+void hash_print_statistics PARAMS ((FILE *, const char *,
+ struct hash_control *));
+#endif /* #ifdef hashH */
+
+/* end of hash.c */
diff --git a/gas/input-file.c b/gas/input-file.c
new file mode 100644
index 00000000000..c63f7c9b63b
--- /dev/null
+++ b/gas/input-file.c
@@ -0,0 +1,248 @@
+/* input_file.c - Deal with Input Files -
+ Copyright (C) 1987, 1990, 1991, 1992, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * Confines all details of reading source bytes to this module.
+ * All O/S specific crocks should live here.
+ * What we lose in "efficiency" we gain in modularity.
+ * Note we don't need to #include the "as.h" file. No common coupling!
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "as.h"
+#include "input-file.h"
+
+static int input_file_get PARAMS ((char **));
+
+/* This variable is non-zero if the file currently being read should be
+ preprocessed by app. It is zero if the file can be read straight in.
+ */
+int preprocess = 0;
+
+/*
+ * This code opens a file, then delivers BUFFER_SIZE character
+ * chunks of the file on demand.
+ * BUFFER_SIZE is supposed to be a number chosen for speed.
+ * The caller only asks once what BUFFER_SIZE is, and asks before
+ * the nature of the input files (if any) is known.
+ */
+
+#define BUFFER_SIZE (32 * 1024)
+
+/*
+ * We use static data: the data area is not sharable.
+ */
+
+static FILE *f_in;
+static char *file_name;
+
+/* Struct for saving the state of this module for file includes. */
+struct saved_file
+ {
+ FILE *f_in;
+ char *file_name;
+ int preprocess;
+ char *app_save;
+ };
+
+/* These hooks accomodate most operating systems. */
+
+void
+input_file_begin ()
+{
+ f_in = (FILE *) 0;
+}
+
+void
+input_file_end ()
+{
+}
+
+/* Return BUFFER_SIZE. */
+unsigned int
+input_file_buffer_size ()
+{
+ return (BUFFER_SIZE);
+}
+
+int
+input_file_is_open ()
+{
+ return f_in != (FILE *) 0;
+}
+
+/* Push the state of our input, returning a pointer to saved info that
+ can be restored with input_file_pop (). */
+char *
+input_file_push ()
+{
+ register struct saved_file *saved;
+
+ saved = (struct saved_file *) xmalloc (sizeof *saved);
+
+ saved->f_in = f_in;
+ saved->file_name = file_name;
+ saved->preprocess = preprocess;
+ if (preprocess)
+ saved->app_save = app_push ();
+
+ input_file_begin (); /* Initialize for new file */
+
+ return (char *) saved;
+}
+
+void
+input_file_pop (arg)
+ char *arg;
+{
+ register struct saved_file *saved = (struct saved_file *) arg;
+
+ input_file_end (); /* Close out old file */
+
+ f_in = saved->f_in;
+ file_name = saved->file_name;
+ preprocess = saved->preprocess;
+ if (preprocess)
+ app_pop (saved->app_save);
+
+ free (arg);
+}
+
+void
+input_file_open (filename, pre)
+ char *filename; /* "" means use stdin. Must not be 0. */
+ int pre;
+{
+ int c;
+ char buf[80];
+
+ preprocess = pre;
+
+ assert (filename != 0); /* Filename may not be NULL. */
+ if (filename[0])
+ { /* We have a file name. Suck it and see. */
+ f_in = fopen (filename, "r");
+ file_name = filename;
+ }
+ else
+ { /* use stdin for the input file. */
+ f_in = stdin;
+ file_name = _("{standard input}"); /* For error messages. */
+ }
+ if (f_in == (FILE *) 0)
+ {
+ as_bad (_("Can't open %s for reading."), file_name);
+ as_perror ("%s", file_name);
+ return;
+ }
+
+ c = getc (f_in);
+ if (c == '#')
+ { /* Begins with comment, may not want to preprocess */
+ c = getc (f_in);
+ if (c == 'N')
+ {
+ fgets (buf, 80, f_in);
+ if (!strcmp (buf, "O_APP\n"))
+ preprocess = 0;
+ if (!strchr (buf, '\n'))
+ ungetc ('#', f_in); /* It was longer */
+ else
+ ungetc ('\n', f_in);
+ }
+ else if (c == '\n')
+ ungetc ('\n', f_in);
+ else
+ ungetc ('#', f_in);
+ }
+ else
+ ungetc (c, f_in);
+}
+
+/* Close input file. */
+void
+input_file_close ()
+{
+ if (f_in != NULL)
+ {
+ fclose (f_in);
+ } /* don't close a null file pointer */
+ f_in = 0;
+} /* input_file_close() */
+
+/* This function is passed to do_scrub_chars. */
+
+static int
+input_file_get (from)
+ char **from;
+{
+ static char buf[BUFFER_SIZE];
+ int size;
+
+ size = fread (buf, sizeof (char), sizeof buf, f_in);
+ if (size < 0)
+ {
+ as_perror (_("Can't read from %s"), file_name);
+ size = 0;
+ }
+ *from = buf;
+ return size;
+}
+
+/* Read a buffer from the input file. */
+
+char *
+input_file_give_next_buffer (where)
+ char *where; /* Where to place 1st character of new buffer. */
+{
+ char *return_value; /* -> Last char of what we read, + 1. */
+ register int size;
+
+ if (f_in == (FILE *) 0)
+ return 0;
+ /*
+ * fflush (stdin); could be done here if you want to synchronise
+ * stdin and stdout, for the case where our input file is stdin.
+ * Since the assembler shouldn't do any output to stdout, we
+ * don't bother to synch output and input.
+ */
+ if (preprocess)
+ size = do_scrub_chars (input_file_get, where, BUFFER_SIZE);
+ else
+ size = fread (where, sizeof (char), BUFFER_SIZE, f_in);
+ if (size < 0)
+ {
+ as_perror (_("Can't read from %s"), file_name);
+ size = 0;
+ }
+ if (size)
+ return_value = where + size;
+ else
+ {
+ if (fclose (f_in))
+ as_perror (_("Can't close %s"), file_name);
+ f_in = (FILE *) 0;
+ return_value = 0;
+ }
+ return (return_value);
+}
+
+/* end of input-file.c */
diff --git a/gas/input-file.h b/gas/input-file.h
new file mode 100644
index 00000000000..129bf2821d0
--- /dev/null
+++ b/gas/input-file.h
@@ -0,0 +1,68 @@
+/* input_file.h header for input-file.c
+ Copyright (C) 1987, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*"input_file.c":Operating-system dependant functions to read source files.*/
+
+
+/*
+ * No matter what the operating system, this module must provide the
+ * following services to its callers.
+ *
+ * input_file_begin() Call once before anything else.
+ *
+ * input_file_end() Call once after everything else.
+ *
+ * input_file_buffer_size() Call anytime. Returns largest possible
+ * delivery from
+ * input_file_give_next_buffer().
+ *
+ * input_file_open(name) Call once for each input file.
+ *
+ * input_file_give_next_buffer(where) Call once to get each new buffer.
+ * Return 0: no more chars left in file,
+ * the file has already been closed.
+ * Otherwise: return a pointer to just
+ * after the last character we read
+ * into the buffer.
+ * If we can only read 0 characters, then
+ * end-of-file is faked.
+ *
+ * input_file_push() Push state, which can be restored
+ * later. Does implicit input_file_begin.
+ * Returns char * to saved state.
+ *
+ * input_file_pop (arg) Pops previously saved state.
+ *
+ * input_file_close () Closes opened file.
+ *
+ * All errors are reported (using as_perror) so caller doesn't have to think
+ * about I/O errors. No I/O errors are fatal: an end-of-file may be faked.
+ */
+
+char *input_file_give_next_buffer PARAMS ((char *where));
+char *input_file_push PARAMS ((void));
+unsigned int input_file_buffer_size PARAMS ((void));
+int input_file_is_open PARAMS ((void));
+void input_file_begin PARAMS ((void));
+void input_file_close PARAMS ((void));
+void input_file_end PARAMS ((void));
+void input_file_open PARAMS ((char *filename, int pre));
+void input_file_pop PARAMS ((char *arg));
+
+/* end of input_file.h */
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
new file mode 100644
index 00000000000..46a3bb3b7f8
--- /dev/null
+++ b/gas/input-scrub.c
@@ -0,0 +1,521 @@
+/* input_scrub.c - Break up input buffers into whole numbers of lines.
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <errno.h> /* Need this to make errno declaration right */
+#include "as.h"
+#include "input-file.h"
+#include "sb.h"
+#include "listing.h"
+
+/*
+ * O/S independent module to supply buffers of sanitised source code
+ * to rest of assembler. We get sanitised input data of arbitrary length.
+ * We break these buffers on line boundaries, recombine pieces that
+ * were broken across buffers, and return a buffer of full lines to
+ * the caller.
+ * The last partial line begins the next buffer we build and return to caller.
+ * The buffer returned to caller is preceeded by BEFORE_STRING and followed
+ * by AFTER_STRING, as sentinels. The last character before AFTER_STRING
+ * is a newline.
+ * Also looks after line numbers, for e.g. error messages.
+ */
+
+/*
+ * We don't care how filthy our buffers are, but our callers assume
+ * that the following sanitation has already been done.
+ *
+ * No comments, reduce a comment to a space.
+ * Reduce a tab to a space unless it is 1st char of line.
+ * All multiple tabs and spaces collapsed into 1 char. Tab only
+ * legal if 1st char of line.
+ * # line file statements converted to .line x;.file y; statements.
+ * Escaped newlines at end of line: remove them but add as many newlines
+ * to end of statement as you removed in the middle, to synch line numbers.
+ */
+
+#define BEFORE_STRING ("\n")
+#define AFTER_STRING ("\0") /* memcpy of 0 chars might choke. */
+#define BEFORE_SIZE (1)
+#define AFTER_SIZE (1)
+
+static char *buffer_start; /*->1st char of full buffer area. */
+static char *partial_where; /*->after last full line in buffer. */
+static int partial_size; /* >=0. Number of chars in partial line in buffer. */
+static char save_source[AFTER_SIZE];
+/* Because we need AFTER_STRING just after last */
+/* full line, it clobbers 1st part of partial */
+/* line. So we preserve 1st part of partial */
+/* line here. */
+static unsigned int buffer_length; /* What is the largest size buffer that */
+/* input_file_give_next_buffer() could */
+/* return to us? */
+
+/* The index into an sb structure we are reading from. -1 if none. */
+static int sb_index = -1;
+
+/* If we are reading from an sb structure, this is it. */
+static sb from_sb;
+
+/* The number of nested sb structures we have included. */
+int macro_nest;
+
+/* We can have more than one source file open at once, though the info for all
+ but the latest one are saved off in a struct input_save. These files remain
+ open, so we are limited by the number of open files allowed by the
+ underlying OS. We may also sequentially read more than one source file in an
+ assembly. */
+
+/* We must track the physical file and line number for error messages. We also
+ track a "logical" file and line number corresponding to (C?) compiler
+ source line numbers. Whenever we open a file we must fill in
+ physical_input_file. So if it is NULL we have not opened any files yet. */
+
+static char *physical_input_file;
+static char *logical_input_file;
+
+typedef unsigned int line_numberT; /* 1-origin line number in a source file. */
+/* A line ends in '\n' or eof. */
+
+static line_numberT physical_input_line;
+static int logical_input_line;
+
+/* Struct used to save the state of the input handler during include files */
+struct input_save
+ {
+ char *buffer_start;
+ char *partial_where;
+ int partial_size;
+ char save_source[AFTER_SIZE];
+ unsigned int buffer_length;
+ char *physical_input_file;
+ char *logical_input_file;
+ line_numberT physical_input_line;
+ int logical_input_line;
+ int sb_index;
+ sb from_sb;
+ struct input_save *next_saved_file; /* Chain of input_saves */
+ char *input_file_save; /* Saved state of input routines */
+ char *saved_position; /* Caller's saved position in buf */
+ };
+
+static struct input_save *input_scrub_push PARAMS ((char *saved_position));
+static char *input_scrub_pop PARAMS ((struct input_save *arg));
+static void as_1_char PARAMS ((unsigned int c, FILE * stream));
+
+/* Saved information about the file that .include'd this one. When we hit EOF,
+ we automatically pop to that file. */
+
+static struct input_save *next_saved_file;
+
+/* Push the state of input reading and scrubbing so that we can #include.
+ The return value is a 'void *' (fudged for old compilers) to a save
+ area, which can be restored by passing it to input_scrub_pop(). */
+static struct input_save *
+input_scrub_push (saved_position)
+ char *saved_position;
+{
+ register struct input_save *saved;
+
+ saved = (struct input_save *) xmalloc (sizeof *saved);
+
+ saved->saved_position = saved_position;
+ saved->buffer_start = buffer_start;
+ saved->partial_where = partial_where;
+ saved->partial_size = partial_size;
+ saved->buffer_length = buffer_length;
+ saved->physical_input_file = physical_input_file;
+ saved->logical_input_file = logical_input_file;
+ saved->physical_input_line = physical_input_line;
+ saved->logical_input_line = logical_input_line;
+ saved->sb_index = sb_index;
+ saved->from_sb = from_sb;
+ memcpy (saved->save_source, save_source, sizeof (save_source));
+ saved->next_saved_file = next_saved_file;
+ saved->input_file_save = input_file_push ();
+
+ input_file_begin (); /* Reinitialize! */
+ logical_input_line = -1;
+ logical_input_file = (char *) NULL;
+ buffer_length = input_file_buffer_size ();
+ sb_index = -1;
+
+ buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
+ memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
+
+ return saved;
+} /* input_scrub_push() */
+
+static char *
+input_scrub_pop (saved)
+ struct input_save *saved;
+{
+ char *saved_position;
+
+ input_scrub_end (); /* Finish off old buffer */
+
+ input_file_pop (saved->input_file_save);
+ saved_position = saved->saved_position;
+ buffer_start = saved->buffer_start;
+ buffer_length = saved->buffer_length;
+ physical_input_file = saved->physical_input_file;
+ logical_input_file = saved->logical_input_file;
+ physical_input_line = saved->physical_input_line;
+ logical_input_line = saved->logical_input_line;
+ sb_index = saved->sb_index;
+ from_sb = saved->from_sb;
+ partial_where = saved->partial_where;
+ partial_size = saved->partial_size;
+ next_saved_file = saved->next_saved_file;
+ memcpy (save_source, saved->save_source, sizeof (save_source));
+
+ free (saved);
+ return saved_position;
+}
+
+
+void
+input_scrub_begin ()
+{
+ know (strlen (BEFORE_STRING) == BEFORE_SIZE);
+ know (strlen (AFTER_STRING) == AFTER_SIZE || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1));
+
+ input_file_begin ();
+
+ buffer_length = input_file_buffer_size ();
+
+ buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
+ memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
+
+ /* Line number things. */
+ logical_input_line = -1;
+ logical_input_file = (char *) NULL;
+ physical_input_file = NULL; /* No file read yet. */
+ next_saved_file = NULL; /* At EOF, don't pop to any other file */
+ do_scrub_begin (flag_m68k_mri);
+}
+
+void
+input_scrub_end ()
+{
+ if (buffer_start)
+ {
+ free (buffer_start);
+ buffer_start = 0;
+ input_file_end ();
+ }
+}
+
+/* Start reading input from a new file. */
+
+char * /* Return start of caller's part of buffer. */
+input_scrub_new_file (filename)
+ char *filename;
+{
+ input_file_open (filename, !flag_no_comments);
+ physical_input_file = filename[0] ? filename : _("{standard input}");
+ physical_input_line = 0;
+
+ partial_size = 0;
+ return (buffer_start + BEFORE_SIZE);
+}
+
+
+/* Include a file from the current file. Save our state, cause it to
+ be restored on EOF, and begin handling a new file. Same result as
+ input_scrub_new_file. */
+
+char *
+input_scrub_include_file (filename, position)
+ char *filename;
+ char *position;
+{
+ next_saved_file = input_scrub_push (position);
+ return input_scrub_new_file (filename);
+}
+
+/* Start getting input from an sb structure. This is used when
+ expanding a macro. */
+
+void
+input_scrub_include_sb (from, position)
+ sb *from;
+ char *position;
+{
+ if (macro_nest > max_macro_nest)
+ as_fatal (_("macros nested too deeply"));
+ ++macro_nest;
+
+ next_saved_file = input_scrub_push (position);
+
+ sb_new (&from_sb);
+ if (from->len >= 1 && from->ptr[0] != '\n')
+ {
+ /* Add the sentinel required by read.c. */
+ sb_add_char (&from_sb, '\n');
+ }
+ sb_add_sb (&from_sb, from);
+ sb_index = 1;
+
+ /* These variables are reset by input_scrub_push. Restore them
+ since we are, after all, still at the same point in the file. */
+ logical_input_line = next_saved_file->logical_input_line;
+ logical_input_file = next_saved_file->logical_input_file;
+}
+
+void
+input_scrub_close ()
+{
+ input_file_close ();
+}
+
+char *
+input_scrub_next_buffer (bufp)
+ char **bufp;
+{
+ register char *limit; /*->just after last char of buffer. */
+
+ if (sb_index >= 0)
+ {
+ if (sb_index >= from_sb.len)
+ {
+ sb_kill (&from_sb);
+ cond_finish_check (macro_nest);
+ --macro_nest;
+ partial_where = NULL;
+ if (next_saved_file != NULL)
+ *bufp = input_scrub_pop (next_saved_file);
+ return partial_where;
+ }
+
+ partial_where = from_sb.ptr + from_sb.len;
+ partial_size = 0;
+ *bufp = from_sb.ptr + sb_index;
+ sb_index = from_sb.len;
+ return partial_where;
+ }
+
+ *bufp = buffer_start + BEFORE_SIZE;
+
+ if (partial_size)
+ {
+ memcpy (buffer_start + BEFORE_SIZE, partial_where,
+ (unsigned int) partial_size);
+ memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
+ }
+ limit = input_file_give_next_buffer (buffer_start
+ + BEFORE_SIZE
+ + partial_size);
+ if (limit)
+ {
+ register char *p; /* Find last newline. */
+
+ for (p = limit - 1; *p != '\n'; --p)
+ ;
+ ++p;
+
+ while (p <= buffer_start + BEFORE_SIZE)
+ {
+ int limoff;
+
+ limoff = limit - buffer_start;
+ buffer_length += input_file_buffer_size ();
+ buffer_start = xrealloc (buffer_start,
+ (BEFORE_SIZE
+ + 2 * buffer_length
+ + AFTER_SIZE));
+ *bufp = buffer_start + BEFORE_SIZE;
+ limit = input_file_give_next_buffer (buffer_start + limoff);
+
+ if (limit == NULL)
+ {
+ as_warn (_("partial line at end of file ignored"));
+ partial_where = NULL;
+ if (next_saved_file)
+ *bufp = input_scrub_pop (next_saved_file);
+ return NULL;
+ }
+
+ for (p = limit - 1; *p != '\n'; --p)
+ ;
+ ++p;
+ }
+
+ partial_where = p;
+ partial_size = limit - p;
+ memcpy (save_source, partial_where, (int) AFTER_SIZE);
+ memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
+ }
+ else
+ {
+ partial_where = 0;
+ if (partial_size > 0)
+ {
+ as_warn (_("Partial line at end of file ignored"));
+ }
+
+ /* Tell the listing we've finished the file. */
+ LISTING_EOF ();
+
+ /* If we should pop to another file at EOF, do it. */
+ if (next_saved_file)
+ {
+ *bufp = input_scrub_pop (next_saved_file); /* Pop state */
+ /* partial_where is now correct to return, since we popped it. */
+ }
+ }
+ return (partial_where);
+} /* input_scrub_next_buffer() */
+
+/*
+ * The remaining part of this file deals with line numbers, error
+ * messages and so on.
+ */
+
+
+int
+seen_at_least_1_file () /* TRUE if we opened any file. */
+{
+ return (physical_input_file != NULL);
+}
+
+void
+bump_line_counters ()
+{
+ if (sb_index < 0)
+ {
+ ++physical_input_line;
+ if (logical_input_line >= 0)
+ ++logical_input_line;
+ }
+}
+
+/*
+ * new_logical_line()
+ *
+ * Tells us what the new logical line number and file are.
+ * If the line_number is -1, we don't change the current logical line
+ * number. If it is -2, we decrement the logical line number (this is
+ * to support the .appfile pseudo-op inserted into the stream by
+ * do_scrub_chars).
+ * If the fname is NULL, we don't change the current logical file name.
+ * Returns nonzero if the filename actually changes.
+ */
+int
+new_logical_line (fname, line_number)
+ char *fname; /* DON'T destroy it! We point to it! */
+ int line_number;
+{
+ if (line_number >= 0)
+ logical_input_line = line_number;
+ else if (line_number == -2 && logical_input_line > 0)
+ --logical_input_line;
+
+ if (fname
+ && (logical_input_file == NULL
+ || strcmp (logical_input_file, fname)))
+ {
+ logical_input_file = fname;
+ return 1;
+ }
+ else
+ return 0;
+} /* new_logical_line() */
+
+/*
+ * a s _ w h e r e ()
+ *
+ * Return the current file name and line number.
+ * namep should be char * const *, but there are compilers which screw
+ * up declarations like that, and it's easier to avoid it.
+ */
+void
+as_where (namep, linep)
+ char **namep;
+ unsigned int *linep;
+{
+ if (logical_input_file != NULL
+ && (linep == NULL || logical_input_line >= 0))
+ {
+ *namep = logical_input_file;
+ if (linep != NULL)
+ *linep = logical_input_line;
+ }
+ else if (physical_input_file != NULL)
+ {
+ *namep = physical_input_file;
+ if (linep != NULL)
+ *linep = physical_input_line;
+ }
+ else
+ {
+ *namep = 0;
+ if (linep != NULL)
+ *linep = 0;
+ }
+} /* as_where() */
+
+
+
+
+/*
+ * a s _ h o w m u c h ()
+ *
+ * Output to given stream how much of line we have scanned so far.
+ * Assumes we have scanned up to and including input_line_pointer.
+ * No free '\n' at end of line.
+ */
+void
+as_howmuch (stream)
+ FILE *stream; /* Opened for write please. */
+{
+ register char *p; /* Scan input line. */
+ /* register char c; JF unused */
+
+ for (p = input_line_pointer - 1; *p != '\n'; --p)
+ {
+ }
+ ++p; /* p->1st char of line. */
+ for (; p <= input_line_pointer; p++)
+ {
+ /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */
+ as_1_char ((unsigned char) *p, stream);
+ }
+}
+
+static void
+as_1_char (c, stream)
+ unsigned int c;
+ FILE *stream;
+{
+ if (c > 127)
+ {
+ (void) putc ('%', stream);
+ c -= 128;
+ }
+ if (c < 32)
+ {
+ (void) putc ('^', stream);
+ c += '@';
+ }
+ (void) putc (c, stream);
+}
+
+/* end of input_scrub.c */
diff --git a/gas/itbl-lex.l b/gas/itbl-lex.l
new file mode 100644
index 00000000000..a905ddd007a
--- /dev/null
+++ b/gas/itbl-lex.l
@@ -0,0 +1,114 @@
+/* itbl-lex.l
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+%{
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "itbl-parse.h"
+
+#ifdef DEBUG
+#define DBG(x) printf x
+#define MDBG(x) printf x
+#else
+#define DBG(x)
+#define MDBG(x)
+#endif
+
+int insntbl_line = 1;
+%}
+
+ALNUM [A-Za-z0-9_]
+DIGIT [0-9]
+ALPHA [A-Za-z_]
+HEX [0-9A-Fa-f]
+
+%%
+
+"creg"|"CREG" {
+ return CREG;
+ }
+"dreg"|"DREG" {
+ return DREG;
+ }
+"greg"|"GREG" {
+ return GREG;
+ }
+"immed"|"IMMED" {
+ return IMMED;
+ }
+"addr"|"ADDR" {
+ return ADDR;
+ }
+"insn"|"INSN" {
+ return INSN;
+ }
+"p"{DIGIT} {
+ yytext[yyleng] = 0;
+ yylval.processor = strtoul (yytext+1, 0, 0);
+ return PNUM;
+ }
+{DIGIT}+ {
+ yytext[yyleng] = 0;
+ yylval.num = strtoul (yytext, 0, 0);
+ return NUM;
+ }
+"0x"{HEX}+ {
+ yytext[yyleng] = 0;
+ yylval.num = strtoul (yytext, 0, 0);
+ return NUM;
+ }
+{ALPHA}{ALNUM}* {
+ yytext[yyleng] = 0;
+ yylval.str = strdup (yytext);
+ return ID;
+ }
+";"|"#" {
+ int c;
+ while ((c = input ()) != EOF)
+ {
+ if (c == '\n')
+ {
+ unput (c);
+ break;
+ }
+ }
+ }
+"\n" {
+ insntbl_line++;
+ MDBG (("in lex, NL = %d (x%x)\n", NL, NL));
+ return NL;
+ }
+" "|"\t" {
+ }
+. {
+ MDBG (("char = %x, %d\n", yytext[0], yytext[0]));
+ return yytext[0];
+ }
+%%
+
+#ifndef yywrap
+int
+yywrap ()
+ {
+ return 1;
+ }
+#endif
diff --git a/gas/itbl-ops.c b/gas/itbl-ops.c
new file mode 100644
index 00000000000..f008dcafebc
--- /dev/null
+++ b/gas/itbl-ops.c
@@ -0,0 +1,921 @@
+/* itbl-ops.c
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*======================================================================*/
+/*
+ * Herein lies the support for dynamic specification of processor
+ * instructions and registers. Mnemonics, values, and formats for each
+ * instruction and register are specified in an ascii file consisting of
+ * table entries. The grammar for the table is defined in the document
+ * "Processor instruction table specification".
+ *
+ * Instructions use the gnu assembler syntax, with the addition of
+ * allowing mnemonics for register.
+ * Eg. "func $2,reg3,0x100,symbol ; comment"
+ * func - opcode name
+ * $n - register n
+ * reg3 - mnemonic for processor's register defined in table
+ * 0xddd..d - immediate value
+ * symbol - address of label or external symbol
+ *
+ * First, itbl_parse reads in the table of register and instruction
+ * names and formats, and builds a list of entries for each
+ * processor/type combination. lex and yacc are used to parse
+ * the entries in the table and call functions defined here to
+ * add each entry to our list.
+ *
+ * Then, when assembling or disassembling, these functions are called to
+ * 1) get information on a processor's registers and
+ * 2) assemble/disassemble an instruction.
+ * To assemble(disassemble) an instruction, the function
+ * itbl_assemble(itbl_disassemble) is called to search the list of
+ * instruction entries, and if a match is found, uses the format
+ * described in the instruction entry structure to complete the action.
+ *
+ * Eg. Suppose we have a Mips coprocessor "cop3" with data register "d2"
+ * and we want to define function "pig" which takes two operands.
+ *
+ * Given the table entries:
+ * "p3 insn pig 0x1:24-21 dreg:20-16 immed:15-0"
+ * "p3 dreg d2 0x2"
+ * and that the instruction encoding for coprocessor pz has encoding:
+ * #define MIPS_ENCODE_COP_NUM(z) ((0x21|(z<<1))<<25)
+ * #define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
+ *
+ * a structure to describe the instruction might look something like:
+ * struct itbl_entry = {
+ * e_processor processor = e_p3
+ * e_type type = e_insn
+ * char *name = "pig"
+ * uint value = 0x1
+ * uint flags = 0
+ * struct itbl_range range = 24-21
+ * struct itbl_field *field = {
+ * e_type type = e_dreg
+ * struct itbl_range range = 20-16
+ * struct itbl_field *next = {
+ * e_type type = e_immed
+ * struct itbl_range range = 15-0
+ * struct itbl_field *next = 0
+ * };
+ * };
+ * struct itbl_entry *next = 0
+ * };
+ *
+ * And the assembler instructions:
+ * "pig d2,0x100"
+ * "pig $2,0x100"
+ *
+ * would both assemble to the hex value:
+ * "0x4e220100"
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "itbl-ops.h"
+#include "itbl-parse.h"
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+#include <assert.h>
+#define ASSERT(x) assert(x)
+#define DBG(x) printf x
+#else
+#define ASSERT(x)
+#define DBG(x)
+#endif
+
+#ifndef min
+#define min(a,b) (a<b?a:b)
+#endif
+
+int itbl_have_entries = 0;
+
+/*======================================================================*/
+/* structures for keeping itbl format entries */
+
+struct itbl_range
+ {
+ int sbit; /* mask starting bit position */
+ int ebit; /* mask ending bit position */
+ };
+
+struct itbl_field
+ {
+ e_type type; /* dreg/creg/greg/immed/symb */
+ struct itbl_range range; /* field's bitfield range within instruction */
+ unsigned long flags; /* field flags */
+ struct itbl_field *next; /* next field in list */
+ };
+
+
+/* These structures define the instructions and registers for a processor.
+ * If the type is an instruction, the structure defines the format of an
+ * instruction where the fields are the list of operands.
+ * The flags field below uses the same values as those defined in the
+ * gnu assembler and are machine specific. */
+struct itbl_entry
+ {
+ e_processor processor; /* processor number */
+ e_type type; /* dreg/creg/greg/insn */
+ char *name; /* mnemionic name for insn/register */
+ unsigned long value; /* opcode/instruction mask/register number */
+ unsigned long flags; /* effects of the instruction */
+ struct itbl_range range; /* bit range within instruction for value */
+ struct itbl_field *fields; /* list of operand definitions (if any) */
+ struct itbl_entry *next; /* next entry */
+ };
+
+
+/* local data and structures */
+
+static int itbl_num_opcodes = 0;
+/* Array of entries for each processor and entry type */
+static struct itbl_entry *entries[e_nprocs][e_ntypes] =
+{
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0}
+};
+
+/* local prototypes */
+static unsigned long build_opcode PARAMS ((struct itbl_entry *e));
+static e_type get_type PARAMS ((int yytype));
+static e_processor get_processor PARAMS ((int yyproc));
+static struct itbl_entry **get_entries PARAMS ((e_processor processor,
+ e_type type));
+static struct itbl_entry *find_entry_byname PARAMS ((e_processor processor,
+ e_type type, char *name));
+static struct itbl_entry *find_entry_byval PARAMS ((e_processor processor,
+ e_type type, unsigned long val, struct itbl_range *r));
+static struct itbl_entry *alloc_entry PARAMS ((e_processor processor,
+ e_type type, char *name, unsigned long value));
+static unsigned long apply_range PARAMS ((unsigned long value,
+ struct itbl_range r));
+static unsigned long extract_range PARAMS ((unsigned long value,
+ struct itbl_range r));
+static struct itbl_field *alloc_field PARAMS ((e_type type, int sbit,
+ int ebit, unsigned long flags));
+
+
+/*======================================================================*/
+/* Interfaces to the parser */
+
+
+/* Open the table and use lex and yacc to parse the entries.
+ * Return 1 for failure; 0 for success. */
+
+int
+itbl_parse (char *insntbl)
+{
+ extern FILE *yyin;
+ extern int yyparse (void);
+ yyin = fopen (insntbl, "r");
+ if (yyin == 0)
+ {
+ printf ("Can't open processor instruction specification file \"%s\"\n",
+ insntbl);
+ return 1;
+ }
+ else
+ {
+ while (yyparse ());
+ }
+ fclose (yyin);
+ itbl_have_entries = 1;
+ return 0;
+}
+
+/* Add a register entry */
+
+struct itbl_entry *
+itbl_add_reg (int yyprocessor, int yytype, char *regname,
+ int regnum)
+{
+#if 0
+#include "as.h"
+#include "symbols.h"
+ /* Since register names don't have a prefix, we put them in the symbol table so
+ they can't be used as symbols. This also simplifies argument parsing as
+ we can let gas parse registers for us. The recorded register number is
+ regnum. */
+ /* Use symbol_create here instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+ symbol_table_insert (symbol_create (regname, reg_section,
+ regnum, &zero_address_frag));
+#endif
+ return alloc_entry (get_processor (yyprocessor), get_type (yytype), regname,
+ (unsigned long) regnum);
+}
+
+/* Add an instruction entry */
+
+struct itbl_entry *
+itbl_add_insn (int yyprocessor, char *name, unsigned long value,
+ int sbit, int ebit, unsigned long flags)
+{
+ struct itbl_entry *e;
+ e = alloc_entry (get_processor (yyprocessor), e_insn, name, value);
+ if (e)
+ {
+ e->range.sbit = sbit;
+ e->range.ebit = ebit;
+ e->flags = flags;
+ itbl_num_opcodes++;
+ }
+ return e;
+}
+
+/* Add an operand to an instruction entry */
+
+struct itbl_field *
+itbl_add_operand (struct itbl_entry *e, int yytype, int sbit,
+ int ebit, unsigned long flags)
+{
+ struct itbl_field *f, **last_f;
+ if (!e)
+ return 0;
+ /* Add to end of fields' list. */
+ f = alloc_field (get_type (yytype), sbit, ebit, flags);
+ if (f)
+ {
+ last_f = &e->fields;
+ while (*last_f)
+ last_f = &(*last_f)->next;
+ *last_f = f;
+ f->next = 0;
+ }
+ return f;
+}
+
+
+/*======================================================================*/
+/* Interfaces for assembler and disassembler */
+
+#ifndef STAND_ALONE
+#include "as.h"
+#include "symbols.h"
+static void append_insns_as_macros (void);
+
+/* initialize for gas */
+void
+itbl_init (void)
+{
+ struct itbl_entry *e, **es;
+ e_processor procn;
+ e_type type;
+
+ if (!itbl_have_entries)
+ return;
+
+ /* Since register names don't have a prefix, put them in the symbol table so
+ they can't be used as symbols. This simplifies argument parsing as
+ we can let gas parse registers for us. */
+ /* Use symbol_create instead of symbol_new so we don't try to
+ output registers into the object file's symbol table. */
+
+ for (type = e_regtype0; type < e_nregtypes; type++)
+ for (procn = e_p0; procn < e_nprocs; procn++)
+ {
+ es = get_entries (procn, type);
+ for (e = *es; e; e = e->next)
+ {
+ symbol_table_insert (symbol_create (e->name, reg_section,
+ e->value, &zero_address_frag));
+ }
+ }
+ append_insns_as_macros ();
+}
+
+
+/* Append insns to opcodes table and increase number of opcodes
+ * Structure of opcodes table:
+ * struct itbl_opcode
+ * {
+ * const char *name;
+ * const char *args; - string describing the arguments.
+ * unsigned long match; - opcode, or ISA level if pinfo=INSN_MACRO
+ * unsigned long mask; - opcode mask, or macro id if pinfo=INSN_MACRO
+ * unsigned long pinfo; - insn flags, or INSN_MACRO
+ * };
+ * examples:
+ * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
+ * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
+ */
+
+static char *form_args (struct itbl_entry *e);
+static void
+append_insns_as_macros (void)
+{
+ struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
+ struct itbl_entry *e, **es;
+ int n, id, size, new_size, new_num_opcodes;
+
+ if (!itbl_have_entries)
+ return;
+
+ if (!itbl_num_opcodes) /* no new instructions to add! */
+ {
+ return;
+ }
+ DBG (("previous num_opcodes=%d\n", ITBL_NUM_OPCODES));
+
+ new_num_opcodes = ITBL_NUM_OPCODES + itbl_num_opcodes;
+ ASSERT (new_num_opcodes >= itbl_num_opcodes);
+
+ size = sizeof (struct ITBL_OPCODE_STRUCT) * ITBL_NUM_OPCODES;
+ ASSERT (size >= 0);
+ DBG (("I get=%d\n", size / sizeof (ITBL_OPCODES[0])));
+
+ new_size = sizeof (struct ITBL_OPCODE_STRUCT) * new_num_opcodes;
+ ASSERT (new_size > size);
+
+ /* FIXME since ITBL_OPCODES culd be a static table,
+ we can't realloc or delete the old memory. */
+ new_opcodes = (struct ITBL_OPCODE_STRUCT *) malloc (new_size);
+ if (!new_opcodes)
+ {
+ printf (_("Unable to allocate memory for new instructions\n"));
+ return;
+ }
+ if (size) /* copy prexisting opcodes table */
+ memcpy (new_opcodes, ITBL_OPCODES, size);
+
+ /* FIXME! some NUMOPCODES are calculated expressions.
+ These need to be changed before itbls can be supported. */
+
+ id = ITBL_NUM_MACROS; /* begin the next macro id after the last */
+ o = &new_opcodes[ITBL_NUM_OPCODES]; /* append macro to opcodes list */
+ for (n = e_p0; n < e_nprocs; n++)
+ {
+ es = get_entries (n, e_insn);
+ for (e = *es; e; e = e->next)
+ {
+ /* name, args, mask, match, pinfo
+ * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
+ * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
+ * Construct args from itbl_fields.
+ */
+ o->name = e->name;
+ o->args = strdup (form_args (e));
+ o->mask = apply_range (e->value, e->range);
+ /* FIXME how to catch durring assembly? */
+ /* mask to identify this insn */
+ o->match = apply_range (e->value, e->range);
+ o->pinfo = 0;
+
+#ifdef USE_MACROS
+ o->mask = id++; /* FIXME how to catch durring assembly? */
+ o->match = 0; /* for macros, the insn_isa number */
+ o->pinfo = INSN_MACRO;
+#endif
+
+ /* Don't add instructions which caused an error */
+ if (o->args)
+ o++;
+ else
+ new_num_opcodes--;
+ }
+ }
+ ITBL_OPCODES = new_opcodes;
+ ITBL_NUM_OPCODES = new_num_opcodes;
+
+ /* FIXME
+ At this point, we can free the entries, as they should have
+ been added to the assembler's tables.
+ Don't free name though, since name is being used by the new
+ opcodes table.
+
+ Eventually, we should also free the new opcodes table itself
+ on exit.
+ */
+}
+
+static char *
+form_args (struct itbl_entry *e)
+{
+ static char s[31];
+ char c = 0, *p = s;
+ struct itbl_field *f;
+
+ ASSERT (e);
+ for (f = e->fields; f; f = f->next)
+ {
+ switch (f->type)
+ {
+ case e_dreg:
+ c = 'd';
+ break;
+ case e_creg:
+ c = 't';
+ break;
+ case e_greg:
+ c = 's';
+ break;
+ case e_immed:
+ c = 'i';
+ break;
+ case e_addr:
+ c = 'a';
+ break;
+ default:
+ c = 0; /* ignore; unknown field type */
+ }
+ if (c)
+ {
+ if (p != s)
+ *p++ = ',';
+ *p++ = c;
+ }
+ }
+ *p = 0;
+ return s;
+}
+#endif /* !STAND_ALONE */
+
+
+/* Get processor's register name from val */
+
+unsigned long
+itbl_get_reg_val (char *name)
+{
+ e_type t;
+ e_processor p;
+ int r = 0;
+ for (p = e_p0; p < e_nprocs; p++)
+ for (t = e_regtype0; t < e_nregtypes; t++)
+ {
+ if (r = itbl_get_val (p, t, name), r)
+ return r;
+ }
+ return 0;
+}
+
+char *
+itbl_get_name (e_processor processor, e_type type, unsigned long val)
+{
+ struct itbl_entry *r;
+ /* type depends on instruction passed */
+ r = find_entry_byval (processor, type, val, 0);
+ if (r)
+ return r->name;
+ else
+ return 0; /* error; invalid operand */
+}
+
+/* Get processor's register value from name */
+
+unsigned long
+itbl_get_val (e_processor processor, e_type type, char *name)
+{
+ struct itbl_entry *r;
+ /* type depends on instruction passed */
+ r = find_entry_byname (processor, type, name);
+ if (r)
+ return r->value;
+ else
+ return 0; /* error; invalid operand */
+}
+
+
+/* Assemble instruction "name" with operands "s".
+ * name - name of instruction
+ * s - operands
+ * returns - long word for assembled instruction */
+
+unsigned long
+itbl_assemble (char *name, char *s)
+{
+ unsigned long opcode;
+ struct itbl_entry *e;
+ struct itbl_field *f;
+ char *n;
+ int processor;
+
+ if (!name || !*name)
+ return 0; /* error! must have a opcode name/expr */
+
+ /* find entry in list of instructions for all processors */
+ for (processor = 0; processor < e_nprocs; processor++)
+ {
+ e = find_entry_byname (processor, e_insn, name);
+ if (e)
+ break;
+ }
+ if (!e)
+ return 0; /* opcode not in table; invalid instrustion */
+ opcode = build_opcode (e);
+
+ /* parse opcode's args (if any) */
+ for (f = e->fields; f; f = f->next) /* for each arg, ... */
+ {
+ struct itbl_entry *r;
+ unsigned long value;
+ if (!s || !*s)
+ return 0; /* error - not enough operands */
+ n = itbl_get_field (&s);
+ /* n should be in form $n or 0xhhh (are symbol names valid?? */
+ switch (f->type)
+ {
+ case e_dreg:
+ case e_creg:
+ case e_greg:
+ /* Accept either a string name
+ * or '$' followed by the register number */
+ if (*n == '$')
+ {
+ n++;
+ value = strtol (n, 0, 10);
+ /* FIXME! could have "0l"... then what?? */
+ if (value == 0 && *n != '0')
+ return 0; /* error; invalid operand */
+ }
+ else
+ {
+ r = find_entry_byname (e->processor, f->type, n);
+ if (r)
+ value = r->value;
+ else
+ return 0; /* error; invalid operand */
+ }
+ break;
+ case e_addr:
+ /* use assembler's symbol table to find symbol */
+ /* FIXME!! Do we need this?
+ if so, what about relocs??
+ my_getExpression (&imm_expr, s);
+ return 0; /-* error; invalid operand *-/
+ break;
+ */
+ /* If not a symbol, fall thru to IMMED */
+ case e_immed:
+ if (*n == '0' && *(n + 1) == 'x') /* hex begins 0x... */
+ {
+ n += 2;
+ value = strtol (n, 0, 16);
+ /* FIXME! could have "0xl"... then what?? */
+ }
+ else
+ {
+ value = strtol (n, 0, 10);
+ /* FIXME! could have "0l"... then what?? */
+ if (value == 0 && *n != '0')
+ return 0; /* error; invalid operand */
+ }
+ break;
+ default:
+ return 0; /* error; invalid field spec */
+ }
+ opcode |= apply_range (value, f->range);
+ }
+ if (s && *s)
+ return 0; /* error - too many operands */
+ return opcode; /* done! */
+}
+
+/* Disassemble instruction "insn".
+ * insn - instruction
+ * s - buffer to hold disassembled instruction
+ * returns - 1 if succeeded; 0 if failed
+ */
+
+int
+itbl_disassemble (char *s, unsigned long insn)
+{
+ e_processor processor;
+ struct itbl_entry *e;
+ struct itbl_field *f;
+
+ if (!ITBL_IS_INSN (insn))
+ return 0; /* error*/
+ processor = get_processor (ITBL_DECODE_PNUM (insn));
+
+ /* find entry in list */
+ e = find_entry_byval (processor, e_insn, insn, 0);
+ if (!e)
+ return 0; /* opcode not in table; invalid instrustion */
+ strcpy (s, e->name);
+
+ /* parse insn's args (if any) */
+ for (f = e->fields; f; f = f->next) /* for each arg, ... */
+ {
+ struct itbl_entry *r;
+ unsigned long value;
+
+ if (f == e->fields) /* first operand is preceeded by tab */
+ strcat (s, "\t");
+ else /* ','s separate following operands */
+ strcat (s, ",");
+ value = extract_range (insn, f->range);
+ /* n should be in form $n or 0xhhh (are symbol names valid?? */
+ switch (f->type)
+ {
+ case e_dreg:
+ case e_creg:
+ case e_greg:
+ /* Accept either a string name
+ * or '$' followed by the register number */
+ r = find_entry_byval (e->processor, f->type, value, &f->range);
+ if (r)
+ strcat (s, r->name);
+ else
+ sprintf (s, "%s$%d", s, value);
+ break;
+ case e_addr:
+ /* use assembler's symbol table to find symbol */
+ /* FIXME!! Do we need this?
+ * if so, what about relocs??
+ */
+ /* If not a symbol, fall thru to IMMED */
+ case e_immed:
+ sprintf (s, "%s0x%x", s, value);
+ break;
+ default:
+ return 0; /* error; invalid field spec */
+ }
+ }
+ return 1; /* done! */
+}
+
+/*======================================================================*/
+/*
+ * Local functions for manipulating private structures containing
+ * the names and format for the new instructions and registers
+ * for each processor.
+ */
+
+/* Calculate instruction's opcode and function values from entry */
+
+static unsigned long
+build_opcode (struct itbl_entry *e)
+{
+ unsigned long opcode;
+
+ opcode = apply_range (e->value, e->range);
+ opcode |= ITBL_ENCODE_PNUM (e->processor);
+ return opcode;
+}
+
+/* Calculate absolute value given the relative value and bit position range
+ * within the instruction.
+ * The range is inclusive where 0 is least significant bit.
+ * A range of { 24, 20 } will have a mask of
+ * bit 3 2 1
+ * pos: 1098 7654 3210 9876 5432 1098 7654 3210
+ * bin: 0000 0001 1111 0000 0000 0000 0000 0000
+ * hex: 0 1 f 0 0 0 0 0
+ * mask: 0x01f00000.
+ */
+
+static unsigned long
+apply_range (unsigned long rval, struct itbl_range r)
+{
+ unsigned long mask;
+ unsigned long aval;
+ int len = MAX_BITPOS - r.sbit;
+
+ ASSERT (r.sbit >= r.ebit);
+ ASSERT (MAX_BITPOS >= r.sbit);
+ ASSERT (r.ebit >= 0);
+
+ /* create mask by truncating 1s by shifting */
+ mask = 0xffffffff << len;
+ mask = mask >> len;
+ mask = mask >> r.ebit;
+ mask = mask << r.ebit;
+
+ aval = (rval << r.ebit) & mask;
+ return aval;
+}
+
+/* Calculate relative value given the absolute value and bit position range
+ * within the instruction. */
+
+static unsigned long
+extract_range (unsigned long aval, struct itbl_range r)
+{
+ unsigned long mask;
+ unsigned long rval;
+ int len = MAX_BITPOS - r.sbit;
+
+ /* create mask by truncating 1s by shifting */
+ mask = 0xffffffff << len;
+ mask = mask >> len;
+ mask = mask >> r.ebit;
+ mask = mask << r.ebit;
+
+ rval = (aval & mask) >> r.ebit;
+ return rval;
+}
+
+/* Extract processor's assembly instruction field name from s;
+ * forms are "n args" "n,args" or "n" */
+/* Return next argument from string pointer "s" and advance s.
+ * delimiters are " ,\0" */
+
+char *
+itbl_get_field (char **S)
+{
+ static char n[128];
+ char *p, *ps, *s;
+ int len;
+
+ s = *S;
+ if (!s || !*s)
+ return 0;
+ p = s + strlen (s);
+ if (ps = strchr (s, ','), ps)
+ p = ps;
+ if (ps = strchr (s, ' '), ps)
+ p = min (p, ps);
+ if (ps = strchr (s, '\0'), ps)
+ p = min (p, ps);
+ if (p == 0)
+ return 0; /* error! */
+ len = p - s;
+ ASSERT (128 > len + 1);
+ strncpy (n, s, len);
+ n[len] = 0;
+ if (s[len] == '\0')
+ s = 0; /* no more args */
+ else
+ s += len + 1; /* advance to next arg */
+
+ *S = s;
+ return n;
+}
+
+/* Search entries for a given processor and type
+ * to find one matching the name "n".
+ * Return a pointer to the entry */
+
+static struct itbl_entry *
+find_entry_byname (e_processor processor,
+ e_type type, char *n)
+{
+ struct itbl_entry *e, **es;
+
+ es = get_entries (processor, type);
+ for (e = *es; e; e = e->next) /* for each entry, ... */
+ {
+ if (!strcmp (e->name, n))
+ return e;
+ }
+ return 0;
+}
+
+/* Search entries for a given processor and type
+ * to find one matching the value "val" for the range "r".
+ * Return a pointer to the entry.
+ * This function is used for disassembling fields of an instruction.
+ */
+
+static struct itbl_entry *
+find_entry_byval (e_processor processor, e_type type,
+ unsigned long val, struct itbl_range *r)
+{
+ struct itbl_entry *e, **es;
+ unsigned long eval;
+
+ es = get_entries (processor, type);
+ for (e = *es; e; e = e->next) /* for each entry, ... */
+ {
+ if (processor != e->processor)
+ continue;
+ /* For insns, we might not know the range of the opcode,
+ * so a range of 0 will allow this routine to match against
+ * the range of the entry to be compared with.
+ * This could cause ambiguities.
+ * For operands, we get an extracted value and a range.
+ */
+ /* if range is 0, mask val against the range of the compared entry. */
+ if (r == 0) /* if no range passed, must be whole 32-bits
+ * so create 32-bit value from entry's range */
+ {
+ eval = apply_range (e->value, e->range);
+ val &= apply_range (0xffffffff, e->range);
+ }
+ else if (r->sbit == e->range.sbit && r->ebit == e->range.ebit
+ || e->range.sbit == 0 && e->range.ebit == 0)
+ {
+ eval = apply_range (e->value, *r);
+ val = apply_range (val, *r);
+ }
+ else
+ continue;
+ if (val == eval)
+ return e;
+ }
+ return 0;
+}
+
+/* Return a pointer to the list of entries for a given processor and type. */
+
+static struct itbl_entry **
+get_entries (e_processor processor, e_type type)
+{
+ return &entries[processor][type];
+}
+
+/* Return an integral value for the processor passed from yyparse. */
+
+static e_processor
+get_processor (int yyproc)
+{
+ /* translate from yacc's processor to enum */
+ if (yyproc >= e_p0 && yyproc < e_nprocs)
+ return (e_processor) yyproc;
+ return e_invproc; /* error; invalid processor */
+}
+
+/* Return an integral value for the entry type passed from yyparse. */
+
+static e_type
+get_type (int yytype)
+{
+ switch (yytype)
+ {
+ /* translate from yacc's type to enum */
+ case INSN:
+ return e_insn;
+ case DREG:
+ return e_dreg;
+ case CREG:
+ return e_creg;
+ case GREG:
+ return e_greg;
+ case ADDR:
+ return e_addr;
+ case IMMED:
+ return e_immed;
+ default:
+ return e_invtype; /* error; invalid type */
+ }
+}
+
+
+/* Allocate and initialize an entry */
+
+static struct itbl_entry *
+alloc_entry (e_processor processor, e_type type,
+ char *name, unsigned long value)
+{
+ struct itbl_entry *e, **es;
+ if (!name)
+ return 0;
+ e = (struct itbl_entry *) malloc (sizeof (struct itbl_entry));
+ if (e)
+ {
+ memset (e, 0, sizeof (struct itbl_entry));
+ e->name = (char *) malloc (sizeof (strlen (name)) + 1);
+ if (e->name)
+ strcpy (e->name, name);
+ e->processor = processor;
+ e->type = type;
+ e->value = value;
+ es = get_entries (e->processor, e->type);
+ e->next = *es;
+ *es = e;
+ }
+ return e;
+}
+
+/* Allocate and initialize an entry's field */
+
+static struct itbl_field *
+alloc_field (e_type type, int sbit, int ebit,
+ unsigned long flags)
+{
+ struct itbl_field *f;
+ f = (struct itbl_field *) malloc (sizeof (struct itbl_field));
+ if (f)
+ {
+ memset (f, 0, sizeof (struct itbl_field));
+ f->type = type;
+ f->range.sbit = sbit;
+ f->range.ebit = ebit;
+ f->flags = flags;
+ }
+ return f;
+}
diff --git a/gas/itbl-ops.h b/gas/itbl-ops.h
new file mode 100644
index 00000000000..2946eff0066
--- /dev/null
+++ b/gas/itbl-ops.h
@@ -0,0 +1,109 @@
+/* itbl-ops.h
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* External functions, constants and defines for itbl support */
+
+#include "ansidecl.h"
+
+/* Include file notes: "expr.h" needed before targ-*.h,
+ * "targ-env.h" includes the chain of target dependant headers,
+ * "targ-cpu.h" has the HAVE_ITBL_CPU define, and
+ * as.h includes them all */
+#include "as.h"
+
+#ifdef HAVE_ITBL_CPU
+#include "itbl-cpu.h"
+#endif
+
+/* Defaults for definitions required by generic code */
+#ifndef ITBL_NUMBER_OF_PROCESSORS
+#define ITBL_NUMBER_OF_PROCESSORS 1
+#endif
+
+#ifndef ITBL_MAX_BITPOS
+#define ITBL_MAX_BITPOS 31
+#endif
+
+#ifndef ITBL_TYPE
+#define ITBL_TYPE unsigned long
+#endif
+
+#ifndef ITBL_IS_INSN
+#define ITBL_IS_INSN(insn) 1
+#endif
+
+#ifndef ITBL_DECODE_PNUM
+#define ITBL_DECODE_PNUM(insn) 0
+#endif
+
+#ifndef ITBL_ENCODE_PNUM
+#define ITBL_ENCODE_PNUM(pnum) 0
+#endif
+
+typedef ITBL_TYPE t_insn;
+
+/* types of entries */
+typedef enum
+ {
+ e_insn,
+ e_dreg,
+ e_regtype0 = e_dreg,
+ e_creg,
+ e_greg,
+ e_addr,
+ e_nregtypes = e_greg + 1,
+ e_immed,
+ e_ntypes,
+ e_invtype /* invalid type */
+ } e_type;
+
+typedef enum
+ {
+ e_p0,
+ e_nprocs = NUMBER_OF_PROCESSORS,
+ e_invproc /* invalid processor */
+ } e_processor;
+
+/* 0 means an instruction table was not specified. */
+extern int itbl_have_entries;
+
+/* These routines are visible to the main part of the assembler */
+
+int itbl_parse PARAMS ((char *insntbl));
+void itbl_init PARAMS ((void));
+char *itbl_get_field PARAMS ((char **s));
+unsigned long itbl_assemble PARAMS ((char *name, char *operands));
+int itbl_disassemble PARAMS ((char *str, unsigned long insn));
+int itbl_parse PARAMS ((char *tbl)); /* parses insn tbl */
+unsigned long itbl_get_reg_val PARAMS ((char *name));
+unsigned long itbl_get_val PARAMS ((e_processor processor, e_type type,
+ char *name));
+char *itbl_get_name PARAMS ((e_processor processor, e_type type,
+ unsigned long val));
+
+/* These routines are called by the table parser used to build the
+ dynamic list of new processor instructions and registers. */
+
+struct itbl_entry *itbl_add_reg PARAMS ((int yyproc, int yytype,
+ char *regname, int regnum));
+struct itbl_entry *itbl_add_insn PARAMS ((int yyproc, char *name,
+ unsigned long value, int sbit, int ebit, unsigned long flags));
+struct itbl_field *itbl_add_operand PARAMS ((struct itbl_entry * e, int yytype,
+ int sbit, int ebit, unsigned long flags));
diff --git a/gas/itbl-parse.y b/gas/itbl-parse.y
new file mode 100644
index 00000000000..7966ee8fe1b
--- /dev/null
+++ b/gas/itbl-parse.y
@@ -0,0 +1,459 @@
+/* itbl-parse.y
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+%{
+
+/*
+
+Yacc grammar for instruction table entries.
+
+=======================================================================
+Original Instruction table specification document:
+
+ MIPS Coprocessor Table Specification
+ ====================================
+
+This document describes the format of the MIPS coprocessor table. The
+table specifies a list of valid functions, data registers and control
+registers that can be used in coprocessor instructions. This list,
+together with the coprocessor instruction classes listed below,
+specifies the complete list of coprocessor instructions that will
+be recognized and assembled by the GNU assembler. In effect,
+this makes the GNU assembler table-driven, where the table is
+specified by the programmer.
+
+The table is an ordinary text file that the GNU assembler reads when
+it starts. Using the information in the table, the assembler
+generates an internal list of valid coprocessor registers and
+functions. The assembler uses this internal list in addition to the
+standard MIPS registers and instructions which are built-in to the
+assembler during code generation.
+
+To specify the coprocessor table when invoking the GNU assembler, use
+the command line option "--itbl file", where file is the
+complete name of the table, including path and extension.
+
+Examples:
+
+ gas -t cop.tbl test.s -o test.o
+ gas -t /usr/local/lib/cop.tbl test.s -o test.o
+ gas --itbl d:\gnu\data\cop.tbl test.s -o test.o
+
+Only one table may be supplied during a single invocation of
+the assembler.
+
+
+Instruction classes
+===================
+
+Below is a list of the valid coprocessor instruction classes for
+any given coprocessor "z". These instructions are already recognized
+by the assembler, and are listed here only for reference.
+
+Class format instructions
+-------------------------------------------------
+Class1:
+ op base rt offset
+ LWCz rt,offset (base)
+ SWCz rt,offset (base)
+Class2:
+ COPz sub rt rd 0
+ MTCz rt,rd
+ MFCz rt,rd
+ CTCz rt,rd
+ CFCz rt,rd
+Class3:
+ COPz CO cofun
+ COPz cofun
+Class4:
+ COPz BC br offset
+ BCzT offset
+ BCzF offset
+Class5:
+ COPz sub rt rd 0
+ DMFCz rt,rd
+ DMTCz rt,rd
+Class6:
+ op base rt offset
+ LDCz rt,offset (base)
+ SDCz rt,offset (base)
+Class7:
+ COPz BC br offset
+ BCzTL offset
+ BCzFL offset
+
+The coprocessor table defines coprocessor-specific registers that can
+be used with all of the above classes of instructions, where
+appropriate. It also defines additional coprocessor-specific
+functions for Class3 (COPz cofun) instructions, Thus, the table allows
+the programmer to use convenient mnemonics and operands for these
+functions, instead of the COPz mmenmonic and cofun operand.
+
+The names of the MIPS general registers and their aliases are defined
+by the assembler and will be recognized as valid register names by the
+assembler when used (where allowed) in coprocessor instructions.
+However, the names and values of all coprocessor data and control
+register mnemonics must be specified in the coprocessor table.
+
+
+Table Grammar
+=============
+
+Here is the grammar for the coprocessor table:
+
+ table -> entry*
+
+ entry -> [z entrydef] [comment] '\n'
+
+ entrydef -> type name val
+ entrydef -> 'insn' name val funcdef ; type of entry (instruction)
+
+ z -> 'p'['0'..'3'] ; processor number
+ type -> ['dreg' | 'creg' | 'greg' ] ; type of entry (register)
+ ; 'dreg', 'creg' or 'greg' specifies a data, control, or general
+ ; register mnemonic, respectively
+ name -> [ltr|dec]* ; mnemonic of register/function
+ val -> [dec|hex] ; register/function number (integer constant)
+
+ funcdef -> frange flags fields
+ ; bitfield range for opcode
+ ; list of fields' formats
+ fields -> field*
+ field -> [','] ftype frange flags
+ flags -> ['*' flagexpr]
+ flagexpr -> '[' flagexpr ']'
+ flagexpr -> val '|' flagexpr
+ ftype -> [ type | 'immed' | 'addr' ]
+ ; 'immed' specifies an immediate value; see grammar for "val" above
+ ; 'addr' specifies a C identifier; name of symbol to be resolved at
+ ; link time
+ frange -> ':' val '-' val ; starting to ending bit positions, where
+ ; where 0 is least significant bit
+ frange -> (null) ; default range of 31-0 will be assumed
+
+ comment -> [';'|'#'] [char]*
+ char -> any printable character
+ ltr -> ['a'..'z'|'A'..'Z']
+ dec -> ['0'..'9']* ; value in decimal
+ hex -> '0x'['0'..'9' | 'a'..'f' | 'A'..'F']* ; value in hexidecimal
+
+
+Examples
+========
+
+Example 1:
+
+The table:
+
+ p1 dreg d1 1 ; data register "d1" for COP1 has value 1
+ p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3
+ p3 func fill 0x1f:24-20 ; function "fill" for COP3 has value 31 and
+ ; no fields
+
+will allow the assembler to accept the following coprocessor instructions:
+
+ LWC1 d1,0x100 ($2)
+ fill
+
+Here, the general purpose register "$2", and instruction "LWC1", are standard
+mnemonics built-in to the MIPS assembler.
+
+
+Example 2:
+
+The table:
+
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 func fee 0x1f:24-20 dreg:17-13 creg:12-8 immed:7-0
+ ; function "fee" for COP3 has value 31, and 3 fields
+ ; consisting of a data register, a control register,
+ ; and an immediate value.
+
+will allow the assembler to accept the following coprocessor instruction:
+
+ fee d3,c2,0x1
+
+and will emit the object code:
+
+ 31-26 25 24-20 19-18 17-13 12-8 7-0
+ COPz CO fun dreg creg immed
+ 010011 1 11111 00 00011 10110 00000001
+
+ 0x4ff07601
+
+
+Example 3:
+
+The table:
+
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 func fuu 0x01f00001 dreg:17-13 creg:12-8
+
+will allow the assembler to accept the following coprocessor
+instruction:
+
+ fuu d3,c2
+
+and will emit the object code:
+
+ 31-26 25 24-20 19-18 17-13 12-8 7-0
+ COPz CO fun dreg creg
+ 010011 1 11111 00 00011 10110 00000001
+
+ 0x4ff07601
+
+In this way, the programmer can force arbitrary bits of an instruction
+to have predefined values.
+
+=======================================================================
+Additional notes:
+
+Encoding of ranges:
+To handle more than one bit position range within an instruction,
+use 0s to mask out the ranges which don't apply.
+May decide to modify the syntax to allow commas separate multiple
+ranges within an instruction (range','range).
+
+Changes in grammar:
+ The number of parms argument to the function entry
+was deleted from the original format such that we now count the fields.
+
+----
+FIXME! should really change lexical analyzer
+to recognize 'dreg' etc. in context sensative way.
+Currently function names or mnemonics may be incorrectly parsed as keywords
+
+FIXME! hex is ambiguous with any digit
+
+*/
+
+#include <stdio.h>
+#include "itbl-ops.h"
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+#ifndef DBG_LVL
+#define DBG_LVL 1
+#endif
+#else
+#define DBG_LVL 0
+#endif
+
+#if DBG_LVL >= 1
+#define DBG(x) printf x
+#else
+#define DBG(x)
+#endif
+
+#if DBG_LVL >= 2
+#define DBGL2(x) printf x
+#else
+#define DBGL2(x)
+#endif
+
+static int sbit, ebit;
+static struct itbl_entry *insn=0;
+extern int insntbl_line;
+int yyparse PARAMS ((void));
+int yylex PARAMS ((void));
+static int yyerror PARAMS ((const char *));
+
+%}
+
+%union
+ {
+ char *str;
+ int num;
+ int processor;
+ unsigned long val;
+ }
+
+%token DREG CREG GREG IMMED ADDR INSN NUM ID NL PNUM
+%type <val> value flags flagexpr
+%type <num> number NUM ftype regtype pnum PNUM
+%type <str> ID name
+
+%start insntbl
+
+%%
+
+insntbl:
+ entrys
+ ;
+
+entrys:
+ entry entrys
+ |
+ ;
+
+entry:
+ pnum regtype name value NL
+ {
+ DBG (("line %d: entry pnum=%d type=%d name=%s value=x%x\n",
+ insntbl_line, $1, $2, $3, $4));
+ itbl_add_reg ($1, $2, $3, $4);
+ }
+ | pnum INSN name value range flags
+ {
+ DBG (("line %d: entry pnum=%d type=INSN name=%s value=x%x",
+ insntbl_line, $1, $3, $4));
+ DBG ((" sbit=%d ebit=%d flags=0x%x\n", sbit, ebit, $6));
+ insn=itbl_add_insn ($1, $3, $4, sbit, ebit, $6);
+ }
+ fieldspecs NL
+ | NL
+ | error NL
+ ;
+
+fieldspecs:
+ ',' fieldspec fieldspecs
+ | fieldspec fieldspecs
+ |
+ ;
+
+ftype:
+ regtype
+ {
+ DBGL2 (("ftype\n"));
+ $$ = $1;
+ }
+ | ADDR
+ {
+ DBGL2 (("addr\n"));
+ $$ = ADDR;
+ }
+ | IMMED
+ {
+ DBGL2 (("immed\n"));
+ $$ = IMMED;
+ }
+ ;
+
+fieldspec:
+ ftype range flags
+ {
+ DBG (("line %d: field type=%d sbit=%d ebit=%d, flags=0x%x\n",
+ insntbl_line, $1, sbit, ebit, $3));
+ itbl_add_operand (insn, $1, sbit, ebit, $3);
+ }
+ ;
+
+flagexpr:
+ NUM '|' flagexpr
+ {
+ $$ = $1 | $3;
+ }
+ | '[' flagexpr ']'
+ {
+ $$ = $2;
+ }
+ | NUM
+ {
+ $$ = $1;
+ }
+ ;
+
+flags:
+ '*' flagexpr
+ {
+ DBGL2 (("flags=%d\n", $2));
+ $$ = $2;
+ }
+ |
+ {
+ $$ = 0;
+ }
+ ;
+
+range:
+ ':' NUM '-' NUM
+ {
+ DBGL2 (("range %d %d\n", $2, $4));
+ sbit = $2;
+ ebit = $4;
+ }
+ |
+ {
+ sbit = 31;
+ ebit = 0;
+ }
+ ;
+
+pnum:
+ PNUM
+ {
+ DBGL2 (("pnum=%d\n",$1));
+ $$ = $1;
+ }
+ ;
+
+regtype:
+ DREG
+ {
+ DBGL2 (("dreg\n"));
+ $$ = DREG;
+ }
+ | CREG
+ {
+ DBGL2 (("creg\n"));
+ $$ = CREG;
+ }
+ | GREG
+ {
+ DBGL2 (("greg\n"));
+ $$ = GREG;
+ }
+ ;
+
+name:
+ ID
+ {
+ DBGL2 (("name=%s\n",$1));
+ $$ = $1;
+ }
+ ;
+
+number:
+ NUM
+ {
+ DBGL2 (("num=%d\n",$1));
+ $$ = $1;
+ }
+ ;
+
+value:
+ NUM
+ {
+ DBGL2 (("val=x%x\n",$1));
+ $$ = $1;
+ }
+ ;
+%%
+
+static int
+yyerror (msg)
+ const char *msg;
+{
+ printf ("line %d: %s\n", insntbl_line, msg);
+ return 0;
+}
diff --git a/gas/link.cmd b/gas/link.cmd
new file mode 100644
index 00000000000..a035ca87daa
--- /dev/null
+++ b/gas/link.cmd
@@ -0,0 +1,10 @@
+ALIGN=1024
+RESNUM 0x0000, 0x8000
+; Putting in .lit1 gives errors.
+ORDER .data=0x80002000, .data1, .lit, .bss
+; Let's put this on the command line so it goes first, which is what
+; GDB expects.
+; LOAD /s2/amd/29k/lib/crt0.o
+LOAD /s2/amd/29k/lib/libqcb0h.lib
+LOAD /s2/amd/29k/lib/libscb0h.lib
+LOAD /s2/amd/29k/lib/libacb0h.lib
diff --git a/gas/listing.c b/gas/listing.c
new file mode 100644
index 00000000000..e2b173be7d6
--- /dev/null
+++ b/gas/listing.c
@@ -0,0 +1,1420 @@
+/* listing.c - mainting assembly listings
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/*
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+
+
+ A listing page looks like:
+
+ LISTING_HEADER sourcefilename pagenumber
+ TITLE LINE
+ SUBTITLE LINE
+ linenumber address data source
+ linenumber address data source
+ linenumber address data source
+ linenumber address data source
+
+ If not overridden, the listing commands are:
+
+ .title "stuff"
+ Put "stuff" onto the title line
+ .sbttl "stuff"
+ Put stuff onto the subtitle line
+
+ If these commands come within 10 lines of the top of the page, they
+ will affect the page they are on, as well as any subsequent page
+
+ .eject
+ Thow a page
+ .list
+ Increment the enable listing counter
+ .nolist
+ Decrement the enable listing counter
+
+ .psize Y[,X]
+ Set the paper size to X wide and Y high. Setting a psize Y of
+ zero will suppress form feeds except where demanded by .eject
+
+ If the counter goes below zero, listing is suppressed.
+
+
+ Listings are a maintained by read calling various listing_<foo>
+ functions. What happens most is that the macro NO_LISTING is not
+ defined (from the Makefile), then the macro LISTING_NEWLINE expands
+ into a call to listing_newline. The call is done from read.c, every
+ time it sees a newline, and -l is on the command line.
+
+ The function listing_newline remembers the frag associated with the
+ newline, and creates a new frag - note that this is wasteful, but not
+ a big deal, since listing slows things down a lot anyway. The
+ function also rememebers when the filename changes.
+
+ When all the input has finished, and gas has had a chance to settle
+ down, the listing is output. This is done by running down the list of
+ frag/source file records, and opening the files as needed and printing
+ out the bytes and chars associated with them.
+
+ The only things which the architecture can change about the listing
+ are defined in these macros:
+
+ LISTING_HEADER The name of the architecture
+ LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
+ the clumping of the output data. eg a value of
+ 2 makes words look like 1234 5678, whilst 1
+ would make the same value look like 12 34 56
+ 78
+ LISTING_LHS_WIDTH Number of words of above size for the lhs
+
+ LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
+ for the second line
+
+ LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation
+ LISTING_RHS_WIDTH Number of chars from the input file to print
+ on a line
+*/
+
+#include <ctype.h>
+
+#include "as.h"
+#include <obstack.h>
+#include "input-file.h"
+#include "subsegs.h"
+
+#ifndef NO_LISTING
+
+#ifndef LISTING_HEADER
+#define LISTING_HEADER "GAS LISTING"
+#endif
+#ifndef LISTING_WORD_SIZE
+#define LISTING_WORD_SIZE 4
+#endif
+#ifndef LISTING_LHS_WIDTH
+#define LISTING_LHS_WIDTH 1
+#endif
+#ifndef LISTING_LHS_WIDTH_SECOND
+#define LISTING_LHS_WIDTH_SECOND 1
+#endif
+#ifndef LISTING_RHS_WIDTH
+#define LISTING_RHS_WIDTH 100
+#endif
+#ifndef LISTING_LHS_CONT_LINES
+#define LISTING_LHS_CONT_LINES 4
+#endif
+
+/* This structure remembers which .s were used */
+typedef struct file_info_struct
+{
+ struct file_info_struct * next;
+ char * filename;
+ long pos;
+ unsigned int linenum;
+ int at_end;
+}
+file_info_type;
+
+/* This structure rememebrs which line from which file goes into which
+ frag */
+struct list_info_struct
+{
+ /* Frag which this line of source is nearest to */
+ fragS * frag;
+
+ /* The actual line in the source file */
+ unsigned int line;
+ /* Pointer to the file info struct for the file which this line
+ belongs to */
+ file_info_type * file;
+
+ /* The expanded text of any macro that may have been executing. */
+ char * line_contents;
+
+ /* Next in list */
+ struct list_info_struct * next;
+
+ /* Pointer to the file info struct for the high level language
+ source line that belongs here */
+ file_info_type * hll_file;
+ /* High level language source line */
+ unsigned int hll_line;
+
+ /* Pointer to any error message associated with this line */
+ char * message;
+
+ enum
+ {
+ EDICT_NONE,
+ EDICT_SBTTL,
+ EDICT_TITLE,
+ EDICT_NOLIST,
+ EDICT_LIST,
+ EDICT_NOLIST_NEXT,
+ EDICT_EJECT
+ } edict;
+ char * edict_arg;
+
+ /* Nonzero if this line is to be omitted because it contains
+ debugging information. This can become a flags field if we come
+ up with more information to store here. */
+ int debugging;
+};
+
+typedef struct list_info_struct list_info_type;
+
+
+int listing_lhs_width = LISTING_LHS_WIDTH;
+int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
+int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
+int listing_rhs_width = LISTING_RHS_WIDTH;
+
+struct list_info_struct * listing_tail;
+
+static file_info_type * file_info_head;
+static file_info_type * last_open_file_info;
+static FILE * last_open_file;
+static struct list_info_struct * head;
+static int paper_width = 200;
+static int paper_height = 60;
+
+extern int listing;
+
+/* File to output listings to. */
+static FILE * list_file;
+
+/* This static array is used to keep the text of data to be printed
+ before the start of the line. */
+
+#define MAX_BYTES \
+ (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \
+ + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \
+ * listing_lhs_cont_lines) \
+ + 20)
+
+static char * data_buffer;
+
+/* Prototypes. */
+static void listing_message PARAMS ((const char *name, const char *message));
+static file_info_type * file_info PARAMS ((const char *file_name));
+static void new_frag PARAMS ((void));
+static char * buffer_line PARAMS ((file_info_type *file,
+ char *line, unsigned int size));
+static void listing_page PARAMS ((list_info_type *list));
+static unsigned int calc_hex PARAMS ((list_info_type *list));
+static void print_lines PARAMS ((list_info_type *, unsigned int,
+ char *, unsigned int));
+static void list_symbol_table PARAMS ((void));
+static void print_source PARAMS ((file_info_type *current_file,
+ list_info_type *list,
+ char *buffer,
+ unsigned int width));
+static int debugging_pseudo PARAMS ((list_info_type *, const char *));
+static void listing_listing PARAMS ((char *name));
+
+
+static void
+listing_message (name, message)
+ const char *name;
+ const char *message;
+{
+ unsigned int l = strlen (name) + strlen (message) + 1;
+ char *n = (char *) xmalloc (l);
+ strcpy (n, name);
+ strcat (n, message);
+ if (listing_tail != (list_info_type *) NULL)
+ {
+ listing_tail->message = n;
+ }
+}
+
+void
+listing_warning (message)
+ const char *message;
+{
+ listing_message (_("Warning:"), message);
+}
+
+void
+listing_error (message)
+ const char *message;
+{
+ listing_message (_("Error:"), message);
+}
+
+static file_info_type *
+file_info (file_name)
+ const char *file_name;
+{
+ /* Find an entry with this file name */
+ file_info_type *p = file_info_head;
+
+ while (p != (file_info_type *) NULL)
+ {
+ if (strcmp (p->filename, file_name) == 0)
+ return p;
+ p = p->next;
+ }
+
+ /* Make new entry */
+
+ p = (file_info_type *) xmalloc (sizeof (file_info_type));
+ p->next = file_info_head;
+ file_info_head = p;
+ p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
+ strcpy (p->filename, file_name);
+ p->pos = 0;
+ p->linenum = 0;
+ p->at_end = 0;
+
+ return p;
+}
+
+
+static void
+new_frag ()
+{
+
+ frag_wane (frag_now);
+ frag_new (0);
+
+}
+
+void
+listing_newline (ps)
+ char *ps;
+{
+ char *file;
+ unsigned int line;
+ static unsigned int last_line = 0xffff;
+ static char *last_file = NULL;
+ list_info_type *new = NULL;
+
+ if (listing == 0)
+ return;
+
+ if (now_seg == absolute_section)
+ return;
+
+#ifdef OBJ_ELF
+ /* In ELF, anything in a section beginning with .debug or .line is
+ considered to be debugging information. This includes the
+ statement which switches us into the debugging section, which we
+ can only set after we are already in the debugging section. */
+ if ((listing & LISTING_NODEBUG) != 0
+ && listing_tail != NULL
+ && ! listing_tail->debugging)
+ {
+ const char *segname;
+
+ segname = segment_name (now_seg);
+ if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
+ || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
+ listing_tail->debugging = 1;
+ }
+#endif
+
+ as_where (&file, &line);
+ if (ps == NULL)
+ {
+ if (line == last_line && !(last_file && file && strcmp (file, last_file)))
+ return;
+
+ new = (list_info_type *) xmalloc (sizeof (list_info_type));
+
+ /* Detect if we are reading from stdin by examining the file
+ name returned by as_where().
+
+ [FIXME: We rely upon the name in the strcmp below being the
+ same as the one used by input_scrub_new_file(), if that is
+ not true, then this code will fail].
+
+ If we are reading from stdin, then we need to save each input line
+ here (assuming of course that we actually have a line of input to read),
+ so that it can be displayed in the listing that is produced at the end
+ of the assembly. */
+ if (strcmp (file, _("{standard input}")) == 0
+ && input_line_pointer != NULL)
+ {
+ char * copy;
+ int len;
+ int seen_quote = 0;
+
+ for (copy = input_line_pointer - 1;
+ * copy && (seen_quote
+ || (! is_end_of_line [(unsigned char) * copy]));
+ copy ++)
+ if (* copy == '"' && copy[-1] != '\\')
+ seen_quote = ! seen_quote;
+
+ len = (copy - input_line_pointer) + 2;
+
+ copy = xmalloc (len);
+
+ if (copy != NULL)
+ {
+ char * src = input_line_pointer - 1;
+ char * dest = copy;
+
+ while (--len)
+ {
+ char c = * src ++;
+
+ /* Omit control characters in the listing. */
+ if (isascii (c) && ! iscntrl (c))
+ * dest ++ = c;
+ }
+
+ *dest = 0;
+ }
+
+ new->line_contents = copy;
+ }
+ else
+ new->line_contents = NULL;
+ }
+ else
+ {
+ new = (list_info_type *) xmalloc (sizeof (list_info_type));
+ new->line_contents = ps;
+ }
+
+ last_line = line;
+ last_file = file;
+
+ new_frag ();
+
+ if (listing_tail)
+ listing_tail->next = new;
+ else
+ head = new;
+
+ listing_tail = new;
+
+ new->frag = frag_now;
+ new->line = line;
+ new->file = file_info (file);
+ new->next = (list_info_type *) NULL;
+ new->message = (char *) NULL;
+ new->edict = EDICT_NONE;
+ new->hll_file = (file_info_type *) NULL;
+ new->hll_line = 0;
+ new->debugging = 0;
+
+ new_frag ();
+
+#ifdef OBJ_ELF
+ /* In ELF, anything in a section beginning with .debug or .line is
+ considered to be debugging information. */
+ if ((listing & LISTING_NODEBUG) != 0)
+ {
+ const char *segname;
+
+ segname = segment_name (now_seg);
+ if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
+ || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
+ new->debugging = 1;
+ }
+#endif
+}
+
+/* Attach all current frags to the previous line instead of the
+ current line. This is called by the MIPS backend when it discovers
+ that it needs to add some NOP instructions; the added NOP
+ instructions should go with the instruction that has the delay, not
+ with the new instruction. */
+
+void
+listing_prev_line ()
+{
+ list_info_type *l;
+ fragS *f;
+
+ if (head == (list_info_type *) NULL
+ || head == listing_tail)
+ return;
+
+ new_frag ();
+
+ for (l = head; l->next != listing_tail; l = l->next)
+ ;
+
+ for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
+ if (f->line == listing_tail)
+ f->line = l;
+
+ listing_tail->frag = frag_now;
+ new_frag ();
+}
+
+/*
+ This function returns the next source line from the file supplied,
+ truncated to size. It appends a fake line to the end of each input
+ file to make
+*/
+
+static char *
+buffer_line (file, line, size)
+ file_info_type * file;
+ char *line;
+ unsigned int size;
+{
+ unsigned int count = 0;
+ int c;
+
+ char *p = line;
+
+ /* If we couldn't open the file, return an empty line */
+ if (file->at_end)
+ return "";
+
+ /* Check the cache and see if we last used this file. */
+ if (!last_open_file_info || file != last_open_file_info)
+ {
+ if (last_open_file)
+ {
+ last_open_file_info->pos = ftell (last_open_file);
+ fclose (last_open_file);
+ }
+
+ last_open_file_info = file;
+ last_open_file = fopen (file->filename, "r");
+ if (last_open_file == NULL)
+ {
+ file->at_end = 1;
+ return "";
+ }
+
+ /* Seek to where we were last time this file was open. */
+ if (file->pos)
+ fseek(last_open_file, file->pos, SEEK_SET);
+ }
+
+ c = fgetc (last_open_file);
+
+ size -= 1; /* leave room for null */
+
+ while (c != EOF && c != '\n')
+ {
+ if (count < size)
+ *p++ = c;
+ count++;
+
+ c = fgetc (last_open_file);
+
+ }
+ if (c == EOF)
+ {
+ file->at_end = 1;
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '.';
+ }
+ file->linenum++;
+ *p++ = 0;
+ return line;
+}
+
+
+static const char *fn;
+
+static unsigned int eject; /* Eject pending */
+static unsigned int page; /* Current page number */
+static char *title; /* current title */
+static char *subtitle; /* current subtitle */
+static unsigned int on_page; /* number of lines printed on current page */
+
+
+static void
+listing_page (list)
+ list_info_type *list;
+{
+ /* Grope around, see if we can see a title or subtitle edict coming up
+ soon (we look down 10 lines of the page and see if it's there)*/
+ if ((eject || (on_page >= (unsigned int) paper_height)) && paper_height != 0)
+ {
+ unsigned int c = 10;
+ int had_title = 0;
+ int had_subtitle = 0;
+
+ page++;
+
+ while (c != 0 && list)
+ {
+ if (list->edict == EDICT_SBTTL && !had_subtitle)
+ {
+ had_subtitle = 1;
+ subtitle = list->edict_arg;
+ }
+ if (list->edict == EDICT_TITLE && !had_title)
+ {
+ had_title = 1;
+ title = list->edict_arg;
+ }
+ list = list->next;
+ c--;
+ }
+
+
+ if (page > 1)
+ {
+ fprintf (list_file, "\f");
+ }
+
+ fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
+ fprintf (list_file, "%s\n", title);
+ fprintf (list_file, "%s\n", subtitle);
+ on_page = 3;
+ eject = 0;
+ }
+}
+
+
+static unsigned int
+calc_hex (list)
+ list_info_type * list;
+{
+ int data_buffer_size;
+ list_info_type *first = list;
+ unsigned int address = ~ (unsigned int) 0;
+ fragS *frag;
+ fragS *frag_ptr;
+ unsigned int byte_in_frag;
+
+ /* Find first frag which says it belongs to this line */
+ frag = list->frag;
+ while (frag && frag->line != list)
+ frag = frag->fr_next;
+
+ frag_ptr = frag;
+
+ data_buffer_size = 0;
+
+ /* Dump all the frags which belong to this line */
+ while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
+ {
+ /* Print as many bytes from the fixed part as is sensible */
+ byte_in_frag = 0;
+ while ((offsetT) byte_in_frag < frag_ptr->fr_fix
+ && data_buffer_size < MAX_BYTES - 3)
+ {
+ if (address == ~ (unsigned int) 0)
+ {
+ address = frag_ptr->fr_address;
+ }
+
+ sprintf (data_buffer + data_buffer_size,
+ "%02X",
+ (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
+ data_buffer_size += 2;
+ byte_in_frag++;
+ }
+ {
+ unsigned int var_rep_max = byte_in_frag;
+ unsigned int var_rep_idx = byte_in_frag;
+
+ /* Print as many bytes from the variable part as is sensible */
+ while (((offsetT) byte_in_frag
+ < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
+ && data_buffer_size < MAX_BYTES - 3)
+ {
+ if (address == ~ (unsigned int) 0)
+ {
+ address = frag_ptr->fr_address;
+ }
+ sprintf (data_buffer + data_buffer_size,
+ "%02X",
+ (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
+#if 0
+ data_buffer[data_buffer_size++] = '*';
+ data_buffer[data_buffer_size++] = '*';
+#endif
+ data_buffer_size += 2;
+
+ var_rep_idx++;
+ byte_in_frag++;
+
+ if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
+ var_rep_idx = var_rep_max;
+ }
+ }
+
+ frag_ptr = frag_ptr->fr_next;
+ }
+ data_buffer[data_buffer_size] = '\0';
+ return address;
+}
+
+
+
+
+
+
+static void
+print_lines (list, lineno, string, address)
+ list_info_type *list;
+ unsigned int lineno;
+ char *string;
+ unsigned int address;
+{
+ unsigned int idx;
+ unsigned int nchars;
+ unsigned int lines;
+ unsigned int byte_in_word = 0;
+ char *src = data_buffer;
+
+ /* Print the stuff on the first line */
+ listing_page (list);
+ nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
+
+ /* Print the hex for the first line */
+ if (address == ~ (unsigned int) 0)
+ {
+ fprintf (list_file, "% 4d ", lineno);
+ for (idx = 0; idx < nchars; idx++)
+ fprintf (list_file, " ");
+
+ fprintf (list_file, "\t%s\n", string ? string : "");
+
+ on_page ++;
+
+ listing_page (0);
+
+ return;
+ }
+
+ if (had_errors ())
+ fprintf (list_file, "% 4d ???? ", lineno);
+ else
+ fprintf (list_file, "% 4d %04x ", lineno, address);
+
+ /* And the data to go along with it */
+ idx = 0;
+
+ while (*src && idx < nchars)
+ {
+ fprintf (list_file, "%c%c", src[0], src[1]);
+ src += 2;
+ byte_in_word++;
+
+ if (byte_in_word == LISTING_WORD_SIZE)
+ {
+ fprintf (list_file, " ");
+ idx++;
+ byte_in_word = 0;
+ }
+
+ idx += 2;
+ }
+
+ for (; idx < nchars; idx++)
+ fprintf (list_file, " ");
+
+ fprintf (list_file, "\t%s\n", string ? string : "");
+ on_page++;
+ listing_page (list);
+
+ if (list->message)
+ {
+ fprintf (list_file, "**** %s\n", list->message);
+ listing_page (list);
+ on_page++;
+ }
+
+ for (lines = 0;
+ lines < (unsigned int) listing_lhs_cont_lines
+ && *src;
+ lines ++)
+ {
+ nchars = ((LISTING_WORD_SIZE * 2) + 1)
+ * listing_lhs_width_second - 1;
+ idx = 0;
+
+ /* Print any more lines of data, but more compactly */
+ fprintf (list_file, "% 4d ", lineno);
+
+ while (*src && idx < nchars)
+ {
+ fprintf (list_file, "%c%c", src[0], src[1]);
+ src += 2;
+ idx += 2;
+ byte_in_word++;
+
+ if (byte_in_word == LISTING_WORD_SIZE)
+ {
+ fprintf (list_file, " ");
+ idx++;
+ byte_in_word = 0;
+ }
+ }
+
+ fprintf (list_file, "\n");
+ on_page ++;
+ listing_page (list);
+ }
+}
+
+
+static void
+list_symbol_table ()
+{
+ extern symbolS *symbol_rootP;
+ int got_some = 0;
+
+ symbolS *ptr;
+ eject = 1;
+ listing_page (0);
+
+ for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
+ {
+ if (SEG_NORMAL (S_GET_SEGMENT (ptr))
+ || S_GET_SEGMENT (ptr) == absolute_section)
+ {
+#ifdef BFD_ASSEMBLER
+ /* Don't report section symbols. They are not interesting. */
+ if (ptr->bsym->flags & BSF_SECTION_SYM)
+ continue;
+#endif
+ if (S_GET_NAME (ptr))
+ {
+ char buf[30], fmt[8];
+ valueT val = S_GET_VALUE (ptr);
+
+ /* @@ Note that this is dependent on the compilation options,
+ not solely on the target characteristics. */
+ if (sizeof (val) == 4 && sizeof (int) == 4)
+ sprintf (buf, "%08lx", (unsigned long) val);
+ else if (sizeof (val) <= sizeof (unsigned long))
+ {
+ sprintf (fmt, "%%0%lulx",
+ (unsigned long) (sizeof (val) * 2));
+ sprintf (buf, fmt, (unsigned long) val);
+ }
+#if defined (BFD64)
+ else if (sizeof (val) > 4)
+ sprintf_vma (buf, val);
+#endif
+ else
+ abort ();
+
+ if (!got_some)
+ {
+ fprintf (list_file, "DEFINED SYMBOLS\n");
+ on_page++;
+ got_some = 1;
+ }
+
+ if (ptr->sy_frag && ptr->sy_frag->line)
+ {
+ fprintf (list_file, "%20s:%-5d %s:%s %s\n",
+ ptr->sy_frag->line->file->filename,
+ ptr->sy_frag->line->line,
+ segment_name (S_GET_SEGMENT (ptr)),
+ buf, S_GET_NAME (ptr));
+ }
+ else
+ {
+ fprintf (list_file, "%33s:%s %s\n",
+ segment_name (S_GET_SEGMENT (ptr)),
+ buf, S_GET_NAME (ptr));
+ }
+
+ on_page ++;
+ listing_page (0);
+ }
+ }
+
+ }
+ if (!got_some)
+ {
+ fprintf (list_file, "NO DEFINED SYMBOLS\n");
+ on_page++;
+ }
+ fprintf (list_file, "\n");
+ on_page++;
+ listing_page (0);
+
+ got_some = 0;
+
+ for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
+ {
+ if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
+ {
+ if (S_GET_SEGMENT (ptr) == undefined_section)
+ {
+ if (!got_some)
+ {
+ got_some = 1;
+ fprintf (list_file, "UNDEFINED SYMBOLS\n");
+ on_page++;
+ listing_page (0);
+ }
+ fprintf (list_file, "%s\n", S_GET_NAME (ptr));
+ on_page++;
+ listing_page (0);
+ }
+ }
+ }
+ if (!got_some)
+ {
+ fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
+ on_page++;
+ listing_page (0);
+ }
+}
+
+static void
+print_source (current_file, list, buffer, width)
+ file_info_type *current_file;
+ list_info_type *list;
+ char *buffer;
+ unsigned int width;
+{
+ if (!current_file->at_end)
+ {
+ while (current_file->linenum < list->hll_line
+ && !current_file->at_end)
+ {
+ char *p = buffer_line (current_file, buffer, width);
+ fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
+ current_file->filename, p);
+ on_page++;
+ listing_page (list);
+ }
+ }
+}
+
+/* Sometimes the user doesn't want to be bothered by the debugging
+ records inserted by the compiler, see if the line is suspicious. */
+
+static int
+debugging_pseudo (list, line)
+ list_info_type *list;
+ const char *line;
+{
+ static int in_debug;
+ int was_debug;
+
+ if (list->debugging)
+ {
+ in_debug = 1;
+ return 1;
+ }
+
+ was_debug = in_debug;
+ in_debug = 0;
+
+ while (isspace ((unsigned char) *line))
+ line++;
+
+ if (*line != '.')
+ {
+#ifdef OBJ_ELF
+ /* The ELF compiler sometimes emits blank lines after switching
+ out of a debugging section. If the next line drops us back
+ into debugging information, then don't print the blank line.
+ This is a hack for a particular compiler behaviour, not a
+ general case. */
+ if (was_debug
+ && *line == '\0'
+ && list->next != NULL
+ && list->next->debugging)
+ {
+ in_debug = 1;
+ return 1;
+ }
+#endif
+
+ return 0;
+ }
+
+ line++;
+
+ if (strncmp (line, "def", 3) == 0)
+ return 1;
+ if (strncmp (line, "val", 3) == 0)
+ return 1;
+ if (strncmp (line, "scl", 3) == 0)
+ return 1;
+ if (strncmp (line, "line", 4) == 0)
+ return 1;
+ if (strncmp (line, "endef", 5) == 0)
+ return 1;
+ if (strncmp (line, "ln", 2) == 0)
+ return 1;
+ if (strncmp (line, "type", 4) == 0)
+ return 1;
+ if (strncmp (line, "size", 4) == 0)
+ return 1;
+ if (strncmp (line, "dim", 3) == 0)
+ return 1;
+ if (strncmp (line, "tag", 3) == 0)
+ return 1;
+
+ if (strncmp (line, "stabs", 5) == 0)
+ return 1;
+ if (strncmp (line, "stabn", 5) == 0)
+ return 1;
+
+ return 0;
+}
+
+static void
+listing_listing (name)
+ char *name;
+{
+ list_info_type *list = head;
+ file_info_type *current_hll_file = (file_info_type *) NULL;
+ char *message;
+ char *buffer;
+ char *p;
+ int show_listing = 1;
+ unsigned int width;
+
+ buffer = xmalloc (listing_rhs_width);
+ data_buffer = xmalloc (MAX_BYTES);
+ eject = 1;
+ list = head;
+
+ while (list != (list_info_type *) NULL && 0)
+ {
+ if (list->next)
+ list->frag = list->next->frag;
+ list = list->next;
+
+ }
+
+ list = head->next;
+
+
+ while (list)
+ {
+ int list_line;
+
+ width = listing_rhs_width > paper_width ? paper_width :
+ listing_rhs_width;
+
+ list_line = list->line;
+ switch (list->edict)
+ {
+ case EDICT_LIST:
+ /* Skip all lines up to the current. */
+ list_line--;
+ break;
+ case EDICT_NOLIST:
+ show_listing--;
+ break;
+ case EDICT_NOLIST_NEXT:
+ break;
+ case EDICT_EJECT:
+ break;
+ case EDICT_NONE:
+ break;
+ case EDICT_TITLE:
+ title = list->edict_arg;
+ break;
+ case EDICT_SBTTL:
+ subtitle = list->edict_arg;
+ break;
+ default:
+ abort ();
+ }
+
+ if (show_listing <= 0)
+ {
+ while (list->file->linenum < list_line
+ && !list->file->at_end)
+ p = buffer_line (list->file, buffer, width);
+ }
+
+ if (list->edict == EDICT_LIST)
+ {
+ /* Enable listing for the single line that caused the enable. */
+ list_line++;
+ show_listing++;
+ }
+
+ if (show_listing > 0)
+ {
+ /* Scan down the list and print all the stuff which can be done
+ with this line (or lines). */
+ message = 0;
+
+ if (list->hll_file)
+ {
+ current_hll_file = list->hll_file;
+ }
+
+ if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
+ {
+ print_source (current_hll_file, list, buffer, width);
+ }
+
+ if (list->line_contents)
+ {
+ if (!((listing & LISTING_NODEBUG)
+ && debugging_pseudo (list, list->line_contents)))
+ {
+ print_lines (list,
+ list->file->linenum == 0 ? list->line : list->file->linenum,
+ list->line_contents, calc_hex (list));
+ }
+ free (list->line_contents);
+ list->line_contents = NULL;
+ }
+ else
+ {
+ while (list->file->linenum < list_line
+ && !list->file->at_end)
+ {
+ unsigned int address;
+
+ p = buffer_line (list->file, buffer, width);
+
+ if (list->file->linenum < list_line)
+ address = ~ (unsigned int) 0;
+ else
+ address = calc_hex (list);
+
+ if (!((listing & LISTING_NODEBUG)
+ && debugging_pseudo (list, p)))
+ print_lines (list, list->file->linenum, p, address);
+ }
+ }
+
+ if (list->edict == EDICT_EJECT)
+ {
+ eject = 1;
+ }
+ }
+
+ if (list->edict == EDICT_NOLIST_NEXT)
+ --show_listing;
+
+ list = list->next;
+ }
+
+ free (buffer);
+ free (data_buffer);
+ data_buffer = NULL;
+}
+
+void
+listing_print (name)
+ char *name;
+{
+ int using_stdout;
+
+ title = "";
+ subtitle = "";
+
+ if (name == NULL)
+ {
+ list_file = stdout;
+ using_stdout = 1;
+ }
+ else
+ {
+ list_file = fopen (name, "w");
+ if (list_file != NULL)
+ using_stdout = 0;
+ else
+ {
+ as_perror (_("can't open list file: %s"), name);
+ list_file = stdout;
+ using_stdout = 1;
+ }
+ }
+
+ if (listing & LISTING_NOFORM)
+ {
+ paper_height = 0;
+ }
+
+ if (listing & LISTING_LISTING)
+ {
+ listing_listing (name);
+ }
+
+ if (listing & LISTING_SYMBOLS)
+ {
+ list_symbol_table ();
+ }
+
+ if (! using_stdout)
+ {
+ if (fclose (list_file) == EOF)
+ as_perror (_("error closing list file: %s"), name);
+ }
+
+ if (last_open_file)
+ {
+ fclose (last_open_file);
+ }
+}
+
+
+void
+listing_file (name)
+ const char *name;
+{
+ fn = name;
+}
+
+void
+listing_eject (ignore)
+ int ignore;
+{
+ if (listing)
+ listing_tail->edict = EDICT_EJECT;
+}
+
+void
+listing_flags (ignore)
+ int ignore;
+{
+ while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
+ input_line_pointer++;
+
+}
+
+/* Turn listing on or off. An argument of 0 means to turn off
+ listing. An argument of 1 means to turn on listing. An argument
+ of 2 means to turn off listing, but as of the next line; that is,
+ the current line should be listed, but the next line should not. */
+
+void
+listing_list (on)
+ int on;
+{
+ if (listing)
+ {
+ switch (on)
+ {
+ case 0:
+ if (listing_tail->edict == EDICT_LIST)
+ listing_tail->edict = EDICT_NONE;
+ else
+ listing_tail->edict = EDICT_NOLIST;
+ break;
+ case 1:
+ if (listing_tail->edict == EDICT_NOLIST
+ || listing_tail->edict == EDICT_NOLIST_NEXT)
+ listing_tail->edict = EDICT_NONE;
+ else
+ listing_tail->edict = EDICT_LIST;
+ break;
+ case 2:
+ listing_tail->edict = EDICT_NOLIST_NEXT;
+ break;
+ default:
+ abort ();
+ }
+ }
+}
+
+
+void
+listing_psize (width_only)
+ int width_only;
+{
+ if (! width_only)
+ {
+ paper_height = get_absolute_expression ();
+
+ if (paper_height < 0 || paper_height > 1000)
+ {
+ paper_height = 0;
+ as_warn (_("strange paper height, set to no form"));
+ }
+
+ if (*input_line_pointer != ',')
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ ++input_line_pointer;
+ }
+
+ paper_width = get_absolute_expression ();
+
+ demand_empty_rest_of_line ();
+}
+
+void
+listing_nopage (ignore)
+ int ignore;
+{
+ paper_height = 0;
+}
+
+void
+listing_title (depth)
+ int depth;
+{
+ int quoted;
+ char *start;
+ char *ttl;
+ unsigned int length;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '\"')
+ quoted = 0;
+ else
+ {
+ quoted = 1;
+ ++input_line_pointer;
+ }
+
+ start = input_line_pointer;
+
+ while (*input_line_pointer)
+ {
+ if (quoted
+ ? *input_line_pointer == '\"'
+ : is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (listing)
+ {
+ length = input_line_pointer - start;
+ ttl = xmalloc (length + 1);
+ memcpy (ttl, start, length);
+ ttl[length] = 0;
+ listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
+ listing_tail->edict_arg = ttl;
+ }
+ if (quoted)
+ input_line_pointer++;
+ demand_empty_rest_of_line ();
+ return;
+ }
+ else if (*input_line_pointer == '\n')
+ {
+ as_bad (_("New line in title"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+ else
+ {
+ input_line_pointer++;
+ }
+ }
+}
+
+
+
+void
+listing_source_line (line)
+ unsigned int line;
+{
+ if (listing)
+ {
+ new_frag ();
+ listing_tail->hll_line = line;
+ new_frag ();
+ }
+}
+
+void
+listing_source_file (file)
+ const char *file;
+{
+ if (listing)
+ listing_tail->hll_file = file_info (file);
+}
+
+
+
+#else
+
+
+/* Dummy functions for when compiled without listing enabled */
+
+void
+listing_flags (ignore)
+ int ignore;
+{
+ s_ignore (0);
+}
+
+void
+listing_list (on)
+ int on;
+{
+ s_ignore (0);
+}
+
+void
+listing_eject (ignore)
+ int ignore;
+{
+ s_ignore (0);
+}
+
+void
+listing_psize (ignore)
+ int ignore;
+{
+ s_ignore (0);
+}
+
+void
+listing_nopage (ignore)
+ int ignore;
+{
+ s_ignore (0);
+}
+
+void
+listing_title (depth)
+ int depth;
+{
+ s_ignore (0);
+}
+
+void
+listing_file (name)
+ const char *name;
+{
+
+}
+
+void
+listing_newline (name)
+ char *name;
+{
+
+}
+
+void
+listing_source_line (n)
+ unsigned int n;
+{
+
+}
+void
+listing_source_file (n)
+ const char *n;
+{
+
+}
+
+#endif
diff --git a/gas/listing.h b/gas/listing.h
new file mode 100644
index 00000000000..c0d5c373e55
--- /dev/null
+++ b/gas/listing.h
@@ -0,0 +1,67 @@
+/* This file is listing.h
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 1997
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef __listing_h__
+#define __listing_h__
+
+#define LISTING_LISTING 1
+#define LISTING_SYMBOLS 2
+#define LISTING_NOFORM 4
+#define LISTING_HLL 8
+#define LISTING_NODEBUG 16
+#define LISTING_NOCOND 32
+#define LISTING_MACEXP 64
+
+#define LISTING_DEFAULT (LISTING_LISTING | LISTING_HLL | LISTING_SYMBOLS)
+
+#ifndef NO_LISTING
+#define LISTING_NEWLINE() { if (listing) listing_newline(NULL); }
+#else
+#define LISTING_NEWLINE() {;}
+#endif
+#define LISTING_EOF() LISTING_NEWLINE()
+
+#define LISTING_SKIP_COND() ((listing & LISTING_NOCOND) != 0)
+
+void listing_eject PARAMS ((int));
+void listing_error PARAMS ((const char *message));
+void listing_file PARAMS ((const char *name));
+void listing_flags PARAMS ((int));
+void listing_list PARAMS ((int on));
+void listing_newline PARAMS ((char *ps));
+void listing_prev_line PARAMS ((void));
+void listing_print PARAMS ((char *name));
+void listing_psize PARAMS ((int));
+void listing_nopage PARAMS ((int));
+void listing_source_file PARAMS ((const char *));
+void listing_source_line PARAMS ((unsigned int));
+void listing_title PARAMS ((int depth));
+void listing_warning PARAMS ((const char *message));
+void listing_width PARAMS ((unsigned int x));
+
+extern int listing_lhs_width;
+extern int listing_lhs_width_second;
+extern int listing_lhs_cont_lines;
+extern int listing_rhs_width;
+
+#endif /* __listing_h__ */
+
+/* end of listing.h */
diff --git a/gas/literal.c b/gas/literal.c
new file mode 100644
index 00000000000..a3f8fc4da1e
--- /dev/null
+++ b/gas/literal.c
@@ -0,0 +1,95 @@
+/* as.c - GAS literal pool management.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+ Written by Ken Raeburn (raeburn@cygnus.com).
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This isn't quite a "constant" pool. Some of the values may get
+ adjusted at run time, e.g., for symbolic relocations when shared
+ libraries are in use. It's more of a "literal" pool.
+
+ On the Alpha, this should be used for .lita and .lit8. (Is there
+ ever a .lit4?) On the MIPS, it could be used for .lit4 as well.
+
+ The expressions passed here should contain either constants or symbols,
+ not a combination of both. Typically, the constant pool is accessed
+ with some sort of GP register, so the size of the pool must be kept down
+ if possible. The exception is section offsets -- if you're storing a
+ pointer to the start of .data, for example, and your machine provides
+ for 16-bit signed addends, you might want to store .data+32K, so that
+ you can access all of the first 64K of .data with the one pointer.
+
+ This isn't a requirement, just a guideline that can help keep .o file
+ size down. */
+
+#include "as.h"
+#include "subsegs.h"
+
+#if defined (BFD_ASSEMBLER) && defined (NEED_LITERAL_POOL)
+
+valueT
+add_to_literal_pool (sym, addend, sec, size)
+ symbolS *sym;
+ valueT addend;
+ segT sec;
+ int size;
+{
+ segT current_section = now_seg;
+ int current_subsec = now_subseg;
+ valueT offset;
+ bfd_reloc_code_real_type reloc_type;
+ char *p;
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp;
+
+ offset = 0;
+ /* @@ This assumes all entries in a given section will be of the same
+ size... Probably correct, but unwise to rely on. */
+ /* This must always be called with the same subsegment. */
+ if (seginfo->frchainP)
+ for (fixp = seginfo->frchainP->fix_root;
+ fixp != (fixS *) NULL;
+ fixp = fixp->fx_next, offset += size)
+ {
+ if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
+ return offset;
+ }
+
+ subseg_set (sec, 0);
+ p = frag_more (size);
+ memset (p, 0, size);
+
+ switch (size)
+ {
+ case 4:
+ reloc_type = BFD_RELOC_32;
+ break;
+ case 8:
+ reloc_type = BFD_RELOC_64;
+ break;
+ default:
+ abort ();
+ }
+ fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0,
+ reloc_type);
+
+ subseg_set (current_section, current_subsec);
+ offset = seginfo->literal_pool_size;
+ seginfo->literal_pool_size += size;
+ return offset;
+}
+#endif /* BFD_ASSEMBLER */
diff --git a/gas/mac-as.r b/gas/mac-as.r
new file mode 100644
index 00000000000..f36c033cb07
--- /dev/null
+++ b/gas/mac-as.r
@@ -0,0 +1,42 @@
+/* Resources for GNU AS. */
+
+#include "SysTypes.r"
+
+/* Version resources. */
+
+resource 'vers' (1) {
+ 0,
+ 0,
+ 0,
+ 0,
+ verUs,
+ VERSION_STRING,
+ VERSION_STRING " (C) 1986-95 FSF, Inc."
+};
+
+resource 'vers' (2, purgeable) {
+ 0,
+ 0,
+ 0,
+ 0,
+ verUs,
+ VERSION_STRING,
+ "GAS " VERSION_STRING " for MPW"
+};
+
+#ifdef WANT_CFRG
+
+#include "CodeFragmentTypes.r"
+
+resource 'cfrg' (0) {
+ {
+ kPowerPC,
+ kFullLib,
+ kNoVersionNum, kNoVersionNum,
+ 0,0,
+ kIsApp, kOnDiskFlat, kZeroOffset, kWholeFork,
+ PROG_NAME
+ }
+};
+
+#endif /* WANT_CFRG */
diff --git a/gas/macro.c b/gas/macro.c
new file mode 100644
index 00000000000..9d92ff4f1b1
--- /dev/null
+++ b/gas/macro.c
@@ -0,0 +1,1259 @@
+/* macro.c - macro support for gas and gasp
+ Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "config.h"
+
+/* AIX requires this to be the first thing in the file. */
+#ifdef __GNUC__
+# ifndef alloca
+# ifdef __STDC__
+extern void *alloca ();
+# else
+extern char *alloca ();
+# endif
+# endif
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# if !defined (__STDC__) && !defined (__hpux)
+extern char *alloca ();
+# else
+extern void *alloca ();
+# endif /* __STDC__, __hpux */
+# endif /* alloca */
+# endif /* _AIX */
+# endif /* HAVE_ALLOCA_H */
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <ctype.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "libiberty.h"
+#include "sb.h"
+#include "hash.h"
+#include "macro.h"
+
+#include "asintl.h"
+
+/* The routines in this file handle macro definition and expansion.
+ They are called by both gasp and gas. */
+
+/* Structures used to store macros.
+
+ Each macro knows its name and included text. It gets built with a
+ list of formal arguments, and also keeps a hash table which points
+ into the list to speed up formal search. Each formal knows its
+ name and its default value. Each time the macro is expanded, the
+ formals get the actual values attatched to them. */
+
+/* describe the formal arguments to a macro */
+
+typedef struct formal_struct
+ {
+ struct formal_struct *next; /* next formal in list */
+ sb name; /* name of the formal */
+ sb def; /* the default value */
+ sb actual; /* the actual argument (changed on each expansion) */
+ int index; /* the index of the formal 0..formal_count-1 */
+ }
+formal_entry;
+
+/* Other values found in the index field of a formal_entry. */
+#define QUAL_INDEX (-1)
+#define NARG_INDEX (-2)
+#define LOCAL_INDEX (-3)
+
+/* describe the macro. */
+
+typedef struct macro_struct
+ {
+ sb sub; /* substitution text. */
+ int formal_count; /* number of formal args. */
+ formal_entry *formals; /* pointer to list of formal_structs */
+ struct hash_control *formal_hash; /* hash table of formals. */
+ }
+macro_entry;
+
+/* Internal functions. */
+
+static int get_token PARAMS ((int, sb *, sb *));
+static int getstring PARAMS ((int, sb *, sb *));
+static int get_any_string PARAMS ((int, sb *, sb *, int, int));
+static int do_formals PARAMS ((macro_entry *, int, sb *));
+static int get_apost_token PARAMS ((int, sb *, sb *, int));
+static int sub_actual
+ PARAMS ((int, sb *, sb *, struct hash_control *, int, sb *, int));
+static const char *macro_expand_body
+ PARAMS ((sb *, sb *, formal_entry *, struct hash_control *, int, int));
+static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *, int));
+
+#define ISWHITE(x) ((x) == ' ' || (x) == '\t')
+
+#define ISSEP(x) \
+ ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
+ || (x) == ')' || (x) == '(' \
+ || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
+
+#define ISBASE(x) \
+ ((x) == 'b' || (x) == 'B' \
+ || (x) == 'q' || (x) == 'Q' \
+ || (x) == 'h' || (x) == 'H' \
+ || (x) == 'd' || (x) == 'D')
+
+/* The macro hash table. */
+
+static struct hash_control *macro_hash;
+
+/* Whether any macros have been defined. */
+
+int macro_defined;
+
+/* Whether we are in GASP alternate mode. */
+
+static int macro_alternate;
+
+/* Whether we are in MRI mode. */
+
+static int macro_mri;
+
+/* Whether we should strip '@' characters. */
+
+static int macro_strip_at;
+
+/* Function to use to parse an expression. */
+
+static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
+
+/* Number of macro expansions that have been done. */
+
+static int macro_number;
+
+/* Initialize macro processing. */
+
+void
+macro_init (alternate, mri, strip_at, expr)
+ int alternate;
+ int mri;
+ int strip_at;
+ int (*expr) PARAMS ((const char *, int, sb *, int *));
+{
+ macro_hash = hash_new ();
+ macro_defined = 0;
+ macro_alternate = alternate;
+ macro_mri = mri;
+ macro_strip_at = strip_at;
+ macro_expr = expr;
+}
+
+/* Switch in and out of MRI mode on the fly. */
+
+void
+macro_mri_mode (mri)
+ int mri;
+{
+ macro_mri = mri;
+}
+
+/* Read input lines till we get to a TO string.
+ Increase nesting depth if we get a FROM string.
+ Put the results into sb at PTR.
+ Add a new input line to an sb using GET_LINE.
+ Return 1 on success, 0 on unexpected EOF. */
+
+int
+buffer_and_nest (from, to, ptr, get_line)
+ const char *from;
+ const char *to;
+ sb *ptr;
+ int (*get_line) PARAMS ((sb *));
+{
+ int from_len = strlen (from);
+ int to_len = strlen (to);
+ int depth = 1;
+ int line_start = ptr->len;
+
+ int more = get_line (ptr);
+
+ while (more)
+ {
+ /* Try and find the first pseudo op on the line */
+ int i = line_start;
+
+ if (! macro_alternate && ! macro_mri)
+ {
+ /* With normal syntax we can suck what we want till we get
+ to the dot. With the alternate, labels have to start in
+ the first column, since we cant tell what's a label and
+ whats a pseudoop */
+
+ /* Skip leading whitespace */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+
+ /* Skip over a label */
+ while (i < ptr->len
+ && (isalnum ((unsigned char) ptr->ptr[i])
+ || ptr->ptr[i] == '_'
+ || ptr->ptr[i] == '$'))
+ i++;
+
+ /* And a colon */
+ if (i < ptr->len
+ && ptr->ptr[i] == ':')
+ i++;
+
+ }
+ /* Skip trailing whitespace */
+ while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+ i++;
+
+ if (i < ptr->len && (ptr->ptr[i] == '.'
+ || macro_alternate
+ || macro_mri))
+ {
+ if (ptr->ptr[i] == '.')
+ i++;
+ if (strncasecmp (ptr->ptr + i, from, from_len) == 0)
+ depth++;
+ if (strncasecmp (ptr->ptr + i, to, to_len) == 0)
+ {
+ depth--;
+ if (depth == 0)
+ {
+ /* Reset the string to not include the ending rune */
+ ptr->len = line_start;
+ break;
+ }
+ }
+ }
+
+ /* Add a CR to the end and keep running */
+ sb_add_char (ptr, '\n');
+ line_start = ptr->len;
+ more = get_line (ptr);
+ }
+
+ /* Return 1 on success, 0 on unexpected EOF. */
+ return depth == 0;
+}
+
+/* Pick up a token. */
+
+static int
+get_token (idx, in, name)
+ int idx;
+ sb *in;
+ sb *name;
+{
+ if (idx < in->len
+ && (isalpha ((unsigned char) in->ptr[idx])
+ || in->ptr[idx] == '_'
+ || in->ptr[idx] == '$'))
+ {
+ sb_add_char (name, in->ptr[idx++]);
+ while (idx < in->len
+ && (isalnum ((unsigned char) in->ptr[idx])
+ || in->ptr[idx] == '_'
+ || in->ptr[idx] == '$'))
+ {
+ sb_add_char (name, in->ptr[idx++]);
+ }
+ }
+ /* Ignore trailing & */
+ if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
+ idx++;
+ return idx;
+}
+
+/* Pick up a string. */
+
+static int
+getstring (idx, in, acc)
+ int idx;
+ sb *in;
+ sb *acc;
+{
+ idx = sb_skip_white (idx, in);
+
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
+ || (in->ptr[idx] == '\'' && macro_alternate)))
+ {
+ if (in->ptr[idx] == '<')
+ {
+ int nest = 0;
+ idx++;
+ while ((in->ptr[idx] != '>' || nest)
+ && idx < in->len)
+ {
+ if (in->ptr[idx] == '!')
+ {
+ idx++ ;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else
+ {
+ if (in->ptr[idx] == '>')
+ nest--;
+ if (in->ptr[idx] == '<')
+ nest++;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ }
+ idx++;
+ }
+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ idx++;
+ while (idx < in->len)
+ {
+ if (macro_alternate && in->ptr[idx] == '!')
+ {
+ idx++ ;
+ sb_add_char (acc, in->ptr[idx++]);
+ }
+ else
+ {
+ if (in->ptr[idx] == tchar)
+ {
+ idx++;
+ if (idx >= in->len || in->ptr[idx] != tchar)
+ break;
+ }
+ sb_add_char (acc, in->ptr[idx]);
+ idx++;
+ }
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* Fetch string from the input stream,
+ rules:
+ 'Bxyx<whitespace> -> return 'Bxyza
+ %<char> -> return string of decimal value of x
+ "<string>" -> return string
+ xyx<whitespace> -> return xyz
+*/
+
+static int
+get_any_string (idx, in, out, expand, pretend_quoted)
+ int idx;
+ sb *in;
+ sb *out;
+ int expand;
+ int pretend_quoted;
+{
+ sb_reset (out);
+ idx = sb_skip_white (idx, in);
+
+ if (idx < in->len)
+ {
+ if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
+ {
+ while (!ISSEP (in->ptr[idx]))
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ else if (in->ptr[idx] == '%'
+ && macro_alternate
+ && expand)
+ {
+ int val;
+ char buf[20];
+ /* Turns the next expression into a string */
+ idx = (*macro_expr) (_("% operator needs absolute expression"),
+ idx + 1,
+ in,
+ &val);
+ sprintf(buf, "%d", val);
+ sb_add_string (out, buf);
+ }
+ else if (in->ptr[idx] == '"'
+ || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
+ || (macro_alternate && in->ptr[idx] == '\''))
+ {
+ if (macro_alternate
+ && ! macro_strip_at
+ && expand)
+ {
+ /* Keep the quotes */
+ sb_add_char (out, '\"');
+
+ idx = getstring (idx, in, out);
+ sb_add_char (out, '\"');
+ }
+ else
+ {
+ idx = getstring (idx, in, out);
+ }
+ }
+ else
+ {
+ while (idx < in->len
+ && (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\''
+ || pretend_quoted
+ || (in->ptr[idx] != ' '
+ && in->ptr[idx] != '\t'
+ && in->ptr[idx] != ','
+ && (in->ptr[idx] != '<'
+ || (! macro_alternate && ! macro_mri)))))
+ {
+ if (in->ptr[idx] == '"'
+ || in->ptr[idx] == '\'')
+ {
+ char tchar = in->ptr[idx];
+ sb_add_char (out, in->ptr[idx++]);
+ while (idx < in->len
+ && in->ptr[idx] != tchar)
+ sb_add_char (out, in->ptr[idx++]);
+ if (idx == in->len)
+ return idx;
+ }
+ sb_add_char (out, in->ptr[idx++]);
+ }
+ }
+ }
+
+ return idx;
+}
+
+/* Pick up the formal parameters of a macro definition. */
+
+static int
+do_formals (macro, idx, in)
+ macro_entry *macro;
+ int idx;
+ sb *in;
+{
+ formal_entry **p = &macro->formals;
+
+ macro->formal_count = 0;
+ macro->formal_hash = hash_new ();
+ while (idx < in->len)
+ {
+ formal_entry *formal;
+
+ formal = (formal_entry *) xmalloc (sizeof (formal_entry));
+
+ sb_new (&formal->name);
+ sb_new (&formal->def);
+ sb_new (&formal->actual);
+
+ idx = sb_skip_white (idx, in);
+ idx = get_token (idx, in, &formal->name);
+ if (formal->name.len == 0)
+ break;
+ idx = sb_skip_white (idx, in);
+ if (formal->name.len)
+ {
+ /* This is a formal */
+ if (idx < in->len && in->ptr[idx] == '=')
+ {
+ /* Got a default */
+ idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
+ }
+ }
+
+ /* Add to macro's hash table */
+ hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
+
+ formal->index = macro->formal_count;
+ idx = sb_skip_comma (idx, in);
+ macro->formal_count++;
+ *p = formal;
+ p = &formal->next;
+ *p = NULL;
+ }
+
+ if (macro_mri)
+ {
+ formal_entry *formal;
+ const char *name;
+
+ /* Add a special NARG formal, which macro_expand will set to the
+ number of arguments. */
+ formal = (formal_entry *) xmalloc (sizeof (formal_entry));
+
+ sb_new (&formal->name);
+ sb_new (&formal->def);
+ sb_new (&formal->actual);
+
+ /* The same MRI assemblers which treat '@' characters also use
+ the name $NARG. At least until we find an exception. */
+ if (macro_strip_at)
+ name = "$NARG";
+ else
+ name = "NARG";
+
+ sb_add_string (&formal->name, name);
+
+ /* Add to macro's hash table */
+ hash_jam (macro->formal_hash, name, formal);
+
+ formal->index = NARG_INDEX;
+ *p = formal;
+ formal->next = NULL;
+ }
+
+ return idx;
+}
+
+/* Define a new macro. Returns NULL on success, otherwise returns an
+ error message. If NAMEP is not NULL, *NAMEP is set to the name of
+ the macro which was defined. */
+
+const char *
+define_macro (idx, in, label, get_line, namep)
+ int idx;
+ sb *in;
+ sb *label;
+ int (*get_line) PARAMS ((sb *));
+ const char **namep;
+{
+ macro_entry *macro;
+ sb name;
+ const char *namestr;
+
+ macro = (macro_entry *) xmalloc (sizeof (macro_entry));
+ sb_new (&macro->sub);
+ sb_new (&name);
+
+ macro->formal_count = 0;
+ macro->formals = 0;
+
+ idx = sb_skip_white (idx, in);
+ if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
+ return _("unexpected end of file in macro definition");
+ if (label != NULL && label->len != 0)
+ {
+ sb_add_sb (&name, label);
+ if (idx < in->len && in->ptr[idx] == '(')
+ {
+ /* It's the label: MACRO (formals,...) sort */
+ idx = do_formals (macro, idx + 1, in);
+ if (in->ptr[idx] != ')')
+ return _("missing ) after formals");
+ }
+ else
+ {
+ /* It's the label: MACRO formals,... sort */
+ idx = do_formals (macro, idx, in);
+ }
+ }
+ else
+ {
+ idx = get_token (idx, in, &name);
+ idx = sb_skip_comma (idx, in);
+ idx = do_formals (macro, idx, in);
+ }
+
+ /* and stick it in the macro hash table */
+ for (idx = 0; idx < name.len; idx++)
+ if (isupper ((unsigned char) name.ptr[idx]))
+ name.ptr[idx] = tolower (name.ptr[idx]);
+ namestr = sb_terminate (&name);
+ hash_jam (macro_hash, namestr, (PTR) macro);
+
+ macro_defined = 1;
+
+ if (namep != NULL)
+ *namep = namestr;
+
+ return NULL;
+}
+
+/* Scan a token, and then skip KIND. */
+
+static int
+get_apost_token (idx, in, name, kind)
+ int idx;
+ sb *in;
+ sb *name;
+ int kind;
+{
+ idx = get_token (idx, in, name);
+ if (idx < in->len
+ && in->ptr[idx] == kind
+ && (! macro_mri || macro_strip_at)
+ && (! macro_strip_at || kind == '@'))
+ idx++;
+ return idx;
+}
+
+/* Substitute the actual value for a formal parameter. */
+
+static int
+sub_actual (start, in, t, formal_hash, kind, out, copyifnotthere)
+ int start;
+ sb *in;
+ sb *t;
+ struct hash_control *formal_hash;
+ int kind;
+ sb *out;
+ int copyifnotthere;
+{
+ int src;
+ formal_entry *ptr;
+
+ src = get_apost_token (start, in, t, kind);
+ /* See if it's in the macro's hash table, unless this is
+ macro_strip_at and kind is '@' and the token did not end in '@'. */
+ if (macro_strip_at
+ && kind == '@'
+ && (src == start || in->ptr[src - 1] != '@'))
+ ptr = NULL;
+ else
+ ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
+ if (ptr)
+ {
+ if (ptr->actual.len)
+ {
+ sb_add_sb (out, &ptr->actual);
+ }
+ else
+ {
+ sb_add_sb (out, &ptr->def);
+ }
+ }
+ else if (kind == '&')
+ {
+ /* Doing this permits people to use & in macro bodies. */
+ sb_add_char (out, '&');
+ }
+ else if (copyifnotthere)
+ {
+ sb_add_sb (out, t);
+ }
+ else
+ {
+ sb_add_char (out, '\\');
+ sb_add_sb (out, t);
+ }
+ return src;
+}
+
+/* Expand the body of a macro. */
+
+static const char *
+macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
+ sb *in;
+ sb *out;
+ formal_entry *formals;
+ struct hash_control *formal_hash;
+ int comment_char;
+ int locals;
+{
+ sb t;
+ int src = 0;
+ int inquote = 0;
+ formal_entry *loclist = NULL;
+
+ sb_new (&t);
+
+ while (src < in->len)
+ {
+ if (in->ptr[src] == '&')
+ {
+ sb_reset (&t);
+ if (macro_mri)
+ {
+ if (src + 1 < in->len && in->ptr[src + 1] == '&')
+ src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
+ else
+ sb_add_char (out, in->ptr[src++]);
+ }
+ else
+ {
+ /* FIXME: Why do we do this? */
+ src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
+ }
+ }
+ else if (in->ptr[src] == '\\')
+ {
+ src++;
+ if (in->ptr[src] == comment_char && comment_char != '\0')
+ {
+ /* This is a comment, just drop the rest of the line */
+ while (src < in->len
+ && in->ptr[src] != '\n')
+ src++;
+ }
+ else if (in->ptr[src] == '(')
+ {
+ /* Sub in till the next ')' literally */
+ src++;
+ while (src < in->len && in->ptr[src] != ')')
+ {
+ sb_add_char (out, in->ptr[src++]);
+ }
+ if (in->ptr[src] == ')')
+ src++;
+ else
+ return _("missplaced )");
+ }
+ else if (in->ptr[src] == '@')
+ {
+ /* Sub in the macro invocation number */
+
+ char buffer[10];
+ src++;
+ sprintf (buffer, "%05d", macro_number);
+ sb_add_string (out, buffer);
+ }
+ else if (in->ptr[src] == '&')
+ {
+ /* This is a preprocessor variable name, we don't do them
+ here */
+ sb_add_char (out, '\\');
+ sb_add_char (out, '&');
+ src++;
+ }
+ else if (macro_mri
+ && isalnum ((unsigned char) in->ptr[src]))
+ {
+ int ind;
+ formal_entry *f;
+
+ if (isdigit ((unsigned char) in->ptr[src]))
+ ind = in->ptr[src] - '0';
+ else if (isupper ((unsigned char) in->ptr[src]))
+ ind = in->ptr[src] - 'A' + 10;
+ else
+ ind = in->ptr[src] - 'a' + 10;
+ ++src;
+ for (f = formals; f != NULL; f = f->next)
+ {
+ if (f->index == ind - 1)
+ {
+ if (f->actual.len != 0)
+ sb_add_sb (out, &f->actual);
+ else
+ sb_add_sb (out, &f->def);
+ break;
+ }
+ }
+ }
+ else
+ {
+ sb_reset (&t);
+ src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
+ }
+ }
+ else if ((macro_alternate || macro_mri)
+ && (isalpha ((unsigned char) in->ptr[src])
+ || in->ptr[src] == '_'
+ || in->ptr[src] == '$')
+ && (! inquote
+ || ! macro_strip_at
+ || (src > 0 && in->ptr[src - 1] == '@')))
+ {
+ if (! locals
+ || src + 5 >= in->len
+ || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
+ || ! ISWHITE (in->ptr[src + 5]))
+ {
+ sb_reset (&t);
+ src = sub_actual (src, in, &t, formal_hash,
+ (macro_strip_at && inquote) ? '@' : '\'',
+ out, 1);
+ }
+ else
+ {
+ formal_entry *f;
+
+ src = sb_skip_white (src + 5, in);
+ while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
+ {
+ static int loccnt;
+ char buf[20];
+ const char *err;
+
+ f = (formal_entry *) xmalloc (sizeof (formal_entry));
+ sb_new (&f->name);
+ sb_new (&f->def);
+ sb_new (&f->actual);
+ f->index = LOCAL_INDEX;
+ f->next = loclist;
+ loclist = f;
+
+ src = get_token (src, in, &f->name);
+ ++loccnt;
+ sprintf (buf, "LL%04x", loccnt);
+ sb_add_string (&f->actual, buf);
+
+ err = hash_jam (formal_hash, sb_terminate (&f->name), f);
+ if (err != NULL)
+ return err;
+
+ src = sb_skip_comma (src, in);
+ }
+ }
+ }
+ else if (comment_char != '\0'
+ && in->ptr[src] == comment_char
+ && src + 1 < in->len
+ && in->ptr[src + 1] == comment_char
+ && !inquote)
+ {
+ /* Two comment chars in a row cause the rest of the line to
+ be dropped. */
+ while (src < in->len && in->ptr[src] != '\n')
+ src++;
+ }
+ else if (in->ptr[src] == '"'
+ || (macro_mri && in->ptr[src] == '\''))
+ {
+ inquote = !inquote;
+ sb_add_char (out, in->ptr[src++]);
+ }
+ else if (in->ptr[src] == '@' && macro_strip_at)
+ {
+ ++src;
+ if (src < in->len
+ && in->ptr[src] == '@')
+ {
+ sb_add_char (out, '@');
+ ++src;
+ }
+ }
+ else if (macro_mri
+ && in->ptr[src] == '='
+ && src + 1 < in->len
+ && in->ptr[src + 1] == '=')
+ {
+ formal_entry *ptr;
+
+ sb_reset (&t);
+ src = get_token (src + 2, in, &t);
+ ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
+ if (ptr == NULL)
+ {
+ /* FIXME: We should really return a warning string here,
+ but we can't, because the == might be in the MRI
+ comment field, and, since the nature of the MRI
+ comment field depends upon the exact instruction
+ being used, we don't have enough information here to
+ figure out whether it is or not. Instead, we leave
+ the == in place, which should cause a syntax error if
+ it is not in a comment. */
+ sb_add_char (out, '=');
+ sb_add_char (out, '=');
+ sb_add_sb (out, &t);
+ }
+ else
+ {
+ if (ptr->actual.len)
+ {
+ sb_add_string (out, "-1");
+ }
+ else
+ {
+ sb_add_char (out, '0');
+ }
+ }
+ }
+ else
+ {
+ sb_add_char (out, in->ptr[src++]);
+ }
+ }
+
+ sb_kill (&t);
+
+ while (loclist != NULL)
+ {
+ formal_entry *f;
+
+ f = loclist->next;
+ hash_delete (formal_hash, sb_terminate (&loclist->name));
+ sb_kill (&loclist->name);
+ sb_kill (&loclist->def);
+ sb_kill (&loclist->actual);
+ free (loclist);
+ loclist = f;
+ }
+
+ return NULL;
+}
+
+/* Assign values to the formal parameters of a macro, and expand the
+ body. */
+
+static const char *
+macro_expand (idx, in, m, out, comment_char)
+ int idx;
+ sb *in;
+ macro_entry *m;
+ sb *out;
+ int comment_char;
+{
+ sb t;
+ formal_entry *ptr;
+ formal_entry *f;
+ int is_positional = 0;
+ int is_keyword = 0;
+ int narg = 0;
+ const char *err;
+
+ sb_new (&t);
+
+ /* Reset any old value the actuals may have */
+ for (f = m->formals; f; f = f->next)
+ sb_reset (&f->actual);
+ f = m->formals;
+ while (f != NULL && f->index < 0)
+ f = f->next;
+
+ if (macro_mri)
+ {
+ /* The macro may be called with an optional qualifier, which may
+ be referred to in the macro body as \0. */
+ if (idx < in->len && in->ptr[idx] == '.')
+ {
+ formal_entry *n;
+
+ n = (formal_entry *) xmalloc (sizeof (formal_entry));
+ sb_new (&n->name);
+ sb_new (&n->def);
+ sb_new (&n->actual);
+ n->index = QUAL_INDEX;
+
+ n->next = m->formals;
+ m->formals = n;
+
+ idx = get_any_string (idx + 1, in, &n->actual, 1, 0);
+ }
+ }
+
+ /* Peel off the actuals and store them away in the hash tables' actuals */
+ idx = sb_skip_white (idx, in);
+ while (idx < in->len && in->ptr[idx] != comment_char)
+ {
+ int scan;
+
+ /* Look and see if it's a positional or keyword arg */
+ scan = idx;
+ while (scan < in->len
+ && !ISSEP (in->ptr[scan])
+ && !(macro_mri && in->ptr[scan] == '\'')
+ && (!macro_alternate && in->ptr[scan] != '='))
+ scan++;
+ if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
+ {
+ is_keyword = 1;
+
+ /* It's OK to go from positional to keyword. */
+
+ /* This is a keyword arg, fetch the formal name and
+ then the actual stuff */
+ sb_reset (&t);
+ idx = get_token (idx, in, &t);
+ if (in->ptr[idx] != '=')
+ return _("confusion in formal parameters");
+
+ /* Lookup the formal in the macro's list */
+ ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
+ if (!ptr)
+ return _("macro formal argument does not exist");
+ else
+ {
+ /* Insert this value into the right place */
+ sb_reset (&ptr->actual);
+ idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
+ if (ptr->actual.len > 0)
+ ++narg;
+ }
+ }
+ else
+ {
+ /* This is a positional arg */
+ is_positional = 1;
+ if (is_keyword)
+ return _("can't mix positional and keyword arguments");
+
+ if (!f)
+ {
+ formal_entry **pf;
+ int c;
+
+ if (!macro_mri)
+ return _("too many positional arguments");
+
+ f = (formal_entry *) xmalloc (sizeof (formal_entry));
+ sb_new (&f->name);
+ sb_new (&f->def);
+ sb_new (&f->actual);
+ f->next = NULL;
+
+ c = -1;
+ for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
+ if ((*pf)->index >= c)
+ c = (*pf)->index + 1;
+ if (c == -1)
+ c = 0;
+ *pf = f;
+ f->index = c;
+ }
+
+ sb_reset (&f->actual);
+ idx = get_any_string (idx, in, &f->actual, 1, 0);
+ if (f->actual.len > 0)
+ ++narg;
+ do
+ {
+ f = f->next;
+ }
+ while (f != NULL && f->index < 0);
+ }
+
+ if (! macro_mri)
+ idx = sb_skip_comma (idx, in);
+ else
+ {
+ if (in->ptr[idx] == ',')
+ ++idx;
+ if (ISWHITE (in->ptr[idx]))
+ break;
+ }
+ }
+
+ if (macro_mri)
+ {
+ char buffer[20];
+
+ sb_reset (&t);
+ sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
+ ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
+ sb_reset (&ptr->actual);
+ sprintf (buffer, "%d", narg);
+ sb_add_string (&ptr->actual, buffer);
+ }
+
+ err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash,
+ comment_char, 1);
+ if (err != NULL)
+ return err;
+
+ /* Discard any unnamed formal arguments. */
+ if (macro_mri)
+ {
+ formal_entry **pf;
+
+ pf = &m->formals;
+ while (*pf != NULL)
+ {
+ if ((*pf)->name.len != 0)
+ pf = &(*pf)->next;
+ else
+ {
+ sb_kill (&(*pf)->name);
+ sb_kill (&(*pf)->def);
+ sb_kill (&(*pf)->actual);
+ f = (*pf)->next;
+ free (*pf);
+ *pf = f;
+ }
+ }
+ }
+
+ sb_kill (&t);
+ macro_number++;
+
+ return NULL;
+}
+
+/* Check for a macro. If one is found, put the expansion into
+ *EXPAND. COMMENT_CHAR is the comment character--this is used by
+ gasp. Return 1 if a macro is found, 0 otherwise. */
+
+int
+check_macro (line, expand, comment_char, error)
+ const char *line;
+ sb *expand;
+ int comment_char;
+ const char **error;
+{
+ const char *s;
+ char *copy, *cs;
+ macro_entry *macro;
+ sb line_sb;
+
+ if (! isalpha ((unsigned char) *line)
+ && *line != '_'
+ && *line != '$'
+ && (! macro_mri || *line != '.'))
+ return 0;
+
+ s = line + 1;
+ while (isalnum ((unsigned char) *s)
+ || *s == '_'
+ || *s == '$')
+ ++s;
+
+ copy = (char *) alloca (s - line + 1);
+ memcpy (copy, line, s - line);
+ copy[s - line] = '\0';
+ for (cs = copy; *cs != '\0'; cs++)
+ if (isupper ((unsigned char) *cs))
+ *cs = tolower (*cs);
+
+ macro = (macro_entry *) hash_find (macro_hash, copy);
+
+ if (macro == NULL)
+ return 0;
+
+ /* Wrap the line up in an sb. */
+ sb_new (&line_sb);
+ while (*s != '\0' && *s != '\n' && *s != '\r')
+ sb_add_char (&line_sb, *s++);
+
+ sb_new (expand);
+ *error = macro_expand (0, &line_sb, macro, expand, comment_char);
+
+ sb_kill (&line_sb);
+
+ return 1;
+}
+
+/* Delete a macro. */
+
+void
+delete_macro (name)
+ const char *name;
+{
+ hash_delete (macro_hash, name);
+}
+
+/* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
+ combined macro definition and execution. This returns NULL on
+ success, or an error message otherwise. */
+
+const char *
+expand_irp (irpc, idx, in, out, get_line, comment_char)
+ int irpc;
+ int idx;
+ sb *in;
+ sb *out;
+ int (*get_line) PARAMS ((sb *));
+ int comment_char;
+{
+ const char *mn;
+ sb sub;
+ formal_entry f;
+ struct hash_control *h;
+ const char *err;
+
+ if (irpc)
+ mn = "IRPC";
+ else
+ mn = "IRP";
+
+ idx = sb_skip_white (idx, in);
+
+ sb_new (&sub);
+ if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
+ return _("unexpected end of file in irp or irpc");
+
+ sb_new (&f.name);
+ sb_new (&f.def);
+ sb_new (&f.actual);
+
+ idx = get_token (idx, in, &f.name);
+ if (f.name.len == 0)
+ return _("missing model parameter");
+
+ h = hash_new ();
+ err = hash_jam (h, sb_terminate (&f.name), &f);
+ if (err != NULL)
+ return err;
+
+ f.index = 1;
+ f.next = NULL;
+
+ sb_reset (out);
+
+ idx = sb_skip_comma (idx, in);
+ if (idx >= in->len || in->ptr[idx] == comment_char)
+ {
+ /* Expand once with a null string. */
+ err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
+ if (err != NULL)
+ return err;
+ }
+ else
+ {
+ if (irpc && in->ptr[idx] == '"')
+ ++idx;
+ while (idx < in->len && in->ptr[idx] != comment_char)
+ {
+ if (!irpc)
+ idx = get_any_string (idx, in, &f.actual, 1, 0);
+ else
+ {
+ if (in->ptr[idx] == '"')
+ {
+ int nxt;
+
+ nxt = sb_skip_white (idx + 1, in);
+ if (nxt >= in->len || in->ptr[nxt] == comment_char)
+ {
+ idx = nxt;
+ break;
+ }
+ }
+ sb_reset (&f.actual);
+ sb_add_char (&f.actual, in->ptr[idx]);
+ ++idx;
+ }
+ err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
+ if (err != NULL)
+ return err;
+ if (!irpc)
+ idx = sb_skip_comma (idx, in);
+ else
+ idx = sb_skip_white (idx, in);
+ }
+ }
+
+ hash_die (h);
+ sb_kill (&sub);
+
+ return NULL;
+}
diff --git a/gas/macro.h b/gas/macro.h
new file mode 100644
index 00000000000..cdeea4ad3b4
--- /dev/null
+++ b/gas/macro.h
@@ -0,0 +1,53 @@
+/* macro.h - header file for macro support for gas and gasp
+ Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef MACRO_H
+
+#define MACRO_H
+
+#include "ansidecl.h"
+#include "sb.h"
+
+/* Whether any macros have been defined. */
+
+extern int macro_defined;
+
+/* The macro nesting level. */
+
+extern int macro_nest;
+
+extern int buffer_and_nest
+ PARAMS ((const char *, const char *, sb *, int (*) PARAMS ((sb *))));
+extern void macro_init
+ PARAMS ((int alternate, int mri, int strip_at,
+ int (*) PARAMS ((const char *, int, sb *, int *))));
+extern void macro_mri_mode PARAMS ((int));
+extern const char *define_macro
+ PARAMS ((int idx, sb *in, sb *label, int (*get_line) PARAMS ((sb *)),
+ const char **namep));
+extern int check_macro PARAMS ((const char *, sb *, int, const char **));
+extern void delete_macro PARAMS ((const char *));
+extern const char *expand_irp
+ PARAMS ((int, int, sb *, sb *, int (*) PARAMS ((sb *)), int));
+
+#endif
diff --git a/gas/makefile.vms b/gas/makefile.vms
new file mode 100644
index 00000000000..f4c30d47dd2
--- /dev/null
+++ b/gas/makefile.vms
@@ -0,0 +1,124 @@
+#
+# makefile for gas
+#
+# Created by Klaus K"ampf, kkaempf@progis.de
+#
+CC=gcc
+ifeq ($(ARCH),ALPHA)
+ifeq ($(CC),gcc)
+DEFS=
+CFLAGS=/include=([],[-.bfd],[.config],[-.include],[-])$(DEFS)
+LFLAGS=
+LIBS=,GNU_CC_LIBRARY:libgcc/lib,sys$$library:vaxcrtl.olb/lib,GNU_CC_LIBRARY:crt0.obj
+else
+DEFS=/define=("table_size_of_flonum_powers_of_ten"="tabsiz_flonum_powers_of_ten",\
+"_bfd_generic_get_section_contents_in_window"="_bfd_generic_get_win_section_cont",\
+"_elf_section_from_bfd_section"="_bfd_elf_sec_from_bfd_sec","const=")
+CFLAGS=/noopt/nodebug/include=([],[-.bfd],[.config],[-.include],[-])$(DEFS)\
+/warnings=disable=(missingreturn,implicitfunc,ptrmismatch,undefescap,longextern,duptypespec)
+LFLAGS=
+LIBS=,sys$$library:vaxcrtl.olb/lib
+endif
+
+else # ARCH not ALPHA
+
+ifeq ($(CC),gcc)
+DEFS=
+CFLAGS=/include=([],[.config],[-.include],[-])$(DEFS)
+LFLAGS=
+LIBS=,GNU_CC_LIBRARY:libgcc/lib,sys$$library:vaxcrtl.olb/lib,GNU_CC_LIBRARY:crtbegin.obj,GNU_CC_LIBRARY:crtend.obj
+#LIBS=,gnu_cc:[000000]gcclib.olb/lib,sys$$library:vaxcrtl.olb/lib
+else
+error DECC is broken on VAX
+DEFS=/define=("table_size_of_flonum_powers_of_ten"="tabsiz_flonum_powers_of_ten","const=")
+CFLAGS=/noopt/debug/include=([],[.config],[-.include],[-])$(DEFS)\
+/warnings=disable=(missingreturn,implicitfunc,ptrmismatch,undefescap,longextern,duptypespec)
+LFLAGS=
+LIBS=,sys$$library:vaxcrtl.olb/lib
+endif
+endif
+
+
+OBJS=targ-cpu.obj,obj-format.obj,atof-targ.obj,app.obj,as.obj,atof-generic.obj,\
+ bignum-copy.obj,cond.obj,depend.obj,expr.obj,flonum-konst.obj,flonum-copy.obj,\
+ flonum-mult.obj,frags.obj,hash.obj,input-file.obj,input-scrub.obj,\
+ literal.obj,messages.obj,output-file.obj,read.obj,subsegs.obj,symbols.obj,\
+ write.obj,listing.obj,ecoff.obj,stabs.obj,sb.obj,macro.obj,ehopt.obj
+
+GASPOBJS = gasp.obj,macro.obj,sb.obj,hash.obj
+
+LIBIBERTY = [-.libiberty]libiberty.olb
+
+ifeq ($(ARCH),ALPHA)
+LIBBFD = [-.bfd]libbfd.olb
+LIBOPCODES = [-.opcodes]libopcodes.olb
+BFDDEP = [-.bfd]bfd.h
+else
+LIBBFD =
+LIBOPCODES =
+BFDDEP =
+endif
+
+all: config.status $(BFDDEP) as.exe gasp.exe
+
+as.exe: $(OBJS) $(LIBOPCODES) $(LIBBFD) $(LIBIBERTY)
+ifeq ($(ARCH),ALPHA)
+ link$(LFLAGS)/exe=$@ $(OBJS),$(LIBOPCODES)/lib,$(LIBBFD)/lib,$(LIBIBERTY)/lib$(LIBS)
+else
+ link$(LFLAGS)/exe=$@ $(OBJS),$(LIBIBERTY)/lib$(LIBS)
+endif
+
+gasp.exe: $(GASPOBJS) $(LIBBFD) $(LIBIBERTY)
+ifeq ($(ARCH),ALPHA)
+ link$(LFLAGS)/exe=$@ $(GASPOBJS),$(LIBBFD)/lib,$(LIBIBERTY)/lib$(LIBS)
+else
+ link$(LFLAGS)/exe=$@ $(GASPOBJS),$(LIBIBERTY)/lib$(LIBS)
+endif
+
+config.status:
+ $$ @config-gas
+
+ifeq ($(ARCH),ALPHA)
+CPU=alpha
+OBJFORMAT=evax
+FLTFORMAT=ieee
+else
+CPU=vax
+OBJFORMAT=vms
+FLTFORMAT=vax
+endif
+
+targ-cpu.c: [.config]tc-$(CPU).c
+ copy $< $@
+targ-cpu.h: [.config]tc-$(CPU).h
+ copy $< $@
+targ-env.h: [.config]te-generic.h
+ copy $< $@
+obj-format.h: [.config]obj-$(OBJFORMAT).h
+ copy $< $@
+obj-format.c: [.config]obj-$(OBJFORMAT).c
+ copy $< $@
+atof-targ.c: [.config]atof-$(FLTFORMAT).c
+ copy $< $@
+
+targ-cpu.obj: targ-cpu.c targ-cpu.h [.config]atof-vax.c
+
+[-.bfd]bfd.h:
+ $(CD) [-.bfd]
+ gmake -f makefile.vms "CC=$(CC)"
+ $(CD) [-.gas]
+
+install: as.exe gasp.exe
+ $(CP) $^ GNU_ROOT\:[BIN]
+
+clean:
+ $$ purge
+ $(RM) *.obj;
+ $(RM) *.exe;
+ $(RM) atof-targ.c;
+ $(RM) obj-format.c;
+ $(RM) obj-format.h;
+ $(RM) targ-env.h;
+ $(RM) targ-cpu.h;
+ $(RM) targ-cpu.c;
+ $(RM) config.status;
diff --git a/gas/messages.c b/gas/messages.c
new file mode 100644
index 00000000000..e4b7ad00a11
--- /dev/null
+++ b/gas/messages.c
@@ -0,0 +1,541 @@
+/* messages.c - error reporter -
+ Copyright (C) 1987, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "as.h"
+
+#include <stdio.h>
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef USE_STDARG
+#include <stdarg.h>
+#endif
+
+#ifdef USE_VARARGS
+#include <varargs.h>
+#endif
+
+#if !defined (USE_STDARG) && !defined (USE_VARARGS)
+/* Roll our own. */
+#define va_alist REST
+#define va_dcl
+typedef int * va_list;
+#define va_start(ARGS) ARGS = &REST
+#define va_end(ARGS)
+#endif
+
+static void identify PARAMS ((char *));
+static void as_show_where PARAMS ((void));
+static void as_warn_internal PARAMS ((char *, unsigned int, char *));
+static void as_bad_internal PARAMS ((char *, unsigned int, char *));
+
+/*
+ * Despite the rest of the comments in this file, (FIXME-SOON),
+ * here is the current scheme for error messages etc:
+ *
+ * as_fatal() is used when gas is quite confused and
+ * continuing the assembly is pointless. In this case we
+ * exit immediately with error status.
+ *
+ * as_bad() is used to mark errors that result in what we
+ * presume to be a useless object file. Say, we ignored
+ * something that might have been vital. If we see any of
+ * these, assembly will continue to the end of the source,
+ * no object file will be produced, and we will terminate
+ * with error status. The new option, -Z, tells us to
+ * produce an object file anyway but we still exit with
+ * error status. The assumption here is that you don't want
+ * this object file but we could be wrong.
+ *
+ * as_warn() is used when we have an error from which we
+ * have a plausible error recovery. eg, masking the top
+ * bits of a constant that is longer than will fit in the
+ * destination. In this case we will continue to assemble
+ * the source, although we may have made a bad assumption,
+ * and we will produce an object file and return normal exit
+ * status (ie, no error). The new option -X tells us to
+ * treat all as_warn() errors as as_bad() errors. That is,
+ * no object file will be produced and we will exit with
+ * error status. The idea here is that we don't kill an
+ * entire make because of an error that we knew how to
+ * correct. On the other hand, sometimes you might want to
+ * stop the make at these points.
+ *
+ * as_tsktsk() is used when we see a minor error for which
+ * our error recovery action is almost certainly correct.
+ * In this case, we print a message and then assembly
+ * continues as though no error occurred.
+ */
+
+static void
+identify (file)
+ char *file;
+{
+ static int identified;
+ if (identified)
+ return;
+ identified++;
+
+ if (!file)
+ {
+ unsigned int x;
+ as_where (&file, &x);
+ }
+
+ if (file)
+ fprintf (stderr, "%s: ", file);
+ fprintf (stderr, _("Assembler messages:\n"));
+}
+
+static int warning_count; /* Count of number of warnings issued */
+
+int
+had_warnings ()
+{
+ return (warning_count);
+}
+
+/* Nonzero if we've hit a 'bad error', and should not write an obj file,
+ and exit with a nonzero error code */
+
+static int error_count;
+
+int
+had_errors ()
+{
+ return (error_count);
+}
+
+
+/* Print the current location to stderr. */
+
+static void
+as_show_where ()
+{
+ char *file;
+ unsigned int line;
+
+ as_where (&file, &line);
+ identify (file);
+ if (file)
+ fprintf (stderr, "%s:%u: ", file, line);
+}
+
+/*
+ * a s _ p e r r o r
+ *
+ * Like perror(3), but with more info.
+ */
+
+void
+as_perror (gripe, filename)
+ const char *gripe; /* Unpunctuated error theme. */
+ const char *filename;
+{
+ const char *errtxt;
+
+ as_show_where ();
+ fprintf (stderr, gripe, filename);
+#ifdef BFD_ASSEMBLER
+ errtxt = bfd_errmsg (bfd_get_error ());
+#else
+ errtxt = xstrerror (errno);
+#endif
+ fprintf (stderr, ": %s\n", errtxt);
+ errno = 0;
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_no_error);
+#endif
+}
+
+/*
+ * a s _ t s k t s k ()
+ *
+ * Send to stderr a string as a warning, and locate warning
+ * in input file(s).
+ * Please only use this for when we have some recovery action.
+ * Please explain in string (which may have '\n's) what recovery was done.
+ */
+
+#ifdef USE_STDARG
+void
+as_tsktsk (const char *format,...)
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args, format);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ (void) putc ('\n', stderr);
+} /* as_tsktsk() */
+#else
+void
+as_tsktsk (format, va_alist)
+ const char *format;
+ va_dcl
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ (void) putc ('\n', stderr);
+} /* as_tsktsk() */
+#endif /* not NO_STDARG */
+
+/* The common portion of as_warn and as_warn_where. */
+
+static void
+as_warn_internal (file, line, buffer)
+ char *file;
+ unsigned int line;
+ char *buffer;
+{
+ ++warning_count;
+
+ if (file == NULL)
+ as_where (&file, &line);
+
+ identify (file);
+ if (file)
+ fprintf (stderr, "%s:%u: ", file, line);
+ fprintf (stderr, _("Warning: "));
+ fputs (buffer, stderr);
+ (void) putc ('\n', stderr);
+#ifndef NO_LISTING
+ listing_warning (buffer);
+#endif
+}
+
+/*
+ * a s _ w a r n ()
+ *
+ * Send to stderr a string as a warning, and locate warning
+ * in input file(s).
+ * Please only use this for when we have some recovery action.
+ * Please explain in string (which may have '\n's) what recovery was done.
+ */
+
+#ifdef USE_STDARG
+void
+as_warn (const char *format,...)
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal ((char *) NULL, 0, buffer);
+ }
+} /* as_warn() */
+#else
+/*VARARGS1 */
+void
+as_warn (format, va_alist)
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal ((char *) NULL, 0, buffer);
+ }
+} /* as_warn() */
+#endif /* not NO_STDARG */
+
+/* as_warn_where, like as_bad but the file name and line number are
+ passed in. Unfortunately, we have to repeat the function in order
+ to handle the varargs correctly and portably. */
+
+#ifdef USE_STDARG
+void
+as_warn_where (char *file, unsigned int line, const char *format,...)
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal (file, line, buffer);
+ }
+} /* as_warn() */
+#else
+/*VARARGS1 */
+void
+as_warn_where (file, line, format, va_alist)
+ char *file;
+ unsigned int line;
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ if (!flag_no_warnings)
+ {
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+ as_warn_internal (file, line, buffer);
+ }
+} /* as_warn() */
+#endif /* not NO_STDARG */
+
+/* The common portion of as_bad and as_bad_where. */
+
+static void
+as_bad_internal (file, line, buffer)
+ char *file;
+ unsigned int line;
+ char *buffer;
+{
+ ++error_count;
+
+ if (file == NULL)
+ as_where (&file, &line);
+
+ identify (file);
+ if (file)
+ fprintf (stderr, "%s:%u: ", file, line);
+ fprintf (stderr, _("Error: "));
+ fputs (buffer, stderr);
+ (void) putc ('\n', stderr);
+#ifndef NO_LISTING
+ listing_error (buffer);
+#endif
+}
+
+/*
+ * a s _ b a d ()
+ *
+ * Send to stderr a string as a warning, and locate warning in input file(s).
+ * Please us when there is no recovery, but we want to continue processing
+ * but not produce an object file.
+ * Please explain in string (which may have '\n's) what recovery was done.
+ */
+
+#ifdef USE_STDARG
+void
+as_bad (const char *format,...)
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal ((char *) NULL, 0, buffer);
+}
+
+#else
+/*VARARGS1 */
+void
+as_bad (format, va_alist)
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal ((char *) NULL, 0, buffer);
+}
+#endif /* not NO_STDARG */
+
+/* as_bad_where, like as_bad but the file name and line number are
+ passed in. Unfortunately, we have to repeat the function in order
+ to handle the varargs correctly and portably. */
+
+#ifdef USE_STDARG
+void
+as_bad_where (char *file, unsigned int line, const char *format,...)
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args, format);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal (file, line, buffer);
+}
+
+#else
+/*VARARGS1 */
+void
+as_bad_where (file, line, format, va_alist)
+ char *file;
+ unsigned int line;
+ const char *format;
+ va_dcl
+{
+ va_list args;
+ char buffer[2000];
+
+ va_start (args);
+ vsprintf (buffer, format, args);
+ va_end (args);
+
+ as_bad_internal (file, line, buffer);
+}
+#endif /* not NO_STDARG */
+
+/*
+ * a s _ f a t a l ()
+ *
+ * Send to stderr a string as a fatal message, and print location of error in
+ * input file(s).
+ * Please only use this for when we DON'T have some recovery action.
+ * It xexit()s with a warning status.
+ */
+
+#ifdef USE_STDARG
+void
+as_fatal (const char *format,...)
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args, format);
+ fprintf (stderr, _("Fatal error: "));
+ vfprintf (stderr, format, args);
+ (void) putc ('\n', stderr);
+ va_end (args);
+ xexit (EXIT_FAILURE);
+} /* as_fatal() */
+#else
+/*VARARGS1*/
+void
+as_fatal (format, va_alist)
+ char *format;
+ va_dcl
+{
+ va_list args;
+
+ as_show_where ();
+ va_start (args);
+ fprintf (stderr, _("Fatal error: "));
+ vfprintf (stderr, format, args);
+ (void) putc ('\n', stderr);
+ va_end (args);
+ xexit (EXIT_FAILURE);
+} /* as_fatal() */
+#endif /* not NO_STDARG */
+
+/*
+ * as_assert: Indicate assertion failure.
+ * Arguments: Filename, line number, optional function name.
+ */
+
+void
+as_assert (file, line, fn)
+ const char *file, *fn;
+ int line;
+{
+ as_show_where ();
+ fprintf (stderr, _("Internal error!\n"));
+ if (fn)
+ fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
+ fn, file, line);
+ else
+ fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
+ fprintf (stderr, _("Please report this bug.\n"));
+ xexit (EXIT_FAILURE);
+}
+
+/* as_abort: Print a friendly message saying how totally hosed we are,
+ and exit without producing a core file. */
+void
+as_abort (file, line, fn)
+ const char *file, *fn;
+ int line;
+{
+ as_show_where ();
+ if (fn)
+ fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
+ file, line, fn);
+ else
+ fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
+ file, line);
+ fprintf (stderr, _("Please report this bug.\n"));
+ xexit (EXIT_FAILURE);
+}
+
+/* Support routines. */
+
+void
+fprint_value (file, val)
+ FILE *file;
+ valueT val;
+{
+ if (sizeof (val) <= sizeof (long))
+ {
+ fprintf (file, "%ld", (long) val);
+ return;
+ }
+#ifdef BFD_ASSEMBLER
+ if (sizeof (val) <= sizeof (bfd_vma))
+ {
+ fprintf_vma (file, val);
+ return;
+ }
+#endif
+ abort ();
+}
+
+void
+sprint_value (buf, val)
+ char *buf;
+ valueT val;
+{
+ if (sizeof (val) <= sizeof (long))
+ {
+ sprintf (buf, "%ld", (long) val);
+ return;
+ }
+#ifdef BFD_ASSEMBLER
+ if (sizeof (val) <= sizeof (bfd_vma))
+ {
+ sprintf_vma (buf, val);
+ return;
+ }
+#endif
+ abort ();
+}
+
+/* end of messages.c */
diff --git a/gas/mpw-config.in b/gas/mpw-config.in
new file mode 100644
index 00000000000..9e29b1d945c
--- /dev/null
+++ b/gas/mpw-config.in
@@ -0,0 +1,115 @@
+# Configuration fragment for GAS.
+
+Set target_arch `echo {target_canonical} | sed -e 's/-.*-.*//'`
+
+If "{target_arch}" =~ /powerpc/
+ Set short_arch_name "ppc"
+ Set target_cpu "powerpc"
+Else
+ Set short_arch_name "{target_arch}"
+End If
+
+# The following works for many configurations, though not all.
+
+Set obj_format `echo {target_canonical} | sed -e 's/.*-.*-//'`
+Set target_os `echo {target_canonical} | sed -e 's/.*-.*-//'`
+
+Set bfd_gas no
+
+Set TDEFINES ""
+
+Set EXTRA_OBJECTS ""
+
+# Default emulation.
+
+Set em generic
+
+If "{target_canonical}" =~ /m68k-apple-macos/
+ Set obj_format "coff"
+ Set TDEFINES '-d M68KCOFF'
+ Set EXTRA_OBJECTS '"{o}"m68k-parse.c.o'
+
+Else If "{target_canonical}" =~ /powerpc-apple-macos/
+ Set obj_format "coff"
+ Set bfd_gas yes
+ Set em macos
+
+Else If "{target_canonical}" =~ /i386-\Option-x-go32/
+ Set obj_format "coff"
+ Set TDEFINES '-d I386COFF'
+
+Else If "{target_canonical}" =~ /m68k-\Option-x-coff/
+ Set TDEFINES '-d M68KCOFF'
+
+Else If "{target_canonical}" =~ /mips-idt-ecoff/
+ Set bfd_gas yes
+ Set TDEFINES '-d TARGET_BYTES_BIG_ENDIAN=1'
+
+Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/
+ # Assume other OSes etc use ELF
+ Set obj_format "elf"
+ Set bfd_gas yes
+ Set TDEFINES '-d TARGET_BYTES_BIG_ENDIAN=1'
+ forward-include "{srcroot}"bfd:elf-bfd.h 'bfd/elf-bfd.h'
+
+Else If "{target_canonical}" =~ /sh-\Option-x-hms/
+ Set obj_format "coff"
+ forward-include "{srcroot}"opcodes:sh-opc.h 'opcodes/sh-opc.h'
+End If
+
+forward-include "{srcdir}"config:tc-{short_arch_name}.c targ-cpu.c
+forward-include "{srcdir}"config:tc-{short_arch_name}.h targ-cpu.h
+
+forward-include "{srcdir}"config:obj-{obj_format}.c obj-format.c
+forward-include "{srcdir}"config:obj-{obj_format}.h obj-format.h
+
+forward-include "{srcdir}"config:te-{em}.h targ-env.h
+
+# Special cases for float handling.
+
+If "{target_arch}" =~ /ns32k/
+ forward-include "{srcdir}"config:atof-ns32k.c atof-targ.c
+Else If "{target_arch}" =~ /tahoe/
+ forward-include "{srcdir}"config:atof-tahoe.c atof-targ.c
+Else If "{target_arch}" =~ /vax/
+ forward-include "{srcdir}"config:atof-vax.c atof-targ.c
+Else
+ # Use IEEE by default.
+ forward-include "{srcdir}"config:atof-ieee.c atof-targ.c
+End If
+
+Echo '# From mpw-config.in' > "{o}"mk.tmp
+Echo "TDEFINES = " {TDEFINES} >> "{o}"mk.tmp
+Echo "EXTRA_OBJECTS = " {EXTRA_OBJECTS} >> "{o}"mk.tmp
+# (We use the -n option here so as not to get extra spaces inserted)
+Echo -n 'TARG_CPU_DEP = {TARG_CPU_DEP_' >> "{o}"mk.tmp
+Echo -n {short_arch_name} >> "{o}"mk.tmp
+Echo -n '}' >> "{o}"mk.tmp
+Echo '# End from mpw-config.in' >> "{o}"mk.tmp
+
+Echo '/* conf. Generated by mpw-configure. */' > "{o}"conf.new
+Echo -n '#define TARGET_CPU "' >> "{o}"conf.new
+Echo -n "{target_cpu}" >> "{o}"conf.new
+Echo '"' >> "{o}"conf.new
+Echo -n '#define TARGET_OS "' >> "{o}"conf.new
+Echo -n "{target_os}" >> "{o}"conf.new
+Echo '"' >> "{o}"conf.new
+Echo -n '#define TARGET_ALIAS "' >> "{o}"conf.new
+Echo -n "{target_alias}" >> "{o}"conf.new
+Echo '"' >> "{o}"conf.new
+Echo -n '#define TARGET_CANONICAL "' >> "{o}"conf.new
+Echo -n "{target_canonical}" >> "{o}"conf.new
+Echo '"' >> "{o}"conf.new
+Echo '#include "mpw.h"' >> "{o}"conf.new
+If "{bfd_gas}" =~ /yes/
+ Echo "#define BFD_ASSEMBLER" >> "{o}"conf.new
+Else
+ Echo "#define MANY_SEGMENTS" >> "{o}"conf.new
+End If
+Echo '#define CR_EOL' >> "{o}"conf.new
+Echo '#define OBJ_COFF_OMIT_TIMESTAMP' >> "{o}"conf.new
+Echo '#define LOSING_COMPILER' >> "{o}"conf.new
+
+MoveIfChange "{o}"conf.new "{o}"conf
+
+sed -e "s/@srcdir@/{srcdir}/" "{srcdir}"gdbinit.in > "{o}"_gdbinit
diff --git a/gas/mpw-make.sed b/gas/mpw-make.sed
new file mode 100644
index 00000000000..16f12a50550
--- /dev/null
+++ b/gas/mpw-make.sed
@@ -0,0 +1,100 @@
+# Sed commands that finish translating the GAS Unix Makefile to MPW syntax.
+
+/^# @target_frag@/a\
+\
+HDEFINES = \
+LOCAL_LOADLIBES = \
+
+/^srcroot = /s/^/#/
+/^target_alias = /s/^/#/
+
+/INCLUDES/s/-i "{srcdir}":\([a-z]*\)/-i "{topsrcdir}"\1/
+/INCLUDES/s/-i "{srcdir}"\.\./-i "{topsrcdir}"/
+
+/^INCLUDES = .*$/s/$/ -i "{topsrcdir}"include:mpw: -i ::extra-include:/
+
+/$(TARG_CPU_DEP_@target_cpu_type@)/s/$(TARG_CPU_DEP_@target_cpu_type@)/{TARG_CPU_DEP}/
+
+/@OPCODES_LIB@/s/@OPCODES_LIB@/::opcodes:libopcodes.o/
+/@BFDLIB@/s/@BFDLIB@/::bfd:libbfd.o/
+
+# Point at the libraries directly.
+/@OPCODES_DEP@/s/@OPCODES_DEP@/::opcodes:libopcodes.o/
+/@BFDDEP@/s/@BFDDEP@/::bfd:libbfd.o/
+
+# Don't need this.
+/@HLDFLAGS@/s/@HLDFLAGS@//
+
+/extra_objects@/s/extra_objects@/{EXTRA_OBJECTS}/
+
+/LOADLIBES/s/{LOADLIBES}/{EXTRALIBS}/
+
+/@ALL_OBJ_DEPS@/s/@ALL_OBJ_DEPS@/::bfd:bfd.h/
+
+# This causes problems - not sure why.
+/^tags TAGS/,/etags /d
+
+/^make-gas.com/s/^/#/
+
+/true/s/ ; @true$//
+
+# Remove references to conf.in, we don't need them.
+/conf\.in/s/conf\.in//g
+
+# Use _gdbinit everywhere instead of .gdbinit.
+/gdbinit/s/\.gdbinit/_gdbinit/g
+
+/atof-targ/s/"{s}"atof-targ\.c/"{o}"atof-targ.c/g
+/config/s/"{s}"config\.h/"{o}"config.h/g
+/config/s/^config\.h/"{o}"config.h/
+/obj-format/s/"{s}"obj-format\.c/"{o}"obj-format.c/g
+/obj-format/s/"{s}"obj-format\.h/"{o}"obj-format.h/g
+/targ-cpu/s/"{s}"targ-cpu\.c/"{o}"targ-cpu.c/g
+/targ-cpu/s/"{s}"targ-cpu\.h/"{o}"targ-cpu.h/g
+/targ-env/s/"{s}"targ-env\.h/"{o}"targ-env.h/g
+
+/m68k-parse.c/s/"{s}"m68k-parse\.c/"{o}"m68k-parse.c/g
+/m68k-parse.c/s/^m68k-parse\.c/"{o}"m68k-parse.c/
+
+# Whack out the config.h dependency, it only causes excess rebuilds.
+/{OBJS}/s/{OBJS} \\Option-f "{o}"config.h/{OBJS} \\Option-f/
+/gasp.c/s/gasp\.c "{o}"config.h/gasp.c/
+
+# ALL_CFLAGS includes TDEFINES, which is not desirable at link time.
+/CC_LD/s/ALL_CFLAGS/CFLAGS/g
+
+# The resource file is called mac-as.r.
+/as.new.r/s/as\.new\.r/mac-as.r/
+/gasp.new.r/s/gasp\.new\.r/mac-as.r/
+
+# ...and the PROG_NAME doesn't have a .new in it.
+/PROG_NAME/s/PROG_NAME='"'as.new'"'/PROG_NAME='"'as'"'/
+/PROG_NAME/s/PROG_NAME='"'gasp.new'"'/PROG_NAME='"'gasp'"'/
+
+# Whack out recursive makes, they won't work.
+/^[ ][ ]*srcroot=/,/^[ ][ ]*(cd /d
+
+# Work around quoting problems by using multiple echo commands.
+/'#define GAS_VERSION "{VERSION}"'/c\
+ Echo -n '#define GAS_VERSION "' >> "{o}"config.new\
+ Echo -n "{VERSION}" >> "{o}"config.new\
+ Echo -n '"' >> "{o}"config.new
+
+# Add a "stamps" target.
+$a\
+stamps \\Option-f config-stamp\
+
+/^install \\Option-f/,/^$/c\
+install \\Option-f all install-only\
+\
+install-only \\Option-f\
+ NewFolderRecursive "{bindir}"\
+ Duplicate -y :as.new "{bindir}"as\
+ Duplicate -y :gasp.new "{bindir}"gasp\
+
+
+# Whack out config-rebuilding targets, they won't work.
+/^Makefile \\Option-f/,/^$/d
+/^config.status \\Option-f/,/^$/d
+
+/^"{o}"config.h \\Option-f/s/^/#/
diff --git a/gas/obj.h b/gas/obj.h
new file mode 100644
index 00000000000..b95e75c96e9
--- /dev/null
+++ b/gas/obj.h
@@ -0,0 +1,81 @@
+/* obj.h - defines the object dependent hooks for all object
+ format backends.
+
+ Copyright (C) 1987, 90, 91, 92, 93, 95, 96, 97, 1999
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+char *obj_default_output_file_name PARAMS ((void));
+void obj_emit_relocations PARAMS ((char **where, fixS * fixP,
+ relax_addressT segment_address_in_file));
+void obj_emit_strings PARAMS ((char **where));
+void obj_emit_symbols PARAMS ((char **where, symbolS * symbols));
+#ifndef obj_read_begin_hook
+void obj_read_begin_hook PARAMS ((void));
+#endif
+#ifndef BFD_ASSEMBLER
+void obj_crawl_symbol_chain PARAMS ((object_headers * headers));
+void obj_header_append PARAMS ((char **where, object_headers * headers));
+#ifndef obj_pre_write_hook
+void obj_pre_write_hook PARAMS ((object_headers * headers));
+#endif
+#endif
+
+#ifndef obj_symbol_new_hook
+void obj_symbol_new_hook PARAMS ((symbolS * symbolP));
+#endif
+
+void obj_symbol_to_chars PARAMS ((char **where, symbolS * symbolP));
+
+extern const pseudo_typeS obj_pseudo_table[];
+
+#ifdef BFD_ASSEMBLER
+struct format_ops {
+ int flavor;
+ unsigned dfl_leading_underscore : 1;
+ unsigned emit_section_symbols : 1;
+ void (*frob_symbol) PARAMS ((symbolS *, int *));
+ void (*frob_file) PARAMS ((void));
+ void (*frob_file_after_relocs) PARAMS ((void));
+ bfd_vma (*s_get_size) PARAMS ((symbolS *));
+ void (*s_set_size) PARAMS ((symbolS *, bfd_vma));
+ bfd_vma (*s_get_align) PARAMS ((symbolS *));
+ void (*s_set_align) PARAMS ((symbolS *, bfd_vma));
+ void (*copy_symbol_attributes) PARAMS ((symbolS *, symbolS *));
+ void (*generate_asm_lineno) PARAMS ((void));
+ void (*process_stab) PARAMS ((segT, int, const char *, int, int, int));
+ int (*sec_sym_ok_for_reloc) PARAMS ((asection *));
+ void (*pop_insert) PARAMS ((void));
+ /* For configurations using ECOFF_DEBUGGING, this callback is used. */
+ void (*ecoff_set_ext) PARAMS ((symbolS *, struct ecoff_extr *));
+
+ void (*read_begin_hook) PARAMS ((void));
+ void (*symbol_new_hook) PARAMS ((symbolS *));
+};
+
+extern const struct format_ops elf_format_ops;
+extern const struct format_ops ecoff_format_ops;
+extern const struct format_ops coff_format_ops;
+
+#ifndef this_format
+COMMON const struct format_ops *this_format;
+#endif
+#endif
+
+/* end of obj.h */
diff --git a/gas/output-file.c b/gas/output-file.c
new file mode 100644
index 00000000000..b05af48a53d
--- /dev/null
+++ b/gas/output-file.c
@@ -0,0 +1,156 @@
+/* output-file.c - Deal with the output file
+ Copyright (C) 1987, 90, 91, 93, 92, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+
+#include "as.h"
+
+#include "output-file.h"
+
+#ifdef BFD_HEADERS
+#define USE_BFD
+#endif
+
+#ifdef BFD_ASSEMBLER
+#define USE_BFD
+#ifndef TARGET_MACH
+#define TARGET_MACH 0
+#endif
+#endif
+
+#ifdef USE_BFD
+#include "bfd.h"
+bfd *stdoutput;
+
+void
+output_file_create (name)
+ char *name;
+{
+ if (name[0] == '-' && name[1] == '\0')
+ {
+ as_fatal (_("Can't open a bfd on stdout %s "), name);
+ }
+ else if (!(stdoutput = bfd_openw (name, TARGET_FORMAT)))
+ {
+ as_perror (_("FATAL: Can't create %s"), name);
+ exit (EXIT_FAILURE);
+ }
+ bfd_set_format (stdoutput, bfd_object);
+#ifdef BFD_ASSEMBLER
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, TARGET_MACH);
+#endif
+ if (flag_traditional_format)
+ stdoutput->flags |= BFD_TRADITIONAL_FORMAT;
+}
+
+void
+output_file_close (filename)
+ char *filename;
+{
+#ifdef BFD_ASSEMBLER
+ /* Close the bfd. */
+ if (bfd_close (stdoutput) == 0)
+ {
+ bfd_perror (filename);
+ as_perror (_("FATAL: Can't close %s\n"), filename);
+ exit (EXIT_FAILURE);
+ }
+#else
+ /* Close the bfd without getting bfd to write out anything by itself */
+ if (bfd_close_all_done (stdoutput) == 0)
+ {
+ as_perror (_("FATAL: Can't close %s\n"), filename);
+ exit (EXIT_FAILURE);
+ }
+#endif
+ stdoutput = NULL; /* Trust nobody! */
+}
+
+#ifndef BFD_ASSEMBLER
+void
+output_file_append (where, length, filename)
+ char *where;
+ long length;
+ char *filename;
+{
+ abort ();
+}
+#endif
+
+#else
+
+static FILE *stdoutput;
+
+void
+output_file_create (name)
+ char *name;
+{
+ if (name[0] == '-' && name[1] == '\0')
+ {
+ stdoutput = stdout;
+ return;
+ }
+
+ stdoutput = fopen (name, "wb");
+
+ /* Some systems don't grok "b" in fopen modes. */
+ if (stdoutput == NULL)
+ stdoutput = fopen (name, "w");
+
+ if (stdoutput == NULL)
+ {
+ as_perror (_("FATAL: Can't create %s"), name);
+ exit (EXIT_FAILURE);
+ }
+}
+
+void
+output_file_close (filename)
+ char *filename;
+{
+ if (EOF == fclose (stdoutput))
+ {
+ as_perror (_("FATAL: Can't close %s"), filename);
+ exit (EXIT_FAILURE);
+ }
+ stdoutput = NULL; /* Trust nobody! */
+}
+
+void
+output_file_append (where, length, filename)
+ char *where;
+ long length;
+ char *filename;
+{
+ for (; length; length--, where++)
+ {
+ (void) putc (*where, stdoutput);
+ if (ferror (stdoutput))
+ /* if ( EOF == (putc( *where, stdoutput )) ) */
+ {
+ as_perror (_("Failed to emit an object byte"), filename);
+ as_fatal (_("Can't continue"));
+ }
+ }
+}
+
+#endif
+
+/* end of output-file.c */
diff --git a/gas/output-file.h b/gas/output-file.h
new file mode 100644
index 00000000000..942f1efe3eb
--- /dev/null
+++ b/gas/output-file.h
@@ -0,0 +1,25 @@
+/* This file is output-file.h
+
+ Copyright (C) 1987-1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+void output_file_append PARAMS ((char *where, long length, char *filename));
+void output_file_close PARAMS ((char *filename));
+void output_file_create PARAMS ((char *name));
+
+/* end of output-file.h */
diff --git a/gas/po/Make-in b/gas/po/Make-in
new file mode 100644
index 00000000000..0552db1feef
--- /dev/null
+++ b/gas/po/Make-in
@@ -0,0 +1,251 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gas/po/POTFILES.in b/gas/po/POTFILES.in
new file mode 100644
index 00000000000..0023b7ad945
--- /dev/null
+++ b/gas/po/POTFILES.in
@@ -0,0 +1,193 @@
+config/tc-hppa.c
+config/tc-m32r.c
+config/aout_gnu.h
+config/atof-ieee.c
+config/atof-tahoe.c
+config/atof-vax.c
+config/e-i386coff.c
+config/e-i386elf.c
+config/e-mipsecoff.c
+config/e-mipself.c
+config/itbl-mips.h
+config/m68k-parse.h
+config/m88k-opcode.h
+config/obj-aout.c
+config/obj-aout.h
+config/obj-bout.c
+config/obj-bout.h
+config/obj-coff.c
+config/obj-coff.h
+config/obj-ecoff.c
+config/obj-ecoff.h
+config/obj-elf.c
+config/obj-elf.h
+config/obj-evax.c
+config/obj-evax.h
+config/obj-generic.c
+config/obj-generic.h
+config/obj-hp300.c
+config/obj-hp300.h
+config/obj-ieee.c
+config/obj-ieee.h
+config/obj-multi.c
+config/obj-multi.h
+config/obj-som.c
+config/obj-som.h
+config/obj-vms.c
+config/obj-vms.h
+config/tc-a29k.c
+config/tc-a29k.h
+config/tc-alpha.c
+config/tc-alpha.h
+config/tc-arc.c
+config/tc-arc.h
+config/tc-arm.c
+config/tc-arm.h
+config/tc-d10v.c
+config/tc-d10v.h
+config/tc-d30v.c
+config/tc-d30v.h
+config/tc-mcore.c
+config/tc-fr30.c
+config/tc-fr30.h
+config/tc-generic.c
+config/tc-generic.h
+config/tc-h8300.c
+config/tc-h8300.h
+config/tc-h8500.c
+config/tc-h8500.h
+config/tc-mips.c
+config/tc-hppa.h
+config/tc-i386.c
+config/tc-i386.h
+config/tc-i860.c
+config/tc-i860.h
+config/tc-i960.c
+config/tc-i960.h
+config/tc-mn10300.c
+config/tc-m32r.h
+config/tc-m68851.h
+config/tc-m68k.c
+config/tc-m68k.h
+config/tc-m88k.c
+config/tc-m88k.h
+config/tc-mcore.h
+config/tc-mips.h
+config/tc-mn10200.c
+config/tc-mn10200.h
+config/tc-mn10300.h
+config/tc-ns32k.c
+config/tc-ns32k.h
+config/tc-ppc.c
+config/tc-ppc.h
+config/tc-sh.c
+config/tc-sh.h
+config/tc-sparc.c
+config/tc-sparc.h
+config/tc-tahoe.c
+config/tc-tahoe.h
+config/tc-tic30.c
+config/tc-tic30.h
+config/tc-tic80.c
+config/tc-tic80.h
+config/tc-v850.c
+config/tc-v850.h
+config/tc-vax.c
+config/tc-vax.h
+config/tc-w65.c
+config/tc-w65.h
+config/tc-z8k.c
+config/tc-z8k.h
+config/te-386bsd.h
+config/te-aux.h
+config/te-delt88.h
+config/te-delta.h
+config/te-dpx2.h
+config/te-dynix.h
+config/te-epoc-pe.h
+config/te-generic.h
+config/te-go32.h
+config/te-hp300.h
+config/te-hppa.h
+config/te-i386aix.h
+config/te-ic960.h
+config/te-linux.h
+config/te-lnews.h
+config/te-lynx.h
+config/te-mach.h
+config/te-macos.h
+config/te-multi.h
+config/te-nbsd.h
+config/te-nbsd532.h
+config/te-pc532mach.h
+config/te-pe.h
+config/te-ppcnw.h
+config/te-psos.h
+config/te-riscix.h
+config/te-sparcaout.h
+config/te-sun3.h
+config/te-svr4.h
+config/te-sysv32.h
+config/vax-inst.h
+config/vms-a-conf.h
+config/vms-conf.h
+app.c
+as.c
+as.h
+asintl.h
+atof-generic.c
+bignum-copy.c
+bignum.h
+bit_fix.h
+cgen.c
+cgen.h
+cond.c
+debug.c
+depend.c
+ecoff.c
+ecoff.h
+ehopt.c
+emul-target.h
+emul.h
+expr.c
+expr.h
+flonum-copy.c
+flonum-konst.c
+flonum-mult.c
+flonum.h
+frags.c
+frags.h
+gasp.c
+hash.c
+hash.h
+input-file.c
+input-file.h
+input-scrub.c
+itbl-ops.c
+itbl-ops.h
+listing.c
+listing.h
+literal.c
+macro.c
+macro.h
+messages.c
+obj.h
+output-file.c
+output-file.h
+read.c
+read.h
+sb.c
+sb.h
+stabs.c
+struc-symbol.h
+subsegs.c
+subsegs.h
+symbols.c
+symbols.h
+tc.h
+write.c
+write.h
+testsuite/gas/all/itbl-test.c
+testsuite/gas/mips/elf_e_flags.c
+testsuite/gas/tic80/relocs1.c
+testsuite/gas/tic80/relocs2.c
diff --git a/gas/po/gas.pot b/gas/po/gas.pot
new file mode 100644
index 00000000000..cd9abba5189
--- /dev/null
+++ b/gas/po/gas.pot
@@ -0,0 +1,3853 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1999-04-18 18:31-0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: app.c:435 app.c:449
+msgid "end of file in comment"
+msgstr ""
+
+#: app.c:528
+msgid "end of file in string: inserted '\"'"
+msgstr ""
+
+#: app.c:594
+#, c-format
+msgid "Unknown escape '\\%c' in string: Ignored"
+msgstr ""
+
+#: app.c:603
+msgid "End of file in string: '\"' inserted"
+msgstr ""
+
+#: app.c:723
+msgid "end of file not at end of a line; newline inserted"
+msgstr ""
+
+#: app.c:869
+msgid "end of file in multiline comment"
+msgstr ""
+
+#: app.c:918
+msgid "end of file after a one-character quote; \\0 inserted"
+msgstr ""
+
+#: app.c:926
+msgid "end of file in escape character"
+msgstr ""
+
+#: app.c:938
+msgid "Missing close quote: (assumed)"
+msgstr ""
+
+#: app.c:997 app.c:1051 app.c:1120
+msgid "end of file in comment; newline inserted"
+msgstr ""
+
+#: app.c:1061
+msgid "EOF in Comment: Newline inserted"
+msgstr ""
+
+#: as.c:121
+#, c-format
+msgid "GNU assembler version %s (%s) using BFD version %s"
+msgstr ""
+
+#: as.c:124
+#, c-format
+msgid "GNU assembler version %s (%s)"
+msgstr ""
+
+#: as.c:133
+#, c-format
+msgid "Usage: %s [option...] [asmfile...]\n"
+msgstr ""
+
+#: as.c:135
+msgid ""
+"Options:\n"
+" -a[sub-option...]\tturn on listings\n"
+" Sub-options [default hls]:\n"
+" c omit false conditionals\n"
+" d omit debugging directives\n"
+" h include high-level source\n"
+" l include assembly\n"
+" m include macro expansions\n"
+" n omit forms processing\n"
+" s include symbols\n"
+" =file set listing file name (must be last sub-option)\n"
+msgstr ""
+
+#: as.c:148
+msgid ""
+" -D\t\t produce assembler debugging messages\n"
+" --defsym SYM=VAL define symbol SYM to given value\n"
+" -f\t\t skip whitespace and comment preprocessing\n"
+" --gstabs\t generate stabs debugging information\n"
+" --help\t\t show this message and exit\n"
+" -I DIR\t\t add DIR to search list for .include directives\n"
+" -J\t\t don't warn about signed overflow\n"
+" -K\t\t warn when differences altered for long displacements\n"
+" -L,--keep-locals keep local symbols (e.g. starting with `L')\n"
+msgstr ""
+
+#: as.c:159
+msgid ""
+" -M,--mri\t assemble in MRI compatibility mode\n"
+" --MD FILE\t write dependency information in FILE (default none)\n"
+" -nocpp\t\t ignored\n"
+" -o OBJFILE\t name the object-file output OBJFILE (default a.out)\n"
+" -R\t\t fold data section into text section\n"
+" --statistics\t print various measured statistics from execution\n"
+" --strip-local-absolute strip local absolute symbols\n"
+" --traditional-format\t Use same format as native assembler when possible\n"
+" --version\t\t print assembler version number and exit\n"
+" -W\t\t\t suppress warnings\n"
+" --itbl INSTTBL\t extend instruction set to include instructions\n"
+"\t\t\t matching the specifications defined in file INSTTBL\n"
+" -w\t\t\t ignored\n"
+" -X\t\t\t ignored\n"
+" -Z\t\t\t generate object file even after errors\n"
+msgstr ""
+
+#: as.c:176
+msgid ""
+" --listing-lhs-width\t set the width in words of the output data column "
+"of\n"
+"\t\t\t the listing\n"
+" --listing-lhs-width2\t set the width in words of the continuation lines\n"
+"\t\t\t of the output data column; ignored if smaller than\n"
+"\t\t\t the width of the first line\n"
+" --listing-rhs-width\t set the max width in characters of the lines from\n"
+"\t\t\t the source file\n"
+" --listing-cont-lines\t set the maximum number of continuation lines used\n"
+"\t\t\t for the output data column of the listing\n"
+msgstr ""
+
+#: as.c:189 gasp.c:3583
+msgid ""
+"\n"
+"Report bugs to bug-gnu-utils@gnu.org\n"
+msgstr ""
+
+#: as.c:226
+msgid "missing emulation mode name"
+msgstr ""
+
+#: as.c:241
+#, c-format
+msgid "unrecognized emulation name `%s'"
+msgstr ""
+
+#. This output is intended to follow the GNU standards document.
+#: as.c:459
+#, c-format
+msgid "GNU assembler %s\n"
+msgstr ""
+
+#: as.c:460
+msgid "Copyright 1997 Free Software Foundation, Inc.\n"
+msgstr ""
+
+#: as.c:461 gasp.c:3677
+msgid ""
+"This program is free software; you may redistribute it under the terms of\n"
+"the GNU General Public License. This program has absolutely no warranty.\n"
+msgstr ""
+
+#: as.c:464
+#, c-format
+msgid "This assembler was configured for a target of `%s'.\n"
+msgstr ""
+
+#: as.c:471
+msgid "multiple emulation names specified"
+msgstr ""
+
+#: as.c:473
+msgid "emulations not handled in this configuration"
+msgstr ""
+
+#: as.c:478
+#, c-format
+msgid "alias = %s\n"
+msgstr ""
+
+#: as.c:479
+#, c-format
+msgid "canonical = %s\n"
+msgstr ""
+
+#: as.c:480
+#, c-format
+msgid "cpu-type = %s\n"
+msgstr ""
+
+#: as.c:482
+#, c-format
+msgid "format = %s\n"
+msgstr ""
+
+#: as.c:485
+#, c-format
+msgid "bfd-target = %s\n"
+msgstr ""
+
+#: as.c:498
+msgid "bad defsym; format is --defsym name=value"
+msgstr ""
+
+#: as.c:518
+msgid "No file name following -t option\n"
+msgstr ""
+
+#: as.c:534
+#, c-format
+msgid "Failed to read instruction table %s\n"
+msgstr ""
+
+#: as.c:634
+#, c-format
+msgid "invalid listing option `%c'"
+msgstr ""
+
+#: as.c:856
+#, c-format
+msgid "%s: total time in assembly: %ld.%06ld\n"
+msgstr ""
+
+#: as.c:859
+#, c-format
+msgid "%s: data size %ld\n"
+msgstr ""
+
+#.
+#. * We have a GROSS internal error.
+#. * This should never happen.
+#.
+#: atof-generic.c:438 config/tc-a29k.c:544 config/tc-i860.c:335
+#: config/tc-i860.c:708 config/tc-m68k.c:3045 config/tc-m68k.c:3074
+#: config/tc-sparc.c:2157
+msgid "failed sanity check."
+msgstr ""
+
+#: cond.c:75
+msgid "invalid identifier for \".ifdef\""
+msgstr ""
+
+#: cond.c:128
+msgid "non-constant expression in \".if\" statement"
+msgstr ""
+
+#: cond.c:224
+msgid "bad format for ifc or ifnc"
+msgstr ""
+
+#: cond.c:257
+msgid "\".endif\" without \".if\""
+msgstr ""
+
+#: cond.c:287
+msgid ".else without matching .if - ignored"
+msgstr ""
+
+#: cond.c:292
+msgid "duplicate \"else\" - ignored"
+msgstr ""
+
+#: cond.c:295
+msgid "here is the previous \"else\""
+msgstr ""
+
+#: cond.c:298
+msgid "here is the previous \"if\""
+msgstr ""
+
+#: cond.c:343
+msgid ".ifeqs syntax error"
+msgstr ""
+
+#: cond.c:430
+msgid "end of macro inside conditional"
+msgstr ""
+
+#: cond.c:432
+msgid "end of file inside conditional"
+msgstr ""
+
+#: cond.c:435
+msgid "here is the start of the unterminated conditional"
+msgstr ""
+
+#: cond.c:439
+msgid "here is the \"else\" of the unterminated conditional"
+msgstr ""
+
+#: config/obj-aout.c:157
+#, c-format
+msgid "Attempt to put a common symbol into set %s"
+msgstr ""
+
+#: config/obj-aout.c:161
+#, c-format
+msgid "Attempt to put an undefined symbol into set %s"
+msgstr ""
+
+#: config/obj-aout.c:192 config/obj-elf.c:1527 ecoff.c:3663
+#, c-format
+msgid "Symbol `%s' can not be both weak and common"
+msgstr ""
+
+#: config/obj-aout.c:250 config/obj-coff.c:1766
+msgid "unresolved relocation"
+msgstr ""
+
+#: config/obj-aout.c:252 config/obj-coff.c:1768
+#, c-format
+msgid "bad relocation: symbol `%s' not in symbol table"
+msgstr ""
+
+#: config/obj-aout.c:339
+#, c-format
+msgid "%s: bad type for weak symbol"
+msgstr ""
+
+#: config/obj-aout.c:453 config/obj-coff.c:2700 write.c:1796
+#, c-format
+msgid "%s: global symbols not supported in common sections"
+msgstr ""
+
+#: config/obj-aout.c:520
+#, c-format
+msgid "Local symbol %s never defined."
+msgstr ""
+
+#: config/obj-aout.c:608
+msgid "subsegment index too high"
+msgstr ""
+
+#: config/obj-bout.c:312 config/obj-vms.c:566
+#, c-format
+msgid "Local symbol %s never defined"
+msgstr ""
+
+#: config/obj-coff.c:133
+#, c-format
+msgid "Inserting \"%s\" into structure table failed: %s"
+msgstr ""
+
+#: config/obj-coff.c:452 config/obj-coff.c:2113
+msgid ".ln pseudo-op inside .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:512 config/obj-coff.c:2170
+msgid ".def pseudo-op used inside of .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:558 config/obj-coff.c:2223
+msgid ".endef pseudo-op used outside of .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:592
+#, c-format
+msgid "`%s' symbol without preceding function"
+msgstr ""
+
+#: config/obj-coff.c:634 config/obj-coff.c:2298
+#, c-format
+msgid "unexpected storage class %d"
+msgstr ""
+
+#: config/obj-coff.c:736 config/obj-coff.c:2405
+msgid ".dim pseudo-op used outside of .def/.endef: ignored."
+msgstr ""
+
+#: config/obj-coff.c:756 config/obj-coff.c:2425
+msgid "badly formed .dim directive ignored"
+msgstr ""
+
+#: config/obj-coff.c:807 config/obj-coff.c:2488
+msgid ".size pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:823 config/obj-coff.c:2504
+msgid ".scl pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:841 config/obj-coff.c:2522
+msgid ".tag pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:860 config/obj-coff.c:2540
+#, c-format
+msgid "tag not found for .tag %s"
+msgstr ""
+
+#: config/obj-coff.c:875 config/obj-coff.c:2555
+msgid ".type pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:897 config/obj-coff.c:2577
+msgid ".val pseudo-op used outside of .def/.endef ignored."
+msgstr ""
+
+#: config/obj-coff.c:1026 config/obj-coff.c:2773
+msgid "mismatched .eb"
+msgstr ""
+
+#: config/obj-coff.c:1044 config/obj-coff.c:2813
+msgid "C_EFCN symbol out of scope"
+msgstr ""
+
+#. STYP_INFO
+#. STYP_LIB
+#. STYP_OVER
+#: config/obj-coff.c:1253
+#, c-format
+msgid "unsupported section attribute '%c'"
+msgstr ""
+
+#: config/obj-coff.c:1258 config/obj-coff.c:3516 config/tc-ppc.c:3778
+#, c-format
+msgid "unknown section attribute '%c'"
+msgstr ""
+
+#: config/obj-coff.c:1280 config/tc-ppc.c:3796 read.c:2478
+#, c-format
+msgid "error setting flags for \"%s\": %s"
+msgstr ""
+
+#: config/obj-coff.c:1399
+#, c-format
+msgid "0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"
+msgstr ""
+
+#: config/obj-coff.c:1593 config/obj-ieee.c:69
+msgid "Out of step\n"
+msgstr ""
+
+#: config/obj-coff.c:2028
+msgid "bfd_coff_swap_scnhdr_out failed"
+msgstr ""
+
+#: config/obj-coff.c:2255
+msgid "`.bf' symbol without preceding function\n"
+msgstr ""
+
+#: config/obj-coff.c:3216 config/obj-ieee.c:522 output-file.c:52
+#: output-file.c:119
+#, c-format
+msgid "FATAL: Can't create %s"
+msgstr ""
+
+#: config/obj-coff.c:3390
+#, c-format
+msgid "Can't close %s: %s"
+msgstr ""
+
+#: config/obj-coff.c:3424
+#, c-format
+msgid "Too many new sections; can't add \"%s\""
+msgstr ""
+
+#: config/obj-coff.c:3834 config/tc-m88k.c:1260 config/tc-sparc.c:3015
+msgid "Expected comma after name"
+msgstr ""
+
+#: config/obj-coff.c:3840 read.c:1934
+msgid "Missing size expression"
+msgstr ""
+
+#: config/obj-coff.c:3846
+#, c-format
+msgid "lcomm length (%d.) <0! Ignored."
+msgstr ""
+
+#: config/obj-coff.c:3874 read.c:2160
+#, c-format
+msgid "Symbol %s already defined"
+msgstr ""
+
+#: config/obj-coff.c:3968 config/tc-i960.c:3201
+#, c-format
+msgid "No 'bal' entry point for leafproc %s"
+msgstr ""
+
+#: config/obj-coff.c:4047 write.c:2501
+#, c-format
+msgid "Negative of non-absolute symbol %s"
+msgstr ""
+
+#: config/obj-coff.c:4068 write.c:2515
+msgid "callj to difference of 2 symbols"
+msgstr ""
+
+#: config/obj-coff.c:4114
+#, c-format
+msgid "Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %ld."
+msgstr ""
+
+#. This is a COBR instruction. They have only a 13-bit
+#. displacement and are only to be used for local branches:
+#. flag as error, don't generate relocation.
+#: config/obj-coff.c:4204 config/tc-i960.c:3221 write.c:2659
+msgid "can't use COBR format with external label"
+msgstr ""
+
+#: config/obj-coff.c:4278
+#, c-format
+msgid "Value of %ld too large for field of %d bytes at 0x%lx"
+msgstr ""
+
+#: config/obj-coff.c:4292 write.c:2747
+#, c-format
+msgid "Signed .word overflow; switch may be too large; %ld at 0x%lx"
+msgstr ""
+
+#: config/obj-ecoff.c:239
+msgid "Can't set GP value"
+msgstr ""
+
+#: config/obj-ecoff.c:246
+msgid "Can't set register masks"
+msgstr ""
+
+#: config/obj-elf.c:274 config/tc-sparc.c:3156 config/tc-v850.c:263
+msgid "Expected comma after symbol-name"
+msgstr ""
+
+#: config/obj-elf.c:281 config/tc-arc.c:778 config/tc-sparc.c:3163
+#, c-format
+msgid ".COMMon length (%d.) <0! Ignored."
+msgstr ""
+
+#: config/obj-elf.c:291 config/tc-alpha.c:3429 config/tc-sparc.c:3173
+#: config/tc-v850.c:285
+msgid "Ignoring attempt to re-define symbol"
+msgstr ""
+
+#: config/obj-elf.c:299 config/tc-arc.c:796 config/tc-sparc.c:3181
+#: config/tc-v850.c:295
+#, c-format
+msgid "Length of .comm \"%s\" is already %ld. Not changed to %d."
+msgstr ""
+
+#: config/obj-elf.c:322 config/tc-arc.c:815 config/tc-v850.c:322
+msgid "Common alignment negative; 0 assumed"
+msgstr ""
+
+#: config/obj-elf.c:341 config/tc-m32r.c:1298 config/tc-ppc.c:1389
+#: config/tc-v850.c:385
+msgid "Common alignment not a power of 2"
+msgstr ""
+
+#: config/obj-elf.c:404 config/tc-arc.c:875 config/tc-sparc.c:3305
+#: config/tc-v850.c:563
+#, c-format
+msgid "bad .common segment %s"
+msgstr ""
+
+#: config/obj-elf.c:589
+msgid "Missing section name"
+msgstr ""
+
+#: config/obj-elf.c:654
+msgid "Bad .section directive: want a,w,x in string"
+msgstr ""
+
+#: config/obj-elf.c:703
+msgid "Unrecognized section type"
+msgstr ""
+
+#: config/obj-elf.c:717
+msgid "Bad .section directive - character following name is not '#'"
+msgstr ""
+
+#: config/obj-elf.c:749
+msgid "Unrecognized section attribute"
+msgstr ""
+
+#: config/obj-elf.c:770
+#, c-format
+msgid "Setting incorrect section type for %s"
+msgstr ""
+
+#: config/obj-elf.c:780
+#, c-format
+msgid "Setting incorrect section attributes for %s"
+msgstr ""
+
+#: config/obj-elf.c:905
+msgid ".previous without corresponding .section; ignored"
+msgstr ""
+
+#: config/obj-elf.c:954
+#, c-format
+msgid "multiple .symver directives for symbol `%s'"
+msgstr ""
+
+#: config/obj-elf.c:963
+msgid "expected comma after name in .symver"
+msgstr ""
+
+#: config/obj-elf.c:984
+#, c-format
+msgid "missing version name in `%s' for symbol `%s'"
+msgstr ""
+
+#: config/obj-elf.c:1187 config/obj-som.c:148 config/obj-som.c:193
+msgid "Expected quoted string"
+msgstr ""
+
+#: config/obj-elf.c:1208
+#, c-format
+msgid "expected comma after name `%s' in .size directive"
+msgstr ""
+
+#: config/obj-elf.c:1217
+msgid "missing expression in .size directive"
+msgstr ""
+
+#: config/obj-elf.c:1283
+#, c-format
+msgid "ignoring unrecognized symbol type \"%s\""
+msgstr ""
+
+#: config/obj-elf.c:1453
+msgid ".size expression too complicated to fix up"
+msgstr ""
+
+#: config/obj-elf.c:1484
+#, c-format
+msgid ""
+"invalid attempt to declare external version name as default in symbol `%s'"
+msgstr ""
+
+#: config/obj-elf.c:1610
+#, c-format
+msgid "Failed to set up debugging information: %s"
+msgstr ""
+
+#: config/obj-elf.c:1626
+#, c-format
+msgid "Can't start writing .mdebug section: %s"
+msgstr ""
+
+#: config/obj-elf.c:1634
+#, c-format
+msgid "Could not write .mdebug section: %s"
+msgstr ""
+
+#: config/obj-ieee.c:460
+msgid "too many sections"
+msgstr ""
+
+#: config/obj-som.c:131
+msgid "Only one .version pseudo-op per file!"
+msgstr ""
+
+#: config/obj-som.c:157
+#, c-format
+msgid "FATAL: Attaching version header %s"
+msgstr ""
+
+#: config/obj-som.c:176
+msgid "Only one .copyright pseudo-op per file!"
+msgstr ""
+
+#: config/obj-som.c:202
+#, c-format
+msgid "FATAL: Attaching copyright header %s"
+msgstr ""
+
+#: config/obj-vms.c:464
+#, c-format
+msgid "compiler emitted zero-size common symbol `%s' already defined"
+msgstr ""
+
+#: config/obj-vms.c:474
+#, c-format
+msgid "compiler redefined zero-size common symbol `%s'"
+msgstr ""
+
+#: config/obj-vms.c:597
+#, c-format
+msgid "Couldn't create VMS object file \"%s\""
+msgstr ""
+
+#: config/obj-vms.c:623
+msgid "I/O error writing VMS object file (length prefix)"
+msgstr ""
+
+#: config/obj-vms.c:637
+msgid "I/O error writing VMS object file"
+msgstr ""
+
+#: config/obj-vms.c:1240
+msgid "Couldn't find source file \"%s\", status=%%X%x"
+msgstr ""
+
+#: config/obj-vms.c:1749 config/obj-vms.c:2937
+#, c-format
+msgid "debugger forward reference error, dbx type %d"
+msgstr ""
+
+#: config/obj-vms.c:1825
+#, c-format
+msgid "Variable descriptor %d too complicated. Defined as `void *'."
+msgstr ""
+
+#: config/obj-vms.c:2144
+msgid ""
+"***Warning - the assembly code generated by the compiler has placed \n"
+" global constant(s) in the text psect. These will not be available to \n"
+" other modules, since this is not the correct way to handle this. You \n"
+" have two options: 1) get a patched compiler that does not put global \n"
+" constants in the text psect, or 2) remove the 'const' keyword from \n"
+" definitions of global variables in your source module(s). Don't say \n"
+" I didn't warn you! \n"
+msgstr ""
+
+#: config/obj-vms.c:2463
+#, c-format
+msgid "debugginer output: %d is an unknown untyped variable."
+msgstr ""
+
+#: config/obj-vms.c:2681
+#, c-format
+msgid "debugger output: structure element `%s' has undefined type"
+msgstr ""
+
+#: config/obj-vms.c:2792
+#, c-format
+msgid "debugger output: %d is an unknown type of variable."
+msgstr ""
+
+#: config/obj-vms.c:2926
+#, c-format
+msgid "debugger output: Unable to resolve %d circular references."
+msgstr ""
+
+#: config/obj-vms.c:3131
+#, c-format
+msgid "Module name truncated: %s\n"
+msgstr ""
+
+#: config/obj-vms.c:3410
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr ""
+
+#. impossible
+#: config/obj-vms.c:3694
+#, c-format
+msgid "Unknown VMS psect type (%ld)"
+msgstr ""
+
+#: config/obj-vms.c:3735
+#, c-format
+msgid "Globalsymbol attribute for symbol %s was unexpected."
+msgstr ""
+
+#: config/obj-vms.c:3885
+msgid "Invalid data type for globalvalue"
+msgstr ""
+
+#: config/obj-vms.c:3897
+#, c-format
+msgid "Invalid globalvalue of %s"
+msgstr ""
+
+#: config/obj-vms.c:4247
+msgid "Couldn't find fixup fragment when checking for indirect reference"
+msgstr ""
+
+#: config/obj-vms.c:4591 config/obj-vms.c:4733
+msgid "Fixup data addsy and subsy don't have the same type"
+msgstr ""
+
+#: config/obj-vms.c:4595 config/obj-vms.c:4737
+msgid "Fixup data addsy and subsy don't have an appropriate type"
+msgstr ""
+
+#: config/obj-vms.c:4598 config/obj-vms.c:4740
+msgid "Fixup data is erroneously \"pcrel\""
+msgstr ""
+
+#: config/obj-vms.c:4614 config/obj-vms.c:4759
+msgid "Fixup datum is not a longword"
+msgstr ""
+
+#: config/obj-vms.c:4618 config/obj-vms.c:4763
+msgid "Fixup datum is not \"fixP->fx_addsy\""
+msgstr ""
+
+#: config/obj-vms.c:4834
+#, c-format
+msgid ""
+"g++ wrote an extern reference to `%s' as a routine.\n"
+"I will fix it, but I hope that it was note really a routine."
+msgstr ""
+
+#: config/obj-vms.c:4966
+msgid "Can't handle global xtors symbols yet."
+msgstr ""
+
+#: config/obj-vms.c:4969
+#, c-format
+msgid "Unknown %s"
+msgstr ""
+
+#.
+#. * Error otherwise.
+#.
+#: config/obj-vms.c:5054
+#, c-format
+msgid "unhandled stab type %d"
+msgstr ""
+
+#: config/tc-a29k.c:160 config/tc-sparc.c:3357
+msgid "Unknown segment type"
+msgstr ""
+
+#. Probably a memory allocation problem? Give up now.
+#: config/tc-a29k.c:330 config/tc-hppa.c:1354 config/tc-i860.c:202
+#: config/tc-mips.c:1102 config/tc-mips.c:1144 config/tc-sparc.c:715
+msgid "Broken assembler. No assembly attempted."
+msgstr ""
+
+#: config/tc-a29k.c:375 config/tc-arc.c:534 config/tc-d10v.c:481
+#: config/tc-d30v.c:540 config/tc-h8300.c:305 config/tc-h8500.c:297
+#: config/tc-mcore.c:380 config/tc-mn10200.c:936 config/tc-mn10300.c:1307
+#: config/tc-ppc.c:1844 config/tc-sh.c:478 config/tc-tic80.c:291
+#: config/tc-v850.c:2033 config/tc-w65.c:257 config/tc-z8k.c:341
+msgid "missing operand"
+msgstr ""
+
+#: config/tc-a29k.c:415 config/tc-hppa.c:1471 config/tc-i860.c:407
+#: config/tc-i860.c:423 config/tc-sparc.c:1191 config/tc-sparc.c:1197
+#, c-format
+msgid "Unknown opcode: `%s'"
+msgstr ""
+
+#: config/tc-a29k.c:420
+#, c-format
+msgid "Unknown opcode `%s'."
+msgstr ""
+
+#: config/tc-a29k.c:452
+#, c-format
+msgid "Too many operands: %s"
+msgstr ""
+
+#: config/tc-a29k.c:474 config/tc-a29k.c:505
+#, c-format
+msgid "Immediate value of %ld is too large"
+msgstr ""
+
+#: config/tc-a29k.c:892 config/tc-i860.c:940
+#, c-format
+msgid "bad relocation type: 0x%02x"
+msgstr ""
+
+#: config/tc-a29k.c:916
+#, c-format
+msgid "need %o3\n"
+msgstr ""
+
+#: config/tc-a29k.c:932
+msgid "a29k_convert_frag\n"
+msgstr ""
+
+#: config/tc-a29k.c:941
+msgid "a29k_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-a29k.c:1092
+#, c-format
+msgid "label \"$%d\" redefined"
+msgstr ""
+
+#: config/tc-a29k.c:1165
+msgid "Invalid expression after %%%%\n"
+msgstr ""
+
+#: config/tc-a29k.c:1176
+msgid "Invalid register in & expression"
+msgstr ""
+
+#: config/tc-alpha.c:722
+#, c-format
+msgid "internal error: can't hash opcode `%s': %s"
+msgstr ""
+
+#: config/tc-alpha.c:756
+#, c-format
+msgid "internal error: can't hash macro `%s': %s"
+msgstr ""
+
+#: config/tc-alpha.c:832 config/tc-i960.c:2711
+msgid "syntax error"
+msgstr ""
+
+#: config/tc-alpha.c:905 config/tc-arm.c:4982 config/tc-h8300.c:1413
+#: config/tc-h8500.c:1222 config/tc-hppa.c:3651 config/tc-i860.c:813
+#: config/tc-m68k.c:4003 config/tc-m88k.c:1106 config/tc-ns32k.c:1588
+#: config/tc-sparc.c:2433 config/tc-z8k.c:1355
+msgid "Bad call to MD_ATOF()"
+msgstr ""
+
+#: config/tc-alpha.c:955
+#, c-format
+msgid "Unknown CPU identifier `%s'"
+msgstr ""
+
+#: config/tc-alpha.c:999
+msgid ""
+"Alpha options:\n"
+"-32addr\t\t\ttreat addresses as 32-bit values\n"
+"-F\t\t\tlack floating point instructions support\n"
+"-mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n"
+"\t\t\tspecify variant of Alpha architecture\n"
+"-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n"
+"\t\t\tthese variants include PALcode opcodes\n"
+msgstr ""
+
+#: config/tc-alpha.c:1009
+msgid ""
+"VMS options:\n"
+"-+\t\t\thash encode (don't truncate) names longer than 64 characters\n"
+"-H\t\t\tshow new symbol after hash truncation\n"
+msgstr ""
+
+#: config/tc-alpha.c:1165
+#, c-format
+msgid "unhandled relocation type %s"
+msgstr ""
+
+#: config/tc-alpha.c:1178
+msgid "non-absolute expression in constant field"
+msgstr ""
+
+#: config/tc-alpha.c:1192
+#, c-format
+msgid "type %d reloc done?\n"
+msgstr ""
+
+#: config/tc-alpha.c:1243 config/tc-alpha.c:1250 config/tc-mips.c:7777
+msgid "Used $at without \".set noat\""
+msgstr ""
+
+#: config/tc-alpha.c:1407
+#, c-format
+msgid "cannot represent `%s' relocation in object file"
+msgstr ""
+
+#: config/tc-alpha.c:1414
+#, c-format
+msgid "internal error? cannot generate `%s' relocation"
+msgstr ""
+
+#: config/tc-alpha.c:1468
+#, c-format
+msgid "frame reg expected, using $%d."
+msgstr ""
+
+#: config/tc-alpha.c:1793
+#, c-format
+msgid "operand out of range (%s not between %d and %d)"
+msgstr ""
+
+#: config/tc-alpha.c:1890 config/tc-arc.c:547 config/tc-d10v.c:570
+#: config/tc-d30v.c:623 config/tc-mn10200.c:991 config/tc-mn10300.c:1382
+#: config/tc-ppc.c:1810 config/tc-ppc.c:1917 config/tc-ppc.c:1929
+#: config/tc-v850.c:1819 config/tc-v850.c:1842 config/tc-v850.c:2055
+msgid "too many fixups"
+msgstr ""
+
+#: config/tc-alpha.c:2015 config/tc-alpha.c:2073
+#, c-format
+msgid "inappropriate arguments for opcode `%s'"
+msgstr ""
+
+#: config/tc-alpha.c:2017 config/tc-alpha.c:2075
+#, c-format
+msgid "opcode `%s' not supported for target %s"
+msgstr ""
+
+#: config/tc-alpha.c:2021 config/tc-alpha.c:2078
+#, c-format
+msgid "unknown opcode `%s'"
+msgstr ""
+
+#: config/tc-alpha.c:2130
+msgid "can not resolve expression"
+msgstr ""
+
+#: config/tc-alpha.c:2268 config/tc-alpha.c:2445
+msgid "overflow in literal (.lita) table"
+msgstr ""
+
+#: config/tc-alpha.c:2275 config/tc-alpha.c:2297 config/tc-alpha.c:2458
+#: config/tc-alpha.c:2680 config/tc-alpha.c:2727 config/tc-alpha.c:2775
+#: config/tc-alpha.c:2864 config/tc-alpha.c:3065 config/tc-alpha.c:3166
+msgid "macro requires $at register while noat in effect"
+msgstr ""
+
+#: config/tc-alpha.c:2277 config/tc-alpha.c:2299 config/tc-alpha.c:2460
+msgid "macro requires $at while $at in use"
+msgstr ""
+
+#: config/tc-alpha.c:2407 expr.c:82 read.c:3101
+msgid "bignum invalid; zero assumed"
+msgstr ""
+
+#: config/tc-alpha.c:2409 expr.c:84 read.c:3103 read.c:3432 read.c:4328
+msgid "floating point number invalid; zero assumed"
+msgstr ""
+
+#: config/tc-alpha.c:2414
+msgid "can't handle expression"
+msgstr ""
+
+#: config/tc-alpha.c:2451
+msgid "overflow in literal (.lit8) table"
+msgstr ""
+
+#: config/tc-alpha.c:3400 config/tc-ppc.c:1338 config/tc-ppc.c:3542
+#: read.c:1358
+#, c-format
+msgid ".COMMon length (%ld.) <0! Ignored."
+msgstr ""
+
+#: config/tc-alpha.c:3438 config/tc-alpha.c:3447 config/tc-ppc.c:3579
+#: read.c:1379
+#, c-format
+msgid "Length of .comm \"%s\" is already %ld. Not changed to %ld."
+msgstr ""
+
+#: config/tc-alpha.c:3549 ecoff.c:3105
+msgid ".ent directive has no name"
+msgstr ""
+
+#: config/tc-alpha.c:3557
+msgid "nested .ent directives"
+msgstr ""
+
+#: config/tc-alpha.c:3593 ecoff.c:3053
+msgid ".end directive has no name"
+msgstr ""
+
+#: config/tc-alpha.c:3602
+msgid ".end directive names different symbol than .ent"
+msgstr ""
+
+#: config/tc-alpha.c:3676
+#, c-format
+msgid "Invalid argument %d to .prologue."
+msgstr ""
+
+#: config/tc-alpha.c:3704
+msgid "ECOFF debugging is disabled."
+msgstr ""
+
+#: config/tc-alpha.c:3725
+msgid "Unknown section directive"
+msgstr ""
+
+#: config/tc-alpha.c:3762
+msgid ".ent directive has no symbol"
+msgstr ""
+
+#: config/tc-alpha.c:3790
+msgid "Bad .frame directive 1./2. param"
+msgstr ""
+
+#: config/tc-alpha.c:3802
+msgid "Bad .frame directive 3./4. param"
+msgstr ""
+
+#: config/tc-alpha.c:3827
+msgid ".pdesc directive not in link (.link) section"
+msgstr ""
+
+#: config/tc-alpha.c:3835
+msgid ".pdesc has no matching .ent"
+msgstr ""
+
+#: config/tc-alpha.c:3845
+msgid ".pdesc directive has no entry symbol"
+msgstr ""
+
+#: config/tc-alpha.c:3857
+msgid "No comma after .pdesc <entryname>"
+msgstr ""
+
+#: config/tc-alpha.c:3880
+msgid "unknown procedure kind"
+msgstr ""
+
+#: config/tc-alpha.c:3975
+msgid ".name directive not in link (.link) section"
+msgstr ""
+
+#: config/tc-alpha.c:3983
+msgid ".name directive has no symbol"
+msgstr ""
+
+#: config/tc-alpha.c:4018
+msgid "No symbol after .linkage"
+msgstr ""
+
+#: config/tc-alpha.c:4047
+msgid "No symbol after .code_address"
+msgstr ""
+
+#: config/tc-alpha.c:4082 ecoff.c:3269
+msgid "Bad .mask directive"
+msgstr ""
+
+#: config/tc-alpha.c:4104 ecoff.c:3200
+msgid "Bad .fmask directive"
+msgstr ""
+
+#: config/tc-alpha.c:4275 read.c:2123 read.c:2675 stabs.c:460
+#, c-format
+msgid "Expected comma after name \"%s\""
+msgstr ""
+
+#. symbolP->sy_other = (signed char) temp;
+#: config/tc-alpha.c:4286
+#, c-format
+msgid "unhandled: .proc %s,%d"
+msgstr ""
+
+#: config/tc-alpha.c:4321
+#, c-format
+msgid "Tried to .set unrecognized mode `%s'"
+msgstr ""
+
+#. not fatal, but it might not work in the end
+#: config/tc-alpha.c:4338
+msgid "File overrides no-base-register option."
+msgstr ""
+
+#: config/tc-alpha.c:4355
+#, c-format
+msgid "Bad base register, using $%d."
+msgstr ""
+
+#: config/tc-alpha.c:4377
+#, c-format
+msgid "Alignment too large: %d. assumed"
+msgstr ""
+
+#: config/tc-alpha.c:4381 config/tc-d30v.c:2163
+msgid "Alignment negative: 0 assumed"
+msgstr ""
+
+#: config/tc-alpha.c:4694
+#, c-format
+msgid "Chose GP value of %lx\n"
+msgstr ""
+
+#: config/tc-arc.c:136
+msgid ""
+"ARC options:\n"
+"-EB\t\t\tgenerate big endian output\n"
+"-EL\t\t\tgenerate little endian output\n"
+msgstr ""
+
+#: config/tc-arc.c:154 config/tc-arc.c:177 config/tc-arc.c:921
+#: config/tc-hppa.c:1316 config/tc-hppa.c:6410 config/tc-hppa.c:6416
+#: config/tc-hppa.c:6422 config/tc-mn10300.c:890 config/tc-mn10300.c:2023
+msgid "could not set architecture and machine"
+msgstr ""
+
+#: config/tc-arc.c:174
+msgid "virtual memory exhausted"
+msgstr ""
+
+#: config/tc-arc.c:253 config/tc-mn10200.c:1354 config/tc-mn10300.c:1930
+#: config/tc-ppc.c:1095 config/tc-v850.c:1618
+#, c-format
+msgid "operand out of range (%s not between %ld and %ld)"
+msgstr ""
+
+#: config/tc-arc.c:388
+#, c-format
+msgid "unknown syntax format character `%c'"
+msgstr ""
+
+#: config/tc-arc.c:487
+msgid "too many suffixes"
+msgstr ""
+
+#: config/tc-arc.c:532 config/tc-d10v.c:479 config/tc-d30v.c:538
+#: config/tc-mn10200.c:933 config/tc-mn10300.c:1304 config/tc-ppc.c:1842
+#: config/tc-tic80.c:287 config/tc-v850.c:2030
+msgid "illegal operand"
+msgstr ""
+
+#: config/tc-arc.c:619 config/tc-mn10200.c:1032 config/tc-mn10300.c:1452
+#: config/tc-ppc.c:1966 config/tc-v850.c:2108
+#, c-format
+msgid "junk at end of line: `%s'"
+msgstr ""
+
+#: config/tc-arc.c:659
+msgid "8 byte instruction in delay slot"
+msgstr ""
+
+#: config/tc-arc.c:661
+msgid "8 byte jump instruction with delay slot"
+msgstr ""
+
+#: config/tc-arc.c:669
+msgid "conditional branch follows set of flags"
+msgstr ""
+
+#: config/tc-arc.c:748 config/tc-arm.c:6041
+#, c-format
+msgid "bad instruction `%s'"
+msgstr ""
+
+#: config/tc-arc.c:771
+msgid "expected comma after symbol-name"
+msgstr ""
+
+#: config/tc-arc.c:788
+msgid "ignoring attempt to re-define symbol"
+msgstr ""
+
+#: config/tc-arc.c:803
+msgid "expected comma after common length"
+msgstr ""
+
+#: config/tc-arc.c:896
+msgid ".cpu command must appear before any instructions"
+msgstr ""
+
+#: config/tc-arc.c:915
+msgid ".cpu conflicts with previous value"
+msgstr ""
+
+#: config/tc-arc.c:926
+msgid "bad .cpu op"
+msgstr ""
+
+#: config/tc-arc.c:950 config/tc-ppc.c:2615
+msgid "missing rename string"
+msgstr ""
+
+#: config/tc-arc.c:962
+msgid "invalid symbol to rename to"
+msgstr ""
+
+#: config/tc-arc.c:1009 config/tc-d10v.c:274 config/tc-d30v.c:353
+#: config/tc-mips.c:9317 config/tc-mn10200.c:356 config/tc-ppc.c:4363
+#: config/tc-sh.c:1187 config/tc-v850.c:1276
+msgid "bad call to md_atof"
+msgstr ""
+
+#: config/tc-arc.c:1096
+#, c-format
+msgid "missing ')' in %-op"
+msgstr ""
+
+#: config/tc-arc.c:1130
+msgid "expression too complex for %%st"
+msgstr ""
+
+#: config/tc-arc.c:1324 config/tc-arm.c:2937 config/tc-d10v.c:1448
+#: config/tc-d30v.c:1810 config/tc-mips.c:3361 config/tc-mips.c:4317
+#: config/tc-mips.c:5102 config/tc-mips.c:5648 config/tc-ppc.c:4698
+#: config/tc-v850.c:2339
+msgid "expression too complex"
+msgstr ""
+
+#: config/tc-arc.c:1390 config/tc-ppc.c:4801 config/tc-v850.c:2383
+msgid "unresolved expression that must be resolved"
+msgstr ""
+
+#: config/tc-arc.c:1454 config/tc-sparc.c:2880
+#, c-format
+msgid "internal error: can't export reloc type %d (`%s')"
+msgstr ""
+
+#: config/tc-arm.c:983
+msgid "Literal Pool Overflow"
+msgstr ""
+
+#: config/tc-arm.c:1103
+msgid "Invalid syntax for .req directive."
+msgstr ""
+
+#: config/tc-arm.c:1139
+msgid "Nothing to put in the pool\n"
+msgstr ""
+
+#: config/tc-arm.c:1151
+msgid "Inserting implicit pool at change of section"
+msgstr ""
+
+#: config/tc-arm.c:1183 config/tc-mips.c:10603 read.c:2017
+#, c-format
+msgid "Alignment too large: %d. assumed."
+msgstr ""
+
+#: config/tc-arm.c:1186 read.c:2022
+msgid "Alignment negative. 0 assumed."
+msgstr ""
+
+#: config/tc-arm.c:1251
+msgid "selected processor does not support THUMB opcodes"
+msgstr ""
+
+#: config/tc-arm.c:1263
+msgid "selected processor does not support ARM opcodes"
+msgstr ""
+
+#: config/tc-arm.c:1272
+#, c-format
+msgid "invalid instruction size selected (%d)"
+msgstr ""
+
+#: config/tc-arm.c:1307
+#, c-format
+msgid "invalid operand to .code directive (%d) (expecting 16 or 32)"
+msgstr ""
+
+#: config/tc-arm.c:1319
+msgid "Garbage following instruction"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden
+#: config/tc-arm.c:1367
+#, c-format
+msgid "Register expected, not '%.100s'"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden
+#: config/tc-arm.c:1393
+msgid "<psr(f)> expected"
+msgstr ""
+
+#: config/tc-arm.c:1424
+msgid "Illegal co-processor number"
+msgstr ""
+
+#: config/tc-arm.c:1431
+msgid "Bad or missing co-processor number"
+msgstr ""
+
+#: config/tc-arm.c:1456
+msgid "bad or missing expression"
+msgstr ""
+
+#: config/tc-arm.c:1462
+msgid "immediate co-processor expression too large"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden
+#: config/tc-arm.c:1487
+msgid "Co-processor register expected"
+msgstr ""
+
+#. In the few cases where we might be able to accept something else
+#. this error can be overridden
+#: config/tc-arm.c:1511
+msgid "Floating point register expected"
+msgstr ""
+
+#: config/tc-arm.c:1529
+msgid "immediate expression expected"
+msgstr ""
+
+#: config/tc-arm.c:1544
+msgid "co-processor address must be word aligned"
+msgstr ""
+
+#: config/tc-arm.c:1550
+msgid "offset too large"
+msgstr ""
+
+#: config/tc-arm.c:1600
+msgid "pc may not be used in post-increment"
+msgstr ""
+
+#: config/tc-arm.c:1616 config/tc-arm.c:2727
+msgid "pre-indexed expression expected"
+msgstr ""
+
+#: config/tc-arm.c:1630 config/tc-arm.c:2740 config/tc-arm.c:3089
+msgid "missing ]"
+msgstr ""
+
+#: config/tc-arm.c:1641
+msgid "pc may not be used with write-back"
+msgstr ""
+
+#: config/tc-arm.c:1696
+msgid "<psr> expected"
+msgstr ""
+
+#: config/tc-arm.c:1758 config/tc-arm.c:2378
+msgid "Register or shift expression expected"
+msgstr ""
+
+#: config/tc-arm.c:1772 config/tc-arm.c:2090 config/tc-arm.c:2345
+#: config/tc-arm.c:2365
+msgid "Invalid constant"
+msgstr ""
+
+#: config/tc-arm.c:1783
+msgid "Error: unrecognised syntax for second argument to msr instruction"
+msgstr ""
+
+#: config/tc-arm.c:1833
+msgid "rdhi, rdlo and rm must all be different"
+msgstr ""
+
+#: config/tc-arm.c:1890
+msgid "rd and rm should be different in mul"
+msgstr ""
+
+#: config/tc-arm.c:1947
+msgid "rd and rm should be different in mla"
+msgstr ""
+
+#: config/tc-arm.c:2074
+msgid "bad_segment"
+msgstr ""
+
+#: config/tc-arm.c:2121 config/tc-arm.c:2199
+msgid "Shift expression expected"
+msgstr ""
+
+#: config/tc-arm.c:2163
+msgid "Invalid immediate shift"
+msgstr ""
+
+#: config/tc-arm.c:2192
+msgid "shift requires register or #expression"
+msgstr ""
+
+#: config/tc-arm.c:2193
+msgid "shift requires #expression"
+msgstr ""
+
+#: config/tc-arm.c:2336 config/tc-arm.c:2770
+msgid "Constant expression expected"
+msgstr ""
+
+#: config/tc-arm.c:2432
+msgid "Invalid floating point immediate expression"
+msgstr ""
+
+#: config/tc-arm.c:2435
+msgid "Floating point register or immediate expression expected"
+msgstr ""
+
+#: config/tc-arm.c:2574
+msgid "address offset too large"
+msgstr ""
+
+#: config/tc-arm.c:2645
+msgid "Processor does not support halfwords or signed bytes"
+msgstr ""
+
+#: config/tc-arm.c:2667
+msgid "Address expected"
+msgstr ""
+
+#: config/tc-arm.c:2698 config/tc-arm.c:2712 config/tc-arm.c:2750
+msgid "destination register same as write-back base\n"
+msgstr ""
+
+#: config/tc-arm.c:2790
+msgid "literal pool insertion failed"
+msgstr ""
+
+#: config/tc-arm.c:2826
+msgid "Pre-increment instruction with translate"
+msgstr ""
+
+#: config/tc-arm.c:2868
+msgid "Bad range in register list"
+msgstr ""
+
+#: config/tc-arm.c:2876 config/tc-arm.c:2885 config/tc-arm.c:2927
+#, c-format
+msgid "Warning: Duplicated register (r%d) in register list"
+msgstr ""
+
+#: config/tc-arm.c:2888
+msgid "Warning: Register range not in ascending order"
+msgstr ""
+
+#: config/tc-arm.c:2900
+msgid "Missing `}'"
+msgstr ""
+
+#: config/tc-arm.c:2916
+msgid "invalid register mask"
+msgstr ""
+
+#: config/tc-arm.c:2977
+msgid "r15 not allowed as base register"
+msgstr ""
+
+#: config/tc-arm.c:3047 config/tc-arm.c:3061
+msgid "r15 not allowed in swap"
+msgstr ""
+
+#: config/tc-arm.c:3158
+msgid "Use of r15 in bx has undefined behaviour"
+msgstr ""
+
+#: config/tc-arm.c:3417 config/tc-v850.c:1921 config/tc-v850.c:1942
+msgid "constant expression expected"
+msgstr ""
+
+#: config/tc-arm.c:3423
+msgid "Constant value required for number of registers"
+msgstr ""
+
+#: config/tc-arm.c:3431
+msgid "number of registers must be in the range [1:4]"
+msgstr ""
+
+#: config/tc-arm.c:3493
+msgid "R15 not allowed as base register with write-back"
+msgstr ""
+
+#: config/tc-arm.c:3745
+msgid "lo register required"
+msgstr ""
+
+#: config/tc-arm.c:3753
+msgid "hi register required"
+msgstr ""
+
+#: config/tc-arm.c:3823
+msgid "dest and source1 must be the same register"
+msgstr ""
+
+#: config/tc-arm.c:3830
+msgid "subtract valid only on lo regs"
+msgstr ""
+
+#: config/tc-arm.c:3854
+msgid "invalid Hi register with immediate"
+msgstr ""
+
+#: config/tc-arm.c:3881 config/tc-arm.c:3914 config/tc-arm.c:3924
+msgid "immediate value out of range"
+msgstr ""
+
+#: config/tc-arm.c:3892
+msgid "invalid immediate value for stack adjust"
+msgstr ""
+
+#: config/tc-arm.c:3903
+msgid "invalid immediate for address calculation"
+msgstr ""
+
+#: config/tc-arm.c:3990
+msgid "source1 and dest must be same register"
+msgstr ""
+
+#: config/tc-arm.c:4025
+msgid "Invalid immediate for shift"
+msgstr ""
+
+#: config/tc-arm.c:4104
+msgid "only lo regs allowed with immediate"
+msgstr ""
+
+#: config/tc-arm.c:4123
+msgid "invalid immediate"
+msgstr ""
+
+#: config/tc-arm.c:4178
+msgid "expected ']'"
+msgstr ""
+
+#: config/tc-arm.c:4245
+msgid "byte or halfword not valid for base register"
+msgstr ""
+
+#: config/tc-arm.c:4250
+msgid "R15 based store not allowed"
+msgstr ""
+
+#: config/tc-arm.c:4255
+msgid "Invalid base register for register offset"
+msgstr ""
+
+#: config/tc-arm.c:4273
+msgid "invalid offset"
+msgstr ""
+
+#: config/tc-arm.c:4284
+msgid "invalid base register in load/store"
+msgstr ""
+
+#: config/tc-arm.c:4308 config/tc-arm.c:5471 config/tc-arm.c:5480
+#: config/tc-arm.c:5487 config/tc-arm.c:5494 config/tc-arm.c:5501
+msgid "Invalid offset"
+msgstr ""
+
+#: config/tc-arm.c:4386
+msgid "dest and source1 one must be the same register"
+msgstr ""
+
+#: config/tc-arm.c:4394
+msgid "Rs and Rd must be different in MUL"
+msgstr ""
+
+#: config/tc-arm.c:4539
+msgid ""
+"Inserted missing '!': load/store multiple always writes back base register"
+msgstr ""
+
+#: config/tc-arm.c:4555 config/tc-arm.c:4657
+msgid "Expression too complex"
+msgstr ""
+
+#: config/tc-arm.c:4561
+msgid "only lo-regs valid in load/store multiple"
+msgstr ""
+
+#: config/tc-arm.c:4608
+msgid "Syntax: ldrs[b] Rd, [Rb, Ro]"
+msgstr ""
+
+#: config/tc-arm.c:4673
+msgid "invalid register list to push/pop instruction"
+msgstr ""
+
+#: config/tc-arm.c:4811
+msgid "Virtual memory exhausted"
+msgstr ""
+
+#: config/tc-arm.c:5203
+#, c-format
+msgid "invalid constant (%x) after fixup\n"
+msgstr ""
+
+#: config/tc-arm.c:5215 config/tc-arm.c:5236
+#, c-format
+msgid "bad immediate value for offset (%d)"
+msgstr ""
+
+#: config/tc-arm.c:5234 config/tc-arm.c:5257
+msgid "invalid literal constant: pool needs to be closer\n"
+msgstr ""
+
+#: config/tc-arm.c:5274
+msgid "shift expression is too large"
+msgstr ""
+
+#: config/tc-arm.c:5292 config/tc-arm.c:5301
+msgid "Invalid swi expression"
+msgstr ""
+
+#: config/tc-arm.c:5311
+msgid "Invalid expression in load/store multiple"
+msgstr ""
+
+#: config/tc-arm.c:5341 config/tc-arm.c:5357 config/tc-mips.c:10430
+msgid "Branch out of range"
+msgstr ""
+
+#: config/tc-arm.c:5376
+msgid "Branch with link out of range"
+msgstr ""
+
+#: config/tc-arm.c:5443
+msgid "Illegal value for co-processor offset"
+msgstr ""
+
+#: config/tc-arm.c:5466
+#, c-format
+msgid "Invalid offset, target not word aligned (0x%08X)"
+msgstr ""
+
+#: config/tc-arm.c:5537
+msgid "Invalid immediate for stack address calculation"
+msgstr ""
+
+#: config/tc-arm.c:5546
+#, c-format
+msgid "Invalid immediate for address calculation (value = 0x%08X)"
+msgstr ""
+
+#: config/tc-arm.c:5555
+msgid "Invalid 8bit immediate"
+msgstr ""
+
+#: config/tc-arm.c:5563
+msgid "Invalid 3bit immediate"
+msgstr ""
+
+#: config/tc-arm.c:5579
+#, c-format
+msgid "Invalid immediate: %d is too large"
+msgstr ""
+
+#: config/tc-arm.c:5593
+#, c-format
+msgid "Illegal Thumb shift value: %d"
+msgstr ""
+
+#: config/tc-arm.c:5607
+#, c-format
+msgid "Bad relocation fixup type (%d)\n"
+msgstr ""
+
+#: config/tc-arm.c:5676
+msgid "Literal referenced across section boundry (Implicit dump?)"
+msgstr ""
+
+#: config/tc-arm.c:5695
+#, c-format
+msgid "Internal_relocation (type %d) not fixed up (IMMEDIATE)"
+msgstr ""
+
+#: config/tc-arm.c:5701
+#, c-format
+msgid "Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
+msgstr ""
+
+#: config/tc-arm.c:5724
+#, c-format
+msgid "Can not represent %s relocation in this object file format (%d)"
+msgstr ""
+
+#: config/tc-arm.c:5742 config/tc-mips.c:11909 config/tc-sh.c:2277
+#, c-format
+msgid "Can not represent %s relocation in this object file format"
+msgstr ""
+
+#: config/tc-arm.c:5755
+msgid "md_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-arm.c:5825
+#, c-format
+msgid "No operator -- statement `%s'\n"
+msgstr ""
+
+#: config/tc-arm.c:5875 config/tc-arm.c:5927
+#, c-format
+msgid "Opcode `%s' must have suffix from <%s>\n"
+msgstr ""
+
+#: config/tc-arm.c:5900
+msgid "Warning: Use of the 'nv' conditional is deprecated\n"
+msgstr ""
+
+#: config/tc-arm.c:6019
+#, c-format
+msgid "register '%s' does not exist\n"
+msgstr ""
+
+#: config/tc-arm.c:6025
+#, c-format
+msgid "ignoring redefinition of register alias '%s'"
+msgstr ""
+
+#: config/tc-arm.c:6030
+#, c-format
+msgid ""
+"ignoring redefinition of register alias '%s' to non-existant register '%s'"
+msgstr ""
+
+#: config/tc-arm.c:6034
+msgid "ignoring incomplete .req pseuso op"
+msgstr ""
+
+#: config/tc-arm.c:6210
+#, c-format
+msgid "Unrecognised APCS switch -m%s"
+msgstr ""
+
+#: config/tc-arm.c:6336 config/tc-arm.c:6347 config/tc-arm.c:6358
+#: config/tc-arm.c:6363
+#, c-format
+msgid "Invalid architecture variant -m%s"
+msgstr ""
+
+#: config/tc-arm.c:6370
+#, c-format
+msgid "Invalid processor variant -m%s"
+msgstr ""
+
+#: config/tc-arm.c:6392
+msgid ""
+" ARM Specific Assembler Options:\n"
+" -m[arm][<processor name>] select processor variant\n"
+" -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n"
+" -mthumb only allow Thumb instructions\n"
+" -mthumb-interwork mark the assembled code as supporting "
+"interworking\n"
+" -mall allow any instruction\n"
+" -mfpa10, -mfpa11 select floating point architecture\n"
+" -mfpe-old don't allow floating-point multiple "
+"instructions\n"
+" -mno-fpu don't allow any floating-point instructions.\n"
+msgstr ""
+
+#: config/tc-arm.c:6403
+msgid " -k generate PIC code.\n"
+msgstr ""
+
+#: config/tc-arm.c:6407
+msgid ""
+" -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to "
+"use\n"
+msgstr ""
+
+#: config/tc-arm.c:6410
+msgid " -mapcs-float floating point args are passed in FP regs\n"
+msgstr ""
+
+#: config/tc-arm.c:6413
+msgid ""
+" -mapcs-reentrant the code is position independent/reentrant\n"
+msgstr ""
+
+#: config/tc-arm.c:6418
+msgid " -moabi support the old ELF ABI\n"
+msgstr ""
+
+#: config/tc-arm.c:6423
+msgid ""
+" -EB assemble code for a big endian cpu\n"
+" -EL assemble code for a little endian cpu\n"
+msgstr ""
+
+#: config/tc-arm.c:6596
+#, c-format
+msgid "%s: unexpected function type: %d"
+msgstr ""
+
+#: config/tc-d10v.c:218
+msgid ""
+"D10V options:\n"
+"-O optimize. Will do some operations in parallel.\n"
+msgstr ""
+
+#: config/tc-d10v.c:521 config/tc-d10v.c:603 config/tc-d30v.c:639
+#, c-format
+msgid "operand out of range: %d"
+msgstr ""
+
+#: config/tc-d10v.c:664
+msgid "Instruction must be executed in parallel with another instruction."
+msgstr ""
+
+#: config/tc-d10v.c:716
+msgid "Instruction must be executed in parallel"
+msgstr ""
+
+#: config/tc-d10v.c:719
+msgid "Long instructions may not be combined."
+msgstr ""
+
+#: config/tc-d10v.c:759
+msgid "One of these instructions may not be executed in parallel."
+msgstr ""
+
+#: config/tc-d10v.c:764 config/tc-d30v.c:843
+msgid "Two IU instructions may not be executed in parallel"
+msgstr ""
+
+#: config/tc-d10v.c:766 config/tc-d10v.c:774 config/tc-d10v.c:789
+#: config/tc-d10v.c:802 config/tc-d30v.c:844 config/tc-d30v.c:853
+msgid "Swapping instruction order"
+msgstr ""
+
+#: config/tc-d10v.c:772 config/tc-d30v.c:850
+msgid "Two MU instructions may not be executed in parallel"
+msgstr ""
+
+#: config/tc-d10v.c:793 config/tc-d30v.c:869
+msgid "IU instruction may not be in the left container"
+msgstr ""
+
+#: config/tc-d10v.c:806 config/tc-d30v.c:882
+msgid "MU instruction may not be in the right container"
+msgstr ""
+
+#: config/tc-d10v.c:810 config/tc-d30v.c:890
+msgid "unknown execution type passed to write_2_short()"
+msgstr ""
+
+#: config/tc-d10v.c:1023 config/tc-d10v.c:1037 config/tc-h8300.c:1279
+#: config/tc-h8500.c:1122 config/tc-mcore.c:709 config/tc-sh.c:1040
+#: config/tc-z8k.c:1223
+msgid "can't find opcode "
+msgstr ""
+
+#: config/tc-d10v.c:1050 config/tc-d10v.c:1068 config/tc-d30v.c:1368
+msgid "Unable to mix instructions as specified"
+msgstr ""
+
+#: config/tc-d10v.c:1116 config/tc-d30v.c:1503
+#, c-format
+msgid "unknown opcode: %s"
+msgstr ""
+
+#: config/tc-d10v.c:1197 config/tc-d10v.c:1343 config/tc-tic80.c:537
+msgid "bad opcode or operands"
+msgstr ""
+
+#: config/tc-d10v.c:1246 config/tc-m68k.c:4110
+msgid "value out of range"
+msgstr ""
+
+#: config/tc-d10v.c:1318
+msgid "illegal operand - register name found where none expected"
+msgstr ""
+
+#: config/tc-d10v.c:1354 config/tc-tic80.c:548
+msgid "Register number must be EVEN"
+msgstr ""
+
+#: config/tc-d10v.c:1385 config/tc-d30v.c:1754 config/tc-mn10200.c:1234
+#: config/tc-mn10300.c:1786 config/tc-ppc.c:4997 config/tc-v850.c:2254
+#, c-format
+msgid "reloc %d not supported by object file format"
+msgstr ""
+
+#: config/tc-d10v.c:1498
+#, c-format
+msgid "line %d: rep or repi must include at least 4 instructions"
+msgstr ""
+
+#: config/tc-d10v.c:1517 config/tc-d30v.c:1935
+#, c-format
+msgid "line %d: unknown relocation type: 0x%x"
+msgstr ""
+
+#: config/tc-d30v.c:184
+#, c-format
+msgid "Register name %s conflicts with symbol of the same name"
+msgstr ""
+
+#: config/tc-d30v.c:276
+msgid ""
+"\n"
+"D30V options:\n"
+"-O Make adjacent short instructions parallel if "
+"possible.\n"
+"-n Warn about all NOPs inserted by the assembler.\n"
+"-N\t\t\tWarn about NOPs inserted after word multiplies.\n"
+"-c Warn about symbols whoes names match register "
+"names.\n"
+"-C Opposite of -C. -c is the default.\n"
+msgstr ""
+
+#: config/tc-d30v.c:450
+msgid "unexpected 12-bit reloc type"
+msgstr ""
+
+#: config/tc-d30v.c:457
+msgid "unexpected 18-bit reloc type"
+msgstr ""
+
+#: config/tc-d30v.c:701
+#, c-format
+msgid "%s NOP inserted"
+msgstr ""
+
+#: config/tc-d30v.c:702
+msgid "sequential"
+msgstr ""
+
+#: config/tc-d30v.c:702
+msgid "parallel"
+msgstr ""
+
+#: config/tc-d30v.c:839
+msgid "Instructions may not be executed in parallel"
+msgstr ""
+
+#: config/tc-d30v.c:852 config/tc-d30v.c:859 config/tc-d30v.c:875
+#: config/tc-d30v.c:884
+#, c-format
+msgid "Executing %s in IU may not work"
+msgstr ""
+
+#: config/tc-d30v.c:871
+#, c-format
+msgid "special left instruction `%s' kills instruction `%s' in right container"
+msgstr ""
+
+#: config/tc-d30v.c:1250 config/tc-d30v.c:1267
+msgid "Cannot assemble instruction"
+msgstr ""
+
+#: config/tc-d30v.c:1252
+msgid "First opcode is long. Unable to mix instructions as specified."
+msgstr ""
+
+#: config/tc-d30v.c:1320
+msgid "word of NOPs added between word multiply and load"
+msgstr ""
+
+#: config/tc-d30v.c:1322
+msgid "word of NOPs added between word multiply and 16-bit multiply"
+msgstr ""
+
+#: config/tc-d30v.c:1352
+msgid "Instruction uses long version, so it cannot be mixed as specified"
+msgstr ""
+
+#: config/tc-d30v.c:1436 config/tc-d30v.c:1473
+#, c-format
+msgid "unknown condition code: %s"
+msgstr ""
+
+#: config/tc-d30v.c:1466
+#, c-format
+msgid "cmpu doesn't support condition code %s"
+msgstr ""
+
+#: config/tc-d30v.c:1514
+#, c-format
+msgid "operands for opcode `%s' do not match any valid format"
+msgstr ""
+
+#: config/tc-d30v.c:1727
+msgid "Odd numbered register used as target of multi-register instruction"
+msgstr ""
+
+#: config/tc-d30v.c:1824
+#, c-format
+msgid "line %d: unable to place address of symbol '%s' into a byte"
+msgstr ""
+
+#: config/tc-d30v.c:1827
+#, c-format
+msgid "line %d: unable to place value %x into a byte"
+msgstr ""
+
+#: config/tc-d30v.c:1835
+#, c-format
+msgid "line %d: unable to place address of symbol '%s' into a short"
+msgstr ""
+
+#: config/tc-d30v.c:1838
+#, c-format
+msgid "line %d: unable to place value %x into a short"
+msgstr ""
+
+#: config/tc-d30v.c:1846
+#, c-format
+msgid "line %d: unable to place address of symbol '%s' into a quad"
+msgstr ""
+
+#: config/tc-d30v.c:2016
+#, c-format
+msgid "value too large to fit in %d bits"
+msgstr ""
+
+#: config/tc-d30v.c:2159
+#, c-format
+msgid "Alignment too large: %d assumed"
+msgstr ""
+
+#: config/tc-h8300.c:254 config/tc-h8300.c:262
+msgid "Reg not valid for H8/300"
+msgstr ""
+
+#: config/tc-h8300.c:423 config/tc-h8300.c:426 config/tc-h8300.c:429
+#: config/tc-h8300.c:433
+msgid "Invalid register list for ldm/stm\n"
+msgstr ""
+
+#: config/tc-h8300.c:490 config/tc-h8300.c:553 config/tc-h8300.c:560
+msgid "Wrong size pointer register for architecture."
+msgstr ""
+
+#: config/tc-h8300.c:518 config/tc-h8300.c:527 config/tc-h8300.c:537
+msgid "expected @(exp, reg16)"
+msgstr ""
+
+#: config/tc-h8300.c:617
+msgid "expect :8 or :16 here"
+msgstr ""
+
+#: config/tc-h8300.c:823
+#, c-format
+msgid "operand %s0x%lx out of range."
+msgstr ""
+
+#: config/tc-h8300.c:910
+msgid "Can't work out size of operand.\n"
+msgstr ""
+
+#: config/tc-h8300.c:964
+#, c-format
+msgid "Opcode `%s' with these operand types not available in H8/300 mode"
+msgstr ""
+
+#: config/tc-h8300.c:1016 config/tc-h8300.c:1036
+msgid "Need #1 or #2 here"
+msgstr ""
+
+#: config/tc-h8300.c:1031
+msgid "#4 not valid on H8/300."
+msgstr ""
+
+#: config/tc-h8300.c:1112 config/tc-h8300.c:1150
+#, c-format
+msgid "branch operand has odd offset (%lx)\n"
+msgstr ""
+
+#: config/tc-h8300.c:1191
+msgid "destination operand must be 16 bit register"
+msgstr ""
+
+#: config/tc-h8300.c:1201
+msgid "source operand must be 8 bit register"
+msgstr ""
+
+#: config/tc-h8300.c:1209
+msgid "destination operand must be 16bit absolute address"
+msgstr ""
+
+#: config/tc-h8300.c:1216
+msgid "destination operand must be 8 bit register"
+msgstr ""
+
+#: config/tc-h8300.c:1225
+msgid "source operand must be 16bit absolute address"
+msgstr ""
+
+#: config/tc-h8300.c:1233
+msgid "invalid operands"
+msgstr ""
+
+#: config/tc-h8300.c:1290 config/tc-h8500.c:1129 config/tc-mips.c:8513
+#: config/tc-sh.c:1047 config/tc-w65.c:759 config/tc-z8k.c:1235
+msgid "unknown opcode"
+msgstr ""
+
+#: config/tc-h8300.c:1336
+msgid "mismatch between opcode size and operand size"
+msgstr ""
+
+#: config/tc-h8300.c:1348 config/tc-h8500.c:1157 config/tc-sh.c:1144
+#: config/tc-w65.c:791 config/tc-z8k.c:1290
+msgid "call to tc_crawl_symbol_chain \n"
+msgstr ""
+
+#: config/tc-h8300.c:1362 config/tc-h8500.c:1171 config/tc-sh.c:1151
+#: config/tc-w65.c:805 config/tc-z8k.c:1304
+msgid "call to tc_headers_hook \n"
+msgstr ""
+
+#: config/tc-h8300.c:1451 config/tc-h8500.c:1260 config/tc-z8k.c:1415
+msgid "call to tc_aout_fix_to_chars \n"
+msgstr ""
+
+#: config/tc-h8300.c:1461 config/tc-z8k.c:1425
+msgid "call to md_convert_frag \n"
+msgstr ""
+
+#: config/tc-h8300.c:1506 config/tc-z8k.c:1500
+msgid "call tomd_estimate_size_before_relax \n"
+msgstr ""
+
+#: config/tc-h8500.c:337
+msgid ":24 not valid for this opcode"
+msgstr ""
+
+#: config/tc-h8500.c:344
+msgid "expect :8,:16 or :24"
+msgstr ""
+
+#: config/tc-h8500.c:401
+msgid "syntax error in reg list"
+msgstr ""
+
+#: config/tc-h8500.c:419
+msgid "missing final register in range"
+msgstr ""
+
+#: config/tc-h8500.c:506 config/tc-h8500.c:513 config/tc-h8500.c:519
+msgid "expected @(exp, Rn)"
+msgstr ""
+
+#: config/tc-h8500.c:535
+msgid "@Rn+ needs word register"
+msgstr ""
+
+#: config/tc-h8500.c:545
+msgid "@Rn needs word register"
+msgstr ""
+
+#: config/tc-h8500.c:845 config/tc-sh.c:844
+#, c-format
+msgid "unhandled %d\n"
+msgstr ""
+
+#: config/tc-h8500.c:873 config/tc-sh.c:865
+#, c-format
+msgid "operand must be absolute in range %d..%d"
+msgstr ""
+
+#: config/tc-h8500.c:963 config/tc-sh.c:986
+#, c-format
+msgid "failed for %d\n"
+msgstr ""
+
+#: config/tc-h8500.c:1145 config/tc-sh.c:1082 config/tc-w65.c:779
+msgid "invalid operands for opcode"
+msgstr ""
+
+#: config/tc-hppa.c:1114
+msgid "Missing .exit\n"
+msgstr ""
+
+#: config/tc-hppa.c:1117
+msgid "Missing .procend\n"
+msgstr ""
+
+#: config/tc-hppa.c:1126
+msgid "Not in a space.\n"
+msgstr ""
+
+#: config/tc-hppa.c:1129
+msgid "Not in a subspace.\n"
+msgstr ""
+
+#: config/tc-hppa.c:1291
+msgid "Invalid field selector. Assuming F%%."
+msgstr ""
+
+#: config/tc-hppa.c:1322
+msgid "-R option not supported on this target."
+msgstr ""
+
+#: config/tc-hppa.c:1336
+#, c-format
+msgid "Internal error: can't hash `%s': %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:1344 config/tc-i860.c:191 config/tc-sparc.c:704
+#, c-format
+msgid "internal error: losing opcode: `%s' \"%s\"\n"
+msgstr ""
+
+#: config/tc-hppa.c:1406 config/tc-hppa.c:6539 config/tc-hppa.c:6591
+msgid "Missing function name for .PROC (corrupted label chain)"
+msgstr ""
+
+#: config/tc-hppa.c:1409 config/tc-hppa.c:6594
+msgid "Missing function name for .PROC"
+msgstr ""
+
+#: config/tc-hppa.c:1518 config/tc-hppa.c:4430
+msgid "could not update architecture and machine"
+msgstr ""
+
+#: config/tc-hppa.c:1714
+msgid "Invalid Indexed Load Completer."
+msgstr ""
+
+#: config/tc-hppa.c:1723
+msgid "Invalid Indexed Load Completer Syntax."
+msgstr ""
+
+#: config/tc-hppa.c:1756
+msgid "Invalid Short Load/Store Completer."
+msgstr ""
+
+#: config/tc-hppa.c:1807 config/tc-hppa.c:1812
+msgid "Invalid Store Bytes Short Completer"
+msgstr ""
+
+#: config/tc-hppa.c:1822 config/tc-hppa.c:1866
+#, c-format
+msgid "Invalid Compare/Subtract Condition: %c"
+msgstr ""
+
+#: config/tc-hppa.c:1840 config/tc-hppa.c:2375
+msgid "Invalid Compare/Subtract Condition."
+msgstr ""
+
+#: config/tc-hppa.c:1881
+msgid "Invalid Compare/Subtract Condition"
+msgstr ""
+
+#: config/tc-hppa.c:1970 config/tc-hppa.c:2062
+#, c-format
+msgid "Invalid Add Condition: %s"
+msgstr ""
+
+#: config/tc-hppa.c:2132 config/tc-hppa.c:2245
+msgid "Invalid Logical Instruction Condition."
+msgstr ""
+
+#: config/tc-hppa.c:2301
+msgid "Invalid Shift/Extract/Deposit Condition."
+msgstr ""
+
+#: config/tc-hppa.c:2337
+#, c-format
+msgid "Invalid Bit Branch Condition: %c"
+msgstr ""
+
+#: config/tc-hppa.c:2776 config/tc-hppa.c:2791
+#, c-format
+msgid "Invalid CBit Specification: %s"
+msgstr ""
+
+#: config/tc-hppa.c:2977 config/tc-hppa.c:3010 config/tc-hppa.c:3047
+msgid "Branch to unaligned address"
+msgstr ""
+
+#: config/tc-hppa.c:3147
+msgid "Invalid SFU identifier"
+msgstr ""
+
+#: config/tc-hppa.c:3207
+msgid "Invalid COPR identifier"
+msgstr ""
+
+#: config/tc-hppa.c:3447 config/tc-hppa.c:3473 config/tc-hppa.c:3498
+#: config/tc-hppa.c:3523 config/tc-hppa.c:3548
+msgid "Invalid register for single precision fmpyadd or fmpysub"
+msgstr ""
+
+#: config/tc-hppa.c:3572
+msgid "Invalid Floating Point Operand Format."
+msgstr ""
+
+#: config/tc-hppa.c:3595
+#, c-format
+msgid "Invalid operands %s"
+msgstr ""
+
+#: config/tc-hppa.c:4130
+msgid "Unknown relocation encountered in md_apply_fix."
+msgstr ""
+
+#: config/tc-hppa.c:4140
+#, c-format
+msgid "no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n"
+msgstr ""
+
+#: config/tc-hppa.c:4282 config/tc-hppa.c:4307
+#, c-format
+msgid "Undefined register: '%s'."
+msgstr ""
+
+#: config/tc-hppa.c:4345
+#, c-format
+msgid "Non-absolute symbol: '%s'."
+msgstr ""
+
+#: config/tc-hppa.c:4360
+#, c-format
+msgid "Undefined absolute constant: '%s'."
+msgstr ""
+
+#: config/tc-hppa.c:4469
+#, c-format
+msgid "Invalid FP Compare Condition: %s"
+msgstr ""
+
+#: config/tc-hppa.c:4526
+#, c-format
+msgid "Invalid FTEST completer: %s"
+msgstr ""
+
+#: config/tc-hppa.c:4593 config/tc-hppa.c:4632
+#, c-format
+msgid "Invalid FP Operand Format: %3s"
+msgstr ""
+
+#: config/tc-hppa.c:4713
+msgid "Bad segment in expression."
+msgstr ""
+
+#: config/tc-hppa.c:4772
+msgid "Bad segment (should be absolute)."
+msgstr ""
+
+#: config/tc-hppa.c:4871
+#, c-format
+msgid "Invalid argument location: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:4902
+#, c-format
+msgid "Invalid argument description: %d"
+msgstr ""
+
+#: config/tc-hppa.c:4925
+#, c-format
+msgid "Invalid Nullification: (%c)"
+msgstr ""
+
+#: config/tc-hppa.c:5657
+#, c-format
+msgid "Invalid .CALL argument: %s"
+msgstr ""
+
+#: config/tc-hppa.c:5776
+msgid ".callinfo is not within a procedure definition"
+msgstr ""
+
+#: config/tc-hppa.c:5796
+#, c-format
+msgid "FRAME parameter must be a multiple of 8: %d\n"
+msgstr ""
+
+#: config/tc-hppa.c:5815
+msgid "Value for ENTRY_GR must be in the range 3..18\n"
+msgstr ""
+
+#: config/tc-hppa.c:5827
+msgid "Value for ENTRY_FR must be in the range 12..21\n"
+msgstr ""
+
+#: config/tc-hppa.c:5837
+msgid "Value for ENTRY_SR must be 3\n"
+msgstr ""
+
+#: config/tc-hppa.c:5893
+#, c-format
+msgid "Invalid .CALLINFO argument: %s"
+msgstr ""
+
+#: config/tc-hppa.c:5983
+msgid "The .ENTER pseudo-op is not supported"
+msgstr ""
+
+#: config/tc-hppa.c:5997
+msgid "Misplaced .entry. Ignored."
+msgstr ""
+
+#: config/tc-hppa.c:6001
+msgid "Missing .callinfo."
+msgstr ""
+
+#: config/tc-hppa.c:6049
+msgid ".REG must use a label"
+msgstr ""
+
+#: config/tc-hppa.c:6051
+msgid ".EQU must use a label"
+msgstr ""
+
+#: config/tc-hppa.c:6102
+msgid ".EXIT must appear within a procedure"
+msgstr ""
+
+#: config/tc-hppa.c:6106
+msgid "Missing .callinfo"
+msgstr ""
+
+#: config/tc-hppa.c:6110
+msgid "No .ENTRY for this .EXIT"
+msgstr ""
+
+#: config/tc-hppa.c:6137
+#, c-format
+msgid "Cannot define export symbol: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:6190
+#, c-format
+msgid "Using ENTRY rather than CODE in export directive for %s"
+msgstr ""
+
+#: config/tc-hppa.c:6291
+#, c-format
+msgid "Undefined .EXPORT/.IMPORT argument (ignored): %s"
+msgstr ""
+
+#: config/tc-hppa.c:6373
+msgid "Missing label name on .LABEL"
+msgstr ""
+
+#: config/tc-hppa.c:6378
+msgid "extra .LABEL arguments ignored."
+msgstr ""
+
+#: config/tc-hppa.c:6393
+msgid "The .LEAVE pseudo-op is not supported"
+msgstr ""
+
+#: config/tc-hppa.c:6426
+msgid "Unrecognized .LEVEL argument\n"
+msgstr ""
+
+#: config/tc-hppa.c:6460
+#, c-format
+msgid "Cannot define static symbol: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:6493
+msgid "Nested procedures"
+msgstr ""
+
+#: config/tc-hppa.c:6503
+msgid "Cannot allocate unwind descriptor\n"
+msgstr ""
+
+#: config/tc-hppa.c:6598
+msgid "misplaced .procend"
+msgstr ""
+
+#: config/tc-hppa.c:6601
+msgid "Missing .callinfo for this procedure"
+msgstr ""
+
+#: config/tc-hppa.c:6604
+msgid "Missing .EXIT for a .ENTRY"
+msgstr ""
+
+#: config/tc-hppa.c:6704
+msgid "Invalid .SPACE argument"
+msgstr ""
+
+#: config/tc-hppa.c:6752
+msgid "Can't change spaces within a procedure definition. Ignored"
+msgstr ""
+
+#: config/tc-hppa.c:6879
+#, c-format
+msgid "Undefined space: '%s' Assuming space number = 0."
+msgstr ""
+
+#: config/tc-hppa.c:6921
+msgid "Must be in a space before changing or declaring subspaces.\n"
+msgstr ""
+
+#: config/tc-hppa.c:6925
+msgid "Can't change subspaces within a procedure definition. Ignored"
+msgstr ""
+
+#: config/tc-hppa.c:6961
+msgid "Parameters of an existing subspace can't be modified"
+msgstr ""
+
+#: config/tc-hppa.c:7014
+msgid "Alignment must be a power of 2"
+msgstr ""
+
+#: config/tc-hppa.c:7056
+msgid "FIRST not supported as a .SUBSPACE argument"
+msgstr ""
+
+#: config/tc-hppa.c:7058
+msgid "Invalid .SUBSPACE argument"
+msgstr ""
+
+#: config/tc-hppa.c:7098
+msgid "Ignoring subspace decl due to ELF BFD bugs."
+msgstr ""
+
+#: config/tc-hppa.c:7261
+#, c-format
+msgid "Internal error: Unable to find containing space for %s."
+msgstr ""
+
+#: config/tc-hppa.c:7302
+#, c-format
+msgid "Out of memory: could not allocate new space chain entry: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:7388
+#, c-format
+msgid "Out of memory: could not allocate new subspace chain entry: %s\n"
+msgstr ""
+
+#: config/tc-hppa.c:8044
+#, c-format
+msgid "Symbol '%s' could not be created."
+msgstr ""
+
+#: config/tc-hppa.c:8048
+msgid "No memory for symbol name."
+msgstr ""
+
+#: config/tc-i386.c:502
+msgid "same type of prefix used twice"
+msgstr ""
+
+#: config/tc-i386.c:536
+msgid "Bad argument to syntax directive."
+msgstr ""
+
+#: config/tc-i386.c:619 config/tc-m68k.c:3630
+#, c-format
+msgid "Internal Error: Can't hash %s: %s"
+msgstr ""
+
+#: config/tc-i386.c:850
+msgid "Unknown"
+msgstr ""
+
+#: config/tc-i386.c:898 config/tc-i386.c:4360 config/tc-m68k.c:762
+#, c-format
+msgid "Can not do %d byte pc-relative relocation"
+msgstr ""
+
+#: config/tc-i386.c:908 config/tc-i386.c:4363 config/tc-m68k.c:769
+#, c-format
+msgid "Can not do %d byte relocation"
+msgstr ""
+
+#: config/tc-i386.c:1009 config/tc-i386.c:1095
+#, c-format
+msgid "no such 386 instruction: `%s'"
+msgstr ""
+
+#: config/tc-i386.c:1018
+#, c-format
+msgid "invalid character %s in mnemonic"
+msgstr ""
+
+#: config/tc-i386.c:1025
+msgid "expecting prefix; got nothing"
+msgstr ""
+
+#: config/tc-i386.c:1027
+msgid "expecting mnemonic; got nothing"
+msgstr ""
+
+#: config/tc-i386.c:1045
+#, c-format
+msgid "redundant %s prefix"
+msgstr ""
+
+#: config/tc-i386.c:1104
+#, c-format
+msgid "expecting string instruction after `%s'"
+msgstr ""
+
+#: config/tc-i386.c:1127
+#, c-format
+msgid "invalid character %s before operand %d"
+msgstr ""
+
+#: config/tc-i386.c:1141
+#, c-format
+msgid "unbalanced parenthesis in operand %d."
+msgstr ""
+
+#: config/tc-i386.c:1144
+#, c-format
+msgid "unbalanced brackets in operand %d."
+msgstr ""
+
+#: config/tc-i386.c:1153
+#, c-format
+msgid "invalid character %s in operand %d"
+msgstr ""
+
+#: config/tc-i386.c:1180
+#, c-format
+msgid "spurious operands; (%d operands/instruction max)"
+msgstr ""
+
+#: config/tc-i386.c:1201
+msgid "expecting operand after ','; got nothing"
+msgstr ""
+
+#: config/tc-i386.c:1206
+msgid "expecting operand before ','; got nothing"
+msgstr ""
+
+#. we found no match
+#: config/tc-i386.c:1433
+#, c-format
+msgid "suffix or operands invalid for `%s'"
+msgstr ""
+
+#. Warn them that a data or address size prefix doesn't affect
+#. assembly of the next line of code.
+#: config/tc-i386.c:1442
+#, c-format
+msgid "stand-alone `%s' prefix"
+msgstr ""
+
+#: config/tc-i386.c:1466 config/tc-i386.c:1481
+msgid "`%s' operand %d must use `%%es' segment"
+msgstr ""
+
+#: config/tc-i386.c:1547 config/tc-i386.c:1586 config/tc-i386.c:1613
+msgid "using `%%%s' instead of `%%%s' due to `%c' suffix"
+msgstr ""
+
+#: config/tc-i386.c:1558 config/tc-i386.c:1575 config/tc-i386.c:1602
+msgid "`%%%s' not allowed with `%s%c'"
+msgstr ""
+
+#: config/tc-i386.c:1642 config/tc-i386.c:1662
+msgid "no instruction mnemonic suffix given; can't determine immediate size"
+msgstr ""
+
+#: config/tc-i386.c:1687
+msgid ""
+"no instruction mnemonic suffix given and no register operands; can't size "
+"instruction"
+msgstr ""
+
+#. reversed arguments on faddp, fsubp, etc.
+#: config/tc-i386.c:1800
+msgid "translating to `%s %%%s,%%%s'"
+msgstr ""
+
+#. extraneous `l' suffix on fp insn
+#: config/tc-i386.c:1807
+msgid "translating to `%s %%%s'"
+msgstr ""
+
+#: config/tc-i386.c:2033
+msgid "you can't `pop %%cs'"
+msgstr ""
+
+#. UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc
+#: config/tc-i386.c:2064
+#, c-format
+msgid "translating to `%sp'"
+msgstr ""
+
+#: config/tc-i386.c:2095 config/tc-i386.c:2198 config/tc-i386.c:2258
+msgid "skipping prefixes on this instruction"
+msgstr ""
+
+#: config/tc-i386.c:2115 config/tc-i386.c:2222 config/tc-i386.c:2271
+msgid "16-bit jump out of range"
+msgstr ""
+
+#: config/tc-i386.c:2217
+#, c-format
+msgid "`%s' only takes byte displacement; %ld shortened to %d"
+msgstr ""
+
+#: config/tc-i386.c:2280
+#, c-format
+msgid "can't handle non absolute segment in `%s'"
+msgstr ""
+
+#: config/tc-i386.c:2537
+msgid "Only 1 or 2 immediate operands are allowed"
+msgstr ""
+
+#: config/tc-i386.c:2568 config/tc-i386.c:2797
+msgid "GOT relocations not supported in 16 bit mode"
+msgstr ""
+
+#: config/tc-i386.c:2589 config/tc-i386.c:2818
+msgid "Bad reloc specifier in expression"
+msgstr ""
+
+#: config/tc-i386.c:2606 config/tc-i386.c:2851
+#, c-format
+msgid "Ignoring junk `%s' after expression"
+msgstr ""
+
+#. missing or bad expr becomes absolute 0
+#: config/tc-i386.c:2613
+#, c-format
+msgid "Missing or invalid immediate expression `%s' taken as 0"
+msgstr ""
+
+#: config/tc-i386.c:2648 config/tc-i386.c:2870
+#, c-format
+msgid "Unimplemented segment type %d in operand"
+msgstr ""
+
+#: config/tc-i386.c:2691
+#, c-format
+msgid "expecting scale factor of 1, 2, 4, or 8: got `%s'"
+msgstr ""
+
+#: config/tc-i386.c:2697
+#, c-format
+msgid "scale factor of %d without an index register"
+msgstr ""
+
+#: config/tc-i386.c:3045 config/tc-i386.c:3051 config/tc-i386.c:3060
+#, c-format
+msgid "bad segment name `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3226 config/tc-i386.c:3481
+#, c-format
+msgid "too many memory references for `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3337 config/tc-i386.c:3350 config/tc-i386.c:3662
+#: config/tc-i386.c:3675
+#, c-format
+msgid "`%s' is not a valid %s bit base/index expression"
+msgstr ""
+
+#: config/tc-i386.c:3434
+#, c-format
+msgid "bad memory operand `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3449
+#, c-format
+msgid "Junk `%s' after register"
+msgstr ""
+
+#: config/tc-i386.c:3590
+#, c-format
+msgid "expecting `,' or `)' after index register in `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3607
+#, c-format
+msgid "expecting `)' after scale factor in `%s'"
+msgstr ""
+
+#: config/tc-i386.c:3614
+#, c-format
+msgid "expecting index register or scale factor after `,'; got '%c'"
+msgstr ""
+
+#: config/tc-i386.c:3621
+#, c-format
+msgid "expecting `,' or `)' after base register in `%s'"
+msgstr ""
+
+#. it's not a memory operand; argh!
+#: config/tc-i386.c:3684
+#, c-format
+msgid "invalid char %s beginning operand %d `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4087
+msgid "Bad call to md_atof ()"
+msgstr ""
+
+#: config/tc-i386.c:4148 config/tc-i386.c:4161
+#, c-format
+msgid "bad register name `%s'"
+msgstr ""
+
+#: config/tc-i386.c:4215
+msgid "-m\t\t\tdo long jump\n"
+msgstr ""
+
+#: config/tc-i386.c:4255
+msgid "GOT already in symbol table"
+msgstr ""
+
+#: config/tc-i386.c:4395 config/tc-mcore.c:2017 config/tc-sh.c:2415
+#, c-format
+msgid "Cannot represent relocation type %s"
+msgstr ""
+
+#: config/tc-i860.c:157 config/tc-i860.c:161
+msgid "Unknown temporary pseudo register"
+msgstr ""
+
+#: config/tc-i860.c:183 config/tc-mips.c:1099 config/tc-sparc.c:696
+#, c-format
+msgid "internal error: can't hash `%s': %s\n"
+msgstr ""
+
+#: config/tc-i860.c:341
+#, c-format
+msgid "Expanded opcode after delayed branch: `%s'"
+msgstr ""
+
+#: config/tc-i860.c:343
+#, c-format
+msgid "Expanded opcode in dual mode: `%s'"
+msgstr ""
+
+#: config/tc-i860.c:580
+msgid "Fsr1 equals fdest with Pipelining"
+msgstr ""
+
+#: config/tc-i860.c:631
+msgid "5-bit immediate too large"
+msgstr ""
+
+#: config/tc-i860.c:725
+msgid "Illegal operands"
+msgstr ""
+
+#: config/tc-i860.c:749 config/tc-sparc.c:2338
+msgid "bad segment"
+msgstr ""
+
+#: config/tc-i860.c:878
+#, c-format
+msgid "26-bit branch w/o pc relative set: 0x%08x"
+msgstr ""
+
+#. align pcrel offset, see manual
+#. check for overflow
+#: config/tc-i860.c:882
+#, c-format
+msgid "26-bit branch offset overflow: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:891 config/tc-i860.c:922
+#, c-format
+msgid "16-bit immediate 4-byte alignment error: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:896 config/tc-i860.c:927
+#, c-format
+msgid "16-bit immediate 2-byte alignment error: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:904
+#, c-format
+msgid "16-bit branch offset overflow: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:912
+#, c-format
+msgid "16-bit immediate 16-byte alignment error: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:917
+#, c-format
+msgid "16-bit immediate 8-byte alignment error: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:933
+#, c-format
+msgid "16-bit immediate overflow: 0x%08x"
+msgstr ""
+
+#: config/tc-i860.c:951
+msgid "md_number_to_disp\n"
+msgstr ""
+
+#: config/tc-i860.c:961
+msgid "i860_number_to_field\n"
+msgstr ""
+
+#: config/tc-i860.c:1001
+msgid "i860_convert_frag\n"
+msgstr ""
+
+#: config/tc-i860.c:1010
+msgid "i860_estimate_size_before_relax\n"
+msgstr ""
+
+#: config/tc-i960.c:544
+#, c-format
+msgid "Hashing returned \"%s\"."
+msgstr ""
+
+#. Offset of last character in opcode mnemonic
+#: config/tc-i960.c:578
+msgid "branch prediction invalid on this opcode"
+msgstr ""
+
+#: config/tc-i960.c:621
+#, c-format
+msgid "invalid opcode, \"%s\"."
+msgstr ""
+
+#: config/tc-i960.c:626
+#, c-format
+msgid "improper number of operands. expecting %d, got %d"
+msgstr ""
+
+#: config/tc-i960.c:771 config/tc-m32r.c:1873
+msgid "Bad call to md_atof()"
+msgstr ""
+
+#: config/tc-i960.c:861
+#, c-format
+msgid "Fixup of %ld too large for field width of %d"
+msgstr ""
+
+#: config/tc-i960.c:979
+#, c-format
+msgid "invalid architecture %s"
+msgstr ""
+
+#: config/tc-i960.c:999
+msgid "I960 options:\n"
+msgstr ""
+
+#: config/tc-i960.c:1002
+msgid ""
+"\n"
+"\t\t\tspecify variant of 960 architecture\n"
+"-b\t\t\tadd code to collect statistics about branches taken\n"
+"-link-relax\t\tpreserve individual alignment directives so linker\n"
+"\t\t\tcan do relaxing (b.out format only)\n"
+"-no-relax\t\tdon't alter compare-and-branch instructions for\n"
+"\t\t\tlong displacements\n"
+msgstr ""
+
+#: config/tc-i960.c:1400
+msgid "too many operands"
+msgstr ""
+
+#: config/tc-i960.c:1460 config/tc-i960.c:1690
+msgid "expression syntax error"
+msgstr ""
+
+#: config/tc-i960.c:1498
+msgid "attempt to branch into different segment"
+msgstr ""
+
+#: config/tc-i960.c:1502
+#, c-format
+msgid "target of %s instruction must be a label"
+msgstr ""
+
+#: config/tc-i960.c:1542
+msgid "unmatched '['"
+msgstr ""
+
+#: config/tc-i960.c:1553
+msgid "garbage after index spec ignored"
+msgstr ""
+
+#. We never moved: there was no opcode either!
+#: config/tc-i960.c:1620
+msgid "missing opcode"
+msgstr ""
+
+#: config/tc-i960.c:1928
+msgid "invalid constant"
+msgstr ""
+
+#: config/tc-i960.c:2041
+msgid "invalid index register"
+msgstr ""
+
+#: config/tc-i960.c:2064
+msgid "invalid scale factor"
+msgstr ""
+
+#: config/tc-i960.c:2247
+msgid "unaligned register"
+msgstr ""
+
+#: config/tc-i960.c:2270
+msgid "no such sfr in this architecture"
+msgstr ""
+
+#: config/tc-i960.c:2308
+msgid "illegal literal"
+msgstr ""
+
+#. Should not happen: see block comment above
+#: config/tc-i960.c:2541
+#, c-format
+msgid "Trying to 'bal' to %s"
+msgstr ""
+
+#: config/tc-i960.c:2552
+msgid "Looks like a proc, but can't tell what kind.\n"
+msgstr ""
+
+#: config/tc-i960.c:2584
+msgid "should have 1 or 2 operands"
+msgstr ""
+
+#: config/tc-i960.c:2593 config/tc-i960.c:2612
+#, c-format
+msgid "Redefining leafproc %s"
+msgstr ""
+
+#: config/tc-i960.c:2642
+msgid "should have two operands"
+msgstr ""
+
+#: config/tc-i960.c:2652
+msgid "'entry_num' must be absolute number in [0,31]"
+msgstr ""
+
+#: config/tc-i960.c:2661
+#, c-format
+msgid "Redefining entrynum for sysproc %s"
+msgstr ""
+
+#: config/tc-i960.c:2772
+msgid "architecture of opcode conflicts with that of earlier instruction(s)"
+msgstr ""
+
+#: config/tc-i960.c:2793
+msgid "big endian mode is not supported"
+msgstr ""
+
+#: config/tc-i960.c:2795
+#, c-format
+msgid "ignoring unrecognized .endian type `%s'"
+msgstr ""
+
+#: config/tc-i960.c:3052
+#, c-format
+msgid "leafproc symbol '%s' undefined"
+msgstr ""
+
+#: config/tc-i960.c:3062
+#, c-format
+msgid "Warning: making leafproc entries %s and %s both global\n"
+msgstr ""
+
+#: config/tc-i960.c:3169
+msgid "option --link-relax is only supported in b.out format"
+msgstr ""
+
+#: config/tc-i960.c:3212
+msgid "callj to difference of two symbols"
+msgstr ""
+
+#. Pretend that we do not recognise this option.
+#: config/tc-m32r.c:232
+#, c-format
+msgid "%s: unrecognised option: -hidden\n"
+msgstr ""
+
+#: config/tc-m32r.c:265
+msgid " M32R specific command line options:\n"
+msgstr ""
+
+#: config/tc-m32r.c:287
+msgid ""
+" -warn-unmatched-high warn when an (s)high reloc has no matching low "
+"reloc\n"
+msgstr ""
+
+#: config/tc-m32r.c:289
+msgid " -no-warn-unmatched-high do not warn about missing low relocs\n"
+msgstr ""
+
+#: config/tc-m32r.c:291
+msgid " -Wuh synonym for -warn-unmatched-high\n"
+msgstr ""
+
+#: config/tc-m32r.c:293
+msgid " -Wnuh synonym for -no-warn-unmatched-high\n"
+msgstr ""
+
+#: config/tc-m32r.c:297
+msgid " -relax create linker relaxable code\n"
+msgstr ""
+
+#: config/tc-m32r.c:299
+msgid " -cpu-desc provide runtime cpu description file\n"
+msgstr ""
+
+#: config/tc-m32r.c:429 read.c:2734 read.c:4799
+#, c-format
+msgid "symbol `%s' already defined"
+msgstr ""
+
+#: config/tc-m32r.c:700
+msgid "Instructions write to the same destination register."
+msgstr ""
+
+#: config/tc-m32r.c:708
+msgid "Instructions do not use parallel execution pipelines."
+msgstr ""
+
+#: config/tc-m32r.c:715
+msgid "Instructions share the same execution pipeline"
+msgstr ""
+
+#: config/tc-m32r.c:784 config/tc-m32r.c:870
+#, c-format
+msgid "not a 16 bit instruction '%s'"
+msgstr ""
+
+#: config/tc-m32r.c:791 config/tc-m32r.c:877 config/tc-m32r.c:1038
+#, c-format
+msgid "unknown instruction '%s'"
+msgstr ""
+
+#: config/tc-m32r.c:799 config/tc-m32r.c:884 config/tc-m32r.c:1045
+#, c-format
+msgid "instruction '%s' is for the M32RX only"
+msgstr ""
+
+#: config/tc-m32r.c:807 config/tc-m32r.c:892
+#, c-format
+msgid "instruction '%s' cannot be executed in parallel."
+msgstr ""
+
+#: config/tc-m32r.c:854 config/tc-m32r.c:917 config/tc-m32r.c:1098
+msgid "internal error: lookup/get operands failed"
+msgstr ""
+
+#: config/tc-m32r.c:902
+#, c-format
+msgid "'%s': only the NOP instruction can be issued in parallel on the m32r"
+msgstr ""
+
+#: config/tc-m32r.c:931
+#, c-format
+msgid ""
+"%s: output of 1st instruction is the same as an input to 2nd instruction - "
+"is this intentional ?"
+msgstr ""
+
+#: config/tc-m32r.c:935
+#, c-format
+msgid ""
+"%s: output of 2nd instruction is the same as an input to 1st instruction - "
+"is this intentional ?"
+msgstr ""
+
+#: config/tc-m32r.c:1264 config/tc-ppc.c:1330 config/tc-ppc.c:3534 read.c:1349
+msgid "Expected comma after symbol-name: rest of line ignored."
+msgstr ""
+
+#: config/tc-m32r.c:1273
+#, c-format
+msgid ".SCOMMon length (%ld.) <0! Ignored."
+msgstr ""
+
+#: config/tc-m32r.c:1287 config/tc-ppc.c:1352 config/tc-ppc.c:2261
+#: config/tc-ppc.c:3558
+msgid "ignoring bad alignment"
+msgstr ""
+
+#: config/tc-m32r.c:1313 config/tc-ppc.c:1363 config/tc-ppc.c:3570 read.c:1369
+#: read.c:2083
+#, c-format
+msgid "Ignoring attempt to re-define symbol `%s'."
+msgstr ""
+
+#: config/tc-m32r.c:1322
+#, c-format
+msgid "Length of .scomm \"%s\" is already %ld. Not changed to %ld."
+msgstr ""
+
+#: config/tc-m32r.c:1566
+msgid "Addend to unresolved symbol not on word boundary."
+msgstr ""
+
+#: config/tc-m32r.c:1795
+msgid "Unmatched high/shigh reloc"
+msgstr ""
+
+#: config/tc-m68k.c:636
+msgid "Unknown PC relative instruction"
+msgstr ""
+
+#: config/tc-m68k.c:764
+#, c-format
+msgid "Can not do %d byte pc-relative pic relocation"
+msgstr ""
+
+#: config/tc-m68k.c:771
+#, c-format
+msgid "Can not do %d byte pic relocation"
+msgstr ""
+
+#: config/tc-m68k.c:875 config/tc-mips.c:11891
+#, c-format
+msgid "Cannot make %s relocation PC relative"
+msgstr ""
+
+#: config/tc-m68k.c:987 config/tc-tahoe.c:1505 config/tc-vax.c:1773
+msgid "No operator"
+msgstr ""
+
+#: config/tc-m68k.c:1017 config/tc-tahoe.c:1522 config/tc-vax.c:1790
+msgid "Unknown operator"
+msgstr ""
+
+#: config/tc-m68k.c:1764
+msgid "invalid instruction for this architecture; needs "
+msgstr ""
+
+#: config/tc-m68k.c:1769
+msgid "fpu (68040, 68060 or 68881/68882)"
+msgstr ""
+
+#: config/tc-m68k.c:1772
+msgid "mmu (68030 or 68851)"
+msgstr ""
+
+#: config/tc-m68k.c:1775
+msgid "68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:1778
+msgid "68000 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:1781
+msgid "68010 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:1809
+msgid "operands mismatch"
+msgstr ""
+
+#: config/tc-m68k.c:1866 config/tc-m68k.c:1872 config/tc-m68k.c:1878
+msgid "operand out of range"
+msgstr ""
+
+#: config/tc-m68k.c:1935
+#, c-format
+msgid "Bignum too big for %c format; truncated"
+msgstr ""
+
+#: config/tc-m68k.c:2003
+msgid "displacement too large for this architecture; needs 68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:2113
+msgid ""
+"scale factor invalid on this architecture; needs cpu32 or 68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:2167
+msgid "Forcing byte displacement"
+msgstr ""
+
+#: config/tc-m68k.c:2169
+msgid "byte displacement out of range"
+msgstr ""
+
+#: config/tc-m68k.c:2216 config/tc-m68k.c:2254
+msgid "invalid operand mode for this architecture; needs 68020 or higher"
+msgstr ""
+
+#: config/tc-m68k.c:2240 config/tc-m68k.c:2274
+msgid ":b not permitted; defaulting to :w"
+msgstr ""
+
+#: config/tc-m68k.c:2356
+msgid "unsupported byte value; use a different suffix"
+msgstr ""
+
+#: config/tc-m68k.c:2370
+msgid "unknown/incorrect operand"
+msgstr ""
+
+#: config/tc-m68k.c:2403 config/tc-m68k.c:2411 config/tc-m68k.c:2418
+#: config/tc-m68k.c:2425
+msgid "out of range"
+msgstr ""
+
+#: config/tc-m68k.c:2475
+msgid "Can't use long branches on 68000/68010/5200"
+msgstr ""
+
+#: config/tc-m68k.c:2563
+msgid "Expression out of range, using 0"
+msgstr ""
+
+#: config/tc-m68k.c:2668 config/tc-m68k.c:2684
+msgid "Floating point register in register list"
+msgstr ""
+
+#: config/tc-m68k.c:2674
+msgid "Wrong register in floating-point reglist"
+msgstr ""
+
+#: config/tc-m68k.c:2690
+msgid "incorrect register in reglist"
+msgstr ""
+
+#: config/tc-m68k.c:2696
+msgid "wrong register in floating-point reglist"
+msgstr ""
+
+#: config/tc-m68k.c:2772
+msgid "failed sanity check"
+msgstr ""
+
+#. ERROR
+#: config/tc-m68k.c:3108
+msgid "Extra )"
+msgstr ""
+
+#. ERROR
+#: config/tc-m68k.c:3119
+msgid "Missing )"
+msgstr ""
+
+#: config/tc-m68k.c:3136
+msgid "Missing operand"
+msgstr ""
+
+#: config/tc-m68k.c:3427
+#, c-format
+msgid "%s -- statement `%s' ignored"
+msgstr ""
+
+#: config/tc-m68k.c:3471
+#, c-format
+msgid "Don't know how to figure width of %c in md_assemble()"
+msgstr ""
+
+#: config/tc-m68k.c:3639 config/tc-m68k.c:3675
+#, c-format
+msgid "Internal Error: Can't find %s in hash table"
+msgstr ""
+
+#: config/tc-m68k.c:3642 config/tc-m68k.c:3678
+#, c-format
+msgid "Internal Error: Can't hash %s: %s"
+msgstr ""
+
+#: config/tc-m68k.c:3804
+#, c-format
+msgid "unrecognized default cpu `%s' ???"
+msgstr ""
+
+#: config/tc-m68k.c:3816
+msgid "68040 and 68851 specified; mmu instructions may assemble incorrectly"
+msgstr ""
+
+#: config/tc-m68k.c:3836
+msgid "options for 68881 and no-68881 both given"
+msgstr ""
+
+#: config/tc-m68k.c:3838
+msgid "options for 68851 and no-68851 both given"
+msgstr ""
+
+#: config/tc-m68k.c:3909
+#, c-format
+msgid "text label `%s' aligned to odd boundary"
+msgstr ""
+
+#: config/tc-m68k.c:4126
+msgid "invalid byte branch offset"
+msgstr ""
+
+#: config/tc-m68k.c:4183
+msgid "short branch with zero offset: use :w"
+msgstr ""
+
+#: config/tc-m68k.c:4229
+msgid "Long branch offset not supported."
+msgstr ""
+
+#: config/tc-m68k.c:4290
+#, c-format
+msgid "Internal error (long PC-relative operand) for insn 0x%04x at 0x%lx"
+msgstr ""
+
+#: config/tc-m68k.c:4321
+msgid "displacement doesn't fit in one byte"
+msgstr ""
+
+#: config/tc-m68k.c:4434
+msgid "Long branch offset to extern symbol not supported."
+msgstr ""
+
+#: config/tc-m68k.c:4783 config/tc-m68k.c:4794
+msgid "expression out of range: defaulting to 1"
+msgstr ""
+
+#: config/tc-m68k.c:4826
+msgid "expression out of range: defaulting to 0"
+msgstr ""
+
+#: config/tc-m68k.c:4859 config/tc-m68k.c:4871
+#, c-format
+msgid "Can't deal with expression; defaulting to %ld"
+msgstr ""
+
+#: config/tc-m68k.c:4885
+msgid "expression doesn't fit in BYTE"
+msgstr ""
+
+#: config/tc-m68k.c:4889
+msgid "expression doesn't fit in WORD"
+msgstr ""
+
+#: config/tc-m68k.c:4982
+#, c-format
+msgid "%s: unrecognized processor name"
+msgstr ""
+
+#: config/tc-m68k.c:5047
+msgid "bad coprocessor id"
+msgstr ""
+
+#: config/tc-m68k.c:5053
+msgid "unrecognized fopt option"
+msgstr ""
+
+#: config/tc-m68k.c:5187
+#, c-format
+msgid "option `%s' may not be negated"
+msgstr ""
+
+#: config/tc-m68k.c:5198
+#, c-format
+msgid "option `%s' not recognized"
+msgstr ""
+
+#: config/tc-m68k.c:5231
+msgid "bad format of OPT NEST=depth"
+msgstr ""
+
+#: config/tc-m68k.c:5294
+msgid "missing label"
+msgstr ""
+
+#: config/tc-m68k.c:5318 config/tc-m68k.c:5347
+msgid "bad register list"
+msgstr ""
+
+#: config/tc-m68k.c:5320
+#, c-format
+msgid "bad register list: %s"
+msgstr ""
+
+#: config/tc-m68k.c:5418
+msgid "restore without save"
+msgstr ""
+
+#: config/tc-m68k.c:5595 config/tc-m68k.c:5944
+msgid "syntax error in structured control directive"
+msgstr ""
+
+#: config/tc-m68k.c:5646
+msgid "missing condition code in structured control directive"
+msgstr ""
+
+#: config/tc-m68k.c:5978
+msgid "missing then"
+msgstr ""
+
+#: config/tc-m68k.c:6060
+msgid "else without matching if"
+msgstr ""
+
+#: config/tc-m68k.c:6094
+msgid "endi without matching if"
+msgstr ""
+
+#: config/tc-m68k.c:6135
+msgid "break outside of structured loop"
+msgstr ""
+
+#: config/tc-m68k.c:6174
+msgid "next outside of structured loop"
+msgstr ""
+
+#: config/tc-m68k.c:6226
+msgid "missing ="
+msgstr ""
+
+#: config/tc-m68k.c:6264
+msgid "missing to or downto"
+msgstr ""
+
+#: config/tc-m68k.c:6300 config/tc-m68k.c:6334 config/tc-m68k.c:6544
+msgid "missing do"
+msgstr ""
+
+#: config/tc-m68k.c:6437
+msgid "endf without for"
+msgstr ""
+
+#: config/tc-m68k.c:6493
+msgid "until without repeat"
+msgstr ""
+
+#: config/tc-m68k.c:6580
+msgid "endw without while"
+msgstr ""
+
+#: config/tc-m68k.c:6696
+#, c-format
+msgid "unrecognized option `%s'"
+msgstr ""
+
+#: config/tc-m68k.c:6741
+#, c-format
+msgid "unrecognized architecture specification `%s'"
+msgstr ""
+
+#: config/tc-m68k.c:6811
+msgid ""
+"680X0 options:\n"
+"-l\t\t\tuse 1 word for refs to undefined symbols [default 2]\n"
+"-m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060\n"
+" | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -m68360\n"
+" | -mcpu32 | -m5200\n"
+"\t\t\tspecify variant of 680X0 architecture [default 68020]\n"
+"-m68881 | -m68882 | -mno-68881 | -mno-68882\n"
+"\t\t\ttarget has/lacks floating-point coprocessor\n"
+"\t\t\t[default yes for 68020, 68030, and cpu32]\n"
+msgstr ""
+
+#: config/tc-m68k.c:6821
+msgid ""
+"-m68851 | -mno-68851\n"
+"\t\t\ttarget has/lacks memory-management unit coprocessor\n"
+"\t\t\t[default yes for 68020 and up]\n"
+"-pic, -k\t\tgenerate position independent code\n"
+"-S\t\t\tturn jbsr into jsr\n"
+"--register-prefix-optional\n"
+"\t\t\trecognize register names without prefix character\n"
+"--bitwise-or\t\tdo not treat `|' as a comment character\n"
+msgstr ""
+
+#: config/tc-m68k.c:6830
+msgid ""
+"--base-size-default-16\tbase reg without size is 16 bits\n"
+"--base-size-default-32\tbase reg without size is 32 bits (default)\n"
+"--disp-size-default-16\tdisplacement with unknown size is 16 bits\n"
+"--disp-size-default-32\tdisplacement with unknown size is 32 bits (default)\n"
+msgstr ""
+
+#: config/tc-m68k.c:6865
+#, c-format
+msgid "Error %s in %s\n"
+msgstr ""
+
+#: config/tc-m68k.c:6869
+#, c-format
+msgid "Opcode(%d.%s): "
+msgstr ""
+
+#: config/tc-m88k.c:206
+#, c-format
+msgid "Can't hash instruction '%s':%s"
+msgstr ""
+
+#: config/tc-m88k.c:258
+#, c-format
+msgid "Invalid mnemonic '%s'"
+msgstr ""
+
+#: config/tc-m88k.c:278
+msgid "Parameter syntax error"
+msgstr ""
+
+#: config/tc-m88k.c:333
+msgid "Unknown relocation type"
+msgstr ""
+
+#. Having this here repeats the warning somtimes.
+#. But can't we stand that?
+#: config/tc-m88k.c:446
+msgid "Use of obsolete instruction"
+msgstr ""
+
+#: config/tc-m88k.c:563
+msgid "Expression truncated to 16 bits"
+msgstr ""
+
+#: config/tc-m88k.c:629 config/tc-m88k.c:651
+msgid "Expression truncated to 5 bits"
+msgstr ""
+
+#: config/tc-m88k.c:873
+msgid "Expression truncated to 9 bits"
+msgstr ""
+
+#: config/tc-m88k.c:895
+msgid "Removed lower 2 bits of expression"
+msgstr ""
+
+#: config/tc-m88k.c:1034
+msgid "Bad relocation type"
+msgstr ""
+
+#: config/tc-m88k.c:1047
+msgid "md_number_to_disp not defined"
+msgstr ""
+
+#: config/tc-m88k.c:1057
+msgid "md_number_to_field not defined"
+msgstr ""
+
+#: config/tc-m88k.c:1170
+msgid "Relaxation should never occur"
+msgstr ""
+
+#: config/tc-m88k.c:1267 config/tc-sparc.c:3024 read.c:1940
+#, c-format
+msgid "BSS length (%d.) <0! Ignored."
+msgstr ""
+
+#: config/tc-m88k.c:1311
+#, c-format
+msgid "Ignoring attempt to re-define symbol %s."
+msgstr ""
+
+#: config/tc-mcore.c:273
+#, c-format
+msgid "register expected, but saw '%.6s'"
+msgstr ""
+
+#: config/tc-mcore.c:357
+#, c-format
+msgid "control register expected, but saw '%.6s'"
+msgstr ""
+
+#: config/tc-mcore.c:513
+msgid "more than 65K literal pools"
+msgstr ""
+
+#: config/tc-mcore.c:567
+msgid "missing ']'"
+msgstr ""
+
+#: config/tc-mcore.c:607
+msgid "operand must be a constant"
+msgstr ""
+
+#: config/tc-mcore.c:609
+#, c-format
+msgid "operand must be absolute in range %d..%d, not %d"
+msgstr ""
+
+#: config/tc-mcore.c:646
+msgid "operand must be a multiple of 4"
+msgstr ""
+
+#: config/tc-mcore.c:653
+msgid "operand must be a multiple of 2"
+msgstr ""
+
+#: config/tc-mcore.c:667 config/tc-mcore.c:1177 config/tc-mcore.c:1231
+msgid "base register expected"
+msgstr ""
+
+#: config/tc-mcore.c:716
+#, c-format
+msgid "unknown opcode \"%s\""
+msgstr ""
+
+#: config/tc-mcore.c:759
+msgid "invalid register: r15 illegal"
+msgstr ""
+
+#: config/tc-mcore.c:808
+msgid "M340 specific opcode used when assembling for M210"
+msgstr ""
+
+#: config/tc-mcore.c:827 config/tc-mcore.c:866 config/tc-mcore.c:885
+#: config/tc-mcore.c:904 config/tc-mcore.c:931 config/tc-mcore.c:960
+#: config/tc-mcore.c:997 config/tc-mcore.c:1032 config/tc-mcore.c:1051
+#: config/tc-mcore.c:1070 config/tc-mcore.c:1102 config/tc-mcore.c:1124
+#: config/tc-mcore.c:1180 config/tc-mcore.c:1234 config/tc-mcore.c:1269
+#: config/tc-mcore.c:1323 config/tc-mcore.c:1345 config/tc-mcore.c:1368
+msgid "second operand missing"
+msgstr ""
+
+#: config/tc-mcore.c:842
+msgid "destination register must be r1"
+msgstr ""
+
+#: config/tc-mcore.c:863
+msgid "source register must be r1"
+msgstr ""
+
+#: config/tc-mcore.c:926 config/tc-mcore.c:983
+msgid "immediate is not a power of two"
+msgstr ""
+
+#: config/tc-mcore.c:954
+msgid "translating bgeni to movi"
+msgstr ""
+
+#: config/tc-mcore.c:991
+msgid "translating mgeni to movi"
+msgstr ""
+
+#: config/tc-mcore.c:1023
+msgid "translating bmaski to movi"
+msgstr ""
+
+#: config/tc-mcore.c:1097
+#, c-format
+msgid "displacement too large (%d)"
+msgstr ""
+
+#: config/tc-mcore.c:1111
+msgid "Invalid register: r0 and r15 illegal"
+msgstr ""
+
+#: config/tc-mcore.c:1138
+msgid "bad starting register: r0 and r15 invalid"
+msgstr ""
+
+#: config/tc-mcore.c:1151
+msgid "ending register must be r15"
+msgstr ""
+
+#: config/tc-mcore.c:1171
+msgid "bad base register: must be r0"
+msgstr ""
+
+#: config/tc-mcore.c:1189
+msgid "first register must be r4"
+msgstr ""
+
+#: config/tc-mcore.c:1200
+msgid "last register must be r7"
+msgstr ""
+
+#: config/tc-mcore.c:1237
+msgid "reg-reg expected"
+msgstr ""
+
+#: config/tc-mcore.c:1342
+msgid "second operand must be 1"
+msgstr ""
+
+#: config/tc-mcore.c:1363
+msgid "zero used as immediate value"
+msgstr ""
+
+#: config/tc-mcore.c:1374
+#, c-format
+msgid "unimplemented opcode \"%s\""
+msgstr ""
+
+#: config/tc-mcore.c:1444 config/tc-w65.c:856
+msgid "Bad call to MD_NTOF()"
+msgstr ""
+
+#: config/tc-mcore.c:1513
+#, c-format
+msgid "unrecognised cpu type '%s'"
+msgstr ""
+
+#: config/tc-mcore.c:1535
+msgid ""
+"MCORE specific options:\n"
+" -{no-}jsri2bsr\t disable/enable jsri to bsr transformation (def: on)\n"
+" -{no-}sifilter\t disable/enable silicon filter behavior (def: off)\n"
+" -relax\t\t alter jump instructions for long displacements\n"
+msgstr ""
+
diff --git a/gas/read.c b/gas/read.c
new file mode 100644
index 00000000000..7fee24161eb
--- /dev/null
+++ b/gas/read.c
@@ -0,0 +1,5054 @@
+/* read.c - read a source file -
+ Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#if 0
+#define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
+ change this a bit. But then, GNU isn't
+ spozed to run on your machine anyway.
+ (RMS is so shortsighted sometimes.)
+ */
+#else
+#define MASK_CHAR ((int)(unsigned char)-1)
+#endif
+
+
+/* This is the largest known floating point format (for now). It will
+ grow when we do 4361 style flonums. */
+
+#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
+
+/* Routines that read assembler source text to build spagetti in memory.
+ Another group of these functions is in the expr.c module. */
+
+/* for isdigit() */
+#include <ctype.h>
+
+#include "as.h"
+#include "subsegs.h"
+#include "sb.h"
+#include "macro.h"
+#include "obstack.h"
+#include "listing.h"
+#include "ecoff.h"
+
+#ifndef TC_START_LABEL
+#define TC_START_LABEL(x,y) (x==':')
+#endif
+
+/* The NOP_OPCODE is for the alignment fill value.
+ * fill it a nop instruction so that the disassembler does not choke
+ * on it
+ */
+#ifndef NOP_OPCODE
+#define NOP_OPCODE 0x00
+#endif
+
+char *input_line_pointer; /*->next char of source file to parse. */
+
+#if BITS_PER_CHAR != 8
+/* The following table is indexed by[(char)] and will break if
+ a char does not have exactly 256 states (hopefully 0:255!)! */
+die horribly;
+#endif
+
+#ifndef LEX_AT
+/* The m88k unfortunately uses @ as a label beginner. */
+#define LEX_AT 0
+#endif
+
+#ifndef LEX_BR
+/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */
+#define LEX_BR 0
+#endif
+
+#ifndef LEX_PCT
+/* The Delta 68k assembler permits % inside label names. */
+#define LEX_PCT 0
+#endif
+
+#ifndef LEX_QM
+/* The PowerPC Windows NT assemblers permits ? inside label names. */
+#define LEX_QM 0
+#endif
+
+#ifndef LEX_DOLLAR
+/* The a29k assembler does not permits labels to start with $. */
+#define LEX_DOLLAR 3
+#endif
+
+#ifndef LEX_TILDE
+/* The Delta 68k assembler permits ~ at start of label names. */
+#define LEX_TILDE 0
+#endif
+
+/* used by is_... macros. our ctype[] */
+char lex_type[256] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
+ 0, 0, 0, 0, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
+ LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
+};
+
+
+/*
+ * In: a character.
+ * Out: 1 if this character ends a line.
+ */
+#define Z_ (0)
+char is_end_of_line[256] =
+{
+#ifdef CR_EOL
+ 99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, 99, Z_, Z_, /* @abcdefghijklmno */
+#else
+ 99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, Z_, /* @abcdefghijklmno */
+#endif
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+#ifdef TC_HPPA
+ Z_,99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* _!"#$%&'()*+,-./ */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* 0123456789:;<=>? */
+#else
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, /* 0123456789:;<=>? */
+#endif
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+ Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */
+};
+#undef Z_
+
+/* Functions private to this file. */
+
+static char *buffer; /* 1st char of each buffer of lines is here. */
+static char *buffer_limit; /*->1 + last char in buffer. */
+
+/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 in the
+ tc-<CPU>.h file. See the "Porting GAS" section of the internals manual. */
+int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+
+static char *old_buffer; /* JF a hack */
+static char *old_input;
+static char *old_limit;
+
+/* Variables for handling include file directory table. */
+
+char **include_dirs; /* Table of pointers to directories to
+ search for .include's */
+int include_dir_count; /* How many are in the table */
+int include_dir_maxlen = 1;/* Length of longest in table */
+
+#ifndef WORKING_DOT_WORD
+struct broken_word *broken_words;
+int new_broken_words;
+#endif
+
+/* The current offset into the absolute section. We don't try to
+ build frags in the absolute section, since no data can be stored
+ there. We just keep track of the current offset. */
+addressT abs_section_offset;
+
+/* If this line had an MRI style label, it is stored in this variable.
+ This is used by some of the MRI pseudo-ops. */
+symbolS *line_label;
+
+/* This global variable is used to support MRI common sections. We
+ translate such sections into a common symbol. This variable is
+ non-NULL when we are in an MRI common section. */
+symbolS *mri_common_symbol;
+
+/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we
+ need to align to an even byte boundary unless the next pseudo-op is
+ dc.b, ds.b, or dcb.b. This variable is set to 1 if an alignment
+ may be needed. */
+static int mri_pending_align;
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+/* This variable is set to be non-zero if the next string we see might
+ be the name of the source file in DWARF debugging information. See
+ the comment in emit_expr for the format we look for. */
+static int dwarf_file_string;
+#endif
+#endif
+
+static void cons_worker PARAMS ((int, int));
+static int scrub_from_string PARAMS ((char **));
+static void do_align PARAMS ((int, char *, int, int));
+static void s_align PARAMS ((int, int));
+static int hex_float PARAMS ((int, char *));
+static void do_org PARAMS ((segT, expressionS *, int));
+char *demand_copy_string PARAMS ((int *lenP));
+static segT get_segmented_expression PARAMS ((expressionS *expP));
+static segT get_known_segmented_expression PARAMS ((expressionS * expP));
+static void pobegin PARAMS ((void));
+static int get_line_sb PARAMS ((sb *));
+static void generate_file_debug PARAMS ((void));
+
+
+void
+read_begin ()
+{
+ const char *p;
+
+ pobegin ();
+ obj_read_begin_hook ();
+
+ /* Something close -- but not too close -- to a multiple of 1024.
+ The debugging malloc I'm using has 24 bytes of overhead. */
+ obstack_begin (&notes, chunksize);
+ obstack_begin (&cond_obstack, chunksize);
+
+ /* Use machine dependent syntax */
+ for (p = line_separator_chars; *p; p++)
+ is_end_of_line[(unsigned char) *p] = 1;
+ /* Use more. FIXME-SOMEDAY. */
+
+ if (flag_mri)
+ lex_type['?'] = 3;
+}
+
+/* set up pseudo-op tables */
+
+static struct hash_control *po_hash;
+
+static const pseudo_typeS potable[] =
+{
+ {"abort", s_abort, 0},
+ {"align", s_align_ptwo, 0},
+ {"ascii", stringer, 0},
+ {"asciz", stringer, 1},
+ {"balign", s_align_bytes, 0},
+ {"balignw", s_align_bytes, -2},
+ {"balignl", s_align_bytes, -4},
+/* block */
+ {"byte", cons, 1},
+ {"comm", s_comm, 0},
+ {"common", s_mri_common, 0},
+ {"common.s", s_mri_common, 1},
+ {"data", s_data, 0},
+ {"dc", cons, 2},
+ {"dc.b", cons, 1},
+ {"dc.d", float_cons, 'd'},
+ {"dc.l", cons, 4},
+ {"dc.s", float_cons, 'f'},
+ {"dc.w", cons, 2},
+ {"dc.x", float_cons, 'x'},
+ {"dcb", s_space, 2},
+ {"dcb.b", s_space, 1},
+ {"dcb.d", s_float_space, 'd'},
+ {"dcb.l", s_space, 4},
+ {"dcb.s", s_float_space, 'f'},
+ {"dcb.w", s_space, 2},
+ {"dcb.x", s_float_space, 'x'},
+ {"ds", s_space, 2},
+ {"ds.b", s_space, 1},
+ {"ds.d", s_space, 8},
+ {"ds.l", s_space, 4},
+ {"ds.p", s_space, 12},
+ {"ds.s", s_space, 4},
+ {"ds.w", s_space, 2},
+ {"ds.x", s_space, 12},
+ {"debug", s_ignore, 0},
+#ifdef S_SET_DESC
+ {"desc", s_desc, 0},
+#endif
+/* dim */
+ {"double", float_cons, 'd'},
+/* dsect */
+ {"eject", listing_eject, 0}, /* Formfeed listing */
+ {"else", s_else, 0},
+ {"elsec", s_else, 0},
+ {"end", s_end, 0},
+ {"endc", s_endif, 0},
+ {"endfunc", s_func, 1},
+ {"endif", s_endif, 0},
+/* endef */
+ {"equ", s_set, 0},
+ {"equiv", s_set, 1},
+ {"err", s_err, 0},
+ {"exitm", s_mexit, 0},
+/* extend */
+ {"extern", s_ignore, 0}, /* We treat all undef as ext */
+ {"appfile", s_app_file, 1},
+ {"appline", s_app_line, 0},
+ {"fail", s_fail, 0},
+ {"file", s_app_file, 0},
+ {"fill", s_fill, 0},
+ {"float", float_cons, 'f'},
+ {"format", s_ignore, 0},
+ {"func", s_func, 0},
+ {"global", s_globl, 0},
+ {"globl", s_globl, 0},
+ {"hword", cons, 2},
+ {"if", s_if, (int) O_ne},
+ {"ifc", s_ifc, 0},
+ {"ifdef", s_ifdef, 0},
+ {"ifeq", s_if, (int) O_eq},
+ {"ifeqs", s_ifeqs, 0},
+ {"ifge", s_if, (int) O_ge},
+ {"ifgt", s_if, (int) O_gt},
+ {"ifle", s_if, (int) O_le},
+ {"iflt", s_if, (int) O_lt},
+ {"ifnc", s_ifc, 1},
+ {"ifndef", s_ifdef, 1},
+ {"ifne", s_if, (int) O_ne},
+ {"ifnes", s_ifeqs, 1},
+ {"ifnotdef", s_ifdef, 1},
+ {"include", s_include, 0},
+ {"int", cons, 4},
+ {"irp", s_irp, 0},
+ {"irep", s_irp, 0},
+ {"irpc", s_irp, 1},
+ {"irepc", s_irp, 1},
+ {"lcomm", s_lcomm, 0},
+ {"lflags", listing_flags, 0}, /* Listing flags */
+ {"linkonce", s_linkonce, 0},
+ {"list", listing_list, 1}, /* Turn listing on */
+ {"llen", listing_psize, 1},
+ {"long", cons, 4},
+ {"lsym", s_lsym, 0},
+ {"macro", s_macro, 0},
+ {"mexit", s_mexit, 0},
+ {"mri", s_mri, 0},
+ {".mri", s_mri, 0}, /* Special case so .mri works in MRI mode. */
+ {"name", s_ignore, 0},
+ {"noformat", s_ignore, 0},
+ {"nolist", listing_list, 0}, /* Turn listing off */
+ {"nopage", listing_nopage, 0},
+ {"octa", cons, 16},
+ {"offset", s_struct, 0},
+ {"org", s_org, 0},
+ {"p2align", s_align_ptwo, 0},
+ {"p2alignw", s_align_ptwo, -2},
+ {"p2alignl", s_align_ptwo, -4},
+ {"page", listing_eject, 0},
+ {"plen", listing_psize, 0},
+ {"print", s_print, 0},
+ {"psize", listing_psize, 0}, /* set paper size */
+ {"purgem", s_purgem, 0},
+ {"quad", cons, 8},
+ {"rep", s_rept, 0},
+ {"rept", s_rept, 0},
+ {"rva", s_rva, 4},
+ {"sbttl", listing_title, 1}, /* Subtitle of listing */
+/* scl */
+/* sect */
+ {"set", s_set, 0},
+ {"short", cons, 2},
+ {"single", float_cons, 'f'},
+/* size */
+ {"space", s_space, 0},
+ {"skip", s_space, 0},
+ {"sleb128", s_leb128, 1},
+ {"spc", s_ignore, 0},
+ {"stabd", s_stab, 'd'},
+ {"stabn", s_stab, 'n'},
+ {"stabs", s_stab, 's'},
+ {"string", stringer, 1},
+ {"struct", s_struct, 0},
+/* tag */
+ {"text", s_text, 0},
+
+ /* This is for gcc to use. It's only just been added (2/94), so gcc
+ won't be able to use it for a while -- probably a year or more.
+ But once this has been released, check with gcc maintainers
+ before deleting it or even changing the spelling. */
+ {"this_GCC_requires_the_GNU_assembler", s_ignore, 0},
+ /* If we're folding case -- done for some targets, not necessarily
+ all -- the above string in an input file will be converted to
+ this one. Match it either way... */
+ {"this_gcc_requires_the_gnu_assembler", s_ignore, 0},
+
+ {"title", listing_title, 0}, /* Listing title */
+ {"ttl", listing_title, 0},
+/* type */
+ {"uleb128", s_leb128, 0},
+/* use */
+/* val */
+ {"xcom", s_comm, 0},
+ {"xdef", s_globl, 0},
+ {"xref", s_ignore, 0},
+ {"xstabs", s_xstab, 's'},
+ {"word", cons, 2},
+ {"zero", s_space, 0},
+ {NULL} /* end sentinel */
+};
+
+static int pop_override_ok = 0;
+static const char *pop_table_name;
+
+void
+pop_insert (table)
+ const pseudo_typeS *table;
+{
+ const char *errtxt;
+ const pseudo_typeS *pop;
+ for (pop = table; pop->poc_name; pop++)
+ {
+ errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
+ if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists")))
+ as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name,
+ errtxt);
+ }
+}
+
+#ifndef md_pop_insert
+#define md_pop_insert() pop_insert(md_pseudo_table)
+#endif
+
+#ifndef obj_pop_insert
+#define obj_pop_insert() pop_insert(obj_pseudo_table)
+#endif
+
+static void
+pobegin ()
+{
+ po_hash = hash_new ();
+
+ /* Do the target-specific pseudo ops. */
+ pop_table_name = "md";
+ md_pop_insert ();
+
+ /* Now object specific. Skip any that were in the target table. */
+ pop_table_name = "obj";
+ pop_override_ok = 1;
+ obj_pop_insert ();
+
+ /* Now portable ones. Skip any that we've seen already. */
+ pop_table_name = "standard";
+ pop_insert (potable);
+}
+
+#define HANDLE_CONDITIONAL_ASSEMBLY() \
+ if (ignore_input ()) \
+ { \
+ while (! is_end_of_line[(unsigned char) *input_line_pointer++]) \
+ if (input_line_pointer == buffer_limit) \
+ break; \
+ continue; \
+ }
+
+
+/* This function is used when scrubbing the characters between #APP
+ and #NO_APP. */
+
+static char *scrub_string;
+static char *scrub_string_end;
+
+static int
+scrub_from_string (from)
+ char **from;
+{
+ int size;
+
+ *from = scrub_string;
+ size = scrub_string_end - scrub_string;
+ scrub_string = scrub_string_end;
+ return size;
+}
+
+/* read_a_source_file()
+ *
+ * We read the file, putting things into a web that
+ * represents what we have been reading.
+ */
+void
+read_a_source_file (name)
+ char *name;
+{
+ register char c;
+ register char *s; /* string of symbol, '\0' appended */
+ register int temp;
+ pseudo_typeS *pop;
+
+ buffer = input_scrub_new_file (name);
+
+ listing_file (name);
+ listing_newline (NULL);
+ register_dependency (name);
+
+ /* Generate debugging information before we've read anything in to denote
+ this file as the "main" source file and not a subordinate one
+ (e.g. N_SO vs N_SOL in stabs). */
+ generate_file_debug ();
+
+ while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
+ { /* We have another line to parse. */
+ know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
+ contin: /* JF this goto is my fault I admit it.
+ Someone brave please re-write the whole
+ input section here? Pleeze??? */
+ while (input_line_pointer < buffer_limit)
+ {
+ /* We have more of this buffer to parse. */
+
+ /*
+ * We now have input_line_pointer->1st char of next line.
+ * If input_line_pointer [-1] == '\n' then we just
+ * scanned another line: so bump line counters.
+ */
+ if (is_end_of_line[(unsigned char) input_line_pointer[-1]])
+ {
+#ifdef md_start_line_hook
+ md_start_line_hook ();
+#endif
+
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+
+ line_label = NULL;
+
+ if (flag_m68k_mri
+#ifdef LABELS_WITHOUT_COLONS
+ || 1
+#endif
+ )
+ {
+ /* Text at the start of a line must be a label, we
+ run down and stick a colon in. */
+ if (is_name_beginner (*input_line_pointer))
+ {
+ char *line_start = input_line_pointer;
+ char c;
+ int mri_line_macro;
+
+ LISTING_NEWLINE ();
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ c = get_symbol_end ();
+
+ /* In MRI mode, the EQU and MACRO pseudoops must
+ be handled specially. */
+ mri_line_macro = 0;
+ if (flag_m68k_mri)
+ {
+ char *rest = input_line_pointer + 1;
+
+ if (*rest == ':')
+ ++rest;
+ if (*rest == ' ' || *rest == '\t')
+ ++rest;
+ if ((strncasecmp (rest, "EQU", 3) == 0
+ || strncasecmp (rest, "SET", 3) == 0)
+ && (rest[3] == ' ' || rest[3] == '\t'))
+ {
+ input_line_pointer = rest + 3;
+ equals (line_start,
+ strncasecmp (rest, "SET", 3) == 0);
+ continue;
+ }
+ if (strncasecmp (rest, "MACRO", 5) == 0
+ && (rest[5] == ' '
+ || rest[5] == '\t'
+ || is_end_of_line[(unsigned char) rest[5]]))
+ mri_line_macro = 1;
+ }
+
+ /* In MRI mode, we need to handle the MACRO
+ pseudo-op specially: we don't want to put the
+ symbol in the symbol table. */
+ if (! mri_line_macro)
+ line_label = colon (line_start);
+ else
+ line_label = symbol_create (line_start,
+ absolute_section,
+ (valueT) 0,
+ &zero_address_frag);
+
+ *input_line_pointer = c;
+ if (c == ':')
+ input_line_pointer++;
+ }
+ }
+ }
+
+ /*
+ * We are at the begining of a line, or similar place.
+ * We expect a well-formed assembler statement.
+ * A "symbol-name:" is a statement.
+ *
+ * Depending on what compiler is used, the order of these tests
+ * may vary to catch most common case 1st.
+ * Each test is independent of all other tests at the (top) level.
+ * PLEASE make a compiler that doesn't use this assembler.
+ * It is crufty to waste a compiler's time encoding things for this
+ * assembler, which then wastes more time decoding it.
+ * (And communicating via (linear) files is silly!
+ * If you must pass stuff, please pass a tree!)
+ */
+ if ((c = *input_line_pointer++) == '\t'
+ || c == ' '
+ || c == '\f'
+ || c == 0)
+ {
+ c = *input_line_pointer++;
+ }
+ know (c != ' '); /* No further leading whitespace. */
+
+#ifndef NO_LISTING
+ /* If listing is on, and we are expanding a macro, then give
+ the listing code the contents of the expanded line. */
+ if (listing)
+ {
+ if ((listing & LISTING_MACEXP) && macro_nest > 0)
+ {
+ char *copy;
+ int len;
+
+ /* Find the end of the current expanded macro line. */
+ for (s = input_line_pointer-1; *s ; ++s)
+ if (is_end_of_line[(unsigned char) *s])
+ break;
+
+ /* Copy it for safe keeping. Also give an indication of
+ how much macro nesting is involved at this point. */
+ len = s - (input_line_pointer-1);
+ copy = (char *) xmalloc (len + macro_nest + 2);
+ memset (copy, '>', macro_nest);
+ copy[macro_nest] = ' ';
+ memcpy (copy + macro_nest + 1, input_line_pointer-1, len);
+ copy[macro_nest+1+len] = '\0';
+
+ /* Install the line with the listing facility. */
+ listing_newline (copy);
+ }
+ else
+ listing_newline (NULL);
+ }
+#endif
+
+ /*
+ * C is the 1st significant character.
+ * Input_line_pointer points after that character.
+ */
+ if (is_name_beginner (c))
+ {
+ /* want user-defined label or pseudo/opcode */
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ s = --input_line_pointer;
+ c = get_symbol_end (); /* name's delimiter */
+ /*
+ * C is character after symbol.
+ * That character's place in the input line is now '\0'.
+ * S points to the beginning of the symbol.
+ * [In case of pseudo-op, s->'.'.]
+ * Input_line_pointer->'\0' where c was.
+ */
+ if (TC_START_LABEL(c, input_line_pointer))
+ {
+ if (flag_m68k_mri)
+ {
+ char *rest = input_line_pointer + 1;
+
+ /* In MRI mode, \tsym: set 0 is permitted. */
+
+ if (*rest == ':')
+ ++rest;
+ if (*rest == ' ' || *rest == '\t')
+ ++rest;
+ if ((strncasecmp (rest, "EQU", 3) == 0
+ || strncasecmp (rest, "SET", 3) == 0)
+ && (rest[3] == ' ' || rest[3] == '\t'))
+ {
+ input_line_pointer = rest + 3;
+ equals (s, 1);
+ continue;
+ }
+ }
+
+ line_label = colon (s); /* user-defined label */
+ *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
+ /* Input_line_pointer->after ':'. */
+ SKIP_WHITESPACE ();
+
+
+ }
+ else if (c == '='
+ || ((c == ' ' || c == '\t')
+ && input_line_pointer[1] == '='
+#ifdef TC_EQUAL_IN_INSN
+ && ! TC_EQUAL_IN_INSN (c, input_line_pointer)
+#endif
+ ))
+ {
+ equals (s, 1);
+ demand_empty_rest_of_line ();
+ }
+ else
+ { /* expect pseudo-op or machine instruction */
+ pop = NULL;
+
+#define IGNORE_OPCODE_CASE
+#ifdef IGNORE_OPCODE_CASE
+ {
+ char *s2 = s;
+ while (*s2)
+ {
+ if (isupper ((unsigned char) *s2))
+ *s2 = tolower (*s2);
+ s2++;
+ }
+ }
+#endif
+
+ if (flag_m68k_mri
+#ifdef NO_PSEUDO_DOT
+ || 1
+#endif
+ )
+ {
+ /* The MRI assembler and the m88k use pseudo-ops
+ without a period. */
+ pop = (pseudo_typeS *) hash_find (po_hash, s);
+ if (pop != NULL && pop->poc_handler == NULL)
+ pop = NULL;
+ }
+
+ if (pop != NULL
+ || (! flag_m68k_mri && *s == '.'))
+ {
+ /*
+ * PSEUDO - OP.
+ *
+ * WARNING: c has next char, which may be end-of-line.
+ * We lookup the pseudo-op table with s+1 because we
+ * already know that the pseudo-op begins with a '.'.
+ */
+
+ if (pop == NULL)
+ pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
+
+ /* In MRI mode, we may need to insert an
+ automatic alignment directive. What a hack
+ this is. */
+ if (mri_pending_align
+ && (pop == NULL
+ || ! ((pop->poc_handler == cons
+ && pop->poc_val == 1)
+ || (pop->poc_handler == s_space
+ && pop->poc_val == 1)
+#ifdef tc_conditional_pseudoop
+ || tc_conditional_pseudoop (pop)
+#endif
+ || pop->poc_handler == s_if
+ || pop->poc_handler == s_ifdef
+ || pop->poc_handler == s_ifc
+ || pop->poc_handler == s_ifeqs
+ || pop->poc_handler == s_else
+ || pop->poc_handler == s_endif
+ || pop->poc_handler == s_globl
+ || pop->poc_handler == s_ignore)))
+ {
+ do_align (1, (char *) NULL, 0, 0);
+ mri_pending_align = 0;
+ if (line_label != NULL)
+ {
+ line_label->sy_frag = frag_now;
+ S_SET_VALUE (line_label, frag_now_fix ());
+ }
+ }
+
+ /* Print the error msg now, while we still can */
+ if (pop == NULL)
+ {
+ as_bad (_("Unknown pseudo-op: `%s'"), s);
+ *input_line_pointer = c;
+ s_ignore (0);
+ continue;
+ }
+
+ /* Put it back for error messages etc. */
+ *input_line_pointer = c;
+ /* The following skip of whitespace is compulsory.
+ A well shaped space is sometimes all that separates
+ keyword from operands. */
+ if (c == ' ' || c == '\t')
+ input_line_pointer++;
+ /*
+ * Input_line is restored.
+ * Input_line_pointer->1st non-blank char
+ * after pseudo-operation.
+ */
+ (*pop->poc_handler) (pop->poc_val);
+
+ /* If that was .end, just get out now. */
+ if (pop->poc_handler == s_end)
+ goto quit;
+ }
+ else
+ {
+ int inquote = 0;
+
+ /* WARNING: c has char, which may be end-of-line. */
+ /* Also: input_line_pointer->`\0` where c was. */
+ *input_line_pointer = c;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer]
+ || inquote
+#ifdef TC_EOL_IN_INSN
+ || TC_EOL_IN_INSN (input_line_pointer)
+#endif
+ )
+ {
+ if (flag_m68k_mri && *input_line_pointer == '\'')
+ inquote = ! inquote;
+ input_line_pointer++;
+ }
+
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ generate_lineno_debug ();
+
+ if (macro_defined)
+ {
+ sb out;
+ const char *err;
+
+ if (check_macro (s, &out, '\0', &err))
+ {
+ if (err != NULL)
+ as_bad (err);
+ *input_line_pointer++ = c;
+ input_scrub_include_sb (&out,
+ input_line_pointer);
+ sb_kill (&out);
+ buffer_limit =
+ input_scrub_next_buffer (&input_line_pointer);
+ continue;
+ }
+ }
+
+ if (mri_pending_align)
+ {
+ do_align (1, (char *) NULL, 0, 0);
+ mri_pending_align = 0;
+ if (line_label != NULL)
+ {
+ line_label->sy_frag = frag_now;
+ S_SET_VALUE (line_label, frag_now_fix ());
+ }
+ }
+
+ md_assemble (s); /* Assemble 1 instruction. */
+
+ *input_line_pointer++ = c;
+
+ /* We resume loop AFTER the end-of-line from
+ this instruction. */
+ } /* if (*s=='.') */
+ } /* if c==':' */
+ continue;
+ } /* if (is_name_beginner(c) */
+
+
+ /* Empty statement? */
+ if (is_end_of_line[(unsigned char) c])
+ continue;
+
+ if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB)
+ && isdigit ((unsigned char) c))
+ {
+ /* local label ("4:") */
+ char *backup = input_line_pointer;
+
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+ temp = c - '0';
+
+ while (isdigit ((unsigned char) *input_line_pointer))
+ {
+ temp = (temp * 10) + *input_line_pointer - '0';
+ ++input_line_pointer;
+ } /* read the whole number */
+
+ if (LOCAL_LABELS_DOLLAR
+ && *input_line_pointer == '$'
+ && *(input_line_pointer + 1) == ':')
+ {
+ input_line_pointer += 2;
+
+ if (dollar_label_defined (temp))
+ {
+ as_fatal (_("label \"%d$\" redefined"), temp);
+ }
+
+ define_dollar_label (temp);
+ colon (dollar_label_name (temp, 0));
+ continue;
+ }
+
+ if (LOCAL_LABELS_FB
+ && *input_line_pointer++ == ':')
+ {
+ fb_label_instance_inc (temp);
+ colon (fb_label_name (temp, 0));
+ continue;
+ }
+
+ input_line_pointer = backup;
+ } /* local label ("4:") */
+
+ if (c && strchr (line_comment_chars, c))
+ { /* Its a comment. Better say APP or NO_APP */
+ char *ends;
+ char *new_buf;
+ char *new_tmp;
+ unsigned int new_length;
+ char *tmp_buf = 0;
+
+ bump_line_counters ();
+ s = input_line_pointer;
+ if (strncmp (s, "APP\n", 4))
+ continue; /* We ignore it */
+ s += 4;
+
+ ends = strstr (s, "#NO_APP\n");
+
+ if (!ends)
+ {
+ unsigned int tmp_len;
+ unsigned int num;
+
+ /* The end of the #APP wasn't in this buffer. We
+ keep reading in buffers until we find the #NO_APP
+ that goes with this #APP There is one. The specs
+ guarentee it. . . */
+ tmp_len = buffer_limit - s;
+ tmp_buf = xmalloc (tmp_len + 1);
+ memcpy (tmp_buf, s, tmp_len);
+ do
+ {
+ new_tmp = input_scrub_next_buffer (&buffer);
+ if (!new_tmp)
+ break;
+ else
+ buffer_limit = new_tmp;
+ input_line_pointer = buffer;
+ ends = strstr (buffer, "#NO_APP\n");
+ if (ends)
+ num = ends - buffer;
+ else
+ num = buffer_limit - buffer;
+
+ tmp_buf = xrealloc (tmp_buf, tmp_len + num);
+ memcpy (tmp_buf + tmp_len, buffer, num);
+ tmp_len += num;
+ }
+ while (!ends);
+
+ input_line_pointer = ends ? ends + 8 : NULL;
+
+ s = tmp_buf;
+ ends = s + tmp_len;
+
+ }
+ else
+ {
+ input_line_pointer = ends + 8;
+ }
+
+ scrub_string = s;
+ scrub_string_end = ends;
+
+ new_length = ends - s;
+ new_buf = (char *) xmalloc (new_length);
+ new_tmp = new_buf;
+ for (;;)
+ {
+ int space;
+ int size;
+
+ space = (new_buf + new_length) - new_tmp;
+ size = do_scrub_chars (scrub_from_string, new_tmp, space);
+
+ if (size < space)
+ {
+ new_tmp += size;
+ break;
+ }
+
+ new_buf = xrealloc (new_buf, new_length + 100);
+ new_tmp = new_buf + new_length;
+ new_length += 100;
+ }
+
+ if (tmp_buf)
+ free (tmp_buf);
+ old_buffer = buffer;
+ old_input = input_line_pointer;
+ old_limit = buffer_limit;
+ buffer = new_buf;
+ input_line_pointer = new_buf;
+ buffer_limit = new_tmp;
+ continue;
+ }
+
+ HANDLE_CONDITIONAL_ASSEMBLY ();
+
+#ifdef tc_unrecognized_line
+ if (tc_unrecognized_line (c))
+ continue;
+#endif
+
+ /* as_warn("Junk character %d.",c); Now done by ignore_rest */
+ input_line_pointer--; /* Report unknown char as ignored. */
+ ignore_rest_of_line ();
+ } /* while (input_line_pointer<buffer_limit) */
+
+#ifdef md_after_pass_hook
+ md_after_pass_hook ();
+#endif
+
+ if (old_buffer)
+ {
+ free (buffer);
+ bump_line_counters ();
+ if (old_input != 0)
+ {
+ buffer = old_buffer;
+ input_line_pointer = old_input;
+ buffer_limit = old_limit;
+ old_buffer = 0;
+ goto contin;
+ }
+ }
+ } /* while (more buffers to scan) */
+
+ quit:
+
+#ifdef md_cleanup
+ md_cleanup();
+#endif
+ input_scrub_close (); /* Close the input file */
+}
+
+/* For most MRI pseudo-ops, the line actually ends at the first
+ nonquoted space. This function looks for that point, stuffs a null
+ in, and sets *STOPCP to the character that used to be there, and
+ returns the location.
+
+ Until I hear otherwise, I am going to assume that this is only true
+ for the m68k MRI assembler. */
+
+char *
+mri_comment_field (stopcp)
+ char *stopcp;
+{
+#ifdef TC_M68K
+
+ char *s;
+ int inquote = 0;
+
+ know (flag_m68k_mri);
+
+ for (s = input_line_pointer;
+ ((! is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t')
+ || inquote);
+ s++)
+ {
+ if (*s == '\'')
+ inquote = ! inquote;
+ }
+ *stopcp = *s;
+ *s = '\0';
+ return s;
+
+#else
+
+ char *s;
+
+ for (s = input_line_pointer; ! is_end_of_line[(unsigned char) *s]; s++)
+ ;
+ *stopcp = *s;
+ *s = '\0';
+ return s;
+
+#endif
+
+}
+
+/* Skip to the end of an MRI comment field. */
+
+void
+mri_comment_end (stop, stopc)
+ char *stop;
+ int stopc;
+{
+ know (flag_mri);
+
+ input_line_pointer = stop;
+ *stop = stopc;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+}
+
+void
+s_abort (ignore)
+ int ignore;
+{
+ as_fatal (_(".abort detected. Abandoning ship."));
+}
+
+/* Guts of .align directive. N is the power of two to which to align.
+ FILL may be NULL, or it may point to the bytes of the fill pattern.
+ LEN is the length of whatever FILL points to, if anything. MAX is
+ the maximum number of characters to skip when doing the alignment,
+ or 0 if there is no maximum. */
+
+static void
+do_align (n, fill, len, max)
+ int n;
+ char *fill;
+ int len;
+ int max;
+{
+ char default_fill;
+
+#ifdef md_do_align
+ md_do_align (n, fill, len, max, just_record_alignment);
+#endif
+
+ if (fill == NULL)
+ {
+ int maybe_text;
+
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#else
+ if (now_seg != data_section && now_seg != bss_section)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#endif
+
+ if (maybe_text)
+ default_fill = NOP_OPCODE;
+ else
+ default_fill = 0;
+ fill = &default_fill;
+ len = 1;
+ }
+
+ /* Only make a frag if we HAVE to. . . */
+ if (n != 0 && !need_pass_2)
+ {
+ if (len <= 1)
+ frag_align (n, *fill, max);
+ else
+ frag_align_pattern (n, fill, len, max);
+ }
+
+#ifdef md_do_align
+ just_record_alignment:
+#endif
+
+ record_alignment (now_seg, n);
+}
+
+/* Handle the .align pseudo-op. A positive ARG is a default alignment
+ (in bytes). A negative ARG is the negative of the length of the
+ fill pattern. BYTES_P is non-zero if the alignment value should be
+ interpreted as the byte boundary, rather than the power of 2. */
+
+static void
+s_align (arg, bytes_p)
+ int arg;
+ int bytes_p;
+{
+ register unsigned int align;
+ char *stop = NULL;
+ char stopc;
+ offsetT fill = 0;
+ int max;
+ int fill_p;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (arg < 0)
+ align = 0;
+ else
+ align = arg; /* Default value from pseudo-op table */
+ }
+ else
+ {
+ align = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ }
+
+ if (bytes_p)
+ {
+ /* Convert to a power of 2. */
+ if (align != 0)
+ {
+ unsigned int i;
+
+ for (i = 0; (align & 1) == 0; align >>= 1, ++i)
+ ;
+ if (align != 1)
+ as_bad (_("Alignment not a power of 2"));
+ align = i;
+ }
+ }
+
+ if (align > 15)
+ {
+ align = 15;
+ as_bad (_("Alignment too large: %u assumed"), align);
+ }
+
+ if (*input_line_pointer != ',')
+ {
+ fill_p = 0;
+ max = 0;
+ }
+ else
+ {
+ ++input_line_pointer;
+ if (*input_line_pointer == ',')
+ fill_p = 0;
+ else
+ {
+ fill = get_absolute_expression ();
+ SKIP_WHITESPACE ();
+ fill_p = 1;
+ }
+
+ if (*input_line_pointer != ',')
+ max = 0;
+ else
+ {
+ ++input_line_pointer;
+ max = get_absolute_expression ();
+ }
+ }
+
+ if (! fill_p)
+ {
+ if (arg < 0)
+ as_warn (_("expected fill pattern missing"));
+ do_align (align, (char *) NULL, 0, max);
+ }
+ else
+ {
+ int fill_len;
+
+ if (arg >= 0)
+ fill_len = 1;
+ else
+ fill_len = - arg;
+ if (fill_len <= 1)
+ {
+ char fill_char;
+
+ fill_char = fill;
+ do_align (align, &fill_char, fill_len, max);
+ }
+ else
+ {
+ char ab[16];
+
+ if ((size_t) fill_len > sizeof ab)
+ abort ();
+ md_number_to_chars (ab, fill, fill_len);
+ do_align (align, ab, fill_len, max);
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* Handle the .align pseudo-op on machines where ".align 4" means
+ align to a 4 byte boundary. */
+
+void
+s_align_bytes (arg)
+ int arg;
+{
+ s_align (arg, 1);
+}
+
+/* Handle the .align pseudo-op on machines where ".align 4" means align
+ to a 2**4 boundary. */
+
+void
+s_align_ptwo (arg)
+ int arg;
+{
+ s_align (arg, 0);
+}
+
+void
+s_comm (ignore)
+ int ignore;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ offsetT temp;
+ register symbolS *symbolP;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ /* just after name is now '\0' */
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ input_line_pointer++; /* skip ',' */
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+ {
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ if (S_GET_VALUE (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) != (valueT) temp)
+ as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
+ S_GET_NAME (symbolP),
+ (long) S_GET_VALUE (symbolP),
+ (long) temp);
+ }
+ else
+ {
+ S_SET_VALUE (symbolP, (valueT) temp);
+ S_SET_EXTERNAL (symbolP);
+ }
+#ifdef OBJ_VMS
+ {
+ extern int flag_one;
+ if ( (!temp) || !flag_one)
+ S_GET_OTHER(symbolP) = const_flag;
+ }
+#endif /* not OBJ_VMS */
+ know (symbolP->sy_frag == &zero_address_frag);
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+} /* s_comm() */
+
+/* The MRI COMMON pseudo-op. We handle this by creating a common
+ symbol with the appropriate name. We make s_space do the right
+ thing by increasing the size. */
+
+void
+s_mri_common (small)
+ int small;
+{
+ char *name;
+ char c;
+ char *alc = NULL;
+ symbolS *sym;
+ offsetT align;
+ char *stop = NULL;
+ char stopc;
+
+ if (! flag_mri)
+ {
+ s_comm (0);
+ return;
+ }
+
+ stop = mri_comment_field (&stopc);
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ if (! isdigit ((unsigned char) *name))
+ c = get_symbol_end ();
+ else
+ {
+ do
+ {
+ ++input_line_pointer;
+ }
+ while (isdigit ((unsigned char) *input_line_pointer));
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (line_label != NULL)
+ {
+ alc = (char *) xmalloc (strlen (S_GET_NAME (line_label))
+ + (input_line_pointer - name)
+ + 1);
+ sprintf (alc, "%s%s", name, S_GET_NAME (line_label));
+ name = alc;
+ }
+ }
+
+ sym = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ if (alc != NULL)
+ free (alc);
+
+ if (*input_line_pointer != ',')
+ align = 0;
+ else
+ {
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ }
+
+ if (S_IS_DEFINED (sym) && ! S_IS_COMMON (sym))
+ {
+ as_bad (_("attempt to re-define symbol `%s'"), S_GET_NAME (sym));
+ ignore_rest_of_line ();
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
+ S_SET_EXTERNAL (sym);
+ mri_common_symbol = sym;
+
+#ifdef S_SET_ALIGN
+ if (align != 0)
+ S_SET_ALIGN (sym, align);
+#endif
+
+ if (line_label != NULL)
+ {
+ line_label->sy_value.X_op = O_symbol;
+ line_label->sy_value.X_add_symbol = sym;
+ line_label->sy_value.X_add_number = S_GET_VALUE (sym);
+ line_label->sy_frag = &zero_address_frag;
+ S_SET_SEGMENT (line_label, expr_section);
+ }
+
+ /* FIXME: We just ignore the small argument, which distinguishes
+ COMMON and COMMON.S. I don't know what we can do about it. */
+
+ /* Ignore the type and hptype. */
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+
+ demand_empty_rest_of_line ();
+
+ mri_comment_end (stop, stopc);
+}
+
+void
+s_data (ignore)
+ int ignore;
+{
+ segT section;
+ register int temp;
+
+ temp = get_absolute_expression ();
+ if (flag_readonly_data_in_text)
+ {
+ section = text_section;
+ temp += 1000;
+ }
+ else
+ section = data_section;
+
+ subseg_set (section, (subsegT) temp);
+
+#ifdef OBJ_VMS
+ const_flag = 0;
+#endif
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .appfile pseudo-op. This is automatically generated by
+ do_scrub_chars when a preprocessor # line comment is seen with a
+ file name. This default definition may be overridden by the object
+ or CPU specific pseudo-ops. This function is also the default
+ definition for .file; the APPFILE argument is 1 for .appfile, 0 for
+ .file. */
+
+void
+s_app_file (appfile)
+ int appfile;
+{
+ register char *s;
+ int length;
+
+ /* Some assemblers tolerate immediately following '"' */
+ if ((s = demand_copy_string (&length)) != 0)
+ {
+ /* If this is a fake .appfile, a fake newline was inserted into
+ the buffer. Passing -2 to new_logical_line tells it to
+ account for it. */
+ int may_omit
+ = (! new_logical_line (s, appfile ? -2 : -1) && appfile);
+
+ /* In MRI mode, the preprocessor may have inserted an extraneous
+ backquote. */
+ if (flag_m68k_mri
+ && *input_line_pointer == '\''
+ && is_end_of_line[(unsigned char) input_line_pointer[1]])
+ ++input_line_pointer;
+
+ demand_empty_rest_of_line ();
+ if (! may_omit)
+ {
+#ifdef LISTING
+ if (listing)
+ listing_source_file (s);
+#endif
+ register_dependency (s);
+#ifdef obj_app_file
+ obj_app_file (s);
+#endif
+ }
+ }
+}
+
+/* Handle the .appline pseudo-op. This is automatically generated by
+ do_scrub_chars when a preprocessor # line comment is seen. This
+ default definition may be overridden by the object or CPU specific
+ pseudo-ops. */
+
+void
+s_app_line (ignore)
+ int ignore;
+{
+ int l;
+
+ /* The given number is that of the next line. */
+ l = get_absolute_expression () - 1;
+ if (l < 0)
+ /* Some of the back ends can't deal with non-positive line numbers.
+ Besides, it's silly. */
+ as_warn (_("Line numbers must be positive; line number %d rejected."), l+1);
+ else
+ {
+ new_logical_line ((char *) NULL, l);
+#ifdef LISTING
+ if (listing)
+ listing_source_line (l);
+#endif
+ }
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .end pseudo-op. Actually, the real work is done in
+ read_a_source_file. */
+
+void
+s_end (ignore)
+ int ignore;
+{
+ if (flag_mri)
+ {
+ /* The MRI assembler permits the start symbol to follow .end,
+ but we don't support that. */
+ SKIP_WHITESPACE ();
+ if (! is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != '*'
+ && *input_line_pointer != '!')
+ as_warn (_("start address not supported"));
+ }
+}
+
+/* Handle the .err pseudo-op. */
+
+void
+s_err (ignore)
+ int ignore;
+{
+ as_bad (_(".err encountered"));
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI fail pseudo-op. */
+
+void
+s_fail (ignore)
+ int ignore;
+{
+ offsetT temp;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ temp = get_absolute_expression ();
+ if (temp >= 500)
+ as_warn (_(".fail %ld encountered"), (long) temp);
+ else
+ as_bad (_(".fail %ld encountered"), (long) temp);
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+void
+s_fill (ignore)
+ int ignore;
+{
+ expressionS rep_exp;
+ long size = 1;
+ register long fill = 0;
+ char *p;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ get_known_segmented_expression (&rep_exp);
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ size = get_absolute_expression ();
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ fill = get_absolute_expression ();
+ }
+ }
+
+ /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */
+#define BSD_FILL_SIZE_CROCK_8 (8)
+ if (size > BSD_FILL_SIZE_CROCK_8)
+ {
+ as_warn (_(".fill size clamped to %d."), BSD_FILL_SIZE_CROCK_8);
+ size = BSD_FILL_SIZE_CROCK_8;
+ }
+ if (size < 0)
+ {
+ as_warn (_("Size negative: .fill ignored."));
+ size = 0;
+ }
+ else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0)
+ {
+ if (rep_exp.X_add_number < 0)
+ as_warn (_("Repeat < 0, .fill ignored"));
+ size = 0;
+ }
+
+ if (size && !need_pass_2)
+ {
+ if (rep_exp.X_op == O_constant)
+ {
+ p = frag_var (rs_fill, (int) size, (int) size,
+ (relax_substateT) 0, (symbolS *) 0,
+ (offsetT) rep_exp.X_add_number,
+ (char *) 0);
+ }
+ else
+ {
+ /* We don't have a constant repeat count, so we can't use
+ rs_fill. We can get the same results out of rs_space,
+ but its argument is in bytes, so we must multiply the
+ repeat count by size. */
+
+ symbolS *rep_sym;
+ rep_sym = make_expr_symbol (&rep_exp);
+ if (size != 1)
+ {
+ expressionS size_exp;
+ size_exp.X_op = O_constant;
+ size_exp.X_add_number = size;
+
+ rep_exp.X_op = O_multiply;
+ rep_exp.X_add_symbol = rep_sym;
+ rep_exp.X_op_symbol = make_expr_symbol (&size_exp);
+ rep_exp.X_add_number = 0;
+ rep_sym = make_expr_symbol (&rep_exp);
+ }
+
+ p = frag_var (rs_space, (int) size, (int) size,
+ (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0);
+ }
+ memset (p, 0, (unsigned int) size);
+ /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
+ * flavoured AS. The following bizzare behaviour is to be
+ * compatible with above. I guess they tried to take up to 8
+ * bytes from a 4-byte expression and they forgot to sign
+ * extend. Un*x Sux. */
+#define BSD_FILL_SIZE_CROCK_4 (4)
+ md_number_to_chars (p, (valueT) fill,
+ (size > BSD_FILL_SIZE_CROCK_4
+ ? BSD_FILL_SIZE_CROCK_4
+ : (int) size));
+ /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
+ * but emits no error message because it seems a legal thing to do.
+ * It is a degenerate case of .fill but could be emitted by a compiler.
+ */
+ }
+ demand_empty_rest_of_line ();
+}
+
+void
+s_globl (ignore)
+ int ignore;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ S_SET_EXTERNAL (symbolP);
+ if (c == ',')
+ {
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* Handle the MRI IRP and IRPC pseudo-ops. */
+
+void
+s_irp (irpc)
+ int irpc;
+{
+ char *file;
+ unsigned int line;
+ sb s;
+ const char *err;
+ sb out;
+
+ as_where (&file, &line);
+
+ sb_new (&s);
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (&s, *input_line_pointer++);
+
+ sb_new (&out);
+
+ err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0');
+ if (err != NULL)
+ as_bad_where (file, line, "%s", err);
+
+ sb_kill (&s);
+
+ input_scrub_include_sb (&out, input_line_pointer);
+ sb_kill (&out);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Handle the .linkonce pseudo-op. This tells the assembler to mark
+ the section to only be linked once. However, this is not supported
+ by most object file formats. This takes an optional argument,
+ which is what to do about duplicates. */
+
+void
+s_linkonce (ignore)
+ int ignore;
+{
+ enum linkonce_type type;
+
+ SKIP_WHITESPACE ();
+
+ type = LINKONCE_DISCARD;
+
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *s;
+ char c;
+
+ s = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (s, "discard") == 0)
+ type = LINKONCE_DISCARD;
+ else if (strcasecmp (s, "one_only") == 0)
+ type = LINKONCE_ONE_ONLY;
+ else if (strcasecmp (s, "same_size") == 0)
+ type = LINKONCE_SAME_SIZE;
+ else if (strcasecmp (s, "same_contents") == 0)
+ type = LINKONCE_SAME_CONTENTS;
+ else
+ as_warn (_("unrecognized .linkonce type `%s'"), s);
+
+ *input_line_pointer = c;
+ }
+
+#ifdef obj_handle_link_once
+ obj_handle_link_once (type);
+#else /* ! defined (obj_handle_link_once) */
+#ifdef BFD_ASSEMBLER
+ {
+ flagword flags;
+
+ if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0)
+ as_warn (_(".linkonce is not supported for this object file format"));
+
+ flags = bfd_get_section_flags (stdoutput, now_seg);
+ flags |= SEC_LINK_ONCE;
+ switch (type)
+ {
+ default:
+ abort ();
+ case LINKONCE_DISCARD:
+ flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ case LINKONCE_ONE_ONLY:
+ flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+ break;
+ case LINKONCE_SAME_SIZE:
+ flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+ break;
+ case LINKONCE_SAME_CONTENTS:
+ flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+ }
+ if (! bfd_set_section_flags (stdoutput, now_seg, flags))
+ as_bad (_("bfd_set_section_flags: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
+#else /* ! defined (BFD_ASSEMBLER) */
+ as_warn (_(".linkonce is not supported for this object file format"));
+#endif /* ! defined (BFD_ASSEMBLER) */
+#endif /* ! defined (obj_handle_link_once) */
+
+ demand_empty_rest_of_line ();
+}
+
+static void
+s_lcomm_internal (needs_align, bytes_p)
+ /* 1 if this was a ".bss" directive, which may require a 3rd argument
+ (alignment); 0 if it was an ".lcomm" (2 args only) */
+ int needs_align;
+ /* 1 if the alignment value should be interpreted as the byte boundary,
+ rather than the power of 2. */
+ int bytes_p;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ register int temp;
+ register symbolS *symbolP;
+ segT current_seg = now_seg;
+ subsegT current_subseg = now_subseg;
+ const int max_alignment = 15;
+ int align = 0;
+ segT bss_seg = bss_section;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+
+ /* Accept an optional comma after the name. The comma used to be
+ required, but Irix 5 cc does not generate it. */
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+
+ if (*input_line_pointer == '\n')
+ {
+ as_bad (_("Missing size expression"));
+ return;
+ }
+
+ if ((temp = get_absolute_expression ()) < 0)
+ {
+ as_warn (_("BSS length (%d.) <0! Ignored."), temp);
+ ignore_rest_of_line ();
+ return;
+ }
+
+#if defined (TC_MIPS) || defined (TC_ALPHA)
+ if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
+ /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */
+ if (temp <= bfd_get_gp_size (stdoutput))
+ {
+ bss_seg = subseg_new (".sbss", 1);
+ seg_info (bss_seg)->bss = 1;
+#ifdef BFD_ASSEMBLER
+ if (! bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
+ as_warn (_("error setting flags for \".sbss\": %s"),
+ bfd_errmsg (bfd_get_error ()));
+#endif
+ }
+ }
+#endif
+ if (!needs_align)
+ {
+ /* FIXME. This needs to be machine independent. */
+ if (temp >= 8)
+ align = 3;
+ else if (temp >= 4)
+ align = 2;
+ else if (temp >= 2)
+ align = 1;
+ else
+ align = 0;
+
+#ifdef OBJ_EVAX
+ /* FIXME: This needs to be done in a more general fashion. */
+ align = 3;
+#endif
+
+ record_alignment(bss_seg, align);
+ }
+
+ if (needs_align)
+ {
+ align = 0;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("Expected comma after size"));
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\n')
+ {
+ as_bad (_("Missing alignment"));
+ return;
+ }
+ align = get_absolute_expression ();
+ if (bytes_p)
+ {
+ /* Convert to a power of 2. */
+ if (align != 0)
+ {
+ unsigned int i;
+
+ for (i = 0; (align & 1) == 0; align >>= 1, ++i)
+ ;
+ if (align != 1)
+ as_bad (_("Alignment not a power of 2"));
+ align = i;
+ }
+ }
+ if (align > max_alignment)
+ {
+ align = max_alignment;
+ as_warn (_("Alignment too large: %d. assumed."), align);
+ }
+ else if (align < 0)
+ {
+ align = 0;
+ as_warn (_("Alignment negative. 0 assumed."));
+ }
+ record_alignment (bss_seg, align);
+ } /* if needs align */
+ else
+ {
+ /* Assume some objects may require alignment on some systems. */
+#if defined (TC_ALPHA) && ! defined (VMS)
+ if (temp > 1)
+ {
+ align = ffs (temp) - 1;
+ if (temp % (1 << align))
+ abort ();
+ }
+#endif
+ }
+
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+
+ if (
+#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
+ S_GET_OTHER (symbolP) == 0 &&
+ S_GET_DESC (symbolP) == 0 &&
+#endif /* OBJ_AOUT or OBJ_BOUT */
+ (S_GET_SEGMENT (symbolP) == bss_seg
+ || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
+ {
+ char *pfrag;
+
+ subseg_set (bss_seg, 1);
+
+ if (align)
+ frag_align (align, 0, 0);
+ /* detach from old frag */
+ if (S_GET_SEGMENT (symbolP) == bss_seg)
+ symbolP->sy_frag->fr_symbol = NULL;
+
+ symbolP->sy_frag = frag_now;
+ pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
+ (offsetT) temp, (char *) 0);
+ *pfrag = 0;
+
+ S_SET_SEGMENT (symbolP, bss_seg);
+
+#ifdef OBJ_COFF
+ /* The symbol may already have been created with a preceding
+ ".globl" directive -- be careful not to step on storage class
+ in that case. Otherwise, set it to static. */
+ if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
+ {
+ S_SET_STORAGE_CLASS (symbolP, C_STAT);
+ }
+#endif /* OBJ_COFF */
+
+#ifdef S_SET_SIZE
+ S_SET_SIZE (symbolP, temp);
+#endif
+ }
+ else
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
+ S_GET_NAME (symbolP));
+
+ subseg_set (current_seg, current_subseg);
+
+ demand_empty_rest_of_line ();
+} /* s_lcomm_internal() */
+
+void
+s_lcomm (needs_align)
+ int needs_align;
+{
+ s_lcomm_internal (needs_align, 0);
+}
+
+void s_lcomm_bytes (needs_align)
+ int needs_align;
+{
+ s_lcomm_internal (needs_align, 1);
+}
+
+void
+s_lsym (ignore)
+ int ignore;
+{
+ register char *name;
+ register char c;
+ register char *p;
+ expressionS exp;
+ register symbolS *symbolP;
+
+ /* we permit ANY defined expression: BSD4.2 demands constants */
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("Expected comma after name \"%s\""), name);
+ *p = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ expression (&exp);
+ if (exp.X_op != O_constant
+ && exp.X_op != O_register)
+ {
+ as_bad (_("bad expression"));
+ ignore_rest_of_line ();
+ return;
+ }
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+
+ /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
+ symbolP->sy_desc == 0) out of this test because coff doesn't have
+ those fields, and I can't see when they'd ever be tripped. I
+ don't think I understand why they were here so I may have
+ introduced a bug. As recently as 1.37 didn't have this test
+ anyway. xoxorich. */
+
+ if (S_GET_SEGMENT (symbolP) == undefined_section
+ && S_GET_VALUE (symbolP) == 0)
+ {
+ /* The name might be an undefined .global symbol; be sure to
+ keep the "external" bit. */
+ S_SET_SEGMENT (symbolP,
+ (exp.X_op == O_constant
+ ? absolute_section
+ : reg_section));
+ S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ }
+ else
+ {
+ as_bad (_("Symbol %s already defined"), name);
+ }
+ *p = c;
+ demand_empty_rest_of_line ();
+} /* s_lsym() */
+
+/* Read a line into an sb. */
+
+static int
+get_line_sb (line)
+ sb *line;
+{
+ char quote1, quote2, inquote;
+
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+
+ if (input_line_pointer >= buffer_limit)
+ {
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ if (buffer_limit == 0)
+ return 0;
+ }
+
+ /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this
+ code needs to be changed. */
+ if (! flag_m68k_mri)
+ quote1 = '"';
+ else
+ quote1 = '\0';
+
+ quote2 = '\0';
+ if (flag_m68k_mri)
+ quote2 = '\'';
+#ifdef LEX_IS_STRINGQUOTE
+ quote2 = '\'';
+#endif
+
+ inquote = '\0';
+ while (! is_end_of_line[(unsigned char) *input_line_pointer]
+ || (inquote != '\0' && *input_line_pointer != '\n'))
+ {
+ if (inquote == *input_line_pointer)
+ inquote = '\0';
+ else if (inquote == '\0')
+ {
+ if (*input_line_pointer == quote1)
+ inquote = quote1;
+ else if (*input_line_pointer == quote2)
+ inquote = quote2;
+ }
+ sb_add_char (line, *input_line_pointer++);
+ }
+ while (input_line_pointer < buffer_limit
+ && is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+ ++input_line_pointer;
+ }
+ return 1;
+}
+
+/* Define a macro. This is an interface to macro.c, which is shared
+ between gas and gasp. */
+
+void
+s_macro (ignore)
+ int ignore;
+{
+ char *file;
+ unsigned int line;
+ sb s;
+ sb label;
+ const char *err;
+ const char *name;
+
+ as_where (&file, &line);
+
+ sb_new (&s);
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (&s, *input_line_pointer++);
+
+ sb_new (&label);
+ if (line_label != NULL)
+ sb_add_string (&label, S_GET_NAME (line_label));
+
+ err = define_macro (0, &s, &label, get_line_sb, &name);
+ if (err != NULL)
+ as_bad_where (file, line, "%s", err);
+ else
+ {
+ if (line_label != NULL)
+ {
+ S_SET_SEGMENT (line_label, undefined_section);
+ S_SET_VALUE (line_label, 0);
+ line_label->sy_frag = &zero_address_frag;
+ }
+
+ if (((flag_m68k_mri
+#ifdef NO_PSEUDO_DOT
+ || 1
+#endif
+ )
+ && hash_find (po_hash, name) != NULL)
+ || (! flag_m68k_mri
+ && *name == '.'
+ && hash_find (po_hash, name + 1) != NULL))
+ as_warn (_("attempt to redefine pseudo-op `%s' ignored"),
+ name);
+ }
+
+ sb_kill (&s);
+}
+
+/* Handle the .mexit pseudo-op, which immediately exits a macro
+ expansion. */
+
+void
+s_mexit (ignore)
+ int ignore;
+{
+ cond_exit_macro (macro_nest);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Switch in and out of MRI mode. */
+
+void
+s_mri (ignore)
+ int ignore;
+{
+ int on, old_flag;
+
+ on = get_absolute_expression ();
+ old_flag = flag_mri;
+ if (on != 0)
+ {
+ flag_mri = 1;
+#ifdef TC_M68K
+ flag_m68k_mri = 1;
+#endif
+ macro_mri_mode (1);
+ }
+ else
+ {
+ flag_mri = 0;
+ flag_m68k_mri = 0;
+ macro_mri_mode (0);
+ }
+
+ /* Operator precedence changes in m68k MRI mode, so we need to
+ update the operator rankings. */
+ expr_set_precedence ();
+
+#ifdef MRI_MODE_CHANGE
+ if (on != old_flag)
+ MRI_MODE_CHANGE (on);
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle changing the location counter. */
+
+static void
+do_org (segment, exp, fill)
+ segT segment;
+ expressionS *exp;
+ int fill;
+{
+ if (segment != now_seg && segment != absolute_section)
+ as_bad (_("invalid segment \"%s\"; segment \"%s\" assumed"),
+ segment_name (segment), segment_name (now_seg));
+
+ if (now_seg == absolute_section)
+ {
+ if (fill != 0)
+ as_warn (_("ignoring fill value in absolute section"));
+ if (exp->X_op != O_constant)
+ {
+ as_bad (_("only constant offsets supported in absolute section"));
+ exp->X_add_number = 0;
+ }
+ abs_section_offset = exp->X_add_number;
+ }
+ else
+ {
+ char *p;
+
+ p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol,
+ exp->X_add_number, (char *) NULL);
+ *p = fill;
+ }
+}
+
+void
+s_org (ignore)
+ int ignore;
+{
+ register segT segment;
+ expressionS exp;
+ register long temp_fill;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /* The m68k MRI assembler has a different meaning for .org. It
+ means to create an absolute section at a given address. We can't
+ support that--use a linker script instead. */
+ if (flag_m68k_mri)
+ {
+ as_bad (_("MRI style ORG pseudo-op not supported"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Don't believe the documentation of BSD 4.2 AS. There is no such
+ thing as a sub-segment-relative origin. Any absolute origin is
+ given a warning, then assumed to be segment-relative. Any
+ segmented origin expression ("foo+42") had better be in the right
+ segment or the .org is ignored.
+
+ BSD 4.2 AS warns if you try to .org backwards. We cannot because
+ we never know sub-segment sizes when we are reading code. BSD
+ will crash trying to emit negative numbers of filler bytes in
+ certain .orgs. We don't crash, but see as-write for that code.
+
+ Don't make frag if need_pass_2==1. */
+ segment = get_known_segmented_expression (&exp);
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ temp_fill = get_absolute_expression ();
+ }
+ else
+ temp_fill = 0;
+
+ if (!need_pass_2)
+ do_org (segment, &exp, temp_fill);
+
+ demand_empty_rest_of_line ();
+} /* s_org() */
+
+/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be
+ called by the obj-format routine which handles section changing
+ when in MRI mode. It will create a new section, and return it. It
+ will set *TYPE to the section type: one of 'C' (code), 'D' (data),
+ 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the
+ flags will be set in the section. */
+
+void
+s_mri_sect (type)
+ char *type;
+{
+#ifdef TC_M68K
+
+ char *name;
+ char c;
+ segT seg;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ if (! isdigit ((unsigned char) *name))
+ c = get_symbol_end ();
+ else
+ {
+ do
+ {
+ ++input_line_pointer;
+ }
+ while (isdigit ((unsigned char) *input_line_pointer));
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ }
+
+ name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ seg = subseg_new (name, 0);
+
+ if (*input_line_pointer == ',')
+ {
+ int align;
+
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ record_alignment (seg, align);
+ }
+
+ *type = 'C';
+ if (*input_line_pointer == ',')
+ {
+ c = *++input_line_pointer;
+ c = toupper ((unsigned char) c);
+ if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
+ *type = c;
+ else
+ as_bad (_("unrecognized section type"));
+ ++input_line_pointer;
+
+#ifdef BFD_ASSEMBLER
+ {
+ flagword flags;
+
+ flags = SEC_NO_FLAGS;
+ if (*type == 'C')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE;
+ else if (*type == 'D' || *type == 'M')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA;
+ else if (*type == 'R')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM;
+ if (flags != SEC_NO_FLAGS)
+ {
+ if (! bfd_set_section_flags (stdoutput, seg, flags))
+ as_warn (_("error setting flags for \"%s\": %s"),
+ bfd_section_name (stdoutput, seg),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ }
+#endif
+ }
+
+ /* Ignore the HP type. */
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+
+ demand_empty_rest_of_line ();
+
+#else /* ! TC_M68K */
+#ifdef TC_I960
+
+ char *name;
+ char c;
+ segT seg;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ seg = subseg_new (name, 0);
+
+ if (*input_line_pointer != ',')
+ *type = 'C';
+ else
+ {
+ char *sectype;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ sectype = input_line_pointer;
+ c = get_symbol_end ();
+ if (*sectype == '\0')
+ *type = 'C';
+ else if (strcasecmp (sectype, "text") == 0)
+ *type = 'C';
+ else if (strcasecmp (sectype, "data") == 0)
+ *type = 'D';
+ else if (strcasecmp (sectype, "romdata") == 0)
+ *type = 'R';
+ else
+ as_warn (_("unrecognized section type `%s'"), sectype);
+ *input_line_pointer = c;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ char *seccmd;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ seccmd = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (seccmd, "absolute") == 0)
+ {
+ as_bad (_("absolute sections are not supported"));
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ else if (strcasecmp (seccmd, "align") == 0)
+ {
+ int align;
+
+ *input_line_pointer = c;
+ align = get_absolute_expression ();
+ record_alignment (seg, align);
+ }
+ else
+ {
+ as_warn (_("unrecognized section command `%s'"), seccmd);
+ *input_line_pointer = c;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+#else /* ! TC_I960 */
+ /* The MRI assembler seems to use different forms of .sect for
+ different targets. */
+ as_bad ("MRI mode not supported for this target");
+ ignore_rest_of_line ();
+#endif /* ! TC_I960 */
+#endif /* ! TC_M68K */
+}
+
+/* Handle the .print pseudo-op. */
+
+void
+s_print (ignore)
+ int ignore;
+{
+ char *s;
+ int len;
+
+ s = demand_copy_C_string (&len);
+ printf ("%s\n", s);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .purgem pseudo-op. */
+
+void
+s_purgem (ignore)
+ int ignore;
+{
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ char *name;
+ char c;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ delete_macro (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .rept pseudo-op. */
+
+void
+s_rept (ignore)
+ int ignore;
+{
+ int count;
+ sb one;
+ sb many;
+
+ count = get_absolute_expression ();
+
+ sb_new (&one);
+ if (! buffer_and_nest ("REPT", "ENDR", &one, get_line_sb))
+ {
+ as_bad (_("rept without endr"));
+ return;
+ }
+
+ sb_new (&many);
+ while (count-- > 0)
+ sb_add_sb (&many, &one);
+
+ sb_kill (&one);
+
+ input_scrub_include_sb (&many, input_line_pointer);
+ sb_kill (&many);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Handle the .equ, .equiv and .set directives. If EQUIV is 1, then
+ this is .equiv, and it is an error if the symbol is already
+ defined. */
+
+void
+s_set (equiv)
+ int equiv;
+{
+ register char *name;
+ register char delim;
+ register char *end_name;
+ register symbolS *symbolP;
+
+ /*
+ * Especial apologies for the random logic:
+ * this just grew, and could be parsed much more simply!
+ * Dean in haste.
+ */
+ name = input_line_pointer;
+ delim = get_symbol_end ();
+ end_name = input_line_pointer;
+ *end_name = delim;
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer != ',')
+ {
+ *end_name = 0;
+ as_bad (_("Expected comma after name \"%s\""), name);
+ *end_name = delim;
+ ignore_rest_of_line ();
+ return;
+ }
+
+ input_line_pointer++;
+ *end_name = 0;
+
+ if (name[0] == '.' && name[1] == '\0')
+ {
+ /* Turn '. = mumble' into a .org mumble */
+ register segT segment;
+ expressionS exp;
+
+ segment = get_known_segmented_expression (&exp);
+
+ if (!need_pass_2)
+ do_org (segment, &exp, 0);
+
+ *end_name = delim;
+ return;
+ }
+
+ if ((symbolP = symbol_find (name)) == NULL
+ && (symbolP = md_undefined_symbol (name)) == NULL)
+ {
+#ifndef NO_LISTING
+ /* When doing symbol listings, play games with dummy fragments living
+ outside the normal fragment chain to record the file and line info
+ for this symbol. */
+ if (listing & LISTING_SYMBOLS)
+ {
+ extern struct list_info_struct *listing_tail;
+ fragS *dummy_frag = (fragS *) xmalloc (sizeof(fragS));
+ memset (dummy_frag, 0, sizeof(fragS));
+ dummy_frag->fr_type = rs_fill;
+ dummy_frag->line = listing_tail;
+ symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
+ dummy_frag->fr_symbol = symbolP;
+ }
+ else
+#endif
+ symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+
+#ifdef OBJ_COFF
+ /* "set" symbols are local unless otherwise specified. */
+ SF_SET_LOCAL (symbolP);
+#endif /* OBJ_COFF */
+
+ } /* make a new symbol */
+
+ symbol_table_insert (symbolP);
+
+ *end_name = delim;
+
+ if (equiv
+ && S_IS_DEFINED (symbolP)
+ && S_GET_SEGMENT (symbolP) != reg_section)
+ as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+
+ pseudo_set (symbolP);
+ demand_empty_rest_of_line ();
+} /* s_set() */
+
+void
+s_space (mult)
+ int mult;
+{
+ expressionS exp;
+ expressionS val;
+ char *p = 0;
+ char *stop = NULL;
+ char stopc;
+ int bytes;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ /* In m68k MRI mode, we need to align to a word boundary, unless
+ this is ds.b. */
+ if (flag_m68k_mri && mult > 1)
+ {
+ if (now_seg == absolute_section)
+ {
+ abs_section_offset += abs_section_offset & 1;
+ if (line_label != NULL)
+ S_SET_VALUE (line_label, abs_section_offset);
+ }
+ else if (mri_common_symbol != NULL)
+ {
+ valueT val;
+
+ val = S_GET_VALUE (mri_common_symbol);
+ if ((val & 1) != 0)
+ {
+ S_SET_VALUE (mri_common_symbol, val + 1);
+ if (line_label != NULL)
+ {
+ know (line_label->sy_value.X_op == O_symbol);
+ know (line_label->sy_value.X_add_symbol == mri_common_symbol);
+ line_label->sy_value.X_add_number += 1;
+ }
+ }
+ }
+ else
+ {
+ do_align (1, (char *) NULL, 0, 0);
+ if (line_label != NULL)
+ {
+ line_label->sy_frag = frag_now;
+ S_SET_VALUE (line_label, frag_now_fix ());
+ }
+ }
+ }
+
+ bytes = mult;
+
+ expression (&exp);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ expression (&val);
+ }
+ else
+ {
+ val.X_op = O_constant;
+ val.X_add_number = 0;
+ }
+
+ if (val.X_op != O_constant
+ || val.X_add_number < - 0x80
+ || val.X_add_number > 0xff
+ || (mult != 0 && mult != 1 && val.X_add_number != 0))
+ {
+ if (exp.X_op != O_constant)
+ as_bad (_("Unsupported variable size or fill value"));
+ else
+ {
+ offsetT i;
+
+ if (mult == 0)
+ mult = 1;
+ bytes = mult * exp.X_add_number;
+ for (i = 0; i < exp.X_add_number; i++)
+ emit_expr (&val, mult);
+ }
+ }
+ else
+ {
+ if (exp.X_op == O_constant)
+ {
+ long repeat;
+
+ repeat = exp.X_add_number;
+ if (mult)
+ repeat *= mult;
+ bytes = repeat;
+ if (repeat <= 0)
+ {
+ if (! flag_mri)
+ as_warn (_(".space repeat count is zero, ignored"));
+ else if (repeat < 0)
+ as_warn (_(".space repeat count is negative, ignored"));
+ goto getout;
+ }
+
+ /* If we are in the absolute section, just bump the offset. */
+ if (now_seg == absolute_section)
+ {
+ abs_section_offset += repeat;
+ goto getout;
+ }
+
+ /* If we are secretly in an MRI common section, then
+ creating space just increases the size of the common
+ symbol. */
+ if (mri_common_symbol != NULL)
+ {
+ S_SET_VALUE (mri_common_symbol,
+ S_GET_VALUE (mri_common_symbol) + repeat);
+ goto getout;
+ }
+
+ if (!need_pass_2)
+ p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
+ (offsetT) repeat, (char *) 0);
+ }
+ else
+ {
+ if (now_seg == absolute_section)
+ {
+ as_bad (_("space allocation too complex in absolute section"));
+ subseg_set (text_section, 0);
+ }
+ if (mri_common_symbol != NULL)
+ {
+ as_bad (_("space allocation too complex in common section"));
+ mri_common_symbol = NULL;
+ }
+ if (!need_pass_2)
+ p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
+ make_expr_symbol (&exp), (offsetT) 0, (char *) 0);
+ }
+
+ if (p)
+ *p = val.X_add_number;
+ }
+
+ getout:
+
+ /* In MRI mode, after an odd number of bytes, we must align to an
+ even word boundary, unless the next instruction is a dc.b, ds.b
+ or dcb.b. */
+ if (flag_mri && (bytes & 1) != 0)
+ mri_pending_align = 1;
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* This is like s_space, but the value is a floating point number with
+ the given precision. This is for the MRI dcb.s pseudo-op and
+ friends. */
+
+void
+s_float_space (float_type)
+ int float_type;
+{
+ offsetT count;
+ int flen;
+ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ count = get_absolute_expression ();
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad (_("missing value"));
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
+ ++input_line_pointer;
+
+ SKIP_WHITESPACE ();
+
+ /* Skip any 0{letter} that may be present. Don't even check if the
+ * letter is legal. */
+ if (input_line_pointer[0] == '0'
+ && isalpha ((unsigned char) input_line_pointer[1]))
+ input_line_pointer += 2;
+
+ /* Accept :xxxx, where the x's are hex digits, for a floating point
+ with the exact digits specified. */
+ if (input_line_pointer[0] == ':')
+ {
+ flen = hex_float (float_type, temp);
+ if (flen < 0)
+ {
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ }
+ else
+ {
+ char *err;
+
+ err = md_atof (float_type, temp, &flen);
+ know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+ know (flen > 0);
+ if (err)
+ {
+ as_bad (_("Bad floating literal: %s"), err);
+ ignore_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+ }
+
+ while (--count >= 0)
+ {
+ char *p;
+
+ p = frag_more (flen);
+ memcpy (p, temp, (unsigned int) flen);
+ }
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+/* Handle the .struct pseudo-op, as found in MIPS assemblers. */
+
+void
+s_struct (ignore)
+ int ignore;
+{
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+ abs_section_offset = get_absolute_expression ();
+ subseg_set (absolute_section, 0);
+ demand_empty_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+void
+s_text (ignore)
+ int ignore;
+{
+ register int temp;
+
+ temp = get_absolute_expression ();
+ subseg_set (text_section, (subsegT) temp);
+ demand_empty_rest_of_line ();
+#ifdef OBJ_VMS
+ const_flag &= ~IN_DEFAULT_SECTION;
+#endif
+} /* s_text() */
+
+
+void
+demand_empty_rest_of_line ()
+{
+ SKIP_WHITESPACE ();
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ input_line_pointer++;
+ }
+ else
+ {
+ ignore_rest_of_line ();
+ }
+ /* Return having already swallowed end-of-line. */
+} /* Return pointing just after end-of-line. */
+
+void
+ignore_rest_of_line () /* For suspect lines: gives warning. */
+{
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (isprint ((unsigned char) *input_line_pointer))
+ as_bad (_("Rest of line ignored. First ignored character is `%c'."),
+ *input_line_pointer);
+ else
+ as_bad (_("Rest of line ignored. First ignored character valued 0x%x."),
+ *input_line_pointer);
+ while (input_line_pointer < buffer_limit
+ && !is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ input_line_pointer++;
+ }
+ }
+ input_line_pointer++; /* Return pointing just after end-of-line. */
+ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+}
+
+void
+discard_rest_of_line ()
+{
+ while (input_line_pointer < buffer_limit
+ && !is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ input_line_pointer++;
+ }
+ input_line_pointer++; /* Return pointing just after end-of-line. */
+ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
+}
+
+/*
+ * pseudo_set()
+ *
+ * In: Pointer to a symbol.
+ * Input_line_pointer->expression.
+ *
+ * Out: Input_line_pointer->just after any whitespace after expression.
+ * Tried to set symbol to value of expression.
+ * Will change symbols type, value, and frag;
+ */
+void
+pseudo_set (symbolP)
+ symbolS *symbolP;
+{
+ expressionS exp;
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ int ext;
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+ know (symbolP); /* NULL pointer is logic error. */
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ ext = S_IS_EXTERNAL (symbolP);
+#endif /* OBJ_AOUT or OBJ_BOUT */
+
+ (void) expression (&exp);
+
+ if (exp.X_op == O_illegal)
+ as_bad (_("illegal expression; zero assumed"));
+ else if (exp.X_op == O_absent)
+ as_bad (_("missing expression; zero assumed"));
+ else if (exp.X_op == O_big)
+ {
+ if (exp.X_add_number > 0)
+ as_bad (_("bignum invalid; zero assumed"));
+ else
+ as_bad (_("floating point number invalid; zero assumed"));
+ }
+ else if (exp.X_op == O_subtract
+ && (S_GET_SEGMENT (exp.X_add_symbol)
+ == S_GET_SEGMENT (exp.X_op_symbol))
+ && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
+ && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag)
+ {
+ exp.X_op = O_constant;
+ exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
+ - S_GET_VALUE (exp.X_op_symbol));
+ }
+
+ switch (exp.X_op)
+ {
+ case O_illegal:
+ case O_absent:
+ case O_big:
+ exp.X_add_number = 0;
+ /* Fall through. */
+ case O_constant:
+ S_SET_SEGMENT (symbolP, absolute_section);
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ if (ext)
+ S_SET_EXTERNAL (symbolP);
+ else
+ S_CLEAR_EXTERNAL (symbolP);
+#endif /* OBJ_AOUT or OBJ_BOUT */
+ S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ if (exp.X_op != O_constant)
+ symbolP->sy_frag = &zero_address_frag;
+ break;
+
+ case O_register:
+ S_SET_SEGMENT (symbolP, reg_section);
+ S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
+ symbolP->sy_frag = &zero_address_frag;
+ break;
+
+ case O_symbol:
+ if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section
+ || exp.X_add_number != 0)
+ symbolP->sy_value = exp;
+ else
+ {
+ symbolS *s = exp.X_add_symbol;
+
+ S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s));
+#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
+ if (ext)
+ S_SET_EXTERNAL (symbolP);
+ else
+ S_CLEAR_EXTERNAL (symbolP);
+#endif /* OBJ_AOUT or OBJ_BOUT */
+ S_SET_VALUE (symbolP,
+ exp.X_add_number + S_GET_VALUE (s));
+ symbolP->sy_frag = s->sy_frag;
+ copy_symbol_attributes (symbolP, s);
+ }
+ break;
+
+ default:
+ /* The value is some complex expression.
+ FIXME: Should we set the segment to anything? */
+ symbolP->sy_value = exp;
+ break;
+ }
+}
+
+/*
+ * cons()
+ *
+ * CONStruct more frag of .bytes, or .words etc.
+ * Should need_pass_2 be 1 then emit no frag(s).
+ * This understands EXPRESSIONS.
+ *
+ * Bug (?)
+ *
+ * This has a split personality. We use expression() to read the
+ * value. We can detect if the value won't fit in a byte or word.
+ * But we can't detect if expression() discarded significant digits
+ * in the case of a long. Not worth the crocks required to fix it.
+ */
+
+/* Select a parser for cons expressions. */
+
+/* Some targets need to parse the expression in various fancy ways.
+ You can define TC_PARSE_CONS_EXPRESSION to do whatever you like
+ (for example, the HPPA does this). Otherwise, you can define
+ BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or
+ REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these
+ are defined, which is the normal case, then only simple expressions
+ are permitted. */
+
+static void
+parse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes));
+
+#ifndef TC_PARSE_CONS_EXPRESSION
+#ifdef BITFIELD_CONS_EXPRESSIONS
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
+static void
+parse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes));
+#endif
+#ifdef REPEAT_CONS_EXPRESSIONS
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
+static void
+parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes));
+#endif
+
+/* If we haven't gotten one yet, just call expression. */
+#ifndef TC_PARSE_CONS_EXPRESSION
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
+#endif
+#endif
+
+/* worker to do .byte etc statements */
+/* clobbers input_line_pointer, checks */
+/* end-of-line. */
+static void
+cons_worker (nbytes, rva)
+ register int nbytes; /* 1=.byte, 2=.word, 4=.long */
+ int rva;
+{
+ int c;
+ expressionS exp;
+ char *stop = NULL;
+ char stopc;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+ return;
+ }
+
+#ifdef md_cons_align
+ md_cons_align (nbytes);
+#endif
+
+ c = 0;
+ do
+ {
+ if (flag_m68k_mri)
+ parse_mri_cons (&exp, (unsigned int) nbytes);
+ else
+ TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+
+ if (rva)
+ {
+ if (exp.X_op == O_symbol)
+ exp.X_op = O_symbol_rva;
+ else
+ as_fatal (_("rva without symbol"));
+ }
+ emit_expr (&exp, (unsigned int) nbytes);
+ ++c;
+ }
+ while (*input_line_pointer++ == ',');
+
+ /* In MRI mode, after an odd number of bytes, we must align to an
+ even word boundary, unless the next instruction is a dc.b, ds.b
+ or dcb.b. */
+ if (flag_mri && nbytes == 1 && (c & 1) != 0)
+ mri_pending_align = 1;
+
+ input_line_pointer--; /* Put terminator back into stream. */
+
+ demand_empty_rest_of_line ();
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+}
+
+
+void
+cons (size)
+ int size;
+{
+ cons_worker (size, 0);
+}
+
+void
+s_rva (size)
+ int size;
+{
+ cons_worker (size, 1);
+}
+
+/* Put the contents of expression EXP into the object file using
+ NBYTES bytes. If need_pass_2 is 1, this does nothing. */
+
+void
+emit_expr (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ operatorT op;
+ register char *p;
+ valueT extra_digit = 0;
+
+ /* Don't do anything if we are going to make another pass. */
+ if (need_pass_2)
+ return;
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+ /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will
+ appear as a four byte positive constant in the .line section,
+ followed by a 2 byte 0xffff. Look for that case here. */
+ {
+ static int dwarf_line = -1;
+
+ if (strcmp (segment_name (now_seg), ".line") != 0)
+ dwarf_line = -1;
+ else if (dwarf_line >= 0
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && (exp->X_add_number == -1 || exp->X_add_number == 0xffff))
+ listing_source_line ((unsigned int) dwarf_line);
+ else if (nbytes == 4
+ && exp->X_op == O_constant
+ && exp->X_add_number >= 0)
+ dwarf_line = exp->X_add_number;
+ else
+ dwarf_line = -1;
+ }
+
+ /* When gcc emits DWARF 1 debugging pseudo-ops, a file name will
+ appear as a 2 byte TAG_compile_unit (0x11) followed by a 2 byte
+ AT_sibling (0x12) followed by a four byte address of the sibling
+ followed by a 2 byte AT_name (0x38) followed by the name of the
+ file. We look for that case here. */
+ {
+ static int dwarf_file = 0;
+
+ if (strcmp (segment_name (now_seg), ".debug") != 0)
+ dwarf_file = 0;
+ else if (dwarf_file == 0
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && exp->X_add_number == 0x11)
+ dwarf_file = 1;
+ else if (dwarf_file == 1
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && exp->X_add_number == 0x12)
+ dwarf_file = 2;
+ else if (dwarf_file == 2
+ && nbytes == 4)
+ dwarf_file = 3;
+ else if (dwarf_file == 3
+ && nbytes == 2
+ && exp->X_op == O_constant
+ && exp->X_add_number == 0x38)
+ dwarf_file = 4;
+ else
+ dwarf_file = 0;
+
+ /* The variable dwarf_file_string tells stringer that the string
+ may be the name of the source file. */
+ if (dwarf_file == 4)
+ dwarf_file_string = 1;
+ else
+ dwarf_file_string = 0;
+ }
+#endif
+#endif
+
+ if (check_eh_frame (exp, &nbytes))
+ return;
+
+ op = exp->X_op;
+
+ /* Allow `.word 0' in the absolute section. */
+ if (now_seg == absolute_section)
+ {
+ if (op != O_constant || exp->X_add_number != 0)
+ as_bad (_("attempt to store value in absolute section"));
+ abs_section_offset += nbytes;
+ return;
+ }
+
+ /* Handle a negative bignum. */
+ if (op == O_uminus
+ && exp->X_add_number == 0
+ && exp->X_add_symbol->sy_value.X_op == O_big
+ && exp->X_add_symbol->sy_value.X_add_number > 0)
+ {
+ int i;
+ unsigned long carry;
+
+ exp = &exp->X_add_symbol->sy_value;
+
+ /* Negate the bignum: one's complement each digit and add 1. */
+ carry = 1;
+ for (i = 0; i < exp->X_add_number; i++)
+ {
+ unsigned long next;
+
+ next = (((~ (generic_bignum[i] & LITTLENUM_MASK))
+ & LITTLENUM_MASK)
+ + carry);
+ generic_bignum[i] = next & LITTLENUM_MASK;
+ carry = next >> LITTLENUM_NUMBER_OF_BITS;
+ }
+
+ /* We can ignore any carry out, because it will be handled by
+ extra_digit if it is needed. */
+
+ extra_digit = (valueT) -1;
+ op = O_big;
+ }
+
+ if (op == O_absent || op == O_illegal)
+ {
+ as_warn (_("zero assumed for missing expression"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_big && exp->X_add_number <= 0)
+ {
+ as_bad (_("floating point number invalid; zero assumed"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_register)
+ {
+ as_warn (_("register value used as expression"));
+ op = O_constant;
+ }
+
+ p = frag_more ((int) nbytes);
+
+#ifndef WORKING_DOT_WORD
+ /* If we have the difference of two symbols in a word, save it on
+ the broken_words list. See the code in write.c. */
+ if (op == O_subtract && nbytes == 2)
+ {
+ struct broken_word *x;
+
+ x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
+ x->next_broken_word = broken_words;
+ broken_words = x;
+ x->seg = now_seg;
+ x->subseg = now_subseg;
+ x->frag = frag_now;
+ x->word_goes_here = p;
+ x->dispfrag = 0;
+ x->add = exp->X_add_symbol;
+ x->sub = exp->X_op_symbol;
+ x->addnum = exp->X_add_number;
+ x->added = 0;
+ new_broken_words++;
+ return;
+ }
+#endif
+
+ /* If we have an integer, but the number of bytes is too large to
+ pass to md_number_to_chars, handle it as a bignum. */
+ if (op == O_constant && nbytes > sizeof (valueT))
+ {
+ valueT val;
+ int gencnt;
+
+ if (! exp->X_unsigned && exp->X_add_number < 0)
+ extra_digit = (valueT) -1;
+ val = (valueT) exp->X_add_number;
+ gencnt = 0;
+ do
+ {
+ generic_bignum[gencnt] = val & LITTLENUM_MASK;
+ val >>= LITTLENUM_NUMBER_OF_BITS;
+ ++gencnt;
+ }
+ while (val != 0);
+ op = exp->X_op = O_big;
+ exp->X_add_number = gencnt;
+ }
+
+ if (op == O_constant)
+ {
+ register valueT get;
+ register valueT use;
+ register valueT mask;
+ valueT hibit;
+ register valueT unmask;
+
+ /* JF << of >= number of bits in the object is undefined. In
+ particular SPARC (Sun 4) has problems */
+ if (nbytes >= sizeof (valueT))
+ {
+ mask = 0;
+ if (nbytes > sizeof (valueT))
+ hibit = 0;
+ else
+ hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1);
+ }
+ else
+ {
+ /* Don't store these bits. */
+ mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes);
+ hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1);
+ }
+
+ unmask = ~mask; /* Do store these bits. */
+
+#ifdef NEVER
+ "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
+ mask = ~(unmask >> 1); /* Includes sign bit now. */
+#endif
+
+ get = exp->X_add_number;
+ use = get & unmask;
+ if ((get & mask) != 0
+ && ((get & mask) != mask
+ || (get & hibit) == 0))
+ { /* Leading bits contain both 0s & 1s. */
+ as_warn (_("Value 0x%lx truncated to 0x%lx."),
+ (unsigned long) get, (unsigned long) use);
+ }
+ /* put bytes in right order. */
+ md_number_to_chars (p, use, (int) nbytes);
+ }
+ else if (op == O_big)
+ {
+ unsigned int size;
+ LITTLENUM_TYPE *nums;
+
+ know (nbytes % CHARS_PER_LITTLENUM == 0);
+
+ size = exp->X_add_number * CHARS_PER_LITTLENUM;
+ if (nbytes < size)
+ {
+ as_warn (_("Bignum truncated to %d bytes"), nbytes);
+ size = nbytes;
+ }
+
+ if (target_big_endian)
+ {
+ while (nbytes > size)
+ {
+ md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
+ nbytes -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ }
+
+ nums = generic_bignum + size / CHARS_PER_LITTLENUM;
+ while (size > 0)
+ {
+ --nums;
+ md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
+ size -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ }
+ }
+ else
+ {
+ nums = generic_bignum;
+ while (size > 0)
+ {
+ md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
+ ++nums;
+ size -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ nbytes -= CHARS_PER_LITTLENUM;
+ }
+
+ while (nbytes > 0)
+ {
+ md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
+ nbytes -= CHARS_PER_LITTLENUM;
+ p += CHARS_PER_LITTLENUM;
+ }
+ }
+ }
+ else
+ {
+ memset (p, 0, nbytes);
+
+ /* Now we need to generate a fixS to record the symbol value.
+ This is easy for BFD. For other targets it can be more
+ complex. For very complex cases (currently, the HPPA and
+ NS32K), you can define TC_CONS_FIX_NEW to do whatever you
+ want. For simpler cases, you can define TC_CONS_RELOC to be
+ the name of the reloc code that should be stored in the fixS.
+ If neither is defined, the code uses NO_RELOC if it is
+ defined, and otherwise uses 0. */
+
+#ifdef BFD_ASSEMBLER
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
+#else
+ {
+ bfd_reloc_code_real_type r;
+
+ switch (nbytes)
+ {
+ case 1:
+ r = BFD_RELOC_8;
+ break;
+ case 2:
+ r = BFD_RELOC_16;
+ break;
+ case 4:
+ r = BFD_RELOC_32;
+ break;
+ case 8:
+ r = BFD_RELOC_64;
+ break;
+ default:
+ as_bad (_("unsupported BFD relocation size %u"), nbytes);
+ r = BFD_RELOC_32;
+ break;
+ }
+ fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp,
+ 0, r);
+ }
+#endif
+#else
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
+#else
+ /* Figure out which reloc number to use. Use TC_CONS_RELOC if
+ it is defined, otherwise use NO_RELOC if it is defined,
+ otherwise use 0. */
+#ifndef TC_CONS_RELOC
+#ifdef NO_RELOC
+#define TC_CONS_RELOC NO_RELOC
+#else
+#define TC_CONS_RELOC 0
+#endif
+#endif
+ fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
+ TC_CONS_RELOC);
+#endif /* TC_CONS_FIX_NEW */
+#endif /* BFD_ASSEMBLER */
+ }
+}
+
+#ifdef BITFIELD_CONS_EXPRESSIONS
+
+/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as
+ w:x,y:z, where w and y are bitwidths and x and y are values. They
+ then pack them all together. We do a little better in that we allow
+ them in words, longs, etc. and we'll pack them in target byte order
+ for you.
+
+ The rules are: pack least significat bit first, if a field doesn't
+ entirely fit, put it in the next unit. Overflowing the bitfield is
+ explicitly *not* even a warning. The bitwidth should be considered
+ a "mask".
+
+ To use this function the tc-XXX.h file should define
+ BITFIELD_CONS_EXPRESSIONS. */
+
+static void
+parse_bitfield_cons (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ unsigned int bits_available = BITS_PER_CHAR * nbytes;
+ char *hold = input_line_pointer;
+
+ (void) expression (exp);
+
+ if (*input_line_pointer == ':')
+ { /* bitfields */
+ long value = 0;
+
+ for (;;)
+ {
+ unsigned long width;
+
+ if (*input_line_pointer != ':')
+ {
+ input_line_pointer = hold;
+ break;
+ } /* next piece is not a bitfield */
+
+ /* In the general case, we can't allow
+ full expressions with symbol
+ differences and such. The relocation
+ entries for symbols not defined in this
+ assembly would require arbitrary field
+ widths, positions, and masks which most
+ of our current object formats don't
+ support.
+
+ In the specific case where a symbol
+ *is* defined in this assembly, we
+ *could* build fixups and track it, but
+ this could lead to confusion for the
+ backends. I'm lazy. I'll take any
+ SEG_ABSOLUTE. I think that means that
+ you can use a previous .set or
+ .equ type symbol. xoxorich. */
+
+ if (exp->X_op == O_absent)
+ {
+ as_warn (_("using a bit field width of zero"));
+ exp->X_add_number = 0;
+ exp->X_op = O_constant;
+ } /* implied zero width bitfield */
+
+ if (exp->X_op != O_constant)
+ {
+ *input_line_pointer = '\0';
+ as_bad (_("field width \"%s\" too complex for a bitfield"), hold);
+ *input_line_pointer = ':';
+ demand_empty_rest_of_line ();
+ return;
+ } /* too complex */
+
+ if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
+ {
+ as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"),
+ width, nbytes, (BITS_PER_CHAR * nbytes));
+ width = BITS_PER_CHAR * nbytes;
+ } /* too big */
+
+ if (width > bits_available)
+ {
+ /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
+ input_line_pointer = hold;
+ exp->X_add_number = value;
+ break;
+ } /* won't fit */
+
+ hold = ++input_line_pointer; /* skip ':' */
+
+ (void) expression (exp);
+ if (exp->X_op != O_constant)
+ {
+ char cache = *input_line_pointer;
+
+ *input_line_pointer = '\0';
+ as_bad (_("field value \"%s\" too complex for a bitfield"), hold);
+ *input_line_pointer = cache;
+ demand_empty_rest_of_line ();
+ return;
+ } /* too complex */
+
+ value |= ((~(-1 << width) & exp->X_add_number)
+ << ((BITS_PER_CHAR * nbytes) - bits_available));
+
+ if ((bits_available -= width) == 0
+ || is_it_end_of_statement ()
+ || *input_line_pointer != ',')
+ {
+ break;
+ } /* all the bitfields we're gonna get */
+
+ hold = ++input_line_pointer;
+ (void) expression (exp);
+ } /* forever loop */
+
+ exp->X_add_number = value;
+ exp->X_op = O_constant;
+ exp->X_unsigned = 1;
+ } /* if looks like a bitfield */
+} /* parse_bitfield_cons() */
+
+#endif /* BITFIELD_CONS_EXPRESSIONS */
+
+/* Handle an MRI style string expression. */
+
+static void
+parse_mri_cons (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ if (*input_line_pointer != '\''
+ && (input_line_pointer[1] != '\''
+ || (*input_line_pointer != 'A'
+ && *input_line_pointer != 'E')))
+ TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+ else
+ {
+ unsigned int scan;
+ unsigned int result = 0;
+
+ /* An MRI style string. Cut into as many bytes as will fit into
+ a nbyte chunk, left justify if necessary, and separate with
+ commas so we can try again later. */
+ if (*input_line_pointer == 'A')
+ ++input_line_pointer;
+ else if (*input_line_pointer == 'E')
+ {
+ as_bad (_("EBCDIC constants are not supported"));
+ ++input_line_pointer;
+ }
+
+ input_line_pointer++;
+ for (scan = 0; scan < nbytes; scan++)
+ {
+ if (*input_line_pointer == '\'')
+ {
+ if (input_line_pointer[1] == '\'')
+ {
+ input_line_pointer++;
+ }
+ else
+ break;
+ }
+ result = (result << 8) | (*input_line_pointer++);
+ }
+
+ /* Left justify */
+ while (scan < nbytes)
+ {
+ result <<= 8;
+ scan++;
+ }
+ /* Create correct expression */
+ exp->X_op = O_constant;
+ exp->X_add_number = result;
+ /* Fake it so that we can read the next char too */
+ if (input_line_pointer[0] != '\'' ||
+ (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
+ {
+ input_line_pointer -= 2;
+ input_line_pointer[0] = ',';
+ input_line_pointer[1] = '\'';
+ }
+ else
+ input_line_pointer++;
+ }
+}
+
+#ifdef REPEAT_CONS_EXPRESSIONS
+
+/* Parse a repeat expression for cons. This is used by the MIPS
+ assembler. The format is NUMBER:COUNT; NUMBER appears in the
+ object file COUNT times.
+
+ To use this for a target, define REPEAT_CONS_EXPRESSIONS. */
+
+static void
+parse_repeat_cons (exp, nbytes)
+ expressionS *exp;
+ unsigned int nbytes;
+{
+ expressionS count;
+ register int i;
+
+ expression (exp);
+
+ if (*input_line_pointer != ':')
+ {
+ /* No repeat count. */
+ return;
+ }
+
+ ++input_line_pointer;
+ expression (&count);
+ if (count.X_op != O_constant
+ || count.X_add_number <= 0)
+ {
+ as_warn (_("Unresolvable or nonpositive repeat count; using 1"));
+ return;
+ }
+
+ /* The cons function is going to output this expression once. So we
+ output it count - 1 times. */
+ for (i = count.X_add_number - 1; i > 0; i--)
+ emit_expr (exp, nbytes);
+}
+
+#endif /* REPEAT_CONS_EXPRESSIONS */
+
+/* Parse a floating point number represented as a hex constant. This
+ permits users to specify the exact bits they want in the floating
+ point number. */
+
+static int
+hex_float (float_type, bytes)
+ int float_type;
+ char *bytes;
+{
+ int length;
+ int i;
+
+ switch (float_type)
+ {
+ case 'f':
+ case 'F':
+ case 's':
+ case 'S':
+ length = 4;
+ break;
+
+ case 'd':
+ case 'D':
+ case 'r':
+ case 'R':
+ length = 8;
+ break;
+
+ case 'x':
+ case 'X':
+ length = 12;
+ break;
+
+ case 'p':
+ case 'P':
+ length = 12;
+ break;
+
+ default:
+ as_bad (_("Unknown floating type type '%c'"), float_type);
+ return -1;
+ }
+
+ /* It would be nice if we could go through expression to parse the
+ hex constant, but if we get a bignum it's a pain to sort it into
+ the buffer correctly. */
+ i = 0;
+ while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
+ {
+ int d;
+
+ /* The MRI assembler accepts arbitrary underscores strewn about
+ through the hex constant, so we ignore them as well. */
+ if (*input_line_pointer == '_')
+ {
+ ++input_line_pointer;
+ continue;
+ }
+
+ if (i >= length)
+ {
+ as_warn (_("Floating point constant too large"));
+ return -1;
+ }
+ d = hex_value (*input_line_pointer) << 4;
+ ++input_line_pointer;
+ while (*input_line_pointer == '_')
+ ++input_line_pointer;
+ if (hex_p (*input_line_pointer))
+ {
+ d += hex_value (*input_line_pointer);
+ ++input_line_pointer;
+ }
+ if (target_big_endian)
+ bytes[i] = d;
+ else
+ bytes[length - i - 1] = d;
+ ++i;
+ }
+
+ if (i < length)
+ {
+ if (target_big_endian)
+ memset (bytes + i, 0, length - i);
+ else
+ memset (bytes, 0, length - i);
+ }
+
+ return length;
+}
+
+/*
+ * float_cons()
+ *
+ * CONStruct some more frag chars of .floats .ffloats etc.
+ * Makes 0 or more new frags.
+ * If need_pass_2 == 1, no frags are emitted.
+ * This understands only floating literals, not expressions. Sorry.
+ *
+ * A floating constant is defined by atof_generic(), except it is preceded
+ * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
+ * reading, I decided to be incompatible. This always tries to give you
+ * rounded bits to the precision of the pseudo-op. Former AS did premature
+ * truncatation, restored noisy bits instead of trailing 0s AND gave you
+ * a choice of 2 flavours of noise according to which of 2 floating-point
+ * scanners you directed AS to use.
+ *
+ * In: input_line_pointer->whitespace before, or '0' of flonum.
+ *
+ */
+
+void
+float_cons (float_type)
+ /* Clobbers input_line-pointer, checks end-of-line. */
+ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
+{
+ register char *p;
+ int length; /* Number of chars in an object. */
+ register char *err; /* Error from scanning floating literal. */
+ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ do
+ {
+ /* input_line_pointer->1st char of a flonum (we hope!). */
+ SKIP_WHITESPACE ();
+
+ /* Skip any 0{letter} that may be present. Don't even check if the
+ * letter is legal. Someone may invent a "z" format and this routine
+ * has no use for such information. Lusers beware: you get
+ * diagnostics if your input is ill-conditioned.
+ */
+ if (input_line_pointer[0] == '0'
+ && isalpha ((unsigned char) input_line_pointer[1]))
+ input_line_pointer += 2;
+
+ /* Accept :xxxx, where the x's are hex digits, for a floating
+ point with the exact digits specified. */
+ if (input_line_pointer[0] == ':')
+ {
+ ++input_line_pointer;
+ length = hex_float (float_type, temp);
+ if (length < 0)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ {
+ err = md_atof (float_type, temp, &length);
+ know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
+ know (length > 0);
+ if (err)
+ {
+ as_bad (_("Bad floating literal: %s"), err);
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+
+ if (!need_pass_2)
+ {
+ int count;
+
+ count = 1;
+
+#ifdef REPEAT_CONS_EXPRESSIONS
+ if (*input_line_pointer == ':')
+ {
+ expressionS count_exp;
+
+ ++input_line_pointer;
+ expression (&count_exp);
+ if (count_exp.X_op != O_constant
+ || count_exp.X_add_number <= 0)
+ {
+ as_warn (_("unresolvable or nonpositive repeat count; using 1"));
+ }
+ else
+ count = count_exp.X_add_number;
+ }
+#endif
+
+ while (--count >= 0)
+ {
+ p = frag_more (length);
+ memcpy (p, temp, (unsigned int) length);
+ }
+ }
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+
+ --input_line_pointer; /* Put terminator back into stream. */
+ demand_empty_rest_of_line ();
+} /* float_cons() */
+
+/* Return the size of a LEB128 value */
+
+static inline int
+sizeof_sleb128 (value)
+ offsetT value;
+{
+ register int size = 0;
+ register unsigned byte;
+
+ do
+ {
+ byte = (value & 0x7f);
+ /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
+ Fortunately, we can structure things so that the extra work reduces
+ to a noop on systems that do things "properly". */
+ value = (value >> 7) | ~(-(offsetT)1 >> 7);
+ size += 1;
+ }
+ while (!(((value == 0) && ((byte & 0x40) == 0))
+ || ((value == -1) && ((byte & 0x40) != 0))));
+
+ return size;
+}
+
+static inline int
+sizeof_uleb128 (value)
+ valueT value;
+{
+ register int size = 0;
+ register unsigned byte;
+
+ do
+ {
+ byte = (value & 0x7f);
+ value >>= 7;
+ size += 1;
+ }
+ while (value != 0);
+
+ return size;
+}
+
+int
+sizeof_leb128 (value, sign)
+ valueT value;
+ int sign;
+{
+ if (sign)
+ return sizeof_sleb128 ((offsetT) value);
+ else
+ return sizeof_uleb128 (value);
+}
+
+/* Output a LEB128 value. */
+
+static inline int
+output_sleb128 (p, value)
+ char *p;
+ offsetT value;
+{
+ register char *orig = p;
+ register int more;
+
+ do
+ {
+ unsigned byte = (value & 0x7f);
+
+ /* Sadly, we cannot rely on typical arithmetic right shift behaviour.
+ Fortunately, we can structure things so that the extra work reduces
+ to a noop on systems that do things "properly". */
+ value = (value >> 7) | ~(-(offsetT)1 >> 7);
+
+ more = !((((value == 0) && ((byte & 0x40) == 0))
+ || ((value == -1) && ((byte & 0x40) != 0))));
+ if (more)
+ byte |= 0x80;
+
+ *p++ = byte;
+ }
+ while (more);
+
+ return p - orig;
+}
+
+static inline int
+output_uleb128 (p, value)
+ char *p;
+ valueT value;
+{
+ char *orig = p;
+
+ do
+ {
+ unsigned byte = (value & 0x7f);
+ value >>= 7;
+ if (value != 0)
+ /* More bytes to follow. */
+ byte |= 0x80;
+
+ *p++ = byte;
+ }
+ while (value != 0);
+
+ return p - orig;
+}
+
+int
+output_leb128 (p, value, sign)
+ char *p;
+ valueT value;
+ int sign;
+{
+ if (sign)
+ return output_sleb128 (p, (offsetT) value);
+ else
+ return output_uleb128 (p, value);
+}
+
+/* Do the same for bignums. We combine sizeof with output here in that
+ we don't output for NULL values of P. It isn't really as critical as
+ for "normal" values that this be streamlined. */
+
+static int
+output_big_sleb128 (p, bignum, size)
+ char *p;
+ LITTLENUM_TYPE *bignum;
+ int size;
+{
+ char *orig = p;
+ valueT val = 0;
+ int loaded = 0;
+ unsigned byte;
+
+ /* Strip leading sign extensions off the bignum. */
+ while (size > 0 && bignum[size-1] == (LITTLENUM_TYPE)-1)
+ size--;
+
+ do
+ {
+ if (loaded < 7 && size > 0)
+ {
+ val |= (*bignum << loaded);
+ loaded += 8 * CHARS_PER_LITTLENUM;
+ size--;
+ bignum++;
+ }
+
+ byte = val & 0x7f;
+ loaded -= 7;
+ val >>= 7;
+
+ if (size == 0)
+ {
+ if ((val == 0 && (byte & 0x40) == 0)
+ || (~(val | ~(((valueT)1 << loaded) - 1)) == 0
+ && (byte & 0x40) != 0))
+ byte |= 0x80;
+ }
+
+ if (orig)
+ *p = byte;
+ p++;
+ }
+ while (byte & 0x80);
+
+ return p - orig;
+}
+
+static int
+output_big_uleb128 (p, bignum, size)
+ char *p;
+ LITTLENUM_TYPE *bignum;
+ int size;
+{
+ char *orig = p;
+ valueT val = 0;
+ int loaded = 0;
+ unsigned byte;
+
+ /* Strip leading zeros off the bignum. */
+ /* XXX: Is this needed? */
+ while (size > 0 && bignum[size-1] == 0)
+ size--;
+
+ do
+ {
+ if (loaded < 7 && size > 0)
+ {
+ val |= (*bignum << loaded);
+ loaded += 8 * CHARS_PER_LITTLENUM;
+ size--;
+ bignum++;
+ }
+
+ byte = val & 0x7f;
+ loaded -= 7;
+ val >>= 7;
+
+ if (size > 0 || val)
+ byte |= 0x80;
+
+ if (orig)
+ *p = byte;
+ p++;
+ }
+ while (byte & 0x80);
+
+ return p - orig;
+}
+
+static inline int
+output_big_leb128 (p, bignum, size, sign)
+ char *p;
+ LITTLENUM_TYPE *bignum;
+ int size, sign;
+{
+ if (sign)
+ return output_big_sleb128 (p, bignum, size);
+ else
+ return output_big_uleb128 (p, bignum, size);
+}
+
+/* Generate the appropriate fragments for a given expression to emit a
+ leb128 value. */
+
+void
+emit_leb128_expr(exp, sign)
+ expressionS *exp;
+ int sign;
+{
+ operatorT op = exp->X_op;
+
+ if (op == O_absent || op == O_illegal)
+ {
+ as_warn (_("zero assumed for missing expression"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_big && exp->X_add_number <= 0)
+ {
+ as_bad (_("floating point number invalid; zero assumed"));
+ exp->X_add_number = 0;
+ op = O_constant;
+ }
+ else if (op == O_register)
+ {
+ as_warn (_("register value used as expression"));
+ op = O_constant;
+ }
+
+ if (op == O_constant)
+ {
+ /* If we've got a constant, emit the thing directly right now. */
+
+ valueT value = exp->X_add_number;
+ int size;
+ char *p;
+
+ size = sizeof_leb128 (value, sign);
+ p = frag_more (size);
+ output_leb128 (p, value, sign);
+ }
+ else if (op == O_big)
+ {
+ /* O_big is a different sort of constant. */
+
+ int size;
+ char *p;
+
+ size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
+ p = frag_more (size);
+ output_big_leb128 (p, generic_bignum, exp->X_add_number, sign);
+ }
+ else
+ {
+ /* Otherwise, we have to create a variable sized fragment and
+ resolve things later. */
+
+ frag_var (rs_leb128, sizeof_uleb128 (~(valueT)0), 0, sign,
+ make_expr_symbol (exp), 0, (char *) NULL);
+ }
+}
+
+/* Parse the .sleb128 and .uleb128 pseudos. */
+
+void
+s_leb128 (sign)
+ int sign;
+{
+ expressionS exp;
+
+ do {
+ expression (&exp);
+ emit_leb128_expr (&exp, sign);
+ } while (*input_line_pointer++ == ',');
+
+ input_line_pointer--;
+ demand_empty_rest_of_line ();
+}
+
+/*
+ * stringer()
+ *
+ * We read 0 or more ',' seperated, double-quoted strings.
+ *
+ * Caller should have checked need_pass_2 is FALSE because we don't check it.
+ */
+
+
+void
+stringer (append_zero) /* Worker to do .ascii etc statements. */
+ /* Checks end-of-line. */
+ register int append_zero; /* 0: don't append '\0', else 1 */
+{
+ register unsigned int c;
+ char *start;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ /*
+ * The following awkward logic is to parse ZERO or more strings,
+ * comma separated. Recall a string expression includes spaces
+ * before the opening '\"' and spaces after the closing '\"'.
+ * We fake a leading ',' if there is (supposed to be)
+ * a 1st, expression. We keep demanding expressions for each
+ * ','.
+ */
+ if (is_it_end_of_statement ())
+ {
+ c = 0; /* Skip loop. */
+ ++input_line_pointer; /* Compensate for end of loop. */
+ }
+ else
+ {
+ c = ','; /* Do loop. */
+ }
+ while (c == ',' || c == '<' || c == '"')
+ {
+ SKIP_WHITESPACE ();
+ switch (*input_line_pointer)
+ {
+ case '\"':
+ ++input_line_pointer; /*->1st char of string. */
+ start = input_line_pointer;
+ while (is_a_char (c = next_char_of_string ()))
+ {
+ FRAG_APPEND_1_CHAR (c);
+ }
+ if (append_zero)
+ {
+ FRAG_APPEND_1_CHAR (0);
+ }
+ know (input_line_pointer[-1] == '\"');
+
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+ /* In ELF, when gcc is emitting DWARF 1 debugging output, it
+ will emit .string with a filename in the .debug section
+ after a sequence of constants. See the comment in
+ emit_expr for the sequence. emit_expr will set
+ dwarf_file_string to non-zero if this string might be a
+ source file name. */
+ if (strcmp (segment_name (now_seg), ".debug") != 0)
+ dwarf_file_string = 0;
+ else if (dwarf_file_string)
+ {
+ c = input_line_pointer[-1];
+ input_line_pointer[-1] = '\0';
+ listing_source_file (start);
+ input_line_pointer[-1] = c;
+ }
+#endif
+#endif
+
+ break;
+ case '<':
+ input_line_pointer++;
+ c = get_single_number ();
+ FRAG_APPEND_1_CHAR (c);
+ if (*input_line_pointer != '>')
+ {
+ as_bad (_("Expected <nn>"));
+ }
+ input_line_pointer++;
+ break;
+ case ',':
+ input_line_pointer++;
+ break;
+ }
+ SKIP_WHITESPACE ();
+ c = *input_line_pointer;
+ }
+
+ demand_empty_rest_of_line ();
+} /* stringer() */
+
+/* FIXME-SOMEDAY: I had trouble here on characters with the
+ high bits set. We'll probably also have trouble with
+ multibyte chars, wide chars, etc. Also be careful about
+ returning values bigger than 1 byte. xoxorich. */
+
+unsigned int
+next_char_of_string ()
+{
+ register unsigned int c;
+
+ c = *input_line_pointer++ & CHAR_MASK;
+ switch (c)
+ {
+ case '\"':
+ c = NOT_A_CHAR;
+ break;
+
+ case '\n':
+ as_warn (_("Unterminated string: Newline inserted."));
+ bump_line_counters ();
+ break;
+
+#ifndef NO_STRING_ESCAPES
+ case '\\':
+ switch (c = *input_line_pointer++)
+ {
+ case 'b':
+ c = '\b';
+ break;
+
+ case 'f':
+ c = '\f';
+ break;
+
+ case 'n':
+ c = '\n';
+ break;
+
+ case 'r':
+ c = '\r';
+ break;
+
+ case 't':
+ c = '\t';
+ break;
+
+ case 'v':
+ c = '\013';
+ break;
+
+ case '\\':
+ case '"':
+ break; /* As itself. */
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ long number;
+ int i;
+
+ for (i = 0, number = 0; isdigit (c) && i < 3; c = *input_line_pointer++, i++)
+ {
+ number = number * 8 + c - '0';
+ }
+ c = number & 0xff;
+ }
+ --input_line_pointer;
+ break;
+
+ case 'x':
+ case 'X':
+ {
+ long number;
+
+ number = 0;
+ c = *input_line_pointer++;
+ while (isxdigit (c))
+ {
+ if (isdigit (c))
+ number = number * 16 + c - '0';
+ else if (isupper (c))
+ number = number * 16 + c - 'A' + 10;
+ else
+ number = number * 16 + c - 'a' + 10;
+ c = *input_line_pointer++;
+ }
+ c = number & 0xff;
+ --input_line_pointer;
+ }
+ break;
+
+ case '\n':
+ /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
+ as_warn (_("Unterminated string: Newline inserted."));
+ c = '\n';
+ bump_line_counters ();
+ break;
+
+ default:
+
+#ifdef ONLY_STANDARD_ESCAPES
+ as_bad (_("Bad escaped character in string, '?' assumed"));
+ c = '?';
+#endif /* ONLY_STANDARD_ESCAPES */
+
+ break;
+ } /* switch on escaped char */
+ break;
+#endif /* ! defined (NO_STRING_ESCAPES) */
+
+ default:
+ break;
+ } /* switch on char */
+ return (c);
+} /* next_char_of_string() */
+
+static segT
+get_segmented_expression (expP)
+ register expressionS *expP;
+{
+ register segT retval;
+
+ retval = expression (expP);
+ if (expP->X_op == O_illegal
+ || expP->X_op == O_absent
+ || expP->X_op == O_big)
+ {
+ as_bad (_("expected address expression; zero assumed"));
+ expP->X_op = O_constant;
+ expP->X_add_number = 0;
+ retval = absolute_section;
+ }
+ return retval;
+}
+
+static segT
+get_known_segmented_expression (expP)
+ register expressionS *expP;
+{
+ register segT retval;
+
+ if ((retval = get_segmented_expression (expP)) == undefined_section)
+ {
+ /* There is no easy way to extract the undefined symbol from the
+ expression. */
+ if (expP->X_add_symbol != NULL
+ && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
+ as_warn (_("symbol \"%s\" undefined; zero assumed"),
+ S_GET_NAME (expP->X_add_symbol));
+ else
+ as_warn (_("some symbol undefined; zero assumed"));
+ retval = absolute_section;
+ expP->X_op = O_constant;
+ expP->X_add_number = 0;
+ }
+ know (retval == absolute_section || SEG_NORMAL (retval));
+ return (retval);
+} /* get_known_segmented_expression() */
+
+offsetT
+get_absolute_expression ()
+{
+ expressionS exp;
+
+ expression (&exp);
+ if (exp.X_op != O_constant)
+ {
+ if (exp.X_op != O_absent)
+ as_bad (_("bad or irreducible absolute expression; zero assumed"));
+ exp.X_add_number = 0;
+ }
+ return exp.X_add_number;
+}
+
+char /* return terminator */
+get_absolute_expression_and_terminator (val_pointer)
+ long *val_pointer; /* return value of expression */
+{
+ /* FIXME: val_pointer should probably be offsetT *. */
+ *val_pointer = (long) get_absolute_expression ();
+ return (*input_line_pointer++);
+}
+
+/*
+ * demand_copy_C_string()
+ *
+ * Like demand_copy_string, but return NULL if the string contains any '\0's.
+ * Give a warning if that happens.
+ */
+char *
+demand_copy_C_string (len_pointer)
+ int *len_pointer;
+{
+ register char *s;
+
+ if ((s = demand_copy_string (len_pointer)) != 0)
+ {
+ register int len;
+
+ for (len = *len_pointer; len > 0; len--)
+ {
+ if (*s == 0)
+ {
+ s = 0;
+ len = 1;
+ *len_pointer = 0;
+ as_bad (_("This string may not contain \'\\0\'"));
+ }
+ }
+ }
+ return s;
+}
+
+/*
+ * demand_copy_string()
+ *
+ * Demand string, but return a safe (=private) copy of the string.
+ * Return NULL if we can't read a string here.
+ */
+char *
+demand_copy_string (lenP)
+ int *lenP;
+{
+ register unsigned int c;
+ register int len;
+ char *retval;
+
+ len = 0;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '\"')
+ {
+ input_line_pointer++; /* Skip opening quote. */
+
+ while (is_a_char (c = next_char_of_string ()))
+ {
+ obstack_1grow (&notes, c);
+ len++;
+ }
+ /* JF this next line is so demand_copy_C_string will return a
+ null terminated string. */
+ obstack_1grow (&notes, '\0');
+ retval = obstack_finish (&notes);
+ }
+ else
+ {
+ as_warn (_("Missing string"));
+ retval = NULL;
+ ignore_rest_of_line ();
+ }
+ *lenP = len;
+ return (retval);
+} /* demand_copy_string() */
+
+/*
+ * is_it_end_of_statement()
+ *
+ * In: Input_line_pointer->next character.
+ *
+ * Do: Skip input_line_pointer over all whitespace.
+ *
+ * Out: 1 if input_line_pointer->end-of-line.
+*/
+int
+is_it_end_of_statement ()
+{
+ SKIP_WHITESPACE ();
+ return (is_end_of_line[(unsigned char) *input_line_pointer]);
+} /* is_it_end_of_statement() */
+
+void
+equals (sym_name, reassign)
+ char *sym_name;
+ int reassign;
+{
+ register symbolS *symbolP; /* symbol we are working with */
+ char *stop = NULL;
+ char stopc;
+
+ input_line_pointer++;
+ if (*input_line_pointer == '=')
+ input_line_pointer++;
+
+ while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
+ input_line_pointer++;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
+ if (sym_name[0] == '.' && sym_name[1] == '\0')
+ {
+ /* Turn '. = mumble' into a .org mumble */
+ register segT segment;
+ expressionS exp;
+
+ segment = get_known_segmented_expression (&exp);
+ if (!need_pass_2)
+ do_org (segment, &exp, 0);
+ }
+ else
+ {
+ symbolP = symbol_find_or_make (sym_name);
+ /* Permit register names to be redefined. */
+ if (! reassign
+ && S_IS_DEFINED (symbolP)
+ && S_GET_SEGMENT (symbolP) != reg_section)
+ as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+ pseudo_set (symbolP);
+ }
+
+ if (flag_mri)
+ {
+ ignore_rest_of_line (); /* check garbage after the expression */
+ mri_comment_end (stop, stopc);
+ }
+} /* equals() */
+
+/* .include -- include a file at this point. */
+
+/* ARGSUSED */
+void
+s_include (arg)
+ int arg;
+{
+ char *newbuf;
+ char *filename;
+ int i;
+ FILE *try;
+ char *path;
+
+ if (! flag_m68k_mri)
+ {
+ filename = demand_copy_string (&i);
+ if (filename == NULL)
+ {
+ /* demand_copy_string has already printed an error and
+ called ignore_rest_of_line. */
+ return;
+ }
+ }
+ else
+ {
+ SKIP_WHITESPACE ();
+ i = 0;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != ' '
+ && *input_line_pointer != '\t')
+ {
+ obstack_1grow (&notes, *input_line_pointer);
+ ++input_line_pointer;
+ ++i;
+ }
+ obstack_1grow (&notes, '\0');
+ filename = obstack_finish (&notes);
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
+ demand_empty_rest_of_line ();
+ path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ );
+ for (i = 0; i < include_dir_count; i++)
+ {
+ strcpy (path, include_dirs[i]);
+ strcat (path, "/");
+ strcat (path, filename);
+ if (0 != (try = fopen (path, "r")))
+ {
+ fclose (try);
+ goto gotit;
+ }
+ }
+ free (path);
+ path = filename;
+gotit:
+ /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
+ register_dependency (path);
+ newbuf = input_scrub_include_file (path, input_line_pointer);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+} /* s_include() */
+
+void
+add_include_dir (path)
+ char *path;
+{
+ int i;
+
+ if (include_dir_count == 0)
+ {
+ include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
+ include_dirs[0] = "."; /* Current dir */
+ include_dir_count = 2;
+ }
+ else
+ {
+ include_dir_count++;
+ include_dirs = (char **) realloc (include_dirs,
+ include_dir_count * sizeof (*include_dirs));
+ }
+
+ include_dirs[include_dir_count - 1] = path; /* New one */
+
+ i = strlen (path);
+ if (i > include_dir_maxlen)
+ include_dir_maxlen = i;
+} /* add_include_dir() */
+
+/* Output debugging information to denote the source file. */
+
+static void
+generate_file_debug ()
+{
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_file ();
+}
+
+/* Output line number debugging information for the current source line. */
+
+void
+generate_lineno_debug ()
+{
+#ifdef ECOFF_DEBUGGING
+ /* ECOFF assemblers automatically generate debugging information.
+ FIXME: This should probably be handled elsewhere. */
+ if (debug_type == DEBUG_UNSPECIFIED)
+ {
+ if (ECOFF_DEBUGGING && ecoff_no_current_file ())
+ debug_type = DEBUG_ECOFF;
+ else
+ debug_type = DEBUG_NONE;
+ }
+#endif
+
+ switch (debug_type)
+ {
+ case DEBUG_UNSPECIFIED:
+ case DEBUG_NONE:
+ break;
+ case DEBUG_STABS:
+ stabs_generate_asm_lineno ();
+ break;
+ case DEBUG_ECOFF:
+ ecoff_generate_asm_lineno ();
+ break;
+ case DEBUG_DWARF:
+ case DEBUG_DWARF2:
+ /* FIXME. */
+ break;
+ }
+}
+
+/* Output debugging information to mark a function entry point or end point.
+ END_P is zero for .func, and non-zero for .endfunc. */
+
+void
+s_func (end_p)
+ int end_p;
+{
+ do_s_func (end_p, NULL);
+}
+
+/* Subroutine of s_func so targets can choose a different default prefix.
+ If DEFAULT_PREFIX is NULL, use the target's "leading char". */
+
+void
+do_s_func (end_p, default_prefix)
+ int end_p;
+ const char *default_prefix;
+{
+ /* Record the current function so that we can issue an error message for
+ misplaced .func,.endfunc, and also so that .endfunc needs no
+ arguments. */
+ static char *current_name;
+ static char *current_label;
+
+ if (end_p)
+ {
+ if (current_name == NULL)
+ {
+ as_bad (_("missing .func"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_endfunc (current_name, current_label);
+
+ current_name = current_label = NULL;
+ }
+ else /* ! end_p */
+ {
+ char *name,*label;
+ char delim1,delim2;
+
+ if (current_name != NULL)
+ {
+ as_bad (_(".endfunc missing for previous .func"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ name = input_line_pointer;
+ delim1 = get_symbol_end ();
+ name = xstrdup (name);
+ *input_line_pointer = delim1;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ if (default_prefix)
+ asprintf (&label, "%s%s", default_prefix, name);
+ else
+ {
+ char leading_char = 0;
+#ifdef BFD_ASSEMBLER
+ leading_char = bfd_get_symbol_leading_char (stdoutput);
+#endif
+ /* Missing entry point, use function's name with the leading
+ char prepended. */
+ if (leading_char)
+ asprintf (&label, "%c%s", leading_char, name);
+ else
+ label = name;
+ }
+ }
+ else
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ label = input_line_pointer;
+ delim2 = get_symbol_end ();
+ label = xstrdup (label);
+ *input_line_pointer = delim2;
+ }
+
+ if (debug_type == DEBUG_STABS)
+ stabs_generate_asm_func (name, label);
+
+ current_name = name;
+ current_label = label;
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+void
+s_ignore (arg)
+ int arg;
+{
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ ++input_line_pointer;
+ }
+ ++input_line_pointer;
+}
+
+
+void
+read_print_statistics (file)
+ FILE *file;
+{
+ hash_print_statistics (file, "pseudo-op table", po_hash);
+}
+
+/* end of read.c */
diff --git a/gas/read.h b/gas/read.h
new file mode 100644
index 00000000000..61e20172be8
--- /dev/null
+++ b/gas/read.h
@@ -0,0 +1,166 @@
+/* read.h - of read.c
+ Copyright (C) 1986, 90, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern char *input_line_pointer;/* -> char we are parsing now. */
+
+#define PERMIT_WHITESPACE /* Define to make whitespace be allowed in */
+/* many syntactically unnecessary places. */
+/* Normally undefined. For compatibility */
+/* with ancient GNU cc. */
+/* #undef PERMIT_WHITESPACE */
+
+#ifdef PERMIT_WHITESPACE
+#define SKIP_WHITESPACE() {if (* input_line_pointer == ' ') ++ input_line_pointer;}
+#else
+#define SKIP_WHITESPACE() know(*input_line_pointer != ' ' )
+#endif
+
+
+#define LEX_NAME (1) /* may continue a name */
+#define LEX_BEGIN_NAME (2) /* may begin a name */
+
+#define is_name_beginner(c) \
+ ( lex_type[(unsigned char) (c)] & LEX_BEGIN_NAME )
+#define is_part_of_name(c) \
+ ( lex_type[(unsigned char) (c)] & LEX_NAME )
+
+#ifndef is_a_char
+#define CHAR_MASK (0xff)
+#define NOT_A_CHAR (CHAR_MASK+1)
+#define is_a_char(c) (((unsigned)(c)) <= CHAR_MASK)
+#endif /* is_a_char() */
+
+extern char lex_type[];
+extern char is_end_of_line[];
+
+extern int is_it_end_of_statement PARAMS ((void));
+
+extern int target_big_endian;
+
+/* These are initialized by the CPU specific target files (tc-*.c). */
+extern const char comment_chars[];
+extern const char line_comment_chars[];
+extern const char line_separator_chars[];
+
+/* Table of -I directories. */
+extern char **include_dirs;
+extern int include_dir_count;
+extern int include_dir_maxlen;
+
+/* The offset in the absolute section. */
+extern addressT abs_section_offset;
+
+/* The label on a line, used by some of the pseudo-ops. */
+extern symbolS *line_label;
+
+/* This is used to support MRI common sections. */
+extern symbolS *mri_common_symbol;
+
+/* Possible arguments to .linkonce. */
+enum linkonce_type
+{
+ LINKONCE_UNSET = 0,
+ LINKONCE_DISCARD,
+ LINKONCE_ONE_ONLY,
+ LINKONCE_SAME_SIZE,
+ LINKONCE_SAME_CONTENTS
+};
+
+extern void pop_insert PARAMS ((const pseudo_typeS *));
+extern unsigned int get_stab_string_offset
+ PARAMS ((const char *string, const char *stabstr_secname));
+extern char *demand_copy_C_string PARAMS ((int *len_pointer));
+extern char get_absolute_expression_and_terminator
+ PARAMS ((long *val_pointer));
+extern offsetT get_absolute_expression PARAMS ((void));
+extern unsigned int next_char_of_string PARAMS ((void));
+extern void s_mri_sect PARAMS ((char *));
+extern char *mri_comment_field PARAMS ((char *));
+extern void mri_comment_end PARAMS ((char *, int));
+extern void add_include_dir PARAMS ((char *path));
+extern void cons PARAMS ((int nbytes));
+extern void demand_empty_rest_of_line PARAMS ((void));
+extern void emit_expr PARAMS ((expressionS *exp, unsigned int nbytes));
+extern void emit_leb128_expr PARAMS ((expressionS *, int));
+extern void equals PARAMS ((char *sym_name, int reassign));
+extern void float_cons PARAMS ((int float_type));
+extern void ignore_rest_of_line PARAMS ((void));
+extern void discard_rest_of_line PARAMS ((void));
+extern int output_leb128 PARAMS ((char *, valueT, int sign));
+extern void pseudo_set PARAMS ((symbolS * symbolP));
+extern void read_a_source_file PARAMS ((char *name));
+extern void read_begin PARAMS ((void));
+extern void read_print_statistics PARAMS ((FILE *));
+extern int sizeof_leb128 PARAMS ((valueT, int sign));
+extern void stabs_generate_asm_file PARAMS ((void));
+extern void stabs_generate_asm_lineno PARAMS ((void));
+extern void stabs_generate_asm_func PARAMS ((const char *, const char *));
+extern void stabs_generate_asm_endfunc PARAMS ((const char *, const char *));
+
+extern void generate_lineno_debug PARAMS ((void));
+
+extern void s_abort PARAMS ((int));
+extern void s_align_bytes PARAMS ((int arg));
+extern void s_align_ptwo PARAMS ((int));
+extern void s_app_file PARAMS ((int));
+extern void s_app_line PARAMS ((int));
+extern void s_comm PARAMS ((int));
+extern void s_data PARAMS ((int));
+extern void s_desc PARAMS ((int));
+extern void s_else PARAMS ((int arg));
+extern void s_end PARAMS ((int arg));
+extern void s_endif PARAMS ((int arg));
+extern void s_err PARAMS ((int));
+extern void s_fail PARAMS ((int));
+extern void s_fill PARAMS ((int));
+extern void s_float_space PARAMS ((int mult));
+extern void s_func PARAMS ((int));
+extern void do_s_func PARAMS ((int, const char *));
+extern void s_globl PARAMS ((int arg));
+extern void s_if PARAMS ((int arg));
+extern void s_ifc PARAMS ((int arg));
+extern void s_ifdef PARAMS ((int arg));
+extern void s_ifeqs PARAMS ((int arg));
+extern void s_ignore PARAMS ((int arg));
+extern void s_include PARAMS ((int arg));
+extern void s_irp PARAMS ((int arg));
+extern void s_lcomm PARAMS ((int needs_align));
+extern void s_lcomm_bytes PARAMS ((int needs_align));
+extern void s_leb128 PARAMS ((int sign));
+extern void s_linkonce PARAMS ((int));
+extern void s_lsym PARAMS ((int));
+extern void s_macro PARAMS ((int));
+extern void s_mexit PARAMS ((int));
+extern void s_mri PARAMS ((int));
+extern void s_mri_common PARAMS ((int));
+extern void s_org PARAMS ((int));
+extern void s_print PARAMS ((int));
+extern void s_purgem PARAMS ((int));
+extern void s_rept PARAMS ((int));
+extern void s_set PARAMS ((int));
+extern void s_space PARAMS ((int mult));
+extern void s_stab PARAMS ((int what));
+extern void s_struct PARAMS ((int));
+extern void s_text PARAMS ((int));
+extern void stringer PARAMS ((int append_zero));
+extern void s_xstab PARAMS ((int what));
+extern void s_rva PARAMS ((int));
+
+/* end of read.h */
diff --git a/gas/sb.c b/gas/sb.c
new file mode 100644
index 00000000000..6ec23fcdb92
--- /dev/null
+++ b/gas/sb.c
@@ -0,0 +1,289 @@
+/* sb.c - string buffer manipulation routines
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "config.h"
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include "libiberty.h"
+#include "sb.h"
+
+/* These routines are about manipulating strings.
+
+ They are managed in things called `sb's which is an abbreviation
+ for string buffers. An sb has to be created, things can be glued
+ on to it, and at the end of it's life it should be freed. The
+ contents should never be pointed at whilst it is still growing,
+ since it could be moved at any time
+
+ eg:
+ sb_new (&foo);
+ sb_grow... (&foo,...);
+ use foo->ptr[*];
+ sb_kill (&foo);
+
+*/
+
+#define dsize 5
+
+static void sb_check PARAMS ((sb *, int));
+
+/* Statistics of sb structures. */
+
+int string_count[sb_max_power_two];
+
+/* Free list of sb structures. */
+
+static sb_list_vector free_list;
+
+/* initializes an sb. */
+
+void
+sb_build (ptr, size)
+ sb *ptr;
+ int size;
+{
+ /* see if we can find one to allocate */
+ sb_element *e;
+
+ if (size > sb_max_power_two)
+ abort ();
+
+ e = free_list.size[size];
+ if (!e)
+ {
+ /* nothing there, allocate one and stick into the free list */
+ e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size));
+ e->next = free_list.size[size];
+ e->size = 1 << size;
+ free_list.size[size] = e;
+ string_count[size]++;
+ }
+
+ /* remove from free list */
+
+ free_list.size[size] = e->next;
+
+ /* copy into callers world */
+ ptr->ptr = e->data;
+ ptr->pot = size;
+ ptr->len = 0;
+ ptr->item = e;
+}
+
+
+void
+sb_new (ptr)
+ sb *ptr;
+{
+ sb_build (ptr, dsize);
+}
+
+/* deallocate the sb at ptr */
+
+void
+sb_kill (ptr)
+ sb *ptr;
+{
+ /* return item to free list */
+ ptr->item->next = free_list.size[ptr->pot];
+ free_list.size[ptr->pot] = ptr->item;
+}
+
+/* add the sb at s to the end of the sb at ptr */
+
+void
+sb_add_sb (ptr, s)
+ sb *ptr;
+ sb *s;
+{
+ sb_check (ptr, s->len);
+ memcpy (ptr->ptr + ptr->len, s->ptr, s->len);
+ ptr->len += s->len;
+}
+
+/* make sure that the sb at ptr has room for another len characters,
+ and grow it if it doesn't. */
+
+static void
+sb_check (ptr, len)
+ sb *ptr;
+ int len;
+{
+ if (ptr->len + len >= 1 << ptr->pot)
+ {
+ sb tmp;
+ int pot = ptr->pot;
+ while (ptr->len + len >= 1 << pot)
+ pot++;
+ sb_build (&tmp, pot);
+ sb_add_sb (&tmp, ptr);
+ sb_kill (ptr);
+ *ptr = tmp;
+ }
+}
+
+/* make the sb at ptr point back to the beginning. */
+
+void
+sb_reset (ptr)
+ sb *ptr;
+{
+ ptr->len = 0;
+}
+
+/* add character c to the end of the sb at ptr. */
+
+void
+sb_add_char (ptr, c)
+ sb *ptr;
+ int c;
+{
+ sb_check (ptr, 1);
+ ptr->ptr[ptr->len++] = c;
+}
+
+/* add null terminated string s to the end of sb at ptr. */
+
+void
+sb_add_string (ptr, s)
+ sb *ptr;
+ const char *s;
+{
+ int len = strlen (s);
+ sb_check (ptr, len);
+ memcpy (ptr->ptr + ptr->len, s, len);
+ ptr->len += len;
+}
+
+/* add string at s of length len to sb at ptr */
+
+void
+sb_add_buffer (ptr, s, len)
+ sb *ptr;
+ const char *s;
+ int len;
+{
+ sb_check (ptr, len);
+ memcpy (ptr->ptr + ptr->len, s, len);
+ ptr->len += len;
+}
+
+/* print the sb at ptr to the output file */
+
+void
+sb_print (outfile, ptr)
+ FILE *outfile;
+ sb *ptr;
+{
+ int i;
+ int nc = 0;
+
+ for (i = 0; i < ptr->len; i++)
+ {
+ if (nc)
+ {
+ fprintf (outfile, ",");
+ }
+ fprintf (outfile, "%d", ptr->ptr[i]);
+ nc = 1;
+ }
+}
+
+void
+sb_print_at (outfile, idx, ptr)
+ FILE *outfile;
+ int idx;
+ sb *ptr;
+{
+ int i;
+ for (i = idx; i < ptr->len; i++)
+ putc (ptr->ptr[i], outfile);
+}
+
+/* put a null at the end of the sb at in and return the start of the
+ string, so that it can be used as an arg to printf %s. */
+
+char *
+sb_name (in)
+ sb *in;
+{
+ /* stick a null on the end of the string */
+ sb_add_char (in, 0);
+ return in->ptr;
+}
+
+/* like sb_name, but don't include the null byte in the string. */
+
+char *
+sb_terminate (in)
+ sb *in;
+{
+ sb_add_char (in, 0);
+ --in->len;
+ return in->ptr;
+}
+
+/* start at the index idx into the string in sb at ptr and skip
+ whitespace. return the index of the first non whitespace character */
+
+int
+sb_skip_white (idx, ptr)
+ int idx;
+ sb *ptr;
+{
+ while (idx < ptr->len
+ && (ptr->ptr[idx] == ' '
+ || ptr->ptr[idx] == '\t'))
+ idx++;
+ return idx;
+}
+
+/* start at the index idx into the sb at ptr. skips whitespace,
+ a comma and any following whitespace. returnes the index of the
+ next character. */
+
+int
+sb_skip_comma (idx, ptr)
+ int idx;
+ sb *ptr;
+{
+ while (idx < ptr->len
+ && (ptr->ptr[idx] == ' '
+ || ptr->ptr[idx] == '\t'))
+ idx++;
+
+ if (idx < ptr->len
+ && ptr->ptr[idx] == ',')
+ idx++;
+
+ while (idx < ptr->len
+ && (ptr->ptr[idx] == ' '
+ || ptr->ptr[idx] == '\t'))
+ idx++;
+
+ return idx;
+}
diff --git a/gas/sb.h b/gas/sb.h
new file mode 100644
index 00000000000..7e6daf167de
--- /dev/null
+++ b/gas/sb.h
@@ -0,0 +1,99 @@
+/* sb.h - header file for string buffer manipulation routines
+ Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+
+ Written by Steve and Judy Chamberlain of Cygnus Support,
+ sac@cygnus.com
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef SB_H
+
+#define SB_H
+
+#include <stdio.h>
+#include "ansidecl.h"
+
+/* string blocks
+
+ I had a couple of choices when deciding upon this data structure.
+ gas uses null terminated strings for all its internal work. This
+ often means that parts of the program that want to examine
+ substrings have to manipulate the data in the string to do the
+ right thing (a common operation is to single out a bit of text by
+ saving away the character after it, nulling it out, operating on
+ the substring and then replacing the character which was under the
+ null). This is a pain and I remember a load of problems that I had with
+ code in gas which almost got this right. Also, it's harder to grow and
+ allocate null terminated strings efficiently.
+
+ Obstacks provide all the functionality needed, but are too
+ complicated, hence the sb.
+
+ An sb is allocated by the caller, and is initialzed to point to an
+ sb_element. sb_elements are kept on a free lists, and used when
+ needed, replaced onto the free list when unused.
+ */
+
+#define sb_max_power_two 30 /* don't allow strings more than
+ 2^sb_max_power_two long */
+/* structure of an sb */
+typedef struct sb
+ {
+ char *ptr; /* points to the current block. */
+ int len; /* how much is used. */
+ int pot; /* the maximum length is 1<<pot */
+ struct le *item;
+ }
+sb;
+
+/* Structure of the free list object of an sb */
+typedef struct le
+ {
+ struct le *next;
+ int size;
+ char data[1];
+ }
+sb_element;
+
+/* The free list */
+typedef struct
+ {
+ sb_element *size[sb_max_power_two];
+ } sb_list_vector;
+
+extern int string_count[sb_max_power_two];
+
+extern void sb_build PARAMS ((sb *, int));
+extern void sb_new PARAMS ((sb *));
+extern void sb_kill PARAMS ((sb *));
+extern void sb_add_sb PARAMS ((sb *, sb *));
+extern void sb_reset PARAMS ((sb *));
+extern void sb_add_char PARAMS ((sb *, int));
+extern void sb_add_string PARAMS ((sb *, const char *));
+extern void sb_add_buffer PARAMS ((sb *, const char *, int));
+extern void sb_print PARAMS ((FILE *, sb *));
+extern void sb_print_at PARAMS ((FILE *, int, sb *));
+extern char *sb_name PARAMS ((sb *));
+extern char *sb_terminate PARAMS ((sb *));
+extern int sb_skip_white PARAMS ((int, sb *));
+extern int sb_skip_comma PARAMS ((int, sb *));
+
+/* Actually in input-scrub.c. */
+extern void input_scrub_include_sb PARAMS ((sb *, char *));
+
+#endif /* SB_H */
diff --git a/gas/stabs.c b/gas/stabs.c
new file mode 100644
index 00000000000..db7e1bfb6d3
--- /dev/null
+++ b/gas/stabs.c
@@ -0,0 +1,632 @@
+/* Generic stabs parsing for gas.
+ Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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,
+or (at your option) any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "as.h"
+#include "obstack.h"
+#include "subsegs.h"
+#include "ecoff.h"
+
+/* We need this, despite the apparent object format dependency, since
+ it defines stab types, which all object formats can use now. */
+
+#include "aout/stab_gnu.h"
+
+static void s_stab_generic PARAMS ((int, char *, char *));
+static void generate_asm_file PARAMS ((int, char *));
+
+/* Allow backends to override the names used for the stab sections. */
+#ifndef STAB_SECTION_NAME
+#define STAB_SECTION_NAME ".stab"
+#endif
+
+#ifndef STAB_STRING_SECTION_NAME
+#define STAB_STRING_SECTION_NAME ".stabstr"
+#endif
+
+/* Non-zero if we're in the middle of a .func function, in which case
+ stabs_generate_asm_lineno emits function relative line number stabs.
+ Otherwise it emits line number stabs with absolute addresses. Note that
+ both cases only apply to assembler code assembled with -gstabs. */
+static int in_dot_func_p;
+
+/* Label at start of current function if in_dot_func_p != 0. */
+static const char *current_function_label;
+
+/*
+ * Handle .stabX directives, which used to be open-coded.
+ * So much creeping featurism overloaded the semantics that we decided
+ * to put all .stabX thinking in one place. Here.
+ *
+ * We try to make any .stabX directive legal. Other people's AS will often
+ * do assembly-time consistency checks: eg assigning meaning to n_type bits
+ * and "protecting" you from setting them to certain values. (They also zero
+ * certain bits before emitting symbols. Tut tut.)
+ *
+ * If an expression is not absolute we either gripe or use the relocation
+ * information. Other people's assemblers silently forget information they
+ * don't need and invent information they need that you didn't supply.
+ */
+
+/*
+ * Build a string dictionary entry for a .stabX symbol.
+ * The symbol is added to the .<secname>str section.
+ */
+
+#ifndef SEPARATE_STAB_SECTIONS
+#define SEPARATE_STAB_SECTIONS 0
+#endif
+
+unsigned int
+get_stab_string_offset (string, stabstr_secname)
+ const char *string;
+ const char *stabstr_secname;
+{
+ unsigned int length;
+ unsigned int retval;
+ segT save_seg;
+ subsegT save_subseg;
+ segT seg;
+ char *p;
+
+ if (! SEPARATE_STAB_SECTIONS)
+ abort ();
+
+ length = strlen (string);
+
+ save_seg = now_seg;
+ save_subseg = now_subseg;
+
+ /* Create the stab string section. */
+ seg = subseg_new (stabstr_secname, 0);
+
+ retval = seg_info (seg)->stabu.stab_string_size;
+ if (retval <= 0)
+ {
+ /* Make sure the first string is empty. */
+ p = frag_more (1);
+ *p = 0;
+ retval = seg_info (seg)->stabu.stab_string_size = 1;
+#ifdef BFD_ASSEMBLER
+ bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING);
+ if (seg->name == stabstr_secname)
+ seg->name = xstrdup (stabstr_secname);
+#endif
+ }
+
+ if (length > 0)
+ { /* Ordinary case. */
+ p = frag_more (length + 1);
+ strcpy (p, string);
+
+ seg_info (seg)->stabu.stab_string_size += length + 1;
+ }
+ else
+ retval = 0;
+
+ subseg_set (save_seg, save_subseg);
+
+ return retval;
+}
+
+#ifdef AOUT_STABS
+#ifndef OBJ_PROCESS_STAB
+#define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D)
+#endif
+
+static void aout_process_stab PARAMS ((int, const char *, int, int, int));
+
+static void
+aout_process_stab (what, string, type, other, desc)
+ int what;
+ const char *string;
+ int type, other, desc;
+{
+ /* Put the stab information in the symbol table. */
+ symbolS *symbol;
+
+ /* Create the symbol now, but only insert it into the symbol chain
+ after any symbols mentioned in the value expression get into the
+ symbol chain. This is to avoid "continuation symbols" (where one
+ ends in "\" and the debug info is continued in the next .stabs
+ directive) from being separated by other random symbols. */
+ symbol = symbol_create (string, undefined_section, 0,
+ (struct frag *) NULL);
+ if (what == 's' || what == 'n')
+ {
+ /* Pick up the value from the input line. */
+ symbol->sy_frag = &zero_address_frag;
+ pseudo_set (symbol);
+ }
+ else
+ {
+ /* .stabd sets the name to NULL. Why? */
+ S_SET_NAME (symbol, NULL);
+ symbol->sy_frag = frag_now;
+ S_SET_VALUE (symbol, (valueT) frag_now_fix ());
+ }
+
+ symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ S_SET_TYPE (symbol, type);
+ S_SET_OTHER (symbol, other);
+ S_SET_DESC (symbol, desc);
+}
+#endif
+
+/* This can handle different kinds of stabs (s,n,d) and different
+ kinds of stab sections. */
+
+static void
+s_stab_generic (what, stab_secname, stabstr_secname)
+ int what;
+ char *stab_secname;
+ char *stabstr_secname;
+{
+ long longint;
+ char *string;
+ int type;
+ int other;
+ int desc;
+
+ /* The general format is:
+ .stabs "STRING",TYPE,OTHER,DESC,VALUE
+ .stabn TYPE,OTHER,DESC,VALUE
+ .stabd TYPE,OTHER,DESC
+ At this point input_line_pointer points after the pseudo-op and
+ any trailing whitespace. The argument what is one of 's', 'n' or
+ 'd' indicating which type of .stab this is. */
+
+ if (what != 's')
+ string = "";
+ else
+ {
+ int length;
+
+ string = demand_copy_C_string (&length);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ {
+ as_warn (_(".stabs: Missing comma"));
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+
+ if (get_absolute_expression_and_terminator (&longint) != ',')
+ {
+ as_warn (_(".stab%c: Missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ type = longint;
+
+ if (get_absolute_expression_and_terminator (&longint) != ',')
+ {
+ as_warn (_(".stab%c: Missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ other = longint;
+
+ desc = get_absolute_expression ();
+ if (what == 's' || what == 'n')
+ {
+ if (*input_line_pointer != ',')
+ {
+ as_warn (_(".stab%c: Missing comma"), what);
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ }
+
+#ifdef TC_PPC
+#ifdef OBJ_ELF
+ /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
+ given 4 arguments, make it a .stabn */
+ else if (what == 'd')
+ {
+ char *save_location = input_line_pointer;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ what = 'n';
+ }
+ else
+ input_line_pointer = save_location;
+ }
+#endif /* OBJ_ELF */
+#endif /* TC_PPC */
+
+#ifndef NO_LISTING
+ if (listing)
+ {
+ switch (type)
+ {
+ case N_SLINE:
+ listing_source_line ((unsigned int) desc);
+ break;
+ case N_SO:
+ case N_SOL:
+ listing_source_file (string);
+ break;
+ }
+ }
+#endif /* ! NO_LISTING */
+
+ /* We have now gathered the type, other, and desc information. For
+ .stabs or .stabn, input_line_pointer is now pointing at the
+ value. */
+
+ if (SEPARATE_STAB_SECTIONS)
+ /* Output the stab information in a separate section. This is used
+ at least for COFF and ELF. */
+ {
+ segT saved_seg = now_seg;
+ subsegT saved_subseg = now_subseg;
+ fragS *saved_frag = frag_now;
+ valueT dot;
+ segT seg;
+ unsigned int stroff;
+ char *p;
+
+ static segT cached_sec;
+ static char *cached_secname;
+
+ dot = frag_now_fix ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ if (cached_secname && !strcmp (cached_secname, stab_secname))
+ {
+ seg = cached_sec;
+ subseg_set (seg, 0);
+ }
+ else
+ {
+ seg = subseg_new (stab_secname, 0);
+ if (cached_secname)
+ free (cached_secname);
+ cached_secname = xstrdup (stab_secname);
+ cached_sec = seg;
+ }
+
+ if (! seg_info (seg)->hadone)
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_section_flags (stdoutput, seg,
+ SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+#endif
+#ifdef INIT_STAB_SECTION
+ INIT_STAB_SECTION (seg);
+#endif
+ seg_info (seg)->hadone = 1;
+ }
+
+ stroff = get_stab_string_offset (string, stabstr_secname);
+ if (what == 's')
+ {
+ /* release the string */
+ obstack_free (&notes, string);
+ }
+
+ /* At least for now, stabs in a special stab section are always
+ output as 12 byte blocks of information. */
+ p = frag_more (8);
+ md_number_to_chars (p, (valueT) stroff, 4);
+ md_number_to_chars (p + 4, (valueT) type, 1);
+ md_number_to_chars (p + 5, (valueT) other, 1);
+ md_number_to_chars (p + 6, (valueT) desc, 2);
+
+ if (what == 's' || what == 'n')
+ {
+ /* Pick up the value from the input line. */
+ cons (4);
+ input_line_pointer--;
+ }
+ else
+ {
+ const char *fake;
+ symbolS *symbol;
+ expressionS exp;
+
+ /* Arrange for a value representing the current location. */
+ fake = FAKE_LABEL_NAME;
+ symbol = symbol_new (fake, saved_seg, dot, saved_frag);
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = symbol;
+ exp.X_add_number = 0;
+
+ emit_expr (&exp, 4);
+ }
+
+#ifdef OBJ_PROCESS_STAB
+ OBJ_PROCESS_STAB (seg, what, string, type, other, desc);
+#endif
+
+ subseg_set (saved_seg, saved_subseg);
+ }
+ else
+ {
+#ifdef OBJ_PROCESS_STAB
+ OBJ_PROCESS_STAB (0, what, string, type, other, desc);
+#else
+ abort ();
+#endif
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* Regular stab directive. */
+
+void
+s_stab (what)
+ int what;
+{
+ s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
+}
+
+/* "Extended stabs", used in Solaris only now. */
+
+void
+s_xstab (what)
+ int what;
+{
+ int length;
+ char *stab_secname, *stabstr_secname;
+ static char *saved_secname, *saved_strsecname;
+
+ /* @@ MEMORY LEAK: This allocates a copy of the string, but in most
+ cases it will be the same string, so we could release the storage
+ back to the obstack it came from. */
+ stab_secname = demand_copy_C_string (&length);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ input_line_pointer++;
+ else
+ {
+ as_bad (_("comma missing in .xstabs"));
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* To get the name of the stab string section, simply add "str" to
+ the stab section name. */
+ if (saved_secname == 0 || strcmp (saved_secname, stab_secname))
+ {
+ stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4);
+ strcpy (stabstr_secname, stab_secname);
+ strcat (stabstr_secname, "str");
+ if (saved_secname)
+ {
+ free (saved_secname);
+ free (saved_strsecname);
+ }
+ saved_secname = stab_secname;
+ saved_strsecname = stabstr_secname;
+ }
+ s_stab_generic (what, saved_secname, saved_strsecname);
+}
+
+#ifdef S_SET_DESC
+
+/* Frob invented at RMS' request. Set the n_desc of a symbol. */
+
+void
+s_desc (ignore)
+ int ignore;
+{
+ char *name;
+ char c;
+ char *p;
+ symbolS *symbolP;
+ int temp;
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad (_("Expected comma after name \"%s\""), name);
+ *p = c;
+ ignore_rest_of_line ();
+ }
+ else
+ {
+ input_line_pointer++;
+ temp = get_absolute_expression ();
+ *p = 0;
+ symbolP = symbol_find_or_make (name);
+ *p = c;
+ S_SET_DESC (symbolP, temp);
+ }
+ demand_empty_rest_of_line ();
+} /* s_desc() */
+
+#endif /* defined (S_SET_DESC) */
+
+/* Generate stabs debugging information to denote the main source file. */
+
+void
+stabs_generate_asm_file ()
+{
+ char *file;
+ unsigned int lineno;
+
+ as_where (&file, &lineno);
+ generate_asm_file (N_SO, file);
+}
+
+/* Generate stabs debugging information to denote the source file.
+ TYPE is one of N_SO, N_SOL. */
+
+static void
+generate_asm_file (type, file)
+ int type;
+ char *file;
+{
+ static char *last_file;
+ static int label_count;
+ char *hold;
+ char buf[100];
+ char sym[30];
+
+ /* Rather than try to do this in some efficient fashion, we just
+ generate a string and then parse it again. That lets us use the
+ existing stabs hook, which expect to see a string, rather than
+ inventing new ones. */
+
+ hold = input_line_pointer;
+
+ if (last_file == NULL
+ || strcmp (last_file, file) != 0)
+ {
+ sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count);
+ ++label_count;
+
+ sprintf (buf, "\"%s\",%d,0,0,%s\n", file, type, sym);
+ input_line_pointer = buf;
+ s_stab ('s');
+ colon (sym);
+
+ if (last_file != NULL)
+ free (last_file);
+ last_file = xstrdup (file);
+ }
+
+ input_line_pointer = hold;
+}
+
+/* Generate stabs debugging information for the current line. This is
+ used to produce debugging information for an assembler file. */
+
+void
+stabs_generate_asm_lineno ()
+{
+ static int label_count;
+ char *hold;
+ char *file;
+ unsigned int lineno;
+ char *buf;
+ char sym[30];
+
+ /* Rather than try to do this in some efficient fashion, we just
+ generate a string and then parse it again. That lets us use the
+ existing stabs hook, which expect to see a string, rather than
+ inventing new ones. */
+
+ hold = input_line_pointer;
+
+ as_where (&file, &lineno);
+
+ generate_asm_file (N_SOL, file);
+
+ sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count);
+ ++label_count;
+
+ if (in_dot_func_p)
+ {
+ buf = (char *) alloca (100 + strlen (current_function_label));
+ sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno,
+ sym, current_function_label);
+ }
+ else
+ {
+ buf = (char *) alloca (100);
+ sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym);
+ }
+ input_line_pointer = buf;
+ s_stab ('n');
+ colon (sym);
+
+ input_line_pointer = hold;
+}
+
+/* Emit a function stab.
+ All assembler functions are assumed to have return type `void'. */
+
+void
+stabs_generate_asm_func (funcname, startlabname)
+ const char *funcname;
+ const char *startlabname;
+{
+ static int void_emitted_p;
+ char *hold = input_line_pointer;
+ char *buf;
+ char *file;
+ unsigned int lineno;
+
+ if (! void_emitted_p)
+ {
+ input_line_pointer = "\"void:t1=1\",128,0,0,0";
+ s_stab ('s');
+ void_emitted_p = 1;
+ }
+
+ as_where (&file, &lineno);
+ asprintf (&buf, "\"%s:F1\",%d,0,%d,%s",
+ funcname, N_FUN, lineno + 1, startlabname);
+ input_line_pointer = buf;
+ s_stab ('s');
+ free (buf);
+
+ input_line_pointer = hold;
+ current_function_label = xstrdup (startlabname);
+ in_dot_func_p = 1;
+}
+
+/* Emit a stab to record the end of a function. */
+
+void
+stabs_generate_asm_endfunc (funcname, startlabname)
+ const char *funcname;
+ const char *startlabname;
+{
+ static int label_count;
+ char *hold = input_line_pointer;
+ char *buf;
+ char sym[30];
+
+ sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count);
+ ++label_count;
+ colon (sym);
+
+ asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname);
+ input_line_pointer = buf;
+ s_stab ('s');
+ free (buf);
+
+ input_line_pointer = hold;
+ in_dot_func_p = 0;
+ current_function_label = NULL;
+}
diff --git a/gas/stamp-h.in b/gas/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/gas/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/gas/struc-symbol.h b/gas/struc-symbol.h
new file mode 100644
index 00000000000..aeb04050670
--- /dev/null
+++ b/gas/struc-symbol.h
@@ -0,0 +1,166 @@
+/* struct_symbol.h - Internal symbol structure
+ Copyright (C) 1987, 92, 93, 94, 95, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef __struc_symbol_h__
+#define __struc_symbol_h__
+
+#ifdef BFD_ASSEMBLER
+/* The BFD code wants to walk the list in both directions. */
+#undef SYMBOLS_NEED_BACKPOINTERS
+#define SYMBOLS_NEED_BACKPOINTERS
+#endif
+
+/* our version of an nlist node */
+struct symbol
+{
+#ifndef BFD_ASSEMBLER
+ /* The (4-origin) position of sy_name in the symbol table of the object
+ file. This will be 0 for (nameless) .stabd symbols.
+
+ Not used until write_object_file() time. */
+ unsigned long sy_name_offset;
+
+ /* What we write in .o file (if permitted). */
+ obj_symbol_type sy_symbol;
+
+ /* The 24 bit symbol number. Symbol numbers start at 0 and are unsigned. */
+ long sy_number;
+#else
+ /* BFD symbol */
+ asymbol *bsym;
+#endif
+
+ /* The value of the symbol. */
+ expressionS sy_value;
+
+ /* Forwards and (optionally) backwards chain pointers. */
+ struct symbol *sy_next;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ struct symbol *sy_previous;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+ /* Pointer to the frag this symbol is attached to, if any.
+ Otherwise, NULL. */
+ struct frag *sy_frag;
+
+ unsigned int written : 1;
+ /* Whether symbol value has been completely resolved (used during
+ final pass over symbol table). */
+ unsigned int sy_resolved : 1;
+ /* Whether the symbol value is currently being resolved (used to
+ detect loops in symbol dependencies). */
+ unsigned int sy_resolving : 1;
+ /* Whether the symbol value is used in a reloc. This is used to
+ ensure that symbols used in relocs are written out, even if they
+ are local and would otherwise not be. */
+ unsigned int sy_used_in_reloc : 1;
+
+ /* Whether the symbol is used as an operand or in an expression.
+ NOTE: Not all the backends keep this information accurate;
+ backends which use this bit are responsible for setting it when
+ a symbol is used in backend routines. */
+ unsigned int sy_used : 1;
+
+ /* This is set if the symbol is defined in an MRI common section.
+ We handle such sections as single common symbols, so symbols
+ defined within them must be treated specially by the relocation
+ routines. */
+ unsigned int sy_mri_common : 1;
+
+#ifdef OBJ_SYMFIELD_TYPE
+ OBJ_SYMFIELD_TYPE sy_obj;
+#endif
+
+#ifdef TC_SYMFIELD_TYPE
+ TC_SYMFIELD_TYPE sy_tc;
+#endif
+
+#ifdef TARGET_SYMBOL_FIELDS
+ TARGET_SYMBOL_FIELDS
+#endif
+};
+
+typedef struct symbol symbolS;
+
+#ifndef WORKING_DOT_WORD
+struct broken_word
+ {
+ /* Linked list -- one of these structures per ".word x-y+C"
+ expression. */
+ struct broken_word *next_broken_word;
+ /* Segment and subsegment for broken word. */
+ segT seg;
+ subsegT subseg;
+ /* Which frag is this broken word in? */
+ fragS *frag;
+ /* Where in the frag is it? */
+ char *word_goes_here;
+ /* Where to add the break. */
+ fragS *dispfrag; /* where to add the break */
+ /* Operands of expression. */
+ symbolS *add;
+ symbolS *sub;
+ offsetT addnum;
+
+ int added; /* nasty thing happend yet? */
+ /* 1: added and has a long-jump */
+ /* 2: added but uses someone elses long-jump */
+
+ /* Pointer to broken_word with a similar long-jump. */
+ struct broken_word *use_jump;
+ };
+extern struct broken_word *broken_words;
+#endif /* ndef WORKING_DOT_WORD */
+
+/*
+ * Current means for getting from symbols to segments and vice verse.
+ * This will change for infinite-segments support (e.g. COFF).
+ */
+extern const segT N_TYPE_seg[]; /* subseg.c */
+
+#define SEGMENT_TO_SYMBOL_TYPE(seg) ( seg_N_TYPE [(int) (seg)] )
+extern const short seg_N_TYPE[];/* subseg.c */
+
+#define N_REGISTER 30 /* Fake N_TYPE value for SEG_REGISTER */
+
+void symbol_clear_list_pointers PARAMS ((symbolS * symbolP));
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+
+void symbol_insert PARAMS ((symbolS * addme, symbolS * target,
+ symbolS ** rootP, symbolS ** lastP));
+void symbol_remove PARAMS ((symbolS * symbolP, symbolS ** rootP,
+ symbolS ** lastP));
+
+#define symbol_previous(s) ((s)->sy_previous)
+
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+void verify_symbol_chain PARAMS ((symbolS * rootP, symbolS * lastP));
+void verify_symbol_chain_2 PARAMS ((symbolS * symP));
+
+void symbol_append PARAMS ((symbolS * addme, symbolS * target,
+ symbolS ** rootP, symbolS ** lastP));
+
+#define symbol_next(s) ((s)->sy_next)
+
+#endif /* __struc_symbol_h__ */
+
+/* end of struc-symbol.h */
diff --git a/gas/subsegs.c b/gas/subsegs.c
new file mode 100644
index 00000000000..bdf28688bd1
--- /dev/null
+++ b/gas/subsegs.c
@@ -0,0 +1,618 @@
+/* subsegs.c - subsegments -
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * Segments & sub-segments.
+ */
+
+#include "as.h"
+
+#include "subsegs.h"
+#include "obstack.h"
+
+frchainS *frchain_root, *frchain_now;
+
+static struct obstack frchains;
+
+#ifndef BFD_ASSEMBLER
+#ifdef MANY_SEGMENTS
+segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
+
+#else
+/* Commented in "subsegs.h". */
+frchainS *data0_frchainP, *bss0_frchainP;
+
+#endif /* MANY_SEGMENTS */
+char const *const seg_name[] =
+{
+ "absolute",
+#ifdef MANY_SEGMENTS
+ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9",
+ "e10", "e11", "e12", "e13", "e14", "e15", "e16", "e17", "e18", "e19",
+ "e20", "e21", "e22", "e23", "e24", "e25", "e26", "e27", "e28", "e29",
+ "e30", "e31", "e32", "e33", "e34", "e35", "e36", "e37", "e38", "e39",
+#else
+ "text",
+ "data",
+ "bss",
+#endif /* MANY_SEGMENTS */
+ "unknown",
+ "ASSEMBLER-INTERNAL-LOGIC-ERROR!",
+ "expr",
+ "debug",
+ "transfert vector preload",
+ "transfert vector postload",
+ "register",
+ "",
+}; /* Used by error reporters, dumpers etc. */
+#else /* BFD_ASSEMBLER */
+
+/* Gas segment information for bfd_abs_section_ptr and
+ bfd_und_section_ptr. */
+static segment_info_type *abs_seg_info;
+static segment_info_type *und_seg_info;
+
+#endif /* BFD_ASSEMBLER */
+
+static void subseg_set_rest PARAMS ((segT, subsegT));
+
+static fragS dummy_frag;
+
+static frchainS absolute_frchain;
+
+void
+subsegs_begin ()
+{
+ /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know (SEG_ABSOLUTE == 0);
+ know (SEG_TEXT == 1);
+ know (SEG_DATA == 2);
+ know (SEG_BSS == 3);
+ know (SEG_UNKNOWN == 4);
+ know (SEG_GOOF == 5);
+ know (SEG_EXPR == 6);
+ know (SEG_DEBUG == 7);
+ know (SEG_NTV == 8);
+ know (SEG_PTV == 9);
+ know (SEG_REGISTER == 10);
+ know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
+#endif
+
+ obstack_begin (&frchains, chunksize);
+#if __GNUC__ >= 2
+ obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
+#endif
+
+ frchain_root = NULL;
+ frchain_now = NULL; /* Warn new_subseg() that we are booting. */
+
+ frag_now = &dummy_frag;
+
+#ifndef BFD_ASSEMBLER
+ now_subseg = 42; /* Lie for 1st call to subseg_new. */
+#ifdef MANY_SEGMENTS
+ {
+ int i;
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ subseg_set (i, 0);
+ segment_info[i].frchainP = frchain_now;
+ }
+ }
+#else
+ subseg_set (SEG_DATA, 0); /* .data 0 */
+ data0_frchainP = frchain_now;
+
+ subseg_set (SEG_BSS, 0);
+ bss0_frchainP = frchain_now;
+
+#endif /* ! MANY_SEGMENTS */
+#endif /* ! BFD_ASSEMBLER */
+
+ absolute_frchain.frch_seg = absolute_section;
+ absolute_frchain.frch_subseg = 0;
+#ifdef BFD_ASSEMBLER
+ absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
+#endif
+ absolute_frchain.frch_frag_now = &zero_address_frag;
+ absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
+}
+
+/*
+ * subseg_change()
+ *
+ * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the
+ * subsegment. If we are already in the correct subsegment, change nothing.
+ * This is used eg as a worker for subseg_set [which does make a new frag_now]
+ * and for changing segments after we have read the source. We construct eg
+ * fixSs even after the source file is read, so we do have to keep the
+ * segment context correct.
+ */
+void
+subseg_change (seg, subseg)
+ register segT seg;
+ register int subseg;
+{
+ now_seg = seg;
+ now_subseg = subseg;
+
+ if (now_seg == absolute_section)
+ return;
+
+#ifdef BFD_ASSEMBLER
+ {
+ segment_info_type *seginfo;
+ seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg);
+ if (! seginfo)
+ {
+ seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
+ seginfo->fix_root = NULL;
+ seginfo->fix_tail = NULL;
+ seginfo->bfd_section = seg;
+ seginfo->sym = 0;
+ if (seg == bfd_abs_section_ptr)
+ abs_seg_info = seginfo;
+ else if (seg == bfd_und_section_ptr)
+ und_seg_info = seginfo;
+ else
+ bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
+ }
+ }
+#else
+#ifdef MANY_SEGMENTS
+ seg_fix_rootP = &segment_info[seg].fix_root;
+ seg_fix_tailP = &segment_info[seg].fix_tail;
+#else
+ if (seg == SEG_DATA)
+ {
+ seg_fix_rootP = &data_fix_root;
+ seg_fix_tailP = &data_fix_tail;
+ }
+ else if (seg == SEG_TEXT)
+ {
+ seg_fix_rootP = &text_fix_root;
+ seg_fix_tailP = &text_fix_tail;
+ }
+ else
+ {
+ know (seg == SEG_BSS);
+ seg_fix_rootP = &bss_fix_root;
+ seg_fix_tailP = &bss_fix_tail;
+ }
+
+#endif
+#endif
+}
+
+static void
+subseg_set_rest (seg, subseg)
+ segT seg;
+ subsegT subseg;
+{
+ register frchainS *frcP; /* crawl frchain chain */
+ register frchainS **lastPP; /* address of last pointer */
+ frchainS *newP; /* address of new frchain */
+
+ mri_common_symbol = NULL;
+
+ if (frag_now && frchain_now)
+ frchain_now->frch_frag_now = frag_now;
+
+ assert (frchain_now == 0
+ || now_seg == undefined_section
+ || now_seg == absolute_section
+ || frchain_now->frch_last == frag_now);
+
+ subseg_change (seg, (int) subseg);
+
+ if (seg == absolute_section)
+ {
+ frchain_now = &absolute_frchain;
+ frag_now = &zero_address_frag;
+ return;
+ }
+
+ assert (frchain_now == 0
+ || now_seg == undefined_section
+ || frchain_now->frch_last == frag_now);
+
+ /*
+ * Attempt to find or make a frchain for that sub seg.
+ * Crawl along chain of frchainSs, begins @ frchain_root.
+ * If we need to make a frchainS, link it into correct
+ * position of chain rooted in frchain_root.
+ */
+ for (frcP = *(lastPP = &frchain_root);
+ frcP && frcP->frch_seg <= seg;
+ frcP = *(lastPP = &frcP->frch_next))
+ {
+ if (frcP->frch_seg == seg
+ && frcP->frch_subseg >= subseg)
+ {
+ break;
+ }
+ }
+ /*
+ * frcP: Address of the 1st frchainS in correct segment with
+ * frch_subseg >= subseg.
+ * We want to either use this frchainS, or we want
+ * to insert a new frchainS just before it.
+ *
+ * If frcP==NULL, then we are at the end of the chain
+ * of frchainS-s. A NULL frcP means we fell off the end
+ * of the chain looking for a
+ * frch_subseg >= subseg, so we
+ * must make a new frchainS.
+ *
+ * If we ever maintain a pointer to
+ * the last frchainS in the chain, we change that pointer
+ * ONLY when frcP==NULL.
+ *
+ * lastPP: Address of the pointer with value frcP;
+ * Never NULL.
+ * May point to frchain_root.
+ *
+ */
+ if (!frcP
+ || (frcP->frch_seg > seg
+ || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
+ {
+ /*
+ * This should be the only code that creates a frchainS.
+ */
+ newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
+ newP->frch_subseg = subseg;
+ newP->frch_seg = seg;
+#ifdef BFD_ASSEMBLER
+ newP->fix_root = NULL;
+ newP->fix_tail = NULL;
+#endif
+ obstack_begin (&newP->frch_obstack, chunksize);
+#if __GNUC__ >= 2
+ obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
+#endif
+ newP->frch_frag_now = frag_alloc (&newP->frch_obstack);
+ newP->frch_frag_now->fr_type = rs_fill;
+
+ newP->frch_root = newP->frch_last = newP->frch_frag_now;
+
+ *lastPP = newP;
+ newP->frch_next = frcP; /* perhaps NULL */
+
+#ifdef BFD_ASSEMBLER
+ {
+ segment_info_type *seginfo;
+ seginfo = seg_info (seg);
+ if (seginfo && seginfo->frchainP == frcP)
+ seginfo->frchainP = newP;
+ }
+#endif
+
+ frcP = newP;
+ }
+ /*
+ * Here with frcP pointing to the frchainS for subseg.
+ */
+ frchain_now = frcP;
+ frag_now = frcP->frch_frag_now;
+
+ assert (frchain_now->frch_last == frag_now);
+}
+
+/*
+ * subseg_set(segT, subsegT)
+ *
+ * If you attempt to change to the current subsegment, nothing happens.
+ *
+ * In: segT, subsegT code for new subsegment.
+ * frag_now -> incomplete frag for current subsegment.
+ * If frag_now==NULL, then there is no old, incomplete frag, so
+ * the old frag is not closed off.
+ *
+ * Out: now_subseg, now_seg updated.
+ * Frchain_now points to the (possibly new) struct frchain for this
+ * sub-segment.
+ * Frchain_root updated if needed.
+ */
+
+#ifndef BFD_ASSEMBLER
+
+segT
+subseg_new (segname, subseg)
+ const char *segname;
+ subsegT subseg;
+{
+ int i;
+
+ for (i = 0; i < (int) SEG_MAXIMUM_ORDINAL; i++)
+ {
+ const char *s;
+
+ s = segment_name ((segT) i);
+ if (strcmp (segname, s) == 0
+ || (segname[0] == '.'
+ && strcmp (segname + 1, s) == 0))
+ {
+ subseg_set ((segT) i, subseg);
+ return (segT) i;
+ }
+#ifdef obj_segment_name
+ s = obj_segment_name ((segT) i);
+ if (strcmp (segname, s) == 0
+ || (segname[0] == '.'
+ && strcmp (segname + 1, s) == 0))
+ {
+ subseg_set ((segT) i, subseg);
+ return (segT) i;
+ }
+#endif
+ }
+
+#ifdef obj_add_segment
+ {
+ segT new_seg;
+ new_seg = obj_add_segment (segname);
+ subseg_set (new_seg, subseg);
+ return new_seg;
+ }
+#else
+ as_bad (_("Attempt to switch to nonexistent segment \"%s\""), segname);
+ return now_seg;
+#endif
+}
+
+void
+subseg_set (seg, subseg) /* begin assembly for a new sub-segment */
+ register segT seg; /* SEG_DATA or SEG_TEXT */
+ register subsegT subseg;
+{
+#ifndef MANY_SEGMENTS
+ know (seg == SEG_DATA
+ || seg == SEG_TEXT
+ || seg == SEG_BSS
+ || seg == SEG_ABSOLUTE);
+#endif
+
+ if (seg != now_seg || subseg != now_subseg)
+ { /* we just changed sub-segments */
+ subseg_set_rest (seg, subseg);
+ }
+ mri_common_symbol = NULL;
+}
+
+#else /* BFD_ASSEMBLER */
+
+segT
+subseg_get (segname, force_new)
+ const char *segname;
+ int force_new;
+{
+ segT secptr;
+ segment_info_type *seginfo;
+ const char *now_seg_name = (now_seg
+ ? bfd_get_section_name (stdoutput, now_seg)
+ : 0);
+
+ if (!force_new
+ && now_seg_name
+ && (now_seg_name == segname
+ || !strcmp (now_seg_name, segname)))
+ return now_seg;
+
+ if (!force_new)
+ secptr = bfd_make_section_old_way (stdoutput, segname);
+ else
+ secptr = bfd_make_section_anyway (stdoutput, segname);
+
+ seginfo = seg_info (secptr);
+ if (! seginfo)
+ {
+ /* Check whether output_section is set first because secptr may
+ be bfd_abs_section_ptr. */
+ if (secptr->output_section != secptr)
+ secptr->output_section = secptr;
+ seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
+ memset ((PTR) seginfo, 0, sizeof (*seginfo));
+ seginfo->fix_root = NULL;
+ seginfo->fix_tail = NULL;
+ seginfo->bfd_section = secptr;
+ if (secptr == bfd_abs_section_ptr)
+ abs_seg_info = seginfo;
+ else if (secptr == bfd_und_section_ptr)
+ und_seg_info = seginfo;
+ else
+ bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
+ seginfo->frchainP = NULL;
+ seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
+ seginfo->sym = NULL;
+ seginfo->dot = NULL;
+ }
+ return secptr;
+}
+
+segT
+subseg_new (segname, subseg)
+ const char *segname;
+ subsegT subseg;
+{
+ segT secptr;
+ segment_info_type *seginfo;
+
+ secptr = subseg_get (segname, 0);
+ subseg_set_rest (secptr, subseg);
+ seginfo = seg_info (secptr);
+ if (! seginfo->frchainP)
+ seginfo->frchainP = frchain_now;
+ return secptr;
+}
+
+/* Like subseg_new, except a new section is always created, even if
+ a section with that name already exists. */
+segT
+subseg_force_new (segname, subseg)
+ const char *segname;
+ subsegT subseg;
+{
+ segT secptr;
+ segment_info_type *seginfo;
+
+ secptr = subseg_get (segname, 1);
+ subseg_set_rest (secptr, subseg);
+ seginfo = seg_info (secptr);
+ if (! seginfo->frchainP)
+ seginfo->frchainP = frchain_now;
+ return secptr;
+}
+
+void
+subseg_set (secptr, subseg)
+ segT secptr;
+ subsegT subseg;
+{
+ if (! (secptr == now_seg && subseg == now_subseg))
+ subseg_set_rest (secptr, subseg);
+ mri_common_symbol = NULL;
+}
+
+#ifndef obj_sec_sym_ok_for_reloc
+#define obj_sec_sym_ok_for_reloc(SEC) 0
+#endif
+
+/* Get the gas information we are storing for a section. */
+
+segment_info_type *
+seg_info (sec)
+ segT sec;
+{
+ if (sec == bfd_abs_section_ptr)
+ return abs_seg_info;
+ else if (sec == bfd_und_section_ptr)
+ return und_seg_info;
+ else
+ return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
+}
+
+symbolS *
+section_symbol (sec)
+ segT sec;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ symbolS *s;
+
+ if (seginfo == 0)
+ abort ();
+ if (seginfo->sym)
+ return seginfo->sym;
+
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+ if (! EMIT_SECTION_SYMBOLS
+#ifdef BFD_ASSEMBLER
+ || symbol_table_frozen
+#endif
+ )
+ {
+ /* Here we know it won't be going into the symbol table. */
+ s = symbol_create (sec->name, sec, 0, &zero_address_frag);
+ }
+ else
+ {
+ s = symbol_find_base (sec->name, 0);
+ if (s == NULL)
+ s = symbol_new (sec->name, sec, 0, &zero_address_frag);
+ else
+ {
+ if (S_GET_SEGMENT (s) == undefined_section)
+ {
+ S_SET_SEGMENT (s, sec);
+ s->sy_frag = &zero_address_frag;
+ }
+ }
+ }
+
+ S_CLEAR_EXTERNAL (s);
+
+ /* Use the BFD section symbol, if possible. */
+ if (obj_sec_sym_ok_for_reloc (sec))
+ s->bsym = sec->symbol;
+
+ seginfo->sym = s;
+ return s;
+}
+
+#endif /* BFD_ASSEMBLER */
+
+void
+subsegs_print_statistics (file)
+ FILE *file;
+{
+ frchainS *frchp;
+ fprintf (file, "frag chains:\n");
+ for (frchp = frchain_root; frchp; frchp = frchp->frch_next)
+ {
+ int count = 0;
+ fragS *fragp;
+
+ /* If frch_subseg is non-zero, it's probably been chained onto
+ the end of a previous subsection. Don't count it again. */
+ if (frchp->frch_subseg != 0)
+ continue;
+
+ /* Skip gas-internal sections. */
+ if (segment_name (frchp->frch_seg)[0] == '*')
+ continue;
+
+ for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
+ {
+#if 0
+ switch (fragp->fr_type)
+ {
+ case rs_fill:
+ fprintf (file, "f"); break;
+ case rs_align:
+ fprintf (file, "a"); break;
+ case rs_align_code:
+ fprintf (file, "c"); break;
+ case rs_org:
+ fprintf (file, "o"); break;
+ case rs_machine_dependent:
+ fprintf (file, "m"); break;
+ case rs_space:
+ fprintf (file, "s"); break;
+ case 0:
+ fprintf (file, "0"); break;
+ default:
+ fprintf (file, "?"); break;
+ }
+#endif
+ count++;
+ }
+ fprintf (file, "\n");
+ fprintf (file, "\t%p %-10s\t%10d frags\n", frchp,
+ segment_name (frchp->frch_seg), count);
+ }
+}
+
+/* end of subsegs.c */
diff --git a/gas/subsegs.h b/gas/subsegs.h
new file mode 100644
index 00000000000..4840d5b5c2b
--- /dev/null
+++ b/gas/subsegs.h
@@ -0,0 +1,159 @@
+/* subsegs.h -> subsegs.c
+ Copyright (C) 1987, 92, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/*
+ * For every sub-segment the user mentions in the ASsembler program,
+ * we make one struct frchain. Each sub-segment has exactly one struct frchain
+ * and vice versa.
+ *
+ * Struct frchain's are forward chained (in ascending order of sub-segment
+ * code number). The chain runs through frch_next of each subsegment.
+ * This makes it hard to find a subsegment's frags
+ * if programmer uses a lot of them. Most programs only use text0 and
+ * data0, so they don't suffer. At least this way:
+ * (1) There are no "arbitrary" restrictions on how many subsegments
+ * can be programmed;
+ * (2) Subsegments' frchain-s are (later) chained together in the order in
+ * which they are emitted for object file viz text then data.
+ *
+ * From each struct frchain dangles a chain of struct frags. The frags
+ * represent code fragments, for that sub-segment, forward chained.
+ */
+
+#include "obstack.h"
+
+struct frchain /* control building of a frag chain */
+{ /* FRCH = FRagment CHain control */
+ struct frag *frch_root; /* 1st struct frag in chain, or NULL */
+ struct frag *frch_last; /* last struct frag in chain, or NULL */
+ struct frchain *frch_next; /* next in chain of struct frchain-s */
+ segT frch_seg; /* SEG_TEXT or SEG_DATA. */
+ subsegT frch_subseg; /* subsegment number of this chain */
+#ifdef BFD_ASSEMBLER
+ fixS *fix_root; /* Root of fixups for this subsegment. */
+ fixS *fix_tail; /* Last fixup for this subsegment. */
+#endif
+ struct obstack frch_obstack; /* for objects in this frag chain */
+ fragS *frch_frag_now; /* frag_now for this subsegment */
+};
+
+typedef struct frchain frchainS;
+
+/* All subsegments' chains hang off here. NULL means no frchains yet. */
+extern frchainS *frchain_root;
+
+/* Frchain we are assembling into now. That is, the current segment's
+ frag chain, even if it contains no (complete) frags. */
+extern frchainS *frchain_now;
+
+
+typedef struct segment_info_struct
+{
+ frchainS *frchainP;
+ unsigned int hadone : 1;
+
+ /* This field is set if this is a .bss section which does not really
+ have any contents. Once upon a time a .bss section did not have
+ any frags, but that is no longer true. This field prevent the
+ SEC_HAS_CONTENTS flag from being set for the section even if
+ there are frags. */
+ unsigned int bss : 1;
+
+ int user_stuff;
+
+ /* Fixups for this segment. If BFD_ASSEMBLER, this is only valid
+ after the frchains are run together. */
+ fixS *fix_root;
+ fixS *fix_tail;
+
+#if defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ struct internal_scnhdr scnhdr;
+ enum linkonce_type linkonce;
+ const char *name;
+#endif
+
+ symbolS *dot;
+
+ struct lineno_list *lineno_list_head;
+ struct lineno_list *lineno_list_tail;
+
+#ifdef BFD_ASSEMBLER
+ /* Which BFD section does this gas segment correspond to? */
+ asection *bfd_section;
+
+ /* NULL, or pointer to the gas symbol that is the section symbol for
+ this section. sym->bsym and bfd_section->symbol should be the same. */
+ symbolS *sym;
+#endif
+
+ union
+ {
+ /* Current size of section holding stabs strings. */
+ unsigned long stab_string_size;
+ /* Initial frag for ELF. */
+ char *p;
+ }
+ stabu;
+
+#ifdef NEED_LITERAL_POOL
+ unsigned long literal_pool_size;
+#endif
+
+#ifdef TC_SEGMENT_INFO_TYPE
+ TC_SEGMENT_INFO_TYPE tc_segment_info_data;
+#endif
+} segment_info_type;
+
+#ifdef BFD_ASSEMBLER
+
+extern segment_info_type *seg_info PARAMS ((segT));
+extern symbolS *section_symbol PARAMS ((segT));
+
+#else /* ! BFD_ASSEMBLER */
+
+#ifdef MANY_SEGMENTS
+
+extern segment_info_type segment_info[];
+
+#define seg_info(SEC) (&segment_info[SEC])
+
+#else
+
+/* Sentinel for frchain crawling. Points to the 1st data-segment
+ frchain. (Which is pointed to by the last text-segment frchain.) */
+extern frchainS *data0_frchainP;
+extern frchainS *bss0_frchainP;
+
+/* Dummy so stuff can compile. Should never be used. */
+struct seg_info_trash {
+ struct {
+ unsigned stab_string_size : 1;
+ } stabu;
+ unsigned hadone : 1;
+};
+#define seg_info(S) (abort (), (struct seg_info_trash *) 0)
+
+#endif
+
+#endif /* ! BFD_ASSEMBLER */
+
+extern void subsegs_print_statistics PARAMS ((FILE *));
+
+/* end of subsegs.h */
diff --git a/gas/symbols.c b/gas/symbols.c
new file mode 100644
index 00000000000..a1cde6a7de2
--- /dev/null
+++ b/gas/symbols.c
@@ -0,0 +1,1785 @@
+/* symbols.c -symbol table-
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* #define DEBUG_SYMS / * to debug symbol list maintenance */
+
+#include <ctype.h>
+
+#include "as.h"
+
+#include "obstack.h" /* For "symbols.h" */
+#include "subsegs.h"
+
+/* This is non-zero if symbols are case sensitive, which is the
+ default. */
+int symbols_case_sensitive = 1;
+
+#ifndef WORKING_DOT_WORD
+extern int new_broken_words;
+#endif
+
+/* symbol-name => struct symbol pointer */
+static struct hash_control *sy_hash;
+
+/* Below are commented in "symbols.h". */
+symbolS *symbol_rootP;
+symbolS *symbol_lastP;
+symbolS abs_symbol;
+
+#ifdef DEBUG_SYMS
+#define debug_verify_symchain verify_symbol_chain
+#else
+#define debug_verify_symchain(root, last) ((void) 0)
+#endif
+
+struct obstack notes;
+
+static void fb_label_init PARAMS ((void));
+static long dollar_label_instance PARAMS ((long));
+static long fb_label_instance PARAMS ((long));
+
+static void print_binary PARAMS ((FILE *, const char *, expressionS *));
+
+/* symbol_new()
+
+ Return a pointer to a new symbol. Die if we can't make a new
+ symbol. Fill in the symbol's values. Add symbol to end of symbol
+ chain.
+
+ This function should be called in the general case of creating a
+ symbol. However, if the output file symbol table has already been
+ set, and you are certain that this symbol won't be wanted in the
+ output file, you can call symbol_create. */
+
+symbolS *
+symbol_new (name, segment, valu, frag)
+ const char *name;
+ segT segment;
+ valueT valu;
+ fragS *frag;
+{
+ symbolS *symbolP = symbol_create (name, segment, valu, frag);
+
+ /*
+ * Link to end of symbol chain.
+ */
+#ifdef BFD_ASSEMBLER
+ {
+ extern int symbol_table_frozen;
+ if (symbol_table_frozen)
+ abort ();
+ }
+#endif
+ symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ return symbolP;
+}
+
+symbolS *
+symbol_create (name, segment, valu, frag)
+ const char *name; /* It is copied, the caller can destroy/modify */
+ segT segment; /* Segment identifier (SEG_<something>) */
+ valueT valu; /* Symbol value */
+ fragS *frag; /* Associated fragment */
+{
+ unsigned int name_length;
+ char *preserved_copy_of_name;
+ symbolS *symbolP;
+
+ name_length = strlen (name) + 1; /* +1 for \0 */
+ obstack_grow (&notes, name, name_length);
+ preserved_copy_of_name = obstack_finish (&notes);
+#ifdef STRIP_UNDERSCORE
+ if (preserved_copy_of_name[0] == '_')
+ preserved_copy_of_name++;
+#endif
+
+#ifdef tc_canonicalize_symbol_name
+ preserved_copy_of_name =
+ tc_canonicalize_symbol_name (preserved_copy_of_name);
+#endif
+
+ if (! symbols_case_sensitive)
+ {
+ unsigned char *s;
+
+ for (s = (unsigned char *) preserved_copy_of_name; *s != '\0'; s++)
+ if (islower (*s))
+ *s = toupper (*s);
+ }
+
+ symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
+
+ /* symbol must be born in some fixed state. This seems as good as any. */
+ memset (symbolP, 0, sizeof (symbolS));
+
+#ifdef BFD_ASSEMBLER
+ symbolP->bsym = bfd_make_empty_symbol (stdoutput);
+ if (symbolP->bsym == NULL)
+ as_perror ("%s", "bfd_make_empty_symbol");
+ symbolP->bsym->udata.p = (PTR) symbolP;
+#endif
+ S_SET_NAME (symbolP, preserved_copy_of_name);
+
+ S_SET_SEGMENT (symbolP, segment);
+ S_SET_VALUE (symbolP, valu);
+ symbol_clear_list_pointers (symbolP);
+
+ symbolP->sy_frag = frag;
+#ifndef BFD_ASSEMBLER
+ symbolP->sy_number = ~0;
+ symbolP->sy_name_offset = (unsigned int) ~0;
+#endif
+
+ obj_symbol_new_hook (symbolP);
+
+#ifdef tc_symbol_new_hook
+ tc_symbol_new_hook (symbolP);
+#endif
+
+ return symbolP;
+}
+
+
+/*
+ * colon()
+ *
+ * We have just seen "<name>:".
+ * Creates a struct symbol unless it already exists.
+ *
+ * Gripes if we are redefining a symbol incompatibly (and ignores it).
+ *
+ */
+symbolS *
+colon (sym_name) /* just seen "x:" - rattle symbols & frags */
+ const char *sym_name; /* symbol name, as a cannonical string */
+ /* We copy this string: OK to alter later. */
+{
+ register symbolS *symbolP; /* symbol we are working with */
+
+ /* Sun local labels go out of scope whenever a non-local symbol is
+ defined. */
+ if (LOCAL_LABELS_DOLLAR)
+ {
+ int local;
+
+#ifdef BFD_ASSEMBLER
+ local = bfd_is_local_label_name (stdoutput, sym_name);
+#else
+ local = LOCAL_LABEL (sym_name);
+#endif
+
+ if (! local)
+ dollar_label_clear ();
+ }
+
+#ifndef WORKING_DOT_WORD
+ if (new_broken_words)
+ {
+ struct broken_word *a;
+ int possible_bytes;
+ fragS *frag_tmp;
+ char *frag_opcode;
+
+ extern const int md_short_jump_size;
+ extern const int md_long_jump_size;
+ possible_bytes = (md_short_jump_size
+ + new_broken_words * md_long_jump_size);
+
+ frag_tmp = frag_now;
+ frag_opcode = frag_var (rs_broken_word,
+ possible_bytes,
+ possible_bytes,
+ (relax_substateT) 0,
+ (symbolS *) broken_words,
+ (offsetT) 0,
+ NULL);
+
+ /* We want to store the pointer to where to insert the jump table in the
+ fr_opcode of the rs_broken_word frag. This requires a little
+ hackery. */
+ while (frag_tmp
+ && (frag_tmp->fr_type != rs_broken_word
+ || frag_tmp->fr_opcode))
+ frag_tmp = frag_tmp->fr_next;
+ know (frag_tmp);
+ frag_tmp->fr_opcode = frag_opcode;
+ new_broken_words = 0;
+
+ for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
+ a->dispfrag = frag_tmp;
+ }
+#endif /* WORKING_DOT_WORD */
+
+ if ((symbolP = symbol_find (sym_name)) != 0)
+ {
+#ifdef RESOLVE_SYMBOL_REDEFINITION
+ if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
+ return symbolP;
+#endif
+ /*
+ * Now check for undefined symbols
+ */
+ if (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
+ {
+ if (S_GET_VALUE (symbolP) == 0)
+ {
+ symbolP->sy_frag = frag_now;
+#ifdef OBJ_VMS
+ S_SET_OTHER(symbolP, const_flag);
+#endif
+ S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
+ S_SET_SEGMENT (symbolP, now_seg);
+#ifdef N_UNDF
+ know (N_UNDF == 0);
+#endif /* if we have one, it better be zero. */
+
+ }
+ else
+ {
+ /*
+ * There are still several cases to check:
+ * A .comm/.lcomm symbol being redefined as
+ * initialized data is OK
+ * A .comm/.lcomm symbol being redefined with
+ * a larger size is also OK
+ *
+ * This only used to be allowed on VMS gas, but Sun cc
+ * on the sparc also depends on it.
+ */
+
+ if (((!S_IS_DEBUG (symbolP)
+ && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
+ && S_IS_EXTERNAL (symbolP))
+ || S_GET_SEGMENT (symbolP) == bss_section)
+ && (now_seg == data_section
+ || now_seg == S_GET_SEGMENT (symbolP)))
+ {
+ /*
+ * Select which of the 2 cases this is
+ */
+ if (now_seg != data_section)
+ {
+ /*
+ * New .comm for prev .comm symbol.
+ * If the new size is larger we just
+ * change its value. If the new size
+ * is smaller, we ignore this symbol
+ */
+ if (S_GET_VALUE (symbolP)
+ < ((unsigned) frag_now_fix ()))
+ {
+ S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
+ }
+ }
+ else
+ {
+ /* It is a .comm/.lcomm being converted to initialized
+ data. */
+ symbolP->sy_frag = frag_now;
+#ifdef OBJ_VMS
+ S_SET_OTHER(symbolP, const_flag);
+#endif
+ S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
+ S_SET_SEGMENT (symbolP, now_seg); /* keep N_EXT bit */
+ }
+ }
+ else
+ {
+#if defined (S_GET_OTHER) && defined (S_GET_DESC)
+ as_fatal (_("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld."),
+ sym_name,
+ segment_name (S_GET_SEGMENT (symbolP)),
+ S_GET_OTHER (symbolP), S_GET_DESC (symbolP),
+ (long) S_GET_VALUE (symbolP));
+#else
+ as_fatal (_("Symbol \"%s\" is already defined as \"%s\"/%ld."),
+ sym_name,
+ segment_name (S_GET_SEGMENT (symbolP)),
+ (long) S_GET_VALUE (symbolP));
+#endif
+ }
+ } /* if the undefined symbol has no value */
+ }
+ else
+ {
+ /* Don't blow up if the definition is the same */
+ if (!(frag_now == symbolP->sy_frag
+ && S_GET_VALUE (symbolP) == frag_now_fix ()
+ && S_GET_SEGMENT (symbolP) == now_seg))
+ as_fatal (_("Symbol %s already defined."), sym_name);
+ } /* if this symbol is not yet defined */
+
+ }
+ else
+ {
+ symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
+ frag_now);
+#ifdef OBJ_VMS
+ S_SET_OTHER (symbolP, const_flag);
+#endif /* OBJ_VMS */
+
+ symbol_table_insert (symbolP);
+ } /* if we have seen this symbol before */
+
+ if (mri_common_symbol != NULL)
+ {
+ /* This symbol is actually being defined within an MRI common
+ section. This requires special handling. */
+ symbolP->sy_value.X_op = O_symbol;
+ symbolP->sy_value.X_add_symbol = mri_common_symbol;
+ symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
+ symbolP->sy_frag = &zero_address_frag;
+ S_SET_SEGMENT (symbolP, expr_section);
+ symbolP->sy_mri_common = 1;
+ }
+
+#ifdef tc_frob_label
+ tc_frob_label (symbolP);
+#endif
+#ifdef obj_frob_label
+ obj_frob_label (symbolP);
+#endif
+
+ return symbolP;
+}
+
+
+/*
+ * symbol_table_insert()
+ *
+ * Die if we can't insert the symbol.
+ *
+ */
+
+void
+symbol_table_insert (symbolP)
+ symbolS *symbolP;
+{
+ register const char *error_string;
+
+ know (symbolP);
+ know (S_GET_NAME (symbolP));
+
+ if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
+ {
+ as_fatal (_("Inserting \"%s\" into symbol table failed: %s"),
+ S_GET_NAME (symbolP), error_string);
+ } /* on error */
+} /* symbol_table_insert() */
+
+/*
+ * symbol_find_or_make()
+ *
+ * If a symbol name does not exist, create it as undefined, and insert
+ * it into the symbol table. Return a pointer to it.
+ */
+symbolS *
+symbol_find_or_make (name)
+ const char *name;
+{
+ register symbolS *symbolP;
+
+ symbolP = symbol_find (name);
+
+ if (symbolP == NULL)
+ {
+ symbolP = symbol_make (name);
+
+ symbol_table_insert (symbolP);
+ } /* if symbol wasn't found */
+
+ return (symbolP);
+} /* symbol_find_or_make() */
+
+symbolS *
+symbol_make (name)
+ CONST char *name;
+{
+ symbolS *symbolP;
+
+ /* Let the machine description default it, e.g. for register names. */
+ symbolP = md_undefined_symbol ((char *) name);
+
+ if (!symbolP)
+ symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
+
+ return (symbolP);
+} /* symbol_make() */
+
+/*
+ * symbol_find()
+ *
+ * Implement symbol table lookup.
+ * In: A symbol's name as a string: '\0' can't be part of a symbol name.
+ * Out: NULL if the name was not in the symbol table, else the address
+ * of a struct symbol associated with that name.
+ */
+
+symbolS *
+symbol_find (name)
+ CONST char *name;
+{
+#ifdef STRIP_UNDERSCORE
+ return (symbol_find_base (name, 1));
+#else /* STRIP_UNDERSCORE */
+ return (symbol_find_base (name, 0));
+#endif /* STRIP_UNDERSCORE */
+} /* symbol_find() */
+
+symbolS *
+symbol_find_base (name, strip_underscore)
+ CONST char *name;
+ int strip_underscore;
+{
+ if (strip_underscore && *name == '_')
+ name++;
+
+#ifdef tc_canonicalize_symbol_name
+ {
+ char *copy;
+
+ copy = (char *) alloca (strlen (name) + 1);
+ strcpy (copy, name);
+ name = tc_canonicalize_symbol_name (copy);
+ }
+#endif
+
+ if (! symbols_case_sensitive)
+ {
+ unsigned char *copy;
+
+ copy = (unsigned char *) alloca (strlen (name) + 1);
+ strcpy (copy, name);
+ name = (const char *) copy;
+ for (; *copy != '\0'; copy++)
+ if (islower (*copy))
+ *copy = toupper (*copy);
+ }
+
+ return ((symbolS *) hash_find (sy_hash, name));
+}
+
+/*
+ * Once upon a time, symbols were kept in a singly linked list. At
+ * least coff needs to be able to rearrange them from time to time, for
+ * which a doubly linked list is much more convenient. Loic did these
+ * as macros which seemed dangerous to me so they're now functions.
+ * xoxorich.
+ */
+
+/* Link symbol ADDME after symbol TARGET in the chain. */
+void
+symbol_append (addme, target, rootPP, lastPP)
+ symbolS *addme;
+ symbolS *target;
+ symbolS **rootPP;
+ symbolS **lastPP;
+{
+ if (target == NULL)
+ {
+ know (*rootPP == NULL);
+ know (*lastPP == NULL);
+ addme->sy_next = NULL;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ addme->sy_previous = NULL;
+#endif
+ *rootPP = addme;
+ *lastPP = addme;
+ return;
+ } /* if the list is empty */
+
+ if (target->sy_next != NULL)
+ {
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ target->sy_next->sy_previous = addme;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+ }
+ else
+ {
+ know (*lastPP == target);
+ *lastPP = addme;
+ } /* if we have a next */
+
+ addme->sy_next = target->sy_next;
+ target->sy_next = addme;
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ addme->sy_previous = target;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+ debug_verify_symchain (symbol_rootP, symbol_lastP);
+}
+
+/* Set the chain pointers of SYMBOL to null. */
+void
+symbol_clear_list_pointers (symbolP)
+ symbolS *symbolP;
+{
+ symbolP->sy_next = NULL;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ symbolP->sy_previous = NULL;
+#endif
+}
+
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+/* Remove SYMBOLP from the list. */
+void
+symbol_remove (symbolP, rootPP, lastPP)
+ symbolS *symbolP;
+ symbolS **rootPP;
+ symbolS **lastPP;
+{
+ if (symbolP == *rootPP)
+ {
+ *rootPP = symbolP->sy_next;
+ } /* if it was the root */
+
+ if (symbolP == *lastPP)
+ {
+ *lastPP = symbolP->sy_previous;
+ } /* if it was the tail */
+
+ if (symbolP->sy_next != NULL)
+ {
+ symbolP->sy_next->sy_previous = symbolP->sy_previous;
+ } /* if not last */
+
+ if (symbolP->sy_previous != NULL)
+ {
+ symbolP->sy_previous->sy_next = symbolP->sy_next;
+ } /* if not first */
+
+ debug_verify_symchain (*rootPP, *lastPP);
+}
+
+/* Link symbol ADDME before symbol TARGET in the chain. */
+void
+symbol_insert (addme, target, rootPP, lastPP)
+ symbolS *addme;
+ symbolS *target;
+ symbolS **rootPP;
+ symbolS **lastPP;
+{
+ if (target->sy_previous != NULL)
+ {
+ target->sy_previous->sy_next = addme;
+ }
+ else
+ {
+ know (*rootPP == target);
+ *rootPP = addme;
+ } /* if not first */
+
+ addme->sy_previous = target->sy_previous;
+ target->sy_previous = addme;
+ addme->sy_next = target;
+
+ debug_verify_symchain (*rootPP, *lastPP);
+}
+
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+void
+verify_symbol_chain (rootP, lastP)
+ symbolS *rootP;
+ symbolS *lastP;
+{
+ symbolS *symbolP = rootP;
+
+ if (symbolP == NULL)
+ return;
+
+ for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
+ {
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ assert (symbolP->sy_next->sy_previous == symbolP);
+#else
+ /* Walk the list anyways, to make sure pointers are still good. */
+ ;
+#endif /* SYMBOLS_NEED_BACKPOINTERS */
+ }
+
+ assert (lastP == symbolP);
+}
+
+void
+verify_symbol_chain_2 (sym)
+ symbolS *sym;
+{
+ symbolS *p = sym, *n = sym;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+ while (symbol_previous (p))
+ p = symbol_previous (p);
+#endif
+ while (symbol_next (n))
+ n = symbol_next (n);
+ verify_symbol_chain (p, n);
+}
+
+/* Resolve the value of a symbol. This is called during the final
+ pass over the symbol table to resolve any symbols with complex
+ values. */
+
+valueT
+resolve_symbol_value (symp, finalize)
+ symbolS *symp;
+ int finalize;
+{
+ int resolved;
+ valueT final_val;
+ segT final_seg;
+
+ if (symp->sy_resolved)
+ {
+ if (symp->sy_value.X_op == O_constant)
+ return (valueT) symp->sy_value.X_add_number;
+ else
+ return 0;
+ }
+
+ resolved = 0;
+ final_seg = S_GET_SEGMENT (symp);
+
+ if (symp->sy_resolving)
+ {
+ if (finalize)
+ as_bad (_("Symbol definition loop encountered at %s"), S_GET_NAME (symp));
+ final_val = 0;
+ resolved = 1;
+ }
+ else
+ {
+ symbolS *add_symbol, *op_symbol;
+ offsetT left, right;
+ segT seg_left, seg_right;
+ operatorT op;
+
+ symp->sy_resolving = 1;
+
+ /* Help out with CSE. */
+ add_symbol = symp->sy_value.X_add_symbol;
+ op_symbol = symp->sy_value.X_op_symbol;
+ final_val = symp->sy_value.X_add_number;
+ op = symp->sy_value.X_op;
+
+ switch (op)
+ {
+ default:
+ BAD_CASE (op);
+ break;
+
+ case O_absent:
+ final_val = 0;
+ /* Fall through. */
+
+ case O_constant:
+ final_val += symp->sy_frag->fr_address;
+ if (final_seg == expr_section)
+ final_seg = absolute_section;
+ resolved = 1;
+ break;
+
+ case O_symbol:
+ case O_symbol_rva:
+ left = resolve_symbol_value (add_symbol, finalize);
+ do_symbol:
+
+ if (symp->sy_mri_common)
+ {
+ /* This is a symbol inside an MRI common section. The
+ relocation routines are going to handle it specially.
+ Don't change the value. */
+ resolved = add_symbol->sy_resolved;
+ break;
+ }
+
+ if (finalize && final_val == 0)
+ copy_symbol_attributes (symp, add_symbol);
+
+ /* If we have equated this symbol to an undefined symbol, we
+ keep X_op set to O_symbol, and we don't change
+ X_add_number. This permits the routine which writes out
+ relocation to detect this case, and convert the
+ relocation to be against the symbol to which this symbol
+ is equated. */
+ if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol))
+ {
+ if (finalize)
+ {
+ S_SET_SEGMENT (symp, S_GET_SEGMENT (add_symbol));
+ symp->sy_value.X_op = O_symbol;
+ symp->sy_value.X_add_symbol = add_symbol;
+ symp->sy_value.X_add_number = final_val;
+ }
+ final_val = 0;
+ resolved = add_symbol->sy_resolved;
+ goto exit_dont_set_value;
+ }
+ else
+ {
+ final_val += symp->sy_frag->fr_address + left;
+ if (final_seg == expr_section || final_seg == undefined_section)
+ final_seg = S_GET_SEGMENT (add_symbol);
+ }
+
+ resolved = add_symbol->sy_resolved;
+ break;
+
+ case O_uminus:
+ case O_bit_not:
+ case O_logical_not:
+ left = resolve_symbol_value (add_symbol, finalize);
+
+ if (op == O_uminus)
+ left = -left;
+ else if (op == O_logical_not)
+ left = !left;
+ else
+ left = ~left;
+
+ final_val += left + symp->sy_frag->fr_address;
+ if (final_seg == expr_section || final_seg == undefined_section)
+ final_seg = absolute_section;
+
+ resolved = add_symbol->sy_resolved;
+ break;
+
+ case O_multiply:
+ case O_divide:
+ case O_modulus:
+ case O_left_shift:
+ case O_right_shift:
+ case O_bit_inclusive_or:
+ case O_bit_or_not:
+ case O_bit_exclusive_or:
+ case O_bit_and:
+ case O_add:
+ case O_subtract:
+ case O_eq:
+ case O_ne:
+ case O_lt:
+ case O_le:
+ case O_ge:
+ case O_gt:
+ case O_logical_and:
+ case O_logical_or:
+ left = resolve_symbol_value (add_symbol, finalize);
+ right = resolve_symbol_value (op_symbol, finalize);
+ seg_left = S_GET_SEGMENT (add_symbol);
+ seg_right = S_GET_SEGMENT (op_symbol);
+
+ /* Simplify addition or subtraction of a constant by folding the
+ constant into X_add_number. */
+ if (op == O_add || op == O_subtract)
+ {
+ if (seg_right == absolute_section)
+ {
+ if (op == O_add)
+ final_val += right;
+ else
+ final_val -= right;
+ op = O_symbol;
+ op_symbol = NULL;
+ goto do_symbol;
+ }
+ else if (seg_left == absolute_section && op == O_add)
+ {
+ op = O_symbol;
+ final_val += left;
+ add_symbol = op_symbol;
+ left = right;
+ op_symbol = NULL;
+ goto do_symbol;
+ }
+ }
+
+ /* Subtraction is permitted if both operands are in the same
+ section. Otherwise, both operands must be absolute. We
+ already handled the case of addition or subtraction of a
+ constant above. This will probably need to be changed
+ for an object file format which supports arbitrary
+ expressions, such as IEEE-695. */
+ /* Don't emit messages unless we're finalizing the symbol value,
+ otherwise we may get the same message multiple times. */
+ if ((seg_left != absolute_section || seg_right != absolute_section)
+ && (op != O_subtract || seg_left != seg_right)
+ && finalize)
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (symp, &file, &line))
+ {
+ if (seg_left == undefined_section)
+ as_bad_where (file, line,
+ _("undefined symbol %s in operation"),
+ S_GET_NAME (symp->sy_value.X_add_symbol));
+ if (seg_right == undefined_section)
+ as_bad_where (file, line,
+ _("undefined symbol %s in operation"),
+ S_GET_NAME (symp->sy_value.X_op_symbol));
+ if (seg_left != undefined_section
+ && seg_right != undefined_section)
+ as_bad_where (file, line, _("invalid section for operation"));
+ }
+ else
+ {
+ if (seg_left == undefined_section)
+ as_bad (_("undefined symbol %s in operation setting %s"),
+ S_GET_NAME (symp->sy_value.X_add_symbol),
+ S_GET_NAME (symp));
+ if (seg_right == undefined_section)
+ as_bad (_("undefined symbol %s in operation setting %s"),
+ S_GET_NAME (symp->sy_value.X_op_symbol),
+ S_GET_NAME (symp));
+ if (seg_left != undefined_section
+ && seg_right != undefined_section)
+ as_bad (_("invalid section for operation setting %s"),
+ S_GET_NAME (symp));
+ }
+ }
+
+ /* Check for division by zero. */
+ if ((op == O_divide || op == O_modulus) && right == 0)
+ {
+ /* If seg_right is not absolute_section, then we've
+ already issued a warning about using a bad symbol. */
+ if (seg_right == absolute_section && finalize)
+ {
+ char *file;
+ unsigned int line;
+
+ if (expr_symbol_where (symp, &file, &line))
+ as_bad_where (file, line, _("division by zero"));
+ else
+ as_bad (_("division by zero when setting %s"),
+ S_GET_NAME (symp));
+ }
+
+ right = 1;
+ }
+
+ switch (symp->sy_value.X_op)
+ {
+ case O_multiply: left *= right; break;
+ case O_divide: left /= right; break;
+ case O_modulus: left %= right; break;
+ case O_left_shift: left <<= right; break;
+ case O_right_shift: left >>= right; break;
+ case O_bit_inclusive_or: left |= right; break;
+ case O_bit_or_not: left |= ~right; break;
+ case O_bit_exclusive_or: left ^= right; break;
+ case O_bit_and: left &= right; break;
+ case O_add: left += right; break;
+ case O_subtract: left -= right; break;
+ case O_eq: left = left == right ? ~ (offsetT) 0 : 0; break;
+ case O_ne: left = left != right ? ~ (offsetT) 0 : 0; break;
+ case O_lt: left = left < right ? ~ (offsetT) 0 : 0; break;
+ case O_le: left = left <= right ? ~ (offsetT) 0 : 0; break;
+ case O_ge: left = left >= right ? ~ (offsetT) 0 : 0; break;
+ case O_gt: left = left > right ? ~ (offsetT) 0 : 0; break;
+ case O_logical_and: left = left && right; break;
+ case O_logical_or: left = left || right; break;
+ default: abort ();
+ }
+
+ final_val += symp->sy_frag->fr_address + left;
+ if (final_seg == expr_section || final_seg == undefined_section)
+ final_seg = absolute_section;
+ resolved = (add_symbol->sy_resolved && op_symbol->sy_resolved);
+ break;
+
+ case O_register:
+ case O_big:
+ case O_illegal:
+ /* Give an error (below) if not in expr_section. We don't
+ want to worry about expr_section symbols, because they
+ are fictional (they are created as part of expression
+ resolution), and any problems may not actually mean
+ anything. */
+ break;
+ }
+
+ symp->sy_resolving = 0;
+ }
+
+ if (finalize)
+ {
+ S_SET_VALUE (symp, final_val);
+
+#if defined (OBJ_AOUT) && ! defined (BFD_ASSEMBLER)
+ /* The old a.out backend does not handle S_SET_SEGMENT correctly
+ for a stab symbol, so we use this bad hack. */
+ if (final_seg != S_GET_SEGMENT (symp))
+#endif
+ S_SET_SEGMENT (symp, final_seg);
+ }
+
+exit_dont_set_value:
+ /* Don't worry if we can't resolve an expr_section symbol. */
+ if (finalize)
+ {
+ if (resolved)
+ symp->sy_resolved = 1;
+ else if (S_GET_SEGMENT (symp) != expr_section)
+ {
+ as_bad (_("can't resolve value for symbol \"%s\""), S_GET_NAME (symp));
+ symp->sy_resolved = 1;
+ }
+ }
+
+ return final_val;
+}
+
+/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
+ They are *really* local. That is, they go out of scope whenever we see a
+ label that isn't local. Also, like fb labels, there can be multiple
+ instances of a dollar label. Therefor, we name encode each instance with
+ the instance number, keep a list of defined symbols separate from the real
+ symbol table, and we treat these buggers as a sparse array. */
+
+static long *dollar_labels;
+static long *dollar_label_instances;
+static char *dollar_label_defines;
+static unsigned long dollar_label_count;
+static unsigned long dollar_label_max;
+
+int
+dollar_label_defined (label)
+ long label;
+{
+ long *i;
+
+ know ((dollar_labels != NULL) || (dollar_label_count == 0));
+
+ for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
+ if (*i == label)
+ return dollar_label_defines[i - dollar_labels];
+
+ /* if we get here, label isn't defined */
+ return 0;
+} /* dollar_label_defined() */
+
+static long
+dollar_label_instance (label)
+ long label;
+{
+ long *i;
+
+ know ((dollar_labels != NULL) || (dollar_label_count == 0));
+
+ for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
+ if (*i == label)
+ return (dollar_label_instances[i - dollar_labels]);
+
+ /* If we get here, we haven't seen the label before, therefore its instance
+ count is zero. */
+ return 0;
+}
+
+void
+dollar_label_clear ()
+{
+ memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
+}
+
+#define DOLLAR_LABEL_BUMP_BY 10
+
+void
+define_dollar_label (label)
+ long label;
+{
+ long *i;
+
+ for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
+ if (*i == label)
+ {
+ ++dollar_label_instances[i - dollar_labels];
+ dollar_label_defines[i - dollar_labels] = 1;
+ return;
+ }
+
+ /* if we get to here, we don't have label listed yet. */
+
+ if (dollar_labels == NULL)
+ {
+ dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
+ dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
+ dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
+ dollar_label_max = DOLLAR_LABEL_BUMP_BY;
+ dollar_label_count = 0;
+ }
+ else if (dollar_label_count == dollar_label_max)
+ {
+ dollar_label_max += DOLLAR_LABEL_BUMP_BY;
+ dollar_labels = (long *) xrealloc ((char *) dollar_labels,
+ dollar_label_max * sizeof (long));
+ dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
+ dollar_label_max * sizeof (long));
+ dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
+ } /* if we needed to grow */
+
+ dollar_labels[dollar_label_count] = label;
+ dollar_label_instances[dollar_label_count] = 1;
+ dollar_label_defines[dollar_label_count] = 1;
+ ++dollar_label_count;
+}
+
+/*
+ * dollar_label_name()
+ *
+ * Caller must copy returned name: we re-use the area for the next name.
+ *
+ * The mth occurence of label n: is turned into the symbol "Ln^Am"
+ * where n is the label number and m is the instance number. "L" makes
+ * it a label discarded unless debugging and "^A"('\1') ensures no
+ * ordinary symbol SHOULD get the same name as a local label
+ * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
+ *
+ * fb labels get the same treatment, except that ^B is used in place of ^A.
+ */
+
+char * /* Return local label name. */
+dollar_label_name (n, augend)
+ register long n; /* we just saw "n$:" : n a number */
+ register int augend; /* 0 for current instance, 1 for new instance */
+{
+ long i;
+ /* Returned to caller, then copied. used for created names ("4f") */
+ static char symbol_name_build[24];
+ register char *p;
+ register char *q;
+ char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
+
+ know (n >= 0);
+ know (augend == 0 || augend == 1);
+ p = symbol_name_build;
+ *p++ = 'L';
+
+ /* Next code just does sprintf( {}, "%d", n); */
+ /* label number */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = n; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p = *--q) != '\0')
+ ++p;
+
+ *p++ = 1; /* ^A */
+
+ /* instance number */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p++ = *--q) != '\0');;
+
+ /* The label, as a '\0' ended string, starts at symbol_name_build. */
+ return symbol_name_build;
+}
+
+/*
+ * Sombody else's idea of local labels. They are made by "n:" where n
+ * is any decimal digit. Refer to them with
+ * "nb" for previous (backward) n:
+ * or "nf" for next (forward) n:.
+ *
+ * We do a little better and let n be any number, not just a single digit, but
+ * since the other guy's assembler only does ten, we treat the first ten
+ * specially.
+ *
+ * Like someone else's assembler, we have one set of local label counters for
+ * entire assembly, not one set per (sub)segment like in most assemblers. This
+ * implies that one can refer to a label in another segment, and indeed some
+ * crufty compilers have done just that.
+ *
+ * Since there could be a LOT of these things, treat them as a sparse array.
+ */
+
+#define FB_LABEL_SPECIAL (10)
+
+static long fb_low_counter[FB_LABEL_SPECIAL];
+static long *fb_labels;
+static long *fb_label_instances;
+static long fb_label_count;
+static long fb_label_max;
+
+/* this must be more than FB_LABEL_SPECIAL */
+#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
+
+static void
+fb_label_init ()
+{
+ memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
+} /* fb_label_init() */
+
+/* add one to the instance number of this fb label */
+void
+fb_label_instance_inc (label)
+ long label;
+{
+ long *i;
+
+ if (label < FB_LABEL_SPECIAL)
+ {
+ ++fb_low_counter[label];
+ return;
+ }
+
+ if (fb_labels != NULL)
+ {
+ for (i = fb_labels + FB_LABEL_SPECIAL;
+ i < fb_labels + fb_label_count; ++i)
+ {
+ if (*i == label)
+ {
+ ++fb_label_instances[i - fb_labels];
+ return;
+ } /* if we find it */
+ } /* for each existing label */
+ }
+
+ /* if we get to here, we don't have label listed yet. */
+
+ if (fb_labels == NULL)
+ {
+ fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
+ fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
+ fb_label_max = FB_LABEL_BUMP_BY;
+ fb_label_count = FB_LABEL_SPECIAL;
+
+ }
+ else if (fb_label_count == fb_label_max)
+ {
+ fb_label_max += FB_LABEL_BUMP_BY;
+ fb_labels = (long *) xrealloc ((char *) fb_labels,
+ fb_label_max * sizeof (long));
+ fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
+ fb_label_max * sizeof (long));
+ } /* if we needed to grow */
+
+ fb_labels[fb_label_count] = label;
+ fb_label_instances[fb_label_count] = 1;
+ ++fb_label_count;
+}
+
+static long
+fb_label_instance (label)
+ long label;
+{
+ long *i;
+
+ if (label < FB_LABEL_SPECIAL)
+ {
+ return (fb_low_counter[label]);
+ }
+
+ if (fb_labels != NULL)
+ {
+ for (i = fb_labels + FB_LABEL_SPECIAL;
+ i < fb_labels + fb_label_count; ++i)
+ {
+ if (*i == label)
+ {
+ return (fb_label_instances[i - fb_labels]);
+ } /* if we find it */
+ } /* for each existing label */
+ }
+
+ /* We didn't find the label, so this must be a reference to the
+ first instance. */
+ return 0;
+}
+
+/*
+ * fb_label_name()
+ *
+ * Caller must copy returned name: we re-use the area for the next name.
+ *
+ * The mth occurence of label n: is turned into the symbol "Ln^Bm"
+ * where n is the label number and m is the instance number. "L" makes
+ * it a label discarded unless debugging and "^B"('\2') ensures no
+ * ordinary symbol SHOULD get the same name as a local label
+ * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
+ *
+ * dollar labels get the same treatment, except that ^A is used in place of ^B. */
+
+char * /* Return local label name. */
+fb_label_name (n, augend)
+ long n; /* we just saw "n:", "nf" or "nb" : n a number */
+ long augend; /* 0 for nb, 1 for n:, nf */
+{
+ long i;
+ /* Returned to caller, then copied. used for created names ("4f") */
+ static char symbol_name_build[24];
+ register char *p;
+ register char *q;
+ char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
+
+ know (n >= 0);
+ know (augend == 0 || augend == 1);
+ p = symbol_name_build;
+ *p++ = 'L';
+
+ /* Next code just does sprintf( {}, "%d", n); */
+ /* label number */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = n; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p = *--q) != '\0')
+ ++p;
+
+ *p++ = 2; /* ^B */
+
+ /* instance number */
+ q = symbol_name_temporary;
+ for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
+ {
+ *q = i % 10 + '0';
+ i /= 10;
+ }
+ while ((*p++ = *--q) != '\0');;
+
+ /* The label, as a '\0' ended string, starts at symbol_name_build. */
+ return (symbol_name_build);
+} /* fb_label_name() */
+
+/*
+ * decode name that may have been generated by foo_label_name() above. If
+ * the name wasn't generated by foo_label_name(), then return it unaltered.
+ * This is used for error messages.
+ */
+
+char *
+decode_local_label_name (s)
+ char *s;
+{
+ char *p;
+ char *symbol_decode;
+ int label_number;
+ int instance_number;
+ char *type;
+ const char *message_format = _("\"%d\" (instance number %d of a %s label)");
+
+ if (s[0] != 'L')
+ return s;
+
+ for (label_number = 0, p = s + 1; isdigit ((unsigned char) *p); ++p)
+ label_number = (10 * label_number) + *p - '0';
+
+ if (*p == 1)
+ type = "dollar";
+ else if (*p == 2)
+ type = "fb";
+ else
+ return s;
+
+ for (instance_number = 0, p++; isdigit ((unsigned char) *p); ++p)
+ instance_number = (10 * instance_number) + *p - '0';
+
+ symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
+ sprintf (symbol_decode, message_format, label_number, instance_number, type);
+
+ return symbol_decode;
+}
+
+/* Get the value of a symbol. */
+
+valueT
+S_GET_VALUE (s)
+ symbolS *s;
+{
+ if (!s->sy_resolved && s->sy_value.X_op != O_constant)
+ resolve_symbol_value (s, 1);
+ if (s->sy_value.X_op != O_constant)
+ {
+ static symbolS *recur;
+
+ /* FIXME: In non BFD assemblers, S_IS_DEFINED and S_IS_COMMON
+ may call S_GET_VALUE. We use a static symbol to avoid the
+ immediate recursion. */
+ if (recur == s)
+ return (valueT) s->sy_value.X_add_number;
+ recur = s;
+ if (! s->sy_resolved
+ || s->sy_value.X_op != O_symbol
+ || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
+ as_bad (_("Attempt to get value of unresolved symbol %s"),
+ S_GET_NAME (s));
+ recur = NULL;
+ }
+ return (valueT) s->sy_value.X_add_number;
+}
+
+/* Set the value of a symbol. */
+
+void
+S_SET_VALUE (s, val)
+ symbolS *s;
+ valueT val;
+{
+ s->sy_value.X_op = O_constant;
+ s->sy_value.X_add_number = (offsetT) val;
+ s->sy_value.X_unsigned = 0;
+}
+
+void
+copy_symbol_attributes (dest, src)
+ symbolS *dest, *src;
+{
+#ifdef BFD_ASSEMBLER
+ /* In an expression, transfer the settings of these flags.
+ The user can override later, of course. */
+#define COPIED_SYMFLAGS (BSF_FUNCTION | BSF_OBJECT)
+ dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
+#endif
+
+#ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
+ OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
+#endif
+}
+
+#ifdef BFD_ASSEMBLER
+
+int
+S_IS_FUNCTION (s)
+ symbolS *s;
+{
+ flagword flags = s->bsym->flags;
+
+ return (flags & BSF_FUNCTION) != 0;
+}
+
+int
+S_IS_EXTERNAL (s)
+ symbolS *s;
+{
+ flagword flags = s->bsym->flags;
+
+ /* sanity check */
+ if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
+ abort ();
+
+ return (flags & BSF_GLOBAL) != 0;
+}
+
+int
+S_IS_WEAK (s)
+ symbolS *s;
+{
+ return (s->bsym->flags & BSF_WEAK) != 0;
+}
+
+int
+S_IS_COMMON (s)
+ symbolS *s;
+{
+ return bfd_is_com_section (s->bsym->section);
+}
+
+int
+S_IS_DEFINED (s)
+ symbolS *s;
+{
+ return s->bsym->section != undefined_section;
+}
+
+int
+S_IS_DEBUG (s)
+ symbolS *s;
+{
+ if (s->bsym->flags & BSF_DEBUGGING)
+ return 1;
+ return 0;
+}
+
+int
+S_IS_LOCAL (s)
+ symbolS *s;
+{
+ flagword flags = s->bsym->flags;
+ const char *name;
+
+ /* sanity check */
+ if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
+ abort ();
+
+ if (bfd_get_section (s->bsym) == reg_section)
+ return 1;
+
+ if (flag_strip_local_absolute
+ && (flags & BSF_GLOBAL) == 0
+ && bfd_get_section (s->bsym) == absolute_section)
+ return 1;
+
+ name = S_GET_NAME (s);
+ return (name != NULL
+ && ! S_IS_DEBUG (s)
+ && (strchr (name, '\001')
+ || strchr (name, '\002')
+ || (! flag_keep_locals
+ && (bfd_is_local_label (stdoutput, s->bsym)
+ || (flag_mri
+ && name[0] == '?'
+ && name[1] == '?')))));
+}
+
+int
+S_IS_EXTERN (s)
+ symbolS *s;
+{
+ return S_IS_EXTERNAL (s);
+}
+
+int
+S_IS_STABD (s)
+ symbolS *s;
+{
+ return S_GET_NAME (s) == 0;
+}
+
+CONST char *
+S_GET_NAME (s)
+ symbolS *s;
+{
+ return s->bsym->name;
+}
+
+segT
+S_GET_SEGMENT (s)
+ symbolS *s;
+{
+ return s->bsym->section;
+}
+
+void
+S_SET_SEGMENT (s, seg)
+ symbolS *s;
+ segT seg;
+{
+ /* Don't reassign section symbols. The direct reason is to prevent seg
+ faults assigning back to const global symbols such as *ABS*, but it
+ shouldn't happen anyway. */
+
+ if (s->bsym->flags & BSF_SECTION_SYM)
+ {
+ if (s->bsym->section != seg)
+ abort();
+ }
+ else
+ s->bsym->section = seg;
+}
+
+void
+S_SET_EXTERNAL (s)
+ symbolS *s;
+{
+ if ((s->bsym->flags & BSF_WEAK) != 0)
+ {
+ /* Let .weak override .global. */
+ return;
+ }
+ s->bsym->flags |= BSF_GLOBAL;
+ s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK);
+}
+
+void
+S_CLEAR_EXTERNAL (s)
+ symbolS *s;
+{
+ if ((s->bsym->flags & BSF_WEAK) != 0)
+ {
+ /* Let .weak override. */
+ return;
+ }
+ s->bsym->flags |= BSF_LOCAL;
+ s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK);
+}
+
+void
+S_SET_WEAK (s)
+ symbolS *s;
+{
+ s->bsym->flags |= BSF_WEAK;
+ s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL);
+}
+
+void
+S_SET_NAME (s, name)
+ symbolS *s;
+ char *name;
+{
+ s->bsym->name = name;
+}
+#endif /* BFD_ASSEMBLER */
+
+void
+symbol_begin ()
+{
+ symbol_lastP = NULL;
+ symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
+ sy_hash = hash_new ();
+
+ memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
+#ifdef BFD_ASSEMBLER
+#if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
+ abs_symbol.bsym = bfd_abs_section.symbol;
+#endif
+#else
+ /* Can't initialise a union. Sigh. */
+ S_SET_SEGMENT (&abs_symbol, absolute_section);
+#endif
+ abs_symbol.sy_value.X_op = O_constant;
+ abs_symbol.sy_frag = &zero_address_frag;
+
+ if (LOCAL_LABELS_FB)
+ fb_label_init ();
+}
+
+
+int indent_level;
+
+/* Maximum indent level.
+ Available for modification inside a gdb session. */
+int max_indent_level = 8;
+
+#if 0
+
+static void
+indent ()
+{
+ printf ("%*s", indent_level * 4, "");
+}
+
+#endif
+
+void
+print_symbol_value_1 (file, sym)
+ FILE *file;
+ symbolS *sym;
+{
+ const char *name = S_GET_NAME (sym);
+ if (!name || !name[0])
+ name = "(unnamed)";
+ fprintf (file, "sym %lx %s", (unsigned long) sym, name);
+ if (sym->sy_frag != &zero_address_frag)
+ fprintf (file, " frag %lx", (long) sym->sy_frag);
+ if (sym->written)
+ fprintf (file, " written");
+ if (sym->sy_resolved)
+ fprintf (file, " resolved");
+ else if (sym->sy_resolving)
+ fprintf (file, " resolving");
+ if (sym->sy_used_in_reloc)
+ fprintf (file, " used-in-reloc");
+ if (sym->sy_used)
+ fprintf (file, " used");
+ if (S_IS_LOCAL (sym))
+ fprintf (file, " local");
+ if (S_IS_EXTERN (sym))
+ fprintf (file, " extern");
+ if (S_IS_DEBUG (sym))
+ fprintf (file, " debug");
+ if (S_IS_DEFINED (sym))
+ fprintf (file, " defined");
+ fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
+ if (sym->sy_resolved)
+ {
+ segT s = S_GET_SEGMENT (sym);
+
+ if (s != undefined_section
+ && s != expr_section)
+ fprintf (file, " %lx", (long) S_GET_VALUE (sym));
+ }
+ else if (indent_level < max_indent_level
+ && S_GET_SEGMENT (sym) != undefined_section)
+ {
+ indent_level++;
+ fprintf (file, "\n%*s<", indent_level * 4, "");
+ print_expr_1 (file, &sym->sy_value);
+ fprintf (file, ">");
+ indent_level--;
+ }
+ fflush (file);
+}
+
+void
+print_symbol_value (sym)
+ symbolS *sym;
+{
+ indent_level = 0;
+ print_symbol_value_1 (stderr, sym);
+ fprintf (stderr, "\n");
+}
+
+static void
+print_binary (file, name, exp)
+ FILE *file;
+ const char * name;
+ expressionS *exp;
+{
+ indent_level++;
+ fprintf (file, "%s\n%*s<", name, indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_op_symbol);
+ fprintf (file, ">");
+ indent_level--;
+}
+
+void
+print_expr_1 (file, exp)
+ FILE *file;
+ expressionS *exp;
+{
+ fprintf (file, "expr %lx ", (long) exp);
+ switch (exp->X_op)
+ {
+ case O_illegal:
+ fprintf (file, "illegal");
+ break;
+ case O_absent:
+ fprintf (file, "absent");
+ break;
+ case O_constant:
+ fprintf (file, "constant %lx", (long) exp->X_add_number);
+ break;
+ case O_symbol:
+ indent_level++;
+ fprintf (file, "symbol\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">");
+ maybe_print_addnum:
+ if (exp->X_add_number)
+ fprintf (file, "\n%*s%lx", indent_level * 4, "",
+ (long) exp->X_add_number);
+ indent_level--;
+ break;
+ case O_register:
+ fprintf (file, "register #%d", (int) exp->X_add_number);
+ break;
+ case O_big:
+ fprintf (file, "big");
+ break;
+ case O_uminus:
+ fprintf (file, "uminus -<");
+ indent_level++;
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">");
+ goto maybe_print_addnum;
+ case O_bit_not:
+ fprintf (file, "bit_not");
+ break;
+ case O_multiply:
+ print_binary (file, "multiply", exp);
+ break;
+ case O_divide:
+ print_binary (file, "divide", exp);
+ break;
+ case O_modulus:
+ print_binary (file, "modulus", exp);
+ break;
+ case O_left_shift:
+ print_binary (file, "lshift", exp);
+ break;
+ case O_right_shift:
+ print_binary (file, "rshift", exp);
+ break;
+ case O_bit_inclusive_or:
+ print_binary (file, "bit_ior", exp);
+ break;
+ case O_bit_exclusive_or:
+ print_binary (file, "bit_xor", exp);
+ break;
+ case O_bit_and:
+ print_binary (file, "bit_and", exp);
+ break;
+ case O_eq:
+ print_binary (file, "eq", exp);
+ break;
+ case O_ne:
+ print_binary (file, "ne", exp);
+ break;
+ case O_lt:
+ print_binary (file, "lt", exp);
+ break;
+ case O_le:
+ print_binary (file, "le", exp);
+ break;
+ case O_ge:
+ print_binary (file, "ge", exp);
+ break;
+ case O_gt:
+ print_binary (file, "gt", exp);
+ break;
+ case O_logical_and:
+ print_binary (file, "logical_and", exp);
+ break;
+ case O_logical_or:
+ print_binary (file, "logical_or", exp);
+ break;
+ case O_add:
+ indent_level++;
+ fprintf (file, "add\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_op_symbol);
+ fprintf (file, ">");
+ goto maybe_print_addnum;
+ case O_subtract:
+ indent_level++;
+ fprintf (file, "subtract\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_add_symbol);
+ fprintf (file, ">\n%*s<", indent_level * 4, "");
+ print_symbol_value_1 (file, exp->X_op_symbol);
+ fprintf (file, ">");
+ goto maybe_print_addnum;
+ default:
+ fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
+ break;
+ }
+ fflush (stdout);
+}
+
+void
+print_expr (exp)
+ expressionS *exp;
+{
+ print_expr_1 (stderr, exp);
+ fprintf (stderr, "\n");
+}
+
+void
+symbol_print_statistics (file)
+ FILE *file;
+{
+ hash_print_statistics (file, "symbol table", sy_hash);
+}
+
+/* end of symbols.c */
diff --git a/gas/symbols.h b/gas/symbols.h
new file mode 100644
index 00000000000..c6efbdb34de
--- /dev/null
+++ b/gas/symbols.h
@@ -0,0 +1,90 @@
+/* symbols.h -
+ Copyright (C) 1987, 90, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+extern struct obstack notes; /* eg FixS live here. */
+
+extern struct obstack cond_obstack; /* this is where we track .ifdef/.endif
+ (if we do that at all). */
+
+extern symbolS *symbol_rootP; /* all the symbol nodes */
+extern symbolS *symbol_lastP; /* last struct symbol we made, or NULL */
+
+extern symbolS abs_symbol;
+
+extern int symbol_table_frozen;
+
+/* This is non-zero if symbols are case sensitive, which is the
+ default. */
+extern int symbols_case_sensitive;
+
+char *decode_local_label_name PARAMS ((char *s));
+symbolS *symbol_find PARAMS ((CONST char *name));
+symbolS *symbol_find_base PARAMS ((CONST char *name, int strip_underscore));
+symbolS *symbol_find_or_make PARAMS ((const char *name));
+symbolS *symbol_make PARAMS ((CONST char *name));
+symbolS *symbol_new PARAMS ((CONST char *name, segT segment, valueT value,
+ fragS * frag));
+symbolS *symbol_create PARAMS ((CONST char *name, segT segment, valueT value,
+ fragS * frag));
+symbolS *colon PARAMS ((const char *sym_name));
+void local_colon PARAMS ((int n));
+void symbol_begin PARAMS ((void));
+void symbol_print_statistics PARAMS ((FILE *));
+void symbol_table_insert PARAMS ((symbolS * symbolP));
+valueT resolve_symbol_value PARAMS ((symbolS *, int));
+
+void print_symbol_value PARAMS ((symbolS *));
+void print_expr PARAMS ((expressionS *));
+void print_expr_1 PARAMS ((FILE *, expressionS *));
+void print_symbol_value_1 PARAMS ((FILE *, symbolS *));
+
+int dollar_label_defined PARAMS ((long l));
+void dollar_label_clear PARAMS ((void));
+void define_dollar_label PARAMS ((long l));
+char *dollar_label_name PARAMS ((long l, int augend));
+
+void fb_label_instance_inc PARAMS ((long label));
+char *fb_label_name PARAMS ((long n, long augend));
+
+extern void copy_symbol_attributes PARAMS ((symbolS *, symbolS *));
+
+/* Get and set the values of symbols. These used to be macros. */
+extern valueT S_GET_VALUE PARAMS ((symbolS *));
+extern void S_SET_VALUE PARAMS ((symbolS *, valueT));
+
+#ifdef BFD_ASSEMBLER
+extern int S_IS_EXTERNAL PARAMS ((symbolS *));
+extern int S_IS_WEAK PARAMS ((symbolS *));
+extern int S_IS_COMMON PARAMS ((symbolS *));
+extern int S_IS_DEFINED PARAMS ((symbolS *));
+extern int S_IS_DEBUG PARAMS ((symbolS *));
+extern int S_IS_LOCAL PARAMS ((symbolS *));
+extern int S_IS_EXTERN PARAMS ((symbolS *));
+extern int S_IS_STABD PARAMS ((symbolS *));
+extern CONST char *S_GET_NAME PARAMS ((symbolS *));
+extern segT S_GET_SEGMENT PARAMS ((symbolS *));
+extern void S_SET_SEGMENT PARAMS ((symbolS *, segT));
+extern void S_SET_EXTERNAL PARAMS ((symbolS *));
+extern void S_SET_NAME PARAMS ((symbolS *, char *));
+extern void S_CLEAR_EXTERNAL PARAMS ((symbolS *));
+extern void S_SET_WEAK PARAMS ((symbolS *));
+#endif
+
+/* end of symbols.h */
diff --git a/gas/tc.h b/gas/tc.h
new file mode 100644
index 00000000000..4e4046ccc14
--- /dev/null
+++ b/gas/tc.h
@@ -0,0 +1,112 @@
+/* tc.h - target cpu dependent
+
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* In theory (mine, at least!) the machine dependent part of the assembler
+ should only have to include one file. This one. -- JF */
+
+extern const pseudo_typeS md_pseudo_table[];
+
+/* JF moved this here from as.h under the theory that nobody except MACHINE.c
+ and write.c care about it anyway. */
+
+struct relax_type
+{
+ /* Forward reach. Signed number. > 0. */
+ long rlx_forward;
+ /* Backward reach. Signed number. < 0. */
+ long rlx_backward;
+
+ /* Bytes length of this address. */
+ unsigned char rlx_length;
+
+ /* Next longer relax-state. 0 means there is no 'next' relax-state. */
+ relax_substateT rlx_more;
+};
+
+typedef struct relax_type relax_typeS;
+
+extern const int md_reloc_size; /* Size of a relocation record */
+
+char *md_atof PARAMS ((int what_statement_type, char *literalP, int *sizeP));
+#ifndef md_estimate_size_before_relax
+int md_estimate_size_before_relax PARAMS ((fragS * fragP, segT segment));
+#endif
+int md_parse_option PARAMS ((int c, char *arg));
+void md_show_usage PARAMS ((FILE *));
+long md_pcrel_from PARAMS ((fixS * fixP));
+short tc_coff_fix2rtype PARAMS ((fixS * fixP));
+void md_assemble PARAMS ((char *str));
+void md_begin PARAMS ((void));
+#ifndef md_create_long_jump
+void md_create_long_jump PARAMS ((char *ptr, addressT from_addr,
+ addressT to_addr, fragS * frag,
+ symbolS * to_symbol));
+#endif
+#ifndef md_create_short_jump
+void md_create_short_jump PARAMS ((char *ptr, addressT from_addr,
+ addressT to_addr, fragS * frag,
+ symbolS * to_symbol));
+#endif
+void md_number_to_chars PARAMS ((char *buf, valueT val, int n));
+
+#ifndef md_operand
+void md_operand PARAMS ((expressionS * expressionP));
+#endif
+
+#ifdef MD_APPLY_FIX3
+int md_apply_fix3 PARAMS ((fixS * fixP, valueT *val, segT seg));
+#endif
+#ifdef BFD_ASSEMBLER
+int md_apply_fix PARAMS ((fixS * fixP, valueT *val));
+#ifndef md_convert_frag
+void md_convert_frag PARAMS ((bfd * headers, segT sec, fragS * fragP));
+#endif
+#ifndef tc_headers_hook
+void tc_headers_hook PARAMS ((segT *, fixS *));
+#endif
+#ifndef RELOC_EXPANSION_POSSIBLE
+extern arelent *tc_gen_reloc PARAMS ((asection *, fixS *));
+#else
+extern arelent **tc_gen_reloc PARAMS ((asection *, fixS *));
+#endif
+#else /* not BFD_ASSEMBLER */
+void md_apply_fix PARAMS ((fixS * fixP, long val));
+#ifndef md_convert_frag
+void md_convert_frag PARAMS ((object_headers * headers, segT, fragS * fragP));
+#endif
+
+#ifndef tc_crawl_symbol_chain
+void tc_crawl_symbol_chain PARAMS ((object_headers * headers));
+#endif /* tc_crawl_symbol_chain */
+
+#ifndef tc_headers_hook
+void tc_headers_hook PARAMS ((object_headers * headers));
+#endif /* tc_headers_hook */
+#endif /* BFD_ASSEMBLER */
+
+#ifndef md_section_align
+valueT md_section_align PARAMS ((segT seg, valueT size));
+#endif
+
+#ifndef md_undefined_symbol
+symbolS *md_undefined_symbol PARAMS ((char *name));
+#endif
+
+/* end of tc.h */
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
new file mode 100644
index 00000000000..d8f865680e5
--- /dev/null
+++ b/gas/testsuite/ChangeLog
@@ -0,0 +1,2333 @@
+1999-05-02 Nick Clifton <nickc@cygnus.com>
+
+ * gas/mcore/allinsn.d: Update to match latest assembler
+ operations.
+
+1999-04-16 DJ Delorie <dj@cygnus.com>
+
+ * gas/i386/amd.s: Add NOPs to align for coff targets
+ * gas/i386/amd.d: and check for them.
+
+Thu Apr 15 15:03:43 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/basic/basic.exp (do_coprmem): No longer expected to file.
+
+Wed Apr 14 13:43:06 1999 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/basic/branch.s: Do not use immediate value where we
+ really want a register.
+ * gas/hppa/basic/coprmem.s: Likewise.
+ * gas/hppa/basic/fmemLRbug.s: Likewise.
+ * gas/hppa/basic/coprmem.s: Likewise.
+ * gas/hppa/basic/spop.s: Likewise.
+ * gas/hppa/basic/imem.s: Likewise.
+ * gas/hppa/parse/badfmpyadd.s: Likewise.
+ * gas/hppa/parse/calldatabug.s: Likewise.
+ * gas/hppa/parse/entrybug.s: Likewise.
+ * gas/hppa/parse/exprbug.s: Likewise.
+ * gas/hppa/parse/fixup7bug.s: Likewise.
+ * gas/hppa/parse/labelbug.s: Likewise.
+ * gas/hppa/reloc/applybug.s: Likewise.
+ * gas/hppa/reloc/funcrelocbug.s: Likewise.
+ * gas/hppa/reloc/labelopbug.s: Likewise.
+ * gas/hppa/reloc/longcall.s: Likewise.
+ * gas/hppa/reloc/plabelbug.s: Likewise.
+ * gas/hppa/reloc/reduce.s: Likewise.
+ * gas/hppa/reloc/reduce2.s: Likewise.
+ * gas/hppa/reloc/reduce3.s: Likewise.
+ * gas/hppa/unsorted/brlenbug.s: Likewise.
+ * gas/hppa/unsorted/importbug.s: Likewise.
+ * gas/hppa/unsorted/lasbeldiffs.s: Likewise.
+
+ * gas/hppa/basic/basic.exp (do_imem): Handle multiple encodings
+ for loads and stores using reg + small d addresses.
+ No longer expect failure for mis-parse of imm %reg.
+
+1999-04-13 Doug Evans <devans@casey.cygnus.com>
+
+ * gas/m32r/m32rx.d (cmpu__rach): Fix expected output.
+ * gas/m32r/m32rx.s (bc__add,add__bc): Explicitly specify short branch
+ so branch relaxation restrictions won't interfere with parallelization
+ attempts.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * gas/mcore: New Directory.
+ * gas/mcore/allinsn.exp: New File: Expect file for MCore assembly
+ tests.
+ * gas/mcore/allinsn.s: New File: Source file for MCore assembly
+ tests.
+ * gas/mcore/allinsn.d: New File: Expected output file for MCore
+ assembly tests.
+
+1999-03-20 Doug Evans <devans@casey.cygnus.com>
+
+ * gas/m32r/m32rx.[sd]: Fix a few more testcases.
+
+1999-03-16 Martin Hunt <hunt@cygnus.com>
+
+ * gas/d30v/d30.exp (run_list_test): Add new tests,
+ label, guard-debug, serial, warn_oddreg, bittest, and mul.
+
+ * gas/d30v/opt.s: Fix some warnings and add a few labels
+ to keep things from parallelizing where we don't want them to.
+
+ * gas/d30v/reloc.s: Fix warning.
+
+ * gas/d30v/opt.d, reloc.d, inst.d: Rebuild.
+
+ * gas/d30v/label.s: New test. Check that labels are aligned
+ on 8-byte boundaries.
+
+ * gas/d30v/guard-debug.s: New test. Test output with "-g".
+
+ * gas/d30v/serial.s: New test. Check for warnings with
+ illegal serial instructions.
+
+ * gas/d30v/warn_oddreg.s: New test. CHeck for warnings when
+ odd-numbered registers are used for some instructions.
+
+ * gas/d30v/bittest.s: New test. Check for bit operation
+ instructions (BCLR, BNOT, BSET, BTST) in the IU.
+
+ * gas/d30v/mul.s: New test. Check for restricted sequences
+ in a bunch of different multiply instructions.
+
+ * gas/vtable/vtable.exp (run_list_test): Don't
+ run test on D30V.
+
+1999-03-05 Nick Clifton <nickc@cygnus.com>
+
+ * gas/all/gas.exp: Expect strongarm-coff target to fail cofftag
+ test.
+
+1999-02-13 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * gas/mips/mips.exp: Run the new tests, below.
+ * gas/mips/elf_e_flags1.d, gas/mips/elf_e_flags2.d,
+ gas/mips/elf_e_flags3.d, gas/mips/elf_e_flags4.d: New files.
+ * gas/mips/elf_e_flags.c, gas/mips/elf_e_flags.s: New files.
+
+ * lib/gas-defs.exp (run_dump_test): Document. It's not
+ really trivial.
+
+ * lib/gas-defs.exp (run_dump_test): Clean up logic for guessing
+ $program (the dump tool).
+
+1999-02-10 Doug Evans <devans@casey.cygnus.com>
+
+ * gas/m32r/allinsn.d: Prefix all | with \.
+ (push,pop): Fix expected output.
+ * gas/m32r/relax-1.d: Emitted nops are serial, not parallel.
+ * gas/m32r/fslot.d: Prefix all | with \.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * gas/vtable/inherit0.s: Do not use '@' prefix to .type operator.
+ Some ports use it as a comment initiator.
+
+ * gas/vtable/entry1.d: Do not look for an addend. Some ports use
+ REL relocations and so do not have one.
+
+1998-12-18 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.s: Fix to match latest assembler syntax.
+ * gas/fr30/allinsn.d: Fix to match latest assembler output
+
+1998-12-03 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.d: Updated to match latest assembler output.
+
+1998-12-02 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.s: Replace illegal insns with legal versions.
+
+ * gas/fr30/allinsn.d: Update to match latest assembler output.
+
+Thu Nov 19 15:59:51 1998 Dave Brolley <brolley@cygnus.com>
+
+ * gas/fr30/allinsn.s: Reorder insns for better simulation.
+
+Thu Nov 19 07:50:44 1998 Doug Evans <devans@charmed.cygnus.com>
+
+ * gas/mips/sync.[sd]: New testcase.
+ * gas/mips/mips.exp: Run it.
+
+Wed Nov 18 11:27:56 1998 Dave Brolley <brolley@cygnus.com>
+
+ * gas/fr30/allinsn.s (dmov): Correct hex literals.
+
+Tue Nov 17 15:24:20 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.s: Moved currently un-assembliable instructions
+ to end of file.
+
+ * gas/fr30/allinsn.d: Added disassembly of currently assembliable
+ opcodes.
+
+Mon Nov 16 16:50:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.s: Fix syntax errors.
+
+Mon Nov 16 19:27:52 1998 Dave Brolley <brolley@cygnus.com>
+
+ * gas/fr30/allinsn.s: Fixed more typos.
+
+Fri Nov 13 13:15:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.s: Fixed typos and added some tests of upper
+ case vs lower case.
+
+Tue Nov 10 14:54:47 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/fr30/allinsn.s: New file.
+ * gas/fr30/allinsn.d: New file.
+ * gas/fr30/allinsn.exp: New file.
+ * gas/fr30/fr30.exp: New file.
+
+Mon Nov 2 20:16:50 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gas/m32r/fslot.[sd]: New testcase.
+ * gas/m32r/m32r.exp: Run it.
+
+Tue Oct 20 11:35:06 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * gas/i386/i386.exp: Run AMD insn test.
+ * gas/i386/amd.s: New test.
+ * gas/i386/amd.d: New test results.
+
+Sun Sep 20 01:00:01 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * gas/vtable/inherit1.l: Require only the word GAS somewere in the
+ first line of the listing.
+
+Tue Sep 1 10:20:03 1998 Richard Henderson <rth@cygnus.com>
+
+ * gas/ppc/astest.d: Adjust regexps to match a 64-bit host.
+ * gas/ppc/astest2.d: Likewise.
+
+Mon Aug 31 13:25:07 1998 Richard Henderson <rth@cygnus.com>
+
+ * gas/vtable/{entry0.d,entry1.d,inherit0.d}: Fix pattern matching
+ of whitespace for 64-bit hosts.
+
+Mon Aug 31 12:45:49 1998 Richard Henderson <rth@cygnus.com>
+
+ * gas/vtable/vtable.exp: New.
+ * gas/vtable/{entry0.s,entry0.d}: New.
+ * gas/vtable/{entry1.s,entry1.d}: New.
+ * gas/vtable/{inherit0.s,inherit0.d}: New.
+ * gas/vtable/{inherit1.s,inherit1.l}: New.
+
+Thu Aug 20 23:18:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/i386/white.l: Revert patch of August 12.
+
+Wed Aug 12 11:54:37 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/udf.s: New test.
+ * gas/mn10300/basic.exp: Run it.
+
+Wed Aug 12 13:25:38 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * gas/i386/general.l: Test andb $~0x80,foo.
+ * gas/i386/general.s: Update.
+
+ * gas/i386/white.l: Expect warning for stand-alone ss prefix.
+
+Tue Jul 21 12:46:59 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * gas/i386/white.s: Add some more whitespace tests.
+ * gas/i386/white.l: Update accordingly.
+
+Mon Jul 13 18:15:11 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * gas/i386/*: All new i386 testsuite.
+
+1998-07-02 Ken Raeburn <raeburn@cygnus.com>
+
+ * lib/gas-defs.exp (gas_init): Complain if target name isn't in
+ canonical form.
+
+Wed Jul 1 15:35:09 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/all/gas.exp: Expect ARM and Thumb cofftag test to fail.
+
+Wed Jul 1 17:31:39 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/ppc/simpshft.s: Add alignment so that it works on AIX.
+ * gas/ppc/simpshft.d: Change accordingly. Only dump the .text
+ section.
+
+Tue Jun 23 15:14:43 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/v850/hilo2.s: Use r1 as the destination of the movea
+ instruction, since r0 is read only.
+
+ * gas/v850/basic.exp: Fix names of special area relocations.
+ Set -mwarn-signed-overflow flag when running range.s test.
+
+Sun Jun 21 12:44:43 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/d30v/reloc.d: Updated to match latest assembler output.
+
+Wed Jun 17 14:02:10 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/mips/delay.d: Add -mcpu=NNNN to gas flags to let test case
+ run on differently targeted assembler.
+ * gas/mips/{ld-ilocks-addr32,ld-svr4pic.d}: Ditto.
+ * gas/mips/{ld-xgot.d,lif-svr4pic.d,lif-xgot.d}: Same.
+ * gas/mips/{mips16.d,mips4.d,nodelay.d}: Again.
+ * gas/mips/{trunc.d,uld.d,ulh-xgot.d,usd.d}: And then some.
+
+ * gas/mips/ld-ilocks.d: Removed disassembler flags to let target
+ defaults go unmodified. Replaced $f4/$f5 with $fp[45], as the
+ original `ld.d' had. Find `ld.s'.
+ * gas/mips/mul-ilocks.d: Nearly ditto.
+
+Thu Jun 11 16:50:46 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/d30v/inst.d: Expect repeati instrucitons to be combined.
+
+ * gas/d30v/inst.s: Add nop to keep assembled instructions at
+ expected addresses.
+
+Mon Jun 8 18:47:11 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/d30v/array.d: Updated to match latest assembler results.
+ * gas/d30v/reloc.d: Partially updated to match latest assembler
+ results.
+
+Fri Jun 5 19:15:59 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * gas/m68k/operands.s: For all pc relative addresses change tstl
+ to pea since the former does not allow pcrel on m68000. Do not
+ make label foo global, so that references to it can be relaxed on
+ ELF targets.
+ * gas/m68k/operands.d, gas/m68k/op68000.d: Updated.
+
+Tue Jun 2 15:08:36 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * gas/ppc/ppc.exp: Run simpshft test.
+ * gas/ppc/simpshft.d: New file.
+ * gas/ppc/simpshft.s: New file.
+
+Mon Jun 1 17:00:22 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mips/div-ilocks.d: Handle both "break" instruction variants.
+ * gas/mips/{div.d, mul-ilocks.d, mul.d}: Likewise.
+
+Fri May 29 12:07:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips.exp: Adjust ilocks initialization to match current
+ assembler defaults more closely.
+
+ * gas/sh/fp.s: Remove ftst/nan. The assembler no longer supports
+ the instruction.
+ * gas/sh/basic.exp: Adjust accordingly.
+
+Wed May 27 15:26:51 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/d30v/align.d: Updated to match latest assembler output.
+ * gas/d30v/inst.d: Updated to match latest assembler output.
+ * gas/d30v/inst.s: Updated to match latest assembler rules.
+ * gas/d30v/opt.d: Updated to match latest assembler output.
+
+Fri May 22 15:56:51 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gas/m32r/allinsn.d: Handle 64 bit bfd_vma.
+ * gas/m32r/uppercase.d: Likewise.
+
+Thu May 21 15:03:06 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/arm/thumb.s: Add period to start of labels to prevent
+ assembler thinking that they are function entry points.
+
+Tue May 19 18:17:10 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips16.d: Correct to reflect bug fix to disassembler.
+
+Mon May 18 13:11:45 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/mips/{div,ld,mul}.d: Add assembler -mcpu= flag to match
+ disassembler.
+
+Fri May 15 14:51:01 1998 Gavin Koch <gavin@cygnus.com>
+
+ * gas/mips/mips.exp: Distinguish chains with 32-bit addresses.
+ * gas/mips/ld-ilocks-addr32.d : New.
+
+Wed May 13 15:06:31 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gas/m32r/uppercase.[sd]: Test for HIGH,SHIGH,LOW,SDA.
+
+Thu May 7 13:05:25 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/mips/break20.[sd]: New tests for 20-bit operand break and
+ sddbp instructions.
+ * gas/mips/trap20.[sd]: New tests for 20-bit operand trap
+ instructions.
+ * gas/mips/mips.exp: Run them.
+
+Thu Apr 30 11:55:01 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/d30v/{inst,array,opt,reloc}.d: Accept <symbol+offset> labels
+ in disassembly, where the offset is in hex and has a "0x" prefix.
+
+Tue Apr 28 16:38:34 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/mips/lineno.[sd]: Assembly source line number test.
+ * gas/mips/mips.exp: Added lineno test.
+
+Wed Apr 8 18:45:17 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gas/testsuite/all/gas.exp: No longer expect failures for
+ difference of undefined symbols on mn10x00 targets.
+
+Mon Mar 23 10:47:33 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/all/align.s: Back out ".section text" change below;
+ use ".text" again.
+ * gas/macros/semi.s: Ditto.
+
+Fri Mar 20 18:51:49 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * gas/all/align.s: Identify ".text" section explicitly.
+ * gas/macros/semi.s: Ditto.
+
+
+
+Mon Mar 2 13:30:40 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * gas/m32r/allinsn.[sd] (ldi8a,ldi16a): Delete.
+ (ldi16): Improve test.
+ (nop): Fix test.
+
+Thu Feb 12 20:12:39 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp/macro.out: Adjust to reflect the fact that keyword
+ arguments are now permitted after positional arguments.
+
+Wed Feb 4 15:27:44 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/arm/arm7t.d: Update to match latest assembler output.
+
+Wed Feb 4 15:40:00 1998 Geoffrey Keating <geoffk@ozemail.com.au>
+
+ * gas/ppc/ppc.exp: New file.
+ * gas/ppc/astest.s, gas/ppc/astest.d: New test.
+ * gas/ppc/astest2.s, gas/ppc/astest2.d: New test.
+
+Sun Feb 1 21:43:54 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mips/4010.s: Pad test code out to a 16byte boundary.
+ * gas/mips/4010.d: Corresponding changes.
+ * gas/mips/4100.s: Pad test code out to a 16byte boundary.
+ * gas/mips/4100.d: Corresponding changes.
+ * gas/mips/4650.s: Pad test code out to a 16byte boundary.
+ * gas/mips/4650.d: Corresponding changes.
+
+Fri Jan 30 14:09:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/moveml.d: Add test comments, fix regexps.
+
+Thu Jan 29 13:34:49 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * gas/m32r/{allinsn,high-1}.d: Allow # constant prefix to be missing.
+
+Thu Jan 29 09:43:50 1998 Richard Henderson <rth@cygnus.com>
+
+ * gas/m68k/mri_moveml.[sd]: Moved to ...
+ * gas/mri/moveml.[sd]: ... here.
+ * gas/mri/mri.exp: Run it.
+
+Tue Jan 27 21:55:44 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mips/4010.s: Add 4010 tests.
+ * gas/mips/4010.d: Expected output.
+ * gas/mips/4100.s: Add 4010 tests.
+ * gas/mips/4100.d: Expected output.
+ * gas/mips/4650.s: Add 4010 tests.
+ * gas/mips/4650.d: Expected output.
+ * gas/mips/mips.exp: Run the new tests.
+ * gas/mips/*.d: Pass the right processor model to objdump.
+ Fix minor cases where expected output was wrong due to opcode
+ conflicts.
+
+Tue Jan 27 05:35:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * gas/m68k/mri_moveml.[sd]: New testcase.
+
+Thu Jan 22 17:29:07 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/m32r/high-1.d: Add hash prefix to constants.
+
+ * gas/m32r/allinsn.s: Add hash prefix to some constants.
+ * gas/m32r/allinsn.d: Add hash prefix to constants.
+
+Wed Jan 21 21:24:08 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * gas/m88k/init.d: Fix hexadecimal offsets.
+
+Wed Jan 14 17:49:22 1998 Nick Clifton <nickc@cygnus.com>
+
+ * gas/m32r/uppercase.d: Fix white space matching.
+ * gas/m32r/relax-1.d: Fix white space matching.
+
+Wed Jan 14 15:44:32 1998 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mips/div.d: Update for recent assembler changes.
+ * gas/mips/div-ilocks.d: Likewise.
+
+Wed Jan 14 11:13:06 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * gas/m32r/allinsn.d (cmpui): Update output to new format.
+
+Thu Dec 18 11:10:42 1997 Nick Clifton <nickc@cygnus.com>
+
+ * gas/arm/inst.d: Updated to match latest disassembler changes.
+
+ * gas/arm/arm7t.d: Updated to match latest disassembler changes.
+
+Tue Dec 16 22:19:25 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * gas/mips/lb-xgot.d, gas/mips/rol.d, gas/mips/jal-svr4pic.d,
+ gas/mips/jal-xgot.d: Add assembler option to select a specific
+ target chip, the R3000.
+ * gas/mips/lb-xgot-ilocks.d: New test, specifically selecting
+ R3900.
+ * gas/mips/mips.exp: Run it.
+
+ * gas/ieee-fp/x930509a.exp: Don't run IEEE FP tests for Vax
+ targets.
+
+Wed Oct 15 10:40:14 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gas/ieee-fp/x930509a.s: Tweak slightly to work on the PA.
+
+ * gas/hppa/unsorted/unsorted.exp: Update for recent disassembler
+ changes.
+
+Thu Oct 9 18:10:44 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/set64.[sd]: `set' doesn't take negative arguments.
+
+Thu Oct 9 12:59:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/arm/arm7t.d: Update for recent disassembler changes.
+ * gas/h8300/ffxx1.d: Likewise.
+
+Wed Oct 8 16:22:50 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/reloc64.[sd]: Add testcases for %hix,%lox.
+
+Wed Oct 8 15:12:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/sparc/synth.d: Update for recent disassembler changes.
+ * gas/sparc/synth64.d: Likewise.
+
+ * gas/mips/beq.s: Add .text to .globl to mark the symbol to as a
+ function symbol.
+ * gas/mips/jal.s: Likewise.
+
+Tue Oct 7 13:30:30 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/reloc64.[sd]: New testcase.
+ * gas/sparc/sparc.exp: Run it.
+
+Sat Oct 4 19:14:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/ieee-fp/x930509a.exp: Accept m68k listing format.
+
+Fri Oct 3 15:46:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/ieee-fp/x930509a.exp: Remove setup_xfail; it should now
+ work. Correct for big endian and for tabs in input file.
+
+ * gas/alpha/fp.exp: Check for alpha-*-osf*, not alpha-*-osf1*.
+ * gas/alpha/fp.s: Change comment characters from ! to #.
+
+Thu Sep 18 11:17:53 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/splet.d: Update to new objdump output format.
+ * gas/sparc/{asi.d,membar.d,prefetch.d,rdpr.d,wrpr.d}: Likewise.
+ * gas/sparc/set64.[ds]: New testcase.
+ * gas/sparc/splet-2.[ds]: New testcase.
+ * gas/sparc/sparc.exp: Run them.
+
+Tue Sep 16 15:27:08 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merge changes from Martin Hunt:
+
+ * gas/d30v/inst.s: Add some new tests.
+
+ * gas/d30v/{inst, opt, reloc}.d: Update results with
+ new disassembler changes.
+
+ * gas/d30v/inst.[sd]: Update examples for d*i instructions.
+
+ * gas/d30v/*.d: Update all test results because
+ of new ".s" and ".l" extensions.
+
+ * gas/d30v/inst.[sd]: Correct entry for mulx2h.
+ * gas/d30v/opt.[sd]: Correct st2w instruction.
+
+ * gas/d30v/align.d: Change expected output.
+
+ * gas/d30v/reloc.[sd]: Add test case.
+
+ * gas/d30v/array.[sd]: New test case.
+
+ * gas/d30v/opt.[sd]: Added more test cases.
+
+ * gas/d30v/opt.s: Add test cases.
+ * gas/d30v/reloc.s: Fix a test case.
+ * gas/d30v/{opt,reloc}.d: Regenerate.
+
+Mon Sep 8 14:21:23 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/m32r/high-1.[ds]: New testcase.
+ * gas/m32r/m32r.exp: Run it.
+
+Mon Aug 25 11:04:24 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/m32r/relax-1.[ds]: New testcase.
+ * gas/m32r/m32r.exp: Run it.
+
+Thu Aug 14 23:49:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/arc: New directory
+ * gas/arc/{arc.exp,alias.[sd],branch.[sd],flag.[sd],insn3.[sd],j.[sd],
+ ld.[sd],math.[sd],sshift.[sd],st.[sd],warn.{exp,s}}: New files.
+
+Wed Aug 6 00:33:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Set AS and GASP to as-new, not as.new.
+
+Tue Aug 5 12:33:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Set NM to nm-new, not nm.new, to match
+ recent change in binutils build directory.
+
+Thu Jul 31 15:21:51 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gas/v850/range.s: New test.
+ * gas/v850/basic.exp: Run it.
+
+Tue Jul 29 14:35:02 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gas/v850/hilo2.s: New test.
+ * gas/v850/fepsw.s: New test.
+ * gas/v850/basic.exp: Run them.
+
+Tue Jul 15 13:03:17 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/m32r/uppercase.[sd]: New testcase.
+ * gas/m32r/m32r.exp: New file.
+
+Mon Jun 16 14:32:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/pcrel.d: Update for m68k disassembler changes.
+ * gas/m68k/operands.d: Likewise.
+
+Mon Jun 2 16:50:03 1997 Nick Clifton <nickc@cygnus.com>
+
+ * gas/arm/arm.exp: Added changes from armT-970328-branch.
+
+Mon Jun 2 12:09:02 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gas/mips/mips.exp: The r3900 has interlocks for mul, but
+ not div.
+
+Mon Jun 2 12:03:32 1997 Gavin Koch <gavin@.cygnus.com>
+
+ * gas/mips/mul.{d,s}: End the tests with no-ops.
+
+Mon Jun 2 11:48:58 1997 Gavin Koch <gavin@cygnus.com>
+
+ * lib/gas-defs.exp (regexp_diff): Improve messages when one
+ file is shorter than the other.
+
+Wed May 7 16:18:30 1997 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * gas/m88k/init.{s,d}: New checks for proper padding of
+ .init sections.
+ * gas/m88k/m88.exp: Run them.
+
+ * gas/m68k/t2.d: New file for check of presence of section
+ symbols on the m68k-motorola-sysv.
+ * gas/m68k/all.exp: Run t2 if [istarget m68*-motorola-sysv].
+
+Wed May 7 16:12:24 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/gas.exp: Don't run cofftag test for m88k-coff.
+
+ * gas/mips/lifloat.s: Update for recent changes to floating point
+ handling.
+ * gas/mips/lif-empic.d, gas/mips/lif-svr4pic.d: Likewise.
+ * gas/mips/lif-xgot.d, gas/mips/lifloat.d: Likewise.
+
+ * gas/mips/mips.exp: Handle Irix 6 like Irix 5.
+
+Sat Apr 19 23:16:35 1997 Niklas Hallqvist <niklas@petra.appli.se>
+
+ * gas/mips/mips.exp: Handle OpenBSD like NetBSD.
+
+Wed Apr 16 12:20:24 1997 Martin Hunt <hunt@cygnus.com>
+
+ * gas/d30v/d30.exp: Add optimizer test case.
+ * gas/d30v/opt.s: Add conditional compilation tests.
+ * gas/d30v/opt.d: Rebuild.
+
+Tue Apr 15 18:10:01 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gas/mips/{delay.d,nodelay.d}: added.
+
+Mon Apr 7 12:57:45 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/m32r/allinsn.d: Update to new objdump output style.
+
+Fri Apr 4 13:19:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/float.s: Put a tab before .text, to keep the PA happy.
+
+ * gas/arm/arm.exp: Only run inst and arm7t on targets which can
+ handle -EL. Add setup_xfail for thumb.
+
+ * gas/h8300/ffxx1.d: Don't fail if BFD is 64 bits.
+
+Thu Apr 3 18:26:56 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/m32r/allinsn.{exp,s.d}: New testcases.
+
+Thu Mar 27 00:42:28 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * gas/d30v/d30.exp: Add test case reloc.
+ * gas/d30v/reloc.[sd]: New files to test relocations.
+
+Sat Mar 15 17:21:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/arm/inst.d: Update for disassembler changes.
+ * gas/arm/arm7t.d: Likewise.
+
+Tue Mar 11 13:31:56 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * gas/m68k/op68000.d: Update for recent assembler bug fix.
+
+Wed Mar 5 13:01:24 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gas/all/gas.exp: xfail a couple tests for the mn10300.
+
+Mon Mar 3 11:41:00 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{add.d, float.d, regops2.d, relocs1.d, relocs1b.d,
+ relocs2.d, relocs2b.d}: Adjust to objdump format tweaks.
+
+Thu Feb 27 15:21:46 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{align.d, align.lst, align.s} New test for the
+ ".align" pseudop.
+ * gas/tic80/tic80.exp: Run the align test.
+
+Wed Feb 26 20:36:46 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{float.d, float.lst, float.s}: New tests for
+ simple floating point operands.
+ * gas/tic80/tic80.exp: Run the float test.
+
+Wed Feb 26 15:16:04 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{regops2.d, regops2.lst, regops2.s, regops3.d,
+ regops3.lst, regops3.s, regops4.d, regops4.lst, regops4.s}:
+ New tests for :m and :s operand modifiers.
+ * gas/tic80/tic80.exp: Run the regops2, regops3, and regops4 tests.
+
+Tue Feb 25 13:45:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/macros/semi.s: Force the final alignment to use a fill value
+ of 0.
+
+ * gas/all/cond.s, gas/all/cond.d: New test.
+ * gas/all/gas.exp: Run it.
+
+Mon Feb 24 10:52:12 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * lib/gas-defs.exp(gas_init): Added new parameter for script
+ name.
+
+Mon Feb 24 10:40:28 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{add.d, bitnum.d, ccode.d, cregops.d, endmask.d,
+ regops.d, relocs1.d,
+ (relocs1.c): Add file for reference.
+ (relocs1b.d): Split reloc table contents test to different test file.
+ (relocs2.c): Add test that uses various types (char, short, int, ...) of
+ static and global variables with data shuffling to generate lots of ld/st
+ instructions for the different types.
+ (relocs2.d): New file, expected code for relocs2 test.
+ (relocs2.lst): New file, TI assembler listing for reference.
+ (relocs2.s): New file, assembly source for relocs2 test.
+ (relocs2b.d): New file, expected reloc table contents for relocs2 test.
+ (tic80.exp): Run the relocs1b, relocs2, and relocs2b tests.
+
+Sun Feb 23 17:54:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * gas/all/itbl-test.c(main): Update function calls.
+ Remove parameters from itbl_get_reg_val and
+ change itbl_get_insn_name to itbl_get_field.
+
+Sun Feb 23 17:22:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * gas/mips/itbl: Add comments.
+ * gas/mips/itbl.s: Add comments. Prefix register names with $.
+ * gas/all/itbl: Generic table for testing for itbl support.
+ * gas/all/itbl.s: Generic assembly for testing for itbl support.
+ * gas/mips/itbl-test.c: Moved to gas/all.
+ * gas/all/itbl-test.c: Moved from gas/mips.
+
+Sat Feb 22 20:24:23 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{add.lst, bitnum.lst, ccode.lst, cregops.lst,
+ endmask.lst, regops.lst}: Remove ^M's from end of lines.
+ * gas/tic80/bitnum.s: Add comment to each line showing value
+ that symbolic BITNUM assembles to. Add coverage for raw
+ numeric values for the BITNUM operand.
+ * gas/tic80/bitnum.d: Update due to bitnum.s changes.
+ * gas/tic80/regops.d: Update due to opcode library additions
+ of floating point test BITNUM values that are ambiguous with
+ the integral ones.
+ * gas/tic80/relocs1.s: New test case that tests simple relocs.
+ * gas/tic80/relocs1.d: Expected output for above.
+ * gas/tic80/relocs1.lst: TI assembler listing for above.
+ * gas/tic80/tic80.exp: Add relocs1 test.
+
+Fri Feb 21 14:23:14 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * gas/d30v/{align.d, align.s, d30.exp, guard.d, guard.s,
+ inst.d, inst.s, opt.d, opt.s}: Test files for D30V.
+
+Wed Feb 19 00:55:29 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/macros/semi.s, gas/macros/semi.d: New test.
+ * gas/macros/macros.exp: Run it.
+ * gas/mri/semi.s, gas/mri/semi.d: New test.
+ * gas/mri/mri.exp: Run it.
+
+Tue Feb 18 13:37:06 1997 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/unsorted/unsorted.exp (align4 tests): Tweak expected
+ output.
+
+Fri Feb 14 17:56:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/align.d, gas/all/align.s: New test.
+ * gas/all/gas.exp: Run it.
+
+Thu Feb 13 14:44:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips16.d: Correct PC relative instruction bytes.
+
+Wed Feb 12 12:33:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/lif-svr4pic.d: Pass -EB when running the assembler.
+ * gas/mips/lif-xgot.d: Likewise.
+ * gas/mips/ulh-svr4pic.d: Likewise.
+ * gas/mips/ulh-xgot.d: Likewise.
+
+ * gas/mips/mips16.d: Update for yet another change in disassembly
+ output (this one is spacing only).
+
+Tue Feb 11 14:45:39 1997 Fred Fish <fnf@cygnus.com>
+
+ * gas/tic80/{add.d, add.lst, add.s, bitnum.d, bitnum.lst, bitnum.s,
+ ccode.d, ccode.lst, ccode.s, cregops.d, cregops.lst, cregops.s,
+ endmask.d, endmask.lst, endmask.s, regops.d, regops.lst, regops.s,
+ tic80.exp}: New files for TIc80 test cases.
+
+Tue Feb 11 15:46:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips16.d: Update for change in disassembly output.
+
+Mon Feb 10 22:24:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * gas/mips/itbl-test.c: Add copyright message and fix indentation.
+
+Mon Feb 10 17:54:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * gas/mips/itbl-test.c: New file. Stand-alone assembler and
+ dissassembler for itbl support.
+
+Mon Feb 10 17:20:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * gas/mips/itbl: New file. Instruction Spec for testing --itbl
+ option.
+ * gas/mips/itbl.s: New file. Assembly with ne2w instructions
+ specified in itbl.
+
+Fri Feb 7 16:42:53 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * gasp/gasp.exp: Use prune_warnings instead of prune_system_crud.
+ * lib/gas-defs.exp: Ditto.
+
+Mon Feb 3 15:46:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/arm/inst.d, gas/arm/arm7t.d: Pass --prefix-addresses to
+ objdump. Update for current relocation printing style.
+
+Thu Jan 30 11:57:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips16.d: Update for disassembler changes.
+
+Thu Jan 23 03:15:06 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * gas/mips/mips.exp: set ilocks for all 4100/4300
+
+Thu Jan 2 16:49:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips16.s, gas/mips/mips16.d: New test.
+ * gas/mips/mips.exp: Run mips16 test.
+
+ * gas/mips/mips.exp: Run dli test unconditionally.
+ * gas/mips/dli.s: Add text symbol. Add nops to round to 16 byte
+ boundary.
+ * gas/mips/dli.d: Corresponding changes.
+
+Tue Dec 31 13:03:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/sparc/synth.d: Use --prefix-addresses for objdump.
+ * gas/sparc/synth64.d: Likewise.
+
+Tue Dec 24 16:30:58 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * gas/mips/*-ilocks.d: Fix regexps to resemble disassembled output.
+
+Fri Dec 13 13:05:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/*.[sd]: Add explicit nops, sometimes controlled by
+ .ifdef, to accomodate change to avoid default alignment on
+ embedded systems.
+
+Wed Dec 11 09:26:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10200/basic.exp (do_movb): Fix bit pattern for
+ "movb dm,(an)".
+
+Tue Dec 10 13:01:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/basic.exp: Update after endianness changes to
+ the assembler.
+
+ * gas/mn10200/{mov1.s,mov2.s,mov3.s,mov4.s,movx.s}: New tests.
+ * gas/mn10200/{movb.s, movbu.s}: Likewise.
+ * gas/mn10200/basic.exp: Run them.
+
+Mon Dec 9 17:08:38 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10200/*.s: New tests for the mn10200 assembler.
+ * gas/mn10200/basic.exp: Run them.
+
+Fri Dec 6 15:35:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/*.s: Remove '$' register prefixing.
+
+Mon Nov 25 16:35:33 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc-solaris/addend.exp: Fix patterns, you can't assume
+ \r will be present.
+
+Mon Nov 25 13:45:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/*.d: Update for disassembler changes.
+ * gas/mri/*.d: Likewise.
+
+Mon Nov 25 11:38:37 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/*.s: Use '$' as register prefix for
+ all register operands.
+
+Thu Nov 21 11:52:54 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/all/gas.exp: xfail a couple tests for the mn10300.
+
+Wed Nov 20 11:31:41 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/other.s: Update for correct syntax on a
+ few instructions (those with register lists).
+ * gas/mn10300/basic.exp: Corresponding changes.
+
+Tue Nov 19 13:36:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/movm.s: Update for correct syntax.
+ * gas/mn10300/basic.exp: Update expected movm bit patterns.
+
+Fri Nov 15 13:57:42 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/other.s: Put parens around register
+ argument in calls and jmp instructions.
+
+Wed Nov 13 13:16:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/h8300/ffxx1.d: Update for recent disassembler changes.
+
+Mon Nov 11 16:03:24 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/reloc/reloc.exp: Pass "--prefix-addresses" to objdump
+ as needed.
+ * gas/hppa/unsorted/unsorted.exp: Likewise.
+
+Thu Nov 7 00:27:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/basic.exp: Check opcode insertion for
+ extended instructions.
+ * gas/mn10300/extend.s: Tweak constants for better
+ testsuite coverage.
+
+Wed Nov 6 13:50:07 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/basic.exp: Test insertion of operands
+ into call and jmp instructions with 32bit offsets.
+ Fix typo in bit test patterns.
+ * gas/mn10300/other.s: Tweak constants to improve
+ testsuite coverage.
+
+ * gas/mn10300/basic.exp: Test insertion of 32bit operand
+ in calls, btst, bclr & bset instructions.
+
+ * gas/mn10300/*.s: Tweak constants in 32bit insns for
+ better testing coverage.
+ * gas/mn10300/basic.exp: Test insertion of most 32bit
+ operands.
+
+Tue Nov 5 13:33:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/basic.exp: Check bit patterns for indexed mov,
+ movbu, movhu instructions. Check bit patterns for more bit
+ operations. Check bit patterns for various 16bit call, retf
+ and ret instructions.
+ * gas/mn10300/other.s: Update operands for better test coverage.
+
+Mon Nov 4 12:55:11 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/basic.exp: Check bit patterns for a couple more
+ mov and cmp instructions.
+
+Tue Oct 29 17:05:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/*.d: Update for disassembler changes.
+
+Wed Oct 16 22:39:50 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/v850/reloc.s: New tests.
+ * gas/v850/basic.exp: Run them.
+
+Mon Oct 14 13:52:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips: Add symbols to several testsuites, since the ELF
+ assembler now always builds a symbol table, which means that
+ objdump will no longer report `No symbols in FILE'. Change the
+ expected output accordingly.
+
+Thu Oct 10 13:11:48 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/basic.exp: Check bit patterns for instructions
+ with a single 8bit or 16bit immediate operand.
+
+ * gas/mn10300/basic.exp: Check bit patterns for many
+ instructions. Add missing test in do_mov1.
+ * gas/mn10300/mov1.s: Add missing test.
+
+Wed Oct 9 14:15:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10300/{add.s, bcc.s, bit.s, cmp.s, ext.s}: New tests.
+ * gas/mn10300/{extend.s logical.s, loop.s, mov1.s}: Likewise.
+ * gas/mn10300/{mov2.s, mov3.s, mov4.s, movbu.s}: Likewise.
+ * gas/mn10300/{movhu.s, movm.s, muldiv.s, other.s}: Likewise.
+ * gas/mn10300/{shift.s, sub.s}: Likewise.
+ * gas/mn10300/basic.exp: Run them.
+
+Thu Oct 3 09:57:03 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/mn10200, gas/mn10300: New directories for Matsushita
+ mn10200 and mn10300 tests.
+
+Tue Oct 1 15:38:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/gas-defs.exp (gas_version): Fix for current version
+ printing.
+
+Sun Sep 29 07:55:58 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/splet.d: Fix typo in cpusha result.
+
+Mon Sep 23 12:33:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/fmoveml.s, gas/m68k/fmoveml.d: Add tests for fmovemx.
+
+Wed Sep 18 12:14:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/cofftag.s: Use .p2align rather than .align.
+
+Fri Sep 13 15:28:04 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/h8300/macs.s: Add "stmac" instructions.
+ * gas/h8300/basic.exp: Test them.
+
+Thu Sep 12 10:28:44 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/arm/thumb.s (back): Check assembly of Thumb BL.
+
+Mon Sep 9 14:37:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips4.s, gas/mips/mips4.d: Use $fccN for condition code
+ registers.
+
+Fri Sep 6 18:23:54 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/mips/dli.{s,d}: More test cases added.
+
+Wed Sep 4 11:47:29 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/mips/mips.exp: Add check for dli macro instruction.
+ * gas/mips/dli.{s,d}: Added.
+
+Sat Aug 31 01:25:03 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/v850/basic.exp (do_mem): Check bit patterns for short
+ load/store instructions. Remove xfails for short load/store
+ instructions.
+ * gas/v850/mem.s: Offsets for short load/store operands
+ are unsigned.
+
+ * gas/v850/basic.exp (do_branch): Check offsets in branch insns.
+ (do_jumps): Likewise.
+
+Fri Aug 30 00:37:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/v850/misc.s: Tweak register numbers for better testing.
+ * gas/v850/basic.exp (do_misc): Corresponding changes.
+
+ * gas/v850/hilo.s: New testfile.
+ * gas/v850/basic.exp: Run hilo tests.
+
+Thu Aug 29 11:32:23 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/arm/arm7t.d: Explicitly force little-endian assembly.
+
+Fri Aug 23 11:02:55 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/v850/basic.exp (do_move): Test instruction bit patterns.
+ * gas/v850/move.s: Tweak constants for better testing.
+
+ * gas/v850/basic.exp (do_mem): Test instruction bit patterns.
+ xfail sst and sld tests.
+ (do_mov): Remove bogus xfail.
+ * gas/v850/mem.s: sst and sld instructions can only index from
+ "ep" register.
+
+ * gas/v850/basic.exp (do_logical): Test instruction bit patterns.
+ Update addresses.
+ * gas/v850/logical.s: Tweak constants for better testing.
+
+ * gas/v850/basic.exp (do_jump): Test instruction bit patterns,
+ but not displacements (yet).
+
+ * gas/v850/basic.exp (do_compare): Test instruction bit patterns.
+
+ * gas/v850/basic.exp (do_branch): Test instruction bit patterns,
+ but not displacements (yet).
+
+ * gas/v850/basic.exp (do_bit): Test instruction bit patterns.
+
+ * gas/v850/basic.exp (do_arith): Test instruction bit patterns.
+ * gas/v850/arith.s: Tweak constants for better testing.
+
+ * gas/v850/basic.exp (do_misc): No longer expect failures
+ assembling "ldsr" and "stsr" opcodes.
+ * gas/v850/misc.s: Re-enable assembling of "ldsr" and "stsr"
+ opcodes.
+
+ * gas/v850/basic.exp (do_misc): No longer expect failures
+ assembling "trap" opcodes.
+ * gas/v850/misc.s: Re-enable assembling of "trap" opcodes.
+
+ * gas/v850: New directory with v850 tests.
+
+Fri Aug 16 00:19:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/basic/purge.s: Use "%sr4" on pitlb, pitlbe
+ fic and fice instructions to test 3bit space identifiers.
+ * gas/hppa/basic/system.s: Similarly for iitlba and
+ iitlbp.
+ * gas/hppa/basic/basic.exp: Corresponding changes.
+
+Thu Aug 15 16:25:05 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/arm/arm.exp: Change inst.s test to check objdump.
+ * gas/arm/inst.d: Added.
+
+Thu Aug 15 16:06:02 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/arm/thumb.s: Added.
+ * gas/arm/immed.s: Added.
+ * gas/arm/arch4t.s: Added.
+ * gas/arm/arm.exp: Updated to run the new tests.
+
+Tue Aug 6 11:06:29 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/h8300/misch.s: Reenable "eepmov.w" test.
+ * gas/h8300/miscs.s: Likewise.
+ * gas/h8300/h8300.exp: Check for correct assembly of "eepmov.w"
+ on the H8/300H and H8/S. Don't expect it to fail.
+
+Wed Jul 31 10:57:44 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/asi.s: Update ASI_AS_IF_USER_{PRIMARY,SECONDARY}_LITTLE.
+
+Wed Jul 31 15:55:12 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/arm/arm7t.s: Added.
+ * gas/arm/arm7t.d: Added.
+ * gas/arm/arm.exp: Updated to run the new test.
+
+Mon Jul 8 14:27:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/pcrel.d: Rename from schwab.d.
+ * gas/m68k/pcrel.s: Rename from schwab.s.
+
+Mon Jul 8 14:23:26 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * gas/m68k/schwab.d: Correct for ELF format.
+ * gas/m68k/all.exp: Run "schwab" test for all targets.
+
+Thu Jul 4 14:23:36 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Avoid DOS file naming problems:
+ * gas/h8300/branch.s: Rename from branches.s.
+ * gas/h8300/branchh.s: Rename from branchesh.s.
+ * gas/h8300/branchs.s: Rename from branchess.s.
+ * gas/h8300/rotsh.s: Rename from rotshift.s.
+ * gas/h8300/rotshh.s: Rename from rotshifth.s.
+ * gas/h8300/rotshs.s: Rename from rotshifts.s.
+ * gas/h8300/h8300.exp: Corresponding changes.
+
+Thu Jul 4 14:01:46 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gas/mips/mips.exp: Add new tests for processors with interlocks
+ on div and mul.
+ * gas/mips/div-ilocks.d: Added.
+ * gas/mips/mul-ilocks.d: Added.
+
+Wed Jul 3 14:20:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/gas.exp: Remove setup_xfail for h8300*-*-* for two tests
+ which now pass.
+ * gas/h8300/h8300.exp: Fix regexp of mov32bug test to work on a 64
+ bit host.
+
+Sat Jun 29 18:21:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/gas.exp: Add setup_xfail for vax*-*-vms* for 930509a
+ test.
+ * gas/vax/quad.exp: Expect a nop after the movq.
+
+Tue Jun 18 12:39:49 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * gas/h8300/cbranchh.s: Switch into h8300h mode.
+ * gas/h8300/h8300.exp (H8/300H misc tests): Fix test names.
+
+ * gas/h8300/{addsubs.s,bitops1s.s,bitops2s.s}: New tests for the
+ H8/S.
+ * gas/h8300/{bitops3.s,bitops4.s,cbranchs.s,logicals.s}: Likewise.
+ * gas/h8300/{branchess.s,compares.s,macs.s,decimals.s}: Likewise.
+ * gas/h8300/{incdecs.s,divmuls.s,miscs.s,multiples.s}: Likewise.
+ * gas/h8300/{movbs.s,movws.s,movls.s,pushpops.s}: Likewise.
+ * gas/h8300/{rotshifts.s,extends.s}: Likewise.
+ * gas/h8300/h8300.exp: Run them.
+
+Mon Jun 10 14:14:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/cofftag.s, gas/all/cofftag.d: New test for COFF enum tag
+ with the same name as a global variable.
+ * gas/all/gas.exp: Run cofftag test for any COFF target.
+
+Thu Jun 6 12:30:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/all.exp: Pass -m68020 when assembling the disperr.s
+ test.
+
+Fri May 31 10:11:13 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/h8300/h8300.exp: Fix add.l test for H8/300H.
+
+Wed May 29 16:35:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/jal-xgot.d: Correct for 64 bit output.
+
+Thu Apr 25 19:31:59 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/sparc.exp: Only run sparclet tests if sparclet.
+
+Wed Apr 24 17:06:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/op68000.d: Add statements now caught by gas.
+
+Mon Apr 22 16:45:12 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/splet.[ds]: New tests for sparclet extensions.
+ * gas/sparc/sparc.exp: Run them.
+
+Mon Apr 15 17:25:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/la.d: Updated for April 5 MIPS assembler changes.
+ * gas/mips/lb.d, gas/mips/ld.d, gas/mips/sb.d: Likewise.
+ * gas/mips/uld.d, gas/mips/ulh.d, gas/mips/ulw.d: Likewise.
+ * gas/mips/usd.d, gas/mips/ush.d, gas/mips/usw.d: Likewise.
+
+Wed Apr 10 14:27:51 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/h8300/mov32bug.s: New test.
+ * gas/h8300/h8300.exp: Run it.
+
+Fri Apr 5 10:13:28 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/h8300/{addsubh.s,bitops1h.s,bitops2h.s}: New h8300h tests.
+ * gas/h8300/{bitops3h.s,bitops4h.s,branchesh.s}: New h8300h tests.
+ * gas/h8300/{cbranchh.s,compareh.s,decimalh.s}: New h8300h tests.
+ * gas/h8300/{divmulh.s,incdech.s,logicalh.s}: New h8300h tests.
+ * gas/h8300/{misch.s,movbh.s,movwh.s}: New h8300h tests.
+ * gas/h8300/{pushpoph.s,rotshifth.s}: New h8300h tests.
+ * gas/h8300/h8300.exp: Run them.
+
+ * gas/h8300/{movb.s,movw.s}: Correct predecrement syntax.
+
+ * gas/h8300/h8300.exp: Fix typos in bitops4 and movb tests.
+
+ * gas/h8300/{addsub.s,bitops1.s,bitops2.s}: New h8300 tests.
+ * gas/h8300/{bitops3.s,bitops4.s,branches.s}: New h8300 tests.
+ * gas/h8300/{cbranch.s,compare.s,decimal.s}: New h8300 tests.
+ * gas/h8300/{divmul.s,incdec.s,logical.s}: New h8300 tests.
+ * gas/h8300/{misc.s,movb.s,movw.s}: New h8300 tests.
+ * gas/h8300/{pushpop.s,rotshift.s}: New h8300 tests.
+ * gas/h8300/h8300.exp: Run them.
+
+Fri Mar 15 17:16:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/sparc/synth.d: Don't require sparc in the file format, since
+ it won't be there on SunOS.
+
+Thu Mar 7 14:51:23 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * gas/sparc/synth.[ds]: New testcase.
+ * gas/sparc/sparc.exp: Run it.
+
+Fri Mar 1 12:01:48 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/all/gas.exp: xfail difference of two undefined symbols
+ and difference of forward references for the h8300.
+
+Thu Feb 22 16:40:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/lb-xgot.d: Correct.
+
+Mon Feb 19 02:43:36 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * gas/sparc/{asi,membar,prefetch,rdpr,synth64,wrpr}.d: Pass -Av9
+ to gas.
+ * gas/sparc/addend.exp: Execute for any sparc cpu.
+ * gas/sparc/{mismatch.exp,mism-1.s}: New test.
+
+Wed Feb 14 13:49:59 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/jal-xgot.d, gas/mips/la-xgot.d: New tests.
+ * gas/mips/lb-xgot.d, gas/mips/ld-xgot.d: New tests.
+ * gas/mips/lif-xgot.d, gas/mips/ulh-xgot.d: New tests.
+ * gas/mips/mips.exp: Run new tests if svr4pic.
+
+Sat Jan 27 13:27:45 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * lib/gas-dg.exp (gas-dg-test): Delete default_flags and libs args.
+
+Fri Jan 26 14:24:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/unsorted/unsorted.exp: Update for objdump changes.
+
+Wed Jan 10 12:40:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/*.d: Update for changes to disassembler.
+
+Wed Jan 3 22:59:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/ulh-svr4pic.d: Update for tc-mips.c load_address
+ change.
+
+Fri Nov 17 10:32:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/immconst.d: New test.
+ * gas/mri/mri.exp: Run it.
+ * gas/mri/constants.s: Test immediate constants.
+ * gas/mri/constants.d: Corresponding change.
+
+ * gas/m68k/link.s: Add nop to pad to eight byte boundary.
+ * gas/m68k/link.d: Corresponding change.
+
+Sun Nov 12 21:28:11 1995 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/unsorted/brlenbug.s: New test.
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+Sun Nov 5 12:49:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/beq.s: Declare text_label global.
+ * gas/mips/jal.s: Likewise.
+
+Fri Nov 3 12:35:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/link.s: Use "&" instead of "#" for immediate values.
+
+ * gas/m68k/fmoveml.s, gas/m68k/fmoveml.d: New test.
+ * gas/m68k/all.exp: Run it.
+
+Thu Nov 2 23:11:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/m68k/link.s, gas/m68k/link.d: New test.
+ * gas/m68k/all.exp: Run it.
+
+Tue Oct 24 10:57:20 1995 Jeffrey A Law (law@cygnus.com)
+
+ * gas/hppa/basic/basic.exp: Test lci and syncdma instructions.
+ * gas/hppa/basic/system.s: Corresponding changes.
+
+Fri Oct 6 17:13:35 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * gas/m68k/operands.d: Don't require a fixed number of leading
+ zeros in any number.
+
+ * gas/m68k/operands.s, gas/m68k/bitfield.s: Use "&" instead of "#"
+ for immediate values.
+
+Fri Oct 6 10:54:13 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/arm/arm.exp: Renamed from gas.exp.
+ * gas/arm/le-fpconst.[sd]: New testcase.
+
+Fri Sep 29 15:12:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/mri.exp: Only run tests for m68k target.
+
+Mon Sep 25 12:31:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/mri.exp: Add setup_xfail for arm*-*-* for constants
+ test.
+
+Thu Sep 21 01:26:08 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/sh/fp.s (fmac): Update for new assembly syntax.
+
+Mon Sep 18 14:04:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/gas-defs.exp (gas_run): Call prune_system_crud.
+ (run_dump_test, objdump): Likewise.
+
+Thu Sep 14 13:10:10 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/{wrdr.[ds],rdpr.[ds]}: New tests.
+ * gas/sparc/sparc.exp: Run them.
+
+Wed Sep 13 16:35:51 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in, configure.in: Remove; the testsuite is now run
+ directly from the gas Makefile.
+
+Mon Sep 11 11:44:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/empty.s: New file.
+ * gas/mri/mri.exp: Test assembling empty.s.
+ * gas/mri/comment.s: Add a couple more comment variants.
+
+ * gas/mri/mri.exp: Add xfail for the expr test for all hppa
+ targets.
+
+Wed Sep 6 21:39:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/comment.s, gas/mri/comment.d: New test.
+ * gas/mri/mri.exp: Run it.
+ * gas/mri/expr.s: Remove whitespace in operand field.
+ * gas/mri/for.s: Add comments for further testing.
+ * gas/macros/test2.s: Put in an upper case ELSE to test case
+ insensitivity.
+
+Wed Aug 30 16:12:03 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/{prefetch.[ds],synth64.[ds]}: New tests.
+
+Tue Aug 29 18:59:33 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * gas/sparc/sparc.exp: New file.
+ * gas/sparc/{asi.[ds],membar.[ds]}: New tests.
+
+Mon Aug 21 14:39:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/macros/*: New tests for macros.
+
+ * gas/mri/common.s: Use data, not .data.
+
+ * gasp/pl3.out: Update for changes in commented source output when
+ LOCAL is used.
+
+Sat Aug 19 17:36:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp/gasp.exp (gasp_test): Call prune_system_crud on the output
+ of diff.
+ * lib/gas-defs.exp: Define prune_system_crud if it is not already
+ defined.
+
+Fri Aug 18 11:09:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gasp/mri/*.out: Use ;, not !, for the comment character.
+
+Wed Aug 16 12:24:12 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/mri.exp: Change hppa*-*-* expected failures to only
+ expect failure for targets which use SOM.
+
+ * lib/gas-defs.exp (run_dump_test): If the program to run does not
+ exist, mark the test as untested.
+
+ * gas/mri/mri.exp: Add setup_xfail for i960 b.out targets for
+ common test.
+
+ * lib/gas-defs.exp (run_dump_test): Name the output file dump.o,
+ rather than using an implicit a.out.
+
+ * gas/mri/for.s: Add nop to round out to four byte boundary.
+ * gas/mri/repeat.s: Likewise.
+ * gas/mri/while.s: Likewise.
+ * gas/mri/for.d: Expected added nop.
+ * gas/mri/repeat.d: Likewise.
+ * gas/mri/while.d: Likewise.
+
+ * gas/mips/*.d: Change all test names to say MIPS.
+
+Tue Aug 15 15:42:33 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/for.d, gas/mri/for.s: New test.
+ * gas/mri/if.d, gas/mri/if.s: New test.
+ * gas/mri/repeat.d, gas/mri/repeat.s: New test.
+ * gas/mri/while.d, gas/mri/while.s: New test.
+ * gas/mri/mri.exp: Run the new tests.
+
+Mon Aug 14 16:03:07 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/expr.d: Permit leading zeroes, in case we're using a
+ 64-bit BFD.
+
+ * gasp/mri/*: New tests.
+ * gasp/gasp.exp: Run them. Also, clean up the test names used in
+ pass and fail.
+
+Sun Aug 13 00:39:24 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/sh/basic.exp: Update now that we know the right
+ bit patters for the new sts instructions.
+
+Thu Aug 10 00:46:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/char.d: Fix for little endian machines.
+ * gas/mri/float.d: Likewise.
+
+Wed Aug 9 15:34:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/all/struct.s, gas/all/struct.d: New test.
+ * gas/all/gas.exp: Run it.
+
+Tue Aug 8 17:11:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/common.s, gas/mri/common.d: New test.
+ * gas/mri/mri.exp: Run it.
+
+Mon Aug 7 22:39:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/mri.exp: Add setup_xfail for a29k*-*-* for constants
+ test.
+
+ * gasp/crash1.out, gasp/macro.out, gasp/sfunc.out: Complete
+ truncated files, so that the tests pass.
+
+ * gas/mri/mri.exp: Add setup_xfail for hppa*-*-* for equ,
+ constants, and expr.
+
+ * gas/m68k/all.exp: Run schwab test on hpux*, not just hpux. Run
+ on vxworks*, not just vxworks5.1.
+
+ * lib/gas-defs.exp (fail_phase, pass_phase): Remove.
+ (run_dump_test): Just call pass or fail.
+
+ * gas/m68k/operands.s, gas/m68k/operands.d: New test.
+ * gas/m68k/op68000.d: New test.
+ * gas/m68k/cas.s, gas/m68k/cas.d: New test.
+ * gas/m68k/bitfield.s, gas/m68k/bitfield.d: New test.
+ * gas/m68k/schwab.d: Run objdump with -j .text. Adjust for
+ changes to disassembler.
+ * gas/m68k/all.exp: Run new tests. Run schwab test for
+ m68k-*-coff*.
+
+Mon Aug 7 03:01:32 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/sh/*: New tests for the hitachi-sh.
+
+Tue Aug 1 18:02:47 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mri/*: New tests for MRI mode.
+
+ * lib/gas-defs.exp (run_dump_test): Support using objcopy. Dump
+ program executions to the log file before running them. Use the
+ simple program name, rather than the path to the binary being run,
+ in pass/fail messages.
+ (regexp_diff): If the regexp file has the special comment #pass,
+ stop checking at that point.
+ * config/default.exp: Set NM, NMFLAGS, OBJCOPY, and OBJCOPYFLAGS,
+ if they are not already set.
+
+Tue Aug 1 11:41:30 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * Makefile.in: Remove superfluous runtest gasp.
+
+Mon Jul 31 18:19:26 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * gasp/*: New.
+ * Makefile.in: Use gasp tests.
+ * config/default.exp: Add gasp stuff.
+
+Thu Jul 20 18:56:48 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/all/gas.exp: Disable tests that are not appropriate for
+ the PA.
+
+Thu Jul 13 18:22:49 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * gas/m68k/all.exp: Run schwab test for m68k vxworks5.1.
+
+Wed Jun 21 21:28:57 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/m68k/schwab.*: New test based on a test case from Andreas
+ Schwab.
+ * gas/m68k/all.exp: Run it for some aout configurations.
+
+Mon Jun 12 22:27:18 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/parse/badfmpyadd.s: New test.
+ * gas/hppa/parse/parse.exp: Run it.
+
+Sun May 21 20:26:18 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/unsorted.exp: Disable align4 tests for
+ ELF targets.
+
+Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * arm/arm7dm.s: New file -- tests for ARM7DM instructions.
+ * arm/arm6.s: Correct bogus tests.
+ * arm/gas.exp (arm6.s): Is now a valid test.
+ (arm7dm.s): New test.
+ * arm/float.s: Add load/store multiple floating point instruction
+ tests.
+
+Wed May 3 13:14:44 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/longcall.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+Tue May 2 16:37:48 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/mips/ld.d: Modified for gas delay-slot fixes.
+
+Sat Apr 29 23:35:18 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * lib/gas-dg.exp: New file.
+
+Tue Apr 11 13:57:52 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/mips/mips4.d: Allow more than exactly 8 zeros in bc1*
+ targets.
+
+Mon Apr 10 15:36:39 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * lib/gas-defs.exp (pass_phase): New proc.
+ (run_dump_test): Note passing or failing of each phase of this
+ test, instead of failure of phases or passing of complete test.
+ Ensure test file name is in reported message.
+
+Sat Apr 8 12:46:33 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * lib/gas-defs.exp (run_dump_test): Handle arguments with paths.
+ Always resolve testcase status before returning.
+ If `slurp_options' fails, return and don't do test.
+ (slurp_options): Fix "can't open" error message.
+ Return -1 to indicate error.
+
+Mon Mar 20 22:45:30 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/common.s: New test.
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+Fri Mar 10 19:07:09 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/h8300/ffxx1.s: Add .word 0 at the end to eliminate
+ uncertainty as to whether there should be trailing bytes in the
+ output file.
+ * gas/h8300/ffxx1.d: Adjust reloc values to permit an addend value
+ of 0x00000000ffffffff on 64-bit hosts. (I'm not sure if this is
+ correct.) End with "..." to match trailing zero bytes.
+
+Wed Mar 8 15:50:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/mips4.d, gas/mips/mips4.s: New files.
+ * gas/mips/mips.exp: Run new test.
+
+Thu Feb 23 17:58:50 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/basic/fmemLRbug.s: Add indexing variants.
+ * gas/hppa/basic/basic.exp: Test them.
+
+Wed Feb 15 15:43:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gas/mips/uld.d: New file.
+ * gas/mips/uld.s: New file.
+ * gas/mips/usd.d: New file.
+ * gas/mips/usd.s: New file.
+ * gas/mips/mips.exp: Run new tests.
+
+Thu Feb 9 10:57:39 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/applybug.s: New test.
+ * gas/hppa/reloc/reloc.exp (do_applybug_test): Run it.
+
+Thu Feb 2 00:34:55 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/picreloc.s: New test.
+ * gas/hppa/reloc/reloc.exp (do_pic_relocation_test): Run it.
+
+Fri Jan 27 14:02:02 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/h8300/ffxx1.d, gas/h8300/ffxx1.s, gas/h8300/cmpsi2.s,
+ gas/h8300/h8300.exp: New tests.
+
+Mon Jan 23 21:44:26 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/basic/basic.exp (do_system): Update.
+
+Wed Jan 11 17:20:25 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/mips/mips.exp: Don't run the memory-access tests if the
+ format is a.out, because the generated code is different from what
+ is used with other formats.
+
+Tue Jan 10 11:42:13 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/unsorted.exp (align4.s): Fix glitch in
+ regexp to avoid losing without a controlling tty.
+
+Fri Dec 30 18:08:20 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/i386/pushw.l: Fixed whitespace to match current listing
+ style.
+
+ * gas/all/gas.exp: Mark test p1480.s expected to pass, even with
+ listings enabled.
+
+Thu Dec 15 18:14:27 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (AS_FOR_TARGET, OBJDUMP_FOR_TARGET): Don't set.
+ (uninstall): Don't set OBJDUMP and OBJDUMPFLAGS in site.exp.
+ * config/default.exp: Default OBJDUMP and OBJDUMPFLAGS. Use
+ findfile and transform procedures to determine objdump program
+ name.
+
+ * gas/mips/abs.s, gas/mips/div.s: Force some padding at the end,
+ in case the format doesn't automatically require it.
+ * gas/mips/beq.d, gas/mips/jal.d: Handle MIPS_JMP as an alternate
+ name for the reloc type.
+
+ * lib/gas-defs.exp (file_contents, verbose_eval): New procs.
+ (run_dump_test): If verbosity level is over 3, print out dump
+ command and its output.
+
+Tue Dec 13 18:21:09 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * gas/mips/jal-svr4pic.d: Fix 0-strings to work with 64-bit hosted
+ disassembly.
+
+Fri Dec 9 19:54:04 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/all/gas.exp (comment.s test): Make the "\r" optional, since
+ it depends on tty modes.
+
+ * lib/gas-defs.exp (gas_start): Try using -nottycopy instead of
+ -nottyinit.
+
+ * gas/arm/gas.exp: The arm6 test should report errors, for now.
+
+Thu Dec 8 20:19:09 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * lib/gas-defs.exp: Use -i in expect_after command.
+
+Wed Dec 7 16:49:14 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/mips/mul.d,jal.d: Fix 0-strings to work with 64-bit hosted
+ disassembly.
+
+ * gas/ieee-fp: Renamed from ieee.fp.
+
+ * lib/gas-defs.exp: Make sure timeout is at least 2 minutes.
+
+Wed Nov 30 10:48:00 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/parse: Renamed from gas/hppa/more.parse.
+
+Mon Nov 28 00:40:26 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/parse.exp (nosubspace.s): No longer expected
+ to fail. Fix comments for the test. Tweak test name.
+
+Tue Nov 22 23:38:20 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: Minor tweaks to match current PA ELF
+ output.
+
+Fri Nov 18 17:56:57 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * gas/mips/ld.d: Adjust to work for both big and little endian
+ code.
+ * gas/mips/ld.s, gas/mips/lif-empic.d: Likewise.
+ * gas/mips/lifloat.d, gas/mips/ulh-empic.d: Likewise.
+ * gas/mips/ulh.d, gas/mips/ulw.d, gas/mips/ush.d: Likewise.
+ * gas/mips/usw.d: Likewise.
+
+Tue Nov 15 11:09:57 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/align4.s: New test.
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+ * gas/hppa/unsorted/unsorted.exp (importbug): Tweak to match
+ current expected PA ELF output.
+ * gas/hppa/reloc/reloc.exp (do_r_no_reloc): Likewise.
+ (do_plabel_relocation_test): Likewise.
+
+Thu Nov 3 18:14:09 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * gas/all/p1480.s: Use larger constant, so expression can have a
+ positive value.
+ * gas/all/gas.exp: Expect p1480.s without listings to pass.
+
+Thu Nov 3 15:43:46 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * gas/mips/ulh.d, gas/mips/ulw.d, gas/mips/ush.d, gas/mips/usw.d:
+ Correct test cases.
+
+Thu Oct 20 00:55:13 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/blebug3.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+Mon Oct 17 02:33:53 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reduce3.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+Sun Oct 16 22:25:56 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp (r_no_reloc): Tweak output to match
+ current reality.
+
+Wed Sep 28 21:21:34 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reduce.s: Renamed from relocreduce.s
+ * gas/hppa/reloc/reduce2.s: Renamed from relocreduce2.s
+ * gas/hppa/reloc/r_no_reloc.s: Renamed from r_no_relocbug.s
+ * gas/hppa/reloc/reloc.exp: Changed accordingly.
+
+Wed Sep 28 13:25:10 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * gas/mips/beq.d, gas/mips/beq.s: Test that unconditional branch
+ overflows are correctly converted to jumps.
+
+Mon Sep 26 17:41:43 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * gas/mips: Add test cases for PIC code, both SVR4 style and
+ -membedded-pic style.
+
+Fri Sep 23 14:45:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * gas/mips: New directory with MIPS specific test cases.
+
+ * lib/gas-defs.exp (run_dump_test): Permit the .d file to specify
+ the name of the source file to assemble.
+ (regexp_diff): Put the reason for failure in the log file.
+
+Wed Sep 21 13:44:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * lib/gas-defs.exp: Don't try to use shell redirection, since TCL
+ doesn't support it. Redirect stdout using > instead of 1>, and
+ don't bother to redirect stderr since TCL redirects it anyhow.
+ (run_dump_test): Pass appropriate arguments to program, defaulting
+ to -r.
+
+Sat Sep 17 01:04:56 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gas/vax: New directory.
+ * gas/vax/{quad.s,quad.exp}: New test, for immediate quadword
+ values.
+
+Mon Sep 12 22:19:11 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/r_no_relocbug.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+ * gas/hppa/reloc/reloc.exp (do_function_reloc_bug): Update
+ expected output.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * gas/arm/*: New subtree. Add ARM tests.
+
+Mon Aug 8 12:13:31 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/unsorted.exp: Accept any character
+ between foo's type and foo itself.
+
+Fri Jul 15 19:09:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * lib/gas-defs.exp (run_dump_test): New routine for running the
+ assembler, running objdump or nm (not fully supported) on the
+ resulting object file, and comparing the results against a file of
+ regular expressions in the test suite, all in one command.
+ Options for the assembler and objdump are read from comments at
+ the start of the .d file.
+ (fail_phase, slurp_options): New auxiliary routines.
+ (regexp_diff): Always return a value. Fix bugs in actually doing
+ the regexp test.
+
+ * gas/sun4/addend.exp: Use run_dump_test.
+ * gas/sun4/addend.d: Fix regular expressions so that they work.
+
+Thu Jul 7 11:55:33 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/relocreduce2.s: More relocation reduction tests.
+ * gas/hppa/reloc/reloc.exp: Run them.
+
+Thu Jun 30 18:49:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/default.exp: Look for "as.new" in "$base_dir/..", where
+ it got compiled, not in "$base_dir".
+ * config/unknown.exp: Deleted.
+
+Sun Jun 26 13:23:54 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/lib/gas-defs.exp (gas_finish): Call "close" and "wait"
+ before exiting. Enclose both calls inside a "catch".
+ (objdump_finish): Likewise.
+
+Fri Jun 10 10:23:35 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp (roundmode test): Tweak expected output
+ for SOM to match current testcase.
+
+Thu Jun 2 19:46:58 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gas/i386/{pushw.s,pushw.l}: New test.
+ * gas/i386/all.exp: Run it.
+
+ * Makefile.in (distclean): Remove site config files and gas.sum.
+
+Fri May 27 12:24:18 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gas/m68k/disperr.s: Use % for registers.
+
+ * gas/m68k-coff/gas.exp: Expect failure for p2389a.s.
+
+Tue May 17 14:53:08 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * lib/gas-defs.exp: Replace error proc calls with perror calls.
+
+Mon May 16 13:19:16 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: Tweak expected output to match new
+ ELF code.
+ * gas/hppa/reloc/roundmode.s: Avoid "S" and "D" modes, ELF does
+ not support them.
+ * gas/hppa/unsorted/unsorted.exp: Tweak expected output to match
+ new ELF code.
+
+Thu May 5 17:27:54 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * config/default.exp: Renamed from unix-gas.exp.
+
+Mon Apr 11 10:31:00 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in (check): Set TCL_LIBRARY for runtest.
+
+Mon Apr 11 07:54:10 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/callinfobug.s: Add missing name for
+ procedure.
+
+ * gas/hppa/reloc/funcrelocbug.s: Place the trampoline in the
+ $DATA$ rather than $LIT$ subspace.
+
+Sun Mar 27 14:05:33 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/funcrelocbug.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+Thu Mar 17 13:38:04 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/importbug.s: New test.
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+Wed Mar 16 11:57:07 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/regpopbug.s: Add trivial .equ test.
+
+ * gas/hppa/unsorted/globalbug.s: New test (expected to fail).
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+ * gas/hppa/more.parse/callinfobug.s: New test.
+ * gas/hppa/omre.parse/parse.exp: Run it.
+
+ * gas/hppa/more.parse/regpopbug.s: New test.
+ * gas/hppa/more.parse/parse.exp: Run it.
+
+Mon Feb 28 14:10:04 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * lib/gas-defs.exp (objdump): New proc.
+ (objdump_start): Deleted unused proc.
+ (objdump_start_common): Merged into objdump_start_no_subdir.
+
+ * gas/alpha/fp.exp: Use objdump instead of
+ objdump_start_no_subdir, since the former actually waits for
+ objdump to finish. Specify .rdata section only. Make comment
+ indicate Alpha architecture rather than SPARC.
+ * gas/alpha/fp.d: Omit .reginfo patterns. Just use "." to match
+ against ASCII code 0x2a ("*", special in regexp).
+ * gas/sun4/addend.exp: Use objdump instead of
+ objdump_start_no_subdir.
+
+Thu Feb 24 07:11:57 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/parse.exp (no subspace test): Only expect
+ a failure if gas is not producing an ELF object.
+
+Mon Feb 14 09:24:03 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/basic/fmemLRbug.s: New test.
+ * gas/hppa/basic/basic.exp: Run it.
+
+Thu Feb 10 00:34:26 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gas/alpha/fp.*: New files.
+ * lib/gas-defs.exp (regexp_diff): Report noted mismatch at
+ verbosity level 3 or above only.
+
+Mon Feb 7 15:53:10 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/*/*.exp: Change xfails to check for PA ELF rather than
+ PA OSF1.
+
+Fri Feb 4 23:42:14 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/xmpyubug.s: New test.
+ * gas/hppa/more.parse/parse.exp: Run it.
+
+Fri Feb 4 17:13:20 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * lib/gas-defs.exp (regexp_diff): New procedure, vaguely based on
+ "simple_diff" from linker test suite.
+ * gas/sun4/addend.exp: Use it.
+ * gas/sun4/addend.d: New file.
+
+Sun Jan 30 23:34:58 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * gas/all/gas.exp: Adjust regexp for x930509.s for current listing
+ format.
+
+Thu Jan 20 16:44:51 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * gas/all/gas.exp, lib/gas-defs.exp, sun4/addend.exp,
+ sparc-solaris/addend.exp: Tweaked to fix a few bugs and to run
+ well under either version of expect.
+
+Mon Jan 17 00:25:03 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/basic/fp_misc.s: Delete copr instruction. It's tested
+ elsewhere now.
+ * gas/hppa/basic/{copr, coprmem, spop}.s: New tests.
+ * gas/hppa/basic/basic.exp: Run them.
+
+Thu Jan 13 11:59:22 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/all/gas.exp: No longer expect difference of forward
+ references to fail.
+ * gas/all/x930509.s: Fix testcase to match how the expect code was
+ written.
+
+Wed Jan 12 13:41:10 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: Fix typo in last change. Latest test
+ for cross-subspace call bugs is no longer expected to fail.
+
+ * gas/hppa/more.parse/procbug.s: Add test for another bug relating
+ to having a function's label follow the .PROC directive.
+
+Tue Jan 11 21:47:48 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: Add test for cross-subspace call bug
+ found while working on multiple $CODE$ subspace support.
+
+Mon Jan 10 09:54:15 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/parse.exp: procbug.s is no longer expected
+ to fail.
+ * gas/hppa/more.parse/procbug.s: Add missing .procend.
+
+Mon Jan 3 10:07:47 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/labelbug.s: Add testcase for bug in last
+ app.c change.
+
+Wed Dec 29 11:32:39 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/labelbug.s: Add more colonless label tests.
+
+Wed Dec 15 08:24:31 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * Makefile.in (site.exp): Don't set ASFLAGS. Quote value of
+ OBJDUMPFLAGS in case it's empty. Use temporary names until the
+ end; make creating site.exp the final step.
+ (check): Pass in ASFLAGS.
+
+ * gas/all/gas.exp: Use all_ones proc. Change regexp for matching
+ C comments to avoid bugs in latest expect code.
+
+Wed Dec 8 14:30:14 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/m68k/disperr.s: New test.
+ * gas/m68k/all.exp: Run it.
+
+Sun Dec 5 19:24:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/roundmode.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it. Fix typo in last change.
+
+Wed Dec 1 10:44:18 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: Run the first half of bogus R_EXIT
+ test for ELF.
+
+Tue Nov 30 13:43:21 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/parse.exp: Test for error on for subspace
+ directive is an XFAIL for SOM assmeblers.
+
+ * gas/hppa/reloc/reloc.exp: Remove XFAIL for relocation on
+ cross-subspace call test.
+
+Sun Nov 28 12:12:50 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/appbug.s: New test.
+ * gas/hppa/more.parse/parse.exp: Run it.
+
+ * gas/hppa/unsorted/align3.s: New test.
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+Sat Nov 27 22:50:01 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/all/p2425.s: Insert a tab before assembler directives so
+ that the directives are not interpreted as labels.
+
+ * gas/hppa/basic/weird.s: Sync with GDB version.
+
+ * gas/hppa/more.parse/labelbug.s: New test.
+
+ * gas/hppa/more.parse/parse.exp: Run it.
+
+Wed Nov 24 01:25:03 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/fixupbug.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+ * gas/hppa/reloc/exitbug.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+Sun Nov 21 22:11:10 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: Minor fixes so that SOM & ELF can
+ share the same test code.
+ * gas/hppa/reloc/relocreduce.s: Likewise.
+
+ * gas/hppa/basic/fmem.s: Add quadword FP store instructions.
+ * gas/hppa/basic/basic.exp: Test quadword FP store instructions.
+
+Sun Nov 7 00:31:41 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp: No longer expect failure for
+ field selector on ble instruction test.
+
+ * gas/hppa/basic/basic.exp: No longer expect failures for
+ system instruction tests now that probei is fixed.
+
+Sat Nov 6 22:45:08 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/selectorbug.s: New test.
+ * gas/hppa/reloc/reloc.exp: Run it.
+
+Thu Nov 4 17:01:30 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/fragbug.s: New test.
+ * gas/hppa/unsorted/unsorted.exp: Run it.
+
+Thu Nov 04 09:09:49 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Changed RUNTESTFLAGS to RUNTEST_FLAGS
+
+Tue Nov 2 22:12:30 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/{defbug.s, stdreg.s}: New tests.
+ * gas/hppa/more.parse/parse.exp: Run them.
+
+Mon Nov 1 23:37:58 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/reloc/reloc.exp (reloc_reduce): Correct offsets at
+ which specific relocations are expected to be found.
+
+Sat Oct 30 14:12:31 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/unsorted/unsorted.exp (ss_align): Remove OSF xfail.
+
+ * gas/hppa/more.parse/parse.exp: Add new test.
+ * gas/hppa/more.parse/ssbug.s: New test to make sure non-default
+ sections are handled correctly.
+
+ * gas/all/gas.exp: Disable (and fail) p1480.s for all PA targets.
+
+Fri Oct 29 16:29:06 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/more.parse/calldatabug.s: Colonize.
+ * gas/hppa/more.parse/parse.exp: Fix typos.
+
+Thu Oct 28 21:40:06 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gas/hppa/{basic, more.parse, reloc, unsorted}: New directories.
+ * gas/hppa/*/*.exp: New test drivers.
+ * gas/hppa/*/*.s: New test files.
+
+Mon Oct 25 09:40:59 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * gas/sun4: New directory.
+ * gas/sun4/addend.s,addend.exp: New test case.
+ * gas/sparc-solaris/addend.s,addend.exp: Solaris version of same
+ test case.
+
+ * gas/all/gas.exp: Check `*' in C comments.
+
+ * lib/gas-defs.exp (all_ones): New procedure, for a predicate to
+ simplify some tests.
+ (want_no_output): Return zero or nonzero, depending on success or
+ failure.
+ (gas_test_old): Return value from want_no_output.
+ (objdump_start_common): Split off from objdump_start.
+ (objdump_start_no_subdir): New procedure.
+
+Wed Oct 20 07:25:48 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * gas/all/diff1.s, gas/m68k/pic1.s: New tests.
+ * gas/all/gas.exp, gas/m68k/all.exp: Run them.
+
+ * Makefile.in (OBJDUMP_FOR_TARGET): Define similar to
+ AS_FOR_TARGET.
+ (check): Don't pass ASFLAGS variable.
+ (site.exp): Put ASFLAGS, OBJDUMP, OBJDUMPFLAGS into site.exp.
+
+ From Jeff Law:
+
+ * lib/gas-defs.exp (objdump_start, objdump_finish): New functions
+ so that tests can parse the output of objdump looking for errors
+ in relocation entires, file headers and the like.
+
+Thu Sep 23 16:20:34 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * gas/ieee.fp/x930509a.exp: Currently expected to fail always.
+ * gas/all/gas.exp (p1480.s, x930509.s): Ditto. Break up gas_test
+ call so it no longer performs multiple tests.
+ * gas/m68k/all.exp (t2.s): Don't bother with listings.
+ (p2410.s): Don't pass unwanted arguments to gas_test_error.
+
+Wed Aug 25 16:50:08 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * lib/do*: Remove RCS id strings.
+
+Mon May 17 15:09:45 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * gas/all/float.s, gas/all/p1480.s, gas/m68k/p2410.s: New tests.
+ * gas/all/gas.exp, gas/m68k/all.exp: Run them.
+ * gas/i386: New directory.
+
+Mon May 10 14:50:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * Added directory structure, to categorize tests by targets.
+ * Added new tests all/x930509.s, ieee.fp/x930509a.s, m68k/p2663.s,
+ and refined some to examine the assembler listing output.
+ * lib/gas-defs.exp: Renamed gas_start to gas_run. Added some
+ expect_after patterns.
+ (gas_start, gas_finish): New procs, for tests that examine process
+ output.
+ * config/unix-gas.exp: Invoke gas_init directly, instead of
+ requiring test .exp files do it.
+
+Wed Apr 21 01:24:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * gas/gas.exp: Handle new tests, and changes to testing procs.
+
+ * lib/gas-defs.exp (want_no_output): New proc; success iff output
+ is empty.
+ (gas_test_old): Functionally same as old gas_test.
+ (gas_test_ignore_stdout): Rewritten to use want_no_output.
+ (gas_test): New argument lists set of options to be tried in
+ combinations. Option with trailing ">" indicates standard output
+ should be ignored.
+
+ * gas/p2425a.s: Use %-form for registers, so this test can be run
+ on m68k-coff targets too.
+
+ * gas/p2430a.s: New test case, whitespace &c matches customer
+ report more closely. Gets different results from p2430.s; this is
+ bad, and not yet tested for.
+
+Mon Apr 5 12:27:19 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * gas/p2389a.s, gas/p2411.s, gas/t2.s: New test cases.
+ * lib/run: New script.
+ * gas/gas-defs.exp (gas_start): Takes new args, assembler options
+ and redirection options. Use "run" script so redirection works.
+ (gas_test): Now takes assembler options as separate arg from input
+ file name.
+ (gas_test_ignore_stdout): New proc. Discards output.
+ (gas_test_error): New proc. Expects assembler to generate output.
+ (target_cpu_family setting): Handle i486->i386 also.
+
+ * lib/do*: Scripts moved here from gas/testscripts. May be useful
+ someday for writing more test cases; not currently used.
+
+Tue Mar 30 11:45:27 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * gas/sol-gcc.s, gas/sol-cc.s, gas/p2425a.s, gas/p2389.s: New test
+ cases.
+ * gas/gas.exp: Enable them for appropriate targets. Removed some
+ useless comments &c. Changed m68k target test to be more general.
+
+ * lib/gas-defs.exp (gas_exit, gas_init): New procs.
+ * gas/gas.exp: Call gas_init.
+
+Mon Mar 29 00:00:00 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * Test suite created.
+
diff --git a/gas/testsuite/config/default.exp b/gas/testsuite/config/default.exp
new file mode 100644
index 00000000000..4134a030306
--- /dev/null
+++ b/gas/testsuite/config/default.exp
@@ -0,0 +1,46 @@
+load_lib gas-defs.exp
+
+global AS
+if ![info exists AS] then {
+ set AS [findfile $base_dir/../as-new "../as-new" [transform as]]
+}
+
+global GASP
+if ![info exists GASP] then {
+ set GASP [findfile $base_dir/../gasp-new "../gasp-new" [transform gasp]]
+}
+
+global ASFLAGS
+if ![info exists ASFLAGS] then {
+ set ASFLAGS ""
+}
+
+if ![info exists OBJDUMP] then {
+ set OBJDUMP [findfile $base_dir/../../binutils/objdump \
+ $base_dir/../../binutils/objdump \
+ [transform objdump]]
+}
+
+if ![info exists OBJDUMPFLAGS] then {
+ set OBJDUMPFLAGS {}
+}
+
+if ![info exists NM] then {
+ set NM [findfile $base_dir/../../binutils/nm-new \
+ $base_dir/../../binutils/nm-new \
+ [transform nm]]
+}
+
+if ![info exists NMFLAGS] then {
+ set NMFLAGS {}
+}
+
+if ![info exists OBJCOPY] then {
+ set OBJCOPY [findfile $base_dir/../../binutils/objcopy]
+}
+
+if ![info exists OBJCOPYFLAGS] then {
+ set OBJCOPYFLAGS {}
+}
+
+gas_init
diff --git a/gas/testsuite/gas/all/align.d b/gas/testsuite/gas/all/align.d
new file mode 100644
index 00000000000..86ede6186a9
--- /dev/null
+++ b/gas/testsuite/gas/all/align.d
@@ -0,0 +1,12 @@
+#objdump: -s -j .text
+#name: align
+
+# Test the alignment pseudo-op.
+
+.*: .*
+
+Contents of section .text:
+ 0000 ff00ff01 ff020202 ffff0303 04040404 ................
+ 0010 ffffffff 05050505 ff090a0a 0a0a0a0a ................
+ 0020 ff00ff01 ff020202 ffff0303 04040404 ................
+ 0030 ffffffff 05050505 ff090a0a 0a0a0a0a ................
diff --git a/gas/testsuite/gas/all/align.s b/gas/testsuite/gas/all/align.s
new file mode 100644
index 00000000000..9ccca130cc0
--- /dev/null
+++ b/gas/testsuite/gas/all/align.s
@@ -0,0 +1,61 @@
+/* Test the alignment pseudo-ops. */
+ .text
+
+ .byte 0xff
+ .p2align 1,0
+
+ .byte 0xff
+ .p2align 1,1
+
+ .byte 0xff
+ .p2align 2,2
+
+ .byte 0xff
+ .byte 0xff
+ .p2alignw 2,0x0303
+
+ .p2align 3,4
+ .byte 0xff
+ .byte 0xff
+ .byte 0xff
+ .byte 0xff
+ .p2alignl 3,0x05050505
+
+ .p2align 1,6
+ .p2align 1,7
+
+ .byte 0xff
+ .p2align 3,8,5
+ .byte 9
+ .p2align 3,0xa
+
+ .byte 0xff
+ .balign 2,0
+
+ .byte 0xff
+ .balign 2,1
+
+ .byte 0xff
+ .balign 4,2
+
+ .byte 0xff
+ .byte 0xff
+ .balignw 4,0x0303
+
+ .balign 8,4
+ .byte 0xff
+ .byte 0xff
+ .byte 0xff
+ .byte 0xff
+ .balignl 8,0x05050505
+
+ .balign 2,6
+ .balign 2,7
+
+ .byte 0xff
+ .balign 8,8,5
+ .byte 9
+ .balign 8,0xa
+
+ .p2align 5
+ .balign 32
diff --git a/gas/testsuite/gas/all/cofftag.d b/gas/testsuite/gas/all/cofftag.d
new file mode 100644
index 00000000000..59898b621ed
--- /dev/null
+++ b/gas/testsuite/gas/all/cofftag.d
@@ -0,0 +1,25 @@
+#objdump: -t
+#name: cofftag
+
+.*: file format .*
+
+SYMBOL TABLE:
+\[ 0\]\(sec -2\)\(fl 0x00\)\(ty 0\)\(scl 103\) \(nx 1\) 0x0+0000 foo.c
+File
+\[ 2\]\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 6\) \(nx 0\) 0x0+0000 gcc2_compiled.
+\[ 3\]\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 6\) \(nx 0\) 0x0+0000 ___gnu_compiled_c
+\[ 4\]\(sec -2\)\(fl 0x00\)\(ty a\)\(scl 15\) \(nx 1\) 0x0+0000 _token
+AUX lnno 0 size 0x4 tagndx 0 endndx 10
+\[ 6\]\(sec -1\)\(fl 0x00\)\(ty b\)\(scl 16\) \(nx 0\) 0x0+0000 _operator
+\[ 7\]\(sec -1\)\(fl 0x00\)\(ty b\)\(scl 16\) \(nx 0\) 0x0+0001 _flags
+\[ 8\]\(sec -1\)\(fl 0x00\)\(ty 0\)\(scl 102\) \(nx 1\) 0x0+0004 .eos
+AUX lnno 0 size 0x4 tagndx 4
+\[ 10\]\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 3\) \(nx 1\) 0x[0-9a-f]+ .text
+AUX scnlen 0x[0-9a-f]+ nreloc 0 nlnno 0
+\[ 12\]\(sec 2\)\(fl 0x00\)\(ty 0\)\(scl 3\) \(nx 1\) 0x[0-9a-f]+ .data
+AUX scnlen 0x[0-9a-f]+ nreloc 0 nlnno 0
+\[ 14\]\(sec 3\)\(fl 0x00\)\(ty 0\)\(scl 3\) \(nx 1\) 0x[0-9a-f]+ .bss
+AUX scnlen 0x[0-9a-f]+ nreloc 0 nlnno 0
+\[ 16\]\(sec 2\)\(fl 0x00\)\(ty 2\)\(scl 2\) \(nx 0\) 0x0+0000 _token
+\[ 17\]\(sec 2\)\(fl 0x00\)\(ty a\)\(scl 2\) \(nx 1\) 0x[0-9a-f]+ _what
+AUX lnno 0 size 0x4 tagndx 4
diff --git a/gas/testsuite/gas/all/cofftag.s b/gas/testsuite/gas/all/cofftag.s
new file mode 100644
index 00000000000..8156599b129
--- /dev/null
+++ b/gas/testsuite/gas/all/cofftag.s
@@ -0,0 +1,57 @@
+/* This file was compiled from this C source:
+ char token =0;
+ enum token {
+ operator,
+ flags
+ };
+
+ enum token what= operator;
+ */
+
+ .file "foo.c"
+gcc2_compiled.:
+___gnu_compiled_c:
+.globl _token
+.data
+_token:
+ .byte 0
+.text
+ .def _token
+ .scl 15
+ .type 012
+ .size 4
+ .endef
+ .def _operator
+ .val 0
+ .scl 16
+ .type 013
+ .endef
+ .def _flags
+ .val 1
+ .scl 16
+ .type 013
+ .endef
+ .def .eos
+ .val 4
+ .scl 102
+ .tag _token
+ .size 4
+ .endef
+.globl _what
+.data
+ .p2align 2
+_what:
+ .long 0
+.text
+ .def _token
+ .val _token
+ .scl 2
+ .type 02
+ .endef
+ .def _what
+ .val _what
+ .scl 2
+ .tag _token
+ .size 4
+ .type 012
+ .endef
diff --git a/gas/testsuite/gas/all/comment.s b/gas/testsuite/gas/all/comment.s
new file mode 100644
index 00000000000..76bc641a75c
--- /dev/null
+++ b/gas/testsuite/gas/all/comment.s
@@ -0,0 +1,3 @@
+# This test file is to see whether comments get written into listings
+# correctly. The file has no real contents.
+/* C comments too! */
diff --git a/gas/testsuite/gas/all/cond.d b/gas/testsuite/gas/all/cond.d
new file mode 100644
index 00000000000..4ee3942efb8
--- /dev/null
+++ b/gas/testsuite/gas/all/cond.d
@@ -0,0 +1,20 @@
+# This should match the output of gas -alc cond.s.
+
+.*cond.s.*
+
+
+ 1[ ]+.if 0
+ 8[ ]+.else
+ 9[ ]+.if 1
+ 10[ ]+.endc
+ 11 0000 0[02]00 ?000[02][ ]+.long[ ]+2
+ 12[ ]+.if 0
+ 14[ ]+.else
+ 15 0004 0[04]00 ?000[04][ ]+.long[ ]+4
+ 16[ ]+.endc
+ 17[ ]+.endc
+ 18 0008 0000 ?0000[ ]+.p2align 5,0
+ 18[ ]+0000 ?0000
+ 18[ ]+0000 ?0000
+ 18[ ]+0000 ?0000
+ 18[ ]+0000 ?0000
diff --git a/gas/testsuite/gas/all/cond.s b/gas/testsuite/gas/all/cond.s
new file mode 100644
index 00000000000..39583211e6f
--- /dev/null
+++ b/gas/testsuite/gas/all/cond.s
@@ -0,0 +1,18 @@
+ .if 0
+ .if 1
+ .endc
+ .long 0
+ .if 0
+ .long 1
+ .endc
+ .else
+ .if 1
+ .endc
+ .long 2
+ .if 0
+ .long 3
+ .else
+ .long 4
+ .endc
+ .endc
+ .p2align 5,0
diff --git a/gas/testsuite/gas/all/diff1.s b/gas/testsuite/gas/all/diff1.s
new file mode 100644
index 00000000000..10a89fdc4e5
--- /dev/null
+++ b/gas/testsuite/gas/all/diff1.s
@@ -0,0 +1,5 @@
+# Difference of two undefined symbols.
+# The assembler should reject this.
+ .text
+ .globl _foo
+_foo: .long _a - _b
diff --git a/gas/testsuite/gas/all/float.s b/gas/testsuite/gas/all/float.s
new file mode 100644
index 00000000000..b098cad1cc2
--- /dev/null
+++ b/gas/testsuite/gas/all/float.s
@@ -0,0 +1,4 @@
+ .text
+foo: .single 0r1.2345e+06
+ .single 0f3.14159
+ .double 0r2.718282
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
new file mode 100644
index 00000000000..9544551d60a
--- /dev/null
+++ b/gas/testsuite/gas/all/gas.exp
@@ -0,0 +1,145 @@
+#
+# These tests should be valid on all targets.
+#
+
+# I think currently all targets fail this one when listings are enabled.
+gas_test "p2425.s" "" "" "pcrel values in assignment"
+
+# p1480.s uses a ".space" directive which for most assemblers means
+# "allocate some space". On the PA it means "switch into this space".
+#
+# Therefore this test (as it is currently written) is completely bogus
+# for any PA target. Do not bother trying to run it and just claim
+# it fails.
+if [istarget hppa*-*-*] then {
+ setup_xfail *-*-*
+ fail "simplifiable double subtraction"
+} else {
+ gas_test "p1480.s" "" "-a>" "simplifiable double subtraction"
+}
+
+gas_test "float.s" "" "" "simple FP constants"
+
+# This test is meaningless for the PA; the difference of two undefined
+# symbols is something that is (and must be) supported on the PA.
+if ![istarget hppa*-*-*] then {
+ gas_test_error "diff1.s" "" "difference of two undefined symbols"
+}
+
+proc do_comment {} {
+ set testname "comment.s: comments in listings"
+ set x1 0
+ set x2 0
+ set x3 0
+ set white {[ \t]*}
+ gas_start "comment.s" "-al"
+ while 1 {
+# Apparently CRLF is received when using ptys for subprocesses; hence the
+# \r\n for line 3.
+ expect {
+ -re "^ +1\[ \t\]+# This\[^\n\]*\n" { set x1 1 }
+ -re "^ +2\[ \t\]+# correctly\[^\n\]*\n" { set x2 1 }
+ -re "^ +3\[ \t\]+/. C comments too. ./\r?\n" { set x3 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ gas_finish
+ if [all_ones $x1 $x2 $x3] then { pass $testname } else { fail $testname }
+}
+
+do_comment
+
+#
+# Test x930509a -- correct assembly of differences involving forward
+# references.
+#
+
+proc do_930509a {} {
+ set testname "difference between forward references"
+ set x 0
+ gas_start "x930509.s" "-al"
+ while 1 {
+# We need to accomodate both byte orders here.
+# If ".long" means an 8-byte value on some target someday, this test will have
+# to be fixed.
+ expect {
+ -re "^ +1 .... 0000 *0000" { fail $testname; set x 1 }
+ -re "^ +1 .... 0400 *0000" { pass $testname; set x 1 }
+ -re "^ +1 .... 0000 *0004" { pass $testname; set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ gas_finish
+ if !$x then { fail $testname }
+}
+
+# This test is meaningless for the PA; the difference of two symbols
+# must not be resolved by the assembler.
+if ![istarget hppa*-*-*] then {
+ # the vax fails because VMS can apparently actually handle this
+ # case in relocs, so gas doesn't handle it itself.
+ setup_xfail "vax*-*-vms*"
+ setup_xfail "mn10300*-*-*"
+ setup_xfail "mn10200*-*-*"
+ do_930509a
+}
+
+case $target_triplet in {
+ { hppa*-*-* } { }
+ default {
+ run_dump_test struct
+ run_dump_test align
+ }
+}
+
+# This test is for any COFF target.
+# We omit m88k COFF because it uses weird pseudo-op names.
+# We omit the ARM toolchains because they define locals to
+# start with '.', which eliminates .eos, .text etc from the output.
+if { ([istarget *-*-coff*] && ![istarget m88*-*-*] && ![istarget *arm*-*-coff] && ![istarget thumb*-*-coff]) \
+ ||([istarget *-*-pe*] && ![istarget arm*-*-pe*] && ![istarget thumb*-*-pe*]) \
+ || [istarget a29k-*-udi*] \
+ || [istarget a29k-*-ebmon*] \
+ || [istarget a29k-*-sym*] \
+ || [istarget a29k-*-vxworks*] \
+ || [istarget i*86-*-aix*] \
+ || [istarget i*86-*-sco*] \
+ || [istarget i*86-*-isc*] \
+ || [istarget i*86-*-go32*] \
+ || [istarget i*86-*-cygwin*] \
+ || [istarget i*86-*-*nt] \
+ || ([istarget i960-*-vxworks5.*] && ![istarget i960-*-vxworks5.0*]) } {
+ run_dump_test cofftag
+}
+
+# Test omitting conditionals from listings.
+proc test_cond {} {
+ global comp_output
+ global srcdir
+ global subdir
+
+ set testname "conditional listings"
+ gas_run cond.s -alc ">dump.out"
+ if ![string match "" $comp_output] {
+ send_log "$comp_output\n"
+ fail $testname
+ } else {
+ if { [regexp_diff dump.out $srcdir/$subdir/cond.d] } {
+ fail $testname
+ } else {
+ pass $testname
+ }
+ }
+}
+
+test_cond
+
+# FIXME: this is here cause of a bug in DejaGnu 1.1.1. When it is no longer
+# in use, then this can be removed.
+if [info exists errorInfo] then {
+ unset errorInfo
+}
diff --git a/gas/testsuite/gas/all/itbl b/gas/testsuite/gas/all/itbl
new file mode 100644
index 00000000000..ac66dfbfe46
--- /dev/null
+++ b/gas/testsuite/gas/all/itbl
@@ -0,0 +1,20 @@
+
+ ; Test case for assembler option "itbl".
+ ; Run as "as --itbl itbl itbl.s"
+ ; or with stand-alone test case "itbl-test itbl itbl.s".
+ ; The "p<n>" represent processors of a multi-processor system.
+
+ p1 dreg d1 1 ; data register "d1" for COP1 has value 1
+ p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3
+ p3 insn fie 0x1e:24-20 ; function "fill" for COP3 has value 31
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 insn fee 0x1e:24-20,dreg:17-13,creg:12-8,immed:7-0
+
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 insn fum 0x01e00001 dreg:17-13 creg:12-8
+ p3 insn foh 0xf:24-21 dreg:20-16 immed:15-0
+
+ p3 insn pig 0x1:24-21*[0x100|0x2], dreg:20-16, immed:15-0*0x10000
+
diff --git a/gas/testsuite/gas/all/itbl-test.c b/gas/testsuite/gas/all/itbl-test.c
new file mode 100644
index 00000000000..023f5d95bee
--- /dev/null
+++ b/gas/testsuite/gas/all/itbl-test.c
@@ -0,0 +1,129 @@
+
+
+/* itbl-test.c
+
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Stand-alone test for instruction specification table support.
+ Run using "itbl-test <itbl> <asm.s>"
+ where <itbl> is the name of the instruction table,
+ and <asm.s> is the name of the assembler fie. */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "itbl-ops.h"
+
+static int test_reg (e_processor processor, e_type type, char *name,
+ unsigned long val);
+
+int
+main (int argc, char **argv)
+{
+ unsigned int insn;
+ FILE *fas;
+ int aline = 0;
+ char s[81], *name;
+
+ if (argc < 3)
+ {
+ printf ("usage: %s itbl asm.s\n", argv[0]);
+ exit (0);
+ }
+ if (itbl_parse (argv[1]) != 0)
+ {
+ printf ("failed to parse itbl\n");
+ exit (0);
+ }
+
+ fas = fopen (argv[2], "r");
+ if (fas == 0)
+ {
+ printf ("failed to open asm file %s\n", argv[2]);
+ exit (0);
+ }
+ while (fgets (s, 80, fas))
+ {
+ char *p;
+ aline++;
+
+ if (p = strchr (s, ';'), p) /* strip comments */
+ *p = 0;
+ if (p = strchr (s, '#'), p) /* strip comments */
+ *p = 0;
+ p = s + strlen (s) - 1;
+ while (p >= s && (*p == ' ' || *p == '\t' || *p == '\n')) /* strip trailing spaces */
+ p--;
+ *(p + 1) = 0;
+ p = s;
+ while (*p && (*p == ' ' || *p == '\t' || *p == '\n')) /* strip leading spaces */
+ p++;
+ if (!*p)
+ continue;
+
+ name = itbl_get_field (&p);
+ insn = itbl_assemble (name, p);
+ if (insn == 0)
+ printf ("line %d: Invalid instruction (%s)\n", aline, s);
+ else
+ {
+ char buf[128];
+ printf ("line %d: insn(%s) = 0x%x)\n", aline, s, insn);
+ if (!itbl_disassemble (buf, insn))
+ printf ("line %d: Can't disassemble instruction "
+ "(0x%x)\n", aline, insn);
+ else
+ printf ("line %d: disasm(0x%x) = %s)\n", aline, insn, buf);
+ }
+ }
+
+ test_reg (1, e_dreg, "d1", 1);
+ test_reg (3, e_creg, "c2", 22);
+ test_reg (3, e_dreg, "d3", 3);
+
+ return 0;
+}
+
+static int
+test_reg (e_processor processor, e_type type, char *name,
+ unsigned long val)
+{
+ char *n;
+ unsigned long v;
+
+ n = itbl_get_name (processor, type, val);
+ if (!n || strcmp (n, name))
+ printf ("Error - reg name not found for proessor=%d, type=%d, val=%d\n",
+ processor, type, val);
+ else
+ printf ("name=%s found for processor=%d, type=%d, val=%d\n",
+ n, processor, type, val);
+
+ /* We require that names be unique amoung processors and types. */
+ v = itbl_get_reg_val (name);
+ if (!v || v != val)
+ printf ("Error - reg val not found for processor=%d, type=%d, name=%s\n",
+ processor, type, name);
+ else
+ printf ("val=0x%x found for processor=%d, type=%d, name=%s\n",
+ v, processor, type, name);
+ return 0;
+}
diff --git a/gas/testsuite/gas/all/itbl.s b/gas/testsuite/gas/all/itbl.s
new file mode 100644
index 00000000000..9351aa4bb3c
--- /dev/null
+++ b/gas/testsuite/gas/all/itbl.s
@@ -0,0 +1,13 @@
+
+ ; Test case for assembler option "itbl".
+ ; Run as "as --itbl itbl itbl.s"
+ ; or with stand-alone test case "itbl-test itbl itbl.s".
+
+ ; Assemble processor instructions as defined in "itbl".
+
+ fee $d3,$c2,0x1 ; 0x4ff07601
+ fie ; 0x4ff00000
+ foh $2,0x100
+ fum $d3,$c2 ; 0x4ff07601
+ pig $2,0x100
+
diff --git a/gas/testsuite/gas/all/p1480.s b/gas/testsuite/gas/all/p1480.s
new file mode 100644
index 00000000000..9d0ba81a169
--- /dev/null
+++ b/gas/testsuite/gas/all/p1480.s
@@ -0,0 +1,3 @@
+start: .long 0, 1, 2, 3, 4, 5, 6, 7
+ .space 0x80 - (. - start)
+foo: .long 42
diff --git a/gas/testsuite/gas/all/p2425.s b/gas/testsuite/gas/all/p2425.s
new file mode 100644
index 00000000000..1c9dc958522
--- /dev/null
+++ b/gas/testsuite/gas/all/p2425.s
@@ -0,0 +1,6 @@
+ .text
+ .globl _frobnitz
+_frobnitz:
+ .long 1, 2, 3, 4, 5, 6, 7, GRUMP, 42
+ GRUMP=.-_frobnitz
+ HALFGRUMP=GRUMP/2
diff --git a/gas/testsuite/gas/all/struct.d b/gas/testsuite/gas/all/struct.d
new file mode 100644
index 00000000000..8dc5dd48c10
--- /dev/null
+++ b/gas/testsuite/gas/all/struct.d
@@ -0,0 +1,8 @@
+#nm: --extern-only
+#name: struct
+
+# Test the .struct pseudo-op.
+
+0+00 A w1
+0+02 A w2
+0+04 A w3
diff --git a/gas/testsuite/gas/all/struct.s b/gas/testsuite/gas/all/struct.s
new file mode 100644
index 00000000000..9ecfd0bcc82
--- /dev/null
+++ b/gas/testsuite/gas/all/struct.s
@@ -0,0 +1,10 @@
+ .globl w1
+ .globl w2
+ .globl w3
+ .long 0
+ .struct 0
+w1: .short 0
+w2: .short 0
+w3: .short 0
+ .text
+ .long 0
diff --git a/gas/testsuite/gas/all/x930509.s b/gas/testsuite/gas/all/x930509.s
new file mode 100644
index 00000000000..1299991bf9d
--- /dev/null
+++ b/gas/testsuite/gas/all/x930509.s
@@ -0,0 +1,3 @@
+ .long L2-L1
+L1: .long 0x1234
+L2: .long 0x5678
diff --git a/gas/testsuite/gas/alpha/fp.d b/gas/testsuite/gas/alpha/fp.d
new file mode 100644
index 00000000000..9e6f7e9a5cd
--- /dev/null
+++ b/gas/testsuite/gas/alpha/fp.d
@@ -0,0 +1,7 @@
+
+.*: file format ecoff-littlealpha
+
+Contents of section .rdata:
+ 0000 71a37909 4f930a40 5441789a cd4b881b q.y.O..@TAx..K..
+ 0010 2a404f93 790971a3 789a5440 5441789a .@O.y.q.x.T@TAx.
+ 0020 00000000 00000000 00000000 00000000 ................
diff --git a/gas/testsuite/gas/alpha/fp.exp b/gas/testsuite/gas/alpha/fp.exp
new file mode 100644
index 00000000000..05ec881cfe6
--- /dev/null
+++ b/gas/testsuite/gas/alpha/fp.exp
@@ -0,0 +1,15 @@
+#
+# Alpha OSF/1 tests
+#
+
+if [istarget alpha-*-osf*] then {
+ set testname "fp constants (part 2)"
+ if [gas_test_old "fp.s" "" "fp constants (part 1)"] then {
+ objdump "-s -j .rdata > a.dump"
+ if { [regexp_diff "a.dump" "$srcdir/$subdir/fp.d"] == 0 } then {
+ pass $testname
+ } else {
+ fail $testname
+ }
+ }
+}
diff --git a/gas/testsuite/gas/alpha/fp.s b/gas/testsuite/gas/alpha/fp.s
new file mode 100644
index 00000000000..7cebbbe16ce
--- /dev/null
+++ b/gas/testsuite/gas/alpha/fp.s
@@ -0,0 +1,14 @@
+ .rdata
+# These three formats are 8 bytes each.
+ .t_floating 3.32192809488736218171e0
+# .byte 0x71, 0xa3, 0x79, 0x09, 0x4f, 0x93, 0x0a, 0x40
+ .d_floating 3.32192809488736218171e0
+# .byte 0x54, 0x41, 0x78, 0x9a, 0xcd, 0x4b, 0x88, 0x1b
+ .g_floating 3.32192809488736218171e0
+# .byte 0x2a, 0x40, 0x4f, 0x93, 0x79, 0x09, 0x71, 0xa3
+# The next two are four bytes each.
+ .s_floating 3.32192809488736218171e0
+# .byte 0x78, 0x9a, 0x54, 0x40, 0, 0, 0, 0
+ .f_floating 3.32192809488736218171e0
+# .byte 0x54, 0x41, 0x78, 0x9a, 0, 0, 0, 0
+ .long 0, 0, 0, 0
diff --git a/gas/testsuite/gas/arc/alias.d b/gas/testsuite/gas/arc/alias.d
new file mode 100644
index 00000000000..b51acf63e9e
--- /dev/null
+++ b/gas/testsuite/gas/arc/alias.d
@@ -0,0 +1,68 @@
+#objdump: -dr
+#name: @OC@
+
+# Test the @OC@ insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 @IC+0@008200 @OC@ r0,r1
+00000004 @IC+3@6e3800 @OC@ fp,sp
+00000008 @IC+0@1ffe00 @OC@ r0,0
+0000000c @IC+0@3fffff @OC@ r1,-1
+00000010 @IC+7@e10400 @OC@ 0,r2
+00000014 @IC+7@e187ff @OC@ -1,r3
+00000018 @IC+0@9ffeff @OC@ r4,255
+0000001c @IC+7@e28aff @OC@ 255,r5
+00000020 @IC+0@dfff00 @OC@ r6,-256
+00000024 @IC+7@e38f00 @OC@ -256,r7
+00000028 @IC+1@1f7c00 @OC@ r8,256
+00000030 @IC+1@3f7c00 @OC@ r9,-257
+00000038 @IC+7@c51400 @OC@ 511,r10
+00000040 @IC+1@7f7c00 @OC@ r11,1111638594
+00000048 @IC+7@c61800 @OC@ 305419896,r12
+00000050 @IC+7@ff7cff @OC@ 255,256
+00000058 @IC+7@dffeff @OC@ 256,255
+00000060 @IC+0@1f7c00 @OC@ r0,0
+ RELOC: 00000064 R_ARC_32 foo
+00000068 @IC+0@008200 @OC@ r0,r1
+0000006c @IC+0@620800 @OC@ r3,r4
+00000070 @IC+0@c38e01 @OC@.eq r6,r7
+00000074 @IC+1@251401 @OC@.eq r9,r10
+00000078 @IC+1@869a02 @OC@.ne r12,r13
+0000007c @IC+1@e82002 @OC@.ne r15,r16
+00000080 @IC+2@49a603 @OC@.p r18,r19
+00000084 @IC+2@ab2c03 @OC@.p r21,r22
+00000088 @IC+3@0cb204 @OC@.n r24,r25
+0000008c @IC+3@6e3804 @OC@.n fp,sp
+00000090 @IC+3@cfbe05 @OC@.c ilink2,blink
+00000094 @IC+4@314405 @OC@.c r33,r34
+00000098 @IC+4@92ca05 @OC@.c r36,r37
+0000009c @IC+4@f45006 @OC@.nc r39,r40
+000000a0 @IC+5@55d606 @OC@.nc r42,r43
+000000a4 @IC+5@b75c06 @OC@.nc r45,r46
+000000a8 @IC+6@18e207 @OC@.v r48,r49
+000000ac @IC+6@7a6807 @OC@.v r51,r52
+000000b0 @IC+6@dbee08 @OC@.nv r54,r55
+000000b4 @IC+7@3d7408 @OC@.nv r57,r58
+000000b8 @IC+7@9e7809 @OC@.gt lp_count,lp_count
+000000bc @IC+0@1f7c0a @OC@.ge r0,0
+000000c4 @IC+7@c0820b @OC@.lt 1,r1
+000000cc @IC+7@df7c0c @OC@.le 2,2
+000000d4 @IC+0@61860d @OC@.hi r3,r3
+000000d8 @IC+0@82080e @OC@.ls r4,r4
+000000dc @IC+0@a28a0f @OC@.pnz r5,r5
+000000e0 @IC+0@008300 @OC@.f r0,r1
+000000e4 @IC+0@5efa01 @OC@.f r2,1
+000000e8 @IC+7@a18601 @OC@.f 1,r3
+000000ec @IC+7@a20800 @OC@.f 0,r4
+000000f0 @IC+0@bf7d00 @OC@.f r5,512
+000000f8 @IC+7@c30d00 @OC@.f 512,r6
+00000100 @IC+7@df7d00 @OC@.f 512,512
+00000108 @IC+0@008301 @OC@.eq.f r0,r1
+0000010c @IC+0@3f7d02 @OC@.ne.f r1,0
+00000114 @IC+7@c1050b @OC@.lt.f 0,r2
+0000011c @IC+7@c10509 @OC@.gt.f 1,r2
+00000124 @IC+0@1f7d0c @OC@.le.f r0,512
+0000012c @IC+7@c1050a @OC@.ge.f 512,r2
+00000134 @IC+7@df7d04 @OC@.n.f 512,512
diff --git a/gas/testsuite/gas/arc/alias.s b/gas/testsuite/gas/arc/alias.s
new file mode 100644
index 00000000000..d524440f987
--- /dev/null
+++ b/gas/testsuite/gas/arc/alias.s
@@ -0,0 +1,76 @@
+# @OC@ test
+
+# reg,reg
+ @OC@ r0,r1
+ @OC@ fp,sp
+
+# shimm values
+ @OC@ r0,0
+ @OC@ r1,-1
+ @OC@ 0,r2
+ @OC@ -1,r3
+ @OC@ r4,255
+ @OC@ 255,r5
+ @OC@ r6,-256
+ @OC@ -256,r7
+
+# limm values
+ @OC@ r8,256
+ @OC@ r9,-257
+ @OC@ 511,r10
+ @OC@ r11,0x42424242
+ @OC@ 0x12345678,r12
+
+# shimm and limm
+ @OC@ 255,256
+ @OC@ 256,255
+
+# symbols
+ @OC@ r0,foo
+
+# conditional execution
+ @OC@.al r0,r1
+ @OC@.ra r3,r4
+ @OC@.eq r6,r7
+ @OC@.z r9,r10
+ @OC@.ne r12,r13
+ @OC@.nz r15,r16
+ @OC@.pl r18,r19
+ @OC@.p r21,r22
+ @OC@.mi r24,r25
+ @OC@.n r27,r28
+ @OC@.cs r30,r31
+ @OC@.c r33,r34
+ @OC@.lo r36,r37
+ @OC@.cc r39,r40
+ @OC@.nc r42,r43
+ @OC@.hs r45,r46
+ @OC@.vs r48,r49
+ @OC@.v r51,r52
+ @OC@.vc r54,r55
+ @OC@.nv r57,r58
+ @OC@.gt r60,r60
+ @OC@.ge r0,0
+ @OC@.lt 1,r1
+ @OC@.le 2,2
+ @OC@.hi r3,r3
+ @OC@.ls r4,r4
+ @OC@.pnz r5,r5
+
+# flag setting
+ @OC@.f r0,r1
+ @OC@.f r2,1
+ @OC@.f 1,r3
+ @OC@.f 0,r4
+ @OC@.f r5,512
+ @OC@.f 512,r6
+ @OC@.f 512,512
+
+# conditional execution + flag setting
+ @OC@.eq.f r0,r1
+ @OC@.ne.f r1,0
+ @OC@.lt.f 0,r2
+ @OC@.gt.f 1,r2
+ @OC@.le.f r0,512
+ @OC@.ge.f 512,r2
+ @OC@.n.f 512,512
diff --git a/gas/testsuite/gas/arc/arc.exp b/gas/testsuite/gas/arc/arc.exp
new file mode 100644
index 00000000000..b0984535e2e
--- /dev/null
+++ b/gas/testsuite/gas/arc/arc.exp
@@ -0,0 +1,114 @@
+# ARC gas testsuite
+
+# Test an insn from a template .s/.d.
+# The best way to create the .d file is to run the tests without it, let
+# dejagnu crash, run as.new on the just built .s file, run objdump -dr on
+# the result of that, copy the result into the .d file, and edit in the
+# necessary patterns (@OC@, etc.). Sounds complicated but it's easy. The
+# catch is that we assume a working assembler is used to build it. That's
+# obviously not entirely kosher, but once the .d file is created one can
+# verify it's contents over time.
+#
+# Template patterns:
+# @OC@ - placeholder for the opcode
+# @IC+?@ - place holder for the insn code
+# @I3+??@ - place holder for the operation code of code 3 insns.
+
+proc test_template_insn { cpu tmpl opcode icode } {
+ global srcdir subdir objdir
+
+ # Change @OC@ in the template file to $opcode
+
+ set in_fd [open $srcdir/$subdir/$tmpl.s r]
+ set out_fd [open $objdir/$opcode.s w]
+ # FIXME: check return codes
+
+ puts $out_fd "\t.cpu $cpu\n"
+ while { [gets $in_fd line] >= 0 } {
+ regsub "@OC@" $line $opcode line
+ puts $out_fd $line
+ }
+
+ close $in_fd
+ close $out_fd
+
+ # Create output template.
+
+ set in_fd [open $srcdir/$subdir/$tmpl.d r]
+ set out_fd [open $objdir/$opcode.d w]
+ # FIXME: check return codes
+
+ while { [gets $in_fd line] >= 0 } {
+ regsub "@OC@" $line $opcode line
+ #send_user "$line\n"
+ if [string match "*@IC+?@*" $line] {
+ # Insert the opcode. It occupies the top 5 bits.
+ regexp "^(.*)@IC\\+(.)@(.*)$" $line junk leftpart n rightpart
+ set n [expr ($icode << 3) + $n]
+ set n [format "%02x" $n]
+ puts $out_fd "$leftpart$n$rightpart"
+ } elseif [string match "*@I3+??@*" $line] {
+ # Insert insn 3 code (register C field)
+ # b15=8/0, b8=1/0 (their respective hex values in the objdump)
+ regexp "^(.*)@I3\\+(.)(.)@(.*)$" $line junk leftpart b15 b8 rightpart
+ set n [expr ($icode << 1) + ($b15 << 4) + ($b8 << 0)]
+ set n [format "%02x" $n]
+ puts $out_fd "$leftpart$n$rightpart"
+ } else {
+ puts $out_fd $line
+ }
+ }
+
+ close $in_fd
+ close $out_fd
+
+ # Finally, run the test.
+
+ run_dump_test $objdir/$opcode
+
+ # "make clean" won't delete these, so for now we must.
+ catch "exec rm -f $objdir/$opcode.s $objdir/$opcode.d"
+}
+
+# Run the tests.
+
+if [istarget arc*-*-*] then {
+
+ test_template_insn base math adc 9
+ test_template_insn base math add 8
+ test_template_insn base math and 12
+ test_template_insn base math bic 14
+ test_template_insn base math or 13
+ test_template_insn base math sbc 11
+ test_template_insn base math sub 10
+ test_template_insn base math xor 15
+
+ test_template_insn base alias mov 12
+ test_template_insn base alias rlc 9
+ test_template_insn base alias asl 8
+# `lsl' gets dumped as `asl' so this must be tested elsewhere.
+# test_template_insn base alias lsl 8
+
+ test_template_insn base sshift asr 1
+ test_template_insn base sshift lsr 2
+ test_template_insn base sshift ror 3
+ test_template_insn base sshift rrc 4
+
+ test_template_insn base branch b 4
+ test_template_insn base branch bl 5
+ test_template_insn base branch lp 6
+
+ run_dump_test "j"
+
+ test_template_insn base insn3 sexb 5
+ test_template_insn base insn3 sexw 6
+ test_template_insn base insn3 extb 7
+ test_template_insn base insn3 extw 8
+
+ run_dump_test "flag"
+# run_dump_test "nop"
+
+ run_dump_test "ld"
+ run_dump_test "st"
+
+}
diff --git a/gas/testsuite/gas/arc/branch.d b/gas/testsuite/gas/arc/branch.d
new file mode 100644
index 00000000000..4c9b014b1ba
--- /dev/null
+++ b/gas/testsuite/gas/arc/branch.d
@@ -0,0 +1,45 @@
+#objdump: -dr
+#name: @OC@
+
+# Test the @OC@ insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 <text_label> @IC+7@ffff80 @OC@ 00000000 <text_label>
+00000004 <text_label\+4> @IC+7@ffff00 @OC@ 00000000 <text_label>
+00000008 <text_label\+8> @IC+7@fffe80 @OC@ 00000000 <text_label>
+0000000c <text_label\+c> @IC+7@fffe01 @OC@eq 00000000 <text_label>
+00000010 <text_label\+10> @IC+7@fffd81 @OC@eq 00000000 <text_label>
+00000014 <text_label\+14> @IC+7@fffd02 @OC@ne 00000000 <text_label>
+00000018 <text_label\+18> @IC+7@fffc82 @OC@ne 00000000 <text_label>
+0000001c <text_label\+1c> @IC+7@fffc03 @OC@p 00000000 <text_label>
+00000020 <text_label\+20> @IC+7@fffb83 @OC@p 00000000 <text_label>
+00000024 <text_label\+24> @IC+7@fffb04 @OC@n 00000000 <text_label>
+00000028 <text_label\+28> @IC+7@fffa84 @OC@n 00000000 <text_label>
+0000002c <text_label\+2c> @IC+7@fffa05 @OC@c 00000000 <text_label>
+00000030 <text_label\+30> @IC+7@fff985 @OC@c 00000000 <text_label>
+00000034 <text_label\+34> @IC+7@fff905 @OC@c 00000000 <text_label>
+00000038 <text_label\+38> @IC+7@fff886 @OC@nc 00000000 <text_label>
+0000003c <text_label\+3c> @IC+7@fff806 @OC@nc 00000000 <text_label>
+00000040 <text_label\+40> @IC+7@fff786 @OC@nc 00000000 <text_label>
+00000044 <text_label\+44> @IC+7@fff707 @OC@v 00000000 <text_label>
+00000048 <text_label\+48> @IC+7@fff687 @OC@v 00000000 <text_label>
+0000004c <text_label\+4c> @IC+7@fff608 @OC@nv 00000000 <text_label>
+00000050 <text_label\+50> @IC+7@fff588 @OC@nv 00000000 <text_label>
+00000054 <text_label\+54> @IC+7@fff509 @OC@gt 00000000 <text_label>
+00000058 <text_label\+58> @IC+7@fff48a @OC@ge 00000000 <text_label>
+0000005c <text_label\+5c> @IC+7@fff40b @OC@lt 00000000 <text_label>
+00000060 <text_label\+60> @IC+7@fff38c @OC@le 00000000 <text_label>
+00000064 <text_label\+64> @IC+7@fff30d @OC@hi 00000000 <text_label>
+00000068 <text_label\+68> @IC+7@fff28e @OC@ls 00000000 <text_label>
+0000006c <text_label\+6c> @IC+7@fff20f @OC@pnz 00000000 <text_label>
+00000070 <text_label\+70> @IC+7@ffff80 @OC@ 00000070 <text_label\+70>
+ RELOC: 00000070 R_ARC_B22_PCREL external_text_label
+00000074 <text_label\+74> @IC+0@000000 @OC@ 00000078 <text_label\+78>
+00000078 <text_label\+78> @IC+7@fff0a0 @OC@.d 00000000 <text_label>
+0000007c <text_label\+7c> @IC+7@fff000 @OC@ 00000000 <text_label>
+00000080 <text_label\+80> @IC+7@ffefc0 @OC@.jd 00000000 <text_label>
+00000084 <text_label\+84> @IC+7@ffef21 @OC@eq.d 00000000 <text_label>
+00000088 <text_label\+88> @IC+7@ffee82 @OC@ne 00000000 <text_label>
+0000008c <text_label\+8c> @IC+7@ffee46 @OC@nc.jd 00000000 <text_label>
diff --git a/gas/testsuite/gas/arc/branch.s b/gas/testsuite/gas/arc/branch.s
new file mode 100644
index 00000000000..8bf1618ffc4
--- /dev/null
+++ b/gas/testsuite/gas/arc/branch.s
@@ -0,0 +1,47 @@
+# @OC@ test
+
+text_label:
+
+# Condition tests
+ @OC@ text_label
+ @OC@al text_label
+ @OC@ra text_label
+ @OC@eq text_label
+ @OC@z text_label
+ @OC@ne text_label
+ @OC@nz text_label
+ @OC@pl text_label
+ @OC@p text_label
+ @OC@mi text_label
+ @OC@n text_label
+ @OC@cs text_label
+ @OC@c text_label
+ @OC@lo text_label
+ @OC@cc text_label
+ @OC@nc text_label
+ @OC@hs text_label
+ @OC@vs text_label
+ @OC@v text_label
+ @OC@vc text_label
+ @OC@nv text_label
+ @OC@gt text_label
+ @OC@ge text_label
+ @OC@lt text_label
+ @OC@le text_label
+ @OC@hi text_label
+ @OC@ls text_label
+ @OC@pnz text_label
+
+ @OC@ external_text_label
+
+ @OC@ 0
+
+# Delay slots
+ @OC@.d text_label
+ @OC@.nd text_label
+ @OC@.jd text_label
+
+# Condition tests and delay slots
+ @OC@eq.d text_label
+ @OC@ne.nd text_label
+ @OC@cc.jd text_label
diff --git a/gas/testsuite/gas/arc/flag.d b/gas/testsuite/gas/arc/flag.d
new file mode 100644
index 00000000000..68f36d39f1e
--- /dev/null
+++ b/gas/testsuite/gas/arc/flag.d
@@ -0,0 +1,29 @@
+#objdump: -dr
+#name: flag
+
+# Test the flag macro.
+
+.*: +file format elf32-.*arc
+
+No symbols in "a.out".
+Disassembly of section .text:
+00000000 1fa00000 flag r0
+00000004 1fbf8001 flag 1
+00000008 1fbf8002 flag 2
+0000000c 1fbf8004 flag 4
+00000010 1fbf8008 flag 8
+00000014 1fbf8010 flag 16
+00000018 1fbf8020 flag 32
+0000001c 1fbf8040 flag 64
+00000020 1fbf8080 flag 128
+00000024 1fbf0000 flag -2147483647
+0000002c 1fa0000b flag.lt r0
+00000030 1fbf0009 flag.gt 1
+00000038 1fbf0009 flag.gt 2
+00000040 1fbf0009 flag.gt 4
+00000048 1fbf0009 flag.gt 8
+00000050 1fbf0009 flag.gt 16
+00000058 1fbf0009 flag.gt 32
+00000060 1fbf0009 flag.gt 64
+00000068 1fbf0009 flag.gt 128
+00000070 1fbf000a flag.ge -2147483647
diff --git a/gas/testsuite/gas/arc/flag.s b/gas/testsuite/gas/arc/flag.s
new file mode 100644
index 00000000000..7067aa5465e
--- /dev/null
+++ b/gas/testsuite/gas/arc/flag.s
@@ -0,0 +1,27 @@
+# flag test
+
+ flag r0
+
+ flag 1
+ flag 2
+ flag 4
+ flag 8
+ flag 16
+ flag 32
+ flag 64
+ flag 128
+
+ flag 0x80000001
+
+ flag.lt r0
+
+ flag.gt 1
+ flag.gt 2
+ flag.gt 4
+ flag.gt 8
+ flag.gt 16
+ flag.gt 32
+ flag.gt 64
+ flag.gt 128
+
+ flag.ge 0x80000001
diff --git a/gas/testsuite/gas/arc/insn3.d b/gas/testsuite/gas/arc/insn3.d
new file mode 100644
index 00000000000..c0207a77a4b
--- /dev/null
+++ b/gas/testsuite/gas/arc/insn3.d
@@ -0,0 +1,44 @@
+#objdump: -dr
+#name: @OC@
+
+# Test the @OC@ insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 1800@I3+80@00 @OC@ r0,r1
+00000004 1b6e@I3+00@00 @OC@ fp,sp
+00000008 181f@I3+80@00 @OC@ r0,0
+0000000c 183f@I3+81@ff @OC@ r1,-1
+00000010 1fe1@I3+00@00 @OC@ 0,r2
+00000014 1fe1@I3+81@ff @OC@ -1,r3
+00000018 189f@I3+80@ff @OC@ r4,255
+0000001c 1fe2@I3+80@ff @OC@ 255,r5
+00000020 18df@I3+81@00 @OC@ r6,-256
+00000024 1fe3@I3+81@00 @OC@ -256,r7
+00000028 191f@I3+00@00 @OC@ r8,256
+00000030 193f@I3+00@00 @OC@ r9,-257
+00000038 1fc5@I3+00@00 @OC@ 511,r10
+00000040 197f@I3+00@00 @OC@ r11,1111638594
+00000048 1fc6@I3+00@00 @OC@ 305419896,r12
+00000050 1fff@I3+00@ff @OC@ 255,256
+00000058 1fdf@I3+80@ff @OC@ 256,255
+00000060 181f@I3+00@00 @OC@ r0,0
+ RELOC: 00000064 R_ARC_32 foo
+00000068 1945@I3+80@01 @OC@.eq r10,r11
+0000006c 1986@I3+80@02 @OC@.ne r12,r13
+00000070 19df@I3+00@0b @OC@.lt r14,0
+00000078 19ff@I3+00@09 @OC@.gt r15,512
+00000080 1800@I3+81@00 @OC@.f r0,r1
+00000084 185e@I3+80@01 @OC@.f r2,1
+00000088 1fa2@I3+00@00 @OC@.f 0,r4
+0000008c 18bf@I3+01@00 @OC@.f r5,512
+00000094 1fc3@I3+01@00 @OC@.f 512,r6
+0000009c 1fdf@I3+01@00 @OC@.f 512,512
+000000a4 1800@I3+81@01 @OC@.eq.f r0,r1
+000000a8 183f@I3+01@02 @OC@.ne.f r1,0
+000000b0 1fc1@I3+01@0b @OC@.lt.f 0,r2
+000000b8 1fc1@I3+01@09 @OC@.gt.f 1,r2
+000000c0 181f@I3+01@0c @OC@.le.f r0,512
+000000c8 1fc1@I3+01@0a @OC@.ge.f 512,r2
+000000d0 1fdf@I3+01@04 @OC@.n.f 512,512
diff --git a/gas/testsuite/gas/arc/insn3.s b/gas/testsuite/gas/arc/insn3.s
new file mode 100644
index 00000000000..f12fb88355f
--- /dev/null
+++ b/gas/testsuite/gas/arc/insn3.s
@@ -0,0 +1,52 @@
+# Insn 3 @OC@ test
+
+# reg,reg
+ @OC@ r0,r1
+ @OC@ fp,sp
+
+# shimm values
+ @OC@ r0,0
+ @OC@ r1,-1
+ @OC@ 0,r2
+ @OC@ -1,r3
+ @OC@ r4,255
+ @OC@ 255,r5
+ @OC@ r6,-256
+ @OC@ -256,r7
+
+# limm values
+ @OC@ r8,256
+ @OC@ r9,-257
+ @OC@ 511,r10
+ @OC@ r11,0x42424242
+ @OC@ 0x12345678,r12
+
+# shimm and limm
+ @OC@ 255,256
+ @OC@ 256,255
+
+# symbols
+ @OC@ r0,foo
+
+# conditional execution
+ @OC@.eq r10,r11
+ @OC@.ne r12,r13
+ @OC@.lt r14,0
+ @OC@.gt r15,512
+
+# flag setting
+ @OC@.f r0,r1
+ @OC@.f r2,1
+ @OC@.f 0,r4
+ @OC@.f r5,512
+ @OC@.f 512,r6
+ @OC@.f 512,512
+
+# conditional execution + flag setting
+ @OC@.eq.f r0,r1
+ @OC@.ne.f r1,0
+ @OC@.lt.f 0,r2
+ @OC@.gt.f 1,r2
+ @OC@.le.f r0,512
+ @OC@.ge.f 512,r2
+ @OC@.n.f 512,512
diff --git a/gas/testsuite/gas/arc/j.d b/gas/testsuite/gas/arc/j.d
new file mode 100644
index 00000000000..af103f0d1a7
--- /dev/null
+++ b/gas/testsuite/gas/arc/j.d
@@ -0,0 +1,75 @@
+#objdump: -dr
+#name: j
+
+# Test the j insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 <text_label> 38000000 j r0
+00000004 <text_label\+4> 38000020 j.d r0
+00000008 <text_label\+8> 38000040 j.jd r0
+0000000c <text_label\+c> 38000000 j r0
+00000010 <text_label\+10> 38008000 j r1
+00000014 <text_label\+14> 38008020 j.d r1
+00000018 <text_label\+18> 38008040 j.jd r1
+0000001c <text_label\+1c> 38008000 j r1
+00000020 <text_label\+20> 381f0000 j 0
+ RELOC: 00000024 R_ARC_32 .text
+00000028 <text_label\+28> 381f0000 j 0
+ RELOC: 0000002c R_ARC_32 .text
+00000030 <text_label\+30> 381f0000 j 0
+ RELOC: 00000034 R_ARC_32 .text
+00000038 <text_label\+38> 381f0001 jeq 0
+ RELOC: 0000003c R_ARC_32 .text
+00000040 <text_label\+40> 381f0001 jeq 0
+ RELOC: 00000044 R_ARC_32 .text
+00000048 <text_label\+48> 381f0002 jne 0
+ RELOC: 0000004c R_ARC_32 .text
+00000050 <text_label\+50> 381f0002 jne 0
+ RELOC: 00000054 R_ARC_32 .text
+00000058 <text_label\+58> 381f0003 jp 0
+ RELOC: 0000005c R_ARC_32 .text
+00000060 <text_label\+60> 381f0003 jp 0
+ RELOC: 00000064 R_ARC_32 .text
+00000068 <text_label\+68> 381f0004 jn 0
+ RELOC: 0000006c R_ARC_32 .text
+00000070 <text_label\+70> 381f0004 jn 0
+ RELOC: 00000074 R_ARC_32 .text
+00000078 <text_label\+78> 381f0005 jc 0
+ RELOC: 0000007c R_ARC_32 .text
+00000080 <text_label\+80> 381f0005 jc 0
+ RELOC: 00000084 R_ARC_32 .text
+00000088 <text_label\+88> 381f0005 jc 0
+ RELOC: 0000008c R_ARC_32 .text
+00000090 <text_label\+90> 381f0006 jnc 0
+ RELOC: 00000094 R_ARC_32 .text
+00000098 <text_label\+98> 381f0006 jnc 0
+ RELOC: 0000009c R_ARC_32 .text
+000000a0 <text_label\+a0> 381f0006 jnc 0
+ RELOC: 000000a4 R_ARC_32 .text
+000000a8 <text_label\+a8> 381f0007 jv 0
+ RELOC: 000000ac R_ARC_32 .text
+000000b0 <text_label\+b0> 381f0007 jv 0
+ RELOC: 000000b4 R_ARC_32 .text
+000000b8 <text_label\+b8> 381f0008 jnv 0
+ RELOC: 000000bc R_ARC_32 .text
+000000c0 <text_label\+c0> 381f0008 jnv 0
+ RELOC: 000000c4 R_ARC_32 .text
+000000c8 <text_label\+c8> 381f0009 jgt 0
+ RELOC: 000000cc R_ARC_32 .text
+000000d0 <text_label\+d0> 381f000a jge 0
+ RELOC: 000000d4 R_ARC_32 .text
+000000d8 <text_label\+d8> 381f000b jlt 0
+ RELOC: 000000dc R_ARC_32 .text
+000000e0 <text_label\+e0> 381f000c jle 0
+ RELOC: 000000e4 R_ARC_32 .text
+000000e8 <text_label\+e8> 381f000d jhi 0
+ RELOC: 000000ec R_ARC_32 .text
+000000f0 <text_label\+f0> 381f000e jls 0
+ RELOC: 000000f4 R_ARC_32 .text
+000000f8 <text_label\+f8> 381f000f jpnz 0
+ RELOC: 000000fc R_ARC_32 .text
+00000100 <text_label\+100> 381f0000 j 0
+ RELOC: 00000104 R_ARC_32 external_text_label
+00000108 <text_label\+108> 381f0000 j 0
diff --git a/gas/testsuite/gas/arc/j.s b/gas/testsuite/gas/arc/j.s
new file mode 100644
index 00000000000..0161af215fc
--- /dev/null
+++ b/gas/testsuite/gas/arc/j.s
@@ -0,0 +1,45 @@
+# j test
+
+text_label:
+ j r0
+ j.d r0
+ j.jd r0
+ j.nd r0
+
+ j.f [r1]
+ j.d.f [r1]
+ j.jd.f [r1]
+ j.nd.f [r1]
+
+ j text_label
+ jal text_label
+ jra text_label
+ jeq text_label
+ jz text_label
+ jne text_label
+ jnz text_label
+ jpl text_label
+ jp text_label
+ jmi text_label
+ jn text_label
+ jcs text_label
+ jc text_label
+ jlo text_label
+ jcc text_label
+ jnc text_label
+ jhs text_label
+ jvs text_label
+ jv text_label
+ jvc text_label
+ jnv text_label
+ jgt text_label
+ jge text_label
+ jlt text_label
+ jle text_label
+ jhi text_label
+ jls text_label
+ jpnz text_label
+
+ j external_text_label
+
+ j 0
diff --git a/gas/testsuite/gas/arc/ld.d b/gas/testsuite/gas/arc/ld.d
new file mode 100644
index 00000000000..d6dd0a1a5dd
--- /dev/null
+++ b/gas/testsuite/gas/arc/ld.d
@@ -0,0 +1,30 @@
+#objdump: -dr
+#name: ld/lr
+
+# Test the ld/lr insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 08008000 ld r0,\[r1\]
+00000004 00418800 ld r2,\[r3,r4\]
+00000008 08a30001 ld r5,\[r6,1\]
+0000000c 08e401ff ld r7,\[r8,-1\]
+00000010 092500ff ld r9,\[r10,255\]
+00000014 09660100 ld r11,\[r12,-256\]
+00000018 01a77c00 ld r13,\[r14,256\]
+00000020 01e87c00 ld r15,\[r16,-257\]
+00000028 023f3800 ld r17,\[305419896,sp\]
+00000030 0a7f0000 ld r19,\[0\]
+ RELOC: 00000034 R_ARC_32 foo
+00000038 0a9f0000 ld r20,\[4\]
+ RELOC: 0000003c R_ARC_32 foo
+00000040 081f8400 ldb r0,\[0\]
+00000044 081f8800 ldw r0,\[0\]
+00000048 081f8200 ld.x r0,\[0\]
+0000004c 081f9000 ld.a r0,\[0\]
+00000050 081fc000 ld.di r0,\[0\]
+00000054 08005600 ldb.x.a.di r0,\[r0\]
+00000058 0800a000 lr r0,\[r1\]
+0000005c 085fa000 lr r2,\[status\]
+00000060 087f2000 lr r3,\[305419896\]
diff --git a/gas/testsuite/gas/arc/ld.s b/gas/testsuite/gas/arc/ld.s
new file mode 100644
index 00000000000..aa26719df1b
--- /dev/null
+++ b/gas/testsuite/gas/arc/ld.s
@@ -0,0 +1,24 @@
+# ld/lr test
+
+ ld r0,[r1]
+ ld r2,[r3,r4]
+ ld r5,[r6,1]
+ ld r7,[r8,-1]
+ ld r9,[r10,255]
+ ld r11,[r12,-256]
+ ld r13,[r14,256]
+ ld r15,[r16,-257]
+ ld r17,[0x12345678,r28]
+ ld r19,[foo]
+ ld r20,[foo+4]
+
+ ldb r0,[0]
+ ldw r0,[0]
+ ld.x r0,[0]
+ ld.a r0,[0]
+ ld.di r0,[0]
+ ldb.x.a.di r0,[r0]
+
+ lr r0,[r1]
+ lr r2,[status]
+ lr r3,[0x12345678]
diff --git a/gas/testsuite/gas/arc/math.d b/gas/testsuite/gas/arc/math.d
new file mode 100644
index 00000000000..ccb79c5ca77
--- /dev/null
+++ b/gas/testsuite/gas/arc/math.d
@@ -0,0 +1,78 @@
+#objdump: -dr
+#name: @OC@
+
+# Test the @OC@ insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 @IC+0@008400 @OC@ r0,r1,r2
+00000004 @IC+3@4db800 @OC@ r26,fp,sp
+00000008 @IC+3@af3e00 @OC@ ilink1,ilink2,blink
+0000000c @IC+7@5df800 @OC@ r58,r59,lp_count
+00000010 @IC+0@00fe00 @OC@ r0,r1,0
+00000014 @IC+0@1f8400 @OC@ r0,0,r2
+00000018 @IC+7@e08400 @OC@ 0,r1,r2
+0000001c @IC+0@00ffff @OC@ r0,r1,-1
+00000020 @IC+0@1f85ff @OC@ r0,-1,r2
+00000024 @IC+7@e085ff @OC@ -1,r1,r2
+00000028 @IC+0@00feff @OC@ r0,r1,255
+0000002c @IC+0@1f84ff @OC@ r0,255,r2
+00000030 @IC+7@e084ff @OC@ 255,r1,r2
+00000034 @IC+0@00ff00 @OC@ r0,r1,-256
+00000038 @IC+0@1f8500 @OC@ r0,-256,r2
+0000003c @IC+7@e08500 @OC@ -256,r1,r2
+00000040 @IC+0@00fc00 @OC@ r0,r1,256
+00000048 @IC+0@1f0400 @OC@ r0,-257,r2
+00000050 @IC+7@c08400 @OC@ 511,r1,r2
+00000058 @IC+0@1f0400 @OC@ r0,1111638594,r2
+00000060 @IC+7@c0fc00 @OC@ 305419896,r1,305419896
+00000068 @IC+0@1ffcff @OC@ r0,255,256
+00000070 @IC+0@1f7eff @OC@ r0,256,255
+00000078 @IC+7@e0fcff @OC@ 255,r1,256
+00000080 @IC+7@ff04ff @OC@ 255,256,r2
+00000088 @IC+7@c0feff @OC@ 256,r1,255
+00000090 @IC+7@df84ff @OC@ 256,255,r2
+00000098 @IC+0@00fc00 @OC@ r0,r1,0
+ RELOC: 0000009c R_ARC_32 foo
+000000a0 @IC+0@008400 @OC@ r0,r1,r2
+000000a4 @IC+0@620a00 @OC@ r3,r4,r5
+000000a8 @IC+0@c39001 @OC@.eq r6,r7,r8
+000000ac @IC+1@251601 @OC@.eq r9,r10,r11
+000000b0 @IC+1@869c02 @OC@.ne r12,r13,r14
+000000b4 @IC+1@e82202 @OC@.ne r15,r16,r17
+000000b8 @IC+2@49a803 @OC@.p r18,r19,r20
+000000bc @IC+2@ab2e03 @OC@.p r21,r22,r23
+000000c0 @IC+3@0cb404 @OC@.n r24,r25,r26
+000000c4 @IC+3@6e3a04 @OC@.n fp,sp,ilink1
+000000c8 @IC+3@cfc005 @OC@.c ilink2,blink,r32
+000000cc @IC+4@314605 @OC@.c r33,r34,r35
+000000d0 @IC+4@92cc05 @OC@.c r36,r37,r38
+000000d4 @IC+4@f45206 @OC@.nc r39,r40,r41
+000000d8 @IC+5@55d806 @OC@.nc r42,r43,r44
+000000dc @IC+5@b75e06 @OC@.nc r45,r46,r47
+000000e0 @IC+6@18e407 @OC@.v r48,r49,r50
+000000e4 @IC+6@7a6a07 @OC@.v r51,r52,r53
+000000e8 @IC+6@dbf008 @OC@.nv r54,r55,r56
+000000ec @IC+7@3d7608 @OC@.nv r57,r58,r59
+000000f0 @IC+7@9e0009 @OC@.gt lp_count,lp_count,r0
+000000f4 @IC+0@007c0a @OC@.ge r0,r0,0
+000000fc @IC+0@3f020b @OC@.lt r1,1,r1
+00000104 @IC+7@c0840c @OC@.le 2,r1,r2
+0000010c @IC+0@7f060d @OC@.hi r3,3,r3
+00000114 @IC+7@df080e @OC@.ls 4,4,r4
+0000011c @IC+7@c2fc0f @OC@.pnz 5,r5,5
+00000124 @IC+0@008500 @OC@.f r0,r1,r2
+00000128 @IC+0@00fa01 @OC@.f r0,r1,1
+0000012c @IC+0@1e8401 @OC@.f r0,1,r2
+00000130 @IC+7@a08400 @OC@.f 0,r1,r2
+00000134 @IC+0@00fd00 @OC@.f r0,r1,512
+0000013c @IC+0@1f0500 @OC@.f r0,512,r2
+00000144 @IC+7@c08500 @OC@.f 512,r1,r2
+0000014c @IC+0@008501 @OC@.eq.f r0,r1,r2
+00000150 @IC+0@00fd02 @OC@.ne.f r0,r1,0
+00000158 @IC+0@1f050b @OC@.lt.f r0,0,r2
+00000160 @IC+7@c08509 @OC@.gt.f 0,r1,r2
+00000168 @IC+0@00fd0c @OC@.le.f r0,r1,512
+00000170 @IC+0@1f050a @OC@.ge.f r0,512,r2
+00000178 @IC+7@c08504 @OC@.n.f 512,r1,r2
diff --git a/gas/testsuite/gas/arc/math.s b/gas/testsuite/gas/arc/math.s
new file mode 100644
index 00000000000..775169a8a50
--- /dev/null
+++ b/gas/testsuite/gas/arc/math.s
@@ -0,0 +1,89 @@
+# @OC@ test
+
+# Stay away from operands with duplicate arguments (eg: add r0,r1,r1).
+# They will be disassembled as they're macro counterparts (eg: asl r0,r1).
+
+# reg,reg,reg
+ @OC@ r0,r1,r2
+ @OC@ r26,fp,sp
+ @OC@ ilink1,ilink2,blink
+ @OC@ r58,r59,lp_count
+
+# shimm values
+ @OC@ r0,r1,0
+ @OC@ r0,0,r2
+ @OC@ 0,r1,r2
+ @OC@ r0,r1,-1
+ @OC@ r0,-1,r2
+ @OC@ -1,r1,r2
+ @OC@ r0,r1,255
+ @OC@ r0,255,r2
+ @OC@ 255,r1,r2
+ @OC@ r0,r1,-256
+ @OC@ r0,-256,r2
+ @OC@ -256,r1,r2
+
+# limm values
+ @OC@ r0,r1,256
+ @OC@ r0,-257,r2
+ @OC@ 511,r1,r2
+ @OC@ r0,0x42424242,r2
+ @OC@ 0x12345678,r1,0x12345678
+
+# shimm and limm
+ @OC@ r0,255,256
+ @OC@ r0,256,255
+ @OC@ 255,r1,256
+ @OC@ 255,256,r2
+ @OC@ 256,r1,255
+ @OC@ 256,255,r2
+
+# symbols
+ @OC@ r0,r1,foo
+
+# conditional execution
+ @OC@.al r0,r1,r2
+ @OC@.ra r3,r4,r5
+ @OC@.eq r6,r7,r8
+ @OC@.z r9,r10,r11
+ @OC@.ne r12,r13,r14
+ @OC@.nz r15,r16,r17
+ @OC@.pl r18,r19,r20
+ @OC@.p r21,r22,r23
+ @OC@.mi r24,r25,r26
+ @OC@.n r27,r28,r29
+ @OC@.cs r30,r31,r32
+ @OC@.c r33,r34,r35
+ @OC@.lo r36,r37,r38
+ @OC@.cc r39,r40,r41
+ @OC@.nc r42,r43,r44
+ @OC@.hs r45,r46,r47
+ @OC@.vs r48,r49,r50
+ @OC@.v r51,r52,r53
+ @OC@.vc r54,r55,r56
+ @OC@.nv r57,r58,r59
+ @OC@.gt r60,r60,r0
+ @OC@.ge r0,r0,0
+ @OC@.lt r1,1,r1
+ @OC@.le 2,r1,r2
+ @OC@.hi r3,3,r3
+ @OC@.ls 4,4,r4
+ @OC@.pnz 5,r5,5
+
+# flag setting
+ @OC@.f r0,r1,r2
+ @OC@.f r0,r1,1
+ @OC@.f r0,1,r2
+ @OC@.f 0,r1,r2
+ @OC@.f r0,r1,512
+ @OC@.f r0,512,r2
+ @OC@.f 512,r1,r2
+
+# conditional execution + flag setting
+ @OC@.eq.f r0,r1,r2
+ @OC@.ne.f r0,r1,0
+ @OC@.lt.f r0,0,r2
+ @OC@.gt.f 0,r1,r2
+ @OC@.le.f r0,r1,512
+ @OC@.ge.f r0,512,r2
+ @OC@.n.f 512,r1,r2
diff --git a/gas/testsuite/gas/arc/sshift.d b/gas/testsuite/gas/arc/sshift.d
new file mode 100644
index 00000000000..c0207a77a4b
--- /dev/null
+++ b/gas/testsuite/gas/arc/sshift.d
@@ -0,0 +1,44 @@
+#objdump: -dr
+#name: @OC@
+
+# Test the @OC@ insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 1800@I3+80@00 @OC@ r0,r1
+00000004 1b6e@I3+00@00 @OC@ fp,sp
+00000008 181f@I3+80@00 @OC@ r0,0
+0000000c 183f@I3+81@ff @OC@ r1,-1
+00000010 1fe1@I3+00@00 @OC@ 0,r2
+00000014 1fe1@I3+81@ff @OC@ -1,r3
+00000018 189f@I3+80@ff @OC@ r4,255
+0000001c 1fe2@I3+80@ff @OC@ 255,r5
+00000020 18df@I3+81@00 @OC@ r6,-256
+00000024 1fe3@I3+81@00 @OC@ -256,r7
+00000028 191f@I3+00@00 @OC@ r8,256
+00000030 193f@I3+00@00 @OC@ r9,-257
+00000038 1fc5@I3+00@00 @OC@ 511,r10
+00000040 197f@I3+00@00 @OC@ r11,1111638594
+00000048 1fc6@I3+00@00 @OC@ 305419896,r12
+00000050 1fff@I3+00@ff @OC@ 255,256
+00000058 1fdf@I3+80@ff @OC@ 256,255
+00000060 181f@I3+00@00 @OC@ r0,0
+ RELOC: 00000064 R_ARC_32 foo
+00000068 1945@I3+80@01 @OC@.eq r10,r11
+0000006c 1986@I3+80@02 @OC@.ne r12,r13
+00000070 19df@I3+00@0b @OC@.lt r14,0
+00000078 19ff@I3+00@09 @OC@.gt r15,512
+00000080 1800@I3+81@00 @OC@.f r0,r1
+00000084 185e@I3+80@01 @OC@.f r2,1
+00000088 1fa2@I3+00@00 @OC@.f 0,r4
+0000008c 18bf@I3+01@00 @OC@.f r5,512
+00000094 1fc3@I3+01@00 @OC@.f 512,r6
+0000009c 1fdf@I3+01@00 @OC@.f 512,512
+000000a4 1800@I3+81@01 @OC@.eq.f r0,r1
+000000a8 183f@I3+01@02 @OC@.ne.f r1,0
+000000b0 1fc1@I3+01@0b @OC@.lt.f 0,r2
+000000b8 1fc1@I3+01@09 @OC@.gt.f 1,r2
+000000c0 181f@I3+01@0c @OC@.le.f r0,512
+000000c8 1fc1@I3+01@0a @OC@.ge.f 512,r2
+000000d0 1fdf@I3+01@04 @OC@.n.f 512,512
diff --git a/gas/testsuite/gas/arc/sshift.s b/gas/testsuite/gas/arc/sshift.s
new file mode 100644
index 00000000000..e2fa661fa5c
--- /dev/null
+++ b/gas/testsuite/gas/arc/sshift.s
@@ -0,0 +1,52 @@
+# Single shift @OC@ test
+
+# reg,reg
+ @OC@ r0,r1
+ @OC@ fp,sp
+
+# shimm values
+ @OC@ r0,0
+ @OC@ r1,-1
+ @OC@ 0,r2
+ @OC@ -1,r3
+ @OC@ r4,255
+ @OC@ 255,r5
+ @OC@ r6,-256
+ @OC@ -256,r7
+
+# limm values
+ @OC@ r8,256
+ @OC@ r9,-257
+ @OC@ 511,r10
+ @OC@ r11,0x42424242
+ @OC@ 0x12345678,r12
+
+# shimm and limm
+ @OC@ 255,256
+ @OC@ 256,255
+
+# symbols
+ @OC@ r0,foo
+
+# conditional execution
+ @OC@.eq r10,r11
+ @OC@.ne r12,r13
+ @OC@.lt r14,0
+ @OC@.gt r15,512
+
+# flag setting
+ @OC@.f r0,r1
+ @OC@.f r2,1
+ @OC@.f 0,r4
+ @OC@.f r5,512
+ @OC@.f 512,r6
+ @OC@.f 512,512
+
+# conditional execution + flag setting
+ @OC@.eq.f r0,r1
+ @OC@.ne.f r1,0
+ @OC@.lt.f 0,r2
+ @OC@.gt.f 1,r2
+ @OC@.le.f r0,512
+ @OC@.ge.f 512,r2
+ @OC@.n.f 512,512
diff --git a/gas/testsuite/gas/arc/st.d b/gas/testsuite/gas/arc/st.d
new file mode 100644
index 00000000000..cca99a83394
--- /dev/null
+++ b/gas/testsuite/gas/arc/st.d
@@ -0,0 +1,25 @@
+#objdump: -dr
+#name: st/sr
+
+# Test the st/sr insn.
+
+.*: +file format elf32-.*arc
+
+Disassembly of section .text:
+00000000 10008000 st r0,\[r1\]
+00000004 10030a01 st r5,\[r6,1\]
+00000008 10040fff st r7,\[r8,-1\]
+0000000c 100512ff st r9,\[r10,255\]
+00000010 10061700 st r11,\[r12,-256\]
+00000014 101f2600 st r19,\[0\]
+ RELOC: 00000018 R_ARC_32 foo
+0000001c 101f2800 st r20,\[4\]
+ RELOC: 00000020 R_ARC_32 foo
+00000024 105f0000 stb r0,\[0\]
+0000002c 109f0000 stw r0,\[0\]
+00000034 111f0000 st.a r0,\[0\]
+0000003c 141f0000 st.di r0,\[0\]
+00000044 15400000 stb.a.di r0,\[r0\]
+00000048 12008000 sr r0,\[r1\]
+0000004c 121f8400 sr r2,\[status\]
+00000050 121f0600 sr r3,\[305419896\]
diff --git a/gas/testsuite/gas/arc/st.s b/gas/testsuite/gas/arc/st.s
new file mode 100644
index 00000000000..10af198a787
--- /dev/null
+++ b/gas/testsuite/gas/arc/st.s
@@ -0,0 +1,19 @@
+# st/sr test
+
+ st r0,[r1]
+ st r5,[r6,1]
+ st r7,[r8,-1]
+ st r9,[r10,255]
+ st r11,[r12,-256]
+ st r19,[foo]
+ st r20,[foo+4]
+
+ stb r0,[0]
+ stw r0,[0]
+ st.a r0,[0]
+ st.di r0,[0]
+ stb.a.di r0,[r0]
+
+ sr r0,[r1]
+ sr r2,[status]
+ sr r3,[0x12345678]
diff --git a/gas/testsuite/gas/arc/warn.exp b/gas/testsuite/gas/arc/warn.exp
new file mode 100644
index 00000000000..79ff1263d5e
--- /dev/null
+++ b/gas/testsuite/gas/arc/warn.exp
@@ -0,0 +1,13 @@
+# Test assembler warnings.
+
+if [istarget arc*-*-*] {
+
+ load_lib gas-dg.exp
+
+ dg-init
+
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/warn*.s]] "" ""
+
+ dg-finish
+
+}
diff --git a/gas/testsuite/gas/arc/warn.s b/gas/testsuite/gas/arc/warn.s
new file mode 100644
index 00000000000..6fcb43725fa
--- /dev/null
+++ b/gas/testsuite/gas/arc/warn.s
@@ -0,0 +1,14 @@
+; Test ARC specific assembler warnings
+;
+; { dg-do assemble { target arc-*-* } }
+
+ b.d foo
+ mov r0,256 ; { dg-warning "8 byte instruction in delay slot" "8 byte insn in delay slot" }
+
+ j.d foo ; { dg-warning "8 byte jump instruction with delay slot" "8 byte jump with delay slot" }
+ mov r0,r1
+
+ sub.f 0,r0,r2
+ beq foo ; { dg-warning "conditional branch follows set of flags" "cc set/branch nop test" }
+
+foo:
diff --git a/gas/testsuite/gas/arm/arch4t.s b/gas/testsuite/gas/arm/arch4t.s
new file mode 100644
index 00000000000..8d28f7f3ec1
--- /dev/null
+++ b/gas/testsuite/gas/arm/arch4t.s
@@ -0,0 +1,21 @@
+.text
+.align 0
+
+ bx r0
+ bxeq r1
+
+foo:
+ ldrh r3, foo
+ ldrsh r4, [r5]
+ ldrsb r4, [r1, r3]
+ ldrsh r1, [r4, r4]!
+ ldreqsb r1, [r5, -r3]
+ ldrneh r2, [r6], r7
+ ldrccsh r2, [r7], +r8
+ ldrsb r2, [r3, #255]
+ ldrsh r1, [r4, #-250]
+ ldrsb r1, [r5, #+240]
+
+ strh r2, bar
+ strneh r3, [r3]
+bar:
diff --git a/gas/testsuite/gas/arm/arm.exp b/gas/testsuite/gas/arm/arm.exp
new file mode 100644
index 00000000000..f21c54df310
--- /dev/null
+++ b/gas/testsuite/gas/arm/arm.exp
@@ -0,0 +1,34 @@
+#
+# Some ARM tests
+#
+if [istarget arm-*-*] then {
+ run_dump_test "inst"
+
+ gas_test "arm3.s" "" $stdoptlist "Arm 3 instructions"
+
+ gas_test "arm6.s" "" $stdoptlist "Arm 6 instructions"
+
+ gas_test "arm7dm.s" "" $stdoptlist "Arm 7DM instructions"
+
+ run_dump_test "arm7t"
+
+ gas_test "thumb.s" "" $stdoptlist "Thumb instructions"
+
+ gas_test "arch4t.s" "" $stdoptlist "Arm architecture 4t instructions"
+
+ gas_test "copro.s" "" $stdoptlist "Co processor instructions"
+
+ gas_test "immed.s" "" $stdoptlist "immediate expressions"
+
+ gas_test "float.s" "" $stdoptlist "Core floating point instructions"
+}
+
+# Not all arm targets are bi-endian, so only run this test on ones
+# we know that are. FIXME: We should probably also key off armeb/armel.
+
+if [istarget arm-*-pe] {
+ run_dump_test "le-fpconst"
+
+ # Since big-endian numbers have the normal format, this doesn't exist.
+ #run_dump_test "be-fpconst"
+}
diff --git a/gas/testsuite/gas/arm/arm3.s b/gas/testsuite/gas/arm/arm3.s
new file mode 100644
index 00000000000..ebcf915ccb1
--- /dev/null
+++ b/gas/testsuite/gas/arm/arm3.s
@@ -0,0 +1,6 @@
+.text
+.align 0
+ swp r0, r1, [r8]
+ swpb r2, r3, [r3]
+ swpgeb r4, r1, [r4]
+
diff --git a/gas/testsuite/gas/arm/arm6.s b/gas/testsuite/gas/arm/arm6.s
new file mode 100644
index 00000000000..4b517129c62
--- /dev/null
+++ b/gas/testsuite/gas/arm/arm6.s
@@ -0,0 +1,12 @@
+.text
+.align 0
+
+ mrs r8, cpsr
+ mrseq r9, cpsr_all
+ mrs r2, spsr
+
+ msr cpsr, r1
+ msrne cpsr_flg, #0xf0000000
+ msr spsr_flg, r8
+ msr spsr_all, r9
+
diff --git a/gas/testsuite/gas/arm/arm7dm.s b/gas/testsuite/gas/arm/arm7dm.s
new file mode 100644
index 00000000000..7496c70e987
--- /dev/null
+++ b/gas/testsuite/gas/arm/arm7dm.s
@@ -0,0 +1,12 @@
+.text
+.align 0
+
+ smull r0, r1, r2, r3
+ umull r0, r1, r2, r3
+ smlal r0, r1, r2, r3
+ umlal r0, r1, r4, r3
+
+ smullne r0, r1, r3, r4
+ smulls r1, r0, r9, r11
+ umlaleqs r2, r9, r4, r9
+ smlalge r14, r10, r8, r14
diff --git a/gas/testsuite/gas/arm/arm7t.d b/gas/testsuite/gas/arm/arm7t.d
new file mode 100644
index 00000000000..143a161cd29
--- /dev/null
+++ b/gas/testsuite/gas/arm/arm7t.d
@@ -0,0 +1,68 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: ARM arm7t
+#as: -marm7t -EL
+
+# Test the halfword and signextend memory transfers:
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <[^>]*> e1d100b0 ? ldrh r0, \[r1\]
+00000004 <[^>]*> e1f100b0 ? ldrh r0, \[r1\]!
+00000008 <[^>]*> e19100b2 ? ldrh r0, \[r1, r2\]
+0000000c <[^>]*> e1b100b2 ? ldrh r0, \[r1, r2\]!
+00000010 <[^>]*> e1d100bc ? ldrh r0, \[r1, #12\]
+00000014 <[^>]*> e1f100bc ? ldrh r0, \[r1, #12\]!
+00000018 <[^>]*> e15100bc ? ldrh r0, \[r1, -#12\]
+0000001c <[^>]*> e09100b2 ? ldrh r0, \[r1\], r2
+00000020 <[^>]*> e3a00cff ? mov r0, #65280
+00000024 <[^>]*> e1df0bb4 ? ldrh r0, 000000e0 <\$\$lit_1>
+00000028 <[^>]*> e1df0abc ? ldrh r0, 000000dc <.L2>
+0000002c <[^>]*> e1c100b0 ? strh r0, \[r1\]
+00000030 <[^>]*> e1e100b0 ? strh r0, \[r1\]!
+00000034 <[^>]*> e18100b2 ? strh r0, \[r1, r2\]
+00000038 <[^>]*> e1a100b2 ? strh r0, \[r1, r2\]!
+0000003c <[^>]*> e1c100bc ? strh r0, \[r1, #12\]
+00000040 <[^>]*> e1e100bc ? strh r0, \[r1, #12\]!
+00000044 <[^>]*> e14100bc ? strh r0, \[r1, -#12\]
+00000048 <[^>]*> e08100b2 ? strh r0, \[r1\], r2
+0000004c <[^>]*> e1cf08b8 ? strh r0, 000000dc <.L2>
+00000050 <[^>]*> e1d100d0 ? ldrsb r0, \[r1\]
+00000054 <[^>]*> e1f100d0 ? ldrsb r0, \[r1\]!
+00000058 <[^>]*> e19100d2 ? ldrsb r0, \[r1, r2\]
+0000005c <[^>]*> e1b100d2 ? ldrsb r0, \[r1, r2\]!
+00000060 <[^>]*> e1d100dc ? ldrsb r0, \[r1, #12\]
+00000064 <[^>]*> e1f100dc ? ldrsb r0, \[r1, #12\]!
+00000068 <[^>]*> e15100dc ? ldrsb r0, \[r1, -#12\]
+0000006c <[^>]*> e09100d2 ? ldrsb r0, \[r1\], r2
+00000070 <[^>]*> e3a000de ? mov r0, #222
+00000074 <[^>]*> e1df06d0 ? ldrsb r0, 000000dc <.L2>
+00000078 <[^>]*> e1d100f0 ? ldrsh r0, \[r1\]
+0000007c <[^>]*> e1f100f0 ? ldrsh r0, \[r1\]!
+00000080 <[^>]*> e19100f2 ? ldrsh r0, \[r1, r2\]
+00000084 <[^>]*> e1b100f2 ? ldrsh r0, \[r1, r2\]!
+00000088 <[^>]*> e1d100fc ? ldrsh r0, \[r1, #12\]
+0000008c <[^>]*> e1f100fc ? ldrsh r0, \[r1, #12\]!
+00000090 <[^>]*> e15100fc ? ldrsh r0, \[r1, -#12\]
+00000094 <[^>]*> e09100f2 ? ldrsh r0, \[r1\], r2
+00000098 <[^>]*> e3a00cff ? mov r0, #65280
+0000009c <[^>]*> e1df03fc ? ldrsh r0, 000000e0 <\$\$lit_1>
+000000a0 <[^>]*> e1df03f4 ? ldrsh r0, 000000dc <.L2>
+000000a4 <[^>]*> e19100b2 ? ldrh r0, \[r1, r2\]
+000000a8 <[^>]*> 119100b2 ? ldrneh r0, \[r1, r2\]
+000000ac <[^>]*> 819100b2 ? ldrhih r0, \[r1, r2\]
+000000b0 <[^>]*> b19100b2 ? ldrlth r0, \[r1, r2\]
+000000b4 <[^>]*> e19100f2 ? ldrsh r0, \[r1, r2\]
+000000b8 <[^>]*> 119100f2 ? ldrnesh r0, \[r1, r2\]
+000000bc <[^>]*> 819100f2 ? ldrhish r0, \[r1, r2\]
+000000c0 <[^>]*> b19100f2 ? ldrltsh r0, \[r1, r2\]
+000000c4 <[^>]*> e19100d2 ? ldrsb r0, \[r1, r2\]
+000000c8 <[^>]*> 119100d2 ? ldrnesb r0, \[r1, r2\]
+000000cc <[^>]*> 819100d2 ? ldrhisb r0, \[r1, r2\]
+000000d0 <[^>]*> b19100d2 ? ldrltsb r0, \[r1, r2\]
+000000d4 <[^>]*> e1df00f4 ? ldrsh r0, 000000e0 <\$\$lit_1>
+000000d8 <[^>]*> e1df00f4 ? ldrsh r0, 000000e4 <\$\$lit_1\+0x4>
+000000dc <[^>]*> 00000000 ? andeq r0, r0, r0
+[ ]*dc:.*.LC0
+000000e0 <[^>]*> 0000c0de ? .*
+000000e4 <[^>]*> 0000dead ? .*
diff --git a/gas/testsuite/gas/arm/arm7t.s b/gas/testsuite/gas/arm/arm7t.s
new file mode 100644
index 00000000000..656e90e0330
--- /dev/null
+++ b/gas/testsuite/gas/arm/arm7t.s
@@ -0,0 +1,79 @@
+ .section .rdata
+ .align 0
+.LC0:
+ .ascii "some data\000"
+
+ .text
+ .align 0
+
+loadhalfwords:
+ ldrh r0, [r1]
+ ldrh r0, [r1]!
+ ldrh r0, [r1, r2]
+ ldrh r0, [r1, r2]!
+ ldrh r0, [r1,#0x0C]
+ ldrh r0, [r1,#0x0C]!
+ ldrh r0, [r1,#-0x0C]
+ ldrh r0, [r1], r2
+ ldrh r0, =0xFF00
+ ldrh r0, =0xC0DE
+ ldrh r0, .L2
+
+storehalfwords:
+ strh r0, [r1]
+ strh r0, [r1]!
+ strh r0, [r1, r2]
+ strh r0, [r1, r2]!
+ strh r0, [r1,#0x0C]
+ strh r0, [r1,#0x0C]!
+ strh r0, [r1,#-0x0C]
+ strh r0, [r1], r2
+ strh r0, .L2
+
+loadsignedbytes:
+ ldrsb r0, [r1]
+ ldrsb r0, [r1]!
+ ldrsb r0, [r1, r2]
+ ldrsb r0, [r1, r2]!
+ ldrsb r0, [r1,#0x0C]
+ ldrsb r0, [r1,#0x0C]!
+ ldrsb r0, [r1,#-0x0C]
+ ldrsb r0, [r1], r2
+ ldrsb r0, =0xDE
+ ldrsb r0, .L2
+
+loadsignedhalfwords:
+ ldrsh r0, [r1]
+ ldrsh r0, [r1]!
+ ldrsh r0, [r1, r2]
+ ldrsh r0, [r1, r2]!
+ ldrsh r0, [r1, #0x0C]
+ ldrsh r0, [r1, #0x0C]!
+ ldrsh r0, [r1, #-0x0C]
+ ldrsh r0, [r1], r2
+ ldrsh r0, =0xFF00
+ ldrsh r0, =0xC0DE
+ ldrsh r0, .L2
+
+misc:
+ ldralh r0, [r1, r2]
+ ldrneh r0, [r1, r2]
+ ldrhih r0, [r1, r2]
+ ldrlth r0, [r1, r2]
+
+ ldralsh r0, [r1, r2]
+ ldrnesh r0, [r1, r2]
+ ldrhish r0, [r1, r2]
+ ldrltsh r0, [r1, r2]
+
+ ldralsb r0, [r1, r2]
+ ldrnesb r0, [r1, r2]
+ ldrhisb r0, [r1, r2]
+ ldrltsb r0, [r1, r2]
+
+ ldrsh r0, =0xC0DE
+ ldrsh r0, =0xDEAD
+
+ .align
+.L2:
+ .word .LC0
diff --git a/gas/testsuite/gas/arm/copro.s b/gas/testsuite/gas/arm/copro.s
new file mode 100644
index 00000000000..46c9b920df0
--- /dev/null
+++ b/gas/testsuite/gas/arm/copro.s
@@ -0,0 +1,24 @@
+.text
+.align 0
+ cdp p1, 4, cr1, cr2, cr3
+ cdpeq 4, 3, c1, c4, cr5, 5
+
+ ldc 5, cr9, [r3]
+ ldcl 1, cr14, [r1, #32]
+ ldcmi 0, cr0, [r2, #1020]!
+ ldcpll p7, c1, [r3], #64
+ ldc p0, c8, foo
+foo:
+
+ stc 5, cr0, [r3]
+ stcl 3, cr15, [r0, #8]
+ stceq p4, cr12, [r2, #100]!
+ stccc p6, c8, [r4], #48
+ stc p1, c7, bar
+bar:
+
+ mrc 2, 3, r5, c1, c2
+ mrcge p4, 5, r15, cr1, cr2, 7
+
+ mcr p7, 1, r15, cr1, cr1
+ mcrlt 5, 1, r8, cr2, cr9, 0
diff --git a/gas/testsuite/gas/arm/float.s b/gas/testsuite/gas/arm/float.s
new file mode 100644
index 00000000000..48aee965cb2
--- /dev/null
+++ b/gas/testsuite/gas/arm/float.s
@@ -0,0 +1,162 @@
+.text
+.align 0
+ mvfe f0, f1
+ mvfeqe f3, f5
+ mvfeqd f4, #1.0
+ mvfs f4, f7
+ mvfsp f0, f1
+ mvfdm f3, f4
+ mvfez f7, f7
+
+ adfe f0, f1, #2.0
+ adfeqe f1, f2, #0.5
+ adfsm f3, f4, f5
+
+ sufd f0, f0, #2.0
+ sufs f1, f2, #10.0
+ sufneez f3, f4, f5
+
+ rsfs f1, f1, #0.0
+ rsfdp f3, f0, #5.0
+ rsfled f7, f6, f0
+
+ mufd f0, f0, f0
+ mufez f1, f2, #3.0
+ mufals f0, f0, #4.0
+
+ dvfd f0, f0, #1.0000
+ dvfez f0, f1, #10e0
+ dvfmism f3, f4, f5
+
+ rdfe f0, f1, #1.0e1
+ rdfs f3, f7, #0f1
+ rdfccdp f4, f4, f3
+
+ powd f0, f2, f3
+ pows f1, f3, #0e1e1
+ powcsez f4, f7, #1
+
+ rpws f7, f6, f7
+ rpweqd f0, f1, f2
+ rpwem f2, f2, f3
+
+ rmfd f1, f2, #3
+ rmfvss f3, f4, f4
+ rmfep f4, f7, f0
+
+ fmls f0, f1, f2
+ fmleqs f1, f3, f5
+ fmlplsz f4, f6, f0
+
+ fdvs f1, f3, #10
+ fdvsp f0, f1, f2
+ fdvhssm f4, f4, f4
+
+ frds f1, f1, #1.0
+ frdgts f2, f1, f0
+ frdgtsz f4, f4, f5
+
+ pold f0, f1, f2
+ polsz f4, f6, #3.0
+ poleqe f5, f6, f7
+
+ mnfs f0, f1
+ mnfd f0, #3.0
+ mnfez f0, #4.0
+ mnfeqez f0, f5
+ mnfsp f0, f4
+ mnfdm f1, f7
+
+ absd f0, f1
+ abssp f1, #3.0
+ abseqe f4, f5
+
+ rnds f1, f2
+ rndd f3, f4
+ rndeqez f6, #4.0
+
+ sqts f5, f5
+ sqtdp f6, f6
+ sqtplez f7, f6
+
+ logs f0, #10
+ loge f0, #0f10
+ lognedz f0, f1
+
+ lgne f1, f2
+ lgndz f1, f3
+ lgnvcs f3, f4
+
+ exps f1, f3
+ expem f3, #10.0
+ exppld f6, f7
+
+ sind f0, f1
+ sinsm f1, f2
+ singte f4, #5
+
+ cosd f1, f3
+ cosem f4, f5
+ cosnedp f6, f1
+
+ tane f1, f5
+ tansz f4, f7
+ tangedz f1, #4.0
+
+ asne f4, f5
+ asnsp f6, #5e-1
+ asnmidz f5, f5
+
+ acss f5, f6
+ acsd f6, f0
+ acshsem f1, #0.05e1
+
+ atne f0, f5
+ atnsz f1, #5
+ atnltd f3, f2
+
+ urde f5, f4
+ nrme f6, f5
+ nrmpldz f7, f5
+
+ fltsp f0, r8
+ flte f1, r0
+ flteqdz f5, r7
+
+ fix r0, f1
+ fixz r1, f7
+ fixcsm r5, f5
+
+ wfc r0
+ wfs r1
+ rfseq r2
+ rfc r4
+
+ cmf f0, #1
+ cmf f1, f2
+ cmfeq f0, f1
+
+ cnf f0, #3
+ cnf f1, #0.5
+ cnfvs f3, f4
+
+ cmfe f0, f1
+ cmfeeq f1, f2
+ cmfeqe f3, #5.0
+
+ cnfe f1, f3
+ cnfeeq f3, f4
+ cnfeqe f4, f7
+ cnfale f4, #5.0
+
+ lfm f0, 4, [r0]
+ lfm f0, 4, [r0, #0]
+ lfm f1, 4, [r1, #64]
+ sfm f2, 4, [r14, #1020]!
+ sfmeq f7, 3, [r8], #-1020
+
+ lfmfd f6, 2, [r15]
+ sfmea f7, 1, [r8]!
+ lfmeqea f5, 4, [r6]
+ sfmnefd f4, 3, [r2]
+ sfmnefd f4, 3, [r2]!
diff --git a/gas/testsuite/gas/arm/immed.s b/gas/testsuite/gas/arm/immed.s
new file mode 100644
index 00000000000..5d2092be18b
--- /dev/null
+++ b/gas/testsuite/gas/arm/immed.s
@@ -0,0 +1,11 @@
+@ Tests for complex immediate expressions - none of these need
+@ relocations
+ .text
+bar:
+ mov r0, #0
+ mov r0, #(. - bar - 8)
+ ldr r0, bar
+ ldr r0, [pc, # (bar - . -8)]
+ .space 4096
+ mov r0, #(. - bar - 8) & 0xff
+ ldr r0, [pc, # (bar - . -8) & 0xff]
diff --git a/gas/testsuite/gas/arm/inst.d b/gas/testsuite/gas/arm/inst.d
new file mode 100644
index 00000000000..decb8f01b76
--- /dev/null
+++ b/gas/testsuite/gas/arm/inst.d
@@ -0,0 +1,168 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: ARM basic instructions
+#as: -marm2 -EL
+
+# Test the standard ARM instructions:
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00000000 <[^>]*> e3a00000 ? mov r0, #0
+00000004 <[^>]*> e1a01002 ? mov r1, r2
+00000008 <[^>]*> e1a03184 ? mov r3, r4, lsl #3
+0000000c <[^>]*> e1a05736 ? mov r5, r6, lsr r7
+00000010 <[^>]*> e1a08a59 ? mov r8, r9, asr sl
+00000014 <[^>]*> e1a0bd1c ? mov fp, ip, lsl sp
+00000018 <[^>]*> e1a0e06f ? mov lr, pc, rrx
+0000001c <[^>]*> e1a01002 ? mov r1, r2
+00000020 <[^>]*> 01a02003 ? moveq r2, r3
+00000024 <[^>]*> 11a04005 ? movne r4, r5
+00000028 <[^>]*> b1a06007 ? movlt r6, r7
+0000002c <[^>]*> a1a08009 ? movge r8, r9
+00000030 <[^>]*> d1a0a00b ? movle sl, fp
+00000034 <[^>]*> c1a0c00d ? movgt ip, sp
+00000038 <[^>]*> 31a01002 ? movcc r1, r2
+0000003c <[^>]*> 21a01003 ? movcs r1, r3
+00000040 <[^>]*> 41a03006 ? movmi r3, r6
+00000044 <[^>]*> 51a07009 ? movpl r7, r9
+00000048 <[^>]*> 61a01008 ? movvs r1, r8
+0000004c <[^>]*> 71a09fa1 ? movvc r9, r1, lsr #31
+00000050 <[^>]*> 81a0800f ? movhi r8, pc
+00000054 <[^>]*> 91a0f00e ? movls pc, lr
+00000058 <[^>]*> 21a09008 ? movcs r9, r8
+0000005c <[^>]*> 31a01003 ? movcc r1, r3
+00000060 <[^>]*> e1b00008 ? movs r0, r8
+00000064 <[^>]*> 31b00007 ? movccs r0, r7
+00000068 <[^>]*> e281000a ? add r0, r1, #10
+0000006c <[^>]*> e0832004 ? add r2, r3, r4
+00000070 <[^>]*> e0865287 ? add r5, r6, r7, lsl #5
+00000074 <[^>]*> e0821113 ? add r1, r2, r3, lsl r1
+00000078 <[^>]*> e201000a ? and r0, r1, #10
+0000007c <[^>]*> e0032004 ? and r2, r3, r4
+00000080 <[^>]*> e0065287 ? and r5, r6, r7, lsl #5
+00000084 <[^>]*> e0021113 ? and r1, r2, r3, lsl r1
+00000088 <[^>]*> e221000a ? eor r0, r1, #10
+0000008c <[^>]*> e0232004 ? eor r2, r3, r4
+00000090 <[^>]*> e0265287 ? eor r5, r6, r7, lsl #5
+00000094 <[^>]*> e0221113 ? eor r1, r2, r3, lsl r1
+00000098 <[^>]*> e241000a ? sub r0, r1, #10
+0000009c <[^>]*> e0432004 ? sub r2, r3, r4
+000000a0 <[^>]*> e0465287 ? sub r5, r6, r7, lsl #5
+000000a4 <[^>]*> e0421113 ? sub r1, r2, r3, lsl r1
+000000a8 <[^>]*> e2a1000a ? adc r0, r1, #10
+000000ac <[^>]*> e0a32004 ? adc r2, r3, r4
+000000b0 <[^>]*> e0a65287 ? adc r5, r6, r7, lsl #5
+000000b4 <[^>]*> e0a21113 ? adc r1, r2, r3, lsl r1
+000000b8 <[^>]*> e2c1000a ? sbc r0, r1, #10
+000000bc <[^>]*> e0c32004 ? sbc r2, r3, r4
+000000c0 <[^>]*> e0c65287 ? sbc r5, r6, r7, lsl #5
+000000c4 <[^>]*> e0c21113 ? sbc r1, r2, r3, lsl r1
+000000c8 <[^>]*> e261000a ? rsb r0, r1, #10
+000000cc <[^>]*> e0632004 ? rsb r2, r3, r4
+000000d0 <[^>]*> e0665287 ? rsb r5, r6, r7, lsl #5
+000000d4 <[^>]*> e0621113 ? rsb r1, r2, r3, lsl r1
+000000d8 <[^>]*> e2e1000a ? rsc r0, r1, #10
+000000dc <[^>]*> e0e32004 ? rsc r2, r3, r4
+000000e0 <[^>]*> e0e65287 ? rsc r5, r6, r7, lsl #5
+000000e4 <[^>]*> e0e21113 ? rsc r1, r2, r3, lsl r1
+000000e8 <[^>]*> e381000a ? orr r0, r1, #10
+000000ec <[^>]*> e1832004 ? orr r2, r3, r4
+000000f0 <[^>]*> e1865287 ? orr r5, r6, r7, lsl #5
+000000f4 <[^>]*> e1821113 ? orr r1, r2, r3, lsl r1
+000000f8 <[^>]*> e3c1000a ? bic r0, r1, #10
+000000fc <[^>]*> e1c32004 ? bic r2, r3, r4
+00000100 <[^>]*> e1c65287 ? bic r5, r6, r7, lsl #5
+00000104 <[^>]*> e1c21113 ? bic r1, r2, r3, lsl r1
+00000108 <[^>]*> e3e0000a ? mvn r0, #10
+0000010c <[^>]*> e1e02004 ? mvn r2, r4
+00000110 <[^>]*> e1e05287 ? mvn r5, r7, lsl #5
+00000114 <[^>]*> e1e01113 ? mvn r1, r3, lsl r1
+00000118 <[^>]*> e310000a ? tst r0, #10
+0000011c <[^>]*> e1120004 ? tst r2, r4
+00000120 <[^>]*> e1150287 ? tst r5, r7, lsl #5
+00000124 <[^>]*> e1110113 ? tst r1, r3, lsl r1
+00000128 <[^>]*> e330000a ? teq r0, #10
+0000012c <[^>]*> e1320004 ? teq r2, r4
+00000130 <[^>]*> e1350287 ? teq r5, r7, lsl #5
+00000134 <[^>]*> e1310113 ? teq r1, r3, lsl r1
+00000138 <[^>]*> e350000a ? cmp r0, #10
+0000013c <[^>]*> e1520004 ? cmp r2, r4
+00000140 <[^>]*> e1550287 ? cmp r5, r7, lsl #5
+00000144 <[^>]*> e1510113 ? cmp r1, r3, lsl r1
+00000148 <[^>]*> e370000a ? cmn r0, #10
+0000014c <[^>]*> e1720004 ? cmn r2, r4
+00000150 <[^>]*> e1750287 ? cmn r5, r7, lsl #5
+00000154 <[^>]*> e1710113 ? cmn r1, r3, lsl r1
+00000158 <[^>]*> e330f00a ? teqp r0, #10
+0000015c <[^>]*> e132f004 ? teqp r2, r4
+00000160 <[^>]*> e135f287 ? teqp r5, r7, lsl #5
+00000164 <[^>]*> e131f113 ? teqp r1, r3, lsl r1
+00000168 <[^>]*> e370f00a ? cmnp r0, #10
+0000016c <[^>]*> e172f004 ? cmnp r2, r4
+00000170 <[^>]*> e175f287 ? cmnp r5, r7, lsl #5
+00000174 <[^>]*> e171f113 ? cmnp r1, r3, lsl r1
+00000178 <[^>]*> e350f00a ? cmpp r0, #10
+0000017c <[^>]*> e152f004 ? cmpp r2, r4
+00000180 <[^>]*> e155f287 ? cmpp r5, r7, lsl #5
+00000184 <[^>]*> e151f113 ? cmpp r1, r3, lsl r1
+00000188 <[^>]*> e310f00a ? tstp r0, #10
+0000018c <[^>]*> e112f004 ? tstp r2, r4
+00000190 <[^>]*> e115f287 ? tstp r5, r7, lsl #5
+00000194 <[^>]*> e111f113 ? tstp r1, r3, lsl r1
+00000198 <[^>]*> e0000291 ? mul r0, r1, r2
+0000019c <[^>]*> e0110392 ? muls r1, r2, r3
+000001a0 <[^>]*> 10000091 ? mulne r0, r1, r0
+000001a4 <[^>]*> 90190798 ? mullss r9, r8, r7
+000001a8 <[^>]*> e021ba99 ? mla r1, r9, sl, fp
+000001ac <[^>]*> e033c994 ? mlas r3, r4, r9, ip
+000001b0 <[^>]*> b029d798 ? mlalt r9, r8, r7, sp
+000001b4 <[^>]*> a034e391 ? mlages r4, r1, r3, lr
+000001b8 <[^>]*> e5910000 ? ldr r0, \[r1\]
+000001bc <[^>]*> e7911002 ? ldr r1, \[r1, r2\]
+000001c0 <[^>]*> e7b32004 ? ldr r2, \[r3, r4\]!
+000001c4 <[^>]*> e5922020 ? ldr r2, \[r2, #32\]
+000001c8 <[^>]*> e7932424 ? ldr r2, \[r3, r4, lsr #8\]
+000001cc <[^>]*> 07b54484 ? ldreq r4, \[r5, r4, lsl #9\]!
+000001d0 <[^>]*> 14954006 ? ldrne r4, \[r5\], #6
+000001d4 <[^>]*> e6b21003 ? ldrt r1, \[r2\], r3
+000001d8 <[^>]*> e6942425 ? ldr r2, \[r4\], r5, lsr #8
+000001dc <[^>]*> e51f0008 ? ldr r0, 000001dc <[^>]*>
+000001e0 <[^>]*> e5d43000 ? ldrb r3, \[r4\]
+000001e4 <[^>]*> 14f85000 ? ldrnebt r5, \[r8\]
+000001e8 <[^>]*> e5810000 ? str r0, \[r1\]
+000001ec <[^>]*> e7811002 ? str r1, \[r1, r2\]
+000001f0 <[^>]*> e7a33004 ? str r3, \[r3, r4\]!
+000001f4 <[^>]*> e5822020 ? str r2, \[r2, #32\]
+000001f8 <[^>]*> e7832424 ? str r2, \[r3, r4, lsr #8\]
+000001fc <[^>]*> 07a54484 ? streq r4, \[r5, r4, lsl #9\]!
+00000200 <[^>]*> 14854006 ? strne r4, \[r5\], #6
+00000204 <[^>]*> e6821003 ? str r1, \[r2\], r3
+00000208 <[^>]*> e6a42425 ? strt r2, \[r4\], r5, lsr #8
+0000020c <[^>]*> e50f1004 ? str r1, 00000210 <[^>]*>
+00000210 <[^>]*> e5c71000 ? strb r1, \[r7\]
+00000214 <[^>]*> e4e02000 ? strbt r2, \[r0\]
+00000218 <[^>]*> e8900002 ? ldmia r0, {r1}
+0000021c <[^>]*> 09920038 ? ldmeqib r2, {r3, r4, r5}
+00000220 <[^>]*> e853ffff ? ldmda r3, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}\^
+00000224 <[^>]*> e93b05ff ? ldmdb fp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sl}
+00000228 <[^>]*> e99100f7 ? ldmib r1, {r0, r1, r2, r4, r5, r6, r7}
+0000022c <[^>]*> e89201f8 ? ldmia r2, {r3, r4, r5, r6, r7, r8}
+00000230 <[^>]*> e9130003 ? ldmdb r3, {r0, r1}
+00000234 <[^>]*> e8740300 ? ldmda r4!, {r8, r9}\^
+00000238 <[^>]*> e8800002 ? stmia r0, {r1}
+0000023c <[^>]*> 09820038 ? stmeqib r2, {r3, r4, r5}
+00000240 <[^>]*> e843ffff ? stmda r3, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}\^
+00000244 <[^>]*> e92a05ff ? stmdb sl!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sl}
+00000248 <[^>]*> e8010007 ? stmda r1, {r0, r1, r2}
+0000024c <[^>]*> e9020018 ? stmdb r2, {r3, r4}
+00000250 <[^>]*> e8830003 ? stmia r3, {r0, r1}
+00000254 <[^>]*> e9e40300 ? stmib r4!, {r8, r9}\^
+00000258 <[^>]*> ef123456 ? swi 0x00123456
+0000025c <[^>]*> 2f000033 ? swics 0x00000033
+00000260 <[^>]*> ebfffffe ? bl 00000260 <[^>]*>
+[ ]*260:.*_wombat.*
+00000264 <[^>]*> 5bffffe9 ? blpl 00000210 <bar>
+00000268 <[^>]*> eafffffe ? b 00000268 <[^>]*>
+[ ]*268:.*_wibble.*
+0000026c <[^>]*> dafffffe ? ble 0000026c <[^>]*>
+[ ]*26c:.*testerfunc.*
diff --git a/gas/testsuite/gas/arm/inst.s b/gas/testsuite/gas/arm/inst.s
new file mode 100644
index 00000000000..ff092c9256b
--- /dev/null
+++ b/gas/testsuite/gas/arm/inst.s
@@ -0,0 +1,189 @@
+@ Test file for ARM/GAS -- basic instructions
+
+.text
+.align
+ mov r0, #0
+ mov r1, r2
+ mov r3, r4, lsl #3
+ mov r5, r6, lsr r7
+ mov r8, r9, asr r10
+ mov r11, r12, asl r13
+ mov r14, r15, rrx
+ moval r1, r2
+ moveq r2, r3
+ movne r4, r5
+ movlt r6, r7
+ movge r8, r9
+ movle r10, r11
+ movgt r12, r13
+ movcc r1, r2
+ movcs r1, r3
+ movmi r3, r6
+ movpl r7, r9
+ movvs r1, r8
+ movvc r9, r1, lsr #31
+ movhi r8, r15
+ movls r15, r14
+ movhs r9, r8
+ movul r1, r3
+ movs r0, r8
+ movuls r0, r7
+
+ add r0, r1, #10
+ add r2, r3, r4
+ add r5, r6, r7, asl #5
+ add r1, r2, r3, lsl r1
+
+ and r0, r1, #10
+ and r2, r3, r4
+ and r5, r6, r7, asl #5
+ and r1, r2, r3, lsl r1
+
+ eor r0, r1, #10
+ eor r2, r3, r4
+ eor r5, r6, r7, asl #5
+ eor r1, r2, r3, lsl r1
+
+ sub r0, r1, #10
+ sub r2, r3, r4
+ sub r5, r6, r7, asl #5
+ sub r1, r2, r3, lsl r1
+
+ adc r0, r1, #10
+ adc r2, r3, r4
+ adc r5, r6, r7, asl #5
+ adc r1, r2, r3, lsl r1
+
+ sbc r0, r1, #10
+ sbc r2, r3, r4
+ sbc r5, r6, r7, asl #5
+ sbc r1, r2, r3, lsl r1
+
+ rsb r0, r1, #10
+ rsb r2, r3, r4
+ rsb r5, r6, r7, asl #5
+ rsb r1, r2, r3, lsl r1
+
+ rsc r0, r1, #10
+ rsc r2, r3, r4
+ rsc r5, r6, r7, asl #5
+ rsc r1, r2, r3, lsl r1
+
+ orr r0, r1, #10
+ orr r2, r3, r4
+ orr r5, r6, r7, asl #5
+ orr r1, r2, r3, lsl r1
+
+ bic r0, r1, #10
+ bic r2, r3, r4
+ bic r5, r6, r7, asl #5
+ bic r1, r2, r3, lsl r1
+
+ mvn r0, #10
+ mvn r2, r4
+ mvn r5, r7, asl #5
+ mvn r1, r3, lsl r1
+
+ tst r0, #10
+ tst r2, r4
+ tst r5, r7, asl #5
+ tst r1, r3, lsl r1
+
+ teq r0, #10
+ teq r2, r4
+ teq r5, r7, asl #5
+ teq r1, r3, lsl r1
+
+ cmp r0, #10
+ cmp r2, r4
+ cmp r5, r7, asl #5
+ cmp r1, r3, lsl r1
+
+ cmn r0, #10
+ cmn r2, r4
+ cmn r5, r7, asl #5
+ cmn r1, r3, lsl r1
+
+ teqp r0, #10
+ teqp r2, r4
+ teqp r5, r7, asl #5
+ teqp r1, r3, lsl r1
+
+ cmnp r0, #10
+ cmnp r2, r4
+ cmnp r5, r7, asl #5
+ cmnp r1, r3, lsl r1
+
+ cmpp r0, #10
+ cmpp r2, r4
+ cmpp r5, r7, asl #5
+ cmpp r1, r3, lsl r1
+
+ tstp r0, #10
+ tstp r2, r4
+ tstp r5, r7, asl #5
+ tstp r1, r3, lsl r1
+
+ mul r0, r1, r2
+ muls r1, r2, r3
+ mulne r0, r1, r0
+ mullss r9, r8, r7
+
+ mla r1, r9, r10, r11
+ mlas r3, r4, r9, r12
+ mlalt r9, r8, r7, r13
+ mlages r4, r1, r3, r14
+
+ ldr r0, [r1]
+ ldr r1, [r1, r2]
+ ldr r2, [r3, r4]!
+ ldr r2, [r2, #32]
+ ldr r2, [r3, r4, lsr #8]
+ ldreq r4, [r5, r4, asl #9]!
+ ldrne r4, [r5], #6
+ ldrt r1, [r2], r3
+ ldr r2, [r4], r5, lsr #8
+foo:
+ ldr r0, foo
+ ldrb r3, [r4]
+ ldrnebt r5, [r8]
+
+ str r0, [r1]
+ str r1, [r1, r2]
+ str r3, [r3, r4]!
+ str r2, [r2, #32]
+ str r2, [r3, r4, lsr #8]
+ streq r4, [r5, r4, asl #9]!
+ strne r4, [r5], #6
+ str r1, [r2], r3
+ strt r2, [r4], r5, lsr #8
+ str r1, bar
+bar:
+ stralb r1, [r7]
+ strbt r2, [r0]
+
+ ldmia r0, {r1}
+ ldmeqib r2, {r3, r4, r5}
+ ldmalda r3, {r0-r15}^
+ ldmdb r11!, {r0-r8, r10}
+ ldmed r1, {r0, r1, r2}|0xf0
+ ldmfd r2, {r3, r4}+{r5, r6, r7, r8}
+ ldmea r3, 3
+ ldmfa r4!, {r8, r9}^
+
+ stmia r0, {r1}
+ stmeqib r2, {r3, r4, r5}
+ stmalda r3, {r0-r15}^
+ stmdb r10!, {r0-r8, r10}
+ stmed r1, {r0, r1, r2}
+ stmfd r2, {r3, r4}
+ stmea r3, 3
+ stmfa r4!, {r8, r9}^
+
+ swi 0x123456
+ swihs 0x33
+
+ bl _wombat
+ blpl bar
+ b _wibble
+ ble testerfunc
diff --git a/gas/testsuite/gas/arm/le-fpconst.d b/gas/testsuite/gas/arm/le-fpconst.d
new file mode 100644
index 00000000000..354e0e0c9f3
--- /dev/null
+++ b/gas/testsuite/gas/arm/le-fpconst.d
@@ -0,0 +1,8 @@
+#objdump: -s
+#as: -EL
+#name: arm little-endian fpconst
+
+.*: +file format .*arm.*
+
+Contents of section .text:
+ 0000 cdcc8c3f 00000000 9999f13f 9a999999 .*
diff --git a/gas/testsuite/gas/arm/le-fpconst.s b/gas/testsuite/gas/arm/le-fpconst.s
new file mode 100644
index 00000000000..8a3c3d70145
--- /dev/null
+++ b/gas/testsuite/gas/arm/le-fpconst.s
@@ -0,0 +1,8 @@
+# Test fp constants.
+# These need ARM specific support because 8 byte fp constants in little
+# endian mode are represented abnormally.
+
+ .text
+ .float 1.1
+ .float 0
+ .double 1.1
diff --git a/gas/testsuite/gas/arm/thumb.s b/gas/testsuite/gas/arm/thumb.s
new file mode 100644
index 00000000000..ea4b82d1438
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb.s
@@ -0,0 +1,193 @@
+ .text
+ .code 16
+.foo:
+ lsl r2, r1, #3
+ lsr r3, r4, #31
+wibble/data:
+ asr r7, r0, #5
+
+ lsl r1, r2, #0
+ lsr r3, r4, #0
+ asr r4, r5, #0
+
+ lsr r6, r7, #32
+ asr r0, r1, #32
+
+ add r1, r2, r3
+ add r2, r4, #2
+ sub r3, r5, r7
+ sub r2, r4, #7
+
+ mov r4, #255
+ cmp r3, #250
+ add r6, #123
+ sub r5, #128
+
+ and r3, r5
+ eor r4, r6
+ lsl r1, r0
+ lsr r2, r3
+ asr r4, r6
+ adc r5, r7
+ sbc r0, r4
+ ror r1, r4
+ tst r2, r5
+ neg r1, r1
+ cmp r2, r3
+ cmn r1, r4
+ orr r0, r3
+ mul r4, r5
+ bic r5, r7
+ mvn r5, r5
+
+ add r1, r13
+ add r12, r2
+ add r9, r9
+ cmp r1, r14
+ cmp r8, r0
+ cmp r12, r14
+ mov r0, r9
+ mov r9, r4
+ mov r8, r8
+ bx r7
+ bx r8
+ .align 0
+ bx pc
+
+ ldr r3, [pc, #128]
+ ldr r4, bar
+
+ str r0, [r1, r2]
+ strb r1, [r2, r4]
+ ldr r5, [r6, r7]
+ ldrb r2, [r4, r5]
+
+ .align 0
+bar:
+ strh r1, [r2, r3]
+ ldrh r3, [r4, r0]
+ ldsb r1, [r6, r7]
+ ldsh r2, [r0, r5]
+
+ str r3, [r3, #124]
+ ldr r1, [r4, #124]
+ ldr r5, [r5]
+ strb r1, [r5, #31]
+ strb r1, [r4, #5]
+ strb r2, [r6]
+
+ strh r4, [r5, #62]
+ ldrh r5, [r0, #4]
+ ldrh r3, [r2]
+
+ str r3, [r13, #1020]
+ ldr r1, [r13, #44]
+ ldr r2, [r13]
+
+ add r7, r15, #1020
+ add r4, r13, #512
+
+ add r13, #268
+ add r13, #-104
+ sub r13, #268
+ sub r13, #-108
+
+ push {r0, r1, r2, r4}
+ push {r0, r3-r7, lr}
+ pop {r3, r4, r7}
+ pop {r0-r7, r15}
+
+ stmia r3!, {r0, r1, r4-r7}
+ ldmia r0!, {r1-r7}
+
+ beq bar
+ bne bar
+ bcs bar
+ bcc bar
+ bmi bar
+ bpl bar
+ bvs bar
+ bvc bar
+ bhi bar
+ bls bar
+ bge bar
+ bgt bar
+ blt bar
+ bgt bar
+ ble bar
+ bhi bar
+ blo bar
+ bul bar
+
+close:
+ lsl r4, r5, #near - close
+near:
+ add r2, r3, #near - close
+
+ add sp, sp, #127 << 2
+ sub sp, sp, #127 << 2
+ add r0, sp, #255 << 2
+ add r0, pc, #255 << 2
+
+ add sp, sp, #bar - .foo
+ sub sp, sp, #bar - .foo
+ add r0, sp, #bar - .foo
+ add r0, pc, #bar - .foo
+
+ add r1, #bar - .foo
+ mov r6, #bar - .foo
+ cmp r7, #bar - .foo
+
+ nop
+ nop
+
+ .arm
+.localbar:
+ b .localbar
+ b .wombat
+ bl .localbar
+ bl .wombat
+
+ bx r0
+ swi 0x123456
+
+ .thumb
+ @ The following will be disassembled incorrectly if we do not
+ @ have a Thumb symbol defined before the first Thumb instruction:
+morethumb:
+ adr r0, forwardonly
+
+ b .foo
+ b .wombat
+ bl .foo
+ bl .wombat
+
+ bx r0
+
+ swi 0xff
+ .align 0
+forwardonly:
+ beq .wombat
+ bne .wombat
+ bcs .wombat
+ bcc .wombat
+ bmi .wombat
+ bpl .wombat
+ bvs .wombat
+ bvc .wombat
+ bhi .wombat
+ bls .wombat
+ bge .wombat
+ bgt .wombat
+ blt .wombat
+ bgt .wombat
+ ble .wombat
+ bhi .wombat
+ blo .wombat
+ bul .wombat
+
+.back:
+ bl .local
+ .space (1 << 11) @ leave space to force long offsets
+.local:
+ bl .back
diff --git a/gas/testsuite/gas/d30v/align.d b/gas/testsuite/gas/d30v/align.d
new file mode 100644
index 00000000000..466768f5dc1
--- /dev/null
+++ b/gas/testsuite/gas/d30v/align.d
@@ -0,0 +1,17 @@
+#objdump: -dr
+#name: D30V alignment test
+#as:
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+0+0000 <start>:
+ 0: 08815a80 00f00000 abs r21, r42 || nop
+ 8: 08815a80 00f00000 abs r21, r42 || nop
+ 10: 08815a80 00f00000 abs r21, r42 || nop
+ 18: 00f00000 00f00000 abs r21, r42 || nop
+ 20: 08815a80 00f00000 abs r21, r42 || nop
+ 28: 08815a80 00f00000 abs r21, r42 || nop
+ 30: 08815a80 00f00000 abs r21, r42 || nop
+ ...
diff --git a/gas/testsuite/gas/d30v/align.s b/gas/testsuite/gas/d30v/align.s
new file mode 100644
index 00000000000..ef0039c6940
--- /dev/null
+++ b/gas/testsuite/gas/d30v/align.s
@@ -0,0 +1,28 @@
+# tests proper handling of aligns on D30V
+
+ .text
+ .align 3
+start:
+ abs r21,r42
+ .align 3
+ abs r21,r42
+ .align 4
+ abs r21,r42
+ .align 4
+ abs r21,r42
+
+ .data
+ .long 0xdeadbeef
+
+ .text
+ abs r21,r42
+
+ .data
+ .align 4
+ .long 0xdeadbeef
+
+ .text
+ .align 3
+ abs r21,r42
+ .end
+
diff --git a/gas/testsuite/gas/d30v/array.d b/gas/testsuite/gas/d30v/array.d
new file mode 100644
index 00000000000..e81bc3394ea
--- /dev/null
+++ b/gas/testsuite/gas/d30v/array.d
@@ -0,0 +1,31 @@
+#objdump: -dr
+#name: D30V array test
+#as:
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+0+0000 <__foo-0x48>:
+ 0: 880820c0 80000048 add.l r2, r3, 0x48
+ 0: R_D30V_32 .text
+ 8: 880820c0 80000049 add.l r2, r3, 0x49
+ 8: R_D30V_32 .text
+ 10: 880820c0 8000004a add.l r2, r3, 0x4a
+ 10: R_D30V_32 .text
+ 18: 880820c0 8000004b add.l r2, r3, 0x4b
+ 18: R_D30V_32 .text
+ 20: 880820c0 8000004c add.l r2, r3, 0x4c
+ 20: R_D30V_32 .text
+ 28: 880820c0 8000004d add.l r2, r3, 0x4d
+ 28: R_D30V_32 .text
+ 30: 880820c0 8000004e add.l r2, r3, 0x4e
+ 30: R_D30V_32 .text
+ 38: 880820c0 8000004f add.l r2, r3, 0x4f
+ 38: R_D30V_32 .text
+ 40: 880820c0 80000050 add.l r2, r3, 0x50
+ 40: R_D30V_32 .text
+
+0+0048 <__foo>:
+ 48: 12345678 12345678 .long 0x12345678 || .long 0x12345678
+ 50: 12345678 00000000 .long 0x12345678 || bra.s r0
diff --git a/gas/testsuite/gas/d30v/array.s b/gas/testsuite/gas/d30v/array.s
new file mode 100644
index 00000000000..3a187dd5afa
--- /dev/null
+++ b/gas/testsuite/gas/d30v/array.s
@@ -0,0 +1,15 @@
+# D30V array test
+ .text
+ add r2, r3 , __foo
+ add r2, r3 , __foo+1
+ add r2, r3 , __foo+2
+ add r2, r3 , __foo+3
+ add r2, r3 , __foo+4
+ add r2, r3 , __foo+5
+ add r2, r3 , __foo+6
+ add r2, r3 , __foo+7
+ add r2, r3 , __foo+8
+__foo:
+ .int 0x12345678
+ .int 0x12345678
+ .int 0x12345678
diff --git a/gas/testsuite/gas/d30v/bittest.d b/gas/testsuite/gas/d30v/bittest.d
new file mode 100644
index 00000000000..b96ab46cb84
--- /dev/null
+++ b/gas/testsuite/gas/d30v/bittest.d
@@ -0,0 +1,20 @@
+#objdump: -dr
+#name: D30V bittest opt
+#as: -WO
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 00f00000 84401083 nop -> ldw.s r1, @\(r2, r3\)
+ 8: 04406144 00f00000 ldw.s r6, @\(r5, r4\) || nop
+ 10: 00f00000 82201083 nop -> bset r1, r2, r3
+ 18: 80f00000 02001083 nop <- btst f1, r2, r3
+ 20: 00f00000 02301083 nop || bclr r1, r2, r3
+ 28: 00f00000 82101083 nop -> bnot r1, r2, r3
+ 30: 02101083 80f00000 bnot r1, r2, r3 -> nop
+ 38: 047c0105 02201083 moddec r4, 0x5 || bset r1, r2, r3
+ 40: 02201083 847c0105 bset r1, r2, r3 -> moddec r4, 0x5
+ 48: 02201083 08c04146 bset r1, r2, r3 || joinll.s r4, r5, r6
+ 50: 02201083 08c04146 bset r1, r2, r3 || joinll.s r4, r5, r6 \ No newline at end of file
diff --git a/gas/testsuite/gas/d30v/bittest.l b/gas/testsuite/gas/d30v/bittest.l
new file mode 100644
index 00000000000..75d1b7ed544
--- /dev/null
+++ b/gas/testsuite/gas/d30v/bittest.l
@@ -0,0 +1,56 @@
+.*: Assembler messages:
+.*: Warning: Swapping instruction order
+.*: Warning: Executing bset in IU may not work
+.*: Warning: Executing btst in IU may not work
+.*: Warning: Executing bclr in IU may not work
+.*: Warning: Executing bnot in IU may not work
+.*: Warning: Executing bset in IU may not work
+.*: Warning: Swapping instruction order
+GAS LISTING .*
+
+
+ 1 # bittest.s
+ 2 #
+ 3 # Bit operation instructions \(BCLR, BNOT, BSET, BTST\) should not be placed in IU.
+ 4 # If the user specifically indicates they should be in the IU, GAS will
+ 5 # generate warnings. The reason why this is not an error is that those instructions
+ 6 # will fail in IU only occasionally. Thus GAS should pack them in MU for
+ 7 # safety, and it just needs to draw attention when a violation is given.
+ 8
+ 9
+ 10 0000 00F00000 nop -> ldw R1, @\(R2,R3\)
+ 10 84401083
+ 11 0008 04406144 nop || ldw R6, @\(R5,R4\)
+.* Warning:Swapping instruction order
+ 11 00F00000
+ 12
+ 13 0010 00F00000 nop -> BSET R1, R2, R3
+.* Warning:Executing bset in IU may not work
+ 13 82201083
+ 14 0018 80F00000 nop <- BTST F1, R2, R3
+.* Warning:Executing btst in IU may not work
+ 14 02001083
+ 15 0020 00F00000 nop || BCLR R1, R2, R3
+.* Warning:Executing bclr in IU may not work
+ 15 02301083
+ 16 0028 00F00000 nop -> BNOT R1, R2, R3
+.* Warning:Executing bnot in IU may not work
+ 16 82101083
+ 17 0030 02101083 BNOT r1, r2, r3 -> nop
+ 17 80F00000
+ 18
+ 19 0038 047C0105 bset r1, r2, r3 || moddec r4, 5
+.* Warning:Swapping instruction order
+ 19 02201083
+ 20
+ 21 bset r1, r2, r3
+ 22 0040 02201083 moddec r4, 5
+ 22 847C0105
+ 23
+ 24 bset r1, r2, r3
+ 25 0048 02201083 joinll r4, r5, r6
+ 25 88C04146
+ 26
+ 27 joinll r4, r5, r6
+ 28 0050 82201083 bset r1, r2, r3
+ 28 08C04146
diff --git a/gas/testsuite/gas/d30v/bittest.s b/gas/testsuite/gas/d30v/bittest.s
new file mode 100644
index 00000000000..b79a56c95cd
--- /dev/null
+++ b/gas/testsuite/gas/d30v/bittest.s
@@ -0,0 +1,28 @@
+# bittest.s
+#
+# Bit operation instructions (BCLR, BNOT, BSET, BTST) should not be placed in IU.
+# If the user specifically indicates they should be in the IU, GAS will
+# generate warnings. The reason why this is not an error is that those instructions
+# will fail in IU only occasionally. Thus GAS should pack them in MU for
+# safety, and it just needs to draw attention when a violation is given.
+
+
+ nop -> ldw R1, @(R2,R3)
+ nop || ldw R6, @(R5,R4)
+
+ nop -> BSET R1, R2, R3
+ nop <- BTST F1, R2, R3
+ nop || BCLR R1, R2, R3
+ nop -> BNOT R1, R2, R3
+ BNOT r1, r2, r3 -> nop
+
+ bset r1, r2, r3 || moddec r4, 5
+
+ bset r1, r2, r3
+ moddec r4, 5
+
+ bset r1, r2, r3
+ joinll r4, r5, r6
+
+ joinll r4, r5, r6
+ bset r1, r2, r3
diff --git a/gas/testsuite/gas/d30v/d30.exp b/gas/testsuite/gas/d30v/d30.exp
new file mode 100644
index 00000000000..275b0e06df1
--- /dev/null
+++ b/gas/testsuite/gas/d30v/d30.exp
@@ -0,0 +1,35 @@
+#
+# D30V assembler tests
+#
+
+proc run_list_test { name opts } {
+ global srcdir subdir
+ set testname "D30V $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s $opts ">&dump.out"
+ if {[regexp_diff "dump.out" "${file}.l"] } {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+}
+
+if {[istarget d30v-*-*]} {
+ run_dump_test "inst"
+ run_dump_test "align"
+ run_dump_test "guard"
+ run_dump_test "guard-debug"
+ run_dump_test "reloc"
+ run_dump_test "opt"
+ run_dump_test "array"
+ run_dump_test "label"
+ run_list_test "warn_oddreg" "-al"
+ run_list_test "bittest" "-al"
+ run_dump_test "bittest"
+ run_list_test "serial" "-al"
+ run_list_test "serial2" "-al"
+ run_list_test "serial2O" "-al -O"
+ run_dump_test "mul"
+}
+
diff --git a/gas/testsuite/gas/d30v/guard-debug.d b/gas/testsuite/gas/d30v/guard-debug.d
new file mode 100644
index 00000000000..e9a154c851c
--- /dev/null
+++ b/gas/testsuite/gas/d30v/guard-debug.d
@@ -0,0 +1,25 @@
+#objdump: -ldr
+#name: D30V debug (-g) test
+#as: -g
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <.text>:
+.*:[0-9]+
+ 0: 08001083 00f00000 add.s r1, r2, r3 || nop
+.*:[0-9]+
+ 8: 08001083 00f00000 add.s r1, r2, r3 || nop
+.*:[0-9]+
+ 10: 18001083 00f00000 add.s/tx r1, r2, r3 || nop
+.*:[0-9]+
+ 18: 28001083 00f00000 add.s/fx r1, r2, r3 || nop
+.*:[0-9]+
+ 20: 38001083 00f00000 add.s/xt r1, r2, r3 || nop
+.*:[0-9]+
+ 28: 48001083 00f00000 add.s/xf r1, r2, r3 || nop
+.*:[0-9]+
+ 30: 58001083 00f00000 add.s/tt r1, r2, r3 || nop
+.*:[0-9]+
+ 38: 68001083 00f00000 add.s/tf r1, r2, r3 || nop
diff --git a/gas/testsuite/gas/d30v/guard-debug.s b/gas/testsuite/gas/d30v/guard-debug.s
new file mode 100644
index 00000000000..3f20f7b187d
--- /dev/null
+++ b/gas/testsuite/gas/d30v/guard-debug.s
@@ -0,0 +1,17 @@
+# Same as guard.s but here we are testing debug (-g) assembly
+# On the D30V, assembling with -g should disable the VLIW packing
+# and put only one instruction per line.
+
+ .text
+
+ add r1,r2,r3
+ add/al r1,r2,r3
+ add/tx r1,r2,r3
+ add/fx r1,r2,r3
+ add/xt r1,r2,r3
+ add/xf r1,r2,r3
+ add/tt r1,r2,r3
+ add/tf r1,r2,r3
+
+
+
diff --git a/gas/testsuite/gas/d30v/guard.d b/gas/testsuite/gas/d30v/guard.d
new file mode 100644
index 00000000000..0cfa2da7ae7
--- /dev/null
+++ b/gas/testsuite/gas/d30v/guard.d
@@ -0,0 +1,17 @@
+#objdump: -dr
+#name: D30V guarded execution test
+#as:
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+0+0000 <.text>:
+ 0: 08001083 88001083 add.s r1, r2, r3 -> add.s r1, r2, r3
+ 8: 18001083 a8001083 add.s/tx r1, r2, r3 -> add.s/fx r1, r2, r3
+ 10: 38001083 c8001083 add.s/xt r1, r2, r3 -> add.s/xf r1, r2, r3
+ 18: 58001083 e8001083 add.s/tt r1, r2, r3 -> add.s/tf r1, r2, r3
+ 20: 08001083 88001083 add.s r1, r2, r3 -> add.s r1, r2, r3
+ 28: 18001083 a8001083 add.s/tx r1, r2, r3 -> add.s/fx r1, r2, r3
+ 30: 38001083 c8001083 add.s/xt r1, r2, r3 -> add.s/xf r1, r2, r3
+ 38: 58001083 e8001083 add.s/tt r1, r2, r3 -> add.s/tf r1, r2, r3
diff --git a/gas/testsuite/gas/d30v/guard.s b/gas/testsuite/gas/d30v/guard.s
new file mode 100644
index 00000000000..ed9cd30bb4c
--- /dev/null
+++ b/gas/testsuite/gas/d30v/guard.s
@@ -0,0 +1,24 @@
+# D30V guarded execution assembly test
+
+ .text
+
+ add r1,r2,r3
+ add/al r1,r2,r3
+ add/tx r1,r2,r3
+ add/fx r1,r2,r3
+ add/xt r1,r2,r3
+ add/xf r1,r2,r3
+ add/tt r1,r2,r3
+ add/tf r1,r2,r3
+
+# check case sensitivity too
+ ADD r1,r2,r3
+ ADD/AL r1,r2,r3
+ ADD/tx r1,r2,r3
+ add/FX r1,r2,r3
+ ADD/XT r1,r2,r3
+ ADD/XF r1,r2,r3
+ add/TT r1,r2,r3
+ ADD/tf r1,r2,r3
+
+
diff --git a/gas/testsuite/gas/d30v/inst.d b/gas/testsuite/gas/d30v/inst.d
new file mode 100644
index 00000000000..9861cbf6cf2
--- /dev/null
+++ b/gas/testsuite/gas/d30v/inst.d
@@ -0,0 +1,256 @@
+#objdump: -dr
+#name: D30V basic instruction test
+#as:
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <start>:
+ 0: 08815a80 88001083 abs r21, r42 -> add.s r1, r2, r3
+ 8: 080b2cda 00f00000 add.s r50, r51, 0x1a || nop
+ 10: 880b2cf7 8ab1beef add.l r50, r51, 0xdeadbeef
+ 18: 08101083 881b2cda add2h.s r1, r2, r3 -> add2h.s r50, r51, 0x1a
+ 20: 881b2cf7 8ab1beef add2h.l r50, r51, 0xdeadbeef
+ 28: 08401083 884b2cda addc.s r1, r2, r3 -> addc.s r50, r51, 0x1a
+ 30: 884b2cf7 8ab1beef addc.l r50, r51, 0xdeadbeef
+ 38: 09001083 890b2cda addhlll.s r1, r2, r3 -> addhlll.s r50, r51, 0x1a
+ 40: 890b2cf7 8ab1beef addhlll.l r50, r51, 0xdeadbeef
+ 48: 09101083 891b2cda addhllh.s r1, r2, r3 -> addhllh.s r50, r51, 0x1a
+ 50: 891b2cf7 8ab1beef addhllh.l r50, r51, 0xdeadbeef
+ 58: 09201083 892b2cda addhlhl.s r1, r2, r3 -> addhlhl.s r50, r51, 0x1a
+ 60: 892b2cf7 8ab1beef addhlhl.l r50, r51, 0xdeadbeef
+ 68: 09301083 893b2cda addhlhh.s r1, r2, r3 -> addhlhh.s r50, r51, 0x1a
+ 70: 893b2cf7 8ab1beef addhlhh.l r50, r51, 0xdeadbeef
+ 78: 09401083 894b2cda addhhll.s r1, r2, r3 -> addhhll.s r50, r51, 0x1a
+ 80: 894b2cf7 8ab1beef addhhll.l r50, r51, 0xdeadbeef
+ 88: 09501083 895b2cda addhhlh.s r1, r2, r3 -> addhhlh.s r50, r51, 0x1a
+ 90: 895b2cf7 8ab1beef addhhlh.l r50, r51, 0xdeadbeef
+ 98: 09601083 896b2cda addhhhl.s r1, r2, r3 -> addhhhl.s r50, r51, 0x1a
+ a0: 896b2cf7 8ab1beef addhhhl.l r50, r51, 0xdeadbeef
+ a8: 09701083 897b2cda addhhhh.s r1, r2, r3 -> addhhhh.s r50, r51, 0x1a
+ b0: 897b2cf7 8ab1beef addhhhh.l r50, r51, 0xdeadbeef
+ b8: 08601083 886b2cda adds.s r1, r2, r3 -> adds.s r50, r51, 0x1a
+ c0: 886b2cf7 8ab1beef adds.l r50, r51, 0xdeadbeef
+ c8: 08701083 887b2cda adds2h.s r1, r2, r3 -> adds2h.s r50, r51, 0x1a
+ d0: 887b2cf7 8ab1beef adds2h.l r50, r51, 0xdeadbeef
+ d8: 03801083 838b2cda and.s r1, r2, r3 -> and.s r50, r51, 0x1a
+ e0: 838b2cf7 8ab1beef and.l r50, r51, 0xdeadbeef
+ e8: 02800042 82883105 andfg f0, f1, f2 -> andfg f3, s, 0x5
+ f0: 08a01083 88a84146 avg.s r1, r2, r3 -> avg.s r4, r5, 0x6
+ f8: 88ab2cf7 8ab1beef avg.l r50, r51, 0xdeadbeef
+ 100: 08b01083 88b84146 avg2h.s r1, r2, r3 -> avg2h.s r4, r5, 0x6
+ 108: 88bb2cf7 8ab1beef avg2h.l r50, r51, 0xdeadbeef
+ 110: 02301083 82384146 bclr r1, r2, r3 -> bclr r4, r5, 0x6
+ 118: 02101083 82185cc6 bnot r1, r2, r3 -> bnot r5, r51, 0x6
+ 120: 00000029 00f00000 bra.s r41 || nop
+ 128: 00080008 00f00000 bra.s 40 \(168 <start\+0x168>\) || nop
+ 130: 00081e01 00f00000 bra.s f008 \(f138 <start\+0xf138>\) || nop
+ 138: 0046902a 00f00000 bratnz.s r41, r42 || nop
+ 140: 804c1000 8000f00d bratnz.l r1, f00d \(f14d <start\+0xf14d>\)
+ 148: 804c1037 8ab1f00d bratnz.l r1, -21520ff3 \(deadf155 <start\+0xdeadf155>\)
+ 150: 0042902a 00f00000 bratzr.s r41, r42 || nop
+ 158: 80481000 8000f00d bratzr.l r1, f00d \(f165 <start\+0xf165>\)
+ 160: 80481037 8ab1f00d bratzr.l r1, -21520ff3 \(deadf16d <start\+0xdeadf16d>\)
+ 168: 02201083 82285cc6 bset r1, r2, r3 -> bset r5, r51, 0x6
+ 170: 00200029 00f00000 bsr.s r41 || nop
+ 178: 00281e01 00f00000 bsr.s f008 \(f180 <start\+0xf180>\) || nop
+ 180: 80280037 8ab1f00d bsr.l -21520ff3 \(deadf18d <start\+0xdeadf18d>\)
+ 188: 0066902a 00f00000 bsrtnz.s r41, r42 || nop
+ 190: 806c1000 8000f00d bsrtnz.l r1, f00d \(f19d <start\+0xf19d>\)
+ 198: 806c1037 8ab1f00d bsrtnz.l r1, -21520ff3 \(deadf1a5 <start\+0xdeadf1a5>\)
+ 1a0: 0062902a 00f00000 bsrtzr.s r41, r42 || nop
+ 1a8: 80681000 8000f00d bsrtzr.l r1, f00d \(f1b5 <start\+0xf1b5>\)
+ 1b0: 80681037 8ab1f00d bsrtzr.l r1, -21520ff3 \(deadf1bd <start\+0xdeadf1bd>\)
+ 1b8: 02001083 82085cc6 btst f1, r2, r3 -> btst v, r51, 0x6
+ 1c0: 02c000c1 82c09515 cmpeq.s f0, r3, r1 -> cmpne.s f1, r20, r21
+ 1c8: 02c127e0 82c1b0c4 cmpgt.s f2, r31, r32 -> cmpge.s f3, r3, r4
+ 1d0: 02c240c4 82c2d0c4 cmplt.s s, r3, r4 -> cmple.s v, r3, r4
+ 1d8: 02c360c4 82c3f0c4 cmpps.s va, r3, r4 -> cmpng.s c, r3, r4
+ 1e0: 02d127e0 82d1b0c4 cmpugt.s f2, r31, r32 -> cmpuge.s f3, r3, r4
+ 1e8: 02d240c4 82d2d0c4 cmpult.s s, r3, r4 -> cmpule.s v, r3, r4
+ 1f0: 01001008 81081020 dbra.s r1, r8 -> dbra.s r1, 100 \(2f0 <start\+0x2f0>\)
+ 1f8: 81081037 8ab1f00d dbra.l r1, -21520ff3 \(deadf205 <start\+0xdeadf205>\)
+ 200: 0140201f 81482020 dbrai.s 10, r31 -> dbrai.s 10, 100 \(300 <start\+0x300>\)
+ 208: 81482037 8ab1f00d dbrai.l 10, -21520ff3 \(deadf215 <start\+0xdeadf215>\)
+ 210: 01201008 00f00000 dbsr.s r1, r8 || nop
+ 218: 01281020 00f00000 dbsr.s r1, 100 \(318 <start\+0x318>\) || nop
+ 220: 81281037 8ab1f00d dbsr.l r1, -21520ff3 \(deadf22d <start\+0xdeadf22d>\)
+ 228: 0160401f 00f00000 dbsri.s 20, r31 || nop
+ 230: 01684020 00f00000 dbsri.s 20, 100 \(330 <start\+0x330>\) || nop
+ 238: 81684037 8ab1f00d dbsri.l 20, -21520ff3 \(deadf245 <start\+0xdeadf245>\)
+ 240: 01101020 00f00000 djmp.s r1, r32 || nop
+ 248: 81181000 8000f00d djmp.l r1, f00d <start\+0xf00d>
+ 250: 81181037 8ab1f00d djmp.l r1, deadf00d <start\+0xdeadf00d>
+ 258: 01506020 00f00000 djmpi.s 30, r32 || nop
+ 260: 81586000 8000f00d djmpi.l 30, f00d <start\+0xf00d>
+ 268: 81586037 8ab1f00d djmpi.l 30, deadf00d <start\+0xdeadf00d>
+ 270: 01301020 00f00000 djsr.s r1, r32 || nop
+ 278: 81381000 8000f00d djsr.l r1, f00d <start\+0xf00d>
+ 280: 81381037 8ab1f00d djsr.l r1, deadf00d <start\+0xdeadf00d>
+ 288: 01702020 00f00000 djsri.s 10, r32 || nop
+ 290: 81784000 8000f00d djsri.l 20, f00d <start\+0xf00d>
+ 298: 81788037 8ab1f00d djsri.l 40, deadf00d <start\+0xdeadf00d>
+ 2a0: 00100029 00f00000 jmp.s r41 || nop
+ 2a8: 00181e01 00f00000 jmp.s f008 <start\+0xf008> || nop
+ 2b0: 80180037 8ab1f00d jmp.l deadf00d <start\+0xdeadf00d>
+ 2b8: 0056902a 00f00000 jmptnz.s r41, r42 || nop
+ 2c0: 805c1000 8000f00d jmptnz.l r1, f00d <start\+0xf00d>
+ 2c8: 805c1037 8ab1f00d jmptnz.l r1, deadf00d <start\+0xdeadf00d>
+ 2d0: 0052902a 00f00000 jmptzr.s r41, r42 || nop
+ 2d8: 80581000 8000f00d jmptzr.l r1, f00d <start\+0xf00d>
+ 2e0: 80581037 8ab1f00d jmptzr.l r1, deadf00d <start\+0xdeadf00d>
+ 2e8: 08c01084 88c8108f joinll.s r1, r2, r4 -> joinll.s r1, r2, 0xf
+ 2f0: 88c810b7 8ab1f00d joinll.l r1, r2, 0xdeadf00d
+ 2f8: 08d01084 88d8108f joinlh.s r1, r2, r4 -> joinlh.s r1, r2, 0xf
+ 300: 88d810b7 8ab1f00d joinlh.l r1, r2, 0xdeadf00d
+ 308: 08e01084 88e8108f joinhl.s r1, r2, r4 -> joinhl.s r1, r2, 0xf
+ 310: 88e810b7 8ab1f00d joinhl.l r1, r2, 0xdeadf00d
+ 318: 08f01084 88f8108f joinhh.s r1, r2, r4 -> joinhh.s r1, r2, 0xf
+ 320: 88f810b7 8ab1f00d joinhh.l r1, r2, 0xdeadf00d
+ 328: 00300029 00f00000 jsr.s r41 || nop
+ 330: 00381e01 00f00000 jsr.s f008 <start\+0xf008> || nop
+ 338: 80380037 8ab1f00d jsr.l deadf00d <start\+0xdeadf00d>
+ 340: 0076902a 00f00000 jsrtnz.s r41, r42 || nop
+ 348: 807c1000 8000f00d jsrtnz.l r1, f00d <start\+0xf00d>
+ 350: 807c1037 8ab1f00d jsrtnz.l r1, deadf00d <start\+0xdeadf00d>
+ 358: 0072902a 00f00000 jsrtzr.s r41, r42 || nop
+ 360: 80781000 8000f00d jsrtzr.l r1, f00d <start\+0xf00d>
+ 368: 80781037 8ab1f00d jsrtzr.l r1, deadf00d <start\+0xdeadf00d>
+ 370: 043061c8 843461c8 ld2h.s r6, @\(r7, r8\) -> ld2h.s r6, @\(r7\+, r8\)
+ 378: 043c61c8 843861da ld2h.s r6, @\(r7-, r8\) -> ld2h.s r6, @\(r7, 0x1a\)
+ 380: 843861c0 80001234 ld2h.l r6, @\(r7, 0x1234\)
+ 388: 046061c8 846461c8 ld2w.s r6, @\(r7, r8\) -> ld2w.s r6, @\(r7\+, r8\)
+ 390: 046c61c8 846861da ld2w.s r6, @\(r7-, r8\) -> ld2w.s r6, @\(r7, 0x1a\)
+ 398: 846861c0 80001234 ld2w.l r6, @\(r7, 0x1234\)
+ 3a0: 045061c8 845461c8 ld4bh.s r6, @\(r7, r8\) -> ld4bh.s r6, @\(r7\+, r8\)
+ 3a8: 045c61c8 845861da ld4bh.s r6, @\(r7-, r8\) -> ld4bh.s r6, @\(r7, 0x1a\)
+ 3b0: 845861c0 80001234 ld4bh.l r6, @\(r7, 0x1234\)
+ 3b8: 04d061c8 84d461c8 ld4bhu.s r6, @\(r7, r8\) -> ld4bhu.s r6, @\(r7\+, r8\)
+ 3c0: 04dc61c8 84d861da ld4bhu.s r6, @\(r7-, r8\) -> ld4bhu.s r6, @\(r7, 0x1a\)
+ 3c8: 84d861c0 80001234 ld4bhu.l r6, @\(r7, 0x1234\)
+ 3d0: 040061c8 840461c8 ldb.s r6, @\(r7, r8\) -> ldb.s r6, @\(r7\+, r8\)
+ 3d8: 040c61c8 840861da ldb.s r6, @\(r7-, r8\) -> ldb.s r6, @\(r7, 0x1a\)
+ 3e0: 840861c0 80001234 ldb.l r6, @\(r7, 0x1234\)
+ 3e8: 049061c8 849461c8 ldbu.s r6, @\(r7, r8\) -> ldbu.s r6, @\(r7\+, r8\)
+ 3f0: 049c61c8 849861da ldbu.s r6, @\(r7-, r8\) -> ldbu.s r6, @\(r7, 0x1a\)
+ 3f8: 849861c0 80001234 ldbu.l r6, @\(r7, 0x1234\)
+ 400: 042061c8 842461c8 ldh.s r6, @\(r7, r8\) -> ldh.s r6, @\(r7\+, r8\)
+ 408: 042c61c8 842861da ldh.s r6, @\(r7-, r8\) -> ldh.s r6, @\(r7, 0x1a\)
+ 410: 842861c0 80001234 ldh.l r6, @\(r7, 0x1234\)
+ 418: 041061c8 841461c8 ldhh.s r6, @\(r7, r8\) -> ldhh.s r6, @\(r7\+, r8\)
+ 420: 041c61c8 841861da ldhh.s r6, @\(r7-, r8\) -> ldhh.s r6, @\(r7, 0x1a\)
+ 428: 841861c0 80001234 ldhh.l r6, @\(r7, 0x1234\)
+ 430: 04a061c8 84a461c8 ldhu.s r6, @\(r7, r8\) -> ldhu.s r6, @\(r7\+, r8\)
+ 438: 04ac61c8 84a861da ldhu.s r6, @\(r7-, r8\) -> ldhu.s r6, @\(r7, 0x1a\)
+ 440: 84a861c0 80001234 ldhu.l r6, @\(r7, 0x1234\)
+ 448: 044061c8 844461c8 ldw.s r6, @\(r7, r8\) -> ldw.s r6, @\(r7\+, r8\)
+ 450: 044c61c8 844861da ldw.s r6, @\(r7-, r8\) -> ldw.s r6, @\(r7, 0x1a\)
+ 458: 844861c0 80001234 ldw.l r6, @\(r7, 0x1234\)
+ 460: 8b48109f 0b401084 mac0 r1, r2, 0x1f <- mac0 r1, r2, r4
+ 468: 8b4c109f 0b441084 mac1 r1, r2, 0x1f <- mac1 r1, r2, r4
+ 470: 8b58109f 0b501084 macs0 r1, r2, 0x1f <- macs0 r1, r2, r4
+ 478: 8b5c109f 0b541084 macs1 r1, r2, 0x1f <- macs1 r1, r2, r4
+ 480: 047c004a 8474004a moddec r1, 0xa -> modinc r1, 0xa
+ 488: 8b68109f 0b601084 msub0 r1, r2, 0x1f <- msub0 r1, r2, r4
+ 490: 8b6c109f 0b641084 msub1 r1, r2, 0x1f <- msub1 r1, r2, r4
+ 498: 8b08108a 0b001084 mul r1, r2, 0xa <- mul r1, r2, r4
+ 4a0: 8b78109f 0b701084 msubs0 r1, r2, 0x1f <- msubs0 r1, r2, r4
+ 4a8: 8b7c109f 0b741084 msubs1 r1, r2, 0x1f <- msubs1 r1, r2, r4
+ 4b0: 00f00000 00f00000 nop || nop
+ 4b8: 8a08108a 0a001084 mul2h r1, r2, 0xa <- mul2h r1, r2, r4
+ 4c0: 8a48108a 0a401084 mulhxll r1, r2, 0xa <- mulhxll r1, r2, r4
+ 4c8: 8a58108a 0a501084 mulhxlh r1, r2, 0xa <- mulhxlh r1, r2, r4
+ 4d0: 8a68108a 0a601084 mulhxhl r1, r2, 0xa <- mulhxhl r1, r2, r4
+ 4d8: 8a78108a 0a701084 mulhxhh r1, r2, 0xa <- mulhxhh r1, r2, r4
+ 4e0: 8b900044 0a108084 mulxs a0, r1, r4 <- mulx2h r8, r2, r4
+ 4e8: 8b88108a 0b800044 mulx a1, r2, 0xa <- mulx a0, r1, r4
+ 4f0: 8bf8204a 0bf01004 mvfacc r2, a1, 0xa <- mvfacc r1, a0, r4
+ 4f8: 8b98108a 0a18808a mulxs a1, r2, 0xa <- mulx2h r8, r2, 0xa
+ 500: 01e0a080 81e0a1c0 mvfsys r10, pc -> mvfsys r10, rpt_c
+ 508: 01e0a000 81e0a002 mvfsys r10, psw -> mvfsys r10, pswh
+ 510: 01e0a001 81e0a003 mvfsys r10, pswl -> mvfsys r10, f0
+ 518: 01e0a103 8af01084 mvfsys r10, s -> mvtacc a1, r2, r4
+ 520: 00e07280 80e00280 mvtsys rpt_c, r10 -> mvtsys psw, r10
+ 528: 00e00282 80e00281 mvtsys pswh, r10 -> mvtsys pswl, r10
+ 530: 00e00283 80e03283 mvtsys f0, r10 -> mvtsys f3, r10
+ 538: 00e04283 80e05283 mvtsys s, r10 -> mvtsys v, r10
+ 540: 00e06283 80e07283 mvtsys va, r10 -> mvtsys c, r10
+ 548: 00f00000 83901080 nop -> not r1, r2
+ 550: 02901080 83a01084 notfg f1, f2 -> or.s r1, r2, r4
+ 558: 03a8109a 00f00000 or.s r1, r2, 0x1a || nop
+ 560: 83a810b7 8ab1f00d or.l r1, r2, 0xdeadf00d
+ 568: 02a01084 82a84081 orfg f1, f2, s -> orfg s, f2, 0x1
+ 570: 00800000 00f00000 reit || nop
+ 578: 01801002 00f00000 repeat.s r1, r2 || nop
+ 580: 81884000 8000dead repeat.l r4, dead \(e42d <start\+0xe42d>\)
+ 588: 81884037 8ab1f00d repeat.l r4, -21520ff3 \(deadf595 <start\+0xdeadf595>\)
+ 590: 01a0a001 81a8a200 repeati.s a \(59a <start\+0x59a>\), r1 -> repeati.s a \(59a <start\+0x59a>\), 1000 \(1590 <start\+0x1590>\)
+ 598: 00f00000 00f00000 nop || nop
+ 5a0: 03401084 8348108a rot r1, r2, r4 -> rot r1, r2, 0xa
+ 5a8: 03501084 8358108a rot2h r1, r2, r4 -> rot2h r1, r2, 0xa
+ 5b0: 8a88108a 0a801084 sat r1, r2, 0xa <- sat r1, r2, r4
+ 5b8: 8a98108a 0a901084 sat2h r1, r2, 0xa <- sat2h r1, r2, r4
+ 5c0: 8bc8108a 0bc01084 sathl r1, r2, 0xa <- sathl r1, r2, r4
+ 5c8: 8bd8108a 0bd01084 sathh r1, r2, 0xa <- sathh r1, r2, r4
+ 5d0: 8aa8108a 0aa01084 satz r1, r2, 0xa <- satz r1, r2, r4
+ 5d8: 8ab8108a 0ab01084 satz2h r1, r2, 0xa <- satz2h r1, r2, r4
+ 5e0: 03001084 8308108a sra r1, r2, r4 -> sra r1, r2, 0xa
+ 5e8: 03101084 8318108a sra2h r1, r2, r4 -> sra2h r1, r2, 0xa
+ 5f0: 03601084 8368108a src r1, r2, r4 -> src r1, r2, 0xa
+ 5f8: 03201084 8328108a srl r1, r2, r4 -> srl r1, r2, 0xa
+ 600: 03301084 8338108a srl2h r1, r2, r4 -> srl2h r1, r2, 0xa
+ 608: 053061c8 853461c8 st2h.s r6, @\(r7, r8\) -> st2h.s r6, @\(r7\+, r8\)
+ 610: 053c61c8 853861da st2h.s r6, @\(r7-, r8\) -> st2h.s r6, @\(r7, 0x1a\)
+ 618: 853861c0 80001234 st2h.l r6, @\(r7, 0x1234\)
+ 620: 056061c8 856461c8 st2w.s r6, @\(r7, r8\) -> st2w.s r6, @\(r7\+, r8\)
+ 628: 056c61c8 856861da st2w.s r6, @\(r7-, r8\) -> st2w.s r6, @\(r7, 0x1a\)
+ 630: 856861c0 80001234 st2w.l r6, @\(r7, 0x1234\)
+ 638: 055061c8 855461c8 st4hb.s r6, @\(r7, r8\) -> st4hb.s r6, @\(r7\+, r8\)
+ 640: 055c61c8 855861da st4hb.s r6, @\(r7-, r8\) -> st4hb.s r6, @\(r7, 0x1a\)
+ 648: 855861c0 80001234 st4hb.l r6, @\(r7, 0x1234\)
+ 650: 050061c8 850461c8 stb.s r6, @\(r7, r8\) -> stb.s r6, @\(r7\+, r8\)
+ 658: 050c61c8 850861da stb.s r6, @\(r7-, r8\) -> stb.s r6, @\(r7, 0x1a\)
+ 660: 850861c0 80001234 stb.l r6, @\(r7, 0x1234\)
+ 668: 052061c8 852461c8 sth.s r6, @\(r7, r8\) -> sth.s r6, @\(r7\+, r8\)
+ 670: 052c61c8 852861da sth.s r6, @\(r7-, r8\) -> sth.s r6, @\(r7, 0x1a\)
+ 678: 852861c0 80001234 sth.l r6, @\(r7, 0x1234\)
+ 680: 051061c8 851461c8 sthh.s r6, @\(r7, r8\) -> sthh.s r6, @\(r7\+, r8\)
+ 688: 051c61c8 851861da sthh.s r6, @\(r7-, r8\) -> sthh.s r6, @\(r7, 0x1a\)
+ 690: 851861c0 80001234 sthh.l r6, @\(r7, 0x1234\)
+ 698: 054061c8 854461c8 stw.s r6, @\(r7, r8\) -> stw.s r6, @\(r7\+, r8\)
+ 6a0: 054c61c8 854861da stw.s r6, @\(r7-, r8\) -> stw.s r6, @\(r7, 0x1a\)
+ 6a8: 854861c0 80001234 stw.l r6, @\(r7, 0x1234\)
+ 6b0: 08201083 882b2cda sub.s r1, r2, r3 -> sub.s r50, r51, 0x1a
+ 6b8: 882b2cf7 8ab1beef sub.l r50, r51, 0xdeadbeef
+ 6c0: 08301083 883b2cda sub2h.s r1, r2, r3 -> sub2h.s r50, r51, 0x1a
+ 6c8: 883b2cf7 8ab1beef sub2h.l r50, r51, 0xdeadbeef
+ 6d0: 08501083 885b2cda subb.s r1, r2, r3 -> subb.s r50, r51, 0x1a
+ 6d8: 885b2cf7 8ab1beef subb.l r50, r51, 0xdeadbeef
+ 6e0: 09801083 898b2cda subhlll.s r1, r2, r3 -> subhlll.s r50, r51, 0x1a
+ 6e8: 898b2cf7 8ab1beef subhlll.l r50, r51, 0xdeadbeef
+ 6f0: 09901083 899b2cda subhllh.s r1, r2, r3 -> subhllh.s r50, r51, 0x1a
+ 6f8: 899b2cf7 8ab1beef subhllh.l r50, r51, 0xdeadbeef
+ 700: 09a01083 89ab2cda subhlhl.s r1, r2, r3 -> subhlhl.s r50, r51, 0x1a
+ 708: 89ab2cf7 8ab1beef subhlhl.l r50, r51, 0xdeadbeef
+ 710: 09b01083 89bb2cda subhlhh.s r1, r2, r3 -> subhlhh.s r50, r51, 0x1a
+ 718: 89bb2cf7 8ab1beef subhlhh.l r50, r51, 0xdeadbeef
+ 720: 09c01083 89cb2cda subhhll.s r1, r2, r3 -> subhhll.s r50, r51, 0x1a
+ 728: 89cb2cf7 8ab1beef subhhll.l r50, r51, 0xdeadbeef
+ 730: 09d01083 89db2cda subhhlh.s r1, r2, r3 -> subhhlh.s r50, r51, 0x1a
+ 738: 89db2cf7 8ab1beef subhhlh.l r50, r51, 0xdeadbeef
+ 740: 09e01083 89eb2cda subhhhl.s r1, r2, r3 -> subhhhl.s r50, r51, 0x1a
+ 748: 89eb2cf7 8ab1beef subhhhl.l r50, r51, 0xdeadbeef
+ 750: 09f01083 89fb2cda subhhhh.s r1, r2, r3 -> subhhhh.s r50, r51, 0x1a
+ 758: 89fb2cf7 8ab1beef subhhhh.l r50, r51, 0xdeadbeef
+ 760: 00900001 00f00000 trap.s r1 || nop
+ 768: 0098000a 00f00000 trap.s 0xa || nop
+ 770: 03b01084 83b8108a xor.s r1, r2, r4 -> xor.s r1, r2, 0xa
+ 778: 83b810b7 8ab1f00d xor.l r1, r2, 0xdeadf00d
+ 780: 02b01084 82b8110a xorfg f1, f2, s -> xorfg f1, s, 0xa
+ 788: 00f00000 80f00000 nop -> nop
+ 790: 00f00000 80f00000 nop -> nop
+ 798: 00f00000 00f00000 nop || nop
+ 7a0: 80f00000 00f00000 nop <- nop
+ 7a8: 03901080 00f00000 not r1, r2 || nop
+ 7b0: 039020c0 80f00000 not r2, r3 -> nop
diff --git a/gas/testsuite/gas/d30v/inst.s b/gas/testsuite/gas/d30v/inst.s
new file mode 100644
index 00000000000..ee6611eb117
--- /dev/null
+++ b/gas/testsuite/gas/d30v/inst.s
@@ -0,0 +1,504 @@
+# test all instructions
+
+start:
+ abs r21,r42
+
+ add r1,r2,r3
+ add r50,r51,0x1a
+ add r50,r51,0xdeadbeef
+
+ add2h r1,r2,r3
+ add2h r50,r51,0x1a
+ add2h r50,r51,0xdeadbeef
+
+ addc r1,r2,r3
+ addc r50,r51,0x1a
+ addc r50,r51,0xdeadbeef
+
+ addhlll r1,r2,r3
+ addhlll r50,r51,0x1a
+ addhlll r50,r51,0xdeadbeef
+
+ addhllh r1,r2,r3
+ addhllh r50,r51,0x1a
+ addhllh r50,r51,0xdeadbeef
+
+ addhlhl r1,r2,r3
+ addhlhl r50,r51,0x1a
+ addhlhl r50,r51,0xdeadbeef
+
+ addhlhh r1,r2,r3
+ addhlhh r50,r51,0x1a
+ addhlhh r50,r51,0xdeadbeef
+
+ addhhll r1,r2,r3
+ addhhll r50,r51,0x1a
+ addhhll r50,r51,0xdeadbeef
+
+ addhhlh r1,r2,r3
+ addhhlh r50,r51,0x1a
+ addhhlh r50,r51,0xdeadbeef
+
+ addhhhl r1,r2,r3
+ addhhhl r50,r51,0x1a
+ addhhhl r50,r51,0xdeadbeef
+
+ addhhhh r1,r2,r3
+ addhhhh r50,r51,0x1a
+ addhhhh r50,r51,0xdeadbeef
+
+ adds r1,r2,r3
+ adds r50,r51,0x1a
+ adds r50,r51,0xdeadbeef
+
+ adds2h r1,r2,r3
+ adds2h r50,r51,0x1a
+ adds2h r50,r51,0xdeadbeef
+
+ and r1,r2,r3
+ and r50,r51,0x1a
+ and r50,r51,0xdeadbeef
+
+ andfg f0,f1,f2
+ andfg f3,f4,5
+
+ avg r1,r2,r3
+ avg r4,r5,6
+ avg r50,r51,0xdeadbeef
+
+ avg2h r1,r2,r3
+ avg2h r4,r5,6
+ avg2h r50,r51,0xdeadbeef
+
+ bclr r1,r2,r3
+ bclr r4,r5,6
+
+ bnot r1,r2,r3
+ bnot r5,r51,6
+
+ bra r41
+ bra 0x40
+ bra 0xf00d
+
+ bratnz r41,r42
+ bratnz r1,0xf00d
+ bratnz r1,0xdeadf00d
+
+ bratzr r41,r42
+ bratzr r1,0xf00d
+ bratzr r1,0xdeadf00d
+
+ bset r1,r2,r3
+ bset r5,r51,6
+
+ bsr r41
+ bsr 0xf00d
+ bsr 0xdeadf00d
+
+ bsrtnz r41,r42
+ bsrtnz r1,0xf00d
+ bsrtnz r1,0xdeadf00d
+
+ bsrtzr r41,r42
+ bsrtzr r1,0xf00d
+ bsrtzr r1,0xdeadf00d
+
+ btst f1,r2,r3
+ btst f5,r51,6
+
+ cmpeq f0,r3,r1
+ cmpne f1,r20,r21
+ cmpgt f2,r31,r32
+ cmpge f3,r3,r4
+ cmplt f4,r3,r4
+ cmple f5,r3,r4
+ cmpps f6,r3,r4
+ cmpng f7,r3,r4
+
+ cmpugt f2,r31,r32
+ cmpuge f3,r3,r4
+ cmpult f4,r3,r4
+ cmpule f5,r3,r4
+
+ dbra r1,r8
+ dbra r1,0x100
+ dbra r1,0xdeadf00d
+
+ dbrai 0x10,r31
+ dbrai 0x10,0x100
+ dbrai 0x10,0xdeadf00d
+
+ dbsr r1,r8 || nop
+ dbsr r1,0x100 || nop
+ dbsr r1,0xdeadf00d
+
+ dbsri 0x20,r31 || nop
+ dbsri 0x20,0x100 || nop
+ dbsri 0x20,0xdeadf00d
+
+ djmp r1,r32
+ djmp r1,0xf00d
+ djmp r1,0xdeadf00d
+
+ djmpi 0x30,r32
+ djmpi 0x30,0xf00d
+ djmpi 0x30,0xdeadf00d
+
+ djsr r1,r32
+ djsr r1,0xf00d
+ djsr r1,0xdeadf00d
+
+ djsri 0x10,r32
+ djsri 0x20,0xf00d
+ djsri 0x40,0xdeadf00d
+
+ jmp r41
+ jmp 0xf00d
+ jmp 0xdeadf00d
+
+ jmptnz r41,r42
+ jmptnz r1,0xf00d
+ jmptnz r1,0xdeadf00d
+
+ jmptzr r41,r42
+ jmptzr r1,0xf00d
+ jmptzr r1,0xdeadf00d
+
+ joinll r1,r2,r4
+ joinll r1,r2,0xf
+ joinll r1,r2,0xdeadf00d
+
+ joinlh r1,r2,r4
+ joinlh r1,r2,0xf
+ joinlh r1,r2,0xdeadf00d
+
+ joinhl r1,r2,r4
+ joinhl r1,r2,0xf
+ joinhl r1,r2,0xdeadf00d
+
+ joinhh r1,r2,r4
+ joinhh r1,r2,0xf
+ joinhh r1,r2,0xdeadf00d
+
+ jsr r41
+ jsr 0xf00d
+ jsr 0xdeadf00d
+
+ jsrtnz r41,r42
+ jsrtnz r1,0xf00d
+ jsrtnz r1,0xdeadf00d
+
+ jsrtzr r41,r42
+ jsrtzr r1,0xf00d
+ jsrtzr r1,0xdeadf00d
+
+ ld2h r6,@(r7,r8)
+ ld2h r6,@(r7+,r8)
+ ld2h r6,@(r7-,r8)
+ ld2h r6,@(r7,0x1a)
+ ld2h r6,@(r7,0x1234)
+
+ ld2w r6,@(r7,r8)
+ ld2w r6,@(r7+,r8)
+ ld2w r6,@(r7-,r8)
+ ld2w r6,@(r7,0x1a)
+ ld2w r6,@(r7,0x1234)
+
+ ld4bh r6,@(r7,r8)
+ ld4bh r6,@(r7+,r8)
+ ld4bh r6,@(r7-,r8)
+ ld4bh r6,@(r7,0x1a)
+ ld4bh r6,@(r7,0x1234)
+
+ ld4bhu r6,@(r7,r8)
+ ld4bhu r6,@(r7+,r8)
+ ld4bhu r6,@(r7-,r8)
+ ld4bhu r6,@(r7,0x1a)
+ ld4bhu r6,@(r7,0x1234)
+
+ ldb r6,@(r7,r8)
+ ldb r6,@(r7+,r8)
+ ldb r6,@(r7-,r8)
+ ldb r6,@(r7,0x1a)
+ ldb r6,@(r7,0x1234)
+
+ ldbu r6,@(r7,r8)
+ ldbu r6,@(r7+,r8)
+ ldbu r6,@(r7-,r8)
+ ldbu r6,@(r7,0x1a)
+ ldbu r6,@(r7,0x1234)
+
+ ldh r6,@(r7,r8)
+ ldh r6,@(r7+,r8)
+ ldh r6,@(r7-,r8)
+ ldh r6,@(r7,0x1a)
+ ldh r6,@(r7,0x1234)
+
+ ldhh r6,@(r7,r8)
+ ldhh r6,@(r7+,r8)
+ ldhh r6,@(r7-,r8)
+ ldhh r6,@(r7,0x1a)
+ ldhh r6,@(r7,0x1234)
+
+ ldhu r6,@(r7,r8)
+ ldhu r6,@(r7+,r8)
+ ldhu r6,@(r7-,r8)
+ ldhu r6,@(r7,0x1a)
+ ldhu r6,@(r7,0x1234)
+
+ ldw r6,@(r7,r8)
+ ldw r6,@(r7+,r8)
+ ldw r6,@(r7-,r8)
+ ldw r6,@(r7,0x1a)
+ ldw r6,@(r7,0x1234)
+
+ mac0 r1,r2,r4
+ mac0 r1,r2,0x1f
+ mac1 r1,r2,r4
+ mac1 r1,r2,0x1f
+
+ macs0 r1,r2,r4
+ macs0 r1,r2,0x1f
+ macs1 r1,r2,r4
+ macs1 r1,r2,0x1f
+
+ moddec r1,0xa
+
+ modinc r1,0xa
+
+ msub0 r1,r2,r4
+ msub0 r1,r2,0x1f
+ msub1 r1,r2,r4
+ msub1 r1,r2,0x1f
+
+ mul r1,r2,r4
+ mul r1,r2,0xa
+
+ msubs0 r1,r2,r4
+ msubs0 r1,r2,0x1f
+ msubs1 r1,r2,r4
+ msubs1 r1,r2,0x1f
+
+ mul2h r1,r2,r4
+ mul2h r1,r2,0xa
+
+ mulhxll r1,r2,r4
+ mulhxll r1,r2,0xa
+
+ mulhxlh r1,r2,r4
+ mulhxlh r1,r2,0xa
+
+ mulhxhl r1,r2,r4
+ mulhxhl r1,r2,0xa
+
+ mulhxhh r1,r2,r4
+ mulhxhh r1,r2,0xa
+
+ mulx2h r8,r2,r4
+ mulxs a0,r1,r4
+
+ mulx a0,r1,r4
+ mulx a1,r2,0xa
+
+ mvfacc r1,a0,r4
+ mvfacc r2,a1,0xa
+
+ mulx2h r8,r2,0xa
+ mulxs a1,r2,0xa
+
+ mvfsys r10,pc
+ mvfsys r10,rpt_c
+ mvfsys r10,psw
+ mvfsys r10,pswh
+ mvfsys r10,pswl
+ mvfsys r10,f0
+ mvfsys r10,S
+
+ mvtacc a1,r2,r4
+
+ mvtsys rpt_c, r10
+ mvtsys psw, r10
+ mvtsys pswh, r10
+ mvtsys pswl, r10
+ mvtsys f0, r10
+ mvtsys f3, r10
+ mvtsys S, r10
+ mvtsys V, r10
+ mvtsys VA, r10
+ mvtsys C, r10
+
+ nop
+
+ not r1,r2
+
+ notfg f1,f2
+
+ or r1,r2,r4
+ or r1,r2,0x1a
+ or r1,r2,0xdeadf00d
+
+ orfg f1,f2,f4
+ orfg f4,f2,0x1
+
+ reit
+
+ repeat r1,r2
+ repeat r4,0xdead
+ repeat r4,0xdeadf00d
+
+ repeati 0xa,r1
+ repeati 0xa,0x1001
+
+ nop || nop
+
+ rot r1,r2,r4
+ rot r1,r2,0xa
+
+ rot2h r1,r2,r4
+ rot2h r1,r2,0xa
+
+ sat r1,r2,r4
+ sat r1,r2,0xa
+
+ sat2h r1,r2,r4
+ sat2h r1,r2,0xa
+
+ sathl r1,r2,r4
+ sathl r1,r2,0xa
+
+ sathh r1,r2,r4
+ sathh r1,r2,0xa
+
+ satz r1,r2,r4
+ satz r1,r2,0xa
+
+ satz2h r1,r2,r4
+ satz2h r1,r2,0xa
+
+ sra r1,r2,r4
+ sra r1,r2,0xa
+
+ sra2h r1,r2,r4
+ sra2h r1,r2,0xa
+
+ src r1,r2,r4
+ src r1,r2,0xa
+
+ srl r1,r2,r4
+ srl r1,r2,0xa
+
+ srl2h r1,r2,r4
+ srl2h r1,r2,0xa
+
+
+ st2h r6,@(r7,r8)
+ st2h r6,@(r7+,r8)
+ st2h r6,@(r7-,r8)
+ st2h r6,@(r7,0x1a)
+ st2h r6,@(r7,0x1234)
+
+ st2w r6,@(r7,r8)
+ st2w r6,@(r7+,r8)
+ st2w r6,@(r7-,r8)
+ st2w r6,@(r7,0x1a)
+ st2w r6,@(r7,0x1234)
+
+ st4hb r6,@(r7,r8)
+ st4hb r6,@(r7+,r8)
+ st4hb r6,@(r7-,r8)
+ st4hb r6,@(r7,0x1a)
+ st4hb r6,@(r7,0x1234)
+
+ stb r6,@(r7,r8)
+ stb r6,@(r7+,r8)
+ stb r6,@(r7-,r8)
+ stb r6,@(r7,0x1a)
+ stb r6,@(r7,0x1234)
+
+ sth r6,@(r7,r8)
+ sth r6,@(r7+,r8)
+ sth r6,@(r7-,r8)
+ sth r6,@(r7,0x1a)
+ sth r6,@(r7,0x1234)
+
+ sthh r6,@(r7,r8)
+ sthh r6,@(r7+,r8)
+ sthh r6,@(r7-,r8)
+ sthh r6,@(r7,0x1a)
+ sthh r6,@(r7,0x1234)
+
+ stw r6,@(r7,r8)
+ stw r6,@(r7+,r8)
+ stw r6,@(r7-,r8)
+ stw r6,@(r7,0x1a)
+ stw r6,@(r7,0x1234)
+
+ sub r1,r2,r3
+ sub r50,r51,0x1a
+ sub r50,r51,0xdeadbeef
+
+ sub2h r1,r2,r3
+ sub2h r50,r51,0x1a
+ sub2h r50,r51,0xdeadbeef
+
+ subb r1,r2,r3
+ subb r50,r51,0x1a
+ subb r50,r51,0xdeadbeef
+
+ subhlll r1,r2,r3
+ subhlll r50,r51,0x1a
+ subhlll r50,r51,0xdeadbeef
+
+ subhllh r1,r2,r3
+ subhllh r50,r51,0x1a
+ subhllh r50,r51,0xdeadbeef
+
+ subhlhl r1,r2,r3
+ subhlhl r50,r51,0x1a
+ subhlhl r50,r51,0xdeadbeef
+
+ subhlhh r1,r2,r3
+ subhlhh r50,r51,0x1a
+ subhlhh r50,r51,0xdeadbeef
+
+ subhhll r1,r2,r3
+ subhhll r50,r51,0x1a
+ subhhll r50,r51,0xdeadbeef
+
+ subhhlh r1,r2,r3
+ subhhlh r50,r51,0x1a
+ subhhlh r50,r51,0xdeadbeef
+
+ subhhhl r1,r2,r3
+ subhhhl r50,r51,0x1a
+ subhhhl r50,r51,0xdeadbeef
+
+ subhhhh r1,r2,r3
+ subhhhh r50,r51,0x1a
+ subhhhh r50,r51,0xdeadbeef
+
+ trap r1
+ trap 0xa
+
+ xor r1,r2,r4
+ xor r1,r2,0xa
+ xor r1,r2,0xdeadf00d
+
+ xorfg f1,f2,f4
+ xorfg f1,f4,0xa
+
+# VLIW syntax test
+ nop
+ nop
+ nop -> nop
+ nop || nop
+ nop <- nop
+
+# try changing sections
+ not r1,r2
+ .section .foo
+ add r10,r12,6
+ .text
+ not r2,r3
+ nop
+ \ No newline at end of file
diff --git a/gas/testsuite/gas/d30v/label-debug.d b/gas/testsuite/gas/d30v/label-debug.d
new file mode 100644
index 00000000000..e429f81e0f4
--- /dev/null
+++ b/gas/testsuite/gas/d30v/label-debug.d
@@ -0,0 +1,24 @@
+#objdump: -ldr
+#name: D30V debug (-g) test
+#as: -g
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <_abc-0x18>:
+.*label-debug.s:4
+ 0: 10080003 00f00000 bra.s\/tx 18 \(18 <_abc>\) \|\| nop
+.*label-debug.s:5
+ 8: 00f00000 00f00000 nop || nop
+ 10: 0e000004 00f00000 .long 0xe000004 || nop
+
+00000018 <_abc>:
+.*label-debug.s:8
+ 18: 00f00000 00f00000 nop || nop
+.*label-debug.s:9
+ 20: 00f00000 00f00000 nop || nop
+.*label-debug.s:10
+ 28: 00f00000 00f00000 nop || nop
+.*label-debug.s:11
+ 30: 00f00000 00f00000 nop || nop
diff --git a/gas/testsuite/gas/d30v/label-debug.s b/gas/testsuite/gas/d30v/label-debug.s
new file mode 100644
index 00000000000..9640aa49bd7
--- /dev/null
+++ b/gas/testsuite/gas/d30v/label-debug.s
@@ -0,0 +1,11 @@
+# labels should be aligned on 8-byte boundries
+
+ .text
+ bra.s/tx _abc || nop
+ nop || nop
+ .word 0x0e000004
+_abc:
+ nop
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/d30v/label.d b/gas/testsuite/gas/d30v/label.d
new file mode 100644
index 00000000000..66cfcdab740
--- /dev/null
+++ b/gas/testsuite/gas/d30v/label.d
@@ -0,0 +1,16 @@
+#objdump: -dr
+#name: D30V label alignment test
+#as:
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <_abc-0x18>:
+ 0: 10080003 00f00000 bra.s/tx 18 (18 <_abc>) || nop
+ 8: 00f00000 00f00000 nop || nop
+ 10: 0e000004 00f00000 .long 0xe000004 || nop
+
+00000018 <_abc>:
+ 18: 00f00000 80f00000 nop -> nop
+ 20: 00f00000 80f00000 nop -> nop
diff --git a/gas/testsuite/gas/d30v/label.s b/gas/testsuite/gas/d30v/label.s
new file mode 100644
index 00000000000..9640aa49bd7
--- /dev/null
+++ b/gas/testsuite/gas/d30v/label.s
@@ -0,0 +1,11 @@
+# labels should be aligned on 8-byte boundries
+
+ .text
+ bra.s/tx _abc || nop
+ nop || nop
+ .word 0x0e000004
+_abc:
+ nop
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/d30v/mul.d b/gas/testsuite/gas/d30v/mul.d
new file mode 100644
index 00000000000..04e0a550b15
--- /dev/null
+++ b/gas/testsuite/gas/d30v/mul.d
@@ -0,0 +1,20 @@
+#objdump: -dr
+#name: D30V alignment test
+#as: -WO
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 8a105187 0a1020c4 mulx2h r5, r6, r7 <- mulx2h r2, r3, r4
+ 8: 00f00000 0a10824a nop || mulx2h r8, r9, r10
+ 10: 00f00000 0a10b30d nop || mulx2h r11, r12, r13
+ 18: 8a111493 0a10e3d0 mulx2h r17, r18, r19 <- mulx2h r14, r15, r16
+ 20: 8a117619 0a114556 mulx2h r23, r24, r25 <- mulx2h r20, r21, r22
+ 28: 8b01d79f 0a11a6dc mul r29, r30, r31 <- mulx2h r26, r27, r28
+ 30: 8b005187 0b0020c4 mul r5, r6, r7 <- mul r2, r3, r4
+ 38: 8a10b30d 0a10824a mulx2h r11, r12, r13 <- mulx2h r8, r9, r10
+ 40: 80f00000 0b00e3d0 nop <- mul r14, r15, r16
+ 48: 00f00000 0a111493 nop || mulx2h r17, r18, r19
+ 50: 8b017619 0a114556 mul r23, r24, r25 <- mulx2h r20, r21, r22
diff --git a/gas/testsuite/gas/d30v/mul.s b/gas/testsuite/gas/d30v/mul.s
new file mode 100644
index 00000000000..fe678595067
--- /dev/null
+++ b/gas/testsuite/gas/d30v/mul.s
@@ -0,0 +1,19 @@
+# One of the rule on restricted sequence is consecutive IU instruction
+# IU: MUL, MAC, MACS, MSUB, MSUBS (a)
+# IU: MULHXpp, MULX2H, MUL2H (b)
+# This means that instructions in group (a) and in (b) should not be executed
+# in IU in consecutive cycles in the order (a)->(b). It does neither prohibit
+# executions in the reverse order (b)-> (a) nor consecutive execution of
+# group (a)->(a) or (b)->(b)
+
+ mulx2h r5,r6,r7 <- mulx2h r2,r3,r4
+ nop || mulx2h r8,r9,r10
+ nop || mulx2h r11,r12,r13
+ mulx2h r14,r15,r16
+ mulx2h r17,r18,r19
+ mulx2h r23,r24,r25 <- mulx2h r20,r21,r22
+ mul r29,r30,r31 <- mulx2h r26,r27,r28
+ mul r5, r6, r7 <- mul r2, r3, r4
+ mulx2h r11, r12, r13 <- mulx2h r8, r9, r10
+ mulx2h r17, r18, r19 <- mul r14, r15, r16
+ mul r23, r24, r25 <- mulx2h r20, r21, r22
diff --git a/gas/testsuite/gas/d30v/opt.d b/gas/testsuite/gas/d30v/opt.d
new file mode 100644
index 00000000000..b4bfa9c12fd
--- /dev/null
+++ b/gas/testsuite/gas/d30v/opt.d
@@ -0,0 +1,89 @@
+#objdump: -dr
+#name: D30V optimization test
+#as: -O
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <start>:
+ 0: 08801080 08803100 abs r1, r2 || abs r3, r4
+ 8: 02900100 02901080 notfg f0, s || notfg f1, f2
+ 10: 08801080 02901080 abs r1, r2 || notfg f1, f2
+ 18: 08001083 82907000 add.s r1, r2, r3 -> notfg c, f0
+ 20: 08001083 829001c0 add.s r1, r2, r3 -> notfg f0, c
+ 28: 00080000 00f00000 bra.s 0 \(28 <start\+0x28>\) || nop
+ 30: 08801080 88801080 abs r1, r2 -> abs r1, r2
+ 38: 00080000 00f00000 bra.s 0 \(38 <start\+0x38>\) || nop
+ 40: 002bffff 00f00000 bsr.s -8 \(38 <start\+0x38>\) || nop
+ 48: 08801080 88801080 abs r1, r2 -> abs r1, r2
+ 50: 00280000 08801080 bsr.s 0 \(50 <start\+0x50>\) || abs r1, r2
+ 58: 04001083 85007209 ldb.s r1, @\(r2, r3\) -> stb.s r7, @\(r8, r9\)
+ 60: 05007209 84001083 stb.s r7, @\(r8, r9\) -> ldb.s r1, @\(r2, r3\)
+ 68: 04007209 84001083 ldb.s r7, @\(r8, r9\) -> ldb.s r1, @\(r2, r3\)
+ 70: 05007209 85001083 stb.s r7, @\(r8, r9\) -> stb.s r1, @\(r2, r3\)
+ 78: 080030c6 854820c0 add.s r3, r3, r6 -> stw.s r2, @\(r3, 0x0\)
+ 80: 02c28105 90180000 cmple.s f0, r4, r5 -> jmp.s/tx 0 <start>
+ 88: 02c28105 a0180000 cmple.s f0, r4, r5 -> jmp.s/fx 0 <start>
+ 90: 30180000 02c28105 jmp.s/xt 0 <start> || cmple.s f0, r4, r5
+ 98: 40180000 02c28105 jmp.s/xf 0 <start> || cmple.s f0, r4, r5
+ a0: 02c28105 d0180000 cmple.s f0, r4, r5 -> jmp.s/tt 0 <start>
+ a8: 02c28105 e0180000 cmple.s f0, r4, r5 -> jmp.s/tf 0 <start>
+ b0: 10180000 02c29105 jmp.s/tx 0 <start> || cmple.s f1, r4, r5
+ b8: 02c29105 b0180000 cmple.s f1, r4, r5 -> jmp.s/xt 0 <start>
+ c0: 08084001 82c28105 add.s r4, r0, 0x1 -> cmple.s f0, r4, r5
+ c8: 08084001 02c280c5 add.s r4, r0, 0x1 || cmple.s f0, r3, r5
+ d0: 04604006 886054d4 ld2w.s r4, @\(r0, r6\) -> adds.s r5, r19, r20
+ d8: 04604006 88603154 ld2w.s r4, @\(r0, r6\) -> adds.s r3, r5, r20
+ e0: 04604006 086064d4 ld2w.s r4, @\(r0, r6\) || adds.s r6, r19, r20
+ e8: 04604006 086074d4 ld2w.s r4, @\(r0, r6\) || adds.s r7, r19, r20
+ f0: 04604006 08607014 ld2w.s r4, @\(r0, r6\) || adds.s r7, r0, r20
+ f8: 05604006 086054d4 st2w.s r4, @\(r0, r6\) || adds.s r5, r19, r20
+ 100: 05604006 08603154 st2w.s r4, @\(r0, r6\) || adds.s r3, r5, r20
+ 108: 05604006 086064d4 st2w.s r4, @\(r0, r6\) || adds.s r6, r19, r20
+ 110: 05604006 086074d4 st2w.s r4, @\(r0, r6\) || adds.s r7, r19, r20
+ 118: 05604006 08607014 st2w.s r4, @\(r0, r6\) || adds.s r7, r0, r20
+ 120: 0560a0c4 85628aec st2w.s r10, @\(r3, r4\) -> st2w.s r40, @\(r43, r44\)
+ 128: 05401083 84429aab stw.s r1, @\(r2, r3\) -> ldw.s r41, @\(r42, r43\)
+ 130: 04401083 84029aab ldw.s r1, @\(r2, r3\) -> ldb.s r41, @\(r42, r43\)
+ 138: 0444418b 88689182 ldw.s r4, @\(r6\+, r11\) -> adds.s r9, r6, 0x2
+ 140: 044c418b 08689182 ldw.s r4, @\(r6-, r11\) || adds.s r9, r6, 0x2
+ 148: 054c418b 88689182 stw.s r4, @\(r6-, r11\) -> adds.s r9, r6, 0x2
+ 150: 0440418b 08689182 ldw.s r4, @\(r6, r11\) || adds.s r9, r6, 0x2
+ 158: 0440418b 08689182 ldw.s r4, @\(r6, r11\) || adds.s r9, r6, 0x2
+ 160: 00180000 00f00000 jmp.s 0 <start> || nop
+ 168: 00380000 08801080 jsr.s 0 <start> || abs r1, r2
+ 170: 08801080 00f00000 abs r1, r2 || nop
+ 178: 00080000 00f00000 bra.s 0 \(178 <start\+0x178>\) || nop
+ 180: 00280000 08801080 bsr.s 0 \(180 <start\+0x180>\) || abs r1, r2
+ 188: 08801080 00f00000 abs r1, r2 || nop
+
+00000190 <label1>:
+ 190: 05602083 89004146 st2w.s r2, @\(r2, r3\) -> addhlll.s r4, r5, r6
+
+00000198 <label2>:
+ 198: 05508209 8990a2cc st4hb.s r8, @\(r8, r9\) -> subhllh.s r10, r11, r12
+
+000001a0 <label3>:
+ 1a0: 0460e38f 8a610452 ld2w.s r14, @\(r14, r15\) -> mulhxhl r16, r17, r18
+
+000001a8 <label4>:
+ 1a8: 04413515 8a1165d8 ldw.s r19, @\(r20, r21\) -> mulx2h r22, r23, r24
+
+000001b0 <label5>:
+ 1b0: 0421969b 8a01c75e ldh.s r25, @\(r26, r27\) -> mul2h r28, r29, r30
+
+000001b8 <label6>:
+ 1b8: 80f00000 0b001083 nop <- mul r1, r2, r3
+ 1c0: 08007209 0a404146 add.s r7, r8, r9 || mulhxll r4, r5, r6
+
+000001c8 <label7>:
+ 1c8: 04405180 0b0020c4 ldw.s r5, @\(r6, r0\) || mul r2, r3, r4
+ 1d0: 80f00000 0b007209 nop <- mul r7, r8, r9
+ 1d8: 0440a2c0 00f00000 ldw.s r10, @\(r11, r0\) || nop
+ 1e0: 80f00000 0b00c34e nop <- mul r12, r13, r14
+ 1e8: 0440f400 0b4420c4 ldw.s r15, @\(r16, r0\) || mac1 r2, r3, r4
+ 1f0: 00f00000 00f00000 nop || nop
+ 1f8: 04405180 00f00000 ldw.s r5, @\(r6, r0\) || nop
+ 200: 80f00000 0b407209 nop <- mac0 r7, r8, r9
+ 208: 0440a2c0 8440a2c0 ldw.s r10, @\(r11, r0\) -> ldw.s r10, @\(r11, r0\)
diff --git a/gas/testsuite/gas/d30v/opt.s b/gas/testsuite/gas/d30v/opt.s
new file mode 100644
index 00000000000..573330027ec
--- /dev/null
+++ b/gas/testsuite/gas/d30v/opt.s
@@ -0,0 +1,216 @@
+# D30V parallel optimization test
+# assemble with "-O"
+
+ .text
+start:
+ abs r1,r2
+ abs r3,r4
+
+ notfg f0,f4
+ notfg f1,f2
+
+ abs r1,r2
+ notfg f1,f2
+
+# both change C flag
+ add r1,r2,r3
+ notfg C,f0
+
+# one uses and one changes C flag
+ add r1,r2,r3
+ notfg f0,C
+
+ bra .
+ abs r1,r2
+
+ abs r1,r2
+ bra .
+
+ bsr .
+ abs r1,r2
+
+ abs r1,r2
+ abs r1,r2
+ bsr .
+
+ ldb r1,@(r2,r3)
+ stb r7,@(r8,r9)
+
+ stb r7,@(r8,r9)
+ ldb r1,@(r2,r3)
+
+ ldb r7,@(r8,r9)
+ ldb r1,@(r2,r3)
+
+ stb r7,@(r8,r9)
+ stb r1,@(r2,r3)
+
+ add r3, r3, r6
+ stw r2, @(r3, 0)
+
+# should be serial because of conditional execution
+ cmple f0,r4,r5
+ jmp/tx 0x0
+
+ cmple f0,r4,r5
+ jmp/fx 0x0
+
+ cmple f0,r4,r5
+ jmp/xt 0x0
+
+ cmple f0,r4,r5
+ jmp/xf 0x0
+
+ cmple f0,r4,r5
+ jmp/tt 0x0
+
+ cmple f0,r4,r5
+ jmp/tf 0x0
+
+ cmple f1,r4,r5
+ jmp/tx 0x0
+
+ cmple f1,r4,r5
+ jmp/xt 0x0
+
+ # serial because of the r4 dependency
+ add r4, r0, 1
+ cmple f0, r4, r5
+
+ # parallel
+ add r4, r0, 1
+ cmple f0, r3, r5
+
+ # serial because ld2w loads r5
+ ld2w r4,@(r0,r6)
+ adds r5,r19,r20
+
+ # serial because ld2w loads r5
+ ld2w r4,@(r0,r6)
+ adds r3,r5,r20
+
+ # parallel even though ld2w uses r6 and adds changes it
+ ld2w r4,@(r0,r6)
+ adds r6,r19,r20
+
+ # parallel
+ ld2w r4,@(r0,r6)
+ adds r7,r19,r20
+
+ # parallel
+ ld2w r4,@(r0,r6)
+ adds r7,r0,r20
+
+ # parallel even though st2w uses r5 and adds modifies it
+ st2w r4,@(r0,r6)
+ adds r5,r19,r20
+
+ # parallel, both use but don't modify r5
+ st2w r4,@(r0,r6)
+ adds r3,r5,r20
+
+ # parallel even though st2w uses r6 and adds changes it
+ st2w r4,@(r0,r6)
+ adds r6,r19,r20
+
+ # parallel
+ st2w r4,@(r0,r6)
+ adds r7,r19,r20
+
+ # parallel
+ st2w r4,@(r0,r6)
+ adds r7,r0,r20
+
+# test memory dependencies
+
+ # always serial because one could overwrite the other
+ st2w r10,@(r3,r4)
+ st2w r40,@(r43,r44)
+
+ # always serial
+ stw r1,@(r2,r3)
+ ldw r41,@(r42,r43)
+
+ # reads can happen in parallel but the current architecture
+ # doesn't support it
+ ldw r1,@(r2,r3)
+ ldb r41,@(r42,r43)
+
+# test post increment and decrement dependencies
+
+ # serial
+ ldw r4,@(r6+,r11)
+ adds r9,r6,2
+
+ # parallel, modification to r6 happens last
+ adds r9,r6,2
+ ldw r4,@(r6-,r11)
+
+ # serial
+ stw r4,@(r6-,r11)
+ adds r9,r6,2
+
+ # parallel
+ ldw r4,@(r6,r11)
+ adds r9,r6,2
+
+ # parallel
+ adds r9,r6,2
+ ldw r4,@(r6,r11)
+
+# if the first instruction is a jmp, don't parallelize
+ jmp 0
+ abs r1,r2
+
+ jsr 0
+ abs r1,r2
+
+ .align 3
+
+ bra 0
+ abs r1,r2
+
+ bsr 0
+ abs r1,r2
+
+# Explicitly prohibited from parallel execution.
+# The labels are here to prevent instruction pairs
+# from being merged with following pairs.
+
+label1:
+ st2w r2, @(r2, r3)
+ addhlll r4, r5, r6
+label2:
+ st4hb r8, @(r8, r9)
+ subhllh r10, r11, r12
+label3:
+ ld2w r14, @(r14, r15)
+ mulhxhl r16, r17, r18
+label4:
+ ldw r19, @(r20, r21)
+ mulx2h r22, r23, r24
+label5:
+ ldh r25, @(r26, r27)
+ mul2h r28, r29, r30
+
+# Insertion of NOPs required to prevent pipeline clashes.
+
+label6:
+ mul r1,r2,r3
+ mulhxll r4,r5,r6
+ add r7, r8, r9
+label7:
+
+ mul r2,r3,r4
+ ldw r5, @(r6,r0)
+
+ ldw r10, @(r11, r0) <- mul r7,r8,r9
+
+ mul r12,r13,r14 -> ldw r15, @(r16, r0)
+
+ mac1 r2,r3,r4
+ ldw r5, @(r6,r0)
+
+ ldw r10, @(r11, r0) <- mac0 r7,r8,r9
+ ldw r10, @(r11, r0)
+
diff --git a/gas/testsuite/gas/d30v/reloc.d b/gas/testsuite/gas/d30v/reloc.d
new file mode 100644
index 00000000000..1de2780b483
--- /dev/null
+++ b/gas/testsuite/gas/d30v/reloc.d
@@ -0,0 +1,93 @@
+#objdump: -dr
+#name: D30V relocation test
+#as:
+
+.*: +file format elf32-d30v
+
+Disassembly of section .text:
+
+00000000 <start>:
+ 0: 88082000 80000028 add.l r2, r0, 0x28
+ 0: R_D30V_32 .text
+ 8: 88084000 80000000 add.l r4, r0, 0x0
+ 8: R_D30V_32 .data
+ 10: 88084000 80000006 add.l r4, r0, 0x6
+ 10: R_D30V_32 .data
+ 18: 88084000 80000000 add.l r4, r0, 0x0
+ 18: R_D30V_32 unk
+ 20: 80080000 80000018 bra.l 18 \(38 <cont>\)
+
+00000028 <hello>:
+ 28: 48656c6c 6f20576f .long 0x48656c6c || .long 0x6f20576f
+ 30: 726c640a 00f00000 .long 0x726c640a || nop
+
+00000038 <cont>:
+ 38: 80180000 80000048 jmp.l 48 <cont2>
+ 38: R_D30V_32 .text
+ 40: 088020c0 00f00000 abs r2, r3 || nop
+
+00000048 <cont2>:
+ 48: 000bfff7 00f00000 bra.s -48 \(0 <start>\) || nop
+ 50: 00080205 00f00000 bra.s 1028 \(1078 <exit>\) || nop
+ 58: 00180000 00f00000 jmp.s 0 <start> || nop
+ 60: 006c1ffb 00f00000 bsrtnz.s r1, -28 \(38 <cont>\) || nop
+ 68: 006c1ffa 00f00000 bsrtnz.s r1, -30 \(38 <cont>\) || nop
+ 70: 004c1ff9 00f00000 bratnz.s r1, -38 \(38 <cont>\) || nop
+ 78: 004c1ff8 00f00000 bratnz.s r1, -40 \(38 <cont>\) || nop
+ 80: 005c1007 00f00000 jmptnz.s r1, 38 <cont> || nop
+ 80: R_D30V_15 .text
+ 88: 006c11f1 00f00000 bsrtnz.s r1, f88 \(1010 <foo>\) || nop
+ 90: 005c1000 00f00000 jmptnz.s r1, 0 <start> || nop
+ 90: R_D30V_15 unk
+ 98: 006c1000 00f00000 bsrtnz.s r1, 0 \(98 <cont2\+0x50>\) || nop
+ 98: R_D30V_15_PCREL unk
+ a0: 805c1000 80000000 jmptnz.l r1, 0 <start>
+ a0: R_D30V_32 unk
+ a8: 806c1000 80000000 bsrtnz.l r1, 0 \(a8 <cont2\+0x60>\)
+ a8: R_D30V_32_PCREL unk
+ b0: 000801ec 00f00000 bra.s f60 \(1010 <foo>\) || nop
+ b8: 80080000 80000f58 bra.l f58 \(1010 <foo>\)
+ c0: 000bffe8 00f00000 bra.s -c0 \(0 <start>\) || nop
+ c8: 80180000 80000000 jmp.l 0 <start>
+ c8: R_D30V_32 .text
+ d0: 80180000 80000000 jmp.l 0 <start>
+ d0: R_D30V_32 .text
+ d8: 00180000 00f00000 jmp.s 0 <start> || nop
+ d8: R_D30V_21 .text
+ e0: 00180202 00f00000 jmp.s 1010 <foo> || nop
+ e0: R_D30V_21 .text
+ e8: 000bffe3 00f00000 bra.s -e8 \(0 <start>\) || nop
+ f0: 80080000 80000000 bra.l 0 \(f0 <cont2\+0xa8>\)
+ f0: R_D30V_32_PCREL unknown
+ f8: 80180000 80000000 jmp.l 0 <start>
+ f8: R_D30V_32 unknown
+ 100: 00180000 00f00000 jmp.s 0 <start> || nop
+ 100: R_D30V_21 unknown
+ 108: 00080000 00f00000 bra.s 0 \(108 <cont2\+0xc0>\) || nop
+ 108: R_D30V_21_PCREL unknown
+ ...
+
+00001010 <foo>:
+ 1010: 08001000 00f00000 add.s r1, r0, r0 || nop
+ 1018: 846bc000 80001070 ld2w.l r60, @\(r0, 0x1070\)
+ 1018: R_D30V_32 .text
+ 1020: 0803e000 8028000b add.s r62, r0, r0 -> bsr.s 58 \(1078 <exit>\)
+ 1028: 002bfffd 00f00000 bsr.s -18 \(1010 <foo>\) || nop
+ 1030: 000bfe03 00f00000 bra.s -fe8 \(48 <cont2>\) || nop
+ 1038: 000bfe02 00f00000 bra.s -ff0 \(48 <cont2>\) || nop
+ 1040: 00280007 00f00000 bsr.s 38 \(1078 <exit>\) || nop
+ 1048: 0018020f 00f00000 jmp.s 1078 <exit> || nop
+ 1048: R_D30V_21 .text
+ 1050: 0018020f 00f00000 jmp.s 1078 <exit> || nop
+ 1050: R_D30V_21 .text
+ 1058: 0018020f 00f00000 jmp.s 1078 <exit> || nop
+ 1058: R_D30V_21 .text
+ 1060: 80280000 80000018 bsr.l 18 \(1078 <exit>\)
+ 1068: 80180000 80001078 jmp.l 1078 <exit>
+ 1068: R_D30V_32 .text
+
+00001070 <longzero>:
+ ...
+
+00001078 <exit>:
+ 1078: 0010003e 00f00000 jmp.s r62 || nop
diff --git a/gas/testsuite/gas/d30v/reloc.s b/gas/testsuite/gas/d30v/reloc.s
new file mode 100644
index 00000000000..2a99bf9447e
--- /dev/null
+++ b/gas/testsuite/gas/d30v/reloc.s
@@ -0,0 +1,68 @@
+# D30V relocation test
+
+ .text
+start:
+ add r2, r0, hello
+ add r4, r0, bar
+ add r4, r0, bar2
+ add r4, r0, unk
+ bra cont
+hello: .ascii "Hello World\n"
+ .align 3
+cont: jmp cont2
+ abs r2,r3
+cont2:
+ bra start || nop
+ bra.s exit
+ jmp 0 || nop
+ bsrtnz.s r1,cont
+ bsrtnz r1,cont
+ bratnz.s r1,cont
+ bratnz r1,cont
+ jmptnz.s r1,cont
+ bsrtnz.s r1, foo
+ jmptnz.s r1, unk
+ bsrtnz.s r1, unk
+ jmptnz r1, unk
+ bsrtnz r1, unk
+ bra.s foo
+ bra foo
+ bra start
+ jmp start
+ jmp start
+ jmp.s start
+ jmp.s foo
+ bra start
+ bra unknown
+ jmp unknown
+ jmp.s unknown
+ bra.s unknown
+
+ .data
+bar: .asciz "XYZZY"
+bar2: .long 0xdeadbeef
+
+ .text
+ .space 0xF00,0
+
+foo:
+ add r1,r0,r0
+ ld2w r60, @(r0,longzero)
+ add r62,r0,r0
+ bsr.s exit
+ bsr.s foo
+ bra.s cont2
+ bra.s cont2
+ bsr.s exit
+ jmp.s exit
+ jmp.s exit
+ jmp.s exit
+ bsr exit
+ jmp exit
+
+longzero:
+ .quad 0
+
+ .text
+exit:
+ jmp r62
diff --git a/gas/testsuite/gas/d30v/serial.l b/gas/testsuite/gas/d30v/serial.l
new file mode 100644
index 00000000000..f7a5a670766
--- /dev/null
+++ b/gas/testsuite/gas/d30v/serial.l
@@ -0,0 +1,46 @@
+.*: Assembler messages:
+.*:6: Error: Unable to mix instructions as specified
+.*:7: Error: Unable to mix instructions as specified
+.*:8: Error: Unable to mix instructions as specified
+.*:9: Error: Unable to mix instructions as specified
+GAS LISTING .*
+
+
+ 1 # serial.s
+ 2 #
+ 3 # In the following examples, the right-subinstructions
+ 4 # will never be executed. GAS should detect this.
+ 5
+ 6 \?\?\?\? 000000F0 trap r21 -> add r2, r0, r0 ; right instruction will never be executed.
+\*\*\*\* Error:Unable to mix instructions as specified
+ 6 000000F0
+ 6 000000F0
+ 6 00000090
+ 6 001500F0
+ 7 \?\?\?\? 08002000 dbt -> add r2, r0, r0 ; ditto
+\*\*\*\* Error:Unable to mix instructions as specified
+ 7 00F00000
+ 7 00B00000
+ 7 00F00000
+ 8 \?\?\?\? 08002000 rtd -> add r2, r0, r0 ; ditto
+\*\*\*\* Error:Unable to mix instructions as specified
+ 8 00F00000
+ 8 00A00000
+ 8 00F00000
+ 9 \?\?\?\? 08002000 reit -> add r2, r0, r0 ; ditto
+\*\*\*\* Error:Unable to mix instructions as specified
+ 9 00F00000
+ 9 00800000
+ 9 00F00000
+ 10 \?\?\?\? 08002000 mvtsys psw, r1 -> add r2, r0, r0 ; OK
+ 10 00F00000
+ 10 00E00040
+ 10 88002000
+ 11 \?\?\?\? 00E00042 mvtsys pswh, r1 -> add r2, r0, r0 ; OK
+ 11 88002000
+ 12 \?\?\?\? 00E00041 mvtsys pswl, r1 -> add r2, r0, r0 ; OK
+ 12 88002000
+ 13 \?\?\?\? 00E00043 mvtsys f0, r1 -> add r2, r0, r0 ; OK
+ 13 88002000
+ 14 \?\?\?\? 00E0A040 mvtsys mod_s, r1 -> add r2, r0, r0 ; OK
+ 14 88002000
diff --git a/gas/testsuite/gas/d30v/serial.s b/gas/testsuite/gas/d30v/serial.s
new file mode 100644
index 00000000000..0995d634b84
--- /dev/null
+++ b/gas/testsuite/gas/d30v/serial.s
@@ -0,0 +1,14 @@
+# serial.s
+#
+# In the following examples, the right-subinstructions
+# will never be executed. GAS should detect this.
+
+ trap r21 -> add r2, r0, r0 ; right instruction will never be executed.
+ dbt -> add r2, r0, r0 ; ditto
+ rtd -> add r2, r0, r0 ; ditto
+ reit -> add r2, r0, r0 ; ditto
+ mvtsys psw, r1 -> add r2, r0, r0 ; OK
+ mvtsys pswh, r1 -> add r2, r0, r0 ; OK
+ mvtsys pswl, r1 -> add r2, r0, r0 ; OK
+ mvtsys f0, r1 -> add r2, r0, r0 ; OK
+ mvtsys mod_s, r1 -> add r2, r0, r0 ; OK
diff --git a/gas/testsuite/gas/d30v/serial2.l b/gas/testsuite/gas/d30v/serial2.l
new file mode 100644
index 00000000000..2de04dc2dbb
--- /dev/null
+++ b/gas/testsuite/gas/d30v/serial2.l
@@ -0,0 +1,138 @@
+.*: Assembler messages:
+.*:5: Error: Unable to mix instructions as specified
+.*:6: Error: Unable to mix instructions as specified
+.*:8: Error: Unable to mix instructions as specified
+.*:9: Error: Unable to mix instructions as specified
+.*:11: Error: Unable to mix instructions as specified
+.*:12: Error: Unable to mix instructions as specified
+.*:13: Error: Unable to mix instructions as specified
+.*:14: Error: Unable to mix instructions as specified
+.*:16: Error: Unable to mix instructions as specified
+.*:17: Error: Unable to mix instructions as specified
+.*:18: Error: Unable to mix instructions as specified
+.*:19: Error: Unable to mix instructions as specified
+.*:21: Error: Unable to mix instructions as specified
+.*:22: Error: Unable to mix instructions as specified
+.*:23: Error: Unable to mix instructions as specified
+.*:24: Error: Unable to mix instructions as specified
+.*:26: Error: Unable to mix instructions as specified
+.*:27: Error: Unable to mix instructions as specified
+.*:28: Error: Unable to mix instructions as specified
+.*:29: Error: Unable to mix instructions as specified
+GAS LISTING .*
+
+
+ 1 # D30V serial execution test
+ 2
+ 3 .text
+ 4
+ 5 \?\?\?\? 000000F0 bra -3 -> add r3,r0,0 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 5 000000F0
+ 5 000000F0
+ 5 0000000B
+ 5 FFFF00F0
+ 6 \?\?\?\? 08083000 bsr -3 -> add r3,r0,0 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 6 00F00000
+ 6 002BFFFF
+ 6 00F00000
+ 7
+ 8 \?\?\?\? 08083000 bra/tx -3 -> add r3,r0,0 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 8 00F00000
+ 8 100BFFFF
+ 8 00F00000
+ 9 \?\?\?\? 08083000 bsr/tx -3 -> add r3,r0,0 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 9 00F00000
+ 9 102BFFFF
+ 9 00F00000
+ 10
+ 11 \?\?\?\? 08083000 bsr -3 -> bsr -10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 11 00F00000
+ 11 002BFFFF
+ 11 00F00000
+ 12 \?\?\?\? 002BFFFE bsr -3 -> bsr/xt -10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 12 00F00000
+ 12 002BFFFF
+ 12 00F00000
+ 13 \?\?\?\? 302BFFFE bsr/tx -3 -> bsr -10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 13 00F00000
+ 13 102BFFFF
+ 13 00F00000
+ 14 \?\?\?\? 002BFFFE bsr/tx -3 -> bsr/fx -10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 14 00F00000
+ 14 102BFFFF
+ 14 00F00000
+ 15
+ 16 \?\?\?\? 202BFFFE bra -3 -> bra 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 16 00F00000
+ 16 000BFFFF
+ 16 00F00000
+ 17 \?\?\?\? 00080001 bra -3 -> bra/tx 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 17 00F00000
+ 17 000BFFFF
+ GAS LISTING .*
+
+
+ 17 00F00000
+ 18 \?\?\?\? 10080001 bra/tx -3 -> bra 10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 18 00F00000
+ 18 100BFFFF
+ 18 00F00000
+ 19 \?\?\?\? 00080001 bra/tx -3 -> bra/fx 10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 19 00F00000
+ 19 100BFFFF
+ 19 00F00000
+ 20
+ 21 \?\?\?\? 20080001 bsr -3 -> bra 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 21 00F00000
+ 21 002BFFFF
+ 21 00F00000
+ 22 \?\?\?\? 00080001 bsr -3 -> bra/tx 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 22 00F00000
+ 22 002BFFFF
+ 22 00F00000
+ 23 \?\?\?\? 10080001 bsr/tx -3 -> bra 10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 23 00F00000
+ 23 102BFFFF
+ 23 00F00000
+ 24 \?\?\?\? 00080001 bsr/tx -3 -> bra/fx 10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 24 00F00000
+ 24 102BFFFF
+ 24 00F00000
+ 25
+ 26 \?\?\?\? 20080001 bra -3 -> bsr 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 26 00F00000
+ 26 000BFFFF
+ 26 00F00000
+ 27 \?\?\?\? 00280001 bra -3 -> bsr/tx 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 27 00F00000
+ 27 000BFFFF
+ 27 00F00000
+ 28 \?\?\?\? 10280001 bra/tx -3 -> bsr 10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 28 00F00000
+ 28 100BFFFF
+ 28 00F00000
+ 29 \?\?\?\? 00280001 bra/tx -3 -> bsr/fx 10 ; Valid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 29 00F00000
+ 29 100BFFFF
+ 29 00F00000
+ 29 20280001
diff --git a/gas/testsuite/gas/d30v/serial2.s b/gas/testsuite/gas/d30v/serial2.s
new file mode 100644
index 00000000000..04531590228
--- /dev/null
+++ b/gas/testsuite/gas/d30v/serial2.s
@@ -0,0 +1,29 @@
+# D30V serial execution test
+
+ .text
+
+ bra -3 -> add r3,r0,0 ; Invalid
+ bsr -3 -> add r3,r0,0 ; Invalid
+
+ bra/tx -3 -> add r3,r0,0 ; Valid
+ bsr/tx -3 -> add r3,r0,0 ; Valid
+
+ bsr -3 -> bsr -10 ; Invalid
+ bsr -3 -> bsr/xt -10 ; Invalid
+ bsr/tx -3 -> bsr -10 ; Valid
+ bsr/tx -3 -> bsr/fx -10 ; Valid
+
+ bra -3 -> bra 10 ; Invalid
+ bra -3 -> bra/tx 10 ; Invalid
+ bra/tx -3 -> bra 10 ; Valid
+ bra/tx -3 -> bra/fx 10 ; Valid
+
+ bsr -3 -> bra 10 ; Invalid
+ bsr -3 -> bra/tx 10 ; Invalid
+ bsr/tx -3 -> bra 10 ; Valid
+ bsr/tx -3 -> bra/fx 10 ; Valid
+
+ bra -3 -> bsr 10 ; Invalid
+ bra -3 -> bsr/tx 10 ; Invalid
+ bra/tx -3 -> bsr 10 ; Valid
+ bra/tx -3 -> bsr/fx 10 ; Valid
diff --git a/gas/testsuite/gas/d30v/serial2O.l b/gas/testsuite/gas/d30v/serial2O.l
new file mode 100644
index 00000000000..d9eb05cb1a9
--- /dev/null
+++ b/gas/testsuite/gas/d30v/serial2O.l
@@ -0,0 +1,99 @@
+.*: Assembler messages:
+.*:5: Error: Unable to mix instructions as specified
+.*:6: Error: Unable to mix instructions as specified
+.*:11: Error: Unable to mix instructions as specified
+.*:12: Error: Unable to mix instructions as specified
+.*:16: Error: Unable to mix instructions as specified
+.*:17: Error: Unable to mix instructions as specified
+.*:21: Error: Unable to mix instructions as specified
+.*:22: Error: Unable to mix instructions as specified
+.*:26: Error: Unable to mix instructions as specified
+.*:27: Error: Unable to mix instructions as specified
+GAS LISTING .*
+
+
+ 1 # D30V serial execution test
+ 2
+ 3 .text
+ 4
+ 5 \?\?\?\? 000000F0 bra -3 -> add r3,r0,0 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 5 000000F0
+ 5 000000F0
+ 5 0000000B
+ 5 FFFF00F0
+ 6 \?\?\?\? 08083000 bsr -3 -> add r3,r0,0 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 6 00F00000
+ 6 002BFFFF
+ 6 00F00000
+ 7
+ 8 \?\?\?\? 08083000 bra/tx -3 -> add r3,r0,0 ; Valid
+ 8 00F00000
+ 8 100BFFFF
+ 8 88083000
+ 9 \?\?\?\? 102BFFFF bsr/tx -3 -> add r3,r0,0 ; Valid
+ 9 88083000
+ 10
+ 11 \?\?\?\? 002BFFFF bsr -3 -> bsr -10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 11 00F00000
+ 12 \?\?\?\? 002BFFFE bsr -3 -> bsr/xt -10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 12 00F00000
+ 12 002BFFFF
+ 12 00F00000
+ 13 \?\?\?\? 302BFFFE bsr/tx -3 -> bsr -10 ; Valid
+ 13 00F00000
+ 13 102BFFFF
+ 13 802BFFFE
+ 14 \?\?\?\? 102BFFFF bsr/tx -3 -> bsr/fx -10 ; Valid
+ 14 A02BFFFE
+ 15
+ 16 \?\?\?\? 000BFFFF bra -3 -> bra 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 16 00F00000
+ 17 \?\?\?\? 00080001 bra -3 -> bra/tx 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 17 00F00000
+ 17 000BFFFF
+ 17 00F00000
+ 18 \?\?\?\? 10080001 bra/tx -3 -> bra 10 ; Valid
+ 18 00F00000
+ 18 100BFFFF
+ 18 80080001
+ 19 \?\?\?\? 100BFFFF bra/tx -3 -> bra/fx 10 ; Valid
+ 19 A0080001
+ 20
+ 21 \?\?\?\? 002BFFFF bsr -3 -> bra 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 21 00F00000
+ 22 \?\?\?\? 00080001 bsr -3 -> bra/tx 10 ; Invalid
+ GAS LISTING .*
+
+
+\*\*\*\* Error:Unable to mix instructions as specified
+ 22 00F00000
+ 22 002BFFFF
+ 22 00F00000
+ 23 \?\?\?\? 10080001 bsr/tx -3 -> bra 10 ; Valid
+ 23 00F00000
+ 23 102BFFFF
+ 23 80080001
+ 24 \?\?\?\? 102BFFFF bsr/tx -3 -> bra/fx 10 ; Valid
+ 24 A0080001
+ 25
+ 26 \?\?\?\? 000BFFFF bra -3 -> bsr 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 26 00F00000
+ 27 \?\?\?\? 00280001 bra -3 -> bsr/tx 10 ; Invalid
+\*\*\*\* Error:Unable to mix instructions as specified
+ 27 00F00000
+ 27 000BFFFF
+ 27 00F00000
+ 28 \?\?\?\? 10280001 bra/tx -3 -> bsr 10 ; Valid
+ 28 00F00000
+ 28 100BFFFF
+ 28 80280001
+ 29 \?\?\?\? 100BFFFF bra/tx -3 -> bsr/fx 10 ; Valid
+ 29 A0280001
diff --git a/gas/testsuite/gas/d30v/serial2O.s b/gas/testsuite/gas/d30v/serial2O.s
new file mode 100644
index 00000000000..04531590228
--- /dev/null
+++ b/gas/testsuite/gas/d30v/serial2O.s
@@ -0,0 +1,29 @@
+# D30V serial execution test
+
+ .text
+
+ bra -3 -> add r3,r0,0 ; Invalid
+ bsr -3 -> add r3,r0,0 ; Invalid
+
+ bra/tx -3 -> add r3,r0,0 ; Valid
+ bsr/tx -3 -> add r3,r0,0 ; Valid
+
+ bsr -3 -> bsr -10 ; Invalid
+ bsr -3 -> bsr/xt -10 ; Invalid
+ bsr/tx -3 -> bsr -10 ; Valid
+ bsr/tx -3 -> bsr/fx -10 ; Valid
+
+ bra -3 -> bra 10 ; Invalid
+ bra -3 -> bra/tx 10 ; Invalid
+ bra/tx -3 -> bra 10 ; Valid
+ bra/tx -3 -> bra/fx 10 ; Valid
+
+ bsr -3 -> bra 10 ; Invalid
+ bsr -3 -> bra/tx 10 ; Invalid
+ bsr/tx -3 -> bra 10 ; Valid
+ bsr/tx -3 -> bra/fx 10 ; Valid
+
+ bra -3 -> bsr 10 ; Invalid
+ bra -3 -> bsr/tx 10 ; Invalid
+ bra/tx -3 -> bsr 10 ; Valid
+ bra/tx -3 -> bsr/fx 10 ; Valid
diff --git a/gas/testsuite/gas/d30v/warn_oddreg.l b/gas/testsuite/gas/d30v/warn_oddreg.l
new file mode 100644
index 00000000000..f1fb43cb2ca
--- /dev/null
+++ b/gas/testsuite/gas/d30v/warn_oddreg.l
@@ -0,0 +1,40 @@
+.*: Assembler messages:
+.*:5: Warning: Odd numbered register used as target of multi-register instruction
+.*:6: Warning: Odd numbered register used as target of multi-register instruction
+.*:7: Warning: Odd numbered register used as target of multi-register instruction
+.*:8: Warning: Odd numbered register used as target of multi-register instruction
+.*:9: Warning: Odd numbered register used as target of multi-register instruction
+.*:10: Warning: Odd numbered register used as target of multi-register instruction
+.*:11: Warning: Odd numbered register used as target of multi-register instruction
+.*:12: Warning: Odd numbered register used as target of multi-register instruction
+GAS LISTING .*
+
+
+ 1 # GAS should print a warning when an odd register is used as a target
+ 2 # of multi-word instructions: ld2w, ld4bh, ld4bhu, ld2h, st2w, st4hb, st2h,
+ 3 # and mulx2h
+ 4
+ 5 0000 05681000 st2w r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 5 00F00000
+ 6 0008 04681000 ld2w r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 6 00F00000
+ 7 0010 04581000 ld4bh r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 7 00F00000
+ 8 0018 04D81000 ld4bhu r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 8 00F00000
+ 9 0020 04381000 ld2h r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 9 00F00000
+ 10 0028 05581000 st4hb r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 10 00F00000
+ 11 0030 05381000 st2h r1, @(r0, 0) || nop
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 11 00F00000
+ 12 0038 00F00000 nop || mulx2h r1, r5, r6
+.* Warning:Odd numbered register used as target of multi-register instruction
+ 12 0A101146
diff --git a/gas/testsuite/gas/d30v/warn_oddreg.s b/gas/testsuite/gas/d30v/warn_oddreg.s
new file mode 100644
index 00000000000..c09f750948a
--- /dev/null
+++ b/gas/testsuite/gas/d30v/warn_oddreg.s
@@ -0,0 +1,12 @@
+# GAS should print a warning when an odd register is used as a target
+# of multi-word instructions: ld2w, ld4bh, ld4bhu, ld2h, st2w, st4hb, st2h,
+# and mulx2h
+
+st2w r1, @(r0, 0) || nop
+ld2w r1, @(r0, 0) || nop
+ld4bh r1, @(r0, 0) || nop
+ld4bhu r1, @(r0, 0) || nop
+ld2h r1, @(r0, 0) || nop
+st4hb r1, @(r0, 0) || nop
+st2h r1, @(r0, 0) || nop
+nop || mulx2h r1, r5, r6
diff --git a/gas/testsuite/gas/fr30/allinsn.d b/gas/testsuite/gas/fr30/allinsn.d
new file mode 100644
index 00000000000..2bac763d91a
--- /dev/null
+++ b/gas/testsuite/gas/fr30/allinsn.d
@@ -0,0 +1,440 @@
+#as:
+#objdump: -dr
+#name: allinsn
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000 <add>:
+ 0: a6 01 add r0,r1
+ 2: a4 02 add 0x0,r2
+
+0+0004 <add2>:
+ 4: a5 f3 add2 -1,r3
+
+0+0006 <addc>:
+ 6: a7 45 addc r4,r5
+
+0+0008 <addn>:
+ 8: a2 67 addn r6,r7
+ a: a0 f8 addn 0xf,r8
+
+0+000c <addn2>:
+ c: a1 09 addn2 -16,r9
+
+0+000e <sub>:
+ e: ac ab sub r10,r11
+
+0+0010 <subc>:
+ 10: ad cd subc r12,r13
+
+0+0012 <subn>:
+ 12: ae ef subn r14,r15
+
+0+0014 <cmp>:
+ 14: aa de cmp r13,r14
+ 16: a8 1f cmp 0x1,r15
+
+0+0018 <cmp2>:
+ 18: a9 10 cmp2 -15,r0
+
+0+001a <and>:
+ 1a: 82 12 and r1,r2
+ 1c: 84 34 and r3,@r4
+
+0+001e <andh>:
+ 1e: 85 56 andh r5,@r6
+
+0+0020 <andb>:
+ 20: 86 78 andb r7,@r8
+
+0+0022 <or>:
+ 22: 92 9a or r9,r10
+ 24: 94 bc or r11,@r12
+
+0+0026 <orh>:
+ 26: 95 de orh r13,@r14
+
+0+0028 <orb>:
+ 28: 96 fd orb r15,@r13
+
+0+002a <eor>:
+ 2a: 9a ef eor r14,r15
+ 2c: 9c 01 eor r0,@r1
+
+0+002e <eorh>:
+ 2e: 9d 23 eorh r2,@r3
+
+0+0030 <eorb>:
+ 30: 9e 45 eorb r4,@r5
+
+0+0032 <bandl>:
+ 32: 80 f6 bandl 0xf,@r6
+
+0+0034 <nadh>:
+ 34: 81 77 bandh 0x7,@r7
+
+0+0036 <borl>:
+ 36: 90 38 borl 0x3,@r8
+
+0+0038 <borh>:
+ 38: 91 d9 borh 0xd,@r9
+
+0+003a <beorl>:
+ 3a: 98 fa beorl 0xf,@r10
+
+0+003c <beorh>:
+ 3c: 99 1b beorh 0x1,@r11
+
+0+003e <btstl>:
+ 3e: 88 0c btstl 0x0,@r12
+
+0+0040 <btsth>:
+ 40: 89 8d btsth 0x8,@r13
+
+0+0042 <mul>:
+ 42: af ef mul r14,r15
+
+0+0044 <mulu>:
+ 44: ab de mulu r13,r14
+
+0+0046 <muluh>:
+ 46: bb f0 muluh r15,r0
+
+0+0048 <mulh>:
+ 48: bf 12 mulh r1,r2
+
+0+004a <div0s>:
+ 4a: 97 43 div0s r3
+
+0+004c <div0u>:
+ 4c: 97 54 div0u r4
+
+0+004e <div1>:
+ 4e: 97 65 div1 r5
+
+0+0050 <div2>:
+ 50: 97 76 div2 r6
+
+0+0052 <div3>:
+ 52: 9f 60 div3
+
+0+0054 <div4s>:
+ 54: 9f 70 div4s
+
+0+0056 <lsl>:
+ 56: b6 78 lsl r7,r8
+ 58: b4 39 lsl 0x3,r9
+
+0+005a <lsl2>:
+ 5a: b5 0a lsl2 0x0,r10
+
+0+005c <lsr>:
+ 5c: b2 bc lsr r11,r12
+ 5e: b0 fd lsr 0xf,r13
+
+0+0060 <lsr2>:
+ 60: b1 fe lsr2 0xf,r14
+
+0+0062 <asr>:
+ 62: ba fd asr r15,r13
+ 64: b8 6e asr 0x6,r14
+
+0+0066 <asr2>:
+ 66: b9 7f asr2 0x7,r15
+
+0+0068 <ldi_8>:
+ 68: cf f2 ldi:8 0xff,r2
+
+0+006a <ld>:
+ 6a: 04 34 ld @r3,r4
+ 6c: 00 56 ld @\(r13,r5\),r6
+ 6e: 27 f7 ld @\(r14,508\),r7
+ 70: 03 f8 ld @\(r15,0x3c\),r8
+ 72: 07 09 ld @r15\+,r9
+ 74: 07 90 ld @r15\+,ps
+ 76: 07 80 ld @r15\+,tbr
+ 78: 07 81 ld @r15\+,rp
+ 7a: 07 82 ld @r15\+,ssp
+
+0+007c <lduh>:
+ 7c: 05 ab lduh @r10,r11
+ 7e: 01 cd lduh @\(r13,r12\),r13
+ 80: 48 0f lduh @\(r14,-256\),r15
+
+0+0082 <ldub>:
+ 82: 06 de ldub @r13,r14
+ 84: 02 f0 ldub @\(r13,r15\),r0
+ 86: 68 01 ldub @\(r14,-128\),r1
+
+0+0088 <st>:
+ 88: 14 32 st r2,@r3
+ 8a: 10 54 st r4,@\(r13,r5\)
+ 8c: 38 06 st r6,@\(r14,-512\)
+ 8e: 13 f7 st r7,@\(r15,0x3c\)
+ 90: 17 08 st r8,@-r15
+ 92: 17 84 st mdh,@-r15
+ 94: 17 90 st ps,@-r15
+
+0+0096 <sth>:
+ 96: 15 a9 sth r9,@r10
+ 98: 11 cb sth r11,@\(r13,r12\)
+ 9a: 54 0d sth r13,@\(r14,128\)
+
+0+009c <stb>:
+ 9c: 16 fe stb r14,@r15
+ 9e: 12 10 stb r0,@\(r13,r1\)
+ a0: 78 02 stb r2,@\(r14,-128\)
+
+0+00a2 <mov>:
+ a2: 8b 34 mov r3,r4
+ a4: b7 55 mov mdl,r5
+ a6: 17 16 mov ps,r6
+ a8: b3 37 mov r7,usp
+ aa: 07 18 mov r8,ps
+
+0+00ac <jmp>:
+ ac: 97 09 jmp @r9
+
+0+00ae <ret>:
+ ae: 97 20 ret
+
+0+00b0 <bra>:
+ b0: e0 a7 bra 0 \<add\>
+
+0+00b2 <bno>:
+ b2: e1 a6 bno 0 \<add\>
+
+0+00b4 <beq>:
+ b4: e2 a5 beq 0 \<add\>
+
+0+00b6 <bne>:
+ b6: e3 a4 bne 0 \<add\>
+
+0+00b8 <bc>:
+ b8: e4 a3 bc 0 \<add\>
+
+0+00ba <bnc>:
+ ba: e5 a2 bnc 0 \<add\>
+
+0+00bc <bn>:
+ bc: e6 a1 bn 0 \<add\>
+
+0+00be <bp>:
+ be: e7 a0 bp 0 \<add\>
+
+0+00c0 <bv>:
+ c0: e8 9f bv 0 \<add\>
+
+0+00c2 <bnv>:
+ c2: e9 9e bnv 0 \<add\>
+
+0+00c4 <blt>:
+ c4: ea 9d blt 0 \<add\>
+
+0+00c6 <bge>:
+ c6: eb 9c bge 0 \<add\>
+
+0+00c8 <ble>:
+ c8: ec 9b ble 0 \<add\>
+
+0+00ca <bgt>:
+ ca: ed 9a bgt 0 \<add\>
+
+0+00cc <bls>:
+ cc: ee 99 bls 0 \<add\>
+
+0+00ce <bhi>:
+ ce: ef 98 bhi 0 \<add\>
+
+0+00d0 <jmp_d>:
+ d0: 9f 0b jmp:d @r11
+ d2: 9f a0 nop
+
+0+00d4 <ret_d>:
+ d4: 9f 20 ret:d
+ d6: 9f a0 nop
+
+0+00d8 <bra_d>:
+ d8: f0 fb bra:d d0 \<jmp_d\>
+ da: 9f a0 nop
+
+0+00dc <bno_d>:
+ dc: f1 f9 bno:d d0 \<jmp_d\>
+ de: 9f a0 nop
+
+0+00e0 <beq_d>:
+ e0: f2 f7 beq:d d0 \<jmp_d\>
+ e2: 9f a0 nop
+
+0+00e4 <bne_d>:
+ e4: f3 f5 bne:d d0 \<jmp_d\>
+ e6: 9f a0 nop
+
+0+00e8 <bc_d>:
+ e8: f4 f3 bc:d d0 \<jmp_d\>
+ ea: 9f a0 nop
+
+0+00ec <bnc_d>:
+ ec: f5 f1 bnc:d d0 \<jmp_d\>
+ ee: 9f a0 nop
+
+0+00f0 <bn_d>:
+ f0: f6 ef bn:d d0 \<jmp_d\>
+ f2: 9f a0 nop
+
+0+00f4 <bp_d>:
+ f4: f7 ed bp:d d0 \<jmp_d\>
+ f6: 9f a0 nop
+
+0+00f8 <bv_d>:
+ f8: f8 eb bv:d d0 \<jmp_d\>
+ fa: 9f a0 nop
+
+0+00fc <bnv_d>:
+ fc: f9 e9 bnv:d d0 \<jmp_d\>
+ fe: 9f a0 nop
+
+0+0100 <blt_d>:
+ 100: fa e7 blt:d d0 \<jmp_d\>
+ 102: 9f a0 nop
+
+0+0104 <bge_d>:
+ 104: fb e5 bge:d d0 \<jmp_d\>
+ 106: 9f a0 nop
+
+0+0108 <ble_d>:
+ 108: fc e3 ble:d d0 \<jmp_d\>
+ 10a: 9f a0 nop
+
+0+010c <bgt_d>:
+ 10c: fd e1 bgt:d d0 \<jmp_d\>
+ 10e: 9f a0 nop
+
+0+0110 <bls_d>:
+ 110: fe df bls:d d0 \<jmp_d\>
+ 112: 9f a0 nop
+
+0+0114 <bhi_d>:
+ 114: ff dd bhi:d d0 \<jmp_d\>
+ 116: 9f a0 nop
+
+0+0118 <ldres>:
+ 118: bc 82 ldres @r2\+,0x8
+
+0+011a <stres>:
+ 11a: bd f3 stres 0xf,@r3\+
+
+0+011c <nop>:
+ 11c: 9f a0 nop
+
+0+011e <andccr>:
+ 11e: 83 ff andccr 0xff
+
+0+0120 <orccr>:
+ 120: 93 7d orccr 0x7d
+
+0+0122 <stilm>:
+ 122: 87 61 stilm 0x61
+
+0+0124 <addsp>:
+ 124: a3 80 addsp -512
+
+0+0126 <extsb>:
+ 126: 97 89 extsb r9
+
+0+0128 <extub>:
+ 128: 97 9a extub r10
+
+0+012a <extsh>:
+ 12a: 97 ab extsh r11
+
+0+012c <extuh>:
+ 12c: 97 bc extuh r12
+
+0+012e <enter>:
+ 12e: 0f ff enter 0x3fc
+
+0+0130 <leave>:
+ 130: 9f 90 leave
+
+0+0132 <xchb>:
+ 132: 8a ef xchb @r14,r15
+
+0+0134 <ldi_32>:
+ 134: 9f 80 12 34 ldi:32 0x12345678,r0
+ 138: 56 78
+
+0+013a <copop>:
+ 13a: 9f cf 01 34 copop 0xf,0x1,cr3,cr4
+ 13e: 9f cf 04 56 copop 0xf,0x4,cr5,cr6
+ 142: 9f cf ff 70 copop 0xf,0xff,cr7,cr0
+
+0+0146 <copld>:
+ 146: 9f d0 00 40 copld 0x0,0x0,r4,cr0
+
+0+014a <copst>:
+ 14a: 9f e7 02 15 copst 0x7,0x2,cr1,r5
+
+0+014e <copsv>:
+ 14e: 9f f8 03 26 copsv 0x8,0x3,cr2,r6
+
+0+0152 <ldm0>:
+ 152: 8c 8d ldm0 \(r0,r2,r3,r7\)
+
+0+0154 <ldm1>:
+ 154: 8d 89 ldm1 \(r8,r11,r15\)
+
+0+0156 <stm0>:
+ 156: 8e 30 stm0 \(r2,r3\)
+
+0+0158 <stm1>:
+ 158: 8f 06 stm1 \(r13,r14\)
+
+0+015a <call>:
+ 15a: d7 52 call 0 \<add\>
+ 15c: 97 1a call @r10
+
+0+015e <call_d>:
+ 15e: df 50 call:d 0 \<add\>
+ 160: 9f a0 nop
+ 162: 9f 1c call:d @r12
+ 164: 9f a0 nop
+
+0+0166 <dmov>:
+ 166: 08 22 dmov @0x88,r13
+ 168: 18 15 dmov r13,@0x54
+ 16a: 0c 11 dmov @0x44,@r13\+
+ 16c: 1c 00 dmov @r13\+,@0x0
+ 16e: 0b 0b dmov @0x2c,@-r15
+ 170: 1b 09 dmov @r15\+,@0x24
+
+0+0172 <dmovh>:
+ 172: 09 44 dmovh @0x88,r13
+ 174: 19 29 dmovh r13,@0x52
+ 176: 0d 1a dmovh @0x34,@r13\+
+ 178: 1d 29 dmovh @r13\+,@0x52
+
+0+017a <dmovb>:
+ 17a: 0a 91 dmovb @0x91,r13
+ 17c: 1a 53 dmovb r13,@0x53
+ 17e: 0e 47 dmovb @0x47,@r13\+
+ 180: 1e 00 dmovb @r13\+,@0x0
+
+0+0182 <ldi_20>:
+ 182: 9b f1 ff ff ldi:20 0xfffff,r1
+
+0+0186 <finish>:
+ 186: 9f 80 00 00 ldi:32 0x8000,r0
+ 18a: 80 00
+ 18c: b3 20 mov r0,ssp
+ 18e: 9f 80 00 00 ldi:32 0x1,r0
+ 192: 00 01
+ 194: 1f 0a int 0xa
+
+0+0196 <inte>:
+ 196: 9f 30 inte
+
+0+0198 <reti>:
+ 198: 97 30 reti
diff --git a/gas/testsuite/gas/fr30/allinsn.exp b/gas/testsuite/gas/fr30/allinsn.exp
new file mode 100644
index 00000000000..eccfe187829
--- /dev/null
+++ b/gas/testsuite/gas/fr30/allinsn.exp
@@ -0,0 +1,5 @@
+# FR30 assembler testsuite.
+
+if [istarget fr30*-*-*] {
+ run_dump_test "allinsn"
+}
diff --git a/gas/testsuite/gas/fr30/allinsn.s b/gas/testsuite/gas/fr30/allinsn.s
new file mode 100644
index 00000000000..683d24ae77b
--- /dev/null
+++ b/gas/testsuite/gas/fr30/allinsn.s
@@ -0,0 +1,434 @@
+ .data
+foodata: .word 42
+ .text
+footext:
+ .global add
+add:
+ add r0, r1
+ add #0, r2
+ .global add2
+add2:
+ add2 #-1, r3
+ .global addc
+addc:
+ addc r4, r5
+ .global addn
+addn:
+ addn r6, r7
+ addn #15, r8
+ .global addn2
+addn2:
+ addn2 #-16, r9
+ .global sub
+sub:
+ sub r10, r11
+ .global subc
+subc:
+ subc r12, r13
+ .global subn
+subn:
+ subn r14, r15
+ .global cmp
+cmp:
+ cmp ac, fp
+ cmp #1, sp
+ .global cmp2
+cmp2:
+ cmp2 #-15, r0
+ .global and
+and:
+ and r1, r2
+ and r3, @r4
+ .global andh
+andh:
+ andh r5, @r6
+ .global andb
+andb:
+ andb r7, @r8
+ .global or
+or:
+ or r9, r10
+ or r11, @r12
+ .global orh
+orh:
+ orh r13, @r14
+ .global orb
+orb:
+ orb r15, @ac
+ .global eor
+eor:
+ eor fp, sp
+ eor r0, @r1
+ .global eorh
+eorh:
+ eorh r2, @r3
+ .global eorb
+eorb:
+ eorb r4, @r5
+ .global bandl
+bandl:
+ bandl #15, @r6
+ .global bandh
+nadh:
+ bandh #7, @r7
+ .global borl
+borl:
+ borl #3, @r8
+ .global borh
+borh:
+ borh #13, @r9
+ .global beorl
+beorl:
+ beorl #15, @r10
+ .global beorh
+beorh:
+ beorh #1, @r11
+ .global btstl
+btstl:
+ btstl #0, @r12
+ .global btsth
+btsth:
+ btsth #8, @r13
+ .global mul
+mul:
+ mul r14, r15
+ .global mulu
+mulu:
+ mulu ac, fp
+ .global muluh
+muluh:
+ muluh sp, r0
+ .global mulh
+mulh:
+ mulh r1, r2
+ .global div0s
+div0s:
+ div0s r3
+ .global div0u
+div0u:
+ div0u r4
+ .global div1
+div1:
+ div1 r5
+ .global div2
+div2:
+ div2 r6
+ .global div3
+div3:
+ div3
+ .global div4s
+div4s:
+ div4s
+ .global lsl
+lsl:
+ lsl r7, r8
+ lsl #3, r9
+ .global lsl2
+lsl2:
+ lsl2 #0, r10
+ .global lsr
+lsr:
+ lsr r11, r12
+ lsr #15, r13
+ .global lsr2
+lsr2:
+ lsr2 #15, r14
+ .global asr
+asr:
+ asr r15, ac
+ asr #6, fp
+ .global asr2
+asr2:
+ asr2 #7, sp
+ .global ldi_8
+ldi_8:
+ ldi:8 #0xff, r2
+ .global ld
+ld:
+ ld @r3, r4
+ ld @(R13, r5), r6
+ ld @(R14, 0x1fc), r7
+ ld @(R15, 0x3c), r8
+ ld @r15+, r9
+ ld @r15+, ps
+ ld @R15+, tbr
+ ld @r15+, rp
+ ld @R15+, ssp
+ .global lduh
+lduh:
+ lduh @r10, r11
+ lduh @(r13, r12), r13
+ lduh @(r14, #-256), r15
+ .global ldub
+ldub:
+ ldub @ac, fp
+ ldub @(r13, sp), r0
+ ldub @(r14, -128), r1
+ .global st
+st:
+ st r2, @r3
+ st r4, @(r13, r5)
+ st r6, @(r14, -512)
+ st r7, @(r15, 0x3c)
+ st r8, @ - r15
+ st MDH, @-r15
+ st PS, @ - r15
+ .global lsth
+sth:
+ sth r9, @r10
+ sth r11, @(r13, r12)
+ sth r13, @(r14, 128)
+ .global stb
+stb:
+ STB r14, @r15
+ stb r0, @(r13, r1)
+ STB r2, @(r14, -128)
+ .global mov
+mov:
+ mov r3, r4
+ MOV mdl, r5
+ mov ps, r6
+ mov r7, usp
+ mov r8, ps
+ .global jmp
+jmp:
+ jmp @r9
+ .global ret
+ret:
+ ret
+ .global bra
+bra:
+ bra footext
+ .global bno
+bno:
+ bno footext
+ .global beq
+beq:
+ beq footext
+ .global bne
+bne:
+ bne footext
+ .global bc
+bc:
+ bc footext
+ .global bnc
+bnc:
+ bnc footext
+ .global bn
+bn:
+ bn footext
+ .global bp
+bp:
+ bp footext
+ .global bv
+bv:
+ bv footext
+ .global bnv
+bnv:
+ bnv footext
+ .global blt
+blt:
+ blt footext
+ .global bge
+bge:
+ bge footext
+ .global ble
+ble:
+ ble footext
+ .global bgt
+bgt:
+ bgt footext
+ .global bls
+bls:
+ bls footext
+ .global bhi
+bhi:
+ bhi footext
+delay_footext:
+ .global jmp_d
+jmp_d:
+ jmp:d @r11
+ nop
+ .global ret_d
+ret_d:
+ ret:d
+ nop
+ .global bra_d
+bra_d:
+ bra:D delay_footext
+ nop
+ .global bno_d
+bno_d:
+ bno:d delay_footext
+ nop
+ .global beq_d
+beq_d:
+ beq:D delay_footext
+ nop
+ .global bne_d
+bne_d:
+ bne:d delay_footext
+ nop
+ .global bc_d
+bc_d:
+ bc:d delay_footext
+ nop
+ .global bnc_d
+bnc_d:
+ bnc:d delay_footext
+ nop
+ .global bn_d
+bn_d:
+ bn:d delay_footext
+ nop
+ .global bp_d
+bp_d:
+ bp:d delay_footext
+ nop
+ .global bv_d
+bv_d:
+ bv:d delay_footext
+ nop
+ .global bnv_d
+bnv_d:
+ bnv:d delay_footext
+ nop
+ .global blt_d
+blt_d:
+ blt:d delay_footext
+ nop
+ .global bge_d
+bge_d:
+ bge:d delay_footext
+ nop
+ .global ble_d
+ble_d:
+ ble:d delay_footext
+ nop
+ .global bgt_d
+bgt_d:
+ bgt:d delay_footext
+ nop
+ .global bls_d
+bls_d:
+ bls:d delay_footext
+ nop
+ .global bhi_d
+bhi_d:
+ bhi:d delay_footext
+ nop
+ .global ldres
+ldres:
+ ldres @r2+, #8
+ .global stres
+stres:
+ stres #15, @r3+
+ .global nop
+nop:
+ nop
+ .global andccr
+andccr:
+ andccr #255
+ .global orccr
+orccr:
+ orccr #125
+ .global stilm
+stilm:
+ stilm #97
+ .global addsp
+addsp:
+ addsp #-512
+ .global extsb
+extsb:
+ extsb r9
+ .global extub
+extub:
+ extub r10
+ .global extsh
+extsh:
+ extsh r11
+ .global extuh
+extuh:
+ extuh r12
+ .global enter
+enter:
+ enter #1020
+ .global leave
+leave:
+ leave
+ .global xchb
+xchb:
+ xchb @r14, r15
+ .global ldi_32
+ldi_32:
+ ldi:32 #0x12345678, r0
+ .global copop
+copop:
+ copop #15, #1, cr3, cr4
+ copop #15, #4, cr5, cr6
+ copop #15, #255, cr7, cr0
+ .global copld
+copld:
+ copld #0, #0, r4, cr0
+ .global copst
+copst:
+ copst #7, #2, cr1, r5
+ .global copsv
+copsv:
+ copsv #8, #3, cr2, r6
+ .global ldm0
+ldm0:
+ ldm0 (r0, r2, r3, r7)
+ .global ldm1
+ldm1:
+ ldm1 (r8, r11, r15)
+ .global stm0
+stm0:
+ stm0 (r2, r3)
+ .global stm1
+stm1:
+ stm1 (r13, r14)
+ .global call
+call:
+ call footext
+ call @r10
+ .global call_d
+call_d:
+ call:D footext
+ nop
+ call:d @r12
+ nop
+ .global dmov
+dmov:
+ dmov @0x88, r13
+ dmov r13, @0x54
+ dmov @0x44, @r13+
+ dmov @R13+, @0x2
+ dmov @0x2c, @-r15
+ dmov @r15+, @38
+ .global dmovh
+dmovh:
+ dmovh @0x88, r13
+ dmovh r13, @0x52
+ dmovh @0x34, @r13 +
+ dmovh @r13+, @0x52
+ .global dmovb
+dmovb:
+ dmovb @0x91, r13
+ dmovb r13, @0x53
+ dmovb @71, @r13+
+ dmovb @r13+, @0x0
+ .global ldi_20
+ldi_20:
+ ldi:20 #0x000fffff, r1
+finish:
+ ldi:32 #0x8000,r0
+ mov r0,ssp
+ ldi:32 #1,r0
+ int #10
+ .global inte
+inte:
+ inte
+ .global reti
+reti:
+ reti
diff --git a/gas/testsuite/gas/fr30/fr30.exp b/gas/testsuite/gas/fr30/fr30.exp
new file mode 100644
index 00000000000..06286b1ca98
--- /dev/null
+++ b/gas/testsuite/gas/fr30/fr30.exp
@@ -0,0 +1,5 @@
+# FR30 testcases
+
+if [istarget fr30*-*-*] {
+# run_dump_test "high-1"
+}
diff --git a/gas/testsuite/gas/h8300/addsub.s b/gas/testsuite/gas/h8300/addsub.s
new file mode 100644
index 00000000000..802b0d7621f
--- /dev/null
+++ b/gas/testsuite/gas/h8300/addsub.s
@@ -0,0 +1,16 @@
+ .text
+h8300_add_sub:
+ add.b #16,r1l
+ add.b r1h,r1l
+ add.w r1,r2
+ adds #1,r4
+ adds #2,r5
+ addx r0l,r1l
+ addx #16,r2h
+ sub.b r0l,r1l
+ sub.w r0,r1
+ subs #1,r4
+ subs #2,r5
+ subx r0l,r1l
+ subx #16,r2h
+
diff --git a/gas/testsuite/gas/h8300/addsubh.s b/gas/testsuite/gas/h8300/addsubh.s
new file mode 100644
index 00000000000..1f885d3fc5f
--- /dev/null
+++ b/gas/testsuite/gas/h8300/addsubh.s
@@ -0,0 +1,25 @@
+ .h8300h
+ .text
+h8300h_add_sub:
+ add.b #16,r1l
+ add.b r1h,r1l
+ add.w #32,r1
+ add.w r1,r2
+ add.l #64,er1
+ add.l er1,er2
+ adds #1,er4
+ adds #2,er5
+ adds #4,er6
+ addx r0l,r1l
+ addx #16,r2h
+ sub.b r0l,r1l
+ sub.w #16,r1
+ sub.w r0,r1
+ sub.l #64,er1
+ sub.l er1,er2
+ subs #1,er4
+ subs #2,er5
+ subs #4,er6
+ subx r0l,r1l
+ subx #16,r2h
+
diff --git a/gas/testsuite/gas/h8300/addsubs.s b/gas/testsuite/gas/h8300/addsubs.s
new file mode 100644
index 00000000000..b0b3699e458
--- /dev/null
+++ b/gas/testsuite/gas/h8300/addsubs.s
@@ -0,0 +1,25 @@
+ .h8300s
+ .text
+h8300s_add_sub:
+ add.b #16,r1l
+ add.b r1h,r1l
+ add.w #32,r1
+ add.w r1,r2
+ add.l #64,er1
+ add.l er1,er2
+ adds #1,er4
+ adds #2,er5
+ adds #4,er6
+ addx r0l,r1l
+ addx #16,r2h
+ sub.b r0l,r1l
+ sub.w #16,r1
+ sub.w r0,r1
+ sub.l #64,er1
+ sub.l er1,er2
+ subs #1,er4
+ subs #2,er5
+ subs #4,er6
+ subx r0l,r1l
+ subx #16,r2h
+
diff --git a/gas/testsuite/gas/h8300/bitops1.s b/gas/testsuite/gas/h8300/bitops1.s
new file mode 100644
index 00000000000..3c107a1b822
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops1.s
@@ -0,0 +1,18 @@
+ .text
+h8300_bit_ops_1:
+ band #0,r0l
+ band #0,@r0
+ band #0,@64:8
+ bclr #0,r0l
+ bclr #0,@r0
+ bclr #0,@64:8
+ bclr r1l,r0l
+ bclr r1l,@r0
+ bclr r1l,@64:8
+ biand #0,r0l
+ biand #0,@r0
+ biand #0,@64:8
+ bild #0,r0l
+ bild #0,@r0
+ bild #0,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops1h.s b/gas/testsuite/gas/h8300/bitops1h.s
new file mode 100644
index 00000000000..4139a590e8f
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops1h.s
@@ -0,0 +1,19 @@
+ .h8300h
+ .text
+h8300h_bit_ops_1:
+ band #0,r0l
+ band #0,@er0
+ band #0,@64:8
+ bclr #0,r0l
+ bclr #0,@er0
+ bclr #0,@64:8
+ bclr r1l,r0l
+ bclr r1l,@er0
+ bclr r1l,@64:8
+ biand #0,r0l
+ biand #0,@er0
+ biand #0,@64:8
+ bild #0,r0l
+ bild #0,@er0
+ bild #0,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops1s.s b/gas/testsuite/gas/h8300/bitops1s.s
new file mode 100644
index 00000000000..c6599d41a9a
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops1s.s
@@ -0,0 +1,29 @@
+ .h8300s
+ .text
+h8300s_bit_ops_1:
+ band #0,r0l
+ band #0,@er0
+ band #0,@64:8
+ band #0,@128:16
+ band #0,@65536:32
+ bclr #0,r0l
+ bclr #0,@er0
+ bclr #0,@64:8
+ bclr #0,@128:16
+ bclr #0,@65536:32
+ bclr r1l,r0l
+ bclr r1l,@er0
+ bclr r1l,@64:8
+ bclr r1l,@128:16
+ bclr r1l,@65536:32
+ biand #0,r0l
+ biand #0,@er0
+ biand #0,@64:8
+ biand #0,@128:16
+ biand #0,@65536:32
+ bild #0,r0l
+ bild #0,@er0
+ bild #0,@64:8
+ bild #0,@128:16
+ bild #0,@65536:32
+
diff --git a/gas/testsuite/gas/h8300/bitops2.s b/gas/testsuite/gas/h8300/bitops2.s
new file mode 100644
index 00000000000..3996e5a469f
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops2.s
@@ -0,0 +1,15 @@
+ .text
+h8300_bit_ops_2:
+ bior #0,r0l
+ bior #0,@r0
+ bior #0,@64:8
+ bist #0,r0l
+ bist #0,@r0
+ bist #0,@64:8
+ bixor #0,r0l
+ bixor #0,@r0
+ bixor #0,@64:8
+ bld #0,r0l
+ bld #0,@r0
+ bld #0,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops2h.s b/gas/testsuite/gas/h8300/bitops2h.s
new file mode 100644
index 00000000000..22be74e4b78
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops2h.s
@@ -0,0 +1,16 @@
+ .h8300h
+ .text
+h8300h_bit_ops_2:
+ bior #0,r0l
+ bior #0,@er0
+ bior #0,@64:8
+ bist #0,r0l
+ bist #0,@er0
+ bist #0,@64:8
+ bixor #0,r0l
+ bixor #0,@er0
+ bixor #0,@64:8
+ bld #0,r0l
+ bld #0,@er0
+ bld #0,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops2s.s b/gas/testsuite/gas/h8300/bitops2s.s
new file mode 100644
index 00000000000..94705201f0d
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops2s.s
@@ -0,0 +1,23 @@
+ .h8300s
+ .text
+h8300s_bit_ops_2:
+ bior #0,r0l
+ bior #0,@er0
+ bior #0,@64:8
+ bior #0,@128:16
+ bior #0,@65536:32
+ bist #0,r0l
+ bist #0,@er0
+ bist #0,@64:8
+ bist #0,@128:16
+ bist #0,@65536:32
+ bixor #0,r0l
+ bixor #0,@er0
+ bixor #0,@64:8
+ bixor #0,@128:16
+ bixor #0,@65536:32
+ bld #0,r0l
+ bld #0,@er0
+ bld #0,@64:8
+ bld #0,@128:16
+ bld #0,@65536:32
diff --git a/gas/testsuite/gas/h8300/bitops3.s b/gas/testsuite/gas/h8300/bitops3.s
new file mode 100644
index 00000000000..78c9bfb482e
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops3.s
@@ -0,0 +1,15 @@
+ .text
+h8300_bit_ops_3:
+ bnot #0,r0l
+ bnot #0,@r0
+ bnot #0,@64:8
+ bnot r1l,r0l
+ bnot r1l,@r0
+ bnot r1l,@64:8
+ bset #0,r0l
+ bset #0,@r0
+ bset #0,@64:8
+ bset r1l,r0l
+ bset r1l,@r0
+ bset r1l,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops3h.s b/gas/testsuite/gas/h8300/bitops3h.s
new file mode 100644
index 00000000000..fdeda609080
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops3h.s
@@ -0,0 +1,16 @@
+ .h8300h
+ .text
+h8300h_bit_ops_3:
+ bnot #0,r0l
+ bnot #0,@er0
+ bnot #0,@64:8
+ bnot r1l,r0l
+ bnot r1l,@er0
+ bnot r1l,@64:8
+ bset #0,r0l
+ bset #0,@er0
+ bset #0,@64:8
+ bset r1l,r0l
+ bset r1l,@er0
+ bset r1l,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops3s.s b/gas/testsuite/gas/h8300/bitops3s.s
new file mode 100644
index 00000000000..7c64e06d783
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops3s.s
@@ -0,0 +1,24 @@
+ .h8300s
+ .text
+h8300s_bit_ops_3:
+ bnot #0,r0l
+ bnot #0,@er0
+ bnot #0,@64:8
+ bnot #0,@128:16
+ bnot #0,@65536:32
+ bnot r1l,r0l
+ bnot r1l,@er0
+ bnot r1l,@64:8
+ bnot r1l,@128:16
+ bnot r1l,@65536:32
+ bset #0,r0l
+ bset #0,@er0
+ bset #0,@64:8
+ bset #0,@128:16
+ bset #0,@65536:32
+ bset r1l,r0l
+ bset r1l,@er0
+ bset r1l,@64:8
+ bset r1l,@128:16
+ bset r1l,@65536:32
+
diff --git a/gas/testsuite/gas/h8300/bitops4.s b/gas/testsuite/gas/h8300/bitops4.s
new file mode 100644
index 00000000000..f7e66d8b251
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops4.s
@@ -0,0 +1,18 @@
+ .text
+h8300_bit_ops_4:
+ bor #0,r0l
+ bor #0,@r0
+ bor #0,@64:8
+ bst #0,r0l
+ bst #0,@r0
+ bst #0,@64:8
+ btst #0,r0l
+ btst #0,@r0
+ btst #0,@64:8
+ btst r1l,r0l
+ btst r1l,@r0
+ btst r1l,@64:8
+ bxor #0,r0l
+ bxor #0,@r0
+ bxor #0,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops4h.s b/gas/testsuite/gas/h8300/bitops4h.s
new file mode 100644
index 00000000000..ed35e17dcbd
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops4h.s
@@ -0,0 +1,19 @@
+ .h8300h
+ .text
+h8300h_bit_ops_4:
+ bor #0,r0l
+ bor #0,@er0
+ bor #0,@64:8
+ bst #0,r0l
+ bst #0,@er0
+ bst #0,@64:8
+ btst #0,r0l
+ btst #0,@er0
+ btst #0,@64:8
+ btst r1l,r0l
+ btst r1l,@er0
+ btst r1l,@64:8
+ bxor #0,r0l
+ bxor #0,@er0
+ bxor #0,@64:8
+
diff --git a/gas/testsuite/gas/h8300/bitops4s.s b/gas/testsuite/gas/h8300/bitops4s.s
new file mode 100644
index 00000000000..e8f47b6dc21
--- /dev/null
+++ b/gas/testsuite/gas/h8300/bitops4s.s
@@ -0,0 +1,29 @@
+ .h8300s
+ .text
+h8300s_bit_ops_4:
+ bor #0,r0l
+ bor #0,@er0
+ bor #0,@64:8
+ bor #0,@128:16
+ bor #0,@65536:32
+ bst #0,r0l
+ bst #0,@er0
+ bst #0,@64:8
+ bst #0,@128:16
+ bst #0,@65536:32
+ btst #0,r0l
+ btst #0,@er0
+ btst #0,@64:8
+ btst #0,@128:16
+ btst #0,@65536:32
+ btst r1l,r0l
+ btst r1l,@er0
+ btst r1l,@64:8
+ btst r1l,@128:16
+ btst r1l,@65536:32
+ bxor #0,r0l
+ bxor #0,@er0
+ bxor #0,@64:8
+ bxor #0,@128:16
+ bxor #0,@65536:32
+
diff --git a/gas/testsuite/gas/h8300/branch.s b/gas/testsuite/gas/h8300/branch.s
new file mode 100644
index 00000000000..25806153c42
--- /dev/null
+++ b/gas/testsuite/gas/h8300/branch.s
@@ -0,0 +1,10 @@
+ .text
+h8300_branches:
+ bsr h8300_branches
+ jmp h8300_branches
+ jmp @r0
+ jmp @@16:8
+ jsr h8300_branches
+ jsr @r0
+ jsr @@16:8
+
diff --git a/gas/testsuite/gas/h8300/branchh.s b/gas/testsuite/gas/h8300/branchh.s
new file mode 100644
index 00000000000..7cbc62f3e2b
--- /dev/null
+++ b/gas/testsuite/gas/h8300/branchh.s
@@ -0,0 +1,12 @@
+ .h8300h
+ .text
+h8300h_branches:
+ bsr h8300h_branches:8
+ bsr h8300h_branches:16
+ jmp h8300h_branches
+ jmp @er0
+ jmp @@16:8
+ jsr h8300h_branches
+ jsr @er0
+ jsr @@16:8
+
diff --git a/gas/testsuite/gas/h8300/branchs.s b/gas/testsuite/gas/h8300/branchs.s
new file mode 100644
index 00000000000..8f33e17967a
--- /dev/null
+++ b/gas/testsuite/gas/h8300/branchs.s
@@ -0,0 +1,12 @@
+ .h8300s
+ .text
+h8300s_branches:
+ bsr h8300s_branches:8
+ bsr h8300s_branches:16
+ jmp h8300s_branches
+ jmp @er0
+ jmp @@16:8
+ jsr h8300s_branches
+ jsr @er0
+ jsr @@16:8
+
diff --git a/gas/testsuite/gas/h8300/cbranch.s b/gas/testsuite/gas/h8300/cbranch.s
new file mode 100644
index 00000000000..ae3d53ed88c
--- /dev/null
+++ b/gas/testsuite/gas/h8300/cbranch.s
@@ -0,0 +1,23 @@
+ .text
+h8300_cbranch:
+ bra h8300_cbranch
+ bt h8300_cbranch
+ brn h8300_cbranch
+ bf h8300_cbranch
+ bhi h8300_cbranch
+ bls h8300_cbranch
+ bcc h8300_cbranch
+ bhs h8300_cbranch
+ bcs h8300_cbranch
+ blo h8300_cbranch
+ bne h8300_cbranch
+ beq h8300_cbranch
+ bvc h8300_cbranch
+ bvs h8300_cbranch
+ bpl h8300_cbranch
+ bmi h8300_cbranch
+ bge h8300_cbranch
+ blt h8300_cbranch
+ bgt h8300_cbranch
+ ble h8300_cbranch
+
diff --git a/gas/testsuite/gas/h8300/cbranchh.s b/gas/testsuite/gas/h8300/cbranchh.s
new file mode 100644
index 00000000000..a64e1a2aade
--- /dev/null
+++ b/gas/testsuite/gas/h8300/cbranchh.s
@@ -0,0 +1,44 @@
+ .text
+ .h8300h
+h8300h_cbranch:
+ bra h8300h_cbranch:8
+ bt h8300h_cbranch:8
+ brn h8300h_cbranch:8
+ bf h8300h_cbranch:8
+ bhi h8300h_cbranch:8
+ bls h8300h_cbranch:8
+ bcc h8300h_cbranch:8
+ bhs h8300h_cbranch:8
+ bcs h8300h_cbranch:8
+ blo h8300h_cbranch:8
+ bne h8300h_cbranch:8
+ beq h8300h_cbranch:8
+ bvc h8300h_cbranch:8
+ bvs h8300h_cbranch:8
+ bpl h8300h_cbranch:8
+ bmi h8300h_cbranch:8
+ bge h8300h_cbranch:8
+ blt h8300h_cbranch:8
+ bgt h8300h_cbranch:8
+ ble h8300h_cbranch:8
+ bra h8300h_cbranch:16
+ bt h8300h_cbranch:16
+ brn h8300h_cbranch:16
+ bf h8300h_cbranch:16
+ bhi h8300h_cbranch:16
+ bls h8300h_cbranch:16
+ bcc h8300h_cbranch:16
+ bhs h8300h_cbranch:16
+ bcs h8300h_cbranch:16
+ blo h8300h_cbranch:16
+ bne h8300h_cbranch:16
+ beq h8300h_cbranch:16
+ bvc h8300h_cbranch:16
+ bvs h8300h_cbranch:16
+ bpl h8300h_cbranch:16
+ bmi h8300h_cbranch:16
+ bge h8300h_cbranch:16
+ blt h8300h_cbranch:16
+ bgt h8300h_cbranch:16
+ ble h8300h_cbranch:16
+
diff --git a/gas/testsuite/gas/h8300/cbranchs.s b/gas/testsuite/gas/h8300/cbranchs.s
new file mode 100644
index 00000000000..14222ea7721
--- /dev/null
+++ b/gas/testsuite/gas/h8300/cbranchs.s
@@ -0,0 +1,44 @@
+ .text
+ .h8300s
+h8300s_cbranch:
+ bra h8300s_cbranch:8
+ bt h8300s_cbranch:8
+ brn h8300s_cbranch:8
+ bf h8300s_cbranch:8
+ bhi h8300s_cbranch:8
+ bls h8300s_cbranch:8
+ bcc h8300s_cbranch:8
+ bhs h8300s_cbranch:8
+ bcs h8300s_cbranch:8
+ blo h8300s_cbranch:8
+ bne h8300s_cbranch:8
+ beq h8300s_cbranch:8
+ bvc h8300s_cbranch:8
+ bvs h8300s_cbranch:8
+ bpl h8300s_cbranch:8
+ bmi h8300s_cbranch:8
+ bge h8300s_cbranch:8
+ blt h8300s_cbranch:8
+ bgt h8300s_cbranch:8
+ ble h8300s_cbranch:8
+ bra h8300s_cbranch:16
+ bt h8300s_cbranch:16
+ brn h8300s_cbranch:16
+ bf h8300s_cbranch:16
+ bhi h8300s_cbranch:16
+ bls h8300s_cbranch:16
+ bcc h8300s_cbranch:16
+ bhs h8300s_cbranch:16
+ bcs h8300s_cbranch:16
+ blo h8300s_cbranch:16
+ bne h8300s_cbranch:16
+ beq h8300s_cbranch:16
+ bvc h8300s_cbranch:16
+ bvs h8300s_cbranch:16
+ bpl h8300s_cbranch:16
+ bmi h8300s_cbranch:16
+ bge h8300s_cbranch:16
+ blt h8300s_cbranch:16
+ bgt h8300s_cbranch:16
+ ble h8300s_cbranch:16
+
diff --git a/gas/testsuite/gas/h8300/cmpsi2.s b/gas/testsuite/gas/h8300/cmpsi2.s
new file mode 100644
index 00000000000..ef7f03aa92b
--- /dev/null
+++ b/gas/testsuite/gas/h8300/cmpsi2.s
@@ -0,0 +1,28 @@
+# 1 "libgcc1.S"
+;; libgcc1 routines for the Hitachi h8/300 cpu.
+;; Contributed by Steve Chamberlain.
+;; sac@cygnus.com
+ .section .text
+ .align 2
+ .global ___cmpsi2
+___cmpsi2:
+ cmp.w r2 ,r0
+ bne .L2
+ cmp.w r3 ,r1
+ bne .L2
+ mov.w #1,r0
+ rts
+.L2:
+ cmp.w r0 ,r2
+ bgt .L4
+ bne .L3
+ cmp.w r1 ,r3
+ bls .L3
+.L4:
+ sub.w r0 ,r0
+ rts
+.L3:
+ mov.w #2,r0
+.L5:
+ rts
+ .end
diff --git a/gas/testsuite/gas/h8300/compare.s b/gas/testsuite/gas/h8300/compare.s
new file mode 100644
index 00000000000..60c1a417d76
--- /dev/null
+++ b/gas/testsuite/gas/h8300/compare.s
@@ -0,0 +1,6 @@
+ .text
+h8300_cmp:
+ cmp.b #0,r0l
+ cmp.b r0h,r0l
+ cmp.w r0,r1
+
diff --git a/gas/testsuite/gas/h8300/compareh.s b/gas/testsuite/gas/h8300/compareh.s
new file mode 100644
index 00000000000..c81e88e0c20
--- /dev/null
+++ b/gas/testsuite/gas/h8300/compareh.s
@@ -0,0 +1,10 @@
+ .h8300h
+ .text
+h8300h_cmp:
+ cmp.b #0,r0l
+ cmp.b r0h,r0l
+ cmp.w #32,r0
+ cmp.w r0,r1
+ cmp.l #64,er0
+ cmp.l er0,er1
+
diff --git a/gas/testsuite/gas/h8300/compares.s b/gas/testsuite/gas/h8300/compares.s
new file mode 100644
index 00000000000..e23f3fe8e94
--- /dev/null
+++ b/gas/testsuite/gas/h8300/compares.s
@@ -0,0 +1,10 @@
+ .h8300s
+ .text
+h8300s_cmp:
+ cmp.b #0,r0l
+ cmp.b r0h,r0l
+ cmp.w #32,r0
+ cmp.w r0,r1
+ cmp.l #64,er0
+ cmp.l er0,er1
+
diff --git a/gas/testsuite/gas/h8300/decimal.s b/gas/testsuite/gas/h8300/decimal.s
new file mode 100644
index 00000000000..8d4c0a0da9d
--- /dev/null
+++ b/gas/testsuite/gas/h8300/decimal.s
@@ -0,0 +1,5 @@
+ .text
+h8300_decimal:
+ daa r0l
+ das r0l
+
diff --git a/gas/testsuite/gas/h8300/decimalh.s b/gas/testsuite/gas/h8300/decimalh.s
new file mode 100644
index 00000000000..939240568eb
--- /dev/null
+++ b/gas/testsuite/gas/h8300/decimalh.s
@@ -0,0 +1,6 @@
+ .h8300h
+ .text
+h8300h_decimal:
+ daa r0l
+ das r0l
+
diff --git a/gas/testsuite/gas/h8300/decimals.s b/gas/testsuite/gas/h8300/decimals.s
new file mode 100644
index 00000000000..b7802fcf1ac
--- /dev/null
+++ b/gas/testsuite/gas/h8300/decimals.s
@@ -0,0 +1,6 @@
+ .h8300s
+ .text
+h8300s_decimal:
+ daa r0l
+ das r0l
+
diff --git a/gas/testsuite/gas/h8300/divmul.s b/gas/testsuite/gas/h8300/divmul.s
new file mode 100644
index 00000000000..37372ce4841
--- /dev/null
+++ b/gas/testsuite/gas/h8300/divmul.s
@@ -0,0 +1,5 @@
+ .text
+h8300_div_mul:
+ divxu r0l,r1
+ mulxu r0l,r1
+
diff --git a/gas/testsuite/gas/h8300/divmulh.s b/gas/testsuite/gas/h8300/divmulh.s
new file mode 100644
index 00000000000..db60f8f49aa
--- /dev/null
+++ b/gas/testsuite/gas/h8300/divmulh.s
@@ -0,0 +1,12 @@
+ .h8300h
+ .text
+h8300h_div_mul:
+ divxu.b r0l,r1
+ divxu.w r0,er1
+ divxs.b r0l,r1
+ divxs.w r0,er1
+ mulxu.b r0l,r1
+ mulxu.w r0,er1
+ mulxs.b r0l,r1
+ mulxs.w r0,er1
+
diff --git a/gas/testsuite/gas/h8300/divmuls.s b/gas/testsuite/gas/h8300/divmuls.s
new file mode 100644
index 00000000000..db60f8f49aa
--- /dev/null
+++ b/gas/testsuite/gas/h8300/divmuls.s
@@ -0,0 +1,12 @@
+ .h8300h
+ .text
+h8300h_div_mul:
+ divxu.b r0l,r1
+ divxu.w r0,er1
+ divxs.b r0l,r1
+ divxs.w r0,er1
+ mulxu.b r0l,r1
+ mulxu.w r0,er1
+ mulxs.b r0l,r1
+ mulxs.w r0,er1
+
diff --git a/gas/testsuite/gas/h8300/extendh.s b/gas/testsuite/gas/h8300/extendh.s
new file mode 100644
index 00000000000..c034c833ee6
--- /dev/null
+++ b/gas/testsuite/gas/h8300/extendh.s
@@ -0,0 +1,8 @@
+ .h8300h
+ .text
+h8300h_extend:
+ exts.w r0
+ exts.l er0
+ extu.w r0
+ extu.l er0
+
diff --git a/gas/testsuite/gas/h8300/extends.s b/gas/testsuite/gas/h8300/extends.s
new file mode 100644
index 00000000000..a26e9ba70a3
--- /dev/null
+++ b/gas/testsuite/gas/h8300/extends.s
@@ -0,0 +1,8 @@
+ .h8300s
+ .text
+h8300s_extend:
+ exts.w r0
+ exts.l er0
+ extu.w r0
+ extu.l er0
+
diff --git a/gas/testsuite/gas/h8300/ffxx1.d b/gas/testsuite/gas/h8300/ffxx1.d
new file mode 100644
index 00000000000..93455d52175
--- /dev/null
+++ b/gas/testsuite/gas/h8300/ffxx1.d
@@ -0,0 +1,23 @@
+#objdump: --prefix-addresses -dr
+#name: FFxx1
+
+# Test for FFxx:8 addressing.
+
+.*: file format .*h8300.*
+
+Disassembly of section .text:
+ ...
+ 0: 16 main
+0+0400 <main> f8 7f mov.b #0x7f,r0l
+0+0402 <main[+](0x|)2> 28 bb mov.b @0xbb:8,r0l
+0+0404 <main[+](0x|)4> 6a 88 ff b9 mov.b r0l,@0xffb9:16
+0+0408 <main[+](0x|)8> f8 01 mov.b #0x1,r0l
+0+040a <loop> 6a 88 ff bb mov.b r0l,@0xffbb:16
+0+040e <delay> 79 01 00 00 mov.w #0x0,r1
+0+0412 <deloop> 0b 01 adds #0x1,er1
+0+0414 <deloop[+](0x|)2> 46 00 bne .0 \(416\)
+ 415: DISP8 deloop[+]0xffffffff
+0+0416 <deloop[+](0x|)4> 12 88 rotl r0l
+0+0418 <deloop[+](0x|)6> 40 00 bra .0 \(41a\)
+ 419: DISP8 loop[+]0xffffffff
+ ...
diff --git a/gas/testsuite/gas/h8300/ffxx1.s b/gas/testsuite/gas/h8300/ffxx1.s
new file mode 100644
index 00000000000..53fc84160d4
--- /dev/null
+++ b/gas/testsuite/gas/h8300/ffxx1.s
@@ -0,0 +1,20 @@
+ .equ p6ddr, 0xffb9 ;0x7f for output
+ .equ p6dr, 0xffbb
+ .equ seed, 0x01
+ .text
+ .org 0
+reset: .word main ;reset vector
+;
+ .org 0x400
+main: mov.b #0x7f,r0l ;port 6 ddr = 7F
+ mov.b @0xffbb:8,r0l ;***test***
+ mov.b r0l,@p6ddr:16
+;
+ mov.b #seed,r0l ;start with 0000001
+loop: mov.b r0l,@p6dr:16 ;output to port 6
+delay: mov.w #0x0000,r1
+deloop: adds.w #1,r1
+ bne deloop:8 ;not = 0
+ rotl r0l
+ bra loop:8
+ .word 0
diff --git a/gas/testsuite/gas/h8300/h8300.exp b/gas/testsuite/gas/h8300/h8300.exp
new file mode 100644
index 00000000000..2b7d41ec0b9
--- /dev/null
+++ b/gas/testsuite/gas/h8300/h8300.exp
@@ -0,0 +1,2183 @@
+#
+# Some H8/300 tests
+#
+proc do_h8300_add_sub {} {
+ set testname "addsub.s: h8300 add/sub tests"
+ set x 0
+
+ gas_start "addsub.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 8910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 0819\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 0912\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 0B04\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 0B85\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0E89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 9210\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 1889\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 1901\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 1B04\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 1B85\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 1E89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 B210\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 13] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_logical {} {
+ set testname "logical.s: h8300 logical tests"
+ set x 0
+
+ gas_start "logical.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 E910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1691\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 0610\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 C810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1498\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0410\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c D810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 1589\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0510\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 1788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 1708\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 11] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_cbranch {} {
+ set testname "cbranch.s: h8300 conditional branch tests"
+ set x 0
+
+ gas_start "cbranch.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 4100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 4100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 4200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 4300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 4400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 4400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 4500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 4500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 4600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 4700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 4800\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 4900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 4A00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 4B00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 4C00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 4D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 4E00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 4F00\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 20] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_bitops1 {} {
+ set testname "bitops1.s: h8300 bitops tests #1"
+ set x 0
+
+ gas_start "bitops1.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7608\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D007200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F407200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 6298\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7D006290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7F406290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7688\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7C007680\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7E407680\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 7788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 7C007780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 7E407780\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 15] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_bitops2 {} {
+ set testname "bitops2.s: h8300 bitops tests #2"
+ set x 0
+
+ gas_start "bitops2.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7488\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007480\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407480\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D006780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F406780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 7588\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7C007580\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7E407580\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7C007700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7E407700\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 12] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_bitops3 {} {
+ set testname "bitops3.s: h8300 bitops tests #3"
+ set x 0
+
+ gas_start "bitops3.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7108\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7D007100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7F407100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6198\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D006190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F406190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 7008\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7D007000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7F407000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 6098\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7D006090\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7F406090\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 12] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_bitops4 {} {
+ set testname "bitops4.s: h8300 bitops tests #4"
+ set x 0
+
+ gas_start "bitops4.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7408\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D006700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F406700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 7308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7C007300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7E407300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 6398\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7C006390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7E406390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 7508\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 7C007500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 7E407500\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 15] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_branch {} {
+ set testname "branch.s: h8300 branch tests"
+ set x 0
+
+ gas_start "branch.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 5500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 5A000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 5900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 5B00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 5E000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 5D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 5F00\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 7] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_compare {} {
+ set testname "compare.s: h8300 compare tests"
+ set x 0
+
+ gas_start "compare.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 A800\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1C08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1D01\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 3] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_decimal {} {
+ set testname "decimal.s: h8300 decimal tests"
+ set x 0
+
+ gas_start "decimal.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0F08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1F08\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 2] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_incdec {} {
+ set testname "incdec.s: h8300 incdec tests"
+ set x 0
+
+ gas_start "incdec.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 1A08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 0A08\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 2] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_divmul {} {
+ set testname "divmul.s: h8300 divmul tests"
+ set x 0
+
+ gas_start "divmul.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 5181\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 5081\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 2] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_misc {} {
+ set testname "misc.s: h8300 misc tests"
+ set x 0
+
+ gas_start "misc.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7B5C598F\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 0700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 0308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 5670\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 5470\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 0180\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0208\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 8] then { pass $testname } else { fail $testname }
+
+ setup_xfail "h8300*-*-*"
+ fail "h8300 movfpe/movtpe tests"
+}
+
+proc do_h8300_movb {} {
+ set testname "movb.s: h8300 movb tests"
+ set x 0
+
+ gas_start "movb.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0C89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 F810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 6818\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6E180010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6C18\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 2810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 6A080000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 6898\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 6E980010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 6C98\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 3810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 6A880000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 12] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_movw {} {
+ set testname "movw.s: h8300 movw tests"
+ set x 0
+
+ gas_start "movw.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0D01\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 79000010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 6F100010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 6D10\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 6B000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 6990\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 6F900010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 6D90\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 6B800000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 10] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_pushpop {} {
+ set testname "pushpop.s: h8300 pushpop tests"
+ set x 0
+
+ gas_start "pushpop.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 6D70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 6DF0\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 2] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300_rotate_shift {} {
+ set testname "rotsh.s: h8300 rotate and shift tests"
+ set x 0
+
+ gas_start "rotsh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 1288\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1388\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 1308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1088\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 1188\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 1008\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 1108\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 8] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_add_sub {} {
+ set testname "addsubh.s: h8300h add/sub tests"
+ set x 0
+
+ gas_start "addsubh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 8910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 0819\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 79110020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 0912\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7A110000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0A92\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 0B04\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 0B85\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 0B96\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 0E89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 9210\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 1889\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 79310010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 1901\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7A310000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 1A92\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c 1B04\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 1B85\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 1B96\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 1E89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 B210\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 21] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_logical {} {
+ set testname "logicalh.s: h8300h logical tests"
+ set x 0
+
+ gas_start "logicalh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 E910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1691\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 79610020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 6611\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7A610000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 01F06611\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 0610\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 C810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 1498\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 79410020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 6411\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7A410000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 01F06411\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 0410\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c D810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 1589\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 79510020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 6511\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 7A510000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 01F06511\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 0510\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0042 1788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0044 1790\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0046 17B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 1708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 1710\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 1730\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 27] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_cbranch {} {
+ set testname "cbranchh.s: h8300h conditional branch tests"
+ set x 0
+
+ gas_start "cbranchh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 4100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 4100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 4200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 4300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 4400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 4400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 4500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 4500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 4600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 4700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 4800\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 4900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 4A00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 4B00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 4C00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 4D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 4E00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 4F00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 58000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c 58000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 58100000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 58100000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 58200000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 58300000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 58400000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0044 58400000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 58500000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 58500000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0050 58600000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0054 58700000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 58800000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005c 58900000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0060 58A00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0064 58B00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0068 58C00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 006c 58D00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0070 58E00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0074 58F00000\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 40] then { pass $testname } else { fail $testname }
+}
+proc do_h8300h_bitops1 {} {
+ set testname "bitops1h.s: h8300h bitops tests #1"
+ set x 0
+
+ gas_start "bitops1h.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7608\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D007200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F407200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 6298\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7D006290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7F406290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7688\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7C007680\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7E407680\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 7788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 7C007780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 7E407780\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 15] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_bitops2 {} {
+ set testname "bitops2h.s: h8300h bitops tests #2"
+ set x 0
+
+ gas_start "bitops2h.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7488\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007480\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407480\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D006780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F406780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 7588\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7C007580\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7E407580\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7C007700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7E407700\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 12] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_bitops3 {} {
+ set testname "bitops3h.s: h8300h bitops tests #3"
+ set x 0
+
+ gas_start "bitops3h.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7108\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7D007100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7F407100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6198\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D006190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F406190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 7008\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7D007000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7F407000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 6098\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7D006090\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7F406090\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 12] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_bitops4 {} {
+ set testname "bitops4h.s: h8300h bitops tests #4"
+ set x 0
+
+ gas_start "bitops4h.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7408\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 7D006700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 7F406700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 7308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 7C007300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7E407300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 6398\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 7C006390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7E406390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 7508\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 7C007500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 7E407500\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 15] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_branch {} {
+ set testname "branchh.s: h8300h branch tests"
+ set x 0
+
+ gas_start "branchh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 5500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 5C000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 5A000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 5900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 5B00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 5E000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 5D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 5F00\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 8] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_compare {} {
+ set testname "compareh.s: h8300h compare tests"
+ set x 0
+
+ gas_start "compareh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 A800\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1C08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 79200020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1D01\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7A200000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 1F81\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 6] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_decimal {} {
+ set testname "decimalh.s: h8300h decimal tests"
+ set x 0
+
+ gas_start "decimalh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0F08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1F08\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 2] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_incdec {} {
+ set testname "incdech.s: h8300h incdec tests"
+ set x 0
+
+ gas_start "incdech.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 1A08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1B50\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1BD0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 1B70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1BF0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0A08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 0B50\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 0BD0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0B70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 0BF0\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 10] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_divmul {} {
+ set testname "divmulh.s: h8300h divmul tests"
+ set x 0
+
+ gas_start "divmulh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 5181\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 5301\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 01D05181\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01D05301\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 5081\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 5201\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 01C05081\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 01C05201\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 8] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_misc {} {
+ set testname "misch.s: h8300h misc tests"
+ set x 0
+
+ gas_start "misch.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7B5C598F\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 7BD4598F\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 0700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 01406900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 01406F00\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 01407800\[^\n\]*\n +\[0-9\]+ +6B200000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 01406D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 01406B00\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 01406B20\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 5670\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 5470\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 0180\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003a 0208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 01406980\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 01406F80\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0046 01407800\[^\n\]*\n +\[0-9\]+ +6BA00000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0050 01406D80\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0054 01406B80\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005a 01406BA0\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 21] then { pass $testname } else { fail $testname }
+
+ setup_xfail "h8300*-*-*"
+ fail "h8300h movfpe/movtpe tests"
+}
+
+proc do_h8300h_movb {} {
+ set testname "movbh.s: h8300h movb tests"
+ set x 0
+
+ gas_start "movbh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0C89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 F810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 6818\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6E180010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 78106A28\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 6C18\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 2810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 6A080000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 6A280000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 6898\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6E980010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 78106AA8\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 6C98\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 3810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 6A880000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 6AA80000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 16] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_movw {} {
+ set testname "movwh.s: h8300h movw tests"
+ set x 0
+
+ gas_start "movwh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0D01\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 79000010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 6F100010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 78106B20\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 6D10\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 6B000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 6B200000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 6990\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6F900010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 78106BA0\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 6D90\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 6B800000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 6BA00000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 14] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_movl {} {
+ set testname "movlh.s: h8300h movl tests"
+ set x 0
+
+ gas_start "movlh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0F81\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7A000000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01006910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 01006F10\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 01007810\[^\n\]*\n +\[0-9\]+ +6B200000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 01006D10\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 01006B00\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 01006B20\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 01006990\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 01006F90\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 01007890\[^\n\]*\n +\[0-9\]+ +6BA00000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0042 01006D90\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0046 01006B80\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 01006BA0\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 14] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_pushpop {} {
+ set testname "pushpoph.s: h8300h pushpop tests"
+ set x 0
+
+ gas_start "pushpoph.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 6D70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 01006D70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6DF0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01006DF0\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 4] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_rotate_shift {} {
+ set testname "rotshh.s: h8300h rotate and shift tests"
+ set x 0
+
+ gas_start "rotshh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 1288\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 12B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 1388\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 13B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 1208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 1210\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 1230\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 1308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 1310\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 1330\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 1088\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 1090\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 10B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 1188\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 1190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 11B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 1008\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 1010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 1030\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 1108\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c 1110\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 1130\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 24] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_extend {} {
+ set testname "extendh.s: h8300h extend tests"
+ set x 0
+
+ gas_start "extendh.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 17D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 17F0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1750\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 1770\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 4] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_add_sub {} {
+ set testname "addsubs.s: h8300s add/sub tests"
+ set x 0
+
+ gas_start "addsubs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 8910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 0819\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 79110020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 0912\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7A110000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0A92\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 0B04\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 0B85\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 0B96\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 0E89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 9210\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 1889\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 79310010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 1901\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7A310000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 1A92\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c 1B04\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 1B85\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 1B96\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 1E89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 B210\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 21] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_logical {} {
+ set testname "logicals.s: h8300s logical tests"
+ set x 0
+
+ gas_start "logicals.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 E910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1691\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 79610020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 6611\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7A610000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 01F06611\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 0610\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 01410610\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a C810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 1498\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 79410020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6411\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 7A410000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 01F06411\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 0410\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 01410410\[^\n\]*\n" { set x [expr $x+1] }
+
+ -re " +\[0-9\]+ 0034 D810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 1589\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 79510020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 6511\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003e 7A510000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0044 01F06511\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 0510\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 01410510\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004e 1788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0050 1790\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0052 17B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0054 1708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0056 1710\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 1730\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 30] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_cbranch {} {
+ set testname "cbranchs.s: h8300s conditional branch tests"
+ set x 0
+
+ gas_start "cbranchs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 4100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 4100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 4200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 4300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 4400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 4400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 4500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 4500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 4600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 4700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 4800\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 4900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 4A00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 4B00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 4C00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 4D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 4E00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 4F00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 58000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c 58000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 58100000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 58100000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 58200000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 58300000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 58400000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0044 58400000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 58500000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 58500000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0050 58600000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0054 58700000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 58800000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005c 58900000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0060 58A00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0064 58B00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0068 58C00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 006c 58D00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0070 58E00000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0074 58F00000\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 40] then { pass $testname } else { fail $testname }
+}
+proc do_h8300s_bitops1 {} {
+ set testname "bitops1s.s: h8300s bitops tests #1"
+ set x 0
+
+ gas_start "bitops1s.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7608\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407600\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6A100080\[^\n\]*\n +\[0-9\]+ +7600" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 6A300001\[^\n\]*\n +\[0-9\]+ +00007600" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 7208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7D007200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7F407200\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6A180080\[^\n\]*\n +\[0-9\]+ +7200" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 6A380001\[^\n\]*\n +\[0-9\]+ +00007200" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 6298\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 7D006290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 7F406290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003a 6A180080\[^\n\]*\n +\[0-9\]+ +6290" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 6A380001\[^\n\]*\n +\[0-9\]+ +00006290" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 7688\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 7C007680\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004e 7E407680\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0052 6A100080\[^\n\]*\n +\[0-9\]+ +7680" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 6A300001\[^\n\]*\n +\[0-9\]+ +00007680" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0060 7788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0062 7C007780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0066 7E407780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 006a 6A100080\[^\n\]*\n +\[0-9\]+ +7780" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0070 6A300001\[^\n\]*\n +\[0-9\]+ +00007780" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 25] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_bitops2 {} {
+ set testname "bitops2s.s: h8300s bitops tests #2"
+ set x 0
+
+ gas_start "bitops2s.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7488\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007480\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407480\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6A100080\[^\n\]*\n +\[0-9\]+ +7480" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 6A300001\[^\n\]*\n +\[0-9\]+ +00007480" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 6788\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7D006780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7F406780\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6A180080\[^\n\]*\n +\[0-9\]+ +6780" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 6A380001\[^\n\]*\n +\[0-9\]+ +00006780" { set x [expr $x+1] }
+
+ -re " +\[0-9\]+ 0030 7588\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 7C007580\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 7E407580\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003a 6A100080\[^\n\]*\n +\[0-9\]+ +7580" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 6A300001\[^\n\]*\n +\[0-9\]+ +00007580" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 7708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 7C007700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004e 7E407700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0052 6A100080\[^\n\]*\n +\[0-9\]+ +7700" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 6A300001\[^\n\]*\n +\[0-9\]+ +00007700" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 20] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_bitops3 {} {
+ set testname "bitops3s.s: h8300s bitops tests #3"
+ set x 0
+
+ gas_start "bitops3s.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7108\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7D007100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7F407100\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6A180080\[^\n\]*\n +\[0-9\]+ +7100" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 6A380001\[^\n\]*\n +\[0-9\]+ +00007100" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 6198\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7D006190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7F406190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6A180080\[^\n\]*\n +\[0-9\]+ +6190" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 6A380001\[^\n\]*\n +\[0-9\]+ +00006190" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 7008\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 7D007000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 7F407000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003a 6A180080\[^\n\]*\n +\[0-9\]+ +7000" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 6A380001\[^\n\]*\n +\[0-9\]+ +00007000" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 6098\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 7D006090\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004e 7F406090\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0052 6A180080\[^\n\]*\n +\[0-9\]+ +6090" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 6A380001\[^\n\]*\n +\[0-9\]+ +00006090" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 20] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_bitops4 {} {
+ set testname "bitops4s.s: h8300s bitops tests #4"
+ set x 0
+
+ gas_start "bitops4s.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7408\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7C007400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 7E407400\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 6A100080\[^\n\]*\n +\[0-9\]+ +7400" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 6A300001\[^\n\]*\n +\[0-9\]+ +00007400" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 6708\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 7D006700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 7F406700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6A180080\[^\n\]*\n +\[0-9\]+ +6700" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 6A380001\[^\n\]*\n +\[0-9\]+ +00006700" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 7308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 7C007300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 7E407300\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003a 6A100080\[^\n\]*\n +\[0-9\]+ +7300" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 6A300001\[^\n\]*\n +\[0-9\]+ +00007300" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 6398\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 7C006390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004e 7E406390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0052 6A100080\[^\n\]*\n +\[0-9\]+ +6390" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 6A300001\[^\n\]*\n +\[0-9\]+ +00006390" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0060 7508\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0062 7C007500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0066 7E407500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 006a 6A100080\[^\n\]*\n +\[0-9\]+ +7500" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0070 6A300001\[^\n\]*\n +\[0-9\]+ +00007500" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 25] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_branch {} {
+ set testname "branchs.s: h8300s branch tests"
+ set x 0
+
+ gas_start "branchs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 5500\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 5C000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 5A000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 5900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 5B00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 5E000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 5D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 5F00\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 8] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_compare {} {
+ set testname "compares.s: h8300s compare tests"
+ set x 0
+
+ gas_start "compares.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 A800\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1C08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 79200020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1D01\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 7A200000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 1F81\[^\n\]*\n" { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 6] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_decimal {} {
+ set testname "decimals.s: h8300s decimal tests"
+ set x 0
+
+ gas_start "decimals.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0F08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1F08\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 2] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_incdec {} {
+ set testname "incdecs.s: h8300s incdec tests"
+ set x 0
+
+ gas_start "incdecs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 1A08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 1B50\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1BD0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 1B70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 1BF0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0A08\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 0B50\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 0BD0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0B70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 0BF0\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 10] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_divmul {} {
+ set testname "divmuls.s: h8300s divmul tests"
+ set x 0
+
+ gas_start "divmuls.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 5181\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 5301\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 01D05181\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01D05301\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 5081\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 5201\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 01C05081\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 01C05201\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 8] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_misc {} {
+ set testname "miscs.s: h8300s misc tests"
+ set x 0
+
+ gas_start "miscs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 7B5C598F\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 7BD4598F\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 0700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 01410700\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 0318\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 01406900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 01406F00\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 01407800\[^\n\]*\n +\[0-9\]+ +6B200000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 01406D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 01406B00\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 01406B20\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 01416900\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 01416F00\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0042 01417800\[^\n\]*\n +\[0-9\]+ +6B200000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 01416D00\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0050 01416B00\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0056 01416B20\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005e 0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0060 5670\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0062 5470\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0064 0180\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0066 0208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0068 0218\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 006a 01406980\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 006e 01406F80\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0074 01407800\[^\n\]*\n +\[0-9\]+ +6BA00000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 007e 01406D80\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0082 01406B80\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0088 01406BA0\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0090 01416980\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0094 01416F80\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 009a 01417800\[^\n\]*\n +\[0-9\]+ +6BA00000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 00a4 01416D80\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 00a8 01416B80\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 00ae 01416BA0\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 36] then { pass $testname } else { fail $testname }
+
+ setup_xfail "h8300*-*-*"
+ fail "h8300s movfpe/movtpe tests"
+}
+
+proc do_h8300s_movb {} {
+ set testname "movbs.s: h8300s movb tests"
+ set x 0
+
+ gas_start "movbs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0C89\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 F810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 6818\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6E180010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 78106A28\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 6C18\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 2810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 6A080000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 6A280000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 6898\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6E980010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 78106AA8\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 6C98\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 3810\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 6A880000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 6AA80000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 16] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_movw {} {
+ set testname "movws.s: h8300s movw tests"
+ set x 0
+
+ gas_start "movws.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0D01\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 79000010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 6F100010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 78106B20\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 6D10\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 6B000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 6B200000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 6990\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 6F900010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 78106BA0\[^\n\]*\n +\[0-9\]+ +00000020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 6D90\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 6B800000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 6BA00000\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 14] then { pass $testname } else { fail $testname }
+}
+
+
+proc do_h8300s_movl {} {
+ set testname "movls.s: h8300s movl tests"
+ set x 0
+
+ gas_start "movls.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 0F81\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 7A000000\[^\n\]*\n +\[0-9\]+ +0040\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01006910\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 01006F10\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 01007810\[^\n\]*\n +\[0-9\]+ +6B200000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 01006D10\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 01006B00\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 01006B20\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 01006990\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 01006F90\[^\n\]*\n +\[0-9\]+ +0010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 01007890\[^\n\]*\n +\[0-9\]+ +6BA00000\[^\n\]*\n +\[0-9\]+ +0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0042 01006D90\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0046 01006B80\[^\n\]*\n +\[0-9\]+ +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 01006BA0\[^\n\]*\n +\[0-9\]+ +00000000\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 14] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_pushpop {} {
+ set testname "pushpops.s: h8300s pushpop tests"
+ set x 0
+
+ gas_start "pushpops.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 6D70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 01006D70\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 6DF0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01006DF0\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 4] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_rotate_shift {} {
+ set testname "rotshs.s: h8300s rotate and shift tests"
+ set x 0
+
+ gas_start "rotshs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 1288\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 12C8\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1290\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 12D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 12B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 12F0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 1388\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000e 13C8\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 1390\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0012 13D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 13B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0016 13F0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0018 1208\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001a 1248\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001c 1210\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 001e 1250\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0020 1230\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0022 1270\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0024 1308\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0026 1348\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0028 1310\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002a 1350\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002c 1330\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 002e 1370\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0030 1088\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0032 10C8\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0034 1090\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0036 10D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0038 10B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003a 10F0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003c 1188\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 003e 11C8\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0040 1190\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0042 11D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0044 11B0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0046 11F0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0048 1008\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004a 1048\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004c 1010\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 004e 1050\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0050 1030\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0052 1070\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0054 1108\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0056 1148\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0058 1110\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005a 1150\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005c 1130\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 005e 1170\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 48] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_extend {} {
+ set testname "extends.s: h8300s extend tests"
+ set x 0
+
+ gas_start "extends.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 17D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 17F0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 1750\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 1770\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 4] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_mac {} {
+ set testname "macs.s: h8300s mac tests"
+ set x 0
+
+ gas_start "macs.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 01A0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0002 0320\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 0331\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0006 01606D01\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000a 0220\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 0231\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 6] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300s_multiple {} {
+ set testname "multiples.s: h8300s multiple tests"
+ set x 0
+
+ gas_start "multiples.s" "-al"
+
+ # Check each instruction bit pattern to verify it got
+ # assembled correctly.
+ while 1 {
+ expect {
+ -re " +\[0-9\]+ 0000 01106D71\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0004 01206D72\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0008 01306D73\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 000c 01106DF0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0010 01206DF0\[^\n\]*\n" { set x [expr $x+1] }
+ -re " +\[0-9\]+ 0014 01306DF0\[^\n\]*\n" { set x [expr $x+1] }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 6] then { pass $testname } else { fail $testname }
+}
+
+proc do_h8300h_mov32bug {} {
+ set testname "mov32bug.s: h8300h mov32bug test"
+ set x 0
+
+ if [gas_test_old "mov32bug.s" "" "Proper relocation for mov.l (part 1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+
+ while 1 {
+ expect {
+ -re "00000002\[^\n\]*32\[^\n\]*_a.0x0*88ca6c00\[^\n\]*\n"
+ { set x [expr $x+1] }
+ timeout { perror "timeout\n; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x == 1] then { pass $testname } else { fail $testname }
+}
+
+if [istarget h8300*-*-*] then {
+ # Test the basic h8300 instruction parser
+ do_h8300_add_sub
+ do_h8300_logical
+ do_h8300_cbranch
+ do_h8300_bitops1
+ do_h8300_bitops2
+ do_h8300_bitops3
+ do_h8300_bitops4
+ do_h8300_branch
+ do_h8300_compare
+ do_h8300_decimal
+ do_h8300_incdec
+ do_h8300_divmul
+ do_h8300_misc
+ do_h8300_movb
+ do_h8300_movw
+ do_h8300_pushpop
+ do_h8300_rotate_shift
+
+ # Now test the h8300h instruction parser
+ do_h8300h_add_sub
+ do_h8300h_logical
+ do_h8300h_cbranch
+ do_h8300h_bitops1
+ do_h8300h_bitops2
+ do_h8300h_bitops3
+ do_h8300h_bitops4
+ do_h8300h_branch
+ do_h8300h_compare
+ do_h8300h_decimal
+ do_h8300h_incdec
+ do_h8300h_divmul
+ do_h8300h_misc
+ do_h8300h_movb
+ do_h8300h_movw
+ do_h8300h_movl
+ do_h8300_pushpop
+ do_h8300h_rotate_shift
+ do_h8300h_extend
+
+ # Now test the h8300s instruction parser
+ do_h8300s_add_sub
+ do_h8300s_logical
+ do_h8300s_cbranch
+ do_h8300s_bitops1
+ do_h8300s_bitops2
+ do_h8300s_bitops3
+ do_h8300s_bitops4
+ do_h8300s_branch
+ do_h8300s_compare
+ do_h8300s_decimal
+ do_h8300s_incdec
+ do_h8300s_divmul
+ do_h8300s_misc
+ do_h8300s_movb
+ do_h8300s_movw
+ do_h8300s_movl
+ do_h8300_pushpop
+ do_h8300s_rotate_shift
+ do_h8300s_extend
+ do_h8300s_mac
+ do_h8300s_multiple
+
+ do_h8300h_mov32bug
+
+ # Now some random tests
+ set svr4pic [expr [istarget *-*-elf*] || [istarget *-*-irix5*] ]
+ set empic [expr [istarget *-*-ecoff*] || [istarget *-*-ultrix*] || [istarget *-*-irix\[1-4\]*] ]
+ set aout [expr [istarget *-*-bsd*] || [istarget *-*-netbsd*]]
+
+ run_dump_test "ffxx1"
+ gas_test "cmpsi2.s" "" "" "cmpsi2.s"
+}
diff --git a/gas/testsuite/gas/h8300/incdec.s b/gas/testsuite/gas/h8300/incdec.s
new file mode 100644
index 00000000000..26188277317
--- /dev/null
+++ b/gas/testsuite/gas/h8300/incdec.s
@@ -0,0 +1,5 @@
+ .text
+h8300_incdec:
+ dec r0l
+ inc r0l
+
diff --git a/gas/testsuite/gas/h8300/incdech.s b/gas/testsuite/gas/h8300/incdech.s
new file mode 100644
index 00000000000..bb93fc54b36
--- /dev/null
+++ b/gas/testsuite/gas/h8300/incdech.s
@@ -0,0 +1,14 @@
+ .h8300h
+ .text
+h8300h_incdec:
+ dec.b r0l
+ dec.w #1,r0
+ dec.w #2,r0
+ dec.l #1,er0
+ dec.l #2,er0
+ inc.b r0l
+ inc.w #1,r0
+ inc.w #2,r0
+ inc.l #1,er0
+ inc.l #2,er0
+
diff --git a/gas/testsuite/gas/h8300/incdecs.s b/gas/testsuite/gas/h8300/incdecs.s
new file mode 100644
index 00000000000..2345708b023
--- /dev/null
+++ b/gas/testsuite/gas/h8300/incdecs.s
@@ -0,0 +1,14 @@
+ .h8300s
+ .text
+h8300s_incdec:
+ dec.b r0l
+ dec.w #1,r0
+ dec.w #2,r0
+ dec.l #1,er0
+ dec.l #2,er0
+ inc.b r0l
+ inc.w #1,r0
+ inc.w #2,r0
+ inc.l #1,er0
+ inc.l #2,er0
+
diff --git a/gas/testsuite/gas/h8300/logical.s b/gas/testsuite/gas/h8300/logical.s
new file mode 100644
index 00000000000..3f7e3b7145d
--- /dev/null
+++ b/gas/testsuite/gas/h8300/logical.s
@@ -0,0 +1,14 @@
+ .text
+h8300_logical:
+ and #16,r1l
+ and r1l,r1h
+ andc #16,ccr
+ or #16,r0l
+ or r1l,r0l
+ orc #16,ccr
+ xor #16,r0l
+ xor r0l,r1l
+ xorc #16,ccr
+ neg r0l
+ not r0l
+
diff --git a/gas/testsuite/gas/h8300/logicalh.s b/gas/testsuite/gas/h8300/logicalh.s
new file mode 100644
index 00000000000..9e95f11d454
--- /dev/null
+++ b/gas/testsuite/gas/h8300/logicalh.s
@@ -0,0 +1,31 @@
+ .h8300h
+ .text
+h8300h_logical:
+ and.b #16,r1l
+ and.b r1l,r1h
+ and.w #32,r1
+ and.w r1,r1
+ and.l #64,er1
+ and.l er1,er1
+ andc #16,ccr
+ or.b #16,r0l
+ or.b r1l,r0l
+ or.w #32,r1
+ or.w r1,r1
+ or.l #64,er1
+ or.l er1,er1
+ orc #16,ccr
+ xor.b #16,r0l
+ xor.b r0l,r1l
+ xor.w #32,r1
+ xor.w r1,r1
+ xor.l #64,er1
+ xor.l er1,er1
+ xorc #16,ccr
+ neg.b r0l
+ neg.w r0
+ neg.l er0
+ not.b r0l
+ not.w r0
+ not.l er0
+
diff --git a/gas/testsuite/gas/h8300/logicals.s b/gas/testsuite/gas/h8300/logicals.s
new file mode 100644
index 00000000000..c3c4cbaaf0f
--- /dev/null
+++ b/gas/testsuite/gas/h8300/logicals.s
@@ -0,0 +1,34 @@
+ .h8300s
+ .text
+h8300s_logical:
+ and.b #16,r1l
+ and.b r1l,r1h
+ and.w #32,r1
+ and.w r1,r1
+ and.l #64,er1
+ and.l er1,er1
+ andc #16,ccr
+ andc #16,exr
+ or.b #16,r0l
+ or.b r1l,r0l
+ or.w #32,r1
+ or.w r1,r1
+ or.l #64,er1
+ or.l er1,er1
+ orc #16,ccr
+ orc #16,exr
+ xor.b #16,r0l
+ xor.b r0l,r1l
+ xor.w #32,r1
+ xor.w r1,r1
+ xor.l #64,er1
+ xor.l er1,er1
+ xorc #16,ccr
+ xorc #16,exr
+ neg.b r0l
+ neg.w r0
+ neg.l er0
+ not.b r0l
+ not.w r0
+ not.l er0
+
diff --git a/gas/testsuite/gas/h8300/macs.s b/gas/testsuite/gas/h8300/macs.s
new file mode 100644
index 00000000000..e2df6ddb652
--- /dev/null
+++ b/gas/testsuite/gas/h8300/macs.s
@@ -0,0 +1,11 @@
+ .h8300s
+ .text
+h8300s_mac:
+ clrmac
+ ldmac er0,mach
+ ldmac er1,macl
+ mac @er0+,@er1+
+ stmac mach,er0
+ stmac macl,er1
+
+
diff --git a/gas/testsuite/gas/h8300/misc.s b/gas/testsuite/gas/h8300/misc.s
new file mode 100644
index 00000000000..1f6f8084b67
--- /dev/null
+++ b/gas/testsuite/gas/h8300/misc.s
@@ -0,0 +1,13 @@
+ .text
+h8300_misc:
+ eepmov
+ ldc #0,ccr
+ ldc r0l,ccr
+; movfpe 16:16,r0l
+; movtpe r0l,16:16
+ nop
+ rte
+ rts
+ sleep
+ stc ccr,r0l
+
diff --git a/gas/testsuite/gas/h8300/misch.s b/gas/testsuite/gas/h8300/misch.s
new file mode 100644
index 00000000000..f7ecb3de079
--- /dev/null
+++ b/gas/testsuite/gas/h8300/misch.s
@@ -0,0 +1,27 @@
+ .h8300h
+ .text
+h8300h_misc:
+ eepmov.b
+ eepmov.w
+ ldc.b #0,ccr
+ ldc.b r0l,ccr
+ ldc.w @er0,ccr
+ ldc.w @(16:16,er0),ccr
+ ldc.w @(32:24,er0),ccr
+ ldc.w @er0+,ccr
+ ldc.w @h8300h_misc:16,ccr
+ ldc.w @h8300h_misc:24,ccr
+; movfpe 16:16,r0l
+; movtpe r0l,16:16
+ nop
+ rte
+ rts
+ sleep
+ stc.b ccr,r0l
+ stc.w ccr,@er0
+ stc.w ccr,@(16:16,er0)
+ stc.w ccr,@(32:24,er0)
+ stc.w ccr,@-er0
+ stc.w ccr,@h8300h_misc:16
+ stc.w ccr,@h8300h_misc:24
+
diff --git a/gas/testsuite/gas/h8300/miscs.s b/gas/testsuite/gas/h8300/miscs.s
new file mode 100644
index 00000000000..d37a1770c75
--- /dev/null
+++ b/gas/testsuite/gas/h8300/miscs.s
@@ -0,0 +1,41 @@
+ .h8300s
+ .text
+h8300s_misc:
+ eepmov.b
+ eepmov.w
+ ldc.b #0,ccr
+ ldc.b r0l,ccr
+ ldc.b #0,exr
+ ldc.b r0l,exr
+ ldc.w @er0,ccr
+ ldc.w @(16:16,er0),ccr
+ ldc.w @(32:32,er0),ccr
+ ldc.w @er0+,ccr
+ ldc.w @h8300s_misc:16,ccr
+ ldc.w @h8300s_misc:32,ccr
+ ldc.w @er0,exr
+ ldc.w @(16:16,er0),exr
+ ldc.w @(32:32,er0),exr
+ ldc.w @er0+,exr
+ ldc.w @h8300s_misc:16,exr
+ ldc.w @h8300s_misc:32,exr
+; movfpe 16:16,r0l
+; movtpe r0l,16:16
+ nop
+ rte
+ rts
+ sleep
+ stc.b ccr,r0l
+ stc.b exr,r0l
+ stc.w ccr,@er0
+ stc.w ccr,@(16:16,er0)
+ stc.w ccr,@(32:32,er0)
+ stc.w ccr,@-er0
+ stc.w ccr,@h8300s_misc:16
+ stc.w ccr,@h8300s_misc:32
+ stc.w exr,@er0
+ stc.w exr,@(16:16,er0)
+ stc.w exr,@(32:32,er0)
+ stc.w exr,@-er0
+ stc.w exr,@h8300s_misc:16
+ stc.w exr,@h8300s_misc:32
diff --git a/gas/testsuite/gas/h8300/mov32bug.s b/gas/testsuite/gas/h8300/mov32bug.s
new file mode 100644
index 00000000000..68393e3f54e
--- /dev/null
+++ b/gas/testsuite/gas/h8300/mov32bug.s
@@ -0,0 +1,4 @@
+ .h8300h
+ .global _a
+blah:
+ mov.l #_a-2000000000,er2
diff --git a/gas/testsuite/gas/h8300/movb.s b/gas/testsuite/gas/h8300/movb.s
new file mode 100644
index 00000000000..fa040c0a7bf
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movb.s
@@ -0,0 +1,15 @@
+ .text
+h8300_movb:
+ mov.b r0l,r1l
+ mov.b #16,r0l
+ mov.b @r1,r0l
+ mov.b @(16:16,r1),r0l
+ mov.b @r1+,r0l
+ mov.b @16:8,r0l
+ mov.b @h8300_movb:16,r0l
+ mov.b r0l,@r1
+ mov.b r0l,@(16:16,r1)
+ mov.b r0l,@-r1
+ mov.b r0l,@16:8
+ mov.b r0l,@h8300_movb:16
+
diff --git a/gas/testsuite/gas/h8300/movbh.s b/gas/testsuite/gas/h8300/movbh.s
new file mode 100644
index 00000000000..7d711f8512e
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movbh.s
@@ -0,0 +1,20 @@
+ .h8300h
+ .text
+h8300h_movb:
+ mov.b r0l,r1l
+ mov.b #16,r0l
+ mov.b @er1,r0l
+ mov.b @(16:16,er1),r0l
+ mov.b @(32:24,er1),r0l
+ mov.b @er1+,r0l
+ mov.b @16:8,r0l
+ mov.b @h8300h_movb:16,r0l
+ mov.b @h8300h_movb:24,r0l
+ mov.b r0l,@er1
+ mov.b r0l,@(16:16,er1)
+ mov.b r0l,@(32:24,er1)
+ mov.b r0l,@-er1
+ mov.b r0l,@16:8
+ mov.b r0l,@h8300h_movb:16
+ mov.b r0l,@h8300h_movb:24
+
diff --git a/gas/testsuite/gas/h8300/movbs.s b/gas/testsuite/gas/h8300/movbs.s
new file mode 100644
index 00000000000..925002c811a
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movbs.s
@@ -0,0 +1,20 @@
+ .h8300s
+ .text
+h8300s_movb:
+ mov.b r0l,r1l
+ mov.b #16,r0l
+ mov.b @er1,r0l
+ mov.b @(16:16,er1),r0l
+ mov.b @(32:32,er1),r0l
+ mov.b @er1+,r0l
+ mov.b @16:8,r0l
+ mov.b @h8300s_movb:16,r0l
+ mov.b @h8300s_movb:32,r0l
+ mov.b r0l,@er1
+ mov.b r0l,@(16:16,er1)
+ mov.b r0l,@(32:32,er1)
+ mov.b r0l,@-er1
+ mov.b r0l,@16:8
+ mov.b r0l,@h8300s_movb:16
+ mov.b r0l,@h8300s_movb:32
+
diff --git a/gas/testsuite/gas/h8300/movlh.s b/gas/testsuite/gas/h8300/movlh.s
new file mode 100644
index 00000000000..0cc78e8d361
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movlh.s
@@ -0,0 +1,18 @@
+ .h8300h
+ .text
+h8300h_movl:
+ mov.l er0,er1
+ mov.l #64,er0
+ mov.l @er1,er0
+ mov.l @(16:16,er1),er0
+ mov.l @(32:24,er1),er0
+ mov.l @er1+,er0
+ mov.l @h8300h_movl:16,er0
+ mov.l @h8300h_movl:24,er0
+ mov.l er0,@er1
+ mov.l er0,@(16:16,er1)
+ mov.l er0,@(32:24,er1)
+ mov.l er0,@-er1
+ mov.l er0,@h8300h_movl:16
+ mov.l er0,@h8300h_movl:24
+
diff --git a/gas/testsuite/gas/h8300/movls.s b/gas/testsuite/gas/h8300/movls.s
new file mode 100644
index 00000000000..46437677389
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movls.s
@@ -0,0 +1,18 @@
+ .h8300s
+ .text
+h8300s_movl:
+ mov.l er0,er1
+ mov.l #64,er0
+ mov.l @er1,er0
+ mov.l @(16:16,er1),er0
+ mov.l @(32:32,er1),er0
+ mov.l @er1+,er0
+ mov.l @h8300s_movl:16,er0
+ mov.l @h8300s_movl:32,er0
+ mov.l er0,@er1
+ mov.l er0,@(16:16,er1)
+ mov.l er0,@(32:32,er1)
+ mov.l er0,@-er1
+ mov.l er0,@h8300s_movl:16
+ mov.l er0,@h8300s_movl:32
+
diff --git a/gas/testsuite/gas/h8300/movw.s b/gas/testsuite/gas/h8300/movw.s
new file mode 100644
index 00000000000..0cc64f8d522
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movw.s
@@ -0,0 +1,13 @@
+ .text
+h8300_movw:
+ mov.w r0,r1
+ mov.w #16,r0
+ mov.w @r1,r0
+ mov.w @(16:16,r1),r0
+ mov.w @r1+,r0
+ mov.w @h8300_movw:16,r0
+ mov.w r0,@r1
+ mov.w r0,@(16:16,r1)
+ mov.w r0,@-r1
+ mov.w r0,@h8300_movw:16
+
diff --git a/gas/testsuite/gas/h8300/movwh.s b/gas/testsuite/gas/h8300/movwh.s
new file mode 100644
index 00000000000..595057cb3d7
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movwh.s
@@ -0,0 +1,18 @@
+ .h8300h
+ .text
+h8300h_movw:
+ mov.w r0,r1
+ mov.w #16,r0
+ mov.w @er1,r0
+ mov.w @(16:16,er1),r0
+ mov.w @(32:24,er1),r0
+ mov.w @er1+,r0
+ mov.w @h8300h_movw:16,r0
+ mov.w @h8300h_movw:24,r0
+ mov.w r0,@er1
+ mov.w r0,@(16:16,er1)
+ mov.w r0,@(32:24,er1)
+ mov.w r0,@-er1
+ mov.w r0,@h8300h_movw:16
+ mov.w r0,@h8300h_movw:24
+
diff --git a/gas/testsuite/gas/h8300/movws.s b/gas/testsuite/gas/h8300/movws.s
new file mode 100644
index 00000000000..a4f21df2542
--- /dev/null
+++ b/gas/testsuite/gas/h8300/movws.s
@@ -0,0 +1,18 @@
+ .h8300s
+ .text
+h8300s_movw:
+ mov.w r0,r1
+ mov.w #16,r0
+ mov.w @er1,r0
+ mov.w @(16:16,er1),r0
+ mov.w @(32:32,er1),r0
+ mov.w @er1+,r0
+ mov.w @h8300s_movw:16,r0
+ mov.w @h8300s_movw:32,r0
+ mov.w r0,@er1
+ mov.w r0,@(16:16,er1)
+ mov.w r0,@(32:32,er1)
+ mov.w r0,@-er1
+ mov.w r0,@h8300s_movw:16
+ mov.w r0,@h8300s_movw:32
+
diff --git a/gas/testsuite/gas/h8300/multiples.s b/gas/testsuite/gas/h8300/multiples.s
new file mode 100644
index 00000000000..52079b6d219
--- /dev/null
+++ b/gas/testsuite/gas/h8300/multiples.s
@@ -0,0 +1,10 @@
+ .h8300s
+ .text
+h8300s_multiple:
+ ldm.l @sp+,er0-er1
+ ldm.l @sp+,er0-er2
+ ldm.l @sp+,er0-er3
+ stm.l er0-er1,@-sp
+ stm.l er0-er2,@-sp
+ stm.l er0-er3,@-sp
+
diff --git a/gas/testsuite/gas/h8300/pushpop.s b/gas/testsuite/gas/h8300/pushpop.s
new file mode 100644
index 00000000000..941b7357537
--- /dev/null
+++ b/gas/testsuite/gas/h8300/pushpop.s
@@ -0,0 +1,5 @@
+ .text
+h8300_push_pop:
+ pop r0
+ push r0
+
diff --git a/gas/testsuite/gas/h8300/pushpoph.s b/gas/testsuite/gas/h8300/pushpoph.s
new file mode 100644
index 00000000000..6049639f567
--- /dev/null
+++ b/gas/testsuite/gas/h8300/pushpoph.s
@@ -0,0 +1,8 @@
+ .h8300h
+ .text
+h8300h_push_pop:
+ pop.w r0
+ pop.l er0
+ push.w r0
+ push.l er0
+
diff --git a/gas/testsuite/gas/h8300/pushpops.s b/gas/testsuite/gas/h8300/pushpops.s
new file mode 100644
index 00000000000..741df04ecc5
--- /dev/null
+++ b/gas/testsuite/gas/h8300/pushpops.s
@@ -0,0 +1,8 @@
+ .h8300s
+ .text
+h8300s_push_pop:
+ pop.w r0
+ pop.l er0
+ push.w r0
+ push.l er0
+
diff --git a/gas/testsuite/gas/h8300/rotsh.s b/gas/testsuite/gas/h8300/rotsh.s
new file mode 100644
index 00000000000..a9aa87df95e
--- /dev/null
+++ b/gas/testsuite/gas/h8300/rotsh.s
@@ -0,0 +1,11 @@
+ .text
+h8300_rotate_shift:
+ rotl r0l
+ rotr r0l
+ rotxl r0l
+ rotxr r0l
+ shal r0l
+ shar r0l
+ shll r0l
+ shlr r0l
+
diff --git a/gas/testsuite/gas/h8300/rotshh.s b/gas/testsuite/gas/h8300/rotshh.s
new file mode 100644
index 00000000000..c7abe40a28f
--- /dev/null
+++ b/gas/testsuite/gas/h8300/rotshh.s
@@ -0,0 +1,27 @@
+ .h8300h
+ .text
+h8300h_rotate_shift:
+ rotl.b r0l
+ rotl.w r0
+ rotl.l er0
+ rotr.b r0l
+ rotr.w r0
+ rotr.l er0
+ rotxl.b r0l
+ rotxl.w r0
+ rotxl.l er0
+ rotxr.b r0l
+ rotxr.w r0
+ rotxr.l er0
+ shal.b r0l
+ shal.w r0
+ shal.l er0
+ shar.b r0l
+ shar.w r0
+ shar.l er0
+ shll.b r0l
+ shll.w r0
+ shll.l er0
+ shlr.b r0l
+ shlr.w r0
+ shlr.l er0
diff --git a/gas/testsuite/gas/h8300/rotshs.s b/gas/testsuite/gas/h8300/rotshs.s
new file mode 100644
index 00000000000..36c41cb59c5
--- /dev/null
+++ b/gas/testsuite/gas/h8300/rotshs.s
@@ -0,0 +1,51 @@
+ .h8300s
+ .text
+h8300s_rotate_shift:
+ rotl.b r0l
+ rotl.b #2,r0l
+ rotl.w r0
+ rotl.w #2,r0
+ rotl.l er0
+ rotl.l #2,er0
+ rotr.b r0l
+ rotr.b #2,r0l
+ rotr.w r0
+ rotr.w #2,r0
+ rotr.l er0
+ rotr.l #2,er0
+ rotxl.b r0l
+ rotxl.b #2,r0l
+ rotxl.w r0
+ rotxl.w #2,r0
+ rotxl.l er0
+ rotxl.l #2,er0
+ rotxr.b r0l
+ rotxr.b #2,r0l
+ rotxr.w r0
+ rotxr.w #2,r0
+ rotxr.l er0
+ rotxr.l #2,er0
+ shal.b r0l
+ shal.b #2,r0l
+ shal.w r0
+ shal.w #2,r0
+ shal.l er0
+ shal.l #2,er0
+ shar.b r0l
+ shar.b #2,r0l
+ shar.w r0
+ shar.w #2,r0
+ shar.l er0
+ shar.l #2,er0
+ shll.b r0l
+ shll.b #2,r0l
+ shll.w r0
+ shll.w #2,r0
+ shll.l er0
+ shll.l #2,er0
+ shlr.b r0l
+ shlr.b #2,r0l
+ shlr.w r0
+ shlr.w #2,r0
+ shlr.l er0
+ shlr.l #2,er0
diff --git a/gas/testsuite/gas/hppa/README b/gas/testsuite/gas/hppa/README
new file mode 100644
index 00000000000..a6b174a3bc5
--- /dev/null
+++ b/gas/testsuite/gas/hppa/README
@@ -0,0 +1,34 @@
+Notes on how the HPPA testsuite is organized:
+
+basic.parse -- this directory contains the basic instruction parsing
+tests and a simple .stab parsing test. This would be where you'd
+add code to make sure new instructions are parsed correctly, new
+completers (such as cache hits) are parsed correctly, etc.
+
+It's also a reasonable place to make sure parsing of the various
+assembler directives is handled correctly. If you're going to add
+such code, try to be reasonably complete. Add test code for each
+basic directive and test all (or a noteworthy) subset of arguments.
+
+It should only be necessary to have an assembler to run these tests;
+calling objdump_start or something similar should not be done from
+this directory.
+
+
+more.parse -- this is where you should put additional parsing tests, such
+as tests to check mode selector parsing, string parsing, expression parsing,
+etc. It's also a reasonable place to put parsing tests which are not complete
+enough (whatever that means) for basic.parse.
+
+It should only be necessary to have an assembler to run these tests;
+calling objdump_start or something similar should not be done from
+this directory.
+
+
+reloc -- this is where you tests which examine relocations produced
+by GAS belong. To run these tests you must have a functioning objdump.
+
+
+unsorted -- this is where everything else goes. As groups of related tests
+end up in this directory, they should be broken out into a new class of
+tests.
diff --git a/gas/testsuite/gas/hppa/basic/add.s b/gas/testsuite/gas/hppa/basic/add.s
new file mode 100644
index 00000000000..4d1d4cd6d7a
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/add.s
@@ -0,0 +1,100 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic add/sh?add instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ add %r4,%r5,%r6
+ add,= %r4,%r5,%r6
+ add,< %r4,%r5,%r6
+ add,<= %r4,%r5,%r6
+ add,nuv %r4,%r5,%r6
+ add,znv %r4,%r5,%r6
+ add,sv %r4,%r5,%r6
+ add,od %r4,%r5,%r6
+ add,tr %r4,%r5,%r6
+ add,<> %r4,%r5,%r6
+ add,>= %r4,%r5,%r6
+ add,> %r4,%r5,%r6
+ add,uv %r4,%r5,%r6
+ add,vnz %r4,%r5,%r6
+ add,nsv %r4,%r5,%r6
+ add,ev %r4,%r5,%r6
+
+ addl %r4,%r5,%r6
+ addl,= %r4,%r5,%r6
+ addl,< %r4,%r5,%r6
+ addl,<= %r4,%r5,%r6
+ addl,nuv %r4,%r5,%r6
+ addl,znv %r4,%r5,%r6
+ addl,sv %r4,%r5,%r6
+ addl,od %r4,%r5,%r6
+ addl,tr %r4,%r5,%r6
+ addl,<> %r4,%r5,%r6
+ addl,>= %r4,%r5,%r6
+ addl,> %r4,%r5,%r6
+ addl,uv %r4,%r5,%r6
+ addl,vnz %r4,%r5,%r6
+ addl,nsv %r4,%r5,%r6
+ addl,ev %r4,%r5,%r6
+
+ addo %r4,%r5,%r6
+ addo,= %r4,%r5,%r6
+ addo,< %r4,%r5,%r6
+ addo,<= %r4,%r5,%r6
+ addo,nuv %r4,%r5,%r6
+ addo,znv %r4,%r5,%r6
+ addo,sv %r4,%r5,%r6
+ addo,od %r4,%r5,%r6
+ addo,tr %r4,%r5,%r6
+ addo,<> %r4,%r5,%r6
+ addo,>= %r4,%r5,%r6
+ addo,> %r4,%r5,%r6
+ addo,uv %r4,%r5,%r6
+ addo,vnz %r4,%r5,%r6
+ addo,nsv %r4,%r5,%r6
+ addo,ev %r4,%r5,%r6
+
+ addc %r4,%r5,%r6
+ addc,= %r4,%r5,%r6
+ addc,< %r4,%r5,%r6
+ addc,<= %r4,%r5,%r6
+ addc,nuv %r4,%r5,%r6
+ addc,znv %r4,%r5,%r6
+ addc,sv %r4,%r5,%r6
+ addc,od %r4,%r5,%r6
+ addc,tr %r4,%r5,%r6
+ addc,<> %r4,%r5,%r6
+ addc,>= %r4,%r5,%r6
+ addc,> %r4,%r5,%r6
+ addc,uv %r4,%r5,%r6
+ addc,vnz %r4,%r5,%r6
+ addc,nsv %r4,%r5,%r6
+ addc,ev %r4,%r5,%r6
+
+ addco %r4,%r5,%r6
+ addco,= %r4,%r5,%r6
+ addco,< %r4,%r5,%r6
+ addco,<= %r4,%r5,%r6
+ addco,nuv %r4,%r5,%r6
+ addco,znv %r4,%r5,%r6
+ addco,sv %r4,%r5,%r6
+ addco,od %r4,%r5,%r6
+ addco,tr %r4,%r5,%r6
+ addco,<> %r4,%r5,%r6
+ addco,>= %r4,%r5,%r6
+ addco,> %r4,%r5,%r6
+ addco,uv %r4,%r5,%r6
+ addco,vnz %r4,%r5,%r6
+ addco,nsv %r4,%r5,%r6
+ addco,ev %r4,%r5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/addi.s b/gas/testsuite/gas/hppa/basic/addi.s
new file mode 100644
index 00000000000..b036b801606
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/addi.s
@@ -0,0 +1,83 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ addi 123,%r5,%r6
+ addi,= 123,%r5,%r6
+ addi,< 123,%r5,%r6
+ addi,<= 123,%r5,%r6
+ addi,nuv 123,%r5,%r6
+ addi,znv 123,%r5,%r6
+ addi,sv 123,%r5,%r6
+ addi,od 123,%r5,%r6
+ addi,tr 123,%r5,%r6
+ addi,<> 123,%r5,%r6
+ addi,>= 123,%r5,%r6
+ addi,> 123,%r5,%r6
+ addi,uv 123,%r5,%r6
+ addi,vnz 123,%r5,%r6
+ addi,nsv 123,%r5,%r6
+ addi,ev 123,%r5,%r6
+
+ addio 123,%r5,%r6
+ addio,= 123,%r5,%r6
+ addio,< 123,%r5,%r6
+ addio,<= 123,%r5,%r6
+ addio,nuv 123,%r5,%r6
+ addio,znv 123,%r5,%r6
+ addio,sv 123,%r5,%r6
+ addio,od 123,%r5,%r6
+ addio,tr 123,%r5,%r6
+ addio,<> 123,%r5,%r6
+ addio,>= 123,%r5,%r6
+ addio,> 123,%r5,%r6
+ addio,uv 123,%r5,%r6
+ addio,vnz 123,%r5,%r6
+ addio,nsv 123,%r5,%r6
+ addio,ev 123,%r5,%r6
+
+ addit 123,%r5,%r6
+ addit,= 123,%r5,%r6
+ addit,< 123,%r5,%r6
+ addit,<= 123,%r5,%r6
+ addit,nuv 123,%r5,%r6
+ addit,znv 123,%r5,%r6
+ addit,sv 123,%r5,%r6
+ addit,od 123,%r5,%r6
+ addit,tr 123,%r5,%r6
+ addit,<> 123,%r5,%r6
+ addit,>= 123,%r5,%r6
+ addit,> 123,%r5,%r6
+ addit,uv 123,%r5,%r6
+ addit,vnz 123,%r5,%r6
+ addit,nsv 123,%r5,%r6
+ addit,ev 123,%r5,%r6
+
+ addito 123,%r5,%r6
+ addito,= 123,%r5,%r6
+ addito,< 123,%r5,%r6
+ addito,<= 123,%r5,%r6
+ addito,nuv 123,%r5,%r6
+ addito,znv 123,%r5,%r6
+ addito,sv 123,%r5,%r6
+ addito,od 123,%r5,%r6
+ addito,tr 123,%r5,%r6
+ addito,<> 123,%r5,%r6
+ addito,>= 123,%r5,%r6
+ addito,> 123,%r5,%r6
+ addito,uv 123,%r5,%r6
+ addito,vnz 123,%r5,%r6
+ addito,nsv 123,%r5,%r6
+ addito,ev 123,%r5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/basic.exp b/gas/testsuite/gas/hppa/basic/basic.exp
new file mode 100644
index 00000000000..a9ba5ea9e2a
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/basic.exp
@@ -0,0 +1,2262 @@
+# Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by the Center for Software Science at the Univeristy of Utah
+# and by Cygnus Support.
+
+proc do_imem {} {
+ set testname "imem.s: integer memory loads and stores"
+ set x 0
+
+ gas_start "imem.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 489A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0000 0C80109A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 449A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 0C80105A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 409A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 0C80101A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 689A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 0C9A1280\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 649A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 0C9A1240\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 609A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 0C9A1200\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 4C9A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 6C9A0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 0C85009A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 0C85209A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 0C8500BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 0C8520BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 0C85005A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 0C85205A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 0C85007A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 0C85207A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 0C85001A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 0C85201A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 0C85003A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 0C85203A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 0C85019A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 0C85219A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 0C8501BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 0C8521BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 0C8501DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 0C8521DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 0C8501FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 0C8521FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 0C80109A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 0C8030BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 0C8010BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 0C80105A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 0C80307A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 0C80107A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 0C80101A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 0C80303A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 0C80103A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 0C80119A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 0C8031BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 0C8011BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 0C8011DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 0C8031FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 0C8011FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 0C9A1280\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 0C9A32A0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 0C9A12A0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 0C9A1240\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 0C9A3260\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 0C9A1260\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 0C9A1200\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 0C9A3220\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 0C9A1220\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 0C9A1380\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 0C9A33A0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 0C9A13A0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc 0C9A1300\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 0C9A1300\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 0C9A3300\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 0C9A1320\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec 0C9A3320\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==60] then { pass $testname } else { fail $testname }
+}
+
+proc do_immed {} {
+ set testname "immed.s: immediate tests"
+ set x 0
+
+ gas_start "immed.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 375A000A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 234DFBD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 28ADFBD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==3] then { pass $testname } else { fail $testname }
+}
+
+proc do_branch {} {
+ set testname "branch.s: branch tests"
+ set x 0
+
+ gas_start "branch.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E85F1FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 E85F1FEF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 E81F1FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c E81F1FDF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 E85F3FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 E85F3FCF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 E8444000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c E8444002\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 E8044000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 E8044002\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 E840C000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c E840C002\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 E040446C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 E040446E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 E440446C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c E440446E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 CB441FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 CB443FED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 CB445FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c CB447FDD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 CB449FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 CB44BFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 CB44DFC5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c CB44FFBD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 CB441FB7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 CB443FAF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 CB445FA7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c CB447F9F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 CB449F97\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 CB44BF8F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 CB44DF87\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c CB44FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 CF4A1FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 CF4A3FED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 CF4A5FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c CF4A7FDD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 CF4A9FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 CF4ABFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 CF4ADFC5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c CF4AFFBD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 CF4A1FB7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 CF4A3FAF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 CF4A5FA7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac CF4A7F9F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 CF4A9F97\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 CF4ABF8F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 CF4ADF87\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc CF4AFF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 80801FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 80803FED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 80805FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 80807FDD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 80809FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 8080BFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 8080DFC5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc 8080FFBD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 88801FB5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 88803FAD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 88805FA5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec 88807F9D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 88809F95\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 8880BF8D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 8880DF85\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc 8880FF7D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0100 80801F77\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0104 80803F6F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0108 80805F67\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 010c 80807F5F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0110 80809F57\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0114 8080BF4F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0118 8080DF47\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011c 8080FF3F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0120 88801F37\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0124 88803F2F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0128 88805F27\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 012c 88807F1F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0130 88809F17\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0134 8880BF0F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0138 8880DF07\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 013c 8880FEFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0140 84801FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0144 84805FED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0148 84807FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 014c 84809FDD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0150 8480BFD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0154 8480DFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0158 8480FFC5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 015c 8C801FBD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0160 8C803FB5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0164 8C805FAD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0168 8C807FA5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 016c 8C809F9D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0170 8C80BF95\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0174 8C80DF8D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0178 8C80FE85\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 017c 84801F7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0180 84803F77\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0184 84805F6F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0188 84807F67\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 018c 84809F5F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0190 8480BF57\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0194 8480DF4F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0198 8480FF47\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 019c 8C801F3F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01a0 8C803F37\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01a4 8C805F2F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01a8 8C807F27\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01ac 8C809F1F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01b0 8C80BF17\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01b4 8C80DF0F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01b8 8C80FF07\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01bc A0811FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01c0 A0813FED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01c4 A0815FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01c8 A0817FDD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01cc A0819FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01d0 A081BFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01d4 A081DFC5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01d8 A081FFBD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01dc A8811FB5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01e0 A8813FAD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01e4 A8815FA5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01e8 A8817F9D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01ec A8819F95\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01f0 A881BF8D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01f4 A881DF85\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01f8 A881FF7D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01fc A0811F77\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0200 A0813F6F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0204 A0815F67\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0208 A0817F5F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 020c A0819F57\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0210 A081BF4F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0214 A081DF47\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0218 A081FF3F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 021c A8811F37\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0220 A8813F2F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0224 A8815F27\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0228 A8817F1F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 022c A8819F17\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0230 A881BF0F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0234 A881DF07\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0238 A881FEFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 023c A49F1FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0240 A49F3FED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0244 A49F5FE5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0248 A49F7FDD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 024c A49F9FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0250 A49FBFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0254 A49FDFC5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0258 A49FFFBD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 025c AC9F1FB5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0260 AC9F3FAD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0264 AC9F5FA5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0268 AC9F7F9D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 026c AC9F9F95\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0270 AC9FBF8D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0274 AC9FDF85\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0278 AC9FFC85\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 027c A49F1F77\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0280 A49F3F6F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0284 A49F5F67\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0288 A49F7F5F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 028c A49F9F57\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0290 A49FBF4F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0294 A49FDF47\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0298 A49FFF3F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 029c AC9F1F37\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02a0 AC9F3F2F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02a4 AC9F5F27\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02a8 AC9F7F1F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02ac AC9F9F17\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02b0 AC9FBF0F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02b4 AC9FDF07\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02b8 AC9FFEFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02bc C0045FF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02c0 C004DFED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02c4 C0045FE7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02c8 C004DFDF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02cc C4A45FD5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02d0 C4A4DFCD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02d4 C4A45FC7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 02d8 C4A4DFBF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==183] then { pass $testname } else { fail $testname }
+}
+
+proc do_add {} {
+ set testname "add.s: add tests"
+ set x 0
+
+ gas_start "add.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A48606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A41606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A43606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A45606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A47606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A49606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A40A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A42A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A44A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A46A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A48A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A4AA06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A4CA06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A4EA06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A41A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A43A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A45A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A47A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A49A06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4BA06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A4DA06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A4FA06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A40E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A42E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A44E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A46E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 08A48E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 08A4AE06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 08A4CE06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 08A4EE06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 08A41E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 08A43E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 08A45E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 08A47E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 08A49E06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 08A4BE06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 08A4DE06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 08A4FE06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 08A40706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 08A42706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 08A44706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 08A46706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 08A48706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 08A4A706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 08A4C706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc 08A4E706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 08A41706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 08A43706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 08A45706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec 08A47706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 08A49706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 08A4B706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 08A4D706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc 08A4F706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0100 08A40F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0104 08A42F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0108 08A44F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 010c 08A46F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0110 08A48F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0114 08A4AF06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0118 08A4CF06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011c 08A4EF06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0120 08A41F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0124 08A43F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0128 08A45F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 012c 08A47F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0130 08A49F06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0134 08A4BF06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0138 08A4DF06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 013c 08A4FF06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==80] then { pass $testname } else { fail $testname }
+}
+
+proc do_sh1add {} {
+ set testname "sh1add.s: sh1add tests"
+ set x 0
+
+ gas_start "sh1add.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A48646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A41646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A43646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A45646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A47646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A49646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F646\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A40A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A42A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A44A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A46A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A48A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A4AA46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A4CA46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A4EA46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A41A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A43A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A45A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A47A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A49A46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4BA46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A4DA46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A4FA46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A40E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A42E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A44E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A46E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 08A48E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 08A4AE46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 08A4CE46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 08A4EE46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 08A41E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 08A43E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 08A45E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 08A47E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 08A49E46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 08A4BE46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 08A4DE46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 08A4FE46\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==48] then { pass $testname } else { fail $testname }
+}
+
+proc do_sh2add {} {
+ set testname "sh2add.s: sh2add tests"
+ set x 0
+
+ gas_start "sh2add.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A48686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A41686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A43686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A45686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A47686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A49686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F686\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A40A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A42A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A44A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A46A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A48A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A4AA86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A4CA86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A4EA86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A41A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A43A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A45A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A47A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A49A86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4BA86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A4DA86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A4FA86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A40E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A42E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A44E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A46E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 08A48E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 08A4AE86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 08A4CE86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 08A4EE86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 08A41E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 08A43E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 08A45E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 08A47E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 08A49E86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 08A4BE86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 08A4DE86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 08A4FE86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==48] then { pass $testname } else { fail $testname }
+}
+
+proc do_sh3add {} {
+ set testname "sh3add.s: sh3add tests"
+ set x 0
+
+ gas_start "sh3add.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A406C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A426C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A446C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A466C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A486C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A6C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C6C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E6C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A416C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A436C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A456C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A476C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A496C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B6C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D6C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F6C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A40AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A42AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A44AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A46AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A48AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A4AAC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A4CAC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A4EAC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A41AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A43AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A45AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A47AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A49AC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4BAC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A4DAC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A4FAC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A40EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A42EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A44EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A46EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 08A48EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 08A4AEC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 08A4CEC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 08A4EEC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 08A41EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 08A43EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 08A45EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 08A47EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 08A49EC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 08A4BEC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 08A4DEC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 08A4FEC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==48] then { pass $testname } else { fail $testname }
+}
+
+proc do_sub {} {
+ set testname "sub.s: sub tests"
+ set x 0
+
+ gas_start "sub.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A48406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A41406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A43406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A45406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A47406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A49406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F406\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A40C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A42C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A44C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A46C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A48C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A4AC06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A4CC06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A4EC06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A41C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A43C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A45C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A47C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A49C06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4BC06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A4DC06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A4FC06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A40506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A42506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A44506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A46506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 08A48506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 08A4A506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 08A4C506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 08A4E506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 08A41506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 08A43506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 08A45506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 08A47506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 08A49506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 08A4B506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 08A4D506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 08A4F506\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 08A40D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 08A42D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 08A44D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 08A46D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 08A48D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 08A4AD06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 08A4CD06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc 08A4ED06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 08A41D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 08A43D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 08A45D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec 08A47D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 08A49D06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 08A4BD06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 08A4DD06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc 08A4FD06\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0100 08A404C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0104 08A424C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0108 08A444C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 010c 08A464C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0110 08A484C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0114 08A4A4C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0118 08A4C4C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011c 08A4E4C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0120 08A414C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0124 08A434C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0128 08A454C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 012c 08A474C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0130 08A494C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0134 08A4B4C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0138 08A4D4C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 013c 08A4F4C6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0140 08A40CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0144 08A42CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0148 08A44CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 014c 08A46CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0150 08A48CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0154 08A4ACC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0158 08A4CCC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 015c 08A4ECC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0160 08A41CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0164 08A43CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0168 08A45CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 016c 08A47CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0170 08A49CC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0174 08A4BCC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0178 08A4DCC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 017c 08A4FCC6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==96] then { pass $testname } else { fail $testname }
+}
+
+proc do_ds {} {
+ set testname "ds.s: ds tests"
+ set x 0
+
+ gas_start "ds.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A48446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A41446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A43446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A45446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A47446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A49446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F446\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==16] then { pass $testname } else { fail $testname }
+}
+
+proc do_comclr {} {
+ set testname "comclr.s: comclr tests"
+ set x 0
+
+ gas_start "comclr.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A48886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4A886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A4C886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A4E886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A41886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A43886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A45886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A47886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A49886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A4B886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4D886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A4F886\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 90A600F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 90A620F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 90A640F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 90A660F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 90A680F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 90A6A0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 90A6C0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 90A6E0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 90A610F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 90A630F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 90A650F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 90A670F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 90A690F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 90A6B0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 90A6D0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 90A6F0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==32] then { pass $testname } else { fail $testname }
+}
+
+proc do_logical {} {
+ set testname "logical.s: logical tests"
+ set x 0
+
+ gas_start "logical.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A42246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A44246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A46246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A4E246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A41246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A43246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A45246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A47246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A4F246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A40286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A42286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A44286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A46286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A4E286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A41286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A43286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A45286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A47286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A4F286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A40206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A42206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A44206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A46206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A4E206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A41206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A43206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A45206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A47206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4F206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A40006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A42006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A44006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A46006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A4E006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A41006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 08A43006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 08A45006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 08A47006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 08A4F006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==40] then { pass $testname } else { fail $testname }
+}
+
+proc do_unit {} {
+ set testname "unit.s: unit tests"
+ set x 0
+
+ gas_start "unit.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08A40386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08A44386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08A46386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08A48386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 08A4C386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 08A4E386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08A41386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08A45386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08A47386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08A49386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 08A4D386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 08A4F386\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08A40986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08A44986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08A46986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08A48986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 08A4C986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 08A4E986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08A41986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08A45986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08A47986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08A49986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 08A4D986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 08A4F986\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 08A409C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 08A449C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 08A469C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 08A489C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 08A4C9C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 08A4E9C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 08A419C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 08A459C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 08A479C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 08A499C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 08A4D9C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 08A4F9C6\[^\n]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==36] then { pass $testname } else { fail $testname }
+}
+
+proc do_dcor {} {
+ set testname "dcor.s: dcor tests"
+ set x 0
+
+ gas_start "dcor.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08800B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 08804B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08806B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 08808B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 0880CB85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 0880EB85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 08801B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 08805B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 08807B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 08809B85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 0880DB85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 0880FB85\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 08800BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 08804BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 08806BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 08808BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 0880CBC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 0880EBC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 08801BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 08805BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 08807BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 08809BC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 0880DBC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 0880FBC5\[^\n]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==24] then { pass $testname } else { fail $testname }
+}
+
+proc do_addi {} {
+ set testname "addi.s: addi tests"
+ set x 0
+
+ gas_start "addi.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 B4A600F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 B4A620F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 B4A640F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c B4A660F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 B4A680F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 B4A6A0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 B4A6C0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c B4A6E0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 B4A610F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 B4A630F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 B4A650F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c B4A670F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 B4A690F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 B4A6B0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 B4A6D0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c B4A6F0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 B4A608F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 B4A628F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 B4A648F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c B4A668F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 B4A688F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 B4A6A8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 B4A6C8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c B4A6E8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 B4A618F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 B4A638F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 B4A658F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c B4A678F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 B4A698F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 B4A6B8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 B4A6D8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c B4A6F8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 B0A600F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 B0A620F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 B0A640F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c B0A660F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 B0A680F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 B0A6A0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 B0A6C0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c B0A6E0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 B0A610F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 B0A630F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 B0A650F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac B0A670F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 B0A690F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 B0A6B0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 B0A6D0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc B0A6F0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 B0A608F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 B0A628F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 B0A648F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc B0A668F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 B0A688F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 B0A6A8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 B0A6C8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc B0A6E8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 B0A618F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 B0A638F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 B0A658F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec B0A678F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 B0A698F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 B0A6B8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 B0A6D8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc B0A6F8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==64] then { pass $testname } else { fail $testname }
+}
+
+proc do_subi {} {
+ set testname "subi.s: subi tests"
+ set x 0
+
+ gas_start "subi.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 94A600F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 94A620F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 94A640F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 94A660F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 94A680F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 94A6A0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 94A6C0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 94A6E0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 94A610F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 94A630F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 94A650F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 94A670F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 94A690F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 94A6B0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 94A6D0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 94A6F0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 94A608F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 94A628F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 94A648F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 94A668F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 94A688F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 94A6A8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 94A6C8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 94A6E8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 94A618F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 94A638F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 94A658F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 94A678F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 94A698F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 94A6B8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 94A6D8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 94A6F8F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==32] then { pass $testname } else { fail $testname }
+}
+
+proc do_shift {} {
+ set testname "shift.s: shift tests"
+ set x 0
+
+ gas_start "shift.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 D0A40006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 D0A42006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 D0A44006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c D0A46006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 D0A48006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 D0A4A006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 D0A4C006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c D0A4E006\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 D0A40B46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 D0A42B46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 D0A44B46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c D0A46B46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 D0A48B46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 D0A4AB46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 D0A4CB46\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c D0A4EB46\[^\n]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==16] then { pass $testname } else { fail $testname }
+}
+
+proc do_extract {} {
+ set testname "extract.s: extract tests"
+ set x 0
+
+ gas_start "extract.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 D08618B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 D08638B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 D08658B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c D08678B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 D08698B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 D086B8B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 D086D8B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c D086F8B6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 D0861CB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 D0863CB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 D0865CB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c D0867CB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 D0869CB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 D086BCB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 D086DCB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c D086FCB6\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 D086101B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 D086301B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 D086501B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c D086701B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 D086901B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 D086B01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 D086D01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c D086F01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 D086141B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 D086341B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 D086541B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c D086741B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 D086941B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 D086B41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 D086D41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c D086F41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==32] then { pass $testname } else { fail $testname }
+}
+
+proc do_deposit {} {
+ set testname "deposit.s: deposit tests"
+ set x 0
+
+ gas_start "deposit.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 D4C40B56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 D4C42B56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 D4C44B56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c D4C46B56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 D4C48B56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 D4C4AB56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 D4C4CB56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c D4C4EB56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 D4C40F56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 D4C42F56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 D4C44F56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c D4C46F56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 D4C48F56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 D4C4AF56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 D4C4CF56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c D4C4EF56\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 D4C4001B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 D4C4201B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 D4C4401B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c D4C4601B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 D4C4801B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 D4C4A01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 D4C4C01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c D4C4E01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 D4C4041B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 D4C4241B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 D4C4441B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c D4C4641B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 D4C4841B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 D4C4A41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 D4C4C41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c D4C4E41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 D4DF141B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 D4DF341B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 D4DF541B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c D4DF741B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 D4DF941B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 D4DFB41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 D4DFD41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c D4DFF41B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 D4DF101B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 D4DF301B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 D4DF501B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac D4DF701B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 D4DF901B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 D4DFB01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 D4DFD01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc D4DFF01B\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 D4DF1F76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 D4DF3F76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 D4DF5F76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc D4DF7F76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 D4DF9F76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 D4DFBF76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 D4DFDF76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc D4DFFF76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 D4DF1B76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 D4DF3B76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 D4DF5B76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec D4DF7B76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 D4DF9B76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 D4DFBB76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 D4DFDB76\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc D4DFFB76\[^\n]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==64] then { pass $testname } else { fail $testname }
+}
+
+proc do_system {} {
+ set testname "system.s: system tests"
+ set x 0
+
+ gas_start "system.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 00018005\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 00000C00\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 00000CA0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 00050D64\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 00050E64\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 00041860\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 00A010A4\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 00041820\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 01441840\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 000004A4\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 014008A4\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 00000400\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 00100400\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 140004D2\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 04A61187\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 04A13187\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 04A611C7\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 04A131C7\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 04A41346\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 04A41366\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 04A41306\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 04A41326\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 04A41306\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 04A41040\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 04A42040\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 04A41000\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 04A42000\[^\n]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==27] then { pass $testname } else { fail $testname }
+}
+
+proc do_purge {} {
+ set testname "purge.s: purge tests"
+ set x 0
+
+ gas_start "purge.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 04A41200\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 04A41220\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 04A42200\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 04A42220\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 04A41240\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 04A41260\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 04A42240\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 04A42260\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 04A41380\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 04A413A0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 04A41280\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 04A412A0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 04A42280\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 04A422A0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 04A412C0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 04A412E0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 04A422C0\[^\n]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 04A422E0\[^\n]*\n" { set x [expr $x+1] }
+
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==18] then { pass $testname } else { fail $testname }
+}
+
+proc do_fp_misc {} {
+ set testname "fp_misc.s: fp_misc tests"
+ set x 0
+
+ gas_start "fp_misc.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 30002420\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+}
+
+proc do_fmem {} {
+ set testname "fmem.s: fmem tests"
+ set x 0
+
+ gas_start "fmem.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 24A40006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 24A42006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 24A40026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 24A42026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 2CA40006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 2CA42006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 2CA40026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 2CA42026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 24A40206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 24A42206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 24A40226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 24A42226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 2CA40206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 2CA42206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 2CA40226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 2CA42226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 3CA40206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 3CA42206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 3CA40226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 3CA42226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 24A01006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 24A03026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 24A01026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 2CA01006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 2CA03026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 2CA01026\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 24A01206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 24A03226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 24A01226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 2CA01206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 2CA03226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 2CA01226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 3CA01206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 3CA03226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 3CA01226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==35] then { pass $testname } else { fail $testname }
+}
+
+proc do_fp_comp {} {
+ set testname "fp_comp.s: fp_comp tests"
+ set x 0
+
+ gas_start "fp_comp.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 30A0400A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 30A0480A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 30A0580A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 32804018\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 32804818\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 30A0600A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 30A0680A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 30A0780A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 32806018\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 32806818\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 30A0800A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 30A0880A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 30A0980A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 32808018\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 32808818\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 30A0A00A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 30A0A80A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 30A0B80A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 3280A018\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 3280A818\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 3088060C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 30880E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 30881E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 3298061C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 32980E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 32981E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 3088260C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 30882E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 30883E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 3298261C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 32982E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 32983E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 3088460C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 30884E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 30885E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 3298461C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 32984E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 32985E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 3088660C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 30886E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 30887E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 3298661C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 32986E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 32987E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 3088860C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 30888E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 30889E0C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 3298861C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 32988E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 32989E1C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 180120E2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 1A11A4D2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 980120E2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 9A11A4D2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 38854706\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==55] then { pass $testname } else { fail $testname }
+}
+
+proc do_fp_conv {} {
+ set testname "fp_conv.s: fp_conv tests"
+ set x 0
+
+ gas_start "fp_conv.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 30A0020A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 30A0220A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 30A0620A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 30A00A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 30A02A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 30A06A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 30A01A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 30A03A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 30A07A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 32800218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 32802218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 32806218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 32800A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 32802A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 32806A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 32801A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 32803A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 32807A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 30A0820A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 30A0A20A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 30A0E20A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 30A08A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 30A0AA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 30A0EA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 30A09A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 30A0BA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 30A0FA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 32808218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 3280A218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 3280E218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 32808A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 3280AA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 3280EA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 32809A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 3280BA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 3280FA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 30A1020A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 30A1220A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 30A1620A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 30A10A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 30A12A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 30A16A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 30A11A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 30A13A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 30A17A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 32810218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 32812218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 32816218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 32810A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 32812A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 32816A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 32811A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 32813A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 32817A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 30A1820A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc 30A1A20A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 30A1E20A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 30A18A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 30A1AA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec 30A1EA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 30A19A0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 30A1BA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 30A1FA0A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc 32818218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0100 3281A218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0104 3281E218\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0108 32818A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 010c 3281AA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0110 3281EA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0114 32819A18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0118 3281BA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011c 3281FA18\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==72] then { pass $testname } else { fail $testname }
+}
+
+proc do_fp_fcmp {} {
+ set testname "fp_fcmp.s: fp_fcmp tests"
+ set x 0
+
+ gas_start "fp_fcmp.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 30850400\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 30850401\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 30850402\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 30850403\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 30850404\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 30850405\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 30850406\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 30850407\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 30850408\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 30850409\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 3085040A\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 3085040B\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 3085040C\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 3085040D\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 3085040E\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 3085040F\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 30850410\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 30850411\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 30850412\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 30850413\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 30850414\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 30850415\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 30850416\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 30850417\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 30850418\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 30850419\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 3085041A\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 3085041B\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 3085041C\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 3085041D\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 3085041E\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 3085041F\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 30850C00\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 30850C01\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 30850C02\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 30850C03\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 30850C04\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 30850C05\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 30850C06\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 30850C07\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 30850C08\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 30850C09\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 30850C0A\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 30850C0B\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 30850C0C\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 30850C0D\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 30850C0E\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 30850C0F\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 30850C10\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 30850C11\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 30850C12\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00cc 30850C13\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d0 30850C14\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 30850C15\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d8 30850C16\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00dc 30850C17\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 30850C18\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e4 30850C19\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e8 30850C1A\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec 30850C1B\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f0 30850C1C\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f4 30850C1D\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 30850C1E\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fc 30850C1F\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0100 30851C00\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0104 30851C01\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0108 30851C02\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 010c 30851C03\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0110 30851C04\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0114 30851C05\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0118 30851C06\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011c 30851C07\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0120 30851C08\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0124 30851C09\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0128 30851C0A\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 012c 30851C0B\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0130 30851C0C\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0134 30851C0D\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0138 30851C0E\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 013c 30851C0F\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0140 30851C10\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0144 30851C11\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0148 30851C12\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 014c 30851C13\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0150 30851C14\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0154 30851C15\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0158 30851C16\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 015c 30851C17\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0160 30851C18\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0164 30851C19\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0168 30851C1A\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 016c 30851C1B\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0170 30851C1C\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0174 30851C1D\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0178 30851C1E\[^\n\]*\n" {set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 017c 30851C1F\[^\n\]*\n" {set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==96] then { pass $testname } else { fail $testname }
+}
+
+proc do_special {} {
+ set testname "special.s: special tests"
+ set x 0
+
+ gas_start "special.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 04A41680\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 04A416A0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 04A41A80\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 04A41AA0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_spop {} {
+ set testname "spop.s: spop tests"
+ set x 0
+
+ # This tickles a bug in the expression parser.
+ gas_start "spop.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 10000105\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 10001913\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 10000125\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 10001933\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 10002B05\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 10039B05\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 10002B25\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 10039B25\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 10A00505\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 10A01D13\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 10A00525\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 10A01D33\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 10C50705\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 10C51F13\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 10C50725\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 10C51F33\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==16] then { pass $testname } else { fail $testname }
+}
+
+proc do_copr {} {
+ set testname "copr.s: copr tests"
+ set x 0
+
+ gas_start "copr.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 30000105\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 30000713\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 30000125\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 30000733\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_coprmem {} {
+ set testname "coprmem.s: copr memory tests"
+ set x 0
+
+ gas_start "coprmem.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 2485011A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 2485211A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 2485013A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 2485213A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 2C85011A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 2C85211A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 2C85013A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 2C85213A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 2485031A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 2485231A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 2485033A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 2485233A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 2C85031A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 2C85231A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 2C85033A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 2C85233A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 2480111A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 2480313A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 2480113A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 2C80111A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 2C80313A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 2C80113A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 2480131A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 2480333A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 2480133A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 2C80131A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 2C80333A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 2C80133A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==28] then { pass $testname } else { fail $testname }
+}
+
+proc do_fmem_LR_tests {} {
+ set testname "fmemLRbug.s: LR register selection on fp mem instructions"
+ set x 0
+
+ gas_start "fmemLRbug.s" "-al"
+
+ # Make sure we correctly handle field selectors.
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 27401246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 27481206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 27501206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 2F401206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 2F481206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 2F501206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 27401046\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 27481006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 27501006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 2F401006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 2F481006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c 2F501006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 27401246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 27481206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 27501206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 2F401206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 2F481206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 2F501206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 27401046\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c 27481006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 27501006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 2F401006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 2F481006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005c 2F501006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0060 27590246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 27590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0068 27590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006c 2F590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 2F590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 2F590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 27590046\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c 27590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 27590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 2F590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 2F590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c 2F590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 27590246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 27590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 27590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c 2F590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 2F590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 2F590206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 27590046\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac 27590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 27590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b4 2F590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b8 2F590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc 2F590006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c0 E840C000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c4 08000240\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==50] then { pass $testname } else { fail $testname }
+}
+
+if [istarget hppa*-*-*] then {
+ # Test the basic instruction parser.
+ do_imem
+ do_immed
+ do_branch
+ do_add
+ do_sh1add
+ do_sh2add
+ do_sh3add
+ do_sub
+ do_ds
+ do_comclr
+ do_logical
+ do_unit
+ do_dcor
+ do_addi
+ do_subi
+ do_shift
+ do_extract
+ do_deposit
+ do_system
+ do_purge
+ do_fp_misc
+ do_fmem
+ do_fp_comp
+ do_fp_conv
+ do_fp_fcmp
+ do_special
+ do_spop
+ do_copr
+ do_coprmem
+
+ # The "weird.s" file from the gdb testsuite. Simply verify it
+ # assembles.
+ gas_test "weird.s" "" "" "stabs parsing"
+
+ # Test that we correctly assemble some FP memory tests which
+ # L/R register selects. (Regression test for a bug Tege found).
+ do_fmem_LR_tests
+}
diff --git a/gas/testsuite/gas/hppa/basic/branch.s b/gas/testsuite/gas/hppa/basic/branch.s
new file mode 100644
index 00000000000..a1f839dd684
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/branch.s
@@ -0,0 +1,227 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; More branching instructions than you ever knew what to do with.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+branch_tests:
+ bl branch_tests,%r2
+ bl,n branch_tests,%r2
+ b branch_tests
+ b,n branch_tests
+ gate branch_tests,%r2
+ gate,n branch_tests,%r2
+ blr %r4,%r2
+ blr,n %r4,%r2
+ blr %r4,%r0
+ blr,n %r4,%r0
+ bv %r0(%r2)
+ bv,n %r0(%r2)
+ be 0x1234(%sr1,%r2)
+ be,n 0x1234(%sr1,%r2)
+ ble 0x1234(%sr1,%r2)
+ ble,n 0x1234(%sr1,%r2)
+
+movb_tests:
+ movb %r4,%r26,movb_tests
+ movb,= %r4,%r26,movb_tests
+ movb,< %r4,%r26,movb_tests
+ movb,od %r4,%r26,movb_tests
+ movb,tr %r4,%r26,movb_tests
+ movb,<> %r4,%r26,movb_tests
+ movb,>= %r4,%r26,movb_tests
+ movb,ev %r4,%r26,movb_tests
+movb_nullified_tests:
+ movb,n %r4,%r26,movb_tests
+ movb,=,n %r4,%r26,movb_tests
+ movb,<,n %r4,%r26,movb_tests
+ movb,od,n %r4,%r26,movb_tests
+ movb,tr,n %r4,%r26,movb_tests
+ movb,<>,n %r4,%r26,movb_tests
+ movb,>=,n %r4,%r26,movb_tests
+ movb,ev,n %r4,%r26,movb_tests
+
+movib_tests:
+ movib 5,%r26,movib_tests
+ movib,= 5,%r26,movib_tests
+ movib,< 5,%r26,movib_tests
+ movib,od 5,%r26,movib_tests
+ movib,tr 5,%r26,movib_tests
+ movib,<> 5,%r26,movib_tests
+ movib,>= 5,%r26,movib_tests
+ movib,ev 5,%r26,movib_tests
+movib_nullified_tests:
+ movib,n 5,%r26,movib_tests
+ movib,=,n 5,%r26,movib_tests
+ movib,<,n 5,%r26,movib_tests
+ movib,od,n 5,%r26,movib_tests
+ movib,tr,n 5,%r26,movib_tests
+ movib,<>,n 5,%r26,movib_tests
+ movib,>=,n 5,%r26,movib_tests
+ movib,ev,n 5,%r26,movib_tests
+
+comb_tests:
+ comb %r0,%r4,comb_tests
+ comb,= %r0,%r4,comb_tests
+ comb,< %r0,%r4,comb_tests
+ comb,<= %r0,%r4,comb_tests
+ comb,<< %r0,%r4,comb_tests
+ comb,<<= %r0,%r4,comb_tests
+ comb,sv %r0,%r4,comb_tests
+ comb,od %r0,%r4,comb_tests
+ comb,tr %r0,%r4,comb_tests
+ comb,<> %r0,%r4,comb_tests
+ comb,>= %r0,%r4,comb_tests
+ comb,> %r0,%r4,comb_tests
+ comb,>>= %r0,%r4,comb_tests
+ comb,>> %r0,%r4,comb_tests
+ comb,nsv %r0,%r4,comb_tests
+ comb,ev %r0,%r4,comb_tests
+comb_nullified_tests:
+ comb,n %r0,%r4,comb_tests
+ comb,=,n %r0,%r4,comb_tests
+ comb,<,n %r0,%r4,comb_tests
+ comb,<=,n %r0,%r4,comb_tests
+ comb,<<,n %r0,%r4,comb_tests
+ comb,<<=,n %r0,%r4,comb_tests
+ comb,sv,n %r0,%r4,comb_tests
+ comb,od,n %r0,%r4,comb_tests
+ comb,tr,n %r0,%r4,comb_tests
+ comb,<>,n %r0,%r4,comb_tests
+ comb,>=,n %r0,%r4,comb_tests
+ comb,>,n %r0,%r4,comb_tests
+ comb,>>=,n %r0,%r4,comb_tests
+ comb,>>,n %r0,%r4,comb_tests
+ comb,nsv,n %r0,%r4,comb_tests
+ comb,ev,n %r0,%r4,comb_tests
+
+comib_tests:
+ comib 0,%r4,comib_tests
+ comib,< 0,%r4,comib_tests
+ comib,<= 0,%r4,comib_tests
+ comib,<< 0,%r4,comib_tests
+ comib,<<= 0,%r4,comib_tests
+ comib,sv 0,%r4,comib_tests
+ comib,od 0,%r4,comib_tests
+ comib,tr 0,%r4,comib_tests
+ comib,<> 0,%r4,comib_tests
+ comib,>= 0,%r4,comib_tests
+ comib,> 0,%r4,comib_tests
+ comib,>>= 0,%r4,comib_tests
+ comib,>> 0,%r4,comib_tests
+ comib,nsv 0,%r4,comib_tests
+ comib,ev 0,%r4,comb_tests
+
+comib_nullified_tests:
+ comib,n 0,%r4,comib_tests
+ comib,=,n 0,%r4,comib_tests
+ comib,<,n 0,%r4,comib_tests
+ comib,<=,n 0,%r4,comib_tests
+ comib,<<,n 0,%r4,comib_tests
+ comib,<<=,n 0,%r4,comib_tests
+ comib,sv,n 0,%r4,comib_tests
+ comib,od,n 0,%r4,comib_tests
+ comib,tr,n 0,%r4,comib_tests
+ comib,<>,n 0,%r4,comib_tests
+ comib,>=,n 0,%r4,comib_tests
+ comib,>,n 0,%r4,comib_tests
+ comib,>>=,n 0,%r4,comib_tests
+ comib,>>,n 0,%r4,comib_tests
+ comib,nsv,n 0,%r4,comib_tests
+ comib,ev,n 0,%r4,comib_tests
+
+
+
+addb_tests:
+ addb %r1,%r4,addb_tests
+ addb,= %r1,%r4,addb_tests
+ addb,< %r1,%r4,addb_tests
+ addb,<= %r1,%r4,addb_tests
+ addb,nuv %r1,%r4,addb_tests
+ addb,znv %r1,%r4,addb_tests
+ addb,sv %r1,%r4,addb_tests
+ addb,od %r1,%r4,addb_tests
+ addb,tr %r1,%r4,addb_tests
+ addb,<> %r1,%r4,addb_tests
+ addb,>= %r1,%r4,addb_tests
+ addb,> %r1,%r4,addb_tests
+ addb,uv %r1,%r4,addb_tests
+ addb,vnz %r1,%r4,addb_tests
+ addb,nsv %r1,%r4,addb_tests
+ addb,ev %r1,%r4,addb_tests
+addb_nullified_tests:
+ addb,n %r1,%r4,addb_tests
+ addb,=,n %r1,%r4,addb_tests
+ addb,<,n %r1,%r4,addb_tests
+ addb,<=,n %r1,%r4,addb_tests
+ addb,nuv,n %r1,%r4,addb_tests
+ addb,znv,n %r1,%r4,addb_tests
+ addb,sv,n %r1,%r4,addb_tests
+ addb,od,n %r1,%r4,addb_tests
+ addb,tr,n %r1,%r4,addb_tests
+ addb,<>,n %r1,%r4,addb_tests
+ addb,>=,n %r1,%r4,addb_tests
+ addb,>,n %r1,%r4,addb_tests
+ addb,uv,n %r1,%r4,addb_tests
+ addb,vnz,n %r1,%r4,addb_tests
+ addb,nsv,n %r1,%r4,addb_tests
+ addb,ev,n %r1,%r4,addb_tests
+
+addib_tests:
+ addib -1,%r4,addib_tests
+ addib,= -1,%r4,addib_tests
+ addib,< -1,%r4,addib_tests
+ addib,<= -1,%r4,addib_tests
+ addib,nuv -1,%r4,addib_tests
+ addib,znv -1,%r4,addib_tests
+ addib,sv -1,%r4,addib_tests
+ addib,od -1,%r4,addib_tests
+ addib,tr -1,%r4,addib_tests
+ addib,<> -1,%r4,addib_tests
+ addib,>= -1,%r4,addib_tests
+ addib,> -1,%r4,addib_tests
+ addib,uv -1,%r4,addib_tests
+ addib,vnz -1,%r4,addib_tests
+ addib,nsv -1,%r4,addib_tests
+ addib,ev -1,%r4,comb_tests
+
+addib_nullified_tests:
+ addib,n -1,%r4,addib_tests
+ addib,=,n -1,%r4,addib_tests
+ addib,<,n -1,%r4,addib_tests
+ addib,<=,n -1,%r4,addib_tests
+ addib,nuv,n -1,%r4,addib_tests
+ addib,znv,n -1,%r4,addib_tests
+ addib,sv,n -1,%r4,addib_tests
+ addib,od,n -1,%r4,addib_tests
+ addib,tr,n -1,%r4,addib_tests
+ addib,<>,n -1,%r4,addib_tests
+ addib,>=,n -1,%r4,addib_tests
+ addib,>,n -1,%r4,addib_tests
+ addib,uv,n -1,%r4,addib_tests
+ addib,vnz,n -1,%r4,addib_tests
+ addib,nsv,n -1,%r4,addib_tests
+ addib,ev,n -1,%r4,addib_tests
+
+
+; Needs to check lots of stuff (like corner bit cases)
+bb_tests:
+ bvb,< %r4,bb_tests
+ bvb,>= %r4,bb_tests
+ bvb,<,n %r4,bb_tests
+ bvb,>=,n %r4,bb_tests
+ bb,< %r4,5,bb_tests
+ bb,>= %r4,5,bb_tests
+ bb,<,n %r4,5,bb_tests
+ bb,>=,n %r4,5,bb_tests
+
diff --git a/gas/testsuite/gas/hppa/basic/comclr.s b/gas/testsuite/gas/hppa/basic/comclr.s
new file mode 100644
index 00000000000..a8e5aa6bef8
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/comclr.s
@@ -0,0 +1,50 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ comclr %r4,%r5,%r6
+ comclr,= %r4,%r5,%r6
+ comclr,< %r4,%r5,%r6
+ comclr,<= %r4,%r5,%r6
+ comclr,<< %r4,%r5,%r6
+ comclr,<<= %r4,%r5,%r6
+ comclr,sv %r4,%r5,%r6
+ comclr,od %r4,%r5,%r6
+ comclr,tr %r4,%r5,%r6
+ comclr,<> %r4,%r5,%r6
+ comclr,>= %r4,%r5,%r6
+ comclr,> %r4,%r5,%r6
+ comclr,>>= %r4,%r5,%r6
+ comclr,>> %r4,%r5,%r6
+ comclr,nsv %r4,%r5,%r6
+ comclr,ev %r4,%r5,%r6
+
+ comiclr 123,%r5,%r6
+ comiclr,= 123,%r5,%r6
+ comiclr,< 123,%r5,%r6
+ comiclr,<= 123,%r5,%r6
+ comiclr,<< 123,%r5,%r6
+ comiclr,<<= 123,%r5,%r6
+ comiclr,sv 123,%r5,%r6
+ comiclr,od 123,%r5,%r6
+ comiclr,tr 123,%r5,%r6
+ comiclr,<> 123,%r5,%r6
+ comiclr,>= 123,%r5,%r6
+ comiclr,> 123,%r5,%r6
+ comiclr,>>= 123,%r5,%r6
+ comiclr,>> 123,%r5,%r6
+ comiclr,nsv 123,%r5,%r6
+ comiclr,ev 123,%r5,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/copr.s b/gas/testsuite/gas/hppa/basic/copr.s
new file mode 100644
index 00000000000..77cb6a271fa
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/copr.s
@@ -0,0 +1,19 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+copr_tests:
+ copr,4,5
+ copr,4,115
+ copr,4,5,n
+ copr,4,115,n
diff --git a/gas/testsuite/gas/hppa/basic/coprmem.s b/gas/testsuite/gas/hppa/basic/coprmem.s
new file mode 100644
index 00000000000..7eff1516bd4
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/coprmem.s
@@ -0,0 +1,55 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic copr memory tests which also test the various
+; addressing modes and completers.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+;
+copr_indexing_load
+
+ cldwx,4 %r5(%sr0,%r4),%r26
+ cldwx,4,s %r5(%sr0,%r4),%r26
+ cldwx,4,m %r5(%sr0,%r4),%r26
+ cldwx,4,sm %r5(%sr0,%r4),%r26
+ clddx,4 %r5(%sr0,%r4),%r26
+ clddx,4,s %r5(%sr0,%r4),%r26
+ clddx,4,m %r5(%sr0,%r4),%r26
+ clddx,4,sm %r5(%sr0,%r4),%r26
+
+copr_indexing_store
+ cstwx,4 %r26,%r5(%sr0,%r4)
+ cstwx,4,s %r26,%r5(%sr0,%r4)
+ cstwx,4,m %r26,%r5(%sr0,%r4)
+ cstwx,4,sm %r26,%r5(%sr0,%r4)
+ cstdx,4 %r26,%r5(%sr0,%r4)
+ cstdx,4,s %r26,%r5(%sr0,%r4)
+ cstdx,4,m %r26,%r5(%sr0,%r4)
+ cstdx,4,sm %r26,%r5(%sr0,%r4)
+
+copr_short_memory
+ cldws,4 0(%sr0,%r4),%r26
+ cldws,4,mb 0(%sr0,%r4),%r26
+ cldws,4,ma 0(%sr0,%r4),%r26
+ cldds,4 0(%sr0,%r4),%r26
+ cldds,4,mb 0(%sr0,%r4),%r26
+ cldds,4,ma 0(%sr0,%r4),%r26
+ cstws,4 %r26,0(%sr0,%r4)
+ cstws,4,mb %r26,0(%sr0,%r4)
+ cstws,4,ma %r26,0(%sr0,%r4)
+ cstds,4 %r26,0(%sr0,%r4)
+ cstds,4,mb %r26,0(%sr0,%r4)
+ cstds,4,ma %r26,0(%sr0,%r4)
+
+; gas fucks this up thinks it gets the expression 4 modulo 5
+; cldwx,4 %r5(0,%r4),%r%r26
diff --git a/gas/testsuite/gas/hppa/basic/dcor.s b/gas/testsuite/gas/hppa/basic/dcor.s
new file mode 100644
index 00000000000..84745548139
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/dcor.s
@@ -0,0 +1,41 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ dcor %r4,%r5
+ dcor,sbz %r4,%r5
+ dcor,shz %r4,%r5
+ dcor,sdc %r4,%r5
+ dcor,sbc %r4,%r5
+ dcor,shc %r4,%r5
+ dcor,tr %r4,%r5
+ dcor,nbz %r4,%r5
+ dcor,nhz %r4,%r5
+ dcor,ndc %r4,%r5
+ dcor,nbc %r4,%r5
+ dcor,nhc %r4,%r5
+
+ idcor %r4,%r5
+ idcor,sbz %r4,%r5
+ idcor,shz %r4,%r5
+ idcor,sdc %r4,%r5
+ idcor,sbc %r4,%r5
+ idcor,shc %r4,%r5
+ idcor,tr %r4,%r5
+ idcor,nbz %r4,%r5
+ idcor,nhz %r4,%r5
+ idcor,ndc %r4,%r5
+ idcor,nbc %r4,%r5
+ idcor,nhc %r4,%r5
diff --git a/gas/testsuite/gas/hppa/basic/deposit.s b/gas/testsuite/gas/hppa/basic/deposit.s
new file mode 100644
index 00000000000..70853b36992
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/deposit.s
@@ -0,0 +1,88 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ zdep %r4,5,10,%r6
+ zdep,= %r4,5,10,%r6
+ zdep,< %r4,5,10,%r6
+ zdep,od %r4,5,10,%r6
+ zdep,tr %r4,5,10,%r6
+ zdep,<> %r4,5,10,%r6
+ zdep,>= %r4,5,10,%r6
+ zdep,ev %r4,5,10,%r6
+
+ dep %r4,5,10,%r6
+ dep,= %r4,5,10,%r6
+ dep,< %r4,5,10,%r6
+ dep,od %r4,5,10,%r6
+ dep,tr %r4,5,10,%r6
+ dep,<> %r4,5,10,%r6
+ dep,>= %r4,5,10,%r6
+ dep,ev %r4,5,10,%r6
+
+ zvdep %r4,5,%r6
+ zvdep,= %r4,5,%r6
+ zvdep,< %r4,5,%r6
+ zvdep,od %r4,5,%r6
+ zvdep,tr %r4,5,%r6
+ zvdep,<> %r4,5,%r6
+ zvdep,>= %r4,5,%r6
+ zvdep,ev %r4,5,%r6
+
+ vdep %r4,5,%r6
+ vdep,= %r4,5,%r6
+ vdep,< %r4,5,%r6
+ vdep,od %r4,5,%r6
+ vdep,tr %r4,5,%r6
+ vdep,<> %r4,5,%r6
+ vdep,>= %r4,5,%r6
+ vdep,ev %r4,5,%r6
+
+ vdepi -1,5,%r6
+ vdepi,= -1,5,%r6
+ vdepi,< -1,5,%r6
+ vdepi,od -1,5,%r6
+ vdepi,tr -1,5,%r6
+ vdepi,<> -1,5,%r6
+ vdepi,>= -1,5,%r6
+ vdepi,ev -1,5,%r6
+
+ zvdepi -1,5,%r6
+ zvdepi,= -1,5,%r6
+ zvdepi,< -1,5,%r6
+ zvdepi,od -1,5,%r6
+ zvdepi,tr -1,5,%r6
+ zvdepi,<> -1,5,%r6
+ zvdepi,>= -1,5,%r6
+ zvdepi,ev -1,5,%r6
+
+ depi -1,4,10,%r6
+ depi,= -1,4,10,%r6
+ depi,< -1,4,10,%r6
+ depi,od -1,4,10,%r6
+ depi,tr -1,4,10,%r6
+ depi,<> -1,4,10,%r6
+ depi,>= -1,4,10,%r6
+ depi,ev -1,4,10,%r6
+
+ zdepi -1,4,10,%r6
+ zdepi,= -1,4,10,%r6
+ zdepi,< -1,4,10,%r6
+ zdepi,od -1,4,10,%r6
+ zdepi,tr -1,4,10,%r6
+ zdepi,<> -1,4,10,%r6
+ zdepi,>= -1,4,10,%r6
+ zdepi,ev -1,4,10,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/ds.s b/gas/testsuite/gas/hppa/basic/ds.s
new file mode 100644
index 00000000000..5831e2618ea
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/ds.s
@@ -0,0 +1,32 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ ds %r4,%r5,%r6
+ ds,= %r4,%r5,%r6
+ ds,< %r4,%r5,%r6
+ ds,<= %r4,%r5,%r6
+ ds,<< %r4,%r5,%r6
+ ds,<<= %r4,%r5,%r6
+ ds,sv %r4,%r5,%r6
+ ds,od %r4,%r5,%r6
+ ds,tr %r4,%r5,%r6
+ ds,<> %r4,%r5,%r6
+ ds,>= %r4,%r5,%r6
+ ds,> %r4,%r5,%r6
+ ds,>>= %r4,%r5,%r6
+ ds,>> %r4,%r5,%r6
+ ds,nsv %r4,%r5,%r6
+ ds,ev %r4,%r5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/extract.s b/gas/testsuite/gas/hppa/basic/extract.s
new file mode 100644
index 00000000000..29030f4d489
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/extract.s
@@ -0,0 +1,51 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ extru %r4,5,10,%r6
+ extru,= %r4,5,10,%r6
+ extru,< %r4,5,10,%r6
+ extru,od %r4,5,10,%r6
+ extru,tr %r4,5,10,%r6
+ extru,<> %r4,5,10,%r6
+ extru,>= %r4,5,10,%r6
+ extru,ev %r4,5,10,%r6
+
+ extrs %r4,5,10,%r6
+ extrs,= %r4,5,10,%r6
+ extrs,< %r4,5,10,%r6
+ extrs,od %r4,5,10,%r6
+ extrs,tr %r4,5,10,%r6
+ extrs,<> %r4,5,10,%r6
+ extrs,>= %r4,5,10,%r6
+ extrs,ev %r4,5,10,%r6
+
+ vextru %r4,5,%r6
+ vextru,= %r4,5,%r6
+ vextru,< %r4,5,%r6
+ vextru,od %r4,5,%r6
+ vextru,tr %r4,5,%r6
+ vextru,<> %r4,5,%r6
+ vextru,>= %r4,5,%r6
+ vextru,ev %r4,5,%r6
+
+ vextrs %r4,5,%r6
+ vextrs,= %r4,5,%r6
+ vextrs,< %r4,5,%r6
+ vextrs,od %r4,5,%r6
+ vextrs,tr %r4,5,%r6
+ vextrs,<> %r4,5,%r6
+ vextrs,>= %r4,5,%r6
+ vextrs,ev %r4,5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/fmem.s b/gas/testsuite/gas/hppa/basic/fmem.s
new file mode 100644
index 00000000000..b730b40011c
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/fmem.s
@@ -0,0 +1,52 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ fldwx %r4(%sr0,%r5),%fr6
+ fldwx,s %r4(%sr0,%r5),%fr6
+ fldwx,m %r4(%sr0,%r5),%fr6
+ fldwx,sm %r4(%sr0,%r5),%fr6
+ flddx %r4(%sr0,%r5),%fr6
+ flddx,s %r4(%sr0,%r5),%fr6
+ flddx,m %r4(%sr0,%r5),%fr6
+ flddx,sm %r4(%sr0,%r5),%fr6
+ fstwx %fr6,%r4(%sr0,%r5)
+ fstwx,s %fr6,%r4(%sr0,%r5)
+ fstwx,m %fr6,%r4(%sr0,%r5)
+ fstwx,sm %fr6,%r4(%sr0,%r5)
+ fstdx %fr6,%r4(%sr0,%r5)
+ fstdx,s %fr6,%r4(%sr0,%r5)
+ fstdx,m %fr6,%r4(%sr0,%r5)
+ fstdx,sm %fr6,%r4(%sr0,%r5)
+ fstqx %fr6,%r4(%sr0,%r5)
+ fstqx,s %fr6,%r4(%sr0,%r5)
+ fstqx,m %fr6,%r4(%sr0,%r5)
+ fstqx,sm %fr6,%r4(%sr0,%r5)
+
+ fldws 0(%sr0,%r5),%fr6
+ fldws,mb 0(%sr0,%r5),%fr6
+ fldws,ma 0(%sr0,%r5),%fr6
+ fldds 0(%sr0,%r5),%fr6
+ fldds,mb 0(%sr0,%r5),%fr6
+ fldds,ma 0(%sr0,%r5),%fr6
+ fstws %fr6,0(%sr0,%r5)
+ fstws,mb %fr6,0(%sr0,%r5)
+ fstws,ma %fr6,0(%sr0,%r5)
+ fstds %fr6,0(%sr0,%r5)
+ fstds,mb %fr6,0(%sr0,%r5)
+ fstds,ma %fr6,0(%sr0,%r5)
+ fstqs %fr6,0(%sr0,%r5)
+ fstqs,mb %fr6,0(%sr0,%r5)
+ fstqs,ma %fr6,0(%sr0,%r5)
diff --git a/gas/testsuite/gas/hppa/basic/fmemLRbug.s b/gas/testsuite/gas/hppa/basic/fmemLRbug.s
new file mode 100644
index 00000000000..f1330bb628e
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/fmemLRbug.s
@@ -0,0 +1,76 @@
+ .code
+ .export f
+f
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ fstws %fr6R,0(%r26)
+ fstws %fr6L,4(%r26)
+ fstws %fr6,8(%r26)
+
+ fstds %fr6R,0(%r26)
+ fstds %fr6L,4(%r26)
+ fstds %fr6,8(%r26)
+
+ fldws 0(%r26),%fr6R
+ fldws 4(%r26),%fr6L
+ fldws 8(%r26),%fr6
+
+ fldds 0(%r26),%fr6R
+ fldds 4(%r26),%fr6L
+ fldds 8(%r26),%fr6
+
+ fstws %fr6R,0(%sr0,%r26)
+ fstws %fr6L,4(%sr0,%r26)
+ fstws %fr6,8(%sr0,%r26)
+
+ fstds %fr6R,0(%sr0,%r26)
+ fstds %fr6L,4(%sr0,%r26)
+ fstds %fr6,8(%sr0,%r26)
+
+ fldws 0(%sr0,%r26),%fr6R
+ fldws 4(%sr0,%r26),%fr6L
+ fldws 8(%sr0,%r26),%fr6
+
+ fldds 0(%sr0,%r26),%fr6R
+ fldds 4(%sr0,%r26),%fr6L
+ fldds 8(%sr0,%r26),%fr6
+
+ fstwx %fr6R,%r25(%r26)
+ fstwx %fr6L,%r25(%r26)
+ fstwx %fr6,%r25(%r26)
+
+ fstdx %fr6R,%r25(%r26)
+ fstdx %fr6L,%r25(%r26)
+ fstdx %fr6,%r25(%r26)
+
+ fldwx %r25(%r26),%fr6R
+ fldwx %r25(%r26),%fr6L
+ fldwx %r25(%r26),%fr6
+
+ flddx %r25(%r26),%fr6R
+ flddx %r25(%r26),%fr6L
+ flddx %r25(%r26),%fr6
+
+ fstwx %fr6R,%r25(%sr0,%r26)
+ fstwx %fr6L,%r25(%sr0,%r26)
+ fstwx %fr6,%r25(%sr0,%r26)
+
+ fstdx %fr6R,%r25(%sr0,%r26)
+ fstdx %fr6L,%r25(%sr0,%r26)
+ fstdx %fr6,%r25(%sr0,%r26)
+
+ fldwx %r25(%sr0,%r26),%fr6R
+ fldwx %r25(%sr0,%r26),%fr6L
+ fldwx %r25(%sr0,%r26),%fr6
+
+ flddx %r25(%sr0,%r26),%fr6R
+ flddx %r25(%sr0,%r26),%fr6L
+ flddx %r25(%sr0,%r26),%fr6
+
+ bv %r0(%r2)
+ nop
+
+ .exit
+ .procend
diff --git a/gas/testsuite/gas/hppa/basic/fp_comp.s b/gas/testsuite/gas/hppa/basic/fp_comp.s
new file mode 100644
index 00000000000..c1017f7db95
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/fp_comp.s
@@ -0,0 +1,81 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ fcpy,sgl %fr5,%fr10
+ fcpy,dbl %fr5,%fr10
+ fcpy,quad %fr5,%fr10
+ fcpy,sgl %fr20,%fr24
+ fcpy,dbl %fr20,%fr24
+
+ fabs,sgl %fr5,%fr10
+ fabs,dbl %fr5,%fr10
+ fabs,quad %fr5,%fr10
+ fabs,sgl %fr20,%fr24
+ fabs,dbl %fr20,%fr24
+
+ fsqrt,sgl %fr5,%fr10
+ fsqrt,dbl %fr5,%fr10
+ fsqrt,quad %fr5,%fr10
+ fsqrt,sgl %fr20,%fr24
+ fsqrt,dbl %fr20,%fr24
+
+ frnd,sgl %fr5,%fr10
+ frnd,dbl %fr5,%fr10
+ frnd,quad %fr5,%fr10
+ frnd,sgl %fr20,%fr24
+ frnd,dbl %fr20,%fr24
+
+ fadd,sgl %fr4,%fr8,%fr12
+ fadd,dbl %fr4,%fr8,%fr12
+ fadd,quad %fr4,%fr8,%fr12
+ fadd,sgl %fr20,%fr24,%fr28
+ fadd,dbl %fr20,%fr24,%fr28
+ fadd,quad %fr20,%fr24,%fr28
+
+ fsub,sgl %fr4,%fr8,%fr12
+ fsub,dbl %fr4,%fr8,%fr12
+ fsub,quad %fr4,%fr8,%fr12
+ fsub,sgl %fr20,%fr24,%fr28
+ fsub,dbl %fr20,%fr24,%fr28
+ fsub,quad %fr20,%fr24,%fr28
+
+ fmpy,sgl %fr4,%fr8,%fr12
+ fmpy,dbl %fr4,%fr8,%fr12
+ fmpy,quad %fr4,%fr8,%fr12
+ fmpy,sgl %fr20,%fr24,%fr28
+ fmpy,dbl %fr20,%fr24,%fr28
+ fmpy,quad %fr20,%fr24,%fr28
+
+ fdiv,sgl %fr4,%fr8,%fr12
+ fdiv,dbl %fr4,%fr8,%fr12
+ fdiv,quad %fr4,%fr8,%fr12
+ fdiv,sgl %fr20,%fr24,%fr28
+ fdiv,dbl %fr20,%fr24,%fr28
+ fdiv,quad %fr20,%fr24,%fr28
+
+ frem,sgl %fr4,%fr8,%fr12
+ frem,dbl %fr4,%fr8,%fr12
+ frem,quad %fr4,%fr8,%fr12
+ frem,sgl %fr20,%fr24,%fr28
+ frem,dbl %fr20,%fr24,%fr28
+ frem,quad %fr20,%fr24,%fr28
+
+ fmpyadd,sgl %fr16,%fr17,%fr18,%fr19,%fr20
+ fmpyadd,dbl %fr16,%fr17,%fr18,%fr19,%fr20
+ fmpysub,sgl %fr16,%fr17,%fr18,%fr19,%fr20
+ fmpysub,dbl %fr16,%fr17,%fr18,%fr19,%fr20
+
+ xmpyu %fr4,%fr5,%fr6
diff --git a/gas/testsuite/gas/hppa/basic/fp_conv.s b/gas/testsuite/gas/hppa/basic/fp_conv.s
new file mode 100644
index 00000000000..5a44cb1637b
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/fp_conv.s
@@ -0,0 +1,92 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ fcnvff,sgl,sgl %fr5,%fr10
+ fcnvff,sgl,dbl %fr5,%fr10
+ fcnvff,sgl,quad %fr5,%fr10
+ fcnvff,dbl,sgl %fr5,%fr10
+ fcnvff,dbl,dbl %fr5,%fr10
+ fcnvff,dbl,quad %fr5,%fr10
+ fcnvff,quad,sgl %fr5,%fr10
+ fcnvff,quad,dbl %fr5,%fr10
+ fcnvff,quad,quad %fr5,%fr10
+ fcnvff,sgl,sgl %fr20,%fr24
+ fcnvff,sgl,dbl %fr20,%fr24
+ fcnvff,sgl,quad %fr20,%fr24
+ fcnvff,dbl,sgl %fr20,%fr24
+ fcnvff,dbl,dbl %fr20,%fr24
+ fcnvff,dbl,quad %fr20,%fr24
+ fcnvff,quad,sgl %fr20,%fr24
+ fcnvff,quad,dbl %fr20,%fr24
+ fcnvff,quad,quad %fr20,%fr24
+
+ fcnvxf,sgl,sgl %fr5,%fr10
+ fcnvxf,sgl,dbl %fr5,%fr10
+ fcnvxf,sgl,quad %fr5,%fr10
+ fcnvxf,dbl,sgl %fr5,%fr10
+ fcnvxf,dbl,dbl %fr5,%fr10
+ fcnvxf,dbl,quad %fr5,%fr10
+ fcnvxf,quad,sgl %fr5,%fr10
+ fcnvxf,quad,dbl %fr5,%fr10
+ fcnvxf,quad,quad %fr5,%fr10
+ fcnvxf,sgl,sgl %fr20,%fr24
+ fcnvxf,sgl,dbl %fr20,%fr24
+ fcnvxf,sgl,quad %fr20,%fr24
+ fcnvxf,dbl,sgl %fr20,%fr24
+ fcnvxf,dbl,dbl %fr20,%fr24
+ fcnvxf,dbl,quad %fr20,%fr24
+ fcnvxf,quad,sgl %fr20,%fr24
+ fcnvxf,quad,dbl %fr20,%fr24
+ fcnvxf,quad,quad %fr20,%fr24
+
+ fcnvfx,sgl,sgl %fr5,%fr10
+ fcnvfx,sgl,dbl %fr5,%fr10
+ fcnvfx,sgl,quad %fr5,%fr10
+ fcnvfx,dbl,sgl %fr5,%fr10
+ fcnvfx,dbl,dbl %fr5,%fr10
+ fcnvfx,dbl,quad %fr5,%fr10
+ fcnvfx,quad,sgl %fr5,%fr10
+ fcnvfx,quad,dbl %fr5,%fr10
+ fcnvfx,quad,quad %fr5,%fr10
+ fcnvfx,sgl,sgl %fr20,%fr24
+ fcnvfx,sgl,dbl %fr20,%fr24
+ fcnvfx,sgl,quad %fr20,%fr24
+ fcnvfx,dbl,sgl %fr20,%fr24
+ fcnvfx,dbl,dbl %fr20,%fr24
+ fcnvfx,dbl,quad %fr20,%fr24
+ fcnvfx,quad,sgl %fr20,%fr24
+ fcnvfx,quad,dbl %fr20,%fr24
+ fcnvfx,quad,quad %fr20,%fr24
+
+ fcnvfxt,sgl,sgl %fr5,%fr10
+ fcnvfxt,sgl,dbl %fr5,%fr10
+ fcnvfxt,sgl,quad %fr5,%fr10
+ fcnvfxt,dbl,sgl %fr5,%fr10
+ fcnvfxt,dbl,dbl %fr5,%fr10
+ fcnvfxt,dbl,quad %fr5,%fr10
+ fcnvfxt,quad,sgl %fr5,%fr10
+ fcnvfxt,quad,dbl %fr5,%fr10
+ fcnvfxt,quad,quad %fr5,%fr10
+ fcnvfxt,sgl,sgl %fr20,%fr24
+ fcnvfxt,sgl,dbl %fr20,%fr24
+ fcnvfxt,sgl,quad %fr20,%fr24
+ fcnvfxt,dbl,sgl %fr20,%fr24
+ fcnvfxt,dbl,dbl %fr20,%fr24
+ fcnvfxt,dbl,quad %fr20,%fr24
+ fcnvfxt,quad,sgl %fr20,%fr24
+ fcnvfxt,quad,dbl %fr20,%fr24
+ fcnvfxt,quad,quad %fr20,%fr24
+
diff --git a/gas/testsuite/gas/hppa/basic/fp_fcmp.s b/gas/testsuite/gas/hppa/basic/fp_fcmp.s
new file mode 100644
index 00000000000..fbd092c1a70
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/fp_fcmp.s
@@ -0,0 +1,114 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ fcmp,sgl,false? %fr4,%fr5
+ fcmp,sgl,false %fr4,%fr5
+ fcmp,sgl,? %fr4,%fr5
+ fcmp,sgl,!<=> %fr4,%fr5
+ fcmp,sgl,= %fr4,%fr5
+ fcmp,sgl,=T %fr4,%fr5
+ fcmp,sgl,?= %fr4,%fr5
+ fcmp,sgl,!<> %fr4,%fr5
+ fcmp,sgl,!?>= %fr4,%fr5
+ fcmp,sgl,< %fr4,%fr5
+ fcmp,sgl,?< %fr4,%fr5
+ fcmp,sgl,!>= %fr4,%fr5
+ fcmp,sgl,!?> %fr4,%fr5
+ fcmp,sgl,<= %fr4,%fr5
+ fcmp,sgl,?<= %fr4,%fr5
+ fcmp,sgl,!> %fr4,%fr5
+ fcmp,sgl,!?<= %fr4,%fr5
+ fcmp,sgl,> %fr4,%fr5
+ fcmp,sgl,?> %fr4,%fr5
+ fcmp,sgl,!<= %fr4,%fr5
+ fcmp,sgl,!?< %fr4,%fr5
+ fcmp,sgl,>= %fr4,%fr5
+ fcmp,sgl,?>= %fr4,%fr5
+ fcmp,sgl,!< %fr4,%fr5
+ fcmp,sgl,!?= %fr4,%fr5
+ fcmp,sgl,<> %fr4,%fr5
+ fcmp,sgl,!= %fr4,%fr5
+ fcmp,sgl,!=T %fr4,%fr5
+ fcmp,sgl,!? %fr4,%fr5
+ fcmp,sgl,<=> %fr4,%fr5
+ fcmp,sgl,true? %fr4,%fr5
+ fcmp,sgl,true %fr4,%fr5
+
+ fcmp,dbl,false? %fr4,%fr5
+ fcmp,dbl,false %fr4,%fr5
+ fcmp,dbl,? %fr4,%fr5
+ fcmp,dbl,!<=> %fr4,%fr5
+ fcmp,dbl,= %fr4,%fr5
+ fcmp,dbl,=T %fr4,%fr5
+ fcmp,dbl,?= %fr4,%fr5
+ fcmp,dbl,!<> %fr4,%fr5
+ fcmp,dbl,!?>= %fr4,%fr5
+ fcmp,dbl,< %fr4,%fr5
+ fcmp,dbl,?< %fr4,%fr5
+ fcmp,dbl,!>= %fr4,%fr5
+ fcmp,dbl,!?> %fr4,%fr5
+ fcmp,dbl,<= %fr4,%fr5
+ fcmp,dbl,?<= %fr4,%fr5
+ fcmp,dbl,!> %fr4,%fr5
+ fcmp,dbl,!?<= %fr4,%fr5
+ fcmp,dbl,> %fr4,%fr5
+ fcmp,dbl,?> %fr4,%fr5
+ fcmp,dbl,!<= %fr4,%fr5
+ fcmp,dbl,!?< %fr4,%fr5
+ fcmp,dbl,>= %fr4,%fr5
+ fcmp,dbl,?>= %fr4,%fr5
+ fcmp,dbl,!< %fr4,%fr5
+ fcmp,dbl,!?= %fr4,%fr5
+ fcmp,dbl,<> %fr4,%fr5
+ fcmp,dbl,!= %fr4,%fr5
+ fcmp,dbl,!=T %fr4,%fr5
+ fcmp,dbl,!? %fr4,%fr5
+ fcmp,dbl,<=> %fr4,%fr5
+ fcmp,dbl,true? %fr4,%fr5
+ fcmp,dbl,true %fr4,%fr5
+
+ fcmp,quad,false? %fr4,%fr5
+ fcmp,quad,false %fr4,%fr5
+ fcmp,quad,? %fr4,%fr5
+ fcmp,quad,!<=> %fr4,%fr5
+ fcmp,quad,= %fr4,%fr5
+ fcmp,quad,=T %fr4,%fr5
+ fcmp,quad,?= %fr4,%fr5
+ fcmp,quad,!<> %fr4,%fr5
+ fcmp,quad,!?>= %fr4,%fr5
+ fcmp,quad,< %fr4,%fr5
+ fcmp,quad,?< %fr4,%fr5
+ fcmp,quad,!>= %fr4,%fr5
+ fcmp,quad,!?> %fr4,%fr5
+ fcmp,quad,<= %fr4,%fr5
+ fcmp,quad,?<= %fr4,%fr5
+ fcmp,quad,!> %fr4,%fr5
+ fcmp,quad,!?<= %fr4,%fr5
+ fcmp,quad,> %fr4,%fr5
+ fcmp,quad,?> %fr4,%fr5
+ fcmp,quad,!<= %fr4,%fr5
+ fcmp,quad,!?< %fr4,%fr5
+ fcmp,quad,>= %fr4,%fr5
+ fcmp,quad,?>= %fr4,%fr5
+ fcmp,quad,!< %fr4,%fr5
+ fcmp,quad,!?= %fr4,%fr5
+ fcmp,quad,<> %fr4,%fr5
+ fcmp,quad,!= %fr4,%fr5
+ fcmp,quad,!=T %fr4,%fr5
+ fcmp,quad,!? %fr4,%fr5
+ fcmp,quad,<=> %fr4,%fr5
+ fcmp,quad,true? %fr4,%fr5
+ fcmp,quad,true %fr4,%fr5
diff --git a/gas/testsuite/gas/hppa/basic/fp_misc.s b/gas/testsuite/gas/hppa/basic/fp_misc.s
new file mode 100644
index 00000000000..356ac044883
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/fp_misc.s
@@ -0,0 +1,18 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+fpu_misc_tests:
+ ftest
diff --git a/gas/testsuite/gas/hppa/basic/imem.s b/gas/testsuite/gas/hppa/basic/imem.s
new file mode 100644
index 00000000000..3c49c121d14
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/imem.s
@@ -0,0 +1,93 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT integer_memory_tests,CODE
+ .EXPORT integer_indexing_load,CODE
+ .EXPORT integer_load_short_memory,CODE
+ .EXPORT integer_store_short_memory,CODE
+ .EXPORT main,CODE
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+; Basic integer memory tests which also test the various
+; addressing modes and completers.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+;
+integer_memory_tests:
+ ldw 0(%sr0,%r4),%r26
+ ldh 0(%sr0,%r4),%r26
+ ldb 0(%sr0,%r4),%r26
+ stw %r26,0(%sr0,%r4)
+ sth %r26,0(%sr0,%r4)
+ stb %r26,0(%sr0,%r4)
+
+; Should make sure pre/post modes are recognized correctly.
+ ldwm 0(%sr0,%r4),%r26
+ stwm %r26,0(%sr0,%r4)
+
+integer_indexing_load:
+ ldwx %r5(%sr0,%r4),%r26
+ ldwx,s %r5(%sr0,%r4),%r26
+ ldwx,m %r5(%sr0,%r4),%r26
+ ldwx,sm %r5(%sr0,%r4),%r26
+ ldhx %r5(%sr0,%r4),%r26
+ ldhx,s %r5(%sr0,%r4),%r26
+ ldhx,m %r5(%sr0,%r4),%r26
+ ldhx,sm %r5(%sr0,%r4),%r26
+ ldbx %r5(%sr0,%r4),%r26
+ ldbx,s %r5(%sr0,%r4),%r26
+ ldbx,m %r5(%sr0,%r4),%r26
+ ldbx,sm %r5(%sr0,%r4),%r26
+ ldwax %r5(%r4),%r26
+ ldwax,s %r5(%r4),%r26
+ ldwax,m %r5(%r4),%r26
+ ldwax,sm %r5(%r4),%r26
+ ldcwx %r5(%sr0,%r4),%r26
+ ldcwx,s %r5(%sr0,%r4),%r26
+ ldcwx,m %r5(%sr0,%r4),%r26
+ ldcwx,sm %r5(%sr0,%r4),%r26
+
+integer_load_short_memory:
+ ldws 0(%sr0,%r4),%r26
+ ldws,mb 0(%sr0,%r4),%r26
+ ldws,ma 0(%sr0,%r4),%r26
+ ldhs 0(%sr0,%r4),%r26
+ ldhs,mb 0(%sr0,%r4),%r26
+ ldhs,ma 0(%sr0,%r4),%r26
+ ldbs 0(%sr0,%r4),%r26
+ ldbs,mb 0(%sr0,%r4),%r26
+ ldbs,ma 0(%sr0,%r4),%r26
+ ldwas 0(%r4),%r26
+ ldwas,mb 0(%r4),%r26
+ ldwas,ma 0(%r4),%r26
+ ldcws 0(%sr0,%r4),%r26
+ ldcws,mb 0(%sr0,%r4),%r26
+ ldcws,ma 0(%sr0,%r4),%r26
+
+integer_store_short_memory:
+ stws %r26,0(%sr0,%r4)
+ stws,mb %r26,0(%sr0,%r4)
+ stws,ma %r26,0(%sr0,%r4)
+ sths %r26,0(%sr0,%r4)
+ sths,mb %r26,0(%sr0,%r4)
+ sths,ma %r26,0(%sr0,%r4)
+ stbs %r26,0(%sr0,%r4)
+ stbs,mb %r26,0(%sr0,%r4)
+ stbs,ma %r26,0(%sr0,%r4)
+ stwas %r26,0(%r4)
+ stwas,mb %r26,0(%r4)
+ stwas,ma %r26,0(%r4)
+ stbys %r26,0(%sr0,%r4)
+ stbys,b %r26,0(%sr0,%r4)
+ stbys,e %r26,0(%sr0,%r4)
+ stbys,b,m %r26,0(%sr0,%r4)
+ stbys,e,m %r26,0(%sr0,%r4)
diff --git a/gas/testsuite/gas/hppa/basic/immed.s b/gas/testsuite/gas/hppa/basic/immed.s
new file mode 100644
index 00000000000..dd27d2fe03a
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/immed.s
@@ -0,0 +1,21 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+immediate_tests:
+ ldo 5(%r26),%r26
+ ldil L%0xdeadbeef,%r26
+ addil L%0xdeadbeef,%r5
+
diff --git a/gas/testsuite/gas/hppa/basic/logical.s b/gas/testsuite/gas/hppa/basic/logical.s
new file mode 100644
index 00000000000..771059ed0b8
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/logical.s
@@ -0,0 +1,60 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ or %r4,%r5,%r6
+ or,= %r4,%r5,%r6
+ or,< %r4,%r5,%r6
+ or,<= %r4,%r5,%r6
+ or,od %r4,%r5,%r6
+ or,tr %r4,%r5,%r6
+ or,<> %r4,%r5,%r6
+ or,>= %r4,%r5,%r6
+ or,> %r4,%r5,%r6
+ or,ev %r4,%r5,%r6
+
+ xor %r4,%r5,%r6
+ xor,= %r4,%r5,%r6
+ xor,< %r4,%r5,%r6
+ xor,<= %r4,%r5,%r6
+ xor,od %r4,%r5,%r6
+ xor,tr %r4,%r5,%r6
+ xor,<> %r4,%r5,%r6
+ xor,>= %r4,%r5,%r6
+ xor,> %r4,%r5,%r6
+ xor,ev %r4,%r5,%r6
+
+ and %r4,%r5,%r6
+ and,= %r4,%r5,%r6
+ and,< %r4,%r5,%r6
+ and,<= %r4,%r5,%r6
+ and,od %r4,%r5,%r6
+ and,tr %r4,%r5,%r6
+ and,<> %r4,%r5,%r6
+ and,>= %r4,%r5,%r6
+ and,> %r4,%r5,%r6
+ and,ev %r4,%r5,%r6
+
+ andcm %r4,%r5,%r6
+ andcm,= %r4,%r5,%r6
+ andcm,< %r4,%r5,%r6
+ andcm,<= %r4,%r5,%r6
+ andcm,od %r4,%r5,%r6
+ andcm,tr %r4,%r5,%r6
+ andcm,<> %r4,%r5,%r6
+ andcm,>= %r4,%r5,%r6
+ andcm,> %r4,%r5,%r6
+ andcm,ev %r4,%r5,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/purge.s b/gas/testsuite/gas/hppa/basic/purge.s
new file mode 100644
index 00000000000..2319f90839e
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/purge.s
@@ -0,0 +1,35 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ pdtlb %r4(%sr0,%r5)
+ pdtlb,m %r4(%sr0,%r5)
+ pitlb %r4(%sr4,%r5)
+ pitlb,m %r4(%sr4,%r5)
+ pdtlbe %r4(%sr0,%r5)
+ pdtlbe,m %r4(%sr0,%r5)
+ pitlbe %r4(%sr4,%r5)
+ pitlbe,m %r4(%sr4,%r5)
+ pdc %r4(%sr0,%r5)
+ pdc,m %r4(%sr0,%r5)
+ fdc %r4(%sr0,%r5)
+ fdc,m %r4(%sr0,%r5)
+ fic %r4(%sr4,%r5)
+ fic,m %r4(%sr4,%r5)
+ fdce %r4(%sr0,%r5)
+ fdce,m %r4(%sr0,%r5)
+ fice %r4(%sr4,%r5)
+ fice,m %r4(%sr4,%r5)
+
diff --git a/gas/testsuite/gas/hppa/basic/sh1add.s b/gas/testsuite/gas/hppa/basic/sh1add.s
new file mode 100644
index 00000000000..325d6cc129b
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/sh1add.s
@@ -0,0 +1,67 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ sh1add %r4,%r5,%r6
+ sh1add,= %r4,%r5,%r6
+ sh1add,< %r4,%r5,%r6
+ sh1add,<= %r4,%r5,%r6
+ sh1add,nuv %r4,%r5,%r6
+ sh1add,znv %r4,%r5,%r6
+ sh1add,sv %r4,%r5,%r6
+ sh1add,od %r4,%r5,%r6
+ sh1add,tr %r4,%r5,%r6
+ sh1add,<> %r4,%r5,%r6
+ sh1add,>= %r4,%r5,%r6
+ sh1add,> %r4,%r5,%r6
+ sh1add,uv %r4,%r5,%r6
+ sh1add,vnz %r4,%r5,%r6
+ sh1add,nsv %r4,%r5,%r6
+ sh1add,ev %r4,%r5,%r6
+
+ sh1addl %r4,%r5,%r6
+ sh1addl,= %r4,%r5,%r6
+ sh1addl,< %r4,%r5,%r6
+ sh1addl,<= %r4,%r5,%r6
+ sh1addl,nuv %r4,%r5,%r6
+ sh1addl,znv %r4,%r5,%r6
+ sh1addl,sv %r4,%r5,%r6
+ sh1addl,od %r4,%r5,%r6
+ sh1addl,tr %r4,%r5,%r6
+ sh1addl,<> %r4,%r5,%r6
+ sh1addl,>= %r4,%r5,%r6
+ sh1addl,> %r4,%r5,%r6
+ sh1addl,uv %r4,%r5,%r6
+ sh1addl,vnz %r4,%r5,%r6
+ sh1addl,nsv %r4,%r5,%r6
+ sh1addl,ev %r4,%r5,%r6
+
+ sh1addo %r4,%r5,%r6
+ sh1addo,= %r4,%r5,%r6
+ sh1addo,< %r4,%r5,%r6
+ sh1addo,<= %r4,%r5,%r6
+ sh1addo,nuv %r4,%r5,%r6
+ sh1addo,znv %r4,%r5,%r6
+ sh1addo,sv %r4,%r5,%r6
+ sh1addo,od %r4,%r5,%r6
+ sh1addo,tr %r4,%r5,%r6
+ sh1addo,<> %r4,%r5,%r6
+ sh1addo,>= %r4,%r5,%r6
+ sh1addo,> %r4,%r5,%r6
+ sh1addo,uv %r4,%r5,%r6
+ sh1addo,vnz %r4,%r5,%r6
+ sh1addo,nsv %r4,%r5,%r6
+ sh1addo,ev %r4,%r5,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/sh2add.s b/gas/testsuite/gas/hppa/basic/sh2add.s
new file mode 100644
index 00000000000..d19c99b77d4
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/sh2add.s
@@ -0,0 +1,67 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ sh2add %r4,%r5,%r6
+ sh2add,= %r4,%r5,%r6
+ sh2add,< %r4,%r5,%r6
+ sh2add,<= %r4,%r5,%r6
+ sh2add,nuv %r4,%r5,%r6
+ sh2add,znv %r4,%r5,%r6
+ sh2add,sv %r4,%r5,%r6
+ sh2add,od %r4,%r5,%r6
+ sh2add,tr %r4,%r5,%r6
+ sh2add,<> %r4,%r5,%r6
+ sh2add,>= %r4,%r5,%r6
+ sh2add,> %r4,%r5,%r6
+ sh2add,uv %r4,%r5,%r6
+ sh2add,vnz %r4,%r5,%r6
+ sh2add,nsv %r4,%r5,%r6
+ sh2add,ev %r4,%r5,%r6
+
+ sh2addl %r4,%r5,%r6
+ sh2addl,= %r4,%r5,%r6
+ sh2addl,< %r4,%r5,%r6
+ sh2addl,<= %r4,%r5,%r6
+ sh2addl,nuv %r4,%r5,%r6
+ sh2addl,znv %r4,%r5,%r6
+ sh2addl,sv %r4,%r5,%r6
+ sh2addl,od %r4,%r5,%r6
+ sh2addl,tr %r4,%r5,%r6
+ sh2addl,<> %r4,%r5,%r6
+ sh2addl,>= %r4,%r5,%r6
+ sh2addl,> %r4,%r5,%r6
+ sh2addl,uv %r4,%r5,%r6
+ sh2addl,vnz %r4,%r5,%r6
+ sh2addl,nsv %r4,%r5,%r6
+ sh2addl,ev %r4,%r5,%r6
+
+ sh2addo %r4,%r5,%r6
+ sh2addo,= %r4,%r5,%r6
+ sh2addo,< %r4,%r5,%r6
+ sh2addo,<= %r4,%r5,%r6
+ sh2addo,nuv %r4,%r5,%r6
+ sh2addo,znv %r4,%r5,%r6
+ sh2addo,sv %r4,%r5,%r6
+ sh2addo,od %r4,%r5,%r6
+ sh2addo,tr %r4,%r5,%r6
+ sh2addo,<> %r4,%r5,%r6
+ sh2addo,>= %r4,%r5,%r6
+ sh2addo,> %r4,%r5,%r6
+ sh2addo,uv %r4,%r5,%r6
+ sh2addo,vnz %r4,%r5,%r6
+ sh2addo,nsv %r4,%r5,%r6
+ sh2addo,ev %r4,%r5,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/sh3add.s b/gas/testsuite/gas/hppa/basic/sh3add.s
new file mode 100644
index 00000000000..a51e6e36428
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/sh3add.s
@@ -0,0 +1,67 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ sh3add %r4,%r5,%r6
+ sh3add,= %r4,%r5,%r6
+ sh3add,< %r4,%r5,%r6
+ sh3add,<= %r4,%r5,%r6
+ sh3add,nuv %r4,%r5,%r6
+ sh3add,znv %r4,%r5,%r6
+ sh3add,sv %r4,%r5,%r6
+ sh3add,od %r4,%r5,%r6
+ sh3add,tr %r4,%r5,%r6
+ sh3add,<> %r4,%r5,%r6
+ sh3add,>= %r4,%r5,%r6
+ sh3add,> %r4,%r5,%r6
+ sh3add,uv %r4,%r5,%r6
+ sh3add,vnz %r4,%r5,%r6
+ sh3add,nsv %r4,%r5,%r6
+ sh3add,ev %r4,%r5,%r6
+
+ sh3addl %r4,%r5,%r6
+ sh3addl,= %r4,%r5,%r6
+ sh3addl,< %r4,%r5,%r6
+ sh3addl,<= %r4,%r5,%r6
+ sh3addl,nuv %r4,%r5,%r6
+ sh3addl,znv %r4,%r5,%r6
+ sh3addl,sv %r4,%r5,%r6
+ sh3addl,od %r4,%r5,%r6
+ sh3addl,tr %r4,%r5,%r6
+ sh3addl,<> %r4,%r5,%r6
+ sh3addl,>= %r4,%r5,%r6
+ sh3addl,> %r4,%r5,%r6
+ sh3addl,uv %r4,%r5,%r6
+ sh3addl,vnz %r4,%r5,%r6
+ sh3addl,nsv %r4,%r5,%r6
+ sh3addl,ev %r4,%r5,%r6
+
+ sh3addo %r4,%r5,%r6
+ sh3addo,= %r4,%r5,%r6
+ sh3addo,< %r4,%r5,%r6
+ sh3addo,<= %r4,%r5,%r6
+ sh3addo,nuv %r4,%r5,%r6
+ sh3addo,znv %r4,%r5,%r6
+ sh3addo,sv %r4,%r5,%r6
+ sh3addo,od %r4,%r5,%r6
+ sh3addo,tr %r4,%r5,%r6
+ sh3addo,<> %r4,%r5,%r6
+ sh3addo,>= %r4,%r5,%r6
+ sh3addo,> %r4,%r5,%r6
+ sh3addo,uv %r4,%r5,%r6
+ sh3addo,vnz %r4,%r5,%r6
+ sh3addo,nsv %r4,%r5,%r6
+ sh3addo,ev %r4,%r5,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/shift.s b/gas/testsuite/gas/hppa/basic/shift.s
new file mode 100644
index 00000000000..5cc621dbb36
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/shift.s
@@ -0,0 +1,34 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ vshd %r4,%r5,%r6
+ vshd,= %r4,%r5,%r6
+ vshd,< %r4,%r5,%r6
+ vshd,od %r4,%r5,%r6
+ vshd,tr %r4,%r5,%r6
+ vshd,<> %r4,%r5,%r6
+ vshd,>= %r4,%r5,%r6
+ vshd,ev %r4,%r5,%r6
+
+ shd %r4,%r5,5,%r6
+ shd,= %r4,%r5,5,%r6
+ shd,< %r4,%r5,5,%r6
+ shd,od %r4,%r5,5,%r6
+ shd,tr %r4,%r5,5,%r6
+ shd,<> %r4,%r5,5,%r6
+ shd,>= %r4,%r5,5,%r6
+ shd,ev %r4,%r5,5,%r6
+
diff --git a/gas/testsuite/gas/hppa/basic/special.s b/gas/testsuite/gas/hppa/basic/special.s
new file mode 100644
index 00000000000..d341667bb20
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/special.s
@@ -0,0 +1,15 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ gfw %r4(%sr0,%r5)
+ gfw,m %r4(%sr0,%r5)
+ gfr %r4(%sr0,%r5)
+ gfr,m %r4(%sr0,%r5)
diff --git a/gas/testsuite/gas/hppa/basic/spop.s b/gas/testsuite/gas/hppa/basic/spop.s
new file mode 100644
index 00000000000..9076a95b6b5
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/spop.s
@@ -0,0 +1,34 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+spop_tests:
+ spop0,4,5
+ spop0,4,115
+ spop0,4,5,n
+ spop0,4,115,n
+ spop1,4,5 %r5
+ spop1,4,115 %r5
+ spop1,4,5,n %r5
+ spop1,4,115,n %r5
+ spop2,4,5 %r5
+ spop2,4,115 %r5
+ spop2,4,5,n %r5
+ spop2,4,115,n %r5
+ spop3,4,5 %r5,%r6
+ spop3,4,115 %r5,%r6
+ spop3,4,5,n %r5,%r6
+ spop3,4,115,n %r5,%r6
+
+; Gas fucks this up... Thinks it has the expression 5 mod r5.
+; spop1,4,5 %r5
diff --git a/gas/testsuite/gas/hppa/basic/sub.s b/gas/testsuite/gas/hppa/basic/sub.s
new file mode 100644
index 00000000000..64ff0df506d
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/sub.s
@@ -0,0 +1,117 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ sub %r4,%r5,%r6
+ sub,= %r4,%r5,%r6
+ sub,< %r4,%r5,%r6
+ sub,<= %r4,%r5,%r6
+ sub,<< %r4,%r5,%r6
+ sub,<<= %r4,%r5,%r6
+ sub,sv %r4,%r5,%r6
+ sub,od %r4,%r5,%r6
+ sub,tr %r4,%r5,%r6
+ sub,<> %r4,%r5,%r6
+ sub,>= %r4,%r5,%r6
+ sub,> %r4,%r5,%r6
+ sub,>>= %r4,%r5,%r6
+ sub,>> %r4,%r5,%r6
+ sub,nsv %r4,%r5,%r6
+ sub,ev %r4,%r5,%r6
+
+ subo %r4,%r5,%r6
+ subo,= %r4,%r5,%r6
+ subo,< %r4,%r5,%r6
+ subo,<= %r4,%r5,%r6
+ subo,<< %r4,%r5,%r6
+ subo,<<= %r4,%r5,%r6
+ subo,sv %r4,%r5,%r6
+ subo,od %r4,%r5,%r6
+ subo,tr %r4,%r5,%r6
+ subo,<> %r4,%r5,%r6
+ subo,>= %r4,%r5,%r6
+ subo,> %r4,%r5,%r6
+ subo,>>= %r4,%r5,%r6
+ subo,>> %r4,%r5,%r6
+ subo,nsv %r4,%r5,%r6
+ subo,ev %r4,%r5,%r6
+
+ subb %r4,%r5,%r6
+ subb,= %r4,%r5,%r6
+ subb,< %r4,%r5,%r6
+ subb,<= %r4,%r5,%r6
+ subb,<< %r4,%r5,%r6
+ subb,<<= %r4,%r5,%r6
+ subb,sv %r4,%r5,%r6
+ subb,od %r4,%r5,%r6
+ subb,tr %r4,%r5,%r6
+ subb,<> %r4,%r5,%r6
+ subb,>= %r4,%r5,%r6
+ subb,> %r4,%r5,%r6
+ subb,>>= %r4,%r5,%r6
+ subb,>> %r4,%r5,%r6
+ subb,nsv %r4,%r5,%r6
+ subb,ev %r4,%r5,%r6
+
+ subbo %r4,%r5,%r6
+ subbo,= %r4,%r5,%r6
+ subbo,< %r4,%r5,%r6
+ subbo,<= %r4,%r5,%r6
+ subbo,<< %r4,%r5,%r6
+ subbo,<<= %r4,%r5,%r6
+ subbo,sv %r4,%r5,%r6
+ subbo,od %r4,%r5,%r6
+ subbo,tr %r4,%r5,%r6
+ subbo,<> %r4,%r5,%r6
+ subbo,>= %r4,%r5,%r6
+ subbo,> %r4,%r5,%r6
+ subbo,>>= %r4,%r5,%r6
+ subbo,>> %r4,%r5,%r6
+ subbo,nsv %r4,%r5,%r6
+ subbo,ev %r4,%r5,%r6
+
+ subt %r4,%r5,%r6
+ subt,= %r4,%r5,%r6
+ subt,< %r4,%r5,%r6
+ subt,<= %r4,%r5,%r6
+ subt,<< %r4,%r5,%r6
+ subt,<<= %r4,%r5,%r6
+ subt,sv %r4,%r5,%r6
+ subt,od %r4,%r5,%r6
+ subt,tr %r4,%r5,%r6
+ subt,<> %r4,%r5,%r6
+ subt,>= %r4,%r5,%r6
+ subt,> %r4,%r5,%r6
+ subt,>>= %r4,%r5,%r6
+ subt,>> %r4,%r5,%r6
+ subt,nsv %r4,%r5,%r6
+ subt,ev %r4,%r5,%r6
+
+ subto %r4,%r5,%r6
+ subto,= %r4,%r5,%r6
+ subto,< %r4,%r5,%r6
+ subto,<= %r4,%r5,%r6
+ subto,<< %r4,%r5,%r6
+ subto,<<= %r4,%r5,%r6
+ subto,sv %r4,%r5,%r6
+ subto,od %r4,%r5,%r6
+ subto,tr %r4,%r5,%r6
+ subto,<> %r4,%r5,%r6
+ subto,>= %r4,%r5,%r6
+ subto,> %r4,%r5,%r6
+ subto,>>= %r4,%r5,%r6
+ subto,>> %r4,%r5,%r6
+ subto,nsv %r4,%r5,%r6
+ subto,ev %r4,%r5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/subi.s b/gas/testsuite/gas/hppa/basic/subi.s
new file mode 100644
index 00000000000..063267c87fb
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/subi.s
@@ -0,0 +1,49 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ subi 123,%r5,%r6
+ subi,= 123,%r5,%r6
+ subi,< 123,%r5,%r6
+ subi,<= 123,%r5,%r6
+ subi,<< 123,%r5,%r6
+ subi,<<= 123,%r5,%r6
+ subi,sv 123,%r5,%r6
+ subi,od 123,%r5,%r6
+ subi,tr 123,%r5,%r6
+ subi,<> 123,%r5,%r6
+ subi,>= 123,%r5,%r6
+ subi,> 123,%r5,%r6
+ subi,>>= 123,%r5,%r6
+ subi,>> 123,%r5,%r6
+ subi,nsv 123,%r5,%r6
+ subi,ev 123,%r5,%r6
+
+ subio 123,%r5,%r6
+ subio,= 123,%r5,%r6
+ subio,< 123,%r5,%r6
+ subio,<= 123,%r5,%r6
+ subio,<< 123,%r5,%r6
+ subio,<<= 123,%r5,%r6
+ subio,sv 123,%r5,%r6
+ subio,od 123,%r5,%r6
+ subio,tr 123,%r5,%r6
+ subio,<> 123,%r5,%r6
+ subio,>= 123,%r5,%r6
+ subio,> 123,%r5,%r6
+ subio,>>= 123,%r5,%r6
+ subio,>> 123,%r5,%r6
+ subio,nsv 123,%r5,%r6
+ subio,ev 123,%r5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/system.s b/gas/testsuite/gas/hppa/basic/system.s
new file mode 100644
index 00000000000..1b2e7bf1763
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/system.s
@@ -0,0 +1,46 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+ break 5,12
+ rfi
+ rfir
+ ssm 5,%r4
+ rsm 5,%r4
+ mtsm %r4
+ ldsid (%sr0,%r5),%r4
+ mtsp %r4,%sr0
+ mtctl %r4,%cr10
+ mfsp %sr0,%r4
+ mfctl %cr10,%r4
+ sync
+ syncdma
+ diag 1234
+
+ prober (%sr0,%r5),%r6,%r7
+ proberi (%sr0,%r5),1,%r7
+ probew (%sr0,%r5),%r6,%r7
+ probewi (%sr0,%r5),1,%r7
+
+ lpa %r4(%sr0,%r5),%r6
+ lpa,m %r4(%sr0,%r5),%r6
+ lha %r4(%sr0,%r5),%r6
+ lha,m %r4(%sr0,%r5),%r6
+ lci %r4(%sr0,%r5),%r6
+
+ idtlba %r4,(%sr0,%r5)
+ iitlba %r4,(%sr4,%r5)
+ idtlbp %r4,(%sr0,%r5)
+ iitlbp %r4,(%sr4,%r5)
diff --git a/gas/testsuite/gas/hppa/basic/unit.s b/gas/testsuite/gas/hppa/basic/unit.s
new file mode 100644
index 00000000000..b69b10ee9d5
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/unit.s
@@ -0,0 +1,55 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+
+ uxor %r4,%r5,%r6
+ uxor,sbz %r4,%r5,%r6
+ uxor,shz %r4,%r5,%r6
+ uxor,sdc %r4,%r5,%r6
+ uxor,sbc %r4,%r5,%r6
+ uxor,shc %r4,%r5,%r6
+ uxor,tr %r4,%r5,%r6
+ uxor,nbz %r4,%r5,%r6
+ uxor,nhz %r4,%r5,%r6
+ uxor,ndc %r4,%r5,%r6
+ uxor,nbc %r4,%r5,%r6
+ uxor,nhc %r4,%r5,%r6
+
+ uaddcm %r4,%r5,%r6
+ uaddcm,sbz %r4,%r5,%r6
+ uaddcm,shz %r4,%r5,%r6
+ uaddcm,sdc %r4,%r5,%r6
+ uaddcm,sbc %r4,%r5,%r6
+ uaddcm,shc %r4,%r5,%r6
+ uaddcm,tr %r4,%r5,%r6
+ uaddcm,nbz %r4,%r5,%r6
+ uaddcm,nhz %r4,%r5,%r6
+ uaddcm,ndc %r4,%r5,%r6
+ uaddcm,nbc %r4,%r5,%r6
+ uaddcm,nhc %r4,%r5,%r6
+
+ uaddcmt %r4,%r5,%r6
+ uaddcmt,sbz %r4,%r5,%r6
+ uaddcmt,shz %r4,%r5,%r6
+ uaddcmt,sdc %r4,%r5,%r6
+ uaddcmt,sbc %r4,%r5,%r6
+ uaddcmt,shc %r4,%r5,%r6
+ uaddcmt,tr %r4,%r5,%r6
+ uaddcmt,nbz %r4,%r5,%r6
+ uaddcmt,nhz %r4,%r5,%r6
+ uaddcmt,ndc %r4,%r5,%r6
+ uaddcmt,nbc %r4,%r5,%r6
+ uaddcmt,nhc %r4,%r5,%r6
diff --git a/gas/testsuite/gas/hppa/basic/weird.s b/gas/testsuite/gas/hppa/basic/weird.s
new file mode 100644
index 00000000000..6df4ea165a9
--- /dev/null
+++ b/gas/testsuite/gas/hppa/basic/weird.s
@@ -0,0 +1,870 @@
+ .stabs "weird.c",0x64,0,0,Label0
+Label0:
+ .stabs "inttype:t1=bu4;0;32;",0x80,0,0,0
+
+
+ .stabs "sym32: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "type32:t32= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+
+ .stabs "attr104:G404=@h !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr105:G405=@i !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "var0:G300=@a8;1",0x20,0,0, 0
+ .export var0
+ .data
+ .align 4
+var0:
+ .long 42
+
+ .stabs "sym33:! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym35:# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym36:$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym37:% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym38:& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym39:' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym40:( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym41:) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym42:* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym43:+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym44:, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym45:- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .export attr122
+ .data
+ .align 4
+attr122:
+ .long 42
+ .export attr123
+ .data
+ .align 4
+attr123:
+ .long 42
+ .export attr124
+ .data
+ .align 4
+attr124:
+ .long 42
+
+ .stabs "sym46:. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym47:/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym48:0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym49:1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym50:2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "attr96:G396=@` !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr97:G397=@a !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr98:G398=@b !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr99:G399=@c !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "sym51:3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym52:4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym53:5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym54:6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym55:7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym56:8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym57:9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym58:: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym59:; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym60:< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym61:= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym62:> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym63:? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym64:@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym65:A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym66:B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym67:C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym68:D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym69:E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym70:F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym71:G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym72:H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym73:I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym74:J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym75:K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym76:L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym77:M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym78:N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym79:O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym80:P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym81:Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym82:R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym83:S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym84:T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym85:U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym86:V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym87:W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym88:X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym89:Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym90:Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym91:[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "sym93:] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym94:^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym95:_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym96:` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym97:a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym98:b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym99:c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym100:d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym101:e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym102:f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym103:g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym104:h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym105:i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym106:j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym107:k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym108:l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym109:m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym110:n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym111:o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym112:p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym113:q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym114:r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym115:s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym116:t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym117:u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym118:v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym119:w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym120:x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym121:y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym122:z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym123:{ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym124:| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym125:} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "sym126:~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "type33:t33=! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type35:t35=# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type36:t36=$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type37:t37=% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type38:t38=& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type39:t39=' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type40:t40=( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type41:t41=) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type42:t42=* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type43:t43=+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type44:t44=, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type45:t45=- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type46:t46=. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type47:t47=/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type48:t48=0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type49:t49=1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type50:t50=2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type51:t51=3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type52:t52=4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type53:t53=5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type54:t54=6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type55:t55=7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type56:t56=8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type57:t57=9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type58:t58=: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type59:t59=; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type60:t60=< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type61:t61== !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type62:t62=> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type63:t63=? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type64:t64=@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type65:t65=A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type66:t66=B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type67:t67=C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .export attr66
+ .data
+ .align 4
+attr66:
+ .long 42
+ .export attr67
+ .data
+ .align 4
+attr67:
+ .long 42
+ .export attr68
+ .data
+ .align 4
+attr68:
+ .long 42
+ .export attr69
+ .data
+ .align 4
+attr69:
+ .long 42
+
+ .stabs "type68:t68=D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type69:t69=E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type70:t70=F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type71:t71=G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type72:t72=H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type73:t73=I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type74:t74=J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type75:t75=K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type76:t76=L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type77:t77=M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type78:t78=N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type79:t79=O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type80:t80=P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type81:t81=Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type82:t82=R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type83:t83=S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type84:t84=T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type85:t85=U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type86:t86=V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type87:t87=W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "attr69:G369=@E !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr70:G370=@F !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr71:G371=@G !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "type88:t88=X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type89:t89=Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type90:t90=Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type91:t91=[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "type93:t93=] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type94:t94=^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type95:t95=_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type96:t96=` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type97:t97=a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type98:t98=b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type99:t99=c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type100:t100=d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type101:t101=e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type102:t102=f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type103:t103=g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type104:t104=h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type105:t105=i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type106:t106=j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type107:t107=k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type108:t108=l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type109:t109=m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type110:t110=n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type111:t111=o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type112:t112=p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type113:t113=q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type114:t114=r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type115:t115=s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type116:t116=t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type117:t117=u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type118:t118=v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type119:t119=w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type120:t120=x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type121:t121=y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type122:t122=z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type123:t123={ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type124:t124=| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type125:t125=} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type126:t126=~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+
+ .stabs "attr32:G332=@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr33:G333=@! !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr35:G334=@# !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "primary:G200=ered:0,green:1,blue:2,;", 0x20,0,0, 0
+
+ .stabs "attr36:G335=@$ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .export primary
+ .data
+ .align 4
+primary:
+ .long 42
+
+ .stabs "attr37:G337=@% !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "const69:c=e1,69", 0x80,0,0, 0
+
+ .stabs "const70:c=e190=bs2;0;16;,70", 0x80,0,0, 0
+
+ .stabs "attr38:G338=@& !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "bad_neg0type:t201=s8field0:1,0,32;field2:-534,32,64;field3:-1,96,32;;", 0x80,0,0, 0
+
+ .stabs "bad_neg0:G201", 0x20,0,0, 0
+
+ .export bad_neg0
+ .data
+ .align 4
+bad_neg0:
+ .long 42
+ .long 43, 44, 45
+
+ .stabs "attr39:G339=@' !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr41:G341=@) !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr42:G342=@* !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr43:G343=@+ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr44:G344=@, !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr46:G346=@. !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr47:G347=@/ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr58:G358=@: !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "attr59:G359=@;@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "attr60:G360=@< !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr61:G361=@= !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr62:G362=@> !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr63:G363=@? !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr64:G364=@@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr65:G365=@A !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr66:G366=@B !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr67:G367=@C !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr68:G368=@D !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr72:G372=@H !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr73:G373=@I !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr74:G374=@J !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr75:G375=@K !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr76:G376=@L !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr77:G377=@M !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr78:G378=@N !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr79:G379=@O !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr80:G380=@P !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr81:G381=@Q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr82:G382=@R !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr83:G383=@S !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr84:G384=@T !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr85:G385=@U !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr86:G386=@V !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr87:G387=@W !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr88:G388=@X !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr89:G389=@Y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr90:G390=@Z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr91:G391=@[ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .stabs "attr93:G393=@] !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+
+ .export _common0
+ .data
+ .align 4
+_common0:
+ .long 42
+ .long 24
+ .long 22
+ .export common0
+ .data
+ .align 4
+common0:
+ .long 42
+ .long 24
+ .long 22
+ .stabs "common0",0xe2,0,0,0
+ .stabs "common0var0:S1", 0x20,0,0, 0
+ .stabs "common0var1:S1", 0x20,0,0, 4
+ .stabs "common0var2:S1", 0x20,0,0, 8
+ .stabs "common0",0xe4,0,0,0
+
+ .stabs "attr94:G394=@^ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr95:G395=@_ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr100:G400=@d !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr101:G401=@e !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr102:G402=@f !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr103:G403=@g !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr106:G406=@j !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr107:G407=@k !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr108:G408=@l !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr109:G409=@m !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr110:G410=@n !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr111:G411=@o !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr112:G412=@p !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr113:G413=@q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr114:G414=@r !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr115:G415=@s !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr116:G416=@t !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr117:G417=@u !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr118:G418=@v !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr119:G419=@w !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr120:G420=@x !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr121:G421=@y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr122:G422=@z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr123:G423=@{ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr124:G424=@| !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr125:G425=@} !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+ .stabs "attr126:G426=@~ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
+
+ .export attr32
+ .data
+ .align 4
+attr32:
+ .long 42
+ .export attr33
+ .data
+ .align 4
+attr33:
+ .long 42
+ .export attr35
+ .data
+ .align 4
+attr35:
+ .long 42
+ .export attr36
+ .data
+ .align 4
+attr36:
+ .long 42
+ .export attr37
+ .data
+ .align 4
+attr37:
+ .long 42
+ .export attr38
+ .data
+ .align 4
+attr38:
+ .long 42
+ .export attr39
+ .data
+ .align 4
+attr39:
+ .long 42
+ .export attr41
+ .data
+ .align 4
+attr41:
+ .long 42
+ .export attr42
+ .data
+ .align 4
+attr42:
+ .long 42
+ .export attr43
+ .data
+ .align 4
+attr43:
+ .long 42
+ .export attr44
+ .data
+ .align 4
+attr44:
+ .long 42
+ .export attr46
+ .data
+ .align 4
+attr46:
+ .long 42
+ .export attr47
+ .data
+ .align 4
+attr47:
+ .long 42
+ .export attr58
+ .data
+ .align 4
+attr58:
+ .long 42
+ .export attr59
+ .data
+ .align 4
+attr59:
+ .long 42
+ .export attr60
+ .data
+ .align 4
+attr60:
+ .long 42
+ .export attr61
+ .data
+ .align 4
+attr61:
+ .long 42
+ .export attr62
+ .data
+ .align 4
+attr62:
+ .long 42
+ .export attr63
+ .data
+ .align 4
+attr63:
+ .long 42
+ .export attr64
+ .data
+ .align 4
+attr64:
+ .long 42
+ .export attr65
+ .data
+ .align 4
+attr65:
+ .long 42
+ .export attr70
+ .data
+ .align 4
+attr70:
+ .long 42
+ .export attr71
+ .data
+ .align 4
+attr71:
+ .long 42
+ .export attr72
+ .data
+ .align 4
+attr72:
+ .long 42
+ .export attr73
+ .data
+ .align 4
+attr73:
+ .long 42
+ .export attr74
+ .data
+ .align 4
+attr74:
+ .long 42
+ .export attr75
+ .data
+ .align 4
+attr75:
+ .long 42
+ .export attr76
+ .data
+ .align 4
+attr76:
+ .long 42
+ .export attr77
+ .data
+ .align 4
+attr77:
+ .long 42
+ .export attr78
+ .data
+ .align 4
+attr78:
+ .long 42
+ .export attr79
+ .data
+ .align 4
+attr79:
+ .long 42
+ .export attr80
+ .data
+ .align 4
+attr80:
+ .long 42
+ .export attr81
+ .data
+ .align 4
+attr81:
+ .long 42
+ .export attr82
+ .data
+ .align 4
+attr82:
+ .long 42
+ .export attr83
+ .data
+ .align 4
+attr83:
+ .long 42
+ .export attr84
+ .data
+ .align 4
+attr84:
+ .long 42
+
+ .stabs "float72type:t202=R87;9;", 0x80,0,0, 0
+
+ .stabs "int256var:G203=bu32;0;256;", 0x20,0,0, 0
+ .export int256var
+ .data
+ .align 4
+int256var:
+ .long 42
+ .long 0x2b, 0x2c, 0x2d, 0x2d, 0x2c, 0x2b, 0x2a
+
+
+ .stabs "consth:c=e1,4294967296", 0x80,0,0, 0
+
+ .stabs "consth2:c=e1,-734723985732642758928475678987234563284937456", 0x80,0,0, 0
+
+ .stabs "bad_neg0const:c=S201,128,128,11222211343434345656565677888877", 0x80,0,0, 0
+
+ .stabs "bad_type0:t(-3,7)", 0x80,0,0, 0
+ .stabs "bad_type1:t(42,6)", 0x80,0,0, 0
+
+ .stabs "array_index0:t205=r1;0;5;", 0x80,0,0, 0
+ .stabs "array0:G206=a205;1", 0x20,0,0, 0
+ .export array0
+ .data
+ .align 4
+array0:
+ .long 42
+ .long 43, 44, 45, 46, 47
+
+ .stabs "array_index1:t207=", 0x80,0,0, 0
+ .stabs "array1:G208=aeai1_red:0,ai1_green:1,ai1_blue:2,;;1", 0x20,0,0, 0
+ .export array1
+ .data
+ .align 4
+array1:
+ .long 42
+ .long 43, 44
+
+ .stabs "inttype_one:t209=1", 0x80,0,0, 0
+ .stabs "inttype_two:t210=1", 0x80,0,0, 0
+ .stabs "one_var:G209", 0x20,0,0, 0
+ .export one_var
+ .data
+ .align 4
+one_var:
+ .long 42
+ .stabs "two_var:G210", 0x20,0,0, 0
+ .export two_var
+ .data
+ .align 4
+two_var:
+ .long 42
+
+ .stabs "intp:t211=*1", 0x80,0,0, 0
+ .stabs "pointer_to_int_var:G212=*1", 0x80,0,0, 0
+ .stabs "intp_var:G211", 0x20,0,0, 0
+ .export intp_var
+ .data
+ .align 4
+intp_var:
+ .long 42
+
+ .stabs "unrecog_const:c=xjksdflskd33,4;473;", 0x80,0,0, 0
+
+ .export attr85
+ .data
+ .align 4
+attr85:
+ .long 42
+ .export attr86
+ .data
+ .align 4
+attr86:
+ .long 42
+ .export attr87
+ .data
+ .align 4
+attr87:
+ .long 42
+ .export attr88
+ .data
+ .align 4
+attr88:
+ .long 42
+ .export attr89
+ .data
+ .align 4
+attr89:
+ .long 42
+ .export attr90
+ .data
+ .align 4
+attr90:
+ .long 42
+ .export attr91
+ .data
+ .align 4
+attr91:
+ .long 42
+ .export attr92
+ .data
+ .align 4
+attr92:
+ .long 42
+ .export attr93
+ .data
+ .align 4
+attr93:
+ .long 42
+ .export attr94
+ .data
+ .align 4
+attr94:
+ .long 42
+ .export attr95
+ .data
+ .align 4
+attr95:
+ .long 42
+ .export attr96
+ .data
+ .align 4
+attr96:
+ .long 42
+ .export attr97
+ .data
+ .align 4
+attr97:
+ .long 42
+ .export attr98
+ .data
+ .align 4
+attr98:
+ .long 42
+ .export attr99
+ .data
+ .align 4
+attr99:
+ .long 42
+ .export attr100
+ .data
+ .align 4
+attr100:
+ .long 42
+ .export attr101
+ .data
+ .align 4
+attr101:
+ .long 42
+ .export attr102
+ .data
+ .align 4
+attr102:
+ .long 42
+ .export attr103
+ .data
+ .align 4
+attr103:
+ .long 42
+ .export attr104
+ .data
+ .align 4
+attr104:
+ .long 42
+ .export attr105
+ .data
+ .align 4
+attr105:
+ .long 42
+ .export attr106
+ .data
+ .align 4
+attr106:
+ .long 42
+ .export attr107
+ .data
+ .align 4
+attr107:
+ .long 42
+ .export attr108
+ .data
+ .align 4
+attr108:
+ .long 42
+ .export attr109
+ .data
+ .align 4
+attr109:
+ .long 42
+ .export attr110
+ .data
+ .align 4
+attr110:
+ .long 42
+ .export attr111
+ .data
+ .align 4
+attr111:
+ .long 42
+ .export attr112
+ .data
+ .align 4
+attr112:
+ .long 42
+ .export attr113
+ .data
+ .align 4
+attr113:
+ .long 42
+ .export attr114
+ .data
+ .align 4
+attr114:
+ .long 42
+ .export attr115
+ .data
+ .align 4
+attr115:
+ .long 42
+ .export attr116
+ .data
+ .align 4
+attr116:
+ .long 42
+ .export attr117
+ .data
+ .align 4
+attr117:
+ .long 42
+ .export attr118
+ .data
+ .align 4
+attr118:
+ .long 42
+ .export attr119
+ .data
+ .align 4
+attr119:
+ .long 42
+ .export attr120
+ .data
+ .align 4
+attr120:
+ .long 42
+ .export attr121
+ .data
+ .align 4
+attr121:
+ .long 42
+ .export attr125
+ .data
+ .align 4
+attr125:
+ .long 42
+ .export attr126
+ .data
+ .align 4
+attr126:
+ .long 42
+
+ .stabs "var1:G301=@s32;1",0x20,0,0, 0
+ .export var1
+ .data
+ .align 4
+var1:
+ .long 42
+ .stabs "var2:G302=@p42;1",0x20,0,0, 0
+ .export var2
+ .data
+ .align 4
+var2:
+ .long 42
+ .stabs "var3:G303=@P;1",0x20,0,0, 0
+ .export var3
+ .data
+ .align 4
+var3:
+ .long 42
+
+
+
+
+
+
+
+
+
+
+
+
+ .stabs "v_comb:G448=s24!2,020,445=s12!1,120,444=s4x:1,0,32;;;$vb444:446=*444,0;a:/01,32,32;;;0264,447=s12!1,120,444;$vb444:446,0;b:/01,32,32;;;comb:/01,128,32;;", 0x20,0,0, 0
+
+ .export v_comb
+ .align 1
+v_comb:
+ .long v_comb_shared
+ .long 43
+ .long v_comb_shared
+ .long 44
+ .long 45
+v_comb_shared:
+ .long 42
+
+ .stabs "sym92:\\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "type92:t92=\\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",0x80,0,0,0
+ .stabs "attr92:G392=@\\ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",0x20,0,0, 0
diff --git a/gas/testsuite/gas/hppa/parse/align1.s b/gas/testsuite/gas/hppa/parse/align1.s
new file mode 100644
index 00000000000..df81e96dee5
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/align1.s
@@ -0,0 +1,41 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 1
+ .align 8
+ nop
+; "8" assumed if no alignment given.
+ .align
+ nop
+ .align 4096
+ nop
+
+
+ .SPACE $PRIVATE$
+ .SUBSPA $BSS$
+
+ .ALIGN 8
+$L00BSS:
+home_buff:
+ .BLOCK 1024
+ .ALIGN 8
+current_buff:
+ .BLOCK 1024
+ .ALIGN 4
+lock_file:
+ .BLOCK 4
+ .ALIGN 8
+L332.name:
+ .BLOCK 30
+ .ALIGN 4
+L352.last_case_wa:
+ .BLOCK 4
+
+
diff --git a/gas/testsuite/gas/hppa/parse/align2.s b/gas/testsuite/gas/hppa/parse/align2.s
new file mode 100644
index 00000000000..af734c81391
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/align2.s
@@ -0,0 +1,15 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 3
+
+
+
+
diff --git a/gas/testsuite/gas/hppa/parse/appbug.s b/gas/testsuite/gas/hppa/parse/appbug.s
new file mode 100644
index 00000000000..7a37f9ee579
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/appbug.s
@@ -0,0 +1 @@
+# 1 "crt0.s"
diff --git a/gas/testsuite/gas/hppa/parse/badfmpyadd.s b/gas/testsuite/gas/hppa/parse/badfmpyadd.s
new file mode 100644
index 00000000000..fd1c1f813cd
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/badfmpyadd.s
@@ -0,0 +1,33 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT foobar,ENTRY,PRIV_LEV=3,ARGW0=FR,ARGW1=FU,ARGW2=FR,ARGW3=FU,RTNVAL=FR
+foobar
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ ldo -64(%r30),%r20
+ addil LR'x-$global$,%r27
+ fldds 8(%r20),%fr4
+ fldds 0(%r20),%fr22
+ ldo RR'x-$global$(%r1),%r19
+ fmpysub,sgl %fr5L,%fr7L,%fr5L,%fr22L,%fr4L
+ bv %r0(%r2)
+ fstds %fr5,0(%r19)
+ .EXIT
+ .PROCEND
+ .SPACE $PRIVATE$
+ .SUBSPA $BSS$
+
+x .comm 8
+y .comm 8
diff --git a/gas/testsuite/gas/hppa/parse/block1.s b/gas/testsuite/gas/hppa/parse/block1.s
new file mode 100644
index 00000000000..317699f1c8d
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/block1.s
@@ -0,0 +1,18 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $DATA$
+
+foo:
+ .block
+bar:
+ .block 0x7fffffff
+com:
+
+
+
diff --git a/gas/testsuite/gas/hppa/parse/block2.s b/gas/testsuite/gas/hppa/parse/block2.s
new file mode 100644
index 00000000000..1a3b5f14ed7
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/block2.s
@@ -0,0 +1,15 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $DATA$
+
+foo:
+ .block -1
+
+
+
diff --git a/gas/testsuite/gas/hppa/parse/calldatabug.s b/gas/testsuite/gas/hppa/parse/calldatabug.s
new file mode 100644
index 00000000000..6c80cf4677b
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/calldatabug.s
@@ -0,0 +1,189 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .IMPORT printf,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+LC$0000:
+ .STRING "%d %lf %d\x0a\x00"
+ .align 4
+ .EXPORT error__3AAAiidi
+ .EXPORT error__3AAAiidi,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=FR,ARGW4=FU,RTNVAL=GR
+error__3AAAiidi:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r9,8(%r4)
+ stw %r8,12(%r4)
+ stw %r7,16(%r4)
+ stw %r6,20(%r4)
+ stw %r5,24(%r4)
+ copy %r26,%r5
+ ldo -8(%r0),%r6
+ ldo -32(%r4),%r19
+ add %r19,%r6,%r7
+ stw %r25,0(%r7)
+ ldo -12(%r0),%r8
+ ldo -32(%r4),%r19
+ add %r19,%r8,%r9
+ stw %r24,0(%r9)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -24(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldo -28(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ stw %r22,-52(%r30)
+ ldil L'LC$0000,%r26
+ ldo R'LC$0000(%r26),%r26
+ ldw 0(%r19),%r25
+ fldds 0(%r20),%fr7
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=FR,ARGW3=FU
+ bl printf,%r2
+ nop
+ bl,n L$0002,%r0
+ bl,n L$0001,%r0
+L$0002:
+L$0001:
+ ldw 8(%r4),%r9
+ ldw 12(%r4),%r8
+ ldw 16(%r4),%r7
+ ldw 20(%r4),%r6
+ ldw 24(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT ok__3AAAidi
+ .EXPORT ok__3AAAidi,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=FR,ARGW3=FU,RTNVAL=GR
+ok__3AAAidi:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r9,8(%r4)
+ stw %r8,12(%r4)
+ stw %r7,16(%r4)
+ stw %r6,20(%r4)
+ stw %r5,24(%r4)
+ copy %r26,%r5
+ ldo -8(%r0),%r6
+ ldo -32(%r4),%r19
+ add %r19,%r6,%r7
+ stw %r25,0(%r7)
+ ldo -16(%r0),%r8
+ ldo -32(%r4),%r19
+ add %r19,%r8,%r9
+ fstds %fr7,0(%r9)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -16(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldo -20(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ stw %r22,-52(%r30)
+ ldil L'LC$0000,%r26
+ ldo R'LC$0000(%r26),%r26
+ ldw 0(%r19),%r25
+ fldds 0(%r20),%fr7
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=FR,ARGW3=FU
+ bl printf,%r2
+ nop
+ bl,n L$0004,%r0
+ bl,n L$0003,%r0
+L$0004:
+L$0003:
+ ldw 8(%r4),%r9
+ ldw 12(%r4),%r8
+ ldw 16(%r4),%r7
+ ldw 20(%r4),%r6
+ ldw 24(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT __main,CODE
+ .align 8
+LC$0001:
+ ; .double 5.50000000000000000000e+00
+ .word 1075183616 ; = 0x40160000
+ .word 0 ; = 0x0
+ .align 4
+ .EXPORT main
+ .EXPORT main,PRIV_LEV=3,RTNVAL=GR
+main:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ .CALL
+ bl __main,%r2
+ nop
+ ldo -24(%r0),%r19
+ ldo -32(%r30),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0001,%r20
+ ldo R'LC$0001(%r20),%r21
+ ldw 0(%r21),%r22
+ ldw 4(%r21),%r23
+ stw %r22,0(%r19)
+ stw %r23,4(%r19)
+ ldo 3(%r0),%r19
+ stw %r19,-60(%r30)
+ ldo 8(%r4),%r26
+ ldo 1(%r0),%r25
+ ldo 4(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl error__3AAAiidi,%r2
+ nop
+ ldo 3(%r0),%r19
+ stw %r19,-52(%r30)
+ ldo 8(%r4),%r26
+ ldo 1(%r0),%r25
+ ldil L'LC$0001,%r19
+ ldo R'LC$0001(%r19),%r20
+ fldds 0(%r20),%fr7
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=FR,ARGW3=FU
+ bl ok__3AAAidi,%r2
+ nop
+ copy %r0,%r28
+ bl,n L$0005,%r0
+ bl,n L$0005,%r0
+L$0005:
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+
diff --git a/gas/testsuite/gas/hppa/parse/callinfobug.s b/gas/testsuite/gas/hppa/parse/callinfobug.s
new file mode 100644
index 00000000000..c08c7736066
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/callinfobug.s
@@ -0,0 +1,8 @@
+ .space $TEXT$
+ .subspa $CODE$
+ .align 4
+ .export divu,millicode
+ .proc
+ .callinfo millicode
+divu
+ .procend
diff --git a/gas/testsuite/gas/hppa/parse/defbug.s b/gas/testsuite/gas/hppa/parse/defbug.s
new file mode 100644
index 00000000000..064caf4d3df
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/defbug.s
@@ -0,0 +1,18 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .import _seterrno
+ .export vfork ! .label vfork ! .proc! .callinfo no_calls! .entry ! .label __vfork ! mtsp %r0,%sr0! ldil L%0xc0000004,%r1! ble R%0xc0000004(%sr0,%r1)! ldi 66 ,%r22 ! b,n yyy! b,n __vfork ! b _seterrno! copy %r28,%r26! .label yyy
+ add,= %r0,%r29,%r0
+ copy %r0,%r28
+ bv,n (%r2)
+ .exit
+ .procend
diff --git a/gas/testsuite/gas/hppa/parse/entrybug.s b/gas/testsuite/gas/hppa/parse/entrybug.s
new file mode 100644
index 00000000000..c4fe7a4368d
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/entrybug.s
@@ -0,0 +1,24 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .PARAM foo,RTNVAL=GR
+foo:
+ .PROC
+ .CALLINFO FRAME=128,NO_CALLS,ENTRY_GR=1,ENTRY_FR=11
+ .ENTRY
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
+ .SPACE $TEXT$
+ .SUBSPA $LIT$
+
diff --git a/gas/testsuite/gas/hppa/parse/exportbug.s b/gas/testsuite/gas/hppa/parse/exportbug.s
new file mode 100644
index 00000000000..4966415040f
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/exportbug.s
@@ -0,0 +1,14 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+
+
diff --git a/gas/testsuite/gas/hppa/parse/exprbug.s b/gas/testsuite/gas/hppa/parse/exprbug.s
new file mode 100644
index 00000000000..07bad422d26
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/exprbug.s
@@ -0,0 +1,39 @@
+ .space $TEXT$
+ .subspa $CODE$
+
+ .align 8
+ .export icode,data
+icode:
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ bv,n %r0(%r2)
+ .exit
+ nop
+ .procend
+
+ ;
+ ; FIRST, argv array of pointers to args, 1st is same as path.
+ ;
+ .align 8
+ic_argv:
+ .word ic_argv1-icode ; second, pointer to 1st argument
+ .word ic_path-icode ; first, pointer to init path
+ .word 0 ; fourth, NULL argv terminator (pad)
+ .word 0 ; third, NULL argv terminator
+
+ic_path:
+ .blockz 4096 ; must be multiple of 4 bytes
+ .word 0 ; in case full string is used
+ .word 0 ; this will be the string terminator
+
+ic_argv1:
+ .blockz 4096 ; must be multiple of 4 bytes
+ .word 0 ; in case full string is used
+ .word 0 ; this will be the string terminator
+
+ .export szicode,data
+szicode:
+ .word szicode-icode
+ .word 0 ; must have at least one filler at end
+
diff --git a/gas/testsuite/gas/hppa/parse/fixup7bug.s b/gas/testsuite/gas/hppa/parse/fixup7bug.s
new file mode 100644
index 00000000000..23c8740c626
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/fixup7bug.s
@@ -0,0 +1,6192 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .IMPORT xmalloc,CODE
+ .IMPORT _obstack_newchunk,CODE
+ .IMPORT memset,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT alloc_type,CODE
+ .EXPORT alloc_type,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+alloc_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r7,32(%r4)
+ stw %r6,36(%r4)
+ stw %r5,40(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0002,%r0
+ nop
+ ldo 52(%r0),%r26
+ .CALL ARGW0=GR
+ bl xmalloc,%r2
+ nop
+ copy %r28,%r7
+ bl,n L$0003,%r0
+L$0002:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo 120(%r19),%r20
+ stw %r20,8(%r4)
+ ldw 8(%r4),%r19
+ stw %r19,12(%r4)
+ ldo 52(%r0),%r19
+ stw %r19,16(%r4)
+ ldw 12(%r4),%r19
+ ldw 12(%r4),%r20
+ ldw 16(%r19),%r19
+ ldw 12(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 16(%r4),%r20
+ comclr,< %r19,%r20,%r0
+ bl L$0004,%r0
+ nop
+ ldw 12(%r4),%r26
+ ldw 16(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl _obstack_newchunk,%r2
+ nop
+ copy %r0,%r19
+ bl,n L$0005,%r0
+L$0004:
+ copy %r0,%r19
+L$0005:
+ ldw 12(%r4),%r19
+ ldw 12(%r4),%r20
+ ldw 12(%r20),%r21
+ ldw 16(%r4),%r22
+ add %r21,%r22,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 8(%r4),%r19
+ stw %r19,20(%r4)
+ ldw 20(%r4),%r19
+ ldw 8(%r19),%r20
+ stw %r20,24(%r4)
+ ldw 20(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 24(%r4),%r19
+ comclr,= %r20,%r19,%r0
+ bl L$0006,%r0
+ nop
+ ldw 20(%r4),%r19
+ ldw 40(%r19),%r20
+ copy %r20,%r21
+ depi -1,1,1,%r21
+ stw %r21,40(%r19)
+L$0006:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 20(%r4),%r21
+ ldw 12(%r20),%r20
+ ldw 24(%r21),%r21
+ add %r20,%r21,%r20
+ ldw 20(%r4),%r21
+ ldw 24(%r21),%r22
+ uaddcm %r0,%r22,%r21
+ and %r20,%r21,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r19),%r19
+ ldw 4(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 20(%r4),%r20
+ ldw 20(%r4),%r21
+ ldw 16(%r20),%r20
+ ldw 4(%r21),%r21
+ sub %r20,%r21,%r20
+ comclr,> %r19,%r20,%r0
+ bl L$0007,%r0
+ nop
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 16(%r20),%r21
+ stw %r21,12(%r19)
+ copy %r21,%r19
+ bl,n L$0008,%r0
+L$0007:
+ copy %r0,%r19
+L$0008:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r20),%r21
+ stw %r21,8(%r19)
+ ldw 24(%r4),%r7
+L$0003:
+ copy %r7,%r26
+ copy %r0,%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+ stw %r0,0(%r7)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,12(%r7)
+ ldo -1(%r0),%r19
+ stw %r19,44(%r7)
+ copy %r7,%r28
+ bl,n L$0001,%r0
+L$0001:
+ ldw 32(%r4),%r7
+ ldw 36(%r4),%r6
+ ldw 40(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT make_pointer_type,CODE
+ .EXPORT make_pointer_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+make_pointer_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r9,16(%r4)
+ stw %r8,20(%r4)
+ stw %r7,24(%r4)
+ stw %r6,28(%r4)
+ stw %r5,32(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 20(%r19),%r9
+ comiclr,<> 0,%r9,%r0
+ bl L$0010,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0011,%r0
+ nop
+ copy %r9,%r28
+ bl,n L$0009,%r0
+ bl,n L$0012,%r0
+L$0011:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0013,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,0(%r19)
+ copy %r9,%r28
+ bl,n L$0009,%r0
+L$0013:
+L$0012:
+L$0010:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0015,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0014,%r0
+ nop
+ bl,n L$0015,%r0
+L$0015:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ copy %r28,%r9
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0016,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,0(%r19)
+L$0016:
+ bl,n L$0017,%r0
+L$0014:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r9
+ ldw 12(%r9),%r19
+ stw %r19,8(%r4)
+ copy %r9,%r26
+ copy %r0,%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+ ldw 8(%r4),%r19
+ stw %r19,12(%r9)
+L$0017:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,16(%r9)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,20(%r19)
+ ldo 4(%r0),%r19
+ stw %r19,8(%r9)
+ ldo 1(%r0),%r19
+ stw %r19,0(%r9)
+ ldh 32(%r9),%r19
+ copy %r19,%r20
+ depi -1,31,1,%r20
+ sth %r20,32(%r9)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 20(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0018,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,20(%r19)
+L$0018:
+ copy %r9,%r28
+ bl,n L$0009,%r0
+L$0009:
+ ldw 16(%r4),%r9
+ ldw 20(%r4),%r8
+ ldw 24(%r4),%r7
+ ldw 28(%r4),%r6
+ ldw 32(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT lookup_pointer_type,CODE
+ .EXPORT lookup_pointer_type,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+lookup_pointer_type:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,8(%r4)
+ stw %r5,12(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ copy %r0,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl make_pointer_type,%r2
+ nop
+ bl,n L$0019,%r0
+L$0019:
+ ldw 8(%r4),%r6
+ ldw 12(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT make_reference_type,CODE
+ .EXPORT make_reference_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+make_reference_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r9,16(%r4)
+ stw %r8,20(%r4)
+ stw %r7,24(%r4)
+ stw %r6,28(%r4)
+ stw %r5,32(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 24(%r19),%r9
+ comiclr,<> 0,%r9,%r0
+ bl L$0021,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0022,%r0
+ nop
+ copy %r9,%r28
+ bl,n L$0020,%r0
+ bl,n L$0023,%r0
+L$0022:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0024,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,0(%r19)
+ copy %r9,%r28
+ bl,n L$0020,%r0
+L$0024:
+L$0023:
+L$0021:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0026,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0025,%r0
+ nop
+ bl,n L$0026,%r0
+L$0026:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ copy %r28,%r9
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0027,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,0(%r19)
+L$0027:
+ bl,n L$0028,%r0
+L$0025:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r9
+ ldw 12(%r9),%r19
+ stw %r19,8(%r4)
+ copy %r9,%r26
+ copy %r0,%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+ ldw 8(%r4),%r19
+ stw %r19,12(%r9)
+L$0028:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,16(%r9)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,24(%r19)
+ ldo 4(%r0),%r19
+ stw %r19,8(%r9)
+ ldo 16(%r0),%r19
+ stw %r19,0(%r9)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 24(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0029,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,24(%r19)
+L$0029:
+ copy %r9,%r28
+ bl,n L$0020,%r0
+L$0020:
+ ldw 16(%r4),%r9
+ ldw 20(%r4),%r8
+ ldw 24(%r4),%r7
+ ldw 28(%r4),%r6
+ ldw 32(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT lookup_reference_type,CODE
+ .EXPORT lookup_reference_type,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+lookup_reference_type:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,8(%r4)
+ stw %r5,12(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ copy %r0,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl make_reference_type,%r2
+ nop
+ bl,n L$0030,%r0
+L$0030:
+ ldw 8(%r4),%r6
+ ldw 12(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT make_function_type,CODE
+ .EXPORT make_function_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+make_function_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r9,16(%r4)
+ stw %r8,20(%r4)
+ stw %r7,24(%r4)
+ stw %r6,28(%r4)
+ stw %r5,32(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 28(%r19),%r9
+ comiclr,<> 0,%r9,%r0
+ bl L$0032,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0033,%r0
+ nop
+ copy %r9,%r28
+ bl,n L$0031,%r0
+ bl,n L$0034,%r0
+L$0033:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0035,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,0(%r19)
+ copy %r9,%r28
+ bl,n L$0031,%r0
+L$0035:
+L$0034:
+L$0032:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0037,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0036,%r0
+ nop
+ bl,n L$0037,%r0
+L$0037:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ copy %r28,%r9
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0038,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,0(%r19)
+L$0038:
+ bl,n L$0039,%r0
+L$0036:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r9
+ ldw 12(%r9),%r19
+ stw %r19,8(%r4)
+ copy %r9,%r26
+ copy %r0,%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+ ldw 8(%r4),%r19
+ stw %r19,12(%r9)
+L$0039:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,16(%r9)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,28(%r19)
+ ldo 1(%r0),%r19
+ stw %r19,8(%r9)
+ ldo 6(%r0),%r19
+ stw %r19,0(%r9)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 28(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0040,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ stw %r9,28(%r19)
+L$0040:
+ copy %r9,%r28
+ bl,n L$0031,%r0
+L$0031:
+ ldw 16(%r4),%r9
+ ldw 20(%r4),%r8
+ ldw 24(%r4),%r7
+ ldw 28(%r4),%r6
+ ldw 32(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT lookup_function_type,CODE
+ .EXPORT lookup_function_type,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+lookup_function_type:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,8(%r4)
+ stw %r5,12(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ copy %r0,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl make_function_type,%r2
+ nop
+ bl,n L$0041,%r0
+L$0041:
+ ldw 8(%r4),%r6
+ ldw 12(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT smash_to_member_type,CODE
+ .align 4
+ .EXPORT lookup_member_type,CODE
+ .EXPORT lookup_member_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+lookup_member_type:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r8,8(%r4)
+ stw %r7,12(%r4)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo 24(%r4),%r1
+ fstds,ma %fr12,8(%r1)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ stw %r28,-16(%r30)
+ fldws -16(%r30),%fr12
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ fstws %fr12,-16(%r30)
+ ldw -16(%r30),%r26
+ ldw 0(%r19),%r25
+ ldw 0(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl smash_to_member_type,%r2
+ nop
+ fstws %fr12,-16(%r30)
+ ldw -16(%r30),%r28
+ bl,n L$0042,%r0
+L$0042:
+ ldw 8(%r4),%r8
+ ldw 12(%r4),%r7
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 24(%r4),%r1
+ fldds,ma 8(%r1),%fr12
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT allocate_stub_method,CODE
+ .EXPORT allocate_stub_method,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+allocate_stub_method:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ stw %r28,8(%r4)
+ ldw 8(%r4),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,16(%r19)
+ ldw 8(%r4),%r19
+ ldo 4(%r0),%r20
+ sth %r20,32(%r19)
+ ldw 8(%r4),%r19
+ ldo 15(%r0),%r20
+ stw %r20,0(%r19)
+ ldw 8(%r4),%r19
+ ldo 1(%r0),%r20
+ stw %r20,8(%r19)
+ ldw 8(%r4),%r28
+ bl,n L$0043,%r0
+L$0043:
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT builtin_type_int,DATA
+ .align 4
+ .EXPORT create_array_type,CODE
+ .EXPORT create_array_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+create_array_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r10,56(%r4)
+ stw %r9,60(%r4)
+ stw %r8,64(%r4)
+ stw %r7,68(%r4)
+ stw %r6,72(%r4)
+ stw %r5,76(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ stw %r28,8(%r4)
+ ldw 8(%r4),%r19
+ ldo 2(%r0),%r20
+ stw %r20,0(%r19)
+ ldw 8(%r4),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,16(%r19)
+ ldw 8(%r4),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 0(%r20),%r20
+ ldw 8(%r21),%r21
+ stw %r20,-16(%r30)
+ fldws -16(%r30),%fr5
+ stw %r21,-16(%r30)
+ fldws -16(%r30),%fr5R
+ xmpyu %fr5,%fr5R,%fr4
+ fstws %fr4R,-16(%r30)
+ ldw -16(%r30),%r24
+ stw %r24,8(%r19)
+ ldw 8(%r4),%r19
+ ldo 1(%r0),%r20
+ sth %r20,34(%r19)
+ ldw 8(%r4),%r9
+ ldw 8(%r4),%r19
+ ldw 12(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0050,%r0
+ nop
+ ldw 8(%r4),%r19
+ ldw 12(%r19),%r20
+ ldo 120(%r20),%r19
+ stw %r19,16(%r4)
+ ldw 16(%r4),%r19
+ stw %r19,20(%r4)
+ ldo 16(%r0),%r19
+ stw %r19,24(%r4)
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 16(%r19),%r19
+ ldw 12(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 24(%r4),%r20
+ comclr,< %r19,%r20,%r0
+ bl L$0045,%r0
+ nop
+ ldw 20(%r4),%r26
+ ldw 24(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl _obstack_newchunk,%r2
+ nop
+ copy %r0,%r19
+ bl,n L$0046,%r0
+L$0045:
+ copy %r0,%r19
+L$0046:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r20),%r21
+ ldw 24(%r4),%r22
+ add %r21,%r22,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 16(%r4),%r19
+ stw %r19,28(%r4)
+ ldw 28(%r4),%r19
+ ldw 8(%r19),%r20
+ stw %r20,32(%r4)
+ ldw 28(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 32(%r4),%r19
+ comclr,= %r20,%r19,%r0
+ bl L$0047,%r0
+ nop
+ ldw 28(%r4),%r19
+ ldw 40(%r19),%r20
+ copy %r20,%r21
+ depi -1,1,1,%r21
+ stw %r21,40(%r19)
+L$0047:
+ ldw 28(%r4),%r19
+ ldw 28(%r4),%r20
+ ldw 28(%r4),%r21
+ ldw 12(%r20),%r20
+ ldw 24(%r21),%r21
+ add %r20,%r21,%r20
+ ldw 28(%r4),%r21
+ ldw 24(%r21),%r22
+ uaddcm %r0,%r22,%r21
+ and %r20,%r21,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 28(%r4),%r19
+ ldw 28(%r4),%r20
+ ldw 12(%r19),%r19
+ ldw 4(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 28(%r4),%r20
+ ldw 28(%r4),%r21
+ ldw 16(%r20),%r20
+ ldw 4(%r21),%r21
+ sub %r20,%r21,%r20
+ comclr,> %r19,%r20,%r0
+ bl L$0048,%r0
+ nop
+ ldw 28(%r4),%r19
+ ldw 28(%r4),%r20
+ ldw 16(%r20),%r21
+ stw %r21,12(%r19)
+ copy %r21,%r19
+ bl,n L$0049,%r0
+L$0048:
+ copy %r0,%r19
+L$0049:
+ ldw 28(%r4),%r19
+ ldw 28(%r4),%r20
+ ldw 12(%r20),%r21
+ stw %r21,8(%r19)
+ ldw 32(%r4),%r10
+ bl,n L$0051,%r0
+L$0050:
+ ldo 16(%r0),%r26
+ .CALL ARGW0=GR
+ bl xmalloc,%r2
+ nop
+ copy %r28,%r10
+L$0051:
+ stw %r10,36(%r9)
+ ldw 8(%r4),%r19
+ ldw 12(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ stw %r28,12(%r4)
+ ldw 12(%r4),%r19
+ ldo 11(%r0),%r20
+ stw %r20,0(%r19)
+ ldw 12(%r4),%r19
+ addil L'builtin_type_int-$global$,%r27
+ ldw R'builtin_type_int-$global$(%r1),%r20
+ stw %r20,16(%r19)
+ ldw 12(%r4),%r19
+ ldo 4(%r0),%r20
+ stw %r20,8(%r19)
+ ldw 12(%r4),%r19
+ ldo 2(%r0),%r20
+ sth %r20,34(%r19)
+ ldw 12(%r4),%r9
+ ldw 12(%r4),%r19
+ ldw 12(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0057,%r0
+ nop
+ ldw 12(%r4),%r19
+ ldw 12(%r19),%r20
+ ldo 120(%r20),%r19
+ stw %r19,36(%r4)
+ ldw 36(%r4),%r19
+ stw %r19,40(%r4)
+ ldo 32(%r0),%r19
+ stw %r19,44(%r4)
+ ldw 40(%r4),%r19
+ ldw 40(%r4),%r20
+ ldw 16(%r19),%r19
+ ldw 12(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 44(%r4),%r20
+ comclr,< %r19,%r20,%r0
+ bl L$0052,%r0
+ nop
+ ldw 40(%r4),%r26
+ ldw 44(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl _obstack_newchunk,%r2
+ nop
+ copy %r0,%r19
+ bl,n L$0053,%r0
+L$0052:
+ copy %r0,%r19
+L$0053:
+ ldw 40(%r4),%r19
+ ldw 40(%r4),%r20
+ ldw 12(%r20),%r21
+ ldw 44(%r4),%r22
+ add %r21,%r22,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 36(%r4),%r19
+ stw %r19,48(%r4)
+ ldw 48(%r4),%r19
+ ldw 8(%r19),%r20
+ stw %r20,52(%r4)
+ ldw 48(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 52(%r4),%r19
+ comclr,= %r20,%r19,%r0
+ bl L$0054,%r0
+ nop
+ ldw 48(%r4),%r19
+ ldw 40(%r19),%r20
+ copy %r20,%r21
+ depi -1,1,1,%r21
+ stw %r21,40(%r19)
+L$0054:
+ ldw 48(%r4),%r19
+ ldw 48(%r4),%r20
+ ldw 48(%r4),%r21
+ ldw 12(%r20),%r20
+ ldw 24(%r21),%r21
+ add %r20,%r21,%r20
+ ldw 48(%r4),%r21
+ ldw 24(%r21),%r22
+ uaddcm %r0,%r22,%r21
+ and %r20,%r21,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 48(%r4),%r19
+ ldw 48(%r4),%r20
+ ldw 12(%r19),%r19
+ ldw 4(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 48(%r4),%r20
+ ldw 48(%r4),%r21
+ ldw 16(%r20),%r20
+ ldw 4(%r21),%r21
+ sub %r20,%r21,%r20
+ comclr,> %r19,%r20,%r0
+ bl L$0055,%r0
+ nop
+ ldw 48(%r4),%r19
+ ldw 48(%r4),%r20
+ ldw 16(%r20),%r21
+ stw %r21,12(%r19)
+ copy %r21,%r19
+ bl,n L$0056,%r0
+L$0055:
+ copy %r0,%r19
+L$0056:
+ ldw 48(%r4),%r19
+ ldw 48(%r4),%r20
+ ldw 12(%r20),%r21
+ stw %r21,8(%r19)
+ ldw 52(%r4),%r10
+ bl,n L$0058,%r0
+L$0057:
+ ldo 32(%r0),%r26
+ .CALL ARGW0=GR
+ bl xmalloc,%r2
+ nop
+ copy %r28,%r10
+L$0058:
+ stw %r10,36(%r9)
+ ldw 12(%r4),%r19
+ ldw 36(%r19),%r20
+ stw %r0,0(%r20)
+ ldw 12(%r4),%r19
+ ldo 16(%r0),%r20
+ ldw 36(%r19),%r21
+ add %r20,%r21,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldo -1(%r20),%r21
+ stw %r21,0(%r19)
+ ldw 12(%r4),%r20
+ ldw 36(%r20),%r19
+ addil L'builtin_type_int-$global$,%r27
+ ldw R'builtin_type_int-$global$(%r1),%r20
+ stw %r20,8(%r19)
+ ldw 12(%r4),%r19
+ ldo 16(%r0),%r20
+ ldw 36(%r19),%r21
+ add %r20,%r21,%r19
+ addil L'builtin_type_int-$global$,%r27
+ ldw R'builtin_type_int-$global$(%r1),%r20
+ stw %r20,8(%r19)
+ ldw 8(%r4),%r19
+ ldw 36(%r19),%r20
+ ldw 12(%r4),%r19
+ stw %r19,8(%r20)
+ ldw 8(%r4),%r19
+ ldo -1(%r0),%r20
+ stw %r20,44(%r19)
+ ldw 8(%r4),%r28
+ bl,n L$0044,%r0
+L$0044:
+ ldw 56(%r4),%r10
+ ldw 60(%r4),%r9
+ ldw 64(%r4),%r8
+ ldw 68(%r4),%r7
+ ldw 72(%r4),%r6
+ ldw 76(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT smash_to_member_type,CODE
+ .EXPORT smash_to_member_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR
+smash_to_member_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r10,16(%r4)
+ stw %r9,20(%r4)
+ stw %r8,24(%r4)
+ stw %r7,28(%r4)
+ stw %r6,32(%r4)
+ stw %r5,36(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r20
+ stw %r20,8(%r4)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ copy %r0,%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ stw %r20,12(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -12(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,16(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,40(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo 1(%r0),%r20
+ stw %r20,8(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo 14(%r0),%r20
+ stw %r20,0(%r19)
+L$0059:
+ ldw 16(%r4),%r10
+ ldw 20(%r4),%r9
+ ldw 24(%r4),%r8
+ ldw 28(%r4),%r7
+ ldw 32(%r4),%r6
+ ldw 36(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT smash_to_method_type,CODE
+ .EXPORT smash_to_method_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+smash_to_method_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r12,16(%r4)
+ stw %r11,20(%r4)
+ stw %r10,24(%r4)
+ stw %r9,28(%r4)
+ stw %r8,32(%r4)
+ stw %r7,36(%r4)
+ stw %r6,40(%r4)
+ stw %r5,44(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -16(%r0),%r11
+ ldo -32(%r4),%r19
+ add %r19,%r11,%r12
+ stw %r23,0(%r12)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r20
+ stw %r20,8(%r4)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ copy %r0,%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ stw %r20,12(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -12(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,16(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,40(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -16(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,48(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo 1(%r0),%r20
+ stw %r20,8(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo 15(%r0),%r20
+ stw %r20,0(%r19)
+L$0060:
+ ldw 16(%r4),%r12
+ ldw 20(%r4),%r11
+ ldw 24(%r4),%r10
+ ldw 28(%r4),%r9
+ ldw 32(%r4),%r8
+ ldw 36(%r4),%r7
+ ldw 40(%r4),%r6
+ ldw 44(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT strncmp,CODE
+ .align 4
+LC$0000:
+ .STRING "struct \x00"
+ .align 4
+LC$0001:
+ .STRING "union \x00"
+ .align 4
+LC$0002:
+ .STRING "enum \x00"
+ .align 4
+ .EXPORT type_name_no_tag,CODE
+ .EXPORT type_name_no_tag,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+type_name_no_tag:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,8(%r4)
+ stw %r5,12(%r4)
+ copy %r26,%r5
+ ldw 4(%r5),%r6
+ comiclr,<> 0,%r6,%r0
+ bl L$0062,%r0
+ nop
+ ldw 0(%r5),%r19
+ comiclr,<> 4,%r19,%r0
+ bl L$0066,%r0
+ nop
+ comiclr,>= 4,%r19,%r0
+ bl L$0072,%r0
+ nop
+ comiclr,<> 3,%r19,%r0
+ bl L$0064,%r0
+ nop
+ bl,n L$0070,%r0
+L$0072:
+ comiclr,<> 5,%r19,%r0
+ bl L$0068,%r0
+ nop
+ bl,n L$0070,%r0
+L$0064:
+ copy %r6,%r26
+ ldil L'LC$0000,%r25
+ ldo R'LC$0000(%r25),%r25
+ ldo 7(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl strncmp,%r2
+ nop
+ copy %r28,%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0065,%r0
+ nop
+ ldo 7(%r6),%r6
+L$0065:
+ bl,n L$0063,%r0
+L$0066:
+ copy %r6,%r26
+ ldil L'LC$0001,%r25
+ ldo R'LC$0001(%r25),%r25
+ ldo 6(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl strncmp,%r2
+ nop
+ copy %r28,%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0067,%r0
+ nop
+ ldo 6(%r6),%r6
+L$0067:
+ bl,n L$0063,%r0
+L$0068:
+ copy %r6,%r26
+ ldil L'LC$0002,%r25
+ ldo R'LC$0002(%r25),%r25
+ ldo 5(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl strncmp,%r2
+ nop
+ copy %r28,%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0069,%r0
+ nop
+ ldo 5(%r6),%r6
+L$0069:
+ bl,n L$0063,%r0
+L$0070:
+ bl,n L$0063,%r0
+L$0063:
+L$0062:
+ copy %r6,%r28
+ bl,n L$0061,%r0
+L$0061:
+ ldw 8(%r4),%r6
+ ldw 12(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT current_language,DATA
+ .IMPORT strcmp,CODE
+ .align 4
+ .EXPORT lookup_primitive_typename,CODE
+ .EXPORT lookup_primitive_typename,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+lookup_primitive_typename:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ addil L'current_language-$global$,%r27
+ ldw R'current_language-$global$(%r1),%r19
+ ldw 8(%r19),%r20
+ stw %r20,8(%r4)
+L$0074:
+ ldw 8(%r4),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0075,%r0
+ nop
+ ldw 8(%r4),%r19
+ ldw 0(%r19),%r20
+ ldw 0(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 4(%r19),%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2
+ nop
+ copy %r28,%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0077,%r0
+ nop
+ ldw 8(%r4),%r19
+ ldw 0(%r19),%r20
+ ldw 0(%r20),%r28
+ bl,n L$0073,%r0
+L$0077:
+L$0076:
+ ldw 8(%r4),%r19
+ ldo 4(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0074,%r0
+L$0075:
+ copy %r0,%r28
+ bl,n L$0073,%r0
+L$0073:
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT lookup_symbol,CODE
+ .IMPORT error,CODE
+ .align 4
+LC$0003:
+ .STRING "No type named %s.\x00"
+ .align 4
+ .EXPORT lookup_typename,CODE
+ .EXPORT lookup_typename,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR
+lookup_typename:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r12,8(%r4)
+ stw %r11,12(%r4)
+ stw %r10,16(%r4)
+ stw %r9,20(%r4)
+ stw %r8,24(%r4)
+ stw %r7,28(%r4)
+ stw %r6,32(%r4)
+ stw %r5,36(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ stw %r0,-52(%r30)
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ ldo 1(%r0),%r24
+ copy %r0,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl lookup_symbol,%r2
+ nop
+ copy %r28,%r11
+ comiclr,<> 0,%r11,%r0
+ bl L$0080,%r0
+ nop
+ ldw 8(%r11),%r19
+ comiclr,= 8,%r19,%r0
+ bl L$0080,%r0
+ nop
+ bl,n L$0079,%r0
+L$0080:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl lookup_primitive_typename,%r2
+ nop
+ copy %r28,%r12
+ comiclr,<> 0,%r12,%r0
+ bl L$0081,%r0
+ nop
+ copy %r12,%r28
+ bl,n L$0078,%r0
+ bl,n L$0082,%r0
+L$0081:
+ comiclr,= 0,%r12,%r0
+ bl L$0083,%r0
+ nop
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0083,%r0
+ nop
+ copy %r0,%r28
+ bl,n L$0078,%r0
+ bl,n L$0084,%r0
+L$0083:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0003,%r26
+ ldo R'LC$0003(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0084:
+L$0082:
+L$0079:
+ ldw 12(%r11),%r28
+ bl,n L$0078,%r0
+L$0078:
+ ldw 8(%r4),%r12
+ ldw 12(%r4),%r11
+ ldw 16(%r4),%r10
+ ldw 20(%r4),%r9
+ ldw 24(%r4),%r8
+ ldw 28(%r4),%r7
+ ldw 32(%r4),%r6
+ ldw 36(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT alloca,CODE
+ .IMPORT strlen,CODE
+ .IMPORT strcpy,CODE
+ .align 4
+LC$0004:
+ .STRING "unsigned \x00"
+ .align 4
+ .EXPORT lookup_unsigned_typename,CODE
+ .EXPORT lookup_unsigned_typename,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+lookup_unsigned_typename:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl strlen,%r2
+ nop
+ copy %r28,%r19
+ ldo 10(%r19),%r20
+ ldo 7(%r20),%r21
+ copy %r21,%r19
+ ldo 63(%r19),%r20
+ extru %r20,25,26,%r19
+ zdep %r19,25,26,%r20
+ ldo -96(%r30),%r19
+ add %r30,%r20,%r30
+ ldo 7(%r19),%r20
+ extru %r20,28,29,%r19
+ zdep %r19,28,29,%r20
+ stw %r20,8(%r4)
+ ldw 8(%r4),%r26
+ ldil L'LC$0004,%r25
+ ldo R'LC$0004(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcpy,%r2
+ nop
+ ldw 8(%r4),%r20
+ ldo 9(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ copy %r19,%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcpy,%r2
+ nop
+ ldw 8(%r4),%r26
+ copy %r0,%r25
+ copy %r0,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl lookup_typename,%r2
+ nop
+ bl,n L$0085,%r0
+L$0085:
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0005:
+ .STRING "signed \x00"
+ .align 4
+ .EXPORT lookup_signed_typename,CODE
+ .EXPORT lookup_signed_typename,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+lookup_signed_typename:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl strlen,%r2
+ nop
+ copy %r28,%r19
+ ldo 8(%r19),%r20
+ ldo 7(%r20),%r21
+ copy %r21,%r19
+ ldo 63(%r19),%r20
+ extru %r20,25,26,%r19
+ zdep %r19,25,26,%r20
+ ldo -96(%r30),%r19
+ add %r30,%r20,%r30
+ ldo 7(%r19),%r20
+ extru %r20,28,29,%r19
+ zdep %r19,28,29,%r20
+ stw %r20,12(%r4)
+ ldw 12(%r4),%r26
+ ldil L'LC$0005,%r25
+ ldo R'LC$0005(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcpy,%r2
+ nop
+ ldw 12(%r4),%r20
+ ldo 7(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ copy %r19,%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcpy,%r2
+ nop
+ ldw 12(%r4),%r26
+ copy %r0,%r25
+ ldo 1(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl lookup_typename,%r2
+ nop
+ stw %r28,8(%r4)
+ ldw 8(%r4),%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0087,%r0
+ nop
+ ldw 8(%r4),%r28
+ bl,n L$0086,%r0
+L$0087:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ copy %r0,%r25
+ copy %r0,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl lookup_typename,%r2
+ nop
+ bl,n L$0086,%r0
+L$0086:
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0006:
+ .STRING "No struct type named %s.\x00"
+ .align 4
+LC$0007:
+ .STRING "This context has class, union or enum %s, not a struct.\x00"
+ .align 4
+ .EXPORT lookup_struct,CODE
+ .EXPORT lookup_struct,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+lookup_struct:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r9,8(%r4)
+ stw %r8,12(%r4)
+ stw %r7,16(%r4)
+ stw %r6,20(%r4)
+ stw %r5,24(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ stw %r0,-52(%r30)
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ ldo 2(%r0),%r24
+ copy %r0,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl lookup_symbol,%r2
+ nop
+ copy %r28,%r9
+ comiclr,= 0,%r9,%r0
+ bl L$0089,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0006,%r26
+ ldo R'LC$0006(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0089:
+ ldw 12(%r9),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 3,%r20,%r0
+ bl L$0090,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0007,%r26
+ ldo R'LC$0007(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0090:
+ ldw 12(%r9),%r28
+ bl,n L$0088,%r0
+L$0088:
+ ldw 8(%r4),%r9
+ ldw 12(%r4),%r8
+ ldw 16(%r4),%r7
+ ldw 20(%r4),%r6
+ ldw 24(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0008:
+ .STRING "No union type named %s.\x00"
+ .align 4
+LC$0009:
+ .STRING "This context has class, struct or enum %s, not a union.\x00"
+ .align 4
+ .EXPORT lookup_union,CODE
+ .EXPORT lookup_union,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+lookup_union:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r9,8(%r4)
+ stw %r8,12(%r4)
+ stw %r7,16(%r4)
+ stw %r6,20(%r4)
+ stw %r5,24(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ stw %r0,-52(%r30)
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ ldo 2(%r0),%r24
+ copy %r0,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl lookup_symbol,%r2
+ nop
+ copy %r28,%r9
+ comiclr,= 0,%r9,%r0
+ bl L$0092,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0008,%r26
+ ldo R'LC$0008(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0092:
+ ldw 12(%r9),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 4,%r20,%r0
+ bl L$0093,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0009,%r26
+ ldo R'LC$0009(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0093:
+ ldw 12(%r9),%r28
+ bl,n L$0091,%r0
+L$0091:
+ ldw 8(%r4),%r9
+ ldw 12(%r4),%r8
+ ldw 16(%r4),%r7
+ ldw 20(%r4),%r6
+ ldw 24(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0010:
+ .STRING "No enum type named %s.\x00"
+ .align 4
+LC$0011:
+ .STRING "This context has class, struct or union %s, not an enum.\x00"
+ .align 4
+ .EXPORT lookup_enum,CODE
+ .EXPORT lookup_enum,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+lookup_enum:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r9,8(%r4)
+ stw %r8,12(%r4)
+ stw %r7,16(%r4)
+ stw %r6,20(%r4)
+ stw %r5,24(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ stw %r0,-52(%r30)
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ ldo 2(%r0),%r24
+ copy %r0,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl lookup_symbol,%r2
+ nop
+ copy %r28,%r9
+ comiclr,= 0,%r9,%r0
+ bl L$0095,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0010,%r26
+ ldo R'LC$0010(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0095:
+ ldw 12(%r9),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 5,%r20,%r0
+ bl L$0096,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0011,%r26
+ ldo R'LC$0011(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0096:
+ ldw 12(%r9),%r28
+ bl,n L$0094,%r0
+L$0094:
+ ldw 8(%r4),%r9
+ ldw 12(%r4),%r8
+ ldw 16(%r4),%r7
+ ldw 20(%r4),%r6
+ ldw 24(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT strcat,CODE
+ .align 4
+LC$0012:
+ .STRING "<\x00"
+ .align 4
+LC$0013:
+ .STRING " >\x00"
+ .align 4
+LC$0014:
+ .STRING "No template type named %s.\x00"
+ .align 4
+ .EXPORT lookup_template_type,CODE
+ .EXPORT lookup_template_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR
+lookup_template_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r11,16(%r4)
+ stw %r10,20(%r4)
+ stw %r9,24(%r4)
+ stw %r8,28(%r4)
+ stw %r7,32(%r4)
+ stw %r6,36(%r4)
+ stw %r5,40(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl strlen,%r2
+ nop
+ copy %r28,%r11
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 4(%r19),%r26
+ .CALL ARGW0=GR
+ bl strlen,%r2
+ nop
+ copy %r28,%r19
+ add %r11,%r19,%r20
+ ldo 4(%r20),%r19
+ ldo 7(%r19),%r20
+ copy %r20,%r19
+ ldo 63(%r19),%r20
+ extru %r20,25,26,%r19
+ zdep %r19,25,26,%r20
+ ldo -96(%r30),%r19
+ add %r30,%r20,%r30
+ ldo 7(%r19),%r20
+ extru %r20,28,29,%r19
+ zdep %r19,28,29,%r20
+ stw %r20,12(%r4)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 12(%r4),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcpy,%r2
+ nop
+ ldw 12(%r4),%r26
+ ldil L'LC$0012,%r25
+ ldo R'LC$0012(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcat,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r4),%r26
+ ldw 4(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcat,%r2
+ nop
+ ldw 12(%r4),%r26
+ ldil L'LC$0013,%r25
+ ldo R'LC$0013(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcat,%r2
+ nop
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ stw %r0,-52(%r30)
+ ldw 12(%r4),%r26
+ ldw 0(%r19),%r25
+ ldo 1(%r0),%r24
+ copy %r0,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl lookup_symbol,%r2
+ nop
+ stw %r28,8(%r4)
+ ldw 8(%r4),%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0098,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0014,%r26
+ ldo R'LC$0014(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0098:
+ ldw 8(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 0(%r20),%r19
+ comiclr,<> 3,%r19,%r0
+ bl L$0099,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0007,%r26
+ ldo R'LC$0007(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0099:
+ ldw 8(%r4),%r19
+ ldw 12(%r19),%r28
+ bl,n L$0097,%r0
+L$0097:
+ ldw 16(%r4),%r11
+ ldw 20(%r4),%r10
+ ldw 24(%r4),%r9
+ ldw 28(%r4),%r8
+ ldw 32(%r4),%r7
+ ldw 36(%r4),%r6
+ ldw 40(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT current_target,DATA
+ .IMPORT fflush,CODE
+ .IMPORT __iob,DATA
+ .IMPORT fprintf,CODE
+ .align 4
+LC$0015:
+ .STRING "Type \x00"
+ .IMPORT type_print,CODE
+ .align 4
+LC$0016:
+ .STRING "\x00"
+ .align 4
+LC$0017:
+ .STRING " is not a structure or union type.\x00"
+ .IMPORT check_stub_type,CODE
+ .align 4
+LC$0018:
+ .STRING " has no component named \x00"
+ .IMPORT fputs_filtered,CODE
+ .align 4
+LC$0019:
+ .STRING ".\x00"
+ .align 4
+ .EXPORT lookup_struct_elt_type,CODE
+ .EXPORT lookup_struct_elt_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR
+lookup_struct_elt_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r11,24(%r4)
+ stw %r10,28(%r4)
+ stw %r9,32(%r4)
+ stw %r8,36(%r4)
+ stw %r7,40(%r4)
+ stw %r6,44(%r4)
+ stw %r5,48(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 1,%r20,%r0
+ bl L$0102,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ ldo 16(%r0),%r19
+ comclr,<> %r20,%r19,%r0
+ bl L$0102,%r0
+ nop
+ bl,n L$0101,%r0
+L$0102:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 16(%r20),%r21
+ stw %r21,0(%r19)
+L$0101:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 3,%r20,%r0
+ bl L$0103,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 4,%r20,%r0
+ bl L$0103,%r0
+ nop
+ addil L'current_target-$global$,%r27
+ ldw R'current_target-$global$(%r1),%r19
+ ldw 76(%r19),%r11
+ copy %r11,%r22
+ .CALL ARGW0=GR
+ bl $$dyncall,%r31
+ copy %r31,%r2
+ addil L'__iob-$global$+16,%r27
+ ldo R'__iob-$global$+16(%r1),%r26
+ .CALL ARGW0=GR
+ bl fflush,%r2
+ nop
+ addil L'__iob-$global$+32,%r27
+ ldo R'__iob-$global$+32(%r1),%r26
+ ldil L'LC$0015,%r25
+ ldo R'LC$0015(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl fprintf,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ ldil L'LC$0016,%r25
+ ldo R'LC$0016(%r25),%r25
+ addil L'__iob-$global$+32,%r27
+ ldo R'__iob-$global$+32(%r1),%r24
+ ldo -1(%r0),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl type_print,%r2
+ nop
+ ldil L'LC$0017,%r26
+ ldo R'LC$0017(%r26),%r26
+ .CALL ARGW0=GR
+ bl error,%r2
+ nop
+L$0103:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl check_stub_type,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 34(%r19),%r20
+ extrs %r20,31,16,%r19
+ ldo -1(%r19),%r20
+ stw %r20,8(%r4)
+L$0104:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldh 0(%r20),%r21
+ extrs %r21,31,16,%r19
+ ldw 8(%r4),%r20
+ comclr,>= %r20,%r19,%r0
+ bl L$0105,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldw 12(%r19),%r20
+ stw %r20,12(%r4)
+ ldw 12(%r4),%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0107,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 12(%r4),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2
+ nop
+ copy %r28,%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0107,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldw 8(%r19),%r28
+ bl,n L$0100,%r0
+L$0107:
+L$0106:
+ ldw 8(%r4),%r19
+ ldo -1(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0104,%r0
+L$0105:
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldh 0(%r20),%r21
+ extrs %r21,31,16,%r19
+ ldo -1(%r19),%r20
+ stw %r20,8(%r4)
+L$0108:
+ ldw 8(%r4),%r19
+ comiclr,<= 0,%r19,%r0
+ bl L$0109,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 8(%r19),%r26
+ ldw 0(%r20),%r25
+ copy %r0,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl lookup_struct_elt_type,%r2
+ nop
+ stw %r28,16(%r4)
+ ldw 16(%r4),%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0111,%r0
+ nop
+ ldw 16(%r4),%r28
+ bl,n L$0100,%r0
+L$0111:
+L$0110:
+ ldw 8(%r4),%r19
+ ldo -1(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0108,%r0
+L$0109:
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0112,%r0
+ nop
+ copy %r0,%r28
+ bl,n L$0100,%r0
+L$0112:
+ addil L'current_target-$global$,%r27
+ ldw R'current_target-$global$(%r1),%r19
+ ldw 76(%r19),%r11
+ copy %r11,%r22
+ .CALL ARGW0=GR
+ bl $$dyncall,%r31
+ copy %r31,%r2
+ addil L'__iob-$global$+16,%r27
+ ldo R'__iob-$global$+16(%r1),%r26
+ .CALL ARGW0=GR
+ bl fflush,%r2
+ nop
+ addil L'__iob-$global$+32,%r27
+ ldo R'__iob-$global$+32(%r1),%r26
+ ldil L'LC$0015,%r25
+ ldo R'LC$0015(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl fprintf,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ ldil L'LC$0016,%r25
+ ldo R'LC$0016(%r25),%r25
+ addil L'__iob-$global$+32,%r27
+ ldo R'__iob-$global$+32(%r1),%r24
+ ldo -1(%r0),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl type_print,%r2
+ nop
+ addil L'__iob-$global$+32,%r27
+ ldo R'__iob-$global$+32(%r1),%r26
+ ldil L'LC$0018,%r25
+ ldo R'LC$0018(%r25),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl fprintf,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ addil L'__iob-$global$+32,%r27
+ ldo R'__iob-$global$+32(%r1),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl fputs_filtered,%r2
+ nop
+ ldil L'LC$0019,%r26
+ ldo R'LC$0019(%r26),%r26
+ .CALL ARGW0=GR
+ bl error,%r2
+ nop
+ ldo -1(%r0),%r28
+ bl,n L$0100,%r0
+L$0100:
+ ldw 24(%r4),%r11
+ ldw 28(%r4),%r10
+ ldw 32(%r4),%r9
+ ldw 36(%r4),%r8
+ ldw 40(%r4),%r7
+ ldw 44(%r4),%r6
+ ldw 48(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT fill_in_vptr_fieldno,CODE
+ .EXPORT fill_in_vptr_fieldno,ENTRY,PRIV_LEV=3,ARGW0=GR
+fill_in_vptr_fieldno:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 44(%r19),%r20
+ comiclr,> 0,%r20,%r0
+ bl L$0114,%r0
+ nop
+ ldo 1(%r0),%r19
+ stw %r19,8(%r4)
+L$0115:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldh 0(%r20),%r21
+ extrs %r21,31,16,%r19
+ ldw 8(%r4),%r20
+ comclr,< %r20,%r19,%r0
+ bl L$0116,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldw 8(%r19),%r26
+ .CALL ARGW0=GR
+ bl fill_in_vptr_fieldno,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldw 8(%r19),%r20
+ ldw 44(%r20),%r19
+ comiclr,<= 0,%r19,%r0
+ bl L$0118,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 8(%r4),%r21
+ zdep %r21,27,28,%r22
+ ldw 36(%r20),%r21
+ add %r22,%r21,%r20
+ ldw 8(%r20),%r21
+ ldw 44(%r21),%r20
+ stw %r20,44(%r19)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 8(%r4),%r21
+ zdep %r21,27,28,%r22
+ ldw 36(%r20),%r21
+ add %r22,%r21,%r20
+ ldw 8(%r20),%r21
+ ldw 40(%r21),%r20
+ stw %r20,40(%r19)
+ bl,n L$0116,%r0
+L$0118:
+L$0117:
+ ldw 8(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0115,%r0
+L$0116:
+L$0114:
+L$0113:
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .EXPORT stub_noname_complaint,DATA
+ .align 4
+LC$0020:
+ .STRING "stub type has NULL name\x00"
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+stub_noname_complaint:
+ .word LC$0020
+ .word 0
+ .word 0
+ .IMPORT complain,CODE
+ .IMPORT memcpy,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT check_stub_type,CODE
+ .EXPORT check_stub_type,ENTRY,PRIV_LEV=3,ARGW0=GR
+check_stub_type:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 32(%r19),%r20
+ ldo 4(%r0),%r21
+ and %r20,%r21,%r19
+ extrs %r19,31,16,%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0120,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl type_name_no_tag,%r2
+ nop
+ stw %r28,8(%r4)
+ ldw 8(%r4),%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0121,%r0
+ nop
+ addil L'stub_noname_complaint-$global$,%r27
+ ldo R'stub_noname_complaint-$global$(%r1),%r26
+ copy %r0,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl complain,%r2
+ nop
+ bl,n L$0119,%r0
+L$0121:
+ stw %r0,-52(%r30)
+ ldw 8(%r4),%r26
+ copy %r0,%r25
+ ldo 2(%r0),%r24
+ copy %r0,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl lookup_symbol,%r2
+ nop
+ stw %r28,12(%r4)
+ ldw 12(%r4),%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0122,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 12(%r4),%r20
+ ldw 0(%r19),%r26
+ ldw 12(%r20),%r25
+ ldo 52(%r0),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memcpy,%r2
+ nop
+L$0122:
+L$0120:
+L$0119:
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT gdb_mangle_name,CODE
+ .IMPORT cplus_demangle,CODE
+ .align 4
+LC$0021:
+ .STRING "Internal: Cannot demangle mangled name `%s'.\x00"
+ .IMPORT strchr,CODE
+ .IMPORT parse_and_eval_type,CODE
+ .IMPORT builtin_type_void,DATA
+ .IMPORT free,CODE
+ .align 4
+ .EXPORT check_stub_method,CODE
+ .EXPORT check_stub_method,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR
+check_stub_method:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r11,64(%r4)
+ stw %r10,68(%r4)
+ stw %r9,72(%r4)
+ stw %r8,76(%r4)
+ stw %r7,80(%r4)
+ stw %r6,84(%r4)
+ stw %r5,88(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldo -12(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ ldw 0(%r21),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl gdb_mangle_name,%r2
+ nop
+ stw %r28,12(%r4)
+ ldw 12(%r4),%r26
+ ldo 3(%r0),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl cplus_demangle,%r2
+ nop
+ stw %r28,16(%r4)
+ stw %r0,28(%r4)
+ ldo 1(%r0),%r19
+ stw %r19,32(%r4)
+ ldw 16(%r4),%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0124,%r0
+ nop
+ ldil L'LC$0021,%r26
+ ldo R'LC$0021(%r26),%r26
+ ldw 12(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+L$0124:
+ ldw 16(%r4),%r26
+ ldo 40(%r0),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strchr,%r2
+ nop
+ copy %r28,%r19
+ ldo 1(%r19),%r20
+ stw %r20,20(%r4)
+ ldw 20(%r4),%r19
+ stw %r19,24(%r4)
+L$0125:
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0126,%r0
+ nop
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 40(%r0),%r20
+ comclr,= %r19,%r20,%r0
+ bl L$0127,%r0
+ nop
+ ldw 28(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,28(%r4)
+ bl,n L$0128,%r0
+L$0127:
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 41(%r0),%r20
+ comclr,= %r19,%r20,%r0
+ bl L$0129,%r0
+ nop
+ ldw 28(%r4),%r19
+ ldo -1(%r19),%r20
+ stw %r20,28(%r4)
+ bl,n L$0130,%r0
+L$0129:
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 44(%r0),%r20
+ comclr,= %r19,%r20,%r0
+ bl L$0131,%r0
+ nop
+ ldw 28(%r4),%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0131,%r0
+ nop
+ ldw 32(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,32(%r4)
+L$0131:
+L$0130:
+L$0128:
+ ldw 24(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,24(%r4)
+ bl,n L$0125,%r0
+L$0126:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0137,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r20
+ ldo 120(%r20),%r19
+ stw %r19,44(%r4)
+ ldw 44(%r4),%r19
+ stw %r19,48(%r4)
+ ldw 32(%r4),%r20
+ ldo 2(%r20),%r19
+ zdep %r19,29,30,%r20
+ stw %r20,52(%r4)
+ ldw 48(%r4),%r19
+ ldw 48(%r4),%r20
+ ldw 16(%r19),%r19
+ ldw 12(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 52(%r4),%r20
+ comclr,< %r19,%r20,%r0
+ bl L$0132,%r0
+ nop
+ ldw 48(%r4),%r26
+ ldw 52(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl _obstack_newchunk,%r2
+ nop
+ copy %r0,%r19
+ bl,n L$0133,%r0
+L$0132:
+ copy %r0,%r19
+L$0133:
+ ldw 48(%r4),%r19
+ ldw 48(%r4),%r20
+ ldw 12(%r20),%r21
+ ldw 52(%r4),%r22
+ add %r21,%r22,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 44(%r4),%r19
+ stw %r19,56(%r4)
+ ldw 56(%r4),%r19
+ ldw 8(%r19),%r20
+ stw %r20,60(%r4)
+ ldw 56(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 60(%r4),%r19
+ comclr,= %r20,%r19,%r0
+ bl L$0134,%r0
+ nop
+ ldw 56(%r4),%r19
+ ldw 40(%r19),%r20
+ copy %r20,%r21
+ depi -1,1,1,%r21
+ stw %r21,40(%r19)
+L$0134:
+ ldw 56(%r4),%r19
+ ldw 56(%r4),%r20
+ ldw 56(%r4),%r21
+ ldw 12(%r20),%r20
+ ldw 24(%r21),%r21
+ add %r20,%r21,%r20
+ ldw 56(%r4),%r21
+ ldw 24(%r21),%r22
+ uaddcm %r0,%r22,%r21
+ and %r20,%r21,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 56(%r4),%r19
+ ldw 56(%r4),%r20
+ ldw 12(%r19),%r19
+ ldw 4(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 56(%r4),%r20
+ ldw 56(%r4),%r21
+ ldw 16(%r20),%r20
+ ldw 4(%r21),%r21
+ sub %r20,%r21,%r20
+ comclr,> %r19,%r20,%r0
+ bl L$0135,%r0
+ nop
+ ldw 56(%r4),%r19
+ ldw 56(%r4),%r20
+ ldw 16(%r20),%r21
+ stw %r21,12(%r19)
+ copy %r21,%r19
+ bl,n L$0136,%r0
+L$0135:
+ copy %r0,%r19
+L$0136:
+ ldw 56(%r4),%r19
+ ldw 56(%r4),%r20
+ ldw 12(%r20),%r21
+ stw %r21,8(%r19)
+ ldw 60(%r4),%r11
+ bl,n L$0138,%r0
+L$0137:
+ ldw 32(%r4),%r20
+ ldo 2(%r20),%r19
+ zdep %r19,29,30,%r20
+ copy %r20,%r26
+ .CALL ARGW0=GR
+ bl xmalloc,%r2
+ nop
+ copy %r28,%r11
+L$0138:
+ stw %r11,36(%r4)
+ ldw 20(%r4),%r19
+ stw %r19,24(%r4)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl lookup_pointer_type,%r2
+ nop
+ copy %r28,%r19
+ ldw 36(%r4),%r20
+ stw %r19,0(%r20)
+ ldo 1(%r0),%r19
+ stw %r19,32(%r4)
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 41(%r0),%r20
+ comclr,<> %r19,%r20,%r0
+ bl L$0139,%r0
+ nop
+ stw %r0,28(%r4)
+L$0140:
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0141,%r0
+ nop
+ ldw 28(%r4),%r19
+ comiclr,>= 0,%r19,%r0
+ bl L$0142,%r0
+ nop
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 44(%r0),%r20
+ comclr,<> %r19,%r20,%r0
+ bl L$0143,%r0
+ nop
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 41(%r0),%r20
+ comclr,<> %r19,%r20,%r0
+ bl L$0143,%r0
+ nop
+ bl,n L$0142,%r0
+L$0143:
+ ldw 24(%r4),%r19
+ ldw 20(%r4),%r20
+ sub %r19,%r20,%r19
+ ldw 20(%r4),%r26
+ copy %r19,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl parse_and_eval_type,%r2
+ nop
+ copy %r28,%r19
+ ldw 32(%r4),%r20
+ zdep %r20,29,30,%r21
+ ldw 36(%r4),%r22
+ add %r21,%r22,%r20
+ stw %r19,0(%r20)
+ ldw 32(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,32(%r4)
+ ldw 24(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,20(%r4)
+L$0142:
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 40(%r0),%r20
+ comclr,= %r19,%r20,%r0
+ bl L$0144,%r0
+ nop
+ ldw 28(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,28(%r4)
+ bl,n L$0145,%r0
+L$0144:
+ ldw 24(%r4),%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 41(%r0),%r20
+ comclr,= %r19,%r20,%r0
+ bl L$0146,%r0
+ nop
+ ldw 28(%r4),%r19
+ ldo -1(%r19),%r20
+ stw %r20,28(%r4)
+L$0146:
+L$0145:
+ ldw 24(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,24(%r4)
+ bl,n L$0140,%r0
+L$0141:
+L$0139:
+ ldo -2(%r0),%r19
+ ldw 24(%r4),%r20
+ add %r19,%r20,%r19
+ ldb 0(%r19),%r20
+ extrs %r20,31,8,%r19
+ ldo 46(%r0),%r20
+ comclr,<> %r19,%r20,%r0
+ bl L$0147,%r0
+ nop
+ ldw 32(%r4),%r19
+ zdep %r19,29,30,%r20
+ ldw 36(%r4),%r21
+ add %r20,%r21,%r19
+ addil L'builtin_type_void-$global$,%r27
+ ldw R'builtin_type_void-$global$(%r1),%r20
+ stw %r20,0(%r19)
+ bl,n L$0148,%r0
+L$0147:
+ ldw 32(%r4),%r19
+ zdep %r19,29,30,%r20
+ ldw 36(%r4),%r21
+ add %r20,%r21,%r19
+ stw %r0,0(%r19)
+L$0148:
+ ldw 16(%r4),%r26
+ .CALL ARGW0=GR
+ bl free,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ zdep %r21,30,31,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 20(%r19),%r21
+ add %r20,%r21,%r19
+ ldw 8(%r19),%r20
+ stw %r20,8(%r4)
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ zdep %r20,29,30,%r19
+ add %r19,%r20,%r19
+ zdep %r19,29,30,%r19
+ ldw 8(%r4),%r20
+ add %r19,%r20,%r19
+ ldw 12(%r4),%r20
+ stw %r20,0(%r19)
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ zdep %r20,29,30,%r19
+ add %r19,%r20,%r19
+ zdep %r19,29,30,%r19
+ ldw 8(%r4),%r20
+ add %r19,%r20,%r19
+ ldw 4(%r19),%r20
+ stw %r20,40(%r4)
+ ldw 40(%r4),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ stw %r21,40(%r19)
+ ldw 40(%r4),%r19
+ ldw 36(%r4),%r20
+ stw %r20,48(%r19)
+ ldw 40(%r4),%r19
+ ldw 40(%r4),%r20
+ ldh 32(%r20),%r21
+ copy %r21,%r20
+ depi 0,29,1,%r20
+ sth %r20,32(%r19)
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ zdep %r20,29,30,%r19
+ add %r19,%r20,%r19
+ zdep %r19,29,30,%r19
+ ldw 8(%r4),%r20
+ add %r19,%r20,%r19
+ ldw 16(%r19),%r20
+ copy %r20,%r21
+ depi 0,4,1,%r21
+ stw %r21,16(%r19)
+L$0123:
+ ldw 64(%r4),%r11
+ ldw 68(%r4),%r10
+ ldw 72(%r4),%r9
+ ldw 76(%r4),%r8
+ ldw 80(%r4),%r7
+ ldw 84(%r4),%r6
+ ldw 88(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT allocate_cplus_struct_type,CODE
+ .EXPORT allocate_cplus_struct_type,ENTRY,PRIV_LEV=3,ARGW0=GR
+allocate_cplus_struct_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r8,32(%r4)
+ stw %r7,36(%r4)
+ stw %r6,40(%r4)
+ stw %r5,44(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldil L'cplus_struct_default,%r20
+ ldo R'cplus_struct_default(%r20),%r20
+ comclr,= %r19,%r20,%r0
+ bl L$0150,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r7
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0156,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 12(%r19),%r20
+ ldo 120(%r20),%r19
+ stw %r19,8(%r4)
+ ldw 8(%r4),%r19
+ stw %r19,12(%r4)
+ ldo 24(%r0),%r19
+ stw %r19,16(%r4)
+ ldw 12(%r4),%r19
+ ldw 12(%r4),%r20
+ ldw 16(%r19),%r19
+ ldw 12(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 16(%r4),%r20
+ comclr,< %r19,%r20,%r0
+ bl L$0151,%r0
+ nop
+ ldw 12(%r4),%r26
+ ldw 16(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl _obstack_newchunk,%r2
+ nop
+ copy %r0,%r19
+ bl,n L$0152,%r0
+L$0151:
+ copy %r0,%r19
+L$0152:
+ ldw 12(%r4),%r19
+ ldw 12(%r4),%r20
+ ldw 12(%r20),%r21
+ ldw 16(%r4),%r22
+ add %r21,%r22,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 8(%r4),%r19
+ stw %r19,20(%r4)
+ ldw 20(%r4),%r19
+ ldw 8(%r19),%r20
+ stw %r20,24(%r4)
+ ldw 20(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 24(%r4),%r19
+ comclr,= %r20,%r19,%r0
+ bl L$0153,%r0
+ nop
+ ldw 20(%r4),%r19
+ ldw 40(%r19),%r20
+ copy %r20,%r21
+ depi -1,1,1,%r21
+ stw %r21,40(%r19)
+L$0153:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 20(%r4),%r21
+ ldw 12(%r20),%r20
+ ldw 24(%r21),%r21
+ add %r20,%r21,%r20
+ ldw 20(%r4),%r21
+ ldw 24(%r21),%r22
+ uaddcm %r0,%r22,%r21
+ and %r20,%r21,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r19),%r19
+ ldw 4(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 20(%r4),%r20
+ ldw 20(%r4),%r21
+ ldw 16(%r20),%r20
+ ldw 4(%r21),%r21
+ sub %r20,%r21,%r20
+ comclr,> %r19,%r20,%r0
+ bl L$0154,%r0
+ nop
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 16(%r20),%r21
+ stw %r21,12(%r19)
+ copy %r21,%r19
+ bl,n L$0155,%r0
+L$0154:
+ copy %r0,%r19
+L$0155:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r20),%r21
+ stw %r21,8(%r19)
+ ldw 24(%r4),%r8
+ bl,n L$0157,%r0
+L$0156:
+ ldo 24(%r0),%r26
+ .CALL ARGW0=GR
+ bl xmalloc,%r2
+ nop
+ copy %r28,%r8
+L$0157:
+ stw %r8,48(%r7)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldil L'cplus_struct_default,%r19
+ copy %r20,%r21
+ ldo R'cplus_struct_default(%r19),%r22
+ ldws,ma 4(%r22),%r19
+ ldws,ma 4(%r22),%r20
+ stws,ma %r19,4(%r21)
+ ldws,ma 4(%r22),%r19
+ stws,ma %r20,4(%r21)
+ ldws,ma 4(%r22),%r20
+ stws,ma %r19,4(%r21)
+ ldws,ma 4(%r22),%r19
+ stws,ma %r20,4(%r21)
+ ldws,ma 4(%r22),%r20
+ stws,ma %r19,4(%r21)
+ stw %r20,0(%r21)
+L$0150:
+L$0149:
+ ldw 32(%r4),%r8
+ ldw 36(%r4),%r7
+ ldw 40(%r4),%r6
+ ldw 44(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT obsavestring,CODE
+ .align 4
+ .EXPORT init_type,CODE
+ .EXPORT init_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR
+init_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r14,8(%r4)
+ stw %r13,12(%r4)
+ stw %r12,16(%r4)
+ stw %r11,20(%r4)
+ stw %r10,24(%r4)
+ stw %r9,28(%r4)
+ stw %r8,32(%r4)
+ stw %r7,36(%r4)
+ stw %r6,40(%r4)
+ stw %r5,44(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -12(%r0),%r9
+ ldo -32(%r4),%r19
+ add %r19,%r9,%r10
+ stw %r24,0(%r10)
+ ldo -16(%r0),%r11
+ ldo -32(%r4),%r19
+ add %r19,%r11,%r12
+ stw %r23,0(%r12)
+ ldo -20(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl alloc_type,%r2
+ nop
+ copy %r28,%r13
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,0(%r13)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,8(%r13)
+ ldo -12(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldh 32(%r13),%r20
+ ldh 2(%r19),%r19
+ or %r20,%r19,%r20
+ sth %r20,32(%r13)
+ ldo -16(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0159,%r0
+ nop
+ ldo -20(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0159,%r0
+ nop
+ ldo -16(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r14
+ ldo -16(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r26
+ .CALL ARGW0=GR
+ bl strlen,%r2
+ nop
+ copy %r28,%r19
+ ldo -20(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldo 120(%r21),%r20
+ ldw 0(%r14),%r26
+ copy %r19,%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl obsavestring,%r2
+ nop
+ copy %r28,%r19
+ stw %r19,4(%r13)
+ bl,n L$0160,%r0
+L$0159:
+ ldo -16(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,4(%r13)
+L$0160:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 3,%r20,%r0
+ bl L$0162,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 4,%r20,%r0
+ bl L$0162,%r0
+ nop
+ bl,n L$0161,%r0
+L$0162:
+ ldil L'cplus_struct_default,%r19
+ ldo R'cplus_struct_default(%r19),%r19
+ stw %r19,48(%r13)
+L$0161:
+ copy %r13,%r28
+ bl,n L$0158,%r0
+L$0158:
+ ldw 8(%r4),%r14
+ ldw 12(%r4),%r13
+ ldw 16(%r4),%r12
+ ldw 20(%r4),%r11
+ ldw 24(%r4),%r10
+ ldw 28(%r4),%r9
+ ldw 32(%r4),%r8
+ ldw 36(%r4),%r7
+ ldw 40(%r4),%r6
+ ldw 44(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0022:
+ .STRING "internal error - invalid fundamental type id %d\x00"
+ .align 4
+LC$0023:
+ .STRING "internal error: unhandled type id %d\x00"
+ .align 4
+LC$0024:
+ .STRING "void\x00"
+ .align 4
+LC$0025:
+ .STRING "boolean\x00"
+ .align 4
+LC$0026:
+ .STRING "string\x00"
+ .align 4
+LC$0027:
+ .STRING "char\x00"
+ .align 4
+LC$0028:
+ .STRING "signed char\x00"
+ .align 4
+LC$0029:
+ .STRING "unsigned char\x00"
+ .align 4
+LC$0030:
+ .STRING "short\x00"
+ .align 4
+LC$0031:
+ .STRING "unsigned short\x00"
+ .align 4
+LC$0032:
+ .STRING "int\x00"
+ .align 4
+LC$0033:
+ .STRING "unsigned int\x00"
+ .align 4
+LC$0034:
+ .STRING "fixed decimal\x00"
+ .align 4
+LC$0035:
+ .STRING "long\x00"
+ .align 4
+LC$0036:
+ .STRING "unsigned long\x00"
+ .align 4
+LC$0037:
+ .STRING "long long\x00"
+ .align 4
+LC$0038:
+ .STRING "signed long long\x00"
+ .align 4
+LC$0039:
+ .STRING "unsigned long long\x00"
+ .align 4
+LC$0040:
+ .STRING "float\x00"
+ .align 4
+LC$0041:
+ .STRING "double\x00"
+ .align 4
+LC$0042:
+ .STRING "floating decimal\x00"
+ .align 4
+LC$0043:
+ .STRING "long double\x00"
+ .align 4
+LC$0044:
+ .STRING "complex\x00"
+ .align 4
+LC$0045:
+ .STRING "double complex\x00"
+ .align 4
+LC$0046:
+ .STRING "long double complex\x00"
+ .align 4
+ .EXPORT lookup_fundamental_type,CODE
+ .EXPORT lookup_fundamental_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
+lookup_fundamental_type:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r12,32(%r4)
+ stw %r11,36(%r4)
+ stw %r10,40(%r4)
+ stw %r9,44(%r4)
+ stw %r8,48(%r4)
+ stw %r7,52(%r4)
+ stw %r6,56(%r4)
+ stw %r5,60(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ copy %r0,%r9
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<= 0,%r20,%r0
+ bl L$0165,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 25(%r0),%r19
+ comclr,<= %r20,%r19,%r0
+ bl L$0165,%r0
+ nop
+ bl,n L$0164,%r0
+L$0165:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0022,%r26
+ ldo R'LC$0022(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+ bl,n L$0166,%r0
+L$0164:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 196(%r19),%r20
+ comiclr,= 0,%r20,%r0
+ bl L$0167,%r0
+ nop
+ ldo 104(%r0),%r11
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r12
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo 120(%r19),%r20
+ stw %r20,8(%r4)
+ ldw 8(%r4),%r19
+ stw %r19,12(%r4)
+ stw %r11,16(%r4)
+ ldw 12(%r4),%r19
+ ldw 12(%r4),%r20
+ ldw 16(%r19),%r19
+ ldw 12(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 16(%r4),%r20
+ comclr,< %r19,%r20,%r0
+ bl L$0168,%r0
+ nop
+ ldw 12(%r4),%r26
+ ldw 16(%r4),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl _obstack_newchunk,%r2
+ nop
+ copy %r0,%r19
+ bl,n L$0169,%r0
+L$0168:
+ copy %r0,%r19
+L$0169:
+ ldw 12(%r4),%r19
+ ldw 12(%r4),%r20
+ ldw 12(%r20),%r21
+ ldw 16(%r4),%r22
+ add %r21,%r22,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 8(%r4),%r19
+ stw %r19,20(%r4)
+ ldw 20(%r4),%r19
+ ldw 8(%r19),%r20
+ stw %r20,24(%r4)
+ ldw 20(%r4),%r19
+ ldw 12(%r19),%r20
+ ldw 24(%r4),%r19
+ comclr,= %r20,%r19,%r0
+ bl L$0170,%r0
+ nop
+ ldw 20(%r4),%r19
+ ldw 40(%r19),%r20
+ copy %r20,%r21
+ depi -1,1,1,%r21
+ stw %r21,40(%r19)
+L$0170:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 20(%r4),%r21
+ ldw 12(%r20),%r20
+ ldw 24(%r21),%r21
+ add %r20,%r21,%r20
+ ldw 20(%r4),%r21
+ ldw 24(%r21),%r22
+ uaddcm %r0,%r22,%r21
+ and %r20,%r21,%r20
+ copy %r20,%r21
+ stw %r21,12(%r19)
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r19),%r19
+ ldw 4(%r20),%r20
+ sub %r19,%r20,%r19
+ ldw 20(%r4),%r20
+ ldw 20(%r4),%r21
+ ldw 16(%r20),%r20
+ ldw 4(%r21),%r21
+ sub %r20,%r21,%r20
+ comclr,> %r19,%r20,%r0
+ bl L$0171,%r0
+ nop
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 16(%r20),%r21
+ stw %r21,12(%r19)
+ copy %r21,%r19
+ bl,n L$0172,%r0
+L$0171:
+ copy %r0,%r19
+L$0172:
+ ldw 20(%r4),%r19
+ ldw 20(%r4),%r20
+ ldw 12(%r20),%r21
+ stw %r21,8(%r19)
+ ldw 24(%r4),%r19
+ stw %r19,196(%r12)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 196(%r19),%r26
+ copy %r0,%r25
+ copy %r11,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2
+ nop
+L$0167:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ zdep %r21,29,30,%r20
+ ldw 196(%r19),%r19
+ add %r20,%r19,%r10
+ ldw 0(%r10),%r9
+ comiclr,= 0,%r9,%r0
+ bl L$0173,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ addi,uv -26,%r20,%r0
+ blr,n %r20,%r0
+ b,n L$0175
+L$0202:
+ b L$0176
+ nop
+ b L$0177
+ nop
+ b L$0179
+ nop
+ b L$0180
+ nop
+ b L$0181
+ nop
+ b L$0182
+ nop
+ b L$0183
+ nop
+ b L$0184
+ nop
+ b L$0185
+ nop
+ b L$0186
+ nop
+ b L$0187
+ nop
+ b L$0189
+ nop
+ b L$0190
+ nop
+ b L$0191
+ nop
+ b L$0192
+ nop
+ b L$0193
+ nop
+ b L$0194
+ nop
+ b L$0195
+ nop
+ b L$0196
+ nop
+ b L$0198
+ nop
+ b L$0199
+ nop
+ b L$0200
+ nop
+ b L$0201
+ nop
+ b L$0178
+ nop
+ b L$0188
+ nop
+ b L$0197
+ nop
+L$0175:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldil L'LC$0023,%r26
+ ldo R'LC$0023(%r26),%r26
+ ldw 0(%r19),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl error,%r2
+ nop
+ bl,n L$0174,%r0
+L$0176:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 9(%r0),%r26
+ ldo 1(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0024,%r23
+ ldo R'LC$0024(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0177:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ ldo 1(%r0),%r24
+ ldil L'LC$0025,%r23
+ ldo R'LC$0025(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0178:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 12(%r0),%r26
+ ldo 1(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0026,%r23
+ ldo R'LC$0026(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0179:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 1(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0027,%r23
+ ldo R'LC$0027(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0180:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 1(%r0),%r25
+ ldo 2(%r0),%r24
+ ldil L'LC$0028,%r23
+ ldo R'LC$0028(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0181:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 1(%r0),%r25
+ ldo 1(%r0),%r24
+ ldil L'LC$0029,%r23
+ ldo R'LC$0029(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0182:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 2(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0030,%r23
+ ldo R'LC$0030(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0183:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 2(%r0),%r25
+ ldo 2(%r0),%r24
+ ldil L'LC$0030,%r23
+ ldo R'LC$0030(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0184:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 2(%r0),%r25
+ ldo 1(%r0),%r24
+ ldil L'LC$0031,%r23
+ ldo R'LC$0031(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0185:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0032,%r23
+ ldo R'LC$0032(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0186:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ ldo 2(%r0),%r24
+ ldil L'LC$0032,%r23
+ ldo R'LC$0032(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0187:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ ldo 1(%r0),%r24
+ ldil L'LC$0033,%r23
+ ldo R'LC$0033(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0188:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0034,%r23
+ ldo R'LC$0034(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0189:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0035,%r23
+ ldo R'LC$0035(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0190:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ ldo 2(%r0),%r24
+ ldil L'LC$0035,%r23
+ ldo R'LC$0035(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0191:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 4(%r0),%r25
+ ldo 1(%r0),%r24
+ ldil L'LC$0036,%r23
+ ldo R'LC$0036(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0192:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 8(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0037,%r23
+ ldo R'LC$0037(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0193:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 8(%r0),%r25
+ ldo 2(%r0),%r24
+ ldil L'LC$0038,%r23
+ ldo R'LC$0038(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0194:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 7(%r0),%r26
+ ldo 8(%r0),%r25
+ ldo 1(%r0),%r24
+ ldil L'LC$0039,%r23
+ ldo R'LC$0039(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0195:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 4(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0040,%r23
+ ldo R'LC$0040(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0196:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 8(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0041,%r23
+ ldo R'LC$0041(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0197:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 8(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0042,%r23
+ ldo R'LC$0042(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0198:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 16(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0043,%r23
+ ldo R'LC$0043(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0199:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 8(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0044,%r23
+ ldo R'LC$0044(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0200:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 16(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0045,%r23
+ ldo R'LC$0045(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0201:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ stw %r20,-52(%r30)
+ ldo 8(%r0),%r26
+ ldo 16(%r0),%r25
+ copy %r0,%r24
+ ldil L'LC$0046,%r23
+ ldo R'LC$0046(%r23),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl init_type,%r2
+ nop
+ copy %r28,%r9
+ bl,n L$0174,%r0
+L$0174:
+ stw %r9,0(%r10)
+L$0173:
+L$0166:
+ copy %r9,%r28
+ bl,n L$0163,%r0
+L$0163:
+ ldw 32(%r4),%r12
+ ldw 36(%r4),%r11
+ ldw 40(%r4),%r10
+ ldw 44(%r4),%r9
+ ldw 48(%r4),%r8
+ ldw 52(%r4),%r7
+ ldw 56(%r4),%r6
+ ldw 60(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT puts_filtered,CODE
+ .align 4
+LC$0047:
+ .STRING " \x00"
+ .IMPORT printf_filtered,CODE
+ .align 4
+LC$0048:
+ .STRING "1\x00"
+ .align 4
+LC$0049:
+ .STRING "0\x00"
+ .align 4
+print_bit_vector:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r8,16(%r4)
+ stw %r7,20(%r4)
+ stw %r6,24(%r4)
+ stw %r5,28(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ stw %r0,8(%r4)
+L$0204:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 8(%r4),%r20
+ ldw 0(%r19),%r19
+ comclr,< %r20,%r19,%r0
+ bl L$0205,%r0
+ nop
+ ldw 8(%r4),%r19
+ ldw 8(%r4),%r20
+ comiclr,> 0,%r19,%r0
+ bl L$0208,%r0
+ nop
+ ldo 7(%r19),%r19
+L$0208:
+ extrs %r19,28,29,%r19
+ zdep %r19,28,29,%r21
+ sub %r20,%r21,%r19
+ comiclr,= 0,%r19,%r0
+ bl L$0207,%r0
+ nop
+ ldil L'LC$0047,%r26
+ ldo R'LC$0047(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0207:
+ ldw 8(%r4),%r20
+ extrs %r20,28,29,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ add %r19,%r21,%r20
+ ldb 0(%r20),%r19
+ ldw 8(%r4),%r20
+ extru %r20,31,3,%r21
+ subi,>>= 31,%r21,%r20
+ copy %r0,%r20
+ mtsar %r20
+ vextrs %r19,32,%r19
+ extru %r19,31,1,%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0209,%r0
+ nop
+ ldil L'LC$0048,%r26
+ ldo R'LC$0048(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0210,%r0
+L$0209:
+ ldil L'LC$0049,%r26
+ ldo R'LC$0049(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+L$0210:
+L$0206:
+ ldw 8(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0204,%r0
+L$0205:
+L$0203:
+ ldw 16(%r4),%r8
+ ldw 20(%r4),%r7
+ ldw 24(%r4),%r6
+ ldw 28(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT recursive_dump_type,CODE
+ .align 4
+print_arg_types:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r8,8(%r4)
+ stw %r7,12(%r4)
+ stw %r6,16(%r4)
+ stw %r5,20(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0212,%r0
+ nop
+L$0213:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0214,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldo 2(%r21),%r20
+ ldw 0(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl recursive_dump_type,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 4(%r20),%r21
+ stw %r21,0(%r19)
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ comiclr,= 9,%r20,%r0
+ bl L$0215,%r0
+ nop
+ bl,n L$0214,%r0
+L$0215:
+ bl,n L$0213,%r0
+L$0214:
+L$0212:
+L$0211:
+ ldw 8(%r4),%r8
+ ldw 12(%r4),%r7
+ ldw 16(%r4),%r6
+ ldw 20(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .IMPORT printfi_filtered,CODE
+ .align 4
+LC$0050:
+ .STRING "fn_fieldlists 0x%x\x0a\x00"
+ .align 4
+LC$0051:
+ .STRING "[%d] name '%s' (0x%x) length %d\x0a\x00"
+ .align 4
+LC$0052:
+ .STRING "[%d] physname '%s' (0x%x)\x0a\x00"
+ .align 4
+LC$0053:
+ .STRING "type 0x%x\x0a\x00"
+ .align 4
+LC$0054:
+ .STRING "args 0x%x\x0a\x00"
+ .align 4
+LC$0055:
+ .STRING "fcontext 0x%x\x0a\x00"
+ .align 4
+LC$0056:
+ .STRING "is_const %d\x0a\x00"
+ .align 4
+LC$0057:
+ .STRING "is_volatile %d\x0a\x00"
+ .align 4
+LC$0058:
+ .STRING "is_private %d\x0a\x00"
+ .align 4
+LC$0059:
+ .STRING "is_protected %d\x0a\x00"
+ .align 4
+LC$0060:
+ .STRING "is_stub %d\x0a\x00"
+ .align 4
+LC$0061:
+ .STRING "voffset %u\x0a\x00"
+ .align 4
+dump_fn_fieldlists:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,192(%r30)
+ stw %r8,24(%r4)
+ stw %r7,28(%r4)
+ stw %r6,32(%r4)
+ stw %r5,36(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldw 48(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0050,%r25
+ ldo R'LC$0050(%r25),%r25
+ ldw 20(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ stw %r0,8(%r4)
+L$0217:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldh 2(%r20),%r21
+ extrs %r21,31,16,%r19
+ ldw 8(%r4),%r20
+ comclr,< %r20,%r19,%r0
+ bl L$0218,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldw 8(%r4),%r21
+ zdep %r21,30,31,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 20(%r19),%r21
+ add %r20,%r21,%r19
+ ldw 8(%r19),%r20
+ stw %r20,16(%r4)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 2(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldw 48(%r21),%r20
+ ldw 8(%r4),%r22
+ zdep %r22,30,31,%r21
+ add %r21,%r22,%r21
+ zdep %r21,29,30,%r21
+ ldw 20(%r20),%r22
+ add %r21,%r22,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ ldw 48(%r22),%r21
+ ldw 8(%r4),%r23
+ zdep %r23,30,31,%r22
+ add %r22,%r23,%r22
+ zdep %r22,29,30,%r22
+ ldw 20(%r21),%r23
+ add %r22,%r23,%r21
+ ldw 0(%r21),%r22
+ stw %r22,-52(%r30)
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ ldw 48(%r22),%r21
+ ldw 8(%r4),%r23
+ zdep %r23,30,31,%r22
+ add %r22,%r23,%r22
+ zdep %r22,29,30,%r22
+ ldw 20(%r21),%r23
+ add %r22,%r23,%r21
+ ldw 4(%r21),%r22
+ stw %r22,-56(%r30)
+ copy %r19,%r26
+ ldil L'LC$0051,%r25
+ ldo R'LC$0051(%r25),%r25
+ ldw 8(%r4),%r24
+ ldw 0(%r20),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ stw %r0,12(%r4)
+L$0220:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldw 8(%r4),%r21
+ zdep %r21,30,31,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 20(%r19),%r21
+ add %r20,%r21,%r19
+ ldw 12(%r4),%r20
+ ldw 4(%r19),%r19
+ comclr,< %r20,%r19,%r0
+ bl L$0221,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 4(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 12(%r4),%r22
+ zdep %r22,29,30,%r21
+ add %r21,%r22,%r21
+ zdep %r21,29,30,%r21
+ ldw 16(%r4),%r22
+ add %r21,%r22,%r21
+ ldw 0(%r21),%r22
+ stw %r22,-52(%r30)
+ copy %r19,%r26
+ ldil L'LC$0052,%r25
+ ldo R'LC$0052(%r25),%r25
+ ldw 12(%r4),%r24
+ ldw 0(%r20),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ copy %r19,%r26
+ ldil L'LC$0053,%r25
+ ldo R'LC$0053(%r25),%r25
+ ldw 4(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldw 12(%r4),%r20
+ zdep %r20,29,30,%r19
+ add %r19,%r20,%r19
+ zdep %r19,29,30,%r19
+ ldw 16(%r4),%r20
+ add %r19,%r20,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldo 10(%r21),%r20
+ ldw 4(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl recursive_dump_type,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r22
+ add %r20,%r22,%r21
+ ldw 4(%r21),%r20
+ copy %r19,%r26
+ ldil L'LC$0054,%r25
+ ldo R'LC$0054(%r25),%r25
+ ldw 48(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldw 12(%r4),%r20
+ zdep %r20,29,30,%r19
+ add %r19,%r20,%r19
+ zdep %r19,29,30,%r19
+ ldw 16(%r4),%r21
+ add %r19,%r21,%r20
+ ldw 4(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 48(%r19),%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl print_arg_types,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ copy %r19,%r26
+ ldil L'LC$0055,%r25
+ ldo R'LC$0055(%r25),%r25
+ ldw 12(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 16(%r20),%r21
+ extru %r21,0+1-1,1,%r20
+ copy %r19,%r26
+ ldil L'LC$0056,%r25
+ ldo R'LC$0056(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 16(%r20),%r21
+ extru %r21,1+1-1,1,%r20
+ copy %r19,%r26
+ ldil L'LC$0057,%r25
+ ldo R'LC$0057(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 16(%r20),%r21
+ extru %r21,2+1-1,1,%r20
+ copy %r19,%r26
+ ldil L'LC$0058,%r25
+ ldo R'LC$0058(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 16(%r20),%r21
+ extru %r21,3+1-1,1,%r20
+ copy %r19,%r26
+ ldil L'LC$0059,%r25
+ ldo R'LC$0059(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 16(%r20),%r21
+ extru %r21,4+1-1,1,%r20
+ copy %r19,%r26
+ ldil L'LC$0060,%r25
+ ldo R'LC$0060(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 8(%r20),%r19
+ ldw 12(%r4),%r21
+ zdep %r21,29,30,%r20
+ add %r20,%r21,%r20
+ zdep %r20,29,30,%r20
+ ldw 16(%r4),%r21
+ add %r20,%r21,%r20
+ ldw 16(%r20),%r21
+ extru %r21,8+24-1,24,%r22
+ ldo -2(%r22),%r20
+ copy %r19,%r26
+ ldil L'LC$0061,%r25
+ ldo R'LC$0061(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+L$0222:
+ ldw 12(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,12(%r4)
+ bl,n L$0220,%r0
+L$0221:
+L$0219:
+ ldw 8(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0217,%r0
+L$0218:
+L$0216:
+ ldw 24(%r4),%r8
+ ldw 28(%r4),%r7
+ ldw 32(%r4),%r6
+ ldw 36(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0062:
+ .STRING "n_baseclasses %d\x0a\x00"
+ .align 4
+LC$0063:
+ .STRING "nfn_fields %d\x0a\x00"
+ .align 4
+LC$0064:
+ .STRING "nfn_fields_total %d\x0a\x00"
+ .align 4
+LC$0065:
+ .STRING "virtual_field_bits (%d bits at *0x%x)\x00"
+ .align 4
+LC$0066:
+ .STRING "\x0a\x00"
+ .align 4
+LC$0067:
+ .STRING "private_field_bits (%d bits at *0x%x)\x00"
+ .align 4
+LC$0068:
+ .STRING "protected_field_bits (%d bits at *0x%x)\x00"
+ .align 4
+print_cplus_stuff:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r8,16(%r4)
+ stw %r7,20(%r4)
+ stw %r6,24(%r4)
+ stw %r5,28(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 48(%r20),%r21
+ ldh 0(%r21),%r22
+ extrs %r22,31,16,%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0062,%r25
+ ldo R'LC$0062(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 48(%r20),%r21
+ ldh 2(%r21),%r22
+ extrs %r22,31,16,%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0063,%r25
+ ldo R'LC$0063(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldw 48(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0064,%r25
+ ldo R'LC$0064(%r25),%r25
+ ldw 4(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldh 0(%r20),%r21
+ extrs %r21,31,16,%r19
+ comiclr,< 0,%r19,%r0
+ bl L$0224,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 48(%r20),%r21
+ ldh 0(%r21),%r22
+ extrs %r22,31,16,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ ldw 48(%r22),%r21
+ ldw 0(%r19),%r26
+ ldil L'LC$0065,%r25
+ ldo R'LC$0065(%r25),%r25
+ copy %r20,%r24
+ ldw 8(%r21),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 48(%r20),%r21
+ ldh 0(%r21),%r22
+ extrs %r22,31,16,%r20
+ ldw 8(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl print_bit_vector,%r2
+ nop
+ ldil L'LC$0066,%r26
+ ldo R'LC$0066(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0224:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 34(%r19),%r20
+ extrs %r20,31,16,%r19
+ comiclr,< 0,%r19,%r0
+ bl L$0225,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldw 12(%r20),%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0226,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldh 34(%r20),%r21
+ extrs %r21,31,16,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ ldw 48(%r22),%r21
+ ldw 0(%r19),%r26
+ ldil L'LC$0067,%r25
+ ldo R'LC$0067(%r25),%r25
+ copy %r20,%r24
+ ldw 12(%r21),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldh 34(%r20),%r21
+ extrs %r21,31,16,%r20
+ ldw 12(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl print_bit_vector,%r2
+ nop
+ ldil L'LC$0066,%r26
+ ldo R'LC$0066(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0226:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldw 16(%r20),%r19
+ comiclr,<> 0,%r19,%r0
+ bl L$0227,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldh 34(%r20),%r21
+ extrs %r21,31,16,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ ldw 48(%r22),%r21
+ ldw 0(%r19),%r26
+ ldil L'LC$0068,%r25
+ ldo R'LC$0068(%r25),%r25
+ copy %r20,%r24
+ ldw 16(%r21),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 48(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldh 34(%r20),%r21
+ extrs %r21,31,16,%r20
+ ldw 16(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl print_bit_vector,%r2
+ nop
+ ldil L'LC$0066,%r26
+ ldo R'LC$0066(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0227:
+L$0225:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ ldh 2(%r20),%r21
+ extrs %r21,31,16,%r19
+ comiclr,< 0,%r19,%r0
+ bl L$0228,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl dump_fn_fieldlists,%r2
+ nop
+L$0228:
+L$0223:
+ ldw 16(%r4),%r8
+ ldw 20(%r4),%r7
+ ldw 24(%r4),%r6
+ ldw 28(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .align 4
+LC$0069:
+ .STRING "type node 0x%x\x0a\x00"
+ .align 4
+LC$0070:
+ .STRING "name '%s' (0x%x)\x0a\x00"
+ .align 4
+LC$0071:
+ .STRING "<NULL>\x00"
+ .align 4
+LC$0072:
+ .STRING "code 0x%x \x00"
+ .align 4
+LC$0073:
+ .STRING "(TYPE_CODE_UNDEF)\x00"
+ .align 4
+LC$0074:
+ .STRING "(TYPE_CODE_PTR)\x00"
+ .align 4
+LC$0075:
+ .STRING "(TYPE_CODE_ARRAY)\x00"
+ .align 4
+LC$0076:
+ .STRING "(TYPE_CODE_STRUCT)\x00"
+ .align 4
+LC$0077:
+ .STRING "(TYPE_CODE_UNION)\x00"
+ .align 4
+LC$0078:
+ .STRING "(TYPE_CODE_ENUM)\x00"
+ .align 4
+LC$0079:
+ .STRING "(TYPE_CODE_FUNC)\x00"
+ .align 4
+LC$0080:
+ .STRING "(TYPE_CODE_INT)\x00"
+ .align 4
+LC$0081:
+ .STRING "(TYPE_CODE_FLT)\x00"
+ .align 4
+LC$0082:
+ .STRING "(TYPE_CODE_VOID)\x00"
+ .align 4
+LC$0083:
+ .STRING "(TYPE_CODE_SET)\x00"
+ .align 4
+LC$0084:
+ .STRING "(TYPE_CODE_RANGE)\x00"
+ .align 4
+LC$0085:
+ .STRING "(TYPE_CODE_PASCAL_ARRAY)\x00"
+ .align 4
+LC$0086:
+ .STRING "(TYPE_CODE_ERROR)\x00"
+ .align 4
+LC$0087:
+ .STRING "(TYPE_CODE_MEMBER)\x00"
+ .align 4
+LC$0088:
+ .STRING "(TYPE_CODE_METHOD)\x00"
+ .align 4
+LC$0089:
+ .STRING "(TYPE_CODE_REF)\x00"
+ .align 4
+LC$0090:
+ .STRING "(TYPE_CODE_CHAR)\x00"
+ .align 4
+LC$0091:
+ .STRING "(TYPE_CODE_BOOL)\x00"
+ .align 4
+LC$0092:
+ .STRING "(UNKNOWN TYPE CODE)\x00"
+ .align 4
+LC$0093:
+ .STRING "length %d\x0a\x00"
+ .align 4
+LC$0094:
+ .STRING "objfile 0x%x\x0a\x00"
+ .align 4
+LC$0095:
+ .STRING "target_type 0x%x\x0a\x00"
+ .align 4
+LC$0096:
+ .STRING "pointer_type 0x%x\x0a\x00"
+ .align 4
+LC$0097:
+ .STRING "reference_type 0x%x\x0a\x00"
+ .align 4
+LC$0098:
+ .STRING "function_type 0x%x\x0a\x00"
+ .align 4
+LC$0099:
+ .STRING "flags 0x%x\x00"
+ .align 4
+LC$0100:
+ .STRING " TYPE_FLAG_UNSIGNED\x00"
+ .align 4
+LC$0101:
+ .STRING " TYPE_FLAG_SIGNED\x00"
+ .align 4
+LC$0102:
+ .STRING " TYPE_FLAG_STUB\x00"
+ .align 4
+LC$0103:
+ .STRING "nfields %d 0x%x\x0a\x00"
+ .align 4
+LC$0104:
+ .STRING "[%d] bitpos %d bitsize %d type 0x%x name '%s' (0x%x)\x0a\x00"
+ .align 4
+LC$0105:
+ .STRING "vptr_basetype 0x%x\x0a\x00"
+ .align 4
+LC$0106:
+ .STRING "vptr_fieldno %d\x0a\x00"
+ .align 4
+LC$0107:
+ .STRING "arg_types 0x%x\x0a\x00"
+ .align 4
+LC$0108:
+ .STRING "cplus_stuff 0x%x\x0a\x00"
+ .align 4
+LC$0109:
+ .STRING "type_specific 0x%x\x00"
+ .align 4
+LC$0110:
+ .STRING " (unknown data form)\x00"
+ .align 4
+ .EXPORT recursive_dump_type,CODE
+ .EXPORT recursive_dump_type,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR
+recursive_dump_type:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r8,16(%r4)
+ stw %r7,20(%r4)
+ stw %r6,24(%r4)
+ stw %r5,28(%r4)
+ ldo -4(%r0),%r5
+ ldo -32(%r4),%r19
+ add %r19,%r5,%r6
+ stw %r26,0(%r6)
+ ldo -8(%r0),%r7
+ ldo -32(%r4),%r19
+ add %r19,%r7,%r8
+ stw %r25,0(%r8)
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0069,%r25
+ ldo R'LC$0069(%r25),%r25
+ ldw 0(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r22
+ add %r22,%r21,%r21
+ ldw 0(%r21),%r22
+ ldw 4(%r22),%r21
+ ldo -4(%r0),%r22
+ ldo -32(%r4),%r24
+ add %r24,%r22,%r23
+ ldw 0(%r23),%r22
+ ldw 4(%r22),%r23
+ comiclr,= 0,%r23,%r0
+ bl L$0230,%r0
+ nop
+ ldil L'LC$0071,%r21
+ ldo R'LC$0071(%r21),%r21
+L$0230:
+ ldw 0(%r19),%r26
+ ldil L'LC$0070,%r25
+ ldo R'LC$0070(%r25),%r25
+ ldw 4(%r20),%r24
+ copy %r21,%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0072,%r25
+ ldo R'LC$0072(%r25),%r25
+ ldw 0(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 0(%r19),%r20
+ addi,uv -19,%r20,%r0
+ blr,n %r20,%r0
+ b,n L$0251
+L$0252:
+ b L$0232
+ nop
+ b L$0233
+ nop
+ b L$0234
+ nop
+ b L$0235
+ nop
+ b L$0236
+ nop
+ b L$0237
+ nop
+ b L$0238
+ nop
+ b L$0239
+ nop
+ b L$0240
+ nop
+ b L$0241
+ nop
+ b L$0242
+ nop
+ b L$0243
+ nop
+ b L$0244
+ nop
+ b L$0245
+ nop
+ b L$0246
+ nop
+ b L$0247
+ nop
+ b L$0248
+ nop
+ b L$0249
+ nop
+ b L$0250
+ nop
+L$0232:
+ ldil L'LC$0073,%r26
+ ldo R'LC$0073(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0233:
+ ldil L'LC$0074,%r26
+ ldo R'LC$0074(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0234:
+ ldil L'LC$0075,%r26
+ ldo R'LC$0075(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0235:
+ ldil L'LC$0076,%r26
+ ldo R'LC$0076(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0236:
+ ldil L'LC$0077,%r26
+ ldo R'LC$0077(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0237:
+ ldil L'LC$0078,%r26
+ ldo R'LC$0078(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0238:
+ ldil L'LC$0079,%r26
+ ldo R'LC$0079(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0239:
+ ldil L'LC$0080,%r26
+ ldo R'LC$0080(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0240:
+ ldil L'LC$0081,%r26
+ ldo R'LC$0081(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0241:
+ ldil L'LC$0082,%r26
+ ldo R'LC$0082(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0242:
+ ldil L'LC$0083,%r26
+ ldo R'LC$0083(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0243:
+ ldil L'LC$0084,%r26
+ ldo R'LC$0084(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0244:
+ ldil L'LC$0085,%r26
+ ldo R'LC$0085(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0245:
+ ldil L'LC$0086,%r26
+ ldo R'LC$0086(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0246:
+ ldil L'LC$0087,%r26
+ ldo R'LC$0087(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0247:
+ ldil L'LC$0088,%r26
+ ldo R'LC$0088(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0248:
+ ldil L'LC$0089,%r26
+ ldo R'LC$0089(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0249:
+ ldil L'LC$0090,%r26
+ ldo R'LC$0090(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0250:
+ ldil L'LC$0091,%r26
+ ldo R'LC$0091(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0251:
+ ldil L'LC$0092,%r26
+ ldo R'LC$0092(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0231,%r0
+L$0231:
+ ldil L'LC$0066,%r26
+ ldo R'LC$0066(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0093,%r25
+ ldo R'LC$0093(%r25),%r25
+ ldw 8(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0094,%r25
+ ldo R'LC$0094(%r25),%r25
+ ldw 12(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0095,%r25
+ ldo R'LC$0095(%r25),%r25
+ ldw 16(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 16(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0253,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldo 2(%r21),%r20
+ ldw 16(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl recursive_dump_type,%r2
+ nop
+L$0253:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0096,%r25
+ ldo R'LC$0096(%r25),%r25
+ ldw 20(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0097,%r25
+ ldo R'LC$0097(%r25),%r25
+ ldw 24(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0098,%r25
+ ldo R'LC$0098(%r25),%r25
+ ldw 28(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldh 32(%r20),%r21
+ extrs %r21,31,16,%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0099,%r25
+ ldo R'LC$0099(%r25),%r25
+ copy %r20,%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 32(%r19),%r20
+ extru %r20,31,1,%r19
+ extrs %r19,31,16,%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0254,%r0
+ nop
+ ldil L'LC$0100,%r26
+ ldo R'LC$0100(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0254:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 32(%r19),%r20
+ ldo 2(%r0),%r21
+ and %r20,%r21,%r19
+ extrs %r19,31,16,%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0255,%r0
+ nop
+ ldil L'LC$0101,%r26
+ ldo R'LC$0101(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0255:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 32(%r19),%r20
+ ldo 4(%r0),%r21
+ and %r20,%r21,%r19
+ extrs %r19,31,16,%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0256,%r0
+ nop
+ ldil L'LC$0102,%r26
+ ldo R'LC$0102(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+L$0256:
+ ldil L'LC$0066,%r26
+ ldo R'LC$0066(%r26),%r26
+ .CALL ARGW0=GR
+ bl puts_filtered,%r2
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldh 34(%r20),%r21
+ extrs %r21,31,16,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 0(%r19),%r26
+ ldil L'LC$0103,%r25
+ ldo R'LC$0103(%r25),%r25
+ copy %r20,%r24
+ ldw 36(%r21),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ stw %r0,8(%r4)
+L$0257:
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldh 34(%r19),%r20
+ extrs %r20,31,16,%r19
+ ldw 8(%r4),%r20
+ comclr,< %r20,%r19,%r0
+ bl L$0258,%r0
+ nop
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldo 2(%r20),%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 8(%r4),%r21
+ zdep %r21,27,28,%r22
+ ldw 36(%r20),%r21
+ add %r22,%r21,%r20
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 8(%r4),%r22
+ zdep %r22,27,28,%r23
+ ldw 36(%r21),%r22
+ add %r23,%r22,%r21
+ ldw 4(%r21),%r22
+ stw %r22,-52(%r30)
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 8(%r4),%r22
+ zdep %r22,27,28,%r23
+ ldw 36(%r21),%r22
+ add %r23,%r22,%r21
+ ldw 8(%r21),%r22
+ stw %r22,-56(%r30)
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 8(%r4),%r22
+ zdep %r22,27,28,%r23
+ ldw 36(%r21),%r22
+ add %r23,%r22,%r21
+ ldw 12(%r21),%r22
+ stw %r22,-60(%r30)
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 8(%r4),%r22
+ zdep %r22,27,28,%r23
+ ldw 36(%r21),%r22
+ add %r23,%r22,%r21
+ ldw 12(%r21),%r22
+ stw %r22,-64(%r30)
+ ldo -4(%r0),%r21
+ ldo -32(%r4),%r23
+ add %r23,%r21,%r22
+ ldw 0(%r22),%r21
+ ldw 8(%r4),%r22
+ zdep %r22,27,28,%r23
+ ldw 36(%r21),%r22
+ add %r23,%r22,%r21
+ ldw 12(%r21),%r22
+ comiclr,= 0,%r22,%r0
+ bl L$0260,%r0
+ nop
+ ldil L'LC$0071,%r21
+ ldo R'LC$0071(%r21),%r21
+ stw %r21,-64(%r30)
+L$0260:
+ copy %r19,%r26
+ ldil L'LC$0104,%r25
+ ldo R'LC$0104(%r25),%r25
+ ldw 8(%r4),%r24
+ ldw 0(%r20),%r23
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldw 8(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0261,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 8(%r4),%r20
+ zdep %r20,27,28,%r21
+ ldw 36(%r19),%r20
+ add %r21,%r20,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldo 4(%r21),%r20
+ ldw 8(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl recursive_dump_type,%r2
+ nop
+L$0261:
+L$0259:
+ ldw 8(%r4),%r19
+ ldo 1(%r19),%r20
+ stw %r20,8(%r4)
+ bl,n L$0257,%r0
+L$0258:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0105,%r25
+ ldo R'LC$0105(%r25),%r25
+ ldw 40(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 40(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0262,%r0
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r20),%r21
+ ldo 2(%r21),%r20
+ ldw 40(%r19),%r26
+ copy %r20,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl recursive_dump_type,%r2
+ nop
+L$0262:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0106,%r25
+ ldo R'LC$0106(%r25),%r25
+ ldw 44(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldw 0(%r19),%r20
+ ldw 0(%r20),%r19
+ comiclr,<> 6,%r19,%r0
+ bl L$0265,%r0
+ nop
+ comiclr,>= 6,%r19,%r0
+ bl L$0270,%r0
+ nop
+ comiclr,<> 3,%r19,%r0
+ bl L$0266,%r0
+ nop
+ bl,n L$0267,%r0
+L$0270:
+ comiclr,<> 15,%r19,%r0
+ bl L$0264,%r0
+ nop
+ bl,n L$0267,%r0
+L$0264:
+L$0265:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0107,%r25
+ ldo R'LC$0107(%r25),%r25
+ ldw 48(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 48(%r19),%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl print_arg_types,%r2
+ nop
+ bl,n L$0263,%r0
+L$0266:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0108,%r25
+ ldo R'LC$0108(%r25),%r25
+ ldw 48(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -8(%r0),%r20
+ ldo -32(%r4),%r21
+ add %r21,%r20,%r20
+ ldw 0(%r19),%r26
+ ldw 0(%r20),%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl print_cplus_stuff,%r2
+ nop
+ bl,n L$0263,%r0
+L$0267:
+ ldo -8(%r0),%r19
+ ldo -32(%r4),%r20
+ add %r20,%r19,%r19
+ ldo -4(%r0),%r20
+ ldo -32(%r4),%r22
+ add %r22,%r20,%r21
+ ldw 0(%r21),%r20
+ ldw 0(%r19),%r26
+ ldil L'LC$0109,%r25
+ ldo R'LC$0109(%r25),%r25
+ ldw 48(%r20),%r24
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl printfi_filtered,%r2
+ nop
+ ldo -4(%r0),%r19
+ ldo -32(%r4),%r21
+ add %r21,%r19,%r20
+ ldw 0(%r20),%r19
+ ldw 48(%r19),%r20
+ comiclr,<> 0,%r20,%r0
+ bl L$0268,%r0
+ nop
+ ldil L'LC$0110,%r26
+ ldo R'LC$0110(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+L$0268:
+ ldil L'LC$0066,%r26
+ ldo R'LC$0066(%r26),%r26
+ .CALL ARGW0=GR
+ bl printf_filtered,%r2
+ nop
+ bl,n L$0263,%r0
+L$0263:
+L$0229:
+ ldw 16(%r4),%r8
+ ldw 20(%r4),%r7
+ ldw 24(%r4),%r6
+ ldw 28(%r4),%r5
+ ldo 8(%r4),%r30
+ ldw -28(%r30),%r2
+ bv %r0(%r2)
+ ldwm -8(%r30),%r4
+ .EXIT
+ .PROCEND
+ .SPACE $PRIVATE$
+ .SUBSPA $BSS$
+
+cplus_struct_default: .comm 24
+
diff --git a/gas/testsuite/gas/hppa/parse/global.s b/gas/testsuite/gas/hppa/parse/global.s
new file mode 100644
index 00000000000..550c4a57766
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/global.s
@@ -0,0 +1,15 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+ .IMPORT foo,data
+
+ .align 4
+; Official gas code will not accept sym-$global$.
+ addil L%foo-$global$,%r27
+
diff --git a/gas/testsuite/gas/hppa/parse/labelbug.s b/gas/testsuite/gas/hppa/parse/labelbug.s
new file mode 100644
index 00000000000..3f36a71f7eb
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/labelbug.s
@@ -0,0 +1,35 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$, SORT=8
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; A comment. This should not be interpreted as a label, but both of the
+; following statements should.
+label_without_colon
+label_with_colon:
+
+; A problem tege found...
+; Input scrubbing in gas makes life a real nightmare for assemblers
+; in which the *position* within a line determines how to interpret
+; a stream a characters. These test one particular case where gas
+; had the tendency to delete the whitespace between the opcode and
+; operands if a label without a colon began a line, and the operands
+; started with a non-numeric character.
+L$1 add %r2,%r2,%r2
+L$2: add %r2,%r2,%r2
+L$3
+ add %r2,%r2,%r2
+
+L$4 add %r2,%r2,%r2
+L$5: add %r2,%r2,%r2
+L$6
+ add %r2,%r2,%r2
+
+; An instruction or pseudo-op may begin anywhere after column 0.
+ b,n label_without_colon
diff --git a/gas/testsuite/gas/hppa/parse/linesepbug.s b/gas/testsuite/gas/hppa/parse/linesepbug.s
new file mode 100644
index 00000000000..a819c153e95
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/linesepbug.s
@@ -0,0 +1,20 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; Basic immediate instruction tests.
+;
+; We could/should test some of the corner cases for register and
+; immediate fields. We should also check the assorted field
+; selectors to make sure they're handled correctly.
+
+foo:
+ .WORD 0 !.IMPORT $bar$,DATA
+
diff --git a/gas/testsuite/gas/hppa/parse/lselbug.s b/gas/testsuite/gas/hppa/parse/lselbug.s
new file mode 100644
index 00000000000..29cd997e289
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/lselbug.s
@@ -0,0 +1,18 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; In gas-1.36 the ldil instruction using parenthesis generated
+; garbage bits while the one without parens worked fine.
+ ldil L%(0x00040000 | 0x00000008 | 0x00000002),%r21
+ ldo L%(0x00040000 | 0x00000008 | 0x00000002) (%r21),%r21
+ ldil L%0x00040000 | 0x00000008 | 0x00000002,%r21
+ ldo L%0x00040000 | 0x00000008 | 0x00000002 (%r21),%r21
+
diff --git a/gas/testsuite/gas/hppa/parse/nosubspace.s b/gas/testsuite/gas/hppa/parse/nosubspace.s
new file mode 100644
index 00000000000..2904603c093
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/nosubspace.s
@@ -0,0 +1,21 @@
+ .SPACE $TEXT$
+
+ .align 4
+ .EXPORT mpn_add_n
+ .EXPORT mpn_add_n,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR
+mpn_add_n:
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+
+ add %r0,%r0,%r0 ; reset cy
+Loop:
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addc %r19,%r20,%r19
+ addib,<> -1,%r23,Loop
+ stws,ma %r19,4(0,%r26)
+
+ bv 0(2)
+ addc %r0,%r0,%r28
diff --git a/gas/testsuite/gas/hppa/parse/parse.exp b/gas/testsuite/gas/hppa/parse/parse.exp
new file mode 100644
index 00000000000..da4c2a7486d
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/parse.exp
@@ -0,0 +1,222 @@
+# Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by the Center for Software Science at the University of Utah
+# and by Cygnus Support.
+
+proc do_string_tests {} {
+ set testname "stringer.s: Test embedded quotes and octal escapes in strings"
+ set x 0
+
+ gas_start "stringer.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 23696E63\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 6C756465\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 6B2E6465\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 66220A00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 09307831\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 3233\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==6] then { pass $testname } else { fail $testname }
+}
+
+proc do_lsel_test {} {
+ set testname "lselbugs.s: lselbug"
+ set x 0
+
+ gas_start "lselbug.s" "-al"
+
+ # Make sure we correctly handle field selectors.
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 22A04000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 36B50100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 22A04000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 36B50100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_valid_align_tests {} {
+ set testname "align1.s: valid alignment tests"
+ set x 0
+
+ gas_start "align1.s" "-al"
+
+ # Make sure we correctly handle field selectors.
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08000240\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 08000240\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 1000 08000240\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0000\[^\n\]*BLOCK\[^\n\]*1024\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0400\[^\n\]*BLOCK\[^\n\]*1024\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0800\[^\n\]*BLOCK\[^\n\]*4\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0804\[^\n\]*ALIGN\[^\n\]*8\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0808\[^\n\]*BLOCK\[^\n\]*30\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0826\[^\n\]*ALIGN\[^\n\]*4\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0828\[^\n\]*BLOCK\[^\n\]*4\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==10] then { pass $testname } else { fail $testname }
+}
+
+if [istarget hppa*-*-*] then {
+ # GAS-2.0 does not always parse ! as a line separator when it should.
+ setup_xfail hppa*-*-*
+ gas_test "linesepbug.s" "" "" "line separator bug"
+
+ # Make sure GAS accepts syntax for accessing static data.
+ gas_test "global.s" "" "" "check for sym-\$global\$ acceptance"
+
+ # GAS-2.0 (and 1.36 for that matter) can not handle a .proc which
+ # has no label before it.
+ gas_test "procbug.s" "" "" "Label following .proc"
+
+ # One is required to explicitly IMPORT any non-local symbol used
+ # in an assembly file. Make sure we give an error if we use
+ # an undefined symbol.
+ setup_xfail hppa*-*-*
+ gas_test_error "undefbug.s" "" "Check for error when using undefined symbol"
+
+ # This file has code and assembler directives before switching into any
+ # space/subspace pair. This should report an error for SOM (it is not
+ # an error for ELF. The file also has mismatched entry/exit and
+ # proc/procend pairs which are errors for both SOM and ELF.
+ gas_test_error "nosubspace.s" "" "Check for error(s) in input file "
+
+ # This file should return errors for both the ENTRY_GR and ENTRY_FR
+ # directives (they are out-of-range)
+ gas_test_error "entrybug.s" "" "Check for error on entry_gr and entry_fr"
+
+ # Make sure embedded quotes and octal escapes in strings work
+ do_string_tests
+
+ # Make sure we do not die on a .version directive
+ gas_test "versionbug.s" "" "" ".version directive"
+
+ # Make sure we give an error on a bogus .space directive.
+ # recent version of gas2 went into infinite loops printing
+ # errors on this test.
+ gas_test_error "spacebug.s" "" "Check for error on bogus .space directive"
+
+ # GAS should give an error for this test.
+ gas_test_error "calldatabug.s" "" "Check for invalid aguments on .call"
+
+ # Old versions of gas incorrectly gave errors on some valid .EXPORT lines
+ gas_test "exportbug.s" "" "" "syntax check for an old .EXPORT bug"
+
+ # Old versions of gas choked on this file for some reason
+ gas_test "fixup7bug.s" "" "" "check for old \"fixup7\" gas bug"
+
+ # Test an L% selector parsing bug which existed in gas-1.36
+ do_lsel_test
+
+ # First check how some valid alignments are handled.
+ do_valid_align_tests
+
+ # Now check to make sure an invalid argument is flagged as an error.
+ gas_test_error "align2.s" "" "Check for error on bogus argument to .align"
+
+ # GAS can't handle upper bound for a PA .block[z] directive
+ setup_xfail hppa*-*-*
+ gas_test "block1.s" "" "" "Check min/max values for .block"
+
+ # Now check for an invalid argument
+ gas_test_error "block2.s" "" "Check for error on bogus argument to .block"
+
+ # GAS-1.36 choked on this file.
+ # FIXME. Should check relocations made for this test!
+ gas_test "exprbug.s" "" "" "Check for sym1-sym2 acceptance"
+
+ # Bad things happen in the PA ELF backend (others too?) if a non-default
+ # section is created...
+ setup_xfail hppa*-*-*elf*
+ gas_test "ssbug.s" "" "" "Check for acceptance of non-default subspaces"
+
+ # To be compatable with certain "features" of the HP compiler
+ # non-existant registers should default to %r0.
+ gas_test "defbug.s" "" "" "Missing register should default to %%r0"
+
+ # Make sure GAS understands a reasonable set of standard predefined
+ # registers. eg %rp, %dp, %sp, etc.
+ gas_test "stdreg.s" "" "" "Test standard predefined registers"
+
+ # Make sure GAS will accept a label without a colon.
+ gas_test "labelbug.s" "" "" "Test label without colon"
+
+ # Make sure we grok # line directives.
+ gas_test "appbug.s" "" "" "Test acceptance of #line directives"
+
+ # Make sure we give errors if a floating point format is specified
+ # for an xmpyu instruction (integer multiple)
+ gas_test_error "xmpyubug.s" "" "Check for error on bogus argument to xmpyu"
+
+ # Make sure gas handles various kinds of .reg pseudo-ops
+ gas_test "regpopbug.s" "" "" "Test for bugs in .reg pseudo-op"
+
+ # Check some bugs that have appeared in parsing .callinfo directives
+ gas_test "callinfobug.s" "" "" "Test for bugs in .callinfo directive"
+
+ # Check for bogus registers in single precision fmpyadd/fmpysub
+ # instructions
+ gas_test_error "badfmpyadd.s" "" "Check for error on bad fmpyadd insn"
+}
+
diff --git a/gas/testsuite/gas/hppa/parse/procbug.s b/gas/testsuite/gas/hppa/parse/procbug.s
new file mode 100644
index 00000000000..5ae5057f643
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/procbug.s
@@ -0,0 +1,16 @@
+ .space $TEXT$
+ .subspa $CODE$
+ .align 4
+ .export divu,entry
+ .proc
+ .callinfo
+divu: stws,ma %r4,4(%r5) ; save registers on stack
+ .procend
+
+ .export divu2,entry
+ .proc
+ .callinfo
+ .entry
+divu2: stws,ma %r4,4(%r5) ; save registers on stack
+ .exit
+ .procend
diff --git a/gas/testsuite/gas/hppa/parse/regpopbug.s b/gas/testsuite/gas/hppa/parse/regpopbug.s
new file mode 100644
index 00000000000..46db2621902
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/regpopbug.s
@@ -0,0 +1,17 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+r0 .reg %r0
+shift .reg %sar
+fpreg10 .reg %fr10
+shift2 .reg shift
+
+; Make sure we didn't botch .equ...
+yabba .equ r0 + shift
diff --git a/gas/testsuite/gas/hppa/parse/spacebug.s b/gas/testsuite/gas/hppa/parse/spacebug.s
new file mode 100644
index 00000000000..183b40138c7
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/spacebug.s
@@ -0,0 +1,3 @@
+start: .long 0, 1, 2, 3, 4, 5, 6, 7
+ .space 0x20 - (. - start)
+foo: .long 42
diff --git a/gas/testsuite/gas/hppa/parse/ssbug.s b/gas/testsuite/gas/hppa/parse/ssbug.s
new file mode 100644
index 00000000000..1960e0d3095
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/ssbug.s
@@ -0,0 +1,10 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SUBSPA $SHORTBSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=80
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+
+
diff --git a/gas/testsuite/gas/hppa/parse/stdreg.s b/gas/testsuite/gas/hppa/parse/stdreg.s
new file mode 100644
index 00000000000..e42978e2414
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/stdreg.s
@@ -0,0 +1,27 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .export foo
+foo:
+ .proc
+ .callinfo no_calls
+ .entry
+ ldi 15,%sp
+ ldi 15,%rp
+ ldi 15,%dp
+ ldi 15,%ret0
+ ldi 15,%ret1
+ ldi 15,%arg0
+ ldi 15,%arg1
+ ldi 15,%arg2
+ ldi 15,%arg3
+ .exit
+ .procend
diff --git a/gas/testsuite/gas/hppa/parse/stringer.s b/gas/testsuite/gas/hppa/parse/stringer.s
new file mode 100644
index 00000000000..06c5e6dc272
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/stringer.s
@@ -0,0 +1,19 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+
+; GAS used to mis-parse the embedded quotes
+ .STRING "#include \"awk.def\"\x0a\x00"
+
+; Octal escapes used to consume > 3 chars which led to this
+; string being screwed in a big way.
+ .STRING "\0110x123"
+
+
diff --git a/gas/testsuite/gas/hppa/parse/undefbug.s b/gas/testsuite/gas/hppa/parse/undefbug.s
new file mode 100644
index 00000000000..d5eda92fd4c
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/undefbug.s
@@ -0,0 +1,14 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ bl somewhere,%r2
+ nop
+
diff --git a/gas/testsuite/gas/hppa/parse/versionbug.s b/gas/testsuite/gas/hppa/parse/versionbug.s
new file mode 100644
index 00000000000..9fef1b73f40
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/versionbug.s
@@ -0,0 +1,9 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .VERSION "abc123"
+
diff --git a/gas/testsuite/gas/hppa/parse/xmpyubug.s b/gas/testsuite/gas/hppa/parse/xmpyubug.s
new file mode 100644
index 00000000000..3ee727478fa
--- /dev/null
+++ b/gas/testsuite/gas/hppa/parse/xmpyubug.s
@@ -0,0 +1,17 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+; No format selector for xmpyu!
+ xmpyu,sgl %fr4,%fr5,%fr6
+ xmpyu,dbl %fr4,%fr5,%fr6
+ xmpyu,quad %fr4,%fr5,%fr6
+
+
diff --git a/gas/testsuite/gas/hppa/reloc/applybug.s b/gas/testsuite/gas/hppa/reloc/applybug.s
new file mode 100644
index 00000000000..f8ed6e8e20c
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/applybug.s
@@ -0,0 +1,130 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+tab___2
+ .word L$0002
+ .word L$0003
+ .word L$0004
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT execute,CODE
+ .EXPORT execute,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+execute
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ addil L'buf-$global$,%r27
+ ldo R'buf-$global$(%r1),%r20
+ ldil L'L$0002,%r19
+ movb,<> %r26,%r26,L$0002
+ ldo R'L$0002(%r19),%r22
+ copy %r0,%r21
+ addil L'tab___2-$global$,%r27
+ ldo R'tab___2-$global$(%r1),%r23
+ addil L'optab-$global$,%r27
+ ldo R'optab-$global$(%r1),%r20
+L$0009
+ sh2add %r21,%r23,%r19
+ ldh 2(%r19),%r19
+ ldo 1(%r21),%r21
+ sub %r19,%r22,%r19
+ comib,>= 2,%r21,L$0009
+ sths,ma %r19,2(%r20)
+ bv,n %r0(%r2)
+L$0002
+ ldi 120,%r19
+ stbs,ma %r19,1(%r20)
+ ldhs,ma 2(%r26),%r19
+ add %r22,%r19,%r19
+ bv,n %r0(%r19)
+L$0003
+ ldi 121,%r19
+ stbs,ma %r19,1(%r20)
+ ldhs,ma 2(%r26),%r19
+ add %r22,%r19,%r19
+ bv,n %r0(%r19)
+L$0004
+ ldi 122,%r19
+ stb %r19,0(%r20)
+ bv %r0(%r2)
+ stbs,mb %r0,1(%r20)
+ .EXIT
+ .PROCEND
+ .IMPORT __main,CODE
+ .IMPORT strcmp,CODE
+ .SPACE $TEXT$
+ .SUBSPA $LIT$
+
+ .align 4
+L$C0000
+ .STRING "xyxyz\x00"
+ .IMPORT abort,CODE
+ .IMPORT exit,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT main,CODE
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ .CALL
+ bl __main,%r2
+ ldo 128(%r30),%r30
+ .CALL ARGW0=GR
+ bl execute,%r2
+ copy %r0,%r26
+ addil L'optab-$global$,%r27
+ copy %r1,%r19
+ ldo R'optab-$global$(%r19),%r21
+ ldh 2(%r21),%r20
+ ldh R'optab-$global$(%r19),%r19
+ addil L'p-$global$,%r27
+ copy %r1,%r22
+ sth %r20,R'p-$global$(%r22)
+ ldo R'p-$global$(%r22),%r26
+ sth %r20,4(%r26)
+ sth %r19,2(%r26)
+ ldh 4(%r21),%r19
+ .CALL ARGW0=GR
+ bl execute,%r2
+ sth %r19,6(%r26)
+ addil L'buf-$global$,%r27
+ copy %r1,%r19
+ ldo R'buf-$global$(%r19),%r26
+ ldil L'L$C0000,%r25
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2
+ ldo R'L$C0000(%r25),%r25
+ comib,=,n 0,%r28,L$0011
+ .CALL
+ bl abort,%r2
+ nop
+L$0011
+ .CALL ARGW0=GR
+ bl exit,%r2
+ copy %r0,%r26
+ nop
+ .EXIT
+ .PROCEND
+ .SPACE $PRIVATE$
+ .SUBSPA $BSS$
+
+optab .comm 10
+buf .comm 10
+p .comm 10
diff --git a/gas/testsuite/gas/hppa/reloc/blebug.s b/gas/testsuite/gas/hppa/reloc/blebug.s
new file mode 100644
index 00000000000..09307747395
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/blebug.s
@@ -0,0 +1,16 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .IMPORT $$dyncall,MILLICODE ; Code for dynamic function calls.
+
+_sigtramp:
+ ldil L%$$dyncall,%r2 ; whose address is in r22.
+ ble R%$$dyncall(%sr4,%r2)
diff --git a/gas/testsuite/gas/hppa/reloc/blebug2.s b/gas/testsuite/gas/hppa/reloc/blebug2.s
new file mode 100644
index 00000000000..9577b53cb84
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/blebug2.s
@@ -0,0 +1,14 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+
+ ldil L%0xc0001004,%r1
+ ble R%0xc0001004(%sr7,%r1)
diff --git a/gas/testsuite/gas/hppa/reloc/blebug3.s b/gas/testsuite/gas/hppa/reloc/blebug3.s
new file mode 100644
index 00000000000..5ee9b3b80a8
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/blebug3.s
@@ -0,0 +1,14 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .import yabba,code
+
+ ble R%yabba(%sr4,%r0)
diff --git a/gas/testsuite/gas/hppa/reloc/exitbug.s b/gas/testsuite/gas/hppa/reloc/exitbug.s
new file mode 100644
index 00000000000..8898e358da2
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/exitbug.s
@@ -0,0 +1,19 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT foo,CODE
+ .EXPORT foo,ENTRY,PRIV_LEV=3
+foo:
+ .PROC
+ .CALLINFO FRAME=0
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/fixupbug.s b/gas/testsuite/gas/hppa/reloc/fixupbug.s
new file mode 100644
index 00000000000..8a58d026d7c
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/fixupbug.s
@@ -0,0 +1,19 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ b,n $$foo
+ nop
+ nop
+
+ .SPACE $TEXT$
+ .SUBSPA $MILLICODE$
+$$foo:
+ nop
diff --git a/gas/testsuite/gas/hppa/reloc/funcrelocbug.s b/gas/testsuite/gas/hppa/reloc/funcrelocbug.s
new file mode 100644
index 00000000000..46a43bc62b9
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/funcrelocbug.s
@@ -0,0 +1,186 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT g,CODE
+ .EXPORT g,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR
+g
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r3,%r1
+ copy %r30,%r3
+ stwm %r1,128(%r30)
+ stw %r26,-36(%r3)
+ stw %r25,-40(%r3)
+ stw %r24,-44(%r3)
+ ldw -36(%r3),%r26
+ ldw -40(%r3),%r25
+ ldw -44(%r3),%r19
+ copy %r19,%r22
+ .CALL ARGW0=GR
+ bl $$dyncall,%r31
+ copy %r31,%r2
+ copy %r28,%r19
+ comiclr,<> 0,%r19,%r0
+ bl,n L$0002,%r0
+ ldw -36(%r3),%r28
+ bl,n L$0001,%r0
+ bl,n L$0003,%r0
+L$0002
+ ldw -40(%r3),%r28
+ bl,n L$0001,%r0
+L$0003
+L$0001
+ ldw -20(%r3),%r2
+ ldo 64(%r3),%r30
+ ldwm -64(%r30),%r3
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
+ .align 4
+f2___4
+ .PROC
+ .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ copy %r3,%r1
+ copy %r30,%r3
+ stwm %r1,64(%r30)
+ stw %r29,8(%r3)
+ stw %r26,-36(%r3)
+ stw %r25,-40(%r3)
+ ldw -36(%r3),%r19
+ ldw -40(%r3),%r20
+ comclr,>= %r20,%r19,%r19
+ ldi 1,%r19
+ copy %r19,%r28
+ bl,n L$0005,%r0
+L$0005
+ ldo 64(%r3),%r30
+ ldwm -64(%r30),%r3
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
+ .IMPORT abort,CODE
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+L$TRAMP0000
+ ldw 36(%r22),%r21
+ bb,>=,n %r21,30,.+16
+ depi 0,31,2,%r21
+ ldw 4(%r21),%r19
+ ldw 0(%r21),%r21
+ ldsid (%r21),%r1
+ mtsp %r1,%sr0
+ be 0(%sr0,%r21)
+ ldw 40(%r22),%r29
+ .word 0
+ .word 0
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT f,CODE
+ .EXPORT f,ENTRY,PRIV_LEV=3,RTNVAL=GR
+f
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r3,%r1
+ copy %r30,%r3
+ stwm %r1,192(%r30)
+ ldo 16(%r3),%r19
+ addil L'L$TRAMP0000-$global$,%r27
+ ldo R'L$TRAMP0000-$global$(%r1),%r22
+ ldo 40(%r0),%r20
+ ldws,ma 4(%r22),%r21
+ addib,>= -4,%r20,.-4
+ stws,ma %r21,4(%r19)
+ ldil L'f2___4,%r20
+ ldo R'f2___4(%r20),%r19
+ stw %r19,52(%r3)
+ ldo 8(%r3),%r19
+ stw %r19,56(%r3)
+ ldo 16(%r3),%r19
+ ldo 48(%r3),%r20
+ fdc %r0(%r19)
+ fdc %r0(%r20)
+ sync
+ ldo 32(%r19),%r22
+ mfsp %sr0,%r21
+ ldsid (%r19),%r20
+ mtsp %r20,%sr0
+ fic %r0(%sr0,%r19)
+ fic %r0(%sr0,%r22)
+ sync
+ mtsp %r21,%sr0
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ ldo 16(%r3),%r19
+ ldi 1,%r26
+ ldi 2,%r25
+ copy %r19,%r24
+ .CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO
+ bl g,%r2
+ nop
+ copy %r28,%r19
+ comiclr,<> 2,%r19,%r0
+ bl,n L$0006,%r0
+ .CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO
+ bl abort,%r2
+ nop
+L$0006
+L$0004
+ ldw -20(%r3),%r2
+ ldo 64(%r3),%r30
+ ldwm -64(%r30),%r3
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
+ .IMPORT __main,CODE
+ .IMPORT exit,CODE
+ .align 4
+ .EXPORT main,CODE
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r3,%r1
+ copy %r30,%r3
+ stwm %r1,128(%r30)
+ .CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO
+ bl __main,%r2
+ nop
+ .CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO
+ bl f,%r2
+ nop
+ copy %r0,%r26
+ .CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO
+ bl exit,%r2
+ nop
+L$0007
+ ldw -20(%r3),%r2
+ ldo 64(%r3),%r30
+ ldwm -64(%r30),%r3
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/labelopbug.s b/gas/testsuite/gas/hppa/reloc/labelopbug.s
new file mode 100644
index 00000000000..3cdc421b221
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/labelopbug.s
@@ -0,0 +1,37 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+s:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ copy %r4,%r1
+ copy %r30,%r4
+ stwm %r1,128(%r30)
+ stw %r30,12(%r4)
+ ldil L'L$0007,%r19
+ ldo R'L$0007(%r19),%r19
+ comib,>= 0,%r26,L$0002
+ stw %r19,8(%r4)
+L$0003:
+L$0002:
+ b L$0001
+ ldo 1(%r0),%r28
+L$0007:
+ ldil L'L$0002,%r19
+ ldo R'L$0002(%r19),%r19
+ comb,= %r29,%r19,L$0002
+ ldo -8(%r4),%r4
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/longcall.s b/gas/testsuite/gas/hppa/reloc/longcall.s
new file mode 100644
index 00000000000..fc3996f0bef
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/longcall.s
@@ -0,0 +1,40 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .IMPORT bar,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT foo,CODE
+ .EXPORT foo,ENTRY,PRIV_LEV=3,RTNVAL=GR
+foo
+ .PROC
+ .CALLINFO FRAME=64,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ .CALL
+ bl bar,%r2
+ ldo 64(%r30),%r30
+ .blockz 262144
+ ldw -84(%r30),%r2
+ bv %r0(%r2)
+ ldo -64(%r30),%r30
+ .EXIT
+ .PROCEND
+ .align 4
+ .EXPORT bar,CODE
+ .EXPORT bar,ENTRY,PRIV_LEV=3,RTNVAL=GR
+bar
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/picreloc.s b/gas/testsuite/gas/hppa/reloc/picreloc.s
new file mode 100644
index 00000000000..639a44c3abc
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/picreloc.s
@@ -0,0 +1,13 @@
+
+ .SPACE $TEXT$,SORT=8
+ .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24
+ .SPACE $PRIVATE$,SORT=16
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=0x1f,SORT=16
+bogo
+ .ALIGN 8
+ .WORD bogo+4 ; = 0x4
+ .STRING "\x00\x00\x00{\x00\x00\x01\xC8\x00\x00\x03\x15"
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+ .EXPORT bogo
+ .END
diff --git a/gas/testsuite/gas/hppa/reloc/plabelbug.s b/gas/testsuite/gas/hppa/reloc/plabelbug.s
new file mode 100644
index 00000000000..ee05b32e1f8
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/plabelbug.s
@@ -0,0 +1,47 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .IMPORT abort,CODE
+ .EXPORT f,DATA
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+f:
+ .word P%abort
+ .word P%abort
+ .IMPORT __main,CODE
+ .IMPORT printf,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+LC$0000:
+ .STRING "frob\x0a\x00"
+ .align 4
+ .EXPORT main,CODE
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ stw %r2,-20(%r30)
+ ldo 128(%r30),%r30
+ .CALL
+ bl __main,%r2
+ nop
+ ldil L'LC$0000,%r26
+ .CALL ARGW0=GR
+ bl printf,%r2
+ ldo R'LC$0000(%r26),%r26
+ ldw -148(%r30),%r2
+ bv %r0(%r2)
+ ldo -128(%r30),%r30
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/r_no_reloc.s b/gas/testsuite/gas/hppa/reloc/r_no_reloc.s
new file mode 100644
index 00000000000..026f2d08230
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/r_no_reloc.s
@@ -0,0 +1,45 @@
+ .COPYRIGHT "MetaWare Incorporated, 1992"
+ .VERSION "hc2.6a -O1 t3.c\n"
+
+ .SPACE $PRIVATE$,SORT=16
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=0x1F,SORT=80,ZERO
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=0x1F,SORT=16
+
+ .SPACE $TEXT$,SORT=8
+ .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=44,CODE_ONLY,SORT=24
+
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+ .ALIGN 8
+$L00DATA
+ .ALIGN 8
+ .EXPORT s
+s
+ .WORD 0x0
+ .BLOCKZ 786425
+ .BLOCKZ 7
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+L$001.3
+g .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ ;ldo 120(%r0),%r28 --> to delay slot
+ bv %r0(%r2)
+ .EXIT
+ ldo 120(%r0),%r28
+ .PROCEND
+
+
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+ .ALIGN 4
+ .EXPORT l
+l
+ .WORD P'g
+ .IMPORT common,DATA ; common section, size=0
+ .IMPORT $global$,DATA
+ .EXPORT g,ENTRY,PRIV_LEV=3,RTNVAL=GR
+ .END
+
diff --git a/gas/testsuite/gas/hppa/reloc/reduce.s b/gas/testsuite/gas/hppa/reloc/reduce.s
new file mode 100644
index 00000000000..737752f2112
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/reduce.s
@@ -0,0 +1,48 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .PARAM foo,RTNVAL=GR
+foo:
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+LC$0000:
+ .word P%foo
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT bar,CODE
+ .EXPORT bar,ENTRY,PRIV_LEV=3,RTNVAL=GR
+bar:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP
+ .ENTRY
+ ldil L'LC$0000,%r19
+ ldw R'LC$0000(%r19),%r26
+ stw %r2,-20(%r30)
+ .CALL ARGW0=GR
+ bl foo,%r2
+ ldo 128(%r30),%r30
+ ldw -148(%r30),%r2
+ bv %r0(%r2)
+ ldo -128(%r30),%r30
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/reduce2.s b/gas/testsuite/gas/hppa/reloc/reduce2.s
new file mode 100644
index 00000000000..6c3fa3781cd
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/reduce2.s
@@ -0,0 +1,80 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $TEXT$
+ .SUBSPA $LIT$
+
+ .align 8
+L$P0000
+ .word 0x12345678
+ .word 0x0
+
+ .align 8
+L$C0000
+ .word 0x3ff00000
+ .word 0x0
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT g,ENTRY,PRIV_LEV=3,RTNVAL=FR
+g
+ .PROC
+ .CALLINFO FRAME=0,NO_CALLS
+ .ENTRY
+ stw %r19,-32(%r30)
+ ldw T'L$C0000(%r19),%r20
+ bv %r0(%r2)
+ fldds 0(%r20),%fr4
+ .EXIT
+ .PROCEND
+ .IMPORT abort,CODE
+ .IMPORT exit,CODE
+ .SPACE $TEXT$
+ .SUBSPA $LIT$
+
+ .align 8
+L$C0001
+ .word 0x3ff00000
+ .word 0x0
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
+ .ENTRY
+ stw %r2,-20(%r30)
+ ldo 128(%r30),%r30
+ stw %r19,-32(%r30)
+ stw %r4,-128(%r30)
+
+ copy %r19,%r4
+ .CALL
+ bl g,%r2
+ copy %r4,%r19
+ copy %r4,%r19
+ ldw T'L$C0001(%r19),%r20
+ fldds 0(%r20),%fr8
+ fcmp,dbl,= %fr4,%fr8
+ ftest
+ add,tr %r0,%r0,%r0
+ b,n L$0003
+ .CALL
+ bl abort,%r2
+ nop
+L$0003
+ .CALL ARGW0=GR
+ bl exit,%r2
+ ldi 0,%r26
+ nop
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/reduce3.s b/gas/testsuite/gas/hppa/reloc/reduce3.s
new file mode 100644
index 00000000000..9671e784c3e
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/reduce3.s
@@ -0,0 +1,51 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .EXPORT blah,DATA
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 8
+blah
+ ; .double 0e+00
+ .word 0 ; = 0x0
+ .word 0 ; = 0x0
+ .EXPORT foo,DATA
+ .align 8
+foo
+ ; .double 0e+00
+ .word 0 ; = 0x0
+ .word 0 ; = 0x0
+ .EXPORT yabba,DATA
+ .align 4
+yabba
+ .word 1
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT bar,CODE
+ .EXPORT bar,ENTRY,PRIV_LEV=3,RTNVAL=GR
+bar
+ .PROC
+ .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ copy %r3,%r1
+ copy %r30,%r3
+ stwm %r1,64(%r30)
+ addil L'yabba-$global$,%r27
+ ldo R'yabba-$global$(%r1),%r19
+ ldi 2,%r20
+ stw %r20,0(%r19)
+L$0001
+ ldo 64(%r3),%r30
+ ldwm -64(%r30),%r3
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/reloc/reloc.exp b/gas/testsuite/gas/hppa/reloc/reloc.exp
new file mode 100644
index 00000000000..ccb236cba71
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/reloc.exp
@@ -0,0 +1,679 @@
+# Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by the Center for Software Science at the University of Utah
+# and by Cygnus Support.
+
+proc do_ble_relocation_test {} {
+ set testname "blebug.s: Test for proper relocation for BLE (part 2)"
+ set x 0
+
+ if [gas_test_old "blebug.s" "" "Proper relocation for BLE (part 1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+
+ if ![istarget hppa*-*-*elf*] then {
+ # At one time both versions of the assembler would incorrectly use
+ # a PC-relative relocation for a BLE instruction.
+ while 1 {
+ expect {
+ -re "^00000004\[^\n\]*ABS_CALL\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ } else {
+ # At one time both versions of the assembler would incorrectly use
+ # a PC-relative relocation for a BLE instruction.
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*DIR21L\[^\n\]*\n" { set x 1 }
+ -re "^00000004\[^\n\]*DIR17R\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+}
+
+proc do_relocation_reduction_tests {} {
+ set testname "reduce.s: Test relocation reductions (part 2)"
+ set x 0
+
+ if [gas_test_old "reduce.s" "" "Relocation reductions (part1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Check to make sure relocations involving procedure labels
+ # are not reduced to a relocation involving some other symbol.
+ # Doing so makes generating parameter relocation stubs impossible.
+ while 1 {
+ expect {
+ -re "^00000004\[^\n\]*PLABEL\[^\n\]*foo\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000014\[^\n\]*PCREL\[^\n\]*foo\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+
+ set testname "reduce2.s: More relocation reduction tests (part 2)"
+ set x 0
+
+ if [gas_test_old "reduce2.s" "" "More relocatoin reductions (part1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Check to make sure DLT relative relocs are not reduced to sym+addend
+ # Doing so doesn't work as one might expect
+ while 1 {
+ expect {
+ -re "^00000004\[^\n\]*DLT\[^\n\]*L.C0000\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000001c\[^\n\]*DLT\[^\n\]*L.C0000\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000030\[^\n\]*DLT\[^\n\]*L.C0001\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000048\[^\n\]*DLT\[^\n\]*L.C0001\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+
+ set testname "reduce3.s: Test even more relocation reductions (part 2)"
+ set x 0
+
+ if [gas_test_old "reduce3.s" "" "Even more relocation reductions (part1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Check to make sure relocations involving procedure labels
+ # are not reduced to a relocation involving some other symbol.
+ # Doing so makes generating parameter relocation stubs impossible.
+ while 1 {
+ expect {
+ -re "^0000000c\[^\n\]*yabba\[^\n\+\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000000c\[^\n\]*yabba\+\[^\n\]*\n"
+ { set x 0; break }
+ -re "^00000010\[^\n\]*yabba\[^\n\+\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000010\[^\n\]*yabba\+\[^\n\]*\n"
+ { set x 0; break }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+}
+
+proc do_ble_mode_selector_test {} {
+ set testname "blebug2.s: blebug2"
+ set x 0
+
+ gas_start "blebug2.s" "-al"
+
+ # GAS uses too many bits on the BLE instruction.
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 20202801\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 E420E008\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+}
+
+proc do_ble_relocation_test {} {
+ set testname "blebug3.s: blebug3"
+ set x 0
+
+ gas_start "blebug3.s" "-al"
+
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E4002000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+}
+
+proc do_plabel_relocation_test {} {
+ set testname "plabelbug.s: Old gas-1.36 plabel bug (part 2)"
+ set x 0
+
+ if [gas_test_old "plabelbug.s" "" "Old gas-1.36 plabel bug (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Check that we make PLABEL relocation entries when they're needed.
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*PLABEL\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000004\[^\n\]*PLABEL\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_selector_scope_test {} {
+ set testname "selectorbug.s: Test scope of field selector"
+ set x 0
+
+ if [gas_test_old "selectorbug.s" "" "Test scope of field selector (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Check to make sure the relocation entry after the plabel is correct.
+ # If an old field selector was incorrectly "carried" over, then
+ # this test will fail.
+ if [istarget hppa*-*-*elf*] then {
+ while 1 {
+ expect {
+ -re "^00000014\[^\n\]*DIR32\[^\n\]*\n"
+ { set x 1 }
+ -re "^00000014\[^\n\]*PLABEL\[^\n\]*foo\[^\n\]*\n"
+ { set x 0 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ } else {
+ while 1 {
+ expect {
+ -re "^00000014\[^\n\]*DATA_ONE\[^\n\]*\n"
+ { set x 1 }
+ -re "^00000014\[^\n\]*PLABEL\[^\n\]*foo\[^\n\]*\n"
+ { set x 0 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_local_label_as_operand_test {} {
+ set testname "labelopbug.s: Test local label as operand (non-branching)"
+ set x 0
+
+ if [gas_test_old "labelopbug.s" "" "Local label as operand (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Check to make sure we handle difference of local lables as an operand
+ # to a non-branching instruction correctly.
+ while 1 {
+ expect {
+ -re "^0000002c\[^\n\]*0x00000024\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000030\[^\n\]*0x00000024\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_exit_relocation_test {} {
+ set testname "exitbug.s: Test for bogus R_EXIT relocation (part 2)"
+ set x 0
+
+ # Elf (osf) does not use ENTRY/EXIT relocations.
+ # I guess we could look at the unwind subspaces it builds...
+ # Until then, make sure it still assembles.
+ if [istarget hppa*-*-*elf*] then {
+ gas_test_old "exitbug.s" "" "Test for bogus R_EXIT relocation (part 1)"
+ return;
+ }
+
+ if [gas_test_old "exitbug.s" "" "Test for bogus R_EXIT relocation (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Note that a match here is really a FAILURE!
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*R_EXIT\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==0] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_cross_space_fixup_test_1 {} {
+ set testname "fixupbug.s: Test cross space jump/call fixup bug (part 2)"
+ set x 0
+
+ # ELF (osf) doesn't really handle extra sections too well...
+ if [istarget hppa*-*-*elf*] then {
+ return;
+ }
+
+ if [gas_test_old "fixupbug.s" "" "Test cross space jump/call fixup bug (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Make sure GAS generated a fixup/relocation for the cross-space
+ # branch/call
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*PCREL_CALL\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_cross_space_fixup_test_2 {} {
+ set testname "fixupbug.s: Test cross space jump/call fixup bug (part 3)"
+ set x 0
+
+ # ELF (osf) doesn't really handle extra sections too well...
+ if [istarget hppa*-*-*elf*] then {
+ return;
+ }
+
+ gas_start "fixupbug.s" "-al"
+
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E8000002\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+}
+
+proc do_round_mode_test {} {
+ set testname "roundmode.s: Test switching of rounding modes (part 2)"
+ set x 0
+
+ if [gas_test_old "roundmode.s" "" "Test switch of rounding modes(part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Make sure GAS generated correct relocations to switch rounding modes.
+ # Also make sure (for SOM) that redundant rounding mode relocations
+ # were eliminated.
+ if [istarget hppa*-*-*elf*] then {
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*DIR21L\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000004\[^\n\]*DIR14R\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000008\[^\n\]*DIR21L\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000000c\[^\n\]*DIR14R\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000010\[^\n\]*DIR21L\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000014\[^\n\]*DIR14R\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000018\[^\n\]*DIR21L\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000001c\[^\n\]*DIR14R\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ } else {
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*R_R_MODE\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000004\[^\n\]*R_R_MODE\[^\n\]*\n"
+ { fail $testname }
+ -re "^00000008\[^\n\]*R_N_MODE\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000000c\[^\n\]*R_N_MODE\[^\n\]*\n"
+ { fail $testname }
+ -re "^00000010\[^\n\]*R_R_MODE\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000014\[^\n\]*R_R_MODE\[^\n\]*\n"
+ { fail $testname }
+ -re "^0000001c\[^\n\]*R_R_MODE\[^\n\]*\n"
+ { fail $testname }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [istarget hppa*-*-*elf*] then {
+ if [expr $x==8] then { pass $testname } else { fail $testname }
+ } else {
+ if [expr $x==3] then { pass $testname } else { fail $testname }
+ }
+ }
+}
+
+proc do_function_reloc_bug {} {
+ set testname "funcrelocbug.s: Test for reloc bug in non-plabel function reference (part 2)"
+ set x 0
+
+ if [gas_test_old "funcrelocbug.s" "" "Test for reloc bug in non-plabel function reference (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Make sure GAS generated a correct relocation for the reference.
+ # branch/call
+ while 1 {
+ expect {
+ -re "^000000cc\[^\n\]*f2___4\[^\n+\]*\n"
+ { set x [expr $x+1] }
+ -re "^000000d0\[^\n\]*f2___4\[^\n+\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+
+ set testname "funcrelocbug.s: Test for reloc bug in non-plabel function reference (part3)"
+ set x 0
+
+ objdump_start_no_subdir "a.out" "--prefix-addresses -d"
+ # Make sure we didn't put anything in the instruction itself!
+ while 1 {
+ expect {
+ -re "^000000cc\[^\n\]*ldil 0,r20\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^000000d0\[^\n\]*ldo 0\[\(\]+r20\[\)\]+,r19\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+ }
+
+}
+
+proc do_r_no_reloc {} {
+ set testname "r_no_reloc.s: Test for reloc bug in 4-byte R_NO_RELCOATION fixups (part 2)"
+ set x 0
+
+ if [gas_test_old "r_no_reloc.s" "" "Test for reloc bug in 4-byte R_NO_RELOCATION fixups (part 1)"] {
+ objdump_start_no_subdir "a.out" "-r"
+
+ # Make sure GAS generated a correct relocation for the reference.
+ while 1 {
+ expect {
+ -re "^000c0004\[^\n\]*PLABEL\[^\n]*g\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+
+ }
+}
+
+proc do_pic_relocation_test {} {
+ set testname "picreloc.s: Test for proper PIC relocation (part 2)"
+ set x 0
+
+ # ELF (osf) doesn't really handle extra sections too well...
+ if [istarget hppa*-*-*elf*] then {
+ return;
+ }
+
+ gas_start "picreloc.s" "-al"
+
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 00000004\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+}
+
+proc do_apply_test {} {
+ set testname "applybug.s: Test for proper fixup appliation (part 2)"
+ set x 0
+
+ # ELF (osf) doesn't really handle extra sections too well...
+ if [istarget hppa*-*-*elf*] then {
+ return;
+ }
+
+ gas_start "applybug.s" "-al"
+
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 00000000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==3] then { pass $testname } else { fail $testname }
+}
+if [istarget hppa*-*-*] then {
+ # Make sure we put the right relocation entry on a BLE instruction.
+ do_ble_relocation_test
+
+ # Make sure relocation reductions are not too agressive about
+ # adjusting relocations against some symbols.
+ do_relocation_reduction_tests
+
+ # Check that mode selectors on a ble instruction actually work.
+ do_ble_mode_selector_test
+
+ # Check that we take the -8 adjustment into account when zeroing
+ # out the displacement field in a ble instruction with a reloc
+ do_ble_relocation_test
+
+ # 1.36 simply didn't generate all the plabels it should have. Make
+ # sure gas-2 does.
+ do_plabel_relocation_test
+
+ # Make sure a field selector only effects the current instruction
+ # or assembler directive.
+ do_selector_scope_test
+
+ # This should really generate a relocation. It would make life much
+ # easier on the optimizing linker. Until then just make sure the
+ # difference is computed correctly.
+ do_local_label_as_operand_test
+
+ # GAS2 incorrectly generated R_EXIT relocations when .exit directives
+ # were not in the source code.
+ do_exit_relocation_test
+
+ # GAS2 incorrectly thought it could apply a fixup for a pc-relative
+ # branch/call which crossed different subspaces.
+ # Also check that the assembled instruction is correct
+ do_cross_space_fixup_test_1
+ do_cross_space_fixup_test_2
+
+ # Make sure we switch rounding modes correctly
+ do_round_mode_test
+
+ # Test for a bug found when a function was used in a non-branching
+ # instruction *without* a plabel (for portable runtime model)
+ do_function_reloc_bug
+
+ # Test for an off-by-one bug in the handling of 4-byte R_NO_RELOCATION
+ # fixups.
+ do_r_no_reloc
+
+ # Test a relocation problem which shows up when building shared
+ # libraries in SOM
+ do_pic_relocation_test
+
+ # Test a problem with md_apply_fix that was introduced when fixing
+ # the pic relocation test.
+ do_apply_test
+
+ # Make sure gas doesn't resolve long-calls which are to be fixed
+ # by the linker
+ gas_test "longcall.s" "" "" "Avoid resolving long-calls"
+}
diff --git a/gas/testsuite/gas/hppa/reloc/roundmode.s b/gas/testsuite/gas/hppa/reloc/roundmode.s
new file mode 100644
index 00000000000..5a87e638bca
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/roundmode.s
@@ -0,0 +1,23 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .IMPORT foo,data
+
+; Switch in/out of different rounding modes.
+; Also make sure we "optimize" away useless rounding mode relocations
+ addil LR'foo-0x12345,%r27
+ ldo RR'foo-0x12345(%r1),%r1
+ addil L'foo-0x12345,%r27
+ ldo R'foo-0x12345(%r1),%r1
+ addil LR'foo-0x12345,%r27
+ ldo RR'foo-0x12345(%r1),%r1
+ addil LR'foo-0x12345,%r27
+ ldo RR'foo-0x12345(%r1),%r1
diff --git a/gas/testsuite/gas/hppa/reloc/selectorbug.s b/gas/testsuite/gas/hppa/reloc/selectorbug.s
new file mode 100644
index 00000000000..6925d383f51
--- /dev/null
+++ b/gas/testsuite/gas/hppa/reloc/selectorbug.s
@@ -0,0 +1,28 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .EXPORT intVec_error_handler,DATA
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+intVec_error_handler:
+ .word P%default_intVec_error_handler__FPCc
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT foo,CODE
+ .EXPORT foo,ENTRY,PRIV_LEV=3
+foo:
+ .PROC
+ .CALLINFO FRAME=0
+ .ENTRY
+ .stabd 68,0,41
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/unsorted/align3.s b/gas/testsuite/gas/hppa/unsorted/align3.s
new file mode 100644
index 00000000000..8bd24082cb8
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/align3.s
@@ -0,0 +1,20 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SPACE $TEXT$
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .blockz 4
+
+main:
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .PROC
+ .CALLINFO FRAME=0
+ .ENTRY
+ nop
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/unsorted/align4.s b/gas/testsuite/gas/hppa/unsorted/align4.s
new file mode 100644
index 00000000000..9f2f99bd0d4
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/align4.s
@@ -0,0 +1,4 @@
+ .space $TEXT$
+ .subspa $YABBA$
+ .subspa $MILLICODE$
+ .align 64
diff --git a/gas/testsuite/gas/hppa/unsorted/brlenbug.s b/gas/testsuite/gas/hppa/unsorted/brlenbug.s
new file mode 100644
index 00000000000..58e5c7eef88
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/brlenbug.s
@@ -0,0 +1,3502 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+done___2
+ .word 0
+ .IMPORT memset,CODE
+ .EXPORT re_syntax_options,DATA
+ .align 4
+re_syntax_options
+ .word 0
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+re_error_msg
+ .word 0
+ .word L$C0000
+ .word L$C0001
+ .word L$C0002
+ .word L$C0003
+ .word L$C0004
+ .word L$C0005
+ .word L$C0006
+ .word L$C0007
+ .word L$C0008
+ .word L$C0009
+ .word L$C0010
+ .word L$C0011
+ .word L$C0012
+ .word L$C0013
+ .word L$C0014
+ .word L$C0015
+ .SPACE $TEXT$
+ .SUBSPA $LIT$
+
+ .align 4
+L$C0015
+ .STRING "Unmatched ) or \\)\x00"
+ .align 4
+L$C0014
+ .STRING "Regular expression too big\x00"
+ .align 4
+L$C0013
+ .STRING "Premature end of regular expression\x00"
+ .align 4
+L$C0012
+ .STRING "Invalid preceding regular expression\x00"
+ .align 4
+L$C0011
+ .STRING "Memory exhausted\x00"
+ .align 4
+L$C0010
+ .STRING "Invalid range end\x00"
+ .align 4
+L$C0009
+ .STRING "Invalid content of \\{\\}\x00"
+ .align 4
+L$C0008
+ .STRING "Unmatched \\{\x00"
+ .align 4
+L$C0007
+ .STRING "Unmatched ( or \\(\x00"
+ .align 4
+L$C0006
+ .STRING "Unmatched [ or [^\x00"
+ .align 4
+L$C0005
+ .STRING "Invalid back reference\x00"
+ .align 4
+L$C0004
+ .STRING "Trailing backslash\x00"
+ .align 4
+L$C0003
+ .STRING "Invalid character class name\x00"
+ .align 4
+L$C0002
+ .STRING "Invalid collation character\x00"
+ .align 4
+L$C0001
+ .STRING "Invalid regular expression\x00"
+ .align 4
+L$C0000
+ .STRING "No match\x00"
+ .EXPORT re_max_failures,DATA
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+re_max_failures
+ .word 2000
+ .IMPORT malloc,CODE
+ .IMPORT realloc,CODE
+ .IMPORT free,CODE
+ .IMPORT strcmp,CODE
+ .SPACE $TEXT$
+ .SUBSPA $LIT$
+
+ .align 4
+L$C0016
+ .STRING "alnum\x00"
+ .align 4
+L$C0017
+ .STRING "alpha\x00"
+ .align 4
+L$C0018
+ .STRING "blank\x00"
+ .align 4
+L$C0019
+ .STRING "cntrl\x00"
+ .align 4
+L$C0020
+ .STRING "digit\x00"
+ .align 4
+L$C0021
+ .STRING "graph\x00"
+ .align 4
+L$C0022
+ .STRING "lower\x00"
+ .align 4
+L$C0023
+ .STRING "print\x00"
+ .align 4
+L$C0024
+ .STRING "punct\x00"
+ .align 4
+L$C0025
+ .STRING "space\x00"
+ .align 4
+L$C0026
+ .STRING "upper\x00"
+ .align 4
+L$C0027
+ .STRING "xdigit\x00"
+ .IMPORT __alnum,DATA
+ .IMPORT __ctype2,DATA
+ .IMPORT __ctype,DATA
+ .IMPORT at_begline_loc_p,CODE
+ .IMPORT at_endline_loc_p,CODE
+ .IMPORT store_op1,CODE
+ .IMPORT insert_op1,CODE
+ .IMPORT store_op2,CODE
+ .IMPORT insert_op2,CODE
+ .IMPORT compile_range,CODE
+ .IMPORT group_in_compile_stack,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+regex_compile
+ .PROC
+ .CALLINFO FRAME=320,CALLS,SAVE_RP,ENTRY_GR=18
+ .ENTRY
+ stw %r2,-20(%r30) ;# 8989 reload_outsi+2/6
+ ldo 320(%r30),%r30 ;# 8991 addsi3/2
+ stw %r18,-168(%r30) ;# 8993 reload_outsi+2/6
+ stw %r17,-164(%r30) ;# 8995 reload_outsi+2/6
+ stw %r16,-160(%r30) ;# 8997 reload_outsi+2/6
+ stw %r15,-156(%r30) ;# 8999 reload_outsi+2/6
+ stw %r14,-152(%r30) ;# 9001 reload_outsi+2/6
+ stw %r13,-148(%r30) ;# 9003 reload_outsi+2/6
+ stw %r12,-144(%r30) ;# 9005 reload_outsi+2/6
+ stw %r11,-140(%r30) ;# 9007 reload_outsi+2/6
+ stw %r10,-136(%r30) ;# 9009 reload_outsi+2/6
+ stw %r9,-132(%r30) ;# 9011 reload_outsi+2/6
+ stw %r8,-128(%r30) ;# 9013 reload_outsi+2/6
+ stw %r7,-124(%r30) ;# 9015 reload_outsi+2/6
+ stw %r6,-120(%r30) ;# 9017 reload_outsi+2/6
+ stw %r5,-116(%r30) ;# 9019 reload_outsi+2/6
+ stw %r4,-112(%r30) ;# 9021 reload_outsi+2/6
+ stw %r3,-108(%r30) ;# 9023 reload_outsi+2/6
+ stw %r26,-276(%r30) ;# 4 reload_outsi+2/6
+ ldi 0,%r9 ;# 25 reload_outsi+2/2
+ ldi 0,%r8 ;# 28 reload_outsi+2/2
+ stw %r0,-260(%r30) ;# 34 reload_outsi+2/6
+ ldi 0,%r10 ;# 31 reload_outsi+2/2
+ ldi 640,%r26 ;# 37 reload_outsi+2/2
+ ldw -276(%r30),%r1 ;# 8774 reload_outsi+2/5
+ copy %r24,%r15 ;# 8 reload_outsi+2/1
+ stw %r1,-296(%r30) ;# 2325 reload_outsi+2/6
+ copy %r23,%r5 ;# 10 reload_outsi+2/1
+ addl %r1,%r25,%r16 ;# 19 addsi3/1
+ .CALL ARGW0=GR
+ bl malloc,%r2 ;# 39 call_value_internal_symref
+ ldw 20(%r5),%r14 ;# 22 reload_outsi+2/5
+ comib,<> 0,%r28,L$0021 ;# 48 bleu+1
+ stw %r28,-312(%r30) ;# 43 reload_outsi+2/6
+L$0953
+ bl L$0867,%r0 ;# 53 jump
+ ldi 12,%r28 ;# 51 reload_outsi+2/2
+L$0021
+ ldi 32,%r19 ;# 58 reload_outsi+2/2
+ stw %r19,-308(%r30) ;# 59 reload_outsi+2/6
+ stw %r0,-304(%r30) ;# 62 reload_outsi+2/6
+ stw %r15,12(%r5) ;# 65 reload_outsi+2/6
+ stw %r0,8(%r5) ;# 85 reload_outsi+2/6
+ stw %r0,24(%r5) ;# 88 reload_outsi+2/6
+ addil LR'done___2-$global$,%r27 ;# 92 pic2_lo_sum+1
+ ldw 28(%r5),%r19 ;# 68 reload_outsi+2/5
+ ldw RR'done___2-$global$(%r1),%r20 ;# 94 reload_outsi+2/5
+ depi 0,3,1,%r19 ;# 69 andsi3/2
+ depi 0,6,2,%r19 ;# 80 andsi3/2
+ comib,<> 0,%r20,L$0022 ;# 95 bleu+1
+ stw %r19,28(%r5) ;# 82 reload_outsi+2/6
+ addil LR're_syntax_table-$global$,%r27 ;# 99 pic2_lo_sum+1
+ ldo RR're_syntax_table-$global$(%r1),%r4 ;# 100 movhi-2
+ copy %r4,%r26 ;# 101 reload_outsi+2/1
+ ldi 0,%r25 ;# 102 reload_outsi+2/2
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2 ;# 104 call_value_internal_symref
+ ldi 256,%r24 ;# 103 reload_outsi+2/2
+ ldi 1,%r20 ;# 8732 movqi+1/2
+ ldo 97(%r4),%r19 ;# 8736 addsi3/2
+ ldo 122(%r4),%r4 ;# 8738 addsi3/2
+ stbs,ma %r20,1(%r19) ;# 115 movqi+1/6
+L$1155
+ comb,>=,n %r4,%r19,L$1155 ;# 121 bleu+1
+ stbs,ma %r20,1(%r19) ;# 115 movqi+1/6
+ ldi 1,%r21 ;# 8717 movqi+1/2
+ addil LR're_syntax_table-$global$,%r27 ;# 8712 pic2_lo_sum+1
+ ldo RR're_syntax_table-$global$(%r1),%r19 ;# 8715 movhi-2
+ ldo 65(%r19),%r20 ;# 8721 addsi3/2
+ ldo 90(%r19),%r19 ;# 8723 addsi3/2
+ stbs,ma %r21,1(%r20) ;# 138 movqi+1/6
+L$1156
+ comb,>=,n %r19,%r20,L$1156 ;# 144 bleu+1
+ stbs,ma %r21,1(%r20) ;# 138 movqi+1/6
+ ldi 48,%r20 ;# 151 reload_outsi+2/2
+ ldi 57,%r22 ;# 7976 reload_outsi+2/2
+ ldi 1,%r21 ;# 8707 movqi+1/2
+ addil LR're_syntax_table-$global$+48,%r27 ;# 8705 pic2_lo_sum+1
+ ldo RR're_syntax_table-$global$+48(%r1),%r19 ;# 8711 movhi-2
+L$0037
+ ldo 1(%r20),%r20 ;# 164 addsi3/2
+ comb,>= %r22,%r20,L$0037 ;# 167 bleu+1
+ stbs,ma %r21,1(%r19) ;# 161 movqi+1/6
+ addil LR're_syntax_table-$global$,%r27 ;# 174 pic2_lo_sum+1
+ ldo RR're_syntax_table-$global$(%r1),%r19 ;# 175 movhi-2
+ ldi 1,%r20 ;# 176 movqi+1/2
+ stb %r20,95(%r19) ;# 177 movqi+1/6
+ addil LR'done___2-$global$,%r27 ;# 178 pic2_lo_sum+1
+ ldi 1,%r19 ;# 180 reload_outsi+2/2
+ stw %r19,RR'done___2-$global$(%r1) ;# 181 reload_outsi+2/6
+L$0022
+ ldw 4(%r5),%r19 ;# 187 reload_outsi+2/5
+ comib,<>,n 0,%r19,L$0039 ;# 189 bleu+1
+ ldw 0(%r5),%r26 ;# 193 reload_outsi+2/5
+ comib,=,n 0,%r26,L$0040 ;# 195 bleu+1
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 205 call_value_internal_symref
+ ldi 32,%r25 ;# 203 reload_outsi+2/2
+ bl L$1157,%r0 ;# 211 jump
+ stw %r28,0(%r5) ;# 223 reload_outsi+2/6
+L$0040
+ .CALL ARGW0=GR
+ bl malloc,%r2 ;# 219 call_value_internal_symref
+ ldi 32,%r26 ;# 217 reload_outsi+2/2
+ stw %r28,0(%r5) ;# 223 reload_outsi+2/6
+L$1157
+ ldw 0(%r5),%r19 ;# 228 reload_outsi+2/5
+ comib,<> 0,%r19,L$0042 ;# 230 bleu+1
+ ldi 32,%r19 ;# 243 reload_outsi+2/2
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 234 call_internal_symref
+ ldw -312(%r30),%r26 ;# 232 reload_outsi+2/5
+ bl L$0867,%r0 ;# 238 jump
+ ldi 12,%r28 ;# 51 reload_outsi+2/2
+L$0042
+ stw %r19,4(%r5) ;# 244 reload_outsi+2/6
+L$0039
+ ldw 0(%r5),%r6 ;# 249 reload_outsi+2/5
+ ldw -296(%r30),%r19 ;# 7981 reload_outsi+2/5
+ comclr,<> %r16,%r19,%r0 ;# 7982 bleu+1
+ bl L$0044,%r0
+ copy %r6,%r12 ;# 253 reload_outsi+2/1
+ ldw -296(%r30),%r19 ;# 2334 reload_outsi+2/5
+L$1178
+ ldbs,ma 1(%r19),%r7 ;# 277 zero_extendqisi2/2
+ comib,= 0,%r14,L$0047 ;# 282 bleu+1
+ stw %r19,-296(%r30) ;# 2337 reload_outsi+2/6
+ addl %r14,%r7,%r19 ;# 283 addsi3/1
+ ldb 0(%r19),%r7 ;# 286 zero_extendqisi2/2
+L$0047
+ ldo -10(%r7),%r19 ;# 7895 addsi3/2
+ addi,uv -115,%r19,%r0 ;# 7896 casesi0
+ blr,n %r19,%r0
+ b,n L$0076
+L$0863
+ bl L$0376,%r0
+ nop ;# 9092 switch_jump
+L$0954
+ bl L$0076,%r0
+ nop ;# 9095 switch_jump
+L$0955
+ bl L$0076,%r0
+ nop ;# 9098 switch_jump
+L$0956
+ bl L$0076,%r0
+ nop ;# 9101 switch_jump
+L$0957
+ bl L$0076,%r0
+ nop ;# 9104 switch_jump
+L$0958
+ bl L$0076,%r0
+ nop ;# 9107 switch_jump
+L$0959
+ bl L$0076,%r0
+ nop ;# 9110 switch_jump
+L$0960
+ bl L$0076,%r0
+ nop ;# 9113 switch_jump
+L$0961
+ bl L$0076,%r0
+ nop ;# 9116 switch_jump
+L$0962
+ bl L$0076,%r0
+ nop ;# 9119 switch_jump
+L$0963
+ bl L$0076,%r0
+ nop ;# 9122 switch_jump
+L$0964
+ bl L$0076,%r0
+ nop ;# 9125 switch_jump
+L$0965
+ bl L$0076,%r0
+ nop ;# 9128 switch_jump
+L$0966
+ bl L$0076,%r0
+ nop ;# 9131 switch_jump
+L$0967
+ bl L$0076,%r0
+ nop ;# 9134 switch_jump
+L$0968
+ bl L$0076,%r0
+ nop ;# 9137 switch_jump
+L$0969
+ bl L$0076,%r0
+ nop ;# 9140 switch_jump
+L$0970
+ bl L$0076,%r0
+ nop ;# 9143 switch_jump
+L$0971
+ bl L$0076,%r0
+ nop ;# 9146 switch_jump
+L$0972
+ bl L$0076,%r0
+ nop ;# 9149 switch_jump
+L$0973
+ bl L$0076,%r0
+ nop ;# 9152 switch_jump
+L$0974
+ bl L$0076,%r0
+ nop ;# 9155 switch_jump
+L$0975
+ bl L$0076,%r0
+ nop ;# 9158 switch_jump
+L$0976
+ bl L$0076,%r0
+ nop ;# 9161 switch_jump
+L$0977
+ bl L$0076,%r0
+ nop ;# 9164 switch_jump
+L$0978
+ bl L$0076,%r0
+ nop ;# 9167 switch_jump
+L$0979
+ bl L$0077,%r0 ;# 9170 switch_jump
+ ldw -296(%r30),%r26 ;# 2349 reload_outsi+2/5
+L$0980
+ bl L$0076,%r0
+ nop ;# 9173 switch_jump
+L$0981
+ bl L$0076,%r0
+ nop ;# 9176 switch_jump
+L$0982
+ bl L$0076,%r0
+ nop ;# 9179 switch_jump
+L$0983
+ bl L$0368,%r0
+ nop ;# 9182 switch_jump
+L$0984
+ bl L$0372,%r0
+ nop ;# 9185 switch_jump
+L$0985
+ bl L$0104,%r0
+ nop ;# 9188 switch_jump
+L$0986
+ bl L$1158,%r0 ;# 9191 switch_jump
+ ldi 1026,%r19 ;# 662 reload_outsi+2/2
+L$0987
+ bl L$0076,%r0
+ nop ;# 9194 switch_jump
+L$0988
+ bl L$0076,%r0
+ nop ;# 9197 switch_jump
+L$0989
+ bl L$0196,%r0 ;# 9200 switch_jump
+ ldw 0(%r5),%r4 ;# 8027 reload_outsi+2/5
+L$0990
+ bl L$0076,%r0
+ nop ;# 9203 switch_jump
+L$0991
+ bl L$0076,%r0
+ nop ;# 9206 switch_jump
+L$0992
+ bl L$0076,%r0
+ nop ;# 9209 switch_jump
+L$0993
+ bl L$0076,%r0
+ nop ;# 9212 switch_jump
+L$0994
+ bl L$0076,%r0
+ nop ;# 9215 switch_jump
+L$0995
+ bl L$0076,%r0
+ nop ;# 9218 switch_jump
+L$0996
+ bl L$0076,%r0
+ nop ;# 9221 switch_jump
+L$0997
+ bl L$0076,%r0
+ nop ;# 9224 switch_jump
+L$0998
+ bl L$0076,%r0
+ nop ;# 9227 switch_jump
+L$0999
+ bl L$0076,%r0
+ nop ;# 9230 switch_jump
+L$1000
+ bl L$0076,%r0
+ nop ;# 9233 switch_jump
+L$1001
+ bl L$0076,%r0
+ nop ;# 9236 switch_jump
+L$1002
+ bl L$0076,%r0
+ nop ;# 9239 switch_jump
+L$1003
+ bl L$0076,%r0
+ nop ;# 9242 switch_jump
+L$1004
+ bl L$0076,%r0
+ nop ;# 9245 switch_jump
+L$1005
+ bl L$0076,%r0
+ nop ;# 9248 switch_jump
+L$1006
+ bl L$0101,%r0 ;# 9251 switch_jump
+ ldi 1026,%r19 ;# 662 reload_outsi+2/2
+L$1007
+ bl L$0076,%r0
+ nop ;# 9254 switch_jump
+L$1008
+ bl L$0076,%r0
+ nop ;# 9257 switch_jump
+L$1009
+ bl L$0076,%r0
+ nop ;# 9260 switch_jump
+L$1010
+ bl L$0076,%r0
+ nop ;# 9263 switch_jump
+L$1011
+ bl L$0076,%r0
+ nop ;# 9266 switch_jump
+L$1012
+ bl L$0076,%r0
+ nop ;# 9269 switch_jump
+L$1013
+ bl L$0076,%r0
+ nop ;# 9272 switch_jump
+L$1014
+ bl L$0076,%r0
+ nop ;# 9275 switch_jump
+L$1015
+ bl L$0076,%r0
+ nop ;# 9278 switch_jump
+L$1016
+ bl L$0076,%r0
+ nop ;# 9281 switch_jump
+L$1017
+ bl L$0076,%r0
+ nop ;# 9284 switch_jump
+L$1018
+ bl L$0076,%r0
+ nop ;# 9287 switch_jump
+L$1019
+ bl L$0076,%r0
+ nop ;# 9290 switch_jump
+L$1020
+ bl L$0076,%r0
+ nop ;# 9293 switch_jump
+L$1021
+ bl L$0076,%r0
+ nop ;# 9296 switch_jump
+L$1022
+ bl L$0076,%r0
+ nop ;# 9299 switch_jump
+L$1023
+ bl L$0076,%r0
+ nop ;# 9302 switch_jump
+L$1024
+ bl L$0076,%r0
+ nop ;# 9305 switch_jump
+L$1025
+ bl L$0076,%r0
+ nop ;# 9308 switch_jump
+L$1026
+ bl L$0076,%r0
+ nop ;# 9311 switch_jump
+L$1027
+ bl L$0076,%r0
+ nop ;# 9314 switch_jump
+L$1028
+ bl L$0076,%r0
+ nop ;# 9317 switch_jump
+L$1029
+ bl L$0076,%r0
+ nop ;# 9320 switch_jump
+L$1030
+ bl L$0076,%r0
+ nop ;# 9323 switch_jump
+L$1031
+ bl L$0076,%r0
+ nop ;# 9326 switch_jump
+L$1032
+ bl L$0076,%r0
+ nop ;# 9329 switch_jump
+L$1033
+ bl L$0076,%r0
+ nop ;# 9332 switch_jump
+L$1034
+ bl L$0216,%r0 ;# 9335 switch_jump
+ ldw -296(%r30),%r19 ;# 2418 reload_outsi+2/5
+L$1035
+ bl L$0387,%r0 ;# 9338 switch_jump
+ ldw -296(%r30),%r19 ;# 3797 reload_outsi+2/5
+L$1036
+ bl L$0076,%r0
+ nop ;# 9341 switch_jump
+L$1037
+ bl L$0053,%r0 ;# 9344 switch_jump
+ ldw -276(%r30),%r1 ;# 8777 reload_outsi+2/5
+L$1038
+ bl L$0076,%r0
+ nop ;# 9347 switch_jump
+L$1039
+ bl L$0076,%r0
+ nop ;# 9350 switch_jump
+L$1040
+ bl L$0076,%r0
+ nop ;# 9353 switch_jump
+L$1041
+ bl L$0076,%r0
+ nop ;# 9356 switch_jump
+L$1042
+ bl L$0076,%r0
+ nop ;# 9359 switch_jump
+L$1043
+ bl L$0076,%r0
+ nop ;# 9362 switch_jump
+L$1044
+ bl L$0076,%r0
+ nop ;# 9365 switch_jump
+L$1045
+ bl L$0076,%r0
+ nop ;# 9368 switch_jump
+L$1046
+ bl L$0076,%r0
+ nop ;# 9371 switch_jump
+L$1047
+ bl L$0076,%r0
+ nop ;# 9374 switch_jump
+L$1048
+ bl L$0076,%r0
+ nop ;# 9377 switch_jump
+L$1049
+ bl L$0076,%r0
+ nop ;# 9380 switch_jump
+L$1050
+ bl L$0076,%r0
+ nop ;# 9383 switch_jump
+L$1051
+ bl L$0076,%r0
+ nop ;# 9386 switch_jump
+L$1052
+ bl L$0076,%r0
+ nop ;# 9389 switch_jump
+L$1053
+ bl L$0076,%r0
+ nop ;# 9392 switch_jump
+L$1054
+ bl L$0076,%r0
+ nop ;# 9395 switch_jump
+L$1055
+ bl L$0076,%r0
+ nop ;# 9398 switch_jump
+L$1056
+ bl L$0076,%r0
+ nop ;# 9401 switch_jump
+L$1057
+ bl L$0076,%r0
+ nop ;# 9404 switch_jump
+L$1058
+ bl L$0076,%r0
+ nop ;# 9407 switch_jump
+L$1059
+ bl L$0076,%r0
+ nop ;# 9410 switch_jump
+L$1060
+ bl L$0076,%r0
+ nop ;# 9413 switch_jump
+L$1061
+ bl L$0076,%r0
+ nop ;# 9416 switch_jump
+L$1062
+ bl L$0076,%r0
+ nop ;# 9419 switch_jump
+L$1063
+ bl L$0076,%r0
+ nop ;# 9422 switch_jump
+L$1064
+ bl L$0076,%r0
+ nop ;# 9425 switch_jump
+L$1065
+ bl L$0076,%r0
+ nop ;# 9428 switch_jump
+L$1066
+ bl L$0383,%r0 ;# 9431 switch_jump
+ ldi 4608,%r20 ;# 3778 reload_outsi+2/2
+L$1067
+ bl L$0380,%r0
+ nop ;# 9434 switch_jump
+L$1068
+ bl,n L$0076,%r0 ;# 7899 jump
+L$0053
+ ldw -296(%r30),%r25 ;# 2343 reload_outsi+2/5
+ ldo 1(%r1),%r19 ;# 306 addsi3/2
+ comb,=,n %r19,%r25,L$0055 ;# 308 bleu+1
+ bb,< %r15,28,L$0055 ;# 313 bleu+3
+ ldw -276(%r30),%r26 ;# 315 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl at_begline_loc_p,%r2 ;# 321 call_value_internal_symref
+ copy %r15,%r24 ;# 319 reload_outsi+2/1
+ extrs %r28,31,8,%r28 ;# 324 extendqisi2
+ comiclr,<> 0,%r28,%r0 ;# 326 bleu+1
+ bl,n L$0076,%r0
+L$0055
+ ldw 0(%r5),%r4 ;# 7986 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 7989 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 7987 subsi3/1
+ ldo 1(%r19),%r19 ;# 7988 addsi3/2
+ comb,>>=,n %r20,%r19,L$0060 ;# 7990 bleu+1
+ ldil L'65536,%r3 ;# 8701 reload_outsi+2/3
+L$0061
+ comclr,<> %r3,%r20,%r0 ;# 357 bleu+1
+ bl L$0944,%r0
+ zdep %r20,30,31,%r19 ;# 367 ashlsi3+1
+ comb,>>= %r3,%r19,L$0066 ;# 375 bleu+1
+ stw %r19,4(%r5) ;# 369 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 378 reload_outsi+2/6
+L$0066
+ ldw 0(%r5),%r26 ;# 385 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 389 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 387 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 397 bleu+1
+ stw %r28,0(%r5) ;# 393 reload_outsi+2/6
+ comb,= %r28,%r4,L$0059 ;# 407 bleu+1
+ sub %r6,%r4,%r19 ;# 409 subsi3/1
+ addl %r28,%r19,%r6 ;# 412 addsi3/1
+ sub %r12,%r4,%r19 ;# 413 subsi3/1
+ comib,= 0,%r10,L$0069 ;# 418 bleu+1
+ addl %r28,%r19,%r12 ;# 416 addsi3/1
+ sub %r10,%r4,%r19 ;# 419 subsi3/1
+ addl %r28,%r19,%r10 ;# 422 addsi3/1
+L$0069
+ comib,= 0,%r8,L$0070 ;# 425 bleu+1
+ sub %r8,%r4,%r19 ;# 426 subsi3/1
+ addl %r28,%r19,%r8 ;# 429 addsi3/1
+L$0070
+ comib,= 0,%r9,L$0059 ;# 432 bleu+1
+ sub %r9,%r4,%r19 ;# 433 subsi3/1
+ addl %r28,%r19,%r9 ;# 436 addsi3/1
+L$0059
+ ldw 0(%r5),%r4 ;# 337 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 341 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 338 subsi3/1
+ ldo 1(%r19),%r19 ;# 339 addsi3/2
+ comb,<< %r20,%r19,L$0061
+ nop ;# 343 bleu+1
+L$0060
+ ldi 8,%r19 ;# 458 movqi+1/2
+ bl L$0043,%r0 ;# 479 jump
+ stbs,ma %r19,1(%r6) ;# 459 movqi+1/6
+L$0077
+ comb,=,n %r16,%r26,L$0079 ;# 485 bleu+1
+ bb,< %r15,28,L$0079 ;# 490 bleu+3
+ copy %r16,%r25 ;# 494 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl at_endline_loc_p,%r2 ;# 498 call_value_internal_symref
+ copy %r15,%r24 ;# 496 reload_outsi+2/1
+ extrs %r28,31,8,%r28 ;# 501 extendqisi2
+ comiclr,<> 0,%r28,%r0 ;# 503 bleu+1
+ bl,n L$0076,%r0
+L$0079
+ ldw 0(%r5),%r4 ;# 7994 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 7997 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 7995 subsi3/1
+ ldo 1(%r19),%r19 ;# 7996 addsi3/2
+ comb,>>=,n %r20,%r19,L$0084 ;# 7998 bleu+1
+ ldil L'65536,%r3 ;# 8699 reload_outsi+2/3
+L$0085
+ comclr,<> %r3,%r20,%r0 ;# 534 bleu+1
+ bl L$0944,%r0
+ zdep %r20,30,31,%r19 ;# 544 ashlsi3+1
+ comb,>>= %r3,%r19,L$0090 ;# 552 bleu+1
+ stw %r19,4(%r5) ;# 546 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 555 reload_outsi+2/6
+L$0090
+ ldw 0(%r5),%r26 ;# 562 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 566 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 564 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 574 bleu+1
+ stw %r28,0(%r5) ;# 570 reload_outsi+2/6
+ comb,= %r28,%r4,L$0083 ;# 584 bleu+1
+ sub %r6,%r4,%r19 ;# 586 subsi3/1
+ addl %r28,%r19,%r6 ;# 589 addsi3/1
+ sub %r12,%r4,%r19 ;# 590 subsi3/1
+ comib,= 0,%r10,L$0093 ;# 595 bleu+1
+ addl %r28,%r19,%r12 ;# 593 addsi3/1
+ sub %r10,%r4,%r19 ;# 596 subsi3/1
+ addl %r28,%r19,%r10 ;# 599 addsi3/1
+L$0093
+ comib,= 0,%r8,L$0094 ;# 602 bleu+1
+ sub %r8,%r4,%r19 ;# 603 subsi3/1
+ addl %r28,%r19,%r8 ;# 606 addsi3/1
+L$0094
+ comib,= 0,%r9,L$0083 ;# 609 bleu+1
+ sub %r9,%r4,%r19 ;# 610 subsi3/1
+ addl %r28,%r19,%r9 ;# 613 addsi3/1
+L$0083
+ ldw 0(%r5),%r4 ;# 514 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 518 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 515 subsi3/1
+ ldo 1(%r19),%r19 ;# 516 addsi3/2
+ comb,<< %r20,%r19,L$0085
+ nop ;# 520 bleu+1
+L$0084
+ ldi 9,%r19 ;# 635 movqi+1/2
+ bl L$0043,%r0 ;# 656 jump
+ stbs,ma %r19,1(%r6) ;# 636 movqi+1/6
+L$0877
+ bl L$0110,%r0 ;# 897 jump
+ stw %r21,-296(%r30) ;# 2391 reload_outsi+2/6
+L$0101
+L$1158
+ and %r15,%r19,%r19 ;# 663 andsi3/1
+ comiclr,= 0,%r19,%r0 ;# 665 bleu+1
+ bl,n L$0076,%r0
+L$0104
+ comib,<> 0,%r8,L$0105 ;# 674 bleu+1
+ ldi 0,%r13 ;# 711 reload_outsi+2/2
+ extrs,>= %r15,26,1,%r0 ;# 681 bleu+3
+ extrs,< %r15,27,1,%r0 ;# 700 movsi-4
+ nop
+ bl,n L$0076,%r0
+L$0105
+ ldi 0,%r11 ;# 714 reload_outsi+2/2
+ ldi 0,%r22 ;# 716 reload_outsi+2/2
+ ldi 43,%r24 ;# 8688 reload_outsi+2/2
+ ldi 63,%r23 ;# 8690 reload_outsi+2/2
+ ldi 42,%r28 ;# 8692 reload_outsi+2/2
+ ldi 2,%r19 ;# 8694 reload_outsi+2/2
+ and %r15,%r19,%r25 ;# 8695 andsi3/1
+ ldi 92,%r26 ;# 8697 reload_outsi+2/2
+L$0109
+ comb,= %r24,%r7,L$0112 ;# 727 bleu+1
+ copy %r11,%r19 ;# 8780 reload_outsi+2/1
+ depi -1,31,1,%r19 ;# 729 iorsi3+1/2
+ bl L$0113,%r0 ;# 731 jump
+ extrs %r19,31,8,%r19 ;# 730 extendqisi2
+L$0112
+ extrs %r11,31,8,%r19 ;# 734 extendqisi2
+L$0113
+L$1159
+ comb,= %r23,%r7,L$0114 ;# 744 bleu+1
+ copy %r19,%r11 ;# 737 reload_outsi+2/1
+ copy %r22,%r19 ;# 8783 reload_outsi+2/1
+ depi -1,31,1,%r19 ;# 746 iorsi3+1/2
+ bl L$0115,%r0 ;# 748 jump
+ extrs %r19,31,8,%r19 ;# 747 extendqisi2
+L$0114
+ extrs %r22,31,8,%r19 ;# 751 extendqisi2
+L$0115
+ ldw -296(%r30),%r21 ;# 2355 reload_outsi+2/5
+ comb,= %r16,%r21,L$0110 ;# 757 bleu+1
+ copy %r19,%r22 ;# 754 reload_outsi+2/1
+ copy %r21,%r20 ;# 8743 reload_outsi+2/1
+ ldbs,ma 1(%r20),%r7 ;# 776 zero_extendqisi2/2
+ comib,= 0,%r14,L$0118 ;# 781 bleu+1
+ stw %r20,-296(%r30) ;# 2364 reload_outsi+2/6
+ addl %r14,%r7,%r19 ;# 782 addsi3/1
+ ldb 0(%r19),%r7 ;# 785 zero_extendqisi2/2
+L$0118
+ comb,= %r28,%r7,L$0109
+ nop ;# 802 bleu+1
+ comib,<>,n 0,%r25,L$0869 ;# 807 bleu+1
+ comb,= %r24,%r7,L$1159 ;# 811 bleu+1
+ extrs %r11,31,8,%r19 ;# 734 extendqisi2
+ comb,= %r23,%r7,L$0109 ;# 815 bleu+1
+ ldw -296(%r30),%r19 ;# 2400 reload_outsi+2/5
+ bl,n L$1160,%r0 ;# 827 jump
+L$0869
+ comb,<> %r26,%r7,L$0126 ;# 831 bleu+1
+ ldw -296(%r30),%r19 ;# 2400 reload_outsi+2/5
+ comclr,<> %r16,%r20,%r0 ;# 835 bleu+1
+ bl L$0903,%r0
+ ldo 1(%r20),%r19 ;# 863 addsi3/2
+ ldb 1(%r21),%r3 ;# 860 zero_extendqisi2/2
+ comib,= 0,%r14,L$0129 ;# 865 bleu+1
+ stw %r19,-296(%r30) ;# 2379 reload_outsi+2/6
+ addl %r14,%r3,%r19 ;# 866 addsi3/1
+ ldb 0(%r19),%r3 ;# 869 zero_extendqisi2/2
+L$0129
+ comb,= %r24,%r3,L$0109 ;# 886 bleu+1
+ copy %r3,%r7 ;# 903 reload_outsi+2/1
+ comb,<> %r23,%r3,L$0877
+ nop ;# 890 bleu+1
+ bl,n L$0109,%r0 ;# 905 jump
+L$0126
+L$1160
+ ldo -1(%r19),%r19 ;# 910 addsi3/2
+ stw %r19,-296(%r30) ;# 2397 reload_outsi+2/6
+L$0110
+ comiclr,<> 0,%r8,%r0 ;# 927 bleu+1
+ bl L$1161,%r0
+ ldw -296(%r30),%r19 ;# 2328 reload_outsi+2/5
+ comib,=,n 0,%r22,L$0137 ;# 934 bleu+1
+ ldw 0(%r5),%r3 ;# 8002 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8005 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8003 subsi3/1
+ ldo 3(%r19),%r19 ;# 8004 addsi3/2
+ comb,>>=,n %r20,%r19,L$0139 ;# 8006 bleu+1
+ ldil L'65536,%r4 ;# 8686 reload_outsi+2/3
+L$0140
+ comclr,<> %r4,%r20,%r0 ;# 961 bleu+1
+ bl L$0944,%r0
+ zdep %r20,30,31,%r19 ;# 971 ashlsi3+1
+ comb,>>= %r4,%r19,L$0145 ;# 979 bleu+1
+ stw %r19,4(%r5) ;# 973 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 982 reload_outsi+2/6
+L$0145
+ ldw 0(%r5),%r26 ;# 989 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 993 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 991 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 1001 bleu+1
+ stw %r28,0(%r5) ;# 997 reload_outsi+2/6
+ comb,= %r28,%r3,L$0138 ;# 1011 bleu+1
+ sub %r6,%r3,%r19 ;# 1013 subsi3/1
+ addl %r28,%r19,%r6 ;# 1016 addsi3/1
+ sub %r12,%r3,%r19 ;# 1017 subsi3/1
+ comib,= 0,%r10,L$0148 ;# 1022 bleu+1
+ addl %r28,%r19,%r12 ;# 1020 addsi3/1
+ sub %r10,%r3,%r19 ;# 1023 subsi3/1
+ addl %r28,%r19,%r10 ;# 1026 addsi3/1
+L$0148
+ comib,= 0,%r8,L$0149 ;# 1029 bleu+1
+ sub %r8,%r3,%r19 ;# 1030 subsi3/1
+ addl %r28,%r19,%r8 ;# 1033 addsi3/1
+L$0149
+ comib,= 0,%r9,L$0138 ;# 1036 bleu+1
+ sub %r9,%r3,%r19 ;# 1037 subsi3/1
+ addl %r28,%r19,%r9 ;# 1040 addsi3/1
+L$0138
+ ldw 0(%r5),%r3 ;# 941 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 945 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 942 subsi3/1
+ ldo 3(%r19),%r19 ;# 943 addsi3/2
+ comb,<< %r20,%r19,L$0140
+ nop ;# 947 bleu+1
+L$0139
+ comib,= 0,%r14,L$0154 ;# 1063 bleu+1
+ ldw -296(%r30),%r19 ;# 2403 reload_outsi+2/5
+ ldb -2(%r19),%r19 ;# 1066 zero_extendqisi2/2
+ addl %r14,%r19,%r19 ;# 1067 addsi3/1
+ bl L$0947,%r0 ;# 1071 jump
+ ldb 0(%r19),%r19 ;# 1069 movqi+1/5
+L$0154
+ ldb -2(%r19),%r19 ;# 1075 movqi+1/5
+L$0947
+ comib,= 0,%r14,L$0156 ;# 1079 bleu+1
+ extrs %r19,31,8,%r20 ;# 1076 extendqisi2
+ ldb 46(%r14),%r19 ;# 1081 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 1082 extendqisi2
+ comb,= %r19,%r20,L$0157 ;# 1084 bleu+1
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+ bl,n L$1162,%r0 ;# 1085 jump
+L$0156
+ ldi 46,%r19 ;# 1089 reload_outsi+2/2
+ comb,<> %r19,%r20,L$1162 ;# 1091 bleu+1
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+L$0157
+ comib,= 0,%r11,L$0153 ;# 1096 bleu+1
+ ldw -296(%r30),%r19 ;# 2409 reload_outsi+2/5
+ comb,<<= %r16,%r19,L$1162 ;# 1098 bleu+1
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+ comib,=,n 0,%r14,L$0158 ;# 1100 bleu+1
+ ldb 0(%r19),%r19 ;# 1103 zero_extendqisi2/2
+ addl %r14,%r19,%r19 ;# 1104 addsi3/1
+L$0158
+ ldb 0(%r19),%r19 ;# 1112 movqi+1/5
+ comib,= 0,%r14,L$0160 ;# 1116 bleu+1
+ extrs %r19,31,8,%r20 ;# 1113 extendqisi2
+ ldb 10(%r14),%r19 ;# 1118 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 1119 extendqisi2
+ comb,= %r19,%r20,L$0161 ;# 1121 bleu+1
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+ bl,n L$1162,%r0 ;# 1122 jump
+L$0160
+ comib,<> 10,%r20,L$1162 ;# 1126 bleu+1
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+L$0161
+ bb,< %r15,25,L$1162 ;# 1134 bleu+3
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+ ldi 12,%r26 ;# 1140 reload_outsi+2/2
+ copy %r6,%r25 ;# 1142 reload_outsi+2/1
+ sub %r8,%r6,%r24 ;# 1137 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl store_op1,%r2 ;# 1146 call_internal_symref
+ ldo -3(%r24),%r24 ;# 1144 addsi3/2
+ bl L$0162,%r0 ;# 1151 jump
+ ldi 1,%r13 ;# 1149 reload_outsi+2/2
+L$0153
+ ldi 17,%r26 ;# 1159 reload_outsi+2/2
+L$1162
+ copy %r6,%r25 ;# 1161 reload_outsi+2/1
+ sub %r8,%r6,%r24 ;# 1156 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl store_op1,%r2 ;# 1165 call_internal_symref
+ ldo -6(%r24),%r24 ;# 1163 addsi3/2
+L$0162
+ ldo 3(%r6),%r6 ;# 1168 addsi3/2
+L$0137
+ ldw 0(%r5),%r3 ;# 8010 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8013 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8011 subsi3/1
+ ldo 3(%r19),%r19 ;# 8012 addsi3/2
+ comb,>>=,n %r20,%r19,L$0164 ;# 8014 bleu+1
+ ldil L'65536,%r4 ;# 8684 reload_outsi+2/3
+L$0165
+ comclr,<> %r4,%r20,%r0 ;# 1195 bleu+1
+ bl L$0944,%r0
+ zdep %r20,30,31,%r19 ;# 1205 ashlsi3+1
+ comb,>>= %r4,%r19,L$0170 ;# 1213 bleu+1
+ stw %r19,4(%r5) ;# 1207 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 1216 reload_outsi+2/6
+L$0170
+ ldw 0(%r5),%r26 ;# 1223 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 1227 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 1225 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 1235 bleu+1
+ stw %r28,0(%r5) ;# 1231 reload_outsi+2/6
+ comb,= %r28,%r3,L$0163 ;# 1245 bleu+1
+ sub %r6,%r3,%r19 ;# 1247 subsi3/1
+ addl %r28,%r19,%r6 ;# 1250 addsi3/1
+ sub %r12,%r3,%r19 ;# 1251 subsi3/1
+ comib,= 0,%r10,L$0173 ;# 1256 bleu+1
+ addl %r28,%r19,%r12 ;# 1254 addsi3/1
+ sub %r10,%r3,%r19 ;# 1257 subsi3/1
+ addl %r28,%r19,%r10 ;# 1260 addsi3/1
+L$0173
+ comib,= 0,%r8,L$0174 ;# 1263 bleu+1
+ sub %r8,%r3,%r19 ;# 1264 subsi3/1
+ addl %r28,%r19,%r8 ;# 1267 addsi3/1
+L$0174
+ comib,= 0,%r9,L$0163 ;# 1270 bleu+1
+ sub %r9,%r3,%r19 ;# 1271 subsi3/1
+ addl %r28,%r19,%r9 ;# 1274 addsi3/1
+L$0163
+ ldw 0(%r5),%r3 ;# 1175 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 1179 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 1176 subsi3/1
+ ldo 3(%r19),%r19 ;# 1177 addsi3/2
+ comb,<< %r20,%r19,L$0165
+ nop ;# 1181 bleu+1
+L$0164
+ ldi 14,%r26 ;# 8786 reload_outsi+2/2
+ comiclr,= 0,%r13,%r0 ;# 1310 beq-1/2
+ ldi 15,%r26
+ copy %r8,%r25 ;# 1312 reload_outsi+2/1
+ sub %r6,%r8,%r24 ;# 1314 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op1,%r2 ;# 1318 call_internal_symref
+ copy %r6,%r23 ;# 1316 reload_outsi+2/1
+ ldi 0,%r9 ;# 1321 reload_outsi+2/2
+ comib,<> 0,%r11,L$0043 ;# 1326 bleu+1
+ ldo 3(%r6),%r6 ;# 1323 addsi3/2
+ ldw 0(%r5),%r3 ;# 8019 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8022 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8020 subsi3/1
+ ldo 3(%r19),%r19 ;# 8021 addsi3/2
+ comb,>>=,n %r20,%r19,L$0182 ;# 8023 bleu+1
+ ldil L'65536,%r4 ;# 8682 reload_outsi+2/3
+L$0183
+ comb,= %r4,%r20,L$0944 ;# 1352 bleu+1
+ zdep %r20,30,31,%r19 ;# 1362 ashlsi3+1
+ comb,>>= %r4,%r19,L$0188 ;# 1370 bleu+1
+ stw %r19,4(%r5) ;# 1364 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 1373 reload_outsi+2/6
+L$0188
+ ldw 0(%r5),%r26 ;# 1380 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 1384 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 1382 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 1392 bleu+1
+ stw %r28,0(%r5) ;# 1388 reload_outsi+2/6
+ comb,= %r28,%r3,L$0181 ;# 1402 bleu+1
+ sub %r6,%r3,%r19 ;# 1404 subsi3/1
+ addl %r28,%r19,%r6 ;# 1407 addsi3/1
+ sub %r12,%r3,%r19 ;# 1408 subsi3/1
+ comib,= 0,%r10,L$0191 ;# 1413 bleu+1
+ addl %r28,%r19,%r12 ;# 1411 addsi3/1
+ sub %r10,%r3,%r19 ;# 1414 subsi3/1
+ addl %r28,%r19,%r10 ;# 1417 addsi3/1
+L$0191
+ comib,= 0,%r8,L$0192 ;# 1420 bleu+1
+ sub %r8,%r3,%r19 ;# 1421 subsi3/1
+ addl %r28,%r19,%r8 ;# 1424 addsi3/1
+L$0192
+ comib,= 0,%r9,L$0181 ;# 1427 bleu+1
+ sub %r9,%r3,%r19 ;# 1428 subsi3/1
+ addl %r28,%r19,%r9 ;# 1431 addsi3/1
+L$0181
+ ldw 0(%r5),%r3 ;# 1332 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 1336 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 1333 subsi3/1
+ ldo 3(%r19),%r19 ;# 1334 addsi3/2
+ comb,<< %r20,%r19,L$0183
+ nop ;# 1338 bleu+1
+L$0182
+ ldi 18,%r26 ;# 1454 reload_outsi+2/2
+ copy %r8,%r25 ;# 1456 reload_outsi+2/1
+ ldi 3,%r24 ;# 1458 reload_outsi+2/2
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op1,%r2 ;# 1462 call_internal_symref
+ copy %r6,%r23 ;# 1460 reload_outsi+2/1
+ bl L$0043,%r0 ;# 1470 jump
+ ldo 3(%r6),%r6 ;# 1464 addsi3/2
+L$0196
+ ldw 4(%r5),%r20 ;# 8030 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8028 subsi3/1
+ ldo 1(%r19),%r19 ;# 8029 addsi3/2
+ comb,>>= %r20,%r19,L$0201 ;# 8031 bleu+1
+ copy %r6,%r8 ;# 1475 reload_outsi+2/1
+ ldil L'65536,%r3 ;# 8680 reload_outsi+2/3
+L$0202
+ comb,= %r3,%r20,L$0944 ;# 1503 bleu+1
+ zdep %r20,30,31,%r19 ;# 1513 ashlsi3+1
+ comb,>>= %r3,%r19,L$0207 ;# 1521 bleu+1
+ stw %r19,4(%r5) ;# 1515 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 1524 reload_outsi+2/6
+L$0207
+ ldw 0(%r5),%r26 ;# 1531 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 1535 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 1533 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 1543 bleu+1
+ stw %r28,0(%r5) ;# 1539 reload_outsi+2/6
+ comb,= %r28,%r4,L$0200 ;# 1553 bleu+1
+ sub %r6,%r4,%r19 ;# 1555 subsi3/1
+ addl %r28,%r19,%r6 ;# 1558 addsi3/1
+ sub %r12,%r4,%r19 ;# 1559 subsi3/1
+ comib,= 0,%r10,L$0210 ;# 1564 bleu+1
+ addl %r28,%r19,%r12 ;# 1562 addsi3/1
+ sub %r10,%r4,%r19 ;# 1565 subsi3/1
+ addl %r28,%r19,%r10 ;# 1568 addsi3/1
+L$0210
+ comib,= 0,%r8,L$0211 ;# 1571 bleu+1
+ sub %r8,%r4,%r19 ;# 1572 subsi3/1
+ addl %r28,%r19,%r8 ;# 1575 addsi3/1
+L$0211
+ comib,= 0,%r9,L$0200 ;# 1578 bleu+1
+ sub %r9,%r4,%r19 ;# 1579 subsi3/1
+ addl %r28,%r19,%r9 ;# 1582 addsi3/1
+L$0200
+ ldw 0(%r5),%r4 ;# 1483 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 1487 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 1484 subsi3/1
+ ldo 1(%r19),%r19 ;# 1485 addsi3/2
+ comb,<< %r20,%r19,L$0202
+ nop ;# 1489 bleu+1
+L$0201
+ ldi 2,%r19 ;# 1604 movqi+1/2
+ bl L$0043,%r0 ;# 1617 jump
+ stbs,ma %r19,1(%r6) ;# 1605 movqi+1/6
+L$0216
+ comb,= %r16,%r19,L$0902 ;# 1626 bleu+1
+ ldi 0,%r13 ;# 1623 reload_outsi+2/2
+ ldw 0(%r5),%r3 ;# 8035 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8038 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8036 subsi3/1
+ ldo 34(%r19),%r19 ;# 8037 addsi3/2
+ comb,>>= %r20,%r19,L$0219 ;# 8039 bleu+1
+ ldil L'65536,%r4 ;# 8678 reload_outsi+2/3
+L$0220
+ comb,= %r4,%r20,L$0944 ;# 1661 bleu+1
+ zdep %r20,30,31,%r19 ;# 1671 ashlsi3+1
+ comb,>>= %r4,%r19,L$0225 ;# 1679 bleu+1
+ stw %r19,4(%r5) ;# 1673 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 1682 reload_outsi+2/6
+L$0225
+ ldw 0(%r5),%r26 ;# 1689 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 1693 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 1691 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 1701 bleu+1
+ stw %r28,0(%r5) ;# 1697 reload_outsi+2/6
+ comb,= %r28,%r3,L$0218 ;# 1711 bleu+1
+ sub %r6,%r3,%r19 ;# 1713 subsi3/1
+ addl %r28,%r19,%r6 ;# 1716 addsi3/1
+ sub %r12,%r3,%r19 ;# 1717 subsi3/1
+ comib,= 0,%r10,L$0228 ;# 1722 bleu+1
+ addl %r28,%r19,%r12 ;# 1720 addsi3/1
+ sub %r10,%r3,%r19 ;# 1723 subsi3/1
+ addl %r28,%r19,%r10 ;# 1726 addsi3/1
+L$0228
+ comib,= 0,%r8,L$0229 ;# 1729 bleu+1
+ sub %r8,%r3,%r19 ;# 1730 subsi3/1
+ addl %r28,%r19,%r8 ;# 1733 addsi3/1
+L$0229
+ comib,= 0,%r9,L$0218 ;# 1736 bleu+1
+ sub %r9,%r3,%r19 ;# 1737 subsi3/1
+ addl %r28,%r19,%r9 ;# 1740 addsi3/1
+L$0218
+ ldw 0(%r5),%r3 ;# 1641 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 1645 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 1642 subsi3/1
+ ldo 34(%r19),%r19 ;# 1643 addsi3/2
+ comb,<< %r20,%r19,L$0220
+ nop ;# 1647 bleu+1
+L$0219
+ ldw 0(%r5),%r4 ;# 8043 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8046 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8044 subsi3/1
+ ldo 1(%r19),%r19 ;# 8045 addsi3/2
+ comb,>>= %r20,%r19,L$0237 ;# 8047 bleu+1
+ copy %r6,%r8 ;# 1763 reload_outsi+2/1
+ ldil L'65536,%r3 ;# 8676 reload_outsi+2/3
+L$0238
+ comb,= %r3,%r20,L$0944 ;# 1791 bleu+1
+ zdep %r20,30,31,%r19 ;# 1801 ashlsi3+1
+ comb,>>= %r3,%r19,L$0243 ;# 1809 bleu+1
+ stw %r19,4(%r5) ;# 1803 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 1812 reload_outsi+2/6
+L$0243
+ ldw 0(%r5),%r26 ;# 1819 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 1823 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 1821 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 1831 bleu+1
+ stw %r28,0(%r5) ;# 1827 reload_outsi+2/6
+ comb,= %r28,%r4,L$0236 ;# 1841 bleu+1
+ sub %r6,%r4,%r19 ;# 1843 subsi3/1
+ addl %r28,%r19,%r6 ;# 1846 addsi3/1
+ sub %r12,%r4,%r19 ;# 1847 subsi3/1
+ comib,= 0,%r10,L$0246 ;# 1852 bleu+1
+ addl %r28,%r19,%r12 ;# 1850 addsi3/1
+ sub %r10,%r4,%r19 ;# 1853 subsi3/1
+ addl %r28,%r19,%r10 ;# 1856 addsi3/1
+L$0246
+ comib,= 0,%r8,L$0247 ;# 1859 bleu+1
+ sub %r8,%r4,%r19 ;# 1860 subsi3/1
+ addl %r28,%r19,%r8 ;# 1863 addsi3/1
+L$0247
+ comib,= 0,%r9,L$0236 ;# 1866 bleu+1
+ sub %r9,%r4,%r19 ;# 1867 subsi3/1
+ addl %r28,%r19,%r9 ;# 1870 addsi3/1
+L$0236
+ ldw 0(%r5),%r4 ;# 1771 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 1775 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 1772 subsi3/1
+ ldo 1(%r19),%r19 ;# 1773 addsi3/2
+ comb,<< %r20,%r19,L$0238
+ nop ;# 1777 bleu+1
+L$0237
+ copy %r6,%r22 ;# 1909 reload_outsi+2/1
+ ldo 1(%r6),%r6 ;# 1891 addsi3/2
+ ldw -296(%r30),%r19 ;# 2421 reload_outsi+2/5
+ ldb 0(%r19),%r19 ;# 1893 movqi+1/5
+ ldi 94,%r21 ;# 1896 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 1894 extendqisi2
+ comb,<> %r21,%r19,L$0251 ;# 1898 bleu+1
+ ldi 3,%r20 ;# 8051 movqi+1/2
+ ldi 4,%r20 ;# 1900 movqi+1/2
+L$0251
+ stb %r20,0(%r22) ;# 1911 movqi+1/6
+ ldw -296(%r30),%r20 ;# 2424 reload_outsi+2/5
+ ldb 0(%r20),%r19 ;# 1923 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 1924 extendqisi2
+ comb,<> %r21,%r19,L$0254 ;# 1928 bleu+1
+ ldo 1(%r20),%r19 ;# 1930 addsi3/2
+ stw %r19,-296(%r30) ;# 2427 reload_outsi+2/6
+L$0254
+ ldw 0(%r5),%r4 ;# 8052 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8055 reload_outsi+2/5
+ ldw -296(%r30),%r1 ;# 2433 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8053 subsi3/1
+ ldo 1(%r19),%r19 ;# 8054 addsi3/2
+ comb,>>= %r20,%r19,L$0259 ;# 8056 bleu+1
+ stw %r1,-268(%r30) ;# 8789 reload_outsi+2/6
+ ldil L'65536,%r3 ;# 8674 reload_outsi+2/3
+L$0260
+ comb,= %r3,%r20,L$0944 ;# 1962 bleu+1
+ zdep %r20,30,31,%r19 ;# 1972 ashlsi3+1
+ comb,>>= %r3,%r19,L$0265 ;# 1980 bleu+1
+ stw %r19,4(%r5) ;# 1974 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 1983 reload_outsi+2/6
+L$0265
+ ldw 0(%r5),%r26 ;# 1990 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 1994 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 1992 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 2002 bleu+1
+ stw %r28,0(%r5) ;# 1998 reload_outsi+2/6
+ comb,= %r28,%r4,L$0258 ;# 2012 bleu+1
+ sub %r6,%r4,%r19 ;# 2014 subsi3/1
+ addl %r28,%r19,%r6 ;# 2017 addsi3/1
+ sub %r12,%r4,%r19 ;# 2018 subsi3/1
+ comib,= 0,%r10,L$0268 ;# 2023 bleu+1
+ addl %r28,%r19,%r12 ;# 2021 addsi3/1
+ sub %r10,%r4,%r19 ;# 2024 subsi3/1
+ addl %r28,%r19,%r10 ;# 2027 addsi3/1
+L$0268
+ comib,= 0,%r8,L$0269 ;# 2030 bleu+1
+ sub %r8,%r4,%r19 ;# 2031 subsi3/1
+ addl %r28,%r19,%r8 ;# 2034 addsi3/1
+L$0269
+ comib,= 0,%r9,L$0258 ;# 2037 bleu+1
+ sub %r9,%r4,%r19 ;# 2038 subsi3/1
+ addl %r28,%r19,%r9 ;# 2041 addsi3/1
+L$0258
+ ldw 0(%r5),%r4 ;# 1942 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 1946 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 1943 subsi3/1
+ ldo 1(%r19),%r19 ;# 1944 addsi3/2
+ comb,<< %r20,%r19,L$0260
+ nop ;# 1948 bleu+1
+L$0259
+ ldi 32,%r19 ;# 2063 movqi+1/2
+ stbs,ma %r19,1(%r6) ;# 2064 movqi+1/6
+ copy %r6,%r26 ;# 2077 reload_outsi+2/1
+ ldi 0,%r25 ;# 2079 reload_outsi+2/2
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl memset,%r2 ;# 2083 call_value_internal_symref
+ ldi 32,%r24 ;# 2081 reload_outsi+2/2
+ ldb -2(%r6),%r19 ;# 2087 zero_extendqisi2/2
+ comib,<> 4,%r19,L$0274 ;# 2089 bleu+1
+ ldi 93,%r17 ;# 8622 reload_outsi+2/2
+ bb,>=,n %r15,23,L$0274 ;# 2094 movsi-4
+ ldb 1(%r6),%r19 ;# 2097 movqi+1/5
+ depi -1,29,1,%r19 ;# 2099 iorsi3+1/2
+ stb %r19,1(%r6) ;# 2101 movqi+1/6
+L$0274
+ ldi 4,%r18 ;# 8628 reload_outsi+2/2
+ and %r15,%r18,%r1 ;# 8629 andsi3/1
+ stw %r1,-252(%r30) ;# 8792 reload_outsi+2/6
+ ldo -288(%r30),%r11 ;# 8632 addsi3/2
+L$0275
+ ldw -296(%r30),%r20 ;# 2436 reload_outsi+2/5
+L$1165
+ comb,= %r16,%r20,L$0902 ;# 2109 bleu+1
+ copy %r20,%r21 ;# 8745 reload_outsi+2/1
+ ldbs,ma 1(%r21),%r7 ;# 2134 zero_extendqisi2/2
+ comib,= 0,%r14,L$0280 ;# 2139 bleu+1
+ stw %r21,-296(%r30) ;# 2445 reload_outsi+2/6
+ addl %r14,%r7,%r19 ;# 2140 addsi3/1
+ ldb 0(%r19),%r7 ;# 2143 zero_extendqisi2/2
+L$0280
+ bb,>= %r15,31,L$0285 ;# 2159 movsi-4
+ ldi 92,%r19 ;# 2161 reload_outsi+2/2
+ comb,<>,n %r19,%r7,L$0285 ;# 2163 bleu+1
+ comb,= %r16,%r21,L$0903 ;# 2167 bleu+1
+ ldo 1(%r21),%r19 ;# 2195 addsi3/2
+ ldb 1(%r20),%r3 ;# 2192 zero_extendqisi2/2
+ comib,= 0,%r14,L$0288 ;# 2197 bleu+1
+ stw %r19,-296(%r30) ;# 2460 reload_outsi+2/6
+ addl %r14,%r3,%r19 ;# 2198 addsi3/1
+ ldb 0(%r19),%r3 ;# 2201 zero_extendqisi2/2
+L$0288
+ extru %r3,28,29,%r19 ;# 2216 lshrsi3/2
+ addl %r6,%r19,%r19 ;# 2219 addsi3/1
+ bl L$0948,%r0 ;# 2235 jump
+ extru %r3,31,3,%r20 ;# 2222 andsi3/1
+L$0285
+ comb,<>,n %r17,%r7,L$0293 ;# 2243 bleu+1
+ ldw -268(%r30),%r1 ;# 8798 reload_outsi+2/5
+ ldw -296(%r30),%r20 ;# 2466 reload_outsi+2/5
+ ldo 1(%r1),%r19 ;# 2244 addsi3/2
+ comb,<>,n %r19,%r20,L$0276 ;# 2246 bleu+1
+L$0293
+ comib,= 0,%r13,L$0294 ;# 2253 bleu+1
+ ldi 45,%r1 ;# 8801 reload_outsi+2/2
+ comb,<> %r1,%r7,L$1163 ;# 2257 bleu+1
+ ldw -296(%r30),%r20 ;# 2524 reload_outsi+2/5
+ ldw -296(%r30),%r19 ;# 2469 reload_outsi+2/5
+ ldb 0(%r19),%r19 ;# 2259 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 2260 extendqisi2
+ comb,<>,n %r17,%r19,L$0895 ;# 2264 bleu+1
+L$0294
+ ldi 45,%r1 ;# 8804 reload_outsi+2/2
+ comb,<> %r1,%r7,L$1163 ;# 2280 bleu+1
+ ldw -296(%r30),%r20 ;# 2524 reload_outsi+2/5
+ ldw -276(%r30),%r1 ;# 8807 reload_outsi+2/5
+ ldo -2(%r20),%r19 ;# 2281 addsi3/2
+ comb,>>,n %r1,%r19,L$1179 ;# 2283 bleu+1
+ ldb -2(%r20),%r19 ;# 2285 movqi+1/5
+ ldi 91,%r1 ;# 8810 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 2286 extendqisi2
+ comb,= %r1,%r19,L$1163 ;# 2290 bleu+1
+ ldw -276(%r30),%r1 ;# 8813 reload_outsi+2/5
+L$1179
+ ldo -3(%r20),%r19 ;# 2294 addsi3/2
+ comb,>>,n %r1,%r19,L$0297 ;# 2296 bleu+1
+ ldb -3(%r20),%r19 ;# 2298 movqi+1/5
+ ldi 91,%r1 ;# 8816 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 2299 extendqisi2
+ comb,<> %r1,%r19,L$1164 ;# 2303 bleu+1
+ ldw -296(%r30),%r19 ;# 2487 reload_outsi+2/5
+ ldb -2(%r20),%r19 ;# 2305 movqi+1/5
+ ldi 94,%r20 ;# 2308 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 2306 extendqisi2
+ comb,= %r20,%r19,L$1163 ;# 2310 bleu+1
+ ldw -296(%r30),%r20 ;# 2524 reload_outsi+2/5
+L$0297
+ ldw -296(%r30),%r19 ;# 2487 reload_outsi+2/5
+L$1164
+ ldb 0(%r19),%r19 ;# 2315 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 2316 extendqisi2
+ comb,<> %r17,%r19,L$0302 ;# 2320 bleu+1
+ ldw -296(%r30),%r20 ;# 2524 reload_outsi+2/5
+L$1163
+ ldb 0(%r20),%r19 ;# 2526 movqi+1/5
+ ldi 45,%r1 ;# 8819 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 2527 extendqisi2
+ comb,<>,n %r1,%r19,L$0300 ;# 2531 bleu+1
+ ldb 1(%r20),%r19 ;# 2535 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 2536 extendqisi2
+ comb,=,n %r17,%r19,L$0300 ;# 2540 bleu+1
+ comb,= %r16,%r20,L$0922 ;# 2550 bleu+1
+ ldo 1(%r20),%r19 ;# 2559 addsi3/2
+ stw %r19,-296(%r30) ;# 2561 reload_outsi+2/6
+L$0302
+ stw %r6,-52(%r30) ;# 2588 reload_outsi+2/6
+ ldo -296(%r30),%r26 ;# 2590 addsi3/2
+ copy %r16,%r25 ;# 2592 reload_outsi+2/1
+ copy %r14,%r24 ;# 2594 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl compile_range,%r2 ;# 2598 call_value_internal_symref
+ copy %r15,%r23 ;# 2596 reload_outsi+2/1
+ movb,= %r28,%r4,L$1165 ;# 2603 decrement_and_branch_until_zero+2/1
+ ldw -296(%r30),%r20 ;# 2436 reload_outsi+2/5
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 2607 call_internal_symref
+ ldw -312(%r30),%r26 ;# 2605 reload_outsi+2/5
+ bl L$0867,%r0 ;# 2611 jump
+ copy %r4,%r28 ;# 2609 reload_outsi+2/1
+L$0300
+ ldw -252(%r30),%r1 ;# 8822 reload_outsi+2/5
+ comib,= 0,%r1,L$0309 ;# 2624 bleu+1
+ ldi 91,%r1 ;# 8825 reload_outsi+2/2
+ comb,<> %r1,%r7,L$1166 ;# 2628 bleu+1
+ ldi 0,%r13 ;# 3624 reload_outsi+2/2
+ ldw -296(%r30),%r20 ;# 2630 reload_outsi+2/5
+ ldb 0(%r20),%r19 ;# 2632 movqi+1/5
+ ldi 58,%r1 ;# 8828 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 2633 extendqisi2
+ comb,<>,n %r1,%r19,L$1166 ;# 2637 bleu+1
+ comb,= %r16,%r20,L$0922 ;# 2647 bleu+1
+ ldo 1(%r20),%r19 ;# 2656 addsi3/2
+ stw %r19,-296(%r30) ;# 2658 reload_outsi+2/6
+ comb,= %r16,%r19,L$0902 ;# 2689 bleu+1
+ ldi 0,%r3 ;# 2684 reload_outsi+2/2
+L$0317
+ ldw -296(%r30),%r19 ;# 2709 reload_outsi+2/5
+ comb,= %r16,%r19,L$0922 ;# 2711 bleu+1
+ ldo 1(%r19),%r20 ;# 2720 addsi3/2
+ stw %r20,-296(%r30) ;# 2722 reload_outsi+2/6
+ comib,= 0,%r14,L$0321 ;# 2729 bleu+1
+ ldb 0(%r19),%r7 ;# 2725 zero_extendqisi2/2
+ addl %r14,%r7,%r19 ;# 2730 addsi3/1
+ ldb 0(%r19),%r7 ;# 2733 zero_extendqisi2/2
+L$0321
+ ldi 58,%r1 ;# 8831 reload_outsi+2/2
+ comb,= %r1,%r7,L$1167 ;# 2750 bleu+1
+ addl %r11,%r3,%r19 ;# 2789 addsi3/1
+ comb,=,n %r17,%r7,L$1167 ;# 2754 bleu+1
+ comb,=,n %r16,%r20,L$1167 ;# 2758 bleu+1
+ comib,= 6,%r3,L$1167 ;# 2760 bleu+1
+ copy %r3,%r20 ;# 2770 reload_outsi+2/1
+ ldo 1(%r20),%r19 ;# 2771 addsi3/2
+ extru %r19,31,8,%r3 ;# 2772 zero_extendqisi2/1
+ addl %r11,%r20,%r20 ;# 2776 addsi3/1
+ bl L$0317,%r0 ;# 2783 jump
+ stb %r7,0(%r20) ;# 2778 movqi+1/6
+L$1167
+ comb,<> %r1,%r7,L$0328 ;# 2796 bleu+1
+ stb %r0,0(%r19) ;# 2791 movqi+1/6
+ ldw -296(%r30),%r19 ;# 2798 reload_outsi+2/5
+ ldb 0(%r19),%r19 ;# 2800 movqi+1/5
+ extrs %r19,31,8,%r19 ;# 2801 extendqisi2
+ comb,<> %r17,%r19,L$1168 ;# 2805 bleu+1
+ ldi 255,%r19 ;# 8069 reload_outsi+2/2
+ copy %r11,%r26 ;# 2813 reload_outsi+2/1
+ ldil LR'L$C0016,%r1 ;# 8835 add_high_const+3
+ ldo RR'L$C0016(%r1),%r1 ;# 8836 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2817 call_value_internal_symref
+ copy %r1,%r25 ;# 2815 reload_outsi+2/1
+ copy %r11,%r26 ;# 2829 reload_outsi+2/1
+ ldil LR'L$C0017,%r1 ;# 8837 add_high_const+3
+ ldo RR'L$C0017(%r1),%r1 ;# 8838 movhi-2
+ copy %r1,%r25 ;# 2831 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2821 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2833 call_value_internal_symref
+ stw %r28,-244(%r30) ;# 8841 reload_outsi+2/6
+ copy %r11,%r26 ;# 2845 reload_outsi+2/1
+ ldil LR'L$C0018,%r1 ;# 8842 add_high_const+3
+ ldo RR'L$C0018(%r1),%r1 ;# 8843 movhi-2
+ copy %r1,%r25 ;# 2847 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2837 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2849 call_value_internal_symref
+ stw %r28,-236(%r30) ;# 8846 reload_outsi+2/6
+ copy %r11,%r26 ;# 2861 reload_outsi+2/1
+ ldil LR'L$C0019,%r1 ;# 8847 add_high_const+3
+ ldo RR'L$C0019(%r1),%r1 ;# 8848 movhi-2
+ copy %r1,%r25 ;# 2863 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2853 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2865 call_value_internal_symref
+ stw %r28,-228(%r30) ;# 8851 reload_outsi+2/6
+ copy %r11,%r26 ;# 2877 reload_outsi+2/1
+ ldil LR'L$C0020,%r1 ;# 8852 add_high_const+3
+ ldo RR'L$C0020(%r1),%r1 ;# 8853 movhi-2
+ copy %r1,%r25 ;# 2879 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2869 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2881 call_value_internal_symref
+ stw %r28,-220(%r30) ;# 8856 reload_outsi+2/6
+ copy %r11,%r26 ;# 2893 reload_outsi+2/1
+ ldil LR'L$C0021,%r1 ;# 8857 add_high_const+3
+ ldo RR'L$C0021(%r1),%r1 ;# 8858 movhi-2
+ copy %r1,%r25 ;# 2895 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2885 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2897 call_value_internal_symref
+ stw %r28,-212(%r30) ;# 8861 reload_outsi+2/6
+ copy %r11,%r26 ;# 2909 reload_outsi+2/1
+ ldil LR'L$C0022,%r1 ;# 8862 add_high_const+3
+ ldo RR'L$C0022(%r1),%r1 ;# 8863 movhi-2
+ copy %r1,%r25 ;# 2911 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2901 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2913 call_value_internal_symref
+ stw %r28,-204(%r30) ;# 8866 reload_outsi+2/6
+ copy %r11,%r26 ;# 2925 reload_outsi+2/1
+ ldil LR'L$C0023,%r1 ;# 8867 add_high_const+3
+ ldo RR'L$C0023(%r1),%r1 ;# 8868 movhi-2
+ copy %r1,%r25 ;# 2927 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2917 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2929 call_value_internal_symref
+ stw %r28,-196(%r30) ;# 8871 reload_outsi+2/6
+ copy %r11,%r26 ;# 2941 reload_outsi+2/1
+ ldil LR'L$C0024,%r1 ;# 8872 add_high_const+3
+ ldo RR'L$C0024(%r1),%r1 ;# 8873 movhi-2
+ copy %r1,%r25 ;# 2943 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2933 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2945 call_value_internal_symref
+ stw %r28,-188(%r30) ;# 8876 reload_outsi+2/6
+ copy %r11,%r26 ;# 2957 reload_outsi+2/1
+ ldil LR'L$C0025,%r1 ;# 8877 add_high_const+3
+ ldo RR'L$C0025(%r1),%r1 ;# 8878 movhi-2
+ copy %r1,%r25 ;# 2959 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2949 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2961 call_value_internal_symref
+ stw %r28,-180(%r30) ;# 8881 reload_outsi+2/6
+ copy %r11,%r26 ;# 2973 reload_outsi+2/1
+ ldil LR'L$C0026,%r19 ;# 2970 add_high_const+3
+ ldo RR'L$C0026(%r19),%r3 ;# 2971 movhi-2
+ copy %r3,%r25 ;# 2975 reload_outsi+2/1
+ comiclr,<> 0,%r28,%r28 ;# 2965 scc
+ ldi 1,%r28
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2977 call_value_internal_symref
+ stw %r28,-172(%r30) ;# 8884 reload_outsi+2/6
+ copy %r11,%r26 ;# 2989 reload_outsi+2/1
+ ldil LR'L$C0027,%r19 ;# 2986 add_high_const+3
+ ldo RR'L$C0027(%r19),%r4 ;# 2987 movhi-2
+ comiclr,<> 0,%r28,%r13 ;# 2981 scc
+ ldi 1,%r13
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 2993 call_value_internal_symref
+ copy %r4,%r25 ;# 2991 reload_outsi+2/1
+ copy %r11,%r26 ;# 3005 reload_outsi+2/1
+ ldil LR'L$C0017,%r1 ;# 8885 add_high_const+3
+ ldo RR'L$C0017(%r1),%r1 ;# 8886 movhi-2
+ comiclr,<> 0,%r28,%r7 ;# 2997 scc
+ ldi 1,%r7
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3009 call_value_internal_symref
+ copy %r1,%r25 ;# 3007 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3013 bleu+1
+ copy %r11,%r26 ;# 3018 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3022 call_value_internal_symref
+ copy %r3,%r25 ;# 3020 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3026 bleu+1
+ copy %r11,%r26 ;# 3031 reload_outsi+2/1
+ ldil LR'L$C0022,%r1 ;# 8887 add_high_const+3
+ ldo RR'L$C0022(%r1),%r1 ;# 8888 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3035 call_value_internal_symref
+ copy %r1,%r25 ;# 3033 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3039 bleu+1
+ copy %r11,%r26 ;# 3044 reload_outsi+2/1
+ ldil LR'L$C0020,%r1 ;# 8889 add_high_const+3
+ ldo RR'L$C0020(%r1),%r1 ;# 8890 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3048 call_value_internal_symref
+ copy %r1,%r25 ;# 3046 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3052 bleu+1
+ copy %r11,%r26 ;# 3057 reload_outsi+2/1
+ ldil LR'L$C0016,%r1 ;# 8891 add_high_const+3
+ ldo RR'L$C0016(%r1),%r1 ;# 8892 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3061 call_value_internal_symref
+ copy %r1,%r25 ;# 3059 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3065 bleu+1
+ copy %r11,%r26 ;# 3070 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3074 call_value_internal_symref
+ copy %r4,%r25 ;# 3072 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3078 bleu+1
+ copy %r11,%r26 ;# 3083 reload_outsi+2/1
+ ldil LR'L$C0025,%r1 ;# 8893 add_high_const+3
+ ldo RR'L$C0025(%r1),%r1 ;# 8894 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3087 call_value_internal_symref
+ copy %r1,%r25 ;# 3085 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3091 bleu+1
+ copy %r11,%r26 ;# 3096 reload_outsi+2/1
+ ldil LR'L$C0023,%r1 ;# 8895 add_high_const+3
+ ldo RR'L$C0023(%r1),%r1 ;# 8896 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3100 call_value_internal_symref
+ copy %r1,%r25 ;# 3098 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3104 bleu+1
+ copy %r11,%r26 ;# 3109 reload_outsi+2/1
+ ldil LR'L$C0024,%r1 ;# 8897 add_high_const+3
+ ldo RR'L$C0024(%r1),%r1 ;# 8898 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3113 call_value_internal_symref
+ copy %r1,%r25 ;# 3111 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3117 bleu+1
+ copy %r11,%r26 ;# 3122 reload_outsi+2/1
+ ldil LR'L$C0021,%r1 ;# 8899 add_high_const+3
+ ldo RR'L$C0021(%r1),%r1 ;# 8900 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3126 call_value_internal_symref
+ copy %r1,%r25 ;# 3124 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3130 bleu+1
+ copy %r11,%r26 ;# 3135 reload_outsi+2/1
+ ldil LR'L$C0019,%r1 ;# 8901 add_high_const+3
+ ldo RR'L$C0019(%r1),%r1 ;# 8902 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3139 call_value_internal_symref
+ copy %r1,%r25 ;# 3137 reload_outsi+2/1
+ comib,= 0,%r28,L$0329 ;# 3143 bleu+1
+ copy %r11,%r26 ;# 3148 reload_outsi+2/1
+ ldil LR'L$C0018,%r1 ;# 8903 add_high_const+3
+ ldo RR'L$C0018(%r1),%r1 ;# 8904 movhi-2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl strcmp,%r2 ;# 3152 call_value_internal_symref
+ copy %r1,%r25 ;# 3150 reload_outsi+2/1
+ comib,<>,n 0,%r28,L$0900 ;# 3156 bleu+1
+L$0329
+ ldw -296(%r30),%r19 ;# 3173 reload_outsi+2/5
+ comb,= %r16,%r19,L$0922 ;# 3175 bleu+1
+ ldo 1(%r19),%r19 ;# 3184 addsi3/2
+ comb,= %r16,%r19,L$0902 ;# 3214 bleu+1
+ stw %r19,-296(%r30) ;# 3186 reload_outsi+2/6
+ ldi 0,%r22 ;# 3227 reload_outsi+2/2
+ addil LR'__alnum-$global$,%r27 ;# 8596 pic2_lo_sum+1
+ copy %r1,%r2 ;# 8907 reload_outsi+2/1
+ addil LR'__ctype2-$global$,%r27 ;# 8598 pic2_lo_sum+1
+ copy %r1,%r23 ;# 8910 reload_outsi+2/1
+ addil LR'__ctype-$global$,%r27 ;# 8600 pic2_lo_sum+1
+ copy %r1,%r4 ;# 8913 reload_outsi+2/1
+ ldi 32,%r25 ;# 8605 reload_outsi+2/2
+ ldi 2,%r24 ;# 8607 reload_outsi+2/2
+ ldi 16,%r31 ;# 8609 reload_outsi+2/2
+ ldi 8,%r29 ;# 8611 reload_outsi+2/2
+ ldi 128,%r28 ;# 8613 reload_outsi+2/2
+ ldi 255,%r26 ;# 8615 reload_outsi+2/2
+ ldw -244(%r30),%r1 ;# 8916 reload_outsi+2/5
+L$1173
+ comib,=,n 0,%r1,L$0343 ;# 3240 bleu+1
+ stw %r22,RR'__alnum-$global$(%r2) ;# 3244 reload_outsi+2/6
+ ldw RR'__ctype2-$global$(%r23),%r19 ;# 3248 reload_outsi+2/5
+ ldw RR'__ctype-$global$(%r4),%r21 ;# 3260 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3253 addsi3/1
+ addl %r21,%r22,%r21 ;# 3265 addsi3/1
+ ldb 0(%r19),%r20 ;# 3255 movqi+1/5
+ ldb 0(%r21),%r19 ;# 3267 movqi+1/5
+ extru %r20,31,1,%r20 ;# 3256 andsi3/1
+ and %r19,%r18,%r19 ;# 3270 andsi3/1
+ or %r20,%r19,%r20 ;# 3278 xordi3-1
+ comib,<> 0,%r20,L$1169 ;# 3280 bleu+1
+ extru %r22,31,8,%r19 ;# 3330 zero_extendqisi2/1
+L$0343
+ ldw -236(%r30),%r1 ;# 8919 reload_outsi+2/5
+ comib,= 0,%r1,L$0344 ;# 3285 bleu+1
+ ldw RR'__ctype2-$global$(%r23),%r19 ;# 3289 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3290 addsi3/1
+ ldb 0(%r19),%r19 ;# 3292 movqi+1/5
+ bb,< %r19,31,L$1169 ;# 3296 bleu+3
+ extru %r22,31,8,%r19 ;# 3330 zero_extendqisi2/1
+L$0344
+ ldw -228(%r30),%r1 ;# 8922 reload_outsi+2/5
+ comib,=,n 0,%r1,L$0345 ;# 3301 bleu+1
+ comb,= %r25,%r22,L$1169 ;# 3305 bleu+1
+ extru %r22,31,8,%r19 ;# 3330 zero_extendqisi2/1
+ comib,= 9,%r22,L$1170 ;# 3307 bleu+1
+ extru %r19,28,29,%r21 ;# 3332 lshrsi3/2
+L$0345
+ ldw -220(%r30),%r1 ;# 8925 reload_outsi+2/5
+ comib,= 0,%r1,L$0341 ;# 3312 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3316 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3317 addsi3/1
+ ldb 0(%r19),%r19 ;# 3319 movqi+1/5
+ and %r19,%r25,%r19 ;# 3322 andsi3/1
+ comib,= 0,%r19,L$0341 ;# 3325 bleu+1
+ extru %r22,31,8,%r19 ;# 3330 zero_extendqisi2/1
+L$1169
+ extru %r19,28,29,%r21 ;# 3332 lshrsi3/2
+L$1170
+ addl %r6,%r21,%r21 ;# 3335 addsi3/1
+ extru %r19,31,3,%r19 ;# 3339 andsi3/1
+ subi 31,%r19,%r19 ;# 3340 subsi3/2
+ ldb 0(%r21),%r20 ;# 3343 movqi+1/5
+ mtsar %r19 ;# 8928 reload_outsi+2/7
+ vdepi -1,1,%r20 ;# 3348 vdepi_ior
+ stb %r20,0(%r21) ;# 3350 movqi+1/6
+L$0341
+ ldw -212(%r30),%r1 ;# 8931 reload_outsi+2/5
+ comib,= 0,%r1,L$0348 ;# 3354 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3358 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3359 addsi3/1
+ ldb 0(%r19),%r19 ;# 3361 movqi+1/5
+ and %r19,%r18,%r19 ;# 3364 andsi3/1
+ comib,<> 0,%r19,L$1171 ;# 3367 bleu+1
+ extru %r22,31,8,%r19 ;# 3426 zero_extendqisi2/1
+L$0348
+ ldw -204(%r30),%r1 ;# 8934 reload_outsi+2/5
+ comib,= 0,%r1,L$0349 ;# 3372 bleu+1
+ ldw RR'__ctype2-$global$(%r23),%r19 ;# 3376 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3377 addsi3/1
+ ldb 0(%r19),%r19 ;# 3379 movqi+1/5
+ and %r19,%r24,%r19 ;# 3382 andsi3/1
+ comib,<> 0,%r19,L$1171 ;# 3385 bleu+1
+ extru %r22,31,8,%r19 ;# 3426 zero_extendqisi2/1
+L$0349
+ ldw -196(%r30),%r1 ;# 8937 reload_outsi+2/5
+ comib,= 0,%r1,L$0350 ;# 3390 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3394 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3395 addsi3/1
+ ldb 0(%r19),%r19 ;# 3397 movqi+1/5
+ and %r19,%r24,%r19 ;# 3400 andsi3/1
+ comib,<> 0,%r19,L$1171 ;# 3403 bleu+1
+ extru %r22,31,8,%r19 ;# 3426 zero_extendqisi2/1
+L$0350
+ ldw -188(%r30),%r1 ;# 8940 reload_outsi+2/5
+ comib,= 0,%r1,L$0346 ;# 3408 bleu+1
+ ldw RR'__ctype2-$global$(%r23),%r19 ;# 3412 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3413 addsi3/1
+ ldb 0(%r19),%r19 ;# 3415 movqi+1/5
+ and %r19,%r18,%r19 ;# 3418 andsi3/1
+ comib,= 0,%r19,L$0346 ;# 3421 bleu+1
+ extru %r22,31,8,%r19 ;# 3426 zero_extendqisi2/1
+L$1171
+ extru %r19,28,29,%r21 ;# 3428 lshrsi3/2
+ addl %r6,%r21,%r21 ;# 3431 addsi3/1
+ extru %r19,31,3,%r19 ;# 3435 andsi3/1
+ subi 31,%r19,%r19 ;# 3436 subsi3/2
+ ldb 0(%r21),%r20 ;# 3439 movqi+1/5
+ mtsar %r19 ;# 8943 reload_outsi+2/7
+ vdepi -1,1,%r20 ;# 3444 vdepi_ior
+ stb %r20,0(%r21) ;# 3446 movqi+1/6
+L$0346
+ ldw -180(%r30),%r1 ;# 8946 reload_outsi+2/5
+ comib,= 0,%r1,L$0353 ;# 3450 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3454 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3455 addsi3/1
+ ldb 0(%r19),%r19 ;# 3457 movqi+1/5
+ and %r19,%r31,%r19 ;# 3460 andsi3/1
+ comib,<> 0,%r19,L$1172 ;# 3463 bleu+1
+ extru %r22,31,8,%r19 ;# 3520 zero_extendqisi2/1
+L$0353
+ ldw -172(%r30),%r1 ;# 8949 reload_outsi+2/5
+ comib,= 0,%r1,L$0354 ;# 3468 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3472 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3473 addsi3/1
+ ldb 0(%r19),%r19 ;# 3475 movqi+1/5
+ and %r19,%r29,%r19 ;# 3478 andsi3/1
+ comib,<> 0,%r19,L$1172 ;# 3481 bleu+1
+ extru %r22,31,8,%r19 ;# 3520 zero_extendqisi2/1
+L$0354
+ comib,= 0,%r13,L$0355 ;# 3486 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3490 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3491 addsi3/1
+ ldb 0(%r19),%r19 ;# 3493 movqi+1/5
+ bb,< %r19,31,L$1172 ;# 3497 bleu+3
+ extru %r22,31,8,%r19 ;# 3520 zero_extendqisi2/1
+L$0355
+ comib,= 0,%r7,L$0339 ;# 3502 bleu+1
+ ldw RR'__ctype-$global$(%r4),%r19 ;# 3506 reload_outsi+2/5
+ addl %r19,%r22,%r19 ;# 3507 addsi3/1
+ ldb 0(%r19),%r19 ;# 3509 movqi+1/5
+ and %r19,%r28,%r19 ;# 3512 andsi3/1
+ comib,= 0,%r19,L$0339 ;# 3515 bleu+1
+ extru %r22,31,8,%r19 ;# 3520 zero_extendqisi2/1
+L$1172
+ extru %r19,28,29,%r21 ;# 3522 lshrsi3/2
+ addl %r6,%r21,%r21 ;# 3525 addsi3/1
+ extru %r19,31,3,%r19 ;# 3529 andsi3/1
+ subi 31,%r19,%r19 ;# 3530 subsi3/2
+ ldb 0(%r21),%r20 ;# 3533 movqi+1/5
+ mtsar %r19 ;# 8952 reload_outsi+2/7
+ vdepi -1,1,%r20 ;# 3538 vdepi_ior
+ stb %r20,0(%r21) ;# 3540 movqi+1/6
+L$0339
+ ldo 1(%r22),%r22 ;# 3546 addsi3/2
+ comb,>=,n %r26,%r22,L$1173 ;# 3233 bleu+1
+ ldw -244(%r30),%r1 ;# 8916 reload_outsi+2/5
+ bl L$0275,%r0 ;# 3559 jump
+ ldi 1,%r13 ;# 3556 reload_outsi+2/2
+L$0328
+ ldi 255,%r19 ;# 8069 reload_outsi+2/2
+L$1168
+ comb,= %r19,%r3,L$0359 ;# 8070 bleu+1
+ copy %r19,%r21 ;# 8595 reload_outsi+2/1
+L$0360
+ ldo -1(%r3),%r20 ;# 3571 addsi3/2
+ ldw -296(%r30),%r19 ;# 3583 reload_outsi+2/5
+ extru %r20,31,8,%r3 ;# 3572 zero_extendqisi2/1
+ ldo -1(%r19),%r19 ;# 3584 addsi3/2
+ comb,<> %r21,%r3,L$0360 ;# 3577 bleu+1
+ stw %r19,-296(%r30) ;# 3588 reload_outsi+2/6
+L$0359
+ ldb 11(%r6),%r19 ;# 3599 movqi+1/5
+ depi -1,28,1,%r19 ;# 3601 iorsi3+1/2
+ stb %r19,11(%r6) ;# 3603 movqi+1/6
+ ldb 7(%r6),%r19 ;# 3606 movqi+1/5
+ ldi 0,%r13 ;# 3613 reload_outsi+2/2
+ depi -1,29,1,%r19 ;# 3608 iorsi3+1/2
+ bl L$0275,%r0 ;# 3618 jump
+ stb %r19,7(%r6) ;# 3610 movqi+1/6
+L$0309
+ ldi 0,%r13 ;# 3624 reload_outsi+2/2
+L$1166
+ extru %r7,21+8-1,8,%r19 ;# 3627 extzv
+ addl %r6,%r19,%r19 ;# 3630 addsi3/1
+ extru %r7,31,3,%r20 ;# 3633 andsi3/1
+L$0948
+ subi 31,%r20,%r20 ;# 3634 subsi3/2
+ ldb 0(%r19),%r21 ;# 3637 movqi+1/5
+ mtsar %r20 ;# 8955 reload_outsi+2/7
+ vdepi -1,1,%r21 ;# 3642 vdepi_ior
+ bl L$0275,%r0 ;# 3653 jump
+ stb %r21,0(%r19) ;# 3644 movqi+1/6
+L$0276
+ ldb -1(%r6),%r20 ;# 8074 movqi+1/5
+ extru %r20,31,8,%r19 ;# 8075 zero_extendqisi2/1
+ comib,= 0,%r19,L$0364 ;# 8076 bleu+1
+ addl %r19,%r6,%r19 ;# 8079 addsi3/1
+ ldb -1(%r19),%r19 ;# 8082 zero_extendqisi2/2
+ comib,<> 0,%r19,L$0364 ;# 8083 bleu+1
+ ldo -1(%r20),%r19 ;# 8242 addsi3/2
+ bl L$1183,%r0 ;# 8253 jump
+ stb %r19,-1(%r6) ;# 3688 movqi+1/6
+L$0365
+ ldo -1(%r19),%r19 ;# 3686 addsi3/2
+ stb %r19,-1(%r6) ;# 3688 movqi+1/6
+L$1183
+ extru %r19,31,8,%r19 ;# 3662 zero_extendqisi2/1
+ comib,= 0,%r19,L$0364 ;# 3664 bleu+1
+ addl %r19,%r6,%r19 ;# 3668 addsi3/1
+ ldb -1(%r19),%r19 ;# 3672 zero_extendqisi2/2
+ comib,=,n 0,%r19,L$0365 ;# 3674 bleu+1
+ ldb -1(%r6),%r19 ;# 3683 movqi+1/5
+L$0364
+ ldb -1(%r6),%r19 ;# 3700 zero_extendqisi2/2
+ bl L$0043,%r0 ;# 3705 jump
+ addl %r6,%r19,%r6 ;# 3701 addsi3/1
+L$0368
+ bb,>=,n %r15,18,L$0076 ;# 3713 movsi-4
+ bl L$1181,%r0 ;# 3721 jump
+ ldw 24(%r5),%r19 ;# 3861 reload_outsi+2/5
+L$0372
+ bb,>=,n %r15,18,L$0076 ;# 3730 movsi-4
+ bl,n L$0374,%r0 ;# 3738 jump
+L$0376
+ bb,>=,n %r15,20,L$0076 ;# 3747 movsi-4
+ bl,n L$0378,%r0 ;# 3755 jump
+L$0380
+ bb,>=,n %r15,16,L$0076 ;# 3764 movsi-4
+ bl,n L$0378,%r0 ;# 3772 jump
+L$0383
+ and %r15,%r20,%r19 ;# 3779 andsi3/1
+ comb,= %r20,%r19,L$1174 ;# 3783 bleu+1
+ ldi -1,%r4 ;# 5074 reload_outsi+2/2
+ bl,n L$0076,%r0 ;# 3791 jump
+L$0387
+ comb,=,n %r16,%r19,L$0903 ;# 3799 bleu+1
+ ldb 0(%r19),%r7 ;# 3831 zero_extendqisi2/2
+ ldo 1(%r19),%r19 ;# 3826 addsi3/2
+ stw %r19,-296(%r30) ;# 3828 reload_outsi+2/6
+ ldo -39(%r7),%r19 ;# 7446 addsi3/2
+ addi,uv -86,%r19,%r0 ;# 7447 casesi0
+ blr,n %r19,%r0
+ b,n L$0397
+L$0817
+ bl L$0759,%r0 ;# 9437 switch_jump
+ ldw 0(%r5),%r4 ;# 8204 reload_outsi+2/5
+L$1069
+ bl L$0395,%r0
+ nop ;# 9440 switch_jump
+L$1070
+ bl L$0422,%r0
+ nop ;# 9443 switch_jump
+L$1071
+ bl L$0397,%r0
+ nop ;# 9446 switch_jump
+L$1072
+ bl L$0811,%r0
+ nop ;# 9449 switch_jump
+L$1073
+ bl L$0397,%r0
+ nop ;# 9452 switch_jump
+L$1074
+ bl L$0397,%r0
+ nop ;# 9455 switch_jump
+L$1075
+ bl L$0397,%r0
+ nop ;# 9458 switch_jump
+L$1076
+ bl L$0397,%r0
+ nop ;# 9461 switch_jump
+L$1077
+ bl L$0397,%r0
+ nop ;# 9464 switch_jump
+L$1078
+ bl L$0787,%r0
+ nop ;# 9467 switch_jump
+L$1079
+ bl L$0787,%r0
+ nop ;# 9470 switch_jump
+L$1080
+ bl L$0787,%r0
+ nop ;# 9473 switch_jump
+L$1081
+ bl L$0787,%r0
+ nop ;# 9476 switch_jump
+L$1082
+ bl L$0787,%r0
+ nop ;# 9479 switch_jump
+L$1083
+ bl L$0787,%r0
+ nop ;# 9482 switch_jump
+L$1084
+ bl L$0787,%r0
+ nop ;# 9485 switch_jump
+L$1085
+ bl L$0787,%r0
+ nop ;# 9488 switch_jump
+L$1086
+ bl L$0787,%r0
+ nop ;# 9491 switch_jump
+L$1087
+ bl L$0397,%r0
+ nop ;# 9494 switch_jump
+L$1088
+ bl L$0397,%r0
+ nop ;# 9497 switch_jump
+L$1089
+ bl L$0659,%r0 ;# 9500 switch_jump
+ ldw 0(%r5),%r4 ;# 8164 reload_outsi+2/5
+L$1090
+ bl L$0397,%r0
+ nop ;# 9503 switch_jump
+L$1091
+ bl L$0679,%r0 ;# 9506 switch_jump
+ ldw 0(%r5),%r4 ;# 8172 reload_outsi+2/5
+L$1092
+ bl L$0811,%r0
+ nop ;# 9509 switch_jump
+L$1093
+ bl L$0397,%r0
+ nop ;# 9512 switch_jump
+L$1094
+ bl L$0397,%r0
+ nop ;# 9515 switch_jump
+L$1095
+ bl L$0719,%r0 ;# 9518 switch_jump
+ ldw 0(%r5),%r4 ;# 8188 reload_outsi+2/5
+L$1096
+ bl L$0397,%r0
+ nop ;# 9521 switch_jump
+L$1097
+ bl L$0397,%r0
+ nop ;# 9524 switch_jump
+L$1098
+ bl L$0397,%r0
+ nop ;# 9527 switch_jump
+L$1099
+ bl L$0397,%r0
+ nop ;# 9530 switch_jump
+L$1100
+ bl L$0397,%r0
+ nop ;# 9533 switch_jump
+L$1101
+ bl L$0397,%r0
+ nop ;# 9536 switch_jump
+L$1102
+ bl L$0397,%r0
+ nop ;# 9539 switch_jump
+L$1103
+ bl L$0397,%r0
+ nop ;# 9542 switch_jump
+L$1104
+ bl L$0397,%r0
+ nop ;# 9545 switch_jump
+L$1105
+ bl L$0397,%r0
+ nop ;# 9548 switch_jump
+L$1106
+ bl L$0397,%r0
+ nop ;# 9551 switch_jump
+L$1107
+ bl L$0397,%r0
+ nop ;# 9554 switch_jump
+L$1108
+ bl L$0397,%r0
+ nop ;# 9557 switch_jump
+L$1109
+ bl L$0397,%r0
+ nop ;# 9560 switch_jump
+L$1110
+ bl L$0397,%r0
+ nop ;# 9563 switch_jump
+L$1111
+ bl L$0397,%r0
+ nop ;# 9566 switch_jump
+L$1112
+ bl L$0397,%r0
+ nop ;# 9569 switch_jump
+L$1113
+ bl L$0397,%r0
+ nop ;# 9572 switch_jump
+L$1114
+ bl L$0397,%r0
+ nop ;# 9575 switch_jump
+L$1115
+ bl L$0397,%r0
+ nop ;# 9578 switch_jump
+L$1116
+ bl L$0639,%r0 ;# 9581 switch_jump
+ ldw 0(%r5),%r4 ;# 8156 reload_outsi+2/5
+L$1117
+ bl L$0397,%r0
+ nop ;# 9584 switch_jump
+L$1118
+ bl L$0397,%r0
+ nop ;# 9587 switch_jump
+L$1119
+ bl L$0397,%r0
+ nop ;# 9590 switch_jump
+L$1120
+ bl L$0397,%r0
+ nop ;# 9593 switch_jump
+L$1121
+ bl L$0397,%r0
+ nop ;# 9596 switch_jump
+L$1122
+ bl L$0397,%r0
+ nop ;# 9599 switch_jump
+L$1123
+ bl L$0397,%r0
+ nop ;# 9602 switch_jump
+L$1124
+ bl L$0397,%r0
+ nop ;# 9605 switch_jump
+L$1125
+ bl L$0739,%r0 ;# 9608 switch_jump
+ ldw 0(%r5),%r4 ;# 8196 reload_outsi+2/5
+L$1126
+ bl L$0397,%r0
+ nop ;# 9611 switch_jump
+L$1127
+ bl L$0699,%r0 ;# 9614 switch_jump
+ ldw 0(%r5),%r4 ;# 8180 reload_outsi+2/5
+L$1128
+ bl L$0397,%r0
+ nop ;# 9617 switch_jump
+L$1129
+ bl L$0397,%r0
+ nop ;# 9620 switch_jump
+L$1130
+ bl L$0397,%r0
+ nop ;# 9623 switch_jump
+L$1131
+ bl L$0397,%r0
+ nop ;# 9626 switch_jump
+L$1132
+ bl L$0397,%r0
+ nop ;# 9629 switch_jump
+L$1133
+ bl L$0397,%r0
+ nop ;# 9632 switch_jump
+L$1134
+ bl L$0397,%r0
+ nop ;# 9635 switch_jump
+L$1135
+ bl L$0397,%r0
+ nop ;# 9638 switch_jump
+L$1136
+ bl L$0397,%r0
+ nop ;# 9641 switch_jump
+L$1137
+ bl L$0397,%r0
+ nop ;# 9644 switch_jump
+L$1138
+ bl L$0397,%r0
+ nop ;# 9647 switch_jump
+L$1139
+ bl L$0397,%r0
+ nop ;# 9650 switch_jump
+L$1140
+ bl L$0397,%r0
+ nop ;# 9653 switch_jump
+L$1141
+ bl L$0397,%r0
+ nop ;# 9656 switch_jump
+L$1142
+ bl L$0397,%r0
+ nop ;# 9659 switch_jump
+L$1143
+ bl L$0397,%r0
+ nop ;# 9662 switch_jump
+L$1144
+ bl L$0397,%r0
+ nop ;# 9665 switch_jump
+L$1145
+ bl L$0397,%r0
+ nop ;# 9668 switch_jump
+L$1146
+ bl L$0397,%r0
+ nop ;# 9671 switch_jump
+L$1147
+ bl L$0397,%r0
+ nop ;# 9674 switch_jump
+L$1148
+ bl L$0619,%r0 ;# 9677 switch_jump
+ ldw 0(%r5),%r4 ;# 8148 reload_outsi+2/5
+L$1149
+ bl L$0397,%r0
+ nop ;# 9680 switch_jump
+L$1150
+ bl L$0397,%r0
+ nop ;# 9683 switch_jump
+L$1151
+ bl L$0397,%r0
+ nop ;# 9686 switch_jump
+L$1152
+ bl L$0506,%r0
+ nop ;# 9689 switch_jump
+L$1153
+ bl L$0472,%r0 ;# 9692 switch_jump
+ ldil L'33792,%r19 ;# 4724 add_high_const+3
+L$1154
+ bl,n L$0397,%r0 ;# 7450 jump
+L$0395
+ bb,<,n %r15,18,L$0397 ;# 3853 bleu+3
+ ldw 24(%r5),%r19 ;# 3861 reload_outsi+2/5
+L$1181
+ ldo 1(%r19),%r19 ;# 3862 addsi3/2
+ stw %r19,24(%r5) ;# 3866 reload_outsi+2/6
+ ldw -304(%r30),%r20 ;# 3871 reload_outsi+2/5
+ ldw -260(%r30),%r1 ;# 8958 reload_outsi+2/5
+ ldw -308(%r30),%r19 ;# 3873 reload_outsi+2/5
+ ldo 1(%r1),%r1 ;# 3868 addsi3/2
+ comb,<> %r19,%r20,L$0398 ;# 3875 bleu+1
+ stw %r1,-260(%r30) ;# 8961 reload_outsi+2/6
+ zdep %r20,28,29,%r25 ;# 3885 ashlsi3+1
+ sh1addl %r20,%r25,%r25 ;# 3886 ashlsi3-2
+ ldw -312(%r30),%r26 ;# 3890 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 3894 call_value_internal_symref
+ zdep %r25,29,30,%r25 ;# 3892 ashlsi3+1
+ comib,= 0,%r28,L$0953 ;# 3903 bleu+1
+ stw %r28,-312(%r30) ;# 3898 reload_outsi+2/6
+ ldw -308(%r30),%r19 ;# 3912 reload_outsi+2/5
+ zdep %r19,30,31,%r19 ;# 3914 ashlsi3+1
+ stw %r19,-308(%r30) ;# 3916 reload_outsi+2/6
+L$0398
+ ldw -304(%r30),%r20 ;# 3921 reload_outsi+2/5
+ ldw -312(%r30),%r21 ;# 3923 reload_outsi+2/5
+ ldw 0(%r5),%r19 ;# 3933 reload_outsi+2/5
+ sh2addl %r20,%r20,%r20 ;# 3928 ashlsi3-2
+ sh2addl %r20,%r21,%r21 ;# 3931 ashlsi3-2
+ sub %r12,%r19,%r19 ;# 3934 subsi3/1
+ stw %r19,0(%r21) ;# 3936 reload_outsi+2/6
+ ldw -304(%r30),%r19 ;# 3939 reload_outsi+2/5
+ ldw -312(%r30),%r20 ;# 3941 reload_outsi+2/5
+ sh2addl %r19,%r19,%r19 ;# 3946 ashlsi3-2
+ comib,= 0,%r10,L$0400 ;# 3951 bleu+1
+ sh2addl %r19,%r20,%r20 ;# 3949 ashlsi3-2
+ ldw 0(%r5),%r19 ;# 3953 reload_outsi+2/5
+ sub %r10,%r19,%r19 ;# 3954 subsi3/1
+ ldo 1(%r19),%r19 ;# 3955 addsi3/2
+ bl L$0401,%r0 ;# 3958 jump
+ stw %r19,4(%r20) ;# 3957 reload_outsi+2/6
+L$0400
+ stw %r0,4(%r20) ;# 3962 reload_outsi+2/6
+L$0401
+ ldw -304(%r30),%r20 ;# 3966 reload_outsi+2/5
+ ldw -312(%r30),%r21 ;# 3968 reload_outsi+2/5
+ ldw 0(%r5),%r19 ;# 3978 reload_outsi+2/5
+ sh2addl %r20,%r20,%r20 ;# 3973 ashlsi3-2
+ sh2addl %r20,%r21,%r21 ;# 3976 ashlsi3-2
+ sub %r6,%r19,%r19 ;# 3979 subsi3/1
+ stw %r19,12(%r21) ;# 3981 reload_outsi+2/6
+ ldw -304(%r30),%r19 ;# 3984 reload_outsi+2/5
+ ldw -312(%r30),%r20 ;# 3986 reload_outsi+2/5
+ ldw -260(%r30),%r1 ;# 8964 reload_outsi+2/5
+ sh2addl %r19,%r19,%r19 ;# 3991 ashlsi3-2
+ sh2addl %r19,%r20,%r20 ;# 3994 ashlsi3-2
+ ldi 255,%r19 ;# 3999 reload_outsi+2/2
+ comb,<< %r19,%r1,L$0402 ;# 4001 bleu+1
+ stw %r1,16(%r20) ;# 3996 reload_outsi+2/6
+ ldw -304(%r30),%r20 ;# 4005 reload_outsi+2/5
+ ldw -312(%r30),%r21 ;# 4007 reload_outsi+2/5
+ ldw 0(%r5),%r19 ;# 4017 reload_outsi+2/5
+ sh2addl %r20,%r20,%r20 ;# 4012 ashlsi3-2
+ sh2addl %r20,%r21,%r21 ;# 4015 ashlsi3-2
+ sub %r6,%r19,%r19 ;# 4018 subsi3/1
+ ldo 2(%r19),%r19 ;# 4019 addsi3/2
+ stw %r19,8(%r21) ;# 4021 reload_outsi+2/6
+ ldw 0(%r5),%r4 ;# 8087 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8090 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8088 subsi3/1
+ ldo 3(%r19),%r19 ;# 8089 addsi3/2
+ comb,>>=,n %r20,%r19,L$0407 ;# 8091 bleu+1
+ ldil L'65536,%r3 ;# 8593 reload_outsi+2/3
+L$0408
+ comb,= %r3,%r20,L$0944 ;# 4049 bleu+1
+ zdep %r20,30,31,%r19 ;# 4059 ashlsi3+1
+ comb,>>= %r3,%r19,L$0413 ;# 4067 bleu+1
+ stw %r19,4(%r5) ;# 4061 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 4070 reload_outsi+2/6
+L$0413
+ ldw 0(%r5),%r26 ;# 4077 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 4081 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 4079 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 4089 bleu+1
+ stw %r28,0(%r5) ;# 4085 reload_outsi+2/6
+ comb,= %r28,%r4,L$0406 ;# 4099 bleu+1
+ sub %r6,%r4,%r19 ;# 4101 subsi3/1
+ comib,= 0,%r10,L$0416 ;# 4110 bleu+1
+ addl %r28,%r19,%r6 ;# 4104 addsi3/1
+ sub %r10,%r4,%r19 ;# 4111 subsi3/1
+ addl %r28,%r19,%r10 ;# 4114 addsi3/1
+L$0416
+ comib,= 0,%r8,L$0417 ;# 4117 bleu+1
+ sub %r8,%r4,%r19 ;# 4118 subsi3/1
+ addl %r28,%r19,%r8 ;# 4121 addsi3/1
+L$0417
+ comib,= 0,%r9,L$0406 ;# 4124 bleu+1
+ sub %r9,%r4,%r19 ;# 4125 subsi3/1
+ addl %r28,%r19,%r9 ;# 4128 addsi3/1
+L$0406
+ ldw 0(%r5),%r4 ;# 4029 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 4033 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 4030 subsi3/1
+ ldo 3(%r19),%r19 ;# 4031 addsi3/2
+ comb,<< %r20,%r19,L$0408
+ nop ;# 4035 bleu+1
+L$0407
+ ldi 5,%r19 ;# 4150 movqi+1/2
+ stbs,ma %r19,1(%r6) ;# 4151 movqi+1/6
+ ldb -257(%r30),%r1 ;# 4156 movqi+1/5
+ stbs,ma %r1,1(%r6) ;# 8968 movqi+1/6
+ stbs,ma %r0,1(%r6) ;# 4159 movqi+1/6
+L$0402
+ ldi 0,%r10 ;# 4182 reload_outsi+2/2
+ ldi 0,%r8 ;# 4185 reload_outsi+2/2
+ copy %r6,%r12 ;# 4188 reload_outsi+2/1
+ ldw -304(%r30),%r19 ;# 4174 reload_outsi+2/5
+ ldi 0,%r9 ;# 4191 reload_outsi+2/2
+ ldo 1(%r19),%r19 ;# 4175 addsi3/2
+ bl L$0043,%r0 ;# 4193 jump
+ stw %r19,-304(%r30) ;# 4179 reload_outsi+2/6
+L$0422
+ bb,< %r15,18,L$0397 ;# 4201 bleu+3
+ ldw -304(%r30),%r19 ;# 4207 reload_outsi+2/5
+ comib,<>,n 0,%r19,L$0374 ;# 4209 bleu+1
+ bb,>=,n %r15,14,L$0950 ;# 4215 movsi-4
+ bl,n L$0397,%r0 ;# 4230 jump
+L$0374
+ comib,=,n 0,%r10,L$0427 ;# 4237 bleu+1
+ ldw 0(%r5),%r4 ;# 8095 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8098 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8096 subsi3/1
+ ldo 1(%r19),%r19 ;# 8097 addsi3/2
+ comb,>>=,n %r20,%r19,L$0432 ;# 8099 bleu+1
+ ldil L'65536,%r3 ;# 8591 reload_outsi+2/3
+L$0433
+ comb,= %r3,%r20,L$0944 ;# 4266 bleu+1
+ zdep %r20,30,31,%r19 ;# 4276 ashlsi3+1
+ comb,>>= %r3,%r19,L$0438 ;# 4284 bleu+1
+ stw %r19,4(%r5) ;# 4278 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 4287 reload_outsi+2/6
+L$0438
+ ldw 0(%r5),%r26 ;# 4294 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 4298 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 4296 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 4306 bleu+1
+ stw %r28,0(%r5) ;# 4302 reload_outsi+2/6
+ comb,= %r28,%r4,L$0431 ;# 4316 bleu+1
+ sub %r6,%r4,%r19 ;# 4318 subsi3/1
+ addl %r28,%r19,%r6 ;# 4321 addsi3/1
+ sub %r12,%r4,%r19 ;# 4322 subsi3/1
+ comib,= 0,%r10,L$0441 ;# 4327 bleu+1
+ addl %r28,%r19,%r12 ;# 4325 addsi3/1
+ sub %r10,%r4,%r19 ;# 4328 subsi3/1
+ addl %r28,%r19,%r10 ;# 4331 addsi3/1
+L$0441
+ comib,= 0,%r8,L$0442 ;# 4334 bleu+1
+ sub %r8,%r4,%r19 ;# 4335 subsi3/1
+ addl %r28,%r19,%r8 ;# 4338 addsi3/1
+L$0442
+ comib,= 0,%r9,L$0431 ;# 4341 bleu+1
+ sub %r9,%r4,%r19 ;# 4342 subsi3/1
+ addl %r28,%r19,%r9 ;# 4345 addsi3/1
+L$0431
+ ldw 0(%r5),%r4 ;# 4246 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 4250 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 4247 subsi3/1
+ ldo 1(%r19),%r19 ;# 4248 addsi3/2
+ comb,<< %r20,%r19,L$0433
+ nop ;# 4252 bleu+1
+L$0432
+ ldi 19,%r19 ;# 4367 movqi+1/2
+ stbs,ma %r19,1(%r6) ;# 4368 movqi+1/6
+ uaddcm %r6,%r10,%r24 ;# 4381 adddi3+1
+ ldi 13,%r26 ;# 4384 reload_outsi+2/2
+ copy %r10,%r25 ;# 4386 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl store_op1,%r2 ;# 4390 call_internal_symref
+ ldo -3(%r24),%r24 ;# 4388 addsi3/2
+L$0427
+ ldw -304(%r30),%r19 ;# 4395 reload_outsi+2/5
+ comib,<>,n 0,%r19,L$0447 ;# 4397 bleu+1
+ bb,<,n %r15,14,L$0076 ;# 4403 bleu+3
+L$0950
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 4414 call_internal_symref
+ ldw -312(%r30),%r26 ;# 4412 reload_outsi+2/5
+ bl L$0867,%r0 ;# 4418 jump
+ ldi 16,%r28 ;# 4416 reload_outsi+2/2
+L$0447
+ ldo -1(%r19),%r19 ;# 4427 addsi3/2
+ stw %r19,-304(%r30) ;# 4431 reload_outsi+2/6
+ ldw -312(%r30),%r20 ;# 4436 reload_outsi+2/5
+ sh2addl %r19,%r19,%r19 ;# 4441 ashlsi3-2
+ sh2addl %r19,%r20,%r20 ;# 4444 ashlsi3-2
+ ldw 0(%r5),%r21 ;# 4446 reload_outsi+2/5
+ ldw 0(%r20),%r19 ;# 4448 reload_outsi+2/5
+ ldw 4(%r20),%r20 ;# 4464 reload_outsi+2/5
+ comib,= 0,%r20,L$0450 ;# 4466 bleu+1
+ addl %r21,%r19,%r12 ;# 4449 addsi3/1
+ addl %r21,%r20,%r19 ;# 4483 addsi3/1
+ bl L$0451,%r0 ;# 4485 jump
+ ldo -1(%r19),%r10 ;# 4484 addsi3/2
+L$0450
+ ldi 0,%r10 ;# 4489 reload_outsi+2/2
+L$0451
+ ldw -304(%r30),%r19 ;# 4493 reload_outsi+2/5
+ ldw -312(%r30),%r20 ;# 4495 reload_outsi+2/5
+ ldw 0(%r5),%r21 ;# 4505 reload_outsi+2/5
+ sh2addl %r19,%r19,%r19 ;# 4500 ashlsi3-2
+ sh2addl %r19,%r20,%r20 ;# 4503 ashlsi3-2
+ ldw 12(%r20),%r19 ;# 4507 reload_outsi+2/5
+ ldw 16(%r20),%r7 ;# 4523 reload_outsi+2/5
+ addl %r21,%r19,%r8 ;# 4508 addsi3/1
+ ldi 255,%r19 ;# 4529 reload_outsi+2/2
+ comb,<< %r19,%r7,L$0043 ;# 4531 bleu+1
+ ldi 0,%r9 ;# 4526 reload_outsi+2/2
+ ldw 8(%r20),%r19 ;# 4550 reload_outsi+2/5
+ ldw -260(%r30),%r1 ;# 8971 reload_outsi+2/5
+ addl %r21,%r19,%r19 ;# 4551 addsi3/1
+ sub %r1,%r7,%r20 ;# 4557 subsi3/1
+ stb %r20,0(%r19) ;# 4559 movqi+1/6
+ ldw 0(%r5),%r4 ;# 8103 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8106 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8104 subsi3/1
+ ldo 3(%r19),%r19 ;# 8105 addsi3/2
+ comb,>>=,n %r20,%r19,L$0457 ;# 8107 bleu+1
+ ldil L'65536,%r3 ;# 8589 reload_outsi+2/3
+L$0458
+ comb,= %r3,%r20,L$0944 ;# 4587 bleu+1
+ zdep %r20,30,31,%r19 ;# 4597 ashlsi3+1
+ comb,>>= %r3,%r19,L$0463 ;# 4605 bleu+1
+ stw %r19,4(%r5) ;# 4599 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 4608 reload_outsi+2/6
+L$0463
+ ldw 0(%r5),%r26 ;# 4615 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 4619 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 4617 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 4627 bleu+1
+ stw %r28,0(%r5) ;# 4623 reload_outsi+2/6
+ comb,= %r28,%r4,L$0456 ;# 4637 bleu+1
+ sub %r6,%r4,%r19 ;# 4639 subsi3/1
+ addl %r28,%r19,%r6 ;# 4642 addsi3/1
+ sub %r12,%r4,%r19 ;# 4643 subsi3/1
+ comib,= 0,%r10,L$0466 ;# 4648 bleu+1
+ addl %r28,%r19,%r12 ;# 4646 addsi3/1
+ sub %r10,%r4,%r19 ;# 4649 subsi3/1
+ addl %r28,%r19,%r10 ;# 4652 addsi3/1
+L$0466
+ comib,= 0,%r8,L$0467 ;# 4655 bleu+1
+ sub %r8,%r4,%r19 ;# 4656 subsi3/1
+ addl %r28,%r19,%r8 ;# 4659 addsi3/1
+L$0467
+ comib,= 0,%r9,L$0456 ;# 4662 bleu+1
+ sub %r9,%r4,%r19 ;# 4663 subsi3/1
+ addl %r28,%r19,%r9 ;# 4666 addsi3/1
+L$0456
+ ldw 0(%r5),%r4 ;# 4567 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 4571 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 4568 subsi3/1
+ ldo 3(%r19),%r19 ;# 4569 addsi3/2
+ comb,<< %r20,%r19,L$0458
+ nop ;# 4573 bleu+1
+L$0457
+ ldi 6,%r19 ;# 4688 movqi+1/2
+ stbs,ma %r19,1(%r6) ;# 4689 movqi+1/6
+ stbs,ma %r7,1(%r6) ;# 4694 movqi+1/6
+ ldw -260(%r30),%r1 ;# 8974 reload_outsi+2/5
+ sub %r1,%r7,%r19 ;# 4700 subsi3/1
+ bl L$0043,%r0 ;# 4720 jump
+ stbs,ma %r19,1(%r6) ;# 4702 movqi+1/6
+L$0472
+ ldo R'33792(%r19),%r19 ;# 4725 movhi-2
+ and %r15,%r19,%r19 ;# 4726 andsi3/1
+ comib,<>,n 0,%r19,L$0397 ;# 4728 bleu+1
+L$0378
+ bb,<,n %r15,21,L$0076 ;# 4739 bleu+3
+ ldw 0(%r5),%r3 ;# 8111 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8114 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8112 subsi3/1
+ ldo 3(%r19),%r19 ;# 8113 addsi3/2
+ comb,>>=,n %r20,%r19,L$0476 ;# 8115 bleu+1
+ ldil L'65536,%r4 ;# 8587 reload_outsi+2/3
+L$0477
+ comb,= %r4,%r20,L$0944 ;# 4768 bleu+1
+ zdep %r20,30,31,%r19 ;# 4778 ashlsi3+1
+ comb,>>= %r4,%r19,L$0482 ;# 4786 bleu+1
+ stw %r19,4(%r5) ;# 4780 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 4789 reload_outsi+2/6
+L$0482
+ ldw 0(%r5),%r26 ;# 4796 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 4800 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 4798 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 4808 bleu+1
+ stw %r28,0(%r5) ;# 4804 reload_outsi+2/6
+ comb,= %r28,%r3,L$0475 ;# 4818 bleu+1
+ sub %r6,%r3,%r19 ;# 4820 subsi3/1
+ addl %r28,%r19,%r6 ;# 4823 addsi3/1
+ sub %r12,%r3,%r19 ;# 4824 subsi3/1
+ comib,= 0,%r10,L$0485 ;# 4829 bleu+1
+ addl %r28,%r19,%r12 ;# 4827 addsi3/1
+ sub %r10,%r3,%r19 ;# 4830 subsi3/1
+ addl %r28,%r19,%r10 ;# 4833 addsi3/1
+L$0485
+ comib,= 0,%r8,L$0486 ;# 4836 bleu+1
+ sub %r8,%r3,%r19 ;# 4837 subsi3/1
+ addl %r28,%r19,%r8 ;# 4840 addsi3/1
+L$0486
+ comib,= 0,%r9,L$0475 ;# 4843 bleu+1
+ sub %r9,%r3,%r19 ;# 4844 subsi3/1
+ addl %r28,%r19,%r9 ;# 4847 addsi3/1
+L$0475
+ ldw 0(%r5),%r3 ;# 4748 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 4752 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 4749 subsi3/1
+ ldo 3(%r19),%r19 ;# 4750 addsi3/2
+ comb,<< %r20,%r19,L$0477
+ nop ;# 4754 bleu+1
+L$0476
+ ldi 14,%r26 ;# 4873 reload_outsi+2/2
+ copy %r12,%r25 ;# 4875 reload_outsi+2/1
+ sub %r6,%r25,%r24 ;# 4870 subsi3/1
+ ldo 3(%r24),%r24 ;# 4877 addsi3/2
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op1,%r2 ;# 4881 call_internal_symref
+ copy %r6,%r23 ;# 4879 reload_outsi+2/1
+ ldi 0,%r9 ;# 4884 reload_outsi+2/2
+ comib,= 0,%r10,L$0490 ;# 4889 bleu+1
+ ldo 3(%r6),%r6 ;# 4886 addsi3/2
+ ldi 13,%r26 ;# 4894 reload_outsi+2/2
+ copy %r10,%r25 ;# 4896 reload_outsi+2/1
+ sub %r6,%r25,%r24 ;# 4891 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl store_op1,%r2 ;# 4900 call_internal_symref
+ ldo -3(%r24),%r24 ;# 4898 addsi3/2
+L$0490
+ ldw 0(%r5),%r3 ;# 8119 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8122 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8120 subsi3/1
+ ldo 3(%r19),%r19 ;# 8121 addsi3/2
+ comb,>>= %r20,%r19,L$0492 ;# 8123 bleu+1
+ copy %r6,%r10 ;# 4904 reload_outsi+2/1
+ ldil L'65536,%r4 ;# 8585 reload_outsi+2/3
+L$0493
+ comb,= %r4,%r20,L$0944 ;# 4929 bleu+1
+ zdep %r20,30,31,%r19 ;# 4939 ashlsi3+1
+ comb,>>= %r4,%r19,L$0498 ;# 4947 bleu+1
+ stw %r19,4(%r5) ;# 4941 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 4950 reload_outsi+2/6
+L$0498
+ ldw 0(%r5),%r26 ;# 4957 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 4961 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 4959 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 4969 bleu+1
+ stw %r28,0(%r5) ;# 4965 reload_outsi+2/6
+ comb,= %r28,%r3,L$0491 ;# 4979 bleu+1
+ sub %r6,%r3,%r19 ;# 4981 subsi3/1
+ comib,= 0,%r10,L$0501 ;# 4990 bleu+1
+ addl %r28,%r19,%r6 ;# 4984 addsi3/1
+ sub %r10,%r3,%r19 ;# 4991 subsi3/1
+ addl %r28,%r19,%r10 ;# 4994 addsi3/1
+L$0501
+ comib,= 0,%r8,L$0502 ;# 4997 bleu+1
+ sub %r8,%r3,%r19 ;# 4998 subsi3/1
+ addl %r28,%r19,%r8 ;# 5001 addsi3/1
+L$0502
+ comib,= 0,%r9,L$0491 ;# 5004 bleu+1
+ sub %r9,%r3,%r19 ;# 5005 subsi3/1
+ addl %r28,%r19,%r9 ;# 5008 addsi3/1
+L$0491
+ ldw 0(%r5),%r3 ;# 4909 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 4913 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 4910 subsi3/1
+ ldo 3(%r19),%r19 ;# 4911 addsi3/2
+ comb,<< %r20,%r19,L$0493
+ nop ;# 4915 bleu+1
+L$0492
+ ldo 3(%r6),%r6 ;# 5030 addsi3/2
+ ldi 0,%r8 ;# 5033 reload_outsi+2/2
+ bl L$0043,%r0 ;# 5038 jump
+ copy %r6,%r12 ;# 5036 reload_outsi+2/1
+L$0506
+ bb,>= %r15,22,L$0397 ;# 5046 movsi-4
+ ldi 4608,%r20 ;# 5048 reload_outsi+2/2
+ and %r15,%r20,%r19 ;# 5049 andsi3/1
+ comb,= %r20,%r19,L$0397 ;# 5053 bleu+1
+ ldw -296(%r30),%r20 ;# 5055 reload_outsi+2/5
+ ldw -276(%r30),%r1 ;# 8977 reload_outsi+2/5
+ ldo -2(%r20),%r19 ;# 5056 addsi3/2
+ comb,<> %r1,%r19,L$1175 ;# 5058 bleu+1
+ ldi -1,%r4 ;# 5074 reload_outsi+2/2
+ comb,=,n %r16,%r20,L$0397 ;# 5062 bleu+1
+L$1174
+ ldw -296(%r30),%r20 ;# 5079 reload_outsi+2/5
+L$1175
+ copy %r4,%r11 ;# 5076 reload_outsi+2/1
+ comb,<> %r16,%r20,L$0517 ;# 5085 bleu+1
+ ldo -1(%r20),%r23 ;# 5080 addsi3/2
+ bb,>=,n %r15,19,L$0915 ;# 5092 movsi-4
+ bl L$1182,%r0 ;# 5107 jump
+ stw %r23,-296(%r30) ;# 5968 reload_outsi+2/6
+L$0517
+ ldo 1(%r20),%r19 ;# 5134 addsi3/2
+ stw %r19,-296(%r30) ;# 5136 reload_outsi+2/6
+ comib,= 0,%r14,L$0515 ;# 5143 bleu+1
+ ldb 0(%r20),%r7 ;# 5139 zero_extendqisi2/2
+ addl %r14,%r7,%r19 ;# 5144 addsi3/1
+ ldb 0(%r19),%r7 ;# 5147 zero_extendqisi2/2
+L$0515
+ addil LR'__ctype-$global$,%r27 ;# 8257 pic2_lo_sum+1
+ ldw RR'__ctype-$global$(%r1),%r21 ;# 8259 reload_outsi+2/5
+ addl %r21,%r7,%r19 ;# 8260 addsi3/1
+ ldb 0(%r19),%r19 ;# 8261 movqi+1/5
+ bb,>= %r19,29,L$0513 ;# 8265 movsi-4
+ ldi 4,%r20 ;# 8263 reload_outsi+2/2
+ copy %r20,%r22 ;# 8583 reload_outsi+2/1
+L$0522
+ comiclr,< -1,%r11,%r0 ;# 8128 movsicc+1/1
+ ldi 0,%r11
+ sh2addl %r11,%r11,%r19 ;# 5188 ashlsi3-2
+ sh1addl %r19,%r7,%r19 ;# 5191 ashlsi3-2
+ ldw -296(%r30),%r20 ;# 5194 reload_outsi+2/5
+ comb,= %r16,%r20,L$0513 ;# 5196 bleu+1
+ ldo -48(%r19),%r11 ;# 5192 addsi3/2
+ ldo 1(%r20),%r19 ;# 5215 addsi3/2
+ stw %r19,-296(%r30) ;# 5217 reload_outsi+2/6
+ comib,= 0,%r14,L$0520 ;# 5224 bleu+1
+ ldb 0(%r20),%r7 ;# 5220 zero_extendqisi2/2
+ addl %r14,%r7,%r19 ;# 5225 addsi3/1
+ ldb 0(%r19),%r7 ;# 5228 zero_extendqisi2/2
+L$0520
+ addl %r21,%r7,%r19 ;# 5166 addsi3/1
+ ldb 0(%r19),%r19 ;# 5168 movqi+1/5
+ and %r19,%r22,%r19 ;# 5172 andsi3/1
+ comib,<> 0,%r19,L$0522
+ nop ;# 5174 bleu+1
+L$0513
+ ldi 44,%r19 ;# 5252 reload_outsi+2/2
+ comb,<> %r19,%r7,L$0532 ;# 5254 bleu+1
+ ldw -296(%r30),%r20 ;# 5259 reload_outsi+2/5
+ comb,= %r16,%r20,L$0533 ;# 5261 bleu+1
+ ldo 1(%r20),%r19 ;# 5278 addsi3/2
+ stw %r19,-296(%r30) ;# 5280 reload_outsi+2/6
+ comib,= 0,%r14,L$0535 ;# 5287 bleu+1
+ ldb 0(%r20),%r7 ;# 5283 zero_extendqisi2/2
+ addl %r14,%r7,%r19 ;# 5288 addsi3/1
+ ldb 0(%r19),%r7 ;# 5291 zero_extendqisi2/2
+L$0535
+ addil LR'__ctype-$global$,%r27 ;# 8269 pic2_lo_sum+1
+ ldw RR'__ctype-$global$(%r1),%r21 ;# 8271 reload_outsi+2/5
+ addl %r21,%r7,%r19 ;# 8272 addsi3/1
+ ldb 0(%r19),%r19 ;# 8273 movqi+1/5
+ bb,>= %r19,29,L$0533 ;# 8277 movsi-4
+ ldi 4,%r20 ;# 8275 reload_outsi+2/2
+ copy %r20,%r22 ;# 8578 reload_outsi+2/1
+L$0542
+ comiclr,< -1,%r4,%r0 ;# 8132 movsicc+1/1
+ ldi 0,%r4
+ sh2addl %r4,%r4,%r19 ;# 5332 ashlsi3-2
+ sh1addl %r19,%r7,%r19 ;# 5335 ashlsi3-2
+ ldw -296(%r30),%r20 ;# 5338 reload_outsi+2/5
+ comb,= %r16,%r20,L$0533 ;# 5340 bleu+1
+ ldo -48(%r19),%r4 ;# 5336 addsi3/2
+ ldo 1(%r20),%r19 ;# 5359 addsi3/2
+ stw %r19,-296(%r30) ;# 5361 reload_outsi+2/6
+ comib,= 0,%r14,L$0540 ;# 5368 bleu+1
+ ldb 0(%r20),%r7 ;# 5364 zero_extendqisi2/2
+ addl %r14,%r7,%r19 ;# 5369 addsi3/1
+ ldb 0(%r19),%r7 ;# 5372 zero_extendqisi2/2
+L$0540
+ addl %r21,%r7,%r19 ;# 5310 addsi3/1
+ ldb 0(%r19),%r19 ;# 5312 movqi+1/5
+ and %r19,%r22,%r19 ;# 5316 andsi3/1
+ comib,<> 0,%r19,L$0542
+ nop ;# 5318 bleu+1
+L$0533
+ comiclr,< -1,%r4,%r0 ;# 8136 beq-1/4
+ zdepi -1,31,15,%r4
+ bl,n L$0553,%r0 ;# 5401 jump
+L$0532
+ copy %r11,%r4 ;# 5406 reload_outsi+2/1
+L$0553
+ comib,> 0,%r11,L$0951 ;# 5410 bleu+1
+ zdepi -1,31,15,%r19 ;# 5412 reload_outsi+2/4
+ comb,<,n %r19,%r4,L$0951 ;# 5414 bleu+1
+ comb,<,n %r4,%r11,L$0951 ;# 5416 bleu+1
+ bb,< %r15,19,L$1176 ;# 5451 bleu+3
+ ldi 125,%r19 ;# 5514 reload_outsi+2/2
+ ldi 92,%r19 ;# 5455 reload_outsi+2/2
+ comb,<> %r19,%r7,L$0915 ;# 5457 bleu+1
+ ldw -296(%r30),%r20 ;# 5473 reload_outsi+2/5
+ comb,= %r16,%r20,L$0922 ;# 5475 bleu+1
+ ldo 1(%r20),%r19 ;# 5484 addsi3/2
+ stw %r19,-296(%r30) ;# 5486 reload_outsi+2/6
+ comib,= 0,%r14,L$0558 ;# 5493 bleu+1
+ ldb 0(%r20),%r7 ;# 5489 zero_extendqisi2/2
+ addl %r14,%r7,%r19 ;# 5494 addsi3/1
+ ldb 0(%r19),%r7 ;# 5497 zero_extendqisi2/2
+L$0558
+ ldi 125,%r19 ;# 5514 reload_outsi+2/2
+L$1176
+ comb,=,n %r19,%r7,L$0566 ;# 5516 bleu+1
+L$0951
+ bb,<,n %r15,19,L$0511 ;# 5523 bleu+3
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 5534 call_internal_symref
+ ldw -312(%r30),%r26 ;# 5532 reload_outsi+2/5
+ bl L$0867,%r0 ;# 5538 jump
+ ldi 10,%r28 ;# 5536 reload_outsi+2/2
+L$0566
+ comib,<>,n 0,%r8,L$0569 ;# 5545 bleu+1
+ bb,<,n %r15,26,L$0917 ;# 5552 bleu+3
+ bb,>=,n %r15,27,L$0511 ;# 5571 movsi-4
+ copy %r6,%r8 ;# 5574 reload_outsi+2/1
+L$0569
+ comib,<> 0,%r4,L$0574 ;# 5587 bleu+1
+ ldi 10,%r13 ;# 8980 reload_outsi+2/2
+ ldw 0(%r5),%r3 ;# 8139 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8142 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8140 subsi3/1
+ ldo 3(%r19),%r19 ;# 8141 addsi3/2
+ comb,>>=,n %r20,%r19,L$0576 ;# 8143 bleu+1
+ ldil L'65536,%r4 ;# 8573 reload_outsi+2/3
+L$0577
+ comb,= %r4,%r20,L$0944 ;# 5613 bleu+1
+ zdep %r20,30,31,%r19 ;# 5623 ashlsi3+1
+ comb,>>= %r4,%r19,L$0582 ;# 5631 bleu+1
+ stw %r19,4(%r5) ;# 5625 reload_outsi+2/6
+ stw %r4,4(%r5) ;# 5634 reload_outsi+2/6
+L$0582
+ ldw 0(%r5),%r26 ;# 5641 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 5645 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 5643 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 5653 bleu+1
+ stw %r28,0(%r5) ;# 5649 reload_outsi+2/6
+ comb,= %r28,%r3,L$0575 ;# 5663 bleu+1
+ sub %r6,%r3,%r19 ;# 5665 subsi3/1
+ addl %r28,%r19,%r6 ;# 5668 addsi3/1
+ sub %r12,%r3,%r19 ;# 5669 subsi3/1
+ comib,= 0,%r10,L$0585 ;# 5674 bleu+1
+ addl %r28,%r19,%r12 ;# 5672 addsi3/1
+ sub %r10,%r3,%r19 ;# 5675 subsi3/1
+ addl %r28,%r19,%r10 ;# 5678 addsi3/1
+L$0585
+ comib,= 0,%r8,L$0586 ;# 5681 bleu+1
+ sub %r8,%r3,%r19 ;# 5682 subsi3/1
+ addl %r28,%r19,%r8 ;# 5685 addsi3/1
+L$0586
+ comib,= 0,%r9,L$0575 ;# 5688 bleu+1
+ sub %r9,%r3,%r19 ;# 5689 subsi3/1
+ addl %r28,%r19,%r9 ;# 5692 addsi3/1
+L$0575
+ ldw 0(%r5),%r3 ;# 5593 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 5597 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 5594 subsi3/1
+ ldo 3(%r19),%r19 ;# 5595 addsi3/2
+ comb,<< %r20,%r19,L$0577
+ nop ;# 5599 bleu+1
+L$0576
+ ldi 12,%r26 ;# 5718 reload_outsi+2/2
+ copy %r8,%r25 ;# 5720 reload_outsi+2/1
+ sub %r6,%r8,%r24 ;# 5722 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op1,%r2 ;# 5726 call_internal_symref
+ copy %r6,%r23 ;# 5724 reload_outsi+2/1
+ bl L$0590,%r0 ;# 5730 jump
+ ldo 3(%r6),%r6 ;# 5728 addsi3/2
+L$0574
+ comiclr,> 2,%r4,%r0 ;# 8282 beq-1/2
+ ldi 20,%r13
+ ldw 0(%r5),%r3 ;# 8285 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8288 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 8286 subsi3/1
+ addl %r19,%r13,%r19 ;# 8287 addsi3/1
+ comb,>>=,n %r20,%r19,L$0868 ;# 8289 bleu+1
+ ldil L'65536,%r7 ;# 8571 reload_outsi+2/3
+L$0595
+ comb,= %r7,%r20,L$0944 ;# 5769 bleu+1
+ zdep %r20,30,31,%r19 ;# 5779 ashlsi3+1
+ comb,>>= %r7,%r19,L$0600 ;# 5787 bleu+1
+ stw %r19,4(%r5) ;# 5781 reload_outsi+2/6
+ stw %r7,4(%r5) ;# 5790 reload_outsi+2/6
+L$0600
+ ldw 0(%r5),%r26 ;# 5797 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 5801 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 5799 reload_outsi+2/5
+ comib,= 0,%r28,L$0953 ;# 5809 bleu+1
+ stw %r28,0(%r5) ;# 5805 reload_outsi+2/6
+ comb,= %r28,%r3,L$0593 ;# 5819 bleu+1
+ sub %r6,%r3,%r19 ;# 5821 subsi3/1
+ addl %r28,%r19,%r6 ;# 5824 addsi3/1
+ sub %r12,%r3,%r19 ;# 5825 subsi3/1
+ comib,= 0,%r10,L$0603 ;# 5830 bleu+1
+ addl %r28,%r19,%r12 ;# 5828 addsi3/1
+ sub %r10,%r3,%r19 ;# 5831 subsi3/1
+ addl %r28,%r19,%r10 ;# 5834 addsi3/1
+L$0603
+ comib,= 0,%r8,L$0604 ;# 5837 bleu+1
+ sub %r8,%r3,%r19 ;# 5838 subsi3/1
+ addl %r28,%r19,%r8 ;# 5841 addsi3/1
+L$0604
+ comib,= 0,%r9,L$0593 ;# 5844 bleu+1
+ sub %r9,%r3,%r19 ;# 5845 subsi3/1
+ addl %r28,%r19,%r9 ;# 5848 addsi3/1
+L$0593
+ ldw 0(%r5),%r3 ;# 5749 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 5753 reload_outsi+2/5
+ sub %r6,%r3,%r19 ;# 5750 subsi3/1
+ addl %r19,%r13,%r19 ;# 5751 addsi3/1
+ comb,<< %r20,%r19,L$0595
+ nop ;# 5755 bleu+1
+L$0868
+ comib,>= 1,%r4,L$0608 ;# 5872 bleu+1
+ ldo 5(%r6),%r19 ;# 5870 addsi3/2
+ sub %r19,%r8,%r19 ;# 5874 subsi3/1
+ bl L$0609,%r0 ;# 5876 jump
+ ldo 2(%r19),%r24 ;# 5875 addsi3/2
+L$0608
+ sub %r19,%r8,%r19 ;# 5879 subsi3/1
+ ldo -3(%r19),%r24 ;# 5880 addsi3/2
+L$0609
+ ldi 20,%r26 ;# 5885 reload_outsi+2/2
+ copy %r8,%r25 ;# 5887 reload_outsi+2/1
+ copy %r11,%r23 ;# 5891 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op2,%r2 ;# 5893 call_internal_symref
+ stw %r6,-52(%r30) ;# 5883 reload_outsi+2/6
+ ldo 5(%r6),%r6 ;# 5895 addsi3/2
+ ldi 22,%r26 ;# 5900 reload_outsi+2/2
+ copy %r8,%r25 ;# 5902 reload_outsi+2/1
+ ldi 5,%r24 ;# 5904 reload_outsi+2/2
+ copy %r11,%r23 ;# 5906 reload_outsi+2/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op2,%r2 ;# 5908 call_internal_symref
+ stw %r6,-52(%r30) ;# 5898 reload_outsi+2/6
+ comib,>= 1,%r4,L$0590 ;# 5913 bleu+1
+ ldo 5(%r6),%r6 ;# 5910 addsi3/2
+ ldi 21,%r26 ;# 5921 reload_outsi+2/2
+ copy %r6,%r25 ;# 5923 reload_outsi+2/1
+ sub %r8,%r6,%r24 ;# 5917 subsi3/1
+ ldo 2(%r24),%r24 ;# 5925 addsi3/2
+ ldo -1(%r4),%r4 ;# 5919 addsi3/2
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl store_op2,%r2 ;# 5929 call_internal_symref
+ copy %r4,%r23 ;# 5927 reload_outsi+2/1
+ ldo 5(%r6),%r6 ;# 5931 addsi3/2
+ stw %r6,-52(%r30) ;# 5936 reload_outsi+2/6
+ ldi 22,%r26 ;# 5938 reload_outsi+2/2
+ copy %r8,%r25 ;# 5940 reload_outsi+2/1
+ sub %r6,%r8,%r24 ;# 5942 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
+ bl insert_op2,%r2 ;# 5946 call_internal_symref
+ copy %r4,%r23 ;# 5944 reload_outsi+2/1
+ ldo 5(%r6),%r6 ;# 5948 addsi3/2
+L$0590
+ bl L$0043,%r0 ;# 5963 jump
+ ldi 0,%r9 ;# 5956 reload_outsi+2/2
+L$0511
+ stw %r23,-296(%r30) ;# 5968 reload_outsi+2/6
+L$1182
+ ldw -296(%r30),%r20 ;# 5977 reload_outsi+2/5
+ comb,= %r16,%r20,L$0922 ;# 5979 bleu+1
+ ldo 1(%r20),%r21 ;# 5988 addsi3/2
+ ldb 0(%r20),%r20 ;# 5992 movqi+1/5
+ stw %r21,-296(%r30) ;# 5990 reload_outsi+2/6
+ comib,= 0,%r14,L$0612 ;# 5997 bleu+1
+ extru %r20,31,8,%r7 ;# 5993 zero_extendqisi2/1
+ addl %r14,%r7,%r19 ;# 5998 addsi3/1
+ ldb 0(%r19),%r7 ;# 6001 zero_extendqisi2/2
+L$0612
+ bb,< %r15,19,L$0076 ;# 6019 bleu+3
+ ldw -276(%r30),%r1 ;# 8983 reload_outsi+2/5
+ comb,>>= %r1,%r21,L$0076 ;# 6025 bleu+1
+ extrs %r20,31,8,%r20 ;# 6030 extendqisi2
+ ldi 92,%r19 ;# 6032 reload_outsi+2/2
+ comb,=,n %r19,%r20,L$0397 ;# 6034 bleu+1
+ bl,n L$0076,%r0 ;# 6042 jump
+L$0619
+ ldw 4(%r5),%r20 ;# 8151 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8149 subsi3/1
+ ldo 1(%r19),%r19 ;# 8150 addsi3/2
+ comb,>>= %r20,%r19,L$0624 ;# 8152 bleu+1
+ copy %r6,%r8 ;# 6047 reload_outsi+2/1
+ ldil L'65536,%r3 ;# 8569 reload_outsi+2/3
+L$0625
+ comb,= %r3,%r20,L$0944 ;# 6075 bleu+1
+ zdep %r20,30,31,%r19 ;# 6085 ashlsi3+1
+ comb,>>= %r3,%r19,L$0630 ;# 6093 bleu+1
+ stw %r19,4(%r5) ;# 6087 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6096 reload_outsi+2/6
+L$0630
+ ldw 0(%r5),%r26 ;# 6103 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6107 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6105 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6115 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6111 reload_outsi+2/6
+ comb,= %r28,%r4,L$0623 ;# 6125 bleu+1
+ sub %r6,%r4,%r19 ;# 6127 subsi3/1
+ addl %r28,%r19,%r6 ;# 6130 addsi3/1
+ sub %r12,%r4,%r19 ;# 6131 subsi3/1
+ comib,= 0,%r10,L$0633 ;# 6136 bleu+1
+ addl %r28,%r19,%r12 ;# 6134 addsi3/1
+ sub %r10,%r4,%r19 ;# 6137 subsi3/1
+ addl %r28,%r19,%r10 ;# 6140 addsi3/1
+L$0633
+ comib,= 0,%r8,L$0634 ;# 6143 bleu+1
+ sub %r8,%r4,%r19 ;# 6144 subsi3/1
+ addl %r28,%r19,%r8 ;# 6147 addsi3/1
+L$0634
+ comib,= 0,%r9,L$0623 ;# 6150 bleu+1
+ sub %r9,%r4,%r19 ;# 6151 subsi3/1
+ addl %r28,%r19,%r9 ;# 6154 addsi3/1
+L$0623
+ ldw 0(%r5),%r4 ;# 6055 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6059 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6056 subsi3/1
+ ldo 1(%r19),%r19 ;# 6057 addsi3/2
+ comb,<< %r20,%r19,L$0625
+ nop ;# 6061 bleu+1
+L$0624
+ ldi 23,%r19 ;# 6176 movqi+1/2
+ bl L$0043,%r0 ;# 6189 jump
+ stbs,ma %r19,1(%r6) ;# 6177 movqi+1/6
+L$0639
+ ldw 4(%r5),%r20 ;# 8159 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8157 subsi3/1
+ ldo 1(%r19),%r19 ;# 8158 addsi3/2
+ comb,>>= %r20,%r19,L$0644 ;# 8160 bleu+1
+ copy %r6,%r8 ;# 6194 reload_outsi+2/1
+ ldil L'65536,%r3 ;# 8567 reload_outsi+2/3
+L$0645
+ comb,= %r3,%r20,L$0944 ;# 6222 bleu+1
+ zdep %r20,30,31,%r19 ;# 6232 ashlsi3+1
+ comb,>>= %r3,%r19,L$0650 ;# 6240 bleu+1
+ stw %r19,4(%r5) ;# 6234 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6243 reload_outsi+2/6
+L$0650
+ ldw 0(%r5),%r26 ;# 6250 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6254 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6252 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6262 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6258 reload_outsi+2/6
+ comb,= %r28,%r4,L$0643 ;# 6272 bleu+1
+ sub %r6,%r4,%r19 ;# 6274 subsi3/1
+ addl %r28,%r19,%r6 ;# 6277 addsi3/1
+ sub %r12,%r4,%r19 ;# 6278 subsi3/1
+ comib,= 0,%r10,L$0653 ;# 6283 bleu+1
+ addl %r28,%r19,%r12 ;# 6281 addsi3/1
+ sub %r10,%r4,%r19 ;# 6284 subsi3/1
+ addl %r28,%r19,%r10 ;# 6287 addsi3/1
+L$0653
+ comib,= 0,%r8,L$0654 ;# 6290 bleu+1
+ sub %r8,%r4,%r19 ;# 6291 subsi3/1
+ addl %r28,%r19,%r8 ;# 6294 addsi3/1
+L$0654
+ comib,= 0,%r9,L$0643 ;# 6297 bleu+1
+ sub %r9,%r4,%r19 ;# 6298 subsi3/1
+ addl %r28,%r19,%r9 ;# 6301 addsi3/1
+L$0643
+ ldw 0(%r5),%r4 ;# 6202 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6206 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6203 subsi3/1
+ ldo 1(%r19),%r19 ;# 6204 addsi3/2
+ comb,<< %r20,%r19,L$0645
+ nop ;# 6208 bleu+1
+L$0644
+ ldi 24,%r19 ;# 6323 movqi+1/2
+ bl L$0043,%r0 ;# 6336 jump
+ stbs,ma %r19,1(%r6) ;# 6324 movqi+1/6
+L$0659
+ ldw 4(%r5),%r20 ;# 8167 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8165 subsi3/1
+ ldo 1(%r19),%r19 ;# 8166 addsi3/2
+ comb,>>=,n %r20,%r19,L$0664 ;# 8168 bleu+1
+ ldil L'65536,%r3 ;# 8565 reload_outsi+2/3
+L$0665
+ comb,= %r3,%r20,L$0944 ;# 6366 bleu+1
+ zdep %r20,30,31,%r19 ;# 6376 ashlsi3+1
+ comb,>>= %r3,%r19,L$0670 ;# 6384 bleu+1
+ stw %r19,4(%r5) ;# 6378 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6387 reload_outsi+2/6
+L$0670
+ ldw 0(%r5),%r26 ;# 6394 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6398 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6396 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6406 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6402 reload_outsi+2/6
+ comb,= %r28,%r4,L$0663 ;# 6416 bleu+1
+ sub %r6,%r4,%r19 ;# 6418 subsi3/1
+ addl %r28,%r19,%r6 ;# 6421 addsi3/1
+ sub %r12,%r4,%r19 ;# 6422 subsi3/1
+ comib,= 0,%r10,L$0673 ;# 6427 bleu+1
+ addl %r28,%r19,%r12 ;# 6425 addsi3/1
+ sub %r10,%r4,%r19 ;# 6428 subsi3/1
+ addl %r28,%r19,%r10 ;# 6431 addsi3/1
+L$0673
+ comib,= 0,%r8,L$0674 ;# 6434 bleu+1
+ sub %r8,%r4,%r19 ;# 6435 subsi3/1
+ addl %r28,%r19,%r8 ;# 6438 addsi3/1
+L$0674
+ comib,= 0,%r9,L$0663 ;# 6441 bleu+1
+ sub %r9,%r4,%r19 ;# 6442 subsi3/1
+ addl %r28,%r19,%r9 ;# 6445 addsi3/1
+L$0663
+ ldw 0(%r5),%r4 ;# 6346 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6350 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6347 subsi3/1
+ ldo 1(%r19),%r19 ;# 6348 addsi3/2
+ comb,<< %r20,%r19,L$0665
+ nop ;# 6352 bleu+1
+L$0664
+ ldi 25,%r19 ;# 6467 movqi+1/2
+ bl L$0043,%r0 ;# 6480 jump
+ stbs,ma %r19,1(%r6) ;# 6468 movqi+1/6
+L$0679
+ ldw 4(%r5),%r20 ;# 8175 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8173 subsi3/1
+ ldo 1(%r19),%r19 ;# 8174 addsi3/2
+ comb,>>=,n %r20,%r19,L$0684 ;# 8176 bleu+1
+ ldil L'65536,%r3 ;# 8563 reload_outsi+2/3
+L$0685
+ comb,= %r3,%r20,L$0944 ;# 6510 bleu+1
+ zdep %r20,30,31,%r19 ;# 6520 ashlsi3+1
+ comb,>>= %r3,%r19,L$0690 ;# 6528 bleu+1
+ stw %r19,4(%r5) ;# 6522 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6531 reload_outsi+2/6
+L$0690
+ ldw 0(%r5),%r26 ;# 6538 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6542 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6540 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6550 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6546 reload_outsi+2/6
+ comb,= %r28,%r4,L$0683 ;# 6560 bleu+1
+ sub %r6,%r4,%r19 ;# 6562 subsi3/1
+ addl %r28,%r19,%r6 ;# 6565 addsi3/1
+ sub %r12,%r4,%r19 ;# 6566 subsi3/1
+ comib,= 0,%r10,L$0693 ;# 6571 bleu+1
+ addl %r28,%r19,%r12 ;# 6569 addsi3/1
+ sub %r10,%r4,%r19 ;# 6572 subsi3/1
+ addl %r28,%r19,%r10 ;# 6575 addsi3/1
+L$0693
+ comib,= 0,%r8,L$0694 ;# 6578 bleu+1
+ sub %r8,%r4,%r19 ;# 6579 subsi3/1
+ addl %r28,%r19,%r8 ;# 6582 addsi3/1
+L$0694
+ comib,= 0,%r9,L$0683 ;# 6585 bleu+1
+ sub %r9,%r4,%r19 ;# 6586 subsi3/1
+ addl %r28,%r19,%r9 ;# 6589 addsi3/1
+L$0683
+ ldw 0(%r5),%r4 ;# 6490 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6494 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6491 subsi3/1
+ ldo 1(%r19),%r19 ;# 6492 addsi3/2
+ comb,<< %r20,%r19,L$0685
+ nop ;# 6496 bleu+1
+L$0684
+ ldi 26,%r19 ;# 6611 movqi+1/2
+ bl L$0043,%r0 ;# 6624 jump
+ stbs,ma %r19,1(%r6) ;# 6612 movqi+1/6
+L$0699
+ ldw 4(%r5),%r20 ;# 8183 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8181 subsi3/1
+ ldo 1(%r19),%r19 ;# 8182 addsi3/2
+ comb,>>=,n %r20,%r19,L$0704 ;# 8184 bleu+1
+ ldil L'65536,%r3 ;# 8561 reload_outsi+2/3
+L$0705
+ comb,= %r3,%r20,L$0944 ;# 6654 bleu+1
+ zdep %r20,30,31,%r19 ;# 6664 ashlsi3+1
+ comb,>>= %r3,%r19,L$0710 ;# 6672 bleu+1
+ stw %r19,4(%r5) ;# 6666 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6675 reload_outsi+2/6
+L$0710
+ ldw 0(%r5),%r26 ;# 6682 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6686 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6684 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6694 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6690 reload_outsi+2/6
+ comb,= %r28,%r4,L$0703 ;# 6704 bleu+1
+ sub %r6,%r4,%r19 ;# 6706 subsi3/1
+ addl %r28,%r19,%r6 ;# 6709 addsi3/1
+ sub %r12,%r4,%r19 ;# 6710 subsi3/1
+ comib,= 0,%r10,L$0713 ;# 6715 bleu+1
+ addl %r28,%r19,%r12 ;# 6713 addsi3/1
+ sub %r10,%r4,%r19 ;# 6716 subsi3/1
+ addl %r28,%r19,%r10 ;# 6719 addsi3/1
+L$0713
+ comib,= 0,%r8,L$0714 ;# 6722 bleu+1
+ sub %r8,%r4,%r19 ;# 6723 subsi3/1
+ addl %r28,%r19,%r8 ;# 6726 addsi3/1
+L$0714
+ comib,= 0,%r9,L$0703 ;# 6729 bleu+1
+ sub %r9,%r4,%r19 ;# 6730 subsi3/1
+ addl %r28,%r19,%r9 ;# 6733 addsi3/1
+L$0703
+ ldw 0(%r5),%r4 ;# 6634 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6638 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6635 subsi3/1
+ ldo 1(%r19),%r19 ;# 6636 addsi3/2
+ comb,<< %r20,%r19,L$0705
+ nop ;# 6640 bleu+1
+L$0704
+ ldi 27,%r19 ;# 6755 movqi+1/2
+ bl L$0043,%r0 ;# 6768 jump
+ stbs,ma %r19,1(%r6) ;# 6756 movqi+1/6
+L$0719
+ ldw 4(%r5),%r20 ;# 8191 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8189 subsi3/1
+ ldo 1(%r19),%r19 ;# 8190 addsi3/2
+ comb,>>=,n %r20,%r19,L$0724 ;# 8192 bleu+1
+ ldil L'65536,%r3 ;# 8559 reload_outsi+2/3
+L$0725
+ comb,= %r3,%r20,L$0944 ;# 6798 bleu+1
+ zdep %r20,30,31,%r19 ;# 6808 ashlsi3+1
+ comb,>>= %r3,%r19,L$0730 ;# 6816 bleu+1
+ stw %r19,4(%r5) ;# 6810 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6819 reload_outsi+2/6
+L$0730
+ ldw 0(%r5),%r26 ;# 6826 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6830 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6828 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6838 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6834 reload_outsi+2/6
+ comb,= %r28,%r4,L$0723 ;# 6848 bleu+1
+ sub %r6,%r4,%r19 ;# 6850 subsi3/1
+ addl %r28,%r19,%r6 ;# 6853 addsi3/1
+ sub %r12,%r4,%r19 ;# 6854 subsi3/1
+ comib,= 0,%r10,L$0733 ;# 6859 bleu+1
+ addl %r28,%r19,%r12 ;# 6857 addsi3/1
+ sub %r10,%r4,%r19 ;# 6860 subsi3/1
+ addl %r28,%r19,%r10 ;# 6863 addsi3/1
+L$0733
+ comib,= 0,%r8,L$0734 ;# 6866 bleu+1
+ sub %r8,%r4,%r19 ;# 6867 subsi3/1
+ addl %r28,%r19,%r8 ;# 6870 addsi3/1
+L$0734
+ comib,= 0,%r9,L$0723 ;# 6873 bleu+1
+ sub %r9,%r4,%r19 ;# 6874 subsi3/1
+ addl %r28,%r19,%r9 ;# 6877 addsi3/1
+L$0723
+ ldw 0(%r5),%r4 ;# 6778 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6782 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6779 subsi3/1
+ ldo 1(%r19),%r19 ;# 6780 addsi3/2
+ comb,<< %r20,%r19,L$0725
+ nop ;# 6784 bleu+1
+L$0724
+ ldi 28,%r19 ;# 6899 movqi+1/2
+ bl L$0043,%r0 ;# 6912 jump
+ stbs,ma %r19,1(%r6) ;# 6900 movqi+1/6
+L$0739
+ ldw 4(%r5),%r20 ;# 8199 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8197 subsi3/1
+ ldo 1(%r19),%r19 ;# 8198 addsi3/2
+ comb,>>=,n %r20,%r19,L$0744 ;# 8200 bleu+1
+ ldil L'65536,%r3 ;# 8557 reload_outsi+2/3
+L$0745
+ comb,= %r3,%r20,L$0944 ;# 6942 bleu+1
+ zdep %r20,30,31,%r19 ;# 6952 ashlsi3+1
+ comb,>>= %r3,%r19,L$0750 ;# 6960 bleu+1
+ stw %r19,4(%r5) ;# 6954 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 6963 reload_outsi+2/6
+L$0750
+ ldw 0(%r5),%r26 ;# 6970 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 6974 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 6972 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 6982 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 6978 reload_outsi+2/6
+ comb,= %r28,%r4,L$0743 ;# 6992 bleu+1
+ sub %r6,%r4,%r19 ;# 6994 subsi3/1
+ addl %r28,%r19,%r6 ;# 6997 addsi3/1
+ sub %r12,%r4,%r19 ;# 6998 subsi3/1
+ comib,= 0,%r10,L$0753 ;# 7003 bleu+1
+ addl %r28,%r19,%r12 ;# 7001 addsi3/1
+ sub %r10,%r4,%r19 ;# 7004 subsi3/1
+ addl %r28,%r19,%r10 ;# 7007 addsi3/1
+L$0753
+ comib,= 0,%r8,L$0754 ;# 7010 bleu+1
+ sub %r8,%r4,%r19 ;# 7011 subsi3/1
+ addl %r28,%r19,%r8 ;# 7014 addsi3/1
+L$0754
+ comib,= 0,%r9,L$0743 ;# 7017 bleu+1
+ sub %r9,%r4,%r19 ;# 7018 subsi3/1
+ addl %r28,%r19,%r9 ;# 7021 addsi3/1
+L$0743
+ ldw 0(%r5),%r4 ;# 6922 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 6926 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 6923 subsi3/1
+ ldo 1(%r19),%r19 ;# 6924 addsi3/2
+ comb,<< %r20,%r19,L$0745
+ nop ;# 6928 bleu+1
+L$0744
+ ldi 10,%r19 ;# 7043 movqi+1/2
+ bl L$0043,%r0 ;# 7056 jump
+ stbs,ma %r19,1(%r6) ;# 7044 movqi+1/6
+L$0759
+ ldw 4(%r5),%r20 ;# 8207 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8205 subsi3/1
+ ldo 1(%r19),%r19 ;# 8206 addsi3/2
+ comb,>>=,n %r20,%r19,L$0764 ;# 8208 bleu+1
+ ldil L'65536,%r3 ;# 8555 reload_outsi+2/3
+L$0765
+ comb,= %r3,%r20,L$0944 ;# 7086 bleu+1
+ zdep %r20,30,31,%r19 ;# 7096 ashlsi3+1
+ comb,>>= %r3,%r19,L$0770 ;# 7104 bleu+1
+ stw %r19,4(%r5) ;# 7098 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 7107 reload_outsi+2/6
+L$0770
+ ldw 0(%r5),%r26 ;# 7114 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 7118 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 7116 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 7126 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 7122 reload_outsi+2/6
+ comb,= %r28,%r4,L$0763 ;# 7136 bleu+1
+ sub %r6,%r4,%r19 ;# 7138 subsi3/1
+ addl %r28,%r19,%r6 ;# 7141 addsi3/1
+ sub %r12,%r4,%r19 ;# 7142 subsi3/1
+ comib,= 0,%r10,L$0773 ;# 7147 bleu+1
+ addl %r28,%r19,%r12 ;# 7145 addsi3/1
+ sub %r10,%r4,%r19 ;# 7148 subsi3/1
+ addl %r28,%r19,%r10 ;# 7151 addsi3/1
+L$0773
+ comib,= 0,%r8,L$0774 ;# 7154 bleu+1
+ sub %r8,%r4,%r19 ;# 7155 subsi3/1
+ addl %r28,%r19,%r8 ;# 7158 addsi3/1
+L$0774
+ comib,= 0,%r9,L$0763 ;# 7161 bleu+1
+ sub %r9,%r4,%r19 ;# 7162 subsi3/1
+ addl %r28,%r19,%r9 ;# 7165 addsi3/1
+L$0763
+ ldw 0(%r5),%r4 ;# 7066 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 7070 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 7067 subsi3/1
+ ldo 1(%r19),%r19 ;# 7068 addsi3/2
+ comb,<< %r20,%r19,L$0765
+ nop ;# 7072 bleu+1
+L$0764
+ ldi 11,%r19 ;# 7187 movqi+1/2
+ bl L$0043,%r0 ;# 7200 jump
+ stbs,ma %r19,1(%r6) ;# 7188 movqi+1/6
+L$0787
+ bb,< %r15,17,L$0076 ;# 7216 bleu+3
+ ldo -48(%r7),%r19 ;# 7224 addsi3/2
+ ldw -260(%r30),%r1 ;# 8986 reload_outsi+2/5
+ extru %r19,31,8,%r3 ;# 7225 zero_extendqisi2/1
+ comb,<< %r1,%r3,L$0939 ;# 7230 bleu+1
+ ldo -312(%r30),%r26 ;# 7244 addsi3/2
+ .CALL ARGW0=GR,ARGW1=GR
+ bl group_in_compile_stack,%r2 ;# 7248 call_value_internal_symref
+ copy %r3,%r25 ;# 7246 reload_outsi+2/1
+ extrs %r28,31,8,%r28 ;# 7251 extendqisi2
+ comib,<>,n 0,%r28,L$0076 ;# 7253 bleu+1
+ ldw 0(%r5),%r4 ;# 8212 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8215 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8213 subsi3/1
+ ldo 2(%r19),%r19 ;# 8214 addsi3/2
+ comb,>>= %r20,%r19,L$0795 ;# 8216 bleu+1
+ copy %r6,%r8 ;# 7260 reload_outsi+2/1
+ ldil L'65536,%r7 ;# 8553 reload_outsi+2/3
+L$0796
+ comb,= %r7,%r20,L$0944 ;# 7288 bleu+1
+ zdep %r20,30,31,%r19 ;# 7298 ashlsi3+1
+ comb,>>= %r7,%r19,L$0801 ;# 7306 bleu+1
+ stw %r19,4(%r5) ;# 7300 reload_outsi+2/6
+ stw %r7,4(%r5) ;# 7309 reload_outsi+2/6
+L$0801
+ ldw 0(%r5),%r26 ;# 7316 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 7320 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 7318 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 7328 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 7324 reload_outsi+2/6
+ comb,= %r28,%r4,L$0794 ;# 7338 bleu+1
+ sub %r6,%r4,%r19 ;# 7340 subsi3/1
+ addl %r28,%r19,%r6 ;# 7343 addsi3/1
+ sub %r12,%r4,%r19 ;# 7344 subsi3/1
+ comib,= 0,%r10,L$0804 ;# 7349 bleu+1
+ addl %r28,%r19,%r12 ;# 7347 addsi3/1
+ sub %r10,%r4,%r19 ;# 7350 subsi3/1
+ addl %r28,%r19,%r10 ;# 7353 addsi3/1
+L$0804
+ comib,= 0,%r8,L$0805 ;# 7356 bleu+1
+ sub %r8,%r4,%r19 ;# 7357 subsi3/1
+ addl %r28,%r19,%r8 ;# 7360 addsi3/1
+L$0805
+ comib,= 0,%r9,L$0794 ;# 7363 bleu+1
+ sub %r9,%r4,%r19 ;# 7364 subsi3/1
+ addl %r28,%r19,%r9 ;# 7367 addsi3/1
+L$0794
+ ldw 0(%r5),%r4 ;# 7268 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 7272 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 7269 subsi3/1
+ ldo 2(%r19),%r19 ;# 7270 addsi3/2
+ comb,<< %r20,%r19,L$0796
+ nop ;# 7274 bleu+1
+L$0795
+ ldi 7,%r19 ;# 7389 movqi+1/2
+ stbs,ma %r19,1(%r6) ;# 7390 movqi+1/6
+ bl L$0043,%r0 ;# 7405 jump
+ stbs,ma %r3,1(%r6) ;# 7393 movqi+1/6
+L$0811
+ bb,< %r15,30,L$0104
+ nop ;# 7414 bleu+3
+L$0397
+ comib,= 0,%r14,L$0815 ;# 7429 bleu+1
+ addl %r14,%r7,%r19 ;# 7430 addsi3/1
+ bl L$0816,%r0 ;# 7434 jump
+ ldb 0(%r19),%r19 ;# 7433 zero_extendqisi2/2
+L$0815
+ copy %r7,%r19 ;# 7438 reload_outsi+2/1
+L$0816
+ copy %r19,%r7 ;# 7441 reload_outsi+2/1
+L$0076
+ comib,=,n 0,%r9,L$0820 ;# 7460 bleu+1
+ ldb 0(%r9),%r20 ;# 7463 zero_extendqisi2/2
+ addl %r9,%r20,%r19 ;# 7464 addsi3/1
+ ldo 1(%r19),%r19 ;# 7465 addsi3/2
+ comb,<> %r6,%r19,L$0820 ;# 7467 bleu+1
+ ldi 255,%r19 ;# 7472 reload_outsi+2/2
+ comb,= %r19,%r20,L$0820 ;# 7474 bleu+1
+ ldw -296(%r30),%r21 ;# 7476 reload_outsi+2/5
+ ldb 0(%r21),%r19 ;# 7478 movqi+1/5
+ extrs %r19,31,8,%r20 ;# 7479 extendqisi2
+ ldi 42,%r19 ;# 7481 reload_outsi+2/2
+ comb,= %r19,%r20,L$0820 ;# 7483 bleu+1
+ ldi 94,%r19 ;# 7490 reload_outsi+2/2
+ comb,=,n %r19,%r20,L$0820 ;# 7492 bleu+1
+ bb,>= %r15,30,L$0821 ;# 7497 movsi-4
+ ldi 92,%r19 ;# 7504 reload_outsi+2/2
+ comb,<>,n %r19,%r20,L$0822 ;# 7506 bleu+1
+ ldb 1(%r21),%r19 ;# 7510 movqi+1/5
+ extrs %r19,31,8,%r20 ;# 7511 extendqisi2
+L$0821
+ ldi 43,%r19 ;# 7534 reload_outsi+2/2
+ comb,= %r19,%r20,L$0820 ;# 7536 bleu+1
+ ldi 63,%r19 ;# 7543 reload_outsi+2/2
+ comb,=,n %r19,%r20,L$0820 ;# 7545 bleu+1
+L$0822
+ bb,>=,n %r15,22,L$0819 ;# 7553 movsi-4
+ bb,>= %r15,19,L$0823 ;# 7558 movsi-4
+ ldw -296(%r30),%r19 ;# 7560 reload_outsi+2/5
+ ldb 0(%r19),%r19 ;# 7562 movqi+1/5
+ ldi 123,%r20 ;# 7565 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 7563 extendqisi2
+ comb,=,n %r20,%r19,L$0820 ;# 7567 bleu+1
+ ldw 0(%r5),%r4 ;# 8228 reload_outsi+2/5
+ bl,n L$1177,%r0 ;# 7568 jump
+L$0823
+ ldw -296(%r30),%r21 ;# 7572 reload_outsi+2/5
+ ldb 0(%r21),%r19 ;# 7574 movqi+1/5
+ ldi 92,%r20 ;# 7577 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 7575 extendqisi2
+ comb,<>,n %r20,%r19,L$0819 ;# 7579 bleu+1
+ ldb 1(%r21),%r19 ;# 7583 movqi+1/5
+ ldi 123,%r20 ;# 7586 reload_outsi+2/2
+ extrs %r19,31,8,%r19 ;# 7584 extendqisi2
+ comb,<>,n %r20,%r19,L$0819 ;# 7588 bleu+1
+L$0820
+ ldw 0(%r5),%r4 ;# 8220 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 8223 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8221 subsi3/1
+ ldo 2(%r19),%r19 ;# 8222 addsi3/2
+ comb,>>= %r20,%r19,L$0829 ;# 8224 bleu+1
+ copy %r6,%r8 ;# 7596 reload_outsi+2/1
+ ldil L'65536,%r3 ;# 8551 reload_outsi+2/3
+L$0830
+ comb,= %r3,%r20,L$0944 ;# 7624 bleu+1
+ zdep %r20,30,31,%r19 ;# 7634 ashlsi3+1
+ comb,>>= %r3,%r19,L$0835 ;# 7642 bleu+1
+ stw %r19,4(%r5) ;# 7636 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 7645 reload_outsi+2/6
+L$0835
+ ldw 0(%r5),%r26 ;# 7652 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 7656 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 7654 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 7664 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 7660 reload_outsi+2/6
+ comb,= %r28,%r4,L$0828 ;# 7674 bleu+1
+ sub %r6,%r4,%r19 ;# 7676 subsi3/1
+ addl %r28,%r19,%r6 ;# 7679 addsi3/1
+ sub %r12,%r4,%r19 ;# 7680 subsi3/1
+ comib,= 0,%r10,L$0838 ;# 7685 bleu+1
+ addl %r28,%r19,%r12 ;# 7683 addsi3/1
+ sub %r10,%r4,%r19 ;# 7686 subsi3/1
+ addl %r28,%r19,%r10 ;# 7689 addsi3/1
+L$0838
+ comib,= 0,%r8,L$0839 ;# 7692 bleu+1
+ sub %r8,%r4,%r19 ;# 7693 subsi3/1
+ addl %r28,%r19,%r8 ;# 7696 addsi3/1
+L$0839
+ comib,= 0,%r9,L$0828 ;# 7699 bleu+1
+ sub %r9,%r4,%r19 ;# 7700 subsi3/1
+ addl %r28,%r19,%r9 ;# 7703 addsi3/1
+L$0828
+ ldw 0(%r5),%r4 ;# 7604 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 7608 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 7605 subsi3/1
+ ldo 2(%r19),%r19 ;# 7606 addsi3/2
+ comb,<< %r20,%r19,L$0830
+ nop ;# 7610 bleu+1
+L$0829
+ ldi 1,%r19 ;# 7725 movqi+1/2
+ stbs,ma %r19,1(%r6) ;# 7726 movqi+1/6
+ stbs,ma %r0,1(%r6) ;# 7729 movqi+1/6
+ ldo -1(%r6),%r9 ;# 7741 addsi3/2
+L$0819
+ ldw 0(%r5),%r4 ;# 8228 reload_outsi+2/5
+L$1177
+ ldw 4(%r5),%r20 ;# 8231 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 8229 subsi3/1
+ ldo 1(%r19),%r19 ;# 8230 addsi3/2
+ comb,>>=,n %r20,%r19,L$0848 ;# 8232 bleu+1
+ ldil L'65536,%r3 ;# 8549 reload_outsi+2/3
+L$0849
+ comb,= %r3,%r20,L$0944 ;# 7771 bleu+1
+ zdep %r20,30,31,%r19 ;# 7781 ashlsi3+1
+ comb,>>= %r3,%r19,L$0854 ;# 7789 bleu+1
+ stw %r19,4(%r5) ;# 7783 reload_outsi+2/6
+ stw %r3,4(%r5) ;# 7792 reload_outsi+2/6
+L$0854
+ ldw 0(%r5),%r26 ;# 7799 reload_outsi+2/5
+ .CALL ARGW0=GR,ARGW1=GR
+ bl realloc,%r2 ;# 7803 call_value_internal_symref
+ ldw 4(%r5),%r25 ;# 7801 reload_outsi+2/5
+ comiclr,<> 0,%r28,%r0 ;# 7811 bleu+1
+ bl L$0953,%r0
+ stw %r28,0(%r5) ;# 7807 reload_outsi+2/6
+ comb,= %r28,%r4,L$0847 ;# 7821 bleu+1
+ sub %r6,%r4,%r19 ;# 7823 subsi3/1
+ addl %r28,%r19,%r6 ;# 7826 addsi3/1
+ sub %r12,%r4,%r19 ;# 7827 subsi3/1
+ comib,= 0,%r10,L$0857 ;# 7832 bleu+1
+ addl %r28,%r19,%r12 ;# 7830 addsi3/1
+ sub %r10,%r4,%r19 ;# 7833 subsi3/1
+ addl %r28,%r19,%r10 ;# 7836 addsi3/1
+L$0857
+ comib,= 0,%r8,L$0858 ;# 7839 bleu+1
+ sub %r8,%r4,%r19 ;# 7840 subsi3/1
+ addl %r28,%r19,%r8 ;# 7843 addsi3/1
+L$0858
+ comib,= 0,%r9,L$0847 ;# 7846 bleu+1
+ sub %r9,%r4,%r19 ;# 7847 subsi3/1
+ addl %r28,%r19,%r9 ;# 7850 addsi3/1
+L$0847
+ ldw 0(%r5),%r4 ;# 7751 reload_outsi+2/5
+ ldw 4(%r5),%r20 ;# 7755 reload_outsi+2/5
+ sub %r6,%r4,%r19 ;# 7752 subsi3/1
+ ldo 1(%r19),%r19 ;# 7753 addsi3/2
+ comb,<< %r20,%r19,L$0849
+ nop ;# 7757 bleu+1
+L$0848
+ stbs,ma %r7,1(%r6) ;# 7872 movqi+1/6
+ ldb 0(%r9),%r19 ;# 7885 movqi+1/5
+ ldo 1(%r19),%r19 ;# 7888 addsi3/2
+ stb %r19,0(%r9) ;# 7890 movqi+1/6
+L$0043
+ ldw -296(%r30),%r19 ;# 2328 reload_outsi+2/5
+L$1161
+ comclr,= %r16,%r19,%r0 ;# 258 bleu+1
+ bl L$1178,%r0
+ ldw -296(%r30),%r19 ;# 2334 reload_outsi+2/5
+L$0044
+ comib,= 0,%r10,L$0865 ;# 7913 bleu+1
+ ldi 13,%r26 ;# 7918 reload_outsi+2/2
+ copy %r10,%r25 ;# 7920 reload_outsi+2/1
+ sub %r6,%r25,%r24 ;# 7915 subsi3/1
+ .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
+ bl store_op1,%r2 ;# 7924 call_internal_symref
+ ldo -3(%r24),%r24 ;# 7922 addsi3/2
+L$0865
+ ldw -304(%r30),%r19 ;# 7928 reload_outsi+2/5
+ comib,<>,n 0,%r19,L$0866 ;# 7930 bleu+1
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 7946 call_internal_symref
+ ldw -312(%r30),%r26 ;# 7944 reload_outsi+2/5
+ ldw 0(%r5),%r19 ;# 7949 reload_outsi+2/5
+ ldi 0,%r28 ;# 7955 reload_outsi+2/2
+ sub %r6,%r19,%r19 ;# 7950 subsi3/1
+ bl L$0867,%r0 ;# 7957 jump
+ stw %r19,8(%r5) ;# 7952 reload_outsi+2/6
+L$0895
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 2269 call_internal_symref
+ ldw -312(%r30),%r26 ;# 2267 reload_outsi+2/5
+ bl L$0867,%r0 ;# 2273 jump
+ ldi 11,%r28 ;# 2271 reload_outsi+2/2
+L$0900
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 3161 call_internal_symref
+ ldw -312(%r30),%r26 ;# 3159 reload_outsi+2/5
+ bl L$0867,%r0 ;# 3165 jump
+ ldi 4,%r28 ;# 3163 reload_outsi+2/2
+L$0902
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 3218 call_internal_symref
+ ldw -312(%r30),%r26 ;# 3216 reload_outsi+2/5
+ bl L$0867,%r0 ;# 3222 jump
+ ldi 7,%r28 ;# 3220 reload_outsi+2/2
+L$0903
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 3803 call_internal_symref
+ ldw -312(%r30),%r26 ;# 3801 reload_outsi+2/5
+ bl L$0867,%r0 ;# 3807 jump
+ ldi 5,%r28 ;# 3805 reload_outsi+2/2
+L$0915
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 5461 call_internal_symref
+ ldw -312(%r30),%r26 ;# 5459 reload_outsi+2/5
+ bl L$0867,%r0 ;# 5465 jump
+ ldi 9,%r28 ;# 5463 reload_outsi+2/2
+L$0917
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 5557 call_internal_symref
+ ldw -312(%r30),%r26 ;# 5555 reload_outsi+2/5
+ bl L$0867,%r0 ;# 5561 jump
+ ldi 13,%r28 ;# 5559 reload_outsi+2/2
+L$0922
+ bl L$0867,%r0 ;# 5983 jump
+ ldi 14,%r28 ;# 5981 reload_outsi+2/2
+L$0939
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 7235 call_internal_symref
+ ldw -312(%r30),%r26 ;# 7233 reload_outsi+2/5
+ bl L$0867,%r0 ;# 7239 jump
+ ldi 6,%r28 ;# 7237 reload_outsi+2/2
+L$0944
+ bl L$0867,%r0 ;# 7775 jump
+ ldi 15,%r28 ;# 7773 reload_outsi+2/2
+L$0866
+ .CALL ARGW0=GR
+ bl free,%r2 ;# 7935 call_internal_symref
+ ldw -312(%r30),%r26 ;# 7933 reload_outsi+2/5
+ ldi 8,%r28 ;# 7937 reload_outsi+2/2
+L$0867
+ ldw -340(%r30),%r2 ;# 9026 reload_outsi+2/5
+ ldw -168(%r30),%r18 ;# 9028 reload_outsi+2/5
+ ldw -164(%r30),%r17 ;# 9030 reload_outsi+2/5
+ ldw -160(%r30),%r16 ;# 9032 reload_outsi+2/5
+ ldw -156(%r30),%r15 ;# 9034 reload_outsi+2/5
+ ldw -152(%r30),%r14 ;# 9036 reload_outsi+2/5
+ ldw -148(%r30),%r13 ;# 9038 reload_outsi+2/5
+ ldw -144(%r30),%r12 ;# 9040 reload_outsi+2/5
+ ldw -140(%r30),%r11 ;# 9042 reload_outsi+2/5
+ ldw -136(%r30),%r10 ;# 9044 reload_outsi+2/5
+ ldw -132(%r30),%r9 ;# 9046 reload_outsi+2/5
+ ldw -128(%r30),%r8 ;# 9048 reload_outsi+2/5
+ ldw -124(%r30),%r7 ;# 9050 reload_outsi+2/5
+ ldw -120(%r30),%r6 ;# 9052 reload_outsi+2/5
+ ldw -116(%r30),%r5 ;# 9054 reload_outsi+2/5
+ ldw -112(%r30),%r4 ;# 9056 reload_outsi+2/5
+ ldw -108(%r30),%r3 ;# 9058 reload_outsi+2/5
+ bv %r0(%r2) ;# 9061 return_internal
+ ldo -320(%r30),%r30 ;# 9060 addsi3/2
+ .EXIT
+ .PROCEND
+ .SPACE $PRIVATE$
+ .SUBSPA $BSS$
+
+ .align 1
+re_syntax_table
+ .block 256
diff --git a/gas/testsuite/gas/hppa/unsorted/common.s b/gas/testsuite/gas/hppa/unsorted/common.s
new file mode 100644
index 00000000000..d92b0cba70e
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/common.s
@@ -0,0 +1,8 @@
+ .text
+text_symbol:
+ .long 1
+ .long external_symbol
+ .data
+data_symbol:
+ .long 2
+common_symbol .comm 4
diff --git a/gas/testsuite/gas/hppa/unsorted/fragbug.s b/gas/testsuite/gas/hppa/unsorted/fragbug.s
new file mode 100644
index 00000000000..57341937e7c
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/fragbug.s
@@ -0,0 +1,3 @@
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+ nop
diff --git a/gas/testsuite/gas/hppa/unsorted/globalbug.s b/gas/testsuite/gas/hppa/unsorted/globalbug.s
new file mode 100644
index 00000000000..d0f05f64c0a
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/globalbug.s
@@ -0,0 +1,16 @@
+
+ .space $PRIVATE$
+ .subspa $GLOBAL$
+ .export $global$
+$global$
+ .space $TEXT$
+ .subspa $CODE$
+
+ .proc
+ .callinfo
+ivaaddr
+ nop
+ nop
+ addil L%ivaaddr-$global$,%dp
+ ldo R%ivaaddr-$global$(%r1),%r19
+ .procend
diff --git a/gas/testsuite/gas/hppa/unsorted/importbug.s b/gas/testsuite/gas/hppa/unsorted/importbug.s
new file mode 100644
index 00000000000..104afb6f262
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/importbug.s
@@ -0,0 +1,42 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .EXPORT foo,DATA
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+
+ .align 4
+foo:
+ .word 0
+ .IMPORT __main,CODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT main,CODE
+ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
+main:
+ .PROC
+ .CALLINFO FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
+ .ENTRY
+ .import foo
+ stw %r2,-20(0,%r30)
+ copy %r3,%r1
+ copy %r30,%r3
+ stwm %r1,64(%r30)
+ .CALL
+ bl __main,%r2
+ nop
+L$0001:
+ ldw -20(%r3),%r2
+ ldo 64(%r3),%r30
+ ldwm -64(%r30),%r3
+ bv,n %r0(%r2)
+ .EXIT
+ .PROCEND
diff --git a/gas/testsuite/gas/hppa/unsorted/labeldiffs.s b/gas/testsuite/gas/hppa/unsorted/labeldiffs.s
new file mode 100644
index 00000000000..6ee66f97354
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/labeldiffs.s
@@ -0,0 +1,40 @@
+; Should check to make sure something useful gets put on those .word
+; statements.
+ .space $TEXT$
+ .subspa $CODE$
+
+ .align 8
+ .export icode,data
+icode:
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+ bv,n %r0(%r2)
+ .exit
+ nop
+ .procend
+
+ ;
+ ; FIRST, argv array of pointers to args, 1st is same as path.
+ ;
+ .align 8
+ic_argv:
+ .word ic_argv1-icode ; second, pointer to 1st argument
+ .word ic_path-icode ; first, pointer to init path
+ .word 0 ; fourth, NULL argv terminator (pad)
+ .word 0 ; third, NULL argv terminator
+
+ic_path:
+ .blockz 4096 ; must be multiple of 4 bytes
+ .word 0 ; in case full string is used
+ .word 0 ; this will be the string terminator
+
+ic_argv1:
+ .blockz 4096 ; must be multiple of 4 bytes
+ .word 0 ; in case full string is used
+ .word 0 ; this will be the string terminator
+
+ .export szicode,data
+szicode:
+ .word szicode-icode
+ .word 0 ; must have at least one filler at end
diff --git a/gas/testsuite/gas/hppa/unsorted/locallabel.s b/gas/testsuite/gas/hppa/unsorted/locallabel.s
new file mode 100644
index 00000000000..7d5721edaa6
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/locallabel.s
@@ -0,0 +1,15 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+
+Label:
+L$01234:
+
diff --git a/gas/testsuite/gas/hppa/unsorted/ss_align.s b/gas/testsuite/gas/hppa/unsorted/ss_align.s
new file mode 100644
index 00000000000..6e98eb2e69a
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/ss_align.s
@@ -0,0 +1,12 @@
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=64,ACCESS=31
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+; gcc_compiled.:
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$
+sym1: .WORD 2
+
diff --git a/gas/testsuite/gas/hppa/unsorted/unsorted.exp b/gas/testsuite/gas/hppa/unsorted/unsorted.exp
new file mode 100644
index 00000000000..31300c70b2f
--- /dev/null
+++ b/gas/testsuite/gas/hppa/unsorted/unsorted.exp
@@ -0,0 +1,258 @@
+# Copyright (C) 1993, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by the Center for Software Science at the University of Utah
+# and by Cygnus Support.
+
+proc do_subspace_align_test {} {
+ set testname "ss_align.s: Test subspace alignment (part 2)"
+ set x 0
+
+ if [gas_test_old "ss_align.s" "" "subspace alignment (part 1)"] then {
+ objdump_start_no_subdir "a.out" "-h"
+
+ # Check the headers for the correct alignment value for the
+ # .data section (elf) or the $DATA$ subspace (som).
+ if [istarget hppa*-*-*elf*] then {
+ while 1 {
+ expect {
+ -re "data\[^\n\]* 2..6\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ } else {
+ while 1 {
+ expect {
+ -re "DATA\[^\n\]* 2..6\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_local_label_test {} {
+ set testname "locallabel.s: Elimination of local labels (part 2)"
+ set x 0
+
+ if [gas_test_old "locallabel.s" "" "Elimination of local labels (part1)"] {
+ objdump_start_no_subdir "a.out" "-t"
+
+ while 1 {
+ expect {
+ -re "^00000000\[^\n\]*Label\[^\n\]*\n" { set x 1 }
+ -re "^00000000\[^\n\]*L\$01234\[^\n\]*\n" { set x 0 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_frchain_test {} {
+ set testname "fragbug.s: Test bug in frag chaining (part 2)"
+ set x 0
+
+ if [gas_test_old "fragbug.s" "" "Test bug in frag chaining (part1)"] {
+ objdump_start_no_subdir "a.out" "--prefix-addresses -d"
+
+ while 1 {
+ expect {
+ -re "^0x00000000\[^\n\]*nop\[^\n\]*\n" { set x 1 }
+ -re "^0x00000004\[^\n\]*nop\[^\n\]*\n" { set x 0 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_align3_test {} {
+ set testname "align3.s: Test for alignment bug when switching subspaces (part2)"
+ set x 0
+
+ if [gas_test_old "align3.s" "" "Test for alignment bug when switching subspaces (part1)"] {
+ objdump_start_no_subdir "a.out" "--prefix-addresses -d"
+
+ while 1 {
+ expect {
+ -re "\[^\n\]* <main> nop\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]* <.*end_main> nop\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]* <main+.*> nop\[^\n\]*\n" { set x 0 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_align4_test {} {
+ set testname "align4.s: More subspace alignment tests (part2)"
+ set x 0
+
+ if [istarget hppa*-*-*elf*] then {
+ return
+ }
+
+ if [gas_test_old "align4.s" "" "More subspace alignment tests (part1)"] {
+ objdump_start_no_subdir "a.out" "-h"
+
+ while 1 {
+ expect {
+ -re "\[^\n\]*MILLICODE\[^\n\]*2..6\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*YABBA\[^\n\]*2..3\[^\n\]*\n"
+ { set x [expr $x+1] }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==2] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_import_test {} {
+ set testname "importbug.s: Test for bug in .import directive (part2)"
+ set x 0
+
+ if [gas_test_old "importbug.s" "" "Test for bug in .import directive (part1)"] {
+ objdump_start_no_subdir "a.out" "--syms"
+
+ while 1 {
+ expect {
+ -re "\[^\n\]*.DATA..foo\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*.data.*foo\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+proc do_common_test {} {
+ set testname "common.s: Test for bug in .comm handling (part2)"
+ set x 0
+
+ if [gas_test_old "common.s" "" "Test for bug in .comm handling (part1)"] {
+ objdump_start_no_subdir "a.out" "--syms"
+
+ while 1 {
+ expect {
+ -re "\[^\n\]*.COM.*common_symbol\[^\n\]*\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==1] then { pass $testname } else { fail $testname }
+ }
+}
+
+if [istarget hppa*-*-*] then {
+ # Make sure subspace alignment requests from the subspace directives
+ # are honored
+ do_subspace_align_test
+
+ # Make sure the correct labels end up in the symbol table
+ do_local_label_test
+
+ # GAS-1.36 choked on this file.
+ gas_test "labeldiffs.s" "" "" "Difference of labels"
+
+ # Test a recent bug where frag chaining wasn't working correctly.
+ do_frchain_test
+
+ # Test bug where switching between subspaces creates bogus alignments
+ do_align3_test
+
+ # Test bug where switching between subspaces creates bogus alignments
+ do_align4_test
+
+ # Test a problem where $global$ is defined, then used within the
+ # same source file.
+ setup_xfail hppa*-*-*
+ gas_test "globalbug.s" "" "" "Use \$global\$ in file which defines it"
+
+ # Test that importing a defined symbol doesn't screw up the symbol's
+ # space/subspace.
+ do_import_test
+
+ # Test for a buglet in the handling of common symbols
+ do_common_test
+
+ # Test for an off-by-2 bug in range check for conditional branches
+ gas_test_error "brlenbug.s" "" "Check for error(s) in branch length"
+
+}
+
diff --git a/gas/testsuite/gas/i386/amd.d b/gas/testsuite/gas/i386/amd.d
new file mode 100644
index 00000000000..2fe8b0e8b28
--- /dev/null
+++ b/gas/testsuite/gas/i386/amd.d
@@ -0,0 +1,37 @@
+#objdump: -dw
+#name: i386 amd
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <.text>:
+ 0: 0f 0d 03 [ ]*prefetch \(%ebx\)
+ 3: 0f 0d 0c 75 00 10 00 00 [ ]*prefetchw 0x1000\(,%esi,2\)
+ b: 0f 0e [ ]*femms
+ d: 0f 0f 00 bf [ ]*pavgusb \(%eax\),%mm0
+ 11: 0f 0f 48 02 1d [ ]*pf2id 0x2\(%eax\),%mm1
+ 16: 0f 0f 90 00 01 00 00 ae [ ]*pfacc 0x100\(%eax\),%mm2
+ 1e: 0f 0f 1e 9e [ ]*pfadd \(%esi\),%mm3
+ 22: 0f 0f 66 02 b0 [ ]*pfcmpeq 0x2\(%esi\),%mm4
+ 27: 0f 0f ae 90 90 00 00 90 [ ]*pfcmpge 0x9090\(%esi\),%mm5
+ 2f: 0f 0f 74 75 00 a0 [ ]*pfcmpgt 0x0\(%ebp,%esi,2\),%mm6
+ 35: 0f 0f 7c 75 02 a4 [ ]*pfmax 0x2\(%ebp,%esi,2\),%mm7
+ 3b: 0f 0f 84 75 90 90 90 90 94 [ ]*pfmin 0x90909090\(%ebp,%esi,2\),%mm0
+ 44: 0f 0f 0d 04 00 00 00 b4 [ ]*pfmul 0x4,%mm1
+ 4c: 2e 0f 0f 54 c3 07 96 [ ]*pfrcp %cs:0x7\(%ebx,%eax,8\),%mm2
+ 53: 0f 0f d8 a6 [ ]*pfrcpit1 %mm0,%mm3
+ 57: 0f 0f e1 b6 [ ]*pfrcpit2 %mm1,%mm4
+ 5b: 0f 0f ea a7 [ ]*pfrsqit1 %mm2,%mm5
+ 5f: 0f 0f f3 97 [ ]*pfrsqrt %mm3,%mm6
+ 63: 0f 0f fc 9a [ ]*pfsub %mm4,%mm7
+ 67: 0f 0f c5 aa [ ]*pfsubr %mm5,%mm0
+ 6b: 0f 0f ce 0d [ ]*pi2fd %mm6,%mm1
+ 6f: 0f 0f d7 b7 [ ]*pfmulhrw %mm7,%mm2
+ 73: 2e 0f [ ]*\(bad\)
+ 75: 0f 54 [ ]*\(bad\)
+ 77: c3 [ ]*ret
+ 78: 07 [ ]*pop %es
+ 79: c3 [ ]*ret
+ 7a: 90 [ ]*nop
+ 7b: 90 [ ]*nop
diff --git a/gas/testsuite/gas/i386/amd.s b/gas/testsuite/gas/i386/amd.s
new file mode 100644
index 00000000000..5e4d581f08e
--- /dev/null
+++ b/gas/testsuite/gas/i386/amd.s
@@ -0,0 +1,33 @@
+#AMD 3DNow! instructions
+
+.text
+ prefetch (%ebx)
+ prefetchw 0x1000(,%esi,2)
+ femms
+ pavgusb (%eax),%mm0
+ pf2id 2(%eax),%mm1
+ pfacc 0x100(%eax),%mm2
+ pfadd (%esi),%mm3
+ pfcmpeq 2(%esi),%mm4
+ pfcmpge 0x9090(%esi),%mm5
+ pfcmpgt (%ebp,%esi,2),%mm6
+ pfmax 2(%ebp,%esi,2),%mm7
+ pfmin 0x90909090(%ebp,%esi,2),%mm0
+ pfmul 4,%mm1
+ pfrcp %cs:7(%ebx,%eax,8),%mm2
+ pfrcpit1 %mm0,%mm3
+ pfrcpit2 %mm1,%mm4
+ pfrsqit1 %mm2,%mm5
+ pfrsqrt %mm3,%mm6
+ pfsub %mm4,%mm7
+ pfsubr %mm5,%mm0
+ pi2fd %mm6,%mm1
+ pmulhrw %mm7,%mm2
+
+# This is a 3DNow! instruction, with a prefix, that isn't quite right
+# Everything's good bar the opcode suffix
+.byte 0x2e, 0x0f, 0x0f, 0x54, 0xc3, 0x07, 0xc3
+
+# to make us insensitive to alignment
+ nop
+ nop
diff --git a/gas/testsuite/gas/i386/float.l b/gas/testsuite/gas/i386/float.l
new file mode 100644
index 00000000000..6d6cadd740f
--- /dev/null
+++ b/gas/testsuite/gas/i386/float.l
@@ -0,0 +1,81 @@
+.*: Assembler messages:
+.*:3: Warning:.*faddp.*
+.*:14: Warning:.*fsubp.*
+.*:25: Warning:.*fsubrp.*
+.*:36: Warning:.*fmulp.*
+.*:47: Warning:.*fdivp.*
+.*:58: Warning:.*fdivrp.*
+ 1 [ ]*.psize 0
+ 2 [ ]*.text
+ 3 0000 DEC1 [ ]*fadd
+.*Warning:.*faddp.*
+ 4 0002 D8C3 [ ]*fadd %st\(3\)
+ 5 0004 D8C3 [ ]*fadd %st\(3\),%st
+ 6 0006 DCC3 [ ]*fadd %st,%st\(3\)
+ 7 0008 D803 [ ]*fadds \(%ebx\)
+ 8 000a DC03 [ ]*faddl \(%ebx\)
+ 9 000c DE03 [ ]*fiadds \(%ebx\)
+ 10 000e DA03 [ ]*fiaddl \(%ebx\)
+ 11 0010 DEC1 [ ]*faddp
+ 12 0012 DEC3 [ ]*faddp %st\(3\)
+ 13 0014 DEC3 [ ]*faddp %st,%st\(3\)
+ 14 0016 DEE1 [ ]*fsub
+.*Warning:.*fsubp.*
+ 15 0018 D8E3 [ ]*fsub %st\(3\)
+ 16 001a D8E3 [ ]*fsub %st\(3\),%st
+ 17 001c DCE3 [ ]*fsub %st,%st\(3\)
+ 18 001e D823 [ ]*fsubs \(%ebx\)
+ 19 0020 DC23 [ ]*fsubl \(%ebx\)
+ 20 0022 DE23 [ ]*fisubs \(%ebx\)
+ 21 0024 DA23 [ ]*fisubl \(%ebx\)
+ 22 0026 DEE1 [ ]*fsubp
+ 23 0028 DEE3 [ ]*fsubp %st\(3\)
+ 24 002a DEE3 [ ]*fsubp %st,%st\(3\)
+ 25 002c DEE9 [ ]*fsubr
+.*Warning:.*fsubrp.*
+ 26 002e D8EB [ ]*fsubr %st\(3\)
+ 27 0030 D8EB [ ]*fsubr %st\(3\),%st
+ 28 0032 DCEB [ ]*fsubr %st,%st\(3\)
+ 29 0034 D82B [ ]*fsubrs \(%ebx\)
+ 30 0036 DC2B [ ]*fsubrl \(%ebx\)
+ 31 0038 DE2B [ ]*fisubrs \(%ebx\)
+ 32 003a DA2B [ ]*fisubrl \(%ebx\)
+ 33 003c DEE9 [ ]*fsubrp
+ 34 003e DEEB [ ]*fsubrp %st\(3\)
+ 35 0040 DEEB [ ]*fsubrp %st,%st\(3\)
+ 36 0042 DEC9 [ ]*fmul
+.*Warning:.*fmulp.*
+ 37 0044 D8CB [ ]*fmul %st\(3\)
+ 38 0046 D8CB [ ]*fmul %st\(3\),%st
+ 39 0048 DCCB [ ]*fmul %st,%st\(3\)
+ 40 004a D80B [ ]*fmuls \(%ebx\)
+ 41 004c DC0B [ ]*fmull \(%ebx\)
+ 42 004e DE0B [ ]*fimuls \(%ebx\)
+ 43 0050 DA0B [ ]*fimull \(%ebx\)
+ 44 0052 DEC9 [ ]*fmulp
+ 45 0054 DECB [ ]*fmulp %st\(3\)
+ 46 0056 DECB [ ]*fmulp %st,%st\(3\)
+ 47 0058 DEF1 [ ]*fdiv
+.*Warning:.*fdivp.*
+ 48 005a D8F3 [ ]*fdiv %st\(3\)
+ 49 005c D8F3 [ ]*fdiv %st\(3\),%st
+ 50 005e DCF3 [ ]*fdiv %st,%st\(3\)
+ 51 0060 D833 [ ]*fdivs \(%ebx\)
+ 52 0062 DC33 [ ]*fdivl \(%ebx\)
+ 53 0064 DE33 [ ]*fidivs \(%ebx\)
+ 54 0066 DA33 [ ]*fidivl \(%ebx\)
+ 55 0068 DEF1 [ ]*fdivp
+ 56 006a DEF3 [ ]*fdivp %st\(3\)
+ 57 006c DEF3 [ ]*fdivp %st,%st\(3\)
+ 58 006e DEF9 [ ]*fdivr
+.*Warning:.*fdivrp.*
+ 59 0070 D8FB [ ]*fdivr %st\(3\)
+ 60 0072 D8FB [ ]*fdivr %st\(3\),%st
+ 61 0074 DCFB [ ]*fdivr %st,%st\(3\)
+ 62 0076 D83B [ ]*fdivrs \(%ebx\)
+ 63 0078 DC3B [ ]*fdivrl \(%ebx\)
+ 64 007a DE3B [ ]*fidivrs \(%ebx\)
+ 65 007c DA3B [ ]*fidivrl \(%ebx\)
+ 66 007e DEF9 [ ]*fdivrp
+ 67 0080 DEFB [ ]*fdivrp %st\(3\)
+ 68 0082 DEFB [ ]*fdivrp %st,%st\(3\)
diff --git a/gas/testsuite/gas/i386/float.s b/gas/testsuite/gas/i386/float.s
new file mode 100644
index 00000000000..6bb09f8b891
--- /dev/null
+++ b/gas/testsuite/gas/i386/float.s
@@ -0,0 +1,68 @@
+.psize 0
+.text
+ fadd
+ fadd %st(3)
+ fadd %st(3),%st
+ fadd %st,%st(3)
+ fadds (%ebx)
+ faddl (%ebx)
+ fiadds (%ebx)
+ fiaddl (%ebx)
+ faddp
+ faddp %st(3)
+ faddp %st,%st(3)
+ fsub
+ fsub %st(3)
+ fsub %st(3),%st
+ fsub %st,%st(3)
+ fsubs (%ebx)
+ fsubl (%ebx)
+ fisubs (%ebx)
+ fisubl (%ebx)
+ fsubp
+ fsubp %st(3)
+ fsubp %st,%st(3)
+ fsubr
+ fsubr %st(3)
+ fsubr %st(3),%st
+ fsubr %st,%st(3)
+ fsubrs (%ebx)
+ fsubrl (%ebx)
+ fisubrs (%ebx)
+ fisubrl (%ebx)
+ fsubrp
+ fsubrp %st(3)
+ fsubrp %st,%st(3)
+ fmul
+ fmul %st(3)
+ fmul %st(3),%st
+ fmul %st,%st(3)
+ fmuls (%ebx)
+ fmull (%ebx)
+ fimuls (%ebx)
+ fimull (%ebx)
+ fmulp
+ fmulp %st(3)
+ fmulp %st,%st(3)
+ fdiv
+ fdiv %st(3)
+ fdiv %st(3),%st
+ fdiv %st,%st(3)
+ fdivs (%ebx)
+ fdivl (%ebx)
+ fidivs (%ebx)
+ fidivl (%ebx)
+ fdivp
+ fdivp %st(3)
+ fdivp %st,%st(3)
+ fdivr
+ fdivr %st(3)
+ fdivr %st(3),%st
+ fdivr %st,%st(3)
+ fdivrs (%ebx)
+ fdivrl (%ebx)
+ fidivrs (%ebx)
+ fidivrl (%ebx)
+ fdivrp
+ fdivrp %st(3)
+ fdivrp %st,%st(3)
diff --git a/gas/testsuite/gas/i386/general.l b/gas/testsuite/gas/i386/general.l
new file mode 100644
index 00000000000..a4034471ea5
--- /dev/null
+++ b/gas/testsuite/gas/i386/general.l
@@ -0,0 +1,205 @@
+.*: Assembler messages:
+.*:10: Warning:.*
+.*:12: Warning:.*
+.*:19: Warning:.*
+.*:22: Warning:.*
+.*:81: Warning:.*
+.*:82: Warning:.*
+.*:83: Warning:.*
+.*:84: Warning:.*
+.*:85: Warning:.*
+.*:86: Warning:.*
+.*:87: Warning:.*
+.*:88: Warning:.*
+.*:89: Warning:.*
+.*:90: Warning:.*
+.*:91: Warning:.*
+.*:92: Warning:.*
+.*:93: Warning:.*
+.*:94: Warning:.*
+.*:95: Warning:.*
+.*:96: Warning:.*
+.*:97: Warning:.*
+.*:98: Warning:.*
+.*:99: Warning:.*
+.*:100: Warning:.*
+.*:101: Warning:.*
+.*:135: Warning:.*
+ 1 .psize 0
+ 2 .text
+ 3 # test various segment reg insns
+ 4 0000 1E push %ds
+ 5 0001 1E pushl %ds
+ 6 0002 1F pop %ds
+ 7 0003 1F popl %ds
+ 8 0004 8CD8 mov %ds,%eax
+ 9 0006 8CD8 movl %ds,%eax
+ 10 0008 8CD8 movl %ds,%ax
+.*Warning:.*
+ 11 000a 8ED8 mov %eax,%ds
+ 12 000c 8ED8 movl %ax,%ds
+.*Warning:.*
+ 13 000e 8ED8 movl %eax,%ds
+ 14
+ 15 0010 661E pushw %ds
+ 16 0012 661F popw %ds
+ 17 0014 668CD8 mov %ds,%ax
+ 18 0017 668CD8 movw %ds,%ax
+ 19 001a 668CD8 movw %ds,%eax
+.*Warning:.*
+ 20 001d 8ED8 mov %ax,%ds
+ 21 001f 8ED8 movw %ax,%ds
+ 22 0021 8ED8 movw %eax,%ds
+.*Warning:.*
+ 23
+ 24 # test various pushes
+ 25 0023 6A0A pushl \$10
+ 26 0025 666A0A pushw \$10
+ 27 0028 6A0A push \$10
+ 28 002a 68E80300 00 pushl \$1000
+ 29 002f 6668E803 pushw \$1000
+ 30 0033 68E80300 00 push \$1000
+ 31 0038 FF355700 0000 pushl 1f
+ 32 003e 66FF3557 000000 pushw 1f
+ 33 0045 FF355700 0000 push 1f
+ 34 004b FFB30C00 0000 push \(1f-.\)\(%ebx\)
+ 35 0051 FF350600 0000 push 1f-.
+ 36 # these, and others like them should have no operand size prefix
+ 37 0057 0F00D1 1: lldt %cx
+ 38 005a 0F01F0 lmsw %ax
+ 39
+ 40 # Just to make sure these don't become illegal due to over-enthusiastic
+ 41 # register checking
+ 42 005d 660FBEF8 movsbw %al,%di
+ 43 0061 0FBEC8 movsbl %al,%ecx
+ 44 0064 0FBFC8 movswl %ax,%ecx
+ 45 0067 660FB6F8 movzbw %al,%di
+ 46 006b 0FB6C8 movzbl %al,%ecx
+ 47 006e 0FB7C8 movzwl %ax,%ecx
+ 48
+ 49 0071 EC in %dx,%al
+ 50 0072 66ED in %dx,%ax
+ 51 0074 ED in %dx,%eax
+ 52 0075 EC in \(%dx\),%al
+ 53 0076 66ED in \(%dx\),%ax
+ 54 0078 ED in \(%dx\),%eax
+ 55 0079 EC inb %dx,%al
+ 56 007a 66ED inw %dx,%ax
+ 57 007c ED inl %dx,%eax
+ 58 007d EC inb %dx
+ 59 007e 66ED inw %dx
+ 60 0080 ED inl %dx
+ 61 0081 E4FF inb \$255
+ 62 0083 66E502 inw \$2
+ 63 0086 E504 inl \$4
+ 64 0088 EF outl %eax,%dx
+ 65 0089 E62A out %al, \$42
+ 66 008b 66E50D in \$13, %ax
+ 67 # These are used in AIX.
+ 68 008e 66ED inw \(%dx\)
+ 69 0090 66EF outw \(%dx\)
+ 70
+ 71 0092 A4 movsb
+ 72 0093 66A7 cmpsw
+ 73 0095 AF scasl
+ 74 0096 D7 xlatb
+ 75 0097 2EA5 movsl %cs:\(%esi\),%es:\(%edi\)
+ 76 0099 0F9303 setae \(%ebx\)
+ 77 009c 0F9303 setaeb \(%ebx\)
+ 78 009f 0F93C0 setae %al
+ 79
+ 80 #these should give warnings
+ 81 00a2 0C01 orb \$1,%ax
+.*Warning:.*
+ 82 00a4 0C01 orb \$1,%eax
+.*Warning:.*
+ 83 00a6 80CB01 orb \$1,%bx
+.*Warning:.*
+ 84 00a9 80CB01 orb \$1,%ebx
+.*Warning:.*
+ 85 00ac D9C1 fldl %st\(1\)
+.*Warning:.*
+ 86 00ae DDD2 fstl %st\(2\)
+.*Warning:.*
+ 87 00b0 DDDB fstpl %st\(3\)
+.*Warning:.*
+ 88 00b2 D8D4 fcoml %st\(4\)
+.*Warning:.*
+ 89 00b4 D8DD fcompl %st\(5\)
+.*Warning:.*
+ 90 00b6 DEC1 faddp %st\(1\),%st
+.*Warning:.*
+ 91 00b8 DECA fmulp %st\(2\),%st
+.*Warning:.*
+ 92 00ba DEE3 fsubp %st\(3\),%st
+.*Warning:.*
+ 93 00bc DEEC fsubrp %st\(4\),%st
+.*Warning:.*
+ 94 00be DEF5 fdivp %st\(5\),%st
+.*Warning:.*
+ 95 00c0 DEFE fdivrp %st\(6\),%st
+.*Warning:.*
+ 96 00c2 DEC1 fadd
+.*Warning:.*
+ 97 00c4 DEE1 fsub
+.*Warning:.*
+ 98 00c6 DEC9 fmul
+.*Warning:.*
+ 99 00c8 DEF1 fdiv
+.*Warning:.*
+ 100 00ca DEE9 fsubr
+.*Warning:.*
+ 101 00cc DEF9 fdivr
+.*Warning:.*
+ 102 #these should all be legal
+ 103 00ce 0FA31556 341200 btl %edx, 0x123456
+ 104 00d5 0FA3D0 btl %edx, %eax
+ 105 00d8 0C01 orb \$1,%al
+ 106 00da 80CB01 orb \$1,%bl
+ 107 00dd A1110000 00 movl 17,%eax
+ 108 00e2 A1110000 00 mov 17,%eax
+ 109 00e7 66ED inw %dx,%ax
+ 110 00e9 ED inl %dx,%eax
+ 111 00ea 66ED inw \(%dx\),%ax
+ 112 00ec ED inl \(%dx\),%eax
+ 113 00ed EC in \(%dx\),%al
+ 114 00ee 66ED in \(%dx\),%ax
+ 115 00f0 ED in \(%dx\),%eax
+ 116 00f1 0FB61437 movzbl \(%edi,%esi\),%edx
+ 117 00f5 0FB6451C movzbl 28\(%ebp\),%eax
+ 118 00f9 0FB6C0 movzbl %al,%eax
+ 119 00fc 0FB6F1 movzbl %cl,%esi
+ 120 00ff 26D7 xlat %es:\(%ebx\)
+ 121 0101 D7 xlat
+ 122 0102 D7 xlatb
+ 123 0103 DDD8 1: fstp %st\(0\)
+ 124 0105 E2FC loop 1b
+ 125 0107 F6F1 divb %cl
+ 126 0109 66F7F1 divw %cx
+ 127 010c F7F1 divl %ecx
+ 128 010e F6F1 div %cl
+ 129 0110 66F7F1 div %cx
+ 130 0113 F7F1 div %ecx
+ 131 0115 F6F1 div %cl,%al
+ 132 0117 66F7F1 div %cx,%ax
+ 133 011a F7F1 div %ecx,%eax
+ 134 011c 8EDE mov %si,%ds
+ 135 011e 8EDE movl %si,%ds # warning here
+.*Warning:.*
+ 136 0120 1E pushl %ds
+ 137 0121 1E push %ds
+ 138 0122 A0000000 00 mov 0,%al
+ 139 0127 66A10000 0100 mov 0x10000,%ax
+ 140 012d 89C3 mov %eax,%ebx
+ 141 012f 9C pushf
+ 142 0130 9C pushfl
+ 143 0131 669C pushfw
+ 144 0133 9D popf
+ 145 0134 9D popfl
+ 146 0135 669D popfw
+ 147 0137 89341D00 000000 mov %esi,\(,%ebx,1\)
+ 148 013e 80250000 00007F andb \$~0x80,foo
+ 149
+ 150 # Force a good alignment.
+ 151 0145 0000 .word 0
+ 152 0147 00 .byte 0
diff --git a/gas/testsuite/gas/i386/general.s b/gas/testsuite/gas/i386/general.s
new file mode 100644
index 00000000000..d73f489cfdc
--- /dev/null
+++ b/gas/testsuite/gas/i386/general.s
@@ -0,0 +1,152 @@
+.psize 0
+.text
+# test various segment reg insns
+ push %ds
+ pushl %ds
+ pop %ds
+ popl %ds
+ mov %ds,%eax
+ movl %ds,%eax
+ movl %ds,%ax
+ mov %eax,%ds
+ movl %ax,%ds
+ movl %eax,%ds
+
+ pushw %ds
+ popw %ds
+ mov %ds,%ax
+ movw %ds,%ax
+ movw %ds,%eax
+ mov %ax,%ds
+ movw %ax,%ds
+ movw %eax,%ds
+
+# test various pushes
+ pushl $10
+ pushw $10
+ push $10
+ pushl $1000
+ pushw $1000
+ push $1000
+ pushl 1f
+ pushw 1f
+ push 1f
+ push (1f-.)(%ebx)
+ push 1f-.
+# these, and others like them should have no operand size prefix
+1: lldt %cx
+ lmsw %ax
+
+# Just to make sure these don't become illegal due to over-enthusiastic
+# register checking
+ movsbw %al,%di
+ movsbl %al,%ecx
+ movswl %ax,%ecx
+ movzbw %al,%di
+ movzbl %al,%ecx
+ movzwl %ax,%ecx
+
+ in %dx,%al
+ in %dx,%ax
+ in %dx,%eax
+ in (%dx),%al
+ in (%dx),%ax
+ in (%dx),%eax
+ inb %dx,%al
+ inw %dx,%ax
+ inl %dx,%eax
+ inb %dx
+ inw %dx
+ inl %dx
+ inb $255
+ inw $2
+ inl $4
+ outl %eax,%dx
+ out %al, $42
+ in $13, %ax
+# These are used in AIX.
+ inw (%dx)
+ outw (%dx)
+
+ movsb
+ cmpsw
+ scasl
+ xlatb
+ movsl %cs:(%esi),%es:(%edi)
+ setae (%ebx)
+ setaeb (%ebx)
+ setae %al
+
+#these should give warnings
+ orb $1,%ax
+ orb $1,%eax
+ orb $1,%bx
+ orb $1,%ebx
+ fldl %st(1)
+ fstl %st(2)
+ fstpl %st(3)
+ fcoml %st(4)
+ fcompl %st(5)
+ faddp %st(1),%st
+ fmulp %st(2),%st
+ fsubp %st(3),%st
+ fsubrp %st(4),%st
+ fdivp %st(5),%st
+ fdivrp %st(6),%st
+ fadd
+ fsub
+ fmul
+ fdiv
+ fsubr
+ fdivr
+#these should all be legal
+ btl %edx, 0x123456
+ btl %edx, %eax
+ orb $1,%al
+ orb $1,%bl
+ movl 17,%eax
+ mov 17,%eax
+ inw %dx,%ax
+ inl %dx,%eax
+ inw (%dx),%ax
+ inl (%dx),%eax
+ in (%dx),%al
+ in (%dx),%ax
+ in (%dx),%eax
+ movzbl (%edi,%esi),%edx
+ movzbl 28(%ebp),%eax
+ movzbl %al,%eax
+ movzbl %cl,%esi
+ xlat %es:(%ebx)
+ xlat
+ xlatb
+1: fstp %st(0)
+ loop 1b
+ divb %cl
+ divw %cx
+ divl %ecx
+ div %cl
+ div %cx
+ div %ecx
+ div %cl,%al
+ div %cx,%ax
+ div %ecx,%eax
+ mov %si,%ds
+ movl %si,%ds # warning here
+ pushl %ds
+ push %ds
+ mov 0,%al
+ mov 0x10000,%ax
+ mov %eax,%ebx
+ pushf
+ pushfl
+ pushfw
+ popf
+ popfl
+ popfw
+ mov %esi,(,%ebx,1)
+ andb $~0x80,foo
+
+ # Force a good alignment.
+ .word 0
+ .byte 0
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
new file mode 100644
index 00000000000..cef1ff7ac0a
--- /dev/null
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -0,0 +1,34 @@
+#
+# i386 tests
+#
+proc run_list_test { name opts } {
+ global srcdir subdir
+ set testname "i386 $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s $opts ">&dump.out"
+ if { [regexp_diff "dump.out" "${file}.l"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+}
+
+
+if [istarget "i*86-*-*"] then {
+
+ run_list_test "float" "-al"
+ run_list_test "general" "-al --listing-lhs-width=2"
+ run_list_test "inval" "-al"
+ run_list_test "modrm" "-al --listing-lhs-width=2"
+ run_dump_test "opcode"
+ run_dump_test "prefix"
+ run_dump_test "amd"
+
+ # The reloc and white tests require support for 8 and 16 bit
+ # relocs, so we only run them for ELF targets.
+ if {[istarget "*-*-elf*"] || [istarget "*-*-linux*"]} then {
+ run_dump_test "reloc"
+ run_list_test "white" "-al --listing-lhs-width=3"
+ }
+}
diff --git a/gas/testsuite/gas/i386/inval.l b/gas/testsuite/gas/i386/inval.l
new file mode 100644
index 00000000000..e7894991853
--- /dev/null
+++ b/gas/testsuite/gas/i386/inval.l
@@ -0,0 +1,98 @@
+.*: Assembler messages:
+.*:3: Error: .*
+.*:4: Error: .*
+.*:5: Error: .*
+.*:6: Error: .*
+.*:7: Error: .*
+.*:8: Error: .*
+.*:9: Error: .*
+.*:10: Error: .*
+.*:11: Error: .*
+.*:12: Error: .*
+.*:13: Error: .*
+.*:14: Error: .*
+.*:15: Error: .*
+.*:16: Error: .*
+.*:17: Error: .*
+.*:18: Error: .*
+.*:19: Error: .*
+.*:20: Error: .*
+.*:21: Error: .*
+.*:22: Error: .*
+.*:23: Error: .*
+.*:24: Error: .*
+.*:25: Error: .*
+.*:26: Error: .*
+.*:27: Error: .*
+.*:28: Error: .*
+.*:29: Error: .*
+.*:30: Error: .*
+.*:31: Error: .*
+.*:32: Error: .*
+.*:33: Error: .*
+.*:34: Error: .*
+.*:35: Error: .*
+.*:36: Error: .*
+.*:37: Error: .*
+.*:38: Error: .*
+.*:39: Error: .*
+.*:40: Error: .*
+.*:41: Error: .*
+.*:42: Error: .*
+.*:43: Error: .*
+.*:44: Error: .*
+.*:45: Error: .*
+.*:46: Error: .*
+.*:47: Error: .*
+.*:48: Error: .*
+GAS LISTING .*
+
+
+ 1 [ ]* .text
+ 2 [ ]*# All the following should be illegal
+ 3 [ ]* mov \(%dx\),%al
+ 4 [ ]* mov \(%eax,%esp,2\),%al
+ 5 [ ]* setae %eax
+ 6 [ ]* pushb %ds
+ 7 [ ]* popb %ds
+ 8 [ ]* pushb %al
+ 9 [ ]* popb %al
+ 10 [ ]* pushb %ah
+ 11 [ ]* popb %ah
+ 12 [ ]* pushb %ax
+ 13 [ ]* popb %ax
+ 14 [ ]* pushb %eax
+ 15 [ ]* popb %eax
+ 16 [ ]* movb %ds,%ax
+ 17 [ ]* movb %ds,%eax
+ 18 [ ]* movb %ax,%ds
+ 19 [ ]* movb %eax,%ds
+ 20 [ ]* movdb %eax,%mm0
+ 21 [ ]* movqb 0,%mm0
+ 22 [ ]* ldsb 0,%eax
+ 23 [ ]* setnew 0
+ 24 [ ]* movdw %eax,%mm0
+ 25 [ ]* movqw 0,%mm0
+ 26 [ ]* div %cx,%al
+ 27 [ ]* div %cl,%ax
+ 28 [ ]* div %ecx,%al
+ 29 [ ]* imul 10,%bx,%ecx
+ 30 [ ]* imul 10,%bx,%al
+ 31 [ ]* popab
+ 32 [ ]* stil
+ 33 [ ]* aaab
+ 34 [ ]* cwdel
+ 35 [ ]* cwdw
+ 36 [ ]* callww 0
+ 37 [ ]*foo: jaw foo
+ 38 [ ]* jcxzw foo
+ 39 [ ]* jecxzl foo
+ 40 [ ]* loopb foo
+ 41 [ ]* xlatw %es:%bx
+ 42 [ ]* xlatl %es:%bx
+ 43 [ ]* intl 2
+ 44 [ ]* int3b
+ 45 [ ]* hltb
+ 46 [ ]* fstb %st\(0\)
+ 47 [ ]* fcompll 28\(%ebp\)
+ 48 [ ]* fldlw \(%eax\)
diff --git a/gas/testsuite/gas/i386/inval.s b/gas/testsuite/gas/i386/inval.s
new file mode 100644
index 00000000000..e37a18eac60
--- /dev/null
+++ b/gas/testsuite/gas/i386/inval.s
@@ -0,0 +1,48 @@
+ .text
+# All the following should be illegal
+ mov (%dx),%al
+ mov (%eax,%esp,2),%al
+ setae %eax
+ pushb %ds
+ popb %ds
+ pushb %al
+ popb %al
+ pushb %ah
+ popb %ah
+ pushb %ax
+ popb %ax
+ pushb %eax
+ popb %eax
+ movb %ds,%ax
+ movb %ds,%eax
+ movb %ax,%ds
+ movb %eax,%ds
+ movdb %eax,%mm0
+ movqb 0,%mm0
+ ldsb 0,%eax
+ setnew 0
+ movdw %eax,%mm0
+ movqw 0,%mm0
+ div %cx,%al
+ div %cl,%ax
+ div %ecx,%al
+ imul 10,%bx,%ecx
+ imul 10,%bx,%al
+ popab
+ stil
+ aaab
+ cwdel
+ cwdw
+ callww 0
+foo: jaw foo
+ jcxzw foo
+ jecxzl foo
+ loopb foo
+ xlatw %es:%bx
+ xlatl %es:%bx
+ intl 2
+ int3b
+ hltb
+ fstb %st(0)
+ fcompll 28(%ebp)
+ fldlw (%eax)
diff --git a/gas/testsuite/gas/i386/modrm.l b/gas/testsuite/gas/i386/modrm.l
new file mode 100644
index 00000000000..8a1bc7912f3
--- /dev/null
+++ b/gas/testsuite/gas/i386/modrm.l
@@ -0,0 +1,1984 @@
+.*: Assembler messages:
+.*:128: Warning:.*
+.*:129: Warning:.*
+.*:130: Warning:.*
+.*:131: Warning:.*
+.*:132: Warning:.*
+.*:133: Warning:.*
+.*:134: Warning:.*
+.*:135: Warning:.*
+.*:192: Warning:.*
+.*:193: Warning:.*
+.*:194: Warning:.*
+.*:195: Warning:.*
+.*:196: Warning:.*
+.*:197: Warning:.*
+.*:198: Warning:.*
+.*:199: Warning:.*
+.*:256: Warning:.*
+.*:257: Warning:.*
+.*:258: Warning:.*
+.*:259: Warning:.*
+.*:260: Warning:.*
+.*:261: Warning:.*
+.*:262: Warning:.*
+.*:263: Warning:.*
+.*:384: Warning:.*
+.*:385: Warning:.*
+.*:386: Warning:.*
+.*:387: Warning:.*
+.*:388: Warning:.*
+.*:389: Warning:.*
+.*:390: Warning:.*
+.*:391: Warning:.*
+.*:448: Warning:.*
+.*:449: Warning:.*
+.*:450: Warning:.*
+.*:451: Warning:.*
+.*:452: Warning:.*
+.*:453: Warning:.*
+.*:454: Warning:.*
+.*:455: Warning:.*
+.*:512: Warning:.*
+.*:513: Warning:.*
+.*:514: Warning:.*
+.*:515: Warning:.*
+.*:516: Warning:.*
+.*:517: Warning:.*
+.*:518: Warning:.*
+.*:519: Warning:.*
+.*:640: Warning:.*
+.*:641: Warning:.*
+.*:642: Warning:.*
+.*:643: Warning:.*
+.*:644: Warning:.*
+.*:645: Warning:.*
+.*:646: Warning:.*
+.*:647: Warning:.*
+.*:704: Warning:.*
+.*:705: Warning:.*
+.*:706: Warning:.*
+.*:707: Warning:.*
+.*:708: Warning:.*
+.*:709: Warning:.*
+.*:710: Warning:.*
+.*:711: Warning:.*
+.*:768: Warning:.*
+.*:769: Warning:.*
+.*:770: Warning:.*
+.*:771: Warning:.*
+.*:772: Warning:.*
+.*:773: Warning:.*
+.*:774: Warning:.*
+.*:775: Warning:.*
+.*:812: Warning:.*
+.*:820: Warning:.*
+.*:828: Warning:.*
+.*:833: Warning:.*
+.*:834: Warning:.*
+.*:835: Warning:.*
+.*:961: Warning:.*
+.*:962: Warning:.*
+.*:963: Warning:.*
+.*:964: Warning:.*
+.*:965: Warning:.*
+.*:966: Warning:.*
+.*:967: Warning:.*
+.*:968: Warning:.*
+.*:1025: Warning:.*
+.*:1026: Warning:.*
+.*:1027: Warning:.*
+.*:1028: Warning:.*
+.*:1029: Warning:.*
+.*:1030: Warning:.*
+.*:1031: Warning:.*
+.*:1032: Warning:.*
+.*:1089: Warning:.*
+.*:1090: Warning:.*
+.*:1091: Warning:.*
+.*:1092: Warning:.*
+.*:1093: Warning:.*
+.*:1094: Warning:.*
+.*:1095: Warning:.*
+.*:1096: Warning:.*
+.*:1217: Warning:.*
+.*:1218: Warning:.*
+.*:1219: Warning:.*
+.*:1220: Warning:.*
+.*:1221: Warning:.*
+.*:1222: Warning:.*
+.*:1223: Warning:.*
+.*:1224: Warning:.*
+.*:1281: Warning:.*
+.*:1282: Warning:.*
+.*:1283: Warning:.*
+.*:1284: Warning:.*
+.*:1285: Warning:.*
+.*:1286: Warning:.*
+.*:1287: Warning:.*
+.*:1288: Warning:.*
+.*:1345: Warning:.*
+.*:1346: Warning:.*
+.*:1347: Warning:.*
+.*:1348: Warning:.*
+.*:1349: Warning:.*
+.*:1350: Warning:.*
+.*:1351: Warning:.*
+.*:1352: Warning:.*
+.*:1473: Warning:.*
+.*:1474: Warning:.*
+.*:1475: Warning:.*
+.*:1476: Warning:.*
+.*:1477: Warning:.*
+.*:1478: Warning:.*
+.*:1479: Warning:.*
+.*:1480: Warning:.*
+.*:1537: Warning:.*
+.*:1538: Warning:.*
+.*:1539: Warning:.*
+.*:1540: Warning:.*
+.*:1541: Warning:.*
+.*:1542: Warning:.*
+.*:1543: Warning:.*
+.*:1544: Warning:.*
+.*:1601: Warning:.*
+.*:1602: Warning:.*
+.*:1603: Warning:.*
+.*:1604: Warning:.*
+.*:1605: Warning:.*
+.*:1606: Warning:.*
+.*:1607: Warning:.*
+.*:1608: Warning:.*
+.*:1645: Warning:.*
+.*:1653: Warning:.*
+.*:1661: Warning:.*
+.*:1666: Warning:.*
+.*:1667: Warning:.*
+.*:1668: Warning:.*
+ 1 .psize 0
+ 2 .text
+ 3 0000 368C18 mov %ds,%ss:\(%eax\)
+ 4 0003 368C19 mov %ds,%ss:\(%ecx\)
+ 5 0006 368C1A mov %ds,%ss:\(%edx\)
+ 6 0009 368C1B mov %ds,%ss:\(%ebx\)
+ 7 000c 368C1D00 000000 mov %ds,%ss:0
+ 8 0013 368C1E mov %ds,%ss:\(%esi\)
+ 9 0016 368C1F mov %ds,%ss:\(%edi\)
+ 10 0019 368C5812 mov %ds,%ss:0x12\(%eax\)
+ 11 001d 368C5912 mov %ds,%ss:0x12\(%ecx\)
+ 12 0021 368C5A12 mov %ds,%ss:0x12\(%edx\)
+ 13 0025 368C5B12 mov %ds,%ss:0x12\(%ebx\)
+ 14 0029 8C5D12 mov %ds,%ss:0x12\(%ebp\)
+ 15 002c 368C5E12 mov %ds,%ss:0x12\(%esi\)
+ 16 0030 368C5F12 mov %ds,%ss:0x12\(%edi\)
+ 17 0034 368C9878 563412 mov %ds,%ss:0x12345678\(%eax\)
+ 18 003b 368C9978 563412 mov %ds,%ss:0x12345678\(%ecx\)
+ 19 0042 368C9A78 563412 mov %ds,%ss:0x12345678\(%edx\)
+ 20 0049 368C9B78 563412 mov %ds,%ss:0x12345678\(%ebx\)
+ 21 0050 8C9D7856 3412 mov %ds,%ss:0x12345678\(%ebp\)
+ 22 0056 368C9E78 563412 mov %ds,%ss:0x12345678\(%esi\)
+ 23 005d 368C9F78 563412 mov %ds,%ss:0x12345678\(%edi\)
+ 24 0064 8CD8 mov %ds,%eax
+ 25 0066 8CD9 mov %ds,%ecx
+ 26 0068 8CDA mov %ds,%edx
+ 27 006a 8CDB mov %ds,%ebx
+ 28 006c 8CDC mov %ds,%esp
+ 29 006e 8CDD mov %ds,%ebp
+ 30 0070 8CDE mov %ds,%esi
+ 31 0072 8CDF mov %ds,%edi
+ 32 0074 368C1C00 mov %ds,%ss:\(%eax,%eax,1\)
+ 33 0078 368C1C01 mov %ds,%ss:\(%ecx,%eax,1\)
+ 34 007c 368C1C02 mov %ds,%ss:\(%edx,%eax,1\)
+ 35 0080 368C1C03 mov %ds,%ss:\(%ebx,%eax,1\)
+ 36 0084 8C1C04 mov %ds,%ss:\(%esp,%eax,1\)
+ 37 0087 368C1C05 00000000 mov %ds,%ss:\(,%eax,1\)
+ 38 008f 368C1C06 mov %ds,%ss:\(%esi,%eax,1\)
+ 39 0093 368C1C07 mov %ds,%ss:\(%edi,%eax,1\)
+ 40 0097 368C1C08 mov %ds,%ss:\(%eax,%ecx,1\)
+ 41 009b 368C1C09 mov %ds,%ss:\(%ecx,%ecx,1\)
+ 42 009f 368C1C0A mov %ds,%ss:\(%edx,%ecx,1\)
+ 43 00a3 368C1C0B mov %ds,%ss:\(%ebx,%ecx,1\)
+ 44 00a7 8C1C0C mov %ds,%ss:\(%esp,%ecx,1\)
+ 45 00aa 368C1C0D 00000000 mov %ds,%ss:\(,%ecx,1\)
+ 46 00b2 368C1C0E mov %ds,%ss:\(%esi,%ecx,1\)
+ 47 00b6 368C1C0F mov %ds,%ss:\(%edi,%ecx,1\)
+ 48 00ba 368C1C10 mov %ds,%ss:\(%eax,%edx,1\)
+ 49 00be 368C1C11 mov %ds,%ss:\(%ecx,%edx,1\)
+ 50 00c2 368C1C12 mov %ds,%ss:\(%edx,%edx,1\)
+ 51 00c6 368C1C13 mov %ds,%ss:\(%ebx,%edx,1\)
+ 52 00ca 8C1C14 mov %ds,%ss:\(%esp,%edx,1\)
+ 53 00cd 368C1C15 00000000 mov %ds,%ss:\(,%edx,1\)
+ 54 00d5 368C1C16 mov %ds,%ss:\(%esi,%edx,1\)
+ 55 00d9 368C1C17 mov %ds,%ss:\(%edi,%edx,1\)
+ 56 00dd 368C1C18 mov %ds,%ss:\(%eax,%ebx,1\)
+ 57 00e1 368C1C19 mov %ds,%ss:\(%ecx,%ebx,1\)
+ 58 00e5 368C1C1A mov %ds,%ss:\(%edx,%ebx,1\)
+ 59 00e9 368C1C1B mov %ds,%ss:\(%ebx,%ebx,1\)
+ 60 00ed 8C1C1C mov %ds,%ss:\(%esp,%ebx,1\)
+ 61 00f0 368C1C1D 00000000 mov %ds,%ss:\(,%ebx,1\)
+ 62 00f8 368C1C1E mov %ds,%ss:\(%esi,%ebx,1\)
+ 63 00fc 368C1C1F mov %ds,%ss:\(%edi,%ebx,1\)
+ 64 0100 368C18 mov %ds,%ss:\(%eax,1\)
+ 65 0103 368C19 mov %ds,%ss:\(%ecx,1\)
+ 66 0106 368C1A mov %ds,%ss:\(%edx,1\)
+ 67 0109 368C1B mov %ds,%ss:\(%ebx,1\)
+ 68 010c 8C1C24 mov %ds,%ss:\(%esp,1\)
+ 69 010f 368C1D00 000000 mov %ds,%ss:\(,1\)
+ 70 0116 368C1E mov %ds,%ss:\(%esi,1\)
+ 71 0119 368C1F mov %ds,%ss:\(%edi,1\)
+ 72 011c 368C1C28 mov %ds,%ss:\(%eax,%ebp,1\)
+ 73 0120 368C1C29 mov %ds,%ss:\(%ecx,%ebp,1\)
+ 74 0124 368C1C2A mov %ds,%ss:\(%edx,%ebp,1\)
+ 75 0128 368C1C2B mov %ds,%ss:\(%ebx,%ebp,1\)
+ 76 012c 8C1C2C mov %ds,%ss:\(%esp,%ebp,1\)
+ 77 012f 368C1C2D 00000000 mov %ds,%ss:\(,%ebp,1\)
+ 78 0137 368C1C2E mov %ds,%ss:\(%esi,%ebp,1\)
+ 79 013b 368C1C2F mov %ds,%ss:\(%edi,%ebp,1\)
+ 80 013f 368C1C30 mov %ds,%ss:\(%eax,%esi,1\)
+ 81 0143 368C1C31 mov %ds,%ss:\(%ecx,%esi,1\)
+ 82 0147 368C1C32 mov %ds,%ss:\(%edx,%esi,1\)
+ 83 014b 368C1C33 mov %ds,%ss:\(%ebx,%esi,1\)
+ 84 014f 8C1C34 mov %ds,%ss:\(%esp,%esi,1\)
+ 85 0152 368C1C35 00000000 mov %ds,%ss:\(,%esi,1\)
+ 86 015a 368C1C36 mov %ds,%ss:\(%esi,%esi,1\)
+ 87 015e 368C1C37 mov %ds,%ss:\(%edi,%esi,1\)
+ 88 0162 368C1C38 mov %ds,%ss:\(%eax,%edi,1\)
+ 89 0166 368C1C39 mov %ds,%ss:\(%ecx,%edi,1\)
+ 90 016a 368C1C3A mov %ds,%ss:\(%edx,%edi,1\)
+ 91 016e 368C1C3B mov %ds,%ss:\(%ebx,%edi,1\)
+ 92 0172 8C1C3C mov %ds,%ss:\(%esp,%edi,1\)
+ 93 0175 368C1C3D 00000000 mov %ds,%ss:\(,%edi,1\)
+ 94 017d 368C1C3E mov %ds,%ss:\(%esi,%edi,1\)
+ 95 0181 368C1C3F mov %ds,%ss:\(%edi,%edi,1\)
+ 96 0185 368C1C40 mov %ds,%ss:\(%eax,%eax,2\)
+ 97 0189 368C1C41 mov %ds,%ss:\(%ecx,%eax,2\)
+ 98 018d 368C1C42 mov %ds,%ss:\(%edx,%eax,2\)
+ 99 0191 368C1C43 mov %ds,%ss:\(%ebx,%eax,2\)
+ 100 0195 8C1C44 mov %ds,%ss:\(%esp,%eax,2\)
+ 101 0198 368C1C45 00000000 mov %ds,%ss:\(,%eax,2\)
+ 102 01a0 368C1C46 mov %ds,%ss:\(%esi,%eax,2\)
+ 103 01a4 368C1C47 mov %ds,%ss:\(%edi,%eax,2\)
+ 104 01a8 368C1C48 mov %ds,%ss:\(%eax,%ecx,2\)
+ 105 01ac 368C1C49 mov %ds,%ss:\(%ecx,%ecx,2\)
+ 106 01b0 368C1C4A mov %ds,%ss:\(%edx,%ecx,2\)
+ 107 01b4 368C1C4B mov %ds,%ss:\(%ebx,%ecx,2\)
+ 108 01b8 8C1C4C mov %ds,%ss:\(%esp,%ecx,2\)
+ 109 01bb 368C1C4D 00000000 mov %ds,%ss:\(,%ecx,2\)
+ 110 01c3 368C1C4E mov %ds,%ss:\(%esi,%ecx,2\)
+ 111 01c7 368C1C4F mov %ds,%ss:\(%edi,%ecx,2\)
+ 112 01cb 368C1C50 mov %ds,%ss:\(%eax,%edx,2\)
+ 113 01cf 368C1C51 mov %ds,%ss:\(%ecx,%edx,2\)
+ 114 01d3 368C1C52 mov %ds,%ss:\(%edx,%edx,2\)
+ 115 01d7 368C1C53 mov %ds,%ss:\(%ebx,%edx,2\)
+ 116 01db 8C1C54 mov %ds,%ss:\(%esp,%edx,2\)
+ 117 01de 368C1C55 00000000 mov %ds,%ss:\(,%edx,2\)
+ 118 01e6 368C1C56 mov %ds,%ss:\(%esi,%edx,2\)
+ 119 01ea 368C1C57 mov %ds,%ss:\(%edi,%edx,2\)
+ 120 01ee 368C1C58 mov %ds,%ss:\(%eax,%ebx,2\)
+ 121 01f2 368C1C59 mov %ds,%ss:\(%ecx,%ebx,2\)
+ 122 01f6 368C1C5A mov %ds,%ss:\(%edx,%ebx,2\)
+ 123 01fa 368C1C5B mov %ds,%ss:\(%ebx,%ebx,2\)
+ 124 01fe 8C1C5C mov %ds,%ss:\(%esp,%ebx,2\)
+ 125 0201 368C1C5D 00000000 mov %ds,%ss:\(,%ebx,2\)
+ 126 0209 368C1C5E mov %ds,%ss:\(%esi,%ebx,2\)
+ 127 020d 368C1C5F mov %ds,%ss:\(%edi,%ebx,2\)
+ 128 0211 368C18 mov %ds,%ss:\(%eax,2\)
+.*Warning:.*
+ 129 0214 368C19 mov %ds,%ss:\(%ecx,2\)
+.*Warning:.*
+ 130 0217 368C1A mov %ds,%ss:\(%edx,2\)
+.*Warning:.*
+ 131 021a 368C1B mov %ds,%ss:\(%ebx,2\)
+.*Warning:.*
+ 132 021d 8C1C24 mov %ds,%ss:\(%esp,2\)
+.*Warning:.*
+ 133 0220 368C1D00 000000 mov %ds,%ss:\(,2\)
+.*Warning:.*
+ 134 0227 368C1E mov %ds,%ss:\(%esi,2\)
+.*Warning:.*
+ 135 022a 368C1F mov %ds,%ss:\(%edi,2\)
+.*Warning:.*
+ 136 022d 368C1C68 mov %ds,%ss:\(%eax,%ebp,2\)
+ 137 0231 368C1C69 mov %ds,%ss:\(%ecx,%ebp,2\)
+ 138 0235 368C1C6A mov %ds,%ss:\(%edx,%ebp,2\)
+ 139 0239 368C1C6B mov %ds,%ss:\(%ebx,%ebp,2\)
+ 140 023d 8C1C6C mov %ds,%ss:\(%esp,%ebp,2\)
+ 141 0240 368C1C6D 00000000 mov %ds,%ss:\(,%ebp,2\)
+ 142 0248 368C1C6E mov %ds,%ss:\(%esi,%ebp,2\)
+ 143 024c 368C1C6F mov %ds,%ss:\(%edi,%ebp,2\)
+ 144 0250 368C1C70 mov %ds,%ss:\(%eax,%esi,2\)
+ 145 0254 368C1C71 mov %ds,%ss:\(%ecx,%esi,2\)
+ 146 0258 368C1C72 mov %ds,%ss:\(%edx,%esi,2\)
+ 147 025c 368C1C73 mov %ds,%ss:\(%ebx,%esi,2\)
+ 148 0260 8C1C74 mov %ds,%ss:\(%esp,%esi,2\)
+ 149 0263 368C1C75 00000000 mov %ds,%ss:\(,%esi,2\)
+ 150 026b 368C1C76 mov %ds,%ss:\(%esi,%esi,2\)
+ 151 026f 368C1C77 mov %ds,%ss:\(%edi,%esi,2\)
+ 152 0273 368C1C78 mov %ds,%ss:\(%eax,%edi,2\)
+ 153 0277 368C1C79 mov %ds,%ss:\(%ecx,%edi,2\)
+ 154 027b 368C1C7A mov %ds,%ss:\(%edx,%edi,2\)
+ 155 027f 368C1C7B mov %ds,%ss:\(%ebx,%edi,2\)
+ 156 0283 8C1C7C mov %ds,%ss:\(%esp,%edi,2\)
+ 157 0286 368C1C7D 00000000 mov %ds,%ss:\(,%edi,2\)
+ 158 028e 368C1C7E mov %ds,%ss:\(%esi,%edi,2\)
+ 159 0292 368C1C7F mov %ds,%ss:\(%edi,%edi,2\)
+ 160 0296 368C1C80 mov %ds,%ss:\(%eax,%eax,4\)
+ 161 029a 368C1C81 mov %ds,%ss:\(%ecx,%eax,4\)
+ 162 029e 368C1C82 mov %ds,%ss:\(%edx,%eax,4\)
+ 163 02a2 368C1C83 mov %ds,%ss:\(%ebx,%eax,4\)
+ 164 02a6 8C1C84 mov %ds,%ss:\(%esp,%eax,4\)
+ 165 02a9 368C1C85 00000000 mov %ds,%ss:\(,%eax,4\)
+ 166 02b1 368C1C86 mov %ds,%ss:\(%esi,%eax,4\)
+ 167 02b5 368C1C87 mov %ds,%ss:\(%edi,%eax,4\)
+ 168 02b9 368C1C88 mov %ds,%ss:\(%eax,%ecx,4\)
+ 169 02bd 368C1C89 mov %ds,%ss:\(%ecx,%ecx,4\)
+ 170 02c1 368C1C8A mov %ds,%ss:\(%edx,%ecx,4\)
+ 171 02c5 368C1C8B mov %ds,%ss:\(%ebx,%ecx,4\)
+ 172 02c9 8C1C8C mov %ds,%ss:\(%esp,%ecx,4\)
+ 173 02cc 368C1C8D 00000000 mov %ds,%ss:\(,%ecx,4\)
+ 174 02d4 368C1C8E mov %ds,%ss:\(%esi,%ecx,4\)
+ 175 02d8 368C1C8F mov %ds,%ss:\(%edi,%ecx,4\)
+ 176 02dc 368C1C90 mov %ds,%ss:\(%eax,%edx,4\)
+ 177 02e0 368C1C91 mov %ds,%ss:\(%ecx,%edx,4\)
+ 178 02e4 368C1C92 mov %ds,%ss:\(%edx,%edx,4\)
+ 179 02e8 368C1C93 mov %ds,%ss:\(%ebx,%edx,4\)
+ 180 02ec 8C1C94 mov %ds,%ss:\(%esp,%edx,4\)
+ 181 02ef 368C1C95 00000000 mov %ds,%ss:\(,%edx,4\)
+ 182 02f7 368C1C96 mov %ds,%ss:\(%esi,%edx,4\)
+ 183 02fb 368C1C97 mov %ds,%ss:\(%edi,%edx,4\)
+ 184 02ff 368C1C98 mov %ds,%ss:\(%eax,%ebx,4\)
+ 185 0303 368C1C99 mov %ds,%ss:\(%ecx,%ebx,4\)
+ 186 0307 368C1C9A mov %ds,%ss:\(%edx,%ebx,4\)
+ 187 030b 368C1C9B mov %ds,%ss:\(%ebx,%ebx,4\)
+ 188 030f 8C1C9C mov %ds,%ss:\(%esp,%ebx,4\)
+ 189 0312 368C1C9D 00000000 mov %ds,%ss:\(,%ebx,4\)
+ 190 031a 368C1C9E mov %ds,%ss:\(%esi,%ebx,4\)
+ 191 031e 368C1C9F mov %ds,%ss:\(%edi,%ebx,4\)
+ 192 0322 368C18 mov %ds,%ss:\(%eax,4\)
+.*Warning:.*
+ 193 0325 368C19 mov %ds,%ss:\(%ecx,4\)
+.*Warning:.*
+ 194 0328 368C1A mov %ds,%ss:\(%edx,4\)
+.*Warning:.*
+ 195 032b 368C1B mov %ds,%ss:\(%ebx,4\)
+.*Warning:.*
+ 196 032e 8C1C24 mov %ds,%ss:\(%esp,4\)
+.*Warning:.*
+ 197 0331 368C1D00 000000 mov %ds,%ss:\(,4\)
+.*Warning:.*
+ 198 0338 368C1E mov %ds,%ss:\(%esi,4\)
+.*Warning:.*
+ 199 033b 368C1F mov %ds,%ss:\(%edi,4\)
+.*Warning:.*
+ 200 033e 368C1CA8 mov %ds,%ss:\(%eax,%ebp,4\)
+ 201 0342 368C1CA9 mov %ds,%ss:\(%ecx,%ebp,4\)
+ 202 0346 368C1CAA mov %ds,%ss:\(%edx,%ebp,4\)
+ 203 034a 368C1CAB mov %ds,%ss:\(%ebx,%ebp,4\)
+ 204 034e 8C1CAC mov %ds,%ss:\(%esp,%ebp,4\)
+ 205 0351 368C1CAD 00000000 mov %ds,%ss:\(,%ebp,4\)
+ 206 0359 368C1CAE mov %ds,%ss:\(%esi,%ebp,4\)
+ 207 035d 368C1CAF mov %ds,%ss:\(%edi,%ebp,4\)
+ 208 0361 368C1CB0 mov %ds,%ss:\(%eax,%esi,4\)
+ 209 0365 368C1CB1 mov %ds,%ss:\(%ecx,%esi,4\)
+ 210 0369 368C1CB2 mov %ds,%ss:\(%edx,%esi,4\)
+ 211 036d 368C1CB3 mov %ds,%ss:\(%ebx,%esi,4\)
+ 212 0371 8C1CB4 mov %ds,%ss:\(%esp,%esi,4\)
+ 213 0374 368C1CB5 00000000 mov %ds,%ss:\(,%esi,4\)
+ 214 037c 368C1CB6 mov %ds,%ss:\(%esi,%esi,4\)
+ 215 0380 368C1CB7 mov %ds,%ss:\(%edi,%esi,4\)
+ 216 0384 368C1CB8 mov %ds,%ss:\(%eax,%edi,4\)
+ 217 0388 368C1CB9 mov %ds,%ss:\(%ecx,%edi,4\)
+ 218 038c 368C1CBA mov %ds,%ss:\(%edx,%edi,4\)
+ 219 0390 368C1CBB mov %ds,%ss:\(%ebx,%edi,4\)
+ 220 0394 8C1CBC mov %ds,%ss:\(%esp,%edi,4\)
+ 221 0397 368C1CBD 00000000 mov %ds,%ss:\(,%edi,4\)
+ 222 039f 368C1CBE mov %ds,%ss:\(%esi,%edi,4\)
+ 223 03a3 368C1CBF mov %ds,%ss:\(%edi,%edi,4\)
+ 224 03a7 368C1CC0 mov %ds,%ss:\(%eax,%eax,8\)
+ 225 03ab 368C1CC1 mov %ds,%ss:\(%ecx,%eax,8\)
+ 226 03af 368C1CC2 mov %ds,%ss:\(%edx,%eax,8\)
+ 227 03b3 368C1CC3 mov %ds,%ss:\(%ebx,%eax,8\)
+ 228 03b7 8C1CC4 mov %ds,%ss:\(%esp,%eax,8\)
+ 229 03ba 368C1CC5 00000000 mov %ds,%ss:\(,%eax,8\)
+ 230 03c2 368C1CC6 mov %ds,%ss:\(%esi,%eax,8\)
+ 231 03c6 368C1CC7 mov %ds,%ss:\(%edi,%eax,8\)
+ 232 03ca 368C1CC8 mov %ds,%ss:\(%eax,%ecx,8\)
+ 233 03ce 368C1CC9 mov %ds,%ss:\(%ecx,%ecx,8\)
+ 234 03d2 368C1CCA mov %ds,%ss:\(%edx,%ecx,8\)
+ 235 03d6 368C1CCB mov %ds,%ss:\(%ebx,%ecx,8\)
+ 236 03da 8C1CCC mov %ds,%ss:\(%esp,%ecx,8\)
+ 237 03dd 368C1CCD 00000000 mov %ds,%ss:\(,%ecx,8\)
+ 238 03e5 368C1CCE mov %ds,%ss:\(%esi,%ecx,8\)
+ 239 03e9 368C1CCF mov %ds,%ss:\(%edi,%ecx,8\)
+ 240 03ed 368C1CD0 mov %ds,%ss:\(%eax,%edx,8\)
+ 241 03f1 368C1CD1 mov %ds,%ss:\(%ecx,%edx,8\)
+ 242 03f5 368C1CD2 mov %ds,%ss:\(%edx,%edx,8\)
+ 243 03f9 368C1CD3 mov %ds,%ss:\(%ebx,%edx,8\)
+ 244 03fd 8C1CD4 mov %ds,%ss:\(%esp,%edx,8\)
+ 245 0400 368C1CD5 00000000 mov %ds,%ss:\(,%edx,8\)
+ 246 0408 368C1CD6 mov %ds,%ss:\(%esi,%edx,8\)
+ 247 040c 368C1CD7 mov %ds,%ss:\(%edi,%edx,8\)
+ 248 0410 368C1CD8 mov %ds,%ss:\(%eax,%ebx,8\)
+ 249 0414 368C1CD9 mov %ds,%ss:\(%ecx,%ebx,8\)
+ 250 0418 368C1CDA mov %ds,%ss:\(%edx,%ebx,8\)
+ 251 041c 368C1CDB mov %ds,%ss:\(%ebx,%ebx,8\)
+ 252 0420 8C1CDC mov %ds,%ss:\(%esp,%ebx,8\)
+ 253 0423 368C1CDD 00000000 mov %ds,%ss:\(,%ebx,8\)
+ 254 042b 368C1CDE mov %ds,%ss:\(%esi,%ebx,8\)
+ 255 042f 368C1CDF mov %ds,%ss:\(%edi,%ebx,8\)
+ 256 0433 368C18 mov %ds,%ss:\(%eax,8\)
+.*Warning:.*
+ 257 0436 368C19 mov %ds,%ss:\(%ecx,8\)
+.*Warning:.*
+ 258 0439 368C1A mov %ds,%ss:\(%edx,8\)
+.*Warning:.*
+ 259 043c 368C1B mov %ds,%ss:\(%ebx,8\)
+.*Warning:.*
+ 260 043f 8C1C24 mov %ds,%ss:\(%esp,8\)
+.*Warning:.*
+ 261 0442 368C1D00 000000 mov %ds,%ss:\(,8\)
+.*Warning:.*
+ 262 0449 368C1E mov %ds,%ss:\(%esi,8\)
+.*Warning:.*
+ 263 044c 368C1F mov %ds,%ss:\(%edi,8\)
+.*Warning:.*
+ 264 044f 368C1CE8 mov %ds,%ss:\(%eax,%ebp,8\)
+ 265 0453 368C1CE9 mov %ds,%ss:\(%ecx,%ebp,8\)
+ 266 0457 368C1CEA mov %ds,%ss:\(%edx,%ebp,8\)
+ 267 045b 368C1CEB mov %ds,%ss:\(%ebx,%ebp,8\)
+ 268 045f 8C1CEC mov %ds,%ss:\(%esp,%ebp,8\)
+ 269 0462 368C1CED 00000000 mov %ds,%ss:\(,%ebp,8\)
+ 270 046a 368C1CEE mov %ds,%ss:\(%esi,%ebp,8\)
+ 271 046e 368C1CEF mov %ds,%ss:\(%edi,%ebp,8\)
+ 272 0472 368C1CF0 mov %ds,%ss:\(%eax,%esi,8\)
+ 273 0476 368C1CF1 mov %ds,%ss:\(%ecx,%esi,8\)
+ 274 047a 368C1CF2 mov %ds,%ss:\(%edx,%esi,8\)
+ 275 047e 368C1CF3 mov %ds,%ss:\(%ebx,%esi,8\)
+ 276 0482 8C1CF4 mov %ds,%ss:\(%esp,%esi,8\)
+ 277 0485 368C1CF5 00000000 mov %ds,%ss:\(,%esi,8\)
+ 278 048d 368C1CF6 mov %ds,%ss:\(%esi,%esi,8\)
+ 279 0491 368C1CF7 mov %ds,%ss:\(%edi,%esi,8\)
+ 280 0495 368C1CF8 mov %ds,%ss:\(%eax,%edi,8\)
+ 281 0499 368C1CFA mov %ds,%ss:\(%edx,%edi,8\)
+ 282 049d 368C1CF9 mov %ds,%ss:\(%ecx,%edi,8\)
+ 283 04a1 368C1CFB mov %ds,%ss:\(%ebx,%edi,8\)
+ 284 04a5 8C1CFC mov %ds,%ss:\(%esp,%edi,8\)
+ 285 04a8 368C1CFD 00000000 mov %ds,%ss:\(,%edi,8\)
+ 286 04b0 368C1CFE mov %ds,%ss:\(%esi,%edi,8\)
+ 287 04b4 368C1CFF mov %ds,%ss:\(%edi,%edi,8\)
+ 288 04b8 368C5C00 12 mov %ds,%ss:0x12\(%eax,%eax,1\)
+ 289 04bd 368C5C01 12 mov %ds,%ss:0x12\(%ecx,%eax,1\)
+ 290 04c2 368C5C02 12 mov %ds,%ss:0x12\(%edx,%eax,1\)
+ 291 04c7 368C5C03 12 mov %ds,%ss:0x12\(%ebx,%eax,1\)
+ 292 04cc 8C5C0412 mov %ds,%ss:0x12\(%esp,%eax,1\)
+ 293 04d0 8C5C0512 mov %ds,%ss:0x12\(%ebp,%eax,1\)
+ 294 04d4 368C5C06 12 mov %ds,%ss:0x12\(%esi,%eax,1\)
+ 295 04d9 368C5C07 12 mov %ds,%ss:0x12\(%edi,%eax,1\)
+ 296 04de 368C5C08 12 mov %ds,%ss:0x12\(%eax,%ecx,1\)
+ 297 04e3 368C5C09 12 mov %ds,%ss:0x12\(%ecx,%ecx,1\)
+ 298 04e8 368C5C0A 12 mov %ds,%ss:0x12\(%edx,%ecx,1\)
+ 299 04ed 368C5C0B 12 mov %ds,%ss:0x12\(%ebx,%ecx,1\)
+ 300 04f2 8C5C0C12 mov %ds,%ss:0x12\(%esp,%ecx,1\)
+ 301 04f6 8C5C0D12 mov %ds,%ss:0x12\(%ebp,%ecx,1\)
+ 302 04fa 368C5C0E 12 mov %ds,%ss:0x12\(%esi,%ecx,1\)
+ 303 04ff 368C5C0F 12 mov %ds,%ss:0x12\(%edi,%ecx,1\)
+ 304 0504 368C5C10 12 mov %ds,%ss:0x12\(%eax,%edx,1\)
+ 305 0509 368C5C11 12 mov %ds,%ss:0x12\(%ecx,%edx,1\)
+ 306 050e 368C5C12 12 mov %ds,%ss:0x12\(%edx,%edx,1\)
+ 307 0513 368C5C13 12 mov %ds,%ss:0x12\(%ebx,%edx,1\)
+ 308 0518 8C5C1412 mov %ds,%ss:0x12\(%esp,%edx,1\)
+ 309 051c 8C5C1512 mov %ds,%ss:0x12\(%ebp,%edx,1\)
+ 310 0520 368C5C16 12 mov %ds,%ss:0x12\(%esi,%edx,1\)
+ 311 0525 368C5C17 12 mov %ds,%ss:0x12\(%edi,%edx,1\)
+ 312 052a 368C5C18 12 mov %ds,%ss:0x12\(%eax,%ebx,1\)
+ 313 052f 368C5C19 12 mov %ds,%ss:0x12\(%ecx,%ebx,1\)
+ 314 0534 368C5C1A 12 mov %ds,%ss:0x12\(%edx,%ebx,1\)
+ 315 0539 368C5C1B 12 mov %ds,%ss:0x12\(%ebx,%ebx,1\)
+ 316 053e 8C5C1C12 mov %ds,%ss:0x12\(%esp,%ebx,1\)
+ 317 0542 8C5C1D12 mov %ds,%ss:0x12\(%ebp,%ebx,1\)
+ 318 0546 368C5C1E 12 mov %ds,%ss:0x12\(%esi,%ebx,1\)
+ 319 054b 368C5C1F 12 mov %ds,%ss:0x12\(%edi,%ebx,1\)
+ 320 0550 368C5812 mov %ds,%ss:0x12\(%eax,1\)
+ 321 0554 368C5912 mov %ds,%ss:0x12\(%ecx,1\)
+ 322 0558 368C5A12 mov %ds,%ss:0x12\(%edx,1\)
+ 323 055c 368C5B12 mov %ds,%ss:0x12\(%ebx,1\)
+ 324 0560 8C5C2412 mov %ds,%ss:0x12\(%esp,1\)
+ 325 0564 8C5D12 mov %ds,%ss:0x12\(%ebp,1\)
+ 326 0567 368C5E12 mov %ds,%ss:0x12\(%esi,1\)
+ 327 056b 368C5F12 mov %ds,%ss:0x12\(%edi,1\)
+ 328 056f 368C5C28 12 mov %ds,%ss:0x12\(%eax,%ebp,1\)
+ 329 0574 368C5C29 12 mov %ds,%ss:0x12\(%ecx,%ebp,1\)
+ 330 0579 368C5C2A 12 mov %ds,%ss:0x12\(%edx,%ebp,1\)
+ 331 057e 368C5C2B 12 mov %ds,%ss:0x12\(%ebx,%ebp,1\)
+ 332 0583 8C5C2C12 mov %ds,%ss:0x12\(%esp,%ebp,1\)
+ 333 0587 8C5C2D12 mov %ds,%ss:0x12\(%ebp,%ebp,1\)
+ 334 058b 368C5C2E 12 mov %ds,%ss:0x12\(%esi,%ebp,1\)
+ 335 0590 368C5C2F 12 mov %ds,%ss:0x12\(%edi,%ebp,1\)
+ 336 0595 368C5C30 12 mov %ds,%ss:0x12\(%eax,%esi,1\)
+ 337 059a 368C5C31 12 mov %ds,%ss:0x12\(%ecx,%esi,1\)
+ 338 059f 368C5C32 12 mov %ds,%ss:0x12\(%edx,%esi,1\)
+ 339 05a4 368C5C33 12 mov %ds,%ss:0x12\(%ebx,%esi,1\)
+ 340 05a9 8C5C3412 mov %ds,%ss:0x12\(%esp,%esi,1\)
+ 341 05ad 8C5C3512 mov %ds,%ss:0x12\(%ebp,%esi,1\)
+ 342 05b1 368C5C36 12 mov %ds,%ss:0x12\(%esi,%esi,1\)
+ 343 05b6 368C5C37 12 mov %ds,%ss:0x12\(%edi,%esi,1\)
+ 344 05bb 368C5C38 12 mov %ds,%ss:0x12\(%eax,%edi,1\)
+ 345 05c0 368C5C39 12 mov %ds,%ss:0x12\(%ecx,%edi,1\)
+ 346 05c5 368C5C3A 12 mov %ds,%ss:0x12\(%edx,%edi,1\)
+ 347 05ca 368C5C3B 12 mov %ds,%ss:0x12\(%ebx,%edi,1\)
+ 348 05cf 8C5C3C12 mov %ds,%ss:0x12\(%esp,%edi,1\)
+ 349 05d3 8C5C3D12 mov %ds,%ss:0x12\(%ebp,%edi,1\)
+ 350 05d7 368C5C3E 12 mov %ds,%ss:0x12\(%esi,%edi,1\)
+ 351 05dc 368C5C3F 12 mov %ds,%ss:0x12\(%edi,%edi,1\)
+ 352 05e1 368C5C40 12 mov %ds,%ss:0x12\(%eax,%eax,2\)
+ 353 05e6 368C5C41 12 mov %ds,%ss:0x12\(%ecx,%eax,2\)
+ 354 05eb 368C5C42 12 mov %ds,%ss:0x12\(%edx,%eax,2\)
+ 355 05f0 368C5C43 12 mov %ds,%ss:0x12\(%ebx,%eax,2\)
+ 356 05f5 8C5C4412 mov %ds,%ss:0x12\(%esp,%eax,2\)
+ 357 05f9 8C5C4512 mov %ds,%ss:0x12\(%ebp,%eax,2\)
+ 358 05fd 368C5C46 12 mov %ds,%ss:0x12\(%esi,%eax,2\)
+ 359 0602 368C5C47 12 mov %ds,%ss:0x12\(%edi,%eax,2\)
+ 360 0607 368C5C48 12 mov %ds,%ss:0x12\(%eax,%ecx,2\)
+ 361 060c 368C5C49 12 mov %ds,%ss:0x12\(%ecx,%ecx,2\)
+ 362 0611 368C5C4A 12 mov %ds,%ss:0x12\(%edx,%ecx,2\)
+ 363 0616 368C5C4B 12 mov %ds,%ss:0x12\(%ebx,%ecx,2\)
+ 364 061b 8C5C4C12 mov %ds,%ss:0x12\(%esp,%ecx,2\)
+ 365 061f 8C5C4D12 mov %ds,%ss:0x12\(%ebp,%ecx,2\)
+ 366 0623 368C5C4E 12 mov %ds,%ss:0x12\(%esi,%ecx,2\)
+ 367 0628 368C5C4F 12 mov %ds,%ss:0x12\(%edi,%ecx,2\)
+ 368 062d 368C5C50 12 mov %ds,%ss:0x12\(%eax,%edx,2\)
+ 369 0632 368C5C51 12 mov %ds,%ss:0x12\(%ecx,%edx,2\)
+ 370 0637 368C5C52 12 mov %ds,%ss:0x12\(%edx,%edx,2\)
+ 371 063c 368C5C53 12 mov %ds,%ss:0x12\(%ebx,%edx,2\)
+ 372 0641 8C5C5412 mov %ds,%ss:0x12\(%esp,%edx,2\)
+ 373 0645 8C5C5512 mov %ds,%ss:0x12\(%ebp,%edx,2\)
+ 374 0649 368C5C56 12 mov %ds,%ss:0x12\(%esi,%edx,2\)
+ 375 064e 368C5C57 12 mov %ds,%ss:0x12\(%edi,%edx,2\)
+ 376 0653 368C5C58 12 mov %ds,%ss:0x12\(%eax,%ebx,2\)
+ 377 0658 368C5C59 12 mov %ds,%ss:0x12\(%ecx,%ebx,2\)
+ 378 065d 368C5C5A 12 mov %ds,%ss:0x12\(%edx,%ebx,2\)
+ 379 0662 368C5C5B 12 mov %ds,%ss:0x12\(%ebx,%ebx,2\)
+ 380 0667 8C5C5C12 mov %ds,%ss:0x12\(%esp,%ebx,2\)
+ 381 066b 8C5C5D12 mov %ds,%ss:0x12\(%ebp,%ebx,2\)
+ 382 066f 368C5C5E 12 mov %ds,%ss:0x12\(%esi,%ebx,2\)
+ 383 0674 368C5C5F 12 mov %ds,%ss:0x12\(%edi,%ebx,2\)
+ 384 0679 368C5812 mov %ds,%ss:0x12\(%eax,2\)
+.*Warning:.*
+ 385 067d 368C5912 mov %ds,%ss:0x12\(%ecx,2\)
+.*Warning:.*
+ 386 0681 368C5A12 mov %ds,%ss:0x12\(%edx,2\)
+.*Warning:.*
+ 387 0685 368C5B12 mov %ds,%ss:0x12\(%ebx,2\)
+.*Warning:.*
+ 388 0689 8C5C2412 mov %ds,%ss:0x12\(%esp,2\)
+.*Warning:.*
+ 389 068d 8C5D12 mov %ds,%ss:0x12\(%ebp,2\)
+.*Warning:.*
+ 390 0690 368C5E12 mov %ds,%ss:0x12\(%esi,2\)
+.*Warning:.*
+ 391 0694 368C5F12 mov %ds,%ss:0x12\(%edi,2\)
+.*Warning:.*
+ 392 0698 368C5C68 12 mov %ds,%ss:0x12\(%eax,%ebp,2\)
+ 393 069d 368C5C69 12 mov %ds,%ss:0x12\(%ecx,%ebp,2\)
+ 394 06a2 368C5C6A 12 mov %ds,%ss:0x12\(%edx,%ebp,2\)
+ 395 06a7 368C5C6B 12 mov %ds,%ss:0x12\(%ebx,%ebp,2\)
+ 396 06ac 8C5C6C12 mov %ds,%ss:0x12\(%esp,%ebp,2\)
+ 397 06b0 8C5C6D12 mov %ds,%ss:0x12\(%ebp,%ebp,2\)
+ 398 06b4 368C5C6E 12 mov %ds,%ss:0x12\(%esi,%ebp,2\)
+ 399 06b9 368C5C6F 12 mov %ds,%ss:0x12\(%edi,%ebp,2\)
+ 400 06be 368C5C70 12 mov %ds,%ss:0x12\(%eax,%esi,2\)
+ 401 06c3 368C5C71 12 mov %ds,%ss:0x12\(%ecx,%esi,2\)
+ 402 06c8 368C5C72 12 mov %ds,%ss:0x12\(%edx,%esi,2\)
+ 403 06cd 368C5C73 12 mov %ds,%ss:0x12\(%ebx,%esi,2\)
+ 404 06d2 8C5C7412 mov %ds,%ss:0x12\(%esp,%esi,2\)
+ 405 06d6 8C5C7512 mov %ds,%ss:0x12\(%ebp,%esi,2\)
+ 406 06da 368C5C76 12 mov %ds,%ss:0x12\(%esi,%esi,2\)
+ 407 06df 368C5C77 12 mov %ds,%ss:0x12\(%edi,%esi,2\)
+ 408 06e4 368C5C78 12 mov %ds,%ss:0x12\(%eax,%edi,2\)
+ 409 06e9 368C5C79 12 mov %ds,%ss:0x12\(%ecx,%edi,2\)
+ 410 06ee 368C5C7A 12 mov %ds,%ss:0x12\(%edx,%edi,2\)
+ 411 06f3 368C5C7B 12 mov %ds,%ss:0x12\(%ebx,%edi,2\)
+ 412 06f8 8C5C7C12 mov %ds,%ss:0x12\(%esp,%edi,2\)
+ 413 06fc 8C5C7D12 mov %ds,%ss:0x12\(%ebp,%edi,2\)
+ 414 0700 368C5C7E 12 mov %ds,%ss:0x12\(%esi,%edi,2\)
+ 415 0705 368C5C7F 12 mov %ds,%ss:0x12\(%edi,%edi,2\)
+ 416 070a 368C5C80 12 mov %ds,%ss:0x12\(%eax,%eax,4\)
+ 417 070f 368C5C81 12 mov %ds,%ss:0x12\(%ecx,%eax,4\)
+ 418 0714 368C5C82 12 mov %ds,%ss:0x12\(%edx,%eax,4\)
+ 419 0719 368C5C83 12 mov %ds,%ss:0x12\(%ebx,%eax,4\)
+ 420 071e 8C5C8412 mov %ds,%ss:0x12\(%esp,%eax,4\)
+ 421 0722 8C5C8512 mov %ds,%ss:0x12\(%ebp,%eax,4\)
+ 422 0726 368C5C86 12 mov %ds,%ss:0x12\(%esi,%eax,4\)
+ 423 072b 368C5C87 12 mov %ds,%ss:0x12\(%edi,%eax,4\)
+ 424 0730 368C5C88 12 mov %ds,%ss:0x12\(%eax,%ecx,4\)
+ 425 0735 368C5C89 12 mov %ds,%ss:0x12\(%ecx,%ecx,4\)
+ 426 073a 368C5C8A 12 mov %ds,%ss:0x12\(%edx,%ecx,4\)
+ 427 073f 368C5C8B 12 mov %ds,%ss:0x12\(%ebx,%ecx,4\)
+ 428 0744 8C5C8C12 mov %ds,%ss:0x12\(%esp,%ecx,4\)
+ 429 0748 8C5C8D12 mov %ds,%ss:0x12\(%ebp,%ecx,4\)
+ 430 074c 368C5C8E 12 mov %ds,%ss:0x12\(%esi,%ecx,4\)
+ 431 0751 368C5C8F 12 mov %ds,%ss:0x12\(%edi,%ecx,4\)
+ 432 0756 368C5C90 12 mov %ds,%ss:0x12\(%eax,%edx,4\)
+ 433 075b 368C5C91 12 mov %ds,%ss:0x12\(%ecx,%edx,4\)
+ 434 0760 368C5C92 12 mov %ds,%ss:0x12\(%edx,%edx,4\)
+ 435 0765 368C5C93 12 mov %ds,%ss:0x12\(%ebx,%edx,4\)
+ 436 076a 8C5C9412 mov %ds,%ss:0x12\(%esp,%edx,4\)
+ 437 076e 8C5C9512 mov %ds,%ss:0x12\(%ebp,%edx,4\)
+ 438 0772 368C5C96 12 mov %ds,%ss:0x12\(%esi,%edx,4\)
+ 439 0777 368C5C97 12 mov %ds,%ss:0x12\(%edi,%edx,4\)
+ 440 077c 368C5C98 12 mov %ds,%ss:0x12\(%eax,%ebx,4\)
+ 441 0781 368C5C99 12 mov %ds,%ss:0x12\(%ecx,%ebx,4\)
+ 442 0786 368C5C9A 12 mov %ds,%ss:0x12\(%edx,%ebx,4\)
+ 443 078b 368C5C9B 12 mov %ds,%ss:0x12\(%ebx,%ebx,4\)
+ 444 0790 8C5C9C12 mov %ds,%ss:0x12\(%esp,%ebx,4\)
+ 445 0794 8C5C9D12 mov %ds,%ss:0x12\(%ebp,%ebx,4\)
+ 446 0798 368C5C9E 12 mov %ds,%ss:0x12\(%esi,%ebx,4\)
+ 447 079d 368C5C9F 12 mov %ds,%ss:0x12\(%edi,%ebx,4\)
+ 448 07a2 368C5812 mov %ds,%ss:0x12\(%eax,4\)
+.*Warning:.*
+ 449 07a6 368C5912 mov %ds,%ss:0x12\(%ecx,4\)
+.*Warning:.*
+ 450 07aa 368C5A12 mov %ds,%ss:0x12\(%edx,4\)
+.*Warning:.*
+ 451 07ae 368C5B12 mov %ds,%ss:0x12\(%ebx,4\)
+.*Warning:.*
+ 452 07b2 8C5C2412 mov %ds,%ss:0x12\(%esp,4\)
+.*Warning:.*
+ 453 07b6 8C5D12 mov %ds,%ss:0x12\(%ebp,4\)
+.*Warning:.*
+ 454 07b9 368C5E12 mov %ds,%ss:0x12\(%esi,4\)
+.*Warning:.*
+ 455 07bd 368C5F12 mov %ds,%ss:0x12\(%edi,4\)
+.*Warning:.*
+ 456 07c1 368C5CA8 12 mov %ds,%ss:0x12\(%eax,%ebp,4\)
+ 457 07c6 368C5CA9 12 mov %ds,%ss:0x12\(%ecx,%ebp,4\)
+ 458 07cb 368C5CAA 12 mov %ds,%ss:0x12\(%edx,%ebp,4\)
+ 459 07d0 368C5CAB 12 mov %ds,%ss:0x12\(%ebx,%ebp,4\)
+ 460 07d5 8C5CAC12 mov %ds,%ss:0x12\(%esp,%ebp,4\)
+ 461 07d9 8C5CAD12 mov %ds,%ss:0x12\(%ebp,%ebp,4\)
+ 462 07dd 368C5CAE 12 mov %ds,%ss:0x12\(%esi,%ebp,4\)
+ 463 07e2 368C5CAF 12 mov %ds,%ss:0x12\(%edi,%ebp,4\)
+ 464 07e7 368C5CB0 12 mov %ds,%ss:0x12\(%eax,%esi,4\)
+ 465 07ec 368C5CB1 12 mov %ds,%ss:0x12\(%ecx,%esi,4\)
+ 466 07f1 368C5CB2 12 mov %ds,%ss:0x12\(%edx,%esi,4\)
+ 467 07f6 368C5CB3 12 mov %ds,%ss:0x12\(%ebx,%esi,4\)
+ 468 07fb 8C5CB412 mov %ds,%ss:0x12\(%esp,%esi,4\)
+ 469 07ff 8C5CB512 mov %ds,%ss:0x12\(%ebp,%esi,4\)
+ 470 0803 368C5CB6 12 mov %ds,%ss:0x12\(%esi,%esi,4\)
+ 471 0808 368C5CB7 12 mov %ds,%ss:0x12\(%edi,%esi,4\)
+ 472 080d 368C5CB8 12 mov %ds,%ss:0x12\(%eax,%edi,4\)
+ 473 0812 368C5CB9 12 mov %ds,%ss:0x12\(%ecx,%edi,4\)
+ 474 0817 368C5CBA 12 mov %ds,%ss:0x12\(%edx,%edi,4\)
+ 475 081c 368C5CBB 12 mov %ds,%ss:0x12\(%ebx,%edi,4\)
+ 476 0821 8C5CBC12 mov %ds,%ss:0x12\(%esp,%edi,4\)
+ 477 0825 8C5CBD12 mov %ds,%ss:0x12\(%ebp,%edi,4\)
+ 478 0829 368C5CBE 12 mov %ds,%ss:0x12\(%esi,%edi,4\)
+ 479 082e 368C5CBF 12 mov %ds,%ss:0x12\(%edi,%edi,4\)
+ 480 0833 368C5CC0 12 mov %ds,%ss:0x12\(%eax,%eax,8\)
+ 481 0838 368C5CC1 12 mov %ds,%ss:0x12\(%ecx,%eax,8\)
+ 482 083d 368C5CC2 12 mov %ds,%ss:0x12\(%edx,%eax,8\)
+ 483 0842 368C5CC3 12 mov %ds,%ss:0x12\(%ebx,%eax,8\)
+ 484 0847 8C5CC412 mov %ds,%ss:0x12\(%esp,%eax,8\)
+ 485 084b 8C5CC512 mov %ds,%ss:0x12\(%ebp,%eax,8\)
+ 486 084f 368C5CC6 12 mov %ds,%ss:0x12\(%esi,%eax,8\)
+ 487 0854 368C5CC7 12 mov %ds,%ss:0x12\(%edi,%eax,8\)
+ 488 0859 368C5CC8 12 mov %ds,%ss:0x12\(%eax,%ecx,8\)
+ 489 085e 368C5CC9 12 mov %ds,%ss:0x12\(%ecx,%ecx,8\)
+ 490 0863 368C5CCA 12 mov %ds,%ss:0x12\(%edx,%ecx,8\)
+ 491 0868 368C5CCB 12 mov %ds,%ss:0x12\(%ebx,%ecx,8\)
+ 492 086d 8C5CCC12 mov %ds,%ss:0x12\(%esp,%ecx,8\)
+ 493 0871 8C5CCD12 mov %ds,%ss:0x12\(%ebp,%ecx,8\)
+ 494 0875 368C5CCE 12 mov %ds,%ss:0x12\(%esi,%ecx,8\)
+ 495 087a 368C5CCF 12 mov %ds,%ss:0x12\(%edi,%ecx,8\)
+ 496 087f 368C5CD0 12 mov %ds,%ss:0x12\(%eax,%edx,8\)
+ 497 0884 368C5CD1 12 mov %ds,%ss:0x12\(%ecx,%edx,8\)
+ 498 0889 368C5CD2 12 mov %ds,%ss:0x12\(%edx,%edx,8\)
+ 499 088e 368C5CD3 12 mov %ds,%ss:0x12\(%ebx,%edx,8\)
+ 500 0893 8C5CD412 mov %ds,%ss:0x12\(%esp,%edx,8\)
+ 501 0897 8C5CD512 mov %ds,%ss:0x12\(%ebp,%edx,8\)
+ 502 089b 368C5CD6 12 mov %ds,%ss:0x12\(%esi,%edx,8\)
+ 503 08a0 368C5CD7 12 mov %ds,%ss:0x12\(%edi,%edx,8\)
+ 504 08a5 368C5CD8 12 mov %ds,%ss:0x12\(%eax,%ebx,8\)
+ 505 08aa 368C5CD9 12 mov %ds,%ss:0x12\(%ecx,%ebx,8\)
+ 506 08af 368C5CDA 12 mov %ds,%ss:0x12\(%edx,%ebx,8\)
+ 507 08b4 368C5CDB 12 mov %ds,%ss:0x12\(%ebx,%ebx,8\)
+ 508 08b9 8C5CDC12 mov %ds,%ss:0x12\(%esp,%ebx,8\)
+ 509 08bd 8C5CDD12 mov %ds,%ss:0x12\(%ebp,%ebx,8\)
+ 510 08c1 368C5CDE 12 mov %ds,%ss:0x12\(%esi,%ebx,8\)
+ 511 08c6 368C5CDF 12 mov %ds,%ss:0x12\(%edi,%ebx,8\)
+ 512 08cb 368C5812 mov %ds,%ss:0x12\(%eax,8\)
+.*Warning:.*
+ 513 08cf 368C5912 mov %ds,%ss:0x12\(%ecx,8\)
+.*Warning:.*
+ 514 08d3 368C5A12 mov %ds,%ss:0x12\(%edx,8\)
+.*Warning:.*
+ 515 08d7 368C5B12 mov %ds,%ss:0x12\(%ebx,8\)
+.*Warning:.*
+ 516 08db 8C5C2412 mov %ds,%ss:0x12\(%esp,8\)
+.*Warning:.*
+ 517 08df 8C5D12 mov %ds,%ss:0x12\(%ebp,8\)
+.*Warning:.*
+ 518 08e2 368C5E12 mov %ds,%ss:0x12\(%esi,8\)
+.*Warning:.*
+ 519 08e6 368C5F12 mov %ds,%ss:0x12\(%edi,8\)
+.*Warning:.*
+ 520 08ea 368C5CE8 12 mov %ds,%ss:0x12\(%eax,%ebp,8\)
+ 521 08ef 368C5CE9 12 mov %ds,%ss:0x12\(%ecx,%ebp,8\)
+ 522 08f4 368C5CEA 12 mov %ds,%ss:0x12\(%edx,%ebp,8\)
+ 523 08f9 368C5CEB 12 mov %ds,%ss:0x12\(%ebx,%ebp,8\)
+ 524 08fe 8C5CEC12 mov %ds,%ss:0x12\(%esp,%ebp,8\)
+ 525 0902 8C5CED12 mov %ds,%ss:0x12\(%ebp,%ebp,8\)
+ 526 0906 368C5CEE 12 mov %ds,%ss:0x12\(%esi,%ebp,8\)
+ 527 090b 368C5CEF 12 mov %ds,%ss:0x12\(%edi,%ebp,8\)
+ 528 0910 368C5CF0 12 mov %ds,%ss:0x12\(%eax,%esi,8\)
+ 529 0915 368C5CF1 12 mov %ds,%ss:0x12\(%ecx,%esi,8\)
+ 530 091a 368C5CF2 12 mov %ds,%ss:0x12\(%edx,%esi,8\)
+ 531 091f 368C5CF3 12 mov %ds,%ss:0x12\(%ebx,%esi,8\)
+ 532 0924 8C5CF412 mov %ds,%ss:0x12\(%esp,%esi,8\)
+ 533 0928 8C5CF512 mov %ds,%ss:0x12\(%ebp,%esi,8\)
+ 534 092c 368C5CF6 12 mov %ds,%ss:0x12\(%esi,%esi,8\)
+ 535 0931 368C5CF7 12 mov %ds,%ss:0x12\(%edi,%esi,8\)
+ 536 0936 368C5CF8 12 mov %ds,%ss:0x12\(%eax,%edi,8\)
+ 537 093b 368C5CFA 12 mov %ds,%ss:0x12\(%edx,%edi,8\)
+ 538 0940 368C5CF9 12 mov %ds,%ss:0x12\(%ecx,%edi,8\)
+ 539 0945 368C5CFB 12 mov %ds,%ss:0x12\(%ebx,%edi,8\)
+ 540 094a 8C5CFC12 mov %ds,%ss:0x12\(%esp,%edi,8\)
+ 541 094e 8C5CFD12 mov %ds,%ss:0x12\(%ebp,%edi,8\)
+ 542 0952 368C5CFE 12 mov %ds,%ss:0x12\(%esi,%edi,8\)
+ 543 0957 368C5CFF 12 mov %ds,%ss:0x12\(%edi,%edi,8\)
+ 544 095c 368C9C00 78563412 mov %ds,%ss:0x12345678\(%eax,%eax,1\)
+ 545 0964 368C9C01 78563412 mov %ds,%ss:0x12345678\(%ecx,%eax,1\)
+ 546 096c 368C9C02 78563412 mov %ds,%ss:0x12345678\(%edx,%eax,1\)
+ 547 0974 368C9C03 78563412 mov %ds,%ss:0x12345678\(%ebx,%eax,1\)
+ 548 097c 8C9C0478 563412 mov %ds,%ss:0x12345678\(%esp,%eax,1\)
+ 549 0983 8C9C0578 563412 mov %ds,%ss:0x12345678\(%ebp,%eax,1\)
+ 550 098a 368C9C06 78563412 mov %ds,%ss:0x12345678\(%esi,%eax,1\)
+ 551 0992 368C9C07 78563412 mov %ds,%ss:0x12345678\(%edi,%eax,1\)
+ 552 099a 368C9C08 78563412 mov %ds,%ss:0x12345678\(%eax,%ecx,1\)
+ 553 09a2 368C9C09 78563412 mov %ds,%ss:0x12345678\(%ecx,%ecx,1\)
+ 554 09aa 368C9C0A 78563412 mov %ds,%ss:0x12345678\(%edx,%ecx,1\)
+ 555 09b2 368C9C0B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ecx,1\)
+ 556 09ba 8C9C0C78 563412 mov %ds,%ss:0x12345678\(%esp,%ecx,1\)
+ 557 09c1 8C9C0D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ecx,1\)
+ 558 09c8 368C9C0E 78563412 mov %ds,%ss:0x12345678\(%esi,%ecx,1\)
+ 559 09d0 368C9C0F 78563412 mov %ds,%ss:0x12345678\(%edi,%ecx,1\)
+ 560 09d8 368C9C10 78563412 mov %ds,%ss:0x12345678\(%eax,%edx,1\)
+ 561 09e0 368C9C11 78563412 mov %ds,%ss:0x12345678\(%ecx,%edx,1\)
+ 562 09e8 368C9C12 78563412 mov %ds,%ss:0x12345678\(%edx,%edx,1\)
+ 563 09f0 368C9C13 78563412 mov %ds,%ss:0x12345678\(%ebx,%edx,1\)
+ 564 09f8 8C9C1478 563412 mov %ds,%ss:0x12345678\(%esp,%edx,1\)
+ 565 09ff 8C9C1578 563412 mov %ds,%ss:0x12345678\(%ebp,%edx,1\)
+ 566 0a06 368C9C16 78563412 mov %ds,%ss:0x12345678\(%esi,%edx,1\)
+ 567 0a0e 368C9C17 78563412 mov %ds,%ss:0x12345678\(%edi,%edx,1\)
+ 568 0a16 368C9C18 78563412 mov %ds,%ss:0x12345678\(%eax,%ebx,1\)
+ 569 0a1e 368C9C19 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebx,1\)
+ 570 0a26 368C9C1A 78563412 mov %ds,%ss:0x12345678\(%edx,%ebx,1\)
+ 571 0a2e 368C9C1B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebx,1\)
+ 572 0a36 8C9C1C78 563412 mov %ds,%ss:0x12345678\(%esp,%ebx,1\)
+ 573 0a3d 8C9C1D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebx,1\)
+ 574 0a44 368C9C1E 78563412 mov %ds,%ss:0x12345678\(%esi,%ebx,1\)
+ 575 0a4c 368C9C1F 78563412 mov %ds,%ss:0x12345678\(%edi,%ebx,1\)
+ 576 0a54 368C9878 563412 mov %ds,%ss:0x12345678\(%eax,1\)
+ 577 0a5b 368C9978 563412 mov %ds,%ss:0x12345678\(%ecx,1\)
+ 578 0a62 368C9A78 563412 mov %ds,%ss:0x12345678\(%edx,1\)
+ 579 0a69 368C9B78 563412 mov %ds,%ss:0x12345678\(%ebx,1\)
+ 580 0a70 8C9C2478 563412 mov %ds,%ss:0x12345678\(%esp,1\)
+ 581 0a77 8C9D7856 3412 mov %ds,%ss:0x12345678\(%ebp,1\)
+ 582 0a7d 368C9E78 563412 mov %ds,%ss:0x12345678\(%esi,1\)
+ 583 0a84 368C9F78 563412 mov %ds,%ss:0x12345678\(%edi,1\)
+ 584 0a8b 368C9C28 78563412 mov %ds,%ss:0x12345678\(%eax,%ebp,1\)
+ 585 0a93 368C9C29 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebp,1\)
+ 586 0a9b 368C9C2A 78563412 mov %ds,%ss:0x12345678\(%edx,%ebp,1\)
+ 587 0aa3 368C9C2B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebp,1\)
+ 588 0aab 8C9C2C78 563412 mov %ds,%ss:0x12345678\(%esp,%ebp,1\)
+ 589 0ab2 8C9C2D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebp,1\)
+ 590 0ab9 368C9C2E 78563412 mov %ds,%ss:0x12345678\(%esi,%ebp,1\)
+ 591 0ac1 368C9C2F 78563412 mov %ds,%ss:0x12345678\(%edi,%ebp,1\)
+ 592 0ac9 368C9C30 78563412 mov %ds,%ss:0x12345678\(%eax,%esi,1\)
+ 593 0ad1 368C9C31 78563412 mov %ds,%ss:0x12345678\(%ecx,%esi,1\)
+ 594 0ad9 368C9C32 78563412 mov %ds,%ss:0x12345678\(%edx,%esi,1\)
+ 595 0ae1 368C9C33 78563412 mov %ds,%ss:0x12345678\(%ebx,%esi,1\)
+ 596 0ae9 8C9C3478 563412 mov %ds,%ss:0x12345678\(%esp,%esi,1\)
+ 597 0af0 8C9C3578 563412 mov %ds,%ss:0x12345678\(%ebp,%esi,1\)
+ 598 0af7 368C9C36 78563412 mov %ds,%ss:0x12345678\(%esi,%esi,1\)
+ 599 0aff 368C9C37 78563412 mov %ds,%ss:0x12345678\(%edi,%esi,1\)
+ 600 0b07 368C9C38 78563412 mov %ds,%ss:0x12345678\(%eax,%edi,1\)
+ 601 0b0f 368C9C39 78563412 mov %ds,%ss:0x12345678\(%ecx,%edi,1\)
+ 602 0b17 368C9C3A 78563412 mov %ds,%ss:0x12345678\(%edx,%edi,1\)
+ 603 0b1f 368C9C3B 78563412 mov %ds,%ss:0x12345678\(%ebx,%edi,1\)
+ 604 0b27 8C9C3C78 563412 mov %ds,%ss:0x12345678\(%esp,%edi,1\)
+ 605 0b2e 8C9C3D78 563412 mov %ds,%ss:0x12345678\(%ebp,%edi,1\)
+ 606 0b35 368C9C3E 78563412 mov %ds,%ss:0x12345678\(%esi,%edi,1\)
+ 607 0b3d 368C9C3F 78563412 mov %ds,%ss:0x12345678\(%edi,%edi,1\)
+ 608 0b45 368C9C40 78563412 mov %ds,%ss:0x12345678\(%eax,%eax,2\)
+ 609 0b4d 368C9C41 78563412 mov %ds,%ss:0x12345678\(%ecx,%eax,2\)
+ 610 0b55 368C9C42 78563412 mov %ds,%ss:0x12345678\(%edx,%eax,2\)
+ 611 0b5d 368C9C43 78563412 mov %ds,%ss:0x12345678\(%ebx,%eax,2\)
+ 612 0b65 8C9C4478 563412 mov %ds,%ss:0x12345678\(%esp,%eax,2\)
+ 613 0b6c 8C9C4578 563412 mov %ds,%ss:0x12345678\(%ebp,%eax,2\)
+ 614 0b73 368C9C46 78563412 mov %ds,%ss:0x12345678\(%esi,%eax,2\)
+ 615 0b7b 368C9C47 78563412 mov %ds,%ss:0x12345678\(%edi,%eax,2\)
+ 616 0b83 368C9C48 78563412 mov %ds,%ss:0x12345678\(%eax,%ecx,2\)
+ 617 0b8b 368C9C49 78563412 mov %ds,%ss:0x12345678\(%ecx,%ecx,2\)
+ 618 0b93 368C9C4A 78563412 mov %ds,%ss:0x12345678\(%edx,%ecx,2\)
+ 619 0b9b 368C9C4B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ecx,2\)
+ 620 0ba3 8C9C4C78 563412 mov %ds,%ss:0x12345678\(%esp,%ecx,2\)
+ 621 0baa 8C9C4D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ecx,2\)
+ 622 0bb1 368C9C4E 78563412 mov %ds,%ss:0x12345678\(%esi,%ecx,2\)
+ 623 0bb9 368C9C4F 78563412 mov %ds,%ss:0x12345678\(%edi,%ecx,2\)
+ 624 0bc1 368C9C50 78563412 mov %ds,%ss:0x12345678\(%eax,%edx,2\)
+ 625 0bc9 368C9C51 78563412 mov %ds,%ss:0x12345678\(%ecx,%edx,2\)
+ 626 0bd1 368C9C52 78563412 mov %ds,%ss:0x12345678\(%edx,%edx,2\)
+ 627 0bd9 368C9C53 78563412 mov %ds,%ss:0x12345678\(%ebx,%edx,2\)
+ 628 0be1 8C9C5478 563412 mov %ds,%ss:0x12345678\(%esp,%edx,2\)
+ 629 0be8 8C9C5578 563412 mov %ds,%ss:0x12345678\(%ebp,%edx,2\)
+ 630 0bef 368C9C56 78563412 mov %ds,%ss:0x12345678\(%esi,%edx,2\)
+ 631 0bf7 368C9C57 78563412 mov %ds,%ss:0x12345678\(%edi,%edx,2\)
+ 632 0bff 368C9C58 78563412 mov %ds,%ss:0x12345678\(%eax,%ebx,2\)
+ 633 0c07 368C9C59 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebx,2\)
+ 634 0c0f 368C9C5A 78563412 mov %ds,%ss:0x12345678\(%edx,%ebx,2\)
+ 635 0c17 368C9C5B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebx,2\)
+ 636 0c1f 8C9C5C78 563412 mov %ds,%ss:0x12345678\(%esp,%ebx,2\)
+ 637 0c26 8C9C5D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebx,2\)
+ 638 0c2d 368C9C5E 78563412 mov %ds,%ss:0x12345678\(%esi,%ebx,2\)
+ 639 0c35 368C9C5F 78563412 mov %ds,%ss:0x12345678\(%edi,%ebx,2\)
+ 640 0c3d 368C9878 563412 mov %ds,%ss:0x12345678\(%eax,2\)
+.*Warning:.*
+ 641 0c44 368C9978 563412 mov %ds,%ss:0x12345678\(%ecx,2\)
+.*Warning:.*
+ 642 0c4b 368C9A78 563412 mov %ds,%ss:0x12345678\(%edx,2\)
+.*Warning:.*
+ 643 0c52 368C9B78 563412 mov %ds,%ss:0x12345678\(%ebx,2\)
+.*Warning:.*
+ 644 0c59 8C9C2478 563412 mov %ds,%ss:0x12345678\(%esp,2\)
+.*Warning:.*
+ 645 0c60 8C9D7856 3412 mov %ds,%ss:0x12345678\(%ebp,2\)
+.*Warning:.*
+ 646 0c66 368C9E78 563412 mov %ds,%ss:0x12345678\(%esi,2\)
+.*Warning:.*
+ 647 0c6d 368C9F78 563412 mov %ds,%ss:0x12345678\(%edi,2\)
+.*Warning:.*
+ 648 0c74 368C9C68 78563412 mov %ds,%ss:0x12345678\(%eax,%ebp,2\)
+ 649 0c7c 368C9C69 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebp,2\)
+ 650 0c84 368C9C6A 78563412 mov %ds,%ss:0x12345678\(%edx,%ebp,2\)
+ 651 0c8c 368C9C6B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebp,2\)
+ 652 0c94 8C9C6C78 563412 mov %ds,%ss:0x12345678\(%esp,%ebp,2\)
+ 653 0c9b 8C9C6D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebp,2\)
+ 654 0ca2 368C9C6E 78563412 mov %ds,%ss:0x12345678\(%esi,%ebp,2\)
+ 655 0caa 368C9C6F 78563412 mov %ds,%ss:0x12345678\(%edi,%ebp,2\)
+ 656 0cb2 368C9C70 78563412 mov %ds,%ss:0x12345678\(%eax,%esi,2\)
+ 657 0cba 368C9C71 78563412 mov %ds,%ss:0x12345678\(%ecx,%esi,2\)
+ 658 0cc2 368C9C72 78563412 mov %ds,%ss:0x12345678\(%edx,%esi,2\)
+ 659 0cca 368C9C73 78563412 mov %ds,%ss:0x12345678\(%ebx,%esi,2\)
+ 660 0cd2 8C9C7478 563412 mov %ds,%ss:0x12345678\(%esp,%esi,2\)
+ 661 0cd9 8C9C7578 563412 mov %ds,%ss:0x12345678\(%ebp,%esi,2\)
+ 662 0ce0 368C9C76 78563412 mov %ds,%ss:0x12345678\(%esi,%esi,2\)
+ 663 0ce8 368C9C77 78563412 mov %ds,%ss:0x12345678\(%edi,%esi,2\)
+ 664 0cf0 368C9C78 78563412 mov %ds,%ss:0x12345678\(%eax,%edi,2\)
+ 665 0cf8 368C9C79 78563412 mov %ds,%ss:0x12345678\(%ecx,%edi,2\)
+ 666 0d00 368C9C7A 78563412 mov %ds,%ss:0x12345678\(%edx,%edi,2\)
+ 667 0d08 368C9C7B 78563412 mov %ds,%ss:0x12345678\(%ebx,%edi,2\)
+ 668 0d10 8C9C7C78 563412 mov %ds,%ss:0x12345678\(%esp,%edi,2\)
+ 669 0d17 8C9C7D78 563412 mov %ds,%ss:0x12345678\(%ebp,%edi,2\)
+ 670 0d1e 368C9C7E 78563412 mov %ds,%ss:0x12345678\(%esi,%edi,2\)
+ 671 0d26 368C9C7F 78563412 mov %ds,%ss:0x12345678\(%edi,%edi,2\)
+ 672 0d2e 368C9C80 78563412 mov %ds,%ss:0x12345678\(%eax,%eax,4\)
+ 673 0d36 368C9C81 78563412 mov %ds,%ss:0x12345678\(%ecx,%eax,4\)
+ 674 0d3e 368C9C82 78563412 mov %ds,%ss:0x12345678\(%edx,%eax,4\)
+ 675 0d46 368C9C83 78563412 mov %ds,%ss:0x12345678\(%ebx,%eax,4\)
+ 676 0d4e 8C9C8478 563412 mov %ds,%ss:0x12345678\(%esp,%eax,4\)
+ 677 0d55 8C9C8578 563412 mov %ds,%ss:0x12345678\(%ebp,%eax,4\)
+ 678 0d5c 368C9C86 78563412 mov %ds,%ss:0x12345678\(%esi,%eax,4\)
+ 679 0d64 368C9C87 78563412 mov %ds,%ss:0x12345678\(%edi,%eax,4\)
+ 680 0d6c 368C9C88 78563412 mov %ds,%ss:0x12345678\(%eax,%ecx,4\)
+ 681 0d74 368C9C89 78563412 mov %ds,%ss:0x12345678\(%ecx,%ecx,4\)
+ 682 0d7c 368C9C8A 78563412 mov %ds,%ss:0x12345678\(%edx,%ecx,4\)
+ 683 0d84 368C9C8B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ecx,4\)
+ 684 0d8c 8C9C8C78 563412 mov %ds,%ss:0x12345678\(%esp,%ecx,4\)
+ 685 0d93 8C9C8D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ecx,4\)
+ 686 0d9a 368C9C8E 78563412 mov %ds,%ss:0x12345678\(%esi,%ecx,4\)
+ 687 0da2 368C9C8F 78563412 mov %ds,%ss:0x12345678\(%edi,%ecx,4\)
+ 688 0daa 368C9C90 78563412 mov %ds,%ss:0x12345678\(%eax,%edx,4\)
+ 689 0db2 368C9C91 78563412 mov %ds,%ss:0x12345678\(%ecx,%edx,4\)
+ 690 0dba 368C9C92 78563412 mov %ds,%ss:0x12345678\(%edx,%edx,4\)
+ 691 0dc2 368C9C93 78563412 mov %ds,%ss:0x12345678\(%ebx,%edx,4\)
+ 692 0dca 8C9C9478 563412 mov %ds,%ss:0x12345678\(%esp,%edx,4\)
+ 693 0dd1 8C9C9578 563412 mov %ds,%ss:0x12345678\(%ebp,%edx,4\)
+ 694 0dd8 368C9C96 78563412 mov %ds,%ss:0x12345678\(%esi,%edx,4\)
+ 695 0de0 368C9C97 78563412 mov %ds,%ss:0x12345678\(%edi,%edx,4\)
+ 696 0de8 368C9C98 78563412 mov %ds,%ss:0x12345678\(%eax,%ebx,4\)
+ 697 0df0 368C9C99 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebx,4\)
+ 698 0df8 368C9C9A 78563412 mov %ds,%ss:0x12345678\(%edx,%ebx,4\)
+ 699 0e00 368C9C9B 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebx,4\)
+ 700 0e08 8C9C9C78 563412 mov %ds,%ss:0x12345678\(%esp,%ebx,4\)
+ 701 0e0f 8C9C9D78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebx,4\)
+ 702 0e16 368C9C9E 78563412 mov %ds,%ss:0x12345678\(%esi,%ebx,4\)
+ 703 0e1e 368C9C9F 78563412 mov %ds,%ss:0x12345678\(%edi,%ebx,4\)
+ 704 0e26 368C9878 563412 mov %ds,%ss:0x12345678\(%eax,4\)
+.*Warning:.*
+ 705 0e2d 368C9978 563412 mov %ds,%ss:0x12345678\(%ecx,4\)
+.*Warning:.*
+ 706 0e34 368C9A78 563412 mov %ds,%ss:0x12345678\(%edx,4\)
+.*Warning:.*
+ 707 0e3b 368C9B78 563412 mov %ds,%ss:0x12345678\(%ebx,4\)
+.*Warning:.*
+ 708 0e42 8C9C2478 563412 mov %ds,%ss:0x12345678\(%esp,4\)
+.*Warning:.*
+ 709 0e49 8C9D7856 3412 mov %ds,%ss:0x12345678\(%ebp,4\)
+.*Warning:.*
+ 710 0e4f 368C9E78 563412 mov %ds,%ss:0x12345678\(%esi,4\)
+.*Warning:.*
+ 711 0e56 368C9F78 563412 mov %ds,%ss:0x12345678\(%edi,4\)
+.*Warning:.*
+ 712 0e5d 368C9CA8 78563412 mov %ds,%ss:0x12345678\(%eax,%ebp,4\)
+ 713 0e65 368C9CA9 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebp,4\)
+ 714 0e6d 368C9CAA 78563412 mov %ds,%ss:0x12345678\(%edx,%ebp,4\)
+ 715 0e75 368C9CAB 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebp,4\)
+ 716 0e7d 8C9CAC78 563412 mov %ds,%ss:0x12345678\(%esp,%ebp,4\)
+ 717 0e84 8C9CAD78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebp,4\)
+ 718 0e8b 368C9CAE 78563412 mov %ds,%ss:0x12345678\(%esi,%ebp,4\)
+ 719 0e93 368C9CAF 78563412 mov %ds,%ss:0x12345678\(%edi,%ebp,4\)
+ 720 0e9b 368C9CB0 78563412 mov %ds,%ss:0x12345678\(%eax,%esi,4\)
+ 721 0ea3 368C9CB1 78563412 mov %ds,%ss:0x12345678\(%ecx,%esi,4\)
+ 722 0eab 368C9CB2 78563412 mov %ds,%ss:0x12345678\(%edx,%esi,4\)
+ 723 0eb3 368C9CB3 78563412 mov %ds,%ss:0x12345678\(%ebx,%esi,4\)
+ 724 0ebb 8C9CB478 563412 mov %ds,%ss:0x12345678\(%esp,%esi,4\)
+ 725 0ec2 8C9CB578 563412 mov %ds,%ss:0x12345678\(%ebp,%esi,4\)
+ 726 0ec9 368C9CB6 78563412 mov %ds,%ss:0x12345678\(%esi,%esi,4\)
+ 727 0ed1 368C9CB7 78563412 mov %ds,%ss:0x12345678\(%edi,%esi,4\)
+ 728 0ed9 368C9CB8 78563412 mov %ds,%ss:0x12345678\(%eax,%edi,4\)
+ 729 0ee1 368C9CB9 78563412 mov %ds,%ss:0x12345678\(%ecx,%edi,4\)
+ 730 0ee9 368C9CBA 78563412 mov %ds,%ss:0x12345678\(%edx,%edi,4\)
+ 731 0ef1 368C9CBB 78563412 mov %ds,%ss:0x12345678\(%ebx,%edi,4\)
+ 732 0ef9 8C9CBC78 563412 mov %ds,%ss:0x12345678\(%esp,%edi,4\)
+ 733 0f00 8C9CBD78 563412 mov %ds,%ss:0x12345678\(%ebp,%edi,4\)
+ 734 0f07 368C9CBE 78563412 mov %ds,%ss:0x12345678\(%esi,%edi,4\)
+ 735 0f0f 368C9CBF 78563412 mov %ds,%ss:0x12345678\(%edi,%edi,4\)
+ 736 0f17 368C9CC0 78563412 mov %ds,%ss:0x12345678\(%eax,%eax,8\)
+ 737 0f1f 368C9CC1 78563412 mov %ds,%ss:0x12345678\(%ecx,%eax,8\)
+ 738 0f27 368C9CC2 78563412 mov %ds,%ss:0x12345678\(%edx,%eax,8\)
+ 739 0f2f 368C9CC3 78563412 mov %ds,%ss:0x12345678\(%ebx,%eax,8\)
+ 740 0f37 8C9CC478 563412 mov %ds,%ss:0x12345678\(%esp,%eax,8\)
+ 741 0f3e 8C9CC578 563412 mov %ds,%ss:0x12345678\(%ebp,%eax,8\)
+ 742 0f45 368C9CC6 78563412 mov %ds,%ss:0x12345678\(%esi,%eax,8\)
+ 743 0f4d 368C9CC7 78563412 mov %ds,%ss:0x12345678\(%edi,%eax,8\)
+ 744 0f55 368C9CC8 78563412 mov %ds,%ss:0x12345678\(%eax,%ecx,8\)
+ 745 0f5d 368C9CC9 78563412 mov %ds,%ss:0x12345678\(%ecx,%ecx,8\)
+ 746 0f65 368C9CCA 78563412 mov %ds,%ss:0x12345678\(%edx,%ecx,8\)
+ 747 0f6d 368C9CCB 78563412 mov %ds,%ss:0x12345678\(%ebx,%ecx,8\)
+ 748 0f75 8C9CCC78 563412 mov %ds,%ss:0x12345678\(%esp,%ecx,8\)
+ 749 0f7c 8C9CCD78 563412 mov %ds,%ss:0x12345678\(%ebp,%ecx,8\)
+ 750 0f83 368C9CCE 78563412 mov %ds,%ss:0x12345678\(%esi,%ecx,8\)
+ 751 0f8b 368C9CCF 78563412 mov %ds,%ss:0x12345678\(%edi,%ecx,8\)
+ 752 0f93 368C9CD0 78563412 mov %ds,%ss:0x12345678\(%eax,%edx,8\)
+ 753 0f9b 368C9CD1 78563412 mov %ds,%ss:0x12345678\(%ecx,%edx,8\)
+ 754 0fa3 368C9CD2 78563412 mov %ds,%ss:0x12345678\(%edx,%edx,8\)
+ 755 0fab 368C9CD3 78563412 mov %ds,%ss:0x12345678\(%ebx,%edx,8\)
+ 756 0fb3 8C9CD478 563412 mov %ds,%ss:0x12345678\(%esp,%edx,8\)
+ 757 0fba 8C9CD578 563412 mov %ds,%ss:0x12345678\(%ebp,%edx,8\)
+ 758 0fc1 368C9CD6 78563412 mov %ds,%ss:0x12345678\(%esi,%edx,8\)
+ 759 0fc9 368C9CD7 78563412 mov %ds,%ss:0x12345678\(%edi,%edx,8\)
+ 760 0fd1 368C9CD8 78563412 mov %ds,%ss:0x12345678\(%eax,%ebx,8\)
+ 761 0fd9 368C9CD9 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebx,8\)
+ 762 0fe1 368C9CDA 78563412 mov %ds,%ss:0x12345678\(%edx,%ebx,8\)
+ 763 0fe9 368C9CDB 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebx,8\)
+ 764 0ff1 8C9CDC78 563412 mov %ds,%ss:0x12345678\(%esp,%ebx,8\)
+ 765 0ff8 8C9CDD78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebx,8\)
+ 766 0fff 368C9CDE 78563412 mov %ds,%ss:0x12345678\(%esi,%ebx,8\)
+ 767 1007 368C9CDF 78563412 mov %ds,%ss:0x12345678\(%edi,%ebx,8\)
+ 768 100f 368C9878 563412 mov %ds,%ss:0x12345678\(%eax,8\)
+.*Warning:.*
+ 769 1016 368C9978 563412 mov %ds,%ss:0x12345678\(%ecx,8\)
+.*Warning:.*
+ 770 101d 368C9A78 563412 mov %ds,%ss:0x12345678\(%edx,8\)
+.*Warning:.*
+ 771 1024 368C9B78 563412 mov %ds,%ss:0x12345678\(%ebx,8\)
+.*Warning:.*
+ 772 102b 8C9C2478 563412 mov %ds,%ss:0x12345678\(%esp,8\)
+.*Warning:.*
+ 773 1032 8C9D7856 3412 mov %ds,%ss:0x12345678\(%ebp,8\)
+.*Warning:.*
+ 774 1038 368C9E78 563412 mov %ds,%ss:0x12345678\(%esi,8\)
+.*Warning:.*
+ 775 103f 368C9F78 563412 mov %ds,%ss:0x12345678\(%edi,8\)
+.*Warning:.*
+ 776 1046 368C9CE8 78563412 mov %ds,%ss:0x12345678\(%eax,%ebp,8\)
+ 777 104e 368C9CE9 78563412 mov %ds,%ss:0x12345678\(%ecx,%ebp,8\)
+ 778 1056 368C9CEA 78563412 mov %ds,%ss:0x12345678\(%edx,%ebp,8\)
+ 779 105e 368C9CEB 78563412 mov %ds,%ss:0x12345678\(%ebx,%ebp,8\)
+ 780 1066 8C9CEC78 563412 mov %ds,%ss:0x12345678\(%esp,%ebp,8\)
+ 781 106d 8C9CED78 563412 mov %ds,%ss:0x12345678\(%ebp,%ebp,8\)
+ 782 1074 368C9CEE 78563412 mov %ds,%ss:0x12345678\(%esi,%ebp,8\)
+ 783 107c 368C9CEF 78563412 mov %ds,%ss:0x12345678\(%edi,%ebp,8\)
+ 784 1084 368C9CF0 78563412 mov %ds,%ss:0x12345678\(%eax,%esi,8\)
+ 785 108c 368C9CF1 78563412 mov %ds,%ss:0x12345678\(%ecx,%esi,8\)
+ 786 1094 368C9CF2 78563412 mov %ds,%ss:0x12345678\(%edx,%esi,8\)
+ 787 109c 368C9CF3 78563412 mov %ds,%ss:0x12345678\(%ebx,%esi,8\)
+ 788 10a4 8C9CF478 563412 mov %ds,%ss:0x12345678\(%esp,%esi,8\)
+ 789 10ab 8C9CF578 563412 mov %ds,%ss:0x12345678\(%ebp,%esi,8\)
+ 790 10b2 368C9CF6 78563412 mov %ds,%ss:0x12345678\(%esi,%esi,8\)
+ 791 10ba 368C9CF7 78563412 mov %ds,%ss:0x12345678\(%edi,%esi,8\)
+ 792 10c2 368C9CF8 78563412 mov %ds,%ss:0x12345678\(%eax,%edi,8\)
+ 793 10ca 368C9CFA 78563412 mov %ds,%ss:0x12345678\(%edx,%edi,8\)
+ 794 10d2 368C9CF9 78563412 mov %ds,%ss:0x12345678\(%ecx,%edi,8\)
+ 795 10da 368C9CFB 78563412 mov %ds,%ss:0x12345678\(%ebx,%edi,8\)
+ 796 10e2 8C9CFC78 563412 mov %ds,%ss:0x12345678\(%esp,%edi,8\)
+ 797 10e9 8C9CFD78 563412 mov %ds,%ss:0x12345678\(%ebp,%edi,8\)
+ 798 10f0 368C9CFE 78563412 mov %ds,%ss:0x12345678\(%esi,%edi,8\)
+ 799 10f8 368C9CFF 78563412 mov %ds,%ss:0x12345678\(%edi,%edi,8\)
+ 800 1100 8C5C0500 mov %ds,%ss:\(%ebp,%eax,1\)
+ 801 1104 8C5C0D00 mov %ds,%ss:\(%ebp,%ecx,1\)
+ 802 1108 8C5C1500 mov %ds,%ss:\(%ebp,%edx,1\)
+ 803 110c 8C5C1D00 mov %ds,%ss:\(%ebp,%ebx,1\)
+ 804 1110 8C5D00 mov %ds,%ss:\(%ebp,1\)
+ 805 1113 8C5C2D00 mov %ds,%ss:\(%ebp,%ebp,1\)
+ 806 1117 8C5C3500 mov %ds,%ss:\(%ebp,%esi,1\)
+ 807 111b 8C5C3D00 mov %ds,%ss:\(%ebp,%edi,1\)
+ 808 111f 8C5C4500 mov %ds,%ss:\(%ebp,%eax,2\)
+ 809 1123 8C5C4D00 mov %ds,%ss:\(%ebp,%ecx,2\)
+ 810 1127 8C5C5500 mov %ds,%ss:\(%ebp,%edx,2\)
+ 811 112b 8C5C5D00 mov %ds,%ss:\(%ebp,%ebx,2\)
+ 812 112f 8C5D00 mov %ds,%ss:\(%ebp,2\)
+.*Warning:.*
+ 813 1132 8C5C6D00 mov %ds,%ss:\(%ebp,%ebp,2\)
+ 814 1136 8C5C7500 mov %ds,%ss:\(%ebp,%esi,2\)
+ 815 113a 8C5C7D00 mov %ds,%ss:\(%ebp,%edi,2\)
+ 816 113e 8C5C8500 mov %ds,%ss:\(%ebp,%eax,4\)
+ 817 1142 8C5C8D00 mov %ds,%ss:\(%ebp,%ecx,4\)
+ 818 1146 8C5C9500 mov %ds,%ss:\(%ebp,%edx,4\)
+ 819 114a 8C5C9D00 mov %ds,%ss:\(%ebp,%ebx,4\)
+ 820 114e 8C5D00 mov %ds,%ss:\(%ebp,4\)
+.*Warning:.*
+ 821 1151 8C5CAD00 mov %ds,%ss:\(%ebp,%ebp,4\)
+ 822 1155 8C5CB500 mov %ds,%ss:\(%ebp,%esi,4\)
+ 823 1159 8C5CBD00 mov %ds,%ss:\(%ebp,%edi,4\)
+ 824 115d 8C5CC500 mov %ds,%ss:\(%ebp,%eax,8\)
+ 825 1161 8C5CCD00 mov %ds,%ss:\(%ebp,%ecx,8\)
+ 826 1165 8C5CD500 mov %ds,%ss:\(%ebp,%edx,8\)
+ 827 1169 8C5CDD00 mov %ds,%ss:\(%ebp,%ebx,8\)
+ 828 116d 8C5D00 mov %ds,%ss:\(%ebp,8\)
+.*Warning:.*
+ 829 1170 8C5CED00 mov %ds,%ss:\(%ebp,%ebp,8\)
+ 830 1174 8C5CF500 mov %ds,%ss:\(%ebp,%esi,8\)
+ 831 1178 8C5CFD00 mov %ds,%ss:\(%ebp,%edi,8\)
+ 832 117c 368C1D12 000000 mov %ds,%ss:0x12\(,1\)
+ 833 1183 368C1D12 000000 mov %ds,%ss:0x12\(,2\)
+.*Warning:.*
+ 834 118a 368C1D12 000000 mov %ds,%ss:0x12\(,4\)
+.*Warning:.*
+ 835 1191 368C1D12 000000 mov %ds,%ss:0x12\(,8\)
+.*Warning:.*
+ 836 1198 8C18 mov %ds,%ds:\(%eax\)
+ 837 119a 8C19 mov %ds,%ds:\(%ecx\)
+ 838 119c 8C1A mov %ds,%ds:\(%edx\)
+ 839 119e 8C1B mov %ds,%ds:\(%ebx\)
+ 840 11a0 8C1D0000 0000 mov %ds,%ds:0
+ 841 11a6 8C1E mov %ds,%ds:\(%esi\)
+ 842 11a8 8C1F mov %ds,%ds:\(%edi\)
+ 843 11aa 8C5812 mov %ds,%ds:0x12\(%eax\)
+ 844 11ad 8C5912 mov %ds,%ds:0x12\(%ecx\)
+ 845 11b0 8C5A12 mov %ds,%ds:0x12\(%edx\)
+ 846 11b3 8C5B12 mov %ds,%ds:0x12\(%ebx\)
+ 847 11b6 3E8C5D12 mov %ds,%ds:0x12\(%ebp\)
+ 848 11ba 8C5E12 mov %ds,%ds:0x12\(%esi\)
+ 849 11bd 8C5F12 mov %ds,%ds:0x12\(%edi\)
+ 850 11c0 8C987856 3412 mov %ds,%ds:0x12345678\(%eax\)
+ 851 11c6 8C997856 3412 mov %ds,%ds:0x12345678\(%ecx\)
+ 852 11cc 8C9A7856 3412 mov %ds,%ds:0x12345678\(%edx\)
+ 853 11d2 8C9B7856 3412 mov %ds,%ds:0x12345678\(%ebx\)
+ 854 11d8 3E8C9D78 563412 mov %ds,%ds:0x12345678\(%ebp\)
+ 855 11df 8C9E7856 3412 mov %ds,%ds:0x12345678\(%esi\)
+ 856 11e5 8C9F7856 3412 mov %ds,%ds:0x12345678\(%edi\)
+ 857 11eb 8CD8 mov %ds,%eax
+ 858 11ed 8CD9 mov %ds,%ecx
+ 859 11ef 8CDA mov %ds,%edx
+ 860 11f1 8CDB mov %ds,%ebx
+ 861 11f3 8CDC mov %ds,%esp
+ 862 11f5 8CDD mov %ds,%ebp
+ 863 11f7 8CDE mov %ds,%esi
+ 864 11f9 8CDF mov %ds,%edi
+ 865 11fb 8C1C00 mov %ds,%ds:\(%eax,%eax,1\)
+ 866 11fe 8C1C01 mov %ds,%ds:\(%ecx,%eax,1\)
+ 867 1201 8C1C02 mov %ds,%ds:\(%edx,%eax,1\)
+ 868 1204 8C1C03 mov %ds,%ds:\(%ebx,%eax,1\)
+ 869 1207 3E8C1C04 mov %ds,%ds:\(%esp,%eax,1\)
+ 870 120b 8C1C0500 000000 mov %ds,%ds:\(,%eax,1\)
+ 871 1212 8C1C06 mov %ds,%ds:\(%esi,%eax,1\)
+ 872 1215 8C1C07 mov %ds,%ds:\(%edi,%eax,1\)
+ 873 1218 8C1C08 mov %ds,%ds:\(%eax,%ecx,1\)
+ 874 121b 8C1C09 mov %ds,%ds:\(%ecx,%ecx,1\)
+ 875 121e 8C1C0A mov %ds,%ds:\(%edx,%ecx,1\)
+ 876 1221 8C1C0B mov %ds,%ds:\(%ebx,%ecx,1\)
+ 877 1224 3E8C1C0C mov %ds,%ds:\(%esp,%ecx,1\)
+ 878 1228 8C1C0D00 000000 mov %ds,%ds:\(,%ecx,1\)
+ 879 122f 8C1C0E mov %ds,%ds:\(%esi,%ecx,1\)
+ 880 1232 8C1C0F mov %ds,%ds:\(%edi,%ecx,1\)
+ 881 1235 8C1C10 mov %ds,%ds:\(%eax,%edx,1\)
+ 882 1238 8C1C11 mov %ds,%ds:\(%ecx,%edx,1\)
+ 883 123b 8C1C12 mov %ds,%ds:\(%edx,%edx,1\)
+ 884 123e 8C1C13 mov %ds,%ds:\(%ebx,%edx,1\)
+ 885 1241 3E8C1C14 mov %ds,%ds:\(%esp,%edx,1\)
+ 886 1245 8C1C1500 000000 mov %ds,%ds:\(,%edx,1\)
+ 887 124c 8C1C16 mov %ds,%ds:\(%esi,%edx,1\)
+ 888 124f 8C1C17 mov %ds,%ds:\(%edi,%edx,1\)
+ 889 1252 8C1C18 mov %ds,%ds:\(%eax,%ebx,1\)
+ 890 1255 8C1C19 mov %ds,%ds:\(%ecx,%ebx,1\)
+ 891 1258 8C1C1A mov %ds,%ds:\(%edx,%ebx,1\)
+ 892 125b 8C1C1B mov %ds,%ds:\(%ebx,%ebx,1\)
+ 893 125e 3E8C1C1C mov %ds,%ds:\(%esp,%ebx,1\)
+ 894 1262 8C1C1D00 000000 mov %ds,%ds:\(,%ebx,1\)
+ 895 1269 8C1C1E mov %ds,%ds:\(%esi,%ebx,1\)
+ 896 126c 8C1C1F mov %ds,%ds:\(%edi,%ebx,1\)
+ 897 126f 8C18 mov %ds,%ds:\(%eax,1\)
+ 898 1271 8C19 mov %ds,%ds:\(%ecx,1\)
+ 899 1273 8C1A mov %ds,%ds:\(%edx,1\)
+ 900 1275 8C1B mov %ds,%ds:\(%ebx,1\)
+ 901 1277 3E8C1C24 mov %ds,%ds:\(%esp,1\)
+ 902 127b 8C1D0000 0000 mov %ds,%ds:\(,1\)
+ 903 1281 8C1E mov %ds,%ds:\(%esi,1\)
+ 904 1283 8C1F mov %ds,%ds:\(%edi,1\)
+ 905 1285 8C1C28 mov %ds,%ds:\(%eax,%ebp,1\)
+ 906 1288 8C1C29 mov %ds,%ds:\(%ecx,%ebp,1\)
+ 907 128b 8C1C2A mov %ds,%ds:\(%edx,%ebp,1\)
+ 908 128e 8C1C2B mov %ds,%ds:\(%ebx,%ebp,1\)
+ 909 1291 3E8C1C2C mov %ds,%ds:\(%esp,%ebp,1\)
+ 910 1295 8C1C2D00 000000 mov %ds,%ds:\(,%ebp,1\)
+ 911 129c 8C1C2E mov %ds,%ds:\(%esi,%ebp,1\)
+ 912 129f 8C1C2F mov %ds,%ds:\(%edi,%ebp,1\)
+ 913 12a2 8C1C30 mov %ds,%ds:\(%eax,%esi,1\)
+ 914 12a5 8C1C31 mov %ds,%ds:\(%ecx,%esi,1\)
+ 915 12a8 8C1C32 mov %ds,%ds:\(%edx,%esi,1\)
+ 916 12ab 8C1C33 mov %ds,%ds:\(%ebx,%esi,1\)
+ 917 12ae 3E8C1C34 mov %ds,%ds:\(%esp,%esi,1\)
+ 918 12b2 8C1C3500 000000 mov %ds,%ds:\(,%esi,1\)
+ 919 12b9 8C1C36 mov %ds,%ds:\(%esi,%esi,1\)
+ 920 12bc 8C1C37 mov %ds,%ds:\(%edi,%esi,1\)
+ 921 12bf 8C1C38 mov %ds,%ds:\(%eax,%edi,1\)
+ 922 12c2 8C1C39 mov %ds,%ds:\(%ecx,%edi,1\)
+ 923 12c5 8C1C3A mov %ds,%ds:\(%edx,%edi,1\)
+ 924 12c8 8C1C3B mov %ds,%ds:\(%ebx,%edi,1\)
+ 925 12cb 3E8C1C3C mov %ds,%ds:\(%esp,%edi,1\)
+ 926 12cf 8C1C3D00 000000 mov %ds,%ds:\(,%edi,1\)
+ 927 12d6 8C1C3E mov %ds,%ds:\(%esi,%edi,1\)
+ 928 12d9 8C1C3F mov %ds,%ds:\(%edi,%edi,1\)
+ 929 12dc 8C1C40 mov %ds,%ds:\(%eax,%eax,2\)
+ 930 12df 8C1C41 mov %ds,%ds:\(%ecx,%eax,2\)
+ 931 12e2 8C1C42 mov %ds,%ds:\(%edx,%eax,2\)
+ 932 12e5 8C1C43 mov %ds,%ds:\(%ebx,%eax,2\)
+ 933 12e8 3E8C1C44 mov %ds,%ds:\(%esp,%eax,2\)
+ 934 12ec 8C1C4500 000000 mov %ds,%ds:\(,%eax,2\)
+ 935 12f3 8C1C46 mov %ds,%ds:\(%esi,%eax,2\)
+ 936 12f6 8C1C47 mov %ds,%ds:\(%edi,%eax,2\)
+ 937 12f9 8C1C48 mov %ds,%ds:\(%eax,%ecx,2\)
+ 938 12fc 8C1C49 mov %ds,%ds:\(%ecx,%ecx,2\)
+ 939 12ff 8C1C4A mov %ds,%ds:\(%edx,%ecx,2\)
+ 940 1302 8C1C4B mov %ds,%ds:\(%ebx,%ecx,2\)
+ 941 1305 3E8C1C4C mov %ds,%ds:\(%esp,%ecx,2\)
+ 942 1309 8C1C4D00 000000 mov %ds,%ds:\(,%ecx,2\)
+ 943 1310 8C1C4E mov %ds,%ds:\(%esi,%ecx,2\)
+ 944 1313 8C1C4F mov %ds,%ds:\(%edi,%ecx,2\)
+ 945 1316 8C1C50 mov %ds,%ds:\(%eax,%edx,2\)
+ 946 1319 8C1C51 mov %ds,%ds:\(%ecx,%edx,2\)
+ 947 131c 8C1C52 mov %ds,%ds:\(%edx,%edx,2\)
+ 948 131f 8C1C53 mov %ds,%ds:\(%ebx,%edx,2\)
+ 949 1322 3E8C1C54 mov %ds,%ds:\(%esp,%edx,2\)
+ 950 1326 8C1C5500 000000 mov %ds,%ds:\(,%edx,2\)
+ 951 132d 8C1C56 mov %ds,%ds:\(%esi,%edx,2\)
+ 952 1330 8C1C57 mov %ds,%ds:\(%edi,%edx,2\)
+ 953 1333 8C1C58 mov %ds,%ds:\(%eax,%ebx,2\)
+ 954 1336 8C1C59 mov %ds,%ds:\(%ecx,%ebx,2\)
+ 955 1339 8C1C5A mov %ds,%ds:\(%edx,%ebx,2\)
+ 956 133c 8C1C5B mov %ds,%ds:\(%ebx,%ebx,2\)
+ 957 133f 3E8C1C5C mov %ds,%ds:\(%esp,%ebx,2\)
+ 958 1343 8C1C5D00 000000 mov %ds,%ds:\(,%ebx,2\)
+ 959 134a 8C1C5E mov %ds,%ds:\(%esi,%ebx,2\)
+ 960 134d 8C1C5F mov %ds,%ds:\(%edi,%ebx,2\)
+ 961 1350 8C18 mov %ds,%ds:\(%eax,2\)
+.*Warning:.*
+ 962 1352 8C19 mov %ds,%ds:\(%ecx,2\)
+.*Warning:.*
+ 963 1354 8C1A mov %ds,%ds:\(%edx,2\)
+.*Warning:.*
+ 964 1356 8C1B mov %ds,%ds:\(%ebx,2\)
+.*Warning:.*
+ 965 1358 3E8C1C24 mov %ds,%ds:\(%esp,2\)
+.*Warning:.*
+ 966 135c 8C1D0000 0000 mov %ds,%ds:\(,2\)
+.*Warning:.*
+ 967 1362 8C1E mov %ds,%ds:\(%esi,2\)
+.*Warning:.*
+ 968 1364 8C1F mov %ds,%ds:\(%edi,2\)
+.*Warning:.*
+ 969 1366 8C1C68 mov %ds,%ds:\(%eax,%ebp,2\)
+ 970 1369 8C1C69 mov %ds,%ds:\(%ecx,%ebp,2\)
+ 971 136c 8C1C6A mov %ds,%ds:\(%edx,%ebp,2\)
+ 972 136f 8C1C6B mov %ds,%ds:\(%ebx,%ebp,2\)
+ 973 1372 3E8C1C6C mov %ds,%ds:\(%esp,%ebp,2\)
+ 974 1376 8C1C6D00 000000 mov %ds,%ds:\(,%ebp,2\)
+ 975 137d 8C1C6E mov %ds,%ds:\(%esi,%ebp,2\)
+ 976 1380 8C1C6F mov %ds,%ds:\(%edi,%ebp,2\)
+ 977 1383 8C1C70 mov %ds,%ds:\(%eax,%esi,2\)
+ 978 1386 8C1C71 mov %ds,%ds:\(%ecx,%esi,2\)
+ 979 1389 8C1C72 mov %ds,%ds:\(%edx,%esi,2\)
+ 980 138c 8C1C73 mov %ds,%ds:\(%ebx,%esi,2\)
+ 981 138f 3E8C1C74 mov %ds,%ds:\(%esp,%esi,2\)
+ 982 1393 8C1C7500 000000 mov %ds,%ds:\(,%esi,2\)
+ 983 139a 8C1C76 mov %ds,%ds:\(%esi,%esi,2\)
+ 984 139d 8C1C77 mov %ds,%ds:\(%edi,%esi,2\)
+ 985 13a0 8C1C78 mov %ds,%ds:\(%eax,%edi,2\)
+ 986 13a3 8C1C79 mov %ds,%ds:\(%ecx,%edi,2\)
+ 987 13a6 8C1C7A mov %ds,%ds:\(%edx,%edi,2\)
+ 988 13a9 8C1C7B mov %ds,%ds:\(%ebx,%edi,2\)
+ 989 13ac 3E8C1C7C mov %ds,%ds:\(%esp,%edi,2\)
+ 990 13b0 8C1C7D00 000000 mov %ds,%ds:\(,%edi,2\)
+ 991 13b7 8C1C7E mov %ds,%ds:\(%esi,%edi,2\)
+ 992 13ba 8C1C7F mov %ds,%ds:\(%edi,%edi,2\)
+ 993 13bd 8C1C80 mov %ds,%ds:\(%eax,%eax,4\)
+ 994 13c0 8C1C81 mov %ds,%ds:\(%ecx,%eax,4\)
+ 995 13c3 8C1C82 mov %ds,%ds:\(%edx,%eax,4\)
+ 996 13c6 8C1C83 mov %ds,%ds:\(%ebx,%eax,4\)
+ 997 13c9 3E8C1C84 mov %ds,%ds:\(%esp,%eax,4\)
+ 998 13cd 8C1C8500 000000 mov %ds,%ds:\(,%eax,4\)
+ 999 13d4 8C1C86 mov %ds,%ds:\(%esi,%eax,4\)
+ 1000 13d7 8C1C87 mov %ds,%ds:\(%edi,%eax,4\)
+ 1001 13da 8C1C88 mov %ds,%ds:\(%eax,%ecx,4\)
+ 1002 13dd 8C1C89 mov %ds,%ds:\(%ecx,%ecx,4\)
+ 1003 13e0 8C1C8A mov %ds,%ds:\(%edx,%ecx,4\)
+ 1004 13e3 8C1C8B mov %ds,%ds:\(%ebx,%ecx,4\)
+ 1005 13e6 3E8C1C8C mov %ds,%ds:\(%esp,%ecx,4\)
+ 1006 13ea 8C1C8D00 000000 mov %ds,%ds:\(,%ecx,4\)
+ 1007 13f1 8C1C8E mov %ds,%ds:\(%esi,%ecx,4\)
+ 1008 13f4 8C1C8F mov %ds,%ds:\(%edi,%ecx,4\)
+ 1009 13f7 8C1C90 mov %ds,%ds:\(%eax,%edx,4\)
+ 1010 13fa 8C1C91 mov %ds,%ds:\(%ecx,%edx,4\)
+ 1011 13fd 8C1C92 mov %ds,%ds:\(%edx,%edx,4\)
+ 1012 1400 8C1C93 mov %ds,%ds:\(%ebx,%edx,4\)
+ 1013 1403 3E8C1C94 mov %ds,%ds:\(%esp,%edx,4\)
+ 1014 1407 8C1C9500 000000 mov %ds,%ds:\(,%edx,4\)
+ 1015 140e 8C1C96 mov %ds,%ds:\(%esi,%edx,4\)
+ 1016 1411 8C1C97 mov %ds,%ds:\(%edi,%edx,4\)
+ 1017 1414 8C1C98 mov %ds,%ds:\(%eax,%ebx,4\)
+ 1018 1417 8C1C99 mov %ds,%ds:\(%ecx,%ebx,4\)
+ 1019 141a 8C1C9A mov %ds,%ds:\(%edx,%ebx,4\)
+ 1020 141d 8C1C9B mov %ds,%ds:\(%ebx,%ebx,4\)
+ 1021 1420 3E8C1C9C mov %ds,%ds:\(%esp,%ebx,4\)
+ 1022 1424 8C1C9D00 000000 mov %ds,%ds:\(,%ebx,4\)
+ 1023 142b 8C1C9E mov %ds,%ds:\(%esi,%ebx,4\)
+ 1024 142e 8C1C9F mov %ds,%ds:\(%edi,%ebx,4\)
+ 1025 1431 8C18 mov %ds,%ds:\(%eax,4\)
+.*Warning:.*
+ 1026 1433 8C19 mov %ds,%ds:\(%ecx,4\)
+.*Warning:.*
+ 1027 1435 8C1A mov %ds,%ds:\(%edx,4\)
+.*Warning:.*
+ 1028 1437 8C1B mov %ds,%ds:\(%ebx,4\)
+.*Warning:.*
+ 1029 1439 3E8C1C24 mov %ds,%ds:\(%esp,4\)
+.*Warning:.*
+ 1030 143d 8C1D0000 0000 mov %ds,%ds:\(,4\)
+.*Warning:.*
+ 1031 1443 8C1E mov %ds,%ds:\(%esi,4\)
+.*Warning:.*
+ 1032 1445 8C1F mov %ds,%ds:\(%edi,4\)
+.*Warning:.*
+ 1033 1447 8C1CA8 mov %ds,%ds:\(%eax,%ebp,4\)
+ 1034 144a 8C1CA9 mov %ds,%ds:\(%ecx,%ebp,4\)
+ 1035 144d 8C1CAA mov %ds,%ds:\(%edx,%ebp,4\)
+ 1036 1450 8C1CAB mov %ds,%ds:\(%ebx,%ebp,4\)
+ 1037 1453 3E8C1CAC mov %ds,%ds:\(%esp,%ebp,4\)
+ 1038 1457 8C1CAD00 000000 mov %ds,%ds:\(,%ebp,4\)
+ 1039 145e 8C1CAE mov %ds,%ds:\(%esi,%ebp,4\)
+ 1040 1461 8C1CAF mov %ds,%ds:\(%edi,%ebp,4\)
+ 1041 1464 8C1CB0 mov %ds,%ds:\(%eax,%esi,4\)
+ 1042 1467 8C1CB1 mov %ds,%ds:\(%ecx,%esi,4\)
+ 1043 146a 8C1CB2 mov %ds,%ds:\(%edx,%esi,4\)
+ 1044 146d 8C1CB3 mov %ds,%ds:\(%ebx,%esi,4\)
+ 1045 1470 3E8C1CB4 mov %ds,%ds:\(%esp,%esi,4\)
+ 1046 1474 8C1CB500 000000 mov %ds,%ds:\(,%esi,4\)
+ 1047 147b 8C1CB6 mov %ds,%ds:\(%esi,%esi,4\)
+ 1048 147e 8C1CB7 mov %ds,%ds:\(%edi,%esi,4\)
+ 1049 1481 8C1CB8 mov %ds,%ds:\(%eax,%edi,4\)
+ 1050 1484 8C1CB9 mov %ds,%ds:\(%ecx,%edi,4\)
+ 1051 1487 8C1CBA mov %ds,%ds:\(%edx,%edi,4\)
+ 1052 148a 8C1CBB mov %ds,%ds:\(%ebx,%edi,4\)
+ 1053 148d 3E8C1CBC mov %ds,%ds:\(%esp,%edi,4\)
+ 1054 1491 8C1CBD00 000000 mov %ds,%ds:\(,%edi,4\)
+ 1055 1498 8C1CBE mov %ds,%ds:\(%esi,%edi,4\)
+ 1056 149b 8C1CBF mov %ds,%ds:\(%edi,%edi,4\)
+ 1057 149e 8C1CC0 mov %ds,%ds:\(%eax,%eax,8\)
+ 1058 14a1 8C1CC1 mov %ds,%ds:\(%ecx,%eax,8\)
+ 1059 14a4 8C1CC2 mov %ds,%ds:\(%edx,%eax,8\)
+ 1060 14a7 8C1CC3 mov %ds,%ds:\(%ebx,%eax,8\)
+ 1061 14aa 3E8C1CC4 mov %ds,%ds:\(%esp,%eax,8\)
+ 1062 14ae 8C1CC500 000000 mov %ds,%ds:\(,%eax,8\)
+ 1063 14b5 8C1CC6 mov %ds,%ds:\(%esi,%eax,8\)
+ 1064 14b8 8C1CC7 mov %ds,%ds:\(%edi,%eax,8\)
+ 1065 14bb 8C1CC8 mov %ds,%ds:\(%eax,%ecx,8\)
+ 1066 14be 8C1CC9 mov %ds,%ds:\(%ecx,%ecx,8\)
+ 1067 14c1 8C1CCA mov %ds,%ds:\(%edx,%ecx,8\)
+ 1068 14c4 8C1CCB mov %ds,%ds:\(%ebx,%ecx,8\)
+ 1069 14c7 3E8C1CCC mov %ds,%ds:\(%esp,%ecx,8\)
+ 1070 14cb 8C1CCD00 000000 mov %ds,%ds:\(,%ecx,8\)
+ 1071 14d2 8C1CCE mov %ds,%ds:\(%esi,%ecx,8\)
+ 1072 14d5 8C1CCF mov %ds,%ds:\(%edi,%ecx,8\)
+ 1073 14d8 8C1CD0 mov %ds,%ds:\(%eax,%edx,8\)
+ 1074 14db 8C1CD1 mov %ds,%ds:\(%ecx,%edx,8\)
+ 1075 14de 8C1CD2 mov %ds,%ds:\(%edx,%edx,8\)
+ 1076 14e1 8C1CD3 mov %ds,%ds:\(%ebx,%edx,8\)
+ 1077 14e4 3E8C1CD4 mov %ds,%ds:\(%esp,%edx,8\)
+ 1078 14e8 8C1CD500 000000 mov %ds,%ds:\(,%edx,8\)
+ 1079 14ef 8C1CD6 mov %ds,%ds:\(%esi,%edx,8\)
+ 1080 14f2 8C1CD7 mov %ds,%ds:\(%edi,%edx,8\)
+ 1081 14f5 8C1CD8 mov %ds,%ds:\(%eax,%ebx,8\)
+ 1082 14f8 8C1CD9 mov %ds,%ds:\(%ecx,%ebx,8\)
+ 1083 14fb 8C1CDA mov %ds,%ds:\(%edx,%ebx,8\)
+ 1084 14fe 8C1CDB mov %ds,%ds:\(%ebx,%ebx,8\)
+ 1085 1501 3E8C1CDC mov %ds,%ds:\(%esp,%ebx,8\)
+ 1086 1505 8C1CDD00 000000 mov %ds,%ds:\(,%ebx,8\)
+ 1087 150c 8C1CDE mov %ds,%ds:\(%esi,%ebx,8\)
+ 1088 150f 8C1CDF mov %ds,%ds:\(%edi,%ebx,8\)
+ 1089 1512 8C18 mov %ds,%ds:\(%eax,8\)
+.*Warning:.*
+ 1090 1514 8C19 mov %ds,%ds:\(%ecx,8\)
+.*Warning:.*
+ 1091 1516 8C1A mov %ds,%ds:\(%edx,8\)
+.*Warning:.*
+ 1092 1518 8C1B mov %ds,%ds:\(%ebx,8\)
+.*Warning:.*
+ 1093 151a 3E8C1C24 mov %ds,%ds:\(%esp,8\)
+.*Warning:.*
+ 1094 151e 8C1D0000 0000 mov %ds,%ds:\(,8\)
+.*Warning:.*
+ 1095 1524 8C1E mov %ds,%ds:\(%esi,8\)
+.*Warning:.*
+ 1096 1526 8C1F mov %ds,%ds:\(%edi,8\)
+.*Warning:.*
+ 1097 1528 8C1CE8 mov %ds,%ds:\(%eax,%ebp,8\)
+ 1098 152b 8C1CE9 mov %ds,%ds:\(%ecx,%ebp,8\)
+ 1099 152e 8C1CEA mov %ds,%ds:\(%edx,%ebp,8\)
+ 1100 1531 8C1CEB mov %ds,%ds:\(%ebx,%ebp,8\)
+ 1101 1534 3E8C1CEC mov %ds,%ds:\(%esp,%ebp,8\)
+ 1102 1538 8C1CED00 000000 mov %ds,%ds:\(,%ebp,8\)
+ 1103 153f 8C1CEE mov %ds,%ds:\(%esi,%ebp,8\)
+ 1104 1542 8C1CEF mov %ds,%ds:\(%edi,%ebp,8\)
+ 1105 1545 8C1CF0 mov %ds,%ds:\(%eax,%esi,8\)
+ 1106 1548 8C1CF1 mov %ds,%ds:\(%ecx,%esi,8\)
+ 1107 154b 8C1CF2 mov %ds,%ds:\(%edx,%esi,8\)
+ 1108 154e 8C1CF3 mov %ds,%ds:\(%ebx,%esi,8\)
+ 1109 1551 3E8C1CF4 mov %ds,%ds:\(%esp,%esi,8\)
+ 1110 1555 8C1CF500 000000 mov %ds,%ds:\(,%esi,8\)
+ 1111 155c 8C1CF6 mov %ds,%ds:\(%esi,%esi,8\)
+ 1112 155f 8C1CF7 mov %ds,%ds:\(%edi,%esi,8\)
+ 1113 1562 8C1CF8 mov %ds,%ds:\(%eax,%edi,8\)
+ 1114 1565 8C1CFA mov %ds,%ds:\(%edx,%edi,8\)
+ 1115 1568 8C1CF9 mov %ds,%ds:\(%ecx,%edi,8\)
+ 1116 156b 8C1CFB mov %ds,%ds:\(%ebx,%edi,8\)
+ 1117 156e 3E8C1CFC mov %ds,%ds:\(%esp,%edi,8\)
+ 1118 1572 8C1CFD00 000000 mov %ds,%ds:\(,%edi,8\)
+ 1119 1579 8C1CFE mov %ds,%ds:\(%esi,%edi,8\)
+ 1120 157c 8C1CFF mov %ds,%ds:\(%edi,%edi,8\)
+ 1121 157f 8C5C0012 mov %ds,%ds:0x12\(%eax,%eax,1\)
+ 1122 1583 8C5C0112 mov %ds,%ds:0x12\(%ecx,%eax,1\)
+ 1123 1587 8C5C0212 mov %ds,%ds:0x12\(%edx,%eax,1\)
+ 1124 158b 8C5C0312 mov %ds,%ds:0x12\(%ebx,%eax,1\)
+ 1125 158f 3E8C5C04 12 mov %ds,%ds:0x12\(%esp,%eax,1\)
+ 1126 1594 3E8C5C05 12 mov %ds,%ds:0x12\(%ebp,%eax,1\)
+ 1127 1599 8C5C0612 mov %ds,%ds:0x12\(%esi,%eax,1\)
+ 1128 159d 8C5C0712 mov %ds,%ds:0x12\(%edi,%eax,1\)
+ 1129 15a1 8C5C0812 mov %ds,%ds:0x12\(%eax,%ecx,1\)
+ 1130 15a5 8C5C0912 mov %ds,%ds:0x12\(%ecx,%ecx,1\)
+ 1131 15a9 8C5C0A12 mov %ds,%ds:0x12\(%edx,%ecx,1\)
+ 1132 15ad 8C5C0B12 mov %ds,%ds:0x12\(%ebx,%ecx,1\)
+ 1133 15b1 3E8C5C0C 12 mov %ds,%ds:0x12\(%esp,%ecx,1\)
+ 1134 15b6 3E8C5C0D 12 mov %ds,%ds:0x12\(%ebp,%ecx,1\)
+ 1135 15bb 8C5C0E12 mov %ds,%ds:0x12\(%esi,%ecx,1\)
+ 1136 15bf 8C5C0F12 mov %ds,%ds:0x12\(%edi,%ecx,1\)
+ 1137 15c3 8C5C1012 mov %ds,%ds:0x12\(%eax,%edx,1\)
+ 1138 15c7 8C5C1112 mov %ds,%ds:0x12\(%ecx,%edx,1\)
+ 1139 15cb 8C5C1212 mov %ds,%ds:0x12\(%edx,%edx,1\)
+ 1140 15cf 8C5C1312 mov %ds,%ds:0x12\(%ebx,%edx,1\)
+ 1141 15d3 3E8C5C14 12 mov %ds,%ds:0x12\(%esp,%edx,1\)
+ 1142 15d8 3E8C5C15 12 mov %ds,%ds:0x12\(%ebp,%edx,1\)
+ 1143 15dd 8C5C1612 mov %ds,%ds:0x12\(%esi,%edx,1\)
+ 1144 15e1 8C5C1712 mov %ds,%ds:0x12\(%edi,%edx,1\)
+ 1145 15e5 8C5C1812 mov %ds,%ds:0x12\(%eax,%ebx,1\)
+ 1146 15e9 8C5C1912 mov %ds,%ds:0x12\(%ecx,%ebx,1\)
+ 1147 15ed 8C5C1A12 mov %ds,%ds:0x12\(%edx,%ebx,1\)
+ 1148 15f1 8C5C1B12 mov %ds,%ds:0x12\(%ebx,%ebx,1\)
+ 1149 15f5 3E8C5C1C 12 mov %ds,%ds:0x12\(%esp,%ebx,1\)
+ 1150 15fa 3E8C5C1D 12 mov %ds,%ds:0x12\(%ebp,%ebx,1\)
+ 1151 15ff 8C5C1E12 mov %ds,%ds:0x12\(%esi,%ebx,1\)
+ 1152 1603 8C5C1F12 mov %ds,%ds:0x12\(%edi,%ebx,1\)
+ 1153 1607 8C5812 mov %ds,%ds:0x12\(%eax,1\)
+ 1154 160a 8C5912 mov %ds,%ds:0x12\(%ecx,1\)
+ 1155 160d 8C5A12 mov %ds,%ds:0x12\(%edx,1\)
+ 1156 1610 8C5B12 mov %ds,%ds:0x12\(%ebx,1\)
+ 1157 1613 3E8C5C24 12 mov %ds,%ds:0x12\(%esp,1\)
+ 1158 1618 3E8C5D12 mov %ds,%ds:0x12\(%ebp,1\)
+ 1159 161c 8C5E12 mov %ds,%ds:0x12\(%esi,1\)
+ 1160 161f 8C5F12 mov %ds,%ds:0x12\(%edi,1\)
+ 1161 1622 8C5C2812 mov %ds,%ds:0x12\(%eax,%ebp,1\)
+ 1162 1626 8C5C2912 mov %ds,%ds:0x12\(%ecx,%ebp,1\)
+ 1163 162a 8C5C2A12 mov %ds,%ds:0x12\(%edx,%ebp,1\)
+ 1164 162e 8C5C2B12 mov %ds,%ds:0x12\(%ebx,%ebp,1\)
+ 1165 1632 3E8C5C2C 12 mov %ds,%ds:0x12\(%esp,%ebp,1\)
+ 1166 1637 3E8C5C2D 12 mov %ds,%ds:0x12\(%ebp,%ebp,1\)
+ 1167 163c 8C5C2E12 mov %ds,%ds:0x12\(%esi,%ebp,1\)
+ 1168 1640 8C5C2F12 mov %ds,%ds:0x12\(%edi,%ebp,1\)
+ 1169 1644 8C5C3012 mov %ds,%ds:0x12\(%eax,%esi,1\)
+ 1170 1648 8C5C3112 mov %ds,%ds:0x12\(%ecx,%esi,1\)
+ 1171 164c 8C5C3212 mov %ds,%ds:0x12\(%edx,%esi,1\)
+ 1172 1650 8C5C3312 mov %ds,%ds:0x12\(%ebx,%esi,1\)
+ 1173 1654 3E8C5C34 12 mov %ds,%ds:0x12\(%esp,%esi,1\)
+ 1174 1659 3E8C5C35 12 mov %ds,%ds:0x12\(%ebp,%esi,1\)
+ 1175 165e 8C5C3612 mov %ds,%ds:0x12\(%esi,%esi,1\)
+ 1176 1662 8C5C3712 mov %ds,%ds:0x12\(%edi,%esi,1\)
+ 1177 1666 8C5C3812 mov %ds,%ds:0x12\(%eax,%edi,1\)
+ 1178 166a 8C5C3912 mov %ds,%ds:0x12\(%ecx,%edi,1\)
+ 1179 166e 8C5C3A12 mov %ds,%ds:0x12\(%edx,%edi,1\)
+ 1180 1672 8C5C3B12 mov %ds,%ds:0x12\(%ebx,%edi,1\)
+ 1181 1676 3E8C5C3C 12 mov %ds,%ds:0x12\(%esp,%edi,1\)
+ 1182 167b 3E8C5C3D 12 mov %ds,%ds:0x12\(%ebp,%edi,1\)
+ 1183 1680 8C5C3E12 mov %ds,%ds:0x12\(%esi,%edi,1\)
+ 1184 1684 8C5C3F12 mov %ds,%ds:0x12\(%edi,%edi,1\)
+ 1185 1688 8C5C4012 mov %ds,%ds:0x12\(%eax,%eax,2\)
+ 1186 168c 8C5C4112 mov %ds,%ds:0x12\(%ecx,%eax,2\)
+ 1187 1690 8C5C4212 mov %ds,%ds:0x12\(%edx,%eax,2\)
+ 1188 1694 8C5C4312 mov %ds,%ds:0x12\(%ebx,%eax,2\)
+ 1189 1698 3E8C5C44 12 mov %ds,%ds:0x12\(%esp,%eax,2\)
+ 1190 169d 3E8C5C45 12 mov %ds,%ds:0x12\(%ebp,%eax,2\)
+ 1191 16a2 8C5C4612 mov %ds,%ds:0x12\(%esi,%eax,2\)
+ 1192 16a6 8C5C4712 mov %ds,%ds:0x12\(%edi,%eax,2\)
+ 1193 16aa 8C5C4812 mov %ds,%ds:0x12\(%eax,%ecx,2\)
+ 1194 16ae 8C5C4912 mov %ds,%ds:0x12\(%ecx,%ecx,2\)
+ 1195 16b2 8C5C4A12 mov %ds,%ds:0x12\(%edx,%ecx,2\)
+ 1196 16b6 8C5C4B12 mov %ds,%ds:0x12\(%ebx,%ecx,2\)
+ 1197 16ba 3E8C5C4C 12 mov %ds,%ds:0x12\(%esp,%ecx,2\)
+ 1198 16bf 3E8C5C4D 12 mov %ds,%ds:0x12\(%ebp,%ecx,2\)
+ 1199 16c4 8C5C4E12 mov %ds,%ds:0x12\(%esi,%ecx,2\)
+ 1200 16c8 8C5C4F12 mov %ds,%ds:0x12\(%edi,%ecx,2\)
+ 1201 16cc 8C5C5012 mov %ds,%ds:0x12\(%eax,%edx,2\)
+ 1202 16d0 8C5C5112 mov %ds,%ds:0x12\(%ecx,%edx,2\)
+ 1203 16d4 8C5C5212 mov %ds,%ds:0x12\(%edx,%edx,2\)
+ 1204 16d8 8C5C5312 mov %ds,%ds:0x12\(%ebx,%edx,2\)
+ 1205 16dc 3E8C5C54 12 mov %ds,%ds:0x12\(%esp,%edx,2\)
+ 1206 16e1 3E8C5C55 12 mov %ds,%ds:0x12\(%ebp,%edx,2\)
+ 1207 16e6 8C5C5612 mov %ds,%ds:0x12\(%esi,%edx,2\)
+ 1208 16ea 8C5C5712 mov %ds,%ds:0x12\(%edi,%edx,2\)
+ 1209 16ee 8C5C5812 mov %ds,%ds:0x12\(%eax,%ebx,2\)
+ 1210 16f2 8C5C5912 mov %ds,%ds:0x12\(%ecx,%ebx,2\)
+ 1211 16f6 8C5C5A12 mov %ds,%ds:0x12\(%edx,%ebx,2\)
+ 1212 16fa 8C5C5B12 mov %ds,%ds:0x12\(%ebx,%ebx,2\)
+ 1213 16fe 3E8C5C5C 12 mov %ds,%ds:0x12\(%esp,%ebx,2\)
+ 1214 1703 3E8C5C5D 12 mov %ds,%ds:0x12\(%ebp,%ebx,2\)
+ 1215 1708 8C5C5E12 mov %ds,%ds:0x12\(%esi,%ebx,2\)
+ 1216 170c 8C5C5F12 mov %ds,%ds:0x12\(%edi,%ebx,2\)
+ 1217 1710 8C5812 mov %ds,%ds:0x12\(%eax,2\)
+.*Warning:.*
+ 1218 1713 8C5912 mov %ds,%ds:0x12\(%ecx,2\)
+.*Warning:.*
+ 1219 1716 8C5A12 mov %ds,%ds:0x12\(%edx,2\)
+.*Warning:.*
+ 1220 1719 8C5B12 mov %ds,%ds:0x12\(%ebx,2\)
+.*Warning:.*
+ 1221 171c 3E8C5C24 12 mov %ds,%ds:0x12\(%esp,2\)
+.*Warning:.*
+ 1222 1721 3E8C5D12 mov %ds,%ds:0x12\(%ebp,2\)
+.*Warning:.*
+ 1223 1725 8C5E12 mov %ds,%ds:0x12\(%esi,2\)
+.*Warning:.*
+ 1224 1728 8C5F12 mov %ds,%ds:0x12\(%edi,2\)
+.*Warning:.*
+ 1225 172b 8C5C6812 mov %ds,%ds:0x12\(%eax,%ebp,2\)
+ 1226 172f 8C5C6912 mov %ds,%ds:0x12\(%ecx,%ebp,2\)
+ 1227 1733 8C5C6A12 mov %ds,%ds:0x12\(%edx,%ebp,2\)
+ 1228 1737 8C5C6B12 mov %ds,%ds:0x12\(%ebx,%ebp,2\)
+ 1229 173b 3E8C5C6C 12 mov %ds,%ds:0x12\(%esp,%ebp,2\)
+ 1230 1740 3E8C5C6D 12 mov %ds,%ds:0x12\(%ebp,%ebp,2\)
+ 1231 1745 8C5C6E12 mov %ds,%ds:0x12\(%esi,%ebp,2\)
+ 1232 1749 8C5C6F12 mov %ds,%ds:0x12\(%edi,%ebp,2\)
+ 1233 174d 8C5C7012 mov %ds,%ds:0x12\(%eax,%esi,2\)
+ 1234 1751 8C5C7112 mov %ds,%ds:0x12\(%ecx,%esi,2\)
+ 1235 1755 8C5C7212 mov %ds,%ds:0x12\(%edx,%esi,2\)
+ 1236 1759 8C5C7312 mov %ds,%ds:0x12\(%ebx,%esi,2\)
+ 1237 175d 3E8C5C74 12 mov %ds,%ds:0x12\(%esp,%esi,2\)
+ 1238 1762 3E8C5C75 12 mov %ds,%ds:0x12\(%ebp,%esi,2\)
+ 1239 1767 8C5C7612 mov %ds,%ds:0x12\(%esi,%esi,2\)
+ 1240 176b 8C5C7712 mov %ds,%ds:0x12\(%edi,%esi,2\)
+ 1241 176f 8C5C7812 mov %ds,%ds:0x12\(%eax,%edi,2\)
+ 1242 1773 8C5C7912 mov %ds,%ds:0x12\(%ecx,%edi,2\)
+ 1243 1777 8C5C7A12 mov %ds,%ds:0x12\(%edx,%edi,2\)
+ 1244 177b 8C5C7B12 mov %ds,%ds:0x12\(%ebx,%edi,2\)
+ 1245 177f 3E8C5C7C 12 mov %ds,%ds:0x12\(%esp,%edi,2\)
+ 1246 1784 3E8C5C7D 12 mov %ds,%ds:0x12\(%ebp,%edi,2\)
+ 1247 1789 8C5C7E12 mov %ds,%ds:0x12\(%esi,%edi,2\)
+ 1248 178d 8C5C7F12 mov %ds,%ds:0x12\(%edi,%edi,2\)
+ 1249 1791 8C5C8012 mov %ds,%ds:0x12\(%eax,%eax,4\)
+ 1250 1795 8C5C8112 mov %ds,%ds:0x12\(%ecx,%eax,4\)
+ 1251 1799 8C5C8212 mov %ds,%ds:0x12\(%edx,%eax,4\)
+ 1252 179d 8C5C8312 mov %ds,%ds:0x12\(%ebx,%eax,4\)
+ 1253 17a1 3E8C5C84 12 mov %ds,%ds:0x12\(%esp,%eax,4\)
+ 1254 17a6 3E8C5C85 12 mov %ds,%ds:0x12\(%ebp,%eax,4\)
+ 1255 17ab 8C5C8612 mov %ds,%ds:0x12\(%esi,%eax,4\)
+ 1256 17af 8C5C8712 mov %ds,%ds:0x12\(%edi,%eax,4\)
+ 1257 17b3 8C5C8812 mov %ds,%ds:0x12\(%eax,%ecx,4\)
+ 1258 17b7 8C5C8912 mov %ds,%ds:0x12\(%ecx,%ecx,4\)
+ 1259 17bb 8C5C8A12 mov %ds,%ds:0x12\(%edx,%ecx,4\)
+ 1260 17bf 8C5C8B12 mov %ds,%ds:0x12\(%ebx,%ecx,4\)
+ 1261 17c3 3E8C5C8C 12 mov %ds,%ds:0x12\(%esp,%ecx,4\)
+ 1262 17c8 3E8C5C8D 12 mov %ds,%ds:0x12\(%ebp,%ecx,4\)
+ 1263 17cd 8C5C8E12 mov %ds,%ds:0x12\(%esi,%ecx,4\)
+ 1264 17d1 8C5C8F12 mov %ds,%ds:0x12\(%edi,%ecx,4\)
+ 1265 17d5 8C5C9012 mov %ds,%ds:0x12\(%eax,%edx,4\)
+ 1266 17d9 8C5C9112 mov %ds,%ds:0x12\(%ecx,%edx,4\)
+ 1267 17dd 8C5C9212 mov %ds,%ds:0x12\(%edx,%edx,4\)
+ 1268 17e1 8C5C9312 mov %ds,%ds:0x12\(%ebx,%edx,4\)
+ 1269 17e5 3E8C5C94 12 mov %ds,%ds:0x12\(%esp,%edx,4\)
+ 1270 17ea 3E8C5C95 12 mov %ds,%ds:0x12\(%ebp,%edx,4\)
+ 1271 17ef 8C5C9612 mov %ds,%ds:0x12\(%esi,%edx,4\)
+ 1272 17f3 8C5C9712 mov %ds,%ds:0x12\(%edi,%edx,4\)
+ 1273 17f7 8C5C9812 mov %ds,%ds:0x12\(%eax,%ebx,4\)
+ 1274 17fb 8C5C9912 mov %ds,%ds:0x12\(%ecx,%ebx,4\)
+ 1275 17ff 8C5C9A12 mov %ds,%ds:0x12\(%edx,%ebx,4\)
+ 1276 1803 8C5C9B12 mov %ds,%ds:0x12\(%ebx,%ebx,4\)
+ 1277 1807 3E8C5C9C 12 mov %ds,%ds:0x12\(%esp,%ebx,4\)
+ 1278 180c 3E8C5C9D 12 mov %ds,%ds:0x12\(%ebp,%ebx,4\)
+ 1279 1811 8C5C9E12 mov %ds,%ds:0x12\(%esi,%ebx,4\)
+ 1280 1815 8C5C9F12 mov %ds,%ds:0x12\(%edi,%ebx,4\)
+ 1281 1819 8C5812 mov %ds,%ds:0x12\(%eax,4\)
+.*Warning:.*
+ 1282 181c 8C5912 mov %ds,%ds:0x12\(%ecx,4\)
+.*Warning:.*
+ 1283 181f 8C5A12 mov %ds,%ds:0x12\(%edx,4\)
+.*Warning:.*
+ 1284 1822 8C5B12 mov %ds,%ds:0x12\(%ebx,4\)
+.*Warning:.*
+ 1285 1825 3E8C5C24 12 mov %ds,%ds:0x12\(%esp,4\)
+.*Warning:.*
+ 1286 182a 3E8C5D12 mov %ds,%ds:0x12\(%ebp,4\)
+.*Warning:.*
+ 1287 182e 8C5E12 mov %ds,%ds:0x12\(%esi,4\)
+.*Warning:.*
+ 1288 1831 8C5F12 mov %ds,%ds:0x12\(%edi,4\)
+.*Warning:.*
+ 1289 1834 8C5CA812 mov %ds,%ds:0x12\(%eax,%ebp,4\)
+ 1290 1838 8C5CA912 mov %ds,%ds:0x12\(%ecx,%ebp,4\)
+ 1291 183c 8C5CAA12 mov %ds,%ds:0x12\(%edx,%ebp,4\)
+ 1292 1840 8C5CAB12 mov %ds,%ds:0x12\(%ebx,%ebp,4\)
+ 1293 1844 3E8C5CAC 12 mov %ds,%ds:0x12\(%esp,%ebp,4\)
+ 1294 1849 3E8C5CAD 12 mov %ds,%ds:0x12\(%ebp,%ebp,4\)
+ 1295 184e 8C5CAE12 mov %ds,%ds:0x12\(%esi,%ebp,4\)
+ 1296 1852 8C5CAF12 mov %ds,%ds:0x12\(%edi,%ebp,4\)
+ 1297 1856 8C5CB012 mov %ds,%ds:0x12\(%eax,%esi,4\)
+ 1298 185a 8C5CB112 mov %ds,%ds:0x12\(%ecx,%esi,4\)
+ 1299 185e 8C5CB212 mov %ds,%ds:0x12\(%edx,%esi,4\)
+ 1300 1862 8C5CB312 mov %ds,%ds:0x12\(%ebx,%esi,4\)
+ 1301 1866 3E8C5CB4 12 mov %ds,%ds:0x12\(%esp,%esi,4\)
+ 1302 186b 3E8C5CB5 12 mov %ds,%ds:0x12\(%ebp,%esi,4\)
+ 1303 1870 8C5CB612 mov %ds,%ds:0x12\(%esi,%esi,4\)
+ 1304 1874 8C5CB712 mov %ds,%ds:0x12\(%edi,%esi,4\)
+ 1305 1878 8C5CB812 mov %ds,%ds:0x12\(%eax,%edi,4\)
+ 1306 187c 8C5CB912 mov %ds,%ds:0x12\(%ecx,%edi,4\)
+ 1307 1880 8C5CBA12 mov %ds,%ds:0x12\(%edx,%edi,4\)
+ 1308 1884 8C5CBB12 mov %ds,%ds:0x12\(%ebx,%edi,4\)
+ 1309 1888 3E8C5CBC 12 mov %ds,%ds:0x12\(%esp,%edi,4\)
+ 1310 188d 3E8C5CBD 12 mov %ds,%ds:0x12\(%ebp,%edi,4\)
+ 1311 1892 8C5CBE12 mov %ds,%ds:0x12\(%esi,%edi,4\)
+ 1312 1896 8C5CBF12 mov %ds,%ds:0x12\(%edi,%edi,4\)
+ 1313 189a 8C5CC012 mov %ds,%ds:0x12\(%eax,%eax,8\)
+ 1314 189e 8C5CC112 mov %ds,%ds:0x12\(%ecx,%eax,8\)
+ 1315 18a2 8C5CC212 mov %ds,%ds:0x12\(%edx,%eax,8\)
+ 1316 18a6 8C5CC312 mov %ds,%ds:0x12\(%ebx,%eax,8\)
+ 1317 18aa 3E8C5CC4 12 mov %ds,%ds:0x12\(%esp,%eax,8\)
+ 1318 18af 3E8C5CC5 12 mov %ds,%ds:0x12\(%ebp,%eax,8\)
+ 1319 18b4 8C5CC612 mov %ds,%ds:0x12\(%esi,%eax,8\)
+ 1320 18b8 8C5CC712 mov %ds,%ds:0x12\(%edi,%eax,8\)
+ 1321 18bc 8C5CC812 mov %ds,%ds:0x12\(%eax,%ecx,8\)
+ 1322 18c0 8C5CC912 mov %ds,%ds:0x12\(%ecx,%ecx,8\)
+ 1323 18c4 8C5CCA12 mov %ds,%ds:0x12\(%edx,%ecx,8\)
+ 1324 18c8 8C5CCB12 mov %ds,%ds:0x12\(%ebx,%ecx,8\)
+ 1325 18cc 3E8C5CCC 12 mov %ds,%ds:0x12\(%esp,%ecx,8\)
+ 1326 18d1 3E8C5CCD 12 mov %ds,%ds:0x12\(%ebp,%ecx,8\)
+ 1327 18d6 8C5CCE12 mov %ds,%ds:0x12\(%esi,%ecx,8\)
+ 1328 18da 8C5CCF12 mov %ds,%ds:0x12\(%edi,%ecx,8\)
+ 1329 18de 8C5CD012 mov %ds,%ds:0x12\(%eax,%edx,8\)
+ 1330 18e2 8C5CD112 mov %ds,%ds:0x12\(%ecx,%edx,8\)
+ 1331 18e6 8C5CD212 mov %ds,%ds:0x12\(%edx,%edx,8\)
+ 1332 18ea 8C5CD312 mov %ds,%ds:0x12\(%ebx,%edx,8\)
+ 1333 18ee 3E8C5CD4 12 mov %ds,%ds:0x12\(%esp,%edx,8\)
+ 1334 18f3 3E8C5CD5 12 mov %ds,%ds:0x12\(%ebp,%edx,8\)
+ 1335 18f8 8C5CD612 mov %ds,%ds:0x12\(%esi,%edx,8\)
+ 1336 18fc 8C5CD712 mov %ds,%ds:0x12\(%edi,%edx,8\)
+ 1337 1900 8C5CD812 mov %ds,%ds:0x12\(%eax,%ebx,8\)
+ 1338 1904 8C5CD912 mov %ds,%ds:0x12\(%ecx,%ebx,8\)
+ 1339 1908 8C5CDA12 mov %ds,%ds:0x12\(%edx,%ebx,8\)
+ 1340 190c 8C5CDB12 mov %ds,%ds:0x12\(%ebx,%ebx,8\)
+ 1341 1910 3E8C5CDC 12 mov %ds,%ds:0x12\(%esp,%ebx,8\)
+ 1342 1915 3E8C5CDD 12 mov %ds,%ds:0x12\(%ebp,%ebx,8\)
+ 1343 191a 8C5CDE12 mov %ds,%ds:0x12\(%esi,%ebx,8\)
+ 1344 191e 8C5CDF12 mov %ds,%ds:0x12\(%edi,%ebx,8\)
+ 1345 1922 8C5812 mov %ds,%ds:0x12\(%eax,8\)
+.*Warning:.*
+ 1346 1925 8C5912 mov %ds,%ds:0x12\(%ecx,8\)
+.*Warning:.*
+ 1347 1928 8C5A12 mov %ds,%ds:0x12\(%edx,8\)
+.*Warning:.*
+ 1348 192b 8C5B12 mov %ds,%ds:0x12\(%ebx,8\)
+.*Warning:.*
+ 1349 192e 3E8C5C24 12 mov %ds,%ds:0x12\(%esp,8\)
+.*Warning:.*
+ 1350 1933 3E8C5D12 mov %ds,%ds:0x12\(%ebp,8\)
+.*Warning:.*
+ 1351 1937 8C5E12 mov %ds,%ds:0x12\(%esi,8\)
+.*Warning:.*
+ 1352 193a 8C5F12 mov %ds,%ds:0x12\(%edi,8\)
+.*Warning:.*
+ 1353 193d 8C5CE812 mov %ds,%ds:0x12\(%eax,%ebp,8\)
+ 1354 1941 8C5CE912 mov %ds,%ds:0x12\(%ecx,%ebp,8\)
+ 1355 1945 8C5CEA12 mov %ds,%ds:0x12\(%edx,%ebp,8\)
+ 1356 1949 8C5CEB12 mov %ds,%ds:0x12\(%ebx,%ebp,8\)
+ 1357 194d 3E8C5CEC 12 mov %ds,%ds:0x12\(%esp,%ebp,8\)
+ 1358 1952 3E8C5CED 12 mov %ds,%ds:0x12\(%ebp,%ebp,8\)
+ 1359 1957 8C5CEE12 mov %ds,%ds:0x12\(%esi,%ebp,8\)
+ 1360 195b 8C5CEF12 mov %ds,%ds:0x12\(%edi,%ebp,8\)
+ 1361 195f 8C5CF012 mov %ds,%ds:0x12\(%eax,%esi,8\)
+ 1362 1963 8C5CF112 mov %ds,%ds:0x12\(%ecx,%esi,8\)
+ 1363 1967 8C5CF212 mov %ds,%ds:0x12\(%edx,%esi,8\)
+ 1364 196b 8C5CF312 mov %ds,%ds:0x12\(%ebx,%esi,8\)
+ 1365 196f 3E8C5CF4 12 mov %ds,%ds:0x12\(%esp,%esi,8\)
+ 1366 1974 3E8C5CF5 12 mov %ds,%ds:0x12\(%ebp,%esi,8\)
+ 1367 1979 8C5CF612 mov %ds,%ds:0x12\(%esi,%esi,8\)
+ 1368 197d 8C5CF712 mov %ds,%ds:0x12\(%edi,%esi,8\)
+ 1369 1981 8C5CF812 mov %ds,%ds:0x12\(%eax,%edi,8\)
+ 1370 1985 8C5CFA12 mov %ds,%ds:0x12\(%edx,%edi,8\)
+ 1371 1989 8C5CF912 mov %ds,%ds:0x12\(%ecx,%edi,8\)
+ 1372 198d 8C5CFB12 mov %ds,%ds:0x12\(%ebx,%edi,8\)
+ 1373 1991 3E8C5CFC 12 mov %ds,%ds:0x12\(%esp,%edi,8\)
+ 1374 1996 3E8C5CFD 12 mov %ds,%ds:0x12\(%ebp,%edi,8\)
+ 1375 199b 8C5CFE12 mov %ds,%ds:0x12\(%esi,%edi,8\)
+ 1376 199f 8C5CFF12 mov %ds,%ds:0x12\(%edi,%edi,8\)
+ 1377 19a3 8C9C0078 563412 mov %ds,%ds:0x12345678\(%eax,%eax,1\)
+ 1378 19aa 8C9C0178 563412 mov %ds,%ds:0x12345678\(%ecx,%eax,1\)
+ 1379 19b1 8C9C0278 563412 mov %ds,%ds:0x12345678\(%edx,%eax,1\)
+ 1380 19b8 8C9C0378 563412 mov %ds,%ds:0x12345678\(%ebx,%eax,1\)
+ 1381 19bf 3E8C9C04 78563412 mov %ds,%ds:0x12345678\(%esp,%eax,1\)
+ 1382 19c7 3E8C9C05 78563412 mov %ds,%ds:0x12345678\(%ebp,%eax,1\)
+ 1383 19cf 8C9C0678 563412 mov %ds,%ds:0x12345678\(%esi,%eax,1\)
+ 1384 19d6 8C9C0778 563412 mov %ds,%ds:0x12345678\(%edi,%eax,1\)
+ 1385 19dd 8C9C0878 563412 mov %ds,%ds:0x12345678\(%eax,%ecx,1\)
+ 1386 19e4 8C9C0978 563412 mov %ds,%ds:0x12345678\(%ecx,%ecx,1\)
+ 1387 19eb 8C9C0A78 563412 mov %ds,%ds:0x12345678\(%edx,%ecx,1\)
+ 1388 19f2 8C9C0B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ecx,1\)
+ 1389 19f9 3E8C9C0C 78563412 mov %ds,%ds:0x12345678\(%esp,%ecx,1\)
+ 1390 1a01 3E8C9C0D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ecx,1\)
+ 1391 1a09 8C9C0E78 563412 mov %ds,%ds:0x12345678\(%esi,%ecx,1\)
+ 1392 1a10 8C9C0F78 563412 mov %ds,%ds:0x12345678\(%edi,%ecx,1\)
+ 1393 1a17 8C9C1078 563412 mov %ds,%ds:0x12345678\(%eax,%edx,1\)
+ 1394 1a1e 8C9C1178 563412 mov %ds,%ds:0x12345678\(%ecx,%edx,1\)
+ 1395 1a25 8C9C1278 563412 mov %ds,%ds:0x12345678\(%edx,%edx,1\)
+ 1396 1a2c 8C9C1378 563412 mov %ds,%ds:0x12345678\(%ebx,%edx,1\)
+ 1397 1a33 3E8C9C14 78563412 mov %ds,%ds:0x12345678\(%esp,%edx,1\)
+ 1398 1a3b 3E8C9C15 78563412 mov %ds,%ds:0x12345678\(%ebp,%edx,1\)
+ 1399 1a43 8C9C1678 563412 mov %ds,%ds:0x12345678\(%esi,%edx,1\)
+ 1400 1a4a 8C9C1778 563412 mov %ds,%ds:0x12345678\(%edi,%edx,1\)
+ 1401 1a51 8C9C1878 563412 mov %ds,%ds:0x12345678\(%eax,%ebx,1\)
+ 1402 1a58 8C9C1978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebx,1\)
+ 1403 1a5f 8C9C1A78 563412 mov %ds,%ds:0x12345678\(%edx,%ebx,1\)
+ 1404 1a66 8C9C1B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebx,1\)
+ 1405 1a6d 3E8C9C1C 78563412 mov %ds,%ds:0x12345678\(%esp,%ebx,1\)
+ 1406 1a75 3E8C9C1D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebx,1\)
+ 1407 1a7d 8C9C1E78 563412 mov %ds,%ds:0x12345678\(%esi,%ebx,1\)
+ 1408 1a84 8C9C1F78 563412 mov %ds,%ds:0x12345678\(%edi,%ebx,1\)
+ 1409 1a8b 8C987856 3412 mov %ds,%ds:0x12345678\(%eax,1\)
+ 1410 1a91 8C997856 3412 mov %ds,%ds:0x12345678\(%ecx,1\)
+ 1411 1a97 8C9A7856 3412 mov %ds,%ds:0x12345678\(%edx,1\)
+ 1412 1a9d 8C9B7856 3412 mov %ds,%ds:0x12345678\(%ebx,1\)
+ 1413 1aa3 3E8C9C24 78563412 mov %ds,%ds:0x12345678\(%esp,1\)
+ 1414 1aab 3E8C9D78 563412 mov %ds,%ds:0x12345678\(%ebp,1\)
+ 1415 1ab2 8C9E7856 3412 mov %ds,%ds:0x12345678\(%esi,1\)
+ 1416 1ab8 8C9F7856 3412 mov %ds,%ds:0x12345678\(%edi,1\)
+ 1417 1abe 8C9C2878 563412 mov %ds,%ds:0x12345678\(%eax,%ebp,1\)
+ 1418 1ac5 8C9C2978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebp,1\)
+ 1419 1acc 8C9C2A78 563412 mov %ds,%ds:0x12345678\(%edx,%ebp,1\)
+ 1420 1ad3 8C9C2B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebp,1\)
+ 1421 1ada 3E8C9C2C 78563412 mov %ds,%ds:0x12345678\(%esp,%ebp,1\)
+ 1422 1ae2 3E8C9C2D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebp,1\)
+ 1423 1aea 8C9C2E78 563412 mov %ds,%ds:0x12345678\(%esi,%ebp,1\)
+ 1424 1af1 8C9C2F78 563412 mov %ds,%ds:0x12345678\(%edi,%ebp,1\)
+ 1425 1af8 8C9C3078 563412 mov %ds,%ds:0x12345678\(%eax,%esi,1\)
+ 1426 1aff 8C9C3178 563412 mov %ds,%ds:0x12345678\(%ecx,%esi,1\)
+ 1427 1b06 8C9C3278 563412 mov %ds,%ds:0x12345678\(%edx,%esi,1\)
+ 1428 1b0d 8C9C3378 563412 mov %ds,%ds:0x12345678\(%ebx,%esi,1\)
+ 1429 1b14 3E8C9C34 78563412 mov %ds,%ds:0x12345678\(%esp,%esi,1\)
+ 1430 1b1c 3E8C9C35 78563412 mov %ds,%ds:0x12345678\(%ebp,%esi,1\)
+ 1431 1b24 8C9C3678 563412 mov %ds,%ds:0x12345678\(%esi,%esi,1\)
+ 1432 1b2b 8C9C3778 563412 mov %ds,%ds:0x12345678\(%edi,%esi,1\)
+ 1433 1b32 8C9C3878 563412 mov %ds,%ds:0x12345678\(%eax,%edi,1\)
+ 1434 1b39 8C9C3978 563412 mov %ds,%ds:0x12345678\(%ecx,%edi,1\)
+ 1435 1b40 8C9C3A78 563412 mov %ds,%ds:0x12345678\(%edx,%edi,1\)
+ 1436 1b47 8C9C3B78 563412 mov %ds,%ds:0x12345678\(%ebx,%edi,1\)
+ 1437 1b4e 3E8C9C3C 78563412 mov %ds,%ds:0x12345678\(%esp,%edi,1\)
+ 1438 1b56 3E8C9C3D 78563412 mov %ds,%ds:0x12345678\(%ebp,%edi,1\)
+ 1439 1b5e 8C9C3E78 563412 mov %ds,%ds:0x12345678\(%esi,%edi,1\)
+ 1440 1b65 8C9C3F78 563412 mov %ds,%ds:0x12345678\(%edi,%edi,1\)
+ 1441 1b6c 8C9C4078 563412 mov %ds,%ds:0x12345678\(%eax,%eax,2\)
+ 1442 1b73 8C9C4178 563412 mov %ds,%ds:0x12345678\(%ecx,%eax,2\)
+ 1443 1b7a 8C9C4278 563412 mov %ds,%ds:0x12345678\(%edx,%eax,2\)
+ 1444 1b81 8C9C4378 563412 mov %ds,%ds:0x12345678\(%ebx,%eax,2\)
+ 1445 1b88 3E8C9C44 78563412 mov %ds,%ds:0x12345678\(%esp,%eax,2\)
+ 1446 1b90 3E8C9C45 78563412 mov %ds,%ds:0x12345678\(%ebp,%eax,2\)
+ 1447 1b98 8C9C4678 563412 mov %ds,%ds:0x12345678\(%esi,%eax,2\)
+ 1448 1b9f 8C9C4778 563412 mov %ds,%ds:0x12345678\(%edi,%eax,2\)
+ 1449 1ba6 8C9C4878 563412 mov %ds,%ds:0x12345678\(%eax,%ecx,2\)
+ 1450 1bad 8C9C4978 563412 mov %ds,%ds:0x12345678\(%ecx,%ecx,2\)
+ 1451 1bb4 8C9C4A78 563412 mov %ds,%ds:0x12345678\(%edx,%ecx,2\)
+ 1452 1bbb 8C9C4B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ecx,2\)
+ 1453 1bc2 3E8C9C4C 78563412 mov %ds,%ds:0x12345678\(%esp,%ecx,2\)
+ 1454 1bca 3E8C9C4D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ecx,2\)
+ 1455 1bd2 8C9C4E78 563412 mov %ds,%ds:0x12345678\(%esi,%ecx,2\)
+ 1456 1bd9 8C9C4F78 563412 mov %ds,%ds:0x12345678\(%edi,%ecx,2\)
+ 1457 1be0 8C9C5078 563412 mov %ds,%ds:0x12345678\(%eax,%edx,2\)
+ 1458 1be7 8C9C5178 563412 mov %ds,%ds:0x12345678\(%ecx,%edx,2\)
+ 1459 1bee 8C9C5278 563412 mov %ds,%ds:0x12345678\(%edx,%edx,2\)
+ 1460 1bf5 8C9C5378 563412 mov %ds,%ds:0x12345678\(%ebx,%edx,2\)
+ 1461 1bfc 3E8C9C54 78563412 mov %ds,%ds:0x12345678\(%esp,%edx,2\)
+ 1462 1c04 3E8C9C55 78563412 mov %ds,%ds:0x12345678\(%ebp,%edx,2\)
+ 1463 1c0c 8C9C5678 563412 mov %ds,%ds:0x12345678\(%esi,%edx,2\)
+ 1464 1c13 8C9C5778 563412 mov %ds,%ds:0x12345678\(%edi,%edx,2\)
+ 1465 1c1a 8C9C5878 563412 mov %ds,%ds:0x12345678\(%eax,%ebx,2\)
+ 1466 1c21 8C9C5978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebx,2\)
+ 1467 1c28 8C9C5A78 563412 mov %ds,%ds:0x12345678\(%edx,%ebx,2\)
+ 1468 1c2f 8C9C5B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebx,2\)
+ 1469 1c36 3E8C9C5C 78563412 mov %ds,%ds:0x12345678\(%esp,%ebx,2\)
+ 1470 1c3e 3E8C9C5D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebx,2\)
+ 1471 1c46 8C9C5E78 563412 mov %ds,%ds:0x12345678\(%esi,%ebx,2\)
+ 1472 1c4d 8C9C5F78 563412 mov %ds,%ds:0x12345678\(%edi,%ebx,2\)
+ 1473 1c54 8C987856 3412 mov %ds,%ds:0x12345678\(%eax,2\)
+.*Warning:.*
+ 1474 1c5a 8C997856 3412 mov %ds,%ds:0x12345678\(%ecx,2\)
+.*Warning:.*
+ 1475 1c60 8C9A7856 3412 mov %ds,%ds:0x12345678\(%edx,2\)
+.*Warning:.*
+ 1476 1c66 8C9B7856 3412 mov %ds,%ds:0x12345678\(%ebx,2\)
+.*Warning:.*
+ 1477 1c6c 3E8C9C24 78563412 mov %ds,%ds:0x12345678\(%esp,2\)
+.*Warning:.*
+ 1478 1c74 3E8C9D78 563412 mov %ds,%ds:0x12345678\(%ebp,2\)
+.*Warning:.*
+ 1479 1c7b 8C9E7856 3412 mov %ds,%ds:0x12345678\(%esi,2\)
+.*Warning:.*
+ 1480 1c81 8C9F7856 3412 mov %ds,%ds:0x12345678\(%edi,2\)
+.*Warning:.*
+ 1481 1c87 8C9C6878 563412 mov %ds,%ds:0x12345678\(%eax,%ebp,2\)
+ 1482 1c8e 8C9C6978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebp,2\)
+ 1483 1c95 8C9C6A78 563412 mov %ds,%ds:0x12345678\(%edx,%ebp,2\)
+ 1484 1c9c 8C9C6B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebp,2\)
+ 1485 1ca3 3E8C9C6C 78563412 mov %ds,%ds:0x12345678\(%esp,%ebp,2\)
+ 1486 1cab 3E8C9C6D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebp,2\)
+ 1487 1cb3 8C9C6E78 563412 mov %ds,%ds:0x12345678\(%esi,%ebp,2\)
+ 1488 1cba 8C9C6F78 563412 mov %ds,%ds:0x12345678\(%edi,%ebp,2\)
+ 1489 1cc1 8C9C7078 563412 mov %ds,%ds:0x12345678\(%eax,%esi,2\)
+ 1490 1cc8 8C9C7178 563412 mov %ds,%ds:0x12345678\(%ecx,%esi,2\)
+ 1491 1ccf 8C9C7278 563412 mov %ds,%ds:0x12345678\(%edx,%esi,2\)
+ 1492 1cd6 8C9C7378 563412 mov %ds,%ds:0x12345678\(%ebx,%esi,2\)
+ 1493 1cdd 3E8C9C74 78563412 mov %ds,%ds:0x12345678\(%esp,%esi,2\)
+ 1494 1ce5 3E8C9C75 78563412 mov %ds,%ds:0x12345678\(%ebp,%esi,2\)
+ 1495 1ced 8C9C7678 563412 mov %ds,%ds:0x12345678\(%esi,%esi,2\)
+ 1496 1cf4 8C9C7778 563412 mov %ds,%ds:0x12345678\(%edi,%esi,2\)
+ 1497 1cfb 8C9C7878 563412 mov %ds,%ds:0x12345678\(%eax,%edi,2\)
+ 1498 1d02 8C9C7978 563412 mov %ds,%ds:0x12345678\(%ecx,%edi,2\)
+ 1499 1d09 8C9C7A78 563412 mov %ds,%ds:0x12345678\(%edx,%edi,2\)
+ 1500 1d10 8C9C7B78 563412 mov %ds,%ds:0x12345678\(%ebx,%edi,2\)
+ 1501 1d17 3E8C9C7C 78563412 mov %ds,%ds:0x12345678\(%esp,%edi,2\)
+ 1502 1d1f 3E8C9C7D 78563412 mov %ds,%ds:0x12345678\(%ebp,%edi,2\)
+ 1503 1d27 8C9C7E78 563412 mov %ds,%ds:0x12345678\(%esi,%edi,2\)
+ 1504 1d2e 8C9C7F78 563412 mov %ds,%ds:0x12345678\(%edi,%edi,2\)
+ 1505 1d35 8C9C8078 563412 mov %ds,%ds:0x12345678\(%eax,%eax,4\)
+ 1506 1d3c 8C9C8178 563412 mov %ds,%ds:0x12345678\(%ecx,%eax,4\)
+ 1507 1d43 8C9C8278 563412 mov %ds,%ds:0x12345678\(%edx,%eax,4\)
+ 1508 1d4a 8C9C8378 563412 mov %ds,%ds:0x12345678\(%ebx,%eax,4\)
+ 1509 1d51 3E8C9C84 78563412 mov %ds,%ds:0x12345678\(%esp,%eax,4\)
+ 1510 1d59 3E8C9C85 78563412 mov %ds,%ds:0x12345678\(%ebp,%eax,4\)
+ 1511 1d61 8C9C8678 563412 mov %ds,%ds:0x12345678\(%esi,%eax,4\)
+ 1512 1d68 8C9C8778 563412 mov %ds,%ds:0x12345678\(%edi,%eax,4\)
+ 1513 1d6f 8C9C8878 563412 mov %ds,%ds:0x12345678\(%eax,%ecx,4\)
+ 1514 1d76 8C9C8978 563412 mov %ds,%ds:0x12345678\(%ecx,%ecx,4\)
+ 1515 1d7d 8C9C8A78 563412 mov %ds,%ds:0x12345678\(%edx,%ecx,4\)
+ 1516 1d84 8C9C8B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ecx,4\)
+ 1517 1d8b 3E8C9C8C 78563412 mov %ds,%ds:0x12345678\(%esp,%ecx,4\)
+ 1518 1d93 3E8C9C8D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ecx,4\)
+ 1519 1d9b 8C9C8E78 563412 mov %ds,%ds:0x12345678\(%esi,%ecx,4\)
+ 1520 1da2 8C9C8F78 563412 mov %ds,%ds:0x12345678\(%edi,%ecx,4\)
+ 1521 1da9 8C9C9078 563412 mov %ds,%ds:0x12345678\(%eax,%edx,4\)
+ 1522 1db0 8C9C9178 563412 mov %ds,%ds:0x12345678\(%ecx,%edx,4\)
+ 1523 1db7 8C9C9278 563412 mov %ds,%ds:0x12345678\(%edx,%edx,4\)
+ 1524 1dbe 8C9C9378 563412 mov %ds,%ds:0x12345678\(%ebx,%edx,4\)
+ 1525 1dc5 3E8C9C94 78563412 mov %ds,%ds:0x12345678\(%esp,%edx,4\)
+ 1526 1dcd 3E8C9C95 78563412 mov %ds,%ds:0x12345678\(%ebp,%edx,4\)
+ 1527 1dd5 8C9C9678 563412 mov %ds,%ds:0x12345678\(%esi,%edx,4\)
+ 1528 1ddc 8C9C9778 563412 mov %ds,%ds:0x12345678\(%edi,%edx,4\)
+ 1529 1de3 8C9C9878 563412 mov %ds,%ds:0x12345678\(%eax,%ebx,4\)
+ 1530 1dea 8C9C9978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebx,4\)
+ 1531 1df1 8C9C9A78 563412 mov %ds,%ds:0x12345678\(%edx,%ebx,4\)
+ 1532 1df8 8C9C9B78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebx,4\)
+ 1533 1dff 3E8C9C9C 78563412 mov %ds,%ds:0x12345678\(%esp,%ebx,4\)
+ 1534 1e07 3E8C9C9D 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebx,4\)
+ 1535 1e0f 8C9C9E78 563412 mov %ds,%ds:0x12345678\(%esi,%ebx,4\)
+ 1536 1e16 8C9C9F78 563412 mov %ds,%ds:0x12345678\(%edi,%ebx,4\)
+ 1537 1e1d 8C987856 3412 mov %ds,%ds:0x12345678\(%eax,4\)
+.*Warning:.*
+ 1538 1e23 8C997856 3412 mov %ds,%ds:0x12345678\(%ecx,4\)
+.*Warning:.*
+ 1539 1e29 8C9A7856 3412 mov %ds,%ds:0x12345678\(%edx,4\)
+.*Warning:.*
+ 1540 1e2f 8C9B7856 3412 mov %ds,%ds:0x12345678\(%ebx,4\)
+.*Warning:.*
+ 1541 1e35 3E8C9C24 78563412 mov %ds,%ds:0x12345678\(%esp,4\)
+.*Warning:.*
+ 1542 1e3d 3E8C9D78 563412 mov %ds,%ds:0x12345678\(%ebp,4\)
+.*Warning:.*
+ 1543 1e44 8C9E7856 3412 mov %ds,%ds:0x12345678\(%esi,4\)
+.*Warning:.*
+ 1544 1e4a 8C9F7856 3412 mov %ds,%ds:0x12345678\(%edi,4\)
+.*Warning:.*
+ 1545 1e50 8C9CA878 563412 mov %ds,%ds:0x12345678\(%eax,%ebp,4\)
+ 1546 1e57 8C9CA978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebp,4\)
+ 1547 1e5e 8C9CAA78 563412 mov %ds,%ds:0x12345678\(%edx,%ebp,4\)
+ 1548 1e65 8C9CAB78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebp,4\)
+ 1549 1e6c 3E8C9CAC 78563412 mov %ds,%ds:0x12345678\(%esp,%ebp,4\)
+ 1550 1e74 3E8C9CAD 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebp,4\)
+ 1551 1e7c 8C9CAE78 563412 mov %ds,%ds:0x12345678\(%esi,%ebp,4\)
+ 1552 1e83 8C9CAF78 563412 mov %ds,%ds:0x12345678\(%edi,%ebp,4\)
+ 1553 1e8a 8C9CB078 563412 mov %ds,%ds:0x12345678\(%eax,%esi,4\)
+ 1554 1e91 8C9CB178 563412 mov %ds,%ds:0x12345678\(%ecx,%esi,4\)
+ 1555 1e98 8C9CB278 563412 mov %ds,%ds:0x12345678\(%edx,%esi,4\)
+ 1556 1e9f 8C9CB378 563412 mov %ds,%ds:0x12345678\(%ebx,%esi,4\)
+ 1557 1ea6 3E8C9CB4 78563412 mov %ds,%ds:0x12345678\(%esp,%esi,4\)
+ 1558 1eae 3E8C9CB5 78563412 mov %ds,%ds:0x12345678\(%ebp,%esi,4\)
+ 1559 1eb6 8C9CB678 563412 mov %ds,%ds:0x12345678\(%esi,%esi,4\)
+ 1560 1ebd 8C9CB778 563412 mov %ds,%ds:0x12345678\(%edi,%esi,4\)
+ 1561 1ec4 8C9CB878 563412 mov %ds,%ds:0x12345678\(%eax,%edi,4\)
+ 1562 1ecb 8C9CB978 563412 mov %ds,%ds:0x12345678\(%ecx,%edi,4\)
+ 1563 1ed2 8C9CBA78 563412 mov %ds,%ds:0x12345678\(%edx,%edi,4\)
+ 1564 1ed9 8C9CBB78 563412 mov %ds,%ds:0x12345678\(%ebx,%edi,4\)
+ 1565 1ee0 3E8C9CBC 78563412 mov %ds,%ds:0x12345678\(%esp,%edi,4\)
+ 1566 1ee8 3E8C9CBD 78563412 mov %ds,%ds:0x12345678\(%ebp,%edi,4\)
+ 1567 1ef0 8C9CBE78 563412 mov %ds,%ds:0x12345678\(%esi,%edi,4\)
+ 1568 1ef7 8C9CBF78 563412 mov %ds,%ds:0x12345678\(%edi,%edi,4\)
+ 1569 1efe 8C9CC078 563412 mov %ds,%ds:0x12345678\(%eax,%eax,8\)
+ 1570 1f05 8C9CC178 563412 mov %ds,%ds:0x12345678\(%ecx,%eax,8\)
+ 1571 1f0c 8C9CC278 563412 mov %ds,%ds:0x12345678\(%edx,%eax,8\)
+ 1572 1f13 8C9CC378 563412 mov %ds,%ds:0x12345678\(%ebx,%eax,8\)
+ 1573 1f1a 3E8C9CC4 78563412 mov %ds,%ds:0x12345678\(%esp,%eax,8\)
+ 1574 1f22 3E8C9CC5 78563412 mov %ds,%ds:0x12345678\(%ebp,%eax,8\)
+ 1575 1f2a 8C9CC678 563412 mov %ds,%ds:0x12345678\(%esi,%eax,8\)
+ 1576 1f31 8C9CC778 563412 mov %ds,%ds:0x12345678\(%edi,%eax,8\)
+ 1577 1f38 8C9CC878 563412 mov %ds,%ds:0x12345678\(%eax,%ecx,8\)
+ 1578 1f3f 8C9CC978 563412 mov %ds,%ds:0x12345678\(%ecx,%ecx,8\)
+ 1579 1f46 8C9CCA78 563412 mov %ds,%ds:0x12345678\(%edx,%ecx,8\)
+ 1580 1f4d 8C9CCB78 563412 mov %ds,%ds:0x12345678\(%ebx,%ecx,8\)
+ 1581 1f54 3E8C9CCC 78563412 mov %ds,%ds:0x12345678\(%esp,%ecx,8\)
+ 1582 1f5c 3E8C9CCD 78563412 mov %ds,%ds:0x12345678\(%ebp,%ecx,8\)
+ 1583 1f64 8C9CCE78 563412 mov %ds,%ds:0x12345678\(%esi,%ecx,8\)
+ 1584 1f6b 8C9CCF78 563412 mov %ds,%ds:0x12345678\(%edi,%ecx,8\)
+ 1585 1f72 8C9CD078 563412 mov %ds,%ds:0x12345678\(%eax,%edx,8\)
+ 1586 1f79 8C9CD178 563412 mov %ds,%ds:0x12345678\(%ecx,%edx,8\)
+ 1587 1f80 8C9CD278 563412 mov %ds,%ds:0x12345678\(%edx,%edx,8\)
+ 1588 1f87 8C9CD378 563412 mov %ds,%ds:0x12345678\(%ebx,%edx,8\)
+ 1589 1f8e 3E8C9CD4 78563412 mov %ds,%ds:0x12345678\(%esp,%edx,8\)
+ 1590 1f96 3E8C9CD5 78563412 mov %ds,%ds:0x12345678\(%ebp,%edx,8\)
+ 1591 1f9e 8C9CD678 563412 mov %ds,%ds:0x12345678\(%esi,%edx,8\)
+ 1592 1fa5 8C9CD778 563412 mov %ds,%ds:0x12345678\(%edi,%edx,8\)
+ 1593 1fac 8C9CD878 563412 mov %ds,%ds:0x12345678\(%eax,%ebx,8\)
+ 1594 1fb3 8C9CD978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebx,8\)
+ 1595 1fba 8C9CDA78 563412 mov %ds,%ds:0x12345678\(%edx,%ebx,8\)
+ 1596 1fc1 8C9CDB78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebx,8\)
+ 1597 1fc8 3E8C9CDC 78563412 mov %ds,%ds:0x12345678\(%esp,%ebx,8\)
+ 1598 1fd0 3E8C9CDD 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebx,8\)
+ 1599 1fd8 8C9CDE78 563412 mov %ds,%ds:0x12345678\(%esi,%ebx,8\)
+ 1600 1fdf 8C9CDF78 563412 mov %ds,%ds:0x12345678\(%edi,%ebx,8\)
+ 1601 1fe6 8C987856 3412 mov %ds,%ds:0x12345678\(%eax,8\)
+.*Warning:.*
+ 1602 1fec 8C997856 3412 mov %ds,%ds:0x12345678\(%ecx,8\)
+.*Warning:.*
+ 1603 1ff2 8C9A7856 3412 mov %ds,%ds:0x12345678\(%edx,8\)
+.*Warning:.*
+ 1604 1ff8 8C9B7856 3412 mov %ds,%ds:0x12345678\(%ebx,8\)
+.*Warning:.*
+ 1605 1ffe 3E8C9C24 78563412 mov %ds,%ds:0x12345678\(%esp,8\)
+.*Warning:.*
+ 1606 2006 3E8C9D78 563412 mov %ds,%ds:0x12345678\(%ebp,8\)
+.*Warning:.*
+ 1607 200d 8C9E7856 3412 mov %ds,%ds:0x12345678\(%esi,8\)
+.*Warning:.*
+ 1608 2013 8C9F7856 3412 mov %ds,%ds:0x12345678\(%edi,8\)
+.*Warning:.*
+ 1609 2019 8C9CE878 563412 mov %ds,%ds:0x12345678\(%eax,%ebp,8\)
+ 1610 2020 8C9CE978 563412 mov %ds,%ds:0x12345678\(%ecx,%ebp,8\)
+ 1611 2027 8C9CEA78 563412 mov %ds,%ds:0x12345678\(%edx,%ebp,8\)
+ 1612 202e 8C9CEB78 563412 mov %ds,%ds:0x12345678\(%ebx,%ebp,8\)
+ 1613 2035 3E8C9CEC 78563412 mov %ds,%ds:0x12345678\(%esp,%ebp,8\)
+ 1614 203d 3E8C9CED 78563412 mov %ds,%ds:0x12345678\(%ebp,%ebp,8\)
+ 1615 2045 8C9CEE78 563412 mov %ds,%ds:0x12345678\(%esi,%ebp,8\)
+ 1616 204c 8C9CEF78 563412 mov %ds,%ds:0x12345678\(%edi,%ebp,8\)
+ 1617 2053 8C9CF078 563412 mov %ds,%ds:0x12345678\(%eax,%esi,8\)
+ 1618 205a 8C9CF178 563412 mov %ds,%ds:0x12345678\(%ecx,%esi,8\)
+ 1619 2061 8C9CF278 563412 mov %ds,%ds:0x12345678\(%edx,%esi,8\)
+ 1620 2068 8C9CF378 563412 mov %ds,%ds:0x12345678\(%ebx,%esi,8\)
+ 1621 206f 3E8C9CF4 78563412 mov %ds,%ds:0x12345678\(%esp,%esi,8\)
+ 1622 2077 3E8C9CF5 78563412 mov %ds,%ds:0x12345678\(%ebp,%esi,8\)
+ 1623 207f 8C9CF678 563412 mov %ds,%ds:0x12345678\(%esi,%esi,8\)
+ 1624 2086 8C9CF778 563412 mov %ds,%ds:0x12345678\(%edi,%esi,8\)
+ 1625 208d 8C9CF878 563412 mov %ds,%ds:0x12345678\(%eax,%edi,8\)
+ 1626 2094 8C9CFA78 563412 mov %ds,%ds:0x12345678\(%edx,%edi,8\)
+ 1627 209b 8C9CF978 563412 mov %ds,%ds:0x12345678\(%ecx,%edi,8\)
+ 1628 20a2 8C9CFB78 563412 mov %ds,%ds:0x12345678\(%ebx,%edi,8\)
+ 1629 20a9 3E8C9CFC 78563412 mov %ds,%ds:0x12345678\(%esp,%edi,8\)
+ 1630 20b1 3E8C9CFD 78563412 mov %ds,%ds:0x12345678\(%ebp,%edi,8\)
+ 1631 20b9 8C9CFE78 563412 mov %ds,%ds:0x12345678\(%esi,%edi,8\)
+ 1632 20c0 8C9CFF78 563412 mov %ds,%ds:0x12345678\(%edi,%edi,8\)
+ 1633 20c7 3E8C5C05 00 mov %ds,%ds:\(%ebp,%eax,1\)
+ 1634 20cc 3E8C5C0D 00 mov %ds,%ds:\(%ebp,%ecx,1\)
+ 1635 20d1 3E8C5C15 00 mov %ds,%ds:\(%ebp,%edx,1\)
+ 1636 20d6 3E8C5C1D 00 mov %ds,%ds:\(%ebp,%ebx,1\)
+ 1637 20db 3E8C5D00 mov %ds,%ds:\(%ebp,1\)
+ 1638 20df 3E8C5C2D 00 mov %ds,%ds:\(%ebp,%ebp,1\)
+ 1639 20e4 3E8C5C35 00 mov %ds,%ds:\(%ebp,%esi,1\)
+ 1640 20e9 3E8C5C3D 00 mov %ds,%ds:\(%ebp,%edi,1\)
+ 1641 20ee 3E8C5C45 00 mov %ds,%ds:\(%ebp,%eax,2\)
+ 1642 20f3 3E8C5C4D 00 mov %ds,%ds:\(%ebp,%ecx,2\)
+ 1643 20f8 3E8C5C55 00 mov %ds,%ds:\(%ebp,%edx,2\)
+ 1644 20fd 3E8C5C5D 00 mov %ds,%ds:\(%ebp,%ebx,2\)
+ 1645 2102 3E8C5D00 mov %ds,%ds:\(%ebp,2\)
+.*Warning:.*
+ 1646 2106 3E8C5C6D 00 mov %ds,%ds:\(%ebp,%ebp,2\)
+ 1647 210b 3E8C5C75 00 mov %ds,%ds:\(%ebp,%esi,2\)
+ 1648 2110 3E8C5C7D 00 mov %ds,%ds:\(%ebp,%edi,2\)
+ 1649 2115 3E8C5C85 00 mov %ds,%ds:\(%ebp,%eax,4\)
+ 1650 211a 3E8C5C8D 00 mov %ds,%ds:\(%ebp,%ecx,4\)
+ 1651 211f 3E8C5C95 00 mov %ds,%ds:\(%ebp,%edx,4\)
+ 1652 2124 3E8C5C9D 00 mov %ds,%ds:\(%ebp,%ebx,4\)
+ 1653 2129 3E8C5D00 mov %ds,%ds:\(%ebp,4\)
+.*Warning:.*
+ 1654 212d 3E8C5CAD 00 mov %ds,%ds:\(%ebp,%ebp,4\)
+ 1655 2132 3E8C5CB5 00 mov %ds,%ds:\(%ebp,%esi,4\)
+ 1656 2137 3E8C5CBD 00 mov %ds,%ds:\(%ebp,%edi,4\)
+ 1657 213c 3E8C5CC5 00 mov %ds,%ds:\(%ebp,%eax,8\)
+ 1658 2141 3E8C5CCD 00 mov %ds,%ds:\(%ebp,%ecx,8\)
+ 1659 2146 3E8C5CD5 00 mov %ds,%ds:\(%ebp,%edx,8\)
+ 1660 214b 3E8C5CDD 00 mov %ds,%ds:\(%ebp,%ebx,8\)
+ 1661 2150 3E8C5D00 mov %ds,%ds:\(%ebp,8\)
+.*Warning:.*
+ 1662 2154 3E8C5CED 00 mov %ds,%ds:\(%ebp,%ebp,8\)
+ 1663 2159 3E8C5CF5 00 mov %ds,%ds:\(%ebp,%esi,8\)
+ 1664 215e 3E8C5CFD 00 mov %ds,%ds:\(%ebp,%edi,8\)
+ 1665 2163 8C1D1200 0000 mov %ds,%ds:0x12\(,1\)
+ 1666 2169 8C1D1200 0000 mov %ds,%ds:0x12\(,2\)
+.*Warning:.*
+ 1667 216f 8C1D1200 0000 mov %ds,%ds:0x12\(,4\)
+.*Warning:.*
+ 1668 2175 8C1D1200 0000 mov %ds,%ds:0x12\(,8\)
+.*Warning:.*
+ 1669 [ ]*
+ 1670 [ ]* # Force a good alignment.
+ 1671 217b 00 [ ]* .byte 0
diff --git a/gas/testsuite/gas/i386/modrm.s b/gas/testsuite/gas/i386/modrm.s
new file mode 100644
index 00000000000..a6fc689aa6c
--- /dev/null
+++ b/gas/testsuite/gas/i386/modrm.s
@@ -0,0 +1,1671 @@
+.psize 0
+.text
+ mov %ds,%ss:(%eax)
+ mov %ds,%ss:(%ecx)
+ mov %ds,%ss:(%edx)
+ mov %ds,%ss:(%ebx)
+ mov %ds,%ss:0
+ mov %ds,%ss:(%esi)
+ mov %ds,%ss:(%edi)
+ mov %ds,%ss:0x12(%eax)
+ mov %ds,%ss:0x12(%ecx)
+ mov %ds,%ss:0x12(%edx)
+ mov %ds,%ss:0x12(%ebx)
+ mov %ds,%ss:0x12(%ebp)
+ mov %ds,%ss:0x12(%esi)
+ mov %ds,%ss:0x12(%edi)
+ mov %ds,%ss:0x12345678(%eax)
+ mov %ds,%ss:0x12345678(%ecx)
+ mov %ds,%ss:0x12345678(%edx)
+ mov %ds,%ss:0x12345678(%ebx)
+ mov %ds,%ss:0x12345678(%ebp)
+ mov %ds,%ss:0x12345678(%esi)
+ mov %ds,%ss:0x12345678(%edi)
+ mov %ds,%eax
+ mov %ds,%ecx
+ mov %ds,%edx
+ mov %ds,%ebx
+ mov %ds,%esp
+ mov %ds,%ebp
+ mov %ds,%esi
+ mov %ds,%edi
+ mov %ds,%ss:(%eax,%eax,1)
+ mov %ds,%ss:(%ecx,%eax,1)
+ mov %ds,%ss:(%edx,%eax,1)
+ mov %ds,%ss:(%ebx,%eax,1)
+ mov %ds,%ss:(%esp,%eax,1)
+ mov %ds,%ss:(,%eax,1)
+ mov %ds,%ss:(%esi,%eax,1)
+ mov %ds,%ss:(%edi,%eax,1)
+ mov %ds,%ss:(%eax,%ecx,1)
+ mov %ds,%ss:(%ecx,%ecx,1)
+ mov %ds,%ss:(%edx,%ecx,1)
+ mov %ds,%ss:(%ebx,%ecx,1)
+ mov %ds,%ss:(%esp,%ecx,1)
+ mov %ds,%ss:(,%ecx,1)
+ mov %ds,%ss:(%esi,%ecx,1)
+ mov %ds,%ss:(%edi,%ecx,1)
+ mov %ds,%ss:(%eax,%edx,1)
+ mov %ds,%ss:(%ecx,%edx,1)
+ mov %ds,%ss:(%edx,%edx,1)
+ mov %ds,%ss:(%ebx,%edx,1)
+ mov %ds,%ss:(%esp,%edx,1)
+ mov %ds,%ss:(,%edx,1)
+ mov %ds,%ss:(%esi,%edx,1)
+ mov %ds,%ss:(%edi,%edx,1)
+ mov %ds,%ss:(%eax,%ebx,1)
+ mov %ds,%ss:(%ecx,%ebx,1)
+ mov %ds,%ss:(%edx,%ebx,1)
+ mov %ds,%ss:(%ebx,%ebx,1)
+ mov %ds,%ss:(%esp,%ebx,1)
+ mov %ds,%ss:(,%ebx,1)
+ mov %ds,%ss:(%esi,%ebx,1)
+ mov %ds,%ss:(%edi,%ebx,1)
+ mov %ds,%ss:(%eax,1)
+ mov %ds,%ss:(%ecx,1)
+ mov %ds,%ss:(%edx,1)
+ mov %ds,%ss:(%ebx,1)
+ mov %ds,%ss:(%esp,1)
+ mov %ds,%ss:(,1)
+ mov %ds,%ss:(%esi,1)
+ mov %ds,%ss:(%edi,1)
+ mov %ds,%ss:(%eax,%ebp,1)
+ mov %ds,%ss:(%ecx,%ebp,1)
+ mov %ds,%ss:(%edx,%ebp,1)
+ mov %ds,%ss:(%ebx,%ebp,1)
+ mov %ds,%ss:(%esp,%ebp,1)
+ mov %ds,%ss:(,%ebp,1)
+ mov %ds,%ss:(%esi,%ebp,1)
+ mov %ds,%ss:(%edi,%ebp,1)
+ mov %ds,%ss:(%eax,%esi,1)
+ mov %ds,%ss:(%ecx,%esi,1)
+ mov %ds,%ss:(%edx,%esi,1)
+ mov %ds,%ss:(%ebx,%esi,1)
+ mov %ds,%ss:(%esp,%esi,1)
+ mov %ds,%ss:(,%esi,1)
+ mov %ds,%ss:(%esi,%esi,1)
+ mov %ds,%ss:(%edi,%esi,1)
+ mov %ds,%ss:(%eax,%edi,1)
+ mov %ds,%ss:(%ecx,%edi,1)
+ mov %ds,%ss:(%edx,%edi,1)
+ mov %ds,%ss:(%ebx,%edi,1)
+ mov %ds,%ss:(%esp,%edi,1)
+ mov %ds,%ss:(,%edi,1)
+ mov %ds,%ss:(%esi,%edi,1)
+ mov %ds,%ss:(%edi,%edi,1)
+ mov %ds,%ss:(%eax,%eax,2)
+ mov %ds,%ss:(%ecx,%eax,2)
+ mov %ds,%ss:(%edx,%eax,2)
+ mov %ds,%ss:(%ebx,%eax,2)
+ mov %ds,%ss:(%esp,%eax,2)
+ mov %ds,%ss:(,%eax,2)
+ mov %ds,%ss:(%esi,%eax,2)
+ mov %ds,%ss:(%edi,%eax,2)
+ mov %ds,%ss:(%eax,%ecx,2)
+ mov %ds,%ss:(%ecx,%ecx,2)
+ mov %ds,%ss:(%edx,%ecx,2)
+ mov %ds,%ss:(%ebx,%ecx,2)
+ mov %ds,%ss:(%esp,%ecx,2)
+ mov %ds,%ss:(,%ecx,2)
+ mov %ds,%ss:(%esi,%ecx,2)
+ mov %ds,%ss:(%edi,%ecx,2)
+ mov %ds,%ss:(%eax,%edx,2)
+ mov %ds,%ss:(%ecx,%edx,2)
+ mov %ds,%ss:(%edx,%edx,2)
+ mov %ds,%ss:(%ebx,%edx,2)
+ mov %ds,%ss:(%esp,%edx,2)
+ mov %ds,%ss:(,%edx,2)
+ mov %ds,%ss:(%esi,%edx,2)
+ mov %ds,%ss:(%edi,%edx,2)
+ mov %ds,%ss:(%eax,%ebx,2)
+ mov %ds,%ss:(%ecx,%ebx,2)
+ mov %ds,%ss:(%edx,%ebx,2)
+ mov %ds,%ss:(%ebx,%ebx,2)
+ mov %ds,%ss:(%esp,%ebx,2)
+ mov %ds,%ss:(,%ebx,2)
+ mov %ds,%ss:(%esi,%ebx,2)
+ mov %ds,%ss:(%edi,%ebx,2)
+ mov %ds,%ss:(%eax,2)
+ mov %ds,%ss:(%ecx,2)
+ mov %ds,%ss:(%edx,2)
+ mov %ds,%ss:(%ebx,2)
+ mov %ds,%ss:(%esp,2)
+ mov %ds,%ss:(,2)
+ mov %ds,%ss:(%esi,2)
+ mov %ds,%ss:(%edi,2)
+ mov %ds,%ss:(%eax,%ebp,2)
+ mov %ds,%ss:(%ecx,%ebp,2)
+ mov %ds,%ss:(%edx,%ebp,2)
+ mov %ds,%ss:(%ebx,%ebp,2)
+ mov %ds,%ss:(%esp,%ebp,2)
+ mov %ds,%ss:(,%ebp,2)
+ mov %ds,%ss:(%esi,%ebp,2)
+ mov %ds,%ss:(%edi,%ebp,2)
+ mov %ds,%ss:(%eax,%esi,2)
+ mov %ds,%ss:(%ecx,%esi,2)
+ mov %ds,%ss:(%edx,%esi,2)
+ mov %ds,%ss:(%ebx,%esi,2)
+ mov %ds,%ss:(%esp,%esi,2)
+ mov %ds,%ss:(,%esi,2)
+ mov %ds,%ss:(%esi,%esi,2)
+ mov %ds,%ss:(%edi,%esi,2)
+ mov %ds,%ss:(%eax,%edi,2)
+ mov %ds,%ss:(%ecx,%edi,2)
+ mov %ds,%ss:(%edx,%edi,2)
+ mov %ds,%ss:(%ebx,%edi,2)
+ mov %ds,%ss:(%esp,%edi,2)
+ mov %ds,%ss:(,%edi,2)
+ mov %ds,%ss:(%esi,%edi,2)
+ mov %ds,%ss:(%edi,%edi,2)
+ mov %ds,%ss:(%eax,%eax,4)
+ mov %ds,%ss:(%ecx,%eax,4)
+ mov %ds,%ss:(%edx,%eax,4)
+ mov %ds,%ss:(%ebx,%eax,4)
+ mov %ds,%ss:(%esp,%eax,4)
+ mov %ds,%ss:(,%eax,4)
+ mov %ds,%ss:(%esi,%eax,4)
+ mov %ds,%ss:(%edi,%eax,4)
+ mov %ds,%ss:(%eax,%ecx,4)
+ mov %ds,%ss:(%ecx,%ecx,4)
+ mov %ds,%ss:(%edx,%ecx,4)
+ mov %ds,%ss:(%ebx,%ecx,4)
+ mov %ds,%ss:(%esp,%ecx,4)
+ mov %ds,%ss:(,%ecx,4)
+ mov %ds,%ss:(%esi,%ecx,4)
+ mov %ds,%ss:(%edi,%ecx,4)
+ mov %ds,%ss:(%eax,%edx,4)
+ mov %ds,%ss:(%ecx,%edx,4)
+ mov %ds,%ss:(%edx,%edx,4)
+ mov %ds,%ss:(%ebx,%edx,4)
+ mov %ds,%ss:(%esp,%edx,4)
+ mov %ds,%ss:(,%edx,4)
+ mov %ds,%ss:(%esi,%edx,4)
+ mov %ds,%ss:(%edi,%edx,4)
+ mov %ds,%ss:(%eax,%ebx,4)
+ mov %ds,%ss:(%ecx,%ebx,4)
+ mov %ds,%ss:(%edx,%ebx,4)
+ mov %ds,%ss:(%ebx,%ebx,4)
+ mov %ds,%ss:(%esp,%ebx,4)
+ mov %ds,%ss:(,%ebx,4)
+ mov %ds,%ss:(%esi,%ebx,4)
+ mov %ds,%ss:(%edi,%ebx,4)
+ mov %ds,%ss:(%eax,4)
+ mov %ds,%ss:(%ecx,4)
+ mov %ds,%ss:(%edx,4)
+ mov %ds,%ss:(%ebx,4)
+ mov %ds,%ss:(%esp,4)
+ mov %ds,%ss:(,4)
+ mov %ds,%ss:(%esi,4)
+ mov %ds,%ss:(%edi,4)
+ mov %ds,%ss:(%eax,%ebp,4)
+ mov %ds,%ss:(%ecx,%ebp,4)
+ mov %ds,%ss:(%edx,%ebp,4)
+ mov %ds,%ss:(%ebx,%ebp,4)
+ mov %ds,%ss:(%esp,%ebp,4)
+ mov %ds,%ss:(,%ebp,4)
+ mov %ds,%ss:(%esi,%ebp,4)
+ mov %ds,%ss:(%edi,%ebp,4)
+ mov %ds,%ss:(%eax,%esi,4)
+ mov %ds,%ss:(%ecx,%esi,4)
+ mov %ds,%ss:(%edx,%esi,4)
+ mov %ds,%ss:(%ebx,%esi,4)
+ mov %ds,%ss:(%esp,%esi,4)
+ mov %ds,%ss:(,%esi,4)
+ mov %ds,%ss:(%esi,%esi,4)
+ mov %ds,%ss:(%edi,%esi,4)
+ mov %ds,%ss:(%eax,%edi,4)
+ mov %ds,%ss:(%ecx,%edi,4)
+ mov %ds,%ss:(%edx,%edi,4)
+ mov %ds,%ss:(%ebx,%edi,4)
+ mov %ds,%ss:(%esp,%edi,4)
+ mov %ds,%ss:(,%edi,4)
+ mov %ds,%ss:(%esi,%edi,4)
+ mov %ds,%ss:(%edi,%edi,4)
+ mov %ds,%ss:(%eax,%eax,8)
+ mov %ds,%ss:(%ecx,%eax,8)
+ mov %ds,%ss:(%edx,%eax,8)
+ mov %ds,%ss:(%ebx,%eax,8)
+ mov %ds,%ss:(%esp,%eax,8)
+ mov %ds,%ss:(,%eax,8)
+ mov %ds,%ss:(%esi,%eax,8)
+ mov %ds,%ss:(%edi,%eax,8)
+ mov %ds,%ss:(%eax,%ecx,8)
+ mov %ds,%ss:(%ecx,%ecx,8)
+ mov %ds,%ss:(%edx,%ecx,8)
+ mov %ds,%ss:(%ebx,%ecx,8)
+ mov %ds,%ss:(%esp,%ecx,8)
+ mov %ds,%ss:(,%ecx,8)
+ mov %ds,%ss:(%esi,%ecx,8)
+ mov %ds,%ss:(%edi,%ecx,8)
+ mov %ds,%ss:(%eax,%edx,8)
+ mov %ds,%ss:(%ecx,%edx,8)
+ mov %ds,%ss:(%edx,%edx,8)
+ mov %ds,%ss:(%ebx,%edx,8)
+ mov %ds,%ss:(%esp,%edx,8)
+ mov %ds,%ss:(,%edx,8)
+ mov %ds,%ss:(%esi,%edx,8)
+ mov %ds,%ss:(%edi,%edx,8)
+ mov %ds,%ss:(%eax,%ebx,8)
+ mov %ds,%ss:(%ecx,%ebx,8)
+ mov %ds,%ss:(%edx,%ebx,8)
+ mov %ds,%ss:(%ebx,%ebx,8)
+ mov %ds,%ss:(%esp,%ebx,8)
+ mov %ds,%ss:(,%ebx,8)
+ mov %ds,%ss:(%esi,%ebx,8)
+ mov %ds,%ss:(%edi,%ebx,8)
+ mov %ds,%ss:(%eax,8)
+ mov %ds,%ss:(%ecx,8)
+ mov %ds,%ss:(%edx,8)
+ mov %ds,%ss:(%ebx,8)
+ mov %ds,%ss:(%esp,8)
+ mov %ds,%ss:(,8)
+ mov %ds,%ss:(%esi,8)
+ mov %ds,%ss:(%edi,8)
+ mov %ds,%ss:(%eax,%ebp,8)
+ mov %ds,%ss:(%ecx,%ebp,8)
+ mov %ds,%ss:(%edx,%ebp,8)
+ mov %ds,%ss:(%ebx,%ebp,8)
+ mov %ds,%ss:(%esp,%ebp,8)
+ mov %ds,%ss:(,%ebp,8)
+ mov %ds,%ss:(%esi,%ebp,8)
+ mov %ds,%ss:(%edi,%ebp,8)
+ mov %ds,%ss:(%eax,%esi,8)
+ mov %ds,%ss:(%ecx,%esi,8)
+ mov %ds,%ss:(%edx,%esi,8)
+ mov %ds,%ss:(%ebx,%esi,8)
+ mov %ds,%ss:(%esp,%esi,8)
+ mov %ds,%ss:(,%esi,8)
+ mov %ds,%ss:(%esi,%esi,8)
+ mov %ds,%ss:(%edi,%esi,8)
+ mov %ds,%ss:(%eax,%edi,8)
+ mov %ds,%ss:(%edx,%edi,8)
+ mov %ds,%ss:(%ecx,%edi,8)
+ mov %ds,%ss:(%ebx,%edi,8)
+ mov %ds,%ss:(%esp,%edi,8)
+ mov %ds,%ss:(,%edi,8)
+ mov %ds,%ss:(%esi,%edi,8)
+ mov %ds,%ss:(%edi,%edi,8)
+ mov %ds,%ss:0x12(%eax,%eax,1)
+ mov %ds,%ss:0x12(%ecx,%eax,1)
+ mov %ds,%ss:0x12(%edx,%eax,1)
+ mov %ds,%ss:0x12(%ebx,%eax,1)
+ mov %ds,%ss:0x12(%esp,%eax,1)
+ mov %ds,%ss:0x12(%ebp,%eax,1)
+ mov %ds,%ss:0x12(%esi,%eax,1)
+ mov %ds,%ss:0x12(%edi,%eax,1)
+ mov %ds,%ss:0x12(%eax,%ecx,1)
+ mov %ds,%ss:0x12(%ecx,%ecx,1)
+ mov %ds,%ss:0x12(%edx,%ecx,1)
+ mov %ds,%ss:0x12(%ebx,%ecx,1)
+ mov %ds,%ss:0x12(%esp,%ecx,1)
+ mov %ds,%ss:0x12(%ebp,%ecx,1)
+ mov %ds,%ss:0x12(%esi,%ecx,1)
+ mov %ds,%ss:0x12(%edi,%ecx,1)
+ mov %ds,%ss:0x12(%eax,%edx,1)
+ mov %ds,%ss:0x12(%ecx,%edx,1)
+ mov %ds,%ss:0x12(%edx,%edx,1)
+ mov %ds,%ss:0x12(%ebx,%edx,1)
+ mov %ds,%ss:0x12(%esp,%edx,1)
+ mov %ds,%ss:0x12(%ebp,%edx,1)
+ mov %ds,%ss:0x12(%esi,%edx,1)
+ mov %ds,%ss:0x12(%edi,%edx,1)
+ mov %ds,%ss:0x12(%eax,%ebx,1)
+ mov %ds,%ss:0x12(%ecx,%ebx,1)
+ mov %ds,%ss:0x12(%edx,%ebx,1)
+ mov %ds,%ss:0x12(%ebx,%ebx,1)
+ mov %ds,%ss:0x12(%esp,%ebx,1)
+ mov %ds,%ss:0x12(%ebp,%ebx,1)
+ mov %ds,%ss:0x12(%esi,%ebx,1)
+ mov %ds,%ss:0x12(%edi,%ebx,1)
+ mov %ds,%ss:0x12(%eax,1)
+ mov %ds,%ss:0x12(%ecx,1)
+ mov %ds,%ss:0x12(%edx,1)
+ mov %ds,%ss:0x12(%ebx,1)
+ mov %ds,%ss:0x12(%esp,1)
+ mov %ds,%ss:0x12(%ebp,1)
+ mov %ds,%ss:0x12(%esi,1)
+ mov %ds,%ss:0x12(%edi,1)
+ mov %ds,%ss:0x12(%eax,%ebp,1)
+ mov %ds,%ss:0x12(%ecx,%ebp,1)
+ mov %ds,%ss:0x12(%edx,%ebp,1)
+ mov %ds,%ss:0x12(%ebx,%ebp,1)
+ mov %ds,%ss:0x12(%esp,%ebp,1)
+ mov %ds,%ss:0x12(%ebp,%ebp,1)
+ mov %ds,%ss:0x12(%esi,%ebp,1)
+ mov %ds,%ss:0x12(%edi,%ebp,1)
+ mov %ds,%ss:0x12(%eax,%esi,1)
+ mov %ds,%ss:0x12(%ecx,%esi,1)
+ mov %ds,%ss:0x12(%edx,%esi,1)
+ mov %ds,%ss:0x12(%ebx,%esi,1)
+ mov %ds,%ss:0x12(%esp,%esi,1)
+ mov %ds,%ss:0x12(%ebp,%esi,1)
+ mov %ds,%ss:0x12(%esi,%esi,1)
+ mov %ds,%ss:0x12(%edi,%esi,1)
+ mov %ds,%ss:0x12(%eax,%edi,1)
+ mov %ds,%ss:0x12(%ecx,%edi,1)
+ mov %ds,%ss:0x12(%edx,%edi,1)
+ mov %ds,%ss:0x12(%ebx,%edi,1)
+ mov %ds,%ss:0x12(%esp,%edi,1)
+ mov %ds,%ss:0x12(%ebp,%edi,1)
+ mov %ds,%ss:0x12(%esi,%edi,1)
+ mov %ds,%ss:0x12(%edi,%edi,1)
+ mov %ds,%ss:0x12(%eax,%eax,2)
+ mov %ds,%ss:0x12(%ecx,%eax,2)
+ mov %ds,%ss:0x12(%edx,%eax,2)
+ mov %ds,%ss:0x12(%ebx,%eax,2)
+ mov %ds,%ss:0x12(%esp,%eax,2)
+ mov %ds,%ss:0x12(%ebp,%eax,2)
+ mov %ds,%ss:0x12(%esi,%eax,2)
+ mov %ds,%ss:0x12(%edi,%eax,2)
+ mov %ds,%ss:0x12(%eax,%ecx,2)
+ mov %ds,%ss:0x12(%ecx,%ecx,2)
+ mov %ds,%ss:0x12(%edx,%ecx,2)
+ mov %ds,%ss:0x12(%ebx,%ecx,2)
+ mov %ds,%ss:0x12(%esp,%ecx,2)
+ mov %ds,%ss:0x12(%ebp,%ecx,2)
+ mov %ds,%ss:0x12(%esi,%ecx,2)
+ mov %ds,%ss:0x12(%edi,%ecx,2)
+ mov %ds,%ss:0x12(%eax,%edx,2)
+ mov %ds,%ss:0x12(%ecx,%edx,2)
+ mov %ds,%ss:0x12(%edx,%edx,2)
+ mov %ds,%ss:0x12(%ebx,%edx,2)
+ mov %ds,%ss:0x12(%esp,%edx,2)
+ mov %ds,%ss:0x12(%ebp,%edx,2)
+ mov %ds,%ss:0x12(%esi,%edx,2)
+ mov %ds,%ss:0x12(%edi,%edx,2)
+ mov %ds,%ss:0x12(%eax,%ebx,2)
+ mov %ds,%ss:0x12(%ecx,%ebx,2)
+ mov %ds,%ss:0x12(%edx,%ebx,2)
+ mov %ds,%ss:0x12(%ebx,%ebx,2)
+ mov %ds,%ss:0x12(%esp,%ebx,2)
+ mov %ds,%ss:0x12(%ebp,%ebx,2)
+ mov %ds,%ss:0x12(%esi,%ebx,2)
+ mov %ds,%ss:0x12(%edi,%ebx,2)
+ mov %ds,%ss:0x12(%eax,2)
+ mov %ds,%ss:0x12(%ecx,2)
+ mov %ds,%ss:0x12(%edx,2)
+ mov %ds,%ss:0x12(%ebx,2)
+ mov %ds,%ss:0x12(%esp,2)
+ mov %ds,%ss:0x12(%ebp,2)
+ mov %ds,%ss:0x12(%esi,2)
+ mov %ds,%ss:0x12(%edi,2)
+ mov %ds,%ss:0x12(%eax,%ebp,2)
+ mov %ds,%ss:0x12(%ecx,%ebp,2)
+ mov %ds,%ss:0x12(%edx,%ebp,2)
+ mov %ds,%ss:0x12(%ebx,%ebp,2)
+ mov %ds,%ss:0x12(%esp,%ebp,2)
+ mov %ds,%ss:0x12(%ebp,%ebp,2)
+ mov %ds,%ss:0x12(%esi,%ebp,2)
+ mov %ds,%ss:0x12(%edi,%ebp,2)
+ mov %ds,%ss:0x12(%eax,%esi,2)
+ mov %ds,%ss:0x12(%ecx,%esi,2)
+ mov %ds,%ss:0x12(%edx,%esi,2)
+ mov %ds,%ss:0x12(%ebx,%esi,2)
+ mov %ds,%ss:0x12(%esp,%esi,2)
+ mov %ds,%ss:0x12(%ebp,%esi,2)
+ mov %ds,%ss:0x12(%esi,%esi,2)
+ mov %ds,%ss:0x12(%edi,%esi,2)
+ mov %ds,%ss:0x12(%eax,%edi,2)
+ mov %ds,%ss:0x12(%ecx,%edi,2)
+ mov %ds,%ss:0x12(%edx,%edi,2)
+ mov %ds,%ss:0x12(%ebx,%edi,2)
+ mov %ds,%ss:0x12(%esp,%edi,2)
+ mov %ds,%ss:0x12(%ebp,%edi,2)
+ mov %ds,%ss:0x12(%esi,%edi,2)
+ mov %ds,%ss:0x12(%edi,%edi,2)
+ mov %ds,%ss:0x12(%eax,%eax,4)
+ mov %ds,%ss:0x12(%ecx,%eax,4)
+ mov %ds,%ss:0x12(%edx,%eax,4)
+ mov %ds,%ss:0x12(%ebx,%eax,4)
+ mov %ds,%ss:0x12(%esp,%eax,4)
+ mov %ds,%ss:0x12(%ebp,%eax,4)
+ mov %ds,%ss:0x12(%esi,%eax,4)
+ mov %ds,%ss:0x12(%edi,%eax,4)
+ mov %ds,%ss:0x12(%eax,%ecx,4)
+ mov %ds,%ss:0x12(%ecx,%ecx,4)
+ mov %ds,%ss:0x12(%edx,%ecx,4)
+ mov %ds,%ss:0x12(%ebx,%ecx,4)
+ mov %ds,%ss:0x12(%esp,%ecx,4)
+ mov %ds,%ss:0x12(%ebp,%ecx,4)
+ mov %ds,%ss:0x12(%esi,%ecx,4)
+ mov %ds,%ss:0x12(%edi,%ecx,4)
+ mov %ds,%ss:0x12(%eax,%edx,4)
+ mov %ds,%ss:0x12(%ecx,%edx,4)
+ mov %ds,%ss:0x12(%edx,%edx,4)
+ mov %ds,%ss:0x12(%ebx,%edx,4)
+ mov %ds,%ss:0x12(%esp,%edx,4)
+ mov %ds,%ss:0x12(%ebp,%edx,4)
+ mov %ds,%ss:0x12(%esi,%edx,4)
+ mov %ds,%ss:0x12(%edi,%edx,4)
+ mov %ds,%ss:0x12(%eax,%ebx,4)
+ mov %ds,%ss:0x12(%ecx,%ebx,4)
+ mov %ds,%ss:0x12(%edx,%ebx,4)
+ mov %ds,%ss:0x12(%ebx,%ebx,4)
+ mov %ds,%ss:0x12(%esp,%ebx,4)
+ mov %ds,%ss:0x12(%ebp,%ebx,4)
+ mov %ds,%ss:0x12(%esi,%ebx,4)
+ mov %ds,%ss:0x12(%edi,%ebx,4)
+ mov %ds,%ss:0x12(%eax,4)
+ mov %ds,%ss:0x12(%ecx,4)
+ mov %ds,%ss:0x12(%edx,4)
+ mov %ds,%ss:0x12(%ebx,4)
+ mov %ds,%ss:0x12(%esp,4)
+ mov %ds,%ss:0x12(%ebp,4)
+ mov %ds,%ss:0x12(%esi,4)
+ mov %ds,%ss:0x12(%edi,4)
+ mov %ds,%ss:0x12(%eax,%ebp,4)
+ mov %ds,%ss:0x12(%ecx,%ebp,4)
+ mov %ds,%ss:0x12(%edx,%ebp,4)
+ mov %ds,%ss:0x12(%ebx,%ebp,4)
+ mov %ds,%ss:0x12(%esp,%ebp,4)
+ mov %ds,%ss:0x12(%ebp,%ebp,4)
+ mov %ds,%ss:0x12(%esi,%ebp,4)
+ mov %ds,%ss:0x12(%edi,%ebp,4)
+ mov %ds,%ss:0x12(%eax,%esi,4)
+ mov %ds,%ss:0x12(%ecx,%esi,4)
+ mov %ds,%ss:0x12(%edx,%esi,4)
+ mov %ds,%ss:0x12(%ebx,%esi,4)
+ mov %ds,%ss:0x12(%esp,%esi,4)
+ mov %ds,%ss:0x12(%ebp,%esi,4)
+ mov %ds,%ss:0x12(%esi,%esi,4)
+ mov %ds,%ss:0x12(%edi,%esi,4)
+ mov %ds,%ss:0x12(%eax,%edi,4)
+ mov %ds,%ss:0x12(%ecx,%edi,4)
+ mov %ds,%ss:0x12(%edx,%edi,4)
+ mov %ds,%ss:0x12(%ebx,%edi,4)
+ mov %ds,%ss:0x12(%esp,%edi,4)
+ mov %ds,%ss:0x12(%ebp,%edi,4)
+ mov %ds,%ss:0x12(%esi,%edi,4)
+ mov %ds,%ss:0x12(%edi,%edi,4)
+ mov %ds,%ss:0x12(%eax,%eax,8)
+ mov %ds,%ss:0x12(%ecx,%eax,8)
+ mov %ds,%ss:0x12(%edx,%eax,8)
+ mov %ds,%ss:0x12(%ebx,%eax,8)
+ mov %ds,%ss:0x12(%esp,%eax,8)
+ mov %ds,%ss:0x12(%ebp,%eax,8)
+ mov %ds,%ss:0x12(%esi,%eax,8)
+ mov %ds,%ss:0x12(%edi,%eax,8)
+ mov %ds,%ss:0x12(%eax,%ecx,8)
+ mov %ds,%ss:0x12(%ecx,%ecx,8)
+ mov %ds,%ss:0x12(%edx,%ecx,8)
+ mov %ds,%ss:0x12(%ebx,%ecx,8)
+ mov %ds,%ss:0x12(%esp,%ecx,8)
+ mov %ds,%ss:0x12(%ebp,%ecx,8)
+ mov %ds,%ss:0x12(%esi,%ecx,8)
+ mov %ds,%ss:0x12(%edi,%ecx,8)
+ mov %ds,%ss:0x12(%eax,%edx,8)
+ mov %ds,%ss:0x12(%ecx,%edx,8)
+ mov %ds,%ss:0x12(%edx,%edx,8)
+ mov %ds,%ss:0x12(%ebx,%edx,8)
+ mov %ds,%ss:0x12(%esp,%edx,8)
+ mov %ds,%ss:0x12(%ebp,%edx,8)
+ mov %ds,%ss:0x12(%esi,%edx,8)
+ mov %ds,%ss:0x12(%edi,%edx,8)
+ mov %ds,%ss:0x12(%eax,%ebx,8)
+ mov %ds,%ss:0x12(%ecx,%ebx,8)
+ mov %ds,%ss:0x12(%edx,%ebx,8)
+ mov %ds,%ss:0x12(%ebx,%ebx,8)
+ mov %ds,%ss:0x12(%esp,%ebx,8)
+ mov %ds,%ss:0x12(%ebp,%ebx,8)
+ mov %ds,%ss:0x12(%esi,%ebx,8)
+ mov %ds,%ss:0x12(%edi,%ebx,8)
+ mov %ds,%ss:0x12(%eax,8)
+ mov %ds,%ss:0x12(%ecx,8)
+ mov %ds,%ss:0x12(%edx,8)
+ mov %ds,%ss:0x12(%ebx,8)
+ mov %ds,%ss:0x12(%esp,8)
+ mov %ds,%ss:0x12(%ebp,8)
+ mov %ds,%ss:0x12(%esi,8)
+ mov %ds,%ss:0x12(%edi,8)
+ mov %ds,%ss:0x12(%eax,%ebp,8)
+ mov %ds,%ss:0x12(%ecx,%ebp,8)
+ mov %ds,%ss:0x12(%edx,%ebp,8)
+ mov %ds,%ss:0x12(%ebx,%ebp,8)
+ mov %ds,%ss:0x12(%esp,%ebp,8)
+ mov %ds,%ss:0x12(%ebp,%ebp,8)
+ mov %ds,%ss:0x12(%esi,%ebp,8)
+ mov %ds,%ss:0x12(%edi,%ebp,8)
+ mov %ds,%ss:0x12(%eax,%esi,8)
+ mov %ds,%ss:0x12(%ecx,%esi,8)
+ mov %ds,%ss:0x12(%edx,%esi,8)
+ mov %ds,%ss:0x12(%ebx,%esi,8)
+ mov %ds,%ss:0x12(%esp,%esi,8)
+ mov %ds,%ss:0x12(%ebp,%esi,8)
+ mov %ds,%ss:0x12(%esi,%esi,8)
+ mov %ds,%ss:0x12(%edi,%esi,8)
+ mov %ds,%ss:0x12(%eax,%edi,8)
+ mov %ds,%ss:0x12(%edx,%edi,8)
+ mov %ds,%ss:0x12(%ecx,%edi,8)
+ mov %ds,%ss:0x12(%ebx,%edi,8)
+ mov %ds,%ss:0x12(%esp,%edi,8)
+ mov %ds,%ss:0x12(%ebp,%edi,8)
+ mov %ds,%ss:0x12(%esi,%edi,8)
+ mov %ds,%ss:0x12(%edi,%edi,8)
+ mov %ds,%ss:0x12345678(%eax,%eax,1)
+ mov %ds,%ss:0x12345678(%ecx,%eax,1)
+ mov %ds,%ss:0x12345678(%edx,%eax,1)
+ mov %ds,%ss:0x12345678(%ebx,%eax,1)
+ mov %ds,%ss:0x12345678(%esp,%eax,1)
+ mov %ds,%ss:0x12345678(%ebp,%eax,1)
+ mov %ds,%ss:0x12345678(%esi,%eax,1)
+ mov %ds,%ss:0x12345678(%edi,%eax,1)
+ mov %ds,%ss:0x12345678(%eax,%ecx,1)
+ mov %ds,%ss:0x12345678(%ecx,%ecx,1)
+ mov %ds,%ss:0x12345678(%edx,%ecx,1)
+ mov %ds,%ss:0x12345678(%ebx,%ecx,1)
+ mov %ds,%ss:0x12345678(%esp,%ecx,1)
+ mov %ds,%ss:0x12345678(%ebp,%ecx,1)
+ mov %ds,%ss:0x12345678(%esi,%ecx,1)
+ mov %ds,%ss:0x12345678(%edi,%ecx,1)
+ mov %ds,%ss:0x12345678(%eax,%edx,1)
+ mov %ds,%ss:0x12345678(%ecx,%edx,1)
+ mov %ds,%ss:0x12345678(%edx,%edx,1)
+ mov %ds,%ss:0x12345678(%ebx,%edx,1)
+ mov %ds,%ss:0x12345678(%esp,%edx,1)
+ mov %ds,%ss:0x12345678(%ebp,%edx,1)
+ mov %ds,%ss:0x12345678(%esi,%edx,1)
+ mov %ds,%ss:0x12345678(%edi,%edx,1)
+ mov %ds,%ss:0x12345678(%eax,%ebx,1)
+ mov %ds,%ss:0x12345678(%ecx,%ebx,1)
+ mov %ds,%ss:0x12345678(%edx,%ebx,1)
+ mov %ds,%ss:0x12345678(%ebx,%ebx,1)
+ mov %ds,%ss:0x12345678(%esp,%ebx,1)
+ mov %ds,%ss:0x12345678(%ebp,%ebx,1)
+ mov %ds,%ss:0x12345678(%esi,%ebx,1)
+ mov %ds,%ss:0x12345678(%edi,%ebx,1)
+ mov %ds,%ss:0x12345678(%eax,1)
+ mov %ds,%ss:0x12345678(%ecx,1)
+ mov %ds,%ss:0x12345678(%edx,1)
+ mov %ds,%ss:0x12345678(%ebx,1)
+ mov %ds,%ss:0x12345678(%esp,1)
+ mov %ds,%ss:0x12345678(%ebp,1)
+ mov %ds,%ss:0x12345678(%esi,1)
+ mov %ds,%ss:0x12345678(%edi,1)
+ mov %ds,%ss:0x12345678(%eax,%ebp,1)
+ mov %ds,%ss:0x12345678(%ecx,%ebp,1)
+ mov %ds,%ss:0x12345678(%edx,%ebp,1)
+ mov %ds,%ss:0x12345678(%ebx,%ebp,1)
+ mov %ds,%ss:0x12345678(%esp,%ebp,1)
+ mov %ds,%ss:0x12345678(%ebp,%ebp,1)
+ mov %ds,%ss:0x12345678(%esi,%ebp,1)
+ mov %ds,%ss:0x12345678(%edi,%ebp,1)
+ mov %ds,%ss:0x12345678(%eax,%esi,1)
+ mov %ds,%ss:0x12345678(%ecx,%esi,1)
+ mov %ds,%ss:0x12345678(%edx,%esi,1)
+ mov %ds,%ss:0x12345678(%ebx,%esi,1)
+ mov %ds,%ss:0x12345678(%esp,%esi,1)
+ mov %ds,%ss:0x12345678(%ebp,%esi,1)
+ mov %ds,%ss:0x12345678(%esi,%esi,1)
+ mov %ds,%ss:0x12345678(%edi,%esi,1)
+ mov %ds,%ss:0x12345678(%eax,%edi,1)
+ mov %ds,%ss:0x12345678(%ecx,%edi,1)
+ mov %ds,%ss:0x12345678(%edx,%edi,1)
+ mov %ds,%ss:0x12345678(%ebx,%edi,1)
+ mov %ds,%ss:0x12345678(%esp,%edi,1)
+ mov %ds,%ss:0x12345678(%ebp,%edi,1)
+ mov %ds,%ss:0x12345678(%esi,%edi,1)
+ mov %ds,%ss:0x12345678(%edi,%edi,1)
+ mov %ds,%ss:0x12345678(%eax,%eax,2)
+ mov %ds,%ss:0x12345678(%ecx,%eax,2)
+ mov %ds,%ss:0x12345678(%edx,%eax,2)
+ mov %ds,%ss:0x12345678(%ebx,%eax,2)
+ mov %ds,%ss:0x12345678(%esp,%eax,2)
+ mov %ds,%ss:0x12345678(%ebp,%eax,2)
+ mov %ds,%ss:0x12345678(%esi,%eax,2)
+ mov %ds,%ss:0x12345678(%edi,%eax,2)
+ mov %ds,%ss:0x12345678(%eax,%ecx,2)
+ mov %ds,%ss:0x12345678(%ecx,%ecx,2)
+ mov %ds,%ss:0x12345678(%edx,%ecx,2)
+ mov %ds,%ss:0x12345678(%ebx,%ecx,2)
+ mov %ds,%ss:0x12345678(%esp,%ecx,2)
+ mov %ds,%ss:0x12345678(%ebp,%ecx,2)
+ mov %ds,%ss:0x12345678(%esi,%ecx,2)
+ mov %ds,%ss:0x12345678(%edi,%ecx,2)
+ mov %ds,%ss:0x12345678(%eax,%edx,2)
+ mov %ds,%ss:0x12345678(%ecx,%edx,2)
+ mov %ds,%ss:0x12345678(%edx,%edx,2)
+ mov %ds,%ss:0x12345678(%ebx,%edx,2)
+ mov %ds,%ss:0x12345678(%esp,%edx,2)
+ mov %ds,%ss:0x12345678(%ebp,%edx,2)
+ mov %ds,%ss:0x12345678(%esi,%edx,2)
+ mov %ds,%ss:0x12345678(%edi,%edx,2)
+ mov %ds,%ss:0x12345678(%eax,%ebx,2)
+ mov %ds,%ss:0x12345678(%ecx,%ebx,2)
+ mov %ds,%ss:0x12345678(%edx,%ebx,2)
+ mov %ds,%ss:0x12345678(%ebx,%ebx,2)
+ mov %ds,%ss:0x12345678(%esp,%ebx,2)
+ mov %ds,%ss:0x12345678(%ebp,%ebx,2)
+ mov %ds,%ss:0x12345678(%esi,%ebx,2)
+ mov %ds,%ss:0x12345678(%edi,%ebx,2)
+ mov %ds,%ss:0x12345678(%eax,2)
+ mov %ds,%ss:0x12345678(%ecx,2)
+ mov %ds,%ss:0x12345678(%edx,2)
+ mov %ds,%ss:0x12345678(%ebx,2)
+ mov %ds,%ss:0x12345678(%esp,2)
+ mov %ds,%ss:0x12345678(%ebp,2)
+ mov %ds,%ss:0x12345678(%esi,2)
+ mov %ds,%ss:0x12345678(%edi,2)
+ mov %ds,%ss:0x12345678(%eax,%ebp,2)
+ mov %ds,%ss:0x12345678(%ecx,%ebp,2)
+ mov %ds,%ss:0x12345678(%edx,%ebp,2)
+ mov %ds,%ss:0x12345678(%ebx,%ebp,2)
+ mov %ds,%ss:0x12345678(%esp,%ebp,2)
+ mov %ds,%ss:0x12345678(%ebp,%ebp,2)
+ mov %ds,%ss:0x12345678(%esi,%ebp,2)
+ mov %ds,%ss:0x12345678(%edi,%ebp,2)
+ mov %ds,%ss:0x12345678(%eax,%esi,2)
+ mov %ds,%ss:0x12345678(%ecx,%esi,2)
+ mov %ds,%ss:0x12345678(%edx,%esi,2)
+ mov %ds,%ss:0x12345678(%ebx,%esi,2)
+ mov %ds,%ss:0x12345678(%esp,%esi,2)
+ mov %ds,%ss:0x12345678(%ebp,%esi,2)
+ mov %ds,%ss:0x12345678(%esi,%esi,2)
+ mov %ds,%ss:0x12345678(%edi,%esi,2)
+ mov %ds,%ss:0x12345678(%eax,%edi,2)
+ mov %ds,%ss:0x12345678(%ecx,%edi,2)
+ mov %ds,%ss:0x12345678(%edx,%edi,2)
+ mov %ds,%ss:0x12345678(%ebx,%edi,2)
+ mov %ds,%ss:0x12345678(%esp,%edi,2)
+ mov %ds,%ss:0x12345678(%ebp,%edi,2)
+ mov %ds,%ss:0x12345678(%esi,%edi,2)
+ mov %ds,%ss:0x12345678(%edi,%edi,2)
+ mov %ds,%ss:0x12345678(%eax,%eax,4)
+ mov %ds,%ss:0x12345678(%ecx,%eax,4)
+ mov %ds,%ss:0x12345678(%edx,%eax,4)
+ mov %ds,%ss:0x12345678(%ebx,%eax,4)
+ mov %ds,%ss:0x12345678(%esp,%eax,4)
+ mov %ds,%ss:0x12345678(%ebp,%eax,4)
+ mov %ds,%ss:0x12345678(%esi,%eax,4)
+ mov %ds,%ss:0x12345678(%edi,%eax,4)
+ mov %ds,%ss:0x12345678(%eax,%ecx,4)
+ mov %ds,%ss:0x12345678(%ecx,%ecx,4)
+ mov %ds,%ss:0x12345678(%edx,%ecx,4)
+ mov %ds,%ss:0x12345678(%ebx,%ecx,4)
+ mov %ds,%ss:0x12345678(%esp,%ecx,4)
+ mov %ds,%ss:0x12345678(%ebp,%ecx,4)
+ mov %ds,%ss:0x12345678(%esi,%ecx,4)
+ mov %ds,%ss:0x12345678(%edi,%ecx,4)
+ mov %ds,%ss:0x12345678(%eax,%edx,4)
+ mov %ds,%ss:0x12345678(%ecx,%edx,4)
+ mov %ds,%ss:0x12345678(%edx,%edx,4)
+ mov %ds,%ss:0x12345678(%ebx,%edx,4)
+ mov %ds,%ss:0x12345678(%esp,%edx,4)
+ mov %ds,%ss:0x12345678(%ebp,%edx,4)
+ mov %ds,%ss:0x12345678(%esi,%edx,4)
+ mov %ds,%ss:0x12345678(%edi,%edx,4)
+ mov %ds,%ss:0x12345678(%eax,%ebx,4)
+ mov %ds,%ss:0x12345678(%ecx,%ebx,4)
+ mov %ds,%ss:0x12345678(%edx,%ebx,4)
+ mov %ds,%ss:0x12345678(%ebx,%ebx,4)
+ mov %ds,%ss:0x12345678(%esp,%ebx,4)
+ mov %ds,%ss:0x12345678(%ebp,%ebx,4)
+ mov %ds,%ss:0x12345678(%esi,%ebx,4)
+ mov %ds,%ss:0x12345678(%edi,%ebx,4)
+ mov %ds,%ss:0x12345678(%eax,4)
+ mov %ds,%ss:0x12345678(%ecx,4)
+ mov %ds,%ss:0x12345678(%edx,4)
+ mov %ds,%ss:0x12345678(%ebx,4)
+ mov %ds,%ss:0x12345678(%esp,4)
+ mov %ds,%ss:0x12345678(%ebp,4)
+ mov %ds,%ss:0x12345678(%esi,4)
+ mov %ds,%ss:0x12345678(%edi,4)
+ mov %ds,%ss:0x12345678(%eax,%ebp,4)
+ mov %ds,%ss:0x12345678(%ecx,%ebp,4)
+ mov %ds,%ss:0x12345678(%edx,%ebp,4)
+ mov %ds,%ss:0x12345678(%ebx,%ebp,4)
+ mov %ds,%ss:0x12345678(%esp,%ebp,4)
+ mov %ds,%ss:0x12345678(%ebp,%ebp,4)
+ mov %ds,%ss:0x12345678(%esi,%ebp,4)
+ mov %ds,%ss:0x12345678(%edi,%ebp,4)
+ mov %ds,%ss:0x12345678(%eax,%esi,4)
+ mov %ds,%ss:0x12345678(%ecx,%esi,4)
+ mov %ds,%ss:0x12345678(%edx,%esi,4)
+ mov %ds,%ss:0x12345678(%ebx,%esi,4)
+ mov %ds,%ss:0x12345678(%esp,%esi,4)
+ mov %ds,%ss:0x12345678(%ebp,%esi,4)
+ mov %ds,%ss:0x12345678(%esi,%esi,4)
+ mov %ds,%ss:0x12345678(%edi,%esi,4)
+ mov %ds,%ss:0x12345678(%eax,%edi,4)
+ mov %ds,%ss:0x12345678(%ecx,%edi,4)
+ mov %ds,%ss:0x12345678(%edx,%edi,4)
+ mov %ds,%ss:0x12345678(%ebx,%edi,4)
+ mov %ds,%ss:0x12345678(%esp,%edi,4)
+ mov %ds,%ss:0x12345678(%ebp,%edi,4)
+ mov %ds,%ss:0x12345678(%esi,%edi,4)
+ mov %ds,%ss:0x12345678(%edi,%edi,4)
+ mov %ds,%ss:0x12345678(%eax,%eax,8)
+ mov %ds,%ss:0x12345678(%ecx,%eax,8)
+ mov %ds,%ss:0x12345678(%edx,%eax,8)
+ mov %ds,%ss:0x12345678(%ebx,%eax,8)
+ mov %ds,%ss:0x12345678(%esp,%eax,8)
+ mov %ds,%ss:0x12345678(%ebp,%eax,8)
+ mov %ds,%ss:0x12345678(%esi,%eax,8)
+ mov %ds,%ss:0x12345678(%edi,%eax,8)
+ mov %ds,%ss:0x12345678(%eax,%ecx,8)
+ mov %ds,%ss:0x12345678(%ecx,%ecx,8)
+ mov %ds,%ss:0x12345678(%edx,%ecx,8)
+ mov %ds,%ss:0x12345678(%ebx,%ecx,8)
+ mov %ds,%ss:0x12345678(%esp,%ecx,8)
+ mov %ds,%ss:0x12345678(%ebp,%ecx,8)
+ mov %ds,%ss:0x12345678(%esi,%ecx,8)
+ mov %ds,%ss:0x12345678(%edi,%ecx,8)
+ mov %ds,%ss:0x12345678(%eax,%edx,8)
+ mov %ds,%ss:0x12345678(%ecx,%edx,8)
+ mov %ds,%ss:0x12345678(%edx,%edx,8)
+ mov %ds,%ss:0x12345678(%ebx,%edx,8)
+ mov %ds,%ss:0x12345678(%esp,%edx,8)
+ mov %ds,%ss:0x12345678(%ebp,%edx,8)
+ mov %ds,%ss:0x12345678(%esi,%edx,8)
+ mov %ds,%ss:0x12345678(%edi,%edx,8)
+ mov %ds,%ss:0x12345678(%eax,%ebx,8)
+ mov %ds,%ss:0x12345678(%ecx,%ebx,8)
+ mov %ds,%ss:0x12345678(%edx,%ebx,8)
+ mov %ds,%ss:0x12345678(%ebx,%ebx,8)
+ mov %ds,%ss:0x12345678(%esp,%ebx,8)
+ mov %ds,%ss:0x12345678(%ebp,%ebx,8)
+ mov %ds,%ss:0x12345678(%esi,%ebx,8)
+ mov %ds,%ss:0x12345678(%edi,%ebx,8)
+ mov %ds,%ss:0x12345678(%eax,8)
+ mov %ds,%ss:0x12345678(%ecx,8)
+ mov %ds,%ss:0x12345678(%edx,8)
+ mov %ds,%ss:0x12345678(%ebx,8)
+ mov %ds,%ss:0x12345678(%esp,8)
+ mov %ds,%ss:0x12345678(%ebp,8)
+ mov %ds,%ss:0x12345678(%esi,8)
+ mov %ds,%ss:0x12345678(%edi,8)
+ mov %ds,%ss:0x12345678(%eax,%ebp,8)
+ mov %ds,%ss:0x12345678(%ecx,%ebp,8)
+ mov %ds,%ss:0x12345678(%edx,%ebp,8)
+ mov %ds,%ss:0x12345678(%ebx,%ebp,8)
+ mov %ds,%ss:0x12345678(%esp,%ebp,8)
+ mov %ds,%ss:0x12345678(%ebp,%ebp,8)
+ mov %ds,%ss:0x12345678(%esi,%ebp,8)
+ mov %ds,%ss:0x12345678(%edi,%ebp,8)
+ mov %ds,%ss:0x12345678(%eax,%esi,8)
+ mov %ds,%ss:0x12345678(%ecx,%esi,8)
+ mov %ds,%ss:0x12345678(%edx,%esi,8)
+ mov %ds,%ss:0x12345678(%ebx,%esi,8)
+ mov %ds,%ss:0x12345678(%esp,%esi,8)
+ mov %ds,%ss:0x12345678(%ebp,%esi,8)
+ mov %ds,%ss:0x12345678(%esi,%esi,8)
+ mov %ds,%ss:0x12345678(%edi,%esi,8)
+ mov %ds,%ss:0x12345678(%eax,%edi,8)
+ mov %ds,%ss:0x12345678(%edx,%edi,8)
+ mov %ds,%ss:0x12345678(%ecx,%edi,8)
+ mov %ds,%ss:0x12345678(%ebx,%edi,8)
+ mov %ds,%ss:0x12345678(%esp,%edi,8)
+ mov %ds,%ss:0x12345678(%ebp,%edi,8)
+ mov %ds,%ss:0x12345678(%esi,%edi,8)
+ mov %ds,%ss:0x12345678(%edi,%edi,8)
+ mov %ds,%ss:(%ebp,%eax,1)
+ mov %ds,%ss:(%ebp,%ecx,1)
+ mov %ds,%ss:(%ebp,%edx,1)
+ mov %ds,%ss:(%ebp,%ebx,1)
+ mov %ds,%ss:(%ebp,1)
+ mov %ds,%ss:(%ebp,%ebp,1)
+ mov %ds,%ss:(%ebp,%esi,1)
+ mov %ds,%ss:(%ebp,%edi,1)
+ mov %ds,%ss:(%ebp,%eax,2)
+ mov %ds,%ss:(%ebp,%ecx,2)
+ mov %ds,%ss:(%ebp,%edx,2)
+ mov %ds,%ss:(%ebp,%ebx,2)
+ mov %ds,%ss:(%ebp,2)
+ mov %ds,%ss:(%ebp,%ebp,2)
+ mov %ds,%ss:(%ebp,%esi,2)
+ mov %ds,%ss:(%ebp,%edi,2)
+ mov %ds,%ss:(%ebp,%eax,4)
+ mov %ds,%ss:(%ebp,%ecx,4)
+ mov %ds,%ss:(%ebp,%edx,4)
+ mov %ds,%ss:(%ebp,%ebx,4)
+ mov %ds,%ss:(%ebp,4)
+ mov %ds,%ss:(%ebp,%ebp,4)
+ mov %ds,%ss:(%ebp,%esi,4)
+ mov %ds,%ss:(%ebp,%edi,4)
+ mov %ds,%ss:(%ebp,%eax,8)
+ mov %ds,%ss:(%ebp,%ecx,8)
+ mov %ds,%ss:(%ebp,%edx,8)
+ mov %ds,%ss:(%ebp,%ebx,8)
+ mov %ds,%ss:(%ebp,8)
+ mov %ds,%ss:(%ebp,%ebp,8)
+ mov %ds,%ss:(%ebp,%esi,8)
+ mov %ds,%ss:(%ebp,%edi,8)
+ mov %ds,%ss:0x12(,1)
+ mov %ds,%ss:0x12(,2)
+ mov %ds,%ss:0x12(,4)
+ mov %ds,%ss:0x12(,8)
+ mov %ds,%ds:(%eax)
+ mov %ds,%ds:(%ecx)
+ mov %ds,%ds:(%edx)
+ mov %ds,%ds:(%ebx)
+ mov %ds,%ds:0
+ mov %ds,%ds:(%esi)
+ mov %ds,%ds:(%edi)
+ mov %ds,%ds:0x12(%eax)
+ mov %ds,%ds:0x12(%ecx)
+ mov %ds,%ds:0x12(%edx)
+ mov %ds,%ds:0x12(%ebx)
+ mov %ds,%ds:0x12(%ebp)
+ mov %ds,%ds:0x12(%esi)
+ mov %ds,%ds:0x12(%edi)
+ mov %ds,%ds:0x12345678(%eax)
+ mov %ds,%ds:0x12345678(%ecx)
+ mov %ds,%ds:0x12345678(%edx)
+ mov %ds,%ds:0x12345678(%ebx)
+ mov %ds,%ds:0x12345678(%ebp)
+ mov %ds,%ds:0x12345678(%esi)
+ mov %ds,%ds:0x12345678(%edi)
+ mov %ds,%eax
+ mov %ds,%ecx
+ mov %ds,%edx
+ mov %ds,%ebx
+ mov %ds,%esp
+ mov %ds,%ebp
+ mov %ds,%esi
+ mov %ds,%edi
+ mov %ds,%ds:(%eax,%eax,1)
+ mov %ds,%ds:(%ecx,%eax,1)
+ mov %ds,%ds:(%edx,%eax,1)
+ mov %ds,%ds:(%ebx,%eax,1)
+ mov %ds,%ds:(%esp,%eax,1)
+ mov %ds,%ds:(,%eax,1)
+ mov %ds,%ds:(%esi,%eax,1)
+ mov %ds,%ds:(%edi,%eax,1)
+ mov %ds,%ds:(%eax,%ecx,1)
+ mov %ds,%ds:(%ecx,%ecx,1)
+ mov %ds,%ds:(%edx,%ecx,1)
+ mov %ds,%ds:(%ebx,%ecx,1)
+ mov %ds,%ds:(%esp,%ecx,1)
+ mov %ds,%ds:(,%ecx,1)
+ mov %ds,%ds:(%esi,%ecx,1)
+ mov %ds,%ds:(%edi,%ecx,1)
+ mov %ds,%ds:(%eax,%edx,1)
+ mov %ds,%ds:(%ecx,%edx,1)
+ mov %ds,%ds:(%edx,%edx,1)
+ mov %ds,%ds:(%ebx,%edx,1)
+ mov %ds,%ds:(%esp,%edx,1)
+ mov %ds,%ds:(,%edx,1)
+ mov %ds,%ds:(%esi,%edx,1)
+ mov %ds,%ds:(%edi,%edx,1)
+ mov %ds,%ds:(%eax,%ebx,1)
+ mov %ds,%ds:(%ecx,%ebx,1)
+ mov %ds,%ds:(%edx,%ebx,1)
+ mov %ds,%ds:(%ebx,%ebx,1)
+ mov %ds,%ds:(%esp,%ebx,1)
+ mov %ds,%ds:(,%ebx,1)
+ mov %ds,%ds:(%esi,%ebx,1)
+ mov %ds,%ds:(%edi,%ebx,1)
+ mov %ds,%ds:(%eax,1)
+ mov %ds,%ds:(%ecx,1)
+ mov %ds,%ds:(%edx,1)
+ mov %ds,%ds:(%ebx,1)
+ mov %ds,%ds:(%esp,1)
+ mov %ds,%ds:(,1)
+ mov %ds,%ds:(%esi,1)
+ mov %ds,%ds:(%edi,1)
+ mov %ds,%ds:(%eax,%ebp,1)
+ mov %ds,%ds:(%ecx,%ebp,1)
+ mov %ds,%ds:(%edx,%ebp,1)
+ mov %ds,%ds:(%ebx,%ebp,1)
+ mov %ds,%ds:(%esp,%ebp,1)
+ mov %ds,%ds:(,%ebp,1)
+ mov %ds,%ds:(%esi,%ebp,1)
+ mov %ds,%ds:(%edi,%ebp,1)
+ mov %ds,%ds:(%eax,%esi,1)
+ mov %ds,%ds:(%ecx,%esi,1)
+ mov %ds,%ds:(%edx,%esi,1)
+ mov %ds,%ds:(%ebx,%esi,1)
+ mov %ds,%ds:(%esp,%esi,1)
+ mov %ds,%ds:(,%esi,1)
+ mov %ds,%ds:(%esi,%esi,1)
+ mov %ds,%ds:(%edi,%esi,1)
+ mov %ds,%ds:(%eax,%edi,1)
+ mov %ds,%ds:(%ecx,%edi,1)
+ mov %ds,%ds:(%edx,%edi,1)
+ mov %ds,%ds:(%ebx,%edi,1)
+ mov %ds,%ds:(%esp,%edi,1)
+ mov %ds,%ds:(,%edi,1)
+ mov %ds,%ds:(%esi,%edi,1)
+ mov %ds,%ds:(%edi,%edi,1)
+ mov %ds,%ds:(%eax,%eax,2)
+ mov %ds,%ds:(%ecx,%eax,2)
+ mov %ds,%ds:(%edx,%eax,2)
+ mov %ds,%ds:(%ebx,%eax,2)
+ mov %ds,%ds:(%esp,%eax,2)
+ mov %ds,%ds:(,%eax,2)
+ mov %ds,%ds:(%esi,%eax,2)
+ mov %ds,%ds:(%edi,%eax,2)
+ mov %ds,%ds:(%eax,%ecx,2)
+ mov %ds,%ds:(%ecx,%ecx,2)
+ mov %ds,%ds:(%edx,%ecx,2)
+ mov %ds,%ds:(%ebx,%ecx,2)
+ mov %ds,%ds:(%esp,%ecx,2)
+ mov %ds,%ds:(,%ecx,2)
+ mov %ds,%ds:(%esi,%ecx,2)
+ mov %ds,%ds:(%edi,%ecx,2)
+ mov %ds,%ds:(%eax,%edx,2)
+ mov %ds,%ds:(%ecx,%edx,2)
+ mov %ds,%ds:(%edx,%edx,2)
+ mov %ds,%ds:(%ebx,%edx,2)
+ mov %ds,%ds:(%esp,%edx,2)
+ mov %ds,%ds:(,%edx,2)
+ mov %ds,%ds:(%esi,%edx,2)
+ mov %ds,%ds:(%edi,%edx,2)
+ mov %ds,%ds:(%eax,%ebx,2)
+ mov %ds,%ds:(%ecx,%ebx,2)
+ mov %ds,%ds:(%edx,%ebx,2)
+ mov %ds,%ds:(%ebx,%ebx,2)
+ mov %ds,%ds:(%esp,%ebx,2)
+ mov %ds,%ds:(,%ebx,2)
+ mov %ds,%ds:(%esi,%ebx,2)
+ mov %ds,%ds:(%edi,%ebx,2)
+ mov %ds,%ds:(%eax,2)
+ mov %ds,%ds:(%ecx,2)
+ mov %ds,%ds:(%edx,2)
+ mov %ds,%ds:(%ebx,2)
+ mov %ds,%ds:(%esp,2)
+ mov %ds,%ds:(,2)
+ mov %ds,%ds:(%esi,2)
+ mov %ds,%ds:(%edi,2)
+ mov %ds,%ds:(%eax,%ebp,2)
+ mov %ds,%ds:(%ecx,%ebp,2)
+ mov %ds,%ds:(%edx,%ebp,2)
+ mov %ds,%ds:(%ebx,%ebp,2)
+ mov %ds,%ds:(%esp,%ebp,2)
+ mov %ds,%ds:(,%ebp,2)
+ mov %ds,%ds:(%esi,%ebp,2)
+ mov %ds,%ds:(%edi,%ebp,2)
+ mov %ds,%ds:(%eax,%esi,2)
+ mov %ds,%ds:(%ecx,%esi,2)
+ mov %ds,%ds:(%edx,%esi,2)
+ mov %ds,%ds:(%ebx,%esi,2)
+ mov %ds,%ds:(%esp,%esi,2)
+ mov %ds,%ds:(,%esi,2)
+ mov %ds,%ds:(%esi,%esi,2)
+ mov %ds,%ds:(%edi,%esi,2)
+ mov %ds,%ds:(%eax,%edi,2)
+ mov %ds,%ds:(%ecx,%edi,2)
+ mov %ds,%ds:(%edx,%edi,2)
+ mov %ds,%ds:(%ebx,%edi,2)
+ mov %ds,%ds:(%esp,%edi,2)
+ mov %ds,%ds:(,%edi,2)
+ mov %ds,%ds:(%esi,%edi,2)
+ mov %ds,%ds:(%edi,%edi,2)
+ mov %ds,%ds:(%eax,%eax,4)
+ mov %ds,%ds:(%ecx,%eax,4)
+ mov %ds,%ds:(%edx,%eax,4)
+ mov %ds,%ds:(%ebx,%eax,4)
+ mov %ds,%ds:(%esp,%eax,4)
+ mov %ds,%ds:(,%eax,4)
+ mov %ds,%ds:(%esi,%eax,4)
+ mov %ds,%ds:(%edi,%eax,4)
+ mov %ds,%ds:(%eax,%ecx,4)
+ mov %ds,%ds:(%ecx,%ecx,4)
+ mov %ds,%ds:(%edx,%ecx,4)
+ mov %ds,%ds:(%ebx,%ecx,4)
+ mov %ds,%ds:(%esp,%ecx,4)
+ mov %ds,%ds:(,%ecx,4)
+ mov %ds,%ds:(%esi,%ecx,4)
+ mov %ds,%ds:(%edi,%ecx,4)
+ mov %ds,%ds:(%eax,%edx,4)
+ mov %ds,%ds:(%ecx,%edx,4)
+ mov %ds,%ds:(%edx,%edx,4)
+ mov %ds,%ds:(%ebx,%edx,4)
+ mov %ds,%ds:(%esp,%edx,4)
+ mov %ds,%ds:(,%edx,4)
+ mov %ds,%ds:(%esi,%edx,4)
+ mov %ds,%ds:(%edi,%edx,4)
+ mov %ds,%ds:(%eax,%ebx,4)
+ mov %ds,%ds:(%ecx,%ebx,4)
+ mov %ds,%ds:(%edx,%ebx,4)
+ mov %ds,%ds:(%ebx,%ebx,4)
+ mov %ds,%ds:(%esp,%ebx,4)
+ mov %ds,%ds:(,%ebx,4)
+ mov %ds,%ds:(%esi,%ebx,4)
+ mov %ds,%ds:(%edi,%ebx,4)
+ mov %ds,%ds:(%eax,4)
+ mov %ds,%ds:(%ecx,4)
+ mov %ds,%ds:(%edx,4)
+ mov %ds,%ds:(%ebx,4)
+ mov %ds,%ds:(%esp,4)
+ mov %ds,%ds:(,4)
+ mov %ds,%ds:(%esi,4)
+ mov %ds,%ds:(%edi,4)
+ mov %ds,%ds:(%eax,%ebp,4)
+ mov %ds,%ds:(%ecx,%ebp,4)
+ mov %ds,%ds:(%edx,%ebp,4)
+ mov %ds,%ds:(%ebx,%ebp,4)
+ mov %ds,%ds:(%esp,%ebp,4)
+ mov %ds,%ds:(,%ebp,4)
+ mov %ds,%ds:(%esi,%ebp,4)
+ mov %ds,%ds:(%edi,%ebp,4)
+ mov %ds,%ds:(%eax,%esi,4)
+ mov %ds,%ds:(%ecx,%esi,4)
+ mov %ds,%ds:(%edx,%esi,4)
+ mov %ds,%ds:(%ebx,%esi,4)
+ mov %ds,%ds:(%esp,%esi,4)
+ mov %ds,%ds:(,%esi,4)
+ mov %ds,%ds:(%esi,%esi,4)
+ mov %ds,%ds:(%edi,%esi,4)
+ mov %ds,%ds:(%eax,%edi,4)
+ mov %ds,%ds:(%ecx,%edi,4)
+ mov %ds,%ds:(%edx,%edi,4)
+ mov %ds,%ds:(%ebx,%edi,4)
+ mov %ds,%ds:(%esp,%edi,4)
+ mov %ds,%ds:(,%edi,4)
+ mov %ds,%ds:(%esi,%edi,4)
+ mov %ds,%ds:(%edi,%edi,4)
+ mov %ds,%ds:(%eax,%eax,8)
+ mov %ds,%ds:(%ecx,%eax,8)
+ mov %ds,%ds:(%edx,%eax,8)
+ mov %ds,%ds:(%ebx,%eax,8)
+ mov %ds,%ds:(%esp,%eax,8)
+ mov %ds,%ds:(,%eax,8)
+ mov %ds,%ds:(%esi,%eax,8)
+ mov %ds,%ds:(%edi,%eax,8)
+ mov %ds,%ds:(%eax,%ecx,8)
+ mov %ds,%ds:(%ecx,%ecx,8)
+ mov %ds,%ds:(%edx,%ecx,8)
+ mov %ds,%ds:(%ebx,%ecx,8)
+ mov %ds,%ds:(%esp,%ecx,8)
+ mov %ds,%ds:(,%ecx,8)
+ mov %ds,%ds:(%esi,%ecx,8)
+ mov %ds,%ds:(%edi,%ecx,8)
+ mov %ds,%ds:(%eax,%edx,8)
+ mov %ds,%ds:(%ecx,%edx,8)
+ mov %ds,%ds:(%edx,%edx,8)
+ mov %ds,%ds:(%ebx,%edx,8)
+ mov %ds,%ds:(%esp,%edx,8)
+ mov %ds,%ds:(,%edx,8)
+ mov %ds,%ds:(%esi,%edx,8)
+ mov %ds,%ds:(%edi,%edx,8)
+ mov %ds,%ds:(%eax,%ebx,8)
+ mov %ds,%ds:(%ecx,%ebx,8)
+ mov %ds,%ds:(%edx,%ebx,8)
+ mov %ds,%ds:(%ebx,%ebx,8)
+ mov %ds,%ds:(%esp,%ebx,8)
+ mov %ds,%ds:(,%ebx,8)
+ mov %ds,%ds:(%esi,%ebx,8)
+ mov %ds,%ds:(%edi,%ebx,8)
+ mov %ds,%ds:(%eax,8)
+ mov %ds,%ds:(%ecx,8)
+ mov %ds,%ds:(%edx,8)
+ mov %ds,%ds:(%ebx,8)
+ mov %ds,%ds:(%esp,8)
+ mov %ds,%ds:(,8)
+ mov %ds,%ds:(%esi,8)
+ mov %ds,%ds:(%edi,8)
+ mov %ds,%ds:(%eax,%ebp,8)
+ mov %ds,%ds:(%ecx,%ebp,8)
+ mov %ds,%ds:(%edx,%ebp,8)
+ mov %ds,%ds:(%ebx,%ebp,8)
+ mov %ds,%ds:(%esp,%ebp,8)
+ mov %ds,%ds:(,%ebp,8)
+ mov %ds,%ds:(%esi,%ebp,8)
+ mov %ds,%ds:(%edi,%ebp,8)
+ mov %ds,%ds:(%eax,%esi,8)
+ mov %ds,%ds:(%ecx,%esi,8)
+ mov %ds,%ds:(%edx,%esi,8)
+ mov %ds,%ds:(%ebx,%esi,8)
+ mov %ds,%ds:(%esp,%esi,8)
+ mov %ds,%ds:(,%esi,8)
+ mov %ds,%ds:(%esi,%esi,8)
+ mov %ds,%ds:(%edi,%esi,8)
+ mov %ds,%ds:(%eax,%edi,8)
+ mov %ds,%ds:(%edx,%edi,8)
+ mov %ds,%ds:(%ecx,%edi,8)
+ mov %ds,%ds:(%ebx,%edi,8)
+ mov %ds,%ds:(%esp,%edi,8)
+ mov %ds,%ds:(,%edi,8)
+ mov %ds,%ds:(%esi,%edi,8)
+ mov %ds,%ds:(%edi,%edi,8)
+ mov %ds,%ds:0x12(%eax,%eax,1)
+ mov %ds,%ds:0x12(%ecx,%eax,1)
+ mov %ds,%ds:0x12(%edx,%eax,1)
+ mov %ds,%ds:0x12(%ebx,%eax,1)
+ mov %ds,%ds:0x12(%esp,%eax,1)
+ mov %ds,%ds:0x12(%ebp,%eax,1)
+ mov %ds,%ds:0x12(%esi,%eax,1)
+ mov %ds,%ds:0x12(%edi,%eax,1)
+ mov %ds,%ds:0x12(%eax,%ecx,1)
+ mov %ds,%ds:0x12(%ecx,%ecx,1)
+ mov %ds,%ds:0x12(%edx,%ecx,1)
+ mov %ds,%ds:0x12(%ebx,%ecx,1)
+ mov %ds,%ds:0x12(%esp,%ecx,1)
+ mov %ds,%ds:0x12(%ebp,%ecx,1)
+ mov %ds,%ds:0x12(%esi,%ecx,1)
+ mov %ds,%ds:0x12(%edi,%ecx,1)
+ mov %ds,%ds:0x12(%eax,%edx,1)
+ mov %ds,%ds:0x12(%ecx,%edx,1)
+ mov %ds,%ds:0x12(%edx,%edx,1)
+ mov %ds,%ds:0x12(%ebx,%edx,1)
+ mov %ds,%ds:0x12(%esp,%edx,1)
+ mov %ds,%ds:0x12(%ebp,%edx,1)
+ mov %ds,%ds:0x12(%esi,%edx,1)
+ mov %ds,%ds:0x12(%edi,%edx,1)
+ mov %ds,%ds:0x12(%eax,%ebx,1)
+ mov %ds,%ds:0x12(%ecx,%ebx,1)
+ mov %ds,%ds:0x12(%edx,%ebx,1)
+ mov %ds,%ds:0x12(%ebx,%ebx,1)
+ mov %ds,%ds:0x12(%esp,%ebx,1)
+ mov %ds,%ds:0x12(%ebp,%ebx,1)
+ mov %ds,%ds:0x12(%esi,%ebx,1)
+ mov %ds,%ds:0x12(%edi,%ebx,1)
+ mov %ds,%ds:0x12(%eax,1)
+ mov %ds,%ds:0x12(%ecx,1)
+ mov %ds,%ds:0x12(%edx,1)
+ mov %ds,%ds:0x12(%ebx,1)
+ mov %ds,%ds:0x12(%esp,1)
+ mov %ds,%ds:0x12(%ebp,1)
+ mov %ds,%ds:0x12(%esi,1)
+ mov %ds,%ds:0x12(%edi,1)
+ mov %ds,%ds:0x12(%eax,%ebp,1)
+ mov %ds,%ds:0x12(%ecx,%ebp,1)
+ mov %ds,%ds:0x12(%edx,%ebp,1)
+ mov %ds,%ds:0x12(%ebx,%ebp,1)
+ mov %ds,%ds:0x12(%esp,%ebp,1)
+ mov %ds,%ds:0x12(%ebp,%ebp,1)
+ mov %ds,%ds:0x12(%esi,%ebp,1)
+ mov %ds,%ds:0x12(%edi,%ebp,1)
+ mov %ds,%ds:0x12(%eax,%esi,1)
+ mov %ds,%ds:0x12(%ecx,%esi,1)
+ mov %ds,%ds:0x12(%edx,%esi,1)
+ mov %ds,%ds:0x12(%ebx,%esi,1)
+ mov %ds,%ds:0x12(%esp,%esi,1)
+ mov %ds,%ds:0x12(%ebp,%esi,1)
+ mov %ds,%ds:0x12(%esi,%esi,1)
+ mov %ds,%ds:0x12(%edi,%esi,1)
+ mov %ds,%ds:0x12(%eax,%edi,1)
+ mov %ds,%ds:0x12(%ecx,%edi,1)
+ mov %ds,%ds:0x12(%edx,%edi,1)
+ mov %ds,%ds:0x12(%ebx,%edi,1)
+ mov %ds,%ds:0x12(%esp,%edi,1)
+ mov %ds,%ds:0x12(%ebp,%edi,1)
+ mov %ds,%ds:0x12(%esi,%edi,1)
+ mov %ds,%ds:0x12(%edi,%edi,1)
+ mov %ds,%ds:0x12(%eax,%eax,2)
+ mov %ds,%ds:0x12(%ecx,%eax,2)
+ mov %ds,%ds:0x12(%edx,%eax,2)
+ mov %ds,%ds:0x12(%ebx,%eax,2)
+ mov %ds,%ds:0x12(%esp,%eax,2)
+ mov %ds,%ds:0x12(%ebp,%eax,2)
+ mov %ds,%ds:0x12(%esi,%eax,2)
+ mov %ds,%ds:0x12(%edi,%eax,2)
+ mov %ds,%ds:0x12(%eax,%ecx,2)
+ mov %ds,%ds:0x12(%ecx,%ecx,2)
+ mov %ds,%ds:0x12(%edx,%ecx,2)
+ mov %ds,%ds:0x12(%ebx,%ecx,2)
+ mov %ds,%ds:0x12(%esp,%ecx,2)
+ mov %ds,%ds:0x12(%ebp,%ecx,2)
+ mov %ds,%ds:0x12(%esi,%ecx,2)
+ mov %ds,%ds:0x12(%edi,%ecx,2)
+ mov %ds,%ds:0x12(%eax,%edx,2)
+ mov %ds,%ds:0x12(%ecx,%edx,2)
+ mov %ds,%ds:0x12(%edx,%edx,2)
+ mov %ds,%ds:0x12(%ebx,%edx,2)
+ mov %ds,%ds:0x12(%esp,%edx,2)
+ mov %ds,%ds:0x12(%ebp,%edx,2)
+ mov %ds,%ds:0x12(%esi,%edx,2)
+ mov %ds,%ds:0x12(%edi,%edx,2)
+ mov %ds,%ds:0x12(%eax,%ebx,2)
+ mov %ds,%ds:0x12(%ecx,%ebx,2)
+ mov %ds,%ds:0x12(%edx,%ebx,2)
+ mov %ds,%ds:0x12(%ebx,%ebx,2)
+ mov %ds,%ds:0x12(%esp,%ebx,2)
+ mov %ds,%ds:0x12(%ebp,%ebx,2)
+ mov %ds,%ds:0x12(%esi,%ebx,2)
+ mov %ds,%ds:0x12(%edi,%ebx,2)
+ mov %ds,%ds:0x12(%eax,2)
+ mov %ds,%ds:0x12(%ecx,2)
+ mov %ds,%ds:0x12(%edx,2)
+ mov %ds,%ds:0x12(%ebx,2)
+ mov %ds,%ds:0x12(%esp,2)
+ mov %ds,%ds:0x12(%ebp,2)
+ mov %ds,%ds:0x12(%esi,2)
+ mov %ds,%ds:0x12(%edi,2)
+ mov %ds,%ds:0x12(%eax,%ebp,2)
+ mov %ds,%ds:0x12(%ecx,%ebp,2)
+ mov %ds,%ds:0x12(%edx,%ebp,2)
+ mov %ds,%ds:0x12(%ebx,%ebp,2)
+ mov %ds,%ds:0x12(%esp,%ebp,2)
+ mov %ds,%ds:0x12(%ebp,%ebp,2)
+ mov %ds,%ds:0x12(%esi,%ebp,2)
+ mov %ds,%ds:0x12(%edi,%ebp,2)
+ mov %ds,%ds:0x12(%eax,%esi,2)
+ mov %ds,%ds:0x12(%ecx,%esi,2)
+ mov %ds,%ds:0x12(%edx,%esi,2)
+ mov %ds,%ds:0x12(%ebx,%esi,2)
+ mov %ds,%ds:0x12(%esp,%esi,2)
+ mov %ds,%ds:0x12(%ebp,%esi,2)
+ mov %ds,%ds:0x12(%esi,%esi,2)
+ mov %ds,%ds:0x12(%edi,%esi,2)
+ mov %ds,%ds:0x12(%eax,%edi,2)
+ mov %ds,%ds:0x12(%ecx,%edi,2)
+ mov %ds,%ds:0x12(%edx,%edi,2)
+ mov %ds,%ds:0x12(%ebx,%edi,2)
+ mov %ds,%ds:0x12(%esp,%edi,2)
+ mov %ds,%ds:0x12(%ebp,%edi,2)
+ mov %ds,%ds:0x12(%esi,%edi,2)
+ mov %ds,%ds:0x12(%edi,%edi,2)
+ mov %ds,%ds:0x12(%eax,%eax,4)
+ mov %ds,%ds:0x12(%ecx,%eax,4)
+ mov %ds,%ds:0x12(%edx,%eax,4)
+ mov %ds,%ds:0x12(%ebx,%eax,4)
+ mov %ds,%ds:0x12(%esp,%eax,4)
+ mov %ds,%ds:0x12(%ebp,%eax,4)
+ mov %ds,%ds:0x12(%esi,%eax,4)
+ mov %ds,%ds:0x12(%edi,%eax,4)
+ mov %ds,%ds:0x12(%eax,%ecx,4)
+ mov %ds,%ds:0x12(%ecx,%ecx,4)
+ mov %ds,%ds:0x12(%edx,%ecx,4)
+ mov %ds,%ds:0x12(%ebx,%ecx,4)
+ mov %ds,%ds:0x12(%esp,%ecx,4)
+ mov %ds,%ds:0x12(%ebp,%ecx,4)
+ mov %ds,%ds:0x12(%esi,%ecx,4)
+ mov %ds,%ds:0x12(%edi,%ecx,4)
+ mov %ds,%ds:0x12(%eax,%edx,4)
+ mov %ds,%ds:0x12(%ecx,%edx,4)
+ mov %ds,%ds:0x12(%edx,%edx,4)
+ mov %ds,%ds:0x12(%ebx,%edx,4)
+ mov %ds,%ds:0x12(%esp,%edx,4)
+ mov %ds,%ds:0x12(%ebp,%edx,4)
+ mov %ds,%ds:0x12(%esi,%edx,4)
+ mov %ds,%ds:0x12(%edi,%edx,4)
+ mov %ds,%ds:0x12(%eax,%ebx,4)
+ mov %ds,%ds:0x12(%ecx,%ebx,4)
+ mov %ds,%ds:0x12(%edx,%ebx,4)
+ mov %ds,%ds:0x12(%ebx,%ebx,4)
+ mov %ds,%ds:0x12(%esp,%ebx,4)
+ mov %ds,%ds:0x12(%ebp,%ebx,4)
+ mov %ds,%ds:0x12(%esi,%ebx,4)
+ mov %ds,%ds:0x12(%edi,%ebx,4)
+ mov %ds,%ds:0x12(%eax,4)
+ mov %ds,%ds:0x12(%ecx,4)
+ mov %ds,%ds:0x12(%edx,4)
+ mov %ds,%ds:0x12(%ebx,4)
+ mov %ds,%ds:0x12(%esp,4)
+ mov %ds,%ds:0x12(%ebp,4)
+ mov %ds,%ds:0x12(%esi,4)
+ mov %ds,%ds:0x12(%edi,4)
+ mov %ds,%ds:0x12(%eax,%ebp,4)
+ mov %ds,%ds:0x12(%ecx,%ebp,4)
+ mov %ds,%ds:0x12(%edx,%ebp,4)
+ mov %ds,%ds:0x12(%ebx,%ebp,4)
+ mov %ds,%ds:0x12(%esp,%ebp,4)
+ mov %ds,%ds:0x12(%ebp,%ebp,4)
+ mov %ds,%ds:0x12(%esi,%ebp,4)
+ mov %ds,%ds:0x12(%edi,%ebp,4)
+ mov %ds,%ds:0x12(%eax,%esi,4)
+ mov %ds,%ds:0x12(%ecx,%esi,4)
+ mov %ds,%ds:0x12(%edx,%esi,4)
+ mov %ds,%ds:0x12(%ebx,%esi,4)
+ mov %ds,%ds:0x12(%esp,%esi,4)
+ mov %ds,%ds:0x12(%ebp,%esi,4)
+ mov %ds,%ds:0x12(%esi,%esi,4)
+ mov %ds,%ds:0x12(%edi,%esi,4)
+ mov %ds,%ds:0x12(%eax,%edi,4)
+ mov %ds,%ds:0x12(%ecx,%edi,4)
+ mov %ds,%ds:0x12(%edx,%edi,4)
+ mov %ds,%ds:0x12(%ebx,%edi,4)
+ mov %ds,%ds:0x12(%esp,%edi,4)
+ mov %ds,%ds:0x12(%ebp,%edi,4)
+ mov %ds,%ds:0x12(%esi,%edi,4)
+ mov %ds,%ds:0x12(%edi,%edi,4)
+ mov %ds,%ds:0x12(%eax,%eax,8)
+ mov %ds,%ds:0x12(%ecx,%eax,8)
+ mov %ds,%ds:0x12(%edx,%eax,8)
+ mov %ds,%ds:0x12(%ebx,%eax,8)
+ mov %ds,%ds:0x12(%esp,%eax,8)
+ mov %ds,%ds:0x12(%ebp,%eax,8)
+ mov %ds,%ds:0x12(%esi,%eax,8)
+ mov %ds,%ds:0x12(%edi,%eax,8)
+ mov %ds,%ds:0x12(%eax,%ecx,8)
+ mov %ds,%ds:0x12(%ecx,%ecx,8)
+ mov %ds,%ds:0x12(%edx,%ecx,8)
+ mov %ds,%ds:0x12(%ebx,%ecx,8)
+ mov %ds,%ds:0x12(%esp,%ecx,8)
+ mov %ds,%ds:0x12(%ebp,%ecx,8)
+ mov %ds,%ds:0x12(%esi,%ecx,8)
+ mov %ds,%ds:0x12(%edi,%ecx,8)
+ mov %ds,%ds:0x12(%eax,%edx,8)
+ mov %ds,%ds:0x12(%ecx,%edx,8)
+ mov %ds,%ds:0x12(%edx,%edx,8)
+ mov %ds,%ds:0x12(%ebx,%edx,8)
+ mov %ds,%ds:0x12(%esp,%edx,8)
+ mov %ds,%ds:0x12(%ebp,%edx,8)
+ mov %ds,%ds:0x12(%esi,%edx,8)
+ mov %ds,%ds:0x12(%edi,%edx,8)
+ mov %ds,%ds:0x12(%eax,%ebx,8)
+ mov %ds,%ds:0x12(%ecx,%ebx,8)
+ mov %ds,%ds:0x12(%edx,%ebx,8)
+ mov %ds,%ds:0x12(%ebx,%ebx,8)
+ mov %ds,%ds:0x12(%esp,%ebx,8)
+ mov %ds,%ds:0x12(%ebp,%ebx,8)
+ mov %ds,%ds:0x12(%esi,%ebx,8)
+ mov %ds,%ds:0x12(%edi,%ebx,8)
+ mov %ds,%ds:0x12(%eax,8)
+ mov %ds,%ds:0x12(%ecx,8)
+ mov %ds,%ds:0x12(%edx,8)
+ mov %ds,%ds:0x12(%ebx,8)
+ mov %ds,%ds:0x12(%esp,8)
+ mov %ds,%ds:0x12(%ebp,8)
+ mov %ds,%ds:0x12(%esi,8)
+ mov %ds,%ds:0x12(%edi,8)
+ mov %ds,%ds:0x12(%eax,%ebp,8)
+ mov %ds,%ds:0x12(%ecx,%ebp,8)
+ mov %ds,%ds:0x12(%edx,%ebp,8)
+ mov %ds,%ds:0x12(%ebx,%ebp,8)
+ mov %ds,%ds:0x12(%esp,%ebp,8)
+ mov %ds,%ds:0x12(%ebp,%ebp,8)
+ mov %ds,%ds:0x12(%esi,%ebp,8)
+ mov %ds,%ds:0x12(%edi,%ebp,8)
+ mov %ds,%ds:0x12(%eax,%esi,8)
+ mov %ds,%ds:0x12(%ecx,%esi,8)
+ mov %ds,%ds:0x12(%edx,%esi,8)
+ mov %ds,%ds:0x12(%ebx,%esi,8)
+ mov %ds,%ds:0x12(%esp,%esi,8)
+ mov %ds,%ds:0x12(%ebp,%esi,8)
+ mov %ds,%ds:0x12(%esi,%esi,8)
+ mov %ds,%ds:0x12(%edi,%esi,8)
+ mov %ds,%ds:0x12(%eax,%edi,8)
+ mov %ds,%ds:0x12(%edx,%edi,8)
+ mov %ds,%ds:0x12(%ecx,%edi,8)
+ mov %ds,%ds:0x12(%ebx,%edi,8)
+ mov %ds,%ds:0x12(%esp,%edi,8)
+ mov %ds,%ds:0x12(%ebp,%edi,8)
+ mov %ds,%ds:0x12(%esi,%edi,8)
+ mov %ds,%ds:0x12(%edi,%edi,8)
+ mov %ds,%ds:0x12345678(%eax,%eax,1)
+ mov %ds,%ds:0x12345678(%ecx,%eax,1)
+ mov %ds,%ds:0x12345678(%edx,%eax,1)
+ mov %ds,%ds:0x12345678(%ebx,%eax,1)
+ mov %ds,%ds:0x12345678(%esp,%eax,1)
+ mov %ds,%ds:0x12345678(%ebp,%eax,1)
+ mov %ds,%ds:0x12345678(%esi,%eax,1)
+ mov %ds,%ds:0x12345678(%edi,%eax,1)
+ mov %ds,%ds:0x12345678(%eax,%ecx,1)
+ mov %ds,%ds:0x12345678(%ecx,%ecx,1)
+ mov %ds,%ds:0x12345678(%edx,%ecx,1)
+ mov %ds,%ds:0x12345678(%ebx,%ecx,1)
+ mov %ds,%ds:0x12345678(%esp,%ecx,1)
+ mov %ds,%ds:0x12345678(%ebp,%ecx,1)
+ mov %ds,%ds:0x12345678(%esi,%ecx,1)
+ mov %ds,%ds:0x12345678(%edi,%ecx,1)
+ mov %ds,%ds:0x12345678(%eax,%edx,1)
+ mov %ds,%ds:0x12345678(%ecx,%edx,1)
+ mov %ds,%ds:0x12345678(%edx,%edx,1)
+ mov %ds,%ds:0x12345678(%ebx,%edx,1)
+ mov %ds,%ds:0x12345678(%esp,%edx,1)
+ mov %ds,%ds:0x12345678(%ebp,%edx,1)
+ mov %ds,%ds:0x12345678(%esi,%edx,1)
+ mov %ds,%ds:0x12345678(%edi,%edx,1)
+ mov %ds,%ds:0x12345678(%eax,%ebx,1)
+ mov %ds,%ds:0x12345678(%ecx,%ebx,1)
+ mov %ds,%ds:0x12345678(%edx,%ebx,1)
+ mov %ds,%ds:0x12345678(%ebx,%ebx,1)
+ mov %ds,%ds:0x12345678(%esp,%ebx,1)
+ mov %ds,%ds:0x12345678(%ebp,%ebx,1)
+ mov %ds,%ds:0x12345678(%esi,%ebx,1)
+ mov %ds,%ds:0x12345678(%edi,%ebx,1)
+ mov %ds,%ds:0x12345678(%eax,1)
+ mov %ds,%ds:0x12345678(%ecx,1)
+ mov %ds,%ds:0x12345678(%edx,1)
+ mov %ds,%ds:0x12345678(%ebx,1)
+ mov %ds,%ds:0x12345678(%esp,1)
+ mov %ds,%ds:0x12345678(%ebp,1)
+ mov %ds,%ds:0x12345678(%esi,1)
+ mov %ds,%ds:0x12345678(%edi,1)
+ mov %ds,%ds:0x12345678(%eax,%ebp,1)
+ mov %ds,%ds:0x12345678(%ecx,%ebp,1)
+ mov %ds,%ds:0x12345678(%edx,%ebp,1)
+ mov %ds,%ds:0x12345678(%ebx,%ebp,1)
+ mov %ds,%ds:0x12345678(%esp,%ebp,1)
+ mov %ds,%ds:0x12345678(%ebp,%ebp,1)
+ mov %ds,%ds:0x12345678(%esi,%ebp,1)
+ mov %ds,%ds:0x12345678(%edi,%ebp,1)
+ mov %ds,%ds:0x12345678(%eax,%esi,1)
+ mov %ds,%ds:0x12345678(%ecx,%esi,1)
+ mov %ds,%ds:0x12345678(%edx,%esi,1)
+ mov %ds,%ds:0x12345678(%ebx,%esi,1)
+ mov %ds,%ds:0x12345678(%esp,%esi,1)
+ mov %ds,%ds:0x12345678(%ebp,%esi,1)
+ mov %ds,%ds:0x12345678(%esi,%esi,1)
+ mov %ds,%ds:0x12345678(%edi,%esi,1)
+ mov %ds,%ds:0x12345678(%eax,%edi,1)
+ mov %ds,%ds:0x12345678(%ecx,%edi,1)
+ mov %ds,%ds:0x12345678(%edx,%edi,1)
+ mov %ds,%ds:0x12345678(%ebx,%edi,1)
+ mov %ds,%ds:0x12345678(%esp,%edi,1)
+ mov %ds,%ds:0x12345678(%ebp,%edi,1)
+ mov %ds,%ds:0x12345678(%esi,%edi,1)
+ mov %ds,%ds:0x12345678(%edi,%edi,1)
+ mov %ds,%ds:0x12345678(%eax,%eax,2)
+ mov %ds,%ds:0x12345678(%ecx,%eax,2)
+ mov %ds,%ds:0x12345678(%edx,%eax,2)
+ mov %ds,%ds:0x12345678(%ebx,%eax,2)
+ mov %ds,%ds:0x12345678(%esp,%eax,2)
+ mov %ds,%ds:0x12345678(%ebp,%eax,2)
+ mov %ds,%ds:0x12345678(%esi,%eax,2)
+ mov %ds,%ds:0x12345678(%edi,%eax,2)
+ mov %ds,%ds:0x12345678(%eax,%ecx,2)
+ mov %ds,%ds:0x12345678(%ecx,%ecx,2)
+ mov %ds,%ds:0x12345678(%edx,%ecx,2)
+ mov %ds,%ds:0x12345678(%ebx,%ecx,2)
+ mov %ds,%ds:0x12345678(%esp,%ecx,2)
+ mov %ds,%ds:0x12345678(%ebp,%ecx,2)
+ mov %ds,%ds:0x12345678(%esi,%ecx,2)
+ mov %ds,%ds:0x12345678(%edi,%ecx,2)
+ mov %ds,%ds:0x12345678(%eax,%edx,2)
+ mov %ds,%ds:0x12345678(%ecx,%edx,2)
+ mov %ds,%ds:0x12345678(%edx,%edx,2)
+ mov %ds,%ds:0x12345678(%ebx,%edx,2)
+ mov %ds,%ds:0x12345678(%esp,%edx,2)
+ mov %ds,%ds:0x12345678(%ebp,%edx,2)
+ mov %ds,%ds:0x12345678(%esi,%edx,2)
+ mov %ds,%ds:0x12345678(%edi,%edx,2)
+ mov %ds,%ds:0x12345678(%eax,%ebx,2)
+ mov %ds,%ds:0x12345678(%ecx,%ebx,2)
+ mov %ds,%ds:0x12345678(%edx,%ebx,2)
+ mov %ds,%ds:0x12345678(%ebx,%ebx,2)
+ mov %ds,%ds:0x12345678(%esp,%ebx,2)
+ mov %ds,%ds:0x12345678(%ebp,%ebx,2)
+ mov %ds,%ds:0x12345678(%esi,%ebx,2)
+ mov %ds,%ds:0x12345678(%edi,%ebx,2)
+ mov %ds,%ds:0x12345678(%eax,2)
+ mov %ds,%ds:0x12345678(%ecx,2)
+ mov %ds,%ds:0x12345678(%edx,2)
+ mov %ds,%ds:0x12345678(%ebx,2)
+ mov %ds,%ds:0x12345678(%esp,2)
+ mov %ds,%ds:0x12345678(%ebp,2)
+ mov %ds,%ds:0x12345678(%esi,2)
+ mov %ds,%ds:0x12345678(%edi,2)
+ mov %ds,%ds:0x12345678(%eax,%ebp,2)
+ mov %ds,%ds:0x12345678(%ecx,%ebp,2)
+ mov %ds,%ds:0x12345678(%edx,%ebp,2)
+ mov %ds,%ds:0x12345678(%ebx,%ebp,2)
+ mov %ds,%ds:0x12345678(%esp,%ebp,2)
+ mov %ds,%ds:0x12345678(%ebp,%ebp,2)
+ mov %ds,%ds:0x12345678(%esi,%ebp,2)
+ mov %ds,%ds:0x12345678(%edi,%ebp,2)
+ mov %ds,%ds:0x12345678(%eax,%esi,2)
+ mov %ds,%ds:0x12345678(%ecx,%esi,2)
+ mov %ds,%ds:0x12345678(%edx,%esi,2)
+ mov %ds,%ds:0x12345678(%ebx,%esi,2)
+ mov %ds,%ds:0x12345678(%esp,%esi,2)
+ mov %ds,%ds:0x12345678(%ebp,%esi,2)
+ mov %ds,%ds:0x12345678(%esi,%esi,2)
+ mov %ds,%ds:0x12345678(%edi,%esi,2)
+ mov %ds,%ds:0x12345678(%eax,%edi,2)
+ mov %ds,%ds:0x12345678(%ecx,%edi,2)
+ mov %ds,%ds:0x12345678(%edx,%edi,2)
+ mov %ds,%ds:0x12345678(%ebx,%edi,2)
+ mov %ds,%ds:0x12345678(%esp,%edi,2)
+ mov %ds,%ds:0x12345678(%ebp,%edi,2)
+ mov %ds,%ds:0x12345678(%esi,%edi,2)
+ mov %ds,%ds:0x12345678(%edi,%edi,2)
+ mov %ds,%ds:0x12345678(%eax,%eax,4)
+ mov %ds,%ds:0x12345678(%ecx,%eax,4)
+ mov %ds,%ds:0x12345678(%edx,%eax,4)
+ mov %ds,%ds:0x12345678(%ebx,%eax,4)
+ mov %ds,%ds:0x12345678(%esp,%eax,4)
+ mov %ds,%ds:0x12345678(%ebp,%eax,4)
+ mov %ds,%ds:0x12345678(%esi,%eax,4)
+ mov %ds,%ds:0x12345678(%edi,%eax,4)
+ mov %ds,%ds:0x12345678(%eax,%ecx,4)
+ mov %ds,%ds:0x12345678(%ecx,%ecx,4)
+ mov %ds,%ds:0x12345678(%edx,%ecx,4)
+ mov %ds,%ds:0x12345678(%ebx,%ecx,4)
+ mov %ds,%ds:0x12345678(%esp,%ecx,4)
+ mov %ds,%ds:0x12345678(%ebp,%ecx,4)
+ mov %ds,%ds:0x12345678(%esi,%ecx,4)
+ mov %ds,%ds:0x12345678(%edi,%ecx,4)
+ mov %ds,%ds:0x12345678(%eax,%edx,4)
+ mov %ds,%ds:0x12345678(%ecx,%edx,4)
+ mov %ds,%ds:0x12345678(%edx,%edx,4)
+ mov %ds,%ds:0x12345678(%ebx,%edx,4)
+ mov %ds,%ds:0x12345678(%esp,%edx,4)
+ mov %ds,%ds:0x12345678(%ebp,%edx,4)
+ mov %ds,%ds:0x12345678(%esi,%edx,4)
+ mov %ds,%ds:0x12345678(%edi,%edx,4)
+ mov %ds,%ds:0x12345678(%eax,%ebx,4)
+ mov %ds,%ds:0x12345678(%ecx,%ebx,4)
+ mov %ds,%ds:0x12345678(%edx,%ebx,4)
+ mov %ds,%ds:0x12345678(%ebx,%ebx,4)
+ mov %ds,%ds:0x12345678(%esp,%ebx,4)
+ mov %ds,%ds:0x12345678(%ebp,%ebx,4)
+ mov %ds,%ds:0x12345678(%esi,%ebx,4)
+ mov %ds,%ds:0x12345678(%edi,%ebx,4)
+ mov %ds,%ds:0x12345678(%eax,4)
+ mov %ds,%ds:0x12345678(%ecx,4)
+ mov %ds,%ds:0x12345678(%edx,4)
+ mov %ds,%ds:0x12345678(%ebx,4)
+ mov %ds,%ds:0x12345678(%esp,4)
+ mov %ds,%ds:0x12345678(%ebp,4)
+ mov %ds,%ds:0x12345678(%esi,4)
+ mov %ds,%ds:0x12345678(%edi,4)
+ mov %ds,%ds:0x12345678(%eax,%ebp,4)
+ mov %ds,%ds:0x12345678(%ecx,%ebp,4)
+ mov %ds,%ds:0x12345678(%edx,%ebp,4)
+ mov %ds,%ds:0x12345678(%ebx,%ebp,4)
+ mov %ds,%ds:0x12345678(%esp,%ebp,4)
+ mov %ds,%ds:0x12345678(%ebp,%ebp,4)
+ mov %ds,%ds:0x12345678(%esi,%ebp,4)
+ mov %ds,%ds:0x12345678(%edi,%ebp,4)
+ mov %ds,%ds:0x12345678(%eax,%esi,4)
+ mov %ds,%ds:0x12345678(%ecx,%esi,4)
+ mov %ds,%ds:0x12345678(%edx,%esi,4)
+ mov %ds,%ds:0x12345678(%ebx,%esi,4)
+ mov %ds,%ds:0x12345678(%esp,%esi,4)
+ mov %ds,%ds:0x12345678(%ebp,%esi,4)
+ mov %ds,%ds:0x12345678(%esi,%esi,4)
+ mov %ds,%ds:0x12345678(%edi,%esi,4)
+ mov %ds,%ds:0x12345678(%eax,%edi,4)
+ mov %ds,%ds:0x12345678(%ecx,%edi,4)
+ mov %ds,%ds:0x12345678(%edx,%edi,4)
+ mov %ds,%ds:0x12345678(%ebx,%edi,4)
+ mov %ds,%ds:0x12345678(%esp,%edi,4)
+ mov %ds,%ds:0x12345678(%ebp,%edi,4)
+ mov %ds,%ds:0x12345678(%esi,%edi,4)
+ mov %ds,%ds:0x12345678(%edi,%edi,4)
+ mov %ds,%ds:0x12345678(%eax,%eax,8)
+ mov %ds,%ds:0x12345678(%ecx,%eax,8)
+ mov %ds,%ds:0x12345678(%edx,%eax,8)
+ mov %ds,%ds:0x12345678(%ebx,%eax,8)
+ mov %ds,%ds:0x12345678(%esp,%eax,8)
+ mov %ds,%ds:0x12345678(%ebp,%eax,8)
+ mov %ds,%ds:0x12345678(%esi,%eax,8)
+ mov %ds,%ds:0x12345678(%edi,%eax,8)
+ mov %ds,%ds:0x12345678(%eax,%ecx,8)
+ mov %ds,%ds:0x12345678(%ecx,%ecx,8)
+ mov %ds,%ds:0x12345678(%edx,%ecx,8)
+ mov %ds,%ds:0x12345678(%ebx,%ecx,8)
+ mov %ds,%ds:0x12345678(%esp,%ecx,8)
+ mov %ds,%ds:0x12345678(%ebp,%ecx,8)
+ mov %ds,%ds:0x12345678(%esi,%ecx,8)
+ mov %ds,%ds:0x12345678(%edi,%ecx,8)
+ mov %ds,%ds:0x12345678(%eax,%edx,8)
+ mov %ds,%ds:0x12345678(%ecx,%edx,8)
+ mov %ds,%ds:0x12345678(%edx,%edx,8)
+ mov %ds,%ds:0x12345678(%ebx,%edx,8)
+ mov %ds,%ds:0x12345678(%esp,%edx,8)
+ mov %ds,%ds:0x12345678(%ebp,%edx,8)
+ mov %ds,%ds:0x12345678(%esi,%edx,8)
+ mov %ds,%ds:0x12345678(%edi,%edx,8)
+ mov %ds,%ds:0x12345678(%eax,%ebx,8)
+ mov %ds,%ds:0x12345678(%ecx,%ebx,8)
+ mov %ds,%ds:0x12345678(%edx,%ebx,8)
+ mov %ds,%ds:0x12345678(%ebx,%ebx,8)
+ mov %ds,%ds:0x12345678(%esp,%ebx,8)
+ mov %ds,%ds:0x12345678(%ebp,%ebx,8)
+ mov %ds,%ds:0x12345678(%esi,%ebx,8)
+ mov %ds,%ds:0x12345678(%edi,%ebx,8)
+ mov %ds,%ds:0x12345678(%eax,8)
+ mov %ds,%ds:0x12345678(%ecx,8)
+ mov %ds,%ds:0x12345678(%edx,8)
+ mov %ds,%ds:0x12345678(%ebx,8)
+ mov %ds,%ds:0x12345678(%esp,8)
+ mov %ds,%ds:0x12345678(%ebp,8)
+ mov %ds,%ds:0x12345678(%esi,8)
+ mov %ds,%ds:0x12345678(%edi,8)
+ mov %ds,%ds:0x12345678(%eax,%ebp,8)
+ mov %ds,%ds:0x12345678(%ecx,%ebp,8)
+ mov %ds,%ds:0x12345678(%edx,%ebp,8)
+ mov %ds,%ds:0x12345678(%ebx,%ebp,8)
+ mov %ds,%ds:0x12345678(%esp,%ebp,8)
+ mov %ds,%ds:0x12345678(%ebp,%ebp,8)
+ mov %ds,%ds:0x12345678(%esi,%ebp,8)
+ mov %ds,%ds:0x12345678(%edi,%ebp,8)
+ mov %ds,%ds:0x12345678(%eax,%esi,8)
+ mov %ds,%ds:0x12345678(%ecx,%esi,8)
+ mov %ds,%ds:0x12345678(%edx,%esi,8)
+ mov %ds,%ds:0x12345678(%ebx,%esi,8)
+ mov %ds,%ds:0x12345678(%esp,%esi,8)
+ mov %ds,%ds:0x12345678(%ebp,%esi,8)
+ mov %ds,%ds:0x12345678(%esi,%esi,8)
+ mov %ds,%ds:0x12345678(%edi,%esi,8)
+ mov %ds,%ds:0x12345678(%eax,%edi,8)
+ mov %ds,%ds:0x12345678(%edx,%edi,8)
+ mov %ds,%ds:0x12345678(%ecx,%edi,8)
+ mov %ds,%ds:0x12345678(%ebx,%edi,8)
+ mov %ds,%ds:0x12345678(%esp,%edi,8)
+ mov %ds,%ds:0x12345678(%ebp,%edi,8)
+ mov %ds,%ds:0x12345678(%esi,%edi,8)
+ mov %ds,%ds:0x12345678(%edi,%edi,8)
+ mov %ds,%ds:(%ebp,%eax,1)
+ mov %ds,%ds:(%ebp,%ecx,1)
+ mov %ds,%ds:(%ebp,%edx,1)
+ mov %ds,%ds:(%ebp,%ebx,1)
+ mov %ds,%ds:(%ebp,1)
+ mov %ds,%ds:(%ebp,%ebp,1)
+ mov %ds,%ds:(%ebp,%esi,1)
+ mov %ds,%ds:(%ebp,%edi,1)
+ mov %ds,%ds:(%ebp,%eax,2)
+ mov %ds,%ds:(%ebp,%ecx,2)
+ mov %ds,%ds:(%ebp,%edx,2)
+ mov %ds,%ds:(%ebp,%ebx,2)
+ mov %ds,%ds:(%ebp,2)
+ mov %ds,%ds:(%ebp,%ebp,2)
+ mov %ds,%ds:(%ebp,%esi,2)
+ mov %ds,%ds:(%ebp,%edi,2)
+ mov %ds,%ds:(%ebp,%eax,4)
+ mov %ds,%ds:(%ebp,%ecx,4)
+ mov %ds,%ds:(%ebp,%edx,4)
+ mov %ds,%ds:(%ebp,%ebx,4)
+ mov %ds,%ds:(%ebp,4)
+ mov %ds,%ds:(%ebp,%ebp,4)
+ mov %ds,%ds:(%ebp,%esi,4)
+ mov %ds,%ds:(%ebp,%edi,4)
+ mov %ds,%ds:(%ebp,%eax,8)
+ mov %ds,%ds:(%ebp,%ecx,8)
+ mov %ds,%ds:(%ebp,%edx,8)
+ mov %ds,%ds:(%ebp,%ebx,8)
+ mov %ds,%ds:(%ebp,8)
+ mov %ds,%ds:(%ebp,%ebp,8)
+ mov %ds,%ds:(%ebp,%esi,8)
+ mov %ds,%ds:(%ebp,%edi,8)
+ mov %ds,%ds:0x12(,1)
+ mov %ds,%ds:0x12(,2)
+ mov %ds,%ds:0x12(,4)
+ mov %ds,%ds:0x12(,8)
+
+ # Force a good alignment.
+ .byte 0
diff --git a/gas/testsuite/gas/i386/opcode.d b/gas/testsuite/gas/i386/opcode.d
new file mode 100644
index 00000000000..fc3c158a161
--- /dev/null
+++ b/gas/testsuite/gas/i386/opcode.d
@@ -0,0 +1,574 @@
+#as: -J
+#objdump: -dw
+#name: i386 opcode
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <foo>:
+ 0: 00 90 90 90 90 90 [ ]*add %dl,0x90909090\(%eax\)
+ 6: 01 90 90 90 90 90 [ ]*add %edx,0x90909090\(%eax\)
+ c: 02 90 90 90 90 90 [ ]*add 0x90909090\(%eax\),%dl
+ 12: 03 90 90 90 90 90 [ ]*add 0x90909090\(%eax\),%edx
+ 18: 04 90 [ ]*add \$0x90,%al
+ 1a: 05 90 90 90 90 [ ]*add \$0x90909090,%eax
+ 1f: 06 [ ]*push %es
+ 20: 07 [ ]*pop %es
+ 21: 08 90 90 90 90 90 [ ]*or %dl,0x90909090\(%eax\)
+ 27: 09 90 90 90 90 90 [ ]*or %edx,0x90909090\(%eax\)
+ 2d: 0a 90 90 90 90 90 [ ]*or 0x90909090\(%eax\),%dl
+ 33: 0b 90 90 90 90 90 [ ]*or 0x90909090\(%eax\),%edx
+ 39: 0c 90 [ ]*or \$0x90,%al
+ 3b: 0d 90 90 90 90 [ ]*or \$0x90909090,%eax
+ 40: 0e [ ]*push %cs
+ 41: 10 90 90 90 90 90 [ ]*adc %dl,0x90909090\(%eax\)
+ 47: 11 90 90 90 90 90 [ ]*adc %edx,0x90909090\(%eax\)
+ 4d: 12 90 90 90 90 90 [ ]*adc 0x90909090\(%eax\),%dl
+ 53: 13 90 90 90 90 90 [ ]*adc 0x90909090\(%eax\),%edx
+ 59: 14 90 [ ]*adc \$0x90,%al
+ 5b: 15 90 90 90 90 [ ]*adc \$0x90909090,%eax
+ 60: 16 [ ]*push %ss
+ 61: 17 [ ]*pop %ss
+ 62: 18 90 90 90 90 90 [ ]*sbb %dl,0x90909090\(%eax\)
+ 68: 19 90 90 90 90 90 [ ]*sbb %edx,0x90909090\(%eax\)
+ 6e: 1a 90 90 90 90 90 [ ]*sbb 0x90909090\(%eax\),%dl
+ 74: 1b 90 90 90 90 90 [ ]*sbb 0x90909090\(%eax\),%edx
+ 7a: 1c 90 [ ]*sbb \$0x90,%al
+ 7c: 1d 90 90 90 90 [ ]*sbb \$0x90909090,%eax
+ 81: 1e [ ]*push %ds
+ 82: 1f [ ]*pop %ds
+ 83: 20 90 90 90 90 90 [ ]*and %dl,0x90909090\(%eax\)
+ 89: 21 90 90 90 90 90 [ ]*and %edx,0x90909090\(%eax\)
+ 8f: 22 90 90 90 90 90 [ ]*and 0x90909090\(%eax\),%dl
+ 95: 23 90 90 90 90 90 [ ]*and 0x90909090\(%eax\),%edx
+ 9b: 24 90 [ ]*and \$0x90,%al
+ 9d: 25 90 90 90 90 [ ]*and \$0x90909090,%eax
+ a2: 27 [ ]*daa
+ a3: 28 90 90 90 90 90 [ ]*sub %dl,0x90909090\(%eax\)
+ a9: 29 90 90 90 90 90 [ ]*sub %edx,0x90909090\(%eax\)
+ af: 2a 90 90 90 90 90 [ ]*sub 0x90909090\(%eax\),%dl
+ b5: 2b 90 90 90 90 90 [ ]*sub 0x90909090\(%eax\),%edx
+ bb: 2c 90 [ ]*sub \$0x90,%al
+ bd: 2d 90 90 90 90 [ ]*sub \$0x90909090,%eax
+ c2: 2f [ ]*das
+ c3: 30 90 90 90 90 90 [ ]*xor %dl,0x90909090\(%eax\)
+ c9: 31 90 90 90 90 90 [ ]*xor %edx,0x90909090\(%eax\)
+ cf: 32 90 90 90 90 90 [ ]*xor 0x90909090\(%eax\),%dl
+ d5: 33 90 90 90 90 90 [ ]*xor 0x90909090\(%eax\),%edx
+ db: 34 90 [ ]*xor \$0x90,%al
+ dd: 35 90 90 90 90 [ ]*xor \$0x90909090,%eax
+ e2: 37 [ ]*aaa
+ e3: 38 90 90 90 90 90 [ ]*cmp %dl,0x90909090\(%eax\)
+ e9: 39 90 90 90 90 90 [ ]*cmp %edx,0x90909090\(%eax\)
+ ef: 3a 90 90 90 90 90 [ ]*cmp 0x90909090\(%eax\),%dl
+ f5: 3b 90 90 90 90 90 [ ]*cmp 0x90909090\(%eax\),%edx
+ fb: 3c 90 [ ]*cmp \$0x90,%al
+ fd: 3d 90 90 90 90 [ ]*cmp \$0x90909090,%eax
+ 102: 3f [ ]*aas
+ 103: 40 [ ]*inc %eax
+ 104: 41 [ ]*inc %ecx
+ 105: 42 [ ]*inc %edx
+ 106: 43 [ ]*inc %ebx
+ 107: 44 [ ]*inc %esp
+ 108: 45 [ ]*inc %ebp
+ 109: 46 [ ]*inc %esi
+ 10a: 47 [ ]*inc %edi
+ 10b: 48 [ ]*dec %eax
+ 10c: 49 [ ]*dec %ecx
+ 10d: 4a [ ]*dec %edx
+ 10e: 4b [ ]*dec %ebx
+ 10f: 4c [ ]*dec %esp
+ 110: 4d [ ]*dec %ebp
+ 111: 4e [ ]*dec %esi
+ 112: 4f [ ]*dec %edi
+ 113: 50 [ ]*push %eax
+ 114: 51 [ ]*push %ecx
+ 115: 52 [ ]*push %edx
+ 116: 53 [ ]*push %ebx
+ 117: 54 [ ]*push %esp
+ 118: 55 [ ]*push %ebp
+ 119: 56 [ ]*push %esi
+ 11a: 57 [ ]*push %edi
+ 11b: 58 [ ]*pop %eax
+ 11c: 59 [ ]*pop %ecx
+ 11d: 5a [ ]*pop %edx
+ 11e: 5b [ ]*pop %ebx
+ 11f: 5c [ ]*pop %esp
+ 120: 5d [ ]*pop %ebp
+ 121: 5e [ ]*pop %esi
+ 122: 5f [ ]*pop %edi
+ 123: 60 [ ]*pusha
+ 124: 61 [ ]*popa
+ 125: 62 90 90 90 90 90 [ ]*bound %edx,0x90909090\(%eax\)
+ 12b: 63 90 90 90 90 90 [ ]*arpl %dx,0x90909090\(%eax\)
+ 131: 68 90 90 90 90 [ ]*push \$0x90909090
+ 136: 69 90 90 90 90 90 90 90 90 90 [ ]*imul \$0x90909090,0x90909090\(%eax\),%edx
+ 140: 6a 90 [ ]*push \$0xffffff90
+ 142: 6b 90 90 90 90 90 90 [ ]*imul \$0xffffff90,0x90909090\(%eax\),%edx
+ 149: 6c [ ]*insb \(%dx\),%es:\(%edi\)
+ 14a: 6d [ ]*insl \(%dx\),%es:\(%edi\)
+ 14b: 6e [ ]*outsb %ds:\(%esi\),\(%dx\)
+ 14c: 6f [ ]*outsl %ds:\(%esi\),\(%dx\)
+ 14d: 70 90 [ ]*jo (0x)?df.*
+ 14f: 71 90 [ ]*jno (0x)?e1.*
+ 151: 72 90 [ ]*jb (0x)?e3.*
+ 153: 73 90 [ ]*jae (0x)?e5.*
+ 155: 74 90 [ ]*je (0x)?e7.*
+ 157: 75 90 [ ]*jne (0x)?e9.*
+ 159: 76 90 [ ]*jbe (0x)?eb.*
+ 15b: 77 90 [ ]*ja (0x)?ed.*
+ 15d: 78 90 [ ]*js (0x)?ef.*
+ 15f: 79 90 [ ]*jns (0x)?f1.*
+ 161: 7a 90 [ ]*jp (0x)?f3.*
+ 163: 7b 90 [ ]*jnp (0x)?f5.*
+ 165: 7c 90 [ ]*jl (0x)?f7.*
+ 167: 7d 90 [ ]*jge (0x)?f9.*
+ 169: 7e 90 [ ]*jle (0x)?fb.*
+ 16b: 7f 90 [ ]*jg (0x)?fd.*
+ 16d: 80 90 90 90 90 90 90 [ ]*adcb \$0x90,0x90909090\(%eax\)
+ 174: 81 90 90 90 90 90 90 90 90 90 [ ]*adcl \$0x90909090,0x90909090\(%eax\)
+ 17e: 83 90 90 90 90 90 90 [ ]*adcl \$0xffffff90,0x90909090\(%eax\)
+ 185: 84 90 90 90 90 90 [ ]*test %dl,0x90909090\(%eax\)
+ 18b: 85 90 90 90 90 90 [ ]*test %edx,0x90909090\(%eax\)
+ 191: 86 90 90 90 90 90 [ ]*xchg %dl,0x90909090\(%eax\)
+ 197: 87 90 90 90 90 90 [ ]*xchg %edx,0x90909090\(%eax\)
+ 19d: 88 90 90 90 90 90 [ ]*mov %dl,0x90909090\(%eax\)
+ 1a3: 89 90 90 90 90 90 [ ]*mov %edx,0x90909090\(%eax\)
+ 1a9: 8a 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%dl
+ 1af: 8b 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%edx
+ 1b5: 8c 90 90 90 90 90 [ ]*movl %ss,0x90909090\(%eax\)
+ 1bb: 8d 90 90 90 90 90 [ ]*lea 0x90909090\(%eax\),%edx
+ 1c1: 8e 90 90 90 90 90 [ ]*movl 0x90909090\(%eax\),%ss
+ 1c7: 8f 80 90 90 90 90 [ ]*popl 0x90909090\(%eax\)
+ 1cd: 90 [ ]*nop
+ 1ce: 91 [ ]*xchg %eax,%ecx
+ 1cf: 92 [ ]*xchg %eax,%edx
+ 1d0: 93 [ ]*xchg %eax,%ebx
+ 1d1: 94 [ ]*xchg %eax,%esp
+ 1d2: 95 [ ]*xchg %eax,%ebp
+ 1d3: 96 [ ]*xchg %eax,%esi
+ 1d4: 97 [ ]*xchg %eax,%edi
+ 1d5: 98 [ ]*cwtl
+ 1d6: 99 [ ]*cltd
+ 1d7: 9a 90 90 90 90 90 90 [ ]*lcall \$0x9090,\$0x90909090
+ 1de: 9b [ ]*fwait
+ 1df: 9c [ ]*pushf
+ 1e0: 9d [ ]*popf
+ 1e1: 9e [ ]*sahf
+ 1e2: 9f [ ]*lahf
+ 1e3: a0 90 90 90 90 [ ]*mov 0x90909090,%al
+ 1e8: a1 90 90 90 90 [ ]*mov 0x90909090,%eax
+ 1ed: a2 90 90 90 90 [ ]*mov %al,0x90909090
+ 1f2: a3 90 90 90 90 [ ]*mov %eax,0x90909090
+ 1f7: a4 [ ]*movsb %ds:\(%esi\),%es:\(%edi\)
+ 1f8: a5 [ ]*movsl %ds:\(%esi\),%es:\(%edi\)
+ 1f9: a6 [ ]*cmpsb %es:\(%edi\),%ds:\(%esi\)
+ 1fa: a7 [ ]*cmpsl %es:\(%edi\),%ds:\(%esi\)
+ 1fb: a8 90 [ ]*test \$0x90,%al
+ 1fd: a9 90 90 90 90 [ ]*test \$0x90909090,%eax
+ 202: aa [ ]*stos %al,%es:\(%edi\)
+ 203: ab [ ]*stos %eax,%es:\(%edi\)
+ 204: ac [ ]*lods %ds:\(%esi\),%al
+ 205: ad [ ]*lods %ds:\(%esi\),%eax
+ 206: ae [ ]*scas %es:\(%edi\),%al
+ 207: af [ ]*scas %es:\(%edi\),%eax
+ 208: b0 90 [ ]*mov \$0x90,%al
+ 20a: b1 90 [ ]*mov \$0x90,%cl
+ 20c: b2 90 [ ]*mov \$0x90,%dl
+ 20e: b3 90 [ ]*mov \$0x90,%bl
+ 210: b4 90 [ ]*mov \$0x90,%ah
+ 212: b5 90 [ ]*mov \$0x90,%ch
+ 214: b6 90 [ ]*mov \$0x90,%dh
+ 216: b7 90 [ ]*mov \$0x90,%bh
+ 218: b8 90 90 90 90 [ ]*mov \$0x90909090,%eax
+ 21d: b9 90 90 90 90 [ ]*mov \$0x90909090,%ecx
+ 222: ba 90 90 90 90 [ ]*mov \$0x90909090,%edx
+ 227: bb 90 90 90 90 [ ]*mov \$0x90909090,%ebx
+ 22c: bc 90 90 90 90 [ ]*mov \$0x90909090,%esp
+ 231: bd 90 90 90 90 [ ]*mov \$0x90909090,%ebp
+ 236: be 90 90 90 90 [ ]*mov \$0x90909090,%esi
+ 23b: bf 90 90 90 90 [ ]*mov \$0x90909090,%edi
+ 240: c0 90 90 90 90 90 90 [ ]*rclb \$0x90,0x90909090\(%eax\)
+ 247: c1 90 90 90 90 90 90 [ ]*rcll \$0x90,0x90909090\(%eax\)
+ 24e: c2 90 90 [ ]*ret \$0x9090
+ 251: c3 [ ]*ret
+ 252: c4 90 90 90 90 90 [ ]*les 0x90909090\(%eax\),%edx
+ 258: c5 90 90 90 90 90 [ ]*lds 0x90909090\(%eax\),%edx
+ 25e: c6 80 90 90 90 90 90 [ ]*movb \$0x90,0x90909090\(%eax\)
+ 265: c7 80 90 90 90 90 90 90 90 90 [ ]*movl \$0x90909090,0x90909090\(%eax\)
+ 26f: c8 90 90 90 [ ]*enter \$0x9090,\$0x90
+ 273: c9 [ ]*leave
+ 274: ca 90 90 [ ]*lret \$0x9090
+ 277: cb [ ]*lret
+ 278: cc [ ]*int3
+ 279: cd 90 [ ]*int \$0x90
+ 27b: ce [ ]*into
+ 27c: cf [ ]*iret
+ 27d: d0 90 90 90 90 90 [ ]*rclb 0x90909090\(%eax\)
+ 283: d1 90 90 90 90 90 [ ]*rcll 0x90909090\(%eax\)
+ 289: d2 90 90 90 90 90 [ ]*rclb %cl,0x90909090\(%eax\)
+ 28f: d3 90 90 90 90 90 [ ]*rcll %cl,0x90909090\(%eax\)
+ 295: d4 90 [ ]*aam \$0xffffff90
+ 297: d5 90 [ ]*aad \$0xffffff90
+ 299: d7 [ ]*xlat %ds:\(%ebx\)
+ 29a: d8 90 90 90 90 90 [ ]*fcoms 0x90909090\(%eax\)
+ 2a0: d9 90 90 90 90 90 [ ]*fsts 0x90909090\(%eax\)
+ 2a6: da 90 90 90 90 90 [ ]*ficoml 0x90909090\(%eax\)
+ 2ac: db 90 90 90 90 90 [ ]*fistl 0x90909090\(%eax\)
+ 2b2: dc 90 90 90 90 90 [ ]*fcoml 0x90909090\(%eax\)
+ 2b8: dd 90 90 90 90 90 [ ]*fstl 0x90909090\(%eax\)
+ 2be: de 90 90 90 90 90 [ ]*ficom 0x90909090\(%eax\)
+ 2c4: df 90 90 90 90 90 [ ]*fist 0x90909090\(%eax\)
+ 2ca: e0 90 [ ]*loopne (0x)?25c.*
+ 2cc: e1 90 [ ]*loope (0x)?25e.*
+ 2ce: e2 90 [ ]*loop (0x)?260.*
+ 2d0: e3 90 [ ]*jecxz (0x)?262.*
+ 2d2: e4 90 [ ]*in \$0x90,%al
+ 2d4: e5 90 [ ]*in \$0x90,%eax
+ 2d6: e6 90 [ ]*out %al,\$0x90
+ 2d8: e7 90 [ ]*out %eax,\$0x90
+ 2da: e8 90 90 90 90 [ ]*call (0x)?9090936f.*
+ 2df: e9 90 90 90 90 [ ]*jmp (0x)?90909374.*
+ 2e4: ea 90 90 90 90 90 90 [ ]*ljmp \$0x9090,\$0x90909090
+ 2eb: eb 90 [ ]*jmp (0x)?27d.*
+ 2ed: ec [ ]*in \(%dx\),%al
+ 2ee: ed [ ]*in \(%dx\),%eax
+ 2ef: ee [ ]*out %al,\(%dx\)
+ 2f0: ef [ ]*out %eax,\(%dx\)
+ 2f1: f4 [ ]*hlt
+ 2f2: f5 [ ]*cmc
+ 2f3: f6 90 90 90 90 90 [ ]*notb 0x90909090\(%eax\)
+ 2f9: f7 90 90 90 90 90 [ ]*notl 0x90909090\(%eax\)
+ 2ff: f8 [ ]*clc
+ 300: f9 [ ]*stc
+ 301: fa [ ]*cli
+ 302: fb [ ]*sti
+ 303: fc [ ]*cld
+ 304: fd [ ]*std
+ 305: ff 90 90 90 90 90 [ ]*call \*0x90909090\(%eax\)
+ 30b: 0f 00 90 90 90 90 90 [ ]*lldt 0x90909090\(%eax\)
+ 312: 0f 01 90 90 90 90 90 [ ]*lgdt 0x90909090\(%eax\)
+ 319: 0f 02 90 90 90 90 90 [ ]*lar 0x90909090\(%eax\),%edx
+ 320: 0f 03 90 90 90 90 90 [ ]*lsl 0x90909090\(%eax\),%edx
+ 327: 0f 06 [ ]*clts
+ 329: 0f 08 [ ]*invd
+ 32b: 0f 09 [ ]*wbinvd
+ 32d: 0f 0b [ ]*ud2a
+ 32f: 0f 20 d0 [ ]*mov %cr2,%eax
+ 332: 0f 21 d0 [ ]*mov %db2,%eax
+ 335: 0f 22 d0 [ ]*mov %eax,%cr2
+ 338: 0f 23 d0 [ ]*mov %eax,%db2
+ 33b: 0f 24 d0 [ ]*mov %tr2,%eax
+ 33e: 0f 26 d0 [ ]*mov %eax,%tr2
+ 341: 0f 30 [ ]*wrmsr
+ 343: 0f 31 [ ]*rdtsc
+ 345: 0f 32 [ ]*rdmsr
+ 347: 0f 33 [ ]*rdpmc
+ 349: 0f 40 90 90 90 90 90 [ ]*cmovo 0x90909090\(%eax\),%edx
+ 350: 0f 41 90 90 90 90 90 [ ]*cmovno 0x90909090\(%eax\),%edx
+ 357: 0f 42 90 90 90 90 90 [ ]*cmovb 0x90909090\(%eax\),%edx
+ 35e: 0f 43 90 90 90 90 90 [ ]*cmovae 0x90909090\(%eax\),%edx
+ 365: 0f 44 90 90 90 90 90 [ ]*cmove 0x90909090\(%eax\),%edx
+ 36c: 0f 45 90 90 90 90 90 [ ]*cmovne 0x90909090\(%eax\),%edx
+ 373: 0f 46 90 90 90 90 90 [ ]*cmovbe 0x90909090\(%eax\),%edx
+ 37a: 0f 47 90 90 90 90 90 [ ]*cmova 0x90909090\(%eax\),%edx
+ 381: 0f 48 90 90 90 90 90 [ ]*cmovs 0x90909090\(%eax\),%edx
+ 388: 0f 49 90 90 90 90 90 [ ]*cmovns 0x90909090\(%eax\),%edx
+ 38f: 0f 4a 90 90 90 90 90 [ ]*cmovp 0x90909090\(%eax\),%edx
+ 396: 0f 4b 90 90 90 90 90 [ ]*cmovnp 0x90909090\(%eax\),%edx
+ 39d: 0f 4c 90 90 90 90 90 [ ]*cmovl 0x90909090\(%eax\),%edx
+ 3a4: 0f 4d 90 90 90 90 90 [ ]*cmovge 0x90909090\(%eax\),%edx
+ 3ab: 0f 4e 90 90 90 90 90 [ ]*cmovle 0x90909090\(%eax\),%edx
+ 3b2: 0f 4f 90 90 90 90 90 [ ]*cmovg 0x90909090\(%eax\),%edx
+ 3b9: 0f 60 90 90 90 90 90 [ ]*punpcklbw 0x90909090\(%eax\),%mm2
+ 3c0: 0f 61 90 90 90 90 90 [ ]*punpcklwd 0x90909090\(%eax\),%mm2
+ 3c7: 0f 62 90 90 90 90 90 [ ]*punpckldq 0x90909090\(%eax\),%mm2
+ 3ce: 0f 63 90 90 90 90 90 [ ]*packsswb 0x90909090\(%eax\),%mm2
+ 3d5: 0f 64 90 90 90 90 90 [ ]*pcmpgtb 0x90909090\(%eax\),%mm2
+ 3dc: 0f 65 90 90 90 90 90 [ ]*pcmpgtw 0x90909090\(%eax\),%mm2
+ 3e3: 0f 66 90 90 90 90 90 [ ]*pcmpgtd 0x90909090\(%eax\),%mm2
+ 3ea: 0f 67 90 90 90 90 90 [ ]*packuswb 0x90909090\(%eax\),%mm2
+ 3f1: 0f 68 90 90 90 90 90 [ ]*punpckhbw 0x90909090\(%eax\),%mm2
+ 3f8: 0f 69 90 90 90 90 90 [ ]*punpckhwd 0x90909090\(%eax\),%mm2
+ 3ff: 0f 6a 90 90 90 90 90 [ ]*punpckhdq 0x90909090\(%eax\),%mm2
+ 406: 0f 6b 90 90 90 90 90 [ ]*packssdw 0x90909090\(%eax\),%mm2
+ 40d: 0f 6e 90 90 90 90 90 [ ]*movd 0x90909090\(%eax\),%mm2
+ 414: 0f 6f 90 90 90 90 90 [ ]*movq 0x90909090\(%eax\),%mm2
+ 41b: 0f 71 d0 90 [ ]*psrlw \$0x90,%mm0
+ 41f: 0f 72 d0 90 [ ]*psrld \$0x90,%mm0
+ 423: 0f 73 d0 90 [ ]*psrlq \$0x90,%mm0
+ 427: 0f 74 90 90 90 90 90 [ ]*pcmpeqb 0x90909090\(%eax\),%mm2
+ 42e: 0f 75 90 90 90 90 90 [ ]*pcmpeqw 0x90909090\(%eax\),%mm2
+ 435: 0f 76 90 90 90 90 90 [ ]*pcmpeqd 0x90909090\(%eax\),%mm2
+ 43c: 0f 77 [ ]*emms
+ 43e: 0f 7e 90 90 90 90 90 [ ]*movd %mm2,0x90909090\(%eax\)
+ 445: 0f 7f 90 90 90 90 90 [ ]*movq %mm2,0x90909090\(%eax\)
+ 44c: 0f 80 90 90 90 90 [ ]*jo (0x)?909094e2.*
+ 452: 0f 81 90 90 90 90 [ ]*jno (0x)?909094e8.*
+ 458: 0f 82 90 90 90 90 [ ]*jb (0x)?909094ee.*
+ 45e: 0f 83 90 90 90 90 [ ]*jae (0x)?909094f4.*
+ 464: 0f 84 90 90 90 90 [ ]*je (0x)?909094fa.*
+ 46a: 0f 85 90 90 90 90 [ ]*jne (0x)?90909500.*
+ 470: 0f 86 90 90 90 90 [ ]*jbe (0x)?90909506.*
+ 476: 0f 87 90 90 90 90 [ ]*ja (0x)?9090950c.*
+ 47c: 0f 88 90 90 90 90 [ ]*js (0x)?90909512.*
+ 482: 0f 89 90 90 90 90 [ ]*jns (0x)?90909518.*
+ 488: 0f 8a 90 90 90 90 [ ]*jp (0x)?9090951e.*
+ 48e: 0f 8b 90 90 90 90 [ ]*jnp (0x)?90909524.*
+ 494: 0f 8c 90 90 90 90 [ ]*jl (0x)?9090952a.*
+ 49a: 0f 8d 90 90 90 90 [ ]*jge (0x)?90909530.*
+ 4a0: 0f 8e 90 90 90 90 [ ]*jle (0x)?90909536.*
+ 4a6: 0f 8f 90 90 90 90 [ ]*jg (0x)?9090953c.*
+ 4ac: 0f 90 80 90 90 90 90 [ ]*seto 0x90909090\(%eax\)
+ 4b3: 0f 91 80 90 90 90 90 [ ]*setno 0x90909090\(%eax\)
+ 4ba: 0f 92 80 90 90 90 90 [ ]*setb 0x90909090\(%eax\)
+ 4c1: 0f 93 80 90 90 90 90 [ ]*setae 0x90909090\(%eax\)
+ 4c8: 0f 94 80 90 90 90 90 [ ]*sete 0x90909090\(%eax\)
+ 4cf: 0f 95 80 90 90 90 90 [ ]*setne 0x90909090\(%eax\)
+ 4d6: 0f 96 80 90 90 90 90 [ ]*setbe 0x90909090\(%eax\)
+ 4dd: 0f 97 80 90 90 90 90 [ ]*seta 0x90909090\(%eax\)
+ 4e4: 0f 98 80 90 90 90 90 [ ]*sets 0x90909090\(%eax\)
+ 4eb: 0f 99 80 90 90 90 90 [ ]*setns 0x90909090\(%eax\)
+ 4f2: 0f 9a 80 90 90 90 90 [ ]*setp 0x90909090\(%eax\)
+ 4f9: 0f 9b 80 90 90 90 90 [ ]*setnp 0x90909090\(%eax\)
+ 500: 0f 9c 80 90 90 90 90 [ ]*setl 0x90909090\(%eax\)
+ 507: 0f 9d 80 90 90 90 90 [ ]*setge 0x90909090\(%eax\)
+ 50e: 0f 9e 80 90 90 90 90 [ ]*setle 0x90909090\(%eax\)
+ 515: 0f 9f 80 90 90 90 90 [ ]*setg 0x90909090\(%eax\)
+ 51c: 0f a0 [ ]*push %fs
+ 51e: 0f a1 [ ]*pop %fs
+ 520: 0f a2 [ ]*cpuid
+ 522: 0f a3 90 90 90 90 90 [ ]*bt %edx,0x90909090\(%eax\)
+ 529: 0f a4 90 90 90 90 90 90 [ ]*shld \$0x90,%edx,0x90909090\(%eax\)
+ 531: 0f a5 90 90 90 90 90 [ ]*shld %cl,%edx,0x90909090\(%eax\)
+ 538: 0f a8 [ ]*push %gs
+ 53a: 0f a9 [ ]*pop %gs
+ 53c: 0f aa [ ]*rsm
+ 53e: 0f ab 90 90 90 90 90 [ ]*bts %edx,0x90909090\(%eax\)
+ 545: 0f ac 90 90 90 90 90 90 [ ]*shrd \$0x90,%edx,0x90909090\(%eax\)
+ 54d: 0f ad 90 90 90 90 90 [ ]*shrd %cl,%edx,0x90909090\(%eax\)
+ 554: 0f af 90 90 90 90 90 [ ]*imul 0x90909090\(%eax\),%edx
+ 55b: 0f b0 90 90 90 90 90 [ ]*cmpxchg %dl,0x90909090\(%eax\)
+ 562: 0f b1 90 90 90 90 90 [ ]*cmpxchg %edx,0x90909090\(%eax\)
+ 569: 0f b2 90 90 90 90 90 [ ]*lss 0x90909090\(%eax\),%edx
+ 570: 0f b3 90 90 90 90 90 [ ]*btr %edx,0x90909090\(%eax\)
+ 577: 0f b4 90 90 90 90 90 [ ]*lfs 0x90909090\(%eax\),%edx
+ 57e: 0f b5 90 90 90 90 90 [ ]*lgs 0x90909090\(%eax\),%edx
+ 585: 0f b6 90 90 90 90 90 [ ]*movzbl 0x90909090\(%eax\),%edx
+ 58c: 0f b7 90 90 90 90 90 [ ]*movzwl 0x90909090\(%eax\),%edx
+ 593: 0f b9 [ ]*ud2b
+ 595: 0f bb 90 90 90 90 90 [ ]*btc %edx,0x90909090\(%eax\)
+ 59c: 0f bc 90 90 90 90 90 [ ]*bsf 0x90909090\(%eax\),%edx
+ 5a3: 0f bd 90 90 90 90 90 [ ]*bsr 0x90909090\(%eax\),%edx
+ 5aa: 0f be 90 90 90 90 90 [ ]*movsbl 0x90909090\(%eax\),%edx
+ 5b1: 0f bf 90 90 90 90 90 [ ]*movswl 0x90909090\(%eax\),%edx
+ 5b8: 0f c0 90 90 90 90 90 [ ]*xadd %dl,0x90909090\(%eax\)
+ 5bf: 0f c1 90 90 90 90 90 [ ]*xadd %edx,0x90909090\(%eax\)
+ 5c6: 0f c8 [ ]*bswap %eax
+ 5c8: 0f c9 [ ]*bswap %ecx
+ 5ca: 0f ca [ ]*bswap %edx
+ 5cc: 0f cb [ ]*bswap %ebx
+ 5ce: 0f cc [ ]*bswap %esp
+ 5d0: 0f cd [ ]*bswap %ebp
+ 5d2: 0f ce [ ]*bswap %esi
+ 5d4: 0f cf [ ]*bswap %edi
+ 5d6: 0f d1 90 90 90 90 90 [ ]*psrlw 0x90909090\(%eax\),%mm2
+ 5dd: 0f d2 90 90 90 90 90 [ ]*psrld 0x90909090\(%eax\),%mm2
+ 5e4: 0f d3 90 90 90 90 90 [ ]*psrlq 0x90909090\(%eax\),%mm2
+ 5eb: 0f d5 90 90 90 90 90 [ ]*pmullw 0x90909090\(%eax\),%mm2
+ 5f2: 0f d8 90 90 90 90 90 [ ]*psubusb 0x90909090\(%eax\),%mm2
+ 5f9: 0f d9 90 90 90 90 90 [ ]*psubusw 0x90909090\(%eax\),%mm2
+ 600: 0f db 90 90 90 90 90 [ ]*pand 0x90909090\(%eax\),%mm2
+ 607: 0f dc 90 90 90 90 90 [ ]*paddusb 0x90909090\(%eax\),%mm2
+ 60e: 0f dd 90 90 90 90 90 [ ]*paddusw 0x90909090\(%eax\),%mm2
+ 615: 0f df 90 90 90 90 90 [ ]*pandn 0x90909090\(%eax\),%mm2
+ 61c: 0f e1 90 90 90 90 90 [ ]*psraw 0x90909090\(%eax\),%mm2
+ 623: 0f e2 90 90 90 90 90 [ ]*psrad 0x90909090\(%eax\),%mm2
+ 62a: 0f e5 90 90 90 90 90 [ ]*pmulhw 0x90909090\(%eax\),%mm2
+ 631: 0f e8 90 90 90 90 90 [ ]*psubsb 0x90909090\(%eax\),%mm2
+ 638: 0f e9 90 90 90 90 90 [ ]*psubsw 0x90909090\(%eax\),%mm2
+ 63f: 0f eb 90 90 90 90 90 [ ]*por 0x90909090\(%eax\),%mm2
+ 646: 0f ec 90 90 90 90 90 [ ]*paddsb 0x90909090\(%eax\),%mm2
+ 64d: 0f ed 90 90 90 90 90 [ ]*paddsw 0x90909090\(%eax\),%mm2
+ 654: 0f ef 90 90 90 90 90 [ ]*pxor 0x90909090\(%eax\),%mm2
+ 65b: 0f f1 90 90 90 90 90 [ ]*psllw 0x90909090\(%eax\),%mm2
+ 662: 0f f2 90 90 90 90 90 [ ]*pslld 0x90909090\(%eax\),%mm2
+ 669: 0f f3 90 90 90 90 90 [ ]*psllq 0x90909090\(%eax\),%mm2
+ 670: 0f f5 90 90 90 90 90 [ ]*pmaddwd 0x90909090\(%eax\),%mm2
+ 677: 0f f8 90 90 90 90 90 [ ]*psubb 0x90909090\(%eax\),%mm2
+ 67e: 0f f9 90 90 90 90 90 [ ]*psubw 0x90909090\(%eax\),%mm2
+ 685: 0f fa 90 90 90 90 90 [ ]*psubd 0x90909090\(%eax\),%mm2
+ 68c: 0f fc 90 90 90 90 90 [ ]*paddb 0x90909090\(%eax\),%mm2
+ 693: 0f fd 90 90 90 90 90 [ ]*paddw 0x90909090\(%eax\),%mm2
+ 69a: 0f fe 90 90 90 90 90 [ ]*paddd 0x90909090\(%eax\),%mm2
+ 6a1: 66 01 90 90 90 90 90 [ ]*add %dx,0x90909090\(%eax\)
+ 6a8: 66 03 90 90 90 90 90 [ ]*add 0x90909090\(%eax\),%dx
+ 6af: 66 05 90 90 [ ]*add \$0x9090,%ax
+ 6b3: 66 06 [ ]*pushw %es
+ 6b5: 66 07 [ ]*popw %es
+ 6b7: 66 09 90 90 90 90 90 [ ]*or %dx,0x90909090\(%eax\)
+ 6be: 66 0b 90 90 90 90 90 [ ]*or 0x90909090\(%eax\),%dx
+ 6c5: 66 0d 90 90 [ ]*or \$0x9090,%ax
+ 6c9: 66 0e [ ]*pushw %cs
+ 6cb: 66 11 90 90 90 90 90 [ ]*adc %dx,0x90909090\(%eax\)
+ 6d2: 66 13 90 90 90 90 90 [ ]*adc 0x90909090\(%eax\),%dx
+ 6d9: 66 15 90 90 [ ]*adc \$0x9090,%ax
+ 6dd: 66 16 [ ]*pushw %ss
+ 6df: 66 17 [ ]*popw %ss
+ 6e1: 66 19 90 90 90 90 90 [ ]*sbb %dx,0x90909090\(%eax\)
+ 6e8: 66 1b 90 90 90 90 90 [ ]*sbb 0x90909090\(%eax\),%dx
+ 6ef: 66 1d 90 90 [ ]*sbb \$0x9090,%ax
+ 6f3: 66 1e [ ]*pushw %ds
+ 6f5: 66 1f [ ]*popw %ds
+ 6f7: 66 21 90 90 90 90 90 [ ]*and %dx,0x90909090\(%eax\)
+ 6fe: 66 23 90 90 90 90 90 [ ]*and 0x90909090\(%eax\),%dx
+ 705: 66 25 90 90 [ ]*and \$0x9090,%ax
+ 709: 66 29 90 90 90 90 90 [ ]*sub %dx,0x90909090\(%eax\)
+ 710: 66 2b 90 90 90 90 90 [ ]*sub 0x90909090\(%eax\),%dx
+ 717: 66 2d 90 90 [ ]*sub \$0x9090,%ax
+ 71b: 66 31 90 90 90 90 90 [ ]*xor %dx,0x90909090\(%eax\)
+ 722: 66 33 90 90 90 90 90 [ ]*xor 0x90909090\(%eax\),%dx
+ 729: 66 35 90 90 [ ]*xor \$0x9090,%ax
+ 72d: 66 39 90 90 90 90 90 [ ]*cmp %dx,0x90909090\(%eax\)
+ 734: 66 3b 90 90 90 90 90 [ ]*cmp 0x90909090\(%eax\),%dx
+ 73b: 66 3d 90 90 [ ]*cmp \$0x9090,%ax
+ 73f: 66 40 [ ]*inc %ax
+ 741: 66 41 [ ]*inc %cx
+ 743: 66 42 [ ]*inc %dx
+ 745: 66 43 [ ]*inc %bx
+ 747: 66 44 [ ]*inc %sp
+ 749: 66 45 [ ]*inc %bp
+ 74b: 66 46 [ ]*inc %si
+ 74d: 66 47 [ ]*inc %di
+ 74f: 66 48 [ ]*dec %ax
+ 751: 66 49 [ ]*dec %cx
+ 753: 66 4a [ ]*dec %dx
+ 755: 66 4b [ ]*dec %bx
+ 757: 66 4c [ ]*dec %sp
+ 759: 66 4d [ ]*dec %bp
+ 75b: 66 4e [ ]*dec %si
+ 75d: 66 4f [ ]*dec %di
+ 75f: 66 50 [ ]*push %ax
+ 761: 66 51 [ ]*push %cx
+ 763: 66 52 [ ]*push %dx
+ 765: 66 53 [ ]*push %bx
+ 767: 66 54 [ ]*push %sp
+ 769: 66 55 [ ]*push %bp
+ 76b: 66 56 [ ]*push %si
+ 76d: 66 57 [ ]*push %di
+ 76f: 66 58 [ ]*pop %ax
+ 771: 66 59 [ ]*pop %cx
+ 773: 66 5a [ ]*pop %dx
+ 775: 66 5b [ ]*pop %bx
+ 777: 66 5c [ ]*pop %sp
+ 779: 66 5d [ ]*pop %bp
+ 77b: 66 5e [ ]*pop %si
+ 77d: 66 5f [ ]*pop %di
+ 77f: 66 60 [ ]*pushaw
+ 781: 66 61 [ ]*popaw
+ 783: 66 62 90 90 90 90 90 [ ]*bound %dx,0x90909090\(%eax\)
+ 78a: 66 68 90 90 [ ]*pushw \$0x9090
+ 78e: 66 69 90 90 90 90 90 90 90 [ ]*imul \$0x9090,0x90909090\(%eax\),%dx
+ 797: 66 6a 90 [ ]*pushw \$0xffffff90
+ 79a: 66 6b 90 90 90 90 90 90 [ ]*imul \$0xffffff90,0x90909090\(%eax\),%dx
+ 7a2: 66 6d [ ]*insw \(%dx\),%es:\(%edi\)
+ 7a4: 66 6f [ ]*outsw %ds:\(%esi\),\(%dx\)
+ 7a6: 66 81 90 90 90 90 90 90 90 [ ]*adcw \$0x9090,0x90909090\(%eax\)
+ 7af: 66 83 90 90 90 90 90 90 [ ]*adcw \$0xffffff90,0x90909090\(%eax\)
+ 7b7: 66 85 90 90 90 90 90 [ ]*test %dx,0x90909090\(%eax\)
+ 7be: 66 87 90 90 90 90 90 [ ]*xchg %dx,0x90909090\(%eax\)
+ 7c5: 66 89 90 90 90 90 90 [ ]*mov %dx,0x90909090\(%eax\)
+ 7cc: 66 8b 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%dx
+ 7d3: 66 8c 90 90 90 90 90 [ ]*movw %ss,0x90909090\(%eax\)
+ 7da: 66 8d 90 90 90 90 90 [ ]*lea 0x90909090\(%eax\),%dx
+ 7e1: 66 8f 80 90 90 90 90 [ ]*popw 0x90909090\(%eax\)
+ 7e8: 66 91 [ ]*xchg %ax,%cx
+ 7ea: 66 92 [ ]*xchg %ax,%dx
+ 7ec: 66 93 [ ]*xchg %ax,%bx
+ 7ee: 66 94 [ ]*xchg %ax,%sp
+ 7f0: 66 95 [ ]*xchg %ax,%bp
+ 7f2: 66 96 [ ]*xchg %ax,%si
+ 7f4: 66 97 [ ]*xchg %ax,%di
+ 7f6: 66 98 [ ]*cbtw
+ 7f8: 66 99 [ ]*cwtd
+ 7fa: 66 9a 90 90 90 90 [ ]*lcallw \$0x9090,\$0x9090
+ 800: 66 9c [ ]*pushfw
+ 802: 66 9d [ ]*popfw
+ 804: 66 a1 90 90 90 90 [ ]*mov 0x90909090,%ax
+ 80a: 66 a3 90 90 90 90 [ ]*mov %ax,0x90909090
+ 810: 66 a5 [ ]*movsw %ds:\(%esi\),%es:\(%edi\)
+ 812: 66 a7 [ ]*cmpsw %es:\(%edi\),%ds:\(%esi\)
+ 814: 66 a9 90 90 [ ]*test \$0x9090,%ax
+ 818: 66 ab [ ]*stos %ax,%es:\(%edi\)
+ 81a: 66 ad [ ]*lods %ds:\(%esi\),%ax
+ 81c: 66 af [ ]*scas %es:\(%edi\),%ax
+ 81e: 66 b8 90 90 [ ]*mov \$0x9090,%ax
+ 822: 66 b9 90 90 [ ]*mov \$0x9090,%cx
+ 826: 66 ba 90 90 [ ]*mov \$0x9090,%dx
+ 82a: 66 bb 90 90 [ ]*mov \$0x9090,%bx
+ 82e: 66 bc 90 90 [ ]*mov \$0x9090,%sp
+ 832: 66 bd 90 90 [ ]*mov \$0x9090,%bp
+ 836: 66 be 90 90 [ ]*mov \$0x9090,%si
+ 83a: 66 bf 90 90 [ ]*mov \$0x9090,%di
+ 83e: 66 c1 90 90 90 90 90 90 [ ]*rclw \$0x90,0x90909090\(%eax\)
+ 846: 66 c2 90 90 [ ]*retw \$0x9090
+ 84a: 66 c3 [ ]*retw
+ 84c: 66 c4 90 90 90 90 90 [ ]*les 0x90909090\(%eax\),%dx
+ 853: 66 c5 90 90 90 90 90 [ ]*lds 0x90909090\(%eax\),%dx
+ 85a: 66 c7 80 90 90 90 90 90 90 [ ]*movw \$0x9090,0x90909090\(%eax\)
+ 863: 66 c8 90 90 90 [ ]*enterw \$0x9090,\$0x90
+ 868: 66 c9 [ ]*leavew
+ 86a: 66 ca 90 90 [ ]*lretw \$0x9090
+ 86e: 66 cb [ ]*lretw
+ 870: 66 cf [ ]*iretw
+ 872: 66 d1 90 90 90 90 90 [ ]*rclw 0x90909090\(%eax\)
+ 879: 66 d3 90 90 90 90 90 [ ]*rclw %cl,0x90909090\(%eax\)
+ 880: 66 e5 90 [ ]*in \$0x90,%ax
+ 883: 66 e7 90 [ ]*out %ax,\$0x90
+ 886: 66 e8 8f 90 [ ]*callw (0x)?ffff9919.*
+ 88a: 66 ea 90 90 90 90 [ ]*ljmpw \$0x9090,\$0x9090
+ 890: 66 ed [ ]*in \(%dx\),%ax
+ 892: 66 ef [ ]*out %ax,\(%dx\)
+ 894: 66 f7 90 90 90 90 90 [ ]*notw 0x90909090\(%eax\)
+ 89b: 66 ff 90 90 90 90 90 [ ]*callw \*0x90909090\(%eax\)
+ 8a2: 66 0f 02 90 90 90 90 90 [ ]*lar 0x90909090\(%eax\),%dx
+ 8aa: 66 0f 03 90 90 90 90 90 [ ]*lsl 0x90909090\(%eax\),%dx
+ 8b2: 66 0f 40 90 90 90 90 90 [ ]*cmovo 0x90909090\(%eax\),%dx
+ 8ba: 66 0f 41 90 90 90 90 90 [ ]*cmovno 0x90909090\(%eax\),%dx
+ 8c2: 66 0f 42 90 90 90 90 90 [ ]*cmovb 0x90909090\(%eax\),%dx
+ 8ca: 66 0f 43 90 90 90 90 90 [ ]*cmovae 0x90909090\(%eax\),%dx
+ 8d2: 66 0f 44 90 90 90 90 90 [ ]*cmove 0x90909090\(%eax\),%dx
+ 8da: 66 0f 45 90 90 90 90 90 [ ]*cmovne 0x90909090\(%eax\),%dx
+ 8e2: 66 0f 46 90 90 90 90 90 [ ]*cmovbe 0x90909090\(%eax\),%dx
+ 8ea: 66 0f 47 90 90 90 90 90 [ ]*cmova 0x90909090\(%eax\),%dx
+ 8f2: 66 0f 48 90 90 90 90 90 [ ]*cmovs 0x90909090\(%eax\),%dx
+ 8fa: 66 0f 49 90 90 90 90 90 [ ]*cmovns 0x90909090\(%eax\),%dx
+ 902: 66 0f 4a 90 90 90 90 90 [ ]*cmovp 0x90909090\(%eax\),%dx
+ 90a: 66 0f 4b 90 90 90 90 90 [ ]*cmovnp 0x90909090\(%eax\),%dx
+ 912: 66 0f 4c 90 90 90 90 90 [ ]*cmovl 0x90909090\(%eax\),%dx
+ 91a: 66 0f 4d 90 90 90 90 90 [ ]*cmovge 0x90909090\(%eax\),%dx
+ 922: 66 0f 4e 90 90 90 90 90 [ ]*cmovle 0x90909090\(%eax\),%dx
+ 92a: 66 0f 4f 90 90 90 90 90 [ ]*cmovg 0x90909090\(%eax\),%dx
+ 932: 66 0f a0 [ ]*pushw %fs
+ 935: 66 0f a1 [ ]*popw %fs
+ 938: 66 0f a3 90 90 90 90 90 [ ]*bt %dx,0x90909090\(%eax\)
+ 940: 66 0f a4 90 90 90 90 90 90 [ ]*shld \$0x90,%dx,0x90909090\(%eax\)
+ 949: 66 0f a5 90 90 90 90 90 [ ]*shld %cl,%dx,0x90909090\(%eax\)
+ 951: 66 0f a8 [ ]*pushw %gs
+ 954: 66 0f a9 [ ]*popw %gs
+ 957: 66 0f ab 90 90 90 90 90 [ ]*bts %dx,0x90909090\(%eax\)
+ 95f: 66 0f ac 90 90 90 90 90 90 [ ]*shrd \$0x90,%dx,0x90909090\(%eax\)
+ 968: 66 0f ad 90 90 90 90 90 [ ]*shrd %cl,%dx,0x90909090\(%eax\)
+ 970: 66 0f af 90 90 90 90 90 [ ]*imul 0x90909090\(%eax\),%dx
+ 978: 66 0f b1 90 90 90 90 90 [ ]*cmpxchg %dx,0x90909090\(%eax\)
+ 980: 66 0f b2 90 90 90 90 90 [ ]*lss 0x90909090\(%eax\),%dx
+ 988: 66 0f b3 90 90 90 90 90 [ ]*btr %dx,0x90909090\(%eax\)
+ 990: 66 0f b4 90 90 90 90 90 [ ]*lfs 0x90909090\(%eax\),%dx
+ 998: 66 0f b5 90 90 90 90 90 [ ]*lgs 0x90909090\(%eax\),%dx
+ 9a0: 66 0f b6 90 90 90 90 90 [ ]*movzbw 0x90909090\(%eax\),%dx
+ 9a8: 66 0f bb 90 90 90 90 90 [ ]*btc %dx,0x90909090\(%eax\)
+ 9b0: 66 0f bc 90 90 90 90 90 [ ]*bsf 0x90909090\(%eax\),%dx
+ 9b8: 66 0f bd 90 90 90 90 90 [ ]*bsr 0x90909090\(%eax\),%dx
+ 9c0: 66 0f be 90 90 90 90 90 [ ]*movsbw 0x90909090\(%eax\),%dx
+ 9c8: 66 0f c1 90 90 90 90 90 [ ]*xadd %dx,0x90909090\(%eax\)
diff --git a/gas/testsuite/gas/i386/opcode.s b/gas/testsuite/gas/i386/opcode.s
new file mode 100644
index 00000000000..39c5967b266
--- /dev/null
+++ b/gas/testsuite/gas/i386/opcode.s
@@ -0,0 +1,567 @@
+.text
+foo:
+ add %dl,0x90909090(%eax)
+ add %edx,0x90909090(%eax)
+ add 0x90909090(%eax),%dl
+ add 0x90909090(%eax),%edx
+ add $0x90,%al
+ add $0x90909090,%eax
+ push %es
+ pop %es
+ or %dl,0x90909090(%eax)
+ or %edx,0x90909090(%eax)
+ or 0x90909090(%eax),%dl
+ or 0x90909090(%eax),%edx
+ or $0x90,%al
+ or $0x90909090,%eax
+ push %cs
+ adc %dl,0x90909090(%eax)
+ adc %edx,0x90909090(%eax)
+ adc 0x90909090(%eax),%dl
+ adc 0x90909090(%eax),%edx
+ adc $0x90,%al
+ adc $0x90909090,%eax
+ push %ss
+ pop %ss
+ sbb %dl,0x90909090(%eax)
+ sbb %edx,0x90909090(%eax)
+ sbb 0x90909090(%eax),%dl
+ sbb 0x90909090(%eax),%edx
+ sbb $0x90,%al
+ sbb $0x90909090,%eax
+ push %ds
+ pop %ds
+ and %dl,0x90909090(%eax)
+ and %edx,0x90909090(%eax)
+ and 0x90909090(%eax),%dl
+ and 0x90909090(%eax),%edx
+ and $0x90,%al
+ and $0x90909090,%eax
+ daa
+ sub %dl,0x90909090(%eax)
+ sub %edx,0x90909090(%eax)
+ sub 0x90909090(%eax),%dl
+ sub 0x90909090(%eax),%edx
+ sub $0x90,%al
+ sub $0x90909090,%eax
+ das
+ xor %dl,0x90909090(%eax)
+ xor %edx,0x90909090(%eax)
+ xor 0x90909090(%eax),%dl
+ xor 0x90909090(%eax),%edx
+ xor $0x90,%al
+ xor $0x90909090,%eax
+ aaa
+ cmp %dl,0x90909090(%eax)
+ cmp %edx,0x90909090(%eax)
+ cmp 0x90909090(%eax),%dl
+ cmp 0x90909090(%eax),%edx
+ cmp $0x90,%al
+ cmp $0x90909090,%eax
+ aas
+ inc %eax
+ inc %ecx
+ inc %edx
+ inc %ebx
+ inc %esp
+ inc %ebp
+ inc %esi
+ inc %edi
+ dec %eax
+ dec %ecx
+ dec %edx
+ dec %ebx
+ dec %esp
+ dec %ebp
+ dec %esi
+ dec %edi
+ push %eax
+ push %ecx
+ push %edx
+ push %ebx
+ push %esp
+ push %ebp
+ push %esi
+ push %edi
+ pop %eax
+ pop %ecx
+ pop %edx
+ pop %ebx
+ pop %esp
+ pop %ebp
+ pop %esi
+ pop %edi
+ pusha
+ popa
+ bound %edx,0x90909090(%eax)
+ arpl %dx,0x90909090(%eax)
+ push $0x90909090
+ imul $0x90909090,0x90909090(%eax),%edx
+ push $0xffffff90
+ imul $0xffffff90,0x90909090(%eax),%edx
+ insb (%dx),%es:(%edi)
+ insl (%dx),%es:(%edi)
+ outsb %ds:(%esi),(%dx)
+ outsl %ds:(%esi),(%dx)
+ jo .+2-0x70
+ jno .+2-0x70
+ jb .+2-0x70
+ jae .+2-0x70
+ je .+2-0x70
+ jne .+2-0x70
+ jbe .+2-0x70
+ ja .+2-0x70
+ js .+2-0x70
+ jns .+2-0x70
+ jp .+2-0x70
+ jnp .+2-0x70
+ jl .+2-0x70
+ jge .+2-0x70
+ jle .+2-0x70
+ jg .+2-0x70
+ adcb $0x90,0x90909090(%eax)
+ adcl $0x90909090,0x90909090(%eax)
+ adcl $0xffffff90,0x90909090(%eax)
+ test %dl,0x90909090(%eax)
+ test %edx,0x90909090(%eax)
+ xchg %dl,0x90909090(%eax)
+ xchg %edx,0x90909090(%eax)
+ mov %dl,0x90909090(%eax)
+ mov %edx,0x90909090(%eax)
+ mov 0x90909090(%eax),%dl
+ mov 0x90909090(%eax),%edx
+ movl %ss,0x90909090(%eax)
+ lea 0x90909090(%eax),%edx
+ movl 0x90909090(%eax),%ss
+ popl 0x90909090(%eax)
+ xchg %eax,%eax
+ xchg %eax,%ecx
+ xchg %eax,%edx
+ xchg %eax,%ebx
+ xchg %eax,%esp
+ xchg %eax,%ebp
+ xchg %eax,%esi
+ xchg %eax,%edi
+ cwtl
+ cltd
+ lcall $0x9090,$0x90909090
+ fwait
+ pushf
+ popf
+ sahf
+ lahf
+ mov 0x90909090,%al
+ mov 0x90909090,%eax
+ mov %al,0x90909090
+ mov %eax,0x90909090
+ movsb %ds:(%esi),%es:(%edi)
+ movsl %ds:(%esi),%es:(%edi)
+ cmpsb %es:(%edi),%ds:(%esi)
+ cmpsl %es:(%edi),%ds:(%esi)
+ test $0x90,%al
+ test $0x90909090,%eax
+ stos %al,%es:(%edi)
+ stos %eax,%es:(%edi)
+ lods %ds:(%esi),%al
+ lods %ds:(%esi),%eax
+ scas %es:(%edi),%al
+ scas %es:(%edi),%eax
+ mov $0x90,%al
+ mov $0x90,%cl
+ mov $0x90,%dl
+ mov $0x90,%bl
+ mov $0x90,%ah
+ mov $0x90,%ch
+ mov $0x90,%dh
+ mov $0x90,%bh
+ mov $0x90909090,%eax
+ mov $0x90909090,%ecx
+ mov $0x90909090,%edx
+ mov $0x90909090,%ebx
+ mov $0x90909090,%esp
+ mov $0x90909090,%ebp
+ mov $0x90909090,%esi
+ mov $0x90909090,%edi
+ rclb $0x90,0x90909090(%eax)
+ rcll $0x90,0x90909090(%eax)
+ ret $0x9090
+ ret
+ les 0x90909090(%eax),%edx
+ lds 0x90909090(%eax),%edx
+ movb $0x90,0x90909090(%eax)
+ movl $0x90909090,0x90909090(%eax)
+ enter $0x9090,$0x90
+ leave
+ lret $0x9090
+ lret
+ int3
+ int $0x90
+ into
+ iret
+ rclb 0x90909090(%eax)
+ rcll 0x90909090(%eax)
+ rclb %cl,0x90909090(%eax)
+ rcll %cl,0x90909090(%eax)
+ aam $0xffffff90
+ aad $0xffffff90
+ xlat %ds:(%ebx)
+ fcoms 0x90909090(%eax)
+ fsts 0x90909090(%eax)
+ ficoml 0x90909090(%eax)
+ fistl 0x90909090(%eax)
+ fcoml 0x90909090(%eax)
+ fstl 0x90909090(%eax)
+ ficom 0x90909090(%eax)
+ fist 0x90909090(%eax)
+ loopne .+2-0x70
+ loope .+2-0x70
+ loop .+2-0x70
+ jecxz .+2-0x70
+ in $0x90,%al
+ in $0x90,%eax
+ out %al,$0x90
+ out %eax,$0x90
+ call .+5+0x90909090
+ jmp .+5+0x90909090
+ ljmp $0x9090,$0x90909090
+ jmp .+2-0x70
+ in (%dx),%al
+ in (%dx),%eax
+ out %al,(%dx)
+ out %eax,(%dx)
+ hlt
+ cmc
+ notb 0x90909090(%eax)
+ notl 0x90909090(%eax)
+ clc
+ stc
+ cli
+ sti
+ cld
+ std
+ call *0x90909090(%eax)
+ lldt 0x90909090(%eax)
+ lgdt 0x90909090(%eax)
+ lar 0x90909090(%eax),%edx
+ lsl 0x90909090(%eax),%edx
+ clts
+ invd
+ wbinvd
+ ud2a
+ mov %cr2,%eax
+ mov %db2,%eax
+ mov %eax,%cr2
+ mov %eax,%db2
+ mov %tr2,%eax
+ mov %eax,%tr2
+ wrmsr
+ rdtsc
+ rdmsr
+ rdpmc
+ cmovo 0x90909090(%eax),%edx
+ cmovno 0x90909090(%eax),%edx
+ cmovb 0x90909090(%eax),%edx
+ cmovae 0x90909090(%eax),%edx
+ cmove 0x90909090(%eax),%edx
+ cmovne 0x90909090(%eax),%edx
+ cmovbe 0x90909090(%eax),%edx
+ cmova 0x90909090(%eax),%edx
+ cmovs 0x90909090(%eax),%edx
+ cmovns 0x90909090(%eax),%edx
+ cmovp 0x90909090(%eax),%edx
+ cmovnp 0x90909090(%eax),%edx
+ cmovl 0x90909090(%eax),%edx
+ cmovge 0x90909090(%eax),%edx
+ cmovle 0x90909090(%eax),%edx
+ cmovg 0x90909090(%eax),%edx
+ punpcklbw 0x90909090(%eax),%mm2
+ punpcklwd 0x90909090(%eax),%mm2
+ punpckldq 0x90909090(%eax),%mm2
+ packsswb 0x90909090(%eax),%mm2
+ pcmpgtb 0x90909090(%eax),%mm2
+ pcmpgtw 0x90909090(%eax),%mm2
+ pcmpgtd 0x90909090(%eax),%mm2
+ packuswb 0x90909090(%eax),%mm2
+ punpckhbw 0x90909090(%eax),%mm2
+ punpckhwd 0x90909090(%eax),%mm2
+ punpckhdq 0x90909090(%eax),%mm2
+ packssdw 0x90909090(%eax),%mm2
+ movd 0x90909090(%eax),%mm2
+ movq 0x90909090(%eax),%mm2
+ psrlw $0x90,%mm0
+ psrld $0x90,%mm0
+ psrlq $0x90,%mm0
+ pcmpeqb 0x90909090(%eax),%mm2
+ pcmpeqw 0x90909090(%eax),%mm2
+ pcmpeqd 0x90909090(%eax),%mm2
+ emms
+ movd %mm2,0x90909090(%eax)
+ movq %mm2,0x90909090(%eax)
+ jo .+6+0x90909090
+ jno .+6+0x90909090
+ jb .+6+0x90909090
+ jae .+6+0x90909090
+ je .+6+0x90909090
+ jne .+6+0x90909090
+ jbe .+6+0x90909090
+ ja .+6+0x90909090
+ js .+6+0x90909090
+ jns .+6+0x90909090
+ jp .+6+0x90909090
+ jnp .+6+0x90909090
+ jl .+6+0x90909090
+ jge .+6+0x90909090
+ jle .+6+0x90909090
+ jg .+6+0x90909090
+ seto 0x90909090(%eax)
+ setno 0x90909090(%eax)
+ setb 0x90909090(%eax)
+ setae 0x90909090(%eax)
+ sete 0x90909090(%eax)
+ setne 0x90909090(%eax)
+ setbe 0x90909090(%eax)
+ seta 0x90909090(%eax)
+ sets 0x90909090(%eax)
+ setns 0x90909090(%eax)
+ setp 0x90909090(%eax)
+ setnp 0x90909090(%eax)
+ setl 0x90909090(%eax)
+ setge 0x90909090(%eax)
+ setle 0x90909090(%eax)
+ setg 0x90909090(%eax)
+ push %fs
+ pop %fs
+ cpuid
+ bt %edx,0x90909090(%eax)
+ shld $0x90,%edx,0x90909090(%eax)
+ shld %cl,%edx,0x90909090(%eax)
+ push %gs
+ pop %gs
+ rsm
+ bts %edx,0x90909090(%eax)
+ shrd $0x90,%edx,0x90909090(%eax)
+ shrd %cl,%edx,0x90909090(%eax)
+ imul 0x90909090(%eax),%edx
+ cmpxchg %dl,0x90909090(%eax)
+ cmpxchg %edx,0x90909090(%eax)
+ lss 0x90909090(%eax),%edx
+ btr %edx,0x90909090(%eax)
+ lfs 0x90909090(%eax),%edx
+ lgs 0x90909090(%eax),%edx
+ movzbl 0x90909090(%eax),%edx
+ movzwl 0x90909090(%eax),%edx
+ ud2b
+ btc %edx,0x90909090(%eax)
+ bsf 0x90909090(%eax),%edx
+ bsr 0x90909090(%eax),%edx
+ movsbl 0x90909090(%eax),%edx
+ movswl 0x90909090(%eax),%edx
+ xadd %dl,0x90909090(%eax)
+ xadd %edx,0x90909090(%eax)
+ bswap %eax
+ bswap %ecx
+ bswap %edx
+ bswap %ebx
+ bswap %esp
+ bswap %ebp
+ bswap %esi
+ bswap %edi
+ psrlw 0x90909090(%eax),%mm2
+ psrld 0x90909090(%eax),%mm2
+ psrlq 0x90909090(%eax),%mm2
+ pmullw 0x90909090(%eax),%mm2
+ psubusb 0x90909090(%eax),%mm2
+ psubusw 0x90909090(%eax),%mm2
+ pand 0x90909090(%eax),%mm2
+ paddusb 0x90909090(%eax),%mm2
+ paddusw 0x90909090(%eax),%mm2
+ pandn 0x90909090(%eax),%mm2
+ psraw 0x90909090(%eax),%mm2
+ psrad 0x90909090(%eax),%mm2
+ pmulhw 0x90909090(%eax),%mm2
+ psubsb 0x90909090(%eax),%mm2
+ psubsw 0x90909090(%eax),%mm2
+ por 0x90909090(%eax),%mm2
+ paddsb 0x90909090(%eax),%mm2
+ paddsw 0x90909090(%eax),%mm2
+ pxor 0x90909090(%eax),%mm2
+ psllw 0x90909090(%eax),%mm2
+ pslld 0x90909090(%eax),%mm2
+ psllq 0x90909090(%eax),%mm2
+ pmaddwd 0x90909090(%eax),%mm2
+ psubb 0x90909090(%eax),%mm2
+ psubw 0x90909090(%eax),%mm2
+ psubd 0x90909090(%eax),%mm2
+ paddb 0x90909090(%eax),%mm2
+ paddw 0x90909090(%eax),%mm2
+ paddd 0x90909090(%eax),%mm2
+ add %dx,0x90909090(%eax)
+ add 0x90909090(%eax),%dx
+ add $0x9090,%ax
+ pushw %es
+ popw %es
+ or %dx,0x90909090(%eax)
+ or 0x90909090(%eax),%dx
+ or $0x9090,%ax
+ pushw %cs
+ adc %dx,0x90909090(%eax)
+ adc 0x90909090(%eax),%dx
+ adc $0x9090,%ax
+ pushw %ss
+ popw %ss
+ sbb %dx,0x90909090(%eax)
+ sbb 0x90909090(%eax),%dx
+ sbb $0x9090,%ax
+ pushw %ds
+ popw %ds
+ and %dx,0x90909090(%eax)
+ and 0x90909090(%eax),%dx
+ and $0x9090,%ax
+ sub %dx,0x90909090(%eax)
+ sub 0x90909090(%eax),%dx
+ sub $0x9090,%ax
+ xor %dx,0x90909090(%eax)
+ xor 0x90909090(%eax),%dx
+ xor $0x9090,%ax
+ cmp %dx,0x90909090(%eax)
+ cmp 0x90909090(%eax),%dx
+ cmp $0x9090,%ax
+ inc %ax
+ inc %cx
+ inc %dx
+ inc %bx
+ inc %sp
+ inc %bp
+ inc %si
+ inc %di
+ dec %ax
+ dec %cx
+ dec %dx
+ dec %bx
+ dec %sp
+ dec %bp
+ dec %si
+ dec %di
+ push %ax
+ push %cx
+ push %dx
+ push %bx
+ push %sp
+ push %bp
+ push %si
+ push %di
+ pop %ax
+ pop %cx
+ pop %dx
+ pop %bx
+ pop %sp
+ pop %bp
+ pop %si
+ pop %di
+ pushaw
+ popaw
+ bound %dx,0x90909090(%eax)
+ pushw $0x9090
+ imul $0x9090,0x90909090(%eax),%dx
+ pushw $0xffffff90
+ imul $0xffffff90,0x90909090(%eax),%dx
+ insw (%dx),%es:(%edi)
+ outsw %ds:(%esi),(%dx)
+ adcw $0x9090,0x90909090(%eax)
+ adcw $0xffffff90,0x90909090(%eax)
+ test %dx,0x90909090(%eax)
+ xchg %dx,0x90909090(%eax)
+ mov %dx,0x90909090(%eax)
+ mov 0x90909090(%eax),%dx
+ movw %ss,0x90909090(%eax)
+ lea 0x90909090(%eax),%dx
+ popw 0x90909090(%eax)
+ xchg %ax,%cx
+ xchg %ax,%dx
+ xchg %ax,%bx
+ xchg %ax,%sp
+ xchg %ax,%bp
+ xchg %ax,%si
+ xchg %ax,%di
+ cbtw
+ cwtd
+ lcallw $0x9090,$0x9090
+ pushfw
+ popfw
+ mov 0x90909090,%ax
+ mov %ax,0x90909090
+ movsw %ds:(%esi),%es:(%edi)
+ cmpsw %es:(%edi),%ds:(%esi)
+ test $0x9090,%ax
+ stos %ax,%es:(%edi)
+ lods %ds:(%esi),%ax
+ scas %es:(%edi),%ax
+ mov $0x9090,%ax
+ mov $0x9090,%cx
+ mov $0x9090,%dx
+ mov $0x9090,%bx
+ mov $0x9090,%sp
+ mov $0x9090,%bp
+ mov $0x9090,%si
+ mov $0x9090,%di
+ rclw $0x90,0x90909090(%eax)
+ retw $0x9090
+ retw
+ les 0x90909090(%eax),%dx
+ lds 0x90909090(%eax),%dx
+ movw $0x9090,0x90909090(%eax)
+ enterw $0x9090,$0x90
+ leavew
+ lretw $0x9090
+ lretw
+ iretw
+ rclw 0x90909090(%eax)
+ rclw %cl,0x90909090(%eax)
+ in $0x90,%ax
+ out %ax,$0x90
+ callw .+3+0x9090
+ ljmpw $0x9090,$0x9090
+ in (%dx),%ax
+ out %ax,(%dx)
+ notw 0x90909090(%eax)
+ callw *0x90909090(%eax)
+ lar 0x90909090(%eax),%dx
+ lsl 0x90909090(%eax),%dx
+ cmovo 0x90909090(%eax),%dx
+ cmovno 0x90909090(%eax),%dx
+ cmovb 0x90909090(%eax),%dx
+ cmovae 0x90909090(%eax),%dx
+ cmove 0x90909090(%eax),%dx
+ cmovne 0x90909090(%eax),%dx
+ cmovbe 0x90909090(%eax),%dx
+ cmova 0x90909090(%eax),%dx
+ cmovs 0x90909090(%eax),%dx
+ cmovns 0x90909090(%eax),%dx
+ cmovp 0x90909090(%eax),%dx
+ cmovnp 0x90909090(%eax),%dx
+ cmovl 0x90909090(%eax),%dx
+ cmovge 0x90909090(%eax),%dx
+ cmovle 0x90909090(%eax),%dx
+ cmovg 0x90909090(%eax),%dx
+ pushw %fs
+ popw %fs
+ bt %dx,0x90909090(%eax)
+ shld $0x90,%dx,0x90909090(%eax)
+ shld %cl,%dx,0x90909090(%eax)
+ pushw %gs
+ popw %gs
+ bts %dx,0x90909090(%eax)
+ shrd $0x90,%dx,0x90909090(%eax)
+ shrd %cl,%dx,0x90909090(%eax)
+ imul 0x90909090(%eax),%dx
+ cmpxchg %dx,0x90909090(%eax)
+ lss 0x90909090(%eax),%dx
+ btr %dx,0x90909090(%eax)
+ lfs 0x90909090(%eax),%dx
+ lgs 0x90909090(%eax),%dx
+ movzbw 0x90909090(%eax),%dx
+ btc %dx,0x90909090(%eax)
+ bsf 0x90909090(%eax),%dx
+ bsr 0x90909090(%eax),%dx
+ movsbw 0x90909090(%eax),%dx
+ xadd %dx,0x90909090(%eax)
diff --git a/gas/testsuite/gas/i386/prefix.d b/gas/testsuite/gas/i386/prefix.d
new file mode 100644
index 00000000000..054b658a3cf
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix.d
@@ -0,0 +1,15 @@
+#objdump: -dw
+#name: i386 prefix
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <foo>:
+ 0: 9b 67 26 d9 3c [ ]*addr16 fstcw %es:\(%si\)
+ 5: 9b df e0 [ ]*fstsw %ax
+ 8: 9b df e0 [ ]*fstsw %ax
+ b: 9b df e0 [ ]*fstsw %ax
+ e: 9b 67 df e0 [ ]*addr16 fstsw %ax
+ 12: f3 67 66 36 a7 [ ]*repz addr16 cmpsw %es:\(%di\),%ss:\(%si\)
+ ...
diff --git a/gas/testsuite/gas/i386/prefix.s b/gas/testsuite/gas/i386/prefix.s
new file mode 100644
index 00000000000..043d31068ad
--- /dev/null
+++ b/gas/testsuite/gas/i386/prefix.s
@@ -0,0 +1,11 @@
+.text
+foo:
+ addr16 fstcw %es:(%si)
+ fstsw
+ fstsw %ax
+ fstsw %eax
+ addr16 fstsw %ax
+ addr16 rep cmpsw %es:(%di),%ss:(%si)
+
+ # Get a good alignment.
+ .byte 0
diff --git a/gas/testsuite/gas/i386/reloc.d b/gas/testsuite/gas/i386/reloc.d
new file mode 100644
index 00000000000..c7903dd8d21
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc.d
@@ -0,0 +1,15 @@
+#objdump: -drw
+#name: i386 reloc
+
+.*: +file format .*i386.*
+
+Disassembly of section .text:
+
+00000000 <foo>:
+ 0: b3 00 [ ]*mov \$0x0,%bl 1: R_386_8 .text
+ 2: 68 00 00 00 00 [ ]*push \$0x0 3: R_386_32 .text
+ 7: 05 00 00 00 00 [ ]*add \$0x0,%eax 8: R_386_32 .text
+ c: 81 c3 00 00 00 00 [ ]*add \$0x0,%ebx e: R_386_32 .text
+ 12: 69 d2 00 00 00 00 [ ]*imul \$0x0,%edx,%edx 14: R_386_32 .text
+ 18: 9a 00 00 00 00 00 00 [ ]*lcall \$0x0,\$0x0 19: R_386_32 .text
+ 1f: 66 68 00 00 [ ]*pushw \$0x0 21: R_386_16 .text
diff --git a/gas/testsuite/gas/i386/reloc.s b/gas/testsuite/gas/i386/reloc.s
new file mode 100644
index 00000000000..13ee930db72
--- /dev/null
+++ b/gas/testsuite/gas/i386/reloc.s
@@ -0,0 +1,8 @@
+.text
+foo: mov $foo, %bl
+ push $foo
+ add $foo, %eax
+ add $foo, %ebx
+ imul $foo, %edx
+ lcall $0, $foo
+ pushw $foo
diff --git a/gas/testsuite/gas/i386/white.l b/gas/testsuite/gas/i386/white.l
new file mode 100644
index 00000000000..1ce6161fc98
--- /dev/null
+++ b/gas/testsuite/gas/i386/white.l
@@ -0,0 +1,21 @@
+GAS LISTING .*
+
+
+ 1 # test handling of whitespace, and upper-case
+ 2 .TeXt
+ 3 0000 36 ss
+ 4 0001 8803 mov % al , \( % ebx \)
+ 5 0003 C705D711 00007B00 0000 mOvl \$ 123 , 4567
+ 6 000d 678A787B ADDr16 mov 123 \( % bx , % si , 1 \) , % bh
+ 7 0011 FFE0 jmp \* % eax
+ 8 0013 6626FF23 foo: jmpw % es : \* \( % ebx \)
+ 9
+ 10 0017 A0500000 00 mov \( 0x8 \* 0Xa \) , % al
+ 11 001c B020 mov \$ \( 8 \* 4 \) , % al
+ 12 001e B713 mov \$ foo , % bH
+ 13 0020 B713 movb \$ foo , % BH
+ 14
+ 15 .CODE16
+ 16 0022 66B81300 0000 Mov \$ foo , %eAx
+ 17 .Code32
+ 18 0028 66B81300 mov \$ foo , %ax
diff --git a/gas/testsuite/gas/i386/white.s b/gas/testsuite/gas/i386/white.s
new file mode 100644
index 00000000000..3bf50705ff5
--- /dev/null
+++ b/gas/testsuite/gas/i386/white.s
@@ -0,0 +1,18 @@
+# test handling of whitespace, and upper-case
+.TeXt
+ ss
+ mov % al , ( % ebx )
+ mOvl $ 123 , 4567
+ ADDr16 mov 123 ( % bx , % si , 1 ) , % bh
+ jmp * % eax
+foo: jmpw % es : * ( % ebx )
+
+ mov ( 0x8 * 0Xa ) , % al
+ mov $ ( 8 * 4 ) , % al
+ mov $ foo , % bH
+ movb $ foo , % BH
+
+.CODE16
+ Mov $ foo , %eAx
+.Code32
+ mov $ foo , %ax
diff --git a/gas/testsuite/gas/ieee-fp/x930509a.exp b/gas/testsuite/gas/ieee-fp/x930509a.exp
new file mode 100644
index 00000000000..d788d2c9e44
--- /dev/null
+++ b/gas/testsuite/gas/ieee-fp/x930509a.exp
@@ -0,0 +1,25 @@
+# Reported 93/05/09 by Jim Wilson: IEEE single-precision FLT_MIN value gets
+# assembled incorrectly. (Off by one ulp.)
+
+proc dotest {} {
+ set testname "IEEE FLT_MIN, single-precision"
+ set x 0
+ gas_start "x930509a.s" "-al"
+ while 1 {
+ expect {
+ -re " 00008000\[ \]+.single" { pass $testname; set x 1 }
+ -re " 00800000\[ \]+.single" { pass $testname; set x 1 }
+ -re " 0080 0000\[ \]+.single" { pass $testname; set x 1 }
+ -re " ........ +.single" { fail $testname; set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ gas_finish
+ if !$x then { fail "$testname (listing didn't match)" }
+}
+
+if ![istarget vax*-*-*] then {
+ dotest
+}
diff --git a/gas/testsuite/gas/ieee-fp/x930509a.s b/gas/testsuite/gas/ieee-fp/x930509a.s
new file mode 100644
index 00000000000..261b3383acf
--- /dev/null
+++ b/gas/testsuite/gas/ieee-fp/x930509a.s
@@ -0,0 +1,5 @@
+ .global _flt_min
+ .data
+ .align 4
+_flt_min:
+ .single 0r1.17549435e-38
diff --git a/gas/testsuite/gas/m32r/allinsn.d b/gas/testsuite/gas/m32r/allinsn.d
new file mode 100644
index 00000000000..55965e66054
--- /dev/null
+++ b/gas/testsuite/gas/m32r/allinsn.d
@@ -0,0 +1,374 @@
+#as:
+#objdump: -dr
+#name: allinsn
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000 <add>:
+ 0: 0d ad f0 00 add fp,fp \|\| nop
+
+0+0004 <add3>:
+ 4: 8d ad 00 00 add3 fp,fp,[#]*0
+
+0+0008 <and>:
+ 8: 0d cd f0 00 and fp,fp \|\| nop
+
+0+000c <and3>:
+ c: 8d cd 00 00 and3 fp,fp,[#]*0x0
+
+0+0010 <or>:
+ 10: 0d ed f0 00 or fp,fp \|\| nop
+
+0+0014 <or3>:
+ 14: 8d ed 00 00 or3 fp,fp,[#]*0x0
+
+0+0018 <xor>:
+ 18: 0d dd f0 00 xor fp,fp \|\| nop
+
+0+001c <xor3>:
+ 1c: 8d dd 00 00 xor3 fp,fp,[#]*0x0
+
+0+0020 <addi>:
+ 20: 4d 00 f0 00 addi fp,[#]*0 \|\| nop
+
+0+0024 <addv>:
+ 24: 0d 8d f0 00 addv fp,fp \|\| nop
+
+0+0028 <addv3>:
+ 28: 8d 8d 00 00 addv3 fp,fp,[#]*0
+
+0+002c <addx>:
+ 2c: 0d 9d f0 00 addx fp,fp \|\| nop
+
+0+0030 <bc8>:
+ 30: 7c f4 f0 00 bc 0 <add> \|\| nop
+
+0+0034 <bc8_s>:
+ 34: 7c f3 f0 00 bc 0 <add> \|\| nop
+
+0+0038 <bc24>:
+ 38: 7c f2 f0 00 bc 0 <add> \|\| nop
+
+0+003c <bc24_l>:
+ 3c: fc ff ff f1 bc 0 <add>
+
+0+0040 <beq>:
+ 40: bd 0d ff f0 beq fp,fp,0 <add>
+
+0+0044 <beqz>:
+ 44: b0 8d ff ef beqz fp,0 <add>
+
+0+0048 <bgez>:
+ 48: b0 bd ff ee bgez fp,0 <add>
+
+0+004c <bgtz>:
+ 4c: b0 dd ff ed bgtz fp,0 <add>
+
+0+0050 <blez>:
+ 50: b0 cd ff ec blez fp,0 <add>
+
+0+0054 <bltz>:
+ 54: b0 ad ff eb bltz fp,0 <add>
+
+0+0058 <bnez>:
+ 58: b0 9d ff ea bnez fp,0 <add>
+
+0+005c <bl8>:
+ 5c: 7e e9 f0 00 bl 0 <add> \|\| nop
+
+0+0060 <bl8_s>:
+ 60: 7e e8 f0 00 bl 0 <add> \|\| nop
+
+0+0064 <bl24>:
+ 64: 7e e7 f0 00 bl 0 <add> \|\| nop
+
+0+0068 <bl24_l>:
+ 68: fe ff ff e6 bl 0 <add>
+
+0+006c <bnc8>:
+ 6c: 7d e5 f0 00 bnc 0 <add> \|\| nop
+
+0+0070 <bnc8_s>:
+ 70: 7d e4 f0 00 bnc 0 <add> \|\| nop
+
+0+0074 <bnc24>:
+ 74: 7d e3 f0 00 bnc 0 <add> \|\| nop
+
+0+0078 <bnc24_l>:
+ 78: fd ff ff e2 bnc 0 <add>
+
+0+007c <bne>:
+ 7c: bd 1d ff e1 bne fp,fp,0 <add>
+
+0+0080 <bra8>:
+ 80: 7f e0 f0 00 bra 0 <add> \|\| nop
+
+0+0084 <bra8_s>:
+ 84: 7f df f0 00 bra 0 <add> \|\| nop
+
+0+0088 <bra24>:
+ 88: 7f de f0 00 bra 0 <add> \|\| nop
+
+0+008c <bra24_l>:
+ 8c: ff ff ff dd bra 0 <add>
+
+0+0090 <cmp>:
+ 90: 0d 4d f0 00 cmp fp,fp \|\| nop
+
+0+0094 <cmpi>:
+ 94: 80 4d 00 00 cmpi fp,[#]*0
+
+0+0098 <cmpu>:
+ 98: 0d 5d f0 00 cmpu fp,fp \|\| nop
+
+0+009c <cmpui>:
+ 9c: 80 5d 00 00 cmpui fp,[#]*0
+
+0+00a0 <div>:
+ a0: 9d 0d 00 00 div fp,fp
+
+0+00a4 <divu>:
+ a4: 9d 1d 00 00 divu fp,fp
+
+0+00a8 <rem>:
+ a8: 9d 2d 00 00 rem fp,fp
+
+0+00ac <remu>:
+ ac: 9d 3d 00 00 remu fp,fp
+
+0+00b0 <jl>:
+ b0: 1e cd f0 00 jl fp \|\| nop
+
+0+00b4 <jmp>:
+ b4: 1f cd f0 00 jmp fp \|\| nop
+
+0+00b8 <ld>:
+ b8: 2d cd f0 00 ld fp,@fp \|\| nop
+
+0+00bc <ld_2>:
+ bc: 2d cd f0 00 ld fp,@fp \|\| nop
+
+0+00c0 <ld_d>:
+ c0: ad cd 00 00 ld fp,@\(0,fp\)
+
+0+00c4 <ld_d2>:
+ c4: ad cd 00 00 ld fp,@\(0,fp\)
+
+0+00c8 <ldb>:
+ c8: 2d 8d f0 00 ldb fp,@fp \|\| nop
+
+0+00cc <ldb_2>:
+ cc: 2d 8d f0 00 ldb fp,@fp \|\| nop
+
+0+00d0 <ldb_d>:
+ d0: ad 8d 00 00 ldb fp,@\(0,fp\)
+
+0+00d4 <ldb_d2>:
+ d4: ad 8d 00 00 ldb fp,@\(0,fp\)
+
+0+00d8 <ldh>:
+ d8: 2d ad f0 00 ldh fp,@fp \|\| nop
+
+0+00dc <ldh_2>:
+ dc: 2d ad f0 00 ldh fp,@fp \|\| nop
+
+0+00e0 <ldh_d>:
+ e0: ad ad 00 00 ldh fp,@\(0,fp\)
+
+0+00e4 <ldh_d2>:
+ e4: ad ad 00 00 ldh fp,@\(0,fp\)
+
+0+00e8 <ldub>:
+ e8: 2d 9d f0 00 ldub fp,@fp \|\| nop
+
+0+00ec <ldub_2>:
+ ec: 2d 9d f0 00 ldub fp,@fp \|\| nop
+
+0+00f0 <ldub_d>:
+ f0: ad 9d 00 00 ldub fp,@\(0,fp\)
+
+0+00f4 <ldub_d2>:
+ f4: ad 9d 00 00 ldub fp,@\(0,fp\)
+
+0+00f8 <lduh>:
+ f8: 2d bd f0 00 lduh fp,@fp \|\| nop
+
+0+00fc <lduh_2>:
+ fc: 2d bd f0 00 lduh fp,@fp \|\| nop
+
+0+0100 <lduh_d>:
+ 100: ad bd 00 00 lduh fp,@\(0,fp\)
+
+0+0104 <lduh_d2>:
+ 104: ad bd 00 00 lduh fp,@\(0,fp\)
+
+0+0108 <ld_plus>:
+ 108: 2d ed f0 00 ld fp,@fp\+ \|\| nop
+
+0+010c <ld24>:
+ 10c: ed 00 00 00 ld24 fp,[#]*0 <add>
+ 10c: R_M32R_24 .data
+
+0+0110 <ldi8>:
+ 110: 6d 00 f0 00 ldi fp,[#]*0 \|\| nop
+
+0+0114 <ldi16>:
+ 114: 9d f0 01 00 ldi fp,[#]*256
+
+0+0118 <lock>:
+ 118: 2d dd f0 00 lock fp,@fp \|\| nop
+
+0+011c <machi>:
+ 11c: 3d 4d f0 00 machi fp,fp \|\| nop
+
+0+0120 <maclo>:
+ 120: 3d 5d f0 00 maclo fp,fp \|\| nop
+
+0+0124 <macwhi>:
+ 124: 3d 6d f0 00 macwhi fp,fp \|\| nop
+
+0+0128 <macwlo>:
+ 128: 3d 7d f0 00 macwlo fp,fp \|\| nop
+
+0+012c <mul>:
+ 12c: 1d 6d f0 00 mul fp,fp \|\| nop
+
+0+0130 <mulhi>:
+ 130: 3d 0d f0 00 mulhi fp,fp \|\| nop
+
+0+0134 <mullo>:
+ 134: 3d 1d f0 00 mullo fp,fp \|\| nop
+
+0+0138 <mulwhi>:
+ 138: 3d 2d f0 00 mulwhi fp,fp \|\| nop
+
+0+013c <mulwlo>:
+ 13c: 3d 3d f0 00 mulwlo fp,fp \|\| nop
+
+0+0140 <mv>:
+ 140: 1d 8d f0 00 mv fp,fp \|\| nop
+
+0+0144 <mvfachi>:
+ 144: 5d f0 f0 00 mvfachi fp \|\| nop
+
+0+0148 <mvfaclo>:
+ 148: 5d f1 f0 00 mvfaclo fp \|\| nop
+
+0+014c <mvfacmi>:
+ 14c: 5d f2 f0 00 mvfacmi fp \|\| nop
+
+0+0150 <mvfc>:
+ 150: 1d 90 f0 00 mvfc fp,psw \|\| nop
+
+0+0154 <mvtachi>:
+ 154: 5d 70 f0 00 mvtachi fp \|\| nop
+
+0+0158 <mvtaclo>:
+ 158: 5d 71 f0 00 mvtaclo fp \|\| nop
+
+0+015c <mvtc>:
+ 15c: 10 ad f0 00 mvtc fp,psw \|\| nop
+
+0+0160 <neg>:
+ 160: 0d 3d f0 00 neg fp,fp \|\| nop
+
+0+0164 <nop>:
+ 164: 70 00 f0 00 nop \|\| nop
+
+0+0168 <not>:
+ 168: 0d bd f0 00 not fp,fp \|\| nop
+
+0+016c <rac>:
+ 16c: dd c0 00 00 seth fp,[#]*0x0
+
+0+0170 <sll>:
+ 170: 1d 4d f0 00 sll fp,fp \|\| nop
+
+0+0174 <sll3>:
+ 174: 9d cd 00 00 sll3 fp,fp,[#]*0
+
+0+0178 <slli>:
+ 178: 5d 40 f0 00 slli fp,[#]*0x0 \|\| nop
+
+0+017c <sra>:
+ 17c: 1d 2d f0 00 sra fp,fp \|\| nop
+
+0+0180 <sra3>:
+ 180: 9d ad 00 00 sra3 fp,fp,[#]*0
+
+0+0184 <srai>:
+ 184: 5d 20 f0 00 srai fp,[#]*0x0 \|\| nop
+
+0+0188 <srl>:
+ 188: 1d 0d f0 00 srl fp,fp \|\| nop
+
+0+018c <srl3>:
+ 18c: 9d 8d 00 00 srl3 fp,fp,[#]*0
+
+0+0190 <srli>:
+ 190: 5d 00 f0 00 srli fp,[#]*0x0 \|\| nop
+
+0+0194 <st>:
+ 194: 2d 4d f0 00 st fp,@fp \|\| nop
+
+0+0198 <st_2>:
+ 198: 2d 4d f0 00 st fp,@fp \|\| nop
+
+0+019c <st_d>:
+ 19c: ad 4d 00 00 st fp,@\(0,fp\)
+
+0+01a0 <st_d2>:
+ 1a0: ad 4d 00 00 st fp,@\(0,fp\)
+
+0+01a4 <stb>:
+ 1a4: 2d 0d f0 00 stb fp,@fp \|\| nop
+
+0+01a8 <stb_2>:
+ 1a8: 2d 0d f0 00 stb fp,@fp \|\| nop
+
+0+01ac <stb_d>:
+ 1ac: ad 0d 00 00 stb fp,@\(0,fp\)
+
+0+01b0 <stb_d2>:
+ 1b0: ad 0d 00 00 stb fp,@\(0,fp\)
+
+0+01b4 <sth>:
+ 1b4: 2d 2d f0 00 sth fp,@fp \|\| nop
+
+0+01b8 <sth_2>:
+ 1b8: 2d 2d f0 00 sth fp,@fp \|\| nop
+
+0+01bc <sth_d>:
+ 1bc: ad 2d 00 00 sth fp,@\(0,fp\)
+
+0+01c0 <sth_d2>:
+ 1c0: ad 2d 00 00 sth fp,@\(0,fp\)
+
+0+01c4 <st_plus>:
+ 1c4: 2d 6d f0 00 st fp,@\+fp \|\| nop
+
+0+01c8 <st_minus>:
+ 1c8: 2d 7d f0 00 st fp,@-fp \|\| nop
+
+0+01cc <sub>:
+ 1cc: 0d 2d f0 00 sub fp,fp \|\| nop
+
+0+01d0 <subv>:
+ 1d0: 0d 0d f0 00 subv fp,fp \|\| nop
+
+0+01d4 <subx>:
+ 1d4: 0d 1d f0 00 subx fp,fp \|\| nop
+
+0+01d8 <trap>:
+ 1d8: 10 f0 f0 00 trap [#]*0x0 \|\| nop
+
+0+01dc <unlock>:
+ 1dc: 2d 5d f0 00 unlock fp,@fp \|\| nop
+
+0+01e0 <push>:
+ 1e0: 2d 7f f0 00 push fp \|\| nop
+
+0+01e4 <pop>:
+ 1e4: 2d ef f0 00 pop fp \|\| nop
diff --git a/gas/testsuite/gas/m32r/allinsn.exp b/gas/testsuite/gas/m32r/allinsn.exp
new file mode 100644
index 00000000000..c5ddd0eb3ff
--- /dev/null
+++ b/gas/testsuite/gas/m32r/allinsn.exp
@@ -0,0 +1,5 @@
+# M32R assembler testsuite.
+
+if [istarget m32r*-*-*] {
+ run_dump_test "allinsn"
+}
diff --git a/gas/testsuite/gas/m32r/allinsn.s b/gas/testsuite/gas/m32r/allinsn.s
new file mode 100644
index 00000000000..86b456961a1
--- /dev/null
+++ b/gas/testsuite/gas/m32r/allinsn.s
@@ -0,0 +1,501 @@
+ .data
+foodata: .word 42
+ .text
+footext:
+ .text
+ .global add
+add:
+ add fp,fp
+ .text
+ .global add3
+add3:
+ add3 fp,fp,#0
+ .text
+ .global and
+and:
+ and fp,fp
+ .text
+ .global and3
+and3:
+ and3 fp,fp,#0
+ .text
+ .global or
+or:
+ or fp,fp
+ .text
+ .global or3
+or3:
+ or3 fp,fp,#0
+ .text
+ .global xor
+xor:
+ xor fp,fp
+ .text
+ .global xor3
+xor3:
+ xor3 fp,fp,#0
+ .text
+ .global addi
+addi:
+ addi fp,#0
+ .text
+ .global addv
+addv:
+ addv fp,fp
+ .text
+ .global addv3
+addv3:
+ addv3 fp,fp,#0
+ .text
+ .global addx
+addx:
+ addx fp,fp
+ .text
+ .global bc8
+bc8:
+ bc footext
+ .text
+ .global bc8_s
+bc8_s:
+ bc.s footext
+ .text
+ .global bc24
+bc24:
+ bc footext
+ .text
+ .global bc24_l
+bc24_l:
+ bc.l footext
+ .text
+ .global beq
+beq:
+ beq fp,fp,footext
+ .text
+ .global beqz
+beqz:
+ beqz fp,footext
+ .text
+ .global bgez
+bgez:
+ bgez fp,footext
+ .text
+ .global bgtz
+bgtz:
+ bgtz fp,footext
+ .text
+ .global blez
+blez:
+ blez fp,footext
+ .text
+ .global bltz
+bltz:
+ bltz fp,footext
+ .text
+ .global bnez
+bnez:
+ bnez fp,footext
+ .text
+ .global bl8
+bl8:
+ bl footext
+ .text
+ .global bl8_s
+bl8_s:
+ bl.s footext
+ .text
+ .global bl24
+bl24:
+ bl footext
+ .text
+ .global bl24_l
+bl24_l:
+ bl.l footext
+ .text
+ .global bnc8
+bnc8:
+ bnc footext
+ .text
+ .global bnc8_s
+bnc8_s:
+ bnc.s footext
+ .text
+ .global bnc24
+bnc24:
+ bnc footext
+ .text
+ .global bnc24_l
+bnc24_l:
+ bnc.l footext
+ .text
+ .global bne
+bne:
+ bne fp,fp,footext
+ .text
+ .global bra8
+bra8:
+ bra footext
+ .text
+ .global bra8_s
+bra8_s:
+ bra.s footext
+ .text
+ .global bra24
+bra24:
+ bra footext
+ .text
+ .global bra24_l
+bra24_l:
+ bra.l footext
+ .text
+ .global cmp
+cmp:
+ cmp fp,fp
+ .text
+ .global cmpi
+cmpi:
+ cmpi fp,#0
+ .text
+ .global cmpu
+cmpu:
+ cmpu fp,fp
+ .text
+ .global cmpui
+cmpui:
+ cmpui fp,#0
+ .text
+ .global div
+div:
+ div fp,fp
+ .text
+ .global divu
+divu:
+ divu fp,fp
+ .text
+ .global rem
+rem:
+ rem fp,fp
+ .text
+ .global remu
+remu:
+ remu fp,fp
+ .text
+ .global jl
+jl:
+ jl fp
+ .text
+ .global jmp
+jmp:
+ jmp fp
+ .text
+ .global ld
+ld:
+ ld fp,@fp
+ .text
+ .global ld_2
+ld_2:
+ ld fp,@(fp)
+ .text
+ .global ld_d
+ld_d:
+ ld fp,@(0,fp)
+ .text
+ .global ld_d2
+ld_d2:
+ ld fp,@(fp,0)
+ .text
+ .global ldb
+ldb:
+ ldb fp,@fp
+ .text
+ .global ldb_2
+ldb_2:
+ ldb fp,@(fp)
+ .text
+ .global ldb_d
+ldb_d:
+ ldb fp,@(0,fp)
+ .text
+ .global ldb_d2
+ldb_d2:
+ ldb fp,@(fp,0)
+ .text
+ .global ldh
+ldh:
+ ldh fp,@fp
+ .text
+ .global ldh_2
+ldh_2:
+ ldh fp,@(fp)
+ .text
+ .global ldh_d
+ldh_d:
+ ldh fp,@(0,fp)
+ .text
+ .global ldh_d2
+ldh_d2:
+ ldh fp,@(fp,0)
+ .text
+ .global ldub
+ldub:
+ ldub fp,@fp
+ .text
+ .global ldub_2
+ldub_2:
+ ldub fp,@(fp)
+ .text
+ .global ldub_d
+ldub_d:
+ ldub fp,@(0,fp)
+ .text
+ .global ldub_d2
+ldub_d2:
+ ldub fp,@(fp,0)
+ .text
+ .global lduh
+lduh:
+ lduh fp,@fp
+ .text
+ .global lduh_2
+lduh_2:
+ lduh fp,@(fp)
+ .text
+ .global lduh_d
+lduh_d:
+ lduh fp,@(0,fp)
+ .text
+ .global lduh_d2
+lduh_d2:
+ lduh fp,@(fp,0)
+ .text
+ .global ld_plus
+ld_plus:
+ ld fp,@fp+
+ .text
+ .global ld24
+ld24:
+ ld24 fp,foodata
+ .text
+ .global ldi8
+ldi8:
+ ldi fp,0
+ .text
+ .global ldi16
+ldi16:
+ ldi fp,256
+ .text
+ .global lock
+lock:
+ lock fp,@fp
+ .text
+ .global machi
+machi:
+ machi fp,fp
+ .text
+ .global maclo
+maclo:
+ maclo fp,fp
+ .text
+ .global macwhi
+macwhi:
+ macwhi fp,fp
+ .text
+ .global macwlo
+macwlo:
+ macwlo fp,fp
+ .text
+ .global mul
+mul:
+ mul fp,fp
+ .text
+ .global mulhi
+mulhi:
+ mulhi fp,fp
+ .text
+ .global mullo
+mullo:
+ mullo fp,fp
+ .text
+ .global mulwhi
+mulwhi:
+ mulwhi fp,fp
+ .text
+ .global mulwlo
+mulwlo:
+ mulwlo fp,fp
+ .text
+ .global mv
+mv:
+ mv fp,fp
+ .text
+ .global mvfachi
+mvfachi:
+ mvfachi fp
+ .text
+ .global mvfaclo
+mvfaclo:
+ mvfaclo fp
+ .text
+ .global mvfacmi
+mvfacmi:
+ mvfacmi fp
+ .text
+ .global mvfc
+mvfc:
+ mvfc fp,psw
+ .text
+ .global mvtachi
+mvtachi:
+ mvtachi fp
+ .text
+ .global mvtaclo
+mvtaclo:
+ mvtaclo fp
+ .text
+ .global mvtc
+mvtc:
+ mvtc fp,psw
+ .text
+ .global neg
+neg:
+ neg fp,fp
+ .text
+ .global nop
+nop:
+ nop
+ .text
+ .global not
+not:
+ not fp,fp
+ .text
+ .global rac
+rac:
+ .text
+ .global rach
+rach:
+ .text
+ .global rte
+rte:
+ .text
+ .global seth
+seth:
+ seth fp,0
+ .text
+ .global sll
+sll:
+ sll fp,fp
+ .text
+ .global sll3
+sll3:
+ sll3 fp,fp,0
+ .text
+ .global slli
+slli:
+ slli fp,0
+ .text
+ .global sra
+sra:
+ sra fp,fp
+ .text
+ .global sra3
+sra3:
+ sra3 fp,fp,0
+ .text
+ .global srai
+srai:
+ srai fp,0
+ .text
+ .global srl
+srl:
+ srl fp,fp
+ .text
+ .global srl3
+srl3:
+ srl3 fp,fp,0
+ .text
+ .global srli
+srli:
+ srli fp,0
+ .text
+ .global st
+st:
+ st fp,@fp
+ .text
+ .global st_2
+st_2:
+ st fp,@(fp)
+ .text
+ .global st_d
+st_d:
+ st fp,@(0,fp)
+ .text
+ .global st_d2
+st_d2:
+ st fp,@(fp,0)
+ .text
+ .global stb
+stb:
+ stb fp,@fp
+ .text
+ .global stb_2
+stb_2:
+ stb fp,@(fp)
+ .text
+ .global stb_d
+stb_d:
+ stb fp,@(0,fp)
+ .text
+ .global stb_d2
+stb_d2:
+ stb fp,@(fp,0)
+ .text
+ .global sth
+sth:
+ sth fp,@fp
+ .text
+ .global sth_2
+sth_2:
+ sth fp,@(fp)
+ .text
+ .global sth_d
+sth_d:
+ sth fp,@(0,fp)
+ .text
+ .global sth_d2
+sth_d2:
+ sth fp,@(fp,0)
+ .text
+ .global st_plus
+st_plus:
+ st fp,@+fp
+ .text
+ .global st_minus
+st_minus:
+ st fp,@-fp
+ .text
+ .global sub
+sub:
+ sub fp,fp
+ .text
+ .global subv
+subv:
+ subv fp,fp
+ .text
+ .global subx
+subx:
+ subx fp,fp
+ .text
+ .global trap
+trap:
+ trap 0
+ .text
+ .global unlock
+unlock:
+ unlock fp,@fp
+ .text
+ .global push
+push:
+ push fp
+ .text
+ .global pop
+pop:
+ pop fp
diff --git a/gas/testsuite/gas/m32r/fslot.d b/gas/testsuite/gas/m32r/fslot.d
new file mode 100644
index 00000000000..a9cf02bd7d0
--- /dev/null
+++ b/gas/testsuite/gas/m32r/fslot.d
@@ -0,0 +1,31 @@
+#as:
+#objdump: -dr
+#name: fslot
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0 <bl>:
+ *0: 7e 00 f0 00 bl 0 <bl> \|\| nop
+ *4: 60 08 f0 00 ldi r0,[#]*8 \|\| nop
+
+0+8 <bl_s>:
+ *8: 7e 00 f0 00 bl 8 <bl_s> \|\| nop
+ *c: 60 08 f0 00 ldi r0,[#]*8 \|\| nop
+
+0+10 <bra>:
+ *10: 7f 00 f0 00 bra 10 <bra> \|\| nop
+ *14: 60 08 f0 00 ldi r0,[#]*8 \|\| nop
+
+0+18 <bra_s>:
+ *18: 7f 00 f0 00 bra 18 <bra_s> \|\| nop
+ *1c: 60 08 f0 00 ldi r0,[#]*8 \|\| nop
+
+0+20 <jl>:
+ *20: 1e c0 f0 00 jl r0 \|\| nop
+ *24: 60 08 f0 00 ldi r0,[#]*8 \|\| nop
+
+0+28 <trap>:
+ *28: 10 f4 f0 00 trap [#]*0x4 \|\| nop
+ *2c: 60 08 f0 00 ldi r0,[#]*8 \|\| nop
diff --git a/gas/testsuite/gas/m32r/fslot.s b/gas/testsuite/gas/m32r/fslot.s
new file mode 100644
index 00000000000..586b664d9e5
--- /dev/null
+++ b/gas/testsuite/gas/m32r/fslot.s
@@ -0,0 +1,27 @@
+# Test the FILL-SLOT attribute.
+# The FILL-SLOT attribute ensures the next insn begins on a 32 byte boundary.
+# This is needed for example with bl because the subroutine will return
+# to a 32 bit boundary.
+
+ .text
+bl:
+ bl bl
+ ldi r0,#8
+bl_s:
+ bl.s bl_s
+ ldi r0,#8
+
+bra:
+ bra bra
+ ldi r0,#8
+bra_s:
+ bra.s bra_s
+ ldi r0,#8
+
+jl:
+ jl r0
+ ldi r0,#8
+
+trap:
+ trap #4
+ ldi r0,#8
diff --git a/gas/testsuite/gas/m32r/high-1.d b/gas/testsuite/gas/m32r/high-1.d
new file mode 100644
index 00000000000..b5ccb8c55bc
--- /dev/null
+++ b/gas/testsuite/gas/m32r/high-1.d
@@ -0,0 +1,19 @@
+#as:
+#objdump: -dr
+#name: high-1
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0* <foo>:
+ *0: d4 c0 00 01 seth r4,[#]*0x1
+[ ]*0: R_M32R_HI16_ULO .text
+ *4: 84 e4 00 00 or3 r4,r4,[#]*0x0
+[ ]*4: R_M32R_LO16 .text
+ *8: d4 c0 12 34 seth r4,[#]*0x1234
+ *c: 84 e4 87 65 or3 r4,r4,[#]*0x8765
+ *10: d4 c0 12 35 seth r4,[#]*0x1235
+ *14: 84 e4 87 65 or3 r4,r4,[#]*0x8765
+ *18: d4 c0 87 65 seth r4,[#]*0x8765
+ *1c: 84 e4 43 21 or3 r4,r4,[#]*0x4321
diff --git a/gas/testsuite/gas/m32r/high-1.s b/gas/testsuite/gas/m32r/high-1.s
new file mode 100644
index 00000000000..8a5d1d10ab3
--- /dev/null
+++ b/gas/testsuite/gas/m32r/high-1.s
@@ -0,0 +1,14 @@
+; Test high/shigh handling.
+
+foo:
+ seth r4,#high(foo+0x10000)
+ or3 r4,r4,#low(foo+0x10000)
+
+ seth r4,#high(0x12348765)
+ or3 r4,r4,#low(0x12348765)
+
+ seth r4,#shigh(0x12348765)
+ or3 r4,r4,#low(0x12348765)
+
+ seth r4,#shigh(0x87654321)
+ or3 r4,r4,#low(0x87654321)
diff --git a/gas/testsuite/gas/m32r/m32r.exp b/gas/testsuite/gas/m32r/m32r.exp
new file mode 100644
index 00000000000..28c23642fac
--- /dev/null
+++ b/gas/testsuite/gas/m32r/m32r.exp
@@ -0,0 +1,8 @@
+# M32R testcases
+
+if [istarget m32r*-*-*] {
+ run_dump_test "high-1"
+ run_dump_test "relax-1"
+ run_dump_test "uppercase"
+ run_dump_test "fslot"
+}
diff --git a/gas/testsuite/gas/m32r/outofrange.s b/gas/testsuite/gas/m32r/outofrange.s
new file mode 100644
index 00000000000..570d311bdcd
--- /dev/null
+++ b/gas/testsuite/gas/m32r/outofrange.s
@@ -0,0 +1,145 @@
+; Test error messages where branches are out of range.
+
+; { dg-do assemble { target m32r-*-* } }
+
+ .text
+ .global foo
+foo:
+ bl.s label
+ ; { dg-error "out of range" "out of range bl.s" { target *-*-* } { 8 } }
+ bnc.s label
+ ; { dg-error "out of range" "out of range bnc.s" { target *-*-* } { 10 } }
+ bra.s label
+ ; { dg-error "out of range" "out of range bra.s" { target *-*-* } { 12 } }
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+ ld24 r0,#0
+label:
+ jmp r14
diff --git a/gas/testsuite/gas/m32r/relax-1.d b/gas/testsuite/gas/m32r/relax-1.d
new file mode 100644
index 00000000000..2a4fcb80058
--- /dev/null
+++ b/gas/testsuite/gas/m32r/relax-1.d
@@ -0,0 +1,18 @@
+#as:
+#objdump: -dr
+#name: relax-1
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0* <DoesNotWork>:
+ *0: 70 00 70 00 * nop -> nop
+
+0*4 <Work>:
+ *4: 70 00 70 00 * nop -> nop
+Disassembly of section .branch:
+
+0* <branch>:
+ *0: ff 00 00 01 bra 4 <Work>
+[ ]*0: R_M32R_26_PCREL .text
diff --git a/gas/testsuite/gas/m32r/relax-1.s b/gas/testsuite/gas/m32r/relax-1.s
new file mode 100644
index 00000000000..d4e12c0fd3d
--- /dev/null
+++ b/gas/testsuite/gas/m32r/relax-1.s
@@ -0,0 +1,17 @@
+; Test relaxation into non-zero offset to different segment.
+
+ .section .branch, "ax",@progbits
+ .balign 4
+branch:
+ bra Work
+
+
+ .section .text
+ .balign 4
+DoesNotWork:
+ nop
+ nop
+
+Work:
+ nop
+ nop
diff --git a/gas/testsuite/gas/m32r/uppercase.d b/gas/testsuite/gas/m32r/uppercase.d
new file mode 100644
index 00000000000..12b1345988a
--- /dev/null
+++ b/gas/testsuite/gas/m32r/uppercase.d
@@ -0,0 +1,26 @@
+#as:
+#objdump: -dr
+#name: uppercase
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+0000 <foo>:
+ 0: 10 81 10 91 * mv r0,r1 -> mvfc r0,cbr
+
+0+0004 <high>:
+ 4: d0 c0 00 00 seth r0,#0x0
+[ ]*4: R_M32R_HI16_ULO [.]text
+
+0+0008 <shigh>:
+ 8: d0 c0 00 00 seth r0,#0x0
+[ ]*8: R_M32R_HI16_SLO [.]text
+
+0+000c <low>:
+ c: 80 e0 00 0c or3 r0,r0,#0xc
+[ ]*c: R_M32R_LO16 [.]text
+
+0+0010 <sda>:
+ 10: 80 a0 00 00 add3 r0,r0,#0
+[ ]*10: R_M32R_SDA16 sdavar
diff --git a/gas/testsuite/gas/m32r/uppercase.s b/gas/testsuite/gas/m32r/uppercase.s
new file mode 100644
index 00000000000..bdaeafd9f12
--- /dev/null
+++ b/gas/testsuite/gas/m32r/uppercase.s
@@ -0,0 +1,14 @@
+ .text
+ .global foo
+foo:
+ mv R0,R1
+ mvfc R0,CBR
+
+high:
+ seth r0,#HIGH(high)
+shigh:
+ seth r0,#SHIGH(shigh)
+low:
+ or3 r0,r0,#LOW(low)
+sda:
+ add3 r0,r0,#SDA(sdavar)
diff --git a/gas/testsuite/gas/m68k-coff/gas.exp b/gas/testsuite/gas/m68k-coff/gas.exp
new file mode 100644
index 00000000000..ab7eefa3a52
--- /dev/null
+++ b/gas/testsuite/gas/m68k-coff/gas.exp
@@ -0,0 +1,15 @@
+#
+# Some m68k-coff tests
+#
+if [istarget m68*-*-coff] then {
+ gas_test "p2430.s" "" $stdoptlist "local branch not in text section"
+
+ gas_test "p2430a.s" "" $stdoptlist "local branch not in text section"
+
+ gas_test "t1.s" "" $stdoptlist "multiple .file directives"
+
+ gas_test "p2389.s" "" $stdoptlist "bss fill"
+
+ setup_xfail m68*-*-coff
+ gas_test_error "p2389a.s" "" "detect bss fill with non-zero data"
+}
diff --git a/gas/testsuite/gas/m68k-coff/p2389.s b/gas/testsuite/gas/m68k-coff/p2389.s
new file mode 100644
index 00000000000..3fa93e9b478
--- /dev/null
+++ b/gas/testsuite/gas/m68k-coff/p2389.s
@@ -0,0 +1,19 @@
+# I reached a point where the file looks
+# clean and complies with gas syntax, but it core dumps gas. Here's a
+# little gdb info:
+#
+# Program terminated with signal 11, Segmentation fault.
+# #0 0x6323c in memcpy ()
+# (gdb) bt
+# #0 0x6323c in memcpy ()
+# #1 0xf2b0 in fill_section (abfd=0xeaee8, filehdr=0x8a7f4,
+# file_cursor=0xf7fff654) at obj-format.c:534
+# #2 0x112a8 in write_object_file () at obj-format.c:1786
+# #3 0x13ef8 in main (argc=5, argv=0xf7fff7bc) at ../../p3/gas/as.c:310
+# (gdb)
+#
+# gas did manage to create the .o file at this point.
+
+ .bss
+
+_ASIC_INT_TBL: .space 32,0 | keep interrupt routines here
diff --git a/gas/testsuite/gas/m68k-coff/p2389a.s b/gas/testsuite/gas/m68k-coff/p2389a.s
new file mode 100644
index 00000000000..76b27657ad0
--- /dev/null
+++ b/gas/testsuite/gas/m68k-coff/p2389a.s
@@ -0,0 +1,3 @@
+ .bss
+
+_ASIC_INT_TBL: .space 32,1 | keep interrupt routines here
diff --git a/gas/testsuite/gas/m68k-coff/p2430.s b/gas/testsuite/gas/m68k-coff/p2430.s
new file mode 100644
index 00000000000..49723d9df34
--- /dev/null
+++ b/gas/testsuite/gas/m68k-coff/p2430.s
@@ -0,0 +1,6 @@
+# This differs from p2430a.s (the customer's actual source file) only
+# in whitespace and comments. Strangely, this file gave no problems...
+
+ .sect foo
+tag:
+ bra tag
diff --git a/gas/testsuite/gas/m68k-coff/p2430a.s b/gas/testsuite/gas/m68k-coff/p2430a.s
new file mode 100644
index 00000000000..601fb117d9e
--- /dev/null
+++ b/gas/testsuite/gas/m68k-coff/p2430a.s
@@ -0,0 +1,4 @@
+ .sect foo
+
+tag:
+ bra tag
diff --git a/gas/testsuite/gas/m68k-coff/t1.s b/gas/testsuite/gas/m68k-coff/t1.s
new file mode 100644
index 00000000000..cc015f2a0de
--- /dev/null
+++ b/gas/testsuite/gas/m68k-coff/t1.s
@@ -0,0 +1,36 @@
+# 1 "libgcc1.S"
+# 42 "libxyz1.S"
+# 259 "libgcc1.S"
+ .text
+ .proc
+|#PROC# 04
+ .globl __mulsi3
+ __mulsi3 :
+|#PROLOGUE# 0
+ link %a6 ,#0
+ addl #-LF14, %sp
+ moveml #LS14, %sp @
+|#PROLOGUE# 1
+ movew %a6 @(0x8), %d0
+ muluw %a6 @(0xe), %d0
+ movew %a6 @(0xa), %d1
+ muluw %a6 @(0xc), %d1
+ addw %d1 , %d0
+ lsll #8, %d0
+ lsll #8, %d0
+ movew %a6 @(0xa), %d1
+ muluw %a6 @(0xe), %d1
+ addl %d1 , %d0
+ jra LE14
+LE14:
+|#PROLOGUE# 2
+ moveml %sp @, #LS14
+ unlk %a6
+|#PROLOGUE# 3
+ rts
+ LF14 = 4
+ LS14 = 0x0002
+ LFF14 = 0
+# 354 "libgcc1.S"
+ LSS14 = 0x0
+ LV14 = 0
diff --git a/gas/testsuite/gas/m68k/all.exp b/gas/testsuite/gas/m68k/all.exp
new file mode 100644
index 00000000000..88ab2a05c01
--- /dev/null
+++ b/gas/testsuite/gas/m68k/all.exp
@@ -0,0 +1,39 @@
+#
+# Some generic m68k tests
+#
+if [istarget m68*-*-*] then {
+ gas_test "t2.s" "" "" "cross-section branch"
+ if [istarget m68*-motorola-sysv] then {
+ run_dump_test t2
+ }
+
+ gas_test "pic1.s" "" "" "PIC generation"
+
+ gas_test "disperr.s" "-m68020" "" "Incorrect Displacement too long error"
+
+ gas_test_error "p2410.s" "" "out-of-range 'bras'"
+
+ run_dump_test pcrel
+ run_dump_test operands
+ run_dump_test cas
+ run_dump_test bitfield
+ run_dump_test link
+ run_dump_test fmoveml
+
+ set testname "68000 operands"
+ gas_run "operands.s" "-m68000" "2>err.out"
+ if ![string match "child process exited abnormally" $comp_output] then {
+ send_log "$comp_output\n"
+ verbose "$comp_output" 3
+ fail $testname
+ } else {
+ if [regexp_diff "err.out" "$srcdir/$subdir/op68000.d"] then {
+ fail $testname
+ } else {
+ pass $testname
+ }
+ }
+}
+if [info exists errorInfo] then {
+ unset errorInfo
+ }
diff --git a/gas/testsuite/gas/m68k/bitfield.d b/gas/testsuite/gas/m68k/bitfield.d
new file mode 100644
index 00000000000..5fb1bdd9d86
--- /dev/null
+++ b/gas/testsuite/gas/m68k/bitfield.d
@@ -0,0 +1,28 @@
+#objdump: -d --prefix-addresses
+#name: bitfield
+
+# Test handling of bitfield instruction operands.
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+000 <foo> bfexts %a0@,1,2,%d0
+0+004 <foo\+(0x|)4> bfexts %a0@,1,6,%d0
+0+008 <foo\+(0x|)8> bfexts %a0@,3,2,%d0
+0+00c <foo\+(0x|)c> bfexts %a0@,3,6,%d0
+0+010 <foo\+(0x|)10> bfexts %a0@,1,2,%d0
+0+014 <foo\+(0x|)14> bfexts %a0@,1,6,%d0
+0+018 <foo\+(0x|)18> bfexts %a0@,3,2,%d0
+0+01c <foo\+(0x|)1c> bfexts %a0@,3,6,%d0
+0+020 <foo\+(0x|)20> bfset %a0@,1,2
+0+024 <foo\+(0x|)24> bfset %a0@,1,6
+0+028 <foo\+(0x|)28> bfset %a0@,3,2
+0+02c <foo\+(0x|)2c> bfset %a0@,3,6
+0+030 <foo\+(0x|)30> bfset %a0@,1,2
+0+034 <foo\+(0x|)34> bfset %a0@,1,6
+0+038 <foo\+(0x|)38> bfset %a0@,3,2
+0+03c <foo\+(0x|)3c> bfset %a0@,3,6
+0+040 <foo\+(0x|)40> bfexts %a0@,%d1,%d2,%d0
+0+044 <foo\+(0x|)44> bfexts %a0@,%d1,%d2,%d0
+0+048 <foo\+(0x|)48> bfset %a0@,%d1,%d2
+0+04c <foo\+(0x|)4c> bfset %a0@,%d1,%d2
diff --git a/gas/testsuite/gas/m68k/bitfield.s b/gas/testsuite/gas/m68k/bitfield.s
new file mode 100644
index 00000000000..4d2f758255a
--- /dev/null
+++ b/gas/testsuite/gas/m68k/bitfield.s
@@ -0,0 +1,24 @@
+# Test handling of bitfield instruction operands.
+ .text
+ .globl foo
+foo:
+ bfexts (%a0){&1:&2},%d0
+ bfexts (%a0){&1:&(2+4)},%d0
+ bfexts (%a0){&(1+2):&2},%d0
+ bfexts (%a0){&(1+2):&(2+4)},%d0
+ bfexts %a0@,&1,&2,%d0
+ bfexts %a0@,&1,&(2+4),%d0
+ bfexts %a0@,&1+2,&2,%d0
+ bfexts %a0@,&(1+2),&(2+4),%d0
+ bfset (%a0){&1:&2}
+ bfset (%a0){&1:&(2+4)}
+ bfset (%a0){&(1+2):&2}
+ bfset (%a0){&(1+2):&(2+4)}
+ bfset %a0@,&1,&2
+ bfset %a0@,&1,&(2+4)
+ bfset %a0@,&1+2,&2
+ bfset %a0@,&(1+2),&(2+4)
+ bfexts (%a0){%d1:%d2},%d0
+ bfexts %a0@,%d1,%d2,%d0
+ bfset (%a0){%d1:%d2}
+ bfset %a0@,%d1,%d2
diff --git a/gas/testsuite/gas/m68k/cas.d b/gas/testsuite/gas/m68k/cas.d
new file mode 100644
index 00000000000..6309733d14b
--- /dev/null
+++ b/gas/testsuite/gas/m68k/cas.d
@@ -0,0 +1,20 @@
+#objdump: -d --prefix-addresses
+#name: cas
+
+# Test parsing of the operands of the cas instruction
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+000 <foo> casw %d0,%d1,%a0@
+0+004 <foo\+(0x|)4> casw %d0,%d1,%a0@
+0+008 <foo\+(0x|)8> cas2w %d0,%d2,%d3,%d4,%a0@,%a1@
+0+00e <foo\+(0x|)e> cas2w %d0,%d2,%d3,%d4,@\(%d0\),@\(%d1\)
+0+014 <foo\+(0x|)14> cas2w %d0,%d2,%d3,%d4,%a0@,%a1@
+0+01a <foo\+(0x|)1a> cas2w %d0,%d2,%d3,%d4,%a0@,%a1@
+0+020 <foo\+(0x|)20> cas2w %d0,%d2,%d3,%d4,@\(%d0\),@\(%d1\)
+0+026 <foo\+(0x|)26> cas2w %d0,%d2,%d3,%d4,%a0@,%a1@
+0+02c <foo\+(0x|)2c> cas2w %d0,%d2,%d3,%d4,@\(%d0\),@\(%d1\)
+0+032 <foo\+(0x|)32> cas2w %d0,%d2,%d3,%d4,%a0@,%a1@
+0+038 <foo\+(0x|)38> cas2w %d0,%d2,%d3,%d4,%a0@,%a1@
+0+03e <foo\+(0x|)3e> cas2w %d0,%d2,%d3,%d4,@\(%d0\),@\(%d1\)
diff --git a/gas/testsuite/gas/m68k/cas.s b/gas/testsuite/gas/m68k/cas.s
new file mode 100644
index 00000000000..f64e7f54c3c
--- /dev/null
+++ b/gas/testsuite/gas/m68k/cas.s
@@ -0,0 +1,16 @@
+# Test parsing of the operands of the cas instruction
+ .text
+ .globl foo
+foo:
+ cas %d0,%d1,(%a0)
+ cas %d0,%d1,%a0@
+ cas2 %d0:%d2,%d3:%d4,(%a0):(%a1)
+ cas2 %d0:%d2,%d3:%d4,(%d0):(%d1)
+ cas2 %d0:%d2,%d3:%d4,%a0@:%a1@
+ cas2 %d0:%d2,%d3:%d4,@(%a0):@(%a1)
+ cas2 %d0:%d2,%d3:%d4,@(%d0):@(%d1)
+ cas2 %d0,%d2,%d3,%d4,(%a0),(%a1)
+ cas2 %d0,%d2,%d3,%d4,(%d0),(%d1)
+ cas2 %d0,%d2,%d3,%d4,%a0@,%a1@
+ cas2 %d0,%d2,%d3,%d4,@(%a0),@(%a1)
+ cas2 %d0,%d2,%d3,%d4,@(%d0),@(%d1)
diff --git a/gas/testsuite/gas/m68k/disperr.s b/gas/testsuite/gas/m68k/disperr.s
new file mode 100644
index 00000000000..fcd3b7b2eef
--- /dev/null
+++ b/gas/testsuite/gas/m68k/disperr.s
@@ -0,0 +1,16 @@
+#NO_APP
+gcc2_compiled.:
+___gnu_compiled_c:
+.text
+ .even
+.globl _foo
+_foo:
+ link %a6,#-12
+ fmovex %a6@(-12),%fp0
+ fmovex %fp0,%sp@-
+ jbsr _bar
+ addqw #8,%sp
+ addqw #4,%sp
+L1:
+ unlk %a6
+ rts
diff --git a/gas/testsuite/gas/m68k/fmoveml.d b/gas/testsuite/gas/m68k/fmoveml.d
new file mode 100644
index 00000000000..e4e2793afd9
--- /dev/null
+++ b/gas/testsuite/gas/m68k/fmoveml.d
@@ -0,0 +1,60 @@
+#objdump: -d --prefix-addresses
+#name: fmoveml
+
+# Test handling of fmoveml and fmovemx instructions.
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+000 <foo> fmovel %fpcr,%a0@
+0+004 <foo\+(0x|)4> fmovel %fpsr,%a0@
+0+008 <foo\+(0x|)8> fmovel %fpiar,%a0@
+0+00c <foo\+(0x|)c> fmoveml %fpsr/%fpcr,%a0@
+0+010 <foo\+(0x|)10> fmoveml %fpiar/%fpcr,%a0@
+0+014 <foo\+(0x|)14> fmoveml %fpiar/%fpsr,%a0@
+0+018 <foo\+(0x|)18> fmoveml %fpiar/%fpsr/%fpcr,%a0@
+0+01c <foo\+(0x|)1c> fmovel %fpcr,%d0
+0+020 <foo\+(0x|)20> fmovel %fpsr,%d0
+0+024 <foo\+(0x|)24> fmovel %fpiar,%d0
+0+028 <foo\+(0x|)28> fmovel %fpiar,%a0
+0+02c <foo\+(0x|)2c> fmovel %a0@,%fpcr
+0+030 <foo\+(0x|)30> fmovel %a0@,%fpsr
+0+034 <foo\+(0x|)34> fmovel %a0@,%fpiar
+0+038 <foo\+(0x|)38> fmoveml %a0@,%fpsr/%fpcr
+0+03c <foo\+(0x|)3c> fmoveml %a0@,%fpiar/%fpcr
+0+040 <foo\+(0x|)40> fmoveml %a0@,%fpiar/%fpsr
+0+044 <foo\+(0x|)44> fmoveml %a0@,%fpiar/%fpsr/%fpcr
+0+048 <foo\+(0x|)48> fmovel %d0,%fpcr
+0+04c <foo\+(0x|)4c> fmovel %d0,%fpsr
+0+050 <foo\+(0x|)50> fmovel %d0,%fpiar
+0+054 <foo\+(0x|)54> fmovel %a0,%fpiar
+0+058 <foo\+(0x|)58> fmovel #1,%fpcr
+0+060 <foo\+(0x|)60> fmovel #1,%fpsr
+0+068 <foo\+(0x|)68> fmovel #1,%fpiar
+0+070 <foo\+(0x|)70> fmoveml #1,%fpsr/%fpcr
+0+078 <foo\+(0x|)78> fmoveml #1,%fpiar/%fpcr
+0+080 <foo\+(0x|)80> fmoveml #1,%fpiar/%fpsr
+0+088 <foo\+(0x|)88> fmoveml #1,%fpiar/%fpsr/%fpcr
+0+090 <foo\+(0x|)90> fmovemx %fp1,%a0@
+0+094 <foo\+(0x|)94> fmovemx %fp4,%a0@
+0+098 <foo\+(0x|)98> fmovemx %fp7,%a0@
+0+09c <foo\+(0x|)9c> fmovemx %fp1/%fp3,%a0@
+0+0a0 <foo\+(0x|)a0> fmovemx %fp1-%fp4,%a0@
+0+0a4 <foo\+(0x|)a4> fmovemx %fp0/%fp7,%a0@
+0+0a8 <foo\+(0x|)a8> fmovemx %fp0-%fp7,%a0@
+0+0ac <foo\+(0x|)ac> fmovemx %a0@,%fp0
+0+0b0 <foo\+(0x|)b0> fmovemx %a0@,%fp1
+0+0b4 <foo\+(0x|)b4> fmovemx %a0@,%fp7
+0+0b8 <foo\+(0x|)b8> fmovemx %a0@,%fp0/%fp3
+0+0bc <foo\+(0x|)bc> fmovemx %a0@,%fp0/%fp4
+0+0c0 <foo\+(0x|)c0> fmovemx %a0@,%fp2-%fp4
+0+0c4 <foo\+(0x|)c4> fmovemx %a0@,%fp1-%fp7
+0+0c8 <foo\+(0x|)c8> fmovemx %fp0,%a0@-
+0+0cc <foo\+(0x|)cc> fmovemx %fp0-%fp7,%a0@-
+0+0d0 <foo\+(0x|)d0> fmovemx %fp0/%fp4,%a0@-
+0+0d4 <foo\+(0x|)d4> fmovemx %a0@\+,%fp7
+0+0d8 <foo\+(0x|)d8> fmovemx %a0@\+,%fp0-%fp7
+0+0dc <foo\+(0x|)dc> fmovemx %a0@\+,%fp3/%fp7
+0+0e0 <foo\+(0x|)e0> fmovemx %d0,%a0@-
+0+0e4 <foo\+(0x|)e4> fmovemx %a0@\+,%d0
+0+0e8 <foo\+(0x|)e8> fmovemx %fp1/%fp5,%a0@-
diff --git a/gas/testsuite/gas/m68k/fmoveml.s b/gas/testsuite/gas/m68k/fmoveml.s
new file mode 100644
index 00000000000..e74224bafc0
--- /dev/null
+++ b/gas/testsuite/gas/m68k/fmoveml.s
@@ -0,0 +1,58 @@
+# Test handling of the fmoveml and fmovemx instructions.
+ .text
+ .globl foo
+foo:
+ fmoveml %fpcr,%a0@
+ fmoveml %fpsr,%a0@
+ fmoveml %fpiar,%a0@
+ fmoveml %fpcr/%fpsr,%a0@
+ fmoveml %fpcr/%fpiar,%a0@
+ fmoveml %fpsr/%fpiar,%a0@
+ fmoveml %fpcr/%fpsr/%fpiar,%a0@
+ fmoveml %fpcr,%d0
+ fmoveml %fpsr,%d0
+ fmoveml %fpiar,%d0
+ fmoveml %fpiar,%a0
+ fmoveml %a0@,%fpcr
+ fmoveml %a0@,%fpsr
+ fmoveml %a0@,%fpiar
+ fmoveml %a0@,%fpsr/%fpcr
+ fmoveml %a0@,%fpiar/%fpcr
+ fmoveml %a0@,%fpiar/%fpsr
+ fmoveml %a0@,%fpsr/%fpiar/%fpcr
+ fmoveml %d0,%fpcr
+ fmoveml %d0,%fpsr
+ fmoveml %d0,%fpiar
+ fmoveml %a0,%fpiar
+ fmoveml &1,%fpcr
+ fmoveml &1,%fpsr
+ fmoveml &1,%fpiar
+ fmoveml &1,%fpcr/%fpsr
+ fmoveml &1,%fpcr/%fpiar
+ fmoveml &1,%fpsr/%fpiar
+ fmoveml &1,%fpiar/%fpsr/%fpcr
+
+ fmovemx %fp1,%a0@
+ fmovemx %fp4,%a0@
+ fmovemx %fp7,%a0@
+ fmovemx %fp1/%fp3,%a0@
+ fmovemx %fp1-%fp4,%a0@
+ fmovemx %fp0/%fp7,%a0@
+ fmovemx %fp0-%fp7,%a0@
+ fmovemx %a0@,%fp0
+ fmovemx %a0@,%fp1
+ fmovemx %a0@,%fp7
+ fmovemx %a0@,%fp0/%fp3
+ fmovemx %a0@,%fp0/%fp4
+ fmovemx %a0@,%fp2-%fp4
+ fmovemx %a0@,%fp1-%fp7
+ fmovemx &1,%a0@-
+ fmovemx &0xff,%a0@-
+ fmovemx &0x11,%a0@-
+ fmovemx %a0@+,&1
+ fmovemx %a0@+,&0xff
+ fmovemx %a0@+,&0x11
+ fmovemx %d0,%a0@-
+ fmovemx %a0@+,%d0
+ fmovemx &sym,%a0@-
+ sym = 0x22
diff --git a/gas/testsuite/gas/m68k/link.d b/gas/testsuite/gas/m68k/link.d
new file mode 100644
index 00000000000..005263fdbfa
--- /dev/null
+++ b/gas/testsuite/gas/m68k/link.d
@@ -0,0 +1,17 @@
+#objdump: -d --prefix-addresses
+#name: link
+
+# Test handling of link instruction.
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+000 <foo> linkw %fp,#0
+0+004 <foo\+(0x|)4> linkw %fp,#-4
+0+008 <foo\+(0x|)8> linkw %fp,#-32767
+0+00c <foo\+(0x|)c> linkw %fp,#-32768
+0+010 <foo\+(0x|)10> linkl %fp,#-32769
+0+016 <foo\+(0x|)16> linkw %fp,#32767
+0+01a <foo\+(0x|)1a> linkl %fp,#32768
+0+020 <foo\+(0x|)20> linkl %fp,#32769
+0+026 <foo\+(0x|)26> nop
diff --git a/gas/testsuite/gas/m68k/link.s b/gas/testsuite/gas/m68k/link.s
new file mode 100644
index 00000000000..1a321dd3222
--- /dev/null
+++ b/gas/testsuite/gas/m68k/link.s
@@ -0,0 +1,13 @@
+# Test handling of link instruction.
+ .text
+ .globl foo
+foo:
+ link %a6,&0
+ link %a6,&-4
+ link %a6,&-0x7fff
+ link %a6,&-0x8000
+ link %a6,&-0x8001
+ link %a6,&0x7fff
+ link %a6,&0x8000
+ link %a6,&0x8001
+ nop
diff --git a/gas/testsuite/gas/m68k/op68000.d b/gas/testsuite/gas/m68k/op68000.d
new file mode 100644
index 00000000000..568d5a3a6cd
--- /dev/null
+++ b/gas/testsuite/gas/m68k/op68000.d
@@ -0,0 +1,195 @@
+# This should match the stderr output of gas -m68000 on operands.s.
+# We don't bother to match the exact error message, but instead just
+# look for the statements which should fail.
+
+.*operands.s: Assembler messages:
+.*statement `tstl %a0' ignored
+.*statement `tstl %a0@\(8,%d0:w:2\)' ignored
+.*statement `tstl %a0@\(8,%d0:w:4\)' ignored
+.*statement `tstl %a0@\(8,%d0:w:8\)' ignored
+.*statement `tstl %a0@\(8,%d0:l:2\)' ignored
+.*statement `tstl %a0@\(8,%d0:l:4\)' ignored
+.*statement `tstl %a0@\(8,%d0:l:8\)' ignored
+.*statement `tstl %a0@\(%d0:w:2\)' ignored
+.*statement `tstl \(8,%a0,%d0\*2\)' ignored
+.*statement `tstl \(8,%a0,%d0\*4\)' ignored
+.*statement `tstl \(8,%a0,%d0\*8\)' ignored
+.*statement `tstl \(8,%a0,%d0.w\*2\)' ignored
+.*statement `tstl \(8,%a0,%d0.w\*4\)' ignored
+.*statement `tstl \(8,%a0,%d0.w\*8\)' ignored
+.*statement `tstl \(8,%a0,%d0.l\*2\)' ignored
+.*statement `tstl \(8,%a0,%d0.l\*4\)' ignored
+.*statement `tstl \(8,%a0,%d0.l\*8\)' ignored
+.*statement `tstl \(8,%a1.w\*2,%a0\)' ignored
+.*statement `tstl 8\(%a0,%d0.w\*2\)' ignored
+.*statement `tstl 8\(%d0.w\*2,%a0\)' ignored
+.*statement `tstl 8\(%a1.w\*2,%a0\)' ignored
+.*statement `tstl \(%a0,%d0.w\*2\)' ignored
+.*statement `tstl \(%d0.w\*2,%a0\)' ignored
+.*statement `tstl %a0@\(1000,%d0:w:2\)' ignored
+.*statement `tstl @\(1000,%d0:w:2\)' ignored
+.*statement `tstl @\(%d0:w:2\)' ignored
+.*statement `tstl @\(1000\)' ignored
+.*statement `tstl %a0@\(100000\)' ignored
+.*statement `tstl \(1000,%a0,%d0.w\*2\)' ignored
+.*statement `tstl \(1000,%d0,%a0\)' ignored
+.*statement `tstl \(1000,%a1.w\*2,%a0\)' ignored
+.*statement `tstl 1000\(%a0,%d0.w\*2\)' ignored
+.*statement `tstl 1000\(%d0,%a0\)' ignored
+.*statement `tstl \(1000,%d0.w\*2\)' ignored
+.*statement `tstl 1000\(%d0.w\*2\)' ignored
+.*statement `tstl \(%d0.w\*2\)' ignored
+.*statement `tstl \(100000,%a0\)' ignored
+.*statement `tstl 100000\(%a0\)' ignored
+.*statement `tstl %za1@\(1000,%d0:w:2\)' ignored
+.*statement `tstl %za1@\(100000\)' ignored
+.*statement `tstl \(1000,%za1,%d0.w\*2\)' ignored
+.*statement `tstl \(1000,%d0,%za1\)' ignored
+.*statement `tstl \(1000,%a1.w\*2,%za1\)' ignored
+.*statement `tstl 1000\(%za1,%d0.w\*2\)' ignored
+.*statement `tstl 1000\(%d0,%za1\)' ignored
+.*statement `tstl \(100000,%za1\)' ignored
+.*statement `tstl 100000\(%za1\)' ignored
+.*statement `tstl %a0@\(1000,%zd1:w:2\)' ignored
+.*statement `tstl @\(1000,%zd1:w:2\)' ignored
+.*statement `tstl @\(%zd1:w:2\)' ignored
+.*statement `tstl \(1000,%a0,%zd1.w\*2\)' ignored
+.*statement `tstl \(1000,%zd1,%a0\)' ignored
+.*statement `tstl \(1000,%za1.w\*2,%a0\)' ignored
+.*statement `tstl 1000\(%a0,%zd1.w\*2\)' ignored
+.*statement `tstl 1000\(%zd1,%a0\)' ignored
+.*statement `tstl \(1000,%zd1.w\*2\)' ignored
+.*statement `tstl 1000\(%zd1.w\*2\)' ignored
+.*statement `tstl \(%zd1.w\*2\)' ignored
+.*statement `tstl %a0@\(1000\)@\(2000,%d0:w:2\)' ignored
+.*statement `tstl %a0@\(1000\)@\(%d0:w:2\)' ignored
+.*statement `tstl %a0@\(1000\)@\(2000\)' ignored
+.*statement `tstl @\(1000\)@\(2000,%d0:w:2\)' ignored
+.*statement `tstl @\(1000\)@\(%d0:w:2\)' ignored
+.*statement `tstl @\(1000\)@\(2000\)' ignored
+.*statement `tstl %a0@\(0\)@\(2000,%d0:w:2\)' ignored
+.*statement `tstl %a0@\(0\)@\(%d0:w:2\)' ignored
+.*statement `tstl %a0@\(0\)@\(2000\)' ignored
+.*statement `tstl @\(0\)@\(2000,%d0:w:2\)' ignored
+.*statement `tstl @\(0\)@\(%d0:w:2\)' ignored
+.*statement `tstl @\(0\)@\(2000\)' ignored
+.*statement `tstl \(\[1000,%a0\],%d0:w:2,2000\)' ignored
+.*statement `tstl \(\[1000,%a0\],%d0:w:2\)' ignored
+.*statement `tstl \(\[1000,%a0\],2000\)' ignored
+.*statement `tstl \(\[1000\],%d0:w:2,2000\)' ignored
+.*statement `tstl \(\[1000\],%d0:w:2\)' ignored
+.*statement `tstl \(\[1000\],2000\)' ignored
+.*statement `tstl \(\[%a0\],%d0:w:2,2000\)' ignored
+.*statement `tstl \(\[%a0\],%d0:w:2\)' ignored
+.*statement `tstl \(\[%a0\],2000\)' ignored
+.*statement `tstl \(\[0\],%d0:w:2,2000\)' ignored
+.*statement `tstl \(\[0\],%d0:w:2\)' ignored
+.*statement `tstl \(\[0\],2000\)' ignored
+.*statement `tstl %a0@\(1000,%d0:w:2\)@\(2000\)' ignored
+.*statement `tstl %a0@\(1000,%d0:w:2\)@\(0\)' ignored
+.*statement `tstl @\(1000,%d0:w:2\)@\(2000\)' ignored
+.*statement `tstl @\(1000,%d0:w:2\)@\(0\)' ignored
+.*statement `tstl %a0@\(%d0:w:2\)@\(2000\)' ignored
+.*statement `tstl %a0@\(%d0:w:2\)@\(0\)' ignored
+.*statement `tstl @\(%d0:w:2\)@\(2000\)' ignored
+.*statement `tstl @\(%d0:w:2\)@\(0\)' ignored
+.*statement `tstl \(\[1000,%a0,%d0:w:2\],2000\)' ignored
+.*statement `tstl \(\[1000,%d0:w:2,%a0\],2000\)' ignored
+.*statement `tstl \(\[1000,%d0,%a0\],2000\)' ignored
+.*statement `tstl \(\[1000,%a1,%a0\],2000\)' ignored
+.*statement `tstl \(\[1000,%a1:w:2,%a0\],2000\)' ignored
+.*statement `tstl \(\[1000,%a0,%d0:w:2\]\)' ignored
+.*statement `tstl \(\[1000,%d0,%a0\]\)' ignored
+.*statement `tstl \(\[1000,%d0:w:2\],2000\)' ignored
+.*statement `tstl \(\[1000,%d0:w:2\]\)' ignored
+.*statement `tstl \(\[%a0,%d0:w:2\],2000\)' ignored
+.*statement `tstl \(\[%d0,%a0\],2000\)' ignored
+.*statement `tstl \(\[%a0,%d0:w:2\]\)' ignored
+.*statement `tstl \(\[%d0,%a0\]\)' ignored
+.*statement `tstl \(\[%d0:w:2\],2000\)' ignored
+.*statement `tstl \(\[%d0:w:2\]\)' ignored
+.*statement `pea %pc@\(8,%d0:w:2\)' ignored
+.*statement `pea %pc@\(%d0:w:2\)' ignored
+.*statement `pea \(8,%pc,%d0.w\*2\)' ignored
+.*statement `pea 8\(%pc,%d0.w\*2\)' ignored
+.*statement `pea \(%pc,%d0.w\*2\)' ignored
+.*statement `pea %pc@\(1000,%d0:w:2\)' ignored
+.*statement `pea %pc@\(100000\)' ignored
+.*statement `pea \(1000,%pc,%d0.w\*2\)' ignored
+.*statement `pea \(1000,%d0,%pc\)' ignored
+.*statement `pea \(1000,%a1.w\*2,%pc\)' ignored
+.*statement `pea \(1000,%a1,%pc\)' ignored
+.*statement `pea 1000\(%pc,%d0.w\*2\)' ignored
+.*statement `pea 1000\(%d0,%pc\)' ignored
+.*statement `pea 1000\(%a1,%pc\)' ignored
+.*statement `pea \(100000,%pc\)' ignored
+.*statement `pea 100000\(%pc\)' ignored
+.*statement `pea %zpc@\(1000,%d0:w:2\)' ignored
+.*statement `pea %zpc@\(100000\)' ignored
+.*statement `pea \(1000,%zpc,%d0.w\*2\)' ignored
+.*statement `pea \(1000,%d0,%zpc\)' ignored
+.*statement `pea \(1000,%a1.w\*2,%zpc\)' ignored
+.*statement `pea \(1000,%a1,%zpc\)' ignored
+.*statement `pea 1000\(%zpc,%d0.w\*2\)' ignored
+.*statement `pea 1000\(%d0,%zpc\)' ignored
+.*statement `pea 1000\(%a1,%zpc\)' ignored
+.*statement `pea \(100000,%zpc\)' ignored
+.*statement `pea 100000\(%zpc\)' ignored
+.*statement `pea %pc@\(1000\)@\(2000,%d0:w:2\)' ignored
+.*statement `pea %pc@\(1000\)@\(%d0:w:2\)' ignored
+.*statement `pea %pc@\(1000\)@\(2000\)' ignored
+.*statement `pea %pc@\(0\)@\(2000,%d0:w:2\)' ignored
+.*statement `pea %pc@\(0\)@\(%d0:w:2\)' ignored
+.*statement `pea %pc@\(0\)@\(2000\)' ignored
+.*statement `pea \(\[1000,%pc\],%d0:w:2,2000\)' ignored
+.*statement `pea \(\[1000,%pc\],%d0:w:2\)' ignored
+.*statement `pea \(\[1000,%pc\],2000\)' ignored
+.*statement `pea \(\[%pc\],%d0:w:2,2000\)' ignored
+.*statement `pea \(\[%pc\],%d0:w:2\)' ignored
+.*statement `pea \(\[%pc\],2000\)' ignored
+.*statement `pea %zpc@\(1000\)@\(2000,%d0:w:2\)' ignored
+.*statement `pea %zpc@\(1000\)@\(%d0:w:2\)' ignored
+.*statement `pea %zpc@\(1000\)@\(2000\)' ignored
+.*statement `pea %zpc@\(0\)@\(2000,%d0:w:2\)' ignored
+.*statement `pea %zpc@\(0\)@\(%d0:w:2\)' ignored
+.*statement `pea %zpc@\(0\)@\(2000\)' ignored
+.*statement `pea \(\[1000,%zpc\],%d0:w:2,2000\)' ignored
+.*statement `pea \(\[1000,%zpc\],%d0:w:2\)' ignored
+.*statement `pea \(\[1000,%zpc\],2000\)' ignored
+.*statement `pea \(\[%zpc\],%d0:w:2,2000\)' ignored
+.*statement `pea \(\[%zpc\],%d0:w:2\)' ignored
+.*statement `pea \(\[%zpc\],2000\)' ignored
+.*statement `pea %pc@\(1000,%d0:w:2\)@\(2000\)' ignored
+.*statement `pea %pc@\(1000,%d0:w:2\)@\(0\)' ignored
+.*statement `pea %pc@\(%d0:w:2\)@\(2000\)' ignored
+.*statement `pea %pc@\(%d0:w:2\)@\(0\)' ignored
+.*statement `pea \(\[1000,%pc,%d0:w:2\],2000\)' ignored
+.*statement `pea \(\[1000,%d0:w:2,%pc\],2000\)' ignored
+.*statement `pea \(\[1000,%d0,%pc\],2000\)' ignored
+.*statement `pea \(\[1000,%a1,%pc\],2000\)' ignored
+.*statement `pea \(\[1000,%pc,%a1\],2000\)' ignored
+.*statement `pea \(\[1000,%a1:w:2,%pc\],2000\)' ignored
+.*statement `pea \(\[1000,%pc,%d0:w:2\]\)' ignored
+.*statement `pea \(\[1000,%d0,%pc\]\)' ignored
+.*statement `pea \(\[1000,%a1,%pc\]\)' ignored
+.*statement `pea \(\[%pc,%d0:w:2\],2000\)' ignored
+.*statement `pea \(\[%pc,%a0\],2000\)' ignored
+.*statement `pea \(\[%pc,%d0:w:2\]\)' ignored
+.*statement `pea \(\[%d0,%pc\]\)' ignored
+.*statement `pea %zpc@\(1000,%d0:w:2\)@\(2000\)' ignored
+.*statement `pea %zpc@\(1000,%d0:w:2\)@\(0\)' ignored
+.*statement `pea %zpc@\(%d0:w:2\)@\(2000\)' ignored
+.*statement `pea %zpc@\(%d0:w:2\)@\(0\)' ignored
+.*statement `pea \(\[1000,%zpc,%d0:w:2\],2000\)' ignored
+.*statement `pea \(\[1000,%d0:w:2,%zpc\],2000\)' ignored
+.*statement `pea \(\[1000,%d0,%zpc\],2000\)' ignored
+.*statement `pea \(\[1000,%a1,%zpc\],2000\)' ignored
+.*statement `pea \(\[1000,%zpc,%a1\],2000\)' ignored
+.*statement `pea \(\[1000,%a1:w:2,%zpc\],2000\)' ignored
+.*statement `pea \(\[1000,%zpc,%d0:w:2\]\)' ignored
+.*statement `pea \(\[1000,%d0,%zpc\]\)' ignored
+.*statement `pea \(\[1000,%a1,%zpc\]\)' ignored
+.*statement `pea \(\[%zpc,%d0:w:2\],2000\)' ignored
+.*statement `pea \(\[%zpc,%a0\],2000\)' ignored
+.*statement `pea \(\[%zpc,%d0:w:2\]\)' ignored
+.*statement `pea \(\[%d0,%zpc\]\)' ignored
diff --git a/gas/testsuite/gas/m68k/operands.d b/gas/testsuite/gas/m68k/operands.d
new file mode 100644
index 00000000000..5b383c3f970
--- /dev/null
+++ b/gas/testsuite/gas/m68k/operands.d
@@ -0,0 +1,242 @@
+#objdump: -d --prefix-addresses
+#name: operands
+
+# Test handling of MIT and Motorola syntax operands
+# If you change this file, see also op68000.d.
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+000 <foo> tstl %d0
+0+002 <foo\+(0x|)2> tstl %a0
+0+004 <foo\+(0x|)4> tstl %a0@
+0+006 <foo\+(0x|)6> tstl %a0@
+0+008 <foo\+(0x|)8> tstl %a0@\+
+0+00a <foo\+(0x|)a> tstl %a0@\+
+0+00c <foo\+(0x|)c> tstl %a0@-
+0+00e <foo\+(0x|)e> tstl %a0@-
+0+010 <foo\+(0x|)10> tstl %a0@\(8\)
+0+014 <foo\+(0x|)14> tstl %a0@\(8\)
+0+018 <foo\+(0x|)18> tstl %a0@\(8\)
+0+01c <foo\+(0x|)1c> tstl %a0@\(0+008,%d0:l\)
+0+020 <foo\+(0x|)20> tstl %a0@\(0+008,%d0:w\)
+0+024 <foo\+(0x|)24> tstl %a0@\(0+008,%d0:w\)
+0+028 <foo\+(0x|)28> tstl %a0@\(0+008,%d0:w:2\)
+0+02c <foo\+(0x|)2c> tstl %a0@\(0+008,%d0:w:4\)
+0+030 <foo\+(0x|)30> tstl %a0@\(0+008,%d0:w:8\)
+0+034 <foo\+(0x|)34> tstl %a0@\(0+008,%d0:l\)
+0+038 <foo\+(0x|)38> tstl %a0@\(0+008,%d0:l\)
+0+03c <foo\+(0x|)3c> tstl %a0@\(0+008,%d0:l:2\)
+0+040 <foo\+(0x|)40> tstl %a0@\(0+008,%d0:l:4\)
+0+044 <foo\+(0x|)44> tstl %a0@\(0+008,%d0:l:8\)
+0+048 <foo\+(0x|)48> tstl %a0@\(0+000,%d0:w:2\)
+0+04c <foo\+(0x|)4c> tstl %a0@\(0+008,%d0:l\)
+0+050 <foo\+(0x|)50> tstl %a0@\(0+008,%d0:l\)
+0+054 <foo\+(0x|)54> tstl %a0@\(0+008,%d0:l:2\)
+0+058 <foo\+(0x|)58> tstl %a0@\(0+008,%d0:l:4\)
+0+05c <foo\+(0x|)5c> tstl %a0@\(0+008,%d0:l:8\)
+0+060 <foo\+(0x|)60> tstl %a0@\(0+008,%d0:w\)
+0+064 <foo\+(0x|)64> tstl %a0@\(0+008,%d0:w\)
+0+068 <foo\+(0x|)68> tstl %a0@\(0+008,%d0:w:2\)
+0+06c <foo\+(0x|)6c> tstl %a0@\(0+008,%d0:w:4\)
+0+070 <foo\+(0x|)70> tstl %a0@\(0+008,%d0:w:8\)
+0+074 <foo\+(0x|)74> tstl %a0@\(0+008,%d0:l\)
+0+078 <foo\+(0x|)78> tstl %a0@\(0+008,%d0:l\)
+0+07c <foo\+(0x|)7c> tstl %a0@\(0+008,%d0:l:2\)
+0+080 <foo\+(0x|)80> tstl %a0@\(0+008,%d0:l:4\)
+0+084 <foo\+(0x|)84> tstl %a0@\(0+008,%d0:l:8\)
+0+088 <foo\+(0x|)88> tstl %a0@\(0+008,%d0:l\)
+0+08c <foo\+(0x|)8c> tstl %a0@\(0+008,%a1:w:2\)
+0+090 <foo\+(0x|)90> tstl %a1@\(0+008,%a0:l\)
+0+094 <foo\+(0x|)94> tstl %a0@\(0+008,%d0:w:2\)
+0+098 <foo\+(0x|)98> tstl %a0@\(0+008,%d0:w:2\)
+0+09c <foo\+(0x|)9c> tstl %a0@\(0+008,%a1:w:2\)
+0+0a0 <foo\+(0x|)a0> tstl %a0@\(0+000,%d0:w:2\)
+0+0a4 <foo\+(0x|)a4> tstl %a0@\(0+000,%d0:w:2\)
+0+0a8 <foo\+(0x|)a8> tstl %a0@\(0+3e8,%d0:w:2\)
+0+0ae <foo\+(0x|)ae> tstl @\(0+3e8,%d0:w:2\)
+0+0b4 <foo\+(0x|)b4> tstl @\(0+000,%d0:w:2\)
+0+0b8 <foo\+(0x|)b8> tstl @\(0+3e8\)
+0+0be <foo\+(0x|)be> tstl %a0@\(0+186a0\)
+0+0c6 <foo\+(0x|)c6> tstl %a0@\(0+3e8,%d0:w:2\)
+0+0cc <foo\+(0x|)cc> tstl %a0@\(0+3e8,%d0:l\)
+0+0d2 <foo\+(0x|)d2> tstl %a0@\(0+3e8,%a1:w:2\)
+0+0d8 <foo\+(0x|)d8> tstl %a0@\(0+3e8,%d0:w:2\)
+0+0de <foo\+(0x|)de> tstl %a0@\(0+3e8,%d0:l\)
+0+0e4 <foo\+(0x|)e4> tstl @\(0+3e8,%d0:w:2\)
+0+0ea <foo\+(0x|)ea> tstl @\(0+3e8,%d0:w:2\)
+0+0f0 <foo\+(0x|)f0> tstl @\(0+000,%d0:w:2\)
+0+0f4 <foo\+(0x|)f4> tstl %a0@\(0+186a0\)
+0+0fc <foo\+(0x|)fc> tstl %a0@\(0+186a0\)
+0+104 <foo\+(0x|)104> tstl @\(0+3e8,%d0:w:2\)
+0+10a <foo\+(0x|)10a> tstl @\(0+186a0\)
+0+112 <foo\+(0x|)112> tstl @\(0+3e8,%d0:w:2\)
+0+118 <foo\+(0x|)118> tstl @\(0+3e8,%d0:l\)
+0+11e <foo\+(0x|)11e> tstl @\(0+3e8,%a1:w:2\)
+0+124 <foo\+(0x|)124> tstl @\(0+3e8,%d0:w:2\)
+0+12a <foo\+(0x|)12a> tstl @\(0+3e8,%d0:l\)
+0+130 <foo\+(0x|)130> tstl @\(0+186a0\)
+0+138 <foo\+(0x|)138> tstl @\(0+186a0\)
+0+140 <foo\+(0x|)140> tstl %a0@\(0+3e8\)
+0+146 <foo\+(0x|)146> tstl @\(0+3e8\)
+0+14c <foo\+(0x|)14c> tstl @\(0+000\)
+0+150 <foo\+(0x|)150> tstl %a0@\(0+3e8\)
+0+156 <foo\+(0x|)156> tstl %a0@\(0+3e8\)
+0+15c <foo\+(0x|)15c> tstl %a0@\(0+3e8\)
+0+162 <foo\+(0x|)162> tstl %a0@\(0+3e8\)
+0+168 <foo\+(0x|)168> tstl %a0@\(0+3e8\)
+0+16e <foo\+(0x|)16e> tstl @\(0+3e8\)
+0+174 <foo\+(0x|)174> tstl @\(0+3e8\)
+0+17a <foo\+(0x|)17a> tstl @\(0+000\)
+0+17e <foo\+(0x|)17e> tstl %a0@\(0+3e8\)@\(0+7d0,%d0:w:2\)
+0+186 <foo\+(0x|)186> tstl %a0@\(0+3e8\)@\(0+000,%d0:w:2\)
+0+18c <foo\+(0x|)18c> tstl %a0@\(0+3e8\)@\(0+7d0\)
+0+194 <foo\+(0x|)194> tstl @\(0+3e8\)@\(0+7d0,%d0:w:2\)
+0+19c <foo\+(0x|)19c> tstl @\(0+3e8\)@\(0+000,%d0:w:2\)
+0+1a2 <foo\+(0x|)1a2> tstl @\(0+3e8\)@\(0+7d0\)
+0+1aa <foo\+(0x|)1aa> tstl %a0@\(0+000\)@\(0+7d0,%d0:w:2\)
+0+1b0 <foo\+(0x|)1b0> tstl %a0@\(0+000\)@\(0+000,%d0:w:2\)
+0+1b4 <foo\+(0x|)1b4> tstl %a0@\(0+000\)@\(0+7d0\)
+0+1ba <foo\+(0x|)1ba> tstl @\(0+000\)@\(0+7d0,%d0:w:2\)
+0+1c0 <foo\+(0x|)1c0> tstl @\(0+000\)@\(0+000,%d0:w:2\)
+0+1c4 <foo\+(0x|)1c4> tstl @\(0+000\)@\(0+7d0\)
+0+1ca <foo\+(0x|)1ca> tstl %a0@\(0+3e8\)@\(0+7d0,%d0:w:2\)
+0+1d2 <foo\+(0x|)1d2> tstl %a0@\(0+3e8\)@\(0+000,%d0:w:2\)
+0+1d8 <foo\+(0x|)1d8> tstl %a0@\(0+3e8\)@\(0+7d0\)
+0+1e0 <foo\+(0x|)1e0> tstl @\(0+3e8\)@\(0+7d0,%d0:w:2\)
+0+1e8 <foo\+(0x|)1e8> tstl @\(0+3e8\)@\(0+000,%d0:w:2\)
+0+1ee <foo\+(0x|)1ee> tstl @\(0+3e8\)@\(0+7d0\)
+0+1f6 <foo\+(0x|)1f6> tstl %a0@\(0+000\)@\(0+7d0,%d0:w:2\)
+0+1fc <foo\+(0x|)1fc> tstl %a0@\(0+000\)@\(0+000,%d0:w:2\)
+0+200 <foo\+(0x|)200> tstl %a0@\(0+000\)@\(0+7d0\)
+0+206 <foo\+(0x|)206> tstl @\(0+000\)@\(0+7d0,%d0:w:2\)
+0+20c <foo\+(0x|)20c> tstl @\(0+000\)@\(0+000,%d0:w:2\)
+0+210 <foo\+(0x|)210> tstl @\(0+000\)@\(0+7d0\)
+0+216 <foo\+(0x|)216> tstl %a0@\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+21e <foo\+(0x|)21e> tstl %a0@\(0+3e8,%d0:w:2\)@\(0+000\)
+0+224 <foo\+(0x|)224> tstl @\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+22c <foo\+(0x|)22c> tstl @\(0+3e8,%d0:w:2\)@\(0+000\)
+0+232 <foo\+(0x|)232> tstl %a0@\(0+000,%d0:w:2\)@\(0+7d0\)
+0+238 <foo\+(0x|)238> tstl %a0@\(0+000,%d0:w:2\)@\(0+000\)
+0+23c <foo\+(0x|)23c> tstl @\(0+000,%d0:w:2\)@\(0+7d0\)
+0+242 <foo\+(0x|)242> tstl @\(0+000,%d0:w:2\)@\(0+000\)
+0+246 <foo\+(0x|)246> tstl %a0@\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+24e <foo\+(0x|)24e> tstl %a0@\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+256 <foo\+(0x|)256> tstl %a0@\(0+3e8,%d0:l\)@\(0+7d0\)
+0+25e <foo\+(0x|)25e> tstl %a1@\(0+3e8,%a0:l\)@\(0+7d0\)
+0+266 <foo\+(0x|)266> tstl %a0@\(0+3e8,%a1:w:2\)@\(0+7d0\)
+0+26e <foo\+(0x|)26e> tstl %a0@\(0+3e8,%d0:w:2\)@\(0+000\)
+0+274 <foo\+(0x|)274> tstl %a0@\(0+3e8,%d0:l\)@\(0+000\)
+0+27a <foo\+(0x|)27a> tstl @\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+282 <foo\+(0x|)282> tstl @\(0+3e8,%d0:w:2\)@\(0+000\)
+0+288 <foo\+(0x|)288> tstl %a0@\(0+000,%d0:w:2\)@\(0+7d0\)
+0+28e <foo\+(0x|)28e> tstl %a0@\(0+000,%d0:l\)@\(0+7d0\)
+0+294 <foo\+(0x|)294> tstl %a0@\(0+000,%d0:w:2\)@\(0+000\)
+0+298 <foo\+(0x|)298> tstl %a0@\(0+000,%d0:l\)@\(0+000\)
+0+29c <foo\+(0x|)29c> tstl @\(0+000,%d0:w:2\)@\(0+7d0\)
+0+2a2 <foo\+(0x|)2a2> tstl @\(0+000,%d0:w:2\)@\(0+000\)
+0+2a6 <foo\+(0x|)2a6> pea %pc@\(0+2b0 <foo\+(0x|)2b0>\)
+0+2aa <foo\+(0x|)2aa> pea %pc@\(0+2b4 <foo\+(0x|)2b4>\)
+0+2ae <foo\+(0x|)2ae> pea %pc@\(0+2b8 <foo\+(0x|)2b8>\)
+0+2b2 <foo\+(0x|)2b2> pea %pc@\(0+000 <foo>\)
+0+2b6 <foo\+(0x|)2b6> pea %pc@\(0+2c0 <foo\+(0x|)2c0>,%d0:w:2\)
+0+2ba <foo\+(0x|)2ba> pea %pc@\(0+2bc <foo\+(0x|)2bc>,%d0:w:2\)
+0+2be <foo\+(0x|)2be> pea %pc@\(0+2c8 <foo\+(0x|)2c8>,%d0:w:2\)
+0+2c2 <foo\+(0x|)2c2> pea %pc@\(0+2cc <foo\+(0x|)2cc>,%d0:l\)
+0+2c6 <foo\+(0x|)2c6> pea %pc@\(0+2d0 <foo\+(0x|)2d0>,%a0:l\)
+0+2ca <foo\+(0x|)2ca> pea %pc@\(0+2d4 <foo\+(0x|)2d4>,%d0:w:2\)
+0+2ce <foo\+(0x|)2ce> pea %pc@\(0+2d8 <foo\+(0x|)2d8>,%d0:l\)
+0+2d2 <foo\+(0x|)2d2> pea %pc@\(0+2dc <foo\+(0x|)2dc>,%a0:l\)
+0+2d6 <foo\+(0x|)2d6> pea %pc@\(0+2d8 <foo\+(0x|)2d8>,%d0:w:2\)
+0+2da <foo\+(0x|)2da> pea %pc@\(0+2dc <foo\+(0x|)2dc>,%d0:l\)
+0+2de <foo\+(0x|)2de> pea %pc@\(0+2e0 <foo\+(0x|)2e0>,%a0:l\)
+0+2e2 <foo\+(0x|)2e2> pea %pc@\(0+6cc <.*>,%d0:w:2\)
+0+2e8 <foo\+(0x|)2e8> pea %pc@\(0+1898a <.*>\)
+0+2f0 <foo\+(0x|)2f0> pea %pc@\(0+6da <.*>,%d0:w:2\)
+0+2f6 <foo\+(0x|)2f6> pea %pc@\(0+6e0 <.*>,%d0:l\)
+0+2fc <foo\+(0x|)2fc> pea %pc@\(0+6e6 <.*>,%a1:w:2\)
+0+302 <foo\+(0x|)302> pea %pc@\(0+6ec <.*>,%a1:l\)
+0+308 <foo\+(0x|)308> pea %pc@\(0+6f2 <.*>,%d0:w:2\)
+0+30e <foo\+(0x|)30e> pea %pc@\(0+6f8 <.*>,%d0:l\)
+0+314 <foo\+(0x|)314> pea %pc@\(0+6fe <.*>,%a1:l\)
+0+31a <foo\+(0x|)31a> pea %pc@\(0+189bc <.*>\)
+0+322 <foo\+(0x|)322> pea %pc@\(0+189c4 <.*>\)
+0+32a <foo\+(0x|)32a> pea %zpc@\(0+3e8,%d0:w:2\)
+0+330 <foo\+(0x|)330> pea %zpc@\(0+186a0\)
+0+338 <foo\+(0x|)338> pea %zpc@\(0+3e8,%d0:w:2\)
+0+33e <foo\+(0x|)33e> pea %zpc@\(0+3e8,%d0:l\)
+0+344 <foo\+(0x|)344> pea %zpc@\(0+3e8,%a1:w:2\)
+0+34a <foo\+(0x|)34a> pea %zpc@\(0+3e8,%a1:l\)
+0+350 <foo\+(0x|)350> pea %zpc@\(0+3e8,%d0:w:2\)
+0+356 <foo\+(0x|)356> pea %zpc@\(0+3e8,%d0:l\)
+0+35c <foo\+(0x|)35c> pea %zpc@\(0+3e8,%a1:l\)
+0+362 <foo\+(0x|)362> pea %zpc@\(0+186a0\)
+0+36a <foo\+(0x|)36a> pea %zpc@\(0+186a0\)
+0+372 <foo\+(0x|)372> pea %pc@\(0+75c <.*>\)@\(0+7d0,%d0:w:2\)
+0+37a <foo\+(0x|)37a> pea %pc@\(0+764 <.*>\)@\(0+000,%d0:w:2\)
+0+380 <foo\+(0x|)380> pea %pc@\(0+76a <.*>\)@\(0+7d0\)
+0+388 <foo\+(0x|)388> pea %pc@\(0+38a <foo\+(0x|)38a>\)@\(0+7d0,%d0:w:2\)
+0+38e <foo\+(0x|)38e> pea %pc@\(0+390 <foo\+(0x|)390>\)@\(0+000,%d0:w:2\)
+0+392 <foo\+(0x|)392> pea %pc@\(0+394 <foo\+(0x|)394>\)@\(0+7d0\)
+0+398 <foo\+(0x|)398> pea %pc@\(0+782 <.*>\)@\(0+7d0,%d0:w:2\)
+0+3a0 <foo\+(0x|)3a0> pea %pc@\(0+78a <.*>\)@\(0+000,%d0:w:2\)
+0+3a6 <foo\+(0x|)3a6> pea %pc@\(0+790 <.*>\)@\(0+7d0\)
+0+3ae <foo\+(0x|)3ae> pea %pc@\(0+3b0 <foo\+(0x|)3b0>\)@\(0+7d0,%d0:w:2\)
+0+3b4 <foo\+(0x|)3b4> pea %pc@\(0+3b6 <foo\+(0x|)3b6>\)@\(0+000,%d0:w:2\)
+0+3b8 <foo\+(0x|)3b8> pea %pc@\(0+3ba <foo\+(0x|)3ba>\)@\(0+7d0\)
+0+3be <foo\+(0x|)3be> pea %zpc@\(0+3e8\)@\(0+7d0,%d0:w:2\)
+0+3c6 <foo\+(0x|)3c6> pea %zpc@\(0+3e8\)@\(0+000,%d0:w:2\)
+0+3cc <foo\+(0x|)3cc> pea %zpc@\(0+3e8\)@\(0+7d0\)
+0+3d4 <foo\+(0x|)3d4> pea %zpc@\(0+000\)@\(0+7d0,%d0:w:2\)
+0+3da <foo\+(0x|)3da> pea %zpc@\(0+000\)@\(0+000,%d0:w:2\)
+0+3de <foo\+(0x|)3de> pea %zpc@\(0+000\)@\(0+7d0\)
+0+3e4 <foo\+(0x|)3e4> pea %zpc@\(0+3e8\)@\(0+7d0,%d0:w:2\)
+0+3ec <foo\+(0x|)3ec> pea %zpc@\(0+3e8\)@\(0+000,%d0:w:2\)
+0+3f2 <foo\+(0x|)3f2> pea %zpc@\(0+3e8\)@\(0+7d0\)
+0+3fa <foo\+(0x|)3fa> pea %zpc@\(0+000\)@\(0+7d0,%d0:w:2\)
+0+400 <foo\+(0x|)400> pea %zpc@\(0+000\)@\(0+000,%d0:w:2\)
+0+404 <foo\+(0x|)404> pea %zpc@\(0+000\)@\(0+7d0\)
+0+40a <foo\+(0x|)40a> pea %pc@\(0+7f4 <.*>,%d0:w:2\)@\(0+7d0\)
+0+412 <foo\+(0x|)412> pea %pc@\(0+7fc <.*>,%d0:w:2\)@\(0+000\)
+0+418 <foo\+(0x|)418> pea %pc@\(0+41a <foo\+(0x|)41a>,%d0:w:2\)@\(0+7d0\)
+0+41e <foo\+(0x|)41e> pea %pc@\(0+420 <foo\+(0x|)420>,%d0:w:2\)@\(0+000\)
+0+422 <foo\+(0x|)422> pea %pc@\(0+80c <.*>,%d0:w:2\)@\(0+7d0\)
+0+42a <foo\+(0x|)42a> pea %pc@\(0+814 <.*>,%d0:w:2\)@\(0+7d0\)
+0+432 <foo\+(0x|)432> pea %pc@\(0+81c <.*>,%d0:l\)@\(0+7d0\)
+0+43a <foo\+(0x|)43a> pea %pc@\(0+824 <.*>,%a1:l\)@\(0+7d0\)
+0+442 <foo\+(0x|)442> pea %pc@\(0+82c <.*>,%a1:l\)@\(0+7d0\)
+0+44a <foo\+(0x|)44a> pea %pc@\(0+834 <.*>,%a1:w:2\)@\(0+7d0\)
+0+452 <foo\+(0x|)452> pea %pc@\(0+83c <.*>,%d0:w:2\)@\(0+000\)
+0+458 <foo\+(0x|)458> pea %pc@\(0+842 <.*>,%d0:l\)@\(0+000\)
+0+45e <foo\+(0x|)45e> pea %pc@\(0+848 <.*>,%a1:l\)@\(0+000\)
+0+464 <foo\+(0x|)464> pea %pc@\(0+466 <foo\+(0x|)466>,%d0:w:2\)@\(0+7d0\)
+0+46a <foo\+(0x|)46a> pea %pc@\(0+46c <foo\+(0x|)46c>,%a0:l\)@\(0+7d0\)
+0+470 <foo\+(0x|)470> pea %pc@\(0+472 <foo\+(0x|)472>,%d0:w:2\)@\(0+000\)
+0+474 <foo\+(0x|)474> pea %pc@\(0+476 <foo\+(0x|)476>,%d0:l\)@\(0+000\)
+0+478 <foo\+(0x|)478> pea %zpc@\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+480 <foo\+(0x|)480> pea %zpc@\(0+3e8,%d0:w:2\)@\(0+000\)
+0+486 <foo\+(0x|)486> pea %zpc@\(0+000,%d0:w:2\)@\(0+7d0\)
+0+48c <foo\+(0x|)48c> pea %zpc@\(0+000,%d0:w:2\)@\(0+000\)
+0+490 <foo\+(0x|)490> pea %zpc@\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+498 <foo\+(0x|)498> pea %zpc@\(0+3e8,%d0:w:2\)@\(0+7d0\)
+0+4a0 <foo\+(0x|)4a0> pea %zpc@\(0+3e8,%d0:l\)@\(0+7d0\)
+0+4a8 <foo\+(0x|)4a8> pea %zpc@\(0+3e8,%a1:l\)@\(0+7d0\)
+0+4b0 <foo\+(0x|)4b0> pea %zpc@\(0+3e8,%a1:l\)@\(0+7d0\)
+0+4b8 <foo\+(0x|)4b8> pea %zpc@\(0+3e8,%a1:w:2\)@\(0+7d0\)
+0+4c0 <foo\+(0x|)4c0> pea %zpc@\(0+3e8,%d0:w:2\)@\(0+000\)
+0+4c6 <foo\+(0x|)4c6> pea %zpc@\(0+3e8,%d0:l\)@\(0+000\)
+0+4cc <foo\+(0x|)4cc> pea %zpc@\(0+3e8,%a1:l\)@\(0+000\)
+0+4d2 <foo\+(0x|)4d2> pea %zpc@\(0+000,%d0:w:2\)@\(0+7d0\)
+0+4d8 <foo\+(0x|)4d8> pea %zpc@\(0+000,%a0:l\)@\(0+7d0\)
+0+4de <foo\+(0x|)4de> pea %zpc@\(0+000,%d0:w:2\)@\(0+000\)
+0+4e2 <foo\+(0x|)4e2> pea %zpc@\(0+000,%d0:l\)@\(0+000\)
+0+4e6 <foo\+(0x|)4e6> tstl 0+004 <foo\+(0x|)4>
+0+4ea <foo\+(0x|)4ea> tstl 0+004 <foo\+(0x|)4>
+0+4ee <foo\+(0x|)4ee> tstl 0+004 <foo\+(0x|)4>
+0+4f2 <foo\+(0x|)4f2> tstl 0+186a0 <.*>
+0+4f8 <foo\+(0x|)4f8> tstl 0+008 <foo\+(0x|)8>
+0+4fe <foo\+(0x|)4fe> tstl 0+008 <foo\+(0x|)8>
+0+504 <foo\+(0x|)504> addib #1,%d0
+0+508 <foo\+(0x|)508> addiw #1,%d0
+0+50c <foo\+(0x|)50c> addil #1,%d0
+0+512 <foo\+(0x|)512> addqb #1,%d0
diff --git a/gas/testsuite/gas/m68k/operands.s b/gas/testsuite/gas/m68k/operands.s
new file mode 100644
index 00000000000..b09f56fee12
--- /dev/null
+++ b/gas/testsuite/gas/m68k/operands.s
@@ -0,0 +1,272 @@
+# Test handling of MIT and Motorola syntax operands
+# If you change this file, see also op68000.d.
+ .text
+foo:
+ | Data register direct
+ tstl %d0
+
+ | Address register direct
+ tstl %a0
+
+ | Address register indirect
+ tstl %a0@
+ tstl (%a0)
+
+ | Address register indirect with postincrement
+ tstl %a0@+
+ tstl (%a0)+
+
+ | Address register indirect with predecrement
+ tstl %a0@-
+ tstl -(%a0)
+
+ | Address register indirect with displacement
+ tstl %a0@(8)
+ tstl (8,%a0)
+ tstl 8(%a0)
+
+ | Address register indirect with index (8-bit displacement)
+ tstl %a0@(8,%d0)
+ tstl %a0@(8,%d0:w)
+ tstl %a0@(8,%d0:w:1)
+ tstl %a0@(8,%d0:w:2)
+ tstl %a0@(8,%d0:w:4)
+ tstl %a0@(8,%d0:w:8)
+ tstl %a0@(8,%d0:l)
+ tstl %a0@(8,%d0:l:1)
+ tstl %a0@(8,%d0:l:2)
+ tstl %a0@(8,%d0:l:4)
+ tstl %a0@(8,%d0:l:8)
+ tstl %a0@(%d0:w:2)
+ tstl (8,%a0,%d0)
+ tstl (8,%a0,%d0*1)
+ tstl (8,%a0,%d0*2)
+ tstl (8,%a0,%d0*4)
+ tstl (8,%a0,%d0*8)
+ tstl (8,%a0,%d0.w)
+ tstl (8,%a0,%d0.w*1)
+ tstl (8,%a0,%d0.w*2)
+ tstl (8,%a0,%d0.w*4)
+ tstl (8,%a0,%d0.w*8)
+ tstl (8,%a0,%d0.l)
+ tstl (8,%a0,%d0.l*1)
+ tstl (8,%a0,%d0.l*2)
+ tstl (8,%a0,%d0.l*4)
+ tstl (8,%a0,%d0.l*8)
+ tstl (8,%d0,%a0)
+ tstl (8,%a1.w*2,%a0)
+ tstl (8,%a1,%a0)
+ tstl 8(%a0,%d0.w*2)
+ tstl 8(%d0.w*2,%a0)
+ tstl 8(%a1.w*2,%a0)
+ tstl (%a0,%d0.w*2)
+ tstl (%d0.w*2,%a0)
+
+ | Address register indirect with index (base displacement)
+ tstl %a0@(1000,%d0:w:2)
+ tstl @(1000,%d0:w:2)
+ tstl @(%d0:w:2)
+ tstl @(1000)
+ tstl %a0@(100000)
+ tstl (1000,%a0,%d0.w*2)
+ tstl (1000,%d0,%a0)
+ tstl (1000,%a1.w*2,%a0)
+ tstl 1000(%a0,%d0.w*2)
+ tstl 1000(%d0,%a0)
+ tstl (1000,%d0.w*2)
+ tstl 1000(%d0.w*2)
+ tstl (%d0.w*2)
+ tstl (100000,%a0)
+ tstl 100000(%a0)
+ tstl %za1@(1000,%d0:w:2)
+ tstl %za1@(100000)
+ tstl (1000,%za1,%d0.w*2)
+ tstl (1000,%d0,%za1)
+ tstl (1000,%a1.w*2,%za1)
+ tstl 1000(%za1,%d0.w*2)
+ tstl 1000(%d0,%za1)
+ tstl (100000,%za1)
+ tstl 100000(%za1)
+ tstl %a0@(1000,%zd1:w:2)
+ tstl @(1000,%zd1:w:2)
+ tstl @(%zd1:w:2)
+ tstl (1000,%a0,%zd1.w*2)
+ tstl (1000,%zd1,%a0)
+ tstl (1000,%za1.w*2,%a0)
+ tstl 1000(%a0,%zd1.w*2)
+ tstl 1000(%zd1,%a0)
+ tstl (1000,%zd1.w*2)
+ tstl 1000(%zd1.w*2)
+ tstl (%zd1.w*2)
+
+ | Memory indirect postindexed
+ tstl %a0@(1000)@(2000,%d0:w:2)
+ tstl %a0@(1000)@(%d0:w:2)
+ tstl %a0@(1000)@(2000)
+ tstl @(1000)@(2000,%d0:w:2)
+ tstl @(1000)@(%d0:w:2)
+ tstl @(1000)@(2000)
+ tstl %a0@(0)@(2000,%d0:w:2)
+ tstl %a0@(0)@(%d0:w:2)
+ tstl %a0@(0)@(2000)
+ tstl @(0)@(2000,%d0:w:2)
+ tstl @(0)@(%d0:w:2)
+ tstl @(0)@(2000)
+ tstl ([1000,%a0],%d0:w:2,2000)
+ tstl ([1000,%a0],%d0:w:2)
+ tstl ([1000,%a0],2000)
+ tstl ([1000],%d0:w:2,2000)
+ tstl ([1000],%d0:w:2)
+ tstl ([1000],2000)
+ tstl ([%a0],%d0:w:2,2000)
+ tstl ([%a0],%d0:w:2)
+ tstl ([%a0],2000)
+ tstl ([0],%d0:w:2,2000)
+ tstl ([0],%d0:w:2)
+ tstl ([0],2000)
+
+ | Memory indirect preindexed
+ tstl %a0@(1000,%d0:w:2)@(2000)
+ tstl %a0@(1000,%d0:w:2)@(0)
+ tstl @(1000,%d0:w:2)@(2000)
+ tstl @(1000,%d0:w:2)@(0)
+ tstl %a0@(%d0:w:2)@(2000)
+ tstl %a0@(%d0:w:2)@(0)
+ tstl @(%d0:w:2)@(2000)
+ tstl @(%d0:w:2)@(0)
+ tstl ([1000,%a0,%d0:w:2],2000)
+ tstl ([1000,%d0:w:2,%a0],2000)
+ tstl ([1000,%d0,%a0],2000)
+ tstl ([1000,%a1,%a0],2000)
+ tstl ([1000,%a1:w:2,%a0],2000)
+ tstl ([1000,%a0,%d0:w:2])
+ tstl ([1000,%d0,%a0])
+ tstl ([1000,%d0:w:2],2000)
+ tstl ([1000,%d0:w:2])
+ tstl ([%a0,%d0:w:2],2000)
+ tstl ([%d0,%a0],2000)
+ tstl ([%a0,%d0:w:2])
+ tstl ([%d0,%a0])
+ tstl ([%d0:w:2],2000)
+ tstl ([%d0:w:2])
+
+ | Program counter indirect with displacement
+ pea %pc@(8)
+ pea (8,%pc)
+ pea 8(%pc)
+ pea foo
+
+ | Program counter indirect with index (8-bit displacement)
+ pea %pc@(8,%d0:w:2)
+ pea %pc@(%d0:w:2)
+ pea (8,%pc,%d0.w*2)
+ pea (8,%d0,%pc)
+ pea (8,%a0,%pc)
+ pea 8(%pc,%d0.w*2)
+ pea 8(%d0,%pc)
+ pea 8(%a0,%pc)
+ pea (%pc,%d0.w*2)
+ pea (%d0,%pc)
+ pea (%a0,%pc)
+
+ | Program counter indirect with index (base displacement)
+ pea %pc@(1000,%d0:w:2)
+ pea %pc@(100000)
+ pea (1000,%pc,%d0.w*2)
+ pea (1000,%d0,%pc)
+ pea (1000,%a1.w*2,%pc)
+ pea (1000,%a1,%pc)
+ pea 1000(%pc,%d0.w*2)
+ pea 1000(%d0,%pc)
+ pea 1000(%a1,%pc)
+ pea (100000,%pc)
+ pea 100000(%pc)
+ pea %zpc@(1000,%d0:w:2)
+ pea %zpc@(100000)
+ pea (1000,%zpc,%d0.w*2)
+ pea (1000,%d0,%zpc)
+ pea (1000,%a1.w*2,%zpc)
+ pea (1000,%a1,%zpc)
+ pea 1000(%zpc,%d0.w*2)
+ pea 1000(%d0,%zpc)
+ pea 1000(%a1,%zpc)
+ pea (100000,%zpc)
+ pea 100000(%zpc)
+
+ | Program counter memory indirect postindexed
+ pea %pc@(1000)@(2000,%d0:w:2)
+ pea %pc@(1000)@(%d0:w:2)
+ pea %pc@(1000)@(2000)
+ pea %pc@(0)@(2000,%d0:w:2)
+ pea %pc@(0)@(%d0:w:2)
+ pea %pc@(0)@(2000)
+ pea ([1000,%pc],%d0:w:2,2000)
+ pea ([1000,%pc],%d0:w:2)
+ pea ([1000,%pc],2000)
+ pea ([%pc],%d0:w:2,2000)
+ pea ([%pc],%d0:w:2)
+ pea ([%pc],2000)
+ pea %zpc@(1000)@(2000,%d0:w:2)
+ pea %zpc@(1000)@(%d0:w:2)
+ pea %zpc@(1000)@(2000)
+ pea %zpc@(0)@(2000,%d0:w:2)
+ pea %zpc@(0)@(%d0:w:2)
+ pea %zpc@(0)@(2000)
+ pea ([1000,%zpc],%d0:w:2,2000)
+ pea ([1000,%zpc],%d0:w:2)
+ pea ([1000,%zpc],2000)
+ pea ([%zpc],%d0:w:2,2000)
+ pea ([%zpc],%d0:w:2)
+ pea ([%zpc],2000)
+
+ | Program counter memory indirect preindexed
+ pea %pc@(1000,%d0:w:2)@(2000)
+ pea %pc@(1000,%d0:w:2)@(0)
+ pea %pc@(%d0:w:2)@(2000)
+ pea %pc@(%d0:w:2)@(0)
+ pea ([1000,%pc,%d0:w:2],2000)
+ pea ([1000,%d0:w:2,%pc],2000)
+ pea ([1000,%d0,%pc],2000)
+ pea ([1000,%a1,%pc],2000)
+ pea ([1000,%pc,%a1],2000)
+ pea ([1000,%a1:w:2,%pc],2000)
+ pea ([1000,%pc,%d0:w:2])
+ pea ([1000,%d0,%pc])
+ pea ([1000,%a1,%pc])
+ pea ([%pc,%d0:w:2],2000)
+ pea ([%pc,%a0],2000)
+ pea ([%pc,%d0:w:2])
+ pea ([%d0,%pc])
+ pea %zpc@(1000,%d0:w:2)@(2000)
+ pea %zpc@(1000,%d0:w:2)@(0)
+ pea %zpc@(%d0:w:2)@(2000)
+ pea %zpc@(%d0:w:2)@(0)
+ pea ([1000,%zpc,%d0:w:2],2000)
+ pea ([1000,%d0:w:2,%zpc],2000)
+ pea ([1000,%d0,%zpc],2000)
+ pea ([1000,%a1,%zpc],2000)
+ pea ([1000,%zpc,%a1],2000)
+ pea ([1000,%a1:w:2,%zpc],2000)
+ pea ([1000,%zpc,%d0:w:2])
+ pea ([1000,%d0,%zpc])
+ pea ([1000,%a1,%zpc])
+ pea ([%zpc,%d0:w:2],2000)
+ pea ([%zpc,%a0],2000)
+ pea ([%zpc,%d0:w:2])
+ pea ([%d0,%zpc])
+
+ | Absolute short
+ tstl 4
+ tstl 4.w
+ tstl (4).w
+
+ | Absolute long
+ tstl 100000
+ tstl 8.l
+ tstl (8).l
+
+ | Immediate
+ addib &1,%d0
+ addiw &1,%d0
+ addil &1,%d0
+ addqb &1,%d0
diff --git a/gas/testsuite/gas/m68k/p2410.s b/gas/testsuite/gas/m68k/p2410.s
new file mode 100644
index 00000000000..4f0337a980e
--- /dev/null
+++ b/gas/testsuite/gas/m68k/p2410.s
@@ -0,0 +1,15 @@
+.text
+start: nop
+ nop
+ nop
+ bras label1
+ bras label2
+.globl label1
+label1: nop
+ .space 0xa0
+ nop
+ nop
+.globl label2
+label2: bras label1
+ bras label2
+ nop
diff --git a/gas/testsuite/gas/m68k/p2663.s b/gas/testsuite/gas/m68k/p2663.s
new file mode 100644
index 00000000000..9f3650fb8aa
--- /dev/null
+++ b/gas/testsuite/gas/m68k/p2663.s
@@ -0,0 +1,16 @@
+|
+| This code generates an incorrect pc relative offset
+|
+bug: movel #4,%d7
+ jsr table(%pc,%d7.w) | wrong
+ jsr %pc@(table-.-2:b,%d7:w) | correct but cryptic
+ nop
+ nop
+table:
+ bra junk
+ bra junk
+ bra junk
+
+junk:
+ nop
+ rts
diff --git a/gas/testsuite/gas/m68k/pcrel.d b/gas/testsuite/gas/m68k/pcrel.d
new file mode 100644
index 00000000000..b49835822b3
--- /dev/null
+++ b/gas/testsuite/gas/m68k/pcrel.d
@@ -0,0 +1,88 @@
+#name: pcrel
+#objdump: -drs -j .text --prefix-addresses
+
+.*: file format .*
+
+Contents of section .text:
+ 0000 4e714e71 4cfa0300 fffa4cfa 0300fff4 NqNqL.....L.....
+ 0010 4cfb0300 08ee41fa ffea41fa ffe641fa L.....A...A...A.
+ 0020 ff6241fb 08de41fb 08da41fb 08d641fb .bA...A...A...A.
+ 0030 0920ffd2 41fb0920 ffcc41fb 0930ffff . ..A.. ..A..0..
+ 0040 ffc641fb 0930ffff ffbe4e71 61ff0000 ..A..0....Nqa...
+ 0050 00586100 0052614e 614c4e71 41f90000 .Xa..RaNaLNqA...
+ 0060 00(a6|00)41fa 004241fa 00be41fb 083a41fb ..A..BA...A..:A.
+ 0070 083641fb 083241fb 0920002e 41fb0920 .6A..2A.. ..A..
+ 0080 002841fb 09300000 002241fb 09300000 .\(A..0..."A..0..
+ 0090 001a41fb 09300000 001241fb 0920000a ..A..0....A.. ..
+ 00a0 41fb0804 4e714e71 4e7141fb 088041fb A...NqNqNqA...A.
+ 00b0 0920ff7f 41fb0920 800041fb 0930ffff . ..A.. ..A..0..
+ 00c0 7fff4e71 41fb087f 41fb0920 008041fb ..NqA...A.. ..A.
+ 00d0 09207fff 41fb0930 00008000 4e7141fa . ..A..0....NqA.
+ 00e0 800041fb 0170ffff 7fff4e71 41fa7fff ..A..p....NqA...
+ 00f0 41fb0170 00008000 4e7141fb 0170(ffff|0000) A..p....NqA..p..
+ 0100 (ff04|0000)41fb 0930(ffff|0000) (fefc|0000)4e71 41f90000 ..A..0....NqA...
+ 0110 0000............................... ................
+Disassembly of section \.text:
+0+0000 <.*> nop
+0+0002 <lbl_b> nop
+0+0004 <lbl_b\+(0x|)2> moveml %pc@\(0+0002 <lbl_b>\),%a0-%a1
+0+000a <lbl_b\+(0x|)8> moveml %pc@\(0+0002 <lbl_b>\),%a0-%a1
+0+0010 <lbl_b\+(0x|)e> moveml %pc@\(0+02 <lbl_b>,%d0:l\),%a0-%a1
+0+0016 <lbl_b\+(0x|)14> lea %pc@\(0+0002 <lbl_b>\),%a0
+0+001a <lbl_b\+(0x|)18> lea %pc@\(0+0002 <lbl_b>\),%a0
+0+001e <lbl_b\+(0x|)1c> lea %pc@\(f+ff82 <.*>\),%a0
+0+0022 <lbl_b\+(0x|)20> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+0026 <lbl_b\+(0x|)24> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+002a <lbl_b\+(0x|)28> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+002e <lbl_b\+(0x|)2c> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+0034 <lbl_b\+(0x|)32> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+003a <lbl_b\+(0x|)38> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+0042 <lbl_b\+(0x|)40> lea %pc@\(0+02 <lbl_b>,%d0:l\),%a0
+0+004a <lbl_b\+(0x|)48> nop
+0+004c <lbl_b\+(0x|)4a> bsrl 0+00a6 <lbl_a>
+0+0052 <lbl_b\+(0x|)50> bsrw 0+00a6 <lbl_a>
+0+0056 <lbl_b\+(0x|)54> bsrs 0+00a6 <lbl_a>
+0+0058 <lbl_b\+(0x|)56> bsrs 0+00a6 <lbl_a>
+0+005a <lbl_b\+(0x|)58> nop
+0+005c <lbl_b\+(0x|)5a> lea (0+00a6 <lbl_a>|0+0 <.*>),%a0
+ 5e: (32 \.text|R_68K_32 \.text\+0xa6)
+0+0062 <lbl_b\+(0x|)60> lea %pc@\(0+00a6 <lbl_a>\),%a0
+0+0066 <lbl_b\+(0x|)64> lea %pc@\(0+0126 <.*>\),%a0
+0+006a <lbl_b\+(0x|)68> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+006e <lbl_b\+(0x|)6c> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+0072 <lbl_b\+(0x|)70> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+0076 <lbl_b\+(0x|)74> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+007c <lbl_b\+(0x|)7a> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+0082 <lbl_b\+(0x|)80> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+008a <lbl_b\+(0x|)88> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+0092 <lbl_b\+(0x|)90> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+009a <lbl_b\+(0x|)98> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+00a0 <lbl_b\+(0x|)9e> lea %pc@\(0+a6 <lbl_a>,%d0:l\),%a0
+0+00a4 <lbl_b\+(0x|)a2> nop
+0+00a6 <lbl_a> nop
+0+00a8 <lbl_a\+(0x|)2> nop
+0+00aa <lbl_a\+(0x|)4> lea %pc@\(0+2c <lbl_b\+(0x|)2a>,%d0:l\),%a0
+0+00ae <lbl_a\+(0x|)8> lea %pc@\(0+2f <lbl_b\+(0x|)2d>,%d0:l\),%a0
+0+00b4 <lbl_a\+(0x|)e> lea %pc@\(f+80b6 <.*>,%d0:l\),%a0
+0+00ba <lbl_a\+(0x|)14> lea %pc@\(f+80bb <.*>,%d0:l\),%a0
+0+00c2 <lbl_a\+(0x|)1c> nop
+0+00c4 <lbl_a\+(0x|)1e> lea %pc@\(0+145 <.*>,%d0:l\),%a0
+0+00c8 <lbl_a\+(0x|)22> lea %pc@\(0+14a <.*>,%d0:l\),%a0
+0+00ce <lbl_a\+(0x|)28> lea %pc@\(0+80cf <.*>,%d0:l\),%a0
+0+00d4 <lbl_a\+(0x|)2e> lea %pc@\(0+80d6 <.*>,%d0:l\),%a0
+0+00dc <lbl_a\+(0x|)36> nop
+0+00de <lbl_a\+(0x|)38> lea %pc@\(f+80e0 <.*>\),%a0
+0+00e2 <lbl_a\+(0x|)3c> lea %pc@\(f+80e3 <.*>\),%a0
+0+00ea <lbl_a\+(0x|)44> nop
+0+00ec <lbl_a\+(0x|)46> lea %pc@\(0+80ed <.*>\),%a0
+0+00f0 <lbl_a\+(0x|)4a> lea %pc@\(0+80f2 <.*>\),%a0
+0+00f8 <lbl_a\+(0x|)52> nop
+0+00fa <lbl_a\+(0x|)54> lea %pc@\((0+0 <.*>|0+0fc <lbl_a\+(0x|)56>)\),%a0
+ fe: (DISP32 undef|R_68K_PC32 undef\+0x2)
+0+0102 <lbl_a\+(0x|)5c> lea %pc@\((0+0 <.*>|0+0104 <lbl_a\+(0x|)5e>),%d0:l\),%a0
+ 106: (DISP32 undef|R_68K_PC32 undef\+0x2)
+0+010a <lbl_a\+(0x|)64> nop
+0+010c <lbl_a\+(0x|)66> lea 0+0 <.*>,%a0
+ 10e: (R_68K_)?32 undef
+0+0112 <lbl_a\+(0x|)6c> nop
+0+0114 <lbl_a\+(0x|)6e> orib #0,%d0
diff --git a/gas/testsuite/gas/m68k/pcrel.s b/gas/testsuite/gas/m68k/pcrel.s
new file mode 100644
index 00000000000..9c5c22b90fb
--- /dev/null
+++ b/gas/testsuite/gas/m68k/pcrel.s
@@ -0,0 +1,59 @@
+ nop
+lbl_b: nop
+ moveml lbl_b,%a0-%a1
+ moveml %pc@(lbl_b),%a0-%a1
+ moveml %pc@(lbl_b,%d0),%a0-%a1
+ lea lbl_b,%a0
+ lea %pc@(lbl_b),%a0
+ lea %pc@(lbl_b-128),%a0
+ lea %pc@(lbl_b,%d0),%a0
+ lea %pc@(lbl_b:b,%d0),%a0
+ lea %pc@(lbl_b-.-2:b,%d0),%a0
+ lea %pc@(lbl_b:w,%d0),%a0
+ lea %pc@(lbl_b-.-2:w,%d0),%a0
+ lea %pc@(lbl_b:l,%d0),%a0
+ lea %pc@(lbl_b-.-2:l,%d0),%a0
+ nop
+ bsrl lbl_a
+ bsr lbl_a
+ bsrs lbl_a
+ jbsr lbl_a
+ nop
+ lea lbl_a,%a0
+ lea %pc@(lbl_a),%a0
+ lea %pc@(lbl_a+128),%a0
+ lea %pc@(lbl_a,%d0),%a0
+ lea %pc@(lbl_a:b,%d0),%a0
+ lea %pc@(lbl_a-.-2:b,%d0),%a0
+ lea %pc@(lbl_a:w,%d0),%a0
+ lea %pc@(lbl_a-.-2:w,%d0),%a0
+ lea %pc@(lbl_a:l,%d0),%a0
+ lea %pc@(lbl_a-.-2:l,%d0),%a0
+ lea %pc@(18:l,%d0),%a0
+ lea %pc@(10:w,%d0),%a0
+ lea %pc@(4:b,%d0),%a0
+ nop
+lbl_a: nop
+ nop
+ lea %pc@(.-126,%d0),%a0
+ lea %pc@(.-127,%d0),%a0
+ lea %pc@(.-32766,%d0),%a0
+ lea %pc@(.-32767,%d0),%a0
+ nop
+ lea %pc@(.+129,%d0),%a0
+ lea %pc@(.+130,%d0),%a0
+ lea %pc@(.+32769,%d0),%a0
+ lea %pc@(.+32770,%d0),%a0
+ nop
+ lea %pc@(.-32766),%a0
+ lea %pc@(.-32767),%a0
+ nop
+ lea %pc@(.+32769),%a0
+ lea %pc@(.+32770),%a0
+ nop
+ lea %pc@(undef),%a0
+ lea %pc@(undef,%d0),%a0
+ nop
+ lea undef,%a0
+ nop
+ .long 0
diff --git a/gas/testsuite/gas/m68k/pic1.s b/gas/testsuite/gas/m68k/pic1.s
new file mode 100644
index 00000000000..85787744ae7
--- /dev/null
+++ b/gas/testsuite/gas/m68k/pic1.s
@@ -0,0 +1,5 @@
+ .text
+ .globl _foo
+_foo:
+ leal %pc@(_i), %a0
+ leal %pc@(_i-.), %a1
diff --git a/gas/testsuite/gas/m68k/t2.d b/gas/testsuite/gas/m68k/t2.d
new file mode 100644
index 00000000000..65109c8bb51
--- /dev/null
+++ b/gas/testsuite/gas/m68k/t2.d
@@ -0,0 +1,8 @@
+#PROG: nm
+#name: presence of section symbols
+
+00000012 b .bss
+0000000e d .data
+00000000 t .text
+0000000e d loop1
+00000000 t loop2
diff --git a/gas/testsuite/gas/m68k/t2.s b/gas/testsuite/gas/m68k/t2.s
new file mode 100644
index 00000000000..7b71e86ff97
--- /dev/null
+++ b/gas/testsuite/gas/m68k/t2.s
@@ -0,0 +1,6 @@
+ .text
+loop2:
+ move.l %d1,%a0@+
+ dbf %d0,loop1
+ .data
+loop1: bra loop2
diff --git a/gas/testsuite/gas/m88k/init.d b/gas/testsuite/gas/m88k/init.d
new file mode 100644
index 00000000000..b2d92594096
--- /dev/null
+++ b/gas/testsuite/gas/m88k/init.d
@@ -0,0 +1,11 @@
+#objdump: -d --prefix-addresses
+#name: padding of .init section
+
+.*: +file format .*
+
+Disassembly of section .text:
+Disassembly of section .init:
+00000000 <.init> subu r31,r31,0x10
+00000004 <.init\+0x4> st r13,r31,0x20
+00000008 <.init\+0x8> or r0,r0,r0
+0000000c <.init\+0xc> or r0,r0,r0
diff --git a/gas/testsuite/gas/m88k/init.s b/gas/testsuite/gas/m88k/init.s
new file mode 100644
index 00000000000..29681cb1e22
--- /dev/null
+++ b/gas/testsuite/gas/m88k/init.s
@@ -0,0 +1,5 @@
+; Test proper padding of the .init section
+ section .init,"x"
+ align 4
+ subu r31,r31,16
+ st r13,r31,32
diff --git a/gas/testsuite/gas/m88k/m88k.exp b/gas/testsuite/gas/m88k/m88k.exp
new file mode 100644
index 00000000000..6907c115066
--- /dev/null
+++ b/gas/testsuite/gas/m88k/m88k.exp
@@ -0,0 +1,10 @@
+#
+# Tests for m88k svr3 targets
+#
+if { [istarget m88*-*-sysv3] || [istarget m88*-*-coff* ] } then {
+ set testname "Proper padding of .init section"
+ run_dump_test init
+}
+if [info exists errorInfo] then {
+ unset errorInfo
+}
diff --git a/gas/testsuite/gas/macros/err.s b/gas/testsuite/gas/macros/err.s
new file mode 100644
index 00000000000..cc976311f5c
--- /dev/null
+++ b/gas/testsuite/gas/macros/err.s
@@ -0,0 +1,5 @@
+ .macro m
+ m
+ .endm
+
+ m
diff --git a/gas/testsuite/gas/macros/irp.d b/gas/testsuite/gas/macros/irp.d
new file mode 100644
index 00000000000..6733622981e
--- /dev/null
+++ b/gas/testsuite/gas/macros/irp.d
@@ -0,0 +1,13 @@
+#objdump: -r
+#name: macro irp
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR .*
+OFFSET[ ]+TYPE[ ]+VALUE.*
+0+00[ ]+[a-zA-Z0-9_]+[ ]+r1
+0+04[ ]+[a-zA-Z0-9_]+[ ]+r2
+0+08[ ]+[a-zA-Z0-9_]+[ ]+r3
+0+0c[ ]+[a-zA-Z0-9_]+[ ]+s1
+0+10[ ]+[a-zA-Z0-9_]+[ ]+s2
+0+14[ ]+[a-zA-Z0-9_]+[ ]+s3
diff --git a/gas/testsuite/gas/macros/irp.s b/gas/testsuite/gas/macros/irp.s
new file mode 100644
index 00000000000..2f9a6214453
--- /dev/null
+++ b/gas/testsuite/gas/macros/irp.s
@@ -0,0 +1,8 @@
+ .irp param,1,2,3
+ .long r\param
+ .endr
+
+ .irpc param,123
+ .long s\param
+ .endr
+
diff --git a/gas/testsuite/gas/macros/macros.exp b/gas/testsuite/gas/macros/macros.exp
new file mode 100644
index 00000000000..a51e4859867
--- /dev/null
+++ b/gas/testsuite/gas/macros/macros.exp
@@ -0,0 +1,22 @@
+# Run some tests of gas macros.
+
+if ![istarget hppa*-*-*] {
+ run_dump_test test1
+}
+
+run_dump_test test2
+
+run_dump_test test3
+
+run_dump_test irp
+
+run_dump_test rept
+
+gas_test_error "err.s" "" "macro infinite recursion"
+
+case $target_triplet in {
+ { hppa*-*-* } { }
+ default {
+ run_dump_test semi
+ }
+}
diff --git a/gas/testsuite/gas/macros/rept.d b/gas/testsuite/gas/macros/rept.d
new file mode 100644
index 00000000000..efb5d996dab
--- /dev/null
+++ b/gas/testsuite/gas/macros/rept.d
@@ -0,0 +1,10 @@
+#objdump: -r
+#name: macro rept
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR .*
+OFFSET[ ]+TYPE[ ]+VALUE.*
+0+00[ ]+[a-zA-Z0-9_]+[ ]+r1
+0+04[ ]+[a-zA-Z0-9_]+[ ]+r1
+0+08[ ]+[a-zA-Z0-9_]+[ ]+r1
diff --git a/gas/testsuite/gas/macros/rept.s b/gas/testsuite/gas/macros/rept.s
new file mode 100644
index 00000000000..243cf67b8f7
--- /dev/null
+++ b/gas/testsuite/gas/macros/rept.s
@@ -0,0 +1,3 @@
+ .rept 3
+ .long r1
+ .endr
diff --git a/gas/testsuite/gas/macros/semi.d b/gas/testsuite/gas/macros/semi.d
new file mode 100644
index 00000000000..ae89e738592
--- /dev/null
+++ b/gas/testsuite/gas/macros/semi.d
@@ -0,0 +1,8 @@
+#objdump: -s -j .text
+#name: semi
+
+.*: .*
+
+Contents of section .text:
+ 0000 3b203b20 3a203a20 00000000 00000000 ; ; : : ........
+ 0010 00000000 00000000 00000000 00000000 ................
diff --git a/gas/testsuite/gas/macros/semi.s b/gas/testsuite/gas/macros/semi.s
new file mode 100644
index 00000000000..d6e0963a169
--- /dev/null
+++ b/gas/testsuite/gas/macros/semi.s
@@ -0,0 +1,14 @@
+ .macro semicolon
+ .ascii "; "
+ .endm
+
+ .macro colon
+ .ascii ": "
+ .endm
+
+ semicolon
+ .ascii "; "
+ colon
+ .ascii ": "
+
+ .p2align 5,0
diff --git a/gas/testsuite/gas/macros/test1.d b/gas/testsuite/gas/macros/test1.d
new file mode 100644
index 00000000000..d84b3fb53b3
--- /dev/null
+++ b/gas/testsuite/gas/macros/test1.d
@@ -0,0 +1,5 @@
+#nm: --extern-only
+#name: macro test 1
+
+0+01 A s1
+0+02 A s2
diff --git a/gas/testsuite/gas/macros/test1.s b/gas/testsuite/gas/macros/test1.s
new file mode 100644
index 00000000000..988b7cde0d4
--- /dev/null
+++ b/gas/testsuite/gas/macros/test1.s
@@ -0,0 +1,7 @@
+ .macro m arg1 arg2
+ .globl \arg1
+ \arg1 = \arg2
+ .endm
+
+ m s1,1
+ m s2,2
diff --git a/gas/testsuite/gas/macros/test2.d b/gas/testsuite/gas/macros/test2.d
new file mode 100644
index 00000000000..741d734959a
--- /dev/null
+++ b/gas/testsuite/gas/macros/test2.d
@@ -0,0 +1,10 @@
+#objdump: -r
+#name: macro test 2
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR .*
+OFFSET[ ]+TYPE[ ]+VALUE.*
+0+00[ ]+[a-zA-Z0-9_]+[ ]+r1
+0+04[ ]+[a-zA-Z0-9_]+[ ]+r2
+0+08[ ]+[a-zA-Z0-9_]+[ ]+r3
diff --git a/gas/testsuite/gas/macros/test2.s b/gas/testsuite/gas/macros/test2.s
new file mode 100644
index 00000000000..838ce94032c
--- /dev/null
+++ b/gas/testsuite/gas/macros/test2.s
@@ -0,0 +1,9 @@
+ .macro m arg1 arg2 arg3
+ .long \arg1
+ .ifc ,\arg2\arg3
+ .ELSE
+ m \arg2,\arg3
+ .endif
+ .endm
+
+ m r1,r2,r3
diff --git a/gas/testsuite/gas/macros/test3.d b/gas/testsuite/gas/macros/test3.d
new file mode 100644
index 00000000000..2580f764222
--- /dev/null
+++ b/gas/testsuite/gas/macros/test3.d
@@ -0,0 +1,8 @@
+#objdump: -r
+#name: macro test 3
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR .*
+OFFSET[ ]+TYPE[ ]+VALUE.*
+0+00[ ]+[a-zA-Z0-9_]+[ ]+r1
diff --git a/gas/testsuite/gas/macros/test3.s b/gas/testsuite/gas/macros/test3.s
new file mode 100644
index 00000000000..c6410aec164
--- /dev/null
+++ b/gas/testsuite/gas/macros/test3.s
@@ -0,0 +1,7 @@
+ .macro m arg1 arg2
+ \arg1
+ .exitm
+ \arg2
+ .endm
+
+ m ".long r1",.garbage
diff --git a/gas/testsuite/gas/mcore/allinsn.d b/gas/testsuite/gas/mcore/allinsn.d
new file mode 100644
index 00000000000..913d8f51fe7
--- /dev/null
+++ b/gas/testsuite/gas/mcore/allinsn.d
@@ -0,0 +1,400 @@
+#as:
+#objdump: -dr
+#name: allinsn
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <abs>:
+ 0: 01 e0 abs r0
+
+0+002 <addc>:
+ 2: 06 21 addc r1, r2
+
+0+004 <addi>:
+ 4: 20 03 addi r3, 1
+
+0+006 <addu>:
+ 6: 1c 54 addu r4, r5
+
+0+008 <and>:
+ 8: 16 76 and r6, r7
+
+0+00a <andi>:
+ a: 2e 28 andi r8, 2
+
+0+00c <andn>:
+ c: 1f a9 andn r9, r10
+
+0+00e <asr>:
+ e: 1a cb asr r11, r12
+
+0+010 <asrc>:
+ 10: 3a 0d asrc r13
+
+0+012 <asri>:
+ 12: 3b fe asri r14, 31
+
+0+014 <bclri>:
+ 14: 30 0f bclri r15, 0
+
+0+016 <bf>:
+ 16: ef f4 bf 0x0
+
+0+018 <bgeni>:
+ 18: 32 70 bgeni r0, 7
+
+0+01a <BGENI>:
+ 1a: 32 80 bgeni r0, 8
+
+0+01c <BGENi>:
+ 1c: 33 f0 bgeni r0, 31
+
+0+01e <bgenr>:
+ 1e: 13 21 bgenr r1, r2
+
+0+020 <bkpt>:
+ ...
+
+0+022 <bmaski>:
+ 22: 2c 83 bmaski r3, 8
+
+0+024 <BMASKI>:
+ 24: 2d f3 bmaski r3, 31
+
+0+026 <br>:
+ 26: f7 ff br 0x26
+
+0+028 <brev>:
+ 28: 00 f4 brev r4
+
+0+02a <bseti>:
+ 2a: 35 e5 bseti r5, 30
+
+0+02c <bsr>:
+ 2c: ff e9 bsr 0x0
+
+0+02e <bt>:
+ 2e: e7 e8 bt 0x0
+
+0+030 <btsti>:
+ 30: 37 b6 btsti r6, 27
+
+0+032 <clrc>:
+ 32: 0f 00 cmpne r0, r0
+
+0+034 <clrf>:
+ 34: 01 d7 clrf r7
+
+0+036 <clrt>:
+ 36: 01 c8 clrt r8
+
+0+038 <cmphs>:
+ 38: 0c a9 cmphs r9, r10
+
+0+03a <cmplt>:
+ 3a: 0d cb cmplt r11, r12
+
+0+03c <cmplei>:
+ 3c: 22 eb cmplti r11, 15
+
+0+03e <cmplti>:
+ 3e: 23 fd cmplti r13, 32
+
+0+040 <cmpne>:
+ 40: 0f fe cmpne r14, r15
+
+0+042 <cmpnei>:
+ 42: 2a 00 cmpnei r0, 0
+
+0+044 <decf>:
+ 44: 00 91 decf r1
+
+0+046 <decgt>:
+ 46: 01 a2 decgt r2
+
+0+048 <declt>:
+ 48: 01 83 declt r3
+
+0+04a <decne>:
+ 4a: 01 b4 decne r4
+
+0+04c <dect>:
+ 4c: 00 85 dect r5
+
+0+04e <divs>:
+ 4e: 32 16 divs r6, r1
+
+0+050 <divu>:
+ 50: 2c 18 divu r8, r1
+
+0+052 <doze>:
+ 52: 00 06 doze
+
+0+054 <ff1>:
+ 54: 00 ea ff1 r10
+
+0+056 <incf>:
+ 56: 00 bb incf r11
+
+0+058 <inct>:
+ 58: 00 ac inct r12
+
+0+05a <ixh>:
+ 5a: 1d ed ixh r13, r14
+
+0+05c <ixw>:
+ 5c: 15 0f ixw r15, r0
+
+0+05e <jbf>:
+ 5e: ef d0 bf 0x0
+
+0+060 <jbr>:
+ 60: f0 0e br 0x7e
+
+0+062 <jbsr>:
+ 62: 7f 0a jsri 0x.*
+
+0+064 <jbt>:
+ 64: e0 0c bt 0x7e
+
+0+066 <jmp>:
+ 66: 00 c1 jmp r1
+
+0+068 <jmpi>:
+ 68: 70 09 jmpi 0x.*
+
+0+06a <jsr>:
+ 6a: 00 d2 jsr r2
+
+0+06c <jsri>:
+ 6c: 7f 08 jsri 0x.*
+
+0+06e <ld.b>:
+ 6e: a3 04 ldb r3, \(r4, 0\)
+
+0+070 <ld.h>:
+ 70: c5 16 ldh r5, \(r6, 2\)
+
+0+072 <ld.w>:
+ 72: 87 18 ld r7, \(r8, 4\)
+
+0+074 <ldb>:
+ 74: a9 fa ldb r9, \(r10, 15\)
+
+0+076 <ldh>:
+ 76: cb fc ldh r11, \(r12, 30\)
+
+0+078 <ld>:
+ 78: 8d 5e ld r13, \(r14, 20\)
+
+0+07a <ldw>:
+ 7a: 8d fe ld r13, \(r14, 60\)
+
+0+07c <ldm>:
+ 7c: 00 62 ldm r2-r15, \(r0\)
+
+0+07e <fooloop>:
+ 7e: 00 41 ldq r4-r7, \(r1\)
+
+0+080 <loopt>:
+ 80: 04 8e loopt r8, 0x64
+
+0+082 <LRW>:
+ 82: 79 03 lrw r9, 0x.*
+
+0+084 <lrw>:
+ 84: 79 04 lrw r9, 0x4321
+
+0+086 <foolit>:
+ 86: 12 34 mov r4, r3
+
+0+088 <lsl>:
+ 88: 1b ba lsl r10, r11
+
+0+08a <lslc>:
+ 8a: 3c 0c lslc r12
+
+0+08c <.XP0001>:
+ ...
+ 8c: ADDR32 .text
+ 90: ADDR32 .text.*
+ 94: 00 00 bkpt
+ 96: 43 21 .word 0x4321
+
+0+098 <lsli>:
+ 98: 3d fd lsli r13, 31
+
+0+09a <lsr>:
+ 9a: 0b fe lsr r14, r15
+
+0+09c <lsrc>:
+ 9c: 3e 00 lsrc r0
+
+0+09e <lsri>:
+ 9e: 3e 11 lsri r1, 1
+
+0+0a0 <mclri>:
+ a0: 30 64 bclri r4, 6
+
+0+0a2 <mfcr>:
+ a2: 10 02 mfcr r2, psr
+
+0+0a4 <mov>:
+ a4: 12 43 mov r3, r4
+
+0+0a6 <movf>:
+ a6: 0a 65 movf r5, r6
+
+0+0a8 <movi>:
+ a8: 67 f7 movi r7, 127
+
+0+0aa <movt>:
+ aa: 02 98 movt r8, r9
+
+0+0ac <mtcr>:
+ ac: 18 0a mtcr r10, psr
+
+0+0ae <mult>:
+ ae: 03 cb mult r11, r12
+
+0+0b0 <mvc>:
+ b0: 00 2d mvc r13
+
+0+0b2 <mvcv>:
+ b2: 00 3e mvcv r14
+
+0+0b4 <neg>:
+ b4: 28 02 rsubi r2, 0
+
+0+0b6 <not>:
+ b6: 01 ff not r15
+
+0+0b8 <or>:
+ b8: 1e 10 or r0, r1
+
+0+0ba <rfi>:
+ ba: 00 03 rfi
+
+0+0bc <rolc>:
+ bc: 06 66 addc r6, r6
+
+0+0be <rori>:
+ be: 39 a9 rotli r9, 26
+
+0+0c0 <rotlc>:
+ c0: 06 66 addc r6, r6
+
+0+0c2 <rotli>:
+ c2: 38 a2 rotli r2, 10
+
+0+0c4 <rotri>:
+ c4: 39 a9 rotli r9, 26
+
+0+0c6 <rsub>:
+ c6: 14 43 rsub r3, r4
+
+0+0c8 <rsubi>:
+ c8: 28 05 rsubi r5, 0
+
+0+0ca <rte>:
+ ca: 00 02 rte
+
+0+0cc <rts>:
+ cc: 00 cf jmp r15
+
+0+0ce <setc>:
+ ce: 0c 00 cmphs r0, r0
+
+0+0d0 <sextb>:
+ d0: 01 56 sextb r6
+
+0+0d2 <sexth>:
+ d2: 01 77 sexth r7
+
+0+0d4 <st.b>:
+ d4: b8 09 stb r8, \(r9, 0\)
+
+0+0d6 <st.h>:
+ d6: da 1b sth r10, \(r11, 2\)
+
+0+0d8 <st.w>:
+ d8: 9c 1d st r12, \(r13, 4\)
+
+0+0da <stb>:
+ da: be ff stb r14, \(r15, 15\)
+
+0+0dc <sth>:
+ dc: d0 f1 sth r0, \(r1, 30\)
+
+0+0de <stw>:
+ de: 92 f3 st r2, \(r3, 60\)
+
+0+0e0 <st>:
+ e0: 94 05 st r4, \(r5, 0\)
+
+0+0e2 <stm>:
+ e2: 00 7e stm r14-r15, \(r0\)
+
+0+0e4 <stop>:
+ e4: 00 04 stop
+
+0+0e6 <stq>:
+ e6: 00 51 stq r4-r7, \(r1\)
+
+0+0e8 <subc>:
+ e8: 07 d7 subc r7, r13
+
+0+0ea <subi>:
+ ea: 25 fe subi r14, 32
+
+0+0ec <subu>:
+ ec: 05 39 subu r9, r3
+
+0+0ee <sync>:
+ ee: 00 01 sync
+
+0+0f0 <tstlt>:
+ f0: 37 f5 btsti r5, 31
+
+0+0f2 <tstne>:
+ f2: 2a 07 cmpnei r7, 0
+
+0+0f4 <trap>:
+ f4: 00 0a trap 2
+
+0+0f6 <tst>:
+ f6: 0e ee tst r14, r14
+
+0+0f8 <tstnbz>:
+ f8: 01 92 tstnbz r2
+
+0+0fa <wait>:
+ fa: 00 05 wait
+
+0+0fc <xor>:
+ fc: 17 0f xor r15, r0
+
+0+0fe <xsr>:
+ fe: 38 0b xsr r11
+
+0+0100 <xtrb0>:
+ 100: 01 31 xtrb0 r1, r1
+
+0+0102 <xtrb1>:
+ 102: 01 22 xtrb1 r1, r2
+
+0+0104 <xtrb2>:
+ 104: 01 10 xtrb2 r1, r0
+
+0+0106 <xtrb3>:
+ 106: 01 0d xtrb3 r1, r13
+
+0+0108 <zextb>:
+ 108: 01 48 zextb r8
+
+0+010a <zexth>:
+ 10a: 01 64 zexth r4
+ 10c: 0f 00 cmpne r0, r0
+ 10e: 0f 00 cmpne r0, r0
diff --git a/gas/testsuite/gas/mcore/allinsn.exp b/gas/testsuite/gas/mcore/allinsn.exp
new file mode 100644
index 00000000000..9f57863ab39
--- /dev/null
+++ b/gas/testsuite/gas/mcore/allinsn.exp
@@ -0,0 +1,5 @@
+# M*Core assembler testsuite.
+
+if [istarget mcore-*-*] {
+ run_dump_test "allinsn"
+}
diff --git a/gas/testsuite/gas/mcore/allinsn.s b/gas/testsuite/gas/mcore/allinsn.s
new file mode 100644
index 00000000000..84068404e74
--- /dev/null
+++ b/gas/testsuite/gas/mcore/allinsn.s
@@ -0,0 +1,146 @@
+ .data
+foodata: .word 42
+ .text
+footext:
+
+.macro test insn text=""
+ .export \insn
+\insn:
+ \insn \text
+.endm
+
+ test abs r0
+ test addc "r1,r2" // A double forward slash starts a line comment
+ test addi "r3, 1" # So does a hash
+ test addu "r4, r5" // White space between operands should be ignored
+ test and "r6,r7" ; test andi "r8,#2" // A semicolon seperates statements
+ test andn "r9, r10"
+ test asr "r11, R12" // Uppercase R is allowed as a register prefix
+ test asrc "r13"
+ test asri "r14,#0x1f"
+ test bclri "r15,0"
+ test bf footext
+ test bgeni "sp, 7" // r0 can also be refered to as 'sp'
+ test BGENI "r0, 8" // Officially upper case or mixed case
+ test BGENi "r0, 31" // mnemonics should not be allowed, but we relax this...
+ test bgenr "r1, r2"
+ test bkpt
+ test bmaski "r3,#8"
+ test BMASKI "r3,0x1f"
+ test br . // Dot means the current address
+ test brev r4
+ test bseti "r5,30"
+ test bsr footext
+ test bt footext
+ test btsti "r6, 27"
+ test clrc
+ test clrf r7
+ test clrt r8
+ test cmphs "r9,r10"
+ test cmplt "r11,r12"
+ test cmplei "r11, 14"
+ test cmplti "r13,32"
+ test cmpne "r14, r15"
+ test cmpnei "r0,0"
+ test decf r1
+ test decgt r2
+ test declt r3
+ test decne r4
+ test dect r5
+ test divs "r6,r1"
+ test divu "r8, r1"
+ test doze
+ test ff1 r10
+ test incf r11
+ test inct r12
+ test ixh "r13,r14"
+ test ixw "r15,r0"
+ test jbf footext
+ test jbr fooloop
+ test jbsr footext
+ test jbt fooloop
+ test jmp r1
+ test jmpi footext
+ test jsr r2
+ test jsri footext
+ test ld.b "r3,(r4,0)"
+ test ld.h "r5 , ( r6, #2)"
+ test ld.w "r7, (r8, 0x4)"
+ test ldb "r9,(r10,#0xf)"
+ test ldh "r11, (r12, 30)"
+ test ld "r13, (r14, 20)"
+ test ldw "r13, (r14, 60)"
+ test ldm "r2-r15,(r0)"
+ .export fooloop
+fooloop:
+ test ldq "r4-r7,(r1)"
+ test loopt "r8, fooloop"
+ test LRW "r9, [foolit]"
+ test lrw "r9, 0x4321" // PC rel indirect
+ .global foolit
+foolit:
+ .word 0x1234
+ test lsl "r10,r11"
+ test lslc r12
+ .literals // Dump literals table
+ test lsli "r13,31"
+ test lsr "r14,r15"
+ test lsrc r0
+ test lsri "r1,1"
+ test mclri "r4, 64"
+ test mfcr "r2, cr0"
+ test mov "r3,r4"
+ test movf "r5, r6"
+ test movi "r7, 127"
+ test movt "r8, r9"
+ test mtcr "r10, psr"
+ test mult "r11, r12"
+ test mvc r13
+ test mvcv r14
+ test neg r2
+ test not r15
+ test or "r0,r1"
+ test rfi
+ test rolc "r6, 1"
+ test rori "r9, 6"
+ test rotlc "r6, 1"
+ test rotli "r2, #10"
+ test rotri "r9, 6"
+ test rsub "r3, r4"
+ test rsubi "r5, 0x0"
+ test rte
+ test rts
+ test setc
+ test sextb r6
+ test sexth r7
+ test st.b "r8, (r9, 0)"
+ test st.h "r10, (r11, 2)"
+ test st.w "r12, (r13, 4)"
+ test stb "r14, (r15, 15)"
+ test sth "r0, (r1, 30)"
+ test stw "r2, (r3, 0x3c)"
+ test st "r4, (r5, 0)"
+ test stm "r14 - r15 , (r0)"
+ test stop
+ test stq "r4 - r7 , (r1)"
+ test subc "r7, r13"
+ test subi "r14, 32"
+ test subu "r9, r3"
+ test sync
+ test tstlt r5
+ test tstne r7
+ test trap 2
+ test tst "r14, r14"
+ test tstnbz r2
+ test wait
+ test xor "r15,r0"
+ test xsr r11
+ test xtrb0 "r1, r1"
+ test xtrb1 "r1, r2"
+ test xtrb2 "r1, r0"
+ test xtrb3 "r1, r13"
+ test zextb r8
+ test zexth r4
+ clrc // These two instructions pad the object file
+ clrc // out to a 16 byte boundary.
+ \ No newline at end of file
diff --git a/gas/testsuite/gas/mips/abs.d b/gas/testsuite/gas/mips/abs.d
new file mode 100644
index 00000000000..c86d5c2b0f5
--- /dev/null
+++ b/gas/testsuite/gas/mips/abs.d
@@ -0,0 +1,15 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS abs
+
+# Test the abs macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> bgez \$a0,0+000c <foo\+(0x|)c>
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> neg \$a0,\$a0
+0+000c <[^>]*> bgez \$a1,0+0018 <foo\+(0x|)18>
+0+0010 <[^>]*> move \$a0,\$a1
+0+0014 <[^>]*> neg \$a0,\$a1
+ ...
diff --git a/gas/testsuite/gas/mips/abs.s b/gas/testsuite/gas/mips/abs.s
new file mode 100644
index 00000000000..1f2172bcb02
--- /dev/null
+++ b/gas/testsuite/gas/mips/abs.s
@@ -0,0 +1,5 @@
+# Source file used to test the abs macro.
+foo:
+ abs $4
+ abs $4,$5
+ .space 8
diff --git a/gas/testsuite/gas/mips/add.d b/gas/testsuite/gas/mips/add.d
new file mode 100644
index 00000000000..8c21d1dda30
--- /dev/null
+++ b/gas/testsuite/gas/mips/add.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS add
+
+# Test the add macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> addi \$a0,\$a0,0
+0+0004 <[^>]*> addi \$a0,\$a0,1
+0+0008 <[^>]*> li \$at,0x8000
+0+000c <[^>]*> add \$a0,\$a0,\$at
+0+0010 <[^>]*> addi \$a0,\$a0,-32768
+0+0014 <[^>]*> lui \$at,0x1
+0+0018 <[^>]*> add \$a0,\$a0,\$at
+0+001c <[^>]*> lui \$at,0x1
+0+0020 <[^>]*> ori \$at,\$at,0xa5a5
+0+0024 <[^>]*> add \$a0,\$a0,\$at
+0+0028 <[^>]*> addiu \$a0,\$a0,1
+0+002c <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/add.s b/gas/testsuite/gas/mips/add.s
new file mode 100644
index 00000000000..44e964bdd22
--- /dev/null
+++ b/gas/testsuite/gas/mips/add.s
@@ -0,0 +1,16 @@
+# Source file used to test the add macro.
+
+foo:
+ add $4,$4,0
+ add $4,$4,1
+ add $4,$4,0x8000
+ add $4,$4,-0x8000
+ add $4,$4,0x10000
+ add $4,$4,0x1a5a5
+
+# addu is handled the same way add is; just confirm that it isn't
+# totally broken.
+ addu $4,$4,1
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
diff --git a/gas/testsuite/gas/mips/and.d b/gas/testsuite/gas/mips/and.d
new file mode 100644
index 00000000000..8d617147caa
--- /dev/null
+++ b/gas/testsuite/gas/mips/and.d
@@ -0,0 +1,34 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS and
+
+# Test the and macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> andi \$a0,\$a0,0x0
+0+0004 <[^>]*> andi \$a0,\$a0,0x1
+0+0008 <[^>]*> andi \$a0,\$a0,0x8000
+0+000c <[^>]*> li \$at,-32768
+0+0010 <[^>]*> and \$a0,\$a0,\$at
+0+0014 <[^>]*> lui \$at,0x1
+0+0018 <[^>]*> and \$a0,\$a0,\$at
+0+001c <[^>]*> lui \$at,0x1
+0+0020 <[^>]*> ori \$at,\$at,0xa5a5
+0+0024 <[^>]*> and \$a0,\$a0,\$at
+0+0028 <[^>]*> ori \$a0,\$a1,0x0
+0+002c <[^>]*> nor \$a0,\$a0,\$zero
+0+0030 <[^>]*> ori \$a0,\$a1,0x1
+0+0034 <[^>]*> nor \$a0,\$a0,\$zero
+0+0038 <[^>]*> ori \$a0,\$a1,0x8000
+0+003c <[^>]*> nor \$a0,\$a0,\$zero
+0+0040 <[^>]*> li \$at,-32768
+0+0044 <[^>]*> nor \$a0,\$a1,\$at
+0+0048 <[^>]*> lui \$at,0x1
+0+004c <[^>]*> nor \$a0,\$a1,\$at
+0+0050 <[^>]*> lui \$at,0x1
+0+0054 <[^>]*> ori \$at,\$at,0xa5a5
+0+0058 <[^>]*> nor \$a0,\$a1,\$at
+0+005c <[^>]*> ori \$a0,\$a1,0x0
+0+0060 <[^>]*> xori \$a0,\$a1,0x0
+ ...
diff --git a/gas/testsuite/gas/mips/and.s b/gas/testsuite/gas/mips/and.s
new file mode 100644
index 00000000000..4dfc57e1f4e
--- /dev/null
+++ b/gas/testsuite/gas/mips/and.s
@@ -0,0 +1,28 @@
+# Source file used to test the and macro.
+
+foo:
+ and $4,$4,0
+ and $4,$4,1
+ and $4,$4,0x8000
+ and $4,$4,-0x8000
+ and $4,$4,0x10000
+ and $4,$4,0x1a5a5
+
+# nor, or, and xor are handled by the same code. There is a special
+# case for nor, so we test all variants.
+
+ nor $4,$5,0
+ nor $4,$5,1
+ nor $4,$5,0x8000
+ nor $4,$5,-0x8000
+ nor $4,$5,0x10000
+ nor $4,$5,0x1a5a5
+
+ or $4,$5,0
+
+ xor $4,$5,0
+
+ # Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/beq.d b/gas/testsuite/gas/mips/beq.d
new file mode 100644
index 00000000000..a1329342f24
--- /dev/null
+++ b/gas/testsuite/gas/mips/beq.d
@@ -0,0 +1,40 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS beq
+
+# Test the beq macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> beq \$a0,\$a1,0+0000 <text_label>
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> beqz \$a0,0+0000 <text_label>
+0+000c <[^>]*> nop
+0+0010 <[^>]*> li \$at,1
+0+0014 <[^>]*> beq \$a0,\$at,0+0000 <text_label>
+0+0018 <[^>]*> nop
+0+001c <[^>]*> li \$at,0x8000
+0+0020 <[^>]*> beq \$a0,\$at,0+0000 <text_label>
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> li \$at,-32768
+0+002c <[^>]*> beq \$a0,\$at,0+0000 <text_label>
+0+0030 <[^>]*> nop
+0+0034 <[^>]*> lui \$at,0x1
+0+0038 <[^>]*> beq \$a0,\$at,0+0000 <text_label>
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lui \$at,0x1
+0+0044 <[^>]*> ori \$at,\$at,0xa5a5
+0+0048 <[^>]*> beq \$a0,\$at,0+0000 <text_label>
+0+004c <[^>]*> nop
+0+0050 <[^>]*> bnez \$a0,0+0000 <text_label>
+0+0054 <[^>]*> nop
+0+0058 <[^>]*> beqzl \$a0,0+0000 <text_label>
+0+005c <[^>]*> nop
+0+0060 <[^>]*> bnezl \$a0,0+0000 <text_label>
+ ...
+0+20068 <[^>]*> j 0+0000 <text_label>
+[ ]*20068: (MIPS_JMP|JMPADDR|R_MIPS_26) .text
+0+2006c <[^>]*> nop
+0+20070 <[^>]*> jal 0+0000 <text_label>
+[ ]*20070: (MIPS_JMP|JMPADDR|R_MIPS_26) .text
+ ...
diff --git a/gas/testsuite/gas/mips/beq.s b/gas/testsuite/gas/mips/beq.s
new file mode 100644
index 00000000000..9922eecb279
--- /dev/null
+++ b/gas/testsuite/gas/mips/beq.s
@@ -0,0 +1,28 @@
+# Source file used to test the beq macro.
+ .globl text_label .text
+text_label:
+ beq $4,$5,text_label
+ beq $4,0,text_label
+ beq $4,1,text_label
+ beq $4,0x8000,text_label
+ beq $4,-0x8000,text_label
+ beq $4,0x10000,text_label
+ beq $4,0x1a5a5,text_label
+
+# bne is handled by the same code as beq. Just sanity check.
+ bne $4,0,text_label
+
+# Sanity check beql and bnel
+ .set mips2
+ beql $4,0,text_label
+ bnel $4,0,text_label
+
+# Test that branches which overflow are converted to jumps.
+ .space 0x20000
+ b text_label
+ bal text_label
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/bge.d b/gas/testsuite/gas/mips/bge.d
new file mode 100644
index 00000000000..ee3e27ce8ed
--- /dev/null
+++ b/gas/testsuite/gas/mips/bge.d
@@ -0,0 +1,53 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS bge
+
+# Test the bge macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> slt \$at,\$a0,\$a1
+0+0004 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0008 <[^>]*> nop
+0+000c <[^>]*> bgez \$a0,0+0000 <text_label>
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> blez \$a1,0+0000 <text_label>
+0+0018 <[^>]*> nop
+0+001c <[^>]*> bgez \$a0,0+0000 <text_label>
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> bgtz \$a0,0+0000 <text_label>
+0+0028 <[^>]*> nop
+0+002c <[^>]*> slti \$at,\$a0,2
+0+0030 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0034 <[^>]*> nop
+0+0038 <[^>]*> li \$at,0x8000
+0+003c <[^>]*> slt \$at,\$a0,\$at
+0+0040 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0044 <[^>]*> nop
+0+0048 <[^>]*> slti \$at,\$a0,-32768
+0+004c <[^>]*> beqz \$at,0+0000 <text_label>
+0+0050 <[^>]*> nop
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> slt \$at,\$a0,\$at
+0+005c <[^>]*> beqz \$at,0+0000 <text_label>
+0+0060 <[^>]*> nop
+0+0064 <[^>]*> lui \$at,0x1
+0+0068 <[^>]*> ori \$at,\$at,0xa5a5
+0+006c <[^>]*> slt \$at,\$a0,\$at
+0+0070 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0074 <[^>]*> nop
+0+0078 <[^>]*> slt \$at,\$a1,\$a0
+0+007c <[^>]*> bnez \$at,0+0000 <text_label>
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> bgtz \$a0,0+0000 <text_label>
+0+0088 <[^>]*> nop
+0+008c <[^>]*> bltz \$a1,0+0000 <text_label>
+0+0090 <[^>]*> nop
+0+0094 <[^>]*> bgtz \$a0,0+0000 <text_label>
+0+0098 <[^>]*> nop
+0+009c <[^>]*> slt \$at,\$a0,\$a1
+0+00a0 <[^>]*> beqzl \$at,0+0000 <text_label>
+0+00a4 <[^>]*> nop
+0+00a8 <[^>]*> slt \$at,\$a1,\$a0
+0+00ac <[^>]*> bnezl \$at,0+0000 <text_label>
+ ...
diff --git a/gas/testsuite/gas/mips/bge.s b/gas/testsuite/gas/mips/bge.s
new file mode 100644
index 00000000000..405fd82b2b7
--- /dev/null
+++ b/gas/testsuite/gas/mips/bge.s
@@ -0,0 +1,31 @@
+# Source file used to test the bge macro.
+
+text_label:
+ bge $4,$5,text_label
+ bge $4,$0,text_label
+ bge $0,$5,text_label
+ bge $4,0,text_label
+ bge $4,1,text_label
+ bge $4,2,text_label
+ bge $4,0x8000,text_label
+ bge $4,-0x8000,text_label
+ bge $4,0x10000,text_label
+ bge $4,0x1a5a5,text_label
+
+# bgt is handled like bge, except when both arguments are registers.
+# Just sanity check it otherwise.
+ bgt $4,$5,text_label
+ bgt $4,$0,text_label
+ bgt $0,$5,text_label
+ bgt $4,0,text_label
+
+# Sanity test bgel and bgtl
+ .set mips2
+ bgel $4,$5,text_label
+ bgtl $4,$5,text_label
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/bgeu.d b/gas/testsuite/gas/mips/bgeu.d
new file mode 100644
index 00000000000..93a60401147
--- /dev/null
+++ b/gas/testsuite/gas/mips/bgeu.d
@@ -0,0 +1,47 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS bgeu
+
+# Test the bgeu macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> sltu \$at,\$a0,\$a1
+0+0004 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0008 <[^>]*> nop
+0+000c <[^>]*> beq \$zero,\$a1,0+0000 <text_label>
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> bnez \$a0,0+0000 <text_label>
+0+0018 <[^>]*> nop
+0+001c <[^>]*> sltiu \$at,\$a0,2
+0+0020 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> li \$at,0x8000
+0+002c <[^>]*> sltu \$at,\$a0,\$at
+0+0030 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0034 <[^>]*> nop
+0+0038 <[^>]*> sltiu \$at,\$a0,-32768
+0+003c <[^>]*> beqz \$at,0+0000 <text_label>
+0+0040 <[^>]*> nop
+0+0044 <[^>]*> lui \$at,0x1
+0+0048 <[^>]*> sltu \$at,\$a0,\$at
+0+004c <[^>]*> beqz \$at,0+0000 <text_label>
+0+0050 <[^>]*> nop
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> ori \$at,\$at,0xa5a5
+0+005c <[^>]*> sltu \$at,\$a0,\$at
+0+0060 <[^>]*> beqz \$at,0+0000 <text_label>
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> sltu \$at,\$a1,\$a0
+0+006c <[^>]*> bnez \$at,0+0000 <text_label>
+0+0070 <[^>]*> nop
+0+0074 <[^>]*> bnez \$a0,0+0000 <text_label>
+0+0078 <[^>]*> nop
+0+007c <[^>]*> bnez \$a0,0+0000 <text_label>
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> sltu \$at,\$a0,\$a1
+0+0088 <[^>]*> beqzl \$at,0+0000 <text_label>
+0+008c <[^>]*> nop
+0+0090 <[^>]*> sltu \$at,\$a1,\$a0
+0+0094 <[^>]*> bnezl \$at,0+0000 <text_label>
+ ...
diff --git a/gas/testsuite/gas/mips/bgeu.s b/gas/testsuite/gas/mips/bgeu.s
new file mode 100644
index 00000000000..1c37f96939c
--- /dev/null
+++ b/gas/testsuite/gas/mips/bgeu.s
@@ -0,0 +1,27 @@
+# Source file used to test the bgeu macro.
+
+text_label:
+ bgeu $4,$5,text_label
+ bgeu $0,$5,text_label
+ # A second argument of 0 or $0 is always true
+ bgeu $4,1,text_label
+ bgeu $4,2,text_label
+ bgeu $4,0x8000,text_label
+ bgeu $4,-0x8000,text_label
+ bgeu $4,0x10000,text_label
+ bgeu $4,0x1a5a5,text_label
+
+# bgtu is handled like bgeu, except when both arguments are registers.
+# Just sanity check it otherwise.
+ bgtu $4,$5,text_label
+ bgtu $4,$0,text_label
+ bgtu $4,0,text_label
+
+# Sanity test bgeul and bgtul
+ .set mips2
+ bgeul $4,$5,text_label
+ bgtul $4,$5,text_label
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/blt.d b/gas/testsuite/gas/mips/blt.d
new file mode 100644
index 00000000000..fc10e23a5a8
--- /dev/null
+++ b/gas/testsuite/gas/mips/blt.d
@@ -0,0 +1,53 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS blt
+
+# Test the blt macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> slt \$at,\$a0,\$a1
+0+0004 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0008 <[^>]*> nop
+0+000c <[^>]*> bltz \$a0,0+0000 <text_label>
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> bgtz \$a1,0+0000 <text_label>
+0+0018 <[^>]*> nop
+0+001c <[^>]*> bltz \$a0,0+0000 <text_label>
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> blez \$a0,0+0000 <text_label>
+0+0028 <[^>]*> nop
+0+002c <[^>]*> slti \$at,\$a0,2
+0+0030 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0034 <[^>]*> nop
+0+0038 <[^>]*> li \$at,0x8000
+0+003c <[^>]*> slt \$at,\$a0,\$at
+0+0040 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0044 <[^>]*> nop
+0+0048 <[^>]*> slti \$at,\$a0,-32768
+0+004c <[^>]*> bnez \$at,0+0000 <text_label>
+0+0050 <[^>]*> nop
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> slt \$at,\$a0,\$at
+0+005c <[^>]*> bnez \$at,0+0000 <text_label>
+0+0060 <[^>]*> nop
+0+0064 <[^>]*> lui \$at,0x1
+0+0068 <[^>]*> ori \$at,\$at,0xa5a5
+0+006c <[^>]*> slt \$at,\$a0,\$at
+0+0070 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0074 <[^>]*> nop
+0+0078 <[^>]*> slt \$at,\$a1,\$a0
+0+007c <[^>]*> beqz \$at,0+0000 <text_label>
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> blez \$a0,0+0000 <text_label>
+0+0088 <[^>]*> nop
+0+008c <[^>]*> bgez \$a1,0+0000 <text_label>
+0+0090 <[^>]*> nop
+0+0094 <[^>]*> blez \$a0,0+0000 <text_label>
+0+0098 <[^>]*> nop
+0+009c <[^>]*> slt \$at,\$a0,\$a1
+0+00a0 <[^>]*> bnezl \$at,0+0000 <text_label>
+0+00a4 <[^>]*> nop
+0+00a8 <[^>]*> slt \$at,\$a1,\$a0
+0+00ac <[^>]*> beqzl \$at,0+0000 <text_label>
+ ...
diff --git a/gas/testsuite/gas/mips/blt.s b/gas/testsuite/gas/mips/blt.s
new file mode 100644
index 00000000000..000305696dd
--- /dev/null
+++ b/gas/testsuite/gas/mips/blt.s
@@ -0,0 +1,31 @@
+# Source file used to test the blt macro.
+
+text_label:
+ blt $4,$5,text_label
+ blt $4,$0,text_label
+ blt $0,$5,text_label
+ blt $4,0,text_label
+ blt $4,1,text_label
+ blt $4,2,text_label
+ blt $4,0x8000,text_label
+ blt $4,-0x8000,text_label
+ blt $4,0x10000,text_label
+ blt $4,0x1a5a5,text_label
+
+# ble is handled like blt, except when both arguments are registers.
+# Just sanity check it otherwise.
+ ble $4,$5,text_label
+ ble $4,$0,text_label
+ ble $0,$5,text_label
+ ble $4,0,text_label
+
+# Sanity test bltl and blel
+ .set mips2
+ bltl $4,$5,text_label
+ blel $4,$5,text_label
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/bltu.d b/gas/testsuite/gas/mips/bltu.d
new file mode 100644
index 00000000000..9c261c638ce
--- /dev/null
+++ b/gas/testsuite/gas/mips/bltu.d
@@ -0,0 +1,47 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS bltu
+
+# Test the bltu macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> sltu \$at,\$a0,\$a1
+0+0004 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0008 <[^>]*> nop
+0+000c <[^>]*> bne \$zero,\$a1,0+0000 <text_label>
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> beqz \$a0,0+0000 <text_label>
+0+0018 <[^>]*> nop
+0+001c <[^>]*> sltiu \$at,\$a0,2
+0+0020 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> li \$at,0x8000
+0+002c <[^>]*> sltu \$at,\$a0,\$at
+0+0030 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0034 <[^>]*> nop
+0+0038 <[^>]*> sltiu \$at,\$a0,-32768
+0+003c <[^>]*> bnez \$at,0+0000 <text_label>
+0+0040 <[^>]*> nop
+0+0044 <[^>]*> lui \$at,0x1
+0+0048 <[^>]*> sltu \$at,\$a0,\$at
+0+004c <[^>]*> bnez \$at,0+0000 <text_label>
+0+0050 <[^>]*> nop
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> ori \$at,\$at,0xa5a5
+0+005c <[^>]*> sltu \$at,\$a0,\$at
+0+0060 <[^>]*> bnez \$at,0+0000 <text_label>
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> sltu \$at,\$a1,\$a0
+0+006c <[^>]*> beqz \$at,0+0000 <text_label>
+0+0070 <[^>]*> nop
+0+0074 <[^>]*> beqz \$a0,0+0000 <text_label>
+0+0078 <[^>]*> nop
+0+007c <[^>]*> beqz \$a0,0+0000 <text_label>
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> sltu \$at,\$a0,\$a1
+0+0088 <[^>]*> bnezl \$at,0+0000 <text_label>
+0+008c <[^>]*> nop
+0+0090 <[^>]*> sltu \$at,\$a1,\$a0
+0+0094 <[^>]*> beqzl \$at,0+0000 <text_label>
+ ...
diff --git a/gas/testsuite/gas/mips/bltu.s b/gas/testsuite/gas/mips/bltu.s
new file mode 100644
index 00000000000..44b1ae629eb
--- /dev/null
+++ b/gas/testsuite/gas/mips/bltu.s
@@ -0,0 +1,27 @@
+# Source file used to test the bltu macro.
+
+text_label:
+ bltu $4,$5,text_label
+ bltu $0,$5,text_label
+ # A second argument of 0 or $0 is always false
+ bltu $4,1,text_label
+ bltu $4,2,text_label
+ bltu $4,0x8000,text_label
+ bltu $4,-0x8000,text_label
+ bltu $4,0x10000,text_label
+ bltu $4,0x1a5a5,text_label
+
+# bleu is handled like bltu, except when both arguments are registers.
+# Just sanity check it otherwise.
+ bleu $4,$5,text_label
+ bleu $4,$0,text_label
+ bleu $4,0,text_label
+
+# Sanity test bltul and bleul
+ .set mips2
+ bltul $4,$5,text_label
+ bleul $4,$5,text_label
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/break20.d b/gas/testsuite/gas/mips/break20.d
new file mode 100644
index 00000000000..4498a4cd874
--- /dev/null
+++ b/gas/testsuite/gas/mips/break20.d
@@ -0,0 +1,18 @@
+#as: -mcpu=r3900
+#objdump: -dr --prefix-addresses -mmips:3900
+#name: MIPS 20-bit break
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> break
+0+0004 <[^>]*> break
+0+0008 <[^>]*> break 0x14
+0+000c <[^>]*> break 0x14,0x28
+0+0010 <[^>]*> break 0x3ff,0x3ff
+0+0014 <[^>]*> sdbbp
+0+0018 <[^>]*> sdbbp
+0+001c <[^>]*> sdbbp 0x14
+0+0020 <[^>]*> sdbbp 0x14,0x28
+0+0024 <[^>]*> sdbbp 0x3ff,0x3ff
+ ... \ No newline at end of file
diff --git a/gas/testsuite/gas/mips/break20.s b/gas/testsuite/gas/mips/break20.s
new file mode 100644
index 00000000000..ee35b0ec1b0
--- /dev/null
+++ b/gas/testsuite/gas/mips/break20.s
@@ -0,0 +1,17 @@
+# Source file used to test the 20-bit break instructions
+foo:
+ break
+ break 0
+ break 20
+ break 20,40
+ break 1023,1023
+
+ sdbbp
+ sdbbp 0
+ sdbbp 20
+ sdbbp 20,40
+ sdbbp 1023,1023
+
+# force some padding, to make objdump consistently report that there's some
+# here...
+ .space 8
diff --git a/gas/testsuite/gas/mips/delay.d b/gas/testsuite/gas/mips/delay.d
new file mode 100644
index 00000000000..93dc0ec16b8
--- /dev/null
+++ b/gas/testsuite/gas/mips/delay.d
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS delay
+#as: -mips3 -mcpu=r4000
+
+#
+# Gas should produce nop's after mtc1 and related
+# insn's if the target fpr is used in the
+# immediatly following insn. See also nodelay.d.
+#
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> mtc1 \$zero,\$f0
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> cvt.d.w \$f0,\$f0
+0+000c <[^>]*> mtc1 \$zero,\$f1
+0+0010 <[^>]*> nop
+0+0014 <[^>]*> cvt.d.w \$f1,\$f1
+ ...
diff --git a/gas/testsuite/gas/mips/delay.s b/gas/testsuite/gas/mips/delay.s
new file mode 100644
index 00000000000..5ee2f00aaba
--- /dev/null
+++ b/gas/testsuite/gas/mips/delay.s
@@ -0,0 +1,8 @@
+# Source file used to test the abs macro.
+foo:
+ mtc1 $0,$f0
+ cvt.d.w $f0,$f0
+ mtc1 $0,$f1
+ cvt.d.w $f1,$f1
+ .space 8
+
diff --git a/gas/testsuite/gas/mips/div-ilocks.d b/gas/testsuite/gas/mips/div-ilocks.d
new file mode 100644
index 00000000000..75856d3302e
--- /dev/null
+++ b/gas/testsuite/gas/mips/div-ilocks.d
@@ -0,0 +1,110 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS div
+#source: div.s
+
+# Test the div macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> div \$zero,\$a0,\$a1
+0+0004 <[^>]*> bnez \$a1,0+0010 <foo\+0x10>
+0+0008 <[^>]*> div \$zero,\$a0,\$a1
+0+000c <[^>]*> break (0x0,0x7|0x7)
+0+0010 <[^>]*> li \$at,-1
+0+0014 <[^>]*> bne \$a1,\$at,0+0028 <foo\+0x28>
+0+0018 <[^>]*> lui \$at,0x8000
+0+001c <[^>]*> bne \$a0,\$at,0+0028 <foo\+0x28>
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> break (0x0,0x6|0x6)
+0+0028 <[^>]*> mflo \$a0
+0+002c <[^>]*> bnez \$a2,0+0038 <foo\+0x38>
+0+0030 <[^>]*> div \$zero,\$a1,\$a2
+0+0034 <[^>]*> break (0x0,0x7|0x7)
+0+0038 <[^>]*> li \$at,-1
+0+003c <[^>]*> bne \$a2,\$at,0+0050 <foo\+0x50>
+0+0040 <[^>]*> lui \$at,0x8000
+0+0044 <[^>]*> bne \$a1,\$at,0+0050 <foo\+0x50>
+0+0048 <[^>]*> nop
+0+004c <[^>]*> break (0x0,0x6|0x6)
+0+0050 <[^>]*> mflo \$a0
+0+0054 <[^>]*> move \$a0,\$a0
+0+0058 <[^>]*> move \$a0,\$a1
+0+005c <[^>]*> neg \$a0,\$a0
+0+0060 <[^>]*> neg \$a0,\$a1
+0+0064 <[^>]*> li \$at,2
+0+0068 <[^>]*> div \$zero,\$a0,\$at
+0+006c <[^>]*> mflo \$a0
+0+0070 <[^>]*> li \$at,2
+0+0074 <[^>]*> div \$zero,\$a1,\$at
+0+0078 <[^>]*> mflo \$a0
+0+007c <[^>]*> li \$at,0x8000
+0+0080 <[^>]*> div \$zero,\$a0,\$at
+0+0084 <[^>]*> mflo \$a0
+0+0088 <[^>]*> li \$at,0x8000
+0+008c <[^>]*> div \$zero,\$a1,\$at
+0+0090 <[^>]*> mflo \$a0
+0+0094 <[^>]*> li \$at,-32768
+0+0098 <[^>]*> div \$zero,\$a0,\$at
+0+009c <[^>]*> mflo \$a0
+0+00a0 <[^>]*> li \$at,-32768
+0+00a4 <[^>]*> div \$zero,\$a1,\$at
+0+00a8 <[^>]*> mflo \$a0
+0+00ac <[^>]*> lui \$at,0x1
+0+00b0 <[^>]*> div \$zero,\$a0,\$at
+0+00b4 <[^>]*> mflo \$a0
+0+00b8 <[^>]*> lui \$at,0x1
+0+00bc <[^>]*> div \$zero,\$a1,\$at
+0+00c0 <[^>]*> mflo \$a0
+0+00c4 <[^>]*> lui \$at,0x1
+0+00c8 <[^>]*> ori \$at,\$at,0xa5a5
+0+00cc <[^>]*> div \$zero,\$a0,\$at
+0+00d0 <[^>]*> mflo \$a0
+0+00d4 <[^>]*> lui \$at,0x1
+0+00d8 <[^>]*> ori \$at,\$at,0xa5a5
+0+00dc <[^>]*> div \$zero,\$a1,\$at
+0+00e0 <[^>]*> mflo \$a0
+0+00e4 <[^>]*> divu \$zero,\$a0,\$a1
+0+00e8 <[^>]*> bnez \$a1,0+0f4 <foo\+0xf4>
+0+00ec <[^>]*> divu \$zero,\$a0,\$a1
+0+00f0 <[^>]*> break (0x0,0x7|0x7)
+0+00f4 <[^>]*> mflo \$a0
+0+00f8 <[^>]*> bnez \$a2,0+0104 <foo\+0x104>
+0+00fc <[^>]*> divu \$zero,\$a1,\$a2
+0+0100 <[^>]*> break (0x0,0x7|0x7)
+0+0104 <[^>]*> mflo \$a0
+0+0108 <[^>]*> move \$a0,\$a0
+0+010c <[^>]*> bnez \$a2,0+0118 <foo\+0x118>
+0+0110 <[^>]*> div \$zero,\$a1,\$a2
+0+0114 <[^>]*> break (0x0,0x7|0x7)
+0+0118 <[^>]*> li \$at,-1
+0+011c <[^>]*> bne \$a2,\$at,0+0130 <foo\+0x130>
+0+0120 <[^>]*> lui \$at,0x8000
+0+0124 <[^>]*> bne \$a1,\$at,0+0130 <foo\+0x130>
+0+0128 <[^>]*> nop
+0+012c <[^>]*> break (0x0,0x6|0x6)
+0+0130 <[^>]*> mfhi \$a0
+0+0134 <[^>]*> li \$at,2
+0+0138 <[^>]*> divu \$zero,\$a1,\$at
+0+013c <[^>]*> mfhi \$a0
+0+0140 <[^>]*> bnez \$a2,0+014c <foo\+0x14c>
+0+0144 <[^>]*> ddiv \$zero,\$a1,\$a2
+0+0148 <[^>]*> break (0x0,0x7|0x7)
+0+014c <[^>]*> daddiu \$at,\$zero,-1
+0+0150 <[^>]*> bne \$a2,\$at,0+0168 <foo\+0x168>
+0+0154 <[^>]*> daddiu \$at,\$zero,1
+0+0158 <[^>]*> dsll32 \$at,\$at,0x1f
+0+015c <[^>]*> bne \$a1,\$at,0+0168 <foo\+0x168>
+0+0160 <[^>]*> nop
+0+0164 <[^>]*> break (0x0,0x6|0x6)
+0+0168 <[^>]*> mflo \$a0
+0+016c <[^>]*> li \$at,2
+0+0170 <[^>]*> ddivu \$zero,\$a1,\$at
+0+0174 <[^>]*> mflo \$a0
+0+0178 <[^>]*> li \$at,0x8000
+0+017c <[^>]*> ddiv \$zero,\$a1,\$at
+0+0180 <[^>]*> mfhi \$a0
+0+0184 <[^>]*> li \$at,-32768
+0+0188 <[^>]*> ddivu \$zero,\$a1,\$at
+0+018c <[^>]*> mfhi \$a0
+ ...
diff --git a/gas/testsuite/gas/mips/div.d b/gas/testsuite/gas/mips/div.d
new file mode 100644
index 00000000000..fec5bb2c59b
--- /dev/null
+++ b/gas/testsuite/gas/mips/div.d
@@ -0,0 +1,125 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#as: -mcpu=r4000
+#name: MIPS div
+
+# Test the div macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> div \$zero,\$a0,\$a1
+0+0004 <[^>]*> bnez \$a1,0+0010 <foo\+0x10>
+0+0008 <[^>]*> div \$zero,\$a0,\$a1
+0+000c <[^>]*> break (0x0,0x7|0x7)
+0+0010 <[^>]*> li \$at,-1
+0+0014 <[^>]*> bne \$a1,\$at,0+0028 <foo\+0x28>
+0+0018 <[^>]*> lui \$at,0x8000
+0+001c <[^>]*> bne \$a0,\$at,0+0028 <foo\+0x28>
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> break (0x0,0x6|0x6)
+0+0028 <[^>]*> mflo \$a0
+0+002c <[^>]*> nop
+0+0030 <[^>]*> bnez \$a2,0+003c <foo\+0x3c>
+0+0034 <[^>]*> div \$zero,\$a1,\$a2
+0+0038 <[^>]*> break (0x0,0x7|0x7)
+0+003c <[^>]*> li \$at,-1
+0+0040 <[^>]*> bne \$a2,\$at,0+0054 <foo\+0x54>
+0+0044 <[^>]*> lui \$at,0x8000
+0+0048 <[^>]*> bne \$a1,\$at,0+0054 <foo\+0x54>
+0+004c <[^>]*> nop
+0+0050 <[^>]*> break (0x0,0x6|0x6)
+0+0054 <[^>]*> mflo \$a0
+0+0058 <[^>]*> move \$a0,\$a0
+0+005c <[^>]*> move \$a0,\$a1
+0+0060 <[^>]*> neg \$a0,\$a0
+0+0064 <[^>]*> neg \$a0,\$a1
+0+0068 <[^>]*> li \$at,2
+0+006c <[^>]*> div \$zero,\$a0,\$at
+0+0070 <[^>]*> mflo \$a0
+0+0074 <[^>]*> li \$at,2
+0+0078 <[^>]*> nop
+0+007c <[^>]*> div \$zero,\$a1,\$at
+0+0080 <[^>]*> mflo \$a0
+0+0084 <[^>]*> li \$at,0x8000
+0+0088 <[^>]*> nop
+0+008c <[^>]*> div \$zero,\$a0,\$at
+0+0090 <[^>]*> mflo \$a0
+0+0094 <[^>]*> li \$at,0x8000
+0+0098 <[^>]*> nop
+0+009c <[^>]*> div \$zero,\$a1,\$at
+0+00a0 <[^>]*> mflo \$a0
+0+00a4 <[^>]*> li \$at,-32768
+0+00a8 <[^>]*> nop
+0+00ac <[^>]*> div \$zero,\$a0,\$at
+0+00b0 <[^>]*> mflo \$a0
+0+00b4 <[^>]*> li \$at,-32768
+0+00b8 <[^>]*> nop
+0+00bc <[^>]*> div \$zero,\$a1,\$at
+0+00c0 <[^>]*> mflo \$a0
+0+00c4 <[^>]*> lui \$at,0x1
+0+00c8 <[^>]*> nop
+0+00cc <[^>]*> div \$zero,\$a0,\$at
+0+00d0 <[^>]*> mflo \$a0
+0+00d4 <[^>]*> lui \$at,0x1
+0+00d8 <[^>]*> nop
+0+00dc <[^>]*> div \$zero,\$a1,\$at
+0+00e0 <[^>]*> mflo \$a0
+0+00e4 <[^>]*> lui \$at,0x1
+0+00e8 <[^>]*> ori \$at,\$at,0xa5a5
+0+00ec <[^>]*> div \$zero,\$a0,\$at
+0+00f0 <[^>]*> mflo \$a0
+0+00f4 <[^>]*> lui \$at,0x1
+0+00f8 <[^>]*> ori \$at,\$at,0xa5a5
+0+00fc <[^>]*> div \$zero,\$a1,\$at
+0+0100 <[^>]*> mflo \$a0
+ ...
+0+010c <[^>]*> divu \$zero,\$a0,\$a1
+0+0110 <[^>]*> bnez \$a1,0+011c <foo\+0x11c>
+0+0114 <[^>]*> divu \$zero,\$a0,\$a1
+0+0118 <[^>]*> break (0x0,0x7|0x7)
+0+011c <[^>]*> mflo \$a0
+0+0120 <[^>]*> nop
+0+0124 <[^>]*> bnez \$a2,0+0130 <foo\+0x130>
+0+0128 <[^>]*> divu \$zero,\$a1,\$a2
+0+012c <[^>]*> break (0x0,0x7|0x7)
+0+0130 <[^>]*> mflo \$a0
+0+0134 <[^>]*> move \$a0,\$a0
+0+0138 <[^>]*> bnez \$a2,0+0144 <foo\+0x144>
+0+013c <[^>]*> div \$zero,\$a1,\$a2
+0+0140 <[^>]*> break (0x0,0x7|0x7)
+0+0144 <[^>]*> li \$at,-1
+0+0148 <[^>]*> bne \$a2,\$at,0+015c <foo\+0x15c>
+0+014c <[^>]*> lui \$at,0x8000
+0+0150 <[^>]*> bne \$a1,\$at,0+015c <foo\+0x15c>
+0+0154 <[^>]*> nop
+0+0158 <[^>]*> break (0x0,0x6|0x6)
+0+015c <[^>]*> mfhi \$a0
+0+0160 <[^>]*> li \$at,2
+0+0164 <[^>]*> nop
+0+0168 <[^>]*> divu \$zero,\$a1,\$at
+0+016c <[^>]*> mfhi \$a0
+0+0170 <[^>]*> nop
+0+0174 <[^>]*> bnez \$a2,0+0180 <foo\+0x180>
+0+0178 <[^>]*> ddiv \$zero,\$a1,\$a2
+0+017c <[^>]*> break (0x0,0x7|0x7)
+0+0180 <[^>]*> daddiu \$at,\$zero,-1
+0+0184 <[^>]*> bne \$a2,\$at,0+019c <foo\+0x19c>
+0+0188 <[^>]*> daddiu \$at,\$zero,1
+0+018c <[^>]*> dsll32 \$at,\$at,0x1f
+0+0190 <[^>]*> bne \$a1,\$at,0+019c <foo\+0x19c>
+0+0194 <[^>]*> nop
+0+0198 <[^>]*> break (0x0,0x6|0x6)
+0+019c <[^>]*> mflo \$a0
+0+01a0 <[^>]*> li \$at,2
+0+01a4 <[^>]*> nop
+0+01a8 <[^>]*> ddivu \$zero,\$a1,\$at
+0+01ac <[^>]*> mflo \$a0
+0+01b0 <[^>]*> li \$at,0x8000
+0+01b4 <[^>]*> nop
+0+01b8 <[^>]*> ddiv \$zero,\$a1,\$at
+0+01bc <[^>]*> mfhi \$a0
+0+01c0 <[^>]*> li \$at,-32768
+0+01c4 <[^>]*> nop
+0+01c8 <[^>]*> ddivu \$zero,\$a1,\$at
+0+01cc <[^>]*> mfhi \$a0
+ ...
diff --git a/gas/testsuite/gas/mips/div.s b/gas/testsuite/gas/mips/div.s
new file mode 100644
index 00000000000..6d9990672de
--- /dev/null
+++ b/gas/testsuite/gas/mips/div.s
@@ -0,0 +1,41 @@
+# Source file used to test the div macro.
+foo:
+ div $0,$4,$5
+ div $4,$5
+ div $4,$5,$6
+ div $4,1
+ div $4,$5,1
+ div $4,-1
+ div $4,$5,-1
+ div $4,2
+ div $4,$5,2
+ div $4,0x8000
+ div $4,$5,0x8000
+ div $4,-0x8000
+ div $4,$5,-0x8000
+ div $4,0x10000
+ div $4,$5,0x10000
+ div $4,0x1a5a5
+ div $4,$5,0x1a5a5
+
+# divu is like div, except when both arguments are registers.
+# Just sanity check it otherwise.
+ divu $0,$4,$5
+ divu $4,$5
+ divu $4,$5,$6
+ divu $4,1
+
+# rem is like div, remu is like divu
+ rem $4,$5,$6
+ remu $4,$5,2
+
+# Sanity check the 64 bit versions.
+ .set mips3
+ ddiv $4,$5,$6
+ ddivu $4,$5,2
+ drem $4,$5,0x8000
+ dremu $4,$5,-0x8000
+
+# force some padding, to make objdump consistently report that there's some
+# here...
+ .space 8
diff --git a/gas/testsuite/gas/mips/dli.d b/gas/testsuite/gas/mips/dli.d
new file mode 100644
index 00000000000..72b445e2b16
--- /dev/null
+++ b/gas/testsuite/gas/mips/dli.d
@@ -0,0 +1,115 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS dli
+#as: -mips3
+
+# Test the dli macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> li \$a0,0
+0+0004 <[^>]*> li \$a0,1
+0+0008 <[^>]*> li \$a0,-1
+0+000c <[^>]*> li \$a0,0x8000
+0+0010 <[^>]*> li \$a0,-32768
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> lui \$a0,0x1
+0+001c <[^>]*> ori \$a0,\$a0,0xa5a5
+0+0020 <[^>]*> li \$a0,0x8000
+0+0024 <[^>]*> dsll \$a0,\$a0,0x10
+0+0028 <[^>]*> ori \$a0,\$a0,0x1234
+0+002c <[^>]*> lui \$a0,0xffff
+0+0030 <[^>]*> dsrl32 \$a0,\$a0,0x0
+0+0034 <[^>]*> lui \$a0,0xffff
+0+0038 <[^>]*> dsrl32 \$a0,\$a0,0x0
+0+003c <[^>]*> li \$a0,-1
+0+0040 <[^>]*> li \$a0,-1
+0+0044 <[^>]*> dsrl \$a0,\$a0,0xc
+0+0048 <[^>]*> lui \$a0,0x8000
+0+004c <[^>]*> ori \$a0,\$a0,0x1234
+0+0050 <[^>]*> li \$a0,-32768
+0+0054 <[^>]*> dsll \$a0,\$a0,0x10
+0+0058 <[^>]*> ori \$a0,\$a0,0x1234
+0+005c <[^>]*> dsll \$a0,\$a0,0x10
+0+0060 <[^>]*> ori \$a0,\$a0,0x5678
+0+0064 <[^>]*> lui \$a0,0x8000
+0+0068 <[^>]*> ori \$a0,\$a0,0x1234
+0+006c <[^>]*> dsll \$a0,\$a0,0x10
+0+0070 <[^>]*> ori \$a0,\$a0,0x5678
+0+0074 <[^>]*> dsll \$a0,\$a0,0x10
+0+0078 <[^>]*> li \$a0,-30875
+0+007c <[^>]*> lui \$a0,0xffff
+0+0080 <[^>]*> ori \$a0,\$a0,0x4321
+0+0084 <[^>]*> li \$a0,-16
+0+0088 <[^>]*> li \$a0,-256
+0+008c <[^>]*> li \$a0,-4096
+0+0090 <[^>]*> lui \$a0,0xffff
+0+0094 <[^>]*> lui \$a0,0xfff0
+0+0098 <[^>]*> lui \$a0,0xff00
+0+009c <[^>]*> lui \$a0,0xf000
+0+00a0 <[^>]*> li \$a0,-1
+0+00a4 <[^>]*> dsll32 \$a0,\$a0,0x0
+0+00a8 <[^>]*> li \$a0,-16
+0+00ac <[^>]*> dsll32 \$a0,\$a0,0x0
+0+00b0 <[^>]*> li \$a0,-256
+0+00b4 <[^>]*> dsll32 \$a0,\$a0,0x0
+0+00b8 <[^>]*> li \$a0,-4096
+0+00bc <[^>]*> dsll32 \$a0,\$a0,0x0
+0+00c0 <[^>]*> li \$a0,0xffff
+0+00c4 <[^>]*> dsll32 \$a0,\$a0,0x10
+0+00c8 <[^>]*> li \$a0,0xfff0
+0+00cc <[^>]*> dsll32 \$a0,\$a0,0x10
+0+00d0 <[^>]*> li \$a0,0xff00
+0+00d4 <[^>]*> dsll32 \$a0,\$a0,0x10
+0+00d8 <[^>]*> li \$a0,0xf000
+0+00dc <[^>]*> dsll32 \$a0,\$a0,0x10
+0+00e0 <[^>]*> li \$a0,-1
+0+00e4 <[^>]*> dsrl \$a0,\$a0,0x4
+0+00e8 <[^>]*> li \$a0,-1
+0+00ec <[^>]*> dsrl \$a0,\$a0,0x8
+0+00f0 <[^>]*> li \$a0,-1
+0+00f4 <[^>]*> dsrl \$a0,\$a0,0xc
+0+00f8 <[^>]*> li \$a0,-1
+0+00fc <[^>]*> dsrl \$a0,\$a0,0x10
+0+0100 <[^>]*> li \$a0,-1
+0+0104 <[^>]*> dsrl \$a0,\$a0,0x14
+0+0108 <[^>]*> li \$a0,-1
+0+010c <[^>]*> dsrl \$a0,\$a0,0x18
+0+0110 <[^>]*> li \$a0,-1
+0+0114 <[^>]*> dsrl \$a0,\$a0,0x1c
+0+0118 <[^>]*> lui \$a0,0xffff
+0+011c <[^>]*> dsrl32 \$a0,\$a0,0x0
+0+0120 <[^>]*> lui \$a0,0xfff
+0+0124 <[^>]*> ori \$a0,\$a0,0xffff
+0+0128 <[^>]*> lui \$a0,0xff
+0+012c <[^>]*> ori \$a0,\$a0,0xffff
+0+0130 <[^>]*> lui \$a0,0xf
+0+0134 <[^>]*> ori \$a0,\$a0,0xffff
+0+0138 <[^>]*> li \$a0,0xffff
+0+013c <[^>]*> li \$a0,4095
+0+0140 <[^>]*> li \$a0,255
+0+0144 <[^>]*> li \$a0,15
+0+0148 <[^>]*> lui \$a0,0x3
+0+014c <[^>]*> ori \$a0,\$a0,0xfffc
+0+0150 <[^>]*> li \$a0,0xffff
+0+0154 <[^>]*> dsll \$a0,\$a0,0x1e
+0+0158 <[^>]*> li \$a0,0xffff
+0+015c <[^>]*> dsll32 \$a0,\$a0,0x2
+0+0160 <[^>]*> li \$a0,0xffff
+0+0164 <[^>]*> dsll32 \$a0,\$a0,0x6
+0+0168 <[^>]*> li \$a0,-1
+0+016c <[^>]*> dsll32 \$a0,\$a0,0x0
+0+0170 <[^>]*> dsrl \$a0,\$a0,0xa
+0+0174 <[^>]*> li \$a0,-1
+0+0178 <[^>]*> dsll \$a0,\$a0,0x1c
+0+017c <[^>]*> dsrl \$a0,\$a0,0xa
+0+0180 <[^>]*> li \$a0,-1
+0+0184 <[^>]*> dsll \$a0,\$a0,0x18
+0+0188 <[^>]*> dsrl \$a0,\$a0,0xa
+0+018c <[^>]*> lui \$a0,0x3f
+0+0190 <[^>]*> ori \$a0,\$a0,0xfc03
+0+0194 <[^>]*> dsll \$a0,\$a0,0x10
+0+0198 <[^>]*> ori \$a0,\$a0,0xffff
+0+019c <[^>]*> dsll \$a0,\$a0,0x10
+0+01a0 <[^>]*> ori \$a0,\$a0,0xc000
+ ...
diff --git a/gas/testsuite/gas/mips/dli.s b/gas/testsuite/gas/mips/dli.s
new file mode 100644
index 00000000000..6579528f174
--- /dev/null
+++ b/gas/testsuite/gas/mips/dli.s
@@ -0,0 +1,67 @@
+# Source file used to test the dli macro.
+
+foo:
+ dli $4,0
+ dli $4,1
+ dli $4,-1
+ dli $4,0x8000
+ dli $4,-0x8000
+ dli $4,0x10000
+ dli $4,0x1a5a5
+ dli $4,0x80001234
+ dli $4,0xffffffff
+ dli $4,0x00000000ffffffff
+ dli $4,0xffffffffffffffff
+ dli $4,0x000fffffffffffff
+ dli $4,0xffffffff80001234
+ dli $4,0xffff800012345678
+ dli $4,0x8000123456780000
+ dli $4,0xffffffffffff8765
+ dli $4,0xffffffffffff4321
+
+ dli $4,0xfffffffffffffff0
+ dli $4,0xffffffffffffff00
+ dli $4,0xfffffffffffff000
+ dli $4,0xffffffffffff0000
+ dli $4,0xfffffffffff00000
+ dli $4,0xffffffffff000000
+ dli $4,0xfffffffff0000000
+ dli $4,0xffffffff00000000
+ dli $4,0xfffffff000000000
+ dli $4,0xffffff0000000000
+ dli $4,0xfffff00000000000
+ dli $4,0xffff000000000000
+ dli $4,0xfff0000000000000
+ dli $4,0xff00000000000000
+ dli $4,0xf000000000000000
+
+ dli $4,0x0fffffffffffffff
+ dli $4,0x00ffffffffffffff
+ dli $4,0x000fffffffffffff
+ dli $4,0x0000ffffffffffff
+ dli $4,0x00000fffffffffff
+ dli $4,0x000000ffffffffff
+ dli $4,0x0000000fffffffff
+ dli $4,0x00000000ffffffff
+ dli $4,0x000000000fffffff
+ dli $4,0x0000000000ffffff
+ dli $4,0x00000000000fffff
+ dli $4,0x000000000000ffff
+ dli $4,0x0000000000000fff
+ dli $4,0x00000000000000ff
+ dli $4,0x000000000000000f
+
+ dli $4,0x000000000003fffc
+ dli $4,0x00003fffc0000000
+ dli $4,0x0003fffc00000000
+ dli $4,0x003fffc000000000
+ dli $4,0x003fffffffc00000
+ dli $4,0x003ffffffffc0000
+ dli $4,0x003fffffffffc000
+
+ dli $4,0x003ffc03ffffc000
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/elf_e_flags.c b/gas/testsuite/gas/mips/elf_e_flags.c
new file mode 100644
index 00000000000..17fb1110c8e
--- /dev/null
+++ b/gas/testsuite/gas/mips/elf_e_flags.c
@@ -0,0 +1,24 @@
+/* This file isn't directly used by the test suite; it uses
+ elf_e_flags.s. However, I figured it would be nice to provide the
+ source code from which the .s file was generated.
+
+ It was compiled as follows:
+
+ mips64-elf-gcc -m4650 -S -O elf_e_flags.c
+
+ We use the -m4650 flag to get the 4650-specific 'mul' instruction
+ in there; the test suite wants to be sure that GAS's -m4650 flag
+ will indeed cause it to generate the 4650 mul instruction, and not
+ expand it as a macro. */
+
+int
+foo (int a, int b)
+{
+ return (a * b) + 1;
+}
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/gas/testsuite/gas/mips/elf_e_flags.s b/gas/testsuite/gas/mips/elf_e_flags.s
new file mode 100644
index 00000000000..5fc32eafd12
--- /dev/null
+++ b/gas/testsuite/gas/mips/elf_e_flags.s
@@ -0,0 +1,43 @@
+ .file 1 "elf_e_flags.c"
+gcc2_compiled.:
+__gnu_compiled_c:
+ .text
+ .align 2
+ .globl foo
+ .text
+ .ent foo
+foo:
+ .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, extra= 0
+ .mask 0x00000000,0
+ .fmask 0x00000000,0
+ mul $2,$4,$5
+ .set noreorder
+ .set nomacro
+ j $31
+ addu $2,$2,1
+ .set macro
+ .set reorder
+
+ .end foo
+ .align 2
+ .globl main
+ .text
+ .ent main
+main:
+ .frame $sp,40,$31 # vars= 0, regs= 1/0, args= 32, extra= 0
+ .mask 0x80000000,-8
+ .fmask 0x00000000,0
+ subu $sp,$sp,40
+ sd $31,32($sp)
+ jal __gccmain
+ move $2,$0
+ ld $31,32($sp)
+ #nop
+ .set noreorder
+ .set nomacro
+ j $31
+ addu $sp,$sp,40
+ .set macro
+ .set reorder
+
+ .end main
diff --git a/gas/testsuite/gas/mips/elf_e_flags1.d b/gas/testsuite/gas/mips/elf_e_flags1.d
new file mode 100644
index 00000000000..6faa7c10320
--- /dev/null
+++ b/gas/testsuite/gas/mips/elf_e_flags1.d
@@ -0,0 +1,26 @@
+# name: ELF e_flags: nothing special
+# source: elf_e_flags.s
+# objdump: -fd
+
+.*:.*file format.*mips.*
+architecture: mips:4000, flags 0x00000011:
+HAS_RELOC, HAS_SYMS
+start address 0x0000000000000000
+
+Disassembly of section .text:
+
+0000000000000000 <foo>:
+ 0: 00850019 multu \$a0,\$a1
+ 4: 00001012 mflo \$v0
+ 8: 03e00008 jr \$ra
+ c: 24420001 addiu \$v0,\$v0,1
+
+0000000000000010 <main>:
+ 10: 27bdffd8 addiu \$sp,\$sp,-40
+ 14: ffbf0020 sd \$ra,32\(\$sp\)
+ 18: 0c000000 jal 0 <foo>
+ 1c: 00000000 nop
+ 20: 0000102d move \$v0,\$zero
+ 24: dfbf0020 ld \$ra,32\(\$sp\)
+ 28: 03e00008 jr \$ra
+ 2c: 27bd0028 addiu \$sp,\$sp,40
diff --git a/gas/testsuite/gas/mips/elf_e_flags2.d b/gas/testsuite/gas/mips/elf_e_flags2.d
new file mode 100644
index 00000000000..50661c2f962
--- /dev/null
+++ b/gas/testsuite/gas/mips/elf_e_flags2.d
@@ -0,0 +1,26 @@
+# name: ELF e_flags: -m4650
+# source: elf_e_flags.s
+# as: -m4650
+# objdump: -fd
+
+.*:.*file format.*mips.*
+architecture: mips:4650, flags 0x00000011:
+HAS_RELOC, HAS_SYMS
+start address 0x0000000000000000
+
+Disassembly of section .text:
+
+0000000000000000 <foo>:
+ 0: 70851002 mul \$v0,\$a0,\$a1
+ 4: 03e00008 jr \$ra
+ 8: 24420001 addiu \$v0,\$v0,1
+
+000000000000000c <main>:
+ c: 27bdffd8 addiu \$sp,\$sp,-40
+ 10: ffbf0020 sd \$ra,32\(\$sp\)
+ 14: 0c000000 jal 0 <foo>
+ 18: 00000000 nop
+ 1c: 0000102d move \$v0,\$zero
+ 20: dfbf0020 ld \$ra,32\(\$sp\)
+ 24: 03e00008 jr \$ra
+ 28: 27bd0028 addiu \$sp,\$sp,40
diff --git a/gas/testsuite/gas/mips/elf_e_flags3.d b/gas/testsuite/gas/mips/elf_e_flags3.d
new file mode 100644
index 00000000000..aacc49e40df
--- /dev/null
+++ b/gas/testsuite/gas/mips/elf_e_flags3.d
@@ -0,0 +1,26 @@
+# name: ELF e_flags: -mcpu=4650
+# source: elf_e_flags.s
+# as: -mcpu=4650
+# objdump: -fd
+
+.*:.*file format.*mips.*
+architecture: mips:4650, flags 0x00000011:
+HAS_RELOC, HAS_SYMS
+start address 0x0000000000000000
+
+Disassembly of section .text:
+
+0000000000000000 <foo>:
+ 0: 70851002 mul \$v0,\$a0,\$a1
+ 4: 03e00008 jr \$ra
+ 8: 24420001 addiu \$v0,\$v0,1
+
+000000000000000c <main>:
+ c: 27bdffd8 addiu \$sp,\$sp,-40
+ 10: ffbf0020 sd \$ra,32\(\$sp\)
+ 14: 0c000000 jal 0 <foo>
+ 18: 00000000 nop
+ 1c: 0000102d move \$v0,\$zero
+ 20: dfbf0020 ld \$ra,32\(\$sp\)
+ 24: 03e00008 jr \$ra
+ 28: 27bd0028 addiu \$sp,\$sp,40
diff --git a/gas/testsuite/gas/mips/elf_e_flags4.d b/gas/testsuite/gas/mips/elf_e_flags4.d
new file mode 100644
index 00000000000..5eb70508a2b
--- /dev/null
+++ b/gas/testsuite/gas/mips/elf_e_flags4.d
@@ -0,0 +1,26 @@
+# name: ELF e_flags: -m4650 -mcpu=4650
+# source: elf_e_flags.s
+# as: -m4650 -mcpu=4650
+# objdump: -fd
+
+.*:.*file format.*mips.*
+architecture: mips:4650, flags 0x00000011:
+HAS_RELOC, HAS_SYMS
+start address 0x0000000000000000
+
+Disassembly of section .text:
+
+0000000000000000 <foo>:
+ 0: 70851002 mul \$v0,\$a0,\$a1
+ 4: 03e00008 jr \$ra
+ 8: 24420001 addiu \$v0,\$v0,1
+
+000000000000000c <main>:
+ c: 27bdffd8 addiu \$sp,\$sp,-40
+ 10: ffbf0020 sd \$ra,32\(\$sp\)
+ 14: 0c000000 jal 0 <foo>
+ 18: 00000000 nop
+ 1c: 0000102d move \$v0,\$zero
+ 20: dfbf0020 ld \$ra,32\(\$sp\)
+ 24: 03e00008 jr \$ra
+ 28: 27bd0028 addiu \$sp,\$sp,40
diff --git a/gas/testsuite/gas/mips/itbl b/gas/testsuite/gas/mips/itbl
new file mode 100644
index 00000000000..30f8a79f60c
--- /dev/null
+++ b/gas/testsuite/gas/mips/itbl
@@ -0,0 +1,19 @@
+
+ ; Test case for assembler option "itbl".
+ ; Run as "as --itbl itbl itbl.s"
+ ; or with stand-alone test case "itbl-test itbl itbl.s".
+ ; Here, the processors represent mips coprocessors.
+
+ p1 dreg d1 1 ; data register "d1" for COP1 has value 1
+ p1 creg c3 3 ; ctrl register "c3" for COP1 has value 3
+ p3 insn fie 0x1e:24-20 ; function "fill" for COP3 has value 31
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 insn fee 0x1e:24-20,dreg:17-13,creg:12-8,immed:7-0
+
+ p3 dreg d3 3 ; data register "d3" for COP3 has value 3
+ p3 creg c2 22 ; control register "c2" for COP3 has value 22
+ p3 insn fum 0x01e00001 dreg:17-13 creg:12-8
+ p3 insn foh 0xf:24-21 dreg:20-16 immed:15-0
+
+ p3 insn pig 0x1:24-21*[0x100|0x2], dreg:20-16, immed:15-0*0x10000
diff --git a/gas/testsuite/gas/mips/itbl.s b/gas/testsuite/gas/mips/itbl.s
new file mode 100644
index 00000000000..085545be1cb
--- /dev/null
+++ b/gas/testsuite/gas/mips/itbl.s
@@ -0,0 +1,18 @@
+
+ ; Test case for assembler option "itbl".
+ ; Run as "as --itbl itbl itbl.s"
+ ; or with stand-alone test case "itbl-test itbl itbl.s".
+
+ ; Call mips coprocessor "cofun"s as defined in "itbl".
+
+ fee $d3,$c2,0x1 ; 0x4ff07601
+ fie ; 0x4ff00000
+ foh $2,0x100
+ fum $d3,$c2 ; 0x4ff07601
+ pig $2,0x100
+
+ ; Call a mips coprocessor instruction with register "d1"
+ ; defined in "itbl".
+
+ LWC1 $d1,0x100($2)
+
diff --git a/gas/testsuite/gas/mips/jal-empic.d b/gas/testsuite/gas/mips/jal-empic.d
new file mode 100644
index 00000000000..c46ccfacc77
--- /dev/null
+++ b/gas/testsuite/gas/mips/jal-empic.d
@@ -0,0 +1,26 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS jal-empic
+#as: -mips1 -membedded-pic
+#source: jal.s
+
+# Test the jal macro with -membedded-pic.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> jalr \$t9
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> jalr \$a0,\$t9
+0+000c <[^>]*> nop
+0+0010 <[^>]*> bal 0+0000 <text_label>
+[ ]*10: PCREL16 .text
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> bal 0+0018 <text_label\+(0x|)18>
+[ ]*18: PCREL16 external_text_label
+0+001c <[^>]*> nop
+0+0020 <[^>]*> b 0+0000 <text_label>
+[ ]*20: PCREL16 .text
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> b 0+0028 <text_label\+(0x|)28>
+[ ]*28: PCREL16 external_text_label
+0+002c <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/jal-svr4pic.d b/gas/testsuite/gas/mips/jal-svr4pic.d
new file mode 100644
index 00000000000..b15be76248d
--- /dev/null
+++ b/gas/testsuite/gas/mips/jal-svr4pic.d
@@ -0,0 +1,39 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS R3000 jal-svr4pic
+#as: -mips1 -KPIC -mcpu=r3000
+
+# Test the jal macro with -KPIC.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lui \$gp,0x0
+[ ]*0: R_MIPS_HI16 _gp_disp
+0+0004 <[^>]*> addiu \$gp,\$gp,0
+[ ]*4: R_MIPS_LO16 _gp_disp
+0+0008 <[^>]*> addu \$gp,\$gp,\$t9
+0+000c <[^>]*> sw \$gp,0\(\$sp\)
+0+0010 <[^>]*> jalr \$t9
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> lw \$gp,0\(\$sp\)
+0+001c <[^>]*> jalr \$a0,\$t9
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> lw \$gp,0\(\$sp\)
+0+0028 <[^>]*> nop
+0+002c <[^>]*> lw \$t9,0\(\$gp\)
+[ ]*2c: R_MIPS_GOT16 .text
+0+0030 <[^>]*> nop
+0+0034 <[^>]*> addiu \$t9,\$t9,0
+[ ]*34: R_MIPS_LO16 .text
+0+0038 <[^>]*> jalr \$t9
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lw \$gp,0\(\$sp\)
+0+0044 <[^>]*> nop
+0+0048 <[^>]*> lw \$t9,0\(\$gp\)
+[ ]*48: R_MIPS_CALL16 external_text_label
+0+004c <[^>]*> nop
+0+0050 <[^>]*> jalr \$t9
+0+0054 <[^>]*> nop
+0+0058 <[^>]*> lw \$gp,0\(\$sp\)
+0+005c <[^>]*> b 0+0000 <text_label>
+ ...
diff --git a/gas/testsuite/gas/mips/jal-svr4pic.s b/gas/testsuite/gas/mips/jal-svr4pic.s
new file mode 100644
index 00000000000..9d89dfa50ff
--- /dev/null
+++ b/gas/testsuite/gas/mips/jal-svr4pic.s
@@ -0,0 +1,20 @@
+# Source file used to test the jal macro with -KPIC code.
+
+text_label:
+ .set noreorder
+ .cpload $25
+ .set reorder
+ .cprestore 0
+ jal $25
+ jal $4,$25
+ jal text_label
+ jal external_text_label
+
+# Test j as well
+ j text_label
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/jal-xgot.d b/gas/testsuite/gas/mips/jal-xgot.d
new file mode 100644
index 00000000000..a26dca38b23
--- /dev/null
+++ b/gas/testsuite/gas/mips/jal-xgot.d
@@ -0,0 +1,42 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS R3000 jal-xgot
+#as: -mips1 -KPIC -xgot -mcpu=r3000
+#source: jal-svr4pic.s
+
+# Test the jal macro with -KPIC -xgot.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lui \$gp,0x0
+[ ]*0: R_MIPS_HI16 _gp_disp
+0+0004 <[^>]*> addiu \$gp,\$gp,0
+[ ]*4: R_MIPS_LO16 _gp_disp
+0+0008 <[^>]*> addu \$gp,\$gp,\$t9
+0+000c <[^>]*> sw \$gp,0\(\$sp\)
+0+0010 <[^>]*> jalr \$t9
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> lw \$gp,0\(\$sp\)
+0+001c <[^>]*> jalr \$a0,\$t9
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> lw \$gp,0\(\$sp\)
+0+0028 <[^>]*> nop
+0+002c <[^>]*> lw \$t9,0\(\$gp\)
+[ ]*2c: R_MIPS_GOT16 .text
+0+0030 <[^>]*> nop
+0+0034 <[^>]*> addiu \$t9,\$t9,0
+[ ]*34: R_MIPS_LO16 .text
+0+0038 <[^>]*> jalr \$t9
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lw \$gp,0\(\$sp\)
+0+0044 <[^>]*> lui \$t9,0x0
+[ ]*44: R_MIPS_CALL_HI16 external_text_label
+0+0048 <[^>]*> addu \$t9,\$t9,\$gp
+0+004c <[^>]*> lw \$t9,0\(\$t9\)
+[ ]*4c: R_MIPS_CALL_LO16 external_text_label
+0+0050 <[^>]*> nop
+0+0054 <[^>]*> jalr \$t9
+0+0058 <[^>]*> nop
+0+005c <[^>]*> lw \$gp,0\(\$sp\)
+0+0060 <[^>]*> b 0+0000 <text_label>
+ ...
diff --git a/gas/testsuite/gas/mips/jal.d b/gas/testsuite/gas/mips/jal.d
new file mode 100644
index 00000000000..b7b586f212a
--- /dev/null
+++ b/gas/testsuite/gas/mips/jal.d
@@ -0,0 +1,24 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS jal
+
+# Test the jal macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> jalr \$t9
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> jalr \$a0,\$t9
+0+000c <[^>]*> nop
+0+0010 <[^>]*> jal 0+ <text_label>
+[ ]*10: (MIPS_JMP|MIPS_JMP|JMPADDR|R_MIPS_26) .text
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> jal 0+ <text_label>
+[ ]*18: (MIPS_JMP|JMPADDR|R_MIPS_26) external_text_label
+0+001c <[^>]*> nop
+0+0020 <[^>]*> j 0+ <text_label>
+[ ]*20: (MIPS_JMP|JMPADDR|R_MIPS_26) .text
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> j 0+ <text_label>
+[ ]*28: (MIPS_JMP|JMPADDR|R_MIPS_26) external_text_label
+0+002c <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/jal.s b/gas/testsuite/gas/mips/jal.s
new file mode 100644
index 00000000000..379be9502a8
--- /dev/null
+++ b/gas/testsuite/gas/mips/jal.s
@@ -0,0 +1,11 @@
+# Source file used to test the jal macro.
+ .globl text_label .text
+text_label:
+ jal $25
+ jal $4,$25
+ jal text_label
+ jal external_text_label
+
+# Test j as well
+ j text_label
+ j external_text_label
diff --git a/gas/testsuite/gas/mips/la-empic.d b/gas/testsuite/gas/mips/la-empic.d
new file mode 100644
index 00000000000..af29570d0bd
--- /dev/null
+++ b/gas/testsuite/gas/mips/la-empic.d
@@ -0,0 +1,105 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS la-empic
+#as: -mips1 -membedded-pic
+
+# Test the la macro with -membedded-pic.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> li \$a0,0
+0+0004 <[^>]*> li \$a0,1
+0+0008 <[^>]*> li \$a0,0x8000
+0+000c <[^>]*> li \$a0,-32768
+0+0010 <[^>]*> lui \$a0,0x1
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+001c <[^>]*> li \$a0,0
+0+0020 <[^>]*> addu \$a0,\$a0,\$a1
+0+0024 <[^>]*> li \$a0,1
+0+0028 <[^>]*> addu \$a0,\$a0,\$a1
+0+002c <[^>]*> li \$a0,0x8000
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> li \$a0,-32768
+0+0038 <[^>]*> addu \$a0,\$a0,\$a1
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lui \$a0,0x1
+0+0048 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> addiu \$a0,\$gp,-16384
+[ ]*50: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0054 <[^>]*> addiu \$a0,\$gp,0
+[ ]*54: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0058 <[^>]*> addiu \$a0,\$gp,0
+[ ]*58: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+005c <[^>]*> addiu \$a0,\$gp,0
+[ ]*5c: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+0060 <[^>]*> addiu \$a0,\$gp,0
+[ ]*60: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0064 <[^>]*> addiu \$a0,\$gp,-16384
+[ ]*64: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0068 <[^>]*> addiu \$a0,\$gp,-15384
+[ ]*68: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+006c <[^>]*> addiu \$a0,\$gp,-16383
+[ ]*6c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0070 <[^>]*> addiu \$a0,\$gp,1
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0074 <[^>]*> addiu \$a0,\$gp,1
+[ ]*74: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0078 <[^>]*> addiu \$a0,\$gp,1
+[ ]*78: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+007c <[^>]*> addiu \$a0,\$gp,1
+[ ]*7c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0080 <[^>]*> addiu \$a0,\$gp,-16383
+[ ]*80: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0084 <[^>]*> addiu \$a0,\$gp,-15383
+[ ]*84: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0088 <[^>]*> addiu \$a0,\$gp,-16384
+[ ]*88: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+008c <[^>]*> addu \$a0,\$a0,\$a1
+0+0090 <[^>]*> addiu \$a0,\$gp,0
+[ ]*90: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0094 <[^>]*> addu \$a0,\$a0,\$a1
+0+0098 <[^>]*> addiu \$a0,\$gp,0
+[ ]*98: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+009c <[^>]*> addu \$a0,\$a0,\$a1
+0+00a0 <[^>]*> addiu \$a0,\$gp,0
+[ ]*a0: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00a4 <[^>]*> addu \$a0,\$a0,\$a1
+0+00a8 <[^>]*> addiu \$a0,\$gp,0
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00ac <[^>]*> addu \$a0,\$a0,\$a1
+0+00b0 <[^>]*> addiu \$a0,\$gp,-16384
+[ ]*b0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00b4 <[^>]*> addu \$a0,\$a0,\$a1
+0+00b8 <[^>]*> addiu \$a0,\$gp,-15384
+[ ]*b8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00bc <[^>]*> addu \$a0,\$a0,\$a1
+0+00c0 <[^>]*> addiu \$a0,\$gp,-16383
+[ ]*c0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+00c4 <[^>]*> addu \$a0,\$a0,\$a1
+0+00c8 <[^>]*> addiu \$a0,\$gp,1
+[ ]*c8: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+00cc <[^>]*> addu \$a0,\$a0,\$a1
+0+00d0 <[^>]*> addiu \$a0,\$gp,1
+[ ]*d0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00d4 <[^>]*> addu \$a0,\$a0,\$a1
+0+00d8 <[^>]*> addiu \$a0,\$gp,1
+[ ]*d8: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00dc <[^>]*> addu \$a0,\$a0,\$a1
+0+00e0 <[^>]*> addiu \$a0,\$gp,1
+[ ]*e0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00e4 <[^>]*> addu \$a0,\$a0,\$a1
+0+00e8 <[^>]*> addiu \$a0,\$gp,-16383
+[ ]*e8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ec <[^>]*> addu \$a0,\$a0,\$a1
+0+00f0 <[^>]*> addiu \$a0,\$gp,-15383
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00f4 <[^>]*> addu \$a0,\$a0,\$a1
+0+00f8 <[^>]*> lui \$a0,0x0
+[ ]*f8: RELHI external_text_label
+0+00fc <[^>]*> addiu \$a0,\$a0,252
+[ ]*fc: RELLO external_text_label
+0+0100 <[^>]*> li \$a0,248
+ ...
diff --git a/gas/testsuite/gas/mips/la-empic.s b/gas/testsuite/gas/mips/la-empic.s
new file mode 100644
index 00000000000..c6df5e3b586
--- /dev/null
+++ b/gas/testsuite/gas/mips/la-empic.s
@@ -0,0 +1,57 @@
+# Source file used to test the la macro with -membedded-pic
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+text_label:
+ la $4,0
+ la $4,1
+ la $4,0x8000
+ la $4,-0x8000
+ la $4,0x10000
+ la $4,0x1a5a5
+ la $4,0($5)
+ la $4,1($5)
+ la $4,0x8000($5)
+ la $4,-0x8000($5)
+ la $4,0x10000($5)
+ la $4,0x1a5a5($5)
+ la $4,data_label
+ la $4,big_external_data_label
+ la $4,small_external_data_label
+ la $4,big_external_common
+ la $4,small_external_common
+ la $4,big_local_common
+ la $4,small_local_common
+ la $4,data_label+1
+ la $4,big_external_data_label+1
+ la $4,small_external_data_label+1
+ la $4,big_external_common+1
+ la $4,small_external_common+1
+ la $4,big_local_common+1
+ la $4,small_local_common+1
+ la $4,data_label($5)
+ la $4,big_external_data_label($5)
+ la $4,small_external_data_label($5)
+ la $4,big_external_common($5)
+ la $4,small_external_common($5)
+ la $4,big_local_common($5)
+ la $4,small_local_common($5)
+ la $4,data_label+1($5)
+ la $4,big_external_data_label+1($5)
+ la $4,small_external_data_label+1($5)
+ la $4,big_external_common+1($5)
+ la $4,small_external_common+1($5)
+ la $4,big_local_common+1($5)
+ la $4,small_local_common+1($5)
+
+second_text_label:
+ la $4,external_text_label - text_label
+ la $4,second_text_label - text_label
diff --git a/gas/testsuite/gas/mips/la-svr4pic.d b/gas/testsuite/gas/mips/la-svr4pic.d
new file mode 100644
index 00000000000..4e8a3d54f43
--- /dev/null
+++ b/gas/testsuite/gas/mips/la-svr4pic.d
@@ -0,0 +1,474 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS la-svr4pic
+#as: -mips1 -KPIC --defsym KPIC=1
+#source: la.s
+
+# Test the la macro with -KPIC.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> li \$a0,0
+0+0004 <[^>]*> li \$a0,1
+0+0008 <[^>]*> li \$a0,0x8000
+0+000c <[^>]*> li \$a0,-32768
+0+0010 <[^>]*> lui \$a0,0x1
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+001c <[^>]*> li \$a0,0
+0+0020 <[^>]*> addu \$a0,\$a0,\$a1
+0+0024 <[^>]*> li \$a0,1
+0+0028 <[^>]*> addu \$a0,\$a0,\$a1
+0+002c <[^>]*> li \$a0,0x8000
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> li \$a0,-32768
+0+0038 <[^>]*> addu \$a0,\$a0,\$a1
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lui \$a0,0x1
+0+0048 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*50: R_MIPS_GOT16 .data
+0+0054 <[^>]*> nop
+0+0058 <[^>]*> addiu \$a0,\$a0,0
+[ ]*58: R_MIPS_LO16 .data
+0+005c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*5c: R_MIPS_GOT16 big_external_data_label
+0+0060 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*60: R_MIPS_GOT16 small_external_data_label
+0+0064 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*64: R_MIPS_GOT16 big_external_common
+0+0068 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*68: R_MIPS_GOT16 small_external_common
+0+006c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*6c: R_MIPS_GOT16 .bss
+0+0070 <[^>]*> nop
+0+0074 <[^>]*> addiu \$a0,\$a0,0
+[ ]*74: R_MIPS_LO16 .bss
+0+0078 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*78: R_MIPS_GOT16 .bss
+0+007c <[^>]*> nop
+0+0080 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*80: R_MIPS_LO16 .bss
+0+0084 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*84: R_MIPS_GOT16 .data
+0+0088 <[^>]*> nop
+0+008c <[^>]*> addiu \$a0,\$a0,1
+[ ]*8c: R_MIPS_LO16 .data
+0+0090 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*90: R_MIPS_GOT16 big_external_data_label
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> addiu \$a0,\$a0,1
+0+009c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*9c: R_MIPS_GOT16 small_external_data_label
+0+00a0 <[^>]*> nop
+0+00a4 <[^>]*> addiu \$a0,\$a0,1
+0+00a8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*a8: R_MIPS_GOT16 big_external_common
+0+00ac <[^>]*> nop
+0+00b0 <[^>]*> addiu \$a0,\$a0,1
+0+00b4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*b4: R_MIPS_GOT16 small_external_common
+0+00b8 <[^>]*> nop
+0+00bc <[^>]*> addiu \$a0,\$a0,1
+0+00c0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*c0: R_MIPS_GOT16 .bss
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> addiu \$a0,\$a0,1
+[ ]*c8: R_MIPS_LO16 .bss
+0+00cc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*cc: R_MIPS_GOT16 .bss
+0+00d0 <[^>]*> nop
+0+00d4 <[^>]*> addiu \$a0,\$a0,1001
+[ ]*d4: R_MIPS_LO16 .bss
+0+00d8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*d8: R_MIPS_GOT16 .data
+0+00dc <[^>]*> lui \$at,0x1
+0+00e0 <[^>]*> addiu \$at,\$at,-32768
+[ ]*e0: R_MIPS_LO16 .data
+0+00e4 <[^>]*> addu \$a0,\$a0,\$at
+0+00e8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*e8: R_MIPS_GOT16 big_external_data_label
+0+00ec <[^>]*> lui \$at,0x1
+0+00f0 <[^>]*> addiu \$at,\$at,-32768
+0+00f4 <[^>]*> addu \$a0,\$a0,\$at
+0+00f8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*f8: R_MIPS_GOT16 small_external_data_label
+0+00fc <[^>]*> lui \$at,0x1
+0+0100 <[^>]*> addiu \$at,\$at,-32768
+0+0104 <[^>]*> addu \$a0,\$a0,\$at
+0+0108 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*108: R_MIPS_GOT16 big_external_common
+0+010c <[^>]*> lui \$at,0x1
+0+0110 <[^>]*> addiu \$at,\$at,-32768
+0+0114 <[^>]*> addu \$a0,\$a0,\$at
+0+0118 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*118: R_MIPS_GOT16 small_external_common
+0+011c <[^>]*> lui \$at,0x1
+0+0120 <[^>]*> addiu \$at,\$at,-32768
+0+0124 <[^>]*> addu \$a0,\$a0,\$at
+0+0128 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*128: R_MIPS_GOT16 .bss
+0+012c <[^>]*> lui \$at,0x1
+0+0130 <[^>]*> addiu \$at,\$at,-32768
+[ ]*130: R_MIPS_LO16 .bss
+0+0134 <[^>]*> addu \$a0,\$a0,\$at
+0+0138 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*138: R_MIPS_GOT16 .bss
+0+013c <[^>]*> lui \$at,0x1
+0+0140 <[^>]*> addiu \$at,\$at,-31768
+[ ]*140: R_MIPS_LO16 .bss
+0+0144 <[^>]*> addu \$a0,\$a0,\$at
+0+0148 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*148: R_MIPS_GOT16 .data
+0+014c <[^>]*> nop
+0+0150 <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*150: R_MIPS_LO16 .data
+0+0154 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*154: R_MIPS_GOT16 big_external_data_label
+0+0158 <[^>]*> nop
+0+015c <[^>]*> addiu \$a0,\$a0,-32768
+0+0160 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*160: R_MIPS_GOT16 small_external_data_label
+0+0164 <[^>]*> nop
+0+0168 <[^>]*> addiu \$a0,\$a0,-32768
+0+016c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*16c: R_MIPS_GOT16 big_external_common
+0+0170 <[^>]*> nop
+0+0174 <[^>]*> addiu \$a0,\$a0,-32768
+0+0178 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*178: R_MIPS_GOT16 small_external_common
+0+017c <[^>]*> nop
+0+0180 <[^>]*> addiu \$a0,\$a0,-32768
+0+0184 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*184: R_MIPS_GOT16 .bss
+0+0188 <[^>]*> nop
+0+018c <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*18c: R_MIPS_LO16 .bss
+0+0190 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*190: R_MIPS_GOT16 .bss
+0+0194 <[^>]*> nop
+0+0198 <[^>]*> addiu \$a0,\$a0,-31768
+[ ]*198: R_MIPS_LO16 .bss
+0+019c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*19c: R_MIPS_GOT16 .data
+0+01a0 <[^>]*> lui \$at,0x1
+0+01a4 <[^>]*> addiu \$at,\$at,0
+[ ]*1a4: R_MIPS_LO16 .data
+0+01a8 <[^>]*> addu \$a0,\$a0,\$at
+0+01ac <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1ac: R_MIPS_GOT16 big_external_data_label
+0+01b0 <[^>]*> lui \$at,0x1
+0+01b4 <[^>]*> addiu \$at,\$at,0
+0+01b8 <[^>]*> addu \$a0,\$a0,\$at
+0+01bc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1bc: R_MIPS_GOT16 small_external_data_label
+0+01c0 <[^>]*> lui \$at,0x1
+0+01c4 <[^>]*> addiu \$at,\$at,0
+0+01c8 <[^>]*> addu \$a0,\$a0,\$at
+0+01cc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1cc: R_MIPS_GOT16 big_external_common
+0+01d0 <[^>]*> lui \$at,0x1
+0+01d4 <[^>]*> addiu \$at,\$at,0
+0+01d8 <[^>]*> addu \$a0,\$a0,\$at
+0+01dc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1dc: R_MIPS_GOT16 small_external_common
+0+01e0 <[^>]*> lui \$at,0x1
+0+01e4 <[^>]*> addiu \$at,\$at,0
+0+01e8 <[^>]*> addu \$a0,\$a0,\$at
+0+01ec <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1ec: R_MIPS_GOT16 .bss
+0+01f0 <[^>]*> lui \$at,0x1
+0+01f4 <[^>]*> addiu \$at,\$at,0
+[ ]*1f4: R_MIPS_LO16 .bss
+0+01f8 <[^>]*> addu \$a0,\$a0,\$at
+0+01fc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1fc: R_MIPS_GOT16 .bss
+0+0200 <[^>]*> lui \$at,0x1
+0+0204 <[^>]*> addiu \$at,\$at,1000
+[ ]*204: R_MIPS_LO16 .bss
+0+0208 <[^>]*> addu \$a0,\$a0,\$at
+0+020c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*20c: R_MIPS_GOT16 .data
+0+0210 <[^>]*> lui \$at,0x2
+0+0214 <[^>]*> addiu \$at,\$at,-23131
+[ ]*214: R_MIPS_LO16 .data
+0+0218 <[^>]*> addu \$a0,\$a0,\$at
+0+021c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*21c: R_MIPS_GOT16 big_external_data_label
+0+0220 <[^>]*> lui \$at,0x2
+0+0224 <[^>]*> addiu \$at,\$at,-23131
+0+0228 <[^>]*> addu \$a0,\$a0,\$at
+0+022c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*22c: R_MIPS_GOT16 small_external_data_label
+0+0230 <[^>]*> lui \$at,0x2
+0+0234 <[^>]*> addiu \$at,\$at,-23131
+0+0238 <[^>]*> addu \$a0,\$a0,\$at
+0+023c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*23c: R_MIPS_GOT16 big_external_common
+0+0240 <[^>]*> lui \$at,0x2
+0+0244 <[^>]*> addiu \$at,\$at,-23131
+0+0248 <[^>]*> addu \$a0,\$a0,\$at
+0+024c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*24c: R_MIPS_GOT16 small_external_common
+0+0250 <[^>]*> lui \$at,0x2
+0+0254 <[^>]*> addiu \$at,\$at,-23131
+0+0258 <[^>]*> addu \$a0,\$a0,\$at
+0+025c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*25c: R_MIPS_GOT16 .bss
+0+0260 <[^>]*> lui \$at,0x2
+0+0264 <[^>]*> addiu \$at,\$at,-23131
+[ ]*264: R_MIPS_LO16 .bss
+0+0268 <[^>]*> addu \$a0,\$a0,\$at
+0+026c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*26c: R_MIPS_GOT16 .bss
+0+0270 <[^>]*> lui \$at,0x2
+0+0274 <[^>]*> addiu \$at,\$at,-22131
+[ ]*274: R_MIPS_LO16 .bss
+0+0278 <[^>]*> addu \$a0,\$a0,\$at
+0+027c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*27c: R_MIPS_GOT16 .data
+0+0280 <[^>]*> nop
+0+0284 <[^>]*> addiu \$a0,\$a0,0
+[ ]*284: R_MIPS_LO16 .data
+0+0288 <[^>]*> addu \$a0,\$a0,\$a1
+0+028c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*28c: R_MIPS_GOT16 big_external_data_label
+0+0290 <[^>]*> nop
+0+0294 <[^>]*> addu \$a0,\$a0,\$a1
+0+0298 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*298: R_MIPS_GOT16 small_external_data_label
+0+029c <[^>]*> nop
+0+02a0 <[^>]*> addu \$a0,\$a0,\$a1
+0+02a4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2a4: R_MIPS_GOT16 big_external_common
+0+02a8 <[^>]*> nop
+0+02ac <[^>]*> addu \$a0,\$a0,\$a1
+0+02b0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2b0: R_MIPS_GOT16 small_external_common
+0+02b4 <[^>]*> nop
+0+02b8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02bc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2bc: R_MIPS_GOT16 .bss
+0+02c0 <[^>]*> nop
+0+02c4 <[^>]*> addiu \$a0,\$a0,0
+[ ]*2c4: R_MIPS_LO16 .bss
+0+02c8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02cc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2cc: R_MIPS_GOT16 .bss
+0+02d0 <[^>]*> nop
+0+02d4 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*2d4: R_MIPS_LO16 .bss
+0+02d8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02dc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2dc: R_MIPS_GOT16 .data
+0+02e0 <[^>]*> nop
+0+02e4 <[^>]*> addiu \$a0,\$a0,1
+[ ]*2e4: R_MIPS_LO16 .data
+0+02e8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02ec <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2ec: R_MIPS_GOT16 big_external_data_label
+0+02f0 <[^>]*> nop
+0+02f4 <[^>]*> addiu \$a0,\$a0,1
+0+02f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02fc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2fc: R_MIPS_GOT16 small_external_data_label
+0+0300 <[^>]*> nop
+0+0304 <[^>]*> addiu \$a0,\$a0,1
+0+0308 <[^>]*> addu \$a0,\$a0,\$a1
+0+030c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*30c: R_MIPS_GOT16 big_external_common
+0+0310 <[^>]*> nop
+0+0314 <[^>]*> addiu \$a0,\$a0,1
+0+0318 <[^>]*> addu \$a0,\$a0,\$a1
+0+031c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*31c: R_MIPS_GOT16 small_external_common
+0+0320 <[^>]*> nop
+0+0324 <[^>]*> addiu \$a0,\$a0,1
+0+0328 <[^>]*> addu \$a0,\$a0,\$a1
+0+032c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*32c: R_MIPS_GOT16 .bss
+0+0330 <[^>]*> nop
+0+0334 <[^>]*> addiu \$a0,\$a0,1
+[ ]*334: R_MIPS_LO16 .bss
+0+0338 <[^>]*> addu \$a0,\$a0,\$a1
+0+033c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*33c: R_MIPS_GOT16 .bss
+0+0340 <[^>]*> nop
+0+0344 <[^>]*> addiu \$a0,\$a0,1001
+[ ]*344: R_MIPS_LO16 .bss
+0+0348 <[^>]*> addu \$a0,\$a0,\$a1
+0+034c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*34c: R_MIPS_GOT16 .data
+0+0350 <[^>]*> lui \$at,0x1
+0+0354 <[^>]*> addiu \$at,\$at,-32768
+[ ]*354: R_MIPS_LO16 .data
+0+0358 <[^>]*> addu \$a0,\$a0,\$at
+0+035c <[^>]*> addu \$a0,\$a0,\$a1
+0+0360 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*360: R_MIPS_GOT16 big_external_data_label
+0+0364 <[^>]*> lui \$at,0x1
+0+0368 <[^>]*> addiu \$at,\$at,-32768
+0+036c <[^>]*> addu \$a0,\$a0,\$at
+0+0370 <[^>]*> addu \$a0,\$a0,\$a1
+0+0374 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*374: R_MIPS_GOT16 small_external_data_label
+0+0378 <[^>]*> lui \$at,0x1
+0+037c <[^>]*> addiu \$at,\$at,-32768
+0+0380 <[^>]*> addu \$a0,\$a0,\$at
+0+0384 <[^>]*> addu \$a0,\$a0,\$a1
+0+0388 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*388: R_MIPS_GOT16 big_external_common
+0+038c <[^>]*> lui \$at,0x1
+0+0390 <[^>]*> addiu \$at,\$at,-32768
+0+0394 <[^>]*> addu \$a0,\$a0,\$at
+0+0398 <[^>]*> addu \$a0,\$a0,\$a1
+0+039c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*39c: R_MIPS_GOT16 small_external_common
+0+03a0 <[^>]*> lui \$at,0x1
+0+03a4 <[^>]*> addiu \$at,\$at,-32768
+0+03a8 <[^>]*> addu \$a0,\$a0,\$at
+0+03ac <[^>]*> addu \$a0,\$a0,\$a1
+0+03b0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3b0: R_MIPS_GOT16 .bss
+0+03b4 <[^>]*> lui \$at,0x1
+0+03b8 <[^>]*> addiu \$at,\$at,-32768
+[ ]*3b8: R_MIPS_LO16 .bss
+0+03bc <[^>]*> addu \$a0,\$a0,\$at
+0+03c0 <[^>]*> addu \$a0,\$a0,\$a1
+0+03c4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3c4: R_MIPS_GOT16 .bss
+0+03c8 <[^>]*> lui \$at,0x1
+0+03cc <[^>]*> addiu \$at,\$at,-31768
+[ ]*3cc: R_MIPS_LO16 .bss
+0+03d0 <[^>]*> addu \$a0,\$a0,\$at
+0+03d4 <[^>]*> addu \$a0,\$a0,\$a1
+0+03d8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3d8: R_MIPS_GOT16 .data
+0+03dc <[^>]*> nop
+0+03e0 <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*3e0: R_MIPS_LO16 .data
+0+03e4 <[^>]*> addu \$a0,\$a0,\$a1
+0+03e8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3e8: R_MIPS_GOT16 big_external_data_label
+0+03ec <[^>]*> nop
+0+03f0 <[^>]*> addiu \$a0,\$a0,-32768
+0+03f4 <[^>]*> addu \$a0,\$a0,\$a1
+0+03f8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3f8: R_MIPS_GOT16 small_external_data_label
+0+03fc <[^>]*> nop
+0+0400 <[^>]*> addiu \$a0,\$a0,-32768
+0+0404 <[^>]*> addu \$a0,\$a0,\$a1
+0+0408 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*408: R_MIPS_GOT16 big_external_common
+0+040c <[^>]*> nop
+0+0410 <[^>]*> addiu \$a0,\$a0,-32768
+0+0414 <[^>]*> addu \$a0,\$a0,\$a1
+0+0418 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*418: R_MIPS_GOT16 small_external_common
+0+041c <[^>]*> nop
+0+0420 <[^>]*> addiu \$a0,\$a0,-32768
+0+0424 <[^>]*> addu \$a0,\$a0,\$a1
+0+0428 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*428: R_MIPS_GOT16 .bss
+0+042c <[^>]*> nop
+0+0430 <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*430: R_MIPS_LO16 .bss
+0+0434 <[^>]*> addu \$a0,\$a0,\$a1
+0+0438 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*438: R_MIPS_GOT16 .bss
+0+043c <[^>]*> nop
+0+0440 <[^>]*> addiu \$a0,\$a0,-31768
+[ ]*440: R_MIPS_LO16 .bss
+0+0444 <[^>]*> addu \$a0,\$a0,\$a1
+0+0448 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*448: R_MIPS_GOT16 .data
+0+044c <[^>]*> lui \$at,0x1
+0+0450 <[^>]*> addiu \$at,\$at,0
+[ ]*450: R_MIPS_LO16 .data
+0+0454 <[^>]*> addu \$a0,\$a0,\$at
+0+0458 <[^>]*> addu \$a0,\$a0,\$a1
+0+045c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*45c: R_MIPS_GOT16 big_external_data_label
+0+0460 <[^>]*> lui \$at,0x1
+0+0464 <[^>]*> addiu \$at,\$at,0
+0+0468 <[^>]*> addu \$a0,\$a0,\$at
+0+046c <[^>]*> addu \$a0,\$a0,\$a1
+0+0470 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*470: R_MIPS_GOT16 small_external_data_label
+0+0474 <[^>]*> lui \$at,0x1
+0+0478 <[^>]*> addiu \$at,\$at,0
+0+047c <[^>]*> addu \$a0,\$a0,\$at
+0+0480 <[^>]*> addu \$a0,\$a0,\$a1
+0+0484 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*484: R_MIPS_GOT16 big_external_common
+0+0488 <[^>]*> lui \$at,0x1
+0+048c <[^>]*> addiu \$at,\$at,0
+0+0490 <[^>]*> addu \$a0,\$a0,\$at
+0+0494 <[^>]*> addu \$a0,\$a0,\$a1
+0+0498 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*498: R_MIPS_GOT16 small_external_common
+0+049c <[^>]*> lui \$at,0x1
+0+04a0 <[^>]*> addiu \$at,\$at,0
+0+04a4 <[^>]*> addu \$a0,\$a0,\$at
+0+04a8 <[^>]*> addu \$a0,\$a0,\$a1
+0+04ac <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4ac: R_MIPS_GOT16 .bss
+0+04b0 <[^>]*> lui \$at,0x1
+0+04b4 <[^>]*> addiu \$at,\$at,0
+[ ]*4b4: R_MIPS_LO16 .bss
+0+04b8 <[^>]*> addu \$a0,\$a0,\$at
+0+04bc <[^>]*> addu \$a0,\$a0,\$a1
+0+04c0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4c0: R_MIPS_GOT16 .bss
+0+04c4 <[^>]*> lui \$at,0x1
+0+04c8 <[^>]*> addiu \$at,\$at,1000
+[ ]*4c8: R_MIPS_LO16 .bss
+0+04cc <[^>]*> addu \$a0,\$a0,\$at
+0+04d0 <[^>]*> addu \$a0,\$a0,\$a1
+0+04d4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4d4: R_MIPS_GOT16 .data
+0+04d8 <[^>]*> lui \$at,0x2
+0+04dc <[^>]*> addiu \$at,\$at,-23131
+[ ]*4dc: R_MIPS_LO16 .data
+0+04e0 <[^>]*> addu \$a0,\$a0,\$at
+0+04e4 <[^>]*> addu \$a0,\$a0,\$a1
+0+04e8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4e8: R_MIPS_GOT16 big_external_data_label
+0+04ec <[^>]*> lui \$at,0x2
+0+04f0 <[^>]*> addiu \$at,\$at,-23131
+0+04f4 <[^>]*> addu \$a0,\$a0,\$at
+0+04f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+04fc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4fc: R_MIPS_GOT16 small_external_data_label
+0+0500 <[^>]*> lui \$at,0x2
+0+0504 <[^>]*> addiu \$at,\$at,-23131
+0+0508 <[^>]*> addu \$a0,\$a0,\$at
+0+050c <[^>]*> addu \$a0,\$a0,\$a1
+0+0510 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*510: R_MIPS_GOT16 big_external_common
+0+0514 <[^>]*> lui \$at,0x2
+0+0518 <[^>]*> addiu \$at,\$at,-23131
+0+051c <[^>]*> addu \$a0,\$a0,\$at
+0+0520 <[^>]*> addu \$a0,\$a0,\$a1
+0+0524 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*524: R_MIPS_GOT16 small_external_common
+0+0528 <[^>]*> lui \$at,0x2
+0+052c <[^>]*> addiu \$at,\$at,-23131
+0+0530 <[^>]*> addu \$a0,\$a0,\$at
+0+0534 <[^>]*> addu \$a0,\$a0,\$a1
+0+0538 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*538: R_MIPS_GOT16 .bss
+0+053c <[^>]*> lui \$at,0x2
+0+0540 <[^>]*> addiu \$at,\$at,-23131
+[ ]*540: R_MIPS_LO16 .bss
+0+0544 <[^>]*> addu \$a0,\$a0,\$at
+0+0548 <[^>]*> addu \$a0,\$a0,\$a1
+0+054c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*54c: R_MIPS_GOT16 .bss
+0+0550 <[^>]*> lui \$at,0x2
+0+0554 <[^>]*> addiu \$at,\$at,-22131
+[ ]*554: R_MIPS_LO16 .bss
+0+0558 <[^>]*> addu \$a0,\$a0,\$at
+0+055c <[^>]*> addu \$a0,\$a0,\$a1
diff --git a/gas/testsuite/gas/mips/la-xgot.d b/gas/testsuite/gas/mips/la-xgot.d
new file mode 100644
index 00000000000..6e5cd260281
--- /dev/null
+++ b/gas/testsuite/gas/mips/la-xgot.d
@@ -0,0 +1,618 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS la-xgot
+#as: -mips1 -KPIC -xgot --defsym KPIC=1
+#source: la.s
+
+# Test the la macro with -KPIC -xgot.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> li \$a0,0
+0+0004 <[^>]*> li \$a0,1
+0+0008 <[^>]*> li \$a0,0x8000
+0+000c <[^>]*> li \$a0,-32768
+0+0010 <[^>]*> lui \$a0,0x1
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+001c <[^>]*> li \$a0,0
+0+0020 <[^>]*> addu \$a0,\$a0,\$a1
+0+0024 <[^>]*> li \$a0,1
+0+0028 <[^>]*> addu \$a0,\$a0,\$a1
+0+002c <[^>]*> li \$a0,0x8000
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> li \$a0,-32768
+0+0038 <[^>]*> addu \$a0,\$a0,\$a1
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lui \$a0,0x1
+0+0048 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*50: R_MIPS_GOT16 .data
+0+0054 <[^>]*> nop
+0+0058 <[^>]*> addiu \$a0,\$a0,0
+[ ]*58: R_MIPS_LO16 .data
+0+005c <[^>]*> lui \$a0,0x0
+[ ]*5c: R_MIPS_GOT_HI16 big_external_data_label
+0+0060 <[^>]*> addu \$a0,\$a0,\$gp
+0+0064 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*64: R_MIPS_GOT_LO16 big_external_data_label
+0+0068 <[^>]*> lui \$a0,0x0
+[ ]*68: R_MIPS_GOT_HI16 small_external_data_label
+0+006c <[^>]*> addu \$a0,\$a0,\$gp
+0+0070 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*70: R_MIPS_GOT_LO16 small_external_data_label
+0+0074 <[^>]*> lui \$a0,0x0
+[ ]*74: R_MIPS_GOT_HI16 big_external_common
+0+0078 <[^>]*> addu \$a0,\$a0,\$gp
+0+007c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*7c: R_MIPS_GOT_LO16 big_external_common
+0+0080 <[^>]*> lui \$a0,0x0
+[ ]*80: R_MIPS_GOT_HI16 small_external_common
+0+0084 <[^>]*> addu \$a0,\$a0,\$gp
+0+0088 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*88: R_MIPS_GOT_LO16 small_external_common
+0+008c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*8c: R_MIPS_GOT16 .bss
+0+0090 <[^>]*> nop
+0+0094 <[^>]*> addiu \$a0,\$a0,0
+[ ]*94: R_MIPS_LO16 .bss
+0+0098 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*98: R_MIPS_GOT16 .bss
+0+009c <[^>]*> nop
+0+00a0 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*a0: R_MIPS_LO16 .bss
+0+00a4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*a4: R_MIPS_GOT16 .data
+0+00a8 <[^>]*> nop
+0+00ac <[^>]*> addiu \$a0,\$a0,1
+[ ]*ac: R_MIPS_LO16 .data
+0+00b0 <[^>]*> lui \$a0,0x0
+[ ]*b0: R_MIPS_GOT_HI16 big_external_data_label
+0+00b4 <[^>]*> addu \$a0,\$a0,\$gp
+0+00b8 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*b8: R_MIPS_GOT_LO16 big_external_data_label
+0+00bc <[^>]*> nop
+0+00c0 <[^>]*> addiu \$a0,\$a0,1
+0+00c4 <[^>]*> lui \$a0,0x0
+[ ]*c4: R_MIPS_GOT_HI16 small_external_data_label
+0+00c8 <[^>]*> addu \$a0,\$a0,\$gp
+0+00cc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*cc: R_MIPS_GOT_LO16 small_external_data_label
+0+00d0 <[^>]*> nop
+0+00d4 <[^>]*> addiu \$a0,\$a0,1
+0+00d8 <[^>]*> lui \$a0,0x0
+[ ]*d8: R_MIPS_GOT_HI16 big_external_common
+0+00dc <[^>]*> addu \$a0,\$a0,\$gp
+0+00e0 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*e0: R_MIPS_GOT_LO16 big_external_common
+0+00e4 <[^>]*> nop
+0+00e8 <[^>]*> addiu \$a0,\$a0,1
+0+00ec <[^>]*> lui \$a0,0x0
+[ ]*ec: R_MIPS_GOT_HI16 small_external_common
+0+00f0 <[^>]*> addu \$a0,\$a0,\$gp
+0+00f4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*f4: R_MIPS_GOT_LO16 small_external_common
+0+00f8 <[^>]*> nop
+0+00fc <[^>]*> addiu \$a0,\$a0,1
+0+0100 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*100: R_MIPS_GOT16 .bss
+0+0104 <[^>]*> nop
+0+0108 <[^>]*> addiu \$a0,\$a0,1
+[ ]*108: R_MIPS_LO16 .bss
+0+010c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*10c: R_MIPS_GOT16 .bss
+0+0110 <[^>]*> nop
+0+0114 <[^>]*> addiu \$a0,\$a0,1001
+[ ]*114: R_MIPS_LO16 .bss
+0+0118 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*118: R_MIPS_GOT16 .data
+0+011c <[^>]*> lui \$at,0x1
+0+0120 <[^>]*> addiu \$at,\$at,-32768
+[ ]*120: R_MIPS_LO16 .data
+0+0124 <[^>]*> addu \$a0,\$a0,\$at
+0+0128 <[^>]*> lui \$a0,0x0
+[ ]*128: R_MIPS_GOT_HI16 big_external_data_label
+0+012c <[^>]*> addu \$a0,\$a0,\$gp
+0+0130 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*130: R_MIPS_GOT_LO16 big_external_data_label
+0+0134 <[^>]*> lui \$at,0x1
+0+0138 <[^>]*> addiu \$at,\$at,-32768
+0+013c <[^>]*> addu \$a0,\$a0,\$at
+0+0140 <[^>]*> lui \$a0,0x0
+[ ]*140: R_MIPS_GOT_HI16 small_external_data_label
+0+0144 <[^>]*> addu \$a0,\$a0,\$gp
+0+0148 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*148: R_MIPS_GOT_LO16 small_external_data_label
+0+014c <[^>]*> lui \$at,0x1
+0+0150 <[^>]*> addiu \$at,\$at,-32768
+0+0154 <[^>]*> addu \$a0,\$a0,\$at
+0+0158 <[^>]*> lui \$a0,0x0
+[ ]*158: R_MIPS_GOT_HI16 big_external_common
+0+015c <[^>]*> addu \$a0,\$a0,\$gp
+0+0160 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*160: R_MIPS_GOT_LO16 big_external_common
+0+0164 <[^>]*> lui \$at,0x1
+0+0168 <[^>]*> addiu \$at,\$at,-32768
+0+016c <[^>]*> addu \$a0,\$a0,\$at
+0+0170 <[^>]*> lui \$a0,0x0
+[ ]*170: R_MIPS_GOT_HI16 small_external_common
+0+0174 <[^>]*> addu \$a0,\$a0,\$gp
+0+0178 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*178: R_MIPS_GOT_LO16 small_external_common
+0+017c <[^>]*> lui \$at,0x1
+0+0180 <[^>]*> addiu \$at,\$at,-32768
+0+0184 <[^>]*> addu \$a0,\$a0,\$at
+0+0188 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*188: R_MIPS_GOT16 .bss
+0+018c <[^>]*> lui \$at,0x1
+0+0190 <[^>]*> addiu \$at,\$at,-32768
+[ ]*190: R_MIPS_LO16 .bss
+0+0194 <[^>]*> addu \$a0,\$a0,\$at
+0+0198 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*198: R_MIPS_GOT16 .bss
+0+019c <[^>]*> lui \$at,0x1
+0+01a0 <[^>]*> addiu \$at,\$at,-31768
+[ ]*1a0: R_MIPS_LO16 .bss
+0+01a4 <[^>]*> addu \$a0,\$a0,\$at
+0+01a8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1a8: R_MIPS_GOT16 .data
+0+01ac <[^>]*> nop
+0+01b0 <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*1b0: R_MIPS_LO16 .data
+0+01b4 <[^>]*> lui \$a0,0x0
+[ ]*1b4: R_MIPS_GOT_HI16 big_external_data_label
+0+01b8 <[^>]*> addu \$a0,\$a0,\$gp
+0+01bc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1bc: R_MIPS_GOT_LO16 big_external_data_label
+0+01c0 <[^>]*> nop
+0+01c4 <[^>]*> addiu \$a0,\$a0,-32768
+0+01c8 <[^>]*> lui \$a0,0x0
+[ ]*1c8: R_MIPS_GOT_HI16 small_external_data_label
+0+01cc <[^>]*> addu \$a0,\$a0,\$gp
+0+01d0 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1d0: R_MIPS_GOT_LO16 small_external_data_label
+0+01d4 <[^>]*> nop
+0+01d8 <[^>]*> addiu \$a0,\$a0,-32768
+0+01dc <[^>]*> lui \$a0,0x0
+[ ]*1dc: R_MIPS_GOT_HI16 big_external_common
+0+01e0 <[^>]*> addu \$a0,\$a0,\$gp
+0+01e4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1e4: R_MIPS_GOT_LO16 big_external_common
+0+01e8 <[^>]*> nop
+0+01ec <[^>]*> addiu \$a0,\$a0,-32768
+0+01f0 <[^>]*> lui \$a0,0x0
+[ ]*1f0: R_MIPS_GOT_HI16 small_external_common
+0+01f4 <[^>]*> addu \$a0,\$a0,\$gp
+0+01f8 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1f8: R_MIPS_GOT_LO16 small_external_common
+0+01fc <[^>]*> nop
+0+0200 <[^>]*> addiu \$a0,\$a0,-32768
+0+0204 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*204: R_MIPS_GOT16 .bss
+0+0208 <[^>]*> nop
+0+020c <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*20c: R_MIPS_LO16 .bss
+0+0210 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*210: R_MIPS_GOT16 .bss
+0+0214 <[^>]*> nop
+0+0218 <[^>]*> addiu \$a0,\$a0,-31768
+[ ]*218: R_MIPS_LO16 .bss
+0+021c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*21c: R_MIPS_GOT16 .data
+0+0220 <[^>]*> lui \$at,0x1
+0+0224 <[^>]*> addiu \$at,\$at,0
+[ ]*224: R_MIPS_LO16 .data
+0+0228 <[^>]*> addu \$a0,\$a0,\$at
+0+022c <[^>]*> lui \$a0,0x0
+[ ]*22c: R_MIPS_GOT_HI16 big_external_data_label
+0+0230 <[^>]*> addu \$a0,\$a0,\$gp
+0+0234 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*234: R_MIPS_GOT_LO16 big_external_data_label
+0+0238 <[^>]*> lui \$at,0x1
+0+023c <[^>]*> addiu \$at,\$at,0
+0+0240 <[^>]*> addu \$a0,\$a0,\$at
+0+0244 <[^>]*> lui \$a0,0x0
+[ ]*244: R_MIPS_GOT_HI16 small_external_data_label
+0+0248 <[^>]*> addu \$a0,\$a0,\$gp
+0+024c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*24c: R_MIPS_GOT_LO16 small_external_data_label
+0+0250 <[^>]*> lui \$at,0x1
+0+0254 <[^>]*> addiu \$at,\$at,0
+0+0258 <[^>]*> addu \$a0,\$a0,\$at
+0+025c <[^>]*> lui \$a0,0x0
+[ ]*25c: R_MIPS_GOT_HI16 big_external_common
+0+0260 <[^>]*> addu \$a0,\$a0,\$gp
+0+0264 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*264: R_MIPS_GOT_LO16 big_external_common
+0+0268 <[^>]*> lui \$at,0x1
+0+026c <[^>]*> addiu \$at,\$at,0
+0+0270 <[^>]*> addu \$a0,\$a0,\$at
+0+0274 <[^>]*> lui \$a0,0x0
+[ ]*274: R_MIPS_GOT_HI16 small_external_common
+0+0278 <[^>]*> addu \$a0,\$a0,\$gp
+0+027c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*27c: R_MIPS_GOT_LO16 small_external_common
+0+0280 <[^>]*> lui \$at,0x1
+0+0284 <[^>]*> addiu \$at,\$at,0
+0+0288 <[^>]*> addu \$a0,\$a0,\$at
+0+028c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*28c: R_MIPS_GOT16 .bss
+0+0290 <[^>]*> lui \$at,0x1
+0+0294 <[^>]*> addiu \$at,\$at,0
+[ ]*294: R_MIPS_LO16 .bss
+0+0298 <[^>]*> addu \$a0,\$a0,\$at
+0+029c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*29c: R_MIPS_GOT16 .bss
+0+02a0 <[^>]*> lui \$at,0x1
+0+02a4 <[^>]*> addiu \$at,\$at,1000
+[ ]*2a4: R_MIPS_LO16 .bss
+0+02a8 <[^>]*> addu \$a0,\$a0,\$at
+0+02ac <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2ac: R_MIPS_GOT16 .data
+0+02b0 <[^>]*> lui \$at,0x2
+0+02b4 <[^>]*> addiu \$at,\$at,-23131
+[ ]*2b4: R_MIPS_LO16 .data
+0+02b8 <[^>]*> addu \$a0,\$a0,\$at
+0+02bc <[^>]*> lui \$a0,0x0
+[ ]*2bc: R_MIPS_GOT_HI16 big_external_data_label
+0+02c0 <[^>]*> addu \$a0,\$a0,\$gp
+0+02c4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*2c4: R_MIPS_GOT_LO16 big_external_data_label
+0+02c8 <[^>]*> lui \$at,0x2
+0+02cc <[^>]*> addiu \$at,\$at,-23131
+0+02d0 <[^>]*> addu \$a0,\$a0,\$at
+0+02d4 <[^>]*> lui \$a0,0x0
+[ ]*2d4: R_MIPS_GOT_HI16 small_external_data_label
+0+02d8 <[^>]*> addu \$a0,\$a0,\$gp
+0+02dc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*2dc: R_MIPS_GOT_LO16 small_external_data_label
+0+02e0 <[^>]*> lui \$at,0x2
+0+02e4 <[^>]*> addiu \$at,\$at,-23131
+0+02e8 <[^>]*> addu \$a0,\$a0,\$at
+0+02ec <[^>]*> lui \$a0,0x0
+[ ]*2ec: R_MIPS_GOT_HI16 big_external_common
+0+02f0 <[^>]*> addu \$a0,\$a0,\$gp
+0+02f4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*2f4: R_MIPS_GOT_LO16 big_external_common
+0+02f8 <[^>]*> lui \$at,0x2
+0+02fc <[^>]*> addiu \$at,\$at,-23131
+0+0300 <[^>]*> addu \$a0,\$a0,\$at
+0+0304 <[^>]*> lui \$a0,0x0
+[ ]*304: R_MIPS_GOT_HI16 small_external_common
+0+0308 <[^>]*> addu \$a0,\$a0,\$gp
+0+030c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*30c: R_MIPS_GOT_LO16 small_external_common
+0+0310 <[^>]*> lui \$at,0x2
+0+0314 <[^>]*> addiu \$at,\$at,-23131
+0+0318 <[^>]*> addu \$a0,\$a0,\$at
+0+031c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*31c: R_MIPS_GOT16 .bss
+0+0320 <[^>]*> lui \$at,0x2
+0+0324 <[^>]*> addiu \$at,\$at,-23131
+[ ]*324: R_MIPS_LO16 .bss
+0+0328 <[^>]*> addu \$a0,\$a0,\$at
+0+032c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*32c: R_MIPS_GOT16 .bss
+0+0330 <[^>]*> lui \$at,0x2
+0+0334 <[^>]*> addiu \$at,\$at,-22131
+[ ]*334: R_MIPS_LO16 .bss
+0+0338 <[^>]*> addu \$a0,\$a0,\$at
+0+033c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*33c: R_MIPS_GOT16 .data
+0+0340 <[^>]*> nop
+0+0344 <[^>]*> addiu \$a0,\$a0,0
+[ ]*344: R_MIPS_LO16 .data
+0+0348 <[^>]*> addu \$a0,\$a0,\$a1
+0+034c <[^>]*> lui \$a0,0x0
+[ ]*34c: R_MIPS_GOT_HI16 big_external_data_label
+0+0350 <[^>]*> addu \$a0,\$a0,\$gp
+0+0354 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*354: R_MIPS_GOT_LO16 big_external_data_label
+0+0358 <[^>]*> nop
+0+035c <[^>]*> addu \$a0,\$a0,\$a1
+0+0360 <[^>]*> lui \$a0,0x0
+[ ]*360: R_MIPS_GOT_HI16 small_external_data_label
+0+0364 <[^>]*> addu \$a0,\$a0,\$gp
+0+0368 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*368: R_MIPS_GOT_LO16 small_external_data_label
+0+036c <[^>]*> nop
+0+0370 <[^>]*> addu \$a0,\$a0,\$a1
+0+0374 <[^>]*> lui \$a0,0x0
+[ ]*374: R_MIPS_GOT_HI16 big_external_common
+0+0378 <[^>]*> addu \$a0,\$a0,\$gp
+0+037c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*37c: R_MIPS_GOT_LO16 big_external_common
+0+0380 <[^>]*> nop
+0+0384 <[^>]*> addu \$a0,\$a0,\$a1
+0+0388 <[^>]*> lui \$a0,0x0
+[ ]*388: R_MIPS_GOT_HI16 small_external_common
+0+038c <[^>]*> addu \$a0,\$a0,\$gp
+0+0390 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*390: R_MIPS_GOT_LO16 small_external_common
+0+0394 <[^>]*> nop
+0+0398 <[^>]*> addu \$a0,\$a0,\$a1
+0+039c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*39c: R_MIPS_GOT16 .bss
+0+03a0 <[^>]*> nop
+0+03a4 <[^>]*> addiu \$a0,\$a0,0
+[ ]*3a4: R_MIPS_LO16 .bss
+0+03a8 <[^>]*> addu \$a0,\$a0,\$a1
+0+03ac <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3ac: R_MIPS_GOT16 .bss
+0+03b0 <[^>]*> nop
+0+03b4 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*3b4: R_MIPS_LO16 .bss
+0+03b8 <[^>]*> addu \$a0,\$a0,\$a1
+0+03bc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*3bc: R_MIPS_GOT16 .data
+0+03c0 <[^>]*> nop
+0+03c4 <[^>]*> addiu \$a0,\$a0,1
+[ ]*3c4: R_MIPS_LO16 .data
+0+03c8 <[^>]*> addu \$a0,\$a0,\$a1
+0+03cc <[^>]*> lui \$a0,0x0
+[ ]*3cc: R_MIPS_GOT_HI16 big_external_data_label
+0+03d0 <[^>]*> addu \$a0,\$a0,\$gp
+0+03d4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*3d4: R_MIPS_GOT_LO16 big_external_data_label
+0+03d8 <[^>]*> nop
+0+03dc <[^>]*> addiu \$a0,\$a0,1
+0+03e0 <[^>]*> addu \$a0,\$a0,\$a1
+0+03e4 <[^>]*> lui \$a0,0x0
+[ ]*3e4: R_MIPS_GOT_HI16 small_external_data_label
+0+03e8 <[^>]*> addu \$a0,\$a0,\$gp
+0+03ec <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*3ec: R_MIPS_GOT_LO16 small_external_data_label
+0+03f0 <[^>]*> nop
+0+03f4 <[^>]*> addiu \$a0,\$a0,1
+0+03f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+03fc <[^>]*> lui \$a0,0x0
+[ ]*3fc: R_MIPS_GOT_HI16 big_external_common
+0+0400 <[^>]*> addu \$a0,\$a0,\$gp
+0+0404 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*404: R_MIPS_GOT_LO16 big_external_common
+0+0408 <[^>]*> nop
+0+040c <[^>]*> addiu \$a0,\$a0,1
+0+0410 <[^>]*> addu \$a0,\$a0,\$a1
+0+0414 <[^>]*> lui \$a0,0x0
+[ ]*414: R_MIPS_GOT_HI16 small_external_common
+0+0418 <[^>]*> addu \$a0,\$a0,\$gp
+0+041c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*41c: R_MIPS_GOT_LO16 small_external_common
+0+0420 <[^>]*> nop
+0+0424 <[^>]*> addiu \$a0,\$a0,1
+0+0428 <[^>]*> addu \$a0,\$a0,\$a1
+0+042c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*42c: R_MIPS_GOT16 .bss
+0+0430 <[^>]*> nop
+0+0434 <[^>]*> addiu \$a0,\$a0,1
+[ ]*434: R_MIPS_LO16 .bss
+0+0438 <[^>]*> addu \$a0,\$a0,\$a1
+0+043c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*43c: R_MIPS_GOT16 .bss
+0+0440 <[^>]*> nop
+0+0444 <[^>]*> addiu \$a0,\$a0,1001
+[ ]*444: R_MIPS_LO16 .bss
+0+0448 <[^>]*> addu \$a0,\$a0,\$a1
+0+044c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*44c: R_MIPS_GOT16 .data
+0+0450 <[^>]*> lui \$at,0x1
+0+0454 <[^>]*> addiu \$at,\$at,-32768
+[ ]*454: R_MIPS_LO16 .data
+0+0458 <[^>]*> addu \$a0,\$a0,\$at
+0+045c <[^>]*> addu \$a0,\$a0,\$a1
+0+0460 <[^>]*> lui \$a0,0x0
+[ ]*460: R_MIPS_GOT_HI16 big_external_data_label
+0+0464 <[^>]*> addu \$a0,\$a0,\$gp
+0+0468 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*468: R_MIPS_GOT_LO16 big_external_data_label
+0+046c <[^>]*> lui \$at,0x1
+0+0470 <[^>]*> addiu \$at,\$at,-32768
+0+0474 <[^>]*> addu \$a0,\$a0,\$at
+0+0478 <[^>]*> addu \$a0,\$a0,\$a1
+0+047c <[^>]*> lui \$a0,0x0
+[ ]*47c: R_MIPS_GOT_HI16 small_external_data_label
+0+0480 <[^>]*> addu \$a0,\$a0,\$gp
+0+0484 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*484: R_MIPS_GOT_LO16 small_external_data_label
+0+0488 <[^>]*> lui \$at,0x1
+0+048c <[^>]*> addiu \$at,\$at,-32768
+0+0490 <[^>]*> addu \$a0,\$a0,\$at
+0+0494 <[^>]*> addu \$a0,\$a0,\$a1
+0+0498 <[^>]*> lui \$a0,0x0
+[ ]*498: R_MIPS_GOT_HI16 big_external_common
+0+049c <[^>]*> addu \$a0,\$a0,\$gp
+0+04a0 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*4a0: R_MIPS_GOT_LO16 big_external_common
+0+04a4 <[^>]*> lui \$at,0x1
+0+04a8 <[^>]*> addiu \$at,\$at,-32768
+0+04ac <[^>]*> addu \$a0,\$a0,\$at
+0+04b0 <[^>]*> addu \$a0,\$a0,\$a1
+0+04b4 <[^>]*> lui \$a0,0x0
+[ ]*4b4: R_MIPS_GOT_HI16 small_external_common
+0+04b8 <[^>]*> addu \$a0,\$a0,\$gp
+0+04bc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*4bc: R_MIPS_GOT_LO16 small_external_common
+0+04c0 <[^>]*> lui \$at,0x1
+0+04c4 <[^>]*> addiu \$at,\$at,-32768
+0+04c8 <[^>]*> addu \$a0,\$a0,\$at
+0+04cc <[^>]*> addu \$a0,\$a0,\$a1
+0+04d0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4d0: R_MIPS_GOT16 .bss
+0+04d4 <[^>]*> lui \$at,0x1
+0+04d8 <[^>]*> addiu \$at,\$at,-32768
+[ ]*4d8: R_MIPS_LO16 .bss
+0+04dc <[^>]*> addu \$a0,\$a0,\$at
+0+04e0 <[^>]*> addu \$a0,\$a0,\$a1
+0+04e4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4e4: R_MIPS_GOT16 .bss
+0+04e8 <[^>]*> lui \$at,0x1
+0+04ec <[^>]*> addiu \$at,\$at,-31768
+[ ]*4ec: R_MIPS_LO16 .bss
+0+04f0 <[^>]*> addu \$a0,\$a0,\$at
+0+04f4 <[^>]*> addu \$a0,\$a0,\$a1
+0+04f8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*4f8: R_MIPS_GOT16 .data
+0+04fc <[^>]*> nop
+0+0500 <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*500: R_MIPS_LO16 .data
+0+0504 <[^>]*> addu \$a0,\$a0,\$a1
+0+0508 <[^>]*> lui \$a0,0x0
+[ ]*508: R_MIPS_GOT_HI16 big_external_data_label
+0+050c <[^>]*> addu \$a0,\$a0,\$gp
+0+0510 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*510: R_MIPS_GOT_LO16 big_external_data_label
+0+0514 <[^>]*> nop
+0+0518 <[^>]*> addiu \$a0,\$a0,-32768
+0+051c <[^>]*> addu \$a0,\$a0,\$a1
+0+0520 <[^>]*> lui \$a0,0x0
+[ ]*520: R_MIPS_GOT_HI16 small_external_data_label
+0+0524 <[^>]*> addu \$a0,\$a0,\$gp
+0+0528 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*528: R_MIPS_GOT_LO16 small_external_data_label
+0+052c <[^>]*> nop
+0+0530 <[^>]*> addiu \$a0,\$a0,-32768
+0+0534 <[^>]*> addu \$a0,\$a0,\$a1
+0+0538 <[^>]*> lui \$a0,0x0
+[ ]*538: R_MIPS_GOT_HI16 big_external_common
+0+053c <[^>]*> addu \$a0,\$a0,\$gp
+0+0540 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*540: R_MIPS_GOT_LO16 big_external_common
+0+0544 <[^>]*> nop
+0+0548 <[^>]*> addiu \$a0,\$a0,-32768
+0+054c <[^>]*> addu \$a0,\$a0,\$a1
+0+0550 <[^>]*> lui \$a0,0x0
+[ ]*550: R_MIPS_GOT_HI16 small_external_common
+0+0554 <[^>]*> addu \$a0,\$a0,\$gp
+0+0558 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*558: R_MIPS_GOT_LO16 small_external_common
+0+055c <[^>]*> nop
+0+0560 <[^>]*> addiu \$a0,\$a0,-32768
+0+0564 <[^>]*> addu \$a0,\$a0,\$a1
+0+0568 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*568: R_MIPS_GOT16 .bss
+0+056c <[^>]*> nop
+0+0570 <[^>]*> addiu \$a0,\$a0,-32768
+[ ]*570: R_MIPS_LO16 .bss
+0+0574 <[^>]*> addu \$a0,\$a0,\$a1
+0+0578 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*578: R_MIPS_GOT16 .bss
+0+057c <[^>]*> nop
+0+0580 <[^>]*> addiu \$a0,\$a0,-31768
+[ ]*580: R_MIPS_LO16 .bss
+0+0584 <[^>]*> addu \$a0,\$a0,\$a1
+0+0588 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*588: R_MIPS_GOT16 .data
+0+058c <[^>]*> lui \$at,0x1
+0+0590 <[^>]*> addiu \$at,\$at,0
+[ ]*590: R_MIPS_LO16 .data
+0+0594 <[^>]*> addu \$a0,\$a0,\$at
+0+0598 <[^>]*> addu \$a0,\$a0,\$a1
+0+059c <[^>]*> lui \$a0,0x0
+[ ]*59c: R_MIPS_GOT_HI16 big_external_data_label
+0+05a0 <[^>]*> addu \$a0,\$a0,\$gp
+0+05a4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*5a4: R_MIPS_GOT_LO16 big_external_data_label
+0+05a8 <[^>]*> lui \$at,0x1
+0+05ac <[^>]*> addiu \$at,\$at,0
+0+05b0 <[^>]*> addu \$a0,\$a0,\$at
+0+05b4 <[^>]*> addu \$a0,\$a0,\$a1
+0+05b8 <[^>]*> lui \$a0,0x0
+[ ]*5b8: R_MIPS_GOT_HI16 small_external_data_label
+0+05bc <[^>]*> addu \$a0,\$a0,\$gp
+0+05c0 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*5c0: R_MIPS_GOT_LO16 small_external_data_label
+0+05c4 <[^>]*> lui \$at,0x1
+0+05c8 <[^>]*> addiu \$at,\$at,0
+0+05cc <[^>]*> addu \$a0,\$a0,\$at
+0+05d0 <[^>]*> addu \$a0,\$a0,\$a1
+0+05d4 <[^>]*> lui \$a0,0x0
+[ ]*5d4: R_MIPS_GOT_HI16 big_external_common
+0+05d8 <[^>]*> addu \$a0,\$a0,\$gp
+0+05dc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*5dc: R_MIPS_GOT_LO16 big_external_common
+0+05e0 <[^>]*> lui \$at,0x1
+0+05e4 <[^>]*> addiu \$at,\$at,0
+0+05e8 <[^>]*> addu \$a0,\$a0,\$at
+0+05ec <[^>]*> addu \$a0,\$a0,\$a1
+0+05f0 <[^>]*> lui \$a0,0x0
+[ ]*5f0: R_MIPS_GOT_HI16 small_external_common
+0+05f4 <[^>]*> addu \$a0,\$a0,\$gp
+0+05f8 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*5f8: R_MIPS_GOT_LO16 small_external_common
+0+05fc <[^>]*> lui \$at,0x1
+0+0600 <[^>]*> addiu \$at,\$at,0
+0+0604 <[^>]*> addu \$a0,\$a0,\$at
+0+0608 <[^>]*> addu \$a0,\$a0,\$a1
+0+060c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*60c: R_MIPS_GOT16 .bss
+0+0610 <[^>]*> lui \$at,0x1
+0+0614 <[^>]*> addiu \$at,\$at,0
+[ ]*614: R_MIPS_LO16 .bss
+0+0618 <[^>]*> addu \$a0,\$a0,\$at
+0+061c <[^>]*> addu \$a0,\$a0,\$a1
+0+0620 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*620: R_MIPS_GOT16 .bss
+0+0624 <[^>]*> lui \$at,0x1
+0+0628 <[^>]*> addiu \$at,\$at,1000
+[ ]*628: R_MIPS_LO16 .bss
+0+062c <[^>]*> addu \$a0,\$a0,\$at
+0+0630 <[^>]*> addu \$a0,\$a0,\$a1
+0+0634 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*634: R_MIPS_GOT16 .data
+0+0638 <[^>]*> lui \$at,0x2
+0+063c <[^>]*> addiu \$at,\$at,-23131
+[ ]*63c: R_MIPS_LO16 .data
+0+0640 <[^>]*> addu \$a0,\$a0,\$at
+0+0644 <[^>]*> addu \$a0,\$a0,\$a1
+0+0648 <[^>]*> lui \$a0,0x0
+[ ]*648: R_MIPS_GOT_HI16 big_external_data_label
+0+064c <[^>]*> addu \$a0,\$a0,\$gp
+0+0650 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*650: R_MIPS_GOT_LO16 big_external_data_label
+0+0654 <[^>]*> lui \$at,0x2
+0+0658 <[^>]*> addiu \$at,\$at,-23131
+0+065c <[^>]*> addu \$a0,\$a0,\$at
+0+0660 <[^>]*> addu \$a0,\$a0,\$a1
+0+0664 <[^>]*> lui \$a0,0x0
+[ ]*664: R_MIPS_GOT_HI16 small_external_data_label
+0+0668 <[^>]*> addu \$a0,\$a0,\$gp
+0+066c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*66c: R_MIPS_GOT_LO16 small_external_data_label
+0+0670 <[^>]*> lui \$at,0x2
+0+0674 <[^>]*> addiu \$at,\$at,-23131
+0+0678 <[^>]*> addu \$a0,\$a0,\$at
+0+067c <[^>]*> addu \$a0,\$a0,\$a1
+0+0680 <[^>]*> lui \$a0,0x0
+[ ]*680: R_MIPS_GOT_HI16 big_external_common
+0+0684 <[^>]*> addu \$a0,\$a0,\$gp
+0+0688 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*688: R_MIPS_GOT_LO16 big_external_common
+0+068c <[^>]*> lui \$at,0x2
+0+0690 <[^>]*> addiu \$at,\$at,-23131
+0+0694 <[^>]*> addu \$a0,\$a0,\$at
+0+0698 <[^>]*> addu \$a0,\$a0,\$a1
+0+069c <[^>]*> lui \$a0,0x0
+[ ]*69c: R_MIPS_GOT_HI16 small_external_common
+0+06a0 <[^>]*> addu \$a0,\$a0,\$gp
+0+06a4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*6a4: R_MIPS_GOT_LO16 small_external_common
+0+06a8 <[^>]*> lui \$at,0x2
+0+06ac <[^>]*> addiu \$at,\$at,-23131
+0+06b0 <[^>]*> addu \$a0,\$a0,\$at
+0+06b4 <[^>]*> addu \$a0,\$a0,\$a1
+0+06b8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*6b8: R_MIPS_GOT16 .bss
+0+06bc <[^>]*> lui \$at,0x2
+0+06c0 <[^>]*> addiu \$at,\$at,-23131
+[ ]*6c0: R_MIPS_LO16 .bss
+0+06c4 <[^>]*> addu \$a0,\$a0,\$at
+0+06c8 <[^>]*> addu \$a0,\$a0,\$a1
+0+06cc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*6cc: R_MIPS_GOT16 .bss
+0+06d0 <[^>]*> lui \$at,0x2
+0+06d4 <[^>]*> addiu \$at,\$at,-22131
+[ ]*6d4: R_MIPS_LO16 .bss
+0+06d8 <[^>]*> addu \$a0,\$a0,\$at
+0+06dc <[^>]*> addu \$a0,\$a0,\$a1
diff --git a/gas/testsuite/gas/mips/la.d b/gas/testsuite/gas/mips/la.d
new file mode 100644
index 00000000000..25eaa1e905b
--- /dev/null
+++ b/gas/testsuite/gas/mips/la.d
@@ -0,0 +1,384 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS la
+#as: -mips1
+
+# Test the la macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> li \$a0,0
+0+0004 <[^>]*> li \$a0,1
+0+0008 <[^>]*> li \$a0,0x8000
+0+000c <[^>]*> li \$a0,-32768
+0+0010 <[^>]*> lui \$a0,0x1
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+001c <[^>]*> li \$a0,0
+0+0020 <[^>]*> addu \$a0,\$a0,\$a1
+0+0024 <[^>]*> li \$a0,1
+0+0028 <[^>]*> addu \$a0,\$a0,\$a1
+0+002c <[^>]*> li \$a0,0x8000
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> li \$a0,-32768
+0+0038 <[^>]*> addu \$a0,\$a0,\$a1
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lui \$a0,0x1
+0+0048 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lui \$a0,0x0
+[ ]*50: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0054 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*54: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0058 <[^>]*> lui \$a0,0x0
+[ ]*58: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+005c <[^>]*> addiu \$a0,\$a0,0
+[ ]*5c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0060 <[^>]*> addiu \$a0,\$gp,0
+[ ]*60: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0064 <[^>]*> lui \$a0,0x0
+[ ]*64: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0068 <[^>]*> addiu \$a0,\$a0,0
+[ ]*68: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+006c <[^>]*> addiu \$a0,\$gp,0
+[ ]*6c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0070 <[^>]*> lui \$a0,0x0
+[ ]*70: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0074 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*74: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0078 <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*78: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+007c <[^>]*> lui \$a0,0x0
+[ ]*7c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0080 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*80: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0084 <[^>]*> lui \$a0,0x0
+[ ]*84: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0088 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*88: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+008c <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*8c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0090 <[^>]*> lui \$a0,0x0
+[ ]*90: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0094 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*94: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0098 <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*98: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+009c <[^>]*> lui \$a0,0x0
+[ ]*9c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00a0 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*a0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a4 <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*a4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00a8 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*a8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00ac <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*ac: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00b0 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*b0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00b4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00b8 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*b8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+00bc <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*bc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+00c0 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*c0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00c4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*c4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00c8 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*c8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+00cc <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*cc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+00d0 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*d0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00d4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*d4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00d8 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*d8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+00dc <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*dc: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+00e0 <[^>]*> lui \$a0,0x0
+[ ]*e0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00e4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*e4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00e8 <[^>]*> lui \$a0,0x0
+[ ]*e8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00ec <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*ec: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00f0 <[^>]*> lui \$a0,0x0
+[ ]*f0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+00f4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*f4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+00f8 <[^>]*> lui \$a0,0x0
+[ ]*f8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00fc <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0100 <[^>]*> lui \$a0,0x0
+[ ]*100: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0104 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*104: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0108 <[^>]*> lui \$a0,0x0
+[ ]*108: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+010c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*10c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0110 <[^>]*> lui \$a0,0x0
+[ ]*110: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0114 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*114: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0118 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*118: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+011c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*120: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0124 <[^>]*> addiu \$a0,\$a0,0
+[ ]*124: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0128 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*128: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+012c <[^>]*> addiu \$a0,\$a0,0
+[ ]*12c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0130 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*130: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0134 <[^>]*> addiu \$a0,\$a0,0
+[ ]*134: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0138 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+013c <[^>]*> addiu \$a0,\$a0,0
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0140 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*140: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0144 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*144: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0148 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*148: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+014c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0150 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*150: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0154 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*154: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0158 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*158: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+015c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*15c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0160 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*160: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0164 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*164: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0168 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+016c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0170 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*170: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0174 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*174: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0178 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*178: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+017c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0180 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*180: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0184 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*184: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0188 <[^>]*> lui \$a0,0x0
+[ ]*188: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+018c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*18c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0190 <[^>]*> addu \$a0,\$a0,\$a1
+0+0194 <[^>]*> lui \$a0,0x0
+[ ]*194: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0198 <[^>]*> addiu \$a0,\$a0,0
+[ ]*198: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> addu \$a0,\$a0,\$a1
+0+01a0 <[^>]*> addiu \$a0,\$gp,0
+[ ]*1a0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01a4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01a8 <[^>]*> lui \$a0,0x0
+[ ]*1a8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01ac <[^>]*> addiu \$a0,\$a0,0
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01b0 <[^>]*> addu \$a0,\$a0,\$a1
+0+01b4 <[^>]*> addiu \$a0,\$gp,0
+[ ]*1b4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+01b8 <[^>]*> addu \$a0,\$a0,\$a1
+0+01bc <[^>]*> lui \$a0,0x0
+[ ]*1bc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01c0 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*1c0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01c4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01c8 <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*1c8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01cc <[^>]*> addu \$a0,\$a0,\$a1
+0+01d0 <[^>]*> lui \$a0,0x0
+[ ]*1d0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01d4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*1d4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01d8 <[^>]*> addu \$a0,\$a0,\$a1
+0+01dc <[^>]*> lui \$a0,0x0
+[ ]*1dc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01e0 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*1e0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01e4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01e8 <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*1e8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01ec <[^>]*> addu \$a0,\$a0,\$a1
+0+01f0 <[^>]*> lui \$a0,0x0
+[ ]*1f0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01f4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*1f4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+01fc <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*1fc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0200 <[^>]*> addu \$a0,\$a0,\$a1
+0+0204 <[^>]*> lui \$a0,0x0
+[ ]*204: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0208 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*208: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+020c <[^>]*> addu \$a0,\$a0,\$a1
+0+0210 <[^>]*> addiu \$a0,\$gp,[-0-9]+
+[ ]*210: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0214 <[^>]*> addu \$a0,\$a0,\$a1
+0+0218 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*218: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+021c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*21c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0220 <[^>]*> addu \$a0,\$a0,\$a1
+0+0224 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*224: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0228 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*228: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+022c <[^>]*> addu \$a0,\$a0,\$a1
+0+0230 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*230: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0234 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*234: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0238 <[^>]*> addu \$a0,\$a0,\$a1
+0+023c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*23c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0240 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*240: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0244 <[^>]*> addu \$a0,\$a0,\$a1
+0+0248 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*248: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+024c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*24c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0250 <[^>]*> addu \$a0,\$a0,\$a1
+0+0254 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*254: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0258 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*258: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+025c <[^>]*> addu \$a0,\$a0,\$a1
+0+0260 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*260: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0264 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*264: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0268 <[^>]*> addu \$a0,\$a0,\$a1
+0+026c <[^>]*> lui \$a0,0x0
+[ ]*26c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0270 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*270: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0274 <[^>]*> addu \$a0,\$a0,\$a1
+0+0278 <[^>]*> lui \$a0,0x0
+[ ]*278: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+027c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> addu \$a0,\$a0,\$a1
+0+0284 <[^>]*> lui \$a0,0x0
+[ ]*284: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0288 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*288: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> addu \$a0,\$a0,\$a1
+0+0290 <[^>]*> lui \$a0,0x0
+[ ]*290: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0294 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*294: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0298 <[^>]*> addu \$a0,\$a0,\$a1
+0+029c <[^>]*> lui \$a0,0x0
+[ ]*29c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02a0 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*2a0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02a4 <[^>]*> addu \$a0,\$a0,\$a1
+0+02a8 <[^>]*> lui \$a0,0x0
+[ ]*2a8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02ac <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*2ac: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02b0 <[^>]*> addu \$a0,\$a0,\$a1
+0+02b4 <[^>]*> lui \$a0,0x0
+[ ]*2b4: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02b8 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*2b8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02bc <[^>]*> addu \$a0,\$a0,\$a1
+0+02c0 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2c0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+02c4 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*2c4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02c8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02cc <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2cc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+02d0 <[^>]*> addiu \$a0,\$a0,0
+[ ]*2d0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02d4 <[^>]*> addu \$a0,\$a0,\$a1
+0+02d8 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2d8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+02dc <[^>]*> addiu \$a0,\$a0,0
+[ ]*2dc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+02e0 <[^>]*> addu \$a0,\$a0,\$a1
+0+02e4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2e4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02e8 <[^>]*> addiu \$a0,\$a0,0
+[ ]*2e8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02ec <[^>]*> addu \$a0,\$a0,\$a1
+0+02f0 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2f0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02f4 <[^>]*> addiu \$a0,\$a0,0
+[ ]*2f4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02fc <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2fc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0300 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*300: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0304 <[^>]*> addu \$a0,\$a0,\$a1
+0+0308 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*308: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+030c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*30c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0310 <[^>]*> addu \$a0,\$a0,\$a1
+0+0314 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*314: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0318 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*318: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+031c <[^>]*> addu \$a0,\$a0,\$a1
+0+0320 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*320: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0324 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*324: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0328 <[^>]*> addu \$a0,\$a0,\$a1
+0+032c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*32c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0330 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*330: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0334 <[^>]*> addu \$a0,\$a0,\$a1
+0+0338 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*338: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+033c <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*33c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0340 <[^>]*> addu \$a0,\$a0,\$a1
+0+0344 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*344: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0348 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*348: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+034c <[^>]*> addu \$a0,\$a0,\$a1
+0+0350 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*350: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0354 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*354: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0358 <[^>]*> addu \$a0,\$a0,\$a1
+0+035c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*35c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0360 <[^>]*> addiu \$a0,\$a0,[-0-9]+
+[ ]*360: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0364 <[^>]*> addu \$a0,\$a0,\$a1
+ ...
diff --git a/gas/testsuite/gas/mips/la.s b/gas/testsuite/gas/mips/la.s
new file mode 100644
index 00000000000..078c811684f
--- /dev/null
+++ b/gas/testsuite/gas/mips/la.s
@@ -0,0 +1,114 @@
+# Source file used to test the la macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ la $4,0
+ la $4,1
+ la $4,0x8000
+ la $4,-0x8000
+ la $4,0x10000
+ la $4,0x1a5a5
+ la $4,0($5)
+ la $4,1($5)
+ la $4,0x8000($5)
+ la $4,-0x8000($5)
+ la $4,0x10000($5)
+ la $4,0x1a5a5($5)
+ la $4,data_label
+ la $4,big_external_data_label
+ la $4,small_external_data_label
+ la $4,big_external_common
+ la $4,small_external_common
+ la $4,big_local_common
+ la $4,small_local_common
+ la $4,data_label+1
+ la $4,big_external_data_label+1
+ la $4,small_external_data_label+1
+ la $4,big_external_common+1
+ la $4,small_external_common+1
+ la $4,big_local_common+1
+ la $4,small_local_common+1
+ la $4,data_label+0x8000
+ la $4,big_external_data_label+0x8000
+ la $4,small_external_data_label+0x8000
+ la $4,big_external_common+0x8000
+ la $4,small_external_common+0x8000
+ la $4,big_local_common+0x8000
+ la $4,small_local_common+0x8000
+ la $4,data_label-0x8000
+ la $4,big_external_data_label-0x8000
+ la $4,small_external_data_label-0x8000
+ la $4,big_external_common-0x8000
+ la $4,small_external_common-0x8000
+ la $4,big_local_common-0x8000
+ la $4,small_local_common-0x8000
+ la $4,data_label+0x10000
+ la $4,big_external_data_label+0x10000
+ la $4,small_external_data_label+0x10000
+ la $4,big_external_common+0x10000
+ la $4,small_external_common+0x10000
+ la $4,big_local_common+0x10000
+ la $4,small_local_common+0x10000
+ la $4,data_label+0x1a5a5
+ la $4,big_external_data_label+0x1a5a5
+ la $4,small_external_data_label+0x1a5a5
+ la $4,big_external_common+0x1a5a5
+ la $4,small_external_common+0x1a5a5
+ la $4,big_local_common+0x1a5a5
+ la $4,small_local_common+0x1a5a5
+ la $4,data_label($5)
+ la $4,big_external_data_label($5)
+ la $4,small_external_data_label($5)
+ la $4,big_external_common($5)
+ la $4,small_external_common($5)
+ la $4,big_local_common($5)
+ la $4,small_local_common($5)
+ la $4,data_label+1($5)
+ la $4,big_external_data_label+1($5)
+ la $4,small_external_data_label+1($5)
+ la $4,big_external_common+1($5)
+ la $4,small_external_common+1($5)
+ la $4,big_local_common+1($5)
+ la $4,small_local_common+1($5)
+ la $4,data_label+0x8000($5)
+ la $4,big_external_data_label+0x8000($5)
+ la $4,small_external_data_label+0x8000($5)
+ la $4,big_external_common+0x8000($5)
+ la $4,small_external_common+0x8000($5)
+ la $4,big_local_common+0x8000($5)
+ la $4,small_local_common+0x8000($5)
+ la $4,data_label-0x8000($5)
+ la $4,big_external_data_label-0x8000($5)
+ la $4,small_external_data_label-0x8000($5)
+ la $4,big_external_common-0x8000($5)
+ la $4,small_external_common-0x8000($5)
+ la $4,big_local_common-0x8000($5)
+ la $4,small_local_common-0x8000($5)
+ la $4,data_label+0x10000($5)
+ la $4,big_external_data_label+0x10000($5)
+ la $4,small_external_data_label+0x10000($5)
+ la $4,big_external_common+0x10000($5)
+ la $4,small_external_common+0x10000($5)
+ la $4,big_local_common+0x10000($5)
+ la $4,small_local_common+0x10000($5)
+ la $4,data_label+0x1a5a5($5)
+ la $4,big_external_data_label+0x1a5a5($5)
+ la $4,small_external_data_label+0x1a5a5($5)
+ la $4,big_external_common+0x1a5a5($5)
+ la $4,small_external_common+0x1a5a5($5)
+ la $4,big_local_common+0x1a5a5($5)
+ la $4,small_local_common+0x1a5a5($5)
+
+ .ifndef KPIC
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ .endif
diff --git a/gas/testsuite/gas/mips/lb-empic.d b/gas/testsuite/gas/mips/lb-empic.d
new file mode 100644
index 00000000000..9724a32bc6e
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb-empic.d
@@ -0,0 +1,102 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lb-empic
+#as: -mips1 -membedded-pic
+#source: lb-pic.s
+
+# Test the lb macro with -membedded-pic.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lb \$a0,0\(\$zero\)
+0+0004 <[^>]*> lb \$a0,1\(\$zero\)
+0+0008 <[^>]*> lui \$a0,0x1
+0+000c <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0010 <[^>]*> lb \$a0,-32768\(\$zero\)
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> lb \$a0,0\(\$a0\)
+0+001c <[^>]*> lui \$a0,0x2
+0+0020 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0024 <[^>]*> lb \$a0,0\(\$a1\)
+0+0028 <[^>]*> lb \$a0,1\(\$a1\)
+0+002c <[^>]*> lui \$a0,0x1
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0038 <[^>]*> lb \$a0,-32768\(\$a1\)
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lb \$a0,0\(\$a0\)
+0+0048 <[^>]*> lui \$a0,0x2
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0054 <[^>]*> lb \$a0,-16384\(\$gp\)
+[ ]*54: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0058 <[^>]*> lb \$a0,0\(\$gp\)
+[ ]*58: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+005c <[^>]*> lb \$a0,0\(\$gp\)
+[ ]*5c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0060 <[^>]*> lb \$a0,0\(\$gp\)
+[ ]*60: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+0064 <[^>]*> lb \$a0,0\(\$gp\)
+[ ]*64: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0068 <[^>]*> lb \$a0,-16384\(\$gp\)
+[ ]*68: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+006c <[^>]*> lb \$a0,-15384\(\$gp\)
+[ ]*6c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0070 <[^>]*> lb \$a0,-16383\(\$gp\)
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0074 <[^>]*> lb \$a0,1\(\$gp\)
+[ ]*74: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0078 <[^>]*> lb \$a0,1\(\$gp\)
+[ ]*78: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+007c <[^>]*> lb \$a0,1\(\$gp\)
+[ ]*7c: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+0080 <[^>]*> lb \$a0,1\(\$gp\)
+[ ]*80: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0084 <[^>]*> lb \$a0,-16383\(\$gp\)
+[ ]*84: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0088 <[^>]*> lb \$a0,-15383\(\$gp\)
+[ ]*88: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+008c <[^>]*> addu \$a0,\$a1,\$gp
+0+0090 <[^>]*> lb \$a0,-16384\(\$a0\)
+[ ]*90: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0094 <[^>]*> addu \$a0,\$a1,\$gp
+0+0098 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*98: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+009c <[^>]*> addu \$a0,\$a1,\$gp
+0+00a0 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*a0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a4 <[^>]*> addu \$a0,\$a1,\$gp
+0+00a8 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00ac <[^>]*> addu \$a0,\$a1,\$gp
+0+00b0 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*b0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b4 <[^>]*> addu \$a0,\$a1,\$gp
+0+00b8 <[^>]*> lb \$a0,-16384\(\$a0\)
+[ ]*b8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00bc <[^>]*> addu \$a0,\$a1,\$gp
+0+00c0 <[^>]*> lb \$a0,-15384\(\$a0\)
+[ ]*c0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00c4 <[^>]*> addu \$a0,\$a1,\$gp
+0+00c8 <[^>]*> lb \$a0,-16383\(\$a0\)
+[ ]*c8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+00cc <[^>]*> addu \$a0,\$a1,\$gp
+0+00d0 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*d0: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+00d4 <[^>]*> addu \$a0,\$a1,\$gp
+0+00d8 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*d8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00dc <[^>]*> addu \$a0,\$a1,\$gp
+0+00e0 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*e0: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00e4 <[^>]*> addu \$a0,\$a1,\$gp
+0+00e8 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*e8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00ec <[^>]*> addu \$a0,\$a1,\$gp
+0+00f0 <[^>]*> lb \$a0,-16383\(\$a0\)
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00f4 <[^>]*> addu \$a0,\$a1,\$gp
+0+00f8 <[^>]*> lb \$a0,-15383\(\$a0\)
+[ ]*f8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00fc <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/lb-pic.s b/gas/testsuite/gas/mips/lb-pic.s
new file mode 100644
index 00000000000..f2cfdf9b93d
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb-pic.s
@@ -0,0 +1,55 @@
+# Source file used to test the lb macro with PIC code.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ lb $4,0
+ lb $4,1
+ lb $4,0x8000
+ lb $4,-0x8000
+ lb $4,0x10000
+ lb $4,0x1a5a5
+ lb $4,0($5)
+ lb $4,1($5)
+ lb $4,0x8000($5)
+ lb $4,-0x8000($5)
+ lb $4,0x10000($5)
+ lb $4,0x1a5a5($5)
+ lb $4,data_label
+ lb $4,big_external_data_label
+ lb $4,small_external_data_label
+ lb $4,big_external_common
+ lb $4,small_external_common
+ lb $4,big_local_common
+ lb $4,small_local_common
+ lb $4,data_label+1
+ lb $4,big_external_data_label+1
+ lb $4,small_external_data_label+1
+ lb $4,big_external_common+1
+ lb $4,small_external_common+1
+ lb $4,big_local_common+1
+ lb $4,small_local_common+1
+ lb $4,data_label($5)
+ lb $4,big_external_data_label($5)
+ lb $4,small_external_data_label($5)
+ lb $4,big_external_common($5)
+ lb $4,small_external_common($5)
+ lb $4,big_local_common($5)
+ lb $4,small_local_common($5)
+ lb $4,data_label+1($5)
+ lb $4,big_external_data_label+1($5)
+ lb $4,small_external_data_label+1($5)
+ lb $4,big_external_common+1($5)
+ lb $4,small_external_common+1($5)
+ lb $4,big_local_common+1($5)
+ lb $4,small_local_common+1($5)
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
diff --git a/gas/testsuite/gas/mips/lb-svr4pic.d b/gas/testsuite/gas/mips/lb-svr4pic.d
new file mode 100644
index 00000000000..7d884d60ca5
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb-svr4pic.d
@@ -0,0 +1,182 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lb-svr4pic
+#as: -mips1 -KPIC
+#source: lb-pic.s
+
+# Test the lb macro with -KPIC.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lb \$a0,0\(\$zero\)
+0+0004 <[^>]*> lb \$a0,1\(\$zero\)
+0+0008 <[^>]*> lui \$a0,0x1
+0+000c <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0010 <[^>]*> lb \$a0,-32768\(\$zero\)
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> lb \$a0,0\(\$a0\)
+0+001c <[^>]*> lui \$a0,0x2
+0+0020 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0024 <[^>]*> lb \$a0,0\(\$a1\)
+0+0028 <[^>]*> lb \$a0,1\(\$a1\)
+0+002c <[^>]*> lui \$a0,0x1
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0038 <[^>]*> lb \$a0,-32768\(\$a1\)
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lb \$a0,0\(\$a0\)
+0+0048 <[^>]*> lui \$a0,0x2
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0054 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*54: R_MIPS_GOT16 .data
+0+0058 <[^>]*> nop
+0+005c <[^>]*> addiu \$a0,\$a0,0
+[ ]*5c: R_MIPS_LO16 .data
+0+0060 <[^>]*> lb \$a0,0\(\$a0\)
+0+0064 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*64: R_MIPS_GOT16 big_external_data_label
+0+0068 <[^>]*> nop
+0+006c <[^>]*> lb \$a0,0\(\$a0\)
+0+0070 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*70: R_MIPS_GOT16 small_external_data_label
+0+0074 <[^>]*> nop
+0+0078 <[^>]*> lb \$a0,0\(\$a0\)
+0+007c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*7c: R_MIPS_GOT16 big_external_common
+0+0080 <[^>]*> nop
+0+0084 <[^>]*> lb \$a0,0\(\$a0\)
+0+0088 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*88: R_MIPS_GOT16 small_external_common
+0+008c <[^>]*> nop
+0+0090 <[^>]*> lb \$a0,0\(\$a0\)
+0+0094 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*94: R_MIPS_GOT16 .bss
+0+0098 <[^>]*> nop
+0+009c <[^>]*> addiu \$a0,\$a0,0
+[ ]*9c: R_MIPS_LO16 .bss
+0+00a0 <[^>]*> lb \$a0,0\(\$a0\)
+0+00a4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*a4: R_MIPS_GOT16 .bss
+0+00a8 <[^>]*> nop
+0+00ac <[^>]*> addiu \$a0,\$a0,1000
+[ ]*ac: R_MIPS_LO16 .bss
+0+00b0 <[^>]*> lb \$a0,0\(\$a0\)
+0+00b4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*b4: R_MIPS_GOT16 .data
+0+00b8 <[^>]*> nop
+0+00bc <[^>]*> addiu \$a0,\$a0,0
+[ ]*bc: R_MIPS_LO16 .data
+0+00c0 <[^>]*> lb \$a0,1\(\$a0\)
+0+00c4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*c4: R_MIPS_GOT16 big_external_data_label
+0+00c8 <[^>]*> nop
+0+00cc <[^>]*> lb \$a0,1\(\$a0\)
+0+00d0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*d0: R_MIPS_GOT16 small_external_data_label
+0+00d4 <[^>]*> nop
+0+00d8 <[^>]*> lb \$a0,1\(\$a0\)
+0+00dc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*dc: R_MIPS_GOT16 big_external_common
+0+00e0 <[^>]*> nop
+0+00e4 <[^>]*> lb \$a0,1\(\$a0\)
+0+00e8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*e8: R_MIPS_GOT16 small_external_common
+0+00ec <[^>]*> nop
+0+00f0 <[^>]*> lb \$a0,1\(\$a0\)
+0+00f4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*f4: R_MIPS_GOT16 .bss
+0+00f8 <[^>]*> nop
+0+00fc <[^>]*> addiu \$a0,\$a0,0
+[ ]*fc: R_MIPS_LO16 .bss
+0+0100 <[^>]*> lb \$a0,1\(\$a0\)
+0+0104 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*104: R_MIPS_GOT16 .bss
+0+0108 <[^>]*> nop
+0+010c <[^>]*> addiu \$a0,\$a0,1000
+[ ]*10c: R_MIPS_LO16 .bss
+0+0110 <[^>]*> lb \$a0,1\(\$a0\)
+0+0114 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*114: R_MIPS_GOT16 .data
+0+0118 <[^>]*> nop
+0+011c <[^>]*> addiu \$a0,\$a0,0
+[ ]*11c: R_MIPS_LO16 .data
+0+0120 <[^>]*> addu \$a0,\$a0,\$a1
+0+0124 <[^>]*> lb \$a0,0\(\$a0\)
+0+0128 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*128: R_MIPS_GOT16 big_external_data_label
+0+012c <[^>]*> nop
+0+0130 <[^>]*> addu \$a0,\$a0,\$a1
+0+0134 <[^>]*> lb \$a0,0\(\$a0\)
+0+0138 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*138: R_MIPS_GOT16 small_external_data_label
+0+013c <[^>]*> nop
+0+0140 <[^>]*> addu \$a0,\$a0,\$a1
+0+0144 <[^>]*> lb \$a0,0\(\$a0\)
+0+0148 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*148: R_MIPS_GOT16 big_external_common
+0+014c <[^>]*> nop
+0+0150 <[^>]*> addu \$a0,\$a0,\$a1
+0+0154 <[^>]*> lb \$a0,0\(\$a0\)
+0+0158 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*158: R_MIPS_GOT16 small_external_common
+0+015c <[^>]*> nop
+0+0160 <[^>]*> addu \$a0,\$a0,\$a1
+0+0164 <[^>]*> lb \$a0,0\(\$a0\)
+0+0168 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*168: R_MIPS_GOT16 .bss
+0+016c <[^>]*> nop
+0+0170 <[^>]*> addiu \$a0,\$a0,0
+[ ]*170: R_MIPS_LO16 .bss
+0+0174 <[^>]*> addu \$a0,\$a0,\$a1
+0+0178 <[^>]*> lb \$a0,0\(\$a0\)
+0+017c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*17c: R_MIPS_GOT16 .bss
+0+0180 <[^>]*> nop
+0+0184 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*184: R_MIPS_LO16 .bss
+0+0188 <[^>]*> addu \$a0,\$a0,\$a1
+0+018c <[^>]*> lb \$a0,0\(\$a0\)
+0+0190 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*190: R_MIPS_GOT16 .data
+0+0194 <[^>]*> nop
+0+0198 <[^>]*> addiu \$a0,\$a0,0
+[ ]*198: R_MIPS_LO16 .data
+0+019c <[^>]*> addu \$a0,\$a0,\$a1
+0+01a0 <[^>]*> lb \$a0,1\(\$a0\)
+0+01a4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1a4: R_MIPS_GOT16 big_external_data_label
+0+01a8 <[^>]*> nop
+0+01ac <[^>]*> addu \$a0,\$a0,\$a1
+0+01b0 <[^>]*> lb \$a0,1\(\$a0\)
+0+01b4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1b4: R_MIPS_GOT16 small_external_data_label
+0+01b8 <[^>]*> nop
+0+01bc <[^>]*> addu \$a0,\$a0,\$a1
+0+01c0 <[^>]*> lb \$a0,1\(\$a0\)
+0+01c4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1c4: R_MIPS_GOT16 big_external_common
+0+01c8 <[^>]*> nop
+0+01cc <[^>]*> addu \$a0,\$a0,\$a1
+0+01d0 <[^>]*> lb \$a0,1\(\$a0\)
+0+01d4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1d4: R_MIPS_GOT16 small_external_common
+0+01d8 <[^>]*> nop
+0+01dc <[^>]*> addu \$a0,\$a0,\$a1
+0+01e0 <[^>]*> lb \$a0,1\(\$a0\)
+0+01e4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1e4: R_MIPS_GOT16 .bss
+0+01e8 <[^>]*> nop
+0+01ec <[^>]*> addiu \$a0,\$a0,0
+[ ]*1ec: R_MIPS_LO16 .bss
+0+01f0 <[^>]*> addu \$a0,\$a0,\$a1
+0+01f4 <[^>]*> lb \$a0,1\(\$a0\)
+0+01f8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1f8: R_MIPS_GOT16 .bss
+0+01fc <[^>]*> nop
+0+0200 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*200: R_MIPS_LO16 .bss
+0+0204 <[^>]*> addu \$a0,\$a0,\$a1
+0+0208 <[^>]*> lb \$a0,1\(\$a0\)
+0+020c <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/lb-xgot-ilocks.d b/gas/testsuite/gas/mips/lb-xgot-ilocks.d
new file mode 100644
index 00000000000..c08bd24c97b
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb-xgot-ilocks.d
@@ -0,0 +1,214 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lb-xgot-ilocks
+#as: -mips1 -KPIC -xgot -mcpu=r3900
+#source: lb-pic.s
+
+# Test the lb macro with -KPIC -xgot.
+
+.*: +file format .*
+
+Disassembly of section \.text:
+0+0000 <.*> lb \$a0,0\(\$zero\)
+0+0004 <.*> lb \$a0,1\(\$zero\)
+0+0008 <.*> lui \$a0,0x1
+0+000c <.*> lb \$a0,-32768\(\$a0\)
+0+0010 <.*> lb \$a0,-32768\(\$zero\)
+0+0014 <.*> lui \$a0,0x1
+0+0018 <.*> lb \$a0,0\(\$a0\)
+0+001c <.*> lui \$a0,0x2
+0+0020 <.*> lb \$a0,-23131\(\$a0\)
+0+0024 <.*> lb \$a0,0\(\$a1\)
+0+0028 <.*> lb \$a0,1\(\$a1\)
+0+002c <.*> lui \$a0,0x1
+0+0030 <.*> addu \$a0,\$a0,\$a1
+0+0034 <.*> lb \$a0,-32768\(\$a0\)
+0+0038 <.*> lb \$a0,-32768\(\$a1\)
+0+003c <.*> lui \$a0,0x1
+0+0040 <.*> addu \$a0,\$a0,\$a1
+0+0044 <.*> lb \$a0,0\(\$a0\)
+0+0048 <.*> lui \$a0,0x2
+0+004c <.*> addu \$a0,\$a0,\$a1
+0+0050 <.*> lb \$a0,-23131\(\$a0\)
+0+0054 <.*> lw \$a0,0\(\$gp\)
+ 54: R_MIPS_GOT16 \.data
+0+0058 <.*> nop
+0+005c <.*> addiu \$a0,\$a0,0
+ 5c: R_MIPS_LO16 \.data
+0+0060 <.*> lb \$a0,0\(\$a0\)
+0+0064 <.*> lui \$a0,0x0
+ 64: R_MIPS_GOT_HI16 big_external_data_label
+0+0068 <.*> addu \$a0,\$a0,\$gp
+0+006c <.*> lw \$a0,0\(\$a0\)
+ 6c: R_MIPS_GOT_LO16 big_external_data_label
+0+0070 <.*> lb \$a0,0\(\$a0\)
+0+0074 <.*> lui \$a0,0x0
+ 74: R_MIPS_GOT_HI16 small_external_data_label
+0+0078 <.*> addu \$a0,\$a0,\$gp
+0+007c <.*> lw \$a0,0\(\$a0\)
+ 7c: R_MIPS_GOT_LO16 small_external_data_label
+0+0080 <.*> lb \$a0,0\(\$a0\)
+0+0084 <.*> lui \$a0,0x0
+ 84: R_MIPS_GOT_HI16 big_external_common
+0+0088 <.*> addu \$a0,\$a0,\$gp
+0+008c <.*> lw \$a0,0\(\$a0\)
+ 8c: R_MIPS_GOT_LO16 big_external_common
+0+0090 <.*> lb \$a0,0\(\$a0\)
+0+0094 <.*> lui \$a0,0x0
+ 94: R_MIPS_GOT_HI16 small_external_common
+0+0098 <.*> addu \$a0,\$a0,\$gp
+0+009c <.*> lw \$a0,0\(\$a0\)
+ 9c: R_MIPS_GOT_LO16 small_external_common
+0+00a0 <.*> lb \$a0,0\(\$a0\)
+0+00a4 <.*> lw \$a0,0\(\$gp\)
+ a4: R_MIPS_GOT16 \.bss
+0+00a8 <.*> nop
+0+00ac <.*> addiu \$a0,\$a0,0
+ ac: R_MIPS_LO16 \.bss
+0+00b0 <.*> lb \$a0,0\(\$a0\)
+0+00b4 <.*> lw \$a0,0\(\$gp\)
+ b4: R_MIPS_GOT16 \.bss
+0+00b8 <.*> nop
+0+00bc <.*> addiu \$a0,\$a0,1000
+ bc: R_MIPS_LO16 \.bss
+0+00c0 <.*> lb \$a0,0\(\$a0\)
+0+00c4 <.*> lw \$a0,0\(\$gp\)
+ c4: R_MIPS_GOT16 \.data
+0+00c8 <.*> nop
+0+00cc <.*> addiu \$a0,\$a0,0
+ cc: R_MIPS_LO16 \.data
+0+00d0 <.*> lb \$a0,1\(\$a0\)
+0+00d4 <.*> lui \$a0,0x0
+ d4: R_MIPS_GOT_HI16 big_external_data_label
+0+00d8 <.*> addu \$a0,\$a0,\$gp
+0+00dc <.*> lw \$a0,0\(\$a0\)
+ dc: R_MIPS_GOT_LO16 big_external_data_label
+0+00e0 <.*> lb \$a0,1\(\$a0\)
+0+00e4 <.*> lui \$a0,0x0
+ e4: R_MIPS_GOT_HI16 small_external_data_label
+0+00e8 <.*> addu \$a0,\$a0,\$gp
+0+00ec <.*> lw \$a0,0\(\$a0\)
+ ec: R_MIPS_GOT_LO16 small_external_data_label
+0+00f0 <.*> lb \$a0,1\(\$a0\)
+0+00f4 <.*> lui \$a0,0x0
+ f4: R_MIPS_GOT_HI16 big_external_common
+0+00f8 <.*> addu \$a0,\$a0,\$gp
+0+00fc <.*> lw \$a0,0\(\$a0\)
+ fc: R_MIPS_GOT_LO16 big_external_common
+0+0100 <.*> lb \$a0,1\(\$a0\)
+0+0104 <.*> lui \$a0,0x0
+ 104: R_MIPS_GOT_HI16 small_external_common
+0+0108 <.*> addu \$a0,\$a0,\$gp
+0+010c <.*> lw \$a0,0\(\$a0\)
+ 10c: R_MIPS_GOT_LO16 small_external_common
+0+0110 <.*> lb \$a0,1\(\$a0\)
+0+0114 <.*> lw \$a0,0\(\$gp\)
+ 114: R_MIPS_GOT16 \.bss
+0+0118 <.*> nop
+0+011c <.*> addiu \$a0,\$a0,0
+ 11c: R_MIPS_LO16 \.bss
+0+0120 <.*> lb \$a0,1\(\$a0\)
+0+0124 <.*> lw \$a0,0\(\$gp\)
+ 124: R_MIPS_GOT16 \.bss
+0+0128 <.*> nop
+0+012c <.*> addiu \$a0,\$a0,1000
+ 12c: R_MIPS_LO16 \.bss
+0+0130 <.*> lb \$a0,1\(\$a0\)
+0+0134 <.*> lw \$a0,0\(\$gp\)
+ 134: R_MIPS_GOT16 \.data
+0+0138 <.*> nop
+0+013c <.*> addiu \$a0,\$a0,0
+ 13c: R_MIPS_LO16 \.data
+0+0140 <.*> addu \$a0,\$a0,\$a1
+0+0144 <.*> lb \$a0,0\(\$a0\)
+0+0148 <.*> lui \$a0,0x0
+ 148: R_MIPS_GOT_HI16 big_external_data_label
+0+014c <.*> addu \$a0,\$a0,\$gp
+0+0150 <.*> lw \$a0,0\(\$a0\)
+ 150: R_MIPS_GOT_LO16 big_external_data_label
+0+0154 <.*> addu \$a0,\$a0,\$a1
+0+0158 <.*> lb \$a0,0\(\$a0\)
+0+015c <.*> lui \$a0,0x0
+ 15c: R_MIPS_GOT_HI16 small_external_data_label
+0+0160 <.*> addu \$a0,\$a0,\$gp
+0+0164 <.*> lw \$a0,0\(\$a0\)
+ 164: R_MIPS_GOT_LO16 small_external_data_label
+0+0168 <.*> addu \$a0,\$a0,\$a1
+0+016c <.*> lb \$a0,0\(\$a0\)
+0+0170 <.*> lui \$a0,0x0
+ 170: R_MIPS_GOT_HI16 big_external_common
+0+0174 <.*> addu \$a0,\$a0,\$gp
+0+0178 <.*> lw \$a0,0\(\$a0\)
+ 178: R_MIPS_GOT_LO16 big_external_common
+0+017c <.*> addu \$a0,\$a0,\$a1
+0+0180 <.*> lb \$a0,0\(\$a0\)
+0+0184 <.*> lui \$a0,0x0
+ 184: R_MIPS_GOT_HI16 small_external_common
+0+0188 <.*> addu \$a0,\$a0,\$gp
+0+018c <.*> lw \$a0,0\(\$a0\)
+ 18c: R_MIPS_GOT_LO16 small_external_common
+0+0190 <.*> addu \$a0,\$a0,\$a1
+0+0194 <.*> lb \$a0,0\(\$a0\)
+0+0198 <.*> lw \$a0,0\(\$gp\)
+ 198: R_MIPS_GOT16 \.bss
+0+019c <.*> nop
+0+01a0 <.*> addiu \$a0,\$a0,0
+ 1a0: R_MIPS_LO16 \.bss
+0+01a4 <.*> addu \$a0,\$a0,\$a1
+0+01a8 <.*> lb \$a0,0\(\$a0\)
+0+01ac <.*> lw \$a0,0\(\$gp\)
+ 1ac: R_MIPS_GOT16 \.bss
+0+01b0 <.*> nop
+0+01b4 <.*> addiu \$a0,\$a0,1000
+ 1b4: R_MIPS_LO16 \.bss
+0+01b8 <.*> addu \$a0,\$a0,\$a1
+0+01bc <.*> lb \$a0,0\(\$a0\)
+0+01c0 <.*> lw \$a0,0\(\$gp\)
+ 1c0: R_MIPS_GOT16 \.data
+0+01c4 <.*> nop
+0+01c8 <.*> addiu \$a0,\$a0,0
+ 1c8: R_MIPS_LO16 \.data
+0+01cc <.*> addu \$a0,\$a0,\$a1
+0+01d0 <.*> lb \$a0,1\(\$a0\)
+0+01d4 <.*> lui \$a0,0x0
+ 1d4: R_MIPS_GOT_HI16 big_external_data_label
+0+01d8 <.*> addu \$a0,\$a0,\$gp
+0+01dc <.*> lw \$a0,0\(\$a0\)
+ 1dc: R_MIPS_GOT_LO16 big_external_data_label
+0+01e0 <.*> addu \$a0,\$a0,\$a1
+0+01e4 <.*> lb \$a0,1\(\$a0\)
+0+01e8 <.*> lui \$a0,0x0
+ 1e8: R_MIPS_GOT_HI16 small_external_data_label
+0+01ec <.*> addu \$a0,\$a0,\$gp
+0+01f0 <.*> lw \$a0,0\(\$a0\)
+ 1f0: R_MIPS_GOT_LO16 small_external_data_label
+0+01f4 <.*> addu \$a0,\$a0,\$a1
+0+01f8 <.*> lb \$a0,1\(\$a0\)
+0+01fc <.*> lui \$a0,0x0
+ 1fc: R_MIPS_GOT_HI16 big_external_common
+0+0200 <.*> addu \$a0,\$a0,\$gp
+0+0204 <.*> lw \$a0,0\(\$a0\)
+ 204: R_MIPS_GOT_LO16 big_external_common
+0+0208 <.*> addu \$a0,\$a0,\$a1
+0+020c <.*> lb \$a0,1\(\$a0\)
+0+0210 <.*> lui \$a0,0x0
+ 210: R_MIPS_GOT_HI16 small_external_common
+0+0214 <.*> addu \$a0,\$a0,\$gp
+0+0218 <.*> lw \$a0,0\(\$a0\)
+ 218: R_MIPS_GOT_LO16 small_external_common
+0+021c <.*> addu \$a0,\$a0,\$a1
+0+0220 <.*> lb \$a0,1\(\$a0\)
+0+0224 <.*> lw \$a0,0\(\$gp\)
+ 224: R_MIPS_GOT16 \.bss
+0+0228 <.*> nop
+0+022c <.*> addiu \$a0,\$a0,0
+ 22c: R_MIPS_LO16 \.bss
+0+0230 <.*> addu \$a0,\$a0,\$a1
+0+0234 <.*> lb \$a0,1\(\$a0\)
+0+0238 <.*> lw \$a0,0\(\$gp\)
+ 238: R_MIPS_GOT16 \.bss
+0+023c <.*> nop
+0+0240 <.*> addiu \$a0,\$a0,1000
+ 240: R_MIPS_LO16 \.bss
+0+0244 <.*> addu \$a0,\$a0,\$a1
+0+0248 <.*> lb \$a0,1\(\$a0\)
+0+024c <.*> nop
diff --git a/gas/testsuite/gas/mips/lb-xgot.d b/gas/testsuite/gas/mips/lb-xgot.d
new file mode 100644
index 00000000000..b18c67e5970
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb-xgot.d
@@ -0,0 +1,242 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lb-xgot
+#as: -mips1 -KPIC -xgot -mcpu=r3000
+#source: lb-pic.s
+
+# Test the lb macro with -KPIC -xgot.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lb \$a0,0\(\$zero\)
+0+0004 <[^>]*> lb \$a0,1\(\$zero\)
+0+0008 <[^>]*> lui \$a0,0x1
+0+000c <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0010 <[^>]*> lb \$a0,-32768\(\$zero\)
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> lb \$a0,0\(\$a0\)
+0+001c <[^>]*> lui \$a0,0x2
+0+0020 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0024 <[^>]*> lb \$a0,0\(\$a1\)
+0+0028 <[^>]*> lb \$a0,1\(\$a1\)
+0+002c <[^>]*> lui \$a0,0x1
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0038 <[^>]*> lb \$a0,-32768\(\$a1\)
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lb \$a0,0\(\$a0\)
+0+0048 <[^>]*> lui \$a0,0x2
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0054 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*54: R_MIPS_GOT16 .data
+0+0058 <[^>]*> nop
+0+005c <[^>]*> addiu \$a0,\$a0,0
+[ ]*5c: R_MIPS_LO16 .data
+0+0060 <[^>]*> nop
+0+0064 <[^>]*> lb \$a0,0\(\$a0\)
+0+0068 <[^>]*> lui \$a0,0x0
+[ ]*68: R_MIPS_GOT_HI16 big_external_data_label
+0+006c <[^>]*> addu \$a0,\$a0,\$gp
+0+0070 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*70: R_MIPS_GOT_LO16 big_external_data_label
+0+0074 <[^>]*> nop
+0+0078 <[^>]*> lb \$a0,0\(\$a0\)
+0+007c <[^>]*> lui \$a0,0x0
+[ ]*7c: R_MIPS_GOT_HI16 small_external_data_label
+0+0080 <[^>]*> addu \$a0,\$a0,\$gp
+0+0084 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*84: R_MIPS_GOT_LO16 small_external_data_label
+0+0088 <[^>]*> nop
+0+008c <[^>]*> lb \$a0,0\(\$a0\)
+0+0090 <[^>]*> lui \$a0,0x0
+[ ]*90: R_MIPS_GOT_HI16 big_external_common
+0+0094 <[^>]*> addu \$a0,\$a0,\$gp
+0+0098 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*98: R_MIPS_GOT_LO16 big_external_common
+0+009c <[^>]*> nop
+0+00a0 <[^>]*> lb \$a0,0\(\$a0\)
+0+00a4 <[^>]*> lui \$a0,0x0
+[ ]*a4: R_MIPS_GOT_HI16 small_external_common
+0+00a8 <[^>]*> addu \$a0,\$a0,\$gp
+0+00ac <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*ac: R_MIPS_GOT_LO16 small_external_common
+0+00b0 <[^>]*> nop
+0+00b4 <[^>]*> lb \$a0,0\(\$a0\)
+0+00b8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*b8: R_MIPS_GOT16 .bss
+0+00bc <[^>]*> nop
+0+00c0 <[^>]*> addiu \$a0,\$a0,0
+[ ]*c0: R_MIPS_LO16 .bss
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> lb \$a0,0\(\$a0\)
+0+00cc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*cc: R_MIPS_GOT16 .bss
+0+00d0 <[^>]*> nop
+0+00d4 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*d4: R_MIPS_LO16 .bss
+0+00d8 <[^>]*> nop
+0+00dc <[^>]*> lb \$a0,0\(\$a0\)
+0+00e0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*e0: R_MIPS_GOT16 .data
+0+00e4 <[^>]*> nop
+0+00e8 <[^>]*> addiu \$a0,\$a0,0
+[ ]*e8: R_MIPS_LO16 .data
+0+00ec <[^>]*> nop
+0+00f0 <[^>]*> lb \$a0,1\(\$a0\)
+0+00f4 <[^>]*> lui \$a0,0x0
+[ ]*f4: R_MIPS_GOT_HI16 big_external_data_label
+0+00f8 <[^>]*> addu \$a0,\$a0,\$gp
+0+00fc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*fc: R_MIPS_GOT_LO16 big_external_data_label
+0+0100 <[^>]*> nop
+0+0104 <[^>]*> lb \$a0,1\(\$a0\)
+0+0108 <[^>]*> lui \$a0,0x0
+[ ]*108: R_MIPS_GOT_HI16 small_external_data_label
+0+010c <[^>]*> addu \$a0,\$a0,\$gp
+0+0110 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*110: R_MIPS_GOT_LO16 small_external_data_label
+0+0114 <[^>]*> nop
+0+0118 <[^>]*> lb \$a0,1\(\$a0\)
+0+011c <[^>]*> lui \$a0,0x0
+[ ]*11c: R_MIPS_GOT_HI16 big_external_common
+0+0120 <[^>]*> addu \$a0,\$a0,\$gp
+0+0124 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*124: R_MIPS_GOT_LO16 big_external_common
+0+0128 <[^>]*> nop
+0+012c <[^>]*> lb \$a0,1\(\$a0\)
+0+0130 <[^>]*> lui \$a0,0x0
+[ ]*130: R_MIPS_GOT_HI16 small_external_common
+0+0134 <[^>]*> addu \$a0,\$a0,\$gp
+0+0138 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*138: R_MIPS_GOT_LO16 small_external_common
+0+013c <[^>]*> nop
+0+0140 <[^>]*> lb \$a0,1\(\$a0\)
+0+0144 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*144: R_MIPS_GOT16 .bss
+0+0148 <[^>]*> nop
+0+014c <[^>]*> addiu \$a0,\$a0,0
+[ ]*14c: R_MIPS_LO16 .bss
+0+0150 <[^>]*> nop
+0+0154 <[^>]*> lb \$a0,1\(\$a0\)
+0+0158 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*158: R_MIPS_GOT16 .bss
+0+015c <[^>]*> nop
+0+0160 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*160: R_MIPS_LO16 .bss
+0+0164 <[^>]*> nop
+0+0168 <[^>]*> lb \$a0,1\(\$a0\)
+0+016c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*16c: R_MIPS_GOT16 .data
+0+0170 <[^>]*> nop
+0+0174 <[^>]*> addiu \$a0,\$a0,0
+[ ]*174: R_MIPS_LO16 .data
+0+0178 <[^>]*> nop
+0+017c <[^>]*> addu \$a0,\$a0,\$a1
+0+0180 <[^>]*> lb \$a0,0\(\$a0\)
+0+0184 <[^>]*> lui \$a0,0x0
+[ ]*184: R_MIPS_GOT_HI16 big_external_data_label
+0+0188 <[^>]*> addu \$a0,\$a0,\$gp
+0+018c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*18c: R_MIPS_GOT_LO16 big_external_data_label
+0+0190 <[^>]*> nop
+0+0194 <[^>]*> addu \$a0,\$a0,\$a1
+0+0198 <[^>]*> lb \$a0,0\(\$a0\)
+0+019c <[^>]*> lui \$a0,0x0
+[ ]*19c: R_MIPS_GOT_HI16 small_external_data_label
+0+01a0 <[^>]*> addu \$a0,\$a0,\$gp
+0+01a4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1a4: R_MIPS_GOT_LO16 small_external_data_label
+0+01a8 <[^>]*> nop
+0+01ac <[^>]*> addu \$a0,\$a0,\$a1
+0+01b0 <[^>]*> lb \$a0,0\(\$a0\)
+0+01b4 <[^>]*> lui \$a0,0x0
+[ ]*1b4: R_MIPS_GOT_HI16 big_external_common
+0+01b8 <[^>]*> addu \$a0,\$a0,\$gp
+0+01bc <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1bc: R_MIPS_GOT_LO16 big_external_common
+0+01c0 <[^>]*> nop
+0+01c4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01c8 <[^>]*> lb \$a0,0\(\$a0\)
+0+01cc <[^>]*> lui \$a0,0x0
+[ ]*1cc: R_MIPS_GOT_HI16 small_external_common
+0+01d0 <[^>]*> addu \$a0,\$a0,\$gp
+0+01d4 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*1d4: R_MIPS_GOT_LO16 small_external_common
+0+01d8 <[^>]*> nop
+0+01dc <[^>]*> addu \$a0,\$a0,\$a1
+0+01e0 <[^>]*> lb \$a0,0\(\$a0\)
+0+01e4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1e4: R_MIPS_GOT16 .bss
+0+01e8 <[^>]*> nop
+0+01ec <[^>]*> addiu \$a0,\$a0,0
+[ ]*1ec: R_MIPS_LO16 .bss
+0+01f0 <[^>]*> nop
+0+01f4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01f8 <[^>]*> lb \$a0,0\(\$a0\)
+0+01fc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*1fc: R_MIPS_GOT16 .bss
+0+0200 <[^>]*> nop
+0+0204 <[^>]*> addiu \$a0,\$a0,1000
+[ ]*204: R_MIPS_LO16 .bss
+0+0208 <[^>]*> nop
+0+020c <[^>]*> addu \$a0,\$a0,\$a1
+0+0210 <[^>]*> lb \$a0,0\(\$a0\)
+0+0214 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*214: R_MIPS_GOT16 .data
+0+0218 <[^>]*> nop
+0+021c <[^>]*> addiu \$a0,\$a0,0
+[ ]*21c: R_MIPS_LO16 .data
+0+0220 <[^>]*> nop
+0+0224 <[^>]*> addu \$a0,\$a0,\$a1
+0+0228 <[^>]*> lb \$a0,1\(\$a0\)
+0+022c <[^>]*> lui \$a0,0x0
+[ ]*22c: R_MIPS_GOT_HI16 big_external_data_label
+0+0230 <[^>]*> addu \$a0,\$a0,\$gp
+0+0234 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*234: R_MIPS_GOT_LO16 big_external_data_label
+0+0238 <[^>]*> nop
+0+023c <[^>]*> addu \$a0,\$a0,\$a1
+0+0240 <[^>]*> lb \$a0,1\(\$a0\)
+0+0244 <[^>]*> lui \$a0,0x0
+[ ]*244: R_MIPS_GOT_HI16 small_external_data_label
+0+0248 <[^>]*> addu \$a0,\$a0,\$gp
+0+024c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*24c: R_MIPS_GOT_LO16 small_external_data_label
+0+0250 <[^>]*> nop
+0+0254 <[^>]*> addu \$a0,\$a0,\$a1
+0+0258 <[^>]*> lb \$a0,1\(\$a0\)
+0+025c <[^>]*> lui \$a0,0x0
+[ ]*25c: R_MIPS_GOT_HI16 big_external_common
+0+0260 <[^>]*> addu \$a0,\$a0,\$gp
+0+0264 <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*264: R_MIPS_GOT_LO16 big_external_common
+0+0268 <[^>]*> nop
+0+026c <[^>]*> addu \$a0,\$a0,\$a1
+0+0270 <[^>]*> lb \$a0,1\(\$a0\)
+0+0274 <[^>]*> lui \$a0,0x0
+[ ]*274: R_MIPS_GOT_HI16 small_external_common
+0+0278 <[^>]*> addu \$a0,\$a0,\$gp
+0+027c <[^>]*> lw \$a0,0\(\$a0\)
+[ ]*27c: R_MIPS_GOT_LO16 small_external_common
+0+0280 <[^>]*> nop
+0+0284 <[^>]*> addu \$a0,\$a0,\$a1
+0+0288 <[^>]*> lb \$a0,1\(\$a0\)
+0+028c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*28c: R_MIPS_GOT16 .bss
+0+0290 <[^>]*> nop
+0+0294 <[^>]*> addiu \$a0,\$a0,0
+[ ]*294: R_MIPS_LO16 .bss
+0+0298 <[^>]*> nop
+0+029c <[^>]*> addu \$a0,\$a0,\$a1
+0+02a0 <[^>]*> lb \$a0,1\(\$a0\)
+0+02a4 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*2a4: R_MIPS_GOT16 .bss
+0+02a8 <[^>]*> nop
+0+02ac <[^>]*> addiu \$a0,\$a0,1000
+[ ]*2ac: R_MIPS_LO16 .bss
+0+02b0 <[^>]*> nop
+0+02b4 <[^>]*> addu \$a0,\$a0,\$a1
+0+02b8 <[^>]*> lb \$a0,1\(\$a0\)
+0+02bc <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/lb.d b/gas/testsuite/gas/mips/lb.d
new file mode 100644
index 00000000000..e45c4c4ca64
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb.d
@@ -0,0 +1,395 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lb
+#as: -mips1
+
+# Test the lb macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lb \$a0,0\(\$zero\)
+0+0004 <[^>]*> lb \$a0,1\(\$zero\)
+0+0008 <[^>]*> lui \$a0,0x1
+0+000c <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0010 <[^>]*> lb \$a0,-32768\(\$zero\)
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> lb \$a0,0\(\$a0\)
+0+001c <[^>]*> lui \$a0,0x2
+0+0020 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0024 <[^>]*> lb \$a0,0\(\$a1\)
+0+0028 <[^>]*> lb \$a0,1\(\$a1\)
+0+002c <[^>]*> lui \$a0,0x1
+0+0030 <[^>]*> addu \$a0,\$a0,\$a1
+0+0034 <[^>]*> lb \$a0,-32768\(\$a0\)
+0+0038 <[^>]*> lb \$a0,-32768\(\$a1\)
+0+003c <[^>]*> lui \$a0,0x1
+0+0040 <[^>]*> addu \$a0,\$a0,\$a1
+0+0044 <[^>]*> lb \$a0,0\(\$a0\)
+0+0048 <[^>]*> lui \$a0,0x2
+0+004c <[^>]*> addu \$a0,\$a0,\$a1
+0+0050 <[^>]*> lb \$a0,-23131\(\$a0\)
+0+0054 <[^>]*> lui \$a0,0x0
+[ ]*54: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0058 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*58: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+005c <[^>]*> lui \$a0,0x0
+[ ]*5c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0060 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*60: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0064 <[^>]*> lb \$a0,0\(\$gp\)
+[ ]*64: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0068 <[^>]*> lui \$a0,0x0
+[ ]*68: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+006c <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*6c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0070 <[^>]*> lb \$a0,0\(\$gp\)
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0074 <[^>]*> lui \$a0,0x0
+[ ]*74: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0078 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*78: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+007c <[^>]*> lb \$a0,-16384\(\$gp\)
+[ ]*7c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0080 <[^>]*> lui \$a0,0x0
+[ ]*80: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0084 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*84: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0088 <[^>]*> lui \$a0,0x0
+[ ]*88: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+008c <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*8c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0090 <[^>]*> lb \$a0,1\(\$gp\)
+[ ]*90: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0094 <[^>]*> lui \$a0,0x0
+[ ]*94: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0098 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*98: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+009c <[^>]*> lb \$a0,1\(\$gp\)
+[ ]*9c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00a0 <[^>]*> lui \$a0,0x0
+[ ]*a0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00a4 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*a4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a8 <[^>]*> lb \$a0,[-0-9]+\(\$gp\)
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ac <[^>]*> lui \$a0,[-0-9x]+
+[ ]*ac: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00b0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*b0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00b4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00b8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00bc <[^>]*> lui \$a0,[-0-9x]+
+[ ]*bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+00c0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*c0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+00c4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00c8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00cc <[^>]*> lui \$a0,[-0-9x]+
+[ ]*cc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+00d0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*d0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+00d4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*d4: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00d8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*d8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00dc <[^>]*> lui \$a0,[-0-9x]+
+[ ]*dc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+00e0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*e0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+00e4 <[^>]*> lui \$a0,0x0
+[ ]*e4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00e8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*e8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00ec <[^>]*> lui \$a0,0x0
+[ ]*ec: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00f0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00f4 <[^>]*> lui \$a0,0x0
+[ ]*f4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+00f8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*f8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+00fc <[^>]*> lui \$a0,0x0
+[ ]*fc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0100 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0104 <[^>]*> lui \$a0,0x0
+[ ]*104: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0108 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*108: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+010c <[^>]*> lui \$a0,0x0
+[ ]*10c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0110 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*110: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0114 <[^>]*> lui \$a0,0x0
+[ ]*114: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0118 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*118: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+011c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*11c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0120 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*120: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0124 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*124: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0128 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*128: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0130 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0134 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*134: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0138 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*138: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+013c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*13c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0140 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*140: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0144 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*144: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0148 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*148: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+014c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*14c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0150 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*150: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0154 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*154: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0158 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*158: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+015c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*15c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0160 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*160: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0164 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*164: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0168 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*168: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+016c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*16c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0170 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*170: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0174 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*174: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0178 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*178: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+017c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*17c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0180 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*180: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0184 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*184: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0188 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*188: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+018c <[^>]*> lui \$a0,0x0
+[ ]*18c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0190 <[^>]*> addu \$a0,\$a0,\$a1
+0+0194 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*194: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0198 <[^>]*> lui \$a0,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> addu \$a0,\$a0,\$a1
+0+01a0 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*1a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01a4 <[^>]*> addu \$a0,\$a1,\$gp
+0+01a8 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*1a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> lui \$a0,0x0
+[ ]*1ac: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01b0 <[^>]*> addu \$a0,\$a0,\$a1
+0+01b4 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*1b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01b8 <[^>]*> addu \$a0,\$a1,\$gp
+0+01bc <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*1bc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+01c0 <[^>]*> lui \$a0,0x0
+[ ]*1c0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01c4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01c8 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*1c8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01cc <[^>]*> addu \$a0,\$a1,\$gp
+0+01d0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*1d0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01d4 <[^>]*> lui \$a0,0x0
+[ ]*1d4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01d8 <[^>]*> addu \$a0,\$a0,\$a1
+0+01dc <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01e0 <[^>]*> lui \$a0,0x0
+[ ]*1e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01e4 <[^>]*> addu \$a0,\$a0,\$a1
+0+01e8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*1e8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01ec <[^>]*> addu \$a0,\$a1,\$gp
+0+01f0 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*1f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01f4 <[^>]*> lui \$a0,0x0
+[ ]*1f4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+01fc <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0200 <[^>]*> addu \$a0,\$a1,\$gp
+0+0204 <[^>]*> lb \$a0,1\(\$a0\)
+[ ]*204: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0208 <[^>]*> lui \$a0,0x0
+[ ]*208: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+020c <[^>]*> addu \$a0,\$a0,\$a1
+0+0210 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*210: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0214 <[^>]*> addu \$a0,\$a1,\$gp
+0+0218 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*218: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+021c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*21c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0220 <[^>]*> addu \$a0,\$a0,\$a1
+0+0224 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*224: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0228 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+022c <[^>]*> addu \$a0,\$a0,\$a1
+0+0230 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*230: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0234 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*234: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0238 <[^>]*> addu \$a0,\$a0,\$a1
+0+023c <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0240 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*240: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0244 <[^>]*> addu \$a0,\$a0,\$a1
+0+0248 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*248: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+024c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*24c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0250 <[^>]*> addu \$a0,\$a0,\$a1
+0+0254 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*254: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0258 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+025c <[^>]*> addu \$a0,\$a0,\$a1
+0+0260 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*260: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0264 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*264: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0268 <[^>]*> addu \$a0,\$a0,\$a1
+0+026c <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0270 <[^>]*> lui \$a0,0x0
+[ ]*270: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0274 <[^>]*> addu \$a0,\$a0,\$a1
+0+0278 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*278: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+027c <[^>]*> lui \$a0,0x0
+[ ]*27c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> addu \$a0,\$a0,\$a1
+0+0284 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*284: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0288 <[^>]*> lui \$a0,0x0
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> addu \$a0,\$a0,\$a1
+0+0290 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*290: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0294 <[^>]*> lui \$a0,0x0
+[ ]*294: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0298 <[^>]*> addu \$a0,\$a0,\$a1
+0+029c <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> lui \$a0,0x0
+[ ]*2a0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02a4 <[^>]*> addu \$a0,\$a0,\$a1
+0+02a8 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*2a8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> lui \$a0,0x0
+[ ]*2ac: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02b0 <[^>]*> addu \$a0,\$a0,\$a1
+0+02b4 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*2b4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02b8 <[^>]*> lui \$a0,0x0
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02bc <[^>]*> addu \$a0,\$a0,\$a1
+0+02c0 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*2c0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02c4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2c4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+02c8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02cc <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02d0 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2d0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+02d4 <[^>]*> addu \$a0,\$a0,\$a1
+0+02d8 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*2d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02dc <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2dc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+02e0 <[^>]*> addu \$a0,\$a0,\$a1
+0+02e4 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*2e4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+02e8 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2e8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02ec <[^>]*> addu \$a0,\$a0,\$a1
+0+02f0 <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*2f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02f4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*2f4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02f8 <[^>]*> addu \$a0,\$a0,\$a1
+0+02fc <[^>]*> lb \$a0,0\(\$a0\)
+[ ]*2fc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0300 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*300: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0304 <[^>]*> addu \$a0,\$a0,\$a1
+0+0308 <[^>]*> lb \$a0,[0-9]+\(\$a0\)
+[ ]*308: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+030c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*30c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0310 <[^>]*> addu \$a0,\$a0,\$a1
+0+0314 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*314: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0318 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*318: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+031c <[^>]*> addu \$a0,\$a0,\$a1
+0+0320 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*320: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0324 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*324: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0328 <[^>]*> addu \$a0,\$a0,\$a1
+0+032c <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*32c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0330 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*330: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0334 <[^>]*> addu \$a0,\$a0,\$a1
+0+0338 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*338: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+033c <[^>]*> lui \$a0,[-0-9x]+
+[ ]*33c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0340 <[^>]*> addu \$a0,\$a0,\$a1
+0+0344 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*344: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0348 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*348: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+034c <[^>]*> addu \$a0,\$a0,\$a1
+0+0350 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*350: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0354 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*354: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0358 <[^>]*> addu \$a0,\$a0,\$a1
+0+035c <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*35c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0360 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*360: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0364 <[^>]*> addu \$a0,\$a0,\$a1
+0+0368 <[^>]*> lb \$a0,[-0-9]+\(\$a0\)
+[ ]*368: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+036c <[^>]*> lbu \$a0,0\(\$zero\)
+0+0370 <[^>]*> lh \$a0,0\(\$zero\)
+0+0374 <[^>]*> lhu \$a0,0\(\$zero\)
+0+0378 <[^>]*> lw \$a0,0\(\$zero\)
+0+037c <[^>]*> lwl \$a0,0\(\$zero\)
+0+0380 <[^>]*> lwr \$a0,0\(\$zero\)
+0+0384 <[^>]*> lwc0 \$4,0\(\$zero\)
+0+0388 <[^>]*> lwc1 \$f4,0\(\$zero\)
+0+038c <[^>]*> lwc2 \$4,0\(\$zero\)
+0+0390 <[^>]*> lwc3 \$4,0\(\$zero\)
+ ...
diff --git a/gas/testsuite/gas/mips/lb.s b/gas/testsuite/gas/mips/lb.s
new file mode 100644
index 00000000000..303ccaf6e71
--- /dev/null
+++ b/gas/testsuite/gas/mips/lb.s
@@ -0,0 +1,125 @@
+# Source file used to test the lb macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ lb $4,0
+ lb $4,1
+ lb $4,0x8000
+ lb $4,-0x8000
+ lb $4,0x10000
+ lb $4,0x1a5a5
+ lb $4,0($5)
+ lb $4,1($5)
+ lb $4,0x8000($5)
+ lb $4,-0x8000($5)
+ lb $4,0x10000($5)
+ lb $4,0x1a5a5($5)
+ lb $4,data_label
+ lb $4,big_external_data_label
+ lb $4,small_external_data_label
+ lb $4,big_external_common
+ lb $4,small_external_common
+ lb $4,big_local_common
+ lb $4,small_local_common
+ lb $4,data_label+1
+ lb $4,big_external_data_label+1
+ lb $4,small_external_data_label+1
+ lb $4,big_external_common+1
+ lb $4,small_external_common+1
+ lb $4,big_local_common+1
+ lb $4,small_local_common+1
+ lb $4,data_label+0x8000
+ lb $4,big_external_data_label+0x8000
+ lb $4,small_external_data_label+0x8000
+ lb $4,big_external_common+0x8000
+ lb $4,small_external_common+0x8000
+ lb $4,big_local_common+0x8000
+ lb $4,small_local_common+0x8000
+ lb $4,data_label-0x8000
+ lb $4,big_external_data_label-0x8000
+ lb $4,small_external_data_label-0x8000
+ lb $4,big_external_common-0x8000
+ lb $4,small_external_common-0x8000
+ lb $4,big_local_common-0x8000
+ lb $4,small_local_common-0x8000
+ lb $4,data_label+0x10000
+ lb $4,big_external_data_label+0x10000
+ lb $4,small_external_data_label+0x10000
+ lb $4,big_external_common+0x10000
+ lb $4,small_external_common+0x10000
+ lb $4,big_local_common+0x10000
+ lb $4,small_local_common+0x10000
+ lb $4,data_label+0x1a5a5
+ lb $4,big_external_data_label+0x1a5a5
+ lb $4,small_external_data_label+0x1a5a5
+ lb $4,big_external_common+0x1a5a5
+ lb $4,small_external_common+0x1a5a5
+ lb $4,big_local_common+0x1a5a5
+ lb $4,small_local_common+0x1a5a5
+ lb $4,data_label($5)
+ lb $4,big_external_data_label($5)
+ lb $4,small_external_data_label($5)
+ lb $4,big_external_common($5)
+ lb $4,small_external_common($5)
+ lb $4,big_local_common($5)
+ lb $4,small_local_common($5)
+ lb $4,data_label+1($5)
+ lb $4,big_external_data_label+1($5)
+ lb $4,small_external_data_label+1($5)
+ lb $4,big_external_common+1($5)
+ lb $4,small_external_common+1($5)
+ lb $4,big_local_common+1($5)
+ lb $4,small_local_common+1($5)
+ lb $4,data_label+0x8000($5)
+ lb $4,big_external_data_label+0x8000($5)
+ lb $4,small_external_data_label+0x8000($5)
+ lb $4,big_external_common+0x8000($5)
+ lb $4,small_external_common+0x8000($5)
+ lb $4,big_local_common+0x8000($5)
+ lb $4,small_local_common+0x8000($5)
+ lb $4,data_label-0x8000($5)
+ lb $4,big_external_data_label-0x8000($5)
+ lb $4,small_external_data_label-0x8000($5)
+ lb $4,big_external_common-0x8000($5)
+ lb $4,small_external_common-0x8000($5)
+ lb $4,big_local_common-0x8000($5)
+ lb $4,small_local_common-0x8000($5)
+ lb $4,data_label+0x10000($5)
+ lb $4,big_external_data_label+0x10000($5)
+ lb $4,small_external_data_label+0x10000($5)
+ lb $4,big_external_common+0x10000($5)
+ lb $4,small_external_common+0x10000($5)
+ lb $4,big_local_common+0x10000($5)
+ lb $4,small_local_common+0x10000($5)
+ lb $4,data_label+0x1a5a5($5)
+ lb $4,big_external_data_label+0x1a5a5($5)
+ lb $4,small_external_data_label+0x1a5a5($5)
+ lb $4,big_external_common+0x1a5a5($5)
+ lb $4,small_external_common+0x1a5a5($5)
+ lb $4,big_local_common+0x1a5a5($5)
+ lb $4,small_local_common+0x1a5a5($5)
+
+# Several macros are handled like lb. Sanity check them.
+ lbu $4,0
+ lh $4,0
+ lhu $4,0
+ lw $4,0
+ lwl $4,0
+ lwr $4,0
+ lwc0 $4,0
+ lwc1 $4,0
+ lwc2 $4,0
+ lwc3 $4,0
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/ld-empic.d b/gas/testsuite/gas/mips/ld-empic.d
new file mode 100644
index 00000000000..fa961f69f10
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld-empic.d
@@ -0,0 +1,186 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ld-empic
+#as: -mips1 -membedded-pic --defsym EMPIC=1
+#source: ld-pic.s
+
+# Test the ld macro with -membedded-pic.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$a0,0\(\$zero\)
+0+0004 <[^>]*> lw \$a1,4\(\$zero\)
+0+0008 <[^>]*> lw \$a0,1\(\$zero\)
+0+000c <[^>]*> lw \$a1,5\(\$zero\)
+0+0010 <[^>]*> lui \$at,0x1
+0+0014 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0018 <[^>]*> lw \$a1,-32764\(\$at\)
+0+001c <[^>]*> lw \$a0,-32768\(\$zero\)
+0+0020 <[^>]*> lw \$a1,-32764\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lw \$a0,0\(\$at\)
+0+002c <[^>]*> lw \$a1,4\(\$at\)
+0+0030 <[^>]*> lui \$at,0x2
+0+0034 <[^>]*> lw \$a0,-23131\(\$at\)
+0+0038 <[^>]*> lw \$a1,-23127\(\$at\)
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lw \$a0,0\(\$a1\)
+0+0044 <[^>]*> lw \$a1,4\(\$a1\)
+0+0048 <[^>]*> nop
+0+004c <[^>]*> lw \$a0,1\(\$a1\)
+0+0050 <[^>]*> lw \$a1,5\(\$a1\)
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> addu \$at,\$a1,\$at
+0+005c <[^>]*> lw \$a0,-32768\(\$at\)
+0+0060 <[^>]*> lw \$a1,-32764\(\$at\)
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> lw \$a0,-32768\(\$a1\)
+0+006c <[^>]*> lw \$a1,-32764\(\$a1\)
+0+0070 <[^>]*> lui \$at,0x1
+0+0074 <[^>]*> addu \$at,\$a1,\$at
+0+0078 <[^>]*> lw \$a0,0\(\$at\)
+0+007c <[^>]*> lw \$a1,4\(\$at\)
+0+0080 <[^>]*> lui \$at,0x2
+0+0084 <[^>]*> addu \$at,\$a1,\$at
+0+0088 <[^>]*> lw \$a0,-23131\(\$at\)
+0+008c <[^>]*> lw \$a1,-23127\(\$at\)
+0+0090 <[^>]*> lw \$a0,-16384\(\$gp\)
+[ ]*90: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0094 <[^>]*> lw \$a1,-16380\(\$gp\)
+[ ]*94: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0098 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*98: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+009c <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*9c: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+00a0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*a0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a4 <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*a4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00ac <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*ac: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00b0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*b0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b4 <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*b4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b8 <[^>]*> lw \$a0,-16384\(\$gp\)
+[ ]*b8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00bc <[^>]*> lw \$a1,-16380\(\$gp\)
+[ ]*bc: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00c0 <[^>]*> lw \$a0,-15384\(\$gp\)
+[ ]*c0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00c4 <[^>]*> lw \$a1,-15380\(\$gp\)
+[ ]*c4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00c8 <[^>]*> lw \$a0,-16383\(\$gp\)
+[ ]*c8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+00cc <[^>]*> lw \$a1,-16379\(\$gp\)
+[ ]*cc: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+00d0 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*d0: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+00d4 <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+00d8 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*d8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00dc <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*dc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00e0 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*e0: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00e4 <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*e4: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00e8 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*e8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00ec <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*ec: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00f0 <[^>]*> lw \$a0,-16383\(\$gp\)
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00f4 <[^>]*> lw \$a1,-16379\(\$gp\)
+[ ]*f4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00f8 <[^>]*> lw \$a0,-15383\(\$gp\)
+[ ]*f8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00fc <[^>]*> lw \$a1,-15379\(\$gp\)
+[ ]*fc: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0100 <[^>]*> nop
+0+0104 <[^>]*> addu \$at,\$a1,\$gp
+0+0108 <[^>]*> lw \$a0,-16384\(\$at\)
+[ ]*108: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+010c <[^>]*> lw \$a1,-16380\(\$at\)
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0110 <[^>]*> nop
+0+0114 <[^>]*> addu \$at,\$a1,\$gp
+0+0118 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*118: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+011c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*11c: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0120 <[^>]*> nop
+0+0124 <[^>]*> addu \$at,\$a1,\$gp
+0+0128 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*128: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+012c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*12c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0130 <[^>]*> nop
+0+0134 <[^>]*> addu \$at,\$a1,\$gp
+0+0138 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*138: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+013c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*13c: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+0140 <[^>]*> nop
+0+0144 <[^>]*> addu \$at,\$a1,\$gp
+0+0148 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*148: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+014c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*14c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0150 <[^>]*> nop
+0+0154 <[^>]*> addu \$at,\$a1,\$gp
+0+0158 <[^>]*> lw \$a0,-16384\(\$at\)
+[ ]*158: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+015c <[^>]*> lw \$a1,-16380\(\$at\)
+[ ]*15c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0160 <[^>]*> nop
+0+0164 <[^>]*> addu \$at,\$a1,\$gp
+0+0168 <[^>]*> lw \$a0,-15384\(\$at\)
+[ ]*168: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+016c <[^>]*> lw \$a1,-15380\(\$at\)
+[ ]*16c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0170 <[^>]*> nop
+0+0174 <[^>]*> addu \$at,\$a1,\$gp
+0+0178 <[^>]*> lw \$a0,-16383\(\$at\)
+[ ]*178: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+017c <[^>]*> lw \$a1,-16379\(\$at\)
+[ ]*17c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0180 <[^>]*> nop
+0+0184 <[^>]*> addu \$at,\$a1,\$gp
+0+0188 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*188: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+018c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*18c: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0190 <[^>]*> nop
+0+0194 <[^>]*> addu \$at,\$a1,\$gp
+0+0198 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*198: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+019c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*19c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01a0 <[^>]*> nop
+0+01a4 <[^>]*> addu \$at,\$a1,\$gp
+0+01a8 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*1a8: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+01ac <[^>]*> lw \$a1,5\(\$at\)
+[ ]*1ac: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+01b0 <[^>]*> nop
+0+01b4 <[^>]*> addu \$at,\$a1,\$gp
+0+01b8 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*1b8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+01bc <[^>]*> lw \$a1,5\(\$at\)
+[ ]*1bc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+01c0 <[^>]*> nop
+0+01c4 <[^>]*> addu \$at,\$a1,\$gp
+0+01c8 <[^>]*> lw \$a0,-16383\(\$at\)
+[ ]*1c8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01cc <[^>]*> lw \$a1,-16379\(\$at\)
+[ ]*1cc: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01d0 <[^>]*> nop
+0+01d4 <[^>]*> addu \$at,\$a1,\$gp
+0+01d8 <[^>]*> lw \$a0,-15383\(\$at\)
+[ ]*1d8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01dc <[^>]*> lw \$a1,-15379\(\$at\)
+[ ]*1dc: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
diff --git a/gas/testsuite/gas/mips/ld-ilocks-addr32.d b/gas/testsuite/gas/mips/ld-ilocks-addr32.d
new file mode 100644
index 00000000000..0846d614de4
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld-ilocks-addr32.d
@@ -0,0 +1,632 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#as: -mips3 -mcpu=r4000
+#name: MIPS ld-ilocks
+#source: ld.s
+
+# Test the ld macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <.text> lw \$a0,0\(\$zero\)
+0+0004 <[^>]*> lw \$a1,4\(\$zero\)
+0+0008 <[^>]*> lw \$a0,1\(\$zero\)
+0+000c <[^>]*> lw \$a1,5\(\$zero\)
+0+0010 <[^>]*> lui \$at,0x1
+0+0014 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0018 <[^>]*> lw \$a1,-32764\(\$at\)
+0+001c <[^>]*> lw \$a0,-32768\(\$zero\)
+0+0020 <[^>]*> lw \$a1,-32764\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lw \$a0,0\(\$at\)
+0+002c <[^>]*> lw \$a1,4\(\$at\)
+0+0030 <[^>]*> lui \$at,0x2
+0+0034 <[^>]*> lw \$a0,-23131\(\$at\)
+0+0038 <[^>]*> lw \$a1,-23127\(\$at\)
+0+003c <[^>]*> lw \$a0,0\(\$a1\)
+0+0040 <[^>]*> lw \$a1,4\(\$a1\)
+0+0044 <[^>]*> lw \$a0,1\(\$a1\)
+0+0048 <[^>]*> lw \$a1,5\(\$a1\)
+0+004c <[^>]*> lui \$at,0x1
+0+0050 <[^>]*> addu \$at,\$a1,\$at
+0+0054 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0058 <[^>]*> lw \$a1,-32764\(\$at\)
+0+005c <[^>]*> lw \$a0,-32768\(\$a1\)
+0+0060 <[^>]*> lw \$a1,-32764\(\$a1\)
+0+0064 <[^>]*> lui \$at,0x1
+0+0068 <[^>]*> addu \$at,\$a1,\$at
+0+006c <[^>]*> lw \$a0,0\(\$at\)
+0+0070 <[^>]*> lw \$a1,4\(\$at\)
+0+0074 <[^>]*> lui \$at,0x2
+0+0078 <[^>]*> addu \$at,\$a1,\$at
+0+007c <[^>]*> lw \$a0,-23131\(\$at\)
+0+0080 <[^>]*> lw \$a1,-23127\(\$at\)
+0+0084 <[^>]*> lui \$at,0x0
+[ ]*84: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0088 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*88: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+008c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*8c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0090 <[^>]*> lui \$at,0x0
+[ ]*90: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0094 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*94: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0098 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*98: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+009c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*9c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a0 <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*a0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a4 <[^>]*> lui \$at,0x0
+[ ]*a4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00a8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*a8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00ac <[^>]*> lw \$a1,4\(\$at\)
+[ ]*ac: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00b0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*b0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b4 <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*b4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b8 <[^>]*> lui \$at,0x0
+[ ]*b8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00bc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*bc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00c0 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*c0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00c4 <[^>]*> lw \$a0,-16384\(\$gp\)
+[ ]*c4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00c8 <[^>]*> lw \$a1,-16380\(\$gp\)
+[ ]*c8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00cc <[^>]*> lui \$at,0x0
+[ ]*cc: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00d0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*d0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00d4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*d4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00d8 <[^>]*> lui \$at,0x0
+[ ]*d8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00dc <[^>]*> lw \$a0,1\(\$at\)
+[ ]*dc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00e0 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*e0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00e4 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*e4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00e8 <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*e8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00ec <[^>]*> lui \$at,0x0
+[ ]*ec: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00f0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00f4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*f4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00f8 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*f8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00fc <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*fc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0100 <[^>]*> lui \$at,0x0
+[ ]*100: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*104: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0108 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*108: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+010c <[^>]*> lw \$a0,-16383\(\$gp\)
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0110 <[^>]*> lw \$a1,-16379\(\$gp\)
+[ ]*110: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0114 <[^>]*> lui \$at,0x1
+[ ]*114: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0118 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*118: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+011c <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> lui \$at,0x1
+[ ]*120: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0124 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*124: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0128 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*128: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> lui \$at,0x1
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0130 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0134 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*134: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0138 <[^>]*> lui \$at,0x1
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+013c <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0140 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*140: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0144 <[^>]*> lui \$at,0x1
+[ ]*144: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0148 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*148: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+014c <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0150 <[^>]*> lui \$at,0x1
+[ ]*150: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0154 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*154: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0158 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*158: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+015c <[^>]*> lui \$at,0x1
+[ ]*15c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0160 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*160: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0164 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*164: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0168 <[^>]*> lui \$at,0x0
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+016c <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0170 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*170: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0174 <[^>]*> lui \$at,0x0
+[ ]*174: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0178 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*178: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+017c <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0180 <[^>]*> lui \$at,0x0
+[ ]*180: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0184 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*184: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0188 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*188: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+018c <[^>]*> lui \$at,0x0
+[ ]*18c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0190 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*190: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0194 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*194: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+019c <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01a0 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*1a0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01a4 <[^>]*> lui \$at,0x0
+[ ]*1a4: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01a8 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*1a8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01ac <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01b0 <[^>]*> lui \$at,0x0
+[ ]*1b0: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01b4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*1b4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01b8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*1b8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01bc <[^>]*> lui \$at,0x1
+[ ]*1bc: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01c0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1c0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01c4 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1c4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01c8 <[^>]*> lui \$at,0x1
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01cc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01d0 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1d0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01d4 <[^>]*> lui \$at,0x1
+[ ]*1d4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01d8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1d8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01dc <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01e0 <[^>]*> lui \$at,0x1
+[ ]*1e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01e4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01e8 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1e8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01ec <[^>]*> lui \$at,0x1
+[ ]*1ec: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01f0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1f0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01f4 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1f4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01f8 <[^>]*> lui \$at,0x1
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01fc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0200 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*200: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0204 <[^>]*> lui \$at,0x1
+[ ]*204: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0208 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*208: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+020c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0210 <[^>]*> lui \$at,0x2
+[ ]*210: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0214 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*214: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0218 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*218: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+021c <[^>]*> lui \$at,0x2
+[ ]*21c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0220 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*220: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0224 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*224: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0228 <[^>]*> lui \$at,0x2
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+022c <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0230 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*230: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0234 <[^>]*> lui \$at,0x2
+[ ]*234: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0238 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*238: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+023c <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0240 <[^>]*> lui \$at,0x2
+[ ]*240: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0244 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*244: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0248 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*248: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+024c <[^>]*> lui \$at,0x2
+[ ]*24c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0250 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*250: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0254 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*254: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0258 <[^>]*> lui \$at,0x2
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*260: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0264 <[^>]*> lui \$at,0x0
+[ ]*264: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0268 <[^>]*> addu \$at,\$a1,\$at
+0+026c <[^>]*> lw \$a0,0\(\$at\)
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0270 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*270: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0274 <[^>]*> lui \$at,0x0
+[ ]*274: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0278 <[^>]*> addu \$at,\$a1,\$at
+0+027c <[^>]*> lw \$a0,0\(\$at\)
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*280: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0284 <[^>]*> addu \$at,\$a1,\$gp
+0+0288 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*288: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*28c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0290 <[^>]*> lui \$at,0x0
+[ ]*290: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0294 <[^>]*> addu \$at,\$a1,\$at
+0+0298 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*298: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+029c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> addu \$at,\$a1,\$gp
+0+02a4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*2a4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+02a8 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*2a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> lui \$at,0x0
+[ ]*2ac: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02b0 <[^>]*> addu \$at,\$a1,\$at
+0+02b4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*2b4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02b8 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*2b8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02bc <[^>]*> addu \$at,\$a1,\$gp
+0+02c0 <[^>]*> lw \$a0,-16384\(\$at\)
+[ ]*2c0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+02c4 <[^>]*> lw \$a1,-16380\(\$at\)
+[ ]*2c4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+02c8 <[^>]*> lui \$at,0x0
+[ ]*2c8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+02cc <[^>]*> addu \$at,\$a1,\$at
+0+02d0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2d0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02d4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2d4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02d8 <[^>]*> lui \$at,0x0
+[ ]*2d8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+02dc <[^>]*> addu \$at,\$a1,\$at
+0+02e0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2e0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02e4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02e8 <[^>]*> addu \$at,\$a1,\$gp
+0+02ec <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2ec: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+02f0 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+02f4 <[^>]*> lui \$at,0x0
+[ ]*2f4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02f8 <[^>]*> addu \$at,\$a1,\$at
+0+02fc <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0300 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*300: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0304 <[^>]*> addu \$at,\$a1,\$gp
+0+0308 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*308: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+030c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*30c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0310 <[^>]*> lui \$at,0x0
+[ ]*310: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0314 <[^>]*> addu \$at,\$a1,\$at
+0+0318 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*318: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+031c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*31c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0320 <[^>]*> addu \$at,\$a1,\$gp
+0+0324 <[^>]*> lw \$a0,-16383\(\$at\)
+[ ]*324: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0328 <[^>]*> lw \$a1,-16379\(\$at\)
+[ ]*328: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+032c <[^>]*> lui \$at,0x1
+[ ]*32c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0330 <[^>]*> addu \$at,\$a1,\$at
+0+0334 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*334: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0338 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*338: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+033c <[^>]*> lui \$at,0x1
+[ ]*33c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0340 <[^>]*> addu \$at,\$a1,\$at
+0+0344 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*344: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0348 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*348: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+034c <[^>]*> lui \$at,0x1
+[ ]*34c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0350 <[^>]*> addu \$at,\$a1,\$at
+0+0354 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*354: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0358 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*358: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+035c <[^>]*> lui \$at,0x1
+[ ]*35c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0360 <[^>]*> addu \$at,\$a1,\$at
+0+0364 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*364: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0368 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*368: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+036c <[^>]*> lui \$at,0x1
+[ ]*36c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0370 <[^>]*> addu \$at,\$a1,\$at
+0+0374 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*374: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0378 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*378: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+037c <[^>]*> lui \$at,0x1
+[ ]*37c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0380 <[^>]*> addu \$at,\$a1,\$at
+0+0384 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*384: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0388 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*388: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+038c <[^>]*> lui \$at,0x1
+[ ]*38c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0390 <[^>]*> addu \$at,\$a1,\$at
+0+0394 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*394: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0398 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*398: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+039c <[^>]*> lui \$at,0x0
+[ ]*39c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+03a0 <[^>]*> addu \$at,\$a1,\$at
+0+03a4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3a4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03a8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3a8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03ac <[^>]*> lui \$at,0x0
+[ ]*3ac: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+03b0 <[^>]*> addu \$at,\$a1,\$at
+0+03b4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03b8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03bc <[^>]*> lui \$at,0x0
+[ ]*3bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+03c0 <[^>]*> addu \$at,\$a1,\$at
+0+03c4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3c4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03c8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3c8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03cc <[^>]*> lui \$at,0x0
+[ ]*3cc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+03d0 <[^>]*> addu \$at,\$a1,\$at
+0+03d4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3d4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+03d8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+03dc <[^>]*> lui \$at,0x0
+[ ]*3dc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+03e0 <[^>]*> addu \$at,\$a1,\$at
+0+03e4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3e4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+03e8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3e8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+03ec <[^>]*> lui \$at,0x0
+[ ]*3ec: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+03f0 <[^>]*> addu \$at,\$a1,\$at
+0+03f4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3f4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03f8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3f8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03fc <[^>]*> lui \$at,0x0
+[ ]*3fc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0400 <[^>]*> addu \$at,\$a1,\$at
+0+0404 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*404: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0408 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*408: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+040c <[^>]*> lui \$at,0x1
+[ ]*40c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0410 <[^>]*> addu \$at,\$a1,\$at
+0+0414 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*414: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0418 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*418: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+041c <[^>]*> lui \$at,0x1
+[ ]*41c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0420 <[^>]*> addu \$at,\$a1,\$at
+0+0424 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*424: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0428 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*428: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+042c <[^>]*> lui \$at,0x1
+[ ]*42c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0430 <[^>]*> addu \$at,\$a1,\$at
+0+0434 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*434: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0438 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*438: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+043c <[^>]*> lui \$at,0x1
+[ ]*43c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0440 <[^>]*> addu \$at,\$a1,\$at
+0+0444 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*444: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0448 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*448: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+044c <[^>]*> lui \$at,0x1
+[ ]*44c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0450 <[^>]*> addu \$at,\$a1,\$at
+0+0454 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*454: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0458 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*458: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+045c <[^>]*> lui \$at,0x1
+[ ]*45c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0460 <[^>]*> addu \$at,\$a1,\$at
+0+0464 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*464: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0468 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*468: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+046c <[^>]*> lui \$at,0x1
+[ ]*46c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0470 <[^>]*> addu \$at,\$a1,\$at
+0+0474 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*474: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0478 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*478: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+047c <[^>]*> lui \$at,0x2
+[ ]*47c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0480 <[^>]*> addu \$at,\$a1,\$at
+0+0484 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*484: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0488 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*488: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+048c <[^>]*> lui \$at,0x2
+[ ]*48c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0490 <[^>]*> addu \$at,\$a1,\$at
+0+0494 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*494: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0498 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*498: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+049c <[^>]*> lui \$at,0x2
+[ ]*49c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+04a0 <[^>]*> addu \$at,\$a1,\$at
+0+04a4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4a4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+04a8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4a8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+04ac <[^>]*> lui \$at,0x2
+[ ]*4ac: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+04b0 <[^>]*> addu \$at,\$a1,\$at
+0+04b4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+04b8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+04bc <[^>]*> lui \$at,0x2
+[ ]*4bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+04c0 <[^>]*> addu \$at,\$a1,\$at
+0+04c4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4c4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+04c8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4c8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+04cc <[^>]*> lui \$at,0x2
+[ ]*4cc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+04d0 <[^>]*> addu \$at,\$a1,\$at
+0+04d4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4d4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+04d8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4d8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+04dc <[^>]*> lui \$at,0x2
+[ ]*4dc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+04e0 <[^>]*> addu \$at,\$a1,\$at
+0+04e4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4e4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+04e8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4e8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+04ec <[^>]*> lwc1 \$f5,0\(\$zero\)
+0+04f0 <[^>]*> lwc1 \$f4,4\(\$zero\)
+0+04f4 <[^>]*> lwc1 \$f5,1\(\$zero\)
+0+04f8 <[^>]*> lwc1 \$f4,5\(\$zero\)
+0+04fc <[^>]*> lui \$at,0x1
+0+0500 <[^>]*> lwc1 \$f5,-32768\(\$at\)
+0+0504 <[^>]*> lwc1 \$f4,-32764\(\$at\)
+0+0508 <[^>]*> lwc1 \$f5,-32768\(\$zero\)
+0+050c <[^>]*> lwc1 \$f4,-32764\(\$zero\)
+0+0510 <[^>]*> lwc1 \$f5,0\(\$a1\)
+0+0514 <[^>]*> lwc1 \$f4,4\(\$a1\)
+0+0518 <[^>]*> lwc1 \$f5,1\(\$a1\)
+0+051c <[^>]*> lwc1 \$f4,5\(\$a1\)
+0+0520 <[^>]*> lui \$at,0x1
+0+0524 <[^>]*> addu \$at,\$a1,\$at
+0+0528 <[^>]*> lwc1 \$f5,-32768\(\$at\)
+0+052c <[^>]*> lwc1 \$f4,-32764\(\$at\)
+0+0530 <[^>]*> lwc1 \$f5,-32768\(\$a1\)
+0+0534 <[^>]*> lwc1 \$f4,-32764\(\$a1\)
+0+0538 <[^>]*> lui \$at,0x2
+[ ]*538: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+053c <[^>]*> addu \$at,\$a1,\$at
+0+0540 <[^>]*> lwc1 \$f5,-23131\(\$at\)
+[ ]*540: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0544 <[^>]*> lwc1 \$f4,-23127\(\$at\)
+[ ]*544: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0548 <[^>]*> nop
+0+054c <[^>]*> swc1 \$f5,0\(\$zero\)
+0+0550 <[^>]*> swc1 \$f4,4\(\$zero\)
+0+0554 <[^>]*> swc1 \$f5,1\(\$zero\)
+0+0558 <[^>]*> swc1 \$f4,5\(\$zero\)
+0+055c <[^>]*> lui \$at,0x1
+0+0560 <[^>]*> swc1 \$f5,-32768\(\$at\)
+0+0564 <[^>]*> swc1 \$f4,-32764\(\$at\)
+0+0568 <[^>]*> swc1 \$f5,-32768\(\$zero\)
+0+056c <[^>]*> swc1 \$f4,-32764\(\$zero\)
+0+0570 <[^>]*> swc1 \$f5,0\(\$a1\)
+0+0574 <[^>]*> swc1 \$f4,4\(\$a1\)
+0+0578 <[^>]*> swc1 \$f5,1\(\$a1\)
+0+057c <[^>]*> swc1 \$f4,5\(\$a1\)
+0+0580 <[^>]*> lui \$at,0x1
+0+0584 <[^>]*> addu \$at,\$a1,\$at
+0+0588 <[^>]*> swc1 \$f5,-32768\(\$at\)
+0+058c <[^>]*> swc1 \$f4,-32764\(\$at\)
+0+0590 <[^>]*> swc1 \$f5,-32768\(\$a1\)
+0+0594 <[^>]*> swc1 \$f4,-32764\(\$a1\)
+0+0598 <[^>]*> lui \$at,0x2
+[ ]*598: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+059c <[^>]*> addu \$at,\$a1,\$at
+0+05a0 <[^>]*> swc1 \$f5,-23131\(\$at\)
+[ ]*5a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+05a4 <[^>]*> swc1 \$f4,-23127\(\$at\)
+[ ]*5a4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+05a8 <[^>]*> sw \$a0,0\(\$zero\)
+0+05ac <[^>]*> sw \$a1,4\(\$zero\)
+0+05b0 <[^>]*> lui \$a0,0x2
+[ ]*5b0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+05b4 <[^>]*> addu \$a0,\$a0,\$a1
+0+05b8 <[^>]*> ld \$a0,-23131\(\$a0\)
+[ ]*5b8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+05bc <[^>]*> lui \$at,0x2
+[ ]*5bc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+05c0 <[^>]*> addu \$at,\$at,\$a1
+0+05c4 <[^>]*> sd \$a0,-23131\(\$at\)
+[ ]*5c4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+05c8 <[^>]*> nop
+
diff --git a/gas/testsuite/gas/mips/ld-ilocks.d b/gas/testsuite/gas/mips/ld-ilocks.d
new file mode 100644
index 00000000000..eab2bdc7953
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld-ilocks.d
@@ -0,0 +1,631 @@
+#objdump: -dr --prefix-addresses
+#name: MIPS ld-ilocks
+#source: ld.s
+#as:
+# Test the ld macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <.text> lw \$a0,0\(\$zero\)
+0+0004 <[^>]*> lw \$a1,4\(\$zero\)
+0+0008 <[^>]*> lw \$a0,1\(\$zero\)
+0+000c <[^>]*> lw \$a1,5\(\$zero\)
+0+0010 <[^>]*> lui \$at,0x1
+0+0014 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0018 <[^>]*> lw \$a1,-32764\(\$at\)
+0+001c <[^>]*> lw \$a0,-32768\(\$zero\)
+0+0020 <[^>]*> lw \$a1,-32764\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lw \$a0,0\(\$at\)
+0+002c <[^>]*> lw \$a1,4\(\$at\)
+0+0030 <[^>]*> lui \$at,0x2
+0+0034 <[^>]*> lw \$a0,-23131\(\$at\)
+0+0038 <[^>]*> lw \$a1,-23127\(\$at\)
+0+003c <[^>]*> lw \$a0,0\(\$a1\)
+0+0040 <[^>]*> lw \$a1,4\(\$a1\)
+0+0044 <[^>]*> lw \$a0,1\(\$a1\)
+0+0048 <[^>]*> lw \$a1,5\(\$a1\)
+0+004c <[^>]*> lui \$at,0x1
+0+0050 <[^>]*> addu \$at,\$a1,\$at
+0+0054 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0058 <[^>]*> lw \$a1,-32764\(\$at\)
+0+005c <[^>]*> lw \$a0,-32768\(\$a1\)
+0+0060 <[^>]*> lw \$a1,-32764\(\$a1\)
+0+0064 <[^>]*> lui \$at,0x1
+0+0068 <[^>]*> addu \$at,\$a1,\$at
+0+006c <[^>]*> lw \$a0,0\(\$at\)
+0+0070 <[^>]*> lw \$a1,4\(\$at\)
+0+0074 <[^>]*> lui \$at,0x2
+0+0078 <[^>]*> addu \$at,\$a1,\$at
+0+007c <[^>]*> lw \$a0,-23131\(\$at\)
+0+0080 <[^>]*> lw \$a1,-23127\(\$at\)
+0+0084 <[^>]*> lui \$at,0x0
+[ ]*84: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0088 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*88: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+008c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*8c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0090 <[^>]*> lui \$at,0x0
+[ ]*90: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0094 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*94: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0098 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*98: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+009c <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*9c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a0 <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*a0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00a4 <[^>]*> lui \$at,0x0
+[ ]*a4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00a8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*a8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00ac <[^>]*> lw \$a1,4\(\$at\)
+[ ]*ac: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00b0 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*b0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b4 <[^>]*> lw \$a1,4\(\$gp\)
+[ ]*b4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00b8 <[^>]*> lui \$at,0x0
+[ ]*b8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00bc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*bc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00c0 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*c0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00c4 <[^>]*> lw \$a0,-16384\(\$gp\)
+[ ]*c4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00c8 <[^>]*> lw \$a1,-16380\(\$gp\)
+[ ]*c8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00cc <[^>]*> lui \$at,0x0
+[ ]*cc: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00d0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*d0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00d4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*d4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00d8 <[^>]*> lui \$at,0x0
+[ ]*d8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00dc <[^>]*> lw \$a0,1\(\$at\)
+[ ]*dc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00e0 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*e0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00e4 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*e4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00e8 <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*e8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00ec <[^>]*> lui \$at,0x0
+[ ]*ec: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00f0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00f4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*f4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00f8 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*f8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00fc <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*fc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0100 <[^>]*> lui \$at,0x0
+[ ]*100: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*104: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0108 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*108: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+010c <[^>]*> lw \$a0,-16383\(\$gp\)
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0110 <[^>]*> lw \$a1,-16379\(\$gp\)
+[ ]*110: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0114 <[^>]*> lui \$at,0x1
+[ ]*114: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0118 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*118: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+011c <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> lui \$at,0x1
+[ ]*120: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0124 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*124: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0128 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*128: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> lui \$at,0x1
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0130 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0134 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*134: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0138 <[^>]*> lui \$at,0x1
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+013c <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0140 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*140: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0144 <[^>]*> lui \$at,0x1
+[ ]*144: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0148 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*148: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+014c <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0150 <[^>]*> lui \$at,0x1
+[ ]*150: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0154 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*154: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0158 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*158: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+015c <[^>]*> lui \$at,0x1
+[ ]*15c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0160 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*160: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0164 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*164: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0168 <[^>]*> lui \$at,0x0
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+016c <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0170 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*170: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0174 <[^>]*> lui \$at,0x0
+[ ]*174: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0178 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*178: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+017c <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0180 <[^>]*> lui \$at,0x0
+[ ]*180: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0184 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*184: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0188 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*188: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+018c <[^>]*> lui \$at,0x0
+[ ]*18c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0190 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*190: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0194 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*194: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+019c <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01a0 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*1a0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01a4 <[^>]*> lui \$at,0x0
+[ ]*1a4: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01a8 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*1a8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01ac <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01b0 <[^>]*> lui \$at,0x0
+[ ]*1b0: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01b4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*1b4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01b8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*1b8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01bc <[^>]*> lui \$at,0x1
+[ ]*1bc: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01c0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1c0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01c4 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1c4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01c8 <[^>]*> lui \$at,0x1
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01cc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01d0 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1d0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01d4 <[^>]*> lui \$at,0x1
+[ ]*1d4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01d8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1d8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01dc <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01e0 <[^>]*> lui \$at,0x1
+[ ]*1e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01e4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01e8 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1e8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01ec <[^>]*> lui \$at,0x1
+[ ]*1ec: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01f0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1f0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01f4 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1f4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01f8 <[^>]*> lui \$at,0x1
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01fc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0200 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*200: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0204 <[^>]*> lui \$at,0x1
+[ ]*204: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0208 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*208: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+020c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0210 <[^>]*> lui \$at,0x2
+[ ]*210: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0214 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*214: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0218 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*218: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+021c <[^>]*> lui \$at,0x2
+[ ]*21c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0220 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*220: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0224 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*224: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0228 <[^>]*> lui \$at,0x2
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+022c <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0230 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*230: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0234 <[^>]*> lui \$at,0x2
+[ ]*234: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0238 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*238: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+023c <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0240 <[^>]*> lui \$at,0x2
+[ ]*240: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0244 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*244: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0248 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*248: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+024c <[^>]*> lui \$at,0x2
+[ ]*24c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0250 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*250: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0254 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*254: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0258 <[^>]*> lui \$at,0x2
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*260: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0264 <[^>]*> lui \$at,0x0
+[ ]*264: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0268 <[^>]*> addu \$at,\$a1,\$at
+0+026c <[^>]*> lw \$a0,0\(\$at\)
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0270 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*270: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0274 <[^>]*> lui \$at,0x0
+[ ]*274: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0278 <[^>]*> addu \$at,\$a1,\$at
+0+027c <[^>]*> lw \$a0,0\(\$at\)
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*280: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0284 <[^>]*> addu \$at,\$a1,\$gp
+0+0288 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*288: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*28c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0290 <[^>]*> lui \$at,0x0
+[ ]*290: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0294 <[^>]*> addu \$at,\$a1,\$at
+0+0298 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*298: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+029c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> addu \$at,\$a1,\$gp
+0+02a4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*2a4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+02a8 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*2a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> lui \$at,0x0
+[ ]*2ac: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02b0 <[^>]*> addu \$at,\$a1,\$at
+0+02b4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*2b4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02b8 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*2b8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02bc <[^>]*> addu \$at,\$a1,\$gp
+0+02c0 <[^>]*> lw \$a0,-16384\(\$at\)
+[ ]*2c0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+02c4 <[^>]*> lw \$a1,-16380\(\$at\)
+[ ]*2c4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+02c8 <[^>]*> lui \$at,0x0
+[ ]*2c8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+02cc <[^>]*> addu \$at,\$a1,\$at
+0+02d0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2d0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02d4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2d4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02d8 <[^>]*> lui \$at,0x0
+[ ]*2d8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+02dc <[^>]*> addu \$at,\$a1,\$at
+0+02e0 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2e0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02e4 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02e8 <[^>]*> addu \$at,\$a1,\$gp
+0+02ec <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2ec: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+02f0 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+02f4 <[^>]*> lui \$at,0x0
+[ ]*2f4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02f8 <[^>]*> addu \$at,\$a1,\$at
+0+02fc <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0300 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*300: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0304 <[^>]*> addu \$at,\$a1,\$gp
+0+0308 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*308: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+030c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*30c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0310 <[^>]*> lui \$at,0x0
+[ ]*310: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0314 <[^>]*> addu \$at,\$a1,\$at
+0+0318 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*318: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+031c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*31c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0320 <[^>]*> addu \$at,\$a1,\$gp
+0+0324 <[^>]*> lw \$a0,-16383\(\$at\)
+[ ]*324: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0328 <[^>]*> lw \$a1,-16379\(\$at\)
+[ ]*328: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+032c <[^>]*> lui \$at,0x1
+[ ]*32c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0330 <[^>]*> addu \$at,\$a1,\$at
+0+0334 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*334: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0338 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*338: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+033c <[^>]*> lui \$at,0x1
+[ ]*33c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0340 <[^>]*> addu \$at,\$a1,\$at
+0+0344 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*344: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0348 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*348: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+034c <[^>]*> lui \$at,0x1
+[ ]*34c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0350 <[^>]*> addu \$at,\$a1,\$at
+0+0354 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*354: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0358 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*358: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+035c <[^>]*> lui \$at,0x1
+[ ]*35c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0360 <[^>]*> addu \$at,\$a1,\$at
+0+0364 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*364: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0368 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*368: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+036c <[^>]*> lui \$at,0x1
+[ ]*36c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0370 <[^>]*> addu \$at,\$a1,\$at
+0+0374 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*374: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0378 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*378: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+037c <[^>]*> lui \$at,0x1
+[ ]*37c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0380 <[^>]*> addu \$at,\$a1,\$at
+0+0384 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*384: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0388 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*388: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+038c <[^>]*> lui \$at,0x1
+[ ]*38c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0390 <[^>]*> addu \$at,\$a1,\$at
+0+0394 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*394: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0398 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*398: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+039c <[^>]*> lui \$at,0x0
+[ ]*39c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+03a0 <[^>]*> addu \$at,\$a1,\$at
+0+03a4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3a4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03a8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3a8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03ac <[^>]*> lui \$at,0x0
+[ ]*3ac: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+03b0 <[^>]*> addu \$at,\$a1,\$at
+0+03b4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03b8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03bc <[^>]*> lui \$at,0x0
+[ ]*3bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+03c0 <[^>]*> addu \$at,\$a1,\$at
+0+03c4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3c4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03c8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3c8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03cc <[^>]*> lui \$at,0x0
+[ ]*3cc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+03d0 <[^>]*> addu \$at,\$a1,\$at
+0+03d4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3d4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+03d8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+03dc <[^>]*> lui \$at,0x0
+[ ]*3dc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+03e0 <[^>]*> addu \$at,\$a1,\$at
+0+03e4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3e4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+03e8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3e8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+03ec <[^>]*> lui \$at,0x0
+[ ]*3ec: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+03f0 <[^>]*> addu \$at,\$a1,\$at
+0+03f4 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*3f4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03f8 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*3f8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03fc <[^>]*> lui \$at,0x0
+[ ]*3fc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0400 <[^>]*> addu \$at,\$a1,\$at
+0+0404 <[^>]*> lw \$a0,-32768\(\$at\)
+[ ]*404: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0408 <[^>]*> lw \$a1,-32764\(\$at\)
+[ ]*408: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+040c <[^>]*> lui \$at,0x1
+[ ]*40c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0410 <[^>]*> addu \$at,\$a1,\$at
+0+0414 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*414: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0418 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*418: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+041c <[^>]*> lui \$at,0x1
+[ ]*41c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0420 <[^>]*> addu \$at,\$a1,\$at
+0+0424 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*424: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0428 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*428: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+042c <[^>]*> lui \$at,0x1
+[ ]*42c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0430 <[^>]*> addu \$at,\$a1,\$at
+0+0434 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*434: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0438 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*438: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+043c <[^>]*> lui \$at,0x1
+[ ]*43c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0440 <[^>]*> addu \$at,\$a1,\$at
+0+0444 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*444: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0448 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*448: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+044c <[^>]*> lui \$at,0x1
+[ ]*44c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0450 <[^>]*> addu \$at,\$a1,\$at
+0+0454 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*454: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0458 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*458: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+045c <[^>]*> lui \$at,0x1
+[ ]*45c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0460 <[^>]*> addu \$at,\$a1,\$at
+0+0464 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*464: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0468 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*468: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+046c <[^>]*> lui \$at,0x1
+[ ]*46c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0470 <[^>]*> addu \$at,\$a1,\$at
+0+0474 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*474: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0478 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*478: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+047c <[^>]*> lui \$at,0x2
+[ ]*47c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0480 <[^>]*> addu \$at,\$a1,\$at
+0+0484 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*484: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0488 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*488: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+048c <[^>]*> lui \$at,0x2
+[ ]*48c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0490 <[^>]*> addu \$at,\$a1,\$at
+0+0494 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*494: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0498 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*498: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+049c <[^>]*> lui \$at,0x2
+[ ]*49c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+04a0 <[^>]*> addu \$at,\$a1,\$at
+0+04a4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4a4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+04a8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4a8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+04ac <[^>]*> lui \$at,0x2
+[ ]*4ac: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+04b0 <[^>]*> addu \$at,\$a1,\$at
+0+04b4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+04b8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+04bc <[^>]*> lui \$at,0x2
+[ ]*4bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+04c0 <[^>]*> addu \$at,\$a1,\$at
+0+04c4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4c4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+04c8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4c8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+04cc <[^>]*> lui \$at,0x2
+[ ]*4cc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+04d0 <[^>]*> addu \$at,\$a1,\$at
+0+04d4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4d4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+04d8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4d8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+04dc <[^>]*> lui \$at,0x2
+[ ]*4dc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+04e0 <[^>]*> addu \$at,\$a1,\$at
+0+04e4 <[^>]*> lw \$a0,-23131\(\$at\)
+[ ]*4e4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+04e8 <[^>]*> lw \$a1,-23127\(\$at\)
+[ ]*4e8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+04ec <[^>]*> lwc1 \$f[45],0\(\$zero\)
+0+04f0 <[^>]*> lwc1 \$f[45],4\(\$zero\)
+0+04f4 <[^>]*> lwc1 \$f[45],1\(\$zero\)
+0+04f8 <[^>]*> lwc1 \$f[45],5\(\$zero\)
+0+04fc <[^>]*> lui \$at,0x1
+0+0500 <[^>]*> lwc1 \$f[45],-32768\(\$at\)
+0+0504 <[^>]*> lwc1 \$f[45],-32764\(\$at\)
+0+0508 <[^>]*> lwc1 \$f[45],-32768\(\$zero\)
+0+050c <[^>]*> lwc1 \$f[45],-32764\(\$zero\)
+0+0510 <[^>]*> lwc1 \$f[45],0\(\$a1\)
+0+0514 <[^>]*> lwc1 \$f[45],4\(\$a1\)
+0+0518 <[^>]*> lwc1 \$f[45],1\(\$a1\)
+0+051c <[^>]*> lwc1 \$f[45],5\(\$a1\)
+0+0520 <[^>]*> lui \$at,0x1
+0+0524 <[^>]*> addu \$at,\$a1,\$at
+0+0528 <[^>]*> lwc1 \$f[45],-32768\(\$at\)
+0+052c <[^>]*> lwc1 \$f[45],-32764\(\$at\)
+0+0530 <[^>]*> lwc1 \$f[45],-32768\(\$a1\)
+0+0534 <[^>]*> lwc1 \$f[45],-32764\(\$a1\)
+0+0538 <[^>]*> lui \$at,0x2
+[ ]*538: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+053c <[^>]*> addu \$at,\$a1,\$at
+0+0540 <[^>]*> lwc1 \$f[45],-23131\(\$at\)
+[ ]*540: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0544 <[^>]*> lwc1 \$f[45],-23127\(\$at\)
+[ ]*544: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0548 <[^>]*> nop
+0+054c <[^>]*> swc1 \$f[45],0\(\$zero\)
+0+0550 <[^>]*> swc1 \$f[45],4\(\$zero\)
+0+0554 <[^>]*> swc1 \$f[45],1\(\$zero\)
+0+0558 <[^>]*> swc1 \$f[45],5\(\$zero\)
+0+055c <[^>]*> lui \$at,0x1
+0+0560 <[^>]*> swc1 \$f[45],-32768\(\$at\)
+0+0564 <[^>]*> swc1 \$f[45],-32764\(\$at\)
+0+0568 <[^>]*> swc1 \$f[45],-32768\(\$zero\)
+0+056c <[^>]*> swc1 \$f[45],-32764\(\$zero\)
+0+0570 <[^>]*> swc1 \$f[45],0\(\$a1\)
+0+0574 <[^>]*> swc1 \$f[45],4\(\$a1\)
+0+0578 <[^>]*> swc1 \$f[45],1\(\$a1\)
+0+057c <[^>]*> swc1 \$f[45],5\(\$a1\)
+0+0580 <[^>]*> lui \$at,0x1
+0+0584 <[^>]*> addu \$at,\$a1,\$at
+0+0588 <[^>]*> swc1 \$f[45],-32768\(\$at\)
+0+058c <[^>]*> swc1 \$f[45],-32764\(\$at\)
+0+0590 <[^>]*> swc1 \$f[45],-32768\(\$a1\)
+0+0594 <[^>]*> swc1 \$f[45],-32764\(\$a1\)
+0+0598 <[^>]*> lui \$at,0x2
+[ ]*598: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+059c <[^>]*> addu \$at,\$a1,\$at
+0+05a0 <[^>]*> swc1 \$f[45],-23131\(\$at\)
+[ ]*5a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+05a4 <[^>]*> swc1 \$f[45],-23127\(\$at\)
+[ ]*5a4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+05a8 <[^>]*> sw \$a0,0\(\$zero\)
+0+05ac <[^>]*> sw \$a1,4\(\$zero\)
+0+05b0 <[^>]*> lui \$a0,0x2
+[ ]*5b0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+05b4 <[^>]*> (d|)addu \$a0,\$a0,\$a1
+0+05b8 <[^>]*> ld \$a0,-23131\(\$a0\)
+[ ]*5b8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+05bc <[^>]*> lui \$at,0x2
+[ ]*5bc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+05c0 <[^>]*> (d|)addu \$at,\$at,\$a1
+0+05c4 <[^>]*> sd \$a0,-23131\(\$at\)
+[ ]*5c4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+05c8 <[^>]*> nop
+
diff --git a/gas/testsuite/gas/mips/ld-pic.s b/gas/testsuite/gas/mips/ld-pic.s
new file mode 100644
index 00000000000..ccf52dfcb48
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld-pic.s
@@ -0,0 +1,60 @@
+# Source file used to test the ld macro with PIC code.
+
+ .set mips1
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ ld $4,0
+ ld $4,1
+ ld $4,0x8000
+ ld $4,-0x8000
+ ld $4,0x10000
+ ld $4,0x1a5a5
+ ld $4,0($5)
+ ld $4,1($5)
+ ld $4,0x8000($5)
+ ld $4,-0x8000($5)
+ ld $4,0x10000($5)
+ ld $4,0x1a5a5($5)
+ ld $4,data_label
+ ld $4,big_external_data_label
+ ld $4,small_external_data_label
+ ld $4,big_external_common
+ ld $4,small_external_common
+ ld $4,big_local_common
+ ld $4,small_local_common
+ ld $4,data_label+1
+ ld $4,big_external_data_label+1
+ ld $4,small_external_data_label+1
+ ld $4,big_external_common+1
+ ld $4,small_external_common+1
+ ld $4,big_local_common+1
+ ld $4,small_local_common+1
+ ld $4,data_label($5)
+ ld $4,big_external_data_label($5)
+ ld $4,small_external_data_label($5)
+ ld $4,big_external_common($5)
+ ld $4,small_external_common($5)
+ ld $4,big_local_common($5)
+ ld $4,small_local_common($5)
+ ld $4,data_label+1($5)
+ ld $4,big_external_data_label+1($5)
+ ld $4,small_external_data_label+1($5)
+ ld $4,big_external_common+1($5)
+ ld $4,small_external_common+1($5)
+ ld $4,big_local_common+1($5)
+ ld $4,small_local_common+1($5)
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ .ifndef EMPIC
+ nop
+ nop
+ .endif
diff --git a/gas/testsuite/gas/mips/ld-svr4pic.d b/gas/testsuite/gas/mips/ld-svr4pic.d
new file mode 100644
index 00000000000..2043d798f29
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld-svr4pic.d
@@ -0,0 +1,225 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ld-svr4pic
+#as: -mips1 -mcpu=r3000 -KPIC
+#source: ld-pic.s
+
+# Test the ld macro with -KPIC.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$a0,0\(\$zero\)
+0+0004 <[^>]*> lw \$a1,4\(\$zero\)
+0+0008 <[^>]*> lw \$a0,1\(\$zero\)
+0+000c <[^>]*> lw \$a1,5\(\$zero\)
+0+0010 <[^>]*> lui \$at,0x1
+0+0014 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0018 <[^>]*> lw \$a1,-32764\(\$at\)
+0+001c <[^>]*> lw \$a0,-32768\(\$zero\)
+0+0020 <[^>]*> lw \$a1,-32764\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lw \$a0,0\(\$at\)
+0+002c <[^>]*> lw \$a1,4\(\$at\)
+0+0030 <[^>]*> lui \$at,0x2
+0+0034 <[^>]*> lw \$a0,-23131\(\$at\)
+0+0038 <[^>]*> lw \$a1,-23127\(\$at\)
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lw \$a0,0\(\$a1\)
+0+0044 <[^>]*> lw \$a1,4\(\$a1\)
+0+0048 <[^>]*> nop
+0+004c <[^>]*> lw \$a0,1\(\$a1\)
+0+0050 <[^>]*> lw \$a1,5\(\$a1\)
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> addu \$at,\$a1,\$at
+0+005c <[^>]*> lw \$a0,-32768\(\$at\)
+0+0060 <[^>]*> lw \$a1,-32764\(\$at\)
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> lw \$a0,-32768\(\$a1\)
+0+006c <[^>]*> lw \$a1,-32764\(\$a1\)
+0+0070 <[^>]*> lui \$at,0x1
+0+0074 <[^>]*> addu \$at,\$a1,\$at
+0+0078 <[^>]*> lw \$a0,0\(\$at\)
+0+007c <[^>]*> lw \$a1,4\(\$at\)
+0+0080 <[^>]*> lui \$at,0x2
+0+0084 <[^>]*> addu \$at,\$a1,\$at
+0+0088 <[^>]*> lw \$a0,-23131\(\$at\)
+0+008c <[^>]*> lw \$a1,-23127\(\$at\)
+0+0090 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*90: R_MIPS_GOT16 .data
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*98: R_MIPS_LO16 .data
+0+009c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*9c: R_MIPS_LO16 .data
+0+00a0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*a0: R_MIPS_GOT16 big_external_data_label
+0+00a4 <[^>]*> nop
+0+00a8 <[^>]*> lw \$a0,0\(\$at\)
+0+00ac <[^>]*> lw \$a1,4\(\$at\)
+0+00b0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*b0: R_MIPS_GOT16 small_external_data_label
+0+00b4 <[^>]*> nop
+0+00b8 <[^>]*> lw \$a0,0\(\$at\)
+0+00bc <[^>]*> lw \$a1,4\(\$at\)
+0+00c0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*c0: R_MIPS_GOT16 big_external_common
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> lw \$a0,0\(\$at\)
+0+00cc <[^>]*> lw \$a1,4\(\$at\)
+0+00d0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*d0: R_MIPS_GOT16 small_external_common
+0+00d4 <[^>]*> nop
+0+00d8 <[^>]*> lw \$a0,0\(\$at\)
+0+00dc <[^>]*> lw \$a1,4\(\$at\)
+0+00e0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*e0: R_MIPS_GOT16 .bss
+0+00e4 <[^>]*> nop
+0+00e8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*e8: R_MIPS_LO16 .bss
+0+00ec <[^>]*> lw \$a1,4\(\$at\)
+[ ]*ec: R_MIPS_LO16 .bss
+0+00f0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*f0: R_MIPS_GOT16 .bss
+0+00f4 <[^>]*> nop
+0+00f8 <[^>]*> lw \$a0,1000\(\$at\)
+[ ]*f8: R_MIPS_LO16 .bss
+0+00fc <[^>]*> lw \$a1,1004\(\$at\)
+[ ]*fc: R_MIPS_LO16 .bss
+0+0100 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*100: R_MIPS_GOT16 .data
+0+0104 <[^>]*> nop
+0+0108 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*108: R_MIPS_LO16 .data
+0+010c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*10c: R_MIPS_LO16 .data
+0+0110 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*110: R_MIPS_GOT16 big_external_data_label
+0+0114 <[^>]*> nop
+0+0118 <[^>]*> lw \$a0,1\(\$at\)
+0+011c <[^>]*> lw \$a1,5\(\$at\)
+0+0120 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*120: R_MIPS_GOT16 small_external_data_label
+0+0124 <[^>]*> nop
+0+0128 <[^>]*> lw \$a0,1\(\$at\)
+0+012c <[^>]*> lw \$a1,5\(\$at\)
+0+0130 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*130: R_MIPS_GOT16 big_external_common
+0+0134 <[^>]*> nop
+0+0138 <[^>]*> lw \$a0,1\(\$at\)
+0+013c <[^>]*> lw \$a1,5\(\$at\)
+0+0140 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*140: R_MIPS_GOT16 small_external_common
+0+0144 <[^>]*> nop
+0+0148 <[^>]*> lw \$a0,1\(\$at\)
+0+014c <[^>]*> lw \$a1,5\(\$at\)
+0+0150 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*150: R_MIPS_GOT16 .bss
+0+0154 <[^>]*> nop
+0+0158 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*158: R_MIPS_LO16 .bss
+0+015c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*15c: R_MIPS_LO16 .bss
+0+0160 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*160: R_MIPS_GOT16 .bss
+0+0164 <[^>]*> nop
+0+0168 <[^>]*> lw \$a0,1001\(\$at\)
+[ ]*168: R_MIPS_LO16 .bss
+0+016c <[^>]*> lw \$a1,1005\(\$at\)
+[ ]*16c: R_MIPS_LO16 .bss
+0+0170 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*170: R_MIPS_GOT16 .data
+0+0174 <[^>]*> nop
+0+0178 <[^>]*> addu \$at,\$a1,\$at
+0+017c <[^>]*> lw \$a0,0\(\$at\)
+[ ]*17c: R_MIPS_LO16 .data
+0+0180 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*180: R_MIPS_LO16 .data
+0+0184 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*184: R_MIPS_GOT16 big_external_data_label
+0+0188 <[^>]*> nop
+0+018c <[^>]*> addu \$at,\$a1,\$at
+0+0190 <[^>]*> lw \$a0,0\(\$at\)
+0+0194 <[^>]*> lw \$a1,4\(\$at\)
+0+0198 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*198: R_MIPS_GOT16 small_external_data_label
+0+019c <[^>]*> nop
+0+01a0 <[^>]*> addu \$at,\$a1,\$at
+0+01a4 <[^>]*> lw \$a0,0\(\$at\)
+0+01a8 <[^>]*> lw \$a1,4\(\$at\)
+0+01ac <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1ac: R_MIPS_GOT16 big_external_common
+0+01b0 <[^>]*> nop
+0+01b4 <[^>]*> addu \$at,\$a1,\$at
+0+01b8 <[^>]*> lw \$a0,0\(\$at\)
+0+01bc <[^>]*> lw \$a1,4\(\$at\)
+0+01c0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1c0: R_MIPS_GOT16 small_external_common
+0+01c4 <[^>]*> nop
+0+01c8 <[^>]*> addu \$at,\$a1,\$at
+0+01cc <[^>]*> lw \$a0,0\(\$at\)
+0+01d0 <[^>]*> lw \$a1,4\(\$at\)
+0+01d4 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1d4: R_MIPS_GOT16 .bss
+0+01d8 <[^>]*> nop
+0+01dc <[^>]*> addu \$at,\$a1,\$at
+0+01e0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1e0: R_MIPS_LO16 .bss
+0+01e4 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1e4: R_MIPS_LO16 .bss
+0+01e8 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1e8: R_MIPS_GOT16 .bss
+0+01ec <[^>]*> nop
+0+01f0 <[^>]*> addu \$at,\$a1,\$at
+0+01f4 <[^>]*> lw \$a0,1000\(\$at\)
+[ ]*1f4: R_MIPS_LO16 .bss
+0+01f8 <[^>]*> lw \$a1,1004\(\$at\)
+[ ]*1f8: R_MIPS_LO16 .bss
+0+01fc <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1fc: R_MIPS_GOT16 .data
+0+0200 <[^>]*> nop
+0+0204 <[^>]*> addu \$at,\$a1,\$at
+0+0208 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*208: R_MIPS_LO16 .data
+0+020c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*20c: R_MIPS_LO16 .data
+0+0210 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*210: R_MIPS_GOT16 big_external_data_label
+0+0214 <[^>]*> nop
+0+0218 <[^>]*> addu \$at,\$a1,\$at
+0+021c <[^>]*> lw \$a0,1\(\$at\)
+0+0220 <[^>]*> lw \$a1,5\(\$at\)
+0+0224 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*224: R_MIPS_GOT16 small_external_data_label
+0+0228 <[^>]*> nop
+0+022c <[^>]*> addu \$at,\$a1,\$at
+0+0230 <[^>]*> lw \$a0,1\(\$at\)
+0+0234 <[^>]*> lw \$a1,5\(\$at\)
+0+0238 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*238: R_MIPS_GOT16 big_external_common
+0+023c <[^>]*> nop
+0+0240 <[^>]*> addu \$at,\$a1,\$at
+0+0244 <[^>]*> lw \$a0,1\(\$at\)
+0+0248 <[^>]*> lw \$a1,5\(\$at\)
+0+024c <[^>]*> lw \$at,0\(\$gp\)
+[ ]*24c: R_MIPS_GOT16 small_external_common
+0+0250 <[^>]*> nop
+0+0254 <[^>]*> addu \$at,\$a1,\$at
+0+0258 <[^>]*> lw \$a0,1\(\$at\)
+0+025c <[^>]*> lw \$a1,5\(\$at\)
+0+0260 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*260: R_MIPS_GOT16 .bss
+0+0264 <[^>]*> nop
+0+0268 <[^>]*> addu \$at,\$a1,\$at
+0+026c <[^>]*> lw \$a0,1\(\$at\)
+[ ]*26c: R_MIPS_LO16 .bss
+0+0270 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*270: R_MIPS_LO16 .bss
+0+0274 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*274: R_MIPS_GOT16 .bss
+0+0278 <[^>]*> nop
+0+027c <[^>]*> addu \$at,\$a1,\$at
+0+0280 <[^>]*> lw \$a0,1001\(\$at\)
+[ ]*280: R_MIPS_LO16 .bss
+0+0284 <[^>]*> lw \$a1,1005\(\$at\)
+[ ]*284: R_MIPS_LO16 .bss
+ ...
diff --git a/gas/testsuite/gas/mips/ld-xgot.d b/gas/testsuite/gas/mips/ld-xgot.d
new file mode 100644
index 00000000000..40262cf2446
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld-xgot.d
@@ -0,0 +1,273 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ld-xgot
+#as: -mips1 -mcpu=r3000 -KPIC -xgot
+#source: ld-pic.s
+
+# Test the ld macro with -KPIC -xgot.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$a0,0\(\$zero\)
+0+0004 <[^>]*> lw \$a1,4\(\$zero\)
+0+0008 <[^>]*> lw \$a0,1\(\$zero\)
+0+000c <[^>]*> lw \$a1,5\(\$zero\)
+0+0010 <[^>]*> lui \$at,0x1
+0+0014 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0018 <[^>]*> lw \$a1,-32764\(\$at\)
+0+001c <[^>]*> lw \$a0,-32768\(\$zero\)
+0+0020 <[^>]*> lw \$a1,-32764\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lw \$a0,0\(\$at\)
+0+002c <[^>]*> lw \$a1,4\(\$at\)
+0+0030 <[^>]*> lui \$at,0x2
+0+0034 <[^>]*> lw \$a0,-23131\(\$at\)
+0+0038 <[^>]*> lw \$a1,-23127\(\$at\)
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lw \$a0,0\(\$a1\)
+0+0044 <[^>]*> lw \$a1,4\(\$a1\)
+0+0048 <[^>]*> nop
+0+004c <[^>]*> lw \$a0,1\(\$a1\)
+0+0050 <[^>]*> lw \$a1,5\(\$a1\)
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> addu \$at,\$a1,\$at
+0+005c <[^>]*> lw \$a0,-32768\(\$at\)
+0+0060 <[^>]*> lw \$a1,-32764\(\$at\)
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> lw \$a0,-32768\(\$a1\)
+0+006c <[^>]*> lw \$a1,-32764\(\$a1\)
+0+0070 <[^>]*> lui \$at,0x1
+0+0074 <[^>]*> addu \$at,\$a1,\$at
+0+0078 <[^>]*> lw \$a0,0\(\$at\)
+0+007c <[^>]*> lw \$a1,4\(\$at\)
+0+0080 <[^>]*> lui \$at,0x2
+0+0084 <[^>]*> addu \$at,\$a1,\$at
+0+0088 <[^>]*> lw \$a0,-23131\(\$at\)
+0+008c <[^>]*> lw \$a1,-23127\(\$at\)
+0+0090 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*90: R_MIPS_GOT16 .data
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*98: R_MIPS_LO16 .data
+0+009c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*9c: R_MIPS_LO16 .data
+0+00a0 <[^>]*> lui \$at,0x0
+[ ]*a0: R_MIPS_GOT_HI16 big_external_data_label
+0+00a4 <[^>]*> addu \$at,\$at,\$gp
+0+00a8 <[^>]*> lw \$at,0\(\$at\)
+[ ]*a8: R_MIPS_GOT_LO16 big_external_data_label
+0+00ac <[^>]*> nop
+0+00b0 <[^>]*> lw \$a0,0\(\$at\)
+0+00b4 <[^>]*> lw \$a1,4\(\$at\)
+0+00b8 <[^>]*> lui \$at,0x0
+[ ]*b8: R_MIPS_GOT_HI16 small_external_data_label
+0+00bc <[^>]*> addu \$at,\$at,\$gp
+0+00c0 <[^>]*> lw \$at,0\(\$at\)
+[ ]*c0: R_MIPS_GOT_LO16 small_external_data_label
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> lw \$a0,0\(\$at\)
+0+00cc <[^>]*> lw \$a1,4\(\$at\)
+0+00d0 <[^>]*> lui \$at,0x0
+[ ]*d0: R_MIPS_GOT_HI16 big_external_common
+0+00d4 <[^>]*> addu \$at,\$at,\$gp
+0+00d8 <[^>]*> lw \$at,0\(\$at\)
+[ ]*d8: R_MIPS_GOT_LO16 big_external_common
+0+00dc <[^>]*> nop
+0+00e0 <[^>]*> lw \$a0,0\(\$at\)
+0+00e4 <[^>]*> lw \$a1,4\(\$at\)
+0+00e8 <[^>]*> lui \$at,0x0
+[ ]*e8: R_MIPS_GOT_HI16 small_external_common
+0+00ec <[^>]*> addu \$at,\$at,\$gp
+0+00f0 <[^>]*> lw \$at,0\(\$at\)
+[ ]*f0: R_MIPS_GOT_LO16 small_external_common
+0+00f4 <[^>]*> nop
+0+00f8 <[^>]*> lw \$a0,0\(\$at\)
+0+00fc <[^>]*> lw \$a1,4\(\$at\)
+0+0100 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*100: R_MIPS_GOT16 .bss
+0+0104 <[^>]*> nop
+0+0108 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*108: R_MIPS_LO16 .bss
+0+010c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*10c: R_MIPS_LO16 .bss
+0+0110 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*110: R_MIPS_GOT16 .bss
+0+0114 <[^>]*> nop
+0+0118 <[^>]*> lw \$a0,1000\(\$at\)
+[ ]*118: R_MIPS_LO16 .bss
+0+011c <[^>]*> lw \$a1,1004\(\$at\)
+[ ]*11c: R_MIPS_LO16 .bss
+0+0120 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*120: R_MIPS_GOT16 .data
+0+0124 <[^>]*> nop
+0+0128 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*128: R_MIPS_LO16 .data
+0+012c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*12c: R_MIPS_LO16 .data
+0+0130 <[^>]*> lui \$at,0x0
+[ ]*130: R_MIPS_GOT_HI16 big_external_data_label
+0+0134 <[^>]*> addu \$at,\$at,\$gp
+0+0138 <[^>]*> lw \$at,0\(\$at\)
+[ ]*138: R_MIPS_GOT_LO16 big_external_data_label
+0+013c <[^>]*> nop
+0+0140 <[^>]*> lw \$a0,1\(\$at\)
+0+0144 <[^>]*> lw \$a1,5\(\$at\)
+0+0148 <[^>]*> lui \$at,0x0
+[ ]*148: R_MIPS_GOT_HI16 small_external_data_label
+0+014c <[^>]*> addu \$at,\$at,\$gp
+0+0150 <[^>]*> lw \$at,0\(\$at\)
+[ ]*150: R_MIPS_GOT_LO16 small_external_data_label
+0+0154 <[^>]*> nop
+0+0158 <[^>]*> lw \$a0,1\(\$at\)
+0+015c <[^>]*> lw \$a1,5\(\$at\)
+0+0160 <[^>]*> lui \$at,0x0
+[ ]*160: R_MIPS_GOT_HI16 big_external_common
+0+0164 <[^>]*> addu \$at,\$at,\$gp
+0+0168 <[^>]*> lw \$at,0\(\$at\)
+[ ]*168: R_MIPS_GOT_LO16 big_external_common
+0+016c <[^>]*> nop
+0+0170 <[^>]*> lw \$a0,1\(\$at\)
+0+0174 <[^>]*> lw \$a1,5\(\$at\)
+0+0178 <[^>]*> lui \$at,0x0
+[ ]*178: R_MIPS_GOT_HI16 small_external_common
+0+017c <[^>]*> addu \$at,\$at,\$gp
+0+0180 <[^>]*> lw \$at,0\(\$at\)
+[ ]*180: R_MIPS_GOT_LO16 small_external_common
+0+0184 <[^>]*> nop
+0+0188 <[^>]*> lw \$a0,1\(\$at\)
+0+018c <[^>]*> lw \$a1,5\(\$at\)
+0+0190 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*190: R_MIPS_GOT16 .bss
+0+0194 <[^>]*> nop
+0+0198 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*198: R_MIPS_LO16 .bss
+0+019c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*19c: R_MIPS_LO16 .bss
+0+01a0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1a0: R_MIPS_GOT16 .bss
+0+01a4 <[^>]*> nop
+0+01a8 <[^>]*> lw \$a0,1001\(\$at\)
+[ ]*1a8: R_MIPS_LO16 .bss
+0+01ac <[^>]*> lw \$a1,1005\(\$at\)
+[ ]*1ac: R_MIPS_LO16 .bss
+0+01b0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1b0: R_MIPS_GOT16 .data
+0+01b4 <[^>]*> nop
+0+01b8 <[^>]*> addu \$at,\$a1,\$at
+0+01bc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1bc: R_MIPS_LO16 .data
+0+01c0 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*1c0: R_MIPS_LO16 .data
+0+01c4 <[^>]*> lui \$at,0x0
+[ ]*1c4: R_MIPS_GOT_HI16 big_external_data_label
+0+01c8 <[^>]*> addu \$at,\$at,\$gp
+0+01cc <[^>]*> lw \$at,0\(\$at\)
+[ ]*1cc: R_MIPS_GOT_LO16 big_external_data_label
+0+01d0 <[^>]*> nop
+0+01d4 <[^>]*> addu \$at,\$a1,\$at
+0+01d8 <[^>]*> lw \$a0,0\(\$at\)
+0+01dc <[^>]*> lw \$a1,4\(\$at\)
+0+01e0 <[^>]*> lui \$at,0x0
+[ ]*1e0: R_MIPS_GOT_HI16 small_external_data_label
+0+01e4 <[^>]*> addu \$at,\$at,\$gp
+0+01e8 <[^>]*> lw \$at,0\(\$at\)
+[ ]*1e8: R_MIPS_GOT_LO16 small_external_data_label
+0+01ec <[^>]*> nop
+0+01f0 <[^>]*> addu \$at,\$a1,\$at
+0+01f4 <[^>]*> lw \$a0,0\(\$at\)
+0+01f8 <[^>]*> lw \$a1,4\(\$at\)
+0+01fc <[^>]*> lui \$at,0x0
+[ ]*1fc: R_MIPS_GOT_HI16 big_external_common
+0+0200 <[^>]*> addu \$at,\$at,\$gp
+0+0204 <[^>]*> lw \$at,0\(\$at\)
+[ ]*204: R_MIPS_GOT_LO16 big_external_common
+0+0208 <[^>]*> nop
+0+020c <[^>]*> addu \$at,\$a1,\$at
+0+0210 <[^>]*> lw \$a0,0\(\$at\)
+0+0214 <[^>]*> lw \$a1,4\(\$at\)
+0+0218 <[^>]*> lui \$at,0x0
+[ ]*218: R_MIPS_GOT_HI16 small_external_common
+0+021c <[^>]*> addu \$at,\$at,\$gp
+0+0220 <[^>]*> lw \$at,0\(\$at\)
+[ ]*220: R_MIPS_GOT_LO16 small_external_common
+0+0224 <[^>]*> nop
+0+0228 <[^>]*> addu \$at,\$a1,\$at
+0+022c <[^>]*> lw \$a0,0\(\$at\)
+0+0230 <[^>]*> lw \$a1,4\(\$at\)
+0+0234 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*234: R_MIPS_GOT16 .bss
+0+0238 <[^>]*> nop
+0+023c <[^>]*> addu \$at,\$a1,\$at
+0+0240 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*240: R_MIPS_LO16 .bss
+0+0244 <[^>]*> lw \$a1,4\(\$at\)
+[ ]*244: R_MIPS_LO16 .bss
+0+0248 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*248: R_MIPS_GOT16 .bss
+0+024c <[^>]*> nop
+0+0250 <[^>]*> addu \$at,\$a1,\$at
+0+0254 <[^>]*> lw \$a0,1000\(\$at\)
+[ ]*254: R_MIPS_LO16 .bss
+0+0258 <[^>]*> lw \$a1,1004\(\$at\)
+[ ]*258: R_MIPS_LO16 .bss
+0+025c <[^>]*> lw \$at,0\(\$gp\)
+[ ]*25c: R_MIPS_GOT16 .data
+0+0260 <[^>]*> nop
+0+0264 <[^>]*> addu \$at,\$a1,\$at
+0+0268 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*268: R_MIPS_LO16 .data
+0+026c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*26c: R_MIPS_LO16 .data
+0+0270 <[^>]*> lui \$at,0x0
+[ ]*270: R_MIPS_GOT_HI16 big_external_data_label
+0+0274 <[^>]*> addu \$at,\$at,\$gp
+0+0278 <[^>]*> lw \$at,0\(\$at\)
+[ ]*278: R_MIPS_GOT_LO16 big_external_data_label
+0+027c <[^>]*> nop
+0+0280 <[^>]*> addu \$at,\$a1,\$at
+0+0284 <[^>]*> lw \$a0,1\(\$at\)
+0+0288 <[^>]*> lw \$a1,5\(\$at\)
+0+028c <[^>]*> lui \$at,0x0
+[ ]*28c: R_MIPS_GOT_HI16 small_external_data_label
+0+0290 <[^>]*> addu \$at,\$at,\$gp
+0+0294 <[^>]*> lw \$at,0\(\$at\)
+[ ]*294: R_MIPS_GOT_LO16 small_external_data_label
+0+0298 <[^>]*> nop
+0+029c <[^>]*> addu \$at,\$a1,\$at
+0+02a0 <[^>]*> lw \$a0,1\(\$at\)
+0+02a4 <[^>]*> lw \$a1,5\(\$at\)
+0+02a8 <[^>]*> lui \$at,0x0
+[ ]*2a8: R_MIPS_GOT_HI16 big_external_common
+0+02ac <[^>]*> addu \$at,\$at,\$gp
+0+02b0 <[^>]*> lw \$at,0\(\$at\)
+[ ]*2b0: R_MIPS_GOT_LO16 big_external_common
+0+02b4 <[^>]*> nop
+0+02b8 <[^>]*> addu \$at,\$a1,\$at
+0+02bc <[^>]*> lw \$a0,1\(\$at\)
+0+02c0 <[^>]*> lw \$a1,5\(\$at\)
+0+02c4 <[^>]*> lui \$at,0x0
+[ ]*2c4: R_MIPS_GOT_HI16 small_external_common
+0+02c8 <[^>]*> addu \$at,\$at,\$gp
+0+02cc <[^>]*> lw \$at,0\(\$at\)
+[ ]*2cc: R_MIPS_GOT_LO16 small_external_common
+0+02d0 <[^>]*> nop
+0+02d4 <[^>]*> addu \$at,\$a1,\$at
+0+02d8 <[^>]*> lw \$a0,1\(\$at\)
+0+02dc <[^>]*> lw \$a1,5\(\$at\)
+0+02e0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*2e0: R_MIPS_GOT16 .bss
+0+02e4 <[^>]*> nop
+0+02e8 <[^>]*> addu \$at,\$a1,\$at
+0+02ec <[^>]*> lw \$a0,1\(\$at\)
+[ ]*2ec: R_MIPS_LO16 .bss
+0+02f0 <[^>]*> lw \$a1,5\(\$at\)
+[ ]*2f0: R_MIPS_LO16 .bss
+0+02f4 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*2f4: R_MIPS_GOT16 .bss
+0+02f8 <[^>]*> nop
+0+02fc <[^>]*> addu \$at,\$a1,\$at
+0+0300 <[^>]*> lw \$a0,1001\(\$at\)
+[ ]*300: R_MIPS_LO16 .bss
+0+0304 <[^>]*> lw \$a1,1005\(\$at\)
+[ ]*304: R_MIPS_LO16 .bss
+ ...
diff --git a/gas/testsuite/gas/mips/ld.d b/gas/testsuite/gas/mips/ld.d
new file mode 100644
index 00000000000..5489cf16e3d
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld.d
@@ -0,0 +1,639 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#as: -mcpu=r4000
+#name: MIPS ld
+
+# Test the ld macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$a0,0\(\$zero\)
+0+0004 <[^>]*> lw \$a1,4\(\$zero\)
+0+0008 <[^>]*> lw \$a0,1\(\$zero\)
+0+000c <[^>]*> lw \$a1,5\(\$zero\)
+0+0010 <[^>]*> lui \$at,0x1
+0+0014 <[^>]*> lw \$a0,-32768\(\$at\)
+0+0018 <[^>]*> lw \$a1,-32764\(\$at\)
+0+001c <[^>]*> lw \$a0,-32768\(\$zero\)
+0+0020 <[^>]*> lw \$a1,-32764\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lw \$a0,0\(\$at\)
+0+002c <[^>]*> lw \$a1,4\(\$at\)
+0+0030 <[^>]*> lui \$at,0x2
+0+0034 <[^>]*> lw \$a0,-23131\(\$at\)
+0+0038 <[^>]*> lw \$a1,-23127\(\$at\)
+0+003c <[^>]*> nop
+0+0040 <[^>]*> lw \$a0,0\(\$a1\)
+0+0044 <[^>]*> lw \$a1,4\(\$a1\)
+0+0048 <[^>]*> nop
+0+004c <[^>]*> lw \$a0,1\(\$a1\)
+0+0050 <[^>]*> lw \$a1,5\(\$a1\)
+0+0054 <[^>]*> lui \$at,0x1
+0+0058 <[^>]*> addu \$at,\$a1,\$at
+0+005c <[^>]*> lw \$a0,-32768\(\$at\)
+0+0060 <[^>]*> lw \$a1,-32764\(\$at\)
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> lw \$a0,-32768\(\$a1\)
+0+006c <[^>]*> lw \$a1,-32764\(\$a1\)
+0+0070 <[^>]*> lui \$at,0x1
+0+0074 <[^>]*> addu \$at,\$a1,\$at
+0+0078 <[^>]*> lw \$a0,0\(\$at\)
+0+007c <[^>]*> lw \$a1,4\(\$at\)
+0+0080 <[^>]*> lui \$at,0x2
+0+0084 <[^>]*> addu \$at,\$a1,\$at
+0+0088 <[^>]*> lw \$a0,-23131\(\$at\)
+0+008c <[^>]*> lw \$a1,-23127\(\$at\)
+0+0090 <[^>]*> lui \$at,0x0
+[ ]*90: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0094 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*94: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0098 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*98: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+009c <[^>]*> lui \$at,0x0
+[ ]*9c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00a0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00a4 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*a4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00a8 <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00ac <[^>]*> lw \$a1,[-0-9]+\(\$gp\)
+[ ]*ac: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00b0 <[^>]*> lui \$at,0x0
+[ ]*b0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00b4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00b8 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00bc <[^>]*> lw \$a0,0\(\$gp\)
+[ ]*bc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00c0 <[^>]*> lw \$a1,[-0-9]+\(\$gp\)
+[ ]*c0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00c4 <[^>]*> lui \$at,0x0
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00c8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00cc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*cc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00d0 <[^>]*> lw \$a0,[-0-9]+\(\$gp\)
+[ ]*d0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00d4 <[^>]*> lw \$a1,[-0-9]+\(\$gp\)
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00d8 <[^>]*> lui \$at,0x0
+[ ]*d8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00dc <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*dc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00e0 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*e0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00e4 <[^>]*> lui \$at,0x0
+[ ]*e4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00e8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*e8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00ec <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*ec: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00f0 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00f4 <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*f4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00f8 <[^>]*> lui \$at,0x0
+[ ]*f8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00fc <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0100 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0104 <[^>]*> lw \$a0,1\(\$gp\)
+[ ]*104: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0108 <[^>]*> lw \$a1,5\(\$gp\)
+[ ]*108: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+010c <[^>]*> lui \$at,0x0
+[ ]*10c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0110 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*110: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0114 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*114: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0118 <[^>]*> lw \$a0,[-0-9]+\(\$gp\)
+[ ]*118: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+011c <[^>]*> lw \$a1,[-0-9]+\(\$gp\)
+[ ]*11c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0120 <[^>]*> lui \$at,[-0-9x]+
+[ ]*120: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0124 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*124: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0128 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*128: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+012c <[^>]*> lui \$at,[-0-9x]+
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0130 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0134 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*134: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0138 <[^>]*> lui \$at,[-0-9x]+
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+013c <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0140 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*140: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0144 <[^>]*> lui \$at,[-0-9x]+
+[ ]*144: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0148 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*148: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+014c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0150 <[^>]*> lui \$at,[-0-9x]+
+[ ]*150: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0154 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*154: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0158 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*158: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+015c <[^>]*> lui \$at,[-0-9x]+
+[ ]*15c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0160 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*160: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0164 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*164: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0168 <[^>]*> lui \$at,[-0-9x]+
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+016c <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0170 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*170: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0174 <[^>]*> lui \$at,0x0
+[ ]*174: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0178 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*178: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+017c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0180 <[^>]*> lui \$at,0x0
+[ ]*180: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0184 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*184: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0188 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*188: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+018c <[^>]*> lui \$at,0x0
+[ ]*18c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0190 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*190: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0194 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*194: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+019c <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01a0 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01a4 <[^>]*> lui \$at,0x0
+[ ]*1a4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01a8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*1a8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01ac <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01b0 <[^>]*> lui \$at,0x0
+[ ]*1b0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01b4 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*1b4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01b8 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1b8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01bc <[^>]*> lui \$at,0x0
+[ ]*1bc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01c0 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*1c0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01c4 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1c4: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01c8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01cc <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01d0 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1d0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01d4 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1d4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01d8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01dc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01e0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1e0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01e4 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1e4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01e8 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1e8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01ec <[^>]*> lui \$at,[-0-9x]+
+[ ]*1ec: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01f0 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01f4 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*1f4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01f8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01fc <[^>]*> lw \$a0,0\(\$at\)
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0200 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*200: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0204 <[^>]*> lui \$at,[-0-9x]+
+[ ]*204: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0208 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*208: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+020c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0210 <[^>]*> lui \$at,[-0-9x]+
+[ ]*210: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0214 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*214: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0218 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*218: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+021c <[^>]*> lui \$at,[-0-9x]+
+[ ]*21c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0220 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*220: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0224 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*224: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+022c <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0230 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*230: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0234 <[^>]*> lui \$at,[-0-9x]+
+[ ]*234: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0238 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*238: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+023c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0240 <[^>]*> lui \$at,[-0-9x]+
+[ ]*240: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0244 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*244: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0248 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*248: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+024c <[^>]*> lui \$at,[-0-9x]+
+[ ]*24c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0250 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*250: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0254 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*254: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+025c <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0260 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*260: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0264 <[^>]*> lui \$at,[-0-9x]+
+[ ]*264: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0268 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*268: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+026c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0270 <[^>]*> lui \$at,0x0
+[ ]*270: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0274 <[^>]*> addu \$at,\$a1,\$at
+0+0278 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*278: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+027c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0280 <[^>]*> lui \$at,0x0
+[ ]*280: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0284 <[^>]*> addu \$at,\$a1,\$at
+0+0288 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*288: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+028c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*28c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0290 <[^>]*> nop
+0+0294 <[^>]*> addu \$at,\$a1,\$gp
+0+0298 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*298: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+029c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*29c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+02a0 <[^>]*> lui \$at,0x0
+[ ]*2a0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02a4 <[^>]*> addu \$at,\$a1,\$at
+0+02a8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*2a8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02ac <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*2ac: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02b0 <[^>]*> nop
+0+02b4 <[^>]*> addu \$at,\$a1,\$gp
+0+02b8 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*2b8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+02bc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*2bc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+02c0 <[^>]*> lui \$at,0x0
+[ ]*2c0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02c4 <[^>]*> addu \$at,\$a1,\$at
+0+02c8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*2c8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02cc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02d0 <[^>]*> nop
+0+02d4 <[^>]*> addu \$at,\$a1,\$gp
+0+02d8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*2d8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+02dc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*2dc: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+02e0 <[^>]*> lui \$at,0x0
+[ ]*2e0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+02e4 <[^>]*> addu \$at,\$a1,\$at
+0+02e8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*2e8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02ec <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*2ec: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02f0 <[^>]*> lui \$at,0x0
+[ ]*2f0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+02f4 <[^>]*> addu \$at,\$a1,\$at
+0+02f8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*2f8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02fc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*2fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0300 <[^>]*> nop
+0+0304 <[^>]*> addu \$at,\$a1,\$gp
+0+0308 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*308: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+030c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*30c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0310 <[^>]*> lui \$at,0x0
+[ ]*310: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0314 <[^>]*> addu \$at,\$a1,\$at
+0+0318 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*318: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+031c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*31c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0320 <[^>]*> nop
+0+0324 <[^>]*> addu \$at,\$a1,\$gp
+0+0328 <[^>]*> lw \$a0,1\(\$at\)
+[ ]*328: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+032c <[^>]*> lw \$a1,5\(\$at\)
+[ ]*32c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0330 <[^>]*> lui \$at,0x0
+[ ]*330: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0334 <[^>]*> addu \$at,\$a1,\$at
+0+0338 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*338: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+033c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*33c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0340 <[^>]*> nop
+0+0344 <[^>]*> addu \$at,\$a1,\$gp
+0+0348 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*348: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+034c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*34c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0350 <[^>]*> lui \$at,[-0-9x]+
+[ ]*350: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0354 <[^>]*> addu \$at,\$a1,\$at
+0+0358 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*358: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+035c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*35c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0360 <[^>]*> lui \$at,[-0-9x]+
+[ ]*360: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0364 <[^>]*> addu \$at,\$a1,\$at
+0+0368 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*368: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+036c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*36c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0370 <[^>]*> lui \$at,[-0-9x]+
+[ ]*370: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0374 <[^>]*> addu \$at,\$a1,\$at
+0+0378 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*378: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+037c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*37c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0380 <[^>]*> lui \$at,[-0-9x]+
+[ ]*380: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0384 <[^>]*> addu \$at,\$a1,\$at
+0+0388 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*388: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+038c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*38c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0390 <[^>]*> lui \$at,[-0-9x]+
+[ ]*390: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0394 <[^>]*> addu \$at,\$a1,\$at
+0+0398 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*398: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+039c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*39c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+03a0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*3a0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+03a4 <[^>]*> addu \$at,\$a1,\$at
+0+03a8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*3a8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03ac <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*3ac: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03b0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*3b0: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+03b4 <[^>]*> addu \$at,\$a1,\$at
+0+03b8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*3b8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+03bc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*3bc: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+03c0 <[^>]*> lui \$at,0x0
+[ ]*3c0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+03c4 <[^>]*> addu \$at,\$a1,\$at
+0+03c8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*3c8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03cc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*3cc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03d0 <[^>]*> lui \$at,0x0
+[ ]*3d0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+03d4 <[^>]*> addu \$at,\$a1,\$at
+0+03d8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*3d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03dc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*3dc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03e0 <[^>]*> lui \$at,0x0
+[ ]*3e0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+03e4 <[^>]*> addu \$at,\$a1,\$at
+0+03e8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*3e8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03ec <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*3ec: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03f0 <[^>]*> lui \$at,0x0
+[ ]*3f0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+03f4 <[^>]*> addu \$at,\$a1,\$at
+0+03f8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*3f8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+03fc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*3fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0400 <[^>]*> lui \$at,0x0
+[ ]*400: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0404 <[^>]*> addu \$at,\$a1,\$at
+0+0408 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*408: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+040c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*40c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0410 <[^>]*> lui \$at,0x0
+[ ]*410: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0414 <[^>]*> addu \$at,\$a1,\$at
+0+0418 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*418: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+041c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*41c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0420 <[^>]*> lui \$at,0x0
+[ ]*420: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0424 <[^>]*> addu \$at,\$a1,\$at
+0+0428 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*428: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+042c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*42c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0430 <[^>]*> lui \$at,[-0-9x]+
+[ ]*430: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0434 <[^>]*> addu \$at,\$a1,\$at
+0+0438 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*438: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+043c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*43c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0440 <[^>]*> lui \$at,[-0-9x]+
+[ ]*440: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0444 <[^>]*> addu \$at,\$a1,\$at
+0+0448 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*448: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+044c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*44c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0450 <[^>]*> lui \$at,[-0-9x]+
+[ ]*450: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0454 <[^>]*> addu \$at,\$a1,\$at
+0+0458 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*458: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+045c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*45c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0460 <[^>]*> lui \$at,[-0-9x]+
+[ ]*460: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0464 <[^>]*> addu \$at,\$a1,\$at
+0+0468 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*468: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+046c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*46c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0470 <[^>]*> lui \$at,[-0-9x]+
+[ ]*470: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0474 <[^>]*> addu \$at,\$a1,\$at
+0+0478 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*478: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+047c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*47c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0480 <[^>]*> lui \$at,[-0-9x]+
+[ ]*480: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0484 <[^>]*> addu \$at,\$a1,\$at
+0+0488 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*488: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+048c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*48c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0490 <[^>]*> lui \$at,[-0-9x]+
+[ ]*490: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0494 <[^>]*> addu \$at,\$a1,\$at
+0+0498 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*498: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+049c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*49c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+04a0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*4a0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+04a4 <[^>]*> addu \$at,\$a1,\$at
+0+04a8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4a8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+04ac <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*4ac: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+04b0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*4b0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+04b4 <[^>]*> addu \$at,\$a1,\$at
+0+04b8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+04bc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*4bc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+04c0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*4c0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+04c4 <[^>]*> addu \$at,\$a1,\$at
+0+04c8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4c8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+04cc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*4cc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+04d0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*4d0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+04d4 <[^>]*> addu \$at,\$a1,\$at
+0+04d8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+04dc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*4dc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+04e0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*4e0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+04e4 <[^>]*> addu \$at,\$a1,\$at
+0+04e8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4e8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+04ec <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*4ec: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+04f0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*4f0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+04f4 <[^>]*> addu \$at,\$a1,\$at
+0+04f8 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4f8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+04fc <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*4fc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0500 <[^>]*> lui \$at,[-0-9x]+
+[ ]*500: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0504 <[^>]*> addu \$at,\$a1,\$at
+0+0508 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*508: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+050c <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*50c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0510 <[^>]*> lwc1 \$f[45],0\(\$zero\)
+0+0514 <[^>]*> lwc1 \$f[45],4\(\$zero\)
+0+0518 <[^>]*> lwc1 \$f[45],1\(\$zero\)
+0+051c <[^>]*> lwc1 \$f[45],5\(\$zero\)
+0+0520 <[^>]*> lui \$at,0x1
+0+0524 <[^>]*> lwc1 \$f[45],-32768\(\$at\)
+0+0528 <[^>]*> lwc1 \$f[45],-32764\(\$at\)
+0+052c <[^>]*> lwc1 \$f[45],-32768\(\$zero\)
+0+0530 <[^>]*> lwc1 \$f[45],-32764\(\$zero\)
+0+0534 <[^>]*> lwc1 \$f[45],0\(\$a1\)
+0+0538 <[^>]*> lwc1 \$f[45],4\(\$a1\)
+0+053c <[^>]*> lwc1 \$f[45],1\(\$a1\)
+0+0540 <[^>]*> lwc1 \$f[45],5\(\$a1\)
+0+0544 <[^>]*> lui \$at,0x1
+0+0548 <[^>]*> addu \$at,\$a1,\$at
+0+054c <[^>]*> lwc1 \$f[45],-32768\(\$at\)
+0+0550 <[^>]*> lwc1 \$f[45],-32764\(\$at\)
+0+0554 <[^>]*> lwc1 \$f[45],-32768\(\$a1\)
+0+0558 <[^>]*> lwc1 \$f[45],-32764\(\$a1\)
+0+055c <[^>]*> lui \$at,[-0-9x]+
+[ ]*55c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0560 <[^>]*> addu \$at,\$a1,\$at
+0+0564 <[^>]*> lwc1 \$f[45],[-0-9]+\(\$at\)
+[ ]*564: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0568 <[^>]*> lwc1 \$f[45],[-0-9]+\(\$at\)
+[ ]*568: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+056c <[^>]*> nop
+0+0570 <[^>]*> swc1 \$f[45],0\(\$zero\)
+0+0574 <[^>]*> swc1 \$f[45],4\(\$zero\)
+0+0578 <[^>]*> swc1 \$f[45],1\(\$zero\)
+0+057c <[^>]*> swc1 \$f[45],5\(\$zero\)
+0+0580 <[^>]*> lui \$at,0x1
+0+0584 <[^>]*> swc1 \$f[45],-32768\(\$at\)
+0+0588 <[^>]*> swc1 \$f[45],-32764\(\$at\)
+0+058c <[^>]*> swc1 \$f[45],-32768\(\$zero\)
+0+0590 <[^>]*> swc1 \$f[45],-32764\(\$zero\)
+0+0594 <[^>]*> swc1 \$f[45],0\(\$a1\)
+0+0598 <[^>]*> swc1 \$f[45],4\(\$a1\)
+0+059c <[^>]*> swc1 \$f[45],1\(\$a1\)
+0+05a0 <[^>]*> swc1 \$f[45],5\(\$a1\)
+0+05a4 <[^>]*> lui \$at,0x1
+0+05a8 <[^>]*> addu \$at,\$a1,\$at
+0+05ac <[^>]*> swc1 \$f[45],-32768\(\$at\)
+0+05b0 <[^>]*> swc1 \$f[45],-32764\(\$at\)
+0+05b4 <[^>]*> swc1 \$f[45],-32768\(\$a1\)
+0+05b8 <[^>]*> swc1 \$f[45],-32764\(\$a1\)
+0+05bc <[^>]*> lui \$at,[-0-9x]+
+[ ]*5bc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+05c0 <[^>]*> addu \$at,\$a1,\$at
+0+05c4 <[^>]*> swc1 \$f[45],[-0-9]+\(\$at\)
+[ ]*5c4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+05c8 <[^>]*> swc1 \$f[45],[-0-9]+\(\$at\)
+[ ]*5c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+05cc <[^>]*> sw \$a0,0\(\$zero\)
+0+05d0 <[^>]*> sw \$a1,4\(\$zero\)
+0+05d4 <[^>]*> lui \$a0,[-0-9x]+
+[ ]*5d4: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+05d8 <[^>]*> daddu \$a0,\$a0,\$a1
+0+05dc <[^>]*> ld \$a0,[-0-9]+\(\$a0\)
+[ ]*5dc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+05e0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*5e0: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+05e4 <[^>]*> daddu \$at,\$at,\$a1
+0+05e8 <[^>]*> sd \$a0,[-0-9]+\(\$at\)
+[ ]*5e8: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+05ec <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/ld.s b/gas/testsuite/gas/mips/ld.s
new file mode 100644
index 00000000000..05ee3c03fe0
--- /dev/null
+++ b/gas/testsuite/gas/mips/ld.s
@@ -0,0 +1,144 @@
+# Source file used to test the ld macro.
+
+ .set mips1
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ ld $4,0
+ ld $4,1
+ ld $4,0x8000
+ ld $4,-0x8000
+ ld $4,0x10000
+ ld $4,0x1a5a5
+ ld $4,0($5)
+ ld $4,1($5)
+ ld $4,0x8000($5)
+ ld $4,-0x8000($5)
+ ld $4,0x10000($5)
+ ld $4,0x1a5a5($5)
+ ld $4,data_label
+ ld $4,big_external_data_label
+ ld $4,small_external_data_label
+ ld $4,big_external_common
+ ld $4,small_external_common
+ ld $4,big_local_common
+ ld $4,small_local_common
+ ld $4,data_label+1
+ ld $4,big_external_data_label+1
+ ld $4,small_external_data_label+1
+ ld $4,big_external_common+1
+ ld $4,small_external_common+1
+ ld $4,big_local_common+1
+ ld $4,small_local_common+1
+ ld $4,data_label+0x8000
+ ld $4,big_external_data_label+0x8000
+ ld $4,small_external_data_label+0x8000
+ ld $4,big_external_common+0x8000
+ ld $4,small_external_common+0x8000
+ ld $4,big_local_common+0x8000
+ ld $4,small_local_common+0x8000
+ ld $4,data_label-0x8000
+ ld $4,big_external_data_label-0x8000
+ ld $4,small_external_data_label-0x8000
+ ld $4,big_external_common-0x8000
+ ld $4,small_external_common-0x8000
+ ld $4,big_local_common-0x8000
+ ld $4,small_local_common-0x8000
+ ld $4,data_label+0x10000
+ ld $4,big_external_data_label+0x10000
+ ld $4,small_external_data_label+0x10000
+ ld $4,big_external_common+0x10000
+ ld $4,small_external_common+0x10000
+ ld $4,big_local_common+0x10000
+ ld $4,small_local_common+0x10000
+ ld $4,data_label+0x1a5a5
+ ld $4,big_external_data_label+0x1a5a5
+ ld $4,small_external_data_label+0x1a5a5
+ ld $4,big_external_common+0x1a5a5
+ ld $4,small_external_common+0x1a5a5
+ ld $4,big_local_common+0x1a5a5
+ ld $4,small_local_common+0x1a5a5
+ ld $4,data_label($5)
+ ld $4,big_external_data_label($5)
+ ld $4,small_external_data_label($5)
+ ld $4,big_external_common($5)
+ ld $4,small_external_common($5)
+ ld $4,big_local_common($5)
+ ld $4,small_local_common($5)
+ ld $4,data_label+1($5)
+ ld $4,big_external_data_label+1($5)
+ ld $4,small_external_data_label+1($5)
+ ld $4,big_external_common+1($5)
+ ld $4,small_external_common+1($5)
+ ld $4,big_local_common+1($5)
+ ld $4,small_local_common+1($5)
+ ld $4,data_label+0x8000($5)
+ ld $4,big_external_data_label+0x8000($5)
+ ld $4,small_external_data_label+0x8000($5)
+ ld $4,big_external_common+0x8000($5)
+ ld $4,small_external_common+0x8000($5)
+ ld $4,big_local_common+0x8000($5)
+ ld $4,small_local_common+0x8000($5)
+ ld $4,data_label-0x8000($5)
+ ld $4,big_external_data_label-0x8000($5)
+ ld $4,small_external_data_label-0x8000($5)
+ ld $4,big_external_common-0x8000($5)
+ ld $4,small_external_common-0x8000($5)
+ ld $4,big_local_common-0x8000($5)
+ ld $4,small_local_common-0x8000($5)
+ ld $4,data_label+0x10000($5)
+ ld $4,big_external_data_label+0x10000($5)
+ ld $4,small_external_data_label+0x10000($5)
+ ld $4,big_external_common+0x10000($5)
+ ld $4,small_external_common+0x10000($5)
+ ld $4,big_local_common+0x10000($5)
+ ld $4,small_local_common+0x10000($5)
+ ld $4,data_label+0x1a5a5($5)
+ ld $4,big_external_data_label+0x1a5a5($5)
+ ld $4,small_external_data_label+0x1a5a5($5)
+ ld $4,big_external_common+0x1a5a5($5)
+ ld $4,small_external_common+0x1a5a5($5)
+ ld $4,big_local_common+0x1a5a5($5)
+ ld $4,small_local_common+0x1a5a5($5)
+
+# l.d and s.d are sort of like ld.
+ l.d $f4,0
+ l.d $f4,1
+ l.d $f4,0x8000
+ l.d $f4,-0x8000
+ l.d $f4,0($5)
+ l.d $f4,1($5)
+ l.d $f4,0x8000($5)
+ l.d $f4,-0x8000($5)
+ l.d $f4,small_external_common+0x1a5a5($5)
+ # Little endian will insert a nop here.
+ # We put it in explicitly so that big and little endian are similar.
+ nop
+ s.d $f4,0
+ s.d $f4,1
+ s.d $f4,0x8000
+ s.d $f4,-0x8000
+ s.d $f4,0($5)
+ s.d $f4,1($5)
+ s.d $f4,0x8000($5)
+ s.d $f4,-0x8000($5)
+ s.d $f4,big_external_common+0x1a5a5($5)
+
+# sd is handled like ld. Sanity check it.
+ sd $4,0
+
+# Sanity check the -mips3 versions
+ .set mips3
+ ld $4,big_local_common+0x1a5a5($5)
+ sd $4,small_local_common+0x1a5a5($5)
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
diff --git a/gas/testsuite/gas/mips/li.d b/gas/testsuite/gas/mips/li.d
new file mode 100644
index 00000000000..0fe2b21ea13
--- /dev/null
+++ b/gas/testsuite/gas/mips/li.d
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS li
+
+# Test the li macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> li \$a0,0
+0+0004 <[^>]*> li \$a0,1
+0+0008 <[^>]*> li \$a0,0x8000
+0+000c <[^>]*> li \$a0,-32768
+0+0010 <[^>]*> lui \$a0,0x1
+0+0014 <[^>]*> lui \$a0,0x1
+0+0018 <[^>]*> ori \$a0,\$a0,0xa5a5
+0+001c <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/li.s b/gas/testsuite/gas/mips/li.s
new file mode 100644
index 00000000000..9c3a6018ad8
--- /dev/null
+++ b/gas/testsuite/gas/mips/li.s
@@ -0,0 +1,12 @@
+# Source file used to test the li macro.
+
+foo:
+ li $4,0
+ li $4,1
+ li $4,0x8000
+ li $4,-0x8000
+ li $4,0x10000
+ li $4,0x1a5a5
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
diff --git a/gas/testsuite/gas/mips/lif-empic.d b/gas/testsuite/gas/mips/lif-empic.d
new file mode 100644
index 00000000000..b80dca37787
--- /dev/null
+++ b/gas/testsuite/gas/mips/lif-empic.d
@@ -0,0 +1,24 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lifloat-empic
+#as: -mips1 -membedded-pic --defsym EMPIC=1
+#source: lifloat.s
+
+# Test the li.d and li.s macros with -membedded-pic.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> addiu \$at,\$gp,-16384
+[ ]*0: [A-Z0-9_]*GPREL[A-Z0-9_]* .rdata.*
+0+0004 <[^>]*> lw \$a0,0\(\$at\)
+0+0008 <[^>]*> lw \$a1,4\(\$at\)
+0+000c <[^>]*> lwc1 \$f[45],-16368\(\$gp\)
+[ ]*c: [A-Z0-9_]*LITERAL[A-Z0-9_]* .lit8.*
+0+0010 <[^>]*> lwc1 \$f[45],-16364\(\$gp\)
+[ ]*10: [A-Z0-9_]*LITERAL[A-Z0-9_]* .lit8.*
+0+0014 <[^>]*> lui \$a0,0x3f8f
+0+0018 <[^>]*> ori \$a0,\$a0,0xcd36
+0+001c <[^>]*> lui \$at,0x3f8f
+0+0020 <[^>]*> ori \$at,\$at,0xcd36
+0+0024 <[^>]*> mtc1 \$at,\$f4
+ ...
diff --git a/gas/testsuite/gas/mips/lif-svr4pic.d b/gas/testsuite/gas/mips/lif-svr4pic.d
new file mode 100644
index 00000000000..db09a7fd54c
--- /dev/null
+++ b/gas/testsuite/gas/mips/lif-svr4pic.d
@@ -0,0 +1,30 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lifloat-svr4pic
+#as: -mips1 -mcpu=r3000 -KPIC -EB --defsym SVR4=1
+#source: lifloat.s
+
+# Test the li.d and li.s macros with -KPIC.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*0: R_MIPS_GOT16 .rodata
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*8: R_MIPS_LO16 .rodata
+0+000c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*c: R_MIPS_LO16 .rodata
+0+0010 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*10: R_MIPS_GOT16 .rodata
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> lwc1 \$f5,8\(\$at\)
+[ ]*18: R_MIPS_LO16 .rodata
+0+001c <[^>]*> lwc1 \$f4,12\(\$at\)
+[ ]*1c: R_MIPS_LO16 .rodata
+0+0020 <[^>]*> lui \$a0,0x3f8f
+0+0024 <[^>]*> ori \$a0,\$a0,0xcd36
+0+0028 <[^>]*> lui \$at,0x3f8f
+0+002c <[^>]*> ori \$at,\$at,0xcd36
+0+0030 <[^>]*> mtc1 \$at,\$f4
+ ...
diff --git a/gas/testsuite/gas/mips/lif-xgot.d b/gas/testsuite/gas/mips/lif-xgot.d
new file mode 100644
index 00000000000..7b86e2b2a34
--- /dev/null
+++ b/gas/testsuite/gas/mips/lif-xgot.d
@@ -0,0 +1,30 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lifloat-xgot
+#as: -mips1 -mcpu=r3000 -KPIC -xgot -EB --defsym XGOT=1
+#source: lifloat.s
+
+# Test the li.d and li.s macros with -KPIC -xgot.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*0: R_MIPS_GOT16 .rodata
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> lw \$a0,0\(\$at\)
+[ ]*8: R_MIPS_LO16 .rodata
+0+000c <[^>]*> lw \$a1,4\(\$at\)
+[ ]*c: R_MIPS_LO16 .rodata
+0+0010 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*10: R_MIPS_GOT16 .rodata
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> lwc1 \$f5,8\(\$at\)
+[ ]*18: R_MIPS_LO16 .rodata
+0+001c <[^>]*> lwc1 \$f4,12\(\$at\)
+[ ]*1c: R_MIPS_LO16 .rodata
+0+0020 <[^>]*> lui \$a0,0x3f8f
+0+0024 <[^>]*> ori \$a0,\$a0,0xcd36
+0+0028 <[^>]*> lui \$at,0x3f8f
+0+002c <[^>]*> ori \$at,\$at,0xcd36
+0+0030 <[^>]*> mtc1 \$at,\$f4
+ ...
diff --git a/gas/testsuite/gas/mips/lifloat.d b/gas/testsuite/gas/mips/lifloat.d
new file mode 100644
index 00000000000..e71b5548d47
--- /dev/null
+++ b/gas/testsuite/gas/mips/lifloat.d
@@ -0,0 +1,23 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS lifloat
+#as: -mips1
+
+# Test the li.d and li.s macros.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lui \$at,0x0
+[ ]*0: [A-Z0-9_]*HI[A-Z0-9_]* .ro?data.*
+0+0004 <[^>]*> lw \$a0,[-0-9]+\(\$at\)
+[ ]*4: [A-Z0-9_]*LO[A-Z0-9_]* .ro?data.*
+0+0008 <[^>]*> lw \$a1,[-0-9]+\(\$at\)
+[ ]*8: [A-Z0-9_]*LO[A-Z0-9_]* .ro?data.*
+0+000c <[^>]*> lwc1 \$f[45],[-0-9]+\(\$gp\)
+[ ]*c: [A-Z0-9_]*LITERAL[A-Z0-9_]* .lit8.*
+0+0010 <[^>]*> lwc1 \$f[45],[-0-9]+\(\$gp\)
+[ ]*10: [A-Z0-9_]*LITERAL[A-Z0-9_]* .lit8.*
+0+0014 <[^>]*> lui \$a0,0x3f8f
+0+0018 <[^>]*> ori \$a0,\$a0,0xcd36
+0+001c <[^>]*> lwc1 \$f4,[-0-9]+\(\$gp\)
+[ ]*1c: [A-Z0-9_]*LITERAL[A-Z0-9_]* .lit4.*
diff --git a/gas/testsuite/gas/mips/lifloat.s b/gas/testsuite/gas/mips/lifloat.s
new file mode 100644
index 00000000000..3977f0e7d4e
--- /dev/null
+++ b/gas/testsuite/gas/mips/lifloat.s
@@ -0,0 +1,24 @@
+# Source file used to test the li.d and li.s macros.
+
+foo:
+ li.d $4,1.12345
+ li.d $f4,1.12345
+
+ li.s $4,1.12345
+ li.s $f4,1.12345
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ .ifdef SVR4
+ nop
+ nop
+ nop
+ .endif
+ .ifdef XGOT
+ nop
+ nop
+ nop
+ .endif
+ .ifdef EMPIC
+ nop
+ nop
+ .endif
diff --git a/gas/testsuite/gas/mips/lineno.d b/gas/testsuite/gas/mips/lineno.d
new file mode 100644
index 00000000000..d2a40f7a44d
--- /dev/null
+++ b/gas/testsuite/gas/mips/lineno.d
@@ -0,0 +1,97 @@
+#objdump: -d -l -mmips:4000
+#name: assembly line numbers
+#as: -g -mcpu=r4000
+
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+0+0000 <main-0x10>:
+.*[0-9a-f]+:.*deadbeef.*
+.*[0-9a-f]+:.*deadbeef.*
+.*[0-9a-f]+:.*deadbeef.*
+.*[0-9a-f]+:.*deadbeef.*
+
+0+0010 <main>:
+main\(\):
+.*lineno.s:16
+.*10:.*addiu.*
+.*lineno.s:17
+.*14:.*sd.*
+.*lineno.s:18
+.*18:.*sd.*
+.*lineno.s:19
+.*1c:.*move.*
+.*lineno.s:20
+.*20:.*jal.*
+.*24:.*nop
+.*lineno.s:21
+.*28:.*li.*
+.*lineno.s:22
+.*2c:.*sw.*
+.*lineno.s:23
+.*30:.*lw.*
+.*lineno.s:24
+.*34:.*move.*
+.*lineno.s:25
+.*38:.*sll.*
+.*lineno.s:26
+.*3c:.*addu.*
+.*lineno.s:27
+.*40:.*sw.*
+.*lineno.s:28
+.*44:.*lw.*
+.*lineno.s:29
+.*48:.*jal.*
+.*4c:.*nop
+.*lineno.s:30
+.*50:.*lw.*
+.*lineno.s:31
+.*54:.*move.*
+.*lineno.s:32
+.*58:.*b.*
+.*5c:.*nop
+
+0000000000000060 <\$L1>:
+.*lineno.s:34
+.*60:.*move.*
+.*lineno.s:35
+.*64:.*ld.*
+.*lineno.s:36
+.*68:.*ld.*
+.*lineno.s:37
+.*6c:.*addiu.*
+.*lineno.s:38
+.*70:.*jr.*
+.*74:.*nop
+
+0000000000000078 <g>:
+g\(\):
+.*lineno.s:47
+.*78:.*addiu.*
+.*lineno.s:48
+.*7c:.*sd.*
+.*lineno.s:49
+.*80:.*move.*
+.*lineno.s:50
+.*84:.*sw.*
+.*lineno.s:51
+.*88:.*lw.*
+.*lineno.s:52
+.*8c:.*addiu.*
+.*lineno.s:53
+.*90:.*move.*
+.*lineno.s:54
+.*94:.*b.*
+.*98:.*nop
+
+000000000000009c <\$L2>:
+.*lineno.s:56
+.*9c:.*move.*
+.*lineno.s:57
+.*a0:.*ld.*
+.*lineno.s:58
+.*a4:.*addiu.*
+.*lineno.s:59
+.*a8:.*jr.*
+.*ac:.*nop
diff --git a/gas/testsuite/gas/mips/lineno.s b/gas/testsuite/gas/mips/lineno.s
new file mode 100644
index 00000000000..531f331a4a7
--- /dev/null
+++ b/gas/testsuite/gas/mips/lineno.s
@@ -0,0 +1,60 @@
+ .text
+
+# some data
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+# some real code, compiled from a toy C program
+ .globl main
+ .ent main
+main:
+ .frame $fp,32,$31 # vars= 16, regs= 2/0, args= 0, extra= 0
+ .mask 0xc0000000,-8
+ .fmask 0x00000000,0
+ subu $sp,$sp,32
+ sd $31,24($sp)
+ sd $fp,16($sp)
+ move $fp,$sp
+ jal __main
+ li $2,2 # 0x2
+ sw $2,0($fp)
+ lw $2,0($fp)
+ move $3,$2
+ sll $4,$3,1
+ addu $2,$4,$2
+ sw $2,4($fp)
+ lw $4,4($fp)
+ jal g
+ lw $3,0($fp)
+ move $2,$3
+ b $L1
+$L1:
+ move $sp,$fp
+ ld $31,24($sp)
+ ld $fp,16($sp)
+ addu $sp,$sp,32
+ j $31
+ .end main
+ .align 2
+ .globl g
+ .ent g
+g:
+ .frame $fp,32,$31 # vars= 16, regs= 1/0, args= 0, extra= 0
+ .mask 0x40000000,-16
+ .fmask 0x00000000,0
+ subu $sp,$sp,32
+ sd $fp,16($sp)
+ move $fp,$sp
+ sw $4,0($fp)
+ lw $2,0($fp)
+ addu $3,$2,1
+ move $2,$3
+ b $L2
+$L2:
+ move $sp,$fp
+ ld $fp,16($sp)
+ addu $sp,$sp,32
+ j $31
+ .end g
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
new file mode 100644
index 00000000000..1b5269d9636
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -0,0 +1,102 @@
+#
+# Some generic MIPS tests
+#
+if [istarget mips*-*-*] then {
+ set no_mips16 0
+ set svr4pic [expr [istarget *-*-elf*] || [istarget *-*-irix5*] || [istarget *-*-irix6* ] ]
+ set empic [expr [istarget *-*-ecoff*] || [istarget *-*-ultrix*] || [istarget *-*-irix\[1-4\]*] ]
+ set aout [expr [istarget *-*-bsd*] || [istarget *-*-netbsd*] || [istarget *-*-openbsd*]]
+ set ilocks [istarget mipstx39*-*-*]
+ set gpr_ilocks [expr [istarget mipstx39*-*-*]]
+ set addr32 [expr [istarget mipstx39*-*-*]]
+
+
+
+
+
+ run_dump_test "abs"
+ run_dump_test "add"
+ run_dump_test "and"
+ run_dump_test "break20"
+ run_dump_test "trap20"
+ run_dump_test "beq"
+ run_dump_test "bge"
+ run_dump_test "bgeu"
+ run_dump_test "blt"
+ run_dump_test "bltu"
+ if !$ilocks { run_dump_test "div" } else { run_dump_test "div-ilocks" }
+ run_dump_test "dli"
+ run_dump_test "jal"
+ if $svr4pic { run_dump_test "jal-svr4pic" }
+ if $svr4pic { run_dump_test "jal-xgot" }
+ if $empic { run_dump_test "jal-empic" }
+ if !$aout { run_dump_test "la" }
+ if $svr4pic { run_dump_test "la-svr4pic" }
+ if $svr4pic { run_dump_test "la-xgot" }
+ if $empic { run_dump_test "la-empic" }
+ if !$aout { run_dump_test "lb" }
+ if $svr4pic { run_dump_test "lb-svr4pic" }
+ if $svr4pic {
+ # Both versions specify the cpu, so we can run both regardless of
+ # the interlocking in the configured default cpu.
+ run_dump_test "lb-xgot"
+ run_dump_test "lb-xgot-ilocks"
+ }
+ if $empic { run_dump_test "lb-empic" }
+ if !$aout {
+ if !$gpr_ilocks {
+ run_dump_test "ld"
+ } else {
+ if !$addr32 {
+ run_dump_test "ld-ilocks"
+ } else {
+ run_dump_test "ld-ilocks-addr32"
+ }
+ }
+ }
+ if $svr4pic { run_dump_test "ld-svr4pic" }
+ if $svr4pic { run_dump_test "ld-xgot" }
+ if $empic { run_dump_test "ld-empic" }
+ run_dump_test "li"
+ if !$aout { run_dump_test "lifloat" }
+ if $svr4pic { run_dump_test "lif-svr4pic" }
+ if $svr4pic { run_dump_test "lif-xgot" }
+ if $empic { run_dump_test "lif-empic" }
+ run_dump_test "mips4"
+ if !$ilocks { run_dump_test "mul" } else { run_dump_test "mul-ilocks" }
+ run_dump_test "rol"
+ if !$aout { run_dump_test "sb" }
+ run_dump_test "trunc"
+ if !$aout { run_dump_test "ulh" }
+ if $svr4pic { run_dump_test "ulh-svr4pic" }
+ if $svr4pic { run_dump_test "ulh-xgot" }
+ if $empic { run_dump_test "ulh-empic" }
+ if !$aout {
+ run_dump_test "ulw"
+ run_dump_test "uld"
+ run_dump_test "ush"
+ run_dump_test "usw"
+ run_dump_test "usd"
+ }
+ # The mips16 test can only be run on ELF, because only ELF
+ # supports the necessary mips16 reloc.
+ if { $svr4pic && !$no_mips16 } { run_dump_test "mips16" }
+ run_dump_test "delay"
+ run_dump_test "nodelay"
+ run_dump_test "mips4010"
+ run_dump_test "mips4650"
+ run_dump_test "mips4100"
+ run_dump_test "lineno"
+ run_dump_test "sync"
+
+ # Make sure that -mcpu=FOO and -mFOO are equivalent. Assemble a file
+ # containing 4650-specific instructions with -m4650 and -mcpu=4650,
+ # and verify that they're the same. Specifically, we're checking
+ # that the EF_MIPS_MACH field is set, and that the 4650 'mul'
+ # instruction does get used. In previous versions of GAS,
+ # only -mcpu=4650 would set the EF_MIPS_MACH field; -m4650 wouldn't.
+ run_dump_test "elf_e_flags1"
+ run_dump_test "elf_e_flags2"
+ run_dump_test "elf_e_flags3"
+ run_dump_test "elf_e_flags4"
+}
diff --git a/gas/testsuite/gas/mips/mips16.d b/gas/testsuite/gas/mips/mips16.d
new file mode 100644
index 00000000000..e4c1a0ca621
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16.d
@@ -0,0 +1,683 @@
+#objdump: -dr -mmips:4000
+#as: -mips3 -mcpu=r4000
+#name: mips16
+
+# Test the mips16 instruction set.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+
+0+000000 <data1>:
+ 0: 00000000 nop
+
+0+000004 <insns1>:
+ 4: 3b40 ld \$v0,0\(\$v1\)
+ 6: f000 3b41 ld \$v0,1\(\$v1\)
+ a: f000 3b42 ld \$v0,2\(\$v1\)
+ e: f000 3b43 ld \$v0,3\(\$v1\)
+ 12: f000 3b44 ld \$v0,4\(\$v1\)
+ 16: 3b41 ld \$v0,8\(\$v1\)
+ 18: 3b42 ld \$v0,16\(\$v1\)
+ 1a: 3b44 ld \$v0,32\(\$v1\)
+ 1c: 3b48 ld \$v0,64\(\$v1\)
+ 1e: 3b50 ld \$v0,128\(\$v1\)
+ 20: f100 3b40 ld \$v0,256\(\$v1\)
+ 24: f200 3b40 ld \$v0,512\(\$v1\)
+ 28: f400 3b40 ld \$v0,1024\(\$v1\)
+ 2c: f001 3b40 ld \$v0,2048\(\$v1\)
+ 30: f7ff 3b5f ld \$v0,-1\(\$v1\)
+ 34: f7ff 3b5e ld \$v0,-2\(\$v1\)
+ 38: f7ff 3b5d ld \$v0,-3\(\$v1\)
+ 3c: f7ff 3b5c ld \$v0,-4\(\$v1\)
+ 40: f7ff 3b58 ld \$v0,-8\(\$v1\)
+ 44: f7ff 3b50 ld \$v0,-16\(\$v1\)
+ 48: f7ff 3b40 ld \$v0,-32\(\$v1\)
+ 4c: f7df 3b40 ld \$v0,-64\(\$v1\)
+ 50: f79f 3b40 ld \$v0,-128\(\$v1\)
+ 54: f71f 3b40 ld \$v0,-256\(\$v1\)
+ 58: f61f 3b40 ld \$v0,-512\(\$v1\)
+ 5c: f41f 3b40 ld \$v0,-1024\(\$v1\)
+ 60: f01f 3b40 ld \$v0,-2048\(\$v1\)
+ 64: f7bf fc40 ld \$v0,0 <data1>
+ 68: f6a0 fc54 ld \$v0,71c <data2>
+ 6c: f001 fc40 ld \$v0,868 <bar>
+ 70: f0c1 fc40 ld \$v0,930 <quux>
+ 74: f840 ld \$v0,0\(\$sp\)
+ 76: f000 f841 ld \$v0,1\(\$sp\)
+ 7a: f000 f842 ld \$v0,2\(\$sp\)
+ 7e: f000 f843 ld \$v0,3\(\$sp\)
+ 82: f000 f844 ld \$v0,4\(\$sp\)
+ 86: f841 ld \$v0,8\(\$sp\)
+ 88: f842 ld \$v0,16\(\$sp\)
+ 8a: f844 ld \$v0,32\(\$sp\)
+ 8c: f848 ld \$v0,64\(\$sp\)
+ 8e: f850 ld \$v0,128\(\$sp\)
+ 90: f100 f840 ld \$v0,256\(\$sp\)
+ 94: f200 f840 ld \$v0,512\(\$sp\)
+ 98: f400 f840 ld \$v0,1024\(\$sp\)
+ 9c: f001 f840 ld \$v0,2048\(\$sp\)
+ a0: f7ff f85f ld \$v0,-1\(\$sp\)
+ a4: f7ff f85e ld \$v0,-2\(\$sp\)
+ a8: f7ff f85d ld \$v0,-3\(\$sp\)
+ ac: f7ff f85c ld \$v0,-4\(\$sp\)
+ b0: f7ff f858 ld \$v0,-8\(\$sp\)
+ b4: f7ff f850 ld \$v0,-16\(\$sp\)
+ b8: f7ff f840 ld \$v0,-32\(\$sp\)
+ bc: f7df f840 ld \$v0,-64\(\$sp\)
+ c0: f79f f840 ld \$v0,-128\(\$sp\)
+ c4: f71f f840 ld \$v0,-256\(\$sp\)
+ c8: f61f f840 ld \$v0,-512\(\$sp\)
+ cc: f41f f840 ld \$v0,-1024\(\$sp\)
+ d0: f01f f840 ld \$v0,-2048\(\$sp\)
+ d4: bb40 lwu \$v0,0\(\$v1\)
+ d6: f000 bb41 lwu \$v0,1\(\$v1\)
+ da: f000 bb42 lwu \$v0,2\(\$v1\)
+ de: f000 bb43 lwu \$v0,3\(\$v1\)
+ e2: bb41 lwu \$v0,4\(\$v1\)
+ e4: bb42 lwu \$v0,8\(\$v1\)
+ e6: bb44 lwu \$v0,16\(\$v1\)
+ e8: bb48 lwu \$v0,32\(\$v1\)
+ ea: bb50 lwu \$v0,64\(\$v1\)
+ ec: f080 bb40 lwu \$v0,128\(\$v1\)
+ f0: f100 bb40 lwu \$v0,256\(\$v1\)
+ f4: f200 bb40 lwu \$v0,512\(\$v1\)
+ f8: f400 bb40 lwu \$v0,1024\(\$v1\)
+ fc: f001 bb40 lwu \$v0,2048\(\$v1\)
+ 100: f7ff bb5f lwu \$v0,-1\(\$v1\)
+ 104: f7ff bb5e lwu \$v0,-2\(\$v1\)
+ 108: f7ff bb5d lwu \$v0,-3\(\$v1\)
+ 10c: f7ff bb5c lwu \$v0,-4\(\$v1\)
+ 110: f7ff bb58 lwu \$v0,-8\(\$v1\)
+ 114: f7ff bb50 lwu \$v0,-16\(\$v1\)
+ 118: f7ff bb40 lwu \$v0,-32\(\$v1\)
+ 11c: f7df bb40 lwu \$v0,-64\(\$v1\)
+ 120: f79f bb40 lwu \$v0,-128\(\$v1\)
+ 124: f71f bb40 lwu \$v0,-256\(\$v1\)
+ 128: f61f bb40 lwu \$v0,-512\(\$v1\)
+ 12c: f41f bb40 lwu \$v0,-1024\(\$v1\)
+ 130: f01f bb40 lwu \$v0,-2048\(\$v1\)
+ 134: 9b40 lw \$v0,0\(\$v1\)
+ 136: f000 9b41 lw \$v0,1\(\$v1\)
+ 13a: f000 9b42 lw \$v0,2\(\$v1\)
+ 13e: f000 9b43 lw \$v0,3\(\$v1\)
+ 142: 9b41 lw \$v0,4\(\$v1\)
+ 144: 9b42 lw \$v0,8\(\$v1\)
+ 146: 9b44 lw \$v0,16\(\$v1\)
+ 148: 9b48 lw \$v0,32\(\$v1\)
+ 14a: 9b50 lw \$v0,64\(\$v1\)
+ 14c: f080 9b40 lw \$v0,128\(\$v1\)
+ 150: f100 9b40 lw \$v0,256\(\$v1\)
+ 154: f200 9b40 lw \$v0,512\(\$v1\)
+ 158: f400 9b40 lw \$v0,1024\(\$v1\)
+ 15c: f001 9b40 lw \$v0,2048\(\$v1\)
+ 160: f7ff 9b5f lw \$v0,-1\(\$v1\)
+ 164: f7ff 9b5e lw \$v0,-2\(\$v1\)
+ 168: f7ff 9b5d lw \$v0,-3\(\$v1\)
+ 16c: f7ff 9b5c lw \$v0,-4\(\$v1\)
+ 170: f7ff 9b58 lw \$v0,-8\(\$v1\)
+ 174: f7ff 9b50 lw \$v0,-16\(\$v1\)
+ 178: f7ff 9b40 lw \$v0,-32\(\$v1\)
+ 17c: f7df 9b40 lw \$v0,-64\(\$v1\)
+ 180: f79f 9b40 lw \$v0,-128\(\$v1\)
+ 184: f71f 9b40 lw \$v0,-256\(\$v1\)
+ 188: f61f 9b40 lw \$v0,-512\(\$v1\)
+ 18c: f41f 9b40 lw \$v0,-1024\(\$v1\)
+ 190: f01f 9b40 lw \$v0,-2048\(\$v1\)
+ 194: f67f b20c lw \$v0,0 <data1>
+ 198: f580 b204 lw \$v0,71c <data2>
+ 19c: f6c0 b20c lw \$v0,868 <bar>
+ 1a0: f780 b210 lw \$v0,930 <quux>
+ 1a4: 9200 lw \$v0,0\(\$sp\)
+ 1a6: f000 9201 lw \$v0,1\(\$sp\)
+ 1aa: f000 9202 lw \$v0,2\(\$sp\)
+ 1ae: f000 9203 lw \$v0,3\(\$sp\)
+ 1b2: 9201 lw \$v0,4\(\$sp\)
+ 1b4: 9202 lw \$v0,8\(\$sp\)
+ 1b6: 9204 lw \$v0,16\(\$sp\)
+ 1b8: 9208 lw \$v0,32\(\$sp\)
+ 1ba: 9210 lw \$v0,64\(\$sp\)
+ 1bc: 9220 lw \$v0,128\(\$sp\)
+ 1be: 9240 lw \$v0,256\(\$sp\)
+ 1c0: 9280 lw \$v0,512\(\$sp\)
+ 1c2: f400 9200 lw \$v0,1024\(\$sp\)
+ 1c6: f001 9200 lw \$v0,2048\(\$sp\)
+ 1ca: f7ff 921f lw \$v0,-1\(\$sp\)
+ 1ce: f7ff 921e lw \$v0,-2\(\$sp\)
+ 1d2: f7ff 921d lw \$v0,-3\(\$sp\)
+ 1d6: f7ff 921c lw \$v0,-4\(\$sp\)
+ 1da: f7ff 9218 lw \$v0,-8\(\$sp\)
+ 1de: f7ff 9210 lw \$v0,-16\(\$sp\)
+ 1e2: f7ff 9200 lw \$v0,-32\(\$sp\)
+ 1e6: f7df 9200 lw \$v0,-64\(\$sp\)
+ 1ea: f79f 9200 lw \$v0,-128\(\$sp\)
+ 1ee: f71f 9200 lw \$v0,-256\(\$sp\)
+ 1f2: f61f 9200 lw \$v0,-512\(\$sp\)
+ 1f6: f41f 9200 lw \$v0,-1024\(\$sp\)
+ 1fa: f01f 9200 lw \$v0,-2048\(\$sp\)
+ 1fe: 8b40 lh \$v0,0\(\$v1\)
+ 200: f000 8b41 lh \$v0,1\(\$v1\)
+ 204: 8b41 lh \$v0,2\(\$v1\)
+ 206: f000 8b43 lh \$v0,3\(\$v1\)
+ 20a: 8b42 lh \$v0,4\(\$v1\)
+ 20c: 8b44 lh \$v0,8\(\$v1\)
+ 20e: 8b48 lh \$v0,16\(\$v1\)
+ 210: 8b50 lh \$v0,32\(\$v1\)
+ 212: f040 8b40 lh \$v0,64\(\$v1\)
+ 216: f080 8b40 lh \$v0,128\(\$v1\)
+ 21a: f100 8b40 lh \$v0,256\(\$v1\)
+ 21e: f200 8b40 lh \$v0,512\(\$v1\)
+ 222: f400 8b40 lh \$v0,1024\(\$v1\)
+ 226: f001 8b40 lh \$v0,2048\(\$v1\)
+ 22a: f7ff 8b5f lh \$v0,-1\(\$v1\)
+ 22e: f7ff 8b5e lh \$v0,-2\(\$v1\)
+ 232: f7ff 8b5d lh \$v0,-3\(\$v1\)
+ 236: f7ff 8b5c lh \$v0,-4\(\$v1\)
+ 23a: f7ff 8b58 lh \$v0,-8\(\$v1\)
+ 23e: f7ff 8b50 lh \$v0,-16\(\$v1\)
+ 242: f7ff 8b40 lh \$v0,-32\(\$v1\)
+ 246: f7df 8b40 lh \$v0,-64\(\$v1\)
+ 24a: f79f 8b40 lh \$v0,-128\(\$v1\)
+ 24e: f71f 8b40 lh \$v0,-256\(\$v1\)
+ 252: f61f 8b40 lh \$v0,-512\(\$v1\)
+ 256: f41f 8b40 lh \$v0,-1024\(\$v1\)
+ 25a: f01f 8b40 lh \$v0,-2048\(\$v1\)
+ 25e: ab40 lhu \$v0,0\(\$v1\)
+ 260: f000 ab41 lhu \$v0,1\(\$v1\)
+ 264: ab41 lhu \$v0,2\(\$v1\)
+ 266: f000 ab43 lhu \$v0,3\(\$v1\)
+ 26a: ab42 lhu \$v0,4\(\$v1\)
+ 26c: ab44 lhu \$v0,8\(\$v1\)
+ 26e: ab48 lhu \$v0,16\(\$v1\)
+ 270: ab50 lhu \$v0,32\(\$v1\)
+ 272: f040 ab40 lhu \$v0,64\(\$v1\)
+ 276: f080 ab40 lhu \$v0,128\(\$v1\)
+ 27a: f100 ab40 lhu \$v0,256\(\$v1\)
+ 27e: f200 ab40 lhu \$v0,512\(\$v1\)
+ 282: f400 ab40 lhu \$v0,1024\(\$v1\)
+ 286: f001 ab40 lhu \$v0,2048\(\$v1\)
+ 28a: f7ff ab5f lhu \$v0,-1\(\$v1\)
+ 28e: f7ff ab5e lhu \$v0,-2\(\$v1\)
+ 292: f7ff ab5d lhu \$v0,-3\(\$v1\)
+ 296: f7ff ab5c lhu \$v0,-4\(\$v1\)
+ 29a: f7ff ab58 lhu \$v0,-8\(\$v1\)
+ 29e: f7ff ab50 lhu \$v0,-16\(\$v1\)
+ 2a2: f7ff ab40 lhu \$v0,-32\(\$v1\)
+ 2a6: f7df ab40 lhu \$v0,-64\(\$v1\)
+ 2aa: f79f ab40 lhu \$v0,-128\(\$v1\)
+ 2ae: f71f ab40 lhu \$v0,-256\(\$v1\)
+ 2b2: f61f ab40 lhu \$v0,-512\(\$v1\)
+ 2b6: f41f ab40 lhu \$v0,-1024\(\$v1\)
+ 2ba: f01f ab40 lhu \$v0,-2048\(\$v1\)
+ 2be: 8340 lb \$v0,0\(\$v1\)
+ 2c0: 8341 lb \$v0,1\(\$v1\)
+ 2c2: 8342 lb \$v0,2\(\$v1\)
+ 2c4: 8343 lb \$v0,3\(\$v1\)
+ 2c6: 8344 lb \$v0,4\(\$v1\)
+ 2c8: 8348 lb \$v0,8\(\$v1\)
+ 2ca: 8350 lb \$v0,16\(\$v1\)
+ 2cc: f020 8340 lb \$v0,32\(\$v1\)
+ 2d0: f040 8340 lb \$v0,64\(\$v1\)
+ 2d4: f080 8340 lb \$v0,128\(\$v1\)
+ 2d8: f100 8340 lb \$v0,256\(\$v1\)
+ 2dc: f200 8340 lb \$v0,512\(\$v1\)
+ 2e0: f400 8340 lb \$v0,1024\(\$v1\)
+ 2e4: f001 8340 lb \$v0,2048\(\$v1\)
+ 2e8: f7ff 835f lb \$v0,-1\(\$v1\)
+ 2ec: f7ff 835e lb \$v0,-2\(\$v1\)
+ 2f0: f7ff 835d lb \$v0,-3\(\$v1\)
+ 2f4: f7ff 835c lb \$v0,-4\(\$v1\)
+ 2f8: f7ff 8358 lb \$v0,-8\(\$v1\)
+ 2fc: f7ff 8350 lb \$v0,-16\(\$v1\)
+ 300: f7ff 8340 lb \$v0,-32\(\$v1\)
+ 304: f7df 8340 lb \$v0,-64\(\$v1\)
+ 308: f79f 8340 lb \$v0,-128\(\$v1\)
+ 30c: f71f 8340 lb \$v0,-256\(\$v1\)
+ 310: f61f 8340 lb \$v0,-512\(\$v1\)
+ 314: f41f 8340 lb \$v0,-1024\(\$v1\)
+ 318: f01f 8340 lb \$v0,-2048\(\$v1\)
+ 31c: a340 lbu \$v0,0\(\$v1\)
+ 31e: a341 lbu \$v0,1\(\$v1\)
+ 320: a342 lbu \$v0,2\(\$v1\)
+ 322: a343 lbu \$v0,3\(\$v1\)
+ 324: a344 lbu \$v0,4\(\$v1\)
+ 326: a348 lbu \$v0,8\(\$v1\)
+ 328: a350 lbu \$v0,16\(\$v1\)
+ 32a: f020 a340 lbu \$v0,32\(\$v1\)
+ 32e: f040 a340 lbu \$v0,64\(\$v1\)
+ 332: f080 a340 lbu \$v0,128\(\$v1\)
+ 336: f100 a340 lbu \$v0,256\(\$v1\)
+ 33a: f200 a340 lbu \$v0,512\(\$v1\)
+ 33e: f400 a340 lbu \$v0,1024\(\$v1\)
+ 342: f001 a340 lbu \$v0,2048\(\$v1\)
+ 346: f7ff a35f lbu \$v0,-1\(\$v1\)
+ 34a: f7ff a35e lbu \$v0,-2\(\$v1\)
+ 34e: f7ff a35d lbu \$v0,-3\(\$v1\)
+ 352: f7ff a35c lbu \$v0,-4\(\$v1\)
+ 356: f7ff a358 lbu \$v0,-8\(\$v1\)
+ 35a: f7ff a350 lbu \$v0,-16\(\$v1\)
+ 35e: f7ff a340 lbu \$v0,-32\(\$v1\)
+ 362: f7df a340 lbu \$v0,-64\(\$v1\)
+ 366: f79f a340 lbu \$v0,-128\(\$v1\)
+ 36a: f71f a340 lbu \$v0,-256\(\$v1\)
+ 36e: f61f a340 lbu \$v0,-512\(\$v1\)
+ 372: f41f a340 lbu \$v0,-1024\(\$v1\)
+ 376: f01f a340 lbu \$v0,-2048\(\$v1\)
+ 37a: 7b40 sd \$v0,0\(\$v1\)
+ 37c: f000 7b41 sd \$v0,1\(\$v1\)
+ 380: f000 7b42 sd \$v0,2\(\$v1\)
+ 384: f000 7b43 sd \$v0,3\(\$v1\)
+ 388: f000 7b44 sd \$v0,4\(\$v1\)
+ 38c: 7b41 sd \$v0,8\(\$v1\)
+ 38e: 7b42 sd \$v0,16\(\$v1\)
+ 390: 7b44 sd \$v0,32\(\$v1\)
+ 392: 7b48 sd \$v0,64\(\$v1\)
+ 394: 7b50 sd \$v0,128\(\$v1\)
+ 396: f100 7b40 sd \$v0,256\(\$v1\)
+ 39a: f200 7b40 sd \$v0,512\(\$v1\)
+ 39e: f400 7b40 sd \$v0,1024\(\$v1\)
+ 3a2: f001 7b40 sd \$v0,2048\(\$v1\)
+ 3a6: f7ff 7b5f sd \$v0,-1\(\$v1\)
+ 3aa: f7ff 7b5e sd \$v0,-2\(\$v1\)
+ 3ae: f7ff 7b5d sd \$v0,-3\(\$v1\)
+ 3b2: f7ff 7b5c sd \$v0,-4\(\$v1\)
+ 3b6: f7ff 7b58 sd \$v0,-8\(\$v1\)
+ 3ba: f7ff 7b50 sd \$v0,-16\(\$v1\)
+ 3be: f7ff 7b40 sd \$v0,-32\(\$v1\)
+ 3c2: f7df 7b40 sd \$v0,-64\(\$v1\)
+ 3c6: f79f 7b40 sd \$v0,-128\(\$v1\)
+ 3ca: f71f 7b40 sd \$v0,-256\(\$v1\)
+ 3ce: f61f 7b40 sd \$v0,-512\(\$v1\)
+ 3d2: f41f 7b40 sd \$v0,-1024\(\$v1\)
+ 3d6: f01f 7b40 sd \$v0,-2048\(\$v1\)
+ 3da: f940 sd \$v0,0\(\$sp\)
+ 3dc: f000 f941 sd \$v0,1\(\$sp\)
+ 3e0: f000 f942 sd \$v0,2\(\$sp\)
+ 3e4: f000 f943 sd \$v0,3\(\$sp\)
+ 3e8: f000 f944 sd \$v0,4\(\$sp\)
+ 3ec: f941 sd \$v0,8\(\$sp\)
+ 3ee: f942 sd \$v0,16\(\$sp\)
+ 3f0: f944 sd \$v0,32\(\$sp\)
+ 3f2: f948 sd \$v0,64\(\$sp\)
+ 3f4: f950 sd \$v0,128\(\$sp\)
+ 3f6: f100 f940 sd \$v0,256\(\$sp\)
+ 3fa: f200 f940 sd \$v0,512\(\$sp\)
+ 3fe: f400 f940 sd \$v0,1024\(\$sp\)
+ 402: f001 f940 sd \$v0,2048\(\$sp\)
+ 406: f7ff f95f sd \$v0,-1\(\$sp\)
+ 40a: f7ff f95e sd \$v0,-2\(\$sp\)
+ 40e: f7ff f95d sd \$v0,-3\(\$sp\)
+ 412: f7ff f95c sd \$v0,-4\(\$sp\)
+ 416: f7ff f958 sd \$v0,-8\(\$sp\)
+ 41a: f7ff f950 sd \$v0,-16\(\$sp\)
+ 41e: f7ff f940 sd \$v0,-32\(\$sp\)
+ 422: f7df f940 sd \$v0,-64\(\$sp\)
+ 426: f79f f940 sd \$v0,-128\(\$sp\)
+ 42a: f71f f940 sd \$v0,-256\(\$sp\)
+ 42e: f61f f940 sd \$v0,-512\(\$sp\)
+ 432: f41f f940 sd \$v0,-1024\(\$sp\)
+ 436: f01f f940 sd \$v0,-2048\(\$sp\)
+ 43a: fa00 sd \$ra,0\(\$sp\)
+ 43c: f000 fa01 sd \$ra,1\(\$sp\)
+ 440: f000 fa02 sd \$ra,2\(\$sp\)
+ 444: f000 fa03 sd \$ra,3\(\$sp\)
+ 448: f000 fa04 sd \$ra,4\(\$sp\)
+ 44c: fa01 sd \$ra,8\(\$sp\)
+ 44e: fa02 sd \$ra,16\(\$sp\)
+ 450: fa04 sd \$ra,32\(\$sp\)
+ 452: fa08 sd \$ra,64\(\$sp\)
+ 454: fa10 sd \$ra,128\(\$sp\)
+ 456: fa20 sd \$ra,256\(\$sp\)
+ 458: fa40 sd \$ra,512\(\$sp\)
+ 45a: fa80 sd \$ra,1024\(\$sp\)
+ 45c: f001 fa00 sd \$ra,2048\(\$sp\)
+ 460: f7ff fa1f sd \$ra,-1\(\$sp\)
+ 464: f7ff fa1e sd \$ra,-2\(\$sp\)
+ 468: f7ff fa1d sd \$ra,-3\(\$sp\)
+ 46c: f7ff fa1c sd \$ra,-4\(\$sp\)
+ 470: f7ff fa18 sd \$ra,-8\(\$sp\)
+ 474: f7ff fa10 sd \$ra,-16\(\$sp\)
+ 478: f7ff fa00 sd \$ra,-32\(\$sp\)
+ 47c: f7df fa00 sd \$ra,-64\(\$sp\)
+ 480: f79f fa00 sd \$ra,-128\(\$sp\)
+ 484: f71f fa00 sd \$ra,-256\(\$sp\)
+ 488: f61f fa00 sd \$ra,-512\(\$sp\)
+ 48c: f41f fa00 sd \$ra,-1024\(\$sp\)
+ 490: f01f fa00 sd \$ra,-2048\(\$sp\)
+ 494: db40 sw \$v0,0\(\$v1\)
+ 496: f000 db41 sw \$v0,1\(\$v1\)
+ 49a: f000 db42 sw \$v0,2\(\$v1\)
+ 49e: f000 db43 sw \$v0,3\(\$v1\)
+ 4a2: db41 sw \$v0,4\(\$v1\)
+ 4a4: db42 sw \$v0,8\(\$v1\)
+ 4a6: db44 sw \$v0,16\(\$v1\)
+ 4a8: db48 sw \$v0,32\(\$v1\)
+ 4aa: db50 sw \$v0,64\(\$v1\)
+ 4ac: f080 db40 sw \$v0,128\(\$v1\)
+ 4b0: f100 db40 sw \$v0,256\(\$v1\)
+ 4b4: f200 db40 sw \$v0,512\(\$v1\)
+ 4b8: f400 db40 sw \$v0,1024\(\$v1\)
+ 4bc: f001 db40 sw \$v0,2048\(\$v1\)
+ 4c0: f7ff db5f sw \$v0,-1\(\$v1\)
+ 4c4: f7ff db5e sw \$v0,-2\(\$v1\)
+ 4c8: f7ff db5d sw \$v0,-3\(\$v1\)
+ 4cc: f7ff db5c sw \$v0,-4\(\$v1\)
+ 4d0: f7ff db58 sw \$v0,-8\(\$v1\)
+ 4d4: f7ff db50 sw \$v0,-16\(\$v1\)
+ 4d8: f7ff db40 sw \$v0,-32\(\$v1\)
+ 4dc: f7df db40 sw \$v0,-64\(\$v1\)
+ 4e0: f79f db40 sw \$v0,-128\(\$v1\)
+ 4e4: f71f db40 sw \$v0,-256\(\$v1\)
+ 4e8: f61f db40 sw \$v0,-512\(\$v1\)
+ 4ec: f41f db40 sw \$v0,-1024\(\$v1\)
+ 4f0: f01f db40 sw \$v0,-2048\(\$v1\)
+ 4f4: d200 sw \$v0,0\(\$sp\)
+ 4f6: f000 d201 sw \$v0,1\(\$sp\)
+ 4fa: f000 d202 sw \$v0,2\(\$sp\)
+ 4fe: f000 d203 sw \$v0,3\(\$sp\)
+ 502: d201 sw \$v0,4\(\$sp\)
+ 504: d202 sw \$v0,8\(\$sp\)
+ 506: d204 sw \$v0,16\(\$sp\)
+ 508: d208 sw \$v0,32\(\$sp\)
+ 50a: d210 sw \$v0,64\(\$sp\)
+ 50c: d220 sw \$v0,128\(\$sp\)
+ 50e: d240 sw \$v0,256\(\$sp\)
+ 510: d280 sw \$v0,512\(\$sp\)
+ 512: f400 d200 sw \$v0,1024\(\$sp\)
+ 516: f001 d200 sw \$v0,2048\(\$sp\)
+ 51a: f7ff d21f sw \$v0,-1\(\$sp\)
+ 51e: f7ff d21e sw \$v0,-2\(\$sp\)
+ 522: f7ff d21d sw \$v0,-3\(\$sp\)
+ 526: f7ff d21c sw \$v0,-4\(\$sp\)
+ 52a: f7ff d218 sw \$v0,-8\(\$sp\)
+ 52e: f7ff d210 sw \$v0,-16\(\$sp\)
+ 532: f7ff d200 sw \$v0,-32\(\$sp\)
+ 536: f7df d200 sw \$v0,-64\(\$sp\)
+ 53a: f79f d200 sw \$v0,-128\(\$sp\)
+ 53e: f71f d200 sw \$v0,-256\(\$sp\)
+ 542: f61f d200 sw \$v0,-512\(\$sp\)
+ 546: f41f d200 sw \$v0,-1024\(\$sp\)
+ 54a: f01f d200 sw \$v0,-2048\(\$sp\)
+ 54e: 6200 sw \$ra,0\(\$sp\)
+ 550: f000 6201 sw \$ra,1\(\$sp\)
+ 554: f000 6202 sw \$ra,2\(\$sp\)
+ 558: f000 6203 sw \$ra,3\(\$sp\)
+ 55c: 6201 sw \$ra,4\(\$sp\)
+ 55e: 6202 sw \$ra,8\(\$sp\)
+ 560: 6204 sw \$ra,16\(\$sp\)
+ 562: 6208 sw \$ra,32\(\$sp\)
+ 564: 6210 sw \$ra,64\(\$sp\)
+ 566: 6220 sw \$ra,128\(\$sp\)
+ 568: 6240 sw \$ra,256\(\$sp\)
+ 56a: 6280 sw \$ra,512\(\$sp\)
+ 56c: f400 6200 sw \$ra,1024\(\$sp\)
+ 570: f001 6200 sw \$ra,2048\(\$sp\)
+ 574: f7ff 621f sw \$ra,-1\(\$sp\)
+ 578: f7ff 621e sw \$ra,-2\(\$sp\)
+ 57c: f7ff 621d sw \$ra,-3\(\$sp\)
+ 580: f7ff 621c sw \$ra,-4\(\$sp\)
+ 584: f7ff 6218 sw \$ra,-8\(\$sp\)
+ 588: f7ff 6210 sw \$ra,-16\(\$sp\)
+ 58c: f7ff 6200 sw \$ra,-32\(\$sp\)
+ 590: f7df 6200 sw \$ra,-64\(\$sp\)
+ 594: f79f 6200 sw \$ra,-128\(\$sp\)
+ 598: f71f 6200 sw \$ra,-256\(\$sp\)
+ 59c: f61f 6200 sw \$ra,-512\(\$sp\)
+ 5a0: f41f 6200 sw \$ra,-1024\(\$sp\)
+ 5a4: f01f 6200 sw \$ra,-2048\(\$sp\)
+ 5a8: cb40 sh \$v0,0\(\$v1\)
+ 5aa: f000 cb41 sh \$v0,1\(\$v1\)
+ 5ae: cb41 sh \$v0,2\(\$v1\)
+ 5b0: f000 cb43 sh \$v0,3\(\$v1\)
+ 5b4: cb42 sh \$v0,4\(\$v1\)
+ 5b6: cb44 sh \$v0,8\(\$v1\)
+ 5b8: cb48 sh \$v0,16\(\$v1\)
+ 5ba: cb50 sh \$v0,32\(\$v1\)
+ 5bc: f040 cb40 sh \$v0,64\(\$v1\)
+ 5c0: f080 cb40 sh \$v0,128\(\$v1\)
+ 5c4: f100 cb40 sh \$v0,256\(\$v1\)
+ 5c8: f200 cb40 sh \$v0,512\(\$v1\)
+ 5cc: f400 cb40 sh \$v0,1024\(\$v1\)
+ 5d0: f001 cb40 sh \$v0,2048\(\$v1\)
+ 5d4: f7ff cb5f sh \$v0,-1\(\$v1\)
+ 5d8: f7ff cb5e sh \$v0,-2\(\$v1\)
+ 5dc: f7ff cb5d sh \$v0,-3\(\$v1\)
+ 5e0: f7ff cb5c sh \$v0,-4\(\$v1\)
+ 5e4: f7ff cb58 sh \$v0,-8\(\$v1\)
+ 5e8: f7ff cb50 sh \$v0,-16\(\$v1\)
+ 5ec: f7ff cb40 sh \$v0,-32\(\$v1\)
+ 5f0: f7df cb40 sh \$v0,-64\(\$v1\)
+ 5f4: f79f cb40 sh \$v0,-128\(\$v1\)
+ 5f8: f71f cb40 sh \$v0,-256\(\$v1\)
+ 5fc: f61f cb40 sh \$v0,-512\(\$v1\)
+ 600: f41f cb40 sh \$v0,-1024\(\$v1\)
+ 604: f01f cb40 sh \$v0,-2048\(\$v1\)
+ 608: c340 sb \$v0,0\(\$v1\)
+ 60a: c341 sb \$v0,1\(\$v1\)
+ 60c: c342 sb \$v0,2\(\$v1\)
+ 60e: c343 sb \$v0,3\(\$v1\)
+ 610: c344 sb \$v0,4\(\$v1\)
+ 612: c348 sb \$v0,8\(\$v1\)
+ 614: c350 sb \$v0,16\(\$v1\)
+ 616: f020 c340 sb \$v0,32\(\$v1\)
+ 61a: f040 c340 sb \$v0,64\(\$v1\)
+ 61e: f080 c340 sb \$v0,128\(\$v1\)
+ 622: f100 c340 sb \$v0,256\(\$v1\)
+ 626: f200 c340 sb \$v0,512\(\$v1\)
+ 62a: f400 c340 sb \$v0,1024\(\$v1\)
+ 62e: f001 c340 sb \$v0,2048\(\$v1\)
+ 632: f7ff c35f sb \$v0,-1\(\$v1\)
+ 636: f7ff c35e sb \$v0,-2\(\$v1\)
+ 63a: f7ff c35d sb \$v0,-3\(\$v1\)
+ 63e: f7ff c35c sb \$v0,-4\(\$v1\)
+ 642: f7ff c358 sb \$v0,-8\(\$v1\)
+ 646: f7ff c350 sb \$v0,-16\(\$v1\)
+ 64a: f7ff c340 sb \$v0,-32\(\$v1\)
+ 64e: f7df c340 sb \$v0,-64\(\$v1\)
+ 652: f79f c340 sb \$v0,-128\(\$v1\)
+ 656: f71f c340 sb \$v0,-256\(\$v1\)
+ 65a: f61f c340 sb \$v0,-512\(\$v1\)
+ 65e: f41f c340 sb \$v0,-1024\(\$v1\)
+ 662: f01f c340 sb \$v0,-2048\(\$v1\)
+ 666: 6a00 li \$v0,0
+ 668: 6a01 li \$v0,1
+ 66a: f100 6a00 li \$v0,256
+ 66e: 675e move \$v0,\$s8
+ 670: 6592 move \$s4,\$v0
+ 672: 4350 daddiu \$v0,\$v1,0
+ 674: 4351 daddiu \$v0,\$v1,1
+ 676: 435f daddiu \$v0,\$v1,-1
+ 678: f010 4350 daddiu \$v0,\$v1,16
+ 67c: f7ff 4350 daddiu \$v0,\$v1,-16
+ 680: e388 daddu \$v0,\$v1,\$a0
+ 682: fd40 daddiu \$v0,0
+ 684: fd41 daddiu \$v0,1
+ 686: fd5f daddiu \$v0,-1
+ 688: f020 fd40 daddiu \$v0,32
+ 68c: f7ff fd40 daddiu \$v0,-32
+ 690: f080 fd40 daddiu \$v0,128
+ 694: f79f fd40 daddiu \$v0,-128
+ 698: f17f fe48 dla \$v0,0 <data1>
+ 69c: f080 fe40 dla \$v0,71c <data2>
+ 6a0: f1c0 fe48 dla \$v0,868 <bar>
+ 6a4: f280 fe4c dla \$v0,930 <quux>
+ 6a8: fb00 daddiu \$sp,0
+ 6aa: f000 fb01 daddiu \$sp,1
+ 6ae: f7ff fb1f daddiu \$sp,-1
+ 6b2: fb20 daddiu \$sp,256
+ 6b4: fbe0 daddiu \$sp,-256
+ 6b6: ff40 daddiu \$v0,\$sp,0
+ 6b8: f000 ff41 daddiu \$v0,\$sp,1
+ 6bc: f7ff ff5f daddiu \$v0,\$sp,-1
+ 6c0: ff48 daddiu \$v0,\$sp,32
+ 6c2: f7ff ff40 daddiu \$v0,\$sp,-32
+ 6c6: f080 ff40 daddiu \$v0,\$sp,128
+ 6ca: f79f ff40 daddiu \$v0,\$sp,-128
+ 6ce: 4340 addiu \$v0,\$v1,0
+ 6d0: 4341 addiu \$v0,\$v1,1
+ 6d2: 434f addiu \$v0,\$v1,-1
+ 6d4: f010 4340 addiu \$v0,\$v1,16
+ 6d8: f7ff 4340 addiu \$v0,\$v1,-16
+ 6dc: e389 addu \$v0,\$v1,\$a0
+ 6de: 4a00 addiu \$v0,0
+ 6e0: 4a01 addiu \$v0,1
+ 6e2: 4aff addiu \$v0,-1
+ 6e4: 4a20 addiu \$v0,32
+ 6e6: 4ae0 addiu \$v0,-32
+ 6e8: f080 4a00 addiu \$v0,128
+ 6ec: 4a80 addiu \$v0,-128
+ 6ee: f11f 0a14 la \$v0,0 <data1>
+ 6f2: 0a0b la \$v0,71c <data2>
+ 6f4: 0a5d la \$v0,868 <bar>
+ 6f6: 0a8f la \$v0,930 <quux>
+ 6f8: 6300 addiu \$sp,0
+ 6fa: f000 6301 addiu \$sp,1
+ 6fe: f7ff 631f addiu \$sp,-1
+ 702: 6320 addiu \$sp,256
+ 704: 63e0 addiu \$sp,-256
+ 706: 0200 addiu \$v0,\$sp,0
+ 708: f000 0201 addiu \$v0,\$sp,1
+ 70c: f7ff 021f addiu \$v0,\$sp,-1
+ 710: 0208 addiu \$v0,\$sp,32
+ 712: f7ff 0200 addiu \$v0,\$sp,-32
+ 716: 0220 addiu \$v0,\$sp,128
+ 718: f79f 0200 addiu \$v0,\$sp,-128
+
+0+00071c <data2>:
+ 71c: 00000000 nop
+
+0+000720 <insns2>:
+ 720: e38a dsubu \$v0,\$v1,\$a0
+ 722: e38b subu \$v0,\$v1,\$a0
+ 724: ea6b neg \$v0,\$v1
+ 726: ea6c and \$v0,\$v1
+ 728: ea6d or \$v0,\$v1
+ 72a: ea6e xor \$v0,\$v1
+ 72c: ea6f not \$v0,\$v1
+ 72e: 5200 slti \$v0,0
+ 730: 5201 slti \$v0,1
+ 732: f7ff 521f slti \$v0,-1
+ 736: 52ff slti \$v0,255
+ 738: f100 5200 slti \$v0,256
+ 73c: ea62 slt \$v0,\$v1
+ 73e: 5a00 sltiu \$v0,0
+ 740: 5a01 sltiu \$v0,1
+ 742: f7ff 5a1f sltiu \$v0,-1
+ 746: 5aff sltiu \$v0,255
+ 748: f100 5a00 sltiu \$v0,256
+ 74c: ea63 sltu \$v0,\$v1
+ 74e: 7200 cmpi \$v0,0
+ 750: 7201 cmpi \$v0,1
+ 752: 72ff cmpi \$v0,255
+ 754: f100 7200 cmpi \$v0,256
+ 758: ea6a cmp \$v0,\$v1
+ 75a: f000 3261 dsll \$v0,\$v1,0
+ 75e: 3265 dsll \$v0,\$v1,1
+ 760: 3261 dsll \$v0,\$v1,8
+ 762: f240 3261 dsll \$v0,\$v1,9
+ 766: f7e0 3261 dsll \$v0,\$v1,63
+ 76a: eb54 dsllv \$v0,\$v1
+ 76c: f000 e848 dsrl \$v0,0
+ 770: e948 dsrl \$v0,1
+ 772: e848 dsrl \$v0,8
+ 774: f240 e848 dsrl \$v0,9
+ 778: f7e0 e848 dsrl \$v0,63
+ 77c: eb56 dsrlv \$v0,\$v1
+ 77e: f000 e853 dsra \$v0,0
+ 782: e953 dsra \$v0,1
+ 784: e853 dsra \$v0,8
+ 786: f240 e853 dsra \$v0,9
+ 78a: f7e0 e853 dsra \$v0,63
+ 78e: eb57 dsrav \$v0,\$v1
+ 790: ea12 mflo \$v0
+ 792: eb10 mfhi \$v1
+ 794: f000 3260 sll \$v0,\$v1,0
+ 798: 3264 sll \$v0,\$v1,1
+ 79a: 3260 sll \$v0,\$v1,8
+ 79c: f240 3260 sll \$v0,\$v1,9
+ 7a0: f7c0 3260 sll \$v0,\$v1,31
+ 7a4: eb44 sllv \$v0,\$v1
+ 7a6: f000 3262 srl \$v0,\$v1,0
+ 7aa: 3266 srl \$v0,\$v1,1
+ 7ac: 3262 srl \$v0,\$v1,8
+ 7ae: f240 3262 srl \$v0,\$v1,9
+ 7b2: f7c0 3262 srl \$v0,\$v1,31
+ 7b6: eb46 srlv \$v0,\$v1
+ 7b8: f000 3263 sra \$v0,\$v1,0
+ 7bc: 3267 sra \$v0,\$v1,1
+ 7be: 3263 sra \$v0,\$v1,8
+ 7c0: f240 3263 sra \$v0,\$v1,9
+ 7c4: f7c0 3263 sra \$v0,\$v1,31
+ 7c8: eb47 srav \$v0,\$v1
+ 7ca: ea7c dmult \$v0,\$v1
+ 7cc: ea7d dmultu \$v0,\$v1
+ 7ce: ea7e ddiv \$zero,\$v0,\$v1
+ 7d0: 2b01 bnez \$v1,7d4 <insns2\+(0x|)b4>
+ 7d2: e8e5 break 7
+ 7d4: ea12 mflo \$v0
+ 7d6: 6500 nop
+ 7d8: 6500 nop
+ 7da: ea7f ddivu \$zero,\$v0,\$v1
+ 7dc: 2b01 bnez \$v1,7e0 <insns2\+(0x|)c0>
+ 7de: e8e5 break 7
+ 7e0: ea12 mflo \$v0
+ 7e2: 6500 nop
+ 7e4: 6500 nop
+ 7e6: ea78 mult \$v0,\$v1
+ 7e8: ea79 multu \$v0,\$v1
+ 7ea: ea7a div \$zero,\$v0,\$v1
+ 7ec: 2b01 bnez \$v1,7f0 <insns2\+(0x|)d0>
+ 7ee: e8e5 break 7
+ 7f0: ea12 mflo \$v0
+ 7f2: 6500 nop
+ 7f4: 6500 nop
+ 7f6: ea7b divu \$zero,\$v0,\$v1
+ 7f8: 2b01 bnez \$v1,7fc <insns2\+(0x|)dc>
+ 7fa: e8e5 break 7
+ 7fc: ea12 mflo \$v0
+ 7fe: ea00 jr \$v0
+ 800: 6500 nop
+ 802: e820 jr \$ra
+ 804: 6500 nop
+ 806: ea40 jalr \$v0
+ 808: 6500 nop
+ 80a: f3ff 221b beqz \$v0,4 <insns1>
+ 80e: 2288 beqz \$v0,720 <insns2>
+ 810: 222b beqz \$v0,868 <bar>
+ 812: f080 220d beqz \$v0,930 <quux>
+ 816: f3ff 2a15 bnez \$v0,4 <insns1>
+ 81a: 2a82 bnez \$v0,720 <insns2>
+ 81c: 2a25 bnez \$v0,868 <bar>
+ 81e: f080 2a07 bnez \$v0,930 <quux>
+ 822: f3ff 600f bteqz 4 <insns1>
+ 826: f77f 601b bteqz 720 <insns2>
+ 82a: 601e bteqz 868 <bar>
+ 82c: f080 6000 bteqz 930 <quux>
+ 830: f3ff 6108 btnez 4 <insns1>
+ 834: f77f 6114 btnez 720 <insns2>
+ 838: 6117 btnez 868 <bar>
+ 83a: 617a btnez 930 <quux>
+ 83c: f3ff 1002 b 4 <insns1>
+ 840: 176f b 720 <insns2>
+ 842: 1012 b 868 <bar>
+ 844: 1075 b 930 <quux>
+ 846: e805 break 0
+ 848: e825 break 1
+ 84a: efe5 break 63
+ 84c: 1800 0000 jal 0 <data1>
+ 84c: R_MIPS16_26 extern
+ 850: 6500 nop
+ 852: e809 entry
+ 854: e909 entry \$a0
+ 856: eb49 entry \$a0-\$a2,\$s0
+ 858: e8a9 entry \$s0-\$s1,\$ra
+ 85a: e829 entry \$ra
+ 85c: ef09 exit
+ 85e: ef49 exit \$s0
+ 860: efa9 exit \$s0-\$s1,\$ra
+ 862: ef29 exit \$ra
+ 864: 0000 addiu \$s0,\$sp,0
+ ...
+
+0+000868 <bar>:
+ ...
diff --git a/gas/testsuite/gas/mips/mips16.s b/gas/testsuite/gas/mips/mips16.s
new file mode 100644
index 00000000000..6268fb16506
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips16.s
@@ -0,0 +1,258 @@
+# Test the mips16 instruction set.
+
+ .set mips16
+
+ .macro ldst op, reg, base
+ \op \reg,0(\base)
+ \op \reg,1(\base)
+ \op \reg,2(\base)
+ \op \reg,3(\base)
+ \op \reg,4(\base)
+ \op \reg,8(\base)
+ \op \reg,16(\base)
+ \op \reg,32(\base)
+ \op \reg,64(\base)
+ \op \reg,128(\base)
+ \op \reg,256(\base)
+ \op \reg,512(\base)
+ \op \reg,1024(\base)
+ \op \reg,2048(\base)
+ \op \reg,-1(\base)
+ \op \reg,-2(\base)
+ \op \reg,-3(\base)
+ \op \reg,-4(\base)
+ \op \reg,-8(\base)
+ \op \reg,-16(\base)
+ \op \reg,-32(\base)
+ \op \reg,-64(\base)
+ \op \reg,-128(\base)
+ \op \reg,-256(\base)
+ \op \reg,-512(\base)
+ \op \reg,-1024(\base)
+ \op \reg,-2048(\base)
+ .endm
+
+ .p2align 3
+data1:
+ .word 0
+insns1:
+ ldst ld, $2, $3
+ ld $2,data1
+ ld $2,data2
+ ld $2,bar
+ ld $2,quux
+ ldst ld, $2, $sp
+ ldst lwu, $2, $3
+ ldst lw, $2, $3
+ lw $2,data1
+ lw $2,data2
+ lw $2,bar
+ lw $2,quux
+ ldst lw, $2, $sp
+ ldst lh, $2, $3
+ ldst lhu, $2, $3
+ ldst lb, $2, $3
+ ldst lbu, $2, $3
+ ldst sd, $2, $3
+ ldst sd, $2, $sp
+ ldst sd, $31, $sp
+ ldst sw, $2, $3
+ ldst sw, $2, $sp
+ ldst sw, $31, $sp
+ ldst sh, $2, $3
+ ldst sb, $2, $3
+
+ li $2,0
+ li $2,1
+ li $2,256
+
+ move $2,$30
+ move $20,$2
+
+ daddu $2,$3,0
+ daddu $2,$3,1
+ daddu $2,$3,-1
+ daddu $2,$3,16
+ daddu $2,$3,-16
+ daddu $2,$3,$4
+ daddu $2,0
+ daddu $2,1
+ daddu $2,-1
+ daddu $2,32
+ daddu $2,-32
+ daddu $2,128
+ daddu $2,-128
+ dla $2,data1
+ dla $2,data2
+ dla $2,bar
+ dla $2,quux
+ daddu $sp,0
+ daddu $sp,1
+ daddu $sp,-1
+ daddu $sp,256
+ daddu $sp,-256
+ daddu $2,$sp,0
+ daddu $2,$sp,1
+ daddu $2,$sp,-1
+ daddu $2,$sp,32
+ daddu $2,$sp,-32
+ daddu $2,$sp,128
+ daddu $2,$sp,-128
+
+ addu $2,$3,0
+ addu $2,$3,1
+ addu $2,$3,-1
+ addu $2,$3,16
+ addu $2,$3,-16
+ addu $2,$3,$4
+ addu $2,0
+ addu $2,1
+ addu $2,-1
+ addu $2,32
+ addu $2,-32
+ addu $2,128
+ addu $2,-128
+ la $2,data1
+ la $2,data2
+ la $2,bar
+ la $2,quux
+ addu $sp,0
+ addu $sp,1
+ addu $sp,-1
+ addu $sp,256
+ addu $sp,-256
+ addu $2,$sp,0
+ addu $2,$sp,1
+ addu $2,$sp,-1
+ addu $2,$sp,32
+ addu $2,$sp,-32
+ addu $2,$sp,128
+ addu $2,$sp,-128
+
+data2:
+ .word 0
+insns2:
+ dsubu $2,$3,$4
+ subu $2,$3,$4
+ neg $2,$3
+
+ and $2,$3
+ or $2,$3
+ xor $2,$3
+ not $2,$3
+
+ slt $2,0
+ slt $2,1
+ slt $2,-1
+ slt $2,255
+ slt $2,256
+ slt $2,$3
+ sltu $2,0
+ sltu $2,1
+ sltu $2,-1
+ sltu $2,255
+ sltu $2,256
+ sltu $2,$3
+ cmp $2,0
+ cmp $2,1
+ cmp $2,255
+ cmp $2,256
+ cmp $2,$3
+
+ dsll $2,$3,0
+ dsll $2,$3,1
+ dsll $2,$3,8
+ dsll $2,$3,9
+ dsll $2,$3,63
+ dsll $2,$3
+ dsrl $2,0
+ dsrl $2,1
+ dsrl $2,8
+ dsrl $2,9
+ dsrl $2,63
+ dsrl $2,$3
+ dsra $2,0
+ dsra $2,1
+ dsra $2,8
+ dsra $2,9
+ dsra $2,63
+ dsra $2,$3
+
+ mflo $2
+ mfhi $3
+
+ sll $2,$3,0
+ sll $2,$3,1
+ sll $2,$3,8
+ sll $2,$3,9
+ sll $2,$3,31
+ sll $2,$3
+ srl $2,$3,0
+ srl $2,$3,1
+ srl $2,$3,8
+ srl $2,$3,9
+ srl $2,$3,31
+ srl $2,$3
+ sra $2,$3,0
+ sra $2,$3,1
+ sra $2,$3,8
+ sra $2,$3,9
+ sra $2,$3,31
+ sra $2,$3
+
+ dmult $2,$3
+ dmultu $2,$3
+ ddiv $2,$3
+ ddivu $2,$3
+
+ mult $2,$3
+ multu $2,$3
+ div $2,$3
+ divu $2,$3
+
+ jr $2
+ jr $31
+ jalr $31,$2
+
+ beqz $2,insns1
+ beqz $2,insns2
+ beqz $2,bar
+ beqz $2,quux
+ bnez $2,insns1
+ bnez $2,insns2
+ bnez $2,bar
+ bnez $2,quux
+ bteqz insns1
+ bteqz insns2
+ bteqz bar
+ bteqz quux
+ btnez insns1
+ btnez insns2
+ btnez bar
+ btnez quux
+ b insns1
+ b insns2
+ b bar
+ b quux
+
+ break 0
+ break 1
+ break 63
+
+ jal extern
+
+ entry
+ entry $4
+ entry $4-$6,$16
+ entry $16-$17,$31
+ entry $31
+ exit
+ exit $16
+ exit $16-$17,$31
+ exit $31
+
+ .p2align 3
+bar:
+
+ .skip 200
+quux:
diff --git a/gas/testsuite/gas/mips/mips4.d b/gas/testsuite/gas/mips/mips4.d
new file mode 100644
index 00000000000..956de93f3da
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4.d
@@ -0,0 +1,51 @@
+#objdump: -dr --prefix-addresses -mmips:5000
+#name: MIPS mips4
+#as: -mips4 -mcpu=r5000
+
+# Test the mips4 macros.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> bc1f 00000000+ <text_label>
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> bc1f \$fcc1,00000000+ <text_label>
+0+000c <[^>]*> nop
+0+0010 <[^>]*> bc1fl \$fcc1,00000000+ <text_label>
+0+0014 <[^>]*> nop
+0+0018 <[^>]*> bc1t \$fcc1,00000000+ <text_label>
+0+001c <[^>]*> nop
+0+0020 <[^>]*> bc1tl \$fcc2,00000000+ <text_label>
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> c.f.d \$f4,\$f6
+0+002c <[^>]*> c.f.d \$fcc1,\$f4,\$f6
+0+0030 <[^>]*> ldxc1 \$f2,\$a0\(\$a1\)
+0+0034 <[^>]*> lwxc1 \$f2,\$a0\(\$a1\)
+0+0038 <[^>]*> madd.d \$f0,\$f2,\$f4,\$f6
+0+003c <[^>]*> madd.s \$f0,\$f2,\$f4,\$f6
+0+0040 <[^>]*> movf \$a0,\$a1,\$fcc4
+0+0044 <[^>]*> movf.d \$f4,\$f6,\$fcc0
+0+0048 <[^>]*> movf.s \$f4,\$f6,\$fcc0
+0+004c <[^>]*> movn \$a0,\$a2,\$a2
+0+0050 <[^>]*> movn.d \$f4,\$f5,\$a2
+0+0054 <[^>]*> movn.s \$f4,\$f5,\$a2
+0+0058 <[^>]*> movt \$a0,\$a1,\$fcc4
+0+005c <[^>]*> movt.d \$f4,\$f6,\$fcc0
+0+0060 <[^>]*> movt.s \$f4,\$f6,\$fcc0
+0+0064 <[^>]*> movz \$a0,\$a2,\$a2
+0+0068 <[^>]*> movz.d \$f4,\$f5,\$a2
+0+006c <[^>]*> movz.s \$f4,\$f5,\$a2
+0+0070 <[^>]*> msub.d \$f0,\$f2,\$f4,\$f6
+0+0074 <[^>]*> msub.s \$f0,\$f2,\$f4,\$f6
+0+0078 <[^>]*> nmadd.d \$f0,\$f2,\$f4,\$f6
+0+007c <[^>]*> nmadd.s \$f0,\$f2,\$f4,\$f6
+0+0080 <[^>]*> nmsub.d \$f0,\$f2,\$f4,\$f6
+0+0084 <[^>]*> nmsub.s \$f0,\$f2,\$f4,\$f6
+0+0088 <[^>]*> prefx 0x4,\$a0\(\$a1\)
+0+008c <[^>]*> recip.d \$f4,\$f6
+0+0090 <[^>]*> recip.s \$f4,\$f6
+0+0094 <[^>]*> rsqrt.d \$f4,\$f6
+0+0098 <[^>]*> rsqrt.s \$f4,\$f6
+0+009c <[^>]*> sdxc1 \$f4,\$a0\(\$a1\)
+0+00a0 <[^>]*> swxc1 \$f4,\$a0\(\$a1\)
+ ...
diff --git a/gas/testsuite/gas/mips/mips4.s b/gas/testsuite/gas/mips/mips4.s
new file mode 100644
index 00000000000..bf8b9433031
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4.s
@@ -0,0 +1,52 @@
+# Source file used to test -mips4 instructions.
+
+text_label:
+ bc1f text_label
+ bc1f $fcc1,text_label
+ bc1fl $fcc1,text_label
+ bc1t $fcc1,text_label
+ bc1tl $fcc2,text_label
+ c.f.d $f4,$f6
+ c.f.d $fcc1,$f4,$f6
+ ldxc1 $f2,$4($5)
+ lwxc1 $f2,$4($5)
+ madd.d $f0,$f2,$f4,$f6
+ madd.s $f0,$f2,$f4,$f6
+ movf $4,$5,$fcc4
+ movf.d $f4,$f6,$fcc0
+ movf.s $f4,$f6,$fcc0
+ movn $4,$6,$6
+ movn.d $f4,$f5,$6
+ movn.s $f4,$f5,$6
+ movt $4,$5,$fcc4
+ movt.d $f4,$f6,$fcc0
+ movt.s $f4,$f6,$fcc0
+ movz $4,$6,$6
+ movz.d $f4,$f5,$6
+ movz.s $f4,$f5,$6
+ msub.d $f0,$f2,$f4,$f6
+ msub.s $f0,$f2,$f4,$f6
+ nmadd.d $f0,$f2,$f4,$f6
+ nmadd.s $f0,$f2,$f4,$f6
+ nmsub.d $f0,$f2,$f4,$f6
+ nmsub.s $f0,$f2,$f4,$f6
+
+ # We don't test pref because currently the disassembler will
+ # disassemble it as lwc3. lwc3 is correct for mips1 to mips3,
+ # while pref is correct for mips4. Unfortunately, the
+ # disassembler does not know which architecture it is
+ # disassembling for.
+ # pref 4,0($4)
+
+ prefx 4,$4($5)
+ recip.d $f4,$f6
+ recip.s $f4,$f6
+ rsqrt.d $f4,$f6
+ rsqrt.s $f4,$f6
+ sdxc1 $f4,$4($5)
+ swxc1 $f4,$4($5)
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/mips4010.d b/gas/testsuite/gas/mips/mips4010.d
new file mode 100644
index 00000000000..77de196df89
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4010.d
@@ -0,0 +1,23 @@
+#objdump: -dr --prefix-addresses -mmips:4010
+#name: MIPS 4010
+#as: -mcpu=4010
+
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+0+0000 <stuff> flushi
+0+0004 <stuff\+0x4> flushd
+0+0008 <stuff\+0x8> flushid
+0+000c <stuff\+0xc> madd \$a0,\$a1
+0+0010 <stuff\+0x10> maddu \$a1,\$a2
+0+0014 <stuff\+0x14> ffc \$a2,\$a3
+0+0018 <stuff\+0x18> ffs \$a3,\$t0
+0+001c <stuff\+0x1c> msub \$t0,\$t1
+0+0020 <stuff\+0x20> msubu \$t1,\$t2
+0+0024 <stuff\+0x24> selsl \$t2,\$t3,\$t4
+0+0028 <stuff\+0x28> selsr \$t3,\$t4,\$t5
+0+002c <stuff\+0x2c> waiti
+0+0030 <stuff\+0x30> wb 16\(\$t6\)
+0+0034 <stuff\+0x34> addciu \$t6,\$t7,16
+ ...
diff --git a/gas/testsuite/gas/mips/mips4010.s b/gas/testsuite/gas/mips/mips4010.s
new file mode 100644
index 00000000000..e8d6e255440
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4010.s
@@ -0,0 +1,20 @@
+ .text
+
+stuff:
+ .ent stuff
+ flushi
+ flushd
+ flushid
+ madd $4,$5
+ maddu $5,$6
+ ffc $6,$7
+ ffs $7,$8
+ msub $8,$9
+ msubu $9,$10
+ selsl $10,$11,$12
+ selsr $11,$12,$13
+ waiti
+ wb 16($14)
+ addciu $14,$15,16
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/mips4100.d b/gas/testsuite/gas/mips/mips4100.d
new file mode 100644
index 00000000000..ef84f120580
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4100.d
@@ -0,0 +1,15 @@
+#objdump: -dr --prefix-addresses -mmips:4100
+#name: MIPS 4100
+#as: -mcpu=4100
+
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+0+0000 <stuff> dmadd16 \$a0,\$a1
+ ...
+0+000c <stuff\+0xc> madd16 \$a1,\$a2
+0+0010 <stuff\+0x10> hibernate
+0+0014 <stuff\+0x14> standby
+0+0018 <stuff\+0x18> suspend
+0+001c <stuff\+0x1c> nop
diff --git a/gas/testsuite/gas/mips/mips4100.s b/gas/testsuite/gas/mips/mips4100.s
new file mode 100644
index 00000000000..ca20e0e9781
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4100.s
@@ -0,0 +1,10 @@
+ .text
+
+stuff:
+ .ent stuff
+ dmadd16 $4,$5
+ madd16 $5,$6
+ hibernate
+ standby
+ suspend
+ nop
diff --git a/gas/testsuite/gas/mips/mips4650.d b/gas/testsuite/gas/mips/mips4650.d
new file mode 100644
index 00000000000..5e642a6a837
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4650.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses -mmips:4650
+#name: MIPS 4650
+#as: -mcpu=4650
+
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+0+0000 <stuff> mad \$a0,\$a1
+ ...
+0+000c <stuff\+0xc> madu \$a1,\$a2
+ ...
+0+0018 <stuff\+0x18> mul \$a2,\$a3,\$t0
+0+001c <stuff\+0x1c> nop
diff --git a/gas/testsuite/gas/mips/mips4650.s b/gas/testsuite/gas/mips/mips4650.s
new file mode 100644
index 00000000000..52c22a16f3f
--- /dev/null
+++ b/gas/testsuite/gas/mips/mips4650.s
@@ -0,0 +1,8 @@
+ .text
+
+stuff:
+ .ent stuff
+ mad $4,$5
+ madu $5,$6
+ mul $6,$7,$8
+ nop
diff --git a/gas/testsuite/gas/mips/mul-ilocks.d b/gas/testsuite/gas/mips/mul-ilocks.d
new file mode 100644
index 00000000000..061ed2ee5bf
--- /dev/null
+++ b/gas/testsuite/gas/mips/mul-ilocks.d
@@ -0,0 +1,81 @@
+#objdump: -dr --prefix-addresses
+#name: MIPS mul-ilocks
+#as:
+#source: mul.s
+
+# Test the mul macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> multu \$a0,\$a1
+0+0004 <[^>]*> mflo \$a0
+0+0008 <[^>]*> multu \$a1,\$a2
+0+000c <[^>]*> mflo \$a0
+0+0010 <[^>]*> li \$at,0
+0+0014 <[^>]*> mult \$a1,\$at
+0+0018 <[^>]*> mflo \$a0
+0+001c <[^>]*> li \$at,1
+0+0020 <[^>]*> mult \$a1,\$at
+0+0024 <[^>]*> mflo \$a0
+0+0028 <[^>]*> li \$at,0x8000
+0+002c <[^>]*> mult \$a1,\$at
+0+0030 <[^>]*> mflo \$a0
+0+0034 <[^>]*> li \$at,-32768
+0+0038 <[^>]*> mult \$a1,\$at
+0+003c <[^>]*> mflo \$a0
+0+0040 <[^>]*> lui \$at,0x1
+0+0044 <[^>]*> mult \$a1,\$at
+0+0048 <[^>]*> mflo \$a0
+0+004c <[^>]*> lui \$at,0x1
+0+0050 <[^>]*> ori \$at,\$at,0xa5a5
+0+0054 <[^>]*> mult \$a1,\$at
+0+0058 <[^>]*> mflo \$a0
+0+005c <[^>]*> mult \$a0,\$a1
+0+0060 <[^>]*> mflo \$a0
+0+0064 <[^>]*> sra \$a0,\$a0,0x1f
+0+0068 <[^>]*> mfhi \$at
+0+006c <[^>]*> beq \$a0,\$at,0+78 <foo\+(0x|)78>
+0+0070 <[^>]*> nop
+0+0074 <[^>]*> break (0x0,0x6|0x6)
+0+0078 <[^>]*> mflo \$a0
+0+007c <[^>]*> mult \$a1,\$a2
+0+0080 <[^>]*> mflo \$a0
+0+0084 <[^>]*> sra \$a0,\$a0,0x1f
+0+0088 <[^>]*> mfhi \$at
+0+008c <[^>]*> beq \$a0,\$at,0+98 <foo\+(0x|)98>
+0+0090 <[^>]*> nop
+0+0094 <[^>]*> break (0x0,0x6|0x6)
+0+0098 <[^>]*> mflo \$a0
+0+009c <[^>]*> multu \$a0,\$a1
+0+00a0 <[^>]*> mfhi \$at
+0+00a4 <[^>]*> mflo \$a0
+0+00a8 <[^>]*> beqz \$at,0+b4 <foo\+(0x|)b4>
+0+00ac <[^>]*> nop
+0+00b0 <[^>]*> break (0x0,0x6|0x6)
+0+00b4 <[^>]*> multu \$a1,\$a2
+0+00b8 <[^>]*> mfhi \$at
+0+00bc <[^>]*> mflo \$a0
+0+00c0 <[^>]*> beqz \$at,0+cc <foo\+(0x|)cc>
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> break (0x0,0x6|0x6)
+0+00cc <[^>]*> dmultu \$a1,\$a2
+0+00d0 <[^>]*> mflo \$a0
+0+00d4 <[^>]*> li \$at,1
+0+00d8 <[^>]*> dmult \$a1,\$at
+0+00dc <[^>]*> mflo \$a0
+0+00e0 <[^>]*> dmult \$a1,\$a2
+0+00e4 <[^>]*> mflo \$a0
+0+00e8 <[^>]*> dsra32 \$a0,\$a0,0x1f
+0+00ec <[^>]*> mfhi \$at
+0+00f0 <[^>]*> beq \$a0,\$at,0+fc <foo\+(0x|)fc>
+0+00f4 <[^>]*> nop
+0+00f8 <[^>]*> break (0x0,0x6|0x6)
+0+00fc <[^>]*> mflo \$a0
+0+0100 <[^>]*> dmultu \$a1,\$a2
+0+0104 <[^>]*> mfhi \$at
+0+0108 <[^>]*> mflo \$a0
+0+010c <[^>]*> beqz \$at,0+118 <foo\+(0x|)118>
+0+0110 <[^>]*> nop
+0+0114 <[^>]*> break (0x0,0x6|0x6)
+ ...
diff --git a/gas/testsuite/gas/mips/mul.d b/gas/testsuite/gas/mips/mul.d
new file mode 100644
index 00000000000..92b6265242b
--- /dev/null
+++ b/gas/testsuite/gas/mips/mul.d
@@ -0,0 +1,92 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#as: -mcpu=r4000
+#name: MIPS mul
+
+# Test the mul macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> multu \$a0,\$a1
+0+0004 <[^>]*> mflo \$a0
+ ...
+0+0010 <[^>]*> multu \$a1,\$a2
+0+0014 <[^>]*> mflo \$a0
+0+0018 <[^>]*> li \$at,0
+0+001c <[^>]*> nop
+0+0020 <[^>]*> mult \$a1,\$at
+0+0024 <[^>]*> mflo \$a0
+0+0028 <[^>]*> li \$at,1
+0+002c <[^>]*> nop
+0+0030 <[^>]*> mult \$a1,\$at
+0+0034 <[^>]*> mflo \$a0
+0+0038 <[^>]*> li \$at,0x8000
+0+003c <[^>]*> nop
+0+0040 <[^>]*> mult \$a1,\$at
+0+0044 <[^>]*> mflo \$a0
+0+0048 <[^>]*> li \$at,-32768
+0+004c <[^>]*> nop
+0+0050 <[^>]*> mult \$a1,\$at
+0+0054 <[^>]*> mflo \$a0
+0+0058 <[^>]*> lui \$at,0x1
+0+005c <[^>]*> nop
+0+0060 <[^>]*> mult \$a1,\$at
+0+0064 <[^>]*> mflo \$a0
+0+0068 <[^>]*> lui \$at,0x1
+0+006c <[^>]*> ori \$at,\$at,0xa5a5
+0+0070 <[^>]*> mult \$a1,\$at
+0+0074 <[^>]*> mflo \$a0
+ ...
+0+0080 <[^>]*> mult \$a0,\$a1
+0+0084 <[^>]*> mflo \$a0
+0+0088 <[^>]*> sra \$a0,\$a0,0x1f
+0+008c <[^>]*> mfhi \$at
+0+0090 <[^>]*> beq \$a0,\$at,0+9c <foo\+(0x|)9c>
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> break (0x0,0x6|0x6)
+0+009c <[^>]*> mflo \$a0
+ ...
+0+00a8 <[^>]*> mult \$a1,\$a2
+0+00ac <[^>]*> mflo \$a0
+0+00b0 <[^>]*> sra \$a0,\$a0,0x1f
+0+00b4 <[^>]*> mfhi \$at
+0+00b8 <[^>]*> beq \$a0,\$at,0+c4 <foo\+(0x|)c4>
+0+00bc <[^>]*> nop
+0+00c0 <[^>]*> break (0x0,0x6|0x6)
+0+00c4 <[^>]*> mflo \$a0
+ ...
+0+00d0 <[^>]*> multu \$a0,\$a1
+0+00d4 <[^>]*> mfhi \$at
+0+00d8 <[^>]*> mflo \$a0
+0+00dc <[^>]*> beqz \$at,0+e8 <foo\+(0x|)e8>
+0+00e0 <[^>]*> nop
+0+00e4 <[^>]*> break (0x0,0x6|0x6)
+0+00e8 <[^>]*> multu \$a1,\$a2
+0+00ec <[^>]*> mfhi \$at
+0+00f0 <[^>]*> mflo \$a0
+0+00f4 <[^>]*> beqz \$at,0+100 <foo\+(0x|)100>
+0+00f8 <[^>]*> nop
+0+00fc <[^>]*> break (0x0,0x6|0x6)
+0+0100 <[^>]*> dmultu \$a1,\$a2
+0+0104 <[^>]*> mflo \$a0
+0+0108 <[^>]*> li \$at,1
+0+010c <[^>]*> nop
+0+0110 <[^>]*> dmult \$a1,\$at
+0+0114 <[^>]*> mflo \$a0
+ ...
+0+0120 <[^>]*> dmult \$a1,\$a2
+0+0124 <[^>]*> mflo \$a0
+0+0128 <[^>]*> dsra32 \$a0,\$a0,0x1f
+0+012c <[^>]*> mfhi \$at
+0+0130 <[^>]*> beq \$a0,\$at,0+13c <foo\+(0x|)13c>
+0+0134 <[^>]*> nop
+0+0138 <[^>]*> break (0x0,0x6|0x6)
+0+013c <[^>]*> mflo \$a0
+ ...
+0+0148 <[^>]*> dmultu \$a1,\$a2
+0+014c <[^>]*> mfhi \$at
+0+0150 <[^>]*> mflo \$a0
+0+0154 <[^>]*> beqz \$at,0+160 <foo\+(0x|)160>
+0+0158 <[^>]*> nop
+0+015c <[^>]*> break (0x0,0x6|0x6)
+ ...
diff --git a/gas/testsuite/gas/mips/mul.s b/gas/testsuite/gas/mips/mul.s
new file mode 100644
index 00000000000..b29e369f7b9
--- /dev/null
+++ b/gas/testsuite/gas/mips/mul.s
@@ -0,0 +1,27 @@
+# Source file used to test the mul macro.
+
+foo:
+ mul $4,$5
+ mul $4,$5,$6
+ mul $4,$5,0
+ mul $4,$5,1
+ mul $4,$5,0x8000
+ mul $4,$5,-0x8000
+ mul $4,$5,0x10000
+ mul $4,$5,0x1a5a5
+
+# mulo and mulou are only supported for register arguments
+ mulo $4,$5
+ mulo $4,$5,$6
+
+ mulou $4,$5
+ mulou $4,$5,$6
+
+# Sanity check the 64 bit versions.
+ .set mips3
+ dmul $4,$5,$6
+ dmul $4,$5,1
+ dmulo $4,$5,$6
+ dmulou $4,$5,$6
+
+ .space 8
diff --git a/gas/testsuite/gas/mips/nodelay.d b/gas/testsuite/gas/mips/nodelay.d
new file mode 100644
index 00000000000..dc930799b82
--- /dev/null
+++ b/gas/testsuite/gas/mips/nodelay.d
@@ -0,0 +1,19 @@
+#objdump: -dr --prefix-addresses -mmips:5000
+#name: MIPS nodelay
+#as: -mips4 -mcpu=r8000
+#source: delay.s
+
+# For -mips4
+# Gas should *not* produce nop's after mtc1 and related
+# insn's if the target fpr is used in the immediatly
+# following insn. See also delay.d.
+#
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> mtc1 \$zero,\$f0
+0+0004 <[^>]*> cvt.d.w \$f0,\$f0
+0+0008 <[^>]*> mtc1 \$zero,\$f1
+0+000c <[^>]*> cvt.d.w \$f1,\$f1
+ ...
diff --git a/gas/testsuite/gas/mips/rol.d b/gas/testsuite/gas/mips/rol.d
new file mode 100644
index 00000000000..14ce1425d46
--- /dev/null
+++ b/gas/testsuite/gas/mips/rol.d
@@ -0,0 +1,37 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#as: -mcpu=r3000
+#name: MIPS R3000 rol
+
+# Test the rol and ror macros.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> negu \$at,\$a1
+0+0004 <[^>]*> srlv \$at,\$a0,\$at
+0+0008 <[^>]*> sllv \$a0,\$a0,\$a1
+0+000c <[^>]*> or \$a0,\$a0,\$at
+0+0010 <[^>]*> negu \$at,\$a2
+0+0014 <[^>]*> srlv \$at,\$a1,\$at
+0+0018 <[^>]*> sllv \$a0,\$a1,\$a2
+0+001c <[^>]*> or \$a0,\$a0,\$at
+0+0020 <[^>]*> sll \$at,\$a0,0x1
+0+0024 <[^>]*> srl \$a0,\$a0,0x1f
+0+0028 <[^>]*> or \$a0,\$a0,\$at
+0+002c <[^>]*> sll \$at,\$a1,0x1
+0+0030 <[^>]*> srl \$a0,\$a1,0x1f
+0+0034 <[^>]*> or \$a0,\$a0,\$at
+0+0038 <[^>]*> negu \$at,\$a1
+0+003c <[^>]*> sllv \$at,\$a0,\$at
+0+0040 <[^>]*> srlv \$a0,\$a0,\$a1
+0+0044 <[^>]*> or \$a0,\$a0,\$at
+0+0048 <[^>]*> negu \$at,\$a2
+0+004c <[^>]*> sllv \$at,\$a1,\$at
+0+0050 <[^>]*> srlv \$a0,\$a1,\$a2
+0+0054 <[^>]*> or \$a0,\$a0,\$at
+0+0058 <[^>]*> srl \$at,\$a0,0x1
+0+005c <[^>]*> sll \$a0,\$a0,0x1f
+0+0060 <[^>]*> or \$a0,\$a0,\$at
+0+0064 <[^>]*> srl \$at,\$a1,0x1
+0+0068 <[^>]*> sll \$a0,\$a1,0x1f
+0+006c <[^>]*> or \$a0,\$a0,\$at
diff --git a/gas/testsuite/gas/mips/rol.s b/gas/testsuite/gas/mips/rol.s
new file mode 100644
index 00000000000..259a957e803
--- /dev/null
+++ b/gas/testsuite/gas/mips/rol.s
@@ -0,0 +1,12 @@
+# Source file used to test the rol and ror macros.
+
+foo:
+ rol $4,$5
+ rol $4,$5,$6
+ rol $4,1
+ rol $4,$5,1
+
+ ror $4,$5
+ ror $4,$5,$6
+ ror $4,1
+ ror $4,$5,1
diff --git a/gas/testsuite/gas/mips/sb.d b/gas/testsuite/gas/mips/sb.d
new file mode 100644
index 00000000000..0ef4bc12c2d
--- /dev/null
+++ b/gas/testsuite/gas/mips/sb.d
@@ -0,0 +1,396 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS sb
+#as: -mips1
+
+# Test the sb macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> sb \$a0,0\(\$zero\)
+0+0004 <[^>]*> sb \$a0,1\(\$zero\)
+0+0008 <[^>]*> lui \$at,0x1
+0+000c <[^>]*> sb \$a0,-32768\(\$at\)
+0+0010 <[^>]*> sb \$a0,-32768\(\$zero\)
+0+0014 <[^>]*> lui \$at,0x1
+0+0018 <[^>]*> sb \$a0,0\(\$at\)
+0+001c <[^>]*> lui \$at,0x2
+0+0020 <[^>]*> sb \$a0,-23131\(\$at\)
+0+0024 <[^>]*> sb \$a0,0\(\$a1\)
+0+0028 <[^>]*> sb \$a0,1\(\$a1\)
+0+002c <[^>]*> lui \$at,0x1
+0+0030 <[^>]*> addu \$at,\$at,\$a1
+0+0034 <[^>]*> sb \$a0,-32768\(\$at\)
+0+0038 <[^>]*> sb \$a0,-32768\(\$a1\)
+0+003c <[^>]*> lui \$at,0x1
+0+0040 <[^>]*> addu \$at,\$at,\$a1
+0+0044 <[^>]*> sb \$a0,0\(\$at\)
+0+0048 <[^>]*> lui \$at,0x2
+0+004c <[^>]*> addu \$at,\$at,\$a1
+0+0050 <[^>]*> sb \$a0,-23131\(\$at\)
+0+0054 <[^>]*> lui \$at,0x0
+[ ]*54: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0058 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*58: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+005c <[^>]*> lui \$at,0x0
+[ ]*5c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0060 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*60: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0064 <[^>]*> sb \$a0,0\(\$gp\)
+[ ]*64: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0068 <[^>]*> lui \$at,0x0
+[ ]*68: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+006c <[^>]*> sb \$a0,0\(\$at\)
+[ ]*6c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0070 <[^>]*> sb \$a0,0\(\$gp\)
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0074 <[^>]*> lui \$at,0x0
+[ ]*74: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0078 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*78: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+007c <[^>]*> sb \$a0,[-0-9]+\(\$gp\)
+[ ]*7c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0080 <[^>]*> lui \$at,0x0
+[ ]*80: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0084 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*84: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0088 <[^>]*> lui \$at,0x0
+[ ]*88: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+008c <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*8c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0090 <[^>]*> sb \$a0,1\(\$gp\)
+[ ]*90: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0094 <[^>]*> lui \$at,0x0
+[ ]*94: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0098 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*98: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+009c <[^>]*> sb \$a0,1\(\$gp\)
+[ ]*9c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00a0 <[^>]*> lui \$at,0x0
+[ ]*a0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00a4 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*a4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a8 <[^>]*> sb \$a0,[-0-9]+\(\$gp\)
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ac <[^>]*> lui \$at,[-0-9x]+
+[ ]*ac: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00b0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*b0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00b4 <[^>]*> lui \$at,[-0-9x]+
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00b8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00bc <[^>]*> lui \$at,[-0-9x]+
+[ ]*bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+00c0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*c0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+00c4 <[^>]*> lui \$at,[-0-9x]+
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00c8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00cc <[^>]*> lui \$at,[-0-9x]+
+[ ]*cc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+00d0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*d0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+00d4 <[^>]*> lui \$at,[-0-9x]+
+[ ]*d4: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+00d8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*d8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00dc <[^>]*> lui \$at,[-0-9x]+
+[ ]*dc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+00e0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*e0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+00e4 <[^>]*> lui \$at,0x0
+[ ]*e4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00e8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*e8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00ec <[^>]*> lui \$at,0x0
+[ ]*ec: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00f0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00f4 <[^>]*> lui \$at,0x0
+[ ]*f4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+00f8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*f8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+00fc <[^>]*> lui \$at,0x0
+[ ]*fc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0100 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0104 <[^>]*> lui \$at,0x0
+[ ]*104: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0108 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*108: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+010c <[^>]*> lui \$at,0x0
+[ ]*10c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0110 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*110: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0114 <[^>]*> lui \$at,0x0
+[ ]*114: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0118 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*118: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+011c <[^>]*> lui \$at,[-0-9x]+
+[ ]*11c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0120 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*120: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0124 <[^>]*> lui \$at,[-0-9x]+
+[ ]*124: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0128 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*128: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> lui \$at,[-0-9x]+
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0130 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0134 <[^>]*> lui \$at,[-0-9x]+
+[ ]*134: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0138 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*138: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+013c <[^>]*> lui \$at,[-0-9x]+
+[ ]*13c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0140 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*140: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0144 <[^>]*> lui \$at,[-0-9x]+
+[ ]*144: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0148 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*148: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+014c <[^>]*> lui \$at,[-0-9x]+
+[ ]*14c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0150 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*150: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0154 <[^>]*> lui \$at,[-0-9x]+
+[ ]*154: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0158 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*158: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+015c <[^>]*> lui \$at,[-0-9x]+
+[ ]*15c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0160 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*160: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0164 <[^>]*> lui \$at,[-0-9x]+
+[ ]*164: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0168 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*168: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+016c <[^>]*> lui \$at,[-0-9x]+
+[ ]*16c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0170 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*170: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0174 <[^>]*> lui \$at,[-0-9x]+
+[ ]*174: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0178 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*178: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+017c <[^>]*> lui \$at,[-0-9x]+
+[ ]*17c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0180 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*180: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0184 <[^>]*> lui \$at,[-0-9x]+
+[ ]*184: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0188 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*188: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+018c <[^>]*> lui \$at,0x0
+[ ]*18c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0190 <[^>]*> addu \$at,\$at,\$a1
+0+0194 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*194: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> addu \$at,\$at,\$a1
+0+01a0 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*1a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01a4 <[^>]*> addu \$at,\$a1,\$gp
+0+01a8 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*1a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> lui \$at,0x0
+[ ]*1ac: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01b0 <[^>]*> addu \$at,\$at,\$a1
+0+01b4 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*1b4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01b8 <[^>]*> addu \$at,\$a1,\$gp
+0+01bc <[^>]*> sb \$a0,0\(\$at\)
+[ ]*1bc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+01c0 <[^>]*> lui \$at,0x0
+[ ]*1c0: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01c4 <[^>]*> addu \$at,\$at,\$a1
+0+01c8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*1c8: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01cc <[^>]*> addu \$at,\$a1,\$gp
+0+01d0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*1d0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01d4 <[^>]*> lui \$at,0x0
+[ ]*1d4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01d8 <[^>]*> addu \$at,\$at,\$a1
+0+01dc <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01e0 <[^>]*> lui \$at,0x0
+[ ]*1e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01e4 <[^>]*> addu \$at,\$at,\$a1
+0+01e8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*1e8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01ec <[^>]*> addu \$at,\$a1,\$gp
+0+01f0 <[^>]*> sb \$a0,1\(\$at\)
+[ ]*1f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01f4 <[^>]*> lui \$at,0x0
+[ ]*1f4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01f8 <[^>]*> addu \$at,\$at,\$a1
+0+01fc <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0200 <[^>]*> addu \$at,\$a1,\$gp
+0+0204 <[^>]*> sb \$a0,1\(\$at\)
+[ ]*204: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0208 <[^>]*> lui \$at,0x0
+[ ]*208: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+020c <[^>]*> addu \$at,\$at,\$a1
+0+0210 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*210: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0214 <[^>]*> addu \$at,\$a1,\$gp
+0+0218 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*218: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+021c <[^>]*> lui \$at,[-0-9x]+
+[ ]*21c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0220 <[^>]*> addu \$at,\$at,\$a1
+0+0224 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*224: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+022c <[^>]*> addu \$at,\$at,\$a1
+0+0230 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*230: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0234 <[^>]*> lui \$at,[-0-9x]+
+[ ]*234: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0238 <[^>]*> addu \$at,\$at,\$a1
+0+023c <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0240 <[^>]*> lui \$at,[-0-9x]+
+[ ]*240: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0244 <[^>]*> addu \$at,\$at,\$a1
+0+0248 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*248: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+024c <[^>]*> lui \$at,[-0-9x]+
+[ ]*24c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0250 <[^>]*> addu \$at,\$at,\$a1
+0+0254 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*254: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+025c <[^>]*> addu \$at,\$at,\$a1
+0+0260 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*260: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0264 <[^>]*> lui \$at,[-0-9x]+
+[ ]*264: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0268 <[^>]*> addu \$at,\$at,\$a1
+0+026c <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0270 <[^>]*> lui \$at,0x0
+[ ]*270: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0274 <[^>]*> addu \$at,\$at,\$a1
+0+0278 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*278: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+027c <[^>]*> lui \$at,0x0
+[ ]*27c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> addu \$at,\$at,\$a1
+0+0284 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*284: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0288 <[^>]*> lui \$at,0x0
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> addu \$at,\$at,\$a1
+0+0290 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*290: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0294 <[^>]*> lui \$at,0x0
+[ ]*294: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0298 <[^>]*> addu \$at,\$at,\$a1
+0+029c <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> lui \$at,0x0
+[ ]*2a0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02a4 <[^>]*> addu \$at,\$at,\$a1
+0+02a8 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*2a8: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> lui \$at,0x0
+[ ]*2ac: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02b0 <[^>]*> addu \$at,\$at,\$a1
+0+02b4 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*2b4: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02b8 <[^>]*> lui \$at,0x0
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02bc <[^>]*> addu \$at,\$at,\$a1
+0+02c0 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*2c0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02c4 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2c4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+02c8 <[^>]*> addu \$at,\$at,\$a1
+0+02cc <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+02d0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2d0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+02d4 <[^>]*> addu \$at,\$at,\$a1
+0+02d8 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*2d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+02dc <[^>]*> lui \$at,[-0-9x]+
+[ ]*2dc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+02e0 <[^>]*> addu \$at,\$at,\$a1
+0+02e4 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*2e4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+02e8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2e8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02ec <[^>]*> addu \$at,\$at,\$a1
+0+02f0 <[^>]*> sb \$a0,0\(\$at\)
+[ ]*2f0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02f4 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2f4: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02f8 <[^>]*> addu \$at,\$at,\$a1
+0+02fc <[^>]*> sb \$a0,0\(\$at\)
+[ ]*2fc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0300 <[^>]*> lui \$at,[-0-9x]+
+[ ]*300: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0304 <[^>]*> addu \$at,\$at,\$a1
+0+0308 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*308: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+030c <[^>]*> lui \$at,[-0-9x]+
+[ ]*30c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0310 <[^>]*> addu \$at,\$at,\$a1
+0+0314 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*314: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0318 <[^>]*> lui \$at,[-0-9x]+
+[ ]*318: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+031c <[^>]*> addu \$at,\$at,\$a1
+0+0320 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*320: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0324 <[^>]*> lui \$at,[-0-9x]+
+[ ]*324: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0328 <[^>]*> addu \$at,\$at,\$a1
+0+032c <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*32c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0330 <[^>]*> lui \$at,[-0-9x]+
+[ ]*330: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0334 <[^>]*> addu \$at,\$at,\$a1
+0+0338 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*338: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+033c <[^>]*> lui \$at,[-0-9x]+
+[ ]*33c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0340 <[^>]*> addu \$at,\$at,\$a1
+0+0344 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*344: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0348 <[^>]*> lui \$at,[-0-9x]+
+[ ]*348: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+034c <[^>]*> addu \$at,\$at,\$a1
+0+0350 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*350: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0354 <[^>]*> lui \$at,[-0-9x]+
+[ ]*354: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0358 <[^>]*> addu \$at,\$at,\$a1
+0+035c <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*35c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0360 <[^>]*> lui \$at,[-0-9x]+
+[ ]*360: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0364 <[^>]*> addu \$at,\$at,\$a1
+0+0368 <[^>]*> sb \$a0,[-0-9]+\(\$at\)
+[ ]*368: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+036c <[^>]*> sw \$a0,0\(\$zero\)
+0+0370 <[^>]*> sw \$a1,4\(\$zero\)
+0+0374 <[^>]*> sh \$a0,0\(\$zero\)
+0+0378 <[^>]*> sw \$a0,0\(\$zero\)
+0+037c <[^>]*> swc0 \$4,0\(\$zero\)
+0+0380 <[^>]*> swc1 \$f4,0\(\$zero\)
+0+0384 <[^>]*> swc2 \$4,0\(\$zero\)
+0+0388 <[^>]*> swc3 \$4,0\(\$zero\)
+0+038c <[^>]*> swc1 \$f4,0\(\$zero\)
+0+0390 <[^>]*> swl \$a0,0\(\$zero\)
+0+0394 <[^>]*> swr \$a0,0\(\$zero\)
+ ...
diff --git a/gas/testsuite/gas/mips/sb.s b/gas/testsuite/gas/mips/sb.s
new file mode 100644
index 00000000000..d0c73542abb
--- /dev/null
+++ b/gas/testsuite/gas/mips/sb.s
@@ -0,0 +1,124 @@
+# Source file used to test the sb macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ sb $4,0
+ sb $4,1
+ sb $4,0x8000
+ sb $4,-0x8000
+ sb $4,0x10000
+ sb $4,0x1a5a5
+ sb $4,0($5)
+ sb $4,1($5)
+ sb $4,0x8000($5)
+ sb $4,-0x8000($5)
+ sb $4,0x10000($5)
+ sb $4,0x1a5a5($5)
+ sb $4,data_label
+ sb $4,big_external_data_label
+ sb $4,small_external_data_label
+ sb $4,big_external_common
+ sb $4,small_external_common
+ sb $4,big_local_common
+ sb $4,small_local_common
+ sb $4,data_label+1
+ sb $4,big_external_data_label+1
+ sb $4,small_external_data_label+1
+ sb $4,big_external_common+1
+ sb $4,small_external_common+1
+ sb $4,big_local_common+1
+ sb $4,small_local_common+1
+ sb $4,data_label+0x8000
+ sb $4,big_external_data_label+0x8000
+ sb $4,small_external_data_label+0x8000
+ sb $4,big_external_common+0x8000
+ sb $4,small_external_common+0x8000
+ sb $4,big_local_common+0x8000
+ sb $4,small_local_common+0x8000
+ sb $4,data_label-0x8000
+ sb $4,big_external_data_label-0x8000
+ sb $4,small_external_data_label-0x8000
+ sb $4,big_external_common-0x8000
+ sb $4,small_external_common-0x8000
+ sb $4,big_local_common-0x8000
+ sb $4,small_local_common-0x8000
+ sb $4,data_label+0x10000
+ sb $4,big_external_data_label+0x10000
+ sb $4,small_external_data_label+0x10000
+ sb $4,big_external_common+0x10000
+ sb $4,small_external_common+0x10000
+ sb $4,big_local_common+0x10000
+ sb $4,small_local_common+0x10000
+ sb $4,data_label+0x1a5a5
+ sb $4,big_external_data_label+0x1a5a5
+ sb $4,small_external_data_label+0x1a5a5
+ sb $4,big_external_common+0x1a5a5
+ sb $4,small_external_common+0x1a5a5
+ sb $4,big_local_common+0x1a5a5
+ sb $4,small_local_common+0x1a5a5
+ sb $4,data_label($5)
+ sb $4,big_external_data_label($5)
+ sb $4,small_external_data_label($5)
+ sb $4,big_external_common($5)
+ sb $4,small_external_common($5)
+ sb $4,big_local_common($5)
+ sb $4,small_local_common($5)
+ sb $4,data_label+1($5)
+ sb $4,big_external_data_label+1($5)
+ sb $4,small_external_data_label+1($5)
+ sb $4,big_external_common+1($5)
+ sb $4,small_external_common+1($5)
+ sb $4,big_local_common+1($5)
+ sb $4,small_local_common+1($5)
+ sb $4,data_label+0x8000($5)
+ sb $4,big_external_data_label+0x8000($5)
+ sb $4,small_external_data_label+0x8000($5)
+ sb $4,big_external_common+0x8000($5)
+ sb $4,small_external_common+0x8000($5)
+ sb $4,big_local_common+0x8000($5)
+ sb $4,small_local_common+0x8000($5)
+ sb $4,data_label-0x8000($5)
+ sb $4,big_external_data_label-0x8000($5)
+ sb $4,small_external_data_label-0x8000($5)
+ sb $4,big_external_common-0x8000($5)
+ sb $4,small_external_common-0x8000($5)
+ sb $4,big_local_common-0x8000($5)
+ sb $4,small_local_common-0x8000($5)
+ sb $4,data_label+0x10000($5)
+ sb $4,big_external_data_label+0x10000($5)
+ sb $4,small_external_data_label+0x10000($5)
+ sb $4,big_external_common+0x10000($5)
+ sb $4,small_external_common+0x10000($5)
+ sb $4,big_local_common+0x10000($5)
+ sb $4,small_local_common+0x10000($5)
+ sb $4,data_label+0x1a5a5($5)
+ sb $4,big_external_data_label+0x1a5a5($5)
+ sb $4,small_external_data_label+0x1a5a5($5)
+ sb $4,big_external_common+0x1a5a5($5)
+ sb $4,small_external_common+0x1a5a5($5)
+ sb $4,big_local_common+0x1a5a5($5)
+ sb $4,small_local_common+0x1a5a5($5)
+
+# Several macros are handled like sb. Sanity check them.
+ sd $4,0
+ sh $4,0
+ sw $4,0
+ swc0 $4,0
+ swc1 $4,0
+ swc2 $4,0
+ swc3 $4,0
+ s.s $f4,0
+ swl $4,0
+ swr $4,0
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/sync.d b/gas/testsuite/gas/mips/sync.d
new file mode 100644
index 00000000000..9b50ea2f33e
--- /dev/null
+++ b/gas/testsuite/gas/mips/sync.d
@@ -0,0 +1,10 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: sync instructions
+#as:
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+0+0000 <foo> 0000000f[ ]*sync
+0+0004 <foo\+0x4> 0000040f[ ]*sync.p
+0+0008 <foo\+0x8> 0000000f[ ]*sync
diff --git a/gas/testsuite/gas/mips/sync.s b/gas/testsuite/gas/mips/sync.s
new file mode 100644
index 00000000000..dec0ed3e16d
--- /dev/null
+++ b/gas/testsuite/gas/mips/sync.s
@@ -0,0 +1,5 @@
+ .text
+foo:
+ sync
+ sync.p
+ sync.l
diff --git a/gas/testsuite/gas/mips/trap20.d b/gas/testsuite/gas/mips/trap20.d
new file mode 100644
index 00000000000..997adb0b94e
--- /dev/null
+++ b/gas/testsuite/gas/mips/trap20.d
@@ -0,0 +1,20 @@
+#as: -mcpu=r4000
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS 20-bit trap
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> teq \$zero,\$v1
+0+0004 <[^>]*> teq \$zero,\$v1,0x1
+0+0008 <[^>]*> tge \$zero,\$v1
+0+000c <[^>]*> tge \$zero,\$v1,0x3
+0+0010 <[^>]*> tgeu \$zero,\$v1
+0+0014 <[^>]*> tgeu \$zero,\$v1,0x7
+0+0018 <[^>]*> tlt \$zero,\$v1
+0+001c <[^>]*> tlt \$zero,\$v1,0x1f
+0+0020 <[^>]*> tltu \$zero,\$v1
+0+0024 <[^>]*> tltu \$zero,\$v1,0xff
+0+0028 <[^>]*> tne \$zero,\$v1
+0+002c <[^>]*> tne \$zero,\$v1,0x3ff
+ ...
diff --git a/gas/testsuite/gas/mips/trap20.s b/gas/testsuite/gas/mips/trap20.s
new file mode 100644
index 00000000000..a56d6595693
--- /dev/null
+++ b/gas/testsuite/gas/mips/trap20.s
@@ -0,0 +1,18 @@
+# Source file used to test the 20-bit trap instructions
+foo:
+ teq $0,$3
+ teq $0,$3,1
+ tge $0,$3
+ tge $0,$3,3
+ tgeu $0,$3
+ tgeu $0,$3,7
+ tlt $0,$3
+ tlt $0,$3,31
+ tltu $0,$3
+ tltu $0,$3,255
+ tne $0,$3
+ tne $0,$3,1023
+
+# force some padding, to make objdump consistently report that there's some
+# here...
+ .space 8
diff --git a/gas/testsuite/gas/mips/trunc.d b/gas/testsuite/gas/mips/trunc.d
new file mode 100644
index 00000000000..3738ae15c2d
--- /dev/null
+++ b/gas/testsuite/gas/mips/trunc.d
@@ -0,0 +1,29 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS trunc
+#as: -mips1 -mcpu=r3000
+
+# Test the trunc macros.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> cfc1 \$a0,\$31
+0+0004 <[^>]*> cfc1 \$a0,\$31
+0+0008 <[^>]*> nop
+0+000c <[^>]*> ori \$at,\$a0,0x3
+0+0010 <[^>]*> xori \$at,\$at,0x2
+0+0014 <[^>]*> ctc1 \$at,\$31
+0+0018 <[^>]*> nop
+0+001c <[^>]*> cvt.w.d \$f4,\$f6
+0+0020 <[^>]*> ctc1 \$a0,\$31
+0+0024 <[^>]*> nop
+0+0028 <[^>]*> cfc1 \$a0,\$31
+0+002c <[^>]*> cfc1 \$a0,\$31
+0+0030 <[^>]*> nop
+0+0034 <[^>]*> ori \$at,\$a0,0x3
+0+0038 <[^>]*> xori \$at,\$at,0x2
+0+003c <[^>]*> ctc1 \$at,\$31
+0+0040 <[^>]*> nop
+0+0044 <[^>]*> cvt.w.s \$f4,\$f6
+0+0048 <[^>]*> ctc1 \$a0,\$31
+0+004c <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/trunc.s b/gas/testsuite/gas/mips/trunc.s
new file mode 100644
index 00000000000..e1e90f1e316
--- /dev/null
+++ b/gas/testsuite/gas/mips/trunc.s
@@ -0,0 +1,6 @@
+# Source file used to test the trunc macros.
+
+foo:
+ trunc.w.d $f4,$f6,$4
+
+ trunc.w.s $f4,$f6,$4
diff --git a/gas/testsuite/gas/mips/uld.d b/gas/testsuite/gas/mips/uld.d
new file mode 100644
index 00000000000..f92e29d565c
--- /dev/null
+++ b/gas/testsuite/gas/mips/uld.d
@@ -0,0 +1,270 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS uld
+#as: -mips3 -mcpu=r4000
+
+# Test the uld macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> ldl \$a0,[07]\(\$zero\)
+0+0004 <[^>]*> ldr \$a0,[07]\(\$zero\)
+0+0008 <[^>]*> ldl \$a0,[18]\(\$zero\)
+0+000c <[^>]*> ldr \$a0,[18]\(\$zero\)
+0+0010 <[^>]*> li \$at,0x8000
+0+0014 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0018 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+001c <[^>]*> ldl \$a0,-3276[18]\(\$zero\)
+0+0020 <[^>]*> ldr \$a0,-3276[18]\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+002c <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0030 <[^>]*> lui \$at,0x1
+0+0034 <[^>]*> ori \$at,\$at,0xa5a5
+0+0038 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+003c <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0040 <[^>]*> ldl \$a0,[07]\(\$a1\)
+0+0044 <[^>]*> ldr \$a0,[07]\(\$a1\)
+0+0048 <[^>]*> ldl \$a0,[18]\(\$a1\)
+0+004c <[^>]*> ldr \$a0,[-0-9]+\(\$a1\)
+0+0050 <[^>]*> lui \$at,[-0-9x]+
+[ ]*50: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0054 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*54: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0058 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+005c <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0060 <[^>]*> lui \$at,0x0
+[ ]*60: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0064 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*64: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0068 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+006c <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0070 <[^>]*> daddiu \$at,\$gp,0
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0074 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0078 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+007c <[^>]*> lui \$at,0x0
+[ ]*7c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0080 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*80: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0084 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0088 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+008c <[^>]*> daddiu \$at,\$gp,0
+[ ]*8c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0090 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0094 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0098 <[^>]*> lui \$at,[-0-9x]+
+[ ]*98: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+009c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*9c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00a4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00a8 <[^>]*> daddiu \$at,\$gp,[-0-9]+
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ac <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00b0 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00b4 <[^>]*> lui \$at,0x0
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00b8 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00bc <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00c0 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00c4 <[^>]*> lui \$at,0x0
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00c8 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00cc <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00d0 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00d4 <[^>]*> daddiu \$at,\$gp,1
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00d8 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00dc <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00e0 <[^>]*> lui \$at,0x0
+[ ]*e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00e4 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00e8 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00ec <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00f0 <[^>]*> daddiu \$at,\$gp,1
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00f4 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+00f8 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+00fc <[^>]*> lui \$at,0x0
+[ ]*fc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0100 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0108 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+010c <[^>]*> daddiu \$at,\$gp,[-0-9]+
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0110 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0114 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0118 <[^>]*> lui \$at,[-0-9x]+
+[ ]*118: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+011c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0124 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0128 <[^>]*> lui \$at,[-0-9x]+
+[ ]*128: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*12c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0130 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0134 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0138 <[^>]*> lui \$at,[-0-9x]+
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+013c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0140 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0144 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0148 <[^>]*> lui \$at,[-0-9x]+
+[ ]*148: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+014c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0150 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0154 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0158 <[^>]*> lui \$at,[-0-9x]+
+[ ]*158: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+015c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*15c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0160 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0164 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0168 <[^>]*> lui \$at,[-0-9x]+
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+016c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0170 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0174 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0178 <[^>]*> lui \$at,[-0-9x]+
+[ ]*178: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+017c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0180 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0184 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0188 <[^>]*> lui \$at,0x0
+[ ]*188: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+018c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*18c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0190 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0194 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01a0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+01a4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+01a8 <[^>]*> lui \$at,0x0
+[ ]*1a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01b0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+01b4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+01b8 <[^>]*> lui \$at,0x0
+[ ]*1b8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01bc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1bc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01c0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+01c4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+01c8 <[^>]*> lui \$at,0x0
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01cc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01d0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+01d4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+01d8 <[^>]*> lui \$at,0x0
+[ ]*1d8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01dc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01e0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+01e4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+01e8 <[^>]*> lui \$at,0x0
+[ ]*1e8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01ec <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1ec: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01f0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+01f4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+01f8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01fc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0200 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0204 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0208 <[^>]*> lui \$at,[-0-9x]+
+[ ]*208: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+020c <[^>]*> daddiu \$at,\$at,0
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0210 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0214 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0218 <[^>]*> lui \$at,[-0-9x]+
+[ ]*218: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+021c <[^>]*> daddiu \$at,\$at,0
+[ ]*21c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0220 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0224 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+022c <[^>]*> daddiu \$at,\$at,0
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0230 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0234 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0238 <[^>]*> lui \$at,[-0-9x]+
+[ ]*238: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+023c <[^>]*> daddiu \$at,\$at,0
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0240 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0244 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0248 <[^>]*> lui \$at,[-0-9x]+
+[ ]*248: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+024c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*24c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0250 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0254 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0264 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0268 <[^>]*> lui \$at,[-0-9x]+
+[ ]*268: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+026c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0270 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0274 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0278 <[^>]*> lui \$at,[-0-9x]+
+[ ]*278: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+027c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0284 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0288 <[^>]*> lui \$at,[-0-9x]+
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*28c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0290 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+0294 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+0298 <[^>]*> lui \$at,[-0-9x]+
+[ ]*298: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+029c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+02a4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+02a8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*2ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02b0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+02b4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+02b8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02bc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*2bc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02c0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+02c4 <[^>]*> ldr \$a0,[07]\(\$at\)
+0+02c8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2c8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02cc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02d0 <[^>]*> ldl \$a0,[07]\(\$at\)
+0+02d4 <[^>]*> ldr \$a0,[07]\(\$at\)
+ ...
diff --git a/gas/testsuite/gas/mips/uld.s b/gas/testsuite/gas/mips/uld.s
new file mode 100644
index 00000000000..9eaffbc3294
--- /dev/null
+++ b/gas/testsuite/gas/mips/uld.s
@@ -0,0 +1,66 @@
+# Source file used to test the uld macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ uld $4,0
+ uld $4,1
+ uld $4,0x8000
+ uld $4,-0x8000
+ uld $4,0x10000
+ uld $4,0x1a5a5
+ uld $4,0($5)
+ uld $4,1($5)
+ uld $4,data_label
+ uld $4,big_external_data_label
+ uld $4,small_external_data_label
+ uld $4,big_external_common
+ uld $4,small_external_common
+ uld $4,big_local_common
+ uld $4,small_local_common
+ uld $4,data_label+1
+ uld $4,big_external_data_label+1
+ uld $4,small_external_data_label+1
+ uld $4,big_external_common+1
+ uld $4,small_external_common+1
+ uld $4,big_local_common+1
+ uld $4,small_local_common+1
+ uld $4,data_label+0x8000
+ uld $4,big_external_data_label+0x8000
+ uld $4,small_external_data_label+0x8000
+ uld $4,big_external_common+0x8000
+ uld $4,small_external_common+0x8000
+ uld $4,big_local_common+0x8000
+ uld $4,small_local_common+0x8000
+ uld $4,data_label-0x8000
+ uld $4,big_external_data_label-0x8000
+ uld $4,small_external_data_label-0x8000
+ uld $4,big_external_common-0x8000
+ uld $4,small_external_common-0x8000
+ uld $4,big_local_common-0x8000
+ uld $4,small_local_common-0x8000
+ uld $4,data_label+0x10000
+ uld $4,big_external_data_label+0x10000
+ uld $4,small_external_data_label+0x10000
+ uld $4,big_external_common+0x10000
+ uld $4,small_external_common+0x10000
+ uld $4,big_local_common+0x10000
+ uld $4,small_local_common+0x10000
+ uld $4,data_label+0x1a5a5
+ uld $4,big_external_data_label+0x1a5a5
+ uld $4,small_external_data_label+0x1a5a5
+ uld $4,big_external_common+0x1a5a5
+ uld $4,small_external_common+0x1a5a5
+ uld $4,big_local_common+0x1a5a5
+ uld $4,small_local_common+0x1a5a5
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/ulh-empic.d b/gas/testsuite/gas/mips/ulh-empic.d
new file mode 100644
index 00000000000..945f06b624e
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulh-empic.d
@@ -0,0 +1,91 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ulh-empic
+#as: -mips1 -membedded-pic
+#source: ulh-pic.s
+
+# Test the ulh macro with -membedded-pic.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> addiu \$at,\$gp,-16384
+[ ]*0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0004 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0008 <[^>]*> lbu \$at,[01]\(\$at\)
+0+000c <[^>]*> sll \$a0,\$a0,0x8
+0+0010 <[^>]*> or \$a0,\$a0,\$at
+0+0014 <[^>]*> addiu \$at,\$gp,0
+[ ]*14: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0018 <[^>]*> lbu \$a0,[01]\(\$at\)
+0+001c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0020 <[^>]*> sll \$a0,\$a0,0x8
+0+0024 <[^>]*> or \$a0,\$a0,\$at
+0+0028 <[^>]*> addiu \$at,\$gp,0
+[ ]*28: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+002c <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0030 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0034 <[^>]*> addiu \$at,\$gp,0
+[ ]*34: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+0038 <[^>]*> sb \$a0,[01]\(\$at\)
+0+003c <[^>]*> srl \$a0,\$a0,0x8
+0+0040 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0044 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0048 <[^>]*> sll \$a0,\$a0,0x8
+0+004c <[^>]*> or \$a0,\$a0,\$at
+0+0050 <[^>]*> addiu \$at,\$gp,0
+[ ]*50: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0054 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0058 <[^>]*> swr \$a0,[03]\(\$at\)
+0+005c <[^>]*> addiu \$at,\$gp,-16384
+[ ]*5c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0060 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0064 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0068 <[^>]*> sll \$a0,\$a0,0x8
+0+006c <[^>]*> or \$a0,\$a0,\$at
+0+0070 <[^>]*> addiu \$at,\$gp,-15384
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0074 <[^>]*> lbu \$a0,[01]\(\$at\)
+0+0078 <[^>]*> lbu \$at,[01]\(\$at\)
+0+007c <[^>]*> sll \$a0,\$a0,0x8
+0+0080 <[^>]*> or \$a0,\$a0,\$at
+0+0084 <[^>]*> addiu \$at,\$gp,-16383
+[ ]*84: [A-Z0-9_]*GPREL[A-Z0-9_]* .sdata.*
+0+0088 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+008c <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0090 <[^>]*> addiu \$at,\$gp,1
+[ ]*90: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_data_label
+0+0094 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0098 <[^>]*> srl \$a0,\$a0,0x8
+0+009c <[^>]*> sb \$a0,[01]\(\$at\)
+0+00a0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00a4 <[^>]*> sll \$a0,\$a0,0x8
+0+00a8 <[^>]*> or \$a0,\$a0,\$at
+0+00ac <[^>]*> addiu \$at,\$gp,1
+[ ]*ac: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00b0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+00b4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+00b8 <[^>]*> addiu \$at,\$gp,1
+[ ]*b8: [A-Z0-9_]*GPREL[A-Z0-9_]* big_external_common
+0+00bc <[^>]*> lb \$a0,[01]\(\$at\)
+0+00c0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00c4 <[^>]*> sll \$a0,\$a0,0x8
+0+00c8 <[^>]*> or \$a0,\$a0,\$at
+0+00cc <[^>]*> addiu \$at,\$gp,1
+[ ]*cc: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00d0 <[^>]*> lbu \$a0,[01]\(\$at\)
+0+00d4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00d8 <[^>]*> sll \$a0,\$a0,0x8
+0+00dc <[^>]*> or \$a0,\$a0,\$at
+0+00e0 <[^>]*> addiu \$at,\$gp,-16383
+[ ]*e0: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00e4 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00e8 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00ec <[^>]*> addiu \$at,\$gp,-15383
+[ ]*ec: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00f0 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00f4 <[^>]*> srl \$a0,\$a0,0x8
+0+00f8 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00fc <[^>]*> lbu \$at,[01]\(\$at\)
+0+0100 <[^>]*> sll \$a0,\$a0,0x8
+0+0104 <[^>]*> or \$a0,\$a0,\$at
+ ...
diff --git a/gas/testsuite/gas/mips/ulh-pic.s b/gas/testsuite/gas/mips/ulh-pic.s
new file mode 100644
index 00000000000..633b29c48fd
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulh-pic.s
@@ -0,0 +1,36 @@
+# Test unaligned load and store macros with PIC code. We don't bother
+# to test most cases. The actual loads and stores are tested by the
+# non-PIC test case. We just want to check that the initial address
+# is loaded correctly.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ ulh $4,data_label
+ ulhu $4,big_external_data_label
+ ulw $4,small_external_data_label
+ ush $4,big_external_common
+ usw $4,small_external_common
+ ulh $4,big_local_common
+ ulhu $4,small_local_common
+ ulw $4,data_label+1
+ ush $4,big_external_data_label+1
+ usw $4,small_external_data_label+1
+ ulh $4,big_external_common+1
+ ulhu $4,small_external_common+1
+ ulw $4,big_local_common+1
+ ush $4,small_local_common+1
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ .ifndef XGOT
+ nop
+ nop
+ .endif
diff --git a/gas/testsuite/gas/mips/ulh-svr4pic.d b/gas/testsuite/gas/mips/ulh-svr4pic.d
new file mode 100644
index 00000000000..86e33bd6bc5
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulh-svr4pic.d
@@ -0,0 +1,124 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ulh-svr4pic
+#as: -mips1 -KPIC -EB
+#source: ulh-pic.s
+
+# Test the unaligned load and store macros with -KPIC.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*0: R_MIPS_GOT16 .data
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> addiu \$at,\$at,0
+[ ]*8: R_MIPS_LO16 .data
+0+000c <[^>]*> lb \$a0,0\(\$at\)
+0+0010 <[^>]*> lbu \$at,1\(\$at\)
+0+0014 <[^>]*> sll \$a0,\$a0,0x8
+0+0018 <[^>]*> or \$a0,\$a0,\$at
+0+001c <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1c: R_MIPS_GOT16 big_external_data_label
+0+0020 <[^>]*> nop
+0+0024 <[^>]*> lbu \$a0,0\(\$at\)
+0+0028 <[^>]*> lbu \$at,1\(\$at\)
+0+002c <[^>]*> sll \$a0,\$a0,0x8
+0+0030 <[^>]*> or \$a0,\$a0,\$at
+0+0034 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*34: R_MIPS_GOT16 small_external_data_label
+0+0038 <[^>]*> nop
+0+003c <[^>]*> lwl \$a0,0\(\$at\)
+0+0040 <[^>]*> lwr \$a0,3\(\$at\)
+0+0044 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*44: R_MIPS_GOT16 big_external_common
+0+0048 <[^>]*> nop
+0+004c <[^>]*> sb \$a0,1\(\$at\)
+0+0050 <[^>]*> srl \$a0,\$a0,0x8
+0+0054 <[^>]*> sb \$a0,0\(\$at\)
+0+0058 <[^>]*> lbu \$at,1\(\$at\)
+0+005c <[^>]*> sll \$a0,\$a0,0x8
+0+0060 <[^>]*> or \$a0,\$a0,\$at
+0+0064 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*64: R_MIPS_GOT16 small_external_common
+0+0068 <[^>]*> nop
+0+006c <[^>]*> swl \$a0,0\(\$at\)
+0+0070 <[^>]*> swr \$a0,3\(\$at\)
+0+0074 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*74: R_MIPS_GOT16 .bss
+0+0078 <[^>]*> nop
+0+007c <[^>]*> addiu \$at,\$at,0
+[ ]*7c: R_MIPS_LO16 .bss
+0+0080 <[^>]*> lb \$a0,0\(\$at\)
+0+0084 <[^>]*> lbu \$at,1\(\$at\)
+0+0088 <[^>]*> sll \$a0,\$a0,0x8
+0+008c <[^>]*> or \$a0,\$a0,\$at
+0+0090 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*90: R_MIPS_GOT16 .bss
+0+0094 <[^>]*> nop
+0+0098 <[^>]*> addiu \$at,\$at,1000
+[ ]*98: R_MIPS_LO16 .bss
+0+009c <[^>]*> lbu \$a0,0\(\$at\)
+0+00a0 <[^>]*> lbu \$at,1\(\$at\)
+0+00a4 <[^>]*> sll \$a0,\$a0,0x8
+0+00a8 <[^>]*> or \$a0,\$a0,\$at
+0+00ac <[^>]*> lw \$at,0\(\$gp\)
+[ ]*ac: R_MIPS_GOT16 .data
+0+00b0 <[^>]*> nop
+0+00b4 <[^>]*> addiu \$at,\$at,0
+[ ]*b4: R_MIPS_LO16 .data
+0+00b8 <[^>]*> addiu \$at,\$at,1
+0+00bc <[^>]*> lwl \$a0,0\(\$at\)
+0+00c0 <[^>]*> lwr \$a0,3\(\$at\)
+0+00c4 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*c4: R_MIPS_GOT16 big_external_data_label
+0+00c8 <[^>]*> nop
+0+00cc <[^>]*> addiu \$at,\$at,1
+0+00d0 <[^>]*> sb \$a0,1\(\$at\)
+0+00d4 <[^>]*> srl \$a0,\$a0,0x8
+0+00d8 <[^>]*> sb \$a0,0\(\$at\)
+0+00dc <[^>]*> lbu \$at,1\(\$at\)
+0+00e0 <[^>]*> sll \$a0,\$a0,0x8
+0+00e4 <[^>]*> or \$a0,\$a0,\$at
+0+00e8 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*e8: R_MIPS_GOT16 small_external_data_label
+0+00ec <[^>]*> nop
+0+00f0 <[^>]*> addiu \$at,\$at,1
+0+00f4 <[^>]*> swl \$a0,0\(\$at\)
+0+00f8 <[^>]*> swr \$a0,3\(\$at\)
+0+00fc <[^>]*> lw \$at,0\(\$gp\)
+[ ]*fc: R_MIPS_GOT16 big_external_common
+0+0100 <[^>]*> nop
+0+0104 <[^>]*> addiu \$at,\$at,1
+0+0108 <[^>]*> lb \$a0,0\(\$at\)
+0+010c <[^>]*> lbu \$at,1\(\$at\)
+0+0110 <[^>]*> sll \$a0,\$a0,0x8
+0+0114 <[^>]*> or \$a0,\$a0,\$at
+0+0118 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*118: R_MIPS_GOT16 small_external_common
+0+011c <[^>]*> nop
+0+0120 <[^>]*> addiu \$at,\$at,1
+0+0124 <[^>]*> lbu \$a0,0\(\$at\)
+0+0128 <[^>]*> lbu \$at,1\(\$at\)
+0+012c <[^>]*> sll \$a0,\$a0,0x8
+0+0130 <[^>]*> or \$a0,\$a0,\$at
+0+0134 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*134: R_MIPS_GOT16 .bss
+0+0138 <[^>]*> nop
+0+013c <[^>]*> addiu \$at,\$at,0
+[ ]*13c: R_MIPS_LO16 .bss
+0+0140 <[^>]*> addiu \$at,\$at,1
+0+0144 <[^>]*> lwl \$a0,0\(\$at\)
+0+0148 <[^>]*> lwr \$a0,3\(\$at\)
+0+014c <[^>]*> lw \$at,0\(\$gp\)
+[ ]*14c: R_MIPS_GOT16 .bss
+0+0150 <[^>]*> nop
+0+0154 <[^>]*> addiu \$at,\$at,1000
+[ ]*154: R_MIPS_LO16 .bss
+0+0158 <[^>]*> addiu \$at,\$at,1
+0+015c <[^>]*> sb \$a0,1\(\$at\)
+0+0160 <[^>]*> srl \$a0,\$a0,0x8
+0+0164 <[^>]*> sb \$a0,0\(\$at\)
+0+0168 <[^>]*> lbu \$at,1\(\$at\)
+0+016c <[^>]*> sll \$a0,\$a0,0x8
+0+0170 <[^>]*> or \$a0,\$a0,\$at
+ ...
diff --git a/gas/testsuite/gas/mips/ulh-xgot.d b/gas/testsuite/gas/mips/ulh-xgot.d
new file mode 100644
index 00000000000..982f9ce5c7b
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulh-xgot.d
@@ -0,0 +1,154 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ulh-xgot
+#as: -mips1 -mcpu=r3000 -KPIC -xgot -EB --defsym XGOT=1
+#source: ulh-pic.s
+
+# Test the unaligned load and store macros with -KPIC -xgot.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*0: R_MIPS_GOT16 .data
+0+0004 <[^>]*> nop
+0+0008 <[^>]*> addiu \$at,\$at,0
+[ ]*8: R_MIPS_LO16 .data
+0+000c <[^>]*> nop
+0+0010 <[^>]*> lb \$a0,0\(\$at\)
+0+0014 <[^>]*> lbu \$at,1\(\$at\)
+0+0018 <[^>]*> sll \$a0,\$a0,0x8
+0+001c <[^>]*> or \$a0,\$a0,\$at
+0+0020 <[^>]*> lui \$at,0x0
+[ ]*20: R_MIPS_GOT_HI16 big_external_data_label
+0+0024 <[^>]*> addu \$at,\$at,\$gp
+0+0028 <[^>]*> lw \$at,0\(\$at\)
+[ ]*28: R_MIPS_GOT_LO16 big_external_data_label
+0+002c <[^>]*> nop
+0+0030 <[^>]*> lbu \$a0,0\(\$at\)
+0+0034 <[^>]*> lbu \$at,1\(\$at\)
+0+0038 <[^>]*> sll \$a0,\$a0,0x8
+0+003c <[^>]*> or \$a0,\$a0,\$at
+0+0040 <[^>]*> lui \$at,0x0
+[ ]*40: R_MIPS_GOT_HI16 small_external_data_label
+0+0044 <[^>]*> addu \$at,\$at,\$gp
+0+0048 <[^>]*> lw \$at,0\(\$at\)
+[ ]*48: R_MIPS_GOT_LO16 small_external_data_label
+0+004c <[^>]*> nop
+0+0050 <[^>]*> lwl \$a0,0\(\$at\)
+0+0054 <[^>]*> lwr \$a0,3\(\$at\)
+0+0058 <[^>]*> lui \$at,0x0
+[ ]*58: R_MIPS_GOT_HI16 big_external_common
+0+005c <[^>]*> addu \$at,\$at,\$gp
+0+0060 <[^>]*> lw \$at,0\(\$at\)
+[ ]*60: R_MIPS_GOT_LO16 big_external_common
+0+0064 <[^>]*> nop
+0+0068 <[^>]*> sb \$a0,1\(\$at\)
+0+006c <[^>]*> srl \$a0,\$a0,0x8
+0+0070 <[^>]*> sb \$a0,0\(\$at\)
+0+0074 <[^>]*> lbu \$at,1\(\$at\)
+0+0078 <[^>]*> sll \$a0,\$a0,0x8
+0+007c <[^>]*> or \$a0,\$a0,\$at
+0+0080 <[^>]*> lui \$at,0x0
+[ ]*80: R_MIPS_GOT_HI16 small_external_common
+0+0084 <[^>]*> addu \$at,\$at,\$gp
+0+0088 <[^>]*> lw \$at,0\(\$at\)
+[ ]*88: R_MIPS_GOT_LO16 small_external_common
+0+008c <[^>]*> nop
+0+0090 <[^>]*> swl \$a0,0\(\$at\)
+0+0094 <[^>]*> swr \$a0,3\(\$at\)
+0+0098 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*98: R_MIPS_GOT16 .bss
+0+009c <[^>]*> nop
+0+00a0 <[^>]*> addiu \$at,\$at,0
+[ ]*a0: R_MIPS_LO16 .bss
+0+00a4 <[^>]*> nop
+0+00a8 <[^>]*> lb \$a0,0\(\$at\)
+0+00ac <[^>]*> lbu \$at,1\(\$at\)
+0+00b0 <[^>]*> sll \$a0,\$a0,0x8
+0+00b4 <[^>]*> or \$a0,\$a0,\$at
+0+00b8 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*b8: R_MIPS_GOT16 .bss
+0+00bc <[^>]*> nop
+0+00c0 <[^>]*> addiu \$at,\$at,1000
+[ ]*c0: R_MIPS_LO16 .bss
+0+00c4 <[^>]*> nop
+0+00c8 <[^>]*> lbu \$a0,0\(\$at\)
+0+00cc <[^>]*> lbu \$at,1\(\$at\)
+0+00d0 <[^>]*> sll \$a0,\$a0,0x8
+0+00d4 <[^>]*> or \$a0,\$a0,\$at
+0+00d8 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*d8: R_MIPS_GOT16 .data
+0+00dc <[^>]*> nop
+0+00e0 <[^>]*> addiu \$at,\$at,0
+[ ]*e0: R_MIPS_LO16 .data
+0+00e4 <[^>]*> nop
+0+00e8 <[^>]*> addiu \$at,\$at,1
+0+00ec <[^>]*> lwl \$a0,0\(\$at\)
+0+00f0 <[^>]*> lwr \$a0,3\(\$at\)
+0+00f4 <[^>]*> lui \$at,0x0
+[ ]*f4: R_MIPS_GOT_HI16 big_external_data_label
+0+00f8 <[^>]*> addu \$at,\$at,\$gp
+0+00fc <[^>]*> lw \$at,0\(\$at\)
+[ ]*fc: R_MIPS_GOT_LO16 big_external_data_label
+0+0100 <[^>]*> nop
+0+0104 <[^>]*> addiu \$at,\$at,1
+0+0108 <[^>]*> sb \$a0,1\(\$at\)
+0+010c <[^>]*> srl \$a0,\$a0,0x8
+0+0110 <[^>]*> sb \$a0,0\(\$at\)
+0+0114 <[^>]*> lbu \$at,1\(\$at\)
+0+0118 <[^>]*> sll \$a0,\$a0,0x8
+0+011c <[^>]*> or \$a0,\$a0,\$at
+0+0120 <[^>]*> lui \$at,0x0
+[ ]*120: R_MIPS_GOT_HI16 small_external_data_label
+0+0124 <[^>]*> addu \$at,\$at,\$gp
+0+0128 <[^>]*> lw \$at,0\(\$at\)
+[ ]*128: R_MIPS_GOT_LO16 small_external_data_label
+0+012c <[^>]*> nop
+0+0130 <[^>]*> addiu \$at,\$at,1
+0+0134 <[^>]*> swl \$a0,0\(\$at\)
+0+0138 <[^>]*> swr \$a0,3\(\$at\)
+0+013c <[^>]*> lui \$at,0x0
+[ ]*13c: R_MIPS_GOT_HI16 big_external_common
+0+0140 <[^>]*> addu \$at,\$at,\$gp
+0+0144 <[^>]*> lw \$at,0\(\$at\)
+[ ]*144: R_MIPS_GOT_LO16 big_external_common
+0+0148 <[^>]*> nop
+0+014c <[^>]*> addiu \$at,\$at,1
+0+0150 <[^>]*> lb \$a0,0\(\$at\)
+0+0154 <[^>]*> lbu \$at,1\(\$at\)
+0+0158 <[^>]*> sll \$a0,\$a0,0x8
+0+015c <[^>]*> or \$a0,\$a0,\$at
+0+0160 <[^>]*> lui \$at,0x0
+[ ]*160: R_MIPS_GOT_HI16 small_external_common
+0+0164 <[^>]*> addu \$at,\$at,\$gp
+0+0168 <[^>]*> lw \$at,0\(\$at\)
+[ ]*168: R_MIPS_GOT_LO16 small_external_common
+0+016c <[^>]*> nop
+0+0170 <[^>]*> addiu \$at,\$at,1
+0+0174 <[^>]*> lbu \$a0,0\(\$at\)
+0+0178 <[^>]*> lbu \$at,1\(\$at\)
+0+017c <[^>]*> sll \$a0,\$a0,0x8
+0+0180 <[^>]*> or \$a0,\$a0,\$at
+0+0184 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*184: R_MIPS_GOT16 .bss
+0+0188 <[^>]*> nop
+0+018c <[^>]*> addiu \$at,\$at,0
+[ ]*18c: R_MIPS_LO16 .bss
+0+0190 <[^>]*> nop
+0+0194 <[^>]*> addiu \$at,\$at,1
+0+0198 <[^>]*> lwl \$a0,0\(\$at\)
+0+019c <[^>]*> lwr \$a0,3\(\$at\)
+0+01a0 <[^>]*> lw \$at,0\(\$gp\)
+[ ]*1a0: R_MIPS_GOT16 .bss
+0+01a4 <[^>]*> nop
+0+01a8 <[^>]*> addiu \$at,\$at,1000
+[ ]*1a8: R_MIPS_LO16 .bss
+0+01ac <[^>]*> nop
+0+01b0 <[^>]*> addiu \$at,\$at,1
+0+01b4 <[^>]*> sb \$a0,1\(\$at\)
+0+01b8 <[^>]*> srl \$a0,\$a0,0x8
+0+01bc <[^>]*> sb \$a0,0\(\$at\)
+0+01c0 <[^>]*> lbu \$at,1\(\$at\)
+0+01c4 <[^>]*> sll \$a0,\$a0,0x8
+0+01c8 <[^>]*> or \$a0,\$a0,\$at
+0+01cc <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/ulh.d b/gas/testsuite/gas/mips/ulh.d
new file mode 100644
index 00000000000..8d6d4b45020
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulh.d
@@ -0,0 +1,374 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ulh
+#as: -mips1
+
+# Test the ulh macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lb \$a0,[01]\(\$zero\)
+0+0004 <[^>]*> lbu \$at,[01]\(\$zero\)
+0+0008 <[^>]*> sll \$a0,\$a0,0x8
+0+000c <[^>]*> or \$a0,\$a0,\$at
+0+0010 <[^>]*> lb \$a0,[12]\(\$zero\)
+0+0014 <[^>]*> lbu \$at,[12]\(\$zero\)
+0+0018 <[^>]*> sll \$a0,\$a0,0x8
+0+001c <[^>]*> or \$a0,\$a0,\$at
+0+0020 <[^>]*> li \$at,0x8000
+0+0024 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0028 <[^>]*> lbu \$at,[01]\(\$at\)
+0+002c <[^>]*> sll \$a0,\$a0,0x8
+0+0030 <[^>]*> or \$a0,\$a0,\$at
+0+0034 <[^>]*> lb \$a0,-3276[78]\(\$zero\)
+0+0038 <[^>]*> lbu \$at,-3276[78]\(\$zero\)
+0+003c <[^>]*> sll \$a0,\$a0,0x8
+0+0040 <[^>]*> or \$a0,\$a0,\$at
+0+0044 <[^>]*> lui \$at,0x1
+0+0048 <[^>]*> lb \$a0,[01]\(\$at\)
+0+004c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0050 <[^>]*> sll \$a0,\$a0,0x8
+0+0054 <[^>]*> or \$a0,\$a0,\$at
+0+0058 <[^>]*> lui \$at,0x1
+0+005c <[^>]*> ori \$at,\$at,0xa5a5
+0+0060 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0064 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0068 <[^>]*> sll \$a0,\$a0,0x8
+0+006c <[^>]*> or \$a0,\$a0,\$at
+0+0070 <[^>]*> lb \$a0,[01]\(\$a1\)
+0+0074 <[^>]*> lbu \$at,[01]\(\$a1\)
+0+0078 <[^>]*> sll \$a0,\$a0,0x8
+0+007c <[^>]*> or \$a0,\$a0,\$at
+0+0080 <[^>]*> lb \$a0,[12]\(\$a1\)
+0+0084 <[^>]*> lbu \$at,[12]\(\$a1\)
+0+0088 <[^>]*> sll \$a0,\$a0,0x8
+0+008c <[^>]*> or \$a0,\$a0,\$at
+0+0090 <[^>]*> lui \$at,[-0-9x]+
+[ ]*90: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0094 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*94: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0098 <[^>]*> lb \$a0,[01]\(\$at\)
+0+009c <[^>]*> lbu \$at,[01]\(\$at\)
+0+00a0 <[^>]*> sll \$a0,\$a0,0x8
+0+00a4 <[^>]*> or \$a0,\$a0,\$at
+0+00a8 <[^>]*> lui \$at,0x0
+[ ]*a8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00ac <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*ac: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00b0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+00b4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00b8 <[^>]*> sll \$a0,\$a0,0x8
+0+00bc <[^>]*> or \$a0,\$a0,\$at
+0+00c0 <[^>]*> addiu \$at,\$gp,0
+[ ]*c0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00c4 <[^>]*> lb \$a0,[01]\(\$at\)
+0+00c8 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00cc <[^>]*> sll \$a0,\$a0,0x8
+0+00d0 <[^>]*> or \$a0,\$a0,\$at
+0+00d4 <[^>]*> lui \$at,0x0
+[ ]*d4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00d8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*d8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00dc <[^>]*> lb \$a0,[01]\(\$at\)
+0+00e0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00e4 <[^>]*> sll \$a0,\$a0,0x8
+0+00e8 <[^>]*> or \$a0,\$a0,\$at
+0+00ec <[^>]*> addiu \$at,\$gp,0
+[ ]*ec: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00f0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+00f4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00f8 <[^>]*> sll \$a0,\$a0,0x8
+0+00fc <[^>]*> or \$a0,\$a0,\$at
+0+0100 <[^>]*> lui \$at,[-0-9x]+
+[ ]*100: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*104: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0108 <[^>]*> lb \$a0,[01]\(\$at\)
+0+010c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0110 <[^>]*> sll \$a0,\$a0,0x8
+0+0114 <[^>]*> or \$a0,\$a0,\$at
+0+0118 <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*118: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+011c <[^>]*> lb \$a0,[01]\(\$at\)
+0+0120 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0124 <[^>]*> sll \$a0,\$a0,0x8
+0+0128 <[^>]*> or \$a0,\$a0,\$at
+0+012c <[^>]*> lui \$at,0x0
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0130 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0134 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0138 <[^>]*> lbu \$at,[01]\(\$at\)
+0+013c <[^>]*> sll \$a0,\$a0,0x8
+0+0140 <[^>]*> or \$a0,\$a0,\$at
+0+0144 <[^>]*> lui \$at,0x0
+[ ]*144: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0148 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*148: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+014c <[^>]*> lb \$a0,[01]\(\$at\)
+0+0150 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0154 <[^>]*> sll \$a0,\$a0,0x8
+0+0158 <[^>]*> or \$a0,\$a0,\$at
+0+015c <[^>]*> addiu \$at,\$gp,1
+[ ]*15c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0160 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0164 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0168 <[^>]*> sll \$a0,\$a0,0x8
+0+016c <[^>]*> or \$a0,\$a0,\$at
+0+0170 <[^>]*> lui \$at,0x0
+[ ]*170: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0174 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*174: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0178 <[^>]*> lb \$a0,[01]\(\$at\)
+0+017c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0180 <[^>]*> sll \$a0,\$a0,0x8
+0+0184 <[^>]*> or \$a0,\$a0,\$at
+0+0188 <[^>]*> addiu \$at,\$gp,1
+[ ]*188: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+018c <[^>]*> lb \$a0,[01]\(\$at\)
+0+0190 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0194 <[^>]*> sll \$a0,\$a0,0x8
+0+0198 <[^>]*> or \$a0,\$a0,\$at
+0+019c <[^>]*> lui \$at,0x0
+[ ]*19c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01a0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1a0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01a4 <[^>]*> lb \$a0,[01]\(\$at\)
+0+01a8 <[^>]*> lbu \$at,[01]\(\$at\)
+0+01ac <[^>]*> sll \$a0,\$a0,0x8
+0+01b0 <[^>]*> or \$a0,\$a0,\$at
+0+01b4 <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*1b4: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+01b8 <[^>]*> lb \$a0,[01]\(\$at\)
+0+01bc <[^>]*> lbu \$at,[01]\(\$at\)
+0+01c0 <[^>]*> sll \$a0,\$a0,0x8
+0+01c4 <[^>]*> or \$a0,\$a0,\$at
+0+01c8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01cc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+01d0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+01d4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+01d8 <[^>]*> sll \$a0,\$a0,0x8
+0+01dc <[^>]*> or \$a0,\$a0,\$at
+0+01e0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+01e4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01e8 <[^>]*> lb \$a0,[01]\(\$at\)
+0+01ec <[^>]*> lbu \$at,[01]\(\$at\)
+0+01f0 <[^>]*> sll \$a0,\$a0,0x8
+0+01f4 <[^>]*> or \$a0,\$a0,\$at
+0+01f8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01fc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0200 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0204 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0208 <[^>]*> sll \$a0,\$a0,0x8
+0+020c <[^>]*> or \$a0,\$a0,\$at
+0+0210 <[^>]*> lui \$at,[-0-9x]+
+[ ]*210: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0214 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*214: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0218 <[^>]*> lb \$a0,[01]\(\$at\)
+0+021c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0220 <[^>]*> sll \$a0,\$a0,0x8
+0+0224 <[^>]*> or \$a0,\$a0,\$at
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+022c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0230 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0234 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0238 <[^>]*> sll \$a0,\$a0,0x8
+0+023c <[^>]*> or \$a0,\$a0,\$at
+0+0240 <[^>]*> lui \$at,[-0-9x]+
+[ ]*240: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0244 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*244: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0248 <[^>]*> lb \$a0,[01]\(\$at\)
+0+024c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0250 <[^>]*> sll \$a0,\$a0,0x8
+0+0254 <[^>]*> or \$a0,\$a0,\$at
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0264 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0268 <[^>]*> sll \$a0,\$a0,0x8
+0+026c <[^>]*> or \$a0,\$a0,\$at
+0+0270 <[^>]*> lui \$at,0x0
+[ ]*270: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0274 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*274: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0278 <[^>]*> lb \$a0,[01]\(\$at\)
+0+027c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0280 <[^>]*> sll \$a0,\$a0,0x8
+0+0284 <[^>]*> or \$a0,\$a0,\$at
+0+0288 <[^>]*> lui \$at,0x0
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+028c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*28c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0290 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0294 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0298 <[^>]*> sll \$a0,\$a0,0x8
+0+029c <[^>]*> or \$a0,\$a0,\$at
+0+02a0 <[^>]*> lui \$at,0x0
+[ ]*2a0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+02a4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2a4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+02a8 <[^>]*> lb \$a0,[01]\(\$at\)
+0+02ac <[^>]*> lbu \$at,[01]\(\$at\)
+0+02b0 <[^>]*> sll \$a0,\$a0,0x8
+0+02b4 <[^>]*> or \$a0,\$a0,\$at
+0+02b8 <[^>]*> lui \$at,0x0
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02bc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2bc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02c0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+02c4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+02c8 <[^>]*> sll \$a0,\$a0,0x8
+0+02cc <[^>]*> or \$a0,\$a0,\$at
+0+02d0 <[^>]*> lui \$at,0x0
+[ ]*2d0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02d4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2d4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02d8 <[^>]*> lb \$a0,[01]\(\$at\)
+0+02dc <[^>]*> lbu \$at,[01]\(\$at\)
+0+02e0 <[^>]*> sll \$a0,\$a0,0x8
+0+02e4 <[^>]*> or \$a0,\$a0,\$at
+0+02e8 <[^>]*> lui \$at,0x0
+[ ]*2e8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02ec <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2ec: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02f0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+02f4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+02f8 <[^>]*> sll \$a0,\$a0,0x8
+0+02fc <[^>]*> or \$a0,\$a0,\$at
+0+0300 <[^>]*> lui \$at,0x0
+[ ]*300: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0304 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*304: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0308 <[^>]*> lb \$a0,[01]\(\$at\)
+0+030c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0310 <[^>]*> sll \$a0,\$a0,0x8
+0+0314 <[^>]*> or \$a0,\$a0,\$at
+0+0318 <[^>]*> lui \$at,[-0-9x]+
+[ ]*318: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+031c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*31c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0320 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0324 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0328 <[^>]*> sll \$a0,\$a0,0x8
+0+032c <[^>]*> or \$a0,\$a0,\$at
+0+0330 <[^>]*> lui \$at,[-0-9x]+
+[ ]*330: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0334 <[^>]*> addiu \$at,\$at,0
+[ ]*334: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0338 <[^>]*> lb \$a0,[01]\(\$at\)
+0+033c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0340 <[^>]*> sll \$a0,\$a0,0x8
+0+0344 <[^>]*> or \$a0,\$a0,\$at
+0+0348 <[^>]*> lui \$at,[-0-9x]+
+[ ]*348: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+034c <[^>]*> addiu \$at,\$at,0
+[ ]*34c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0350 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0354 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0358 <[^>]*> sll \$a0,\$a0,0x8
+0+035c <[^>]*> or \$a0,\$a0,\$at
+0+0360 <[^>]*> lui \$at,[-0-9x]+
+[ ]*360: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0364 <[^>]*> addiu \$at,\$at,0
+[ ]*364: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0368 <[^>]*> lb \$a0,[01]\(\$at\)
+0+036c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0370 <[^>]*> sll \$a0,\$a0,0x8
+0+0374 <[^>]*> or \$a0,\$a0,\$at
+0+0378 <[^>]*> lui \$at,[-0-9x]+
+[ ]*378: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+037c <[^>]*> addiu \$at,\$at,0
+[ ]*37c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0380 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0384 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0388 <[^>]*> sll \$a0,\$a0,0x8
+0+038c <[^>]*> or \$a0,\$a0,\$at
+0+0390 <[^>]*> lui \$at,[-0-9x]+
+[ ]*390: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0394 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*394: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0398 <[^>]*> lb \$a0,[01]\(\$at\)
+0+039c <[^>]*> lbu \$at,[01]\(\$at\)
+0+03a0 <[^>]*> sll \$a0,\$a0,0x8
+0+03a4 <[^>]*> or \$a0,\$a0,\$at
+0+03a8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*3a8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+03ac <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3ac: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+03b0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+03b4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+03b8 <[^>]*> sll \$a0,\$a0,0x8
+0+03bc <[^>]*> or \$a0,\$a0,\$at
+0+03c0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*3c0: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+03c4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3c4: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+03c8 <[^>]*> lb \$a0,[01]\(\$at\)
+0+03cc <[^>]*> lbu \$at,[01]\(\$at\)
+0+03d0 <[^>]*> sll \$a0,\$a0,0x8
+0+03d4 <[^>]*> or \$a0,\$a0,\$at
+0+03d8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*3d8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+03dc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3dc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+03e0 <[^>]*> lb \$a0,[01]\(\$at\)
+0+03e4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+03e8 <[^>]*> sll \$a0,\$a0,0x8
+0+03ec <[^>]*> or \$a0,\$a0,\$at
+0+03f0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*3f0: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+03f4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3f4: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+03f8 <[^>]*> lb \$a0,[01]\(\$at\)
+0+03fc <[^>]*> lbu \$at,[01]\(\$at\)
+0+0400 <[^>]*> sll \$a0,\$a0,0x8
+0+0404 <[^>]*> or \$a0,\$a0,\$at
+0+0408 <[^>]*> lui \$at,[-0-9x]+
+[ ]*408: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+040c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*40c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0410 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0414 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0418 <[^>]*> sll \$a0,\$a0,0x8
+0+041c <[^>]*> or \$a0,\$a0,\$at
+0+0420 <[^>]*> lui \$at,[-0-9x]+
+[ ]*420: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0424 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*424: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0428 <[^>]*> lb \$a0,[01]\(\$at\)
+0+042c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0430 <[^>]*> sll \$a0,\$a0,0x8
+0+0434 <[^>]*> or \$a0,\$a0,\$at
+0+0438 <[^>]*> lui \$at,[-0-9x]+
+[ ]*438: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+043c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*43c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0440 <[^>]*> lb \$a0,[01]\(\$at\)
+0+0444 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0448 <[^>]*> sll \$a0,\$a0,0x8
+0+044c <[^>]*> or \$a0,\$a0,\$at
+0+0450 <[^>]*> lui \$at,[-0-9x]+
+[ ]*450: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0454 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*454: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0458 <[^>]*> lb \$a0,[01]\(\$at\)
+0+045c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0460 <[^>]*> sll \$a0,\$a0,0x8
+0+0464 <[^>]*> or \$a0,\$a0,\$at
+0+0468 <[^>]*> lbu \$a0,[01]\(\$zero\)
+0+046c <[^>]*> lbu \$at,[01]\(\$zero\)
+0+0470 <[^>]*> sll \$a0,\$a0,0x8
+0+0474 <[^>]*> or \$a0,\$a0,\$at
+ ...
diff --git a/gas/testsuite/gas/mips/ulh.s b/gas/testsuite/gas/mips/ulh.s
new file mode 100644
index 00000000000..26ecbb9473a
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulh.s
@@ -0,0 +1,69 @@
+# Source file used to test the ulh macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ ulh $4,0
+ ulh $4,1
+ ulh $4,0x8000
+ ulh $4,-0x8000
+ ulh $4,0x10000
+ ulh $4,0x1a5a5
+ ulh $4,0($5)
+ ulh $4,1($5)
+ ulh $4,data_label
+ ulh $4,big_external_data_label
+ ulh $4,small_external_data_label
+ ulh $4,big_external_common
+ ulh $4,small_external_common
+ ulh $4,big_local_common
+ ulh $4,small_local_common
+ ulh $4,data_label+1
+ ulh $4,big_external_data_label+1
+ ulh $4,small_external_data_label+1
+ ulh $4,big_external_common+1
+ ulh $4,small_external_common+1
+ ulh $4,big_local_common+1
+ ulh $4,small_local_common+1
+ ulh $4,data_label+0x8000
+ ulh $4,big_external_data_label+0x8000
+ ulh $4,small_external_data_label+0x8000
+ ulh $4,big_external_common+0x8000
+ ulh $4,small_external_common+0x8000
+ ulh $4,big_local_common+0x8000
+ ulh $4,small_local_common+0x8000
+ ulh $4,data_label-0x8000
+ ulh $4,big_external_data_label-0x8000
+ ulh $4,small_external_data_label-0x8000
+ ulh $4,big_external_common-0x8000
+ ulh $4,small_external_common-0x8000
+ ulh $4,big_local_common-0x8000
+ ulh $4,small_local_common-0x8000
+ ulh $4,data_label+0x10000
+ ulh $4,big_external_data_label+0x10000
+ ulh $4,small_external_data_label+0x10000
+ ulh $4,big_external_common+0x10000
+ ulh $4,small_external_common+0x10000
+ ulh $4,big_local_common+0x10000
+ ulh $4,small_local_common+0x10000
+ ulh $4,data_label+0x1a5a5
+ ulh $4,big_external_data_label+0x1a5a5
+ ulh $4,small_external_data_label+0x1a5a5
+ ulh $4,big_external_common+0x1a5a5
+ ulh $4,small_external_common+0x1a5a5
+ ulh $4,big_local_common+0x1a5a5
+ ulh $4,small_local_common+0x1a5a5
+
+# ulhu is handled like ulh. Sanity check it.
+ ulhu $4,0
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/ulw.d b/gas/testsuite/gas/mips/ulw.d
new file mode 100644
index 00000000000..bfbdc94df04
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulw.d
@@ -0,0 +1,270 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ulw
+#as: -mips1
+
+# Test the ulw macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> lwl \$a0,[03]\(\$zero\)
+0+0004 <[^>]*> lwr \$a0,[03]\(\$zero\)
+0+0008 <[^>]*> lwl \$a0,[14]\(\$zero\)
+0+000c <[^>]*> lwr \$a0,[14]\(\$zero\)
+0+0010 <[^>]*> li \$at,0x8000
+0+0014 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0018 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+001c <[^>]*> lwl \$a0,-3276[58]\(\$zero\)
+0+0020 <[^>]*> lwr \$a0,-3276[58]\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+002c <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0030 <[^>]*> lui \$at,0x1
+0+0034 <[^>]*> ori \$at,\$at,0xa5a5
+0+0038 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+003c <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0040 <[^>]*> lwl \$a0,[03]\(\$a1\)
+0+0044 <[^>]*> lwr \$a0,[03]\(\$a1\)
+0+0048 <[^>]*> lwl \$a0,[14]\(\$a1\)
+0+004c <[^>]*> lwr \$a0,[-0-9]+\(\$a1\)
+0+0050 <[^>]*> lui \$at,[-0-9x]+
+[ ]*50: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0054 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*54: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0058 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+005c <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0060 <[^>]*> lui \$at,0x0
+[ ]*60: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0064 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*64: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0068 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+006c <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0070 <[^>]*> addiu \$at,\$gp,0
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0074 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0078 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+007c <[^>]*> lui \$at,0x0
+[ ]*7c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0080 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*80: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0084 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0088 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+008c <[^>]*> addiu \$at,\$gp,0
+[ ]*8c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0090 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0094 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0098 <[^>]*> lui \$at,[-0-9x]+
+[ ]*98: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+009c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*9c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00a4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00a8 <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ac <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00b0 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00b4 <[^>]*> lui \$at,0x0
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00b8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00bc <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00c0 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00c4 <[^>]*> lui \$at,0x0
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00c8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00cc <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00d0 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00d4 <[^>]*> addiu \$at,\$gp,1
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00d8 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00dc <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00e0 <[^>]*> lui \$at,0x0
+[ ]*e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00e4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00e8 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00ec <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00f0 <[^>]*> addiu \$at,\$gp,1
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00f4 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+00f8 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+00fc <[^>]*> lui \$at,0x0
+[ ]*fc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0100 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0108 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+010c <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0110 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0114 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0118 <[^>]*> lui \$at,[-0-9x]+
+[ ]*118: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+011c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0124 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0128 <[^>]*> lui \$at,[-0-9x]+
+[ ]*128: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*12c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0130 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0134 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0138 <[^>]*> lui \$at,[-0-9x]+
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+013c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0140 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0144 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0148 <[^>]*> lui \$at,[-0-9x]+
+[ ]*148: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+014c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0150 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0154 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0158 <[^>]*> lui \$at,[-0-9x]+
+[ ]*158: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+015c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*15c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0160 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0164 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0168 <[^>]*> lui \$at,[-0-9x]+
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+016c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0170 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0174 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0178 <[^>]*> lui \$at,[-0-9x]+
+[ ]*178: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+017c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0180 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0184 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0188 <[^>]*> lui \$at,0x0
+[ ]*188: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+018c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*18c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0190 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0194 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01a0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+01a4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+01a8 <[^>]*> lui \$at,0x0
+[ ]*1a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01b0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+01b4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+01b8 <[^>]*> lui \$at,0x0
+[ ]*1b8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01bc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1bc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01c0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+01c4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+01c8 <[^>]*> lui \$at,0x0
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01cc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01d0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+01d4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+01d8 <[^>]*> lui \$at,0x0
+[ ]*1d8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01dc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01e0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+01e4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+01e8 <[^>]*> lui \$at,0x0
+[ ]*1e8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01ec <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1ec: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01f0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+01f4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+01f8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01fc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0200 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0204 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0208 <[^>]*> lui \$at,[-0-9x]+
+[ ]*208: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+020c <[^>]*> addiu \$at,\$at,0
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0210 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0214 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0218 <[^>]*> lui \$at,[-0-9x]+
+[ ]*218: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+021c <[^>]*> addiu \$at,\$at,0
+[ ]*21c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0220 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0224 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+022c <[^>]*> addiu \$at,\$at,0
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0230 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0234 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0238 <[^>]*> lui \$at,[-0-9x]+
+[ ]*238: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+023c <[^>]*> addiu \$at,\$at,0
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0240 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0244 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0248 <[^>]*> lui \$at,[-0-9x]+
+[ ]*248: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+024c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*24c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0250 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0254 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0264 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0268 <[^>]*> lui \$at,[-0-9x]+
+[ ]*268: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+026c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0270 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0274 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0278 <[^>]*> lui \$at,[-0-9x]+
+[ ]*278: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+027c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0284 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0288 <[^>]*> lui \$at,[-0-9x]+
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*28c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0290 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+0294 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+0298 <[^>]*> lui \$at,[-0-9x]+
+[ ]*298: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+029c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+02a4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+02a8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02b0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+02b4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+02b8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02bc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2bc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02c0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+02c4 <[^>]*> lwr \$a0,[03]\(\$at\)
+0+02c8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2c8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02cc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02d0 <[^>]*> lwl \$a0,[03]\(\$at\)
+0+02d4 <[^>]*> lwr \$a0,[03]\(\$at\)
+ ...
diff --git a/gas/testsuite/gas/mips/ulw.s b/gas/testsuite/gas/mips/ulw.s
new file mode 100644
index 00000000000..3a36f1c0b5f
--- /dev/null
+++ b/gas/testsuite/gas/mips/ulw.s
@@ -0,0 +1,66 @@
+# Source file used to test the ulw macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ ulw $4,0
+ ulw $4,1
+ ulw $4,0x8000
+ ulw $4,-0x8000
+ ulw $4,0x10000
+ ulw $4,0x1a5a5
+ ulw $4,0($5)
+ ulw $4,1($5)
+ ulw $4,data_label
+ ulw $4,big_external_data_label
+ ulw $4,small_external_data_label
+ ulw $4,big_external_common
+ ulw $4,small_external_common
+ ulw $4,big_local_common
+ ulw $4,small_local_common
+ ulw $4,data_label+1
+ ulw $4,big_external_data_label+1
+ ulw $4,small_external_data_label+1
+ ulw $4,big_external_common+1
+ ulw $4,small_external_common+1
+ ulw $4,big_local_common+1
+ ulw $4,small_local_common+1
+ ulw $4,data_label+0x8000
+ ulw $4,big_external_data_label+0x8000
+ ulw $4,small_external_data_label+0x8000
+ ulw $4,big_external_common+0x8000
+ ulw $4,small_external_common+0x8000
+ ulw $4,big_local_common+0x8000
+ ulw $4,small_local_common+0x8000
+ ulw $4,data_label-0x8000
+ ulw $4,big_external_data_label-0x8000
+ ulw $4,small_external_data_label-0x8000
+ ulw $4,big_external_common-0x8000
+ ulw $4,small_external_common-0x8000
+ ulw $4,big_local_common-0x8000
+ ulw $4,small_local_common-0x8000
+ ulw $4,data_label+0x10000
+ ulw $4,big_external_data_label+0x10000
+ ulw $4,small_external_data_label+0x10000
+ ulw $4,big_external_common+0x10000
+ ulw $4,small_external_common+0x10000
+ ulw $4,big_local_common+0x10000
+ ulw $4,small_local_common+0x10000
+ ulw $4,data_label+0x1a5a5
+ ulw $4,big_external_data_label+0x1a5a5
+ ulw $4,small_external_data_label+0x1a5a5
+ ulw $4,big_external_common+0x1a5a5
+ ulw $4,small_external_common+0x1a5a5
+ ulw $4,big_local_common+0x1a5a5
+ ulw $4,small_local_common+0x1a5a5
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/usd.d b/gas/testsuite/gas/mips/usd.d
new file mode 100644
index 00000000000..63c0b73b63a
--- /dev/null
+++ b/gas/testsuite/gas/mips/usd.d
@@ -0,0 +1,270 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#name: MIPS usd
+#as: -mips3 -mcpu=r4000
+
+# Test the usd macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> sdl \$a0,[07]\(\$zero\)
+0+0004 <[^>]*> sdr \$a0,[07]\(\$zero\)
+0+0008 <[^>]*> sdl \$a0,[18]\(\$zero\)
+0+000c <[^>]*> sdr \$a0,[18]\(\$zero\)
+0+0010 <[^>]*> li \$at,0x8000
+0+0014 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0018 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+001c <[^>]*> sdl \$a0,-3276[18]\(\$zero\)
+0+0020 <[^>]*> sdr \$a0,-3276[18]\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+002c <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0030 <[^>]*> lui \$at,0x1
+0+0034 <[^>]*> ori \$at,\$at,0xa5a5
+0+0038 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+003c <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0040 <[^>]*> sdl \$a0,[07]\(\$a1\)
+0+0044 <[^>]*> sdr \$a0,[07]\(\$a1\)
+0+0048 <[^>]*> sdl \$a0,[18]\(\$a1\)
+0+004c <[^>]*> sdr \$a0,[-0-9]+\(\$a1\)
+0+0050 <[^>]*> lui \$at,[-0-9x]+
+[ ]*50: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0054 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*54: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0058 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+005c <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0060 <[^>]*> lui \$at,[-0-9x]+
+[ ]*60: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0064 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*64: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0068 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+006c <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0070 <[^>]*> daddiu \$at,\$gp,0
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0074 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0078 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+007c <[^>]*> lui \$at,0x0
+[ ]*7c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0080 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*80: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0084 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0088 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+008c <[^>]*> daddiu \$at,\$gp,0
+[ ]*8c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0090 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0094 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0098 <[^>]*> lui \$at,[-0-9x]+
+[ ]*98: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+009c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*9c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00a4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00a8 <[^>]*> daddiu \$at,\$gp,[-0-9]+
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ac <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00b0 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00b4 <[^>]*> lui \$at,0x0
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00b8 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00bc <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00c0 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00c4 <[^>]*> lui \$at,0x0
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00c8 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00cc <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00d0 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00d4 <[^>]*> daddiu \$at,\$gp,1
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00d8 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00dc <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00e0 <[^>]*> lui \$at,0x0
+[ ]*e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00e4 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00e8 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00ec <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00f0 <[^>]*> daddiu \$at,\$gp,1
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00f4 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+00f8 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+00fc <[^>]*> lui \$at,0x0
+[ ]*fc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0100 <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0108 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+010c <[^>]*> daddiu \$at,\$gp,[-0-9]+
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0110 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0114 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0118 <[^>]*> lui \$at,[-0-9x]+
+[ ]*118: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+011c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0124 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0128 <[^>]*> lui \$at,[-0-9x]+
+[ ]*128: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*12c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0130 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0134 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0138 <[^>]*> lui \$at,[-0-9x]+
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+013c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0140 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0144 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0148 <[^>]*> lui \$at,[-0-9x]+
+[ ]*148: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+014c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0150 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0154 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0158 <[^>]*> lui \$at,[-0-9x]+
+[ ]*158: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+015c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*15c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0160 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0164 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0168 <[^>]*> lui \$at,[-0-9x]+
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+016c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0170 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0174 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0178 <[^>]*> lui \$at,[-0-9x]+
+[ ]*178: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+017c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0180 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0184 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0188 <[^>]*> lui \$at,0x0
+[ ]*188: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+018c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*18c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0190 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0194 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01a0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+01a4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+01a8 <[^>]*> lui \$at,0x0
+[ ]*1a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01b0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+01b4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+01b8 <[^>]*> lui \$at,0x0
+[ ]*1b8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01bc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1bc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01c0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+01c4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+01c8 <[^>]*> lui \$at,0x0
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01cc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01d0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+01d4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+01d8 <[^>]*> lui \$at,0x0
+[ ]*1d8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01dc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01e0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+01e4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+01e8 <[^>]*> lui \$at,0x0
+[ ]*1e8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01ec <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1ec: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01f0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+01f4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+01f8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01fc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0200 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0204 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0208 <[^>]*> lui \$at,[-0-9x]+
+[ ]*208: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+020c <[^>]*> daddiu \$at,\$at,0
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0210 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0214 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0218 <[^>]*> lui \$at,[-0-9x]+
+[ ]*218: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+021c <[^>]*> daddiu \$at,\$at,0
+[ ]*21c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0220 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0224 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+022c <[^>]*> daddiu \$at,\$at,0
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0230 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0234 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0238 <[^>]*> lui \$at,[-0-9x]+
+[ ]*238: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+023c <[^>]*> daddiu \$at,\$at,0
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0240 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0244 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0248 <[^>]*> lui \$at,[-0-9x]+
+[ ]*248: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+024c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*24c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0250 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0254 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0264 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0268 <[^>]*> lui \$at,[-0-9x]+
+[ ]*268: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+026c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0270 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0274 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0278 <[^>]*> lui \$at,[-0-9x]+
+[ ]*278: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+027c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0284 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0288 <[^>]*> lui \$at,[-0-9x]+
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*28c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0290 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+0294 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+0298 <[^>]*> lui \$at,[-0-9x]+
+[ ]*298: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+029c <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+02a4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+02a8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*2ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02b0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+02b4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+02b8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02bc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*2bc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02c0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+02c4 <[^>]*> sdr \$a0,[07]\(\$at\)
+0+02c8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2c8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02cc <[^>]*> daddiu \$at,\$at,[-0-9]+
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02d0 <[^>]*> sdl \$a0,[07]\(\$at\)
+0+02d4 <[^>]*> sdr \$a0,[07]\(\$at\)
+ ...
diff --git a/gas/testsuite/gas/mips/usd.s b/gas/testsuite/gas/mips/usd.s
new file mode 100644
index 00000000000..fd367351b70
--- /dev/null
+++ b/gas/testsuite/gas/mips/usd.s
@@ -0,0 +1,66 @@
+# Source file used to test the usd macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ usd $4,0
+ usd $4,1
+ usd $4,0x8000
+ usd $4,-0x8000
+ usd $4,0x10000
+ usd $4,0x1a5a5
+ usd $4,0($5)
+ usd $4,1($5)
+ usd $4,data_label
+ usd $4,big_external_data_label
+ usd $4,small_external_data_label
+ usd $4,big_external_common
+ usd $4,small_external_common
+ usd $4,big_local_common
+ usd $4,small_local_common
+ usd $4,data_label+1
+ usd $4,big_external_data_label+1
+ usd $4,small_external_data_label+1
+ usd $4,big_external_common+1
+ usd $4,small_external_common+1
+ usd $4,big_local_common+1
+ usd $4,small_local_common+1
+ usd $4,data_label+0x8000
+ usd $4,big_external_data_label+0x8000
+ usd $4,small_external_data_label+0x8000
+ usd $4,big_external_common+0x8000
+ usd $4,small_external_common+0x8000
+ usd $4,big_local_common+0x8000
+ usd $4,small_local_common+0x8000
+ usd $4,data_label-0x8000
+ usd $4,big_external_data_label-0x8000
+ usd $4,small_external_data_label-0x8000
+ usd $4,big_external_common-0x8000
+ usd $4,small_external_common-0x8000
+ usd $4,big_local_common-0x8000
+ usd $4,small_local_common-0x8000
+ usd $4,data_label+0x10000
+ usd $4,big_external_data_label+0x10000
+ usd $4,small_external_data_label+0x10000
+ usd $4,big_external_common+0x10000
+ usd $4,small_external_common+0x10000
+ usd $4,big_local_common+0x10000
+ usd $4,small_local_common+0x10000
+ usd $4,data_label+0x1a5a5
+ usd $4,big_external_data_label+0x1a5a5
+ usd $4,small_external_data_label+0x1a5a5
+ usd $4,big_external_common+0x1a5a5
+ usd $4,small_external_common+0x1a5a5
+ usd $4,big_local_common+0x1a5a5
+ usd $4,small_local_common+0x1a5a5
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mips/ush.d b/gas/testsuite/gas/mips/ush.d
new file mode 100644
index 00000000000..c2f0a12eb71
--- /dev/null
+++ b/gas/testsuite/gas/mips/ush.d
@@ -0,0 +1,455 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ush
+#as: -mips1
+
+# Test the ush macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> sb \$a0,[01]\(\$zero\)
+0+0004 <[^>]*> srl \$at,\$a0,0x8
+0+0008 <[^>]*> sb \$at,[01]\(\$zero\)
+0+000c <[^>]*> sb \$a0,[12]\(\$zero\)
+0+0010 <[^>]*> srl \$at,\$a0,0x8
+0+0014 <[^>]*> sb \$at,[12]\(\$zero\)
+0+0018 <[^>]*> li \$at,0x8000
+0+001c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0020 <[^>]*> srl \$a0,\$a0,0x8
+0+0024 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0028 <[^>]*> lbu \$at,[01]\(\$at\)
+0+002c <[^>]*> sll \$a0,\$a0,0x8
+0+0030 <[^>]*> or \$a0,\$a0,\$at
+0+0034 <[^>]*> sb \$a0,-3276[78]\(\$zero\)
+0+0038 <[^>]*> srl \$at,\$a0,0x8
+0+003c <[^>]*> sb \$at,-3276[78]\(\$zero\)
+0+0040 <[^>]*> lui \$at,0x1
+0+0044 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0048 <[^>]*> srl \$a0,\$a0,0x8
+0+004c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0050 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0054 <[^>]*> sll \$a0,\$a0,0x8
+0+0058 <[^>]*> or \$a0,\$a0,\$at
+0+005c <[^>]*> lui \$at,0x1
+0+0060 <[^>]*> ori \$at,\$at,0xa5a5
+0+0064 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0068 <[^>]*> srl \$a0,\$a0,0x8
+0+006c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0070 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0074 <[^>]*> sll \$a0,\$a0,0x8
+0+0078 <[^>]*> or \$a0,\$a0,\$at
+0+007c <[^>]*> sb \$a0,[01]\(\$a1\)
+0+0080 <[^>]*> srl \$at,\$a0,0x8
+0+0084 <[^>]*> sb \$at,[01]\(\$a1\)
+0+0088 <[^>]*> sb \$a0,[12]\(\$a1\)
+0+008c <[^>]*> srl \$at,\$a0,0x8
+0+0090 <[^>]*> sb \$at,[12]\(\$a1\)
+0+0094 <[^>]*> lui \$at,[-0-9x]+
+[ ]*94: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0098 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*98: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+009c <[^>]*> sb \$a0,[01]\(\$at\)
+0+00a0 <[^>]*> srl \$a0,\$a0,0x8
+0+00a4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00a8 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00ac <[^>]*> sll \$a0,\$a0,0x8
+0+00b0 <[^>]*> or \$a0,\$a0,\$at
+0+00b4 <[^>]*> lui \$at,0x0
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00b8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00bc <[^>]*> sb \$a0,[01]\(\$at\)
+0+00c0 <[^>]*> srl \$a0,\$a0,0x8
+0+00c4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00c8 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00cc <[^>]*> sll \$a0,\$a0,0x8
+0+00d0 <[^>]*> or \$a0,\$a0,\$at
+0+00d4 <[^>]*> addiu \$at,\$gp,0
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00d8 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00dc <[^>]*> srl \$a0,\$a0,0x8
+0+00e0 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00e4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+00e8 <[^>]*> sll \$a0,\$a0,0x8
+0+00ec <[^>]*> or \$a0,\$a0,\$at
+0+00f0 <[^>]*> lui \$at,[-0-9x]+
+[ ]*f0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00f4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*f4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00f8 <[^>]*> sb \$a0,[01]\(\$at\)
+0+00fc <[^>]*> srl \$a0,\$a0,0x8
+0+0100 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0104 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0108 <[^>]*> sll \$a0,\$a0,0x8
+0+010c <[^>]*> or \$a0,\$a0,\$at
+0+0110 <[^>]*> addiu \$at,\$gp,0
+[ ]*110: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0114 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0118 <[^>]*> srl \$a0,\$a0,0x8
+0+011c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0120 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0124 <[^>]*> sll \$a0,\$a0,0x8
+0+0128 <[^>]*> or \$a0,\$a0,\$at
+0+012c <[^>]*> lui \$at,[-0-9x]+
+[ ]*12c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0130 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*130: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0134 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0138 <[^>]*> srl \$a0,\$a0,0x8
+0+013c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0140 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0144 <[^>]*> sll \$a0,\$a0,0x8
+0+0148 <[^>]*> or \$a0,\$a0,\$at
+0+014c <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*14c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0150 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0154 <[^>]*> srl \$a0,\$a0,0x8
+0+0158 <[^>]*> sb \$a0,[01]\(\$at\)
+0+015c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0160 <[^>]*> sll \$a0,\$a0,0x8
+0+0164 <[^>]*> or \$a0,\$a0,\$at
+0+0168 <[^>]*> lui \$at,0x0
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+016c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0170 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0174 <[^>]*> srl \$a0,\$a0,0x8
+0+0178 <[^>]*> sb \$a0,[01]\(\$at\)
+0+017c <[^>]*> lbu \$at,[01]\(\$at\)
+0+0180 <[^>]*> sll \$a0,\$a0,0x8
+0+0184 <[^>]*> or \$a0,\$a0,\$at
+0+0188 <[^>]*> lui \$at,0x0
+[ ]*188: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+018c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*18c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0190 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0194 <[^>]*> srl \$a0,\$a0,0x8
+0+0198 <[^>]*> sb \$a0,[01]\(\$at\)
+0+019c <[^>]*> lbu \$at,[01]\(\$at\)
+0+01a0 <[^>]*> sll \$a0,\$a0,0x8
+0+01a4 <[^>]*> or \$a0,\$a0,\$at
+0+01a8 <[^>]*> addiu \$at,\$gp,1
+[ ]*1a8: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> sb \$a0,[01]\(\$at\)
+0+01b0 <[^>]*> srl \$a0,\$a0,0x8
+0+01b4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+01b8 <[^>]*> lbu \$at,[01]\(\$at\)
+0+01bc <[^>]*> sll \$a0,\$a0,0x8
+0+01c0 <[^>]*> or \$a0,\$a0,\$at
+0+01c4 <[^>]*> lui \$at,0x0
+[ ]*1c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01c8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01cc <[^>]*> sb \$a0,[01]\(\$at\)
+0+01d0 <[^>]*> srl \$a0,\$a0,0x8
+0+01d4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+01d8 <[^>]*> lbu \$at,[01]\(\$at\)
+0+01dc <[^>]*> sll \$a0,\$a0,0x8
+0+01e0 <[^>]*> or \$a0,\$a0,\$at
+0+01e4 <[^>]*> addiu \$at,\$gp,1
+[ ]*1e4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+01e8 <[^>]*> sb \$a0,[01]\(\$at\)
+0+01ec <[^>]*> srl \$a0,\$a0,0x8
+0+01f0 <[^>]*> sb \$a0,[01]\(\$at\)
+0+01f4 <[^>]*> lbu \$at,[01]\(\$at\)
+0+01f8 <[^>]*> sll \$a0,\$a0,0x8
+0+01fc <[^>]*> or \$a0,\$a0,\$at
+0+0200 <[^>]*> lui \$at,0x0
+[ ]*200: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0204 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*204: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0208 <[^>]*> sb \$a0,[01]\(\$at\)
+0+020c <[^>]*> srl \$a0,\$a0,0x8
+0+0210 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0214 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0218 <[^>]*> sll \$a0,\$a0,0x8
+0+021c <[^>]*> or \$a0,\$a0,\$at
+0+0220 <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*220: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0224 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0228 <[^>]*> srl \$a0,\$a0,0x8
+0+022c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0230 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0234 <[^>]*> sll \$a0,\$a0,0x8
+0+0238 <[^>]*> or \$a0,\$a0,\$at
+0+023c <[^>]*> lui \$at,[-0-9x]+
+[ ]*23c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0240 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*240: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0244 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0248 <[^>]*> srl \$a0,\$a0,0x8
+0+024c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0250 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0254 <[^>]*> sll \$a0,\$a0,0x8
+0+0258 <[^>]*> or \$a0,\$a0,\$at
+0+025c <[^>]*> lui \$at,[-0-9x]+
+[ ]*25c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0260 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*260: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0264 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0268 <[^>]*> srl \$a0,\$a0,0x8
+0+026c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0270 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0274 <[^>]*> sll \$a0,\$a0,0x8
+0+0278 <[^>]*> or \$a0,\$a0,\$at
+0+027c <[^>]*> lui \$at,[-0-9x]+
+[ ]*27c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0280 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*280: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0284 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0288 <[^>]*> srl \$a0,\$a0,0x8
+0+028c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0290 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0294 <[^>]*> sll \$a0,\$a0,0x8
+0+0298 <[^>]*> or \$a0,\$a0,\$at
+0+029c <[^>]*> lui \$at,[-0-9x]+
+[ ]*29c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2a0: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+02a8 <[^>]*> srl \$a0,\$a0,0x8
+0+02ac <[^>]*> sb \$a0,[01]\(\$at\)
+0+02b0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+02b4 <[^>]*> sll \$a0,\$a0,0x8
+0+02b8 <[^>]*> or \$a0,\$a0,\$at
+0+02bc <[^>]*> lui \$at,[-0-9x]+
+[ ]*2bc: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02c0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2c0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02c4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+02c8 <[^>]*> srl \$a0,\$a0,0x8
+0+02cc <[^>]*> sb \$a0,[01]\(\$at\)
+0+02d0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+02d4 <[^>]*> sll \$a0,\$a0,0x8
+0+02d8 <[^>]*> or \$a0,\$a0,\$at
+0+02dc <[^>]*> lui \$at,[-0-9x]+
+[ ]*2dc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02e0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2e0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02e4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+02e8 <[^>]*> srl \$a0,\$a0,0x8
+0+02ec <[^>]*> sb \$a0,[01]\(\$at\)
+0+02f0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+02f4 <[^>]*> sll \$a0,\$a0,0x8
+0+02f8 <[^>]*> or \$a0,\$a0,\$at
+0+02fc <[^>]*> lui \$at,[-0-9x]+
+[ ]*2fc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+0300 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*300: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0304 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0308 <[^>]*> srl \$a0,\$a0,0x8
+0+030c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0310 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0314 <[^>]*> sll \$a0,\$a0,0x8
+0+0318 <[^>]*> or \$a0,\$a0,\$at
+0+031c <[^>]*> lui \$at,0x0
+[ ]*31c: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0320 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*320: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0324 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0328 <[^>]*> srl \$a0,\$a0,0x8
+0+032c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0330 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0334 <[^>]*> sll \$a0,\$a0,0x8
+0+0338 <[^>]*> or \$a0,\$a0,\$at
+0+033c <[^>]*> lui \$at,0x0
+[ ]*33c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0340 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*340: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0344 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0348 <[^>]*> srl \$a0,\$a0,0x8
+0+034c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0350 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0354 <[^>]*> sll \$a0,\$a0,0x8
+0+0358 <[^>]*> or \$a0,\$a0,\$at
+0+035c <[^>]*> lui \$at,0x0
+[ ]*35c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0360 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*360: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0364 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0368 <[^>]*> srl \$a0,\$a0,0x8
+0+036c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0370 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0374 <[^>]*> sll \$a0,\$a0,0x8
+0+0378 <[^>]*> or \$a0,\$a0,\$at
+0+037c <[^>]*> lui \$at,0x0
+[ ]*37c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0380 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*380: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0384 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0388 <[^>]*> srl \$a0,\$a0,0x8
+0+038c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0390 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0394 <[^>]*> sll \$a0,\$a0,0x8
+0+0398 <[^>]*> or \$a0,\$a0,\$at
+0+039c <[^>]*> lui \$at,0x0
+[ ]*39c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+03a0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3a0: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+03a4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+03a8 <[^>]*> srl \$a0,\$a0,0x8
+0+03ac <[^>]*> sb \$a0,[01]\(\$at\)
+0+03b0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+03b4 <[^>]*> sll \$a0,\$a0,0x8
+0+03b8 <[^>]*> or \$a0,\$a0,\$at
+0+03bc <[^>]*> lui \$at,0x0
+[ ]*3bc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+03c0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3c0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+03c4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+03c8 <[^>]*> srl \$a0,\$a0,0x8
+0+03cc <[^>]*> sb \$a0,[01]\(\$at\)
+0+03d0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+03d4 <[^>]*> sll \$a0,\$a0,0x8
+0+03d8 <[^>]*> or \$a0,\$a0,\$at
+0+03dc <[^>]*> lui \$at,0x0
+[ ]*3dc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+03e0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*3e0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+03e4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+03e8 <[^>]*> srl \$a0,\$a0,0x8
+0+03ec <[^>]*> sb \$a0,[01]\(\$at\)
+0+03f0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+03f4 <[^>]*> sll \$a0,\$a0,0x8
+0+03f8 <[^>]*> or \$a0,\$a0,\$at
+0+03fc <[^>]*> lui \$at,[-0-9x]+
+[ ]*3fc: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0400 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*400: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0404 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0408 <[^>]*> srl \$a0,\$a0,0x8
+0+040c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0410 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0414 <[^>]*> sll \$a0,\$a0,0x8
+0+0418 <[^>]*> or \$a0,\$a0,\$at
+0+041c <[^>]*> lui \$at,[-0-9x]+
+[ ]*41c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0420 <[^>]*> addiu \$at,\$at,0
+[ ]*420: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0424 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0428 <[^>]*> srl \$a0,\$a0,0x8
+0+042c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0430 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0434 <[^>]*> sll \$a0,\$a0,0x8
+0+0438 <[^>]*> or \$a0,\$a0,\$at
+0+043c <[^>]*> lui \$at,[-0-9x]+
+[ ]*43c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0440 <[^>]*> addiu \$at,\$at,0
+[ ]*440: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0444 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0448 <[^>]*> srl \$a0,\$a0,0x8
+0+044c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0450 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0454 <[^>]*> sll \$a0,\$a0,0x8
+0+0458 <[^>]*> or \$a0,\$a0,\$at
+0+045c <[^>]*> lui \$at,[-0-9x]+
+[ ]*45c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0460 <[^>]*> addiu \$at,\$at,0
+[ ]*460: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0464 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0468 <[^>]*> srl \$a0,\$a0,0x8
+0+046c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0470 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0474 <[^>]*> sll \$a0,\$a0,0x8
+0+0478 <[^>]*> or \$a0,\$a0,\$at
+0+047c <[^>]*> lui \$at,[-0-9x]+
+[ ]*47c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0480 <[^>]*> addiu \$at,\$at,0
+[ ]*480: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0484 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0488 <[^>]*> srl \$a0,\$a0,0x8
+0+048c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0490 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0494 <[^>]*> sll \$a0,\$a0,0x8
+0+0498 <[^>]*> or \$a0,\$a0,\$at
+0+049c <[^>]*> lui \$at,[-0-9x]+
+[ ]*49c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+04a0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*4a0: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+04a4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+04a8 <[^>]*> srl \$a0,\$a0,0x8
+0+04ac <[^>]*> sb \$a0,[01]\(\$at\)
+0+04b0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+04b4 <[^>]*> sll \$a0,\$a0,0x8
+0+04b8 <[^>]*> or \$a0,\$a0,\$at
+0+04bc <[^>]*> lui \$at,[-0-9x]+
+[ ]*4bc: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+04c0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*4c0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+04c4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+04c8 <[^>]*> srl \$a0,\$a0,0x8
+0+04cc <[^>]*> sb \$a0,[01]\(\$at\)
+0+04d0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+04d4 <[^>]*> sll \$a0,\$a0,0x8
+0+04d8 <[^>]*> or \$a0,\$a0,\$at
+0+04dc <[^>]*> lui \$at,[-0-9x]+
+[ ]*4dc: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+04e0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*4e0: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+04e4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+04e8 <[^>]*> srl \$a0,\$a0,0x8
+0+04ec <[^>]*> sb \$a0,[01]\(\$at\)
+0+04f0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+04f4 <[^>]*> sll \$a0,\$a0,0x8
+0+04f8 <[^>]*> or \$a0,\$a0,\$at
+0+04fc <[^>]*> lui \$at,[-0-9x]+
+[ ]*4fc: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0500 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*500: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0504 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0508 <[^>]*> srl \$a0,\$a0,0x8
+0+050c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0510 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0514 <[^>]*> sll \$a0,\$a0,0x8
+0+0518 <[^>]*> or \$a0,\$a0,\$at
+0+051c <[^>]*> lui \$at,[-0-9x]+
+[ ]*51c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+0520 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*520: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0524 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0528 <[^>]*> srl \$a0,\$a0,0x8
+0+052c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0530 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0534 <[^>]*> sll \$a0,\$a0,0x8
+0+0538 <[^>]*> or \$a0,\$a0,\$at
+0+053c <[^>]*> lui \$at,[-0-9x]+
+[ ]*53c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0540 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*540: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0544 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0548 <[^>]*> srl \$a0,\$a0,0x8
+0+054c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0550 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0554 <[^>]*> sll \$a0,\$a0,0x8
+0+0558 <[^>]*> or \$a0,\$a0,\$at
+0+055c <[^>]*> lui \$at,[-0-9x]+
+[ ]*55c: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+0560 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*560: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0564 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0568 <[^>]*> srl \$a0,\$a0,0x8
+0+056c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0570 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0574 <[^>]*> sll \$a0,\$a0,0x8
+0+0578 <[^>]*> or \$a0,\$a0,\$at
+0+057c <[^>]*> lui \$at,[-0-9x]+
+[ ]*57c: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0580 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*580: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0584 <[^>]*> sb \$a0,[01]\(\$at\)
+0+0588 <[^>]*> srl \$a0,\$a0,0x8
+0+058c <[^>]*> sb \$a0,[01]\(\$at\)
+0+0590 <[^>]*> lbu \$at,[01]\(\$at\)
+0+0594 <[^>]*> sll \$a0,\$a0,0x8
+0+0598 <[^>]*> or \$a0,\$a0,\$at
+0+059c <[^>]*> lui \$at,[-0-9x]+
+[ ]*59c: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+05a0 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*5a0: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+05a4 <[^>]*> sb \$a0,[01]\(\$at\)
+0+05a8 <[^>]*> srl \$a0,\$a0,0x8
+0+05ac <[^>]*> sb \$a0,[01]\(\$at\)
+0+05b0 <[^>]*> lbu \$at,[01]\(\$at\)
+0+05b4 <[^>]*> sll \$a0,\$a0,0x8
+0+05b8 <[^>]*> or \$a0,\$a0,\$at
+0+05bc <[^>]*> nop
diff --git a/gas/testsuite/gas/mips/ush.s b/gas/testsuite/gas/mips/ush.s
new file mode 100644
index 00000000000..c1558143382
--- /dev/null
+++ b/gas/testsuite/gas/mips/ush.s
@@ -0,0 +1,65 @@
+# Source file used to test the ush macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ ush $4,0
+ ush $4,1
+ ush $4,0x8000
+ ush $4,-0x8000
+ ush $4,0x10000
+ ush $4,0x1a5a5
+ ush $4,0($5)
+ ush $4,1($5)
+ ush $4,data_label
+ ush $4,big_external_data_label
+ ush $4,small_external_data_label
+ ush $4,big_external_common
+ ush $4,small_external_common
+ ush $4,big_local_common
+ ush $4,small_local_common
+ ush $4,data_label+1
+ ush $4,big_external_data_label+1
+ ush $4,small_external_data_label+1
+ ush $4,big_external_common+1
+ ush $4,small_external_common+1
+ ush $4,big_local_common+1
+ ush $4,small_local_common+1
+ ush $4,data_label+0x8000
+ ush $4,big_external_data_label+0x8000
+ ush $4,small_external_data_label+0x8000
+ ush $4,big_external_common+0x8000
+ ush $4,small_external_common+0x8000
+ ush $4,big_local_common+0x8000
+ ush $4,small_local_common+0x8000
+ ush $4,data_label-0x8000
+ ush $4,big_external_data_label-0x8000
+ ush $4,small_external_data_label-0x8000
+ ush $4,big_external_common-0x8000
+ ush $4,small_external_common-0x8000
+ ush $4,big_local_common-0x8000
+ ush $4,small_local_common-0x8000
+ ush $4,data_label+0x10000
+ ush $4,big_external_data_label+0x10000
+ ush $4,small_external_data_label+0x10000
+ ush $4,big_external_common+0x10000
+ ush $4,small_external_common+0x10000
+ ush $4,big_local_common+0x10000
+ ush $4,small_local_common+0x10000
+ ush $4,data_label+0x1a5a5
+ ush $4,big_external_data_label+0x1a5a5
+ ush $4,small_external_data_label+0x1a5a5
+ ush $4,big_external_common+0x1a5a5
+ ush $4,small_external_common+0x1a5a5
+ ush $4,big_local_common+0x1a5a5
+ ush $4,small_local_common+0x1a5a5
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
diff --git a/gas/testsuite/gas/mips/usw.d b/gas/testsuite/gas/mips/usw.d
new file mode 100644
index 00000000000..59d28cc22e2
--- /dev/null
+++ b/gas/testsuite/gas/mips/usw.d
@@ -0,0 +1,270 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS usw
+#as: -mips1
+
+# Test the usw macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> swl \$a0,[03]\(\$zero\)
+0+0004 <[^>]*> swr \$a0,[03]\(\$zero\)
+0+0008 <[^>]*> swl \$a0,[14]\(\$zero\)
+0+000c <[^>]*> swr \$a0,[14]\(\$zero\)
+0+0010 <[^>]*> li \$at,0x8000
+0+0014 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0018 <[^>]*> swr \$a0,[03]\(\$at\)
+0+001c <[^>]*> swl \$a0,-3276[58]\(\$zero\)
+0+0020 <[^>]*> swr \$a0,-3276[58]\(\$zero\)
+0+0024 <[^>]*> lui \$at,0x1
+0+0028 <[^>]*> swl \$a0,[03]\(\$at\)
+0+002c <[^>]*> swr \$a0,[03]\(\$at\)
+0+0030 <[^>]*> lui \$at,0x1
+0+0034 <[^>]*> ori \$at,\$at,0xa5a5
+0+0038 <[^>]*> swl \$a0,[03]\(\$at\)
+0+003c <[^>]*> swr \$a0,[03]\(\$at\)
+0+0040 <[^>]*> swl \$a0,[03]\(\$a1\)
+0+0044 <[^>]*> swr \$a0,[03]\(\$a1\)
+0+0048 <[^>]*> swl \$a0,[14]\(\$a1\)
+0+004c <[^>]*> swr \$a0,[-0-9]+\(\$a1\)
+0+0050 <[^>]*> lui \$at,[-0-9x]+
+[ ]*50: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+0054 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*54: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0058 <[^>]*> swl \$a0,[03]\(\$at\)
+0+005c <[^>]*> swr \$a0,[03]\(\$at\)
+0+0060 <[^>]*> lui \$at,[-0-9x]+
+[ ]*60: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+0064 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*64: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0068 <[^>]*> swl \$a0,[03]\(\$at\)
+0+006c <[^>]*> swr \$a0,[03]\(\$at\)
+0+0070 <[^>]*> addiu \$at,\$gp,0
+[ ]*70: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+0074 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0078 <[^>]*> swr \$a0,[03]\(\$at\)
+0+007c <[^>]*> lui \$at,0x0
+[ ]*7c: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+0080 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*80: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0084 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0088 <[^>]*> swr \$a0,[03]\(\$at\)
+0+008c <[^>]*> addiu \$at,\$gp,0
+[ ]*8c: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+0090 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0094 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0098 <[^>]*> lui \$at,[-0-9x]+
+[ ]*98: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+009c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*9c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+00a0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+00a4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+00a8 <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*a8: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+00ac <[^>]*> swl \$a0,[03]\(\$at\)
+0+00b0 <[^>]*> swr \$a0,[03]\(\$at\)
+0+00b4 <[^>]*> lui \$at,0x0
+[ ]*b4: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+00b8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*b8: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+00bc <[^>]*> swl \$a0,[03]\(\$at\)
+0+00c0 <[^>]*> swr \$a0,[03]\(\$at\)
+0+00c4 <[^>]*> lui \$at,0x0
+[ ]*c4: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+00c8 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*c8: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+00cc <[^>]*> swl \$a0,[03]\(\$at\)
+0+00d0 <[^>]*> swr \$a0,[03]\(\$at\)
+0+00d4 <[^>]*> addiu \$at,\$gp,1
+[ ]*d4: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_data_label
+0+00d8 <[^>]*> swl \$a0,[03]\(\$at\)
+0+00dc <[^>]*> swr \$a0,[03]\(\$at\)
+0+00e0 <[^>]*> lui \$at,0x0
+[ ]*e0: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+00e4 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*e4: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+00e8 <[^>]*> swl \$a0,[03]\(\$at\)
+0+00ec <[^>]*> swr \$a0,[03]\(\$at\)
+0+00f0 <[^>]*> addiu \$at,\$gp,1
+[ ]*f0: [A-Z0-9_]*GPREL[A-Z0-9_]* small_external_common
+0+00f4 <[^>]*> swl \$a0,[03]\(\$at\)
+0+00f8 <[^>]*> swr \$a0,[03]\(\$at\)
+0+00fc <[^>]*> lui \$at,0x0
+[ ]*fc: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+0100 <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*100: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0104 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0108 <[^>]*> swr \$a0,[03]\(\$at\)
+0+010c <[^>]*> addiu \$at,\$gp,[-0-9]+
+[ ]*10c: [A-Z0-9_]*GPREL[A-Z0-9_]* .sbss.*
+0+0110 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0114 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0118 <[^>]*> lui \$at,[-0-9x]+
+[ ]*118: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+011c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*11c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0120 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0124 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0128 <[^>]*> lui \$at,[-0-9x]+
+[ ]*128: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+012c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*12c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0130 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0134 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0138 <[^>]*> lui \$at,[-0-9x]+
+[ ]*138: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+013c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*13c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0140 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0144 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0148 <[^>]*> lui \$at,[-0-9x]+
+[ ]*148: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+014c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*14c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0150 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0154 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0158 <[^>]*> lui \$at,[-0-9x]+
+[ ]*158: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+015c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*15c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0160 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0164 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0168 <[^>]*> lui \$at,[-0-9x]+
+[ ]*168: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+016c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*16c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0170 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0174 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0178 <[^>]*> lui \$at,[-0-9x]+
+[ ]*178: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+017c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*17c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0180 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0184 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0188 <[^>]*> lui \$at,0x0
+[ ]*188: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+018c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*18c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0190 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0194 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0198 <[^>]*> lui \$at,0x0
+[ ]*198: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+019c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*19c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+01a0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+01a4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+01a8 <[^>]*> lui \$at,0x0
+[ ]*1a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+01ac <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+01b0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+01b4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+01b8 <[^>]*> lui \$at,0x0
+[ ]*1b8: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+01bc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1bc: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+01c0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+01c4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+01c8 <[^>]*> lui \$at,0x0
+[ ]*1c8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+01cc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1cc: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+01d0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+01d4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+01d8 <[^>]*> lui \$at,0x0
+[ ]*1d8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+01dc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1dc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+01e0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+01e4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+01e8 <[^>]*> lui \$at,0x0
+[ ]*1e8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+01ec <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1ec: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+01f0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+01f4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+01f8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*1f8: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+01fc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*1fc: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0200 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0204 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0208 <[^>]*> lui \$at,[-0-9x]+
+[ ]*208: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+020c <[^>]*> addiu \$at,\$at,0
+[ ]*20c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0210 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0214 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0218 <[^>]*> lui \$at,[-0-9x]+
+[ ]*218: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+021c <[^>]*> addiu \$at,\$at,0
+[ ]*21c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0220 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0224 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0228 <[^>]*> lui \$at,[-0-9x]+
+[ ]*228: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+022c <[^>]*> addiu \$at,\$at,0
+[ ]*22c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+0230 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0234 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0238 <[^>]*> lui \$at,[-0-9x]+
+[ ]*238: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+023c <[^>]*> addiu \$at,\$at,0
+[ ]*23c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+0240 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0244 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0248 <[^>]*> lui \$at,[-0-9x]+
+[ ]*248: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+024c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*24c: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+0250 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0254 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0258 <[^>]*> lui \$at,[-0-9x]+
+[ ]*258: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+025c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*25c: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+0260 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0264 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0268 <[^>]*> lui \$at,[-0-9x]+
+[ ]*268: [A-Z0-9_]*HI[A-Z0-9_]* .data.*
+0+026c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*26c: [A-Z0-9_]*LO[A-Z0-9_]* .data.*
+0+0270 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0274 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0278 <[^>]*> lui \$at,[-0-9x]+
+[ ]*278: [A-Z0-9_]*HI[A-Z0-9_]* big_external_data_label
+0+027c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*27c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_data_label
+0+0280 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0284 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0288 <[^>]*> lui \$at,[-0-9x]+
+[ ]*288: [A-Z0-9_]*HI[A-Z0-9_]* small_external_data_label
+0+028c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*28c: [A-Z0-9_]*LO[A-Z0-9_]* small_external_data_label
+0+0290 <[^>]*> swl \$a0,[03]\(\$at\)
+0+0294 <[^>]*> swr \$a0,[03]\(\$at\)
+0+0298 <[^>]*> lui \$at,[-0-9x]+
+[ ]*298: [A-Z0-9_]*HI[A-Z0-9_]* big_external_common
+0+029c <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*29c: [A-Z0-9_]*LO[A-Z0-9_]* big_external_common
+0+02a0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+02a4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+02a8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2a8: [A-Z0-9_]*HI[A-Z0-9_]* small_external_common
+0+02ac <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2ac: [A-Z0-9_]*LO[A-Z0-9_]* small_external_common
+0+02b0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+02b4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+02b8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2b8: [A-Z0-9_]*HI[A-Z0-9_]* .bss.*
+0+02bc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2bc: [A-Z0-9_]*LO[A-Z0-9_]* .bss.*
+0+02c0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+02c4 <[^>]*> swr \$a0,[03]\(\$at\)
+0+02c8 <[^>]*> lui \$at,[-0-9x]+
+[ ]*2c8: [A-Z0-9_]*HI[A-Z0-9_]* .sbss.*
+0+02cc <[^>]*> addiu \$at,\$at,[-0-9]+
+[ ]*2cc: [A-Z0-9_]*LO[A-Z0-9_]* .sbss.*
+0+02d0 <[^>]*> swl \$a0,[03]\(\$at\)
+0+02d4 <[^>]*> swr \$a0,[03]\(\$at\)
+ ...
diff --git a/gas/testsuite/gas/mips/usw.s b/gas/testsuite/gas/mips/usw.s
new file mode 100644
index 00000000000..df1c60c285e
--- /dev/null
+++ b/gas/testsuite/gas/mips/usw.s
@@ -0,0 +1,66 @@
+# Source file used to test the usw macro.
+
+ .data
+data_label:
+ .extern big_external_data_label,1000
+ .extern small_external_data_label,1
+ .comm big_external_common,1000
+ .comm small_external_common,1
+ .lcomm big_local_common,1000
+ .lcomm small_local_common,1
+
+ .text
+ usw $4,0
+ usw $4,1
+ usw $4,0x8000
+ usw $4,-0x8000
+ usw $4,0x10000
+ usw $4,0x1a5a5
+ usw $4,0($5)
+ usw $4,1($5)
+ usw $4,data_label
+ usw $4,big_external_data_label
+ usw $4,small_external_data_label
+ usw $4,big_external_common
+ usw $4,small_external_common
+ usw $4,big_local_common
+ usw $4,small_local_common
+ usw $4,data_label+1
+ usw $4,big_external_data_label+1
+ usw $4,small_external_data_label+1
+ usw $4,big_external_common+1
+ usw $4,small_external_common+1
+ usw $4,big_local_common+1
+ usw $4,small_local_common+1
+ usw $4,data_label+0x8000
+ usw $4,big_external_data_label+0x8000
+ usw $4,small_external_data_label+0x8000
+ usw $4,big_external_common+0x8000
+ usw $4,small_external_common+0x8000
+ usw $4,big_local_common+0x8000
+ usw $4,small_local_common+0x8000
+ usw $4,data_label-0x8000
+ usw $4,big_external_data_label-0x8000
+ usw $4,small_external_data_label-0x8000
+ usw $4,big_external_common-0x8000
+ usw $4,small_external_common-0x8000
+ usw $4,big_local_common-0x8000
+ usw $4,small_local_common-0x8000
+ usw $4,data_label+0x10000
+ usw $4,big_external_data_label+0x10000
+ usw $4,small_external_data_label+0x10000
+ usw $4,big_external_common+0x10000
+ usw $4,small_external_common+0x10000
+ usw $4,big_local_common+0x10000
+ usw $4,small_local_common+0x10000
+ usw $4,data_label+0x1a5a5
+ usw $4,big_external_data_label+0x1a5a5
+ usw $4,small_external_data_label+0x1a5a5
+ usw $4,big_external_common+0x1a5a5
+ usw $4,small_external_common+0x1a5a5
+ usw $4,big_local_common+0x1a5a5
+ usw $4,small_local_common+0x1a5a5
+
+# Round to a 16 byte boundary, for ease in testing multiple targets.
+ nop
+ nop
diff --git a/gas/testsuite/gas/mn10200/add.s b/gas/testsuite/gas/mn10200/add.s
new file mode 100644
index 00000000000..ed251bc55ec
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/add.s
@@ -0,0 +1,13 @@
+ .text
+ add d1,d2
+ add d2,a3
+ add a2,d1
+ add a3,a2
+ add 16,d1
+ add 256,d2
+ add 131071,d3
+ add 16,a1
+ add 256,a2
+ add 131071,a3
+ addc d1,d2
+ addnf 16,a2
diff --git a/gas/testsuite/gas/mn10200/basic.exp b/gas/testsuite/gas/mn10200/basic.exp
new file mode 100644
index 00000000000..3793eb17ed3
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/basic.exp
@@ -0,0 +1,836 @@
+# Copyright (C) 1996 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by Cygnus Support.
+
+proc do_add {} {
+ set testname "add.s: Add operations"
+ set x 0
+
+ gas_start "add.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 96\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F20B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F2C9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F24E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 D510\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 F71A0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F463FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 D110\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F70A0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F467FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001d F286\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001f F50E10\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==14] then { pass $testname } else { fail $testname }
+}
+
+proc do_bcc {} {
+ set testname "bcc.s: Bcc tests"
+ set x 0
+
+ gas_start "bcc.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E800\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 E900\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 E100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 E200\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 E300\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a E000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c E500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e E600\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 E700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 E400\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F5FC00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0017 F5FD00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F5FE00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001d F5FF00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 EA00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==15] then { pass $testname } else { fail $testname }
+}
+
+proc do_bccx {} {
+ set testname "bccx.s: Bccx tests"
+ set x 0
+
+ gas_start "bccx.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F5E800\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F5E900\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F5E100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 F5E200\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F5E300\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f F5E000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F5E500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 F5E600\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F5E700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001b F5E400\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e F5EC00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0021 F5ED00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 F5EE00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0027 F5EF00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==14] then { pass $testname } else { fail $testname }
+}
+
+proc do_bit {} {
+ set testname "bit.s: bit tests"
+ set x 0
+
+ gas_start "bit.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F50540\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F7060020\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F029\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 F039\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +12 +FFFF40\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+
+proc do_cmp {} {
+ set testname "cmp.s: cmp tests"
+ set x 0
+
+ gas_start "cmp.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F396\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F22B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F2EF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F26E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 DB10\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a F74A0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e F479FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 EE0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F47DFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +10 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==11] then { pass $testname } else { fail $testname }
+}
+
+proc do_ext {} {
+ set testname "ext.s: ext tests"
+ set x 0
+
+ gas_start "ext.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F3C5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 B2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 B7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 BA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 BD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==5] then { pass $testname } else { fail $testname }
+}
+
+proc do_extend {} {
+ set testname "extend.s: extended instruction tests"
+ set x 0
+
+ gas_start "extend.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F505\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F6FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F90210\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FB030100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d FD030001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 F616\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 F91610\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 FB170100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c FD170001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 F64B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 F65E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 F676\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==15] then { pass $testname } else { fail $testname }
+}
+
+proc do_logical {} {
+ set testname "logical.s: logical tests"
+ set x 0
+
+ gas_start "logical.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F306\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F5027F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F703FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 F710FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F316\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f F50A7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F743FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F714FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F326\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F74FFF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 F3E7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==11] then { pass $testname } else { fail $testname }
+}
+
+proc do_loop {} {
+ set testname "loop.s: loop tests"
+ set x 0
+
+ gas_start "loop.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 D8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 D9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 D1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 D2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 D3\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 D5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 D6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 D7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 D4\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b DB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==12] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov1 {} {
+ set testname "mov1.s: mov1 tests"
+ set x 0
+
+ gas_start "mov1.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F236\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F2F9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F279\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F3F3\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 F3D8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b F3E1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F3C8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f 29\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 6908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F7C90001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F489FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +13 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==13] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov2 {} {
+ set testname "mov2.s: mov2 tests"
+ set x 0
+
+ gas_start "mov2.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F156\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 C90080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F4C1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +4 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a 7908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F7B90001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F4F9FFFF \[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 F116\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0017 F7310080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001b F4D1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +10 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==12] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov3 {} {
+ set testname "mov3.s: mov3 tests"
+ set x 0
+
+ gas_start "mov3.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 09\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 4920\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F7890001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F409FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F1E9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e C18000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0011 F441FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 5920\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F7A90001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F419FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==13] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov4 {} {
+ set testname "mov4.s: mov4 tests"
+ set x 0
+
+ gas_start "mov4.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F1A9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F7218000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F451FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +4 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b 8508\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F90001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F471FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 DD0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F475FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +9 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==11] then { pass $testname } else { fail $testname }
+}
+
+proc do_movx {} {
+ set testname "movx.s: movx tests"
+ set x 0
+
+ gas_start "movx.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F57908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F7790001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F4B9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +4 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F55908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f F7690001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 F439FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==8] then { pass $testname } else { fail $testname }
+}
+
+proc do_movb {} {
+ set testname "movb.s: movb tests"
+ set x 0
+
+ gas_start "movb.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F52908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F7D90001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F4A9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +4 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F06B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e F4C6FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +6 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 19\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F51908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0017 F7990001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001b F429FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +10 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 F0E9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 C50001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0025 F445FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +13 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==16] then { pass $testname } else { fail $testname }
+}
+
+proc do_movbu {} {
+ set testname "movbu.s: movbu tests"
+ set x 0
+
+ gas_start "movbu.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 39\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F53908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F7590001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 F499FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F096\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f CD0080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F4C9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==9] then { pass $testname } else { fail $testname }
+}
+
+proc do_movhu {} {
+ set testname "movhu.s: movhu tests"
+ set x 0
+
+ gas_start "movhu.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F066\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F86608\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 FA660100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FC660001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f F8BD08\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 FABD0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 FCBD0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F4A5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e 398000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0021 FCAD0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0027 F076\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0029 F87620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c FA760100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 FC760001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +15 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0036 F89720\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0039 FA978000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003d FC970001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +18 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0043 F4DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0045 070080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 FC870001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +21 +FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==26] then { pass $testname } else { fail $testname }
+}
+
+proc do_movm {} {
+ set testname "movm.s: movm tests"
+ set x 0
+
+ gas_start "movm.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 CE30\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 CEF8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 CF30\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 CFF8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_muldiv {} {
+ set testname "muldiv.s: muldiv tests"
+ set x 0
+
+ gas_start "muldiv.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F346\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F35B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F36E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==3] then { pass $testname } else { fail $testname }
+}
+
+proc do_other {} {
+ set testname "other.s: other tests"
+ set x 0
+
+ gas_start "other.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 FC0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F4E0FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +3 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 F008\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a FD0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F4E1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +6 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F009\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 FE\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 EB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==11] then { pass $testname } else { fail $testname }
+}
+
+proc do_shift {} {
+ set testname "shift.s: shift tests"
+ set x 0
+
+ gas_start "shift.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F33A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F33F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F335\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F332\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_sub {} {
+ set testname "sub.s: sub tests"
+ set x 0
+
+ gas_start "sub.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 A6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F21B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F2DF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F25E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F71EFF7F \[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b F46AFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F70EFF7F \[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F46EFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +9 +01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0019 F296 \[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==11] then { pass $testname } else { fail $testname }
+}
+
+if [istarget mn10200*-*-*] then {
+ # Test the basic instruction parser.
+ do_add
+ do_bcc
+ do_bccx
+ do_bit
+ do_cmp
+ do_ext
+ do_logical
+ do_mov1
+ do_mov2
+ do_mov3
+ do_mov4
+ do_movb
+ do_movx
+ do_movbu
+ do_muldiv
+ do_other
+ do_shift
+ do_sub
+}
diff --git a/gas/testsuite/gas/mn10200/bcc.s b/gas/testsuite/gas/mn10200/bcc.s
new file mode 100644
index 00000000000..8292dce04fd
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/bcc.s
@@ -0,0 +1,17 @@
+ .text
+foo:
+ beq foo
+ bne foo
+ bgt foo
+ bge foo
+ ble foo
+ blt foo
+ bhi foo
+ bcc foo
+ bls foo
+ bcs foo
+ bvc foo
+ bvs foo
+ bnc foo
+ bns foo
+ bra foo
diff --git a/gas/testsuite/gas/mn10200/bccx.s b/gas/testsuite/gas/mn10200/bccx.s
new file mode 100644
index 00000000000..e4e7edf5e30
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/bccx.s
@@ -0,0 +1,16 @@
+ .text
+foo:
+ beqx foo
+ bnex foo
+ bgtx foo
+ bgex foo
+ blex foo
+ bltx foo
+ bhix foo
+ bccx foo
+ blsx foo
+ bcsx foo
+ bvcx foo
+ bvsx foo
+ bncx foo
+ bnsx foo
diff --git a/gas/testsuite/gas/mn10200/bit.s b/gas/testsuite/gas/mn10200/bit.s
new file mode 100644
index 00000000000..5db60d495bc
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/bit.s
@@ -0,0 +1,5 @@
+ .text
+ btst 64,d1
+ btst 8192,d2
+ bset d1,(a2)
+ bclr d1,(a2)
diff --git a/gas/testsuite/gas/mn10200/cmp.s b/gas/testsuite/gas/mn10200/cmp.s
new file mode 100644
index 00000000000..133925b38c5
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/cmp.s
@@ -0,0 +1,10 @@
+ .text
+ cmp d1,d2
+ cmp d2,a3
+ cmp a3,d3
+ cmp a3,a2
+ cmp 16,d3
+ cmp 256,d2
+ cmp 131071,d1
+ cmp 256,a2
+ cmp 131071,a1
diff --git a/gas/testsuite/gas/mn10200/ext.s b/gas/testsuite/gas/mn10200/ext.s
new file mode 100644
index 00000000000..1be01bac89c
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/ext.s
@@ -0,0 +1,7 @@
+ .text
+ ext d1
+ extx d2
+ extxu d3
+ extxb d2
+ extxbu d1
+
diff --git a/gas/testsuite/gas/mn10200/logical.s b/gas/testsuite/gas/mn10200/logical.s
new file mode 100644
index 00000000000..0809d7f387f
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/logical.s
@@ -0,0 +1,12 @@
+ .text
+ and d1,d2
+ and 127,d2
+ and 32767,d3
+ and 32767,psw
+ or d1,d2
+ or 127,d2
+ or 32767,d3
+ or 32767,psw
+ xor d1,d2
+ xor 32767,d3
+ not d3
diff --git a/gas/testsuite/gas/mn10200/mov1.s b/gas/testsuite/gas/mn10200/mov1.s
new file mode 100644
index 00000000000..c828e32e59d
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/mov1.s
@@ -0,0 +1,13 @@
+ .text
+ mov d1,a2
+ mov a2,d1
+ mov d1,d2
+ mov a2,a1
+ mov psw,d3
+ mov d2,psw
+ mov mdr,d1
+ mov d2,mdr
+ mov (a2),d1
+ mov (8,a2),d1
+ mov (256,a2),d1
+ mov (131071,a2),d1
diff --git a/gas/testsuite/gas/mn10200/mov2.s b/gas/testsuite/gas/mn10200/mov2.s
new file mode 100644
index 00000000000..8df6e2544c4
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/mov2.s
@@ -0,0 +1,10 @@
+ .text
+ mov (d1,a1),d2
+ mov (32768),d1
+ mov (131071),d1
+ mov (8,a2),a1
+ mov (256,a2),a1
+ mov (131071,a2),a1
+ mov (d1,a1),a2
+ mov (32768),a1
+ mov (131071),a1
diff --git a/gas/testsuite/gas/mn10200/mov3.s b/gas/testsuite/gas/mn10200/mov3.s
new file mode 100644
index 00000000000..bd7490a35a6
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/mov3.s
@@ -0,0 +1,11 @@
+ .text
+ mov d1,(a2)
+ mov d1,(32,a2)
+ mov d1,(256,a2)
+ mov d1,(131071,a2)
+ mov d1,(d2,a2)
+ mov d1,(128)
+ mov d1,(131071)
+ mov a1,(32,a2)
+ mov a1,(256,a2)
+ mov a1,(131071,a2)
diff --git a/gas/testsuite/gas/mn10200/mov4.s b/gas/testsuite/gas/mn10200/mov4.s
new file mode 100644
index 00000000000..f1187e01fe8
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/mov4.s
@@ -0,0 +1,9 @@
+ .text
+ mov a1,(d2,a2)
+ mov a1,(128)
+ mov a1,(131071)
+ mov 8,d1
+ mov 256,d1
+ mov 131071,d1
+ mov 256,a1
+ mov 131071,a1
diff --git a/gas/testsuite/gas/mn10200/movb.s b/gas/testsuite/gas/mn10200/movb.s
new file mode 100644
index 00000000000..25566147546
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/movb.s
@@ -0,0 +1,13 @@
+ .text
+ movb (8,a2),d1
+ movb (256,a2),d1
+ movb (131071,a2),d1
+ movb (d2,a2),d3
+ movb (131071),d2
+ movb d1,(a2)
+ movb d1,(8,a2)
+ movb d1,(256,a2)
+ movb d1,(131071,a2)
+ movb d1,(d2,a2)
+ movb d1,(256)
+ movb d1,(131071)
diff --git a/gas/testsuite/gas/mn10200/movbu.s b/gas/testsuite/gas/mn10200/movbu.s
new file mode 100644
index 00000000000..01d973a1b14
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/movbu.s
@@ -0,0 +1,8 @@
+ .text
+ movbu (a2),d1
+ movbu (8,a2),d1
+ movbu (256,a2),d1
+ movbu (131071,a2),d1
+ movbu (d1,a1),d2
+ movbu (32768),d1
+ movbu (131071),d1
diff --git a/gas/testsuite/gas/mn10200/movx.s b/gas/testsuite/gas/mn10200/movx.s
new file mode 100644
index 00000000000..70e1d714f5a
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/movx.s
@@ -0,0 +1,7 @@
+ .text
+ movx (8,a2),d1
+ movx (256,a2),d1
+ movx (131071,a2),d1
+ movx d1,(8,a2)
+ movx d1,(256,a2)
+ movx d1,(131071,a2)
diff --git a/gas/testsuite/gas/mn10200/muldiv.s b/gas/testsuite/gas/mn10200/muldiv.s
new file mode 100644
index 00000000000..0f170265c8d
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/muldiv.s
@@ -0,0 +1,4 @@
+ .text
+ mul d1,d2
+ mulu d2,d3
+ divu d3,d2
diff --git a/gas/testsuite/gas/mn10200/other.s b/gas/testsuite/gas/mn10200/other.s
new file mode 100644
index 00000000000..ecf94bdfd68
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/other.s
@@ -0,0 +1,10 @@
+ .text
+ jmp 256
+ jmp 131071
+ jmp (a2)
+ jsr 256
+ jsr 131071
+ jsr (a2)
+ rts
+ rti
+ nop
diff --git a/gas/testsuite/gas/mn10200/shift.s b/gas/testsuite/gas/mn10200/shift.s
new file mode 100644
index 00000000000..568e769f6fa
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/shift.s
@@ -0,0 +1,5 @@
+ .text
+ asr d2
+ lsr d3
+ ror d1
+ rol d2
diff --git a/gas/testsuite/gas/mn10200/sub.s b/gas/testsuite/gas/mn10200/sub.s
new file mode 100644
index 00000000000..25516548f57
--- /dev/null
+++ b/gas/testsuite/gas/mn10200/sub.s
@@ -0,0 +1,10 @@
+ .text
+ sub d1,d2
+ sub d2,a3
+ sub a3,d3
+ sub a3,a2
+ sub 32767,d2
+ sub 131071,d2
+ sub 32767,a2
+ sub 131071,a2
+ subc d1,d2
diff --git a/gas/testsuite/gas/mn10300/add.s b/gas/testsuite/gas/mn10300/add.s
new file mode 100644
index 00000000000..16f558f5021
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/add.s
@@ -0,0 +1,15 @@
+ .text
+ add d1,d2
+ add d2,a3
+ add a3,a2
+ add a2,d1
+ add 16,d1
+ add 256,d2
+ add 131071,d3
+ add 16,a1
+ add 256,a2
+ add 131071,a3
+ add 16,sp
+ add 256,sp
+ add 131071,sp
+ addc d1,d2
diff --git a/gas/testsuite/gas/mn10300/basic.exp b/gas/testsuite/gas/mn10300/basic.exp
new file mode 100644
index 00000000000..7c057b9a07c
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/basic.exp
@@ -0,0 +1,986 @@
+# Copyright (C) 1996 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by Cygnus Support.
+
+proc do_add {} {
+ set testname "add.s: Add operations"
+ set x 0
+
+ gas_start "add.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F16B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F17E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F159\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 2910\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FAC20001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d FCC3FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 2110\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 FAD20001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0019 FCD3FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001f F8FE10\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 FAFE0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 FCFEFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +14 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c F146\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==17] then { pass $testname } else { fail $testname }
+}
+
+proc do_bcc {} {
+ set testname "bcc.s: Bcc tests"
+ set x 0
+
+ gas_start "bcc.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 C800\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 C900\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 C100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 C200\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 C300\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a C000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c C500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e C600\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 C700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 C400\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F8E800\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0017 F8E900\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F8EA00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001d F8EB00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 CA00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==15] then { pass $testname } else { fail $testname }
+}
+
+proc do_bit {} {
+ set testname "bit.s: bit tests"
+ set x 0
+
+ gas_start "bit.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F8ED40\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 FAEE0020\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 FCEFFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +4 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d FAF90840\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0011 FE02FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +6 +010040\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F086\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a FAF10840\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e FE00FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +9 +010040\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0025 F096\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0027 FAF50840\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002b FE01FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +12 +010040\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==15] then { pass $testname } else { fail $testname }
+}
+
+proc do_cmp {} {
+ set testname "cmp.s: cmp tests"
+ set x 0
+
+ gas_start "cmp.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 A6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F1AB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F19F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 BE\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 AF10\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 FACA0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c FCC9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 BF10\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 FADA0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 FCD9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==12] then { pass $testname } else { fail $testname }
+}
+
+proc do_ext {} {
+ set testname "ext.s: ext tests"
+ set x 0
+
+ gas_start "ext.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F2D1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 12\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 17\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 1A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 1D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==5] then { pass $testname } else { fail $testname }
+}
+
+proc do_extend {} {
+ set testname "extend.s: extended instruction tests"
+ set x 0
+
+ gas_start "extend.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F505\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F6FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F606\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F90210\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FB030001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d FD03FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 F616\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 F91610\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 FB170001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c FD17FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 F64B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 F65E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 F676\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==15] then { pass $testname } else { fail $testname }
+}
+
+proc do_logical {} {
+ set testname "logical.s: logical tests"
+ set x 0
+
+ gas_start "logical.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F206\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F8E27F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 FAE3FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FCE3FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f FAFCFF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 F216\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0015 F8E67F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 FAE7FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c FCE7FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +10 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 FAFDFF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 F226\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 FAEBFF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c FCEBFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +14 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0032 F233\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==17] then { pass $testname } else { fail $testname }
+}
+
+proc do_loop {} {
+ set testname "loop.s: loop tests"
+ set x 0
+
+ gas_start "loop.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 D8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 D9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 D1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 D2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 D3\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 D0\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 D5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 D6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 D7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 D4\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b DB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==12] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov1 {} {
+ set testname "mov1.s: mov1 tests"
+ set x 0
+
+ gas_start "mov1.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 86\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F1E6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 F1D9\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 99\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 3E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F2F4\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 F2FB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b F2E1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000d F2FA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f 76\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F80608\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 FA060001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0017 FC06FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +14 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001d 5908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001f FAB50001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0023 F2E7\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==17] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov2 {} {
+ set testname "mov2.s: mov2 tests"
+ set x 0
+
+ gas_start "mov2.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 FCB5FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +2 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F325\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 310080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000b FCA5FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0011 F006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 F82608\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 FA260001 \[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a FC26FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +9 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 5D08\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 FAB10001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 FCB1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +12 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c F3A5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002e FAA10080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0032 FCA1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +15 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 F8F120\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==20] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov3 {} {
+ set testname "mov3.s: mov3 tests"
+ set x 0
+
+ gas_start "mov3.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 66\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 F81620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 FA160001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 FC16FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e 4620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 FA950080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 FC95FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F35A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c 058000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001f FC85FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0025 F016\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0027 F83620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002a FA360001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002e FC36FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +15 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 4720\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==19] then { pass $testname } else { fail $testname }
+}
+
+proc do_mov4 {} {
+ set testname "mov4.s: mov4 tests"
+ set x 0
+
+ gas_start "mov4.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 FA940080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 FC94FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +3 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a F3DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c FA848000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 FC84FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +6 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F8F520\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0019 8508\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001b 2D0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e FCCDFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +10 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 9508\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 250001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0029 FCDDFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +13 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==16] then { pass $testname } else { fail $testname }
+}
+
+proc do_movbu {} {
+ set testname "movbu.s: movbu tests"
+ set x 0
+
+ gas_start "movbu.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F046\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F84608\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 FA460001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FC46FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f F8B908\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 FAB90001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 FCB9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F425\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e 350080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0021 FCA9FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0027 F056\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0029 F85620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c FA560001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 FC56FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +15 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0036 F89620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0039 FA960080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003d FC96FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +18 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0043 F45A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0045 068000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 FC86FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +21 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==26] then { pass $testname } else { fail $testname }
+}
+
+proc do_movhu {} {
+ set testname "movhu.s: movhu tests"
+ set x 0
+
+ gas_start "movhu.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F066\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F86608\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 FA660001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 FC66FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +5 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f F8BD08\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 FABD0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 FCBDFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F4A5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e 390080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0021 FCADFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +11 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0027 F076\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0029 F87620\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c FA760001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 FC76FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +15 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0036 F89720\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0039 FA970080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003d FC97FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +18 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0043 F4DA\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0045 078000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 FC87FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +21 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==26] then { pass $testname } else { fail $testname }
+}
+
+proc do_movm {} {
+ set testname "movm.s: movm tests"
+ set x 0
+
+ gas_start "movm.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 CE30\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 CEF8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 CF30\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 CFF8\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_muldiv {} {
+ set testname "muldiv.s: muldiv tests"
+ set x 0
+
+ gas_start "muldiv.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F246\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F25B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F26F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F27E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_other {} {
+ set testname "other.s: other tests"
+ set x 0
+
+ gas_start "other.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 08\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0001 44\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 49\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0003 53\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F0F6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 CC0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0009 DCFFFF01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +8 +00\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e CD000130\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +9 +09\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0013 DDFFFF01\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +10 +003020\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F0F2\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c FAFF0001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 FCFFFFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +13 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 DF3007\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0029 DE3005\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c F0FC\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002e F0FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 F0FE\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0032 CB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0033 F0FF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==23] then { pass $testname } else { fail $testname }
+}
+
+proc do_shift {} {
+ set testname "shift.s: shift tests"
+ set x 0
+
+ gas_start "shift.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F2B6\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F8CA04\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0005 F2AB\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0007 F8C704\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a F29E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F8C204\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000f 56\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F285\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F282\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==9] then { pass $testname } else { fail $testname }
+}
+
+proc do_sub {} {
+ set testname "sub.s: sub tests"
+ set x 0
+
+ gas_start "sub.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F106\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F12B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F11F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F13E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 FCC6FFFF \[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +6 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e FCD5FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +7 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F186\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==9] then { pass $testname } else { fail $testname }
+}
+
+proc do_udf {} {
+ set testname "udf.s: udf tests part 1"
+ set x 0
+
+ gas_start "udf.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F601\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F611\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F621\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F631\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 F641\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a F651\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F661\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e F671\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F681\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F691\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F6A1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F6B1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F6C1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F6D1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F6E1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e F6F1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 F501\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 F511\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 F521\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 F531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 F541\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002a F551\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c F561\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002e F571\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 F581\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0032 F591\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 F5A1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0036 F5B1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 F5C1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003a F5D1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c F5E1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003e F5F1\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 F9017F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0043 F9117F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0046 F9217F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0049 F9317F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c F9417F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004f F9517F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0052 F9617F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0055 F9717F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0058 F9817F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005b F9917F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 005e F9A17F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0061 F9B17F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0064 F9C17F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0067 F9D17F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006a F9E17F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 006d F9F17F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0070 FB01FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0074 FB11FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0078 FB21FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 007c FB31FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0080 FB41FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0084 FB51FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0088 FB61FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 008c FB71FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0090 FB81FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0094 FB91FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0098 FBA1FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 009c FBB1FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a0 FBC1FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a4 FBD1FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00a8 FBE1FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ac FBF1FF7F\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b0 FD01FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +66 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00b6 FD11FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +67 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00bc FD21FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +68 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c2 FD31FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +69 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00c8 FD41FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +70 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ce FD51FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +71 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00d4 FD61FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +72 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00da FD71FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +73 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e0 FD81FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +74 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00e6 FD91FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +75 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00ec FDA1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +76 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f2 FDB1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +77 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00f8 FDC1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +78 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 00fe FDD1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +79 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0104 FDE1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +80 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 010a FDF1FFFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +81 +0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0110 F90580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0113 F91580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0116 F92580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0119 F93580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011c F94580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 011f F95580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0122 F96580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0125 F97580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0128 F98580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 012b F99580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 012e F9A580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0131 F9B580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0134 F9C580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0137 F9D580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 013a F9E580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 013d F9F580\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0140 FB050080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0144 FB150080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0148 FB250080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 014c FB350080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0150 FB450080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0154 FB550080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0158 FB650080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 015c FB750080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0160 FB850080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0164 FB950080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0168 FBA50080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 016c FBB50080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0170 FBC50080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0174 FBD50080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0178 FBE50080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 017c FBF50080\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0180 FD050000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +114 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0186 FD150000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +115 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 018c FD250000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +116 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0192 FD350000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +117 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0198 FD450000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +118 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 019e FD550000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +119 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01a4 FD650000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +120 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01aa FD750000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +121 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01b0 FD850000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +122 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01b6 FD950000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +123 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01bc FDA50000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +124 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01c2 FDB50000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +125 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01c8 FDC50000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +126 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01ce FDD50000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +127 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01d4 FDE50000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +128 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 01da FDF50000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +129 +0100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==160] then { pass $testname } else { fail $testname }
+}
+
+
+if [istarget mn10300*-*-*] then {
+ # Test the basic instruction parser.
+ do_add
+ do_bcc
+ do_bit
+ do_cmp
+ do_ext
+ do_extend
+ do_logical
+ do_loop
+ do_mov1
+ do_mov2
+ do_mov3
+ do_mov4
+ do_movbu
+ do_movhu
+ do_movm
+ do_muldiv
+ do_other
+ do_shift
+ do_sub
+ do_udf
+}
diff --git a/gas/testsuite/gas/mn10300/bcc.s b/gas/testsuite/gas/mn10300/bcc.s
new file mode 100644
index 00000000000..8292dce04fd
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/bcc.s
@@ -0,0 +1,17 @@
+ .text
+foo:
+ beq foo
+ bne foo
+ bgt foo
+ bge foo
+ ble foo
+ blt foo
+ bhi foo
+ bcc foo
+ bls foo
+ bcs foo
+ bvc foo
+ bvs foo
+ bnc foo
+ bns foo
+ bra foo
diff --git a/gas/testsuite/gas/mn10300/bit.s b/gas/testsuite/gas/mn10300/bit.s
new file mode 100644
index 00000000000..f5c551952b4
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/bit.s
@@ -0,0 +1,12 @@
+ .text
+ btst 64,d1
+ btst 8192,d2
+ btst 131071,d3
+ btst 64,(8,a1)
+ btst 64,(131071)
+ bset d1,(a2)
+ bset 64,(8,a1)
+ bset 64,(131071)
+ bclr d1,(a2)
+ bclr 64,(8,a1)
+ bclr 64,(131071)
diff --git a/gas/testsuite/gas/mn10300/cmp.s b/gas/testsuite/gas/mn10300/cmp.s
new file mode 100644
index 00000000000..7f8a71d4199
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/cmp.s
@@ -0,0 +1,11 @@
+ .text
+ cmp d1,d2
+ cmp d2,a3
+ cmp a3,d3
+ cmp a3,a2
+ cmp 16,d3
+ cmp 256,d2
+ cmp 131071,d1
+ cmp 16,a3
+ cmp 256,a2
+ cmp 131071,a1
diff --git a/gas/testsuite/gas/mn10300/ext.s b/gas/testsuite/gas/mn10300/ext.s
new file mode 100644
index 00000000000..f0e2e79006f
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/ext.s
@@ -0,0 +1,7 @@
+ .text
+ ext d1
+ extb d2
+ extbu d3
+ exth d2
+ exthu d1
+
diff --git a/gas/testsuite/gas/mn10300/extend.s b/gas/testsuite/gas/mn10300/extend.s
new file mode 100644
index 00000000000..d6405b71fda
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/extend.s
@@ -0,0 +1,15 @@
+ .text
+ putx d1
+ getx d2
+ mulq d1,d2
+ mulq 16,d2
+ mulq 256,d3
+ mulq 131071,d3
+ mulqu d1,d2
+ mulqu 16,d2
+ mulqu 256,d3
+ mulqu 131071,d3
+ sat16 d2,d3
+ sat24 d3,d2
+ bsch d1,d2
+
diff --git a/gas/testsuite/gas/mn10300/logical.s b/gas/testsuite/gas/mn10300/logical.s
new file mode 100644
index 00000000000..b0976db33da
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/logical.s
@@ -0,0 +1,15 @@
+ .text
+ and d1,d2
+ and 127,d2
+ and 32767,d3
+ and 131071,d3
+ and 32767,psw
+ or d1,d2
+ or 127,d2
+ or 32767,d3
+ or 131071,d3
+ or 32767,psw
+ xor d1,d2
+ xor 32767,d3
+ xor 131071,d3
+ not d3
diff --git a/gas/testsuite/gas/mn10300/loop.s b/gas/testsuite/gas/mn10300/loop.s
new file mode 100644
index 00000000000..d9182070e43
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/loop.s
@@ -0,0 +1,15 @@
+ .text
+foo:
+ leq
+ lne
+ lgt
+ lge
+ lle
+ llt
+ lhi
+ lcc
+ lls
+ lcs
+ lra
+ setlb
+
diff --git a/gas/testsuite/gas/mn10300/mov1.s b/gas/testsuite/gas/mn10300/mov1.s
new file mode 100644
index 00000000000..a44cc553b65
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/mov1.s
@@ -0,0 +1,17 @@
+ .text
+ mov d1,d2
+ mov d1,a2
+ mov a2,d1
+ mov a2,a1
+ mov sp,a2
+ mov a1,sp
+ mov d2,psw
+ mov mdr,d1
+ mov d2,mdr
+ mov (a2),d1
+ mov (8,a2),d1
+ mov (256,a2),d1
+ mov (131071,a2),d1
+ mov (8,sp),d1
+ mov (256,sp),d1
+ mov psw,d3
diff --git a/gas/testsuite/gas/mn10300/mov2.s b/gas/testsuite/gas/mn10300/mov2.s
new file mode 100644
index 00000000000..50d1edc5a80
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/mov2.s
@@ -0,0 +1,16 @@
+ .text
+ mov (131071,sp),d1
+ mov (d1,a1),d2
+ mov (32768),d1
+ mov (131071),d1
+ mov (a2),a1
+ mov (8,a2),a1
+ mov (256,a2),a1
+ mov (131071,a2),a1
+ mov (8,sp),a1
+ mov (256,sp),a1
+ mov (131071,sp),a1
+ mov (d1,a1),a2
+ mov (32768),a1
+ mov (131071),a1
+ mov (32,a1),sp
diff --git a/gas/testsuite/gas/mn10300/mov3.s b/gas/testsuite/gas/mn10300/mov3.s
new file mode 100644
index 00000000000..90ec0b98a9b
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/mov3.s
@@ -0,0 +1,16 @@
+ .text
+ mov d1,(a2)
+ mov d1,(32,a2)
+ mov d1,(256,a2)
+ mov d1,(131071,a2)
+ mov d1,(32,sp)
+ mov d1,(32768,sp)
+ mov d1,(131071,sp)
+ mov d1,(d2,a2)
+ mov d1,(128)
+ mov d1,(131071)
+ mov a1,(a2)
+ mov a1,(32,a2)
+ mov a1,(256,a2)
+ mov a1,(131071,a2)
+ mov a1,(32,sp)
diff --git a/gas/testsuite/gas/mn10300/mov4.s b/gas/testsuite/gas/mn10300/mov4.s
new file mode 100644
index 00000000000..99d69c12dc3
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/mov4.s
@@ -0,0 +1,13 @@
+ .text
+ mov a1,(32768,sp)
+ mov a1,(131071,sp)
+ mov a1,(d2,a2)
+ mov a1,(128)
+ mov a1,(131071)
+ mov sp,(32,a1)
+ mov 8,d1
+ mov 256,d1
+ mov 131071,d1
+ mov 8,a1
+ mov 256,a1
+ mov 131071,a1
diff --git a/gas/testsuite/gas/mn10300/movbu.s b/gas/testsuite/gas/mn10300/movbu.s
new file mode 100644
index 00000000000..8fdb7beef4d
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/movbu.s
@@ -0,0 +1,21 @@
+ .text
+ movbu (a2),d1
+ movbu (8,a2),d1
+ movbu (256,a2),d1
+ movbu (131071,a2),d1
+ movbu (8,sp),d1
+ movbu (256,sp),d1
+ movbu (131071,sp),d1
+ movbu (d1,a1),d2
+ movbu (32768),d1
+ movbu (131071),d1
+ movbu d1,(a2)
+ movbu d1,(32,a2)
+ movbu d1,(256,a2)
+ movbu d1,(131071,a2)
+ movbu d1,(32,sp)
+ movbu d1,(32768,sp)
+ movbu d1,(131071,sp)
+ movbu d1,(d2,a2)
+ movbu d1,(128)
+ movbu d1,(131071)
diff --git a/gas/testsuite/gas/mn10300/movhu.s b/gas/testsuite/gas/mn10300/movhu.s
new file mode 100644
index 00000000000..4637e80df7f
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/movhu.s
@@ -0,0 +1,21 @@
+ .text
+ movhu (a2),d1
+ movhu (8,a2),d1
+ movhu (256,a2),d1
+ movhu (131071,a2),d1
+ movhu (8,sp),d1
+ movhu (256,sp),d1
+ movhu (131071,sp),d1
+ movhu (d1,a1),d2
+ movhu (32768),d1
+ movhu (131071),d1
+ movhu d1,(a2)
+ movhu d1,(32,a2)
+ movhu d1,(256,a2)
+ movhu d1,(131071,a2)
+ movhu d1,(32,sp)
+ movhu d1,(32768,sp)
+ movhu d1,(131071,sp)
+ movhu d1,(d2,a2)
+ movhu d1,(128)
+ movhu d1,(131071)
diff --git a/gas/testsuite/gas/mn10300/movm.s b/gas/testsuite/gas/mn10300/movm.s
new file mode 100644
index 00000000000..ccfc6830ef3
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/movm.s
@@ -0,0 +1,5 @@
+ .text
+ movm (sp),[a2,a3]
+ movm (sp),[d2,d3,a2,a3,other]
+ movm [a2,a3],(sp)
+ movm [d2,d3,a2,a3,other],(sp)
diff --git a/gas/testsuite/gas/mn10300/muldiv.s b/gas/testsuite/gas/mn10300/muldiv.s
new file mode 100644
index 00000000000..3f11e5d1661
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/muldiv.s
@@ -0,0 +1,5 @@
+ .text
+ mul d1,d2
+ mulu d2,d3
+ div d3,d3
+ divu d3,d2
diff --git a/gas/testsuite/gas/mn10300/other.s b/gas/testsuite/gas/mn10300/other.s
new file mode 100644
index 00000000000..3eaf74a3f5f
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/other.s
@@ -0,0 +1,20 @@
+ .text
+ clr d2
+ inc d1
+ inc a2
+ inc4 a3
+ jmp (a2)
+ jmp 256
+ jmp 131071
+ call 256,[a2,a3],9
+ call 131071,[a2,a3],32
+ calls (a2)
+ calls 256
+ calls 131071
+ ret [a2,a3],7
+ retf [a2,a3],5
+ rets
+ rti
+ trap
+ nop
+ rtm
diff --git a/gas/testsuite/gas/mn10300/shift.s b/gas/testsuite/gas/mn10300/shift.s
new file mode 100644
index 00000000000..ec8c9cefb9a
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/shift.s
@@ -0,0 +1,10 @@
+ .text
+ asr d1,d2
+ asr 4,d2
+ lsr d2,d3
+ lsr 4,d3
+ asl d3,d2
+ asl 4,d2
+ asl2 d2
+ ror d1
+ rol d2
diff --git a/gas/testsuite/gas/mn10300/sub.s b/gas/testsuite/gas/mn10300/sub.s
new file mode 100644
index 00000000000..13dc663d847
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/sub.s
@@ -0,0 +1,8 @@
+ .text
+ sub d1,d2
+ sub d2,a3
+ sub a3,d3
+ sub a3,a2
+ sub 131071,d2
+ sub 131071,a1
+ subc d1,d2
diff --git a/gas/testsuite/gas/mn10300/udf.s b/gas/testsuite/gas/mn10300/udf.s
new file mode 100644
index 00000000000..87cbd136f23
--- /dev/null
+++ b/gas/testsuite/gas/mn10300/udf.s
@@ -0,0 +1,129 @@
+ .text
+ udf00 d0,d1
+ udf01 d0,d1
+ udf02 d0,d1
+ udf03 d0,d1
+ udf04 d0,d1
+ udf05 d0,d1
+ udf06 d0,d1
+ udf07 d0,d1
+ udf08 d0,d1
+ udf09 d0,d1
+ udf10 d0,d1
+ udf11 d0,d1
+ udf12 d0,d1
+ udf13 d0,d1
+ udf14 d0,d1
+ udf15 d0,d1
+ udf20 d0,d1
+ udf21 d0,d1
+ udf22 d0,d1
+ udf23 d0,d1
+ udf24 d0,d1
+ udf25 d0,d1
+ udf26 d0,d1
+ udf27 d0,d1
+ udf28 d0,d1
+ udf29 d0,d1
+ udf30 d0,d1
+ udf31 d0,d1
+ udf32 d0,d1
+ udf33 d0,d1
+ udf34 d0,d1
+ udf35 d0,d1
+ udf00 127,d1
+ udf01 127,d1
+ udf02 127,d1
+ udf03 127,d1
+ udf04 127,d1
+ udf05 127,d1
+ udf06 127,d1
+ udf07 127,d1
+ udf08 127,d1
+ udf09 127,d1
+ udf10 127,d1
+ udf11 127,d1
+ udf12 127,d1
+ udf13 127,d1
+ udf14 127,d1
+ udf15 127,d1
+ udf00 32767,d1
+ udf01 32767,d1
+ udf02 32767,d1
+ udf03 32767,d1
+ udf04 32767,d1
+ udf05 32767,d1
+ udf06 32767,d1
+ udf07 32767,d1
+ udf08 32767,d1
+ udf09 32767,d1
+ udf10 32767,d1
+ udf11 32767,d1
+ udf12 32767,d1
+ udf13 32767,d1
+ udf14 32767,d1
+ udf15 32767,d1
+ udf00 65535,d1
+ udf01 65535,d1
+ udf02 65535,d1
+ udf03 65535,d1
+ udf04 65535,d1
+ udf05 65535,d1
+ udf06 65535,d1
+ udf07 65535,d1
+ udf08 65535,d1
+ udf09 65535,d1
+ udf10 65535,d1
+ udf11 65535,d1
+ udf12 65535,d1
+ udf13 65535,d1
+ udf14 65535,d1
+ udf15 65535,d1
+ udfu00 128,d1
+ udfu01 128,d1
+ udfu02 128,d1
+ udfu03 128,d1
+ udfu04 128,d1
+ udfu05 128,d1
+ udfu06 128,d1
+ udfu07 128,d1
+ udfu08 128,d1
+ udfu09 128,d1
+ udfu10 128,d1
+ udfu11 128,d1
+ udfu12 128,d1
+ udfu13 128,d1
+ udfu14 128,d1
+ udfu15 128,d1
+ udfu00 32768,d1
+ udfu01 32768,d1
+ udfu02 32768,d1
+ udfu03 32768,d1
+ udfu04 32768,d1
+ udfu05 32768,d1
+ udfu06 32768,d1
+ udfu07 32768,d1
+ udfu08 32768,d1
+ udfu09 32768,d1
+ udfu10 32768,d1
+ udfu11 32768,d1
+ udfu12 32768,d1
+ udfu13 32768,d1
+ udfu14 32768,d1
+ udfu15 32768,d1
+ udfu00 65536,d1
+ udfu01 65536,d1
+ udfu02 65536,d1
+ udfu03 65536,d1
+ udfu04 65536,d1
+ udfu05 65536,d1
+ udfu06 65536,d1
+ udfu07 65536,d1
+ udfu08 65536,d1
+ udfu09 65536,d1
+ udfu10 65536,d1
+ udfu11 65536,d1
+ udfu12 65536,d1
+ udfu13 65536,d1
+ udfu14 65536,d1
+ udfu15 65536,d1
diff --git a/gas/testsuite/gas/mri/char.d b/gas/testsuite/gas/mri/char.d
new file mode 100644
index 00000000000..025f4b5914f
--- /dev/null
+++ b/gas/testsuite/gas/mri/char.d
@@ -0,0 +1,9 @@
+#objcopy: -O srec
+#name: MRI character constants
+#as: -M
+
+# Test MRI character constants
+
+S0.*
+S113....(61616263616263646500000061276200)|(61616263646362610000006500622761).*
+#pass
diff --git a/gas/testsuite/gas/mri/char.s b/gas/testsuite/gas/mri/char.s
new file mode 100644
index 00000000000..7b0a83a9d2e
--- /dev/null
+++ b/gas/testsuite/gas/mri/char.s
@@ -0,0 +1,6 @@
+; Test MRI style character constants.
+
+ dc.b 'a'
+ dc.b 'abc'
+ dc.l 'abcde'
+ dc.l 'a''b'
diff --git a/gas/testsuite/gas/mri/comment.d b/gas/testsuite/gas/mri/comment.d
new file mode 100644
index 00000000000..30434dd2f85
--- /dev/null
+++ b/gas/testsuite/gas/mri/comment.d
@@ -0,0 +1,9 @@
+#nm: --extern-only
+#name: MRI comments
+#as: -M
+
+# Test MRI comments
+
+0+02 A RAM
+0+01 A ROM
+ * U label
diff --git a/gas/testsuite/gas/mri/comment.s b/gas/testsuite/gas/mri/comment.s
new file mode 100644
index 00000000000..857318fa654
--- /dev/null
+++ b/gas/testsuite/gas/mri/comment.s
@@ -0,0 +1,13 @@
+ xref label
+ xdef ROM,RAM
+ * this is a comment
+
+ dc.l label loop if we haven't reach end yet
+
+ROM EQU $00000001 * word wide
+RAM EQU $00000002 word wide
+ dc.l RAM
+ dc.l 0 ,really,a,comment
+; a comment
+ ; another comment
+ ; another comment
diff --git a/gas/testsuite/gas/mri/common.d b/gas/testsuite/gas/mri/common.d
new file mode 100644
index 00000000000..c1c1530c213
--- /dev/null
+++ b/gas/testsuite/gas/mri/common.d
@@ -0,0 +1,8 @@
+#nm: --extern-only
+#name: MRI common sections
+#as: -M
+
+# Test MRI common sections
+
+0+08 C 00com2
+0+08 C com1
diff --git a/gas/testsuite/gas/mri/common.s b/gas/testsuite/gas/mri/common.s
new file mode 100644
index 00000000000..d735c6b9205
--- /dev/null
+++ b/gas/testsuite/gas/mri/common.s
@@ -0,0 +1,11 @@
+; Test MRI common sections
+ common com1
+ ds.l 1
+com2 common 00
+ ds.l 1
+incom ds.l 1
+ common com1
+ ds.l 1
+ data
+ dc.l com1
+ dc.l incom
diff --git a/gas/testsuite/gas/mri/constants.d b/gas/testsuite/gas/mri/constants.d
new file mode 100644
index 00000000000..7210022284d
--- /dev/null
+++ b/gas/testsuite/gas/mri/constants.d
@@ -0,0 +1,20 @@
+#nm: --extern-only
+#name: MRI constants
+#as: -M
+
+# Test MRI style constants
+
+0*0 T foo
+0*a A s01
+0*a A s02
+0*a A s03
+0*a A s04
+0*a A s05
+0*a A s06
+0*a A s07
+0*a A s08
+0*a A s09
+0*61 A s10
+0*61 A s11
+0*61626364 A s12
+0*61276200 A s13
diff --git a/gas/testsuite/gas/mri/constants.s b/gas/testsuite/gas/mri/constants.s
new file mode 100644
index 00000000000..0034e6765e1
--- /dev/null
+++ b/gas/testsuite/gas/mri/constants.s
@@ -0,0 +1,31 @@
+ xdef s01,s02,s03,s04,s05,s06,s07,s08,s09,s10,s11,s12,s13
+s01 equ %1010
+s02 equ 1010b
+s03 equ @12
+s04 equ 12o
+s05 equ 12q
+s06 equ 10
+s07 equ 10d
+s08 equ $a
+s09 equ 0ah
+s10 equ 'a'
+s11 equ A'a'
+s12 equ 'abcd'
+s13 equ 'a''b'
+
+ xdef foo
+foo
+ moveq.l #%1010,d0
+ moveq.l #1010b,d0
+ moveq.l #@12,d0
+ moveq.l #12o,d0
+ moveq.l #12q,d0
+ moveq.l #10,d0
+ moveq.l #10d,d0
+ moveq.l #$a,d0
+ moveq.l #0ah,d0
+ moveq.l #'a',d0
+ moveq.l #A'a',d0
+ nop
+
+ end
diff --git a/gas/testsuite/gas/mri/empty.s b/gas/testsuite/gas/mri/empty.s
new file mode 100644
index 00000000000..94c2cdd71de
--- /dev/null
+++ b/gas/testsuite/gas/mri/empty.s
@@ -0,0 +1,9 @@
+SBT MACRO ; empty macro
+ ENDM
+
+ SBT arg1
+ SBT arg2 - one tww
+ SBT arg3 - one two three
+ SBT arg4 - one two three four
+ SBT arg5 - one two three four five
+ SBT arg6 - one two (three)
diff --git a/gas/testsuite/gas/mri/equ.d b/gas/testsuite/gas/mri/equ.d
new file mode 100644
index 00000000000..e5f9a867768
--- /dev/null
+++ b/gas/testsuite/gas/mri/equ.d
@@ -0,0 +1,7 @@
+#nm: --extern-only
+#name: MRI EQU
+#as: -M
+
+# Test the MRI EQU directive
+
+0*4 A SYMBOL
diff --git a/gas/testsuite/gas/mri/equ.s b/gas/testsuite/gas/mri/equ.s
new file mode 100644
index 00000000000..a6512a10cae
--- /dev/null
+++ b/gas/testsuite/gas/mri/equ.s
@@ -0,0 +1,3 @@
+# Test the MRI EQU directive
+ XDEF SYMBOL
+SYMBOL EQU 4
diff --git a/gas/testsuite/gas/mri/expr.d b/gas/testsuite/gas/mri/expr.d
new file mode 100644
index 00000000000..71dee4eb21f
--- /dev/null
+++ b/gas/testsuite/gas/mri/expr.d
@@ -0,0 +1,11 @@
+#nm: --extern-only
+#name: MRI expressions
+#as: -M
+
+# Test expressions in MRI mode
+
+00* A s1
+00*12 A s2
+00*6 A s3
+(00000000)?ff* A s4
+00* A s5
diff --git a/gas/testsuite/gas/mri/expr.s b/gas/testsuite/gas/mri/expr.s
new file mode 100644
index 00000000000..57677c18e16
--- /dev/null
+++ b/gas/testsuite/gas/mri/expr.s
@@ -0,0 +1,7 @@
+; Test expressions in MRI mode
+ xdef s1,s2,s3,s4,s5
+s1 equ 1>2
+s2 equ 3<<1*3
+s3 equ 5!!3
+s4 equ "0
+s5 equ (1>=2)!(1<>1)
diff --git a/gas/testsuite/gas/mri/float.d b/gas/testsuite/gas/mri/float.d
new file mode 100644
index 00000000000..dea627afa65
--- /dev/null
+++ b/gas/testsuite/gas/mri/float.d
@@ -0,0 +1,10 @@
+#objcopy: -O srec
+#name: MRI floating point constants
+#as: -M
+
+# Test MRI floating point constants
+
+S0.*
+S118....(123456789ABCDEF03F800000412000004120000042)|(F0DEBC9A785634120000803F000020410000204100).*
+S10.....(C80000)|(00C842).*
+#pass
diff --git a/gas/testsuite/gas/mri/float.s b/gas/testsuite/gas/mri/float.s
new file mode 100644
index 00000000000..637f9c6c919
--- /dev/null
+++ b/gas/testsuite/gas/mri/float.s
@@ -0,0 +1,7 @@
+; Test floating point constants in MRI mode.
+
+ dc.d :1234_5678_9abc_def0
+ dc.s 1.0
+ dc.s 1e1
+ dc.s 1_e_1
+ dc.s 1E2
diff --git a/gas/testsuite/gas/mri/for.d b/gas/testsuite/gas/mri/for.d
new file mode 100644
index 00000000000..e75fb95c7bb
--- /dev/null
+++ b/gas/testsuite/gas/mri/for.d
@@ -0,0 +1,30 @@
+#objdump: -d --prefix-addresses
+#name: MRI structured for
+#as: -M
+
+# Test MRI structured for pseudo-op.
+
+.*: file format .*
+
+Disassembly of section .text:
+0+000 <foo> clrw %d1
+0+002 <foo\+(0x|)2> movew #1,%d0
+0+006 <foo\+(0x|)6> cmpiw #10,%d0
+0+00a <foo\+(0x|)a> blts 0+016 <foo\+(0x|)16>
+0+00c <foo\+(0x|)c> addw %d0,%d1
+0+00e <foo\+(0x|)e> bvcs 0+012 <foo\+(0x|)12>
+0+010 <foo\+(0x|)10> bras 0+016 <foo\+(0x|)16>
+0+012 <foo\+(0x|)12> addqw #2,%d0
+0+014 <foo\+(0x|)14> bras 0+006 <foo\+(0x|)6>
+0+016 <foo\+(0x|)16> clrw %d1
+0+018 <foo\+(0x|)18> movew #10,%d0
+0+01c <foo\+(0x|)1c> cmpiw #1,%d0
+0+020 <foo\+(0x|)20> bgts 0+030 <foo\+(0x|)30>
+0+022 <foo\+(0x|)22> cmpiw #100,%d1
+0+026 <foo\+(0x|)26> bgts 0+02a <foo\+(0x|)2a>
+0+028 <foo\+(0x|)28> bras 0+02c <foo\+(0x|)2c>
+0+02a <foo\+(0x|)2a> addw %d0,%d1
+0+02c <foo\+(0x|)2c> subqw #1,%d0
+0+02e <foo\+(0x|)2e> bras 0+01c <foo\+(0x|)1c>
+0+030 <foo\+(0x|)30> nop
+0+032 <foo\+(0x|)32> nop
diff --git a/gas/testsuite/gas/mri/for.s b/gas/testsuite/gas/mri/for.s
new file mode 100644
index 00000000000..7524725a4b7
--- /dev/null
+++ b/gas/testsuite/gas/mri/for.s
@@ -0,0 +1,22 @@
+; Test MRI structured for pseudo-op.
+
+ xdef foo
+foo
+ clr d1
+ for d0 = #1 to #10 by #2 do
+ add d0,d1 arbitrary text 'in comment field
+ if <vs> then
+ break
+ endi
+ endf
+
+ clr d1
+ for d0 = #10 downto #1 do
+ if d1 <ge> #100 then
+ next
+ endi
+ add d0,d1
+ endf
+
+ nop
+ nop
diff --git a/gas/testsuite/gas/mri/if.d b/gas/testsuite/gas/mri/if.d
new file mode 100644
index 00000000000..832972cd402
--- /dev/null
+++ b/gas/testsuite/gas/mri/if.d
@@ -0,0 +1,25 @@
+#objdump: -d --prefix-addresses
+#name: MRI structured if
+#as: -M
+
+# Test MRI structured if pseudo-op.
+
+.*: file format .*
+
+Disassembly of section .text:
+0+000 <foo> cmpw %d1,%d0
+0+002 <foo\+(0x|)2> bles 0+014 <foo\+(0x|)14>
+0+004 <foo\+(0x|)4> cmpw %d2,%d0
+0+006 <foo\+(0x|)6> bles 0+014 <foo\+(0x|)14>
+0+008 <foo\+(0x|)8> cmpw %d1,%d2
+0+00a <foo\+(0x|)a> bles 0+010 <foo\+(0x|)10>
+0+00c <foo\+(0x|)c> movew %d1,%d3
+0+00e <foo\+(0x|)e> bras 0+012 <foo\+(0x|)12>
+0+010 <foo\+(0x|)10> movew %d2,%d3
+0+012 <foo\+(0x|)12> bras 0+01e <foo\+(0x|)1e>
+0+014 <foo\+(0x|)14> cmpw %d0,%d1
+0+016 <foo\+(0x|)16> bgts 0+01c <foo\+(0x|)1c>
+0+018 <foo\+(0x|)18> cmpw %d0,%d2
+0+01a <foo\+(0x|)1a> bles 0+01e <foo\+(0x|)1e>
+0+01c <foo\+(0x|)1c> movew %d0,%d3
+0+01e <foo\+(0x|)1e> nop
diff --git a/gas/testsuite/gas/mri/if.s b/gas/testsuite/gas/mri/if.s
new file mode 100644
index 00000000000..2646be8ab12
--- /dev/null
+++ b/gas/testsuite/gas/mri/if.s
@@ -0,0 +1,17 @@
+; Test MRI structured if pseudo-op.
+
+ xdef foo
+foo
+ if d1 <gt> d0 and d2 <gt> d0 then
+ if d1 <gt> d2 then
+ move d1,d3
+ else
+ move d2,d3
+ endi
+ else
+ if d0 <gt> d1 or d0 <gt> d2 then
+ move d0,d3
+ endi
+ endi
+
+ nop
diff --git a/gas/testsuite/gas/mri/immconst.d b/gas/testsuite/gas/mri/immconst.d
new file mode 100644
index 00000000000..ef2da10afd6
--- /dev/null
+++ b/gas/testsuite/gas/mri/immconst.d
@@ -0,0 +1,22 @@
+#objdump: -d --prefix-addresses
+#name: MRI immediate constants
+#as: -M
+#source: constants.s
+
+# Test MRI immediate constants
+
+.*: file format .*
+
+Disassembly of section .text:
+0+000 <foo> moveq #10,%d0
+0+002 <foo\+(0x|)2> moveq #10,%d0
+0+004 <foo\+(0x|)4> moveq #10,%d0
+0+006 <foo\+(0x|)6> moveq #10,%d0
+0+008 <foo\+(0x|)8> moveq #10,%d0
+0+00a <foo\+(0x|)a> moveq #10,%d0
+0+00c <foo\+(0x|)c> moveq #10,%d0
+0+00e <foo\+(0x|)e> moveq #10,%d0
+0+010 <foo\+(0x|)10> moveq #10,%d0
+0+012 <foo\+(0x|)12> moveq #97,%d0
+0+014 <foo\+(0x|)14> moveq #97,%d0
+0+016 <foo\+(0x|)16> nop
diff --git a/gas/testsuite/gas/mri/label.d b/gas/testsuite/gas/mri/label.d
new file mode 100644
index 00000000000..9ce5858daf7
--- /dev/null
+++ b/gas/testsuite/gas/mri/label.d
@@ -0,0 +1,8 @@
+#nm: --extern-only
+#name: MRI label
+#as: -M
+
+# Test using an MRI style label
+
+0000* T LABEL
+[ ]*U SYMBOL
diff --git a/gas/testsuite/gas/mri/label.s b/gas/testsuite/gas/mri/label.s
new file mode 100644
index 00000000000..b05ec2a4f4b
--- /dev/null
+++ b/gas/testsuite/gas/mri/label.s
@@ -0,0 +1,5 @@
+; Test using an MRI style label
+* Also test MRI style comments
+! And another comment
+ XDEF LABEL
+LABEL DC.L SYMBOL ; And yet another comment
diff --git a/gas/testsuite/gas/mri/moveml.d b/gas/testsuite/gas/mri/moveml.d
new file mode 100644
index 00000000000..2c36fa8ee5c
--- /dev/null
+++ b/gas/testsuite/gas/mri/moveml.d
@@ -0,0 +1,27 @@
+#objdump: -d
+#name: MRI moveml
+#as: -M
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <.text>:
+ 0: 4cdf 07fc moveml %sp@\+,%d2-%a2
+ 4: 4cdf 07fc moveml %sp@\+,%d2-%a2
+ 8: 48f9 07fc 0000 moveml %d2-%a2,0 <.text>
+ e: 0000
+ 10: 48f9 07fc 0000 moveml %d2-%a2,0 <.text>
+ 16: 0000
+ 18: 4cf9 07fc 0000 moveml 0 <.text>,%d2-%a2
+ 1e: 0000
+ 20: 4cf9 07fc 0000 moveml 0 <.text>,%d2-%a2
+ 26: 0000
+ 28: 4cf9 07fc 0001 moveml 16000 <fdsa>,%d2-%a2
+ 2e: 6000
+ 30: 4cf9 07fc 0001 moveml 16000 <fdsa>,%d2-%a2
+ 36: 6000
+ 38: 48f9 07fc 0001 moveml %d2-%a2,16000 <fdsa>
+ 3e: 6000
+ 40: 48f9 07fc 0001 moveml %d2-%a2,16000 <fdsa>
+ 46: 6000
diff --git a/gas/testsuite/gas/mri/moveml.s b/gas/testsuite/gas/mri/moveml.s
new file mode 100644
index 00000000000..b8fc728ba85
--- /dev/null
+++ b/gas/testsuite/gas/mri/moveml.s
@@ -0,0 +1,17 @@
+asdf reg a0-a2/d2-d7
+fdsa equ $16000
+
+ movem.l (sp)+,a0-a2/d2-d7
+ movem.l (sp)+,asdf
+
+ movem.l a0-a2/d2-d7,symbol
+ movem.l asdf,symbol
+
+ movem.l symbol,a0-a2/d2-d7
+ movem.l symbol,asdf
+
+ movem.l fdsa,a0-a2/d2-d7
+ movem.l fdsa,asdf
+
+ movem.l a0-a2/d2-d7,fdsa
+ movem.l asdf,fdsa
diff --git a/gas/testsuite/gas/mri/mri.exp b/gas/testsuite/gas/mri/mri.exp
new file mode 100644
index 00000000000..f3fcded1e59
--- /dev/null
+++ b/gas/testsuite/gas/mri/mri.exp
@@ -0,0 +1,28 @@
+#
+# Test the m68k MRI compatibility mode.
+#
+# I originally thought that most of tests applied to any MRI
+# assembler, but it turns out that different MRI assemblers use
+# different syntaxes.
+#
+
+if ![istarget "m68*-*-*"] {
+ return
+}
+
+run_dump_test label
+run_dump_test equ
+run_dump_test constants
+run_dump_test immconst
+run_dump_test float
+run_dump_test char
+run_dump_test expr
+run_dump_test common
+run_dump_test comment
+gas_test "empty.s" "-M" "" "MRI empty macro"
+run_dump_test for
+run_dump_test if
+run_dump_test repeat
+run_dump_test while
+run_dump_test semi
+run_dump_test moveml
diff --git a/gas/testsuite/gas/mri/repeat.d b/gas/testsuite/gas/mri/repeat.d
new file mode 100644
index 00000000000..3cc5f638390
--- /dev/null
+++ b/gas/testsuite/gas/mri/repeat.d
@@ -0,0 +1,16 @@
+#objdump: -d --prefix-addresses
+#name: MRI structured repeat
+#as: -M
+
+# Test MRI structured repeat pseudo-op.
+
+.*: file format .*
+
+Disassembly of section .text:
+0+000 <foo> bccs 0+000 <foo>
+0+002 <foo\+(0x|)2> clrw %d1
+0+004 <foo\+(0x|)4> addqw #1,%d1
+0+006 <foo\+(0x|)6> cmpiw #10,%d1
+0+00a <foo\+(0x|)a> bgts 0+004 <foo\+(0x|)4>
+0+00c <foo\+(0x|)c> nop
+0+00e <foo\+(0x|)e> nop
diff --git a/gas/testsuite/gas/mri/repeat.s b/gas/testsuite/gas/mri/repeat.s
new file mode 100644
index 00000000000..0e4ea2b6527
--- /dev/null
+++ b/gas/testsuite/gas/mri/repeat.s
@@ -0,0 +1,14 @@
+; Test MRI structured repeat pseudo-op.
+
+ xdef foo
+foo
+ repeat
+ until <cs>
+
+ clr d1
+ repeat
+ add #1,d1
+ until d1 <ge> #10
+
+ nop
+ nop
diff --git a/gas/testsuite/gas/mri/semi.d b/gas/testsuite/gas/mri/semi.d
new file mode 100644
index 00000000000..0decce18472
--- /dev/null
+++ b/gas/testsuite/gas/mri/semi.d
@@ -0,0 +1,9 @@
+#objdump: -s -j .text
+#name: MRI semi
+#as: -M
+
+.*: .*
+
+Contents of section .text:
+ 0000 3b203b20 3a203a20 00000000 00000000 ; ; : : ........
+ 0010 00000000 00000000 00000000 00000000 ................
diff --git a/gas/testsuite/gas/mri/semi.s b/gas/testsuite/gas/mri/semi.s
new file mode 100644
index 00000000000..5b30677c470
--- /dev/null
+++ b/gas/testsuite/gas/mri/semi.s
@@ -0,0 +1,14 @@
+semicolon macro
+ dc.b '; '
+ endm
+
+colon macro
+ dc.b ': '
+ endm
+
+ semicolon
+ dc.b '; '
+ colon
+ dc.b ': '
+
+ p2align 5
diff --git a/gas/testsuite/gas/mri/while.d b/gas/testsuite/gas/mri/while.d
new file mode 100644
index 00000000000..d8dd37a3594
--- /dev/null
+++ b/gas/testsuite/gas/mri/while.d
@@ -0,0 +1,18 @@
+#objdump: -d --prefix-addresses
+#name: MRI structured while
+#as: -M
+
+# Test MRI structure while pseudo-op.
+
+.*: file format .*
+
+Disassembly of section .text:
+0+000 <foo> bccs 0+004 <foo\+(0x|)4>
+0+002 <foo\+(0x|)2> bras 0+000 <foo>
+0+004 <foo\+(0x|)4> clrw %d1
+0+006 <foo\+(0x|)6> cmpiw #10,%d1
+0+00a <foo\+(0x|)a> blts 0+010 <foo\+(0x|)10>
+0+00c <foo\+(0x|)c> addqw #1,%d1
+0+00e <foo\+(0x|)e> bras 0+006 <foo\+(0x|)6>
+0+010 <foo\+(0x|)10> nop
+0+012 <foo\+(0x|)12> nop
diff --git a/gas/testsuite/gas/mri/while.s b/gas/testsuite/gas/mri/while.s
new file mode 100644
index 00000000000..35cbdbbbc15
--- /dev/null
+++ b/gas/testsuite/gas/mri/while.s
@@ -0,0 +1,14 @@
+; Test MRI structured while pseudo-op.
+
+ xdef foo
+foo
+ while <cs> do
+ endw
+
+ clr d1
+ while d1 <le> #10 do
+ add #1,d1
+ endw
+
+ nop
+ nop
diff --git a/gas/testsuite/gas/ppc/astest.d b/gas/testsuite/gas/ppc/astest.d
new file mode 100644
index 00000000000..68aab554dff
--- /dev/null
+++ b/gas/testsuite/gas/ppc/astest.d
@@ -0,0 +1,74 @@
+#objdump: -Dr
+#name: PowerPC test 1
+
+.*: +file format elf32-powerpc
+
+Disassembly of section \.text:
+
+0+0000000 <foo>:
+ 0: 60 00 00 00 nop
+ 4: 60 00 00 00 nop
+ 8: 60 00 00 00 nop
+
+0+000000c <a>:
+ c: 48 00 00 04 b 10 <apfour>
+
+0+0000010 <apfour>:
+ 10: 48 00 00 08 b 18 <apfour\+0x8>
+ 14: 48 00 00 00 b 14 <apfour\+0x4>
+ 14: R_PPC_REL24 x
+ 18: 48 00 00 04 b 1c <apfour\+0xc>
+ 18: R_PPC_REL24 \.data\+0x4
+ 1c: 48 00 00 00 b 1c <apfour\+0xc>
+ 1c: R_PPC_REL24 z
+ 20: 48 00 00 14 b 34 <apfour\+0x24>
+ 20: R_PPC_REL24 z\+0x14
+ 24: 48 00 00 04 b 28 <apfour\+0x18>
+ 28: 48 00 00 00 b 28 <apfour\+0x18>
+ 28: R_PPC_REL24 a
+ 2c: 4b ff ff e4 b 10 <apfour>
+ 30: 48 00 00 04 b 34 <apfour\+0x24>
+ 30: R_PPC_REL24 a\+0x4
+ 34: 4b ff ff e0 b 14 <apfour\+0x4>
+ 38: 48 00 00 00 b 38 <apfour\+0x28>
+ 38: R_PPC_LOCAL24PC a
+ 3c: 4b ff ff d4 b 10 <apfour>
+
+ 40: 00 00 00 40 \.long 0x40
+ 40: R_PPC_ADDR32 \.text\+0x40
+
+ 44: 00 00 00 4c \.long 0x4c
+ 44: R_PPC_ADDR32 \.text\+0x4c
+ 48: 00 00 00 00 \.long 0x0
+ 48: R_PPC_REL32 x
+ 4c: 00 00 00 04 \.long 0x4
+ 4c: R_PPC_REL32 x\+0x4
+ \.\.\.
+ 50: R_PPC_REL32 z
+ 54: R_PPC_REL32 y
+ 58: R_PPC_ADDR32 x
+ 5c: R_PPC_ADDR32 y
+ 60: R_PPC_ADDR32 z
+ 64: ff ff ff fc fnmsub f31,f31,f31,f31
+ 64: R_PPC_ADDR32 x\+0xf+ffffffc
+ 68: ff ff ff fc fnmsub f31,f31,f31,f31
+ 68: R_PPC_ADDR32 y\+0xf+ffffffc
+ 6c: ff ff ff fc fnmsub f31,f31,f31,f31
+ 6c: R_PPC_ADDR32 z\+0xf+ffffffc
+ 70: ff ff ff 9c \.long 0xffffff9c
+ 74: ff ff ff 9c \.long 0xffffff9c
+ \.\.\.
+ 78: R_PPC_ADDR32 a
+ 7c: R_PPC_ADDR32 b
+ 80: R_PPC_ADDR32 apfour
+ 84: ff ff ff fc fnmsub f31,f31,f31,f31
+ 88: 00 00 00 02 \.long 0x2
+ 88: R_PPC_ADDR32 apfour\+0x2
+ 8c: 00 00 00 00 \.long 0x0
+Disassembly of section \.data:
+
+0+0000000 <x>:
+ 0: 00 00 00 00 \.long 0x0
+
+0+0000004 <y>:
+ 4: 00 00 00 00 \.long 0x0
diff --git a/gas/testsuite/gas/ppc/astest.s b/gas/testsuite/gas/ppc/astest.s
new file mode 100644
index 00000000000..f1af216313c
--- /dev/null
+++ b/gas/testsuite/gas/ppc/astest.s
@@ -0,0 +1,52 @@
+ .section ".data"
+ .globl x
+ .globl z
+x: .long 0
+z = . + 4
+four = z - x - 4
+y: .long 0
+
+ .section ".text"
+foo:
+ nop ; nop ; nop
+ .globl a
+a: b .+4
+b: b .+8
+ b x
+ b y
+ b z
+ b z+20
+ b .+four
+ b a
+ b b
+ b a+4
+ b b+4
+ b a@local
+ b b@local
+ .long .
+ .long .+8
+ .long x-.
+ .long x+4-.
+ .long z-.
+ .long y-.
+ .long x
+ .long y
+ .long z
+ .long x-four
+ .long y-four
+ .long z-four
+ .long a-.
+ .long b-.
+ .long a
+ .long b
+
+apfour = a + four
+ .long apfour
+ .long a-apfour
+ .long apfour+2
+ .long apfour-b
+
+ .type foo,@function
+ .type a,@function
+ .type b,@function
+ .type apfour,@function
diff --git a/gas/testsuite/gas/ppc/astest2.d b/gas/testsuite/gas/ppc/astest2.d
new file mode 100644
index 00000000000..740e3bfe19d
--- /dev/null
+++ b/gas/testsuite/gas/ppc/astest2.d
@@ -0,0 +1,75 @@
+#objdump: -Dr
+#name: PowerPC test 2
+
+.*: +file format elf32-powerpc
+
+Disassembly of section .text:
+
+0+0000000 <foo>:
+ 0: 60 00 00 00 nop
+ 4: 60 00 00 00 nop
+ 8: 60 00 00 00 nop
+ c: 48 00 00 04 b 10 <foo\+0x10>
+ 10: 48 00 00 08 b 18 <foo\+0x18>
+ 14: 48 00 00 00 b 14 <foo\+0x14>
+ 14: R_PPC_REL24 x
+ 18: 48 00 00 04 b 1c <foo\+0x1c>
+ 18: R_PPC_REL24 .data\+0x4
+ 1c: 48 00 00 00 b 1c <foo\+0x1c>
+ 1c: R_PPC_REL24 z
+ 20: 48 00 00 14 b 34 <foo\+0x34>
+ 20: R_PPC_REL24 z\+0x14
+ 24: 48 00 00 04 b 28 <foo\+0x28>
+ 28: 48 00 00 00 b 28 <foo\+0x28>
+ 28: R_PPC_REL24 a
+ 2c: 48 00 00 50 b 7c <apfour>
+ 30: 48 00 00 04 b 34 <foo\+0x34>
+ 30: R_PPC_REL24 a\+0x4
+ 34: 48 00 00 4c b 80 <apfour\+0x4>
+ 38: 48 00 00 00 b 38 <foo\+0x38>
+ 38: R_PPC_LOCAL24PC a
+ 3c: 48 00 00 40 b 7c <apfour>
+
+ 40: 00 00 00 40 .long 0x40
+ 40: R_PPC_ADDR32 .text\+0x40
+
+ 44: 00 00 00 4c .long 0x4c
+ 44: R_PPC_ADDR32 .text\+0x4c
+ 48: 00 00 00 00 .long 0x0
+ 48: R_PPC_REL32 x
+ 4c: 00 00 00 04 .long 0x4
+ 4c: R_PPC_REL32 x\+0x4
+ ...
+ 50: R_PPC_REL32 z
+ 54: R_PPC_REL32 y
+ 58: R_PPC_ADDR32 x
+ 5c: R_PPC_ADDR32 y
+ 60: R_PPC_ADDR32 z
+ 64: ff ff ff fc fnmsub f31,f31,f31,f31
+ 64: R_PPC_ADDR32 x\+0xf+ffffffc
+ 68: ff ff ff fc fnmsub f31,f31,f31,f31
+ 68: R_PPC_ADDR32 y\+0xf+ffffffc
+ 6c: ff ff ff fc fnmsub f31,f31,f31,f31
+ 6c: R_PPC_ADDR32 z\+0xf+ffffffc
+ 70: 00 00 00 08 .long 0x8
+ 74: 00 00 00 08 .long 0x8
+
+0+0000078 <a>:
+ 78: 00 00 00 00 .long 0x0
+ 78: R_PPC_ADDR32 a
+
+0+000007c <apfour>:
+ ...
+ 7c: R_PPC_ADDR32 b
+ 80: R_PPC_ADDR32 apfour
+ 84: ff ff ff fc fnmsub f31,f31,f31,f31
+ 88: 00 00 00 02 .long 0x2
+ 88: R_PPC_ADDR32 apfour\+0x2
+ 8c: 00 00 00 00 .long 0x0
+Disassembly of section .data:
+
+0+0000000 <x>:
+ 0: 00 00 00 00 .long 0x0
+
+0+0000004 <y>:
+ 4: 00 00 00 00 .long 0x0
diff --git a/gas/testsuite/gas/ppc/astest2.s b/gas/testsuite/gas/ppc/astest2.s
new file mode 100644
index 00000000000..5af223378fd
--- /dev/null
+++ b/gas/testsuite/gas/ppc/astest2.s
@@ -0,0 +1,52 @@
+four = 4
+ .section ".text"
+foo:
+ nop ; nop ; nop
+ .globl a
+ b .+4
+ b .+8
+ b x
+ b y
+ b z
+ b z+20
+ b .+four
+ b a
+ b b
+ b a+4
+ b b+4
+ b a@local
+ b b@local
+ .long .
+ .long .+8
+ .long x-.
+ .long x+4-.
+ .long z-.
+ .long y-.
+ .long x
+ .long y
+ .long z
+ .long x-four
+ .long y-four
+ .long z-four
+ .long a-.
+ .long b-.
+a: .long a
+b: .long b
+
+apfour = a + four
+ .long apfour
+ .long a-apfour
+ .long apfour+2
+ .long apfour-b
+
+ .section ".data"
+ .globl x
+ .globl z
+x: .long 0
+z = . + 4
+y: .long 0
+
+ .type foo,@function
+ .type a,@function
+ .type b,@function
+ .type apfour,@function
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
new file mode 100644
index 00000000000..572fbc345b4
--- /dev/null
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -0,0 +1,21 @@
+#
+# Some PowerPC tests
+#
+
+# These tests are currently ELF specific, only because nobody has
+# converted them to look for XCOFF relocations.
+
+if { [istarget powerpc*-*-*bsd*] \
+ || [istarget powerpc*-*-elf*] \
+ || [istarget powerpc*-*-eabi*] \
+ || [istarget powerpc*-*-sysv4*] \
+ || [istarget powerpc*-*-linux*] \
+ || [istarget powerpc*-*-solaris*] \
+ || [istarget powerpc*-*-rtems*] } then {
+ run_dump_test "astest"
+ run_dump_test "astest2"
+}
+
+if { [istarget powerpc*-*-*] } then {
+ run_dump_test "simpshft"
+}
diff --git a/gas/testsuite/gas/ppc/simpshft.d b/gas/testsuite/gas/ppc/simpshft.d
new file mode 100644
index 00000000000..06893d55395
--- /dev/null
+++ b/gas/testsuite/gas/ppc/simpshft.d
@@ -0,0 +1,27 @@
+#objdump: -s -j .text
+#as: -mppc64
+#name: PowerPC test 3, simplified shifts
+
+.*
+
+Contents of section \.text:
+ 0000 78640fe0 7883f80e 78a545e4 78640020 xd..x...x.E.xd.
+ 0010 54640ffe 5083f800 54a5402e 5464043e Td..P...T.@.Td.>
+ 0020 78640004 786407e4 7864f806 7864ffe6 xd..xd..xd..xd..
+ 0030 7864f842 7864ffe2 7864000c 7864080c xd.Bxd..xd..xd..
+ 0040 78640fac 786407ec 78640000 78640800 xd..xd..xd..xd..
+ 0050 7864f802 78640000 7864f802 78640800 xd..xd..xd..xd..
+ 0060 78652010 786407e4 7864f806 78640000 xe .xd..xd..xd..
+ 0070 7864f842 78640fe0 78640000 78640040 xd.Bxd..xd..xd.@
+ 0080 786407e0 786407e4 786407a4 78640004 xd..xd..xd..xd..
+ 0090 78640008 78640048 786407e8 78640fa8 xd..xd.Hxd..xd..
+ 00a0 7864f80a 54640000 5464003e 5464f800 xd..Td..Td.>Td..
+ 00b0 5464f83e 5464f87e 5464fffe 50640000 Td.>Td.~Td..Pd..
+ 00c0 5064003e 50640ffe 5064f800 5064003e Pd.>Pd..Pd..Pd.>
+ 00d0 506407fe 5464003e 5464083e 5464f83e Pd..Td.>Td.>Td.>
+ 00e0 5464003e 5464f83e 5464083e 5c65203e Td.>Td.>Td.>\\e >
+ 00f0 5464003e 5464083c 5464f800 5464003e Td.>Td.<Td..Td.>
+ 0100 5464f87e 54640ffe 5464003e 5464007e Td.~Td..Td.>Td.~
+ 0110 546407fe 5464003e 5464003c 54640000 Td..Td.>Td.<Td..
+ 0120 5464003e 5464007e 546407fe 54640fbc Td.>Td.~Td..Td..
+ 0130 5464f800 00000000 Td......
diff --git a/gas/testsuite/gas/ppc/simpshft.s b/gas/testsuite/gas/ppc/simpshft.s
new file mode 100644
index 00000000000..39ff98d07b6
--- /dev/null
+++ b/gas/testsuite/gas/ppc/simpshft.s
@@ -0,0 +1,110 @@
+# These are all the examples from section F.4 of
+# "PowerPC Microprocessor Family: The Programming Environments".
+# 64-bit examples
+ extrdi %r4,%r3,1,0
+ insrdi %r3,%r4,1,0
+ sldi %r5,%r5,8
+ clrldi %r4,%r3,32
+# 32-bit examples
+ extrwi %r4,%r3,1,0
+ insrwi %r3,%r4,1,0
+ slwi %r5,%r5,8
+ clrlwi %r4,%r3,16
+
+
+# These test the remaining corner cases for 64-bit operations.
+ extldi %r4,%r3,1,0
+ extldi %r4,%r3,64,0
+ extldi %r4,%r3,1,63
+ extldi %r4,%r3,64,63 # bit weird, that one.
+
+ extrdi %r4,%r3,63,0
+ extrdi %r4,%r3,1,62
+
+ insrdi %r4,%r3,64,0
+ insrdi %r4,%r3,63,0
+ insrdi %r4,%r3,1,62
+ insrdi %r4,%r3,1,63
+
+ rotldi %r4,%r3,0
+ rotldi %r4,%r3,1
+ rotldi %r4,%r3,63
+
+ rotrdi %r4,%r3,0
+ rotrdi %r4,%r3,1
+ rotrdi %r4,%r3,63
+
+ rotld %r5,%r3,%r4
+
+ sldi %r4,%r3,0
+ sldi %r4,%r3,63
+
+ srdi %r4,%r3,0
+ srdi %r4,%r3,1
+ srdi %r4,%r3,63
+
+ clrldi %r4,%r3,0
+ clrldi %r4,%r3,1
+ clrldi %r4,%r3,63
+
+ clrrdi %r4,%r3,0
+ clrrdi %r4,%r3,1
+ clrrdi %r4,%r3,63
+
+ clrlsldi %r4,%r3,0,0
+ clrlsldi %r4,%r3,1,0
+ clrlsldi %r4,%r3,63,0
+ clrlsldi %r4,%r3,63,1
+ clrlsldi %r4,%r3,63,63
+
+# These test the remaining corner cases for 32-bit operations.
+ extlwi %r4,%r3,1,0
+ extlwi %r4,%r3,32,0
+ extlwi %r4,%r3,1,31
+ extlwi %r4,%r3,32,31 # bit weird, that one.
+
+ extrwi %r4,%r3,31,0
+ extrwi %r4,%r3,1,30
+
+ inslwi %r4,%r3,1,0
+ inslwi %r4,%r3,32,0
+ inslwi %r4,%r3,1,31
+
+ insrwi %r4,%r3,1,0
+ insrwi %r4,%r3,32,0
+ insrwi %r4,%r3,1,31
+
+ rotlwi %r4,%r3,0
+ rotlwi %r4,%r3,1
+ rotlwi %r4,%r3,31
+
+ rotrwi %r4,%r3,0
+ rotrwi %r4,%r3,1
+ rotrwi %r4,%r3,31
+
+ rotlw %r5,%r3,%r4
+
+ slwi %r4,%r3,0
+ slwi %r4,%r3,1
+ slwi %r4,%r3,31
+
+ srwi %r4,%r3,0
+ srwi %r4,%r3,1
+ srwi %r4,%r3,31
+
+ clrlwi %r4,%r3,0
+ clrlwi %r4,%r3,1
+ clrlwi %r4,%r3,31
+
+ clrrwi %r4,%r3,0
+ clrrwi %r4,%r3,1
+ clrrwi %r4,%r3,31
+
+ clrlslwi %r4,%r3,0,0
+ clrlslwi %r4,%r3,1,0
+ clrlslwi %r4,%r3,31,0
+ clrlslwi %r4,%r3,31,1
+ clrlslwi %r4,%r3,31,31
+
+# Force alignment so that we pass the test on AIX
+ .p2align 3
diff --git a/gas/testsuite/gas/sh/basic.exp b/gas/testsuite/gas/sh/basic.exp
new file mode 100644
index 00000000000..30dbb0b2d06
--- /dev/null
+++ b/gas/testsuite/gas/sh/basic.exp
@@ -0,0 +1,86 @@
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by Cygnus Support.
+
+proc do_fp {} {
+ set testname "fp.s: floating point tests (sh3e)"
+ set x 0
+
+ gas_start "fp.s" "-al"
+
+ # Check the assembled instruction against a table built by the HP assembler
+ # Any differences should be checked by hand -- with the number of problems
+ # I've seen in the HP assembler I don't completely trust it.
+ #
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 F008\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 F00A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 F009\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 F00B\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 F006\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a F007\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c F10C\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e F08D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 F09D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 F100\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 F101\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 F102\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 F103\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a F10E\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c F104\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e F105\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 F04D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 F05D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 F06D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 F02D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 F03D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002a F00D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c F01D\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002e 435A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 4356\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0032 436A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 4366\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0036 035A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 4352\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003a 036A\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c 4362\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==31] then { pass $testname } else { fail $testname }
+}
+
+
+if [istarget sh*-*-*] then {
+ # Test the basic instruction parser.
+ do_fp
+}
diff --git a/gas/testsuite/gas/sh/fp.s b/gas/testsuite/gas/sh/fp.s
new file mode 100644
index 00000000000..352d86480ba
--- /dev/null
+++ b/gas/testsuite/gas/sh/fp.s
@@ -0,0 +1,44 @@
+ .file "test.c"
+ .data
+
+! Hitachi SH cc1 (cygnus-2.7.1-950728) arguments: -O -fpeephole
+! -ffunction-cse -freg-struct-return -fdelayed-branch -fcommon -fgnu-linker
+
+gcc2_compiled.:
+___gnu_compiled_c:
+ .text
+ .align 2
+ .global _foo
+_foo:
+ fmov.s @r0,fr0
+ fmov.s fr0,@r0
+ fmov.s @r0+,fr0
+ fmov.s fr0,@-r0
+ fmov.s @(r0,r0),fr0
+ fmov.s fr0,@(r0,r0)
+ fmov fr0,fr1
+ fldi0 fr0
+ fldi1 fr0
+ fadd fr0,fr1
+ fsub fr0,fr1
+ fmul fr0,fr1
+ fdiv fr0,fr1
+ fmac fr0,fr0,fr1
+ fcmp/eq fr0,fr1
+ fcmp/gt fr0,fr1
+ fneg fr0
+ fabs fr0
+ fsqrt fr0
+ float fpul,fr0
+ ftrc fr0,fpul
+ fsts fpul,fr0
+ flds fr0,fpul
+ lds r3,fpul
+ lds.l @r3+,fpul
+ lds r3,fpscr
+ lds.l @r3+,fpscr
+ sts fpul,r3
+ sts.l fpul,@-r3
+ sts fpscr,r3
+ sts.l fpscr,@-r3
+
diff --git a/gas/testsuite/gas/sparc-solaris/addend.exp b/gas/testsuite/gas/sparc-solaris/addend.exp
new file mode 100644
index 00000000000..27838c7b14f
--- /dev/null
+++ b/gas/testsuite/gas/sparc-solaris/addend.exp
@@ -0,0 +1,36 @@
+#
+# Solaris on SPARC tests
+#
+
+if [istarget sparc*-*-solaris2*] then {
+ set x1 0
+ set x2 0
+ set x3 0
+ set x4 0
+ set x5 0
+ set x6 0
+ set testname "addends (part 2)"
+ if [gas_test_old "addend.s" "" "addends (part 1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+ while 1 {
+ # These are what we get using the Solaris assembler.
+ expect {
+ -re "08 R_SPARC_WDISP22 +foo1\[+\]+0x0+04\[^\n\]*\n" { incr x1 }
+ -re "0c R_SPARC_WDISP22 +foo1\[+\]+0x0+04\[^\n\]*\n" { incr x2 }
+ -re "10 R_SPARC_WDISP22 +foo1\[^\n\]*\n" { incr x3 }
+ -re "14 R_SPARC_WDISP22 +foo1\[^\n\]*\n" { incr x4 }
+ -re "1c R_SPARC_32 +foo1\[^\n\]*\n" { incr x5 }
+ -re "20 R_SPARC_32 +foo1\[+\]+0x0+04\[^\n\]*\n" { incr x6 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ objdump_finish
+ if [all_ones $x1 $x2 $x3 $x4 $x5 $x6] then {
+ pass $testname
+ } else {
+ fail $testname
+ }
+ }
+}
diff --git a/gas/testsuite/gas/sparc-solaris/addend.s b/gas/testsuite/gas/sparc-solaris/addend.s
new file mode 100644
index 00000000000..18eb108a9b3
--- /dev/null
+++ b/gas/testsuite/gas/sparc-solaris/addend.s
@@ -0,0 +1,11 @@
+ .global foo
+foo:
+ nop
+ nop
+ ba foo1+0x4
+ ba foo1+0x4
+ ba foo1
+ ba foo1
+ nop
+ .word foo1
+ .word foo1+4
diff --git a/gas/testsuite/gas/sparc-solaris/gas.exp b/gas/testsuite/gas/sparc-solaris/gas.exp
new file mode 100644
index 00000000000..63af6917e98
--- /dev/null
+++ b/gas/testsuite/gas/sparc-solaris/gas.exp
@@ -0,0 +1,10 @@
+#
+# Solaris-2 on SPARC tests
+#
+# The two compilers, cc and gcc, generate quite different debugging
+# records. Verify that we can accept both.
+#
+if [istarget sparc-*-solaris2*] then {
+ gas_test "sol-cc.s" "" $stdoptlist "SPARC Solaris cc -g"
+ gas_test "sol-gcc.s" "" $stdoptlist "SPARC Solaris gcc -g"
+}
diff --git a/gas/testsuite/gas/sparc-solaris/sol-cc.s b/gas/testsuite/gas/sparc-solaris/sol-cc.s
new file mode 100644
index 00000000000..8a250dabb93
--- /dev/null
+++ b/gas/testsuite/gas/sparc-solaris/sol-cc.s
@@ -0,0 +1,81 @@
+ .section ".text" ! [internal]
+ .proc 4
+ .global main
+ .align 4
+ .global main
+main:
+!#PROLOGUE# 0
+!#PROLOGUE# 1
+ save %sp,-96,%sp
+ sethi %hi(.L18),%o0
+ sethi %hi(msg),%o1
+ or %o1,%lo(msg),%o1 ! [internal]
+ call printf,2
+ or %o0,%lo(.L18),%o0 ! [internal]
+ ret
+ restore %g0,0,%o0
+ .type main,#function
+ .size main,(.-main)
+ .section ".data" ! [internal]
+ .align 4
+Ddata.data:
+ .section ".bss" ! [internal]
+Bbss.bss:
+ .section ".rodata" ! [internal]
+Drodata.rodata:
+ .file "hi-sol.c"
+ .global msg
+ .global msg
+msg:
+ .ascii "hello, world!\0"
+ .type msg,#object
+ .size msg,14
+ .section ".data1", #write, #alloc ! [internal]
+ .align 4
+.L18:
+ .ascii "%s\n\0"
+ .ident "acomp: (CDS) SPARCompilers 2.0.1 03 Sep 1992"
+ .section "text" ! [internal]
+ .stabs "/cygint/s1/users/raeburn/",100,0,0,0
+ .stabs "hi-sol.c",100,0,3,0
+ .stabs "",56,0,0,0
+ .stabs "",56,0,0,0
+ .stabs "Xt ; g ; O ; V=2.0",60,0,0,0x2bb773ba
+ .stabs "char:t(0,1)=bsc1;0;8;",128,0,0,0
+ .stabs "short:t(0,2)=bs2;0;16;",128,0,0,0
+ .stabs "int:t(0,3)=bs4;0;32;",128,0,0,0
+ .stabs "long:t(0,4)=bs4;0;32;",128,0,0,0
+ .stabs "long long:t(0,5)=bs8;0;64;",128,0,0,0
+ .stabs "signed char:t(0,6)=bsc1;0;8;",128,0,0,0
+ .stabs "signed short:t(0,7)=bs2;0;16;",128,0,0,0
+ .stabs "signed int:t(0,8)=bs4;0;32;",128,0,0,0
+ .stabs "signed long:t(0,9)=bs4;0;32;",128,0,0,0
+ .stabs "signed long long:t(0,10)=bs8;0;64;",128,0,0,0
+ .stabs "unsigned char:t(0,11)=buc1;0;8;",128,0,0,0
+ .stabs "unsigned short:t(0,12)=bu2;0;16;",128,0,0,0
+ .stabs "unsigned int:t(0,13)=bu4;0;32;",128,0,0,0
+ .stabs "unsigned long:t(0,14)=bu4;0;32;",128,0,0,0
+ .stabs "unsigned long long:t(0,15)=bu8;0;64;",128,0,0,0
+ .stabs "float:t(0,16)=R1;4;",128,0,0,0
+ .stabs "double:t(0,17)=R2;8;",128,0,0,0
+ .stabs "long double:t(0,18)=R6;16;",128,0,0,0
+ .stabs "void:t(0,19)=bs0;0;0",128,0,0,0
+ .stabs "msg:G(0,20)=ar(0,3);0;13;(0,1)",32,0,14,0
+ .stabs "main:F(0,3);(0,3);(0,21)=*(0,22)=*(0,1)",36,0,0,main
+ .stabs "main",42,0,0,0
+ .stabn 192,0,1,0
+ .stabn 68,0,4,0
+ .stabs "argc:p(0,3)",160,0,4,68
+ .stabs "argv:p(0,21)",160,0,4,72
+ .stabs "printf:P(0,3)",36,0,0,0
+ .stabn 224,0,1,0
+ .stabs "",98,0,0,0
+ .section "text" ! [internal]
+ .xstabs ".stab.index","/cygint/s1/users/raeburn/",100,0,0,0
+ .xstabs ".stab.index","hi-sol.c",100,0,3,0
+ .xstabs ".stab.index","",56,0,0,0
+ .xstabs ".stab.index","",56,0,0,0
+ .xstabs ".stab.index","Xt ; g ; O ; V=2.0",60,0,0,0x2bb773ba
+ .xstabs ".stab.index","msg",32,0,0,0
+ .xstabs ".stab.index","main",42,0,0,0
+ .xstabs ".stab.index","main",36,0,0,0
diff --git a/gas/testsuite/gas/sparc-solaris/sol-gcc.s b/gas/testsuite/gas/sparc-solaris/sol-gcc.s
new file mode 100644
index 00000000000..295fdcdd889
--- /dev/null
+++ b/gas/testsuite/gas/sparc-solaris/sol-gcc.s
@@ -0,0 +1,66 @@
+ .file "hi-sol.c"
+.stabs "/1h/devo/src/gas/testsuite/gas/",100,0,0,.LLtext0
+.stabs "hi-sol.c",100,0,0,.LLtext0
+.section ".text"
+.LLtext0:
+ .stabs "gcc2_compiled.", 0x3c, 0, 0, 0
+.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
+.stabs "char:t2=r2;0;127;",128,0,0,0
+.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
+.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
+.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
+.stabs "short int:t6=r1;-32768;32767;",128,0,0,0
+.stabs "long long int:t7=r1;0;-1;",128,0,0,0
+.stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
+.stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
+.stabs "signed char:t10=r1;-128;127;",128,0,0,0
+.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
+.stabs "float:t12=r1;4;0;",128,0,0,0
+.stabs "double:t13=r1;8;0;",128,0,0,0
+.stabs "long double:t14=r1;8;0;",128,0,0,0
+.stabs "void:t15=15",128,0,0,0
+.stabs "msg:G16=ar1;0;13;2",32,0,0,0
+ .global msg
+.section ".rodata"
+ .align 8
+ .type msg,#object
+ .size msg,14
+msg:
+ .asciz "hello, world!"
+ .align 8
+.LLC0:
+ .asciz "%s\n"
+.section ".text"
+ .align 4
+.stabs "main:F1",36,0,0,main
+.stabs "argc:P1",64,0,0,24
+.stabs "argv:P17=*18=*2",64,0,0,25
+ .global main
+ .type main,#function
+ .proc 04
+main:
+.stabn 68,0,4,.LM1-main
+.LM1:
+ !#PROLOGUE# 0
+ save %sp,-112,%sp
+ !#PROLOGUE# 1
+.stabn 68,0,5,.LM2-main
+.LM2:
+.LLBB2:
+ sethi %hi(.LLC0),%o0
+ or %o0,%lo(.LLC0),%o0
+ sethi %hi(msg),%o1
+ call printf,0
+ or %o1,%lo(msg),%o1
+.stabn 68,0,6,.LM3-main
+.LM3:
+.stabn 68,0,7,.LM4-main
+.LM4:
+.LLBE2:
+ ret
+ restore %g0,0,%o0
+.LLfe1:
+ .size main,.LLfe1-main
+.stabn 192,0,0,.LLBB2-main
+.stabn 224,0,0,.LLBE2-main
+ .ident "GCC: (GNU) cygnus-2.3.3"
diff --git a/gas/testsuite/gas/sparc/asi.d b/gas/testsuite/gas/sparc/asi.d
new file mode 100644
index 00000000000..835ea1a8b28
--- /dev/null
+++ b/gas/testsuite/gas/sparc/asi.d
@@ -0,0 +1,35 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 asi
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: c4 80 40 00 lda \[ %g1 \] \(0\), %g2
+ 4: c4 80 5f e0 lda \[ %g1 \] \(255\), %g2
+ 8: c4 80 42 00 lda \[ %g1 \] #ASI_AIUP, %g2
+ c: c4 80 42 20 lda \[ %g1 \] #ASI_AIUS, %g2
+ 10: c4 80 43 00 lda \[ %g1 \] #ASI_AIUP_L, %g2
+ 14: c4 80 43 20 lda \[ %g1 \] #ASI_AIUS_L, %g2
+ 18: c4 80 50 00 lda \[ %g1 \] #ASI_P, %g2
+ 1c: c4 80 50 20 lda \[ %g1 \] #ASI_S, %g2
+ 20: c4 80 50 40 lda \[ %g1 \] #ASI_PNF, %g2
+ 24: c4 80 50 60 lda \[ %g1 \] #ASI_SNF, %g2
+ 28: c4 80 51 00 lda \[ %g1 \] #ASI_P_L, %g2
+ 2c: c4 80 51 20 lda \[ %g1 \] #ASI_S_L, %g2
+ 30: c4 80 51 40 lda \[ %g1 \] #ASI_PNF_L, %g2
+ 34: c4 80 51 60 lda \[ %g1 \] #ASI_SNF_L, %g2
+ 38: c4 80 42 00 lda \[ %g1 \] #ASI_AIUP, %g2
+ 3c: c4 80 42 20 lda \[ %g1 \] #ASI_AIUS, %g2
+ 40: c4 80 43 00 lda \[ %g1 \] #ASI_AIUP_L, %g2
+ 44: c4 80 43 20 lda \[ %g1 \] #ASI_AIUS_L, %g2
+ 48: c4 80 50 00 lda \[ %g1 \] #ASI_P, %g2
+ 4c: c4 80 50 20 lda \[ %g1 \] #ASI_S, %g2
+ 50: c4 80 50 40 lda \[ %g1 \] #ASI_PNF, %g2
+ 54: c4 80 50 60 lda \[ %g1 \] #ASI_SNF, %g2
+ 58: c4 80 51 00 lda \[ %g1 \] #ASI_P_L, %g2
+ 5c: c4 80 51 20 lda \[ %g1 \] #ASI_S_L, %g2
+ 60: c4 80 51 40 lda \[ %g1 \] #ASI_PNF_L, %g2
+ 64: c4 80 51 60 lda \[ %g1 \] #ASI_SNF_L, %g2
diff --git a/gas/testsuite/gas/sparc/asi.s b/gas/testsuite/gas/sparc/asi.s
new file mode 100644
index 00000000000..c56fe9c24db
--- /dev/null
+++ b/gas/testsuite/gas/sparc/asi.s
@@ -0,0 +1,28 @@
+# Test asi's.
+ .text
+ lduwa [%g1]0,%g2
+ lduwa [%g1]255,%g2
+ lduwa [%g1]#ASI_AIUP,%g2
+ lduwa [%g1]#ASI_AIUS,%g2
+ lduwa [%g1]#ASI_AIUP_L,%g2
+ lduwa [%g1]#ASI_AIUS_L,%g2
+ lduwa [%g1]#ASI_P,%g2
+ lduwa [%g1]#ASI_S,%g2
+ lduwa [%g1]#ASI_PNF,%g2
+ lduwa [%g1]#ASI_SNF,%g2
+ lduwa [%g1]#ASI_P_L,%g2
+ lduwa [%g1]#ASI_S_L,%g2
+ lduwa [%g1]#ASI_PNF_L,%g2
+ lduwa [%g1]#ASI_SNF_L,%g2
+ lduwa [%g1]#ASI_AS_IF_USER_PRIMARY,%g2
+ lduwa [%g1]#ASI_AS_IF_USER_SECONDARY,%g2
+ lduwa [%g1]#ASI_AS_IF_USER_PRIMARY_LITTLE,%g2
+ lduwa [%g1]#ASI_AS_IF_USER_SECONDARY_LITTLE,%g2
+ lduwa [%g1]#ASI_PRIMARY,%g2
+ lduwa [%g1]#ASI_SECONDARY,%g2
+ lduwa [%g1]#ASI_PRIMARY_NOFAULT,%g2
+ lduwa [%g1]#ASI_SECONDARY_NOFAULT,%g2
+ lduwa [%g1]#ASI_PRIMARY_LITTLE,%g2
+ lduwa [%g1]#ASI_SECONDARY_LITTLE,%g2
+ lduwa [%g1]#ASI_PRIMARY_NOFAULT_LITTLE,%g2
+ lduwa [%g1]#ASI_SECONDARY_NOFAULT_LITTLE,%g2
diff --git a/gas/testsuite/gas/sparc/membar.d b/gas/testsuite/gas/sparc/membar.d
new file mode 100644
index 00000000000..6ab6b2edb16
--- /dev/null
+++ b/gas/testsuite/gas/sparc/membar.d
@@ -0,0 +1,19 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 membar
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: 81 43 e0 00 membar 0
+ 4: 81 43 e0 7f membar #Sync|#MemIssue|#Lookaside|#StoreStore|#LoadStore|#StoreLoad|#LoadLoad
+ 8: 81 43 e0 7f membar #Sync|#MemIssue|#Lookaside|#StoreStore|#LoadStore|#StoreLoad|#LoadLoad
+ c: 81 43 e0 40 membar #Sync
+ 10: 81 43 e0 20 membar #MemIssue
+ 14: 81 43 e0 10 membar #Lookaside
+ 18: 81 43 e0 08 membar #StoreStore
+ 1c: 81 43 e0 04 membar #LoadStore
+ 20: 81 43 e0 02 membar #StoreLoad
+ 24: 81 43 e0 01 membar #LoadLoad
diff --git a/gas/testsuite/gas/sparc/membar.s b/gas/testsuite/gas/sparc/membar.s
new file mode 100644
index 00000000000..d805e0720fc
--- /dev/null
+++ b/gas/testsuite/gas/sparc/membar.s
@@ -0,0 +1,12 @@
+# Test membar args
+ .text
+ membar 0
+ membar 127
+ membar #Sync|#MemIssue|#Lookaside|#StoreStore|#LoadStore|#StoreLoad|#LoadLoad
+ membar #Sync
+ membar #MemIssue
+ membar #Lookaside
+ membar #StoreStore
+ membar #LoadStore
+ membar #StoreLoad
+ membar #LoadLoad
diff --git a/gas/testsuite/gas/sparc/mism-1.s b/gas/testsuite/gas/sparc/mism-1.s
new file mode 100644
index 00000000000..fac5e482704
--- /dev/null
+++ b/gas/testsuite/gas/sparc/mism-1.s
@@ -0,0 +1,22 @@
+! Test architecture mismatch warnings.
+! We don't test every possible mismatch, we just want to be reasonable sure
+! the mismatch checking code works.
+!
+! { dg-do assemble { target sparc*-*-* } }
+! { dg-options -Av6 }
+
+! sparclite
+
+ divscc %g1,%g2,%g3 ! { dg-error "mismatch|sparclite" "sparclite divscc mismatch" }
+
+ scan %g1,%g2,%g3 ! { dg-error "mismatch|sparclite" "sparclite scan mismatch" }
+
+! v9
+
+ movrz %g1,%g2,%g3 ! { dg-error "mismatch|v9" "v9 fp reg mismatch" }
+
+! v9a
+
+ shutdown ! { dg-error "mismatch|v9a" "v9a shutdown mismatch" }
+
+foo:
diff --git a/gas/testsuite/gas/sparc/mismatch.exp b/gas/testsuite/gas/sparc/mismatch.exp
new file mode 100644
index 00000000000..6f89de2a244
--- /dev/null
+++ b/gas/testsuite/gas/sparc/mismatch.exp
@@ -0,0 +1,20 @@
+# Test architecture mismatch errors.
+#
+# GAS issues two lines of error text for each mismatch:
+#
+# mm-lite.s:7: Error: Architecture mismatch on "divscc".
+# mm-lite.s:7: (Requires sparclite; requested architecture is v8.)
+#
+# The suggested regexp argument to dg-error is "mismatch|<arch>".
+
+if [istarget sparc*-*-*] {
+
+ load_lib gas-dg.exp
+
+ dg-init
+
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/mism-*.s]] "" ""
+
+ dg-finish
+
+}
diff --git a/gas/testsuite/gas/sparc/prefetch.d b/gas/testsuite/gas/sparc/prefetch.d
new file mode 100644
index 00000000000..41803ed97d4
--- /dev/null
+++ b/gas/testsuite/gas/sparc/prefetch.d
@@ -0,0 +1,19 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 prefetch
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: c1 68 40 00 prefetch \[ %g1 \], #n_reads
+ 4: ff 68 40 00 prefetch \[ %g1 \], 31
+ 8: c1 68 40 00 prefetch \[ %g1 \], #n_reads
+ c: c3 68 40 00 prefetch \[ %g1 \], #one_read
+ 10: c5 68 40 00 prefetch \[ %g1 \], #n_writes
+ 14: c7 68 40 00 prefetch \[ %g1 \], #one_write
+ 18: c1 e8 42 00 prefetcha \[ %g1 \] #ASI_AIUP, #n_reads
+ 1c: ff e8 60 00 prefetcha \[ %g1 \] %asi, 31
+ 20: c1 e8 42 20 prefetcha \[ %g1 \] #ASI_AIUS, #n_reads
+ 24: c3 e8 60 00 prefetcha \[ %g1 \] %asi, #one_read
diff --git a/gas/testsuite/gas/sparc/prefetch.s b/gas/testsuite/gas/sparc/prefetch.s
new file mode 100644
index 00000000000..18c68bbbc00
--- /dev/null
+++ b/gas/testsuite/gas/sparc/prefetch.s
@@ -0,0 +1,11 @@
+ .text
+ prefetch [%g1],0
+ prefetch [%g1],31
+ prefetch [%g1],#n_reads
+ prefetch [%g1],#one_read
+ prefetch [%g1],#n_writes
+ prefetch [%g1],#one_write
+ prefetcha [%g1]#ASI_AIUP,0
+ prefetcha [%g1]%asi,31
+ prefetcha [%g1]#ASI_AIUS,#n_reads
+ prefetcha [%g1]%asi,#one_read
diff --git a/gas/testsuite/gas/sparc/rdpr.d b/gas/testsuite/gas/sparc/rdpr.d
new file mode 100644
index 00000000000..60a7b619a67
--- /dev/null
+++ b/gas/testsuite/gas/sparc/rdpr.d
@@ -0,0 +1,26 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 rdpr
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: 83 50 00 00 rdpr %tpc, %g1
+ 4: 85 50 40 00 rdpr %tnpc, %g2
+ 8: 87 50 80 00 rdpr %tstate, %g3
+ c: 89 50 c0 00 rdpr %tt, %g4
+ 10: 8b 51 00 00 rdpr %tick, %g5
+ 14: 8d 51 40 00 rdpr %tba, %g6
+ 18: 8f 51 80 00 rdpr %pstate, %g7
+ 1c: 91 51 c0 00 rdpr %tl, %o0
+ 20: 93 52 00 00 rdpr %pil, %o1
+ 24: 95 52 40 00 rdpr %cwp, %o2
+ 28: 97 52 80 00 rdpr %cansave, %o3
+ 2c: 99 52 c0 00 rdpr %canrestore, %o4
+ 30: 9b 53 00 00 rdpr %cleanwin, %o5
+ 34: 9d 53 40 00 rdpr %otherwin, %sp
+ 38: 9f 53 80 00 rdpr %wstate, %o7
+ 3c: a1 53 c0 00 rdpr %fq, %l0
+ 40: a3 57 c0 00 rdpr %ver, %l1
diff --git a/gas/testsuite/gas/sparc/rdpr.s b/gas/testsuite/gas/sparc/rdpr.s
new file mode 100644
index 00000000000..f44619cea4d
--- /dev/null
+++ b/gas/testsuite/gas/sparc/rdpr.s
@@ -0,0 +1,19 @@
+# Test rdpr
+ .text
+ rdpr %tpc,%g1
+ rdpr %tnpc,%g2
+ rdpr %tstate,%g3
+ rdpr %tt,%g4
+ rdpr %tick,%g5
+ rdpr %tba,%g6
+ rdpr %pstate,%g7
+ rdpr %tl,%o0
+ rdpr %pil,%o1
+ rdpr %cwp,%o2
+ rdpr %cansave,%o3
+ rdpr %canrestore,%o4
+ rdpr %cleanwin,%o5
+ rdpr %otherwin,%o6
+ rdpr %wstate,%o7
+ rdpr %fq,%l0
+ rdpr %ver,%l1
diff --git a/gas/testsuite/gas/sparc/reloc64.d b/gas/testsuite/gas/sparc/reloc64.d
new file mode 100644
index 00000000000..f4b825ad785
--- /dev/null
+++ b/gas/testsuite/gas/sparc/reloc64.d
@@ -0,0 +1,76 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 reloc64
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <foo>:
+ 0: 03 04 8d 15 sethi %hi\(0x12345400\), %g1
+ 4: 82 10 62 78 or %g1, 0x278, %g1.*
+ 8: 01 00 00 00 nop
+ c: 03 00 00 00 sethi %hi\(0x0\), %g1
+ c: R_SPARC_HH22 .text
+ 10: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 10: R_SPARC_HM10 .text
+ 14: 01 00 00 00 nop
+ 18: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 18: R_SPARC_HH22 .text\+0x1234567800000000
+ 1c: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 1c: R_SPARC_HM10 .text\+0x1234567800000000
+ 20: 01 00 00 00 nop
+ 24: 03 3f b7 2e sethi %hi\(0xfedcb800\), %g1
+ 28: 82 10 62 98 or %g1, 0x298, %g1.*
+ 2c: 05 1d 95 0c sethi %hi\(0x76543000\), %g2
+ 30: 84 10 62 10 or %g1, 0x210, %g2
+ 34: 01 00 00 00 nop
+ 38: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 38: R_SPARC_HH22 .text
+ 3c: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 3c: R_SPARC_HM10 .text
+ 40: 05 00 00 00 sethi %hi\(0x0\), %g2
+ 40: R_SPARC_LM22 .text
+ 44: 84 10 60 00 mov %g1, %g2
+ 44: R_SPARC_LO10 .text
+ 48: 01 00 00 00 nop
+ 4c: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 4c: R_SPARC_HH22 .text\+0xfedcba9876543210
+ 50: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 50: R_SPARC_HM10 .text\+0xfedcba9876543210
+ 54: 05 00 00 00 sethi %hi\(0x0\), %g2
+ 54: R_SPARC_LM22 .text\+0xfedcba9876543210
+ 58: 84 10 60 00 mov %g1, %g2
+ 58: R_SPARC_LO10 .text\+0xfedcba9876543210
+ 5c: 01 00 00 00 nop
+ 60: 03 2a 61 d9 sethi %hi\(0xa9876400\), %g1
+ 64: 82 10 61 43 or %g1, 0x143, %g1.*
+ 68: 82 10 62 10 or %g1, 0x210, %g1
+ 6c: 01 00 00 00 nop
+ 70: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 70: R_SPARC_H44 .text
+ 74: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 74: R_SPARC_M44 .text
+ 78: 82 10 60 00 mov %g1, %g1
+ 78: R_SPARC_L44 .text
+ 7c: 01 00 00 00 nop
+ 80: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 80: R_SPARC_H44 .text\+0xa9876543210
+ 84: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 84: R_SPARC_M44 .text\+0xa9876543210
+ 88: 82 10 60 00 mov %g1, %g1
+ 88: R_SPARC_L44 .text\+0xa9876543210
+ 8c: 01 00 00 00 nop
+ 90: 03 22 6a f3 sethi %hi\(0x89abcc00\), %g1
+ 94: 82 18 7e 10 xor %g1, -496, %g1
+ 98: 01 00 00 00 nop
+ 9c: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 9c: R_SPARC_HIX22 .text
+ a0: 82 18 60 00 xor %g1, 0, %g1
+ a0: R_SPARC_LOX10 .text
+ a4: 01 00 00 00 nop
+ a8: 03 00 00 00 sethi %hi\(0x0\), %g1
+ a8: R_SPARC_HIX22 .text\+0xffffffff76543210
+ ac: 82 18 60 00 xor %g1, 0, %g1
+ ac: R_SPARC_LOX10 .text\+0xffffffff76543210
+ b0: 01 00 00 00 nop
diff --git a/gas/testsuite/gas/sparc/reloc64.s b/gas/testsuite/gas/sparc/reloc64.s
new file mode 100644
index 00000000000..9ead6afbf29
--- /dev/null
+++ b/gas/testsuite/gas/sparc/reloc64.s
@@ -0,0 +1,48 @@
+# sparc64 special relocs
+
+foo:
+ sethi %uhi(0x1234567800000000),%g1
+ or %g1,%ulo(0x1234567800000000),%g1
+ nop
+ sethi %uhi(foo),%g1
+ or %g1,%ulo(foo),%g1
+ nop
+ sethi %uhi(foo+0x1234567800000000),%g1
+ or %g1,%ulo(foo+0x1234567800000000),%g1
+ nop
+ sethi %hh(0xfedcba9876543210),%g1
+ or %g1,%hm(0xfedcba9876543210),%g1
+ sethi %lm(0xfedcba9876543210),%g2
+ or %g1,%lo(0xfedcba9876543210),%g2
+ nop
+ sethi %hh(foo),%g1
+ or %g1,%hm(foo),%g1
+ sethi %lm(foo),%g2
+ or %g1,%lo(foo),%g2
+ nop
+ sethi %hh(foo+0xfedcba9876543210),%g1
+ or %g1,%hm(foo+0xfedcba9876543210),%g1
+ sethi %lm(foo+0xfedcba9876543210),%g2
+ or %g1,%lo(foo+0xfedcba9876543210),%g2
+ nop
+ sethi %h44(0xa9876543210),%g1
+ or %g1,%m44(0xa9876543210),%g1
+ or %g1,%l44(0xa9876543210),%g1
+ nop
+ sethi %h44(foo),%g1
+ or %g1,%m44(foo),%g1
+ or %g1,%l44(foo),%g1
+ nop
+ sethi %h44(foo+0xa9876543210),%g1
+ or %g1,%m44(foo+0xa9876543210),%g1
+ or %g1,%l44(foo+0xa9876543210),%g1
+ nop
+ sethi %hix(0xffffffff76543210),%g1
+ xor %g1,%lox(0xffffffff76543210),%g1
+ nop
+ sethi %hix(foo),%g1
+ xor %g1,%lox(foo),%g1
+ nop
+ sethi %hix(foo+0xffffffff76543210),%g1
+ xor %g1,%lox(foo+0xffffffff76543210),%g1
+ nop
diff --git a/gas/testsuite/gas/sparc/set64.d b/gas/testsuite/gas/sparc/set64.d
new file mode 100644
index 00000000000..121becad74d
--- /dev/null
+++ b/gas/testsuite/gas/sparc/set64.d
@@ -0,0 +1,88 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 set64
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <foo>:
+ 0: 05 00 00 00 sethi %hi\(0x0\), %g2
+ 0: R_SPARC_HI22 .text
+ 4: 84 10 a0 00 mov %g2, %g2 ! 0 <foo>
+ 4: R_SPARC_LO10 .text
+ 8: 07 1d 95 0c sethi %hi\(0x76543000\), %g3
+ c: 86 10 e2 10 or %g3, 0x210, %g3 ! 76543210 <\*ABS\*\+(0x|)0x76543210>
+ 10: 88 10 20 00 clr %g4
+ 14: 0b 00 00 3f sethi %hi\(0xfc00\), %g5
+ 18: 8a 11 63 ff or %g5, 0x3ff, %g5 ! ffff <\*ABS\*\+(0x|)ffff>
+ 1c: 03 00 00 00 sethi %hi\(0x0\), %g1
+ 1c: R_SPARC_HH22 .text
+ 20: 82 10 60 00 mov %g1, %g1 ! 0 <foo>
+ 20: R_SPARC_HM10 .text
+ 24: 05 00 00 00 sethi %hi\(0x0\), %g2
+ 24: R_SPARC_HI22 .text
+ 28: 84 10 a0 00 mov %g2, %g2 ! 0 <foo>
+ 28: R_SPARC_LO10 .text
+ 2c: 83 28 70 20 sllx %g1, 0x20, %g1
+ 30: 84 10 80 01 or %g2, %g1, %g2
+ 34: 86 10 3f ff mov -1, %g3
+ 38: 86 10 20 00 clr %g3
+ 3c: 86 10 20 01 mov 1, %g3
+ 40: 86 10 2f ff mov 0xfff, %g3
+ 44: 07 00 00 04 sethi %hi\(0x1000\), %g3
+ 48: 86 10 30 00 mov -4096, %g3
+ 4c: 07 3f ff fb sethi %hi\(0xffffec00\), %g3
+ 50: 86 10 e3 ff or %g3, 0x3ff, %g3 ! ffffefff <\*ABS\*\+(0x|)ffffefff>
+ 54: 87 38 e0 00 sra %g3, 0, %g3
+ 58: 07 00 00 3f sethi %hi\(0xfc00\), %g3
+ 5c: 86 10 e3 ff or %g3, 0x3ff, %g3 ! ffff <\*ABS\*\+(0x|)ffff>
+ 60: 07 3f ff c0 sethi %hi\(0xffff0000\), %g3
+ 64: 87 38 e0 00 sra %g3, 0, %g3
+ 68: 09 1f ff ff sethi %hi\(0x7ffffc00\), %g4
+ 6c: 88 11 23 ff or %g4, 0x3ff, %g4 ! 7fffffff <\*ABS\*\+(0x|)7fffffff>
+ 70: 09 20 00 00 sethi %hi\(0x80000000\), %g4
+ 74: 09 20 00 00 sethi %hi\(0x80000000\), %g4
+ 78: 89 39 20 00 sra %g4, 0, %g4
+ 7c: 82 10 3f ff mov -1, %g1
+ 80: 09 1f ff ff sethi %hi\(0x7ffffc00\), %g4
+ 84: 88 11 23 ff or %g4, 0x3ff, %g4 ! 7fffffff <\*ABS\*\+(0x|)7fffffff>
+ 88: 83 28 70 20 sllx %g1, 0x20, %g1
+ 8c: 88 11 00 01 or %g4, %g1, %g4
+ 90: 09 3f ff ff sethi %hi\(0xfffffc00\), %g4
+ 94: 88 11 23 ff or %g4, 0x3ff, %g4 ! ffffffff <\*ABS\*\+(0x|)ffffffff>
+ 98: 88 10 20 01 mov 1, %g4
+ 9c: 89 29 30 20 sllx %g4, 0x20, %g4
+ a0: 03 1f ff ff sethi %hi\(0x7ffffc00\), %g1
+ a4: 82 10 63 ff or %g1, 0x3ff, %g1 ! 7fffffff <\*ABS\*\+(0x|)7fffffff>
+ a8: 0b 3f ff ff sethi %hi\(0xfffffc00\), %g5
+ ac: 8a 11 63 ff or %g5, 0x3ff, %g5 ! ffffffff <\*ABS\*\+(0x|)ffffffff>
+ b0: 83 28 70 20 sllx %g1, 0x20, %g1
+ b4: 8a 11 40 01 or %g5, %g1, %g5
+ b8: 0b 20 00 00 sethi %hi\(0x80000000\), %g5
+ bc: 8b 29 70 20 sllx %g5, 0x20, %g5
+ c0: 8a 10 3f ff mov -1, %g5
+ c4: 8b 29 70 20 sllx %g5, 0x20, %g5
+ c8: 0b 20 00 00 sethi %hi\(0x80000000\), %g5
+ cc: 8b 39 60 00 sra %g5, 0, %g5
+ d0: 03 3f ff c0 sethi %hi\(0xffff0000\), %g1
+ d4: 0b 3f ff c0 sethi %hi\(0xffff0000\), %g5
+ d8: 83 28 70 20 sllx %g1, 0x20, %g1
+ dc: 8a 11 40 01 or %g5, %g1, %g5
+ e0: 03 3f ff c0 sethi %hi\(0xffff0000\), %g1
+ e4: 8a 10 20 01 mov 1, %g5
+ e8: 83 28 70 20 sllx %g1, 0x20, %g1
+ ec: 8a 11 40 01 or %g5, %g1, %g5
+ f0: 82 10 20 01 mov 1, %g1
+ f4: 0b 3f ff c0 sethi %hi\(0xffff0000\), %g5
+ f8: 8a 11 60 01 or %g5, 1, %g5 ! ffff0001 <\*ABS\*\+(0x|)ffff0001>
+ fc: 83 28 70 20 sllx %g1, 0x20, %g1
+ 100: 8a 11 40 01 or %g5, %g1, %g5
+ 104: 82 10 20 01 mov 1, %g1
+ 108: 0b 3f ff c0 sethi %hi\(0xffff0000\), %g5
+ 10c: 83 28 70 20 sllx %g1, 0x20, %g1
+ 110: 8a 11 40 01 or %g5, %g1, %g5
+ 114: 82 10 20 01 mov 1, %g1
+ 118: 8a 10 20 01 mov 1, %g5
+ 11c: 83 28 70 20 sllx %g1, 0x20, %g1
+ 120: 8a 11 40 01 or %g5, %g1, %g5
diff --git a/gas/testsuite/gas/sparc/set64.s b/gas/testsuite/gas/sparc/set64.s
new file mode 100644
index 00000000000..92dc9317485
--- /dev/null
+++ b/gas/testsuite/gas/sparc/set64.s
@@ -0,0 +1,43 @@
+# sparc64 set insn handling (includes set, setuw, setsw, setx)
+# FIXME: setuw,setsw not tested for yet.
+
+foo:
+ set foo,%g2
+ set 0x76543210,%g3
+ set 0,%g4
+ set 65535,%g5
+
+ setx foo,%g1,%g2
+
+ setx -1,%g1,%g3
+ setx 0,%g1,%g3
+ setx 1,%g1,%g3
+ setx 4095,%g1,%g3
+ setx 4096,%g1,%g3
+ setx -4096,%g1,%g3
+ setx -4097,%g1,%g3
+ setx 65535,%g1,%g3
+ setx -65536,%g1,%g3
+
+ setx 2147483647,%g1,%g4
+ setx 2147483648,%g1,%g4
+ setx -2147483648,%g1,%g4
+ setx -2147483649,%g1,%g4
+ setx 4294967295,%g1,%g4
+ setx 4294967296,%g1,%g4
+
+! GAS doesn't handle large base10 numbers yet.
+! setx 9223372036854775807,%g1,%g5
+! setx 9223372036854775808,%g1,%g5
+! setx -9223372036854775808,%g1,%g5
+! setx -9223372036854775809,%g1,%g5
+
+ setx 0x7fffffffffffffff,%g1,%g5
+ setx 0x8000000000000000,%g1,%g5 ! test only hh22 needed
+ setx 0xffffffff00000000,%g1,%g5 ! test only hm10 needed
+ setx 0xffffffff80000000,%g1,%g5 ! test sign-ext of lower 32
+ setx 0xffff0000ffff0000,%g1,%g5 ! test hh22,hi22
+ setx 0xffff000000000001,%g1,%g5 ! test hh22,lo10
+ setx 0x00000001ffff0001,%g1,%g5 ! test hm10,hi22,lo10
+ setx 0x00000001ffff0000,%g1,%g5 ! test hm10,hi22
+ setx 0x0000000100000001,%g1,%g5 ! test hm10,lo10
diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp
new file mode 100644
index 00000000000..1a793584599
--- /dev/null
+++ b/gas/testsuite/gas/sparc/sparc.exp
@@ -0,0 +1,27 @@
+# Some generic SPARC and SPARC64 tests
+
+# FIXME: The tests here aren't really bullet proof. A mistake in the opcode
+# table can slip through since we use the same table for assembly and
+# disassembly. The way to fix this is to include a hex dump of the insns
+# and test that as well. Later.
+
+if [istarget sparc*-*-*] {
+ run_dump_test "synth"
+}
+
+
+if [istarget sparc64*-*-*] {
+ run_dump_test "asi"
+ run_dump_test "membar"
+ run_dump_test "prefetch"
+ run_dump_test "set64"
+ run_dump_test "synth64"
+ run_dump_test "rdpr"
+ run_dump_test "wrpr"
+ run_dump_test "reloc64"
+}
+
+if [istarget sparclet*-*-*] {
+ run_dump_test "splet"
+ run_dump_test "splet-2"
+}
diff --git a/gas/testsuite/gas/sparc/splet-2.d b/gas/testsuite/gas/sparc/splet-2.d
new file mode 100644
index 00000000000..d0555385c8e
--- /dev/null
+++ b/gas/testsuite/gas/sparc/splet-2.d
@@ -0,0 +1,23 @@
+#as: -Asparclet
+#objdump: -dr
+#name: sparclet coprocessor registers
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <start>:
+ 0: 81 b0 40 c0 cwrcxt %g1, %ccsr
+ 4: 83 b0 40 c0 cwrcxt %g1, %ccfr
+ 8: 85 b0 40 c0 cwrcxt %g1, %cccrcr
+ c: 87 b0 40 c0 cwrcxt %g1, %ccpr
+ 10: 89 b0 40 c0 cwrcxt %g1, %ccsr2
+ 14: 8b b0 40 c0 cwrcxt %g1, %cccrr
+ 18: 8d b0 40 c0 cwrcxt %g1, %ccrstr
+ 1c: 83 b0 01 00 crdcxt %ccsr, %g1
+ 20: 83 b0 41 00 crdcxt %ccfr, %g1
+ 24: 83 b0 81 00 crdcxt %cccrcr, %g1
+ 28: 83 b0 c1 00 crdcxt %ccpr, %g1
+ 2c: 83 b1 01 00 crdcxt %ccsr2, %g1
+ 30: 83 b1 41 00 crdcxt %cccrr, %g1
+ 34: 83 b1 81 00 crdcxt %ccrstr, %g1
diff --git a/gas/testsuite/gas/sparc/splet-2.s b/gas/testsuite/gas/sparc/splet-2.s
new file mode 100644
index 00000000000..5d3449560a5
--- /dev/null
+++ b/gas/testsuite/gas/sparc/splet-2.s
@@ -0,0 +1,21 @@
+! Test sparclet coprocessor registers.
+
+ .text
+ .global start
+start:
+
+ cwrcxt %g1,%ccsr
+ cwrcxt %g1,%ccfr
+ cwrcxt %g1,%cccrcr
+ cwrcxt %g1,%ccpr
+ cwrcxt %g1,%ccsr2
+ cwrcxt %g1,%cccrr
+ cwrcxt %g1,%ccrstr
+
+ crdcxt %ccsr,%g1
+ crdcxt %ccfr,%g1
+ crdcxt %cccrcr,%g1
+ crdcxt %ccpr,%g1
+ crdcxt %ccsr2,%g1
+ crdcxt %cccrr,%g1
+ crdcxt %ccrstr,%g1
diff --git a/gas/testsuite/gas/sparc/splet.d b/gas/testsuite/gas/sparc/splet.d
new file mode 100644
index 00000000000..9ac0a218181
--- /dev/null
+++ b/gas/testsuite/gas/sparc/splet.d
@@ -0,0 +1,195 @@
+#as: -Asparclet
+#objdump: -dr
+#name: sparclet extensions
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <start>:
+ 0: a1 40 00 00 rd %y, %l0
+ 4: a1 40 40 00 rd %asr1, %l0
+ 8: a1 43 c0 00 rd %asr15, %l0
+ c: a1 44 40 00 rd %asr17, %l0
+ 10: a1 44 80 00 rd %asr18, %l0
+ 14: a1 44 c0 00 rd %asr19, %l0
+ 18: a1 45 00 00 rd %asr20, %l0
+ 1c: a1 45 40 00 rd %asr21, %l0
+ 20: a1 45 80 00 rd %asr22, %l0
+ 24: 81 84 20 00 mov %l0, %y
+ 28: 83 84 20 00 mov %l0, %asr1
+ 2c: 9f 84 20 00 mov %l0, %asr15
+ 30: a3 84 20 00 mov %l0, %asr17
+ 34: a5 84 20 00 mov %l0, %asr18
+ 38: a7 84 20 00 mov %l0, %asr19
+ 3c: a9 84 20 00 mov %l0, %asr20
+ 40: ab 84 20 00 mov %l0, %asr21
+ 44: ad 84 20 00 mov %l0, %asr22
+
+0+48 <test_umul>:
+ 48: 86 50 40 02 umul %g1, %g2, %g3
+ 4c: 86 50 40 02 umul %g1, %g2, %g3
+
+0+50 <test_smul>:
+ 50: 86 58 40 02 smul %g1, %g2, %g3
+ 54: 86 58 40 02 smul %g1, %g2, %g3
+
+0+58 <test_stbar>:
+ 58: 81 43 c0 00 stbar
+ 5c: 81 43 c0 00 stbar
+ 60: 00 00 00 01 unimp 0x1
+ 64: 81 dc 40 00 flush %l1
+
+0+68 <test_scan>:
+ 68: a7 64 7f ff scan %l1, -1, %l3
+ 6c: a7 64 60 00 scan %l1, 0, %l3
+ 70: a7 64 40 11 scan %l1, %l1, %l3
+
+0+74 <test_shuffle>:
+ 74: a3 6c 20 01 shuffle %l0, 1, %l1
+ 78: a3 6c 20 02 shuffle %l0, 2, %l1
+ 7c: a3 6c 20 04 shuffle %l0, 4, %l1
+ 80: a3 6c 20 08 shuffle %l0, 8, %l1
+ 84: a3 6c 20 10 shuffle %l0, 0x10, %l1
+ 88: a3 6c 20 18 shuffle %l0, 0x18, %l1
+
+0+8c <test_umac>:
+ 8c: a1 f4 40 12 umac %l1, %l2, %l0
+ 90: a1 f4 60 02 umac %l1, 2, %l0
+ 94: a1 f4 60 02 umac %l1, 2, %l0
+
+0+98 <test_umacd>:
+ 98: a1 74 80 14 umacd %l2, %l4, %l0
+ 9c: a1 74 a0 03 umacd %l2, 3, %l0
+ a0: a1 74 a0 03 umacd %l2, 3, %l0
+
+0+a4 <test_smac>:
+ a4: a1 fc 40 12 smac %l1, %l2, %l0
+ a8: a1 fc 7f d6 smac %l1, -42, %l0
+ ac: a1 fc 7f d6 smac %l1, -42, %l0
+
+0+b0 <test_smacd>:
+ b0: a1 7c 80 14 smacd %l2, %l4, %l0
+ b4: a1 7c a0 7b smacd %l2, 0x7b, %l0
+ b8: a1 7c a0 7b smacd %l2, 0x7b, %l0
+
+0+bc <test_umuld>:
+ bc: 90 4a 80 0c umuld %o2, %o4, %o0
+ c0: 90 4a a2 34 umuld %o2, 0x234, %o0
+ c4: 90 4a a5 67 umuld %o2, 0x567, %o0
+
+0+c8 <test_smuld>:
+ c8: b0 6e 80 1c smuld %i2, %i4, %i0
+ cc: b0 6e b0 00 smuld %i2, -4096, %i0
+ d0: b0 6f 2f ff smuld %i4, 0xfff, %i0
+
+0+d4 <test_coprocessor>:
+ d4: 81 b4 00 11 cpush %l0, %l1
+ d8: 81 b4 20 01 cpush %l0, 1
+ dc: 81 b4 00 51 cpusha %l0, %l1
+ e0: 81 b4 20 41 cpusha %l0, 1
+ e4: a1 b0 00 80 cpull %l0
+ e8: a1 b0 01 00 crdcxt %ccsr, %l0
+ ec: a1 b0 41 00 crdcxt %ccfr, %l0
+ f0: a1 b0 c1 00 crdcxt %ccpr, %l0
+ f4: a1 b0 81 00 crdcxt %cccrcr, %l0
+ f8: 81 b4 00 c0 cwrcxt %l0, %ccsr
+ fc: 83 b4 00 c0 cwrcxt %l0, %ccfr
+ 100: 87 b4 00 c0 cwrcxt %l0, %ccpr
+ 104: 85 b4 00 c0 cwrcxt %l0, %cccrcr
+ 108: 01 c0 00 01 cbn 10c <test_coprocessor\+(0x|)38>
+ 108: WDISP22 stop\+0xfffffef8
+ 10c: 01 00 00 00 nop
+ 110: 21 c0 00 01 cbn,a 114 <test_coprocessor\+(0x|)40>
+ 110: WDISP22 stop\+0xfffffef0
+ 114: 01 00 00 00 nop
+ 118: 03 c0 00 01 cbe 11c <test_coprocessor\+(0x|)48>
+ 118: WDISP22 stop\+0xfffffee8
+ 11c: 01 00 00 00 nop
+ 120: 23 c0 00 01 cbe,a 124 <test_coprocessor\+(0x|)50>
+ 120: WDISP22 stop\+0xfffffee0
+ 124: 01 00 00 00 nop
+ 128: 05 c0 00 01 cbf 12c <test_coprocessor\+(0x|)58>
+ 128: WDISP22 stop\+0xfffffed8
+ 12c: 01 00 00 00 nop
+ 130: 25 c0 00 01 cbf,a 134 <test_coprocessor\+(0x|)60>
+ 130: WDISP22 stop\+0xfffffed0
+ 134: 01 00 00 00 nop
+ 138: 07 c0 00 01 cbef 13c <test_coprocessor\+(0x|)68>
+ 138: WDISP22 stop\+0xfffffec8
+ 13c: 01 00 00 00 nop
+ 140: 27 c0 00 01 cbef,a 144 <test_coprocessor\+(0x|)70>
+ 140: WDISP22 stop\+0xfffffec0
+ 144: 01 00 00 00 nop
+ 148: 09 c0 00 01 cbr 14c <test_coprocessor\+(0x|)78>
+ 148: WDISP22 stop\+0xfffffeb8
+ 14c: 01 00 00 00 nop
+ 150: 29 c0 00 01 cbr,a 154 <test_coprocessor\+(0x|)80>
+ 150: WDISP22 stop\+0xfffffeb0
+ 154: 01 00 00 00 nop
+ 158: 0b c0 00 01 cber 15c <test_coprocessor\+(0x|)88>
+ 158: WDISP22 stop\+0xfffffea8
+ 15c: 01 00 00 00 nop
+ 160: 2b c0 00 01 cber,a 164 <test_coprocessor\+(0x|)90>
+ 160: WDISP22 stop\+0xfffffea0
+ 164: 01 00 00 00 nop
+ 168: 0d c0 00 01 cbfr 16c <test_coprocessor\+(0x|)98>
+ 168: WDISP22 stop\+0xfffffe98
+ 16c: 01 00 00 00 nop
+ 170: 2d c0 00 01 cbfr,a 174 <test_coprocessor\+(0x|)a0>
+ 170: WDISP22 stop\+0xfffffe90
+ 174: 01 00 00 00 nop
+ 178: 0f c0 00 01 cbefr 17c <test_coprocessor\+(0x|)a8>
+ 178: WDISP22 stop\+0xfffffe88
+ 17c: 01 00 00 00 nop
+ 180: 2f c0 00 01 cbefr,a 184 <test_coprocessor\+(0x|)b0>
+ 180: WDISP22 stop\+0xfffffe80
+ 184: 01 00 00 00 nop
+ 188: 11 c0 00 01 cba 18c <test_coprocessor\+(0x|)b8>
+ 188: WDISP22 stop\+0xfffffe78
+ 18c: 01 00 00 00 nop
+ 190: 31 c0 00 01 cba,a 194 <test_coprocessor\+(0x|)c0>
+ 190: WDISP22 stop\+0xfffffe70
+ 194: 01 00 00 00 nop
+ 198: 13 c0 00 01 cbne 19c <test_coprocessor\+(0x|)c8>
+ 198: WDISP22 stop\+0xfffffe68
+ 19c: 01 00 00 00 nop
+ 1a0: 33 c0 00 01 cbne,a 1a4 <test_coprocessor\+(0x|)d0>
+ 1a0: WDISP22 stop\+0xfffffe60
+ 1a4: 01 00 00 00 nop
+ 1a8: 15 c0 00 01 cbnf 1ac <test_coprocessor\+(0x|)d8>
+ 1a8: WDISP22 stop\+0xfffffe58
+ 1ac: 01 00 00 00 nop
+ 1b0: 35 c0 00 01 cbnf,a 1b4 <test_coprocessor\+(0x|)e0>
+ 1b0: WDISP22 stop\+0xfffffe50
+ 1b4: 01 00 00 00 nop
+ 1b8: 17 c0 00 01 cbnef 1bc <test_coprocessor\+(0x|)e8>
+ 1b8: WDISP22 stop\+0xfffffe48
+ 1bc: 01 00 00 00 nop
+ 1c0: 37 c0 00 01 cbnef,a 1c4 <test_coprocessor\+(0x|)f0>
+ 1c0: WDISP22 stop\+0xfffffe40
+ 1c4: 01 00 00 00 nop
+ 1c8: 19 c0 00 01 cbnr 1cc <test_coprocessor\+(0x|)f8>
+ 1c8: WDISP22 stop\+0xfffffe38
+ 1cc: 01 00 00 00 nop
+ 1d0: 39 c0 00 01 cbnr,a 1d4 <test_coprocessor\+(0x|)100>
+ 1d0: WDISP22 stop\+0xfffffe30
+ 1d4: 01 00 00 00 nop
+ 1d8: 1b c0 00 01 cbner 1dc <test_coprocessor\+(0x|)108>
+ 1d8: WDISP22 stop\+0xfffffe28
+ 1dc: 01 00 00 00 nop
+ 1e0: 3b c0 00 01 cbner,a 1e4 <test_coprocessor\+(0x|)110>
+ 1e0: WDISP22 stop\+0xfffffe20
+ 1e4: 01 00 00 00 nop
+ 1e8: 1d c0 00 01 cbnfr 1ec <test_coprocessor\+(0x|)118>
+ 1e8: WDISP22 stop\+0xfffffe18
+ 1ec: 01 00 00 00 nop
+ 1f0: 3d c0 00 01 cbnfr,a 1f4 <test_coprocessor\+(0x|)120>
+ 1f0: WDISP22 stop\+0xfffffe10
+ 1f4: 01 00 00 00 nop
+ 1f8: 1f c0 00 01 cbnefr 1fc <test_coprocessor\+(0x|)128>
+ 1f8: WDISP22 stop\+0xfffffe08
+ 1fc: 01 00 00 00 nop
+ 200: 3f c0 00 01 cbnefr,a 204 <test_coprocessor\+(0x|)130>
+ 200: WDISP22 stop\+0xfffffe00
+ 204: 01 00 00 00 nop
diff --git a/gas/testsuite/gas/sparc/splet.s b/gas/testsuite/gas/sparc/splet.s
new file mode 100644
index 00000000000..0dfd5074bde
--- /dev/null
+++ b/gas/testsuite/gas/sparc/splet.s
@@ -0,0 +1,211 @@
+ .text
+ .global start
+
+! Starting point
+start:
+
+! test all ASRs
+
+ rd %asr0, %l0
+ rd %asr1, %l0
+ rd %asr15, %l0
+ rd %asr17, %l0
+ rd %asr18, %l0
+ rd %asr19, %l0 ! should stop the processor
+ rd %asr20, %l0
+ rd %asr21, %l0
+ rd %asr22, %l0
+
+ wr %l0, 0, %asr0
+ wr %l0, 0, %asr1
+ wr %l0, 0, %asr15
+ wr %l0, 0, %asr17
+ wr %l0, 0, %asr18
+ wr %l0, 0, %asr19
+ wr %l0, 0, %asr20
+ wr %l0, 0, %asr21
+ wr %l0, 0, %asr22
+
+! test UMUL with no overflow inside Y
+test_umul:
+ umul %g1, %g2, %g3
+
+! test UMUL with an overflow inside Y
+
+ umul %g1, %g2, %g3 ! %g3 must be equal to 0
+
+! test SMUL with negative result
+test_smul:
+ smul %g1, %g2, %g3
+
+! test SMUL with positive result
+
+ smul %g1, %g2, %g3
+
+! test STBAR: there are two possible syntaxes
+test_stbar:
+ stbar ! is a valid V8 syntax, at least a synthetic
+ ! instruction
+ rd %asr15, %g0 ! other solution
+
+! test UNIMP
+ unimp 1
+
+! test FLUSH
+ flush %l1 ! is the official V8 syntax
+
+! test SCAN: find first 0
+test_scan:
+ scan %l1, 0xffffffff, %l3
+
+! test scan: find first 1
+
+ scan %l1, 0, %l3
+
+! test scan: find first bit != bit-0
+
+ scan %l1, %l1, %l3
+
+! test SHUFFLE
+test_shuffle:
+ shuffle %l0, 0x1, %l1
+ shuffle %l0, 0x2, %l1
+ shuffle %l0, 0x4, %l1
+ shuffle %l0, 0x8, %l1
+ shuffle %l0, 0x10, %l1
+ shuffle %l0, 0x18, %l1
+
+! test UMAC
+test_umac:
+ umac %l1, %l2, %l0
+ umac %l1, 2, %l0
+ umac 2, %l1, %l0
+
+! test UMACD
+test_umacd:
+ umacd %l2, %l4, %l0
+ umacd %l2, 3, %l0
+ umacd 3, %l2, %l0
+
+! test SMAC
+test_smac:
+ smac %l1, %l2, %l0
+ smac %l1, -42, %l0
+ smac -42, %l1, %l0
+
+! test SMACD
+test_smacd:
+ smacd %l2, %l4, %l0
+ smacd %l2, 123, %l0
+ smacd 123, %l2, %l0
+
+! test UMULD
+test_umuld:
+ umuld %o2, %o4, %o0
+ umuld %o2, 0x234, %o0
+ umuld 0x567, %o2, %o0
+
+! test SMULD
+test_smuld:
+ smuld %i2, %i4, %i0
+ smuld %i2, -4096, %i0
+ smuld 4095, %i4, %i0
+
+! Coprocessor instructions
+test_coprocessor:
+! %ccsr is register # 0
+! %ccfr is register # 1
+! %ccpr is register # 3
+! %cccrcr is register # 2
+
+! test CPUSH: just syntax
+
+ cpush %l0, %l1
+ cpush %l0, 1
+ cpusha %l0, %l1
+ cpusha %l0, 1
+
+! test CPULL: just syntax
+
+ cpull %l0
+
+! test CPRDCXT: just syntax
+
+ crdcxt %ccsr, %l0
+ crdcxt %ccfr, %l0
+ crdcxt %ccpr, %l0
+ crdcxt %cccrcr, %l0
+
+! test CPWRCXT: just syntax
+
+ cwrcxt %l0, %ccsr
+ cwrcxt %l0, %ccfr
+ cwrcxt %l0, %ccpr
+ cwrcxt %l0, %cccrcr
+
+! test CBccc: just syntax
+
+ cbn stop
+ nop
+ cbn,a stop
+ nop
+ cbe stop
+ nop
+ cbe,a stop
+ nop
+ cbf stop
+ nop
+ cbf,a stop
+ nop
+ cbef stop
+ nop
+ cbef,a stop
+ nop
+ cbr stop
+ nop
+ cbr,a stop
+ nop
+ cber stop
+ nop
+ cber,a stop
+ nop
+ cbfr stop
+ nop
+ cbfr,a stop
+ nop
+ cbefr stop
+ nop
+ cbefr,a stop
+ nop
+ cba stop
+ nop
+ cba,a stop
+ nop
+ cbne stop
+ nop
+ cbne,a stop
+ nop
+ cbnf stop
+ nop
+ cbnf,a stop
+ nop
+ cbnef stop
+ nop
+ cbnef,a stop
+ nop
+ cbnr stop
+ nop
+ cbnr,a stop
+ nop
+ cbner stop
+ nop
+ cbner,a stop
+ nop
+ cbnfr stop
+ nop
+ cbnfr,a stop
+ nop
+ cbnefr stop
+ nop
+ cbnefr,a stop
+ nop
diff --git a/gas/testsuite/gas/sparc/synth.d b/gas/testsuite/gas/sparc/synth.d
new file mode 100644
index 00000000000..dd222c5bc36
--- /dev/null
+++ b/gas/testsuite/gas/sparc/synth.d
@@ -0,0 +1,11 @@
+#as: -Av7
+#objdump: -dr --prefix-addresses
+#name: sparc synth
+
+.*: +file format .*
+
+Disassembly of section .text:
+0+0000 <foo> xnor %g1, %g0, %g2
+0+0004 <foo\+(0x|)4> xnor %g1, %g0, %g1
+0+0008 <foo\+(0x|)8> neg %g1, %g2
+0+000c <foo\+(0x|)c> neg %g1
diff --git a/gas/testsuite/gas/sparc/synth.s b/gas/testsuite/gas/sparc/synth.s
new file mode 100644
index 00000000000..9e066289487
--- /dev/null
+++ b/gas/testsuite/gas/sparc/synth.s
@@ -0,0 +1,7 @@
+# common (v8 or v9) synthetic insns
+ .text
+foo:
+ not %g1,%g2
+ not %g1
+ neg %g1,%g2
+ neg %g1
diff --git a/gas/testsuite/gas/sparc/synth64.d b/gas/testsuite/gas/sparc/synth64.d
new file mode 100644
index 00000000000..a29dab7fcf6
--- /dev/null
+++ b/gas/testsuite/gas/sparc/synth64.d
@@ -0,0 +1,19 @@
+#as: -Av9
+#objdump: -dr --prefix-addresses
+#name: sparc64 synth64
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+0+0000 <foo-(0x|)4> iprefetch 0+0004 <foo>
+0+0004 <foo> signx %g1, %g2
+0+0008 <foo\+(0x|)4> clruw %g1, %g2
+0+000c <foo\+(0x|)8> cas \[ %g1 \], %g2, %g3
+0+0010 <foo\+(0x|)c> casl \[ %g1 \], %g2, %g3
+0+0014 <foo\+(0x|)10> casx \[ %g1 \], %g2, %g3
+0+0018 <foo\+(0x|)14> casxl \[ %g1 \], %g2, %g3
+0+001c <foo\+(0x|)18> clrx \[ %g1 \+ %g2 \]
+0+0020 <foo\+(0x|)1c> clrx \[ %g1 \]
+0+0024 <foo\+(0x|)20> clrx \[ %g1 \+ 1 \]
+0+0028 <foo\+(0x|)24> clrx \[ %g1 \+ 0x2a \]
+0+002c <foo\+(0x|)28> clrx \[ 0x42 \]
diff --git a/gas/testsuite/gas/sparc/synth64.s b/gas/testsuite/gas/sparc/synth64.s
new file mode 100644
index 00000000000..659f3c270ba
--- /dev/null
+++ b/gas/testsuite/gas/sparc/synth64.s
@@ -0,0 +1,16 @@
+# sparc64 synthetic insns
+ .text
+ iprefetch foo
+foo:
+ signx %g1,%g2
+ clruw %g1,%g2
+ cas [%g1],%g2,%g3
+ casl [%g1],%g2,%g3
+ casx [%g1],%g2,%g3
+ casxl [%g1],%g2,%g3
+
+ clrx [%g1+%g2]
+ clrx [%g1]
+ clrx [%g1+1]
+ clrx [42+%g1]
+ clrx [0x42]
diff --git a/gas/testsuite/gas/sparc/wrpr.d b/gas/testsuite/gas/sparc/wrpr.d
new file mode 100644
index 00000000000..e75dcb8065e
--- /dev/null
+++ b/gas/testsuite/gas/sparc/wrpr.d
@@ -0,0 +1,24 @@
+#as: -Av9
+#objdump: -dr
+#name: sparc64 wrpr
+
+.*: +file format .*sparc.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: 81 90 40 00 wrpr %g1, %tpc
+ 4: 83 90 80 00 wrpr %g2, %tnpc
+ 8: 85 90 c0 00 wrpr %g3, %tstate
+ c: 87 91 00 00 wrpr %g4, %tt
+ 10: 89 91 40 00 wrpr %g5, %tick
+ 14: 8b 91 80 00 wrpr %g6, %tba
+ 18: 8d 91 c0 00 wrpr %g7, %pstate
+ 1c: 8f 92 00 00 wrpr %o0, %tl
+ 20: 91 92 40 00 wrpr %o1, %pil
+ 24: 93 92 80 00 wrpr %o2, %cwp
+ 28: 95 92 c0 00 wrpr %o3, %cansave
+ 2c: 97 93 00 00 wrpr %o4, %canrestore
+ 30: 99 93 40 00 wrpr %o5, %cleanwin
+ 34: 9b 93 80 00 wrpr %sp, %otherwin
+ 38: 9d 93 c0 00 wrpr %o7, %wstate
diff --git a/gas/testsuite/gas/sparc/wrpr.s b/gas/testsuite/gas/sparc/wrpr.s
new file mode 100644
index 00000000000..67fd4504f4f
--- /dev/null
+++ b/gas/testsuite/gas/sparc/wrpr.s
@@ -0,0 +1,17 @@
+# Test wrpr
+ .text
+ wrpr %g1,%tpc
+ wrpr %g2,%tnpc
+ wrpr %g3,%tstate
+ wrpr %g4,%tt
+ wrpr %g5,%tick
+ wrpr %g6,%tba
+ wrpr %g7,%pstate
+ wrpr %o0,%tl
+ wrpr %o1,%pil
+ wrpr %o2,%cwp
+ wrpr %o3,%cansave
+ wrpr %o4,%canrestore
+ wrpr %o5,%cleanwin
+ wrpr %o6,%otherwin
+ wrpr %o7,%wstate
diff --git a/gas/testsuite/gas/sun4/addend.d b/gas/testsuite/gas/sun4/addend.d
new file mode 100644
index 00000000000..50ff458ab31
--- /dev/null
+++ b/gas/testsuite/gas/sun4/addend.d
@@ -0,0 +1,13 @@
+#objdump: -r
+# name : addends
+.*: +file format a.out-sunos-big
+
+RELOCATION RECORDS FOR \[.text\]:
+OFFSET TYPE +VALUE
+0+08 WDISP22 +foo1\+0xf+fc
+0+0c WDISP22 +foo1\+0xf+f8
+0+10 WDISP22 +foo1\+0xf+f0
+0+14 WDISP22 +foo1\+0xf+ec
+0+1c 32 +foo1
+0+20 32 +foo1\+0x0+4
+#0+20 32 +foo1\+0x0+4
diff --git a/gas/testsuite/gas/sun4/addend.exp b/gas/testsuite/gas/sun4/addend.exp
new file mode 100644
index 00000000000..f27b46ef2ba
--- /dev/null
+++ b/gas/testsuite/gas/sun4/addend.exp
@@ -0,0 +1,7 @@
+#
+# SunOS4 on SPARC tests
+#
+
+if [istarget sparc-*-sunos4*] then {
+ run_dump_test "addend"
+}
diff --git a/gas/testsuite/gas/sun4/addend.s b/gas/testsuite/gas/sun4/addend.s
new file mode 100644
index 00000000000..18eb108a9b3
--- /dev/null
+++ b/gas/testsuite/gas/sun4/addend.s
@@ -0,0 +1,11 @@
+ .global foo
+foo:
+ nop
+ nop
+ ba foo1+0x4
+ ba foo1+0x4
+ ba foo1
+ ba foo1
+ nop
+ .word foo1
+ .word foo1+4
diff --git a/gas/testsuite/gas/template b/gas/testsuite/gas/template
new file mode 100644
index 00000000000..a24d79ed748
--- /dev/null
+++ b/gas/testsuite/gas/template
@@ -0,0 +1,96 @@
+#
+# This is sort of a prototype test case, which parses the listing output
+# from the assembler. Later, more prototypes should be added for cases
+# where objdump gets run over the .o file, and anything else like that...
+#
+# When you write a test case that uses the listing output, just copy this
+# file (trimming down the overly-verbose comments a little), and
+# adjust it to do what you need.
+#
+# Remember that any ".exp" file found in the tree will be processed by
+# dejagnu.
+
+#
+# FIRST SAMPLE TEST CASE
+#
+
+proc do_foo {} {
+# This string is used below when printing out a success or failure message.
+# If more than one test is run by a given .exp file, it'd be nice to include
+# the name of the input file.
+ set testname "foo.s: multi-register tweaking and frobnication"
+
+# I use this as a flag to record whether the test case passed. If this
+# flag is still clear when EOF is reached, this test fails. If there are
+# two or more patterns, and I need to see all of them, I'll create N variables
+# and check if the sum is N.
+ set x 0
+
+# Call gas_start with two arguments: The input file name (which it'll search
+# for in $srcdir/$subdir, that is, the source directory where the .exp file
+# is), and a (possibly empty) string of options to pass to the assembler.
+ gas_start "foo.s" "-al"
+
+# Now I just iterate over all the output lines, looking for what I want
+# to see. Since each pattern explicitly will not span line breaks, there's
+# also a pattern for lines that don't match anything else. (Is it safe to
+# use ".*" for patterns not crossing line breaks? I don't think "$" does the
+# right thing for that, in any case. I should check into whether the extra
+# pattern is even needed.
+
+# Apparently CRLF is received when using ptys for subprocesses; hence the
+# \r\n for matching line number 3.
+
+# Note that if you use "{ ... }" for the expect clause, you can't have
+# comments inside it.
+
+# This test case is kinda bogus in that seeing either a word of all zeros
+# at address zero or a C-style comment on line three that says "Looking for
+# C comments" (with very specific punctuation and whitespace) will cause
+# it to pass this test. Usually
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 00000000\[^\n\]*\n" { set x 1 }
+ -re "^ +3\[ \t\]+/. Looking for C comments. ./\r\n" { set x 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+# This was intended to do any cleanup necessary. It kinda looks like it isn't
+# needed, but just in case, please keep it in for now.
+ gas_finish
+
+# Did we find what we were looking for? If not, flunk it.
+ if $x then { pass $testname } else { fail $testname }
+}
+
+# Now actually run the test. It can be conditionalized if the test is
+# not appropriate for all targets. The proc "istarget" checks a generalized
+# form of the target name, so that (e.g.) "m68332-unknown-aout" would match
+# here. So far, I think only the CPU name is actually ever altered.
+if [istarget m68k-*] then {
+ do_foo
+}
+
+
+
+
+#
+# SECOND SAMPLE TEST CASE
+#
+
+# This is a tiny bit like the C compiler torture tests, in that it'll run
+# the assembler with the power set of the list of options supplied.
+#
+# The first argument is the test file name; the second is arguments that
+# are always to be provided; the third is a space-separated list of options
+# which are optional (ending in ">" if output should be ignored, like "-a>");
+# the fourth is the name of the test. So far, only binary options are handled
+# this way; N-way options (like CPU type for m68k) aren't handled yet.
+#
+# The variable $stdoptlist usually has a reasonable set of optional options
+# for this target.
+
+# No, PIC isn't supported yet. This is only an example.
+gas_test "quux.s" "-K" $stdoptlist "use of quuxes in PIC mode"
diff --git a/gas/testsuite/gas/tic80/add.d b/gas/testsuite/gas/tic80/add.d
new file mode 100644
index 00000000000..3dec70729da
--- /dev/null
+++ b/gas/testsuite/gas/tic80/add.d
@@ -0,0 +1,22 @@
+#objdump: -d
+#name: TIc80 signed and unsigned add instructions
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 0a 00 fb 62.*
+ 4: ff 3f ac 20.*
+ 8: 00 40 2c 21.*
+ c: 00 10 7b 31 00 40 00 00.*
+ 14: 00 10 fb 41 ff bf ff ff.*
+ 1c: 00 10 bb 5a ff ff ff 7f.*
+ 24: 00 10 3b 6b 00 00 00 80.*
+ 2c: 0a 20 fb 62.*
+ 30: ff bf ac 20.*
+ 34: 00 c0 2c 21.*
+ 38: 00 30 7b 31 00 40 00 00.*
+ 40: 00 30 fb 41 ff bf ff ff.*
+ 48: 00 30 bb 5a ff ff ff 7f.*
+ 50: 00 30 3b 6b 00 00 00 80.*
diff --git a/gas/testsuite/gas/tic80/add.lst b/gas/testsuite/gas/tic80/add.lst
new file mode 100644
index 00000000000..e12b3682aab
--- /dev/null
+++ b/gas/testsuite/gas/tic80/add.lst
@@ -0,0 +1,34 @@
+MVP MP Macro Assembler Version 1.13 Mon Feb 10 20:13:33 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+add.s PAGE 1
+
+ 1 ; Test signed and unsigned addition instruction.
+ 2 ; Test boundary conditions to ensure proper handling.
+ 3 ; Note that unsigned addition still uses signed immediates.
+ 4
+ 5 00000000 62FB000A add r10,r11,r12 ; Register form
+ 6 00000004 20AC3FFF add 16383,r2,r4 ; Maximum positive short signed immediate
+ 7 00000008 212C4000 add -16384,r4,r4 ; Minimum negative short signed immediate
+ 8 0000000C 317B1000 add 16384,r5,r6 ; Minimum positive long signed immediate
+ 00000010 00004000
+ 9 00000014 41FB1000 add -16385,r7,r8 ; Maximum negative short signed immediate
+ 00000018 FFFFBFFF
+ 10 0000001C 5ABB1000 add 2147483647,r10,r11 ; Maximum positive long signed immediate
+ 00000020 7FFFFFFF
+ 11 00000024 6B3B1000 add -2147483648,r12,r13 ; Minimum positive long signed immediate
+ 00000028 80000000
+ 12
+ 13 0000002C 62FB200A addu r10,r11,r12 ; Register form
+ 14 00000030 20ACBFFF addu 16383,r2,r4 ; Maximum positive short signed immediate
+ 15 00000034 212CC000 addu -16384,r4,r4 ; Minimum negative short signed immediate
+ 16 00000038 317B3000 addu 16384,r5,r6 ; Minimum positive long signed immediate
+ 0000003C 00004000
+ 17 00000040 41FB3000 addu -16385,r7,r8 ; Maximum negative short signed immediate
+ 00000044 FFFFBFFF
+ 18 00000048 5ABB3000 addu 2147483647,r10,r11 ; Maximum positive long signed immediate
+ 0000004C 7FFFFFFF
+ 19 00000050 6B3B3000 addu -2147483648,r12,r13 ; Minimum positive long signed immediate
+ 00000054 80000000
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/add.s b/gas/testsuite/gas/tic80/add.s
new file mode 100644
index 00000000000..6c229ed1fe4
--- /dev/null
+++ b/gas/testsuite/gas/tic80/add.s
@@ -0,0 +1,19 @@
+; Test signed and unsigned addition instruction.
+; Test boundary conditions to ensure proper handling.
+; Note that unsigned addition still uses signed immediates.
+
+ add r10,r11,r12 ; Register form
+ add 16383,r2,r4 ; Maximum positive short signed immediate
+ add -16384,r4,r4 ; Minimum negative short signed immediate
+ add 16384,r5,r6 ; Minimum positive long signed immediate
+ add -16385,r7,r8 ; Maximum negative long signed immediate
+ add 2147483647,r10,r11 ; Maximum positive long signed immediate
+ add -2147483648,r12,r13 ; Minimum negative long signed immediate
+
+ addu r10,r11,r12 ; Register form
+ addu 16383,r2,r4 ; Maximum positive short signed immediate
+ addu -16384,r4,r4 ; Minimum negative short signed immediate
+ addu 16384,r5,r6 ; Minimum positive long signed immediate
+ addu -16385,r7,r8 ; Maximum negative long signed immediate
+ addu 2147483647,r10,r11 ; Maximum positive long signed immediate
+ addu -2147483648,r12,r13 ; Minimum negative long signed immediate
diff --git a/gas/testsuite/gas/tic80/align.d b/gas/testsuite/gas/tic80/align.d
new file mode 100644
index 00000000000..88f961046e6
--- /dev/null
+++ b/gas/testsuite/gas/tic80/align.d
@@ -0,0 +1,19 @@
+#objdump: -d
+#name: TIc80 .align pseudo op
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: ab 00 00 00.*
+ 4: cd 00 ef 00.*
+ 8: f1 00 00 00.*
+ c: ee 00 00 00.*
+ 10: ac 00 00 00.*
+ 14: 00 00 00 00.*
+ 18: ab 00 00 00.*
+ 1c: 00 00 00 00.*
+ 20: fe 00 00 00.*
+ \.\.\.
+ 30: de ad be ef.*
diff --git a/gas/testsuite/gas/tic80/align.lst b/gas/testsuite/gas/tic80/align.lst
new file mode 100644
index 00000000000..915415ad575
--- /dev/null
+++ b/gas/testsuite/gas/tic80/align.lst
@@ -0,0 +1,47 @@
+MVP MP Macro Assembler Version 1.13 Thu Feb 27 17:02:23 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+align.s PAGE 1
+
+ 1 ;; Test the .align directive.
+ 2
+ 3 00000000 .text
+ 4
+ 5 ;; This should generate 0xAB000000
+ 6 00000000 AB .byte 0xAB
+ 7 00000001 .align ; Should default to 4 byte alignment
+ 8
+ 9 ;; This should generate 0xCD00EF00
+ 10 00000004 CD .byte 0xCD
+ 11 .align 2 ; Should align to the next 2-byte boundary (pad with one null byt
+ 12 00000006 EF .byte 0xEF
+ 13 .align 1
+ 14
+ 15 ;; This should generate 0xF1000000
+ 16 00000007 .align 4 ; Should not affect alignment (already on 4)
+ 17 00000008 F1 .byte 0xF1
+ 18 00000009 .align 4 ; Should align to next 4 byte boundary
+ 19
+ 20 ;; This should generate 0xEE000000 since we are already on 4 byte alignment
+ 21 0000000C EE .byte 0xEE
+ 22 0000000D .align 8
+ 23
+ 24 ;; This should generate 0xAC000000 0x00000000
+ 25 00000010 AC .byte 0xAC
+ 26 00000011 .align 8
+ 27
+ 28 ;; This should generate 0xAB000000 0x00000000 since we are at 8 byte alignment
+ 29 00000018 AB .byte 0xAB
+ 30 00000019 .align 16
+ 31
+ 32 ;; This should generate 0xFE000000 0x00000000 0x00000000 0x00000000
+ 33 00000020 FE .byte 0xFE
+ 34 00000021 .align 16
+ 35
+ 36 ;; This just forces the disassembler to not print ... for trailing nulls
+ 37 00000030 DE .byte 0xDE, 0xAD, 0xBE, 0xEF
+ 00000031 AD
+ 00000032 BE
+ 00000033 EF
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/align.s b/gas/testsuite/gas/tic80/align.s
new file mode 100644
index 00000000000..02c1256f50c
--- /dev/null
+++ b/gas/testsuite/gas/tic80/align.s
@@ -0,0 +1,37 @@
+;; Test the .align directive.
+
+ .text
+
+ ;; This should generate 0xAB000000
+ .byte 0xAB
+ .align ; Should default to 4 byte alignment
+
+ ;; This should generate 0xCD00EF00
+ .byte 0xCD
+ .align 2 ; Should align to the next 2-byte boundary (pad with one null byte)
+ .byte 0xEF
+ .align 1
+
+ ;; This should generate 0xF1000000
+ .align 4 ; Should not affect alignment (already on 4)
+ .byte 0xF1
+ .align 4 ; Should align to next 4 byte boundary
+
+ ;; This should generate 0xEE000000 since we are already on 4 byte alignment
+ .byte 0xEE
+ .align 8
+
+ ;; This should generate 0xAC000000 0x00000000
+ .byte 0xAC
+ .align 8
+
+ ;; This should generate 0xAB000000 0x00000000 since we are at 8 byte alignment
+ .byte 0xAB
+ .align 16
+
+ ;; This should generate 0xFE000000 0x00000000 0x00000000 0x00000000
+ .byte 0xFE
+ .align 16
+
+ ;; This just forces the disassembler to not print ... for trailing nulls
+ .byte 0xDE, 0xAD, 0xBE, 0xEF
diff --git a/gas/testsuite/gas/tic80/bitnum.d b/gas/testsuite/gas/tic80/bitnum.d
new file mode 100644
index 00000000000..fcaee8b086b
--- /dev/null
+++ b/gas/testsuite/gas/tic80/bitnum.d
@@ -0,0 +1,82 @@
+#objdump: -d
+#name: TIc80 coverage of symbolic BITNUM values
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 0a 40 39 fa.*
+ 4: 0a 40 39 f2.*
+ 8: 0a 40 39 ea.*
+ c: 0a 40 39 e2.*
+ 10: 0a 40 39 da.*
+ 14: 0a 40 39 d2.*
+ 18: 0a 40 39 ca.*
+ 1c: 0a 40 39 c2.*
+ 20: 0a 40 39 ba.*
+ 24: 0a 40 39 b2.*
+ 28: 0a 40 39 aa.*
+ 2c: 0a 40 39 a2.*
+ 30: 0a 40 39 9a.*
+ 34: 0a 40 39 92.*
+ 38: 0a 40 39 8a.*
+ 3c: 0a 40 39 82.*
+ 40: 0a 40 39 7a.*
+ 44: 0a 40 39 72.*
+ 48: 0a 40 39 6a.*
+ 4c: 0a 40 39 62.*
+ 50: 0a 40 39 5a.*
+ 54: 0a 40 39 52.*
+ 58: 0a 40 39 4a.*
+ 5c: 0a 40 39 42.*
+ 60: 0a 40 39 3a.*
+ 64: 0a 40 39 32.*
+ 68: 0a 40 39 2a.*
+ 6c: 0a 40 39 22.*
+ 70: 0a 40 39 1a.*
+ 74: 0a 40 39 12.*
+ 78: 0a 40 39 5a.*
+ 7c: 0a 40 39 52.*
+ 80: 0a 40 39 4a.*
+ 84: 0a 40 39 42.*
+ 88: 0a 40 39 3a.*
+ 8c: 0a 40 39 32.*
+ 90: 0a 40 39 2a.*
+ 94: 0a 40 39 22.*
+ 98: 0a 40 39 1a.*
+ 9c: 0a 40 39 12.*
+ a0: 0a 40 39 0a.*
+ a4: 0a 40 39 02.*
+ a8: 0a 40 39 fa.*
+ ac: 0a 40 39 f2.*
+ b0: 0a 40 39 ea.*
+ b4: 0a 40 39 e2.*
+ b8: 0a 40 39 da.*
+ bc: 0a 40 39 d2.*
+ c0: 0a 40 39 ca.*
+ c4: 0a 40 39 c2.*
+ c8: 0a 40 39 ba.*
+ cc: 0a 40 39 b2.*
+ d0: 0a 40 39 aa.*
+ d4: 0a 40 39 a2.*
+ d8: 0a 40 39 9a.*
+ dc: 0a 40 39 92.*
+ e0: 0a 40 39 8a.*
+ e4: 0a 40 39 82.*
+ e8: 0a 40 39 7a.*
+ ec: 0a 40 39 72.*
+ f0: 0a 40 39 6a.*
+ f4: 0a 40 39 62.*
+ f8: 0a 40 39 5a.*
+ fc: 0a 40 39 52.*
+ 100: 0a 40 39 4a.*
+ 104: 0a 40 39 42.*
+ 108: 0a 40 39 3a.*
+ 10c: 0a 40 39 32.*
+ 110: 0a 40 39 2a.*
+ 114: 0a 40 39 22.*
+ 118: 0a 40 39 1a.*
+ 11c: 0a 40 39 12.*
+ 120: 0a 40 39 0a.*
+ 124: 0a 40 39 02.*
diff --git a/gas/testsuite/gas/tic80/bitnum.lst b/gas/testsuite/gas/tic80/bitnum.lst
new file mode 100644
index 00000000000..acc268bb26f
--- /dev/null
+++ b/gas/testsuite/gas/tic80/bitnum.lst
@@ -0,0 +1,97 @@
+MVP MP Macro Assembler Version 1.13 Sat Feb 22 21:37:15 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+bitnum.s PAGE 1
+
+ 1 ;; Test that all the predefined symbol names for the BITNUM field
+ 2 ;; are properly accepted and translated to numeric values. Also
+ 3 ;; verifies that they are disassembled correctly as symbolics, and
+ 4 ;; that the raw numeric values are handled correctly (stored as
+ 5 ;; the one's complement of the operand numeric value.
+ 6
+ 7 00000000 FA39400A bbo r10,r8,eq.b ; (~0 & 0x1F)
+ 8 00000004 F239400A bbo r10,r8,ne.b ; (~1 & 0x1F)
+ 9 00000008 EA39400A bbo r10,r8,gt.b ; (~2 & 0x1F)
+ 10 0000000C E239400A bbo r10,r8,le.b ; (~3 & 0x1F)
+ 11 00000010 DA39400A bbo r10,r8,lt.b ; (~4 & 0x1F)
+ 12 00000014 D239400A bbo r10,r8,ge.b ; (~5 & 0x1F)
+ 13 00000018 CA39400A bbo r10,r8,hi.b ; (~6 & 0x1F)
+ 14 0000001C C239400A bbo r10,r8,ls.b ; (~7 & 0x1F)
+ 15 00000020 BA39400A bbo r10,r8,lo.b ; (~8 & 0x1F)
+ 16 00000024 B239400A bbo r10,r8,hs.b ; (~9 & 0x1F)
+ 17
+ 18 00000028 AA39400A bbo r10,r8,eq.h ; (~10 & 0x1F)
+ 19 0000002C A239400A bbo r10,r8,ne.h ; (~11 & 0x1F)
+ 20 00000030 9A39400A bbo r10,r8,gt.h ; (~12 & 0x1F)
+ 21 00000034 9239400A bbo r10,r8,le.h ; (~13 & 0x1F)
+ 22 00000038 8A39400A bbo r10,r8,lt.h ; (~14 & 0x1F)
+ 23 0000003C 8239400A bbo r10,r8,ge.h ; (~15 & 0x1F)
+ 24 00000040 7A39400A bbo r10,r8,hi.h ; (~16 & 0x1F)
+ 25 00000044 7239400A bbo r10,r8,ls.h ; (~17 & 0x1F)
+ 26 00000048 6A39400A bbo r10,r8,lo.h ; (~18 & 0x1F)
+ 27 0000004C 6239400A bbo r10,r8,hs.h ; (~19 & 0x1F)
+ 28
+ 29 00000050 5A39400A bbo r10,r8,eq.w ; (~20 & 0x1F)
+ 30 00000054 5239400A bbo r10,r8,ne.w ; (~21 & 0x1F)
+ 31 00000058 4A39400A bbo r10,r8,gt.w ; (~22 & 0x1F)
+ 32 0000005C 4239400A bbo r10,r8,le.w ; (~23 & 0x1F)
+ 33 00000060 3A39400A bbo r10,r8,lt.w ; (~24 & 0x1F)
+ 34 00000064 3239400A bbo r10,r8,ge.w ; (~25 & 0x1F)
+ 35 00000068 2A39400A bbo r10,r8,hi.w ; (~26 & 0x1F)
+ 36 0000006C 2239400A bbo r10,r8,ls.w ; (~27 & 0x1F)
+ 37 00000070 1A39400A bbo r10,r8,lo.w ; (~28 & 0x1F)
+ 38 00000074 1239400A bbo r10,r8,hs.w ; (~29 & 0x1F)
+ 39
+ 40 00000078 5A39400A bbo r10,r8,eq.f ; (~20 & 0x1F)
+ 41 0000007C 5239400A bbo r10,r8,ne.f ; (~21 & 0x1F)
+ 42 00000080 4A39400A bbo r10,r8,gt.f ; (~22 & 0x1F)
+ 43 00000084 4239400A bbo r10,r8,le.f ; (~23 & 0x1F)
+ 44 00000088 3A39400A bbo r10,r8,lt.f ; (~24 & 0x1F)
+ 45 0000008C 3239400A bbo r10,r8,ge.f ; (~25 & 0x1F)
+ 46 00000090 2A39400A bbo r10,r8,ou.f ; (~26 & 0x1F)
+ 47 00000094 2239400A bbo r10,r8,in.f ; (~27 & 0x1F)
+ 48 00000098 1A39400A bbo r10,r8,ib.f ; (~28 & 0x1F)
+ 49 0000009C 1239400A bbo r10,r8,ob.f ; (~29 & 0x1F)
+ 50 000000A0 0A39400A bbo r10,r8,uo.f ; (~30 & 0x1F)
+ 51 000000A4 0239400A bbo r10,r8,or.f ; (~31 & 0x1F)
+ 52
+ 53 000000A8 FA39400A bbo r10,r8,0
+ 54 000000AC F239400A bbo r10,r8,1
+ 55 000000B0 EA39400A bbo r10,r8,2
+ MVP MP Macro Assembler Version 1.13 Sat Feb 22 21:37:15 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+bitnum.s PAGE 2
+
+ 56 000000B4 E239400A bbo r10,r8,3
+ 57 000000B8 DA39400A bbo r10,r8,4
+ 58 000000BC D239400A bbo r10,r8,5
+ 59 000000C0 CA39400A bbo r10,r8,6
+ 60 000000C4 C239400A bbo r10,r8,7
+ 61 000000C8 BA39400A bbo r10,r8,8
+ 62 000000CC B239400A bbo r10,r8,9
+ 63 000000D0 AA39400A bbo r10,r8,10
+ 64 000000D4 A239400A bbo r10,r8,11
+ 65 000000D8 9A39400A bbo r10,r8,12
+ 66 000000DC 9239400A bbo r10,r8,13
+ 67 000000E0 8A39400A bbo r10,r8,14
+ 68 000000E4 8239400A bbo r10,r8,15
+ 69 000000E8 7A39400A bbo r10,r8,16
+ 70 000000EC 7239400A bbo r10,r8,17
+ 71 000000F0 6A39400A bbo r10,r8,18
+ 72 000000F4 6239400A bbo r10,r8,19
+ 73 000000F8 5A39400A bbo r10,r8,20
+ 74 000000FC 5239400A bbo r10,r8,21
+ 75 00000100 4A39400A bbo r10,r8,22
+ 76 00000104 4239400A bbo r10,r8,23
+ 77 00000108 3A39400A bbo r10,r8,24
+ 78 0000010C 3239400A bbo r10,r8,25
+ 79 00000110 2A39400A bbo r10,r8,26
+ 80 00000114 2239400A bbo r10,r8,27
+ 81 00000118 1A39400A bbo r10,r8,28
+ 82 0000011C 1239400A bbo r10,r8,29
+ 83 00000120 0A39400A bbo r10,r8,30
+ 84 00000124 0239400A bbo r10,r8,31
+ 85
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/bitnum.s b/gas/testsuite/gas/tic80/bitnum.s
new file mode 100644
index 00000000000..2526e0644ec
--- /dev/null
+++ b/gas/testsuite/gas/tic80/bitnum.s
@@ -0,0 +1,85 @@
+;; Test that all the predefined symbol names for the BITNUM field
+;; are properly accepted and translated to numeric values. Also
+;; verifies that they are disassembled correctly as symbolics, and
+;; that the raw numeric values are handled correctly (stored as
+;; the one's complement of the operand numeric value.
+
+ bbo r10,r8,eq.b ; (~0 & 0x1F)
+ bbo r10,r8,ne.b ; (~1 & 0x1F)
+ bbo r10,r8,gt.b ; (~2 & 0x1F)
+ bbo r10,r8,le.b ; (~3 & 0x1F)
+ bbo r10,r8,lt.b ; (~4 & 0x1F)
+ bbo r10,r8,ge.b ; (~5 & 0x1F)
+ bbo r10,r8,hi.b ; (~6 & 0x1F)
+ bbo r10,r8,ls.b ; (~7 & 0x1F)
+ bbo r10,r8,lo.b ; (~8 & 0x1F)
+ bbo r10,r8,hs.b ; (~9 & 0x1F)
+
+ bbo r10,r8,eq.h ; (~10 & 0x1F)
+ bbo r10,r8,ne.h ; (~11 & 0x1F)
+ bbo r10,r8,gt.h ; (~12 & 0x1F)
+ bbo r10,r8,le.h ; (~13 & 0x1F)
+ bbo r10,r8,lt.h ; (~14 & 0x1F)
+ bbo r10,r8,ge.h ; (~15 & 0x1F)
+ bbo r10,r8,hi.h ; (~16 & 0x1F)
+ bbo r10,r8,ls.h ; (~17 & 0x1F)
+ bbo r10,r8,lo.h ; (~18 & 0x1F)
+ bbo r10,r8,hs.h ; (~19 & 0x1F)
+
+ bbo r10,r8,eq.w ; (~20 & 0x1F)
+ bbo r10,r8,ne.w ; (~21 & 0x1F)
+ bbo r10,r8,gt.w ; (~22 & 0x1F)
+ bbo r10,r8,le.w ; (~23 & 0x1F)
+ bbo r10,r8,lt.w ; (~24 & 0x1F)
+ bbo r10,r8,ge.w ; (~25 & 0x1F)
+ bbo r10,r8,hi.w ; (~26 & 0x1F)
+ bbo r10,r8,ls.w ; (~27 & 0x1F)
+ bbo r10,r8,lo.w ; (~28 & 0x1F)
+ bbo r10,r8,hs.w ; (~29 & 0x1F)
+
+ bbo r10,r8,eq.f ; (~20 & 0x1F)
+ bbo r10,r8,ne.f ; (~21 & 0x1F)
+ bbo r10,r8,gt.f ; (~22 & 0x1F)
+ bbo r10,r8,le.f ; (~23 & 0x1F)
+ bbo r10,r8,lt.f ; (~24 & 0x1F)
+ bbo r10,r8,ge.f ; (~25 & 0x1F)
+ bbo r10,r8,ou.f ; (~26 & 0x1F)
+ bbo r10,r8,in.f ; (~27 & 0x1F)
+ bbo r10,r8,ib.f ; (~28 & 0x1F)
+ bbo r10,r8,ob.f ; (~29 & 0x1F)
+ bbo r10,r8,uo.f ; (~30 & 0x1F)
+ bbo r10,r8,or.f ; (~31 & 0x1F)
+
+ bbo r10,r8,0
+ bbo r10,r8,1
+ bbo r10,r8,2
+ bbo r10,r8,3
+ bbo r10,r8,4
+ bbo r10,r8,5
+ bbo r10,r8,6
+ bbo r10,r8,7
+ bbo r10,r8,8
+ bbo r10,r8,9
+ bbo r10,r8,10
+ bbo r10,r8,11
+ bbo r10,r8,12
+ bbo r10,r8,13
+ bbo r10,r8,14
+ bbo r10,r8,15
+ bbo r10,r8,16
+ bbo r10,r8,17
+ bbo r10,r8,18
+ bbo r10,r8,19
+ bbo r10,r8,20
+ bbo r10,r8,21
+ bbo r10,r8,22
+ bbo r10,r8,23
+ bbo r10,r8,24
+ bbo r10,r8,25
+ bbo r10,r8,26
+ bbo r10,r8,27
+ bbo r10,r8,28
+ bbo r10,r8,29
+ bbo r10,r8,30
+ bbo r10,r8,31
+
diff --git a/gas/testsuite/gas/tic80/ccode.d b/gas/testsuite/gas/tic80/ccode.d
new file mode 100644
index 00000000000..b5a38aa7d05
--- /dev/null
+++ b/gas/testsuite/gas/tic80/ccode.d
@@ -0,0 +1,32 @@
+#objdump: -d
+#name: TIc80 coverage of symbolic condition code values
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 07 a0 79 01.*
+ 4: 07 a0 79 09.*
+ 8: 07 a0 79 11.*
+ c: 07 a0 79 19.*
+ 10: 07 a0 79 21.*
+ 14: 07 a0 79 29.*
+ 18: 07 a0 79 31.*
+ 1c: 07 a0 79 39.*
+ 20: 07 a0 79 41.*
+ 24: 07 a0 79 49.*
+ 28: 07 a0 79 51.*
+ 2c: 07 a0 79 59.*
+ 30: 07 a0 79 61.*
+ 34: 07 a0 79 69.*
+ 38: 07 a0 79 71.*
+ 3c: 07 a0 79 79.*
+ 40: 07 a0 79 81.*
+ 44: 07 a0 79 89.*
+ 48: 07 a0 79 91.*
+ 4c: 07 a0 79 99.*
+ 50: 07 a0 79 a1.*
+ 54: 07 a0 79 a9.*
+ 58: 07 a0 79 b1.*
+ 5c: 07 a0 79 b9.*
diff --git a/gas/testsuite/gas/tic80/ccode.lst b/gas/testsuite/gas/tic80/ccode.lst
new file mode 100644
index 00000000000..460351c6e90
--- /dev/null
+++ b/gas/testsuite/gas/tic80/ccode.lst
@@ -0,0 +1,37 @@
+MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:49 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+ccode.s PAGE 1
+
+ 1 ;; Test that all the predefined symbol names for the condition
+ 2 ;; codes are properly accepted and translated to numeric values.
+ 3 ;; Also verifies that they are disassembled correctly as symbolics.
+ 4
+ 5 00000000 0179A007 bcnd.a r7,r5,nev.b ; 00000
+ 6 00000004 0979A007 bcnd.a r7,r5,gt0.b ; 00001
+ 7 00000008 1179A007 bcnd.a r7,r5,eq0.b ; 00010
+ 8 0000000C 1979A007 bcnd.a r7,r5,ge0.b ; 00011
+ 9 00000010 2179A007 bcnd.a r7,r5,lt0.b ; 00100
+ 10 00000014 2979A007 bcnd.a r7,r5,ne0.b ; 00101
+ 11 00000018 3179A007 bcnd.a r7,r5,le0.b ; 00110
+ 12 0000001C 3979A007 bcnd.a r7,r5,alw.b ; 00111
+ 13
+ 14 00000020 4179A007 bcnd.a r7,r5,nev.h ; 01000
+ 15 00000024 4979A007 bcnd.a r7,r5,gt0.h ; 01001
+ 16 00000028 5179A007 bcnd.a r7,r5,eq0.h ; 01010
+ 17 0000002C 5979A007 bcnd.a r7,r5,ge0.h ; 01011
+ 18 00000030 6179A007 bcnd.a r7,r5,lt0.h ; 01100
+ 19 00000034 6979A007 bcnd.a r7,r5,ne0.h ; 01101
+ 20 00000038 7179A007 bcnd.a r7,r5,le0.h ; 01110
+ 21 0000003C 7979A007 bcnd.a r7,r5,alw.h ; 01111
+ 22
+ 23 00000040 8179A007 bcnd.a r7,r5,nev.w ; 10000
+ 24 00000044 8979A007 bcnd.a r7,r5,gt0.w ; 10001
+ 25 00000048 9179A007 bcnd.a r7,r5,eq0.w ; 10010
+ 26 0000004C 9979A007 bcnd.a r7,r5,ge0.w ; 10011
+ 27 00000050 A179A007 bcnd.a r7,r5,lt0.w ; 10100
+ 28 00000054 A979A007 bcnd.a r7,r5,ne0.w ; 10101
+ 29 00000058 B179A007 bcnd.a r7,r5,le0.w ; 10110
+ 30 0000005C B979A007 bcnd.a r7,r5,alw.w ; 10111
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/ccode.s b/gas/testsuite/gas/tic80/ccode.s
new file mode 100644
index 00000000000..9e4aac11552
--- /dev/null
+++ b/gas/testsuite/gas/tic80/ccode.s
@@ -0,0 +1,30 @@
+;; Test that all the predefined symbol names for the condition
+;; codes are properly accepted and translated to numeric values.
+;; Also verifies that they are disassembled correctly as symbolics.
+
+ bcnd.a r7,r5,nev.b ; 00000
+ bcnd.a r7,r5,gt0.b ; 00001
+ bcnd.a r7,r5,eq0.b ; 00010
+ bcnd.a r7,r5,ge0.b ; 00011
+ bcnd.a r7,r5,lt0.b ; 00100
+ bcnd.a r7,r5,ne0.b ; 00101
+ bcnd.a r7,r5,le0.b ; 00110
+ bcnd.a r7,r5,alw.b ; 00111
+
+ bcnd.a r7,r5,nev.h ; 01000
+ bcnd.a r7,r5,gt0.h ; 01001
+ bcnd.a r7,r5,eq0.h ; 01010
+ bcnd.a r7,r5,ge0.h ; 01011
+ bcnd.a r7,r5,lt0.h ; 01100
+ bcnd.a r7,r5,ne0.h ; 01101
+ bcnd.a r7,r5,le0.h ; 01110
+ bcnd.a r7,r5,alw.h ; 01111
+
+ bcnd.a r7,r5,nev.w ; 10000
+ bcnd.a r7,r5,gt0.w ; 10001
+ bcnd.a r7,r5,eq0.w ; 10010
+ bcnd.a r7,r5,ge0.w ; 10011
+ bcnd.a r7,r5,lt0.w ; 10100
+ bcnd.a r7,r5,ne0.w ; 10101
+ bcnd.a r7,r5,le0.w ; 10110
+ bcnd.a r7,r5,alw.w ; 10111
diff --git a/gas/testsuite/gas/tic80/cregops.d b/gas/testsuite/gas/tic80/cregops.d
new file mode 100644
index 00000000000..44b61e98c13
--- /dev/null
+++ b/gas/testsuite/gas/tic80/cregops.d
@@ -0,0 +1,68 @@
+#objdump: -d
+#name: TIc80 control register operands
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 34 00 02 10.*
+ 4: 39 00 02 10.*
+ 8: 3a 00 02 10.*
+ c: 02 00 02 10.*
+ 10: 00 05 02 10.*
+ 14: 00 04 02 10.*
+ 18: 01 04 02 10.*
+ 1c: 0a 04 02 10.*
+ 20: 0b 04 02 10.*
+ 24: 0c 04 02 10.*
+ 28: 0d 04 02 10.*
+ 2c: 0e 04 02 10.*
+ 30: 0f 04 02 10.*
+ 34: 02 04 02 10.*
+ 38: 03 04 02 10.*
+ 3c: 04 04 02 10.*
+ 40: 05 04 02 10.*
+ 44: 06 04 02 10.*
+ 48: 07 04 02 10.*
+ 4c: 08 04 02 10.*
+ 50: 09 04 02 10.*
+ 54: 33 00 02 10.*
+ 58: 01 00 02 10.*
+ 5c: 00 00 02 10.*
+ 60: 11 00 02 10.*
+ 64: 14 00 02 10.*
+ 68: 13 00 02 10.*
+ 6c: 10 00 02 10.*
+ 70: 12 00 02 10.*
+ 74: 08 00 02 10.*
+ 78: 06 00 02 10.*
+ 7c: 00 03 02 10.*
+ 80: 00 40 02 10.*
+ 84: 01 40 02 10.*
+ 88: 04 00 02 10.*
+ 8c: 00 02 02 10.*
+ 90: 01 02 02 10.*
+ 94: 0a 02 02 10.*
+ 98: 0b 02 02 10.*
+ 9c: 0c 02 02 10.*
+ a0: 0d 02 02 10.*
+ a4: 0e 02 02 10.*
+ a8: 0f 02 02 10.*
+ ac: 02 02 02 10.*
+ b0: 03 02 02 10.*
+ b4: 04 02 02 10.*
+ b8: 05 02 02 10.*
+ bc: 06 02 02 10.*
+ c0: 07 02 02 10.*
+ c4: 08 02 02 10.*
+ c8: 09 02 02 10.*
+ cc: 31 00 02 10.*
+ d0: 30 00 02 10.*
+ d4: 02 40 02 10.*
+ d8: 0d 00 02 10.*
+ dc: 0a 00 02 10.*
+ e0: 20 00 02 10.*
+ e4: 21 00 02 10.*
+ e8: 0e 00 02 10.*
+ ec: 0f 00 02 10.*
diff --git a/gas/testsuite/gas/tic80/cregops.lst b/gas/testsuite/gas/tic80/cregops.lst
new file mode 100644
index 00000000000..65ea57fe643
--- /dev/null
+++ b/gas/testsuite/gas/tic80/cregops.lst
@@ -0,0 +1,76 @@
+MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:56 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+cregops.s PAGE 1
+
+ 1 ;; Test that all predefined symbol names for control registers
+ 2 ;; are properly accepted and translated to numeric values. Also
+ 3 ;; verifies that they are diassembled correctly as symbolics.
+ 4
+ 5 00000000 10020034 rdcr ANASTAT,r2
+ 6 00000004 10020039 rdcr BRK1,r2
+ 7 00000008 1002003A rdcr BRK2,r2
+ 8 0000000C 10020002 rdcr CONFIG,r2
+ 9 00000010 10020500 rdcr DLRU,r2
+ 10 00000014 10020400 rdcr DTAG0,r2
+ 11 00000018 10020401 rdcr DTAG1,r2
+ 12 0000001C 1002040A rdcr DTAG10,r2
+ 13 00000020 1002040B rdcr DTAG11,r2
+ 14 00000024 1002040C rdcr DTAG12,r2
+ 15 00000028 1002040D rdcr DTAG13,r2
+ 16 0000002C 1002040E rdcr DTAG14,r2
+ 17 00000030 1002040F rdcr DTAG15,r2
+ 18 00000034 10020402 rdcr DTAG2,r2
+ 19 00000038 10020403 rdcr DTAG3,r2
+ 20 0000003C 10020404 rdcr DTAG4,r2
+ 21 00000040 10020405 rdcr DTAG5,r2
+ 22 00000044 10020406 rdcr DTAG6,r2
+ 23 00000048 10020407 rdcr DTAG7,r2
+ 24 0000004C 10020408 rdcr DTAG8,r2
+ 25 00000050 10020409 rdcr DTAG9,r2
+ 26 00000054 10020033 rdcr ECOMCNTL,r2
+ 27 00000058 10020001 rdcr EIP,r2
+ 28 0000005C 10020000 rdcr EPC,r2
+ 29 00000060 10020011 rdcr FLTADR,r2
+ 30 00000064 10020014 rdcr FLTDTH,r2
+ 31 00000068 10020013 rdcr FLTDTL,r2
+ 32 0000006C 10020010 rdcr FLTOP,r2
+ 33 00000070 10020012 rdcr FLTTAG,r2
+ 34 00000074 10020008 rdcr FPST,r2
+ 35 00000078 10020006 rdcr IE,r2
+ 36 0000007C 10020300 rdcr ILRU,r2
+ 37 00000080 10024000 rdcr IN0P,r2
+ 38 00000084 10024001 rdcr IN1P,r2
+ 39 00000088 10020004 rdcr INTPEN,r2
+ 40 0000008C 10020200 rdcr ITAG0,r2
+ 41 00000090 10020201 rdcr ITAG1,r2
+ 42 00000094 1002020A rdcr ITAG10,r2
+ 43 00000098 1002020B rdcr ITAG11,r2
+ 44 0000009C 1002020C rdcr ITAG12,r2
+ 45 000000A0 1002020D rdcr ITAG13,r2
+ 46 000000A4 1002020E rdcr ITAG14,r2
+ 47 000000A8 1002020F rdcr ITAG15,r2
+ 48 000000AC 10020202 rdcr ITAG2,r2
+ 49 000000B0 10020203 rdcr ITAG3,r2
+ 50 000000B4 10020204 rdcr ITAG4,r2
+ 51 000000B8 10020205 rdcr ITAG5,r2
+ 52 000000BC 10020206 rdcr ITAG6,r2
+ 53 000000C0 10020207 rdcr ITAG7,r2
+ 54 000000C4 10020208 rdcr ITAG8,r2
+ 55 000000C8 10020209 rdcr ITAG9,r2
+ MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:56 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+cregops.s PAGE 2
+
+ 56 000000CC 10020031 rdcr MIP,r2
+ 57 000000D0 10020030 rdcr MPC,r2
+ 58 000000D4 10024002 rdcr OUTP,r2
+ 59 000000D8 1002000D rdcr PKTREQ,r2
+ 60 000000DC 1002000A rdcr PPERROR,r2
+ 61 000000E0 10020020 rdcr SYSSTK,r2
+ 62 000000E4 10020021 rdcr SYSTMP,r2
+ 63 000000E8 1002000E rdcr TCOUNT,r2
+ 64 000000EC 1002000F rdcr TSCALE,r2
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/cregops.s b/gas/testsuite/gas/tic80/cregops.s
new file mode 100644
index 00000000000..8a0adcf5652
--- /dev/null
+++ b/gas/testsuite/gas/tic80/cregops.s
@@ -0,0 +1,64 @@
+;; Test that all predefined symbol names for control registers
+;; are properly accepted and translated to numeric values. Also
+;; verifies that they are diassembled correctly as symbolics.
+
+ rdcr ANASTAT,r2
+ rdcr BRK1,r2
+ rdcr BRK2,r2
+ rdcr CONFIG,r2
+ rdcr DLRU,r2
+ rdcr DTAG0,r2
+ rdcr DTAG1,r2
+ rdcr DTAG10,r2
+ rdcr DTAG11,r2
+ rdcr DTAG12,r2
+ rdcr DTAG13,r2
+ rdcr DTAG14,r2
+ rdcr DTAG15,r2
+ rdcr DTAG2,r2
+ rdcr DTAG3,r2
+ rdcr DTAG4,r2
+ rdcr DTAG5,r2
+ rdcr DTAG6,r2
+ rdcr DTAG7,r2
+ rdcr DTAG8,r2
+ rdcr DTAG9,r2
+ rdcr ECOMCNTL,r2
+ rdcr EIP,r2
+ rdcr EPC,r2
+ rdcr FLTADR,r2
+ rdcr FLTDTH,r2
+ rdcr FLTDTL,r2
+ rdcr FLTOP,r2
+ rdcr FLTTAG,r2
+ rdcr FPST,r2
+ rdcr IE,r2
+ rdcr ILRU,r2
+ rdcr IN0P,r2
+ rdcr IN1P,r2
+ rdcr INTPEN,r2
+ rdcr ITAG0,r2
+ rdcr ITAG1,r2
+ rdcr ITAG10,r2
+ rdcr ITAG11,r2
+ rdcr ITAG12,r2
+ rdcr ITAG13,r2
+ rdcr ITAG14,r2
+ rdcr ITAG15,r2
+ rdcr ITAG2,r2
+ rdcr ITAG3,r2
+ rdcr ITAG4,r2
+ rdcr ITAG5,r2
+ rdcr ITAG6,r2
+ rdcr ITAG7,r2
+ rdcr ITAG8,r2
+ rdcr ITAG9,r2
+ rdcr MIP,r2
+ rdcr MPC,r2
+ rdcr OUTP,r2
+ rdcr PKTREQ,r2
+ rdcr PPERROR,r2
+ rdcr SYSSTK,r2
+ rdcr SYSTMP,r2
+ rdcr TCOUNT,r2
+ rdcr TSCALE,r2
diff --git a/gas/testsuite/gas/tic80/endmask.d b/gas/testsuite/gas/tic80/endmask.d
new file mode 100644
index 00000000000..5cd08471113
--- /dev/null
+++ b/gas/testsuite/gas/tic80/endmask.d
@@ -0,0 +1,41 @@
+#objdump: -d
+#name: TIc80 coverage of shift instruction ENDMASK field
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 05 00 c7 49.*
+ 4: 25 00 c7 49.*
+ 8: 45 00 c7 49.*
+ c: 65 00 c7 49.*
+ 10: 85 00 c7 49.*
+ 14: a5 00 c7 49.*
+ 18: c5 00 c7 49.*
+ 1c: e5 00 c7 49.*
+ 20: 05 01 c7 49.*
+ 24: 25 01 c7 49.*
+ 28: 45 01 c7 49.*
+ 2c: 65 01 c7 49.*
+ 30: 85 01 c7 49.*
+ 34: a5 01 c7 49.*
+ 38: c5 01 c7 49.*
+ 3c: e5 01 c7 49.*
+ 40: 05 02 c7 49.*
+ 44: 25 02 c7 49.*
+ 48: 45 02 c7 49.*
+ 4c: 65 02 c7 49.*
+ 50: 85 02 c7 49.*
+ 54: a5 02 c7 49.*
+ 58: c5 02 c7 49.*
+ 5c: e5 02 c7 49.*
+ 60: 05 03 c7 49.*
+ 64: 25 03 c7 49.*
+ 68: 45 03 c7 49.*
+ 6c: 65 03 c7 49.*
+ 70: 85 03 c7 49.*
+ 74: a5 03 c7 49.*
+ 78: c5 03 c7 49.*
+ 7c: e5 03 c7 49.*
+ 80: 05 00 c7 49.*
diff --git a/gas/testsuite/gas/tic80/endmask.lst b/gas/testsuite/gas/tic80/endmask.lst
new file mode 100644
index 00000000000..9103b33dd71
--- /dev/null
+++ b/gas/testsuite/gas/tic80/endmask.lst
@@ -0,0 +1,45 @@
+MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:29 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+endmask.s PAGE 1
+
+ 1 ;; Test all possible combinations of the endmask in bits 5-9.
+ 2 ;; The mask that is used is computed as 2**bits-1 where bits
+ 3 ;; are the bits 5-9 from the instruction. Note that 0 and 32
+ 4 ;; are treated identically, and disassembled as 0.
+ 5
+ 6 00000000 49C70005 sl.iz 5,0,r7,r9
+ 7 00000004 49C70025 sl.iz 5,1,r7,r9
+ 8 00000008 49C70045 sl.iz 5,2,r7,r9
+ 9 0000000C 49C70065 sl.iz 5,3,r7,r9
+ 10 00000010 49C70085 sl.iz 5,4,r7,r9
+ 11 00000014 49C700A5 sl.iz 5,5,r7,r9
+ 12 00000018 49C700C5 sl.iz 5,6,r7,r9
+ 13 0000001C 49C700E5 sl.iz 5,7,r7,r9
+ 14 00000020 49C70105 sl.iz 5,8,r7,r9
+ 15 00000024 49C70125 sl.iz 5,9,r7,r9
+ 16 00000028 49C70145 sl.iz 5,10,r7,r9
+ 17 0000002C 49C70165 sl.iz 5,11,r7,r9
+ 18 00000030 49C70185 sl.iz 5,12,r7,r9
+ 19 00000034 49C701A5 sl.iz 5,13,r7,r9
+ 20 00000038 49C701C5 sl.iz 5,14,r7,r9
+ 21 0000003C 49C701E5 sl.iz 5,15,r7,r9
+ 22 00000040 49C70205 sl.iz 5,16,r7,r9
+ 23 00000044 49C70225 sl.iz 5,17,r7,r9
+ 24 00000048 49C70245 sl.iz 5,18,r7,r9
+ 25 0000004C 49C70265 sl.iz 5,19,r7,r9
+ 26 00000050 49C70285 sl.iz 5,20,r7,r9
+ 27 00000054 49C702A5 sl.iz 5,21,r7,r9
+ 28 00000058 49C702C5 sl.iz 5,22,r7,r9
+ 29 0000005C 49C702E5 sl.iz 5,23,r7,r9
+ 30 00000060 49C70305 sl.iz 5,24,r7,r9
+ 31 00000064 49C70325 sl.iz 5,25,r7,r9
+ 32 00000068 49C70345 sl.iz 5,26,r7,r9
+ 33 0000006C 49C70365 sl.iz 5,27,r7,r9
+ 34 00000070 49C70385 sl.iz 5,28,r7,r9
+ 35 00000074 49C703A5 sl.iz 5,29,r7,r9
+ 36 00000078 49C703C5 sl.iz 5,30,r7,r9
+ 37 0000007C 49C703E5 sl.iz 5,31,r7,r9
+ 38 00000080 49C70005 sl.iz 5,32,r7,r9
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/endmask.s b/gas/testsuite/gas/tic80/endmask.s
new file mode 100644
index 00000000000..a36aedebafe
--- /dev/null
+++ b/gas/testsuite/gas/tic80/endmask.s
@@ -0,0 +1,38 @@
+;; Test all possible combinations of the endmask in bits 5-9.
+;; The mask that is used is computed as 2**bits-1 where bits
+;; are the bits 5-9 from the instruction. Note that 0 and 32
+;; are treated identically, and disassembled as 0.
+
+ sl.iz 5,0,r7,r9
+ sl.iz 5,1,r7,r9
+ sl.iz 5,2,r7,r9
+ sl.iz 5,3,r7,r9
+ sl.iz 5,4,r7,r9
+ sl.iz 5,5,r7,r9
+ sl.iz 5,6,r7,r9
+ sl.iz 5,7,r7,r9
+ sl.iz 5,8,r7,r9
+ sl.iz 5,9,r7,r9
+ sl.iz 5,10,r7,r9
+ sl.iz 5,11,r7,r9
+ sl.iz 5,12,r7,r9
+ sl.iz 5,13,r7,r9
+ sl.iz 5,14,r7,r9
+ sl.iz 5,15,r7,r9
+ sl.iz 5,16,r7,r9
+ sl.iz 5,17,r7,r9
+ sl.iz 5,18,r7,r9
+ sl.iz 5,19,r7,r9
+ sl.iz 5,20,r7,r9
+ sl.iz 5,21,r7,r9
+ sl.iz 5,22,r7,r9
+ sl.iz 5,23,r7,r9
+ sl.iz 5,24,r7,r9
+ sl.iz 5,25,r7,r9
+ sl.iz 5,26,r7,r9
+ sl.iz 5,27,r7,r9
+ sl.iz 5,28,r7,r9
+ sl.iz 5,29,r7,r9
+ sl.iz 5,30,r7,r9
+ sl.iz 5,31,r7,r9
+ sl.iz 5,32,r7,r9
diff --git a/gas/testsuite/gas/tic80/float.d b/gas/testsuite/gas/tic80/float.d
new file mode 100644
index 00000000000..87eb85ba7c5
--- /dev/null
+++ b/gas/testsuite/gas/tic80/float.d
@@ -0,0 +1,40 @@
+#objdump: -d
+#name: TIc80 simple floating point operands
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 80 12 be 51 16 68 a9 65.*
+ 8: 00 12 be 51 16 68 a9 e5.*
+ 10: 00 10 be 51 9a 6d 41 19.*
+ 18: 80 b0 3e 52 9a 6d 41 99.*
+ 20: 00 b0 3e 52 00 00 00 00.*
+ 28: 80 72 be 51 00 00 00 40.*
+ 30: 00 72 be 51 00 00 00 3f.*
+ 38: 00 70 be 51 00 00 80 45.*
+ 40: 80 52 be 51 00 00 80 c5.*
+ 48: 00 52 be 51 00 00 00 40.*
+ 50: 00 50 be 51 00 00 00 40.*
+ 58: 80 93 3e 40 00 00 00 40.*
+ 60: 80 95 3e 40 00 00 00 40.*
+ 68: 80 91 3e 40 00 00 00 40.*
+ 70: 80 97 3e 40 00 00 00 40.*
+ 78: 00 92 3e 40 00 00 00 40.*
+ 80: 00 94 3e 40 00 00 00 40.*
+ 88: 00 90 3e 40 00 00 00 40.*
+ 90: 00 96 3e 40 00 00 00 40.*
+ 98: 00 93 3e 40 00 00 00 40.*
+ a0: 00 95 3e 40 00 00 00 40.*
+ a8: 00 91 3e 40 00 00 00 40.*
+ b0: 00 97 3e 40 00 00 00 40.*
+ b8: 80 92 3e 40 00 00 00 40.*
+ c0: 80 94 3e 40 00 00 00 40.*
+ c8: 80 90 3e 40 00 00 00 40.*
+ d0: 80 96 3e 40 00 00 00 40.*
+ d8: 00 f2 3e 50 00 00 00 40.*
+ e0: 00 f0 3e 50 00 00 00 40.*
+ e8: 80 32 be 51 00 00 00 40.*
+ f0: 00 32 be 51 00 00 00 40.*
+ f8: 00 30 be 51 00 00 00 40.*
diff --git a/gas/testsuite/gas/tic80/float.lst b/gas/testsuite/gas/tic80/float.lst
new file mode 100644
index 00000000000..6134590ca6e
--- /dev/null
+++ b/gas/testsuite/gas/tic80/float.lst
@@ -0,0 +1,76 @@
+MVP MP Macro Assembler Version 1.13 Wed Feb 26 22:09:09 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+float.s PAGE 1
+
+ 1 00000000 51BE1280 fadd.sdd 1.0E23,r6,r10 ; Immediate form
+ 00000004 65A96816
+ 2 00000008 51BE1200 fadd.ssd -1.0E23,r6,r10 ; Immediate form
+ 0000000C E5A96816
+ 3 00000010 51BE1000 fadd.sss 1.0E-23,r6,r10 ; Immediate form
+ 00000014 19416D9A
+ 4 00000018 523EB080 fcmp.sd -1.0E-23,r8,r10 ; Immediate form
+ 0000001C 99416D9A
+ 5 00000020 523EB000 fcmp.ss 0.0,r8,r10 ; Immediate form
+ 00000024 00000000
+ 6 00000028 51BE7280 fdiv.sdd 2.0,r6,r10 ; Immediate form
+ 0000002C 40000000
+ 7 00000030 51BE7200 fdiv.ssd 0.5,r6,r10 ; Immediate form
+ 00000034 3F000000
+ 8 00000038 51BE7000 fdiv.sss 4096.0,r6,r10 ; Immediate form
+ 0000003C 45800000
+ 9 00000040 51BE5280 fmpy.sdd -4096.0,r6,r10 ; Immediate form
+ 00000044 C5800000
+ 10 00000048 51BE5200 fmpy.ssd 2.0,r6,r10 ; Immediate form
+ 0000004C 40000000
+ 11 00000050 51BE5000 fmpy.sss 2.0,r6,r10 ; Immediate form
+ 00000054 40000000
+ 12 00000058 403E9380 frndm.sd 2.0,r8 ; Immediate form
+ 0000005C 40000000
+ 13 00000060 403E9580 frndm.si 2.0,r8 ; Immediate form
+ 00000064 40000000
+ 14 00000068 403E9180 frndm.ss 2.0,r8 ; Immediate form
+ 0000006C 40000000
+ 15 00000070 403E9780 frndm.su 2.0,r8 ; Immediate form
+ 00000074 40000000
+ 16 00000078 403E9200 frndn.sd 2.0,r8 ; Immediate form
+ 0000007C 40000000
+ 17 00000080 403E9400 frndn.si 2.0,r8 ; Immediate form
+ 00000084 40000000
+ 18 00000088 403E9000 frndn.ss 2.0,r8 ; Immediate form
+ 0000008C 40000000
+ 19 00000090 403E9600 frndn.su 2.0,r8 ; Immediate form
+ 00000094 40000000
+ 20 00000098 403E9300 frndp.sd 2.0,r8 ; Immediate form
+ 0000009C 40000000
+ 21 000000A0 403E9500 frndp.si 2.0,r8 ; Immediate form
+ 000000A4 40000000
+ 22 000000A8 403E9100 frndp.ss 2.0,r8 ; Immediate form
+ 000000AC 40000000
+ 23 000000B0 403E9700 frndp.su 2.0,r8 ; Immediate form
+ 000000B4 40000000
+ 24 000000B8 403E9280 frndz.sd 2.0,r8 ; Immediate form
+ 000000BC 40000000
+ 25 000000C0 403E9480 frndz.si 2.0,r8 ; Immediate form
+ 000000C4 40000000
+ 26 000000C8 403E9080 frndz.ss 2.0,r8 ; Immediate form
+ 000000CC 40000000
+ 27 000000D0 403E9680 frndz.su 2.0,r8 ; Immediate form
+ 000000D4 40000000
+ 28 000000D8 503EF200 fsqrt.sd 2.0,r10 ; Immediate form
+ MVP MP Macro Assembler Version 1.13 Wed Feb 26 22:09:09 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+float.s PAGE 2
+
+ 000000DC 40000000
+ 29 000000E0 503EF000 fsqrt.ss 2.0,r10 ; Immediate form
+ 000000E4 40000000
+ 30 000000E8 51BE3280 fsub.sdd 2.0,r6,r10 ; Immediate form
+ 000000EC 40000000
+ 31 000000F0 51BE3200 fsub.ssd 2.0,r6,r10 ; Immediate form
+ 000000F4 40000000
+ 32 000000F8 51BE3000 fsub.sss 2.0,r6,r10 ; Immediate form
+ 000000FC 40000000
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/float.s b/gas/testsuite/gas/tic80/float.s
new file mode 100644
index 00000000000..98a2b7ae83d
--- /dev/null
+++ b/gas/testsuite/gas/tic80/float.s
@@ -0,0 +1,32 @@
+ fadd.sdd 0f1.0E23,r6,r10 ; Immediate form
+ fadd.ssd 0f-1.0E23,r6,r10 ; Immediate form
+ fadd.sss 0f1.0E-23,r6,r10 ; Immediate form
+ fcmp.sd 0f-1.0E-23,r8,r10 ; Immediate form
+ fcmp.ss 0f0.0,r8,r10 ; Immediate form
+ fdiv.sdd 0f2.0,r6,r10 ; Immediate form
+ fdiv.ssd 0f0.5,r6,r10 ; Immediate form
+ fdiv.sss 0f4096.0,r6,r10 ; Immediate form
+ fmpy.sdd 0f-4096.0,r6,r10 ; Immediate form
+ fmpy.ssd 0f2.0,r6,r10 ; Immediate form
+ fmpy.sss 0f2.0,r6,r10 ; Immediate form
+ frndm.sd 0f2.0,r8 ; Immediate form
+ frndm.si 0f2.0,r8 ; Immediate form
+ frndm.ss 0f2.0,r8 ; Immediate form
+ frndm.su 0f2.0,r8 ; Immediate form
+ frndn.sd 0f2.0,r8 ; Immediate form
+ frndn.si 0f2.0,r8 ; Immediate form
+ frndn.ss 0f2.0,r8 ; Immediate form
+ frndn.su 0f2.0,r8 ; Immediate form
+ frndp.sd 0f2.0,r8 ; Immediate form
+ frndp.si 0f2.0,r8 ; Immediate form
+ frndp.ss 0f2.0,r8 ; Immediate form
+ frndp.su 0f2.0,r8 ; Immediate form
+ frndz.sd 0f2.0,r8 ; Immediate form
+ frndz.si 0f2.0,r8 ; Immediate form
+ frndz.ss 0f2.0,r8 ; Immediate form
+ frndz.su 0f2.0,r8 ; Immediate form
+ fsqrt.sd 0f2.0,r10 ; Immediate form
+ fsqrt.ss 0f2.0,r10 ; Immediate form
+ fsub.sdd 0f2.0,r6,r10 ; Immediate form
+ fsub.ssd 0f2.0,r6,r10 ; Immediate form
+ fsub.sss 0f2.0,r6,r10 ; Immediate form
diff --git a/gas/testsuite/gas/tic80/regops.d b/gas/testsuite/gas/tic80/regops.d
new file mode 100644
index 00000000000..dd0fa85753c
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops.d
@@ -0,0 +1,188 @@
+#objdump: -d
+#name: TIc80 register operands
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 03 00 3b 29.*
+ 4: 03 20 3b 29.*
+ 8: 05 20 32 11.*
+ c: 05 20 32 11.*
+ 10: 0a 00 33 73.*
+ 14: 0a 80 32 73.*
+ 18: 0a 40 32 73.*
+ 1c: 0a 40 39 1a.*
+ 20: 0a 60 39 fa.*
+ 24: 0a 00 39 22.*
+ 28: 0a 20 39 2a.*
+ 2c: 04 80 b9 21.*
+ 30: 04 a0 b9 21.*
+ 34: 06 00 39 00.*
+ 38: 06 20 39 00.*
+ 3c: 0a 00 03 00.*
+ 40: 06 00 38 f8.*
+ 44: 06 20 38 f8.*
+ 48: 07 40 30 00.*
+ 4c: 03 00 3a 29.*
+ 50: 08 00 b7 02.*
+ 54: 08 00 b7 0a.*
+ 58: 04 04 b4 41.*
+ 5c: 04 24 b4 41.*
+ 60: 04 44 b4 41.*
+ 64: 04 64 b4 41.*
+ 68: 04 04 b5 41.*
+ 6c: 04 24 b5 41.*
+ 70: 04 04 b6 41.*
+ 74: 04 24 b6 41.*
+ 78: 04 44 b6 41.*
+ 7c: 04 64 b6 41.*
+ 80: 05 20 30 08.*
+ 84: e3 47 71 31.*
+ 88: c2 07 71 49.*
+ 8c: 02 00 3e 31.*
+ 90: 02 02 3e 31.*
+ 94: 82 02 3e 31.*
+ 98: 22 02 3e 31.*
+ 9c: a2 02 3e 31.*
+ a0: 04 a0 be 41.*
+ a4: 84 a0 be 41.*
+ a8: 24 a0 be 41.*
+ ac: a4 a0 be 41.*
+ b0: 02 60 3e 31.*
+ b4: 02 62 3e 31.*
+ b8: 82 62 3e 31.*
+ bc: 22 62 3e 31.*
+ c0: a2 62 3e 31.*
+ c4: 02 40 3e 31.*
+ c8: 02 42 3e 31.*
+ cc: 82 42 3e 31.*
+ d0: 22 42 3e 31.*
+ d4: a2 42 3e 31.*
+ d8: 42 45 3e 31.*
+ dc: e2 47 3e 31.*
+ e0: 84 81 3e 30.*
+ e4: 84 83 3e 30.*
+ e8: 84 85 3e 30.*
+ ec: 84 87 3e 30.*
+ f0: a2 81 3e 40.*
+ f4: a2 83 3e 40.*
+ f8: a2 85 3e 40.*
+ fc: a2 87 3e 40.*
+ 100: c4 81 3e 30.*
+ 104: c4 83 3e 30.*
+ 108: e2 81 3e 40.*
+ 10c: e2 83 3e 40.*
+ 110: 04 80 3e 30.*
+ 114: 04 82 3e 30.*
+ 118: 04 84 3e 30.*
+ 11c: 04 86 3e 30.*
+ 120: 22 80 3e 40.*
+ 124: 22 82 3e 40.*
+ 128: 22 84 3e 40.*
+ 12c: 22 86 3e 40.*
+ 130: 44 80 3e 30.*
+ 134: 44 82 3e 30.*
+ 138: 62 80 3e 40.*
+ 13c: 62 82 3e 40.*
+ 140: 04 81 3e 30.*
+ 144: 04 83 3e 30.*
+ 148: 04 85 3e 30.*
+ 14c: 04 87 3e 30.*
+ 150: 22 81 3e 40.*
+ 154: 22 83 3e 40.*
+ 158: 22 85 3e 40.*
+ 15c: 22 87 3e 40.*
+ 160: 44 81 3e 30.*
+ 164: 44 83 3e 30.*
+ 168: 62 81 3e 40.*
+ 16c: 62 83 3e 40.*
+ 170: 84 80 3e 30.*
+ 174: 84 82 3e 30.*
+ 178: 84 84 3e 30.*
+ 17c: 84 86 3e 30.*
+ 180: a2 80 3e 40.*
+ 184: a2 82 3e 40.*
+ 188: a2 84 3e 40.*
+ 18c: a2 86 3e 40.*
+ 190: c4 80 3e 30.*
+ 194: c4 82 3e 30.*
+ 198: e2 80 3e 40.*
+ 19c: e2 82 3e 40.*
+ 1a0: 06 e0 3e 40.*
+ 1a4: 06 e2 3e 40.*
+ 1a8: 26 e2 3e 40.*
+ 1ac: 02 20 3e 31.*
+ 1b0: 02 22 3e 31.*
+ 1b4: 82 22 3e 31.*
+ 1b8: 22 22 3e 31.*
+ 1bc: a2 22 3e 31.*
+ 1c0: e4 e3 31 52.*
+ 1c4: 04 80 b8 41.*
+ 1c8: 04 a0 b8 41.*
+ 1cc: 04 00 b4 41.*
+ 1d0: 04 20 b4 41.*
+ 1d4: 04 40 b4 41.*
+ 1d8: 04 60 b4 41.*
+ 1dc: 04 00 b5 41.*
+ 1e0: 04 20 b5 41.*
+ 1e4: 00 00 ff 41.*
+ 1e8: 01 e0 b2 18.*
+ 1ec: 01 e0 b2 18.*
+ 1f0: 01 c0 b3 18.*
+ 1f4: 01 a0 b3 18.*
+ 1f8: 01 60 b3 18.*
+ 1fc: 06 80 30 20.*
+ 200: 00 20 3f 29.*
+ 204: e2 03 31 52.*
+ 208: e8 07 b1 30.*
+ 20c: e4 c3 b1 30.*
+ 210: 84 01 71 31.*
+ 214: 84 21 71 31.*
+ 218: 84 41 71 31.*
+ 21c: 84 61 71 31.*
+ 220: 84 81 71 31.*
+ 224: 84 a1 71 31.*
+ 228: 84 c1 71 31.*
+ 22c: 84 e1 71 31.*
+ 230: 84 09 71 31.*
+ 234: 84 29 71 31.*
+ 238: 84 49 71 31.*
+ 23c: 84 69 71 31.*
+ 240: 84 89 71 31.*
+ 244: 84 a9 71 31.*
+ 248: 84 c9 71 31.*
+ 24c: 84 e9 71 31.*
+ 250: 84 05 71 31.*
+ 254: 84 25 71 31.*
+ 258: 84 45 71 31.*
+ 25c: 84 65 71 31.*
+ 260: 84 85 71 31.*
+ 264: 84 a5 71 31.*
+ 268: 84 c5 71 31.*
+ 26c: 84 e5 71 31.*
+ 270: 04 a4 b1 41.*
+ 274: 84 0d 71 31.*
+ 278: 84 2d 71 31.*
+ 27c: 84 4d 71 31.*
+ 280: 84 6d 71 31.*
+ 284: 84 8d 71 31.*
+ 288: 84 ad 71 31.*
+ 28c: 84 cd 71 31.*
+ 290: 84 ed 71 31.*
+ 294: 04 64 b1 41.*
+ 298: 04 00 b6 41.*
+ 29c: 04 20 b6 41.*
+ 2a0: 04 40 b6 41.*
+ 2a4: 04 60 b6 41.*
+ 2a8: 07 40 3b 4a.*
+ 2ac: 07 60 3b 4a.*
+ 2b0: 08 a0 b0 21.*
+ 2b4: 0a 20 30 00.*
+ 2b8: 02 00 3c 01.*
+ 2bc: 82 00 bc 01.*
+ 2c0: a2 00 bc 02.*
+ 2c4: 06 a0 70 01.*
+ 2c8: 05 20 b3 39.*
+ 2cc: 07 c0 32 4a.*
diff --git a/gas/testsuite/gas/tic80/regops.lst b/gas/testsuite/gas/tic80/regops.lst
new file mode 100644
index 00000000000..f889dd1a08f
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops.lst
@@ -0,0 +1,264 @@
+MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:24 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops.s PAGE 1
+
+ 1 ;; Simple register forms
+ 2 ;; Those instructions which also use an immediate just use a constant.
+ 3
+ 4 00000000 .text
+ 5
+ 6 00000000 293B0003 add r3,r4,r5
+ 7 00000004 293B2003 addu r3,r4,r5
+ 8 00000008 11322005 and r5,r4,r2
+ 9 0000000C 11322005 and.tt r5,r4,r2
+ 10 00000010 7333000A and.ff r10,r12,r14
+ 11 00000014 7332800A and.ft r10,r12,r14
+ 12 00000018 7332400A and.tf r10,r12,r14
+ 13 0000001C 1A39400A bbo r10,r8,lo.w
+ 14 00000020 FA39600A bbo.a r10,r8,eq.b
+ 15 00000024 2239000A bbz r10,r8,ls.w
+ 16 00000028 2A39200A bbz.a r10,r8,hi.w
+ 17 0000002C 21B98004 bcnd r4,r6,lt0.b
+ 18 00000030 21B9A004 bcnd.a r4,r6,lt0.b
+ 19 00000034 00390006 br r6
+ 20 00000038 00392006 br.a r6
+ 21 0000003C 0003000A brcr 10
+ 22 00000040 F8380006 bsr r6,r31
+ 23 00000044 F8382006 bsr.a r6,r31
+ 24 00000048 00304007 cmnd r7
+ 25 0000004C 293A0003 cmp r3,r4,r5
+ 26 00000050 02B70008 dcachec r8(r10)
+ 27 00000054 0AB70008 dcachef r8(r10)
+ 28 00000058 41B40404 dld.b r4(r6),r8
+ 29 0000005C 41B42404 dld.h r4(r6),r8
+ 30 00000060 41B44404 dld r4(r6),r8
+ 31 00000064 41B46404 dld.d r4(r6),r8
+ 32 00000068 41B50404 dld.ub r4(r6),r8
+ 33 0000006C 41B52404 dld.uh r4(r6),r8
+ 34 00000070 41B60404 dst.b r4(r6),r8
+ 35 00000074 41B62404 dst.h r4(r6),r8
+ 36 00000078 41B64404 dst r4(r6),r8
+ 37 0000007C 41B66404 dst.d r4(r6),r8
+ 38 00000080 08302005 etrap r5
+ 39 00000084 317147E3 exts r3,31,r5,r6
+ 40 00000088 497107C2 extu r2,30,r5,r9
+ 41 0000008C 313E0002 fadd.sss r2,r4,r6
+ 42 00000090 313E0202 fadd.ssd r2,r4,r6
+ 43 00000094 313E0282 fadd.sdd r2,r4,r6
+ 44 00000098 313E0222 fadd.dsd r2,r4,r6
+ 45 0000009C 313E02A2 fadd.ddd r2,r4,r6
+ 46 000000A0 41BEA004 fcmp.ss r4,r6,r8
+ 47 000000A4 41BEA084 fcmp.sd r4,r6,r8
+ 48 000000A8 41BEA024 fcmp.ds r4,r6,r8
+ 49 000000AC 41BEA0A4 fcmp.dd r4,r6,r8
+ 50 000000B0 313E6002 fdiv.sss r2,r4,r6
+ 51 000000B4 313E6202 fdiv.ssd r2,r4,r6
+ 52 000000B8 313E6282 fdiv.sdd r2,r4,r6
+ 53 000000BC 313E6222 fdiv.dsd r2,r4,r6
+ 54 000000C0 313E62A2 fdiv.ddd r2,r4,r6
+ 55 000000C4 313E4002 fmpy.sss r2,r4,r6
+ MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:24 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops.s PAGE 2
+
+ 56 000000C8 313E4202 fmpy.ssd r2,r4,r6
+ 57 000000CC 313E4282 fmpy.sdd r2,r4,r6
+ 58 000000D0 313E4222 fmpy.dsd r2,r4,r6
+ 59 000000D4 313E42A2 fmpy.ddd r2,r4,r6
+ 60 000000D8 313E4542 fmpy.iii r2,r4,r6
+ 61 000000DC 313E47E2 fmpy.uuu r2,r4,r6
+ 62 000000E0 303E8184 frndm.ss r4,r6
+ 63 000000E4 303E8384 frndm.sd r4,r6
+ 64 000000E8 303E8584 frndm.si r4,r6
+ 65 000000EC 303E8784 frndm.su r4,r6
+ 66 000000F0 403E81A2 frndm.ds r2,r8
+ 67 000000F4 403E83A2 frndm.dd r2,r8
+ 68 000000F8 403E85A2 frndm.di r2,r8
+ 69 000000FC 403E87A2 frndm.du r2,r8
+ 70 00000100 303E81C4 frndm.is r4,r6
+ 71 00000104 303E83C4 frndm.id r4,r6
+ 72 00000108 403E81E2 frndm.us r2,r8
+ 73 0000010C 403E83E2 frndm.ud r2,r8
+ 74 00000110 303E8004 frndn.ss r4,r6
+ 75 00000114 303E8204 frndn.sd r4,r6
+ 76 00000118 303E8404 frndn.si r4,r6
+ 77 0000011C 303E8604 frndn.su r4,r6
+ 78 00000120 403E8022 frndn.ds r2,r8
+ 79 00000124 403E8222 frndn.dd r2,r8
+ 80 00000128 403E8422 frndn.di r2,r8
+ 81 0000012C 403E8622 frndn.du r2,r8
+ 82 00000130 303E8044 frndn.is r4,r6
+ 83 00000134 303E8244 frndn.id r4,r6
+ 84 00000138 403E8062 frndn.us r2,r8
+ 85 0000013C 403E8262 frndn.ud r2,r8
+ 86 00000140 303E8104 frndp.ss r4,r6
+ 87 00000144 303E8304 frndp.sd r4,r6
+ 88 00000148 303E8504 frndp.si r4,r6
+ 89 0000014C 303E8704 frndp.su r4,r6
+ 90 00000150 403E8122 frndp.ds r2,r8
+ 91 00000154 403E8322 frndp.dd r2,r8
+ 92 00000158 403E8522 frndp.di r2,r8
+ 93 0000015C 403E8722 frndp.du r2,r8
+ 94 00000160 303E8144 frndp.is r4,r6
+ 95 00000164 303E8344 frndp.id r4,r6
+ 96 00000168 403E8162 frndp.us r2,r8
+ 97 0000016C 403E8362 frndp.ud r2,r8
+ 98 00000170 303E8084 frndz.ss r4,r6
+ 99 00000174 303E8284 frndz.sd r4,r6
+ 100 00000178 303E8484 frndz.si r4,r6
+ 101 0000017C 303E8684 frndz.su r4,r6
+ 102 00000180 403E80A2 frndz.ds r2,r8
+ 103 00000184 403E82A2 frndz.dd r2,r8
+ 104 00000188 403E84A2 frndz.di r2,r8
+ 105 0000018C 403E86A2 frndz.du r2,r8
+ 106 00000190 303E80C4 frndz.is r4,r6
+ 107 00000194 303E82C4 frndz.id r4,r6
+ 108 00000198 403E80E2 frndz.us r2,r8
+ 109 0000019C 403E82E2 frndz.ud r2,r8
+ 110 000001A0 403EE006 fsqrt.ss r6,r8
+ MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:24 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops.s PAGE 3
+
+ 111 000001A4 403EE206 fsqrt.sd r6,r8
+ 112 000001A8 403EE226 fsqrt.dd r6,r8
+ 113 000001AC 313E2002 fsub.sss r2,r4,r6
+ 114 000001B0 313E2202 fsub.ssd r2,r4,r6
+ 115 000001B4 313E2282 fsub.sdd r2,r4,r6
+ 116 000001B8 313E2222 fsub.dsd r2,r4,r6
+ 117 000001BC 313E22A2 fsub.ddd r2,r4,r6
+ 118 000001C0 5231E3E4 ins r4,31,r8,r10
+ 119 000001C4 41B88004 jsr r4(r6),r8
+ 120 000001C8 41B8A004 jsr.a r4(r6),r8
+ 121 000001CC 41B40004 ld.b r4(r6),r8
+ 122 000001D0 41B42004 ld.h r4(r6),r8
+ 123 000001D4 41B44004 ld r4(r6),r8
+ 124 000001D8 41B46004 ld.d r4(r6),r8
+ 125 000001DC 41B50004 ld.ub r4(r6),r8
+ 126 000001E0 41B52004 ld.uh r4(r6),r8
+ 127 000001E4 41FF0007 lmo r7,r8
+ 128 000001E8 18B2E001 or r1,r2,r3
+ 129 000001EC 18B2E001 or.tt r1,r2,r3
+ 130 000001F0 18B3C001 or.ff r1,r2,r3
+ 131 000001F4 18B3A001 or.ft r1,r2,r3
+ 132 000001F8 18B36001 or.tf r1,r2,r3
+ 133 000001FC 20308006 rdcr r6,r4
+ 134 00000200 293F2004 rmo r4,r5
+ 135 00000204 523103E2 rotl r2,31,r8,r10
+ 136 00000208 30B107E8 rotr r8,31,r2,r6
+ 137 0000020C 30B1C3E4 shl r4,31,r2,r6
+ 138 00000210 31710184 sl.dz r4,12,r5,r6
+ 139 00000214 31712184 sl.dm r4,12,r5,r6
+ 140 00000218 31714184 sl.ds r4,12,r5,r6
+ 141 0000021C 31716184 sl.ez r4,12,r5,r6
+ 142 00000220 31718184 sl.em r4,12,r5,r6
+ 143 00000224 3171A184 sl.es r4,12,r5,r6
+ 144 00000228 3171C184 sl.iz r4,12,r5,r6
+ 145 0000022C 3171E184 sl.im r4,12,r5,r6
+ 146 00000230 31710984 sli.dz r4,12,r5,r6
+ 147 00000234 31712984 sli.dm r4,12,r5,r6
+ 148 00000238 31714984 sli.ds r4,12,r5,r6
+ 149 0000023C 31716984 sli.ez r4,12,r5,r6
+ 150 00000240 31718984 sli.em r4,12,r5,r6
+ 151 00000244 3171A984 sli.es r4,12,r5,r6
+ 152 00000248 3171C984 sli.iz r4,12,r5,r6
+ 153 0000024C 3171E984 sli.im r4,12,r5,r6
+ 154 00000250 31710584 sr.dz r4,12,r5,r6
+ 155 00000254 31712584 sr.dm r4,12,r5,r6
+ 156 00000258 31714584 sr.ds r4,12,r5,r6
+ 157 0000025C 31716584 sr.ez r4,12,r5,r6
+ 158 00000260 31718584 sr.em r4,12,r5,r6
+ 159 00000264 3171A584 sr.es r4,12,r5,r6
+ 160 00000268 3171C584 sr.iz r4,12,r5,r6
+ 161 0000026C 3171E584 sr.im r4,12,r5,r6
+ 162 00000270 41B1A404 sra r4,32,r6,r8
+ 163 00000274 31710D84 sri.dz r4,12,r5,r6
+ 164 00000278 31712D84 sri.dm r4,12,r5,r6
+ 165 0000027C 31714D84 sri.ds r4,12,r5,r6
+ MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:24 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops.s PAGE 4
+
+ 166 00000280 31716D84 sri.ez r4,12,r5,r6
+ 167 00000284 31718D84 sri.em r4,12,r5,r6
+ 168 00000288 3171AD84 sri.es r4,12,r5,r6
+ 169 0000028C 3171CD84 sri.iz r4,12,r5,r6
+ 170 00000290 3171ED84 sri.im r4,12,r5,r6
+ 171 00000294 41B16404 srl r4,32,r6,r8
+ 172 00000298 41B60004 st.b r4(r6),r8
+ 173 0000029C 41B62004 st.h r4(r6),r8
+ 174 000002A0 41B64004 st r4(r6),r8
+ 175 000002A4 41B66004 st.d r4(r6),r8
+ 176 000002A8 4A3B4007 sub r7,r8,r9
+ 177 000002AC 4A3B6007 subu r7,r8,r9
+ 178 000002B0 21B0A008 swcr r8,r6,r4
+ 179 000002B4 0030200A trap r10
+ 180 000002B8 013C0002 vadd.ss r2,r4,r4
+ 181 000002BC 01BC0082 vadd.sd r2,r6,r6
+ 182 000002C0 02BC00A2 vadd.dd r2,r10,r10
+ 183 ; vld0.s r6
+ 184 ; vld1.s r7
+ 185 ; vld0.d r6
+ 186 ; vld1.d r8
+ 187 ; vmac.sss r7,r9,0,a3
+ 188 ; vmac.sss r7,r9,0,r10
+ 189 ; vmac.sss r7,r9,a1,a3
+ 190 ; vmac.sss r7,r9,a3,r10
+ 191 ; vmac.ssd r7,r9,0,a0
+ 192 ; vmac.ssd r7,r9,0,r10
+ 193 ; vmac.ssd r7,r9,a1,a2
+ 194 ; vmac.ssd r7,r9,a3,r10
+ 195 ; vmpy.ss r1,r3,r3
+ 196 ; vmpy.sd r5,r6,r6
+ 197 ; vmpy.dd r2,r4,r4
+ 198 ; vmsc.sss r7,r9,0,a0
+ 199 ; vmsc.sss r7,r9,0,r10
+ 200 ; vmsc.sss r7,r9,a0,a1
+ 201 ; vmsc.sss r7,r9,a3,r10
+ 202 ; vmsc.ssd r7,r9,0,a0
+ 203 ; vmsc.ssd r7,r9,0,r10
+ 204 ; vmsc.ssd r7,r9,a0,a1
+ 205 ; vmsc.ssd r7,r9,a3,r10
+ 206 ; vmsub.ss r6,a2,a4
+ 207 ; vmsub.sd r6,a2,a4
+ 208 ; vmsub.ss r4,a4,r6
+ 209 ; vmsub.sd r4,a4,r6
+ 210 ; vrnd.si r4,r6
+ 211 ; vrnd.si r4,a0
+ 212 ; vrnd.su r4,r6
+ 213 ; vrnd.su r4,a0
+ 214 ; vrnd.ss r4,r6
+ 215 ; vrnd.ss r4,a0
+ 216 ; vrnd.sd r4,r6
+ 217 ; vrnd.sd r4,a0
+ 218 ; vrnd.di r4,r6
+ 219 ; vrnd.di r4,a0
+ 220 ; vrnd.du r4,r6
+ MVP MP Macro Assembler Version 1.13 Mon Feb 10 17:00:24 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops.s PAGE 5
+
+ 221 ; vrnd.du r4,a0
+ 222 ; vrnd.ds r4,r6
+ 223 ; vrnd.ds r4,a0
+ 224 ; vrnd.dd r4,r6
+ 225 ; vrnd.dd r4,a0
+ 226 ; vrnd.is r4,r6
+ 227 ; vrnd.id r4,r6
+ 228 ; vrnd.us r4,r6
+ 229 ; vrnd.ud r4,r6
+ 230 ; vst.s r6
+ 231 ; vst.d r6
+ 232 ; vsub.ss r2,r4,r6
+ 233 ; vsub.sd r2,r4,r6
+ 234 ; vsub.dd r2,r4,r6
+ 235 000002C4 0170A006 wrcr r6,r5
+ 236 000002C8 39B32005 xnor r5,r6,r7
+ 237 000002CC 4A32C007 xor r7,r8,r9
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/regops.s b/gas/testsuite/gas/tic80/regops.s
new file mode 100644
index 00000000000..f4f93523c31
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops.s
@@ -0,0 +1,237 @@
+;; Simple register forms
+;; Those instructions which also use an immediate just use a constant.
+
+ .text
+
+ add r3,r4,r5
+ addu r3,r4,r5
+ and r5,r4,r2
+ and.tt r5,r4,r2
+ and.ff r10,r12,r14
+ and.ft r10,r12,r14
+ and.tf r10,r12,r14
+ bbo r10,r8,lo.w
+ bbo.a r10,r8,eq.b
+ bbz r10,r8,ls.w
+ bbz.a r10,r8,hi.w
+ bcnd r4,r6,lt0.b
+ bcnd.a r4,r6,lt0.b
+ br r6
+ br.a r6
+ brcr 10
+ bsr r6,r31
+ bsr.a r6,r31
+ cmnd r7
+ cmp r3,r4,r5
+ dcachec r8(r10)
+ dcachef r8(r10)
+ dld.b r4(r6),r8
+ dld.h r4(r6),r8
+ dld r4(r6),r8
+ dld.d r4(r6),r8
+ dld.ub r4(r6),r8
+ dld.uh r4(r6),r8
+ dst.b r4(r6),r8
+ dst.h r4(r6),r8
+ dst r4(r6),r8
+ dst.d r4(r6),r8
+ etrap r5
+ exts r3,31,r5,r6
+ extu r2,30,r5,r9
+ fadd.sss r2,r4,r6
+ fadd.ssd r2,r4,r6
+ fadd.sdd r2,r4,r6
+ fadd.dsd r2,r4,r6
+ fadd.ddd r2,r4,r6
+ fcmp.ss r4,r6,r8
+ fcmp.sd r4,r6,r8
+ fcmp.ds r4,r6,r8
+ fcmp.dd r4,r6,r8
+ fdiv.sss r2,r4,r6
+ fdiv.ssd r2,r4,r6
+ fdiv.sdd r2,r4,r6
+ fdiv.dsd r2,r4,r6
+ fdiv.ddd r2,r4,r6
+ fmpy.sss r2,r4,r6
+ fmpy.ssd r2,r4,r6
+ fmpy.sdd r2,r4,r6
+ fmpy.dsd r2,r4,r6
+ fmpy.ddd r2,r4,r6
+ fmpy.iii r2,r4,r6
+ fmpy.uuu r2,r4,r6
+ frndm.ss r4,r6
+ frndm.sd r4,r6
+ frndm.si r4,r6
+ frndm.su r4,r6
+ frndm.ds r2,r8
+ frndm.dd r2,r8
+ frndm.di r2,r8
+ frndm.du r2,r8
+ frndm.is r4,r6
+ frndm.id r4,r6
+ frndm.us r2,r8
+ frndm.ud r2,r8
+ frndn.ss r4,r6
+ frndn.sd r4,r6
+ frndn.si r4,r6
+ frndn.su r4,r6
+ frndn.ds r2,r8
+ frndn.dd r2,r8
+ frndn.di r2,r8
+ frndn.du r2,r8
+ frndn.is r4,r6
+ frndn.id r4,r6
+ frndn.us r2,r8
+ frndn.ud r2,r8
+ frndp.ss r4,r6
+ frndp.sd r4,r6
+ frndp.si r4,r6
+ frndp.su r4,r6
+ frndp.ds r2,r8
+ frndp.dd r2,r8
+ frndp.di r2,r8
+ frndp.du r2,r8
+ frndp.is r4,r6
+ frndp.id r4,r6
+ frndp.us r2,r8
+ frndp.ud r2,r8
+ frndz.ss r4,r6
+ frndz.sd r4,r6
+ frndz.si r4,r6
+ frndz.su r4,r6
+ frndz.ds r2,r8
+ frndz.dd r2,r8
+ frndz.di r2,r8
+ frndz.du r2,r8
+ frndz.is r4,r6
+ frndz.id r4,r6
+ frndz.us r2,r8
+ frndz.ud r2,r8
+ fsqrt.ss r6,r8
+ fsqrt.sd r6,r8
+ fsqrt.dd r6,r8
+ fsub.sss r2,r4,r6
+ fsub.ssd r2,r4,r6
+ fsub.sdd r2,r4,r6
+ fsub.dsd r2,r4,r6
+ fsub.ddd r2,r4,r6
+ ins r4,31,r8,r10
+ jsr r4(r6),r8
+ jsr.a r4(r6),r8
+ ld.b r4(r6),r8
+ ld.h r4(r6),r8
+ ld r4(r6),r8
+ ld.d r4(r6),r8
+ ld.ub r4(r6),r8
+ ld.uh r4(r6),r8
+ lmo r7,r8
+ or r1,r2,r3
+ or.tt r1,r2,r3
+ or.ff r1,r2,r3
+ or.ft r1,r2,r3
+ or.tf r1,r2,r3
+ rdcr r6,r4
+ rmo r4,r5
+ rotl r2,31,r8,r10
+ rotr r8,31,r2,r6
+ shl r4,31,r2,r6
+ sl.dz r4,12,r5,r6
+ sl.dm r4,12,r5,r6
+ sl.ds r4,12,r5,r6
+ sl.ez r4,12,r5,r6
+ sl.em r4,12,r5,r6
+ sl.es r4,12,r5,r6
+ sl.iz r4,12,r5,r6
+ sl.im r4,12,r5,r6
+ sli.dz r4,12,r5,r6
+ sli.dm r4,12,r5,r6
+ sli.ds r4,12,r5,r6
+ sli.ez r4,12,r5,r6
+ sli.em r4,12,r5,r6
+ sli.es r4,12,r5,r6
+ sli.iz r4,12,r5,r6
+ sli.im r4,12,r5,r6
+ sr.dz r4,12,r5,r6
+ sr.dm r4,12,r5,r6
+ sr.ds r4,12,r5,r6
+ sr.ez r4,12,r5,r6
+ sr.em r4,12,r5,r6
+ sr.es r4,12,r5,r6
+ sr.iz r4,12,r5,r6
+ sr.im r4,12,r5,r6
+ sra r4,32,r6,r8
+ sri.dz r4,12,r5,r6
+ sri.dm r4,12,r5,r6
+ sri.ds r4,12,r5,r6
+ sri.ez r4,12,r5,r6
+ sri.em r4,12,r5,r6
+ sri.es r4,12,r5,r6
+ sri.iz r4,12,r5,r6
+ sri.im r4,12,r5,r6
+ srl r4,32,r6,r8
+ st.b r4(r6),r8
+ st.h r4(r6),r8
+ st r4(r6),r8
+ st.d r4(r6),r8
+ sub r7,r8,r9
+ subu r7,r8,r9
+ swcr r8,r6,r4
+ trap r10
+ vadd.ss r2,r4,r4
+ vadd.sd r2,r6,r6
+ vadd.dd r2,r10,r10
+; vld0.s r6
+; vld1.s r7
+; vld0.d r6
+; vld1.d r8
+; vmac.sss r7,r9,0,a3
+; vmac.sss r7,r9,0,r10
+; vmac.sss r7,r9,a1,a3
+; vmac.sss r7,r9,a3,r10
+; vmac.ssd r7,r9,0,a0
+; vmac.ssd r7,r9,0,r10
+; vmac.ssd r7,r9,a1,a2
+; vmac.ssd r7,r9,a3,r10
+; vmpy.ss r1,r3,r3
+; vmpy.sd r5,r6,r6
+; vmpy.dd r2,r4,r4
+; vmsc.sss r7,r9,0,a0
+; vmsc.sss r7,r9,0,r10
+; vmsc.sss r7,r9,a0,a1
+; vmsc.sss r7,r9,a3,r10
+; vmsc.ssd r7,r9,0,a0
+; vmsc.ssd r7,r9,0,r10
+; vmsc.ssd r7,r9,a0,a1
+; vmsc.ssd r7,r9,a3,r10
+; vmsub.ss r6,a2,a4
+; vmsub.sd r6,a2,a4
+; vmsub.ss r4,a4,r6
+; vmsub.sd r4,a4,r6
+; vrnd.si r4,r6
+; vrnd.si r4,a0
+; vrnd.su r4,r6
+; vrnd.su r4,a0
+; vrnd.ss r4,r6
+; vrnd.ss r4,a0
+; vrnd.sd r4,r6
+; vrnd.sd r4,a0
+; vrnd.di r4,r6
+; vrnd.di r4,a0
+; vrnd.du r4,r6
+; vrnd.du r4,a0
+; vrnd.ds r4,r6
+; vrnd.ds r4,a0
+; vrnd.dd r4,r6
+; vrnd.dd r4,a0
+; vrnd.is r4,r6
+; vrnd.id r4,r6
+; vrnd.us r4,r6
+; vrnd.ud r4,r6
+; vst.s r6
+; vst.d r6
+; vsub.ss r2,r4,r6
+; vsub.sd r2,r4,r6
+; vsub.dd r2,r4,r6
+ wrcr r6,r5
+ xnor r5,r6,r7
+ xor r7,r8,r9
diff --git a/gas/testsuite/gas/tic80/regops2.d b/gas/testsuite/gas/tic80/regops2.d
new file mode 100644
index 00000000000..0b7f4a16bf5
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops2.d
@@ -0,0 +1,68 @@
+#objdump: -d
+#name: TIc80 register operands with :m modifier
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 08 80 b7 02.*
+ 4: 04 00 9e 02.*
+ 8: fc 7f 9e 02.*
+ c: 00 90 b7 02 78 56 34 12.*
+ 14: 00 90 b7 02 ef be ad de.*
+ 1c: 08 80 b7 0a.*
+ 20: 04 00 9e 0a.*
+ 24: fc 7f 9e 0a.*
+ 28: 00 90 b7 0a 78 56 34 12.*
+ 30: 00 90 b7 0a ef be ad de.*
+ 38: 04 84 b4 41.*
+ 3c: 04 a4 b4 41.*
+ 40: 04 c4 b4 41.*
+ 44: 04 e4 b4 41.*
+ 48: 00 94 b4 41 00 00 00 e0.*
+ 50: 00 b4 b4 41 00 00 00 e0.*
+ 58: 00 d4 b4 41 00 00 00 e0.*
+ 60: 00 f4 b4 41 00 00 00 e0.*
+ 68: 04 84 b5 41.*
+ 6c: 04 a4 b5 41.*
+ 70: 00 94 b5 41 00 00 00 e0.*
+ 78: 00 b4 b5 41 00 00 00 e0.*
+ 80: 04 84 b6 41.*
+ 84: 04 a4 b6 41.*
+ 88: 04 c4 b6 41.*
+ 8c: 04 e4 b6 41.*
+ 90: 00 94 b6 41 00 00 00 e0.*
+ 98: 00 b4 b6 41 00 00 00 e0.*
+ a0: 00 d4 b6 41 00 00 00 e0.*
+ a8: 00 f4 b6 41 00 00 00 e0.*
+ b0: 04 80 b4 41.*
+ b4: 04 a0 b4 41.*
+ b8: 04 c0 b4 41.*
+ bc: 04 e0 b4 41.*
+ c0: f0 7f 92 41.*
+ c4: f0 ff 92 41.*
+ c8: f0 7f 93 41.*
+ cc: f0 ff 93 41.*
+ d0: 00 90 b4 41 00 00 00 e0.*
+ d8: 00 b0 b4 41 00 00 00 e0.*
+ e0: 00 d0 b4 41 00 00 00 e0.*
+ e8: 00 f0 b4 41 00 00 00 e0.*
+ f0: 04 80 b5 41.*
+ f4: 04 a0 b5 41.*
+ f8: f0 7f 96 41.*
+ fc: f0 ff 96 41.*
+ 100: 00 90 b5 41 00 00 00 e0.*
+ 108: 00 b0 b5 41 00 00 00 e0.*
+ 110: 04 80 b6 41.*
+ 114: 04 a0 b6 41.*
+ 118: 04 c0 b6 41.*
+ 11c: 04 e0 b6 41.*
+ 120: 00 7f 9a 41.*
+ 124: 00 ff 9a 41.*
+ 128: 00 7f 9b 41.*
+ 12c: 00 ff 9b 41.*
+ 130: 00 90 b6 41 00 00 00 e0.*
+ 138: 00 b0 b6 41 00 00 00 e0.*
+ 140: 00 d0 b6 41 00 00 00 e0.*
+ 148: 00 f0 b6 41 00 00 00 e0.*
diff --git a/gas/testsuite/gas/tic80/regops2.lst b/gas/testsuite/gas/tic80/regops2.lst
new file mode 100644
index 00000000000..651fb9716f7
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops2.lst
@@ -0,0 +1,96 @@
+MVP MP Macro Assembler Version 1.13 Wed Feb 26 14:32:14 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops2.s PAGE 1
+
+ 1 00000000 02B78008 dcachec r8(r10:m) ; Register form (modified)
+ 2 00000004 029E0004 dcachec 4(r10:m) ; Short Immediate form (positive offset) (modified)
+ 3 00000008 029E7FFC dcachec -4(r10:m) ; Short Immediate form (negative offset) (modified)
+ 4 0000000C 02B79000 dcachec 0x12345678(r10:m) ; Long Immediate form (positive offset) (modified)
+ 00000010 12345678
+ 5 00000014 02B79000 dcachec 0xDEADBEEF(r10:m) ; Long Immediate form (negative offset) (modified)
+ 00000018 DEADBEEF
+ 6 0000001C 0AB78008 dcachef r8(r10:m) ; Register form (modified)
+ 7 00000020 0A9E0004 dcachef 4(r10:m) ; Short Immediate form (positive offset) (modified)
+ 8 00000024 0A9E7FFC dcachef -4(r10:m) ; Short Immediate form (negative offset) (modified)
+ 9 00000028 0AB79000 dcachef 0x12345678(r10:m) ; Long Immediate form (positive offset) (modified)
+ 0000002C 12345678
+ 10 00000030 0AB79000 dcachef 0xDEADBEEF(r10:m) ; Long Immediate form (negative offset) (modified)
+ 00000034 DEADBEEF
+ 11 00000038 41B48404 dld.b r4(r6:m),r8 ; Register form
+ 12 0000003C 41B4A404 dld.h r4(r6:m),r8 ; Register form
+ 13 00000040 41B4C404 dld r4(r6:m),r8 ; Register form
+ 14 00000044 41B4E404 dld.d r4(r6:m),r8 ; Register form
+ 15 00000048 41B49400 dld.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000004C E0000000
+ 16 00000050 41B4B400 dld.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000054 E0000000
+ 17 00000058 41B4D400 dld 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000005C E0000000
+ 18 00000060 41B4F400 dld.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000064 E0000000
+ 19 00000068 41B58404 dld.ub r4(r6:m),r8 ; Register form
+ 20 0000006C 41B5A404 dld.uh r4(r6:m),r8 ; Register form
+ 21 00000070 41B59400 dld.ub 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000074 E0000000
+ 22 00000078 41B5B400 dld.uh 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000007C E0000000
+ 23 00000080 41B68404 dst.b r4(r6:m),r8 ; Register form
+ 24 00000084 41B6A404 dst.h r4(r6:m),r8 ; Register form
+ 25 00000088 41B6C404 dst r4(r6:m),r8 ; Register form
+ 26 0000008C 41B6E404 dst.d r4(r6:m),r8 ; Register form
+ 27 00000090 41B69400 dst.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000094 E0000000
+ 28 00000098 41B6B400 dst.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000009C E0000000
+ 29 000000A0 41B6D400 dst 0xE0000000(r6:m),r8 ; Long Immediate form
+ 000000A4 E0000000
+ 30 000000A8 41B6F400 dst.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ 000000AC E0000000
+ 31 000000B0 41B48004 ld.b r4(r6:m),r8 ; Register form
+ 32 000000B4 41B4A004 ld.h r4(r6:m),r8 ; Register form
+ 33 000000B8 41B4C004 ld r4(r6:m),r8 ; Register form
+ 34 000000BC 41B4E004 ld.d r4(r6:m),r8 ; Register form
+ 35 000000C0 41927FF0 ld.b -16(r6:m),r8 ; Short Immediate form
+ 36 000000C4 4192FFF0 ld.h -16(r6:m),r8 ; Short Immediate form
+ 37 000000C8 41937FF0 ld -16(r6:m),r8 ; Short Immediate form
+ 38 000000CC 4193FFF0 ld.d -16(r6:m),r8 ; Short Immediate form
+ 39 000000D0 41B49000 ld.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ 000000D4 E0000000
+ 40 000000D8 41B4B000 ld.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ MVP MP Macro Assembler Version 1.13 Wed Feb 26 14:32:14 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops2.s PAGE 2
+
+ 000000DC E0000000
+ 41 000000E0 41B4D000 ld 0xE0000000(r6:m),r8 ; Long Immediate form
+ 000000E4 E0000000
+ 42 000000E8 41B4F000 ld.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ 000000EC E0000000
+ 43 000000F0 41B58004 ld.ub r4(r6:m),r8 ; Register form
+ 44 000000F4 41B5A004 ld.uh r4(r6:m),r8 ; Register form
+ 45 000000F8 41967FF0 ld.ub -16(r6:m),r8 ; Short Immediate form
+ 46 000000FC 4196FFF0 ld.uh -16(r6:m),r8 ; Short Immediate form
+ 47 00000100 41B59000 ld.ub 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000104 E0000000
+ 48 00000108 41B5B000 ld.uh 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000010C E0000000
+ 49 00000110 41B68004 st.b r4(r6:m),r8 ; Register form
+ 50 00000114 41B6A004 st.h r4(r6:m),r8 ; Register form
+ 51 00000118 41B6C004 st r4(r6:m),r8 ; Register form
+ 52 0000011C 41B6E004 st.d r4(r6:m),r8 ; Register form
+ 53 00000120 419A7F00 st.b -256(r6:m),r8 ; Short Immediate form
+ 54 00000124 419AFF00 st.h -256(r6:m),r8 ; Short Immediate form
+ 55 00000128 419B7F00 st -256(r6:m),r8 ; Short Immediate form
+ 56 0000012C 419BFF00 st.d -256(r6:m),r8 ; Short Immediate form
+ 57 00000130 41B69000 st.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000134 E0000000
+ 58 00000138 41B6B000 st.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000013C E0000000
+ 59 00000140 41B6D000 st 0xE0000000(r6:m),r8 ; Long Immediate form
+ 00000144 E0000000
+ 60 00000148 41B6F000 st.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ 0000014C E0000000
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/regops2.s b/gas/testsuite/gas/tic80/regops2.s
new file mode 100644
index 00000000000..18755b38467
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops2.s
@@ -0,0 +1,60 @@
+ dcachec r8(r10:m) ; Register form (modified)
+ dcachec 4(r10:m) ; Short Immediate form (positive offset) (modified)
+ dcachec -4(r10:m) ; Short Immediate form (negative offset) (modified)
+ dcachec 0x12345678(r10:m) ; Long Immediate form (positive offset) (modified)
+ dcachec 0xDEADBEEF(r10:m) ; Long Immediate form (negative offset) (modified)
+ dcachef r8(r10:m) ; Register form (modified)
+ dcachef 4(r10:m) ; Short Immediate form (positive offset) (modified)
+ dcachef -4(r10:m) ; Short Immediate form (negative offset) (modified)
+ dcachef 0x12345678(r10:m) ; Long Immediate form (positive offset) (modified)
+ dcachef 0xDEADBEEF(r10:m) ; Long Immediate form (negative offset) (modified)
+ dld.b r4(r6:m),r8 ; Register form
+ dld.h r4(r6:m),r8 ; Register form
+ dld r4(r6:m),r8 ; Register form
+ dld.d r4(r6:m),r8 ; Register form
+ dld.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ dld.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ dld 0xE0000000(r6:m),r8 ; Long Immediate form
+ dld.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ dld.ub r4(r6:m),r8 ; Register form
+ dld.uh r4(r6:m),r8 ; Register form
+ dld.ub 0xE0000000(r6:m),r8 ; Long Immediate form
+ dld.uh 0xE0000000(r6:m),r8 ; Long Immediate form
+ dst.b r4(r6:m),r8 ; Register form
+ dst.h r4(r6:m),r8 ; Register form
+ dst r4(r6:m),r8 ; Register form
+ dst.d r4(r6:m),r8 ; Register form
+ dst.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ dst.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ dst 0xE0000000(r6:m),r8 ; Long Immediate form
+ dst.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ ld.b r4(r6:m),r8 ; Register form
+ ld.h r4(r6:m),r8 ; Register form
+ ld r4(r6:m),r8 ; Register form
+ ld.d r4(r6:m),r8 ; Register form
+ ld.b -16(r6:m),r8 ; Short Immediate form
+ ld.h -16(r6:m),r8 ; Short Immediate form
+ ld -16(r6:m),r8 ; Short Immediate form
+ ld.d -16(r6:m),r8 ; Short Immediate form
+ ld.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ ld.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ ld 0xE0000000(r6:m),r8 ; Long Immediate form
+ ld.d 0xE0000000(r6:m),r8 ; Long Immediate form
+ ld.ub r4(r6:m),r8 ; Register form
+ ld.uh r4(r6:m),r8 ; Register form
+ ld.ub -16(r6:m),r8 ; Short Immediate form
+ ld.uh -16(r6:m),r8 ; Short Immediate form
+ ld.ub 0xE0000000(r6:m),r8 ; Long Immediate form
+ ld.uh 0xE0000000(r6:m),r8 ; Long Immediate form
+ st.b r4(r6:m),r8 ; Register form
+ st.h r4(r6:m),r8 ; Register form
+ st r4(r6:m),r8 ; Register form
+ st.d r4(r6:m),r8 ; Register form
+ st.b -256(r6:m),r8 ; Short Immediate form
+ st.h -256(r6:m),r8 ; Short Immediate form
+ st -256(r6:m),r8 ; Short Immediate form
+ st.d -256(r6:m),r8 ; Short Immediate form
+ st.b 0xE0000000(r6:m),r8 ; Long Immediate form
+ st.h 0xE0000000(r6:m),r8 ; Long Immediate form
+ st 0xE0000000(r6:m),r8 ; Long Immediate form
+ st.d 0xE0000000(r6:m),r8 ; Long Immediate form
diff --git a/gas/testsuite/gas/tic80/regops3.d b/gas/testsuite/gas/tic80/regops3.d
new file mode 100644
index 00000000000..32a30124070
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops3.d
@@ -0,0 +1,28 @@
+#objdump: -d
+#name: TIc80 register operands with :s modifier
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 04 0c b4 41.*
+ 4: 04 2c b4 41.*
+ 8: 04 4c b4 41.*
+ c: 04 6c b4 41.*
+ 10: 04 0c b5 41.*
+ 14: 04 2c b5 41.*
+ 18: 04 0c b6 41.*
+ 1c: 04 2c b6 41.*
+ 20: 04 4c b6 41.*
+ 24: 04 6c b6 41.*
+ 28: 04 08 b4 41.*
+ 2c: 04 28 b4 41.*
+ 30: 04 48 b4 41.*
+ 34: 04 68 b4 41.*
+ 38: 04 08 b5 41.*
+ 3c: 04 28 b5 41.*
+ 40: 04 08 b6 41.*
+ 44: 04 28 b6 41.*
+ 48: 04 48 b6 41.*
+ 4c: 04 68 b6 41.*
diff --git a/gas/testsuite/gas/tic80/regops3.lst b/gas/testsuite/gas/tic80/regops3.lst
new file mode 100644
index 00000000000..d65803f1a67
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops3.lst
@@ -0,0 +1,27 @@
+MVP MP Macro Assembler Version 1.13 Wed Feb 26 14:32:19 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops3.s PAGE 1
+
+ 1 00000000 41B40C04 dld.b r4:s(r6),r8 ; Register form
+ 2 00000004 41B42C04 dld.h r4:s(r6),r8 ; Register form
+ 3 00000008 41B44C04 dld r4:s(r6),r8 ; Register form
+ 4 0000000C 41B46C04 dld.d r4:s(r6),r8 ; Register form
+ 5 00000010 41B50C04 dld.ub r4:s(r6),r8 ; Register form
+ 6 00000014 41B52C04 dld.uh r4:s(r6),r8 ; Register form
+ 7 00000018 41B60C04 dst.b r4:s(r6),r8 ; Register form
+ 8 0000001C 41B62C04 dst.h r4:s(r6),r8 ; Register form
+ 9 00000020 41B64C04 dst r4:s(r6),r8 ; Register form
+ 10 00000024 41B66C04 dst.d r4:s(r6),r8 ; Register form
+ 11 00000028 41B40804 ld.b r4:s(r6),r8 ; Register form
+ 12 0000002C 41B42804 ld.h r4:s(r6),r8 ; Register form
+ 13 00000030 41B44804 ld r4:s(r6),r8 ; Register form
+ 14 00000034 41B46804 ld.d r4:s(r6),r8 ; Register form
+ 15 00000038 41B50804 ld.ub r4:s(r6),r8 ; Register form
+ 16 0000003C 41B52804 ld.uh r4:s(r6),r8 ; Register form
+ 17 00000040 41B60804 st.b r4:s(r6),r8 ; Register form
+ 18 00000044 41B62804 st.h r4:s(r6),r8 ; Register form
+ 19 00000048 41B64804 st r4:s(r6),r8 ; Register form
+ 20 0000004C 41B66804 st.d r4:s(r6),r8 ; Register form
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/regops3.s b/gas/testsuite/gas/tic80/regops3.s
new file mode 100644
index 00000000000..5ed87d5109c
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops3.s
@@ -0,0 +1,20 @@
+ dld.b r4:s(r6),r8 ; Register form
+ dld.h r4:s(r6),r8 ; Register form
+ dld r4:s(r6),r8 ; Register form
+ dld.d r4:s(r6),r8 ; Register form
+ dld.ub r4:s(r6),r8 ; Register form
+ dld.uh r4:s(r6),r8 ; Register form
+ dst.b r4:s(r6),r8 ; Register form
+ dst.h r4:s(r6),r8 ; Register form
+ dst r4:s(r6),r8 ; Register form
+ dst.d r4:s(r6),r8 ; Register form
+ ld.b r4:s(r6),r8 ; Register form
+ ld.h r4:s(r6),r8 ; Register form
+ ld r4:s(r6),r8 ; Register form
+ ld.d r4:s(r6),r8 ; Register form
+ ld.ub r4:s(r6),r8 ; Register form
+ ld.uh r4:s(r6),r8 ; Register form
+ st.b r4:s(r6),r8 ; Register form
+ st.h r4:s(r6),r8 ; Register form
+ st r4:s(r6),r8 ; Register form
+ st.d r4:s(r6),r8 ; Register form
diff --git a/gas/testsuite/gas/tic80/regops4.d b/gas/testsuite/gas/tic80/regops4.d
new file mode 100644
index 00000000000..33607c96924
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops4.d
@@ -0,0 +1,28 @@
+#objdump: -d
+#name: TIc80 register operands with both :m and :s modifier
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <.text>:
+ 0: 04 8c b4 41.*
+ 4: 04 ac b4 41.*
+ 8: 04 cc b4 41.*
+ c: 04 ec b4 41.*
+ 10: 04 8c b5 41.*
+ 14: 04 ac b5 41.*
+ 18: 04 8c b6 41.*
+ 1c: 04 ac b6 41.*
+ 20: 04 cc b6 41.*
+ 24: 04 ec b6 41.*
+ 28: 04 88 b4 41.*
+ 2c: 04 a8 b4 41.*
+ 30: 04 c8 b4 41.*
+ 34: 04 e8 b4 41.*
+ 38: 04 88 b5 41.*
+ 3c: 04 a8 b5 41.*
+ 40: 04 88 b6 41.*
+ 44: 04 a8 b6 41.*
+ 48: 04 c8 b6 41.*
+ 4c: 04 e8 b6 41.*
diff --git a/gas/testsuite/gas/tic80/regops4.lst b/gas/testsuite/gas/tic80/regops4.lst
new file mode 100644
index 00000000000..3af3c9af499
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops4.lst
@@ -0,0 +1,27 @@
+MVP MP Macro Assembler Version 1.13 Wed Feb 26 14:32:25 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+regops4.s PAGE 1
+
+ 1 00000000 41B48C04 dld.b r4:s(r6:m),r8 ; Register form
+ 2 00000004 41B4AC04 dld.h r4:s(r6:m),r8 ; Register form
+ 3 00000008 41B4CC04 dld r4:s(r6:m),r8 ; Register form
+ 4 0000000C 41B4EC04 dld.d r4:s(r6:m),r8 ; Register form
+ 5 00000010 41B58C04 dld.ub r4:s(r6:m),r8 ; Register form
+ 6 00000014 41B5AC04 dld.uh r4:s(r6:m),r8 ; Register form
+ 7 00000018 41B68C04 dst.b r4:s(r6:m),r8 ; Register form
+ 8 0000001C 41B6AC04 dst.h r4:s(r6:m),r8 ; Register form
+ 9 00000020 41B6CC04 dst r4:s(r6:m),r8 ; Register form
+ 10 00000024 41B6EC04 dst.d r4:s(r6:m),r8 ; Register form
+ 11 00000028 41B48804 ld.b r4:s(r6:m),r8 ; Register form
+ 12 0000002C 41B4A804 ld.h r4:s(r6:m),r8 ; Register form
+ 13 00000030 41B4C804 ld r4:s(r6:m),r8 ; Register form
+ 14 00000034 41B4E804 ld.d r4:s(r6:m),r8 ; Register form
+ 15 00000038 41B58804 ld.ub r4:s(r6:m),r8 ; Register form
+ 16 0000003C 41B5A804 ld.uh r4:s(r6:m),r8 ; Register form
+ 17 00000040 41B68804 st.b r4:s(r6:m),r8 ; Register form
+ 18 00000044 41B6A804 st.h r4:s(r6:m),r8 ; Register form
+ 19 00000048 41B6C804 st r4:s(r6:m),r8 ; Register form
+ 20 0000004C 41B6E804 st.d r4:s(r6:m),r8 ; Register form
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/regops4.s b/gas/testsuite/gas/tic80/regops4.s
new file mode 100644
index 00000000000..5ba77e9138e
--- /dev/null
+++ b/gas/testsuite/gas/tic80/regops4.s
@@ -0,0 +1,20 @@
+ dld.b r4:s(r6:m),r8 ; Register form
+ dld.h r4:s(r6:m),r8 ; Register form
+ dld r4:s(r6:m),r8 ; Register form
+ dld.d r4:s(r6:m),r8 ; Register form
+ dld.ub r4:s(r6:m),r8 ; Register form
+ dld.uh r4:s(r6:m),r8 ; Register form
+ dst.b r4:s(r6:m),r8 ; Register form
+ dst.h r4:s(r6:m),r8 ; Register form
+ dst r4:s(r6:m),r8 ; Register form
+ dst.d r4:s(r6:m),r8 ; Register form
+ ld.b r4:s(r6:m),r8 ; Register form
+ ld.h r4:s(r6:m),r8 ; Register form
+ ld r4:s(r6:m),r8 ; Register form
+ ld.d r4:s(r6:m),r8 ; Register form
+ ld.ub r4:s(r6:m),r8 ; Register form
+ ld.uh r4:s(r6:m),r8 ; Register form
+ st.b r4:s(r6:m),r8 ; Register form
+ st.h r4:s(r6:m),r8 ; Register form
+ st r4:s(r6:m),r8 ; Register form
+ st.d r4:s(r6:m),r8 ; Register form
diff --git a/gas/testsuite/gas/tic80/relocs1.c b/gas/testsuite/gas/tic80/relocs1.c
new file mode 100644
index 00000000000..6af04b1100a
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs1.c
@@ -0,0 +1,28 @@
+extern int xfunc (int y);
+
+static int sfunc (int y)
+{
+ xfunc (y);
+}
+
+int gfunc (int y)
+{
+ sfunc (y);
+}
+
+int branches (int y)
+{
+ int z;
+
+ for (z = y; z < y + 10; z++)
+ {
+ if (z & 0x1)
+ {
+ gfunc (z);
+ }
+ else
+ {
+ xfunc (z);
+ }
+ }
+}
diff --git a/gas/testsuite/gas/tic80/relocs1.d b/gas/testsuite/gas/tic80/relocs1.d
new file mode 100644
index 00000000000..14ca6c9b124
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs1.d
@@ -0,0 +1,56 @@
+#objdump: -d
+#name: TIc80 simple relocs, global/local funcs & branches (code)
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <_sfunc>:
+ 0: f0 ff 6c 08.*
+ 4: 0c 00 59 f8.*
+ 8: 00 00 59 10.*
+ c: 00 90 38 f8 00 00 00 00.*
+ 14: 00 00 51 10.*
+ 18: 0c 00 51 f8.*
+ 1c: 1f 80 38 00.*
+ 20: 10 80 6c 08.*
+
+00000024 <_gfunc>:
+ 24: f0 ff 6c 08.*
+ 28: 0c 00 59 f8.*
+ 2c: 00 00 59 10.*
+ 30: 00 90 38 f8 00 00 00 00.*
+ 38: 00 00 51 10.*
+ 3c: 0c 00 51 f8.*
+ 40: 1f 80 38 00.*
+ 44: 10 80 6c 08.*
+
+00000048 <_branches>:
+ 48: f0 ff 6c 08.*
+ 4c: 0c 00 59 f8.*
+ 50: 00 00 59 10.*
+ 54: 00 00 51 10.*
+ 58: 04 00 59 10.*
+ 5c: 00 00 51 10.*
+ 60: 04 00 51 18.*
+ 64: 0a 80 ac 10.*
+ 68: 03 00 ba 10.*
+ 6c: 12 80 a5 30.*
+ 70: 04 00 51 10.*
+ 74: 05 80 a4 f8.*
+ 78: 00 90 38 f8 24 00 00 00.*
+ 80: 04 00 51 10.*
+ 84: 04 80 24 00.*
+ 88: 00 90 38 f8 00 00 00 00.*
+ 90: 04 00 51 10.*
+ 94: 04 00 51 10.*
+ 98: 01 80 ac 10.*
+ 9c: 04 00 59 10.*
+ a0: 00 00 51 18.*
+ a4: 04 00 51 10.*
+ a8: 0a 80 ec 18.*
+ ac: 02 00 fa 10.*
+ b0: f0 ff a5 38.*
+ b4: 0c 00 51 f8.*
+ b8: 1f 80 38 00.*
+ bc: 10 80 6c 08.*
diff --git a/gas/testsuite/gas/tic80/relocs1.lst b/gas/testsuite/gas/tic80/relocs1.lst
new file mode 100644
index 00000000000..9faeb1aab4f
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs1.lst
@@ -0,0 +1,80 @@
+MVP MP Macro Assembler Version 1.13 Sat Feb 22 13:19:28 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+relocs1.s PAGE 1
+
+ 1 ;; This is the hand hacked output of the TI C compiler for a simple
+ 2 ;; test program that contains local/global functions, local/global
+ 3 ;; function calls, and an "if" and "for" statement.
+ 4
+ 5 .global _xfunc
+ 6
+ 7 00000000 _sfunc:
+ 8 00000000 086CFFF0 addu -16,r1,r1
+ 9 00000004 F859000C st 12(r1),r31
+ 10 00000008 10590000 st 0(r1),r2
+ 11 0000000C F8389000 jsr _xfunc(r0),r31
+ 00000010 00000000
+ 12 00000014 10510000 ld 0(r1),r2
+ 13 00000018 F851000C ld 12(r1),r31
+ 14 0000001C 0038801F jsr r31(r0),r0
+ 15 00000020 086C8010 addu 16,r1,r1
+ 16
+ 17 .global _gfunc
+ 18
+ 19 00000024 _gfunc:
+ 20 00000024 086CFFF0 addu -16,r1,r1
+ 21 00000028 F859000C st 12(r1),r31
+ 22 0000002C 10590000 st 0(r1),r2
+ 23 00000030 F8389000 jsr _sfunc(r0),r31
+ 00000034 00000000
+ 24 00000038 10510000 ld 0(r1),r2
+ 25 0000003C F851000C ld 12(r1),r31
+ 26 00000040 0038801F jsr r31(r0),r0
+ 27 00000044 086C8010 addu 16,r1,r1
+ 28
+ 29
+ 30 .global _branches
+ 31
+ 32 00000048 _branches:
+ 33 00000048 086CFFF0 addu -16,r1,r1
+ 34 0000004C F859000C st 12(r1),r31
+ 35 00000050 10590000 st 0(r1),r2
+ 36 00000054 10510000 ld 0(r1),r2
+ 37 00000058 10590004 st 4(r1),r2
+ 38 0000005C 10510000 ld 0(r1),r2
+ 39 00000060 18510004 ld 4(r1),r3
+ 40 00000064 10AC800A addu 10,r2,r2
+ 41 00000068 10BA0003 cmp r3,r2,r2
+ 42 0000006C 30A58012 bbo.a L12,r2,ge.w
+ 43 00000070 L8:
+ 44 00000070 10510004 ld 4(r1),r2
+ 45 00000074 F8A48005 bbz.a L10,r2,0
+ 46 00000078 F8389000 jsr _gfunc(r0),r31
+ 0000007C 00000024
+ 47 00000080 10510004 ld 4(r1),r2
+ 48 00000084 00248004 br.a L11
+ 49 00000088 L10:
+ 50 00000088 F8389000 jsr _xfunc(r0),r31
+ 0000008C 00000000
+ 51 00000090 10510004 ld 4(r1),r2
+ MVP MP Macro Assembler Version 1.13 Sat Feb 22 13:19:28 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+relocs1.s PAGE 2
+
+ 52 00000094 L11:
+ 53 00000094 10510004 ld 4(r1),r2
+ 54 00000098 10AC8001 addu 1,r2,r2
+ 55 0000009C 10590004 st 4(r1),r2
+ 56 000000A0 18510000 ld 0(r1),r3
+ 57 000000A4 10510004 ld 4(r1),r2
+ 58 000000A8 18EC800A addu 10,r3,r3
+ 59 000000AC 10FA0002 cmp r2,r3,r2
+ 60 000000B0 38A5FFF0 bbo.a L8,r2,lt.w
+ 61 000000B4 L12:
+ 62 000000B4 F851000C ld 12(r1),r31
+ 63 000000B8 0038801F jsr r31(r0),r0
+ 64 000000BC 086C8010 addu 16,r1,r1
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/relocs1.s b/gas/testsuite/gas/tic80/relocs1.s
new file mode 100644
index 00000000000..149e3956ed2
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs1.s
@@ -0,0 +1,66 @@
+;; This is the hand hacked output of the TI C compiler for a simple
+;; test program that contains local/global functions, local/global
+;; function calls, and an "if" and "for" statement.
+
+ .file "relocs1.s"
+
+ .global _xfunc
+
+_sfunc:
+ addu -16,r1,r1
+ st 12(r1),r31
+ st 0(r1),r2
+ jsr _xfunc(r0),r31
+ ld 0(r1),r2
+ ld 12(r1),r31
+ jsr r31(r0),r0
+ addu 16,r1,r1
+
+ .global _gfunc
+
+_gfunc:
+ addu -16,r1,r1
+ st 12(r1),r31
+ st 0(r1),r2
+ jsr _sfunc(r0),r31
+ ld 0(r1),r2
+ ld 12(r1),r31
+ jsr r31(r0),r0
+ addu 16,r1,r1
+
+
+ .global _branches
+
+_branches:
+ addu -16,r1,r1
+ st 12(r1),r31
+ st 0(r1),r2
+ ld 0(r1),r2
+ st 4(r1),r2
+ ld 0(r1),r2
+ ld 4(r1),r3
+ addu 10,r2,r2
+ cmp r3,r2,r2
+ bbo.a L12,r2,ge.w
+L8:
+ ld 4(r1),r2
+ bbz.a L10,r2,0
+ jsr _gfunc(r0),r31
+ ld 4(r1),r2
+ br.a L11
+L10:
+ jsr _xfunc(r0),r31
+ ld 4(r1),r2
+L11:
+ ld 4(r1),r2
+ addu 1,r2,r2
+ st 4(r1),r2
+ ld 0(r1),r3
+ ld 4(r1),r2
+ addu 10,r3,r3
+ cmp r2,r3,r2
+ bbo.a L8,r2,lt.w
+L12:
+ ld 12(r1),r31
+ jsr r31(r0),r0
+ addu 16,r1,r1
diff --git a/gas/testsuite/gas/tic80/relocs1b.d b/gas/testsuite/gas/tic80/relocs1b.d
new file mode 100644
index 00000000000..4eb31611d2f
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs1b.d
@@ -0,0 +1,12 @@
+#objdump: -r
+#source: relocs1.s
+#name: TIc80 simple relocs, global/local funcs & branches (relocs)
+
+.*: +file format .*tic80.*
+
+RELOCATION RECORDS FOR \[.text\]:
+OFFSET TYPE VALUE
+00000010 32 _xfunc
+00000034 32 .text
+0000007c 32 .text
+0000008c 32 _xfunc
diff --git a/gas/testsuite/gas/tic80/relocs2.c b/gas/testsuite/gas/tic80/relocs2.c
new file mode 100644
index 00000000000..3f1120c21bd
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs2.c
@@ -0,0 +1,41 @@
+extern char x_char;
+extern short x_short;
+static int x_int;
+extern long x_long;
+extern float x_float;
+extern double x_double;
+extern char *x_char_p;
+
+static char s_char;
+static short s_short;
+static int s_int;
+static long s_long;
+static float s_float;
+static double s_double;
+static char *s_char_p;
+
+char g_char;
+short g_short;
+int g_int;
+long g_long;
+float g_float;
+double g_double;
+char *g_char_p;
+
+main ()
+{
+ x_char = s_char;
+ g_char = x_char;
+ x_short = s_short;
+ g_short = x_short;
+ x_int = s_int;
+ g_int = x_int;
+ x_long = s_long;
+ g_long = x_long;
+ x_float = s_float;
+ g_float = x_float;
+ x_double = s_double;
+ g_double = x_double;
+ x_char_p = s_char_p;
+ g_char_p = x_char_p;
+}
diff --git a/gas/testsuite/gas/tic80/relocs2.d b/gas/testsuite/gas/tic80/relocs2.d
new file mode 100644
index 00000000000..cf3e87ded6b
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs2.d
@@ -0,0 +1,37 @@
+#objdump: -d
+#name: TIc80 simple relocs, static and global variables (code)
+
+.*: +file format .*tic80.*
+
+Disassembly of section .text:
+
+00000000 <_main>:
+ 0: 00 10 34 10 24 02 00 00.*
+ 8: 00 10 36 10 00 00 00 00.*
+ 10: 00 10 34 10 00 00 00 00.*
+ 18: 00 10 36 10 04 02 00 00.*
+ 20: 00 30 34 10 24 03 00 00.*
+ 28: 00 30 36 10 00 00 00 00.*
+ 30: 00 30 34 10 00 00 00 00.*
+ 38: 00 30 36 10 04 03 00 00.*
+ 40: 00 50 34 10 34 02 00 00.*
+ 48: 00 50 36 10 34 03 00 00.*
+ 50: 00 50 34 10 34 03 00 00.*
+ 58: 00 50 36 10 14 02 00 00.*
+ 60: 00 50 34 10 f4 01 00 00.*
+ 68: 00 50 36 10 00 00 00 00.*
+ 70: 00 50 34 10 00 00 00 00.*
+ 78: 00 50 36 10 f4 00 00 00.*
+ 80: 00 50 34 10 f4 02 00 00.*
+ 88: 00 50 36 10 00 00 00 00.*
+ 90: 00 50 34 10 00 00 00 00.*
+ 98: 00 50 36 10 14 03 00 00.*
+ a0: 00 70 34 10 e4 01 00 00.*
+ a8: 00 70 36 10 00 00 00 00.*
+ b0: 00 70 34 10 00 00 00 00.*
+ b8: 00 70 36 10 e4 02 00 00.*
+ c0: 00 50 34 10 44 03 00 00.*
+ c8: 00 50 36 10 00 00 00 00.*
+ d0: 00 50 34 10 00 00 00 00.*
+ d8: 00 50 36 10 e4 00 00 00.*
+ e0: 1f a0 38 00.*
diff --git a/gas/testsuite/gas/tic80/relocs2.lst b/gas/testsuite/gas/tic80/relocs2.lst
new file mode 100644
index 00000000000..0690a8ce843
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs2.lst
@@ -0,0 +1,112 @@
+MVP MP Macro Assembler Version 1.13 Sun Feb 23 12:16:32 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+relocs2.s PAGE 1
+
+ 1 ;; This is the hand hacked output of the TI C compiler for a simple
+ 2 ;; test program that contains static, global, and extern data variables.
+ 3
+ 4 .file "relocs2.s"
+ 5 .global _x_char
+ 6 .global _x_short
+ 7 .global _x_long
+ 8 .global _x_float
+ 9 .global _x_double
+ 10 .global _x_char_p
+ 11 .global _g_char
+ 12 .global _g_short
+ 13 .global _g_int
+ 14 .global _g_long
+ 15 .global _g_float
+ 16 .global _g_double
+ 17 .global _g_char_p
+ 18 .global _main
+ 19
+ 20 00000000 _main:
+ 21 00000000 10341000 ld.b _s_char+0(r0),r2
+ 00000004 0000001C
+ 22 00000008 10361000 st.b _x_char+0(r0),r2
+ 0000000C 00000000
+ 23 00000010 10341000 ld.b _x_char+0(r0),r2
+ 00000014 00000000
+ 24 00000018 10361000 st.b _g_char+0(r0),r2
+ 0000001C 00000014
+ 25 00000020 10343000 ld.h _s_short+0(r0),r2
+ 00000024 0000003C
+ 26 00000028 10363000 st.h _x_short+0(r0),r2
+ 0000002C 00000000
+ 27 00000030 10343000 ld.h _x_short+0(r0),r2
+ 00000034 00000000
+ 28 00000038 10363000 st.h _g_short+0(r0),r2
+ 0000003C 00000034
+ 29 00000040 10345000 ld _s_int+0(r0),r2
+ 00000044 00000020
+ 30 00000048 10365000 st _x_int+0(r0),r2
+ 0000004C 00000040
+ 31 00000050 10345000 ld _x_int+0(r0),r2
+ 00000054 00000040
+ 32 00000058 10365000 st _g_int+0(r0),r2
+ 0000005C 00000018
+ 33 00000060 10345000 ld _s_long+0(r0),r2
+ 00000064 00000010
+ 34 00000068 10365000 st _x_long+0(r0),r2
+ 0000006C 00000000
+ 35 00000070 10345000 ld _x_long+0(r0),r2
+ 00000074 00000000
+ 36 00000078 10365000 st _g_long+0(r0),r2
+ 0000007C 00000004
+ 37 00000080 10345000 ld _s_float+0(r0),r2
+ 00000084 00000030
+ 38 00000088 10365000 st _x_float+0(r0),r2
+ MVP MP Macro Assembler Version 1.13 Sun Feb 23 12:16:32 1997
+Copyright (c) 1993-1995 Texas Instruments Incorporated
+
+relocs2.s PAGE 2
+
+ 0000008C 00000000
+ 39 00000090 10345000 ld _x_float+0(r0),r2
+ 00000094 00000000
+ 40 00000098 10365000 st _g_float+0(r0),r2
+ 0000009C 00000038
+ 41 000000A0 10347000 ld.d _s_double+0(r0),r2
+ 000000A4 00000008
+ 42 000000A8 10367000 st.d _x_double+0(r0),r2
+ 000000AC 00000000
+ 43 000000B0 10347000 ld.d _x_double+0(r0),r2
+ 000000B4 00000000
+ 44 000000B8 10367000 st.d _g_double+0(r0),r2
+ 000000BC 00000028
+ 45 000000C0 10345000 ld _s_char_p+0(r0),r2
+ 000000C4 00000044
+ 46 000000C8 10365000 st _x_char_p+0(r0),r2
+ 000000CC 00000000
+ 47 000000D0 10345000 ld _x_char_p+0(r0),r2
+ 000000D4 00000000
+ 48 000000D8 10365000 st _g_char_p+0(r0),r2
+ 000000DC 00000000
+ 49 000000E0 0038A01F jsr.a r31(r0),r0
+ 50
+ 51 .global _g_char_p
+ 52 00000000 .bss _g_char_p,4,4
+ 53 .global _g_long
+ 54 00000004 .bss _g_long,4,4
+ 55 00000008 .bss _s_double,8,8
+ 56 00000010 .bss _s_long,4,4
+ 57 .global _g_char
+ 58 00000014 .bss _g_char,1,4
+ 59 .global _g_int
+ 60 00000018 .bss _g_int,4,4
+ 61 0000001C .bss _s_char,1,4
+ 62 00000020 .bss _s_int,4,4
+ 63 .global _g_double
+ 64 00000028 .bss _g_double,8,8
+ 65 00000030 .bss _s_float,4,4
+ 66 .global _g_short
+ 67 00000034 .bss _g_short,2,4
+ 68 .global _g_float
+ 69 00000038 .bss _g_float,4,4
+ 70 0000003C .bss _s_short,2,4
+ 71 00000040 .bss _x_int,4,4
+ 72 00000044 .bss _s_char_p,4,4
+
+ No Errors, No Warnings
diff --git a/gas/testsuite/gas/tic80/relocs2.s b/gas/testsuite/gas/tic80/relocs2.s
new file mode 100644
index 00000000000..e4257df8656
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs2.s
@@ -0,0 +1,72 @@
+;; This is the hand hacked output of the TI C compiler for a simple
+;; test program that contains static, global, and extern data variables.
+
+ .file "relocs2.s"
+ .global _x_char
+ .global _x_short
+ .global _x_long
+ .global _x_float
+ .global _x_double
+ .global _x_char_p
+ .global _g_char
+ .global _g_short
+ .global _g_int
+ .global _g_long
+ .global _g_float
+ .global _g_double
+ .global _g_char_p
+ .global _main
+
+_main:
+ ld.b _s_char+0(r0),r2
+ st.b _x_char+0(r0),r2
+ ld.b _x_char+0(r0),r2
+ st.b _g_char+0(r0),r2
+ ld.h _s_short+0(r0),r2
+ st.h _x_short+0(r0),r2
+ ld.h _x_short+0(r0),r2
+ st.h _g_short+0(r0),r2
+ ld _s_int+0(r0),r2
+ st _x_int+0(r0),r2
+ ld _x_int+0(r0),r2
+ st _g_int+0(r0),r2
+ ld _s_long+0(r0),r2
+ st _x_long+0(r0),r2
+ ld _x_long+0(r0),r2
+ st _g_long+0(r0),r2
+ ld _s_float+0(r0),r2
+ st _x_float+0(r0),r2
+ ld _x_float+0(r0),r2
+ st _g_float+0(r0),r2
+ ld.d _s_double+0(r0),r2
+ st.d _x_double+0(r0),r2
+ ld.d _x_double+0(r0),r2
+ st.d _g_double+0(r0),r2
+ ld _s_char_p+0(r0),r2
+ st _x_char_p+0(r0),r2
+ ld _x_char_p+0(r0),r2
+ st _g_char_p+0(r0),r2
+ jsr.a r31(r0),r0
+
+ .global _g_char_p
+ .bss _g_char_p,4,4
+ .global _g_long
+ .bss _g_long,4,4
+ .bss _s_double,8,8
+ .bss _s_long,4,4
+ .global _g_char
+ .bss _g_char,1,4
+ .global _g_int
+ .bss _g_int,4,4
+ .bss _s_char,1,4
+ .bss _s_int,4,4
+ .global _g_double
+ .bss _g_double,8,8
+ .bss _s_float,4,4
+ .global _g_short
+ .bss _g_short,2,4
+ .global _g_float
+ .bss _g_float,4,4
+ .bss _s_short,2,4
+ .bss _x_int,4,4
+ .bss _s_char_p,4,4
diff --git a/gas/testsuite/gas/tic80/relocs2b.d b/gas/testsuite/gas/tic80/relocs2b.d
new file mode 100644
index 00000000000..604f99d90a4
--- /dev/null
+++ b/gas/testsuite/gas/tic80/relocs2b.d
@@ -0,0 +1,38 @@
+#objdump: -r
+#source: relocs2.s
+#name: TIc80 simple relocs, static and global variables (relocs)
+
+.*: +file format .*tic80.*
+
+RELOCATION RECORDS FOR \[.text\]:
+OFFSET TYPE VALUE
+00000004 32 .bss\+0xffffff1c
+0000000c 32 _x_char
+00000014 32 _x_char
+0000001c 32 .bss\+0xffffff1c
+00000024 32 .bss\+0xffffff1c
+0000002c 32 _x_short
+00000034 32 _x_short
+0000003c 32 .bss\+0xffffff1c
+00000044 32 .bss\+0xffffff1c
+0000004c 32 .bss\+0xffffff1c
+00000054 32 .bss\+0xffffff1c
+0000005c 32 .bss\+0xffffff1c
+00000064 32 .bss\+0xffffff1c
+0000006c 32 _x_long
+00000074 32 _x_long
+0000007c 32 .bss\+0xffffff1c
+00000084 32 .bss\+0xffffff1c
+0000008c 32 _x_float
+00000094 32 _x_float
+0000009c 32 .bss\+0xffffff1c
+000000a4 32 .bss\+0xffffff1c
+000000ac 32 _x_double
+000000b4 32 _x_double
+000000bc 32 .bss\+0xffffff1c
+000000c4 32 .bss\+0xffffff1c
+000000cc 32 _x_char_p
+000000d4 32 _x_char_p
+000000dc 32 .bss\+0xffffff1c
+
+
diff --git a/gas/testsuite/gas/tic80/tic80.exp b/gas/testsuite/gas/tic80/tic80.exp
new file mode 100644
index 00000000000..49c4633996f
--- /dev/null
+++ b/gas/testsuite/gas/tic80/tic80.exp
@@ -0,0 +1,21 @@
+#
+# TI TMS320C80 tests.
+#
+if [istarget tic80*-*-*] then {
+
+ run_dump_test "regops"
+ run_dump_test "regops2"
+ run_dump_test "regops3"
+ run_dump_test "regops4"
+ run_dump_test "cregops"
+ run_dump_test "float"
+ run_dump_test "endmask"
+ run_dump_test "bitnum"
+ run_dump_test "ccode"
+ run_dump_test "add"
+ run_dump_test "relocs1"
+ run_dump_test "relocs1b"
+ run_dump_test "relocs2"
+ run_dump_test "relocs2b"
+ run_dump_test "align"
+}
diff --git a/gas/testsuite/gas/v850/arith.s b/gas/testsuite/gas/v850/arith.s
new file mode 100644
index 00000000000..e72140fff13
--- /dev/null
+++ b/gas/testsuite/gas/v850/arith.s
@@ -0,0 +1,24 @@
+
+ .text
+ .global arith_opcodes
+arith_opcodes:
+ add r5,r6
+ add 5,r6
+ addi 7,r5,r6
+ divh r5,r6
+ mulh r5,r6
+ mulh 5,r6
+ mulhi 7,r5,r6
+ sar r5,r6
+ sar 31,r6
+ satadd r5,r6
+ satadd 5,r6
+ satsub r5,r6
+ satsubi 7,r5,r6
+ satsubr r5,r6
+ shl r5,r6
+ shl 31,r6
+ shr r5,r6
+ shr 31,r6
+ sub r5,r6
+ subr r5,r6
diff --git a/gas/testsuite/gas/v850/basic.exp b/gas/testsuite/gas/v850/basic.exp
new file mode 100644
index 00000000000..c06a631576c
--- /dev/null
+++ b/gas/testsuite/gas/v850/basic.exp
@@ -0,0 +1,438 @@
+# Copyright (C) 1996 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# Written by Cygnus Support.
+
+proc do_arith {} {
+ set testname "arith.s: Arithmetic operations"
+ set x 0
+
+ gas_start "arith.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ # -re "^ +\[0-9\]+ 0000 489A0000\[^\n\]*\n" { set x [expr $x+1] }
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 C531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 4532\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 05360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 4530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a E530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c E532\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e E5360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 E537A000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 BF32\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 C530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a 2532\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c A530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e 65360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 8530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 E537C000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 DF32\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002a E5378000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002e 9F32\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 A531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0032 8531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==20] then { pass $testname } else { fail $testname }
+}
+
+proc do_bit {} {
+ set testname "bit.s: bit operations"
+ set x 0
+
+ gas_start "bit.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 C6AF1000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 C66F1000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 C62F1000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c C6EF1000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_branch {} {
+ set testname "branch.s: branch operations"
+ set x 0
+
+ gas_start "branch.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 8F05\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 FEFD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 E6FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 D7FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 CBFD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a B9FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c A1FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e 93FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 82FD\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 FAF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 E0F5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 D8F5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 C4F5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a BCF5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c A1F5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e 99F5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 82F5\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 FAED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 E5ED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0026 DDED\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==20] then { pass $testname } else { fail $testname }
+}
+
+proc do_compare {} {
+ set testname "compare.s: compare operations"
+ set x 0
+
+ gas_start "compare.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 6532\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 E02F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 E82F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c E12F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 E12F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0014 E92F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0018 E92F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001c E22F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 EA2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0024 E32F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0028 EB2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 002c E42F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0030 E42F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0034 EC2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0038 EC2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 003c E52F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0040 ED2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0044 E62F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0048 EE2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 004c E72F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0050 EF2F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0054 6531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==23] then { pass $testname } else { fail $testname }
+}
+
+proc do_jumps {} {
+ set testname "jumps.s: jumps operations"
+ set x 0
+
+ gas_start "jumps.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 802F0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 6500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 BF07FAFF\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==3] then { pass $testname } else { fail $testname }
+}
+
+proc do_logical {} {
+ set testname "logical.s: logical operations"
+ set x 0
+
+ gas_start "logical.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 4531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 C5360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0006 2530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 0531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000a 85360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e 2531\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 A5360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==7] then { pass $testname } else { fail $testname }
+}
+
+proc do_mem {} {
+ set testname "mem.s: memory operations"
+ set x 0
+
+ gas_start "mem.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 05370500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 25370400\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 25370500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 4033\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e 4034\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0010 4035\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 462F0500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 662F0400\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a 662F0500\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e C033\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0020 C034\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0022 4135\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==12] then { pass $testname } else { fail $testname }
+}
+
+proc do_misc {} {
+ set testname "misc.s: misc operations"
+ set x 0
+
+ gas_start "misc.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 E0076001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 E0876001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 E0072001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000c 0000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 000e E0074001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0012 E0070001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0016 FF070001\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001a E72F2000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 001e E53F4000\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==9] then { pass $testname } else { fail $testname }
+}
+
+proc do_move {} {
+ set testname "move.s: move operations"
+ set x 0
+
+ gas_start "move.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 0530\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0002 0532\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 25360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 45360700\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==4] then { pass $testname } else { fail $testname }
+}
+
+proc do_hilo {} {
+ set testname "hilo.s: hilo tests"
+ set x 0
+
+ gas_start "hilo.s" "-al"
+
+ # Instead of having a variable for each match string just increment the
+ # total number of matches seen. That's simpler when testing large numbers
+ # of instructions (as these tests to).
+ while 1 {
+ expect {
+ -re "^ +\[0-9\]+ 0000 200EEFBE\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0004 410EAEDE\[^\n\]*\n" { set x [expr $x+1] }
+ -re "^ +\[0-9\]+ 0008 410EADDE\[^\n\]*\n" { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ gas_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==3] then { pass $testname } else { fail $testname }
+}
+
+
+proc do_simple_reloc_tests {} {
+ set testname "reloc.s: Test for proper relocations (part 2)"
+ set x 0
+
+ if [gas_test_old "reloc.s" "" "Test for proper relocation (part 1)"] then {
+ objdump_start_no_subdir "a.out" "-r"
+
+ while 1 {
+ expect {
+ -re "^00000002\[^\n\]*R_V850_LO16\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000006\[^\n\]*R_V850_HI16_S\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000000a\[^\n\]*R_V850_HI16\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^0000000e\[^\n\]*R_V850_ZDA_16_16_OFFSET\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000012\[^\n\]*R_V850_TDA_16_16_OFFSET\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "^00000016\[^\n\]*R_V850_SDA_16_16_OFFSET\[^\n\]*\n"
+ { set x [expr $x+1] }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ }
+
+ # This was intended to do any cleanup necessary. It kinda looks like it
+ # isn't needed, but just in case, please keep it in for now.
+ objdump_finish
+
+ # Did we find what we were looking for? If not, flunk it.
+ if [expr $x==6] then { pass $testname } else { fail $testname }
+}
+
+if [istarget v850*-*-*] then {
+ # Test the basic instruction parser.
+ do_arith
+ do_bit
+ do_branch
+ do_compare
+ do_jumps
+ do_logical
+ do_mem
+ do_misc
+ do_move
+
+ # Make sure we handle lo() hi() and hi0() correctly.
+ do_hilo
+
+ # Check for proper relocs on lo, hi, hi0, zdaoff, tdaoff and sdaoff
+ # expressions
+ do_simple_reloc_tests
+
+ gas_test "hilo2.s" "" "" "hi/lo regression test"
+ gas_test "fepsw.s" "" "" "eqsw regression test"
+
+ gas_test_error "range.s" "-mwarn-signed-overflow" "Check for range error on byte load/store"
+}
diff --git a/gas/testsuite/gas/v850/bit.s b/gas/testsuite/gas/v850/bit.s
new file mode 100644
index 00000000000..aa1ac05d0e6
--- /dev/null
+++ b/gas/testsuite/gas/v850/bit.s
@@ -0,0 +1,8 @@
+
+ .text
+ .global bit
+bit:
+ clr1 5,16[r6]
+ not1 5,16[r6]
+ set1 5,16[r6]
+ tst1 5,16[r6]
diff --git a/gas/testsuite/gas/v850/branch.s b/gas/testsuite/gas/v850/branch.s
new file mode 100644
index 00000000000..a1c1b428048
--- /dev/null
+++ b/gas/testsuite/gas/v850/branch.s
@@ -0,0 +1,24 @@
+
+ .text
+ .global bcc
+bcc:
+ bgt bcc
+ bge bcc
+ blt bcc
+ ble bcc
+ bh bcc
+ bnl bcc
+ bl bcc
+ bnh bcc
+ be bcc
+ bne bcc
+ bv bcc
+ bnv bcc
+ bn bcc
+ bp bcc
+ bc bcc
+ bnc bcc
+ bz bcc
+ bnz bcc
+ br bcc
+ bsa bcc
diff --git a/gas/testsuite/gas/v850/compare.s b/gas/testsuite/gas/v850/compare.s
new file mode 100644
index 00000000000..d41c8a84de5
--- /dev/null
+++ b/gas/testsuite/gas/v850/compare.s
@@ -0,0 +1,28 @@
+
+ .text
+ .global compare
+compare:
+ cmp r5,r6
+ cmp 5,r6
+ setf v,r5
+ setf nv,r5
+ setf c,r5
+ setf l,r5
+ setf nc,r5
+ setf nl,r5
+ setf z,r5
+ setf nz,r5
+ setf nh,r5
+ setf h,r5
+ setf s,r5
+ setf n,r5
+ setf ns,r5
+ setf p,r5
+ setf t,r5
+ setf sa,r5
+ setf lt,r5
+ setf ge,r5
+ setf le,r5
+ setf gt,r5
+ tst r5,r6
+
diff --git a/gas/testsuite/gas/v850/fepsw.s b/gas/testsuite/gas/v850/fepsw.s
new file mode 100644
index 00000000000..e20333cb2ba
--- /dev/null
+++ b/gas/testsuite/gas/v850/fepsw.s
@@ -0,0 +1,2 @@
+ .text
+ ldsr r17,fepsw
diff --git a/gas/testsuite/gas/v850/hilo.s b/gas/testsuite/gas/v850/hilo.s
new file mode 100644
index 00000000000..5067e56de52
--- /dev/null
+++ b/gas/testsuite/gas/v850/hilo.s
@@ -0,0 +1,5 @@
+
+ .text
+ movea lo(0xdeadbeef),r0,r1
+ movhi hi(0xdeadbeef),r1,r1
+ movhi hi0(0xdeadbeef),r1,r1
diff --git a/gas/testsuite/gas/v850/hilo2.s b/gas/testsuite/gas/v850/hilo2.s
new file mode 100644
index 00000000000..661d59347be
--- /dev/null
+++ b/gas/testsuite/gas/v850/hilo2.s
@@ -0,0 +1,4 @@
+ .text
+ .org 0x10000
+ movea hi(blah),r0,r1
+blah:
diff --git a/gas/testsuite/gas/v850/jumps.s b/gas/testsuite/gas/v850/jumps.s
new file mode 100644
index 00000000000..173164b7fb1
--- /dev/null
+++ b/gas/testsuite/gas/v850/jumps.s
@@ -0,0 +1,8 @@
+
+ .text
+ .global jumps
+jumps:
+ jarl jumps,r5
+ jmp [r5]
+ jr jumps
+
diff --git a/gas/testsuite/gas/v850/logical.s b/gas/testsuite/gas/v850/logical.s
new file mode 100644
index 00000000000..ab00b3bcb08
--- /dev/null
+++ b/gas/testsuite/gas/v850/logical.s
@@ -0,0 +1,11 @@
+
+ .text
+ .global logicals
+logicals:
+ and r5,r6
+ andi 7,r5,r6
+ not r5,r6
+ or r5,r6
+ ori 7,r5,r6
+ xor r5,r6
+ xori 7,r5,r6
diff --git a/gas/testsuite/gas/v850/mem.s b/gas/testsuite/gas/v850/mem.s
new file mode 100644
index 00000000000..9c69cea2784
--- /dev/null
+++ b/gas/testsuite/gas/v850/mem.s
@@ -0,0 +1,16 @@
+
+ .text
+ .global memory
+memory:
+ ld.b 5[r5],r6
+ ld.h 4[r5],r6
+ ld.w 4[r5],r6
+ sld.b 64[ep],r6
+ sld.h 128[ep],r6
+ sld.w 128[ep],r6
+ st.b r5,5[r6]
+ st.h r5,4[r6]
+ st.w r5,4[r6]
+ sst.b r6,64[ep]
+ sst.h r6,128[ep]
+ sst.w r6,128[ep]
diff --git a/gas/testsuite/gas/v850/misc.s b/gas/testsuite/gas/v850/misc.s
new file mode 100644
index 00000000000..52c4e4bbe4b
--- /dev/null
+++ b/gas/testsuite/gas/v850/misc.s
@@ -0,0 +1,13 @@
+
+ .text
+ .global misc
+misc:
+ di
+ ei
+ halt
+ nop
+ reti
+ trap 0
+ trap 31
+ ldsr r7,psw
+ stsr psw,r7
diff --git a/gas/testsuite/gas/v850/move.s b/gas/testsuite/gas/v850/move.s
new file mode 100644
index 00000000000..cba6fae970a
--- /dev/null
+++ b/gas/testsuite/gas/v850/move.s
@@ -0,0 +1,8 @@
+
+ .text
+ .global move
+move:
+ mov r5,r6
+ mov 5,r6
+ movea 7,r5,r6
+ movhi 7,r5,r6
diff --git a/gas/testsuite/gas/v850/range.s b/gas/testsuite/gas/v850/range.s
new file mode 100644
index 00000000000..42accf47792
--- /dev/null
+++ b/gas/testsuite/gas/v850/range.s
@@ -0,0 +1,2 @@
+ .text
+ ld.b 0xff62[r0],r0
diff --git a/gas/testsuite/gas/v850/reloc.s b/gas/testsuite/gas/v850/reloc.s
new file mode 100644
index 00000000000..6738d26dd99
--- /dev/null
+++ b/gas/testsuite/gas/v850/reloc.s
@@ -0,0 +1,7 @@
+ .text
+ movea lo(foo),r0,r1
+ movhi hi(foo),r1,r1
+ movhi hi0(foo),r1,r1
+ movea zdaoff(_foo),r0,r1
+ movhi tdaoff(_foo),ep,r1
+ movhi sdaoff(_foo),gp,r1
diff --git a/gas/testsuite/gas/vax/quad.exp b/gas/testsuite/gas/vax/quad.exp
new file mode 100644
index 00000000000..34770c5b6cf
--- /dev/null
+++ b/gas/testsuite/gas/vax/quad.exp
@@ -0,0 +1,23 @@
+proc do_quad {} {
+ set testname "quad.s: quadword immediate values"
+ set x1 0
+ set x2 0
+ set x3 0
+ gas_start "quad.s" "-al"
+ while 1 {
+ expect {
+ -re "^ +2\[ \t\]+0000+ 7D8F7856\[ \t\]+movq\[^\n\]*\n" { set x1 1 }
+ -re "^ +2\[ \t\]+3412DDCC\[^\n\]*\n" { set x2 1 }
+ -re "^ +2\[ \t\]+BBAA5001\[ \t\]*\r\n" { set x3 1 }
+ -re "\[^\n\]*\n" { }
+ timeout { perror "timeout\n"; break }
+ eof { break }
+ }
+ }
+ gas_finish
+ if [all_ones $x1 $x2 $x3] then { pass $testname } else { fail $testname }
+}
+
+if [istarget vax-*-*] then {
+ do_quad
+}
diff --git a/gas/testsuite/gas/vax/quad.s b/gas/testsuite/gas/vax/quad.s
new file mode 100644
index 00000000000..78ad4ad0fc6
--- /dev/null
+++ b/gas/testsuite/gas/vax/quad.s
@@ -0,0 +1,2 @@
+ .text
+ movq $0xaabbccdd12345678,r0
diff --git a/gas/testsuite/gas/vtable/entry0.d b/gas/testsuite/gas/vtable/entry0.d
new file mode 100644
index 00000000000..ee0bb990276
--- /dev/null
+++ b/gas/testsuite/gas/vtable/entry0.d
@@ -0,0 +1,10 @@
+#objdump: -r
+#name: vtable entry0
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR \[.text\]:
+OFFSET +TYPE +VALUE
+0+0000010 R_.*_GNU_VTENTRY vtbl_a
+
+
diff --git a/gas/testsuite/gas/vtable/entry0.s b/gas/testsuite/gas/vtable/entry0.s
new file mode 100644
index 00000000000..36f89e38949
--- /dev/null
+++ b/gas/testsuite/gas/vtable/entry0.s
@@ -0,0 +1,2 @@
+.text
+.vtable_entry vtbl_a, 16
diff --git a/gas/testsuite/gas/vtable/entry1.d b/gas/testsuite/gas/vtable/entry1.d
new file mode 100644
index 00000000000..7fa6e4b743d
--- /dev/null
+++ b/gas/testsuite/gas/vtable/entry1.d
@@ -0,0 +1,10 @@
+#objdump: -r
+#name: vtable entry1
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR \[.text\]:
+OFFSET +TYPE +VALUE
+0+0000000 R_.*_GNU_VTENTRY vtbl_a.*
+
+
diff --git a/gas/testsuite/gas/vtable/entry1.s b/gas/testsuite/gas/vtable/entry1.s
new file mode 100644
index 00000000000..36f89e38949
--- /dev/null
+++ b/gas/testsuite/gas/vtable/entry1.s
@@ -0,0 +1,2 @@
+.text
+.vtable_entry vtbl_a, 16
diff --git a/gas/testsuite/gas/vtable/inherit0.d b/gas/testsuite/gas/vtable/inherit0.d
new file mode 100644
index 00000000000..62795b1ac1e
--- /dev/null
+++ b/gas/testsuite/gas/vtable/inherit0.d
@@ -0,0 +1,10 @@
+#objdump: -r
+#name: vtable inherit0
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR \[.data\]:
+OFFSET +TYPE +VALUE
+0+0000000 R_.*_GNU_VTINHERIT \*ABS\*
+0+0000010 R_.*_GNU_VTINHERIT vtbl_a
+
diff --git a/gas/testsuite/gas/vtable/inherit0.s b/gas/testsuite/gas/vtable/inherit0.s
new file mode 100644
index 00000000000..d438df6954f
--- /dev/null
+++ b/gas/testsuite/gas/vtable/inherit0.s
@@ -0,0 +1,13 @@
+.data
+
+.type vtbl_a,object
+vtbl_a:
+ .space 16
+.size vtbl_a,16
+.vtable_inherit vtbl_a, 0
+
+.type vtbl_b,object
+vtbl_b:
+ .space 16
+.size vtbl_b,16
+.vtable_inherit vtbl_b, vtbl_a
diff --git a/gas/testsuite/gas/vtable/inherit1.l b/gas/testsuite/gas/vtable/inherit1.l
new file mode 100644
index 00000000000..bdd63583458
--- /dev/null
+++ b/gas/testsuite/gas/vtable/inherit1.l
@@ -0,0 +1,6 @@
+.*: Assembler messages:
+.*:1: Error: expected `vtbl_a' to have already been set for .vtable_inherit
+.*GAS.*
+
+
+ +1.*vtable_inherit vtbl_a, 0
diff --git a/gas/testsuite/gas/vtable/inherit1.s b/gas/testsuite/gas/vtable/inherit1.s
new file mode 100644
index 00000000000..7dd1d2877b7
--- /dev/null
+++ b/gas/testsuite/gas/vtable/inherit1.s
@@ -0,0 +1 @@
+.vtable_inherit vtbl_a, 0
diff --git a/gas/testsuite/gas/vtable/vtable.exp b/gas/testsuite/gas/vtable/vtable.exp
new file mode 100644
index 00000000000..5d144515247
--- /dev/null
+++ b/gas/testsuite/gas/vtable/vtable.exp
@@ -0,0 +1,39 @@
+#
+# vtable tests
+#
+proc run_list_test { name opts } {
+ global srcdir subdir
+ set testname "vtable $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s $opts ">&dump.out"
+ if { [regexp_diff "dump.out" "${file}.l"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+}
+
+# Vtable bits are only supported by ELF targets.
+if {[istarget "*-*-elf*"] || [istarget "*-*-linux*"]} then {
+
+
+ # not supported by D30V
+ if {[istarget "d30v-*-*"]} {
+ return
+ }
+
+ run_dump_test "inherit0"
+ run_list_test "inherit1" "-al"
+
+ # The vtable entry results are different on Rel and Rela targets.
+ if {[istarget "i*86-*-*"] || [istarget "mips*-*-*"]} then {
+
+ run_dump_test "entry0"
+
+ } else {
+
+ run_dump_test "entry1"
+
+ }
+}
diff --git a/gas/testsuite/gasp/INC1.H b/gas/testsuite/gasp/INC1.H
new file mode 100644
index 00000000000..0d3732310f4
--- /dev/null
+++ b/gas/testsuite/gasp/INC1.H
@@ -0,0 +1,3 @@
+FILE 1 FIRST LINE
+ .INCLUDE "INC2.H"
+FILE 1 LAST LINE
diff --git a/gas/testsuite/gasp/INC2.H b/gas/testsuite/gasp/INC2.H
new file mode 100644
index 00000000000..083c3dce2c7
--- /dev/null
+++ b/gas/testsuite/gasp/INC2.H
@@ -0,0 +1,2 @@
+ FILE 2 FIRST LINE
+ FILE 2 LAST LINE
diff --git a/gas/testsuite/gasp/assign.asm b/gas/testsuite/gasp/assign.asm
new file mode 100644
index 00000000000..7f66718468d
--- /dev/null
+++ b/gas/testsuite/gasp/assign.asm
@@ -0,0 +1,13 @@
+
+foo: .ASSIGNC "hello"
+BAR: .ASSIGNA 12+34
+
+ \&foo'foo
+ \&foo\&foo\&foo
+ \&foo \&foo \&foo
+ \&BAR\&bar\&BAR
+
+
+
+
+ .END
diff --git a/gas/testsuite/gasp/assign.err b/gas/testsuite/gasp/assign.err
new file mode 100644
index 00000000000..fe3733f7eab
--- /dev/null
+++ b/gas/testsuite/gasp/assign.err
@@ -0,0 +1 @@
+assign.asm:8 Can't find preprocessor variable bar.
diff --git a/gas/testsuite/gasp/assign.out b/gas/testsuite/gasp/assign.out
new file mode 100644
index 00000000000..85509ae614f
--- /dev/null
+++ b/gas/testsuite/gasp/assign.out
@@ -0,0 +1,22 @@
+!
+
+!foo: .ASSIGNC "hello"
+!BAR: .ASSIGNA 12+34
+!
+
+! \&foo'foo
+ hellofoo
+! \&foo\&foo\&foo
+ hellohellohello
+! \&foo \&foo \&foo
+ hello hello hello
+! \&BAR\&bar\&BAR
+ 4646
+!
+
+!
+
+!
+
+!
+! .END
diff --git a/gas/testsuite/gasp/condass.asm b/gas/testsuite/gasp/condass.asm
new file mode 100644
index 00000000000..2bd9f0732fb
--- /dev/null
+++ b/gas/testsuite/gasp/condass.asm
@@ -0,0 +1,129 @@
+ .AIF 1 EQ 1
+ OK
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 2
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ .AIF 1 EQ 2
+ BAD
+ .AELSE
+ OK
+ .AIF 1 EQ 2
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ .AENDI
+ .AIF 1 LT 2
+ OK
+ .AENDI
+ .AIF 1 EQ 2
+ BAD
+ .AENDI
+ .AIF 1 NE 2
+ OK
+ .AENDI
+ .AIF 1 LE 2
+ OK
+ .AENDI
+ .AIF 1 GT 2
+ BAD
+ .AENDI
+ .AIF 3 GE 2
+ OK
+ .AENDI
+ .AIF 3 LT 2
+ BAD
+ .AENDI
+ .AIF 3 EQ 2
+ BAD
+ .AENDI
+ .AIF 3 NE 2
+ OK
+ .AENDI
+ .AIF 3 LE 2
+ BAD
+ .AENDI
+ .AIF 3 GT 2
+ OK
+ .AENDI
+ .AIF 3 GE 2
+ OK
+ .AENDI
+ .AIF "FOO" EQ "BAR"
+ BAD
+ .AENDI
+ .AIF "FOO" EQ "FOO"
+ OK
+ .AENDI
+ .AIF "FOO" NE "BAR"
+ OK
+ .AENDI
+ .AIF "FOO" EQ "FOO"
+ OK
+ .AENDI
+ .AIF 1 EQ 1
+ .AIF 1 EQ 1
+ OK
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 0
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ OK
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 0
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ .AIF 1 EQ 1
+ OK
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 0
+ BAD
+ .AELSE
+ .AIF 1 EQ 1
+ OK
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 0
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ OK
+ .AENDI
+ .AIF 1 EQ 1
+ OK
+ .AIF 1 EQ 1
+ OK
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 0
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ .AELSE
+ BAD
+ .AENDI
+ .AIF 1 EQ 0
+ BAD
+ .AELSE
+ OK
+ .AENDI
+ .END
diff --git a/gas/testsuite/gasp/condass.err b/gas/testsuite/gasp/condass.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/condass.err
diff --git a/gas/testsuite/gasp/condass.out b/gas/testsuite/gasp/condass.out
new file mode 100644
index 00000000000..115cef5be87
--- /dev/null
+++ b/gas/testsuite/gasp/condass.out
@@ -0,0 +1,155 @@
+! .AIF 1 EQ 1
+! OK
+ OK
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 2
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! .AIF 1 EQ 2
+! BAD
+! .AELSE
+! OK
+ OK
+! .AIF 1 EQ 2
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! .AENDI
+! .AIF 1 LT 2
+! OK
+ OK
+! .AENDI
+! .AIF 1 EQ 2
+! BAD
+! .AENDI
+! .AIF 1 NE 2
+! OK
+ OK
+! .AENDI
+! .AIF 1 LE 2
+! OK
+ OK
+! .AENDI
+! .AIF 1 GT 2
+! BAD
+! .AENDI
+! .AIF 3 GE 2
+! OK
+ OK
+! .AENDI
+! .AIF 3 LT 2
+! BAD
+! .AENDI
+! .AIF 3 EQ 2
+! BAD
+! .AENDI
+! .AIF 3 NE 2
+! OK
+ OK
+! .AENDI
+! .AIF 3 LE 2
+! BAD
+! .AENDI
+! .AIF 3 GT 2
+! OK
+ OK
+! .AENDI
+! .AIF 3 GE 2
+! OK
+ OK
+! .AENDI
+! .AIF "FOO" EQ "BAR"
+! BAD
+! .AENDI
+! .AIF "FOO" EQ "FOO"
+! OK
+ OK
+! .AENDI
+! .AIF "FOO" NE "BAR"
+! OK
+ OK
+! .AENDI
+! .AIF "FOO" EQ "FOO"
+! OK
+ OK
+! .AENDI
+! .AIF 1 EQ 1
+! .AIF 1 EQ 1
+! OK
+ OK
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 0
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! OK
+ OK
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 0
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! .AIF 1 EQ 1
+! OK
+ OK
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 0
+! BAD
+! .AELSE
+! .AIF 1 EQ 1
+! OK
+ OK
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 0
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! OK
+ OK
+! .AENDI
+! .AIF 1 EQ 1
+! OK
+ OK
+! .AIF 1 EQ 1
+! OK
+ OK
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 0
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! .AELSE
+! BAD
+! .AENDI
+! .AIF 1 EQ 0
+! BAD
+! .AELSE
+! OK
+ OK
+! .AENDI
+! .END
diff --git a/gas/testsuite/gasp/crash.asm b/gas/testsuite/gasp/crash.asm
new file mode 100644
index 00000000000..a710cc548d0
--- /dev/null
+++ b/gas/testsuite/gasp/crash.asm
@@ -0,0 +1,22 @@
+
+ Stuff to try and crash it
+
+foo: .MACRO
+ HI
+bar: .MACRO
+ THERE
+ bar
+ .ENDM
+
+
+ .ENDM
+ foo
+ foo
+ foo
+ foo
+ foo
+ bar
+
+
+
+
diff --git a/gas/testsuite/gasp/crash.err b/gas/testsuite/gasp/crash.err
new file mode 100644
index 00000000000..1008802107a
--- /dev/null
+++ b/gas/testsuite/gasp/crash.err
@@ -0,0 +1 @@
+crash.asm:18 Unreasonable expansion (-u turns off check).
diff --git a/gas/testsuite/gasp/crash.out b/gas/testsuite/gasp/crash.out
new file mode 100644
index 00000000000..6b948a3d9d4
--- /dev/null
+++ b/gas/testsuite/gasp/crash.out
@@ -0,0 +1,3059 @@
+!
+
+! Stuff to try and crash it
+ Stuff to try and crash it
+!
+
+!foo: .MACRO
+! HI
+!bar: .MACRO
+! THERE
+! bar
+! .ENDM
+!
+!
+! .ENDM
+! foo
+! HI
+ HI
+!bar: .MACRO
+! THERE
+! bar
+! .ENDM
+!
+
+!
+
+! foo
+! HI
+ HI
+!bar: .MACRO
+! THERE
+! bar
+! .ENDM
+!
+
+!
+
+! foo
+! HI
+ HI
+!bar: .MACRO
+! THERE
+! bar
+! .ENDM
+!
+
+!
+
+! foo
+! HI
+ HI
+!bar: .MACRO
+! THERE
+! bar
+! .ENDM
+!
+
+!
+
+! foo
+! HI
+ HI
+!bar: .MACRO
+! THERE
+! bar
+! .ENDM
+!
+
+!
+
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
+! THERE
+ THERE
+! bar
diff --git a/gas/testsuite/gasp/crash1.asm b/gas/testsuite/gasp/crash1.asm
new file mode 100644
index 00000000000..d2b6b3082e6
--- /dev/null
+++ b/gas/testsuite/gasp/crash1.asm
@@ -0,0 +1,13 @@
+
+
+ .MACRO foo a b c=a
+ \a \b \c \d
+ .ENDM
+
+ foo 1 2
+ foo 1 2 3 4
+ foo 1
+ foo
+
+
+ .END
diff --git a/gas/testsuite/gasp/crash1.err b/gas/testsuite/gasp/crash1.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/crash1.err
diff --git a/gas/testsuite/gasp/crash1.out b/gas/testsuite/gasp/crash1.out
new file mode 100644
index 00000000000..725d078e3c8
--- /dev/null
+++ b/gas/testsuite/gasp/crash1.out
@@ -0,0 +1,24 @@
+!
+
+!
+
+! .MACRO foo a b c=a
+! \a \b \c \d
+! .ENDM
+!
+
+! foo 1 2
+! 1 2 a \d
+ 1 2 a \d
+! foo 1 2 3 4
+! foo 1
+! 1 a \d
+ 1 a \d
+! foo
+! a \d
+ a \d
+!
+
+!
+
+! .END
diff --git a/gas/testsuite/gasp/crash2.asm b/gas/testsuite/gasp/crash2.asm
new file mode 100644
index 00000000000..288a003d9f9
--- /dev/null
+++ b/gas/testsuite/gasp/crash2.asm
@@ -0,0 +1,41 @@
+
+foo: .ASSIGNA 1
+ \&foo+1
+ \&foo+1
+foo: .ASSIGNC "foo"
+ \&foo+1
+ \&foo+1
+
+foo: .ASSIGNA 1
+ \&foo+1
+ \&foo+1
+foo: .ASSIGNC "foo"
+ \&foo+1
+ \&foo+1
+
+foo: .ASSIGNA 1
+ \&foo+1
+ \&foo+1
+foo: .ASSIGNC "foo"
+ \&foo+1
+ \&foo+1
+
+foo: .ASSIGNA 1
+ \&foo+1
+ \&foo+1
+foo: .ASSIGNC "foo"
+ \&foo+1
+ \&foo+1
+
+foo: .ASSIGNA 1
+ \&foo+1
+ \&foo+1
+foo: .ASSIGNC "foo"
+ \&foo+1
+ \&foo+1
+ foo
+ foo foo
+ foo foo
+ foo
+ .END
+
diff --git a/gas/testsuite/gasp/crash2.err b/gas/testsuite/gasp/crash2.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/crash2.err
diff --git a/gas/testsuite/gasp/crash2.out b/gas/testsuite/gasp/crash2.out
new file mode 100644
index 00000000000..0d1a2f7e4a3
--- /dev/null
+++ b/gas/testsuite/gasp/crash2.out
@@ -0,0 +1,69 @@
+!
+
+!foo: .ASSIGNA 1
+! \&foo+1
+ 1+1
+! \&foo+1
+ 1+1
+!foo: .ASSIGNC "foo"
+! \&foo+1
+ foo+1
+! \&foo+1
+ foo+1
+!
+
+!foo: .ASSIGNA 1
+! \&foo+1
+ 1+1
+! \&foo+1
+ 1+1
+!foo: .ASSIGNC "foo"
+! \&foo+1
+ foo+1
+! \&foo+1
+ foo+1
+!
+
+!foo: .ASSIGNA 1
+! \&foo+1
+ 1+1
+! \&foo+1
+ 1+1
+!foo: .ASSIGNC "foo"
+! \&foo+1
+ foo+1
+! \&foo+1
+ foo+1
+!
+
+!foo: .ASSIGNA 1
+! \&foo+1
+ 1+1
+! \&foo+1
+ 1+1
+!foo: .ASSIGNC "foo"
+! \&foo+1
+ foo+1
+! \&foo+1
+ foo+1
+!
+
+!foo: .ASSIGNA 1
+! \&foo+1
+ 1+1
+! \&foo+1
+ 1+1
+!foo: .ASSIGNC "foo"
+! \&foo+1
+ foo+1
+! \&foo+1
+ foo+1
+! foo
+ foo
+! foo foo
+ foo foo
+! foo foo
+ foo foo
+! foo
+ foo
+! .END
diff --git a/gas/testsuite/gasp/data.asm b/gas/testsuite/gasp/data.asm
new file mode 100644
index 00000000000..ba6b0a046f8
--- /dev/null
+++ b/gas/testsuite/gasp/data.asm
@@ -0,0 +1,23 @@
+
+foo .DATA 1,2,3
+bar .DATA 1,2,3,4,5 ,6
+ .DATA.B 12345,12,2
+ .DATA.W 9,2,12,3,13+41,foo+9
+ .DATA.L 2~99
+
+
+
+ .DATAB 1,2,3
+ .DATAB 1,2,3
+
+
+
+
+ .DATAB 1,9+32
+
+ .DATAB.L 1,H'11111111
+ .DATAB.W 2,H'2222
+ .DATAB.B 3,H'333
+
+
+ .END
diff --git a/gas/testsuite/gasp/data.err b/gas/testsuite/gasp/data.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/data.err
diff --git a/gas/testsuite/gasp/data.out b/gas/testsuite/gasp/data.out
new file mode 100644
index 00000000000..e96e1e58caa
--- /dev/null
+++ b/gas/testsuite/gasp/data.out
@@ -0,0 +1,45 @@
+!
+
+!foo .DATA 1,2,3
+foo: .long 1,2,3
+!bar .DATA 1,2,3,4,5 ,6
+bar: .long 1,2,3,4,5,6
+! .DATA.B 12345,12,2
+ .byte 12345,12,2
+! .DATA.W 9,2,12,3,13+41,foo+9
+ .short 9,2,12,3,54,foo+9
+! .DATA.L 2~99
+ .long 97
+!
+
+!
+
+!
+
+! .DATAB 1,2,3
+ .fill 1,4,2
+! .DATAB 1,2,3
+ .fill 1,4,2
+!
+
+!
+
+!
+
+!
+
+! .DATAB 1,9+32
+ .fill 1,4,41
+!
+
+! .DATAB.L 1,H'11111111
+ .fill 1,4,286331153
+! .DATAB.W 2,H'2222
+ .fill 2,2,8738
+! .DATAB.B 3,H'333
+ .fill 3,1,819
+!
+
+!
+
+! .END
diff --git a/gas/testsuite/gasp/exp.asm b/gas/testsuite/gasp/exp.asm
new file mode 100644
index 00000000000..041608a818e
--- /dev/null
+++ b/gas/testsuite/gasp/exp.asm
@@ -0,0 +1,80 @@
+
+; test all ops
+
+a1 .EQU 4+10
+a2 .EQU 4-10
+a3 .EQU 4&10
+a4 .EQU 4|2
+a5 .EQU 4~2
+a6 .EQU 4*10
+a7 .EQU 40/10
+a8 .EQU +7
+a9 .EQU -7
+a10 .EQU ~7
+
+
+ a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
+
+; test the priorities
+
+b1 .EQU 1|2~3&4+5-8*7/2
+b2 .EQU (1|2~(3&(4+5-(8*(7/2)))))
+b3 .EQU 10*2/3*4
+b4 .EQU (((10*2)/3)*4)
+b5 .EQU 10+2-3+4
+b6 .EQU (((10+2)-3)+4)
+
+ b1 b2 b3 b4
+
+; test association
+
+c1 .EQU -~3
+c2 .EQU ~-3
+c3 .EQU -(~3)
+c4 .EQU ~(-3)
+
+ c1 c2 c3 c4
+
+; test rules for symbols
+
+ok1 .EQU FOO
+ok2 .EQU FOO+10
+ok3 .EQU 10+FOO
+ok4 .EQU FOO-10
+
+ ok1
+ ok2
+ ok3
+ ok4
+
+ok5 .EQU FOO+3+4+5+6
+ok6 .EQU FOO-BAR
+
+ ok5
+ ok6
+
+bad1 .EQU FOO+FOO
+bad2 .EQU FOO*2
+bad3 .EQU FOO/2
+bad4 .EQU FOO|2
+bad5 .EQU FOO&2
+bad6 .EQU FOO~2
+bad7 .EQU FOO*2
+
+; test spacing
+
+space1 .EQU 1 + 2 +3+FOO + 3
+space2
+
+; from the SH manual
+
+ .DATA.L 1+(2-(3+(4-5))),1
+
+ .DATA.L -H'fffffff1+H'000000f0*H'00000010|H'000000f0&H'0000ffff,H'00000fff
+
+ .DATA.L -~-~H'0000000f,H'00
+
+
+
+
+ .END
diff --git a/gas/testsuite/gasp/exp.err b/gas/testsuite/gasp/exp.err
new file mode 100644
index 00000000000..f41fd528048
--- /dev/null
+++ b/gas/testsuite/gasp/exp.err
@@ -0,0 +1,7 @@
+exp.asm:56 can't add two relocatable expressions
+exp.asm:57 the * operator cannot take non-absolute arguments.
+exp.asm:58 the / operator cannot take non-absolute arguments.
+exp.asm:59 the | operator cannot take non-absolute arguments.
+exp.asm:60 the & operator cannot take non-absolute arguments.
+exp.asm:61 the ~ operator cannot take non-absolute arguments.
+exp.asm:62 the * operator cannot take non-absolute arguments.
diff --git a/gas/testsuite/gasp/exp.out b/gas/testsuite/gasp/exp.out
new file mode 100644
index 00000000000..cecb9a881e3
--- /dev/null
+++ b/gas/testsuite/gasp/exp.out
@@ -0,0 +1,124 @@
+!
+
+!; test all ops
+ ; test all ops
+!
+
+!a1 .EQU 4+10
+!a2 .EQU 4-10
+!a3 .EQU 4&10
+!a4 .EQU 4|2
+!a5 .EQU 4~2
+!a6 .EQU 4*10
+!a7 .EQU 40/10
+!a8 .EQU +7
+!a9 .EQU -7
+!a10 .EQU ~7
+!
+
+!
+
+! a1 a2 a3 a4 a5 a6 a7 a8 a9 a10
+ 14 -6 0 6 6 40 4 7 -7 -8
+!
+
+!; test the priorities
+ ; test the priorities
+!
+
+!b1 .EQU 1|2~3&4+5-8*7/2
+!b2 .EQU (1|2~(3&(4+5-(8*(7/2)))))
+!b3 .EQU 10*2/3*4
+!b4 .EQU (((10*2)/3)*4)
+!b5 .EQU 10+2-3+4
+!b6 .EQU (((10+2)-3)+4)
+!
+
+! b1 b2 b3 b4
+ 2 2 24 24
+!
+
+!; test association
+ ; test association
+!
+
+!c1 .EQU -~3
+!c2 .EQU ~-3
+!c3 .EQU -(~3)
+!c4 .EQU ~(-3)
+!
+
+! c1 c2 c3 c4
+ 4 2 4 2
+!
+
+!; test rules for symbols
+ ; test rules for symbols
+!
+
+!ok1 .EQU FOO
+!ok2 .EQU FOO+10
+!ok3 .EQU 10+FOO
+!ok4 .EQU FOO-10
+!
+
+! ok1
+ FOO
+! ok2
+ FOO+10
+! ok3
+ FOO+10
+! ok4
+ FOO+-10
+!
+
+!ok5 .EQU FOO+3+4+5+6
+!ok6 .EQU FOO-BAR
+!
+
+! ok5
+ FOO+18
+! ok6
+ FOO-FOO
+!
+
+!bad1 .EQU FOO+FOO
+!bad2 .EQU FOO*2
+!bad3 .EQU FOO/2
+!bad4 .EQU FOO|2
+!bad5 .EQU FOO&2
+!bad6 .EQU FOO~2
+!bad7 .EQU FOO*2
+!
+
+!; test spacing
+ ; test spacing
+!
+
+!space1 .EQU 1 + 2 +3+FOO + 3
+!space2
+space2:
+!
+
+!; from the SH manual
+ ; from the SH manual
+!
+
+! .DATA.L 1+(2-(3+(4-5))),1
+ .long 1,1
+!
+
+! .DATA.L -H'fffffff1+H'000000f0*H'00000010|H'000000f0&H'0000ffff,H'00000fff
+ .long 4095,4095
+!
+
+! .DATA.L -~-~H'0000000f,H'00
+ .long 17,0
+!
+
+!
+
+!
+!
+
+! .END
diff --git a/gas/testsuite/gasp/gasp.exp b/gas/testsuite/gasp/gasp.exp
new file mode 100644
index 00000000000..2a72a6d3591
--- /dev/null
+++ b/gas/testsuite/gasp/gasp.exp
@@ -0,0 +1,40 @@
+# Test gasp.
+
+proc gasp_test { filename testname opt } {
+ global GASP
+ global srcdir
+ global host_triplet
+
+ send_log "$srcdir/lib/run $GASP -I$srcdir/gasp -s $opt $filename.asm -o gasp.out\n"
+ catch "exec $srcdir/lib/run $GASP -I$srcdir/gasp -s $opt $filename.asm -o gasp.out" errs
+ catch "exec diff gasp.out $filename.out" diffs
+ set diffs [prune_warnings $diffs]
+ if ![string match "" $diffs] {
+ send_log "$diffs\n"
+ verbose $diffs
+ fail $testname
+ return 0
+ } else {
+ pass $testname
+ }
+
+}
+
+foreach src [ lsort [ glob $srcdir/gasp/*.asm ] ] {
+ regsub -all ".asm" $src "" t
+ regsub "^.*/(\[^/\]*)$" $t "gasp \\1" testname
+ gasp_test $t $testname ""
+}
+
+foreach src [ lsort [ glob $srcdir/gasp/mri/*.asm ] ] {
+ regsub -all ".asm" $src "" t
+ regsub "^.*/(\[^/\]*)$" $t "gasp MRI \\1" testname
+ gasp_test $t $testname "-M"
+}
+
+# FIXME: this is here cause of a bug in DejaGnu 1.1.1. When it is no longer
+# in use, then this can be removed.
+if [info exists errorInfo] then {
+ unset errorInfo
+}
+
diff --git a/gas/testsuite/gasp/include.asm b/gas/testsuite/gasp/include.asm
new file mode 100644
index 00000000000..69ed1dd5e88
--- /dev/null
+++ b/gas/testsuite/gasp/include.asm
@@ -0,0 +1,4 @@
+ HI
+ .INCLUDE "INC1.H"
+ THERE
+ .END
diff --git a/gas/testsuite/gasp/include.err b/gas/testsuite/gasp/include.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/include.err
diff --git a/gas/testsuite/gasp/include.out b/gas/testsuite/gasp/include.out
new file mode 100644
index 00000000000..d77a0df74fe
--- /dev/null
+++ b/gas/testsuite/gasp/include.out
@@ -0,0 +1,15 @@
+! HI
+ HI
+! .INCLUDE "INC1.H"
+!FILE 1 FIRST LINE
+FILE: 1 FIRST LINE
+! .INCLUDE "INC2.H"
+! FILE 2 FIRST LINE
+ FILE 2 FIRST LINE
+! FILE 2 LAST LINE
+ FILE 2 LAST LINE
+!FILE 1 LAST LINE
+FILE: 1 LAST LINE
+! THERE
+ THERE
+! .END
diff --git a/gas/testsuite/gasp/listing.asm b/gas/testsuite/gasp/listing.asm
new file mode 100644
index 00000000000..2f14cfc5844
--- /dev/null
+++ b/gas/testsuite/gasp/listing.asm
@@ -0,0 +1,15 @@
+
+
+ .HEADING " ""QUOTE"" "
+ .PAGE
+ .PRINT LIST
+ foo
+ .PRINT NOLIST
+ foo
+
+
+ .FORM LIN=12
+ .FORM COL=90
+ .FORM LIN=123 COL=23
+
+ .END
diff --git a/gas/testsuite/gasp/listing.err b/gas/testsuite/gasp/listing.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/listing.err
diff --git a/gas/testsuite/gasp/listing.out b/gas/testsuite/gasp/listing.out
new file mode 100644
index 00000000000..585bda27283
--- /dev/null
+++ b/gas/testsuite/gasp/listing.out
@@ -0,0 +1,28 @@
+!
+
+!
+
+! .HEADING " ""QUOTE"" "
+ .title " "QUOTE" "
+! .PAGE
+ .eject
+! .PRINT LIST
+ .list
+! foo
+ foo
+! .PRINT NOLIST
+ .nolist
+! foo
+ foo
+!
+
+!
+
+! .FORM LIN=12
+ .psize 12,132
+! .FORM COL=90
+ .psize 60,90
+! .FORM LIN=123 COL=23
+ .psize 123,23
+!
+! .END
diff --git a/gas/testsuite/gasp/macro.asm b/gas/testsuite/gasp/macro.asm
new file mode 100644
index 00000000000..dfb16bff296
--- /dev/null
+++ b/gas/testsuite/gasp/macro.asm
@@ -0,0 +1,102 @@
+ .MACRO SUM FROM=0, TO=9
+ ; \FROM \TO
+ MOV R\FROM,R10
+COUNT .ASSIGNA \FROM+1
+ .AWHILE \&COUNT LE \TO
+ MOV R\&COUNT,R10
+COUNT .ASSIGNA \&COUNT+1
+ .AENDW
+ .ENDM
+
+ SUM 0,5
+ SUM TO=5
+ SUM FROM=2, TO=5
+
+
+; hi this is a comment
+ .MACRO BACK_SLASH_SET
+ \(MOV #"\",R0)
+ .ENDM
+ BACK_SLASH_SET
+ .MACRO COMM
+ bar ; this comment will get copied out
+ foo \; this one will get dropped
+ .ENDM
+ COMM
+ BACK_SLASH_SET
+ .MACRO PLUS2
+ ADD #1,R\&V1
+ .SDATA "\&V'1"
+ .ENDM
+V .ASSIGNC "R"
+V1 .ASSIGNA 1
+ PLUS2
+ .MACRO PLUS1 P,P1
+ ADD #1,\P1
+ .SDATA "\P'1"
+ .ENDM
+ PLUS1 R,R1
+
+ .MACRO SUM P1
+ MOV R0,R10
+ ADD R1,R10
+ ADD R2,R10
+ \P1
+ ADD R3,R10
+ .ENDM
+
+ SUM .EXITM
+
+ .MACRO foo bar=a default=b
+ \bar
+ \default
+ bar
+ default
+ .ENDM
+ foo default=dog bar=cat
+ foo X Y
+ foo
+ foo bar=cat default=dog
+
+
+ .MACRO foo bar
+ HI
+ HI \bar
+ HI
+ .ENDM
+
+ foo 1
+ foo 123
+ foo 1 2 3 4
+ foo
+
+
+ .MACRO PUSH Rn
+ MOV.L \Rn,@-r15
+ .ENDM
+ PUSH R0
+ PUSH R1
+
+
+ .MACRO RES_STR STR, Rn
+ MOV.L #str\@,\Rn
+ BRA end_str\@
+ NOP
+str\@ .SDATA "\STR"
+ .ALIGN 2
+end_str\@
+ .ENDM
+
+ RES_STR "ONE",R0
+ RES_STR "TWO",R1
+ RES_STR "THREE",R2
+
+
+
+ RES_STR STR=donkey Rn=R1
+ RES_STR donkey,R1
+ RES_STR donkey Rn=R1
+ .END
+
+
+
diff --git a/gas/testsuite/gasp/macro.err b/gas/testsuite/gasp/macro.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/macro.err
diff --git a/gas/testsuite/gasp/macro.out b/gas/testsuite/gasp/macro.out
new file mode 100644
index 00000000000..0740732c7c2
--- /dev/null
+++ b/gas/testsuite/gasp/macro.out
@@ -0,0 +1,382 @@
+! .MACRO SUM FROM=0, TO=9
+! ; \FROM \TO
+! MOV R\FROM,R10
+!COUNT .ASSIGNA \FROM+1
+! .AWHILE \&COUNT LE \TO
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! .ENDM
+!
+
+! SUM 0,5
+! ; 0 5
+ ; 0 5
+! MOV R0,R10
+ MOV R0,R10
+!COUNT .ASSIGNA 0+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R1,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R2,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R3,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R4,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R5,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! SUM TO=5
+! ; 0 5
+ ; 0 5
+! MOV R0,R10
+ MOV R0,R10
+!COUNT .ASSIGNA 0+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R1,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R2,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R3,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R4,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R5,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! SUM FROM=2, TO=5
+! ; 2 5
+ ; 2 5
+! MOV R2,R10
+ MOV R2,R10
+!COUNT .ASSIGNA 2+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R3,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R4,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+! MOV R\&COUNT,R10
+ MOV R5,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AWHILE \&COUNT LE 5
+! MOV R\&COUNT,R10
+!COUNT .ASSIGNA \&COUNT+1
+! .AENDW
+!
+
+!
+
+!; hi this is a comment
+ ; hi this is a comment
+! .MACRO BACK_SLASH_SET
+! \(MOV #"\",R0)
+! .ENDM
+! BACK_SLASH_SET
+! MOV #"\",R0
+ MOV #"\",R0
+! .MACRO COMM
+! bar ; this comment will get copied out
+! foo \; this one will get dropped
+! .ENDM
+! COMM
+! bar ; this comment will get copied out
+ bar ; this comment will get copied out
+! foo \; this one will get dropped
+ foo \; this one will get dropped
+! BACK_SLASH_SET
+! MOV #"\",R0
+ MOV #"\",R0
+! .MACRO PLUS2
+! ADD #1,R\&V1
+! .SDATA "\&V'1"
+! .ENDM
+!V .ASSIGNC "R"
+!V1 .ASSIGNA 1
+! PLUS2
+! ADD #1,R\&V1
+ ADD #1,R1
+! .SDATA "\&V'1"
+ .byte 82,49
+! .MACRO PLUS1 P,P1
+! ADD #1,\P1
+! .SDATA "\P'1"
+! .ENDM
+! PLUS1 R,R1
+! ADD #1,R1
+ ADD #1,R1
+! .SDATA "R1"
+ .byte 82,49
+!
+
+! .MACRO SUM P1
+! MOV R0,R10
+! ADD R1,R10
+! ADD R2,R10
+! \P1
+! ADD R3,R10
+! .ENDM
+!
+
+! SUM .EXITM
+! MOV R0,R10
+ MOV R0,R10
+! ADD R1,R10
+ ADD R1,R10
+! ADD R2,R10
+ ADD R2,R10
+! .EXITM
+!
+
+! .MACRO foo bar=a default=b
+! \bar
+! \default
+! bar
+! default
+! .ENDM
+! foo default=dog bar=cat
+! cat
+ cat
+! dog
+ dog
+! bar
+ bar
+! default
+ default
+! foo X Y
+! X
+ X
+! Y
+ Y
+! bar
+ bar
+! default
+ default
+! foo
+! a
+ a
+! b
+ b
+! bar
+ bar
+! default
+ default
+! foo bar=cat default=dog
+! cat
+ cat
+! dog
+ dog
+! bar
+ bar
+! default
+ default
+!
+
+!
+
+! .MACRO foo bar
+! HI
+! HI \bar
+! HI
+! .ENDM
+!
+
+! foo 1
+! HI
+ HI
+! HI 1
+ HI 1
+! HI
+ HI
+! foo 123
+! HI
+ HI
+! HI 123
+ HI 123
+! HI
+ HI
+! foo 1 2 3 4
+! foo
+! HI
+ HI
+! HI
+ HI
+! HI
+ HI
+!
+
+!
+! .MACRO PUSH Rn
+! MOV.L \Rn,@-r15
+! .ENDM
+! PUSH R0
+! MOV.L R0,@-r15
+ MOV.L R0,@-r15
+! PUSH R1
+! MOV.L R1,@-r15
+ MOV.L R1,@-r15
+!
+
+!
+
+! .MACRO RES_STR STR, Rn
+! MOV.L #str\@,\Rn
+! BRA end_str\@
+! NOP
+!str\@ .SDATA "\STR"
+! .ALIGN 2
+!end_str\@
+! .ENDM
+!
+! RES_STR "ONE",R0
+! MOV.L #str00018,R0
+ MOV.L #str00018,R0
+! BRA end_str00018
+ BRA end_str00018
+! NOP
+ NOP
+!str00018 .SDATA "ONE"
+str00018: .byte 79,78,69
+! .ALIGN 2
+ .align 2
+!end_str00018
+end_str00018:
+! RES_STR "TWO",R1
+! MOV.L #str00019,R1
+ MOV.L #str00019,R1
+! BRA end_str00019
+ BRA end_str00019
+! NOP
+ NOP
+!str00019 .SDATA "TWO"
+str00019: .byte 84,87,79
+! .ALIGN 2
+ .align 2
+!end_str00019
+end_str00019:
+! RES_STR "THREE",R2
+! MOV.L #str00020,R2
+ MOV.L #str00020,R2
+! BRA end_str00020
+ BRA end_str00020
+! NOP
+ NOP
+!str00020 .SDATA "THREE"
+str00020: .byte 84,72,82,69,69
+! .ALIGN 2
+ .align 2
+!end_str00020
+end_str00020:
+!
+
+!
+
+!
+
+! RES_STR STR=donkey Rn=R1
+! MOV.L #str00021,R1
+ MOV.L #str00021,R1
+! BRA end_str00021
+ BRA end_str00021
+! NOP
+ NOP
+!str00021 .SDATA "donkey"
+str00021: .byte 100,111,110,107,101,121
+! .ALIGN 2
+ .align 2
+!end_str00021
+end_str00021:
+! RES_STR donkey,R1
+! MOV.L #str00022,R1
+ MOV.L #str00022,R1
+! BRA end_str00022
+ BRA end_str00022
+! NOP
+ NOP
+!str00022 .SDATA "donkey"
+str00022: .byte 100,111,110,107,101,121
+! .ALIGN 2
+ .align 2
+!end_str00022
+end_str00022:
+! RES_STR donkey Rn=R1
+! MOV.L #str00023,R1
+ MOV.L #str00023,R1
+! BRA end_str00023
+ BRA end_str00023
+! NOP
+ NOP
+!str00023 .SDATA "donkey"
+str00023: .byte 100,111,110,107,101,121
+! .ALIGN 2
+ .align 2
+!end_str00023
+end_str00023:
+! .END
diff --git a/gas/testsuite/gasp/mdouble.asm b/gas/testsuite/gasp/mdouble.asm
new file mode 100644
index 00000000000..dbb77b4d4a4
--- /dev/null
+++ b/gas/testsuite/gasp/mdouble.asm
@@ -0,0 +1,47 @@
+
+ .MACRO HI
+ A
+ \! this is hidden
+ B
+ ! this is not
+ C
+ .ENDM
+ Hello
+ HI
+ Emily
+
+
+ H'0f
+ 200+H'0F
+
+XX .ASSIGNA Q'100
+! Definition:
+ .MACRO GET X=100,Y,Z
+ MOV #\X+H'0F,@B
+ \Y
+\Z JMP @MAIN
+L\@ ADD #1,@HL
+ MOV #0,@C \! Clear C
+ ADD #2,@C
+ ADD #\&XX, @C
+ .ENDM
+
+ NOP
+
+!Call:
+ GET 200,"ADD #1,@B", ENTRY
+ .END
+
+ ; Definition:
+
+
+ NOP
+
+ ;Call:
+ MOV #200+0F,@B
+ ADD #1,@B
+ENTRY: JMP @MAIN
+L00000: ADD #1,@HL
+ MOV #0,@C
+ ADD #2,@C
+ ADD #0, @C
diff --git a/gas/testsuite/gasp/mdouble.err b/gas/testsuite/gasp/mdouble.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/mdouble.err
diff --git a/gas/testsuite/gasp/mdouble.out b/gas/testsuite/gasp/mdouble.out
new file mode 100644
index 00000000000..9d9ad62d283
--- /dev/null
+++ b/gas/testsuite/gasp/mdouble.out
@@ -0,0 +1,68 @@
+!
+
+! .MACRO HI
+! A
+! \! this is hidden
+! B
+! ! this is not
+! C
+! .ENDM
+! Hello
+ Hello
+! HI
+! A
+ A
+!
+! B
+ B
+! ! this is not
+ ! this is not
+! C
+ C
+! Emily
+ Emily
+!
+!
+
+! H'0f
+ 15
+! 200+H'0F
+ 200+15
+!
+
+!XX .ASSIGNA Q'100
+!! Definition:
+ ! Definition:
+! .MACRO GET X=100,Y,Z
+! MOV #\X+H'0F,@B
+! \Y
+!\Z JMP @MAIN
+!L\@ ADD #1,@HL
+! MOV #0,@C \! Clear C
+! ADD #2,@C
+! ADD #\&XX, @C
+! .ENDM
+!
+
+! NOP
+ NOP
+!
+
+!!Call:
+ !Call:
+! GET 200,"ADD #1,@B", ENTRY
+! MOV #200+H'0F,@B
+ MOV #200+15,@B
+! ADD #1,@B
+ ADD #1,@B
+!ENTRY JMP @MAIN
+ENTRY: JMP @MAIN
+!L00001 ADD #1,@HL
+L00001: ADD #1,@HL
+! MOV #0,@C
+ MOV #0,@C
+! ADD #2,@C
+ ADD #2,@C
+! ADD #\&XX, @C
+ ADD #64, @C
+! .END
diff --git a/gas/testsuite/gasp/mri/embed.asm b/gas/testsuite/gasp/mri/embed.asm
new file mode 100644
index 00000000000..f1b8f78bf84
--- /dev/null
+++ b/gas/testsuite/gasp/mri/embed.asm
@@ -0,0 +1,5 @@
+embed macro label
+addr&&label dc.l label
+ endm
+
+ embed foo
diff --git a/gas/testsuite/gasp/mri/embed.out b/gas/testsuite/gasp/mri/embed.out
new file mode 100644
index 00000000000..92d925f4b09
--- /dev/null
+++ b/gas/testsuite/gasp/mri/embed.out
@@ -0,0 +1,9 @@
+;embed macro label
+;addr&&label dc.l label
+; endm
+;
+
+; embed foo
+;addrfoo dc.l foo
+addrfoo: dc.l foo
+; \ No newline at end of file
diff --git a/gas/testsuite/gasp/mri/exists.asm b/gas/testsuite/gasp/mri/exists.asm
new file mode 100644
index 00000000000..87220c624e9
--- /dev/null
+++ b/gas/testsuite/gasp/mri/exists.asm
@@ -0,0 +1,10 @@
+exists macro arg1,arg2
+ ifne ==arg2
+ move arg1,arg2
+ elsec
+ push arg1
+ endc
+ endm
+
+ exists foo,bar
+ exists foo
diff --git a/gas/testsuite/gasp/mri/exists.out b/gas/testsuite/gasp/mri/exists.out
new file mode 100644
index 00000000000..e75337d5118
--- /dev/null
+++ b/gas/testsuite/gasp/mri/exists.out
@@ -0,0 +1,24 @@
+;exists macro arg1,arg2
+; ifne ==arg2
+; move arg1,arg2
+; elsec
+; push arg1
+; endc
+; endm
+;
+
+; exists foo,bar
+; ifne -1
+; move foo,bar
+ move foo,bar
+; elsec
+; push foo
+; endc
+; exists foo
+; ifne 0
+; move foo,
+; elsec
+; push foo
+ push foo
+; endc
+; \ No newline at end of file
diff --git a/gas/testsuite/gasp/mri/irp.asm b/gas/testsuite/gasp/mri/irp.asm
new file mode 100644
index 00000000000..cda21d9ed3b
--- /dev/null
+++ b/gas/testsuite/gasp/mri/irp.asm
@@ -0,0 +1,4 @@
+ irp param,arg1,arg2,arg3
+ dc.l param
+ endr
+ end quit
diff --git a/gas/testsuite/gasp/mri/irp.out b/gas/testsuite/gasp/mri/irp.out
new file mode 100644
index 00000000000..9105620406f
--- /dev/null
+++ b/gas/testsuite/gasp/mri/irp.out
@@ -0,0 +1,8 @@
+; irp param,arg1,arg2,arg3
+; dc.l param
+; endr
+ dc.l arg1
+ dc.l arg2
+ dc.l arg3
+; end quit
+ end quit
diff --git a/gas/testsuite/gasp/mri/irpc.asm b/gas/testsuite/gasp/mri/irpc.asm
new file mode 100644
index 00000000000..a51d6878919
--- /dev/null
+++ b/gas/testsuite/gasp/mri/irpc.asm
@@ -0,0 +1,3 @@
+ irpc dummy,1234
+ dc.l dummy
+ endr
diff --git a/gas/testsuite/gasp/mri/irpc.out b/gas/testsuite/gasp/mri/irpc.out
new file mode 100644
index 00000000000..59f8824fa6d
--- /dev/null
+++ b/gas/testsuite/gasp/mri/irpc.out
@@ -0,0 +1,8 @@
+; irpc dummy,1234
+; dc.l dummy
+; endr
+ dc.l 1
+ dc.l 2
+ dc.l 3
+ dc.l 4
+; \ No newline at end of file
diff --git a/gas/testsuite/gasp/mri/macro.asm b/gas/testsuite/gasp/mri/macro.asm
new file mode 100644
index 00000000000..b711bd0b412
--- /dev/null
+++ b/gas/testsuite/gasp/mri/macro.asm
@@ -0,0 +1,8 @@
+get macro arg1,arg2,arg3
+ dc.l arg1
+ arg2
+arg3 dc.l \4
+ move.\0 d0,d1
+ endm
+
+ get.b 1,<dc.l 2>,label,four
diff --git a/gas/testsuite/gasp/mri/macro.out b/gas/testsuite/gasp/mri/macro.out
new file mode 100644
index 00000000000..86eeb944a2e
--- /dev/null
+++ b/gas/testsuite/gasp/mri/macro.out
@@ -0,0 +1,18 @@
+;get macro arg1,arg2,arg3
+; dc.l arg1
+; arg2
+;arg3 dc.l \4
+; move.\0 d0,d1
+; endm
+;
+
+; get.b 1,<dc.l 2>,label,four
+; dc.l 1
+ dc.l 1
+; dc.l 2
+ dc.l 2
+;label dc.l four
+label: dc.l four
+; move.b d0,d1
+ move.b d0,d1
+; \ No newline at end of file
diff --git a/gas/testsuite/gasp/mri/narg.asm b/gas/testsuite/gasp/mri/narg.asm
new file mode 100644
index 00000000000..114c94032e9
--- /dev/null
+++ b/gas/testsuite/gasp/mri/narg.asm
@@ -0,0 +1,9 @@
+loop macro arg1,arg2,arg3
+ dc.l NARG
+ ifne NARG
+ dc.l arg1
+ loop arg2,arg3
+ endc
+ endm
+
+ loop 1,2,3
diff --git a/gas/testsuite/gasp/mri/narg.out b/gas/testsuite/gasp/mri/narg.out
new file mode 100644
index 00000000000..723ebc1142b
--- /dev/null
+++ b/gas/testsuite/gasp/mri/narg.out
@@ -0,0 +1,38 @@
+;loop macro arg1,arg2,arg3
+; dc.l NARG
+; ifne NARG
+; dc.l arg1
+; loop arg2,arg3
+; endc
+; endm
+;
+
+; loop 1,2,3
+; dc.l 3
+ dc.l 3
+; ifne 3
+; dc.l 1
+ dc.l 1
+; loop 2,3
+; dc.l 2
+ dc.l 2
+; ifne 2
+; dc.l 2
+ dc.l 2
+; loop 3,
+; dc.l 1
+ dc.l 1
+; ifne 1
+; dc.l 3
+ dc.l 3
+; loop ,
+; dc.l 0
+ dc.l 0
+; ifne 0
+; dc.l
+; loop ,
+; endc
+; endc
+; endc
+; endc
+; \ No newline at end of file
diff --git a/gas/testsuite/gasp/mri/rept.asm b/gas/testsuite/gasp/mri/rept.asm
new file mode 100644
index 00000000000..d563bb217a7
--- /dev/null
+++ b/gas/testsuite/gasp/mri/rept.asm
@@ -0,0 +1,3 @@
+ rept 3
+ dc.l 1
+ endr
diff --git a/gas/testsuite/gasp/mri/rept.out b/gas/testsuite/gasp/mri/rept.out
new file mode 100644
index 00000000000..da4ed6be579
--- /dev/null
+++ b/gas/testsuite/gasp/mri/rept.out
@@ -0,0 +1,16 @@
+; rept 3
+; dc.l 1
+; endr
+; dc.l 1
+ dc.l 1
+; REPT 2
+; dc.l 1
+; ENDR
+; dc.l 1
+ dc.l 1
+; REPT 1
+; dc.l 1
+; ENDR
+; dc.l 1
+ dc.l 1
+; \ No newline at end of file
diff --git a/gas/testsuite/gasp/pl1.asm b/gas/testsuite/gasp/pl1.asm
new file mode 100644
index 00000000000..f38bfde93be
--- /dev/null
+++ b/gas/testsuite/gasp/pl1.asm
@@ -0,0 +1,20 @@
+
+ .ALTERNATE
+
+alloc MACRO val1,val2
+ DB val1
+ DB val2
+ ENDM
+
+ alloc "that's" 'show biz'
+ alloc 0,1
+ alloc 0 1
+ alloc 0 1
+ alloc ,1
+
+
+
+
+
+
+
diff --git a/gas/testsuite/gasp/pl1.err b/gas/testsuite/gasp/pl1.err
new file mode 100644
index 00000000000..a1e33188441
--- /dev/null
+++ b/gas/testsuite/gasp/pl1.err
@@ -0,0 +1 @@
+END missing from end of file.
diff --git a/gas/testsuite/gasp/pl1.out b/gas/testsuite/gasp/pl1.out
new file mode 100644
index 00000000000..8b80f12bb8f
--- /dev/null
+++ b/gas/testsuite/gasp/pl1.out
@@ -0,0 +1,49 @@
+!
+! .ALTERNATE
+!
+
+!alloc MACRO val1,val2
+! DB val1
+! DB val2
+! ENDM
+!
+
+! alloc "that's" 'show biz'
+! DB "that's"
+ .byte 116,104,97,116,39,115
+! DB "show biz"
+ .byte 115,104,111,119,32,98,105,122
+! alloc 0,1
+! DB 0
+ .byte 0
+! DB 1
+ .byte 1
+! alloc 0 1
+! DB 0
+ .byte 0
+! DB 1
+ .byte 1
+! alloc 0 1
+! DB 0
+ .byte 0
+! DB 1
+ .byte 1
+! alloc ,1
+! DB
+ .byte
+! DB 1
+ .byte 1
+!
+
+!
+
+!
+!
+
+!
+
+!
+
+!
+
+! \ No newline at end of file
diff --git a/gas/testsuite/gasp/pl2.asm b/gas/testsuite/gasp/pl2.asm
new file mode 100644
index 00000000000..2971137185b
--- /dev/null
+++ b/gas/testsuite/gasp/pl2.asm
@@ -0,0 +1,28 @@
+
+
+ .ALTERNATE
+
+ ! ok
+ !! also ok
+
+foo MACRO
+ ! you can see me
+ !! but not me
+ ! you can see me
+ !! but not me
+ but this "SHOULD !!BE OK"
+ ENDM
+
+ foo
+
+
+define MACRO val1,val2
+ DB val1 ! this comment will show up
+ DB val2 !! this on won't
+ ENDM
+
+ define 0,1
+
+
+ END
+
diff --git a/gas/testsuite/gasp/pl2.err b/gas/testsuite/gasp/pl2.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pl2.err
diff --git a/gas/testsuite/gasp/pl2.out b/gas/testsuite/gasp/pl2.out
new file mode 100644
index 00000000000..cca6fa36683
--- /dev/null
+++ b/gas/testsuite/gasp/pl2.out
@@ -0,0 +1,51 @@
+!
+
+!
+
+! .ALTERNATE
+!
+
+! ! ok
+ ! ok
+! !! also ok
+ !! also ok
+!
+
+!foo MACRO
+! ! you can see me
+! !! but not me
+! ! you can see me
+! !! but not me
+! but this "SHOULD !!BE OK"
+! ENDM
+!
+
+! foo
+! ! you can see me
+ ! you can see me
+!
+! ! you can see me
+ ! you can see me
+!
+! but this "SHOULD !!BE OK"
+ but this "SHOULD !!BE OK"
+!
+
+!
+
+!define MACRO val1,val2
+! DB val1 ! this comment will show up
+! DB val2 !! this on won't
+! ENDM
+!
+
+! define 0,1
+! DB 0 ! this comment will show up
+ .byte 0! this comment will show up
+! DB 1
+ .byte 1
+!
+
+!
+
+! END
diff --git a/gas/testsuite/gasp/pl3.asm b/gas/testsuite/gasp/pl3.asm
new file mode 100644
index 00000000000..0131dcc1572
--- /dev/null
+++ b/gas/testsuite/gasp/pl3.asm
@@ -0,0 +1,30 @@
+ .ALTERNATE
+
+foo MACRO string
+ LOCAL lab1, lab2
+lab1: DATA.L lab2
+lab2: SDATA string
+ ENDM
+
+ foo "An example"
+ foo "using LOCAL"
+
+! test of LOCAL directive
+
+chk_err MACRO limit
+ LOCAL skip !! frob
+ LOCAL zap,dog,barf
+barf: cmp ax,limit !! check value against
+ !! limit
+ jle skip !! skip call if OK
+skip: call error
+ foo dog
+ zap dog
+ nop
+ ENDM
+
+ chk_err 5
+ chk_err 10
+
+
+ END
diff --git a/gas/testsuite/gasp/pl3.err b/gas/testsuite/gasp/pl3.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pl3.err
diff --git a/gas/testsuite/gasp/pl3.out b/gas/testsuite/gasp/pl3.out
new file mode 100644
index 00000000000..066194c7e27
--- /dev/null
+++ b/gas/testsuite/gasp/pl3.out
@@ -0,0 +1,86 @@
+! .ALTERNATE
+!
+
+!foo MACRO string
+! LOCAL lab1, lab2
+!lab1: DATA.L lab2
+!lab2: SDATA string
+! ENDM
+!
+
+! foo "An example"
+!
+!LL0001: DATA.L LL0002
+LL0001: .long LL0002
+!LL0002: SDATA "An example"
+LL0002: .byte 65,110,32,101,120,97,109,112,108,101
+! foo "using LOCAL"
+!
+!LL0003: DATA.L LL0004
+LL0003: .long LL0004
+!LL0004: SDATA "using LOCAL"
+LL0004: .byte 117,115,105,110,103,32,76,79,67,65,76
+!
+
+!! test of LOCAL directive
+ ! test of LOCAL directive
+!
+
+!chk_err MACRO limit
+! LOCAL skip !! frob
+! LOCAL zap,dog,barf
+!barf: cmp ax,limit !! check value against
+! !! limit
+! jle skip !! skip call if OK
+!skip: call error
+! foo dog
+! zap dog
+! nop
+! ENDM
+!
+
+! chk_err 5
+!
+!
+!LL0008: cmp ax,5
+LL0008: cmp ax,5
+!
+! jle LL0005
+ jle LL0005
+!LL0005: call error
+LL0005: call error
+! foo LL0007
+!
+!LL0009: DATA.L LL000a
+LL0009: .long LL000a
+!LL000a: SDATA LL0007
+LL000a: .byte 76,76,48,48,48,55
+! LL0006 LL0007
+ LL0006 LL0007
+! nop
+ nop
+! chk_err 10
+!
+!
+!LL000e: cmp ax,10
+LL000e: cmp ax,10
+!
+! jle LL000b
+ jle LL000b
+!LL000b: call error
+LL000b: call error
+! foo LL000d
+!
+!LL000f: DATA.L LL0010
+LL000f: .long LL0010
+!LL0010: SDATA LL000d
+LL0010: .byte 76,76,48,48,48,100
+! LL000c LL000d
+ LL000c LL000d
+! nop
+ nop
+!
+
+!
+
+! END
diff --git a/gas/testsuite/gasp/pl4.asm b/gas/testsuite/gasp/pl4.asm
new file mode 100644
index 00000000000..f1dd3e80cd4
--- /dev/null
+++ b/gas/testsuite/gasp/pl4.asm
@@ -0,0 +1,10 @@
+ .ALTERNATE
+! test of macro substitution around &s
+
+
+foo MACRO a,b
+ x&a&b
+ ENDM
+
+ foo 3 2
+ END
diff --git a/gas/testsuite/gasp/pl4.err b/gas/testsuite/gasp/pl4.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pl4.err
diff --git a/gas/testsuite/gasp/pl4.out b/gas/testsuite/gasp/pl4.out
new file mode 100644
index 00000000000..35d1391d188
--- /dev/null
+++ b/gas/testsuite/gasp/pl4.out
@@ -0,0 +1,16 @@
+! .ALTERNATE
+!! test of macro substitution around &s
+ ! test of macro substitution around &s
+!
+
+!
+
+!foo MACRO a,b
+! x&a&b
+! ENDM
+!
+
+! foo 3 2
+! x32
+ x32
+! END
diff --git a/gas/testsuite/gasp/pl5.asm b/gas/testsuite/gasp/pl5.asm
new file mode 100644
index 00000000000..16b999b1fd4
--- /dev/null
+++ b/gas/testsuite/gasp/pl5.asm
@@ -0,0 +1,15 @@
+! test of literal text operator
+ .ALTERNATE
+foop MACRO str1,str2
+ SDATA "str1"
+ SDATA str2
+ ENDM
+
+
+
+ foop this< is a <string> with angle brackets>
+ foop this< is a string with spaces>
+ foop this < is a string with a !>>
+
+
+ END
diff --git a/gas/testsuite/gasp/pl5.err b/gas/testsuite/gasp/pl5.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pl5.err
diff --git a/gas/testsuite/gasp/pl5.out b/gas/testsuite/gasp/pl5.out
new file mode 100644
index 00000000000..0aa488b5ec7
--- /dev/null
+++ b/gas/testsuite/gasp/pl5.out
@@ -0,0 +1,32 @@
+!! test of literal text operator
+ ! test of literal text operator
+! .ALTERNATE
+!foop MACRO str1,str2
+! SDATA "str1"
+! SDATA str2
+! ENDM
+!
+
+!
+
+!
+! foop this< is a <string> with angle brackets>
+! SDATA "this"
+ .byte 116,104,105,115
+! SDATA " is a <string> with angle brackets"
+ .byte 32,105,115,32,97,32,60,115,116,114,105,110,103,62,32,119,105,116,104,32,97,110,103,108,101,32,98,114,97,99,107,101,116,115
+! foop this< is a string with spaces>
+! SDATA "this"
+ .byte 116,104,105,115
+! SDATA " is a string with spaces"
+ .byte 32,105,115,32,97,32,115,116,114,105,110,103,32,119,105,116,104,32,115,112,97,99,101,115
+! foop this < is a string with a !>>
+! SDATA "this"
+ .byte 116,104,105,115
+! SDATA " is a string with a >"
+ .byte 32,105,115,32,97,32,115,116,114,105,110,103,32,119,105,116,104,32,97,32,62
+!
+
+!
+
+! END
diff --git a/gas/testsuite/gasp/pl6.asm b/gas/testsuite/gasp/pl6.asm
new file mode 100644
index 00000000000..162d617588c
--- /dev/null
+++ b/gas/testsuite/gasp/pl6.asm
@@ -0,0 +1,21 @@
+ .ALTERNATE
+! test of expression operator
+define MACRO val, string
+ SDATA val
+ SDATA string
+ ENDM
+ define "1","99%of100" ! notice % within string
+ define %1 + 2, "=3"
+
+
+ define % 1 + 2 %3+4
+
+ define %3*4-2 <=10>
+
+ define %3*4-2 5
+
+ define %1 + 2,<is equal to %1 + 2, right?>
+
+ ! has no effect
+
+ end
diff --git a/gas/testsuite/gasp/pl6.err b/gas/testsuite/gasp/pl6.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pl6.err
diff --git a/gas/testsuite/gasp/pl6.out b/gas/testsuite/gasp/pl6.out
new file mode 100644
index 00000000000..dcd16cf8314
--- /dev/null
+++ b/gas/testsuite/gasp/pl6.out
@@ -0,0 +1,54 @@
+! .ALTERNATE
+!! test of expression operator
+ ! test of expression operator
+!define MACRO val, string
+! SDATA val
+! SDATA string
+! ENDM
+! define "1","99%of100" ! notice % within string
+! SDATA "1"
+ .byte 49
+! SDATA "99%of100"
+ .byte 57,57,37,111,102,49,48,48
+! define %1 + 2, "=3"
+! SDATA 3
+ .byte 51
+! SDATA "=3"
+ .byte 61,51
+!
+
+!
+
+! define % 1 + 2 %3+4
+! SDATA 3
+ .byte 51
+! SDATA 7
+ .byte 55
+!
+
+! define %3*4-2 <=10>
+! SDATA 10
+ .byte 49,48
+! SDATA "=10"
+ .byte 61,49,48
+!
+
+! define %3*4-2 5
+! SDATA 10
+ .byte 49,48
+! SDATA 5
+ .byte 53
+!
+
+! define %1 + 2,<is equal to %1 + 2, right?>
+! SDATA 3
+ .byte 51
+! SDATA "is equal to %1 + 2, right?"
+ .byte 105,115,32,101,113,117,97,108,32,116,111,32,37,49,32,43,32,50,44,32,114,105,103,104,116,63
+!
+
+! ! has no effect
+ ! has no effect
+!
+
+! end
diff --git a/gas/testsuite/gasp/pl7.asm b/gas/testsuite/gasp/pl7.asm
new file mode 100644
index 00000000000..58a40afe101
--- /dev/null
+++ b/gas/testsuite/gasp/pl7.asm
@@ -0,0 +1,12 @@
+ .ALTERNATE
+! test of string operators
+define MACRO str1,str2
+ SDATA str1
+ SDATA "str2"
+ENDM
+ define one" way to get "spaces,0
+ define "lot's! of <special>,chars%", 0
+
+
+
+
diff --git a/gas/testsuite/gasp/pl7.err b/gas/testsuite/gasp/pl7.err
new file mode 100644
index 00000000000..a1e33188441
--- /dev/null
+++ b/gas/testsuite/gasp/pl7.err
@@ -0,0 +1 @@
+END missing from end of file.
diff --git a/gas/testsuite/gasp/pl7.out b/gas/testsuite/gasp/pl7.out
new file mode 100644
index 00000000000..1519b3430c7
--- /dev/null
+++ b/gas/testsuite/gasp/pl7.out
@@ -0,0 +1,26 @@
+! .ALTERNATE
+!! test of string operators
+ ! test of string operators
+!define MACRO str1,str2
+! SDATA str1
+! SDATA "str2"
+!ENDM
+! define one" way to get "spaces,0
+! SDATA one" way to get "spaces
+ .byte 111,110,101,34,32,119,97,121,32,116,111,32,103,101,116,32,34,115,112,97,99,101,115
+! SDATA "0"
+ .byte 48
+! define "lot's! of <special>,chars%", 0
+! SDATA "lot's of <special>,chars%"
+ .byte 108,111,116,39,115,32,111,102,32,60,115,112,101,99,105,97,108,62,44,99,104,97,114,115,37
+! SDATA "0"
+ .byte 48
+!
+
+!
+
+!
+
+!
+
+! \ No newline at end of file
diff --git a/gas/testsuite/gasp/pl8.asm b/gas/testsuite/gasp/pl8.asm
new file mode 100644
index 00000000000..925b1723977
--- /dev/null
+++ b/gas/testsuite/gasp/pl8.asm
@@ -0,0 +1,18 @@
+
+ .ALTERNATE
+ SDATA %1+2+3
+ SDATA "5"
+
+
+
+ MACRO foo
+ SDATA "HI" !! this will go
+ SDATA "THERE ! this will stay
+ ENDM
+
+ foo
+
+
+ SDATA <!<this is <a wacky> example!>!!>
+ SDATA "<this is <a wacky> example>!"
+ END
diff --git a/gas/testsuite/gasp/pl8.err b/gas/testsuite/gasp/pl8.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pl8.err
diff --git a/gas/testsuite/gasp/pl8.out b/gas/testsuite/gasp/pl8.out
new file mode 100644
index 00000000000..37104123303
--- /dev/null
+++ b/gas/testsuite/gasp/pl8.out
@@ -0,0 +1,33 @@
+!
+
+! .ALTERNATE
+! SDATA %1+2+3
+ .byte 37,49,43,50,43,51,32
+! SDATA "5"
+ .byte 53
+!
+
+!
+
+!
+
+! MACRO foo
+! SDATA "HI" !! this will go
+! SDATA "THERE ! this will stay
+! ENDM
+!
+
+! foo
+! SDATA "HI"
+ .byte 72,73
+! SDATA "THERE ! this will stay
+ .byte 84,72,69,82,69,9,32,116,104,105,115,32,119,105,108,108,32,115,116,97,121
+!
+
+!
+
+! SDATA <!<this is <a wacky> example!>!!>
+ .byte 60,116,104,105,115,32,105,115,32,60,97,32,119,97,99,107,121,62,32,101,120,97,109,112,108,101,62,33
+! SDATA "<this is <a wacky> example>!"
+ .byte 60,116,104,105,115,32,105,115,32,60,97,32,119,97,99,107,121,62,32,101,120,97,109,112,108,101,62,34
+! END
diff --git a/gas/testsuite/gasp/pr7583.asm b/gas/testsuite/gasp/pr7583.asm
new file mode 100644
index 00000000000..c97caf546db
--- /dev/null
+++ b/gas/testsuite/gasp/pr7583.asm
@@ -0,0 +1,3 @@
+
+ .sdata "v1.0000"
+ .end
diff --git a/gas/testsuite/gasp/pr7583.err b/gas/testsuite/gasp/pr7583.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/pr7583.err
diff --git a/gas/testsuite/gasp/pr7583.out b/gas/testsuite/gasp/pr7583.out
new file mode 100644
index 00000000000..a5df1d7f58d
--- /dev/null
+++ b/gas/testsuite/gasp/pr7583.out
@@ -0,0 +1,5 @@
+!
+
+! .sdata "v1.0000"
+ .byte 118,49,46,48,48,48,48
+! .end
diff --git a/gas/testsuite/gasp/reg.asm b/gas/testsuite/gasp/reg.asm
new file mode 100644
index 00000000000..eb463ed7e7b
--- /dev/null
+++ b/gas/testsuite/gasp/reg.asm
@@ -0,0 +1,9 @@
+
+
+foo .REG (r1)
+ add foo,foo
+
+bar .reg (r2)
+ add bar,foo
+
+ .END
diff --git a/gas/testsuite/gasp/reg.err b/gas/testsuite/gasp/reg.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/reg.err
diff --git a/gas/testsuite/gasp/reg.out b/gas/testsuite/gasp/reg.out
new file mode 100644
index 00000000000..79268a36bd7
--- /dev/null
+++ b/gas/testsuite/gasp/reg.out
@@ -0,0 +1,15 @@
+!
+
+!
+
+!foo .REG (r1)
+! add foo,foo
+ add r1,r1
+!
+
+!bar .reg (r2)
+! add bar,foo
+ add r2,r1
+!
+
+! .END
diff --git a/gas/testsuite/gasp/rep.asm b/gas/testsuite/gasp/rep.asm
new file mode 100644
index 00000000000..027ac470804
--- /dev/null
+++ b/gas/testsuite/gasp/rep.asm
@@ -0,0 +1,13 @@
+ .AREPEAT 5
+ FIVE
+ .AREPEAT 2
+ TWO
+ .AENDR
+ .AREPEAT 3
+ THREE
+ .AREPEAT 2
+ TWO
+ .AENDR
+ .AENDR
+ .AENDR
+ .END
diff --git a/gas/testsuite/gasp/rep.err b/gas/testsuite/gasp/rep.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/rep.err
diff --git a/gas/testsuite/gasp/rep.out b/gas/testsuite/gasp/rep.out
new file mode 100644
index 00000000000..510d0e1777e
--- /dev/null
+++ b/gas/testsuite/gasp/rep.out
@@ -0,0 +1,391 @@
+! .AREPEAT 5
+! FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! .AENDR
+! FIVE
+ FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 2
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 4
+! FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! .AENDR
+! FIVE
+ FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 2
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 3
+! FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! .AENDR
+! FIVE
+ FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 2
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 2
+! FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! .AENDR
+! FIVE
+ FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 2
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! .AENDR
+! FIVE
+ FIVE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 3
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 2
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! .AENDR
+! THREE
+ THREE
+! .AREPEAT 2
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .AREPEAT 1
+! TWO
+! .AENDR
+! TWO
+ TWO
+! .END
diff --git a/gas/testsuite/gasp/repeat.asm b/gas/testsuite/gasp/repeat.asm
new file mode 100644
index 00000000000..7a85da314ad
--- /dev/null
+++ b/gas/testsuite/gasp/repeat.asm
@@ -0,0 +1,14 @@
+
+ .AREPEAT 10
+ TEN
+ .AREPEAT 2
+ TWENTY
+ .AENDR
+ .AENDR
+
+ .AREPEAT 3
+ ROTCL R2
+ DIV1 R0,R1
+ .AENDR
+
+ .END
diff --git a/gas/testsuite/gasp/repeat.err b/gas/testsuite/gasp/repeat.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/repeat.err
diff --git a/gas/testsuite/gasp/repeat.out b/gas/testsuite/gasp/repeat.out
new file mode 100644
index 00000000000..705d8d88e4d
--- /dev/null
+++ b/gas/testsuite/gasp/repeat.out
@@ -0,0 +1,211 @@
+!
+
+! .AREPEAT 10
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 9
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 8
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 7
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 6
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 5
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 4
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 3
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 2
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! .AENDR
+! TEN
+ TEN
+! .AREPEAT 2
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+! .AREPEAT 1
+! TWENTY
+! .AENDR
+! TWENTY
+ TWENTY
+!
+
+! .AREPEAT 3
+! ROTCL R2
+! DIV1 R0,R1
+! .AENDR
+! ROTCL R2
+ ROTCL R2
+! DIV1 R0,R1
+ DIV1 R0,R1
+! .AREPEAT 2
+! ROTCL R2
+! DIV1 R0,R1
+! .AENDR
+! ROTCL R2
+ ROTCL R2
+! DIV1 R0,R1
+ DIV1 R0,R1
+! .AREPEAT 1
+! ROTCL R2
+! DIV1 R0,R1
+! .AENDR
+! ROTCL R2
+ ROTCL R2
+! DIV1 R0,R1
+ DIV1 R0,R1
+!
+
+! .END
diff --git a/gas/testsuite/gasp/reperr.asm b/gas/testsuite/gasp/reperr.asm
new file mode 100644
index 00000000000..60882b2299b
--- /dev/null
+++ b/gas/testsuite/gasp/reperr.asm
@@ -0,0 +1,2 @@
+
+ .REPEAT 10
diff --git a/gas/testsuite/gasp/reperr.err b/gas/testsuite/gasp/reperr.err
new file mode 100644
index 00000000000..a1e33188441
--- /dev/null
+++ b/gas/testsuite/gasp/reperr.err
@@ -0,0 +1 @@
+END missing from end of file.
diff --git a/gas/testsuite/gasp/reperr.out b/gas/testsuite/gasp/reperr.out
new file mode 100644
index 00000000000..2c9f8c6a911
--- /dev/null
+++ b/gas/testsuite/gasp/reperr.out
@@ -0,0 +1,5 @@
+!
+
+! .REPEAT 10
+ .REPEAT 10
+! \ No newline at end of file
diff --git a/gas/testsuite/gasp/reperr1.asm b/gas/testsuite/gasp/reperr1.asm
new file mode 100644
index 00000000000..2d987e48f40
--- /dev/null
+++ b/gas/testsuite/gasp/reperr1.asm
@@ -0,0 +1,3 @@
+
+ .AREPEAT 10
+ .END
diff --git a/gas/testsuite/gasp/reperr1.err b/gas/testsuite/gasp/reperr1.err
new file mode 100644
index 00000000000..536545be1d2
--- /dev/null
+++ b/gas/testsuite/gasp/reperr1.err
@@ -0,0 +1 @@
+End of file whilst inside AREPEAT, started on line 3.
diff --git a/gas/testsuite/gasp/reperr1.out b/gas/testsuite/gasp/reperr1.out
new file mode 100644
index 00000000000..dd82880b361
--- /dev/null
+++ b/gas/testsuite/gasp/reperr1.out
@@ -0,0 +1,5 @@
+!
+
+! .AREPEAT 10
+! .END
+! \ No newline at end of file
diff --git a/gas/testsuite/gasp/reperr2.asm b/gas/testsuite/gasp/reperr2.asm
new file mode 100644
index 00000000000..de06a712170
--- /dev/null
+++ b/gas/testsuite/gasp/reperr2.asm
@@ -0,0 +1,6 @@
+
+ .AREPEAT 5
+ .AENDR
+ .AENDR
+ .END
+
diff --git a/gas/testsuite/gasp/reperr2.err b/gas/testsuite/gasp/reperr2.err
new file mode 100644
index 00000000000..840ccc52377
--- /dev/null
+++ b/gas/testsuite/gasp/reperr2.err
@@ -0,0 +1 @@
+reperr2.asm:4 AENDR without a AREPEAT.
diff --git a/gas/testsuite/gasp/reperr2.out b/gas/testsuite/gasp/reperr2.out
new file mode 100644
index 00000000000..df7a84d5848
--- /dev/null
+++ b/gas/testsuite/gasp/reperr2.out
@@ -0,0 +1,14 @@
+!
+
+! .AREPEAT 5
+! .AENDR
+! .AREPEAT 4
+! .AENDR
+! .AREPEAT 3
+! .AENDR
+! .AREPEAT 2
+! .AENDR
+! .AREPEAT 1
+! .AENDR
+! .AENDR
+! .END
diff --git a/gas/testsuite/gasp/reperr3.asm b/gas/testsuite/gasp/reperr3.asm
new file mode 100644
index 00000000000..464bc79ba3e
--- /dev/null
+++ b/gas/testsuite/gasp/reperr3.asm
@@ -0,0 +1,21 @@
+ .AREPEAT 4
+ .AREPEAT 4
+ .AREPEAT 4
+ .AREPEAT 4
+ stuff
+ .AENDR
+ which
+ .AENDR
+ will
+ .AENDR
+ get
+ .AENDR
+ repetaed
+ .AENDR
+
+ .AENDR
+ .AENDR
+ .AENDR
+ .AENDR
+ .AENDR
+ .END
diff --git a/gas/testsuite/gasp/reperr3.err b/gas/testsuite/gasp/reperr3.err
new file mode 100644
index 00000000000..1be0dceecf4
--- /dev/null
+++ b/gas/testsuite/gasp/reperr3.err
@@ -0,0 +1,6 @@
+reperr3.asm:14 AENDR without a AREPEAT.
+reperr3.asm:16 AENDR without a AREPEAT.
+reperr3.asm:17 AENDR without a AREPEAT.
+reperr3.asm:18 AENDR without a AREPEAT.
+reperr3.asm:19 AENDR without a AREPEAT.
+reperr3.asm:20 AENDR without a AREPEAT.
diff --git a/gas/testsuite/gasp/reperr3.out b/gas/testsuite/gasp/reperr3.out
new file mode 100644
index 00000000000..9a3513b7ba0
--- /dev/null
+++ b/gas/testsuite/gasp/reperr3.out
@@ -0,0 +1,2035 @@
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! get
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 3
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 2
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 1
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! get
+ get
+! .AREPEAT 3
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! get
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 3
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 2
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 1
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! get
+ get
+! .AREPEAT 2
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! get
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 3
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 2
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 1
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! get
+ get
+! .AREPEAT 1
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! get
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 3
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 2
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! .AREPEAT 1
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! will
+! .AENDR
+! .AREPEAT 4
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 3
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 2
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! .AREPEAT 1
+! .AREPEAT 4
+! stuff
+! .AENDR
+! which
+! .AENDR
+! .AREPEAT 4
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 3
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 2
+! stuff
+! .AENDR
+! stuff
+ stuff
+! .AREPEAT 1
+! stuff
+! .AENDR
+! stuff
+ stuff
+! which
+ which
+! will
+ will
+! get
+ get
+! repetaed
+ repetaed
+! .AENDR
+!
+
+! .AENDR
+! .AENDR
+! .AENDR
+! .AENDR
+! .AENDR
+! .END
diff --git a/gas/testsuite/gasp/sdata.asm b/gas/testsuite/gasp/sdata.asm
new file mode 100644
index 00000000000..d6bd23c2453
--- /dev/null
+++ b/gas/testsuite/gasp/sdata.asm
@@ -0,0 +1,24 @@
+
+
+ .SDATA "HI","STEVE"
+ .SDATA "HI" , "STEVE" , <72>,<73>,<83><69><86><69>
+
+ .SDATA "H""I" , "STEVE" , <72>,<73>,<83><69><86><69>
+
+
+
+ .SDATA "SHOULD NOT FAIL" "HERE"
+ .SDATA "SHOULD FAIL" foo "HERE"
+
+ .SDATAB 8,"BOINK"
+
+ ; examples from book
+
+ .SDATAB 2,"AAAAA"
+ .SDATAB 2,"""BBB"""
+ .SDATAB 2,"AABB"<H'07>
+
+
+a1: .SDATAZ "HI"
+a2: .SDATAC "HI"
+a3: .SDATA "HI"
diff --git a/gas/testsuite/gasp/sdata.err b/gas/testsuite/gasp/sdata.err
new file mode 100644
index 00000000000..7544ccc9579
--- /dev/null
+++ b/gas/testsuite/gasp/sdata.err
@@ -0,0 +1,3 @@
+sdata.asm:19 Character code in string must be absolute expression.
+sdata.asm:19 Missing > for character code.
+END missing from end of file.
diff --git a/gas/testsuite/gasp/sdata.out b/gas/testsuite/gasp/sdata.out
new file mode 100644
index 00000000000..e689d35e82d
--- /dev/null
+++ b/gas/testsuite/gasp/sdata.out
@@ -0,0 +1,59 @@
+!
+
+!
+
+! .SDATA "HI","STEVE"
+ .byte 72,73,83,84,69,86,69
+! .SDATA "HI" , "STEVE" , <72>,<73>,<83><69><86><69>
+ .byte 72,73,83,84,69,86,69,72,73,83,69,86,69
+!
+
+! .SDATA "H""I" , "STEVE" , <72>,<73>,<83><69><86><69>
+ .byte 72,34,73,83,84,69,86,69,72,73,83,69,86,69
+!
+
+!
+
+!
+
+! .SDATA "SHOULD NOT FAIL" "HERE"
+ .byte 83,72,79,85,76,68,32,78,79,84,32,70,65,73,76,72,69,82,69
+! .SDATA "SHOULD FAIL" foo "HERE"
+ .byte 83,72,79,85,76,68,32,70,65,73,76,102,111,111,32,34,72,69,82,69,34,32
+!
+
+! .SDATAB 8,"BOINK"
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+ .byte 66,79,73,78,75
+!
+
+! ; examples from book
+ ; examples from book
+!
+
+! .SDATAB 2,"AAAAA"
+ .byte 65,65,65,65,65
+ .byte 65,65,65,65,65
+! .SDATAB 2,"""BBB"""
+ .byte 34,66,66,66,34
+ .byte 34,66,66,66,34
+! .SDATAB 2,"AABB"<H'07>
+ .byte 65,65,66,66,0
+ .byte 65,65,66,66,0
+!
+
+!
+
+!a1: .SDATAZ "HI"
+a1: .byte 72,73,0
+!a2: .SDATAC "HI"
+a2: .byte 2,72,73
+!a3: .SDATA "HI"
+a3: .byte 72,73
+! \ No newline at end of file
diff --git a/gas/testsuite/gasp/sfunc.asm b/gas/testsuite/gasp/sfunc.asm
new file mode 100644
index 00000000000..b59949a9d14
--- /dev/null
+++ b/gas/testsuite/gasp/sfunc.asm
@@ -0,0 +1,26 @@
+
+ .MACRO RESERVE_STR P1=0 P2
+ .SDATA .SUBSTR("ABCDEFG",\P1,\P2)
+ .ENDM
+
+ RESERVE_STR 2,2
+ RESERVE_STR ,3
+
+
+ .MACRO FIND_STR P1
+ .DATA.W .INSTR("ABCDEFG","\P1", 0)
+ .ENDM
+
+ FIND_STR CDE
+ FIND_STR H
+
+ .MACRO RESERVE_LENGTH P1
+ .ALIGN 4
+ .SRES .LEN("\P1")
+ .ENDM
+
+ RESERVE_LENGTH ABCDEF
+ RESERVE_LENGTH ABC
+
+ .END
+
diff --git a/gas/testsuite/gasp/sfunc.err b/gas/testsuite/gasp/sfunc.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/sfunc.err
diff --git a/gas/testsuite/gasp/sfunc.out b/gas/testsuite/gasp/sfunc.out
new file mode 100644
index 00000000000..50f694ff990
--- /dev/null
+++ b/gas/testsuite/gasp/sfunc.out
@@ -0,0 +1,49 @@
+!
+
+! .MACRO RESERVE_STR P1=0 P2
+! .SDATA .SUBSTR("ABCDEFG",\P1,\P2)
+! .ENDM
+!
+
+! RESERVE_STR 2,2
+! .SDATA .SUBSTR("ABCDEFG",2,2)
+ .byte 67,68
+! RESERVE_STR ,3
+! .SDATA .SUBSTR("ABCDEFG",0,3)
+ .byte 65,66,67
+!
+
+!
+
+! .MACRO FIND_STR P1
+! .DATA.W .INSTR("ABCDEFG","\P1", 0)
+! .ENDM
+!
+
+! FIND_STR CDE
+! .DATA.W .INSTR("ABCDEFG","CDE", 0)
+ .short 2
+! FIND_STR H
+! .DATA.W .INSTR("ABCDEFG","H", 0)
+ .short -1
+!
+
+! .MACRO RESERVE_LENGTH P1
+! .ALIGN 4
+! .SRES .LEN("\P1")
+! .ENDM
+!
+
+! RESERVE_LENGTH ABCDEF
+! .ALIGN 4
+ .align 4
+! .SRES .LEN("ABCDEF")
+ .space 24
+! RESERVE_LENGTH ABC
+! .ALIGN 4
+ .align 4
+! .SRES .LEN("ABC")
+ .space 12
+!
+
+! .END
diff --git a/gas/testsuite/gasp/t1.asm b/gas/testsuite/gasp/t1.asm
new file mode 100644
index 00000000000..df54c6cdf2a
--- /dev/null
+++ b/gas/testsuite/gasp/t1.asm
@@ -0,0 +1,3 @@
+
+ test for eof in middle of line
+ .END
diff --git a/gas/testsuite/gasp/t1.err b/gas/testsuite/gasp/t1.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/t1.err
diff --git a/gas/testsuite/gasp/t1.out b/gas/testsuite/gasp/t1.out
new file mode 100644
index 00000000000..39230e16805
--- /dev/null
+++ b/gas/testsuite/gasp/t1.out
@@ -0,0 +1,5 @@
+!
+
+! test for eof in middle of line
+ test for eof in middle of line
+! .END
diff --git a/gas/testsuite/gasp/t2.asm b/gas/testsuite/gasp/t2.asm
new file mode 100644
index 00000000000..38a351a7755
--- /dev/null
+++ b/gas/testsuite/gasp/t2.asm
@@ -0,0 +1,8 @@
+
+
+ test
++ continued
++ lines
+
+
+ .END
diff --git a/gas/testsuite/gasp/t2.err b/gas/testsuite/gasp/t2.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/t2.err
diff --git a/gas/testsuite/gasp/t2.out b/gas/testsuite/gasp/t2.out
new file mode 100644
index 00000000000..0c44e8bc1d7
--- /dev/null
+++ b/gas/testsuite/gasp/t2.out
@@ -0,0 +1,13 @@
+!
+
+!
+
+! test
+!+continued
+!+lines
+ testcontinuedlines
+!
+
+!
+
+! .END
diff --git a/gas/testsuite/gasp/t3.asm b/gas/testsuite/gasp/t3.asm
new file mode 100644
index 00000000000..27702db8c81
--- /dev/null
+++ b/gas/testsuite/gasp/t3.asm
@@ -0,0 +1,12 @@
+
+ test base convertions
+
+ B'1001000
+ Q'210
+ D'136
+ H'88
+
+ FOOB'1001000BAR
+ FOOQ'210BAR
+ FOOD'136BAR
+ FOOH'88BAR
diff --git a/gas/testsuite/gasp/t3.err b/gas/testsuite/gasp/t3.err
new file mode 100644
index 00000000000..a1e33188441
--- /dev/null
+++ b/gas/testsuite/gasp/t3.err
@@ -0,0 +1 @@
+END missing from end of file.
diff --git a/gas/testsuite/gasp/t3.out b/gas/testsuite/gasp/t3.out
new file mode 100644
index 00000000000..8ad150bfcde
--- /dev/null
+++ b/gas/testsuite/gasp/t3.out
@@ -0,0 +1,25 @@
+!
+
+! test base convertions
+ test base convertions
+!
+
+! B'1001000
+ 72
+! Q'210
+ 136
+! D'136
+ 136
+! H'88
+ 136
+!
+
+! FOOB'1001000BAR
+ FOOB'1001000BAR
+! FOOQ'210BAR
+ FOOQ'210BAR
+! FOOD'136BAR
+ FOOD'136BAR
+! FOOH'88BAR
+ FOOH'88BAR
+! \ No newline at end of file
diff --git a/gas/testsuite/gasp/while.asm b/gas/testsuite/gasp/while.asm
new file mode 100644
index 00000000000..09143ccd818
--- /dev/null
+++ b/gas/testsuite/gasp/while.asm
@@ -0,0 +1,18 @@
+ donkey
+bar .ASSIGNA 0
+ .AWHILE \&bar LT 5
+ HI BAR IS \&bar
+foo .ASSIGNA 0
+ .AWHILE \&foo LT 2
+ HI BEFORE
+ .AREPEAT 2
+ HI MEDIUM \&foo \&bar
+ .AENDR
+ HI AFTER
+foo .ASSIGNA \&foo + 1
+ .AENDW
+bar .ASSIGNA \&bar + 1
+ AND ITS NOW \&bar
+ .AENDW
+ .END
+
diff --git a/gas/testsuite/gasp/while.err b/gas/testsuite/gasp/while.err
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gas/testsuite/gasp/while.err
diff --git a/gas/testsuite/gasp/while.out b/gas/testsuite/gasp/while.out
new file mode 100644
index 00000000000..128aeb1a6dd
--- /dev/null
+++ b/gas/testsuite/gasp/while.out
@@ -0,0 +1,388 @@
+! donkey
+ donkey
+!bar .ASSIGNA 0
+! .AWHILE \&bar LT 5
+! HI BAR IS \&bar
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+! .AENDW
+! HI BAR IS \&bar
+ HI BAR IS 0
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 0
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 0
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 0
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 0
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+ AND ITS NOW 1
+! .AWHILE \&bar LT 5
+! HI BAR IS \&bar
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+! .AENDW
+! HI BAR IS \&bar
+ HI BAR IS 1
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 1
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 1
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 1
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 1
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+ AND ITS NOW 2
+! .AWHILE \&bar LT 5
+! HI BAR IS \&bar
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+! .AENDW
+! HI BAR IS \&bar
+ HI BAR IS 2
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 2
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 2
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 2
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 2
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+ AND ITS NOW 3
+! .AWHILE \&bar LT 5
+! HI BAR IS \&bar
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+! .AENDW
+! HI BAR IS \&bar
+ HI BAR IS 3
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 3
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 3
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 3
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 3
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+ AND ITS NOW 4
+! .AWHILE \&bar LT 5
+! HI BAR IS \&bar
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+! .AENDW
+! HI BAR IS \&bar
+ HI BAR IS 4
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 4
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 0 4
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+! HI BEFORE
+ HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 4
+! .AREPEAT 1
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI MEDIUM \&foo \&bar
+ HI MEDIUM 1 4
+! HI AFTER
+ HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+ AND ITS NOW 5
+! .AWHILE \&bar LT 5
+! HI BAR IS \&bar
+!foo .ASSIGNA 0
+! .AWHILE \&foo LT 2
+! HI BEFORE
+! .AREPEAT 2
+! HI MEDIUM \&foo \&bar
+! .AENDR
+! HI AFTER
+!foo .ASSIGNA \&foo + 1
+! .AENDW
+!bar .ASSIGNA \&bar + 1
+! AND ITS NOW \&bar
+! .AENDW
+! .END
diff --git a/gas/testsuite/lib/doboth b/gas/testsuite/lib/doboth
new file mode 100755
index 00000000000..bcb837cff2b
--- /dev/null
+++ b/gas/testsuite/lib/doboth
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+x=$1 ; shift
+y=$1 ; shift
+
+rm tmp.0 > /dev/null 2>&1
+ln -s $x tmp.0
+$* tmp.0 > tmp.1
+
+rm tmp.0
+ln -s $y tmp.0
+$* tmp.0 > tmp.2
+
+rm tmp.0
+
+diff -c tmp.1 tmp.2
+exit
+
+#eof
diff --git a/gas/testsuite/lib/doobjcmp b/gas/testsuite/lib/doobjcmp
new file mode 100755
index 00000000000..35c32da0de4
--- /dev/null
+++ b/gas/testsuite/lib/doobjcmp
@@ -0,0 +1,88 @@
+#!/bin/sh
+# compare two object files, in depth.
+
+x=$1
+y=$2
+BOTH="$1 $2"
+
+
+# if they cmp, we're fine.
+if (cmp $BOTH > /dev/null)
+then
+ exit 0
+fi
+
+# otherwise, we must look closer.
+if (doboth $BOTH size)
+then
+ echo Sizes ok.
+else
+ echo Sizes differ:
+ size $BOTH
+# exit 1
+fi
+
+if (doboth $BOTH objdump +header)
+then
+ echo Headers ok.
+else
+ echo Header differences.
+# exit 1
+fi
+
+if (doboth $BOTH objdump +text > /dev/null)
+then
+ echo Text ok.
+else
+ echo Text differences.
+# doboth $BOTH objdump +text
+# exit 1
+fi
+
+if (doboth $BOTH objdump +data > /dev/null)
+then
+ echo Data ok.
+else
+ echo Data differences.
+# doboth $BOTH objdump +data
+# exit 1
+fi
+
+if (doboth $BOTH objdump +symbols > /dev/null)
+then
+ echo Symbols ok.
+else
+ echo -n Symbol differences...
+
+ if (doboth $BOTH dounsortsymbols)
+ then
+ echo but symbols are simply ordered differently.
+# echo Now what to do about relocs'?'
+# exit 1
+ else
+ echo and symbols differ in content.
+ exit 1
+ fi
+fi
+
+# of course, if there were symbol diffs, then the reloc symbol indexes
+# will be off.
+
+if (doboth $BOTH objdump -r > /dev/null)
+then
+ echo Reloc ok.
+else
+ echo -n Reloc differences...
+
+ if (doboth $BOTH dounsortreloc)
+ then
+ echo but relocs are simply ordered differently.
+ else
+ echo and relocs differ in content.
+ exit 1
+ fi
+fi
+
+exit
+
+# eof
diff --git a/gas/testsuite/lib/dostriptest b/gas/testsuite/lib/dostriptest
new file mode 100755
index 00000000000..3a517015598
--- /dev/null
+++ b/gas/testsuite/lib/dostriptest
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+x=striptest.xx.$$
+y=striptest.yy.$$
+
+cp $1 $x
+strip $x
+cp $2 $y
+strip $y
+
+doobjcmp $x $y
+exit
+
+#eof
diff --git a/gas/testsuite/lib/dotest b/gas/testsuite/lib/dotest
new file mode 100755
index 00000000000..a768a225300
--- /dev/null
+++ b/gas/testsuite/lib/dotest
@@ -0,0 +1,43 @@
+#!/bin/sh
+# ad hoc debug tool
+
+x=$1
+y=$2
+
+xout=`basename $x`.xxx.$$
+yout=`basename $x`.yyy.$$
+
+mkdir $xout
+mkdir $yout
+
+for i in *.s
+do
+ echo Testing $i...
+ object=`basename $i .s`.o
+ $x $i -o $xout/$object
+ $y $i -o $yout/$object
+
+# if they cmp, we're ok. Otherwise we have to look closer.
+
+ if (cmp $xout/$object $yout/$object)
+ then
+ echo $i is ok.
+ else
+ if (doobjcmp $xout/$object $yout/$object)
+ then
+ echo Not the same but objcmp ok.
+ else
+ exit 1
+ fi
+ fi
+
+ echo
+done
+
+rm -rf $xout $yout
+
+exit 0
+
+# EOF
+
+
diff --git a/gas/testsuite/lib/dounsreloc b/gas/testsuite/lib/dounsreloc
new file mode 100755
index 00000000000..0d695338245
--- /dev/null
+++ b/gas/testsuite/lib/dounsreloc
@@ -0,0 +1,8 @@
+#!/bin/sh
+# objdump the reloc table, but strip off the headings and reloc
+# numbers and sort the result. Intended for use in comparing reloc
+# tables that may not be in the same order.
+
+objdump +reloc +omit-relocation-numbers +omit-symbol-numbers $1 \
+ | sort
+#eof
diff --git a/gas/testsuite/lib/dounssym b/gas/testsuite/lib/dounssym
new file mode 100755
index 00000000000..a44da62fb0a
--- /dev/null
+++ b/gas/testsuite/lib/dounssym
@@ -0,0 +1,8 @@
+#!/bin/sh
+# objdump the symbol table, but strip off the headings and symbol
+# numbers and sort the result. Intended for use in comparing symbol
+# tables that may not be in the same order.
+
+objdump +symbols +omit-symbol-numbers $1 \
+ | sort
+#eof
diff --git a/gas/testsuite/lib/gas-defs.exp b/gas/testsuite/lib/gas-defs.exp
new file mode 100644
index 00000000000..757718ffa47
--- /dev/null
+++ b/gas/testsuite/lib/gas-defs.exp
@@ -0,0 +1,574 @@
+# Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# DejaGnu@cygnus.com
+
+# This file was written by Ken Raeburn (raeburn@cygnus.com).
+
+proc gas_version {} {
+ global AS
+ catch "exec $AS -version < /dev/null" tmp
+ # Should find a way to discard constant parts, keep whatever's
+ # left, so the version string could be almost anything at all...
+ regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
+ if ![info exists number] then {
+ return "[which $AS] (no version number)\n"
+ }
+ clone_output "[which $AS] $number\n"
+ unset version
+}
+
+proc gas_run { prog as_opts redir } {
+ global AS
+ global ASFLAGS
+ global comp_output
+ global srcdir
+ global subdir
+ global host_triplet
+
+ verbose "Executing $srcdir/lib/run $AS $ASFLAGS $as_opts $srcdir/$subdir/$prog $redir"
+ catch "exec $srcdir/lib/run $AS $ASFLAGS $as_opts $srcdir/$subdir/$prog $redir" comp_output
+ set comp_output [prune_warnings $comp_output]
+ verbose "output was $comp_output"
+ return [list $comp_output ""];
+}
+
+proc all_ones { args } {
+ foreach x $args { if [expr $x!=1] { return 0 } }
+ return 1
+}
+
+proc gas_start { prog as_opts } {
+ global AS
+ global ASFLAGS
+ global srcdir
+ global subdir
+ global spawn_id
+
+ verbose "Starting $AS $ASFLAGS $as_opts $prog" 2
+ catch {
+ spawn -noecho -nottycopy $srcdir/lib/run $AS $ASFLAGS $as_opts $srcdir/$subdir/$prog
+ } foo
+ if ![regexp {^[0-9]+} $foo] then {
+ perror "Can't run $subdir/$prog: $foo"
+ }
+}
+
+proc gas_finish { } {
+ global spawn_id
+
+ catch "close"
+ catch "wait"
+}
+
+proc want_no_output { testname } {
+ global comp_output
+
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ verbose "$comp_output" 3
+ }
+ if [string match "" $comp_output] then {
+ pass "$testname"
+ return 1
+ } else {
+ fail "$testname"
+ return 0
+ }
+}
+
+proc gas_test_old { file as_opts testname } {
+ gas_run $file $as_opts ""
+ return [want_no_output $testname]
+}
+
+proc gas_test { file as_opts var_opts testname } {
+ global comp_output
+
+ set i 0
+ foreach word $var_opts {
+ set ignore_stdout($i) [string match "*>" $word]
+ set opt($i) [string trim $word {>}]
+ incr i
+ }
+ set max [expr 1<<$i]
+ for {set i 0} {[expr $i<$max]} {incr i} {
+ set maybe_ignore_stdout ""
+ set extra_opts ""
+ for {set bit 0} {(1<<$bit)<$max} {incr bit} {
+ set num [expr 1<<$bit]
+ if [expr $i&$num] then {
+ set extra_opts "$extra_opts $opt($bit)"
+ if $ignore_stdout($bit) then {
+ set maybe_ignore_stdout ">/dev/null"
+ }
+ }
+ }
+ set extra_opts [string trim $extra_opts]
+ gas_run $file "$as_opts $extra_opts" $maybe_ignore_stdout
+
+ # Should I be able to use a conditional expression here?
+ if [string match "" $extra_opts] then {
+ want_no_output $testname
+ } else {
+ want_no_output "$testname ($extra_opts)"
+ }
+ }
+ if [info exists errorInfo] then {
+ unset errorInfo
+ }
+}
+
+proc gas_test_ignore_stdout { file as_opts testname } {
+ global comp_output
+
+ gas_run $file $as_opts ">/dev/null"
+ want_no_output $testname
+}
+
+proc gas_test_error { file as_opts testname } {
+ global comp_output
+
+ gas_run $file $as_opts ">/dev/null"
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ verbose "$comp_output" 3
+ }
+ if [string match "" $comp_output] then {
+ fail "$testname"
+ } else {
+ pass "$testname"
+ }
+}
+
+proc gas_exit {} {}
+
+proc gas_init { args } {
+ global target_cpu
+ global target_cpu_family
+ global target_family
+ global target_vendor
+ global target_os
+ global stdoptlist
+
+ case "$target_cpu" in {
+ "m68???" { set target_cpu_family m68k }
+ "i[34]86" { set target_cpu_family i386 }
+ default { set target_cpu_family $target_cpu }
+ }
+
+ set target_family "$target_cpu_family-$target_vendor-$target_os"
+ set stdoptlist "-a>"
+
+ if ![istarget "*-*-*"] {
+ perror "Target name [istarget] is not a triple."
+ }
+ # Need to return an empty string.
+ return
+}
+
+
+# run_dump_test FILE
+#
+# Assemble a .s file, then run some utility on it and check the output.
+#
+# There should be an assembly language file named FILE.s in the test
+# suite directory, and a pattern file called FILE.d. `run_dump_test'
+# will assemble FILE.s, run some tool like `objdump', `objcopy', or
+# `nm' on the .o file to produce textual output, and then analyze that
+# with regexps. The FILE.d file specifies what program to run, and
+# what to expect in its output.
+#
+# The FILE.d file begins with zero or more option lines, which specify
+# flags to pass to the assembler, the program to run to dump the
+# assembler's output, and the options it wants. The option lines have
+# the syntax:
+#
+# # OPTION: VALUE
+#
+# OPTION is the name of some option, like "name" or "objdump", and
+# VALUE is OPTION's value. The valid options are described below.
+# Whitespace is ignored everywhere, except within VALUE. The option
+# list ends with the first line that doesn't match the above syntax
+# (hmm, not great for error detection).
+#
+# The interesting options are:
+#
+# name: TEST-NAME
+# The name of this test, passed to DejaGNU's `pass' and `fail'
+# commands. If omitted, this defaults to FILE, the root of the
+# .s and .d files' names.
+#
+# as: FLAGS
+# When assembling FILE.s, pass FLAGS to the assembler.
+#
+# PROG: PROGRAM-NAME
+# The name of the program to run to analyze the .o file produced
+# by the assembler. This can be omitted; run_dump_test will guess
+# which program to run by seeing which of the flags options below
+# is present.
+#
+# objdump: FLAGS
+# nm: FLAGS
+# objcopy: FLAGS
+# Use the specified program to analyze the .o file, and pass it
+# FLAGS, in addition to the .o file name.
+#
+# source: SOURCE
+# Assemble the file SOURCE.s. If omitted, this defaults to FILE.s.
+# This is useful if several .d files want to share a .s file.
+#
+# Each option may occur at most once.
+#
+# After the option lines come regexp lines. `run_dump_test' calls
+# `regexp_diff' to compare the output of the dumping tool against the
+# regexps in FILE.d. `regexp_diff' is defined later in this file; see
+# further comments there.
+
+proc run_dump_test { name } {
+ global subdir srcdir
+ global OBJDUMP NM AS OBJCOPY
+ global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS
+ global host_triplet
+
+ if [string match "*/*" $name] {
+ set file $name
+ set name [file tail $name]
+ } else {
+ set file "$srcdir/$subdir/$name"
+ }
+ set opt_array [slurp_options "${file}.d"]
+ if { $opt_array == -1 } {
+ unresolved $subdir/$name
+ return
+ }
+ set opts(as) {}
+ set opts(objdump) {}
+ set opts(nm) {}
+ set opts(objcopy) {}
+ set opts(name) {}
+ set opts(PROG) {}
+ set opts(source) {}
+
+ foreach i $opt_array {
+ set opt_name [lindex $i 0]
+ set opt_val [lindex $i 1]
+ if ![info exists opts($opt_name)] {
+ perror "unknown option $opt_name in file $file.d"
+ unresolved $subdir/$name
+ return
+ }
+ if [string length $opts($opt_name)] {
+ perror "option $opt_name multiply set in $file.d"
+ unresolved $subdir/$name
+ return
+ }
+ set opts($opt_name) $opt_val
+ }
+
+ if {$opts(PROG) != ""} {
+ switch -- $opts(PROG) {
+ objdump
+ { set program objdump }
+ nm
+ { set program nm }
+ objcopy
+ { set program objcopy }
+ default
+ { perror "unrecognized program option $opts(PROG) in $file.d"
+ unresolved $subdir/$name
+ return }
+ }
+ } else {
+ # Guess which program to run, by seeing which option was specified.
+ set program ""
+ foreach p {objdump objcopy nm} {
+ if {$opts($p) != ""} {
+ if {$program != ""} {
+ perror "ambiguous dump program in $file.d"
+ unresolved $subdir/$name
+ return
+ } else {
+ set program $p
+ }
+ }
+ }
+ if {$program == ""} {
+ perror "dump program unspecified in $file.d"
+ unresolved $subdir/$name
+ return
+ }
+ }
+
+ set progopts1 $opts($program)
+ eval set progopts \$[string toupper $program]FLAGS
+ eval set binary \$[string toupper $program]
+ if { $opts(name) == "" } {
+ set testname "$subdir/$name"
+ } else {
+ set testname $opts(name)
+ }
+
+ if { $opts(source) == "" } {
+ set sourcefile ${file}.s
+ } else {
+ set sourcefile $srcdir/$subdir/$opts(source)
+ }
+
+ send_log "$AS $ASFLAGS $opts(as) -o dump.o $sourcefile\n"
+ catch "exec $srcdir/lib/run $AS $ASFLAGS $opts(as) -o dump.o $sourcefile" comp_output
+ set comp_output [prune_warnings $comp_output]
+
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ verbose "$comp_output" 3
+ fail $testname
+ return
+ }
+
+ if { [which $binary] == 0 } {
+ untested $testname
+ return
+ }
+
+ if { $progopts1 == "" } { set $progopts1 "-r" }
+ verbose "running $binary $progopts $progopts1" 3
+
+ # Objcopy, unlike the other two, won't send its output to stdout,
+ # so we have to run it specially.
+ if { $program == "objcopy" } {
+ send_log "$binary $progopts $progopts1 dump.o dump.out\n"
+ catch "exec $binary $progopts $progopts1 dump.o dump.out" comp_output
+ set comp_output [prune_warnings $comp_output]
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ fail $testname
+ return
+ }
+ } else {
+ send_log "$binary $progopts $progopts1 dump.o > dump.out\n"
+ catch "exec $binary $progopts $progopts1 dump.o > dump.out" comp_output
+ set comp_output [prune_warnings $comp_output]
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ fail $testname
+ return
+ }
+ }
+
+ verbose_eval {[file_contents "dump.out"]} 3
+ if { [regexp_diff "dump.out" "${file}.d"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+
+ pass $testname
+}
+
+proc slurp_options { file } {
+ if [catch { set f [open $file r] } x] {
+ #perror "couldn't open `$file': $x"
+ perror "$x"
+ return -1
+ }
+ set opt_array {}
+ # whitespace expression
+ set ws {[ ]*}
+ set nws {[^ ]*}
+ # whitespace is ignored anywhere except within the options list;
+ # option names are alphabetic only
+ set pat "^#${ws}(\[a-zA-Z\]*)$ws:${ws}(.*)$ws\$"
+ while { [gets $f line] != -1 } {
+ set line [string trim $line]
+ # Whitespace here is space-tab.
+ if [regexp $pat $line xxx opt_name opt_val] {
+ # match!
+ lappend opt_array [list $opt_name $opt_val]
+ } else {
+ break
+ }
+ }
+ close $f
+ return $opt_array
+}
+
+proc objdump { opts } {
+ global OBJDUMP
+ global comp_output
+ global host_triplet
+
+ catch "exec $OBJDUMP $opts" comp_output
+ set comp_output [prune_warnings $comp_output]
+ verbose "objdump output=$comp_output\n" 3
+}
+
+proc objdump_start_no_subdir { prog opts } {
+ global OBJDUMP
+ global srcdir
+ global spawn_id
+
+ verbose "Starting $OBJDUMP $opts $prog" 2
+ catch {
+ spawn -noecho -nottyinit $srcdir/lib/run $OBJDUMP $opts $prog
+ } foo
+ if ![regexp {^[0-9]+} $foo] then {
+ perror "Can't run $prog: $foo"
+ }
+}
+
+proc objdump_finish { } {
+ global spawn_id
+
+ catch "close"
+ catch "wait"
+}
+
+# Default timeout is 10 seconds, loses on a slow machine. But some
+# configurations of dejagnu may override it.
+if {$timeout<120} then { set timeout 120 }
+
+expect_after -i {
+ timeout { perror "timeout" }
+ "virtual memory exhausted" { perror "virtual memory exhausted" }
+ buffer_full { perror "buffer full" }
+ eof { perror "eof" }
+}
+
+# regexp_diff, based on simple_diff taken from ld test suite
+# compares two files line-by-line
+# file1 contains strings, file2 contains regexps and #-comments
+# blank lines are ignored in either file
+# returns non-zero if differences exist
+#
+proc regexp_diff { file_1 file_2 } {
+
+ set eof -1
+ set end_1 0
+ set end_2 0
+ set differences 0
+ set diff_pass 0
+
+ if [file exists $file_1] then {
+ set file_a [open $file_1 r]
+ } else {
+ warning "$file_1 doesn't exist"
+ return 1
+ }
+
+ if [file exists $file_2] then {
+ set file_b [open $file_2 r]
+ } else {
+ fail "$file_2 doesn't exist"
+ close $file_a
+ return 1
+ }
+
+ verbose " Regexp-diff'ing: $file_1 $file_2" 2
+
+ while { 1 } {
+ set line_a ""
+ set line_b ""
+ while { [string length $line_a] == 0 } {
+ if { [gets $file_a line_a] == $eof } {
+ set end_1 1
+ break
+ }
+ }
+ while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
+ if [ string match "#pass" $line_b ] {
+ set end_2 1
+ set diff_pass 1
+ break
+ }
+ if { [gets $file_b line_b] == $eof } {
+ set end_2 1
+ break
+ }
+ }
+
+ if { $diff_pass } {
+ break
+ } elseif { $end_1 && $end_2 } {
+ break
+ } elseif { $end_1 } {
+ send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
+ verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
+ set differences 1
+ break
+ } elseif { $end_2 } {
+ send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
+ verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
+ set differences 1
+ break
+ } else {
+ verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
+ if ![regexp "^$line_b$" "$line_a"] {
+ send_log "regexp_diff match failure\n"
+ send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
+ set differences 1
+ break
+ }
+ }
+ }
+
+ if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
+ send_log "$file_1 and $file_2 are different lengths\n"
+ verbose "$file_1 and $file_2 are different lengths" 3
+ set differences 1
+ }
+
+ close $file_a
+ close $file_b
+
+ return $differences
+}
+
+proc file_contents { filename } {
+ set file [open $filename r]
+ set contents [read $file]
+ close $file
+ return $contents
+}
+
+proc verbose_eval { expr { level 1 } } {
+ global verbose
+ if $verbose>$level then { eval verbose "$expr" $level }
+}
+
+# This definition is taken from an unreleased version of DejaGnu. Once
+# that version gets released, and has been out in the world for a few
+# months at least, it may be safe to delete this copy.
+if ![string length [info proc prune_warnings]] {
+ #
+ # prune_warnings -- delete various system verbosities from TEXT.
+ #
+ # An example is:
+ # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
+ #
+ # Sites with particular verbose os's may wish to override this in site.exp.
+ #
+ proc prune_warnings { text } {
+ # This is from sun4's. Do it for all machines for now.
+ # The "\\1" is to try to preserve a "\n" but only if necessary.
+ regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
+
+ # It might be tempting to get carried away and delete blank lines, etc.
+ # Just delete *exactly* what we're ask to, and that's it.
+ return $text
+ }
+}
diff --git a/gas/testsuite/lib/gas-dg.exp b/gas/testsuite/lib/gas-dg.exp
new file mode 100644
index 00000000000..92f7f3136c1
--- /dev/null
+++ b/gas/testsuite/lib/gas-dg.exp
@@ -0,0 +1,53 @@
+# Define gas callbacks for dg.exp.
+
+load_lib dg.exp
+
+# The use of this function is still in a bit of flux.
+# It should be theoretically possible to assemble, link, and run a file
+# but we currently don't support that. Assembler testcases aren't usually
+# that elaborate anyway. :-)
+
+proc gas-dg-test { prog do_what tool_flags } {
+ # FIXME: the gas testsuite doesn't define tmpdir. Use outdir?
+ set output_file "./a.out"
+
+ switch $do_what {
+ "preprocess" {
+ }
+ "assemble" {
+ }
+ "link" {
+ }
+ "run" {
+ # This is the only place where we care if an executable was
+ # created or not. If it was, dg.exp will try to run it.
+ catch "exec rm -f $output_file"
+ }
+ default {
+ perror "$do_what: not a valid dg-do keyword"
+ return ""
+ }
+ }
+
+ # gas_start prepends $srcdir/$subdir so we must remove it from PROG
+ # if present. First remove extraneous //'s.
+ global srcdir subdir
+ set dir "$srcdir/$subdir"
+ regsub -all "//" $dir "/" dir
+ regsub -all "//" $prog "/" prog
+ if [string match "$dir/*" $prog] {
+ regsub "$dir" $prog "" prog
+ }
+
+ # FIXME: This should be gas_start but it doesn't set comp_output.
+ return [gas_run $prog $tool_flags ""]
+}
+
+proc gas-dg-prune { system text } {
+ #send_user "Before:$text\n"
+ regsub -all "(^|\n)\[^\n\]*: Assembler messages:\[^\n\]*" $text "" text
+ regsub -all "(^|\n)\[^\n\]*: End of file not at end\[^\n\]*Newline inserted." $text "" text
+ #send_user "After:$text\n"
+
+ return $text
+}
diff --git a/gas/testsuite/lib/run b/gas/testsuite/lib/run
new file mode 100755
index 00000000000..d4150f8d4ce
--- /dev/null
+++ b/gas/testsuite/lib/run
@@ -0,0 +1,2 @@
+#!/bin/sh
+eval exec $@
diff --git a/gas/vmsconf.sh b/gas/vmsconf.sh
new file mode 100644
index 00000000000..014538a154e
--- /dev/null
+++ b/gas/vmsconf.sh
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+cat << 'EOF'
+$!make-gas.com
+$! Set the def dir to proper place for use in batch. Works for interactive to.
+$flnm = f$enviroment("PROCEDURE") ! get current procedure name
+$set default 'f$parse(flnm,,,"DEVICE")''f$parse(flnm,,,"DIRECTORY")'
+$v = 'f$verify(0)'
+$!
+$! Command file to build a GNU assembler on VMS
+$!
+$! If you are using a version of GCC that supports global constants
+$! you should remove the define="const=" from the gcc lines.
+$!
+$! Caution: Versions 1.38.1 and earlier had a bug in the handling of
+$! some static constants. If you are using such a version of the
+$! assembler, and you wish to compile without the "const=" hack,
+$! you should first build this version *with* the "const="
+$! definition, and then use that assembler to rebuild it without the
+$! "const=" definition. Failure to do this will result in an assembler
+$! that will mung floating point constants.
+$!
+$! Note: The version of gas shipped on the GCC VMS tapes has been patched
+$! to fix the above mentioned bug.
+$!
+$ !The gcc-vms driver was modified to use `-1' quite some time ago,
+$ !so don't echo this text any more...
+$ !write sys$output "If this assembler is going to be used with GCC 1.n, you"
+$ !write sys$output "need to modify the driver to supply the -1 switch to gas."
+$ !write sys$output "This is required because of a small change in how global"
+$ !write sys$output "constant variables are handled. Failure to include this"
+$ !write sys$output "will result in linker warning messages about mismatched
+$ !write sys$output "psect attributes."
+$!
+$ gas_host="vms"
+$ arch_indx = 1 + ((f$getsyi("CPU").ge.128).and.1) ! vax==1, alpha==2
+$ arch = f$element(arch_indx,"|","|VAX|Alpha|")
+$ if arch.eqs."VAX"
+$ then
+$ cpu_type="vax"
+$ obj_format="vms"
+$ atof="vax"
+$ else
+$ cpu_type="alpha"
+$ obj_format="evax"
+$ atof="ieee"
+$ endif
+$ emulation="generic"
+$!
+$ COPY = "copy/noLog"
+$!
+$ C_DEFS :="""VMS"""
+$! C_DEFS :="""VMS""","""const="""
+$ C_INCLUDES = "/Include=([],[.config],[-.include],[-.include.aout])"
+$ C_FLAGS = "/noVerbose/Debug" + c_includes
+$!
+$!
+$ on error then goto bail
+$ if f$search("[-.libiberty]liberty.olb").eqs.""
+$ then @[-.libiberty]vmsbuild.com
+$ write sys$output "Now building gas."
+$ endif
+$ if "''p1'" .eqs. "LINK" then goto Link
+$!
+$! This helps gcc 1.nn find the aout/* files.
+$!
+$ aout_dev = f$parse(flnm,,,"DEVICE")
+$ tmp = aout_dev - ":"
+$if f$trnlnm(tmp).nes."" then aout_dev = f$trnlnm(tmp)
+$ aout_dir = aout_dev+f$parse(flnm,,,"DIRECTORY")' -
+ - "GAS]" + "INCLUDE.AOUT.]" - "]["
+$assign 'aout_dir' aout/tran=conc
+$ opcode_dir = aout_dev+f$parse(flnm,,,"DIRECTORY")' -
+ - "GAS]" + "INCLUDE.OPCODE.]" - "]["
+$assign 'opcode_dir' opcode/tran=conc
+$!
+$ set verify
+$!
+$ gcc 'c_flags'/Define=('C_DEFS')/Object=[]tc-'cpu_type'.obj [.config]tc-'cpu_type'.c
+$ gcc 'c_flags'/Define=('C_DEFS')/Object=[]obj-'obj_format'.obj [.config]obj-'obj_format'.c
+$ gcc 'c_flags'/Define=('C_DEFS')/Object=[]atof-'atof'.obj [.config]atof-'atof'.c
+EOF
+
+cfiles="`echo $* | sed -e 's/\.o/.c/g' -e 's!../\([^ /]*\)/\([^ /]*\.c\)![-.\1]\2!g'`"
+
+for cfile in $cfiles ; do
+ case $cfile in
+ "[-."*)
+ base=`echo $cfile | sed -e 's/\[.*\]//' -e 's/\.c$//'`
+ echo "\$ gcc 'c_flags'/Define=('C_DEFS')/Object=[]$base.obj $cfile"
+ ;;
+ *)
+ echo "\$ gcc 'c_flags'/Define=('C_DEFS') $cfile"
+ ;;
+ esac
+done
+
+cat << 'EOF'
+$link:
+$!'f$verify(0)'
+$ if f$trnlnm("IFILE$").nes."" then close/noLog ifile$
+$ create gcc-as.opt
+!
+! Linker options file for GNU assembler
+!
+$ open/Append ifile$ gcc-as.opt
+$ write ifile$ "tc-''cpu_type'.obj"
+$ write ifile$ "obj-''obj_format'.obj"
+$ write ifile$ "atof-''atof'.obj"
+$ COPY sys$input: ifile$:
+EOF
+
+for obj in $* ; do
+ # Change "foo.o" into "foo.obj".
+ echo ${obj}bj,- | sed 's!.*/!!g'
+done
+
+cat << 'EOF'
+[-.libiberty]liberty.olb/Lib
+gnu_cc:[000000]gcclib.olb/Lib,sys$library:vaxcrtl.olb/Lib
+! Tell linker exactly what psect attributes we want -- match VAXCRTL.
+psect_attr=ENVIRON,long,pic,ovr,rel,gbl,noshr,noexe,rd,wrt
+$ close ifile$
+$ set verify=(Proc,noImag)
+$ link/noMap/Exec=gcc-as.exe gcc-as.opt/Opt,version.opt/Opt
+$!
+$bail: exit $status + 0*f$verify(v) !'f$verify(0)'
+EOF
diff --git a/gas/write.c b/gas/write.c
new file mode 100644
index 00000000000..18e6e103f94
--- /dev/null
+++ b/gas/write.c
@@ -0,0 +1,2884 @@
+/* write.c - emit .o file
+ Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* This thing should be set up to do byteordering correctly. But... */
+
+#include "as.h"
+#include "subsegs.h"
+#include "obstack.h"
+#include "output-file.h"
+
+/* This looks like a good idea. Let's try turning it on always, for now. */
+#undef BFD_FAST_SECTION_FILL
+#define BFD_FAST_SECTION_FILL
+
+/* The NOP_OPCODE is for the alignment fill value. Fill it with a nop
+ instruction so that the disassembler does not choke on it. */
+#ifndef NOP_OPCODE
+#define NOP_OPCODE 0x00
+#endif
+
+#ifndef TC_ADJUST_RELOC_COUNT
+#define TC_ADJUST_RELOC_COUNT(FIXP,COUNT)
+#endif
+
+#ifndef TC_FORCE_RELOCATION
+#define TC_FORCE_RELOCATION(FIXP) 0
+#endif
+
+#ifndef TC_FORCE_RELOCATION_SECTION
+#define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) TC_FORCE_RELOCATION(FIXP)
+#endif
+
+#ifndef MD_PCREL_FROM_SECTION
+#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from(FIXP)
+#endif
+
+#ifndef WORKING_DOT_WORD
+extern CONST int md_short_jump_size;
+extern CONST int md_long_jump_size;
+#endif
+
+int symbol_table_frozen;
+void print_fixup PARAMS ((fixS *));
+
+#ifdef BFD_ASSEMBLER
+static void renumber_sections PARAMS ((bfd *, asection *, PTR));
+
+/* We generally attach relocs to frag chains. However, after we have
+ chained these all together into a segment, any relocs we add after
+ that must be attached to a segment. This will include relocs added
+ in md_estimate_size_for_relax, for example. */
+static int frags_chained = 0;
+#endif
+
+#ifndef BFD_ASSEMBLER
+
+#ifndef MANY_SEGMENTS
+struct frag *text_frag_root;
+struct frag *data_frag_root;
+struct frag *bss_frag_root;
+
+struct frag *text_last_frag; /* Last frag in segment. */
+struct frag *data_last_frag; /* Last frag in segment. */
+static struct frag *bss_last_frag; /* Last frag in segment. */
+#endif
+
+#ifndef BFD
+static object_headers headers;
+#endif
+
+long string_byte_count;
+char *next_object_file_charP; /* Tracks object file bytes. */
+
+#ifndef OBJ_VMS
+int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;
+#endif
+
+#endif /* BFD_ASSEMBLER */
+
+static int n_fixups;
+
+#ifdef BFD_ASSEMBLER
+static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
+ symbolS *add, symbolS *sub,
+ offsetT offset, int pcrel,
+ bfd_reloc_code_real_type r_type));
+#else
+static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
+ symbolS *add, symbolS *sub,
+ offsetT offset, int pcrel,
+ int r_type));
+#endif
+#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
+static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
+#endif
+static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
+#if defined (BFD_ASSEMBLER) || ! defined (BFD)
+static fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *));
+#endif
+#ifdef BFD_ASSEMBLER
+static void chain_frchains_together PARAMS ((bfd *, segT, PTR));
+static void cvt_frag_to_fill PARAMS ((segT, fragS *));
+static void relax_and_size_seg PARAMS ((bfd *, asection *, PTR));
+static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR));
+static void write_relocs PARAMS ((bfd *, asection *, PTR));
+static void write_contents PARAMS ((bfd *, asection *, PTR));
+static void set_symtab PARAMS ((void));
+#endif
+#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))
+static void merge_data_into_text PARAMS ((void));
+#endif
+#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
+static void cvt_frag_to_fill PARAMS ((object_headers *, segT, fragS *));
+static void remove_subsegs PARAMS ((frchainS *, int, fragS **, fragS **));
+static void relax_and_size_all_segments PARAMS ((void));
+#endif
+
+/*
+ * fix_new()
+ *
+ * Create a fixS in obstack 'notes'.
+ */
+static fixS *
+fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
+ r_type)
+ fragS *frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ int size; /* 1, 2, or 4 usually. */
+ symbolS *add_symbol; /* X_add_symbol. */
+ symbolS *sub_symbol; /* X_op_symbol. */
+ offsetT offset; /* X_add_number. */
+ int pcrel; /* TRUE if PC-relative relocation. */
+#ifdef BFD_ASSEMBLER
+ bfd_reloc_code_real_type r_type; /* Relocation type */
+#else
+ int r_type; /* Relocation type */
+#endif
+{
+ fixS *fixP;
+
+ n_fixups++;
+
+ fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
+
+ fixP->fx_frag = frag;
+ fixP->fx_where = where;
+ fixP->fx_size = size;
+ /* We've made fx_size a narrow field; check that it's wide enough. */
+ if (fixP->fx_size != size)
+ {
+ as_bad (_("field fx_size too small to hold %d"), size);
+ abort ();
+ }
+ fixP->fx_addsy = add_symbol;
+ fixP->fx_subsy = sub_symbol;
+ fixP->fx_offset = offset;
+ fixP->fx_pcrel = pcrel;
+ fixP->fx_plt = 0;
+#if defined(NEED_FX_R_TYPE) || defined (BFD_ASSEMBLER)
+ fixP->fx_r_type = r_type;
+#endif
+ fixP->fx_im_disp = 0;
+ fixP->fx_pcrel_adjust = 0;
+ fixP->fx_bit_fixP = 0;
+ fixP->fx_addnumber = 0;
+ fixP->fx_tcbit = 0;
+ fixP->fx_done = 0;
+ fixP->fx_no_overflow = 0;
+ fixP->fx_signed = 0;
+
+#ifdef USING_CGEN
+ fixP->fx_cgen.insn = NULL;
+ fixP->fx_cgen.opinfo = 0;
+#endif
+
+#ifdef TC_FIX_TYPE
+ TC_INIT_FIX_DATA(fixP);
+#endif
+
+ as_where (&fixP->fx_file, &fixP->fx_line);
+
+ /* Usually, we want relocs sorted numerically, but while
+ comparing to older versions of gas that have relocs
+ reverse sorted, it is convenient to have this compile
+ time option. xoxorich. */
+
+ {
+
+#ifdef BFD_ASSEMBLER
+ fixS **seg_fix_rootP = (frags_chained
+ ? &seg_info (now_seg)->fix_root
+ : &frchain_now->fix_root);
+ fixS **seg_fix_tailP = (frags_chained
+ ? &seg_info (now_seg)->fix_tail
+ : &frchain_now->fix_tail);
+#endif
+
+#ifdef REVERSE_SORT_RELOCS
+
+ fixP->fx_next = *seg_fix_rootP;
+ *seg_fix_rootP = fixP;
+
+#else /* REVERSE_SORT_RELOCS */
+
+ fixP->fx_next = NULL;
+
+ if (*seg_fix_tailP)
+ (*seg_fix_tailP)->fx_next = fixP;
+ else
+ *seg_fix_rootP = fixP;
+ *seg_fix_tailP = fixP;
+
+#endif /* REVERSE_SORT_RELOCS */
+
+ }
+
+ return fixP;
+}
+
+/* Create a fixup relative to a symbol (plus a constant). */
+
+fixS *
+fix_new (frag, where, size, add_symbol, offset, pcrel, r_type)
+ fragS *frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ int size; /* 1, 2, or 4 usually. */
+ symbolS *add_symbol; /* X_add_symbol. */
+ offsetT offset; /* X_add_number. */
+ int pcrel; /* TRUE if PC-relative relocation. */
+#ifdef BFD_ASSEMBLER
+ bfd_reloc_code_real_type r_type; /* Relocation type */
+#else
+ int r_type; /* Relocation type */
+#endif
+{
+ return fix_new_internal (frag, where, size, add_symbol,
+ (symbolS *) NULL, offset, pcrel, r_type);
+}
+
+/* Create a fixup for an expression. Currently we only support fixups
+ for difference expressions. That is itself more than most object
+ file formats support anyhow. */
+
+fixS *
+fix_new_exp (frag, where, size, exp, pcrel, r_type)
+ fragS *frag; /* Which frag? */
+ int where; /* Where in that frag? */
+ int size; /* 1, 2, or 4 usually. */
+ expressionS *exp; /* Expression. */
+ int pcrel; /* TRUE if PC-relative relocation. */
+#ifdef BFD_ASSEMBLER
+ bfd_reloc_code_real_type r_type; /* Relocation type */
+#else
+ int r_type; /* Relocation type */
+#endif
+{
+ symbolS *add = NULL;
+ symbolS *sub = NULL;
+ offsetT off = 0;
+
+ switch (exp->X_op)
+ {
+ case O_absent:
+ break;
+
+ case O_add:
+ /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
+ the difference expression cannot immediately be reduced. */
+ {
+ symbolS *stmp = make_expr_symbol (exp);
+ exp->X_op = O_symbol;
+ exp->X_op_symbol = 0;
+ exp->X_add_symbol = stmp;
+ exp->X_add_number = 0;
+ return fix_new_exp (frag, where, size, exp, pcrel, r_type);
+ }
+
+ case O_symbol_rva:
+ add = exp->X_add_symbol;
+ off = exp->X_add_number;
+
+#if defined(BFD_ASSEMBLER)
+ r_type = BFD_RELOC_RVA;
+#else
+#if defined(TC_RVA_RELOC)
+ r_type = TC_RVA_RELOC;
+#else
+ as_fatal(_("rva not supported"));
+#endif
+#endif
+ break;
+
+ case O_uminus:
+ sub = exp->X_add_symbol;
+ off = exp->X_add_number;
+ break;
+
+ case O_subtract:
+ sub = exp->X_op_symbol;
+ /* Fall through. */
+ case O_symbol:
+ add = exp->X_add_symbol;
+ /* Fall through. */
+ case O_constant:
+ off = exp->X_add_number;
+ break;
+
+ default:
+ add = make_expr_symbol (exp);
+ break;
+ }
+
+ return fix_new_internal (frag, where, size, add, sub, off,
+ pcrel, r_type);
+}
+
+/* Append a string onto another string, bumping the pointer along. */
+void
+append (charPP, fromP, length)
+ char **charPP;
+ char *fromP;
+ unsigned long length;
+{
+ /* Don't trust memcpy() of 0 chars. */
+ if (length == 0)
+ return;
+
+ memcpy (*charPP, fromP, length);
+ *charPP += length;
+}
+
+#ifndef BFD_ASSEMBLER
+int section_alignment[SEG_MAXIMUM_ORDINAL];
+#endif
+
+/*
+ * This routine records the largest alignment seen for each segment.
+ * If the beginning of the segment is aligned on the worst-case
+ * boundary, all of the other alignments within it will work. At
+ * least one object format really uses this info.
+ */
+void
+record_alignment (seg, align)
+ /* Segment to which alignment pertains */
+ segT seg;
+ /* Alignment, as a power of 2 (e.g., 1 => 2-byte boundary, 2 => 4-byte
+ boundary, etc.) */
+ int align;
+{
+ if (seg == absolute_section)
+ return;
+#ifdef BFD_ASSEMBLER
+ if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg))
+ bfd_set_section_alignment (stdoutput, seg, align);
+#else
+ if (align > section_alignment[(int) seg])
+ section_alignment[(int) seg] = align;
+#endif
+}
+
+#ifdef BFD_ASSEMBLER
+
+/* Reset the section indices after removing the gas created sections. */
+
+static void
+renumber_sections (abfd, sec, countparg)
+ bfd *abfd;
+ asection *sec;
+ PTR countparg;
+{
+ int *countp = (int *) countparg;
+
+ sec->index = *countp;
+ ++*countp;
+}
+
+#endif /* defined (BFD_ASSEMBLER) */
+
+#if defined (BFD_ASSEMBLER) || ! defined (BFD)
+
+static fragS *
+chain_frchains_together_1 (section, frchp)
+ segT section;
+ struct frchain *frchp;
+{
+ fragS dummy, *prev_frag = &dummy;
+#ifdef BFD_ASSEMBLER
+ fixS fix_dummy, *prev_fix = &fix_dummy;
+#endif
+
+ for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)
+ {
+ prev_frag->fr_next = frchp->frch_root;
+ prev_frag = frchp->frch_last;
+ assert (prev_frag->fr_type != 0);
+#ifdef BFD_ASSEMBLER
+ if (frchp->fix_root != (fixS *) NULL)
+ {
+ if (seg_info (section)->fix_root == (fixS *) NULL)
+ seg_info (section)->fix_root = frchp->fix_root;
+ prev_fix->fx_next = frchp->fix_root;
+ seg_info (section)->fix_tail = frchp->fix_tail;
+ prev_fix = frchp->fix_tail;
+ }
+#endif
+ }
+ assert (prev_frag->fr_type != 0);
+ prev_frag->fr_next = 0;
+ return prev_frag;
+}
+
+#endif
+
+#ifdef BFD_ASSEMBLER
+
+static void
+chain_frchains_together (abfd, section, xxx)
+ bfd *abfd; /* unused */
+ segT section;
+ PTR xxx; /* unused */
+{
+ segment_info_type *info;
+
+ /* BFD may have introduced its own sections without using
+ subseg_new, so it is possible that seg_info is NULL. */
+ info = seg_info (section);
+ if (info != (segment_info_type *) NULL)
+ info->frchainP->frch_last
+ = chain_frchains_together_1 (section, info->frchainP);
+
+ /* Now that we've chained the frags together, we must add new fixups
+ to the segment, not to the frag chain. */
+ frags_chained = 1;
+}
+
+#endif
+
+#if !defined (BFD) && !defined (BFD_ASSEMBLER)
+
+static void
+remove_subsegs (head, seg, root, last)
+ frchainS *head;
+ int seg;
+ fragS **root;
+ fragS **last;
+{
+ *root = head->frch_root;
+ *last = chain_frchains_together_1 (seg, head);
+}
+
+#endif /* BFD */
+
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
+#ifdef BFD_ASSEMBLER
+static void
+cvt_frag_to_fill (sec, fragP)
+ segT sec;
+ fragS *fragP;
+#else
+static void
+cvt_frag_to_fill (headersP, sec, fragP)
+ object_headers *headersP;
+ segT sec;
+ fragS *fragP;
+#endif
+{
+ switch (fragP->fr_type)
+ {
+ case rs_align:
+ case rs_align_code:
+ case rs_org:
+ case rs_space:
+#ifdef HANDLE_ALIGN
+ HANDLE_ALIGN (fragP);
+#endif
+ know (fragP->fr_next != NULL);
+ fragP->fr_offset = (fragP->fr_next->fr_address
+ - fragP->fr_address
+ - fragP->fr_fix) / fragP->fr_var;
+ if (fragP->fr_offset < 0)
+ {
+ as_bad (_("attempt to .org/.space backwards? (%ld)"),
+ (long) fragP->fr_offset);
+ }
+ fragP->fr_type = rs_fill;
+ break;
+
+ case rs_fill:
+ break;
+
+ case rs_leb128:
+ {
+ valueT value = S_GET_VALUE (fragP->fr_symbol);
+ int size;
+
+ size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value,
+ fragP->fr_subtype);
+
+ fragP->fr_fix += size;
+ fragP->fr_type = rs_fill;
+ fragP->fr_var = 0;
+ fragP->fr_offset = 0;
+ fragP->fr_symbol = NULL;
+ }
+ break;
+
+ case rs_cfa:
+ eh_frame_convert_frag (fragP);
+ break;
+
+ case rs_machine_dependent:
+#ifdef BFD_ASSEMBLER
+ md_convert_frag (stdoutput, sec, fragP);
+#else
+ md_convert_frag (headersP, sec, fragP);
+#endif
+
+ assert (fragP->fr_next == NULL
+ || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
+ == fragP->fr_fix));
+
+ /*
+ * After md_convert_frag, we make the frag into a ".space 0".
+ * Md_convert_frag() should set up any fixSs and constants
+ * required.
+ */
+ frag_wane (fragP);
+ break;
+
+#ifndef WORKING_DOT_WORD
+ case rs_broken_word:
+ {
+ struct broken_word *lie;
+
+ if (fragP->fr_subtype)
+ {
+ fragP->fr_fix += md_short_jump_size;
+ for (lie = (struct broken_word *) (fragP->fr_symbol);
+ lie && lie->dispfrag == fragP;
+ lie = lie->next_broken_word)
+ if (lie->added == 1)
+ fragP->fr_fix += md_long_jump_size;
+ }
+ frag_wane (fragP);
+ }
+ break;
+#endif
+
+ default:
+ BAD_CASE (fragP->fr_type);
+ break;
+ }
+}
+
+#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+
+#ifdef BFD_ASSEMBLER
+static void
+relax_and_size_seg (abfd, sec, xxx)
+ bfd *abfd;
+ asection *sec;
+ PTR xxx;
+{
+ flagword flags;
+ fragS *fragp;
+ segment_info_type *seginfo;
+ int x;
+ valueT size, newsize;
+
+ subseg_change (sec, 0);
+
+ flags = bfd_get_section_flags (abfd, sec);
+
+ seginfo = seg_info (sec);
+ if (seginfo && seginfo->frchainP)
+ {
+ relax_segment (seginfo->frchainP->frch_root, sec);
+ for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
+ cvt_frag_to_fill (sec, fragp);
+ for (fragp = seginfo->frchainP->frch_root;
+ fragp->fr_next;
+ fragp = fragp->fr_next)
+ /* walk to last elt */;
+ size = fragp->fr_address + fragp->fr_fix;
+ }
+ else
+ size = 0;
+
+ if (size > 0 && ! seginfo->bss)
+ flags |= SEC_HAS_CONTENTS;
+
+ /* @@ This is just an approximation. */
+ if (seginfo && seginfo->fix_root)
+ flags |= SEC_RELOC;
+ else
+ flags &= ~SEC_RELOC;
+ x = bfd_set_section_flags (abfd, sec, flags);
+ assert (x == true);
+
+ newsize = md_section_align (sec, size);
+ x = bfd_set_section_size (abfd, sec, newsize);
+ assert (x == true);
+
+ /* If the size had to be rounded up, add some padding in the last
+ non-empty frag. */
+ assert (newsize >= size);
+ if (size != newsize)
+ {
+ fragS *last = seginfo->frchainP->frch_last;
+ fragp = seginfo->frchainP->frch_root;
+ while (fragp->fr_next != last)
+ fragp = fragp->fr_next;
+ last->fr_address = size;
+ fragp->fr_offset += newsize - size;
+ }
+
+#ifdef tc_frob_section
+ tc_frob_section (sec);
+#endif
+#ifdef obj_frob_section
+ obj_frob_section (sec);
+#endif
+}
+
+#ifdef DEBUG2
+static void
+dump_section_relocs (abfd, sec, stream_)
+ bfd *abfd;
+ asection *sec;
+ char *stream_;
+{
+ FILE *stream = (FILE *) stream_;
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp = seginfo->fix_root;
+
+ if (!fixp)
+ return;
+
+ fprintf (stream, "sec %s relocs:\n", sec->name);
+ while (fixp)
+ {
+ symbolS *s = fixp->fx_addsy;
+ if (s)
+ {
+ fprintf (stream, " %08x: %s(%s", fixp, S_GET_NAME (s),
+ s->bsym->section->name);
+ if (s->bsym->flags & BSF_SECTION_SYM)
+ {
+ fprintf (stream, " section sym");
+ if (S_GET_VALUE (s))
+ fprintf (stream, "+%x", S_GET_VALUE (s));
+ }
+ else
+ fprintf (stream, "+%x", S_GET_VALUE (s));
+ fprintf (stream, ")+%x\n", fixp->fx_offset);
+ }
+ else
+ fprintf (stream, " %08x: type %d no sym\n", fixp, fixp->fx_r_type);
+ fixp = fixp->fx_next;
+ }
+}
+#else
+#define dump_section_relocs(ABFD,SEC,STREAM) ((void) 0)
+#endif
+
+#ifndef EMIT_SECTION_SYMBOLS
+#define EMIT_SECTION_SYMBOLS 1
+#endif
+
+static void
+adjust_reloc_syms (abfd, sec, xxx)
+ bfd *abfd;
+ asection *sec;
+ PTR xxx;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp;
+
+ if (seginfo == NULL)
+ return;
+
+ dump_section_relocs (abfd, sec, stderr);
+
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ if (fixp->fx_done)
+ /* ignore it */;
+ else if (fixp->fx_addsy)
+ {
+ symbolS *sym;
+ asection *symsec;
+
+#ifdef DEBUG5
+ fprintf (stderr, "\n\nadjusting fixup:\n");
+ print_fixup (fixp);
+#endif
+
+ sym = fixp->fx_addsy;
+
+ /* All symbols should have already been resolved at this
+ point. It is possible to see unresolved expression
+ symbols, though, since they are not in the regular symbol
+ table. */
+ if (sym != NULL && ! sym->sy_resolved)
+ resolve_symbol_value (sym, 1);
+
+ if (fixp->fx_subsy != NULL && ! fixp->fx_subsy->sy_resolved)
+ resolve_symbol_value (fixp->fx_subsy, 1);
+
+ /* If this symbol is equated to an undefined symbol, convert
+ the fixup to being against that symbol. */
+ if (sym != NULL && sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ {
+ fixp->fx_offset += sym->sy_value.X_add_number;
+ sym = sym->sy_value.X_add_symbol;
+ fixp->fx_addsy = sym;
+ }
+
+ if (sym != NULL && sym->sy_mri_common)
+ {
+ /* These symbols are handled specially in fixup_segment. */
+ goto done;
+ }
+
+ symsec = S_GET_SEGMENT (sym);
+
+ if (symsec == NULL)
+ abort ();
+
+ if (bfd_is_abs_section (symsec))
+ {
+ /* The fixup_segment routine will not use this symbol in a
+ relocation unless TC_FORCE_RELOCATION returns 1. */
+ if (TC_FORCE_RELOCATION (fixp))
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+#ifdef UNDEFINED_DIFFERENCE_OK
+ if (fixp->fx_subsy != NULL)
+ fixp->fx_subsy->sy_used_in_reloc = 1;
+#endif
+ }
+ goto done;
+ }
+
+ /* If it's one of these sections, assume the symbol is
+ definitely going to be output. The code in
+ md_estimate_size_before_relax in tc-mips.c uses this test
+ as well, so if you change this code you should look at that
+ code. */
+ if (bfd_is_und_section (symsec)
+ || bfd_is_com_section (symsec))
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+#ifdef UNDEFINED_DIFFERENCE_OK
+ /* We have the difference of an undefined symbol and some
+ other symbol. Make sure to mark the other symbol as used
+ in a relocation so that it will always be output. */
+ if (fixp->fx_subsy)
+ fixp->fx_subsy->sy_used_in_reloc = 1;
+#endif
+ goto done;
+ }
+
+ /* Don't try to reduce relocs which refer to .linkonce
+ sections. It can lead to confusion when a debugging
+ section refers to a .linkonce section. I hope this will
+ always be correct. */
+ if (symsec != sec)
+ {
+ boolean linkonce;
+
+ linkonce = false;
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE)
+ != 0)
+ linkonce = true;
+#endif
+#ifdef OBJ_ELF
+ /* The GNU toolchain uses an extension for ELF: a section
+ beginning with the magic string .gnu.linkonce is a
+ linkonce section. */
+ if (strncmp (segment_name (symsec), ".gnu.linkonce",
+ sizeof ".gnu.linkonce" - 1) == 0)
+ linkonce = true;
+#endif
+
+ if (linkonce)
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+#ifdef UNDEFINED_DIFFERENCE_OK
+ if (fixp->fx_subsy != NULL)
+ fixp->fx_subsy->sy_used_in_reloc = 1;
+#endif
+ goto done;
+ }
+ }
+
+ /* Since we're reducing to section symbols, don't attempt to reduce
+ anything that's already using one. */
+ if (sym->bsym->flags & BSF_SECTION_SYM)
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ goto done;
+ }
+
+#ifdef BFD_ASSEMBLER
+ /* We can never adjust a reloc against a weak symbol. If we
+ did, and the weak symbol was overridden by a real symbol
+ somewhere else, then our relocation would be pointing at
+ the wrong area of memory. */
+ if (S_IS_WEAK (sym))
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ goto done;
+ }
+#endif
+
+ /* Is there some other reason we can't adjust this one? (E.g.,
+ call/bal links in i960-bout symbols.) */
+#ifdef obj_fix_adjustable
+ if (! obj_fix_adjustable (fixp))
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ goto done;
+ }
+#endif
+
+ /* Is there some other (target cpu dependent) reason we can't adjust
+ this one? (E.g. relocations involving function addresses on
+ the PA. */
+#ifdef tc_fix_adjustable
+ if (! tc_fix_adjustable (fixp))
+ {
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+ goto done;
+ }
+#endif
+
+ /* If the section symbol isn't going to be output, the relocs
+ at least should still work. If not, figure out what to do
+ when we run into that case.
+
+ We refetch the segment when calling section_symbol, rather
+ than using symsec, because S_GET_VALUE may wind up changing
+ the section when it calls resolve_symbol_value. */
+ fixp->fx_offset += S_GET_VALUE (sym);
+ fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
+ fixp->fx_addsy->sy_used_in_reloc = 1;
+
+ done:
+ ;
+ }
+#if 1/*def RELOC_REQUIRES_SYMBOL*/
+ else
+ {
+ /* There was no symbol required by this relocation. However,
+ BFD doesn't really handle relocations without symbols well.
+ (At least, the COFF support doesn't.) So for now we fake up
+ a local symbol in the absolute section. */
+
+ fixp->fx_addsy = section_symbol (absolute_section);
+/* fixp->fx_addsy->sy_used_in_reloc = 1; */
+ }
+#endif
+
+ dump_section_relocs (abfd, sec, stderr);
+}
+
+static void
+write_relocs (abfd, sec, xxx)
+ bfd *abfd;
+ asection *sec;
+ PTR xxx;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ int i;
+ unsigned int n;
+ arelent **relocs;
+ fixS *fixp;
+ char *err;
+
+ /* If seginfo is NULL, we did not create this section; don't do
+ anything with it. */
+ if (seginfo == NULL)
+ return;
+
+ fixup_segment (seginfo->fix_root, sec);
+
+ n = 0;
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ n++;
+
+#ifndef RELOC_EXPANSION_POSSIBLE
+ /* Set up reloc information as well. */
+ relocs = (arelent **) xmalloc (n * sizeof (arelent *));
+ memset ((char*)relocs, 0, n * sizeof (arelent*));
+
+ i = 0;
+ for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
+ {
+ arelent *reloc;
+ bfd_reloc_status_type s;
+ symbolS *sym;
+
+ if (fixp->fx_done)
+ {
+ n--;
+ continue;
+ }
+
+ /* If this is an undefined symbol which was equated to another
+ symbol, then use generate the reloc against the latter symbol
+ rather than the former. */
+ sym = fixp->fx_addsy;
+ while (sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ {
+ symbolS *n;
+
+ /* We must avoid looping, as that can occur with a badly
+ written program. */
+ n = sym->sy_value.X_add_symbol;
+ if (n == sym)
+ break;
+ fixp->fx_offset += sym->sy_value.X_add_number;
+ sym = n;
+ }
+ fixp->fx_addsy = sym;
+
+ reloc = tc_gen_reloc (sec, fixp);
+ if (!reloc)
+ {
+ n--;
+ continue;
+ }
+
+#if 0
+ /* This test is triggered inappropriately for the SH. */
+ if (fixp->fx_where + fixp->fx_size
+ > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+ abort ();
+#endif
+
+ s = bfd_install_relocation (stdoutput, reloc,
+ fixp->fx_frag->fr_literal,
+ fixp->fx_frag->fr_address,
+ sec, &err);
+ switch (s)
+ {
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation overflow"));
+ break;
+ case bfd_reloc_outofrange:
+ as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation out of range"));
+ break;
+ default:
+ as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
+ fixp->fx_file, fixp->fx_line, s);
+ }
+ relocs[i++] = reloc;
+ }
+#else
+ n = n * MAX_RELOC_EXPANSION;
+ /* Set up reloc information as well. */
+ relocs = (arelent **) xmalloc (n * sizeof (arelent *));
+
+ i = 0;
+ for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
+ {
+ arelent **reloc;
+ char *data;
+ bfd_reloc_status_type s;
+ symbolS *sym;
+ int j;
+
+ if (fixp->fx_done)
+ {
+ n--;
+ continue;
+ }
+
+ /* If this is an undefined symbol which was equated to another
+ symbol, then use generate the reloc against the latter symbol
+ rather than the former. */
+ sym = fixp->fx_addsy;
+ while (sym->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+ sym = sym->sy_value.X_add_symbol;
+ fixp->fx_addsy = sym;
+
+ reloc = tc_gen_reloc (sec, fixp);
+
+ for (j = 0; reloc[j]; j++)
+ {
+ relocs[i++] = reloc[j];
+ assert(i <= n);
+ }
+ data = fixp->fx_frag->fr_literal + fixp->fx_where;
+ if (fixp->fx_where + fixp->fx_size
+ > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal error: fixup not contained within frag"));
+ for (j = 0; reloc[j]; j++)
+ {
+ s = bfd_install_relocation (stdoutput, reloc[j],
+ fixp->fx_frag->fr_literal,
+ fixp->fx_frag->fr_address,
+ sec, &err);
+ switch (s)
+ {
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_overflow:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("relocation overflow"));
+ break;
+ default:
+ as_fatal (_("%s:%u: bad return from bfd_install_relocation"),
+ fixp->fx_file, fixp->fx_line);
+ }
+ }
+ }
+ n = i;
+#endif
+
+#ifdef DEBUG4
+ {
+ int i, j, nsyms;
+ asymbol **sympp;
+ sympp = bfd_get_outsymbols (stdoutput);
+ nsyms = bfd_get_symcount (stdoutput);
+ for (i = 0; i < n; i++)
+ if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
+ {
+ for (j = 0; j < nsyms; j++)
+ if (sympp[j] == *relocs[i]->sym_ptr_ptr)
+ break;
+ if (j == nsyms)
+ abort ();
+ }
+ }
+#endif
+
+ if (n)
+ bfd_set_reloc (stdoutput, sec, relocs, n);
+ else
+ bfd_set_section_flags (abfd, sec,
+ (bfd_get_section_flags (abfd, sec)
+ & (flagword) ~SEC_RELOC));
+
+#ifdef DEBUG3
+ {
+ int i;
+ arelent *r;
+ asymbol *s;
+ fprintf (stderr, "relocs for sec %s\n", sec->name);
+ for (i = 0; i < n; i++)
+ {
+ r = relocs[i];
+ s = *r->sym_ptr_ptr;
+ fprintf (stderr, " reloc %2d @%08x off %4x : sym %-10s addend %x\n",
+ i, r, r->address, s->name, r->addend);
+ }
+ }
+#endif
+}
+
+static void
+write_contents (abfd, sec, xxx)
+ bfd *abfd;
+ asection *sec;
+ PTR xxx;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ unsigned long offset = 0;
+ fragS *f;
+
+ /* Write out the frags. */
+ if (seginfo == NULL
+ || ! (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
+ return;
+
+ for (f = seginfo->frchainP->frch_root;
+ f;
+ f = f->fr_next)
+ {
+ int x;
+ unsigned long fill_size;
+ char *fill_literal;
+ long count;
+
+ assert (f->fr_type == rs_fill);
+ if (f->fr_fix)
+ {
+ x = bfd_set_section_contents (stdoutput, sec,
+ f->fr_literal, (file_ptr) offset,
+ (bfd_size_type) f->fr_fix);
+ if (x == false)
+ {
+ bfd_perror (stdoutput->filename);
+ as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
+ exit (EXIT_FAILURE);
+ }
+ offset += f->fr_fix;
+ }
+ fill_literal = f->fr_literal + f->fr_fix;
+ fill_size = f->fr_var;
+ count = f->fr_offset;
+ assert (count >= 0);
+ if (fill_size && count)
+ {
+ char buf[256];
+ if (fill_size > sizeof(buf))
+ {
+ /* Do it the old way. Can this ever happen? */
+ while (count--)
+ {
+ x = bfd_set_section_contents (stdoutput, sec,
+ fill_literal,
+ (file_ptr) offset,
+ (bfd_size_type) fill_size);
+ if (x == false)
+ {
+ bfd_perror (stdoutput->filename);
+ as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
+ exit (EXIT_FAILURE);
+ }
+ offset += fill_size;
+ }
+ }
+ else
+ {
+ /* Build a buffer full of fill objects and output it as
+ often as necessary. This saves on the overhead of
+ potentially lots of bfd_set_section_contents calls. */
+ int n_per_buf, i;
+ if (fill_size == 1)
+ {
+ n_per_buf = sizeof (buf);
+ memset (buf, *fill_literal, n_per_buf);
+ }
+ else
+ {
+ char *bufp;
+ n_per_buf = sizeof(buf)/fill_size;
+ for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size)
+ memcpy(bufp, fill_literal, fill_size);
+ }
+ for (; count > 0; count -= n_per_buf)
+ {
+ n_per_buf = n_per_buf > count ? count : n_per_buf;
+ x = bfd_set_section_contents (stdoutput, sec,
+ buf, (file_ptr) offset,
+ (bfd_size_type) n_per_buf * fill_size);
+ if (x != true)
+ as_fatal (_("Cannot write to output file."));
+ offset += n_per_buf * fill_size;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
+static void
+merge_data_into_text ()
+{
+#if defined(BFD_ASSEMBLER) || defined(MANY_SEGMENTS)
+ seg_info (text_section)->frchainP->frch_last->fr_next =
+ seg_info (data_section)->frchainP->frch_root;
+ seg_info (text_section)->frchainP->frch_last =
+ seg_info (data_section)->frchainP->frch_last;
+ seg_info (data_section)->frchainP = 0;
+#else
+ fixS *tmp;
+
+ text_last_frag->fr_next = data_frag_root;
+ text_last_frag = data_last_frag;
+ data_last_frag = NULL;
+ data_frag_root = NULL;
+ if (text_fix_root)
+ {
+ for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next);;
+ tmp->fx_next = data_fix_root;
+ text_fix_tail = data_fix_tail;
+ }
+ else
+ text_fix_root = data_fix_root;
+ data_fix_root = NULL;
+#endif
+}
+#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT) */
+
+#if !defined (BFD_ASSEMBLER) && !defined (BFD)
+static void
+relax_and_size_all_segments ()
+{
+ fragS *fragP;
+
+ relax_segment (text_frag_root, SEG_TEXT);
+ relax_segment (data_frag_root, SEG_DATA);
+ relax_segment (bss_frag_root, SEG_BSS);
+ /*
+ * Now the addresses of frags are correct within the segment.
+ */
+
+ know (text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0);
+ H_SET_TEXT_SIZE (&headers, text_last_frag->fr_address);
+ text_last_frag->fr_address = H_GET_TEXT_SIZE (&headers);
+
+ /*
+ * Join the 2 segments into 1 huge segment.
+ * To do this, re-compute every rn_address in the SEG_DATA frags.
+ * Then join the data frags after the text frags.
+ *
+ * Determine a_data [length of data segment].
+ */
+ if (data_frag_root)
+ {
+ register relax_addressT slide;
+
+ know ((text_last_frag->fr_type == rs_fill) && (text_last_frag->fr_offset == 0));
+
+ H_SET_DATA_SIZE (&headers, data_last_frag->fr_address);
+ data_last_frag->fr_address = H_GET_DATA_SIZE (&headers);
+ slide = H_GET_TEXT_SIZE (&headers); /* & in file of the data segment. */
+#ifdef OBJ_BOUT
+#define RoundUp(N,S) (((N)+(S)-1)&-(S))
+ /* For b.out: If the data section has a strict alignment
+ requirement, its load address in the .o file will be
+ rounded up from the size of the text section. These
+ two values are *not* the same! Similarly for the bss
+ section.... */
+ slide = RoundUp (slide, 1 << section_alignment[SEG_DATA]);
+#endif
+
+ for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ fragP->fr_address += slide;
+ } /* for each data frag */
+
+ know (text_last_frag != 0);
+ text_last_frag->fr_next = data_frag_root;
+ }
+ else
+ {
+ H_SET_DATA_SIZE (&headers, 0);
+ }
+
+#ifdef OBJ_BOUT
+ /* See above comments on b.out data section address. */
+ {
+ long bss_vma;
+ if (data_last_frag == 0)
+ bss_vma = H_GET_TEXT_SIZE (&headers);
+ else
+ bss_vma = data_last_frag->fr_address;
+ bss_vma = RoundUp (bss_vma, 1 << section_alignment[SEG_BSS]);
+ bss_address_frag.fr_address = bss_vma;
+ }
+#else /* ! OBJ_BOUT */
+ bss_address_frag.fr_address = (H_GET_TEXT_SIZE (&headers) +
+ H_GET_DATA_SIZE (&headers));
+
+#endif /* ! OBJ_BOUT */
+
+ /* Slide all the frags */
+ if (bss_frag_root)
+ {
+ relax_addressT slide = bss_address_frag.fr_address;
+
+ for (fragP = bss_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ fragP->fr_address += slide;
+ } /* for each bss frag */
+ }
+
+ if (bss_last_frag)
+ H_SET_BSS_SIZE (&headers,
+ bss_last_frag->fr_address - bss_frag_root->fr_address);
+ else
+ H_SET_BSS_SIZE (&headers, 0);
+}
+#endif /* ! BFD_ASSEMBLER && ! BFD */
+
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
+#ifdef BFD_ASSEMBLER
+static void
+set_symtab ()
+{
+ int nsyms;
+ asymbol **asympp;
+ symbolS *symp;
+ boolean result;
+ extern PTR bfd_alloc PARAMS ((bfd *, size_t));
+
+ /* Count symbols. We can't rely on a count made by the loop in
+ write_object_file, because *_frob_file may add a new symbol or
+ two. */
+ nsyms = 0;
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ nsyms++;
+
+ if (nsyms)
+ {
+ int i;
+
+ asympp = (asymbol **) bfd_alloc (stdoutput,
+ nsyms * sizeof (asymbol *));
+ symp = symbol_rootP;
+ for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
+ {
+ asympp[i] = symp->bsym;
+ symp->written = 1;
+ }
+ }
+ else
+ asympp = 0;
+ result = bfd_set_symtab (stdoutput, asympp, nsyms);
+ assert (result == true);
+ symbol_table_frozen = 1;
+}
+#endif
+
+/* Finish the subsegments. After every sub-segment, we fake an
+ ".align ...". This conforms to BSD4.2 brane-damage. We then fake
+ ".fill 0" because that is the kind of frag that requires least
+ thought. ".align" frags like to have a following frag since that
+ makes calculating their intended length trivial. */
+
+#ifndef SUB_SEGMENT_ALIGN
+#ifdef BFD_ASSEMBLER
+#define SUB_SEGMENT_ALIGN(SEG) (0)
+#else
+#define SUB_SEGMENT_ALIGN(SEG) (2)
+#endif
+#endif
+
+void
+subsegs_finish ()
+{
+ struct frchain *frchainP;
+
+ for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
+ {
+ subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
+
+ /* This now gets called even if we had errors. In that case,
+ any alignment is meaningless, and, moreover, will look weird
+ if we are generating a listing. */
+ frag_align (had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg),
+ NOP_OPCODE, 0);
+
+ /* frag_align will have left a new frag.
+ Use this last frag for an empty ".fill".
+
+ For this segment ...
+ Create a last frag. Do not leave a "being filled in frag". */
+
+ frag_wane (frag_now);
+ frag_now->fr_fix = 0;
+ know (frag_now->fr_next == NULL);
+ }
+}
+
+/* Write the object file. */
+
+void
+write_object_file ()
+{
+#if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
+ fragS *fragP; /* Track along all frags. */
+#endif
+
+ /* Do we really want to write it? */
+ {
+ int n_warns, n_errs;
+ n_warns = had_warnings ();
+ n_errs = had_errors ();
+ /* The -Z flag indicates that an object file should be generated,
+ regardless of warnings and errors. */
+ if (flag_always_generate_output)
+ {
+ if (n_warns || n_errs)
+ as_warn (_("%d error%s, %d warning%s, generating bad object file.\n"),
+ n_errs, n_errs == 1 ? "" : "s",
+ n_warns, n_warns == 1 ? "" : "s");
+ }
+ else
+ {
+ if (n_errs)
+ as_fatal (_("%d error%s, %d warning%s, no object file generated.\n"),
+ n_errs, n_errs == 1 ? "" : "s",
+ n_warns, n_warns == 1 ? "" : "s");
+ }
+ }
+
+#ifdef OBJ_VMS
+ /* Under VMS we try to be compatible with VAX-11 "C". Thus, we call
+ a routine to check for the definition of the procedure "_main",
+ and if so -- fix it up so that it can be program entry point. */
+ vms_check_for_main ();
+#endif /* OBJ_VMS */
+
+ /* From now on, we don't care about sub-segments. Build one frag chain
+ for each segment. Linked thru fr_next. */
+
+#ifdef BFD_ASSEMBLER
+ /* Remove the sections created by gas for its own purposes. */
+ {
+ asection **seclist, *sec;
+ int i;
+
+ seclist = &stdoutput->sections;
+ while (seclist && *seclist)
+ {
+ sec = *seclist;
+ while (sec == reg_section || sec == expr_section)
+ {
+ sec = sec->next;
+ *seclist = sec;
+ stdoutput->section_count--;
+ if (!sec)
+ break;
+ }
+ if (*seclist)
+ seclist = &(*seclist)->next;
+ }
+ i = 0;
+ bfd_map_over_sections (stdoutput, renumber_sections, &i);
+ }
+
+ bfd_map_over_sections (stdoutput, chain_frchains_together, (char *) 0);
+#else
+ remove_subsegs (frchain_root, SEG_TEXT, &text_frag_root, &text_last_frag);
+ remove_subsegs (data0_frchainP, SEG_DATA, &data_frag_root, &data_last_frag);
+ remove_subsegs (bss0_frchainP, SEG_BSS, &bss_frag_root, &bss_last_frag);
+#endif
+
+ /* We have two segments. If user gave -R flag, then we must put the
+ data frags into the text segment. Do this before relaxing so
+ we know to take advantage of -R and make shorter addresses. */
+#if !defined (OBJ_AOUT) || defined (BFD_ASSEMBLER)
+ if (flag_readonly_data_in_text)
+ {
+ merge_data_into_text ();
+ }
+#endif
+
+#ifdef BFD_ASSEMBLER
+ bfd_map_over_sections (stdoutput, relax_and_size_seg, (char *) 0);
+#else
+ relax_and_size_all_segments ();
+#endif /* BFD_ASSEMBLER */
+
+#ifndef BFD_ASSEMBLER
+ /*
+ *
+ * Crawl the symbol chain.
+ *
+ * For each symbol whose value depends on a frag, take the address of
+ * that frag and subsume it into the value of the symbol.
+ * After this, there is just one way to lookup a symbol value.
+ * Values are left in their final state for object file emission.
+ * We adjust the values of 'L' local symbols, even if we do
+ * not intend to emit them to the object file, because their values
+ * are needed for fix-ups.
+ *
+ * Unless we saw a -L flag, remove all symbols that begin with 'L'
+ * from the symbol chain. (They are still pointed to by the fixes.)
+ *
+ * Count the remaining symbols.
+ * Assign a symbol number to each symbol.
+ * Count the number of string-table chars we will emit.
+ * Put this info into the headers as appropriate.
+ *
+ */
+ know (zero_address_frag.fr_address == 0);
+ string_byte_count = sizeof (string_byte_count);
+
+ obj_crawl_symbol_chain (&headers);
+
+ if (string_byte_count == sizeof (string_byte_count))
+ string_byte_count = 0;
+
+ H_SET_STRING_SIZE (&headers, string_byte_count);
+
+ /*
+ * Addresses of frags now reflect addresses we use in the object file.
+ * Symbol values are correct.
+ * Scan the frags, converting any ".org"s and ".align"s to ".fill"s.
+ * Also converting any machine-dependent frags using md_convert_frag();
+ */
+ subseg_change (SEG_TEXT, 0);
+
+ for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ /* At this point we have linked all the frags into a single
+ chain. However, cvt_frag_to_fill may call md_convert_frag
+ which may call fix_new. We need to ensure that fix_new adds
+ the fixup to the right section. */
+ if (fragP == data_frag_root)
+ subseg_change (SEG_DATA, 0);
+
+ cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
+
+ /* Some assert macros don't work with # directives mixed in. */
+#ifndef NDEBUG
+ if (!(fragP->fr_next == NULL
+#ifdef OBJ_BOUT
+ || fragP->fr_next == data_frag_root
+#endif
+ || ((fragP->fr_next->fr_address - fragP->fr_address)
+ == (fragP->fr_fix + fragP->fr_offset * fragP->fr_var))))
+ abort ();
+#endif
+ }
+#endif /* ! BFD_ASSEMBLER */
+
+#ifndef WORKING_DOT_WORD
+ {
+ struct broken_word *lie;
+ struct broken_word **prevP;
+
+ prevP = &broken_words;
+ for (lie = broken_words; lie; lie = lie->next_broken_word)
+ if (!lie->added)
+ {
+ expressionS exp;
+
+ subseg_change (lie->seg, lie->subseg);
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = lie->add;
+ exp.X_op_symbol = lie->sub;
+ exp.X_add_number = lie->addnum;
+#ifdef BFD_ASSEMBLER
+#ifdef TC_CONS_FIX_NEW
+ TC_CONS_FIX_NEW (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp);
+#else
+ fix_new_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, BFD_RELOC_16);
+#endif
+#else
+#if defined(TC_SPARC) || defined(TC_A29K) || defined(NEED_FX_R_TYPE)
+ fix_new_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, NO_RELOC);
+#else
+#ifdef TC_NS32K
+ fix_new_ns32k_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, 0, 2, 0, 0);
+#else
+ fix_new_exp (lie->frag,
+ lie->word_goes_here - lie->frag->fr_literal,
+ 2, &exp, 0, 0);
+#endif /* TC_NS32K */
+#endif /* TC_SPARC|TC_A29K|NEED_FX_R_TYPE */
+#endif /* BFD_ASSEMBLER */
+ *prevP = lie->next_broken_word;
+ }
+ else
+ prevP = &(lie->next_broken_word);
+
+ for (lie = broken_words; lie;)
+ {
+ struct broken_word *untruth;
+ char *table_ptr;
+ addressT table_addr;
+ addressT from_addr, to_addr;
+ int n, m;
+
+ subseg_change (lie->seg, lie->subseg);
+ fragP = lie->dispfrag;
+
+ /* Find out how many broken_words go here. */
+ n = 0;
+ for (untruth = lie; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word)
+ if (untruth->added == 1)
+ n++;
+
+ table_ptr = lie->dispfrag->fr_opcode;
+ table_addr = lie->dispfrag->fr_address + (table_ptr - lie->dispfrag->fr_literal);
+ /* Create the jump around the long jumps. This is a short
+ jump from table_ptr+0 to table_ptr+n*long_jump_size. */
+ from_addr = table_addr;
+ to_addr = table_addr + md_short_jump_size + n * md_long_jump_size;
+ md_create_short_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add);
+ table_ptr += md_short_jump_size;
+ table_addr += md_short_jump_size;
+
+ for (m = 0; lie && lie->dispfrag == fragP; m++, lie = lie->next_broken_word)
+ {
+ if (lie->added == 2)
+ continue;
+ /* Patch the jump table */
+ /* This is the offset from ??? to table_ptr+0 */
+ to_addr = table_addr - S_GET_VALUE (lie->sub);
+#ifdef BFD_ASSEMBLER
+ to_addr -= lie->sub->sy_frag->fr_address;
+#endif
+ md_number_to_chars (lie->word_goes_here, to_addr, 2);
+ for (untruth = lie->next_broken_word; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word)
+ {
+ if (untruth->use_jump == lie)
+ md_number_to_chars (untruth->word_goes_here, to_addr, 2);
+ }
+
+ /* Install the long jump */
+ /* this is a long jump from table_ptr+0 to the final target */
+ from_addr = table_addr;
+ to_addr = S_GET_VALUE (lie->add) + lie->addnum;
+#ifdef BFD_ASSEMBLER
+ to_addr += lie->add->sy_frag->fr_address;
+#endif
+ md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add);
+ table_ptr += md_long_jump_size;
+ table_addr += md_long_jump_size;
+ }
+ }
+ }
+#endif /* not WORKING_DOT_WORD */
+
+#ifndef BFD_ASSEMBLER
+#ifndef OBJ_VMS
+ { /* not vms */
+ char *the_object_file;
+ long object_file_size;
+ /*
+ * Scan every FixS performing fixups. We had to wait until now to do
+ * this because md_convert_frag() may have made some fixSs.
+ */
+ int trsize, drsize;
+
+ subseg_change (SEG_TEXT, 0);
+ trsize = md_reloc_size * fixup_segment (text_fix_root, SEG_TEXT);
+ subseg_change (SEG_DATA, 0);
+ drsize = md_reloc_size * fixup_segment (data_fix_root, SEG_DATA);
+ H_SET_RELOCATION_SIZE (&headers, trsize, drsize);
+
+ /* FIXME move this stuff into the pre-write-hook */
+ H_SET_MAGIC_NUMBER (&headers, magic_number_for_object_file);
+ H_SET_ENTRY_POINT (&headers, 0);
+
+ obj_pre_write_hook (&headers); /* extra coff stuff */
+
+ object_file_size = H_GET_FILE_SIZE (&headers);
+ next_object_file_charP = the_object_file = xmalloc (object_file_size);
+
+ output_file_create (out_file_name);
+
+ obj_header_append (&next_object_file_charP, &headers);
+
+ know ((next_object_file_charP - the_object_file) == H_GET_HEADER_SIZE (&headers));
+
+ /*
+ * Emit code.
+ */
+ for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ register long count;
+ register char *fill_literal;
+ register long fill_size;
+
+ PROGRESS (1);
+ know (fragP->fr_type == rs_fill);
+ append (&next_object_file_charP, fragP->fr_literal, (unsigned long) fragP->fr_fix);
+ fill_literal = fragP->fr_literal + fragP->fr_fix;
+ fill_size = fragP->fr_var;
+ know (fragP->fr_offset >= 0);
+
+ for (count = fragP->fr_offset; count; count--)
+ {
+ append (&next_object_file_charP, fill_literal, (unsigned long) fill_size);
+ } /* for each */
+
+ } /* for each code frag. */
+
+ know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers)));
+
+ /*
+ * Emit relocations.
+ */
+ obj_emit_relocations (&next_object_file_charP, text_fix_root, (relax_addressT) 0);
+ know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers)));
+#ifdef TC_I960
+ /* Make addresses in data relocation directives relative to beginning of
+ * first data fragment, not end of last text fragment: alignment of the
+ * start of the data segment may place a gap between the segments.
+ */
+ obj_emit_relocations (&next_object_file_charP, data_fix_root, data0_frchainP->frch_root->fr_address);
+#else /* TC_I960 */
+ obj_emit_relocations (&next_object_file_charP, data_fix_root, text_last_frag->fr_address);
+#endif /* TC_I960 */
+
+ know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers) + H_GET_DATA_RELOCATION_SIZE (&headers)));
+
+ /*
+ * Emit line number entries.
+ */
+ OBJ_EMIT_LINENO (&next_object_file_charP, lineno_rootP, the_object_file);
+ know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers) + H_GET_DATA_RELOCATION_SIZE (&headers) + H_GET_LINENO_SIZE (&headers)));
+
+ /*
+ * Emit symbols.
+ */
+ obj_emit_symbols (&next_object_file_charP, symbol_rootP);
+ know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers) + H_GET_DATA_RELOCATION_SIZE (&headers) + H_GET_LINENO_SIZE (&headers) + H_GET_SYMBOL_TABLE_SIZE (&headers)));
+
+ /*
+ * Emit strings.
+ */
+
+ if (string_byte_count > 0)
+ {
+ obj_emit_strings (&next_object_file_charP);
+ } /* only if we have a string table */
+
+#ifdef BFD_HEADERS
+ bfd_seek (stdoutput, 0, 0);
+ bfd_write (the_object_file, 1, object_file_size, stdoutput);
+#else
+
+ /* Write the data to the file */
+ output_file_append (the_object_file, object_file_size, out_file_name);
+ free (the_object_file);
+#endif
+ } /* non vms output */
+#else /* OBJ_VMS */
+ /*
+ * Now do the VMS-dependent part of writing the object file
+ */
+ vms_write_object_file (H_GET_TEXT_SIZE (&headers),
+ H_GET_DATA_SIZE (&headers),
+ H_GET_BSS_SIZE (&headers),
+ text_frag_root, data_frag_root);
+#endif /* OBJ_VMS */
+#else /* BFD_ASSEMBLER */
+
+ /* Resolve symbol values. This needs to be done before processing
+ the relocations. */
+ if (symbol_rootP)
+ {
+ symbolS *symp;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ if (!symp->sy_resolved)
+ resolve_symbol_value (symp, 1);
+ }
+
+ PROGRESS (1);
+
+#ifdef tc_frob_file_before_adjust
+ tc_frob_file_before_adjust ();
+#endif
+#ifdef obj_frob_file_before_adjust
+ obj_frob_file_before_adjust ();
+#endif
+
+ bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *)0);
+
+ /* Set up symbol table, and write it out. */
+ if (symbol_rootP)
+ {
+ symbolS *symp;
+
+ for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+ {
+ int punt = 0;
+ const char *name;
+
+ if (symp->sy_mri_common)
+ {
+ if (S_IS_EXTERNAL (symp))
+ as_bad (_("%s: global symbols not supported in common sections"),
+ S_GET_NAME (symp));
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ continue;
+ }
+
+ name = S_GET_NAME (symp);
+ if (name)
+ {
+ const char *name2 = decode_local_label_name ((char *)S_GET_NAME (symp));
+ /* They only differ if `name' is a fb or dollar local
+ label name. */
+ if (name2 != name && ! S_IS_DEFINED (symp))
+ as_bad (_("local label %s is not defined"), name2);
+ }
+
+ /* Do it again, because adjust_reloc_syms might introduce
+ more symbols. They'll probably only be section symbols,
+ but they'll still need to have the values computed. */
+ if (! symp->sy_resolved)
+ {
+ if (symp->sy_value.X_op == O_constant)
+ {
+ /* This is the normal case; skip the call. */
+ S_SET_VALUE (symp,
+ (S_GET_VALUE (symp)
+ + symp->sy_frag->fr_address));
+ symp->sy_resolved = 1;
+ }
+ else
+ resolve_symbol_value (symp, 1);
+ }
+
+ /* Skip symbols which were equated to undefined or common
+ symbols. */
+ if (symp->sy_value.X_op == O_symbol
+ && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
+ {
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ continue;
+ }
+
+ /* So far, common symbols have been treated like undefined symbols.
+ Put them in the common section now. */
+ if (S_IS_DEFINED (symp) == 0
+ && S_GET_VALUE (symp) != 0)
+ S_SET_SEGMENT (symp, bfd_com_section_ptr);
+#if 0
+ printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
+ S_GET_NAME (symp), symp,
+ S_GET_VALUE (symp),
+ symp->bsym->flags,
+ segment_name (symp->bsym->section));
+#endif
+
+#ifdef obj_frob_symbol
+ obj_frob_symbol (symp, punt);
+#endif
+#ifdef tc_frob_symbol
+ if (! punt || symp->sy_used_in_reloc)
+ tc_frob_symbol (symp, punt);
+#endif
+
+ /* If we don't want to keep this symbol, splice it out of
+ the chain now. If EMIT_SECTION_SYMBOLS is 0, we never
+ want section symbols. Otherwise, we skip local symbols
+ and symbols that the frob_symbol macros told us to punt,
+ but we keep such symbols if they are used in relocs. */
+ if ((! EMIT_SECTION_SYMBOLS
+ && (symp->bsym->flags & BSF_SECTION_SYM) != 0)
+ /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
+ opposites. Sometimes the former checks flags and the
+ latter examines the name... */
+ || (!S_IS_EXTERN (symp)
+ && (S_IS_LOCAL (symp) || punt)
+ && ! symp->sy_used_in_reloc))
+ {
+ symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+ /* After symbol_remove, symbol_next(symp) still returns
+ the one that came after it in the chain. So we don't
+ need to do any extra cleanup work here. */
+
+ continue;
+ }
+
+ /* Make sure we really got a value for the symbol. */
+ if (! symp->sy_resolved)
+ {
+ as_bad (_("can't resolve value for symbol \"%s\""),
+ S_GET_NAME (symp));
+ symp->sy_resolved = 1;
+ }
+
+ /* Set the value into the BFD symbol. Up til now the value
+ has only been kept in the gas symbolS struct. */
+ symp->bsym->value = S_GET_VALUE (symp);
+ }
+ }
+
+ PROGRESS (1);
+
+ /* Now do any format-specific adjustments to the symbol table, such
+ as adding file symbols. */
+#ifdef tc_adjust_symtab
+ tc_adjust_symtab ();
+#endif
+#ifdef obj_adjust_symtab
+ obj_adjust_symtab ();
+#endif
+
+ /* Now that all the sizes are known, and contents correct, we can
+ start writing to the file. */
+ set_symtab ();
+
+ /* If *_frob_file changes the symbol value at this point, it is
+ responsible for moving the changed value into symp->bsym->value
+ as well. Hopefully all symbol value changing can be done in
+ *_frob_symbol. */
+#ifdef tc_frob_file
+ tc_frob_file ();
+#endif
+#ifdef obj_frob_file
+ obj_frob_file ();
+#endif
+
+ bfd_map_over_sections (stdoutput, write_relocs, (char *) 0);
+
+#ifdef tc_frob_file_after_relocs
+ tc_frob_file_after_relocs ();
+#endif
+#ifdef obj_frob_file_after_relocs
+ obj_frob_file_after_relocs ();
+#endif
+
+ bfd_map_over_sections (stdoutput, write_contents, (char *) 0);
+#endif /* BFD_ASSEMBLER */
+}
+#endif /* ! BFD */
+
+/*
+ * relax_segment()
+ *
+ * Now we have a segment, not a crowd of sub-segments, we can make fr_address
+ * values.
+ *
+ * Relax the frags.
+ *
+ * After this, all frags in this segment have addresses that are correct
+ * within the segment. Since segments live in different file addresses,
+ * these frag addresses may not be the same as final object-file addresses.
+ */
+
+#ifdef TC_GENERIC_RELAX_TABLE
+
+static int is_dnrange PARAMS ((fragS *, fragS *));
+
+/* Subroutines of relax_segment. */
+static int
+is_dnrange (f1, f2)
+ fragS *f1;
+ fragS *f2;
+{
+ for (; f1; f1 = f1->fr_next)
+ if (f1->fr_next == f2)
+ return 1;
+ return 0;
+}
+
+/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
+
+long
+relax_frag (fragP, stretch)
+ fragS *fragP;
+ long stretch;
+{
+ const relax_typeS *this_type;
+ const relax_typeS *start_type;
+ relax_substateT next_state;
+ relax_substateT this_state;
+ long aim, target, growth;
+ symbolS *symbolP = fragP->fr_symbol;
+ long offset = fragP->fr_offset;
+ /* Recompute was_address by undoing "+= stretch" done by relax_segment. */
+ unsigned long was_address = fragP->fr_address - stretch;
+ unsigned long address = fragP->fr_address;
+ const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
+
+ this_state = fragP->fr_subtype;
+ start_type = this_type = table + this_state;
+ target = offset;
+
+ if (symbolP)
+ {
+#ifndef DIFF_EXPR_OK
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
+ || (S_GET_SEGMENT (symbolP) == SEG_DATA)
+ || (S_GET_SEGMENT (symbolP) == SEG_BSS)
+ || (S_GET_SEGMENT (symbolP) == SEG_TEXT));
+#endif
+ know (symbolP->sy_frag);
+#endif
+ know (!(S_GET_SEGMENT (symbolP) == absolute_section)
+ || symbolP->sy_frag == &zero_address_frag);
+ target +=
+ S_GET_VALUE (symbolP)
+ + symbolP->sy_frag->fr_address;
+
+ /* If frag has yet to be reached on this pass,
+ assume it will move by STRETCH just as we did.
+ If this is not so, it will be because some frag
+ between grows, and that will force another pass.
+
+ Beware zero-length frags.
+
+ There should be a faster way to do this. */
+
+ if (symbolP->sy_frag->fr_address >= was_address
+ && is_dnrange (fragP, symbolP->sy_frag))
+ {
+ target += stretch;
+ }
+ }
+
+ aim = target - address - fragP->fr_fix;
+#ifdef TC_PCREL_ADJUST
+ /* Currently only the ns32k family needs this */
+ aim += TC_PCREL_ADJUST(fragP);
+/*#else*/
+ /* This machine doesn't want to use pcrel_adjust.
+ In that case, pcrel_adjust should be zero. */
+/* assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);*/
+#endif
+#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE */
+ md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
+#endif
+
+ if (aim < 0)
+ {
+ /* Look backwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim >= this_type->rlx_backward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+ else
+ {
+ /* Look forwards. */
+ for (next_state = this_type->rlx_more; next_state;)
+ if (aim <= this_type->rlx_forward)
+ next_state = 0;
+ else
+ {
+ /* Grow to next state. */
+ this_state = next_state;
+ this_type = table + this_state;
+ next_state = this_type->rlx_more;
+ }
+ }
+
+ growth = this_type->rlx_length - start_type->rlx_length;
+ if (growth != 0)
+ fragP->fr_subtype = this_state;
+ return growth;
+}
+
+#endif /* defined (TC_GENERIC_RELAX_TABLE) */
+
+/* Relax_align. Advance location counter to next address that has 'alignment'
+ lowest order bits all 0s, return size of adjustment made. */
+static relax_addressT
+relax_align (address, alignment)
+ register relax_addressT address; /* Address now. */
+ register int alignment; /* Alignment (binary). */
+{
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~((~0) << alignment);
+ new_address = (address + mask) & (~mask);
+#ifdef LINKER_RELAXING_SHRINKS_ONLY
+ if (linkrelax)
+ /* We must provide lots of padding, so the linker can discard it
+ when needed. The linker will not add extra space, ever. */
+ new_address += (1 << alignment);
+#endif
+ return (new_address - address);
+}
+
+void
+relax_segment (segment_frag_root, segment)
+ struct frag *segment_frag_root;
+ segT segment;
+{
+ register struct frag *fragP;
+ register relax_addressT address;
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know (segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS);
+#endif
+ /* In case md_estimate_size_before_relax() wants to make fixSs. */
+ subseg_change (segment, 0);
+
+ /* For each frag in segment: count and store (a 1st guess of)
+ fr_address. */
+ address = 0;
+ for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ fragP->fr_address = address;
+ address += fragP->fr_fix;
+
+ switch (fragP->fr_type)
+ {
+ case rs_fill:
+ address += fragP->fr_offset * fragP->fr_var;
+ break;
+
+ case rs_align:
+ case rs_align_code:
+ {
+ addressT offset = relax_align (address, (int) fragP->fr_offset);
+
+ if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype)
+ offset = 0;
+
+ if (offset % fragP->fr_var != 0)
+ {
+ as_bad (_("alignment padding (%lu bytes) not a multiple of %ld"),
+ (unsigned long) offset, (long) fragP->fr_var);
+ offset -= (offset % fragP->fr_var);
+ }
+
+ address += offset;
+ }
+ break;
+
+ case rs_org:
+ case rs_space:
+ /* Assume .org is nugatory. It will grow with 1st relax. */
+ break;
+
+ case rs_machine_dependent:
+ address += md_estimate_size_before_relax (fragP, segment);
+ break;
+
+#ifndef WORKING_DOT_WORD
+ /* Broken words don't concern us yet */
+ case rs_broken_word:
+ break;
+#endif
+
+ case rs_leb128:
+ /* Initial guess is always 1; doing otherwise can result in
+ stable solutions that are larger than the minimum. */
+ address += fragP->fr_offset = 1;
+ break;
+
+ case rs_cfa:
+ address += eh_frame_estimate_size_before_relax (fragP);
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_type);
+ break;
+ } /* switch(fr_type) */
+ } /* for each frag in the segment */
+
+ /* Do relax(). */
+ {
+ long stretch; /* May be any size, 0 or negative. */
+ /* Cumulative number of addresses we have */
+ /* relaxed this pass. */
+ /* We may have relaxed more than one address. */
+ long stretched; /* Have we stretched on this pass? */
+ /* This is 'cuz stretch may be zero, when, in fact some piece of code
+ grew, and another shrank. If a branch instruction doesn't fit anymore,
+ we could be scrod. */
+
+ do
+ {
+ stretch = stretched = 0;
+ for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
+ {
+ long growth = 0;
+ addressT was_address;
+ offsetT offset;
+ symbolS *symbolP;
+
+ was_address = fragP->fr_address;
+ address = fragP->fr_address += stretch;
+ symbolP = fragP->fr_symbol;
+ offset = fragP->fr_offset;
+
+ switch (fragP->fr_type)
+ {
+ case rs_fill: /* .fill never relaxes. */
+ growth = 0;
+ break;
+
+#ifndef WORKING_DOT_WORD
+ /* JF: This is RMS's idea. I do *NOT* want to be blamed
+ for it I do not want to write it. I do not want to have
+ anything to do with it. This is not the proper way to
+ implement this misfeature. */
+ case rs_broken_word:
+ {
+ struct broken_word *lie;
+ struct broken_word *untruth;
+
+ /* Yes this is ugly (storing the broken_word pointer
+ in the symbol slot). Still, this whole chunk of
+ code is ugly, and I don't feel like doing anything
+ about it. Think of it as stubbornness in action. */
+ growth = 0;
+ for (lie = (struct broken_word *) (fragP->fr_symbol);
+ lie && lie->dispfrag == fragP;
+ lie = lie->next_broken_word)
+ {
+
+ if (lie->added)
+ continue;
+
+ offset = (lie->add->sy_frag->fr_address
+ + S_GET_VALUE (lie->add)
+ + lie->addnum
+ - (lie->sub->sy_frag->fr_address
+ + S_GET_VALUE (lie->sub)));
+ if (offset <= -32768 || offset >= 32767)
+ {
+ if (flag_warn_displacement)
+ {
+ char buf[50];
+ sprint_value (buf, (addressT) lie->addnum);
+ as_warn (_(".word %s-%s+%s didn't fit"),
+ S_GET_NAME (lie->add),
+ S_GET_NAME (lie->sub),
+ buf);
+ }
+ lie->added = 1;
+ if (fragP->fr_subtype == 0)
+ {
+ fragP->fr_subtype++;
+ growth += md_short_jump_size;
+ }
+ for (untruth = lie->next_broken_word;
+ untruth && untruth->dispfrag == lie->dispfrag;
+ untruth = untruth->next_broken_word)
+ if ((untruth->add->sy_frag == lie->add->sy_frag)
+ && S_GET_VALUE (untruth->add) == S_GET_VALUE (lie->add))
+ {
+ untruth->added = 2;
+ untruth->use_jump = lie;
+ }
+ growth += md_long_jump_size;
+ }
+ }
+
+ break;
+ } /* case rs_broken_word */
+#endif
+ case rs_align:
+ case rs_align_code:
+ {
+ addressT oldoff, newoff;
+
+ oldoff = relax_align (was_address + fragP->fr_fix,
+ (int) offset);
+ newoff = relax_align (address + fragP->fr_fix,
+ (int) offset);
+
+ if (fragP->fr_subtype != 0)
+ {
+ if (oldoff > fragP->fr_subtype)
+ oldoff = 0;
+ if (newoff > fragP->fr_subtype)
+ newoff = 0;
+ }
+
+ growth = newoff - oldoff;
+ }
+ break;
+
+ case rs_org:
+ {
+ long target = offset;
+ long after;
+
+ if (symbolP)
+ {
+#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
+ know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
+ || (S_GET_SEGMENT (symbolP) == SEG_DATA)
+ || (S_GET_SEGMENT (symbolP) == SEG_TEXT)
+ || S_GET_SEGMENT (symbolP) == SEG_BSS);
+ know (symbolP->sy_frag);
+ know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
+ || (symbolP->sy_frag == &zero_address_frag));
+#endif
+ target += S_GET_VALUE (symbolP)
+ + symbolP->sy_frag->fr_address;
+ } /* if we have a symbol */
+
+ know (fragP->fr_next);
+ after = fragP->fr_next->fr_address;
+ growth = target - after;
+ if (growth < 0)
+ {
+ /* Growth may be negative, but variable part of frag
+ cannot have fewer than 0 chars. That is, we can't
+ .org backwards. */
+ as_bad (_("attempt to .org backwards ignored"));
+ growth = 0;
+ }
+
+ growth -= stretch; /* This is an absolute growth factor */
+ break;
+ }
+
+ case rs_space:
+ if (symbolP)
+ {
+ growth = S_GET_VALUE (symbolP);
+ if (symbolP->sy_frag != &zero_address_frag
+ || S_IS_COMMON (symbolP)
+ || ! S_IS_DEFINED (symbolP))
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _(".space specifies non-absolute value"));
+ fragP->fr_symbol = 0;
+ if (growth < 0)
+ {
+ as_warn (_(".space or .fill with negative value, ignored"));
+ growth = 0;
+ }
+ }
+ else
+ growth = 0;
+ break;
+
+ case rs_machine_dependent:
+#ifdef md_relax_frag
+ growth = md_relax_frag (fragP, stretch);
+#else
+#ifdef TC_GENERIC_RELAX_TABLE
+ /* The default way to relax a frag is to look through
+ TC_GENERIC_RELAX_TABLE. */
+ growth = relax_frag (fragP, stretch);
+#endif /* TC_GENERIC_RELAX_TABLE */
+#endif
+ break;
+
+ case rs_leb128:
+ {
+ valueT value;
+ int size;
+
+ value = resolve_symbol_value (fragP->fr_symbol, 0);
+ size = sizeof_leb128 (value, fragP->fr_subtype);
+ growth = size - fragP->fr_offset;
+ fragP->fr_offset = size;
+ }
+ break;
+
+ case rs_cfa:
+ growth = eh_frame_relax_frag (fragP);
+ break;
+
+ default:
+ BAD_CASE (fragP->fr_type);
+ break;
+ }
+ if (growth)
+ {
+ stretch += growth;
+ stretched++;
+ }
+ } /* For each frag in the segment. */
+ }
+ while (stretched); /* Until nothing further to relax. */
+ } /* do_relax */
+
+ /*
+ * We now have valid fr_address'es for each frag.
+ */
+
+ /*
+ * All fr_address's are correct, relative to their own segment.
+ * We have made all the fixS we will ever make.
+ */
+} /* relax_segment() */
+
+#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
+
+#ifndef TC_RELOC_RTSYM_LOC_FIXUP
+#define TC_RELOC_RTSYM_LOC_FIXUP(X) (1)
+#endif
+
+/* fixup_segment()
+
+ Go through all the fixS's in a segment and see which ones can be
+ handled now. (These consist of fixS where we have since discovered
+ the value of a symbol, or the address of the frag involved.)
+ For each one, call md_apply_fix to put the fix into the frag data.
+
+ Result is a count of how many relocation structs will be needed to
+ handle the remaining fixS's that we couldn't completely handle here.
+ These will be output later by emit_relocations(). */
+
+static long
+fixup_segment (fixP, this_segment_type)
+ register fixS *fixP;
+ segT this_segment_type; /* N_TYPE bits for segment. */
+{
+ long seg_reloc_count = 0;
+ symbolS *add_symbolP;
+ symbolS *sub_symbolP;
+ valueT add_number;
+ int size;
+ char *place;
+ long where;
+ int pcrel, plt;
+ fragS *fragP;
+ segT add_symbol_segment = absolute_section;
+
+ /* If the linker is doing the relaxing, we must not do any fixups.
+
+ Well, strictly speaking that's not true -- we could do any that are
+ PC-relative and don't cross regions that could change size. And for the
+ i960 (the only machine for which we've got a relaxing linker right now),
+ we might be able to turn callx/callj into bal anyways in cases where we
+ know the maximum displacement. */
+ if (linkrelax)
+ {
+ for (; fixP; fixP = fixP->fx_next)
+ seg_reloc_count++;
+ TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
+ return seg_reloc_count;
+ }
+
+ for (; fixP; fixP = fixP->fx_next)
+ {
+
+#ifdef DEBUG5
+ fprintf (stderr, "\nprocessing fixup:\n");
+ print_fixup (fixP);
+#endif
+
+
+ fragP = fixP->fx_frag;
+ know (fragP);
+ where = fixP->fx_where;
+ place = fragP->fr_literal + where;
+ size = fixP->fx_size;
+ add_symbolP = fixP->fx_addsy;
+#ifdef TC_VALIDATE_FIX
+ TC_VALIDATE_FIX (fixP, this_segment_type, skip);
+#endif
+ sub_symbolP = fixP->fx_subsy;
+ add_number = fixP->fx_offset;
+ pcrel = fixP->fx_pcrel;
+ plt = fixP->fx_plt;
+
+ if (add_symbolP != NULL
+ && add_symbolP->sy_mri_common)
+ {
+ know (add_symbolP->sy_value.X_op == O_symbol);
+ add_number += S_GET_VALUE (add_symbolP);
+ fixP->fx_offset = add_number;
+ add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
+ }
+
+ if (add_symbolP)
+ add_symbol_segment = S_GET_SEGMENT (add_symbolP);
+
+ if (sub_symbolP)
+ {
+ resolve_symbol_value (sub_symbolP, 1);
+ if (add_symbolP == NULL || add_symbol_segment == absolute_section)
+ {
+ if (add_symbolP != NULL)
+ {
+ add_number += S_GET_VALUE (add_symbolP);
+ add_symbolP = NULL;
+ fixP->fx_addsy = NULL;
+ }
+
+ /* It's just -sym */
+ if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
+ {
+ add_number -= S_GET_VALUE (sub_symbolP);
+ fixP->fx_subsy = NULL;
+ }
+ else if (pcrel
+ && S_GET_SEGMENT (sub_symbolP) == this_segment_type)
+ {
+ /* Should try converting to a constant. */
+ goto bad_sub_reloc;
+ }
+ else
+ bad_sub_reloc:
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Negative of non-absolute symbol %s"),
+ S_GET_NAME (sub_symbolP));
+ }
+ else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
+ && SEG_NORMAL (add_symbol_segment))
+ {
+ /* Difference of 2 symbols from same segment.
+ Can't make difference of 2 undefineds: 'value' means
+ something different for N_UNDF. */
+#ifdef TC_I960
+ /* Makes no sense to use the difference of 2 arbitrary symbols
+ as the target of a call instruction. */
+ if (fixP->fx_tcbit)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("callj to difference of 2 symbols"));
+#endif /* TC_I960 */
+ add_number += S_GET_VALUE (add_symbolP) -
+ S_GET_VALUE (sub_symbolP);
+
+ add_symbolP = NULL;
+ pcrel = 0; /* No further pcrel processing. */
+
+ /* Let the target machine make the final determination
+ as to whether or not a relocation will be needed to
+ handle this fixup. */
+ if (!TC_FORCE_RELOCATION_SECTION (fixP, this_segment_type))
+ {
+ fixP->fx_pcrel = 0;
+ fixP->fx_addsy = NULL;
+ fixP->fx_subsy = NULL;
+ }
+ }
+ else
+ {
+ /* Different segments in subtraction. */
+ know (!(S_IS_EXTERNAL (sub_symbolP)
+ && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
+
+ if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
+ add_number -= S_GET_VALUE (sub_symbolP);
+
+#ifdef DIFF_EXPR_OK
+ else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
+#if 0 /* Do this even if it's already described as pc-relative. For example,
+ on the m68k, an operand of "pc@(foo-.-2)" should address "foo" in a
+ pc-relative mode. */
+ && pcrel
+#endif
+ )
+ {
+ /* Make it pc-relative. */
+ add_number += (MD_PCREL_FROM_SECTION (fixP, this_segment_type)
+ - S_GET_VALUE (sub_symbolP));
+ pcrel = 1;
+ fixP->fx_pcrel = 1;
+ sub_symbolP = 0;
+ fixP->fx_subsy = 0;
+ }
+#endif
+#ifdef UNDEFINED_DIFFERENCE_OK
+ /* The PA needs this for PIC code generation. We basically
+ don't want to do anything if we have the difference of two
+ symbols at this point. */
+ else if (1)
+ {
+ /* Leave it alone. */
+ }
+#endif
+#ifdef BFD_ASSEMBLER
+ else if (fixP->fx_r_type == BFD_RELOC_GPREL32
+ || fixP->fx_r_type == BFD_RELOC_GPREL16)
+ {
+ /* Leave it alone. */
+ }
+#endif
+ else
+ {
+ char buf[50];
+ sprint_value (buf, fragP->fr_address + where);
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Subtraction of two symbols in different sections \"%s\" {%s section} - \"%s\" {%s section} at file address %s."),
+ S_GET_NAME (add_symbolP),
+ segment_name (S_GET_SEGMENT (add_symbolP)),
+ S_GET_NAME (sub_symbolP),
+ segment_name (S_GET_SEGMENT (sub_symbolP)),
+ buf);
+ }
+ }
+ }
+
+ if (add_symbolP)
+ {
+ if (add_symbol_segment == this_segment_type && pcrel && !plt
+ && TC_RELOC_RTSYM_LOC_FIXUP (fixP))
+ {
+ /*
+ * This fixup was made when the symbol's segment was
+ * SEG_UNKNOWN, but it is now in the local segment.
+ * So we know how to do the address without relocation.
+ */
+#ifdef TC_I960
+ /* reloc_callj() may replace a 'call' with a 'calls' or a
+ 'bal', in which cases it modifies *fixP as appropriate.
+ In the case of a 'calls', no further work is required,
+ and *fixP has been set up to make the rest of the code
+ below a no-op. */
+ reloc_callj (fixP);
+#endif /* TC_I960 */
+
+ add_number += S_GET_VALUE (add_symbolP);
+ add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
+ pcrel = 0; /* Lie. Don't want further pcrel processing. */
+
+ /* Let the target machine make the final determination
+ as to whether or not a relocation will be needed to
+ handle this fixup. */
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_pcrel = 0;
+ fixP->fx_addsy = NULL;
+ }
+ }
+ else
+ {
+ if (add_symbol_segment == absolute_section
+ && ! pcrel)
+ {
+#ifdef TC_I960
+ /* See comment about reloc_callj() above. */
+ reloc_callj (fixP);
+#endif /* TC_I960 */
+ add_number += S_GET_VALUE (add_symbolP);
+
+ /* Let the target machine make the final determination
+ as to whether or not a relocation will be needed to
+ handle this fixup. */
+
+ if (!TC_FORCE_RELOCATION (fixP))
+ {
+ fixP->fx_addsy = NULL;
+ add_symbolP = NULL;
+ }
+ }
+ else if (add_symbol_segment == undefined_section
+#ifdef BFD_ASSEMBLER
+ || bfd_is_com_section (add_symbol_segment)
+#endif
+ )
+ {
+#ifdef TC_I960
+ if ((int) fixP->fx_bit_fixP == 13)
+ {
+ /* This is a COBR instruction. They have only a
+ * 13-bit displacement and are only to be used
+ * for local branches: flag as error, don't generate
+ * relocation.
+ */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("can't use COBR format with external label"));
+ fixP->fx_addsy = NULL;
+ fixP->fx_done = 1;
+ continue;
+ } /* COBR */
+#endif /* TC_I960 */
+
+#ifdef OBJ_COFF
+#ifdef TE_I386AIX
+ if (S_IS_COMMON (add_symbolP))
+ add_number += S_GET_VALUE (add_symbolP);
+#endif /* TE_I386AIX */
+#endif /* OBJ_COFF */
+ ++seg_reloc_count;
+ }
+ else
+ {
+ seg_reloc_count++;
+#if !(defined (TC_V850) && defined (OBJ_ELF))
+#if !(defined (TC_M68K) && defined (OBJ_ELF))
+#if !(defined (TC_ARM) && defined (OBJ_ELF))
+#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF)) || defined (TE_PE)
+ add_number += S_GET_VALUE (add_symbolP);
+#endif
+#endif
+#endif
+#endif
+ }
+ }
+ }
+
+ if (pcrel)
+ {
+ add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
+ if (add_symbolP == 0)
+ {
+#ifndef BFD_ASSEMBLER
+ fixP->fx_addsy = &abs_symbol;
+#else
+ fixP->fx_addsy = section_symbol (absolute_section);
+#endif
+ fixP->fx_addsy->sy_used_in_reloc = 1;
+ ++seg_reloc_count;
+ }
+ }
+
+ if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && size > 0)
+ {
+ if ((size_t) size < sizeof (valueT))
+ {
+ valueT mask, hibit;
+
+ /* set all bits to one */
+ mask = 0;
+ mask--;
+ /* Technically, combining these produces an undefined result
+ if size is sizeof (valueT), though I think these two
+ half-way operations should both be defined. And the
+ compiler should be able to combine them if it's valid on
+ the host architecture. */
+ mask <<= size * 4;
+ mask <<= size * 4;
+ hibit = (valueT) 1 << (size * 8 - 1);
+ if (((add_number & mask) != 0
+ || (fixP->fx_signed
+ && (add_number & hibit) != 0))
+ && ((add_number & mask) != mask
+ || (add_number & hibit) == 0))
+ {
+ char buf[50], buf2[50];
+ sprint_value (buf, fragP->fr_address + where);
+ if (add_number > 1000)
+ sprint_value (buf2, add_number);
+ else
+ sprintf (buf2, "%ld", (long) add_number);
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Value of %s too large for field of %d bytes at %s"),
+ buf2, size, buf);
+ } /* generic error checking */
+ }
+#ifdef WARN_SIGNED_OVERFLOW_WORD
+ /* Warn if a .word value is too large when treated as a signed
+ number. We already know it is not too negative. This is to
+ catch over-large switches generated by gcc on the 68k. */
+ if (!flag_signed_overflow_ok
+ && size == 2
+ && add_number > 0x7fff)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
+ (long) add_number,
+ (unsigned long) (fragP->fr_address + where));
+#endif
+ } /* not a bit fix */
+
+ if (!fixP->fx_done)
+ {
+#ifdef MD_APPLY_FIX3
+ md_apply_fix3 (fixP, &add_number, this_segment_type);
+#else
+#ifdef BFD_ASSEMBLER
+ md_apply_fix (fixP, &add_number);
+#else
+ md_apply_fix (fixP, add_number);
+#endif
+#endif
+
+#ifndef TC_HANDLES_FX_DONE
+ /* If the tc-* files haven't been converted, assume it's handling
+ it the old way, where a null fx_addsy means that the fix has
+ been applied completely, and no further work is needed. */
+ if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
+ fixP->fx_done = 1;
+#endif
+ }
+#ifdef TC_VALIDATE_FIX
+ skip: ;
+#endif
+#ifdef DEBUG5
+ fprintf (stderr, "result:\n");
+ print_fixup (fixP);
+#endif
+ } /* For each fixS in this segment. */
+
+ TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
+ return seg_reloc_count;
+}
+
+#endif /* defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS)) */
+
+void
+number_to_chars_bigendian (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if ((size_t) n > sizeof (val) || n <= 0)
+ abort ();
+ while (n--)
+ {
+ buf[n] = val & 0xff;
+ val >>= 8;
+ }
+}
+
+void
+number_to_chars_littleendian (buf, val, n)
+ char *buf;
+ valueT val;
+ int n;
+{
+ if ((size_t) n > sizeof (val) || n <= 0)
+ abort ();
+ while (n--)
+ {
+ *buf++ = val & 0xff;
+ val >>= 8;
+ }
+}
+
+void
+write_print_statistics (file)
+ FILE *file;
+{
+ fprintf (stderr, "fixups: %d\n", n_fixups);
+}
+
+/* for debugging */
+extern int indent_level;
+
+void
+print_fixup (fixp)
+ fixS *fixp;
+{
+ indent_level = 1;
+ fprintf (stderr, "fix %lx %s:%d", (long) fixp, fixp->fx_file, fixp->fx_line);
+ if (fixp->fx_pcrel)
+ fprintf (stderr, " pcrel");
+ if (fixp->fx_pcrel_adjust)
+ fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust);
+ if (fixp->fx_im_disp)
+ {
+#ifdef TC_NS32K
+ fprintf (stderr, " im_disp=%d", fixp->fx_im_disp);
+#else
+ fprintf (stderr, " im_disp");
+#endif
+ }
+ if (fixp->fx_tcbit)
+ fprintf (stderr, " tcbit");
+ if (fixp->fx_done)
+ fprintf (stderr, " done");
+ fprintf (stderr, "\n size=%d frag=%lx where=%ld offset=%lx addnumber=%lx",
+ fixp->fx_size, (long) fixp->fx_frag, (long) fixp->fx_where,
+ (long) fixp->fx_offset, (long) fixp->fx_addnumber);
+#ifdef BFD_ASSEMBLER
+ fprintf (stderr, "\n %s (%d)", bfd_get_reloc_code_name (fixp->fx_r_type),
+ fixp->fx_r_type);
+#else
+#ifdef NEED_FX_R_TYPE
+ fprintf (stderr, " r_type=%d", fixp->fx_r_type);
+#endif
+#endif
+ if (fixp->fx_addsy)
+ {
+ fprintf (stderr, "\n +<");
+ print_symbol_value_1 (stderr, fixp->fx_addsy);
+ fprintf (stderr, ">");
+ }
+ if (fixp->fx_subsy)
+ {
+ fprintf (stderr, "\n -<");
+ print_symbol_value_1 (stderr, fixp->fx_subsy);
+ fprintf (stderr, ">");
+ }
+ fprintf (stderr, "\n");
+#ifdef TC_FIX_DATA_PRINT
+ TC_FIX_DATA_PRINT (stderr, fixp);
+#endif
+}
+
+/* end of write.c */
diff --git a/gas/write.h b/gas/write.h
new file mode 100644
index 00000000000..186d2ada1b6
--- /dev/null
+++ b/gas/write.h
@@ -0,0 +1,208 @@
+/* write.h
+ Copyright (C) 1987, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef __write_h__
+#define __write_h__
+
+#ifndef TC_I960
+#ifdef hpux
+#define EXEC_MACHINE_TYPE HP9000S200_ID
+#endif
+#endif /* TC_I960 */
+
+#ifndef BFD_ASSEMBLER
+
+#ifndef LOCAL_LABEL
+#define LOCAL_LABEL(name) (name [0] == 'L' )
+#endif
+
+#define S_LOCAL_NAME(s) (LOCAL_LABEL (S_GET_NAME (s)))
+
+#endif /* ! BFD_ASSEMBLER */
+
+/* This is the name of a fake symbol which will never appear in the
+ assembler output. S_IS_LOCAL detects it because of the \001. */
+#define FAKE_LABEL_NAME "L0\001"
+
+#include "bit_fix.h"
+
+/*
+ * FixSs may be built up in any order.
+ */
+
+struct fix
+{
+ /* These small fields are grouped together for compactness of
+ this structure, and efficiency of access on some architectures. */
+
+ /* pc-relative offset adjust (only used by m68k) */
+ char fx_pcrel_adjust;
+
+ /* How many bytes are involved? */
+ unsigned char fx_size;
+
+ /* Is this a pc-relative relocation? */
+ unsigned fx_pcrel : 1;
+
+ /* Is this a relocation to a procedure linkage table entry? If so,
+ some of the reductions we try to apply are invalid. A better way
+ might be to represent PLT entries with different kinds of
+ symbols, and use normal relocations (with undefined symbols);
+ look into it for version 2.6. */
+ unsigned fx_plt : 1;
+
+ /* Is this value an immediate displacement? */
+ /* Only used on i960 and ns32k; merge it into TC_FIX_TYPE sometime. */
+ unsigned fx_im_disp : 2;
+
+ /* A bit for the CPU specific code.
+ This probably can be folded into tc_fix_data, below. */
+ unsigned fx_tcbit : 1;
+
+ /* Has this relocation already been applied? */
+ unsigned fx_done : 1;
+
+ /* Suppress overflow complaints on large addends. This is used
+ in the PowerPC ELF config to allow large addends on the
+ BFD_RELOC_{LO16,HI16,HI16_S} relocations.
+
+ @@ Can this be determined from BFD? */
+ unsigned fx_no_overflow : 1;
+
+ /* The value is signed when checking for overflow. */
+ unsigned fx_signed : 1;
+
+ /* Which frag does this fix apply to? */
+ fragS *fx_frag;
+
+ /* Where is the first byte to fix up? */
+ long fx_where;
+
+ /* NULL or Symbol whose value we add in. */
+ symbolS *fx_addsy;
+
+ /* NULL or Symbol whose value we subtract. */
+ symbolS *fx_subsy;
+
+ /* Absolute number we add in. */
+ valueT fx_offset;
+
+ /* Next fixS in linked list, or NULL. */
+ struct fix *fx_next;
+
+ /* If NULL, no bitfix's to do. */
+ /* Only i960-coff and ns32k use this, and i960-coff stores an
+ integer. This can probably be folded into tc_fix_data, below.
+ @@ Alpha also uses it, but only to disable certain relocation
+ processing. */
+ bit_fixS *fx_bit_fixP;
+
+#ifdef BFD_ASSEMBLER
+ bfd_reloc_code_real_type fx_r_type;
+#else
+#ifdef NEED_FX_R_TYPE
+ /* Hack for machines where the type of reloc can't be
+ worked out by looking at how big it is. */
+ int fx_r_type;
+#endif
+#endif
+
+ /* This field is sort of misnamed. It appears to be a sort of random
+ scratch field, for use by the back ends. The main gas code doesn't
+ do anything but initialize it to zero. The use of it does need to
+ be coordinated between the cpu and format files, though. E.g., some
+ coff targets pass the `addend' field from the cpu file via this
+ field. I don't know why the `fx_offset' field above can't be used
+ for that; investigate later and document. KR */
+ valueT fx_addnumber;
+
+ /* The location of the instruction which created the reloc, used
+ in error messages. */
+ char *fx_file;
+ unsigned fx_line;
+
+#ifdef USING_CGEN
+ struct {
+ /* CGEN_INSN entry for this instruction. */
+ const struct cgen_insn *insn;
+ /* Target specific data, usually reloc number. */
+ int opinfo;
+ } fx_cgen;
+#endif
+
+#ifdef TC_FIX_TYPE
+ /* Location where a backend can attach additional data
+ needed to perform fixups. */
+ TC_FIX_TYPE tc_fix_data;
+#endif
+};
+
+typedef struct fix fixS;
+
+#ifndef BFD_ASSEMBLER
+extern char *next_object_file_charP;
+
+#ifndef MANY_SEGMENTS
+COMMON fixS *text_fix_root, *text_fix_tail; /* Chains fixSs. */
+COMMON fixS *data_fix_root, *data_fix_tail; /* Chains fixSs. */
+COMMON fixS *bss_fix_root, *bss_fix_tail; /* Chains fixSs. */
+extern struct frag *text_last_frag; /* Last frag in segment. */
+extern struct frag *data_last_frag; /* Last frag in segment. */
+#endif
+COMMON fixS **seg_fix_rootP, **seg_fix_tailP; /* -> one of above. */
+#endif
+
+extern long string_byte_count;
+extern int section_alignment[];
+
+extern bit_fixS *bit_fix_new
+ PARAMS ((int size, int offset, long base_type, long base_adj, long min,
+ long max, long add));
+extern void append PARAMS ((char **charPP, char *fromP, unsigned long length));
+extern void record_alignment PARAMS ((segT seg, int align));
+extern void subsegs_finish PARAMS ((void));
+extern void write_object_file PARAMS ((void));
+extern long relax_frag PARAMS ((fragS *, long));
+extern void relax_segment
+ PARAMS ((struct frag * seg_frag_root, segT seg_type));
+
+extern void number_to_chars_littleendian PARAMS ((char *, valueT, int));
+extern void number_to_chars_bigendian PARAMS ((char *, valueT, int));
+
+#ifdef BFD_ASSEMBLER
+extern fixS *fix_new
+ PARAMS ((fragS * frag, int where, int size, symbolS * add_symbol,
+ offsetT offset, int pcrel, bfd_reloc_code_real_type r_type));
+extern fixS *fix_new_exp
+ PARAMS ((fragS * frag, int where, int size, expressionS *exp, int pcrel,
+ bfd_reloc_code_real_type r_type));
+#else
+extern fixS *fix_new
+ PARAMS ((fragS * frag, int where, int size, symbolS * add_symbol,
+ offsetT offset, int pcrel, int r_type));
+extern fixS *fix_new_exp
+ PARAMS ((fragS * frag, int where, int size, expressionS *exp, int pcrel,
+ int r_type));
+#endif
+
+extern void write_print_statistics PARAMS ((FILE *));
+
+#endif /* __write_h__ */
+/* end of write.h */
diff --git a/gprof/.gdbinit b/gprof/.gdbinit
new file mode 100644
index 00000000000..e519472ebcd
--- /dev/null
+++ b/gprof/.gdbinit
@@ -0,0 +1 @@
+dir ..
diff --git a/gprof/ChangeLog b/gprof/ChangeLog
new file mode 100644
index 00000000000..24626c2d098
--- /dev/null
+++ b/gprof/ChangeLog
@@ -0,0 +1,1319 @@
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * gprof.h (LC_MESSAGES): Never define.
+ * gprof.c (main): Don't pass LC_MESSAGES to setlocale if the
+ system does not define it.
+
+1999-04-05 H.J. Lu <hjl@gnu.org>
+
+ * corefile.c (core_create_line_syms): Don't use fixed size array
+ for prev_name and prev_filename.
+
+1999-04-04 Michael Hohmuth <hohmuth@innocent.com>
+
+ * gprof.h (FF_BSD44): Define.
+ * gmon.h (struct raw_phdr): Add version, profrate, and spare
+ fields unconditionally.
+ (struct old_raw_phdr): New struct.
+ * gprof.c (main): Handle -O 4.4bsd.
+ * gmon_io.c (gmon_out_read): Handle BSD 4.4 format, either
+ automatically or by user specification.
+ (gmon_out_write): Handle BSD 4.4 format.
+ * configure.in: Don't set BSD44_FORMAT.
+ * gprof.texi (Miscellaneous Options): Document -O 4.4bsd.
+ * configure, gconfig.in: Rebuild.
+
+Tue Feb 16 17:01:33 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change AC_PREREQ to 2.13. Change AM_PROG_INSTALL
+ to AC_PROG_INSTALL. Remove AM_CYGWIN32. Change AM_EXEEXT to
+ AC_EXEEXT. Add comment to AC_DEFINE.
+ * acconfig.h: Remove.
+ * aclocal.m4: Rebuild.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+ * gconfig.in: Rebuild.
+
+Sun Dec 6 21:57:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.texi (Symspecs): Mention that you have to add any
+ underscore yourself when naming a symbol.
+
+Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Wed Aug 12 14:59:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Avoid some overflow cases:
+ * basic_blocks.h (bb_min_calls): Change to unsigned long.
+ * call_graph.h (cg_tally): Change count parameter to unsigned
+ long.
+ * cg_arcs.h (Arc): Change count field to unsigned long.
+ (arc_add): Change count parameter to unsigned long.
+ * source.h (Source_File): Change ncalls field to unsigned long.
+ * symtab.h (Sym): Change fields ncalls, bb_calls, and
+ cg.self_calls to unsigned long.
+ * Many files: Update accordingly.
+
+ * configure, Makefile.in, aclocal.m4: Rebuild with current tools.
+
+Fri Jul 10 17:29:49 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * configure.in (BSD44_FORMAT): Define for cygwin32, win32, mingw32
+ * configure: Rebuild.
+
+Fri Jun 12 13:40:05 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): If maintainer mode, depend on .pot file.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+Sun May 10 22:35:33 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Tue May 5 18:28:40 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gprof.h (_): Undefine BFD's version.
+
+Tue Apr 28 19:17:33 1998 Tom Tromey <tromey@cygnus.com>
+
+ * gprof.c (main): Conditionally call setlocale.
+ * gprof.h: Include <locale.h> if HAVE_LOCALE_H.
+ (LC_MESSAGES): Now can be defined even when ENABLE_NLS.
+
+Tue Apr 28 19:50:09 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * corefile.c: Rename from core.c.
+ * corefile.h: Rename from core.h.
+ * Many .c files: Include corefile.h rather than core.h.
+ * Makefile.am (sources): Change core.c to corefile.c.
+ (noinst_HEADERS): Change core.h to corefile.h.
+ ($(OBJECTS)): Depend upon corefile.h rather than core.h.
+ (corefile.o): Rename target from core.o, depend upon corefile.c.
+ * Makefile.in, po/POTFILES.in: Rebuild.
+
+Mon Apr 27 16:50:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.9.4
+ * configure: Rebuild.
+
+Wed Apr 22 16:01:17 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir).
+
+Wed Apr 22 00:00:22 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * gprof.h: Added includes and defines for gettext.
+ * configure.in (ALL_LINGUAS): New macro.
+ Call CY_GNU_GETTEXT. Create po/Makefile.in and po/Makefile.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY,
+ HAVE_LC_MESSAGES): Define.
+ * gprof.c (main): Call setlocale, bindtextdomain, textdomain.
+ * Makefile.am (SUBDIRS): New macro.
+ (INCLUDES): Look in intl dirs for headers. Define LOCALEDIR.
+ (gprof_DEPENDENCIES): Added INTLDEPS.
+ (gprof_LDADD): Added INTLLLIBS.
+ (POTFILES): New macro.
+ (po/POTFILES.in): New target.
+ * Many files: Wrap user-visible strings with gettext invocation.
+
+Tue Apr 7 12:43:37 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From hjl@lucon.org <H.J. Lu>:
+ * Makefile.am (diststuff): New target.
+ * Makefile.in: Rebuild.
+
+Mon Mar 30 12:47:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set version to 2.9.1.
+ * configure: Rebuild.
+
+ * Branched binutils 2.9.
+
+Sat Mar 28 23:09:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Fix some gcc -Wall warnings:
+ * cg_arcs.c (num_cycles): Change to unsigned int.
+ (numarcs): Likewise.
+ (arc_add): Change maxarcs to unsigned int.
+ (cg_assemble): Change index to unsigned int.
+ * cg_arcs.h (num_cycles, numarcs): Update declarations.
+ * cg_print.c (cg_print): Change index to unsigned int.
+ (cg_print_index): Change index, nnames, todo, i, and j to unsigned
+ int.
+ (cg_print_file_ordering): Change symbol_count and index2 to
+ unsigned int.
+ * core.c (symbol_map_count): Change to unsigned int.
+ (core_create_function_syms): Change j to unsigned int.
+ (core_create_line_syms): Add cast to avoid warning.
+ * hist.c (hist_assign_samples): Change j to unsigned int.
+ (hist_print): Change index to unsigned i nt. Add cast to avoid
+ warning.
+ * sym_ids.c (parse_spec): Add casts to avoid warning.
+ * symtab.c (symtab_finalize): Change j to unsigned int.
+ (sym_lookup): Update printf format strings.
+ * symtab.h (Sym_Table): Change len to unsigned int.
+ * tahoe.c (tahoe_reladdr): Add casts to avoid warnings.
+
+Tue Mar 24 19:00:11 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Add --demangle and --no-demangle options:
+ * gprof.h (demangle): Declare.
+ * gprof.c (demangle): New global variable.
+ (OPTION_DEMANGLE, OPTION_NO_DEMANGLE): Define.
+ (long_options): Add "demangle" and "no-demangle".
+ (usage): Mention --demangle and --no-demangle.
+ (main): Handle OPTION_DEMANGLE and OPTION_NO_DEMANGLE.
+ * utils.c (print_name_only): Only demangle symbol name if demangle
+ is true.
+ * gprof.texi (Output Options): Document new options.
+
+Fri Mar 20 19:21:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild with automake 1.2e.
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Thu Feb 12 14:36:05 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.c (usage): Update bug-gnu-utils address.
+
+Sat Feb 7 15:43:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Fri Feb 6 12:02:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * alpha.c (alpha_Instruction): Use int, not signed.
+
+Fri Feb 6 02:00:19 1998 Jeffrey A Law (law@cygnus.com)
+
+ * core.c (core_init): Adding missing "break".
+
+Thu Feb 5 12:49:37 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, Makefile.in, aclocal.m4: Rebuild with new libtool.
+
+Tue Feb 3 14:25:25 1998 Brent Baccala <baccala@freesoft.org>
+
+ * bbconv.pl: New file.
+ * Makefile.am (EXTRA_DIST): Add bbconv.pl.
+ * Makefile.in: Rebuild.
+
+ * gprof.texi: Extensive additions to document all arguments and
+ output formats.
+
+ * symtab.c (symtab_finalize): Prefer function symbols over line
+ symbols.
+ (dbg_sym_lookup): Correct debugging messages.
+
+ * gprof.c (main): --sum implies --line.
+
+ * cg_print.c (cg_print): When doing line by line profiling, don't
+ use a non-function as a main listing item.
+
+ * call_graph.c (cg_tally): When using line by line profiling, use
+ the function symbol as the child.
+
+ * symtab.h (NBBS): Define.
+ (Sym): Add bb_addr and bb_calls fields.
+ * basic_blocks.c (bb_read_rec): Save multiple basic blocks per
+ symbol.
+ (bb_write_blocks): Adjust for multiple basic blocks per symbol.
+ (print_exec_counts): Don't check whether a symbol is the start of
+ a basic block. Print all basic blocks for a symbol.
+ (annotate_with_count): Rewrite to print all basic block counts and
+ to pay attention to width argument.
+ (print_annotated_source): Don't check whether symbol is the start
+ of a basic block.
+
+ Make it possible to build a cross gprof, although a few cases are
+ still not handled:
+ * configure.in: Don't set MY_TARGET.
+ * gprof.h: Don't include MACHINE_H. Don't define FOPEN_RB or
+ FOPEN_WB; just get them from sysdep.h.
+ * core.h (min_insn_size, offset_to_code): Declare.
+ * core.c (MIN_INSN_SIZE): Don't define.
+ (min_insn_size, offset_to_code): New variables.
+ (core_init): Initialize min_insn_size and offset_to_code.
+ (find_call): New function.
+ (core_create_line_syms): Don't use min_dist. Set is_static in
+ pass 2.
+ * hist.c (UNITS_TO_CODE): Define.
+ * gprof.c (default_excluded_list): Add "__mcount_internal".
+ * gmon.h: Change TARGET_alpha to __alpha__.
+ * hertz.h: Ifdef MACH, define hertz as HZ.
+ * alpha.c (alpha_Instruction): Rename from Instruction. Change
+ all references.
+ (alpha_find_call): Rename from find_call.
+ * alpha.h: Remove.
+ * dummy.c, dummy.h: Remove.
+ * i386.c (i386_iscall): Rename from iscall. Change all
+ references. Check for call instruction, not jump or lcall.
+ (i386_find_call): Rename from find_call. Correct for VMA.
+ Correct call destination computation. Don't dereference symbol if
+ it is NULL.
+ * i386.h: Remove.
+ * ns532.c, ns532.h: Remove.
+ * sparc.c (CALL): Define.
+ (sparc_find_call): Rename from find_call.
+ * sparc.h: Remove.
+ * tahoe.c: Include cg_arcs.h, core.h, hist.h, and symtab.h. Don't
+ include time_host.h.
+ (CALLF, PC): Define.
+ (enum tahoe_opermodes, tahoe_operandenum): Define. Rename all
+ references to opermodes or operandenum to these.
+ (tahoe_operandmode): Rename from operandmode. Call abort if
+ switch does not return.
+ (tahoe_operandname): Rename from operandname. Call abort if
+ switch does not return.
+ (tahoe_operandlength): Rename from operandlength. Call abort if
+ switch does not return.
+ (tahoe_reladdr): Rename from reladdr.
+ (tahoe_find_call): Rename from find_call. Use core_text_space
+ rather than textspace.
+ * tahoe.h: Remove.
+ * vax.c (CALLS, PC): Define.
+ (enum opermodes, operandenum, struct modebyte): Define.
+ (vax_operandmode): Rename from operandmode. Call abort if switch
+ does not return.
+ (vax_operandname): Rename from operandname. Call abort if switch
+ does not return.
+ (vax_operandlength): Rename from operandlength. Call abort if
+ switch does not return.
+ (vax_reladdr): Rename from reladdr.
+ (vax_find_call): Rename from find_call.
+ * vax.h: Remove.
+ * Makefile.am (AUTOMAKE_OPTIONS): Set to cygnus.
+ (MY_TARGET): Remove.
+ (INCLUDES): Remove -DTARGET_$(MY_TARGET) and -DMACHINE_H=
+ \"$(MY_TARGET).h\".
+ (gprof_SOURCES): Add i386.c, alpha.c, vax.c, tahoe.c, sparc.c.
+ (gprof_DEPENDENCIES): Remove $(MY_TARGET).o.
+ (gprof_LDADD): Likewise.
+ (noinst_HEADERS): Remove alpha.h, i386.h, ns532.h, sparc.h,
+ tahoe.h, vax.h, dummy.h.
+ (EXTRA_DIST): Remove alpha.c, i386.c, ns532.c, sparc.c, tahoe.c,
+ vax.c, dummy.c.
+ ($(OBJECTS)): Don't depend upon $(MY_TARGET).h.
+ ($(MY_TARGET).o): Remove target.
+ (i386.o, alpha.o, vax.o, tahoe.o, sparc.o): New targets.
+ * configure, Makefile.in, aclocal.m4: Rebuild.
+
+Mon Dec 29 14:17:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * core.c (core_sym_class): Treat weak symbols as text symbols.
+ From Dean Gaudet <dgaudet@arctic.org>.
+
+Wed Sep 24 11:35:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4: Rebuild with new libtool.
+ * Makefile.in: Rebuild with current automake.
+ * configure: Rebuild.
+
+Sat Aug 9 16:25:01 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.8.2. Call
+ AM_PROG_LIBTOOL. Remove shared library handling; now handled by
+ libtool. Add AM_CONFIG_HEADER. Change AC_PROG_INSTALL to
+ AM_PROG_INSTALL. Add AM_EXEEXT.
+ * Makefile.am (LINK): Remove.
+ (gprof_LDFLAGS): Remove
+ (gprof_DEPENDENCIES): Change libbfd.a to libbfd.la.
+ (gprof_LDADD): Likewise.
+ ($(OBJECTS)): Depend upon gconfig.h and ../bfd/config.h.
+ * gprof.h: Undefine PACKAGE and VERSION after including BFD
+ sysdep.h file, then include new gconfig.h file.
+ * gprof.c (VERSION): Don't define.
+ * acconfig.h: New file.
+ * stamp-h.in: New file.
+ * gconfig.in: New file, created by autoheader.
+ * Makefile.in, configure, aclocal.m4: Rebuild.
+
+Sat Jun 28 23:20:42 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure, Makefile.in: Rebuild with automake 1.2.
+
+Mon Jun 16 15:31:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (INCLUDES): Add -DDEBUG.
+ * Makefile.in: Rebuild.
+
+Tue Apr 15 14:19:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Change to use automake:
+ * Makefile.am: New file.
+ * configure.in: Run AM_INIT_AUTOMAKE, AM_MAINTAINER_MODE, and
+ AM_CYGWIN32.
+ * aclocal.m4: New file, created by aclocal.
+ * Makefile.in: Replace with file created by automake --cygnus.
+ * configure: Rebuild.
+
+Thu Apr 3 13:21:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.c (VERSION): Define as "2.8.1".
+
+ * Branched binutils 2.8.
+
+Thu Mar 27 17:15:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.c (main): Correct copyright message.
+
+Mon Mar 24 11:12:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (.c.o): Define TARGET_$(MY_TARGET) when compiling.
+ * gmon.h: Use bytes counts rather than sizeof in struct raw_phdr
+ and struct raw_arc.
+
+Mon Mar 17 10:54:47 1997 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * cg_arcs.c (arc_add): memset() newly alloced arc to ensure
+ all fields are initialized with 0.
+
+Sat Mar 15 19:17:31 1997 H.J. Lu <hjl@lucon.org>
+
+ * symtab.h (find_call): Declare.
+ * cg_arcs.c (cg_assemble): Don't declare find_call.
+ * hist.c (scale_and_align_entries): Declare.
+
+Thu Feb 27 12:46:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Define BSD44_FORMAT if the target looks like a
+ BSD4.4 derived system.
+ * configure: Rebuild.
+ * Makefile.in (.c.o): Add @DEFS@.
+ * gmon_io.c (gmon_out_read): In BSD44_FORMAT code, get profrate
+ from profrate field, not version field.
+
+Thu Jan 16 17:42:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * dummy.c (find_call): Clear ignore_direct_calls.
+
+Tue Dec 31 15:44:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (.c.o): Add -D_GNU_SOURCE. Put $(CFLAGS) at the
+ end.
+ (gprof): Put $(CFLAGS) after the other options.
+
+Tue Nov 26 17:08:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.
+
+Wed Oct 2 15:23:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc.c (find_call): Align p_lowpc to avoid bus error.
+
+Tue Oct 1 15:58:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.c (usage): Print bug report address.
+ (main): Change version printing to match current GNU standards.
+
+Fri Aug 30 12:16:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gmon.h: Replace #elif with #else/#endif.
+
+Thu Aug 29 17:04:10 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in (i[345]86-*-*): Recognize i686 for pentium pro.
+ * configure: Regenerate.
+
+Thu Aug 22 17:12:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set and substitute HLDENV.
+ * configure: Rebuild.
+ * Makefile.in (HLDENV): New variable.
+ (gprof): Use $(HLDENV).
+
+Wed Aug 7 14:43:51 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * core.c (read_function_mappings): Cast xmalloc return.
+
+Thu Jul 4 12:01:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.c (VERSION): Define as "2.7.1".
+
+ * Released binutils 2.7.
+
+ * bb_exit_func.c: Rename from __bb_exit_func.c, so that it can be
+ stored on a System V file system.
+
+Thu Jun 27 11:36:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_ISC_POSIX.
+ * configure: Rebuild.
+ * Makefile.in (gprof): Pass $(CFLAGS) during link.
+ * hertz.c: Don't include <sys/time.h>; let sysdep.h handle that.
+ If HAVE_SETITIMER is not defined, try using sysconf.
+
+Mon Jun 24 18:27:28 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (exec_prefix, bindir, libdir, mandir, infodir, datadir,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ (AC_PROG_INSTALL): added.
+ * configure: Rebuilt.
+
+Mon Jun 24 12:03:09 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: On alpha*-*-osf*, link against libbfd.a if not
+ using shared libraries.
+ * configure: Rebuild with autoconf 2.10.
+
+Tue Jun 18 17:35:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * core.c (core_create_line_syms): Use xstrdup rather than strdup.
+ * source.c (source_file_lookup_path): Likewise.
+
+Mon Apr 8 14:44:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+ * configure: Rebuild.
+
+Thu Mar 21 17:18:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * core.c (core_create_function_syms): Move filename and func_name
+ inside ifdef where they are used.
+
+ * core.c (core_sym_class): Parenthesize && within ||.
+ * symtab.c (symtab_finalize): Correct parenthesization.
+
+ * cg_print.h (cg_print_file_ordering): Declare.
+ (cg_print_function_ordering): Declare.
+
+ * __bb_exit_func.c (__bb_exit_func): Replace bcopy with memcpy.
+ * cg_arcs.c (arc_add): Likewise.
+ * cg_print.c (cg_print_function_ordering): Likewise.
+
+Thu Mar 21 17:02:02 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * gprof.c (default_excluded_list): Add "__mcount".
+
+ * gprof.c (main): Change ifdef __osf__ to __alpha__.
+
+ * gmon_io.c (gmon_out_read): If BSD44_FORMAT is defined, get the
+ profiling rate from the header.
+
+ * gmon.h (struct raw_phdr): Only include pad if both __alpha__ and
+ __osf__ are defined. Add new fields if BSD44_FORMAT is defined.
+
+ * alpha.h (MIN_INSN_SIZE): Define.
+ * core.c (MIN_INSN_SIZE): If not defined, define as 1.
+ (core_sym_class): Ignore debugging symbols.
+ (core_create_line_syms): Use MIN_INSN_SIZE when gathering line
+ information.
+
+Wed Mar 20 18:15:47 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * cg_print.c (cg_print_function_ordering): Fix __GNUC__ misspelled
+ as __GNU_C__.
+ (order_and_dump_functions_by_arcs): Likewise.
+
+Tue Mar 12 12:19:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.8.
+
+Sun Feb 18 15:06:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check for 'do not mix' from native linker before
+ trying to use -rpath.
+ * configure: Rebuild.
+
+Tue Feb 13 15:32:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set HDLFLAGS for *-*-hpux with --enable-shared.
+ * configure: Rebuild.
+
+Wed Feb 7 14:03:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't set CC. Look for --enable-shared. Set
+ BFDLIB and HLDFLAGS and substitute them.
+ * configure: Rebuild.
+ * Makefile.in (LIBS): Use @BFDLIB@.
+ (HLDFLAGS): New variable.
+ (gprof): Use $(HLDFLAGS).
+
+Mon Feb 5 16:34:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Support for building bfd and opcodes as shared libraries, based on
+ patches from Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * Makefile.in (LIBDEPS): New variable.
+ (LIBS): Use -L../bfd -lbfd.
+ (gprof): Depend upon $(LIBDEPS) rather than $(LIBS).
+
+Sat Dec 30 10:11:03 1995 Jeffrey A Law (law@cygnus.com)
+
+ * gprof.c (long_options): Add "--function-ordering" and
+ "--file-ordering" options.
+ (usage): Add new options to usage message.
+ (main): Handle new options.
+ * gprof.h (STYLE_FUNCTION_ORDER): Define.
+ (STYLE_FILE_ORDER): Define.
+ (function_mapping_file): Declare.
+ * cg_arcs.c (arcs, numarcs): New globals.
+ (arc_add): Put new arcs into the arc array so the function/file
+ ordering code can examine them.
+ * cg_arcs.h (struct arc): New field "has_been_placed".
+ (arcs, numarcs): Declare new globals.
+ * core.c (symbol_map, symbol_map_count): New globals.
+ (read_function_mappings): New function to read in a function
+ to object map file.
+ (core_init): Call read_function_mappings if a function mapping
+ file exists.
+ (core_create_function_syms): Handle function to object file
+ mappings.
+ * symtab.h (struct sym): New fields "mapped", "has_been_placed",
+ "nuses", "prev".
+ * cg_print.c (cmp_arc_count): New function for sorting arcs.
+ (cmp_fun_nuses): Likewise for functions.
+ (cg_print_function_ordering): New function to print a suggested
+ function ordering.
+ (cg_print_file_ordering): Likewise for ordering .o files.
+ (order_and_dump_functions_by_arcs): Helper function for function
+ and object file ordering code.
+
+Sun Dec 24 21:32:27 1995 Jeffrey A Law (law@cygnus.com)
+
+ * core.c (core_sym_class): Ignore symbols without BSF_FUNCTION
+ set if ignore_non_function is set.
+ * gprof.h (ignore_non_functions): Declare.
+ * gprof.c (ignore_non_functions): Define.
+ (long_options): Add "ignore-non-functions".
+ (usage): Add new options.
+ (main): Recognize "-D" and "--ignore-non-functions" option.
+
+Tue Nov 21 13:24:39 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (.m.c): Strip out directory name from function
+ name.
+
+ * hist.c (scale_and_align_entries): Don't use DEFUN_VOID. Do
+ UNITS_TO_CODE adjustment unconditionally; compiler can optimize
+ away zero-offset case. Refer to scaled_addr, not aligned_addr.
+
+ * vax.c: Don't include vax.h here.
+
+Thu Nov 16 03:41:37 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Version 2.6 released.
+
+Wed Nov 8 11:40:04 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * gprof.c (main): Cast getenv return value.
+
+Mon Nov 6 15:05:00 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.in (TAGS): New target.
+
+Wed Nov 1 12:51:21 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (DISTSTUFF): Rename to GEN_FILES, to avoid confusion.
+ (all): Depend on $(GEN_FILES), not diststuff (which also depends
+ on info).
+
+Wed Nov 1 15:23:15 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * sym_ids.c: Include <ctype.h>.
+
+Wed Oct 25 13:24:31 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (diststuff): Also make info.
+ (mostlyclean): Don't remove gprof.info*.
+ (maintainer-clean realclean): Also remove *.info*.
+
+Fri Oct 6 16:25:32 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Makefile.in: Add dependecies for $(OBJS) on header files.
+
+ * cg_print.c (print_cycle, print_members, cg_print_index): Fix new
+ style output format to make it consistent.
+ * dummy.c (find_call): Fix typo in error message.
+
+Wed Sep 20 13:21:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target, synonym for
+ realclean.
+
+Fri Sep 8 14:38:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install): Don't install in $(tooldir).
+
+Fri Aug 25 15:30:05 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ NS32K changes from Ian Dall:
+ * configure.in: Use ns32k, not ns532.
+ * ns532.c: Include symtab.h.
+ (find_call): Renamed from findcall. Print a message.
+ * ns532.h: Remove dummy.h comments.
+
+Tue Aug 22 10:00:45 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * Makefile.in (install): Remove "brokensed" hack, unnecessary now
+ that we're using autoconf.
+
+Wed Jul 19 18:46:13 1995 Fred Fish <fnf@cygnus.com>
+
+ * core.c (get_src_info): Cast arg 7 of bfd_find_nearest_line
+ to proper type of "unsigned int *".
+
+Fri Jun 16 15:29:36 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Use changequote around use of [].
+
+Mon Jun 12 12:14:52 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (distclean, realclean): Remove config.cache and
+ config.log.
+
+Wed May 17 17:56:53 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (Makefile): Added config.status to dependency list.
+ (config.status): New target.
+ (SHELL): New definition.
+
+Tue Apr 25 21:11:12 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (install): Depend on "all".
+
+Thu Apr 20 17:29:07 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in: Change all references to MY_MACHINE to MY_TARGET,
+ to match configure script.
+
+Wed Apr 19 11:19:37 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * gen-c-prog.awk: Changed reference to "make-c-prog.awk" in
+ comment emitted by this script to gen-c-prog.awk.
+
+ * Makefile.in, configure.in: Converted to use autoconf.
+ * configure: New file, generated with autoconf 2.3.
+ * config/{mt-alpha, mt-dummy, mt-i386, mt-ns532, mt-sparc,
+ mt-tahoe, mt-vax}: Removed.
+
+Mon Mar 13 21:44:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * __bb_exit_func.c: New file, from David Mosberger-Tang.
+
+ Thu Feb 9 16:56:07 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
+
+ * All *.c: More cleanup towards GNU format.
+
+ * gmon_out.h (struct gmon_hist_hdr, struct gmon_cg_arc_record):
+ replaced sizeof (bfd_vma) by size (char*) because Ken tells me
+ that bfd_vma is only guaranteed to be at least as big as a pointer.
+
+ (GMON_Record_tag): added explicit enumeration values to ensure
+ compatibility across compilers.
+
+ * gmon_io.c (get_vma, put_vma): replaced sizeof(bfd_vma) by
+ sizeof(char*).
+
+Tue Feb 7 17:24:12 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * All *.c and *.h files: Ran "indent -gnu". Cleaned up a couple
+ of constructs GNU indent couldn't handle. Block comments not yet
+ rewritten in GNU format.
+
+ * gprof.c (VERSION): Changed to 2.6, to get in sync for next
+ binutils release.
+
+Sun Feb 5 16:19:46 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
+
+ * symtab.c (symtab_finalize): ensure globals symbols really
+ are favored over static ones---even if their name looks less
+ preferable; this is important for HP-UX; for example, there
+ is a static label Ltext_something that aliases the global
+ symbol _start
+
+ * hist.c (hist_print): auto-scaling is now in effect for FSF-style
+ output only; also, auto-scaling is now performed based on
+ per-call, rather than total execution time, which is what it was
+ meant to be.
+
+ * gprof.h (File_Format): new type.
+
+ * gprof.c (VERSION): upped to 2.7---seems to be completely out of
+ sync with Cygnus version numbers though...
+
+ (long_options): renamed --gmon-info to --file-info, --width added,
+ renamed --old-file-format to --file-format
+ (main): dito; also added support to read prof files, but as
+ mon_out_read() is not implemented, it's #ifdef'd out for now
+
+ (usage): update to reflect new options.
+
+ * gmon_io.c: replaced "old_file_format" by more general
+ "file_format" option
+
+ * gmon.h (struct raw_phdr): fixed declaration for OSF/1.
+
+ * core.c (core_sym_class): added back check for __gnu_compiled and
+ ___gnu_compiled for the benefit of systems without
+ bfd_find_nearest_line() support
+
+ (get_src_info): now the libbfd is fixed, invoke bfd_find_nearest_line()
+ with section-relative addresses
+
+ (core_create_function_syms): get_src_info() calls are currently
+ enabled for OSF/1 only. It appears to work allright for SunOS
+ 4.1.x as well, but on SPARCs it gets painfully slow with the
+ current implementation of aout_32_find_nearest_line();
+ unfortunately, this means that static functions will not have their
+ filename printed in the call-graph function index; line-level
+ profiling should still work, but requires some patience
+
+ * cg_print.c (cg_print_index): sanitised printing of index when
+ using FSF-style output; in particular, output width is now controlled
+ via option --width and the function tries hard to keep columns
+ aligned even in the presence of (occasional) long names
+
+ * NOTES: a first shot at updating the documentation.
+
+Wed Feb 1 19:07:44 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
+
+ * core.c (core_create_function_syms): fixed computation of min_vma
+ and max_vma.
+
+ * *.c: removed rcsid.
+
+Tue Jan 31 16:18:18 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Lots of changes from David Mosberger-Tang:
+
+ Tue Oct 25 19:20:14 1994 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
+
+ * gprof.c (main): put parentheses around & within &&.
+
+ * basic_blocks.c (bb_read_rec): print warning message (once) when
+ ignoring basic-block execution counts.
+
+ * source.c (source_file_lookup_name): corrected second argument to
+ strcmp().
+
+ * hist.c (print_header): merged Fri Oct 21 18:58:02 1994 change by
+ Ken Raeburn <raeburn@cujo.cygnus.com> from binutils-2.5.1.
+
+ * gmon_io.c (gmon_out_read): the output stule STYLE_GMON_INFO is now
+ supported both for old and new (versioned) gmon.out files. Old
+ files are identified as version 0.
+
+ * gmon.h (struct raw_arc): count field is now sizeof(long) bytes
+ long (instead of 4) because that is what OSF/1 v3.0 uses.
+
+ * core.c: minor fixes and debugging info changes.
+
+ Sun Sep 11 18:47:47 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * core.c (core_init): if .text cannot be found, try $CODE$ (the
+ name of the text-section under HP-UX).
+
+ * hist.c (hist_assign_samples): fixed off-by-one bug: highpc
+ points one past the last sampling bin, so hist_scale should be
+ computed as "hist_scale /= hist_num_bins", not "hist_scale /=
+ hist_num_bins - 1".
+
+ * gmon_io.c, hist.c, hist.h: renamed hist_num_samples to
+ hist_num_bins.
+
+ * configure.in: added alpha-*-*) for per-target config.
+
+ * alpha.c, alpha.h: created.
+
+ * gprof.c (default_excluded_list): <locore>, <hicore> added.
+
+ * core.c (core_create_function_syms, core_create_line_syms):
+ explicitly keep two sentinels "<locore>" and "<hicore>" that catch
+ all addresses outside the text-space. Thus, sym_lookup(&symtab,
+ addr) continues to guarantee not to return 0 on any address. It
+ also avoids incorrectly crediting the first/last symbol in the
+ text-space.
+
+ * core.c (core_create_line_syms): always create function symbols
+ first, then merge in line symbols; this is so that if parts of the
+ program were compiled without -g, function-level symbols are
+ available still.
+
+ * utils.c (print_name_only): support for print_path added.
+
+ * symtab.c (cmp_addr): also use is_func flag in comparison.
+ (symtab_finalize): return immediately when table empty; now
+ more careful about getting rid of the right duplicate symbol.
+
+ * sparc.c (find_call): many fixes---this function was rather
+ botched in binutils-2.4 already; it should work again.
+
+ * source.c (source_file_lookup_path): PATH is now strdup'ed (it is
+ not good to rely on get_src_info() to return distinct string
+ pointers).
+
+ * search_list.c (search_list_append): added cast for xmalloc().
+
+ * hist.c: added explicit initialization to some of the global
+ variables; fixed SItab (scales were off by a factor of 10).
+
+ * hist.h: include of bfd.h added.
+
+ * gprof.c, gprof.h (print_path): added.
+
+ * gprof.h (MAX): fixed.
+
+ * gmon_out.h: renamed gmon_time_hist_hdr to gmon_hist_hdr.
+
+ * gmon_io.c: added some casts to (long) so we can always print as %lx
+
+ * core.c (core_get_text_space): fixed to make it work.
+
+ * cg_print.c (cg_print_index): added support for print_path option.
+
+ * cg_dfn.h (cg_dfn): wrap prototype in PARAMS().
+
+ * call_graph.c, gmon_io.c, hist.c: avoid taking address of array
+ as some compilers complain (e.g., DEC's OSF/1 compiler)
+
+ * basic_blocks.c, gmon_io.c, hist.c, source.c, sym_ids.c,
+ symtab.c: calls to memset() had 2nd and 3rd args reversed.
+
+ Sat Sep 10 21:53:13 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * gprof.c: added "_mcount" to default_excluded_list.
+ (main): if output_style==0 and there is either a histogram or a
+ call-graph, always generate flat and call-graph, no matter what
+ line_granularity is set to.
+
+ * source.c (source_file_lookup_name): if searching for sf->name
+ fails, try again with filename obtained after stripping off any
+ partial path from sf->name.
+
+ * gprof.h (SRCDEBUG): added.
+
+ * search_list.c (search_list_append): directories were added in wrong
+ order.
+
+ * reimplemented selection mechanism from ground up; it is now possible
+ to accurately control what gets included/excluded in each of the
+ output styles; a "symbol-specification" (spec) is the basic means
+ to select a set of symbols; a spec has the syntax:
+
+ spec == (FILENAME:(FUNCNAME|LINE_NUM) | NAME).
+ arc == spec/spec.
+
+ any of the terminal symbols can be empty, in which case they
+ match anything (wildcards). NAME is interpreted as a FILENAME
+ if it contains a dot (e.g., foo.c), as LINE_NUM if it starts
+ with a digit, and as FUNCNAME otherwise.
+
+ For example, to get a call-graph display that ignores arcs
+ from foo() to bar(), you'd say "--no-graph=foo/bar"; to
+ show only arcs into bar() (no matter what the caller),
+ you'd say "--graph=/bar"; and to get a call-graph without
+ any arc info, you'd say "--graph=/"; similarly, to
+ get a flat profile without mcount, you'd say "--no-flat=mcount"
+ and to get a flat profile that shows includes all functions
+ you'd say "--flat=""" (i.e., an empty spec)
+
+ * hist.c (hist_print): top_time wasn't initialized to 0.0.
+
+ Fri Sep 9 01:10:21 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * gmon_out.h: all headers now declared in terms of characters
+ to avoid getting into trouble with different compilers introducing
+ different amount of padding; the code already accessed the fields
+ through bfd functions, so that didn't have to change.
+
+ * hist.c (hist_read_rec, hist_write_rec): added support for
+ collection pc histograms measuring quantities other than time;
+ the histogram header now includes a field that specifies the
+ dimension of the quantity measured by the histogram bins
+ (normally, this is "seconds", but other meaningful dimensions
+ include such things as "I-cache misses", "instruction issue stalls"
+ etc.); there is also a field to specify a one-character
+ abbreviation for the dimension; in the case of time, this would
+ be 's'; in most other cases it probably would be '1' (not a physical
+ dimension).
+
+ Thu Sep 8 16:05:08 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * gprof.c, gmon_io.[ch]: BSD_COMPATIBLE is gone and new_file_version
+ has become old_file_version; gmon_io.c now always supports old-style
+ gmon.out files; it first tries to read gmon.out as a new version
+ file, if that fails, it tries to read it in the old format;
+ although not very likely, it is possible for gprof to mistake an
+ old-style file as a new one (the first 4 bytes would have to
+ be "gmon"---including the trailing '\0'); in that case, it is
+ necessary to specify --old-file-version
+
+ * gprof.h: removed dependency on SYSV; the code now always uses
+ strrchr(), memset(), and memcpy() and does not include either
+ of string.h or strings.h; this should make gprof compile on
+ any (Unix) system without configuration (per suggestion of
+ raeburn@cygnus.com)
+
+ * gprof.c (usage): fixed location of --new-file-format option.
+
+ * cg_arcs.c (propagate_flags): fixed typo in declaration.
+
+ * flat_bl.m: removed formfeed at end of file; the form-feed
+ is now printed cg_print.c only when necessary.
+
+ * major rewrite of gprof---too many changes to mention all of
+ them. new features:
+
+ + -l now requests profiling at the line level (as opposed
+ to function level); in this mode, gprof creates a "symbol"
+ (aka name-list entry) for each line of source code, instead
+ of one per function)
+
+ + support for a new gmon.out file format; the new format
+ consists of a header with a magic and a version number,
+ followed by a sequence of profile data; profile data
+ can any of: (a) PC histogram, (b) call-graph arcs, or
+ (c) basic-block execution counts; the version number makes
+ it possible to extend gmon.out in a backwards compatible
+ fashion
+
+ + support for tcov style annotated output: if the gmon.out file
+ contains basic-block execution counts, the user can request
+ the generation of annotated source files, much like Sun's
+ tcov used to do
+
+ + long options
+
+ + new scheme to suppress symbols that aren't function names
+ (e.g., avoids mistaking a goto label as a function)
+
+ + reorganized source code to make it more managable; as a
+ side effect, gprof now compiles cleanly with "gcc -Wall"
+
+ Thu Sep 1 15:46:49 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * gprof.c (funcsymbol): bfd_find_nearest_line() is now used as a
+ final cross-check to determine whether a static symbol should be
+ considered as a function-name.
+
+ Fri Aug 5 19:32:36 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * gmon_io.c (gmon_out_read): recognize "-" as the filename for
+ stdin; this is useful if you wanna keep gmon.out files compressed;
+ this way you can "gzcat" the compressed file into gprof.
+
+ * gprof.c: flag_min_count now initialized with 1 instead of 0.
+
+ * basic_blocks.c (bb_annotate_source): added support for creating
+ .tcov files when option flag_annotate_make_files is TRUE.
+ (annotate_with_count): all counts less than the minimum count
+ specified by -m are now annotated with hash-marks.
+
+ * gprof.c (main): -A is now followed by a string of option chars.
+
+ * basic_blocks.c (annotate_with_count): replaced b->count with
+ cnt.
+
+ * source.c: flag_annotate_source replaced by source_lock_map.
+
+ * source.h: source_lock_map added.
+
+ * gprof.c (main): new command-line syntax: -S simply specifies
+ which source-files user is interested in; -A requests annotated
+ source files and -AA requests that all lines in a source file
+ are annotated.
+
+ Thu Aug 4 23:27:03 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * basic_blocks.c (PATH_MAX): if undefined, define as 1024.
+
+ * sparc.c, i386.c, tahoe.c, vax.c: added include of "time_hist.h"
+ so s_lowpc etc. get declared.
+
+ * arcs.h (doarcs): created.
+
+ * arcs.c: reordered static functions such that they get defined
+ before use.
+
+ * gprof.c (main): added options:
+ -A: request annotation of all source lines (with -S)
+ -m: minimum execution count (with default basic-block display)
+ -N: force new file format (only if BSD_COMPATIBLE is defined)
+ -S: annotate source file
+ -t: set table length (with -S)
+
+ * Makefile (OBJS): added basic_blocks.o call_graph.o gmon_io.o
+ source.o time_hist.o
+
+ Fri Jul 1 15:23:50 1994 David Mosberger-Tang (davidm@piston.cs.arizona.edu)
+
+ * gprof.c (asgnsamples): computation of "pcl" and "pch" depended
+ on the fact being able to store a long in a double without loss of
+ precision; this does not hold on machines with 64 bit longs and 64
+ bit doubles.
+
+Fri Oct 21 18:58:02 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * printgprof.c (flatprofheader): Always set totime to 1.0 if not
+ greater than 0.0. Suggested by Harold Assink
+ <carlo@sg.tn.tudelft.nl>.
+
+Fri Sep 23 15:06:45 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * printgprof.c (printprof): Use free, not cfree.
+ (printgprof, printindex): Ditto.
+
+Thu Sep 1 10:40:45 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * gprof.h (kfromlist, ktolist, flist, Flist, elist, Elist): Make
+ decls extern to keep native HP compiler quiet.
+
+Tue Aug 30 11:12:13 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * gprof.c (funcsymbol): Ignore ___gnu_compiled as well as
+ __gnu_compiled, for the benefit of systems which add a leading
+ underscore.
+
+Wed Aug 24 12:49:13 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Change i386-*-* to i[345]86-*-*.
+
+Sun Jul 10 00:35:31 1994 Ian Dall (dall@hfrd.dsto.gov.au)
+
+ * ns532.c, ns532.h: New Files. ns532 support.
+
+ * config/mt-ns532: New File. ns532 support.
+
+ * gprof.c: user register int i instead of defaulting the int.
+ Allows compilation with -Dregister= for debugging.
+
+ * configure.in: Add ns532 support.
+
+Thu Jun 23 11:22:41 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (gprof): Depend on $(LIBS).
+
+Fri May 27 12:24:57 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ From binutils-2.4 release:
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: [new] build makefile from makefile.in (dos)
+ * hertz.c: allow static HERTZ (msdos needs it)
+ * gprof.c: allow target to select "r" or "rb" for fopen
+ * gprof.c: ignore __gnu_compiled symbols
+ * i386.h: dfine FOPEN_RB to "rb" for dos.
+
+Tue May 17 15:30:22 1994 E. Michael Smith (ems@cygnus.com)
+
+ * Makefile.in (.m.c:): Added .SUFFIXES : .m
+ so flat_bl.c would make from flat_bl.m file.
+
+Thu May 5 19:23:24 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (install-info): Check for gprof.info in build dir,
+ fall back to srcdir. Depend on it.
+
+ * gprof.h (TRUE, FALSE): Always use undef before defining them.
+
+Mon Apr 4 23:47:30 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (MY_MACHINE): Renamed from MACHINE to avoid losing
+ makes (osf1) in which the value of MACHINE can not be changed.
+ * config/*.mt: Changed appropriately.
+
+Wed Mar 30 16:12:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * gprof.c (getsymtab): Change nosyms to long. Rename
+ get_symtab_upper_bound to bfd_get_symtab_upper_bound. Check for
+ errors from bfd_get_symtab_upper_bound and
+ bfd_canonicalize_symtab.
+
+Tue Mar 22 10:50:52 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * gprof.c (funcsymbol): Use bfd_get_symbol_info instead of
+ bfd_decode_symclass.
+
+Sun Mar 20 15:40:21 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Makefile.in: Avoid bug in hpux sed.
+
+Wed Dec 15 20:16:40 1993 david d `zoo' zuhn (zoo@andros.cygnus.com)
+
+ * gprof.texi (Invoking): add text about -v flag
+
+ * gprof.1: add text about -v flag
+
+Wed Dec 8 16:55:06 1993 david d `zoo' zuhn (zoo@andros.cygnus.com)
+
+ * gprof.c (VERSION): defined a version macro, print the value
+ when the -v option is used
+
+Tue Jul 6 10:11:56 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * Makefile.in: Install correctly.
+
+Thu Jun 24 14:43:22 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * gprof.c (main): Get whoami from argv, instead of hardcoding.
+ Use it in usage message. Split usage message to fit in 80 cols.
+
+Sun Jun 20 20:58:02 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * Makefile.in: Undo 15 June change.
+
+Wed Jun 16 12:54:53 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * gmon.h, gprof.h: structs of chars used to hold external
+ representations.
+ * gprof.c (getpfile, openpfile, readsamples): Swap data in using
+ new structures.
+
+Tue Jun 15 23:09:17 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (.c.o): Look in ../include, not ../bfd, for bfd.h.
+
+Mon Jun 14 16:22:59 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in: remove parentdir support
+
+Mon Jun 7 12:56:17 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (INCLUDES): Add -I../bfd for sysdep.h and bfd.h.
+ * configure.in: No longer need to configure to get sysdep.h.
+
+Tue May 18 21:44:11 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in (install): should not depend on install-info
+
+Mon Apr 26 12:37:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * gprof.h: Include ansidecl.h before sysdep.h. Undefine hz.
+
+Tue Apr 13 16:14:03 1993 Per Bothner (bothner@cygnus.com)
+
+ * M Makefile.in: Add -g to CFLAGS.
+ Ads LDFLAGS and use in place of CFLAGS where appropriate.
+ * configure.in: Make a sysdep.hlink in the same way other
+ bfd-based directories do.
+ * gprof.h (UNIT): Replace non-standard 'u_short' by 'unsigned
+ short'.
+ * gprof.h: #include sysdep.h instead of a bunch of stuff.
+ * gprof.c (main): Fix typo gproff->gprof.
+
+Thu Mar 25 19:00:37 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * gprof.texi: add INFO-DIR-ENTRY
+
+Tue Mar 23 00:03:11 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add installcheck target
+
+Sat Feb 27 18:17:10 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * gprof.c (funcsymbol): Invert test for aflag.
+
+Thu Feb 25 16:01:50 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * printgprof (xmalloc, xrealloc): Cast results of malloc
+ and realloc to PTR.
+
+Wed Feb 3 13:55:33 1993 Jeffrey Osier (jeffrey@fowanton.cygnus.com)
+
+ * Makefile.in: created info, install-info, dvi
+
+Wed Jan 6 00:58:09 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: fix install rule for $(PROG)
+
+Fri Oct 9 11:25:41 1992 Mark Eichin (eichin@cygnus.com)
+
+ * gprof.1: updated SYNOPSIS to match actual behavior.
+
+Mon Oct 5 17:50:16 1992 Per Bothner (bothner@cygnus.com)
+
+ * gen-c-prog.awk: New awk script, lightly changed from
+ previously deleted make-c-prog.awk. Converts a text file
+ to a c function that prints that text.
+ * flat_bl.m, fsf_callg_bl.m, bsd_callg_bl.m: New files.
+ Inputs to gen-c-prog.awk, containing text describing
+ gprof output.
+ * blurbs.c: Removed. Use *_bl.c instead.
+ * Makefile.in: Use gen-cprog.awk to generate *_bl.c files
+ from *_bl.m files. Also, improve *clean rules.
+ * printgprof.c (printgprof): Usw new function names from *_bl.c.
+
+
+Sun Aug 30 19:54:53 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * gprof.h, gprof.c, printfgprof.c: Add support for two
+ output styles: The default is similar to the old FSF gprof,
+ while -T sets the variable bsd_style_output, which causes
+ output matching Berkeley's gprof. The biggest differences
+ are that with the FSF style output, the flat profile comes
+ before the call graph; numbers come before explanations;
+ and there is less gratuitous white space.
+ * gprof.h, gprof.c, printfgprof.c: New discard_underscores
+ variable causes discarding of initial underscores when
+ printing symbol names. It is set unless there is a "main"
+ symbol (without an underscore).
+ * printfgprof.c: New function printnameonly(), called
+ by printname(). It handles stripping of initial '_',
+ as well as C++ name-demangling.
+ * gprof.callg, gprof.flat, make-c-prog.awk: Removed.
+ It is just as convenient to edit blurbs.c directly.
+ * Makefile.in: Removed rule for making blurbs.c.
+ * blurbs.c: This is now a true source file (as opposed
+ to being generated from gprof.callg and gprof.flat).
+ Change style to use one long string literal, instead of
+ one literal per output line. Add FSF-style blurb for call graph.
+
+Wed Aug 19 14:36:39 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: always create installation directories.
+
+Wed Aug 12 15:14:14 1992 Mark Eichin (eichin@cygnus.com)
+
+ * Makefile.in: change ${MACHINE} to $(MACHINE).
+
+Sun Jul 19 17:34:01 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: removed installation of the now useless
+ call.{flag,callg} files.
+
+ * gprof.1: now uses the standard man macros instead of the new BSD
+ mandoc macros.
+
+Sun Jul 12 19:06:00 1992 John Gilmore (gnu at cygnus.com)
+
+ * configure.in: Remove host section, expand target section.
+ * config/mt-{tahoe,vax}: Add, to match existing support files.
+ * config/tmake-*: Remove leftover crud.
+
+ * blurbs.c: New file, created from gprof.flat and gprof.callg by
+ * make-c-prog.awk: which processes text files into C programs.
+ * printgprof.c (flatprofheader, gprofheader): Call new functions
+ to print blurbs.
+ (printblurb): Remove.
+ * Makefile.in: Infrastructure to build blurbs.
+ * pathnames.h: has been removed. Gprof now has no filename
+ dependencies in it.
+ * gprof.c: Lint.
+
+Sat Jul 11 18:07:21 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: define man1dir and install the man page
+
+Fri Jul 10 21:14:08 1992 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: added dummy info and install-info targets
+
+Thu Jun 4 11:34:02 1992 Mark Eichin (eichin at cygnus.com)
+
+ * lookup.c: fixed fencepost in nllookup and added dbg_nllookup for
+ help in debugging the problem (with -DDEBUG)
+ * gprof.c: symbol values are now real values, don't add the vma
+ anymore. (done for solaris; should verify this on other platforms)
+ * ChangeLog: created.
diff --git a/gprof/Makefile.am b/gprof/Makefile.am
new file mode 100644
index 00000000000..7ae149212a5
--- /dev/null
+++ b/gprof/Makefile.am
@@ -0,0 +1,74 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+SUFFIXES = .m
+
+SUBDIRS = po
+
+INCLUDES = -D_GNU_SOURCE -DDEBUG -I../bfd -I$(srcdir)/../include -I$(srcdir)/../bfd -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+bin_PROGRAMS = gprof
+
+## Convenience var listing pure sources.
+sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
+ cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
+ search_list.c symtab.c sym_ids.c utils.c \
+ i386.c alpha.c vax.c tahoe.c sparc.c
+gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
+gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLDEPS)
+gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLLIBS)
+
+noinst_HEADERS = \
+ basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \
+ corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+ search_list.h source.h sym_ids.h symtab.h utils.h
+
+EXTRA_DIST = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c bbconv.pl
+
+BUILT_SOURCES = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
+
+diststuff: $(BUILT_SOURCES) info
+
+.m.c:
+ awk -f $(srcdir)/gen-c-prog.awk > ./$*.c \
+ FUNCTION=`(echo $*|sed -e 's,.*/,,g' -e 's/_bl//')`_blurb \
+ FILE=$*.m $(srcdir)/$*.m
+
+POTFILES = $(sources) $(noinst_HEADERS)
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+info_TEXINFOS = gprof.texi
+man_MANS = gprof.1
+
+# Dependencies.
+$(OBJECTS): ../bfd/bfd.h call_graph.h cg_arcs.h cg_print.h \
+ corefile.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+ search_list.h source.h sym_ids.h symtab.h utils.h \
+ $(srcdir)/../include/libiberty.h $(srcdir)/../bfd/sysdep.h \
+ gconfig.h ../bfd/config.h
+basic_blocks.o: basic_blocks.c
+bsd_call_bl.o: bsd_call_bl.c
+call_graph.o: call_graph.c
+cg_arcs.o: cg_arcs.c
+cg_dfn.o: cg_dfn.c
+cg_print.o: cg_print.c
+corefile.o: corefile.c
+flat_bl.o: flat_bl.c
+fsf_callg_bl.o: fsf_callg_bl.c
+gmon_io.o: gmon_io.c
+gprof.o: gprof.c
+hertz.o: hertz.c
+hist.o: hist.c
+search_list.o: search_list.c
+source.o: source.c
+symtab.o: symtab.c
+sym_ids.o: sym_ids.c
+utils.o: utils.c
+i386.o: i386.c
+alpha.o: alpha.c
+vax.o: vax.c
+tahoe.o: tahoe.c
+sparc.o: sparc.c
diff --git a/gprof/Makefile.in b/gprof/Makefile.in
new file mode 100644
index 00000000000..4aadd88c5a7
--- /dev/null
+++ b/gprof/Makefile.in
@@ -0,0 +1,726 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
+VERSION = @VERSION@
+l = @l@
+
+AUTOMAKE_OPTIONS = cygnus
+
+SUFFIXES = .m
+
+SUBDIRS = po
+
+INCLUDES = -D_GNU_SOURCE -DDEBUG -I../bfd -I$(srcdir)/../include -I$(srcdir)/../bfd -I$(srcdir)/../intl -I../intl -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+bin_PROGRAMS = gprof
+
+sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \
+ cg_print.c corefile.c gmon_io.c gprof.c hertz.c hist.c source.c \
+ search_list.c symtab.c sym_ids.c utils.c \
+ i386.c alpha.c vax.c tahoe.c sparc.c
+
+gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
+gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLDEPS)
+gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(INTLLIBS)
+
+noinst_HEADERS = \
+ basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \
+ corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+ search_list.h source.h sym_ids.h symtab.h utils.h
+
+
+EXTRA_DIST = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c bbconv.pl
+
+BUILT_SOURCES = flat_bl.c bsd_callg_bl.c fsf_callg_bl.c
+
+POTFILES = $(sources) $(noinst_HEADERS)
+
+info_TEXINFOS = gprof.texi
+man_MANS = gprof.1
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = gconfig.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = gprof$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+gprof_OBJECTS = basic_blocks.o call_graph.o cg_arcs.o cg_dfn.o \
+cg_print.o corefile.o gmon_io.o gprof.o hertz.o hist.o source.o \
+search_list.o symtab.o sym_ids.o utils.o i386.o alpha.o vax.o tahoe.o \
+sparc.o flat_bl.o bsd_callg_bl.o fsf_callg_bl.o
+gprof_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi`
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+INFO_DEPS = gprof.info
+DVIS = gprof.dvi
+TEXINFOS = gprof.texi
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+
+NROFF = nroff
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = ./stamp-h.in ChangeLog Makefile.am Makefile.in TODO \
+aclocal.m4 configure configure.in gconfig.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(gprof_SOURCES)
+OBJECTS = $(gprof_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .dvi .info .lo .m .o .ps .s .texi .texinfo .txi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+gconfig.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/gconfig.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=gconfig.h:gconfig.in \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/gconfig.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f gconfig.h
+
+maintainer-clean-hdr:
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+gprof$(EXEEXT): $(gprof_OBJECTS) $(gprof_DEPENDENCIES)
+ @rm -f gprof$(EXEEXT)
+ $(LINK) $(gprof_LDFLAGS) $(gprof_OBJECTS) $(gprof_LDADD) $(LIBS)
+
+gprof.info: gprof.texi
+gprof.dvi: gprof.texi
+
+
+DVIPS = dvips
+
+.texi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.txi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f gprof.aux gprof.cp gprof.cps gprof.dvi gprof.fn gprof.fns \
+ gprof.ky gprof.kys gprof.ps gprof.log gprof.pg gprof.toc \
+ gprof.tp gprof.tps gprof.vr gprof.vrs gprof.op gprof.tr \
+ gprof.cv gprof.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+clean-info: mostlyclean-aminfo
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) gconfig.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)gconfig.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags gconfig.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+info-am: $(INFO_DEPS)
+info: info-recursive
+dvi-am: $(DVIS)
+dvi: dvi-recursive
+check-am:
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+all-recursive-am: gconfig.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-recursive
+
+install-data-am: install-man
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+uninstall: uninstall-recursive
+all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) gconfig.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-aminfo mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-libtool \
+ clean-aminfo clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \
+ distclean-libtool distclean-aminfo distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-aminfo maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-info-am uninstall-info \
+mostlyclean-aminfo distclean-aminfo clean-aminfo \
+maintainer-clean-aminfo install-man1 uninstall-man1 install-man \
+uninstall-man install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-info-am \
+install-info all-recursive-am install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+diststuff: $(BUILT_SOURCES) info
+
+.m.c:
+ awk -f $(srcdir)/gen-c-prog.awk > ./$*.c \
+ FUNCTION=`(echo $*|sed -e 's,.*/,,g' -e 's/_bl//')`_blurb \
+ FILE=$*.m $(srcdir)/$*.m
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+# Dependencies.
+$(OBJECTS): ../bfd/bfd.h call_graph.h cg_arcs.h cg_print.h \
+ corefile.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
+ search_list.h source.h sym_ids.h symtab.h utils.h \
+ $(srcdir)/../include/libiberty.h $(srcdir)/../bfd/sysdep.h \
+ gconfig.h ../bfd/config.h
+basic_blocks.o: basic_blocks.c
+bsd_call_bl.o: bsd_call_bl.c
+call_graph.o: call_graph.c
+cg_arcs.o: cg_arcs.c
+cg_dfn.o: cg_dfn.c
+cg_print.o: cg_print.c
+corefile.o: corefile.c
+flat_bl.o: flat_bl.c
+fsf_callg_bl.o: fsf_callg_bl.c
+gmon_io.o: gmon_io.c
+gprof.o: gprof.c
+hertz.o: hertz.c
+hist.o: hist.c
+search_list.o: search_list.c
+source.o: source.c
+symtab.o: symtab.c
+sym_ids.o: sym_ids.c
+utils.o: utils.c
+i386.o: i386.c
+alpha.o: alpha.c
+vax.o: vax.c
+tahoe.o: tahoe.c
+sparc.o: sparc.c
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gprof/NOTES b/gprof/NOTES
new file mode 100644
index 00000000000..511af302781
--- /dev/null
+++ b/gprof/NOTES
@@ -0,0 +1,438 @@
+Sun Feb 5 16:09:16 1995
+
+This file documents the changes and new features available with this
+version of GNU gprof.
+
+* New Features
+
+ o Long options
+
+ o Supports generalized file format, without breaking backward compatibility:
+ new file format supports basic-block execution counts and non-realtime
+ histograms (see below)
+
+ o Supports profiling at the line level: flat profiles, call-graph profiles,
+ and execution-counts can all be displayed at a level that identifies
+ individual lines rather than just functions
+
+ o Test-coverage support (similar to Sun tcov program): source files
+ can be annotated with the number of times a function was invoked
+ or with the number of times each basic-block in a function was
+ executed
+
+ o Generalized histograms: not just execution-time, but arbitrary
+ histograms are support (for example, performance counter based
+ profiles)
+
+ o Powerful mechanism to select data to be included/excluded from
+ analysis and/or output
+
+ o Support for DEC OSF/1 v3.0
+
+ o Full cross-platform profiling support: gprof uses BFD to support
+ arbitrary, non-native object file formats and non-native byte-orders
+ (this feature has not been tested yet)
+
+ o In the call-graph function index, static function names are now
+ printed together with the filename in which the function was defined
+ (required bfd_find_nearest_line() support and symbolic debugging
+ information to be present in the executable file)
+
+ o Major overhaul of source code (compiles cleanly with -Wall, etc.)
+
+* Supported Platforms
+
+The current version is known to work on:
+
+ o DEC OSF/1 v3.0
+ All features supported.
+
+ o SunOS 4.1.x
+ All features supported.
+
+ o Solaris 2.3
+ Line-level profiling unsupported because bfd_find_nearest_line()
+ is not fully implemented for Elf binaries.
+
+ o HP-UX 9.01
+ Line-level profiling unsupported because bfd_find_nearest_line()
+ is not fully implemented for SOM binaries.
+
+* Detailed Description
+
+** User Interface Changes
+
+The command-line interface is backwards compatible with earlier
+versions of GNU gprof and Berkeley gprof. The only exception is
+the option to delete arcs from the call graph. The old syntax
+was:
+
+ -k fromname toname
+
+while the new syntax is:
+
+ -k fromname/toname
+
+This change was necessary to be compatible with long-option parsing.
+Also, "fromname" and "toname" can now be arbitrary symspecs rather
+than just function names (see below for an explanation of symspecs).
+For example, option "-k gprof.c/" suppresses all arcs due to calls out
+of file "gprof.c".
+
+*** Sym Specs
+
+It is often necessary to apply gprof only to specific parts of a
+program. GNU gprof has a simple but powerful mechanism to achieve
+this. So called {\em symspecs\/} provide the foundation for this
+mechanism. A symspec selects the parts of a profiled program to which
+an operation should be applied to. The syntax of a symspec is
+simple:
+
+ filename_containing_a_dot
+ | funcname_not_containing_a_dot
+ | linenumber
+ | ( [ any_filename ] `:' ( any_funcname | linenumber ) )
+
+Here are some examples:
+
+ main.c Selects everything in file "main.c"---the
+ dot in the string tells gprof to interpret
+ the string as a filename, rather than as
+ a function name. To select a file whose
+ name does contain a dot, a trailing colon
+ should be specified. For example, "odd:" is
+ interpreted as the file named "odd".
+
+ main Selects all functions named "main". Notice
+ that there may be multiple instances of the
+ same function name because some of the
+ definitions may be local (i.e., static).
+ Unless a function name is unique in a program,
+ you must use the colon notation explained
+ below to specify a function from a specific
+ source file. Sometimes, functionnames contain
+ dots. In such cases, it is necessar to
+ add a leading colon to the name. For example,
+ ":.mul" selects function ".mul".
+
+ main.c:main Selects function "main" in file "main.c".
+
+ main.c:134 Selects line 134 in file "main.c".
+
+IMPLEMENTATION NOTE: The source code uses the type sym_id for symspecs.
+At some point, this probably ought to be changed to "sym_spec" to make
+reading the code easier.
+
+*** Long options
+
+GNU gprof now supports long options. The following is a list of all
+supported options. Options that are listed without description
+operate in the same manner as the corresponding option in older
+versions of gprof.
+
+Short Form: Long Form:
+----------- ----------
+-l --line
+ Request profiling at the line-level rather
+ than just at the function level. Source
+ lines are identified by symbols of the form:
+
+ func (file:line)
+
+ where "func" is the function name, "file" is the
+ file name and "line" is the line-number that
+ corresponds to the line.
+
+ To work properly, the binary must contain symbolic
+ debugging information. This means that the source
+ have to be translated with option "-g" specified.
+ Functions for which there is no symbolic debugging
+ information available are treated as if "--line"
+ had not been specified. However, the line number
+ printed with such symbols is usually incorrect
+ and should be ignored.
+
+-a --no-static
+-A[symspec] --annotated-source[=symspec]
+ Request output in the form of annotated source
+ files. If "symspec" is specified, print output only
+ for symbols selected by "symspec". If the option
+ is specified multiple times, annotated output is
+ generated for the union of all symspecs.
+
+ Examples:
+
+ -A Prints annotated source for all
+ source files.
+ -Agprof.c Prints annotated source for file
+ gprof.c.
+ -Afoobar Prints annotated source for files
+ containing a function named "foobar".
+ The entire file will be printed, but
+ only the function itself will be
+ annotated with profile data.
+
+-J[symspec] --no-annotated-source[=symspec]
+ Suppress annotated source output. If specified
+ without argument, annotated output is suppressed
+ completely. With an argument, annotated output
+ is suppressed only for the symbols selected by
+ "symspec". If the option is specified multiple
+ times, annotated output is suppressed for the
+ union of all symspecs. This option has lower
+ precedence than --annotated-source
+
+-p[symspec] --flat-profile[=symspec]
+ Request output in the form of a flat profile
+ (unless any other output-style option is specified,
+ this option is turned on by default). If
+ "symspec" is specified, include only symbols
+ selected by "symspec" in flat profile. If the
+ option is specified multiple times, the flat
+ profile includes symbols selected by the union
+ of all symspecs.
+
+-P[symspec] --no-flat-profile[=symspec]
+ Suppress output in the flat profile. If given
+ without an argument, the flat profile is suppressed
+ completely. If "symspec" is specified, suppress
+ the selected symbols in the flat profile. If the
+ option is specified multiple times, the union of
+ the selected symbols is suppressed. This option
+ has lower precedence than --flat-profile.
+
+-q[symspec] --graph[=symspec]
+ Request output in the form of a call-graph
+ (unless any other output-style option is specified,
+ this option is turned on by default). If "symspec"
+ is specified, include only symbols selected by
+ "symspec" in the call-graph. If the option is
+ specified multiple times, the call-graph includes
+ symbols selected by the union of all symspecs.
+
+-Q[symspec] --no-graph[=symspec]
+ Suppress output in the call-graph. If given without
+ an argument, the call-graph is suppressed completely.
+ With a "symspec", suppress the selected symbols
+ from the call-graph. If the option is specified
+ multiple times, the union of the selected symbols
+ is suppressed. This option has lower precedence
+ than --graph.
+
+-C[symspec] --exec-counts[=symspec]
+ Request output in the form of execution counts.
+ If "symspec" is present, include only symbols
+ selected by "symspec" in the execution count
+ listing. If the option is specified multiple
+ times, the execution count listing includes
+ symbols selected by the union of all symspecs.
+
+-Z[symspec] --no-exec-counts[=symspec]
+ Suppress output in the execution count listing.
+ If given without an argument, the listing is
+ suppressed completely. With a "symspec", suppress
+ the selected symbols from the call-graph. If the
+ option is specified multiple times, the union of
+ the selected symbols is suppressed. This option
+ has lower precedence than --exec-counts.
+
+-i --file-info
+ Print information about the profile files that
+ are read. The information consists of the
+ number and types of records present in the
+ profile file. Currently, a profile file can
+ contain any number and any combination of histogram,
+ call-graph, or basic-block count records.
+
+-s --sum
+
+-x --all-lines
+ This option affects annotated source output only.
+ By default, only the lines at the beginning of
+ a basic-block are annotated. If this option is
+ specified, every line in a basic-block is annotated
+ by repeating the annotation for the first line.
+ This option is identical to tcov's "-a".
+
+-I dirs --directory-path=dirs
+ This option affects annotated source output only.
+ Specifies the list of directories to be searched
+ for source files. The argument "dirs" is a colon
+ separated list of directories. By default, gprof
+ searches for source files relative to the current
+ working directory only.
+
+-z --display-unused-functions
+
+-m num --min-count=num
+ This option affects annotated source and execution
+ count output only. Symbols that are executed
+ less than "num" times are suppressed. For annotated
+ source output, suppressed symbols are marked
+ by five hash-marks (#####). In an execution count
+ output, suppressed symbols do not appear at all.
+
+-L --print-path
+ Normally, source filenames are printed with the path
+ component suppressed. With this option, gprof
+ can be forced to print the full pathname of
+ source filenames. The full pathname is determined
+ from symbolic debugging information in the image file
+ and is relative to the directory in which the compiler
+ was invoked.
+
+-y --separate-files
+ This option affects annotated source output only.
+ Normally, gprof prints annotated source files
+ to standard-output. If this option is specified,
+ annotated source for a file named "path/filename"
+ is generated in the file "filename-ann". That is,
+ annotated output is {\em always\/} generated in
+ gprof's current working directory. Care has to
+ be taken if a program consists of files that have
+ identical filenames, but distinct paths.
+
+-c --static-call-graph
+
+-t num --table-length=num
+ This option affects annotated source output only.
+ After annotating a source file, gprof generates
+ an execution count summary consisting of a table
+ of lines with the top execution counts. By
+ default, this table is ten entries long.
+ This option can be used to change the table length
+ or, by specifying an argument value of 0, it can be
+ suppressed completely.
+
+-n symspec --time=symspec
+ Only symbols selected by "symspec" are considered
+ in total and percentage time computations.
+ However, this option does not affect percentage time
+ computation for the flat profile.
+ If the option is specified multiple times, the union
+ of all selected symbols is used in time computations.
+
+-N --no-time=symspec
+ Exclude the symbols selected by "symspec" from
+ total and percentage time computations.
+ However, this option does not affect percentage time
+ computation for the flat profile.
+ This option is ignored if any --time options are
+ specified.
+
+-w num --width=num
+ Sets the output line width. Currently, this option
+ affects the printing of the call-graph function index
+ only.
+
+-e <no long form---for backwards compatibility only>
+-E <no long form---for backwards compatibility only>
+-f <no long form---for backwards compatibility only>
+-F <no long form---for backwards compatibility only>
+-k <no long form---for backwards compatibility only>
+-b --brief
+-dnum --debug[=num]
+
+-h --help
+ Prints a usage message.
+
+-O name --file-format=name
+ Selects the format of the profile data files.
+ Recognized formats are "auto", "bsd", "magic",
+ and "prof". The last one is not yet supported.
+ Format "auto" attempts to detect the file format
+ automatically (this is the default behavior).
+ It attempts to read the profile data files as
+ "magic" files and if this fails, falls back to
+ the "bsd" format. "bsd" forces gprof to read
+ the data files in the BSD format. "magic" forces
+ gprof to read the data files in the "magic" format.
+
+-T --traditional
+-v --version
+
+** File Format Changes
+
+The old BSD-derived format used for profile data does not contain a
+magic cookie that allows to check whether a data file really is a
+gprof file. Furthermore, it does not provide a version number, thus
+rendering changes to the file format almost impossible. GNU gprof
+uses a new file format that provides these features. For backward
+compatibility, GNU gprof continues to support the old BSD-derived
+format, but not all features are supported with it. For example,
+basic-block execution counts cannot be accommodated by the old file
+format.
+
+The new file format is defined in header file \file{gmon_out.h}. It
+consists of a header containing the magic cookie and a version number,
+as well as some spare bytes available for future extensions. All data
+in a profile data file is in the native format of the host on which
+the profile was collected. GNU gprof adapts automatically to the
+byte-order in use.
+
+In the new file format, the header is followed by a sequence of
+records. Currently, there are three different record types: histogram
+records, call-graph arc records, and basic-block execution count
+records. Each file can contain any number of each record type. When
+reading a file, GNU gprof will ensure records of the same type are
+compatible with each other and compute the union of all records. For
+example, for basic-block execution counts, the union is simply the sum
+of all execution counts for each basic-block.
+
+*** Histogram Records
+
+Histogram records consist of a header that is followed by an array of
+bins. The header contains the text-segment range that the histogram
+spans, the size of the histogram in bytes (unlike in the old BSD
+format, this does not include the size of the header), the rate of the
+profiling clock, and the physical dimension that the bin counts
+represent after being scaled by the profiling clock rate. The
+physical dimension is specified in two parts: a long name of up to 15
+characters and a single character abbreviation. For example, a
+histogram representing real-time would specify the long name as
+"seconds" and the abbreviation as "s". This feature is useful for
+architectures that support performance monitor hardware (which,
+fortunately, is becoming increasingly common). For example, under DEC
+OSF/1, the "uprofile" command can be used to produce a histogram of,
+say, instruction cache misses. In this case, the dimension in the
+histogram header could be set to "i-cache misses" and the abbreviation
+could be set to "1" (because it is simply a count, not a physical
+dimension). Also, the profiling rate would have to be set to 1 in
+this case.
+
+Histogram bins are 16-bit numbers and each bin represent an equal
+amount of text-space. For example, if the text-segment is one
+thousand bytes long and if there are ten bins in the histogram, each
+bin represents one hundred bytes.
+
+
+*** Call-Graph Records
+
+Call-graph records have a format that is identical to the one used in
+the BSD-derived file format. It consists of an arc in the call graph
+and a count indicating the number of times the arc was traversed
+during program execution. Arcs are specified by a pair of addresses:
+the first must be within caller's function and the second must be
+within the callee's function. When performing profiling at the
+function level, these addresses can point anywhere within the
+respective function. However, when profiling at the line-level, it is
+better if the addresses are as close to the call-site/entry-point as
+possible. This will ensure that the line-level call-graph is able to
+identify exactly which line of source code performed calls to a
+function.
+
+*** Basic-Block Execution Count Records
+
+Basic-block execution count records consist of a header followed by a
+sequence of address/count pairs. The header simply specifies the
+length of the sequence. In an address/count pair, the address
+identifies a basic-block and the count specifies the number of times
+that basic-block was executed. Any address within the basic-address can
+be used.
+
+IMPLEMENTATION NOTE: gcc -a can be used to instrument a program to
+record basic-block execution counts. However, the __bb_exit_func()
+that is currently present in libgcc2.c does not generate a gmon.out
+file in a suiteable format. This should be fixed for future releases
+of gcc. In the meantime, contact davidm@cs.arizona.edu for a version
+of __bb_exit_func() to is appropriate.
diff --git a/gprof/TEST b/gprof/TEST
new file mode 100644
index 00000000000..78a90300cae
--- /dev/null
+++ b/gprof/TEST
@@ -0,0 +1,7 @@
+- check whether old file format is properly read when input comes from
+ stdin
+
+- check whether underscores are properly dealt with (both, on systems
+ that prepend them to each C name and on systems that don't)
+
+- ensure gprof fails gracefully when no debugging info available
diff --git a/gprof/TODO b/gprof/TODO
new file mode 100644
index 00000000000..20111c61e74
--- /dev/null
+++ b/gprof/TODO
@@ -0,0 +1,72 @@
+
+- gmon_io.c cannot deal with target architecture that have a pointer size
+ that is different from the host architectures pointer size---fix this
+ (gmon_out.h, and gmon_io.c)
+- add support for prof file format so that prof files can be displayed
+ at the line-level (this is useful for the uprofile tool under DEC's
+ OSF/1)
+- take a hard look at --file-ordering (broken) and --function-ordering
+
++ documentation
++ optimize bfd_find_nearest_line_num() (or replace by different interface)
++ cleanup _bfd_ecoff_find_nearest_line_num() fixes & description
++ ensure "cc -pg" produces good files under OSF/1 v3.0
++ make sure gprof works together with OSF/1 v3.0's profiling libraries
++ implement symtab_parse(); modify sym_lookup() to consider addr_high
++ change gprof.c to collect lists, then invoke symtab_parse() for
+ each list
++ Questions:
+ o is -c (--static-call-graph) useful at all? i can't see
+ how; if it were deleted, gprof would be completely machine
+ independent => yup, it is
+ o are (long) option names appropriate?
+ o -k (--exclude-arc) cannot be implemented with getopt();
+ is new syntax (-k from/to) acceptable? If not, how to
+ fix it?
+ o in the FSF output, the call-graph index now prints
+ the filename of static functions in parentheses; e.g.,
+ static function foo() that is defined in file bar.c
+ would be printed as:
+
+ [4] foo (bar.c)
+
+ is this acceptable? should it be done only optionally?
+ o symbols with addresses that map back to a different
+ name are suppressed (happens with labels, for example);
+ is this acceptable? should it be done only optionally?
++ generalize to allow arbitrary histograms (not just time histograms)
++ basic-block information currently replaces all symbols created from
+ the core because of an ugly ordering conflict---for now, the current
+ solution works, but something cleaner is desirable ==> cleaned up,
+ but it's slower now
++ convert to very new file format (back to trivial format, that is :)
++ replace "dummy.h" for Alpha (if there is any use to it)
++ add support for execution time profiling at a basic-block level
++ fix filename-off-by-one bug for Alpha (see ~/tmp/d.[ch])---no longer
+ relevant
++ "-pg -a" doesn't work as expected because mcleanup() will overwrite
+ the file generated by __bb_exit_func() (or vice versa)
++ first basic-block of fac() seems to get credited to last basic-block
+ of previous function => bug in basic_blocks.c
++ flat profile should provide automatic scaling for per-call times because
+ otherwise they'll always be zero on a fast machine with tons of small
+ functions
++ make "-a" imply to retain line number info (without actually generating
+ the debugging information (unless -g is specified)---no, this is a
+ bad idea, because it is not clear what level of debugging info should
+ be requested (e.g., -g vs. -g3); leaving it up to the user seems best
++ add long options support (or at least use getopt instead of ad-hoc
+ implementation)
++ split into files according to abstract objects that are manipulated
++ replace sccsid by rcsid & add "end of ..." to every .c file
++ use DBG() everywhere
++ fix spacing (" ," -> "," etc.)
++ use DEFUNs everywhere
++ make compile cleanly with -Wall
++ "gcc -pg -O2" doesn't work on tecc.c unless -fno-omit-frame-pointer is
+ specified; find out why
++ make things portable (prototypes, const, etc.)
++ if NEW_GMON_OUT is not defined, have a flag that will allow to
+ read new gmon.out style files. The idea being that everyone
+ will use the new format for basic-block style profiling but
+ the old format for regular gpprofiling
diff --git a/gprof/aclocal.m4 b/gprof/aclocal.m4
new file mode 100644
index 00000000000..ad20122086d
--- /dev/null
+++ b/gprof/aclocal.m4
@@ -0,0 +1,1109 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+# serial 35 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_REQUIRE([AC_SYS_SYMBOL_UNDERSCORE])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ AC_SYS_LIBTOOL_CYGWIN
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+AC_ARG_ENABLE(libtool-lock,
+[ --disable-libtool-lock force libtool not to do file locking],
+need_locks=$enableval,
+need_locks=yes)
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+])
+
+# AC_LIBTOOL_DLOPEN - check for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [lt_dlopen=yes])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED,
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED,
+[AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC,
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC,
+[AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL,
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL,
+[AC_ENABLE_FAST_INSTALL(no)])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_SYS_NM_PARSE - Check for command to grab the raw symbol name followed
+# by C symbol name from nm.
+AC_DEFUN(AC_SYS_NM_PARSE,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+changequote([,])dnl
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+changequote(,)dnl
+lt_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+])
+
+# AC_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin
+AC_DEFUN(AC_SYS_LIBTOOL_CYGWIN,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# AC_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
+# with an underscore?
+AC_DEFUN(AC_SYS_SYMBOL_UNDERSCORE,
+[AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+AC_SUBST(USE_SYMBOL_UNDERSCORE)dnl
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM, [
+AC_CHECK_LIB(mw, _mwvalidcheckl)
+AC_CHECK_LIB(m, cos)
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [
+ AC_CHECK_LIB(ltdl, main, LIBLTDL="-lltdl", [
+ case "$enable_ltdl_install" in
+ no) AC_MSG_WARN([libltdl not installed, but installation disabled]) ;;
+ "") enable_ltdl_install=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-install" ;;
+ esac
+ ])
+ if test x"$enable_ltdl_install" != x"no"; then
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+AC_DEFUN(AM_SYS_NM_PARSE, [indir([AC_SYS_NM_PARSE])])dnl
+AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE, [indir([AC_SYS_SYMBOL_UNDERSCORE])])dnl
+AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN, [indir([AC_SYS_LIBTOOL_CYGWIN])])dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/gprof/alpha.c b/gprof/alpha.c
new file mode 100644
index 00000000000..ad4f22e4674
--- /dev/null
+++ b/gprof/alpha.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1983, 1998 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+#include "symtab.h"
+
+/*
+ * Opcodes of the call instructions:
+ */
+#define OP_Jxx 0x1a
+#define OP_BSR 0x34
+
+#define Jxx_FUNC_JMP 0
+#define Jxx_FUNC_JSR 1
+#define Jxx_FUNC_RET 2
+#define Jxx_FUNC_JSR_COROUTINE 3
+
+typedef union
+ {
+ struct
+ {
+ unsigned other:26;
+ unsigned op_code:6;
+ }
+ a; /* any format */
+ struct
+ {
+ int disp:21;
+ unsigned ra:5;
+ unsigned op_code:6;
+ }
+ b; /* branch format */
+ struct
+ {
+ int hint:14;
+ unsigned func:2;
+ unsigned rb:5;
+ unsigned ra:5;
+ unsigned op_code:6;
+ }
+ j; /* jump format */
+ }
+alpha_Instruction;
+
+static Sym indirect_child;
+
+
+/*
+ * On the Alpha we can only detect PC relative calls, which are
+ * usually generated for calls to functions within the same
+ * object file only. This is still better than nothing, however.
+ * (In particular it should be possible to find functions that
+ * potentially call integer division routines, for example.)
+ */
+void
+alpha_find_call (parent, p_lowpc, p_highpc)
+ Sym *parent;
+ bfd_vma p_lowpc;
+ bfd_vma p_highpc;
+{
+ static bfd_vma delta = 0;
+ bfd_vma dest_pc;
+ alpha_Instruction *pc;
+ Sym *child;
+
+ if (!delta)
+ {
+ delta = (bfd_vma) core_text_space - core_text_sect->vma;
+
+ sym_init (&indirect_child);
+ indirect_child.name = _("<indirect child>");
+ indirect_child.cg.prop.fract = 1.0;
+ indirect_child.cg.cyc.head = &indirect_child;
+ }
+
+ if (!core_text_space)
+ {
+ return;
+ }
+ if (p_lowpc < s_lowpc)
+ {
+ p_lowpc = s_lowpc;
+ }
+ if (p_highpc > s_highpc)
+ {
+ p_highpc = s_highpc;
+ }
+ DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"),
+ parent->name, p_lowpc, p_highpc));
+ for (pc = (alpha_Instruction *) (p_lowpc + delta);
+ pc < (alpha_Instruction *) (p_highpc + delta);
+ ++pc)
+ {
+ switch (pc->a.op_code)
+ {
+ case OP_Jxx:
+ /*
+ * There is no simple and reliable way to determine the
+ * target of a jsr (the hint bits help, but there aren't
+ * enough bits to get a satisfactory hit rate). Instead,
+ * for any indirect jump we simply add an arc from PARENT
+ * to INDIRECT_CHILD---that way the user it at least able
+ * to see that there are other calls as well.
+ */
+ if (pc->j.func == Jxx_FUNC_JSR
+ || pc->j.func == Jxx_FUNC_JSR_COROUTINE)
+ {
+ DBG (CALLDEBUG,
+ printf (_("[find_call] 0x%lx: jsr%s <indirect_child>\n"),
+ (bfd_vma) pc - delta,
+ pc->j.func == Jxx_FUNC_JSR ? "" : "_coroutine"));
+ arc_add (parent, &indirect_child, (unsigned long) 0);
+ }
+ break;
+
+ case OP_BSR:
+ DBG (CALLDEBUG,
+ printf (_("[find_call] 0x%lx: bsr"), (bfd_vma) pc - delta));
+ /*
+ * Regular PC relative addressing. Check that this is the
+ * address of a function. The linker sometimes redirects
+ * the entry point by 8 bytes to skip loading the global
+ * pointer, so we all for either address:
+ */
+ dest_pc = ((bfd_vma) (pc + 1 + pc->b.disp)) - delta;
+ if (dest_pc >= s_lowpc && dest_pc <= s_highpc)
+ {
+ child = sym_lookup (&symtab, dest_pc);
+ DBG (CALLDEBUG,
+ printf (" 0x%lx\t; name=%s, addr=0x%lx",
+ dest_pc, child->name, child->addr));
+ if (child->addr == dest_pc || child->addr == dest_pc - 8)
+ {
+ DBG (CALLDEBUG, printf ("\n"));
+ /* a hit: */
+ arc_add (parent, child, (unsigned long) 0);
+ continue;
+ }
+ }
+ /*
+ * Something funny going on.
+ */
+ DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
+ break;
+
+ default:
+ break;
+ }
+ }
+}
diff --git a/gprof/basic_blocks.c b/gprof/basic_blocks.c
new file mode 100644
index 00000000000..07b6f8d4eb0
--- /dev/null
+++ b/gprof/basic_blocks.c
@@ -0,0 +1,635 @@
+/*
+ * Basic-block level related code: reading/writing of basic-block info
+ * to/from gmon.out; computing and formatting of basic-block related
+ * statistics.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include "basic_blocks.h"
+#include "corefile.h"
+#include "gmon_io.h"
+#include "gmon_out.h"
+#include "gprof.h"
+#include "libiberty.h"
+#include "source.h"
+#include "sym_ids.h"
+
+
+/*
+ * Default option values:
+ */
+bool bb_annotate_all_lines = FALSE;
+unsigned long bb_min_calls = 1;
+int bb_table_length = 10;
+
+/*
+ * Variables used to compute annotated source listing stats:
+ */
+static long num_executable_lines;
+static long num_lines_executed;
+
+
+/*
+ * Helper for sorting. Compares two symbols and returns result
+ * such that sorting will be increasing according to filename, line
+ * number, and address (in that order).
+ */
+
+static int
+DEFUN (cmp_bb, (lp, rp), const void *lp AND const void *rp)
+{
+ int r;
+ const Sym *left = *(const Sym **) lp;
+ const Sym *right = *(const Sym **) rp;
+
+ if (left->file && right->file)
+ {
+ r = strcmp (left->file->name, right->file->name);
+ if (r)
+ {
+ return r;
+ }
+
+ if (left->line_num != right->line_num)
+ {
+ return left->line_num - right->line_num;
+ }
+ }
+
+ if (left->addr < right->addr)
+ {
+ return -1;
+ }
+ else if (left->addr > right->addr)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+/*
+ * Helper for sorting. Order basic blocks in decreasing number of
+ * calls, ties are broken in increasing order of line numbers.
+ */
+static int
+DEFUN (cmp_ncalls, (lp, rp), const void *lp AND const void *rp)
+{
+ const Sym *left = *(const Sym **) lp;
+ const Sym *right = *(const Sym **) rp;
+
+ if (!left)
+ {
+ return 1;
+ }
+ else if (!right)
+ {
+ return -1;
+ }
+
+ if (left->ncalls < right->ncalls)
+ return 1;
+ else if (left->ncalls > right->ncalls)
+ return -1;
+
+ return left->line_num - right->line_num;
+}
+
+
+/*
+ * Skip over variable length string.
+ */
+static void
+DEFUN (fskip_string, (fp), FILE * fp)
+{
+ int ch;
+
+ while ((ch = fgetc (fp)) != EOF)
+ {
+ if (ch == '\0')
+ {
+ break;
+ }
+ }
+}
+
+
+/*
+ * Read a basic-block record from file IFP. FILENAME is the name
+ * of file IFP and is provided for formatting error-messages only.
+ */
+void
+DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
+{
+ int nblocks, b;
+ bfd_vma addr;
+ unsigned long ncalls;
+ Sym *sym;
+
+ if (fread (&nblocks, sizeof (nblocks), 1, ifp) != 1)
+ {
+ fprintf (stderr, _("%s: %s: unexpected end of file\n"), whoami, filename);
+ done (1);
+ }
+
+ nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
+ if (gmon_file_version == 0)
+ {
+ fskip_string (ifp);
+ }
+
+ for (b = 0; b < nblocks; ++b)
+ {
+ if (gmon_file_version == 0)
+ {
+ int line_num;
+ /*
+ * Version 0 had lots of extra stuff that we don't
+ * care about anymore.
+ */
+ if ((fread (&ncalls, sizeof (ncalls), 1, ifp) != 1)
+ || (fread (&addr, sizeof (addr), 1, ifp) != 1)
+ || (fskip_string (ifp), FALSE)
+ || (fskip_string (ifp), FALSE)
+ || (fread (&line_num, sizeof (line_num), 1, ifp) != 1))
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+ else
+ {
+ if (fread (&addr, sizeof (addr), 1, ifp) != 1
+ || fread (&ncalls, sizeof (ncalls), 1, ifp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+
+ /*
+ * Basic-block execution counts are meaningful only if we're
+ * profiling at the line-by-line level:
+ */
+ if (line_granularity)
+ {
+
+ /* convert from target to host endianness: */
+
+ addr = get_vma (core_bfd, (bfd_byte *) & addr);
+ ncalls = bfd_get_32 (core_bfd, (bfd_byte *) &ncalls);
+
+ sym = sym_lookup (&symtab, addr);
+
+ if (sym)
+ {
+ int i;
+
+ DBG (BBDEBUG,
+ printf ("[bb_read_rec] 0x%lx->0x%lx (%s:%d) cnt=%lu\n",
+ addr, sym->addr, sym->name, sym->line_num, ncalls));
+
+ for (i = 0; i < NBBS; i++)
+ {
+ if (! sym->bb_addr[i] || sym->bb_addr[i] == addr)
+ {
+ sym->bb_addr[i] = addr;
+ sym->bb_calls[i] += ncalls;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ static bool user_warned = FALSE;
+
+ if (!user_warned)
+ {
+ user_warned = TRUE;
+ fprintf (stderr,
+ _("%s: warning: ignoring basic-block exec counts (use -l or --line)\n"),
+ whoami);
+ }
+ }
+ }
+ return;
+}
+
+
+/*
+ * Write all basic-blocks with non-zero counts to file OFP. FILENAME
+ * is the name of OFP and is provided for producing error-messages
+ * only.
+ */
+void
+DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
+{
+ const unsigned char tag = GMON_TAG_BB_COUNT;
+ int nblocks = 0;
+ bfd_vma addr;
+ unsigned long ncalls;
+ Sym *sym;
+ int i;
+
+ /* count how many non-zero blocks with have: */
+
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
+ ;
+ nblocks += i;
+ }
+
+ /* write header: */
+ bfd_put_32 (core_bfd, nblocks, (bfd_byte *) & nblocks);
+ if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
+ || fwrite (&nblocks, sizeof (nblocks), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+
+ /* write counts: */
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
+ {
+ put_vma (core_bfd, sym->bb_addr[i], (bfd_byte *) & addr);
+ bfd_put_32 (core_bfd, sym->bb_calls[i], (bfd_byte *) & ncalls);
+
+ if (fwrite (&addr, sizeof (addr), 1, ofp) != 1
+ || fwrite (&ncalls, sizeof (ncalls), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+ }
+}
+
+
+/*
+ * Output basic-block statistics in a format that is easily parseable.
+ * Current the format is:
+ *
+ * <filename>:<line-number>: (<function-name>:<bb-addr): <ncalls>
+ */
+void
+DEFUN_VOID (print_exec_counts)
+{
+ Sym **sorted_bbs, *sym;
+ int i, j, len;
+
+ if (first_output)
+ {
+ first_output = FALSE;
+ }
+ else
+ {
+ printf ("\f\n");
+ }
+
+ /* sort basic-blocks according to function name and line number: */
+
+ sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0]));
+ len = 0;
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ /*
+ * Accept symbol if it's in the INCL_EXEC table
+ * or there is no INCL_EXEC table
+ * and it does not appear in the EXCL_EXEC table.
+ */
+ if (sym_lookup (&syms[INCL_EXEC], sym->addr)
+ || (syms[INCL_EXEC].len == 0
+ && !sym_lookup (&syms[EXCL_EXEC], sym->addr)))
+ {
+ sorted_bbs[len++] = sym;
+ }
+ }
+ qsort (sorted_bbs, len, sizeof (sorted_bbs[0]), cmp_bb);
+
+ /* output basic-blocks: */
+
+ for (i = 0; i < len; ++i)
+ {
+ if (sym->ncalls > 0 || ! ignore_zeros)
+ {
+ printf (_("%s:%d: (%s:0x%lx) %lu executions\n"),
+ sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
+ sym->name, sym->addr, sym->ncalls);
+ }
+ for (j = 0; j < NBBS && sym->bb_addr[j]; j ++)
+ {
+ if (sym->bb_calls[j] > 0 || ! ignore_zeros)
+ {
+ printf (_("%s:%d: (%s:0x%lx) %lu executions\n"),
+ sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
+ sym->name, sym->bb_addr[j], sym->bb_calls[j]);
+ }
+ }
+ }
+ free (sorted_bbs);
+}
+
+/*
+ * Helper for bb_annotated_source: format annotation containing
+ * number of line executions. Depends on being called on each
+ * line of a file in sequential order.
+ *
+ * Global variable bb_annotate_all_lines enables execution count
+ * compression (counts are supressed if identical to the last one)
+ * and prints counts on all executed lines. Otherwise, print
+ * all basic-block execution counts exactly once on the line
+ * that starts the basic-block.
+ */
+
+static void
+DEFUN (annotate_with_count, (buf, width, line_num, arg),
+ char *buf AND int width AND int line_num AND void *arg)
+{
+ Source_File *sf = arg;
+ Sym *b;
+ int i;
+ static unsigned long last_count;
+ unsigned long last_print = (unsigned long) -1;
+
+ b = NULL;
+ if (line_num <= sf->num_lines)
+ {
+ b = sf->line[line_num - 1];
+ }
+ if (!b)
+ {
+ for (i = 0; i < width; i++)
+ buf[i] = ' ';
+ buf[width] = '\0';
+ }
+ else
+ {
+ char tmpbuf[NBBS * 30];
+ char *p;
+ unsigned long ncalls;
+ int ncalls_set;
+ int len;
+
+ ++num_executable_lines;
+
+ p = tmpbuf;
+ *p = '\0';
+
+ ncalls = 0;
+ ncalls_set = 0;
+
+ /* If this is a function entry point, label the line no matter what.
+ * Otherwise, we're in the middle of a function, so check to see
+ * if the first basic-block address is larger than the starting
+ * address of the line. If so, then this line begins with a
+ * a portion of the previous basic-block, so print that prior
+ * execution count (if bb_annotate_all_lines is set).
+ */
+
+ if (b->is_func)
+ {
+ sprintf (p, "%lu", b->ncalls);
+ p += strlen (p);
+ last_count = b->ncalls;
+ last_print = last_count;
+ ncalls = b->ncalls;
+ ncalls_set = 1;
+ }
+ else if (bb_annotate_all_lines
+ && b->bb_addr[0] && b->bb_addr[0] > b->addr)
+ {
+ sprintf (p, "%lu", last_count);
+ p += strlen (p);
+ last_print = last_count;
+ ncalls = last_count;
+ ncalls_set = 1;
+ }
+
+ /* Loop through all of this line's basic-blocks. For each one,
+ * update last_count, then compress sequential identical counts
+ * (if bb_annotate_all_lines) and print the execution count.
+ */
+
+ for (i = 0; i < NBBS && b->bb_addr[i]; i++)
+ {
+ last_count = b->bb_calls[i];
+ if (! ncalls_set)
+ {
+ ncalls = 0;
+ ncalls_set = 1;
+ }
+ ncalls += last_count;
+
+ if (bb_annotate_all_lines && last_count == last_print)
+ {
+ continue;
+ }
+
+ if (p > tmpbuf)
+ *p++ = ',';
+ sprintf (p, "%lu", last_count);
+ p += strlen (p);
+
+ last_print = last_count;
+ }
+
+ /* We're done. If nothing has been printed on this line,
+ * print the last execution count (bb_annotate_all_lines),
+ * which could be from either a previous line (if there were
+ * no BBs on this line), or from this line (if all our BB
+ * counts were compressed out because they were identical).
+ */
+
+ if (bb_annotate_all_lines && p == tmpbuf)
+ {
+ sprintf (p, "%lu", last_count);
+ p += strlen (p);
+ ncalls = last_count;
+ ncalls_set = 1;
+ }
+
+ if (! ncalls_set)
+ {
+ int c;
+
+ for (c = 0; c < width; c++)
+ buf[c] = ' ';
+ buf[width] = '\0';
+ return;
+ }
+
+ ++num_lines_executed;
+
+ if (ncalls < bb_min_calls)
+ {
+ strcpy (tmpbuf, "#####");
+ p = tmpbuf + 5;
+ }
+
+ strcpy (p, " -> ");
+ p += 4;
+
+ len = p - tmpbuf;
+ if (len >= width)
+ {
+ strncpy (buf, tmpbuf, width);
+ buf[width] = '\0';
+ }
+ else
+ {
+ int c;
+
+ strcpy (buf + width - len, tmpbuf);
+ for (c = 0; c < width - len; ++c)
+ buf[c] = ' ';
+ }
+ }
+}
+
+/*
+ * Annotate the files named in SOURCE_FILES with basic-block statistics
+ * (execution counts). After each source files, a few statistics
+ * regarding that source file are printed.
+ */
+void
+DEFUN_VOID (print_annotated_source)
+{
+ Sym *sym, *line_stats, *new_line;
+ Source_File *sf;
+ int i, table_len;
+ FILE *ofp;
+
+ /*
+ * Find maximum line number for each source file that user is
+ * interested in:
+ */
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ /*
+ * Accept symbol if it's file is known, its line number is
+ * bigger than anything we have seen for that file so far and
+ * if it's in the INCL_ANNO table or there is no INCL_ANNO
+ * table and it does not appear in the EXCL_ANNO table.
+ */
+ if (sym->file && sym->line_num > sym->file->num_lines
+ && (sym_lookup (&syms[INCL_ANNO], sym->addr)
+ || (syms[INCL_ANNO].len == 0
+ && !sym_lookup (&syms[EXCL_ANNO], sym->addr))))
+ {
+ sym->file->num_lines = sym->line_num;
+ }
+ }
+
+ /* allocate line descriptors: */
+
+ for (sf = first_src_file; sf; sf = sf->next)
+ {
+ if (sf->num_lines > 0)
+ {
+ sf->line = (void *) xmalloc (sf->num_lines * sizeof (sf->line[0]));
+ memset (sf->line, 0, sf->num_lines * sizeof (sf->line[0]));
+ }
+ }
+
+ /* count executions per line: */
+
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ if (sym->file && sym->file->num_lines
+ && (sym_lookup (&syms[INCL_ANNO], sym->addr)
+ || (syms[INCL_ANNO].len == 0
+ && !sym_lookup (&syms[EXCL_ANNO], sym->addr))))
+ {
+ sym->file->ncalls += sym->ncalls;
+ line_stats = sym->file->line[sym->line_num - 1];
+ if (!line_stats)
+ {
+ /* common case has at most one basic-block per source line: */
+ sym->file->line[sym->line_num - 1] = sym;
+ }
+ else if (!line_stats->addr)
+ {
+ /* sym is the 3rd .. nth basic block for this line: */
+ line_stats->ncalls += sym->ncalls;
+ }
+ else
+ {
+ /* sym is the second basic block for this line */
+ new_line = (Sym *) xmalloc (sizeof (*new_line));
+ *new_line = *line_stats;
+ new_line->addr = 0;
+ new_line->ncalls += sym->ncalls;
+ sym->file->line[sym->line_num - 1] = new_line;
+ }
+ }
+ }
+
+ /* plod over source files, annotating them: */
+
+ for (sf = first_src_file; sf; sf = sf->next)
+ {
+ if (!sf->num_lines || (ignore_zeros && sf->ncalls == 0))
+ {
+ continue;
+ }
+
+ num_executable_lines = num_lines_executed = 0;
+ ofp = annotate_source (sf, 16, annotate_with_count, sf);
+ if (!ofp)
+ {
+ continue;
+ }
+
+ if (bb_table_length > 0)
+ {
+ fprintf (ofp, _("\n\nTop %d Lines:\n\n Line Count\n\n"),
+ bb_table_length);
+
+ /* abuse line arrays---it's not needed anymore: */
+ qsort (sf->line, sf->num_lines, sizeof (sf->line[0]), cmp_ncalls);
+ table_len = bb_table_length;
+ if (table_len > sf->num_lines)
+ {
+ table_len = sf->num_lines;
+ }
+ for (i = 0; i < table_len; ++i)
+ {
+ sym = sf->line[i];
+ if (!sym || sym->ncalls == 0)
+ {
+ break;
+ }
+ fprintf (ofp, "%9d %10lu\n", sym->line_num, sym->ncalls);
+ }
+ }
+
+ free (sf->line);
+ sf->line = 0;
+
+ fprintf (ofp, _("\nExecution Summary:\n\n"));
+ fprintf (ofp, _("%9ld Executable lines in this file\n"),
+ num_executable_lines);
+ fprintf (ofp, _("%9ld Lines executed\n"), num_lines_executed);
+ fprintf (ofp, _("%9.2f Percent of the file executed\n"),
+ num_executable_lines
+ ? 100.0 * num_lines_executed / (double) num_executable_lines
+ : 100.0);
+ fprintf (ofp, _("\n%9lu Total number of line executions\n"),
+ sf->ncalls);
+ fprintf (ofp, _("%9.2f Average executions per line\n"),
+ num_executable_lines
+ ? (double) sf->ncalls / (double) num_executable_lines
+ : 0.0);
+ if (ofp != stdout)
+ {
+ fclose (ofp);
+ }
+ }
+}
diff --git a/gprof/basic_blocks.h b/gprof/basic_blocks.h
new file mode 100644
index 00000000000..923eca11f73
--- /dev/null
+++ b/gprof/basic_blocks.h
@@ -0,0 +1,23 @@
+#ifndef basic_blocks_h
+#define basic_blocks_h
+
+#include <stdio.h>
+#include "gprof.h"
+#include "source.h"
+#include "symtab.h"
+
+/*
+ * Options:
+ */
+extern bool bb_annotate_all_lines; /* force annotation of all lines? */
+extern int bb_table_length; /* length of most-used bb table */
+extern unsigned long bb_min_calls; /* minimum execution count */
+
+extern void bb_read_rec PARAMS ((FILE * ifp, const char *filename));
+extern void bb_write_blocks PARAMS ((FILE * ofp, const char *filename));
+extern void bb_create_syms PARAMS ((void));
+
+extern void print_annotated_source PARAMS ((void));
+extern void print_exec_counts PARAMS ((void));
+
+#endif /* basic_blocks_h */
diff --git a/gprof/bb_exit_func.c b/gprof/bb_exit_func.c
new file mode 100644
index 00000000000..813321566c7
--- /dev/null
+++ b/gprof/bb_exit_func.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1994 David Mosberger-Tang.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ *
+ * __bb_exit_func() dumps all the basic-block statistics linked into
+ * the bb_head chain to .d files.
+ */
+#include <stdio.h>
+#include <strings.h>
+#include "bfd.h"
+#include "gmon_out.h"
+
+/* structure emitted by -a */
+struct bb {
+ long zero_word;
+ const char *filename;
+ long *counts;
+ long ncounts;
+ struct bb *next;
+ const unsigned long *addresses;
+};
+
+struct bb *__bb_head = (struct bb *)0;
+
+
+void
+__bb_exit_func (void)
+{
+ const int version = GMON_VERSION;
+ struct gmon_hdr ghdr;
+ struct bb *ptr;
+ FILE *fp;
+ /*
+ * GEN_GMON_CNT_FILE should be defined on systems with mcleanup()
+ * functions that do not write basic-block to gmon.out. In such
+ * cases profiling with "-pg -a" would result in a gmon.out file
+ * without basic-block info (because the file written here would
+ * be overwritten. Thus, a separate file is generated instead.
+ * The two files can easily be combined by specifying them
+ * on gprof's command line (and possibly generating a gmon.sum
+ * file with "gprof -s").
+ */
+#ifndef GEN_GMON_CNT_FILE
+# define OUT_NAME "gmon.out"
+#else
+# define OUT_NAME "gmon.cnt"
+#endif
+ fp = fopen(OUT_NAME, "wb");
+ if (!fp) {
+ perror(OUT_NAME);
+ return;
+ } /* if */
+ memcpy(&ghdr.cookie[0], GMON_MAGIC, 4);
+ memcpy(&ghdr.version, &version, sizeof(version));
+ fwrite(&ghdr, sizeof(ghdr), 1, fp);
+
+ for (ptr = __bb_head; ptr != 0; ptr = ptr->next) {
+ u_int ncounts = ptr->ncounts;
+ u_char tag;
+ u_int i;
+
+ tag = GMON_TAG_BB_COUNT;
+ fwrite(&tag, sizeof(tag), 1, fp);
+ fwrite(&ncounts, sizeof(ncounts), 1, fp);
+
+ for (i = 0; i < ncounts; ++i) {
+ fwrite(&ptr->addresses[i], sizeof(ptr->addresses[0]), 1, fp);
+ fwrite(&ptr->counts[i], sizeof(ptr->counts[0]), 1, fp);
+ } /* for */
+ } /* for */
+ fclose (fp);
+} /* __bb_exit_func */
+
+ /*** end of __bb_exit_func.c ***/
diff --git a/gprof/bbconv.pl b/gprof/bbconv.pl
new file mode 100755
index 00000000000..7312f5162fe
--- /dev/null
+++ b/gprof/bbconv.pl
@@ -0,0 +1,36 @@
+#! /usr/bin/perl
+
+# This script converts a "bb.out" file into a format
+# suitable for processing by gprof
+
+# Write a new-style gmon header
+
+print pack("A4Ix12", "gmon", 1);
+
+
+# The input file format contains header lines and data lines.
+# Header lines contain a count of how many data lines follow before
+# the next header line. $blockcount is set to the count that
+# appears in each header line, then decremented at each data line.
+# $blockcount should always be zero at the start of a header line,
+# and should never be zero at the start of a data line.
+
+$blockcount=0;
+
+while (<>) {
+ if (/^File .*, ([0-9]+) basic blocks/) {
+ print STDERR "Miscount: line $.\n" if ($blockcount != 0);
+ $blockcount = $1;
+
+ print pack("cI", 2, $blockcount);
+ }
+ if (/Block.*executed([ 0-9]+) time.* address= 0x([0-9a-fA-F]*)/) {
+ print STDERR "Miscount: line $.\n" if ($blockcount == 0);
+ $blockcount-- if ($blockcount > 0);
+
+ $count = $1;
+ $addr = hex $2;
+
+ print pack("II",$addr,$count);
+ }
+}
diff --git a/gprof/bsd_callg_bl.m b/gprof/bsd_callg_bl.m
new file mode 100644
index 00000000000..533c96ca439
--- /dev/null
+++ b/gprof/bsd_callg_bl.m
@@ -0,0 +1,108 @@
+
+
+
+call graph profile:
+ The sum of self and descendents is the major sort
+ for this listing.
+
+ function entries:
+
+index the index of the function in the call graph
+ listing, as an aid to locating it (see below).
+
+%time the percentage of the total time of the program
+ accounted for by this function and its
+ descendents.
+
+self the number of seconds spent in this function
+ itself.
+
+descendents
+ the number of seconds spent in the descendents of
+ this function on behalf of this function.
+
+called the number of times this function is called (other
+ than recursive calls).
+
+self the number of times this function calls itself
+ recursively.
+
+name the name of the function, with an indication of
+ its membership in a cycle, if any.
+
+index the index of the function in the call graph
+ listing, as an aid to locating it.
+
+
+
+ parent listings:
+
+self* the number of seconds of this function's self time
+ which is due to calls from this parent.
+
+descendents*
+ the number of seconds of this function's
+ descendent time which is due to calls from this
+ parent.
+
+called** the number of times this function is called by
+ this parent. This is the numerator of the
+ fraction which divides up the function's time to
+ its parents.
+
+total* the number of times this function was called by
+ all of its parents. This is the denominator of
+ the propagation fraction.
+
+parents the name of this parent, with an indication of the
+ parent's membership in a cycle, if any.
+
+index the index of this parent in the call graph
+ listing, as an aid in locating it.
+
+
+
+ children listings:
+
+self* the number of seconds of this child's self time
+ which is due to being called by this function.
+
+descendent*
+ the number of seconds of this child's descendent's
+ time which is due to being called by this
+ function.
+
+called** the number of times this child is called by this
+ function. This is the numerator of the
+ propagation fraction for this child.
+
+total* the number of times this child is called by all
+ functions. This is the denominator of the
+ propagation fraction.
+
+children the name of this child, and an indication of its
+ membership in a cycle, if any.
+
+index the index of this child in the call graph listing,
+ as an aid to locating it.
+
+
+
+ * these fields are omitted for parents (or
+ children) in the same cycle as the function. If
+ the function (or child) is a member of a cycle,
+ the propagated times and propagation denominator
+ represent the self time and descendent time of the
+ cycle as a whole.
+
+ ** static-only parents and children are indicated
+ by a call count of 0.
+
+
+
+ cycle listings:
+ the cycle as a whole is listed with the same
+ fields as a function entry. Below it are listed
+ the members of the cycle, and their contributions
+ to the time and call counts of the cycle.
+
diff --git a/gprof/call_graph.c b/gprof/call_graph.c
new file mode 100644
index 00000000000..8f12cbd4056
--- /dev/null
+++ b/gprof/call_graph.c
@@ -0,0 +1,116 @@
+#include "cg_arcs.h"
+#include "call_graph.h"
+#include "corefile.h"
+#include "gmon_io.h"
+#include "gmon_out.h"
+#include "symtab.h"
+#include "sym_ids.h"
+
+extern void
+DEFUN (cg_tally, (from_pc, self_pc, count),
+ bfd_vma from_pc AND bfd_vma self_pc AND unsigned long count)
+{
+ Sym *parent;
+ Sym *child;
+
+ parent = sym_lookup (&symtab, from_pc);
+ child = sym_lookup (&symtab, self_pc);
+
+ if (child == NULL || parent == NULL)
+ return;
+
+ /* If we're doing line-by-line profiling, both the parent and the
+ child will probably point to line symbols instead of function
+ symbols. For the parent this is fine, since this identifies the
+ line number in the calling routing, but the child should always
+ point to a function entry point, so we back up in the symbol
+ table until we find it.
+
+ For normal profiling, is_func will be set on all symbols, so this
+ code will do nothing. */
+
+ while (child >= symtab.base && ! child->is_func)
+ --child;
+
+ if (child < symtab.base)
+ return;
+
+ /*
+ * Keep arc if it is on INCL_ARCS table or if the INCL_ARCS table
+ * is empty and it is not in the EXCL_ARCS table.
+ */
+ if (sym_id_arc_is_present (&syms[INCL_ARCS], parent, child)
+ || (syms[INCL_ARCS].len == 0
+ && !sym_id_arc_is_present (&syms[EXCL_ARCS], parent, child)))
+ {
+ child->ncalls += count;
+ DBG (TALLYDEBUG,
+ printf (_("[cg_tally] arc from %s to %s traversed %lu times\n"),
+ parent->name, child->name, count));
+ arc_add (parent, child, count);
+ }
+}
+
+
+/*
+ * Read a record from file IFP describing an arc in the function
+ * call-graph and the count of how many times the arc has been
+ * traversed. FILENAME is the name of file IFP and is provided
+ * for formatting error-messages only.
+ */
+void
+DEFUN (cg_read_rec, (ifp, filename), FILE * ifp AND CONST char *filename)
+{
+ bfd_vma from_pc, self_pc;
+ struct gmon_cg_arc_record arc;
+ unsigned long count;
+
+ if (fread (&arc, sizeof (arc), 1, ifp) != 1)
+ {
+ fprintf (stderr, _("%s: %s: unexpected end of file\n"),
+ whoami, filename);
+ done (1);
+ }
+ from_pc = get_vma (core_bfd, (bfd_byte *) arc.from_pc);
+ self_pc = get_vma (core_bfd, (bfd_byte *) arc.self_pc);
+ count = bfd_get_32 (core_bfd, (bfd_byte *) arc.count);
+ DBG (SAMPLEDEBUG,
+ printf ("[cg_read_rec] frompc 0x%lx selfpc 0x%lx count %lu\n",
+ from_pc, self_pc, count));
+ /* add this arc: */
+ cg_tally (from_pc, self_pc, count);
+}
+
+
+/*
+ * Write all the arcs in the call-graph to file OFP. FILENAME is
+ * the name of OFP and is provided for formatting error-messages
+ * only.
+ */
+void
+DEFUN (cg_write_arcs, (ofp, filename), FILE * ofp AND const char *filename)
+{
+ const unsigned char tag = GMON_TAG_CG_ARC;
+ struct gmon_cg_arc_record raw_arc;
+ Arc *arc;
+ Sym *sym;
+
+ for (sym = symtab.base; sym < symtab.limit; sym++)
+ {
+ for (arc = sym->cg.children; arc; arc = arc->next_child)
+ {
+ put_vma (core_bfd, arc->parent->addr, (bfd_byte *) raw_arc.from_pc);
+ put_vma (core_bfd, arc->child->addr, (bfd_byte *) raw_arc.self_pc);
+ bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count);
+ if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
+ || fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ DBG (SAMPLEDEBUG,
+ printf ("[cg_write_arcs] frompc 0x%lx selfpc 0x%lx count %lu\n",
+ arc->parent->addr, arc->child->addr, arc->count));
+ }
+ }
+}
diff --git a/gprof/call_graph.h b/gprof/call_graph.h
new file mode 100644
index 00000000000..be5139b758f
--- /dev/null
+++ b/gprof/call_graph.h
@@ -0,0 +1,13 @@
+#ifndef call_graph_h
+#define call_graph_h
+
+#include <stdio.h>
+#include "gprof.h"
+#include "symtab.h"
+
+extern void cg_tally PARAMS ((bfd_vma from_pc, bfd_vma self_pc,
+ unsigned long count));
+extern void cg_read_rec PARAMS ((FILE * ifp, const char *filename));
+extern void cg_write_arcs PARAMS ((FILE * ofp, const char *filename));
+
+#endif /* call_graph_h */
diff --git a/gprof/cg_arcs.c b/gprof/cg_arcs.c
new file mode 100644
index 00000000000..07023170ded
--- /dev/null
+++ b/gprof/cg_arcs.c
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "libiberty.h"
+#include "gprof.h"
+#include "call_graph.h"
+#include "cg_arcs.h"
+#include "cg_dfn.h"
+#include "cg_print.h"
+#include "utils.h"
+#include "sym_ids.h"
+
+Sym *cycle_header;
+unsigned int num_cycles;
+Arc **arcs;
+unsigned int numarcs;
+
+/*
+ * Return TRUE iff PARENT has an arc to covers the address
+ * range covered by CHILD.
+ */
+Arc *
+DEFUN (arc_lookup, (parent, child), Sym * parent AND Sym * child)
+{
+ Arc *arc;
+
+ if (!parent || !child)
+ {
+ printf ("[arc_lookup] parent == 0 || child == 0\n");
+ return 0;
+ }
+ DBG (LOOKUPDEBUG, printf ("[arc_lookup] parent %s child %s\n",
+ parent->name, child->name));
+ for (arc = parent->cg.children; arc; arc = arc->next_child)
+ {
+ DBG (LOOKUPDEBUG, printf ("[arc_lookup]\t parent %s child %s\n",
+ arc->parent->name, arc->child->name));
+ if (child->addr >= arc->child->addr
+ && child->end_addr <= arc->child->end_addr)
+ {
+ return arc;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * Add (or just increment) an arc:
+ */
+void
+DEFUN (arc_add, (parent, child, count),
+ Sym * parent AND Sym * child AND unsigned long count)
+{
+ static unsigned int maxarcs = 0;
+ Arc *arc, **newarcs;
+
+ DBG (TALLYDEBUG, printf ("[arc_add] %lu arcs from %s to %s\n",
+ count, parent->name, child->name));
+ arc = arc_lookup (parent, child);
+ if (arc)
+ {
+ /*
+ * A hit: just increment the count.
+ */
+ DBG (TALLYDEBUG, printf ("[tally] hit %lu += %lu\n",
+ arc->count, count));
+ arc->count += count;
+ return;
+ }
+ arc = (Arc *) xmalloc (sizeof (*arc));
+ memset (arc, 0, sizeof (*arc));
+ arc->parent = parent;
+ arc->child = child;
+ arc->count = count;
+
+ /* If this isn't an arc for a recursive call to parent, then add it
+ to the array of arcs. */
+ if (parent != child)
+ {
+ /* If we've exhausted space in our current array, get a new one
+ and copy the contents. We might want to throttle the doubling
+ factor one day. */
+ if (numarcs == maxarcs)
+ {
+ /* Determine how much space we want to allocate. */
+ if (maxarcs == 0)
+ maxarcs = 1;
+ maxarcs *= 2;
+
+ /* Allocate the new array. */
+ newarcs = (Arc **)xmalloc(sizeof (Arc *) * maxarcs);
+
+ /* Copy the old array's contents into the new array. */
+ memcpy (newarcs, arcs, numarcs * sizeof (Arc *));
+
+ /* Free up the old array. */
+ free (arcs);
+
+ /* And make the new array be the current array. */
+ arcs = newarcs;
+ }
+
+ /* Place this arc in the arc array. */
+ arcs[numarcs++] = arc;
+ }
+
+ /* prepend this child to the children of this parent: */
+ arc->next_child = parent->cg.children;
+ parent->cg.children = arc;
+
+ /* prepend this parent to the parents of this child: */
+ arc->next_parent = child->cg.parents;
+ child->cg.parents = arc;
+}
+
+
+static int
+DEFUN (cmp_topo, (lp, rp), const PTR lp AND const PTR rp)
+{
+ const Sym *left = *(const Sym **) lp;
+ const Sym *right = *(const Sym **) rp;
+
+ return left->cg.top_order - right->cg.top_order;
+}
+
+
+static void
+DEFUN (propagate_time, (parent), Sym * parent)
+{
+ Arc *arc;
+ Sym *child;
+ double share, prop_share;
+
+ if (parent->cg.prop.fract == 0.0)
+ {
+ return;
+ }
+
+ /* gather time from children of this parent: */
+
+ for (arc = parent->cg.children; arc; arc = arc->next_child)
+ {
+ child = arc->child;
+ if (arc->count == 0 || child == parent || child->cg.prop.fract == 0)
+ {
+ continue;
+ }
+ if (child->cg.cyc.head != child)
+ {
+ if (parent->cg.cyc.num == child->cg.cyc.num)
+ {
+ continue;
+ }
+ if (parent->cg.top_order <= child->cg.top_order)
+ {
+ fprintf (stderr, "[propagate] toporder botches\n");
+ }
+ child = child->cg.cyc.head;
+ }
+ else
+ {
+ if (parent->cg.top_order <= child->cg.top_order)
+ {
+ fprintf (stderr, "[propagate] toporder botches\n");
+ continue;
+ }
+ }
+ if (child->ncalls == 0)
+ {
+ continue;
+ }
+
+ /* distribute time for this arc: */
+ arc->time = child->hist.time * (((double) arc->count)
+ / ((double) child->ncalls));
+ arc->child_time = child->cg.child_time
+ * (((double) arc->count) / ((double) child->ncalls));
+ share = arc->time + arc->child_time;
+ parent->cg.child_time += share;
+
+ /* (1 - cg.prop.fract) gets lost along the way: */
+ prop_share = parent->cg.prop.fract * share;
+
+ /* fix things for printing: */
+ parent->cg.prop.child += prop_share;
+ arc->time *= parent->cg.prop.fract;
+ arc->child_time *= parent->cg.prop.fract;
+
+ /* add this share to the parent's cycle header, if any: */
+ if (parent->cg.cyc.head != parent)
+ {
+ parent->cg.cyc.head->cg.child_time += share;
+ parent->cg.cyc.head->cg.prop.child += prop_share;
+ }
+ DBG (PROPDEBUG,
+ printf ("[prop_time] child \t");
+ print_name (child);
+ printf (" with %f %f %lu/%lu\n", child->hist.time,
+ child->cg.child_time, arc->count, child->ncalls);
+ printf ("[prop_time] parent\t");
+ print_name (parent);
+ printf ("\n[prop_time] share %f\n", share));
+ }
+}
+
+
+/*
+ * Compute the time of a cycle as the sum of the times of all
+ * its members.
+ */
+static void
+DEFUN_VOID (cycle_time)
+{
+ Sym *member, *cyc;
+
+ for (cyc = &cycle_header[1]; cyc <= &cycle_header[num_cycles]; ++cyc)
+ {
+ for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next)
+ {
+ if (member->cg.prop.fract == 0.0)
+ {
+ /*
+ * All members have the same propfraction except those
+ * that were excluded with -E.
+ */
+ continue;
+ }
+ cyc->hist.time += member->hist.time;
+ }
+ cyc->cg.prop.self = cyc->cg.prop.fract * cyc->hist.time;
+ }
+}
+
+
+static void
+DEFUN_VOID (cycle_link)
+{
+ Sym *sym, *cyc, *member;
+ Arc *arc;
+ int num;
+
+ /* count the number of cycles, and initialize the cycle lists: */
+
+ num_cycles = 0;
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ /* this is how you find unattached cycles: */
+ if (sym->cg.cyc.head == sym && sym->cg.cyc.next)
+ {
+ ++num_cycles;
+ }
+ }
+
+ /*
+ * cycle_header is indexed by cycle number: i.e. it is origin 1,
+ * not origin 0.
+ */
+ cycle_header = (Sym *) xmalloc ((num_cycles + 1) * sizeof (Sym));
+
+ /*
+ * Now link cycles to true cycle-heads, number them, accumulate
+ * the data for the cycle.
+ */
+ num = 0;
+ cyc = cycle_header;
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ if (!(sym->cg.cyc.head == sym && sym->cg.cyc.next != 0))
+ {
+ continue;
+ }
+ ++num;
+ ++cyc;
+ sym_init (cyc);
+ cyc->cg.print_flag = TRUE; /* should this be printed? */
+ cyc->cg.top_order = DFN_NAN; /* graph call chain top-sort order */
+ cyc->cg.cyc.num = num; /* internal number of cycle on */
+ cyc->cg.cyc.head = cyc; /* pointer to head of cycle */
+ cyc->cg.cyc.next = sym; /* pointer to next member of cycle */
+ DBG (CYCLEDEBUG, printf ("[cycle_link] ");
+ print_name (sym);
+ printf (" is the head of cycle %d\n", num));
+
+ /* link members to cycle header: */
+ for (member = sym; member; member = member->cg.cyc.next)
+ {
+ member->cg.cyc.num = num;
+ member->cg.cyc.head = cyc;
+ }
+
+ /*
+ * Count calls from outside the cycle and those among cycle
+ * members:
+ */
+ for (member = sym; member; member = member->cg.cyc.next)
+ {
+ for (arc = member->cg.parents; arc; arc = arc->next_parent)
+ {
+ if (arc->parent == member)
+ {
+ continue;
+ }
+ if (arc->parent->cg.cyc.num == num)
+ {
+ cyc->cg.self_calls += arc->count;
+ }
+ else
+ {
+ cyc->ncalls += arc->count;
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ * Check if any parent of this child (or outside parents of this
+ * cycle) have their print flags on and set the print flag of the
+ * child (cycle) appropriately. Similarly, deal with propagation
+ * fractions from parents.
+ */
+static void
+DEFUN (inherit_flags, (child), Sym * child)
+{
+ Sym *head, *parent, *member;
+ Arc *arc;
+
+ head = child->cg.cyc.head;
+ if (child == head)
+ {
+ /* just a regular child, check its parents: */
+ child->cg.print_flag = FALSE;
+ child->cg.prop.fract = 0.0;
+ for (arc = child->cg.parents; arc; arc = arc->next_parent)
+ {
+ parent = arc->parent;
+ if (child == parent)
+ {
+ continue;
+ }
+ child->cg.print_flag |= parent->cg.print_flag;
+ /*
+ * If the child was never actually called (e.g., this arc
+ * is static (and all others are, too)) no time propagates
+ * along this arc.
+ */
+ if (child->ncalls != 0)
+ {
+ child->cg.prop.fract += parent->cg.prop.fract
+ * (((double) arc->count) / ((double) child->ncalls));
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Its a member of a cycle, look at all parents from outside
+ * the cycle.
+ */
+ head->cg.print_flag = FALSE;
+ head->cg.prop.fract = 0.0;
+ for (member = head->cg.cyc.next; member; member = member->cg.cyc.next)
+ {
+ for (arc = member->cg.parents; arc; arc = arc->next_parent)
+ {
+ if (arc->parent->cg.cyc.head == head)
+ {
+ continue;
+ }
+ parent = arc->parent;
+ head->cg.print_flag |= parent->cg.print_flag;
+ /*
+ * If the cycle was never actually called (e.g. this
+ * arc is static (and all others are, too)) no time
+ * propagates along this arc.
+ */
+ if (head->ncalls != 0)
+ {
+ head->cg.prop.fract += parent->cg.prop.fract
+ * (((double) arc->count) / ((double) head->ncalls));
+ }
+ }
+ }
+ for (member = head; member; member = member->cg.cyc.next)
+ {
+ member->cg.print_flag = head->cg.print_flag;
+ member->cg.prop.fract = head->cg.prop.fract;
+ }
+ }
+}
+
+
+/*
+ * In one top-to-bottom pass over the topologically sorted symbols
+ * propagate:
+ * cg.print_flag as the union of parents' print_flags
+ * propfraction as the sum of fractional parents' propfractions
+ * and while we're here, sum time for functions.
+ */
+static void
+DEFUN (propagate_flags, (symbols), Sym ** symbols)
+{
+ int index;
+ Sym *old_head, *child;
+
+ old_head = 0;
+ for (index = symtab.len - 1; index >= 0; --index)
+ {
+ child = symbols[index];
+ /*
+ * If we haven't done this function or cycle, inherit things
+ * from parent. This way, we are linear in the number of arcs
+ * since we do all members of a cycle (and the cycle itself)
+ * as we hit the first member of the cycle.
+ */
+ if (child->cg.cyc.head != old_head)
+ {
+ old_head = child->cg.cyc.head;
+ inherit_flags (child);
+ }
+ DBG (PROPDEBUG,
+ printf ("[prop_flags] ");
+ print_name (child);
+ printf ("inherits print-flag %d and prop-fract %f\n",
+ child->cg.print_flag, child->cg.prop.fract));
+ if (!child->cg.print_flag)
+ {
+ /*
+ * Printflag is off. It gets turned on by being in the
+ * INCL_GRAPH table, or there being an empty INCL_GRAPH
+ * table and not being in the EXCL_GRAPH table.
+ */
+ if (sym_lookup (&syms[INCL_GRAPH], child->addr)
+ || (syms[INCL_GRAPH].len == 0
+ && !sym_lookup (&syms[EXCL_GRAPH], child->addr)))
+ {
+ child->cg.print_flag = TRUE;
+ }
+ }
+ else
+ {
+ /*
+ * This function has printing parents: maybe someone wants
+ * to shut it up by putting it in the EXCL_GRAPH table.
+ * (But favor INCL_GRAPH over EXCL_GRAPH.)
+ */
+ if (!sym_lookup (&syms[INCL_GRAPH], child->addr)
+ && sym_lookup (&syms[EXCL_GRAPH], child->addr))
+ {
+ child->cg.print_flag = FALSE;
+ }
+ }
+ if (child->cg.prop.fract == 0.0)
+ {
+ /*
+ * No parents to pass time to. Collect time from children
+ * if its in the INCL_TIME table, or there is an empty
+ * INCL_TIME table and its not in the EXCL_TIME table.
+ */
+ if (sym_lookup (&syms[INCL_TIME], child->addr)
+ || (syms[INCL_TIME].len == 0
+ && !sym_lookup (&syms[EXCL_TIME], child->addr)))
+ {
+ child->cg.prop.fract = 1.0;
+ }
+ }
+ else
+ {
+ /*
+ * It has parents to pass time to, but maybe someone wants
+ * to shut it up by puttting it in the EXCL_TIME table.
+ * (But favor being in INCL_TIME tabe over being in
+ * EXCL_TIME table.)
+ */
+ if (!sym_lookup (&syms[INCL_TIME], child->addr)
+ && sym_lookup (&syms[EXCL_TIME], child->addr))
+ {
+ child->cg.prop.fract = 0.0;
+ }
+ }
+ child->cg.prop.self = child->hist.time * child->cg.prop.fract;
+ print_time += child->cg.prop.self;
+ DBG (PROPDEBUG,
+ printf ("[prop_flags] ");
+ print_name (child);
+ printf (" ends up with printflag %d and prop-fract %f\n",
+ child->cg.print_flag, child->cg.prop.fract);
+ printf ("[prop_flags] time %f propself %f print_time %f\n",
+ child->hist.time, child->cg.prop.self, print_time));
+ }
+}
+
+
+/*
+ * Compare by decreasing propagated time. If times are equal, but one
+ * is a cycle header, say that's first (e.g. less, i.e. -1). If one's
+ * name doesn't have an underscore and the other does, say that one is
+ * first. All else being equal, compare by names.
+ */
+static int
+DEFUN (cmp_total, (lp, rp), const PTR lp AND const PTR rp)
+{
+ const Sym *left = *(const Sym **) lp;
+ const Sym *right = *(const Sym **) rp;
+ double diff;
+
+ diff = (left->cg.prop.self + left->cg.prop.child)
+ - (right->cg.prop.self + right->cg.prop.child);
+ if (diff < 0.0)
+ {
+ return 1;
+ }
+ if (diff > 0.0)
+ {
+ return -1;
+ }
+ if (!left->name && left->cg.cyc.num != 0)
+ {
+ return -1;
+ }
+ if (!right->name && right->cg.cyc.num != 0)
+ {
+ return 1;
+ }
+ if (!left->name)
+ {
+ return -1;
+ }
+ if (!right->name)
+ {
+ return 1;
+ }
+ if (left->name[0] != '_' && right->name[0] == '_')
+ {
+ return -1;
+ }
+ if (left->name[0] == '_' && right->name[0] != '_')
+ {
+ return 1;
+ }
+ if (left->ncalls > right->ncalls)
+ {
+ return -1;
+ }
+ if (left->ncalls < right->ncalls)
+ {
+ return 1;
+ }
+ return strcmp (left->name, right->name);
+}
+
+
+/*
+ * Topologically sort the graph (collapsing cycles), and propagates
+ * time bottom up and flags top down.
+ */
+Sym **
+DEFUN_VOID (cg_assemble)
+{
+ Sym *parent, **time_sorted_syms, **top_sorted_syms;
+ unsigned int index;
+ Arc *arc;
+
+ /*
+ * initialize various things:
+ * zero out child times.
+ * count self-recursive calls.
+ * indicate that nothing is on cycles.
+ */
+ for (parent = symtab.base; parent < symtab.limit; parent++)
+ {
+ parent->cg.child_time = 0.0;
+ arc = arc_lookup (parent, parent);
+ if (arc && parent == arc->child)
+ {
+ parent->ncalls -= arc->count;
+ parent->cg.self_calls = arc->count;
+ }
+ else
+ {
+ parent->cg.self_calls = 0;
+ }
+ parent->cg.prop.fract = 0.0;
+ parent->cg.prop.self = 0.0;
+ parent->cg.prop.child = 0.0;
+ parent->cg.print_flag = FALSE;
+ parent->cg.top_order = DFN_NAN;
+ parent->cg.cyc.num = 0;
+ parent->cg.cyc.head = parent;
+ parent->cg.cyc.next = 0;
+ if (ignore_direct_calls)
+ {
+ find_call (parent, parent->addr, (parent + 1)->addr);
+ }
+ }
+ /*
+ * Topologically order things. If any node is unnumbered, number
+ * it and any of its descendents.
+ */
+ for (parent = symtab.base; parent < symtab.limit; parent++)
+ {
+ if (parent->cg.top_order == DFN_NAN)
+ {
+ cg_dfn (parent);
+ }
+ }
+
+ /* link together nodes on the same cycle: */
+ cycle_link ();
+
+ /* sort the symbol table in reverse topological order: */
+ top_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ for (index = 0; index < symtab.len; ++index)
+ {
+ top_sorted_syms[index] = &symtab.base[index];
+ }
+ qsort (top_sorted_syms, symtab.len, sizeof (Sym *), cmp_topo);
+ DBG (DFNDEBUG,
+ printf ("[cg_assemble] topological sort listing\n");
+ for (index = 0; index < symtab.len; ++index)
+ {
+ printf ("[cg_assemble] ");
+ printf ("%d:", top_sorted_syms[index]->cg.top_order);
+ print_name (top_sorted_syms[index]);
+ printf ("\n");
+ }
+ );
+ /*
+ * Starting from the topological top, propagate print flags to
+ * children. also, calculate propagation fractions. this happens
+ * before time propagation since time propagation uses the
+ * fractions.
+ */
+ propagate_flags (top_sorted_syms);
+
+ /*
+ * Starting from the topological bottom, propogate children times
+ * up to parents.
+ */
+ cycle_time ();
+ for (index = 0; index < symtab.len; ++index)
+ {
+ propagate_time (top_sorted_syms[index]);
+ }
+
+ free (top_sorted_syms);
+
+ /*
+ * Now, sort by CG.PROP.SELF + CG.PROP.CHILD. Sorting both the regular
+ * function names and cycle headers.
+ */
+ time_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *));
+ for (index = 0; index < symtab.len; index++)
+ {
+ time_sorted_syms[index] = &symtab.base[index];
+ }
+ for (index = 1; index <= num_cycles; index++)
+ {
+ time_sorted_syms[symtab.len + index - 1] = &cycle_header[index];
+ }
+ qsort (time_sorted_syms, symtab.len + num_cycles, sizeof (Sym *),
+ cmp_total);
+ for (index = 0; index < symtab.len + num_cycles; index++)
+ {
+ time_sorted_syms[index]->cg.index = index + 1;
+ }
+ return time_sorted_syms;
+}
diff --git a/gprof/cg_arcs.h b/gprof/cg_arcs.h
new file mode 100644
index 00000000000..caa0197a2bb
--- /dev/null
+++ b/gprof/cg_arcs.h
@@ -0,0 +1,36 @@
+#ifndef cg_arcs_h
+#define cg_arcs_h
+
+#include "gprof.h"
+#include "symtab.h"
+
+/*
+ * Arc structure for call-graph.
+ *
+ * With pointers to the symbols of the parent and the child, a count
+ * of how many times this arc was traversed, and pointers to the next
+ * parent of this child and the next child of this parent.
+ */
+typedef struct arc
+ {
+ Sym *parent; /* source vertice of arc */
+ Sym *child; /* dest vertice of arc */
+ unsigned long count; /* # of calls from parent to child */
+ double time; /* time inherited along arc */
+ double child_time; /* child-time inherited along arc */
+ struct arc *next_parent; /* next parent of CHILD */
+ struct arc *next_child; /* next child of PARENT */
+ int has_been_placed; /* have this arc's functions been placed? */
+ }
+Arc;
+
+extern unsigned int num_cycles; /* number of cycles discovered */
+extern Sym *cycle_header; /* cycle headers */
+
+extern void arc_add PARAMS ((Sym * parent, Sym * child, unsigned long count));
+extern Arc *arc_lookup PARAMS ((Sym * parent, Sym * child));
+extern Sym **cg_assemble PARAMS ((void));
+extern Arc **arcs;
+extern unsigned int numarcs;
+
+#endif /* cg_arcs_h */
diff --git a/gprof/cg_dfn.c b/gprof/cg_dfn.c
new file mode 100644
index 00000000000..c9e37ab29e5
--- /dev/null
+++ b/gprof/cg_dfn.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <stdio.h>
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "cg_dfn.h"
+#include "symtab.h"
+#include "utils.h"
+
+#define DFN_DEPTH 100
+
+typedef struct
+ {
+ Sym *sym;
+ int cycle_top;
+ }
+DFN_Stack;
+
+DFN_Stack dfn_stack[DFN_DEPTH];
+int dfn_depth = 0;
+int dfn_counter = DFN_NAN;
+
+
+/*
+ * Is CHILD already numbered?
+ */
+static bool
+DEFUN (is_numbered, (child), Sym * child)
+{
+ return child->cg.top_order != DFN_NAN && child->cg.top_order != DFN_BUSY;
+}
+
+
+/*
+ * Is CHILD already busy?
+ */
+static bool
+DEFUN (is_busy, (child), Sym * child)
+{
+ if (child->cg.top_order == DFN_NAN)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ * CHILD is part of a cycle. Find the top caller into this cycle
+ * that is not part of the cycle and make all functions in cycle
+ * members of that cycle (top caller == caller with smallest
+ * depth-first number).
+ */
+static void
+DEFUN (find_cycle, (child), Sym * child)
+{
+ Sym *head = 0;
+ Sym *tail;
+ int cycle_top;
+ int index;
+
+ for (cycle_top = dfn_depth; cycle_top > 0; --cycle_top)
+ {
+ head = dfn_stack[cycle_top].sym;
+ if (child == head)
+ {
+ break;
+ }
+ if (child->cg.cyc.head != child && child->cg.cyc.head == head)
+ {
+ break;
+ }
+ }
+ if (cycle_top <= 0)
+ {
+ fprintf (stderr, "[find_cycle] couldn't find head of cycle\n");
+ done (1);
+ }
+#ifdef DEBUG
+ if (debug_level & DFNDEBUG)
+ {
+ printf ("[find_cycle] dfn_depth %d cycle_top %d ",
+ dfn_depth, cycle_top);
+ if (head)
+ {
+ print_name (head);
+ }
+ else
+ {
+ printf ("<unknown>");
+ }
+ printf ("\n");
+ }
+#endif
+ if (cycle_top == dfn_depth)
+ {
+ /*
+ * This is previous function, e.g. this calls itself. Sort of
+ * boring.
+ *
+ * Since we are taking out self-cycles elsewhere no need for
+ * the special case, here.
+ */
+ DBG (DFNDEBUG,
+ printf ("[find_cycle] ");
+ print_name (child);
+ printf ("\n"));
+ }
+ else
+ {
+ /*
+ * Glom intervening functions that aren't already glommed into
+ * this cycle. Things have been glommed when their cyclehead
+ * field points to the head of the cycle they are glommed
+ * into.
+ */
+ for (tail = head; tail->cg.cyc.next; tail = tail->cg.cyc.next)
+ {
+ /* void: chase down to tail of things already glommed */
+ DBG (DFNDEBUG,
+ printf ("[find_cycle] tail ");
+ print_name (tail);
+ printf ("\n"));
+ }
+ /*
+ * If what we think is the top of the cycle has a cyclehead
+ * field, then it's not really the head of the cycle, which is
+ * really what we want.
+ */
+ if (head->cg.cyc.head != head)
+ {
+ head = head->cg.cyc.head;
+ DBG (DFNDEBUG, printf ("[find_cycle] new cyclehead ");
+ print_name (head);
+ printf ("\n"));
+ }
+ for (index = cycle_top + 1; index <= dfn_depth; ++index)
+ {
+ child = dfn_stack[index].sym;
+ if (child->cg.cyc.head == child)
+ {
+ /*
+ * Not yet glommed anywhere, glom it and fix any
+ * children it has glommed.
+ */
+ tail->cg.cyc.next = child;
+ child->cg.cyc.head = head;
+ DBG (DFNDEBUG, printf ("[find_cycle] glomming ");
+ print_name (child);
+ printf (" onto ");
+ print_name (head);
+ printf ("\n"));
+ for (tail = child; tail->cg.cyc.next; tail = tail->cg.cyc.next)
+ {
+ tail->cg.cyc.next->cg.cyc.head = head;
+ DBG (DFNDEBUG, printf ("[find_cycle] and its tail ");
+ print_name (tail->cg.cyc.next);
+ printf (" onto ");
+ print_name (head);
+ printf ("\n"));
+ }
+ }
+ else if (child->cg.cyc.head != head /* firewall */ )
+ {
+ fprintf (stderr, "[find_cycle] glommed, but not to head\n");
+ done (1);
+ }
+ }
+ }
+}
+
+
+/*
+ * Prepare for visiting the children of PARENT. Push a parent onto
+ * the stack and mark it busy.
+ */
+static void
+DEFUN (pre_visit, (parent), Sym * parent)
+{
+ ++dfn_depth;
+ if (dfn_depth >= DFN_DEPTH)
+ {
+ fprintf (stderr, "[pre_visit] dfn_stack overflow\n");
+ done (1);
+ }
+ dfn_stack[dfn_depth].sym = parent;
+ dfn_stack[dfn_depth].cycle_top = dfn_depth;
+ parent->cg.top_order = DFN_BUSY;
+ DBG (DFNDEBUG, printf ("[pre_visit]\t\t%d:", dfn_depth);
+ print_name (parent);
+ printf ("\n"));
+}
+
+
+/*
+ * Done with visiting node PARENT. Pop PARENT off dfn_stack
+ * and number functions if PARENT is head of a cycle.
+ */
+static void
+DEFUN (post_visit, (parent), Sym * parent)
+{
+ Sym *member;
+
+ DBG (DFNDEBUG, printf ("[post_visit]\t%d: ", dfn_depth);
+ print_name (parent);
+ printf ("\n"));
+ /*
+ * Number functions and things in their cycles unless the function
+ * is itself part of a cycle:
+ */
+ if (parent->cg.cyc.head == parent)
+ {
+ ++dfn_counter;
+ for (member = parent; member; member = member->cg.cyc.next)
+ {
+ member->cg.top_order = dfn_counter;
+ DBG (DFNDEBUG, printf ("[post_visit]\t\tmember ");
+ print_name (member);
+ printf ("-> cg.top_order = %d\n", dfn_counter));
+ }
+ }
+ else
+ {
+ DBG (DFNDEBUG, printf ("[post_visit]\t\tis part of a cycle\n"));
+ }
+ --dfn_depth;
+}
+
+
+/*
+ * Given this PARENT, depth first number its children.
+ */
+void
+DEFUN (cg_dfn, (parent), Sym * parent)
+{
+ Arc *arc;
+
+ DBG (DFNDEBUG, printf ("[dfn] dfn( ");
+ print_name (parent);
+ printf (")\n"));
+ /*
+ * If we're already numbered, no need to look any further:
+ */
+ if (is_numbered (parent))
+ {
+ return;
+ }
+ /*
+ * If we're already busy, must be a cycle:
+ */
+ if (is_busy (parent))
+ {
+ find_cycle (parent);
+ return;
+ }
+ pre_visit (parent);
+ /*
+ * Recursively visit children:
+ */
+ for (arc = parent->cg.children; arc; arc = arc->next_child)
+ {
+ cg_dfn (arc->child);
+ }
+ post_visit (parent);
+}
diff --git a/gprof/cg_dfn.h b/gprof/cg_dfn.h
new file mode 100644
index 00000000000..4bd3030257c
--- /dev/null
+++ b/gprof/cg_dfn.h
@@ -0,0 +1,17 @@
+#ifndef cg_dfn_h
+#define cg_dfn_h
+
+/*
+ * Flags which mark a symbol as topologically ``busy'' or as
+ * topologically ``not_numbered'':
+ */
+#define DFN_BUSY -1
+#define DFN_NAN 0
+
+/*
+ * Depth-first numbering of a call-graph.
+ */
+
+extern void cg_dfn PARAMS ((Sym * root));
+
+#endif /* cg_dfn_h */
diff --git a/gprof/cg_print.c b/gprof/cg_print.c
new file mode 100644
index 00000000000..e645bc7f82f
--- /dev/null
+++ b/gprof/cg_print.c
@@ -0,0 +1,1276 @@
+#include "libiberty.h"
+#include "cg_arcs.h"
+#include "cg_print.h"
+#include "hist.h"
+#include "utils.h"
+
+/*
+ * Return value of comparison functions used to sort tables:
+ */
+#define LESSTHAN -1
+#define EQUALTO 0
+#define GREATERTHAN 1
+
+static void order_and_dump_functions_by_arcs PARAMS ((Arc **, unsigned long,
+ int, Arc **,
+ unsigned long *));
+/* declarations of automatically generated functions to output blurbs: */
+extern void bsd_callg_blurb PARAMS ((FILE * fp));
+extern void fsf_callg_blurb PARAMS ((FILE * fp));
+
+double print_time = 0.0;
+
+
+static void
+DEFUN_VOID (print_header)
+{
+ if (first_output)
+ {
+ first_output = FALSE;
+ }
+ else
+ {
+ printf ("\f\n");
+ }
+ if (!bsd_style_output)
+ {
+ if (print_descriptions)
+ {
+ printf (_("\t\t Call graph (explanation follows)\n\n"));
+ }
+ else
+ {
+ printf (_("\t\t\tCall graph\n\n"));
+ }
+ }
+ printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
+ (long) hist_scale * sizeof (UNIT));
+ if (print_time > 0.0)
+ {
+ printf (_(" for %.2f%% of %.2f seconds\n\n"),
+ 100.0 / print_time, print_time / hz);
+ }
+ else
+ {
+ printf (_(" no time propagated\n\n"));
+ /*
+ * This doesn't hurt, since all the numerators will be 0.0:
+ */
+ print_time = 1.0;
+ }
+ if (bsd_style_output)
+ {
+ printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
+ "", "", "", "", _("called"), _("total"), _("parents"));
+ printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",
+ _("index"), _("%time"), _("self"), _("descendents"),
+ _("called"), _("self"), _("name"), _("index"));
+ printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
+ "", "", "", "", _("called"), _("total"), _("children"));
+ printf ("\n");
+ }
+ else
+ {
+ printf (_("index %% time self children called name\n"));
+ }
+}
+
+
+/*
+ * Print a cycle header.
+ */
+static void
+DEFUN (print_cycle, (cyc), Sym * cyc)
+{
+ char buf[BUFSIZ];
+
+ sprintf (buf, "[%d]", cyc->cg.index);
+ printf (bsd_style_output
+ ? "%-6.6s %5.1f %7.2f %11.2f %7lu"
+ : "%-6.6s %5.1f %7.2f %7.2f %7lu", buf,
+ 100 * (cyc->cg.prop.self + cyc->cg.prop.child) / print_time,
+ cyc->cg.prop.self / hz, cyc->cg.prop.child / hz, cyc->ncalls);
+ if (cyc->cg.self_calls != 0)
+ {
+ printf ("+%-7lu", cyc->cg.self_calls);
+ }
+ else
+ {
+ printf (" %7.7s", "");
+ }
+ printf (_(" <cycle %d as a whole> [%d]\n"), cyc->cg.cyc.num, cyc->cg.index);
+}
+
+
+/*
+ * Compare LEFT and RIGHT membmer. Major comparison key is
+ * CG.PROP.SELF+CG.PROP.CHILD, secondary key is NCALLS+CG.SELF_CALLS.
+ */
+static int
+DEFUN (cmp_member, (left, right), Sym * left AND Sym * right)
+{
+ double left_time = left->cg.prop.self + left->cg.prop.child;
+ double right_time = right->cg.prop.self + right->cg.prop.child;
+ unsigned long left_calls = left->ncalls + left->cg.self_calls;
+ unsigned long right_calls = right->ncalls + right->cg.self_calls;
+
+ if (left_time > right_time)
+ {
+ return GREATERTHAN;
+ }
+ if (left_time < right_time)
+ {
+ return LESSTHAN;
+ }
+
+ if (left_calls > right_calls)
+ {
+ return GREATERTHAN;
+ }
+ if (left_calls < right_calls)
+ {
+ return LESSTHAN;
+ }
+ return EQUALTO;
+}
+
+
+/*
+ * Sort members of a cycle.
+ */
+static void
+DEFUN (sort_members, (cyc), Sym * cyc)
+{
+ Sym *todo, *doing, *prev;
+ /*
+ * Detach cycle members from cyclehead, and insertion sort them
+ * back on.
+ */
+ todo = cyc->cg.cyc.next;
+ cyc->cg.cyc.next = 0;
+ for (doing = todo; doing && doing->cg.cyc.next; doing = todo)
+ {
+ todo = doing->cg.cyc.next;
+ for (prev = cyc; prev->cg.cyc.next; prev = prev->cg.cyc.next)
+ {
+ if (cmp_member (doing, prev->cg.cyc.next) == GREATERTHAN)
+ {
+ break;
+ }
+ }
+ doing->cg.cyc.next = prev->cg.cyc.next;
+ prev->cg.cyc.next = doing;
+ }
+}
+
+
+/*
+ * Print the members of a cycle.
+ */
+static void
+DEFUN (print_members, (cyc), Sym * cyc)
+{
+ Sym *member;
+
+ sort_members (cyc);
+ for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next)
+ {
+ printf (bsd_style_output
+ ? "%6.6s %5.5s %7.2f %11.2f %7lu"
+ : "%6.6s %5.5s %7.2f %7.2f %7lu",
+ "", "", member->cg.prop.self / hz, member->cg.prop.child / hz,
+ member->ncalls);
+ if (member->cg.self_calls != 0)
+ {
+ printf ("+%-7lu", member->cg.self_calls);
+ }
+ else
+ {
+ printf (" %7.7s", "");
+ }
+ printf (" ");
+ print_name (member);
+ printf ("\n");
+ }
+}
+
+
+/*
+ * Compare two arcs to/from the same child/parent.
+ * - if one arc is a self arc, it's least.
+ * - if one arc is within a cycle, it's less than.
+ * - if both arcs are within a cycle, compare arc counts.
+ * - if neither arc is within a cycle, compare with
+ * time + child_time as major key
+ * arc count as minor key
+ */
+static int
+DEFUN (cmp_arc, (left, right), Arc * left AND Arc * right)
+{
+ Sym *left_parent = left->parent;
+ Sym *left_child = left->child;
+ Sym *right_parent = right->parent;
+ Sym *right_child = right->child;
+ double left_time, right_time;
+
+ DBG (TIMEDEBUG,
+ printf ("[cmp_arc] ");
+ print_name (left_parent);
+ printf (" calls ");
+ print_name (left_child);
+ printf (" %f + %f %lu/%lu\n", left->time, left->child_time,
+ left->count, left_child->ncalls);
+ printf ("[cmp_arc] ");
+ print_name (right_parent);
+ printf (" calls ");
+ print_name (right_child);
+ printf (" %f + %f %lu/%lu\n", right->time, right->child_time,
+ right->count, right_child->ncalls);
+ printf ("\n");
+ );
+ if (left_parent == left_child)
+ {
+ return LESSTHAN; /* left is a self call */
+ }
+ if (right_parent == right_child)
+ {
+ return GREATERTHAN; /* right is a self call */
+ }
+
+ if (left_parent->cg.cyc.num != 0 && left_child->cg.cyc.num != 0
+ && left_parent->cg.cyc.num == left_child->cg.cyc.num)
+ {
+ /* left is a call within a cycle */
+ if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0
+ && right_parent->cg.cyc.num == right_child->cg.cyc.num)
+ {
+ /* right is a call within the cycle, too */
+ if (left->count < right->count)
+ {
+ return LESSTHAN;
+ }
+ if (left->count > right->count)
+ {
+ return GREATERTHAN;
+ }
+ return EQUALTO;
+ }
+ else
+ {
+ /* right isn't a call within the cycle */
+ return LESSTHAN;
+ }
+ }
+ else
+ {
+ /* left isn't a call within a cycle */
+ if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0
+ && right_parent->cg.cyc.num == right_child->cg.cyc.num)
+ {
+ /* right is a call within a cycle */
+ return GREATERTHAN;
+ }
+ else
+ {
+ /* neither is a call within a cycle */
+ left_time = left->time + left->child_time;
+ right_time = right->time + right->child_time;
+ if (left_time < right_time)
+ {
+ return LESSTHAN;
+ }
+ if (left_time > right_time)
+ {
+ return GREATERTHAN;
+ }
+ if (left->count < right->count)
+ {
+ return LESSTHAN;
+ }
+ if (left->count > right->count)
+ {
+ return GREATERTHAN;
+ }
+ return EQUALTO;
+ }
+ }
+}
+
+
+static void
+DEFUN (sort_parents, (child), Sym * child)
+{
+ Arc *arc, *detached, sorted, *prev;
+
+ /*
+ * Unlink parents from child, then insertion sort back on to
+ * sorted's parents.
+ * *arc the arc you have detached and are inserting.
+ * *detached the rest of the arcs to be sorted.
+ * sorted arc list onto which you insertion sort.
+ * *prev arc before the arc you are comparing.
+ */
+ sorted.next_parent = 0;
+ for (arc = child->cg.parents; arc; arc = detached)
+ {
+ detached = arc->next_parent;
+
+ /* consider *arc as disconnected; insert it into sorted: */
+ for (prev = &sorted; prev->next_parent; prev = prev->next_parent)
+ {
+ if (cmp_arc (arc, prev->next_parent) != GREATERTHAN)
+ {
+ break;
+ }
+ }
+ arc->next_parent = prev->next_parent;
+ prev->next_parent = arc;
+ }
+
+ /* reattach sorted arcs to child: */
+ child->cg.parents = sorted.next_parent;
+}
+
+
+static void
+DEFUN (print_parents, (child), Sym * child)
+{
+ Sym *parent;
+ Arc *arc;
+ Sym *cycle_head;
+
+ if (child->cg.cyc.head != 0)
+ {
+ cycle_head = child->cg.cyc.head;
+ }
+ else
+ {
+ cycle_head = child;
+ }
+ if (!child->cg.parents)
+ {
+ printf (bsd_style_output
+ ? _("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n")
+ : _("%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n"),
+ "", "", "", "", "", "");
+ return;
+ }
+ sort_parents (child);
+ for (arc = child->cg.parents; arc; arc = arc->next_parent)
+ {
+ parent = arc->parent;
+ if (child == parent || (child->cg.cyc.num != 0
+ && parent->cg.cyc.num == child->cg.cyc.num))
+ {
+ /* selfcall or call among siblings: */
+ printf (bsd_style_output
+ ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s "
+ : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s ",
+ "", "", "", "",
+ arc->count, "");
+ print_name (parent);
+ printf ("\n");
+ }
+ else
+ {
+ /* regular parent of child: */
+ printf (bsd_style_output
+ ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu "
+ : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu ",
+ "", "",
+ arc->time / hz, arc->child_time / hz,
+ arc->count, cycle_head->ncalls);
+ print_name (parent);
+ printf ("\n");
+ }
+ }
+}
+
+
+static void
+DEFUN (sort_children, (parent), Sym * parent)
+{
+ Arc *arc, *detached, sorted, *prev;
+ /*
+ * Unlink children from parent, then insertion sort back on to
+ * sorted's children.
+ * *arc the arc you have detached and are inserting.
+ * *detached the rest of the arcs to be sorted.
+ * sorted arc list onto which you insertion sort.
+ * *prev arc before the arc you are comparing.
+ */
+ sorted.next_child = 0;
+ for (arc = parent->cg.children; arc; arc = detached)
+ {
+ detached = arc->next_child;
+
+ /* consider *arc as disconnected; insert it into sorted: */
+ for (prev = &sorted; prev->next_child; prev = prev->next_child)
+ {
+ if (cmp_arc (arc, prev->next_child) != LESSTHAN)
+ {
+ break;
+ }
+ }
+ arc->next_child = prev->next_child;
+ prev->next_child = arc;
+ }
+
+ /* reattach sorted children to parent: */
+ parent->cg.children = sorted.next_child;
+}
+
+
+static void
+DEFUN (print_children, (parent), Sym * parent)
+{
+ Sym *child;
+ Arc *arc;
+
+ sort_children (parent);
+ arc = parent->cg.children;
+ for (arc = parent->cg.children; arc; arc = arc->next_child)
+ {
+ child = arc->child;
+ if (child == parent || (child->cg.cyc.num != 0
+ && child->cg.cyc.num == parent->cg.cyc.num))
+ {
+ /* self call or call to sibling: */
+ printf (bsd_style_output
+ ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s "
+ : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s ",
+ "", "", "", "", arc->count, "");
+ print_name (child);
+ printf ("\n");
+ }
+ else
+ {
+ /* regular child of parent: */
+ printf (bsd_style_output
+ ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu "
+ : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu ",
+ "", "",
+ arc->time / hz, arc->child_time / hz,
+ arc->count, child->cg.cyc.head->ncalls);
+ print_name (child);
+ printf ("\n");
+ }
+ }
+}
+
+
+static void
+DEFUN (print_line, (np), Sym * np)
+{
+ char buf[BUFSIZ];
+
+ sprintf (buf, "[%d]", np->cg.index);
+ printf (bsd_style_output
+ ? "%-6.6s %5.1f %7.2f %11.2f"
+ : "%-6.6s %5.1f %7.2f %7.2f", buf,
+ 100 * (np->cg.prop.self + np->cg.prop.child) / print_time,
+ np->cg.prop.self / hz, np->cg.prop.child / hz);
+ if ((np->ncalls + np->cg.self_calls) != 0)
+ {
+ printf (" %7lu", np->ncalls);
+ if (np->cg.self_calls != 0)
+ {
+ printf ("+%-7lu ", np->cg.self_calls);
+ }
+ else
+ {
+ printf (" %7.7s ", "");
+ }
+ }
+ else
+ {
+ printf (" %7.7s %7.7s ", "", "");
+ }
+ print_name (np);
+ printf ("\n");
+}
+
+
+/*
+ * Print dynamic call graph.
+ */
+void
+DEFUN (cg_print, (timesortsym), Sym ** timesortsym)
+{
+ unsigned int index;
+ Sym *parent;
+
+ if (print_descriptions && bsd_style_output)
+ {
+ bsd_callg_blurb (stdout);
+ }
+
+ print_header ();
+
+ for (index = 0; index < symtab.len + num_cycles; ++index)
+ {
+ parent = timesortsym[index];
+ if ((ignore_zeros && parent->ncalls == 0
+ && parent->cg.self_calls == 0 && parent->cg.prop.self == 0
+ && parent->cg.prop.child == 0)
+ || !parent->cg.print_flag
+ || (line_granularity && ! parent->is_func))
+ {
+ continue;
+ }
+ if (!parent->name && parent->cg.cyc.num != 0)
+ {
+ /* cycle header: */
+ print_cycle (parent);
+ print_members (parent);
+ }
+ else
+ {
+ print_parents (parent);
+ print_line (parent);
+ print_children (parent);
+ }
+ if (bsd_style_output)
+ printf ("\n");
+ printf ("-----------------------------------------------\n");
+ if (bsd_style_output)
+ printf ("\n");
+ }
+ free (timesortsym);
+ if (print_descriptions && !bsd_style_output)
+ {
+ fsf_callg_blurb (stdout);
+ }
+}
+
+
+static int
+DEFUN (cmp_name, (left, right), const PTR left AND const PTR right)
+{
+ const Sym **npp1 = (const Sym **) left;
+ const Sym **npp2 = (const Sym **) right;
+
+ return strcmp ((*npp1)->name, (*npp2)->name);
+}
+
+
+void
+DEFUN_VOID (cg_print_index)
+{
+ unsigned int index;
+ unsigned int nnames, todo, i, j;
+ int col, starting_col;
+ Sym **name_sorted_syms, *sym;
+ const char *filename;
+ char buf[20];
+ int column_width = (output_width - 1) / 3; /* don't write in last col! */
+ /*
+ * Now, sort regular function name alphabetically to create an
+ * index:
+ */
+ name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *));
+ for (index = 0, nnames = 0; index < symtab.len; index++)
+ {
+ if (ignore_zeros && symtab.base[index].ncalls == 0
+ && symtab.base[index].hist.time == 0)
+ {
+ continue;
+ }
+ name_sorted_syms[nnames++] = &symtab.base[index];
+ }
+ qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name);
+ for (index = 1, todo = nnames; index <= num_cycles; index++)
+ {
+ name_sorted_syms[todo++] = &cycle_header[index];
+ }
+ printf ("\f\n");
+ printf (_("Index by function name\n\n"));
+ index = (todo + 2) / 3;
+ for (i = 0; i < index; i++)
+ {
+ col = 0;
+ starting_col = 0;
+ for (j = i; j < todo; j += index)
+ {
+ sym = name_sorted_syms[j];
+ if (sym->cg.print_flag)
+ {
+ sprintf (buf, "[%d]", sym->cg.index);
+ }
+ else
+ {
+ sprintf (buf, "(%d)", sym->cg.index);
+ }
+ if (j < nnames)
+ {
+ if (bsd_style_output)
+ {
+ printf ("%6.6s %-19.19s", buf, sym->name);
+ }
+ else
+ {
+ col += strlen (buf);
+ for (; col < starting_col + 5; ++col)
+ {
+ putchar (' ');
+ }
+ printf (" %s ", buf);
+ col += print_name_only (sym);
+ if (!line_granularity && sym->is_static && sym->file)
+ {
+ filename = sym->file->name;
+ if (!print_path)
+ {
+ filename = strrchr (filename, '/');
+ if (filename)
+ {
+ ++filename;
+ }
+ else
+ {
+ filename = sym->file->name;
+ }
+ }
+ printf (" (%s)", filename);
+ col += strlen (filename) + 3;
+ }
+ }
+ }
+ else
+ {
+ if (bsd_style_output)
+ {
+ printf ("%6.6s ", buf);
+ sprintf (buf, _("<cycle %d>"), sym->cg.cyc.num);
+ printf ("%-19.19s", buf);
+ }
+ else
+ {
+ col += strlen (buf);
+ for (; col < starting_col + 5; ++col)
+ putchar (' ');
+ printf (" %s ", buf);
+ sprintf (buf, _("<cycle %d>"), sym->cg.cyc.num);
+ printf ("%s", buf);
+ col += strlen (buf);
+ }
+ }
+ starting_col += column_width;
+ }
+ printf ("\n");
+ }
+ free (name_sorted_syms);
+}
+
+/* Compare two arcs based on their usage counts. We want to sort
+ in descending order. */
+static int
+DEFUN (cmp_arc_count, (left, right), const PTR left AND const PTR right)
+{
+ const Arc **npp1 = (const Arc **) left;
+ const Arc **npp2 = (const Arc **) right;
+
+ if ((*npp1)->count > (*npp2)->count)
+ return -1;
+ else if ((*npp1)->count < (*npp2)->count)
+ return 1;
+ else
+ return 0;
+}
+
+/* Compare two funtions based on their usage counts. We want to sort
+ in descending order. */
+static int
+DEFUN (cmp_fun_nuses, (left, right), const PTR left AND const PTR right)
+{
+ const Sym **npp1 = (const Sym **) left;
+ const Sym **npp2 = (const Sym **) right;
+
+ if ((*npp1)->nuses > (*npp2)->nuses)
+ return -1;
+ else if ((*npp1)->nuses < (*npp2)->nuses)
+ return 1;
+ else
+ return 0;
+}
+
+/* Print a suggested function ordering based on the profiling data.
+
+ We perform 4 major steps when ordering functions:
+
+ * Group unused functions together and place them at the
+ end of the function order.
+
+ * Search the highest use arcs (those which account for 90% of
+ the total arc count) for functions which have several parents.
+
+ Group those with the most call sites together (currently the
+ top 1.25% which have at least five different call sites).
+
+ These are emitted at the start of the function order.
+
+ * Use a greedy placement algorithm to place functions which
+ occur in the top 99% of the arcs in the profile. Some provisions
+ are made to handle high usage arcs where the parent and/or
+ child has already been placed.
+
+ * Run the same greedy placement algorithm on the remaining
+ arcs to place the leftover functions.
+
+
+ The various "magic numbers" should (one day) be tuneable by command
+ line options. They were arrived at by benchmarking a few applications
+ with various values to see which values produced better overall function
+ orderings.
+
+ Of course, profiling errors, machine limitations (PA long calls), and
+ poor cutoff values for the placement algorithm may limit the usefullness
+ of the resulting function order. Improvements would be greatly appreciated.
+
+ Suggestions:
+
+ * Place the functions with many callers near the middle of the
+ list to reduce long calls.
+
+ * Propagate arc usage changes as functions are placed. Ie if
+ func1 and func2 are placed together, arcs to/from those arcs
+ to the same parent/child should be combined, then resort the
+ arcs to choose the next one.
+
+ * Implement some global positioning algorithm to place the
+ chains made by the greedy local positioning algorithm. Probably
+ by examining arcs which haven't been placed yet to tie two
+ chains together.
+
+ * Take a function's size and time into account in the algorithm;
+ size in particular is important on the PA (long calls). Placing
+ many small functions onto their own page may be wise.
+
+ * Use better profiling information; many published algorithms
+ are based on call sequences through time, rather than just
+ arc counts.
+
+ * Prodecure cloning could improve performance when a small number
+ of arcs account for most of the calls to a particular function.
+
+ * Use relocation information to avoid moving unused functions
+ completely out of the code stream; this would avoid severe lossage
+ when the profile data bears little resemblance to actual runs.
+
+ * Propagation of arc usages should also improve .o link line
+ ordering which shares the same arc placement algorithm with
+ the function ordering code (in fact it is a degenerate case
+ of function ordering). */
+
+void
+DEFUN_VOID (cg_print_function_ordering)
+{
+ unsigned long index, used, unused, scratch_index;
+ unsigned long unplaced_arc_count, high_arc_count, scratch_arc_count;
+#ifdef __GNUC__
+ unsigned long long total_arcs, tmp_arcs_count;
+#else
+ unsigned long total_arcs, tmp_arcs_count;
+#endif
+ Sym **unused_syms, **used_syms, **scratch_syms;
+ Arc **unplaced_arcs, **high_arcs, **scratch_arcs;
+
+ index = 0;
+ used = 0;
+ unused = 0;
+ scratch_index = 0;
+ unplaced_arc_count = 0;
+ high_arc_count = 0;
+ scratch_arc_count = 0;
+
+ /* First group all the unused functions together. */
+ unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+ scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+ unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+
+ /* Walk through all the functions; mark those which are never
+ called as placed (we'll emit them as a group later). */
+ for (index = 0, used = 0, unused = 0; index < symtab.len; index++)
+ {
+ if (symtab.base[index].ncalls == 0)
+ {
+ /* Filter out gprof generated names. */
+ if (strcmp (symtab.base[index].name, "<locore>")
+ && strcmp (symtab.base[index].name, "<hicore>"))
+ {
+ unused_syms[unused++] = &symtab.base[index];
+ symtab.base[index].has_been_placed = 1;
+ }
+ }
+ else
+ {
+ used_syms[used++] = &symtab.base[index];
+ symtab.base[index].has_been_placed = 0;
+ symtab.base[index].next = 0;
+ symtab.base[index].prev = 0;
+ symtab.base[index].nuses = 0;
+ }
+ }
+
+ /* Sort the arcs from most used to least used. */
+ qsort (arcs, numarcs, sizeof (Arc *), cmp_arc_count);
+
+ /* Compute the total arc count. Also mark arcs as unplaced.
+
+ Note we don't compensate for overflow if that happens!
+ Overflow is much less likely when this file is compiled
+ with GCC as it can double-wide integers via long long. */
+ total_arcs = 0;
+ for (index = 0; index < numarcs; index++)
+ {
+ total_arcs += arcs[index]->count;
+ arcs[index]->has_been_placed = 0;
+ }
+
+ /* We want to pull out those functions which are referenced
+ by many highly used arcs and emit them as a group. This
+ could probably use some tuning. */
+ tmp_arcs_count = 0;
+ for (index = 0; index < numarcs; index++)
+ {
+ tmp_arcs_count += arcs[index]->count;
+
+ /* Count how many times each parent and child are used up
+ to our threshhold of arcs (90%). */
+ if ((double)tmp_arcs_count / (double)total_arcs > 0.90)
+ break;
+
+ arcs[index]->child->nuses++;
+ }
+
+ /* Now sort a temporary symbol table based on the number of
+ times each function was used in the highest used arcs. */
+ memcpy (scratch_syms, used_syms, used * sizeof (Sym *));
+ qsort (scratch_syms, used, sizeof (Sym *), cmp_fun_nuses);
+
+ /* Now pick out those symbols we're going to emit as
+ a group. We take up to 1.25% of the used symbols. */
+ for (index = 0; index < used / 80; index++)
+ {
+ Sym *sym = scratch_syms[index];
+ Arc *arc;
+
+ /* If we hit symbols that aren't used from many call sites,
+ then we can quit. We choose five as the low limit for
+ no particular reason. */
+ if (sym->nuses == 5)
+ break;
+
+ /* We're going to need the arcs between these functions.
+ Unfortunately, we don't know all these functions
+ until we're done. So we keep track of all the arcs
+ to the functions we care about, then prune out those
+ which are uninteresting.
+
+ An interesting variation would be to quit when we found
+ multi-call site functions which account for some percentage
+ of the arcs. */
+
+ arc = sym->cg.children;
+ while (arc)
+ {
+ if (arc->parent != arc->child)
+ scratch_arcs[scratch_arc_count++] = arc;
+ arc->has_been_placed = 1;
+ arc = arc->next_child;
+ }
+
+ arc = sym->cg.parents;
+ while (arc)
+ {
+ if (arc->parent != arc->child)
+ scratch_arcs[scratch_arc_count++] = arc;
+ arc->has_been_placed = 1;
+ arc = arc->next_parent;
+ }
+
+ /* Keep track of how many symbols we're going to place. */
+ scratch_index = index;
+
+ /* A lie, but it makes identifying these functions easier
+ later. */
+ sym->has_been_placed = 1;
+ }
+
+ /* Now walk through the temporary arcs and copy those we care about
+ into the high arcs array. */
+ for (index = 0; index < scratch_arc_count; index++)
+ {
+ Arc *arc = scratch_arcs[index];
+
+ /* If this arc refers to highly used functions, then
+ then we want to keep it. */
+ if (arc->child->has_been_placed
+ && arc->parent->has_been_placed)
+ {
+ high_arcs[high_arc_count++] = scratch_arcs[index];
+
+ /* We need to turn of has_been_placed since we're going to
+ use the main arc placement algorithm on these arcs. */
+ arc->child->has_been_placed = 0;
+ arc->parent->has_been_placed = 0;
+ }
+ }
+
+ /* Dump the multi-site high usage functions which are not going
+ to be ordered by the main ordering algorithm. */
+ for (index = 0; index < scratch_index; index++)
+ {
+ if (scratch_syms[index]->has_been_placed)
+ printf ("%s\n", scratch_syms[index]->name);
+ }
+
+ /* Now we can order the multi-site high use functions based on the
+ arcs between them. */
+ qsort (high_arcs, high_arc_count, sizeof (Arc *), cmp_arc_count);
+ order_and_dump_functions_by_arcs (high_arcs, high_arc_count, 1,
+ unplaced_arcs, &unplaced_arc_count);
+
+ /* Order and dump the high use functions left, these typically
+ have only a few call sites. */
+ order_and_dump_functions_by_arcs (arcs, numarcs, 0,
+ unplaced_arcs, &unplaced_arc_count);
+
+ /* Now place the rarely used functions. */
+ order_and_dump_functions_by_arcs (unplaced_arcs, unplaced_arc_count, 1,
+ scratch_arcs, &scratch_arc_count);
+
+ /* Output any functions not emitted by the order_and_dump calls. */
+ for (index = 0; index < used; index++)
+ if (used_syms[index]->has_been_placed == 0)
+ printf("%s\n", used_syms[index]->name);
+
+ /* Output the unused functions. */
+ for (index = 0; index < unused; index++)
+ printf("%s\n", unused_syms[index]->name);
+
+ unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+ scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+ unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+
+ free (unused_syms);
+ free (used_syms);
+ free (scratch_syms);
+ free (high_arcs);
+ free (scratch_arcs);
+ free (unplaced_arcs);
+}
+
+/* Place functions based on the arcs in ARCS with NUMARCS entries;
+ place unused arcs into UNPLACED_ARCS/UNPLACED_ARC_COUNT.
+
+ If ALL is nonzero, then place all functions referenced by ARCS,
+ else only place those referenced in the top 99% of the arcs in ARCS. */
+
+#define MOST 0.99
+static void
+order_and_dump_functions_by_arcs (arcs, numarcs, all,
+ unplaced_arcs, unplaced_arc_count)
+ Arc **arcs;
+ unsigned long numarcs;
+ int all;
+ Arc **unplaced_arcs;
+ unsigned long *unplaced_arc_count;
+{
+#ifdef __GNUC__
+ unsigned long long tmp_arcs, total_arcs;
+#else
+ unsigned long tmp_arcs, total_arcs;
+#endif
+ unsigned int index;
+
+ /* If needed, compute the total arc count.
+
+ Note we don't compensate for overflow if that happens! */
+ if (! all)
+ {
+ total_arcs = 0;
+ for (index = 0; index < numarcs; index++)
+ total_arcs += arcs[index]->count;
+ }
+ else
+ total_arcs = 0;
+
+ tmp_arcs = 0;
+ for (index = 0; index < numarcs; index++)
+ {
+ Sym *sym1, *sym2;
+ Sym *child, *parent;
+
+ tmp_arcs += arcs[index]->count;
+
+ /* Ignore this arc if it's already been placed. */
+ if (arcs[index]->has_been_placed)
+ continue;
+
+ child = arcs[index]->child;
+ parent = arcs[index]->parent;
+
+ /* If we're not using all arcs, and this is a rarely used
+ arc, then put it on the unplaced_arc list. Similarly
+ if both the parent and child of this arc have been placed. */
+ if ((! all && (double)tmp_arcs / (double)total_arcs > MOST)
+ || child->has_been_placed || parent->has_been_placed)
+ {
+ unplaced_arcs[(*unplaced_arc_count)++] = arcs[index];
+ continue;
+ }
+
+ /* If all slots in the parent and child are full, then there isn't
+ anything we can do right now. We'll place this arc on the
+ unplaced arc list in the hope that a global positioning
+ algorithm can use it to place function chains. */
+ if (parent->next && parent->prev && child->next && child->prev)
+ {
+ unplaced_arcs[(*unplaced_arc_count)++] = arcs[index];
+ continue;
+ }
+
+ /* If the parent is unattached, then find the closest
+ place to attach it onto child's chain. Similarly
+ for the opposite case. */
+ if (!parent->next && !parent->prev)
+ {
+ int next_count = 0;
+ int prev_count = 0;
+ Sym *prev = child;
+ Sym *next = child;
+
+ /* Walk to the beginning and end of the child's chain. */
+ while (next->next)
+ {
+ next = next->next;
+ next_count++;
+ }
+
+ while (prev->prev)
+ {
+ prev = prev->prev;
+ prev_count++;
+ }
+
+ /* Choose the closest. */
+ child = next_count < prev_count ? next : prev;
+ }
+ else if (! child->next && !child->prev)
+ {
+ int next_count = 0;
+ int prev_count = 0;
+ Sym *prev = parent;
+ Sym *next = parent;
+
+ while (next->next)
+ {
+ next = next->next;
+ next_count++;
+ }
+
+ while (prev->prev)
+ {
+ prev = prev->prev;
+ prev_count++;
+ }
+
+ parent = prev_count < next_count ? prev : next;
+ }
+ else
+ {
+ /* Couldn't find anywhere to attach the functions,
+ put the arc on the unplaced arc list. */
+ unplaced_arcs[(*unplaced_arc_count)++] = arcs[index];
+ continue;
+ }
+
+ /* Make sure we don't tie two ends together. */
+ sym1 = parent;
+ if (sym1->next)
+ while (sym1->next)
+ sym1 = sym1->next;
+ else
+ while (sym1->prev)
+ sym1 = sym1->prev;
+
+ sym2 = child;
+ if (sym2->next)
+ while (sym2->next)
+ sym2 = sym2->next;
+ else
+ while (sym2->prev)
+ sym2 = sym2->prev;
+
+ if (sym1 == child
+ && sym2 == parent)
+ {
+ /* This would tie two ends together. */
+ unplaced_arcs[(*unplaced_arc_count)++] = arcs[index];
+ continue;
+ }
+
+ if (parent->next)
+ {
+ /* Must attach to the parent's prev field. */
+ if (! child->next)
+ {
+ /* parent-prev and child-next */
+ parent->prev = child;
+ child->next = parent;
+ arcs[index]->has_been_placed = 1;
+ }
+ }
+ else if (parent->prev)
+ {
+ /* Must attach to the parent's next field. */
+ if (! child->prev)
+ {
+ /* parent-next and child-prev */
+ parent->next = child;
+ child->prev = parent;
+ arcs[index]->has_been_placed = 1;
+ }
+ }
+ else
+ {
+ /* Can attach to either field in the parent, depends
+ on where we've got space in the child. */
+ if (child->prev)
+ {
+ /* parent-prev and child-next */
+ parent->prev = child;
+ child->next = parent;
+ arcs[index]->has_been_placed = 1;
+ }
+ else
+ {
+ /* parent-next and child-prev */
+ parent->next = child;
+ child->prev = parent;
+ arcs[index]->has_been_placed = 1;
+ }
+ }
+ }
+
+ /* Dump the chains of functions we've made. */
+ for (index = 0; index < numarcs; index++)
+ {
+ Sym *sym;
+ if (arcs[index]->parent->has_been_placed
+ || arcs[index]->child->has_been_placed)
+ continue;
+
+ sym = arcs[index]->parent;
+
+ /* If this symbol isn't attached to any other
+ symbols, then we've got a rarely used arc.
+
+ Skip it for now, we'll deal with them later. */
+ if (sym->next == NULL
+ && sym->prev == NULL)
+ continue;
+
+ /* Get to the start of this chain. */
+ while (sym->prev)
+ sym = sym->prev;
+
+ while (sym)
+ {
+ /* Mark it as placed. */
+ sym->has_been_placed = 1;
+ printf ("%s\n", sym->name);
+ sym = sym->next;
+ }
+ }
+
+ /* If we want to place all the arcs, then output those which weren't
+ placed by the main algorithm. */
+ if (all)
+ for (index = 0; index < numarcs; index++)
+ {
+ Sym *sym;
+ if (arcs[index]->parent->has_been_placed
+ || arcs[index]->child->has_been_placed)
+ continue;
+
+ sym = arcs[index]->parent;
+
+ sym->has_been_placed = 1;
+ printf ("%s\n", sym->name);
+ }
+}
+
+/* Print a suggested .o ordering for files on a link line based
+ on profiling information. This uses the function placement
+ code for the bulk of its work. */
+
+struct function_map {
+ char *function_name;
+ char *file_name;
+};
+
+void
+DEFUN_VOID (cg_print_file_ordering)
+{
+ unsigned long scratch_arc_count, index;
+ Arc **scratch_arcs;
+ extern struct function_map *symbol_map;
+ extern unsigned int symbol_map_count;
+ char *last;
+
+ scratch_arc_count = 0;
+
+ scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
+ for (index = 0; index < numarcs; index++)
+ {
+ if (! arcs[index]->parent->mapped
+ || ! arcs[index]->child->mapped)
+ arcs[index]->has_been_placed = 1;
+ }
+
+ order_and_dump_functions_by_arcs (arcs, numarcs, 0,
+ scratch_arcs, &scratch_arc_count);
+
+ /* Output .o's not handled by the main placement algorithm. */
+ for (index = 0; index < symtab.len; index++)
+ {
+ if (symtab.base[index].mapped
+ && ! symtab.base[index].has_been_placed)
+ printf ("%s\n", symtab.base[index].name);
+ }
+
+ /* Now output any .o's that didn't have any text symbols. */
+ last = NULL;
+ for (index = 0; index < symbol_map_count; index++)
+ {
+ unsigned int index2;
+
+ /* Don't bother searching if this symbol is the
+ same as the previous one. */
+ if (last && !strcmp (last, symbol_map[index].file_name))
+ continue;
+
+ for (index2 = 0; index2 < symtab.len; index2++)
+ {
+ if (! symtab.base[index2].mapped)
+ continue;
+
+ if (!strcmp (symtab.base[index2].name, symbol_map[index].file_name))
+ break;
+ }
+
+ /* If we didn't find it in the symbol table, then it must be a .o
+ with no text symbols. Output it last. */
+ if (index2 == symtab.len)
+ printf ("%s\n", symbol_map[index].file_name);
+ last = symbol_map[index].file_name;
+ }
+}
diff --git a/gprof/cg_print.h b/gprof/cg_print.h
new file mode 100644
index 00000000000..782c4aa04c2
--- /dev/null
+++ b/gprof/cg_print.h
@@ -0,0 +1,14 @@
+#ifndef cg_print_h
+#define cg_print_h
+
+#include "gprof.h"
+#include "symtab.h"
+
+extern double print_time; /* total of time being printed */
+
+extern void cg_print PARAMS ((Sym ** cg));
+extern void cg_print_index PARAMS ((void));
+extern void cg_print_file_ordering PARAMS ((void));
+extern void cg_print_function_ordering PARAMS ((void));
+
+#endif /* cg_print_h */
diff --git a/gprof/configure b/gprof/configure
new file mode 100755
index 00000000000..5ff5137eba8
--- /dev/null
+++ b/gprof/configure
@@ -0,0 +1,4403 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock force libtool not to do file locking"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=gprof.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:590: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:611: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:629: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:664: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:717: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:774: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=gprof
+
+VERSION=2.9.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:820: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:833: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:846: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:859: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:872: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:958: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:988: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1018: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1069: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1101: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1112 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1143: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1148: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1176: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1219: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1243: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1246: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1282: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1298: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:1336: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* \($ac_symcode\) *\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if { (eval echo configure:1399: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if { (eval echo configure:1403: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:1455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+echo "$ac_t""$ac_result" 1>&6
+
+echo $ac_n "checking for _ prefix in compiled symbols""... $ac_c" 1>&6
+echo "configure:1501: checking for _ prefix in compiled symbols" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_symbol_underscore'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if { (eval echo configure:1510: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { (eval echo configure:1513: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -rf conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_sys_symbol_underscore" 1>&6
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1539: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1581 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1582: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1603: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1608 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1638: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1670: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ DLLTOOL="false"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1705: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1737: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ AS="false"
+fi
+fi
+
+
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ need_locks=$enableval
+else
+ need_locks=yes
+fi
+
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1875: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1905: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1956: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1988: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1999 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2030: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2035: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2044: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2063: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:2106: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:2160: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+
+ALL_LINGUAS=
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2183: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2198 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2215 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2232 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2263: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2268 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2276: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2293 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2311 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2332 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2367: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2372 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2421: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2442: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 2449 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2456: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2482: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2487 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2515: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2520 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:2550: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2555 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:2562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:2583: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2588 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:2616: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2648: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2653 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2678: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2683 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2706: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2733: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2741 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2785: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2790 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2795: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2824: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2829 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:2877: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2885 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:3025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3053: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3058 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3063: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3093: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3098 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3150: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3155 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:3212: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3217 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:3224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:3245: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:3265: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:3284: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3289 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3294: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:3311: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3316 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:3339: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3347 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:3358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:3374: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3379 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3386: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3414: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3448: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3453 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3503: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3539: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 3571 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:3579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3611: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3645: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3681: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:3771: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:3799: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3804 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3809: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:3872: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:3895: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3900 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:3911: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:3928: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3933 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:3940: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:3959: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:3969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile po/Makefile.in:po/Make-in gconfig.h:gconfig.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@USE_SYMBOL_UNDERSCORE@%$USE_SYMBOL_UNDERSCORE%g
+s%@LN_S@%$LN_S%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile po/Makefile.in:po/Make-in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="gconfig.h:gconfig.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/gprof/configure.bat b/gprof/configure.bat
new file mode 100644
index 00000000000..22ef37eff88
--- /dev/null
+++ b/gprof/configure.bat
@@ -0,0 +1,18 @@
+@echo off
+echo Configuring gprof for go32
+rem This batch file assumes a unix-type "sed" program
+
+echo # Makefile generated by "configure.bat"> Makefile
+
+if exist config.sed del config.sed
+
+echo "/^###$/ i\ ">>config.sed
+echo "MY_MACHINE=i386\ ">>config.sed
+echo "CC=gcc ">>config.sed
+
+echo # >> config.sed
+
+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
+sed -f config2.sed Makefile.in >> Makefile
+del config.sed
+del config2.sed
diff --git a/gprof/configure.in b/gprof/configure.in
new file mode 100644
index 00000000000..b50b55d5fd0
--- /dev/null
+++ b/gprof/configure.in
@@ -0,0 +1,29 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.13)
+AC_INIT(gprof.c)
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE(gprof, 2.9.4)
+
+AM_PROG_LIBTOOL
+
+dnl For simplicity, we use the BFD configuration file for most
+dnl things. However, we also need our own configuration file for
+dnl the automake PACKAGE and VERSION macros. We don't name it
+dnl config.h, to avoid any possible confusion with the bfd config.h.
+AM_CONFIG_HEADER(gconfig.h:gconfig.in)
+
+AC_PROG_CC
+AC_PROG_INSTALL
+
+AC_ISC_POSIX
+
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+AC_OUTPUT(Makefile po/Makefile.in:po/Make-in,
+[sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile])
diff --git a/gprof/corefile.c b/gprof/corefile.c
new file mode 100644
index 00000000000..a6e6f835d27
--- /dev/null
+++ b/gprof/corefile.c
@@ -0,0 +1,762 @@
+#include "libiberty.h"
+#include "gprof.h"
+#include "corefile.h"
+#include "symtab.h"
+
+bfd *core_bfd;
+int core_num_syms;
+asymbol **core_syms;
+asection *core_text_sect;
+PTR core_text_space;
+
+int min_insn_size;
+int offset_to_code;
+
+/* For mapping symbols to specific .o files during file ordering. */
+struct function_map {
+ char *function_name;
+ char *file_name;
+};
+
+struct function_map *symbol_map;
+unsigned int symbol_map_count;
+
+extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+
+static void
+DEFUN (read_function_mappings, (filename), const char *filename)
+{
+ FILE *file = fopen (filename, "r");
+ char dummy[1024];
+ int count = 0;
+
+ if (!file)
+ {
+ fprintf (stderr, _("%s: could not open %s.\n"), whoami, filename);
+ done (1);
+ }
+
+ /* First parse the mapping file so we know how big we need to
+ make our tables. We also do some sanity checks at this
+ time. */
+ while (!feof (file))
+ {
+ int matches;
+
+ matches = fscanf (file, "%[^\n:]", dummy);
+ if (!matches)
+ {
+ fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
+ whoami, filename);
+ done (1);
+ }
+
+ /* Just skip messages about files with no symbols. */
+ if (!strncmp (dummy, "No symbols in ", 14))
+ {
+ fscanf (file, "\n");
+ continue;
+ }
+
+ /* Don't care what else is on this line at this point. */
+ fscanf (file, "%[^\n]\n", dummy);
+ count++;
+ }
+
+ /* Now we know how big we need to make our table. */
+ symbol_map = ((struct function_map *)
+ xmalloc (count * sizeof (struct function_map)));
+
+ /* Rewind the input file so we can read it again. */
+ rewind (file);
+
+ /* Read each entry and put it into the table. */
+ count = 0;
+ while (!feof (file))
+ {
+ int matches;
+ char *tmp;
+
+ matches = fscanf (file, "%[^\n:]", dummy);
+ if (!matches)
+ {
+ fprintf (stderr, _("%s: unable to parse mapping file %s.\n"),
+ whoami, filename);
+ done (1);
+ }
+
+ /* Just skip messages about files with no symbols. */
+ if (!strncmp (dummy, "No symbols in ", 14))
+ {
+ fscanf (file, "\n");
+ continue;
+ }
+
+ /* dummy has the filename, go ahead and copy it. */
+ symbol_map[count].file_name = xmalloc (strlen (dummy) + 1);
+ strcpy (symbol_map[count].file_name, dummy);
+
+ /* Now we need the function name. */
+ fscanf (file, "%[^\n]\n", dummy);
+ tmp = strrchr (dummy, ' ') + 1;
+ symbol_map[count].function_name = xmalloc (strlen (tmp) + 1);
+ strcpy (symbol_map[count].function_name, tmp);
+ count++;
+ }
+
+ /* Record the size of the map table for future reference. */
+ symbol_map_count = count;
+}
+
+void
+DEFUN (core_init, (a_out_name), const char *a_out_name)
+{
+ core_bfd = bfd_openr (a_out_name, 0);
+
+ if (!core_bfd)
+ {
+ perror (a_out_name);
+ done (1);
+ }
+
+ if (!bfd_check_format (core_bfd, bfd_object))
+ {
+ fprintf (stderr, _("%s: %s: not in a.out format\n"), whoami, a_out_name);
+ done (1);
+ }
+
+ /* get core's text section: */
+ core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
+ if (!core_text_sect)
+ {
+ core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
+ if (!core_text_sect)
+ {
+ fprintf (stderr, _("%s: can't find .text section in %s\n"),
+ whoami, a_out_name);
+ done (1);
+ }
+ }
+
+ /* read core's symbol table: */
+
+ /* this will probably give us more than we need, but that's ok: */
+ core_num_syms = bfd_get_symtab_upper_bound (core_bfd);
+ if (core_num_syms < 0)
+ {
+ fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
+ bfd_errmsg (bfd_get_error ()));
+ done (1);
+ }
+
+ core_syms = (asymbol **) xmalloc (core_num_syms);
+ core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);
+ if (core_num_syms < 0)
+ {
+ fprintf (stderr, "%s: %s: %s\n", whoami, a_out_name,
+ bfd_errmsg (bfd_get_error ()));
+ done (1);
+ }
+
+ min_insn_size = 1;
+ offset_to_code = 0;
+
+ switch (bfd_get_arch (core_bfd))
+ {
+ case bfd_arch_vax:
+ case bfd_arch_tahoe:
+ offset_to_code = 2;
+ break;
+
+ case bfd_arch_alpha:
+ min_insn_size = 4;
+ break;
+
+ default:
+ break;
+ }
+
+ if (function_mapping_file)
+ read_function_mappings (function_mapping_file);
+}
+
+
+/*
+ * Read in the text space of an a.out file
+ */
+void
+DEFUN (core_get_text_space, (core_bfd), bfd * core_bfd)
+{
+ core_text_space = (PTR) malloc (core_text_sect->_raw_size);
+
+ if (!core_text_space)
+ {
+ fprintf (stderr, _("%s: ran out room for %ld bytes of text space\n"),
+ whoami, core_text_sect->_raw_size);
+ done (1);
+ }
+ if (!bfd_get_section_contents (core_bfd, core_text_sect, core_text_space,
+ 0, core_text_sect->_raw_size))
+ {
+ bfd_perror ("bfd_get_section_contents");
+ free (core_text_space);
+ core_text_space = 0;
+ }
+ if (!core_text_space)
+ {
+ fprintf (stderr, _("%s: can't do -c\n"), whoami);
+ }
+}
+
+
+void
+DEFUN (find_call, (parent, p_lowpc, p_highpc),
+ Sym * parent AND bfd_vma p_lowpc AND bfd_vma p_highpc)
+{
+ switch (bfd_get_arch (core_bfd))
+ {
+ case bfd_arch_i386:
+ i386_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_alpha:
+ alpha_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_vax:
+ vax_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_sparc:
+ sparc_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_tahoe:
+ tahoe_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ default:
+ fprintf (stderr, _("%s: -c not supported on architecture %s\n"),
+ whoami, bfd_printable_name(core_bfd));
+
+ /* Don't give the error more than once. */
+ ignore_direct_calls = FALSE;
+ }
+}
+
+/*
+ * Return class of symbol SYM. The returned class can be any of:
+ * 0 -> symbol is not interesting to us
+ * 'T' -> symbol is a global name
+ * 't' -> symbol is a local (static) name
+ */
+static int
+DEFUN (core_sym_class, (sym), asymbol * sym)
+{
+ symbol_info syminfo;
+ const char *name;
+ char sym_prefix;
+ int i;
+
+ if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
+ {
+ return 0;
+ }
+
+ /*
+ * Must be a text symbol, and static text symbols don't qualify if
+ * ignore_static_funcs set.
+ */
+ if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
+ {
+ DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
+ sym->name));
+ return 0;
+ }
+
+ bfd_get_symbol_info (core_bfd, sym, &syminfo);
+ i = syminfo.type;
+
+ if (i == 'T')
+ {
+ return i; /* it's a global symbol */
+ }
+
+ if (i == 'W')
+ {
+ /* Treat weak symbols as text symbols. FIXME: a weak symbol may
+ also be a data symbol. */
+ return 'T';
+ }
+
+ if (i != 't')
+ {
+ /* not a static text symbol */
+ DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
+ sym->name, i));
+ return 0;
+ }
+
+ /* do some more filtering on static function-names: */
+
+ if (ignore_static_funcs)
+ {
+ return 0;
+ }
+ /*
+ * Can't zero-length name or funny characters in name, where
+ * `funny' includes: `.' (.o file names) and `$' (Pascal labels).
+ */
+ if (!sym->name || sym->name[0] == '\0')
+ {
+ return 0;
+ }
+
+ for (name = sym->name; *name; ++name)
+ {
+ if (*name == '.' || *name == '$')
+ {
+ return 0;
+ }
+ }
+ /*
+ * On systems where the C compiler adds an underscore to all
+ * names, static names without underscores seem usually to be
+ * labels in hand written assembler in the library. We don't want
+ * these names. This is certainly necessary on a Sparc running
+ * SunOS 4.1 (try profiling a program that does a lot of
+ * division). I don't know whether it has harmful side effects on
+ * other systems. Perhaps it should be made configurable.
+ */
+ sym_prefix = bfd_get_symbol_leading_char (core_bfd);
+ if ((sym_prefix && sym_prefix != sym->name[0])
+ /*
+ * GCC may add special symbols to help gdb figure out the file
+ * language. We want to ignore these, since sometimes they mask
+ * the real function. (dj@ctron)
+ */
+ || !strncmp (sym->name, "__gnu_compiled", 14)
+ || !strncmp (sym->name, "___gnu_compiled", 15))
+ {
+ return 0;
+ }
+
+ /* If the object file supports marking of function symbols, then we can
+ zap anything that doesn't have BSF_FUNCTION set. */
+ if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
+ return 0;
+
+ return 't'; /* it's a static text symbol */
+}
+
+
+/*
+ * Get whatever source info we can get regarding address ADDR:
+ */
+static bool
+DEFUN (get_src_info, (addr, filename, name, line_num),
+ bfd_vma addr AND const char **filename AND const char **name
+ AND int *line_num)
+{
+ const char *fname = 0, *func_name = 0;
+ int l = 0;
+
+ if (bfd_find_nearest_line (core_bfd, core_text_sect, core_syms,
+ addr - core_text_sect->vma,
+ &fname, &func_name, (unsigned int *) &l)
+ && fname && func_name && l)
+ {
+ DBG (AOUTDEBUG, printf ("[get_src_info] 0x%lx -> %s:%d (%s)\n",
+ addr, fname, l, func_name));
+ *filename = fname;
+ *name = func_name;
+ *line_num = l;
+ return TRUE;
+ }
+ else
+ {
+ DBG (AOUTDEBUG, printf ("[get_src_info] no info for 0x%lx (%s:%d,%s)\n",
+ (long) addr, fname ? fname : "<unknown>", l,
+ func_name ? func_name : "<unknown>"));
+ return FALSE;
+ }
+}
+
+
+/*
+ * Read in symbol table from core. One symbol per function is
+ * entered.
+ */
+void
+DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
+{
+ bfd_vma min_vma = ~0, max_vma = 0;
+ int class;
+ long i, found, skip;
+ unsigned int j;
+
+ /* pass 1 - determine upper bound on number of function names: */
+ symtab.len = 0;
+ for (i = 0; i < core_num_syms; ++i)
+ {
+ if (!core_sym_class (core_syms[i]))
+ {
+ continue;
+ }
+
+ /* This should be replaced with a binary search or hashed
+ search. Gross.
+
+ Don't create a symtab entry for a function that has
+ a mapping to a file, unless it's the first function
+ in the file. */
+ skip = 0;
+ for (j = 0; j < symbol_map_count; j++)
+ if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
+ {
+ if (j > 0 && ! strcmp (symbol_map [j].file_name,
+ symbol_map [j - 1].file_name))
+ skip = 1;
+ break;
+ }
+ if (!skip)
+ ++symtab.len;
+ }
+
+ if (symtab.len == 0)
+ {
+ fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
+ done (1);
+ }
+
+ /* the "+ 2" is for the sentinels: */
+ symtab.base = (Sym *) xmalloc ((symtab.len + 2) * sizeof (Sym));
+
+ /* pass 2 - create symbols: */
+
+ symtab.limit = symtab.base;
+ for (i = 0; i < core_num_syms; ++i)
+ {
+ class = core_sym_class (core_syms[i]);
+ if (!class)
+ {
+ DBG (AOUTDEBUG,
+ printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
+ core_syms[i]->value, core_syms[i]->name));
+ continue;
+ }
+ /* This should be replaced with a binary search or hashed
+ search. Gross. */
+
+ skip = 0;
+ found = 0;
+ for (j = 0; j < symbol_map_count; j++)
+ if (!strcmp (core_syms[i]->name, symbol_map[j].function_name))
+ {
+ if (j > 0 && ! strcmp (symbol_map [j].file_name,
+ symbol_map [j - 1].file_name))
+ skip = 1;
+ else
+ found = j;
+ break;
+ }
+
+ if (skip)
+ continue;
+
+ sym_init (symtab.limit);
+
+ /* symbol offsets are always section-relative: */
+
+ symtab.limit->addr = core_syms[i]->value + core_syms[i]->section->vma;
+ if (symbol_map_count
+ && !strcmp (core_syms[i]->name, symbol_map[found].function_name))
+ {
+ symtab.limit->name = symbol_map[found].file_name;
+ symtab.limit->mapped = 1;
+ }
+ else
+ {
+ symtab.limit->name = core_syms[i]->name;
+ symtab.limit->mapped = 0;
+ }
+
+ /* Lookup filename and line number, if we can */
+
+ {
+ const char *filename, *func_name;
+
+ if (get_src_info (symtab.limit->addr, &filename, &func_name,
+ &symtab.limit->line_num))
+ {
+ symtab.limit->file = source_file_lookup_path (filename);
+
+ /* FIXME: Checking __osf__ here does not work with a cross
+ gprof. */
+#ifdef __osf__
+ /*
+ * Suppress symbols that are not function names. This is
+ * useful to suppress code-labels and aliases.
+ *
+ * This is known to be useful under DEC's OSF/1. Under SunOS 4.x,
+ * labels do not appear in the symbol table info, so this isn't
+ * necessary.
+ */
+
+ if (strcmp (symtab.limit->name, func_name) != 0)
+ {
+ /*
+ * The symbol's address maps to a different name, so
+ * it can't be a function-entry point. This happens
+ * for labels, for example.
+ */
+ DBG (AOUTDEBUG,
+ printf ("[core_create_function_syms: rej %s (maps to %s)\n",
+ symtab.limit->name, func_name));
+ continue;
+ }
+#endif
+ }
+ }
+
+ symtab.limit->is_func = TRUE;
+ symtab.limit->is_bb_head = TRUE;
+ if (class == 't')
+ {
+ symtab.limit->is_static = TRUE;
+ }
+
+ min_vma = MIN (symtab.limit->addr, min_vma);
+ max_vma = MAX (symtab.limit->addr, max_vma);
+
+ /*
+ * If we see "main" without an initial '_', we assume names
+ * are *not* prefixed by '_'.
+ */
+ if (symtab.limit->name[0] == 'm' && discard_underscores
+ && strcmp (symtab.limit->name, "main") == 0)
+ {
+ discard_underscores = 0;
+ }
+
+ DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
+ (long) (symtab.limit - symtab.base),
+ symtab.limit->name, symtab.limit->addr));
+ ++symtab.limit;
+ }
+
+ /* create sentinels: */
+
+ sym_init (symtab.limit);
+ symtab.limit->name = "<locore>";
+ symtab.limit->addr = 0;
+ symtab.limit->end_addr = min_vma - 1;
+ ++symtab.limit;
+
+ sym_init (symtab.limit);
+ symtab.limit->name = "<hicore>";
+ symtab.limit->addr = max_vma + 1;
+ symtab.limit->end_addr = ~0;
+ ++symtab.limit;
+
+ symtab.len = symtab.limit - symtab.base;
+ symtab_finalize (&symtab);
+}
+
+
+/*
+ * Read in symbol table from core. One symbol per line of source code
+ * is entered.
+ */
+void
+DEFUN (core_create_line_syms, (core_bfd), bfd * core_bfd)
+{
+ char *prev_name, *prev_filename;
+ int prev_name_len, prev_filename_len;
+ bfd_vma vma, min_vma = ~0, max_vma = 0;
+ bfd_vma offset;
+ Sym *prev, dummy, *sentinel, *sym;
+ const char *filename;
+ int prev_line_num;
+ Sym_Table ltab;
+ /*
+ * Create symbols for functions as usual. This is necessary in
+ * cases where parts of a program were not compiled with -g. For
+ * those parts we still want to get info at the function level:
+ */
+ core_create_function_syms (core_bfd);
+
+ /* pass 1 - counter number of symbols: */
+
+ /*
+ * To find all line information, walk through all possible
+ * text-space addresses (one by one!) and get the debugging
+ * info for each address. When the debugging info changes,
+ * it is time to create a new symbol.
+ *
+ * Of course, this is rather slow and it would be better if
+ * bfd would provide an iterator for enumerating all line infos
+ */
+ prev_name_len = PATH_MAX;
+ prev_filename_len = PATH_MAX;
+ prev_name = xmalloc (prev_name_len);
+ prev_filename = xmalloc (prev_filename_len);
+ ltab.len = 0;
+ prev_line_num = 0;
+ for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
+ {
+ int len;
+
+ vma = core_text_sect->vma + offset;
+ if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
+ || (prev_line_num == dummy.line_num
+ && prev_name != NULL
+ && strcmp (prev_name, dummy.name) == 0
+ && strcmp (prev_filename, filename) == 0))
+ {
+ continue;
+ }
+
+ ++ltab.len;
+ prev_line_num = dummy.line_num;
+
+ len = strlen (dummy.name);
+ if (len >= prev_name_len)
+ {
+ prev_name_len = len + 1024;
+ free (prev_name);
+ prev_name = xmalloc (prev_name_len);
+ }
+ strcpy (prev_name, dummy.name);
+
+ len = strlen (filename);
+ if (len >= prev_filename_len)
+ {
+ prev_filename_len = len + 1024;
+ free (prev_filename);
+ prev_filename = xmalloc (prev_filename_len);
+ }
+ strcpy (prev_filename, filename);
+
+ min_vma = MIN (vma, min_vma);
+ max_vma = MAX (vma, max_vma);
+ }
+
+ free (prev_name);
+ free (prev_filename);
+
+ /* make room for function symbols, too: */
+ ltab.len += symtab.len;
+ ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
+ ltab.limit = ltab.base;
+
+ /* pass 2 - create symbols: */
+
+ /* We now set is_static as we go along, rather than by running
+ through the symbol table at the end.
+
+ The old way called symtab_finalize before the is_static pass,
+ causing a problem since symtab_finalize uses is_static as part of
+ its address conflict resolution algorithm. Since global symbols
+ were prefered over static symbols, and all line symbols were
+ global at that point, static function names that conflicted with
+ their own line numbers (static, but labeled as global) were
+ rejected in favor of the line num.
+
+ This was not the desired functionality. We always want to keep
+ our function symbols and discard any conflicting line symbols.
+ Perhaps symtab_finalize should be modified to make this
+ distinction as well, but the current fix works and the code is a
+ lot cleaner now. */
+
+ prev = 0;
+ for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
+ {
+ sym_init (ltab.limit);
+ if (!get_src_info (core_text_sect->vma + offset, &filename,
+ &ltab.limit->name, &ltab.limit->line_num)
+ || (prev && prev->line_num == ltab.limit->line_num
+ && strcmp (prev->name, ltab.limit->name) == 0
+ && strcmp (prev->file->name, filename) == 0))
+ {
+ continue;
+ }
+
+ /* make name pointer a malloc'ed string: */
+ ltab.limit->name = xstrdup (ltab.limit->name);
+ ltab.limit->file = source_file_lookup_path (filename);
+
+ ltab.limit->addr = core_text_sect->vma + offset;
+
+ /* Set is_static based on the enclosing function, using either:
+ * 1) the previous symbol, if it's from the same function, or
+ * 2) a symtab lookup
+ */
+
+ if (prev && ltab.limit->file == prev->file &&
+ strcmp (ltab.limit->name, prev->name) == 0)
+ {
+ ltab.limit->is_static = prev->is_static;
+ }
+ else
+ {
+ sym = sym_lookup(&symtab, ltab.limit->addr);
+ ltab.limit->is_static = sym->is_static;
+ }
+
+ prev = ltab.limit;
+
+ /*
+ * If we see "main" without an initial '_', we assume names
+ * are *not* prefixed by '_'.
+ */
+ if (ltab.limit->name[0] == 'm' && discard_underscores
+ && strcmp (ltab.limit->name, "main") == 0)
+ {
+ discard_underscores = 0;
+ }
+
+ DBG (AOUTDEBUG, printf ("[core_create_line_syms] %d %s 0x%lx\n",
+ ltab.limit - ltab.base, ltab.limit->name,
+ ltab.limit->addr));
+ ++ltab.limit;
+ }
+
+ /* update sentinels: */
+
+ sentinel = sym_lookup (&symtab, 0);
+ if (strcmp (sentinel->name, "<locore>") == 0
+ && min_vma <= sentinel->end_addr)
+ {
+ sentinel->end_addr = min_vma - 1;
+ }
+
+ sentinel = sym_lookup (&symtab, ~0);
+ if (strcmp (sentinel->name, "<hicore>") == 0 && max_vma >= sentinel->addr)
+ {
+ sentinel->addr = max_vma + 1;
+ }
+
+ /* copy in function symbols: */
+ memcpy (ltab.limit, symtab.base, symtab.len * sizeof (Sym));
+ ltab.limit += symtab.len;
+
+ if ((unsigned int) (ltab.limit - ltab.base) != ltab.len)
+ {
+ fprintf (stderr,
+ _("%s: somebody miscounted: ltab.len=%d instead of %ld\n"),
+ whoami, ltab.len, (long) (ltab.limit - ltab.base));
+ done (1);
+ }
+
+ /* finalize ltab and make it symbol table: */
+
+ symtab_finalize (&ltab);
+ free (symtab.base);
+ symtab = ltab;
+
+}
diff --git a/gprof/corefile.h b/gprof/corefile.h
new file mode 100644
index 00000000000..b396f8500b2
--- /dev/null
+++ b/gprof/corefile.h
@@ -0,0 +1,21 @@
+#ifndef corefile_h
+#define corefile_h
+
+#include "bfd.h"
+
+extern bfd *core_bfd; /* bfd for core-file */
+extern int core_num_syms; /* # of entries in symbol-table */
+extern asymbol **core_syms; /* symbol table in a.out */
+extern asection *core_text_sect; /* core text section */
+extern PTR core_text_space; /* text space of a.out in core */
+
+extern int min_insn_size; /* size of smallest instruction, in bytes */
+extern int offset_to_code; /* offset (in bytes) of code from entry
+ address of routine */
+
+extern void core_init PARAMS ((const char *a_out_name));
+extern void core_get_text_space PARAMS ((bfd * core_bfd));
+extern void core_create_function_syms PARAMS ((bfd * core_bfd));
+extern void core_create_line_syms PARAMS ((bfd * core_bfd));
+
+#endif /* corefile_h */
diff --git a/gprof/flat_bl.m b/gprof/flat_bl.m
new file mode 100644
index 00000000000..db2871a1384
--- /dev/null
+++ b/gprof/flat_bl.m
@@ -0,0 +1,27 @@
+
+ % the percentage of the total running time of the
+time program used by this function.
+
+cumulative a running sum of the number of seconds accounted
+ seconds for by this function and those listed above it.
+
+ self the number of seconds accounted for by this
+seconds function alone. This is the major sort for this
+ listing.
+
+calls the number of times this function was invoked, if
+ this function is profiled, else blank.
+
+ self the average number of milliseconds spent in this
+ms/call function per call, if this function is profiled,
+ else blank.
+
+ total the average number of milliseconds spent in this
+ms/call function and its descendents per call, if this
+ function is profiled, else blank.
+
+name the name of the function. This is the minor sort
+ for this listing. The index shows the location of
+ the function in the gprof listing. If the index is
+ in parenthesis it shows where it would appear in
+ the gprof listing if it were to be printed.
diff --git a/gprof/fsf_callg_bl.m b/gprof/fsf_callg_bl.m
new file mode 100644
index 00000000000..7e16821ede2
--- /dev/null
+++ b/gprof/fsf_callg_bl.m
@@ -0,0 +1,83 @@
+
+ This table describes the call tree of the program, and was sorted by
+ the total amount of time spent in each function and its children.
+
+ Each entry in this table consists of several lines. The line with the
+ index number at the left hand margin lists the current function.
+ The lines above it list the functions that called this function,
+ and the lines below it list the functions this one called.
+ This line lists:
+ index A unique number given to each element of the table.
+ Index numbers are sorted numerically.
+ The index number is printed next to every function name so
+ it is easier to look up where the function in the table.
+
+ % time This is the percentage of the `total' time that was spent
+ in this function and its children. Note that due to
+ different viewpoints, functions excluded by options, etc,
+ these numbers will NOT add up to 100%.
+
+ self This is the total amount of time spent in this function.
+
+ children This is the total amount of time propagated into this
+ function by its children.
+
+ called This is the number of times the function was called.
+ If the function called itself recursively, the number
+ only includes non-recursive calls, and is followed by
+ a `+' and the number of recursive calls.
+
+ name The name of the current function. The index number is
+ printed after it. If the function is a member of a
+ cycle, the cycle number is printed between the
+ function's name and the index number.
+
+
+ For the function's parents, the fields have the following meanings:
+
+ self This is the amount of time that was propagated directly
+ from the function into this parent.
+
+ children This is the amount of time that was propagated from
+ the function's children into this parent.
+
+ called This is the number of times this parent called the
+ function `/' the total number of times the function
+ was called. Recursive calls to the function are not
+ included in the number after the `/'.
+
+ name This is the name of the parent. The parent's index
+ number is printed after it. If the parent is a
+ member of a cycle, the cycle number is printed between
+ the name and the index number.
+
+ If the parents of the function cannot be determined, the word
+ `<spontaneous>' is printed in the `name' field, and all the other
+ fields are blank.
+
+ For the function's children, the fields have the following meanings:
+
+ self This is the amount of time that was propagated directly
+ from the child into the function.
+
+ children This is the amount of time that was propagated from the
+ child's children to the function.
+
+ called This is the number of times the function called
+ this child `/' the total number of times the child
+ was called. Recursive calls by the child are not
+ listed in the number after the `/'.
+
+ name This is the name of the child. The child's index
+ number is printed after it. If the child is a
+ member of a cycle, the cycle number is printed
+ between the name and the index number.
+
+ If there are any cycles (circles) in the call graph, there is an
+ entry for the cycle-as-a-whole. This entry shows who called the
+ cycle (as parents) and the members of the cycle (as children.)
+ The `+' recursive calls entry shows the number of function calls that
+ were internal to the cycle, and the calls entry for each member shows,
+ for that member, how many times it was called from other members of
+ the cycle.
+
diff --git a/gprof/gconfig.in b/gprof/gconfig.in
new file mode 100644
index 00000000000..347e8e0fbb7
--- /dev/null
+++ b/gprof/gconfig.in
@@ -0,0 +1,129 @@
+/* gconfig.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
diff --git a/gprof/gen-c-prog.awk b/gprof/gen-c-prog.awk
new file mode 100644
index 00000000000..b59c1f8d8dd
--- /dev/null
+++ b/gprof/gen-c-prog.awk
@@ -0,0 +1,26 @@
+NR == 1 {
+ FS="\"";
+ print "/* ==> Do not modify this file!! It is created automatically"
+ printf " from %s using the gen-c-prog.awk script. <== */\n\n", FILE
+ print "#include <stdio.h>"
+}
+
+ {
+ if (curfun != FUNCTION)
+ {
+ if (curfun)
+ print "}"
+ curfun = FUNCTION
+ print ""
+ print "void";
+ printf "%s (file)\n", FUNCTION
+ print " FILE *file;";
+ print "{";
+ }
+ printf " fputs (\"";
+ for (i = 1; i < NF; i++)
+ printf "%s\\\"", $i;
+ printf "%s\\n\", file);\n", $NF;
+}
+
+END { print "}" }
diff --git a/gprof/gmon.h b/gprof/gmon.h
new file mode 100644
index 00000000000..541fa4dbdf9
--- /dev/null
+++ b/gprof/gmon.h
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)gmon.h 5.2 (Berkeley) 5/6/91
+ */
+#ifndef gmon_h
+#define gmon_h
+
+struct raw_phdr
+ {
+ /* FIXME: Checking a host compiler define means that we can't use
+ a cross gprof to the alpha. */
+#ifdef __alpha__
+ char low_pc[8]; /* base pc address of sample buffer */
+ char high_pc[8]; /* max pc address of sampled buffer */
+#else
+ char low_pc[4]; /* base pc address of sample buffer */
+ char high_pc[4]; /* max pc address of sampled buffer */
+#endif
+ char ncnt[4]; /* size of sample buffer (plus this header) */
+
+ char version[4]; /* version number */
+ char profrate[4]; /* profiling clock rate */
+ char spare[3*4]; /* reserved */
+ };
+
+#define GMONVERSION 0x00051879
+
+struct old_raw_phdr
+ {
+ /* FIXME: Checking a host compiler define means that we can't use
+ a cross gprof to the alpha. */
+#ifdef __alpha__
+ char low_pc[8]; /* base pc address of sample buffer */
+ char high_pc[8]; /* max pc address of sampled buffer */
+#else
+ char low_pc[4]; /* base pc address of sample buffer */
+ char high_pc[4]; /* max pc address of sampled buffer */
+#endif
+ char ncnt[4]; /* size of sample buffer (plus this header) */
+
+ /* FIXME: Checking host compiler defines here means that we can't
+ use a cross gprof alpha OSF. */
+#if defined (__alpha__) && defined (__osf__)
+ /*
+ * DEC's OSF v3.0 uses 4 bytes of padding to bring the header to
+ * a size that is a multiple of 8.
+ */
+ char pad[4];
+#endif
+ };
+
+/*
+ * Histogram counters are unsigned shorts:
+ */
+#define HISTCOUNTER unsigned short
+
+/*
+ * Fraction of text space to allocate for histogram counters here, 1/2:
+ */
+#define HISTFRACTION 2
+
+/*
+ * Fraction of text space to allocate for from hash buckets. The
+ * value of HASHFRACTION is based on the minimum number of bytes of
+ * separation between two subroutine call points in the object code.
+ * Given MIN_SUBR_SEPARATION bytes of separation the value of
+ * HASHFRACTION is calculated as:
+ *
+ * HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
+ *
+ * For the VAX, the shortest two call sequence is:
+ *
+ * calls $0,(r0)
+ * calls $0,(r0)
+ *
+ * which is separated by only three bytes, thus HASHFRACTION is
+ * calculated as:
+ *
+ * HASHFRACTION = 3 / (2 * 2 - 1) = 1
+ *
+ * Note that the division above rounds down, thus if MIN_SUBR_FRACTION
+ * is less than three, this algorithm will not work!
+ */
+#define HASHFRACTION 1
+
+/*
+ * Percent of text space to allocate for tostructs with a minimum:
+ */
+#define ARCDENSITY 2
+#define MINARCS 50
+
+struct tostruct
+ {
+ char *selfpc;
+ int count;
+ unsigned short link;
+ };
+
+/*
+ * A raw arc, with pointers to the calling site and the called site
+ * and a count. Everything is defined in terms of characters so
+ * as to get a packed representation (otherwise, different compilers
+ * might introduce different padding):
+ */
+struct raw_arc
+ {
+ /* FIXME: Checking a host compiler define means that we can't use
+ a cross gprof to the alpha. */
+#ifdef __alpha__
+ char from_pc[8];
+ char self_pc[8];
+ char count[8];
+#else
+ char from_pc[4];
+ char self_pc[4];
+ char count[4];
+#endif
+ };
+
+/*
+ * General rounding functions:
+ */
+#define ROUNDDOWN(x,y) (((x)/(y))*(y))
+#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
+
+#endif /* gmon_h */
diff --git a/gprof/gmon_io.c b/gprof/gmon_io.c
new file mode 100644
index 00000000000..ff294f5fe45
--- /dev/null
+++ b/gprof/gmon_io.c
@@ -0,0 +1,454 @@
+/*
+ * Input and output from/to gmon.out files.
+ */
+#include "cg_arcs.h"
+#include "basic_blocks.h"
+#include "bfd.h"
+#include "corefile.h"
+#include "call_graph.h"
+#include "gmon_io.h"
+#include "gmon_out.h"
+#include "gmon.h" /* fetch header for old format */
+#include "gprof.h"
+#include "hertz.h"
+#include "hist.h"
+#include "libiberty.h"
+
+int gmon_input = 0;
+int gmon_file_version = 0; /* 0 == old (non-versioned) file format */
+
+/*
+ * This probably ought to be in libbfd.
+ */
+bfd_vma
+DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr)
+{
+ switch (sizeof (char*))
+ {
+ case 4:
+ return bfd_get_32 (abfd, addr);
+ case 8:
+ return bfd_get_64 (abfd, addr);
+ default:
+ fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"),
+ whoami, (long) sizeof (char*));
+ done (1);
+ }
+}
+
+
+/*
+ * This probably ought to be in libbfd.
+ */
+void
+DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr)
+{
+ switch (sizeof (char*))
+ {
+ case 4:
+ bfd_put_32 (abfd, val, addr);
+ break;
+ case 8:
+ bfd_put_64 (abfd, val, addr);
+ break;
+ default:
+ fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"),
+ whoami, (long) sizeof (char*));
+ done (1);
+ }
+}
+
+
+void
+DEFUN (gmon_out_read, (filename), const char *filename)
+{
+ FILE *ifp;
+ struct gmon_hdr ghdr;
+ unsigned char tag;
+ int nhist = 0, narcs = 0, nbbs = 0;
+
+ /* open gmon.out file: */
+
+ if (strcmp (filename, "-") == 0)
+ {
+ ifp = stdin;
+ }
+ else
+ {
+ ifp = fopen (filename, FOPEN_RB);
+ if (!ifp)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+ if (fread (&ghdr, sizeof (struct gmon_hdr), 1, ifp) != 1)
+ {
+ fprintf (stderr, _("%s: file too short to be a gmon file\n"),
+ filename);
+ done (1);
+ }
+
+ if ((file_format == FF_MAGIC) ||
+ (file_format == FF_AUTO && !strncmp (&ghdr.cookie[0], GMON_MAGIC, 4)))
+ {
+ if (file_format == FF_MAGIC && strncmp (&ghdr.cookie[0], GMON_MAGIC, 4))
+ {
+ fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
+ whoami, filename);
+ done (1);
+ }
+
+ /* right magic, so it's probably really a new gmon.out file */
+
+ gmon_file_version = bfd_get_32 (core_bfd, (bfd_byte *) ghdr.version);
+ if (gmon_file_version != GMON_VERSION && gmon_file_version != 0)
+ {
+ fprintf (stderr,
+ _("%s: file `%s' has unsupported version %d\n"),
+ whoami, filename, gmon_file_version);
+ done (1);
+ }
+
+ /* read in all the records: */
+ while (fread (&tag, sizeof (tag), 1, ifp) == 1)
+ {
+ switch (tag)
+ {
+ case GMON_TAG_TIME_HIST:
+ ++nhist;
+ gmon_input |= INPUT_HISTOGRAM;
+ hist_read_rec (ifp, filename);
+ break;
+
+ case GMON_TAG_CG_ARC:
+ ++narcs;
+ gmon_input |= INPUT_CALL_GRAPH;
+ cg_read_rec (ifp, filename);
+ break;
+
+ case GMON_TAG_BB_COUNT:
+ ++nbbs;
+ gmon_input |= INPUT_BB_COUNTS;
+ bb_read_rec (ifp, filename);
+ break;
+
+ default:
+ fprintf (stderr,
+ _("%s: %s: found bad tag %d (file corrupted?)\n"),
+ whoami, filename, tag);
+ done (1);
+ }
+ }
+ }
+ else if (file_format == FF_AUTO
+ || file_format == FF_BSD
+ || file_format == FF_BSD44)
+ {
+ struct hdr
+ {
+ bfd_vma low_pc;
+ bfd_vma high_pc;
+ int ncnt;
+ };
+ int i, samp_bytes, header_size;
+ unsigned long count;
+ bfd_vma from_pc, self_pc;
+ struct raw_arc raw_arc;
+ struct raw_phdr raw;
+ static struct hdr h;
+ UNIT raw_bin_count;
+ struct hdr tmp;
+
+ /*
+ * Information from a gmon.out file is in two parts: an array of
+ * sampling hits within pc ranges, and the arcs.
+ */
+ gmon_input = INPUT_HISTOGRAM | INPUT_CALL_GRAPH;
+
+ /*
+ * This fseek() ought to work even on stdin as long as it's
+ * not an interactive device (heck, is there anybody who would
+ * want to type in a gmon.out at the terminal?).
+ */
+ if (fseek (ifp, 0, SEEK_SET) < 0)
+ {
+ perror (filename);
+ done (1);
+ }
+ if (fread (&raw, 1, sizeof (struct raw_phdr), ifp)
+ != sizeof (struct raw_phdr))
+ {
+ fprintf (stderr, _("%s: file too short to be a gmon file\n"),
+ filename);
+ done (1);
+ }
+ tmp.low_pc = get_vma (core_bfd, (bfd_byte *) &raw.low_pc[0]);
+ tmp.high_pc = get_vma (core_bfd, (bfd_byte *) &raw.high_pc[0]);
+ tmp.ncnt = bfd_get_32 (core_bfd, (bfd_byte *) &raw.ncnt[0]);
+
+ if (bfd_get_32 (core_bfd, (bfd_byte *) &raw.version[0])
+ == GMONVERSION)
+ {
+ int profrate;
+
+ /* 4.4BSD format header. */
+
+ profrate = bfd_get_32 (core_bfd, (bfd_byte *) &raw.profrate[0]);
+ if (!s_highpc)
+ hz = profrate;
+ else if (hz != profrate)
+ {
+ fprintf (stderr,
+ _("%s: profiling rate incompatible with first gmon file\n"),
+ filename);
+ done (1);
+ }
+
+ header_size = sizeof (struct raw_phdr);
+ }
+ else
+ {
+ /* old style BSD format. */
+ if (file_format == FF_BSD44)
+ {
+ fprintf (stderr, _("%s: file `%s' has bad magic cookie\n"),
+ whoami, filename);
+ done (1);
+ }
+
+ if (fseek (ifp, sizeof (struct old_raw_phdr), SEEK_SET) < 0)
+ {
+ perror (filename);
+ done (1);
+ }
+
+ header_size = sizeof (struct old_raw_phdr);
+ }
+
+ if (s_highpc && (tmp.low_pc != h.low_pc ||
+ tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
+ {
+ fprintf (stderr, _("%s: incompatible with first gmon file\n"),
+ filename);
+ done (1);
+ }
+ h = tmp;
+ s_lowpc = (bfd_vma) h.low_pc;
+ s_highpc = (bfd_vma) h.high_pc;
+ lowpc = (bfd_vma) h.low_pc / sizeof (UNIT);
+ highpc = (bfd_vma) h.high_pc / sizeof (UNIT);
+ samp_bytes = h.ncnt - header_size;
+ hist_num_bins = samp_bytes / sizeof (UNIT);
+ DBG (SAMPLEDEBUG,
+ printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
+ h.low_pc, h.high_pc, h.ncnt);
+ printf ("[gmon_out_read] s_lowpc 0x%lx s_highpc 0x%lx\n",
+ s_lowpc, s_highpc);
+ printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx\n",
+ lowpc, highpc);
+ printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
+ samp_bytes, hist_num_bins));
+
+ if (hist_num_bins)
+ {
+ ++nhist;
+ }
+
+ if (!hist_sample)
+ {
+ hist_sample =
+ (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
+ memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
+ }
+
+ for (i = 0; i < hist_num_bins; ++i)
+ {
+ if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
+ {
+ fprintf (stderr,
+ _("%s: unexpected EOF after reading %d/%d bins\n"),
+ whoami, --i, hist_num_bins);
+ done (1);
+ }
+ hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
+ }
+
+ /*
+ * The rest of the file consists of a bunch of <from,self,count>
+ * tuples:
+ */
+ while (fread (&raw_arc, sizeof (raw_arc), 1, ifp) == 1)
+ {
+ ++narcs;
+ from_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.from_pc);
+ self_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.self_pc);
+ count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count);
+ DBG (SAMPLEDEBUG,
+ printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
+ from_pc, self_pc, count));
+ /* add this arc: */
+ cg_tally (from_pc, self_pc, count);
+ }
+ fclose (ifp);
+
+ if (hz == HZ_WRONG)
+ {
+ /*
+ * How many ticks per second? If we can't tell, report
+ * time in ticks.
+ */
+ hz = hertz ();
+ if (hz == HZ_WRONG)
+ {
+ hz = 1;
+ fprintf (stderr, _("time is in ticks, not seconds\n"));
+ }
+ }
+ }
+ else
+ {
+ fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
+ whoami, file_format);
+ done (1);
+ }
+
+ if (output_style & STYLE_GMON_INFO)
+ {
+ printf (_("File `%s' (version %d) contains:\n"),
+ filename, gmon_file_version);
+ printf (_("\t%d histogram record%s\n"),
+ nhist, nhist == 1 ? "" : "s");
+ printf (_("\t%d call-graph record%s\n"),
+ narcs, narcs == 1 ? "" : "s");
+ printf (_("\t%d basic-block count record%s\n"),
+ nbbs, nbbs == 1 ? "" : "s");
+ first_output = FALSE;
+ }
+}
+
+
+void
+DEFUN (gmon_out_write, (filename), const char *filename)
+{
+ FILE *ofp;
+ struct gmon_hdr ghdr;
+
+ ofp = fopen (filename, FOPEN_WB);
+ if (!ofp)
+ {
+ perror (filename);
+ done (1);
+ }
+
+ if (file_format == FF_AUTO || file_format == FF_MAGIC)
+ {
+ /* write gmon header: */
+
+ memcpy (&ghdr.cookie[0], GMON_MAGIC, 4);
+ bfd_put_32 (core_bfd, GMON_VERSION, (bfd_byte *) ghdr.version);
+ if (fwrite (&ghdr, sizeof (ghdr), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+
+ /* write execution time histogram if we have one: */
+ if (gmon_input & INPUT_HISTOGRAM)
+ {
+ hist_write_hist (ofp, filename);
+ }
+
+ /* write call graph arcs if we have any: */
+ if (gmon_input & INPUT_CALL_GRAPH)
+ {
+ cg_write_arcs (ofp, filename);
+ }
+
+ /* write basic-block info if we have it: */
+ if (gmon_input & INPUT_BB_COUNTS)
+ {
+ bb_write_blocks (ofp, filename);
+ }
+ }
+ else if (file_format == FF_BSD || file_format == FF_BSD44)
+ {
+ struct raw_arc raw_arc;
+ UNIT raw_bin_count;
+ struct raw_phdr h;
+ int i;
+ Arc *arc;
+ Sym *sym;
+
+ memset (&h, 0, sizeof h);
+ put_vma (core_bfd, s_lowpc, (bfd_byte *) &h.low_pc);
+ put_vma (core_bfd, s_highpc, (bfd_byte *) &h.high_pc);
+ bfd_put_32 (core_bfd,
+ hist_num_bins * sizeof (UNIT) + sizeof (struct raw_phdr),
+ (bfd_byte *) &h.ncnt);
+
+ /* Write header. Use new style BSD format is explicitly
+ specified, or if the profiling rate is non-standard;
+ otherwise, use the old BSD format. */
+ if (file_format == FF_BSD44
+ || hz != hertz ())
+ {
+ bfd_put_32 (core_bfd, GMONVERSION, (bfd_byte *) &h.version);
+ bfd_put_32 (core_bfd, hz, (bfd_byte *) &h.profrate);
+ if (fwrite (&h, sizeof (struct raw_phdr), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+ else
+ {
+ if (fwrite (&h, sizeof (struct old_raw_phdr), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+
+ /* dump the samples: */
+
+ for (i = 0; i < hist_num_bins; ++i)
+ {
+ bfd_put_16 (core_bfd, hist_sample[i], (bfd_byte *) & raw_bin_count[0]);
+ if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+
+ /* dump the normalized raw arc information: */
+
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ for (arc = sym->cg.children; arc; arc = arc->next_child)
+ {
+ put_vma (core_bfd, arc->parent->addr,
+ (bfd_byte *) raw_arc.from_pc);
+ put_vma (core_bfd, arc->child->addr,
+ (bfd_byte *) raw_arc.self_pc);
+ bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count);
+ if (fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ DBG (SAMPLEDEBUG,
+ printf ("[dumpsum] frompc 0x%lx selfpc 0x%lx count %lu\n",
+ arc->parent->addr, arc->child->addr, arc->count));
+ }
+ }
+ fclose (ofp);
+ }
+ else
+ {
+ fprintf (stderr, _("%s: don't know how to deal with file format %d\n"),
+ whoami, file_format);
+ done (1);
+ }
+}
diff --git a/gprof/gmon_io.h b/gprof/gmon_io.h
new file mode 100644
index 00000000000..bf257a49df6
--- /dev/null
+++ b/gprof/gmon_io.h
@@ -0,0 +1,20 @@
+#ifndef gmon_io_h
+#define gmon_io_h
+
+#include "bfd.h"
+#include "gmon.h"
+
+#define INPUT_HISTOGRAM (1<<0)
+#define INPUT_CALL_GRAPH (1<<1)
+#define INPUT_BB_COUNTS (1<<2)
+
+extern int gmon_input; /* what input did we see? */
+extern int gmon_file_version; /* file version are we dealing with */
+
+extern bfd_vma get_vma PARAMS ((bfd * abfd, bfd_byte * addr));
+extern void put_vma PARAMS ((bfd * abfd, bfd_vma val, bfd_byte * addr));
+
+extern void gmon_out_read PARAMS ((const char *filename));
+extern void gmon_out_write PARAMS ((const char *filename));
+
+#endif /* gmon_io_h */
diff --git a/gprof/gmon_out.h b/gprof/gmon_out.h
new file mode 100644
index 00000000000..2144fb5954b
--- /dev/null
+++ b/gprof/gmon_out.h
@@ -0,0 +1,51 @@
+/*
+ * This file specifies the format of gmon.out files. It should have
+ * as few external dependencies as possible as it is going to be
+ * included in many different programs. That is, minimize the
+ * number of #include's.
+ *
+ * A gmon.out file consists of a header (defined by gmon_hdr) followed
+ * by a sequence of records. Each record starts with a one-byte tag
+ * identifying the type of records, followed by records specific data.
+ */
+#ifndef gmon_out_h
+#define gmon_out_h
+
+#define GMON_MAGIC "gmon" /* magic cookie */
+#define GMON_VERSION 1 /* version number */
+
+/*
+ * Raw header as it appears on file (without padding):
+ */
+struct gmon_hdr
+ {
+ char cookie[4];
+ char version[4];
+ char spare[3 * 4];
+ };
+
+/* types of records in this file: */
+typedef enum
+ {
+ GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2
+ }
+GMON_Record_Tag;
+
+struct gmon_hist_hdr
+ {
+ char low_pc[sizeof (char*)]; /* base pc address of sample buffer */
+ char high_pc[sizeof (char*)]; /* max pc address of sampled buffer */
+ char hist_size[4]; /* size of sample buffer */
+ char prof_rate[4]; /* profiling clock rate */
+ char dimen[15]; /* phys. dim., usually "seconds" */
+ char dimen_abbrev; /* usually 's' for "seconds" */
+ };
+
+struct gmon_cg_arc_record
+ {
+ char from_pc[sizeof (char*)]; /* address within caller's body */
+ char self_pc[sizeof (char*)]; /* address within callee's body */
+ char count[4]; /* number of arc traversals */
+ };
+
+#endif /* gmon_out_h */
diff --git a/gprof/gprof.1 b/gprof/gprof.1
new file mode 100644
index 00000000000..5a734da0b21
--- /dev/null
+++ b/gprof/gprof.1
@@ -0,0 +1,252 @@
+.\" Copyright (c) 1983, 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted provided
+.\" that: (1) source distributions retain this entire copyright notice and
+.\" comment, and (2) distributions including binaries display the following
+.\" acknowledgement: ``This product includes software developed by the
+.\" University of California, Berkeley and its contributors'' in the
+.\" documentation or other materials provided with the distribution and in
+.\" all advertising materials mentioning features or use of this software.
+.\" Neither the name of the University nor the names of its contributors may
+.\" be used to endorse or promote products derived from this software without
+.\" specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)gprof.1 6.6 (Berkeley) 7/24/90
+.\"
+.TH GPROF 1 "January 29, 1993"
+.SH NAME
+gprof \- display call graph profile data
+.SH SYNOPSIS
+.B gprof [ \-abcsz ] [ \-e|\-E
+.I name
+.B ] [ \-f|\-F
+.I name
+.B ]
+.B [ \-k
+.I fromname toname
+.B ] [
+.I objfile
+.B [
+.I gmon.out
+.B ]
+.B ]
+.SH DESCRIPTION
+.B gprof
+produces an execution profile of C, Pascal, or Fortran77 programs.
+The effect of called routines is incorporated in the profile of each caller.
+The profile data is taken from the call graph profile file
+\&(`gmon.out' default) which is created by programs
+that are compiled with the
+.B \-pg
+option of
+.BR cc ( 1 ) ,
+.BR pc ( 1 ) ,
+and
+.BR f77 ( 1 ) .
+The
+.B \-pg
+option also links in versions of the library routines
+that are compiled for profiling.
+.B Gprof
+reads the given object file (the default is `a.out')
+and establishes the relation between its symbol table
+and the call graph profile from `gmon.out'.
+If more than one profile file is specified,
+the
+.B gprof
+output shows the sum of the profile information in the given profile files.
+.PP
+.B Gprof
+calculates the amount of time spent in each routine.
+Next, these times are propagated along the edges of the call graph.
+Cycles are discovered, and calls into a cycle are made to share the time
+of the cycle.
+The first listing shows the functions
+sorted according to the time they represent
+including the time of their call graph descendants.
+Below each function entry is shown its (direct) call graph children,
+and how their times are propagated to this function.
+A similar display above the function shows how this function's time and the
+time of its descendants is propagated to its (direct) call graph parents.
+.PP
+Cycles are also shown, with an entry for the cycle as a whole and
+a listing of the members of the cycle and their contributions to the
+time and call counts of the cycle.
+.PP
+Second, a flat profile is given,
+similar to that provided by
+.BR prof ( 1 ) .
+This listing gives the total execution times, the call counts,
+the time in milliseconds the call spent in the routine itself, and
+the time in milliseconds the call spent in the routine itself including
+its descendants.
+.PP
+Finally, an index of the function names is provided.
+.SH OPTIONS
+The following options are available:
+.TP
+.B \-a
+suppresses the printing of statically declared functions.
+If this option is given, all relevant information about the static function
+(e.g., time samples, calls to other functions, calls from other functions)
+belongs to the function loaded just before the static function in the
+\&`objfile' file.
+.TP
+.B \-b
+suppresses the printing of a description of each field in the profile.
+.TP
+.B \-c
+the static call graph of the program is discovered by a heuristic
+that examines the text space of the object file.
+Static-only parents or children are shown
+with call counts of 0.
+.TP
+.BI "\-e " name
+suppresses the printing of the graph profile entry for routine
+.I name
+and all its descendants
+(unless they have other ancestors that aren't suppressed).
+More than one
+.B \-e
+option may be given.
+Only one
+.I name
+may be given with each
+.B \-e
+option.
+.TP
+.BI "\-E " name
+suppresses the printing of the graph profile entry for routine
+.I name
+(and its descendants) as
+.B \-e ,
+above, and also excludes the time spent in
+.I name
+(and its descendants) from the total and percentage time computations.
+(For example,
+.BI "\-E " mcount
+.BI "\-E " mcleanup
+is the default.)
+.TP
+.BI "\-f " name
+prints the graph profile entry of only the specified routine
+.I name
+and its descendants.
+More than one
+.B \-f
+option may be given.
+Only one
+.I name
+may be given with each
+.B \-f
+option.
+.TP
+.BI "\-F " name
+prints the graph profile entry of only the routine
+.I name
+and its descendants (as
+.B \-f ,
+above) and also uses only the times of the printed routines
+in total time and percentage computations.
+More than one
+.B \-F
+option may be given.
+Only one
+.I name
+may be given with each
+.B \-F
+option.
+The
+.B \-F
+option
+overrides
+the
+.B \-E
+option.
+.TP
+.BI "\-k " "fromname toname"
+will delete any arcs from routine
+.I fromname
+to routine
+.IR toname .
+This can be used to break undesired cycles.
+More than one
+.B \-k
+option may be given.
+Only one pair of routine names may be given with each
+.B \-k
+option.
+.TP
+.B \-s
+a profile file `gmon.sum' is produced that represents
+the sum of the profile information in all the specified profile files.
+This summary profile file may be given to later
+executions of gprof (probably also with a
+.BR \-s )
+to accumulate profile data across several runs of an `objfile' file.
+.TP
+.B -v
+prints the version number for gprof, and then exits.
+.TP
+.B -z
+displays routines that have zero usage (as shown by call counts
+and accumulated time).
+This is useful with the
+.B \-c
+option for discovering which routines were never called.
+.PP
+.SH FILES
+.ta \w'gmon.sum 'u
+a.out the namelist and text space.
+.br
+gmon.out dynamic call graph and profile.
+.br
+gmon.sum summarized dynamic call graph and profile.
+.SH SEE ALSO
+.BR monitor ( 3 ) ,
+.BR profil ( 2 ) ,
+.BR cc ( 1 ) ,
+.BR prof ( 1 )
+.sp
+``An Execution Profiler for Modular Programs'',
+by S. Graham, P. Kessler, M. McKusick;
+.I
+Software \- Practice and Experience,
+Vol. 13, pp. 671-685, 1983.
+.sp
+``gprof: A Call Graph Execution Profiler'',
+by S. Graham, P. Kessler, M. McKusick;
+.I
+Proceedings of the SIGPLAN '82 Symposium on Compiler Construction,
+SIGPLAN Notices, Vol. 17, No 6, pp. 120-126, June 1982.
+.SH HISTORY
+.B Gprof
+appeared in 4.2 BSD.
+.SH BUGS
+The granularity of the sampling is shown, but remains
+statistical at best.
+We assume that the time for each execution of a function
+can be expressed by the total time for the function divided
+by the number of times the function is called.
+Thus the time propagated along the call graph arcs to the function's
+parents is directly proportional to the number of times that
+arc is traversed.
+.PP
+Parents that are not themselves profiled will have the time of
+their profiled children propagated to them, but they will appear
+to be spontaneously invoked in the call graph listing, and will
+not have their time propagated further.
+Similarly, signal catchers, even though profiled, will appear
+to be spontaneous (although for more obscure reasons).
+Any profiled children of signal catchers should have their times
+propagated properly, unless the signal catcher was invoked during
+the execution of the profiling routine, in which case all is lost.
+.PP
+The profiled program must call
+.BR exit ( 2 )
+or return normally for the profiling information to be saved
+in the `gmon.out' file.
diff --git a/gprof/gprof.c b/gprof/gprof.c
new file mode 100644
index 00000000000..cb904870e50
--- /dev/null
+++ b/gprof/gprof.c
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 1983, 1998 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "getopt.h"
+#include "libiberty.h"
+#include "gprof.h"
+#include "basic_blocks.h"
+#include "call_graph.h"
+#include "cg_arcs.h"
+#include "cg_print.h"
+#include "corefile.h"
+#include "gmon_io.h"
+#include "hertz.h"
+#include "hist.h"
+#include "source.h"
+#include "sym_ids.h"
+
+const char *whoami;
+const char *function_mapping_file;
+const char *a_out_name = A_OUTNAME;
+long hz = HZ_WRONG;
+
+/*
+ * Default options values:
+ */
+int debug_level = 0;
+int output_style = 0;
+int output_width = 80;
+bool bsd_style_output = FALSE;
+bool demangle = TRUE;
+bool discard_underscores = TRUE;
+bool ignore_direct_calls = FALSE;
+bool ignore_static_funcs = FALSE;
+bool ignore_zeros = TRUE;
+bool line_granularity = FALSE;
+bool print_descriptions = TRUE;
+bool print_path = FALSE;
+bool ignore_non_functions = FALSE;
+File_Format file_format = FF_AUTO;
+
+bool first_output = TRUE;
+
+char copyright[] =
+ N_("@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n");
+
+static char *gmon_name = GMONNAME; /* profile filename */
+
+bfd *abfd;
+
+/*
+ * Functions that get excluded by default:
+ */
+static char *default_excluded_list[] =
+{
+ "_gprof_mcount", "mcount", "_mcount", "__mcount", "__mcount_internal",
+ "__mcleanup",
+ "<locore>", "<hicore>",
+ 0
+};
+
+/* Codes used for the long options with no short synonyms. 150 isn't
+ special; it's just an arbitrary non-ASCII char value. */
+
+#define OPTION_DEMANGLE (150)
+#define OPTION_NO_DEMANGLE (OPTION_DEMANGLE + 1)
+
+static struct option long_options[] =
+{
+ {"line", no_argument, 0, 'l'},
+ {"no-static", no_argument, 0, 'a'},
+ {"ignore-non-functions", no_argument, 0, 'D'},
+
+ /* output styles: */
+
+ {"annotated-source", optional_argument, 0, 'A'},
+ {"no-annotated-source", optional_argument, 0, 'J'},
+ {"flat-profile", optional_argument, 0, 'p'},
+ {"no-flat-profile", optional_argument, 0, 'P'},
+ {"graph", optional_argument, 0, 'q'},
+ {"no-graph", optional_argument, 0, 'Q'},
+ {"exec-counts", optional_argument, 0, 'C'},
+ {"no-exec-counts", optional_argument, 0, 'Z'},
+ {"function-ordering", no_argument, 0, 'r'},
+ {"file-ordering", required_argument, 0, 'R'},
+ {"file-info", no_argument, 0, 'i'},
+ {"sum", no_argument, 0, 's'},
+
+ /* various options to affect output: */
+
+ {"all-lines", no_argument, 0, 'x'},
+ {"demangle", no_argument, 0, OPTION_DEMANGLE},
+ {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLE},
+ {"directory-path", required_argument, 0, 'I'},
+ {"display-unused-functions", no_argument, 0, 'z'},
+ {"min-count", required_argument, 0, 'm'},
+ {"print-path", no_argument, 0, 'L'},
+ {"separate-files", no_argument, 0, 'y'},
+ {"static-call-graph", no_argument, 0, 'c'},
+ {"table-length", required_argument, 0, 't'},
+ {"time", required_argument, 0, 'n'},
+ {"no-time", required_argument, 0, 'N'},
+ {"width", required_argument, 0, 'w'},
+ /*
+ * These are for backwards-compatibility only. Their functionality
+ * is provided by the output style options already:
+ */
+ {"", required_argument, 0, 'e'},
+ {"", required_argument, 0, 'E'},
+ {"", required_argument, 0, 'f'},
+ {"", required_argument, 0, 'F'},
+ {"", required_argument, 0, 'k'},
+
+ /* miscellaneous: */
+
+ {"brief", no_argument, 0, 'b'},
+ {"debug", optional_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {"file-format", required_argument, 0, 'O'},
+ {"traditional", no_argument, 0, 'T'},
+ {"version", no_argument, 0, 'v'},
+ {0, no_argument, 0, 0}
+};
+
+
+static void
+DEFUN (usage, (stream, status), FILE * stream AND int status)
+{
+ fprintf (stream, _("\
+Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n\
+ [-d[num]] [-k from/to] [-m min-count] [-t table-length]\n\
+ [--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n\
+ [--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n\
+ [--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n\
+ [--function-ordering] [--file-ordering]\n\
+ [--directory-path=dirs] [--display-unused-functions]\n\
+ [--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n\
+ [--no-static] [--print-path] [--separate-files]\n\
+ [--static-call-graph] [--sum] [--table-length=len] [--traditional]\n\
+ [--version] [--width=n] [--ignore-non-functions]\n\
+ [--demangle] [--no-demangle]\n\
+ [image-file] [profile-file...]\n"),
+ whoami);
+ if (status == 0)
+ fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
+ done (status);
+}
+
+
+int
+DEFUN (main, (argc, argv), int argc AND char **argv)
+{
+ char **sp, *str;
+ Sym **cg = 0;
+ int ch, user_specified = 0;
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ whoami = argv[0];
+ xmalloc_set_program_name (whoami);
+
+ while ((ch = getopt_long (argc, argv,
+ "aA::bBcCdD::e:E:f:F:hiI:J::k:lLm:n::N::O:p::P::q::Q::st:Tvw:xyzZ::",
+ long_options, 0))
+ != EOF)
+ {
+ switch (ch)
+ {
+ case 'a':
+ ignore_static_funcs = TRUE;
+ break;
+ case 'A':
+ if (optarg)
+ {
+ sym_id_add (optarg, INCL_ANNO);
+ }
+ output_style |= STYLE_ANNOTATED_SOURCE;
+ user_specified |= STYLE_ANNOTATED_SOURCE;
+ break;
+ case 'b':
+ print_descriptions = FALSE;
+ break;
+ case 'B':
+ output_style |= STYLE_CALL_GRAPH;
+ user_specified |= STYLE_CALL_GRAPH;
+ break;
+ case 'c':
+ ignore_direct_calls = TRUE;
+ break;
+ case 'C':
+ if (optarg)
+ {
+ sym_id_add (optarg, INCL_EXEC);
+ }
+ output_style |= STYLE_EXEC_COUNTS;
+ user_specified |= STYLE_EXEC_COUNTS;
+ break;
+ case 'd':
+ if (optarg)
+ {
+ debug_level |= atoi (optarg);
+ debug_level |= ANYDEBUG;
+ }
+ else
+ {
+ debug_level = ~0;
+ }
+ DBG (ANYDEBUG, printf ("[main] debug-level=0x%x\n", debug_level));
+#ifndef DEBUG
+ printf (_("%s: debugging not supported; -d ignored\n"), whoami);
+#endif /* DEBUG */
+ break;
+ case 'D':
+ ignore_non_functions = TRUE;
+ break;
+ case 'E':
+ sym_id_add (optarg, EXCL_TIME);
+ case 'e':
+ sym_id_add (optarg, EXCL_GRAPH);
+ break;
+ case 'F':
+ sym_id_add (optarg, INCL_TIME);
+ case 'f':
+ sym_id_add (optarg, INCL_GRAPH);
+ break;
+ case 'g':
+ sym_id_add (optarg, EXCL_FLAT);
+ break;
+ case 'G':
+ sym_id_add (optarg, INCL_FLAT);
+ break;
+ case 'h':
+ usage (stdout, 0);
+ case 'i':
+ output_style |= STYLE_GMON_INFO;
+ user_specified |= STYLE_GMON_INFO;
+ break;
+ case 'I':
+ search_list_append (&src_search_list, optarg);
+ break;
+ case 'J':
+ if (optarg)
+ {
+ sym_id_add (optarg, EXCL_ANNO);
+ output_style |= STYLE_ANNOTATED_SOURCE;
+ }
+ else
+ {
+ output_style &= ~STYLE_ANNOTATED_SOURCE;
+ }
+ user_specified |= STYLE_ANNOTATED_SOURCE;
+ break;
+ case 'k':
+ sym_id_add (optarg, EXCL_ARCS);
+ break;
+ case 'l':
+ line_granularity = TRUE;
+ break;
+ case 'L':
+ print_path = TRUE;
+ break;
+ case 'm':
+ bb_min_calls = (unsigned long) strtoul (optarg, (char **) NULL, 10);
+ break;
+ case 'n':
+ sym_id_add (optarg, INCL_TIME);
+ break;
+ case 'N':
+ sym_id_add (optarg, EXCL_TIME);
+ break;
+ case 'O':
+ switch (optarg[0])
+ {
+ case 'a':
+ file_format = FF_AUTO;
+ break;
+ case 'm':
+ file_format = FF_MAGIC;
+ break;
+ case 'b':
+ file_format = FF_BSD;
+ break;
+ case '4':
+ file_format = FF_BSD44;
+ break;
+ case 'p':
+ file_format = FF_PROF;
+ break;
+ default:
+ fprintf (stderr, _("%s: unknown file format %s\n"),
+ optarg, whoami);
+ done (1);
+ }
+ break;
+ case 'p':
+ if (optarg)
+ {
+ sym_id_add (optarg, INCL_FLAT);
+ }
+ output_style |= STYLE_FLAT_PROFILE;
+ user_specified |= STYLE_FLAT_PROFILE;
+ break;
+ case 'P':
+ if (optarg)
+ {
+ sym_id_add (optarg, EXCL_FLAT);
+ output_style |= STYLE_FLAT_PROFILE;
+ }
+ else
+ {
+ output_style &= ~STYLE_FLAT_PROFILE;
+ }
+ user_specified |= STYLE_FLAT_PROFILE;
+ break;
+ case 'q':
+ if (optarg)
+ {
+ if (strchr (optarg, '/'))
+ {
+ sym_id_add (optarg, INCL_ARCS);
+ }
+ else
+ {
+ sym_id_add (optarg, INCL_GRAPH);
+ }
+ }
+ output_style |= STYLE_CALL_GRAPH;
+ user_specified |= STYLE_CALL_GRAPH;
+ break;
+ case 'r':
+ output_style |= STYLE_FUNCTION_ORDER;
+ user_specified |= STYLE_FUNCTION_ORDER;
+ break;
+ case 'R':
+ output_style |= STYLE_FILE_ORDER;
+ user_specified |= STYLE_FILE_ORDER;
+ function_mapping_file = optarg;
+ break;
+ case 'Q':
+ if (optarg)
+ {
+ if (strchr (optarg, '/'))
+ {
+ sym_id_add (optarg, EXCL_ARCS);
+ }
+ else
+ {
+ sym_id_add (optarg, EXCL_GRAPH);
+ }
+ output_style |= STYLE_CALL_GRAPH;
+ }
+ else
+ {
+ output_style &= ~STYLE_CALL_GRAPH;
+ }
+ user_specified |= STYLE_CALL_GRAPH;
+ break;
+ case 's':
+ output_style |= STYLE_SUMMARY_FILE;
+ user_specified |= STYLE_SUMMARY_FILE;
+ break;
+ case 't':
+ bb_table_length = atoi (optarg);
+ if (bb_table_length < 0)
+ {
+ bb_table_length = 0;
+ }
+ break;
+ case 'T':
+ bsd_style_output = TRUE;
+ break;
+ case 'v':
+ /* This output is intended to follow the GNU standards document. */
+ printf (_("GNU gprof %s\n"), VERSION);
+ printf (_("Based on BSD gprof, copyright 1983 Regents of the University of California.\n"));
+ printf (_("\
+This program is free software. This program has absolutely no warranty.\n"));
+ done (0);
+ case 'w':
+ output_width = atoi (optarg);
+ if (output_width < 1)
+ {
+ output_width = 1;
+ }
+ break;
+ case 'x':
+ bb_annotate_all_lines = TRUE;
+ break;
+ case 'y':
+ create_annotation_files = TRUE;
+ break;
+ case 'z':
+ ignore_zeros = FALSE;
+ break;
+ case 'Z':
+ if (optarg)
+ {
+ sym_id_add (optarg, EXCL_EXEC);
+ output_style |= STYLE_EXEC_COUNTS;
+ }
+ else
+ {
+ output_style &= ~STYLE_EXEC_COUNTS;
+ }
+ user_specified |= STYLE_ANNOTATED_SOURCE;
+ break;
+ case OPTION_DEMANGLE:
+ demangle = TRUE;
+ break;
+ case OPTION_NO_DEMANGLE:
+ demangle = FALSE;
+ break;
+ default:
+ usage (stderr, 1);
+ }
+ }
+
+ /* Don't allow both ordering options, they modify the arc data in-place. */
+ if ((user_specified & STYLE_FUNCTION_ORDER)
+ && (user_specified & STYLE_FILE_ORDER))
+ {
+ fprintf (stderr,_("\
+%s: Only one of --function-ordering and --file-ordering may be specified.\n"),
+ whoami);
+ done (1);
+ }
+
+ /* --sum implies --line, otherwise we'd lose b-b counts in gmon.sum */
+ if (output_style & STYLE_SUMMARY_FILE)
+ {
+ line_granularity = 1;
+ }
+
+ /* append value of GPROF_PATH to source search list if set: */
+ str = (char *) getenv ("GPROF_PATH");
+ if (str)
+ {
+ search_list_append (&src_search_list, str);
+ }
+
+ if (optind < argc)
+ {
+ a_out_name = argv[optind++];
+ }
+ if (optind < argc)
+ {
+ gmon_name = argv[optind++];
+ }
+
+ /*
+ * Turn off default functions:
+ */
+ for (sp = &default_excluded_list[0]; *sp; sp++)
+ {
+ sym_id_add (*sp, EXCL_TIME);
+ sym_id_add (*sp, EXCL_GRAPH);
+#ifdef __alpha__
+ sym_id_add (*sp, EXCL_FLAT);
+#endif
+ }
+
+ /*
+ * For line-by-line profiling, also want to keep those
+ * functions off the flat profile:
+ */
+ if (line_granularity)
+ {
+ for (sp = &default_excluded_list[0]; *sp; sp++)
+ {
+ sym_id_add (*sp, EXCL_FLAT);
+ }
+ }
+
+ /*
+ * Read symbol table from core file:
+ */
+ core_init (a_out_name);
+
+ /*
+ * If we should ignore direct function calls, we need to load
+ * to core's text-space:
+ */
+ if (ignore_direct_calls)
+ {
+ core_get_text_space (core_bfd);
+ }
+
+ /*
+ * Create symbols from core image:
+ */
+ if (line_granularity)
+ {
+ core_create_line_syms (core_bfd);
+ }
+ else
+ {
+ core_create_function_syms (core_bfd);
+ }
+
+ /*
+ * Translate sym specs into syms:
+ */
+ sym_id_parse ();
+
+ if (file_format == FF_PROF)
+ {
+#ifdef PROF_SUPPORT_IMPLEMENTED
+ /*
+ * Get information about mon.out file(s):
+ */
+ do
+ {
+ mon_out_read (gmon_name);
+ if (optind < argc)
+ {
+ gmon_name = argv[optind];
+ }
+ }
+ while (optind++ < argc);
+#else
+ fprintf (stderr,
+ _("%s: sorry, file format `prof' is not yet supported\n"),
+ whoami);
+ done (1);
+#endif
+ }
+ else
+ {
+ /*
+ * Get information about gmon.out file(s):
+ */
+ do
+ {
+ gmon_out_read (gmon_name);
+ if (optind < argc)
+ {
+ gmon_name = argv[optind];
+ }
+ }
+ while (optind++ < argc);
+ }
+
+ /*
+ * If user did not specify output style, try to guess something
+ * reasonable:
+ */
+ if (output_style == 0)
+ {
+ if (gmon_input & (INPUT_HISTOGRAM | INPUT_CALL_GRAPH))
+ {
+ output_style = STYLE_FLAT_PROFILE | STYLE_CALL_GRAPH;
+ }
+ else
+ {
+ output_style = STYLE_EXEC_COUNTS;
+ }
+ output_style &= ~user_specified;
+ }
+
+ /*
+ * Dump a gmon.sum file if requested (before any other processing!):
+ */
+ if (output_style & STYLE_SUMMARY_FILE)
+ {
+ gmon_out_write (GMONSUM);
+ }
+
+ if (gmon_input & INPUT_HISTOGRAM)
+ {
+ hist_assign_samples ();
+ }
+
+ if (gmon_input & INPUT_CALL_GRAPH)
+ {
+ cg = cg_assemble ();
+ }
+
+ /* do some simple sanity checks: */
+
+ if ((output_style & STYLE_FLAT_PROFILE)
+ && !(gmon_input & INPUT_HISTOGRAM))
+ {
+ fprintf (stderr, _("%s: gmon.out file is missing histogram\n"), whoami);
+ done (1);
+ }
+
+ if ((output_style & STYLE_CALL_GRAPH) && !(gmon_input & INPUT_CALL_GRAPH))
+ {
+ fprintf (stderr,
+ _("%s: gmon.out file is missing call-graph data\n"), whoami);
+ done (1);
+ }
+
+ /* output whatever user whishes to see: */
+
+ if (cg && (output_style & STYLE_CALL_GRAPH) && bsd_style_output)
+ {
+ cg_print (cg); /* print the dynamic profile */
+ }
+
+ if (output_style & STYLE_FLAT_PROFILE)
+ {
+ hist_print (); /* print the flat profile */
+ }
+
+ if (cg && (output_style & STYLE_CALL_GRAPH))
+ {
+ if (!bsd_style_output)
+ {
+ cg_print (cg); /* print the dynamic profile */
+ }
+ cg_print_index ();
+ }
+
+ if (output_style & STYLE_EXEC_COUNTS)
+ {
+ print_exec_counts ();
+ }
+
+ if (output_style & STYLE_ANNOTATED_SOURCE)
+ {
+ print_annotated_source ();
+ }
+ if (output_style & STYLE_FUNCTION_ORDER)
+ {
+ cg_print_function_ordering ();
+ }
+ if (output_style & STYLE_FILE_ORDER)
+ {
+ cg_print_file_ordering ();
+ }
+ return 0;
+}
+
+void
+done (status)
+ int status;
+{
+ exit (status);
+}
diff --git a/gprof/gprof.h b/gprof/gprof.h
new file mode 100644
index 00000000000..8f62aeefd4a
--- /dev/null
+++ b/gprof/gprof.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)gprof.h 5.9 (Berkeley) 6/1/90
+ */
+#ifndef gprof_h
+#define gprof_h
+
+#include <ansidecl.h>
+
+/* Include the BFD sysdep.h file. */
+#include "sysdep.h"
+
+/* Undefine the BFD PACKAGE and VERSION macros before including the
+ gprof config.h file. */
+#undef PACKAGE
+#undef VERSION
+/* Also undefine BFD's `_' macro; we have our own definition. */
+#undef _
+
+#include "gconfig.h"
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+/* AIX defines hz as a macro. */
+#undef hz
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#define A_OUTNAME "a.out" /* default core filename */
+#define GMONNAME "gmon.out" /* default profile filename */
+#define GMONSUM "gmon.sum" /* profile summary filename */
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+
+/*
+ * These may already be defined on some systems. We could probably
+ * just use the BFD versions of these, since BFD has already dealt
+ * with this problem.
+ */
+#undef FALSE
+#define FALSE 0
+#undef TRUE
+#define TRUE 1
+
+#define STYLE_FLAT_PROFILE (1<<0)
+#define STYLE_CALL_GRAPH (1<<1)
+#define STYLE_SUMMARY_FILE (1<<2)
+#define STYLE_EXEC_COUNTS (1<<3)
+#define STYLE_ANNOTATED_SOURCE (1<<4)
+#define STYLE_GMON_INFO (1<<5)
+#define STYLE_FUNCTION_ORDER (1<<6)
+#define STYLE_FILE_ORDER (1<<7)
+
+#define ANYDEBUG (1<<0) /* 1 */
+#define DFNDEBUG (1<<1) /* 2 */
+#define CYCLEDEBUG (1<<2) /* 4 */
+#define ARCDEBUG (1<<3) /* 8 */
+#define TALLYDEBUG (1<<4) /* 16 */
+#define TIMEDEBUG (1<<5) /* 32 */
+#define SAMPLEDEBUG (1<<6) /* 64 */
+#define AOUTDEBUG (1<<7) /* 128 */
+#define CALLDEBUG (1<<8) /* 256 */
+#define LOOKUPDEBUG (1<<9) /* 512 */
+#define PROPDEBUG (1<<10) /* 1024 */
+#define BBDEBUG (1<<11) /* 2048 */
+#define IDDEBUG (1<<12) /* 4096 */
+#define SRCDEBUG (1<<13) /* 8192 */
+
+#ifdef DEBUG
+#define DBG(l,s) if (debug_level & (l)) {s;}
+#else
+#define DBG(l,s)
+#endif
+
+typedef enum
+ {
+ FF_AUTO = 0, FF_MAGIC, FF_BSD, FF_BSD44, FF_PROF
+ }
+File_Format;
+
+typedef int bool;
+typedef unsigned char UNIT[2]; /* unit of profiling */
+
+extern const char *whoami; /* command-name, for error messages */
+extern const char *function_mapping_file; /* file mapping functions to files */
+extern const char *a_out_name; /* core filename */
+extern long hz; /* ticks per second */
+
+/*
+ * Command-line options:
+ */
+extern int debug_level; /* debug level */
+extern int output_style;
+extern int output_width; /* controls column width in index */
+extern bool bsd_style_output; /* as opposed to FSF style output */
+extern bool demangle; /* demangle symbol names? */
+extern bool discard_underscores; /* discard leading underscores? */
+extern bool ignore_direct_calls; /* don't count direct calls */
+extern bool ignore_static_funcs; /* suppress static functions */
+extern bool ignore_zeros; /* ignore unused symbols/files */
+extern bool line_granularity; /* function or line granularity? */
+extern bool print_descriptions; /* output profile description */
+extern bool print_path; /* print path or just filename? */
+extern bool ignore_non_functions;/* Ignore non-function symbols. */
+
+extern File_Format file_format; /* requested file format */
+
+extern bool first_output; /* no output so far? */
+
+extern void done PARAMS ((int status));
+
+#endif /* gprof_h */
diff --git a/gprof/gprof.texi b/gprof/gprof.texi
new file mode 100644
index 00000000000..43d8b9fc451
--- /dev/null
+++ b/gprof/gprof.texi
@@ -0,0 +1,2028 @@
+\input texinfo @c -*-texinfo-*-
+@setfilename gprof.info
+@settitle GNU gprof
+@setchapternewpage odd
+
+@ifinfo
+@c This is a dir.info fragment to support semi-automated addition of
+@c manuals to an info tree. zoo@cygnus.com is developing this facility.
+@format
+START-INFO-DIR-ENTRY
+* gprof: (gprof). Profiling your program's execution
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This file documents the gprof profiler of the GNU system.
+
+Copyright (C) 1988, 1992, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@finalout
+@smallbook
+
+@titlepage
+@title GNU gprof
+@subtitle The @sc{gnu} Profiler
+@author Jay Fenlason and Richard Stallman
+
+@page
+
+This manual describes the @sc{gnu} profiler, @code{gprof}, and how you
+can use it to determine which parts of a program are taking most of the
+execution time. We assume that you know how to write, compile, and
+execute programs. @sc{gnu} @code{gprof} was written by Jay Fenlason.
+
+This manual was edited January 1993 by Jeffrey Osier
+and updated September 1997 by Brent Baccala.
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1988, 1992, 1997, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the same conditions as for modified versions.
+
+@end titlepage
+
+@ifinfo
+@node Top
+@top Profiling a Program: Where Does It Spend Its Time?
+
+This manual describes the @sc{gnu} profiler, @code{gprof}, and how you
+can use it to determine which parts of a program are taking most of the
+execution time. We assume that you know how to write, compile, and
+execute programs. @sc{gnu} @code{gprof} was written by Jay Fenlason.
+
+This manual was updated August 1997 by Brent Baccala.
+
+@menu
+* Introduction:: What profiling means, and why it is useful.
+
+* Compiling:: How to compile your program for profiling.
+* Executing:: Executing your program to generate profile data
+* Invoking:: How to run @code{gprof}, and its options
+
+* Output:: Interpreting @code{gprof}'s output
+
+* Inaccuracy:: Potential problems you should be aware of
+* How do I?:: Answers to common questions
+* Incompatibilities:: (between @sc{gnu} @code{gprof} and Unix @code{gprof}.)
+* Details:: Details of how profiling is done
+@end menu
+@end ifinfo
+
+@node Introduction
+@chapter Introduction to Profiling
+
+Profiling allows you to learn where your program spent its time and which
+functions called which other functions while it was executing. This
+information can show you which pieces of your program are slower than you
+expected, and might be candidates for rewriting to make your program
+execute faster. It can also tell you which functions are being called more
+or less often than you expected. This may help you spot bugs that had
+otherwise been unnoticed.
+
+Since the profiler uses information collected during the actual execution
+of your program, it can be used on programs that are too large or too
+complex to analyze by reading the source. However, how your program is run
+will affect the information that shows up in the profile data. If you
+don't use some feature of your program while it is being profiled, no
+profile information will be generated for that feature.
+
+Profiling has several steps:
+
+@itemize @bullet
+@item
+You must compile and link your program with profiling enabled.
+@xref{Compiling}.
+
+@item
+You must execute your program to generate a profile data file.
+@xref{Executing}.
+
+@item
+You must run @code{gprof} to analyze the profile data.
+@xref{Invoking}.
+@end itemize
+
+The next three chapters explain these steps in greater detail.
+
+Several forms of output are available from the analysis.
+
+The @dfn{flat profile} shows how much time your program spent in each function,
+and how many times that function was called. If you simply want to know
+which functions burn most of the cycles, it is stated concisely here.
+@xref{Flat Profile}.
+
+The @dfn{call graph} shows, for each function, which functions called it, which
+other functions it called, and how many times. There is also an estimate
+of how much time was spent in the subroutines of each function. This can
+suggest places where you might try to eliminate function calls that use a
+lot of time. @xref{Call Graph}.
+
+The @dfn{annotated source} listing is a copy of the program's
+source code, labeled with the number of times each line of the
+program was executed. @xref{Annotated Source}.
+
+To better understand how profiling works, you may wish to read
+a description of its implementation.
+@xref{Implementation}.
+
+@node Compiling
+@chapter Compiling a Program for Profiling
+
+The first step in generating profile information for your program is
+to compile and link it with profiling enabled.
+
+To compile a source file for profiling, specify the @samp{-pg} option when
+you run the compiler. (This is in addition to the options you normally
+use.)
+
+To link the program for profiling, if you use a compiler such as @code{cc}
+to do the linking, simply specify @samp{-pg} in addition to your usual
+options. The same option, @samp{-pg}, alters either compilation or linking
+to do what is necessary for profiling. Here are examples:
+
+@example
+cc -g -c myprog.c utils.c -pg
+cc -o myprog myprog.o utils.o -pg
+@end example
+
+The @samp{-pg} option also works with a command that both compiles and links:
+
+@example
+cc -o myprog myprog.c utils.c -g -pg
+@end example
+
+If you run the linker @code{ld} directly instead of through a compiler
+such as @code{cc}, you may have to specify a profiling startup file
+@file{gcrt0.o} as the first input file instead of the usual startup
+file @file{crt0.o}. In addition, you would probably want to
+specify the profiling C library, @file{libc_p.a}, by writing
+@samp{-lc_p} instead of the usual @samp{-lc}. This is not absolutely
+necessary, but doing this gives you number-of-calls information for
+standard library functions such as @code{read} and @code{open}. For
+example:
+
+@example
+ld -o myprog /lib/gcrt0.o myprog.o utils.o -lc_p
+@end example
+
+If you compile only some of the modules of the program with @samp{-pg}, you
+can still profile the program, but you won't get complete information about
+the modules that were compiled without @samp{-pg}. The only information
+you get for the functions in those modules is the total time spent in them;
+there is no record of how many times they were called, or from where. This
+will not affect the flat profile (except that the @code{calls} field for
+the functions will be blank), but will greatly reduce the usefulness of the
+call graph.
+
+If you wish to perform line-by-line profiling,
+you will also need to specify the @samp{-g} option,
+instructing the compiler to insert debugging symbols into the program
+that match program addresses to source code lines.
+@xref{Line-by-line}.
+
+In addition to the @samp{-pg} and @samp{-g} options,
+you may also wish to specify the @samp{-a} option when compiling.
+This will instrument
+the program to perform basic-block counting. As the program runs,
+it will count how many times it executed each branch of each @samp{if}
+statement, each iteration of each @samp{do} loop, etc. This will
+enable @code{gprof} to construct an annotated source code
+listing showing how many times each line of code was executed.
+
+@node Executing
+@chapter Executing the Program
+
+Once the program is compiled for profiling, you must run it in order to
+generate the information that @code{gprof} needs. Simply run the program
+as usual, using the normal arguments, file names, etc. The program should
+run normally, producing the same output as usual. It will, however, run
+somewhat slower than normal because of the time spent collecting and the
+writing the profile data.
+
+The way you run the program---the arguments and input that you give
+it---may have a dramatic effect on what the profile information shows. The
+profile data will describe the parts of the program that were activated for
+the particular input you use. For example, if the first command you give
+to your program is to quit, the profile data will show the time used in
+initialization and in cleanup, but not much else.
+
+Your program will write the profile data into a file called @file{gmon.out}
+just before exiting. If there is already a file called @file{gmon.out},
+its contents are overwritten. There is currently no way to tell the
+program to write the profile data under a different name, but you can rename
+the file afterward if you are concerned that it may be overwritten.
+
+In order to write the @file{gmon.out} file properly, your program must exit
+normally: by returning from @code{main} or by calling @code{exit}. Calling
+the low-level function @code{_exit} does not write the profile data, and
+neither does abnormal termination due to an unhandled signal.
+
+The @file{gmon.out} file is written in the program's @emph{current working
+directory} at the time it exits. This means that if your program calls
+@code{chdir}, the @file{gmon.out} file will be left in the last directory
+your program @code{chdir}'d to. If you don't have permission to write in
+this directory, the file is not written, and you will get an error message.
+
+Older versions of the @sc{gnu} profiling library may also write a file
+called @file{bb.out}. This file, if present, contains an human-readable
+listing of the basic-block execution counts. Unfortunately, the
+appearance of a human-readable @file{bb.out} means the basic-block
+counts didn't get written into @file{gmon.out}.
+The Perl script @code{bbconv.pl}, included with the @code{gprof}
+source distribution, will convert a @file{bb.out} file into
+a format readable by @code{gprof}.
+
+@node Invoking
+@chapter @code{gprof} Command Summary
+
+After you have a profile data file @file{gmon.out}, you can run @code{gprof}
+to interpret the information in it. The @code{gprof} program prints a
+flat profile and a call graph on standard output. Typically you would
+redirect the output of @code{gprof} into a file with @samp{>}.
+
+You run @code{gprof} like this:
+
+@smallexample
+gprof @var{options} [@var{executable-file} [@var{profile-data-files}@dots{}]] [> @var{outfile}]
+@end smallexample
+
+@noindent
+Here square-brackets indicate optional arguments.
+
+If you omit the executable file name, the file @file{a.out} is used. If
+you give no profile data file name, the file @file{gmon.out} is used. If
+any file is not in the proper format, or if the profile data file does not
+appear to belong to the executable file, an error message is printed.
+
+You can give more than one profile data file by entering all their names
+after the executable file name; then the statistics in all the data files
+are summed together.
+
+The order of these options does not matter.
+
+@menu
+* Output Options:: Controlling @code{gprof}'s output style
+* Analysis Options:: Controlling how @code{gprof} analyses its data
+* Miscellaneous Options::
+* Depricated Options:: Options you no longer need to use, but which
+ have been retained for compatibility
+* Symspecs:: Specifying functions to include or exclude
+@end menu
+
+@node Output Options,Analysis Options,,Invoking
+@section Output Options
+
+These options specify which of several output formats
+@code{gprof} should produce.
+
+Many of these options take an optional @dfn{symspec} to specify
+functions to be included or excluded. These options can be
+specified multiple times, with different symspecs, to include
+or exclude sets of symbols. @xref{Symspecs}.
+
+Specifying any of these options overrides the default (@samp{-p -q}),
+which prints a flat profile and call graph analysis
+for all functions.
+
+@table @code
+
+@item -A[@var{symspec}]
+@itemx --annotated-source[=@var{symspec}]
+The @samp{-A} option causes @code{gprof} to print annotated source code.
+If @var{symspec} is specified, print output only for matching symbols.
+@xref{Annotated Source}.
+
+@item -b
+@itemx --brief
+If the @samp{-b} option is given, @code{gprof} doesn't print the
+verbose blurbs that try to explain the meaning of all of the fields in
+the tables. This is useful if you intend to print out the output, or
+are tired of seeing the blurbs.
+
+@item -C[@var{symspec}]
+@itemx --exec-counts[=@var{symspec}]
+The @samp{-C} option causes @code{gprof} to
+print a tally of functions and the number of times each was called.
+If @var{symspec} is specified, print tally only for matching symbols.
+
+If the profile data file contains basic-block count records, specifing
+the @samp{-l} option, along with @samp{-C}, will cause basic-block
+execution counts to be tallied and displayed.
+
+@item -i
+@itemx --file-info
+The @samp{-i} option causes @code{gprof} to display summary information
+about the profile data file(s) and then exit. The number of histogram,
+call graph, and basic-block count records is displayed.
+
+@item -I @var{dirs}
+@itemx --directory-path=@var{dirs}
+The @samp{-I} option specifies a list of search directories in
+which to find source files. Environment variable @var{GPROF_PATH}
+can also be used to convery this information.
+Used mostly for annotated source output.
+
+@item -J[@var{symspec}]
+@itemx --no-annotated-source[=@var{symspec}]
+The @samp{-J} option causes @code{gprof} not to
+print annotated source code.
+If @var{symspec} is specified, @code{gprof} prints annotated source,
+but excludes matching symbols.
+
+@item -L
+@itemx --print-path
+Normally, source filenames are printed with the path
+component suppressed. The @samp{-L} option causes @code{gprof}
+to print the full pathname of
+source filenames, which is determined
+from symbolic debugging information in the image file
+and is relative to the directory in which the compiler
+was invoked.
+
+@item -p[@var{symspec}]
+@itemx --flat-profile[=@var{symspec}]
+The @samp{-p} option causes @code{gprof} to print a flat profile.
+If @var{symspec} is specified, print flat profile only for matching symbols.
+@xref{Flat Profile}.
+
+@item -P[@var{symspec}]
+@itemx --no-flat-profile[=@var{symspec}]
+The @samp{-P} option causes @code{gprof} to suppress printing a flat profile.
+If @var{symspec} is specified, @code{gprof} prints a flat profile,
+but excludes matching symbols.
+
+@item -q[@var{symspec}]
+@itemx --graph[=@var{symspec}]
+The @samp{-q} option causes @code{gprof} to print the call graph analysis.
+If @var{symspec} is specified, print call graph only for matching symbols
+and their children.
+@xref{Call Graph}.
+
+@item -Q[@var{symspec}]
+@itemx --no-graph[=@var{symspec}]
+The @samp{-Q} option causes @code{gprof} to suppress printing the
+call graph.
+If @var{symspec} is specified, @code{gprof} prints a call graph,
+but excludes matching symbols.
+
+@item -y
+@itemx --separate-files
+This option affects annotated source output only.
+Normally, gprof prints annotated source files
+to standard-output. If this option is specified,
+annotated source for a file named @file{path/filename}
+is generated in the file @file{filename-ann}.
+
+@item -Z[@var{symspec}]
+@itemx --no-exec-counts[=@var{symspec}]
+The @samp{-Z} option causes @code{gprof} not to
+print a tally of functions and the number of times each was called.
+If @var{symspec} is specified, print tally, but exclude matching symbols.
+
+@item --function-ordering
+The @samp{--function-ordering} option causes @code{gprof} to print a
+suggested function ordering for the program based on profiling data.
+This option suggests an ordering which may improve paging, tlb and
+cache behavior for the program on systems which support arbitrary
+ordering of functions in an executable.
+
+The exact details of how to force the linker to place functions
+in a particular order is system dependent and out of the scope of this
+manual.
+
+@item --file-ordering @var{map_file}
+The @samp{--file-ordering} option causes @code{gprof} to print a
+suggested .o link line ordering for the program based on profiling data.
+This option suggests an ordering which may improve paging, tlb and
+cache behavior for the program on systems which do not support arbitrary
+ordering of functions in an executable.
+
+Use of the @samp{-a} argument is highly recommended with this option.
+
+The @var{map_file} argument is a pathname to a file which provides
+function name to object file mappings. The format of the file is similar to
+the output of the program @code{nm}.
+
+@smallexample
+@group
+c-parse.o:00000000 T yyparse
+c-parse.o:00000004 C yyerrflag
+c-lang.o:00000000 T maybe_objc_method_name
+c-lang.o:00000000 T print_lang_statistics
+c-lang.o:00000000 T recognize_objc_keyword
+c-decl.o:00000000 T print_lang_identifier
+c-decl.o:00000000 T print_lang_type
+@dots{}
+
+@end group
+@end smallexample
+
+GNU @code{nm} @samp{--extern-only} @samp{--defined-only} @samp{-v} @samp{--print-file-name} can be used to create @var{map_file}.
+
+@item -T
+@itemx --traditional
+The @samp{-T} option causes @code{gprof} to print its output in
+``traditional'' BSD style.
+
+@item -w @var{width}
+@itemx --width=@var{width}
+Sets width of output lines to @var{width}.
+Currently only used when printing the function index at the bottom
+of the call graph.
+
+@item -x
+@itemx --all-lines
+This option affects annotated source output only.
+By default, only the lines at the beginning of a basic-block
+are annotated. If this option is specified, every line in
+a basic-block is annotated by repeating the annotation for the
+first line. This behavior is similar to @code{tcov}'s @samp{-a}.
+
+@item --demangle
+@itemx --no-demangle
+These options control whether C++ symbol names should be demangled when
+printing output. The default is to demangle symbols. The
+@code{--no-demangle} option may be used to turn off demangling.
+
+@end table
+
+@node Analysis Options,Miscellaneous Options,Output Options,Invoking
+@section Analysis Options
+
+@table @code
+
+@item -a
+@itemx --no-static
+The @samp{-a} option causes @code{gprof} to suppress the printing of
+statically declared (private) functions. (These are functions whose
+names are not listed as global, and which are not visible outside the
+file/function/block where they were defined.) Time spent in these
+functions, calls to/from them, etc, will all be attributed to the
+function that was loaded directly before it in the executable file.
+@c This is compatible with Unix @code{gprof}, but a bad idea.
+This option affects both the flat profile and the call graph.
+
+@item -c
+@itemx --static-call-graph
+The @samp{-c} option causes the call graph of the program to be
+augmented by a heuristic which examines the text space of the object
+file and identifies function calls in the binary machine code.
+Since normal call graph records are only generated when functions are
+entered, this option identifies children that could have been called,
+but never were. Calls to functions that were not compiled with
+profiling enabled are also identified, but only if symbol table
+entries are present for them.
+Calls to dynamic library routines are typically @emph{not} found
+by this option.
+Parents or children identified via this heuristic
+are indicated in the call graph with call counts of @samp{0}.
+
+@item -D
+@itemx --ignore-non-functions
+The @samp{-D} option causes @code{gprof} to ignore symbols which
+are not known to be functions. This option will give more accurate
+profile data on systems where it is supported (Solaris and HPUX for
+example).
+
+@item -k @var{from}/@var{to}
+The @samp{-k} option allows you to delete from the call graph any arcs from
+symbols matching symspec @var{from} to those matching symspec @var{to}.
+
+@item -l
+@itemx --line
+The @samp{-l} option enables line-by-line profiling, which causes
+histogram hits to be charged to individual source code lines,
+instead of functions.
+If the program was compiled with basic-block counting enabled,
+this option will also identify how many times each line of
+code was executed.
+While line-by-line profiling can help isolate where in a large function
+a program is spending its time, it also significantly increases
+the running time of @code{gprof}, and magnifies statistical
+inaccuracies.
+@xref{Sampling Error}.
+
+@item -m @var{num}
+@itemx --min-count=@var{num}
+This option affects execution count output only.
+Symbols that are executed less than @var{num} times are suppressed.
+
+@item -n[@var{symspec}]
+@itemx --time[=@var{symspec}]
+The @samp{-n} option causes @code{gprof}, in its call graph analysis,
+to only propagate times for symbols matching @var{symspec}.
+
+@item -N[@var{symspec}]
+@itemx --no-time[=@var{symspec}]
+The @samp{-n} option causes @code{gprof}, in its call graph analysis,
+not to propagate times for symbols matching @var{symspec}.
+
+@item -z
+@itemx --display-unused-functions
+If you give the @samp{-z} option, @code{gprof} will mention all
+functions in the flat profile, even those that were never called, and
+that had no time spent in them. This is useful in conjunction with the
+@samp{-c} option for discovering which routines were never called.
+
+@end table
+
+@node Miscellaneous Options,Depricated Options,Analysis Options,Invoking
+@section Miscellaneous Options
+
+@table @code
+
+@item -d[@var{num}]
+@itemx --debug[=@var{num}]
+The @samp{-d @var{num}} option specifies debugging options.
+If @var{num} is not specified, enable all debugging.
+@xref{Debugging}.
+
+@item -O@var{name}
+@itemx --file-format=@var{name}
+Selects the format of the profile data files. Recognized formats are
+@samp{auto} (the default), @samp{bsd}, @samp{4.4bsd}, @samp{magic}, and
+@samp{prof} (not yet supported).
+
+@item -s
+@itemx --sum
+The @samp{-s} option causes @code{gprof} to summarize the information
+in the profile data files it read in, and write out a profile data
+file called @file{gmon.sum}, which contains all the information from
+the profile data files that @code{gprof} read in. The file @file{gmon.sum}
+may be one of the specified input files; the effect of this is to
+merge the data in the other input files into @file{gmon.sum}.
+
+Eventually you can run @code{gprof} again without @samp{-s} to analyze the
+cumulative data in the file @file{gmon.sum}.
+
+@item -v
+@itemx --version
+The @samp{-v} flag causes @code{gprof} to print the current version
+number, and then exit.
+
+@end table
+
+@node Depricated Options,Symspecs,Miscellaneous Options,Invoking
+@section Depricated Options
+
+@table @code
+
+These options have been replaced with newer versions that use symspecs.
+
+@item -e @var{function_name}
+The @samp{-e @var{function}} option tells @code{gprof} to not print
+information about the function @var{function_name} (and its
+children@dots{}) in the call graph. The function will still be listed
+as a child of any functions that call it, but its index number will be
+shown as @samp{[not printed]}. More than one @samp{-e} option may be
+given; only one @var{function_name} may be indicated with each @samp{-e}
+option.
+
+@item -E @var{function_name}
+The @code{-E @var{function}} option works like the @code{-e} option, but
+time spent in the function (and children who were not called from
+anywhere else), will not be used to compute the percentages-of-time for
+the call graph. More than one @samp{-E} option may be given; only one
+@var{function_name} may be indicated with each @samp{-E} option.
+
+@item -f @var{function_name}
+The @samp{-f @var{function}} option causes @code{gprof} to limit the
+call graph to the function @var{function_name} and its children (and
+their children@dots{}). More than one @samp{-f} option may be given;
+only one @var{function_name} may be indicated with each @samp{-f}
+option.
+
+@item -F @var{function_name}
+The @samp{-F @var{function}} option works like the @code{-f} option, but
+only time spent in the function and its children (and their
+children@dots{}) will be used to determine total-time and
+percentages-of-time for the call graph. More than one @samp{-F} option
+may be given; only one @var{function_name} may be indicated with each
+@samp{-F} option. The @samp{-F} option overrides the @samp{-E} option.
+
+@end table
+
+Note that only one function can be specified with each @code{-e},
+@code{-E}, @code{-f} or @code{-F} option. To specify more than one
+function, use multiple options. For example, this command:
+
+@example
+gprof -e boring -f foo -f bar myprogram > gprof.output
+@end example
+
+@noindent
+lists in the call graph all functions that were reached from either
+@code{foo} or @code{bar} and were not reachable from @code{boring}.
+
+@node Symspecs,,Depricated Options,Invoking
+@section Symspecs
+
+Many of the output options allow functions to be included or excluded
+using @dfn{symspecs} (symbol specifications), which observe the
+following syntax:
+
+@example
+ filename_containing_a_dot
+| funcname_not_containing_a_dot
+| linenumber
+| ( [ any_filename ] `:' ( any_funcname | linenumber ) )
+@end example
+
+Here are some sample symspecs:
+
+@table @samp
+@item main.c
+Selects everything in file @file{main.c}---the
+dot in the string tells gprof to interpret
+the string as a filename, rather than as
+a function name. To select a file whose
+name does not contain a dot, a trailing colon
+should be specified. For example, @samp{odd:} is
+interpreted as the file named @file{odd}.
+
+@item main
+Selects all functions named @samp{main}.
+
+Note that there may be multiple instances of the same function name
+because some of the definitions may be local (i.e., static). Unless a
+function name is unique in a program, you must use the colon notation
+explained below to specify a function from a specific source file.
+
+Sometimes, function names contain dots. In such cases, it is necessar
+to add a leading colon to the name. For example, @samp{:.mul} selects
+function @samp{.mul}.
+
+In some object file formats, symbols have a leading underscore. gprof
+will normally not print these underscores. However, you must use the
+underscore when you name a symbol in a symspec. You can use the
+@code{nm} program to see whether symbols have underscores for the object
+file format you are using.
+
+@item main.c:main
+Selects function @samp{main} in file @file{main.c}.
+
+@item main.c:134
+Selects line 134 in file @file{main.c}.
+@end table
+
+@node Output
+@chapter Interpreting @code{gprof}'s Output
+
+@code{gprof} can produce several different output styles, the
+most important of which are described below. The simplest output
+styles (file information, execution count, and function and file ordering)
+are not described here, but are documented with the respective options
+that trigger them.
+@xref{Output Options}.
+
+@menu
+* Flat Profile:: The flat profile shows how much time was spent
+ executing directly in each function.
+* Call Graph:: The call graph shows which functions called which
+ others, and how much time each function used
+ when its subroutine calls are included.
+* Line-by-line:: @code{gprof} can analyze individual source code lines
+* Annotated Source:: The annotated source listing displays source code
+ labeled with execution counts
+@end menu
+
+
+@node Flat Profile,Call Graph,,Output
+@section The Flat Profile
+@cindex flat profile
+
+The @dfn{flat profile} shows the total amount of time your program
+spent executing each function. Unless the @samp{-z} option is given,
+functions with no apparent time spent in them, and no apparent calls
+to them, are not mentioned. Note that if a function was not compiled
+for profiling, and didn't run long enough to show up on the program
+counter histogram, it will be indistinguishable from a function that
+was never called.
+
+This is part of a flat profile for a small program:
+
+@smallexample
+@group
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls ms/call ms/call name
+ 33.34 0.02 0.02 7208 0.00 0.00 open
+ 16.67 0.03 0.01 244 0.04 0.12 offtime
+ 16.67 0.04 0.01 8 1.25 1.25 memccpy
+ 16.67 0.05 0.01 7 1.43 1.43 write
+ 16.67 0.06 0.01 mcount
+ 0.00 0.06 0.00 236 0.00 0.00 tzset
+ 0.00 0.06 0.00 192 0.00 0.00 tolower
+ 0.00 0.06 0.00 47 0.00 0.00 strlen
+ 0.00 0.06 0.00 45 0.00 0.00 strchr
+ 0.00 0.06 0.00 1 0.00 50.00 main
+ 0.00 0.06 0.00 1 0.00 0.00 memcpy
+ 0.00 0.06 0.00 1 0.00 10.11 print
+ 0.00 0.06 0.00 1 0.00 0.00 profil
+ 0.00 0.06 0.00 1 0.00 50.00 report
+@dots{}
+@end group
+@end smallexample
+
+@noindent
+The functions are sorted by first by decreasing run-time spent in them,
+then by decreasing number of calls, then alphabetically by name. The
+functions @samp{mcount} and @samp{profil} are part of the profiling
+aparatus and appear in every flat profile; their time gives a measure of
+the amount of overhead due to profiling.
+
+Just before the column headers, a statement appears indicating
+how much time each sample counted as.
+This @dfn{sampling period} estimates the margin of error in each of the time
+figures. A time figure that is not much larger than this is not
+reliable. In this example, each sample counted as 0.01 seconds,
+suggesting a 100 Hz sampling rate.
+The program's total execution time was 0.06
+seconds, as indicated by the @samp{cumulative seconds} field. Since
+each sample counted for 0.01 seconds, this means only six samples
+were taken during the run. Two of the samples occured while the
+program was in the @samp{open} function, as indicated by the
+@samp{self seconds} field. Each of the other four samples
+occured one each in @samp{offtime}, @samp{memccpy}, @samp{write},
+and @samp{mcount}.
+Since only six samples were taken, none of these values can
+be regarded as particularly reliable.
+In another run,
+the @samp{self seconds} field for
+@samp{mcount} might well be @samp{0.00} or @samp{0.02}.
+@xref{Sampling Error}, for a complete discussion.
+
+The remaining functions in the listing (those whose
+@samp{self seconds} field is @samp{0.00}) didn't appear
+in the histogram samples at all. However, the call graph
+indicated that they were called, so therefore they are listed,
+sorted in decreasing order by the @samp{calls} field.
+Clearly some time was spent executing these functions,
+but the paucity of histogram samples prevents any
+determination of how much time each took.
+
+Here is what the fields in each line mean:
+
+@table @code
+@item % time
+This is the percentage of the total execution time your program spent
+in this function. These should all add up to 100%.
+
+@item cumulative seconds
+This is the cumulative total number of seconds the computer spent
+executing this functions, plus the time spent in all the functions
+above this one in this table.
+
+@item self seconds
+This is the number of seconds accounted for by this function alone.
+The flat profile listing is sorted first by this number.
+
+@item calls
+This is the total number of times the function was called. If the
+function was never called, or the number of times it was called cannot
+be determined (probably because the function was not compiled with
+profiling enabled), the @dfn{calls} field is blank.
+
+@item self ms/call
+This represents the average number of milliseconds spent in this
+function per call, if this function is profiled. Otherwise, this field
+is blank for this function.
+
+@item total ms/call
+This represents the average number of milliseconds spent in this
+function and its descendants per call, if this function is profiled.
+Otherwise, this field is blank for this function.
+This is the only field in the flat profile that uses call graph analysis.
+
+@item name
+This is the name of the function. The flat profile is sorted by this
+field alphabetically after the @dfn{self seconds} and @dfn{calls}
+fields are sorted.
+@end table
+
+@node Call Graph,Line-by-line,Flat Profile,Output
+@section The Call Graph
+@cindex call graph
+
+The @dfn{call graph} shows how much time was spent in each function
+and its children. From this information, you can find functions that,
+while they themselves may not have used much time, called other
+functions that did use unusual amounts of time.
+
+Here is a sample call from a small program. This call came from the
+same @code{gprof} run as the flat profile example in the previous
+chapter.
+
+@smallexample
+@group
+granularity: each sample hit covers 2 byte(s) for 20.00% of 0.05 seconds
+
+index % time self children called name
+ <spontaneous>
+[1] 100.0 0.00 0.05 start [1]
+ 0.00 0.05 1/1 main [2]
+ 0.00 0.00 1/2 on_exit [28]
+ 0.00 0.00 1/1 exit [59]
+-----------------------------------------------
+ 0.00 0.05 1/1 start [1]
+[2] 100.0 0.00 0.05 1 main [2]
+ 0.00 0.05 1/1 report [3]
+-----------------------------------------------
+ 0.00 0.05 1/1 main [2]
+[3] 100.0 0.00 0.05 1 report [3]
+ 0.00 0.03 8/8 timelocal [6]
+ 0.00 0.01 1/1 print [9]
+ 0.00 0.01 9/9 fgets [12]
+ 0.00 0.00 12/34 strncmp <cycle 1> [40]
+ 0.00 0.00 8/8 lookup [20]
+ 0.00 0.00 1/1 fopen [21]
+ 0.00 0.00 8/8 chewtime [24]
+ 0.00 0.00 8/16 skipspace [44]
+-----------------------------------------------
+[4] 59.8 0.01 0.02 8+472 <cycle 2 as a whole> [4]
+ 0.01 0.02 244+260 offtime <cycle 2> [7]
+ 0.00 0.00 236+1 tzset <cycle 2> [26]
+-----------------------------------------------
+@end group
+@end smallexample
+
+The lines full of dashes divide this table into @dfn{entries}, one for each
+function. Each entry has one or more lines.
+
+In each entry, the primary line is the one that starts with an index number
+in square brackets. The end of this line says which function the entry is
+for. The preceding lines in the entry describe the callers of this
+function and the following lines describe its subroutines (also called
+@dfn{children} when we speak of the call graph).
+
+The entries are sorted by time spent in the function and its subroutines.
+
+The internal profiling function @code{mcount} (@pxref{Flat Profile})
+is never mentioned in the call graph.
+
+@menu
+* Primary:: Details of the primary line's contents.
+* Callers:: Details of caller-lines' contents.
+* Subroutines:: Details of subroutine-lines' contents.
+* Cycles:: When there are cycles of recursion,
+ such as @code{a} calls @code{b} calls @code{a}@dots{}
+@end menu
+
+@node Primary
+@subsection The Primary Line
+
+The @dfn{primary line} in a call graph entry is the line that
+describes the function which the entry is about and gives the overall
+statistics for this function.
+
+For reference, we repeat the primary line from the entry for function
+@code{report} in our main example, together with the heading line that
+shows the names of the fields:
+
+@smallexample
+@group
+index % time self children called name
+@dots{}
+[3] 100.0 0.00 0.05 1 report [3]
+@end group
+@end smallexample
+
+Here is what the fields in the primary line mean:
+
+@table @code
+@item index
+Entries are numbered with consecutive integers. Each function
+therefore has an index number, which appears at the beginning of its
+primary line.
+
+Each cross-reference to a function, as a caller or subroutine of
+another, gives its index number as well as its name. The index number
+guides you if you wish to look for the entry for that function.
+
+@item % time
+This is the percentage of the total time that was spent in this
+function, including time spent in subroutines called from this
+function.
+
+The time spent in this function is counted again for the callers of
+this function. Therefore, adding up these percentages is meaningless.
+
+@item self
+This is the total amount of time spent in this function. This
+should be identical to the number printed in the @code{seconds} field
+for this function in the flat profile.
+
+@item children
+This is the total amount of time spent in the subroutine calls made by
+this function. This should be equal to the sum of all the @code{self}
+and @code{children} entries of the children listed directly below this
+function.
+
+@item called
+This is the number of times the function was called.
+
+If the function called itself recursively, there are two numbers,
+separated by a @samp{+}. The first number counts non-recursive calls,
+and the second counts recursive calls.
+
+In the example above, the function @code{report} was called once from
+@code{main}.
+
+@item name
+This is the name of the current function. The index number is
+repeated after it.
+
+If the function is part of a cycle of recursion, the cycle number is
+printed between the function's name and the index number
+(@pxref{Cycles}). For example, if function @code{gnurr} is part of
+cycle number one, and has index number twelve, its primary line would
+be end like this:
+
+@example
+gnurr <cycle 1> [12]
+@end example
+@end table
+
+@node Callers, Subroutines, Primary, Call Graph
+@subsection Lines for a Function's Callers
+
+A function's entry has a line for each function it was called by.
+These lines' fields correspond to the fields of the primary line, but
+their meanings are different because of the difference in context.
+
+For reference, we repeat two lines from the entry for the function
+@code{report}, the primary line and one caller-line preceding it, together
+with the heading line that shows the names of the fields:
+
+@smallexample
+index % time self children called name
+@dots{}
+ 0.00 0.05 1/1 main [2]
+[3] 100.0 0.00 0.05 1 report [3]
+@end smallexample
+
+Here are the meanings of the fields in the caller-line for @code{report}
+called from @code{main}:
+
+@table @code
+@item self
+An estimate of the amount of time spent in @code{report} itself when it was
+called from @code{main}.
+
+@item children
+An estimate of the amount of time spent in subroutines of @code{report}
+when @code{report} was called from @code{main}.
+
+The sum of the @code{self} and @code{children} fields is an estimate
+of the amount of time spent within calls to @code{report} from @code{main}.
+
+@item called
+Two numbers: the number of times @code{report} was called from @code{main},
+followed by the total number of nonrecursive calls to @code{report} from
+all its callers.
+
+@item name and index number
+The name of the caller of @code{report} to which this line applies,
+followed by the caller's index number.
+
+Not all functions have entries in the call graph; some
+options to @code{gprof} request the omission of certain functions.
+When a caller has no entry of its own, it still has caller-lines
+in the entries of the functions it calls.
+
+If the caller is part of a recursion cycle, the cycle number is
+printed between the name and the index number.
+@end table
+
+If the identity of the callers of a function cannot be determined, a
+dummy caller-line is printed which has @samp{<spontaneous>} as the
+``caller's name'' and all other fields blank. This can happen for
+signal handlers.
+@c What if some calls have determinable callers' names but not all?
+@c FIXME - still relevant?
+
+@node Subroutines, Cycles, Callers, Call Graph
+@subsection Lines for a Function's Subroutines
+
+A function's entry has a line for each of its subroutines---in other
+words, a line for each other function that it called. These lines'
+fields correspond to the fields of the primary line, but their meanings
+are different because of the difference in context.
+
+For reference, we repeat two lines from the entry for the function
+@code{main}, the primary line and a line for a subroutine, together
+with the heading line that shows the names of the fields:
+
+@smallexample
+index % time self children called name
+@dots{}
+[2] 100.0 0.00 0.05 1 main [2]
+ 0.00 0.05 1/1 report [3]
+@end smallexample
+
+Here are the meanings of the fields in the subroutine-line for @code{main}
+calling @code{report}:
+
+@table @code
+@item self
+An estimate of the amount of time spent directly within @code{report}
+when @code{report} was called from @code{main}.
+
+@item children
+An estimate of the amount of time spent in subroutines of @code{report}
+when @code{report} was called from @code{main}.
+
+The sum of the @code{self} and @code{children} fields is an estimate
+of the total time spent in calls to @code{report} from @code{main}.
+
+@item called
+Two numbers, the number of calls to @code{report} from @code{main}
+followed by the total number of nonrecursive calls to @code{report}.
+This ratio is used to determine how much of @code{report}'s @code{self}
+and @code{children} time gets credited to @code{main}.
+@xref{Assumptions}.
+
+@item name
+The name of the subroutine of @code{main} to which this line applies,
+followed by the subroutine's index number.
+
+If the caller is part of a recursion cycle, the cycle number is
+printed between the name and the index number.
+@end table
+
+@node Cycles,, Subroutines, Call Graph
+@subsection How Mutually Recursive Functions Are Described
+@cindex cycle
+@cindex recursion cycle
+
+The graph may be complicated by the presence of @dfn{cycles of
+recursion} in the call graph. A cycle exists if a function calls
+another function that (directly or indirectly) calls (or appears to
+call) the original function. For example: if @code{a} calls @code{b},
+and @code{b} calls @code{a}, then @code{a} and @code{b} form a cycle.
+
+Whenever there are call paths both ways between a pair of functions, they
+belong to the same cycle. If @code{a} and @code{b} call each other and
+@code{b} and @code{c} call each other, all three make one cycle. Note that
+even if @code{b} only calls @code{a} if it was not called from @code{a},
+@code{gprof} cannot determine this, so @code{a} and @code{b} are still
+considered a cycle.
+
+The cycles are numbered with consecutive integers. When a function
+belongs to a cycle, each time the function name appears in the call graph
+it is followed by @samp{<cycle @var{number}>}.
+
+The reason cycles matter is that they make the time values in the call
+graph paradoxical. The ``time spent in children'' of @code{a} should
+include the time spent in its subroutine @code{b} and in @code{b}'s
+subroutines---but one of @code{b}'s subroutines is @code{a}! How much of
+@code{a}'s time should be included in the children of @code{a}, when
+@code{a} is indirectly recursive?
+
+The way @code{gprof} resolves this paradox is by creating a single entry
+for the cycle as a whole. The primary line of this entry describes the
+total time spent directly in the functions of the cycle. The
+``subroutines'' of the cycle are the individual functions of the cycle, and
+all other functions that were called directly by them. The ``callers'' of
+the cycle are the functions, outside the cycle, that called functions in
+the cycle.
+
+Here is an example portion of a call graph which shows a cycle containing
+functions @code{a} and @code{b}. The cycle was entered by a call to
+@code{a} from @code{main}; both @code{a} and @code{b} called @code{c}.
+
+@smallexample
+index % time self children called name
+----------------------------------------
+ 1.77 0 1/1 main [2]
+[3] 91.71 1.77 0 1+5 <cycle 1 as a whole> [3]
+ 1.02 0 3 b <cycle 1> [4]
+ 0.75 0 2 a <cycle 1> [5]
+----------------------------------------
+ 3 a <cycle 1> [5]
+[4] 52.85 1.02 0 0 b <cycle 1> [4]
+ 2 a <cycle 1> [5]
+ 0 0 3/6 c [6]
+----------------------------------------
+ 1.77 0 1/1 main [2]
+ 2 b <cycle 1> [4]
+[5] 38.86 0.75 0 1 a <cycle 1> [5]
+ 3 b <cycle 1> [4]
+ 0 0 3/6 c [6]
+----------------------------------------
+@end smallexample
+
+@noindent
+(The entire call graph for this program contains in addition an entry for
+@code{main}, which calls @code{a}, and an entry for @code{c}, with callers
+@code{a} and @code{b}.)
+
+@smallexample
+index % time self children called name
+ <spontaneous>
+[1] 100.00 0 1.93 0 start [1]
+ 0.16 1.77 1/1 main [2]
+----------------------------------------
+ 0.16 1.77 1/1 start [1]
+[2] 100.00 0.16 1.77 1 main [2]
+ 1.77 0 1/1 a <cycle 1> [5]
+----------------------------------------
+ 1.77 0 1/1 main [2]
+[3] 91.71 1.77 0 1+5 <cycle 1 as a whole> [3]
+ 1.02 0 3 b <cycle 1> [4]
+ 0.75 0 2 a <cycle 1> [5]
+ 0 0 6/6 c [6]
+----------------------------------------
+ 3 a <cycle 1> [5]
+[4] 52.85 1.02 0 0 b <cycle 1> [4]
+ 2 a <cycle 1> [5]
+ 0 0 3/6 c [6]
+----------------------------------------
+ 1.77 0 1/1 main [2]
+ 2 b <cycle 1> [4]
+[5] 38.86 0.75 0 1 a <cycle 1> [5]
+ 3 b <cycle 1> [4]
+ 0 0 3/6 c [6]
+----------------------------------------
+ 0 0 3/6 b <cycle 1> [4]
+ 0 0 3/6 a <cycle 1> [5]
+[6] 0.00 0 0 6 c [6]
+----------------------------------------
+@end smallexample
+
+The @code{self} field of the cycle's primary line is the total time
+spent in all the functions of the cycle. It equals the sum of the
+@code{self} fields for the individual functions in the cycle, found
+in the entry in the subroutine lines for these functions.
+
+The @code{children} fields of the cycle's primary line and subroutine lines
+count only subroutines outside the cycle. Even though @code{a} calls
+@code{b}, the time spent in those calls to @code{b} is not counted in
+@code{a}'s @code{children} time. Thus, we do not encounter the problem of
+what to do when the time in those calls to @code{b} includes indirect
+recursive calls back to @code{a}.
+
+The @code{children} field of a caller-line in the cycle's entry estimates
+the amount of time spent @emph{in the whole cycle}, and its other
+subroutines, on the times when that caller called a function in the cycle.
+
+The @code{calls} field in the primary line for the cycle has two numbers:
+first, the number of times functions in the cycle were called by functions
+outside the cycle; second, the number of times they were called by
+functions in the cycle (including times when a function in the cycle calls
+itself). This is a generalization of the usual split into nonrecursive and
+recursive calls.
+
+The @code{calls} field of a subroutine-line for a cycle member in the
+cycle's entry says how many time that function was called from functions in
+the cycle. The total of all these is the second number in the primary line's
+@code{calls} field.
+
+In the individual entry for a function in a cycle, the other functions in
+the same cycle can appear as subroutines and as callers. These lines show
+how many times each function in the cycle called or was called from each other
+function in the cycle. The @code{self} and @code{children} fields in these
+lines are blank because of the difficulty of defining meanings for them
+when recursion is going on.
+
+@node Line-by-line,Annotated Source,Call Graph,Output
+@section Line-by-line Profiling
+
+@code{gprof}'s @samp{-l} option causes the program to perform
+@dfn{line-by-line} profiling. In this mode, histogram
+samples are assigned not to functions, but to individual
+lines of source code. The program usually must be compiled
+with a @samp{-g} option, in addition to @samp{-pg}, in order
+to generate debugging symbols for tracking source code lines.
+
+The flat profile is the most useful output table
+in line-by-line mode.
+The call graph isn't as useful as normal, since
+the current version of @code{gprof} does not propagate
+call graph arcs from source code lines to the enclosing function.
+The call graph does, however, show each line of code
+that called each function, along with a count.
+
+Here is a section of @code{gprof}'s output, without line-by-line profiling.
+Note that @code{ct_init} accounted for four histogram hits, and
+13327 calls to @code{init_block}.
+
+@smallexample
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls us/call us/call name
+ 30.77 0.13 0.04 6335 6.31 6.31 ct_init
+
+
+ Call graph (explanation follows)
+
+
+granularity: each sample hit covers 4 byte(s) for 7.69% of 0.13 seconds
+
+index % time self children called name
+
+ 0.00 0.00 1/13496 name_too_long
+ 0.00 0.00 40/13496 deflate
+ 0.00 0.00 128/13496 deflate_fast
+ 0.00 0.00 13327/13496 ct_init
+[7] 0.0 0.00 0.00 13496 init_block
+
+@end smallexample
+
+Now let's look at some of @code{gprof}'s output from the same program run,
+this time with line-by-line profiling enabled. Note that @code{ct_init}'s
+four histogram hits are broken down into four lines of source code - one hit
+occured on each of lines 349, 351, 382 and 385. In the call graph,
+note how
+@code{ct_init}'s 13327 calls to @code{init_block} are broken down
+into one call from line 396, 3071 calls from line 384, 3730 calls
+from line 385, and 6525 calls from 387.
+
+@smallexample
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self
+ time seconds seconds calls name
+ 7.69 0.10 0.01 ct_init (trees.c:349)
+ 7.69 0.11 0.01 ct_init (trees.c:351)
+ 7.69 0.12 0.01 ct_init (trees.c:382)
+ 7.69 0.13 0.01 ct_init (trees.c:385)
+
+
+ Call graph (explanation follows)
+
+
+granularity: each sample hit covers 4 byte(s) for 7.69% of 0.13 seconds
+
+ % time self children called name
+
+ 0.00 0.00 1/13496 name_too_long (gzip.c:1440)
+ 0.00 0.00 1/13496 deflate (deflate.c:763)
+ 0.00 0.00 1/13496 ct_init (trees.c:396)
+ 0.00 0.00 2/13496 deflate (deflate.c:727)
+ 0.00 0.00 4/13496 deflate (deflate.c:686)
+ 0.00 0.00 5/13496 deflate (deflate.c:675)
+ 0.00 0.00 12/13496 deflate (deflate.c:679)
+ 0.00 0.00 16/13496 deflate (deflate.c:730)
+ 0.00 0.00 128/13496 deflate_fast (deflate.c:654)
+ 0.00 0.00 3071/13496 ct_init (trees.c:384)
+ 0.00 0.00 3730/13496 ct_init (trees.c:385)
+ 0.00 0.00 6525/13496 ct_init (trees.c:387)
+[6] 0.0 0.00 0.00 13496 init_block (trees.c:408)
+
+@end smallexample
+
+
+@node Annotated Source,,Line-by-line,Output
+@section The Annotated Source Listing
+
+@code{gprof}'s @samp{-A} option triggers an annotated source listing,
+which lists the program's source code, each function labeled with the
+number of times it was called. You may also need to specify the
+@samp{-I} option, if @code{gprof} can't find the source code files.
+
+Compiling with @samp{gcc @dots{} -g -pg -a} augments your program
+with basic-block counting code, in addition to function counting code.
+This enables @code{gprof} to determine how many times each line
+of code was exeucted.
+For example, consider the following function, taken from gzip,
+with line numbers added:
+
+@smallexample
+ 1 ulg updcrc(s, n)
+ 2 uch *s;
+ 3 unsigned n;
+ 4 @{
+ 5 register ulg c;
+ 6
+ 7 static ulg crc = (ulg)0xffffffffL;
+ 8
+ 9 if (s == NULL) @{
+10 c = 0xffffffffL;
+11 @} else @{
+12 c = crc;
+13 if (n) do @{
+14 c = crc_32_tab[...];
+15 @} while (--n);
+16 @}
+17 crc = c;
+18 return c ^ 0xffffffffL;
+19 @}
+
+@end smallexample
+
+@code{updcrc} has at least five basic-blocks.
+One is the function itself. The
+@code{if} statement on line 9 generates two more basic-blocks, one
+for each branch of the @code{if}. A fourth basic-block results from
+the @code{if} on line 13, and the contents of the @code{do} loop form
+the fifth basic-block. The compiler may also generate additional
+basic-blocks to handle various special cases.
+
+A program augmented for basic-block counting can be analyzed with
+@code{gprof -l -A}. I also suggest use of the @samp{-x} option,
+which ensures that each line of code is labeled at least once.
+Here is @code{updcrc}'s
+annotated source listing for a sample @code{gzip} run:
+
+@smallexample
+ ulg updcrc(s, n)
+ uch *s;
+ unsigned n;
+ 2 ->@{
+ register ulg c;
+
+ static ulg crc = (ulg)0xffffffffL;
+
+ 2 -> if (s == NULL) @{
+ 1 -> c = 0xffffffffL;
+ 1 -> @} else @{
+ 1 -> c = crc;
+ 1 -> if (n) do @{
+ 26312 -> c = crc_32_tab[...];
+26312,1,26311 -> @} while (--n);
+ @}
+ 2 -> crc = c;
+ 2 -> return c ^ 0xffffffffL;
+ 2 ->@}
+@end smallexample
+
+In this example, the function was called twice, passing once through
+each branch of the @code{if} statement. The body of the @code{do}
+loop was executed a total of 26312 times. Note how the @code{while}
+statement is annotated. It began execution 26312 times, once for
+each iteration through the loop. One of those times (the last time)
+it exited, while it branched back to the beginning of the loop 26311 times.
+
+@node Inaccuracy
+@chapter Inaccuracy of @code{gprof} Output
+
+@menu
+* Sampling Error:: Statistical margins of error
+* Assumptions:: Estimating children times
+@end menu
+
+@node Sampling Error,Assumptions,,Inaccuracy
+@section Statistical Sampling Error
+
+The run-time figures that @code{gprof} gives you are based on a sampling
+process, so they are subject to statistical inaccuracy. If a function runs
+only a small amount of time, so that on the average the sampling process
+ought to catch that function in the act only once, there is a pretty good
+chance it will actually find that function zero times, or twice.
+
+By contrast, the number-of-calls and basic-block figures
+are derived by counting, not
+sampling. They are completely accurate and will not vary from run to run
+if your program is deterministic.
+
+The @dfn{sampling period} that is printed at the beginning of the flat
+profile says how often samples are taken. The rule of thumb is that a
+run-time figure is accurate if it is considerably bigger than the sampling
+period.
+
+The actual amount of error can be predicted.
+For @var{n} samples, the @emph{expected} error
+is the square-root of @var{n}. For example,
+if the sampling period is 0.01 seconds and @code{foo}'s run-time is 1 second,
+@var{n} is 100 samples (1 second/0.01 seconds), sqrt(@var{n}) is 10 samples, so
+the expected error in @code{foo}'s run-time is 0.1 seconds (10*0.01 seconds),
+or ten percent of the observed value.
+Again, if the sampling period is 0.01 seconds and @code{bar}'s run-time is
+100 seconds, @var{n} is 10000 samples, sqrt(@var{n}) is 100 samples, so
+the expected error in @code{bar}'s run-time is 1 second,
+or one percent of the observed value.
+It is likely to
+vary this much @emph{on the average} from one profiling run to the next.
+(@emph{Sometimes} it will vary more.)
+
+This does not mean that a small run-time figure is devoid of information.
+If the program's @emph{total} run-time is large, a small run-time for one
+function does tell you that that function used an insignificant fraction of
+the whole program's time. Usually this means it is not worth optimizing.
+
+One way to get more accuracy is to give your program more (but similar)
+input data so it will take longer. Another way is to combine the data from
+several runs, using the @samp{-s} option of @code{gprof}. Here is how:
+
+@enumerate
+@item
+Run your program once.
+
+@item
+Issue the command @samp{mv gmon.out gmon.sum}.
+
+@item
+Run your program again, the same as before.
+
+@item
+Merge the new data in @file{gmon.out} into @file{gmon.sum} with this command:
+
+@example
+gprof -s @var{executable-file} gmon.out gmon.sum
+@end example
+
+@item
+Repeat the last two steps as often as you wish.
+
+@item
+Analyze the cumulative data using this command:
+
+@example
+gprof @var{executable-file} gmon.sum > @var{output-file}
+@end example
+@end enumerate
+
+@node Assumptions,,Sampling Error,Inaccuracy
+@section Estimating @code{children} Times
+
+Some of the figures in the call graph are estimates---for example, the
+@code{children} time values and all the the time figures in caller and
+subroutine lines.
+
+There is no direct information about these measurements in the profile
+data itself. Instead, @code{gprof} estimates them by making an assumption
+about your program that might or might not be true.
+
+The assumption made is that the average time spent in each call to any
+function @code{foo} is not correlated with who called @code{foo}. If
+@code{foo} used 5 seconds in all, and 2/5 of the calls to @code{foo} came
+from @code{a}, then @code{foo} contributes 2 seconds to @code{a}'s
+@code{children} time, by assumption.
+
+This assumption is usually true enough, but for some programs it is far
+from true. Suppose that @code{foo} returns very quickly when its argument
+is zero; suppose that @code{a} always passes zero as an argument, while
+other callers of @code{foo} pass other arguments. In this program, all the
+time spent in @code{foo} is in the calls from callers other than @code{a}.
+But @code{gprof} has no way of knowing this; it will blindly and
+incorrectly charge 2 seconds of time in @code{foo} to the children of
+@code{a}.
+
+@c FIXME - has this been fixed?
+We hope some day to put more complete data into @file{gmon.out}, so that
+this assumption is no longer needed, if we can figure out how. For the
+nonce, the estimated figures are usually more useful than misleading.
+
+@node How do I?
+@chapter Answers to Common Questions
+
+@table @asis
+@item How do I find which lines in my program were executed the most times?
+
+Compile your program with basic-block counting enabled, run it, then
+use the following pipeline:
+
+@example
+gprof -l -C @var{objfile} | sort -k 3 -n -r
+@end example
+
+This listing will show you the lines in your code executed most often,
+but not necessarily those that consumed the most time.
+
+@item How do I find which lines in my program called a particular function?
+
+Use @code{gprof -l} and lookup the function in the call graph.
+The callers will be broken down by function and line number.
+
+@item How do I analyze a program that runs for less than a second?
+
+Try using a shell script like this one:
+
+@example
+for i in `seq 1 100`; do
+ fastprog
+ mv gmon.out gmon.out.$i
+done
+
+gprof -s fastprog gmon.out.*
+
+gprof fastprog gmon.sum
+@end example
+
+If your program is completely deterministic, all the call counts
+will be simple multiples of 100 (i.e. a function called once in
+each run will appear with a call count of 100).
+
+@end table
+
+@node Incompatibilities
+@chapter Incompatibilities with Unix @code{gprof}
+
+@sc{gnu} @code{gprof} and Berkeley Unix @code{gprof} use the same data
+file @file{gmon.out}, and provide essentially the same information. But
+there are a few differences.
+
+@itemize @bullet
+@item
+@sc{gnu} @code{gprof} uses a new, generalized file format with support
+for basic-block execution counts and non-realtime histograms. A magic
+cookie and version number allows @code{gprof} to easily identify
+new style files. Old BSD-style files can still be read.
+@xref{File Format}.
+
+@item
+For a recursive function, Unix @code{gprof} lists the function as a
+parent and as a child, with a @code{calls} field that lists the number
+of recursive calls. @sc{gnu} @code{gprof} omits these lines and puts
+the number of recursive calls in the primary line.
+
+@item
+When a function is suppressed from the call graph with @samp{-e}, @sc{gnu}
+@code{gprof} still lists it as a subroutine of functions that call it.
+
+@item
+@sc{gnu} @code{gprof} accepts the @samp{-k} with its argument
+in the form @samp{from/to}, instead of @samp{from to}.
+
+@item
+In the annotated source listing,
+if there are multiple basic blocks on the same line,
+@sc{gnu} @code{gprof} prints all of their counts, seperated by commas.
+
+@ignore - it does this now
+@item
+The function names printed in @sc{gnu} @code{gprof} output do not include
+the leading underscores that are added internally to the front of all
+C identifiers on many operating systems.
+@end ignore
+
+@item
+The blurbs, field widths, and output formats are different. @sc{gnu}
+@code{gprof} prints blurbs after the tables, so that you can see the
+tables without skipping the blurbs.
+@end itemize
+
+@node Details
+@chapter Details of Profiling
+
+@menu
+* Implementation:: How a program collets profiling information
+* File Format:: Format of @samp{gmon.out} files
+* Internals:: @code{gprof}'s internal operation
+* Debugging:: Using @code{gprof}'s @samp{-d} option
+@end menu
+
+@node Implementation,File Format,,Details
+@section Implementation of Profiling
+
+Profiling works by changing how every function in your program is compiled
+so that when it is called, it will stash away some information about where
+it was called from. From this, the profiler can figure out what function
+called it, and can count how many times it was called. This change is made
+by the compiler when your program is compiled with the @samp{-pg} option,
+which causes every function to call @code{mcount}
+(or @code{_mcount}, or @code{__mcount}, depending on the OS and compiler)
+as one of its first operations.
+
+The @code{mcount} routine, included in the profiling library,
+is responsible for recording in an in-memory call graph table
+both its parent routine (the child) and its parent's parent. This is
+typically done by examining the stack frame to find both
+the address of the child, and the return address in the original parent.
+Since this is a very machine-dependant operation, @code{mcount}
+itself is typically a short assembly-language stub routine
+that extracts the required
+information, and then calls @code{__mcount_internal}
+(a normal C function) with two arguments - @code{frompc} and @code{selfpc}.
+@code{__mcount_internal} is responsible for maintaining
+the in-memory call graph, which records @code{frompc}, @code{selfpc},
+and the number of times each of these call arcs was transversed.
+
+GCC Version 2 provides a magical function (@code{__builtin_return_address}),
+which allows a generic @code{mcount} function to extract the
+required information from the stack frame. However, on some
+architectures, most notably the SPARC, using this builtin can be
+very computationally expensive, and an assembly language version
+of @code{mcount} is used for performance reasons.
+
+Number-of-calls information for library routines is collected by using a
+special version of the C library. The programs in it are the same as in
+the usual C library, but they were compiled with @samp{-pg}. If you
+link your program with @samp{gcc @dots{} -pg}, it automatically uses the
+profiling version of the library.
+
+Profiling also involves watching your program as it runs, and keeping a
+histogram of where the program counter happens to be every now and then.
+Typically the program counter is looked at around 100 times per second of
+run time, but the exact frequency may vary from system to system.
+
+This is done is one of two ways. Most UNIX-like operating systems
+provide a @code{profil()} system call, which registers a memory
+array with the kernel, along with a scale
+factor that determines how the program's address space maps
+into the array.
+Typical scaling values cause every 2 to 8 bytes of address space
+to map into a single array slot.
+On every tick of the system clock
+(assuming the profiled program is running), the value of the
+program counter is examined and the corresponding slot in
+the memory array is incremented. Since this is done in the kernel,
+which had to interrupt the process anyway to handle the clock
+interrupt, very little additional system overhead is required.
+
+However, some operating systems, most notably Linux 2.0 (and earlier),
+do not provide a @code{profil()} system call. On such a system,
+arrangements are made for the kernel to periodically deliver
+a signal to the process (typically via @code{setitimer()}),
+which then performs the same operation of examining the
+program counter and incrementing a slot in the memory array.
+Since this method requires a signal to be delivered to
+user space every time a sample is taken, it uses considerably
+more overhead than kernel-based profiling. Also, due to the
+added delay required to deliver the signal, this method is
+less accurate as well.
+
+A special startup routine allocates memory for the histogram and
+either calls @code{profil()} or sets up
+a clock signal handler.
+This routine (@code{monstartup}) can be invoked in several ways.
+On Linux systems, a special profiling startup file @code{gcrt0.o},
+which invokes @code{monstartup} before @code{main},
+is used instead of the default @code{crt0.o}.
+Use of this special startup file is one of the effects
+of using @samp{gcc @dots{} -pg} to link.
+On SPARC systems, no special startup files are used.
+Rather, the @code{mcount} routine, when it is invoked for
+the first time (typically when @code{main} is called),
+calls @code{monstartup}.
+
+If the compiler's @samp{-a} option was used, basic-block counting
+is also enabled. Each object file is then compiled with a static array
+of counts, initially zero.
+In the executable code, every time a new basic-block begins
+(i.e. when an @code{if} statement appears), an extra instruction
+is inserted to increment the corresponding count in the array.
+At compile time, a paired array was constructed that recorded
+the starting address of each basic-block. Taken together,
+the two arrays record the starting address of every basic-block,
+along with the number of times it was executed.
+
+The profiling library also includes a function (@code{mcleanup}) which is
+typically registered using @code{atexit()} to be called as the
+program exits, and is responsible for writing the file @file{gmon.out}.
+Profiling is turned off, various headers are output, and the histogram
+is written, followed by the call-graph arcs and the basic-block counts.
+
+The output from @code{gprof} gives no indication of parts of your program that
+are limited by I/O or swapping bandwidth. This is because samples of the
+program counter are taken at fixed intervals of the program's run time.
+Therefore, the
+time measurements in @code{gprof} output say nothing about time that your
+program was not running. For example, a part of the program that creates
+so much data that it cannot all fit in physical memory at once may run very
+slowly due to thrashing, but @code{gprof} will say it uses little time. On
+the other hand, sampling by run time has the advantage that the amount of
+load due to other users won't directly affect the output you get.
+
+@node File Format,Internals,Implementation,Details
+@section Profiling Data File Format
+
+The old BSD-derived file format used for profile data does not contain a
+magic cookie that allows to check whether a data file really is a
+gprof file. Furthermore, it does not provide a version number, thus
+rendering changes to the file format almost impossible. @sc{gnu} @code{gprof}
+uses a new file format that provides these features. For backward
+compatibility, @sc{gnu} @code{gprof} continues to support the old BSD-derived
+format, but not all features are supported with it. For example,
+basic-block execution counts cannot be accommodated by the old file
+format.
+
+The new file format is defined in header file @file{gmon_out.h}. It
+consists of a header containing the magic cookie and a version number,
+as well as some spare bytes available for future extensions. All data
+in a profile data file is in the native format of the host on which
+the profile was collected. @sc{gnu} @code{gprof} adapts automatically to the
+byte-order in use.
+
+In the new file format, the header is followed by a sequence of
+records. Currently, there are three different record types: histogram
+records, call-graph arc records, and basic-block execution count
+records. Each file can contain any number of each record type. When
+reading a file, @sc{gnu} @code{gprof} will ensure records of the same type are
+compatible with each other and compute the union of all records. For
+example, for basic-block execution counts, the union is simply the sum
+of all execution counts for each basic-block.
+
+@subsection Histogram Records
+
+Histogram records consist of a header that is followed by an array of
+bins. The header contains the text-segment range that the histogram
+spans, the size of the histogram in bytes (unlike in the old BSD
+format, this does not include the size of the header), the rate of the
+profiling clock, and the physical dimension that the bin counts
+represent after being scaled by the profiling clock rate. The
+physical dimension is specified in two parts: a long name of up to 15
+characters and a single character abbreviation. For example, a
+histogram representing real-time would specify the long name as
+"seconds" and the abbreviation as "s". This feature is useful for
+architectures that support performance monitor hardware (which,
+fortunately, is becoming increasingly common). For example, under DEC
+OSF/1, the "uprofile" command can be used to produce a histogram of,
+say, instruction cache misses. In this case, the dimension in the
+histogram header could be set to "i-cache misses" and the abbreviation
+could be set to "1" (because it is simply a count, not a physical
+dimension). Also, the profiling rate would have to be set to 1 in
+this case.
+
+Histogram bins are 16-bit numbers and each bin represent an equal
+amount of text-space. For example, if the text-segment is one
+thousand bytes long and if there are ten bins in the histogram, each
+bin represents one hundred bytes.
+
+
+@subsection Call-Graph Records
+
+Call-graph records have a format that is identical to the one used in
+the BSD-derived file format. It consists of an arc in the call graph
+and a count indicating the number of times the arc was traversed
+during program execution. Arcs are specified by a pair of addresses:
+the first must be within caller's function and the second must be
+within the callee's function. When performing profiling at the
+function level, these addresses can point anywhere within the
+respective function. However, when profiling at the line-level, it is
+better if the addresses are as close to the call-site/entry-point as
+possible. This will ensure that the line-level call-graph is able to
+identify exactly which line of source code performed calls to a
+function.
+
+@subsection Basic-Block Execution Count Records
+
+Basic-block execution count records consist of a header followed by a
+sequence of address/count pairs. The header simply specifies the
+length of the sequence. In an address/count pair, the address
+identifies a basic-block and the count specifies the number of times
+that basic-block was executed. Any address within the basic-address can
+be used.
+
+@node Internals,Debugging,File Format,Details
+@section @code{gprof}'s Internal Operation
+
+Like most programs, @code{gprof} begins by processing its options.
+During this stage, it may building its symspec list
+(@code{sym_ids.c:sym_id_add}), if
+options are specified which use symspecs.
+@code{gprof} maintains a single linked list of symspecs,
+which will eventually get turned into 12 symbol tables,
+organized into six include/exclude pairs - one
+pair each for the flat profile (INCL_FLAT/EXCL_FLAT),
+the call graph arcs (INCL_ARCS/EXCL_ARCS),
+printing in the call graph (INCL_GRAPH/EXCL_GRAPH),
+timing propagation in the call graph (INCL_TIME/EXCL_TIME),
+the annotated source listing (INCL_ANNO/EXCL_ANNO),
+and the execution count listing (INCL_EXEC/EXCL_EXEC).
+
+After option processing, @code{gprof} finishes
+building the symspec list by adding all the symspecs in
+@code{default_excluded_list} to the exclude lists
+EXCL_TIME and EXCL_GRAPH, and if line-by-line profiling is specified,
+EXCL_FLAT as well.
+These default excludes are not added to EXCL_ANNO, EXCL_ARCS, and EXCL_EXEC.
+
+Next, the BFD library is called to open the object file,
+verify that it is an object file,
+and read its symbol table (@code{core.c:core_init}),
+using @code{bfd_canonicalize_symtab} after mallocing
+an appropiate sized array of asymbols. At this point,
+function mappings are read (if the @samp{--file-ordering} option
+has been specified), and the core text space is read into
+memory (if the @samp{-c} option was given).
+
+@code{gprof}'s own symbol table, an array of Sym structures,
+is now built.
+This is done in one of two ways, by one of two routines, depending
+on whether line-by-line profiling (@samp{-l} option) has been
+enabled.
+For normal profiling, the BFD canonical symbol table is scanned.
+For line-by-line profiling, every
+text space address is examined, and a new symbol table entry
+gets created every time the line number changes.
+In either case, two passes are made through the symbol
+table - one to count the size of the symbol table required,
+and the other to actually read the symbols. In between the
+two passes, a single array of type @code{Sym} is created of
+the appropiate length.
+Finally, @code{symtab.c:symtab_finalize}
+is called to sort the symbol table and remove duplicate entries
+(entries with the same memory address).
+
+The symbol table must be a contiguous array for two reasons.
+First, the @code{qsort} library function (which sorts an array)
+will be used to sort the symbol table.
+Also, the symbol lookup routine (@code{symtab.c:sym_lookup}),
+which finds symbols
+based on memory address, uses a binary search algorithm
+which requires the symbol table to be a sorted array.
+Function symbols are indicated with an @code{is_func} flag.
+Line number symbols have no special flags set.
+Additionally, a symbol can have an @code{is_static} flag
+to indicate that it is a local symbol.
+
+With the symbol table read, the symspecs can now be translated
+into Syms (@code{sym_ids.c:sym_id_parse}). Remember that a single
+symspec can match multiple symbols.
+An array of symbol tables
+(@code{syms}) is created, each entry of which is a symbol table
+of Syms to be included or excluded from a particular listing.
+The master symbol table and the symspecs are examined by nested
+loops, and every symbol that matches a symspec is inserted
+into the appropriate syms table. This is done twice, once to
+count the size of each required symbol table, and again to build
+the tables, which have been malloced between passes.
+From now on, to determine whether a symbol is on an include
+or exclude symspec list, @code{gprof} simply uses its
+standard symbol lookup routine on the appropriate table
+in the @code{syms} array.
+
+Now the profile data file(s) themselves are read
+(@code{gmon_io.c:gmon_out_read}),
+first by checking for a new-style @samp{gmon.out} header,
+then assuming this is an old-style BSD @samp{gmon.out}
+if the magic number test failed.
+
+New-style histogram records are read by @code{hist.c:hist_read_rec}.
+For the first histogram record, allocate a memory array to hold
+all the bins, and read them in.
+When multiple profile data files (or files with multiple histogram
+records) are read, the starting address, ending address, number
+of bins and sampling rate must match between the various histograms,
+or a fatal error will result.
+If everything matches, just sum the additional histograms into
+the existing in-memory array.
+
+As each call graph record is read (@code{call_graph.c:cg_read_rec}),
+the parent and child addresses
+are matched to symbol table entries, and a call graph arc is
+created by @code{cg_arcs.c:arc_add}, unless the arc fails a symspec
+check against INCL_ARCS/EXCL_ARCS. As each arc is added,
+a linked list is maintained of the parent's child arcs, and of the child's
+parent arcs.
+Both the child's call count and the arc's call count are
+incremented by the record's call count.
+
+Basic-block records are read (@code{basic_blocks.c:bb_read_rec}),
+but only if line-by-line profiling has been selected.
+Each basic-block address is matched to a corresponding line
+symbol in the symbol table, and an entry made in the symbol's
+bb_addr and bb_calls arrays. Again, if multiple basic-block
+records are present for the same address, the call counts
+are cumulative.
+
+A gmon.sum file is dumped, if requested (@code{gmon_io.c:gmon_out_write}).
+
+If histograms were present in the data files, assign them to symbols
+(@code{hist.c:hist_assign_samples}) by iterating over all the sample
+bins and assigning them to symbols. Since the symbol table
+is sorted in order of ascending memory addresses, we can
+simple follow along in the symbol table as we make our pass
+over the sample bins.
+This step includes a symspec check against INCL_FLAT/EXCL_FLAT.
+Depending on the histogram
+scale factor, a sample bin may span multiple symbols,
+in which case a fraction of the sample count is allocated
+to each symbol, proportional to the degree of overlap.
+This effect is rare for normal profiling, but overlaps
+are more common during line-by-line profiling, and can
+cause each of two adjacent lines to be credited with half
+a hit, for example.
+
+If call graph data is present, @code{cg_arcs.c:cg_assemble} is called.
+First, if @samp{-c} was specified, a machine-dependant
+routine (@code{find_call}) scans through each symbol's machine code,
+looking for subroutine call instructions, and adding them
+to the call graph with a zero call count.
+A topological sort is performed by depth-first numbering
+all the symbols (@code{cg_dfn.c:cg_dfn}), so that
+children are always numbered less than their parents,
+then making a array of pointers into the symbol table and sorting it into
+numerical order, which is reverse topological
+order (children appear before parents).
+Cycles are also detected at this point, all members
+of which are assigned the same topological number.
+Two passes are now made through this sorted array of symbol pointers.
+The first pass, from end to beginning (parents to children),
+computes the fraction of child time to propogate to each parent
+and a print flag.
+The print flag reflects symspec handling of INCL_GRAPH/EXCL_GRAPH,
+with a parent's include or exclude (print or no print) property
+being propagated to its children, unless they themselves explicitly appear
+in INCL_GRAPH or EXCL_GRAPH.
+A second pass, from beginning to end (children to parents) actually
+propogates the timings along the call graph, subject
+to a check against INCL_TIME/EXCL_TIME.
+With the print flag, fractions, and timings now stored in the symbol
+structures, the topological sort array is now discarded, and a
+new array of pointers is assembled, this time sorted by propagated time.
+
+Finally, print the various outputs the user requested, which is now fairly
+straightforward. The call graph (@code{cg_print.c:cg_print}) and
+flat profile (@code{hist.c:hist_print}) are regurgitations of values
+already computed. The annotated source listing
+(@code{basic_blocks.c:print_annotated_source}) uses basic-block
+information, if present, to label each line of code with call counts,
+otherwise only the function call counts are presented.
+
+The function ordering code is marginally well documented
+in the source code itself (@code{cg_print.c}). Basically,
+the functions with the most use and the most parents are
+placed first, followed by other functions with the most use,
+followed by lower use functions, followed by unused functions
+at the end.
+
+@node Debugging,,Internals,Details
+@subsection Debugging @code{gprof}
+
+If @code{gprof} was compiled with debugging enabled,
+the @samp{-d} option triggers debugging output
+(to stdout) which can be helpful in understanding its operation.
+The debugging number specified is interpreted as a sum of the following
+options:
+
+@table @asis
+@item 2 - Topological sort
+Monitor depth-first numbering of symbols during call graph analysis
+@item 4 - Cycles
+Shows symbols as they are identified as cycle heads
+@item 16 - Tallying
+As the call graph arcs are read, show each arc and how
+the total calls to each function are tallied
+@item 32 - Call graph arc sorting
+Details sorting individual parents/children within each call graph entry
+@item 64 - Reading histogram and call graph records
+Shows address ranges of histograms as they are read, and each
+call graph arc
+@item 128 - Symbol table
+Reading, classifying, and sorting the symbol table from the object file.
+For line-by-line profiling (@samp{-l} option), also shows line numbers
+being assigned to memory addresses.
+@item 256 - Static call graph
+Trace operation of @samp{-c} option
+@item 512 - Symbol table and arc table lookups
+Detail operation of lookup routines
+@item 1024 - Call graph propagation
+Shows how function times are propagated along the call graph
+@item 2048 - Basic-blocks
+Shows basic-block records as they are read from profile data
+(only meaningful with @samp{-l} option)
+@item 4096 - Symspecs
+Shows symspec-to-symbol pattern matching operation
+@item 8192 - Annotate source
+Tracks operation of @samp{-A} option
+@end table
+
+@contents
+@bye
+
+NEEDS AN INDEX
+
+-T - "traditional BSD style": How is it different? Should the
+differences be documented?
+
+example flat file adds up to 100.01%...
+
+note: time estimates now only go out to one decimal place (0.0), where
+they used to extend two (78.67).
diff --git a/gprof/hertz.c b/gprof/hertz.c
new file mode 100644
index 00000000000..75314acc0c3
--- /dev/null
+++ b/gprof/hertz.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "hertz.h"
+
+
+#ifdef __MSDOS__
+#define HERTZ 18
+#endif
+
+int
+hertz ()
+{
+#ifdef HERTZ
+ return HERTZ;
+#else /* ! defined (HERTZ) */
+#ifdef HAVE_SETITIMER
+ struct itimerval tim;
+
+ tim.it_interval.tv_sec = 0;
+ tim.it_interval.tv_usec = 1;
+ tim.it_value.tv_sec = 0;
+ tim.it_value.tv_usec = 0;
+ setitimer (ITIMER_REAL, &tim, 0);
+ setitimer (ITIMER_REAL, 0, &tim);
+ if (tim.it_interval.tv_usec < 2)
+ {
+ return HZ_WRONG;
+ }
+ return 1000000 / tim.it_interval.tv_usec;
+#else /* ! defined (HAVE_SETITIMER) */
+#if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK)
+ return sysconf (_SC_CLK_TCK);
+#else /* ! defined (HAVE_SYSCONF) || ! defined (_SC_CLK_TCK) */
+ return HZ_WRONG;
+#endif /* ! defined (HAVE_SYSCONF) || ! defined (_SC_CLK_TCK) */
+#endif /* ! defined (HAVE_SETITIMER) */
+#endif /* ! defined (HERTZ) */
+}
diff --git a/gprof/hertz.h b/gprof/hertz.h
new file mode 100644
index 00000000000..2ea01bac882
--- /dev/null
+++ b/gprof/hertz.h
@@ -0,0 +1,22 @@
+#ifndef hertz_h
+#define hertz_h
+
+#include "gprof.h"
+
+#define HZ_WRONG 0 /* impossible clock frequency */
+
+/*
+ * Discover the tick frequency of the machine if something goes wrong,
+ * we return HZ_WRONG, an impossible sampling frequency.
+ */
+
+/* FIXME: Checking for MACH here makes no sense when for a cross
+ gprof. */
+#ifdef MACH
+#include <machine/mach_param.h>
+#define hertz() (HZ)
+#else
+extern int hertz PARAMS ((void));
+#endif
+
+#endif /* hertz_h */
diff --git a/gprof/hist.c b/gprof/hist.c
new file mode 100644
index 00000000000..5cdbbbb0653
--- /dev/null
+++ b/gprof/hist.c
@@ -0,0 +1,596 @@
+/*
+ * Histogram related operations.
+ */
+#include <stdio.h>
+#include "libiberty.h"
+#include "gprof.h"
+#include "corefile.h"
+#include "gmon_io.h"
+#include "gmon_out.h"
+#include "hist.h"
+#include "symtab.h"
+#include "sym_ids.h"
+#include "utils.h"
+
+#define UNITS_TO_CODE (offset_to_code / sizeof(UNIT))
+
+static void scale_and_align_entries PARAMS ((void));
+
+/* declarations of automatically generated functions to output blurbs: */
+extern void flat_blurb PARAMS ((FILE * fp));
+
+bfd_vma s_lowpc; /* lowest address in .text */
+bfd_vma s_highpc = 0; /* highest address in .text */
+bfd_vma lowpc, highpc; /* same, but expressed in UNITs */
+int hist_num_bins = 0; /* number of histogram samples */
+int *hist_sample = 0; /* histogram samples (shorts in the file!) */
+double hist_scale;
+char hist_dimension[sizeof (((struct gmon_hist_hdr *) 0)->dimen) + 1] =
+ "seconds";
+char hist_dimension_abbrev = 's';
+
+static double accum_time; /* accumulated time so far for print_line() */
+static double total_time; /* total time for all routines */
+/*
+ * Table of SI prefixes for powers of 10 (used to automatically
+ * scale some of the values in the flat profile).
+ */
+const struct
+ {
+ char prefix;
+ double scale;
+ }
+SItab[] =
+{
+ {
+ 'T', 1e-12
+ }
+ , /* tera */
+ {
+ 'G', 1e-09
+ }
+ , /* giga */
+ {
+ 'M', 1e-06
+ }
+ , /* mega */
+ {
+ 'K', 1e-03
+ }
+ , /* kilo */
+ {
+ ' ', 1e-00
+ }
+ ,
+ {
+ 'm', 1e+03
+ }
+ , /* milli */
+ {
+ 'u', 1e+06
+ }
+ , /* micro */
+ {
+ 'n', 1e+09
+ }
+ , /* nano */
+ {
+ 'p', 1e+12
+ }
+ , /* pico */
+ {
+ 'f', 1e+15
+ }
+ , /* femto */
+ {
+ 'a', 1e+18
+ }
+ , /* ato */
+};
+
+/*
+ * Read the histogram from file IFP. FILENAME is the name of IFP and
+ * is provided for formatting error messages only.
+ */
+void
+DEFUN (hist_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
+{
+ struct gmon_hist_hdr hdr;
+ bfd_vma n_lowpc, n_highpc;
+ int i, ncnt, profrate;
+ UNIT count;
+
+ if (fread (&hdr, sizeof (hdr), 1, ifp) != 1)
+ {
+ fprintf (stderr, _("%s: %s: unexpected end of file\n"),
+ whoami, filename);
+ done (1);
+ }
+
+ n_lowpc = (bfd_vma) get_vma (core_bfd, (bfd_byte *) hdr.low_pc);
+ n_highpc = (bfd_vma) get_vma (core_bfd, (bfd_byte *) hdr.high_pc);
+ ncnt = bfd_get_32 (core_bfd, (bfd_byte *) hdr.hist_size);
+ profrate = bfd_get_32 (core_bfd, (bfd_byte *) hdr.prof_rate);
+ strncpy (hist_dimension, hdr.dimen, sizeof (hdr.dimen));
+ hist_dimension[sizeof (hdr.dimen)] = '\0';
+ hist_dimension_abbrev = hdr.dimen_abbrev;
+
+ if (!s_highpc)
+ {
+
+ /* this is the first histogram record: */
+
+ s_lowpc = n_lowpc;
+ s_highpc = n_highpc;
+ lowpc = (bfd_vma) n_lowpc / sizeof (UNIT);
+ highpc = (bfd_vma) n_highpc / sizeof (UNIT);
+ hist_num_bins = ncnt;
+ hz = profrate;
+ }
+
+ DBG (SAMPLEDEBUG,
+ printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %d\n",
+ n_lowpc, n_highpc, ncnt);
+ printf ("[hist_read_rec] s_lowpc 0x%lx s_highpc 0x%lx nsamples %d\n",
+ s_lowpc, s_highpc, hist_num_bins);
+ printf ("[hist_read_rec] lowpc 0x%lx highpc 0x%lx\n",
+ lowpc, highpc));
+
+ if (n_lowpc != s_lowpc || n_highpc != s_highpc
+ || ncnt != hist_num_bins || hz != profrate)
+ {
+ fprintf (stderr, _("%s: `%s' is incompatible with first gmon file\n"),
+ whoami, filename);
+ done (1);
+ }
+
+ if (!hist_sample)
+ {
+ hist_sample = (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
+ memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
+ }
+
+ for (i = 0; i < hist_num_bins; ++i)
+ {
+ if (fread (&count[0], sizeof (count), 1, ifp) != 1)
+ {
+ fprintf (stderr,
+ _("%s: %s: unexpected EOF after reading %d of %d samples\n"),
+ whoami, filename, i, hist_num_bins);
+ done (1);
+ }
+ hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
+ }
+}
+
+
+/*
+ * Write execution histogram to file OFP. FILENAME is the name
+ * of OFP and is provided for formatting error-messages only.
+ */
+void
+DEFUN (hist_write_hist, (ofp, filename), FILE * ofp AND const char *filename)
+{
+ struct gmon_hist_hdr hdr;
+ unsigned char tag;
+ UNIT count;
+ int i;
+
+ /* write header: */
+
+ tag = GMON_TAG_TIME_HIST;
+ put_vma (core_bfd, s_lowpc, (bfd_byte *) hdr.low_pc);
+ put_vma (core_bfd, s_highpc, (bfd_byte *) hdr.high_pc);
+ bfd_put_32 (core_bfd, hist_num_bins, (bfd_byte *) hdr.hist_size);
+ bfd_put_32 (core_bfd, hz, (bfd_byte *) hdr.prof_rate);
+ strncpy (hdr.dimen, hist_dimension, sizeof (hdr.dimen));
+ hdr.dimen_abbrev = hist_dimension_abbrev;
+
+ if (fwrite (&tag, sizeof (tag), 1, ofp) != 1
+ || fwrite (&hdr, sizeof (hdr), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+
+ for (i = 0; i < hist_num_bins; ++i)
+ {
+ bfd_put_16 (core_bfd, hist_sample[i], (bfd_byte *) & count[0]);
+ if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
+ {
+ perror (filename);
+ done (1);
+ }
+ }
+}
+
+
+/*
+ * Calculate scaled entry point addresses (to save time in
+ * hist_assign_samples), and, on architectures that have procedure
+ * entry masks at the start of a function, possibly push the scaled
+ * entry points over the procedure entry mask, if it turns out that
+ * the entry point is in one bin and the code for a routine is in the
+ * next bin.
+ */
+static void
+scale_and_align_entries ()
+{
+ Sym *sym;
+ bfd_vma bin_of_entry;
+ bfd_vma bin_of_code;
+
+ for (sym = symtab.base; sym < symtab.limit; sym++)
+ {
+ sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
+ bin_of_entry = (sym->hist.scaled_addr - lowpc) / hist_scale;
+ bin_of_code = (sym->hist.scaled_addr + UNITS_TO_CODE - lowpc) / hist_scale;
+ if (bin_of_entry < bin_of_code)
+ {
+ DBG (SAMPLEDEBUG,
+ printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n",
+ sym->hist.scaled_addr,
+ sym->hist.scaled_addr + UNITS_TO_CODE));
+ sym->hist.scaled_addr += UNITS_TO_CODE;
+ }
+ }
+}
+
+
+/*
+ * Assign samples to the symbol to which they belong.
+ *
+ * Histogram bin I covers some address range [BIN_LOWPC,BIN_HIGH_PC)
+ * which may overlap one more symbol address ranges. If a symbol
+ * overlaps with the bin's address range by O percent, then O percent
+ * of the bin's count is credited to that symbol.
+ *
+ * There are three cases as to where BIN_LOW_PC and BIN_HIGH_PC can be
+ * with respect to the symbol's address range [SYM_LOW_PC,
+ * SYM_HIGH_PC) as shown in the following diagram. OVERLAP computes
+ * the distance (in UNITs) between the arrows, the fraction of the
+ * sample that is to be credited to the symbol which starts at
+ * SYM_LOW_PC.
+ *
+ * sym_low_pc sym_high_pc
+ * | |
+ * v v
+ *
+ * +-----------------------------------------------+
+ * | |
+ * | ->| |<- ->| |<- ->| |<- |
+ * | | | | | |
+ * +---------+ +---------+ +---------+
+ *
+ * ^ ^ ^ ^ ^ ^
+ * | | | | | |
+ * bin_low_pc bin_high_pc bin_low_pc bin_high_pc bin_low_pc bin_high_pc
+ *
+ * For the VAX we assert that samples will never fall in the first two
+ * bytes of any routine, since that is the entry mask, thus we call
+ * scale_and_align_entries() to adjust the entry points if the entry
+ * mask falls in one bin but the code for the routine doesn't start
+ * until the next bin. In conjunction with the alignment of routine
+ * addresses, this should allow us to have only one sample for every
+ * four bytes of text space and never have any overlap (the two end
+ * cases, above).
+ */
+void
+DEFUN_VOID (hist_assign_samples)
+{
+ bfd_vma bin_low_pc, bin_high_pc;
+ bfd_vma sym_low_pc, sym_high_pc;
+ bfd_vma overlap, addr;
+ int bin_count, i;
+ unsigned int j;
+ double time, credit;
+
+ /* read samples and assign to symbols: */
+ hist_scale = highpc - lowpc;
+ hist_scale /= hist_num_bins;
+ scale_and_align_entries ();
+
+ /* iterate over all sample bins: */
+
+ for (i = 0, j = 1; i < hist_num_bins; ++i)
+ {
+ bin_count = hist_sample[i];
+ if (!bin_count)
+ {
+ continue;
+ }
+ bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
+ bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
+ time = bin_count;
+ DBG (SAMPLEDEBUG,
+ printf (
+ "[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%d\n",
+ sizeof (UNIT) * bin_low_pc, sizeof (UNIT) * bin_high_pc,
+ bin_count));
+ total_time += time;
+
+ /* credit all symbols that are covered by bin I: */
+
+ for (j = j - 1; j < symtab.len; ++j)
+ {
+ sym_low_pc = symtab.base[j].hist.scaled_addr;
+ sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
+ /*
+ * If high end of bin is below entry address, go for next
+ * bin:
+ */
+ if (bin_high_pc < sym_low_pc)
+ {
+ break;
+ }
+ /*
+ * If low end of bin is above high end of symbol, go for
+ * next symbol.
+ */
+ if (bin_low_pc >= sym_high_pc)
+ {
+ continue;
+ }
+ overlap =
+ MIN (bin_high_pc, sym_high_pc) - MAX (bin_low_pc, sym_low_pc);
+ if (overlap > 0)
+ {
+ DBG (SAMPLEDEBUG,
+ printf (
+ "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
+ symtab.base[j].addr, sizeof (UNIT) * sym_high_pc,
+ symtab.base[j].name, overlap * time / hist_scale,
+ overlap));
+ addr = symtab.base[j].addr;
+ credit = overlap * time / hist_scale;
+ /*
+ * Credit symbol if it appears in INCL_FLAT or that
+ * table is empty and it does not appear it in
+ * EXCL_FLAT.
+ */
+ if (sym_lookup (&syms[INCL_FLAT], addr)
+ || (syms[INCL_FLAT].len == 0
+ && !sym_lookup (&syms[EXCL_FLAT], addr)))
+ {
+ symtab.base[j].hist.time += credit;
+ }
+ else
+ {
+ total_time -= credit;
+ }
+ }
+ }
+ }
+ DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n",
+ total_time));
+}
+
+
+/*
+ * Print header for flag histogram profile:
+ */
+static void
+DEFUN (print_header, (prefix), const char prefix)
+{
+ char unit[64];
+
+ sprintf (unit, _("%c%c/call"), prefix, hist_dimension_abbrev);
+
+ if (bsd_style_output)
+ {
+ printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
+ (long) hist_scale * sizeof (UNIT));
+ if (total_time > 0.0)
+ {
+ printf (_(" for %.2f%% of %.2f %s\n\n"),
+ 100.0 / total_time, total_time / hz, hist_dimension);
+ }
+ }
+ else
+ {
+ printf (_("\nEach sample counts as %g %s.\n"), 1.0 / hz, hist_dimension);
+ }
+
+ if (total_time <= 0.0)
+ {
+ printf (_(" no time accumulated\n\n"));
+ /* this doesn't hurt since all the numerators will be zero: */
+ total_time = 1.0;
+ }
+
+ printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
+ "% ", _("cumulative"), _("self "), "", _("self "), _("total "), "");
+ printf ("%5.5s %9.9s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
+ _("time"), hist_dimension, hist_dimension, _("calls"), unit, unit,
+ _("name"));
+}
+
+
+static void
+DEFUN (print_line, (sym, scale), Sym * sym AND double scale)
+{
+ if (ignore_zeros && sym->ncalls == 0 && sym->hist.time == 0)
+ {
+ return;
+ }
+
+ accum_time += sym->hist.time;
+ if (bsd_style_output)
+ {
+ printf ("%5.1f %10.2f %8.2f",
+ total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
+ accum_time / hz, sym->hist.time / hz);
+ }
+ else
+ {
+ printf ("%6.2f %9.2f %8.2f",
+ total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
+ accum_time / hz, sym->hist.time / hz);
+ }
+ if (sym->ncalls != 0)
+ {
+ printf (" %8lu %8.2f %8.2f ",
+ sym->ncalls, scale * sym->hist.time / hz / sym->ncalls,
+ scale * (sym->hist.time + sym->cg.child_time) / hz / sym->ncalls);
+ }
+ else
+ {
+ printf (" %8.8s %8.8s %8.8s ", "", "", "");
+ }
+ if (bsd_style_output)
+ {
+ print_name (sym);
+ }
+ else
+ {
+ print_name_only (sym);
+ }
+ printf ("\n");
+}
+
+
+/*
+ * Compare LP and RP. The primary comparison key is execution time,
+ * the secondary is number of invocation, and the tertiary is the
+ * lexicographic order of the function names.
+ */
+static int
+DEFUN (cmp_time, (lp, rp), const PTR lp AND const PTR rp)
+{
+ const Sym *left = *(const Sym **) lp;
+ const Sym *right = *(const Sym **) rp;
+ double time_diff;
+
+ time_diff = right->hist.time - left->hist.time;
+ if (time_diff > 0.0)
+ {
+ return 1;
+ }
+ if (time_diff < 0.0)
+ {
+ return -1;
+ }
+
+ if (right->ncalls > left->ncalls)
+ {
+ return 1;
+ }
+ if (right->ncalls < left->ncalls)
+ {
+ return -1;
+ }
+
+ return strcmp (left->name, right->name);
+}
+
+
+/*
+ * Print the flat histogram profile.
+ */
+void
+DEFUN_VOID (hist_print)
+{
+ Sym **time_sorted_syms, *top_dog, *sym;
+ unsigned int index;
+ int log_scale;
+ double top_time, time;
+ bfd_vma addr;
+
+ if (first_output)
+ {
+ first_output = FALSE;
+ }
+ else
+ {
+ printf ("\f\n");
+ }
+
+ accum_time = 0.0;
+ if (bsd_style_output)
+ {
+ if (print_descriptions)
+ {
+ printf (_("\n\n\nflat profile:\n"));
+ flat_blurb (stdout);
+ }
+ }
+ else
+ {
+ printf (_("Flat profile:\n"));
+ }
+ /*
+ * Sort the symbol table by time (call-count and name as secondary
+ * and tertiary keys):
+ */
+ time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
+ for (index = 0; index < symtab.len; ++index)
+ {
+ time_sorted_syms[index] = &symtab.base[index];
+ }
+ qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time);
+
+ if (bsd_style_output)
+ {
+ log_scale = 5; /* milli-seconds is BSD-default */
+ }
+ else
+ {
+ /*
+ * Search for symbol with highest per-call execution time and
+ * scale accordingly:
+ */
+ log_scale = 0;
+ top_dog = 0;
+ top_time = 0.0;
+ for (index = 0; index < symtab.len; ++index)
+ {
+ sym = time_sorted_syms[index];
+ if (sym->ncalls != 0)
+ {
+ time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
+ if (time > top_time)
+ {
+ top_dog = sym;
+ top_time = time;
+ }
+ }
+ }
+ if (top_dog && top_dog->ncalls != 0 && top_time > 0.0)
+ {
+ top_time /= hz;
+ while (SItab[log_scale].scale * top_time < 1000.0
+ && ((size_t) log_scale
+ < sizeof (SItab) / sizeof (SItab[0]) - 1))
+ {
+ ++log_scale;
+ }
+ }
+ }
+
+ /*
+ * For now, the dimension is always seconds. In the future, we
+ * may also want to support other (pseudo-)dimensions (such as
+ * I-cache misses etc.).
+ */
+ print_header (SItab[log_scale].prefix);
+ for (index = 0; index < symtab.len; ++index)
+ {
+ addr = time_sorted_syms[index]->addr;
+ /*
+ * Print symbol if its in INCL_FLAT table or that table
+ * is empty and the symbol is not in EXCL_FLAT.
+ */
+ if (sym_lookup (&syms[INCL_FLAT], addr)
+ || (syms[INCL_FLAT].len == 0
+ && !sym_lookup (&syms[EXCL_FLAT], addr)))
+ {
+ print_line (time_sorted_syms[index], SItab[log_scale].scale);
+ }
+ }
+ free (time_sorted_syms);
+
+ if (print_descriptions && !bsd_style_output)
+ {
+ flat_blurb (stdout);
+ }
+}
diff --git a/gprof/hist.h b/gprof/hist.h
new file mode 100644
index 00000000000..df62ef770f4
--- /dev/null
+++ b/gprof/hist.h
@@ -0,0 +1,23 @@
+#ifndef hist_h
+#define hist_h
+
+#include "bfd.h"
+
+extern bfd_vma s_lowpc; /* lowpc from the profile file */
+extern bfd_vma s_highpc; /* highpc from the profile file */
+extern bfd_vma lowpc, highpc; /* range profiled, in UNIT's */
+extern int hist_num_bins; /* number of histogram bins */
+extern int *hist_sample; /* code histogram */
+/*
+ * Scale factor converting samples to pc values: each sample covers
+ * HIST_SCALE bytes:
+ */
+extern double hist_scale;
+
+
+extern void hist_read_rec PARAMS ((FILE * ifp, const char *filename));
+extern void hist_write_hist PARAMS ((FILE * ofp, const char *filename));
+extern void hist_assign_samples PARAMS ((void));
+extern void hist_print PARAMS ((void));
+
+#endif /* hist_h */
diff --git a/gprof/i386.c b/gprof/i386.c
new file mode 100644
index 00000000000..18aad1caeec
--- /dev/null
+++ b/gprof/i386.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+#include "symtab.h"
+
+
+int
+DEFUN (i386_iscall, (ip), unsigned char *ip)
+{
+ if (*ip == 0xe8)
+ return 1;
+ return 0;
+}
+
+
+void
+i386_find_call (parent, p_lowpc, p_highpc)
+ Sym *parent;
+ bfd_vma p_lowpc;
+ bfd_vma p_highpc;
+{
+ unsigned char *instructp;
+ Sym *child;
+ bfd_vma destpc, delta;
+
+ if (core_text_space == 0)
+ {
+ return;
+ }
+ if (p_lowpc < s_lowpc)
+ {
+ p_lowpc = s_lowpc;
+ }
+ if (p_highpc > s_highpc)
+ {
+ p_highpc = s_highpc;
+ }
+ DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
+ parent->name, p_lowpc, p_highpc));
+
+ delta = (bfd_vma) core_text_space - core_text_sect->vma;
+
+ for (instructp = (unsigned char *) (p_lowpc + delta);
+ instructp < (unsigned char *) (p_highpc + delta);
+ instructp ++)
+ {
+ if (i386_iscall (instructp))
+ {
+ DBG (CALLDEBUG,
+ printf ("[findcall]\t0x%x:call",
+ instructp - (unsigned char *) delta));
+ /*
+ * regular pc relative addressing
+ * check that this is the address of
+ * a function.
+ */
+
+ destpc = ((bfd_vma) bfd_get_32 (core_bfd, instructp + 1)
+ + (bfd_vma) instructp - (bfd_vma) delta + 5);
+ if (destpc >= s_lowpc && destpc <= s_highpc)
+ {
+ child = sym_lookup (&symtab, destpc);
+ if (child && child->addr == destpc)
+ {
+ /*
+ * a hit
+ */
+ DBG (CALLDEBUG,
+ printf ("\tdestpc 0x%lx (%s)\n", destpc, child->name));
+ arc_add (parent, child, (unsigned long) 0);
+ instructp += 4; /* call is a 5 byte instruction */
+ continue;
+ }
+ }
+ /*
+ * else:
+ * it looked like a callf, but it:
+ * a) wasn't actually a callf, or
+ * b) didn't point to a known function in the symtab, or
+ * c) something funny is going on.
+ */
+ DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
+ }
+ }
+}
diff --git a/gprof/po/Make-in b/gprof/po/Make-in
new file mode 100644
index 00000000000..0552db1feef
--- /dev/null
+++ b/gprof/po/Make-in
@@ -0,0 +1,251 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gprof/po/POTFILES.in b/gprof/po/POTFILES.in
new file mode 100644
index 00000000000..56d864163b8
--- /dev/null
+++ b/gprof/po/POTFILES.in
@@ -0,0 +1,38 @@
+alpha.c
+basic_blocks.c
+basic_blocks.h
+bb_exit_func.c
+call_graph.c
+call_graph.h
+cg_arcs.c
+cg_arcs.h
+cg_dfn.c
+cg_dfn.h
+cg_print.c
+cg_print.h
+corefile.c
+corefile.h
+gmon.h
+gmon_io.c
+gmon_io.h
+gmon_out.h
+gprof.c
+gprof.h
+hertz.c
+hertz.h
+hist.c
+hist.h
+i386.c
+search_list.c
+search_list.h
+source.c
+source.h
+sparc.c
+sym_ids.c
+sym_ids.h
+symtab.c
+symtab.h
+tahoe.c
+utils.c
+utils.h
+vax.c
diff --git a/gprof/po/gprof.pot b/gprof/po/gprof.pot
new file mode 100644
index 00000000000..36bf7870001
--- /dev/null
+++ b/gprof/po/gprof.pot
@@ -0,0 +1,470 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1998-06-12 19:33-0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: alpha.c:89
+msgid "<indirect child>"
+msgstr ""
+
+#: alpha.c:106
+#, c-format
+msgid "[find_call] %s: 0x%lx to 0x%lx\n"
+msgstr ""
+
+#: alpha.c:127
+#, c-format
+msgid "[find_call] 0x%lx: jsr%s <indirect_child>\n"
+msgstr ""
+
+#: alpha.c:136
+#, c-format
+msgid "[find_call] 0x%lx: bsr"
+msgstr ""
+
+#: basic_blocks.c:134 call_graph.c:70 hist.c:105
+#, c-format
+msgid "%s: %s: unexpected end of file\n"
+msgstr ""
+
+#: basic_blocks.c:214
+#, c-format
+msgid "%s: warning: ignoring basic-block exec counts (use -l or --line)\n"
+msgstr ""
+
+#: basic_blocks.c:322 basic_blocks.c:330
+#, c-format
+msgid "%s:%d: (%s:0x%lx) %d executions\n"
+msgstr ""
+
+#: basic_blocks.c:323 basic_blocks.c:331
+msgid "<unknown>"
+msgstr ""
+
+#: basic_blocks.c:584
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Top %d Lines:\n"
+"\n"
+" Line Count\n"
+"\n"
+msgstr ""
+
+#: basic_blocks.c:608
+msgid ""
+"\n"
+"Execution Summary:\n"
+"\n"
+msgstr ""
+
+#: basic_blocks.c:609
+#, c-format
+msgid "%9ld Executable lines in this file\n"
+msgstr ""
+
+#: basic_blocks.c:611
+#, c-format
+msgid "%9ld Lines executed\n"
+msgstr ""
+
+#: basic_blocks.c:612
+#, c-format
+msgid "%9.2f Percent of the file executed\n"
+msgstr ""
+
+#: basic_blocks.c:616
+#, c-format
+msgid ""
+"\n"
+"%9d Total number of line executions\n"
+msgstr ""
+
+#: basic_blocks.c:617
+#, c-format
+msgid "%9.2f Average executions per line\n"
+msgstr ""
+
+#: call_graph.c:48
+#, c-format
+msgid "[cg_tally] arc from %s to %s traversed %d times\n"
+msgstr ""
+
+#: cg_print.c:39
+msgid ""
+"\t\t Call graph (explanation follows)\n"
+"\n"
+msgstr ""
+
+#: cg_print.c:43
+msgid ""
+"\t\t\tCall graph\n"
+"\n"
+msgstr ""
+
+#: cg_print.c:46 hist.c:381
+#, c-format
+msgid ""
+"\n"
+"granularity: each sample hit covers %ld byte(s)"
+msgstr ""
+
+#: cg_print.c:50
+msgid ""
+" for %.2f%% of %.2f seconds\n"
+"\n"
+msgstr ""
+
+#: cg_print.c:55
+msgid ""
+" no time propagated\n"
+"\n"
+msgstr ""
+
+#: cg_print.c:64 cg_print.c:67 cg_print.c:69
+msgid "called"
+msgstr ""
+
+#: cg_print.c:64 cg_print.c:69
+msgid "total"
+msgstr ""
+
+#: cg_print.c:64
+msgid "parents"
+msgstr ""
+
+#: cg_print.c:66 cg_print.c:67
+msgid "index"
+msgstr ""
+
+#: cg_print.c:66
+msgid "%time"
+msgstr ""
+
+#: cg_print.c:66 cg_print.c:67
+msgid "self"
+msgstr ""
+
+#: cg_print.c:66
+msgid "descendents"
+msgstr ""
+
+#: cg_print.c:67 hist.c:405
+msgid "name"
+msgstr ""
+
+#: cg_print.c:69
+msgid "children"
+msgstr ""
+
+#: cg_print.c:74
+msgid "index %% time self children called name\n"
+msgstr ""
+
+#: cg_print.c:101
+#, c-format
+msgid " <cycle %d as a whole> [%d]\n"
+msgstr ""
+
+#: cg_print.c:353
+#, c-format
+msgid "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n"
+msgstr ""
+
+#: cg_print.c:354
+#, c-format
+msgid "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n"
+msgstr ""
+
+#: cg_print.c:587
+msgid ""
+"Index by function name\n"
+"\n"
+msgstr ""
+
+#: cg_print.c:644 cg_print.c:653
+#, c-format
+msgid "<cycle %d>"
+msgstr ""
+
+#: corefile.c:39
+#, c-format
+msgid "%s: could not open %s.\n"
+msgstr ""
+
+#: corefile.c:53 corefile.c:87
+#, c-format
+msgid "%s: unable to parse mapping file %s.\n"
+msgstr ""
+
+#: corefile.c:128
+#, c-format
+msgid "%s: %s: not in a.out format\n"
+msgstr ""
+
+#: corefile.c:139
+#, c-format
+msgid "%s: can't find .text section in %s\n"
+msgstr ""
+
+#: corefile.c:198
+#, c-format
+msgid "%s: ran out room for %ld bytes of text space\n"
+msgstr ""
+
+#: corefile.c:211
+#, c-format
+msgid "%s: can't do -c\n"
+msgstr ""
+
+#: corefile.c:243
+#, c-format
+msgid "%s: -c not supported on architecture %s\n"
+msgstr ""
+
+#: corefile.c:432
+#, c-format
+msgid "%s: file `%s' has no symbols\n"
+msgstr ""
+
+#: corefile.c:726
+#, c-format
+msgid "%s: somebody miscounted: ltab.len=%d instead of %ld\n"
+msgstr ""
+
+#: gmon_io.c:33 gmon_io.c:55
+#, c-format
+msgid "%s: bfd_vma has unexpected size of %ld bytes\n"
+msgstr ""
+
+#: gmon_io.c:87 gmon_io.c:179
+#, c-format
+msgid "%s: file too short to be a gmon file\n"
+msgstr ""
+
+#: gmon_io.c:97
+#, c-format
+msgid "%s: file `%s' has bad magic cookie\n"
+msgstr ""
+
+#: gmon_io.c:108
+#, c-format
+msgid "%s: file `%s' has unsupported version %d\n"
+msgstr ""
+
+#: gmon_io.c:138
+#, c-format
+msgid "%s: %s: found bad tag %d (file corrupted?)\n"
+msgstr ""
+
+#: gmon_io.c:197
+#, c-format
+msgid "%s: profiling rate incompatible with first gmon file\n"
+msgstr ""
+
+#: gmon_io.c:207
+#, c-format
+msgid "%s: incompatible with first gmon file\n"
+msgstr ""
+
+#: gmon_io.c:245
+#, c-format
+msgid "%s: unexpected EOF after reading %d/%d bins\n"
+msgstr ""
+
+#: gmon_io.c:280
+msgid "time is in ticks, not seconds\n"
+msgstr ""
+
+#: gmon_io.c:286 gmon_io.c:410
+#, c-format
+msgid "%s: don't know how to deal with file format %d\n"
+msgstr ""
+
+#: gmon_io.c:293
+#, c-format
+msgid "File `%s' (version %d) contains:\n"
+msgstr ""
+
+#: gmon_io.c:295
+#, c-format
+msgid "\t%d histogram record%s\n"
+msgstr ""
+
+#: gmon_io.c:297
+#, c-format
+msgid "\t%d call-graph record%s\n"
+msgstr ""
+
+#: gmon_io.c:299
+#, c-format
+msgid "\t%d basic-block count record%s\n"
+msgstr ""
+
+#: gprof.c:59
+msgid ""
+"@(#) Copyright (c) 1983 Regents of the University of California.\n"
+" All rights reserved.\n"
+msgstr ""
+
+#: gprof.c:144
+#, c-format
+msgid ""
+"Usage: %s [-[abcDhilLsTvwxyz]] [-[ACeEfFJnNOpPqQZ][name]] [-I dirs]\n"
+"\t[-d[num]] [-k from/to] [-m min-count] [-t table-length]\n"
+"\t[--[no-]annotated-source[=name]] [--[no-]exec-counts[=name]]\n"
+"\t[--[no-]flat-profile[=name]] [--[no-]graph[=name]]\n"
+"\t[--[no-]time=name] [--all-lines] [--brief] [--debug[=level]]\n"
+"\t[--function-ordering] [--file-ordering]\n"
+"\t[--directory-path=dirs] [--display-unused-functions]\n"
+"\t[--file-format=name] [--file-info] [--help] [--line] [--min-count=n]\n"
+"\t[--no-static] [--print-path] [--separate-files]\n"
+"\t[--static-call-graph] [--sum] [--table-length=len] [--traditional]\n"
+"\t[--version] [--width=n] [--ignore-non-functions]\n"
+"\t[--demangle] [--no-demangle]\n"
+"\t[image-file] [profile-file...]\n"
+msgstr ""
+
+#: gprof.c:160
+msgid "Report bugs to bug-gnu-utils@gnu.org\n"
+msgstr ""
+
+#: gprof.c:229
+#, c-format
+msgid "%s: debugging not supported; -d ignored\n"
+msgstr ""
+
+#: gprof.c:306
+#, c-format
+msgid "%s: unknown file format %s\n"
+msgstr ""
+
+#. This output is intended to follow the GNU standards document.
+#: gprof.c:390
+#, c-format
+msgid "GNU gprof %s\n"
+msgstr ""
+
+#: gprof.c:391
+msgid ""
+"Based on BSD gprof, copyright 1983 Regents of the University of California.\n"
+msgstr ""
+
+#: gprof.c:392
+msgid ""
+"This program is free software. This program has absolutely no warranty.\n"
+msgstr ""
+
+#: gprof.c:438
+#, c-format
+msgid ""
+"%s: Only one of --function-ordering and --file-ordering may be specified.\n"
+msgstr ""
+
+#: gprof.c:538
+#, c-format
+msgid "%s: sorry, file format `prof' is not yet supported\n"
+msgstr ""
+
+#: gprof.c:599
+#, c-format
+msgid "%s: gmon.out file is missing histogram\n"
+msgstr ""
+
+#: gprof.c:606
+#, c-format
+msgid "%s: gmon.out file is missing call-graph data\n"
+msgstr ""
+
+#: hist.c:142
+#, c-format
+msgid "%s: `%s' is incompatible with first gmon file\n"
+msgstr ""
+
+#: hist.c:158
+#, c-format
+msgid "%s: %s: unexpected EOF after reading %d of %d samples\n"
+msgstr ""
+
+#: hist.c:377
+#, c-format
+msgid "%c%c/call"
+msgstr ""
+
+#: hist.c:385
+msgid ""
+" for %.2f%% of %.2f %s\n"
+"\n"
+msgstr ""
+
+#: hist.c:391
+#, c-format
+msgid ""
+"\n"
+"Each sample counts as %g %s.\n"
+msgstr ""
+
+#: hist.c:396
+msgid ""
+" no time accumulated\n"
+"\n"
+msgstr ""
+
+#: hist.c:402
+msgid "cumulative"
+msgstr ""
+
+#: hist.c:402
+msgid "self "
+msgstr ""
+
+#: hist.c:402
+msgid "total "
+msgstr ""
+
+#: hist.c:404
+msgid "time"
+msgstr ""
+
+#: hist.c:404
+msgid "calls"
+msgstr ""
+
+#: hist.c:515
+msgid ""
+"\n"
+"\n"
+"\n"
+"flat profile:\n"
+msgstr ""
+
+#: hist.c:521
+msgid "Flat profile:\n"
+msgstr ""
+
+#: source.c:140
+#, c-format
+msgid "%s: could not locate `%s'\n"
+msgstr ""
+
+#: source.c:200
+#, c-format
+msgid "*** File %s:\n"
+msgstr ""
+
+#: utils.c:93
+#, c-format
+msgid " <cycle %d>"
+msgstr ""
diff --git a/gprof/search_list.c b/gprof/search_list.c
new file mode 100644
index 00000000000..d475dbf6a48
--- /dev/null
+++ b/gprof/search_list.c
@@ -0,0 +1,44 @@
+#include "libiberty.h"
+#include "gprof.h"
+#include "search_list.h"
+
+
+void
+DEFUN (search_list_append, (list, paths),
+ Search_List * list AND const char *paths)
+{
+ Search_List_Elem *new_el;
+ const char *beg, *colon;
+ int len;
+
+ colon = paths - 1;
+ do
+ {
+ beg = colon + 1;
+ colon = strchr (beg, ':');
+ if (colon)
+ {
+ len = colon - beg;
+ }
+ else
+ {
+ len = strlen (beg);
+ }
+ new_el = (Search_List_Elem *) xmalloc (sizeof (*new_el) + len);
+ memcpy (new_el->path, beg, len);
+ new_el->path[len] = '\0';
+
+ /* append new path at end of list: */
+ new_el->next = 0;
+ if (list->tail)
+ {
+ list->tail->next = new_el;
+ }
+ else
+ {
+ list->head = new_el;
+ }
+ list->tail = new_el;
+ }
+ while (colon);
+}
diff --git a/gprof/search_list.h b/gprof/search_list.h
new file mode 100644
index 00000000000..54dfe3590f7
--- /dev/null
+++ b/gprof/search_list.h
@@ -0,0 +1,20 @@
+#ifndef search_list_h
+#define search_list_h
+
+typedef struct search_list_elem
+ {
+ struct search_list_elem *next;
+ char path[1];
+ }
+Search_List_Elem;
+
+typedef struct
+ {
+ struct search_list_elem *head;
+ struct search_list_elem *tail;
+ }
+Search_List;
+
+extern void search_list_append PARAMS ((Search_List * list, const char *paths));
+
+#endif /* search_list_h */
diff --git a/gprof/source.c b/gprof/source.c
new file mode 100644
index 00000000000..4901a04b037
--- /dev/null
+++ b/gprof/source.c
@@ -0,0 +1,223 @@
+/*
+ * Keeps track of source files.
+ */
+#include "gprof.h"
+#include "libiberty.h"
+#include "search_list.h"
+#include "source.h"
+
+#define EXT_ANNO "-ann" /* postfix of annotated files */
+
+/*
+ * Default option values:
+ */
+bool create_annotation_files = FALSE;
+
+Search_List src_search_list =
+{0, 0};
+Source_File *first_src_file = 0;
+
+
+Source_File *
+DEFUN (source_file_lookup_path, (path), const char *path)
+{
+ Source_File *sf;
+
+ for (sf = first_src_file; sf; sf = sf->next)
+ {
+ if (strcmp (path, sf->name) == 0)
+ {
+ break;
+ }
+ }
+ if (!sf)
+ {
+ /* create a new source file descriptor: */
+
+ sf = (Source_File *) xmalloc (sizeof (*sf));
+ memset (sf, 0, sizeof (*sf));
+ sf->name = xstrdup (path);
+ sf->next = first_src_file;
+ first_src_file = sf;
+ }
+ return sf;
+}
+
+
+Source_File *
+DEFUN (source_file_lookup_name, (filename), const char *filename)
+{
+ const char *fname;
+ Source_File *sf;
+ /*
+ * The user cannot know exactly how a filename will be stored in
+ * the debugging info (e.g., ../include/foo.h
+ * vs. /usr/include/foo.h). So we simply compare the filename
+ * component of a path only:
+ */
+ for (sf = first_src_file; sf; sf = sf->next)
+ {
+ fname = strrchr (sf->name, '/');
+ if (fname)
+ {
+ ++fname;
+ }
+ else
+ {
+ fname = sf->name;
+ }
+ if (strcmp (filename, fname) == 0)
+ {
+ break;
+ }
+ }
+ return sf;
+}
+
+
+FILE *
+DEFUN (annotate_source, (sf, max_width, annote, arg),
+ Source_File * sf AND int max_width
+ AND void (*annote) PARAMS ((char *buf, int w, int l, void *arg))
+ AND void *arg)
+{
+ static bool first_file = TRUE;
+ int i, line_num, nread;
+ bool new_line;
+ char buf[8192];
+ char fname[PATH_MAX];
+ char *annotation, *name_only;
+ FILE *ifp, *ofp;
+ Search_List_Elem *sle = src_search_list.head;
+
+ /*
+ * Open input file. If open fails, walk along search-list until
+ * open succeeds or reaching end of list:
+ */
+ strcpy (fname, sf->name);
+ if (sf->name[0] == '/')
+ {
+ sle = 0; /* don't use search list for absolute paths */
+ }
+ name_only = 0;
+ while (TRUE)
+ {
+ DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n",
+ sf->name, fname));
+ ifp = fopen (fname, FOPEN_RB);
+ if (ifp)
+ {
+ break;
+ }
+ if (!sle && !name_only)
+ {
+ name_only = strrchr (sf->name, '/');
+ if (name_only)
+ {
+ /* try search-list again, but this time with name only: */
+ ++name_only;
+ sle = src_search_list.head;
+ }
+ }
+ if (sle)
+ {
+ strcpy (fname, sle->path);
+ strcat (fname, "/");
+ if (name_only)
+ {
+ strcat (fname, name_only);
+ }
+ else
+ {
+ strcat (fname, sf->name);
+ }
+ sle = sle->next;
+ }
+ else
+ {
+ if (errno == ENOENT)
+ {
+ fprintf (stderr, _("%s: could not locate `%s'\n"),
+ whoami, sf->name);
+ }
+ else
+ {
+ perror (sf->name);
+ }
+ return 0;
+ }
+ }
+
+ ofp = stdout;
+ if (create_annotation_files)
+ {
+ /* try to create annotated source file: */
+ const char *filename;
+
+ /* create annotation files in the current working directory: */
+ filename = strrchr (sf->name, '/');
+ if (filename)
+ {
+ ++filename;
+ }
+ else
+ {
+ filename = sf->name;
+ }
+
+ strcpy (fname, filename);
+ strcat (fname, EXT_ANNO);
+ ofp = fopen (fname, "w");
+ if (!ofp)
+ {
+ perror (fname);
+ return 0;
+ }
+ }
+
+ /*
+ * Print file names if output goes to stdout and there are
+ * more than one source file:
+ */
+ if (ofp == stdout)
+ {
+ if (first_file)
+ {
+ first_file = FALSE;
+ }
+ else
+ {
+ fputc ('\n', ofp);
+ }
+ if (first_output)
+ {
+ first_output = FALSE;
+ }
+ else
+ {
+ fprintf (ofp, "\f\n");
+ }
+ fprintf (ofp, _("*** File %s:\n"), sf->name);
+ }
+
+ annotation = xmalloc (max_width + 1);
+ line_num = 1;
+ new_line = TRUE;
+ while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0)
+ {
+ for (i = 0; i < nread; ++i)
+ {
+ if (new_line)
+ {
+ (*annote) (annotation, max_width, line_num, arg);
+ fputs (annotation, ofp);
+ ++line_num;
+ new_line = FALSE;
+ }
+ new_line = (buf[i] == '\n');
+ fputc (buf[i], ofp);
+ }
+ }
+ free (annotation);
+ return ofp;
+}
diff --git a/gprof/source.h b/gprof/source.h
new file mode 100644
index 00000000000..b33bad3e0a6
--- /dev/null
+++ b/gprof/source.h
@@ -0,0 +1,55 @@
+#ifndef source_h
+#define source_h
+
+#include <stdio.h>
+#include "gprof.h"
+#include "search_list.h"
+
+typedef struct source_file
+ {
+ struct source_file *next;
+ const char *name; /* name of source file */
+ unsigned long ncalls; /* # of "calls" to this file */
+ int num_lines; /* # of lines in file */
+ int nalloced; /* number of lines allocated */
+ void **line; /* usage-dependent per-line data */
+ }
+Source_File;
+
+/*
+ * Options:
+ */
+extern bool create_annotation_files; /* create annotated output files? */
+
+/*
+ * List of directories to search for source files:
+ */
+extern Search_List src_search_list;
+
+/*
+ * Chain of source-file descriptors:
+ */
+extern Source_File *first_src_file;
+
+/*
+ * Returns pointer to source file descriptor for PATH/FILENAME.
+ */
+extern Source_File *source_file_lookup_path PARAMS ((const char *path));
+extern Source_File *source_file_lookup_name PARAMS ((const char *filename));
+
+/*
+ * Read source file SF output annotated source. The annotation is at
+ * MAX_WIDTH characters wide and for each source-line an annotation is
+ * obtained by invoking function ANNOTE. ARG is an argument passed to
+ * ANNOTE that is left uninterpreted by annotate_source().
+ *
+ * Returns a pointer to the output file (which maybe stdout) such
+ * that summary statistics can be printed. If the returned file
+ * is not stdout, it should be closed when done with it.
+ */
+extern FILE *annotate_source PARAMS ((Source_File * sf, int max_width,
+ void (*annote) (char *b, int w, int l,
+ void *arg),
+ void *arg));
+
+#endif /* source_h */
diff --git a/gprof/sparc.c b/gprof/sparc.c
new file mode 100644
index 00000000000..ad702b1fbad
--- /dev/null
+++ b/gprof/sparc.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+#include "symtab.h"
+
+ /*
+ * opcode of the `callf' instruction
+ */
+#define CALL (0xc0000000)
+
+void
+sparc_find_call (parent, p_lowpc, p_highpc)
+ Sym *parent;
+ bfd_vma p_lowpc;
+ bfd_vma p_highpc;
+{
+ bfd_vma dest_pc, delta;
+ unsigned int *instr;
+ Sym *child;
+
+ delta = (bfd_vma) core_text_space - core_text_sect->vma;
+
+ if (core_text_space == 0)
+ {
+ return;
+ }
+ if (p_lowpc < s_lowpc)
+ {
+ p_lowpc = s_lowpc;
+ }
+ if (p_highpc > s_highpc)
+ {
+ p_highpc = s_highpc;
+ }
+ DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n",
+ parent->name, p_lowpc, p_highpc));
+ for (instr = (unsigned int *) (((p_lowpc + delta) + 3) &~ 3);
+ instr < (unsigned int *) (p_highpc + delta);
+ ++instr)
+ {
+ if ((*instr & CALL))
+ {
+ DBG (CALLDEBUG,
+ printf ("[find_call] 0x%lx: callf", (bfd_vma) instr - delta));
+ /*
+ * Regular pc relative addressing check that this is the
+ * address of a function.
+ */
+ dest_pc = ((bfd_vma) (instr + (*instr & ~CALL))) - delta;
+ if (dest_pc >= s_lowpc && dest_pc <= s_highpc)
+ {
+ child = sym_lookup (&symtab, dest_pc);
+ DBG (CALLDEBUG,
+ printf ("\tdest_pc=0x%lx, (name=%s, addr=0x%lx)\n",
+ dest_pc, child->name, child->addr));
+ if (child->addr == dest_pc)
+ {
+ /* a hit: */
+ arc_add (parent, child, (unsigned long) 0);
+ continue;
+ }
+ }
+ /*
+ * Something funny going on.
+ */
+ DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
+ }
+ }
+}
diff --git a/gprof/stamp-h.in b/gprof/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/gprof/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/gprof/sym_ids.c b/gprof/sym_ids.c
new file mode 100644
index 00000000000..ba3ca28cee7
--- /dev/null
+++ b/gprof/sym_ids.c
@@ -0,0 +1,372 @@
+#include <ctype.h>
+
+#include "libiberty.h"
+#include "cg_arcs.h"
+#include "sym_ids.h"
+
+struct sym_id
+ {
+ struct sym_id *next;
+ char *spec; /* parsing modifies this */
+ Table_Id which_table;
+ bool has_right;
+ struct match
+ {
+ int prev_index; /* index of prev match */
+ Sym *prev_match; /* previous match */
+ Sym *first_match; /* chain of all matches */
+ Sym sym;
+ }
+ left, right;
+ }
+ *id_list;
+
+Sym_Table syms[NUM_TABLES];
+
+#ifdef DEBUG
+const char *table_name[] =
+{
+ "INCL_GRAPH", "EXCL_GRAPH",
+ "INCL_ARCS", "EXCL_ARCS",
+ "INCL_FLAT", "EXCL_FLAT",
+ "INCL_TIME", "EXCL_TIME",
+ "INCL_ANNO", "EXCL_ANNO",
+ "INCL_EXEC", "EXCL_EXEC"
+};
+#endif /* DEBUG */
+
+/*
+ * This is the table in which we keep all the syms that match
+ * the right half of an arc id. It is NOT sorted according
+ * to the addresses, because it is accessed only through
+ * the left half's CHILDREN pointers (so it's crucial not
+ * to reorder this table once pointers into it exist).
+ */
+static Sym_Table right_ids;
+
+static Source_File non_existent_file =
+{
+ 0, "<non-existent-file>"
+};
+
+
+void
+DEFUN (sym_id_add, (spec, which_table),
+ const char *spec AND Table_Id which_table)
+{
+ struct sym_id *id;
+ int len = strlen (spec);
+
+ id = (struct sym_id *) xmalloc (sizeof (*id) + len + 1);
+ memset (id, 0, sizeof (*id));
+
+ id->spec = (char *) id + sizeof (*id);
+ strcpy (id->spec, spec);
+ id->which_table = which_table;
+
+ id->next = id_list;
+ id_list = id;
+}
+
+
+/*
+ * A spec has the syntax FILENAME:(FUNCNAME|LINENUM). As a convenience
+ * to the user, a spec without a colon is interpreted as:
+ *
+ * (i) a FILENAME if it contains a dot
+ * (ii) a FUNCNAME if it starts with a non-digit character
+ * (iii) a LINENUM if it starts with a digit
+ *
+ * A FUNCNAME containing a dot can be specified by :FUNCNAME, a
+ * FILENAME not containing a dot can be specified by FILENAME:.
+ */
+static void
+DEFUN (parse_spec, (spec, sym), char *spec AND Sym * sym)
+{
+ char *colon;
+
+ sym_init (sym);
+ colon = strrchr (spec, ':');
+ if (colon)
+ {
+ *colon = '\0';
+ if (colon > spec)
+ {
+ sym->file = source_file_lookup_name (spec);
+ if (!sym->file)
+ {
+ sym->file = &non_existent_file;
+ }
+ }
+ spec = colon + 1;
+ if (strlen (spec))
+ {
+ if (isdigit ((unsigned char) spec[0]))
+ {
+ sym->line_num = atoi (spec);
+ }
+ else
+ {
+ sym->name = spec;
+ }
+ }
+ }
+ else if (strlen (spec))
+ {
+ /* no colon: spec is a filename if it contains a dot: */
+ if (strchr (spec, '.'))
+ {
+ sym->file = source_file_lookup_name (spec);
+ if (!sym->file)
+ {
+ sym->file = &non_existent_file;
+ }
+ }
+ else if (isdigit ((unsigned char) *spec))
+ {
+ sym->line_num = atoi (spec);
+ }
+ else if (strlen (spec))
+ {
+ sym->name = spec;
+ }
+ }
+}
+
+
+/*
+ * A symbol id has the syntax SPEC[/SPEC], where SPEC is is defined
+ * by parse_spec().
+ */
+static void
+DEFUN (parse_id, (id), struct sym_id *id)
+{
+ char *slash;
+
+ DBG (IDDEBUG, printf ("[parse_id] %s -> ", id->spec));
+
+ slash = strchr (id->spec, '/');
+ if (slash)
+ {
+ parse_spec (slash + 1, &id->right.sym);
+ *slash = '\0';
+ id->has_right = TRUE;
+ }
+ parse_spec (id->spec, &id->left.sym);
+
+#ifdef DEBUG
+ if (debug_level & IDDEBUG)
+ {
+ printf ("%s:", id->left.sym.file ? id->left.sym.file->name : "*");
+ if (id->left.sym.name)
+ {
+ printf ("%s", id->left.sym.name);
+ }
+ else if (id->left.sym.line_num)
+ {
+ printf ("%d", id->left.sym.line_num);
+ }
+ else
+ {
+ printf ("*");
+ }
+ if (id->has_right)
+ {
+ printf ("/%s:",
+ id->right.sym.file ? id->right.sym.file->name : "*");
+ if (id->right.sym.name)
+ {
+ printf ("%s", id->right.sym.name);
+ }
+ else if (id->right.sym.line_num)
+ {
+ printf ("%d", id->right.sym.line_num);
+ }
+ else
+ {
+ printf ("*");
+ }
+ }
+ printf ("\n");
+ }
+#endif
+}
+
+
+/*
+ * Return TRUE iff PATTERN matches SYM.
+ */
+static bool
+DEFUN (match, (pattern, sym), Sym * pattern AND Sym * sym)
+{
+ return (pattern->file ? pattern->file == sym->file : TRUE)
+ && (pattern->line_num ? pattern->line_num == sym->line_num : TRUE)
+ && (pattern->name ? strcmp (pattern->name, sym->name) == 0 : TRUE);
+}
+
+
+static void
+DEFUN (extend_match, (m, sym, tab, second_pass),
+ struct match *m AND Sym * sym AND Sym_Table * tab AND bool second_pass)
+{
+ if (m->prev_match != sym - 1)
+ {
+ /* discontinuity: add new match to table: */
+ if (second_pass)
+ {
+ tab->base[tab->len] = *sym;
+ m->prev_index = tab->len;
+
+ /* link match into match's chain: */
+ tab->base[tab->len].next = m->first_match;
+ m->first_match = &tab->base[tab->len];
+ }
+ ++tab->len;
+ }
+
+ /* extend match to include this symbol: */
+ if (second_pass)
+ {
+ tab->base[m->prev_index].end_addr = sym->end_addr;
+ }
+ m->prev_match = sym;
+}
+
+
+/*
+ * Go through sym_id list produced by option processing and fill
+ * in the various symbol tables indicating what symbols should
+ * be displayed or suppressed for the various kinds of outputs.
+ *
+ * This can potentially produce huge tables and in particulars
+ * tons of arcs, but this happens only if the user makes silly
+ * requests---you get what you ask for!
+ */
+void
+DEFUN_VOID (sym_id_parse)
+{
+ Sym *sym, *left, *right;
+ struct sym_id *id;
+ Sym_Table *tab;
+
+ /*
+ * Convert symbol ids into Syms, so we can deal with them more easily:
+ */
+ for (id = id_list; id; id = id->next)
+ {
+ parse_id (id);
+ }
+
+ /* first determine size of each table: */
+
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ for (id = id_list; id; id = id->next)
+ {
+ if (match (&id->left.sym, sym))
+ {
+ extend_match (&id->left, sym, &syms[id->which_table], FALSE);
+ }
+ if (id->has_right && match (&id->right.sym, sym))
+ {
+ extend_match (&id->right, sym, &right_ids, FALSE);
+ }
+ }
+ }
+
+ /* create tables of appropriate size and reset lengths: */
+
+ for (tab = syms; tab < &syms[NUM_TABLES]; ++tab)
+ {
+ if (tab->len)
+ {
+ tab->base = (Sym *) xmalloc (tab->len * sizeof (Sym));
+ tab->limit = tab->base + tab->len;
+ tab->len = 0;
+ }
+ }
+ if (right_ids.len)
+ {
+ right_ids.base = (Sym *) xmalloc (right_ids.len * sizeof (Sym));
+ right_ids.limit = right_ids.base + right_ids.len;
+ right_ids.len = 0;
+ }
+
+ /* make a second pass through symtab, creating syms as necessary: */
+
+ for (sym = symtab.base; sym < symtab.limit; ++sym)
+ {
+ for (id = id_list; id; id = id->next)
+ {
+ if (match (&id->left.sym, sym))
+ {
+ extend_match (&id->left, sym, &syms[id->which_table], TRUE);
+ }
+ if (id->has_right && match (&id->right.sym, sym))
+ {
+ extend_match (&id->right, sym, &right_ids, TRUE);
+ }
+ }
+ }
+
+ /* go through ids creating arcs as needed: */
+
+ for (id = id_list; id; id = id->next)
+ {
+ if (id->has_right)
+ {
+ for (left = id->left.first_match; left; left = left->next)
+ {
+ for (right = id->right.first_match; right; right = right->next)
+ {
+ DBG (IDDEBUG,
+ printf (
+ "[sym_id_parse]: arc %s:%s(%lx-%lx) -> %s:%s(%lx-%lx) to %s\n",
+ left->file ? left->file->name : "*",
+ left->name ? left->name : "*", left->addr,
+ left->end_addr,
+ right->file ? right->file->name : "*",
+ right->name ? right->name : "*", right->addr,
+ right->end_addr,
+ table_name[id->which_table]));
+ arc_add (left, right, (unsigned long) 0);
+ }
+ }
+ }
+ }
+
+ /* finally, we can sort the tables and we're done: */
+
+ for (tab = &syms[0]; tab < &syms[NUM_TABLES]; ++tab)
+ {
+ DBG (IDDEBUG, printf ("[sym_id_parse] syms[%s]:\n",
+ table_name[tab - &syms[0]]));
+ symtab_finalize (tab);
+ }
+}
+
+
+/*
+ * Symbol tables storing the FROM symbols of arcs do not necessarily
+ * have distinct address ranges. For example, somebody might request
+ * -k /_mcount to suppress any arcs into _mcount, while at the same
+ * time requesting -k a/b. Fortunately, those symbol tables don't get
+ * very big (the user has to type them!), so a linear search is probably
+ * tolerable.
+ */
+bool
+DEFUN (sym_id_arc_is_present, (symtab, from, to),
+ Sym_Table * symtab AND Sym * from AND Sym * to)
+{
+ Sym *sym;
+
+ for (sym = symtab->base; sym < symtab->limit; ++sym)
+ {
+ if (from->addr >= sym->addr && from->addr <= sym->end_addr
+ && arc_lookup (sym, to))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/gprof/sym_ids.h b/gprof/sym_ids.h
new file mode 100644
index 00000000000..90963381b22
--- /dev/null
+++ b/gprof/sym_ids.h
@@ -0,0 +1,25 @@
+#ifndef sym_ids_h
+#define sym_ids_h
+
+#include "symtab.h"
+
+typedef enum
+ {
+ INCL_GRAPH = 0, EXCL_GRAPH,
+ INCL_ARCS, EXCL_ARCS,
+ INCL_FLAT, EXCL_FLAT,
+ INCL_TIME, EXCL_TIME,
+ INCL_ANNO, EXCL_ANNO,
+ INCL_EXEC, EXCL_EXEC,
+ NUM_TABLES
+ }
+Table_Id;
+
+extern Sym_Table syms[NUM_TABLES];
+
+extern void sym_id_add PARAMS ((const char *spec, Table_Id which_table));
+extern void sym_id_parse PARAMS ((void));
+extern bool sym_id_arc_is_present PARAMS ((Sym_Table * symtab,
+ Sym * from, Sym * to));
+
+#endif /* sym_ids_h */
diff --git a/gprof/symtab.c b/gprof/symtab.c
new file mode 100644
index 00000000000..182c6574b4c
--- /dev/null
+++ b/gprof/symtab.c
@@ -0,0 +1,269 @@
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "symtab.h"
+
+Sym_Table symtab;
+
+
+/*
+ * Initialize a symbol (so it's empty).
+ */
+void
+DEFUN (sym_init, (sym), Sym * sym)
+{
+ memset (sym, 0, sizeof (*sym));
+ /*
+ * It is not safe to assume that a binary zero corresponds to
+ * a floating-point 0.0, so initialize floats explicitly:
+ */
+ sym->hist.time = 0.0;
+ sym->cg.child_time = 0.0;
+ sym->cg.prop.fract = 0.0;
+ sym->cg.prop.self = 0.0;
+ sym->cg.prop.child = 0.0;
+}
+
+
+/*
+ * Compare the function entry-point of two symbols and return <0, =0,
+ * or >0 depending on whether the left value is smaller than, equal
+ * to, or greater than the right value. If two symbols are equal
+ * but one has is_func set and the other doesn't, we make the
+ * non-function symbol one "bigger" so that the function symbol will
+ * survive duplicate removal. Finally, if both symbols have the
+ * same is_func value, we discriminate against is_static such that
+ * the global symbol survives.
+ */
+static int
+DEFUN (cmp_addr, (lp, rp), const PTR lp AND const PTR rp)
+{
+ Sym *left = (Sym *) lp;
+ Sym *right = (Sym *) rp;
+
+ if (left->addr > right->addr)
+ {
+ return 1;
+ }
+ else if (left->addr < right->addr)
+ {
+ return -1;
+ }
+
+ if (left->is_func != right->is_func)
+ {
+ return right->is_func - left->is_func;
+ }
+
+ return left->is_static - right->is_static;
+}
+
+
+void
+DEFUN (symtab_finalize, (tab), Sym_Table * tab)
+{
+ Sym *src, *dst;
+ bfd_vma prev_addr;
+
+ if (!tab->len)
+ {
+ return;
+ }
+
+ /*
+ * Sort symbol table in order of increasing function addresses:
+ */
+ qsort (tab->base, tab->len, sizeof (Sym), cmp_addr);
+
+ /*
+ * Remove duplicate entries to speed-up later processing and
+ * set end_addr if its not set yet:
+ */
+ prev_addr = tab->base[0].addr + 1;
+ for (src = dst = tab->base; src < tab->limit; ++src)
+ {
+ if (src->addr == prev_addr)
+ {
+ /*
+ * If same address, favor global symbol over static one,
+ * then function over line number. If both symbols are
+ * either static or global and either function or line, check
+ * whether one has name beginning with underscore while
+ * the other doesn't. In such cases, keep sym without
+ * underscore. This takes cares of compiler generated
+ * symbols (such as __gnu_compiled, __c89_used, etc.).
+ */
+ if ((!src->is_static && dst[-1].is_static)
+ || ((src->is_static == dst[-1].is_static)
+ && ((src->is_func && !dst[-1].is_func)
+ || ((src->is_func == dst[-1].is_func)
+ && ((src->name[0] != '_' && dst[-1].name[0] == '_')
+ || (src->name[0]
+ && src->name[1] != '_'
+ && dst[-1].name[1] == '_'))))))
+ {
+ DBG (AOUTDEBUG | IDDEBUG,
+ printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c",
+ src->name, src->is_static ? 't' : 'T',
+ src->is_func ? 'F' : 'f',
+ dst[-1].name, dst[-1].is_static ? 't' : 'T',
+ dst[-1].is_func ? 'F' : 'f');
+ printf (" (addr=%lx)\n", src->addr));
+ dst[-1] = *src;
+ }
+ else
+ {
+ DBG (AOUTDEBUG | IDDEBUG,
+ printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c",
+ dst[-1].name, dst[-1].is_static ? 't' : 'T',
+ dst[-1].is_func ? 'F' : 'f',
+ src->name, src->is_static ? 't' : 'T',
+ src->is_func ? 'F' : 'f');
+ printf (" (addr=%lx)\n", src->addr));
+ }
+ }
+ else
+ {
+ if (dst > tab->base && dst[-1].end_addr == 0)
+ {
+ dst[-1].end_addr = src->addr - 1;
+ }
+
+ /* retain sym only if it has a non-empty address range: */
+ if (!src->end_addr || src->addr <= src->end_addr)
+ {
+ *dst++ = *src;
+ prev_addr = src->addr;
+ }
+ }
+ }
+ if (tab->len > 0 && dst[-1].end_addr == 0)
+ {
+ dst[-1].end_addr = core_text_sect->vma + core_text_sect->_raw_size - 1;
+ }
+
+ DBG (AOUTDEBUG | IDDEBUG,
+ printf ("[symtab_finalize]: removed %d duplicate entries\n",
+ tab->len - (int) (dst - tab->base)));
+
+ tab->limit = dst;
+ tab->len = tab->limit - tab->base;
+
+ DBG (AOUTDEBUG | IDDEBUG,
+ unsigned int j;
+
+ for (j = 0; j < tab->len; ++j)
+ {
+ printf ("[symtab_finalize] 0x%lx-0x%lx\t%s\n",
+ (long) tab->base[j].addr, (long) tab->base[j].end_addr,
+ tab->base[j].name);
+ }
+ );
+}
+
+
+#ifdef DEBUG
+
+Sym *
+DEFUN (dbg_sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address)
+{
+ long low, mid, high;
+ Sym *sym;
+
+ fprintf (stderr, "[dbg_sym_lookup] address 0x%lx\n", address);
+
+ sym = symtab->base;
+ for (low = 0, high = symtab->len - 1; low != high;)
+ {
+ mid = (high + low) >> 1;
+ fprintf (stderr, "[dbg_sym_lookup] low=0x%lx, mid=0x%lx, high=0x%lx\n",
+ low, mid, high);
+ fprintf (stderr, "[dbg_sym_lookup] sym[m]=0x%lx sym[m + 1]=0x%lx\n",
+ sym[mid].addr, sym[mid + 1].addr);
+ if (sym[mid].addr <= address && sym[mid + 1].addr > address)
+ {
+ return &sym[mid];
+ }
+ if (sym[mid].addr > address)
+ {
+ high = mid;
+ }
+ else
+ {
+ low = mid + 1;
+ }
+ }
+ fprintf (stderr, "[dbg_sym_lookup] binary search fails???\n");
+ return 0;
+}
+
+#endif /* DEBUG */
+
+
+/*
+ * Look up an address in the symbol-table that is sorted by address.
+ * If address does not hit any symbol, 0 is returned.
+ */
+Sym *
+DEFUN (sym_lookup, (symtab, address), Sym_Table * symtab AND bfd_vma address)
+{
+ long low, high;
+ long mid = -1;
+ Sym *sym;
+#ifdef DEBUG
+ int probes = 0;
+#endif /* DEBUG */
+
+ if (!symtab->len)
+ {
+ return 0;
+ }
+
+ sym = symtab->base;
+ for (low = 0, high = symtab->len - 1; low != high;)
+ {
+ DBG (LOOKUPDEBUG, ++probes);
+ mid = (high + low) / 2;
+ if (sym[mid].addr <= address && sym[mid + 1].addr > address)
+ {
+ if (address > sym[mid].end_addr)
+ {
+ /*
+ * Address falls into gap between sym[mid] and
+ * sym[mid + 1]:
+ */
+ return 0;
+ }
+ else
+ {
+ DBG (LOOKUPDEBUG,
+ printf ("[sym_lookup] %d probes (symtab->len=%u)\n",
+ probes, symtab->len - 1));
+ return &sym[mid];
+ }
+ }
+ if (sym[mid].addr > address)
+ {
+ high = mid;
+ }
+ else
+ {
+ low = mid + 1;
+ }
+ }
+ if (sym[mid + 1].addr <= address)
+ {
+ if (address > sym[mid + 1].end_addr)
+ {
+ /* address is beyond end of sym[mid + 1]: */
+ return 0;
+ }
+ else
+ {
+ DBG (LOOKUPDEBUG, printf ("[sym_lookup] %d (%u) probes, fall off\n",
+ probes, symtab->len - 1));
+ return &sym[mid + 1];
+ }
+ }
+ return 0;
+}
diff --git a/gprof/symtab.h b/gprof/symtab.h
new file mode 100644
index 00000000000..a6a450ef1ee
--- /dev/null
+++ b/gprof/symtab.h
@@ -0,0 +1,111 @@
+#ifndef symtab_h
+#define symtab_h
+
+#include "bfd.h"
+#include "gprof.h"
+
+/*
+ * For a profile to be intelligible to a human user, it is necessary
+ * to map code-addresses into source-code information. Source-code
+ * information can be any combination of: (i) function-name, (ii)
+ * source file-name, and (iii) source line number.
+ *
+ * The symbol table is used to map addresses into source-code
+ * information.
+ */
+
+#include "source.h"
+
+#define NBBS 10
+
+/*
+ * Symbol-entry. For each external in the specified file we gather
+ * its address, the number of calls and compute its share of cpu time.
+ */
+typedef struct sym
+ {
+ /*
+ * Common information:
+ *
+ * In the symbol-table, fields ADDR and FUNC_NAME are guaranteed
+ * to contain valid information. FILE may be 0, if unknown and
+ * LINE_NUM maybe 0 if unknown.
+ */
+ bfd_vma addr; /* address of entry point */
+ bfd_vma end_addr; /* end-address */
+ const char *name; /* name of function this sym is from */
+ Source_File *file; /* source file symbol comes from */
+ int line_num; /* source line number */
+ unsigned int is_func:1, /* is this a function entry point? */
+ is_static:1, /* is this a local (static) symbol? */
+ is_bb_head:1, /* is this the head of a basic-blk? */
+ mapped:1, /* this symbol was mapped to another name */
+ has_been_placed:1; /* have we placed this symbol? */
+ unsigned long ncalls; /* how many times executed */
+ int nuses; /* how many times this symbol appears in
+ a particular context */
+ bfd_vma bb_addr[NBBS]; /* address of basic-block start */
+ unsigned long bb_calls[NBBS]; /* how many times basic-block was called */
+ struct sym *next; /* for building chains of syms */
+ struct sym *prev; /* for building chains of syms */
+
+ /* profile-specific information: */
+
+ /* histogram specific info: */
+ struct
+ {
+ double time; /* (weighted) ticks in this routine */
+ bfd_vma scaled_addr; /* scaled entry point */
+ }
+ hist;
+
+ /* call-graph specific info: */
+ struct
+ {
+ unsigned long self_calls; /* how many calls to self */
+ double child_time; /* cumulative ticks in children */
+ int index; /* index in the graph list */
+ int top_order; /* graph call chain top-sort order */
+ bool print_flag; /* should this be printed? */
+ struct
+ {
+ double fract; /* what % of time propagates */
+ double self; /* how much self time propagates */
+ double child; /* how much child time propagates */
+ }
+ prop;
+ struct
+ {
+ int num; /* internal number of cycle on */
+ struct sym *head; /* head of cycle */
+ struct sym *next; /* next member of cycle */
+ }
+ cyc;
+ struct arc *parents; /* list of caller arcs */
+ struct arc *children; /* list of callee arcs */
+ }
+ cg;
+ }
+Sym;
+
+/*
+ * Symbol-tables are always assumed to be sorted in increasing order
+ * of addresses:
+ */
+typedef struct
+ {
+ unsigned int len; /* # of symbols in this table */
+ Sym *base; /* first element in symbol table */
+ Sym *limit; /* limit = base + len */
+ }
+Sym_Table;
+
+extern Sym_Table symtab; /* the symbol table */
+
+extern void sym_init PARAMS ((Sym * sym));
+extern void symtab_finalize PARAMS ((Sym_Table * symtab));
+extern Sym *sym_lookup PARAMS ((Sym_Table * symtab, bfd_vma address));
+
+extern void find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+
+#endif /* symtab_h */
diff --git a/gprof/tahoe.c b/gprof/tahoe.c
new file mode 100644
index 00000000000..d133c177950
--- /dev/null
+++ b/gprof/tahoe.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+#include "symtab.h"
+
+ /*
+ * opcode of the `callf' instruction
+ */
+#define CALLF 0xfe
+
+ /*
+ * register for pc relative addressing
+ */
+#define PC 0xf
+
+enum tahoe_opermodes
+ {
+ literal, indexed, reg, regdef, autodec, autoinc, autoincdef,
+ bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef,
+ immediate, absolute, byterel, bytereldef, wordrel, wordreldef,
+ longrel, longreldef
+ };
+typedef enum tahoe_opermodes tahoe_operandenum;
+
+/*
+ * A symbol to be the child of indirect callf:
+ */
+Sym indirectchild;
+
+
+tahoe_operandenum
+tahoe_operandmode (modep)
+ unsigned char *modep;
+{
+ long usesreg = ((long) *modep) & 0xf;
+
+ switch (((long) *modep) >> 4)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return literal;
+ case 4:
+ return indexed;
+ case 5:
+ return reg;
+ case 6:
+ return regdef;
+ case 7:
+ return autodec;
+ case 8:
+ return usesreg != 0xe ? autoinc : immediate;
+ case 9:
+ return usesreg != PC ? autoincdef : absolute;
+ case 10:
+ return usesreg != PC ? bytedisp : byterel;
+ case 11:
+ return usesreg != PC ? bytedispdef : bytereldef;
+ case 12:
+ return usesreg != PC ? worddisp : wordrel;
+ case 13:
+ return usesreg != PC ? worddispdef : wordreldef;
+ case 14:
+ return usesreg != PC ? longdisp : longrel;
+ case 15:
+ return usesreg != PC ? longdispdef : longreldef;
+ }
+ /* NOTREACHED */
+ abort ();
+}
+
+char *
+tahoe_operandname (mode)
+ tahoe_operandenum mode;
+{
+
+ switch (mode)
+ {
+ case literal:
+ return "literal";
+ case indexed:
+ return "indexed";
+ case reg:
+ return "register";
+ case regdef:
+ return "register deferred";
+ case autodec:
+ return "autodecrement";
+ case autoinc:
+ return "autoincrement";
+ case autoincdef:
+ return "autoincrement deferred";
+ case bytedisp:
+ return "byte displacement";
+ case bytedispdef:
+ return "byte displacement deferred";
+ case byterel:
+ return "byte relative";
+ case bytereldef:
+ return "byte relative deferred";
+ case worddisp:
+ return "word displacement";
+ case worddispdef:
+ return "word displacement deferred";
+ case wordrel:
+ return "word relative";
+ case wordreldef:
+ return "word relative deferred";
+ case immediate:
+ return "immediate";
+ case absolute:
+ return "absolute";
+ case longdisp:
+ return "long displacement";
+ case longdispdef:
+ return "long displacement deferred";
+ case longrel:
+ return "long relative";
+ case longreldef:
+ return "long relative deferred";
+ }
+ /* NOTREACHED */
+ abort ();
+}
+
+long
+tahoe_operandlength (modep)
+ unsigned char *modep;
+{
+
+ switch (tahoe_operandmode (modep))
+ {
+ case literal:
+ case reg:
+ case regdef:
+ case autodec:
+ case autoinc:
+ case autoincdef:
+ return 1;
+ case bytedisp:
+ case bytedispdef:
+ case byterel:
+ case bytereldef:
+ return 2;
+ case worddisp:
+ case worddispdef:
+ case wordrel:
+ case wordreldef:
+ return 3;
+ case immediate:
+ case absolute:
+ case longdisp:
+ case longdispdef:
+ case longrel:
+ case longreldef:
+ return 5;
+ case indexed:
+ return 1 + tahoe_operandlength (modep + 1);
+ }
+ /* NOTREACHED */
+ abort ();
+}
+
+bfd_vma
+tahoe_reladdr (modep)
+ char *modep;
+{
+ tahoe_operandenum mode = tahoe_operandmode (modep);
+ char *cp;
+ short *sp;
+ long *lp;
+ int i;
+ long value = 0;
+
+ cp = modep;
+ ++cp; /* skip over the mode */
+ switch (mode)
+ {
+ default:
+ fprintf (stderr, "[reladdr] not relative address\n");
+ return (bfd_vma) modep;
+ case byterel:
+ return (bfd_vma) (cp + sizeof *cp + *cp);
+ case wordrel:
+ for (i = 0; (size_t) i < sizeof *sp; i++)
+ value = (value << 8) + (cp[i] & 0xff);
+ return (bfd_vma) (cp + sizeof *sp + value);
+ case longrel:
+ for (i = 0; (size_t) i < sizeof *lp; i++)
+ value = (value << 8) + (cp[i] & 0xff);
+ return (bfd_vma) (cp + sizeof *lp + value);
+ }
+}
+
+void
+tahoe_find_call (parent, p_lowpc, p_highpc)
+ Sym *parent;
+ bfd_vma p_lowpc;
+ bfd_vma p_highpc;
+{
+ unsigned char *instructp;
+ long length;
+ Sym *child;
+ tahoe_operandenum mode;
+ tahoe_operandenum firstmode;
+ bfd_vma destpc;
+ static bool inited = FALSE;
+
+ if (!inited)
+ {
+ inited = TRUE;
+ sym_init (&indirectchild);
+ indirectchild.cg.prop.fract = 1.0;
+ indirectchild.cg.cyc.head = &indirectchild;
+ }
+
+ if (core_text_space == 0)
+ {
+ return;
+ }
+ if (p_lowpc < s_lowpc)
+ {
+ p_lowpc = s_lowpc;
+ }
+ if (p_highpc > s_highpc)
+ {
+ p_highpc = s_highpc;
+ }
+ DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
+ parent->name, p_lowpc, p_highpc));
+ for (instructp = (unsigned char *) core_text_space + p_lowpc;
+ instructp < (unsigned char *) core_text_space + p_highpc;
+ instructp += length)
+ {
+ length = 1;
+ if (*instructp == CALLF)
+ {
+ /*
+ * maybe a callf, better check it out.
+ * skip the count of the number of arguments.
+ */
+ DBG (CALLDEBUG, printf ("[findcall]\t0x%x:callf",
+ instructp - (unsigned char *) core_text_space));
+ firstmode = tahoe_operandmode (instructp + length);
+ switch (firstmode)
+ {
+ case literal:
+ case immediate:
+ break;
+ default:
+ goto botched;
+ }
+ length += tahoe_operandlength (instructp + length);
+ mode = tahoe_operandmode (instructp + length);
+ DBG (CALLDEBUG,
+ printf ("\tfirst operand is %s", tahoe_operandname (firstmode));
+ printf ("\tsecond operand is %s\n", tahoe_operandname (mode));
+ );
+ switch (mode)
+ {
+ case regdef:
+ case bytedispdef:
+ case worddispdef:
+ case longdispdef:
+ case bytereldef:
+ case wordreldef:
+ case longreldef:
+ /*
+ * indirect call: call through pointer
+ * either *d(r) as a parameter or local
+ * (r) as a return value
+ * *f as a global pointer
+ * [are there others that we miss?,
+ * e.g. arrays of pointers to functions???]
+ */
+ arc_add (parent, &indirectchild, (unsigned long) 0);
+ length += tahoe_operandlength (instructp + length);
+ continue;
+ case byterel:
+ case wordrel:
+ case longrel:
+ /*
+ * regular pc relative addressing
+ * check that this is the address of
+ * a function.
+ */
+ destpc = tahoe_reladdr (instructp + length)
+ - (bfd_vma) core_text_space;
+ if (destpc >= s_lowpc && destpc <= s_highpc)
+ {
+ child = sym_lookup (&symtab, destpc);
+ DBG (CALLDEBUG,
+ printf ("[findcall]\tdestpc 0x%lx", destpc);
+ printf (" child->name %s", child->name);
+ printf (" child->addr 0x%lx\n", child->addr);
+ );
+ if (child->addr == destpc)
+ {
+ /*
+ * a hit
+ */
+ arc_add (parent, child, (unsigned long) 0);
+ length += tahoe_operandlength (instructp + length);
+ continue;
+ }
+ goto botched;
+ }
+ /*
+ * else:
+ * it looked like a callf,
+ * but it wasn't to anywhere.
+ */
+ goto botched;
+ default:
+ botched:
+ /*
+ * something funny going on.
+ */
+ DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));
+ length = 1;
+ continue;
+ }
+ }
+ }
+}
diff --git a/gprof/utils.c b/gprof/utils.c
new file mode 100644
index 00000000000..e1f031d5e8d
--- /dev/null
+++ b/gprof/utils.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1983, 1998 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <demangle.h>
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "symtab.h"
+
+
+/*
+ * Print name of symbol. Return number of characters printed.
+ */
+int
+DEFUN (print_name_only, (self), Sym * self)
+{
+ const char *name = self->name;
+ const char *filename;
+ char *demangled = 0;
+ char buf[PATH_MAX];
+ int size = 0;
+
+ if (name)
+ {
+ if (!bsd_style_output)
+ {
+ if (name[0] == '_' && name[1] && discard_underscores)
+ {
+ name++;
+ }
+ if (demangle)
+ {
+ demangled = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ if (demangled)
+ {
+ name = demangled;
+ }
+ }
+ }
+ printf ("%s", name);
+ size = strlen (name);
+ if (line_granularity && self->file)
+ {
+ filename = self->file->name;
+ if (!print_path)
+ {
+ filename = strrchr (filename, '/');
+ if (filename)
+ {
+ ++filename;
+ }
+ else
+ {
+ filename = self->file->name;
+ }
+ }
+ sprintf (buf, " (%s:%d)", filename, self->line_num);
+ printf (buf);
+ size += strlen (buf);
+ }
+ if (demangled)
+ {
+ free (demangled);
+ }
+ DBG (DFNDEBUG, printf ("{%d} ", self->cg.top_order));
+ DBG (PROPDEBUG, printf ("%4.0f%% ", 100.0 * self->cg.prop.fract));
+ }
+ return size;
+}
+
+
+void
+DEFUN (print_name, (self), Sym * self)
+{
+ print_name_only (self);
+
+ if (self->cg.cyc.num != 0)
+ {
+ printf (_(" <cycle %d>"), self->cg.cyc.num);
+ }
+ if (self->cg.index != 0)
+ {
+ if (self->cg.print_flag)
+ {
+ printf (" [%d]", self->cg.index);
+ }
+ else
+ {
+ printf (" (%d)", self->cg.index);
+ }
+ }
+}
diff --git a/gprof/utils.h b/gprof/utils.h
new file mode 100644
index 00000000000..27fb9c67349
--- /dev/null
+++ b/gprof/utils.h
@@ -0,0 +1,7 @@
+#ifndef utils_h
+#define utils_h
+
+extern int print_name_only PARAMS ((Sym * self));
+extern void print_name PARAMS ((Sym * self));
+
+#endif /* utils_h */
diff --git a/gprof/vax.c b/gprof/vax.c
new file mode 100644
index 00000000000..1a7bd8dc146
--- /dev/null
+++ b/gprof/vax.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement: ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include "gprof.h"
+#include "cg_arcs.h"
+#include "corefile.h"
+#include "hist.h"
+#include "symtab.h"
+
+ /*
+ * opcode of the `calls' instruction
+ */
+#define CALLS 0xfb
+
+ /*
+ * register for pc relative addressing
+ */
+#define PC 0xf
+
+enum opermodes
+ {
+ literal, indexed, reg, regdef, autodec, autoinc, autoincdef,
+ bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef,
+ immediate, absolute, byterel, bytereldef, wordrel, wordreldef,
+ longrel, longreldef
+ };
+typedef enum opermodes operandenum;
+
+struct modebyte
+ {
+ unsigned int regfield:4;
+ unsigned int modefield:4;
+ };
+
+/*
+ * A symbol to be the child of indirect calls:
+ */
+Sym indirectchild;
+
+
+static operandenum
+vax_operandmode (modep)
+ struct modebyte *modep;
+{
+ long usesreg = modep->regfield;
+
+ switch (modep->modefield)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return literal;
+ case 4:
+ return indexed;
+ case 5:
+ return reg;
+ case 6:
+ return regdef;
+ case 7:
+ return autodec;
+ case 8:
+ return usesreg != PC ? autoinc : immediate;
+ case 9:
+ return usesreg != PC ? autoincdef : absolute;
+ case 10:
+ return usesreg != PC ? bytedisp : byterel;
+ case 11:
+ return usesreg != PC ? bytedispdef : bytereldef;
+ case 12:
+ return usesreg != PC ? worddisp : wordrel;
+ case 13:
+ return usesreg != PC ? worddispdef : wordreldef;
+ case 14:
+ return usesreg != PC ? longdisp : longrel;
+ case 15:
+ return usesreg != PC ? longdispdef : longreldef;
+ }
+ /* NOTREACHED */
+ abort ();
+}
+
+static char *
+vax_operandname (mode)
+ operandenum mode;
+{
+
+ switch (mode)
+ {
+ case literal:
+ return "literal";
+ case indexed:
+ return "indexed";
+ case reg:
+ return "register";
+ case regdef:
+ return "register deferred";
+ case autodec:
+ return "autodecrement";
+ case autoinc:
+ return "autoincrement";
+ case autoincdef:
+ return "autoincrement deferred";
+ case bytedisp:
+ return "byte displacement";
+ case bytedispdef:
+ return "byte displacement deferred";
+ case byterel:
+ return "byte relative";
+ case bytereldef:
+ return "byte relative deferred";
+ case worddisp:
+ return "word displacement";
+ case worddispdef:
+ return "word displacement deferred";
+ case wordrel:
+ return "word relative";
+ case wordreldef:
+ return "word relative deferred";
+ case immediate:
+ return "immediate";
+ case absolute:
+ return "absolute";
+ case longdisp:
+ return "long displacement";
+ case longdispdef:
+ return "long displacement deferred";
+ case longrel:
+ return "long relative";
+ case longreldef:
+ return "long relative deferred";
+ }
+ /* NOTREACHED */
+ abort ();
+}
+
+static long
+vax_operandlength (modep)
+ struct modebyte *modep;
+{
+
+ switch (vax_operandmode (modep))
+ {
+ case literal:
+ case reg:
+ case regdef:
+ case autodec:
+ case autoinc:
+ case autoincdef:
+ return 1;
+ case bytedisp:
+ case bytedispdef:
+ case byterel:
+ case bytereldef:
+ return 2;
+ case worddisp:
+ case worddispdef:
+ case wordrel:
+ case wordreldef:
+ return 3;
+ case immediate:
+ case absolute:
+ case longdisp:
+ case longdispdef:
+ case longrel:
+ case longreldef:
+ return 5;
+ case indexed:
+ return 1 + vax_operandlength ((struct modebyte *) ((char *) modep) + 1);
+ }
+ /* NOTREACHED */
+ abort ();
+}
+
+static bfd_vma
+vax_reladdr (modep)
+ struct modebyte *modep;
+{
+ operandenum mode = vax_operandmode (modep);
+ char *cp;
+ short *sp;
+ long *lp;
+
+ cp = (char *) modep;
+ ++cp; /* skip over the mode */
+ switch (mode)
+ {
+ default:
+ fprintf (stderr, "[reladdr] not relative address\n");
+ return (bfd_vma) modep;
+ case byterel:
+ return (bfd_vma) (cp + sizeof *cp + *cp);
+ case wordrel:
+ sp = (short *) cp;
+ return (bfd_vma) (cp + sizeof *sp + *sp);
+ case longrel:
+ lp = (long *) cp;
+ return (bfd_vma) (cp + sizeof *lp + *lp);
+ }
+}
+
+
+void
+vax_find_call (parent, p_lowpc, p_highpc)
+ Sym *parent;
+ bfd_vma p_lowpc;
+ bfd_vma p_highpc;
+{
+ unsigned char *instructp;
+ long length;
+ Sym *child;
+ operandenum mode;
+ operandenum firstmode;
+ bfd_vma destpc;
+ static bool inited = FALSE;
+
+ if (!inited)
+ {
+ inited = TRUE;
+ sym_init (&indirectchild);
+ indirectchild.cg.prop.fract = 1.0;
+ indirectchild.cg.cyc.head = &indirectchild;
+ }
+
+ if (core_text_space == 0)
+ {
+ return;
+ }
+ if (p_lowpc < s_lowpc)
+ {
+ p_lowpc = s_lowpc;
+ }
+ if (p_highpc > s_highpc)
+ {
+ p_highpc = s_highpc;
+ }
+ DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
+ parent->name, p_lowpc, p_highpc));
+ for (instructp = (unsigned char *) core_text_space + p_lowpc;
+ instructp < (unsigned char *) core_text_space + p_highpc;
+ instructp += length)
+ {
+ length = 1;
+ if (*instructp == CALLS)
+ {
+ /*
+ * maybe a calls, better check it out.
+ * skip the count of the number of arguments.
+ */
+ DBG (CALLDEBUG,
+ printf ("[findcall]\t0x%x:calls",
+ instructp - (unsigned char *) core_text_space));
+ firstmode = vax_operandmode ((struct modebyte *) (instructp + length));
+ switch (firstmode)
+ {
+ case literal:
+ case immediate:
+ break;
+ default:
+ goto botched;
+ }
+ length += vax_operandlength ((struct modebyte *) (instructp + length));
+ mode = vax_operandmode ((struct modebyte *) (instructp + length));
+ DBG (CALLDEBUG,
+ printf ("\tfirst operand is %s", vax_operandname (firstmode));
+ printf ("\tsecond operand is %s\n", vax_operandname (mode)));
+ switch (mode)
+ {
+ case regdef:
+ case bytedispdef:
+ case worddispdef:
+ case longdispdef:
+ case bytereldef:
+ case wordreldef:
+ case longreldef:
+ /*
+ * indirect call: call through pointer
+ * either *d(r) as a parameter or local
+ * (r) as a return value
+ * *f as a global pointer
+ * [are there others that we miss?,
+ * e.g. arrays of pointers to functions???]
+ */
+ arc_add (parent, &indirectchild, (unsigned long) 0);
+ length += vax_operandlength (
+ (struct modebyte *) (instructp + length));
+ continue;
+ case byterel:
+ case wordrel:
+ case longrel:
+ /*
+ * regular pc relative addressing
+ * check that this is the address of
+ * a function.
+ */
+ destpc = vax_reladdr ((struct modebyte *) (instructp + length))
+ - (bfd_vma) core_text_space;
+ if (destpc >= s_lowpc && destpc <= s_highpc)
+ {
+ child = sym_lookup (&symtab, destpc);
+ DBG (CALLDEBUG,
+ printf ("[findcall]\tdestpc 0x%lx", destpc);
+ printf (" child->name %s", child->name);
+ printf (" child->addr 0x%lx\n", child->addr);
+ );
+ if (child->addr == destpc)
+ {
+ /*
+ * a hit
+ */
+ arc_add (parent, child, (unsigned long) 0);
+ length += vax_operandlength ((struct modebyte *)
+ (instructp + length));
+ continue;
+ }
+ goto botched;
+ }
+ /*
+ * else:
+ * it looked like a calls,
+ * but it wasn't to anywhere.
+ */
+ goto botched;
+ default:
+ botched:
+ /*
+ * something funny going on.
+ */
+ DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));
+ length = 1;
+ continue;
+ }
+ }
+ }
+}
diff --git a/include/COPYING b/include/COPYING
new file mode 100644
index 00000000000..60549be514a
--- /dev/null
+++ b/include/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/include/ChangeLog b/include/ChangeLog
new file mode 100644
index 00000000000..fbadf92fdf4
--- /dev/null
+++ b/include/ChangeLog
@@ -0,0 +1,1527 @@
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * bfdlink.h (bfd_elf_version_expr): Rename `match' to `pattern'.
+ Add `match' callback function.
+
+1999-04-10 Richard Henderson <rth@cygnus.com>
+
+ * bfdlink.h (bfd_link_info): Add no_undefined.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * dis-asm.h: Add prototype for print_insn_mcore.
+
+1999-04-02 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.h (splay_tree_compare_pointers): Declare.
+
+1999-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.h (splay_tree_compare_ints): Declare.
+
+Wed Mar 24 12:46:29 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * libiberty.h (basename): Cygwin{,32} should have the prototype.
+
+1999-02-22 Jim Lemke <jlemke@cygnus.com>
+
+ * bfdlink.h (bfd_link_info): add field "mpc860c0".
+
+Mon Feb 1 21:05:46 1999 Catherine Moore <clm@cygnus.com>
+
+ * dis-asm.h (print_insn_i386_att): Declare.
+ (print_insn_i386_intel): Declare.
+
+998-12-30 Michael Meissner <meissner@cygnus.com>
+
+ * dis-asm.h (INIT_DISASSEMBLE_INFO_NO_ARCH): Cast STREAM and
+ FPRINTF_FUNC to avoid compiler warnings.
+
+Wed Dec 30 16:07:14 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * dis-asm.h: change void * to PTR (two places).
+
+Mon Dec 14 09:53:31 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * demangle.h: Don't check IN_GCC anymore.
+ * splay-tree.h: Likewise.
+
+Tue Dec 8 00:30:31 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ The following changes were made by Elena Zannoni
+ <ezannoni@kwikemart.cygnus.com> and Edith Epstein
+ <eepstein@sophia.cygnus.com> as part of a project to merge in
+ changes made by HP; HP did not create ChangeLog entries.
+
+ * dis-asm.h (struct disassemble_info): change the type of stream
+ from FILE* to void*, for use with gdb's new type GDB_FILE.
+ (fprintf_ftype): change FILE* parameter type to void*.
+
+ * demangle.h: (DMGL_EDG): new macro for Kuck and Associates
+ (DMGL_STYLE_MASK): modify to include Kuck and Assoc style
+ (demangling_styles): add new edg_demangling style
+ (EDG_DEMANGLING_STYLE_STRING): new macro
+ (EDG_DEMANGLING): new macro
+
+ * demangle.h (DMGL_HP): new macro, for HP/aCC compiler.
+ (DMGL_STYLE_MASK): modify to include new HP's style.
+ (demangling_styles): add new hp_demangling value.
+ (HP_DEMANGLING_STYLE_STRING): new macro.
+ (ARM_DEMANGLING): coerce to int.
+ (HP_DEMANGLING): new macro.
+
+ * hp-symtab.h: rewritten, from HP.
+ (quick_procedure): change type of language field to unsigned int
+ (quick_module): change type of language field to unsigned int
+ (struct dntt_type_svar): add field thread_specific.
+ (hp_language): add languages modcal and dmpascal.
+
+Mon Nov 30 15:25:58 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * elf/sh.h (elf_sh_reloc_type): Add R_SH_FIRST_INVALID_RELOC,
+ R_SH_LAST_INVALID_RELOC, R_SH_SWITCH8 and R_SH_max.
+
+Fri Nov 20 13:14:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * libiberty.h (basename): Add prototype for FreeBSD.
+
+Fri Nov 13 19:19:11 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libiberty.h: Prototype xcalloc.
+
+Sun Nov 8 17:42:25 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ansidecl.h: Wrap problematic macros with !IN_GCC.
+
+ * demangle.h: Never define PARAMS().
+ * splay-tree.h: Likewise.
+
+Sat Nov 7 18:30:20 1998 Peter Schauer <peter.schauer@regent.e-technik.tu-muenchen.de>
+
+ * dis-asm.h (print_insn_vax): Declare.
+
+Sat Nov 7 16:04:03 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * demangle.h: Don't include gansidecl.h.
+ * splay-tree.h: Likewise.
+
+1998-10-26 16:03 Ulrich Drepper <drepper@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Add new field optimize.
+
+Thu Oct 22 19:58:00 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * splay-tree.h: Wrap function pointer parameter declarations in
+ PARAMS() macro.
+
+1998-10-21 Mark Mitchell <mark@markmitchell.com>
+
+ * splay-tree.h: New file.
+
+Fri Oct 9 00:02:03 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Merge devo and egcs include directories.
+
+Sat Sep 5 12:16:33 1998 Jeffrey A Law (law@cygnus.com)
+
+ * getopt.h, obstack.h: Updated from gcc.
+
+1998-08-03 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * libiberty.h (xexit): Change decl to use modern GCC attribute
+ to indicate exit does not return.
+
+Mon Jun 1 13:48:32 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * obstack.h: Update to latest FSF version.
+
+Tue May 26 20:57:43 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * elf/sparc.h (EF_SPARC_LEDATA, R_SPARC_32LE): Added.
+
+Tue Feb 24 13:05:02 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * dis-asm.h (disassemble_info): Member `symbol' renamed to `symbols'
+ and made an "asymbol **". New member num_symbols.
+ (INIT_DISASSEMBLE_INFO_NO_ARCH): Update.
+
+Tue Feb 17 12:32:18 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_fetch_register, sim_store_register): Add
+ register length parameter. Functions return actual length of
+ register.
+
+Thu Feb 12 16:29:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * getopt.h: Update to latest FSF version.
+
+Wed Feb 11 16:56:06 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * symcat.h: New file.
+
+Mon Feb 2 17:13:31 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ * dis-asm.h (print_insn_tic30): Declare.
+
+Thu Jan 22 16:23:59 1998 Fred Fish <fnf@cygnus.com>
+
+ * dis-asm.h: Add flag INSN_HAS_RELOC to tell disassembly
+ function there is a reloc on this line.
+
+Mon Dec 8 11:22:23 1997 Nick Clifton <nickc@cygnus.com>
+
+ * dis-asm.h: Remove prototype of disasm_symaddr() as this function
+ no longer exists.
+
+Tue Dec 2 10:20:53 1997 Nick Clifton <nickc@cygnus.com>
+
+ * dis-asm.h (disasm_symaddr): New prototype.
+
+Mon Dec 1 20:24:18 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * coff/sh.h (R_SH_SWITCH8): New.
+
+Mon Dec 1 11:29:35 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * callback.h (CB_SYSCALL): Comment out arg names in prototypes.
+
+Wed Nov 26 16:47:58 1997 Michael Meissner <meissner@cygnus.com>
+
+ * callback.h (CB_SYSCALL): Consistantly use names for prototype
+ arguments.
+
+Wed Nov 26 11:39:30 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * callback.h (CB_SYSCALL): Change byte count arguments to
+ {read,write}_mem to `int'. New member `magic'.
+ (CB_SYSCALL_MAGIC,CB_SYSCALL_INIT): New macros.
+
+Tue Nov 25 01:35:52 1997 Doug Evans <devans@seba.cygnus.com>
+
+ * callback.h (struct stat): Move forward decl up.
+ (host_callback): Pass stat struct pointer to stat,fstat.
+ (CB_SYS_nnn): Reorganize.
+ (CB_SYSCALL): New members p1,p2.
+ (cb_host_to_target_stat): Delete fourth arg.
+
+Sat Nov 22 23:34:15 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_stop_reason): Clarify sim_signalled SIGRC
+ argument.
+
+Mon Nov 17 14:00:51 1997 Doug Evans <devans@seba.cygnus.com>
+
+ * callback.h (CB_TARGET_DEFS_MAP): Renamed from target_defs_map.
+ (host_callback): Add stat, fstat, syscall_map, errno_map, open_map,
+ signal_map, stat_map.
+ (errn_map,open_map): Renamed to cb_init_foo_map.
+ (cb_host_to_target_errno,cb_target_to_host_open): Renamed from
+ host_to_target_errno,target_to_host_open.
+ (cb_read_target_syscall_maps): Add prototype.
+ (cb_target_to_host_syscall): Likewise.
+ (cb_host_to_target_stat): Likewise.
+ (cb_syscall): Likewise.
+ (CB_SYS_{exit,open,close,read,write,lseek,unlink,getpid,kill,fstat,
+ argvlen,argv,chdir,stat,chmod,utime,time}): Define.
+ (CB_SYSCALL): New type.
+ (CB_RC): New enum.
+
+Fri Nov 7 10:34:09 1997 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * libiberty.h: Add extern "C" { so it can be used with C++
+ programs.
+ * remote-sim.h: Add extern "C" { so it can be used with C++
+ programs.
+
+Tue Oct 14 16:07:51 1997 Nick Clifton <nickc@cygnus.com>
+
+ * dis-asm.h (struct disassemble_info): New field
+ 'symbol_at_address_func'.
+ (INIT_DISASSEMBLE_INFO_NO_ARCH): Initialise new field with
+ generic_symbol_at_address.
+
+Mon Oct 13 10:17:15 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h: Clarify sim_read, sim_write MEM argument.
+
+Wed Sep 24 18:03:10 1997 Stu Grossman <grossman@babylon-5.cygnus.com>
+
+ * remote-sim.h (SIM_RC): Add a bunch of new return codes for
+ breakpoint stuff.
+ * Add functions to tell the simulator to set/clear/enable/disable
+ intrinsic breakpoints.
+
+Thu Aug 28 19:41:42 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * libiberty.h (dupargv): Add prototype.
+
+Tue Aug 26 12:25:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_create_inferior): Add ABFD arg. Document.
+
+Mon Aug 25 10:50:51 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_open): Add ABFD arg. Document.
+
+Fri Aug 8 16:43:56 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * dis-asm.h (arc_get_disassembler): Declare.
+
+Wed Jul 30 11:39:50 1997 Per Bothner <bothner@deneb.cygnus.com>
+
+ * demangle.h (DMGL_JAVA): New option to request Java demangling.
+
+Tue Jul 22 17:59:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * libiberty.h (PEXECUTE_*): Define.
+ (pexecute, pwait): Declare.
+
+Fri Jun 6 13:02:33 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_kill): Mark as depreciated.
+
+Fri May 23 13:43:41 1997 Fred Fish <fnf@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Add task_link member.
+
+Thu May 22 11:32:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h: Review documentation. Clarify restrictions on
+ when functions can be called.
+
+Wed May 21 16:47:53 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_set_profile_size): Add prototype, document as
+ depreciated.
+
+Tue May 20 09:32:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_open): Add callback struct.
+ (sim_set_callbacks): Drop SIM_DESC argument. Document.
+ (sim_size): Remove recently added SIM_DESC argument. Document.
+
+Mon May 19 19:14:44 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h: Pass SD into sim_size.
+
+Thu May 15 01:24:16 1997 Mark Alexander <marka@cygnus.com>
+
+ * obstack.h (obstack_specify_allocation_with_arg, obstack_chunkfun,
+ obstack_freefun): Eliminate compile warnings in gdb.
+
+Tue May 13 10:21:14 1997 Nick Clifton <nickc@cygnus.com>
+
+ * coff/arm.h (constants): Added new flag bits F_APCS_26 and
+ F_APCS_SET for the f_flags field of the filehdr structure. Added new
+ flags: F_APCS26, F_ARM_2, F_ARM_3, F_ARM_7, F_ARM_7T to store
+ information in the flags field of the internal_f structure used by BFD
+ routines.
+
+Tue Apr 22 10:24:34 1997 Fred Fish <fnf@cygnus.com>
+
+ * floatformat.h (floatformat_byteorders): Add comments for previous
+ formats and add floatformat_littlebyte_bigword, primarily for ARM.
+ Add declaration for floatformat_ieee_double_littlebyte_bigword.
+
+Fri Apr 18 13:04:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * remote-sim.h (sim_stop): New interface - asynchronous
+ notification of a request to stop / suspend the running
+ simulation.
+
+ * remote-sim.h (enum sim_stop): Add sim_running and sim_polling as
+ states for use internal to simulators.
+
+ * callback.h (struct host_callback_strut): Put a magic number at
+ the end of the struct to allow basic checking.
+ (struct host_callback_struct ): Add poll_quit - so
+ that the console etc can be polled at regular intervals.
+
+Thu Apr 17 02:17:12 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.h (struct _bfd): Declare.
+ (sim_load): Return SIM_RC. New arg `abfd'.
+ (sim_create_inferior): Return SIM_RC. Delete arg `start_address'.
+
+Wed Apr 2 17:09:12 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * remote-sim.h (sim_trace, sim_size): Make these global. They
+ will go away shortly.
+
+Wed Apr 2 15:23:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * remote-sim.h (SIM_OPEN_KIND, SIM_RC): New enums.
+ (sim_open): New argument `kind'.
+
+Wed Apr 2 14:45:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * COPYING: Update FSF address.
+
+Fri Mar 28 15:29:54 1997 Mike Meissner <meissner@cygnus.com>
+
+ * callback.h (top level): Include stdarg.h or varargs.h if
+ va_start is not defined.
+ (host_callback_struct): Make {,e}vprintf_filtered take a va_list
+ instead of void *, since va_list might be an array or structure
+ type.
+
+Fri Mar 28 15:44:41 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * libiberty.h (basename): Add prototype for glibc and linux.
+
+Mon Mar 17 19:22:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objalloc.h: New file.
+
+Mon Mar 17 14:57:55 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * remote-sim.h: New file, copied in from gdb/remote-sim.h. One
+ day this will be placed in a directory of its own.
+
+Sat Mar 15 19:00:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * obstack.h: Update to current FSF version.
+
+Thu Mar 6 15:46:59 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * callback.h (struct host_callback_struct): Add callbacks -
+ flush_stdout, write_stderr, flush_stderr, vprintf_filtered,
+ evprintf_filtered. Delete redundant callbacks - printf_filtered.
+
+Thu Feb 27 23:18:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Remove lprefix and lprefix_len
+ fields.
+
+Tue Feb 25 00:10:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * dis-asm.h (INIT_DISASSEMBLE_INFO_NO_ARCH): Initialize
+ bytes_per_chunk and display_endian.
+
+Mon Feb 24 17:47:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * bfdlink.h (struct bfd_elf_version_expr): Define.
+ (struct bfd_elf_version_deps): Define.
+ (struct bfd_elf_version_tree): Define.
+
+Thu Feb 6 14:20:01 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * dis-asm.h: (disassemble_info): Add new fields
+ bytes_per_chunk and display_endian to control the
+ display of raw instructions.
+
+Fri Dec 27 22:17:37 1996 Fred Fish <fnf@cygnus.com>
+
+ * dis-asm.h (print_insn_tic80): Declare.
+
+Sun Dec 8 17:11:12 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * callback.h (host_callback): New member `error'.
+
+Wed Nov 20 00:40:23 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * callback.h: New file, moved here from gdb.
+
+Mon Nov 18 16:34:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * libiberty.h: Checkin again; last checkin failed due to sticky tag.
+
+Wed Nov 13 08:22:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * libiberty.h: Revert last commit due to conflicts with hpux
+ system headers.
+
+Tue Nov 12 16:31:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * libiberty.h: Move prototypes from argv.c here.
+
+Thu Oct 31 14:56:18 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * ansidecl.h (VPARAMS,VA_START): Define.
+
+Fri Oct 25 12:08:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dis-asm.h (disassemble_info): Add bytes_per_line field.
+ (INIT_DISASSEMBLE_INFO_NO_ARCH): Initialize bytes_per_line field.
+
+Thu Oct 24 17:10:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dis-asm.h (disassemble_info): Add symbol field.
+ (INIT_DISASSEMBLE_INFO_NO_ARCH): Initialize symbol field.
+
+Thu Oct 17 11:17:40 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * dis-asm.h (print_insn_m32r): Declare.
+
+Mon Oct 14 23:56:52 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * libiberty.h: Declare parameter types for xmalloc and xrealloc.
+
+Thu Oct 3 13:45:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * fnmatch.h: New file.
+
+Thu Oct 3 10:33:14 1996 Jeffrey A Law (law@cygnus.com)
+
+ * dis-asm.h (print_insn_mn10x00): Delete declaration.
+ (print_insn_mn10200, print_insn_mn10300): Declare.
+
+Wed Oct 2 21:24:43 1996 Jeffrey A Law (law@cygnus.com)
+
+ * dis-asm.h (print_insn_mn10x00): Declare.
+
+Mon Sep 30 13:56:11 1996 Fred Fish <fnf@cygnus.com>
+
+ * libiberty.h: Remove #ifndef PRIVATE_XMALLOC.
+
+Sat Aug 31 13:27:06 1996 Jeffrey A Law (law@cygnus.com)
+
+ * dis-asm.h (print_insn_v850): Declare.
+
+Tue Aug 13 16:10:30 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * obstack.h: Change bcopy to memcpy. Works better on Posix
+ systems, which generally lack bcopy.
+
+Mon Aug 12 17:03:18 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * ansidecl.h: Change WIN32 to _WIN32.
+
+Fri Jul 26 13:58:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dis-asm.h: Add flavour field.
+ (print_insn_alpha): Declare.
+ (print_insn_alpha_osf, print_insn_alpha_vms): Don't declare.
+ (INIT_DISASSEMBLE_INFO): Initialize flavour field.
+
+Tue Jul 23 17:37:58 1996 Fred Fish <fnf@cygnus.com>
+
+ * libiberty.h (PRIVATE_XMALLOC): Enclose xmalloc/xrealloc
+ definitions inside #ifndef so that programs that want to
+ can define PRIVATE_XMALLOC and then define xmalloc and
+ xrealloc anyway they want.
+ (basename): Document in source that we can't declare the
+ parameter type because it is declared inconsistently across
+ different systems.
+
+Mon Jul 22 13:16:13 1996 Richard Henderson <rth@tamu.edu>
+
+ * dis-asm.h (print_insn_alpha): Don't declare.
+ (print_insn_alpha_osf, print_insn_alpha_vms): Declare.
+
+Wed Jul 17 14:45:12 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * dis-asm.h: (print_insn_d10v): Declare.
+
+Mon Jul 15 16:55:38 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dis-asm.h: Get rid of decls for print_insn_i8086,
+ print_insn_sparc64 and print_insn_sparclite.
+ * (INIT_DISASSEMBLE_INFO): Split into two pieces. One,
+ INIT_DISASSEMBLE_INFO_NO_ARCH inits everything except for endian,
+ mach, and arch.
+
+Fri Jul 12 10:19:27 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dis-asm.h (print_insn_i8086): Declare.
+
+Wed Jul 3 16:02:39 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * dis-asm.h (print_insn_sparclite): Declare.
+
+Tue Jun 18 16:02:46 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * dis-asm.h (print_insn_h8300s): Declare.
+
+Tue Jun 18 15:11:33 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * fopen-vms.h: New file.
+
+Tue Jun 4 18:58:16 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Add notice_all field.
+
+Fri Apr 26 10:33:12 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * demangle.h (#ifdef IN_GCC): #include "gansidecl.h".
+ (PROTO,PTR,const): Delete.
+
+Mon Apr 22 17:27:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Add traditional_format field.
+
+Mon Apr 15 15:16:56 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * libiberty.h (choose_temp_base): Add prototype.
+
+Tue Mar 12 17:29:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (bfd_wrapped_link_hash_lookup): Declare.
+ (struct bfd_link_info): Add wrap_hash field.
+
+Wed Feb 14 16:49:17 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de>
+
+ * ieee.h (ieee_record_enum_type): Define
+ ieee_external_reference_info_enum.
+
+Fri Feb 2 17:09:25 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * dis-asm.h (DISASM_RAW_INSN): Delete.
+
+Tue Jan 23 09:21:47 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * dis-asm.h (INIT_DISASSEMBLE_INFO): Set endian to BFD_ENDIAN_UNKNOWN.
+ New argument FPRINTF_FUNC.
+
+Mon Jan 22 16:37:59 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * dis-asm.h (disassemble_info): New members arch, mach, endian.
+ (INIT_DISASSEMBLE_INFO): Initialize them.
+ (DISASM_RAW_INSN{,FLAG}): Define.
+
+Thu Jan 18 11:32:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * demangle.h (cplus_demangle_opname): Change opname parameter to
+ const char *.
+ (cplus_mangle_opname): Change return type and opname parameter to
+ const char *.
+
+Fri Jan 5 00:01:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ieee.h (enum ieee_record): Add ieee_asn_record_enum,
+ ieee_at_record_enum, ieee_ty_record_enum, ieee_atn_record_enum,
+ ieee_bb_record_enum, and ieee_be_record_enum.
+
+Wed Jan 3 13:12:09 1996 Fred Fish <fnf@cygnus.com>
+
+ * obstack.h: Update copyright to 1996.
+ (_obstack_memory_used): Declare.
+ (obstack_memory_used): Define macro.
+
+Thu Dec 28 11:42:12 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libiberty.h (xstrdup): Declare.
+
+Thu Dec 21 14:47:17 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * wait.h: Protect all macros with #ifndef.
+
+Tue Oct 24 21:45:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Add static_link field.
+
+Tue Sep 12 16:28:04 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_callbacks): Add symbol parameter to
+ warning callback.
+
+Fri Sep 1 13:11:51 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_callbacks): Change warning callback
+ to take BFD, section, and address arguments.
+
+Thu Aug 31 16:45:12 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Remove PE stuff.
+
+Tue Aug 22 03:18:23 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * libiberty.h: Declare xstrerror. From Pat Rankin.
+
+Mon Aug 21 18:11:36 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Remove PE stuff.
+
+Wed Aug 2 08:14:12 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * dis-asm.h (print_insn_sparc64): Declare.
+
+Mon Jul 10 13:26:49 1995 Eric Youngdale <eric@aib.com>
+
+ * bfdlink.h (struct bfd_link_info): Add new field symbolic.
+
+Sun Jul 2 17:48:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Change type of base_file to
+ PTR.
+
+Thu Jun 29 00:02:45 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * bfdlink.h (struct bfd_link_info): Added base_file member.
+
+Tue Jun 20 16:40:04 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * ansidecl.h: win32s is ANSI enough.
+
+Thu May 18 04:25:50 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * dis-asm.h (print_insn_arm): Delete declaration.
+ (print_insn_{little,big}_arm): New declarations.
+
+ * floatformat.h (floatformat_arm_ext): Declare.
+
+Sat May 13 10:14:08 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * coff/pe.h: New file.
+ * bfdlink.h (subsytem, stack_heap_parameters): New.
+ * coff/i386.h (NT_SECTION_ALIGNMENT, NT_FILE_ALIGNMENT,
+ NT_DEF_RESERVE, NT_DEF_COMMIT): New.
+ * coff/internal.h (internal_filehdr): New fields for PE.
+ (IMAGE_DATA_DIRECTORY): New.
+ (internal_aouthdr): New fields for PE.
+
+Thu May 4 14:36:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * demangle.h: Don't include ansidecl.h if IN_GCC.
+
+Tue Feb 21 00:37:28 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hp-symtab.h: Don't use bitfield enumerations, the HP C compiler
+ does not handle them correctly.
+
+Thu Feb 9 14:20:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * libiberty.h (basename): Don't declare parameter type; some
+ systems have this in their header files.
+
+Wed Feb 8 17:35:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (struct bfd_link_hash_entry): Change format of common
+ symbol information, to remove restrictions on maximum size and
+ alignment power, by using a pointer to a structure instead.
+
+Mon Feb 6 14:55:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdlink.h (enum bfd_link_hash_type): Rename bfd_link_hash_weak
+ to bfd_link_hash_undefweak. Add bfd_link_hash_defweak.
+
+Mon Jan 16 21:00:23 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dis-asm.h (GDB_INIT_DISASSEMBLE_INFO, etc): Remove all
+ GDB-specific definitions.
+
+Sun Jan 15 18:39:35 1995 Steve Chamberlain <sac@splat>
+
+ * dis-asm.h (print_insn_w65): Declare.
+
+Thu Jan 12 17:51:17 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * libiberty.h (hex_p): Fix sense of test.
+
+Wed Jan 11 22:36:40 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * libiberty.h (_hex_array_size, _hex_bad, _hex_value, hex_init,
+ hex_p, hex_value): New macros and declarations, for hex.c.
+
+Fri Jan 6 17:44:14 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * dis-asm.h: Make idempotent.
+
+Wed Dec 14 13:08:43 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * progress.h: New file, empty definitions for progress macros.
+
+Fri Nov 25 00:14:05 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hp-symtab.h: New file describing the debug symbols emitted
+ by the HP C compilers.
+
+Fri Nov 11 15:48:37 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * bfdlink.h (struct bfd_link_hash_entry): Change u.c.size from 24
+ to 26 bits, and change u.c.alignment_power from 8 to 6 bits. 6
+ bit in the alignment power is enough for a 64 bit address space.
+
+Mon Oct 31 13:02:51 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * demangle.h (cplus_mangle_opname): Declare.
+
+Tue Oct 25 11:38:02 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * bfdlink.h (struct bfd_link_callbacks): Fix comments for
+ multiple_common field.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * aout/aout64.h: Only define QMAGIC if it isn't already defined.
+
+ * dis-asm.h: Add support for the ARM.
+
+Wed Aug 10 12:51:41 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * libiberty.h (strsignal): Document its existence even if we
+ can't declare it.
+
+Tue Aug 2 14:40:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * os9k.h: Remove u_int16, u_int32, and owner_id typedefs and
+ expand their uses. Those names conflict with Mach headers.
+
+Fri Jul 22 14:17:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * bfdlink.h (struct bfd_link_hash_entry): Change u.c.size into a
+ bitfield. Add field u.c.alignment_power.
+
+Sun Jul 10 00:26:39 1994 Ian Dall (dall@hfrd.dsto.gov.au)
+
+ * dis-asm.h: Add print_insn_ns32k declaration.
+
+Mon Jun 20 17:13:29 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * bfdlink.h (bfd_link_hash_table): Make creator a const pointer.
+
+Sat Jun 18 16:09:32 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * demangle.h (cplus_demangle_opname): Declare.
+
+Thu Jun 16 15:19:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfdlink.h (struct bfd_link_info): Add new field shared.
+
+Mon Jun 6 14:39:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfdlink.h (struct bfd_link_hash_entry): Remove written field:
+ not needed for all backends.
+
+Thu Apr 28 19:06:50 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * dis-asm.h (disassembler): Declare.
+
+Fri Apr 1 00:38:17 1994 Jim Wilson (wilson@mole.gnu.ai.mit.edu)
+
+ * obstack.h: Delete use of IN_GCC to control whether
+ stddef.h or gstddef.h is included.
+
+Tue Mar 22 13:06:02 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfdlink.h (enum bfd_link_order_type): Add bfd_data_link_order.
+ (struct bfd_link_order): Add data field to union.
+
+Mon Mar 21 18:45:26 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfdlink.h (struct bfd_link_callbacks): Change bitsize argument
+ to add_to_set to reloc. Remove bitsize argument from constructor.
+ Comment that reloc_overflow, reloc_dangerous and unattached_reloc
+ must handle NULL pointers for reloc location.
+ (enum bfd_link_order_type): Add bfd_section_reloc_link_order and
+ bfd_symbol_reloc_link_order.
+ (struct bfd_link_order): Add reloc field to union.
+ (struct bfd_link_order_reloc): Define.
+
+Mon Mar 14 12:27:50 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ieee-float.h: Removed; no longer used.
+
+Tue Mar 1 18:10:49 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * os9k.h: os9000 target specific header file, the header of the
+ object file is used now.
+
+Sun Feb 27 21:52:26 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * floatformat.h: New file, intended to replace ieee-float.h.
+
+Sun Feb 20 17:15:42 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * ansidecl.h (ANSI_PROTOTYPES): Define if using ANSI prototypes.
+
+Wed Feb 16 01:07:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * libiberty.h: Don't declare strsignal, to avoid conflicts with
+ Solaris system header files.
+
+Sat Feb 12 22:11:32 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * libiberty.h (xexit): Use __volatile__ to avoid losing if
+ compiling with gcc -traditional.
+
+Thu Feb 10 14:05:41 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * libiberty.h: New file. Declares functions provided by
+ libiberty.
+
+Tue Feb 8 05:19:52 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ Handle obstack_chunk_alloc returning NULL. This allows
+ obstacks to be used by libraries, without forcing them
+ to call exit or longjmp.
+ * obstack.h (struct obstack): Add alloc_failed flag.
+ _obstack_begin, _obstack_begin_1): Declare to return int, not void.
+ (obstack_finish): If alloc_failed, return NULL.
+ (obstack_base, obstack_next_free, objstack_object_size):
+ If alloc_failed, return 0.
+ (obstack_grow, obstack_grow0, obstack_1grow, obstack_ptr_grow,
+ obstack_int_grow, obstack_blank): If alloc_failed, do nothing that
+ could corrupt the obstack.
+
+Mon Jan 24 15:06:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfdlink.h (struct bfd_link_callbacks): Add name, reloc_name and
+ addend argments to reloc_overflow callback.
+
+Fri Jan 21 19:13:12 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * dis-asm.h (print_insn_big_powerpc, print_insn_little_powerpc,
+ print_insn_rs6000): Declare.
+
+Thu Jan 6 14:15:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfdlink.h (struct bfd_link_callbacks): Add bitsize argument to
+ add_to_set field. Add new callback named constructor.
+
+Thu Dec 30 10:44:06 1993 Ian Lance Taylor (ian@rtl.cygnus.com)
+
+ * bfdlink.h: New file for new BFD linker backend routines.
+
+Mon Nov 29 10:43:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * dis-asm.h (enum dis_insn_tyupe): Remove non-ANSI trailing comma.
+
+Sat Oct 2 20:42:26 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dis-asm.h: Move comment to right place.
+
+Mon Aug 9 19:03:35 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * obstack.h (obstack_chunkfun, obstack_freefun): Add defns from
+ previous version. Are these Cygnus local changes?
+
+Fri Aug 6 17:05:47 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * getopt.h, obstack.h: Update to latest FSF version.
+
+Mon Aug 2 16:37:14 1993 Stu Grossman (grossman at cygnus.com)
+
+ * coff/i386.h: Add Lynx magic number.
+
+Mon Aug 2 14:45:29 1993 John Gilmore (gnu@cygnus.com)
+
+ * dis-asm.h: Move enum outside of struct defn to avoid warnings.
+
+Mon Aug 2 08:49:30 1993 Stu Grossman (grossman at cygnus.com)
+
+ * wait.h (WEXITSTATUS, WSTOPSIG): Mask down to 8 bits. This is
+ for systems that store stuff into the high 16 bits of a wait
+ status.
+
+Fri Jul 30 18:38:02 1993 John Gilmore (gnu@cygnus.com)
+
+ * dis-asm.h: Add new fields insn_info_valid, branch_delay_insns,
+ data_size, insn_type, target, target2. These are used to return
+ information from the instruction decoders back to the calling
+ program. Add comments, make more readable.
+
+Mon Jul 19 22:14:14 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * nlm: New directory containing NLM/NetWare includes.
+
+Thu Jul 15 12:10:04 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * dis-asm.h (struct disassemble_info): New field application_data.
+
+Thu Jul 15 12:41:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * dis-asm.h: Added declaration of print_insn_m88k.
+
+Thu Jul 8 09:05:26 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * opcode/h8300.h: Lots of little fixes for the h8/300h.
+
+Fri Jul 2 10:31:59 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ansidecl.h: Use ANSI macros if __mips and _SYSTYPE_SVR4 are
+ defined, since RISC/OS cc handles ANSI declarations in SVR4 mode
+ but does not define __STDC__.
+
+Sun Jun 20 18:27:52 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * dis-asm.h: Don't need to include ansidecl.h any more.
+
+Fri Jun 18 03:22:10 1993 John Gilmore (gnu@cygnus.com)
+
+ * oasys.h: Eliminate "int8_type", "int16_type", "int32_type", and
+ their variants. These changes are coordinated with corresponding
+ changes in ../bfd/oasys.c.
+
+Wed Jun 16 10:43:08 1993 Fred Fish (fnf@cygnus.com)
+
+ * bfd.h: Note that it has been removed.
+
+Tue Jun 8 12:16:03 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ Support for H8/300-H
+ * dis-asm.h (print_insn_h8300, print_insn_h8300h): Declare it.
+ * coff/h8300.h: New magic number.
+ * coff/internal.h: New relocations.
+ * opcode/h8300.h: Lots of new opcodes.
+
+Tue Jun 1 07:35:03 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * ansidecl.h (const): Don't define it if it's already defined.
+
+Thu May 27 18:19:51 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * dis-asm.h (print_insn_hppa): Declare it.
+
+ * bfd.h: Moved to bfd directory. Small stub here includes it
+ without requiring "-I../bfd".
+
+Thu Apr 29 12:06:13 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * bfd.h: Updated with BSF_FUNCTION.
+
+Mon Apr 26 18:15:50 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.h, dis-asm.h: Updated with Hitachi SH.
+
+Fri Apr 23 18:41:38 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.h: Updated with alpha changes.
+ * dis-asm.h: Added alpha.
+
+Fri Apr 16 17:35:30 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * bfd.h: Update for signed bfd_*get_*.
+
+Thu Apr 15 09:24:21 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * bfd.h: Updated for file_truncated error.
+
+Thu Apr 8 10:53:47 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ansidecl.h: If no ANSI, define const to be empty.
+
+Thu Apr 1 09:00:10 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * dis-asm.h: Declare a29k and i960 print_insn_*.
+
+ * dis-asm.h: Add print_address_func and related stuff.
+
+ * dis-asm.h (dis_asm_read_memory): Fix prototype.
+
+Wed Mar 31 17:40:16 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dis-asm.h: Add print_insn_sparc.
+
+Wed Mar 31 17:51:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd.h: Updated for BFD_RELOC_MIPS_GPREL and bfd_[gs]et_gp_size
+ prototypes.
+
+Wed Mar 31 16:35:12 1993 Stu Grossman (grossman@cygnus.com)
+
+ * dis-asm.h: (disassemble_info): Fix typo in prototype of
+ dis_asm_memory_error().
+
+Tue Mar 30 19:09:23 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dis-asm.h (disassembler_info): Add read_memory_func,
+ memory_error_func, buffer, and length.
+ ({GDB_,}INIT_DISASSEMBLE_INFO): Set them.
+ print_insn_*: Remove second argument.
+
+Tue Mar 30 14:48:55 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.h: Update for lma field of section.
+
+Tue Mar 30 12:22:55 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * ansidecl.h: Use ANSI versions on AIX regardless of __STDC__.
+
+Fri Mar 19 14:49:49 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * dis-asm.h: Add h8500.
+
+Thu Mar 18 13:49:09 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ieee-float.h: Moved from ../gdb.
+ * dis-asm.h: New file. Interface to dis-assembler.
+
+Thu Mar 11 10:52:57 1993 Fred Fish (fnf@cygnus.com)
+
+ * demangle.h (DMGL_NO_OPTS): Add define (set to 0) to use
+ in place of bare 0, for readability reasons.
+
+Tue Mar 2 17:50:11 1993 Fred Fish (fnf@cygnus.com)
+
+ * demangle.h: Replace all references to cfront with ARM.
+
+Tue Feb 23 12:21:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd.h: Update for new elements in JUMP_TABLE.
+
+Tue Feb 16 00:51:30 1993 John Gilmore (gnu@cygnus.com)
+
+ * bfd.h: Update for BFD_VERSION 2.1.
+
+Tue Jan 26 11:49:20 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd.h: Update for SEC_IS_COMMON flag.
+
+Tue Jan 19 12:25:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.h: Update for bfd_asymbol_value bug fix.
+
+Fri Jan 8 16:37:18 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.h: Update to include ECOFF tdata and target_flavour.
+
+Sun Dec 27 17:52:30 1992 Fred Fish (fnf@cygnus.com)
+
+ * bfd.h: Add declaration for bfd_get_size().
+
+Tue Dec 22 22:42:46 1992 Fred Fish (fnf@cygnus.com)
+
+ * demangle.h: Protect file from multiple inclusions with
+ #if !defined(DEMANGLE_H)...#define DEMANGLE_H...#endif.
+
+Mon Dec 21 21:25:50 1992 Stu Grossman (grossman at cygnus.com)
+
+ * bfd.h: Update to get hppa_core_struct from bfd.c.
+
+Thu Dec 17 00:42:35 1992 John Gilmore (gnu@cygnus.com)
+
+ * bfd.h: Update to get tekhex tdata name change from bfd.
+
+Mon Nov 9 23:55:42 1992 John Gilmore (gnu@cygnus.com)
+
+ * ansidecl.h: Update comments to discourage use of EXFUN.
+
+Thu Nov 5 16:35:44 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * bfd.h: Update to bring in SEC_SHARED_LIBRARY.
+
+Thu Nov 5 03:21:32 1992 John Gilmore (gnu@cygnus.com)
+
+ * bfd.h: Update to match EXFUN, bfd_seclet_struct, and SDEF
+ cleanups in bfd.
+
+Wed Nov 4 07:28:05 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * bout.h (N_CALLNAME, N_BALNAME): Define as char-type values, so
+ widening works consistently.
+
+Fri Oct 16 03:17:08 1992 John Gilmore (gnu@cygnus.com)
+
+ * getopt.h: Update to Revised Standard FSF Version.
+
+Thu Oct 15 21:43:22 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * getopt.h (struct option): use the provided enum for has_arg.
+
+ * demangle.h (AUTO_DEMANGLING, GNU_DEMANGLING,
+ LUCID_DEMANGLING): ultrix compilers require enums to be
+ enums and ints to be ints and casts where they meet. cast some
+ enums into ints.
+
+Thu Oct 15 04:35:51 1992 John Gilmore (gnu@cygnus.com)
+
+ * bfd.h: Update after comment changes.
+
+Thu Oct 8 09:03:02 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.h (bfd_get_symbol_leading_char): new macro for getting in xvec
+
+Thu Sep 3 09:10:50 1992 Stu Grossman (grossman at cygnus.com)
+
+ * bfd.h (struct reloc_howto_struct): size needs to be signed if
+ it's going to hold negative values.
+
+Sun Aug 30 17:50:27 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * demangle.h: New file, moved from ../gdb. Made independent
+ of gdb. Allow demangling style option to be passed as a
+ parameter to cplus_demangle(), but using the
+ current_demangling_style global as the default.
+
+Sat Aug 29 10:07:55 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.h: Merge comment change from current FSF version.
+
+Thu Aug 27 12:59:29 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ * bfd.h: add we32k
+
+Tue Aug 25 15:07:47 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.h: new after Z8000 stuff
+
+Mon Aug 17 09:01:23 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * bfd.h: Regenerated after page/segment size changes.
+
+Sat Aug 1 13:46:31 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.h: Merge changes from current FSF version.
+
+Mon Jul 20 21:06:23 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.h (area_id, flags): Remove, replace with extra_arg,
+ use_extra_arg, and maybe_empty_object.
+ * obstack.h (OBSTACK_MAYBE_EMPTY_OBJECT, OBSTACK_MMALLOC_LIKE):
+ Remove, replaced by maybe_empty_object and use_extra_arg bitfields.
+ * obstack.h (obstack_full_begin, _obstack_begin): Remove area_id
+ and flags arguments.
+ * obstack.h (obstack_alloc_arg): New macro to set extra_arg.
+
+Thu Jul 16 08:12:44 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * bfd.h: new after adding BFD_IS_RELAXABLE
+
+Sat Jul 4 03:22:23 1992 John Gilmore (gnu at cygnus.com)
+
+ * bfd.h: Regen after adding BSF_FILE.
+
+Mon Jun 29 14:18:36 1992 Fred Fish (fnf at sunfish)
+
+ * obstack.h: Convert bcopy() use to memcpy(), which is more
+ portable, more standard, and can take advantage of gcc's builtin
+ functions for increased performance.
+
+Thu Jun 25 04:46:08 1992 John Gilmore (gnu at cygnus.com)
+
+ * ansidecl.h (PARAMS): Incorporate this macro from gdb's defs.h.
+ It's a cleaner way to forward-declare function prototypes.
+
+Fri Jun 19 15:46:32 1992 Stu Grossman (grossman at cygnus.com)
+
+ * bfd.h: HPPA merge.
+
+Tue Jun 16 21:30:56 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * getopt.h: gratuitous white space changes merged from other prep
+ releases.
+
+Thu Jun 11 01:10:55 1992 John Gilmore (gnu at cygnus.com)
+
+ * bfd.h: Regen'd from bfd.c after removing elf_core_tdata_struct.
+
+Mon May 18 17:29:03 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * getopt.h: merged changes from make-3.62.11.
+
+ * getopt.h: merged changes from grep-1.6 (alpha).
+
+Fri May 8 14:53:32 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * getopt.h: merged changes from bison-1.18.
+
+Sat Mar 14 17:25:20 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.h: Add "area_id" and "flags" members to obstack
+ structure. Add obstack_chunkfun() and obstack_freefun() to
+ set functions explicitly. Convert maybe_empty_object to
+ a bit in "flags".
+
+Thu Feb 27 22:01:02 1992 Per Bothner (bothner@cygnus.com)
+
+ * wait.h (WIFSTOPPED): Add IBM rs6000-specific version.
+
+Fri Feb 21 20:49:20 1992 John Gilmore (gnu at cygnus.com)
+
+ * obstack.h: Add obstack_full_begin.
+ * bfd.h, obstack.h: Protolint.
+
+Thu Jan 30 01:18:42 1992 John Gilmore (gnu at cygnus.com)
+
+ * bfd.h: Remove comma from enum declaration.
+
+Mon Jan 27 22:01:13 1992 Steve Chamberlain (sac at cygnus.com)
+
+ * bfd.h : new target entr, bfd_relax_section
+
+Wed Dec 18 17:19:44 1991 Stu Grossman (grossman at cygnus.com)
+
+ * bfd.h, ieee.h, opcode/m68k.h, opcode/sparc.h: ANSIfy enums.
+
+Thu Dec 12 20:59:56 1991 John Gilmore (gnu at cygnus.com)
+
+ * fopen-same.h, fopen-bin.h: New files for configuring
+ whether fopen distinguishes binary files or not. For use
+ by host-dependent config files.
+
+Sat Nov 30 20:46:43 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * bfd.h: change the documentation format.
+
+ * created coff, elf and opcode and aout directories. Moved:
+
+ aout64.h ==> aout/aout64.h
+ ar.h ==> aout/ar.h
+ a.out.encap.h ==> aout/encap.h
+ a.out.host.h ==> aout/host.h
+ a.out.hp.h ==> aout/hp.h
+ a.out.sun4.h ==> aout/sun4.h
+ ranlib.h ==> aout/ranlib.h
+ reloc.h ==> aout/reloc.h
+ stab.def ==> aout/stab.def
+ stab.gnu.h ==> aout/stab_gnu.h
+
+ coff-a29k.h ==> coff/a29k.h
+ coff-h8300.h ==> coff/h8300.h
+ coff-i386.h ==> coff/i386.h
+ coff-i960.h ==> coff/i960.h
+ internalcoff.h ==> coff/internal.h
+ coff-m68k.h ==> coff/m68k.h
+ coff-m88k.h ==> coff/m88k.h
+ coff-mips.h ==> coff/mips.h
+ coff-rs6000.h ==> coff/rs6000.h
+
+ elf-common.h ==> elf/common.h
+ dwarf.h ==> elf/dwarf.h
+ elf-external.h ==> elf/external.h
+ elf-internal.h ==> elf/internal.h
+
+ a29k-opcode.h ==> opcode/a29k.h
+ arm-opcode.h ==> opcode/arm.h
+ h8300-opcode.h ==> opcode/h8300.h
+ i386-opcode.h ==> opcode/i386.h
+ i860-opcode.h ==> opcode/i860.h
+ i960-opcode.h ==> opcode/i960.h
+ m68k-opcode.h ==> opcode/m68k.h
+ m88k-opcode.h ==> opcode/m88k.h
+ mips-opcode.h ==> opcode/mips.h
+ np1-opcode.h ==> opcode/np1.h
+ ns32k-opcode.h ==> opcode/ns32k.h
+ pn-opcode.h ==> opcode/pn.h
+ pyr-opcode.h ==> opcode/pyr.h
+ sparc-opcode.h ==> opcode/sparc.h
+ tahoe-opcode.h ==> opcode/tahoe.h
+ vax-opcode.h ==> opcode/vax.h
+
+
+
+Wed Nov 27 10:38:31 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * internalcoff.h: (internal_scnhdr) took out #def dependency, now
+ s_nreloc and s_nlnno are always long. (internal_reloc): allways
+ has an offset field now.
+
+Fri Nov 22 08:12:58 1991 John Gilmore (gnu at cygnus.com)
+
+ * coff-rs6000.h: Lint; use unsigned chars for external fields.
+ * internalcoff.h: Lint; cast storage classes to signed char.
+
+Thu Nov 21 21:01:05 1991 Per Bothner (bothner at cygnus.com)
+
+ * stab.def: Remove the GNU extended type codes (e.g. N_SETT).
+ * aout64.h: The heuristic for distinguishing between
+ sunos-style and bsd-style ZMAGIC files (wrt. where the
+ text segment starts) is moved into (the default definition of)
+ the macro N_HEADER_IN_TEXT. This definition is only used
+ if no other definition is used - e.g. bfd/newsos3.c defines
+ N_HEADER_IN_TEXT(x) to be always 0 (as before).
+
+Thu Nov 21 11:53:03 1991 John Gilmore (gnu at cygnus.com)
+
+ * aout64.h (N_TXTADDR, N_TXTOFF, N_TXTSIZE): New definitions
+ that should handle all uses. LOGICAL_ versions deleted.
+ Eliminate N_HEADER_IN_TEXT, using a_entry to determine which
+ kind of zmagic a.out file we are looking at.
+ * coff-rs6000.h: Typo.
+
+Tue Nov 19 18:43:37 1991 Per Bothner (bothner at cygnus.com)
+
+ (Note: This is a revised entry, as was aout64.h.)
+ * aout64.h: Some cleanups of N_TXTADDR and N_TXTOFF:
+ Will now work for both old- and new-style ZMAGIC files,
+ depending on N_HEADER_IN_TEXT macro.
+ Add LOGICAL_TXTADDR, LOICAL_TXTOFF and LOGICAL_TXTSIZE
+ that don't count the exec header as part
+ of the text segment, to be consistent with bfd.
+ * a.out.sun4.h: Simplified/fixed for previous change.
+
+Mon Nov 18 00:02:06 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarf.h: Update to DWARF draft 5 version from gcc2.
+
+Thu Nov 14 19:44:59 1991 Per Bothner (bothner at cygnus.com)
+
+ * stab.def: Added defs for extended GNU symbol types,
+ such as N_SETT. These are normally ifdef'd out (because
+ of conflicts with a.out.gnu.h), but are used by bfb_stab_name().
+
+Thu Nov 14 19:17:03 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf-common.h: Add defines to support ELF symbol table code.
+
+Mon Nov 11 19:01:06 1991 Fred Fish (fnf at cygnus.com)
+
+ * elf-internal.h, elf-external.h, elf-common.h: Add support for
+ note sections, which are used in ELF core files to hold copies
+ of various /proc structures.
+
+Thu Nov 7 08:58:26 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * internalcoff.h: took out the M88 dependency in the lineno
+ struct.
+ * coff-m88k.h: defines GET_LINENO_LNNO and PUT_LINENO_LNNO to use
+ 32bit linno entries.
+ * a29k-opcode.h: fixed encoding of mtacc
+
+Sun Nov 3 11:54:22 1991 Per Bothner (bothner at cygnus.com)
+
+ * bfd.h: Updated from ../bfd/bfd-in.h (q.v).
+
+Fri Nov 1 11:13:53 1991 John Gilmore (gnu at cygnus.com)
+
+ * internalcoff.h: Add x_csect defines.
+
+Fri Oct 25 03:18:20 1991 John Gilmore (gnu at cygnus.com)
+
+ * Rename COFF-related files in `coff-ARCH.h' form.
+ coff-a29k.h, coff-i386.h, coff-i960.h, coff-m68k.h, coff-m88k.h,
+ coff-mips.h, coff-rs6000.h to be exact.
+
+Thu Oct 24 22:11:11 1991 John Gilmore (gnu at cygnus.com)
+
+ RS/6000 support, by Metin G. Ozisik, Mimi Phûông-Thåo Võ, and
+ John Gilmore.
+
+ * a.out.gnu.h: Update slightly.
+ * bfd.h: Add new error code, fix doc, add bfd_arch_rs6000.
+ * internalcoff.h: Add more F_ codes for filehdr. Add
+ rs/6000-dependent fields to aouthdr. Add storage classes
+ to syments. Add 6000-specific auxent. Add r_size in reloc.
+ * rs6000coff.c: New file.
+
+Thu Oct 24 04:13:20 1991 Fred Fish (fnf at cygnus.com)
+
+ * dwarf.h: New file for dwarf support. Copied from gcc2
+ distribution.
+
+Wed Oct 16 13:31:45 1991 John Gilmore (gnu at cygnus.com)
+
+ * aout64.h: Remove PAGE_SIZE defines; they are target-dependent.
+ Add N_FN_SEQ for N_FN symbol type used on Sequent machines.
+ * stab.def: Include N_FN_SEQ in table.
+ * bout.h: External formats of structures use unsigned chars.
+
+Fri Oct 11 12:40:43 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * bfd.h:upgrade from bfd.c
+ * internalcoff.h: add n_name, n_zeroes and n_offset macros
+ * amdcoff.h: Define OMAGIC and AOUTHDRSZ.
+
+Fri Oct 11 10:58:06 1991 Per Bothner (bothner at cygnus.com)
+
+ * a.out.host.h: Change SEGMENT_SIZE to 0x1000 for Sony.
+ * bfd.h (align_power): Add (actually move) comment.
+
+Tue Oct 8 15:29:32 1991 Per Bothner (bothner at cygnus.com)
+
+ * sys/h-rtbsd.h: Define MISSING_VFPRINT (for binutils/bucomm.c).
+
+Sun Oct 6 19:24:39 1991 John Gilmore (gnu at cygnus.com)
+
+ * aout64.h: Move struct internal_exec to ../bfd/libaout.h so
+ it can be shared by all `a.out-family' code. Rename
+ EXTERNAL_LIST_SIZE to EXTERNAL_NLIST_SIZE. Use basic types
+ for nlist members, and make strx integral rather than pointer.
+ More commentary on n_type values.
+ * bout.h: Provide a struct external_exec rather than an
+ internal_exec.
+ * m68kcoff.h: Remove `tagentries' which snuck in from the i960
+ COFF port.
+
+Fri Oct 4 01:25:59 1991 John Gilmore (gnu at cygnus.com)
+
+ * h8300-opcode.h: Remove `_enum' from the typedef for an enum.
+ * bfd.h: Update to match bfd changes.
+
+ * sys/h-i386mach.h, sysdep.h: Add 386 Mach host support.
+
+Tue Oct 1 04:58:42 1991 John Gilmore (gnu at cygnus.com)
+
+ * bfd.h, elf-common.h, elf-external.h, elf-internal.h:
+ Add preliminary ELF support, sufficient for GDB, from Fred Fish.
+ * sysdep.h, sys/h-amix.h: Support Amiga SVR4.
+
+ * sys/h-vaxult.h: Make it work. (David Taylor <taylor@think.com>)
+ * a.out.vax.h: Remove unused and confusing file.
+
+Mon Sep 30 12:52:35 1991 Per Bothner (bothner at cygnus.com)
+
+ * sysdep.h: Define NEWSOS3_SYS, and use it.
+
+Fri Sep 20 13:38:21 1991 John Gilmore (gnu at cygnus.com)
+
+ * a.out.gnu.h (N_FN): Its value *really is* 0x1F.
+ Fix it, and add comments warning about or-ing N_EXT with it
+ and/or N_WARNING.
+ * aout64.h (N_FN): Fix value, add comments about N_EXT.
+ * stab.def (table at end): Update to show all the type
+ values <0x20, including low order bits. Move N_FN to
+ its rightful place.
+
+Tue Sep 17 17:41:37 1991 Stu Grossman (grossman at cygnus.com)
+
+ * sys/h-irix3.h: sgi/irix support.
+
+Tue Sep 17 07:52:59 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * stab.def (N_DEFD): Add GNU Modula-2 debug stab, from Andrew
+ Beers.
+
+Thu Sep 12 14:12:59 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * internalcoff.h (SYMNMLEN, FILNMLEN, DIMNUM): Define these
+ for internalcoff, separately from the various external coff's.
+ * amdcoff.h, bcs88kcoff.h, i386coff.h, intel-coff.h, m68kcoff.h,
+ m88k-bcs.h: Prefix SYMNMLEN, FILNMLEN, and DIMNUM with E_'s for
+ the external struct definitions.
+ * ecoff.h: Remove these #define's, kludge no longer needed.
+
+ * sys/h-ultra3.h: Add new Ultracomputer host.
+ * sysdep.h: Add ULTRA3_SYM1_SYS and use it.
+
+Tue Sep 10 10:11:46 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * i386coff.h (LINESZ): Always 6, not based on sizeof().
+ (Fix from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>.)
+
+Wed Sep 4 08:58:37 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * a.out.gnu.h, aout64.h: Add N_WARNING. Change N_FN to 0x0E,
+ to match SunOS and BSD. Add N_COMM as 0x12 for SunOS shared lib
+ support.
+ * stab.def: Add N_COMM to table, fix overlap comment.
+
+Tue Sep 3 06:29:20 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ Merge with latest FSF versions of these files.
+
+ * stab.gnu.h: Add LAST_UNUSED_STAB_CODE.
+ * stab.def: Update to GPL2. Move N_WARNING out, since not a
+ debug symbol. Change comments, and reorder table to numeric
+ order. Update final table comment.
+ (N_DSLINE, N_BSLINE): Renumber from 0x66 and 0x68, to 0x46 and 0x48.
+
+ * obstack.h: GPL2. Merge.
+
+Fri Aug 23 01:54:23 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * a.out.gnu.h, a.out.sun4.h: Make SEGMENT_SIZE able to depend
+ on the particular a.out being examined.
+ * a.out.sun4.h: Define segment sizes for Sun-3's and Sun-4's.
+ * FIXME: a.out.gnu.h is almost obsolete.
+ * FIXME: a.out.sun4.h should be renamed a.out.sun.h now.
+
+Wed Aug 21 20:32:13 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * Start a ChangeLog for the includes directory.
+
+ * a.out.gnu.h (N_FN): Fix value -- was 15, should be 0x1E.
+ * stab.def: Update allocation table in comments at end,
+ to reflect reality as I know it.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/include/ansidecl.h b/include/ansidecl.h
new file mode 100644
index 00000000000..cdb9fb71961
--- /dev/null
+++ b/include/ansidecl.h
@@ -0,0 +1,163 @@
+/* ANSI and traditional C compatability macros
+ Copyright 1991, 1992, 1996 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ANSI and traditional C compatibility macros
+
+ ANSI C is assumed if __STDC__ is #defined.
+
+ Macro ANSI C definition Traditional C definition
+ ----- ---- - ---------- ----------- - ----------
+ PTR `void *' `char *'
+ LONG_DOUBLE `long double' `double'
+ VOLATILE `volatile' `'
+ SIGNED `signed' `'
+ PTRCONST `void *const' `char *'
+ ANSI_PROTOTYPES 1 not defined
+
+ CONST is also defined, but is obsolete. Just use const.
+
+ obsolete -- DEFUN (name, arglist, args)
+
+ Defines function NAME.
+
+ ARGLIST lists the arguments, separated by commas and enclosed in
+ parentheses. ARGLIST becomes the argument list in traditional C.
+
+ ARGS list the arguments with their types. It becomes a prototype in
+ ANSI C, and the type declarations in traditional C. Arguments should
+ be separated with `AND'. For functions with a variable number of
+ arguments, the last thing listed should be `DOTS'.
+
+ obsolete -- DEFUN_VOID (name)
+
+ Defines a function NAME, which takes no arguments.
+
+ obsolete -- EXFUN (name, (prototype)) -- obsolete.
+
+ Replaced by PARAMS. Do not use; will disappear someday soon.
+ Was used in external function declarations.
+ In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
+ parentheses). In traditional C it is `NAME()'.
+ For a function that takes no arguments, PROTOTYPE should be `(void)'.
+
+ obsolete -- PROTO (type, name, (prototype) -- obsolete.
+
+ This one has also been replaced by PARAMS. Do not use.
+
+ PARAMS ((args))
+
+ We could use the EXFUN macro to handle prototype declarations, but
+ the name is misleading and the result is ugly. So we just define a
+ simple macro to handle the parameter lists, as in:
+
+ static int foo PARAMS ((int, char));
+
+ This produces: `static int foo();' or `static int foo (int, char);'
+
+ EXFUN would have done it like this:
+
+ static int EXFUN (foo, (int, char));
+
+ but the function is not external...and it's hard to visually parse
+ the function name out of the mess. EXFUN should be considered
+ obsolete; new code should be written to use PARAMS.
+
+ DOTS is also obsolete.
+
+ Examples:
+
+ extern int printf PARAMS ((const char *format, ...));
+*/
+
+#ifndef _ANSIDECL_H
+
+#define _ANSIDECL_H 1
+
+
+/* Every source file includes this file,
+ so they will all get the switch for lint. */
+/* LINTLIBRARY */
+
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
+/* All known AIX compilers implement these things (but don't always
+ define __STDC__). The RISC/OS MIPS compiler defines these things
+ in SVR4 mode, but does not define __STDC__. */
+
+#define PTR void *
+#define PTRCONST void *CONST
+#define LONG_DOUBLE long double
+
+#ifndef IN_GCC
+#define AND ,
+#define NOARGS void
+#define VOLATILE volatile
+#define SIGNED signed
+#endif /* ! IN_GCC */
+
+#define PARAMS(paramlist) paramlist
+#define ANSI_PROTOTYPES 1
+
+#define VPARAMS(ARGS) ARGS
+#define VA_START(va_list,var) va_start(va_list,var)
+
+/* These are obsolete. Do not use. */
+#ifndef IN_GCC
+#define CONST const
+#define DOTS , ...
+#define PROTO(type, name, arglist) type name arglist
+#define EXFUN(name, proto) name proto
+#define DEFUN(name, arglist, args) name(args)
+#define DEFUN_VOID(name) name(void)
+#endif /* ! IN_GCC */
+
+#else /* Not ANSI C. */
+
+#define PTR char *
+#define PTRCONST PTR
+#define LONG_DOUBLE double
+
+#ifndef IN_GCC
+#define AND ;
+#define NOARGS
+#define VOLATILE
+#define SIGNED
+#endif /* !IN_GCC */
+
+#ifndef const /* some systems define it in header files for non-ansi mode */
+#define const
+#endif
+
+#define PARAMS(paramlist) ()
+
+#define VPARAMS(ARGS) (va_alist) va_dcl
+#define VA_START(va_list,var) va_start(va_list)
+
+/* These are obsolete. Do not use. */
+#ifndef IN_GCC
+#define CONST
+#define DOTS
+#define PROTO(type, name, arglist) type name ()
+#define EXFUN(name, proto) name()
+#define DEFUN(name, arglist, args) name arglist args;
+#define DEFUN_VOID(name) name()
+#endif /* ! IN_GCC */
+
+#endif /* ANSI C. */
+
+#endif /* ansidecl.h */
diff --git a/include/aout/ChangeLog b/include/aout/ChangeLog
new file mode 100644
index 00000000000..854cfd5b5cb
--- /dev/null
+++ b/include/aout/ChangeLog
@@ -0,0 +1,178 @@
+Sun Jun 28 11:33:48 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * stab.def: Add N_ALIAS from SunPro F77.
+
+Mon Mar 11 12:15:52 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * stab.def: Use __define_stab_duplicate rather than __define_stab
+ for duplicate entries N_BROWS and N_MOD2.
+ * stab_gnu.h (__define_stab_duplicate): Define before including
+ stab.def.
+
+Fri Oct 27 17:47:16 1995 Niklas Hallqvist <niklas@appli.se>
+
+ * aout64.h, host.h, hp300hpux.h, sun4.h: Changed PAGE_SIZE to
+ TARGET_PAGE_SIZE.
+
+Tue Sep 12 12:07:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sun4.h (struct internal_sun4_dynamic_link): Change all fields
+ from long to unsigned long.
+
+Wed Jul 12 00:15:13 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * sun4.h (PAGE_SIZE): Undefine before defining.
+
+Thu Jun 16 14:22:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * aout64.h (BMAGIC): Define.
+
+Sat Jun 11 16:16:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add weak symbols as an extension to a.out.
+ * aout64.h (N_WEAKU, N_WEAKA, N_WEAKT, N_WEAKD, N_WEAKB): Define.
+ * stab.def: Update symbol value table.
+
+Thu Jun 2 17:13:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * sun4.h (EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE): Correct from 28 to
+ 24. Fix up ld_got comment.
+
+Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dynix3.h: Cleanup, adapt to current bfd version.
+
+Sat Feb 26 10:25:53 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * aout64.h: Add casts to avoid warnings from SVR4 cc.
+
+Fri Feb 11 12:56:04 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * ar.h (ARMAG, ARMAGB, ARFMAG): Change '\n' to '\012', for greater
+ portability.
+
+Fri Jan 21 00:59:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * sun4.h: Added information about SunOS shared libraries.
+
+Fri Jan 7 08:20:13 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * aout64.h (N_TXTADDR): Add comment regarding OMAGIC and NMAGIC.
+
+Sat Dec 25 14:55:41 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aout64.h (N_DATOFF): Don't pad (revert change of 8 Jul 1993).
+
+Tue Nov 16 15:43:46 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aout64.h: New macros ZMAGIC_DISK_BLOCK_SIZE and N_DISK_BLOCK_SIZE
+ for Linux ZMAGIC.
+ (N_TXTOFF, N_DATOFF): Use them.
+
+Thu Nov 4 00:33:48 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * aout64.h (RELOC_STD_BITS_RELATIVE_LITTLE): Fixed value to match
+ sun3 system; used to overlap other fields.
+ (RELOC_STD_BITS_JMPTABLE_LITTLE): Likewise.
+
+Wed Nov 3 13:48:27 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * aout64.h (RELOC_STD_BITS_BASEREL_LITTLE): Make it 0x10 (Ken's
+ suggestion) to avoid conflict with RELOC_STD_BITS_EXTERN_LITTLE.
+
+Fri Oct 29 15:09:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * hp300hpux.h (N_SHARED_LIB): Define to be 0.
+
+Mon Sep 13 21:00:56 1993 John Gilmore (gnu@cygnus.com)
+
+ * ar.h (ARMAP_TIME_OFFSET): Add and describe.
+
+Mon Aug 23 Sean Fagan (sef@cygnus.com)
+
+ * aout64.h [ARCH_SIZE != 64]: Allow N_BADMAG to be overridden.
+
+Mon Aug 16 14:30:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stab_gnu.h: Include aout/stab.def not just stab.def.
+
+Sun Jul 18 21:41:47 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * dynix3.h: New, for symmetry running dynix.
+
+Thu Jul 8 12:52:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * aout64.h (N_BADMAG): Recognize QMAGIC.
+ N_TXTOFF, N_TXTADDR, N_TXTSIZE: Special code for QMAGIC.
+ N_DATOFF: Pad text size if we need to.
+
+Fri Jun 18 19:19:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * stab.def (N_ECOML): Fix comment.
+
+Mon May 31 09:21:30 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * stab.def: Remove Solaris information on N_FUN stabstring grammar;
+ I've transferred it to gdb/doc/stabs.texinfo, where it belongs.
+
+Mon May 10 05:48:43 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * hp300hpux.h: Patch from Glenn Engel for linker problem and
+ compatibility fix:
+ (OMAGIC, NMAGIC): New definitions.
+ (SHAREMAGIC): Deleted.
+ (HPUX_DOT_O_MAGIC): New macro.
+ (_N_BADMAG): Adjusted.
+ (N_HEADER_IN_TEXT, N_DATADDR): New macros.
+
+Thu Apr 29 12:07:37 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * hp300hpux.h: New file from Glenn Engel, glenne@lsid.hp.com.
+
+Tue Apr 27 05:51:04 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * aout64.h (struct external_exec, *MAGIC, N_BADMAG): Don't define
+ if `external_exec' is already defined as a macro.
+ (N_DATOFF, N_TRELOFF, N_DRELOFF, N_SYMOFF, N_STROFF): Don't define
+ if already defined.
+ (struct external_nlist, EXTERNAL_NLIST_SIZE): Don't define if
+ `external_nlist' is already defined as a macro.
+
+Sat Aug 15 04:23:02 1992 John Gilmore (gnu@cygnus.com)
+
+ * adobe.h: Add description of a.out.adobe format.
+
+Fri Jul 3 00:36:52 1992 John Gilmore (gnu at cygnus.com)
+
+ * stab.def: Update more Solaris definitions.
+ * stab_gnu.h: Add N_SO language types, and Solaris basic float types.
+
+Sun Jun 14 10:53:53 1992 John Gilmore (gnu at cygnus.com)
+
+ * stab.def: Update descriptions of Solaris-2 stabs; add N_UNDF.
+
+Thu Jun 11 01:12:07 1992 John Gilmore (gnu at cygnus.com)
+
+ * stab.def: Add N_OBJ and N_OPT from Solaris-2.
+
+Thu Jan 30 18:12:44 1992 John Gilmore (gnu at cygnus.com)
+
+ * aout/aout64.h: N_TXTSIZE needs some more parentheses.
+ I don't trust C precedence.
+
+Wed Dec 18 14:32:01 1991 Per Bothner (bothner at cygnus.com)
+
+ * aout/aout64.h: Move common sunos-specific test
+ to recognize shared libraries into new macro N_SHARED_LIB.
+ Use it to simplify&reformat N_TXTADDR, N_TXTOFF, N_TXTSIZE.
+
+Sat Nov 30 20:34:52 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * ChangeLog, aout64.h, ar.h, encap.h, host.h, hp.h, ranlib.h,
+ reloc.h, stab.def, stab_gnu.h, sun4.h: All moved from the
+ devo/include directory
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/include/aout/adobe.h b/include/aout/adobe.h
new file mode 100644
index 00000000000..3d2f15c6cb7
--- /dev/null
+++ b/include/aout/adobe.h
@@ -0,0 +1,297 @@
+/* `a.out.adobe' differences from standard a.out files */
+
+#ifndef __A_OUT_ADOBE_H__
+#define __A_OUT_ADOBE_H__
+
+#define BYTES_IN_WORD 4
+
+/* Struct external_exec is the same. */
+
+/* This is the layout on disk of the 32-bit or 64-bit exec header. */
+
+struct external_exec
+{
+ bfd_byte e_info[4]; /* magic number and stuff */
+ bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */
+ bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */
+ bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */
+ bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */
+ bfd_byte e_entry[BYTES_IN_WORD]; /* start address */
+ bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */
+ bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
+};
+
+#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
+
+/* Magic numbers for a.out files */
+
+#undef ZMAGIC
+#define ZMAGIC 0xAD0BE /* Cute, eh? */
+#undef OMAGIC
+#undef NMAGIC
+
+#define N_BADMAG(x) ((x).a_info != ZMAGIC)
+
+/* By default, segment size is constant. But some machines override this
+ to be a function of the a.out header (e.g. machine type). */
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+#undef N_SEGSIZE /* FIXMEXXXX */
+
+/* Segment information for the a.out.Adobe format is specified after the
+ file header. It contains N segment descriptors, followed by one with
+ a type of zero.
+
+ The actual text of the segments starts at N_TXTOFF in the file,
+ regardless of how many or how few segment headers there are. */
+
+struct external_segdesc {
+ unsigned char e_type[1];
+ unsigned char e_size[3];
+ unsigned char e_virtbase[4];
+ unsigned char e_filebase[4];
+};
+
+struct internal_segdesc {
+ unsigned int a_type:8; /* Segment type N_TEXT, N_DATA, 0 */
+ unsigned int a_size:24; /* Segment size */
+ bfd_vma a_virtbase; /* Virtual address */
+ unsigned int a_filebase; /* Base address in object file */
+};
+
+#define N_TXTADDR(x) \
+
+/* This is documented to be at 1024, but appears to really be at 2048.
+ FIXME?! */
+#define N_TXTOFF(x) 2048
+
+#define N_TXTSIZE(x) ((x).a_text)
+
+#define N_DATADDR(x)
+
+#define N_BSSADDR(x)
+
+/* Offsets of the various portions of the file after the text segment. */
+
+#define N_DATOFF(x) ( N_TXTOFF(x) + N_TXTSIZE(x) )
+#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+
+/* Symbols */
+struct external_nlist {
+ bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
+ bfd_byte e_type[1]; /* type of symbol */
+ bfd_byte e_other[1]; /* misc info (usually empty) */
+ bfd_byte e_desc[2]; /* description field */
+ bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
+};
+
+#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
+
+struct internal_nlist {
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+};
+
+/* The n_type field is the symbol type, containing: */
+
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
+#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
+#define N_DATA 6 /* Data sym -- defined at offset in data seg */
+#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
+#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
+#define N_FN 0x1f /* File name of .o file */
+#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
+/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
+#define N_TYPE 0x1e
+#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
+
+#define N_INDR 0x0a
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ elements value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
+
+/* Relocations
+
+ There are two types of relocation flavours for a.out systems,
+ standard and extended. The standard form is used on systems where the
+ instruction has room for all the bits of an offset to the operand, whilst
+ the extended form is used when an address operand has to be split over n
+ instructions. Eg, on the 68k, each move instruction can reference
+ the target with a displacement of 16 or 32 bits. On the sparc, move
+ instructions use an offset of 14 bits, so the offset is stored in
+ the reloc field, and the data in the section is ignored.
+*/
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct reloc_std_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+};
+
+#define RELOC_STD_BITS_PCREL_BIG 0x80
+#define RELOC_STD_BITS_PCREL_LITTLE 0x01
+
+#define RELOC_STD_BITS_LENGTH_BIG 0x60
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5 /* To shift to units place */
+#define RELOC_STD_BITS_LENGTH_LITTLE 0x06
+#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
+
+#define RELOC_STD_BITS_EXTERN_BIG 0x10
+#define RELOC_STD_BITS_EXTERN_LITTLE 0x08
+
+#define RELOC_STD_BITS_BASEREL_BIG 0x08
+#define RELOC_STD_BITS_BASEREL_LITTLE 0x08
+
+#define RELOC_STD_BITS_JMPTABLE_BIG 0x04
+#define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04
+
+#define RELOC_STD_BITS_RELATIVE_BIG 0x02
+#define RELOC_STD_BITS_RELATIVE_LITTLE 0x02
+
+#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
+
+struct reloc_std_internal
+{
+ bfd_vma r_address; /* Address (within segment) to be relocated. */
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in files the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* The next three bits are for SunOS shared libraries, and seem to
+ be undocumented. */
+ unsigned int r_baserel:1; /* Linkage table relative */
+ unsigned int r_jmptable:1; /* pc-relative to jump table */
+ unsigned int r_relative:1; /* "relative relocation" */
+ /* unused */
+ unsigned int r_pad:1; /* Padding -- set to zero */
+};
+
+
+/* EXTENDED RELOCS */
+
+struct reloc_ext_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+ bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
+};
+
+#define RELOC_EXT_BITS_EXTERN_BIG 0x80
+#define RELOC_EXT_BITS_EXTERN_LITTLE 0x01
+
+#define RELOC_EXT_BITS_TYPE_BIG 0x1F
+#define RELOC_EXT_BITS_TYPE_SH_BIG 0
+#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+
+/* Bytes per relocation entry */
+#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
+
+enum reloc_type
+{
+ /* simple relocations */
+ RELOC_8, /* data[0:7] = addend + sv */
+ RELOC_16, /* data[0:15] = addend + sv */
+ RELOC_32, /* data[0:31] = addend + sv */
+ /* pc-rel displacement */
+ RELOC_DISP8, /* data[0:7] = addend - pc + sv */
+ RELOC_DISP16, /* data[0:15] = addend - pc + sv */
+ RELOC_DISP32, /* data[0:31] = addend - pc + sv */
+ /* Special */
+ RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */
+ RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */
+ RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */
+ RELOC_22, /* data[0:21] = (addend + sv) */
+ RELOC_13, /* data[0:12] = (addend + sv) */
+ RELOC_LO10, /* data[0:9] = (addend + sv) */
+ RELOC_SFA_BASE,
+ RELOC_SFA_OFF13,
+ /* P.I.C. (base-relative) */
+ RELOC_BASE10, /* Not sure - maybe we can do this the */
+ RELOC_BASE13, /* right way now */
+ RELOC_BASE22,
+ /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_PC10,
+ RELOC_PC22,
+ /* P.I.C. jump table */
+ RELOC_JMP_TBL,
+ /* reputedly for shared libraries somehow */
+ RELOC_SEGOFF16,
+ RELOC_GLOB_DAT,
+ RELOC_JMP_SLOT,
+ RELOC_RELATIVE,
+
+ RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */
+ RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG,
+ RELOC_CONST,
+ RELOC_CONSTH,
+
+ NO_RELOC
+ };
+
+
+struct reloc_internal {
+ bfd_vma r_address; /* offset of of data to relocate */
+ long r_index; /* symbol table index of symbol */
+ enum reloc_type r_type; /* relocation type */
+ bfd_vma r_addend; /* datum addend */
+};
+
+#endif /* __A_OUT_ADOBE_H__ */
diff --git a/include/aout/aout64.h b/include/aout/aout64.h
new file mode 100644
index 00000000000..76f1140b682
--- /dev/null
+++ b/include/aout/aout64.h
@@ -0,0 +1,475 @@
+/* `a.out' object-file definitions, including extensions to 64-bit fields */
+
+#ifndef __A_OUT_64_H__
+#define __A_OUT_64_H__
+
+/* This is the layout on disk of the 32-bit or 64-bit exec header. */
+
+#ifndef external_exec
+struct external_exec
+{
+ bfd_byte e_info[4]; /* magic number and stuff */
+ bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */
+ bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */
+ bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */
+ bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */
+ bfd_byte e_entry[BYTES_IN_WORD]; /* start address */
+ bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */
+ bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */
+};
+
+#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7)
+
+/* Magic numbers for a.out files */
+
+#if ARCH_SIZE==64
+#define OMAGIC 0x1001 /* Code indicating object file */
+#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */
+#define NMAGIC 0x1003 /* Code indicating pure executable. */
+
+/* There is no 64-bit QMAGIC as far as I know. */
+
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+#else
+#define OMAGIC 0407 /* ...object file or impure executable. */
+#define NMAGIC 0410 /* Code indicating pure executable. */
+#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
+#define BMAGIC 0415 /* Used by a b.out object. */
+
+/* This indicates a demand-paged executable with the header in the text.
+ It is used by 386BSD (and variants) and Linux, at least. */
+#ifndef QMAGIC
+#define QMAGIC 0314
+#endif
+# ifndef N_BADMAG
+# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC \
+ && N_MAGIC(x) != QMAGIC)
+# endif /* N_BADMAG */
+#endif
+
+#endif
+
+#ifdef QMAGIC
+#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC)
+#else
+#define N_IS_QMAGIC(x) (0)
+#endif
+
+/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is
+ the finest granularity at which you can page something, thus it
+ controls the padding (if any) before the text segment of a ZMAGIC
+ file. N_SEGSIZE is the resolution at which things can be marked as
+ read-only versus read/write, so it controls the padding between the
+ text segment and the data segment (in memory; on disk the padding
+ between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same
+ for most machines, but different for sun3. */
+
+/* By default, segment size is constant. But some machines override this
+ to be a function of the a.out header (e.g. machine type). */
+
+#ifndef N_SEGSIZE
+#define N_SEGSIZE(x) SEGMENT_SIZE
+#endif
+
+/* Virtual memory address of the text section.
+ This is getting very complicated. A good reason to discard a.out format
+ for something that specifies these fields explicitly. But til then...
+
+ * OMAGIC and NMAGIC files:
+ (object files: text for "relocatable addr 0" right after the header)
+ start at 0, offset is EXEC_BYTES_SIZE, size as stated.
+ * The text address, offset, and size of ZMAGIC files depend
+ on the entry point of the file:
+ * entry point below TEXT_START_ADDR:
+ (hack for SunOS shared libraries)
+ start at 0, offset is 0, size as stated.
+ * If N_HEADER_IN_TEXT(x) is true (which defaults to being the
+ case when the entry point is EXEC_BYTES_SIZE or further into a page):
+ no padding is needed; text can start after exec header. Sun
+ considers the text segment of such files to include the exec header;
+ for BFD's purposes, we don't, which makes more work for us.
+ start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE,
+ size as stated minus EXEC_BYTES_SIZE.
+ * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when
+ the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page
+ aligned)): (padding is needed so that text can start at a page boundary)
+ start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated.
+
+ Specific configurations may want to hardwire N_HEADER_IN_TEXT,
+ for efficiency or to allow people to play games with the entry point.
+ In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos,
+ and as 0 for most other hosts (Sony News, Vax Ultrix, etc).
+ (Do this in the appropriate bfd target file.)
+ (The default is a heuristic that will break if people try changing
+ the entry point, perhaps with the ld -e flag.)
+
+ * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true,
+ and for which the starting address is TARGET_PAGE_SIZE (or should this be
+ SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC).
+ */
+
+/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header
+ in the text. */
+#ifndef N_HEADER_IN_TEXT
+#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE)
+#endif
+
+/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC
+ files. */
+#ifndef N_SHARED_LIB
+#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
+#endif
+
+/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
+ the assumption that we are dealing with a .o file, not an
+ executable. This is necessary for OMAGIC (but means we don't work
+ right on the output from ld -N); more questionable for NMAGIC. */
+
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) \
+ (/* The address of a QMAGIC file is always one page in, */ \
+ /* with the header in the text. */ \
+ N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \
+ N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\
+ N_SHARED_LIB(x) ? 0 : \
+ N_HEADER_IN_TEXT(x) ? \
+ TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\
+ TEXT_START_ADDR /* a page of padding */\
+ )
+#endif
+
+/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
+ to make the text segment start at a certain boundary. For most
+ systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the
+ time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
+ not what TARGET_PAGE_SIZE needs to be for QMAGIC. */
+
+#ifndef ZMAGIC_DISK_BLOCK_SIZE
+#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE
+#endif
+
+#define N_DISK_BLOCK_SIZE(x) \
+ (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE)
+
+/* Offset in an a.out of the start of the text section. */
+#ifndef N_TXTOFF
+#define N_TXTOFF(x) \
+ (/* For {O,N,Q}MAGIC, no padding. */ \
+ N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \
+ N_SHARED_LIB(x) ? 0 : \
+ N_HEADER_IN_TEXT(x) ? \
+ EXEC_BYTES_SIZE : /* no padding */\
+ ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\
+ )
+#endif
+/* Size of the text section. It's always as stated, except that we
+ offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF
+ for ZMAGIC files that nominally include the exec header
+ as part of the first page of text. (BFD doesn't consider the
+ exec header to be part of the text segment.) */
+#ifndef N_TXTSIZE
+#define N_TXTSIZE(x) \
+ (/* For QMAGIC, we don't consider the header part of the text section. */\
+ N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \
+ (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \
+ N_HEADER_IN_TEXT(x) ? \
+ (x).a_text - EXEC_BYTES_SIZE: /* no padding */\
+ (x).a_text /* a page of padding */\
+ )
+#endif
+/* The address of the data segment in virtual memory.
+ It is the text segment address, plus text segment size, rounded
+ up to a N_SEGSIZE boundary for pure or pageable files. */
+#ifndef N_DATADDR
+#define N_DATADDR(x) \
+ (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
+#endif
+/* The address of the BSS segment -- immediately after the data segment. */
+
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+
+/* Offsets of the various portions of the file after the text segment. */
+
+/* For {Q,Z}MAGIC, there is padding to make the data segment start on
+ a page boundary. Most of the time the a_text field (and thus
+ N_TXTSIZE) already contains this padding. It is possible that for
+ BSDI and/or 386BSD it sometimes doesn't contain the padding, and
+ perhaps we should be adding it here. But this seems kind of
+ questionable and probably should be BSDI/386BSD-specific if we do
+ do it.
+
+ For NMAGIC (at least for hp300 BSD, probably others), there is
+ padding in memory only, not on disk, so we must *not* ever pad here
+ for NMAGIC. */
+
+#ifndef N_DATOFF
+#define N_DATOFF(x) \
+ (N_TXTOFF(x) + N_TXTSIZE(x))
+#endif
+
+#ifndef N_TRELOFF
+#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data )
+#endif
+#ifndef N_DRELOFF
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#endif
+#ifndef N_SYMOFF
+#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize )
+#endif
+#ifndef N_STROFF
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#endif
+
+/* Symbols */
+#ifndef external_nlist
+struct external_nlist {
+ bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */
+ bfd_byte e_type[1]; /* type of symbol */
+ bfd_byte e_other[1]; /* misc info (usually empty) */
+ bfd_byte e_desc[2]; /* description field */
+ bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */
+};
+#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
+#endif
+
+struct internal_nlist {
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+};
+
+/* The n_type field is the symbol type, containing: */
+
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol -- defined at particular addr */
+#define N_TEXT 4 /* Text sym -- defined at offset in text seg */
+#define N_DATA 6 /* Data sym -- defined at offset in data seg */
+#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */
+#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */
+#define N_FN 0x1f /* File name of .o file */
+#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */
+/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
+ N_DATA, or N_BSS. When the low-order bit of other types is set,
+ (e.g. N_WARNING versus N_FN), they are two different types. */
+#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */
+#define N_TYPE 0x1e
+#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */
+
+#define N_INDR 0x0a
+
+/* The following symbols refer to set elements.
+ All the N_SET[ATDB] symbols with the same name form one set.
+ Space is allocated for the set in the text section, and each set
+ elements value is stored into one word of the space.
+ The first word of the space is the length of the set (number of elements).
+
+ The address of the set is made into an N_SETV symbol
+ whose name is the same as the name of the set.
+ This symbol acts like a N_DATA global symbol
+ in that it can satisfy undefined external references. */
+
+/* These appear as input to LD, in a .o file. */
+#define N_SETA 0x14 /* Absolute set element symbol */
+#define N_SETT 0x16 /* Text set element symbol */
+#define N_SETD 0x18 /* Data set element symbol */
+#define N_SETB 0x1A /* Bss set element symbol */
+
+/* This is output from LD. */
+#define N_SETV 0x1C /* Pointer to set vector in data area. */
+
+/* Warning symbol. The text gives a warning message, the next symbol
+ in the table will be undefined. When the symbol is referenced, the
+ message is printed. */
+
+#define N_WARNING 0x1e
+
+/* Weak symbols. These are a GNU extension to the a.out format. The
+ semantics are those of ELF weak symbols. Weak symbols are always
+ externally visible. The N_WEAK? values are squeezed into the
+ available slots. The value of a N_WEAKU symbol is 0. The values
+ of the other types are the definitions. */
+#define N_WEAKU 0x0d /* Weak undefined symbol. */
+#define N_WEAKA 0x0e /* Weak absolute symbol. */
+#define N_WEAKT 0x0f /* Weak text symbol. */
+#define N_WEAKD 0x10 /* Weak data symbol. */
+#define N_WEAKB 0x11 /* Weak bss symbol. */
+
+/* Relocations
+
+ There are two types of relocation flavours for a.out systems,
+ standard and extended. The standard form is used on systems where the
+ instruction has room for all the bits of an offset to the operand, whilst
+ the extended form is used when an address operand has to be split over n
+ instructions. Eg, on the 68k, each move instruction can reference
+ the target with a displacement of 16 or 32 bits. On the sparc, move
+ instructions use an offset of 14 bits, so the offset is stored in
+ the reloc field, and the data in the section is ignored.
+*/
+
+/* This structure describes a single relocation to be performed.
+ The text-relocation section of the file is a vector of these structures,
+ all of which apply to the text section.
+ Likewise, the data-relocation section applies to the data section. */
+
+struct reloc_std_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+};
+
+#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
+#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
+
+#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
+#define RELOC_STD_BITS_LENGTH_SH_BIG 5
+#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
+#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
+
+#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
+#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
+
+#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
+#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
+
+#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
+#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
+
+#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
+#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
+
+#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
+
+struct reloc_std_internal
+{
+ bfd_vma r_address; /* Address (within segment) to be relocated. */
+ /* The meaning of r_symbolnum depends on r_extern. */
+ unsigned int r_symbolnum:24;
+ /* Nonzero means value is a pc-relative offset
+ and it should be relocated for changes in its own address
+ as well as for changes in the symbol or section specified. */
+ unsigned int r_pcrel:1;
+ /* Length (as exponent of 2) of the field to be relocated.
+ Thus, a value of 2 indicates 1<<2 bytes. */
+ unsigned int r_length:2;
+ /* 1 => relocate with value of symbol.
+ r_symbolnum is the index of the symbol
+ in files the symbol table.
+ 0 => relocate with the address of a segment.
+ r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
+ (the N_EXT bit may be set also, but signifies nothing). */
+ unsigned int r_extern:1;
+ /* The next three bits are for SunOS shared libraries, and seem to
+ be undocumented. */
+ unsigned int r_baserel:1; /* Linkage table relative */
+ unsigned int r_jmptable:1; /* pc-relative to jump table */
+ unsigned int r_relative:1; /* "relative relocation" */
+ /* unused */
+ unsigned int r_pad:1; /* Padding -- set to zero */
+};
+
+
+/* EXTENDED RELOCS */
+
+struct reloc_ext_external {
+ bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */
+ bfd_byte r_index[3]; /* symbol table index of symbol */
+ bfd_byte r_type[1]; /* relocation type */
+ bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
+};
+
+#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
+#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
+
+#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
+#define RELOC_EXT_BITS_TYPE_SH_BIG 0
+#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
+
+/* Bytes per relocation entry */
+#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
+
+enum reloc_type
+{
+ /* simple relocations */
+ RELOC_8, /* data[0:7] = addend + sv */
+ RELOC_16, /* data[0:15] = addend + sv */
+ RELOC_32, /* data[0:31] = addend + sv */
+ /* pc-rel displacement */
+ RELOC_DISP8, /* data[0:7] = addend - pc + sv */
+ RELOC_DISP16, /* data[0:15] = addend - pc + sv */
+ RELOC_DISP32, /* data[0:31] = addend - pc + sv */
+ /* Special */
+ RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */
+ RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */
+ RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */
+ RELOC_22, /* data[0:21] = (addend + sv) */
+ RELOC_13, /* data[0:12] = (addend + sv) */
+ RELOC_LO10, /* data[0:9] = (addend + sv) */
+ RELOC_SFA_BASE,
+ RELOC_SFA_OFF13,
+ /* P.I.C. (base-relative) */
+ RELOC_BASE10, /* Not sure - maybe we can do this the */
+ RELOC_BASE13, /* right way now */
+ RELOC_BASE22,
+ /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_PC10,
+ RELOC_PC22,
+ /* P.I.C. jump table */
+ RELOC_JMP_TBL,
+ /* reputedly for shared libraries somehow */
+ RELOC_SEGOFF16,
+ RELOC_GLOB_DAT,
+ RELOC_JMP_SLOT,
+ RELOC_RELATIVE,
+
+ RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */
+ RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG,
+ RELOC_CONST,
+ RELOC_CONSTH,
+
+ /* All the new ones I can think of, for sparc v9 */
+
+ RELOC_64, /* data[0:63] = addend + sv */
+ RELOC_DISP64, /* data[0:63] = addend - pc + sv */
+ RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
+ RELOC_DISP21, /* data[0:20] = addend - pc + sv */
+ RELOC_DISP14, /* data[0:13] = addend - pc + sv */
+ /* Q .
+ What are the other ones,
+ Since this is a clean slate, can we throw away the ones we dont
+ understand ? Should we sort the values ? What about using a
+ microcode format like the 68k ?
+ */
+ NO_RELOC
+ };
+
+
+struct reloc_internal {
+ bfd_vma r_address; /* offset of of data to relocate */
+ long r_index; /* symbol table index of symbol */
+ enum reloc_type r_type; /* relocation type */
+ bfd_vma r_addend; /* datum addend */
+};
+
+/* Q.
+ Should the length of the string table be 4 bytes or 8 bytes ?
+
+ Q.
+ What about archive indexes ?
+
+ */
+
+#endif /* __A_OUT_64_H__ */
diff --git a/include/aout/ar.h b/include/aout/ar.h
new file mode 100644
index 00000000000..7b5dcdabd10
--- /dev/null
+++ b/include/aout/ar.h
@@ -0,0 +1,36 @@
+/* archive file definition for GNU software */
+
+/* So far this is correct for BSDish archives. Don't forget that
+ files must begin on an even byte boundary. */
+
+#ifndef __GNU_AR_H__
+#define __GNU_AR_H__
+
+/* Note that the usual '\n' in magic strings may translate to different
+ characters, as allowed by ANSI. '\012' has a fixed value, and remains
+ compatible with existing BSDish archives. */
+
+#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
+#define ARMAGB "!<bout>\012" /* For b.out archives */
+#define SARMAG 8
+#define ARFMAG "`\012"
+
+/* The ar_date field of the armap (__.SYMDEF) member of an archive
+ must be greater than the modified date of the entire file, or
+ BSD-derived linkers complain. We originally write the ar_date with
+ this offset from the real file's mod-time. After finishing the
+ file, we rewrite ar_date if it's not still greater than the mod date. */
+
+#define ARMAP_TIME_OFFSET 60
+
+struct ar_hdr {
+ char ar_name[16]; /* name of this member */
+ char ar_date[12]; /* file mtime */
+ char ar_uid[6]; /* owner uid; printed as decimal */
+ char ar_gid[6]; /* owner gid; printed as decimal */
+ char ar_mode[8]; /* file mode, printed as octal */
+ char ar_size[10]; /* file size, printed as decimal */
+ char ar_fmag[2]; /* should contain ARFMAG */
+};
+
+#endif /* __GNU_AR_H__ */
diff --git a/include/aout/dynix3.h b/include/aout/dynix3.h
new file mode 100644
index 00000000000..efeeebfc4cc
--- /dev/null
+++ b/include/aout/dynix3.h
@@ -0,0 +1,71 @@
+/*
+ * a.out specifics for Sequent Symmetry running Dynix 3.x
+ */
+#ifndef A_OUT_DYNIX3_H
+#define A_OUT_DYNIX3_H
+
+#define external_exec dynix_external_exec
+
+/* struct exec for Dynix 3
+ *
+ * a_gdtbl and a_bootstrap are only for standalone binaries.
+ * Shared data fields are not supported by the kernel as of Dynix 3.1,
+ * but are supported by Dynix compiler programs.
+ */
+struct dynix_external_exec {
+ unsigned char e_info[4];
+ unsigned char e_text[4];
+ unsigned char e_data[4];
+ unsigned char e_bss[4];
+ unsigned char e_syms[4];
+ unsigned char e_entry[4];
+ unsigned char e_trsize[4];
+ unsigned char e_drsize[4];
+ unsigned char e_g_code[8], e_g_data[8], e_g_desc[8];
+ unsigned char e_shdata[4];
+ unsigned char e_shbss[4];
+ unsigned char e_shdrsize[4];
+ unsigned char e_bootstrap[44];
+ unsigned char e_reserved[12];
+ unsigned char e_version[4];
+};
+
+#define EXEC_BYTES_SIZE (128)
+
+/*
+ * All executables under Dynix are demand paged with read-only text,
+ * Thus no NMAGIC.
+ *
+ * ZMAGIC has a page of 0s at virtual 0,
+ * XMAGIC has an invalid page at virtual 0
+ */
+#define OMAGIC 0x12eb /* .o */
+#define ZMAGIC 0x22eb /* zero @ 0, demand load */
+#define XMAGIC 0x32eb /* invalid @ 0, demand load */
+#define SMAGIC 0x42eb /* standalone, not supported here */
+
+#define N_BADMAG(x) ((OMAGIC != N_MAGIC(x)) && \
+ (ZMAGIC != N_MAGIC(x)) && \
+ (XMAGIC != N_MAGIC(x)) && \
+ (SMAGIC != N_MAGIC(x)))
+
+#define N_ADDRADJ(x) ((ZMAGIC == N_MAGIC(x) || XMAGIC == N_MAGIC(x)) ? 0x1000 : 0)
+
+#define N_TXTOFF(x) (EXEC_BYTES_SIZE)
+#define N_DATOFF(x) (N_TXTOFF(x) + N_TXTSIZE(x))
+#define N_SHDATOFF(x) (N_DATOFF(x) + (x).a_data)
+#define N_TRELOFF(x) (N_SHDATOFF(x) + (x).a_shdata)
+#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
+#define N_SHDRELOFF(x) (N_DRELOFF(x) + (x).a_drsize)
+#define N_SYMOFF(x) (N_SHDRELOFF(x) + (x).a_shdrsize)
+#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
+
+#define N_TXTADDR(x) \
+ (((OMAGIC == N_MAGIC(x)) || (SMAGIC == N_MAGIC(x))) ? 0 \
+ : TEXT_START_ADDR + EXEC_BYTES_SIZE)
+
+#define N_TXTSIZE(x) \
+ (((OMAGIC == N_MAGIC(x)) || (SMAGIC == N_MAGIC(x))) ? ((x).a_text) \
+ : ((x).a_text - N_ADDRADJ(x) - EXEC_BYTES_SIZE))
+
+#endif /* A_OUT_DYNIX3_H */
diff --git a/include/aout/encap.h b/include/aout/encap.h
new file mode 100644
index 00000000000..b215d49be16
--- /dev/null
+++ b/include/aout/encap.h
@@ -0,0 +1,135 @@
+/* Yet Another Try at encapsulating bsd object files in coff.
+ Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+ Written by Pace Willisson 12/9/88
+
+ This file is obsolete. It needs to be converted to just define a bunch
+ of stuff that BFD can use to do coff-encapsulated files. --gnu@cygnus.com
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * We only use the coff headers to tell the kernel
+ * how to exec the file. Therefore, the only fields that need to
+ * be filled in are the scnptr and vaddr for the text and data
+ * sections, and the vaddr for the bss. As far as coff is concerned,
+ * there is no symbol table, relocation, or line numbers.
+ *
+ * A normal bsd header (struct exec) is placed after the coff headers,
+ * and before the real text. I defined a the new fields 'a_machtype'
+ * and a_flags. If a_machtype is M_386, and a_flags & A_ENCAP is
+ * true, then the bsd header is preceeded by a coff header. Macros
+ * like N_TXTOFF and N_TXTADDR use this field to find the bsd header.
+ *
+ * The only problem is to track down the bsd exec header. The
+ * macros HEADER_OFFSET, etc do this.
+ */
+
+#define N_FLAGS_COFF_ENCAPSULATE 0x20 /* coff header precedes bsd header */
+
+/* Describe the COFF header used for encapsulation. */
+
+struct coffheader
+{
+ /* filehdr */
+ unsigned short f_magic;
+ unsigned short f_nscns;
+ long f_timdat;
+ long f_symptr;
+ long f_nsyms;
+ unsigned short f_opthdr;
+ unsigned short f_flags;
+ /* aouthdr */
+ short magic;
+ short vstamp;
+ long tsize;
+ long dsize;
+ long bsize;
+ long entry;
+ long text_start;
+ long data_start;
+ struct coffscn
+ {
+ char s_name[8];
+ long s_paddr;
+ long s_vaddr;
+ long s_size;
+ long s_scnptr;
+ long s_relptr;
+ long s_lnnoptr;
+ unsigned short s_nreloc;
+ unsigned short s_nlnno;
+ long s_flags;
+ } scns[3];
+};
+
+/* Describe some of the parameters of the encapsulation,
+ including how to find the encapsulated BSD header. */
+
+/* FIXME, this is dumb. The same tools can't handle a.outs for different
+ architectures, just because COFF_MAGIC is different; so you need a
+ separate GNU nm for every architecture!!? Unfortunately, it needs to
+ be this way, since the COFF_MAGIC value is determined by the kernel
+ we're trying to fool here. */
+
+#define COFF_MAGIC_I386 0514 /* I386MAGIC */
+#define COFF_MAGIC_M68K 0520 /* MC68MAGIC */
+#define COFF_MAGIC_A29K 0x17A /* Used by asm29k cross-tools */
+
+#ifdef COFF_MAGIC
+short __header_offset_temp;
+#define HEADER_OFFSET(f) \
+ (__header_offset_temp = 0, \
+ fread ((char *)&__header_offset_temp, sizeof (short), 1, (f)), \
+ fseek ((f), -sizeof (short), 1), \
+ __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0)
+#else
+#define HEADER_OFFSET(f) 0
+#endif
+
+#define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1))
+
+/* Describe the characteristics of the BSD header
+ that appears inside the encapsulation. */
+
+/* Encapsulated coff files that are linked ZMAGIC have a text segment
+ offset just past the header (and a matching TXTADDR), excluding
+ the headers from the text segment proper but keeping the physical
+ layout and the virtual memory layout page-aligned.
+
+ Non-encapsulated a.out files that are linked ZMAGIC have a text
+ segment that starts at 0 and an N_TXTADR similarly offset to 0.
+ They too are page-aligned with each other, but they include the
+ a.out header as part of the text.
+
+ The _N_HDROFF gets sizeof struct exec added to it, so we have
+ to compensate here. See <a.out.gnu.h>. */
+
+#undef _N_HDROFF
+#undef N_TXTADDR
+#undef N_DATADDR
+
+#define _N_HDROFF(x) ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
+ sizeof (struct coffheader) : 0)
+
+/* Address of text segment in memory after it is loaded. */
+#define N_TXTADDR(x) \
+ ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
+ sizeof (struct coffheader) + sizeof (struct exec) : 0)
+#define SEGMENT_SIZE 0x400000
+
+#define N_DATADDR(x) \
+ ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
+ (SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1))) : \
+ (N_TXTADDR(x)+(x).a_text))
diff --git a/include/aout/host.h b/include/aout/host.h
new file mode 100644
index 00000000000..8e36212716c
--- /dev/null
+++ b/include/aout/host.h
@@ -0,0 +1,22 @@
+/* Parameters about the a.out format, based on the host system on which
+ the program is compiled. */
+
+/* Address of data segment in memory after it is loaded.
+ It is up to you to define SEGMENT_SIZE
+ on machines not listed here. */
+#ifndef SEGMENT_SIZE
+#if defined(hp300) || defined(pyr)
+#define SEGMENT_SIZE page_size
+#endif
+#ifdef sony
+#define SEGMENT_SIZE 0x1000
+#endif /* Sony. */
+#ifdef is68k
+#define SEGMENT_SIZE 0x20000
+#endif
+#if defined(m68k) && defined(PORTAR)
+#define TARGET_PAGE_SIZE 0x400
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#endif
+#endif /*!defined(SEGMENT_SIZE)*/
+
diff --git a/include/aout/hp.h b/include/aout/hp.h
new file mode 100644
index 00000000000..002f49cf453
--- /dev/null
+++ b/include/aout/hp.h
@@ -0,0 +1,82 @@
+/* Special version of <a.out.h> for use under hp-ux.
+ Copyright 1988, 1991 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* THIS FILE IS OBSOLETE. It needs to be revised as a variant "external"
+ a.out format for use with BFD. */
+
+/* The `exec' structure and overall layout must be close to HP's when
+ we are running on an HP system, otherwise we will not be able to
+ execute the resulting file. */
+
+/* Allow this file to be included twice. */
+#ifndef __GNU_EXEC_MACROS__
+
+struct exec
+{
+ unsigned short a_machtype; /* machine type */
+ unsigned short a_magic; /* magic number */
+ unsigned long a_spare1;
+ unsigned long a_spare2;
+ unsigned long a_text; /* length of text, in bytes */
+ unsigned long a_data; /* length of data, in bytes */
+ unsigned long a_bss; /* length of uninitialized data area for file, in bytes */
+ unsigned long a_trsize; /* length of relocation info for text, in bytes */
+ unsigned long a_drsize; /* length of relocation info for data, in bytes */
+ unsigned long a_spare3; /* HP = pascal interface size */
+ unsigned long a_spare4; /* HP = symbol table size */
+ unsigned long a_spare5; /* HP = debug name table size */
+ unsigned long a_entry; /* start address */
+ unsigned long a_spare6; /* HP = source line table size */
+ unsigned long a_spare7; /* HP = value table size */
+ unsigned long a_syms; /* length of symbol table data in file, in bytes */
+ unsigned long a_spare8;
+};
+
+/* Tell a.out.gnu.h not to define `struct exec'. */
+#define __STRUCT_EXEC_OVERRIDE__
+
+#include "../a.out.gnu.h"
+
+#undef N_MAGIC
+#undef N_MACHTYPE
+#undef N_FLAGS
+#undef N_SET_INFO
+#undef N_SET_MAGIC
+#undef N_SET_MACHTYPE
+#undef N_SET_FLAGS
+
+#define N_MAGIC(exec) ((exec) . a_magic)
+#define N_MACHTYPE(exec) ((exec) . a_machtype)
+#define N_SET_MAGIC(exec, magic) (((exec) . a_magic) = (magic))
+#define N_SET_MACHTYPE(exec, machtype) (((exec) . a_machtype) = (machtype))
+
+#undef N_BADMAG
+#define N_BADMAG(x) ((_N_BADMAG (x)) || (_N_BADMACH (x)))
+
+#define _N_BADMACH(x) \
+(((N_MACHTYPE (x)) != HP9000S200_ID) && \
+ ((N_MACHTYPE (x)) != HP98x6_ID))
+
+#define HP98x6_ID 0x20A
+#define HP9000S200_ID 0x20C
+
+#undef _N_HDROFF
+#define _N_HDROFF(x) (SEGMENT_SIZE - (sizeof (struct exec)))
+
+#define SEGMENT_SIZE 0x1000
+
+#endif /* __GNU_EXEC_MACROS__ */
diff --git a/include/aout/hp300hpux.h b/include/aout/hp300hpux.h
new file mode 100644
index 00000000000..44d5196144d
--- /dev/null
+++ b/include/aout/hp300hpux.h
@@ -0,0 +1,119 @@
+/* Special version of <a.out.h> for use under hp-ux.
+ Copyright (C) 1988,1993 Free Software Foundation, Inc. */
+
+struct hp300hpux_exec_bytes
+{
+ unsigned char e_info[4]; /* a_machtype/a_magic */
+ unsigned char e_spare1[4];
+ unsigned char e_spare2[4];
+ unsigned char e_text[4]; /* length of text, in bytes */
+ unsigned char e_data[4]; /* length of data, in bytes */
+ unsigned char e_bss[4]; /* length of uninitialized data area , in bytes */
+ unsigned char e_trsize[4]; /* length of relocation info for text, in bytes*/
+ unsigned char e_drsize[4]; /* length of relocation info for data, in bytes*/
+ unsigned char e_passize[4];/* HP = pascal interface size */
+ unsigned char e_syms[4]; /* HP = symbol table size */
+ unsigned char e_spare5[4]; /* HP = debug name table size */
+ unsigned char e_entry[4]; /* start address */
+ unsigned char e_spare6[4]; /* HP = source line table size */
+ unsigned char e_supsize[4];/* HP = value table size */
+ unsigned char e_drelocs[4];
+ unsigned char e_extension[4]; /* file offset of extension */
+};
+#define EXEC_BYTES_SIZE 64
+
+struct hp300hpux_nlist_bytes
+ {
+ unsigned char e_value[4];
+ unsigned char e_type[1];
+ unsigned char e_length[1]; /* length of ascii symbol name */
+ unsigned char e_almod[2]; /* alignment mod */
+ unsigned char e_shlib[2]; /* info about dynamic linking */
+ };
+#define EXTERNAL_NLIST_SIZE 10
+
+struct hp300hpux_reloc
+ {
+ unsigned char r_address[4];/* offset of of data to relocate */
+ unsigned char r_index[2]; /* symbol table index of symbol */
+ unsigned char r_type[1]; /* relocation type */
+ unsigned char r_length[1]; /* length of item to reloc */
+ };
+
+struct hp300hpux_header_extension
+{
+ unsigned char e_syms[4];
+ unsigned char unique_headers[12*4];
+ unsigned char e_header[2]; /* type of header */
+ unsigned char e_version[2]; /* version */
+ unsigned char e_size[4]; /* bytes following*/
+ unsigned char e_extension[4];/* file offset of next extension */
+};
+#define EXTERNAL_EXTENSION_HEADER_SIZE (16*4)
+
+/* hpux separates object files (0x106) and impure executables (0x107) */
+/* but the bfd code does not distinguish between them. Since we want to*/
+/* read hpux .o files, we add an special define and use it below in */
+/* offset and address calculations. */
+
+#define HPUX_DOT_O_MAGIC 0x106
+#define OMAGIC 0x107 /* object file or impure executable. */
+#define NMAGIC 0x108 /* Code indicating pure executable. */
+#define ZMAGIC 0x10B /* demand-paged executable. */
+
+#define N_HEADER_IN_TEXT(x) 0
+
+#if 0 /* libaout.h only uses the lower 8 bits */
+#define HP98x6_ID 0x20A
+#define HP9000S200_ID 0x20C
+#endif
+#define HP98x6_ID 0x0A
+#define HP9000S200_ID 0x0C
+
+#define N_BADMAG(x) ((_N_BADMAG (x)) || (_N_BADMACH (x)))
+
+#define N_DATADDR(x) \
+ ((N_MAGIC(x)==OMAGIC || N_MAGIC(x)==HPUX_DOT_O_MAGIC) ? \
+ (N_TXTADDR(x)+N_TXTSIZE(x)) \
+ : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1))))
+
+#define _N_BADMACH(x) \
+(((N_MACHTYPE (x)) != HP9000S200_ID) && \
+ ((N_MACHTYPE (x)) != HP98x6_ID))
+
+#define _N_BADMAG(x) (N_MAGIC(x) != HPUX_DOT_O_MAGIC \
+ && N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC )
+
+#undef _N_HDROFF
+#define _N_HDROFF(x) (SEGMENT_SIZE - (sizeof (struct exec)))
+
+#undef N_DATOFF
+#undef N_PASOFF
+#undef N_SYMOFF
+#undef N_SUPOFF
+#undef N_TRELOFF
+#undef N_DRELOFF
+#undef N_STROFF
+
+#define N_DATOFF(x) ( N_TXTOFF(x) + N_TXTSIZE(x) )
+#define N_PASOFF(x) ( N_DATOFF(x) + (x).a_data)
+#define N_SYMOFF(x) ( N_PASOFF(x) /* + (x).a_passize*/ )
+#define N_SUPOFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#define N_TRELOFF(x) ( N_SUPOFF(x) /* + 0 (x).a_supsize*/ )
+#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize )
+#define N_EXTHOFF(x) ( N_DRELOFF(x) /* + 0 (x).a_drsize */)
+#define N_STROFF(x) ( 0 /* no string table */ )
+
+/* use these when the file has gnu symbol tables */
+#define N_GNU_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#define N_GNU_DRELOFF(x) (N_GNU_TRELOFF(x) + (x).a_trsize)
+#define N_GNU_SYMOFF(x) (N_GNU_DRELOFF(x) + (x).a_drsize)
+
+#define TARGET_PAGE_SIZE 0x1000
+#define SEGMENT_SIZE 0x1000
+#define TEXT_START_ADDR 0
+
+#undef N_SHARED_LIB
+#define N_SHARED_LIB(x) ( 0 /* no shared libraries */ )
diff --git a/include/aout/hppa.h b/include/aout/hppa.h
new file mode 100644
index 00000000000..7e185de768a
--- /dev/null
+++ b/include/aout/hppa.h
@@ -0,0 +1,7 @@
+#include "filehdr.h"
+#include "aouthdr.h"
+#include "scnhdr.h"
+#include "spacehdr.h"
+#include "syms.h"
+
+
diff --git a/include/aout/ranlib.h b/include/aout/ranlib.h
new file mode 100644
index 00000000000..982600514b6
--- /dev/null
+++ b/include/aout/ranlib.h
@@ -0,0 +1,62 @@
+/* ranlib.h -- archive library index member definition for GNU.
+ Copyright 1990-1991 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* The Symdef member of an archive contains two things:
+ a table that maps symbol-string offsets to file offsets,
+ and a symbol-string table. All the symbol names are
+ run together (each with trailing null) in the symbol-string
+ table. There is a single longword bytecount on the front
+ of each of these tables. Thus if we have two symbols,
+ "foo" and "_bar", that are in archive members at offsets
+ 200 and 900, it would look like this:
+ 16 ; byte count of index table
+ 0 ; offset of "foo" in string table
+ 200 ; offset of foo-module in file
+ 4 ; offset of "bar" in string table
+ 900 ; offset of bar-module in file
+ 9 ; byte count of string table
+ "foo\0_bar\0" ; string table */
+
+#define RANLIBMAG "__.SYMDEF" /* Archive file name containing index */
+#define RANLIBSKEW 3 /* Creation time offset */
+
+/* Format of __.SYMDEF:
+ First, a longword containing the size of the 'symdef' data that follows.
+ Second, zero or more 'symdef' structures.
+ Third, a longword containing the length of symbol name strings.
+ Fourth, zero or more symbol name strings (each followed by a null). */
+
+struct symdef
+ {
+ union
+ {
+ unsigned long string_offset; /* In the file */
+ char *name; /* In memory, sometimes */
+ } s;
+ /* this points to the front of the file header (AKA member header --
+ a struct ar_hdr), not to the front of the file or into the file).
+ in other words it only tells you which file to read */
+ unsigned long file_offset;
+ };
+
+/* Compatability with BSD code */
+
+#define ranlib symdef
+#define ran_un s
+#define ran_strx string_offset
+#define ran_name name
+#define ran_off file_offset
diff --git a/include/aout/reloc.h b/include/aout/reloc.h
new file mode 100644
index 00000000000..563c552a357
--- /dev/null
+++ b/include/aout/reloc.h
@@ -0,0 +1,66 @@
+/* reloc.h -- Header file for relocation information.
+ Copyright 1989-1991 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Relocation types for a.out files using reloc_info_extended
+ (SPARC and AMD 29000). */
+
+#ifndef _RELOC_H_READ_
+#define _RELOC_H_READ_ 1
+
+enum reloc_type
+ {
+ RELOC_8, RELOC_16, RELOC_32, /* simple relocations */
+ RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* pc-rel displacement */
+ RELOC_WDISP30, RELOC_WDISP22,
+ RELOC_HI22, RELOC_22,
+ RELOC_13, RELOC_LO10,
+ RELOC_SFA_BASE, RELOC_SFA_OFF13,
+ RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* P.I.C. (base-relative) */
+ RELOC_PC10, RELOC_PC22, /* for some sort of pc-rel P.I.C. (?) */
+ RELOC_JMP_TBL, /* P.I.C. jump table */
+ RELOC_SEGOFF16, /* reputedly for shared libraries somehow */
+ RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE,
+ RELOC_11,
+ RELOC_WDISP2_14,
+ RELOC_WDISP19,
+ RELOC_HHI22,
+ RELOC_HLO10,
+
+ /* 29K relocation types */
+ RELOC_JUMPTARG, RELOC_CONST, RELOC_CONSTH,
+
+ RELOC_WDISP14, RELOC_WDISP21,
+
+ NO_RELOC
+ };
+
+#define RELOC_TYPE_NAMES \
+"8", "16", "32", "DISP8", \
+"DISP16", "DISP32", "WDISP30", "WDISP22", \
+"HI22", "22", "13", "LO10", \
+"SFA_BASE", "SFAOFF13", "BASE10", "BASE13", \
+"BASE22", "PC10", "PC22", "JMP_TBL", \
+"SEGOFF16", "GLOB_DAT", "JMP_SLOT", "RELATIVE", \
+"11", "WDISP2_14", "WDISP19", "HHI22", \
+"HLO10", \
+"JUMPTARG", "CONST", "CONSTH", "WDISP14", \
+"WDISP21", \
+"NO_RELOC"
+
+#endif /* _RELOC_H_READ_ */
+
+/* end of reloc.h */
diff --git a/include/aout/stab.def b/include/aout/stab.def
new file mode 100644
index 00000000000..9c2d2dd142c
--- /dev/null
+++ b/include/aout/stab.def
@@ -0,0 +1,268 @@
+/* Table of DBX symbol codes for the GNU system.
+ Copyright (C) 1988, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files
+ overlaps the N_UNDF used for ordinary symbols. In ELF files, the
+ debug information is in a different file section, so there is no conflict.
+ This symbol's n_value gives the size of the string section associated
+ with this file. The symbol's n_strx (relative to the just-updated
+ string section start address) gives the name of the source file,
+ e.g. "foo.c", without any path information. The symbol's n_desc gives
+ the count of upcoming symbols associated with this file (not including
+ this one). */
+/* __define_stab (N_UNDF, 0x00, "UNDF") */
+
+/* Global variable. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran. Only the name is significant.
+ To find the address, look in the corresponding external symbol. */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C. Value is its address.
+ Desc is supposedly starting line number, but GCC doesn't set it
+ and DBX seems not to miss it. */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage. Value is its address.
+ "Static Sym". */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage. Value is its address. */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine. Only the name is significant. */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Solaris2: Read-only data symbols. */
+__define_stab (N_ROSYM, 0x2c, "ROSYM")
+
+/* Global symbol in Pascal.
+ Supposedly the value is its line number; I'm skeptical. */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris 2. Like N_SO, but for the object file. Two in
+ a row provide the build directory and the relative path of the .o from it.
+ Solaris2 uses this to avoid putting the stabs info into the linked
+ executable; this stab goes into the ".stab.index" section, and the debugger
+ reads the real stabs directly from the .o files instead. */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris 2. Options for the debugger, related to the
+ source language for this module. E.g. whether to use ANSI
+ integral promotions or traditional integral promotions. */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable. Value is number of register. */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit. Can someone say what info it contains? */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment. Desc is the line number;
+ value is corresponding address. On Solaris2, the line number is
+ relative to the start of the current function. */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment. */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment. */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs. ?? Don't know what the fields are.
+ Supposedly the field is "path to associated .cb file". THIS VALUE
+ OVERLAPS WITH N_BSLINE! */
+__define_stab_duplicate (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency. Value is the modification time
+ of the definition file. Other is non-zero if it is imported with the
+ GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+ are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* New in Solaris2. Function start/body/end line numbers. */
+__define_stab(N_FLINE, 0x4C, "FLINE")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2
+ and one is for C++. Still,... */
+/* GNU C++ exception variable. Name is variable name. */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */
+__define_stab_duplicate (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+ this entry is immediately followed by a CAUGHT stab saying what exception
+ was caught. Multiple CAUGHT stabs means that multiple exceptions
+ can be caught here. If Desc is 0, it means all exceptions are caught
+ here. */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element. Value is offset in the structure. */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Solaris2: Last stab emitted for module. */
+__define_stab (N_ENDM, 0x62, "ENDM")
+
+/* Name of main source file.
+ Value is starting text address of the compilation.
+ If multiple N_SO's appear, the first to contain a trailing / is the
+ compilation directory. The first to not contain a trailing / is the
+ source file name, relative to the compilation directory. Others (perhaps
+ resulting from cfront) are ignored.
+ On Solaris2, value is undefined, but desc is a source-language code. */
+
+__define_stab (N_SO, 0x64, "SO")
+
+/* SunPro F77: Name of alias. */
+__define_stab (N_ALIAS, 0x6c, "ALIAS")
+
+/* Automatic variable in the stack. Value is offset from frame pointer.
+ Also used for type descriptions. */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file. Only Sun uses this.
+ In an object file, only the name is significant.
+ The Sun linker puts data into some of the other fields. */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+ Value is starting text address of the compilation. */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable. Value is offset from argument pointer.
+ (On most machines the argument pointer is the same as the frame pointer. */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file. No name.
+ This and N_BINCL act as brackets around the file's output.
+ In an object file, there is no significant data in this entry.
+ The Sun linker puts data into some of the fields. */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point. Value is its address. */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+ The desc is the nesting level in lexical blocks.
+ The value is the address of the start of the text for the block.
+ The variables declared inside the block *precede* the N_LBRAC symbol.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file. Replaces a N_BINCL and everything
+ up to the corresponding N_EINCL. The Sun linker generates these when
+ it finds multiple identical copies of the symbols from an include file.
+ This appears only in output from the Sun linker. */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information. Can someone say what info it contains? */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block. Desc matches the N_LBRAC's desc.
+ The value is the address of the end of the text for the block.
+ On Solaris2, the value is relative to the start of the current function. */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block. Only the name is significant. */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block. Only the name is significant
+ (and it should match the N_BCOMM). */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* Member of a common block; value is offset within the common block.
+ This should occur within a BCOMM/ECOMM pair. */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* Solaris2: Pascal "with" statement: type,,0,0,offset */
+__define_stab (N_WITH, 0xea, "WITH")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+ or something like that. FIXME. I have assigned the values at random
+ since I don't have a Gould here. Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS, 0xF4, "NBBSS")
+__define_stab (N_NBSTS, 0xF6, "NBSTS")
+__define_stab (N_NBLCS, 0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+ The value is the length. */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+/* The above information, in matrix format.
+
+ STAB MATRIX
+ _________________________________________________
+ | 00 - 1F are not dbx stab symbols |
+ | In most cases, the low bit is the EXTernal bit|
+
+ | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
+ | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
+
+ | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
+ | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
+
+ | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
+ | 11 WEAKB | 13 | 15 | 17 |
+
+ | 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
+ | 19 | 1B | 1D | 1F FN |
+
+ |_______________________________________________|
+ | Debug entries with bit 01 set are unused. |
+ | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM |
+ | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E |
+ | 30 PC | 32 NSYMS | 34 NOMAP | 36 |
+ | 38 OBJ | 3A | 3C OPT | 3E |
+ | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE |
+ | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E |
+ | 50 EHDECL*| 52 | 54 CATCH | 56 |
+ | 58 | 5A | 5C | 5E |
+ | 60 SSYM | 62 ENDM | 64 SO | 66 |
+ | 68 | 6A | 6C ALIAS | 6E |
+ | 70 | 72 | 74 | 76 |
+ | 78 | 7A | 7C | 7E |
+ | 80 LSYM | 82 BINCL | 84 SOL | 86 |
+ | 88 | 8A | 8C | 8E |
+ | 90 | 92 | 94 | 96 |
+ | 98 | 9A | 9C | 9E |
+ | A0 PSYM | A2 EINCL | A4 ENTRY | A6 |
+ | A8 | AA | AC | AE |
+ | B0 | B2 | B4 | B6 |
+ | B8 | BA | BC | BE |
+ | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 |
+ | C8 | CA | CC | CE |
+ | D0 | D2 | D4 | D6 |
+ | D8 | DA | DC | DE |
+ | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 |
+ | E8 ECOML | EA WITH | EC | EE |
+ | F0 | F2 | F4 | F6 |
+ | F8 | FA | FC | FE LENG |
+ +-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
diff --git a/include/aout/stab_gnu.h b/include/aout/stab_gnu.h
new file mode 100644
index 00000000000..7d18e14a263
--- /dev/null
+++ b/include/aout/stab_gnu.h
@@ -0,0 +1,37 @@
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use. */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "aout/stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+/* Definitions of "desc" field for N_SO stabs in Solaris2. */
+
+#define N_SO_AS 1
+#define N_SO_C 2
+#define N_SO_ANSI_C 3
+#define N_SO_CC 4 /* C++ */
+#define N_SO_FORTRAN 5
+#define N_SO_PASCAL 6
+
+/* Solaris2: Floating point type values in basic types. */
+
+#define NF_NONE 0
+#define NF_SINGLE 1 /* IEEE 32-bit */
+#define NF_DOUBLE 2 /* IEEE 64-bit */
+#define NF_COMPLEX 3 /* Fortran complex */
+#define NF_COMPLEX16 4 /* Fortran double complex */
+#define NF_COMPLEX32 5 /* Fortran complex*16 */
+#define NF_LDOUBLE 6 /* Long double (whatever that is) */
+
+#endif /* __GNU_STAB_ */
diff --git a/include/aout/sun4.h b/include/aout/sun4.h
new file mode 100644
index 00000000000..f42a0dd4598
--- /dev/null
+++ b/include/aout/sun4.h
@@ -0,0 +1,219 @@
+/* SPARC-specific values for a.out files */
+
+/* Some systems, e.g., AIX, may have defined this in header files already
+ included. */
+#undef TARGET_PAGE_SIZE
+#define TARGET_PAGE_SIZE 0x2000 /* 8K. aka NBPG in <sys/param.h> */
+/* Note that some SPARCs have 4K pages, some 8K, some others. */
+
+#define SEG_SIZE_SPARC TARGET_PAGE_SIZE
+#define SEG_SIZE_SUN3 0x20000 /* Resolution of r/w protection hw */
+
+#define TEXT_START_ADDR TARGET_PAGE_SIZE /* Location 0 is not accessible */
+#define N_HEADER_IN_TEXT(x) 1
+
+/* Non-default definitions of the accessor macros... */
+
+/* Segment size varies on Sun-3 versus Sun-4. */
+
+#define N_SEGSIZE(x) (N_MACHTYPE(x) == M_SPARC? SEG_SIZE_SPARC: \
+ N_MACHTYPE(x) == M_68020? SEG_SIZE_SUN3: \
+ /* Guess? */ TARGET_PAGE_SIZE)
+
+/* Virtual Address of text segment from the a.out file. For OMAGIC,
+ (almost always "unlinked .o's" these days), should be zero.
+ Sun added a kludge so that shared libraries linked ZMAGIC get
+ an address of zero if a_entry (!!!) is lower than the otherwise
+ expected text address. These kludges have gotta go!
+ For linked files, should reflect reality if we know it. */
+
+/* This differs from the version in aout64.h (which we override by defining
+ it here) only for NMAGIC (we return TEXT_START_ADDR+EXEC_BYTES_SIZE;
+ they return 0). */
+
+#define N_TXTADDR(x) \
+ (N_MAGIC(x)==OMAGIC? 0 \
+ : (N_MAGIC(x) == ZMAGIC && (x).a_entry < TEXT_START_ADDR)? 0 \
+ : TEXT_START_ADDR+EXEC_BYTES_SIZE)
+
+/* When a file is linked against a shared library on SunOS 4, the
+ dynamic bit in the exec header is set, and the first symbol in the
+ symbol table is __DYNAMIC. Its value is the address of the
+ following structure. */
+
+struct external_sun4_dynamic
+{
+ /* The version number of the structure. SunOS 4.1.x creates files
+ with version number 3, which is what this structure is based on.
+ According to gdb, version 2 is similar. I believe that version 2
+ used a different type of procedure linkage table, and there may
+ have been other differences. */
+ bfd_byte ld_version[4];
+ /* The virtual address of a 28 byte structure used in debugging.
+ The contents are filled in at run time by ld.so. */
+ bfd_byte ldd[4];
+ /* The virtual address of another structure with information about
+ how to relocate the executable at run time. */
+ bfd_byte ld[4];
+};
+
+/* The size of the debugging structure pointed to by the debugger
+ field of __DYNAMIC. */
+#define EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE (24)
+
+/* The structure pointed to by the linker field of __DYNAMIC. As far
+ as I can tell, most of the addresses in this structure are offsets
+ within the file, but some are actually virtual addresses. */
+
+struct internal_sun4_dynamic_link
+{
+ /* Linked list of loaded objects. This is filled in at runtime by
+ ld.so and probably by dlopen. */
+ unsigned long ld_loaded;
+
+ /* The address of the list of names of shared objects which must be
+ included at runtime. Each entry in the list is 16 bytes: the 4
+ byte address of the string naming the object (e.g., for -lc this
+ is "c"); 4 bytes of flags--the high bit is whether to search for
+ the object using the library path; the 2 byte major version
+ number; the 2 byte minor version number; the 4 byte address of
+ the next entry in the list (zero if this is the last entry). The
+ version numbers seem to only be non-zero when doing library
+ searching. */
+ unsigned long ld_need;
+
+ /* The address of the path to search for the shared objects which
+ must be included. This points to a string in PATH format which
+ is generated from the -L arguments to the linker. According to
+ the man page, ld.so implicitly adds ${LD_LIBRARY_PATH} to the
+ beginning of this string and /lib:/usr/lib:/usr/local/lib to the
+ end. The string is terminated by a null byte. This field is
+ zero if there is no additional path. */
+ unsigned long ld_rules;
+
+ /* The address of the global offset table. This appears to be a
+ virtual address, not a file offset. The first entry in the
+ global offset table seems to be the virtual address of the
+ sun4_dynamic structure (the same value as the __DYNAMIC symbol).
+ The global offset table is used for PIC code to hold the
+ addresses of variables. A dynamically linked file which does not
+ itself contain PIC code has a four byte global offset table. */
+ unsigned long ld_got;
+
+ /* The address of the procedure linkage table. This appears to be a
+ virtual address, not a file offset.
+
+ On a SPARC, the table is composed of 12 byte entries, each of
+ which consists of three instructions. The first entry is
+ sethi %hi(0),%g1
+ jmp %g1
+ nop
+ These instructions are changed by ld.so into a jump directly into
+ ld.so itself. Each subsequent entry is
+ save %sp, -96, %sp
+ call <address of first entry in procedure linkage table>
+ <reloc_number | 0x01000000>
+ The reloc_number is the number of the reloc to use to resolve
+ this entry. The reloc will be a JMP_SLOT reloc against some
+ symbol that is not defined in this object file but should be
+ defined in a shared object (if it is not, ld.so will report a
+ runtime error and exit). The constant 0x010000000 turns the
+ reloc number into a sethi of %g0, which does nothing since %g0 is
+ hardwired to zero.
+
+ When one of these entries is executed, it winds up calling into
+ ld.so. ld.so looks at the reloc number, available via the return
+ address, to determine which entry this is. It then looks at the
+ reloc and patches up the entry in the table into a sethi and jmp
+ to the real address followed by a nop. This means that the reloc
+ lookup only has to happen once, and it also means that the
+ relocation only needs to be done if the function is actually
+ called. The relocation is expensive because ld.so must look up
+ the symbol by name.
+
+ The size of the procedure linkage table is given by the ld_plt_sz
+ field. */
+ unsigned long ld_plt;
+
+ /* The address of the relocs. These are in the same format as
+ ordinary relocs. Symbol index numbers refer to the symbols
+ pointed to by ld_stab. I think the only way to determine the
+ number of relocs is to assume that all the bytes from ld_rel to
+ ld_hash contain reloc entries. */
+ unsigned long ld_rel;
+
+ /* The address of a hash table of symbols. The hash table has
+ roughly the same number of entries as there are dynamic symbols;
+ I think the only way to get the exact size is to assume that
+ every byte from ld_hash to ld_stab is devoted to the hash table.
+
+ Each entry in the hash table is eight bytes. The first four
+ bytes are a symbol index into the dynamic symbols. The second
+ four bytes are the index of the next hash table entry in the
+ bucket. The ld_buckets field gives the number of buckets, say B.
+ The first B entries in the hash table each start a bucket which
+ is chained through the second four bytes of each entry. A value
+ of zero ends the chain.
+
+ The hash function is simply
+ h = 0;
+ while (*string != '\0')
+ h = (h << 1) + *string++;
+ h &= 0x7fffffff;
+
+ To look up a symbol, compute the hash value of the name. Take
+ the modulos of hash value and the number of buckets. Start at
+ that entry in the hash table. See if the symbol (from the first
+ four bytes of the hash table entry) has the name you are looking
+ for. If not, use the chain field (the second four bytes of the
+ hash table entry) to move on to the next entry in this bucket.
+ If the chain field is zero you have reached the end of the
+ bucket, and the symbol is not in the hash table. */
+ unsigned long ld_hash;
+
+ /* The address of the symbol table. This is a list of
+ external_nlist structures. The string indices are relative to
+ the ld_symbols field. I think the only way to determine the
+ number of symbols is to assume that all the bytes between ld_stab
+ and ld_symbols are external_nlist structures. */
+ unsigned long ld_stab;
+
+ /* I don't know what this is for. It seems to always be zero. */
+ unsigned long ld_stab_hash;
+
+ /* The number of buckets in the hash table. */
+ unsigned long ld_buckets;
+
+ /* The address of the symbol string table. The first string in this
+ string table need not be the empty string. */
+ unsigned long ld_symbols;
+
+ /* The size in bytes of the symbol string table. */
+ unsigned long ld_symb_size;
+
+ /* The size in bytes of the text segment. */
+ unsigned long ld_text;
+
+ /* The size in bytes of the procedure linkage table. */
+ unsigned long ld_plt_sz;
+};
+
+/* The external form of the structure. */
+
+struct external_sun4_dynamic_link
+{
+ bfd_byte ld_loaded[4];
+ bfd_byte ld_need[4];
+ bfd_byte ld_rules[4];
+ bfd_byte ld_got[4];
+ bfd_byte ld_plt[4];
+ bfd_byte ld_rel[4];
+ bfd_byte ld_hash[4];
+ bfd_byte ld_stab[4];
+ bfd_byte ld_stab_hash[4];
+ bfd_byte ld_buckets[4];
+ bfd_byte ld_symbols[4];
+ bfd_byte ld_symb_size[4];
+ bfd_byte ld_text[4];
+ bfd_byte ld_plt_sz[4];
+};
diff --git a/include/bfdlink.h b/include/bfdlink.h
new file mode 100644
index 00000000000..a055fa082da
--- /dev/null
+++ b/include/bfdlink.h
@@ -0,0 +1,520 @@
+/* bfdlink.h -- header file for BFD link routines
+ Copyright 1993, 94, 95, 96, 97, 1999 Free Software Foundation, Inc.
+ Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef BFDLINK_H
+#define BFDLINK_H
+
+/* Which symbols to strip during a link. */
+enum bfd_link_strip
+{
+ strip_none, /* Don't strip any symbols. */
+ strip_debugger, /* Strip debugging symbols. */
+ strip_some, /* keep_hash is the list of symbols to keep. */
+ strip_all /* Strip all symbols. */
+};
+
+/* Which local symbols to discard during a link. This is irrelevant
+ if strip_all is used. */
+enum bfd_link_discard
+{
+ discard_none, /* Don't discard any locals. */
+ discard_l, /* Discard local temporary symbols. */
+ discard_all /* Discard all locals. */
+};
+
+/* These are the possible types of an entry in the BFD link hash
+ table. */
+
+enum bfd_link_hash_type
+{
+ bfd_link_hash_new, /* Symbol is new. */
+ bfd_link_hash_undefined, /* Symbol seen before, but undefined. */
+ bfd_link_hash_undefweak, /* Symbol is weak and undefined. */
+ bfd_link_hash_defined, /* Symbol is defined. */
+ bfd_link_hash_defweak, /* Symbol is weak and defined. */
+ bfd_link_hash_common, /* Symbol is common. */
+ bfd_link_hash_indirect, /* Symbol is an indirect link. */
+ bfd_link_hash_warning /* Like indirect, but warn if referenced. */
+};
+
+/* The linking routines use a hash table which uses this structure for
+ its elements. */
+
+struct bfd_link_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+ /* Type of this entry. */
+ enum bfd_link_hash_type type;
+
+ /* Undefined and common symbols are kept in a linked list through
+ this field. This field is not in the union because that would
+ force us to remove entries from the list when we changed their
+ type, which would force the list to be doubly linked, which would
+ waste more memory. When an undefined or common symbol is
+ created, it should be added to this list, the head of which is in
+ the link hash table itself. As symbols are defined, they need
+ not be removed from the list; anything which reads the list must
+ doublecheck the symbol type.
+
+ Weak symbols are not kept on this list.
+
+ Defined and defweak symbols use this field as a reference marker.
+ If the field is not NULL, or this structure is the tail of the
+ undefined symbol list, the symbol has been referenced. If the
+ symbol is undefined and becomes defined, this field will
+ automatically be non-NULL since the symbol will have been on the
+ undefined symbol list. */
+ struct bfd_link_hash_entry *next;
+ /* A union of information depending upon the type. */
+ union
+ {
+ /* Nothing is kept for bfd_hash_new. */
+ /* bfd_link_hash_undefined, bfd_link_hash_undefweak. */
+ struct
+ {
+ bfd *abfd; /* BFD symbol was found in. */
+ } undef;
+ /* bfd_link_hash_defined, bfd_link_hash_defweak. */
+ struct
+ {
+ bfd_vma value; /* Symbol value. */
+ asection *section; /* Symbol section. */
+ } def;
+ /* bfd_link_hash_indirect, bfd_link_hash_warning. */
+ struct
+ {
+ struct bfd_link_hash_entry *link; /* Real symbol. */
+ const char *warning; /* Warning (bfd_link_hash_warning only). */
+ } i;
+ /* bfd_link_hash_common. */
+ struct
+ {
+ /* The linker needs to know three things about common
+ symbols: the size, the alignment, and the section in
+ which the symbol should be placed. We store the size
+ here, and we allocate a small structure to hold the
+ section and the alignment. The alignment is stored as a
+ power of two. We don't store all the information
+ directly because we don't want to increase the size of
+ the union; this structure is a major space user in the
+ linker. */
+ bfd_size_type size; /* Common symbol size. */
+ struct bfd_link_hash_common_entry
+ {
+ unsigned int alignment_power; /* Alignment. */
+ asection *section; /* Symbol section. */
+ } *p;
+ } c;
+ } u;
+};
+
+/* This is the link hash table. It is a derived class of
+ bfd_hash_table. */
+
+struct bfd_link_hash_table
+{
+ /* The hash table itself. */
+ struct bfd_hash_table table;
+ /* The back end which created this hash table. This indicates the
+ type of the entries in the hash table, which is sometimes
+ important information when linking object files of different
+ types together. */
+ const bfd_target *creator;
+ /* A linked list of undefined and common symbols, linked through the
+ next field in the bfd_link_hash_entry structure. */
+ struct bfd_link_hash_entry *undefs;
+ /* Entries are added to the tail of the undefs list. */
+ struct bfd_link_hash_entry *undefs_tail;
+};
+
+/* Look up an entry in a link hash table. If FOLLOW is true, this
+ follows bfd_link_hash_indirect and bfd_link_hash_warning links to
+ the real symbol. */
+extern struct bfd_link_hash_entry *bfd_link_hash_lookup
+ PARAMS ((struct bfd_link_hash_table *, const char *, boolean create,
+ boolean copy, boolean follow));
+
+/* Look up an entry in the main linker hash table if the symbol might
+ be wrapped. This should only be used for references to an
+ undefined symbol, not for definitions of a symbol. */
+
+extern struct bfd_link_hash_entry *bfd_wrapped_link_hash_lookup
+ PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean, boolean,
+ boolean));
+
+/* Traverse a link hash table. */
+extern void bfd_link_hash_traverse
+ PARAMS ((struct bfd_link_hash_table *,
+ boolean (*) (struct bfd_link_hash_entry *, PTR),
+ PTR));
+
+/* Add an entry to the undefs list. */
+extern void bfd_link_add_undef
+ PARAMS ((struct bfd_link_hash_table *, struct bfd_link_hash_entry *));
+
+/* This structure holds all the information needed to communicate
+ between BFD and the linker when doing a link. */
+
+struct bfd_link_info
+{
+ /* Function callbacks. */
+ const struct bfd_link_callbacks *callbacks;
+ /* true if BFD should generate a relocateable object file. */
+ boolean relocateable;
+ /* true if BFD should generate a "task linked" object file,
+ similar to relocatable but also with globals converted to statics. */
+ boolean task_link;
+ /* true if BFD should generate a shared object. */
+ boolean shared;
+ /* true if BFD should pre-bind symbols in a shared object. */
+ boolean symbolic;
+ /* true if shared objects should be linked directly, not shared. */
+ boolean static_link;
+ /* true if the output file should be in a traditional format. This
+ is equivalent to the setting of the BFD_TRADITIONAL_FORMAT flag
+ on the output file, but may be checked when reading the input
+ files. */
+ boolean traditional_format;
+ /* true if we want to produced optimized output files. This might
+ need much more time and therefore must be explicitly selected. */
+ boolean optimize;
+ /* true if BFD should generate errors for undefined symbols
+ even if generating a shared object. */
+ boolean no_undefined;
+ /* Which symbols to strip. */
+ enum bfd_link_strip strip;
+ /* Which local symbols to discard. */
+ enum bfd_link_discard discard;
+ /* true if symbols should be retained in memory, false if they
+ should be freed and reread. */
+ boolean keep_memory;
+ /* The list of input BFD's involved in the link. These are chained
+ together via the link_next field. */
+ bfd *input_bfds;
+ /* If a symbol should be created for each input BFD, this is section
+ where those symbols should be placed. It must be a section in
+ the output BFD. It may be NULL, in which case no such symbols
+ will be created. This is to support CREATE_OBJECT_SYMBOLS in the
+ linker command language. */
+ asection *create_object_symbols_section;
+ /* Hash table handled by BFD. */
+ struct bfd_link_hash_table *hash;
+ /* Hash table of symbols to keep. This is NULL unless strip is
+ strip_some. */
+ struct bfd_hash_table *keep_hash;
+ /* true if every symbol should be reported back via the notice
+ callback. */
+ boolean notice_all;
+ /* Hash table of symbols to report back via the notice callback. If
+ this is NULL, and notice_all is false, then no symbols are
+ reported back. */
+ struct bfd_hash_table *notice_hash;
+ /* Hash table of symbols which are being wrapped (the --wrap linker
+ option). If this is NULL, no symbols are being wrapped. */
+ struct bfd_hash_table *wrap_hash;
+ /* If a base output file is wanted, then this points to it */
+ PTR base_file;
+
+ /* If non-zero, specifies that branches which are problematic for the
+ MPC860 C0 (or earlier) should be checked for and modified. It gives the
+ number of bytes that should be checked at the end of each text page. */
+ int mpc860c0;
+};
+
+/* This structures holds a set of callback functions. These are
+ called by the BFD linker routines. The first argument to each
+ callback function is the bfd_link_info structure being used. Each
+ function returns a boolean value. If the function returns false,
+ then the BFD function which called it will return with a failure
+ indication. */
+
+struct bfd_link_callbacks
+{
+ /* A function which is called when an object is added from an
+ archive. ABFD is the archive element being added. NAME is the
+ name of the symbol which caused the archive element to be pulled
+ in. */
+ boolean (*add_archive_element) PARAMS ((struct bfd_link_info *,
+ bfd *abfd,
+ const char *name));
+ /* A function which is called when a symbol is found with multiple
+ definitions. NAME is the symbol which is defined multiple times.
+ OBFD is the old BFD, OSEC is the old section, OVAL is the old
+ value, NBFD is the new BFD, NSEC is the new section, and NVAL is
+ the new value. OBFD may be NULL. OSEC and NSEC may be
+ bfd_com_section or bfd_ind_section. */
+ boolean (*multiple_definition) PARAMS ((struct bfd_link_info *,
+ const char *name,
+ bfd *obfd,
+ asection *osec,
+ bfd_vma oval,
+ bfd *nbfd,
+ asection *nsec,
+ bfd_vma nval));
+ /* A function which is called when a common symbol is defined
+ multiple times. NAME is the symbol appearing multiple times.
+ OBFD is the BFD of the existing symbol; it may be NULL if this is
+ not known. OTYPE is the type of the existing symbol, which may
+ be bfd_link_hash_defined, bfd_link_hash_defweak,
+ bfd_link_hash_common, or bfd_link_hash_indirect. If OTYPE is
+ bfd_link_hash_common, OSIZE is the size of the existing symbol.
+ NBFD is the BFD of the new symbol. NTYPE is the type of the new
+ symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or
+ bfd_link_hash_indirect. If NTYPE is bfd_link_hash_common, NSIZE
+ is the size of the new symbol. */
+ boolean (*multiple_common) PARAMS ((struct bfd_link_info *,
+ const char *name,
+ bfd *obfd,
+ enum bfd_link_hash_type otype,
+ bfd_vma osize,
+ bfd *nbfd,
+ enum bfd_link_hash_type ntype,
+ bfd_vma nsize));
+ /* A function which is called to add a symbol to a set. ENTRY is
+ the link hash table entry for the set itself (e.g.,
+ __CTOR_LIST__). RELOC is the relocation to use for an entry in
+ the set when generating a relocateable file, and is also used to
+ get the size of the entry when generating an executable file.
+ ABFD, SEC and VALUE identify the value to add to the set. */
+ boolean (*add_to_set) PARAMS ((struct bfd_link_info *,
+ struct bfd_link_hash_entry *entry,
+ bfd_reloc_code_real_type reloc,
+ bfd *abfd, asection *sec, bfd_vma value));
+ /* A function which is called when the name of a g++ constructor or
+ destructor is found. This is only called by some object file
+ formats. CONSTRUCTOR is true for a constructor, false for a
+ destructor. This will use BFD_RELOC_CTOR when generating a
+ relocateable file. NAME is the name of the symbol found. ABFD,
+ SECTION and VALUE are the value of the symbol. */
+ boolean (*constructor) PARAMS ((struct bfd_link_info *,
+ boolean constructor,
+ const char *name, bfd *abfd, asection *sec,
+ bfd_vma value));
+ /* A function which is called to issue a linker warning. For
+ example, this is called when there is a reference to a warning
+ symbol. WARNING is the warning to be issued. SYMBOL is the name
+ of the symbol which triggered the warning; it may be NULL if
+ there is none. ABFD, SECTION and ADDRESS identify the location
+ which trigerred the warning; either ABFD or SECTION or both may
+ be NULL if the location is not known. */
+ boolean (*warning) PARAMS ((struct bfd_link_info *,
+ const char *warning, const char *symbol,
+ bfd *abfd, asection *section,
+ bfd_vma address));
+ /* A function which is called when a relocation is attempted against
+ an undefined symbol. NAME is the symbol which is undefined.
+ ABFD, SECTION and ADDRESS identify the location from which the
+ reference is made. In some cases SECTION may be NULL. */
+ boolean (*undefined_symbol) PARAMS ((struct bfd_link_info *,
+ const char *name, bfd *abfd,
+ asection *section, bfd_vma address));
+ /* A function which is called when a reloc overflow occurs. NAME is
+ the name of the symbol or section the reloc is against,
+ RELOC_NAME is the name of the relocation, and ADDEND is any
+ addend that is used. ABFD, SECTION and ADDRESS identify the
+ location at which the overflow occurs; if this is the result of a
+ bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then
+ ABFD will be NULL. */
+ boolean (*reloc_overflow) PARAMS ((struct bfd_link_info *,
+ const char *name,
+ const char *reloc_name, bfd_vma addend,
+ bfd *abfd, asection *section,
+ bfd_vma address));
+ /* A function which is called when a dangerous reloc is performed.
+ The canonical example is an a29k IHCONST reloc which does not
+ follow an IHIHALF reloc. MESSAGE is an appropriate message.
+ ABFD, SECTION and ADDRESS identify the location at which the
+ problem occurred; if this is the result of a
+ bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then
+ ABFD will be NULL. */
+ boolean (*reloc_dangerous) PARAMS ((struct bfd_link_info *,
+ const char *message,
+ bfd *abfd, asection *section,
+ bfd_vma address));
+ /* A function which is called when a reloc is found to be attached
+ to a symbol which is not being written out. NAME is the name of
+ the symbol. ABFD, SECTION and ADDRESS identify the location of
+ the reloc; if this is the result of a
+ bfd_section_reloc_link_order or bfd_symbol_reloc_link_order, then
+ ABFD will be NULL. */
+ boolean (*unattached_reloc) PARAMS ((struct bfd_link_info *,
+ const char *name,
+ bfd *abfd, asection *section,
+ bfd_vma address));
+ /* A function which is called when a symbol in notice_hash is
+ defined or referenced. NAME is the symbol. ABFD, SECTION and
+ ADDRESS are the value of the symbol. If SECTION is
+ bfd_und_section, this is a reference. */
+ boolean (*notice) PARAMS ((struct bfd_link_info *, const char *name,
+ bfd *abfd, asection *section, bfd_vma address));
+};
+
+/* The linker builds link_order structures which tell the code how to
+ include input data in the output file. */
+
+/* These are the types of link_order structures. */
+
+enum bfd_link_order_type
+{
+ bfd_undefined_link_order, /* Undefined. */
+ bfd_indirect_link_order, /* Built from a section. */
+ bfd_fill_link_order, /* Fill with a 16 bit constant. */
+ bfd_data_link_order, /* Set to explicit data. */
+ bfd_section_reloc_link_order, /* Relocate against a section. */
+ bfd_symbol_reloc_link_order /* Relocate against a symbol. */
+};
+
+/* This is the link_order structure itself. These form a chain
+ attached to the section whose contents they are describing. */
+
+struct bfd_link_order
+{
+ /* Next link_order in chain. */
+ struct bfd_link_order *next;
+ /* Type of link_order. */
+ enum bfd_link_order_type type;
+ /* Offset within output section. */
+ bfd_vma offset;
+ /* Size within output section. */
+ bfd_size_type size;
+ /* Type specific information. */
+ union
+ {
+ struct
+ {
+ /* Section to include. If this is used, then
+ section->output_section must be the section the
+ link_order is attached to, section->output_offset must
+ equal the link_order offset field, and section->_raw_size
+ must equal the link_order size field. Maybe these
+ restrictions should be relaxed someday. */
+ asection *section;
+ } indirect;
+ struct
+ {
+ /* Value to fill with. */
+ unsigned int value;
+ } fill;
+ struct
+ {
+ /* Data to put into file. The size field gives the number
+ of bytes which this field points to. */
+ bfd_byte *contents;
+ } data;
+ struct
+ {
+ /* Description of reloc to generate. Used for
+ bfd_section_reloc_link_order and
+ bfd_symbol_reloc_link_order. */
+ struct bfd_link_order_reloc *p;
+ } reloc;
+ } u;
+};
+
+/* A linker order of type bfd_section_reloc_link_order or
+ bfd_symbol_reloc_link_order means to create a reloc against a
+ section or symbol, respectively. This is used to implement -Ur to
+ generate relocs for the constructor tables. The
+ bfd_link_order_reloc structure describes the reloc that BFD should
+ create. It is similar to a arelent, but I didn't use arelent
+ because the linker does not know anything about most symbols, and
+ any asymbol structure it creates will be partially meaningless.
+ This information could logically be in the bfd_link_order struct,
+ but I didn't want to waste the space since these types of relocs
+ are relatively rare. */
+
+struct bfd_link_order_reloc
+{
+ /* Reloc type. */
+ bfd_reloc_code_real_type reloc;
+
+ union
+ {
+ /* For type bfd_section_reloc_link_order, this is the section
+ the reloc should be against. This must be a section in the
+ output BFD, not any of the input BFDs. */
+ asection *section;
+ /* For type bfd_symbol_reloc_link_order, this is the name of the
+ symbol the reloc should be against. */
+ const char *name;
+ } u;
+
+ /* Addend to use. The object file should contain zero. The BFD
+ backend is responsible for filling in the contents of the object
+ file correctly. For some object file formats (e.g., COFF) the
+ addend must be stored into in the object file, and for some
+ (e.g., SPARC a.out) it is kept in the reloc. */
+ bfd_vma addend;
+};
+
+/* Allocate a new link_order for a section. */
+extern struct bfd_link_order *bfd_new_link_order PARAMS ((bfd *, asection *));
+
+/* These structures are used to describe version information for the
+ ELF linker. These structures could be manipulated entirely inside
+ BFD, but it would be a pain. Instead, the regular linker sets up
+ these structures, and then passes them into BFD. */
+
+/* Regular expressions for a version. */
+
+struct bfd_elf_version_expr
+{
+ /* Next regular expression for this version. */
+ struct bfd_elf_version_expr *next;
+ /* Regular expression. */
+ const char *pattern;
+ /* Matching function. */
+ int (*match) PARAMS((struct bfd_elf_version_expr *, const char *));
+};
+
+/* Version dependencies. */
+
+struct bfd_elf_version_deps
+{
+ /* Next dependency for this version. */
+ struct bfd_elf_version_deps *next;
+ /* The version which this version depends upon. */
+ struct bfd_elf_version_tree *version_needed;
+};
+
+/* A node in the version tree. */
+
+struct bfd_elf_version_tree
+{
+ /* Next version. */
+ struct bfd_elf_version_tree *next;
+ /* Name of this version. */
+ const char *name;
+ /* Version number. */
+ unsigned int vernum;
+ /* Regular expressions for global symbols in this version. */
+ struct bfd_elf_version_expr *globals;
+ /* Regular expressions for local symbols in this version. */
+ struct bfd_elf_version_expr *locals;
+ /* List of versions which this version depends upon. */
+ struct bfd_elf_version_deps *deps;
+ /* Index of the version name. This is used within BFD. */
+ unsigned int name_indx;
+ /* Whether this version tree was used. This is used within BFD. */
+ int used;
+};
+
+#endif
diff --git a/include/bout.h b/include/bout.h
new file mode 100644
index 00000000000..8fc28cc3d6d
--- /dev/null
+++ b/include/bout.h
@@ -0,0 +1,182 @@
+/*
+ * This file is a modified version of 'a.out.h'. It is to be used in all
+ * GNU tools modified to support the i80960 (or tools that operate on
+ * object files created by such tools).
+ *
+ * All i80960 development is done in a CROSS-DEVELOPMENT environment. I.e.,
+ * object code is generated on, and executed under the direction of a symbolic
+ * debugger running on, a host system. We do not want to be subject to the
+ * vagaries of which host it is or whether it supports COFF or a.out format,
+ * or anything else. We DO want to:
+ *
+ * o always generate the same format object files, regardless of host.
+ *
+ * o have an 'a.out' header that we can modify for our own purposes
+ * (the 80960 is typically an embedded processor and may require
+ * enhanced linker support that the normal a.out.h header can't
+ * accommodate).
+ *
+ * As for byte-ordering, the following rules apply:
+ *
+ * o Text and data that is actually downloaded to the target is always
+ * in i80960 (little-endian) order.
+ *
+ * o All other numbers (in the header, symbols, relocation directives)
+ * are in host byte-order: object files CANNOT be lifted from a
+ * little-end host and used on a big-endian (or vice versa) without
+ * modification.
+ * ==> THIS IS NO LONGER TRUE USING BFD. WE CAN GENERATE ANY BYTE ORDER
+ * FOR THE HEADER, AND READ ANY BYTE ORDER. PREFERENCE WOULD BE TO
+ * USE LITTLE-ENDIAN BYTE ORDER THROUGHOUT, REGARDLESS OF HOST. <==
+ *
+ * o The downloader ('comm960') takes care to generate a pseudo-header
+ * with correct (i80960) byte-ordering before shipping text and data
+ * off to the NINDY monitor in the target systems. Symbols and
+ * relocation info are never sent to the target.
+ */
+
+
+#define BMAGIC 0415
+/* We don't accept the following (see N_BADMAG macro).
+ * They're just here so GNU code will compile.
+ */
+#define OMAGIC 0407 /* old impure format */
+#define NMAGIC 0410 /* read-only text */
+#define ZMAGIC 0413 /* demand load format */
+
+/* FILE HEADER
+ * All 'lengths' are given as a number of bytes.
+ * All 'alignments' are for relinkable files only; an alignment of
+ * 'n' indicates the corresponding segment must begin at an
+ * address that is a multiple of (2**n).
+ */
+struct external_exec {
+ /* Standard stuff */
+ unsigned char e_info[4]; /* Identifies this as a b.out file */
+ unsigned char e_text[4]; /* Length of text */
+ unsigned char e_data[4]; /* Length of data */
+ unsigned char e_bss[4]; /* Length of uninitialized data area */
+ unsigned char e_syms[4]; /* Length of symbol table */
+ unsigned char e_entry[4]; /* Runtime start address */
+ unsigned char e_trsize[4]; /* Length of text relocation info */
+ unsigned char e_drsize[4]; /* Length of data relocation info */
+
+ /* Added for i960 */
+ unsigned char e_tload[4]; /* Text runtime load address */
+ unsigned char e_dload[4]; /* Data runtime load address */
+ unsigned char e_talign[1]; /* Alignment of text segment */
+ unsigned char e_dalign[1]; /* Alignment of data segment */
+ unsigned char e_balign[1]; /* Alignment of bss segment */
+ unsigned char e_relaxable[1]; /* Assembled with enough info to allow linker to relax */
+};
+
+#define EXEC_BYTES_SIZE (sizeof (struct external_exec))
+
+/* These macros use the a_xxx field names, since they operate on the exec
+ structure after it's been byte-swapped and realigned on the host machine. */
+#define N_BADMAG(x) (((x).a_info)!=BMAGIC)
+#define N_TXTOFF(x) EXEC_BYTES_SIZE
+#define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text )
+#define N_TROFF(x) ( N_DATOFF(x) + (x).a_data )
+#define N_TRELOFF N_TROFF
+#define N_DROFF(x) ( N_TROFF(x) + (x).a_trsize )
+#define N_DRELOFF N_DROFF
+#define N_SYMOFF(x) ( N_DROFF(x) + (x).a_drsize )
+#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms )
+#define N_DATADDR(x) ( (x).a_dload )
+
+/* Address of text segment in memory after it is loaded. */
+#if !defined (N_TXTADDR)
+#define N_TXTADDR(x) 0
+#endif
+
+/* A single entry in the symbol table
+ */
+struct nlist {
+ union {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx; /* Index into string table */
+ } n_un;
+ unsigned char n_type; /* See below */
+ char n_other; /* Used in i80960 support -- see below */
+ short n_desc;
+ unsigned long n_value;
+};
+
+
+/* Legal values of n_type
+ */
+#define N_UNDF 0 /* Undefined symbol */
+#define N_ABS 2 /* Absolute symbol */
+#define N_TEXT 4 /* Text symbol */
+#define N_DATA 6 /* Data symbol */
+#define N_BSS 8 /* BSS symbol */
+#define N_FN 31 /* Filename symbol */
+
+#define N_EXT 1 /* External symbol (OR'd in with one of above) */
+#define N_TYPE 036 /* Mask for all the type bits */
+#define N_STAB 0340 /* Mask for all bits used for SDB entries */
+
+/* MEANING OF 'n_other'
+ *
+ * If non-zero, the 'n_other' fields indicates either a leaf procedure or
+ * a system procedure, as follows:
+ *
+ * 1 <= n_other <= 32 :
+ * The symbol is the entry point to a system procedure.
+ * 'n_value' is the address of the entry, as for any other
+ * procedure. The system procedure number (which can be used in
+ * a 'calls' instruction) is (n_other-1). These entries come from
+ * '.sysproc' directives.
+ *
+ * n_other == N_CALLNAME
+ * the symbol is the 'call' entry point to a leaf procedure.
+ * The *next* symbol in the symbol table must be the corresponding
+ * 'bal' entry point to the procedure (see following). These
+ * entries come from '.leafproc' directives in which two different
+ * symbols are specified (the first one is represented here).
+ *
+ *
+ * n_other == N_BALNAME
+ * the symbol is the 'bal' entry point to a leaf procedure.
+ * These entries result from '.leafproc' directives in which only
+ * one symbol is specified, or in which the same symbol is
+ * specified twice.
+ *
+ * Note that an N_CALLNAME entry *must* have a corresponding N_BALNAME entry,
+ * but not every N_BALNAME entry must have an N_CALLNAME entry.
+ */
+#define N_CALLNAME ((char)-1)
+#define N_BALNAME ((char)-2)
+#define IS_CALLNAME(x) (N_CALLNAME == (x))
+#define IS_BALNAME(x) (N_BALNAME == (x))
+#define IS_OTHER(x) ((x)>0 && (x) <=32)
+
+#define b_out_relocation_info relocation_info
+struct relocation_info {
+ int r_address; /* File address of item to be relocated */
+ unsigned
+#define r_index r_symbolnum
+ r_symbolnum:24,/* Index of symbol on which relocation is based,
+ * if r_extern is set. Otherwise set to
+ * either N_TEXT, N_DATA, or N_BSS to
+ * indicate section on which relocation is
+ * based.
+ */
+ r_pcrel:1, /* 1 => relocate PC-relative; else absolute
+ * On i960, pc-relative implies 24-bit
+ * address, absolute implies 32-bit.
+ */
+ r_length:2, /* Number of bytes to relocate:
+ * 0 => 1 byte
+ * 1 => 2 bytes -- used for 13 bit pcrel
+ * 2 => 4 bytes
+ */
+ r_extern:1,
+ r_bsr:1, /* Something for the GNU NS32K assembler */
+ r_disp:1, /* Something for the GNU NS32K assembler */
+ r_callj:1, /* 1 if relocation target is an i960 'callj' */
+ r_relaxable:1; /* 1 if enough info is left to relax
+ the data */
+};
diff --git a/include/callback.h b/include/callback.h
new file mode 100644
index 00000000000..30752842ed9
--- /dev/null
+++ b/include/callback.h
@@ -0,0 +1,270 @@
+/* Remote target system call callback support.
+ Copyright 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This interface isn't intended to be specific to any particular kind
+ of remote (hardware, simulator, whatever). As such, support for it
+ (e.g. sim/common/callback.c) should *not* live in the simulator source
+ tree, nor should it live in the gdb source tree. */
+
+/* There are various ways to handle system calls:
+
+ 1) Have a simulator intercept the appropriate trap instruction and
+ directly perform the system call on behalf of the target program.
+ This is the typical way of handling system calls for embedded targets.
+ [Handling system calls for embedded targets isn't that much of an
+ oxymoron as running compiler testsuites make use of the capability.]
+
+ This method of system call handling is done when STATE_ENVIRONMENT
+ is ENVIRONMENT_USER.
+
+ 2) Have a simulator emulate the hardware as much as possible.
+ If the program running on the real hardware communicates with some sort
+ of target manager, one would want to be able to run this program on the
+ simulator as well.
+
+ This method of system call handling is done when STATE_ENVIRONMENT
+ is ENVIRONMENT_OPERATING.
+*/
+
+#ifndef CALLBACK_H
+#define CALLBACK_H
+
+/* ??? The reason why we check for va_start here should be documented. */
+
+#ifndef va_start
+#include <ansidecl.h>
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#endif
+
+/* Mapping of host/target values. */
+/* ??? For debugging purposes, one might want to add a string of the
+ name of the symbol. */
+
+typedef struct {
+ int host_val;
+ int target_val;
+} CB_TARGET_DEFS_MAP;
+
+#define MAX_CALLBACK_FDS 10
+
+/* Forward decl for stat/fstat. */
+struct stat;
+
+typedef struct host_callback_struct host_callback;
+
+struct host_callback_struct
+{
+ int (*close) PARAMS ((host_callback *,int));
+ int (*get_errno) PARAMS ((host_callback *));
+ int (*isatty) PARAMS ((host_callback *, int));
+ int (*lseek) PARAMS ((host_callback *, int, long , int));
+ int (*open) PARAMS ((host_callback *, const char*, int mode));
+ int (*read) PARAMS ((host_callback *,int, char *, int));
+ int (*read_stdin) PARAMS (( host_callback *, char *, int));
+ int (*rename) PARAMS ((host_callback *, const char *, const char *));
+ int (*system) PARAMS ((host_callback *, const char *));
+ long (*time) PARAMS ((host_callback *, long *));
+ int (*unlink) PARAMS ((host_callback *, const char *));
+ int (*write) PARAMS ((host_callback *,int, const char *, int));
+ int (*write_stdout) PARAMS ((host_callback *, const char *, int));
+ void (*flush_stdout) PARAMS ((host_callback *));
+ int (*write_stderr) PARAMS ((host_callback *, const char *, int));
+ void (*flush_stderr) PARAMS ((host_callback *));
+ int (*stat) PARAMS ((host_callback *, const char *, struct stat *));
+ int (*fstat) PARAMS ((host_callback *, int, struct stat *));
+
+ /* When present, call to the client to give it the oportunity to
+ poll any io devices for a request to quit (indicated by a nonzero
+ return value). */
+ int (*poll_quit) PARAMS ((host_callback *));
+
+ /* Used when the target has gone away, so we can close open
+ handles and free memory etc etc. */
+ int (*shutdown) PARAMS ((host_callback *));
+ int (*init) PARAMS ((host_callback *));
+
+ /* depreciated, use vprintf_filtered - Talk to the user on a console. */
+ void (*printf_filtered) PARAMS ((host_callback *, const char *, ...));
+
+ /* Talk to the user on a console. */
+ void (*vprintf_filtered) PARAMS ((host_callback *, const char *, va_list));
+
+ /* Same as vprintf_filtered but to stderr. */
+ void (*evprintf_filtered) PARAMS ((host_callback *, const char *, va_list));
+
+ /* Print an error message and "exit".
+ In the case of gdb "exiting" means doing a longjmp back to the main
+ command loop. */
+ void (*error) PARAMS ((host_callback *, const char *, ...));
+
+ int last_errno; /* host format */
+
+ int fdmap[MAX_CALLBACK_FDS];
+ char fdopen[MAX_CALLBACK_FDS];
+ char alwaysopen[MAX_CALLBACK_FDS];
+
+ /* System call numbers. */
+ CB_TARGET_DEFS_MAP *syscall_map;
+ /* Errno values. */
+ CB_TARGET_DEFS_MAP *errno_map;
+ /* Flags to the open system call. */
+ CB_TARGET_DEFS_MAP *open_map;
+ /* Signal numbers. */
+ CB_TARGET_DEFS_MAP *signal_map;
+ /* Layout of `stat' struct.
+ The format is a series of "name,length" pairs separated by colons.
+ Empty space is indicated with a `name' of "space".
+ All padding must be explicitly mentioned.
+ Lengths are in bytes. If this needs to be extended to bits,
+ use "name.bits".
+ Example: "st_dev,4:st_ino,4:st_mode,4:..." */
+ const char *stat_map;
+
+ /* Marker for those wanting to do sanity checks.
+ This should remain the last member of this struct to help catch
+ miscompilation errors. */
+#define HOST_CALLBACK_MAGIC 4705 /* teds constant */
+ int magic;
+};
+
+extern host_callback default_callback;
+
+/* Canonical versions of system call numbers.
+ It's not intended to willy-nilly throw every system call ever heard
+ of in here. Only include those that have an important use.
+ ??? One can certainly start a discussion over the ones that are currently
+ here, but that will always be true. */
+
+/* These are used by the ANSI C support of libc. */
+#define CB_SYS_exit 1
+#define CB_SYS_open 2
+#define CB_SYS_close 3
+#define CB_SYS_read 4
+#define CB_SYS_write 5
+#define CB_SYS_lseek 6
+#define CB_SYS_unlink 7
+#define CB_SYS_getpid 8
+#define CB_SYS_kill 9
+#define CB_SYS_fstat 10
+/*#define CB_SYS_sbrk 11 - not currently a system call, but reserved. */
+
+/* ARGV support. */
+#define CB_SYS_argvlen 12
+#define CB_SYS_argv 13
+
+/* These are extras added for one reason or another. */
+#define CB_SYS_chdir 14
+#define CB_SYS_stat 15
+#define CB_SYS_chmod 16
+#define CB_SYS_utime 17
+#define CB_SYS_time 18
+
+/* Struct use to pass and return information necessary to perform a
+ system call. */
+/* FIXME: Need to consider target word size. */
+
+typedef struct cb_syscall {
+ /* The target's value of what system call to perform. */
+ int func;
+ /* The arguments to the syscall. */
+ long arg1, arg2, arg3, arg4;
+
+ /* The result. */
+ long result;
+ /* Some system calls have two results. */
+ long result2;
+ /* The target's errno value, or 0 if success.
+ This is converted to the target's value with host_to_target_errno. */
+ int errcode;
+
+ /* Working space to be used by memory read/write callbacks. */
+ PTR p1;
+ PTR p2;
+ long x1,x2;
+
+ /* Callbacks for reading/writing memory (e.g. for read/write syscalls).
+ ??? long or unsigned long might be better to use for the `count'
+ argument here. We mimic sim_{read,write} for now. Be careful to
+ test any changes with -Wall -Werror, mixed signed comparisons
+ will get you. */
+ int (*read_mem) PARAMS ((host_callback * /*cb*/, struct cb_syscall * /*sc*/,
+ unsigned long /*taddr*/, char * /*buf*/,
+ int /*bytes*/));
+ int (*write_mem) PARAMS ((host_callback * /*cb*/, struct cb_syscall * /*sc*/,
+ unsigned long /*taddr*/, const char * /*buf*/,
+ int /*bytes*/));
+
+ /* For sanity checking, should be last entry. */
+ int magic;
+} CB_SYSCALL;
+
+/* Magic number sanity checker. */
+#define CB_SYSCALL_MAGIC 0x12344321
+
+/* Macro to initialize CB_SYSCALL. Called first, before filling in
+ any fields. */
+#define CB_SYSCALL_INIT(sc) \
+do { \
+ memset ((sc), 0, sizeof (*(sc))); \
+ (sc)->magic = CB_SYSCALL_MAGIC; \
+} while (0)
+
+/* Return codes for various interface routines. */
+
+typedef enum {
+ CB_RC_OK = 0,
+ /* generic error */
+ CB_RC_ERR,
+ /* either file not found or no read access */
+ CB_RC_ACCESS,
+ CB_RC_NO_MEM
+} CB_RC;
+
+/* Read in target values for system call numbers, errno values, signals. */
+CB_RC cb_read_target_syscall_maps PARAMS ((host_callback *, const char *));
+
+/* Translate target to host syscall function numbers. */
+int cb_target_to_host_syscall PARAMS ((host_callback *, int));
+
+/* Translate host to target errno value. */
+int cb_host_to_target_errno PARAMS ((host_callback *, int));
+
+/* Translate target to host open flags. */
+int cb_target_to_host_open PARAMS ((host_callback *, int));
+
+/* Translate target signal number to host. */
+int cb_target_to_host_signal PARAMS ((host_callback *, int));
+
+/* Translate host signal number to target. */
+int cb_host_to_target_signal PARAMS ((host_callback *, int));
+
+/* Translate host stat struct to target.
+ If stat struct ptr is NULL, just compute target stat struct size.
+ Result is size of target stat struct or 0 if error. */
+int cb_host_to_target_stat PARAMS ((host_callback *, const struct stat *, PTR));
+
+/* Perform a system call. */
+CB_RC cb_syscall PARAMS ((host_callback *, CB_SYSCALL *));
+
+#endif
diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog
new file mode 100644
index 00000000000..8ad6e0cec4a
--- /dev/null
+++ b/include/coff/ChangeLog
@@ -0,0 +1,793 @@
+1999-04-21 Nick Clifton <nickc@cygnus.com>
+
+ * mcore.h (GET_LINENO_LNNO): New macro.
+ (PUT_LINENO_LNNO): New macro.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * mcore.h: New header file. Defines for Motorolla's MCore
+ processor.
+
+Sun Dec 6 21:36:37 1998 Mark Elbrecht <snowball3@usa.net>
+
+ * internal.h (C_WEAKEXT): Define.
+
+Wed Jan 27 13:35:35 1999 Stan Cox <scox@cygnus.com>
+
+ * coff/arm.h (F_PIC_INT, F_ARM_2, F_ARM_3, F_ARM_4, F_APCS26):
+ Changed values to avoid clashing with IMAGE_FILE_* coff header
+ flag values.
+
+Wed Apr 1 16:06:15 1998 Nick Clifton <nickc@cygnus.com>
+
+ * internal.h: Document numbers associated with Thumb symbol
+ types.
+
+Fri Mar 27 17:16:57 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (ISPTR, ISFCN, ISARY): Add casts to unsigned long.
+
+Mon Feb 2 17:10:38 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ * tic30.h: New file.
+
+Fri Dec 12 11:49:07 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (R_MPPCR15W): New relocation type, for 15 bit PC relative
+ offsets.
+
+Tue Dec 2 10:21:40 1997 Nick Clifton <nickc@cygnus.com>
+
+ * arm.h (COFFARM): New define.
+
+Sat Nov 22 15:10:14 1997 Nick Clifton <nickc@cygnus.com>
+
+ * internal.h (C_THUMBEXTFUNC, C_THUMBSTATFUNC): Constants to
+ define static and external functions.
+
+ * arm.h: Add bits to support PIC and APCS-FLOAT type binaries,
+ when implemented.
+
+Fri Oct 3 14:25:17 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (R_PPL16B): Make constant uppercase for consistency.
+
+Tue Jul 22 18:18:58 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * go32exe.h: New file.
+
+Tue Jul 8 12:23:55 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_TARGET_ID): Add define.
+ * internal.h (struct internal_filehdr): Add f_target_id field.
+
+Tue Jun 3 16:44:18 1997 Nick Clifton <nickc@cygnus.com>
+
+ * internal.h: Add storage classes for Thumb symbols
+
+Mon May 26 14:07:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * tic80.h (R_PPL16B): Correct value.
+
+Sat May 3 08:24:59 1997 Fred Fish <fnf@cygnus.com>
+
+ * internal.h (C_UEXT, C_STATLAB, C_EXTLAB, C_SYSTEM):
+ New storage classes for TIc80.
+
+Fri Apr 18 11:52:55 1997 Niklas Hallqvist <niklas@appli.se>
+
+ * alpha.h (ALPHA_ECOFF_BADMAG): Recognize *BSD/alpha magic too.
+ (ALPHA_R_LITERALSLEAZY): Define.
+ * ecoff.h (ALPHA_MAGIC_BSD): Define.
+
+Wed Jan 29 11:31:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i960.h (R_IPR13, R_ALIGN): Define.
+
+Mon Jan 27 13:34:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (R_IPRMED, R_OPTCALL, R_OPTCALLX): Move definitions
+ from here...
+ * i960.h (R_IPRMED, R_OPTCALL, R_OPTCALLX): ...to here.
+
+Wed Jan 22 20:10:47 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80MAGIC): Renamed to TIC80_AOUTHDR_MAGIC.
+
+Fri Dec 27 22:05:45 1996 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h: New file for TIc80 support.
+
+Thu Dec 19 16:18:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * arm.h (_LIT): Define.
+
+Fri Jun 28 12:54:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * pe.h (FILHSZ): Define.
+
+Wed Jun 26 16:24:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * All files: Define FILHSZ, AOUTSZ, AOUTHDRSZ, SCNHSZ, SYMESZ,
+ AUXESZ, LINESZ, RELSZ as numeric constants rather than uses of
+ sizeof. Define AOUTHDRSZ in all files.
+ * pe.h (AOUTSZ): Define by adding to AOUTHDRSZ.
+
+Fri Jun 21 11:17:46 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha.h: Add declarations for relocation types added for Alpha
+ OSF/1 3.0.
+
+Tue Jun 18 16:04:29 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * h8300.h (H8300SMAGIC): Define.
+ (H8300SBADMAG): Define.
+
+Mon Jun 10 11:53:28 1996 Jeffrey A Law (law@cygnus.com)
+
+ * internal.h (R_BCC_INV, R_JMP_DEL): New relocations for
+ relaxing in the H8/300 series.
+
+Thu May 16 15:49:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sh.h (R_SH_CODE, R_SH_DATA, R_SH_LABEL): Define.
+
+Tue May 7 00:36:39 1996 Jeffrey A Law (law@cygnus.com)
+
+ * internal.h (R_JMPL2): Renamed from R_JMPL_B8 to be
+ consistent with other similar relocs.
+
+ * internal.h (H8/300 specific relocs): Add comments better
+ explaining what each reloc is used for.
+ (R_MOV16B1, R_MOV16B2): Renamed from R_MOVB1 and R_MOVB2.
+ (R_MOV24B1, R_MOV24B2): Renamed from R_MOVLB1 and R_MOVLB2.
+ (R_MOVL1, R_MOVL2): New relocs.
+
+Fri May 3 13:01:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * internal.h (R_PCRWORD_B): Define for the h8300 relaxing
+ linker.
+
+Wed May 1 19:21:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (SCNNMLEN): Define.
+ (struct internal_scnhdr): Use SCNNMLEN for s_name field.
+
+Fri Mar 29 13:41:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * pe.h: Define IMAGE_COMDAT codes.
+
+Wed Mar 27 17:29:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * arm.h (union external_auxent): Add x_checksum, x_associated, and
+ x_comdat fields to x_scn struct.
+ * i386.h (union external_auxent): Likewise.
+ * powerpc.h (union external_auxent): Likewise.
+ * internal.h (union internal_auxent): Likewise.
+
+Thu Mar 21 16:25:57 1996 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * ecoff.h (struct ecoff_find_line): Add caching fields.
+
+Thu Mar 14 15:22:44 1996 Jeffrey A Law (law@cygnus.com)
+
+ * internal.h (R_MEM_INDIRECT): New reloc for the h8300.
+
+Fri Feb 9 10:44:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * aux-coff.h: Rename from aux.h, to avoid problems on hapless DOS
+ systems which think that aux is a com port.
+
+Mon Feb 5 18:35:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i960.h (F_I960HX): Define.
+
+Wed Jan 31 13:11:54 1996 Richard Henderson <rth@tamu.edu>
+
+ * aux.h: New file.
+ * internal.h, m68k.h: Protect against multiple inclusion.
+
+Wed Nov 22 13:48:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.h (_RCONST, STYP_RCONST, RELOC_SECTION_RCONST): Define.
+ (NUM_RELOC_SECTIONS): Update.
+ * symconst.h (scRConst): Define.
+
+Tue Nov 14 18:54:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (C_NT_WEAK): Define.
+
+Thu Nov 9 14:08:30 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * rs6000.h (STYP_OVRFLO): Define.
+
+Tue Nov 7 14:38:45 1995 Kim Knuttila <krk@cygnus.com>
+
+ * coff/powerpc.h (IMAGE_NT_OPTIONAL_HDR_MAGIC): Added define.
+ * coff/pe.h: Added defines for file level flags
+
+Mon Nov 6 17:28:01 1995 Harry Dolan <dolan@ssd.intel.com>
+
+ * i860.h: New file, based on i386.h.
+
+Wed Nov 1 15:25:18 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * m68k.h (PAGEMAGICEXECSWAPPED): Define.
+ (PAGEMAGICPEXECSWAPPED): Define.
+ (PAGEMAGICPEXECTSHLIB): Define.
+ (PAGEMAGICPEXECPAGED): Define.
+ (_COMMENT): DEFINE.
+ * m88k.h (_COMMENT): Define.
+
+Wed Oct 18 18:36:19 1995 Geoffrey Noer <noer@cygnus.com>
+
+ * sym.h: #if 0'd out runtime_pdr struct because it chokes
+ Visual C++ and there aren't any references to it elsewhere in gdb.
+
+Mon Oct 16 11:12:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * rs6000.h (SMALL_AOUTSZ): Define.
+
+ * internal.h (XMC_TD): Define.
+
+Tue Oct 10 18:41:03 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (struct internal_aouthdr): Add o_cputype field.
+ * rs6000.h (AOUTHDR): Rename o_resv1 to o_cputype.
+
+Mon Oct 9 14:45:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * rs6000.h (AOUTHDR): Add o_maxdata field. Add comments.
+ (_PAD, _LOADER): Define.
+ (STYP_LOADER): Define.
+ * internal.h (struct internal_aouthdr): Add o_maxdata field.
+
+Thu Oct 5 10:02:57 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.h: Define section name macros and STYP macros for various
+ Alpha sections: .got, .hash, .dynsym, .dynstr, .rel.dyn, .conflic,
+ .comment, .liblist, .dynamic.
+
+Wed Oct 4 10:56:35 1995 Kim Knuttila <krk@cygnus.com>
+
+ * pe.h: Moved DOSMAGIC and NT_SIGNATURE defines here
+ * powerpc.h: removed DOSMAGIC, NT_SIGNATURE, and DEFAULT_* defines
+ Also removed other unused defines (various MAGIC ones)
+ * i386.h: removed DOSMAGIC, NT_SIGNATURE, and DEFAULT_* defines
+ * arm.h: removed DOSMAGIC, NT_SIGNATURE, and DEFAULT_* defines
+ * apollo.h: removed unused DEFAULT_* defines
+ * alpha.h: removed unused DEFAULT_* defines
+ * h8500.h: removed unused DEFAULT_* defines
+ * h8300.h: removed unused DEFAULT_* defines
+ * i960.h: removed unused DEFAULT_* defines
+ * m88k.h: removed unused DEFAULT_* defines
+ * we32k.h: removed unused DEFAULT_* defines
+ * rs6000.h: removed unused DEFAULT_* defines
+ * mips.h: removed unused DEFAULT_* defines
+ * m68k.h: removed unused DEFAULT_* defines
+ * z8k.h: removed unused DEFAULT_* defines
+ * w65.h: removed unused DEFAULT_* defines
+ * sparc.h: removed unused DEFAULT_* defines
+ * sh.h: removed unused DEFAULT_* defines
+
+Fri Sep 29 08:40:08 1995 Kim Knuttila <krk@cygnus.com>
+
+ * powerpc.h: Reformatted to GNU coding conventions.
+
+Wed Sep 27 06:50:50 1995 Kim Knuttila <krk@nellie>
+
+ * pe.h: added defines for more section characteristics
+ * powerpc.h (new file): base coff definitions for ppc PE
+
+Tue Sep 12 12:08:20 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (struct internal_syment): Change n_numaux field from
+ char to unsigned char.
+
+Fri Sep 1 15:39:36 1995 Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>
+
+ * mips.h (struct rpdr_ext): Define.
+
+Thu Aug 31 16:51:50 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * internal.h (internal_aouthdr, internal_filehdr):
+ don't indirect the pe stuff.
+
+Tue Aug 29 14:16:07 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * i386.h (NT_DEF_RESERVE, NT_DEF_COMMIT): Make the same
+ as 'the other' compiler.
+ * internal.h (NT_IMAGE_BASE): Deleted.
+ (NT_EXE_IMAGE_BASE, NT_DLL_IMAGE_BASE): New.
+ (PE_DEF_SECTION_ALIGNMENT, PE_DEF_FILE_ALIGNMENT): New.
+ (R_IMAGEBASE): New.
+
+Mon Aug 21 18:12:19 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * internal.h: (internal_filehdr): Moved PE stuff into
+ internal_extra_pe_filehdr.
+ (internal_aouthdr): Moved PE stuff into
+ interanl_extra_pe_aouthdr.
+
+Mon Jul 24 14:05:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h: Move R_SH_* relocs from here...
+ * sh.h: ...to here.
+ (R_SH_SWITCH16, R_SH_SWITCH32): Define.
+ (R_SH_USES, R_SH_COUNT, R_SH_ALIGN): Define.
+
+Thu Jun 29 00:04:25 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * internal.h (NT_DEF_RESERVE, NT_DEF_COMMIT): Increase a lot.
+
+Tue May 16 15:08:20 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * internal.h (NT_subsystem, NT_stack_heap): Delete
+
+Tue May 16 15:08:20 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * internal.h (NT_subsystem, NT_stack_heap): Now extern.
+
+Tue Feb 14 17:59:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.h (struct ecoff_fdrtab_entry): Define.
+ (struct ecoff_find_line): Define.
+
+Sat Feb 4 14:38:03 1995 David Mosberger-Tang <davidm@piston.cs.arizona.edu>
+
+ * sym.h (struct pdr): field "prof" added.
+
+ * alpha.h (PDR_BITS1_PROF_*): added, macros for PDR_BITS*_RESERVED_*
+ updated accordingly.
+
+Sun Jan 15 18:38:33 1995 Steve Chamberlain <sac@splat>
+
+ * w65.h: New file.
+
+Wed Nov 23 22:43:38 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * sh.h (SH_ARCH_MAGIC_BIG, SH_ARCH_MAGIC_LITTLE): New.
+ (SHBADMAG): Changed to suit.
+
+Tue Jul 26 17:46:08 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i960.h (F_I960JX): New macro.
+
+Wed Jul 6 00:48:57 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha.h: Add definitions for alpha file header flags, encoding
+ the object type of the file.
+
+Mon Jun 20 13:47:01 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ecoff.h (ecoff_swap_tir_in): Remove declaration.
+ (ecoff_swap_tir_out): Likewise.
+ (ecoff_swap_rndx_in, ecoff_swap_rndx_out): Likewise.
+ (struct ecoff_debug_swap): Add new fields: swap_tir_in,
+ swap_rndx_in, swap_tir_out, swap_rndx_out, read_debug_info.
+
+Sun Jun 12 03:51:52 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * symconst.h: Pick up SGI define for stIndirect.
+
+Fri Apr 22 13:05:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (REGINFO): Don't define.
+ (struct ecoff_reginfo): Don't define.
+
+ * sh.h (SH_ARCH_MAGIC): Rename from SHMAGIC. SHMAGIC is used by
+ several targets to mean a shared library.
+ (SHBADMAG): Corresponding change.
+
+Thu Apr 14 13:00:53 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (RELOC_BITS3_TYPE_BIG): Changed from 0x1e to 0x3e.
+ (RELOC_BITS3_TYPEHI_LITTLE): Define.
+ (RELOC_BITS3_TYPEHI_SH_LITTLE): Define.
+ (MIPS_R_PCREL16): Change value from 8 to 12 to match Irix 4.
+ (MIPS_R_RELHI): Define.
+ (MIPS_R_RELLO): Define.
+ (MIPS_R_SWITCH): Change value from 9 to 22.
+
+Thu Apr 7 14:19:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (MIPS_R_SWITCH): Define.
+
+Thu Mar 31 19:28:33 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * internal.h (internal_aouthdr): Added comments for Apollo fields.
+
+Thu Mar 31 16:28:02 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (STYP_ECOFF_LIB): Define as used on Irix 4.
+
+Fri Mar 25 17:16:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (struct ecoff_debug_info): Add adjust field.
+ (struct ecoff_value_adjust): Define.
+
+Tue Mar 22 13:22:47 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (MIPS_R_PCREL16): Define.
+
+Sat Feb 26 10:26:38 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.h: Add casts to avoid warnings from SVR4 cc.
+
+Mon Feb 21 09:48:46 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * sym.h (struct runtime_pdr): Make field adr bfd_vma, not unsigned
+ long.
+ (SYMR): Make field value bfd_vma, not long.
+
+Fri Feb 4 23:35:53 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * rs6000.h (STYP_DEBUG): Define.
+
+Wed Feb 2 14:31:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * internal.h (union internal_auxent): Change x_csect.x_scnlen into
+ a union of a long and a pointer to a symbol. XCOFF sometimes uses
+ this field as a symbol index.
+
+Mon Jan 10 23:54:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (ecoff_debug_info): Remove fields line_end,
+ external_dnr_end, external_pdr_end, external_sym_end,
+ external_opt_end, external_aux_end, ss_end, external_fdr_end.
+ Replace ifdbase with ifdmap.
+
+Wed Jan 5 17:05:36 1994 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * ecoff.h (STYP_EXTENDESC, STYP_COMMENT, STYP_XDATA, STYP_PDATA):
+ Define.
+
+Wed Jan 5 16:58:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (NUM_RELOC_SECTIONS): Define.
+
+Tue Dec 21 09:24:56 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * sparc.h (struct external_reloc): Rename field r_addend to
+ r_offset.
+
+Sat Dec 11 16:12:32 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h (R_DISP7, R_SH_IMM16): New reloc types.
+
+Tue Nov 23 14:23:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (struct ecoff_debug_swap): Added *_end fields for all
+ the symbolic information pointers.
+
+ * sym.h: Named the EXTR structure ecoff_extr.
+
+Fri Nov 19 08:21:18 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * sparc.h (RELSZ): Use correct size.
+
+Wed Nov 17 17:18:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (struct ecoff_debug_info): Define.
+
+Tue Nov 2 17:56:57 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (struct ecoff_debug_swap): Define.
+
+Thu Oct 28 17:07:50 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * i386.h (I386LYNXMAGIC): Rename to LYNXCOFFMAGIC.
+ * m68k.h (LYNXCOFFMAGIC): Define.
+ * sparc.h: New file.
+
+Tue Oct 19 15:34:50 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * alpha.h (external_aouthdr): Split four byte padding field into
+ two byte bldrev field and two byte padding field.
+
+ * ecoff.h (_LITA, _PDATA, _XDATA, STYP_LITA): Defined.
+
+Wed Oct 13 15:52:34 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ Sun Oct 10 17:27:10 1993 Troy Rollo (troy@cbme.unsw.edu.au)
+
+ * coff/internal.h: Added o_sri, o_inlib and o_vid for Apollos
+ as well as R_DIR16.
+
+ * coff/apollo.h: New file
+
+Mon Oct 11 17:16:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (REGINFO, struct ecoff_reginfo): Define.
+
+Tue Oct 5 10:52:53 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * rs6000.h: Change non-ASCII characters in comment to octal
+ escapes.
+
+Tue Sep 28 03:27:04 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * ecoff.h (_FINI, STYP_ECOFF_FINI): Add to support .fini section.
+
+Fri Sep 24 11:53:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (BADMAG): Recognize MIPS_MAGIC_LITTLE3 and MIPS_MAGIC_BIG3.
+ * ecoff.h: Define MIPS_MAGIC_LITTLE3 and MIPS_MAGIC_BIG3.
+
+Thu Sep 23 21:07:14 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * mips.h (BADMAG): Recognize MIPS_MAGIC_LITTLE2 and MIPS_MAGIC_BIG2.
+ * ecoff.h: Define MIPS_MAGIC_LITTLE2 and MIPS_MAGIC_BIG2.
+
+Thu Sep 16 20:27:21 1993 Jim Kingdon (kingdon@cirdan.cygnus.com)
+
+ * sym.h, symconst.h: Add comment stating these files are not part
+ of GDB, GAS, etc. In 1991, when we asked rms whether we could
+ include these files in GDB (although they are copyrighted by
+ someone besides the FSF), he said it was OK if they were not
+ considered part of GDB.
+
+Fri Sep 10 17:40:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (AUX_PUT_ANY): Cast val argument to bfd_vma.
+
+ * alpha.c (external_aouthdr): Need four bytes of padding between
+ vstamp and tsize.
+
+Tue Sep 7 14:20:43 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff.h (AUX_GET_ANY, AUX_PUT_ANY): Changed to reflect further
+ change in bfd swapping routine names.
+
+Tue Sep 7 10:15:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * ecoff.h (AUX_GET_ANY): Change name of _do_getb32 to reflect bfd
+ changes.
+
+Fri Aug 13 14:30:32 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff.h (RELOC_SECTION_NONE): Define.
+
+Thu Aug 12 11:24:42 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * alpha.h (struct external_reloc): Add r_symndx field.
+ (RELSZ): Correct.
+ (RELOC_BITS*): Correct.
+ (ALPHA_R_*): Define.
+ * ecoff.h (RELOC_SECTION_{XDATA,PDATA,FINI,LITA,ABS}): Define.
+ (r_extern): Undefine.
+ * internal.h (struct internal_reloc): Make r_vaddr bfd_vma rather
+ than long. Add r_extern field.
+
+ * alpha.h (PDR_BITS*): Define.
+ * sym.h (PDR): Give correct names to new fields.
+
+ * ecoff.h: Moved MIPS reloc definitions from here...
+ * mips.h: to here.
+
+Tue Aug 3 11:17:53 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * alpha.h: Corrected external symbolic debugging structures to
+ match actual usage.
+ * internal.h (internal_filehdr, internal_aouthdr,
+ internal_scnhdr): Changed type of some fields to bfd_vma so they
+ can hold 64 bits.
+ * sym.h (HDRR, FDR, PDR, EXTR): Likewise.
+ (PDR): Added new fields found on Alpha.
+ * symconst.h (magicSym2): Define; new value found on Alpha.
+
+ * ecoff.h: New file.
+ * alpha.h, mips.h: Moved common information into ecoff.h. Moved
+ external structure definitions in from ecoff-ext.h.
+ * ecoff-ext.h: Removed; information now in alpha.h and mips.h.
+
+Sun Jul 18 21:43:59 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * i386.h: Recognize I386PTXMAGIC.
+
+Fri Jul 16 09:54:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h (MIPS_AOUT_{OZ}MAGIC): Renamed from {OZ}MAGIC.
+
+Thu Jul 15 12:23:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m88k.h (union external_auxent): Move x_fcn back inside x_fcnary.
+ ({GET,PUT}_FCN_{LNNOPTR,ENDNDX}): Adjust accordingly.
+
+Sun Jul 11 18:00:18 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m68k.h: Define MC68KBCSMAGIC.
+
+Thu Jun 10 11:46:28 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h (_INIT, STYP_MIPS_INIT): Define (used on Irix4).
+ (STYP_OTHER_LOAD): Define as STYP_MIPS_INIT.
+
+Wed Jun 9 15:09:09 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h (OMAGIC): Define.
+
+Mon Apr 26 18:04:47 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h, sh.h: Support for SH.
+
+Sat Apr 24 21:34:59 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * a29k.h: Define _LIT.
+
+Fri Apr 23 18:41:23 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * alpha.h: New file.
+
+Thu Apr 8 12:36:34 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * internal.h (C_SHADOW, C_VERSION): Copied in from m88k.h.
+ * m88k.h, i386.h, we32k.h: Don't define all the storage classes;
+ they're already in internal.h.
+
+Wed Apr 7 11:51:24 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * internal.h: Change n_sclass to unsigned char.
+ Change C_EFCN to 0xff, change RS/6000 dbx symbols
+ to no longer be signed.
+
+Fri Mar 19 14:52:56 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h: Add H8/500 reloc types.
+
+Wed Mar 17 09:46:03 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff-ext.h (AUX_PUT_ANY): Don't use void values in branches of
+ conditional expression.
+
+Thu Mar 4 14:12:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ecoff-ext.h (AUX_GET_*): Rewrote to use new macro AUX_GET_ANY.
+ (AUX_PUT_*): New macros corresponding to the AUX_GET macros.
+ (ecoff_swap_tir_out): Added prototype.
+
+ * mips.h (N_BTMASK, N_TMASK, N_BTSHFT, N_TSHIFT): Define; these
+ are needed to interpret gcc debugging output.
+
+Tue Feb 9 07:43:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * we32k.h (BTYPE, ISPTR, ISFCN, ISARY, DECREF): Removed
+ more definitions duplicated in internal.h.
+
+Wed Feb 3 09:18:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h (RELOC_BITS3_TYPE_*): Correct for big endian machines.
+
+Mon Jan 25 11:35:51 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * internal.h (internal_aouthdr): Added additional fields used only
+ by MIPS ECOFF.
+
+Thu Jan 21 10:28:38 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h (AOUTHDR): Added additional fields used by ECOFF.
+
+Tue Jan 19 12:21:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i386.h, we32k.h (N_*, T_*, DT_*): Removed still more definitions
+ duplicated in internal.h.
+
+ * mips.h (RELOC_SECTION_*, ECOFF_R_*): Defined constants for ECOFF
+ relocs.
+
+Fri Jan 15 18:17:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff-ext.h: Added prototypes for new ECOFF swapping functions.
+ (opt_ext): New structure.
+ * mips.h (ZMAGIC): Defined to be 0413.
+ (_LIB): Defined to be ".lib"
+ (external_reloc): MIPS ECOFF relocs are only 8 bytes. Added
+ macros to aid in swapping.
+
+Fri Jan 8 16:19:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ecoff-ext.h: Added prototypes for ECOFF swapping functions.
+ * internal.h (internal_scnhdr): Always provide s_align field, not
+ just on i960.
+ (internal_reloc): Always provide r_size field, not just on
+ RS/6000.
+ * mips.h (_RDATA, _SDATA, _SBSS, _LIT4, _LIT8, STYP_RDATA,
+ STYP_SDATA, STYP_SBSS, STYP_LIT4, STYP_LIT8): Defined.
+ (CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB, MIPS_UNMARK_STAB,
+ STABS_SYMBOL): Moved in from gdb/mipsread.c.
+
+Wed Jan 6 14:01:46 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i386.h, we32k.h: removed STYP_* defines, since they duplicated
+ those in internal.h.
+
+Tue Dec 29 15:40:07 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * i386.h: define I386AIXMAGIC for Danbury AIX PS/2 compiler.
+
+Sat Dec 12 16:07:57 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * i386.h: don't define BTYPE, ISPTR, ISFCN, ISARY, DECREF: they
+ are defined in internal.h.
+
+Thu Nov 12 09:52:01 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h: (internal_reloc): r_offset is now a long.
+ * z8k.h: slight comment enhancement
+
+Wed Sep 30 07:46:08 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h: changed z8k reloc types
+
+Fri Aug 28 10:16:31 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ * we32k.h: new file
+
+Thu Aug 27 13:00:01 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ * symconst.h: comment out cruft at the end of #endif
+
+Tue Aug 25 15:06:49 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h: added #define for STYP_LIT, removed from a29k and
+ h8300.
+
+ * z8k.h: added z8000 support
+
+Thu Jul 16 16:32:00 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * internal.h: added R_RELLONG_NEG reloc type
+
+Fri Jun 12 20:11:04 1992 John Gilmore (gnu at cygnus.com)
+
+ * symconst.h: Fix unterminated comment.
+
+Wed Jun 10 07:57:49 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * i386.h: a.out magic numbers from
+ mohring@informatik.tu-muenchen.de
+
+Mon Jun 8 20:13:33 1992 John Gilmore (gnu at cygnus.com)
+
+ * ecoff-ext.h, mips.h: Use unsigned chars everywhere.
+ (Suggested by Antti Miettinen.)
+
+Tue Apr 14 15:18:44 1992 John Gilmore (gnu at cygnus.com)
+
+ * sym.h: Add comments.
+ * symconst.h: Merge with Fred's changes.
+
+Tue Apr 14 14:30:05 1992 Fred Fish (fnf@cygnus.com)
+
+ * symconst.h: Pick up SGI defines for stStruct, stUnion, stEnum,
+ langCplusplus, and langCplusplusV2.
+
+Thu Apr 2 19:47:43 1992 John Gilmore (gnu at cygnus.com)
+
+ * sym.h, symconst.h: MIPS has provided redistributable versions
+ of these files. Thanks!
+ * ecoff-ext.h: Add weakext bit to match new sym.h.
+
+Fri Mar 6 00:10:46 1992 John Gilmore (gnu at cygnus.com)
+
+ * ecoff-ext.h: Add relative file descriptors.
+
+Thu Feb 27 11:53:04 1992 John Gilmore (gnu at cygnus.com)
+
+ * ecoff-ext.h: New file for external (in-file) form of ecoff
+ symbol structures.
+
+Thu Feb 6 11:33:32 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * h8300.h: made the external_lineno l_lnno field 4 bytes wide.
+ andded GET/PUT_LINENO_LNNO macros
+
+Sat Nov 30 20:38:35 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * ChangeLog, a29k.h, h8300.h, i386.h, i960.h, internal.h, m68k.h,
+ m88k.h, mips.h, rs6000.h: move from above coff-<foo>.h
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/include/coff/a29k.h b/include/coff/a29k.h
new file mode 100644
index 00000000000..8c3a646ca23
--- /dev/null
+++ b/include/coff/a29k.h
@@ -0,0 +1,305 @@
+/* COFF spec for AMD 290*0
+ Contributed by David Wood @ New York University.
+ */
+
+#ifndef AMD
+# define AMD
+#endif
+
+/****************************************************************/
+
+/*
+** File Header and related definitions
+*/
+
+struct external_filehdr
+{
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+/*
+** Magic numbers for Am29000
+** (AT&T will assign the "real" magic number)
+*/
+
+#define SIPFBOMAGIC 0572 /* Am29000 (Byte 0 is MSB) */
+#define SIPRBOMAGIC 0573 /* Am29000 (Byte 0 is LSB) */
+
+
+#define A29K_MAGIC_BIG SIPFBOMAGIC
+#define A29K_MAGIC_LITTLE SIPRBOMAGIC
+#define A29KBADMAG(x) (((x).f_magic!=A29K_MAGIC_BIG) && \
+ ((x).f_magic!=A29K_MAGIC_LITTLE))
+
+#define OMAGIC A29K_MAGIC_BIG
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+/*
+** File header flags currently known to us.
+**
+** Am29000 will use the F_AR32WR and F_AR32W flags to indicate
+** the byte ordering in the file.
+*/
+
+/*--------------------------------------------------------------*/
+
+/*
+** Optional (a.out) header
+*/
+
+typedef struct external_aouthdr
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+} AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+/* aouthdr magic numbers */
+#define NMAGIC 0410 /* separate i/d executable */
+#define SHMAGIC 0406 /* NYU/Ultra3 shared data executable
+ (writable text) */
+
+#define _ETEXT "_etext"
+
+/*--------------------------------------------------------------*/
+
+/*
+** Section header and related definitions
+*/
+
+struct external_scnhdr
+{
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _LIT ".lit"
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+/*
+** Section types - with additional section type for global
+** registers which will be relocatable for the Am29000.
+**
+** In instances where it is necessary for a linker to produce an
+** output file which contains text or data not based at virtual
+** address 0, e.g. for a ROM, then the linker should accept
+** address base information as command input and use PAD sections
+** to skip over unused addresses.
+*/
+
+#define STYP_BSSREG 0x1200 /* Global register area (like STYP_INFO) */
+#define STYP_ENVIR 0x2200 /* Environment (like STYP_INFO) */
+#define STYP_ABS 0x4000 /* Absolute (allocated, not reloc, loaded) */
+
+/*--------------------------------------------------------------*/
+
+/*
+** Relocation information declaration and related definitions
+*/
+
+struct external_reloc {
+ char r_vaddr[4]; /* (virtual) address of reference */
+ char r_symndx[4]; /* index into symbol table */
+ char r_type[2]; /* relocation type */
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 10 /* sizeof (RELOC) */
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+/*
+** Relocation types for the Am29000
+*/
+
+#define R_ABS 0 /* reference is absolute */
+
+#define R_IREL 030 /* instruction relative (jmp/call) */
+#define R_IABS 031 /* instruction absolute (jmp/call) */
+#define R_ILOHALF 032 /* instruction low half (const) */
+#define R_IHIHALF 033 /* instruction high half (consth) part 1 */
+#define R_IHCONST 034 /* instruction high half (consth) part 2 */
+ /* constant offset of R_IHIHALF relocation */
+#define R_BYTE 035 /* relocatable byte value */
+#define R_HWORD 036 /* relocatable halfword value */
+#define R_WORD 037 /* relocatable word value */
+
+#define R_IGLBLRC 040 /* instruction global register RC */
+#define R_IGLBLRA 041 /* instruction global register RA */
+#define R_IGLBLRB 042 /* instruction global register RB */
+
+/*
+NOTE:
+All the "I" forms refer to 29000 instruction formats. The linker is
+expected to know how the numeric information is split and/or aligned
+within the instruction word(s). R_BYTE works for instructions, too.
+
+If the parameter to a CONSTH instruction is a relocatable type, two
+relocation records are written. The first has an r_type of R_IHIHALF
+(33 octal) and a normal r_vaddr and r_symndx. The second relocation
+record has an r_type of R_IHCONST (34 octal), a normal r_vaddr (which
+is redundant), and an r_symndx containing the 32-bit constant offset
+to the relocation instead of the actual symbol table index. This
+second record is always written, even if the constant offset is zero.
+The constant fields of the instruction are set to zero.
+*/
+
+/*--------------------------------------------------------------*/
+
+/*
+** Line number entry declaration and related definitions
+*/
+
+struct external_lineno
+{
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+#define LINENO struct external_lineno
+#define LINESZ 6 /* sizeof (LINENO) */
+
+/*--------------------------------------------------------------*/
+
+/*
+** Symbol entry declaration and related definitions
+*/
+
+#define E_SYMNMLEN 8 /* Number of characters in a symbol name */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+/*
+** Storage class definitions - new classes for global registers.
+*/
+
+#define C_GLBLREG 19 /* global register */
+#define C_EXTREG 20 /* external global register */
+#define C_DEFREG 21 /* ext. def. of global register */
+
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+/*
+** Derived symbol mask/shifts.
+*/
+
+#define N_BTMASK (0xf)
+#define N_BTSHFT (4)
+#define N_TMASK (0x30)
+#define N_TSHIFT (2)
+
+/*--------------------------------------------------------------*/
+
+/*
+** Auxiliary symbol table entry declaration and related
+** definitions.
+*/
+
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+};
+
+#define AUXENT union external_auxent
+#define AUXESZ 18
diff --git a/include/coff/alpha.h b/include/coff/alpha.h
new file mode 100644
index 00000000000..076cbcbd980
--- /dev/null
+++ b/include/coff/alpha.h
@@ -0,0 +1,362 @@
+/* ECOFF support on Alpha machines.
+ coff/ecoff.h must be included before this file. */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ unsigned char f_magic[2]; /* magic number */
+ unsigned char f_nscns[2]; /* number of sections */
+ unsigned char f_timdat[4]; /* time & date stamp */
+ unsigned char f_symptr[8]; /* file pointer to symtab */
+ unsigned char f_nsyms[4]; /* number of symtab entries */
+ unsigned char f_opthdr[2]; /* sizeof(optional hdr) */
+ unsigned char f_flags[2]; /* flags */
+};
+
+/* Magic numbers are defined in coff/ecoff.h. */
+#define ALPHA_ECOFF_BADMAG(x) \
+ ((x).f_magic != ALPHA_MAGIC && (x).f_magic != ALPHA_MAGIC_BSD)
+
+/* The object type is encoded in the f_flags. */
+#define F_ALPHA_OBJECT_TYPE_MASK 0x3000
+#define F_ALPHA_NO_SHARED 0x1000
+#define F_ALPHA_SHARABLE 0x2000
+#define F_ALPHA_CALL_SHARED 0x3000
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 24
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct external_aouthdr
+{
+ unsigned char magic[2]; /* type of file */
+ unsigned char vstamp[2]; /* version stamp */
+ unsigned char bldrev[2]; /* ?? */
+ unsigned char padding[2]; /* pad to quadword boundary */
+ unsigned char tsize[8]; /* text size in bytes */
+ unsigned char dsize[8]; /* initialized data " " */
+ unsigned char bsize[8]; /* uninitialized data " " */
+ unsigned char entry[8]; /* entry pt. */
+ unsigned char text_start[8]; /* base of text used for this file */
+ unsigned char data_start[8]; /* base of data used for this file */
+ unsigned char bss_start[8]; /* base of bss used for this file */
+ unsigned char gprmask[4]; /* bitmask of general registers used */
+ unsigned char fprmask[4]; /* bitmask of floating point registers used */
+ unsigned char gp_value[8]; /* value for gp register */
+} AOUTHDR;
+
+/* compute size of a header */
+
+#define AOUTSZ 80
+#define AOUTHDRSZ 80
+
+/********************** SECTION HEADER **********************/
+
+struct external_scnhdr {
+ unsigned char s_name[8]; /* section name */
+ unsigned char s_paddr[8]; /* physical address, aliased s_nlib */
+ unsigned char s_vaddr[8]; /* virtual address */
+ unsigned char s_size[8]; /* section size */
+ unsigned char s_scnptr[8]; /* file ptr to raw data for section */
+ unsigned char s_relptr[8]; /* file ptr to relocation */
+ unsigned char s_lnnoptr[8]; /* file ptr to line numbers */
+ unsigned char s_nreloc[2]; /* number of relocation entries */
+ unsigned char s_nlnno[2]; /* number of line number entries*/
+ unsigned char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 64
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ unsigned char r_vaddr[8];
+ unsigned char r_symndx[4];
+ unsigned char r_bits[4];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
+/* Constants to unpack the r_bits field. The Alpha seems to always be
+ little endian, so I haven't bothered to define big endian variants
+ of these. */
+
+#define RELOC_BITS0_TYPE_LITTLE 0xff
+#define RELOC_BITS0_TYPE_SH_LITTLE 0
+
+#define RELOC_BITS1_EXTERN_LITTLE 0x01
+
+#define RELOC_BITS1_OFFSET_LITTLE 0x7e
+#define RELOC_BITS1_OFFSET_SH_LITTLE 1
+
+#define RELOC_BITS1_RESERVED_LITTLE 0x80
+#define RELOC_BITS1_RESERVED_SH_LITTLE 7
+#define RELOC_BITS2_RESERVED_LITTLE 0xff
+#define RELOC_BITS2_RESERVED_SH_LEFT_LITTLE 1
+#define RELOC_BITS3_RESERVED_LITTLE 0x03
+#define RELOC_BITS3_RESERVED_SH_LEFT_LITTLE 9
+
+#define RELOC_BITS3_SIZE_LITTLE 0xfc
+#define RELOC_BITS3_SIZE_SH_LITTLE 2
+
+/* The r_type field in a reloc is one of the following values. */
+#define ALPHA_R_IGNORE 0
+#define ALPHA_R_REFLONG 1
+#define ALPHA_R_REFQUAD 2
+#define ALPHA_R_GPREL32 3
+#define ALPHA_R_LITERAL 4
+#define ALPHA_R_LITUSE 5
+#define ALPHA_R_GPDISP 6
+#define ALPHA_R_BRADDR 7
+#define ALPHA_R_HINT 8
+#define ALPHA_R_SREL16 9
+#define ALPHA_R_SREL32 10
+#define ALPHA_R_SREL64 11
+#define ALPHA_R_OP_PUSH 12
+#define ALPHA_R_OP_STORE 13
+#define ALPHA_R_OP_PSUB 14
+#define ALPHA_R_OP_PRSHIFT 15
+#define ALPHA_R_GPVALUE 16
+#define ALPHA_R_GPRELHIGH 17
+#define ALPHA_R_GPRELLOW 18
+#define ALPHA_R_IMMED 19
+
+/* Overloaded reloc value used by Net- and OpenBSD. */
+#define ALPHA_R_LITERALSLEAZY 17
+
+/* With ALPHA_R_LITUSE, the r_size field is one of the following values. */
+#define ALPHA_R_LU_BASE 1
+#define ALPHA_R_LU_BYTOFF 2
+#define ALPHA_R_LU_JSR 3
+
+/* With ALPHA_R_IMMED, the r_size field is one of the following values. */
+#define ALPHA_R_IMMED_GP_16 1
+#define ALPHA_R_IMMED_GP_HI32 2
+#define ALPHA_R_IMMED_SCN_HI32 3
+#define ALPHA_R_IMMED_BR_HI32 4
+#define ALPHA_R_IMMED_LO32 5
+
+/********************** SYMBOLIC INFORMATION **********************/
+
+/* Written by John Gilmore. */
+
+/* ECOFF uses COFF-like section structures, but its own symbol format.
+ This file defines the symbol format in fields whose size and alignment
+ will not vary on different host systems. */
+
+/* File header as a set of bytes */
+
+struct hdr_ext {
+ unsigned char h_magic[2];
+ unsigned char h_vstamp[2];
+ unsigned char h_ilineMax[4];
+ unsigned char h_idnMax[4];
+ unsigned char h_ipdMax[4];
+ unsigned char h_isymMax[4];
+ unsigned char h_ioptMax[4];
+ unsigned char h_iauxMax[4];
+ unsigned char h_issMax[4];
+ unsigned char h_issExtMax[4];
+ unsigned char h_ifdMax[4];
+ unsigned char h_crfd[4];
+ unsigned char h_iextMax[4];
+ unsigned char h_cbLine[8];
+ unsigned char h_cbLineOffset[8];
+ unsigned char h_cbDnOffset[8];
+ unsigned char h_cbPdOffset[8];
+ unsigned char h_cbSymOffset[8];
+ unsigned char h_cbOptOffset[8];
+ unsigned char h_cbAuxOffset[8];
+ unsigned char h_cbSsOffset[8];
+ unsigned char h_cbSsExtOffset[8];
+ unsigned char h_cbFdOffset[8];
+ unsigned char h_cbRfdOffset[8];
+ unsigned char h_cbExtOffset[8];
+};
+
+/* File descriptor external record */
+
+struct fdr_ext {
+ unsigned char f_adr[8];
+ unsigned char f_cbLineOffset[8];
+ unsigned char f_cbLine[8];
+ unsigned char f_cbSs[8];
+ unsigned char f_rss[4];
+ unsigned char f_issBase[4];
+ unsigned char f_isymBase[4];
+ unsigned char f_csym[4];
+ unsigned char f_ilineBase[4];
+ unsigned char f_cline[4];
+ unsigned char f_ioptBase[4];
+ unsigned char f_copt[4];
+ unsigned char f_ipdFirst[4];
+ unsigned char f_cpd[4];
+ unsigned char f_iauxBase[4];
+ unsigned char f_caux[4];
+ unsigned char f_rfdBase[4];
+ unsigned char f_crfd[4];
+ unsigned char f_bits1[1];
+ unsigned char f_bits2[3];
+ unsigned char f_padding[4];
+};
+
+#define FDR_BITS1_LANG_BIG 0xF8
+#define FDR_BITS1_LANG_SH_BIG 3
+#define FDR_BITS1_LANG_LITTLE 0x1F
+#define FDR_BITS1_LANG_SH_LITTLE 0
+
+#define FDR_BITS1_FMERGE_BIG 0x04
+#define FDR_BITS1_FMERGE_LITTLE 0x20
+
+#define FDR_BITS1_FREADIN_BIG 0x02
+#define FDR_BITS1_FREADIN_LITTLE 0x40
+
+#define FDR_BITS1_FBIGENDIAN_BIG 0x01
+#define FDR_BITS1_FBIGENDIAN_LITTLE 0x80
+
+#define FDR_BITS2_GLEVEL_BIG 0xC0
+#define FDR_BITS2_GLEVEL_SH_BIG 6
+#define FDR_BITS2_GLEVEL_LITTLE 0x03
+#define FDR_BITS2_GLEVEL_SH_LITTLE 0
+
+/* We ignore the `reserved' field in bits2. */
+
+/* Procedure descriptor external record */
+
+struct pdr_ext {
+ unsigned char p_adr[8];
+ unsigned char p_cbLineOffset[8];
+ unsigned char p_isym[4];
+ unsigned char p_iline[4];
+ unsigned char p_regmask[4];
+ unsigned char p_regoffset[4];
+ unsigned char p_iopt[4];
+ unsigned char p_fregmask[4];
+ unsigned char p_fregoffset[4];
+ unsigned char p_frameoffset[4];
+ unsigned char p_lnLow[4];
+ unsigned char p_lnHigh[4];
+ unsigned char p_gp_prologue[1];
+ unsigned char p_bits1[1];
+ unsigned char p_bits2[1];
+ unsigned char p_localoff[1];
+ unsigned char p_framereg[2];
+ unsigned char p_pcreg[2];
+};
+
+#define PDR_BITS1_GP_USED_BIG 0x80
+#define PDR_BITS1_REG_FRAME_BIG 0x40
+#define PDR_BITS1_PROF_BIG 0x20
+#define PDR_BITS1_RESERVED_BIG 0x1f
+#define PDR_BITS1_RESERVED_SH_LEFT_BIG 8
+#define PDR_BITS2_RESERVED_BIG 0xff
+#define PDR_BITS2_RESERVED_SH_BIG 0
+
+#define PDR_BITS1_GP_USED_LITTLE 0x01
+#define PDR_BITS1_REG_FRAME_LITTLE 0x02
+#define PDR_BITS1_PROF_LITTLE 0x04
+#define PDR_BITS1_RESERVED_LITTLE 0xf8
+#define PDR_BITS1_RESERVED_SH_LITTLE 3
+#define PDR_BITS2_RESERVED_LITTLE 0xff
+#define PDR_BITS2_RESERVED_SH_LEFT_LITTLE 5
+
+/* Line numbers */
+
+struct line_ext {
+ unsigned char l_line[4];
+};
+
+/* Symbol external record */
+
+struct sym_ext {
+ unsigned char s_value[8];
+ unsigned char s_iss[4];
+ unsigned char s_bits1[1];
+ unsigned char s_bits2[1];
+ unsigned char s_bits3[1];
+ unsigned char s_bits4[1];
+};
+
+#define SYM_BITS1_ST_BIG 0xFC
+#define SYM_BITS1_ST_SH_BIG 2
+#define SYM_BITS1_ST_LITTLE 0x3F
+#define SYM_BITS1_ST_SH_LITTLE 0
+
+#define SYM_BITS1_SC_BIG 0x03
+#define SYM_BITS1_SC_SH_LEFT_BIG 3
+#define SYM_BITS1_SC_LITTLE 0xC0
+#define SYM_BITS1_SC_SH_LITTLE 6
+
+#define SYM_BITS2_SC_BIG 0xE0
+#define SYM_BITS2_SC_SH_BIG 5
+#define SYM_BITS2_SC_LITTLE 0x07
+#define SYM_BITS2_SC_SH_LEFT_LITTLE 2
+
+#define SYM_BITS2_RESERVED_BIG 0x10
+#define SYM_BITS2_RESERVED_LITTLE 0x08
+
+#define SYM_BITS2_INDEX_BIG 0x0F
+#define SYM_BITS2_INDEX_SH_LEFT_BIG 16
+#define SYM_BITS2_INDEX_LITTLE 0xF0
+#define SYM_BITS2_INDEX_SH_LITTLE 4
+
+#define SYM_BITS3_INDEX_SH_LEFT_BIG 8
+#define SYM_BITS3_INDEX_SH_LEFT_LITTLE 4
+
+#define SYM_BITS4_INDEX_SH_LEFT_BIG 0
+#define SYM_BITS4_INDEX_SH_LEFT_LITTLE 12
+
+/* External symbol external record */
+
+struct ext_ext {
+ struct sym_ext es_asym;
+ unsigned char es_bits1[1];
+ unsigned char es_bits2[3];
+ unsigned char es_ifd[4];
+};
+
+#define EXT_BITS1_JMPTBL_BIG 0x80
+#define EXT_BITS1_JMPTBL_LITTLE 0x01
+
+#define EXT_BITS1_COBOL_MAIN_BIG 0x40
+#define EXT_BITS1_COBOL_MAIN_LITTLE 0x02
+
+#define EXT_BITS1_WEAKEXT_BIG 0x20
+#define EXT_BITS1_WEAKEXT_LITTLE 0x04
+
+/* Dense numbers external record */
+
+struct dnr_ext {
+ unsigned char d_rfd[4];
+ unsigned char d_index[4];
+};
+
+/* Relative file descriptor */
+
+struct rfd_ext {
+ unsigned char rfd[4];
+};
+
+/* Optimizer symbol external record */
+
+struct opt_ext {
+ unsigned char o_bits1[1];
+ unsigned char o_bits2[1];
+ unsigned char o_bits3[1];
+ unsigned char o_bits4[1];
+ struct rndx_ext o_rndx;
+ unsigned char o_offset[4];
+};
+
+#define OPT_BITS2_VALUE_SH_LEFT_BIG 16
+#define OPT_BITS2_VALUE_SH_LEFT_LITTLE 0
+
+#define OPT_BITS3_VALUE_SH_LEFT_BIG 8
+#define OPT_BITS3_VALUE_SH_LEFT_LITTLE 8
+
+#define OPT_BITS4_VALUE_SH_LEFT_BIG 0
+#define OPT_BITS4_VALUE_SH_LEFT_LITTLE 16
diff --git a/include/coff/apollo.h b/include/coff/apollo.h
new file mode 100644
index 00000000000..d1347f1f532
--- /dev/null
+++ b/include/coff/apollo.h
@@ -0,0 +1,252 @@
+/*** coff information for Apollo M68K */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+/* Motorola 68000/68008/68010/68020 */
+#define MC68MAGIC 0520
+#define MC68KWRMAGIC 0520 /* writeable text segments */
+#define MC68TVMAGIC 0521
+#define MC68KROMAGIC 0521 /* readonly shareable text segments */
+#define MC68KPGMAGIC 0522 /* demand paged text segments */
+#define M68MAGIC 0210
+#define M68TVMAGIC 0211
+
+/* Apollo 68000-based machines have a different magic number. This comes
+ * from /usr/include/apollo/filehdr.h
+ */
+#define APOLLOM68KMAGIC 0627
+
+#define OMAGIC M68MAGIC
+#define M68KBADMAG(x) (((x).f_magic!=MC68MAGIC) && ((x).f_magic!=MC68KWRMAGIC) && ((x).f_magic!=MC68TVMAGIC) && \
+ ((x).f_magic!=MC68KROMAGIC) && ((x).f_magic!=MC68KPGMAGIC) && ((x).f_magic!=M68MAGIC) && ((x).f_magic!=M68TVMAGIC) && \
+ ((x).f_magic!=APOLLOM68KMAGIC) )
+
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+ char o_sri[4]; /* Apollo specific - .sri data pointer */
+ char o_inlib[4]; /* Apollo specific - .inlib data pointer */
+ char vid[8]; /* Apollo specific - 64 bit version ID */
+}
+AOUTHDR;
+
+#define APOLLO_COFF_VERSION_NUMBER 1 /* the value of the aouthdr magic */
+#define AOUTHDRSZ 44
+#define AOUTSZ 44
+
+
+
+/********************** SECTION HEADER **********************/
+
+struct external_scnhdr {
+ /* Apollo allow for larger section names by allowing it to be in
+ * the string table.
+ */
+ char s_name[8];
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/* If s_zeores is all zeroes, s_offset gives the real location of the name
+ * in the string table.
+ */
+
+#define s_zeroes section_name.s_name
+#define s_offset (section_name.s_name+4)
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _TV ".tv"
+#define _INIT ".init"
+#define _FINI ".fini"
+#define _LINES ".lines"
+#define _BLOCKS ".blocks"
+#define _SRI ".sri" /* Static Resource Information (systype,
+ et al.) */
+#define _MIR ".mir" /* Module Information Records */
+#define _APTV ".aptv" /* Apollo-style transfer vectors. */
+#define _INLIB ".inlib" /* Shared Library information */
+#define _RWDI ".rwdi" /* Read/write data initialization directives for
+ compressed sections */
+#define _UNWIND ".unwind" /* Stack unwind information */
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+#ifdef M68K_COFF_OFFSET
+ char r_offset[4];
+#endif
+
+};
+
+
+#define RELOC struct external_reloc
+
+#ifdef M68K_COFF_OFFSET
+#define RELSZ 14
+#else
+#define RELSZ 10
+#endif
+
+/* Apollo specific STYP flags */
+
+#define STYP_RELOCATED_NOT_LOADED 0x00010000 /* Section is relocated normally during linking, but need
+ not be loaded during program execution */
+#define STYP_DEBUG 0x00020000 /* debug section */
+#define STYP_OVERLAY 0x00040000 /* Section is overlayed */
+#define STYP_INSTRUCTION 0x00200000 /* Section contains executable code */
+
+#define STYP_ZERO 0x00800000 /* Section is initialized to zero */
+#define STYP_INSTALLED 0x02000000 /* Section should be installable in KGT */
+#define STYP_LOOK_INSTALLED 0x04000000 /* Look for section in KGT */
+#define STYP_SECALIGN1 0x08000000 /* Specially aligned section */
+#define STYP_SECALIGN2 0x10000000 /* " " " */
+#define STYP_COMPRESSED 0x20000000 /* No section data per se (s_scnptr = 0), but there are
+ initialization directives for it in .rwdi section
+ (used in conjunction with STYP_BSS) */
diff --git a/include/coff/arm.h b/include/coff/arm.h
new file mode 100644
index 00000000000..dd578b1a76a
--- /dev/null
+++ b/include/coff/arm.h
@@ -0,0 +1,258 @@
+/*** coff information for the ARM */
+
+#define COFFARM 1
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_INTERWORK file supports switching between ARM and Thumb instruction sets
+ * F_INTERWORK_SET the F_INTERWORK bit is valid
+ * F_APCS_FLOAT code passes float arguments in float registers
+ * F_PIC code is reentrant/position-independent
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ * F_APCS_26 file uses 26 bit ARM Procedure Calling Standard
+ * F_APCS_SET the F_APCS_26, F_APCS_FLOAT and F_PIC bits have been initialised
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+#define F_INTERWORK (0x0010)
+#define F_INTERWORK_SET (0x0020)
+#define F_APCS_FLOAT (0x0040)
+#undef F_AR16WR
+#define F_PIC (0x0080)
+#define F_AR32WR (0x0100)
+#define F_APCS_26 (0x0400)
+#define F_APCS_SET (0x0800)
+
+/* Bits stored in flags field of the internal_f structure */
+
+#define F_INTERWORK (0x0010)
+#define F_PIC_INT (0x0020)
+#define F_APCS_FLOAT (0x0040)
+#define F_ARM_ARCHITECTURE_MASK (0x0c00)
+#define F_ARM_2 (0x0000)
+#define F_ARM_2a (0x0000)
+#define F_ARM_3 (0x0400)
+#define F_ARM_3M (0x0400)
+#define F_ARM_4 (0x0800)
+#define F_ARM_4T (0x0c00)
+#define F_APCS26 (0x4000)
+
+/*
+ * ARMMAGIC ought to encoded the procesor type,
+ * but it is too late to change it now, instead
+ * the flags field of the internal_f structure
+ * is used as shown above.
+ *
+ * XXX - NC 5/6/97
+ */
+
+#define ARMMAGIC 0xa00 /* I just made this up */
+
+#define ARMBADMAG(x) (((x).f_magic != ARMMAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+
+
+}
+AOUTHDR;
+
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+#define OMAGIC 0404 /* object files, eg as output */
+#define ZMAGIC 0413 /* demand load format, eg normal ld output */
+#define STMAGIC 0401 /* target shlib */
+#define SHMAGIC 0443 /* host shlib */
+
+
+/* define some NT default values */
+/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT 0x200
+#define NT_DEF_RESERVE 0x100000
+#define NT_DEF_COMMIT 0x1000
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+#define _LIB ".lib"
+
+/* We use the .rdata section to hold read only data. */
+#define _LIT ".rdata"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ char x_checksum[4]; /* section COMDAT checksum */
+ char x_associated[2]; /* COMDAT associated section index */
+ char x_comdat[1]; /* COMDAT selection number */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+# define _ETEXT "etext"
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+ char r_offset[4];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 14
diff --git a/include/coff/aux-coff.h b/include/coff/aux-coff.h
new file mode 100644
index 00000000000..c89c124d3e0
--- /dev/null
+++ b/include/coff/aux-coff.h
@@ -0,0 +1,31 @@
+/* Modifications of internal.h and m68k.h needed by A/UX
+ Suggested by Ian Lance Taylor <ian@cygnus.com> */
+
+#ifndef GNU_COFF_AUX_H
+#define GNU_COFF_AUX_H 1
+
+#include "coff/internal.h"
+#include "coff/m68k.h"
+
+/* Section contains 64-byte padded pathnames of shared libraries */
+#undef STYP_LIB
+#define STYP_LIB 0x200
+
+/* Section contains shared library initialization code */
+#undef STYP_INIT
+#define STYP_INIT 0x400
+
+/* Section contains .ident information */
+#undef STYP_IDENT
+#define STYP_IDENT 0x800
+
+/* Section types used by bfd and gas not defined (directly) by A/UX */
+#undef STYP_OVER
+#define STYP_OVER 0
+#undef STYP_INFO
+#define STYP_INFO STYP_IDENT
+
+/* Traditional name of the section tagged with STYP_LIB */
+#define _LIB ".lib"
+
+#endif /* GNU_COFF_AUX_H */
diff --git a/include/coff/ecoff.h b/include/coff/ecoff.h
new file mode 100644
index 00000000000..9e4202e4757
--- /dev/null
+++ b/include/coff/ecoff.h
@@ -0,0 +1,421 @@
+#ifndef ECOFF_H
+#define ECOFF_H
+
+/* Generic ECOFF support.
+ This does not include symbol information, found in sym.h and
+ symconst.h. */
+
+/* Mips magic numbers used in filehdr. MIPS_MAGIC_LITTLE is used on
+ little endian machines. MIPS_MAGIC_BIG is used on big endian
+ machines. Where is MIPS_MAGIC_1 from? */
+#define MIPS_MAGIC_1 0x0180
+#define MIPS_MAGIC_LITTLE 0x0162
+#define MIPS_MAGIC_BIG 0x0160
+
+/* These are the magic numbers used for MIPS code compiled at ISA
+ level 2. */
+#define MIPS_MAGIC_LITTLE2 0x0166
+#define MIPS_MAGIC_BIG2 0x0163
+
+/* These are the magic numbers used for MIPS code compiled at ISA
+ level 3. */
+#define MIPS_MAGIC_LITTLE3 0x142
+#define MIPS_MAGIC_BIG3 0x140
+
+/* Alpha magic numbers used in filehdr. */
+#define ALPHA_MAGIC 0x183
+#define ALPHA_MAGIC_BSD 0x185
+
+/* Magic numbers used in a.out header. */
+#define ECOFF_AOUT_OMAGIC 0407 /* not demand paged (ld -N). */
+#define ECOFF_AOUT_ZMAGIC 0413 /* demand load format, eg normal ld output */
+
+/* Names of special sections. */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _RDATA ".rdata"
+#define _SDATA ".sdata"
+#define _SBSS ".sbss"
+#define _LITA ".lita"
+#define _LIT4 ".lit4"
+#define _LIT8 ".lit8"
+#define _LIB ".lib"
+#define _INIT ".init"
+#define _FINI ".fini"
+#define _PDATA ".pdata"
+#define _XDATA ".xdata"
+#define _GOT ".got"
+#define _HASH ".hash"
+#define _DYNSYM ".dynsym"
+#define _DYNSTR ".dynstr"
+#define _RELDYN ".rel.dyn"
+#define _CONFLIC ".conflic"
+#define _COMMENT ".comment"
+#define _LIBLIST ".liblist"
+#define _DYNAMIC ".dynamic"
+#define _RCONST ".rconst"
+
+/* ECOFF uses some additional section flags. */
+#define STYP_RDATA 0x100
+#define STYP_SDATA 0x200
+#define STYP_SBSS 0x400
+#define STYP_GOT 0x1000
+#define STYP_DYNAMIC 0x2000
+#define STYP_DYNSYM 0x4000
+#define STYP_RELDYN 0x8000
+#define STYP_DYNSTR 0x10000
+#define STYP_HASH 0x20000
+#define STYP_LIBLIST 0x40000
+#define STYP_CONFLIC 0x100000
+#define STYP_ECOFF_FINI 0x1000000
+#define STYP_EXTENDESC 0x2000000 /* 0x02FFF000 bits => scn type, rest clr */
+#define STYP_LITA 0x4000000
+#define STYP_LIT8 0x8000000
+#define STYP_LIT4 0x10000000
+#define STYP_ECOFF_LIB 0x40000000
+#define STYP_ECOFF_INIT 0x80000000
+#define STYP_OTHER_LOAD (STYP_ECOFF_INIT | STYP_ECOFF_FINI)
+
+/* extended section types */
+#define STYP_COMMENT 0x2100000
+#define STYP_RCONST 0x2200000
+#define STYP_XDATA 0x2400000
+#define STYP_PDATA 0x2800000
+
+/* The linker needs a section to hold small common variables while
+ linking. There is no convenient way to create it when the linker
+ needs it, so we always create one for each BFD. We then avoid
+ writing it out. */
+#define SCOMMON ".scommon"
+
+/* If the extern bit in a reloc is 1, then r_symndx is an index into
+ the external symbol table. If the extern bit is 0, then r_symndx
+ indicates a section, and is one of the following values. */
+#define RELOC_SECTION_NONE 0
+#define RELOC_SECTION_TEXT 1
+#define RELOC_SECTION_RDATA 2
+#define RELOC_SECTION_DATA 3
+#define RELOC_SECTION_SDATA 4
+#define RELOC_SECTION_SBSS 5
+#define RELOC_SECTION_BSS 6
+#define RELOC_SECTION_INIT 7
+#define RELOC_SECTION_LIT8 8
+#define RELOC_SECTION_LIT4 9
+#define RELOC_SECTION_XDATA 10
+#define RELOC_SECTION_PDATA 11
+#define RELOC_SECTION_FINI 12
+#define RELOC_SECTION_LITA 13
+#define RELOC_SECTION_ABS 14
+#define RELOC_SECTION_RCONST 15
+
+#define NUM_RELOC_SECTIONS 16
+
+/********************** STABS **********************/
+
+/* gcc uses mips-tfile to output type information in special stabs
+ entries. These must match the corresponding definition in
+ gcc/config/mips.h. At some point, these should probably go into a
+ shared include file, but currently gcc and gdb do not share any
+ directories. */
+#define CODE_MASK 0x8F300
+#define ECOFF_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
+#define ECOFF_MARK_STAB(code) ((code)+CODE_MASK)
+#define ECOFF_UNMARK_STAB(code) ((code)-CODE_MASK)
+#define STABS_SYMBOL "@stabs"
+
+/********************** COFF **********************/
+
+/* gcc also uses mips-tfile to output COFF debugging information.
+ These are the values it uses when outputting the .type directive.
+ These should also be in a shared include file. */
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+/********************** AUX **********************/
+
+/* The auxiliary type information is the same on all known ECOFF
+ targets. I can't see any reason that it would ever change, so I am
+ going to gamble and define the external structures here, in the
+ target independent ECOFF header file. The internal forms are
+ defined in coff/sym.h, which was originally donated by MIPS
+ Computer Systems. */
+
+/* Type information external record */
+
+struct tir_ext {
+ unsigned char t_bits1[1];
+ unsigned char t_tq45[1];
+ unsigned char t_tq01[1];
+ unsigned char t_tq23[1];
+};
+
+#define TIR_BITS1_FBITFIELD_BIG ((unsigned int) 0x80)
+#define TIR_BITS1_FBITFIELD_LITTLE ((unsigned int) 0x01)
+
+#define TIR_BITS1_CONTINUED_BIG ((unsigned int) 0x40)
+#define TIR_BITS1_CONTINUED_LITTLE ((unsigned int) 0x02)
+
+#define TIR_BITS1_BT_BIG ((unsigned int) 0x3F)
+#define TIR_BITS1_BT_SH_BIG 0
+#define TIR_BITS1_BT_LITTLE ((unsigned int) 0xFC)
+#define TIR_BITS1_BT_SH_LITTLE 2
+
+#define TIR_BITS_TQ4_BIG ((unsigned int) 0xF0)
+#define TIR_BITS_TQ4_SH_BIG 4
+#define TIR_BITS_TQ5_BIG ((unsigned int) 0x0F)
+#define TIR_BITS_TQ5_SH_BIG 0
+#define TIR_BITS_TQ4_LITTLE ((unsigned int) 0x0F)
+#define TIR_BITS_TQ4_SH_LITTLE 0
+#define TIR_BITS_TQ5_LITTLE ((unsigned int) 0xF0)
+#define TIR_BITS_TQ5_SH_LITTLE 4
+
+#define TIR_BITS_TQ0_BIG ((unsigned int) 0xF0)
+#define TIR_BITS_TQ0_SH_BIG 4
+#define TIR_BITS_TQ1_BIG ((unsigned int) 0x0F)
+#define TIR_BITS_TQ1_SH_BIG 0
+#define TIR_BITS_TQ0_LITTLE ((unsigned int) 0x0F)
+#define TIR_BITS_TQ0_SH_LITTLE 0
+#define TIR_BITS_TQ1_LITTLE ((unsigned int) 0xF0)
+#define TIR_BITS_TQ1_SH_LITTLE 4
+
+#define TIR_BITS_TQ2_BIG ((unsigned int) 0xF0)
+#define TIR_BITS_TQ2_SH_BIG 4
+#define TIR_BITS_TQ3_BIG ((unsigned int) 0x0F)
+#define TIR_BITS_TQ3_SH_BIG 0
+#define TIR_BITS_TQ2_LITTLE ((unsigned int) 0x0F)
+#define TIR_BITS_TQ2_SH_LITTLE 0
+#define TIR_BITS_TQ3_LITTLE ((unsigned int) 0xF0)
+#define TIR_BITS_TQ3_SH_LITTLE 4
+
+/* Relative symbol external record */
+
+struct rndx_ext {
+ unsigned char r_bits[4];
+};
+
+#define RNDX_BITS0_RFD_SH_LEFT_BIG 4
+#define RNDX_BITS1_RFD_BIG ((unsigned int) 0xF0)
+#define RNDX_BITS1_RFD_SH_BIG 4
+
+#define RNDX_BITS0_RFD_SH_LEFT_LITTLE 0
+#define RNDX_BITS1_RFD_LITTLE ((unsigned int) 0x0F)
+#define RNDX_BITS1_RFD_SH_LEFT_LITTLE 8
+
+#define RNDX_BITS1_INDEX_BIG ((unsigned int) 0x0F)
+#define RNDX_BITS1_INDEX_SH_LEFT_BIG 16
+#define RNDX_BITS2_INDEX_SH_LEFT_BIG 8
+#define RNDX_BITS3_INDEX_SH_LEFT_BIG 0
+
+#define RNDX_BITS1_INDEX_LITTLE ((unsigned int) 0xF0)
+#define RNDX_BITS1_INDEX_SH_LITTLE 4
+#define RNDX_BITS2_INDEX_SH_LEFT_LITTLE 4
+#define RNDX_BITS3_INDEX_SH_LEFT_LITTLE 12
+
+/* Auxiliary symbol information external record */
+
+union aux_ext {
+ struct tir_ext a_ti;
+ struct rndx_ext a_rndx;
+ unsigned char a_dnLow[4];
+ unsigned char a_dnHigh[4];
+ unsigned char a_isym[4];
+ unsigned char a_iss[4];
+ unsigned char a_width[4];
+ unsigned char a_count[4];
+};
+
+#define AUX_GET_ANY(bigend, ax, field) \
+ ((bigend) ? bfd_getb32 ((ax)->field) : bfd_getl32 ((ax)->field))
+
+#define AUX_GET_DNLOW(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_dnLow)
+#define AUX_GET_DNHIGH(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_dnHigh)
+#define AUX_GET_ISYM(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_isym)
+#define AUX_GET_ISS(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_iss)
+#define AUX_GET_WIDTH(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_width)
+#define AUX_GET_COUNT(bigend, ax) AUX_GET_ANY ((bigend), (ax), a_count)
+
+#define AUX_PUT_ANY(bigend, val, ax, field) \
+ ((bigend) \
+ ? (bfd_putb32 ((bfd_vma) (val), (ax)->field), 0) \
+ : (bfd_putl32 ((bfd_vma) (val), (ax)->field), 0))
+
+#define AUX_PUT_DNLOW(bigend, val, ax) \
+ AUX_PUT_ANY ((bigend), (val), (ax), a_dnLow)
+#define AUX_PUT_DNHIGH(bigend, val, ax) \
+ AUX_PUT_ANY ((bigend), (val), (ax), a_dnHigh)
+#define AUX_PUT_ISYM(bigend, val, ax) \
+ AUX_PUT_ANY ((bigend), (val), (ax), a_isym)
+#define AUX_PUT_ISS(bigend, val, ax) \
+ AUX_PUT_ANY ((bigend), (val), (ax), a_iss)
+#define AUX_PUT_WIDTH(bigend, val, ax) \
+ AUX_PUT_ANY ((bigend), (val), (ax), a_width)
+#define AUX_PUT_COUNT(bigend, val, ax) \
+ AUX_PUT_ANY ((bigend), (val), (ax), a_count)
+
+/********************** SYMBOLS **********************/
+
+/* For efficiency, gdb deals directly with the unswapped symbolic
+ information (that way it only takes the time to swap information
+ that it really needs to read). gdb originally retrieved the
+ information directly from the BFD backend information, but that
+ strategy, besides being sort of ugly, does not work for MIPS ELF,
+ which also uses ECOFF debugging information. This structure holds
+ pointers to the (mostly) unswapped symbolic information. */
+
+struct ecoff_debug_info
+{
+ /* The swapped ECOFF symbolic header. */
+ HDRR symbolic_header;
+
+ /* Pointers to the unswapped symbolic information. Note that the
+ pointers to external structures point to different sorts of
+ information on different ECOFF targets. The ecoff_debug_swap
+ structure provides the sizes of the structures and the functions
+ needed to swap the information in and out. These pointers are
+ all pointers to arrays, not single structures. They will be NULL
+ if there are no instances of the relevant structure. These
+ fields are also used by the assembler to output ECOFF debugging
+ information. */
+ unsigned char *line;
+ PTR external_dnr; /* struct dnr_ext */
+ PTR external_pdr; /* struct pdr_ext */
+ PTR external_sym; /* struct sym_ext */
+ PTR external_opt; /* struct opt_ext */
+ union aux_ext *external_aux;
+ char *ss;
+ char *ssext;
+ PTR external_fdr; /* struct fdr_ext */
+ PTR external_rfd; /* struct rfd_ext */
+ PTR external_ext; /* struct ext_ext */
+
+ /* These fields are used when linking. They may disappear at some
+ point. */
+ char *ssext_end;
+ PTR external_ext_end;
+
+ /* When linking, this field holds a mapping from the input FDR
+ numbers to the output numbers, and is used when writing out the
+ external symbols. It is NULL if no mapping is required. */
+ RFDT *ifdmap;
+
+ /* The swapped FDR information. Currently this is never NULL, but
+ code using this structure should probably double-check in case
+ this changes in the future. This is a pointer to an array, not a
+ single structure. */
+ FDR *fdr;
+
+ /* When relaxing MIPS embedded PIC code, we may need to adjust
+ symbol values when they are output. This is a linked list of
+ structures indicating how values should be adjusted. There is no
+ requirement that the entries be in any order, or that they not
+ overlap. This field is normally NULL, in which case no
+ adjustments need to be made. */
+ struct ecoff_value_adjust *adjust;
+};
+
+/* This structure describes how to adjust symbol values when
+ outputting MIPS embedded PIC code. These adjustments only apply to
+ the internal symbols, as the external symbol values will come from
+ the hash table and have already been adjusted. */
+
+struct ecoff_value_adjust
+{
+ /* Next entry on adjustment list. */
+ struct ecoff_value_adjust *next;
+ /* Starting VMA of adjustment. This is the VMA in the ECOFF file,
+ not the offset from the start of the section. Thus it should
+ indicate a particular section. */
+ bfd_vma start;
+ /* Ending VMA of adjustment. */
+ bfd_vma end;
+ /* Adjustment. This should be added to the value of the symbol, or
+ FDR. This is zero for the last entry in the array. */
+ long adjust;
+};
+
+/* These structures are used by the ECOFF find_nearest_line function. */
+
+struct ecoff_fdrtab_entry
+{
+ /* Base address in .text of this FDR. */
+ bfd_vma base_addr;
+ FDR *fdr;
+};
+
+struct ecoff_find_line
+{
+ /* Allocated memory to hold function and file names. */
+ char *find_buffer;
+
+ /* FDR table, sorted by address: */
+ long fdrtab_len;
+ struct ecoff_fdrtab_entry *fdrtab;
+
+ /* Cache entry for most recently found line information. The sect
+ field is NULL if this cache does not contain valid information. */
+ struct
+ {
+ asection *sect;
+ bfd_vma start;
+ bfd_vma stop;
+ const char *filename;
+ const char *functionname;
+ unsigned int line_num;
+ } cache;
+};
+
+/********************** SWAPPING **********************/
+
+/* The generic ECOFF code needs to be able to swap debugging
+ information in and out in the specific format used by a particular
+ ECOFF implementation. This structure provides the information
+ needed to do this. */
+
+struct ecoff_debug_swap
+{
+ /* Symbol table magic number. */
+ int sym_magic;
+ /* Alignment of debugging information. E.g., 4. */
+ bfd_size_type debug_align;
+ /* Sizes of external symbolic information. */
+ bfd_size_type external_hdr_size;
+ bfd_size_type external_dnr_size;
+ bfd_size_type external_pdr_size;
+ bfd_size_type external_sym_size;
+ bfd_size_type external_opt_size;
+ bfd_size_type external_fdr_size;
+ bfd_size_type external_rfd_size;
+ bfd_size_type external_ext_size;
+ /* Functions to swap in external symbolic data. */
+ void (*swap_hdr_in) PARAMS ((bfd *, PTR, HDRR *));
+ void (*swap_dnr_in) PARAMS ((bfd *, PTR, DNR *));
+ void (*swap_pdr_in) PARAMS ((bfd *, PTR, PDR *));
+ void (*swap_sym_in) PARAMS ((bfd *, PTR, SYMR *));
+ void (*swap_opt_in) PARAMS ((bfd *, PTR, OPTR *));
+ void (*swap_fdr_in) PARAMS ((bfd *, PTR, FDR *));
+ void (*swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *));
+ void (*swap_ext_in) PARAMS ((bfd *, PTR, EXTR *));
+ void (*swap_tir_in) PARAMS ((int, const struct tir_ext *, TIR *));
+ void (*swap_rndx_in) PARAMS ((int, const struct rndx_ext *, RNDXR *));
+ /* Functions to swap out external symbolic data. */
+ void (*swap_hdr_out) PARAMS ((bfd *, const HDRR *, PTR));
+ void (*swap_dnr_out) PARAMS ((bfd *, const DNR *, PTR));
+ void (*swap_pdr_out) PARAMS ((bfd *, const PDR *, PTR));
+ void (*swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR));
+ void (*swap_opt_out) PARAMS ((bfd *, const OPTR *, PTR));
+ void (*swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR));
+ void (*swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR));
+ void (*swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR));
+ void (*swap_tir_out) PARAMS ((int, const TIR *, struct tir_ext *));
+ void (*swap_rndx_out) PARAMS ((int, const RNDXR *, struct rndx_ext *));
+ /* Function to read symbol data and set up pointers in
+ ecoff_debug_info structure. The section argument is used for
+ ELF, not straight ECOFF. */
+ boolean (*read_debug_info) PARAMS ((bfd *, asection *,
+ struct ecoff_debug_info *));
+};
+
+#endif /* ! defined (ECOFF_H) */
diff --git a/include/coff/go32exe.h b/include/coff/go32exe.h
new file mode 100644
index 00000000000..5bd26c13401
--- /dev/null
+++ b/include/coff/go32exe.h
@@ -0,0 +1,20 @@
+/* COFF information for PC running go32. */
+
+#define STUBSIZE 2048
+
+struct external_filehdr_go32_exe {
+ char stub[STUBSIZE]; /* the stub to load the image */
+ /* the standard COFF header */
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+#undef FILHDR
+#define FILHDR struct external_filehdr_go32_exe
+#undef FILHSZ
+#define FILHSZ STUBSIZE+20
diff --git a/include/coff/h8300.h b/include/coff/h8300.h
new file mode 100644
index 00000000000..9b62394f380
--- /dev/null
+++ b/include/coff/h8300.h
@@ -0,0 +1,204 @@
+/*** coff information for Hitachi H8/300 and H8/300-H */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+
+#define H8300MAGIC 0x8300
+#define H8300HMAGIC 0x8301
+#define H8300SMAGIC 0x8302
+
+#define H8300BADMAG(x) (((x).f_magic!=H8300MAGIC))
+#define H8300HBADMAG(x) (((x).f_magic!=H8300HMAGIC))
+#define H8300SBADMAG(x) (((x).f_magic!=H8300SMAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[4]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the h8 don't have room in the instruction for the entire
+ offset - eg the strange jump and high page addressing modes */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
+
+
+
diff --git a/include/coff/h8500.h b/include/coff/h8500.h
new file mode 100644
index 00000000000..0305bf2b76b
--- /dev/null
+++ b/include/coff/h8500.h
@@ -0,0 +1,201 @@
+/*** coff information for Hitachi H8/500 */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+
+#define H8500MAGIC 0x8500
+
+
+#define H8500BADMAG(x) ((0xffff && ((x).f_magic)!=H8500MAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[4]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the h8 don't have room in the instruction for the entire
+ offset - eg the strange jump and high page addressing modes */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
+
+
+
diff --git a/include/coff/i386.h b/include/coff/i386.h
new file mode 100644
index 00000000000..5ebf4a2e023
--- /dev/null
+++ b/include/coff/i386.h
@@ -0,0 +1,228 @@
+/*** coff information for Intel 386/486. */
+
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+
+
+
+#define I386MAGIC 0x14c
+#define I386PTXMAGIC 0x154
+#define I386AIXMAGIC 0x175
+
+/* This is Lynx's all-platform magic number for executables. */
+
+#define LYNXCOFFMAGIC 0415
+
+#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
+ && (x).f_magic != I386AIXMAGIC \
+ && (x).f_magic != I386PTXMAGIC \
+ && (x).f_magic != LYNXCOFFMAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+
+
+}
+AOUTHDR;
+
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+#define OMAGIC 0404 /* object files, eg as output */
+#define ZMAGIC 0413 /* demand load format, eg normal ld output */
+#define STMAGIC 0401 /* target shlib */
+#define SHMAGIC 0443 /* host shlib */
+
+
+/* define some NT default values */
+/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT 0x200
+#define NT_DEF_RESERVE 0x100000
+#define NT_DEF_COMMIT 0x1000
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+#define _LIB ".lib"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ char x_checksum[4]; /* section COMDAT checksum */
+ char x_associated[2]; /* COMDAT associated section index */
+ char x_comdat[1]; /* COMDAT selection number */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+# define _ETEXT "etext"
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
diff --git a/include/coff/i860.h b/include/coff/i860.h
new file mode 100644
index 00000000000..73686e92b7d
--- /dev/null
+++ b/include/coff/i860.h
@@ -0,0 +1,205 @@
+/* This file was hacked from i386.h [dolan@ssd.intel.com] */
+
+/*** coff information for Intel 860. */
+
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+
+
+
+#define I860MAGIC 0x14d
+
+#define I860BADMAG(x) ((x).f_magic != I860MAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+/* FIXME: What are the a.out magic numbers? */
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+#define _LIB ".lib"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+# define _ETEXT "etext"
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
diff --git a/include/coff/i960.h b/include/coff/i960.h
new file mode 100644
index 00000000000..0935836c14a
--- /dev/null
+++ b/include/coff/i960.h
@@ -0,0 +1,275 @@
+/*** coff information for 80960. Origins: Intel corp, natch. */
+
+/* NOTE: Tagentries (cf TAGBITS) are no longer used by the 960 */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+#define OMAGIC (0407) /* old impure format. data immediately
+ follows text. both sections are rw. */
+#define NMAGIC (0410) /* split i&d, read-only text */
+
+/*
+* Intel 80960 (I960) processor flags.
+* F_I960TYPE == mask for processor type field.
+*/
+
+#define F_I960TYPE (0xf000)
+#define F_I960CORE (0x1000)
+#define F_I960KB (0x2000)
+#define F_I960SB (0x2000)
+#define F_I960MC (0x3000)
+#define F_I960XA (0x4000)
+#define F_I960CA (0x5000)
+#define F_I960KA (0x6000)
+#define F_I960SA (0x6000)
+#define F_I960JX (0x7000)
+#define F_I960HX (0x8000)
+
+
+/** i80960 Magic Numbers
+*/
+
+#define I960ROMAGIC (0x160) /* read-only text segments */
+#define I960RWMAGIC (0x161) /* read-write text segments */
+
+#define I960BADMAG(x) (((x).f_magic!=I960ROMAGIC) && ((x).f_magic!=I960RWMAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+typedef struct {
+ unsigned long phys_addr;
+ unsigned long bitarray;
+} TAGBITS;
+
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+ char tagentries[4]; /* number of tag entries to follow */
+}
+AOUTHDR;
+
+/* return a pointer to the tag bits array */
+
+#define TAGPTR(aout) ((TAGBITS *) (&(aout.tagentries)+1))
+
+/* compute size of a header */
+
+/*#define AOUTSZ(aout) (sizeof(AOUTHDR)+(aout.tagentries*sizeof(TAGBITS)))*/
+#define AOUTSZ 32
+#define AOUTHDRSZ 32
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+ char s_align[4]; /* section alignment */
+};
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 44
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+ char padding[2]; /* force alignment */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_flags[2];
+ char e_type[4];
+ char e_sclass[1];
+ char e_numaux[1];
+ char pad2[2];
+};
+
+
+
+
+#define N_BTMASK (0x1f)
+#define N_TMASK (0x60)
+#define N_BTSHFT (5)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+ /******************************************
+ * I960-specific *2nd* aux. entry formats
+ ******************************************/
+ struct {
+ /* This is a very old typo that keeps getting propagated. */
+#define x_stdindx x_stindx
+ char x_stindx[4]; /* sys. table entry */
+ } x_sc; /* system call entry */
+
+ struct {
+ char x_balntry[4]; /* BAL entry point */
+ } x_bal; /* BAL-callable function */
+
+ struct {
+ char x_timestamp[4]; /* time stamp */
+ char x_idstring[20]; /* producer identity string */
+ } x_ident; /* Producer ident info */
+
+};
+
+
+
+#define SYMENT struct external_syment
+#define SYMESZ 24
+#define AUXENT union external_auxent
+#define AUXESZ 24
+
+# define _ETEXT "_etext"
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+ char pad[2];
+};
+
+/* r_type values for the i960. */
+
+/* The i960 uses R_RELLONG, which is defined in internal.h as 0x11.
+ It is an absolute 32 bit relocation. */
+
+#define R_IPRMED (0x19) /* 24-bit ip-relative relocation */
+#define R_OPTCALL (0x1b) /* 32-bit optimizable call (leafproc/sysproc) */
+#define R_OPTCALLX (0x1c) /* 64-bit optimizable call (leafproc/sysproc) */
+
+/* The following relocation types are defined use by relaxing linkers,
+ which convert 32 bit calls (which require a 64 bit instruction)
+ into 24 bit calls (which require a 32 bit instruction) when
+ possible. It will be possible whenever the target of the call is
+ within a 24 bit range of the call instruction.
+
+ It is always safe to ignore these relocations. They only serve to
+ mark points which the relaxing linker will have to consider. The
+ assembler must ensure that the correct code is generated even if
+ the relocations are ignored. In particular, this means that the
+ R_IPR13 relocation may not appear with an external symbol. */
+
+#define R_IPR13 (0x1d) /* 13 bit ip-relative branch */
+#define R_ALIGN (0x1e) /* alignment marker. This has no
+ associated symbol. Instead, the
+ r_symndx field indicates the
+ require alignment at this point in
+ the file. It must be a power of 2. */
+
+#define RELOC struct external_reloc
+#define RELSZ 12
+
diff --git a/include/coff/internal.h b/include/coff/internal.h
new file mode 100644
index 00000000000..d5ea9510334
--- /dev/null
+++ b/include/coff/internal.h
@@ -0,0 +1,728 @@
+/* Internal format of COFF object file data structures, for GNU BFD.
+ This file is part of BFD, the Binary File Descriptor library. */
+
+#ifndef GNU_COFF_INTERNAL_H
+#define GNU_COFF_INTERNAL_H 1
+
+/* First, make "signed char" work, even on old compilers. */
+#ifndef signed
+#ifndef __STDC__
+#define signed /**/
+#endif
+#endif
+
+/********************** FILE HEADER **********************/
+
+/* extra stuff in a PE header. */
+
+struct internal_extra_pe_filehdr
+{
+ /* DOS header data follows for PE stuff */
+ unsigned short e_magic; /* Magic number, 0x5a4d */
+ unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
+ unsigned short e_cp; /* Pages in file, 0x3 */
+ unsigned short e_crlc; /* Relocations, 0x0 */
+ unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
+ unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
+ unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
+ unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
+ unsigned short e_sp; /* Initial SP value, 0xb8 */
+ unsigned short e_csum; /* Checksum, 0x0 */
+ unsigned short e_ip; /* Initial IP value, 0x0 */
+ unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
+ unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
+ unsigned short e_ovno; /* Overlay number, 0x0 */
+ unsigned short e_res[4]; /* Reserved words, all 0x0 */
+ unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
+ unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
+ unsigned short e_res2[10]; /* Reserved words, all 0x0 */
+ bfd_vma e_lfanew; /* File address of new exe header, 0x80 */
+ unsigned long dos_message[16]; /* text which always follows dos header */
+ bfd_vma nt_signature; /* required NT signature, 0x4550 */
+};
+
+struct internal_filehdr
+{
+ struct internal_extra_pe_filehdr pe;
+
+ /* standard coff internal info */
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ bfd_vma f_symptr; /* file pointer to symtab */
+ long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+ unsigned short f_target_id; /* (TIc80 specific) */
+};
+
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR16WR file is 16-bit little-endian
+ * F_AR32WR file is 32-bit little-endian
+ * F_AR32W file is 32-bit big-endian
+ * F_DYNLOAD rs/6000 aix: dynamically loadable w/imports & exports
+ * F_SHROBJ rs/6000 aix: file is a shared object
+ * F_DLL PE format DLL
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+#define F_AR16WR (0x0080)
+#define F_AR32WR (0x0100)
+#define F_AR32W (0x0200)
+#define F_DYNLOAD (0x1000)
+#define F_SHROBJ (0x2000)
+#define F_DLL (0x2000)
+
+/* extra structure which is used in the optional header */
+typedef struct _IMAGE_DATA_DIRECTORY
+{
+ bfd_vma VirtualAddress;
+ long Size;
+} IMAGE_DATA_DIRECTORY;
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+/* default image base for NT */
+#define NT_EXE_IMAGE_BASE 0x400000
+#define NT_DLL_IMAGE_BASE 0x10000000
+
+/* Extra stuff in a PE aouthdr */
+
+#define PE_DEF_SECTION_ALIGNMENT 0x1000
+#define PE_DEF_FILE_ALIGNMENT 0x200
+
+struct internal_extra_pe_aouthdr
+{
+ /* PE stuff */
+ bfd_vma ImageBase; /* address of specific location in memory that
+ file is located, NT default 0x10000 */
+
+ bfd_vma SectionAlignment; /* section alignment default 0x1000 */
+ bfd_vma FileAlignment; /* file alignment default 0x200 */
+ short MajorOperatingSystemVersion; /* minimum version of the operating */
+ short MinorOperatingSystemVersion; /* system req'd for exe, default to 1*/
+ short MajorImageVersion; /* user defineable field to store version of */
+ short MinorImageVersion; /* exe or dll being created, default to 0 */
+ short MajorSubsystemVersion; /* minimum subsystem version required to */
+ short MinorSubsystemVersion; /* run exe; default to 3.1 */
+ long Reserved1; /* seems to be 0 */
+ long SizeOfImage; /* size of memory to allocate for prog */
+ long SizeOfHeaders; /* size of PE header and section table */
+ long CheckSum; /* set to 0 */
+ short Subsystem;
+
+ /* type of subsystem exe uses for user interface,
+ possible values:
+ 1 - NATIVE Doesn't require a subsystem
+ 2 - WINDOWS_GUI runs in Windows GUI subsystem
+ 3 - WINDOWS_CUI runs in Windows char sub. (console app)
+ 5 - OS2_CUI runs in OS/2 character subsystem
+ 7 - POSIX_CUI runs in Posix character subsystem */
+ short DllCharacteristics; /* flags for DLL init, use 0 */
+ bfd_vma SizeOfStackReserve; /* amount of memory to reserve */
+ bfd_vma SizeOfStackCommit; /* amount of memory initially committed for
+ initial thread's stack, default is 0x1000 */
+ bfd_vma SizeOfHeapReserve; /* amount of virtual memory to reserve and */
+ bfd_vma SizeOfHeapCommit; /* commit, don't know what to defaut it to */
+ long LoaderFlags; /* can probably set to 0 */
+ long NumberOfRvaAndSizes; /* number of entries in next entry, 16 */
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+};
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+struct internal_aouthdr
+{
+ short magic; /* type of file */
+ short vstamp; /* version stamp */
+ bfd_vma tsize; /* text size in bytes, padded to FW bdry*/
+ bfd_vma dsize; /* initialized data " " */
+ bfd_vma bsize; /* uninitialized data " " */
+ bfd_vma entry; /* entry pt. */
+ bfd_vma text_start; /* base of text used for this file */
+ bfd_vma data_start; /* base of data used for this file */
+
+ /* i960 stuff */
+ unsigned long tagentries; /* number of tag entries to follow */
+
+ /* RS/6000 stuff */
+ unsigned long o_toc; /* address of TOC */
+ short o_snentry; /* section number for entry point */
+ short o_sntext; /* section number for text */
+ short o_sndata; /* section number for data */
+ short o_sntoc; /* section number for toc */
+ short o_snloader; /* section number for loader section */
+ short o_snbss; /* section number for bss */
+ short o_algntext; /* max alignment for text */
+ short o_algndata; /* max alignment for data */
+ short o_modtype; /* Module type field, 1R,RE,RO */
+ short o_cputype; /* Encoded CPU type */
+ unsigned long o_maxstack; /* max stack size allowed. */
+ unsigned long o_maxdata; /* max data size allowed. */
+
+ /* ECOFF stuff */
+ bfd_vma bss_start; /* Base of bss section. */
+ bfd_vma gp_value; /* GP register value. */
+ unsigned long gprmask; /* General registers used. */
+ unsigned long cprmask[4]; /* Coprocessor registers used. */
+ unsigned long fprmask; /* Floating pointer registers used. */
+
+ /* Apollo stuff */
+ long o_inlib; /* inlib data */
+ long o_sri; /* Static Resource Information */
+ long vid[2]; /* Version id */
+
+
+ struct internal_extra_pe_aouthdr pe;
+
+};
+
+/********************** STORAGE CLASSES **********************/
+
+/* This used to be defined as -1, but now n_sclass is unsigned. */
+#define C_EFCN 0xff /* physical end of function */
+#define C_NULL 0
+#define C_AUTO 1 /* automatic variable */
+#define C_EXT 2 /* external symbol */
+#define C_STAT 3 /* static */
+#define C_REG 4 /* register variable */
+#define C_EXTDEF 5 /* external definition */
+#define C_LABEL 6 /* label */
+#define C_ULABEL 7 /* undefined label */
+#define C_MOS 8 /* member of structure */
+#define C_ARG 9 /* function argument */
+#define C_STRTAG 10 /* structure tag */
+#define C_MOU 11 /* member of union */
+#define C_UNTAG 12 /* union tag */
+#define C_TPDEF 13 /* type definition */
+#define C_USTATIC 14 /* undefined static */
+#define C_ENTAG 15 /* enumeration tag */
+#define C_MOE 16 /* member of enumeration */
+#define C_REGPARM 17 /* register parameter */
+#define C_FIELD 18 /* bit field */
+#define C_AUTOARG 19 /* auto argument */
+#define C_LASTENT 20 /* dummy entry (end of block) */
+#define C_BLOCK 100 /* ".bb" or ".eb" */
+#define C_FCN 101 /* ".bf" or ".ef" */
+#define C_EOS 102 /* end of structure */
+#define C_FILE 103 /* file name */
+#define C_LINE 104 /* line # reformatted as symbol table entry */
+#define C_ALIAS 105 /* duplicate tag */
+#define C_HIDDEN 106 /* ext symbol in dmert public lib */
+
+#define C_WEAKEXT 127 /* weak symbol -- GNU extension */
+
+/* New storage classes for TIc80 */
+#define C_UEXT 19 /* Tentative external definition */
+#define C_STATLAB 20 /* Static load time label */
+#define C_EXTLAB 21 /* External load time label */
+#define C_SYSTEM 23 /* System Wide variable */
+
+/* New storage classes for WINDOWS_NT */
+#define C_SECTION 104 /* section name */
+#define C_NT_WEAK 105 /* weak external */
+
+ /* New storage classes for 80960 */
+
+/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */
+#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */
+
+#define C_SCALL 107 /* Procedure reachable via system call */
+#define C_LEAFEXT 108 /* External leaf */
+#define C_LEAFSTAT 113 /* Static leaf */
+#define C_OPTVAR 109 /* Optimized variable */
+#define C_DEFINE 110 /* Preprocessor #define */
+#define C_PRAGMA 111 /* Advice to compiler or linker */
+#define C_SEGMENT 112 /* 80960 segment name */
+
+ /* Storage classes for m88k */
+#define C_SHADOW 107 /* shadow symbol */
+#define C_VERSION 108 /* coff version symbol */
+
+ /* New storage classes for RS/6000 */
+#define C_HIDEXT 107 /* Un-named external symbol */
+#define C_BINCL 108 /* Marks beginning of include file */
+#define C_EINCL 109 /* Marks ending of include file */
+
+ /* storage classes for stab symbols for RS/6000 */
+#define C_GSYM (0x80)
+#define C_LSYM (0x81)
+#define C_PSYM (0x82)
+#define C_RSYM (0x83)
+#define C_RPSYM (0x84)
+#define C_STSYM (0x85)
+#define C_TCSYM (0x86)
+#define C_BCOMM (0x87)
+#define C_ECOML (0x88)
+#define C_ECOMM (0x89)
+#define C_DECL (0x8c)
+#define C_ENTRY (0x8d)
+#define C_FUN (0x8e)
+#define C_BSTAT (0x8f)
+#define C_ESTAT (0x90)
+
+/* Storage classes for Thumb symbols */
+#define C_THUMBEXT (128 + C_EXT) /* 130 */
+#define C_THUMBSTAT (128 + C_STAT) /* 131 */
+#define C_THUMBLABEL (128 + C_LABEL) /* 134 */
+#define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */
+#define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */
+
+/********************** SECTION HEADER **********************/
+
+#define SCNNMLEN (8)
+
+struct internal_scnhdr
+{
+ char s_name[SCNNMLEN]; /* section name */
+
+ /* Physical address, aliased s_nlib.
+ In the pei format, this field is the virtual section size
+ (the size of the section after being loaded int memory),
+ NOT the physical address. */
+ bfd_vma s_paddr;
+
+ bfd_vma s_vaddr; /* virtual address */
+ bfd_vma s_size; /* section size */
+ bfd_vma s_scnptr; /* file ptr to raw data for section */
+ bfd_vma s_relptr; /* file ptr to relocation */
+ bfd_vma s_lnnoptr; /* file ptr to line numbers */
+ unsigned long s_nreloc; /* number of relocation entries */
+ unsigned long s_nlnno; /* number of line number entries*/
+ long s_flags; /* flags */
+ long s_align; /* used on I960 */
+};
+
+/*
+ * s_flags "type"
+ */
+#define STYP_REG (0x0000) /* "regular": allocated, relocated, loaded */
+#define STYP_DSECT (0x0001) /* "dummy": relocated only*/
+#define STYP_NOLOAD (0x0002) /* "noload": allocated, relocated, not loaded */
+#define STYP_GROUP (0x0004) /* "grouped": formed of input sections */
+#define STYP_PAD (0x0008) /* "padding": not allocated, not relocated, loaded */
+#define STYP_COPY (0x0010) /* "copy": for decision function used by field update; not allocated, not relocated,
+ loaded; reloc & lineno entries processed normally */
+#define STYP_TEXT (0x0020) /* section contains text only */
+#define S_SHRSEG (0x0020) /* In 3b Update files (output of ogen), sections which appear in SHARED segments of the Pfile
+ will have the S_SHRSEG flag set by ogen, to inform dufr that updating 1 copy of the proc. will
+ update all process invocations. */
+#define STYP_DATA (0x0040) /* section contains data only */
+#define STYP_BSS (0x0080) /* section contains bss only */
+#define S_NEWFCN (0x0100) /* In a minimal file or an update file, a new function (as compared with a replaced function) */
+#define STYP_INFO (0x0200) /* comment: not allocated not relocated, not loaded */
+#define STYP_OVER (0x0400) /* overlay: relocated not allocated or loaded */
+#define STYP_LIB (0x0800) /* for .lib: same as INFO */
+#define STYP_MERGE (0x2000) /* merge section -- combines with text, data or bss sections only */
+#define STYP_REVERSE_PAD (0x4000) /* section will be padded with no-op instructions wherever padding is necessary and there is a
+
+ word of contiguous bytes
+ beginning on a word boundary. */
+
+#define STYP_LIT 0x8020 /* Literal data (like STYP_TEXT) */
+
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+
+struct internal_lineno
+{
+ union
+ {
+ long l_symndx; /* function name symbol index, iff l_lnno == 0*/
+ long l_paddr; /* (physical) address of line number */
+ } l_addr;
+ unsigned long l_lnno; /* line number */
+};
+
+/********************** SYMBOLS **********************/
+
+#define SYMNMLEN 8 /* # characters in a symbol name */
+#define FILNMLEN 14 /* # characters in a file name */
+#define DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct internal_syment
+{
+ union
+ {
+ char _n_name[SYMNMLEN]; /* old COFF version */
+ struct
+ {
+ long _n_zeroes; /* new == 0 */
+ long _n_offset; /* offset into string table */
+ } _n_n;
+ char *_n_nptr[2]; /* allows for overlaying */
+ } _n;
+ long n_value; /* value of symbol */
+ short n_scnum; /* section number */
+ unsigned short n_flags; /* copy of flags from filhdr */
+ unsigned short n_type; /* type and derived type */
+ unsigned char n_sclass; /* storage class */
+ unsigned char n_numaux; /* number of aux. entries */
+};
+
+#define n_name _n._n_name
+#define n_zeroes _n._n_n._n_zeroes
+#define n_offset _n._n_n._n_offset
+
+
+/* Relocatable symbols have number of the section in which they are defined,
+ or one of the following: */
+
+#define N_UNDEF ((short)0) /* undefined symbol */
+#define N_ABS ((short)-1) /* value of symbol is absolute */
+#define N_DEBUG ((short)-2) /* debugging symbol -- value is meaningless */
+#define N_TV ((short)-3) /* indicates symbol needs preload transfer vector */
+#define P_TV ((short)-4) /* indicates symbol needs postload transfer vector*/
+
+/*
+ * Type of a symbol, in low N bits of the word
+ */
+#define T_NULL 0
+#define T_VOID 1 /* function argument (only used by compiler) */
+#define T_CHAR 2 /* character */
+#define T_SHORT 3 /* short integer */
+#define T_INT 4 /* integer */
+#define T_LONG 5 /* long integer */
+#define T_FLOAT 6 /* floating point */
+#define T_DOUBLE 7 /* double word */
+#define T_STRUCT 8 /* structure */
+#define T_UNION 9 /* union */
+#define T_ENUM 10 /* enumeration */
+#define T_MOE 11 /* member of enumeration*/
+#define T_UCHAR 12 /* unsigned character */
+#define T_USHORT 13 /* unsigned short */
+#define T_UINT 14 /* unsigned integer */
+#define T_ULONG 15 /* unsigned long */
+#define T_LNGDBL 16 /* long double */
+
+/*
+ * derived types, in n_type
+*/
+#define DT_NON (0) /* no derived type */
+#define DT_PTR (1) /* pointer */
+#define DT_FCN (2) /* function */
+#define DT_ARY (3) /* array */
+
+#define BTYPE(x) ((x) & N_BTMASK)
+
+#define ISPTR(x) \
+ (((unsigned long) (x) & N_TMASK) == ((unsigned long) DT_PTR << N_BTSHFT))
+#define ISFCN(x) \
+ (((unsigned long) (x) & N_TMASK) == ((unsigned long) DT_FCN << N_BTSHFT))
+#define ISARY(x) \
+ (((unsigned long) (x) & N_TMASK) == ((unsigned long) DT_ARY << N_BTSHFT))
+#define ISTAG(x) \
+ ((x) == C_STRTAG || (x) == C_UNTAG || (x) == C_ENTAG)
+#define DECREF(x) \
+ ((((x) >> N_TSHIFT) & ~ N_BTMASK) | ((x) & N_BTMASK))
+
+union internal_auxent
+{
+ struct
+ {
+
+ union
+ {
+ long l; /* str, un, or enum tag indx */
+ struct coff_ptr_struct *p;
+ } x_tagndx;
+
+ union
+ {
+ struct
+ {
+ unsigned short x_lnno; /* declaration line number */
+ unsigned short x_size; /* str/union/array size */
+ } x_lnsz;
+ long x_fsize; /* size of function */
+ } x_misc;
+
+ union
+ {
+ struct
+ { /* if ISFCN, tag, or .bb */
+ long x_lnnoptr; /* ptr to fcn line # */
+ union
+ { /* entry ndx past block end */
+ long l;
+ struct coff_ptr_struct *p;
+ } x_endndx;
+ } x_fcn;
+
+ struct
+ { /* if ISARY, up to 4 dimen. */
+ unsigned short x_dimen[DIMNUM];
+ } x_ary;
+ } x_fcnary;
+
+ unsigned short x_tvndx; /* tv index */
+ } x_sym;
+
+ union
+ {
+ char x_fname[FILNMLEN];
+ struct
+ {
+ long x_zeroes;
+ long x_offset;
+ } x_n;
+ } x_file;
+
+ struct
+ {
+ long x_scnlen; /* section length */
+ unsigned short x_nreloc; /* # relocation entries */
+ unsigned short x_nlinno; /* # line numbers */
+ unsigned long x_checksum; /* section COMDAT checksum for PE */
+ unsigned short x_associated; /* COMDAT associated section index for PE */
+ unsigned char x_comdat; /* COMDAT selection number for PE */
+ } x_scn;
+
+ struct
+ {
+ long x_tvfill; /* tv fill value */
+ unsigned short x_tvlen; /* length of .tv */
+ unsigned short x_tvran[2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+ /******************************************
+ * RS/6000-specific auxent - last auxent for every external symbol
+ ******************************************/
+ struct
+ {
+ union
+ { /* csect length or enclosing csect */
+ long l;
+ struct coff_ptr_struct *p;
+ } x_scnlen;
+ long x_parmhash; /* parm type hash index */
+ unsigned short x_snhash; /* sect num with parm hash */
+ unsigned char x_smtyp; /* symbol align and type */
+ /* 0-4 - Log 2 of alignment */
+ /* 5-7 - symbol type */
+ unsigned char x_smclas; /* storage mapping class */
+ long x_stab; /* dbx stab info index */
+ unsigned short x_snstab; /* sect num with dbx stab */
+ } x_csect; /* csect definition information */
+
+/* x_smtyp values: */
+
+#define SMTYP_ALIGN(x) ((x) >> 3) /* log2 of alignment */
+#define SMTYP_SMTYP(x) ((x) & 0x7) /* symbol type */
+/* Symbol type values: */
+#define XTY_ER 0 /* External reference */
+#define XTY_SD 1 /* Csect definition */
+#define XTY_LD 2 /* Label definition */
+#define XTY_CM 3 /* .BSS */
+#define XTY_EM 4 /* Error message */
+#define XTY_US 5 /* "Reserved for internal use" */
+
+/* x_smclas values: */
+
+#define XMC_PR 0 /* Read-only program code */
+#define XMC_RO 1 /* Read-only constant */
+#define XMC_DB 2 /* Read-only debug dictionary table */
+#define XMC_TC 3 /* Read-write general TOC entry */
+#define XMC_UA 4 /* Read-write unclassified */
+#define XMC_RW 5 /* Read-write data */
+#define XMC_GL 6 /* Read-only global linkage */
+#define XMC_XO 7 /* Read-only extended operation */
+#define XMC_SV 8 /* Read-only supervisor call */
+#define XMC_BS 9 /* Read-write BSS */
+#define XMC_DS 10 /* Read-write descriptor csect */
+#define XMC_UC 11 /* Read-write unnamed Fortran common */
+#define XMC_TI 12 /* Read-only traceback index csect */
+#define XMC_TB 13 /* Read-only traceback table csect */
+/* 14 ??? */
+#define XMC_TC0 15 /* Read-write TOC anchor */
+#define XMC_TD 16 /* Read-write data in TOC */
+
+ /******************************************
+ * I960-specific *2nd* aux. entry formats
+ ******************************************/
+ struct
+ {
+ /* This is a very old typo that keeps getting propagated. */
+#define x_stdindx x_stindx
+ long x_stindx; /* sys. table entry */
+ } x_sc; /* system call entry */
+
+ struct
+ {
+ unsigned long x_balntry; /* BAL entry point */
+ } x_bal; /* BAL-callable function */
+
+ struct
+ {
+ unsigned long x_timestamp; /* time stamp */
+ char x_idstring[20]; /* producer identity string */
+ } x_ident; /* Producer ident info */
+
+};
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct internal_reloc
+{
+ bfd_vma r_vaddr; /* Virtual address of reference */
+ long r_symndx; /* Index into symbol table */
+ unsigned short r_type; /* Relocation type */
+ unsigned char r_size; /* Used by RS/6000 and ECOFF */
+ unsigned char r_extern; /* Used by ECOFF */
+ unsigned long r_offset; /* Used by Alpha ECOFF, SPARC, others */
+};
+
+#define R_RELBYTE 017
+#define R_RELWORD 020
+#define R_PCRBYTE 022
+#define R_PCRWORD 023
+#define R_PCRLONG 024
+
+#define R_DIR16 01
+#define R_DIR32 06
+#define R_PCLONG 020
+#define R_RELBYTE 017
+#define R_RELWORD 020
+#define R_IMAGEBASE 07
+
+
+#define R_PCR16L 128
+#define R_PCR26L 129
+#define R_VRT16 130
+#define R_HVRT16 131
+#define R_LVRT16 132
+#define R_VRT32 133
+#define R_RELLONG (0x11) /* Direct 32-bit relocation */
+#define R_IPRSHORT (0x18)
+#define R_IPRLONG (0x1a)
+#define R_GETSEG (0x1d)
+#define R_GETPA (0x1e)
+#define R_TAGWORD (0x1f)
+#define R_JUMPTARG 0x20 /* strange 29k 00xx00xx reloc */
+
+
+/* This reloc identifies mov.b instructions with a 16bit absolute
+ address. The linker tries to turn insns with this reloc into
+ an absolute 8-bit address. */
+#define R_MOV16B1 0x41
+
+/* This reloc identifies mov.b instructions which had a 16bit
+ absolute address which have been shortened into a 8-bit
+ absolute address. */
+#define R_MOV16B2 0x42
+
+/* This reloc identifies jmp insns with a 16bit target address;
+ the linker tries to turn these insns into bra insns with
+ an 8bit pc-relative target. */
+#define R_JMP1 0x43
+
+/* This reloc identifies a bra with an 8-bit pc-relative
+ target that was formerlly a jmp insn with a 16bit target. */
+#define R_JMP2 0x44
+
+/* ??? */
+#define R_RELLONG_NEG 0x45
+
+/* This reloc identifies jmp insns with a 24bit target address;
+ the linker tries to turn these insns into bra insns with
+ an 8bit pc-relative target. */
+#define R_JMPL1 0x46
+
+/* This reloc identifies a bra with an 8-bit pc-relative
+ target that was formerlly a jmp insn with a 24bit target. */
+#define R_JMPL2 0x47
+
+/* This reloc identifies mov.b instructions with a 24bit absolute
+ address. The linker tries to turn insns with this reloc into
+ an absolute 8-bit address. */
+
+#define R_MOV24B1 0x48
+
+/* This reloc identifies mov.b instructions which had a 24bit
+ absolute address which have been shortened into a 8-bit
+ absolute address. */
+#define R_MOV24B2 0x49
+
+/* An h8300 memory indirect jump/call. Forces the address of the jump/call
+ target into the function vector (in page zero), and the address of the
+ vector entry to be placed in the jump/call instruction. */
+#define R_MEM_INDIRECT 0x4a
+
+/* This reloc identifies a 16bit pc-relative branch target which was
+ shortened into an 8bit pc-relative branch target. */
+#define R_PCRWORD_B 0x4b
+
+/* This reloc identifies mov.[wl] instructions with a 32/24 bit
+ absolute address; the linker may turn this into a mov.[wl]
+ insn with a 16bit absolute address. */
+#define R_MOVL1 0x4c
+
+/* This reloc identifies mov.[wl] insns which formerlly had
+ a 32/24bit absolute address and how have a 16bit absolute address. */
+#define R_MOVL2 0x4d
+
+/* This reloc identifies a bCC:8 which will have it's condition
+ inverted and its target redirected to the target of the branch
+ in the following insn. */
+#define R_BCC_INV 0x4e
+
+/* This reloc identifies a jmp instruction that has been deleted. */
+#define R_JMP_DEL 0x4f
+
+/* Z8k modes */
+#define R_IMM16 0x01 /* 16 bit abs */
+#define R_JR 0x02 /* jr 8 bit disp */
+#define R_IMM4L 0x23 /* low nibble */
+#define R_IMM8 0x22 /* 8 bit abs */
+#define R_IMM32 R_RELLONG /* 32 bit abs */
+#define R_CALL R_DA /* Absolute address which could be a callr */
+#define R_JP R_DA /* Absolute address which could be a jp */
+#define R_REL16 0x04 /* 16 bit PC rel */
+#define R_CALLR 0x05 /* callr 12 bit disp */
+#define R_SEG 0x10 /* set if in segmented mode */
+#define R_IMM4H 0x24 /* high nibble */
+#define R_DISP7 0x25 /* djnz displacement */
+
+/* H8500 modes */
+
+#define R_H8500_IMM8 1 /* 8 bit immediate */
+#define R_H8500_IMM16 2 /* 16 bit immediate */
+#define R_H8500_PCREL8 3 /* 8 bit pcrel */
+#define R_H8500_PCREL16 4 /* 16 bit pcrel */
+#define R_H8500_HIGH8 5 /* high 8 bits of 24 bit address */
+#define R_H8500_LOW16 7 /* low 16 bits of 24 bit immediate */
+#define R_H8500_IMM24 6 /* 24 bit immediate */
+#define R_H8500_IMM32 8 /* 32 bit immediate */
+#define R_H8500_HIGH16 9 /* high 16 bits of 32 bit immediate */
+
+/* W65 modes */
+
+#define R_W65_ABS8 1 /* addr & 0xff */
+#define R_W65_ABS16 2 /* addr & 0xffff */
+#define R_W65_ABS24 3 /* addr & 0xffffff */
+
+#define R_W65_ABS8S8 4 /* (addr >> 8) & 0xff */
+#define R_W65_ABS8S16 5 /* (addr >> 16) & 0xff */
+
+#define R_W65_ABS16S8 6 /* (addr >> 8) & 0ffff */
+#define R_W65_ABS16S16 7 /* (addr >> 16) & 0ffff */
+
+#define R_W65_PCR8 8
+#define R_W65_PCR16 9
+
+#define R_W65_DP 10 /* direct page 8 bits only */
+
+#endif /* GNU_COFF_INTERNAL_H */
diff --git a/include/coff/m68k.h b/include/coff/m68k.h
new file mode 100644
index 00000000000..c9147ed01b5
--- /dev/null
+++ b/include/coff/m68k.h
@@ -0,0 +1,225 @@
+/*** coff information for M68K */
+
+#ifndef GNU_COFF_M68K_H
+#define GNU_COFF_M68K_H 1
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+/* Motorola 68000/68008/68010/68020 */
+#define MC68MAGIC 0520
+#define MC68KWRMAGIC 0520 /* writeable text segments */
+#define MC68TVMAGIC 0521
+#define MC68KROMAGIC 0521 /* readonly shareable text segments */
+#define MC68KPGMAGIC 0522 /* demand paged text segments */
+#define M68MAGIC 0210
+#define M68TVMAGIC 0211
+
+/* this is the magic of the Bull dpx/2 */
+#define MC68KBCSMAGIC 0526
+
+/* This is Lynx's all-platform magic number for executables. */
+
+#define LYNXCOFFMAGIC 0415
+
+#define OMAGIC M68MAGIC
+
+/* This intentionally does not include MC68KBCSMAGIC; it only includes
+ magic numbers which imply that names do not have underscores. */
+#define M68KBADMAG(x) (((x).f_magic!=MC68MAGIC) && ((x).f_magic!=MC68KWRMAGIC) && ((x).f_magic!=MC68TVMAGIC) && \
+ ((x).f_magic!=MC68KROMAGIC) && ((x).f_magic!=MC68KPGMAGIC) && ((x).f_magic!=M68MAGIC) && ((x).f_magic!=M68TVMAGIC) && ((x).f_magic!=LYNXCOFFMAGIC) )
+
+/* Magic numbers for the a.out header. */
+
+#define PAGEMAGICEXECSWAPPED 0407 /* executable (swapped) */
+#define PAGEMAGICPEXECSWAPPED 0410 /* pure executable (swapped) */
+#define PAGEMAGICPEXECTSHLIB 0443 /* pure executable (target shared library) */
+#define PAGEMAGICPEXECPAGED 0413 /* pure executable (paged) */
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+#ifdef M68K_COFF_OFFSET
+ char r_offset[4];
+#endif
+
+};
+
+
+#define RELOC struct external_reloc
+
+#ifdef M68K_COFF_OFFSET
+#define RELSZ 14
+#else
+#define RELSZ 10
+#endif
+
+#endif /* GNU_COFF_M68K_H */
diff --git a/include/coff/m88k.h b/include/coff/m88k.h
new file mode 100644
index 00000000000..e06eb4165ec
--- /dev/null
+++ b/include/coff/m88k.h
@@ -0,0 +1,219 @@
+/*** coff information for 88k bcs */
+
+/********************** FILE HEADER **********************/
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+#define MC88MAGIC 0540 /* 88k BCS executable */
+#define MC88DMAGIC 0541 /* DG/UX executable */
+#define MC88OMAGIC 0555 /* Object file */
+
+#define MC88BADMAG(x) (((x).f_magic!=MC88MAGIC) &&((x).f_magic!=MC88DMAGIC) && ((x).f_magic != MC88OMAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+#define PAGEMAGIC3 0414 /* Split i&d, zero mapped */
+#define PAGEMAGICBCS 0413
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+/* compute size of a header */
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr
+{
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[4]; /* number of relocation entries */
+ char s_nlnno[4]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 44
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno{
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+
+ char l_lnno[4];
+
+};
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+ char pad2[2];
+};
+
+
+
+
+#define N_BTMASK 017
+#define N_TMASK 060
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+
+/* Note that this isn't the same shape as other coffs */
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ /* 4 */
+ union {
+ char x_fsize[4]; /* size of function */
+ struct {
+ char x_lnno[4]; /* declaration line number */
+ char x_size[4]; /* str/union/array size */
+ } x_lnsz;
+ } x_misc;
+
+ /* 12 */
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ /* 20 */
+
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[4]; /* # relocation entries */
+ char x_nlinno[4]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+};
+
+#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *)ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#define PUT_FCN_LNNOPTR(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
+#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
+#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
+#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
+#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
+#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_nreloc)
+#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_nlinno)
+#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
+#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
+#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_32(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno))
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+
+
+#define SYMENT struct external_syment
+#define SYMESZ 20
+#define AUXENT union external_auxent
+#define AUXESZ 20
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+ char r_offset[2];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 12
+
+#define NO_TVNDX
diff --git a/include/coff/mcore.h b/include/coff/mcore.h
new file mode 100644
index 00000000000..974b62e1630
--- /dev/null
+++ b/include/coff/mcore.h
@@ -0,0 +1,245 @@
+/* Motorolla MCore support for BFD.
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the MCore COFF/PE ABI. */
+
+#ifndef _COFF_MORE_H
+#define _COFF_MORE_H
+
+
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+#define IMAGE_REL_MCORE_ABSOLUTE 0x0000
+#define IMAGE_REL_MCORE_ADDR32 0x0001
+#define IMAGE_REL_MCORE_PCREL_IMM8BY4 0x0002
+#define IMAGE_REL_MCORE_PCREL_IMM11BY2 0x0003
+#define IMAGE_REL_MCORE_PCREL_IMM4BY2 0x0004
+#define IMAGE_REL_MCORE_PCREL_32 0x0005
+#define IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2 0x0006
+
+#define PEMCORE
+
+typedef struct
+{
+ char magic [2]; /* type of file */
+ char vstamp [2]; /* version stamp */
+ char tsize [4]; /* text size in bytes, padded to FW bdry*/
+ char dsize [4]; /* initialized data " " */
+ char bsize [4]; /* uninitialized data " " */
+ char entry [4]; /* entry pt. */
+ char text_start [4]; /* base of text used for this file */
+ char data_start [4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+#define OMAGIC 0404 /* object files, eg as output */
+#define ZMAGIC 0413 /* demand load format, eg normal ld output */
+#define STMAGIC 0401 /* target shlib */
+#define SHMAGIC 0443 /* host shlib */
+
+/* From winnt.h */
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+
+
+/* Define some NT default values. */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT 0x200
+#define NT_DEF_RESERVE 0x100000
+#define NT_DEF_COMMIT 0x1000
+
+
+struct external_reloc
+{
+ char r_vaddr [4];
+ char r_symndx [4];
+ char r_type [2];
+ char r_offset [4];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 14
+
+#define MCOREMAGIC 0xb00 /* I just made this up */
+
+#define MCOREBADMAG(x) (((x).f_magic!= MCOREMAGIC))
+
+struct external_filehdr
+{
+ char f_magic [2]; /* magic number */
+ char f_nscns [2]; /* number of sections */
+ char f_timdat [4]; /* time & date stamp */
+ char f_symptr [4]; /* file pointer to symtab */
+ char f_nsyms [4]; /* number of symtab entries */
+ char f_opthdr [2]; /* sizeof(optional hdr) */
+ char f_flags [2]; /* flags */
+};
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union
+ {
+ char e_name [E_SYMNMLEN];
+ struct
+ {
+ char e_zeroes [4];
+ char e_offset [4];
+ } e;
+ } e;
+
+ char e_value [4];
+ char e_scnum [2];
+ char e_type [2];
+ char e_sclass [1];
+ char e_numaux [1];
+};
+
+#define N_BTMASK 0xf
+#define N_TMASK 0x30
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+union external_auxent
+{
+ struct
+ {
+ char x_tagndx [4]; /* str, un, or enum tag indx */
+
+ union
+ {
+ struct
+ {
+ char x_lnno [2]; /* declaration line number */
+ char x_size [2]; /* str/union/array size */
+ } x_lnsz;
+
+ char x_fsize [4]; /* size of function */
+
+ } x_misc;
+
+ union
+ {
+ struct /* if ISFCN, tag, or .bb */
+ {
+ char x_lnnoptr [4]; /* ptr to fcn line # */
+ char x_endndx [4]; /* entry ndx past block end */
+ } x_fcn;
+
+ struct /* if ISARY, up to 4 dimen. */
+ {
+ char x_dimen [E_DIMNUM][2];
+ } x_ary;
+
+ } x_fcnary;
+
+ char x_tvndx [2]; /* tv index */
+
+ } x_sym;
+
+ union
+ {
+ char x_fname [E_FILNMLEN];
+
+ struct
+ {
+ char x_zeroes [4];
+ char x_offset [4];
+ } x_n;
+
+ } x_file;
+
+ struct
+ {
+ char x_scnlen [4]; /* section length */
+ char x_nreloc [2]; /* # relocation entries */
+ char x_nlinno [2]; /* # line numbers */
+ char x_checksum [4]; /* section COMDAT checksum */
+ char x_associated [2]; /* COMDAT associated section index */
+ char x_comdat [1]; /* COMDAT selection number */
+ } x_scn;
+
+ struct
+ {
+ char x_tvfill [4]; /* tv fill value */
+ char x_tvlen [2]; /* length of .tv */
+ char x_tvran [2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ Line numbers are grouped on a per function basis; first entry in a function
+ grouping will have l_lnno = 0 and in place of physical address will be the
+ symbol table index of the function name. */
+struct external_lineno
+{
+ union
+ {
+ char l_symndx [4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr [4]; /* (physical) address of line number */
+ } l_addr;
+
+ char l_lnno [2]; /* line number */
+};
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32 (abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32 (abfd, val, (bfd_byte *) (ext->l_lnno));
+
+struct external_scnhdr
+{
+ char s_name [8]; /* section name */
+ char s_paddr [4]; /* physical address, aliased s_nlib */
+ char s_vaddr [4]; /* virtual address */
+ char s_size [4]; /* section size */
+ char s_scnptr [4]; /* file ptr to raw data for section */
+ char s_relptr [4]; /* file ptr to relocation */
+ char s_lnnoptr [4]; /* file ptr to line numbers */
+ char s_nreloc [2]; /* number of relocation entries */
+ char s_nlnno [2]; /* number of line number entries*/
+ char s_flags [4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/* Names of "special" sections. */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+
+#endif /* __COFF_MCORE_H */
diff --git a/include/coff/mips.h b/include/coff/mips.h
new file mode 100644
index 00000000000..d4665b1f396
--- /dev/null
+++ b/include/coff/mips.h
@@ -0,0 +1,369 @@
+/* ECOFF support on MIPS machines.
+ coff/ecoff.h must be included before this file. */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ unsigned char f_magic[2]; /* magic number */
+ unsigned char f_nscns[2]; /* number of sections */
+ unsigned char f_timdat[4]; /* time & date stamp */
+ unsigned char f_symptr[4]; /* file pointer to symtab */
+ unsigned char f_nsyms[4]; /* number of symtab entries */
+ unsigned char f_opthdr[2]; /* sizeof(optional hdr) */
+ unsigned char f_flags[2]; /* flags */
+};
+
+/* Magic numbers are defined in coff/ecoff.h. */
+#define MIPS_ECOFF_BADMAG(x) (((x).f_magic!=MIPS_MAGIC_1) && \
+ ((x).f_magic!=MIPS_MAGIC_LITTLE) &&\
+ ((x).f_magic!=MIPS_MAGIC_BIG) && \
+ ((x).f_magic!=MIPS_MAGIC_LITTLE2) && \
+ ((x).f_magic!=MIPS_MAGIC_BIG2) && \
+ ((x).f_magic!=MIPS_MAGIC_LITTLE3) && \
+ ((x).f_magic!=MIPS_MAGIC_BIG3))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct external_aouthdr
+{
+ unsigned char magic[2]; /* type of file */
+ unsigned char vstamp[2]; /* version stamp */
+ unsigned char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ unsigned char dsize[4]; /* initialized data " " */
+ unsigned char bsize[4]; /* uninitialized data " " */
+ unsigned char entry[4]; /* entry pt. */
+ unsigned char text_start[4]; /* base of text used for this file */
+ unsigned char data_start[4]; /* base of data used for this file */
+ unsigned char bss_start[4]; /* base of bss used for this file */
+ unsigned char gprmask[4]; /* ?? */
+ unsigned char cprmask[4][4]; /* ?? */
+ unsigned char gp_value[4]; /* value for gp register */
+} AOUTHDR;
+
+/* compute size of a header */
+
+#define AOUTSZ 56
+#define AOUTHDRSZ 56
+
+/********************** SECTION HEADER **********************/
+
+struct external_scnhdr {
+ unsigned char s_name[8]; /* section name */
+ unsigned char s_paddr[4]; /* physical address, aliased s_nlib */
+ unsigned char s_vaddr[4]; /* virtual address */
+ unsigned char s_size[4]; /* section size */
+ unsigned char s_scnptr[4]; /* file ptr to raw data for section */
+ unsigned char s_relptr[4]; /* file ptr to relocation */
+ unsigned char s_lnnoptr[4]; /* file ptr to line numbers */
+ unsigned char s_nreloc[2]; /* number of relocation entries */
+ unsigned char s_nlnno[2]; /* number of line number entries*/
+ unsigned char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ unsigned char r_vaddr[4];
+ unsigned char r_bits[4];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 8
+
+/* MIPS ECOFF uses a packed 8 byte format for relocs. These constants
+ are used to unpack the r_bits field. */
+
+#define RELOC_BITS0_SYMNDX_SH_LEFT_BIG 16
+#define RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE 0
+
+#define RELOC_BITS1_SYMNDX_SH_LEFT_BIG 8
+#define RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE 8
+
+#define RELOC_BITS2_SYMNDX_SH_LEFT_BIG 0
+#define RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE 16
+
+/* Originally, ECOFF used four bits for the reloc type and had three
+ reserved bits. Irix 4 added another bit for the reloc type, which
+ was easy because it was big endian and one of the spare bits became
+ the new most significant bit. To make this also work for little
+ endian ECOFF, we need to wrap one of the reserved bits around to
+ become the most significant bit of the reloc type. */
+#define RELOC_BITS3_TYPE_BIG 0x3E
+#define RELOC_BITS3_TYPE_SH_BIG 1
+#define RELOC_BITS3_TYPE_LITTLE 0x78
+#define RELOC_BITS3_TYPE_SH_LITTLE 3
+#define RELOC_BITS3_TYPEHI_LITTLE 0x04
+#define RELOC_BITS3_TYPEHI_SH_LITTLE 2
+
+#define RELOC_BITS3_EXTERN_BIG 0x01
+#define RELOC_BITS3_EXTERN_LITTLE 0x80
+
+/* The r_type field in a reloc is one of the following values. I
+ don't know if any other values can appear. These seem to be all
+ that occur in the Ultrix 4.2 libraries. */
+#define MIPS_R_IGNORE 0
+#define MIPS_R_REFHALF 1
+#define MIPS_R_REFWORD 2
+#define MIPS_R_JMPADDR 3
+#define MIPS_R_REFHI 4
+#define MIPS_R_REFLO 5
+#define MIPS_R_GPREL 6
+#define MIPS_R_LITERAL 7
+
+/* These reloc types are a Cygnus extension used when generating
+ position independent code for embedded systems. The numbers are
+ taken from Irix 4, but at least for internal relocs Irix 5 does not
+ give them the same meaning. For an internal reloc the symbol index
+ of RELHI and RELLO is modified as described below for
+ MIPS_R_SWITCH. */
+#define MIPS_R_PCREL16 12
+#define MIPS_R_RELHI 13
+#define MIPS_R_RELLO 14
+
+/* This reloc type is a Cygnus extension used when generating position
+ independent code for embedded systems. It is used for an entry in
+ a switch table, which looks like this:
+ .word $L3-$LS12
+ The object file will contain the correct difference, and does not
+ require adjustment. However, when the linker is relaxing PC
+ relative calls, it is possible for $L3 to move farther away. This
+ reloc always appears in the .text section, and is always against
+ the .text section. However, the symbol index is not
+ RELOC_SECTION_TEXT. It is, instead, the distance between this
+ switch table entry and $LS12. Thus, the original value of $L12 is
+ vaddr - symndx
+ and the original value of $L3 is
+ vaddr - symndx + addend
+ where addend is the value in the object file. Knowing this, the
+ linker can know whether the addend in the object file must be
+ adjusted. */
+#define MIPS_R_SWITCH 22
+
+/********************** STABS **********************/
+
+#define MIPS_IS_STAB ECOFF_IS_STAB
+#define MIPS_MARK_STAB ECOFF_MARK_STAB
+#define MIPS_UNMARK_STAB ECOFF_UNMARK_STAB
+
+/********************** SYMBOLIC INFORMATION **********************/
+
+/* Written by John Gilmore. */
+
+/* ECOFF uses COFF-like section structures, but its own symbol format.
+ This file defines the symbol format in fields whose size and alignment
+ will not vary on different host systems. */
+
+/* File header as a set of bytes */
+
+struct hdr_ext {
+ unsigned char h_magic[2];
+ unsigned char h_vstamp[2];
+ unsigned char h_ilineMax[4];
+ unsigned char h_cbLine[4];
+ unsigned char h_cbLineOffset[4];
+ unsigned char h_idnMax[4];
+ unsigned char h_cbDnOffset[4];
+ unsigned char h_ipdMax[4];
+ unsigned char h_cbPdOffset[4];
+ unsigned char h_isymMax[4];
+ unsigned char h_cbSymOffset[4];
+ unsigned char h_ioptMax[4];
+ unsigned char h_cbOptOffset[4];
+ unsigned char h_iauxMax[4];
+ unsigned char h_cbAuxOffset[4];
+ unsigned char h_issMax[4];
+ unsigned char h_cbSsOffset[4];
+ unsigned char h_issExtMax[4];
+ unsigned char h_cbSsExtOffset[4];
+ unsigned char h_ifdMax[4];
+ unsigned char h_cbFdOffset[4];
+ unsigned char h_crfd[4];
+ unsigned char h_cbRfdOffset[4];
+ unsigned char h_iextMax[4];
+ unsigned char h_cbExtOffset[4];
+};
+
+/* File descriptor external record */
+
+struct fdr_ext {
+ unsigned char f_adr[4];
+ unsigned char f_rss[4];
+ unsigned char f_issBase[4];
+ unsigned char f_cbSs[4];
+ unsigned char f_isymBase[4];
+ unsigned char f_csym[4];
+ unsigned char f_ilineBase[4];
+ unsigned char f_cline[4];
+ unsigned char f_ioptBase[4];
+ unsigned char f_copt[4];
+ unsigned char f_ipdFirst[2];
+ unsigned char f_cpd[2];
+ unsigned char f_iauxBase[4];
+ unsigned char f_caux[4];
+ unsigned char f_rfdBase[4];
+ unsigned char f_crfd[4];
+ unsigned char f_bits1[1];
+ unsigned char f_bits2[3];
+ unsigned char f_cbLineOffset[4];
+ unsigned char f_cbLine[4];
+};
+
+#define FDR_BITS1_LANG_BIG 0xF8
+#define FDR_BITS1_LANG_SH_BIG 3
+#define FDR_BITS1_LANG_LITTLE 0x1F
+#define FDR_BITS1_LANG_SH_LITTLE 0
+
+#define FDR_BITS1_FMERGE_BIG 0x04
+#define FDR_BITS1_FMERGE_LITTLE 0x20
+
+#define FDR_BITS1_FREADIN_BIG 0x02
+#define FDR_BITS1_FREADIN_LITTLE 0x40
+
+#define FDR_BITS1_FBIGENDIAN_BIG 0x01
+#define FDR_BITS1_FBIGENDIAN_LITTLE 0x80
+
+#define FDR_BITS2_GLEVEL_BIG 0xC0
+#define FDR_BITS2_GLEVEL_SH_BIG 6
+#define FDR_BITS2_GLEVEL_LITTLE 0x03
+#define FDR_BITS2_GLEVEL_SH_LITTLE 0
+
+/* We ignore the `reserved' field in bits2. */
+
+/* Procedure descriptor external record */
+
+struct pdr_ext {
+ unsigned char p_adr[4];
+ unsigned char p_isym[4];
+ unsigned char p_iline[4];
+ unsigned char p_regmask[4];
+ unsigned char p_regoffset[4];
+ unsigned char p_iopt[4];
+ unsigned char p_fregmask[4];
+ unsigned char p_fregoffset[4];
+ unsigned char p_frameoffset[4];
+ unsigned char p_framereg[2];
+ unsigned char p_pcreg[2];
+ unsigned char p_lnLow[4];
+ unsigned char p_lnHigh[4];
+ unsigned char p_cbLineOffset[4];
+};
+
+/* Runtime procedure table */
+
+struct rpdr_ext {
+ unsigned char p_adr[4];
+ unsigned char p_regmask[4];
+ unsigned char p_regoffset[4];
+ unsigned char p_fregmask[4];
+ unsigned char p_fregoffset[4];
+ unsigned char p_frameoffset[4];
+ unsigned char p_framereg[2];
+ unsigned char p_pcreg[2];
+ unsigned char p_irpss[4];
+ unsigned char p_reserved[4];
+ unsigned char p_exception_info[4];
+};
+
+/* Line numbers */
+
+struct line_ext {
+ unsigned char l_line[4];
+};
+
+/* Symbol external record */
+
+struct sym_ext {
+ unsigned char s_iss[4];
+ unsigned char s_value[4];
+ unsigned char s_bits1[1];
+ unsigned char s_bits2[1];
+ unsigned char s_bits3[1];
+ unsigned char s_bits4[1];
+};
+
+#define SYM_BITS1_ST_BIG 0xFC
+#define SYM_BITS1_ST_SH_BIG 2
+#define SYM_BITS1_ST_LITTLE 0x3F
+#define SYM_BITS1_ST_SH_LITTLE 0
+
+#define SYM_BITS1_SC_BIG 0x03
+#define SYM_BITS1_SC_SH_LEFT_BIG 3
+#define SYM_BITS1_SC_LITTLE 0xC0
+#define SYM_BITS1_SC_SH_LITTLE 6
+
+#define SYM_BITS2_SC_BIG 0xE0
+#define SYM_BITS2_SC_SH_BIG 5
+#define SYM_BITS2_SC_LITTLE 0x07
+#define SYM_BITS2_SC_SH_LEFT_LITTLE 2
+
+#define SYM_BITS2_RESERVED_BIG 0x10
+#define SYM_BITS2_RESERVED_LITTLE 0x08
+
+#define SYM_BITS2_INDEX_BIG 0x0F
+#define SYM_BITS2_INDEX_SH_LEFT_BIG 16
+#define SYM_BITS2_INDEX_LITTLE 0xF0
+#define SYM_BITS2_INDEX_SH_LITTLE 4
+
+#define SYM_BITS3_INDEX_SH_LEFT_BIG 8
+#define SYM_BITS3_INDEX_SH_LEFT_LITTLE 4
+
+#define SYM_BITS4_INDEX_SH_LEFT_BIG 0
+#define SYM_BITS4_INDEX_SH_LEFT_LITTLE 12
+
+/* External symbol external record */
+
+struct ext_ext {
+ unsigned char es_bits1[1];
+ unsigned char es_bits2[1];
+ unsigned char es_ifd[2];
+ struct sym_ext es_asym;
+};
+
+#define EXT_BITS1_JMPTBL_BIG 0x80
+#define EXT_BITS1_JMPTBL_LITTLE 0x01
+
+#define EXT_BITS1_COBOL_MAIN_BIG 0x40
+#define EXT_BITS1_COBOL_MAIN_LITTLE 0x02
+
+#define EXT_BITS1_WEAKEXT_BIG 0x20
+#define EXT_BITS1_WEAKEXT_LITTLE 0x04
+
+/* Dense numbers external record */
+
+struct dnr_ext {
+ unsigned char d_rfd[4];
+ unsigned char d_index[4];
+};
+
+/* Relative file descriptor */
+
+struct rfd_ext {
+ unsigned char rfd[4];
+};
+
+/* Optimizer symbol external record */
+
+struct opt_ext {
+ unsigned char o_bits1[1];
+ unsigned char o_bits2[1];
+ unsigned char o_bits3[1];
+ unsigned char o_bits4[1];
+ struct rndx_ext o_rndx;
+ unsigned char o_offset[4];
+};
+
+#define OPT_BITS2_VALUE_SH_LEFT_BIG 16
+#define OPT_BITS2_VALUE_SH_LEFT_LITTLE 0
+
+#define OPT_BITS3_VALUE_SH_LEFT_BIG 8
+#define OPT_BITS3_VALUE_SH_LEFT_LITTLE 8
+
+#define OPT_BITS4_VALUE_SH_LEFT_BIG 0
+#define OPT_BITS4_VALUE_SH_LEFT_LITTLE 16
diff --git a/include/coff/pe.h b/include/coff/pe.h
new file mode 100644
index 00000000000..7e676a50882
--- /dev/null
+++ b/include/coff/pe.h
@@ -0,0 +1,169 @@
+/* PE COFF header information */
+
+#ifndef _PE_H
+#define _PE_H
+
+/* NT specific file attributes */
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+/* additional flags to be set for section headers to allow the NT loader to
+ read and write to the section data (to replace the addresses of data in
+ dlls for one thing); also to execute the section in .text's case */
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+/*
+ * Section characteristics added for ppc-nt
+ */
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
+#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
+
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
+#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
+
+/* COMDAT selection codes. */
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
+#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
+#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
+
+/* Magic values that are true for all dos/nt implementations */
+#define DOSMAGIC 0x5a4d
+#define NT_SIGNATURE 0x00004550
+
+ /* NT allows long filenames, we want to accommodate this. This may break
+ some of the bfd functions */
+#undef FILNMLEN
+#define FILNMLEN 18 /* # characters in a file name */
+
+
+#ifdef COFF_IMAGE_WITH_PE
+/* The filehdr is only weired in images */
+
+#undef FILHDR
+struct external_PE_filehdr
+{
+ /* DOS header fields */
+ char e_magic[2]; /* Magic number, 0x5a4d */
+ char e_cblp[2]; /* Bytes on last page of file, 0x90 */
+ char e_cp[2]; /* Pages in file, 0x3 */
+ char e_crlc[2]; /* Relocations, 0x0 */
+ char e_cparhdr[2]; /* Size of header in paragraphs, 0x4 */
+ char e_minalloc[2]; /* Minimum extra paragraphs needed, 0x0 */
+ char e_maxalloc[2]; /* Maximum extra paragraphs needed, 0xFFFF */
+ char e_ss[2]; /* Initial (relative) SS value, 0x0 */
+ char e_sp[2]; /* Initial SP value, 0xb8 */
+ char e_csum[2]; /* Checksum, 0x0 */
+ char e_ip[2]; /* Initial IP value, 0x0 */
+ char e_cs[2]; /* Initial (relative) CS value, 0x0 */
+ char e_lfarlc[2]; /* File address of relocation table, 0x40 */
+ char e_ovno[2]; /* Overlay number, 0x0 */
+ char e_res[4][2]; /* Reserved words, all 0x0 */
+ char e_oemid[2]; /* OEM identifier (for e_oeminfo), 0x0 */
+ char e_oeminfo[2]; /* OEM information; e_oemid specific, 0x0 */
+ char e_res2[10][2]; /* Reserved words, all 0x0 */
+ char e_lfanew[4]; /* File address of new exe header, 0x80 */
+ char dos_message[16][4]; /* other stuff, always follow DOS header */
+ char nt_signature[4]; /* required NT signature, 0x4550 */
+
+ /* From standard header */
+
+
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+
+};
+
+
+#define FILHDR struct external_PE_filehdr
+#undef FILHSZ
+#define FILHSZ 152
+
+#endif
+
+typedef struct
+{
+ AOUTHDR standard;
+
+ /* NT extra fields; see internal.h for descriptions */
+ char ImageBase[4];
+ char SectionAlignment[4];
+ char FileAlignment[4];
+ char MajorOperatingSystemVersion[2];
+ char MinorOperatingSystemVersion[2];
+ char MajorImageVersion[2];
+ char MinorImageVersion[2];
+ char MajorSubsystemVersion[2];
+ char MinorSubsystemVersion[2];
+ char Reserved1[4];
+ char SizeOfImage[4];
+ char SizeOfHeaders[4];
+ char CheckSum[4];
+ char Subsystem[2];
+ char DllCharacteristics[2];
+ char SizeOfStackReserve[4];
+ char SizeOfStackCommit[4];
+ char SizeOfHeapReserve[4];
+ char SizeOfHeapCommit[4];
+ char LoaderFlags[4];
+ char NumberOfRvaAndSizes[4];
+ /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
+ char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
+
+} PEAOUTHDR;
+
+
+#undef AOUTSZ
+#define AOUTSZ (AOUTHDRSZ + 196)
+
+#undef E_FILNMLEN
+#define E_FILNMLEN 18 /* # characters in a file name */
+#endif
+
+
+
diff --git a/include/coff/powerpc.h b/include/coff/powerpc.h
new file mode 100644
index 00000000000..9552cf9f45e
--- /dev/null
+++ b/include/coff/powerpc.h
@@ -0,0 +1,199 @@
+/* Basic coff information for the PowerPC
+ *
+ * Based on coff/rs6000.h, coff/i386.h and others.
+ *
+ * Initial release: Kim Knuttila (krk@cygnus.com)
+ */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+
+/* extra NT defines */
+#define PPCMAGIC 0760 /* peeked on aa PowerPC Windows NT box */
+#define DOSMAGIC 0x5a4d /* from arm.h, i386.h */
+#define NT_SIGNATURE 0x00004550 /* from arm.h, i386.h */
+
+/* from winnt.h */
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+
+#define PPCBADMAG(x) ((x).f_magic != PPCMAGIC)
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+/********************** SECTION HEADER **********************/
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries */
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+#define _LIB ".lib"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0 */
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+
+/* Allow the file name length to be overridden in the including file */
+#ifndef E_FILNMLEN
+#define E_FILNMLEN 14
+#endif
+
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ char x_checksum[4]; /* section COMDAT checksum */
+ char x_associated[2]; /* COMDAT associated section index */
+ char x_comdat[1]; /* COMDAT selection number */
+ } x_scn;
+};
+
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+#define _ETEXT "etext"
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
diff --git a/include/coff/rs6000.h b/include/coff/rs6000.h
new file mode 100644
index 00000000000..0def1d95d15
--- /dev/null
+++ b/include/coff/rs6000.h
@@ -0,0 +1,243 @@
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+ Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+ FIXME: Can someone provide a transliteration of this name into ASCII?
+ Using the following chars caused a compiler warning on HIUX (so I replaced
+ them with octal escapes), and isn't useful without an understanding of what
+ character set it is.
+ Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+ and John Gilmore of Cygnus Support. */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+ /* IBM RS/6000 */
+#define U802WRMAGIC 0730 /* writeable text segments **chh** */
+#define U802ROMAGIC 0735 /* readonly sharable text segments */
+#define U802TOCMAGIC 0737 /* readonly text segments and TOC */
+
+#define BADMAG(x) \
+ ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+ (x).f_magic != U802TOCMAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ unsigned char magic[2]; /* type of file */
+ unsigned char vstamp[2]; /* version stamp */
+ unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */
+ unsigned char dsize[4]; /* initialized data " " */
+ unsigned char bsize[4]; /* uninitialized data " " */
+ unsigned char entry[4]; /* entry pt. */
+ unsigned char text_start[4]; /* base of text used for this file */
+ unsigned char data_start[4]; /* base of data used for this file */
+ unsigned char o_toc[4]; /* address of TOC */
+ unsigned char o_snentry[2]; /* section number of entry point */
+ unsigned char o_sntext[2]; /* section number of .text section */
+ unsigned char o_sndata[2]; /* section number of .data section */
+ unsigned char o_sntoc[2]; /* section number of TOC */
+ unsigned char o_snloader[2]; /* section number of .loader section */
+ unsigned char o_snbss[2]; /* section number of .bss section */
+ unsigned char o_algntext[2]; /* .text alignment */
+ unsigned char o_algndata[2]; /* .data alignment */
+ unsigned char o_modtype[2]; /* module type (??) */
+ unsigned char o_cputype[2]; /* cpu type */
+ unsigned char o_maxstack[4]; /* max stack size (??) */
+ unsigned char o_maxdata[4]; /* max data size (??) */
+ unsigned char o_resv2[12]; /* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */
+#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */
+#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _PAD ".pad"
+#define _LOADER ".loader"
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER. */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG. */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+ another section header with STYP_OVRFLO set. */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+ struct {
+ unsigned char x_scnlen[4];
+ unsigned char x_parmhash[4];
+ unsigned char x_snhash[2];
+ unsigned char x_smtyp[1];
+ unsigned char x_smclas[1];
+ unsigned char x_stab[4];
+ unsigned char x_snstab[2];
+ } x_csect;
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+#define DBXMASK 0x80 /* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_size[1];
+ char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4
diff --git a/include/coff/sh.h b/include/coff/sh.h
new file mode 100644
index 00000000000..41957df7f93
--- /dev/null
+++ b/include/coff/sh.h
@@ -0,0 +1,269 @@
+/*** coff information for Hitachi SH */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+
+#define SH_ARCH_MAGIC_BIG 0x0500
+#define SH_ARCH_MAGIC_LITTLE 0x0550 /* Little endian SH */
+
+
+#define SHBADMAG(x) \
+ (((x).f_magic!=SH_ARCH_MAGIC_BIG) && \
+ ((x).f_magic!=SH_ARCH_MAGIC_LITTLE))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[4]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the h8 don't have room in the instruction for the entire
+ offset - eg the strange jump and high page addressing modes */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
+/* SH relocation types. Not all of these are actually used. */
+
+#define R_SH_UNUSED 0 /* only used internally */
+#define R_SH_PCREL8 3 /* 8 bit pcrel */
+#define R_SH_PCREL16 4 /* 16 bit pcrel */
+#define R_SH_HIGH8 5 /* high 8 bits of 24 bit address */
+#define R_SH_LOW16 7 /* low 16 bits of 24 bit immediate */
+#define R_SH_IMM24 6 /* 24 bit immediate */
+#define R_SH_PCDISP8BY4 9 /* PC rel 8 bits *4 +ve */
+#define R_SH_PCDISP8BY2 10 /* PC rel 8 bits *2 +ve */
+#define R_SH_PCDISP8 11 /* 8 bit branch */
+#define R_SH_PCDISP 12 /* 12 bit branch */
+#define R_SH_IMM32 14 /* 32 bit immediate */
+#define R_SH_IMM8 16 /* 8 bit immediate */
+#define R_SH_IMM8BY2 17 /* 8 bit immediate *2 */
+#define R_SH_IMM8BY4 18 /* 8 bit immediate *4 */
+#define R_SH_IMM4 19 /* 4 bit immediate */
+#define R_SH_IMM4BY2 20 /* 4 bit immediate *2 */
+#define R_SH_IMM4BY4 21 /* 4 bit immediate *4 */
+#define R_SH_PCRELIMM8BY2 22 /* PC rel 8 bits *2 unsigned */
+#define R_SH_PCRELIMM8BY4 23 /* PC rel 8 bits *4 unsigned */
+#define R_SH_IMM16 24 /* 16 bit immediate */
+
+/* The switch table reloc types are used for relaxing. They are
+ generated for expressions such as
+ .word L1 - L2
+ The r_offset field holds the difference between the reloc address
+ and L2. */
+#define R_SH_SWITCH8 33 /* 8 bit switch table entry */
+#define R_SH_SWITCH16 25 /* 16 bit switch table entry */
+#define R_SH_SWITCH32 26 /* 32 bit switch table entry */
+
+/* The USES reloc type is used for relaxing. The compiler will
+ generate .uses pseudo-ops when it finds a function call which it
+ can relax. The r_offset field of the USES reloc holds the PC
+ relative offset to the instruction which loads the register used in
+ the function call. */
+#define R_SH_USES 27 /* .uses pseudo-op */
+
+/* The COUNT reloc type is used for relaxing. The assembler will
+ generate COUNT relocs for addresses referred to by the register
+ loads associated with USES relocs. The r_offset field of the COUNT
+ reloc holds the number of times the address is referenced in the
+ object file. */
+#define R_SH_COUNT 28 /* Count of constant pool uses */
+
+/* The ALIGN reloc type is used for relaxing. The r_offset field is
+ the power of two to which subsequent portions of the object file
+ must be aligned. */
+#define R_SH_ALIGN 29 /* .align pseudo-op */
+
+/* The CODE and DATA reloc types are used for aligning load and store
+ instructions. The assembler will generate a CODE reloc before a
+ block of instructions. It will generate a DATA reloc before data.
+ A section should be processed assuming it contains data, unless a
+ CODE reloc is seen. The only relevant pieces of information in the
+ CODE and DATA relocs are the section and the address. The symbol
+ and offset are meaningless. */
+#define R_SH_CODE 30 /* start of code */
+#define R_SH_DATA 31 /* start of data */
+
+/* The LABEL reloc type is used for aligning load and store
+ instructions. The assembler will generate a LABEL reloc for each
+ label within a block of instructions. This permits the linker to
+ avoid swapping instructions which are the targets of branches. */
+#define R_SH_LABEL 32 /* label */
+
+/* NB: R_SH_SWITCH8 is 33 */
diff --git a/include/coff/sparc.h b/include/coff/sparc.h
new file mode 100644
index 00000000000..82a24f01e7a
--- /dev/null
+++ b/include/coff/sparc.h
@@ -0,0 +1,210 @@
+/*** coff information for Sparc. */
+
+/* This file is an amalgamation of several standard include files that
+ define coff format, such as filehdr.h, aouthdr.h, and so forth. In
+ addition, all datatypes have been translated into character arrays of
+ (presumed) equivalent size. This is necessary so that this file can
+ be used with different systems while still yielding the same results. */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr
+{
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+#define F_RELFLG (0x0001) /* relocation info stripped */
+#define F_EXEC (0x0002) /* file is executable */
+#define F_LNNO (0x0004) /* line numbers stripped */
+#define F_LSYMS (0x0008) /* local symbols stripped */
+
+#define SPARCMAGIC (0540)
+
+/* This is Lynx's all-platform magic number for executables. */
+
+#define LYNXCOFFMAGIC (0415)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+#define OMAGIC 0404 /* object files, eg as output */
+#define ZMAGIC 0413 /* demand load format, eg normal ld output */
+#define STMAGIC 0401 /* target shlib */
+#define SHMAGIC 0443 /* host shlib */
+
+/********************** SECTION HEADER **********************/
+
+struct external_scnhdr
+{
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/* Names of "special" sections. */
+
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _TV ".tv"
+#define _INIT ".init"
+#define _FINI ".fini"
+#define _COMMENT ".comment"
+#define _LIB ".lib"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ Line numbers are grouped on a per function basis; first entry in a function
+ grouping will have l_lnno = 0 and in place of physical address will be the
+ symbol table index of the function name. */
+
+struct external_lineno
+{
+ union {
+ char l_symndx[4]; /* fn name symbol index, iff l_lnno == 0 */
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+#define LINENO struct external_lineno
+#define LINESZ (6)
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN (8) /* # characters in a symbol name */
+#define E_FILNMLEN (14) /* # characters in a file name */
+#define E_DIMNUM (4) /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+#if 0 /* of doubtful value */
+ char e_nptr[2][4];
+ struct {
+ char e_leading_zero[1];
+ char e_dbx_type[1];
+ char e_dbx_desc[2];
+ } e_dbx;
+#endif
+ } e;
+
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+ char padding[2];
+};
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent
+{
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* .tv section info (in auxent of sym .tv)) */
+
+ char x_fill[20]; /* forces to 20-byte size */
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 20
+#define AUXENT union external_auxent
+#define AUXESZ 20
+
+#define _ETEXT "etext"
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+ char r_spare[2];
+ char r_offset[4];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
diff --git a/include/coff/sym.h b/include/coff/sym.h
new file mode 100644
index 00000000000..76204af59ad
--- /dev/null
+++ b/include/coff/sym.h
@@ -0,0 +1,484 @@
+/* Declarations of internal format of MIPS ECOFF symbols.
+ Originally contributed by MIPS Computer Systems and Third Eye Software.
+ Changes contributed by Cygnus Support are in the public domain.
+
+ This file is just aggregated with the files that make up the GNU
+ release; it is not considered part of GAS, GDB, or other GNU
+ programs. */
+
+/*
+ * |-----------------------------------------------------------|
+ * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
+ * | MIPS Computer Systems, Inc. grants reproduction and use |
+ * | rights to all parties, PROVIDED that this comment is |
+ * | maintained in the copy. |
+ * |-----------------------------------------------------------|
+ */
+#ifndef _SYM_H
+#define _SYM_H
+
+/* (C) Copyright 1984 by Third Eye Software, Inc.
+ *
+ * Third Eye Software, Inc. grants reproduction and use rights to
+ * all parties, PROVIDED that this comment is maintained in the copy.
+ *
+ * Third Eye makes no claims about the applicability of this
+ * symbol table to a particular use.
+ */
+
+/*
+ * This file contains the definition of the Third Eye Symbol Table.
+ *
+ * Symbols are assumed to be in 'encounter order' - i.e. the order that
+ * the things they represent were encountered by the compiler/assembler/loader.
+ * EXCEPT for globals! These are assumed to be bunched together,
+ * probably right after the last 'normal' symbol. Globals ARE sorted
+ * in ascending order.
+ *
+ * -----------------------------------------------------------------------
+ * A brief word about Third Eye naming/use conventions:
+ *
+ * All arrays and index's are 0 based.
+ * All "ifooMax" values are the highest legal value PLUS ONE. This makes
+ * them good for allocating arrays, etc. All checks are "ifoo < ifooMax".
+ *
+ * "isym" Index into the SYMbol table.
+ * "ipd" Index into the Procedure Descriptor array.
+ * "ifd" Index into the File Descriptor array.
+ * "iss" Index into String Space.
+ * "cb" Count of Bytes.
+ * "rgPd" array whose domain is "0..ipdMax-1" and RanGe is PDR.
+ * "rgFd" array whose domain is "0..ifdMax-1" and RanGe is FDR.
+ */
+
+
+/*
+ * Symbolic Header (HDR) structure.
+ * As long as all the pointers are set correctly,
+ * we don't care WHAT order the various sections come out in!
+ *
+ * A file produced solely for the use of CDB will probably NOT have
+ * any instructions or data areas in it, as these are available
+ * in the original.
+ */
+
+typedef struct {
+ short magic; /* to verify validity of the table */
+ short vstamp; /* version stamp */
+ long ilineMax; /* number of line number entries */
+ bfd_vma cbLine; /* number of bytes for line number entries */
+ bfd_vma cbLineOffset; /* offset to start of line number entries*/
+ long idnMax; /* max index into dense number table */
+ bfd_vma cbDnOffset; /* offset to start dense number table */
+ long ipdMax; /* number of procedures */
+ bfd_vma cbPdOffset; /* offset to procedure descriptor table */
+ long isymMax; /* number of local symbols */
+ bfd_vma cbSymOffset; /* offset to start of local symbols*/
+ long ioptMax; /* max index into optimization symbol entries */
+ bfd_vma cbOptOffset; /* offset to optimization symbol entries */
+ long iauxMax; /* number of auxillary symbol entries */
+ bfd_vma cbAuxOffset; /* offset to start of auxillary symbol entries*/
+ long issMax; /* max index into local strings */
+ bfd_vma cbSsOffset; /* offset to start of local strings */
+ long issExtMax; /* max index into external strings */
+ bfd_vma cbSsExtOffset; /* offset to start of external strings */
+ long ifdMax; /* number of file descriptor entries */
+ bfd_vma cbFdOffset; /* offset to file descriptor table */
+ long crfd; /* number of relative file descriptor entries */
+ bfd_vma cbRfdOffset; /* offset to relative file descriptor table */
+ long iextMax; /* max index into external symbols */
+ bfd_vma cbExtOffset; /* offset to start of external symbol entries*/
+ /* If you add machine dependent fields, add them here */
+ } HDRR, *pHDRR;
+#define cbHDRR sizeof(HDRR)
+#define hdrNil ((pHDRR)0)
+
+/*
+ * The FDR and PDR structures speed mapping of address <-> name.
+ * They are sorted in ascending memory order and are kept in
+ * memory by CDB at runtime.
+ */
+
+/*
+ * File Descriptor
+ *
+ * There is one of these for EVERY FILE, whether compiled with
+ * full debugging symbols or not. The name of a file should be
+ * the path name given to the compiler. This allows the user
+ * to simply specify the names of the directories where the COMPILES
+ * were done, and we will be able to find their files.
+ * A field whose comment starts with "R - " indicates that it will be
+ * setup at runtime.
+ */
+typedef struct fdr {
+ bfd_vma adr; /* memory address of beginning of file */
+ long rss; /* file name (of source, if known) */
+ long issBase; /* file's string space */
+ bfd_vma cbSs; /* number of bytes in the ss */
+ long isymBase; /* beginning of symbols */
+ long csym; /* count file's of symbols */
+ long ilineBase; /* file's line symbols */
+ long cline; /* count of file's line symbols */
+ long ioptBase; /* file's optimization entries */
+ long copt; /* count of file's optimization entries */
+ unsigned short ipdFirst;/* start of procedures for this file */
+ short cpd; /* count of procedures for this file */
+ long iauxBase; /* file's auxiliary entries */
+ long caux; /* count of file's auxiliary entries */
+ long rfdBase; /* index into the file indirect table */
+ long crfd; /* count file indirect entries */
+ unsigned lang: 5; /* language for this file */
+ unsigned fMerge : 1; /* whether this file can be merged */
+ unsigned fReadin : 1; /* true if it was read in (not just created) */
+ unsigned fBigendian : 1;/* if set, was compiled on big endian machine */
+ /* aux's will be in compile host's sex */
+ unsigned glevel : 2; /* level this file was compiled with */
+ unsigned reserved : 22; /* reserved for future use */
+ bfd_vma cbLineOffset; /* byte offset from header for this file ln's */
+ bfd_vma cbLine; /* size of lines for this file */
+ } FDR, *pFDR;
+#define cbFDR sizeof(FDR)
+#define fdNil ((pFDR)0)
+#define ifdNil -1
+#define ifdTemp 0
+#define ilnNil -1
+
+
+/*
+ * Procedure Descriptor
+ *
+ * There is one of these for EVERY TEXT LABEL.
+ * If a procedure is in a file with full symbols, then isym
+ * will point to the PROC symbols, else it will point to the
+ * global symbol for the label.
+ */
+
+typedef struct pdr {
+ bfd_vma adr; /* memory address of start of procedure */
+ long isym; /* start of local symbol entries */
+ long iline; /* start of line number entries*/
+ long regmask; /* save register mask */
+ long regoffset; /* save register offset */
+ long iopt; /* start of optimization symbol entries*/
+ long fregmask; /* save floating point register mask */
+ long fregoffset; /* save floating point register offset */
+ long frameoffset; /* frame size */
+ short framereg; /* frame pointer register */
+ short pcreg; /* offset or reg of return pc */
+ long lnLow; /* lowest line in the procedure */
+ long lnHigh; /* highest line in the procedure */
+ bfd_vma cbLineOffset; /* byte offset for this procedure from the fd base */
+ /* These fields are new for 64 bit ECOFF. */
+ unsigned gp_prologue : 8; /* byte size of GP prologue */
+ unsigned gp_used : 1; /* true if the procedure uses GP */
+ unsigned reg_frame : 1; /* true if register frame procedure */
+ unsigned prof : 1; /* true if compiled with -pg */
+ unsigned reserved : 13; /* reserved: must be zero */
+ unsigned localoff : 8; /* offset of local variables from vfp */
+ } PDR, *pPDR;
+#define cbPDR sizeof(PDR)
+#define pdNil ((pPDR) 0)
+#define ipdNil -1
+
+/*
+ * The structure of the runtime procedure descriptor created by the loader
+ * for use by the static exception system.
+ */
+/*
+ * If 0'd out because exception_info chokes Visual C++ and because there
+ * don't seem to be any references to this structure elsewhere in gdb.
+ */
+#if 0
+typedef struct runtime_pdr {
+ bfd_vma adr; /* memory address of start of procedure */
+ long regmask; /* save register mask */
+ long regoffset; /* save register offset */
+ long fregmask; /* save floating point register mask */
+ long fregoffset; /* save floating point register offset */
+ long frameoffset; /* frame size */
+ short framereg; /* frame pointer register */
+ short pcreg; /* offset or reg of return pc */
+ long irpss; /* index into the runtime string table */
+ long reserved;
+ struct exception_info *exception_info;/* pointer to exception array */
+} RPDR, *pRPDR;
+#define cbRPDR sizeof(RPDR)
+#define rpdNil ((pRPDR) 0)
+#endif
+
+/*
+ * Line Numbers
+ *
+ * Line Numbers are segregated from the normal symbols because they
+ * are [1] smaller , [2] are of no interest to your
+ * average loader, and [3] are never needed in the middle of normal
+ * scanning and therefore slow things down.
+ *
+ * By definition, the first LINER for any given procedure will have
+ * the first line of a procedure and represent the first address.
+ */
+
+typedef long LINER, *pLINER;
+#define lineNil ((pLINER)0)
+#define cbLINER sizeof(LINER)
+#define ilineNil -1
+
+
+
+/*
+ * The Symbol Structure (GFW, to those who Know!)
+ */
+
+typedef struct {
+ long iss; /* index into String Space of name */
+ bfd_vma value; /* value of symbol */
+ unsigned st : 6; /* symbol type */
+ unsigned sc : 5; /* storage class - text, data, etc */
+ unsigned reserved : 1; /* reserved */
+ unsigned index : 20; /* index into sym/aux table */
+ } SYMR, *pSYMR;
+#define symNil ((pSYMR)0)
+#define cbSYMR sizeof(SYMR)
+#define isymNil -1
+#define indexNil 0xfffff
+#define issNil -1
+#define issNull 0
+
+
+/* The following converts a memory resident string to an iss.
+ * This hack is recognized in SbFIss, in sym.c of the debugger.
+ */
+#define IssFSb(sb) (0x80000000 | ((unsigned long)(sb)))
+
+/* E X T E R N A L S Y M B O L R E C O R D
+ *
+ * Same as the SYMR except it contains file context to determine where
+ * the index is.
+ */
+typedef struct ecoff_extr {
+ unsigned jmptbl:1; /* symbol is a jump table entry for shlibs */
+ unsigned cobol_main:1; /* symbol is a cobol main procedure */
+ unsigned weakext:1; /* symbol is weak external */
+ unsigned reserved:13; /* reserved for future use */
+ int ifd; /* where the iss and index fields point into */
+ SYMR asym; /* symbol for the external */
+ } EXTR, *pEXTR;
+#define extNil ((pEXTR)0)
+#define cbEXTR sizeof(EXTR)
+
+
+/* A U X I L L A R Y T Y P E I N F O R M A T I O N */
+
+/*
+ * Type Information Record
+ */
+typedef struct {
+ unsigned fBitfield : 1; /* set if bit width is specified */
+ unsigned continued : 1; /* indicates additional TQ info in next AUX */
+ unsigned bt : 6; /* basic type */
+ unsigned tq4 : 4;
+ unsigned tq5 : 4;
+ /* ---- 16 bit boundary ---- */
+ unsigned tq0 : 4;
+ unsigned tq1 : 4; /* 6 type qualifiers - tqPtr, etc. */
+ unsigned tq2 : 4;
+ unsigned tq3 : 4;
+ } TIR, *pTIR;
+#define cbTIR sizeof(TIR)
+#define tiNil ((pTIR)0)
+#define itqMax 6
+
+/*
+ * Relative symbol record
+ *
+ * If the rfd field is 4095, the index field indexes into the global symbol
+ * table.
+ */
+
+typedef struct {
+ unsigned rfd : 12; /* index into the file indirect table */
+ unsigned index : 20; /* index int sym/aux/iss tables */
+ } RNDXR, *pRNDXR;
+#define cbRNDXR sizeof(RNDXR)
+#define rndxNil ((pRNDXR)0)
+
+/* dense numbers or sometimes called block numbers are stored in this type,
+ * a rfd of 0xffffffff is an index into the global table.
+ */
+typedef struct {
+ unsigned long rfd; /* index into the file table */
+ unsigned long index; /* index int sym/aux/iss tables */
+ } DNR, *pDNR;
+#define cbDNR sizeof(DNR)
+#define dnNil ((pDNR)0)
+
+
+
+/*
+ * Auxillary information occurs only if needed.
+ * It ALWAYS occurs in this order when present.
+
+ isymMac used by stProc only
+ TIR type info
+ TIR additional TQ info (if first TIR was not enough)
+ rndx if (bt == btStruct,btUnion,btEnum,btSet,btRange,
+ btTypedef):
+ rsym.index == iaux for btSet or btRange
+ else rsym.index == isym
+ dimLow btRange, btSet
+ dimMac btRange, btSet
+ rndx0 As many as there are tq arrays
+ dimLow0
+ dimHigh0
+ ...
+ rndxMax-1
+ dimLowMax-1
+ dimHighMax-1
+ width in bits if (bit field), width in bits.
+ */
+#define cAuxMax (6 + (idimMax*3))
+
+/* a union of all possible info in the AUX universe */
+typedef union {
+ TIR ti; /* type information record */
+ RNDXR rndx; /* relative index into symbol table */
+ long dnLow; /* low dimension */
+ long dnHigh; /* high dimension */
+ long isym; /* symbol table index (end of proc) */
+ long iss; /* index into string space (not used) */
+ long width; /* width for non-default sized struc fields */
+ long count; /* count of ranges for variant arm */
+ } AUXU, *pAUXU;
+#define cbAUXU sizeof(AUXU)
+#define auxNil ((pAUXU)0)
+#define iauxNil -1
+
+
+/*
+ * Optimization symbols
+ *
+ * Optimization symbols contain some overlap information with the normal
+ * symbol table. In particular, the proc information
+ * is somewhat redundant but necessary to easily find the other information
+ * present.
+ *
+ * All of the offsets are relative to the beginning of the last otProc
+ */
+
+typedef struct {
+ unsigned ot: 8; /* optimization type */
+ unsigned value: 24; /* address where we are moving it to */
+ RNDXR rndx; /* points to a symbol or opt entry */
+ unsigned long offset; /* relative offset this occured */
+ } OPTR, *pOPTR;
+#define optNil ((pOPTR) 0)
+#define cbOPTR sizeof(OPTR)
+#define ioptNil -1
+
+/*
+ * File Indirect
+ *
+ * When a symbol is referenced across files the following procedure is used:
+ * 1) use the file index to get the File indirect entry.
+ * 2) use the file indirect entry to get the File descriptor.
+ * 3) add the sym index to the base of that file's sym table
+ *
+ */
+
+typedef long RFDT, *pRFDT;
+#define cbRFDT sizeof(RFDT)
+#define rfdNil -1
+
+/*
+ * The file indirect table in the mips loader is known as an array of FITs.
+ * This is done to keep the code in the loader readable in the area where
+ * these tables are merged. Note this is only a name change.
+ */
+typedef long FIT, *pFIT;
+#define cbFIT sizeof(FIT)
+#define ifiNil -1
+#define fiNil ((pFIT) 0)
+
+#ifdef _LANGUAGE_PASCAL
+#define ifdNil -1
+#define ilnNil -1
+#define ipdNil -1
+#define ilineNil -1
+#define isymNil -1
+#define indexNil 16#fffff
+#define issNil -1
+#define issNull 0
+#define itqMax 6
+#define iauxNil -1
+#define ioptNil -1
+#define rfdNil -1
+#define ifiNil -1
+#endif /* _LANGUAGE_PASCAL */
+
+
+/* Dense numbers
+ *
+ * Rather than use file index, symbol index pairs to represent symbols
+ * and globals, we use dense number so that they can be easily embeded
+ * in intermediate code and the programs that process them can
+ * use direct access tabls instead of hash table (which would be
+ * necesary otherwise because of the sparse name space caused by
+ * file index, symbol index pairs. Dense number are represented
+ * by RNDXRs.
+ */
+
+/*
+ * The following table defines the meaning of each SYM field as
+ * a function of the "st". (scD/B == scData OR scBss)
+ *
+ * Note: the value "isymMac" is used by symbols that have the concept
+ * of enclosing a block of related information. This value is the
+ * isym of the first symbol AFTER the end associated with the primary
+ * symbol. For example if a procedure was at isym==90 and had an
+ * isymMac==155, the associated end would be at isym==154, and the
+ * symbol at 155 would probably (although not necessarily) be the
+ * symbol for the next procedure. This allows rapid skipping over
+ * internal information of various sorts. "stEnd"s ALWAYS have the
+ * isym of the primary symbol that started the block.
+ *
+
+ST SC VALUE INDEX
+-------- ------ -------- ------
+stFile scText address isymMac
+stLabel scText address ---
+stGlobal scD/B address iaux
+stStatic scD/B address iaux
+stParam scAbs offset iaux
+stLocal scAbs offset iaux
+stProc scText address iaux (isymMac is first AUX)
+stStaticProc scText address iaux (isymMac is first AUX)
+
+stMember scNil ordinal --- (if member of enum)
+ (mipsread thinks the case below has a bit, not byte, offset.)
+stMember scNil byte offset iaux (if member of struct/union)
+stMember scBits bit offset iaux (bit field spec)
+
+stBlock scText address isymMac (text block)
+ (the code seems to think that rather than scNil, we see scInfo for
+ the two cases below.)
+stBlock scNil cb isymMac (struct/union member define)
+stBlock scNil cMembers isymMac (enum member define)
+
+ (New types added by SGI to simplify things:)
+stStruct scInfo cb isymMac (struct type define)
+stUnion scInfo cb isymMac (union type define)
+stEnum scInfo cMembers isymMac (enum type define)
+
+stEnd scText address isymStart
+stEnd scNil ------- isymStart (struct/union/enum)
+
+stTypedef scNil ------- iaux
+stRegReloc sc??? value old register number
+stForward sc??? new address isym to original symbol
+
+stConstant scInfo value --- (scalar)
+stConstant scInfo iss --- (complex, e.g. string)
+
+ *
+ */
+#endif
diff --git a/include/coff/symconst.h b/include/coff/symconst.h
new file mode 100644
index 00000000000..f40eef2a311
--- /dev/null
+++ b/include/coff/symconst.h
@@ -0,0 +1,177 @@
+/* Declarations of constants for internal format of MIPS ECOFF symbols.
+ Originally contributed by MIPS Computer Systems and Third Eye Software.
+ Changes contributed by Cygnus Support are in the public domain.
+
+ This file is just aggregated with the files that make up the GNU
+ release; it is not considered part of GAS, GDB, or other GNU
+ programs. */
+
+/*
+ * |-----------------------------------------------------------|
+ * | Copyright (c) 1992, 1991, 1990 MIPS Computer Systems, Inc.|
+ * | MIPS Computer Systems, Inc. grants reproduction and use |
+ * | rights to all parties, PROVIDED that this comment is |
+ * | maintained in the copy. |
+ * |-----------------------------------------------------------|
+ */
+
+/* (C) Copyright 1984 by Third Eye Software, Inc.
+ *
+ * Third Eye Software, Inc. grants reproduction and use rights to
+ * all parties, PROVIDED that this comment is maintained in the copy.
+ *
+ * Third Eye makes no claims about the applicability of this
+ * symbol table to a particular use.
+ */
+
+/* glevels for field in FDR */
+#define GLEVEL_0 2
+#define GLEVEL_1 1
+#define GLEVEL_2 0 /* for upward compat reasons. */
+#define GLEVEL_3 3
+
+/* magic number fo symheader */
+#define magicSym 0x7009
+/* The Alpha uses this value instead, for some reason. */
+#define magicSym2 0x1992
+
+/* Language codes */
+#define langC 0
+#define langPascal 1
+#define langFortran 2
+#define langAssembler 3 /* one Assembley inst might map to many mach */
+#define langMachine 4
+#define langNil 5
+#define langAda 6
+#define langPl1 7
+#define langCobol 8
+#define langStdc 9 /* FIXME: Collides with SGI langCplusplus */
+#define langCplusplus 9 /* FIXME: Collides with langStdc */
+#define langCplusplusV2 10 /* SGI addition */
+#define langMax 11 /* maximun allowed 32 -- 5 bits */
+
+/* The following are value definitions for the fields in the SYMR */
+
+/*
+ * Storage Classes
+ */
+
+#define scNil 0
+#define scText 1 /* text symbol */
+#define scData 2 /* initialized data symbol */
+#define scBss 3 /* un-initialized data symbol */
+#define scRegister 4 /* value of symbol is register number */
+#define scAbs 5 /* value of symbol is absolute */
+#define scUndefined 6 /* who knows? */
+#define scCdbLocal 7 /* variable's value is IN se->va.?? */
+#define scBits 8 /* this is a bit field */
+#define scCdbSystem 9 /* variable's value is IN CDB's address space */
+#define scDbx 9 /* overlap dbx internal use */
+#define scRegImage 10 /* register value saved on stack */
+#define scInfo 11 /* symbol contains debugger information */
+#define scUserStruct 12 /* address in struct user for current process */
+#define scSData 13 /* load time only small data */
+#define scSBss 14 /* load time only small common */
+#define scRData 15 /* load time only read only data */
+#define scVar 16 /* Var parameter (fortran,pascal) */
+#define scCommon 17 /* common variable */
+#define scSCommon 18 /* small common */
+#define scVarRegister 19 /* Var parameter in a register */
+#define scVariant 20 /* Variant record */
+#define scSUndefined 21 /* small undefined(external) data */
+#define scInit 22 /* .init section symbol */
+#define scBasedVar 23 /* Fortran or PL/1 ptr based var */
+#define scXData 24 /* exception handling data */
+#define scPData 25 /* Procedure section */
+#define scFini 26 /* .fini section */
+#define scRConst 27 /* .rconst section */
+#define scMax 32
+
+
+/*
+ * Symbol Types
+ */
+
+#define stNil 0 /* Nuthin' special */
+#define stGlobal 1 /* external symbol */
+#define stStatic 2 /* static */
+#define stParam 3 /* procedure argument */
+#define stLocal 4 /* local variable */
+#define stLabel 5 /* label */
+#define stProc 6 /* " " Procedure */
+#define stBlock 7 /* beginnning of block */
+#define stEnd 8 /* end (of anything) */
+#define stMember 9 /* member (of anything - struct/union/enum */
+#define stTypedef 10 /* type definition */
+#define stFile 11 /* file name */
+#define stRegReloc 12 /* register relocation */
+#define stForward 13 /* forwarding address */
+#define stStaticProc 14 /* load time only static procs */
+#define stConstant 15 /* const */
+#define stStaParam 16 /* Fortran static parameters */
+ /* These new symbol types have been recently added to SGI machines. */
+#define stStruct 26 /* Beginning of block defining a struct type */
+#define stUnion 27 /* Beginning of block defining a union type */
+#define stEnum 28 /* Beginning of block defining an enum type */
+#define stIndirect 34 /* Indirect type specification */
+ /* Pseudo-symbols - internal to debugger */
+#define stStr 60 /* string */
+#define stNumber 61 /* pure number (ie. 4 NOR 2+2) */
+#define stExpr 62 /* 2+2 vs. 4 */
+#define stType 63 /* post-coersion SER */
+#define stMax 64
+
+/* definitions for fields in TIR */
+
+/* type qualifiers for ti.tq0 -> ti.(itqMax-1) */
+#define tqNil 0 /* bt is what you see */
+#define tqPtr 1 /* pointer */
+#define tqProc 2 /* procedure */
+#define tqArray 3 /* duh */
+#define tqFar 4 /* longer addressing - 8086/8 land */
+#define tqVol 5 /* volatile */
+#define tqConst 6 /* const */
+#define tqMax 8
+
+/* basic types as seen in ti.bt */
+#define btNil 0 /* undefined (also, enum members) */
+#define btAdr 1 /* address - integer same size as pointer */
+#define btChar 2 /* character */
+#define btUChar 3 /* unsigned character */
+#define btShort 4 /* short */
+#define btUShort 5 /* unsigned short */
+#define btInt 6 /* int */
+#define btUInt 7 /* unsigned int */
+#define btLong 8 /* long */
+#define btULong 9 /* unsigned long */
+#define btFloat 10 /* float (real) */
+#define btDouble 11 /* Double (real) */
+#define btStruct 12 /* Structure (Record) */
+#define btUnion 13 /* Union (variant) */
+#define btEnum 14 /* Enumerated */
+#define btTypedef 15 /* defined via a typedef, isymRef points */
+#define btRange 16 /* subrange of int */
+#define btSet 17 /* pascal sets */
+#define btComplex 18 /* fortran complex */
+#define btDComplex 19 /* fortran double complex */
+#define btIndirect 20 /* forward or unnamed typedef */
+#define btFixedDec 21 /* Fixed Decimal */
+#define btFloatDec 22 /* Float Decimal */
+#define btString 23 /* Varying Length Character String */
+#define btBit 24 /* Aligned Bit String */
+#define btPicture 25 /* Picture */
+#define btVoid 26 /* void */
+#define btLongLong 27 /* long long */
+#define btULongLong 28 /* unsigned long long */
+#define btMax 64
+
+#if (_MFG == _MIPS)
+/* optimization type codes */
+#define otNil 0
+#define otReg 1 /* move var to reg */
+#define otBlock 2 /* begin basic block */
+#define otProc 3 /* procedure */
+#define otInline 4 /* inline procedure */
+#define otEnd 5 /* whatever you started */
+#define otMax 6 /* KEEP UP TO DATE */
+#endif /* (_MFG == _MIPS) */
diff --git a/include/coff/tic30.h b/include/coff/tic30.h
new file mode 100644
index 00000000000..10b026cebe2
--- /dev/null
+++ b/include/coff/tic30.h
@@ -0,0 +1,203 @@
+/*** coff information for Texas Instruments TMS320C3X */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+#define TIC30MAGIC 0xC000
+
+#define TIC30BADMAG(x) (((x).f_magic!=TIC30MAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[4]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the z8k don't have room in the instruction for the entire
+ offset - eg with segments */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
+/* TMS320C30 relocation types. */
+
+#define R_TIC30_ABS16 0x100 /* 16 bit absolute. */
+#define R_TIC30_ABS24 0x101 /* 24 bit absolute. */
+#define R_TIC30_ABS32 0x102 /* 32 bit absolute. */
+#define R_TIC30_LDP 0x103 /* LDP bits 23-16 to 7-0. */
+#define R_TIC30_PC16 0x104 /* 16 bit pc relative. */
diff --git a/include/coff/tic80.h b/include/coff/tic80.h
new file mode 100644
index 00000000000..5d938f7b1f0
--- /dev/null
+++ b/include/coff/tic80.h
@@ -0,0 +1,228 @@
+/*** coff information for TI TMS320C80 (MVP) */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+ char f_target_id[2]; /* target id (TIc80 specific) */
+};
+
+#define TIC80_ARCH_MAGIC 0x0C1 /* Goes in the file header magic number field */
+#define TIC80_TARGET_ID 0x95 /* Goes in the target id field */
+
+#define TIC80BADMAG(x) ((x).f_magic != TIC80_ARCH_MAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 22
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+#define TIC80_AOUTHDR_MAGIC 0x108 /* Goes in the optional file header magic number field */
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[2]; /* flags */
+ char s_reserved[1]; /* reserved (TIc80 specific) */
+ char s_mempage[1]; /* memory page number (TIc80) */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _CINIT ".cinit"
+#define _CONST ".const"
+#define _SWITCH ".switch"
+#define _STACK ".stack"
+#define _SYSMEM ".sysmem"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+/* FIXME - need to correlate with TIc80 Code Generation Tools User's Guide, CG:A-25 */
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the h8 don't have room in the instruction for the entire
+ offset - eg the strange jump and high page addressing modes */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_reserved[2];
+ char r_type[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 12
+
+/* TIc80 relocation types. */
+
+#define R_ABS 0x00 /* Absolute address - no relocation */
+#define R_RELLONGX 0x11 /* PP: 32 bits, direct */
+#define R_PPBASE 0x34 /* PP: Global base address type */
+#define R_PPLBASE 0x35 /* PP: Local base address type */
+#define R_PP15 0x38 /* PP: Global 15 bit offset */
+#define R_PP15W 0x39 /* PP: Global 15 bit offset divided by 4 */
+#define R_PP15H 0x3A /* PP: Global 15 bit offset divided by 2 */
+#define R_PP16B 0x3B /* PP: Global 16 bit offset for bytes */
+#define R_PPL15 0x3C /* PP: Local 15 bit offset */
+#define R_PPL15W 0x3D /* PP: Local 15 bit offset divided by 4 */
+#define R_PPL15H 0x3E /* PP: Local 15 bit offset divided by 2 */
+#define R_PPL16B 0x3F /* PP: Local 16 bit offset for bytes */
+#define R_PPN15 0x40 /* PP: Global 15 bit negative offset */
+#define R_PPN15W 0x41 /* PP: Global 15 bit negative offset divided by 4 */
+#define R_PPN15H 0x42 /* PP: Global 15 bit negative offset divided by 2 */
+#define R_PPN16B 0x43 /* PP: Global 16 bit negative byte offset */
+#define R_PPLN15 0x44 /* PP: Local 15 bit negative offset */
+#define R_PPLN15W 0x45 /* PP: Local 15 bit negative offset divided by 4 */
+#define R_PPLN15H 0x46 /* PP: Local 15 bit negative offset divided by 2 */
+#define R_PPLN16B 0x47 /* PP: Local 16 bit negative byte offset */
+#define R_MPPCR15W 0x4E /* MP: 15 bit PC-relative divided by 4 */
+#define R_MPPCR 0x4F /* MP: 32 bit PC-relative divided by 4 */
diff --git a/include/coff/w65.h b/include/coff/w65.h
new file mode 100644
index 00000000000..3378c2324d2
--- /dev/null
+++ b/include/coff/w65.h
@@ -0,0 +1,201 @@
+/*** coff information for WDC 65816 */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+
+#define W65MAGIC 0x6500
+
+
+#define W65BADMAG(x) (((x).f_magic!=W65MAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[4]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the w65 don't have room in the instruction for the entire
+ offset - eg the strange jump and high page addressing modes */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
+
+
+
diff --git a/include/coff/we32k.h b/include/coff/we32k.h
new file mode 100644
index 00000000000..553fa35cdad
--- /dev/null
+++ b/include/coff/we32k.h
@@ -0,0 +1,206 @@
+/*** coff information for we32k */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+#define F_BM32B (0020000)
+#define F_BM32MAU (0040000)
+
+#define WE32KMAGIC 0x170 /* we32k sans transfer vector */
+#define FBOMAGIC 0x170 /* we32k sans transfer vector */
+#define MTVMAGIC 0x171 /* we32k with transfer vector */
+#define RBOMAGIC 0x172 /* reserved */
+#define WE32KBADMAG(x) (((x).f_magic != WE32KMAGIC) \
+ && ((x).f_magic != FBOMAGIC) \
+ && ((x).f_magic != RBOMAGIC) \
+ && ((x).f_magic != MTVMAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _TV ".tv"
+#define _INIT ".init"
+#define _FINI ".fini"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+# define _ETEXT "etext"
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
diff --git a/include/coff/z8k.h b/include/coff/z8k.h
new file mode 100644
index 00000000000..19b846ca2e1
--- /dev/null
+++ b/include/coff/z8k.h
@@ -0,0 +1,201 @@
+/*** coff information for Zilog Z800N */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+
+/* Type of cpu is stored in flags */
+#define F_Z8001 0x1000
+#define F_Z8002 0x2000
+#define F_MACHMASK 0xf000
+
+#define Z8KMAGIC 0x8000
+
+#define Z8KBADMAG(x) (((x).f_magic!=Z8KMAGIC))
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes, padded to FW bdry*/
+ char dsize[4]; /* initialized data " " */
+ char bsize[4]; /* uninitialized data " " */
+ char entry[4]; /* entry pt. */
+ char text_start[4]; /* base of text used for this file */
+ char data_start[4]; /* base of data used for this file */
+}
+AOUTHDR;
+
+
+#define AOUTHDRSZ 28
+#define AOUTSZ 28
+
+
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[4]; /* line number */
+};
+
+#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) (ext->l_lnno));
+#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno));
+
+#define LINENO struct external_lineno
+#define LINESZ 8
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+/* The external reloc has an offset field, because some of the reloc
+ types on the z8k don't have room in the instruction for the entire
+ offset - eg with segments */
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_offset[4];
+ char r_type[2];
+ char r_stuff[2];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 16
+
diff --git a/include/demangle.h b/include/demangle.h
new file mode 100644
index 00000000000..63fe5e2adf4
--- /dev/null
+++ b/include/demangle.h
@@ -0,0 +1,95 @@
+/* Defs for interface to demanglers.
+ Copyright 1992, 1995, 1996 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#if !defined (DEMANGLE_H)
+#define DEMANGLE_H
+
+#include <ansidecl.h>
+
+/* Options passed to cplus_demangle (in 2nd parameter). */
+
+#define DMGL_NO_OPTS 0 /* For readability... */
+#define DMGL_PARAMS (1 << 0) /* Include function args */
+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
+
+#define DMGL_AUTO (1 << 8)
+#define DMGL_GNU (1 << 9)
+#define DMGL_LUCID (1 << 10)
+#define DMGL_ARM (1 << 11)
+#define DMGL_HP (1 << 12) /* For the HP aCC compiler; same as ARM
+ except for template arguments, etc. */
+#define DMGL_EDG (1 << 13)
+
+/* If none of these are set, use 'current_demangling_style' as the default. */
+#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG)
+
+/* Enumeration of possible demangling styles.
+
+ Lucid and ARM styles are still kept logically distinct, even though
+ they now both behave identically. The resulting style is actual the
+ union of both. I.E. either style recognizes both "__pt__" and "__rf__"
+ for operator "->", even though the first is lucid style and the second
+ is ARM style. (FIXME?) */
+
+extern enum demangling_styles
+{
+ unknown_demangling = 0,
+ auto_demangling = DMGL_AUTO,
+ gnu_demangling = DMGL_GNU,
+ lucid_demangling = DMGL_LUCID,
+ arm_demangling = DMGL_ARM,
+ hp_demangling = DMGL_HP,
+ edg_demangling = DMGL_EDG
+} current_demangling_style;
+
+/* Define string names for the various demangling styles. */
+
+#define AUTO_DEMANGLING_STYLE_STRING "auto"
+#define GNU_DEMANGLING_STYLE_STRING "gnu"
+#define LUCID_DEMANGLING_STYLE_STRING "lucid"
+#define ARM_DEMANGLING_STYLE_STRING "arm"
+#define HP_DEMANGLING_STYLE_STRING "hp"
+#define EDG_DEMANGLING_STYLE_STRING "edg"
+
+/* Some macros to test what demangling style is active. */
+
+#define CURRENT_DEMANGLING_STYLE current_demangling_style
+#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO)
+#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU)
+#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID)
+#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM)
+#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP)
+#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG)
+
+extern char *
+cplus_demangle PARAMS ((const char *mangled, int options));
+
+extern int
+cplus_demangle_opname PARAMS ((const char *opname, char *result, int options));
+
+extern const char *
+cplus_mangle_opname PARAMS ((const char *opname, int options));
+
+/* Note: This sets global state. FIXME if you care about multi-threading. */
+
+extern void
+set_cplus_marker_for_demangling PARAMS ((int ch));
+
+#endif /* DEMANGLE_H */
diff --git a/include/dis-asm.h b/include/dis-asm.h
new file mode 100644
index 00000000000..666ed690152
--- /dev/null
+++ b/include/dis-asm.h
@@ -0,0 +1,243 @@
+/* Interface between the opcode library and its callers.
+ Written by Cygnus Support, 1993.
+
+ The opcode library (libopcodes.a) provides instruction decoders for
+ a large variety of instruction sets, callable with an identical
+ interface, for making instruction-processing programs more independent
+ of the instruction set being processed. */
+
+#ifndef DIS_ASM_H
+#define DIS_ASM_H
+
+#include <stdio.h>
+#include "bfd.h"
+
+typedef int (*fprintf_ftype) PARAMS((PTR, const char*, ...));
+
+enum dis_insn_type {
+ dis_noninsn, /* Not a valid instruction */
+ dis_nonbranch, /* Not a branch instruction */
+ dis_branch, /* Unconditional branch */
+ dis_condbranch, /* Conditional branch */
+ dis_jsr, /* Jump to subroutine */
+ dis_condjsr, /* Conditional jump to subroutine */
+ dis_dref, /* Data reference instruction */
+ dis_dref2 /* Two data references in instruction */
+};
+
+/* This struct is passed into the instruction decoding routine,
+ and is passed back out into each callback. The various fields are used
+ for conveying information from your main routine into your callbacks,
+ for passing information into the instruction decoders (such as the
+ addresses of the callback functions), or for passing information
+ back from the instruction decoders to their callers.
+
+ It must be initialized before it is first passed; this can be done
+ by hand, or using one of the initialization macros below. */
+
+typedef struct disassemble_info {
+ fprintf_ftype fprintf_func;
+ PTR stream;
+ PTR application_data;
+
+ /* Target description. We could replace this with a pointer to the bfd,
+ but that would require one. There currently isn't any such requirement
+ so to avoid introducing one we record these explicitly. */
+ /* The bfd_flavour. This can be bfd_target_unknown_flavour. */
+ enum bfd_flavour flavour;
+ /* The bfd_arch value. */
+ enum bfd_architecture arch;
+ /* The bfd_mach value. */
+ unsigned long mach;
+ /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
+ enum bfd_endian endian;
+
+ /* An array of pointers to symbols either at the location being disassembled
+ or at the start of the function being disassembled. The array is sorted
+ so that the first symbol is intended to be the one used. The others are
+ present for any misc. purposes. This is not set reliably, but if it is
+ not NULL, it is correct. */
+ asymbol **symbols;
+ /* Number of symbols in array. */
+ int num_symbols;
+
+ /* For use by the disassembler.
+ The top 16 bits are reserved for public use (and are documented here).
+ The bottom 16 bits are for the internal use of the disassembler. */
+ unsigned long flags;
+#define INSN_HAS_RELOC 0x80000000
+ PTR private_data;
+
+ /* Function used to get bytes to disassemble. MEMADDR is the
+ address of the stuff to be disassembled, MYADDR is the address to
+ put the bytes in, and LENGTH is the number of bytes to read.
+ INFO is a pointer to this struct.
+ Returns an errno value or 0 for success. */
+ int (*read_memory_func)
+ PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
+ struct disassemble_info *info));
+
+ /* Function which should be called if we get an error that we can't
+ recover from. STATUS is the errno value from read_memory_func and
+ MEMADDR is the address that we were trying to read. INFO is a
+ pointer to this struct. */
+ void (*memory_error_func)
+ PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
+
+ /* Function called to print ADDR. */
+ void (*print_address_func)
+ PARAMS ((bfd_vma addr, struct disassemble_info *info));
+
+ /* Function called to determine if there is a symbol at the given ADDR.
+ If there is, the function returns 1, otherwise it returns 0.
+ This is used by ports which support an overlay manager where
+ the overlay number is held in the top part of an address. In
+ some circumstances we want to include the overlay number in the
+ address, (normally because there is a symbol associated with
+ that address), but sometimes we want to mask out the overlay bits. */
+ int (* symbol_at_address_func)
+ PARAMS ((bfd_vma addr, struct disassemble_info * info));
+
+ /* These are for buffer_read_memory. */
+ bfd_byte *buffer;
+ bfd_vma buffer_vma;
+ int buffer_length;
+
+ /* This variable may be set by the instruction decoder. It suggests
+ the number of bytes objdump should display on a single line. If
+ the instruction decoder sets this, it should always set it to
+ the same value in order to get reasonable looking output. */
+ int bytes_per_line;
+
+ /* the next two variables control the way objdump displays the raw data */
+ /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
+ /* output will look like this:
+ 00: 00000000 00000000
+ with the chunks displayed according to "display_endian". */
+ int bytes_per_chunk;
+ enum bfd_endian display_endian;
+
+ /* Results from instruction decoders. Not all decoders yet support
+ this information. This info is set each time an instruction is
+ decoded, and is only valid for the last such instruction.
+
+ To determine whether this decoder supports this information, set
+ insn_info_valid to 0, decode an instruction, then check it. */
+
+ char insn_info_valid; /* Branch info has been set. */
+ char branch_delay_insns; /* How many sequential insn's will run before
+ a branch takes effect. (0 = normal) */
+ char data_size; /* Size of data reference in insn, in bytes */
+ enum dis_insn_type insn_type; /* Type of instruction */
+ bfd_vma target; /* Target address of branch or dref, if known;
+ zero if unknown. */
+ bfd_vma target2; /* Second target address for dref2 */
+
+} disassemble_info;
+
+
+/* Standard disassemblers. Disassemble one instruction at the given
+ target address. Return number of bytes processed. */
+typedef int (*disassembler_ftype)
+ PARAMS((bfd_vma, disassemble_info *));
+
+extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i386_att PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i386_intel PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
+extern disassembler_ftype arc_get_disassembler PARAMS ((int, int));
+extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_shl PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_fr30 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_mcore PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_d30v PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_vax PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_tic80 PARAMS ((bfd_vma, disassemble_info*));
+
+/* Fetch the disassembler for a given BFD, if that support is available. */
+extern disassembler_ftype disassembler PARAMS ((bfd *));
+
+
+/* This block of definitions is for particular callers who read instructions
+ into a buffer before calling the instruction decoder. */
+
+/* Here is a function which callers may wish to use for read_memory_func.
+ It gets bytes from a buffer. */
+extern int buffer_read_memory
+ PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
+
+/* This function goes with buffer_read_memory.
+ It prints a message using info->fprintf_func and info->stream. */
+extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
+
+
+/* Just print the address in hex. This is included for completeness even
+ though both GDB and objdump provide their own (to print symbolic
+ addresses). */
+extern void generic_print_address
+ PARAMS ((bfd_vma, struct disassemble_info *));
+
+/* Always true. */
+extern int generic_symbol_at_address
+ PARAMS ((bfd_vma, struct disassemble_info *));
+
+/* Macro to initialize a disassemble_info struct. This should be called
+ by all applications creating such a struct. */
+#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
+ (INFO).flavour = bfd_target_unknown_flavour, \
+ (INFO).arch = bfd_arch_unknown, \
+ (INFO).mach = 0, \
+ (INFO).endian = BFD_ENDIAN_UNKNOWN, \
+ INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC)
+
+/* Call this macro to initialize only the internal variables for the
+ disassembler. Architecture dependent things such as byte order, or machine
+ variant are not touched by this macro. This makes things much easier for
+ GDB which must initialize these things seperatly. */
+
+#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
+ (INFO).fprintf_func = (fprintf_ftype)(FPRINTF_FUNC), \
+ (INFO).stream = (PTR)(STREAM), \
+ (INFO).symbols = NULL, \
+ (INFO).num_symbols = 0, \
+ (INFO).buffer = NULL, \
+ (INFO).buffer_vma = 0, \
+ (INFO).buffer_length = 0, \
+ (INFO).read_memory_func = buffer_read_memory, \
+ (INFO).memory_error_func = perror_memory, \
+ (INFO).print_address_func = generic_print_address, \
+ (INFO).symbol_at_address_func = generic_symbol_at_address, \
+ (INFO).flags = 0, \
+ (INFO).bytes_per_line = 0, \
+ (INFO).bytes_per_chunk = 0, \
+ (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \
+ (INFO).insn_info_valid = 0
+
+#endif /* ! defined (DIS_ASM_H) */
diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog
new file mode 100644
index 00000000000..deaccd412e2
--- /dev/null
+++ b/include/elf/ChangeLog
@@ -0,0 +1,719 @@
+1999-04-21 Nick Clifton <nickc@cygnus.com>
+
+ * reloc-macros.h (START_RELOC_NUMBERS): Prepend an underscore to
+ fake reloc entry name (if possible), in order to avoid conflicts
+ with typedefs of the same name.
+
+1999-04-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.h (EF_MIPS_32BITMODE): New.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * mcore.h: New header file. Defines for Motorolla's MCore
+ processor.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * common.h: Add new constants defined in: "System V Application
+ Binary Interface - DRAFT - April 29, 1998" found at the web site:
+ http://www.sco.com/developer/gabi/contents.html
+
+ (EM_MMA): Removed. Replaced with EM_MCORE as Motorolla own this
+ value.
+
+1999-03-31 Nick Clifton <nickc@cygnus.com>
+
+ * reloc-macros.h: Fixed to not generate an enum with a trailing
+ comma.
+
+1999-03-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.h (E_MIPS_MACH_5000): New.
+
+1999-03-10 Ulrich Drepper <drepper@cygnus.com>
+
+ * common.h: Add definitions for a few more Solaris ELF extensions.
+
+Thu Feb 18 18:58:26 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * external.h: Only use attribute if __GNUC__ is defined.
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ Patch submitted by: Scott Bambrough <scottb@corelcomputer.com>
+
+ * elf/external.h: struct Elf_External_Versym must be packed on
+ ARM. Code uses sizeof(Elf_External_Versym) and assumes it is
+ equal to sizeof(char[2]). Reported by Jim Pick <jim@jimpick.com>
+
+1999-02-02 Nick Clifton <nickc@cygnus.com>
+
+ * dwarf2.h (DWARF2_External_ARange): New structure.
+ (DWARF2_Internal_ARange): New structure.
+
+Mon Feb 1 11:33:56 1999 Catherine Moore <clm@cygnus.com>
+
+ * arm.h: Renumber relocs to conform to standard.
+ (EF_NEW_ABI): Define.
+ (EF_OLD_ABI): Define.
+ * arm-oabi.h: New file.
+
+1999-01-28 Nick Clifton <nickc@cygnus.com>
+
+ * fr30.h: Add R_FR30_GNU_VT{INHERIT,ENTRY} relocs.
+
+1999-01-27 Nick Clifton <nickc@cygnus.com>
+
+ * dwarf2.h: Add typedefs for structures found in dwarf2 sections.
+
+1998-12-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.h (E_MIPS_MACH_4111): New.
+
+1998-12-15 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.h (EF_MIPS_ABI,E_MIPS_ABI_O32,E_MIPS_ABI_O64,
+ E_MIPS_ABI_EABI32,E_MIPS_ABI_EABI64):
+
+1998-12-03 Nick Clifton <nickc@cygnus.com>
+
+ * fr30.h: Add R_FR30_48 reloc.
+
+1998-12-02 Ulrich Drepper <drepper@cygnus.com>
+
+ * mips.h: Add external data type for conflict section.
+
+ * mips.h: Add more LL_* options from Irix 6.5.
+
+ * mips.h: Add R_MIPS_JALR and adjust R_MIPS_max appropriately.
+
+Tue Nov 10 15:12:28 1998 Nick Clifton <nickc@cygnus.com>
+
+ * common.h (EM_CYGNUS_FR30): Reduce to a 16 bit value.
+
+Tue Nov 10 15:17:28 1998 Catherine Moore <clm@cygnus.com>
+
+ * d10v.h: Add vtable relocs.
+
+Wed Nov 4 15:56:50 1998 Nick Clifton <nickc@cygnus.com>
+
+ * common.h (EM_CYGNUS_FR30): New machine number.
+
+ * fr30.h: New file: Definitions for the FR30.
+
+Fri Oct 30 11:54:15 1998 Catherine Moore <clm@cygnus.com>
+
+ From Philip Blundell <pb@nexus.co.uk>:
+ * arm.h (R_ARM_COPY, et al.): New relocs, used by Linux for PIC.
+ (EF_ALIGN8): New flag.
+
+Tue Oct 20 11:19:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * common.h (NT_LWPSTATUS): Close comment accidentally left open.
+
+Mon Oct 19 20:24:11 1998 Catherine Moore <clm@cygnus.com>
+
+ * sh.h: Add vtable relocs.
+
+Mon Oct 19 01:44:42 1998 Felix Lee <flee@cygnus.com>
+
+ * common.h (NT_PSTATUS, NT_FPREGS, NT_PSINFO,
+ NT_LWPSTATUS,NT_LWPSINFO): added.
+ * internal.h (Elf_Internal_Note): new structure members.
+
+Fri Oct 16 14:11:25 1998 Catherine Moore <clm@cygnus.com>
+
+ * m32r.h: Add vtable relocs.
+
+Tue Oct 6 09:22:22 1998 Catherine Moore <clm@cygnus.com>
+
+ * sparc.h: Add vtable relocs.
+
+Mon Oct 5 09:39:22 1998 Catherine Moore <clm@cygnus.com>
+
+ * v850.h: Add vtable relocs.
+
+Sun Oct 4 21:17:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h (R_386_max): Change from 252 to 24.
+
+Mon Sep 21 12:24:44 1998 Catherine Moore <clm@cygnus.com>
+
+ * i386.h: Change vtable reloc numbers.
+
+Sun Sep 20 00:54:22 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k.h: Add vtable relocs and R_68K_max.
+
+Tue Sep 15 09:56:49 CDT 1998 Catherine Moore <clm@cygnus.com>
+
+ * arm.h: Add vtable relocs.
+
+Mon Aug 31 11:25:27 1998 Catherine Moore <clm@cygnus.com>
+
+ * arm.h: Define STT_ARM_TFUNC. Remove ST_THUMB_xxxx
+ definitions.
+
+Sat Aug 29 22:25:51 1998 Richard Henderson <rth@cygnus.com>
+
+ * i386.h: Add vtable relocs.
+
+1998-08-25 16:42 Ulrich Drepper <drepper@cygnus.com>
+
+ * common.h: Add SYMINFO_* macros to access Elf*_Syminfo information.
+
+ * external.h: Add Elf_External_Syminfo definition.
+
+ * internal.h: Add Elf_Internal_Syminfo, Elf32_Internal_Syminfo,
+ and Elf64_Syminfo definitions.
+
+Sun Aug 9 20:26:49 CDT 1998 Catherine Moore <clm@cygnus.com>
+
+ * arm.h: Add ST_THUMB definitions.
+
+Wed Aug 5 15:52:35 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm.h: Add ELF header flags to specify compile time optins:
+ EF_INTERWORK: New flag.
+ EF_APCS_26: New flag.
+ EF_APCS_FLOAT: New flag.
+ EF_PIC: New flag.
+
+1998-07-31 21:28 Ulrich Drepper <drepper@cygnus.com>
+
+ * mips.h: Add missing RHF_* constants.
+
+Fri Jul 31 10:01:40 1998 Catherine Moore <clm@cygnus.com>
+
+ * arm.h: Add R_ARM_THM_PC9 relocation.
+
+1998-07-30 16:25 Ulrich Drepper <drepper@cygnus.com>
+
+ * common.h: Add new DT_* entries and there flag macros from Solaris.
+
+Tue Jul 28 18:14:07 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * sparc.h: (R_SPARC_REV32): Added for little endian data e.g. sparc 86x.
+
+Fri Jul 24 11:22:06 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h: Add R_MN10300_24 relocation.
+
+1998-07-24 Ulrich Drepper <drepper@cygnus.com>
+
+ * mips.h: Add MIPS64 relocation names and values.
+
+Wed Jul 22 19:29:00 Catherine Moore <clm@cygnus.com>
+
+ * arm.h: Rename relocations.
+
+1998-07-22 Ulrich Drepper <drepper@cygnus.com>
+
+ * ppc.h: Define enum as elf_ppc_reloc_type.
+
+Wed Jul 22 16:22:11 1998 Nick Clifton <nickc@cygnus.com>
+
+ * reloc-macros.h: New file. Provides relocation macros:
+ START_RELOC_NUMBERS, RELOC_NUMBER, FAKE_RELOC, EMPTY_RELOC and
+ END_RELOC_NUMBERS used by other elf header files.
+
+ * alpha.h: Use reloc-macros.h.
+ * arc.h: Use reloc-macros.h.
+ * arm.h: Use reloc-macros.h.
+ * d10v.h: Use reloc-macros.h.
+ * d30v.h: Use reloc-macros.h.
+ * hppa.h: Use reloc-macros.h.
+ * i386.h: Use reloc-macros.h.
+ * m32r.h: Use reloc-macros.h.
+ * m68k.h: Use reloc-macros.h.
+ * mips.h: Use reloc-macros.h.
+ * mn10200.h: Use reloc-macros.h.
+ * mn10300.h: Use reloc-macros.h.
+ * ppc.h: Use reloc-macros.h.
+ * sh.h: Use reloc-macros.h.
+ * sparc.h: Use reloc-macros.h.
+ * v850.h: Use reloc-macros.h.
+
+1998-07-22 13:07 Ulrich Drepper <drepper@cygnus.com>
+
+ * mn10300.h: Rewrite relocation definition using macros.
+ * mips.h: Likewise.
+ * ppc.h: Likewise.
+ * alpha.h: Likewise.
+ * arm.h: Likewise.
+ * d10v.h: Likewise.
+ * d30v.h: Likewise.
+ * m32r.h: Likewise.
+ * m68k.h: Likewise.
+ * mn10200.h: Likewise.
+ * sh.h: Likewise.
+ * sparc.h: Likewise.
+
+1998-07-21 13:07 Ulrich Drepper <drepper@cygnus.com>
+
+ * arm.h: New file.
+ * d10v.h: New file.
+ * d30v.h: New file.
+ * i386.h: New file.
+ * m68k.h: New file.
+ * mn10200.h: New file.
+ * sh.h: New file.
+
+ * mips.h: Add R_MIPS_* and SHT_MIPS_* entries.
+
+ * mn10300.h: Add R_MN10300_* entries.
+
+ * ppc.h: Add R_PPC_* entries.
+
+1998-07-20 07:11 Ulrich Drepper <drepper@cygnus.com>
+
+ * mips.h: Add ODK_*, OEX_*, OPAD_*, OHW_*, and OGP_* constants.
+ Define Elf32_External_Lib.
+
+1998-07-19 15:24 Ulrich Drepper <drepper@cygnus.com>
+
+ * mips.h (PT_MIPS_OPTIONS): New symbol.
+ Add lots of DT_MIPS_* symbols.
+
+Fri Jun 26 10:46:35 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h: New file.
+
+Thu Jun 18 19:27:56 1998 Nick Clifton <nickc@cygnus.com>
+
+ * common.h (EM_960, EM_V800, EM_FR20, EM_RH32, EM_MMA,
+ EM_OLD_ALPHA): Add these constants.
+
+Thu Jun 11 17:59:01 1998 Nick Clifton <nickc@cygnus.com>
+
+ * common.h (EM_486, EM_S370): Add these constants.
+
+Tue Jun 9 09:35:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * common.h (EM_ARM): Add this constant.
+
+Wed May 6 09:45:30 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips.h (EF_MIPS_MACH,E_MIPS_MACH_*): Added.
+
+Sat Apr 25 18:35:06 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (STO_ALPHA_NOPV, STO_ALPHA_STD_GPLOAD): New.
+
+Wed Apr 15 15:42:45 1998 Richard Henderson <rth@cygnus.com>
+
+ * common.h (EM_SPARC64): Move and rename to EM_OLD_SPARCV9.
+ (EM_SPARCV9): New. This is the official ABI name and number.
+
+Sat Feb 28 17:04:41 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (EF_ALPHA_32BIT, EF_ALPHA_CANRELAX): New.
+
+Mon Dec 15 15:07:49 1997 Nick Clifton <nickc@cygnus.com>
+
+ * m32r.h (EF_M32R_ARCH, E_M32R_ARCH): New flags to
+ specify machine architecture.
+
+Fri Dec 5 11:20:08 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h: New constants: SHN_V850_SCOMMON, SHN_V850_TCOMMON,
+ SHN_V850_ZCOMMON, SHT_V850_SCOMMON, SHT_V850_TCOMMON,
+ SHT_V850_ZCOMMON to handle v850 common sections.
+ enum reloc_type renamed to v850_reloc_type to avoid name
+ conflict.
+
+Thu Oct 23 13:55:24 1997 Richard Henderson <rth@cygnus.com>
+
+ * sparc.h (enum elf_sparc_reloc_type): Add UA64 & UA16.
+
+Thu Oct 23 00:42:04 1997 Richard Henderson <rth@dot.cygnus.com>
+
+ * sparc.h (DT_SPARC_REGISTER): New macro.
+ (DT_SPARC_PLTFMT): In support of old sparc64-linux .plts; will
+ go away soon.
+
+Tue Sep 30 13:26:58 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (EF_SPARC_HAL_R1, EF_SPARC_EXT_MASK): New macros.
+ (EF_SPARCV9_{MM,TSO,PSO,RMO}): New macros.
+ (SHN_BEFORE,SHN_AFTER): New macros.
+ (SHF_EXCLUDE,SHF_ORDERED): New macros.
+ (STT_REGISTER): New macro.
+ (R_SPARC_GLOB_JMP): Deleted, but slot reserved.
+ (R_SPARC_{DISP64,PLT64,HIX22,LOX10}): New relocations.
+ (R_SPARC_{H44,M44,L44,REGISTER}): New relocations.
+ (ELF64_R_TYPE_{DATA,ID,INFO}): New macros.
+
+Wed Sep 17 16:41:42 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h: Add R_V850_CALLT_6_7_OFFSET and R_V850_CALLT_16_16_OFFSET.
+
+Tue Sep 16 14:16:17 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (reloc_type): Add R_V850_TDA_16_16_OFFSET.
+
+Wed Sep 3 15:11:14 1997 Richard Henderson <rth@cygnus.com>
+
+ * mips.h: Correct typo in comment.
+
+Wed Sep 3 11:25:57 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (reloc_type): Remove R_V850_16_PCREL.
+
+Tue Sep 2 17:41:05 1997 Nick Clifton <nickc@cygnus.com>
+
+ * common.h: Remove magic number for V850E.
+ * common.h: Remove magic number for V850EA.
+ * v850.h: Add new flags for e_flags field in elf header.
+
+Mon Aug 25 16:06:47 1997 Nick Clifton <nickc@cygnus.com>
+
+ * common.h (EM_CYGNUS_V850E): backend magic number for v850e.
+ * common.h (EM_CYGNUS_V850EA): backend magic number for v850ea.
+
+Mon Aug 18 11:05:23 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (reloc_type): Add 16 bit PC relative relocation.
+
+Fri Aug 15 05:10:09 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc.h (enum reloc): Move here from elf32-arc.c.
+
+Fri Aug 8 17:05:29 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc.h: New file.
+ * common.h (EM_CYGNUS_ARC): Define.
+
+Mon Jun 16 14:46:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (Elf_Internal_Ehdr): Change e_phoff and e_shoff from
+ bfd_signed_vma to bfd_size_type, as they are not signed.
+
+Wed Mar 5 15:35:26 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * m32r.h (SHF_M32R_CAN_RELAX): Define.
+
+Mon Feb 24 17:49:01 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * external.h: Dump the 32/64 bit specific forms of the version
+ structures, and just define them as size independent.
+
+ * common.h (VERSYM_HIDDEN, VERSYM_VERSION): Define.
+
+Fri Feb 21 13:00:34 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r.h (enum reloc_type): Add R_M32R_SDA16.
+ (SHN_M32R_SCOMMON): Define.
+
+Wed Feb 19 15:35:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * external.h, internal.h, common.h: Added new structures and
+ definitions for ELF versions.
+
+Tue Feb 18 17:40:36 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * common.h (EM_CYGNUS_D30V): Define.
+
+Mon Jan 27 11:54:44 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * m32r.h (enum reloc_type): Add R_M32R_HI16_[SU]LO,R_M32R_LO16.
+
+Fri Jan 3 11:32:51 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850.h (V850_OTHER_{TDA_BYTE,ERROR}): New bits for the st_other
+ field.
+ (SHN_V850_*): Remove v850 specific section indexes, which are not
+ needed.
+ (enum reloc_type): Move the v850 relocations here from
+ elf32-v850.c
+
+Thu Jan 2 19:30:23 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850.h: New file, provide V850 specific definitions.
+
+Tue Dec 31 14:44:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * common.h (DT_AUXILIARY): Define.
+ (DT_FILTER): Define.
+
+Wed Dec 4 05:03:37 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2.h: Update.
+
+Tue Nov 26 10:44:47 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (STO_MIPS16): Define.
+
+Tue Nov 12 15:45:42 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h: Remove empty file.
+
+Tue Oct 8 11:31:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (EF_MIPS_ABI2): Define.
+
+Thu Oct 3 10:01:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * common.h: Break mn10x00 support into mn10200 and mn10300.
+
+Wed Oct 2 21:26:43 1996 Jeffrey A Law (law@cygnus.com)
+
+ * common.h (EM_CYGNUS_MN10x00): Define.
+
+Mon Sep 23 09:18:04 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * m32r.h: New file.
+
+Fri Aug 30 17:06:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * common.h (EM_SH): Define.
+
+Tue Aug 20 14:47:54 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * common.h (EM_CYGNUS_V850): Define.
+
+Mon Aug 19 10:59:10 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * common.h (EM_CYGNUS_M32R): Define.
+
+Mon Jul 22 18:59:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (SHT_MIPS_IFACE, SHT_MIPS_CONTENT): Define.
+ (SHT_MIPS_SYMBOL_LIB): Define.
+ (SHF_MIPS_MERGE, SHF_MIPS_ADDR32, SHF_MIPS_ADDR64): Define.
+ (SHF_MIPS_NOSTRIP, SHF_MIPS_LOCAL, SHF_MIPS_NAMES): Define.
+
+Thu Jul 18 19:12:15 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * dwarf2.h: New file.
+
+Jul 18 13:20:39 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * common.h (EM_CYGNUS_D10V): Define.
+ * d10v.h: New file.
+
+Fri Jun 21 12:33:24 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha.h: New file.
+ * common.h (EM_ALPHA): Define.
+
+Fri May 31 17:28:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (Elf_External_Options, Elf_Internal_Options): Define.
+ (bfd_mips_elf_swap_options_in): Declare.
+ (bfd_mips_elf_swap_options_out): Declare.
+ (ODK_*): Define.
+ (Elf64_External_RegInfo, Elf64_Internal_RegInfo): Define.
+ (bfd_mips_elf64_swap_reginfo_in): Declare.
+ (bfd_mips_elf64_swap_reginfo_out): Declare.
+
+Thu May 30 12:35:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (E_MIPS_ARCH_4): Define.
+
+Wed May 29 15:35:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (Elf64_Mips_External_Rel): Define.
+ (Elf64_Mips_Internal_Rel): Define.
+ (Elf64_Mips_External_Rela, Elf64_Mips_Internal_Rela): Define.
+ (RSS_*): Define.
+
+Mon Apr 22 18:26:30 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (R_SPARC_[56]): Always define.
+
+Mon Feb 19 01:55:56 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (R_SPARC_{PLT32,HIPLT22,LOPLT10,PCPLT32,PCPLT22,
+ PCPLT10,5,6}): Don't define ifdef SPARC64_OLD_RELOCS.
+
+Tue Feb 6 11:33:58 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (enum sparc_elf_reloc_type): Define.
+
+Wed Jan 17 09:09:16 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * common.h: Define EM_SPARC32PLUS.
+ * sparc.h: New file.
+
+Thu Jan 11 16:27:34 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc.h (SHF_EXCLUDE, SHT_ORDERED): New fields from the abi.
+
+Thu Nov 30 16:47:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (struct elf_segment_map): Add includes_filehdr and
+ includes_phdrs fields.
+
+Tue Nov 28 16:58:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * internal.h (struct elf_segment_map): Define.
+
+Tue Oct 31 15:19:36 1995 Fred Fish <fnf@cygnus.com>
+
+ * common.h, dwarf.h, external.h, hppa.h, internal.h,
+ mips.h, ppc.h: Protect against multiple inclusions.
+
+Thu Sep 21 13:51:58 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc.h (EF_PPC_RELOCATABLE_LIB): Add new flag bit.
+
+Fri Sep 1 15:32:17 1995 Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>
+
+ * mips.h: Add some definitions used on Irix 5.
+
+Tue Jun 20 10:18:28 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa.h (CPU_PA_RISC1_0): Protect from redefinitions.
+ (CPU_PA_RISC1_1): Likewise.
+
+Wed Mar 8 18:14:37 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc.h: New file for PowerPC support.
+
+Tue Feb 14 13:59:13 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * common.h (EM_PPC): Use offical value of 20, not 17.
+ (EM_PPC_OLD): Define this to be the old value of EM_PPC.
+
+Tue Jan 24 09:40:59 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * common.h (EM_PPC): New macro, PowerPC machine id.
+
+Tue Jan 17 10:51:38 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * mips.h (SHT_MIPS_MSYM, SHT_MIPS_DWARF, SHT_MIPS_EVENTS): Define.
+
+Mon Oct 17 13:43:59 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * internal.h (Elf_Internal_Shdr): Remove rawdata and size fields.
+ Add bfd_section field.
+
+Tue May 24 16:11:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (Elf32_External_gptab): Define.
+
+Mon May 16 13:22:04 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * common.h (EM_HPPA): Delete.
+ (EM_PARISC): Add.
+ * hppa.h: New file.
+
+Mon May 9 13:27:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * common.h (SHN_LORESERVE): Rename from SHN_LORESERV.
+ (ELF32_R_TYPE, ELF32_R_INFO): Don't rely on size of unsigned char.
+ (ELF64_R_TYPE): Don't rely on size of unsigned long.
+
+Mon Apr 25 15:53:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * internal.h (Elf_Internal_Shdr): Use PTR, not void *.
+
+Fri Mar 11 00:34:59 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips.h (SHN_MIPS_TEXT, SHN_MIPS_DATA): Define.
+
+Sat Mar 5 14:08:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * internal.h: Remove Elf32_*, Elf64_* typedefs. These names
+ cause conflicts with system headers, e.g. link.h in gdb/solib.c.
+ Combine 32- and 64-bit versions of *_Internal_Dyn.
+ * common.h: Replace uses of Elf64_Word, Elf64_Xword typedefs
+ by their expansion.
+ * mips.h: Replace uses of Elf32_Word, Elf32_Sword, Elf32_Addr
+ typedefs by their expansion. Add DT_MIPS_RLD_MAP definition.
+
+Fri Feb 18 10:39:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * common.h (EM_CYGNUS_POWERPC): Define. This may be temporary,
+ depending upon how quickly I can find a real PowerPC ABI.
+
+Mon Feb 7 08:27:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * internal.h: Change HOST_64_BIT to BFD_HOST_64_BIT.
+
+Wed Feb 2 14:12:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * common.h: Add comments regarding value of EM_HPPA and how to
+ pick an unofficial value.
+
+Wed Nov 17 17:14:26 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (SHT_MIPS_OPTIONS): Define.
+
+Mon Nov 8 17:57:00 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h: Added some more MIPS ABI macro definitions.
+
+Wed Nov 3 22:07:17 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * common.h (EM_MIPS_RS4_BE): New macro.
+
+Tue Oct 12 07:28:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h: New file. MIPS ABI specific information.
+
+Mon Jun 21 13:13:43 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * internal.h: Combined 32- and 64-bit versions of all structures
+ except *_Internal_Dyn. This will simply the assembler interface,
+ and some bfd code.
+
+Tue May 25 02:00:16 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * external.h, internal.h, common.h: Added 64-bit versions of some
+ structures and macros. Renamed old versions to put "32" in the
+ name. Some are unchanged.
+
+Thu Apr 29 12:12:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros.
+ * external.h (Elf_External_Dyn): New type.
+
+ * internal.h (Elf_Intenral_Shdr): New field `size'.
+ (Elf_Internal_Dyn): New type.
+
+Tue Apr 20 16:03:45 1993 Fred Fish (fnf@cygnus.com)
+
+ * dwarf.h (LANG_CHILL): Change value to one randomly picked in
+ the user defined range, to reduce probability of collisions.
+
+Sun Nov 15 09:34:02 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarf.h (AT_src_coords): Whitespace change only.
+ * dwarf.h (AT_body_begin, AT_body_end, LANG_MODULA2):
+ Add from latest gcc.
+ * dwarf.h (LANG_CHILL): Add as GNU extension.
+
+Sat Aug 1 13:46:53 1992 Fred Fish (fnf@cygnus.com)
+
+ * dwarf.h: Replace with current version from gcc distribution.
+
+Fri Jun 19 19:05:09 1992 John Gilmore (gnu at cygnus.com)
+
+ * internal.h: Add real struct tags to all the Type_Defs, so they
+ can be used in prototypes where the Type_Defs are not known.
+
+Fri Apr 3 20:58:58 1992 Mark Eichin (eichin at cygnus.com)
+
+ * common.h: added ELF_R_{SYM,TYPE,INFO} for handling relocation
+ info
+ added EM_MIPS, and corrected value of EM_860 based on System V ABI
+ manual.
+
+ * external.h: added Elf_External_{Rel,Rela}.
+
+ * internal.h: added Elf_Internal_{Rel,Rela}.
+ added rawdata to Elf_Internal_Shdr.
+
+Sat Nov 30 20:43:59 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * common.h, dwarf.h, external.h, internal.h, ChangeLog; moved from
+ ../elf-<foo>
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/include/elf/alpha.h b/include/elf/alpha.h
new file mode 100644
index 00000000000..1ae9d5efd6d
--- /dev/null
+++ b/include/elf/alpha.h
@@ -0,0 +1,108 @@
+/* ALPHA ELF support for BFD.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+
+ By Eric Youngdale, <eric@aib.com>. No processor supplement available
+ for this platform.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the ALPHA ELF ABI. Note
+ that most of this is not actually implemented by BFD. */
+
+#ifndef _ELF_ALPHA_H
+#define _ELF_ALPHA_H
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* All addresses must be below 2GB. */
+#define EF_ALPHA_32BIT 0x00000001
+
+/* All relocations needed for relaxation with code movement are present. */
+#define EF_ALPHA_CANRELAX 0x00000002
+
+/* Processor specific section flags. */
+
+/* This section must be in the global data area. */
+#define SHF_ALPHA_GPREL 0x10000000
+
+/* Section contains some sort of debugging information. The exact
+ format is unspecified. It's probably ECOFF symbols. */
+#define SHT_ALPHA_DEBUG 0x70000001
+
+/* Section contains register usage information. */
+#define SHT_ALPHA_REGINFO 0x70000002
+
+/* A section of type SHT_MIPS_REGINFO contains the following
+ structure. */
+typedef struct
+{
+ /* Mask of general purpose registers used. */
+ unsigned long ri_gprmask;
+ /* Mask of co-processor registers used. */
+ unsigned long ri_cprmask[4];
+ /* GP register value for this object file. */
+ long ri_gp_value;
+} Elf64_RegInfo;
+
+/* Special values for the st_other field in the symbol table. */
+
+#define STO_ALPHA_NOPV 0x80
+#define STO_ALPHA_STD_GPLOAD 0x88
+
+#include "elf/reloc-macros.h"
+
+/* Alpha relocs. */
+START_RELOC_NUMBERS (elf_alpha_reloc_type)
+ RELOC_NUMBER (R_ALPHA_NONE, 0) /* No reloc */
+ RELOC_NUMBER (R_ALPHA_REFLONG, 1) /* Direct 32 bit */
+ RELOC_NUMBER (R_ALPHA_REFQUAD, 2) /* Direct 64 bit */
+ RELOC_NUMBER (R_ALPHA_GPREL32, 3) /* GP relative 32 bit */
+ RELOC_NUMBER (R_ALPHA_LITERAL, 4) /* GP relative 16 bit w/optimization */
+ RELOC_NUMBER (R_ALPHA_LITUSE, 5) /* Optimization hint for LITERAL */
+ RELOC_NUMBER (R_ALPHA_GPDISP, 6) /* Add displacement to GP */
+ RELOC_NUMBER (R_ALPHA_BRADDR, 7) /* PC+4 relative 23 bit shifted */
+ RELOC_NUMBER (R_ALPHA_HINT, 8) /* PC+4 relative 16 bit shifted */
+ RELOC_NUMBER (R_ALPHA_SREL16, 9) /* PC relative 16 bit */
+ RELOC_NUMBER (R_ALPHA_SREL32, 10) /* PC relative 32 bit */
+ RELOC_NUMBER (R_ALPHA_SREL64, 11) /* PC relative 64 bit */
+
+/* Inherited these from ECOFF, but they are not particularly useful
+ and are depreciated. And not implemented in the BFD, btw. */
+ RELOC_NUMBER (R_ALPHA_OP_PUSH, 12) /* OP stack push */
+ RELOC_NUMBER (R_ALPHA_OP_STORE, 13) /* OP stack pop and store */
+ RELOC_NUMBER (R_ALPHA_OP_PSUB, 14) /* OP stack subtract */
+ RELOC_NUMBER (R_ALPHA_OP_PRSHIFT, 15) /* OP stack right shift */
+
+ RELOC_NUMBER (R_ALPHA_GPVALUE, 16)
+ RELOC_NUMBER (R_ALPHA_GPRELHIGH, 17)
+ RELOC_NUMBER (R_ALPHA_GPRELLOW, 18)
+ RELOC_NUMBER (R_ALPHA_IMMED_GP_16, 19)
+ RELOC_NUMBER (R_ALPHA_IMMED_GP_HI32, 20)
+ RELOC_NUMBER (R_ALPHA_IMMED_SCN_HI32, 21)
+ RELOC_NUMBER (R_ALPHA_IMMED_BR_HI32, 22)
+ RELOC_NUMBER (R_ALPHA_IMMED_LO32, 23)
+
+/* These relocations are specific to shared libraries. */
+ RELOC_NUMBER (R_ALPHA_COPY, 24) /* Copy symbol at runtime */
+ RELOC_NUMBER (R_ALPHA_GLOB_DAT, 25) /* Create GOT entry */
+ RELOC_NUMBER (R_ALPHA_JMP_SLOT, 26) /* Create PLT entry */
+ RELOC_NUMBER (R_ALPHA_RELATIVE, 27) /* Adjust by program base */
+
+ EMPTY_RELOC (R_ALPHA_max)
+END_RELOC_NUMBERS
+
+#endif /* _ELF_ALPHA_H */
diff --git a/include/elf/arc.h b/include/elf/arc.h
new file mode 100644
index 00000000000..334b55fa6d0
--- /dev/null
+++ b/include/elf/arc.h
@@ -0,0 +1,54 @@
+/* ARC ELF support for BFD.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans, (dje@cygnus.com)
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the ARC ELF ABI. */
+
+#ifndef _ELF_ARC_H
+#define _ELF_ARC_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_arc_reloc_type)
+ RELOC_NUMBER (R_ARC_NONE, 0)
+ RELOC_NUMBER (R_ARC_32, 1)
+ RELOC_NUMBER (R_ARC_B26, 2)
+ RELOC_NUMBER (R_ARC_B22_PCREL, 3)
+ EMPTY_RELOC (R_ARC_max)
+END_RELOC_NUMBERS
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* Four bit ARC machine type field. */
+#define EF_ARC_MACH 0x0000000f
+
+/* Various CPU types. */
+#define E_ARC_MACH_BASE 0x00000000
+#define E_ARC_MACH_UNUSED1 0x00000001
+#define E_ARC_MACH_UNUSED2 0x00000002
+#define E_ARC_MACH_UNUSED4 0x00000003
+
+/* Leave bits 0xf0 alone in case we ever have more than 16 cpu types.
+ Highly unlikely, but what the heck. */
+
+/* File contains position independent code. */
+#define EF_ARC_PIC 0x00000100
+
+#endif /* _ELF_ARC_H */
diff --git a/include/elf/arm-oabi.h b/include/elf/arm-oabi.h
new file mode 100644
index 00000000000..6109842e83d
--- /dev/null
+++ b/include/elf/arm-oabi.h
@@ -0,0 +1,87 @@
+/* ARM ELF support for BFD.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_ARM_H
+#define _ELF_ARM_H
+
+#include "elf/reloc-macros.h"
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_INTERWORK 0x04
+#define EF_APCS_26 0x08
+#define EF_APCS_FLOAT 0x10
+#define EF_PIC 0x20
+#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */
+#define EF_NEW_ABI 0x80
+#define EF_OLD_ABI 0x100
+
+/* Local aliases for some flags to match names used by COFF port. */
+#define F_INTERWORK EF_INTERWORK
+#define F_APCS26 EF_APCS_26
+#define F_APCS_FLOAT EF_APCS_FLOAT
+#define F_PIC EF_PIC
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC 0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point */
+#define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base */
+
+/* Relocation types. */
+START_RELOC_NUMBERS (elf_arm_reloc_type)
+ RELOC_NUMBER (R_ARM_NONE, 0)
+ RELOC_NUMBER (R_ARM_PC24, 1)
+ RELOC_NUMBER (R_ARM_ABS32, 2)
+ RELOC_NUMBER (R_ARM_REL32, 3)
+ RELOC_NUMBER (R_ARM_ABS8, 4)
+ RELOC_NUMBER (R_ARM_ABS16, 5)
+ RELOC_NUMBER (R_ARM_ABS12, 6)
+ RELOC_NUMBER (R_ARM_THM_ABS5, 7)
+ RELOC_NUMBER (R_ARM_THM_PC22, 8)
+ RELOC_NUMBER (R_ARM_SBREL32, 9)
+ RELOC_NUMBER (R_ARM_AMP_VCALL9, 10)
+ RELOC_NUMBER (R_ARM_THM_PC11, 11) /* cygnus extension to abi: thumb unconditional branch */
+ RELOC_NUMBER (R_ARM_THM_PC9, 12) /* cygnus extension to abi: thumb conditional branch */
+ RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 13)
+ RELOC_NUMBER (R_ARM_GNU_VTENTRY, 14)
+ RELOC_NUMBER (R_ARM_COPY, 20) /* copy symbol at runtime */
+ RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* create GOT entry */
+ RELOC_NUMBER (R_ARM_JUMP_SLOT, 22) /* create PLT entry */
+ RELOC_NUMBER (R_ARM_RELATIVE, 23) /* adjust by program base */
+ RELOC_NUMBER (R_ARM_GOTOFF, 24) /* 32 bit offset to GOT */
+ RELOC_NUMBER (R_ARM_GOTPC, 25) /* 32 bit PC relative offset to GOT */
+ RELOC_NUMBER (R_ARM_GOT32, 26) /* 32 bit GOT entry */
+ RELOC_NUMBER (R_ARM_PLT32, 27) /* 32 bit PLT address */
+ FAKE_RELOC (FIRST_INVALID_RELOC, 28)
+ FAKE_RELOC (LAST_INVALID_RELOC, 249)
+ RELOC_NUMBER (R_ARM_RSBREL32, 250)
+ RELOC_NUMBER (R_ARM_THM_RPC22, 251)
+ RELOC_NUMBER (R_ARM_RREL32, 252)
+ RELOC_NUMBER (R_ARM_RABS32, 253)
+ RELOC_NUMBER (R_ARM_RPC24, 254)
+ RELOC_NUMBER (R_ARM_RBASE, 255)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/arm.h b/include/elf/arm.h
new file mode 100644
index 00000000000..2c94b13e204
--- /dev/null
+++ b/include/elf/arm.h
@@ -0,0 +1,96 @@
+/* ARM ELF support for BFD.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_ARM_H
+#define _ELF_ARM_H
+
+#include "elf/reloc-macros.h"
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_INTERWORK 0x04
+#define EF_APCS_26 0x08
+#define EF_APCS_FLOAT 0x10
+#define EF_PIC 0x20
+#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */
+#define EF_NEW_ABI 0x80
+#define EF_OLD_ABI 0x100
+
+/* Local aliases for some flags to match names used by COFF port. */
+#define F_INTERWORK EF_INTERWORK
+#define F_APCS26 EF_APCS_26
+#define F_APCS_FLOAT EF_APCS_FLOAT
+#define F_PIC EF_PIC
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC 0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point */
+#define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base */
+
+/* Relocation types. */
+START_RELOC_NUMBERS (elf_arm_reloc_type)
+ RELOC_NUMBER (R_ARM_NONE, 0)
+ RELOC_NUMBER (R_ARM_PC24, 1)
+ RELOC_NUMBER (R_ARM_ABS32, 2)
+ RELOC_NUMBER (R_ARM_REL32, 3)
+ RELOC_NUMBER (R_ARM_PC13, 4)
+ RELOC_NUMBER (R_ARM_ABS16, 5)
+ RELOC_NUMBER (R_ARM_ABS12, 6)
+ RELOC_NUMBER (R_ARM_THM_ABS5, 7)
+ RELOC_NUMBER (R_ARM_ABS8, 8)
+ RELOC_NUMBER (R_ARM_SBREL32, 9)
+ RELOC_NUMBER (R_ARM_THM_PC22, 10)
+ RELOC_NUMBER (R_ARM_THM_PC8, 11)
+ RELOC_NUMBER (R_ARM_AMP_VCALL9, 12)
+ RELOC_NUMBER (R_ARM_SWI24, 13)
+ RELOC_NUMBER (R_ARM_THM_SWI8, 14)
+ RELOC_NUMBER (R_ARM_XPC25, 15)
+ RELOC_NUMBER (R_ARM_THM_XPC22, 16)
+ RELOC_NUMBER (R_ARM_COPY, 20) /* copy symbol at runtime */
+ RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* create GOT entry */
+ RELOC_NUMBER (R_ARM_JUMP_SLOT, 22) /* create PLT entry */
+ RELOC_NUMBER (R_ARM_RELATIVE, 23) /* adjust by program base */
+ RELOC_NUMBER (R_ARM_GOTOFF, 24) /* 32 bit offset to GOT */
+ RELOC_NUMBER (R_ARM_GOTPC, 25) /* 32 bit PC relative offset to GOT */
+ RELOC_NUMBER (R_ARM_GOT32, 26) /* 32 bit GOT entry */
+ RELOC_NUMBER (R_ARM_PLT32, 27) /* 32 bit PLT address */
+ FAKE_RELOC (FIRST_INVALID_RELOC1, 28)
+ FAKE_RELOC (LAST_INVALID_RELOC1, 99)
+ RELOC_NUMBER (R_ARM_GNU_VTENTRY, 100)
+ RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101)
+ RELOC_NUMBER (R_ARM_THM_PC11, 102) /* cygnus extension to abi: thumb unconditional branch */
+ RELOC_NUMBER (R_ARM_THM_PC9, 103) /* cygnus extension to abi: thumb conditional branch */
+ FAKE_RELOC (FIRST_INVALID_RELOC2, 104)
+ FAKE_RELOC (LAST_INVALID_RELOC2, 248)
+ RELOC_NUMBER (R_ARM_RXPC25, 249)
+ RELOC_NUMBER (R_ARM_RSBREL32, 250)
+ RELOC_NUMBER (R_ARM_THM_RPC22, 251)
+ RELOC_NUMBER (R_ARM_RREL32, 252)
+ RELOC_NUMBER (R_ARM_RABS32, 253)
+ RELOC_NUMBER (R_ARM_RPC24, 254)
+ RELOC_NUMBER (R_ARM_RBASE, 255)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/common.h b/include/elf/common.h
new file mode 100644
index 00000000000..cda3ba0d9d5
--- /dev/null
+++ b/include/elf/common.h
@@ -0,0 +1,454 @@
+/* ELF support for BFD.
+ Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support, from information published
+ in "UNIX System V Release 4, Programmers Guide: ANSI C and
+ Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+ that are common to both the internal and external representations.
+ For example, ELFMAG0 is the byte 0x7F in both the internal (in-memory)
+ and external (in-file) representations. */
+
+#ifndef _ELF_COMMON_H
+#define _ELF_COMMON_H
+
+/* Fields in e_ident[] */
+
+#define EI_MAG0 0 /* File identification byte 0 index */
+#define ELFMAG0 0x7F /* Magic number byte 0 */
+
+#define EI_MAG1 1 /* File identification byte 1 index */
+#define ELFMAG1 'E' /* Magic number byte 1 */
+
+#define EI_MAG2 2 /* File identification byte 2 index */
+#define ELFMAG2 'L' /* Magic number byte 2 */
+
+#define EI_MAG3 3 /* File identification byte 3 index */
+#define ELFMAG3 'F' /* Magic number byte 3 */
+
+#define EI_CLASS 4 /* File class */
+#define ELFCLASSNONE 0 /* Invalid class */
+#define ELFCLASS32 1 /* 32-bit objects */
+#define ELFCLASS64 2 /* 64-bit objects */
+
+#define EI_DATA 5 /* Data encoding */
+#define ELFDATANONE 0 /* Invalid data encoding */
+#define ELFDATA2LSB 1 /* 2's complement, little endian */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+
+#define EI_VERSION 6 /* File version */
+
+#define EI_OSABI 7 /* Operating System/ABI indication */
+#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX 1 /* HP-UX operating system */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define EI_ABIVERSION 8 /* ABI version */
+
+#define EI_PAD 9 /* Start of padding bytes */
+
+
+/* Values for e_type, which identifies the object file type */
+
+#define ET_NONE 0 /* No file type */
+#define ET_REL 1 /* Relocatable file */
+#define ET_EXEC 2 /* Executable file */
+#define ET_DYN 3 /* Shared object file */
+#define ET_CORE 4 /* Core file */
+#define ET_LOOS 0xFE00 /* Operating system-specific */
+#define ET_HIOS 0xFEFF /* Operating system-specific */
+#define ET_LOPROC 0xFF00 /* Processor-specific */
+#define ET_HIPROC 0xFFFF /* Processor-specific */
+
+/* Values for e_machine, which identifies the architecture */
+
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SUN SPARC */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola m68k family */
+#define EM_88K 5 /* Motorola m88k family */
+#define EM_486 6 /* Intel 80486 */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
+#define EM_S370 9 /* Amdahl */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
+
+#define EM_PARISC 15 /* HPPA */
+#define EM_VPP550 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+
+#define EM_V800 36 /* NEC V800 series */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH32 */
+#define EM_MCORE 39 /* Motorolla MCore */ /* May also be taken by Fujitsu MMA */
+#define EM_ARM 40 /* ARM */
+#define EM_OLD_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Hitachi SH */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_TRICORE 44 /* Siemens Tricore embedded processor */
+#define EM_ARC 45 /* Argonaut RISC Core, Argonaut Technologies Inc. */
+#define EM_H8_300 46 /* Hitachi H8/300 */
+#define EM_H8_300H 47 /* Hitachi H8/300H */
+#define EM_H8S 48 /* Hitachi H8S */
+#define EM_H8_500 49 /* Hitachi H8/500 */
+#define EM_IA_64 50 /* Intel MercedTM Processor */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_68HC12 53 /* Motorola M68HC12 */
+
+/* If it is necessary to assign new unofficial EM_* values, please pick large
+ random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
+ with official or non-GNU unofficial values.
+
+ NOTE: Do not just increment the most recent number by one.
+ Somebody else somewhere will do exactly the same thing, and you
+ will have a collision. Instead, pick a random number. */
+
+/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */
+#define EM_CYGNUS_POWERPC 0x9025
+
+/* Old version of Sparc v9, from before the ABI; this should be
+ removed shortly. */
+#define EM_OLD_SPARCV9 11
+
+/* Old version of PowerPC, this should be removed shortly. */
+#define EM_PPC_OLD 17
+
+/* Cygnus ARC ELF backend. Written in the absence of an ABI. */
+#define EM_CYGNUS_ARC 0x9040
+
+/* Cygnus M32R ELF backend. Written in the absence of an ABI. */
+#define EM_CYGNUS_M32R 0x9041
+
+/* Alpha backend magic number. Written in the absence of an ABI. */
+#define EM_ALPHA 0x9026
+
+/* D10V backend magic number. Written in the absence of an ABI. */
+#define EM_CYGNUS_D10V 0x7650
+
+/* D30V backend magic number. Written in the absence of an ABI. */
+#define EM_CYGNUS_D30V 0x7676
+
+/* V850 backend magic number. Written in the absense of an ABI. */
+#define EM_CYGNUS_V850 0x9080
+
+/* mn10200 and mn10300 backend magic numbers.
+ Written in the absense of an ABI. */
+#define EM_CYGNUS_MN10200 0xdead
+#define EM_CYGNUS_MN10300 0xbeef
+
+/* FR30 magic number - no EABI available. */
+#define EM_CYGNUS_FR30 0x3330
+
+/* See the above comment before you add a new EM_* value here. */
+
+/* Values for e_version */
+
+#define EV_NONE 0 /* Invalid ELF version */
+#define EV_CURRENT 1 /* Current version */
+
+/* Values for program header, p_type field */
+
+#define PT_NULL 0 /* Program header table entry unused */
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved, unspecified semantics */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_LOOS 0x60000000 /* OS-specific */
+#define PT_HIOS 0x6fffffff /* OS-specific */
+#define PT_LOPROC 0x70000000 /* Processor-specific */
+#define PT_HIPROC 0x7FFFFFFF /* Processor-specific */
+
+/* Program segment permissions, in program header p_flags field */
+
+#define PF_X (1 << 0) /* Segment is executable */
+#define PF_W (1 << 1) /* Segment is writable */
+#define PF_R (1 << 2) /* Segment is readable */
+#define PF_MASKOS 0x0F000000 /* OS-specific reserved bits */
+#define PF_MASKPROC 0xF0000000 /* Processor-specific reserved bits */
+
+/* Values for section header, sh_type field */
+
+#define SHT_NULL 0 /* Section header table entry unused */
+#define SHT_PROGBITS 1 /* Program specific (private) data */
+#define SHT_SYMTAB 2 /* Link editing symbol table */
+#define SHT_STRTAB 3 /* A string table */
+#define SHT_RELA 4 /* Relocation entries with addends */
+#define SHT_HASH 5 /* A symbol hash table */
+#define SHT_DYNAMIC 6 /* Information for dynamic linking */
+#define SHT_NOTE 7 /* Information that marks file */
+#define SHT_NOBITS 8 /* Section occupies no space in file */
+#define SHT_REL 9 /* Relocation entries, no addends */
+#define SHT_SHLIB 10 /* Reserved, unspecified semantics */
+#define SHT_DYNSYM 11 /* Dynamic linking symbol table */
+
+#define SHT_LOOS 0x60000000 /* Operating system specific semantics, lo */
+#define SHT_HIOS 0x6fffffff /* Operating system specific semantics, hi */
+
+/* The next three section types are defined by Solaris, and are named
+ SHT_SUNW*. We use them in GNU code, so we also define SHT_GNU*
+ versions. */
+#define SHT_SUNW_verdef 0x6ffffffd /* Versions defined by file */
+#define SHT_SUNW_verneed 0x6ffffffe /* Versions needed by file */
+#define SHT_SUNW_versym 0x6fffffff /* Symbol versions */
+
+#define SHT_GNU_verdef SHT_SUNW_verdef
+#define SHT_GNU_verneed SHT_SUNW_verneed
+#define SHT_GNU_versym SHT_SUNW_versym
+
+#define SHT_LOPROC 0x70000000 /* Processor-specific semantics, lo */
+#define SHT_HIPROC 0x7FFFFFFF /* Processor-specific semantics, hi */
+#define SHT_LOUSER 0x80000000 /* Application-specific semantics */
+#define SHT_HIUSER 0x8FFFFFFF /* Application-specific semantics */
+
+/* Values for section header, sh_flags field */
+
+#define SHF_WRITE (1 << 0) /* Writable data during execution */
+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
+#define SHF_EXECINSTR (1 << 2) /* Executable machine instructions */
+#define SHF_MASKOS 0x0F000000 /* OS-specific semantics */
+#define SHF_MASKPROC 0xF0000000 /* Processor-specific semantics */
+
+/* Values of note segment descriptor types for core files. */
+
+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
+
+/* Note segments for core files on dir-style procfs systems. */
+
+#define NT_PSTATUS 10 /* Has a struct pstatus */
+#define NT_FPREGS 12 /* Has a struct fpregset */
+#define NT_PSINFO 13 /* Has a struct psinfo */
+#define NT_LWPSTATUS 16 /* Has a struct lwpstatus_t */
+#define NT_LWPSINFO 17 /* Has a struct lwpsinfo_t */
+
+/* Values of note segment descriptor types for object files. */
+/* (Only for hppa right now. Should this be moved elsewhere?) */
+
+#define NT_VERSION 1 /* Contains a version string. */
+
+/* These three macros disassemble and assemble a symbol table st_info field,
+ which contains the symbol binding and symbol type. The STB_ and STT_
+ defines identify the binding and type. */
+
+#define ELF_ST_BIND(val) (((unsigned int)(val)) >> 4)
+#define ELF_ST_TYPE(val) ((val) & 0xF)
+#define ELF_ST_INFO(bind,type) (((bind) << 4) + ((type) & 0xF))
+
+#define STN_UNDEF 0 /* undefined symbol index */
+
+#define STB_LOCAL 0 /* Symbol not visible outside obj */
+#define STB_GLOBAL 1 /* Symbol visible outside obj */
+#define STB_WEAK 2 /* Like globals, lower precedence */
+#define STB_LOOS 10 /* OS-specific semantics */
+#define STB_HIOS 12 /* OS-specific semantics */
+#define STB_LOPROC 13 /* Application-specific semantics */
+#define STB_HIPROC 15 /* Application-specific semantics */
+
+#define STT_NOTYPE 0 /* Symbol type is unspecified */
+#define STT_OBJECT 1 /* Symbol is a data object */
+#define STT_FUNC 2 /* Symbol is a code object */
+#define STT_SECTION 3 /* Symbol associated with a section */
+#define STT_FILE 4 /* Symbol gives a file name */
+#define STT_LOOS 10 /* OS-specific semantics */
+#define STT_HIOS 12 /* OS-specific semantics */
+#define STT_LOPROC 13 /* Application-specific semantics */
+#define STT_HIPROC 15 /* Application-specific semantics */
+
+/* Special section indices, which may show up in st_shndx fields, among
+ other places. */
+
+#define SHN_UNDEF 0 /* Undefined section reference */
+#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
+#define SHN_LOPROC 0xFF00 /* Begin range of appl-specific */
+#define SHN_HIPROC 0xFF1F /* End range of appl-specific */
+#define SHN_LOOS 0xFF20 /* OS specific semantics, lo */
+#define SHN_HIOS 0xFF3F /* OS specific semantics, hi */
+#define SHN_ABS 0xFFF1 /* Associated symbol is absolute */
+#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */
+#define SHN_HIRESERVE 0xFFFF /* End range of reserved indices */
+
+/* relocation info handling macros */
+
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((i) & 0xff)
+#define ELF32_R_INFO(s,t) (((s) << 8) + ((t) & 0xff))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+#define ELF64_R_INFO(s,t) (((bfd_vma) (s) << 32) + (bfd_vma) (t))
+
+/* Dynamic section tags */
+
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_BIND_NOW 24
+#define DT_INIT_ARRAY 25
+#define DT_FINI_ARRAY 26
+#define DT_INIT_ARRAYSZ 27
+#define DT_FINI_ARRAYSZ 28
+
+#define DT_LOOS 0x60000000
+#define DT_HIOS 0x6fffffff
+
+/* The next four dynamic tags are used on Solaris. We support them
+ everywhere. */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_PLTPADSZ 0x6ffffdf9
+#define DT_MOVEENT 0x6ffffdfa
+#define DT_MOVESZ 0x6ffffdfb
+#define DT_FEATURE_1 0x6ffffdfc
+#define DT_POSFLAG_1 0x6ffffdfd
+#define DT_SYMINSZ 0x6ffffdfe
+#define DT_SYMINENT 0x6ffffdff
+#define DT_VALRNGHI 0x6ffffdff
+
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_SYMINFO 0x6ffffeff
+#define DT_ADDRRNGHI 0x6ffffeff
+
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+#define DT_FLAGS_1 0x6ffffffb
+#define DT_VERDEF 0x6ffffffc
+#define DT_VERDEFNUM 0x6ffffffd
+#define DT_VERNEED 0x6ffffffe
+#define DT_VERNEEDNUM 0x6fffffff
+
+/* This tag is a GNU extension to the Solaris version scheme. */
+#define DT_VERSYM 0x6ffffff0
+
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* These section tags are used on Solaris. We support them
+ everywhere, and hope they do not conflict. */
+
+#define DT_AUXILIARY 0x7ffffffd
+#define DT_USED 0x7ffffffe
+#define DT_FILTER 0x7fffffff
+
+/* Values used in DT_FEATURE_1 .dynamic entry. */
+#define DTF_1_PARINIT 0x00000001
+
+/* Flag values used in the DT_POSFLAG_1 .dynamic entry. */
+#define DF_P1_LAZYLOAD 0x00000001
+#define DF_P1_GROUPPERM 0x00000002
+
+/* Flag value in in the DT_1_FLAGS .dynamic entry. */
+#define DF_1_NOW 0x00000001
+#define DF_1_GLOBAL 0x00000002
+#define DF_1_GROUP 0x00000004
+#define DF_1_NODELETE 0x00000008
+#define DF_1_LOADFLTR 0x00000010
+#define DF_1_INITFIRST 0x00000020
+#define DF_1_NOOPEN 0x00000040
+#define DF_1_ORIGIN 0x00000080
+#define DF_1_DIRECT 0x00000100
+#define DF_1_TRANS 0x00000200
+#define DF_1_INTERPOSE 0x00000400
+
+/* These constants are used for the version number of a Elf32_Verdef
+ structure. */
+
+#define VER_DEF_NONE 0
+#define VER_DEF_CURRENT 1
+
+/* These constants appear in the vd_flags field of a Elf32_Verdef
+ structure. */
+
+#define VER_FLG_BASE 0x1
+#define VER_FLG_WEAK 0x2
+
+/* These special constants can be found in an Elf32_Versym field. */
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+
+/* These constants are used for the version number of a Elf32_Verneed
+ structure. */
+
+#define VER_NEED_NONE 0
+#define VER_NEED_CURRENT 1
+
+/* This flag appears in a Versym structure. It means that the symbol
+ is hidden, and is only visible with an explicit version number.
+ This is a GNU extension. */
+
+#define VERSYM_HIDDEN 0x8000
+
+/* This is the mask for the rest of the Versym information. */
+
+#define VERSYM_VERSION 0x7fff
+
+/* This is a special token which appears as part of a symbol name. It
+ indictes that the rest of the name is actually the name of a
+ version node, and is not part of the actual name. This is a GNU
+ extension. For example, the symbol name `stat@ver2' is taken to
+ mean the symbol `stat' in version `ver2'. */
+
+#define ELF_VER_CHR '@'
+
+/* Possible values for si_boundto. */
+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags. */
+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
+ loaded */
+/* Syminfo version values. */
+#define SYMINFO_NONE 0
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+#endif /* _ELF_COMMON_H */
diff --git a/include/elf/d10v.h b/include/elf/d10v.h
new file mode 100644
index 00000000000..63b79c801b1
--- /dev/null
+++ b/include/elf/d10v.h
@@ -0,0 +1,38 @@
+/* d10v ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_D10V_H
+#define _ELF_D10V_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocation types. */
+START_RELOC_NUMBERS (elf_d10v_reloc_type)
+ RELOC_NUMBER (R_D10V_NONE, 0)
+ RELOC_NUMBER (R_D10V_10_PCREL_R, 1)
+ RELOC_NUMBER (R_D10V_10_PCREL_L, 2)
+ RELOC_NUMBER (R_D10V_16, 3)
+ RELOC_NUMBER (R_D10V_18, 4)
+ RELOC_NUMBER (R_D10V_18_PCREL, 5)
+ RELOC_NUMBER (R_D10V_32, 6)
+ RELOC_NUMBER (R_D10V_GNU_VTINHERIT, 7)
+ RELOC_NUMBER (R_D10V_GNU_VTENTRY, 8)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/d30v.h b/include/elf/d30v.h
new file mode 100644
index 00000000000..adbad192325
--- /dev/null
+++ b/include/elf/d30v.h
@@ -0,0 +1,42 @@
+/* d30v ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_D30V_H
+#define _ELF_D30V_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_d30v_reloc_type)
+ RELOC_NUMBER (R_D30V_NONE, 0)
+ RELOC_NUMBER (R_D30V_6, 1)
+ RELOC_NUMBER (R_D30V_9_PCREL, 2)
+ RELOC_NUMBER (R_D30V_9_PCREL_R, 3)
+ RELOC_NUMBER (R_D30V_15, 4)
+ RELOC_NUMBER (R_D30V_15_PCREL, 5)
+ RELOC_NUMBER (R_D30V_15_PCREL_R, 6)
+ RELOC_NUMBER (R_D30V_21, 7)
+ RELOC_NUMBER (R_D30V_21_PCREL, 8)
+ RELOC_NUMBER (R_D30V_21_PCREL_R, 9)
+ RELOC_NUMBER (R_D30V_32, 10)
+ RELOC_NUMBER (R_D30V_32_PCREL, 11)
+ RELOC_NUMBER (R_D30V_32_NORMAL, 12)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/dwarf.h b/include/elf/dwarf.h
new file mode 100644
index 00000000000..4333d5eda40
--- /dev/null
+++ b/include/elf/dwarf.h
@@ -0,0 +1,319 @@
+/* Declarations and definitions of codes relating to the DWARF symbolic
+ debugging information format.
+
+ Written by Ron Guilmette (rfg@ncd.com)
+
+Copyright (C) 1992 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file is derived from the DWARF specification (a public document)
+ Revision 1.0.1 (April 8, 1992) developed by the UNIX International
+ Programming Languages Special Interest Group (UI/PLSIG) and distributed
+ by UNIX International. Copies of this specification are available from
+ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
+*/
+
+#ifndef _ELF_DWARF_H
+#define _ELF_DWARF_H
+
+/* Tag names and codes. */
+
+enum dwarf_tag {
+ TAG_padding = 0x0000,
+ TAG_array_type = 0x0001,
+ TAG_class_type = 0x0002,
+ TAG_entry_point = 0x0003,
+ TAG_enumeration_type = 0x0004,
+ TAG_formal_parameter = 0x0005,
+ TAG_global_subroutine = 0x0006,
+ TAG_global_variable = 0x0007,
+ /* 0x0008 -- reserved */
+ /* 0x0009 -- reserved */
+ TAG_label = 0x000a,
+ TAG_lexical_block = 0x000b,
+ TAG_local_variable = 0x000c,
+ TAG_member = 0x000d,
+ /* 0x000e -- reserved */
+ TAG_pointer_type = 0x000f,
+ TAG_reference_type = 0x0010,
+ TAG_compile_unit = 0x0011,
+ TAG_string_type = 0x0012,
+ TAG_structure_type = 0x0013,
+ TAG_subroutine = 0x0014,
+ TAG_subroutine_type = 0x0015,
+ TAG_typedef = 0x0016,
+ TAG_union_type = 0x0017,
+ TAG_unspecified_parameters = 0x0018,
+ TAG_variant = 0x0019,
+ TAG_common_block = 0x001a,
+ TAG_common_inclusion = 0x001b,
+ TAG_inheritance = 0x001c,
+ TAG_inlined_subroutine = 0x001d,
+ TAG_module = 0x001e,
+ TAG_ptr_to_member_type = 0x001f,
+ TAG_set_type = 0x0020,
+ TAG_subrange_type = 0x0021,
+ TAG_with_stmt = 0x0022,
+
+ /* GNU extensions */
+
+ TAG_format_label = 0x8000, /* for FORTRAN 77 and Fortran 90 */
+ TAG_namelist = 0x8001, /* For Fortran 90 */
+ TAG_function_template = 0x8002, /* for C++ */
+ TAG_class_template = 0x8003 /* for C++ */
+};
+
+#define TAG_lo_user 0x8000 /* implementation-defined range start */
+#define TAG_hi_user 0xffff /* implementation-defined range end */
+#define TAG_source_file TAG_compile_unit /* for backward compatibility */
+
+/* Form names and codes. */
+
+enum dwarf_form {
+ FORM_ADDR = 0x1,
+ FORM_REF = 0x2,
+ FORM_BLOCK2 = 0x3,
+ FORM_BLOCK4 = 0x4,
+ FORM_DATA2 = 0x5,
+ FORM_DATA4 = 0x6,
+ FORM_DATA8 = 0x7,
+ FORM_STRING = 0x8
+};
+
+/* Attribute names and codes. */
+
+enum dwarf_attribute {
+ AT_sibling = (0x0010|FORM_REF),
+ AT_location = (0x0020|FORM_BLOCK2),
+ AT_name = (0x0030|FORM_STRING),
+ AT_fund_type = (0x0050|FORM_DATA2),
+ AT_mod_fund_type = (0x0060|FORM_BLOCK2),
+ AT_user_def_type = (0x0070|FORM_REF),
+ AT_mod_u_d_type = (0x0080|FORM_BLOCK2),
+ AT_ordering = (0x0090|FORM_DATA2),
+ AT_subscr_data = (0x00a0|FORM_BLOCK2),
+ AT_byte_size = (0x00b0|FORM_DATA4),
+ AT_bit_offset = (0x00c0|FORM_DATA2),
+ AT_bit_size = (0x00d0|FORM_DATA4),
+ /* (0x00e0|FORM_xxxx) -- reserved */
+ AT_element_list = (0x00f0|FORM_BLOCK4),
+ AT_stmt_list = (0x0100|FORM_DATA4),
+ AT_low_pc = (0x0110|FORM_ADDR),
+ AT_high_pc = (0x0120|FORM_ADDR),
+ AT_language = (0x0130|FORM_DATA4),
+ AT_member = (0x0140|FORM_REF),
+ AT_discr = (0x0150|FORM_REF),
+ AT_discr_value = (0x0160|FORM_BLOCK2),
+ /* (0x0170|FORM_xxxx) -- reserved */
+ /* (0x0180|FORM_xxxx) -- reserved */
+ AT_string_length = (0x0190|FORM_BLOCK2),
+ AT_common_reference = (0x01a0|FORM_REF),
+ AT_comp_dir = (0x01b0|FORM_STRING),
+ AT_const_value_string = (0x01c0|FORM_STRING),
+ AT_const_value_data2 = (0x01c0|FORM_DATA2),
+ AT_const_value_data4 = (0x01c0|FORM_DATA4),
+ AT_const_value_data8 = (0x01c0|FORM_DATA8),
+ AT_const_value_block2 = (0x01c0|FORM_BLOCK2),
+ AT_const_value_block4 = (0x01c0|FORM_BLOCK4),
+ AT_containing_type = (0x01d0|FORM_REF),
+ AT_default_value_addr = (0x01e0|FORM_ADDR),
+ AT_default_value_data2 = (0x01e0|FORM_DATA2),
+ AT_default_value_data4 = (0x01e0|FORM_DATA4),
+ AT_default_value_data8 = (0x01e0|FORM_DATA8),
+ AT_default_value_string = (0x01e0|FORM_STRING),
+ AT_friends = (0x01f0|FORM_BLOCK2),
+ AT_inline = (0x0200|FORM_STRING),
+ AT_is_optional = (0x0210|FORM_STRING),
+ AT_lower_bound_ref = (0x0220|FORM_REF),
+ AT_lower_bound_data2 = (0x0220|FORM_DATA2),
+ AT_lower_bound_data4 = (0x0220|FORM_DATA4),
+ AT_lower_bound_data8 = (0x0220|FORM_DATA8),
+ AT_private = (0x0240|FORM_STRING),
+ AT_producer = (0x0250|FORM_STRING),
+ AT_program = (0x0230|FORM_STRING),
+ AT_protected = (0x0260|FORM_STRING),
+ AT_prototyped = (0x0270|FORM_STRING),
+ AT_public = (0x0280|FORM_STRING),
+ AT_pure_virtual = (0x0290|FORM_STRING),
+ AT_return_addr = (0x02a0|FORM_BLOCK2),
+ AT_abstract_origin = (0x02b0|FORM_REF),
+ AT_start_scope = (0x02c0|FORM_DATA4),
+ AT_stride_size = (0x02e0|FORM_DATA4),
+ AT_upper_bound_ref = (0x02f0|FORM_REF),
+ AT_upper_bound_data2 = (0x02f0|FORM_DATA2),
+ AT_upper_bound_data4 = (0x02f0|FORM_DATA4),
+ AT_upper_bound_data8 = (0x02f0|FORM_DATA8),
+ AT_virtual = (0x0300|FORM_STRING),
+
+ /* GNU extensions. */
+
+ AT_sf_names = (0x8000|FORM_DATA4),
+ AT_src_info = (0x8010|FORM_DATA4),
+ AT_mac_info = (0x8020|FORM_DATA4),
+ AT_src_coords = (0x8030|FORM_DATA4),
+ AT_body_begin = (0x8040|FORM_ADDR),
+ AT_body_end = (0x8050|FORM_ADDR)
+};
+
+#define AT_lo_user 0x8000 /* implementation-defined range start */
+#define AT_hi_user 0xffff /* implementation-defined range end */
+
+/* Location atom names and codes. */
+
+enum dwarf_location_atom {
+ OP_REG = 0x01,
+ OP_BASEREG = 0x02,
+ OP_ADDR = 0x03,
+ OP_CONST = 0x04,
+ OP_DEREF2 = 0x05,
+ OP_DEREF4 = 0x06,
+ OP_ADD = 0x07
+};
+
+#define OP_LO_USER 0x80 /* implementation-defined range start */
+#define OP_HI_USER 0xff /* implementation-defined range end */
+
+/* Fundamental type names and codes. */
+
+enum dwarf_fundamental_type {
+ FT_char = 0x0001,
+ FT_signed_char = 0x0002,
+ FT_unsigned_char = 0x0003,
+ FT_short = 0x0004,
+ FT_signed_short = 0x0005,
+ FT_unsigned_short = 0x0006,
+ FT_integer = 0x0007,
+ FT_signed_integer = 0x0008,
+ FT_unsigned_integer = 0x0009,
+ FT_long = 0x000a,
+ FT_signed_long = 0x000b,
+ FT_unsigned_long = 0x000c,
+ FT_pointer = 0x000d, /* an alias for (void *) */
+ FT_float = 0x000e,
+ FT_dbl_prec_float = 0x000f,
+ FT_ext_prec_float = 0x0010, /* breaks "classic" svr4 SDB */
+ FT_complex = 0x0011, /* breaks "classic" svr4 SDB */
+ FT_dbl_prec_complex = 0x0012, /* breaks "classic" svr4 SDB */
+ /* 0x0013 -- reserved */
+ FT_void = 0x0014,
+ FT_boolean = 0x0015, /* breaks "classic" svr4 SDB */
+ FT_ext_prec_complex = 0x0016, /* breaks "classic" svr4 SDB */
+ FT_label = 0x0017,
+
+ /* GNU extensions
+ The low order byte must indicate the size (in bytes) for the type.
+ All of these types will probably break "classic" svr4 SDB */
+
+ FT_long_long = 0x8008,
+ FT_signed_long_long = 0x8108,
+ FT_unsigned_long_long = 0x8208,
+
+ FT_int8 = 0x9001,
+ FT_signed_int8 = 0x9101,
+ FT_unsigned_int8 = 0x9201,
+ FT_int16 = 0x9302,
+ FT_signed_int16 = 0x9402,
+ FT_unsigned_int16 = 0x9502,
+ FT_int32 = 0x9604,
+ FT_signed_int32 = 0x9704,
+ FT_unsigned_int32 = 0x9804,
+ FT_int64 = 0x9908,
+ FT_signed_int64 = 0x9a08,
+ FT_unsigned_int64 = 0x9b08,
+
+ FT_real32 = 0xa004,
+ FT_real64 = 0xa108,
+ FT_real96 = 0xa20c,
+ FT_real128 = 0xa310
+};
+
+#define FT_lo_user 0x8000 /* implementation-defined range start */
+#define FT_hi_user 0xffff /* implementation defined range end */
+
+/* Type modifier names and codes. */
+
+enum dwarf_type_modifier {
+ MOD_pointer_to = 0x01,
+ MOD_reference_to = 0x02,
+ MOD_const = 0x03,
+ MOD_volatile = 0x04
+};
+
+#define MOD_lo_user 0x80 /* implementation-defined range start */
+#define MOD_hi_user 0xff /* implementation-defined range end */
+
+/* Array ordering names and codes. */
+
+enum dwarf_array_dim_ordering {
+ ORD_row_major = 0,
+ ORD_col_major = 1
+};
+
+/* Array subscript format names and codes. */
+
+enum dwarf_subscr_data_formats {
+ FMT_FT_C_C = 0x0,
+ FMT_FT_C_X = 0x1,
+ FMT_FT_X_C = 0x2,
+ FMT_FT_X_X = 0x3,
+ FMT_UT_C_C = 0x4,
+ FMT_UT_C_X = 0x5,
+ FMT_UT_X_C = 0x6,
+ FMT_UT_X_X = 0x7,
+ FMT_ET = 0x8
+};
+
+/* Derived from above for ease of use. */
+
+#define FMT_CODE(_FUNDAMENTAL_TYPE_P, _UB_CONST_P, _LB_CONST_P) \
+ (((_FUNDAMENTAL_TYPE_P) ? 0 : 4) \
+ | ((_UB_CONST_P) ? 0 : 2) \
+ | ((_LB_CONST_P) ? 0 : 1))
+
+/* Source language names and codes. */
+
+enum dwarf_source_language {
+ LANG_C89 = 0x00000001,
+ LANG_C = 0x00000002,
+ LANG_ADA83 = 0x00000003,
+ LANG_C_PLUS_PLUS = 0x00000004,
+ LANG_COBOL74 = 0x00000005,
+ LANG_COBOL85 = 0x00000006,
+ LANG_FORTRAN77 = 0x00000007,
+ LANG_FORTRAN90 = 0x00000008,
+ LANG_PASCAL83 = 0x00000009,
+ LANG_MODULA2 = 0x0000000a,
+
+ /* GNU extensions */
+
+ LANG_CHILL = 0x00009af3 /* random value for GNU Chill */
+};
+
+#define LANG_lo_user 0x00008000 /* implementation-defined range start */
+#define LANG_hi_user 0x0000ffff /* implementation-defined range end */
+
+/* Names and codes for GNU "macinfo" extension. */
+
+enum dwarf_macinfo_record_type {
+ MACINFO_start = 's',
+ MACINFO_resume = 'r',
+ MACINFO_define = 'd',
+ MACINFO_undef = 'u'
+};
+
+#endif /* _ELF_DWARF_H */
diff --git a/include/elf/dwarf2.h b/include/elf/dwarf2.h
new file mode 100644
index 00000000000..b2cbb24d95d
--- /dev/null
+++ b/include/elf/dwarf2.h
@@ -0,0 +1,637 @@
+/* Declarations and definitions of codes relating to the DWARF symbolic
+ debugging information format.
+ Copyright (C) 1992, 1993, 1995, 1996, 1999 Free Software Foundation, Inc.
+
+ Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
+ Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
+ provided support for this effort -- June 21, 1995.
+
+ Derived from the DWARF 1 implementation written by Ron Guilmette
+ (rfg@netcom.com), November 1990.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option) any
+later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file is derived from the DWARF specification (a public document)
+ Revision 2.0.0 (July 27, 1993) developed by the UNIX International
+ Programming Languages Special Interest Group (UI/PLSIG) and distributed
+ by UNIX International. Copies of this specification are available from
+ UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */
+
+#ifndef _ELF_DWARF2_H
+#define _ELF_DWARF2_H
+
+/* Structure found in the .debug_line section. */
+typedef struct
+{
+ unsigned char li_length [4];
+ unsigned char li_version [2];
+ unsigned char li_prologue_length [4];
+ unsigned char li_min_insn_length [1];
+ unsigned char li_default_is_stmt [1];
+ unsigned char li_line_base [1];
+ unsigned char li_line_range [1];
+ unsigned char li_opcode_base [1];
+}
+DWARF2_External_LineInfo;
+
+typedef struct
+{
+ unsigned long li_length;
+ unsigned short li_version;
+ unsigned int li_prologue_length;
+ unsigned char li_min_insn_length;
+ unsigned char li_default_is_stmt;
+ int li_line_base;
+ unsigned char li_line_range;
+ unsigned char li_opcode_base;
+}
+DWARF2_Internal_LineInfo;
+
+/* Structure found in .debug_pubnames section. */
+typedef struct
+{
+ unsigned char pn_length [4];
+ unsigned char pn_version [2];
+ unsigned char pn_offset [4];
+ unsigned char pn_size [4];
+}
+DWARF2_External_PubNames;
+
+typedef struct
+{
+ unsigned long pn_length;
+ unsigned short pn_version;
+ unsigned long pn_offset;
+ unsigned long pn_size;
+}
+DWARF2_Internal_PubNames;
+
+/* Strcuture found in .debug_info section. */
+typedef struct
+{
+ unsigned char cu_length [4];
+ unsigned char cu_version [2];
+ unsigned char cu_abbrev_offset [4];
+ unsigned char cu_pointer_size [1];
+}
+DWARF2_External_CompUnit;
+
+typedef struct
+{
+ unsigned long cu_length;
+ unsigned short cu_version;
+ unsigned long cu_abbrev_offset;
+ unsigned char cu_pointer_size;
+}
+DWARF2_Internal_CompUnit;
+
+typedef struct
+{
+ unsigned char ar_length [4];
+ unsigned char ar_version [2];
+ unsigned char ar_info_offset [4];
+ unsigned char ar_pointer_size [1];
+ unsigned char ar_segment_size [1];
+}
+DWARF2_External_ARange;
+
+typedef struct
+{
+ unsigned long ar_length;
+ unsigned short ar_version;
+ unsigned long ar_info_offset;
+ unsigned char ar_pointer_size;
+ unsigned char ar_segment_size;
+}
+DWARF2_Internal_ARange;
+
+
+/* Tag names and codes. */
+
+enum dwarf_tag
+ {
+ DW_TAG_padding = 0x00,
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_param = 0x2f,
+ DW_TAG_template_value_param = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ /* SGI/MIPS Extensions */
+ DW_TAG_MIPS_loop = 0x4081,
+ /* GNU extensions */
+ DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */
+ DW_TAG_function_template = 0x4102, /* for C++ */
+ DW_TAG_class_template = 0x4103 /* for C++ */
+ };
+
+#define DW_TAG_lo_user 0x4080
+#define DW_TAG_hi_user 0xffff
+
+/* flag that tells whether entry has a child or not */
+#define DW_children_no 0
+#define DW_children_yes 1
+
+/* Form names and codes. */
+enum dwarf_form
+ {
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16
+ };
+
+/* Attribute names and codes. */
+
+enum dwarf_attribute
+ {
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_subscr_data = 0x0a,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_element_list = 0x0f,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_member = 0x14,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_stride_size = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_items = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ /* SGI/MIPS Extensions */
+ DW_AT_MIPS_fde = 0x2001,
+ DW_AT_MIPS_loop_begin = 0x2002,
+ DW_AT_MIPS_tail_loop_begin = 0x2003,
+ DW_AT_MIPS_epilog_begin = 0x2004,
+ DW_AT_MIPS_loop_unroll_factor = 0x2005,
+ DW_AT_MIPS_software_pipeline_depth = 0x2006,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_MIPS_stride = 0x2008,
+ DW_AT_MIPS_abstract_name = 0x2009,
+ DW_AT_MIPS_clone_origin = 0x200a,
+ DW_AT_MIPS_has_inlines = 0x200b,
+ /* GNU extensions. */
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106
+ };
+
+#define DW_AT_lo_user 0x2000 /* implementation-defined range start */
+#define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */
+
+/* Location atom names and codes. */
+
+enum dwarf_location_atom
+ {
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_skip = 0x2f,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit2 = 0x32,
+ DW_OP_lit3 = 0x33,
+ DW_OP_lit4 = 0x34,
+ DW_OP_lit5 = 0x35,
+ DW_OP_lit6 = 0x36,
+ DW_OP_lit7 = 0x37,
+ DW_OP_lit8 = 0x38,
+ DW_OP_lit9 = 0x39,
+ DW_OP_lit10 = 0x3a,
+ DW_OP_lit11 = 0x3b,
+ DW_OP_lit12 = 0x3c,
+ DW_OP_lit13 = 0x3d,
+ DW_OP_lit14 = 0x3e,
+ DW_OP_lit15 = 0x3f,
+ DW_OP_lit16 = 0x40,
+ DW_OP_lit17 = 0x41,
+ DW_OP_lit18 = 0x42,
+ DW_OP_lit19 = 0x43,
+ DW_OP_lit20 = 0x44,
+ DW_OP_lit21 = 0x45,
+ DW_OP_lit22 = 0x46,
+ DW_OP_lit23 = 0x47,
+ DW_OP_lit24 = 0x48,
+ DW_OP_lit25 = 0x49,
+ DW_OP_lit26 = 0x4a,
+ DW_OP_lit27 = 0x4b,
+ DW_OP_lit28 = 0x4c,
+ DW_OP_lit29 = 0x4d,
+ DW_OP_lit30 = 0x4e,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg2 = 0x52,
+ DW_OP_reg3 = 0x53,
+ DW_OP_reg4 = 0x54,
+ DW_OP_reg5 = 0x55,
+ DW_OP_reg6 = 0x56,
+ DW_OP_reg7 = 0x57,
+ DW_OP_reg8 = 0x58,
+ DW_OP_reg9 = 0x59,
+ DW_OP_reg10 = 0x5a,
+ DW_OP_reg11 = 0x5b,
+ DW_OP_reg12 = 0x5c,
+ DW_OP_reg13 = 0x5d,
+ DW_OP_reg14 = 0x5e,
+ DW_OP_reg15 = 0x5f,
+ DW_OP_reg16 = 0x60,
+ DW_OP_reg17 = 0x61,
+ DW_OP_reg18 = 0x62,
+ DW_OP_reg19 = 0x63,
+ DW_OP_reg20 = 0x64,
+ DW_OP_reg21 = 0x65,
+ DW_OP_reg22 = 0x66,
+ DW_OP_reg23 = 0x67,
+ DW_OP_reg24 = 0x68,
+ DW_OP_reg25 = 0x69,
+ DW_OP_reg26 = 0x6a,
+ DW_OP_reg27 = 0x6b,
+ DW_OP_reg28 = 0x6c,
+ DW_OP_reg29 = 0x6d,
+ DW_OP_reg30 = 0x6e,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg2 = 0x72,
+ DW_OP_breg3 = 0x73,
+ DW_OP_breg4 = 0x74,
+ DW_OP_breg5 = 0x75,
+ DW_OP_breg6 = 0x76,
+ DW_OP_breg7 = 0x77,
+ DW_OP_breg8 = 0x78,
+ DW_OP_breg9 = 0x79,
+ DW_OP_breg10 = 0x7a,
+ DW_OP_breg11 = 0x7b,
+ DW_OP_breg12 = 0x7c,
+ DW_OP_breg13 = 0x7d,
+ DW_OP_breg14 = 0x7e,
+ DW_OP_breg15 = 0x7f,
+ DW_OP_breg16 = 0x80,
+ DW_OP_breg17 = 0x81,
+ DW_OP_breg18 = 0x82,
+ DW_OP_breg19 = 0x83,
+ DW_OP_breg20 = 0x84,
+ DW_OP_breg21 = 0x85,
+ DW_OP_breg22 = 0x86,
+ DW_OP_breg23 = 0x87,
+ DW_OP_breg24 = 0x88,
+ DW_OP_breg25 = 0x89,
+ DW_OP_breg26 = 0x8a,
+ DW_OP_breg27 = 0x8b,
+ DW_OP_breg28 = 0x8c,
+ DW_OP_breg29 = 0x8d,
+ DW_OP_breg30 = 0x8e,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96
+ };
+
+#define DW_OP_lo_user 0x80 /* implementation-defined range start */
+#define DW_OP_hi_user 0xff /* implementation-defined range end */
+
+/* Type encodings. */
+
+enum dwarf_type
+ {
+ DW_ATE_void = 0x0,
+ DW_ATE_address = 0x1,
+ DW_ATE_boolean = 0x2,
+ DW_ATE_complex_float = 0x3,
+ DW_ATE_float = 0x4,
+ DW_ATE_signed = 0x5,
+ DW_ATE_signed_char = 0x6,
+ DW_ATE_unsigned = 0x7,
+ DW_ATE_unsigned_char = 0x8
+ };
+
+#define DW_ATE_lo_user 0x80
+#define DW_ATE_hi_user 0xff
+
+/* Array ordering names and codes. */
+enum dwarf_array_dim_ordering
+ {
+ DW_ORD_row_major = 0,
+ DW_ORD_col_major = 1
+ };
+
+/* access attribute */
+enum dwarf_access_attribute
+ {
+ DW_ACCESS_public = 1,
+ DW_ACCESS_protected = 2,
+ DW_ACCESS_private = 3
+ };
+
+/* visibility */
+enum dwarf_visibility_attribute
+ {
+ DW_VIS_local = 1,
+ DW_VIS_exported = 2,
+ DW_VIS_qualified = 3
+ };
+
+/* virtuality */
+enum dwarf_virtuality_attribute
+ {
+ DW_VIRTUALITY_none = 0,
+ DW_VIRTUALITY_virtual = 1,
+ DW_VIRTUALITY_pure_virtual = 2
+ };
+
+/* case sensitivity */
+enum dwarf_id_case
+ {
+ DW_ID_case_sensitive = 0,
+ DW_ID_up_case = 1,
+ DW_ID_down_case = 2,
+ DW_ID_case_insensitive = 3
+ };
+
+/* calling convention */
+enum dwarf_calling_convention
+ {
+ DW_CC_normal = 0x1,
+ DW_CC_program = 0x2,
+ DW_CC_nocall = 0x3
+ };
+
+#define DW_CC_lo_user 0x40
+#define DW_CC_hi_user 0xff
+
+/* inline attribute */
+enum dwarf_inline_attribute
+ {
+ DW_INL_not_inlined = 0,
+ DW_INL_inlined = 1,
+ DW_INL_declared_not_inlined = 2,
+ DW_INL_declared_inlined = 3
+ };
+
+/* descriminant lists */
+enum dwarf_descrim_list
+ {
+ DW_DSC_label = 0,
+ DW_DSC_range = 1
+ };
+
+/* line number opcodes */
+enum dwarf_line_number_ops
+ {
+ DW_LNS_extended_op = 0,
+ DW_LNS_copy = 1,
+ DW_LNS_advance_pc = 2,
+ DW_LNS_advance_line = 3,
+ DW_LNS_set_file = 4,
+ DW_LNS_set_column = 5,
+ DW_LNS_negate_stmt = 6,
+ DW_LNS_set_basic_block = 7,
+ DW_LNS_const_add_pc = 8,
+ DW_LNS_fixed_advance_pc = 9
+ };
+
+/* line number extended opcodes */
+enum dwarf_line_number_x_ops
+ {
+ DW_LNE_end_sequence = 1,
+ DW_LNE_set_address = 2,
+ DW_LNE_define_file = 3
+ };
+
+/* call frame information */
+enum dwarf_call_frame_info
+ {
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_nop = 0x00,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ /* SGI/MIPS specific */
+ DW_CFA_MIPS_advance_loc8 = 0x1d
+ };
+
+#define DW_CIE_ID 0xffffffff
+#define DW_CIE_VERSION 1
+
+#define DW_CFA_extended 0
+#define DW_CFA_low_user 0x1c
+#define DW_CFA_high_user 0x3f
+
+#define DW_CHILDREN_no 0x00
+#define DW_CHILDREN_yes 0x01
+
+#define DW_ADDR_none 0
+
+/* Source language names and codes. */
+
+enum dwarf_source_language
+ {
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Mips_Assembler = 0x8001
+ };
+
+
+#define DW_LANG_lo_user 0x8000 /* implementation-defined range start */
+#define DW_LANG_hi_user 0xffff /* implementation-defined range start */
+
+/* Names and codes for macro information. */
+
+enum dwarf_macinfo_record_type
+ {
+ DW_MACINFO_define = 1,
+ DW_MACINFO_undef = 2,
+ DW_MACINFO_start_file = 3,
+ DW_MACINFO_end_file = 4,
+ DW_MACINFO_vendor_ext = 255
+ };
+
+#endif /* _ELF_DWARF2_H */
diff --git a/include/elf/external.h b/include/elf/external.h
new file mode 100644
index 00000000000..5cab77e5549
--- /dev/null
+++ b/include/elf/external.h
@@ -0,0 +1,256 @@
+/* ELF support for BFD.
+ Copyright (C) 1991, 92, 93, 95, 97, 98, 1999 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support, from information published
+ in "UNIX System V Release 4, Programmers Guide: ANSI C and
+ Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+ that describe how ELF is represented externally by the BFD library.
+ I.E. it describes the in-file representation of ELF. It requires
+ the elf-common.h file which contains the portions that are common to
+ both the internal and external representations. */
+
+/* The 64-bit stuff is kind of random. Perhaps someone will publish a
+ spec someday. */
+
+#ifndef _ELF_EXTERNAL_H
+#define _ELF_EXTERNAL_H
+
+/* ELF Header (32-bit implementations) */
+
+typedef struct {
+ unsigned char e_ident[16]; /* ELF "magic number" */
+ unsigned char e_type[2]; /* Identifies object file type */
+ unsigned char e_machine[2]; /* Specifies required architecture */
+ unsigned char e_version[4]; /* Identifies object file version */
+ unsigned char e_entry[4]; /* Entry point virtual address */
+ unsigned char e_phoff[4]; /* Program header table file offset */
+ unsigned char e_shoff[4]; /* Section header table file offset */
+ unsigned char e_flags[4]; /* Processor-specific flags */
+ unsigned char e_ehsize[2]; /* ELF header size in bytes */
+ unsigned char e_phentsize[2]; /* Program header table entry size */
+ unsigned char e_phnum[2]; /* Program header table entry count */
+ unsigned char e_shentsize[2]; /* Section header table entry size */
+ unsigned char e_shnum[2]; /* Section header table entry count */
+ unsigned char e_shstrndx[2]; /* Section header string table index */
+} Elf32_External_Ehdr;
+
+typedef struct {
+ unsigned char e_ident[16]; /* ELF "magic number" */
+ unsigned char e_type[2]; /* Identifies object file type */
+ unsigned char e_machine[2]; /* Specifies required architecture */
+ unsigned char e_version[4]; /* Identifies object file version */
+ unsigned char e_entry[8]; /* Entry point virtual address */
+ unsigned char e_phoff[8]; /* Program header table file offset */
+ unsigned char e_shoff[8]; /* Section header table file offset */
+ unsigned char e_flags[4]; /* Processor-specific flags */
+ unsigned char e_ehsize[2]; /* ELF header size in bytes */
+ unsigned char e_phentsize[2]; /* Program header table entry size */
+ unsigned char e_phnum[2]; /* Program header table entry count */
+ unsigned char e_shentsize[2]; /* Section header table entry size */
+ unsigned char e_shnum[2]; /* Section header table entry count */
+ unsigned char e_shstrndx[2]; /* Section header string table index */
+} Elf64_External_Ehdr;
+
+/* Program header */
+
+typedef struct {
+ unsigned char p_type[4]; /* Identifies program segment type */
+ unsigned char p_offset[4]; /* Segment file offset */
+ unsigned char p_vaddr[4]; /* Segment virtual address */
+ unsigned char p_paddr[4]; /* Segment physical address */
+ unsigned char p_filesz[4]; /* Segment size in file */
+ unsigned char p_memsz[4]; /* Segment size in memory */
+ unsigned char p_flags[4]; /* Segment flags */
+ unsigned char p_align[4]; /* Segment alignment, file & memory */
+} Elf32_External_Phdr;
+
+typedef struct {
+ unsigned char p_type[4]; /* Identifies program segment type */
+ unsigned char p_flags[4]; /* Segment flags */
+ unsigned char p_offset[8]; /* Segment file offset */
+ unsigned char p_vaddr[8]; /* Segment virtual address */
+ unsigned char p_paddr[8]; /* Segment physical address */
+ unsigned char p_filesz[8]; /* Segment size in file */
+ unsigned char p_memsz[8]; /* Segment size in memory */
+ unsigned char p_align[8]; /* Segment alignment, file & memory */
+} Elf64_External_Phdr;
+
+/* Section header */
+
+typedef struct {
+ unsigned char sh_name[4]; /* Section name, index in string tbl */
+ unsigned char sh_type[4]; /* Type of section */
+ unsigned char sh_flags[4]; /* Miscellaneous section attributes */
+ unsigned char sh_addr[4]; /* Section virtual addr at execution */
+ unsigned char sh_offset[4]; /* Section file offset */
+ unsigned char sh_size[4]; /* Size of section in bytes */
+ unsigned char sh_link[4]; /* Index of another section */
+ unsigned char sh_info[4]; /* Additional section information */
+ unsigned char sh_addralign[4]; /* Section alignment */
+ unsigned char sh_entsize[4]; /* Entry size if section holds table */
+} Elf32_External_Shdr;
+
+typedef struct {
+ unsigned char sh_name[4]; /* Section name, index in string tbl */
+ unsigned char sh_type[4]; /* Type of section */
+ unsigned char sh_flags[8]; /* Miscellaneous section attributes */
+ unsigned char sh_addr[8]; /* Section virtual addr at execution */
+ unsigned char sh_offset[8]; /* Section file offset */
+ unsigned char sh_size[8]; /* Size of section in bytes */
+ unsigned char sh_link[4]; /* Index of another section */
+ unsigned char sh_info[4]; /* Additional section information */
+ unsigned char sh_addralign[8]; /* Section alignment */
+ unsigned char sh_entsize[8]; /* Entry size if section holds table */
+} Elf64_External_Shdr;
+
+/* Symbol table entry */
+
+typedef struct {
+ unsigned char st_name[4]; /* Symbol name, index in string tbl */
+ unsigned char st_value[4]; /* Value of the symbol */
+ unsigned char st_size[4]; /* Associated symbol size */
+ unsigned char st_info[1]; /* Type and binding attributes */
+ unsigned char st_other[1]; /* No defined meaning, 0 */
+ unsigned char st_shndx[2]; /* Associated section index */
+} Elf32_External_Sym;
+
+typedef struct {
+ unsigned char st_name[4]; /* Symbol name, index in string tbl */
+ unsigned char st_info[1]; /* Type and binding attributes */
+ unsigned char st_other[1]; /* No defined meaning, 0 */
+ unsigned char st_shndx[2]; /* Associated section index */
+ unsigned char st_value[8]; /* Value of the symbol */
+ unsigned char st_size[8]; /* Associated symbol size */
+} Elf64_External_Sym;
+
+/* Note segments */
+
+typedef struct {
+ unsigned char namesz[4]; /* Size of entry's owner string */
+ unsigned char descsz[4]; /* Size of the note descriptor */
+ unsigned char type[4]; /* Interpretation of the descriptor */
+ char name[1]; /* Start of the name+desc data */
+} Elf_External_Note;
+
+/* Relocation Entries */
+typedef struct {
+ unsigned char r_offset[4]; /* Location at which to apply the action */
+ unsigned char r_info[4]; /* index and type of relocation */
+} Elf32_External_Rel;
+
+typedef struct {
+ unsigned char r_offset[4]; /* Location at which to apply the action */
+ unsigned char r_info[4]; /* index and type of relocation */
+ unsigned char r_addend[4]; /* Constant addend used to compute value */
+} Elf32_External_Rela;
+
+typedef struct {
+ unsigned char r_offset[8]; /* Location at which to apply the action */
+ unsigned char r_info[8]; /* index and type of relocation */
+} Elf64_External_Rel;
+
+typedef struct {
+ unsigned char r_offset[8]; /* Location at which to apply the action */
+ unsigned char r_info[8]; /* index and type of relocation */
+ unsigned char r_addend[8]; /* Constant addend used to compute value */
+} Elf64_External_Rela;
+
+/* dynamic section structure */
+
+typedef struct {
+ unsigned char d_tag[4]; /* entry tag value */
+ union {
+ unsigned char d_val[4];
+ unsigned char d_ptr[4];
+ } d_un;
+} Elf32_External_Dyn;
+
+typedef struct {
+ unsigned char d_tag[8]; /* entry tag value */
+ union {
+ unsigned char d_val[8];
+ unsigned char d_ptr[8];
+ } d_un;
+} Elf64_External_Dyn;
+
+/* The version structures are currently size independent. They are
+ named without a 32 or 64. If that ever changes, these structures
+ will need to be renamed. */
+
+/* This structure appears in a SHT_GNU_verdef section. */
+
+typedef struct {
+ unsigned char vd_version[2];
+ unsigned char vd_flags[2];
+ unsigned char vd_ndx[2];
+ unsigned char vd_cnt[2];
+ unsigned char vd_hash[4];
+ unsigned char vd_aux[4];
+ unsigned char vd_next[4];
+} Elf_External_Verdef;
+
+/* This structure appears in a SHT_GNU_verdef section. */
+
+typedef struct {
+ unsigned char vda_name[4];
+ unsigned char vda_next[4];
+} Elf_External_Verdaux;
+
+/* This structure appears in a SHT_GNU_verneed section. */
+
+typedef struct {
+ unsigned char vn_version[2];
+ unsigned char vn_cnt[2];
+ unsigned char vn_file[4];
+ unsigned char vn_aux[4];
+ unsigned char vn_next[4];
+} Elf_External_Verneed;
+
+/* This structure appears in a SHT_GNU_verneed section. */
+
+typedef struct {
+ unsigned char vna_hash[4];
+ unsigned char vna_flags[2];
+ unsigned char vna_other[2];
+ unsigned char vna_name[4];
+ unsigned char vna_next[4];
+} Elf_External_Vernaux;
+
+/* This structure appears in a SHT_GNU_versym section. This is not a
+ standard ELF structure; ELF just uses Elf32_Half. */
+
+typedef struct {
+ unsigned char vs_vers[2];
+}
+#ifdef __GNUC__
+ __attribute__ ((packed))
+#endif
+ Elf_External_Versym;
+
+/* Structure for syminfo section. */
+typedef struct
+{
+ unsigned char si_boundto[2];
+ unsigned char si_flags[2];
+} Elf_External_Syminfo;
+
+#endif /* _ELF_EXTERNAL_H */
diff --git a/include/elf/fr30.h b/include/elf/fr30.h
new file mode 100644
index 00000000000..223b052973a
--- /dev/null
+++ b/include/elf/fr30.h
@@ -0,0 +1,43 @@
+/* FR30 ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_FR30_H
+#define _ELF_FR30_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_fr30_reloc_type)
+ RELOC_NUMBER (R_FR30_NONE, 0)
+ RELOC_NUMBER (R_FR30_8, 1)
+ RELOC_NUMBER (R_FR30_20, 2)
+ RELOC_NUMBER (R_FR30_32, 3)
+ RELOC_NUMBER (R_FR30_48, 4)
+ RELOC_NUMBER (R_FR30_6_IN_4, 5)
+ RELOC_NUMBER (R_FR30_8_IN_8, 6)
+ RELOC_NUMBER (R_FR30_9_IN_8, 7)
+ RELOC_NUMBER (R_FR30_10_IN_8, 8)
+ RELOC_NUMBER (R_FR30_9_PCREL, 9)
+ RELOC_NUMBER (R_FR30_12_PCREL, 10)
+ RELOC_NUMBER (R_FR30_GNU_VTINHERIT, 11)
+ RELOC_NUMBER (R_FR30_GNU_VTENTRY, 12)
+ EMPTY_RELOC (R_FR30_max)
+END_RELOC_NUMBERS
+
+#endif /* _ELF_FR30_H */
diff --git a/include/elf/hppa.h b/include/elf/hppa.h
new file mode 100644
index 00000000000..2952e2398d2
--- /dev/null
+++ b/include/elf/hppa.h
@@ -0,0 +1,187 @@
+/* HPPA ELF support for BFD.
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the HPPA ELF ABI. Note
+ that most of this is not actually implemented by BFD. */
+
+#ifndef _ELF_HPPA_H
+#define _ELF_HPPA_H
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* Target processor IDs to be placed in the low 16 bits of the flags
+ field. Note these names are shared with SOM, and therefore do not
+ follow ELF naming conventions. */
+
+/* PA 1.0 big endian. */
+#ifndef CPU_PA_RISC1_0
+#define CPU_PA_RISC1_0 0x0000020b
+#endif
+
+/* PA 1.1 big endian. */
+#ifndef CPU_PA_RISC1_1
+#define CPU_PA_RISC1_1 0x00000210
+#endif
+
+/* PA 1.0 little endian (unsupported) is 0x0000028b. */
+/* PA 1.1 little endian (unsupported) is 0x00000290. */
+
+/* Trap null address dereferences. */
+#define ELF_PARISC_TRAPNIL 0x00010000
+
+/* .PARISC.archext section is present. */
+#define EF_PARISC_EXT 0x00020000
+
+/* Processor specific section types. */
+
+/* Holds the global offset table, a table of pointers to external
+ data. */
+#define SHT_PARISC_GOT SHT_LOPROC+0
+
+/* Nonloadable section containing information in architecture
+ extensions used by the code. */
+#define SHT_PARISC_ARCH SHT_LOPROC+1
+
+/* Section in which $global$ is defined. */
+#define SHT_PARISC_GLOBAL SHT_LOPROC+2
+
+/* Section holding millicode routines (mul, div, rem, dyncall, etc. */
+#define SHT_PARISC_MILLI SHT_LOPROC+3
+
+/* Section holding unwind information for use by debuggers. */
+#define SHT_PARISC_UNWIND SHT_LOPROC+4
+
+/* Section holding the procedure linkage table. */
+#define SHT_PARISC_PLT SHT_LOPROC+5
+
+/* Short initialized and uninitialized data. */
+#define SHT_PARISC_SDATA SHT_LOPROC+6
+#define SHT_PARISC_SBSS SHT_LOPROC+7
+
+/* Optional section holding argument location/relocation info. */
+#define SHT_PARISC_SYMEXTN SHT_LOPROC+8
+
+/* Option section for linker stubs. */
+#define SHT_PARISC_STUBS SHT_LOPROC+9
+
+/* Processor specific section flags. */
+
+/* This section is near the global data pointer and thus allows short
+ addressing modes to be used. */
+#define SHF_PARISC_SHORT 0x20000000
+
+/* Processor specific symbol types. */
+
+/* Millicode function entry point. */
+#define STT_PARISC_MILLICODE STT_LOPROC+0
+
+
+/* ELF/HPPA relocation types */
+
+#include "reloc-macros.h"
+
+START_RELOC_NUMBERS (elf32_hppa_reloc_type)
+ RELOC_NUMBER (R_PARISC_NONE, 0) /* No reloc */
+
+ /* These relocation types do simple base + offset relocations. */
+
+ RELOC_NUMBER (R_PARISC_DIR32, 0x01)
+ RELOC_NUMBER (R_PARISC_DIR21L, 0x02)
+ RELOC_NUMBER (R_PARISC_DIR17R, 0x03)
+ RELOC_NUMBER (R_PARISC_DIR17F, 0x04)
+ RELOC_NUMBER (R_PARISC_DIR14R, 0x06)
+
+ /* PC-relative relocation types
+ Typically used for calls.
+ Note PCREL17C and PCREL17F differ only in overflow handling.
+ PCREL17C never reports a relocation error.
+
+ When supporting argument relocations, function calls must be
+ accompanied by parameter relocation information. This information is
+ carried in the ten high-order bits of the addend field. The remaining
+ 22 bits of of the addend field are sign-extended to form the Addend.
+
+ Note the code to build argument relocations depends on the
+ addend being zero. A consequence of this limitation is GAS
+ can not perform relocation reductions for function symbols. */
+
+ RELOC_NUMBER (R_PARISC_PCREL21L, 0x0a)
+ RELOC_NUMBER (R_PARISC_PCREL17R, 0x0b)
+ RELOC_NUMBER (R_PARISC_PCREL17F, 0x0c)
+ RELOC_NUMBER (R_PARISC_PCREL17C, 0x0d)
+ RELOC_NUMBER (R_PARISC_PCREL14R, 0x0e)
+ RELOC_NUMBER (R_PARISC_PCREL14F, 0x0f)
+
+ /* DP-relative relocation types. */
+ RELOC_NUMBER (R_PARISC_DPREL21L, 0x12)
+ RELOC_NUMBER (R_PARISC_DPREL14R, 0x16)
+ RELOC_NUMBER (R_PARISC_DPREL14F, 0x17)
+
+ /* Data linkage table (DLT) relocation types
+
+ SOM DLT_REL fixup requests are used to for static data references
+ from position-independent code within shared libraries. They are
+ similar to the GOT relocation types in some SVR4 implementations. */
+
+ RELOC_NUMBER (R_PARISC_DLTREL21L, 0x1a)
+ RELOC_NUMBER (R_PARISC_DLTREL14R, 0x1e)
+ RELOC_NUMBER (R_PARISC_DLTREL14F, 0x1f)
+
+ /* DLT indirect relocation types */
+ RELOC_NUMBER (R_PARISC_DLTIND21L, 0x22)
+ RELOC_NUMBER (R_PARISC_DLTIND14R, 0x26)
+ RELOC_NUMBER (R_PARISC_DLTIND14F, 0x27)
+
+ /* Base relative relocation types. Ugh. These imply lots of state */
+ RELOC_NUMBER (R_PARISC_SETBASE, 0x28)
+ RELOC_NUMBER (R_PARISC_BASEREL32, 0x29)
+ RELOC_NUMBER (R_PARISC_BASEREL21L, 0x2a)
+ RELOC_NUMBER (R_PARISC_BASEREL17R, 0x2b)
+ RELOC_NUMBER (R_PARISC_BASEREL17F, 0x2c)
+ RELOC_NUMBER (R_PARISC_BASEREL14R, 0x2e)
+ RELOC_NUMBER (R_PARISC_BASEREL14F, 0x2f)
+
+ /* Segment relative relocation types. */
+ RELOC_NUMBER (R_PARISC_TEXTREL32, 0x31)
+ RELOC_NUMBER (R_PARISC_DATAREL32, 0x39)
+
+ /* Plabel relocation types. */
+ RELOC_NUMBER (R_PARISC_PLABEL32, 0x41)
+ RELOC_NUMBER (R_PARISC_PLABEL21L, 0x42)
+ RELOC_NUMBER (R_PARISC_PLABEL14R, 0x46)
+
+ /* PLT relocations. */
+ RELOC_NUMBER (R_PARISC_PLTIND21L, 0x82)
+ RELOC_NUMBER (R_PARISC_PLTIND14R, 0x86)
+ RELOC_NUMBER (R_PARISC_PLTIND14F, 0x87)
+
+ /* Misc relocation types. */
+ RELOC_NUMBER (R_PARISC_COPY, 0x88)
+ RELOC_NUMBER (R_PARISC_GLOB_DAT, 0x89)
+ RELOC_NUMBER (R_PARISC_JMP_SLOT, 0x8a)
+ RELOC_NUMBER (R_PARISC_RELATIVE, 0x8b)
+
+ EMPTY_RELOC (R_PARISC_UNIMPLEMENTED)
+END_RELOC_NUMBERS
+
+#ifndef RELOC_MACROS_GEN_FUNC
+typedef enum elf32_hppa_reloc_type elf32_hppa_reloc_type;
+#endif
+
+#endif /* _ELF_HPPA_H */
diff --git a/include/elf/i386.h b/include/elf/i386.h
new file mode 100644
index 00000000000..219f10511fe
--- /dev/null
+++ b/include/elf/i386.h
@@ -0,0 +1,49 @@
+/* ix86 ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_I386_H
+#define _ELF_I386_H
+
+#include "reloc-macros.h"
+
+START_RELOC_NUMBERS (elf_i386_reloc_type)
+ RELOC_NUMBER (R_386_NONE, 0) /* No reloc */
+ RELOC_NUMBER (R_386_32, 1) /* Direct 32 bit */
+ RELOC_NUMBER (R_386_PC32, 2) /* PC relative 32 bit */
+ RELOC_NUMBER (R_386_GOT32, 3) /* 32 bit GOT entry */
+ RELOC_NUMBER (R_386_PLT32, 4) /* 32 bit PLT address */
+ RELOC_NUMBER (R_386_COPY, 5) /* Copy symbol at runtime */
+ RELOC_NUMBER (R_386_GLOB_DAT, 6) /* Create GOT entry */
+ RELOC_NUMBER (R_386_JUMP_SLOT, 7) /* Create PLT entry */
+ RELOC_NUMBER (R_386_RELATIVE, 8) /* Adjust by program base */
+ RELOC_NUMBER (R_386_GOTOFF, 9) /* 32 bit offset to GOT */
+ RELOC_NUMBER (R_386_GOTPC, 10) /* 32 bit PC relative offset to GOT */
+ FAKE_RELOC (FIRST_INVALID_RELOC, 11)
+ FAKE_RELOC (LAST_INVALID_RELOC, 19)
+ RELOC_NUMBER (R_386_16, 20)
+ RELOC_NUMBER (R_386_PC16, 21)
+ RELOC_NUMBER (R_386_8, 22)
+ RELOC_NUMBER (R_386_PC8, 23)
+ RELOC_NUMBER (R_386_max, 24)
+ /* These are GNU extensions to enable C++ vtable garbage collection. */
+ RELOC_NUMBER (R_386_GNU_VTINHERIT, 250)
+ RELOC_NUMBER (R_386_GNU_VTENTRY, 251)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/internal.h b/include/elf/internal.h
new file mode 100644
index 00000000000..a9b81a0707b
--- /dev/null
+++ b/include/elf/internal.h
@@ -0,0 +1,312 @@
+/* ELF support for BFD.
+ Copyright (C) 1991, 92, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support, from information published
+ in "UNIX System V Release 4, Programmers Guide: ANSI C and
+ Programming Support Tools".
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This file is part of ELF support for BFD, and contains the portions
+ that describe how ELF is represented internally in the BFD library.
+ I.E. it describes the in-memory representation of ELF. It requires
+ the elf-common.h file which contains the portions that are common to
+ both the internal and external representations. */
+
+
+/* NOTE that these structures are not kept in the same order as they appear
+ in the object file. In some cases they've been reordered for more optimal
+ packing under various circumstances. */
+
+#ifndef _ELF_INTERNAL_H
+#define _ELF_INTERNAL_H
+
+/* ELF Header */
+
+#define EI_NIDENT 16 /* Size of e_ident[] */
+
+typedef struct elf_internal_ehdr {
+ unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
+ bfd_vma e_entry; /* Entry point virtual address */
+ bfd_size_type e_phoff; /* Program header table file offset */
+ bfd_size_type e_shoff; /* Section header table file offset */
+ unsigned long e_version; /* Identifies object file version */
+ unsigned long e_flags; /* Processor-specific flags */
+ unsigned short e_type; /* Identifies object file type */
+ unsigned short e_machine; /* Specifies required architecture */
+ unsigned short e_ehsize; /* ELF header size in bytes */
+ unsigned short e_phentsize; /* Program header table entry size */
+ unsigned short e_phnum; /* Program header table entry count */
+ unsigned short e_shentsize; /* Section header table entry size */
+ unsigned short e_shnum; /* Section header table entry count */
+ unsigned short e_shstrndx; /* Section header string table index */
+} Elf_Internal_Ehdr;
+
+#define elf32_internal_ehdr elf_internal_ehdr
+#define Elf32_Internal_Ehdr Elf_Internal_Ehdr
+#define elf64_internal_ehdr elf_internal_ehdr
+#define Elf64_Internal_Ehdr Elf_Internal_Ehdr
+
+/* Program header */
+
+struct elf_internal_phdr {
+ unsigned long p_type; /* Identifies program segment type */
+ unsigned long p_flags; /* Segment flags */
+ bfd_vma p_offset; /* Segment file offset */
+ bfd_vma p_vaddr; /* Segment virtual address */
+ bfd_vma p_paddr; /* Segment physical address */
+ bfd_vma p_filesz; /* Segment size in file */
+ bfd_vma p_memsz; /* Segment size in memory */
+ bfd_vma p_align; /* Segment alignment, file & memory */
+};
+
+typedef struct elf_internal_phdr Elf_Internal_Phdr;
+#define elf32_internal_phdr elf_internal_phdr
+#define Elf32_Internal_Phdr Elf_Internal_Phdr
+#define elf64_internal_phdr elf_internal_phdr
+#define Elf64_Internal_Phdr Elf_Internal_Phdr
+
+/* Section header */
+
+typedef struct elf_internal_shdr {
+ unsigned int sh_name; /* Section name, index in string tbl */
+ unsigned int sh_type; /* Type of section */
+ bfd_vma sh_flags; /* Miscellaneous section attributes */
+ bfd_vma sh_addr; /* Section virtual addr at execution */
+ bfd_size_type sh_size; /* Size of section in bytes */
+ bfd_size_type sh_entsize; /* Entry size if section holds table */
+ unsigned long sh_link; /* Index of another section */
+ unsigned long sh_info; /* Additional section information */
+ file_ptr sh_offset; /* Section file offset */
+ unsigned int sh_addralign; /* Section alignment */
+
+ /* The internal rep also has some cached info associated with it. */
+ asection * bfd_section; /* Associated BFD section. */
+ PTR contents; /* Section contents. */
+} Elf_Internal_Shdr;
+
+#define elf32_internal_shdr elf_internal_shdr
+#define Elf32_Internal_Shdr Elf_Internal_Shdr
+#define elf64_internal_shdr elf_internal_shdr
+#define Elf64_Internal_Shdr Elf_Internal_Shdr
+
+/* Symbol table entry */
+
+struct elf_internal_sym {
+ bfd_vma st_value; /* Value of the symbol */
+ bfd_vma st_size; /* Associated symbol size */
+ unsigned long st_name; /* Symbol name, index in string tbl */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* No defined meaning, 0 */
+ unsigned short st_shndx; /* Associated section index */
+};
+
+typedef struct elf_internal_sym Elf_Internal_Sym;
+
+#define elf32_internal_sym elf_internal_sym
+#define elf64_internal_sym elf_internal_sym
+#define Elf32_Internal_Sym Elf_Internal_Sym
+#define Elf64_Internal_Sym Elf_Internal_Sym
+
+/* Note segments */
+
+typedef struct elf_internal_note {
+ unsigned long namesz; /* Size of entry's owner string */
+ unsigned long descsz; /* Size of the note descriptor */
+ unsigned long type; /* Interpretation of the descriptor */
+ char * namedata; /* Start of the name+desc data */
+ char * descdata; /* Start of the desc data */
+ bfd_vma descpos; /* File offset of the descdata */
+} Elf_Internal_Note;
+#define Elf32_Internal_Note Elf_Internal_Note
+#define elf32_internal_note elf_internal_note
+
+/* Relocation Entries */
+
+typedef struct elf_internal_rel {
+ bfd_vma r_offset; /* Location at which to apply the action */
+ /* This needs to support 64-bit values in elf64. */
+ bfd_vma r_info; /* index and type of relocation */
+} Elf_Internal_Rel;
+
+#define elf32_internal_rel elf_internal_rel
+#define Elf32_Internal_Rel Elf_Internal_Rel
+#define elf64_internal_rel elf_internal_rel
+#define Elf64_Internal_Rel Elf_Internal_Rel
+
+typedef struct elf_internal_rela {
+ bfd_vma r_offset; /* Location at which to apply the action */
+ bfd_vma r_info; /* Index and Type of relocation */
+ bfd_signed_vma r_addend; /* Constant addend used to compute value */
+} Elf_Internal_Rela;
+
+#define elf32_internal_rela elf_internal_rela
+#define elf64_internal_rela elf_internal_rela
+#define Elf32_Internal_Rela Elf_Internal_Rela
+#define Elf64_Internal_Rela Elf_Internal_Rela
+
+/* dynamic section structure */
+
+typedef struct elf_internal_dyn {
+ /* This needs to support 64-bit values in elf64. */
+ bfd_vma d_tag; /* entry tag value */
+ union {
+ /* This needs to support 64-bit values in elf64. */
+ bfd_vma d_val;
+ bfd_vma d_ptr;
+ } d_un;
+} Elf_Internal_Dyn;
+
+#define elf32_internal_dyn elf_internal_dyn
+#define elf64_internal_dyn elf_internal_dyn
+#define Elf32_Internal_Dyn Elf_Internal_Dyn
+#define Elf64_Internal_Dyn Elf_Internal_Dyn
+
+/* This structure appears in a SHT_GNU_verdef section. */
+
+typedef struct elf_internal_verdef {
+ unsigned short vd_version; /* Version number of structure. */
+ unsigned short vd_flags; /* Flags (VER_FLG_*). */
+ unsigned short vd_ndx; /* Version index. */
+ unsigned short vd_cnt; /* Number of verdaux entries. */
+ unsigned long vd_hash; /* Hash of name. */
+ unsigned long vd_aux; /* Offset to verdaux entries. */
+ unsigned long vd_next; /* Offset to next verdef. */
+
+ /* These fields are set up when BFD reads in the structure. FIXME:
+ It would be cleaner to store these in a different structure. */
+ bfd *vd_bfd; /* BFD. */
+ const char *vd_nodename; /* Version name. */
+ struct elf_internal_verdef *vd_nextdef; /* vd_next as pointer. */
+ struct elf_internal_verdaux *vd_auxptr; /* vd_aux as pointer. */
+ unsigned int vd_exp_refno; /* Used by the linker. */
+} Elf_Internal_Verdef;
+
+/* This structure appears in a SHT_GNU_verdef section. */
+
+typedef struct elf_internal_verdaux {
+ unsigned long vda_name; /* String table offset of name. */
+ unsigned long vda_next; /* Offset to next verdaux. */
+
+ /* These fields are set up when BFD reads in the structure. FIXME:
+ It would be cleaner to store these in a different structure. */
+ const char *vda_nodename; /* vda_name as pointer. */
+ struct elf_internal_verdaux *vda_nextptr; /* vda_next as pointer. */
+} Elf_Internal_Verdaux;
+
+/* This structure appears in a SHT_GNU_verneed section. */
+
+typedef struct elf_internal_verneed {
+ unsigned short vn_version; /* Version number of structure. */
+ unsigned short vn_cnt; /* Number of vernaux entries. */
+ unsigned long vn_file; /* String table offset of library name. */
+ unsigned long vn_aux; /* Offset to vernaux entries. */
+ unsigned long vn_next; /* Offset to next verneed. */
+
+ /* These fields are set up when BFD reads in the structure. FIXME:
+ It would be cleaner to store these in a different structure. */
+ bfd *vn_bfd; /* BFD. */
+ const char *vn_filename; /* vn_file as pointer. */
+ struct elf_internal_vernaux *vn_auxptr; /* vn_aux as pointer. */
+ struct elf_internal_verneed *vn_nextref; /* vn_nextref as pointer. */
+} Elf_Internal_Verneed;
+
+/* This structure appears in a SHT_GNU_verneed section. */
+
+typedef struct elf_internal_vernaux {
+ unsigned long vna_hash; /* Hash of dependency name. */
+ unsigned short vna_flags; /* Flags (VER_FLG_*). */
+ unsigned short vna_other; /* Unused. */
+ unsigned long vna_name; /* String table offset to version name. */
+ unsigned long vna_next; /* Offset to next vernaux. */
+
+ /* These fields are set up when BFD reads in the structure. FIXME:
+ It would be cleaner to store these in a different structure. */
+ const char *vna_nodename; /* vna_name as pointer. */
+ struct elf_internal_vernaux *vna_nextptr; /* vna_next as pointer. */
+} Elf_Internal_Vernaux;
+
+/* This structure appears in a SHT_GNU_versym section. This is not a
+ standard ELF structure; ELF just uses Elf32_Half. */
+
+typedef struct elf_internal_versym {
+ unsigned short vs_vers;
+} Elf_Internal_Versym;
+
+/* Structure for syminfo section. */
+typedef struct
+{
+ unsigned short int si_boundto;
+ unsigned short int si_flags;
+} Elf_Internal_Syminfo;
+
+
+#define elf32_internal_verdef elf_internal_verdef
+#define elf64_internal_verdef elf_internal_verdef
+#define elf32_internal_verdaux elf_internal_verdaux
+#define elf64_internal_verdaux elf_internal_verdaux
+#define elf32_internal_verneed elf_internal_verneed
+#define elf64_internal_verneed elf_internal_verneed
+#define elf32_internal_vernaux elf_internal_vernaux
+#define elf64_internal_vernaux elf_internal_vernaux
+#define elf32_internal_versym elf_internal_versym
+#define elf64_internal_versym elf_internal_versym
+
+#define Elf32_Internal_Verdef Elf_Internal_Verdef
+#define Elf64_Internal_Verdef Elf_Internal_Verdef
+#define Elf32_Internal_Verdaux Elf_Internal_Verdaux
+#define Elf64_Internal_Verdaux Elf_Internal_Verdaux
+#define Elf32_Internal_Verneed Elf_Internal_Verneed
+#define Elf64_Internal_Verneed Elf_Internal_Verneed
+#define Elf32_Internal_Vernaux Elf_Internal_Vernaux
+#define Elf64_Internal_Vernaux Elf_Internal_Vernaux
+#define Elf32_Internal_Versym Elf_Internal_Versym
+#define Elf64_Internal_Versym Elf_Internal_Versym
+#define Elf32_Internal_Syminfo Elf_Internal_Syminfo
+#define Elf64_Internal_Syminfo Elf_Internal_Syminfo
+
+/* This structure is used to describe how sections should be assigned
+ to program segments. */
+
+struct elf_segment_map
+{
+ /* Next program segment. */
+ struct elf_segment_map *next;
+ /* Program segment type. */
+ unsigned long p_type;
+ /* Program segment flags. */
+ unsigned long p_flags;
+ /* Program segment physical address. */
+ bfd_vma p_paddr;
+ /* Whether the p_flags field is valid; if not, the flags are based
+ on the section flags. */
+ unsigned int p_flags_valid : 1;
+ /* Whether the p_paddr field is valid; if not, the physical address
+ is based on the section lma values. */
+ unsigned int p_paddr_valid : 1;
+ /* Whether this segment includes the file header. */
+ unsigned int includes_filehdr : 1;
+ /* Whether this segment includes the program headers. */
+ unsigned int includes_phdrs : 1;
+ /* Number of sections (may be 0). */
+ unsigned int count;
+ /* Sections. Actual number of elements is in count field. */
+ asection *sections[1];
+};
+
+#endif /* _ELF_INTERNAL_H */
diff --git a/include/elf/m32r.h b/include/elf/m32r.h
new file mode 100644
index 00000000000..0537d1369cd
--- /dev/null
+++ b/include/elf/m32r.h
@@ -0,0 +1,66 @@
+/* M32R ELF support for BFD.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_M32R_H
+#define _ELF_M32R_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_m32r_reloc_type)
+ RELOC_NUMBER (R_M32R_NONE, 0)
+ RELOC_NUMBER (R_M32R_16, 1)
+ RELOC_NUMBER (R_M32R_32, 2)
+ RELOC_NUMBER (R_M32R_24, 3)
+ RELOC_NUMBER (R_M32R_10_PCREL, 4)
+ RELOC_NUMBER (R_M32R_18_PCREL, 5)
+ RELOC_NUMBER (R_M32R_26_PCREL, 6)
+ RELOC_NUMBER (R_M32R_HI16_ULO, 7)
+ RELOC_NUMBER (R_M32R_HI16_SLO, 8)
+ RELOC_NUMBER (R_M32R_LO16, 9)
+ RELOC_NUMBER (R_M32R_SDA16, 10)
+ RELOC_NUMBER (R_M32R_GNU_VTINHERIT, 11)
+ RELOC_NUMBER (R_M32R_GNU_VTENTRY, 12)
+ EMPTY_RELOC (R_M32R_max)
+END_RELOC_NUMBERS
+
+/* Processor specific section indices. These sections do not actually
+ exist. Symbols with a st_shndx field corresponding to one of these
+ values have a special meaning. */
+
+/* Small common symbol. */
+#define SHN_M32R_SCOMMON 0xff00
+
+/* Processor specific section flags. */
+
+/* This section contains sufficient relocs to be relaxed.
+ When relaxing, even relocs of branch instructions the assembler could
+ complete must be present because relaxing may cause the branch target to
+ move. */
+#define SHF_M32R_CAN_RELAX 0x10000000
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* Two bit m32r architecture field. */
+#define EF_M32R_ARCH 0x30000000
+
+/* m32r code. */
+#define E_M32R_ARCH 0x00000000
+
+#endif
diff --git a/include/elf/m68k.h b/include/elf/m68k.h
new file mode 100644
index 00000000000..db31cdcda45
--- /dev/null
+++ b/include/elf/m68k.h
@@ -0,0 +1,56 @@
+/* MC68k ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_M68K_H
+#define _ELF_M68K_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocation types. */
+START_RELOC_NUMBERS (elf_m68k_reloc_type)
+ RELOC_NUMBER (R_68K_NONE, 0) /* No reloc */
+ RELOC_NUMBER (R_68K_32, 1) /* Direct 32 bit */
+ RELOC_NUMBER (R_68K_16, 2) /* Direct 16 bit */
+ RELOC_NUMBER (R_68K_8, 3) /* Direct 8 bit */
+ RELOC_NUMBER (R_68K_PC32, 4) /* PC relative 32 bit */
+ RELOC_NUMBER (R_68K_PC16, 5) /* PC relative 16 bit */
+ RELOC_NUMBER (R_68K_PC8, 6) /* PC relative 8 bit */
+ RELOC_NUMBER (R_68K_GOT32, 7) /* 32 bit PC relative GOT entry */
+ RELOC_NUMBER (R_68K_GOT16, 8) /* 16 bit PC relative GOT entry */
+ RELOC_NUMBER (R_68K_GOT8, 9) /* 8 bit PC relative GOT entry */
+ RELOC_NUMBER (R_68K_GOT32O, 10) /* 32 bit GOT offset */
+ RELOC_NUMBER (R_68K_GOT16O, 11) /* 16 bit GOT offset */
+ RELOC_NUMBER (R_68K_GOT8O, 12) /* 8 bit GOT offset */
+ RELOC_NUMBER (R_68K_PLT32, 13) /* 32 bit PC relative PLT address */
+ RELOC_NUMBER (R_68K_PLT16, 14) /* 16 bit PC relative PLT address */
+ RELOC_NUMBER (R_68K_PLT8, 15) /* 8 bit PC relative PLT address */
+ RELOC_NUMBER (R_68K_PLT32O, 16) /* 32 bit PLT offset */
+ RELOC_NUMBER (R_68K_PLT16O, 17) /* 16 bit PLT offset */
+ RELOC_NUMBER (R_68K_PLT8O, 18) /* 8 bit PLT offset */
+ RELOC_NUMBER (R_68K_COPY, 19) /* Copy symbol at runtime */
+ RELOC_NUMBER (R_68K_GLOB_DAT, 20) /* Create GOT entry */
+ RELOC_NUMBER (R_68K_JMP_SLOT, 21) /* Create PLT entry */
+ RELOC_NUMBER (R_68K_RELATIVE, 22) /* Adjust by program base */
+ /* These are GNU extensions to enable C++ vtable garbage collection. */
+ RELOC_NUMBER (R_68K_GNU_VTINHERIT, 23)
+ RELOC_NUMBER (R_68K_GNU_VTENTRY, 24)
+ EMPTY_RELOC (R_68K_max)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/mcore.h b/include/elf/mcore.h
new file mode 100644
index 00000000000..a7c4dad112d
--- /dev/null
+++ b/include/elf/mcore.h
@@ -0,0 +1,43 @@
+/* Motorolla MCore support for BFD.
+ Copyright (C) 1995, 1999 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the MCore ELF ABI. */
+#ifndef _ELF_MORE_H
+#define _ELF_MORE_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_mcore_reloc_type)
+ RELOC_NUMBER (R_MCORE_NONE, 0)
+ RELOC_NUMBER (R_MCORE_ADDR32, 1)
+ RELOC_NUMBER (R_MCORE_PCRELIMM8BY4, 2)
+ RELOC_NUMBER (R_MCORE_PCRELIMM11BY2, 3)
+ RELOC_NUMBER (R_MCORE_PCRELIMM4BY2, 4)
+ RELOC_NUMBER (R_MCORE_PCREL32, 5)
+ RELOC_NUMBER (R_MCORE_PCRELJSR_IMM11BY2, 6)
+ RELOC_NUMBER (R_MCORE_GNU_VTINHERIT, 7)
+ RELOC_NUMBER (R_MCORE_GNU_VTENTRY, 8)
+ EMPTY_RELOC (R_MCORE_max)
+END_RELOC_NUMBERS
+
+/* Section Attributes. */
+#define SHF_MCORE_NOREAD 0x80000000
+
+#endif /* _ELF_MCORE_H */
diff --git a/include/elf/mips.h b/include/elf/mips.h
new file mode 100644
index 00000000000..c967248da91
--- /dev/null
+++ b/include/elf/mips.h
@@ -0,0 +1,860 @@
+/* MIPS ELF support for BFD.
+ Copyright (C) 1993, 1994, 1995, 1996, 1998 Free Software Foundation, Inc.
+
+ By Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>, from
+ information in the System V Application Binary Interface, MIPS
+ Processor Supplement.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the MIPS ELF ABI. Note
+ that most of this is not actually implemented by BFD. */
+
+#ifndef _ELF_MIPS_H
+#define _ELF_MIPS_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocation types. */
+START_RELOC_NUMBERS (elf_mips_reloc_type)
+ RELOC_NUMBER (R_MIPS_NONE, 0)
+ RELOC_NUMBER (R_MIPS_16, 1)
+ RELOC_NUMBER (R_MIPS_32, 2)
+ RELOC_NUMBER (R_MIPS_REL32, 3)
+ RELOC_NUMBER (R_MIPS_26, 4)
+ RELOC_NUMBER (R_MIPS_HI16, 5)
+ RELOC_NUMBER (R_MIPS_LO16, 6)
+ RELOC_NUMBER (R_MIPS_GPREL16, 7)
+ RELOC_NUMBER (R_MIPS_LITERAL, 8)
+ RELOC_NUMBER (R_MIPS_GOT16, 9)
+ RELOC_NUMBER (R_MIPS_PC16, 10)
+ RELOC_NUMBER (R_MIPS_CALL16, 11)
+ RELOC_NUMBER (R_MIPS_GPREL32, 12)
+ /* The remaining relocs are defined on Irix, although they are not
+ in the MIPS ELF ABI. */
+ RELOC_NUMBER (R_MIPS_UNUSED1, 13)
+ RELOC_NUMBER (R_MIPS_UNUSED2, 14)
+ RELOC_NUMBER (R_MIPS_UNUSED3, 15)
+ RELOC_NUMBER (R_MIPS_SHIFT5, 16)
+ RELOC_NUMBER (R_MIPS_SHIFT6, 17)
+ RELOC_NUMBER (R_MIPS_64, 18)
+ RELOC_NUMBER (R_MIPS_GOT_DISP, 19)
+ RELOC_NUMBER (R_MIPS_GOT_PAGE, 20)
+ RELOC_NUMBER (R_MIPS_GOT_OFST, 21)
+ RELOC_NUMBER (R_MIPS_GOT_HI16, 22)
+ RELOC_NUMBER (R_MIPS_GOT_LO16, 23)
+ RELOC_NUMBER (R_MIPS_SUB, 24)
+ RELOC_NUMBER (R_MIPS_INSERT_A, 25)
+ RELOC_NUMBER (R_MIPS_INSERT_B, 26)
+ RELOC_NUMBER (R_MIPS_DELETE, 27)
+ RELOC_NUMBER (R_MIPS_HIGHER, 28)
+ RELOC_NUMBER (R_MIPS_HIGHEST, 29)
+ RELOC_NUMBER (R_MIPS_CALL_HI16, 30)
+ RELOC_NUMBER (R_MIPS_CALL_LO16, 31)
+ RELOC_NUMBER (R_MIPS_SCN_DISP, 32)
+ RELOC_NUMBER (R_MIPS_REL16, 33)
+ RELOC_NUMBER (R_MIPS_ADD_IMMEDIATE, 34)
+ RELOC_NUMBER (R_MIPS_PJUMP, 35)
+ RELOC_NUMBER (R_MIPS_RELGOT, 36)
+ RELOC_NUMBER (R_MIPS_JALR, 37)
+ RELOC_NUMBER (R_MIPS_max, 38)
+ /* These relocs are used for the mips16. */
+ RELOC_NUMBER (R_MIPS16_26, 100)
+ RELOC_NUMBER (R_MIPS16_GPREL, 101)
+ /* These are GNU extensions to enable C++ vtable garbage collection. */
+ RELOC_NUMBER (R_MIPS_GNU_VTINHERIT, 253)
+ RELOC_NUMBER (R_MIPS_GNU_VTENTRY, 254)
+END_RELOC_NUMBERS
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* At least one .noreorder directive appears in the source. */
+#define EF_MIPS_NOREORDER 0x00000001
+
+/* File contains position independent code. */
+#define EF_MIPS_PIC 0x00000002
+
+/* Code in file uses the standard calling sequence for calling
+ position independent code. */
+#define EF_MIPS_CPIC 0x00000004
+
+/* Code in file uses new ABI (-n32 on Irix 6). */
+#define EF_MIPS_ABI2 0x00000020
+
+/* Indicates code compiled for a 64-bit machine in 32-bit mode.
+ (regs are 32-bits wide.) */
+#define EF_MIPS_32BITMODE 0x00000100
+
+/* Four bit MIPS architecture field. */
+#define EF_MIPS_ARCH 0xf0000000
+
+/* -mips1 code. */
+#define E_MIPS_ARCH_1 0x00000000
+
+/* -mips2 code. */
+#define E_MIPS_ARCH_2 0x10000000
+
+/* -mips3 code. */
+#define E_MIPS_ARCH_3 0x20000000
+
+/* -mips4 code. */
+#define E_MIPS_ARCH_4 0x30000000
+
+/* The ABI of the file. Also see EF_MIPS_ABI2 above. */
+#define EF_MIPS_ABI 0x0000F000
+
+/* The original o32 abi. */
+#define E_MIPS_ABI_O32 0x00001000
+
+/* O32 extended to work on 64 bit architectures */
+#define E_MIPS_ABI_O64 0x00002000
+
+/* EABI in 32 bit mode */
+#define E_MIPS_ABI_EABI32 0x00003000
+
+/* EABI in 64 bit mode */
+#define E_MIPS_ABI_EABI64 0x00004000
+
+
+/* Machine variant if we know it. This field was invented at Cygnus,
+ but it is hoped that other vendors will adopt it. If some standard
+ is developed, this code should be changed to follow it. */
+
+#define EF_MIPS_MACH 0x00FF0000
+
+/* Cygnus is choosing values between 80 and 9F;
+ 00 - 7F should be left for a future standard;
+ the rest are open. */
+
+#define E_MIPS_MACH_3900 0x00810000
+
+#define E_MIPS_MACH_4010 0x00820000
+#define E_MIPS_MACH_4100 0x00830000
+#define E_MIPS_MACH_4650 0x00850000
+#define E_MIPS_MACH_4111 0x00880000
+
+
+/* Processor specific section indices. These sections do not actually
+ exist. Symbols with a st_shndx field corresponding to one of these
+ values have a special meaning. */
+
+/* Defined and allocated common symbol. Value is virtual address. If
+ relocated, alignment must be preserved. */
+#define SHN_MIPS_ACOMMON 0xff00
+
+/* Defined and allocated text symbol. Value is virtual address.
+ Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */
+#define SHN_MIPS_TEXT 0xff01
+
+/* Defined and allocated data symbol. Value is virtual address.
+ Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */
+#define SHN_MIPS_DATA 0xff02
+
+/* Small common symbol. */
+#define SHN_MIPS_SCOMMON 0xff03
+
+/* Small undefined symbol. */
+#define SHN_MIPS_SUNDEFINED 0xff04
+
+/* Processor specific section types. */
+
+/* Section contains the set of dynamic shared objects used when
+ statically linking. */
+#define SHT_MIPS_LIBLIST 0x70000000
+
+/* I'm not sure what this is, but it's used on Irix 5. */
+#define SHT_MIPS_MSYM 0x70000001
+
+/* Section contains list of symbols whose definitions conflict with
+ symbols defined in shared objects. */
+#define SHT_MIPS_CONFLICT 0x70000002
+
+/* Section contains the global pointer table. */
+#define SHT_MIPS_GPTAB 0x70000003
+
+/* Section contains microcode information. The exact format is
+ unspecified. */
+#define SHT_MIPS_UCODE 0x70000004
+
+/* Section contains some sort of debugging information. The exact
+ format is unspecified. It's probably ECOFF symbols. */
+#define SHT_MIPS_DEBUG 0x70000005
+
+/* Section contains register usage information. */
+#define SHT_MIPS_REGINFO 0x70000006
+
+/* ??? */
+#define SHT_MIPS_PACKAGE 0x70000007
+
+/* ??? */
+#define SHT_MIPS_PACKSYM 0x70000008
+
+/* ??? */
+#define SHT_MIPS_RELD 0x70000009
+
+/* Section contains interface information. */
+#define SHT_MIPS_IFACE 0x7000000b
+
+/* Section contains description of contents of another section. */
+#define SHT_MIPS_CONTENT 0x7000000c
+
+/* Section contains miscellaneous options. */
+#define SHT_MIPS_OPTIONS 0x7000000d
+
+/* ??? */
+#define SHT_MIPS_SHDR 0x70000010
+
+/* ??? */
+#define SHT_MIPS_FDESC 0x70000011
+
+/* ??? */
+#define SHT_MIPS_EXTSYM 0x70000012
+
+/* ??? */
+#define SHT_MIPS_DENSE 0x70000013
+
+/* ??? */
+#define SHT_MIPS_PDESC 0x70000014
+
+/* ??? */
+#define SHT_MIPS_LOCSYM 0x70000015
+
+/* ??? */
+#define SHT_MIPS_AUXSYM 0x70000016
+
+/* ??? */
+#define SHT_MIPS_OPTSYM 0x70000017
+
+/* ??? */
+#define SHT_MIPS_LOCSTR 0x70000018
+
+/* ??? */
+#define SHT_MIPS_LINE 0x70000019
+
+/* ??? */
+#define SHT_MIPS_RFDESC 0x7000001a
+
+/* ??? */
+#define SHT_MIPS_DELTASYM 0x7000001b
+
+/* ??? */
+#define SHT_MIPS_DELTAINST 0x7000001c
+
+/* ??? */
+#define SHT_MIPS_DELTACLASS 0x7000001d
+
+/* DWARF debugging section. */
+#define SHT_MIPS_DWARF 0x7000001e
+
+/* ??? */
+#define SHT_MIPS_DELTADECL 0x7000001f
+
+/* List of libraries the binary depends on. Includes a time stamp, version
+ number. */
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+
+/* Events section. */
+#define SHT_MIPS_EVENTS 0x70000021
+
+/* ??? */
+#define SHT_MIPS_TRANSLATE 0x70000022
+
+/* ??? */
+#define SHT_MIPS_PIXIE 0x70000023
+
+/* ??? */
+#define SHT_MIPS_XLATE 0x70000024
+
+/* ??? */
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+
+/* ??? */
+#define SHT_MIPS_WHIRL 0x70000026
+
+/* ??? */
+#define SHT_MIPS_EH_REGION 0x70000027
+
+/* ??? */
+#define SHT_MIPS_XLATE_OLD 0x70000028
+
+/* ??? */
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+
+/* A section of type SHT_MIPS_LIBLIST contains an array of the
+ following structure. The sh_link field is the section index of the
+ string table. The sh_info field is the number of entries in the
+ section. */
+typedef struct
+{
+ /* String table index for name of shared object. */
+ unsigned long l_name;
+ /* Time stamp. */
+ unsigned long l_time_stamp;
+ /* Checksum of symbol names and common sizes. */
+ unsigned long l_checksum;
+ /* String table index for version. */
+ unsigned long l_version;
+ /* Flags. */
+ unsigned long l_flags;
+} Elf32_Lib;
+
+/* The external version of Elf32_Lib. */
+typedef struct
+{
+ unsigned char l_name[4];
+ unsigned char l_time_stamp[4];
+ unsigned char l_checksum[4];
+ unsigned char l_version[4];
+ unsigned char l_flags[4];
+} Elf32_External_Lib;
+
+/* The l_flags field of an Elf32_Lib structure may contain the
+ following flags. */
+
+/* Require an exact match at runtime. */
+#define LL_EXACT_MATCH 0x00000001
+
+/* Ignore version incompatibilities at runtime. */
+#define LL_IGNORE_INT_VER 0x00000002
+
+/* Require matching minor version number. */
+#define LL_REQUIRE_MINOR 0x00000004
+
+/* ??? */
+#define LL_EXPORTS 0x00000008
+
+/* Delay loading of this library until really needed. */
+#define LL_DELAY_LOAD 0x00000010
+
+/* ??? Delta C++ stuff ??? */
+#define LL_DELTA 0x00000020
+
+
+/* A section of type SHT_MIPS_CONFLICT is an array of indices into the
+ .dynsym section. Each element has the following type. */
+typedef unsigned long Elf32_Conflict;
+typedef unsigned char Elf32_External_Conflict[4];
+
+typedef unsigned long Elf64_Conflict;
+typedef unsigned char Elf64_External_Conflict[8];
+
+/* A section of type SHT_MIPS_GPTAB contains information about how
+ much GP space would be required for different -G arguments. This
+ information is only used so that the linker can provide informative
+ suggestions as to the best -G value to use. The sh_info field is
+ the index of the section for which this information applies. The
+ contents of the section are an array of the following union. The
+ first element uses the gt_header field. The remaining elements use
+ the gt_entry field. */
+typedef union
+{
+ struct
+ {
+ /* -G value actually used for this object file. */
+ unsigned long gt_current_g_value;
+ /* Unused. */
+ unsigned long gt_unused;
+ } gt_header;
+ struct
+ {
+ /* If this -G argument has been used... */
+ unsigned long gt_g_value;
+ /* ...this many GP section bytes would be required. */
+ unsigned long gt_bytes;
+ } gt_entry;
+} Elf32_gptab;
+
+/* The external version of Elf32_gptab. */
+
+typedef union
+{
+ struct
+ {
+ unsigned char gt_current_g_value[4];
+ unsigned char gt_unused[4];
+ } gt_header;
+ struct
+ {
+ unsigned char gt_g_value[4];
+ unsigned char gt_bytes[4];
+ } gt_entry;
+} Elf32_External_gptab;
+
+/* A section of type SHT_MIPS_REGINFO contains the following
+ structure. */
+typedef struct
+{
+ /* Mask of general purpose registers used. */
+ unsigned long ri_gprmask;
+ /* Mask of co-processor registers used. */
+ unsigned long ri_cprmask[4];
+ /* GP register value for this object file. */
+ long ri_gp_value;
+} Elf32_RegInfo;
+
+/* The external version of the Elf_RegInfo structure. */
+typedef struct
+{
+ unsigned char ri_gprmask[4];
+ unsigned char ri_cprmask[4][4];
+ unsigned char ri_gp_value[4];
+} Elf32_External_RegInfo;
+
+/* MIPS ELF .reginfo swapping routines. */
+extern void bfd_mips_elf32_swap_reginfo_in
+ PARAMS ((bfd *, const Elf32_External_RegInfo *, Elf32_RegInfo *));
+extern void bfd_mips_elf32_swap_reginfo_out
+ PARAMS ((bfd *, const Elf32_RegInfo *, Elf32_External_RegInfo *));
+
+/* Processor specific section flags. */
+
+/* This section must be in the global data area. */
+#define SHF_MIPS_GPREL 0x10000000
+
+/* This section should be merged. */
+#define SHF_MIPS_MERGE 0x20000000
+
+/* This section contains 32 bit addresses. */
+#define SHF_MIPS_ADDR32 0x40000000
+
+/* This section contains 64 bit addresses. */
+#define SHF_MIPS_ADDR64 0x80000000
+
+/* This section may not be stripped. */
+#define SHF_MIPS_NOSTRIP 0x08000000
+
+/* This section is local to threads. */
+#define SHF_MIPS_LOCAL 0x04000000
+
+/* Linker should generate implicit weak names for this section. */
+#define SHF_MIPS_NAMES 0x02000000
+
+/* Processor specific program header types. */
+
+/* Register usage information. Identifies one .reginfo section. */
+#define PT_MIPS_REGINFO 0x70000000
+
+/* Runtime procedure table. */
+#define PT_MIPS_RTPROC 0x70000001
+
+/* Options (for what ???). */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Processor specific dynamic array tags. */
+
+/* 32 bit version number for runtime linker interface. */
+#define DT_MIPS_RLD_VERSION 0x70000001
+
+/* Time stamp. */
+#define DT_MIPS_TIME_STAMP 0x70000002
+
+/* Checksum of external strings and common sizes. */
+#define DT_MIPS_ICHECKSUM 0x70000003
+
+/* Index of version string in string table. */
+#define DT_MIPS_IVERSION 0x70000004
+
+/* 32 bits of flags. */
+#define DT_MIPS_FLAGS 0x70000005
+
+/* Base address of the segment. */
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+
+/* ??? */
+#define DT_MIPS_MSYM 0x70000007
+
+/* Address of .conflict section. */
+#define DT_MIPS_CONFLICT 0x70000008
+
+/* Address of .liblist section. */
+#define DT_MIPS_LIBLIST 0x70000009
+
+/* Number of local global offset table entries. */
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+
+/* Number of entries in the .conflict section. */
+#define DT_MIPS_CONFLICTNO 0x7000000b
+
+/* Number of entries in the .liblist section. */
+#define DT_MIPS_LIBLISTNO 0x70000010
+
+/* Number of entries in the .dynsym section. */
+#define DT_MIPS_SYMTABNO 0x70000011
+
+/* Index of first external dynamic symbol not referenced locally. */
+#define DT_MIPS_UNREFEXTNO 0x70000012
+
+/* Index of first dynamic symbol in global offset table. */
+#define DT_MIPS_GOTSYM 0x70000013
+
+/* Number of page table entries in global offset table. */
+#define DT_MIPS_HIPAGENO 0x70000014
+
+/* Address of run time loader map, used for debugging. */
+#define DT_MIPS_RLD_MAP 0x70000016
+
+/* Delta C++ class definition. */
+#define DT_MIPS_DELTA_CLASS 0x70000017
+
+/* Number of entries in DT_MIPS_DELTA_CLASS. */
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018
+
+/* Delta C++ class instances. */
+#define DT_MIPS_DELTA_INSTANCE 0x70000019
+
+/* Number of entries in DT_MIPS_DELTA_INSTANCE. */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
+
+/* Delta relocations. */
+#define DT_MIPS_DELTA_RELOC 0x7000001b
+
+/* Number of entries in DT_MIPS_DELTA_RELOC. */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c
+
+/* Delta symbols that Delta relocations refer to. */
+#define DT_MIPS_DELTA_SYM 0x7000001d
+
+/* Number of entries in DT_MIPS_DELTA_SYM. */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e
+
+/* Delta symbols that hold class declarations. */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+
+/* Number of entries in DT_MIPS_DELTA_CLASSSYM. */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+
+/* Flags indicating information about C++ flavor. */
+#define DT_MIPS_CXX_FLAGS 0x70000022
+
+/* Pixie information (???). */
+#define DT_MIPS_PIXIE_INIT 0x70000023
+
+/* ??? */
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+
+/* ??? */
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+
+/* ??? */
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+
+/* ??? */
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+
+/* ??? */
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+
+/* Address of `.MIPS.options'. */
+#define DT_MIPS_OPTIONS 0x70000029
+
+/* Address of `.interface'. */
+#define DT_MIPS_INTERFACE 0x7000002a
+
+/* ??? */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+
+/* Size of the .interface section. */
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c
+
+/* Size of rld_text_resolve function stored in the GOT. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
+
+/* Default suffix of DSO to be added by rld on dlopen() calls. */
+#define DT_MIPS_PERF_SUFFIX 0x7000002e
+
+/* Size of compact relocation section (O32). */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f
+
+/* GP value for auxiliary GOTs. */
+#define DT_MIPS_GP_VALUE 0x70000030
+
+/* Address of auxiliary .dynamic. */
+#define DT_MIPS_AUX_DYNAMIC 0x70000031
+
+/* Flags which may appear in a DT_MIPS_FLAGS entry. */
+
+/* No flags. */
+#define RHF_NONE 0x00000000
+
+/* Uses shortcut pointers. */
+#define RHF_QUICKSTART 0x00000001
+
+/* Hash size is not a power of two. */
+#define RHF_NOTPOT 0x00000002
+
+/* Ignore LD_LIBRARY_PATH. */
+#define RHS_NO_LIBRARY_REPLACEMENT \
+ 0x00000004
+
+#define RHF_NO_MOVE 0x00000008
+#define RHF_SGI_ONLY 0x00000010
+#define RHF_GUARANTEE_INIT 0x00000020
+#define RHF_DELTA_C_PLUS_PLUS 0x00000040
+#define RHF_GUARANTEE_START_INIT 0x00000080
+#define RHF_PIXIE 0x00000100
+#define RHF_DEFAULT_DELAY_LOAD 0x00000200
+#define RHF_REQUICKSTART 0x00000400
+#define RHF_REQUICKSTARTED 0x00000800
+#define RHF_CORD 0x00001000
+#define RHF_NO_UNRES_UNDEF 0x00002000
+#define RHF_RLD_ORDER_SAFE 0x00004000
+
+/* Special values for the st_other field in the symbol table. These
+ are used in an Irix 5 dynamic symbol table. */
+
+#define STO_DEFAULT 0x00
+#define STO_INTERNAL 0x01
+#define STO_HIDDEN 0x02
+#define STO_PROTECTED 0x03
+
+/* This value is used for a mips16 .text symbol. */
+#define STO_MIPS16 0xf0
+
+/* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each
+ relocation entry specifies up to three actual relocations, all at
+ the same address. The first relocation which required a symbol
+ uses the symbol in the r_sym field. The second relocation which
+ requires a symbol uses the symbol in the r_ssym field. If all
+ three relocations require a symbol, the third one uses a zero
+ value. */
+
+/* An entry in a 64 bit SHT_REL section. */
+
+typedef struct
+{
+ /* Address of relocation. */
+ unsigned char r_offset[8];
+ /* Symbol index. */
+ unsigned char r_sym[4];
+ /* Special symbol. */
+ unsigned char r_ssym[1];
+ /* Third relocation. */
+ unsigned char r_type3[1];
+ /* Second relocation. */
+ unsigned char r_type2[1];
+ /* First relocation. */
+ unsigned char r_type[1];
+} Elf64_Mips_External_Rel;
+
+typedef struct
+{
+ /* Address of relocation. */
+ bfd_vma r_offset;
+ /* Symbol index. */
+ unsigned long r_sym;
+ /* Special symbol. */
+ unsigned char r_ssym;
+ /* Third relocation. */
+ unsigned char r_type3;
+ /* Second relocation. */
+ unsigned char r_type2;
+ /* First relocation. */
+ unsigned char r_type;
+} Elf64_Mips_Internal_Rel;
+
+/* An entry in a 64 bit SHT_RELA section. */
+
+typedef struct
+{
+ /* Address of relocation. */
+ unsigned char r_offset[8];
+ /* Symbol index. */
+ unsigned char r_sym[4];
+ /* Special symbol. */
+ unsigned char r_ssym[1];
+ /* Third relocation. */
+ unsigned char r_type3[1];
+ /* Second relocation. */
+ unsigned char r_type2[1];
+ /* First relocation. */
+ unsigned char r_type[1];
+ /* Addend. */
+ unsigned char r_addend[8];
+} Elf64_Mips_External_Rela;
+
+typedef struct
+{
+ /* Address of relocation. */
+ bfd_vma r_offset;
+ /* Symbol index. */
+ unsigned long r_sym;
+ /* Special symbol. */
+ unsigned char r_ssym;
+ /* Third relocation. */
+ unsigned char r_type3;
+ /* Second relocation. */
+ unsigned char r_type2;
+ /* First relocation. */
+ unsigned char r_type;
+ /* Addend. */
+ bfd_signed_vma r_addend;
+} Elf64_Mips_Internal_Rela;
+
+/* Values found in the r_ssym field of a relocation entry. */
+
+/* No relocation. */
+#define RSS_UNDEF 0
+
+/* Value of GP. */
+#define RSS_GP 1
+
+/* Value of GP in object being relocated. */
+#define RSS_GP0 2
+
+/* Address of location being relocated. */
+#define RSS_LOC 3
+
+/* A SHT_MIPS_OPTIONS section contains a series of options, each of
+ which starts with this header. */
+
+typedef struct
+{
+ /* Type of option. */
+ unsigned char kind[1];
+ /* Size of option descriptor, including header. */
+ unsigned char size[1];
+ /* Section index of affected section, or 0 for global option. */
+ unsigned char section[2];
+ /* Information specific to this kind of option. */
+ unsigned char info[4];
+} Elf_External_Options;
+
+typedef struct
+{
+ /* Type of option. */
+ unsigned char kind;
+ /* Size of option descriptor, including header. */
+ unsigned char size;
+ /* Section index of affected section, or 0 for global option. */
+ unsigned short section;
+ /* Information specific to this kind of option. */
+ unsigned long info;
+} Elf_Internal_Options;
+
+/* MIPS ELF option header swapping routines. */
+extern void bfd_mips_elf_swap_options_in
+ PARAMS ((bfd *, const Elf_External_Options *, Elf_Internal_Options *));
+extern void bfd_mips_elf_swap_options_out
+ PARAMS ((bfd *, const Elf_Internal_Options *, Elf_External_Options *));
+
+/* Values which may appear in the kind field of an Elf_Options
+ structure. */
+
+/* Undefined. */
+#define ODK_NULL 0
+
+/* Register usage and GP value. */
+#define ODK_REGINFO 1
+
+/* Exception processing information. */
+#define ODK_EXCEPTIONS 2
+
+/* Section padding information. */
+#define ODK_PAD 3
+
+/* Hardware workarounds performed. */
+#define ODK_HWPATCH 4
+
+/* Fill value used by the linker. */
+#define ODK_FILL 5
+
+/* Reserved space for desktop tools. */
+#define ODK_TAGS 6
+
+/* Hardware workarounds, AND bits when merging. */
+#define ODK_HWAND 7
+
+/* Hardware workarounds, OR bits when merging. */
+#define ODK_HWOR 8
+
+/* GP group to use for text/data sections. */
+#define ODK_GP_GROUP 9
+
+/* ID information. */
+#define ODK_IDENT 10
+
+/* In the 32 bit ABI, an ODK_REGINFO option is just a Elf32_RegInfo
+ structure. In the 64 bit ABI, it is the following structure. The
+ info field of the options header is not used. */
+
+typedef struct
+{
+ /* Mask of general purpose registers used. */
+ unsigned char ri_gprmask[4];
+ /* Padding. */
+ unsigned char ri_pad[4];
+ /* Mask of co-processor registers used. */
+ unsigned char ri_cprmask[4][4];
+ /* GP register value for this object file. */
+ unsigned char ri_gp_value[8];
+} Elf64_External_RegInfo;
+
+typedef struct
+{
+ /* Mask of general purpose registers used. */
+ unsigned long ri_gprmask;
+ /* Padding. */
+ unsigned long ri_pad;
+ /* Mask of co-processor registers used. */
+ unsigned long ri_cprmask[4];
+ /* GP register value for this object file. */
+ bfd_vma ri_gp_value;
+} Elf64_Internal_RegInfo;
+
+/* MIPS ELF reginfo swapping routines. */
+extern void bfd_mips_elf64_swap_reginfo_in
+ PARAMS ((bfd *, const Elf64_External_RegInfo *, Elf64_Internal_RegInfo *));
+extern void bfd_mips_elf64_swap_reginfo_out
+ PARAMS ((bfd *, const Elf64_Internal_RegInfo *, Elf64_External_RegInfo *));
+
+/* Masks for the info work of an ODK_EXCEPTIONS descriptor. */
+#define OEX_FPU_MIN 0x1f /* FPEs which must be enabled. */
+#define OEX_FPU_MAX 0x1f00 /* FPEs which may be enabled. */
+#define OEX_PAGE0 0x10000 /* Page zero must be mapped. */
+#define OEX_SMM 0x20000 /* Force sequential memory mode. */
+#define OEX_FPDBUG 0x40000 /* Force floating-point debug mode. */
+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults. */
+
+/* Masks of the FP exceptions for OEX_FPU_MIN and OEX_FPU_MAX. */
+#define OEX_FPU_INVAL 0x10 /* Invalid operation exception. */
+#define OEX_FPU_DIV0 0x08 /* Division by zero exception. */
+#define OEX_FPU_OFLO 0x04 /* Overflow exception. */
+#define OEX_FPU_UFLO 0x02 /* Underflow exception. */
+#define OEX_FPU_INEX 0x01 /* Inexact exception. */
+
+/* Masks for the info word of an ODK_PAD descriptor. */
+#define OPAD_PREFIX 0x01
+#define OPAD_POSTFIX 0x02
+#define OPAD_SYMBOL 0x04
+
+/* Masks for the info word of an ODK_HWPATCH descriptor. */
+#define OHW_R4KEOP 0x01 /* R4000 end-of-page patch. */
+#define OHW_R8KPFETCH 0x02 /* May need R8000 prefetch patch. */
+#define OHW_R5KEOP 0x04 /* R5000 end-of-page patch. */
+#define OHW_R5KCVTL 0x08 /* R5000 cvt.[ds].l bug (clean == 1). */
+
+/* Masks for the info word of an ODK_IDENT/ODK_GP_GROUP descriptor. */
+#define OGP_GROUP 0x0000ffff /* GP group number. */
+#define OGP_SELF 0xffff0000 /* Self-contained GP groups. */
+
+/* Masks for the info word of an ODK_HWAND/ODK_HWOR descriptor. */
+#define OHWA0_R4KEOP_CHECKED 0x00000001
+#define OHWA0_R4KEOP_CLEAN 0x00000002
+
+
+#endif /* _ELF_MIPS_H */
diff --git a/include/elf/mn10200.h b/include/elf/mn10200.h
new file mode 100644
index 00000000000..5e29e0ad211
--- /dev/null
+++ b/include/elf/mn10200.h
@@ -0,0 +1,39 @@
+/* MN10200 ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the MN10200 ELF ABI. */
+
+#ifndef _ELF_MN10200_H
+#define _ELF_MN10200_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_mn10200_reloc_type)
+ RELOC_NUMBER (R_MN10200_NONE, 0)
+ RELOC_NUMBER (R_MN10200_32, 1)
+ RELOC_NUMBER (R_MN10200_16, 2)
+ RELOC_NUMBER (R_MN10200_8, 3)
+ RELOC_NUMBER (R_MN10200_24, 4)
+ RELOC_NUMBER (R_MN10200_PCREL8, 5)
+ RELOC_NUMBER (R_MN10200_PCREL16, 6)
+ RELOC_NUMBER (R_MN10200_PCREL24, 7)
+END_RELOC_NUMBERS
+
+#endif /* _ELF_MN10200_H */
diff --git a/include/elf/mn10300.h b/include/elf/mn10300.h
new file mode 100644
index 00000000000..64a0750451f
--- /dev/null
+++ b/include/elf/mn10300.h
@@ -0,0 +1,53 @@
+/* MN10300 ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the MN10300 ELF ABI. */
+
+#ifndef _ELF_MN10300_H
+#define _ELF_MN10300_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_mn10300_reloc_type)
+ RELOC_NUMBER (R_MN10300_NONE, 0)
+ RELOC_NUMBER (R_MN10300_32, 1)
+ RELOC_NUMBER (R_MN10300_16, 2)
+ RELOC_NUMBER (R_MN10300_8, 3)
+ RELOC_NUMBER (R_MN10300_PCREL32, 4)
+ RELOC_NUMBER (R_MN10300_PCREL16, 5)
+ RELOC_NUMBER (R_MN10300_PCREL8, 6)
+ RELOC_NUMBER (R_MN10300_GNU_VTINHERIT, 7)
+ RELOC_NUMBER (R_MN10300_GNU_VTENTRY, 8)
+ RELOC_NUMBER (R_MN10300_24, 9)
+ EMPTY_RELOC (R_MN10300_MAX)
+END_RELOC_NUMBERS
+
+/* Machine variant if we know it. This field was invented at Cygnus,
+ but it is hoped that other vendors will adopt it. If some standard
+ is developed, this code should be changed to follow it. */
+
+#define EF_MN10300_MACH 0x00FF0000
+
+/* Cygnus is choosing values between 80 and 9F;
+ 00 - 7F should be left for a future standard;
+ the rest are open. */
+
+#define E_MN10300_MACH_MN10300 0x00810000
+#endif /* _ELF_MN10300_H */
diff --git a/include/elf/ppc.h b/include/elf/ppc.h
new file mode 100644
index 00000000000..b3116d8ad01
--- /dev/null
+++ b/include/elf/ppc.h
@@ -0,0 +1,127 @@
+/* PPC ELF support for BFD.
+ Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+
+ By Michael Meissner, Cygnus Support, <meissner@cygnus.com>, from information
+ in the System V Application Binary Interface, PowerPC Processor Supplement
+ and the PowerPC Embedded Application Binary Interface (eabi).
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the PPC ELF ABI. Note
+ that most of this is not actually implemented by BFD. */
+
+#ifndef _ELF_PPC_H
+#define _ELF_PPC_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+START_RELOC_NUMBERS (elf_ppc_reloc_type)
+ RELOC_NUMBER (R_PPC_NONE, 0)
+ RELOC_NUMBER (R_PPC_ADDR32, 1)
+ RELOC_NUMBER (R_PPC_ADDR24, 2)
+ RELOC_NUMBER (R_PPC_ADDR16, 3)
+ RELOC_NUMBER (R_PPC_ADDR16_LO, 4)
+ RELOC_NUMBER (R_PPC_ADDR16_HI, 5)
+ RELOC_NUMBER (R_PPC_ADDR16_HA, 6)
+ RELOC_NUMBER (R_PPC_ADDR14, 7)
+ RELOC_NUMBER (R_PPC_ADDR14_BRTAKEN, 8)
+ RELOC_NUMBER (R_PPC_ADDR14_BRNTAKEN, 9)
+ RELOC_NUMBER (R_PPC_REL24, 10)
+ RELOC_NUMBER (R_PPC_REL14, 11)
+ RELOC_NUMBER (R_PPC_REL14_BRTAKEN, 12)
+ RELOC_NUMBER (R_PPC_REL14_BRNTAKEN, 13)
+ RELOC_NUMBER (R_PPC_GOT16, 14)
+ RELOC_NUMBER (R_PPC_GOT16_LO, 15)
+ RELOC_NUMBER (R_PPC_GOT16_HI, 16)
+ RELOC_NUMBER (R_PPC_GOT16_HA, 17)
+ RELOC_NUMBER (R_PPC_PLTREL24, 18)
+ RELOC_NUMBER (R_PPC_COPY, 19)
+ RELOC_NUMBER (R_PPC_GLOB_DAT, 20)
+ RELOC_NUMBER (R_PPC_JMP_SLOT, 21)
+ RELOC_NUMBER (R_PPC_RELATIVE, 22)
+ RELOC_NUMBER (R_PPC_LOCAL24PC, 23)
+ RELOC_NUMBER (R_PPC_UADDR32, 24)
+ RELOC_NUMBER (R_PPC_UADDR16, 25)
+ RELOC_NUMBER (R_PPC_REL32, 26)
+ RELOC_NUMBER (R_PPC_PLT32, 27)
+ RELOC_NUMBER (R_PPC_PLTREL32, 28)
+ RELOC_NUMBER (R_PPC_PLT16_LO, 29)
+ RELOC_NUMBER (R_PPC_PLT16_HI, 30)
+ RELOC_NUMBER (R_PPC_PLT16_HA, 31)
+ RELOC_NUMBER (R_PPC_SDAREL16, 32)
+ RELOC_NUMBER (R_PPC_SECTOFF, 33)
+ RELOC_NUMBER (R_PPC_SECTOFF_LO, 34)
+ RELOC_NUMBER (R_PPC_SECTOFF_HI, 35)
+ RELOC_NUMBER (R_PPC_SECTOFF_HA, 36)
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+ in the SVR4 ELF ABI. */
+ RELOC_NUMBER (R_PPC_EMB_NADDR32, 101)
+ RELOC_NUMBER (R_PPC_EMB_NADDR16, 102)
+ RELOC_NUMBER (R_PPC_EMB_NADDR16_LO, 103)
+ RELOC_NUMBER (R_PPC_EMB_NADDR16_HI, 104)
+ RELOC_NUMBER (R_PPC_EMB_NADDR16_HA, 105)
+ RELOC_NUMBER (R_PPC_EMB_SDAI16, 106)
+ RELOC_NUMBER (R_PPC_EMB_SDA2I16, 107)
+ RELOC_NUMBER (R_PPC_EMB_SDA2REL, 108)
+ RELOC_NUMBER (R_PPC_EMB_SDA21, 109)
+ RELOC_NUMBER (R_PPC_EMB_MRKREF, 110)
+ RELOC_NUMBER (R_PPC_EMB_RELSEC16, 111)
+ RELOC_NUMBER (R_PPC_EMB_RELST_LO, 112)
+ RELOC_NUMBER (R_PPC_EMB_RELST_HI, 113)
+ RELOC_NUMBER (R_PPC_EMB_RELST_HA, 114)
+ RELOC_NUMBER (R_PPC_EMB_BIT_FLD, 115)
+ RELOC_NUMBER (R_PPC_EMB_RELSDA, 116)
+
+ /* These are GNU extensions to enable C++ vtable garbage collection. */
+ RELOC_NUMBER (R_PPC_GNU_VTINHERIT, 253)
+ RELOC_NUMBER (R_PPC_GNU_VTENTRY, 254)
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+ that may still be in object files. */
+ RELOC_NUMBER (R_PPC_TOC16, 255)
+
+ EMPTY_RELOC (R_PPC_max)
+END_RELOC_NUMBERS
+
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
+
+ /* CYGNUS local bits below */
+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag */
+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib flag */
+
+/* Processor specific section headers, sh_type field */
+
+#define SHT_ORDERED SHT_HIPROC /* Link editor is to sort the \
+ entries in this section \
+ based on the address \
+ specified in the associated \
+ symbol table entry. */
+
+/* Processor specific section flags, sh_flags field */
+
+#define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude \
+ this section from executable \
+ and shared objects that it \
+ builds when those objects \
+ are not to be furhter \
+ relocated. */
+#endif /* _ELF_PPC_H */
diff --git a/include/elf/reloc-macros.h b/include/elf/reloc-macros.h
new file mode 100644
index 00000000000..976229129c0
--- /dev/null
+++ b/include/elf/reloc-macros.h
@@ -0,0 +1,116 @@
+/* Generic relocation support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* These macros are used by the various *.h target specific header
+ files to either generate an enum containing all the known relocations
+ for that target, or if RELOC_MACROS_GEN_FUNC is defined, a recognition
+ function is generated instead. (This is used by binutils/readelf.c)
+
+ Given a header file like this:
+
+ START_RELOC_NUMBERS (foo)
+ RELOC_NUMBER (R_foo_NONE, 0)
+ RELOC_NUMBER (R_foo_32, 1)
+ FAKE_RELOC (R_foo_illegal, 2)
+ EMPTY_RELOC (R_foo_max)
+ END_RELOC_NUMBERS
+
+ Then the following will be produced by default (ie if
+ RELOC_MACROS_GEN_FUNC is *not* defined).
+
+ enum foo
+ {
+ foo = -1,
+ R_foo_NONE = 0,
+ R_foo_32 = 1,
+ R_foo_illegal = 2,
+ R_foo_max
+ };
+
+ If RELOC_MACROS_GEN_FUNC *is* defined, then instead the
+ following function will be generated:
+
+ static char * foo PARAMS ((unsigned long rtype));
+ static char *
+ foo (rtype)
+ unsigned long rtype;
+ {
+ switch (rtype)
+ {
+ case 0: return "R_foo_NONE";
+ case 1: return "R_foo_32";
+ default: return NULL;
+ }
+ }
+ */
+
+#ifndef _RELOC_MACROS_H
+#define _RELOC_MACROS_H
+
+#ifdef RELOC_MACROS_GEN_FUNC
+
+/* This function takes the relocation number and returns the
+ string version name of the name of that relocation. If
+ the relocation is not recognised, NULL is returned. */
+
+#define START_RELOC_NUMBERS(name) \
+static const char * name PARAMS ((unsigned long rtype)); \
+static const char * \
+name (rtype) \
+ unsigned long rtype; \
+{ \
+ switch (rtype) \
+ {
+
+#ifdef __STDC__
+#define RELOC_NUMBER(name, number) case number : return #name ;
+#else
+#define RELOC_NUMBER(name, number) case number : return "name" ;
+#endif
+
+#define FAKE_RELOC(name, number)
+#define EMPTY_RELOC(name)
+
+#define END_RELOC_NUMBERS \
+ default: return NULL; \
+ } \
+}
+
+
+#else /* Default to generating enum. */
+
+/* Some compilers cannot cope with an enum that ends with a trailing
+ comma, so START_RELOC_NUMBERS creates a fake reloc entry, (initialised
+ to -1 so that the first real entry will still default to 0). Further
+ entries then prepend a comma to their definitions, creating a list
+ of enumerator entries that will satisfy these compilers. */
+#ifdef __STDC__
+#define START_RELOC_NUMBERS(name) enum name { _##name = -1
+#else
+#define START_RELOC_NUMBERS(name) enum name { name = -1
+#endif
+
+#define RELOC_NUMBER(name, number) , name = number
+#define FAKE_RELOC(name, number) , name = number
+#define EMPTY_RELOC(name) , name
+#define END_RELOC_NUMBERS };
+
+#endif
+
+#endif /* RELOC_MACROS_H */
diff --git a/include/elf/sh.h b/include/elf/sh.h
new file mode 100644
index 00000000000..4a476679ab6
--- /dev/null
+++ b/include/elf/sh.h
@@ -0,0 +1,55 @@
+/* SH ELF support for BFD.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_SH_H
+#define _ELF_SH_H
+
+#include "elf/reloc-macros.h"
+
+/* Relocations. */
+/* Relocations 25ff are GNU extensions.
+ 25..33 are used for relaxation and use the same constants as COFF uses. */
+START_RELOC_NUMBERS (elf_sh_reloc_type)
+ RELOC_NUMBER (R_SH_NONE, 0)
+ RELOC_NUMBER (R_SH_DIR32, 1)
+ RELOC_NUMBER (R_SH_REL32, 2)
+ RELOC_NUMBER (R_SH_DIR8WPN, 3)
+ RELOC_NUMBER (R_SH_IND12W, 4)
+ RELOC_NUMBER (R_SH_DIR8WPL, 5)
+ RELOC_NUMBER (R_SH_DIR8WPZ, 6)
+ RELOC_NUMBER (R_SH_DIR8BP, 7)
+ RELOC_NUMBER (R_SH_DIR8W, 8)
+ RELOC_NUMBER (R_SH_DIR8L, 9)
+ FAKE_RELOC (R_SH_FIRST_INVALID_RELOC, 10)
+ FAKE_RELOC (R_SH_LAST_INVALID_RELOC, 24)
+ RELOC_NUMBER (R_SH_SWITCH16, 25)
+ RELOC_NUMBER (R_SH_SWITCH32, 26)
+ RELOC_NUMBER (R_SH_USES, 27)
+ RELOC_NUMBER (R_SH_COUNT, 28)
+ RELOC_NUMBER (R_SH_ALIGN, 29)
+ RELOC_NUMBER (R_SH_CODE, 30)
+ RELOC_NUMBER (R_SH_DATA, 31)
+ RELOC_NUMBER (R_SH_LABEL, 32)
+ RELOC_NUMBER (R_SH_SWITCH8, 33)
+ RELOC_NUMBER (R_SH_GNU_VTINHERIT, 34)
+ RELOC_NUMBER (R_SH_GNU_VTENTRY, 35)
+ EMPTY_RELOC (R_SH_max)
+END_RELOC_NUMBERS
+
+#endif
diff --git a/include/elf/sparc.h b/include/elf/sparc.h
new file mode 100644
index 00000000000..c9e4cdd4040
--- /dev/null
+++ b/include/elf/sparc.h
@@ -0,0 +1,156 @@
+/* SPARC ELF support for BFD.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ By Doug Evans, Cygnus Support, <dje@cygnus.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ELF_SPARC_H
+#define _ELF_SPARC_H
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* These are defined by Sun. */
+
+#define EF_SPARC_32PLUS_MASK 0xffff00 /* bits indicating V8+ type */
+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
+
+#define EF_SPARC_LEDATA 0x800000 /* little endian data */
+
+/* This name is used in the V9 ABI. */
+#define EF_SPARC_EXT_MASK 0xffff00 /* reserved for vendor extensions */
+
+/* V9 memory models */
+#define EF_SPARCV9_MM 0x3 /* memory model mask */
+#define EF_SPARCV9_TSO 0x0 /* total store ordering */
+#define EF_SPARCV9_PSO 0x1 /* partial store ordering */
+#define EF_SPARCV9_RMO 0x2 /* relaxed store ordering */
+
+/* Section indices. */
+
+#define SHN_BEFORE 0xff00 /* used with SHF_ORDERED */
+#define SHN_AFTER 0xff01 /* used with SHF_ORDERED */
+
+/* Section flags. */
+
+#define SHF_EXCLUDE 0x80000000 /* exclude from linking */
+#define SHF_ORDERED 0x40000000 /* treat sh_link,sh_info specially */
+
+/* Symbol types. */
+
+#define STT_REGISTER 13 /* global reg reserved to app. */
+
+#include "elf/reloc-macros.h"
+
+/* Relocation types. */
+START_RELOC_NUMBERS (elf_sparc_reloc_type)
+ RELOC_NUMBER (R_SPARC_NONE, 0)
+ RELOC_NUMBER (R_SPARC_8, 1)
+ RELOC_NUMBER (R_SPARC_16, 2)
+ RELOC_NUMBER (R_SPARC_32, 3)
+ RELOC_NUMBER (R_SPARC_DISP8, 4)
+ RELOC_NUMBER (R_SPARC_DISP16, 5)
+ RELOC_NUMBER (R_SPARC_DISP32, 6)
+ RELOC_NUMBER (R_SPARC_WDISP30, 7)
+ RELOC_NUMBER (R_SPARC_WDISP22, 8)
+ RELOC_NUMBER (R_SPARC_HI22, 9)
+ RELOC_NUMBER (R_SPARC_22, 10)
+ RELOC_NUMBER (R_SPARC_13, 11)
+ RELOC_NUMBER (R_SPARC_LO10, 12)
+ RELOC_NUMBER (R_SPARC_GOT10, 13)
+ RELOC_NUMBER (R_SPARC_GOT13, 14)
+ RELOC_NUMBER (R_SPARC_GOT22, 15)
+ RELOC_NUMBER (R_SPARC_PC10, 16)
+ RELOC_NUMBER (R_SPARC_PC22, 17)
+ RELOC_NUMBER (R_SPARC_WPLT30, 18)
+ RELOC_NUMBER (R_SPARC_COPY, 19)
+ RELOC_NUMBER (R_SPARC_GLOB_DAT, 20)
+ RELOC_NUMBER (R_SPARC_JMP_SLOT, 21)
+ RELOC_NUMBER (R_SPARC_RELATIVE, 22)
+ RELOC_NUMBER (R_SPARC_UA32, 23)
+
+ /* ??? These 6 relocs are new but not currently used. For binary
+ compatility in the sparc64-elf toolchain, we leave them out.
+ A non-binary upward compatible change is expected for sparc64-elf. */
+#ifndef SPARC64_OLD_RELOCS
+ /* ??? New relocs on the UltraSPARC. Not sure what they're for yet. */
+ RELOC_NUMBER (R_SPARC_PLT32, 24)
+ RELOC_NUMBER (R_SPARC_HIPLT22, 25)
+ RELOC_NUMBER (R_SPARC_LOPLT10, 26)
+ RELOC_NUMBER (R_SPARC_PCPLT32, 27)
+ RELOC_NUMBER (R_SPARC_PCPLT22, 28)
+ RELOC_NUMBER (R_SPARC_PCPLT10, 29)
+#endif
+
+ /* v9 relocs */
+ RELOC_NUMBER (R_SPARC_10, 30)
+ RELOC_NUMBER (R_SPARC_11, 31)
+ RELOC_NUMBER (R_SPARC_64, 32)
+ RELOC_NUMBER (R_SPARC_OLO10, 33)
+ RELOC_NUMBER (R_SPARC_HH22, 34)
+ RELOC_NUMBER (R_SPARC_HM10, 35)
+ RELOC_NUMBER (R_SPARC_LM22, 36)
+ RELOC_NUMBER (R_SPARC_PC_HH22, 37)
+ RELOC_NUMBER (R_SPARC_PC_HM10, 38)
+ RELOC_NUMBER (R_SPARC_PC_LM22, 39)
+ RELOC_NUMBER (R_SPARC_WDISP16, 40)
+ RELOC_NUMBER (R_SPARC_WDISP19, 41)
+ RELOC_NUMBER (R_SPARC_UNUSED_42, 42)
+ RELOC_NUMBER (R_SPARC_7, 43)
+ RELOC_NUMBER (R_SPARC_5, 44)
+ RELOC_NUMBER (R_SPARC_6, 45)
+ RELOC_NUMBER (R_SPARC_DISP64, 46)
+ RELOC_NUMBER (R_SPARC_PLT64, 47)
+ RELOC_NUMBER (R_SPARC_HIX22, 48)
+ RELOC_NUMBER (R_SPARC_LOX10, 49)
+ RELOC_NUMBER (R_SPARC_H44, 50)
+ RELOC_NUMBER (R_SPARC_M44, 51)
+ RELOC_NUMBER (R_SPARC_L44, 52)
+ RELOC_NUMBER (R_SPARC_REGISTER, 53)
+ RELOC_NUMBER (R_SPARC_UA64, 54)
+ RELOC_NUMBER (R_SPARC_UA16, 55)
+
+ /* little endian data relocs */
+ RELOC_NUMBER (R_SPARC_REV32, 56)
+
+ RELOC_NUMBER (R_SPARC_GNU_VTINHERIT, 250)
+ RELOC_NUMBER (R_SPARC_GNU_VTENTRY, 251)
+
+ EMPTY_RELOC (R_SPARC_max)
+END_RELOC_NUMBERS
+
+/* Relocation macros. */
+
+#define ELF64_R_TYPE_DATA(info) (((bfd_vma) (info) << 32) >> 40)
+#define ELF64_R_TYPE_ID(info) (((bfd_vma) (info) << 56) >> 56)
+#define ELF64_R_TYPE_INFO(data, type) (((bfd_vma) (data) << 8) \
+ + (bfd_vma) (type))
+
+#define DT_SPARC_REGISTER 0x70000001
+
+/*
+ * FIXME: NOT ABI -- GET RID OF THIS
+ * Defines the format used by the .plt. Currently defined values are
+ * 0 -- reserved to SI
+ * 1 -- absolute address in .got.plt
+ * 2 -- got-relative address in .got.plt
+ */
+
+#define DT_SPARC_PLTFMT 0x70000001
+
+#endif /* _ELF_SPARC_H */
diff --git a/include/elf/v850.h b/include/elf/v850.h
new file mode 100644
index 00000000000..d443b7fdc0d
--- /dev/null
+++ b/include/elf/v850.h
@@ -0,0 +1,111 @@
+/* V850 ELF support for BFD.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Created by Michael Meissner, Cygnus Support <meissner@cygnus.com>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds definitions specific to the MIPS ELF ABI. Note
+ that most of this is not actually implemented by BFD. */
+
+#ifndef _ELF_V850_H
+#define _ELF_V850_H
+
+/* Processor specific flags for the ELF header e_flags field. */
+
+/* Four bit V850 architecture field. */
+#define EF_V850_ARCH 0xf0000000
+
+/* v850 code. */
+#define E_V850_ARCH 0x00000000
+
+/* v850e code. */
+#define E_V850E_ARCH 0x10000000
+
+/* v850ea code. */
+#define E_V850EA_ARCH 0x20000000
+
+
+/* Flags for the st_other field */
+#define V850_OTHER_SDA 0x01 /* symbol had SDA relocations */
+#define V850_OTHER_ZDA 0x02 /* symbol had ZDA relocations */
+#define V850_OTHER_TDA 0x04 /* symbol had TDA relocations */
+#define V850_OTHER_TDA_BYTE 0x08 /* symbol had TDA byte relocations */
+#define V850_OTHER_ERROR 0x80 /* symbol had an error reported */
+
+/* V850 relocations */
+#include "elf/reloc-macros.h"
+
+START_RELOC_NUMBERS (v850_reloc_type)
+ RELOC_NUMBER (R_V850_NONE, 0)
+ RELOC_NUMBER (R_V850_9_PCREL, 1)
+ RELOC_NUMBER (R_V850_22_PCREL, 2)
+ RELOC_NUMBER (R_V850_HI16_S, 3)
+ RELOC_NUMBER (R_V850_HI16, 4)
+ RELOC_NUMBER (R_V850_LO16, 5)
+ RELOC_NUMBER (R_V850_32, 6)
+ RELOC_NUMBER (R_V850_16, 7)
+ RELOC_NUMBER (R_V850_8, 8)
+ RELOC_NUMBER( R_V850_SDA_16_16_OFFSET, 9) /* For ld.b, st.b, set1, clr1, not1, tst1, movea, movhi */
+ RELOC_NUMBER( R_V850_SDA_15_16_OFFSET, 10) /* For ld.w, ld.h, ld.hu, st.w, st.h */
+ RELOC_NUMBER( R_V850_ZDA_16_16_OFFSET, 11) /* For ld.b, st.b, set1, clr1, not1, tst1, movea, movhi */
+ RELOC_NUMBER( R_V850_ZDA_15_16_OFFSET, 12) /* For ld.w, ld.h, ld.hu, st.w, st.h */
+ RELOC_NUMBER( R_V850_TDA_6_8_OFFSET, 13) /* For sst.w, sld.w */
+ RELOC_NUMBER( R_V850_TDA_7_8_OFFSET, 14) /* For sst.h, sld.h */
+ RELOC_NUMBER( R_V850_TDA_7_7_OFFSET, 15) /* For sst.b, sld.b */
+ RELOC_NUMBER( R_V850_TDA_16_16_OFFSET, 16) /* For set1, clr1, not1, tst1, movea, movhi */
+/* CYGNUS LOCAL v850e */
+ RELOC_NUMBER( R_V850_TDA_4_5_OFFSET, 17) /* For sld.hu */
+ RELOC_NUMBER( R_V850_TDA_4_4_OFFSET, 18) /* For sld.bu */
+ RELOC_NUMBER( R_V850_SDA_16_16_SPLIT_OFFSET, 19) /* For ld.bu */
+ RELOC_NUMBER( R_V850_ZDA_16_16_SPLIT_OFFSET, 20) /* For ld.bu */
+ RELOC_NUMBER( R_V850_CALLT_6_7_OFFSET, 21) /* For callt */
+ RELOC_NUMBER( R_V850_CALLT_16_16_OFFSET, 22) /* For callt */
+/* END CYGNUS LOCAL */
+ RELOC_NUMBER (R_V850_GNU_VTINHERIT, 23)
+ RELOC_NUMBER (R_V850_GNU_VTENTRY, 24)
+
+ EMPTY_RELOC (R_V850_max)
+END_RELOC_NUMBERS
+
+
+/* Processor specific section indices. These sections do not actually
+ exist. Symbols with a st_shndx field corresponding to one of these
+ values have a special meaning. */
+
+/* Small data area common symbol. */
+#define SHN_V850_SCOMMON 0xff00
+
+/* Tiny data area common symbol. */
+#define SHN_V850_TCOMMON 0xff01
+
+/* Zero data area common symbol. */
+#define SHN_V850_ZCOMMON 0xff02
+
+
+/* Processor specific section types. */
+
+/* Section contains the .scommon data. */
+#define SHT_V850_SCOMMON 0x70000000
+
+/* Section contains the .scommon data. */
+#define SHT_V850_TCOMMON 0x70000001
+
+/* Section contains the .scommon data. */
+#define SHT_V850_ZCOMMON 0x70000002
+
+
+#endif /* _ELF_V850_H */
diff --git a/include/floatformat.h b/include/floatformat.h
new file mode 100644
index 00000000000..90daca21bcb
--- /dev/null
+++ b/include/floatformat.h
@@ -0,0 +1,111 @@
+/* IEEE floating point support declarations, for GDB, the GNU Debugger.
+ Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if !defined (FLOATFORMAT_H)
+#define FLOATFORMAT_H 1
+
+#include "ansidecl.h"
+
+/* A floatformat consists of a sign bit, an exponent and a mantissa. Once the
+ bytes are concatenated according to the byteorder flag, then each of those
+ fields is contiguous. We number the bits with 0 being the most significant
+ (i.e. BITS_BIG_ENDIAN type numbering), and specify which bits each field
+ contains with the *_start and *_len fields. */
+
+/* What is the order of the bytes. */
+
+enum floatformat_byteorders {
+
+ /* Standard little endian byte order.
+ EX: 1.2345678e10 => 00 00 80 c5 e0 fe 06 42 */
+
+ floatformat_little,
+
+ /* Standard big endian byte order.
+ EX: 1.2345678e10 => 42 06 fe e0 c5 80 00 00 */
+
+ floatformat_big,
+
+ /* Little endian byte order but big endian word order.
+ EX: 1.2345678e10 => e0 fe 06 42 00 00 80 c5 */
+
+ floatformat_littlebyte_bigword
+
+};
+
+enum floatformat_intbit { floatformat_intbit_yes, floatformat_intbit_no };
+
+struct floatformat
+{
+ enum floatformat_byteorders byteorder;
+ unsigned int totalsize; /* Total size of number in bits */
+
+ /* Sign bit is always one bit long. 1 means negative, 0 means positive. */
+ unsigned int sign_start;
+
+ unsigned int exp_start;
+ unsigned int exp_len;
+ /* Amount added to "true" exponent. 0x3fff for many IEEE extendeds. */
+ unsigned int exp_bias;
+ /* Exponent value which indicates NaN. This is the actual value stored in
+ the float, not adjusted by the exp_bias. This usually consists of all
+ one bits. */
+ unsigned int exp_nan;
+
+ unsigned int man_start;
+ unsigned int man_len;
+
+ /* Is the integer bit explicit or implicit? */
+ enum floatformat_intbit intbit;
+};
+
+/* floatformats for IEEE single and double, big and little endian. */
+
+extern const struct floatformat floatformat_ieee_single_big;
+extern const struct floatformat floatformat_ieee_single_little;
+extern const struct floatformat floatformat_ieee_double_big;
+extern const struct floatformat floatformat_ieee_double_little;
+
+/* floatformat for ARM IEEE double, little endian bytes and big endian words */
+
+extern const struct floatformat floatformat_ieee_double_littlebyte_bigword;
+
+/* floatformats for various extendeds. */
+
+extern const struct floatformat floatformat_i387_ext;
+extern const struct floatformat floatformat_m68881_ext;
+extern const struct floatformat floatformat_i960_ext;
+extern const struct floatformat floatformat_m88110_ext;
+extern const struct floatformat floatformat_arm_ext;
+
+/* Convert from FMT to a double.
+ FROM is the address of the extended float.
+ Store the double in *TO. */
+
+extern void
+floatformat_to_double PARAMS ((const struct floatformat *, char *, double *));
+
+/* The converse: convert the double *FROM to FMT
+ and store where TO points. */
+
+extern void
+floatformat_from_double PARAMS ((const struct floatformat *,
+ double *, char *));
+
+#endif /* defined (FLOATFORMAT_H) */
diff --git a/include/fnmatch.h b/include/fnmatch.h
new file mode 100644
index 00000000000..d5eb7000977
--- /dev/null
+++ b/include/fnmatch.h
@@ -0,0 +1,70 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef _FNMATCH_H
+
+#define _FNMATCH_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
+#undef __P
+#define __P(args) args
+#else /* Not C++ or ANSI C. */
+#undef __P
+#define __P(args) ()
+/* We can get away without defining `const' here only because in this file
+ it is used only inside the prototype for `fnmatch', which is elided in
+ non-ANSI C where `const' is problematical. */
+#endif /* C++ or ANSI C. */
+
+
+/* We #undef these before defining them because some losing systems
+ (HP-UX A.08.07 for example) define these in <unistd.h>. */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
+
+#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
+#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
+#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
+#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* Match STRING against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+extern int fnmatch __P ((const char *__pattern, const char *__string,
+ int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/include/fopen-bin.h b/include/fopen-bin.h
new file mode 100644
index 00000000000..b868f63d46d
--- /dev/null
+++ b/include/fopen-bin.h
@@ -0,0 +1,27 @@
+/* Macros for the 'type' part of an fopen, freopen or fdopen.
+
+ <Read|Write>[Update]<Binary file|text file>
+
+ This version is for "binary" systems, where text and binary files are
+ different. An example is Mess-Dose. Many Unix systems could also
+ cope with a "b" in the string, indicating binary files, but some reject this
+ (and thereby don't conform to ANSI C, but what else is new?).
+
+ This file is designed for inclusion by host-dependent .h files. No
+ user application should include it directly, since that would make
+ the application unable to be configured for both "same" and "binary"
+ variant systems. */
+
+#define FOPEN_RB "rb"
+#define FOPEN_WB "wb"
+#define FOPEN_AB "ab"
+#define FOPEN_RUB "r+b"
+#define FOPEN_WUB "w+b"
+#define FOPEN_AUB "a+b"
+
+#define FOPEN_RT "r"
+#define FOPEN_WT "w"
+#define FOPEN_AT "a"
+#define FOPEN_RUT "r+"
+#define FOPEN_WUT "w+"
+#define FOPEN_AUT "a+"
diff --git a/include/fopen-same.h b/include/fopen-same.h
new file mode 100644
index 00000000000..0f37529d33e
--- /dev/null
+++ b/include/fopen-same.h
@@ -0,0 +1,27 @@
+/* Macros for the 'type' part of an fopen, freopen or fdopen.
+
+ <Read|Write>[Update]<Binary file|text file>
+
+ This version is for "same" systems, where text and binary files are
+ the same. An example is Unix. Many Unix systems could also add a
+ "b" to the string, indicating binary files, but some reject this
+ (and thereby don't conform to ANSI C, but what else is new?).
+
+ This file is designed for inclusion by host-dependent .h files. No
+ user application should include it directly, since that would make
+ the application unable to be configured for both "same" and "binary"
+ variant systems. */
+
+#define FOPEN_RB "r"
+#define FOPEN_WB "w"
+#define FOPEN_AB "a"
+#define FOPEN_RUB "r+"
+#define FOPEN_WUB "w+"
+#define FOPEN_AUB "a+"
+
+#define FOPEN_RT "r"
+#define FOPEN_WT "w"
+#define FOPEN_AT "a"
+#define FOPEN_RUT "r+"
+#define FOPEN_WUT "w+"
+#define FOPEN_AUT "a+"
diff --git a/include/fopen-vms.h b/include/fopen-vms.h
new file mode 100644
index 00000000000..da76b7fb59c
--- /dev/null
+++ b/include/fopen-vms.h
@@ -0,0 +1,24 @@
+/* Macros for the 'type' part of an fopen, freopen or fdopen.
+
+ <Read|Write>[Update]<Binary file|text file>
+
+ This version is for VMS systems, where text and binary files are
+ different.
+ This file is designed for inclusion by host-dependent .h files. No
+ user application should include it directly, since that would make
+ the application unable to be configured for both "same" and "binary"
+ variant systems. */
+
+#define FOPEN_RB "rb","rfm=var"
+#define FOPEN_WB "wb","rfm=var"
+#define FOPEN_AB "ab","rfm=var"
+#define FOPEN_RUB "r+b","rfm=var"
+#define FOPEN_WUB "w+b","rfm=var"
+#define FOPEN_AUB "a+b","rfm=var"
+
+#define FOPEN_RT "r"
+#define FOPEN_WT "w"
+#define FOPEN_AT "a"
+#define FOPEN_RUT "r+"
+#define FOPEN_WUT "w+"
+#define FOPEN_AUT "a+"
diff --git a/include/gdbm.h b/include/gdbm.h
new file mode 100644
index 00000000000..3ebc26d198a
--- /dev/null
+++ b/include/gdbm.h
@@ -0,0 +1,91 @@
+/* GNU DBM - DataBase Manager include file
+ Copyright 1989, 1991 Free Software Foundation, Inc.
+ Written by Philip A. Nelson.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* You may contact the author by:
+ e-mail: phil@wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department
+ Western Washington University
+ Bellingham, WA 98226
+ phone: (206) 676-3035
+
+*************************************************************************/
+
+/* Parameters to gdbm_open for READERS, WRITERS, and WRITERS who
+ can create the database. */
+#define GDBM_READER 0
+#define GDBM_WRITER 1
+#define GDBM_WRCREAT 2
+#define GDBM_NEWDB 3
+
+/* Parameters to gdbm_store for simple insertion or replacement. */
+#define GDBM_INSERT 0
+#define GDBM_REPLACE 1
+
+
+/* The data and key structure. This structure is defined for compatibility. */
+typedef struct {
+ char *dptr;
+ int dsize;
+ } datum;
+
+
+/* The file information header. This is good enough for most applications. */
+typedef struct {int dummy[10];} *GDBM_FILE;
+
+
+/* These are the routines! */
+
+extern GDBM_FILE gdbm_open ();
+
+extern void gdbm_close ();
+
+extern datum gdbm_fetch ();
+
+extern int gdbm_store ();
+
+extern int gdbm_delete ();
+
+extern datum gdbm_firstkey ();
+
+extern datum gdbm_nextkey ();
+
+extern int gdbm_reorganize ();
+
+
+/* gdbm sends back the following error codes in the variable gdbm_errno. */
+typedef enum { NO_ERROR,
+ MALLOC_ERROR,
+ BLOCK_SIZE_ERROR,
+ FILE_OPEN_ERROR,
+ FILE_WRITE_ERROR,
+ FILE_SEEK_ERROR,
+ FILE_READ_ERROR,
+ BAD_MAGIC_NUMBER,
+ EMPTY_DATABASE,
+ CANT_BE_READER,
+ CANT_BE_WRITER,
+ READER_CANT_RECOVER,
+ READER_CANT_DELETE,
+ READER_CANT_STORE,
+ READER_CANT_REORGANIZE,
+ UNKNOWN_UPDATE,
+ ITEM_NOT_FOUND,
+ REORGANIZE_FAILED,
+ CANNOT_REPLACE}
+ gdbm_error;
diff --git a/include/getopt.h b/include/getopt.h
new file mode 100644
index 00000000000..fb30719a860
--- /dev/null
+++ b/include/getopt.h
@@ -0,0 +1,133 @@
+/* Declarations for getopt.
+ Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+ const char *name;
+#else
+ char *name;
+#endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* getopt.h */
diff --git a/include/hp-symtab.h b/include/hp-symtab.h
new file mode 100644
index 00000000000..fff56688ed2
--- /dev/null
+++ b/include/hp-symtab.h
@@ -0,0 +1,1871 @@
+/* Definitions and structures for reading debug symbols from the
+ native HP C compiler.
+
+ Written by the Center for Software Science at the University of Utah
+ and by Cygnus Support.
+
+ Copyright 1994 Free Software Foundation, Inc.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef HP_SYMTAB_INCLUDED
+#define HP_SYMTAB_INCLUDED
+
+/* General information:
+
+ This header file defines and describes only the data structures
+ necessary to read debug symbols produced by the HP C compiler,
+ HP ANSI C++ compiler, and HP FORTRAN 90 compiler using the
+ SOM object file format.
+ (For a full description of the debug format, ftp hpux-symtab.h from
+ jaguar.cs.utah.edu:/dist).
+
+ Additional notes (Rich Title)
+ This file is a reverse-engineered version of a file called
+ "symtab.h" which exists internal to HP's Computer Languages Organization
+ in /CLO/Components/DDE/obj/som/symtab.h. Because HP's version of
+ the file is copyrighted and not distributed, it is necessary for
+ GDB to use the reverse-engineered version that follows.
+ Work was done by Cygnus to reverse-engineer the C subset of symtab.h.
+ The WDB project has extended this to also contain the C++
+ symbol definitions, the F90 symbol definitions,
+ and the DOC (debugging-optimized-code) symbol definitions.
+ In some cases (the C++ symbol definitions)
+ I have added internal documentation here that
+ goes beyond what is supplied in HP's symtab.h. If we someday
+ unify these files again, the extra comments should be merged back
+ into HP's symtab.h.
+
+ -------------------------------------------------------------------
+
+ Debug symbols are contained entirely within an unloadable space called
+ $DEBUG$. $DEBUG$ contains several subspaces which group related
+ debug symbols.
+
+ $GNTT$ contains information for global variables, types and contants.
+
+ $LNTT$ contains information for procedures (including nesting), scoping
+ information, local variables, types, and constants.
+
+ $SLT$ contains source line information so that code addresses may be
+ mapped to source lines.
+
+ $VT$ contains various strings and constants for named objects (variables,
+ typedefs, functions, etc). Strings are stored as null-terminated character
+ lists. Constants always begin on word boundaries. The first byte of
+ the VT must be zero (a null string).
+
+ $XT$ is not currently used by GDB.
+
+ Many structures within the subspaces point to other structures within
+ the same subspace, or to structures within a different subspace. These
+ pointers are represented as a structure index from the beginning of
+ the appropriate subspace. */
+
+/* Used to describe where a constant is stored. */
+enum location_type
+{
+ LOCATION_IMMEDIATE,
+ LOCATION_PTR,
+ LOCATION_VT,
+};
+
+/* Languages supported by this debug format. Within the data structures
+ this type is limited to 4 bits for a maximum of 16 languages. */
+enum hp_language
+{
+ HP_LANGUAGE_UNKNOWN,
+ HP_LANGUAGE_C,
+ HP_LANGUAGE_F77,
+ HP_LANGUAGE_PASCAL,
+ HP_LANGUAGE_MODCAL,
+ HP_LANGUAGE_COBOL,
+ HP_LANGUAGE_BASIC,
+ HP_LANGUAGE_ADA,
+ HP_LANGUAGE_CPLUSPLUS,
+ HP_LANGUAGE_DMPASCAL
+};
+
+
+/* Basic data types available in this debug format. Within the data
+ structures this type is limited to 5 bits for a maximum of 32 basic
+ data types. */
+enum hp_type
+{
+ HP_TYPE_UNDEFINED, /* 0 */
+ HP_TYPE_BOOLEAN, /* 1 */
+ HP_TYPE_CHAR, /* 2 */
+ HP_TYPE_INT, /* 3 */
+ HP_TYPE_UNSIGNED_INT, /* 4 */
+ HP_TYPE_REAL, /* 5 */
+ HP_TYPE_COMPLEX, /* 6 */
+ HP_TYPE_STRING200, /* 7 */
+ HP_TYPE_LONGSTRING200, /* 8 */
+ HP_TYPE_TEXT, /* 9 */
+ HP_TYPE_FLABEL, /* 10 */
+ HP_TYPE_FTN_STRING_SPEC, /* 11 */
+ HP_TYPE_MOD_STRING_SPEC, /* 12 */
+ HP_TYPE_PACKED_DECIMAL, /* 13 */
+ HP_TYPE_REAL_3000, /* 14 */
+ HP_TYPE_MOD_STRING_3000, /* 15 */
+ HP_TYPE_ANYPOINTER, /* 16 */
+ HP_TYPE_GLOBAL_ANYPOINTER, /* 17 */
+ HP_TYPE_LOCAL_ANYPOINTER, /* 18 */
+ HP_TYPE_COMPLEXS3000, /* 19 */
+ HP_TYPE_FTN_STRING_S300_COMPAT, /* 20 */
+ HP_TYPE_FTN_STRING_VAX_COMPAT, /* 21 */
+ HP_TYPE_BOOLEAN_S300_COMPAT, /* 22 */
+ HP_TYPE_BOOLEAN_VAX_COMPAT, /* 23 */
+ HP_TYPE_WIDE_CHAR, /* 24 */
+ HP_TYPE_LONG, /* 25 */
+ HP_TYPE_UNSIGNED_LONG, /* 26 */
+ HP_TYPE_DOUBLE, /* 27 */
+ HP_TYPE_TEMPLATE_ARG, /* 28 */
+ HP_TYPE_VOID /* 29 */
+};
+
+/* An immediate name and type table entry.
+
+ extension and immediate will always be one.
+ global will always be zero.
+ hp_type is the basic type this entry describes.
+ bitlength is the length in bits for the basic type. */
+struct dnttp_immediate
+{
+ unsigned int extension: 1;
+ unsigned int immediate: 1;
+ unsigned int global: 1;
+ unsigned int type: 5;
+ unsigned int bitlength: 24;
+};
+
+/* A nonimmediate name and type table entry.
+
+ extension will always be one.
+ immediate will always be zero.
+ if global is zero, this entry points into the LNTT
+ if global is one, this entry points into the GNTT
+ index is the index within the GNTT or LNTT for this entry. */
+struct dnttp_nonimmediate
+{
+ unsigned int extension: 1;
+ unsigned int immediate: 1;
+ unsigned int global: 1;
+ unsigned int index: 29;
+};
+
+/* A pointer to an entry in the GNTT and LNTT tables. It has two
+ forms depending on the type being described.
+
+ The immediate form is used for simple entries and is one
+ word.
+
+ The nonimmediate form is used for complex entries and contains
+ an index into the LNTT or GNTT which describes the entire type.
+
+ If a dnttpointer is -1, then it is a NIL entry. */
+
+#define DNTTNIL (-1)
+typedef union dnttpointer
+{
+ struct dnttp_immediate dntti;
+ struct dnttp_nonimmediate dnttp;
+ int word;
+} dnttpointer;
+
+/* An index into the source line table. As with dnttpointers, a sltpointer
+ of -1 indicates a NIL entry. */
+#define SLTNIL (-1)
+typedef int sltpointer;
+
+/* Index into DOC (= "Debugging Optimized Code") line table */
+#define LTNIL (-1)
+typedef int ltpointer;
+
+/* Index into context table */
+#define CTXTNIL (-1)
+typedef int ctxtpointer;
+
+/* Unsigned byte offset into the VT. */
+typedef unsigned int vtpointer;
+
+/* A DNTT entry (used within the GNTT and LNTT).
+
+ DNTT entries are variable sized objects, but are always a multiple
+ of 3 words (we call each group of 3 words a "block").
+
+ The first bit in each block is an extension bit. This bit is zero
+ for the first block of a DNTT entry. If the entry requires more
+ than one block, then this bit is set to one in all blocks after
+ the first one. */
+
+/* Each DNTT entry describes a particular debug symbol (beginning of
+ a source file, a function, variables, structures, etc.
+
+ The type of the DNTT entry is stored in the "kind" field within the
+ DNTT entry itself. */
+
+enum dntt_entry_type
+{
+ DNTT_TYPE_NIL = -1,
+ DNTT_TYPE_SRCFILE,
+ DNTT_TYPE_MODULE,
+ DNTT_TYPE_FUNCTION,
+ DNTT_TYPE_ENTRY,
+ DNTT_TYPE_BEGIN,
+ DNTT_TYPE_END,
+ DNTT_TYPE_IMPORT,
+ DNTT_TYPE_LABEL,
+ DNTT_TYPE_FPARAM,
+ DNTT_TYPE_SVAR,
+ DNTT_TYPE_DVAR,
+ DNTT_TYPE_HOLE1,
+ DNTT_TYPE_CONST,
+ DNTT_TYPE_TYPEDEF,
+ DNTT_TYPE_TAGDEF,
+ DNTT_TYPE_POINTER,
+ DNTT_TYPE_ENUM,
+ DNTT_TYPE_MEMENUM,
+ DNTT_TYPE_SET,
+ DNTT_TYPE_SUBRANGE,
+ DNTT_TYPE_ARRAY,
+ DNTT_TYPE_STRUCT,
+ DNTT_TYPE_UNION,
+ DNTT_TYPE_FIELD,
+ DNTT_TYPE_VARIANT,
+ DNTT_TYPE_FILE,
+ DNTT_TYPE_FUNCTYPE,
+ DNTT_TYPE_WITH,
+ DNTT_TYPE_COMMON,
+ DNTT_TYPE_COBSTRUCT,
+ DNTT_TYPE_XREF,
+ DNTT_TYPE_SA,
+ DNTT_TYPE_MACRO,
+ DNTT_TYPE_BLOCKDATA,
+ DNTT_TYPE_CLASS_SCOPE,
+ DNTT_TYPE_REFERENCE,
+ DNTT_TYPE_PTRMEM,
+ DNTT_TYPE_PTRMEMFUNC,
+ DNTT_TYPE_CLASS,
+ DNTT_TYPE_GENFIELD,
+ DNTT_TYPE_VFUNC,
+ DNTT_TYPE_MEMACCESS,
+ DNTT_TYPE_INHERITANCE,
+ DNTT_TYPE_FRIEND_CLASS,
+ DNTT_TYPE_FRIEND_FUNC,
+ DNTT_TYPE_MODIFIER,
+ DNTT_TYPE_OBJECT_ID,
+ DNTT_TYPE_MEMFUNC,
+ DNTT_TYPE_TEMPLATE,
+ DNTT_TYPE_TEMPLATE_ARG,
+ DNTT_TYPE_FUNC_TEMPLATE,
+ DNTT_TYPE_LINK,
+ DNTT_TYPE_DYN_ARRAY_DESC,
+ DNTT_TYPE_DESC_SUBRANGE,
+ DNTT_TYPE_BEGIN_EXT,
+ DNTT_TYPE_INLN,
+ DNTT_TYPE_INLN_LIST,
+ DNTT_TYPE_ALIAS,
+ DNTT_TYPE_DOC_FUNCTION,
+ DNTT_TYPE_DOC_MEMFUNC,
+ DNTT_TYPE_MAX
+};
+
+/* DNTT_TYPE_SRCFILE:
+
+ One DNTT_TYPE_SRCFILE symbol is output for the start of each source
+ file and at the begin and end of an included file. A DNTT_TYPE_SRCFILE
+ entry is also output before each DNTT_TYPE_FUNC symbol so that debuggers
+ can determine what file a function was defined in.
+
+ LANGUAGE describes the source file's language.
+
+ NAME points to an VT entry providing the source file's name.
+
+ Note the name used for DNTT_TYPE_SRCFILE entries are exactly as seen
+ by the compiler (ie they may be relative or absolute). C include files
+ via <> inclusion must use absolute paths.
+
+ ADDRESS points to an SLT entry from which line number and code locations
+ may be determined. */
+
+struct dntt_type_srcfile
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10; /* DNTT_TYPE_SRCFILE */
+ unsigned int language: 4;
+ unsigned int unused: 17;
+ vtpointer name;
+ sltpointer address;
+};
+
+/* DNTT_TYPE_MODULE:
+
+ A DNTT_TYPE_MODULE symbol is emitted for the start of a pascal
+ module or C source file. A module indicates a compilation unit
+ for name-scoping purposes; in that regard there should be
+ a 1-1 correspondence between GDB "symtab"'s and MODULE symbol records.
+
+ Each DNTT_TYPE_MODULE must have an associated DNTT_TYPE_END symbol.
+
+ NAME points to a VT entry providing the module's name. Note C
+ source files are considered nameless modules.
+
+ ALIAS point to a VT entry providing a secondary name.
+
+ ADDRESS points to an SLT entry from which line number and code locations
+ may be determined. */
+
+struct dntt_type_module
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10; /* DNTT_TYPE_MODULE */
+ unsigned int unused: 21;
+ vtpointer name;
+ vtpointer alias;
+ dnttpointer unused2;
+ sltpointer address;
+};
+
+/* DNTT_TYPE_FUNCTION,
+ DNTT_TYPE_ENTRY,
+ DNTT_TYPE_BLOCKDATA,
+ DNTT_TYPE_MEMFUNC:
+
+ A DNTT_TYPE_FUNCTION symbol is emitted for each function definition;
+ a DNTT_TYPE_ENTRY symbols is used for secondary entry points. Both
+ symbols used the dntt_type_function structure.
+ A DNTT_TYPE_BLOCKDATA symbol is emitted ...?
+ A DNTT_TYPE_MEMFUNC symbol is emitted for inlined member functions (C++).
+
+ Each of DNTT_TYPE_FUNCTION must have a matching DNTT_TYPE_END.
+
+ GLOBAL is nonzero if the function has global scope.
+
+ LANGUAGE describes the function's source language.
+
+ OPT_LEVEL describes the optimization level the function was compiled
+ with.
+
+ VARARGS is nonzero if the function uses varargs.
+
+ NAME points to a VT entry providing the function's name.
+
+ ALIAS points to a VT entry providing a secondary name for the function.
+
+ FIRSTPARAM points to a LNTT entry which describes the parameter list.
+
+ ADDRESS points to an SLT entry from which line number and code locations
+ may be determined.
+
+ ENTRYADDR is the memory address corresponding the the function's entry point
+
+ RETVAL points to a LNTT entry describing the function's return value.
+
+ LOWADDR is the lowest memory address associated with this function.
+
+ HIADDR is the highest memory address associated with this function. */
+
+struct dntt_type_function
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10; /* DNTT_TYPE_FUNCTION,
+ DNTT_TYPE_ENTRY,
+ DNTT_TYPE_BLOCKDATA
+ or DNTT_TYPE_MEMFUNC */
+ unsigned int global: 1;
+ unsigned int language: 4;
+ unsigned int nest_level: 5;
+ unsigned int opt_level: 2;
+ unsigned int varargs: 1;
+ unsigned int lang_info: 4;
+ unsigned int inlined: 1;
+ unsigned int localalloc: 1;
+ unsigned int expansion: 1;
+ unsigned int unused: 1;
+ vtpointer name;
+ vtpointer alias;
+ dnttpointer firstparam;
+ sltpointer address;
+ CORE_ADDR entryaddr;
+ dnttpointer retval;
+ CORE_ADDR lowaddr;
+ CORE_ADDR hiaddr;
+};
+
+/* DNTT_TYPE_BEGIN:
+
+ A DNTT_TYPE_BEGIN symbol is emitted to begin a new nested scope.
+ Every DNTT_TYPE_BEGIN symbol must have a matching DNTT_TYPE_END symbol.
+
+ CLASSFLAG is nonzero if this is the beginning of a c++ class definition.
+
+ ADDRESS points to an SLT entry from which line number and code locations
+ may be determined. */
+
+struct dntt_type_begin
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int classflag: 1;
+ unsigned int unused: 20;
+ sltpointer address;
+};
+
+/* DNTT_TYPE_END:
+
+ A DNTT_TYPE_END symbol is emitted when closing a scope started by
+ a DNTT_TYPE_MODULE, DNTT_TYPE_FUNCTION, DNTT_TYPE_WITH,
+ DNTT_TYPE_COMMON, DNTT_TYPE_BEGIN, and DNTT_TYPE_CLASS_SCOPE symbols.
+
+ ENDKIND describes what type of scope the DNTT_TYPE_END is closing
+ (one of the above 6 kinds).
+
+ CLASSFLAG is nonzero if this is the end of a c++ class definition.
+
+ ADDRESS points to an SLT entry from which line number and code locations
+ may be determined.
+
+ BEGINSCOPE points to the LNTT entry which opened the scope. */
+
+struct dntt_type_end
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int endkind: 10;
+ unsigned int classflag: 1;
+ unsigned int unused: 10;
+ sltpointer address;
+ dnttpointer beginscope;
+};
+
+/* DNTT_TYPE_IMPORT is unused by GDB. */
+/* DNTT_TYPE_LABEL is unused by GDB. */
+
+/* DNTT_TYPE_FPARAM:
+
+ A DNTT_TYPE_FPARAM symbol is emitted for a function argument. When
+ chained together the symbols represent an argument list for a function.
+
+ REGPARAM is nonzero if this parameter was passed in a register.
+
+ INDIRECT is nonzero if this parameter is a pointer to the parameter
+ (pass by reference or pass by value for large items).
+
+ LONGADDR is nonzero if the parameter is a 64bit pointer.
+
+ NAME is a pointer into the VT for the parameter's name.
+
+ LOCATION describes where the parameter is stored. Depending on the
+ parameter type LOCATION could be a register number, or an offset
+ from the stack pointer.
+
+ TYPE points to a NTT entry describing the type of this parameter.
+
+ NEXTPARAM points to the LNTT entry describing the next parameter. */
+
+struct dntt_type_fparam
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int regparam: 1;
+ unsigned int indirect: 1;
+ unsigned int longaddr: 1;
+ unsigned int copyparam: 1;
+ unsigned int dflt: 1;
+ unsigned int unused: 16;
+ vtpointer name;
+ int location;
+ dnttpointer type;
+ dnttpointer nextparam;
+ int misc;
+};
+
+/* DNTT_TYPE_SVAR:
+
+ A DNTT_TYPE_SVAR is emitted to describe a variable in static storage.
+
+ GLOBAL is nonzero if the variable has global scope.
+
+ INDIRECT is nonzero if the variable is a pointer to an object.
+
+ LONGADDR is nonzero if the variable is in long pointer space.
+
+ STATICMEM is nonzero if the variable is a member of a class.
+
+ A_UNION is nonzero if the variable is an anonymous union member.
+
+ NAME is a pointer into the VT for the variable's name.
+
+ LOCATION provides the memory address for the variable.
+
+ TYPE is a pointer into either the GNTT or LNTT which describes
+ the type of this variable. */
+
+struct dntt_type_svar
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int global: 1;
+ unsigned int indirect: 1;
+ unsigned int longaddr: 1;
+ unsigned int staticmem: 1;
+ unsigned int a_union: 1;
+ unsigned int unused1: 1;
+ unsigned int thread_specific: 1;
+ unsigned int unused2: 14;
+ vtpointer name;
+ CORE_ADDR location;
+ dnttpointer type;
+ unsigned int offset;
+ unsigned int displacement;
+};
+
+/* DNTT_TYPE_DVAR:
+
+ A DNTT_TYPE_DVAR is emitted to describe automatic variables and variables
+ held in registers.
+
+ GLOBAL is nonzero if the variable has global scope.
+
+ INDIRECT is nonzero if the variable is a pointer to an object.
+
+ REGVAR is nonzero if the variable is in a register.
+
+ A_UNION is nonzero if the variable is an anonymous union member.
+
+ NAME is a pointer into the VT for the variable's name.
+
+ LOCATION provides the memory address or register number for the variable.
+
+ TYPE is a pointer into either the GNTT or LNTT which describes
+ the type of this variable. */
+
+struct dntt_type_dvar
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int global: 1;
+ unsigned int indirect: 1;
+ unsigned int regvar: 1;
+ unsigned int a_union: 1;
+ unsigned int unused: 17;
+ vtpointer name;
+ int location;
+ dnttpointer type;
+ unsigned int offset;
+};
+
+/* DNTT_TYPE_CONST:
+
+ A DNTT_TYPE_CONST symbol is emitted for program constants.
+
+ GLOBAL is nonzero if the constant has global scope.
+
+ INDIRECT is nonzero if the constant is a pointer to an object.
+
+ LOCATION_TYPE describes where to find the constant's value
+ (in the VT, memory, or embedded in an instruction).
+
+ CLASSMEM is nonzero if the constant is a member of a class.
+
+ NAME is a pointer into the VT for the constant's name.
+
+ LOCATION provides the memory address, register number or pointer
+ into the VT for the constant's value.
+
+ TYPE is a pointer into either the GNTT or LNTT which describes
+ the type of this variable. */
+
+struct dntt_type_const
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int global: 1;
+ unsigned int indirect: 1;
+ unsigned int: 3;
+ unsigned int classmem: 1;
+ unsigned int unused: 15;
+ vtpointer name;
+ CORE_ADDR location;
+ dnttpointer type;
+ unsigned int offset;
+ unsigned int displacement;
+};
+
+/* DNTT_TYPE_TYPEDEF and DNTT_TYPE_TAGDEF:
+
+ The same structure is used to describe typedefs and tagdefs.
+
+ DNTT_TYPE_TYPEDEFS are associated with C "typedefs".
+
+ DNTT_TYPE_TAGDEFs are associated with C "struct", "union", and "enum"
+ tags, which may have the same name as a typedef in the same scope.
+ Also they are associated with C++ "class" tags, which implicitly have
+ the same name as the class type.
+
+ GLOBAL is nonzero if the typedef/tagdef has global scope.
+
+ TYPEINFO is used to determine if full type information is available
+ for a tag. (usually 1, but can be zero for opaque types in C).
+
+ NAME is a pointer into the VT for the constant's name.
+
+ TYPE points to the underlying type for the typedef/tagdef in the
+ GNTT or LNTT. */
+
+struct dntt_type_type
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10; /* DNTT_TYPE_TYPEDEF or
+ DNTT_TYPE_TAGDEF
+ */
+ unsigned int global: 1;
+ unsigned int typeinfo: 1;
+ unsigned int unused: 19;
+ vtpointer name;
+ dnttpointer type; /* Underlying type, which for TAGDEF's may be
+ * DNTT_TYPE_STRUCT, DNTT_TYPE_UNION,
+ * DNTT_TYPE_ENUM, or DNTT_TYPE_CLASS.
+ * For TYPEDEF's other underlying types
+ * are also possible.
+ */
+};
+
+/* DNTT_TYPE_POINTER:
+
+ Used to describe a pointer to an underlying type.
+
+ POINTSTO is a pointer into the GNTT or LNTT for the type which this
+ pointer points to.
+
+ BITLENGTH is the length of the pointer (not the underlying type). */
+
+struct dntt_type_pointer
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int unused: 21;
+ dnttpointer pointsto;
+ unsigned int bitlength;
+};
+
+
+/* DNTT_TYPE_ENUM:
+
+ Used to describe enumerated types.
+
+ FIRSTMEM is a pointer to a DNTT_TYPE_MEMENUM in the GNTT/LNTT which
+ describes the first member (and contains a pointer to the chain of
+ members).
+
+ BITLENGTH is the number of bits used to hold the values of the enum's
+ members. */
+
+struct dntt_type_enum
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int unused: 21;
+ dnttpointer firstmem;
+ unsigned int bitlength;
+};
+
+/* DNTT_TYPE_MEMENUM
+
+ Used to describe members of an enumerated type.
+
+ CLASSMEM is nonzero if this member is part of a class.
+
+ NAME points into the VT for the name of this member.
+
+ VALUE is the value of this enumeration member.
+
+ NEXTMEM points to the next DNTT_TYPE_MEMENUM in the chain. */
+
+struct dntt_type_memenum
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int classmem: 1;
+ unsigned int unused: 20;
+ vtpointer name;
+ unsigned int value;
+ dnttpointer nextmem;
+};
+
+/* DNTT_TYPE_SET
+
+ Used to describe PASCAL "set" type.
+
+ DECLARATION describes the bitpacking of the set.
+
+ SUBTYPE points to a DNTT entry describing the type of the members.
+
+ BITLENGTH is the size of the set. */
+
+struct dntt_type_set
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int declaration: 2;
+ unsigned int unused: 19;
+ dnttpointer subtype;
+ unsigned int bitlength;
+};
+
+/* DNTT_TYPE_SUBRANGE
+
+ Used to describe subrange type.
+
+ DYN_LOW describes the lower bound of the subrange:
+
+ 00 for a constant lower bound (found in LOWBOUND).
+
+ 01 for a dynamic lower bound with the lower bound found in the the
+ memory address pointed to by LOWBOUND.
+
+ 10 for a dynamic lower bound described by an variable found in the
+ DNTT/LNTT (LOWBOUND would be a pointer into the DNTT/LNTT).
+
+ DYN_HIGH is similar to DYN_LOW, except it describes the upper bound.
+
+ SUBTYPE points to the type of the subrange.
+
+ BITLENGTH is the length in bits needed to describe the subrange's
+ values. */
+
+struct dntt_type_subrange
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int dyn_low: 2;
+ unsigned int dyn_high: 2;
+ unsigned int unused: 17;
+ int lowbound;
+ int highbound;
+ dnttpointer subtype;
+ unsigned int bitlength;
+};
+
+/* DNTT_TYPE_ARRAY
+
+ Used to describe an array type.
+
+ DECLARATION describes the bit packing used in the array.
+
+ ARRAYISBYTES is nonzero if the field in arraylength describes the
+ length in bytes rather than in bits. A value of zero is used to
+ describe an array with size 2**32.
+
+ ELEMISBYTES is nonzero if the length if each element in the array
+ is describes in bytes rather than bits. A value of zero is used
+ to an element with size 2**32.
+
+ ELEMORDER is nonzero if the elements are indexed in increasing order.
+
+ JUSTIFIED if the elements are left justified to index zero.
+
+ ARRAYLENGTH is the length of the array.
+
+ INDEXTYPE is a DNTT pointer to the type used to index the array.
+
+ ELEMTYPE is a DNTT pointer to the type for the array elements.
+
+ ELEMLENGTH is the length of each element in the array (including
+ any padding).
+
+ Multi-dimensional arrays are represented by ELEMTYPE pointing to
+ another DNTT_TYPE_ARRAY. */
+
+struct dntt_type_array
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int declaration: 2;
+ unsigned int dyn_low: 2;
+ unsigned int dyn_high: 2;
+ unsigned int arrayisbytes: 1;
+ unsigned int elemisbytes: 1;
+ unsigned int elemorder: 1;
+ unsigned int justified: 1;
+ unsigned int unused: 11;
+ unsigned int arraylength;
+ dnttpointer indextype;
+ dnttpointer elemtype;
+ unsigned int elemlength;
+};
+
+/* DNTT_TYPE_STRUCT
+
+ DNTT_TYPE_STRUCT is used to describe a C structure.
+
+ DECLARATION describes the bitpacking used.
+
+ FIRSTFIELD is a DNTT pointer to the first field of the structure
+ (each field contains a pointer to the next field, walk the list
+ to access all fields of the structure).
+
+ VARTAGFIELD and VARLIST are used for Pascal variant records.
+
+ BITLENGTH is the size of the structure in bits. */
+
+struct dntt_type_struct
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int declaration: 2;
+ unsigned int unused: 19;
+ dnttpointer firstfield;
+ dnttpointer vartagfield;
+ dnttpointer varlist;
+ unsigned int bitlength;
+};
+
+/* DNTT_TYPE_UNION
+
+ DNTT_TYPE_UNION is used to describe a C union.
+
+ FIRSTFIELD is a DNTT pointer to the beginning of the field chain.
+
+ BITLENGTH is the size of the union in bits. */
+
+struct dntt_type_union
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int unused: 21;
+ dnttpointer firstfield;
+ unsigned int bitlength;
+};
+
+/* DNTT_TYPE_FIELD
+
+ DNTT_TYPE_FIELD describes one field in a structure or union
+ or C++ class.
+
+ VISIBILITY is used to describe the visibility of the field
+ (for c++. public = 0, protected = 1, private = 2).
+
+ A_UNION is nonzero if this field is a member of an anonymous union.
+
+ STATICMEM is nonzero if this field is a static member of a template.
+
+ NAME is a pointer into the VT for the name of the field.
+
+ BITOFFSET gives the offset of this field in bits from the beginning
+ of the structure or union this field is a member of.
+
+ TYPE is a DNTT pointer to the type describing this field.
+
+ BITLENGTH is the size of the entry in bits.
+
+ NEXTFIELD is a DNTT pointer to the next field in the chain. */
+
+struct dntt_type_field
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int visibility: 2;
+ unsigned int a_union: 1;
+ unsigned int staticmem: 1;
+ unsigned int unused: 17;
+ vtpointer name;
+ unsigned int bitoffset;
+ dnttpointer type;
+ unsigned int bitlength;
+ dnttpointer nextfield;
+};
+
+/* DNTT_TYPE_VARIANT is unused by GDB. */
+/* DNTT_TYPE_FILE is unused by GDB. */
+
+/* DNTT_TYPE_FUNCTYPE
+
+ I think this is used to describe a function type (e.g., would
+ be emitted as part of a function-pointer description).
+
+ VARARGS is nonzero if this function uses varargs.
+
+ FIRSTPARAM is a DNTT pointer to the first entry in the parameter
+ chain.
+
+ RETVAL is a DNTT pointer to the type of the return value. */
+
+struct dntt_type_functype
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int varargs: 1;
+ unsigned int info: 4;
+ unsigned int unused: 16;
+ unsigned int bitlength;
+ dnttpointer firstparam;
+ dnttpointer retval;
+};
+
+/* DNTT_TYPE_WITH is emitted by C++ to indicate "with" scoping semantics.
+ (Probably also emitted by PASCAL to support "with"...).
+
+ C++ example: Say "memfunc" is a method of class "c", and say
+ "m" is a data member of class "c". Then from within "memfunc",
+ it is legal to reference "m" directly (e.g. you don't have to
+ say "this->m". The symbol table indicates
+ this by emitting a DNTT_TYPE_WITH symbol within the function "memfunc",
+ pointing to the type symbol for class "c".
+
+ In GDB, this symbol record is unnecessary,
+ because GDB's symbol lookup algorithm
+ infers the "with" semantics when it sees a "this" argument to the member
+ function. So GDB can safely ignore the DNTT_TYPE_WITH record.
+
+ A DNTT_TYPE_WITH has a matching DNTT_TYPE_END symbol
+ */
+
+struct dntt_type_with {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_WITH */
+ unsigned int addrtype: 2; /* 0 => STATTYPE */
+ /* 1 => DYNTYPE */
+ /* 2 => REGTYPE */
+ unsigned int indirect: 1; /* 1 => pointer to object */
+ unsigned int longaddr: 1; /* 1 => in long pointer space */
+ unsigned int nestlevel: 6; /* # of nesting levels back */
+ unsigned int doc_ranges: 1; /* 1 => location is range list */
+ unsigned int unused: 10;
+ long location; /* where stored (allocated) */
+ sltpointer address;
+ dnttpointer type; /* type of with expression */
+ vtpointer name; /* name of with expression */
+ unsigned long offset; /* byte offset from location */
+};
+
+/* DNTT_TYPE_COMMON is unsupported by GDB. */
+/* A DNTT_TYPE_COMMON symbol must have a matching DNTT_TYPE_END symbol */
+
+/* DNTT_TYPE_COBSTRUCT is unsupported by GDB. */
+/* DNTT_TYPE_XREF is unsupported by GDB. */
+/* DNTT_TYPE_SA is unsupported by GDB. */
+/* DNTT_TYPE_MACRO is unsupported by GDB */
+
+/* DNTT_TYPE_BLOCKDATA has the same structure as DNTT_TYPE_FUNCTION */
+
+/* The following are the C++ specific SOM records */
+
+/* The purpose of the DNTT_TYPE_CLASS_SCOPE is to bracket C++ methods
+ and indicate the method name belongs in the "class scope" rather
+ than in the module they are being defined in. For example:
+
+ class c {
+ ...
+ void memfunc(); // member function
+ };
+
+ void c::memfunc() // definition of class c's "memfunc"
+ {
+ ...
+ }
+
+ main()
+ {
+ ...
+ }
+
+ In the above, the name "memfunc" is not directly visible from "main".
+ I.e., you have to say "break c::memfunc".
+ If it were a normal function (not a method), it would be visible
+ via the simple "break memfunc". Since "memfunc" otherwise looks
+ like a normal FUNCTION in the symbol table, the bracketing
+ CLASS_SCOPE is what is used to indicate it is really a method.
+
+
+ A DNTT_TYPE_CLASS_SCOPE symbol must have a matching DNTT_TYPE_END symbol
+*/
+
+struct dntt_type_class_scope {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_CLASS_SCOPE */
+ unsigned int unused: 21;
+ sltpointer address ; /* pointer to SLT entry */
+ dnttpointer type ; /* pointer to class type DNTT */
+};
+
+/* C++ reference parameter.
+ The structure of this record is the same as DNTT_TYPE_POINTER -
+ refer to struct dntt_type_pointer.
+ */
+
+/* The next two describe C++ pointer-to-data-member type, and
+ pointer-to-member-function type, respectively.
+ DNTT_TYPE_PTRMEM and DNTT_TYPE_PTRMEMFUNC have the same structure
+ */
+
+struct dntt_type_ptrmem {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_PTRMEM */
+ unsigned int unused: 21;
+ dnttpointer pointsto ; /* pointer to class DNTT */
+ dnttpointer memtype ; /* type of member */
+};
+
+struct dntt_type_ptrmemfunc {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_PTRMEMFUNC */
+ unsigned int unused: 21;
+ dnttpointer pointsto ; /* pointer to class DNTT */
+ dnttpointer memtype ; /* type of member */
+};
+
+/* The DNTT_TYPE_CLASS symbol is emitted to describe a class type.
+ * "memberlist" points to a chained list of FIELD or GENFIELD records
+ * indicating the class members. "parentlist" points to a chained list
+ * of INHERITANCE records indicating classes from which we inherit
+ * fields.
+ */
+
+struct dntt_type_class
+{
+ unsigned int extension: 1; /* always 0 */
+ unsigned int kind: 10; /* always DNTT_TYPE_CLASS */
+ unsigned int abstract: 1; /* is this an abstract class? */
+ unsigned int class_decl: 2; /* 0=class,1=union,2=struct */
+ unsigned int expansion: 1; /* 1=template expansion */
+ unsigned int unused: 17;
+ dnttpointer memberlist ; /* ptr to chain of [GEN]FIELDs */
+ unsigned long vtbl_loc ; /* offset in obj of ptr to vtbl */
+ dnttpointer parentlist ; /* ptr to K_INHERITANCE list */
+ unsigned long bitlength ; /* total at this level */
+ dnttpointer identlist ; /* ptr to chain of class ident's */
+ dnttpointer friendlist ; /* ptr to K_FRIEND list */
+ dnttpointer templateptr ; /* ptr to template */
+ dnttpointer nextexp ; /* ptr to next expansion */
+};
+
+/* Class members are indicated via either the FIELD record (for
+ data members, same as for C struct fields), or by the GENFIELD record
+ (for member functions).
+ */
+
+struct dntt_type_genfield {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_GENFIELD */
+ unsigned int visibility: 2; /* pub = 0, prot = 1, priv = 2 */
+ unsigned int a_union: 1; /* 1 => anonymous union member */
+ unsigned int unused: 18;
+ dnttpointer field ; /* pointer to field or qualifier */
+ dnttpointer nextfield ; /* pointer to next field */
+};
+
+/* C++ virtual functions */
+
+struct dntt_type_vfunc {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_VFUNC */
+ unsigned int pure: 1; /* pure virtual function ? */
+ unsigned int unused: 20;
+ dnttpointer funcptr ; /* points to FUNCTION symbol */
+ unsigned long vtbl_offset ; /* offset into vtbl for virtual */
+};
+
+/* Not precisely sure what this is intended for - DDE ignores it */
+
+struct dntt_type_memaccess {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_MEMACCESS */
+ unsigned int unused: 21;
+ dnttpointer classptr ; /* pointer to base class */
+ dnttpointer field ; /* pointer field */
+};
+
+/* The DNTT_TYPE_INHERITANCE record describes derived classes.
+ * In particular, the "parentlist" field of the CLASS record points
+ * to a list of INHERITANCE records for classes from which we
+ * inherit members.
+ */
+
+struct dntt_type_inheritance {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_INHERITANCE */
+ unsigned int Virtual: 1; /* virtual base class ? */
+ unsigned int visibility: 2; /* pub = 0, prot = 1, priv = 2 */
+ unsigned int unused: 18;
+ dnttpointer classname ; /* first parent class, if any */
+ unsigned long offset ; /* offset to start of base class */
+ dnttpointer next ; /* pointer to next K_INHERITANCE */
+ unsigned long future[2] ; /* padding to 3-word block end */
+};
+
+/* C++ "friend" classes ... */
+
+struct dntt_type_friend_class {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_FRIEND_CLASS */
+ unsigned int unused: 21;
+ dnttpointer classptr ; /* pointer to class DNTT */
+ dnttpointer next ; /* next DNTT_FRIEND */
+};
+
+struct dntt_type_friend_func {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_FRIEND_FUNC */
+ unsigned int unused: 21;
+ dnttpointer funcptr ; /* pointer to function */
+ dnttpointer classptr ; /* pointer to class DNTT */
+ dnttpointer next ; /* next DNTT_FRIEND */
+ unsigned long future[2] ; /* padding to 3-word block end */
+};
+
+/* DDE appears to ignore the DNTT_TYPE_MODIFIER record.
+ * It could perhaps be used to give better "ptype" output in GDB;
+ * otherwise it is probably safe for GDB to ignore it also.
+ */
+
+struct dntt_type_modifier {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_MODIFIER */
+ unsigned int m_const: 1; /* const */
+ unsigned int m_static: 1; /* static */
+ unsigned int m_void: 1; /* void */
+ unsigned int m_volatile: 1; /* volatile */
+ unsigned int m_duplicate: 1; /* duplicate */
+ unsigned int unused: 16;
+ dnttpointer type ; /* subtype */
+ unsigned long future ; /* padding to 3-word block end */
+};
+
+/* I'm not sure what this was intended for - DDE ignores it */
+
+struct dntt_type_object_id {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_OBJECT_ID */
+ unsigned int indirect: 1; /* Is object_ident addr of addr? */
+ unsigned int unused: 20;
+ unsigned long object_ident ; /* object identifier */
+ unsigned long offset ; /* offset to start of base class */
+ dnttpointer next ; /* pointer to next K_OBJECT_ID */
+ unsigned long segoffset ; /* for linker fixup */
+ unsigned long future ; /* padding to 3-word block end */
+};
+
+/* No separate dntt_type_memfunc; same as dntt_type_func */
+
+/* Symbol records to support templates. These only get used
+ * in DDE's "describe" output (like GDB's "ptype").
+ */
+
+/* The TEMPLATE record is the header for a template-class.
+ * Like the CLASS record, a TEMPLATE record has a memberlist that
+ * points to a list of template members. It also has an arglist
+ * pointing to a list of TEMPLATE_ARG records.
+ */
+
+struct dntt_type_template {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_TEMPLATE */
+ unsigned int abstract: 1; /* is this an abstract class? */
+ unsigned int class_decl: 2; /* 0=class,1=union,2=struct */
+ unsigned int unused: 18;
+ dnttpointer memberlist ; /* ptr to chain of K_[GEN]FIELDs */
+ long unused2 ; /* offset in obj of ptr to vtbl */
+ dnttpointer parentlist ; /* ptr to K_INHERITANCE list */
+ unsigned long bitlength ; /* total at this level */
+ dnttpointer identlist ; /* ptr to chain of class ident's */
+ dnttpointer friendlist ; /* ptr to K_FRIEND list */
+ dnttpointer arglist ; /* ptr to argument list */
+ dnttpointer expansions ; /* ptr to expansion list */
+};
+
+/* Template-class arguments are a list of TEMPL_ARG records
+ * chained together. The "name" field is the name of the formal.
+ * E.g.:
+ * template <class T> class q { ... };
+ * Then "T" is the name of the formal argument.
+ */
+struct dntt_type_templ_arg {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_TEMPL_ARG */
+ unsigned int usagetype: 1; /* 0 type-name 1 expression */
+ unsigned int unused: 20;
+ vtpointer name ; /* name of argument */
+ dnttpointer type ; /* for non type arguments */
+ dnttpointer nextarg ; /* Next argument if any */
+ long future[2] ; /* padding to 3-word block end */
+};
+
+/* FUNC_TEMPLATE records are sort of like FUNCTION, but are emitted
+ * for template member functions. E.g.,
+ * template <class T> class q {
+ ...
+ void f();
+ ...
+ };
+ * Within the list of FIELDs/GENFIELDs defining the member list
+ * of the template "q", "f" would appear as a FUNC_TEMPLATE.
+ * We'll also see instances of FUNCTION "f" records for each
+ * instantiation of the template.
+ */
+
+struct dntt_type_func_template {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_FUNC_TEMPLATE */
+ unsigned int public: 1; /* 1 => globally visible */
+ unsigned int language: 4; /* type of language */
+ unsigned int level: 5; /* nesting level (top level = 0)*/
+ unsigned int optimize: 2; /* level of optimization */
+ unsigned int varargs: 1; /* ellipses. Pascal/800 later */
+ unsigned int info: 4; /* lang-specific stuff; F_xxxx */
+ unsigned int inlined: 1;
+ unsigned int localloc: 1; /* 0 at top, 1 at end of block */
+ unsigned int unused: 2;
+ vtpointer name ; /* name of function */
+ vtpointer alias ; /* alternate name, if any */
+ dnttpointer firstparam ; /* first FPARAM, if any */
+ dnttpointer retval ; /* return type, if any */
+ dnttpointer arglist ; /* ptr to argument list */
+};
+
+/* LINK is apparently intended to link together function template
+ * definitions with their instantiations. However, it is not clear
+ * why this would be needed, except to provide the information on
+ * a "ptype" command. And as far as I can tell, aCC does not
+ * generate this record.
+ */
+
+struct dntt_type_link {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* always DNTT_TYPE_LINK */
+ unsigned int linkKind: 4; /* always LINK_UNKNOWN */
+ unsigned int unused: 17;
+ long future1 ; /* expansion */
+ dnttpointer ptr1 ; /* link from template */
+ dnttpointer ptr2 ; /* to expansion */
+ long future[2] ; /* padding to 3-word block end */
+};
+
+/* end of C++ specific SOM's */
+
+/* DNTT_TYPE_DYN_ARRAY_DESC is unused by GDB */
+/* DNTT_TYPE_DESC_SUBRANGE is unused by GDB */
+/* DNTT_TYPE_BEGIN_EXT is unused by GDB */
+/* DNTT_TYPE_INLN is unused by GDB */
+/* DNTT_TYPE_INLN_LIST is unused by GDB */
+/* DNTT_TYPE_ALIAS is unused by GDB */
+
+struct dntt_type_doc_function {
+ unsigned int extension: 1; /* always zero */
+ unsigned int kind: 10; /* K_DOC_FUNCTION or */
+ /* K_DOC_MEMFUNC */
+ unsigned int global: 1; /* 1 => globally visible */
+ unsigned int language: 4; /* type of language */
+ unsigned int level: 5; /* nesting level (top level = 0)*/
+ unsigned int optimize: 2; /* level of optimization */
+ unsigned int varargs: 1; /* ellipses. Pascal/800 later */
+ unsigned int info: 4; /* lang-specific stuff; F_xxxx */
+ unsigned int inlined: 1;
+ unsigned int localloc: 1; /* 0 at top, 1 at end of block */
+ unsigned int expansion: 1; /* 1 = function expansion */
+ unsigned int doc_clone: 1;
+ vtpointer name; /* name of function */
+ vtpointer alias; /* alternate name, if any */
+ dnttpointer firstparam; /* first FPARAM, if any */
+ sltpointer address; /* code and text locations */
+ CORE_ADDR entryaddr; /* address of entry point */
+ dnttpointer retval; /* return type, if any */
+ CORE_ADDR lowaddr; /* lowest address of function */
+ CORE_ADDR hiaddr; /* highest address of function */
+ dnttpointer inline_list; /* pointer to first inline */
+ ltpointer lt_offset; /* start of frag/cp line table */
+ ctxtpointer ctxt_offset; /* start of context table for this routine */
+};
+
+/* DNTT_TYPE_DOC_MEMFUNC is unused by GDB */
+
+/* DNTT_TYPE_GENERIC and DNTT_TYPE_BLOCK are convience structures
+ so we can examine a DNTT entry in a generic fashion. */
+struct dntt_type_generic
+{
+ unsigned int word[9];
+};
+
+struct dntt_type_block
+{
+ unsigned int extension: 1;
+ unsigned int kind: 10;
+ unsigned int unused: 21;
+ unsigned int word[2];
+};
+
+/* One entry in a DNTT (either the LNTT or GNTT).
+ * This is a union of the above 60 or so structure definitions.
+ */
+union dnttentry
+{
+ struct dntt_type_srcfile dsfile;
+ struct dntt_type_module dmodule;
+ struct dntt_type_function dfunc;
+ struct dntt_type_function dentry;
+ struct dntt_type_begin dbegin;
+ struct dntt_type_end dend;
+ struct dntt_type_fparam dfparam;
+ struct dntt_type_svar dsvar;
+ struct dntt_type_dvar ddvar;
+ struct dntt_type_const dconst;
+ struct dntt_type_type dtype;
+ struct dntt_type_type dtag;
+ struct dntt_type_pointer dptr;
+ struct dntt_type_enum denum;
+ struct dntt_type_memenum dmember;
+ struct dntt_type_set dset;
+ struct dntt_type_subrange dsubr;
+ struct dntt_type_array darray;
+ struct dntt_type_struct dstruct;
+ struct dntt_type_union dunion;
+ struct dntt_type_field dfield;
+ struct dntt_type_functype dfunctype;
+ struct dntt_type_with dwith;
+ struct dntt_type_function dblockdata;
+ struct dntt_type_class_scope dclass_scope;
+ struct dntt_type_pointer dreference;
+ struct dntt_type_ptrmem dptrmem;
+ struct dntt_type_ptrmemfunc dptrmemfunc;
+ struct dntt_type_class dclass;
+ struct dntt_type_genfield dgenfield;
+ struct dntt_type_vfunc dvfunc;
+ struct dntt_type_memaccess dmemaccess;
+ struct dntt_type_inheritance dinheritance;
+ struct dntt_type_friend_class dfriend_class;
+ struct dntt_type_friend_func dfriend_func;
+ struct dntt_type_modifier dmodifier;
+ struct dntt_type_object_id dobject_id;
+ struct dntt_type_template dtemplate;
+ struct dntt_type_templ_arg dtempl_arg;
+ struct dntt_type_func_template dfunc_template;
+ struct dntt_type_link dlink;
+ struct dntt_type_doc_function ddocfunc;
+ struct dntt_type_generic dgeneric;
+ struct dntt_type_block dblock;
+};
+
+/* Source line entry types. */
+enum slttype
+{
+ SLT_NORMAL,
+ SLT_SRCFILE,
+ SLT_MODULE,
+ SLT_FUNCTION,
+ SLT_ENTRY,
+ SLT_BEGIN,
+ SLT_END,
+ SLT_WITH,
+ SLT_EXIT,
+ SLT_ASSIST,
+ SLT_MARKER,
+ SLT_CLASS_SCOPE,
+ SLT_INLN,
+ SLT_NORMAL_OFFSET,
+};
+
+/* A normal source line entry. Simply provides a mapping of a source
+ line number to a code address.
+
+ SLTDESC will always be SLT_NORMAL or SLT_EXIT. */
+
+struct slt_normal
+{
+ unsigned int sltdesc: 4;
+ unsigned int line: 28;
+ CORE_ADDR address;
+};
+
+struct slt_normal_off
+{
+ unsigned int sltdesc: 4;
+ unsigned int offset: 6;
+ unsigned int line: 22;
+ CORE_ADDR address;
+};
+
+/* A special source line entry. Provides a mapping of a declaration
+ to a line number. These entries point back into the DNTT which
+ references them. */
+
+struct slt_special
+{
+ unsigned int sltdesc: 4;
+ unsigned int line: 28;
+ dnttpointer backptr;
+};
+
+/* Used to describe nesting.
+
+ For nested languages, an slt_assist entry must follow each SLT_FUNC
+ entry in the SLT. The address field will point forward to the
+ first slt_normal entry within the function's scope. */
+
+struct slt_assist
+{
+ unsigned int sltdesc: 4;
+ unsigned int unused: 28;
+ sltpointer address;
+};
+
+struct slt_generic
+{
+ unsigned int word[2];
+};
+
+union sltentry
+{
+ struct slt_normal snorm;
+ struct slt_normal_off snormoff;
+ struct slt_special sspec;
+ struct slt_assist sasst;
+ struct slt_generic sgeneric;
+};
+
+/* $LINES$ declarations
+ * This is the line table used for optimized code, which is only present
+ * in the new $PROGRAM_INFO$ debug space.
+ */
+
+#define DST_LN_ESCAPE_FLAG1 15
+#define DST_LN_ESCAPE_FLAG2 14
+#define DST_LN_CTX_SPEC1 13
+#define DST_LN_CTX_SPEC2 12
+
+/*
+ Escape function codes:
+*/
+typedef enum
+ {
+ dst_ln_pad, /* pad byte */
+ dst_ln_escape_1, /* reserved */
+ dst_ln_dpc1_dln1, /* 1 byte line delta, 1 byte pc delta */
+ dst_ln_dpc2_dln2, /* 2 bytes line delta, 2 bytes pc delta */
+ dst_ln_pc4_ln4, /* 4 bytes ABSOLUTE line number, 4 bytes ABSOLUTE pc */
+ dst_ln_dpc0_dln1, /* 1 byte line delta, pc delta = 0 */
+ dst_ln_ln_off_1, /* statement escape, stmt # = 1 (2nd stmt on line) */
+ dst_ln_ln_off, /* statement escape, stmt # = next byte */
+ dst_ln_entry, /* entry escape, next byte is entry number */
+ dst_ln_exit, /* exit escape */
+ dst_ln_stmt_end, /* gap escape, 4 bytes pc delta */
+ dst_ln_stmt_cp, /* current stmt is a critical point */
+ dst_ln_escape_12, /* reserved */
+ dst_ln_escape_13, /* this is an exception site record */
+ dst_ln_nxt_byte, /* next byte contains the real escape code */
+ dst_ln_end, /* end escape, final entry follows */
+ dst_ln_escape1_END_OF_ENUM
+ }
+ dst_ln_escape1_t;
+
+typedef enum
+ {
+ dst_ln_ctx_1, /* next byte describes context switch with 5-bit */
+ /* index into the image table and 3-bit run length. */
+ /* If run length is 0, end with another cxt specifier or ctx_end */
+ dst_ln_ctx_2, /* next 2 bytes switch context: 13 bit index, 3 bit run length */
+ dst_ln_ctx_4, /* next 4 bytes switch context: 29 bit index, 3 bit run length */
+ dst_ln_ctx_end, /* end current context */
+ dst_ln_col_run_1, /* next byte is column position of start of next statement, */
+ /* following byte is length of statement */
+ dst_ln_col_run_2, /* next 2 bytes is column position of start of next statement, */
+ /* following 2 bytes is length of statement */
+ dst_ln_init_base1, /* next 4 bytes are absolute PC, followed by 1 byte of line number */
+ dst_ln_init_base2, /* next 4 bytes are absolute PC, followed by 2 bytes of line number */
+ dst_ln_init_base3, /* next 4 bytes are absolute PC, followed by 3 bytes of line number */
+ dst_ln_escape2_END_OF_ENUM
+ }
+ dst_ln_escape2_t;
+
+typedef union
+ {
+ struct
+ {
+ unsigned int pc_delta : 4; /* 4 bit pc delta */
+ int ln_delta : 4; /* 4 bit line number delta */
+ }
+ delta;
+
+ struct
+ {
+ unsigned int esc_flag : 4; /* alias for pc_delta */
+ unsigned int esc_code : 4; /* escape function code (dst_ln_escape1_t, or ...2_t */
+ }
+ esc;
+
+ struct
+ {
+ unsigned int esc_flag : 4; /* dst_ln_ctx_spec1, or dst_ln_ctx_spec2 */
+ unsigned int run_length : 2;
+ unsigned int ctx_index : 2; /* ...spec2 contains index; ...spec1, index - 4 */
+ }
+ ctx_spec;
+
+ char sdata; /* signed data byte */
+ unsigned char udata; /* unsigned data byte */
+ }
+ dst_ln_entry_t,
+ *dst_ln_entry_ptr_t;
+
+/* Warning: although the above union occupies only 1 byte the compiler treats
+ * it as having size 2 (the minimum size of a struct). Therefore a sequence of
+ * dst_ln_entry_t's cannot be described as an array, and walking through such a
+ * sequence requires convoluted code such as
+ * ln_ptr = (dst_ln_entry_ptr_t) (char*) ln_ptr + 1
+ * We regret the inconvenience. */
+
+/* Structure for interpreting the byte following a dst_ln_ctx1 entry */
+typedef struct {
+ unsigned int ctx1_index : 5; /* 5 bit index into context table */
+ unsigned int ctx1_run_length : 3; /* 3 bit run length */
+} dst_ln_ctx1_t,
+ *dst_ln_ctx1_ptr_t;
+
+/* Structure for interpreting the bytes following a dst_ln_ctx2 entry */
+typedef struct {
+ unsigned int ctx2_index : 13; /* 13 bit index into context table */
+ unsigned int ctx2_run_length : 3; /* 3 bit run length */
+} dst_ln_ctx2_t,
+ *dst_ln_ctx2_ptr_t;
+
+/* Structure for interpreting the bytes following a dst_ln_ctx4 entry */
+typedef struct {
+ unsigned int ctx4_index : 29; /* 29 bit index into context table */
+ unsigned int ctx4_run_length : 3; /* 3 bit run length */
+} dst_ln_ctx4_t,
+ *dst_ln_ctx4_ptr_t;
+
+
+/* PXDB definitions.
+ *
+ * PXDB is a post-processor which takes the executable file
+ * and massages the debug information so that the debugger may
+ * start up and run more efficiently. Some of the tasks
+ * performed by PXDB are:
+ *
+ * o Remove duplicate global type and variable information
+ * from the GNTT,
+ *
+ * o Append the GNTT onto the end of the LNTT and place both
+ * back in the LNTT section,
+ *
+ * o Build quick look-up tables (description follows) for
+ * files, procedures, modules, and paragraphs (for Cobol),
+ * placing these in the GNTT section,
+ *
+ * o Reconstruct the header appearing in the header section
+ * to access this information.
+ *
+ * The "quick look-up" tables are in the $GNTT$ sub-space, in
+ * the following order:
+ *
+ * Procedures -sorted by address
+ * Source files -sorted by address (of the
+ * generated code from routines)
+ * Modules -sorted by address
+ * Classes -<unsorted?>
+ * Address Alias -sorted by index <?>
+ * Object IDs -sorted by object identifier
+ *
+ * Most quick entries have (0-based) indices into the LNTT tables to
+ * the full entries for the item it describes.
+ *
+ * The post-PXDB header is in the $HEADER$ sub-space. Alas, it
+ * occurs in different forms, depending on the optimization level
+ * in the compilation step and whether PXDB was run or not. The
+ * worst part is the forms aren't self-describing, so we'll have
+ * to grovel in the bits to figure out what kind we're looking at
+ * (see hp_get_header in hp-psymtab-read.c).
+ */
+
+/* PXDB versions
+ */
+#define PXDB_VERSION_CPLUSPLUS 1
+#define PXDB_VERSION_7_4 2
+#define PXDB_VERSION_CPP_30 3
+#define PXDB_VERSION_DDE_3_2A 4
+#define PXDB_VERSION_DDE_3_2 5
+#define PXDB_VERSION_DDE_4_0 6
+
+#define PXDB_VERSION_2_1 1
+
+/* Header version for the case that there is no DOC info
+ * but the executable has been processed by pxdb (the easy
+ * case, from "cc -g").
+ */
+typedef struct PXDB_struct {
+ int pd_entries; /* # of entries in function look-up table */
+ int fd_entries; /* # of entries in file look-up table */
+ int md_entries; /* # of entries in module look-up table */
+ unsigned int pxdbed : 1; /* 1 => file has been preprocessed */
+ unsigned int bighdr : 1; /* 1 => this header contains 'time' word */
+ unsigned int sa_header : 1;/* 1 => created by SA version of pxdb */
+ /* used for version check in xdb */
+ unsigned int inlined: 1; /* one or more functions have been inlined */
+ unsigned int spare:12;
+ short version; /* pxdb header version */
+ int globals; /* index into the DNTT where GNTT begins */
+ unsigned int time; /* modify time of file before being pxdbed */
+ int pg_entries; /* # of entries in label look-up table */
+ int functions; /* actual number of functions */
+ int files; /* actual number of files */
+ int cd_entries; /* # of entries in class look-up table */
+ int aa_entries; /* # of entries in addr alias look-up table */
+ int oi_entries; /* # of entries in object id look-up table */
+} PXDB_header, *PXDB_header_ptr;
+
+/* Header version for the case that there is no DOC info and the
+ * executable has NOT been processed by pxdb.
+ */
+typedef struct XDB_header_struct {
+ long gntt_length;
+ long lntt_length;
+ long slt_length;
+ long vt_length;
+ long xt_length;
+} XDB_header;
+
+/* Header version for the case that there is DOC info and the
+ * executable has been processed by pxdb.
+ */
+typedef struct DOC_info_PXDB_header_struct {
+ unsigned int xdb_header: 1; /* bit set if this is post-3.1 xdb */
+ unsigned int doc_header: 1; /* bit set if this is doc-style header*/
+ unsigned int version: 8; /* version of pxdb see defines
+ * PXDB_VERSION_* in this file */
+ unsigned int reserved_for_flags: 16;/* for future use; -- must be
+ * set to zero
+ */
+ unsigned int has_aux_pd_table: 1; /* $GNTT$ has aux PD table */
+ unsigned int has_expr_table: 1; /* space has $EXPR$ */
+ unsigned int has_range_table: 1; /* space has $RANGE$ */
+ unsigned int has_context_table: 1; /* space has $SRC_CTXT$ */
+ unsigned int has_lines_table: 1; /* space contains a $LINES$
+ * subspace for line tables.
+ */
+ unsigned int has_lt_offset_map: 1; /* space contains an lt_offset
+ * subspace for line table mapping
+ */
+ /* the following fields are the same as those in the PXDB_header in $DEBUG$ */
+ int pd_entries; /* # of entries in function look-up table */
+ int fd_entries; /* # of entries in file look-up table */
+ int md_entries; /* # of entries in module look-up table */
+ unsigned int pxdbed : 1; /* 1 => file has been preprocessed */
+ unsigned int bighdr : 1; /* 1 => this header contains 'time' word */
+ unsigned int sa_header : 1;/* 1 => created by SA version of pxdb */
+ /* used for version check in xdb */
+ unsigned int inlined: 1; /* one or more functions have been inlined */
+ unsigned int spare : 28;
+ int globals; /* index into the DNTT where GNTT begins */
+ unsigned int time; /* modify time of file before being pxdbed */
+ int pg_entries; /* # of entries in label look-up table */
+ int functions; /* actual number of functions */
+ int files; /* actual number of files */
+ int cd_entries; /* # of entries in class look-up table */
+ int aa_entries; /* # of entries in addr alias look-up table */
+ int oi_entries; /* # of entries in object id look-up table */
+} DOC_info_PXDB_header;
+
+/* Header version for the case that there is DOC info and the
+ * executable has NOT been processed by pxdb.
+ */
+typedef struct DOC_info_header_struct {
+ unsigned int xdb_header: 1; /* bit set if this is post-3.1 xdb */
+ unsigned int doc_header: 1; /* bit set if this is doc-style header*/
+ unsigned int version: 8; /* version of debug/header
+ format. For 10.0 the value
+ will be 1. For "Davis" the
+ value is 2.
+ */
+ unsigned int reserved_for_flags: 18; /* for future use; -- must be
+ set to zero
+ */
+ unsigned int has_range_table: 1; /* space contains a $RANGE$
+ subspace for variable ranges.
+ */
+ unsigned int has_context_table: 1; /* space contains a $CTXT$
+ subspace for context/inline
+ table.
+ */
+ unsigned int has_lines_table: 1; /* space contains a $LINES$
+ subspace for line tables.
+ */
+ unsigned int has_lt_offset_map: 1; /* space contains an lt_offset
+ subspace for line table mapping
+ */
+
+ long gntt_length; /* same as old header */
+ long lntt_length; /* same as old header */
+ long slt_length; /* same as old header */
+ long vt_length; /* same as old header */
+ long xt_length; /* same as old header */
+ long ctxt_length; /* present only if version >= 2 */
+ long range_length; /* present only if version >= 2 */
+ long expr_length; /* present only if version >= 2 */
+
+} DOC_info_header;
+
+typedef union GenericDebugHeader_union
+{
+ PXDB_header no_doc;
+ DOC_info_PXDB_header doc;
+ XDB_header no_pxdb_no_doc;
+ DOC_info_header no_pxdb_doc;
+} GenericDebugHeader;
+
+
+/* Procedure Descriptor:
+ *
+ * An element of the procedure quick look-up table
+ */
+typedef struct quick_procedure {
+ long isym; /* 0-based index of first symbol*/
+ /* for procedure in $LNTT$, */
+ /* i.e. the procedure itself */
+ CORE_ADDR adrStart; /* memory adr of start of proc */
+ CORE_ADDR adrEnd; /* memory adr of end of proc */
+ char *sbAlias; /* alias name of procedure */
+ char *sbProc; /* real name of procedure */
+ CORE_ADDR adrBp; /* address of entry breakpoint */
+ CORE_ADDR adrExitBp; /* address of exit breakpoint */
+ int icd; /* member of this class (index) */
+ unsigned int ipd; /* index of template for this */
+ /* function (index) */
+ unsigned int unused: 5;
+ unsigned int no_lt_offset: 1;/* no entry in lt_offset table */
+ unsigned int fTemplate: 1; /* function template */
+ unsigned int fExpansion: 1; /* function expansion */
+ unsigned int linked : 1; /* linked with other expansions */
+ unsigned int duplicate: 1; /* clone of another procedure */
+ unsigned int overloaded:1; /* overloaded function */
+ unsigned int member: 1; /* class member function */
+ unsigned int constructor:1; /* constructor function */
+ unsigned int destructor:1; /* destructor function */
+ unsigned int Static: 1; /* static function */
+ unsigned int Virtual: 1; /* virtual function */
+ unsigned int constant: 1; /* constant function */
+ unsigned int pure: 1; /* pure (virtual) function */
+ unsigned int language: 4; /* procedure's language */
+ unsigned int inlined: 1; /* function has been inlined */
+ unsigned int Operator: 1; /* operator function */
+ unsigned int stub: 1; /* bodyless function */
+ unsigned int optimize: 2; /* optimization level */
+ unsigned int level: 5; /* nesting level (top=0) */
+} quick_procedure_entry, *quick_procedure_entry_ptr;
+
+/* Source File Descriptor:
+ *
+ * An element of the source file quick look-up table
+ */
+typedef struct quick_source {
+ long isym; /* 0-based index in $LNTT$ of */
+ /* first symbol for this file */
+ CORE_ADDR adrStart; /* mem adr of start of file's code */
+ CORE_ADDR adrEnd; /* mem adr of end of file's code */
+ char *sbFile; /* name of source file */
+ unsigned int fHasDecl: 1; /* do we have a .d file? */
+ unsigned int fWarned: 1; /* have warned about age problems? */
+ unsigned int fSrcfile: 1; /* 0 => include 1=> source */
+ unsigned short ilnMac; /* lines in file (0 if don't know) */
+ int ipd; /* 0-based index of first procedure*/
+ /* in this file, in the quick */
+ /* look-up table of procedures */
+ unsigned int *rgLn; /* line pointer array, if any */
+} quick_file_entry, *quick_file_entry_ptr;
+
+/* Module Descriptor:
+ *
+ * An element of the module quick reference table
+ */
+typedef struct quick_module {
+ long isym; /* 0-based index of first */
+ /* symbol for module */
+ CORE_ADDR adrStart; /* adr of start of mod. */
+ CORE_ADDR adrEnd; /* adr of end of mod. */
+ char *sbAlias; /* alias name of module */
+ char *sbMod; /* real name of module */
+ unsigned int imports: 1; /* module have any imports? */
+ unsigned int vars_in_front: 1; /* module globals in front? */
+ unsigned int vars_in_gaps: 1; /* module globals in gaps? */
+ unsigned int language: 4; /* type of language */
+ unsigned int unused : 25;
+ unsigned int unused2; /* space for future stuff */
+} quick_module_entry, *quick_module_entry_ptr;
+
+/* Auxiliary Procedure Descriptor:
+ *
+ * An element of the auxiliary procedure quick look-up table
+ */
+typedef struct quick_aux_procedure {
+ long isym_inln; /* start on inline list for proc */
+ long spare;
+} quick_aux_procedure_entry, *quick_aux_procedure_entry_ptr;
+
+/* Paragraph Descriptor:
+ *
+ * An element of the paragraph quick look-up table
+ */
+typedef struct quick_paragraph {
+ long isym; /* first symbol for label (index) */
+ CORE_ADDR adrStart; /* memory adr of start of label */
+ CORE_ADDR adrEnd; /* memory adr of end of label */
+ char *sbLab; /* name of label */
+ unsigned int inst; /* Used in xdb to store inst @ bp */
+ unsigned int sect: 1; /* true = section, false = parag. */
+ unsigned int unused: 31; /* future use */
+} quick_paragraph_entry, *quick_paragraph_entry_ptr;
+
+/*
+ * Class Descriptor:
+ *
+ * An element of the class quick look-up table
+ */
+typedef struct quick_class {
+ char *sbClass; /* name of class */
+ long isym; /* class symbol (tag) */
+ unsigned int type : 2; /* 0=class, 1=union, 2=struct */
+ unsigned int fTemplate : 1;/* class template */
+ unsigned int expansion : 1;/* template expansion */
+ unsigned int unused :28;
+ sltpointer lowscope; /* beginning of defined scope */
+ sltpointer hiscope; /* end of defined scope */
+} quick_class_entry, *quick_class_entry_ptr;
+
+/* Address Alias Entry
+ *
+ * An element of the address alias quick look-up table
+ */
+typedef struct quick_alias {
+ CORE_ADDR low;
+ CORE_ADDR high;
+ int index;
+ unsigned int unused : 31;
+ unsigned int alternate : 1; /* alternate unnamed aliases? */
+} quick_alias_entry, *quick_alias_entry_ptr;
+
+/* Object Identification Entry
+ *
+ * An element of the object identification quick look-up table
+ */
+
+typedef struct quick_obj_ID {
+ CORE_ADDR obj_ident; /* class identifier */
+ long isym; /* class symbol */
+ long offset; /* offset to object start */
+} quick_obj_ID_entry, *quick_obj_ID_entry_ptr;
+
+
+#endif /* HP_SYMTAB_INCLUDED */
+
diff --git a/include/ieee.h b/include/ieee.h
new file mode 100644
index 00000000000..5ade39d33e3
--- /dev/null
+++ b/include/ieee.h
@@ -0,0 +1,139 @@
+/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file
+ Contributed by Cygnus Support. */
+
+#define N_W_VARIABLES 8
+#define Module_Beginning 0xe0
+
+typedef struct ieee_module {
+ char *processor;
+ char *module_name;
+} ieee_module_begin_type;
+
+#define Address_Descriptor 0xec
+typedef struct ieee_address {
+bfd_vma number_of_bits_mau;
+ bfd_vma number_of_maus_in_address;
+
+ unsigned char byte_order;
+#define IEEE_LITTLE 0xcc
+#define IEEE_BIG 0xcd
+} ieee_address_descriptor_type;
+
+typedef union ieee_w_variable {
+ file_ptr offset[N_W_VARIABLES];
+ struct {
+ file_ptr extension_record;
+ file_ptr environmental_record;
+ file_ptr section_part;
+ file_ptr external_part;
+ file_ptr debug_information_part;
+ file_ptr data_part;
+ file_ptr trailer_part;
+ file_ptr me_record;
+ } r;
+} ieee_w_variable_type;
+
+
+
+
+
+typedef enum ieee_record
+{
+ ieee_number_start_enum = 0x00,
+ ieee_number_end_enum=0x7f,
+ ieee_number_repeat_start_enum = 0x80,
+ ieee_number_repeat_end_enum = 0x88,
+ ieee_number_repeat_4_enum = 0x84,
+ ieee_number_repeat_3_enum = 0x83,
+ ieee_number_repeat_2_enum = 0x82,
+ ieee_number_repeat_1_enum = 0x81,
+ ieee_module_beginning_enum = 0xe0,
+ ieee_module_end_enum = 0xe1,
+ ieee_extension_length_1_enum = 0xde,
+ ieee_extension_length_2_enum = 0xdf,
+ ieee_section_type_enum = 0xe6,
+ ieee_section_alignment_enum = 0xe7,
+ ieee_external_symbol_enum = 0xe8,
+ ieee_comma = 0x90,
+ ieee_external_reference_enum = 0xe9,
+ ieee_set_current_section_enum = 0xe5,
+ ieee_address_descriptor_enum = 0xec,
+ ieee_load_constant_bytes_enum = 0xed,
+ ieee_load_with_relocation_enum = 0xe4,
+
+ ieee_variable_A_enum = 0xc1,
+ ieee_variable_B_enum = 0xc2,
+ ieee_variable_C_enum = 0xc3,
+ ieee_variable_D_enum = 0xc4,
+ ieee_variable_E_enum = 0xc5,
+ ieee_variable_F_enum = 0xc6,
+ ieee_variable_G_enum = 0xc7,
+ ieee_variable_H_enum = 0xc8,
+ ieee_variable_I_enum = 0xc9,
+ ieee_variable_J_enum = 0xca,
+ ieee_variable_K_enum = 0xcb,
+ ieee_variable_L_enum = 0xcc,
+ ieee_variable_M_enum = 0xcd,
+ ieee_variable_N_enum = 0xce,
+ ieee_variable_O_enum = 0xcf,
+ ieee_variable_P_enum = 0xd0,
+ ieee_variable_Q_enum = 0xd1,
+ ieee_variable_R_enum = 0xd2,
+ ieee_variable_S_enum = 0xd3,
+ ieee_variable_T_enum = 0xd4,
+ ieee_variable_U_enum = 0xd5,
+ ieee_variable_V_enum = 0xd6,
+ ieee_variable_W_enum = 0xd7,
+ ieee_variable_X_enum = 0xd8,
+ ieee_variable_Y_enum = 0xd9,
+ ieee_variable_Z_enum = 0xda,
+ ieee_function_plus_enum = 0xa5,
+ ieee_function_minus_enum = 0xa6,
+ ieee_function_signed_open_b_enum = 0xba,
+ ieee_function_signed_close_b_enum = 0xbb,
+
+ ieee_function_unsigned_open_b_enum = 0xbc,
+ ieee_function_unsigned_close_b_enum = 0xbd,
+
+ ieee_function_either_open_b_enum = 0xbe,
+ ieee_function_either_close_b_enum = 0xbf,
+ ieee_record_seperator_enum = 0xdb,
+
+ ieee_e2_first_byte_enum = 0xe2,
+ ieee_section_size_enum = 0xe2d3,
+ ieee_physical_region_size_enum = 0xe2c1,
+ ieee_region_base_address_enum = 0xe2c2,
+ ieee_mau_size_enum = 0xe2c6,
+ ieee_m_value_enum = 0xe2cd,
+ ieee_section_base_address_enum = 0xe2cc,
+ ieee_asn_record_enum = 0xe2ce,
+ ieee_section_offset_enum = 0xe2d2,
+ ieee_value_starting_address_enum = 0xe2c7,
+ ieee_assign_value_to_variable_enum = 0xe2d7,
+ ieee_set_current_pc_enum = 0xe2d0,
+ ieee_value_record_enum = 0xe2c9,
+ ieee_nn_record = 0xf0,
+ ieee_at_record_enum = 0xf1,
+ ieee_ty_record_enum = 0xf2,
+ ieee_attribute_record_enum = 0xf1c9,
+ ieee_atn_record_enum = 0xf1ce,
+ ieee_external_reference_info_record_enum = 0xf1d8,
+ ieee_weak_external_reference_enum= 0xf4,
+ ieee_repeat_data_enum = 0xf7,
+ ieee_bb_record_enum = 0xf8,
+ ieee_be_record_enum = 0xf9
+} ieee_record_enum_type;
+
+
+typedef struct ieee_section {
+ unsigned int section_index;
+ unsigned int section_type;
+ char *section_name;
+ unsigned int parent_section_index;
+ unsigned int sibling_section_index;
+ unsigned int context_index;
+} ieee_section_type;
+#define IEEE_REFERENCE_BASE 11
+#define IEEE_PUBLIC_BASE 32
+#define IEEE_SECTION_NUMBER_BASE 1
+
diff --git a/include/libiberty.h b/include/libiberty.h
new file mode 100644
index 00000000000..cf313662ef4
--- /dev/null
+++ b/include/libiberty.h
@@ -0,0 +1,180 @@
+/* Function declarations for libiberty.
+ Written by Cygnus Support, 1994.
+
+ The libiberty library provides a number of functions which are
+ missing on some operating systems. We do not declare those here,
+ to avoid conflicts with the system header files on operating
+ systems that do support those functions. In this file we only
+ declare those functions which are specific to libiberty. */
+
+#ifndef LIBIBERTY_H
+#define LIBIBERTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+
+/* Build an argument vector from a string. Allocates memory using
+ malloc. Use freeargv to free the vector. */
+
+extern char **buildargv PARAMS ((char *));
+
+/* Free a vector returned by buildargv. */
+
+extern void freeargv PARAMS ((char **));
+
+/* Duplicate an argument vector. Allocates memory using malloc. Use
+ freeargv to free the vector. */
+
+extern char **dupargv PARAMS ((char **));
+
+
+/* Return the last component of a path name. Note that we can't use a
+ prototype here because the parameter is declared inconsistently
+ across different systems, sometimes as "char *" and sometimes as
+ "const char *" */
+
+#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) || defined (__CYGWIN__) || defined (__CYGWIN32__)
+extern char *basename PARAMS ((const char *));
+#else
+extern char *basename ();
+#endif
+
+/* Concatenate an arbitrary number of strings, up to (char *) NULL.
+ Allocates memory using xmalloc. */
+
+extern char *concat PARAMS ((const char *, ...));
+
+/* Check whether two file descriptors refer to the same file. */
+
+extern int fdmatch PARAMS ((int fd1, int fd2));
+
+/* Get the amount of time the process has run, in microseconds. */
+
+extern long get_run_time PARAMS ((void));
+
+/* Choose a temporary directory to use for scratch files. */
+
+extern char *choose_temp_base PARAMS ((void));
+
+/* Allocate memory filled with spaces. Allocates using malloc. */
+
+extern const char *spaces PARAMS ((int count));
+
+/* Return the maximum error number for which strerror will return a
+ string. */
+
+extern int errno_max PARAMS ((void));
+
+/* Return the name of an errno value (e.g., strerrno (EINVAL) returns
+ "EINVAL"). */
+
+extern const char *strerrno PARAMS ((int));
+
+/* Given the name of an errno value, return the value. */
+
+extern int strtoerrno PARAMS ((const char *));
+
+/* ANSI's strerror(), but more robust. */
+
+extern char *xstrerror PARAMS ((int));
+
+/* Return the maximum signal number for which strsignal will return a
+ string. */
+
+extern int signo_max PARAMS ((void));
+
+/* Return a signal message string for a signal number
+ (e.g., strsignal (SIGHUP) returns something like "Hangup"). */
+/* This is commented out as it can conflict with one in system headers.
+ We still document its existence though. */
+
+/*extern const char *strsignal PARAMS ((int));*/
+
+/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns
+ "SIGHUP"). */
+
+extern const char *strsigno PARAMS ((int));
+
+/* Given the name of a signal, return its number. */
+
+extern int strtosigno PARAMS ((const char *));
+
+/* Register a function to be run by xexit. Returns 0 on success. */
+
+extern int xatexit PARAMS ((void (*fn) (void)));
+
+/* Exit, calling all the functions registered with xatexit. */
+
+#ifndef __GNUC__
+extern void xexit PARAMS ((int status));
+#else
+void xexit PARAMS ((int status)) __attribute__ ((noreturn));
+#endif
+
+/* Set the program name used by xmalloc. */
+
+extern void xmalloc_set_program_name PARAMS ((const char *));
+
+/* Allocate memory without fail. If malloc fails, this will print a
+ message to stderr (using the name set by xmalloc_set_program_name,
+ if any) and then call xexit. */
+
+#ifdef ANSI_PROTOTYPES
+/* Get a definition for size_t. */
+#include <stddef.h>
+#endif
+extern PTR xmalloc PARAMS ((size_t));
+
+/* Reallocate memory without fail. This works like xmalloc.
+
+ FIXME: We do not declare the parameter types for the same reason as
+ xmalloc. */
+
+extern PTR xrealloc PARAMS ((PTR, size_t));
+
+/* Allocate memory without fail and set it to zero. This works like
+ xmalloc. */
+
+extern PTR xcalloc PARAMS ((size_t, size_t));
+
+/* Copy a string into a memory buffer without fail. */
+
+extern char *xstrdup PARAMS ((const char *));
+
+/* hex character manipulation routines */
+
+#define _hex_array_size 256
+#define _hex_bad 99
+extern char _hex_value[_hex_array_size];
+extern void hex_init PARAMS ((void));
+#define hex_p(c) (hex_value (c) != _hex_bad)
+/* If you change this, note well: Some code relies on side effects in
+ the argument being performed exactly once. */
+#define hex_value(c) (_hex_value[(unsigned char) (c)])
+
+/* Definitions used by the pexecute routine. */
+
+#define PEXECUTE_FIRST 1
+#define PEXECUTE_LAST 2
+#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
+#define PEXECUTE_SEARCH 4
+#define PEXECUTE_VERBOSE 8
+
+/* Execute a program. */
+
+extern int pexecute PARAMS ((const char *, char * const *, const char *,
+ const char *, char **, char **, int));
+
+/* Wait for pexecute to finish. */
+
+extern int pwait PARAMS ((int, int *, int));
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ! defined (LIBIBERTY_H) */
diff --git a/include/mpw/ChangeLog b/include/mpw/ChangeLog
new file mode 100644
index 00000000000..8dbad87eab4
--- /dev/null
+++ b/include/mpw/ChangeLog
@@ -0,0 +1,61 @@
+Tue Feb 27 12:23:04 1996 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw.h (HAVE_VPRINTF): Add and define to have the value 1.
+
+Fri Dec 29 14:40:46 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.h (HAVE_STDLIB_H, etc): Define to have the value 1.
+ (HAVE_FCNTL_H): Define.
+
+Mon Dec 11 15:39:06 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.h (open, access): Define as mpw_open and mpw_access.
+
+Thu Nov 9 15:38:37 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.h: Include unix.h if USE_MW_HEADERS, otherwise include
+ various original MPW include files (ioctl.h, etc).
+ (EIO): Define if not defined.
+ * sys/ioctl.h: Remove, not needed.
+
+Wed Oct 25 12:30:44 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.h: Don't include errno.h or ioctl.h.
+ (ENOENT, EACCES, ENOSYS): Define if not defined.
+ (fdopen): Declare if __STDC__.
+ (R_OK, W_OK, X_OK): Define if not defined.
+
+Tue Sep 26 14:57:21 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.h: New file, universally useful MPW host definitions.
+ Many of these used to live in bfd/hosts/mpw.h.
+ * grp.h: Remove RCS comment.
+ * sys/ioctl.h: Add a comment line.
+
+Wed Dec 14 13:12:14 1994 Stan Shebs <shebs@andros.cygnus.com>
+
+ * spin.h: New file, cursor spinning for progress.
+
+Thu Jun 30 15:32:07 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * fcntl.h (open): Allow optional third arg.
+
+Thu Apr 14 12:54:51 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * dir.h, dirent.h, fcntl.h, grp.h, pwd.h, stat.h: New files.
+ * sys/ioctl.h: New file.
+
+Mon Feb 21 09:44:45 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * sys/stat.h (struct stat): New field st_rsize.
+ (S_IFMT, etc): Use different bit positions.
+ (fstat): Add parameter names to prototype.
+
+Mon Jan 31 19:30:16 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * README: New file.
+ * utime.h, varargs.h: New files, simulated Posix.
+ * sys/{file,param,resource,stat,time,types}.h: New files, more
+ simulated Posix.
+
+
diff --git a/include/mpw/README b/include/mpw/README
new file mode 100644
index 00000000000..10e92de79f6
--- /dev/null
+++ b/include/mpw/README
@@ -0,0 +1 @@
+This is a collection of include files that help imitate Posix in MPW.
diff --git a/include/mpw/dir.h b/include/mpw/dir.h
new file mode 100644
index 00000000000..e6ccd2d5922
--- /dev/null
+++ b/include/mpw/dir.h
@@ -0,0 +1,23 @@
+/* The <dir.h> header gives the layout of a directory. */
+
+#pragma once
+
+#ifndef _DIR_H
+#define _DIR_H
+
+#ifndef _TYPES_H /* not quite right */
+#include <sys/types.h>
+#endif
+
+#define DIRBLKSIZ 512 /* size of directory block */
+
+#ifndef DIRSIZ
+#define DIRSIZ 14
+#endif
+
+struct direct {
+ ino_t d_ino;
+ char d_name[DIRSIZ];
+};
+
+#endif /* _DIR_H */
diff --git a/include/mpw/dirent.h b/include/mpw/dirent.h
new file mode 100644
index 00000000000..38000b2c5f3
--- /dev/null
+++ b/include/mpw/dirent.h
@@ -0,0 +1,31 @@
+#ifndef __dirent_h
+#define __dirent_h
+
+#include "sys/dir.h"
+
+struct dirent {
+ long d_ino; /* inode number of entry */
+ off_t d_off; /* offset of disk directory entry */
+ unsigned short d_reclen; /* length of this record */
+ char d_name[1]; /* name of file */
+};
+
+/*
+#define DIRENTBASESIZE \
+ (((struct dirent *) 0)->d_name - (char *) 0)
+#define DIRENTSIZE(namelen) \
+ ((DIRENTBASESIZE + (namelen) + NBPW) & ~(NBPW - 1))
+*/
+
+/* from Mips posix/dirent.h */
+
+/*
+#undef rewinddir
+*/
+
+extern DIR *opendir();
+extern struct dirent *readdir();
+extern void rewinddir();
+extern int closedir();
+
+#endif /* ! __dirent_h */
diff --git a/include/mpw/fcntl.h b/include/mpw/fcntl.h
new file mode 100644
index 00000000000..30999b4b17d
--- /dev/null
+++ b/include/mpw/fcntl.h
@@ -0,0 +1,124 @@
+/*
+ * FCntl.h -- faccess(), fcntl(), and open() mode flags
+ *
+ * Portions copyright American Telephone & Telegraph
+ * Used with permission, Apple Computer Inc. (1985,1988,1990,1992)
+ * All rights reserved.
+ */
+
+#ifndef __FCNTL__
+#define __FCNTL__
+
+#ifndef __TYPES__
+#include <Types.h>
+#endif
+
+/*
+ * For use by lseek():
+ */
+
+#ifndef __STDIO__ /* these defns exactly paralled in StdIO.h for fseek() */
+#define SEEK_CUR 1
+#define SEEK_END 2
+#define SEEK_SET 0
+#endif
+
+/*
+ * faccess() commands; for general use
+ */
+ /* 'd' => "directory" ops */
+#define F_DELETE (('d'<<8)|0x01)
+#define F_RENAME (('d'<<8)|0x02)
+
+/*
+ * more faccess() commands; for use only by MPW tools
+ */
+
+#define F_OPEN (('d'<<8)|0x00) /* reserved for operating system use */
+ /* 'e' => "editor" ops */
+#define F_GTABINFO (('e'<<8)|0x00) /* get tab offset for file */
+#define F_STABINFO (('e'<<8)|0x01) /* set " " " " */
+#define F_GFONTINFO (('e'<<8)|0x02) /* get font number and size for file */
+#define F_SFONTINFO (('e'<<8)|0x03) /* set " " " " " " */
+#define F_GPRINTREC (('e'<<8)|0x04) /* get print record for file */
+#define F_SPRINTREC (('e'<<8)|0x05) /* set " " " " */
+#define F_GSELINFO (('e'<<8)|0x06) /* get selection information for file */
+#define F_SSELINFO (('e'<<8)|0x07) /* set " " " " */
+#define F_GWININFO (('e'<<8)|0x08) /* get current window position */
+#define F_SWININFO (('e'<<8)|0x09) /* set " " " */
+#define F_GSCROLLINFO (('e'<<8)|0x0A) /* get scroll information */
+#define F_SSCROLLINFO (('e'<<8)|0x0B) /* set " " */
+#define F_GMARKER (('e'<<8)|0x0D) /* Get Marker */
+#define F_SMARKER (('e'<<8)|0x0C) /* Set " */
+#define F_GSAVEONCLOSE (('e'<<8)|0x0F) /* Get Save on close */
+#define F_SSAVEONCLOSE (('e'<<8)|0x0E) /* Set " " " */
+
+/*
+ * argument structures used by various faccess() commands
+ */
+
+struct MarkElement {
+ int start; /* start position of mark */
+ int end; /* end position */
+ unsigned char charCount; /* number of chars in mark name */
+ char name[64]; /* mark name */
+} ; /* note: marker names may be up to 64 characters long */
+
+#ifndef __cplusplus
+typedef struct MarkElement MarkElement;
+#endif
+
+struct SelectionRecord {
+ long startingPos;
+ long endingPos;
+ long displayTop;
+};
+
+#ifndef __cplusplus
+typedef struct SelectionRecord SelectionRecord;
+#endif
+
+
+/*
+ * Mode values accessible to open()
+ */
+#define O_RDONLY 0 /* Bits 0 and 1 are used internally */
+#define O_WRONLY 1 /* Values 0..2 are historical */
+#define O_RDWR 2 /* NOTE: it goes 0, 1, 2, *!* 8, 16, 32, ... */
+#define O_APPEND (1<< 3) /* append (writes guaranteed at the end) */
+#define O_RSRC (1<< 4) /* Open the resource fork */
+#define O_ALIAS (1<< 5) /* Open alias file */
+#define O_CREAT (1<< 8) /* Open with file create */
+#define O_TRUNC (1<< 9) /* Open with truncation */
+#define O_EXCL (1<<10) /* w/ O_CREAT: Exclusive "create-only" */
+#define O_BINARY (1<<11) /* Open as a binary stream */
+#define O_NRESOLVE (1<<14) /* Don't resolve any aliases */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * function prototypes
+ */
+int close(int);
+int creat(const char*);
+int dup(int filedes); /* OBSOLETE: fcntl(filedes, F_DUPFD, 0) is preferred */
+int faccess(char*, unsigned int, long*);
+int fcntl(int, unsigned int, int);
+long lseek(int, long, int);
+int open(const char*, int, ...);
+int read(int, char*, unsigned);
+int unlink(char*);
+int write(int, const char*, unsigned);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * fcntl() commands
+ */
+#define F_DUPFD 0 /* Duplicate files (file descriptor) */
+
+#endif __FCNTL__
diff --git a/include/mpw/grp.h b/include/mpw/grp.h
new file mode 100644
index 00000000000..faf2c6a6be9
--- /dev/null
+++ b/include/mpw/grp.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "sys/types.h"
+
+struct group {
+ char *gr_name;
+ gid_t gr_gid;
+ char *gr_passwd;
+ char **gr_mem;
+};
diff --git a/include/mpw/mpw.h b/include/mpw/mpw.h
new file mode 100644
index 00000000000..58702e725ff
--- /dev/null
+++ b/include/mpw/mpw.h
@@ -0,0 +1,130 @@
+/* Mac MPW host-specific definitions. */
+
+#ifndef __INCLUDE_MPW_H
+#define __INCLUDE_MPW_H
+
+#ifndef MPW
+#define MPW
+#endif
+
+/* MPW C is basically ANSI, but doesn't actually enable __STDC__,
+ nor does it allow __STDC__ to be #defined. */
+
+#ifndef ALMOST_STDC
+#define ALMOST_STDC
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define HAVE_TIME_T_IN_TIME_H 1
+
+#define HAVE_STDLIB_H 1
+
+#define HAVE_ERRNO_H 1
+
+#define HAVE_STDDEF_H 1
+
+#define HAVE_STRING_H 1
+
+#define HAVE_STDARG_H 1
+
+#define HAVE_VPRINTF 1
+
+#ifdef USE_MW_HEADERS
+
+#include <unix.h>
+
+#else
+
+#include <fcntl.h>
+#include <ioctl.h>
+#include <sys/stat.h>
+
+#define HAVE_FCNTL_H 1
+
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
+#endif
+
+#ifndef fileno
+#define fileno(fp) ((fp)->_file)
+#endif
+
+/* stdio.h does not define this if __STDC__, so define here. */
+
+#ifdef __STDC__
+FILE *fdopen(int fildes, const char *mode);
+#endif
+
+#endif /* USE_MW_HEADERS */
+
+/* Add ersatz definitions, for systems that lack them. */
+
+#ifndef EIO
+#define EIO 96
+#endif
+#ifndef ENOENT
+#define ENOENT 97
+#endif
+#ifndef EACCES
+#define EACCES 98
+#endif
+#ifndef ENOSYS
+#define ENOSYS 99
+#endif
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#endif
+
+/* Binary files have different characteristics; for instance, no cr/nl
+ translation. */
+
+#define USE_BINARY_FOPEN
+
+#include <spin.h>
+
+#ifdef MPW_C
+#undef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((int)(P))
+#undef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((char *)(P))
+#endif /* MPW_C */
+
+#define NO_FCNTL
+
+int fstat ();
+
+FILE *mpw_fopen ();
+int mpw_fseek ();
+int mpw_fread ();
+int mpw_fwrite ();
+int mpw_access ();
+int mpw_open ();
+int mpw_creat ();
+void mpw_abort (void);
+
+/* Map these standard functions to improved versions in libiberty. */
+
+#define fopen mpw_fopen
+#define fseek mpw_fseek
+#define fread mpw_fread
+#define fwrite mpw_fwrite
+#define open mpw_open
+#define access mpw_access
+#define creat mpw_creat
+#define abort mpw_abort
+
+#define POSIX_UTIME
+
+#define LOSING_TOTALLY
+
+/* Define this so that files will be closed before being unlinked. */
+
+#define CLOSE_BEFORE_UNLINK
+
+#endif /* __INCLUDE_MPW_H */
diff --git a/include/mpw/pwd.h b/include/mpw/pwd.h
new file mode 100644
index 00000000000..2d4fb70401a
--- /dev/null
+++ b/include/mpw/pwd.h
@@ -0,0 +1,15 @@
+#ifndef __pwd_h
+#define __pwd_h
+
+#include <sys/types.h>
+
+struct passwd {
+ char *pw_name;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char *pw_dir;
+ char *pw_shell;
+ char *pw_passwd;
+};
+
+#endif /* ! __pwd_h */
diff --git a/include/mpw/spin.h b/include/mpw/spin.h
new file mode 100644
index 00000000000..867d14502c0
--- /dev/null
+++ b/include/mpw/spin.h
@@ -0,0 +1,64 @@
+/* Progress macros that use SpinCursor in MPW.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _SPIN_H
+#define _SPIN_H
+
+/* For MPW, progress macros just need to "spin the cursor" frequently,
+ preferably several times per second on a 68K Mac. */
+
+/* In order to determine if we're meeting the goal, define this macro
+ and information about frequency of spinning will be collected and
+ displayed. */
+
+#define SPIN_MEASUREMENT
+
+#include <CursorCtl.h>
+
+/* Programs use this macro to indicate the start of a lengthy
+ activity. STR identifies the particular activity, while N
+ indicates the expected duration, in unspecified units. If N is
+ zero, then the expected time to completion is unknown. */
+
+#undef START_PROGRESS
+#define START_PROGRESS(STR,N) mpw_start_progress (STR, N, __FILE__, __LINE__);
+
+/* Programs use this macro to indicate that progress has been made on a
+ lengthy activity. */
+
+#undef PROGRESS
+#ifdef SPIN_MEASUREMENT
+#define PROGRESS(X) mpw_progress_measured (X, __FILE__, __LINE__);
+#else
+#define PROGRESS(X) mpw_progress (X);
+#endif
+
+/* Programs use this macro to indicate the end of a lengthy activity.
+ STR must match a STR passed to START_PROGRESS previously. */
+
+#undef END_PROGRESS
+#define END_PROGRESS(STR) mpw_end_progress (STR, __FILE__, __LINE__);
+
+extern void mpw_start_progress (char *, int, char *, int);
+
+extern void mpw_progress (int);
+
+extern void mpw_progress_measured (int, char *, int);
+
+extern void mpw_end_progress (char *, char *, int);
+
+#endif /* _SPIN_H */
diff --git a/include/mpw/stat.h b/include/mpw/stat.h
new file mode 100644
index 00000000000..057b8d53113
--- /dev/null
+++ b/include/mpw/stat.h
@@ -0,0 +1,75 @@
+/* The <sys/stat.h> header defines a struct that is used in the stat() and
+ * fstat functions. The information in this struct comes from the i-node of
+ * some file. These calls are the only approved way to inspect i-nodes.
+ */
+
+#ifndef _STAT_H
+#define _STAT_H
+
+#ifndef _TYPES_H /* not quite right */
+#include <sys/types.h>
+#endif
+
+struct stat {
+ dev_t st_dev; /* major/minor device number */
+ ino_t st_ino; /* i-node number */
+ mode_t st_mode; /* file mode, protection bits, etc. */
+ short int st_nlink; /* # links; TEMPORARY HACK: should be nlink_t*/
+ uid_t st_uid; /* uid of the file's owner */
+ short int st_gid; /* gid; TEMPORARY HACK: should be gid_t */
+ dev_t st_rdev;
+ off_t st_size; /* file size */
+ time_t st_atime; /* time of last access */
+ time_t st_mtime; /* time of last data modification */
+ time_t st_ctime; /* time of last file status change */
+};
+
+/* Traditional mask definitions for st_mode. */
+#define S_IFMT 0170000 /* type of file */
+#define S_IFREG 0100000 /* regular */
+#define S_IFBLK 0060000 /* block special */
+#define S_IFDIR 0040000 /* directory */
+#define S_IFCHR 0020000 /* character special */
+#define S_IFIFO 0010000 /* this is a FIFO */
+#define S_ISUID 0004000 /* set user id on execution */
+#define S_ISGID 0002000 /* set group id on execution */
+ /* next is reserved for future use */
+#define S_ISVTX 01000 /* save swapped text even after use */
+
+/* POSIX masks for st_mode. */
+#define S_IRWXU 00700 /* owner: rwx------ */
+#define S_IRUSR 00400 /* owner: r-------- */
+#define S_IWUSR 00200 /* owner: -w------- */
+#define S_IXUSR 00100 /* owner: --x------ */
+
+#define S_IRWXG 00070 /* group: ---rwx--- */
+#define S_IRGRP 00040 /* group: ---r----- */
+#define S_IWGRP 00020 /* group: ----w---- */
+#define S_IXGRP 00010 /* group: -----x--- */
+
+#define S_IRWXO 00007 /* others: ------rwx */
+#define S_IROTH 00004 /* others: ------r-- */
+#define S_IWOTH 00002 /* others: -------w- */
+#define S_IXOTH 00001 /* others: --------x */
+
+/* The following macros test st_mode (from POSIX Sec. 5.6.1.1. */
+#define S_ISREG(m) ((m & S_IFMT) == S_IFREG) /* is a reg file */
+#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) /* is a directory */
+#define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR) /* is a char spec */
+#define S_ISBLK(m) ((m & S_IFMT) == S_IFBLK) /* is a block spec */
+#define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO) /* is a pipe/FIFO */
+
+
+/* Function Prototypes. */
+#ifndef _ANSI_H
+#include <ansi.h>
+#endif
+
+_PROTOTYPE( int chmod, (const char *_path, int _mode) );
+_PROTOTYPE( int fstat, (int _fildes, struct stat *_buf) );
+_PROTOTYPE( int mkdir, (const char *_path, int _mode) );
+_PROTOTYPE( int mkfifo, (const char *_path, int _mode) );
+_PROTOTYPE( int stat , (const char *_path, struct stat *_buf) );
+_PROTOTYPE( mode_t umask, (int _cmask) );
+
+#endif /* _STAT_H */
diff --git a/include/mpw/sys/file.h b/include/mpw/sys/file.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/include/mpw/sys/file.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/mpw/sys/param.h b/include/mpw/sys/param.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/include/mpw/sys/param.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/mpw/sys/resource.h b/include/mpw/sys/resource.h
new file mode 100644
index 00000000000..d39439d61d5
--- /dev/null
+++ b/include/mpw/sys/resource.h
@@ -0,0 +1,9 @@
+#ifndef __SYS_RESOURCE_H__
+#define __SYS_RESOURCE_H__
+
+struct rusage {
+ struct timeval ru_utime;
+ struct timeval ru_stime;
+};
+
+#endif /* __SYS_RESOURCE_H__ */
diff --git a/include/mpw/sys/stat.h b/include/mpw/sys/stat.h
new file mode 100644
index 00000000000..b65c72e10c6
--- /dev/null
+++ b/include/mpw/sys/stat.h
@@ -0,0 +1,44 @@
+/* Imitation sys/stat.h. */
+
+#ifndef __SYS_STAT_H__
+#define __SYS_STAT_H__
+
+#include <sys/types.h>
+#include <time.h>
+
+struct stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ short st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ off_t st_size;
+ off_t st_rsize;
+ time_t st_atime;
+ int st_spare1;
+ time_t st_mtime;
+ int st_spare2;
+ time_t st_ctime;
+ int st_spare3;
+ long st_blksize;
+ long st_blocks;
+ long st_spare4[2];
+};
+
+#define S_IFMT 0170000L
+#define S_IFDIR 0040000L
+#define S_IFREG 0100000L
+#define S_IREAD 0400
+#define S_IWRITE 0200
+#define S_IEXEC 0100
+
+#define S_IFIFO 010000 /* FIFO special */
+#define S_IFCHR 020000 /* character special */
+#define S_IFBLK 030000 /* block special */
+
+int stat (char *path, struct stat *buf);
+int fstat (int fd, struct stat *buf);
+
+#endif /* __SYS_STAT_H___ */
diff --git a/include/mpw/sys/time.h b/include/mpw/sys/time.h
new file mode 100644
index 00000000000..f9e485232a2
--- /dev/null
+++ b/include/mpw/sys/time.h
@@ -0,0 +1,13 @@
+/* Imitation sys/time.h. */
+
+#ifndef __SYS_TIME_H__
+#define __SYS_TIME_H__
+
+#include <time.h>
+
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+
+#endif /* __SYS_TIME_H__ */
diff --git a/include/mpw/sys/types.h b/include/mpw/sys/types.h
new file mode 100644
index 00000000000..d7d9c9f44ba
--- /dev/null
+++ b/include/mpw/sys/types.h
@@ -0,0 +1,15 @@
+/* Imitation sys/types.h. */
+
+#ifndef __SYS_TYPES_H__
+#define __SYS_TYPES_H__
+
+#include <Types.h>
+
+typedef short dev_t;
+typedef short ino_t;
+typedef unsigned short mode_t;
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+typedef long off_t;
+
+#endif /* __SYS_TYPES_H__ */
diff --git a/include/mpw/utime.h b/include/mpw/utime.h
new file mode 100644
index 00000000000..e8bf66f2ba5
--- /dev/null
+++ b/include/mpw/utime.h
@@ -0,0 +1,7 @@
+
+struct utimbuf {
+ time_t actime;
+ time_t modtime;
+};
+
+int utime (char *, struct utimbuf *);
diff --git a/include/mpw/varargs.h b/include/mpw/varargs.h
new file mode 100644
index 00000000000..acb9e4504a2
--- /dev/null
+++ b/include/mpw/varargs.h
@@ -0,0 +1,9 @@
+/* varargs.h. */
+#ifndef __va_list__
+#define __va_list__
+typedef char *va_list;
+#endif
+#define va_dcl int va_alist;
+#define va_start(list) list = (char *) &va_alist
+#define va_end(list)
+#define va_arg(list,mode) ((mode *)(list += sizeof(mode)))[-1]
diff --git a/include/nlm/ChangeLog b/include/nlm/ChangeLog
new file mode 100644
index 00000000000..d9ea3d09e0a
--- /dev/null
+++ b/include/nlm/ChangeLog
@@ -0,0 +1,83 @@
+Fri May 6 13:31:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * external.h (nlmNAME(External_Custom_Header)): Add length,
+ dataOffset, and dataStamp field.
+ (nlmNAME(External_Cygnus_Ext_Header)): Remove.
+ * internal.h (Nlm_Internal_Custom_Header): Add hdrLength,
+ dataOffset, dataStamp and hdr fields.
+
+Fri Apr 22 11:12:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * external.h (struct nlmNAME(external_cygnus_ext_header)): Rename
+ from nlmNAME(external_cygnus_section_header). Change stamp field
+ to 8 bytes. Add bytes field.
+ * internal.h (nlm_internal_cygnus_ext_header): Rename from
+ nlm_internal_cygnus_section_header. Change stamp field to 8
+ bytes.
+
+Thu Apr 21 11:57:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * internal.h (struct nlm_internal_cygnus_section_header): Define.
+ * external.h (struct nlmNAME(external_cygnus_section_header):
+ Define.
+
+Wed Apr 20 14:27:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * internal.h (struct nlm_internal_custom_header): Remove
+ debugRecOffset and debugRecLength fields. Add data field.
+ * external.h (struct nlmNAME(external_custom_header)): Remove
+ debugRecOffset and debugRecLength fields.
+
+Mon Feb 7 08:28:40 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * internal.h: Change HOST_64_BIT to BFD_HOST_64_BIT.
+
+Thu Dec 2 14:14:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * alpha-ext.h: New file describing formats of information in Alpha
+ NetWare files.
+ * common.h: Define some non-external Alpha information.
+
+Wed Nov 17 17:38:58 1993 Sean Eric Fagan (sef@cygnus.com)
+
+ * external.h: Don't define external_fixed_header here.
+ * i386-ext.h, sparc32-ext.h: New header files to define
+ external_fixed_header for particular CPU's.
+
+Wed Oct 27 11:45:56 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * internal.h (Nlm_Internal_Extended_Header): Added fields
+ sharedDebugRecordOffset and sharedDebugRecordCount.
+ * external.h (NlmNAME(External_Extended_Header)): Likewise.
+
+ * common.h (NLM_SIGNATURE): Do not define (it's different for each
+ backend).
+
+Tue Aug 31 13:24:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * internal.h: Change length fields of type char to type unsigned
+ char.
+
+Sat Jul 31 02:12:14 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * common.h (NLM_HIBIT, NLM_HEADER_VERSION): Define.
+
+Thu Jul 22 16:09:47 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * common.h (NLM_CAT*, NLM_ARCH_SIZE, NLM_TARGET_LONG_SIZE,
+ NLM_TARGET_ADDRESS_SIZE, NLM_NAME, NlmNAME, nlmNAME): New
+ macros.
+ * external.h (TARGET_LONG_SIZE, TARGET_ADDRESS_SIZE): Remove
+ macros, convert usages to NLM_ equivalents.
+ * external.h: Use nlmNAME and NlmNAME macros to derive both
+ 32 and 64 bit versions.
+
+Mon Jul 19 22:12:40 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * (common.h, external.h, internal.h): New files for NLM/NetWare
+ support.
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/include/nlm/alpha-ext.h b/include/nlm/alpha-ext.h
new file mode 100644
index 00000000000..37199dd1dc0
--- /dev/null
+++ b/include/nlm/alpha-ext.h
@@ -0,0 +1,166 @@
+/* Alpha NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+ By Ian Lance Taylor, Cygnus Support
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* An Alpha NLM starts with an instance of this structure. */
+
+struct nlm32_alpha_external_prefix_header
+{
+ /* Magic number. Must be NLM32_ALPHA_MAGIC. */
+ unsigned char magic[4];
+ /* Format descriptor. Current value is 2. */
+ unsigned char format[4];
+ /* Size of prefix header. */
+ unsigned char size[4];
+ /* Padding. */
+ unsigned char pad1[4];
+ /* More fields may be added later, supposedly. */
+};
+
+/* The external format of an Alpha NLM reloc. This is the same as an
+ Alpha ECOFF reloc. */
+
+struct nlm32_alpha_external_reloc
+{
+ unsigned char r_vaddr[8];
+ unsigned char r_symndx[4];
+ unsigned char r_bits[4];
+};
+
+/* Constants to unpack the r_bits field of a reloc. */
+
+#define RELOC_BITS0_TYPE_LITTLE 0xff
+#define RELOC_BITS0_TYPE_SH_LITTLE 0
+
+#define RELOC_BITS1_EXTERN_LITTLE 0x01
+
+#define RELOC_BITS1_OFFSET_LITTLE 0x7e
+#define RELOC_BITS1_OFFSET_SH_LITTLE 1
+
+#define RELOC_BITS1_RESERVED_LITTLE 0x80
+#define RELOC_BITS1_RESERVED_SH_LITTLE 7
+#define RELOC_BITS2_RESERVED_LITTLE 0xff
+#define RELOC_BITS2_RESERVED_SH_LEFT_LITTLE 1
+#define RELOC_BITS3_RESERVED_LITTLE 0x03
+#define RELOC_BITS3_RESERVED_SH_LEFT_LITTLE 9
+
+#define RELOC_BITS3_SIZE_LITTLE 0xfc
+#define RELOC_BITS3_SIZE_SH_LITTLE 2
+
+/* The external format of the fixed header. */
+
+typedef struct nlm32_alpha_external_fixed_header
+{
+
+ /* The signature field identifies the file as an NLM. It must contain
+ the signature string, which depends upon the NLM target. */
+
+ unsigned char signature[24];
+
+ /* The version of the header. At this time, the highest version number
+ is 4. */
+
+ unsigned char version[4];
+
+ /* The name of the module, which must be a DOS name (1-8 characters followed
+ by a period and a 1-3 character extension). The first byte is the byte
+ length of the name and the last byte is a null terminator byte. This
+ field is fixed length, and any unused bytes should be null bytes. The
+ value is set by the OUTPUT keyword to NLMLINK. */
+
+ unsigned char moduleName[14];
+
+ /* Padding to make it come out correct. */
+
+ unsigned char pad1[2];
+
+ /* The byte offset of the code image from the start of the file. */
+
+ unsigned char codeImageOffset[4];
+
+ /* The size of the code image, in bytes. */
+
+ unsigned char codeImageSize[4];
+
+ /* The byte offset of the data image from the start of the file. */
+
+ unsigned char dataImageOffset[4];
+
+ /* The size of the data image, in bytes. */
+
+ unsigned char dataImageSize[4];
+
+ /* The size of the uninitialized data region that the loader is to be
+ allocated at load time. Uninitialized data follows the initialized
+ data in the NLM address space. */
+
+ unsigned char uninitializedDataSize[4];
+
+ /* The byte offset of the custom data from the start of the file. The
+ custom data is set by the CUSTOM keyword to NLMLINK. It is possible
+ for this to be EOF if there is no custom data. */
+
+ unsigned char customDataOffset[4];
+
+ /* The size of the custom data, in bytes. */
+
+ unsigned char customDataSize[4];
+
+ /* The byte offset of the module dependencies from the start of the file.
+ The module dependencies are determined by the MODULE keyword in
+ NLMLINK. */
+
+ unsigned char moduleDependencyOffset[4];
+
+ /* The number of module dependencies at the moduleDependencyOffset. */
+
+ unsigned char numberOfModuleDependencies[4];
+
+ /* The byte offset of the relocation fixup data from the start of the file */
+
+ unsigned char relocationFixupOffset[4];
+
+ unsigned char numberOfRelocationFixups[4];
+
+ unsigned char externalReferencesOffset[4];
+
+ unsigned char numberOfExternalReferences[4];
+
+ unsigned char publicsOffset[4];
+
+ unsigned char numberOfPublics[4];
+
+ /* The byte offset of the internal debug info from the start of the file.
+ It is possible for this to be EOF if there is no debug info. */
+
+ unsigned char debugInfoOffset[4];
+
+ unsigned char numberOfDebugRecords[4];
+
+ unsigned char codeStartOffset[4];
+
+ unsigned char exitProcedureOffset[4];
+
+ unsigned char checkUnloadProcedureOffset[4];
+
+ unsigned char moduleType[4];
+
+ unsigned char flags[4];
+
+} Nlm32_alpha_External_Fixed_Header;
diff --git a/include/nlm/common.h b/include/nlm/common.h
new file mode 100644
index 00000000000..e96550a92f6
--- /dev/null
+++ b/include/nlm/common.h
@@ -0,0 +1,124 @@
+/* NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This file is part of NLM support for BFD, and contains the portions
+ that are common to both the internal and external representations. */
+
+/* Semi-portable string concatenation in cpp.
+ The NLM_CAT4 hack is to avoid a problem with some strict ANSI C
+ preprocessors. The problem is, "32_" or "64_" are not a valid
+ preprocessing tokens, and we don't want extra underscores (e.g.,
+ "nlm_32_"). The XNLM_CAT2 macro will cause the inner NLM_CAT macros
+ to be evaluated first, producing still-valid pp-tokens. Then the
+ final concatenation can be done. (Sigh.) */
+
+#ifdef SABER
+# define NLM_CAT(a,b) a##b
+# define NLM_CAT3(a,b,c) a##b##c
+# define NLM_CAT4(a,b,c,d) a##b##c##d
+#else
+# ifdef __STDC__
+# define NLM_CAT(a,b) a##b
+# define NLM_CAT3(a,b,c) a##b##c
+# define XNLM_CAT2(a,b) NLM_CAT(a,b)
+# define NLM_CAT4(a,b,c,d) XNLM_CAT2(NLM_CAT(a,b),NLM_CAT(c,d))
+# else
+# define NLM_CAT(a,b) a/**/b
+# define NLM_CAT3(a,b,c) a/**/b/**/c
+# define NLM_CAT4(a,b,c,d) a/**/b/**/c/**/d
+# endif
+#endif
+
+/* If NLM_ARCH_SIZE is not defined, default to 32. NLM_ARCH_SIZE is
+ optionally defined by the application. */
+
+#ifndef NLM_ARCH_SIZE
+# define NLM_ARCH_SIZE 32
+#endif
+
+#if NLM_ARCH_SIZE == 32
+# define NLM_TARGET_LONG_SIZE 4
+# define NLM_TARGET_ADDRESS_SIZE 4
+# define NLM_NAME(x,y) NLM_CAT4(x,32,_,y)
+# define NLM_HIBIT (((bfd_vma) 1) << 31)
+#endif
+#if NLM_ARCH_SIZE == 64
+# define NLM_TARGET_LONG_SIZE 8
+# define NLM_TARGET_ADDRESS_SIZE 8
+# define NLM_NAME(x,y) NLM_CAT4(x,64,_,y)
+# define NLM_HIBIT (((bfd_vma) 1) << 63)
+#endif
+
+#define NlmNAME(X) NLM_NAME(Nlm,X)
+#define nlmNAME(X) NLM_NAME(nlm,X)
+
+/* Give names to things that should not change. */
+
+#define NLM_MAX_DESCRIPTION_LENGTH 127
+#define NLM_MAX_SCREEN_NAME_LENGTH 71
+#define NLM_MAX_THREAD_NAME_LENGTH 71
+#define NLM_MAX_COPYRIGHT_MESSAGE_LENGTH 255
+#define NLM_OTHER_DATA_LENGTH 400 /* FIXME */
+#define NLM_OLD_THREAD_NAME_LENGTH 5
+#define NLM_SIGNATURE_SIZE 24
+#define NLM_HEADER_VERSION 4
+#define NLM_MODULE_NAME_SIZE 14
+#define NLM_DEFAULT_STACKSIZE (8 * 1024)
+
+/* Alpha information. This should probably be in a separate Alpha
+ header file, but it can't go in alpha-ext.h because some of it is
+ needed by nlmconv.c. */
+
+/* Magic number in Alpha prefix header. */
+#define NLM32_ALPHA_MAGIC (0x83561840)
+
+/* The r_type field in an Alpha reloc is one of the following values. */
+#define ALPHA_R_IGNORE 0
+#define ALPHA_R_REFLONG 1
+#define ALPHA_R_REFQUAD 2
+#define ALPHA_R_GPREL32 3
+#define ALPHA_R_LITERAL 4
+#define ALPHA_R_LITUSE 5
+#define ALPHA_R_GPDISP 6
+#define ALPHA_R_BRADDR 7
+#define ALPHA_R_HINT 8
+#define ALPHA_R_SREL16 9
+#define ALPHA_R_SREL32 10
+#define ALPHA_R_SREL64 11
+#define ALPHA_R_OP_PUSH 12
+#define ALPHA_R_OP_STORE 13
+#define ALPHA_R_OP_PSUB 14
+#define ALPHA_R_OP_PRSHIFT 15
+#define ALPHA_R_GPVALUE 16
+#define ALPHA_R_NW_RELOC 250
+
+/* A local reloc, other than ALPHA_R_GPDISP or ALPHA_R_IGNORE, must be
+ against one of these symbol indices. */
+#define ALPHA_RELOC_SECTION_TEXT 1
+#define ALPHA_RELOC_SECTION_DATA 3
+
+/* An ALPHA_R_NW_RELOC has one of these values in the size field. If
+ it is SETGP, the r_vaddr field holds the GP value to use. If it is
+ LITA, the r_vaddr field holds the address of the .lita section and
+ the r_symndx field holds the size of the .lita section. */
+#define ALPHA_R_NW_RELOC_SETGP 1
+#define ALPHA_R_NW_RELOC_LITA 2
diff --git a/include/nlm/external.h b/include/nlm/external.h
new file mode 100644
index 00000000000..f77a5bb3dda
--- /dev/null
+++ b/include/nlm/external.h
@@ -0,0 +1,174 @@
+/* NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This file is part of NLM support for BFD, and contains the portions
+ that describe how NLM is represented externally by the BFD library.
+ I.E. it describes the in-file representation of NLM. It requires
+ the nlm/common.h file which contains the portions that are common to
+ both the internal and external representations.
+
+ Note that an NLM header consists of three parts:
+
+ (1) A fixed length header that has specific fields of known length,
+ at specific offsets in the file.
+
+ (2) A variable length header that has specific fields in a specific
+ order, but some fields may be variable length.
+
+ (3) A auxiliary header that has various optional fields in no specific
+ order. There is no way to identify the end of the auxiliary headers
+ except by finding a header without a recognized 'stamp'.
+
+ The exact format of the fixed length header unfortunately varies
+ from one NLM target to another, due to padding. Each target
+ defines the correct external format in a separate header file.
+
+*/
+
+/* NLM Header */
+
+/* The version header is one of the optional auxiliary headers and
+ follows the fixed length and variable length NLM headers. */
+
+typedef struct nlmNAME(external_version_header)
+{
+
+ /* The header is recognized by "VeRsIoN#" in the stamp field. */
+ char stamp[8];
+
+ unsigned char majorVersion[NLM_TARGET_LONG_SIZE];
+
+ unsigned char minorVersion[NLM_TARGET_LONG_SIZE];
+
+ unsigned char revision[NLM_TARGET_LONG_SIZE];
+
+ unsigned char year[NLM_TARGET_LONG_SIZE];
+
+ unsigned char month[NLM_TARGET_LONG_SIZE];
+
+ unsigned char day[NLM_TARGET_LONG_SIZE];
+
+} NlmNAME(External_Version_Header);
+
+
+typedef struct nlmNAME(external_copyright_header)
+{
+
+ /* The header is recognized by "CoPyRiGhT=" in the stamp field. */
+
+ char stamp[10];
+
+ unsigned char copyrightMessageLength[1];
+
+ /* There is a variable length field here called 'copyrightMessage'
+ that is the length specified by copyrightMessageLength. */
+
+} NlmNAME(External_Copyright_Header);
+
+
+typedef struct nlmNAME(external_extended_header)
+{
+
+ /* The header is recognized by "MeSsAgEs" in the stamp field. */
+
+ char stamp[8];
+
+ unsigned char languageID[NLM_TARGET_LONG_SIZE];
+
+ unsigned char messageFileOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char messageFileLength[NLM_TARGET_LONG_SIZE];
+
+ unsigned char messageCount[NLM_TARGET_LONG_SIZE];
+
+ unsigned char helpFileOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char helpFileLength[NLM_TARGET_LONG_SIZE];
+
+ unsigned char RPCDataOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char RPCDataLength[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedCodeOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedCodeLength[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedDataOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedDataLength[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedRelocationFixupOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedRelocationFixupCount[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedExternalReferenceOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedExternalReferenceCount[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedPublicsOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedPublicsCount[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedDebugRecordOffset[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedDebugRecordCount[NLM_TARGET_LONG_SIZE];
+
+ unsigned char sharedInitializationOffset[NLM_TARGET_ADDRESS_SIZE];
+
+ unsigned char SharedExitProcedureOffset[NLM_TARGET_ADDRESS_SIZE];
+
+ unsigned char productID[NLM_TARGET_LONG_SIZE];
+
+ unsigned char reserved0[NLM_TARGET_LONG_SIZE];
+
+ unsigned char reserved1[NLM_TARGET_LONG_SIZE];
+
+ unsigned char reserved2[NLM_TARGET_LONG_SIZE];
+
+ unsigned char reserved3[NLM_TARGET_LONG_SIZE];
+
+ unsigned char reserved4[NLM_TARGET_LONG_SIZE];
+
+ unsigned char reserved5[NLM_TARGET_LONG_SIZE];
+
+} NlmNAME(External_Extended_Header);
+
+
+typedef struct nlmNAME(external_custom_header)
+{
+
+ /* The header is recognized by "CuStHeAd" in the stamp field. */
+ char stamp[8];
+
+ /* Length of this header. */
+ unsigned char length[NLM_TARGET_LONG_SIZE];
+
+ /* Offset to data. */
+ unsigned char dataOffset[NLM_TARGET_LONG_SIZE];
+
+ /* Length of data. */
+ unsigned char dataLength[NLM_TARGET_LONG_SIZE];
+
+ /* Stamp for this customer header--we recognize "CyGnUsEx". */
+ char dataStamp[8];
+
+} NlmNAME(External_Custom_Header);
diff --git a/include/nlm/i386-ext.h b/include/nlm/i386-ext.h
new file mode 100644
index 00000000000..d33ad2da770
--- /dev/null
+++ b/include/nlm/i386-ext.h
@@ -0,0 +1,116 @@
+/* i386 NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* The external format of the fixed header. */
+
+typedef struct nlm32_i386_external_fixed_header
+{
+
+ /* The signature field identifies the file as an NLM. It must contain
+ the signature string, which depends upon the NLM target. */
+
+ unsigned char signature[24];
+
+ /* The version of the header. At this time, the highest version number
+ is 4. */
+
+ unsigned char version[4];
+
+ /* The name of the module, which must be a DOS name (1-8 characters followed
+ by a period and a 1-3 character extension). The first byte is the byte
+ length of the name and the last byte is a null terminator byte. This
+ field is fixed length, and any unused bytes should be null bytes. The
+ value is set by the OUTPUT keyword to NLMLINK. */
+
+ unsigned char moduleName[14];
+
+ /* The byte offset of the code image from the start of the file. */
+
+ unsigned char codeImageOffset[4];
+
+ /* The size of the code image, in bytes. */
+
+ unsigned char codeImageSize[4];
+
+ /* The byte offset of the data image from the start of the file. */
+
+ unsigned char dataImageOffset[4];
+
+ /* The size of the data image, in bytes. */
+
+ unsigned char dataImageSize[4];
+
+ /* The size of the uninitialized data region that the loader is to be
+ allocated at load time. Uninitialized data follows the initialized
+ data in the NLM address space. */
+
+ unsigned char uninitializedDataSize[4];
+
+ /* The byte offset of the custom data from the start of the file. The
+ custom data is set by the CUSTOM keyword to NLMLINK. It is possible
+ for this to be EOF if there is no custom data. */
+
+ unsigned char customDataOffset[4];
+
+ /* The size of the custom data, in bytes. */
+
+ unsigned char customDataSize[4];
+
+ /* The byte offset of the module dependencies from the start of the file.
+ The module dependencies are determined by the MODULE keyword in
+ NLMLINK. */
+
+ unsigned char moduleDependencyOffset[4];
+
+ /* The number of module dependencies at the moduleDependencyOffset. */
+
+ unsigned char numberOfModuleDependencies[4];
+
+ /* The byte offset of the relocation fixup data from the start of the file */
+
+ unsigned char relocationFixupOffset[4];
+
+ unsigned char numberOfRelocationFixups[4];
+
+ unsigned char externalReferencesOffset[4];
+
+ unsigned char numberOfExternalReferences[4];
+
+ unsigned char publicsOffset[4];
+
+ unsigned char numberOfPublics[4];
+
+ /* The byte offset of the internal debug info from the start of the file.
+ It is possible for this to be EOF if there is no debug info. */
+
+ unsigned char debugInfoOffset[4];
+
+ unsigned char numberOfDebugRecords[4];
+
+ unsigned char codeStartOffset[4];
+
+ unsigned char exitProcedureOffset[4];
+
+ unsigned char checkUnloadProcedureOffset[4];
+
+ unsigned char moduleType[4];
+
+ unsigned char flags[4];
+
+} Nlm32_i386_External_Fixed_Header;
diff --git a/include/nlm/internal.h b/include/nlm/internal.h
new file mode 100644
index 00000000000..dd27dc407f5
--- /dev/null
+++ b/include/nlm/internal.h
@@ -0,0 +1,309 @@
+/* NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+ Written by Fred Fish @ Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This file is part of NLM support for BFD, and contains the portions
+ that describe how NLM is represented internally in the BFD library.
+ I.E. it describes the in-memory representation of NLM. It requires
+ the nlm/common.h file which contains the portions that are common to
+ both the internal and external representations. */
+
+#if 0
+
+/* Types used by various structures, functions, etc. */
+
+typedef unsigned long Nlm32_Addr; /* Unsigned program address */
+typedef unsigned long Nlm32_Off; /* Unsigned file offset */
+typedef long Nlm32_Sword; /* Signed large integer */
+typedef unsigned long Nlm32_Word; /* Unsigned large integer */
+typedef unsigned short Nlm32_Half; /* Unsigned medium integer */
+typedef unsigned char Nlm32_Char; /* Unsigned tiny integer */
+
+#ifdef BFD_HOST_64_BIT
+typedef unsigned BFD_HOST_64_BIT Nlm64_Addr;
+typedef unsigned BFD_HOST_64_BIT Nlm64_Off;
+typedef BFD_HOST_64_BIT Nlm64_Sxword;
+typedef unsigned BFD_HOST_64_BIT Nlm64_Xword;
+#endif
+typedef long Nlm64_Sword;
+typedef unsigned long Nlm64_Word;
+typedef unsigned short Nlm64_Half;
+
+#endif /* 0 */
+
+/* This structure contains the internal form of the portion of the NLM
+ header that is fixed length. */
+
+typedef struct nlm_internal_fixed_header
+{
+ /* The signature field identifies the file as an NLM. It must contain
+ the signature string, which depends upon the NLM target. */
+
+ char signature[NLM_SIGNATURE_SIZE];
+
+ /* The version of the header. At this time, the highest version number
+ is 4. */
+
+ long version;
+
+ /* The name of the module, which must be a DOS name (1-8 characters followed
+ by a period and a 1-3 character extension. The first byte is the byte
+ length of the name and the last byte is a null terminator byte. This
+ field is fixed length, and any unused bytes should be null bytes. The
+ value is set by the OUTPUT keyword to NLMLINK. */
+
+ char moduleName[NLM_MODULE_NAME_SIZE];
+
+ /* The byte offset of the code image from the start of the file. */
+
+ file_ptr codeImageOffset;
+
+ /* The size of the code image, in bytes. */
+
+ bfd_size_type codeImageSize;
+
+ /* The byte offset of the data image from the start of the file. */
+
+ file_ptr dataImageOffset;
+
+ /* The size of the data image, in bytes. */
+
+ bfd_size_type dataImageSize;
+
+ /* The size of the uninitialized data region that the loader is to be
+ allocated at load time. Uninitialized data follows the initialized
+ data in the NLM address space. */
+
+ bfd_size_type uninitializedDataSize;
+
+ /* The byte offset of the custom data from the start of the file. The
+ custom data is set by the CUSTOM keyword to NLMLINK. */
+
+ file_ptr customDataOffset;
+
+ /* The size of the custom data, in bytes. */
+
+ bfd_size_type customDataSize;
+
+ /* The byte offset of the module dependencies from the start of the file.
+ The module dependencies are determined by the MODULE keyword in
+ NLMLINK. */
+
+ file_ptr moduleDependencyOffset;
+
+ /* The number of module dependencies at the moduleDependencyOffset. */
+
+ long numberOfModuleDependencies;
+
+ /* The byte offset of the relocation fixup data from the start of the file */
+
+ file_ptr relocationFixupOffset;
+ long numberOfRelocationFixups;
+ file_ptr externalReferencesOffset;
+ long numberOfExternalReferences;
+ file_ptr publicsOffset;
+ long numberOfPublics;
+ file_ptr debugInfoOffset;
+ long numberOfDebugRecords;
+ file_ptr codeStartOffset;
+ file_ptr exitProcedureOffset;
+ file_ptr checkUnloadProcedureOffset;
+ long moduleType;
+ long flags;
+} Nlm_Internal_Fixed_Header;
+
+#define nlm32_internal_fixed_header nlm_internal_fixed_header
+#define Nlm32_Internal_Fixed_Header Nlm_Internal_Fixed_Header
+#define nlm64_internal_fixed_header nlm_internal_fixed_header
+#define Nlm64_Internal_Fixed_Header Nlm_Internal_Fixed_Header
+
+/* This structure contains the portions of the NLM header that are either
+ variable in size in the external representation, or else are not at a
+ fixed offset relative to the start of the NLM header due to preceding
+ variable sized fields.
+
+ Note that all the fields must exist in the external header, and in
+ the order used here (the same order is used in the internal form
+ for consistency, not out of necessity). */
+
+typedef struct nlm_internal_variable_header
+{
+
+ /* The descriptionLength field contains the length of the text in
+ descriptionText, excluding the null terminator. The descriptionText
+ field contains the NLM description obtained from the DESCRIPTION
+ keyword in NLMLINK plus the null byte terminator. The descriptionText
+ can be up to NLM_MAX_DESCRIPTION_LENGTH characters. */
+
+ unsigned char descriptionLength;
+ char descriptionText[NLM_MAX_DESCRIPTION_LENGTH + 1];
+
+ /* The stackSize field contains the size of the stack in bytes, as
+ specified by the STACK or STACKSIZE keyword in NLMLINK. If no size
+ is specified, the default is NLM_DEFAULT_STACKSIZE. */
+
+ long stackSize;
+
+ /* The reserved field is included only for completeness. It should contain
+ zero. */
+
+ long reserved;
+
+ /* This field is fixed length, should contain " LONG" (note leading
+ space), and is unused. */
+
+ char oldThreadName[NLM_OLD_THREAD_NAME_LENGTH];
+
+ /* The screenNameLength field contains the length of the actual text stored
+ in the screenName field, excluding the null byte terminator. The
+ screenName field contains the screen name as specified by the SCREENNAME
+ keyword in NLMLINK, and can be up to NLM_MAX_SCREEN_NAME_LENGTH
+ characters. */
+
+ unsigned char screenNameLength;
+ char screenName[NLM_MAX_SCREEN_NAME_LENGTH + 1];
+
+ /* The threadNameLength field contains the length of the actual text stored
+ in the threadName field, excluding the null byte terminator. The
+ threadName field contains the thread name as specified by the THREADNAME
+ keyword in NLMLINK, and can be up to NLM_MAX_THREAD_NAME_LENGTH
+ characters. */
+
+ unsigned char threadNameLength;
+ char threadName[NLM_MAX_THREAD_NAME_LENGTH + 1];
+
+} Nlm_Internal_Variable_Header;
+
+#define nlm32_internal_variable_header nlm_internal_variable_header
+#define Nlm32_Internal_Variable_Header Nlm_Internal_Variable_Header
+#define nlm64_internal_variable_header nlm_internal_variable_header
+#define Nlm64_Internal_Variable_Header Nlm_Internal_Variable_Header
+
+/* The version header is one of the optional auxiliary headers and
+ follows the fixed length and variable length NLM headers. */
+
+typedef struct nlm_internal_version_header
+{
+ /* The header is recognized by "VeRsIoN#" in the stamp field. */
+ char stamp[8];
+ long majorVersion;
+ long minorVersion;
+ long revision;
+ long year;
+ long month;
+ long day;
+} Nlm_Internal_Version_Header;
+
+#define nlm32_internal_version_header nlm_internal_version_header
+#define Nlm32_Internal_Version_Header Nlm_Internal_Version_Header
+#define nlm64_internal_version_header nlm_internal_version_header
+#define Nlm64_Internal_Version_Header Nlm_Internal_Version_Header
+
+typedef struct nlm_internal_copyright_header
+{
+ /* The header is recognized by "CoPyRiGhT=" in the stamp field. */
+ char stamp[10];
+ unsigned char copyrightMessageLength;
+ char copyrightMessage[NLM_MAX_COPYRIGHT_MESSAGE_LENGTH];
+} Nlm_Internal_Copyright_Header;
+
+#define nlm32_internal_copyright_header nlm_internal_copyright_header
+#define Nlm32_Internal_Copyright_Header Nlm_Internal_Copyright_Header
+#define nlm64_internal_copyright_header nlm_internal_copyright_header
+#define Nlm64_Internal_Copyright_Header Nlm_Internal_Copyright_Header
+
+typedef struct nlm_internal_extended_header
+{
+ /* The header is recognized by "MeSsAgEs" in the stamp field. */
+ char stamp[8];
+ long languageID;
+ file_ptr messageFileOffset;
+ bfd_size_type messageFileLength;
+ long messageCount;
+ file_ptr helpFileOffset;
+ bfd_size_type helpFileLength;
+ file_ptr RPCDataOffset;
+ bfd_size_type RPCDataLength;
+ file_ptr sharedCodeOffset;
+ bfd_size_type sharedCodeLength;
+ file_ptr sharedDataOffset;
+ bfd_size_type sharedDataLength;
+ file_ptr sharedRelocationFixupOffset;
+ long sharedRelocationFixupCount;
+ file_ptr sharedExternalReferenceOffset;
+ long sharedExternalReferenceCount;
+ file_ptr sharedPublicsOffset;
+ long sharedPublicsCount;
+ file_ptr sharedDebugRecordOffset;
+ long sharedDebugRecordCount;
+ bfd_vma SharedInitializationOffset;
+ bfd_vma SharedExitProcedureOffset;
+ long productID;
+ long reserved0;
+ long reserved1;
+ long reserved2;
+ long reserved3;
+ long reserved4;
+ long reserved5;
+} Nlm_Internal_Extended_Header;
+
+#define nlm32_internal_extended_header nlm_internal_extended_header
+#define Nlm32_Internal_Extended_Header Nlm_Internal_Extended_Header
+#define nlm64_internal_extended_header nlm_internal_extended_header
+#define Nlm64_Internal_Extended_Header Nlm_Internal_Extended_Header
+
+/* The format of a custom header as stored internally is different
+ from the external format. This is how we store a custom header
+ which we do not recognize. */
+
+typedef struct nlm_internal_custom_header
+{
+ /* The header is recognized by "CuStHeAd" in the stamp field. */
+ char stamp[8];
+ bfd_size_type hdrLength;
+ file_ptr dataOffset;
+ bfd_size_type dataLength;
+ char dataStamp[8];
+ PTR hdr;
+} Nlm_Internal_Custom_Header;
+
+#define nlm32_internal_custom_header nlm_internal_custom_header
+#define Nlm32_Internal_Custom_Header Nlm_Internal_Custom_Header
+#define nlm64_internal_custom_header nlm_internal_custom_header
+#define Nlm64_Internal_Custom_Header Nlm_Internal_Custom_Header
+
+/* The internal Cygnus header is written out externally as a custom
+ header. We don't try to replicate that structure here. */
+
+typedef struct nlm_internal_cygnus_ext_header
+{
+ /* The header is recognized by "CyGnUsEx" in the stamp field. */
+ char stamp[8];
+ /* File location of debugging information. */
+ file_ptr offset;
+ /* Length of debugging information. */
+ bfd_size_type length;
+} Nlm_Internal_Cygnus_Ext_Header;
+
+#define nlm32_internal_cygnus_ext_header nlm_internal_cygnus_ext_header
+#define Nlm32_Internal_Cygnus_Ext_Header Nlm_Internal_Cygnus_Ext_Header
+#define nlm64_internal_cygnus_ext_header nlm_internal_cygnus_ext_header
+#define Nlm64_Internal_Cygnus_Ext_Header Nlm_Internal_Cygnus_Ext_Header
diff --git a/include/nlm/ppc-ext.h b/include/nlm/ppc-ext.h
new file mode 100644
index 00000000000..0aae10772f5
--- /dev/null
+++ b/include/nlm/ppc-ext.h
@@ -0,0 +1,163 @@
+/* PowerPC NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef OLDFORMAT
+
+/* The format of a PowerPC NLM changed. These structures are only
+ used in the old format. */
+
+/* A PowerPC NLM starts with an instance of this structure. */
+
+struct nlm32_powerpc_external_prefix_header
+{
+ /* Signature. Must be "AppleNLM". */
+ char signature[8];
+ /* Version number. Current value is 1. */
+ unsigned char headerVersion[4];
+ /* ??. Should be set to 0. */
+ unsigned char origins[4];
+ /* File creation date in standard Unix time format (seconds since
+ 1/1/70). */
+ unsigned char date[4];
+};
+
+#define NLM32_POWERPC_SIGNATURE "AppleNLM"
+#define NLM32_POWERPC_HEADER_VERSION 1
+
+/* The external format of a PowerPC NLM reloc. This is the same as an
+ XCOFF dynamic reloc. */
+
+struct nlm32_powerpc_external_reloc
+{
+ /* Address. */
+ unsigned char l_vaddr[4];
+ /* Symbol table index. This is 0 for .text and 1 for .data. 2
+ means .bss, but I don't know if it is used. In XCOFF, larger
+ numbers are indices into the dynamic symbol table, but they are
+ presumably not used in an NLM. */
+ unsigned char l_symndx[4];
+ /* Relocation type. */
+ unsigned char l_rtype[2];
+ /* Section number being relocated. */
+ unsigned char l_rsecnm[2];
+};
+
+#endif /* OLDFORMAT */
+
+/* The external format of the fixed header. */
+
+typedef struct nlm32_powerpc_external_fixed_header
+{
+
+ /* The signature field identifies the file as an NLM. It must contain
+ the signature string, which depends upon the NLM target. */
+
+ unsigned char signature[24];
+
+ /* The version of the header. At this time, the highest version number
+ is 4. */
+
+ unsigned char version[4];
+
+ /* The name of the module, which must be a DOS name (1-8 characters followed
+ by a period and a 1-3 character extension). The first byte is the byte
+ length of the name and the last byte is a null terminator byte. This
+ field is fixed length, and any unused bytes should be null bytes. The
+ value is set by the OUTPUT keyword to NLMLINK. */
+
+ unsigned char moduleName[14];
+
+ /* Padding to make it come out correct. */
+
+ unsigned char pad1[2];
+
+ /* The byte offset of the code image from the start of the file. */
+
+ unsigned char codeImageOffset[4];
+
+ /* The size of the code image, in bytes. */
+
+ unsigned char codeImageSize[4];
+
+ /* The byte offset of the data image from the start of the file. */
+
+ unsigned char dataImageOffset[4];
+
+ /* The size of the data image, in bytes. */
+
+ unsigned char dataImageSize[4];
+
+ /* The size of the uninitialized data region that the loader is to be
+ allocated at load time. Uninitialized data follows the initialized
+ data in the NLM address space. */
+
+ unsigned char uninitializedDataSize[4];
+
+ /* The byte offset of the custom data from the start of the file. The
+ custom data is set by the CUSTOM keyword to NLMLINK. It is possible
+ for this to be EOF if there is no custom data. */
+
+ unsigned char customDataOffset[4];
+
+ /* The size of the custom data, in bytes. */
+
+ unsigned char customDataSize[4];
+
+ /* The byte offset of the module dependencies from the start of the file.
+ The module dependencies are determined by the MODULE keyword in
+ NLMLINK. */
+
+ unsigned char moduleDependencyOffset[4];
+
+ /* The number of module dependencies at the moduleDependencyOffset. */
+
+ unsigned char numberOfModuleDependencies[4];
+
+ /* The byte offset of the relocation fixup data from the start of the file */
+
+ unsigned char relocationFixupOffset[4];
+
+ unsigned char numberOfRelocationFixups[4];
+
+ unsigned char externalReferencesOffset[4];
+
+ unsigned char numberOfExternalReferences[4];
+
+ unsigned char publicsOffset[4];
+
+ unsigned char numberOfPublics[4];
+
+ /* The byte offset of the internal debug info from the start of the file.
+ It is possible for this to be EOF if there is no debug info. */
+
+ unsigned char debugInfoOffset[4];
+
+ unsigned char numberOfDebugRecords[4];
+
+ unsigned char codeStartOffset[4];
+
+ unsigned char exitProcedureOffset[4];
+
+ unsigned char checkUnloadProcedureOffset[4];
+
+ unsigned char moduleType[4];
+
+ unsigned char flags[4];
+
+} Nlm32_powerpc_External_Fixed_Header;
diff --git a/include/nlm/sparc32-ext.h b/include/nlm/sparc32-ext.h
new file mode 100644
index 00000000000..0deb2dee923
--- /dev/null
+++ b/include/nlm/sparc32-ext.h
@@ -0,0 +1,120 @@
+/* SPARC NLM (NetWare Loadable Module) support for BFD.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* The external format of the fixed header. */
+
+typedef struct nlm32_sparc_external_fixed_header
+{
+
+ /* The signature field identifies the file as an NLM. It must contain
+ the signature string, which depends upon the NLM target. */
+
+ unsigned char signature[24];
+
+ /* The version of the header. At this time, the highest version number
+ is 4. */
+
+ unsigned char version[4];
+
+ /* The name of the module, which must be a DOS name (1-8 characters followed
+ by a period and a 1-3 character extension). The first byte is the byte
+ length of the name and the last byte is a null terminator byte. This
+ field is fixed length, and any unused bytes should be null bytes. The
+ value is set by the OUTPUT keyword to NLMLINK. */
+
+ unsigned char moduleName[14];
+
+ /* Padding to make it come out correct. */
+
+ unsigned char pad1[2];
+
+ /* The byte offset of the code image from the start of the file. */
+
+ unsigned char codeImageOffset[4];
+
+ /* The size of the code image, in bytes. */
+
+ unsigned char codeImageSize[4];
+
+ /* The byte offset of the data image from the start of the file. */
+
+ unsigned char dataImageOffset[4];
+
+ /* The size of the data image, in bytes. */
+
+ unsigned char dataImageSize[4];
+
+ /* The size of the uninitialized data region that the loader is to be
+ allocated at load time. Uninitialized data follows the initialized
+ data in the NLM address space. */
+
+ unsigned char uninitializedDataSize[4];
+
+ /* The byte offset of the custom data from the start of the file. The
+ custom data is set by the CUSTOM keyword to NLMLINK. It is possible
+ for this to be EOF if there is no custom data. */
+
+ unsigned char customDataOffset[4];
+
+ /* The size of the custom data, in bytes. */
+
+ unsigned char customDataSize[4];
+
+ /* The byte offset of the module dependencies from the start of the file.
+ The module dependencies are determined by the MODULE keyword in
+ NLMLINK. */
+
+ unsigned char moduleDependencyOffset[4];
+
+ /* The number of module dependencies at the moduleDependencyOffset. */
+
+ unsigned char numberOfModuleDependencies[4];
+
+ /* The byte offset of the relocation fixup data from the start of the file */
+
+ unsigned char relocationFixupOffset[4];
+
+ unsigned char numberOfRelocationFixups[4];
+
+ unsigned char externalReferencesOffset[4];
+
+ unsigned char numberOfExternalReferences[4];
+
+ unsigned char publicsOffset[4];
+
+ unsigned char numberOfPublics[4];
+
+ /* The byte offset of the internal debug info from the start of the file.
+ It is possible for this to be EOF if there is no debug info. */
+
+ unsigned char debugInfoOffset[4];
+
+ unsigned char numberOfDebugRecords[4];
+
+ unsigned char codeStartOffset[4];
+
+ unsigned char exitProcedureOffset[4];
+
+ unsigned char checkUnloadProcedureOffset[4];
+
+ unsigned char moduleType[4];
+
+ unsigned char flags[4];
+
+} Nlm32_sparc_External_Fixed_Header;
diff --git a/include/oasys.h b/include/oasys.h
new file mode 100644
index 00000000000..867d2503134
--- /dev/null
+++ b/include/oasys.h
@@ -0,0 +1,152 @@
+/* Oasys object format header file for BFD.
+ Contributed by Cygnus Support. */
+
+#define OASYS_MAX_SEC_COUNT 16
+/* **** */
+
+typedef struct oasys_archive_header {
+ unsigned int version;
+ char create_date[12];
+ char revision_date[12];
+ unsigned int mod_count;
+ file_ptr mod_tbl_offset;
+ unsigned int sym_tbl_size;
+ unsigned int sym_count;
+ file_ptr sym_tbl_offset;
+ unsigned int xref_count;
+ file_ptr xref_lst_offset;
+} oasys_archive_header_type;
+
+typedef struct oasys_extarchive_header {
+ bfd_byte version[4];
+ bfd_byte create_date[12];
+ bfd_byte revision_date[12];
+ bfd_byte mod_count[4];
+ bfd_byte mod_tbl_offset[4];
+ bfd_byte sym_tbl_size[4];
+ bfd_byte sym_count[4];
+ bfd_byte sym_tbl_offset[4];
+ bfd_byte xref_count[4];
+ bfd_byte xref_lst_offset[4];
+} oasys_extarchive_header_type;
+
+typedef struct oasys_module_table {
+ int mod_number;
+ char mod_date[12];
+ unsigned int mod_size;
+ unsigned int dep_count;
+ unsigned int depee_count;
+ file_ptr file_offset;
+ unsigned int sect_count;
+ char *module_name;
+ unsigned int module_name_size;
+} oasys_module_table_type;
+
+
+typedef struct oasys_extmodule_table_a {
+ bfd_byte mod_number[4];
+ bfd_byte mod_date[12];
+ bfd_byte mod_size[4];
+ bfd_byte dep_count[4];
+ bfd_byte depee_count[4];
+ bfd_byte sect_count[4];
+ bfd_byte file_offset[4];
+ bfd_byte mod_name[32];
+} oasys_extmodule_table_type_a_type;
+
+typedef struct oasys_extmodule_table_b {
+ bfd_byte mod_number[4];
+ bfd_byte mod_date[12];
+ bfd_byte mod_size[4];
+ bfd_byte dep_count[4];
+ bfd_byte depee_count[4];
+ bfd_byte sect_count[4];
+ bfd_byte file_offset[4];
+ bfd_byte mod_name_length[4];
+} oasys_extmodule_table_type_b_type;
+
+
+typedef enum oasys_record {
+ oasys_record_is_end_enum = 0,
+ oasys_record_is_data_enum = 1,
+ oasys_record_is_symbol_enum = 2,
+ oasys_record_is_header_enum = 3,
+ oasys_record_is_named_section_enum = 4,
+ oasys_record_is_com_enum = 5,
+ oasys_record_is_debug_enum = 6,
+ oasys_record_is_section_enum = 7,
+ oasys_record_is_debug_file_enum = 8,
+ oasys_record_is_module_enum = 9,
+ oasys_record_is_local_enum = 10
+} oasys_record_enum_type;
+
+
+
+typedef struct oasys_record_header {
+ unsigned char length;
+ unsigned char check_sum;
+ unsigned char type;
+ unsigned char fill;
+} oasys_record_header_type;
+
+typedef struct oasys_data_record {
+ oasys_record_header_type header;
+ unsigned char relb;
+ bfd_byte addr[4];
+ /* maximum total size of data record is 255 bytes */
+ bfd_byte data[246];
+} oasys_data_record_type;
+
+typedef struct oasys_header_record {
+ oasys_record_header_type header;
+ unsigned char version_number;
+ unsigned char rev_number;
+ char module_name[26-6];
+ char description[64-26];
+} oasys_header_record_type;
+
+#define OASYS_VERSION_NUMBER 0
+#define OASYS_REV_NUMBER 0
+
+typedef struct oasys_symbol_record {
+ oasys_record_header_type header;
+ unsigned char relb;
+ bfd_byte value[4];
+ bfd_byte refno[2];
+ char name[64];
+} oasys_symbol_record_type;
+
+#define RELOCATION_PCREL_BIT 0x80
+#define RELOCATION_32BIT_BIT 0x40
+#define RELOCATION_TYPE_BITS 0x30
+#define RELOCATION_TYPE_ABS 0x00
+#define RELOCATION_TYPE_REL 0x10
+#define RELOCATION_TYPE_UND 0x20
+#define RELOCATION_TYPE_COM 0x30
+#define RELOCATION_SECT_BITS 0x0f
+
+typedef struct oasys_section_record {
+ oasys_record_header_type header;
+ unsigned char relb;
+ bfd_byte value[4];
+ bfd_byte vma[4];
+ bfd_byte fill[3];
+} oasys_section_record_type;
+
+typedef struct oasys_end_record {
+ oasys_record_header_type header;
+ unsigned char relb;
+ bfd_byte entry[4];
+ bfd_byte fill[2];
+ bfd_byte zero;
+} oasys_end_record_type;
+
+typedef union oasys_record_union {
+ oasys_record_header_type header;
+ oasys_data_record_type data;
+ oasys_section_record_type section;
+ oasys_symbol_record_type symbol;
+ oasys_header_record_type first;
+ oasys_end_record_type end;
+ bfd_byte pad[256];
+} oasys_record_union_type;
diff --git a/include/objalloc.h b/include/objalloc.h
new file mode 100644
index 00000000000..0b451cdc295
--- /dev/null
+++ b/include/objalloc.h
@@ -0,0 +1,116 @@
+/* objalloc.h -- routines to allocate memory for objects
+ Copyright 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Solutions.
+
+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, 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef OBJALLOC_H
+#define OBJALLOC_H
+
+#include "ansidecl.h"
+
+/* These routines allocate space for an object. The assumption is
+ that the object will want to allocate space as it goes along, but
+ will never want to free any particular block. There is a function
+ to free a block, which also frees all more recently allocated
+ blocks. There is also a function to free all the allocated space.
+
+ This is essentially a specialization of obstacks. The main
+ difference is that a block may not be allocated a bit at a time.
+ Another difference is that these routines are always built on top
+ of malloc, and always pass an malloc failure back to the caller,
+ unlike more recent versions of obstacks. */
+
+/* This is what an objalloc structure looks like. Callers should not
+ refer to these fields, nor should they allocate these structure
+ themselves. Instead, they should only create them via
+ objalloc_init, and only access them via the functions and macros
+ listed below. The structure is only defined here so that we can
+ access it via macros. */
+
+struct objalloc
+{
+ char *current_ptr;
+ unsigned int current_space;
+ PTR chunks;
+};
+
+/* Work out the required alignment. */
+
+struct objalloc_align { char x; double d; };
+
+#if defined (__STDC__) && __STDC__
+#ifndef offsetof
+#include <stddef.h>
+#endif
+#define OBJALLOC_ALIGN \
+ ((ptrdiff_t) ((char *) &((struct objalloc_align *) 0)->d - (char *) 0))
+#else
+#define OBJALLOC_ALIGN \
+ ((long) ((char *) &((struct objalloc_align *) 0)->d - (char *) 0))
+#endif
+
+/* Create an objalloc structure. Returns NULL if malloc fails. */
+
+extern struct objalloc *objalloc_create PARAMS ((void));
+
+/* Allocate space from an objalloc structure. Returns NULL if malloc
+ fails. */
+
+extern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long));
+
+/* The macro version of objalloc_alloc. We only define this if using
+ gcc, because otherwise we would have to evaluate the arguments
+ multiple times, or use a temporary field as obstack.h does. */
+
+#if defined (__GNUC__) && defined (__STDC__) && __STDC__
+
+/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+ does not implement __extension__. But that compiler doesn't define
+ __GNUC_MINOR__. */
+#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+#define __extension__
+#endif
+
+#define objalloc_alloc(o, l) \
+ __extension__ \
+ ({ struct objalloc *__o = (o); \
+ unsigned long __len = (l); \
+ if (__len == 0) \
+ __len = 1; \
+ __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \
+ (__len <= __o->current_space \
+ ? (__o->current_ptr += __len, \
+ __o->current_space -= __len, \
+ (PTR) (__o->current_ptr - __len)) \
+ : _objalloc_alloc (__o, __len)); })
+
+#else /* ! __GNUC__ */
+
+#define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
+
+#endif /* ! __GNUC__ */
+
+/* Free an entire objalloc structure. */
+
+extern void objalloc_free PARAMS ((struct objalloc *));
+
+/* Free a block allocated by objalloc_alloc. This also frees all more
+ recently allocated blocks. */
+
+extern void objalloc_free_block PARAMS ((struct objalloc *, PTR));
+
+#endif /* OBJALLOC_H */
diff --git a/include/obstack.h b/include/obstack.h
new file mode 100644
index 00000000000..38e96777660
--- /dev/null
+++ b/include/obstack.h
@@ -0,0 +1,593 @@
+/* obstack.h - object stack macros
+ Copyright (C) 1988,89,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
+
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects. Each object starts life
+small, and may grow to maturity. (Consider building a word syllable
+by syllable.) An object can move while it is growing. Once it has
+been "finished" it never changes address again. So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
+by calling `obstack_chunk_free'. You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables. Unless you are "fascist pig with a read-only mind"
+--Gosper's immortal quote from HAKMEM item 154, out of context--you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols. At the time you are reading a symbol you don't know
+how long it is. One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer. This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently. Use one obstack for all symbol
+names. As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it. Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses. When you want to build a symbol in the chunk you just
+add chars above the current "high water mark" in the chunk. When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies. No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beginning of the new larger chunk. We then carry on
+accreting characters to the end of the object as we normally would.
+
+A special macro is provided to add a single char at a time to a
+growing object. This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+ We allocate large chunks.
+ We carve out one object at a time from the current chunk.
+ Once carved, an object never moves.
+ We are free to append data of any size to the currently
+ growing object.
+ Exactly one object is growing in an obstack at any one time.
+ You can run one obstack per control block.
+ You may have as many control blocks as you dare.
+ Because of the way we do it, you can `unwind' an obstack
+ back to a previous state. (You may remove objects much
+ as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once. */
+
+#ifndef _OBSTACK_H
+#define _OBSTACK_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* We use subtraction of (char *) 0 instead of casting to int
+ because on word-addressable machines a simple cast to int
+ may ignore the byte-within-word field of the pointer. */
+
+#ifndef __PTR_TO_INT
+# define __PTR_TO_INT(P) ((P) - (char *) 0)
+#endif
+
+#ifndef __INT_TO_PTR
+# define __INT_TO_PTR(P) ((P) + (char *) 0)
+#endif
+
+/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is
+ defined, as with GNU C, use that; that way we don't pollute the
+ namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is
+ available, include it and use ptrdiff_t. In traditional C, long is
+ the best that we can do. */
+
+#ifdef __PTRDIFF_TYPE__
+# define PTR_INT_TYPE __PTRDIFF_TYPE__
+#else
+# ifdef HAVE_STDDEF_H
+# include <stddef.h>
+# define PTR_INT_TYPE ptrdiff_t
+# else
+# define PTR_INT_TYPE long
+# endif
+#endif
+
+#if defined _LIBC || defined HAVE_STRING_H
+# include <string.h>
+# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
+#else
+# ifdef memcpy
+# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
+# else
+# define _obstack_memcpy(To, From, N) bcopy ((From), (To), (N))
+# endif
+#endif
+
+struct _obstack_chunk /* Lives at front of each chunk. */
+{
+ char *limit; /* 1 past end of this chunk */
+ struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+ char contents[4]; /* objects begin here */
+};
+
+struct obstack /* control current object in current chunk */
+{
+ long chunk_size; /* preferred size to allocate chunks in */
+ struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
+ char *object_base; /* address of object we are building */
+ char *next_free; /* where to add next char to current object */
+ char *chunk_limit; /* address of char after current chunk */
+ PTR_INT_TYPE temp; /* Temporary for some macros. */
+ int alignment_mask; /* Mask of alignment for each object. */
+#if defined __STDC__ && __STDC__
+ /* These prototypes vary based on `use_extra_arg', and we use
+ casts to the prototypeless function type in all assignments,
+ but having prototypes here quiets -Wstrict-prototypes. */
+ struct _obstack_chunk *(*chunkfun) (void *, long);
+ void (*freefun) (void *, struct _obstack_chunk *);
+ void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+#else
+ struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
+ void (*freefun) (); /* User's function to free a chunk. */
+ char *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+#endif
+ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
+ unsigned maybe_empty_object:1;/* There is a possibility that the current
+ chunk contains a zero-length object. This
+ prevents freeing the chunk if we allocate
+ a bigger chunk to replace it. */
+ unsigned alloc_failed:1; /* No longer used, as we now call the failed
+ handler on error, but retained for binary
+ compatibility. */
+};
+
+/* Declare the external functions we use; they are in obstack.c. */
+
+#if defined __STDC__ && __STDC__
+extern void _obstack_newchunk (struct obstack *, int);
+extern void _obstack_free (struct obstack *, void *);
+extern int _obstack_begin (struct obstack *, int, int,
+ void *(*) (long), void (*) (void *));
+extern int _obstack_begin_1 (struct obstack *, int, int,
+ void *(*) (void *, long),
+ void (*) (void *, void *), void *);
+extern int _obstack_memory_used (struct obstack *);
+#else
+extern void _obstack_newchunk ();
+extern void _obstack_free ();
+extern int _obstack_begin ();
+extern int _obstack_begin_1 ();
+extern int _obstack_memory_used ();
+#endif
+
+#if defined __STDC__ && __STDC__
+
+/* Do the function-declarations after the structs
+ but before defining the macros. */
+
+void obstack_init (struct obstack *obstack);
+
+void * obstack_alloc (struct obstack *obstack, int size);
+
+void * obstack_copy (struct obstack *obstack, void *address, int size);
+void * obstack_copy0 (struct obstack *obstack, void *address, int size);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+void obstack_blank (struct obstack *obstack, int size);
+
+void obstack_grow (struct obstack *obstack, void *data, int size);
+void obstack_grow0 (struct obstack *obstack, void *data, int size);
+
+void obstack_1grow (struct obstack *obstack, int data_char);
+void obstack_ptr_grow (struct obstack *obstack, void *data);
+void obstack_int_grow (struct obstack *obstack, int data);
+
+void * obstack_finish (struct obstack *obstack);
+
+int obstack_object_size (struct obstack *obstack);
+
+int obstack_room (struct obstack *obstack);
+void obstack_make_room (struct obstack *obstack, int size);
+void obstack_1grow_fast (struct obstack *obstack, int data_char);
+void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
+void obstack_int_grow_fast (struct obstack *obstack, int data);
+void obstack_blank_fast (struct obstack *obstack, int size);
+
+void * obstack_base (struct obstack *obstack);
+void * obstack_next_free (struct obstack *obstack);
+int obstack_alignment_mask (struct obstack *obstack);
+int obstack_chunk_size (struct obstack *obstack);
+int obstack_memory_used (struct obstack *obstack);
+
+#endif /* __STDC__ */
+
+/* Non-ANSI C cannot really support alternative functions for these macros,
+ so we do not declare them. */
+
+/* Error handler called when `obstack_chunk_alloc' failed to allocate
+ more memory. This can be set to a user defined function. The
+ default action is to print a message and abort. */
+#if defined __STDC__ && __STDC__
+extern void (*obstack_alloc_failed_handler) (void);
+#else
+extern void (*obstack_alloc_failed_handler) ();
+#endif
+
+/* Exit value used when `print_and_abort' is used. */
+extern int obstack_exit_failure;
+
+/* Pointer to beginning of object being allocated or to be allocated next.
+ Note that this might not be the final address of the object
+ because a new chunk might be needed to hold the final size. */
+
+#define obstack_base(h) ((h)->object_base)
+
+/* Size for allocating ordinary chunks. */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk. */
+
+#define obstack_next_free(h) ((h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object. */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+/* To prevent prototype warnings provide complete argument list in
+ standard C version. */
+#if defined __STDC__ && __STDC__
+
+# define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
+
+# define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
+
+# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun))
+
+# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) (void *, long)) (chunkfun), \
+ (void (*) (void *, void *)) (freefun), (arg))
+
+# define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
+
+# define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
+
+#else
+
+# define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+# define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
+
+# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
+
+# define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
+
+# define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)()) (newfreefun))
+
+#endif
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+
+#define obstack_memory_used(h) _obstack_memory_used (h)
+
+#if defined __GNUC__ && defined __STDC__ && __STDC__
+/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+ does not implement __extension__. But that compiler doesn't define
+ __GNUC_MINOR__. */
+# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+# define __extension__
+# endif
+
+/* For GNU C, if not -traditional,
+ we can define these macros to compute all args only once
+ without using a global variable.
+ Also, we can avoid using the `temp' slot, to make faster code. */
+
+# define obstack_object_size(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->next_free - __o->object_base); })
+
+# define obstack_room(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->chunk_limit - __o->next_free); })
+
+# define obstack_make_room(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ (void) 0; })
+
+# define obstack_empty_p(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
+
+# define obstack_grow(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len); \
+ _obstack_memcpy (__o->next_free, (char *) (where), __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_grow0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len + 1); \
+ _obstack_memcpy (__o->next_free, (char *) (where), __len); \
+ __o->next_free += __len; \
+ *(__o->next_free)++ = 0; \
+ (void) 0; })
+
+# define obstack_1grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, 1); \
+ *(__o->next_free)++ = (datum); \
+ (void) 0; })
+
+/* These assume that the obstack alignment is good enough for pointers or ints,
+ and that the data added so far to the current object
+ shares that much alignment. */
+
+# define obstack_ptr_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (void *)); \
+ *((void **)__o->next_free)++ = ((void *)datum); \
+ (void) 0; })
+
+# define obstack_int_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (int) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (int)); \
+ *((int *)__o->next_free)++ = ((int)datum); \
+ (void) 0; })
+
+# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
+# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+
+# define obstack_blank(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_alloc(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_blank (__h, (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow0 (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+/* The local variable is named __o1 to avoid a name conflict
+ when obstack_blank is called. */
+# define obstack_finish(OBSTACK) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ void *value; \
+ value = (void *) __o1->object_base; \
+ if (__o1->next_free == value) \
+ __o1->maybe_empty_object = 1; \
+ __o1->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
+ & ~ (__o1->alignment_mask)); \
+ if (__o1->next_free - (char *)__o1->chunk \
+ > __o1->chunk_limit - (char *)__o1->chunk) \
+ __o1->next_free = __o1->chunk_limit; \
+ __o1->object_base = __o1->next_free; \
+ value; })
+
+# define obstack_free(OBSTACK, OBJ) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ void *__obj = (OBJ); \
+ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
+ __o->next_free = __o->object_base = __obj; \
+ else (obstack_free) (__o, __obj); })
+
+#else /* not __GNUC__ or not __STDC__ */
+
+# define obstack_object_size(h) \
+ (unsigned) ((h)->next_free - (h)->object_base)
+
+# define obstack_room(h) \
+ (unsigned) ((h)->chunk_limit - (h)->next_free)
+
+# define obstack_empty_p(h) \
+ ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
+
+/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
+ so that we can avoid having void expressions
+ in the arms of the conditional expression.
+ Casting the third operand to void was tried before,
+ but some compilers won't accept it. */
+
+# define obstack_make_room(h,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0))
+
+# define obstack_grow(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ _obstack_memcpy ((h)->next_free, (char *) (where), (h)->temp), \
+ (h)->next_free += (h)->temp)
+
+# define obstack_grow0(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
+ _obstack_memcpy ((h)->next_free, (char *) (where), (h)->temp), \
+ (h)->next_free += (h)->temp, \
+ *((h)->next_free)++ = 0)
+
+# define obstack_1grow(h,datum) \
+( (((h)->next_free + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), 1), 0) : 0), \
+ (*((h)->next_free)++ = (datum)))
+
+# define obstack_ptr_grow(h,datum) \
+( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
+ (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum)))
+
+# define obstack_int_grow(h,datum) \
+( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
+ (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum)))
+
+# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr)
+# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+
+# define obstack_blank(h,length) \
+( (h)->temp = (length), \
+ (((h)->chunk_limit - (h)->next_free < (h)->temp) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ ((h)->next_free += (h)->temp))
+
+# define obstack_alloc(h,length) \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+# define obstack_copy(h,where,length) \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_copy0(h,where,length) \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_finish(h) \
+( ((h)->next_free == (h)->object_base \
+ ? (((h)->maybe_empty_object = 1), 0) \
+ : 0), \
+ (h)->temp = __PTR_TO_INT ((h)->object_base), \
+ (h)->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
+ & ~ ((h)->alignment_mask)), \
+ (((h)->next_free - (char *) (h)->chunk \
+ > (h)->chunk_limit - (char *) (h)->chunk) \
+ ? ((h)->next_free = (h)->chunk_limit) : 0), \
+ (h)->object_base = (h)->next_free, \
+ __INT_TO_PTR ((h)->temp))
+
+# if defined __STDC__ && __STDC__
+# define obstack_free(h,obj) \
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
+# else
+# define obstack_free(h,obj) \
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
+# endif
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+#ifdef __cplusplus
+} /* C++ */
+#endif
+
+#endif /* obstack.h */
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
new file mode 100644
index 00000000000..79bc3cc7cb8
--- /dev/null
+++ b/include/opcode/ChangeLog
@@ -0,0 +1,1873 @@
+1999-04-14 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (CGEN_ATTR): Delete member num_nonbools.
+ (CGEN_ATTR_TYPE): Update.
+ (CGEN_ATTR_MASK): Number booleans starting at 0.
+ (CGEN_ATTR_VALUE): Update.
+ (CGEN_INSN_ATTR): Update.
+
+Mon Apr 12 23:43:27 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa.h (fmpyfadd, fmpynfadd, fneg, fnegabs): New PA2.0
+ instructions.
+
+Tue Mar 23 11:24:38 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa.h (bb, bvb): Tweak opcode/mask.
+
+
+1999-03-22 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (CGEN_ISA,CGEN_MACH): New typedefs.
+ (struct cgen_cpu_desc): Rename member mach to machs. New member isas.
+ New members word_bitsize,default_insn_bitsize,base_insn-bitsize,
+ min_insn_bitsize,max_insn_bitsize,isa_table,mach_table,rebuild_tables.
+ Delete member max_insn_size.
+ (enum cgen_cpu_open_arg): New enum.
+ (cpu_open): Update prototype.
+ (cpu_open_1): Declare.
+ (cgen_set_cpu): Delete.
+
+1999-03-11 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (CGEN_HW_TABLE): Delete `num_init_entries' member.
+ (CGEN_OPERAND_NIL): New macro.
+ (CGEN_OPERAND): New member `type'.
+ (@arch@_cgen_operand_table): Delete decl.
+ (CGEN_OPERAND_INDEX,CGEN_OPERAND_TYPE,CGEN_OPERAND_ENTRY): Delete.
+ (CGEN_OPERAND_TABLE): New struct.
+ (cgen_operand_lookup_by_name,cgen_operand_lookup_by_num): Declare.
+ (CGEN_OPINST): Pointer to operand table entry replaced with enum.
+ (CGEN_CPU_TABLE): New member `isa'. Change member `operand_table',
+ now a CGEN_OPERAND_TABLE. Add CGEN_CPU_DESC arg to
+ {get,set}_{int,vma}_operand.
+ (@arch@_cgen_cpu_open): New arg `isa'.
+ (cgen_set_cpu): Ditto.
+
+Fri Feb 26 02:36:45 1999 Richard Henderson <rth@cygnus.com>
+
+ * i386.h: Fill in cmov and fcmov alternates. Add fcomi short forms.
+
+1999-02-25 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (enum cgen_asm_type): Add CGEN_ASM_NONE.
+ (CGEN_HW_ENTRY): Delete member `next'. Change type of `type' to
+ enum cgen_hw_type.
+ (CGEN_HW_TABLE): New struct.
+ (hw_table): Delete declaration.
+ (CGEN_OPERAND): Change member hw to hw_type, change type from pointer
+ to table entry to enum.
+ (CGEN_OPINST): Ditto.
+ (CGEN_CPU_TABLE): Change member hw_list to hw_table.
+
+Sat Feb 13 14:13:44 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (AXP_OPCODE_EV6): New.
+ (AXP_OPCODE_NOPAL): Include it.
+
+1999-02-09 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (CGEN_CPU_DESC): Renamed from CGEN_OPCODE_DESC.
+ All uses updated. New members int_insn_p, max_insn_size,
+ parse_operand,insert_operand,extract_operand,print_operand,
+ sizeof_fields,set_fields_bitsize,get_int_operand,set_int_operand,
+ get_vma_operand,set_vma_operand,parse_handlers,insert_handlers,
+ extract_handlers,print_handlers.
+ (CGEN_ATTR): Change type of num_nonbools to unsigned int.
+ (CGEN_ATTR_BOOL_OFFSET): New macro.
+ (CGEN_ATTR_MASK): Subtract it to compute bit number.
+ (CGEN_ATTR_VALUE): Redo bool/nonbool attr calculation.
+ (cgen_opcode_handler): Renamed from cgen_base.
+ (CGEN_HW_ATTR_VALUE): Renamed from CGEN_HW_ATTR, all uses updated.
+ (CGEN_OPERAND_ATTR_VALUE): Renamed from CGEN_OPERAND_ATTR,
+ all uses updated.
+ (CGEN_OPERAND_INDEX): Rewrite to use table entry, not global.
+ (enum cgen_opinst_type): Renamed from cgen_operand_instance_type.
+ (CGEN_IFLD_ATTR_VALUE): Renamed from CGEN_IFLD_ATTR, all uses updated.
+ (CGEN_OPCODE,CGEN_IBASE): New types.
+ (CGEN_INSN): Rewrite.
+ (CGEN_{ASM,DIS}_HASH*): Delete.
+ (init_opcode_table,init_ibld_table): Declare.
+ (CGEN_INSN_ATTR): New type.
+
+Mon Feb 1 21:09:14 1999 Catherine Moore <clm@cygnus.com>
+
+ * i386.h (d_Suf, x_Suf, sld_Suf, sldx_Suf, bwld_Suf): Define.
+ (x_FP, d_FP, dls_FP, sldx_FP): Define.
+ Change *Suf definitions to include x and d suffixes.
+ (movsx): Use w_Suf and b_Suf.
+ (movzx): Likewise.
+ (movs): Use bwld_Suf.
+ (fld): Change ordering. Use sld_FP.
+ (fild): Add Intel Syntax equivalent of fildq.
+ (fst): Use sld_FP.
+ (fist): Use sld_FP.
+ (fstp): Use sld_FP. Add x_FP version.
+ (fistp): LLongMem version for Intel Syntax.
+ (fcom, fcomp): Use sld_FP.
+ (fadd, fiadd, fsub): Use sld_FP.
+ (fsubr): Use sld_FP.
+ (fmul, fimul, fdvi, fidiv, fdivr): Use sld_FP.
+
+1999-01-27 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (enum cgen_mode): Add CGEN_MODE_TARGET_MAX, CGEN_MODE_INT,
+ CGEN_MODE_UINT.
+
+Sat Jan 16 01:29:25 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa.h (bv): Fix mask.
+
+1999-01-05 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (CGEN_ATTR_VALUE_TYPE): New typedef.
+ (CGEN_ATTR): Use it.
+ (CGEN_ATTR_TYPE,CGEN_ATTR_ENTRY): Ditto.
+ (CGEN_ATTR_TABLE): New member dfault.
+
+1998-12-30 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.h (MIPS16_INSN_BRANCH): New.
+
+Wed Dec 9 10:38:48 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following is part of a change made by Edith Epstein
+ <eepstein@sophia.cygnus.com> as part of a project to merge in
+ changes by HP; HP did not create ChangeLog entries.
+
+ * hppa.h (completer_chars): list of chars to not put a space
+ after.
+
+Sun Dec 6 13:21:34 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h (i386_optab): Permit w suffix on processor control and
+ status word instructions.
+
+1998-11-30 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (struct cgen_hw_entry): Delete const on attrs member.
+ (struct cgen_keyword_entry): Ditto.
+ (struct cgen_operand): Ditto.
+ (CGEN_IFLD): New typedef, with associated access macros.
+ (CGEN_IFMT): New typedef, with associated access macros.
+ (CGEN_IFMT): Renamed from CGEN_FORMAT. New member `iflds'.
+ (CGEN_IVALUE): New typedef.
+ (struct cgen_insn): Delete const on syntax,attrs members.
+ `format' now points to format data. Type of `value' is now
+ CGEN_IVALUE.
+ (struct cgen_opcode_table): New member ifld_table.
+
+1998-11-18 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen.h (cgen_extract_fn): Update type of `base_insn' arg.
+ (CGEN_OPERAND_INSTANCE): New member `attrs'.
+ (CGEN_OPERAND_INSTANCE_{ATTRS,ATTR}): New macros.
+ (cgen_dis_lookup_insn): Update type of `base_insn' arg.
+ (cgen_opcode_table): Update type of dis_hash fn.
+ (extract_operand): Update type of `insn_value' arg.
+
+Thu Oct 29 11:38:36 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * cgen.h (CGEN_VERSION_{MAJOR,MINOR,FIXLEVEL}): Delete.
+
+Tue Oct 27 08:57:59 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.h (INSN_MULT): Added.
+
+Tue Oct 20 11:31:34 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (MAX_MNEM_SIZE): Rename from MAX_OPCODE_SIZE.
+
+Mon Oct 19 12:50:00 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_INSN_INT): New typedef.
+ (CGEN_INT_INSN_P): Renamed from CGEN_INT_INSN.
+ (CGEN_INSN_BYTES): Renamed from cgen_insn_t.
+ (CGEN_INSN_BYTES_PTR): New typedef.
+ (CGEN_EXTRACT_INFO): New typedef.
+ (cgen_insert_fn,cgen_extract_fn): Update.
+ (cgen_opcode_table): New member `insn_endian'.
+ (assemble_insn,lookup_insn,lookup_get_insn_operands): Update.
+ (insert_operand,extract_operand): Update.
+ (cgen_get_insn_value,cgen_put_insn_value): Add prototypes.
+
+Fri Oct 9 13:38:13 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_ATTR_BOOLS): New macro.
+ (struct CGEN_HW_ENTRY): New member `attrs'.
+ (CGEN_HW_ATTR): New macro.
+ (struct CGEN_OPERAND_INSTANCE): New member `name'.
+ (CGEN_INSN_INVALID_P): New macro.
+
+Mon Oct 5 00:21:07 1998 Jeffrey A Law (law@cygnus.com)
+
+ * hppa.h: Add "fid".
+
+Sun Oct 4 21:00:00 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ From Robert Andrew Dale <rob@nb.net>
+ * i386.h (i386_optab): Add AMD 3DNow! instructions.
+ (AMD_3DNOW_OPCODE): Define.
+
+Tue Sep 22 17:53:47 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v.h (EITHER_BUT_PREFER_MU): Define.
+
+Mon Aug 10 14:09:38 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * cgen.h (cgen_insn): #if 0 out element `cdx'.
+
+Mon Aug 3 12:21:57 1998 Doug Evans <devans@seba.cygnus.com>
+
+ Move all global state data into opcode table struct, and treat
+ opcode table as something that is "opened/closed".
+ * cgen.h (CGEN_OPCODE_DESC): New type.
+ (all fns): New first arg of opcode table descriptor.
+ (cgen_set_parse_operand_fn): Add prototype.
+ (cgen_current_machine,cgen_current_endian): Delete.
+ (CGEN_OPCODE_TABLE): New members mach,endian,operand_table,
+ parse_operand_fn,asm_hash_table,asm_hash_table_entries,
+ dis_hash_table,dis_hash_table_entries.
+ (opcode_open,opcode_close): Add prototypes.
+
+ * cgen.h (cgen_insn): New element `cdx'.
+
+Thu Jul 30 21:44:25 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * d30v.h (FLAG_LKR): New flag for "left-kills-right" instructions.
+
+Tue Jul 28 10:59:07 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h: Add "no_match_operands" field for instructions.
+ (MN10300_MAX_OPERANDS): Define.
+
+Fri Jul 24 11:44:24 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * cgen.h (cgen_macro_insn_count): Declare.
+
+Tue Jul 21 13:12:13 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_VERSION_{MAJOR,MINOR,FIXLEVEL}): Define.
+ (cgen_insert_fn,cgen_extract_fn): New arg `pc'.
+ (get_operand,put_operand): Replaced with get_{int,vma}_operand,
+ set_{int,vma}_operand.
+
+Fri Jun 26 11:09:06 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h: Add "machine" field for instructions.
+ (MN103, AM30): Define machine types.
+
+Fri Jun 19 16:09:09 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h: Use FP, not sl_Suf, for fxsave and fxrstor.
+
+1998-06-18 Ulrich Drepper <drepper@cygnus.com>
+
+ * i386.h: Add support for fxsave, fxrstor, sysenter and sysexit.
+
+Sat Jun 13 11:31:35 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (i386_optab): Add general form of aad and aam. Add ud2a
+ and ud2b.
+ (i386_regtab): Allow cr0..7, db0..7, dr0..7, tr0..7, not just
+ those that happen to be implemented on pentiums.
+
+Tue Jun 9 12:16:01 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h: Change occurences of Data16 to Size16, Data32 to Size32,
+ IgnoreDataSize to IgnoreSize. Flag address and data size prefixes
+ with Size16|IgnoreSize or Size32|IgnoreSize.
+
+Mon Jun 8 12:15:52 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (REPNE): Rename to REPNE_PREFIX_OPCODE.
+ (REPE): Rename to REPE_PREFIX_OPCODE.
+ (i386_regtab_end): Remove.
+ (i386_prefixtab, i386_prefixtab_end): Remove.
+ (i386_optab): Use NULL as sentinel rather than "" to suit rewrite
+ of md_begin.
+ (MAX_OPCODE_SIZE): Define.
+ (i386_optab_end): Remove.
+ (sl_Suf): Define.
+ (sl_FP): Use sl_Suf.
+
+ * i386.h (i386_optab): Allow 16 bit displacement for `mov
+ mem,acc'. Combine 16 and 32 bit forms of various insns. Allow 16
+ bit form of ljmp. Add IsPrefix modifier to prefixes. Add addr32,
+ data32, dword, and adword prefixes.
+ (i386_regtab): Add BaseIndex modifier to valid 16 bit base/index
+ regs.
+
+Fri Jun 5 23:42:43 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (i386_regtab): Remove BaseIndex modifier from esp.
+
+ * i386.h: Allow `l' suffix on fld, fst, fstp, fcom, fcomp with
+ register operands, because this is a common idiom. Flag them with
+ a warning. Allow illegal faddp, fsubp, fsubrp, fmulp, fdivp,
+ fdivrp because gcc erroneously generates them. Also flag with a
+ warning.
+
+ * i386.h: Add suffix modifiers to most insns, and tighter operand
+ checks in some cases. Fix a number of UnixWare compatibility
+ issues with float insns. Merge some floating point opcodes, using
+ new FloatMF modifier.
+ (WORD_PREFIX_OPCODE): Rename to DATA_PREFIX_OPCODE for
+ consistency.
+
+ * i386.h: Change occurence of ShortformW to W|ShortForm. Add
+ IgnoreDataSize where appropriate.
+
+Wed Jun 3 18:28:45 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h: (one_byte_segment_defaults): Remove.
+ (two_byte_segment_defaults): Remove.
+ (i386_regtab): Add BaseIndex to 32 bit regs reg_type.
+
+Fri May 15 15:59:04 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (cgen_hw_lookup_by_name): Renamed from cgen_hw_lookup.
+ (cgen_hw_lookup_by_num): Declare.
+
+Thu May 7 09:27:58 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips.h (OP_{SH,MASK}_CODE2): Added "q" operand format for lower
+ ten bits of MIPS ISA1 "break" instruction, and for "sdbbp"
+
+Thu May 7 02:14:08 1998 Doug Evans <devans@charmed.cygnus.com>
+
+ * cgen.h (cgen_asm_init_parse): Delete.
+ (cgen_save_fixups,cgen_restore_fixups,cgen_swap_fixups): Delete.
+ (cgen_asm_record_register,cgen_asm_finish_insn): Delete.
+
+Mon Apr 27 10:13:11 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_ATTR_TYPE): Delete `const', moved to uses.
+ (cgen_asm_finish_insn): Update prototype.
+ (cgen_insn): New members num, data.
+ (CGEN_INSN_TABLE): Members asm_hash, asm_hash_table_size,
+ dis_hash, dis_hash_table_size moved to ...
+ (CGEN_OPCODE_TABLE). Here. Renamed from CGEN_OPCODE_DATA.
+ All uses updated. New members asm_hash_p, dis_hash_p.
+ (CGEN_MINSN_EXPANSION): New struct.
+ (cgen_expand_macro_insn): Declare.
+ (cgen_macro_insn_count): Declare.
+ (get_insn_operands): Update prototype.
+ (lookup_get_insn_operands): Declare.
+
+Tue Apr 21 17:11:32 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (i386_optab): Change iclrKludge and imulKludge to
+ regKludge. Add operands types for string instructions.
+
+Mon Apr 20 14:40:29 1998 Tom Tromey <tromey@cygnus.com>
+
+ * i386.h (X): Renamed from `Z_' to preserve formatting of opcode
+ table.
+
+Sun Apr 19 13:54:06 1998 Tom Tromey <tromey@cygnus.com>
+
+ * i386.h (Z_): Renamed from `_' to avoid clash with common alias
+ for `gettext'.
+
+Fri Apr 3 12:04:48 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h: Remove NoModrm flag from all insns: it's never checked.
+ Add IsString flag to string instructions.
+ (IS_STRING): Don't define.
+ (LOCK_PREFIX_OPCODE, CS_PREFIX_OPCODE, DS_PREFIX_OPCODE): Define.
+ (ES_PREFIX_OPCODE, FS_PREFIX_OPCODE, GS_PREFIX_OPCODE): Define.
+ (SS_PREFIX_OPCODE): Define.
+
+Mon Mar 30 21:31:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Revert March 24 patch; no more LinearAddress.
+
+Mon Mar 30 10:25:54 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (i386_optab): Remove fwait (9b) from all floating point
+ instructions, and instead add FWait opcode modifier. Add short
+ form of fldenv and fstenv.
+ (FWAIT_OPCODE): Define.
+
+ * i386.h (i386_optab): Change second operand constraint of `mov
+ sreg,reg|mem' instruction from Reg16|Mem to WordReg|WordMem to
+ allow legal instructions such as `movl %gs,%esi'
+
+Fri Mar 27 18:30:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * h8300.h: Various changes to fully bracket initializers.
+
+Tue Mar 24 18:32:47 1998 H.J. Lu <hjl@gnu.org>
+
+ * i386.h: Set LinearAddress for lidt and lgdt.
+
+Mon Mar 2 10:44:07 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_BOOL_ATTR): New macro.
+
+Thu Feb 26 15:54:31 1998 Michael Meissner <meissner@cygnus.com>
+
+ * d30v.h (FLAG_DELAY): New flag for delayed branches/jumps.
+
+Mon Feb 23 10:38:21 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_CAT3): Delete. Use CONCAT3 now.
+ (cgen_insn): Record syntax and format entries here, rather than
+ separately.
+
+Tue Feb 17 21:42:56 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.h (CGEN_SYNTAX_MAKE_FIELD): New macro.
+
+Tue Feb 17 16:00:56 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (cgen_insert_fn): Change type of result to const char *.
+ (cgen_parse_{signed,unsigned}_integer): Delete min,max arguments.
+ (CGEN_{INSN,KEYWORD,OPERAND}_NBOOL_ATTRS): Renamed from ..._MAX_ATTRS.
+
+Thu Feb 12 18:30:41 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * cgen.h (lookup_insn): New argument alias_p.
+
+Thu Feb 12 03:41:00 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+Fix rac to accept only a0:
+ * d10v.h (OPERAND_ACC): Split into:
+ (OPERAND_ACC0, OPERAND_ACC1) .
+ (OPERAND_GPR): Define.
+
+Wed Feb 11 17:31:53 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_FIELDS): Define here.
+ (CGEN_HW_ENTRY): New member `type'.
+ (hw_list): Delete decl.
+ (enum cgen_mode): Declare.
+ (CGEN_OPERAND): New member `hw'.
+ (enum cgen_operand_instance_type): Declare.
+ (CGEN_OPERAND_INSTANCE): New type.
+ (CGEN_INSN): New member `operands'.
+ (CGEN_OPCODE_DATA): Make hw_list const.
+ (get_insn_operands,lookup_insn): Add prototypes for.
+
+Tue Feb 3 17:11:23 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (CGEN_INSN_MAX_ATTRS): Renamed from CGEN_MAX_INSN_ATTRS.
+ (CGEN_HW_ENTRY): Move `next' entry to end of struct.
+ (CGEN_KEYWORD_MAX_ATTRS): Renamed from CGEN_MAX_KEYWORD_ATTRS.
+ (CGEN_OPERAND_MAX_ATTRS): Renamed from CGEN_MAX_OPERAND_ATTRS.
+
+Mon Feb 2 19:19:15 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * cgen.h: Correct typo in comment end marker.
+
+Mon Feb 2 17:10:38 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ * tic30.h: New file.
+
+Thu Jan 22 17:54:56 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.h: Add prototypes for cgen_save_fixups(),
+ cgen_restore_fixups(), and cgen_swap_fixups(). Change prototype
+ of cgen_asm_finish_insn() to return a char *.
+
+Wed Jan 14 17:21:43 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen.h: Formatting changes to improve readability.
+
+Mon Jan 12 11:37:36 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen.h (*): Clean up pass over `struct foo' usage.
+ (CGEN_ATTR): Make unsigned char.
+ (CGEN_ATTR_TYPE): Update.
+ (CGEN_ATTR_{ENTRY,TABLE}): New types.
+ (cgen_base): Move member `attrs' to cgen_insn.
+ (CGEN_KEYWORD): New member `null_entry'.
+ (CGEN_{SYNTAX,FORMAT}): New types.
+ (cgen_insn): Format and syntax separated from each other.
+
+Tue Dec 16 15:15:52 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v.h (d30v_opcode): Reorder flags somewhat, add new flags for
+ 2 word load/store, ADDppp/SUBppp, 16/32 bit multiply. Make
+ flags_{used,set} long.
+ (d30v_operand): Make flags field long.
+
+Mon Dec 1 12:24:44 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k.h: Fix comment describing operand types.
+
+Sun Nov 23 22:31:27 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v.h (SHORT_CMPU): Add case for cmpu instruction, and move
+ everything else after down.
+
+Tue Nov 18 18:45:14 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * d10v.h (OPERAND_FLAG): Split into:
+ (OPERAND_FFLAG, OPERAND_CFLAG) .
+
+Thu Nov 13 11:04:24 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips.h (struct mips_opcode): Changed comments to reflect new
+ field usage.
+
+Fri Oct 24 22:36:20 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * mips.h: Added to comments a quick-ref list of all assigned
+ operand type characters.
+ (OP_{MASK,SH}_PERFREG): New macros.
+
+Wed Oct 22 17:28:33 1997 Richard Henderson <rth@cygnus.com>
+
+ * sparc.h: Add '_' and '/' for v9a asr's.
+ Patch from David Miller <davem@vger.rutgers.edu>
+
+Tue Oct 14 13:22:29 1997 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h: Bit ops with absolute addresses not in the 8 bit
+ area are not available in the base model (H8/300).
+
+Thu Sep 25 13:03:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k.h: Remove documentation of ` operand specifier.
+
+Wed Sep 24 19:00:34 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k.h: Document q and v operand specifiers.
+
+Mon Sep 15 18:28:37 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (struct v850_opcode): Add processors field.
+ (PROCESSOR_V850, PROCESSOR_ALL): New bit constants.
+ (PROCESSOR_V850E, PROCESSOR_NOT_V850): New bit constants.
+ (PROCESSOR_V850EA): New bit constants.
+
+Mon Sep 15 11:29:43 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merge changes from Martin Hunt:
+
+ * d30v.h: Allow up to 64 control registers. Add
+ SHORT_A5S format.
+
+ * d30v.h (LONG_Db): New form for delayed branches.
+
+ * d30v.h: (LONG_Db): New form for repeati.
+
+ * d30v.h (SHORT_D2B): New form.
+
+ * d30v.h (SHORT_A2): New form.
+
+ * d30v.h (OPERAND_2REG): Add new operand to indicate 2
+ registers are used. Needed for VLIW optimization.
+
+Mon Sep 8 14:05:45 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen.h: Move assembler interface section
+ up so cgen_parse_operand_result is defined for cgen_parse_address.
+ (cgen_parse_address): Update prototype.
+
+Tue Sep 2 15:32:32 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (V850_OPREAND_ADJUST_SHORT_MEMORY): Removed.
+
+Tue Aug 26 12:21:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h (two_byte_segment_defaults): Correct base register 5 in
+ modes 1 and 2 to be ss rather than ds. From Gabriel Paubert
+ <paubert@iram.es>.
+
+ * i386.h: Set ud2 to 0x0f0b. From Gabriel Paubert
+ <paubert@iram.es>.
+
+ * i386.h: Comment fixes for ficom[p]?{s,l} from Gabriel Paubert
+ <paubert@iram.es>.
+
+ * i386.h (JUMP_ON_CX_ZERO): Uncomment (define again).
+ (JUMP_ON_ECX_ZERO): Remove commented out macro.
+
+Fri Aug 22 10:38:29 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (V850_NOT_R0): New flag.
+
+Mon Aug 18 11:05:58 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (struct v850_opcode): Remove flags field.
+
+Wed Aug 13 18:45:48 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850.h (struct v850_opcode): Add flags field.
+ (struct v850_operand): Extend meaning of 'bits' and 'shift'
+ fields.
+ (V850E_INSTRUCTION, V850EA_INSTRUCTION): New flags.
+ (V850E_PUSH_POP, V850E_IMMEDIATE16, V850E_IMMEDIATE32): New flags.
+
+Fri Aug 8 16:58:42 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * arc.h: New file.
+
+Thu Jul 24 21:16:58 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (sparc_opcodes): Declare as const.
+
+Thu Jul 10 12:53:25 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mips.h (FP_S, FP_D): Define. Bitmasks indicating if an insn
+ uses single or double precision floating point resources.
+ (INSN_NO_ISA, INSN_ISA1): Define.
+ (cpu specific INSN macros): Tweak into bitmasks outside the range
+ of INSN_ISA field.
+
+Mon Jun 16 14:10:00 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * i386.h: Fix pand opcode.
+
+Mon Jun 2 11:35:09 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips.h: Widen INSN_ISA and move it to a more convenient
+ bit position. Add INSN_3900.
+
+Tue May 20 11:25:29 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips.h (struct mips_opcode): added new field membership.
+
+Mon May 12 16:26:50 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * i386.h (movd): only Reg32 is allowed.
+
+ * i386.h: add fcomp and ud2. From Wayne Scott
+ <wscott@ichips.intel.com>.
+
+Mon May 5 17:16:21 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Add MMX instructions.
+
+Mon May 5 12:45:19 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * i386.h: Remove W modifier from conditional move instructions.
+
+Mon Apr 14 14:56:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Change the opcodes for fsubp, fsubrp, fdivp, and fdivrp
+ with no arguments to match that generated by the UnixWare
+ assembler.
+
+Thu Apr 10 14:35:00 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen.h (<cpu>_cgen_assemble_insn): New arg for errmsg.
+ (cgen_parse_operand_fn): Declare.
+ (cgen_init_parse_operand): Declare.
+ (cgen_parse_operand): Renamed from cgen_asm_parse_operand,
+ new argument `want'.
+ (enum cgen_parse_operand_result): Renamed from cgen_asm_result.
+ (enum cgen_parse_operand_type): New enum.
+
+Sat Apr 5 13:14:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Revert last patch for the NON_BROKEN_OPCODES cases.
+
+Fri Apr 4 11:46:11 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen.h: New file.
+
+Fri Apr 4 14:02:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Correct opcode values for fsubp, fsubrp, fdivp, and
+ fdivrp.
+
+Tue Mar 25 22:57:26 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850.h (extract): Make unsigned.
+
+Mon Mar 24 14:38:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Add iclr.
+
+Thu Mar 20 19:49:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Change DW to W for cmpxchg and xadd, since they don't
+ take a direction bit.
+
+Sat Mar 15 19:03:29 1997 H.J. Lu <hjl@lucon.org>
+
+ * sparc.h (sparc_opcode_lookup_arch): Use full prototype.
+
+Fri Mar 14 15:22:01 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc.h: Include <ansidecl.h>. Update function declarations to
+ use prototypes, and to use const when appropriate.
+
+Thu Mar 6 14:18:30 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_RELAX): Define.
+
+Mon Feb 24 15:15:56 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h: Change pre_defined_registers to
+ d10v_predefined_registers and reg_name_cnt to d10v_reg_name_cnt.
+
+Sat Feb 22 21:25:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * mips.h: Add macros for cop0, cop1 cop2 and cop3.
+ Change mips_opcodes from const array to a pointer,
+ and change bfd_mips_num_opcodes from const int to int,
+ so that we can increase the size of the mips opcodes table
+ dynamically.
+
+Fri Feb 21 16:34:18 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d30v.h (FLAG_X): Remove unused flag.
+
+Tue Feb 18 17:37:20 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d30v.h: New file.
+
+Fri Feb 14 13:16:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (PDS_NAME): Macro to access name field of predefined symbols.
+ (PDS_VALUE): Macro to access value field of predefined symbols.
+ (tic80_next_predefined_symbol): Add prototype.
+
+Mon Feb 10 10:32:17 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (tic80_symbol_to_value): Change prototype to match
+ change in function, added class parameter.
+
+Thu Feb 6 17:30:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_OPERAND_ENDMASK): Add for flagging TIc80
+ endmask fields, which are somewhat weird in that 0 and 32 are
+ treated exactly the same.
+
+Thu Jan 30 13:46:18 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h: Change all the OPERAND defines to use the form (1 << X)
+ rather than a constant that is 2**X. Reorder them to put bits for
+ operands that have symbolic names in the upper bits, so they can
+ be packed into an int where the lower bits contain the value that
+ corresponds to that symbolic name.
+ (predefined_symbo): Add struct.
+ (tic80_predefined_symbols): Declare array of translations.
+ (tic80_num_predefined_symbols): Declare size of that array.
+ (tic80_value_to_symbol): Declare function.
+ (tic80_symbol_to_value): Declare function.
+
+Wed Jan 29 09:37:25 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.h (MN10200_OPERAND_RELAX): Define.
+
+Sat Jan 18 15:18:59 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_NO_R0_DEST): Add for opcodes where r0 cannot
+ be the destination register.
+
+Thu Jan 16 20:48:55 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (struct tic80_opcode): Change "format" field to "flags".
+ (FMT_UNUSED, FMT_SI, FMT_LI, FMT_REG): Delete.
+ (TIC80_VECTOR): Define a flag bit for the flags. This one means
+ that the opcode can have two vector instructions in a single
+ 32 bit word and we have to encode/decode both.
+
+Tue Jan 14 19:37:09 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_OPERAND_PCREL): Renamed from
+ TIC80_OPERAND_RELATIVE for PC relative.
+ (TIC80_OPERAND_BASEREL): New flag bit for register
+ base relative.
+
+Mon Jan 13 15:56:38 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_OPERAND_FLOAT): Add for floating point operands.
+
+Mon Jan 6 10:51:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_OPERAND_SCALED): Operand may have optional
+ ":s" modifier for scaling.
+
+Sun Jan 5 12:12:19 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_OPERAND_M_SI): Add operand modifier for ":m".
+ (TIC80_OPERAND_M_LI): Ditto
+
+Sat Jan 4 19:02:44 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (TIC80_OPERAND_BITNUM): Renamed from TIC80_OPERAND_CC_SZ.
+ (TIC80_OPERAND_CC): New define for condition code operand.
+ (TIC80_OPERAND_CR): New define for control register operand.
+
+Fri Jan 3 16:22:23 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h (struct tic80_opcode): Name changed.
+ (struct tic80_opcode): Remove format field.
+ (struct tic80_operand): Add insertion and extraction functions.
+ (TIC80_OPERAND_*): Remove old bogus values, start adding new
+ correct ones.
+ (FMT_*): Ditto.
+
+Tue Dec 31 15:05:41 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850.h (V850_OPERAND_ADJUST_SHORT_MEMORY): New flag to adjust
+ type IV instruction offsets.
+
+Fri Dec 27 22:23:10 1996 Fred Fish <fnf@cygnus.com>
+
+ * tic80.h: New file.
+
+Wed Dec 18 10:06:31 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.h (MN10200_OPERAND_NOCHECK): Define.
+
+Sat Dec 14 10:48:31 1996 Fred Fish <fnf@ninemoons.com>
+
+ * mn10200.h: Fix comment, mn10200_operand not powerpc_operand.
+ * mn10300.h: Fix comment, mn10300_operand not powerpc_operand.
+ * v850.h: Fix comment, v850_operand not powerpc_operand.
+
+Mon Dec 9 16:45:39 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200.h: Flesh out structures and definitions needed by
+ the mn10200 assembler & disassembler.
+
+Tue Nov 26 10:46:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h: Add mips16 definitions.
+
+Mon Nov 25 17:56:54 1996 J.T. Conklin <jtc@cygnus.com>
+
+ * m68k.h: Document new <, >, m, n, o and p operand specifiers.
+
+Wed Nov 20 10:59:41 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_PCREL): Define.
+ (MN10300_OPERAND_MEMADDR): Define.
+
+Tue Nov 19 13:30:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_REG_LIST): Define.
+
+Wed Nov 6 13:41:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_SPLIT): Define.
+
+Tue Nov 5 13:26:12 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_EXTENDED): Define.
+
+Mon Nov 4 12:52:48 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_REPEATED): Define.
+
+Fri Nov 1 10:31:02 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha.h: Don't include "bfd.h"; private relocation types are now
+ negative to minimize problems with shared libraries. Organize
+ instruction subsets by AMASK extensions and PALcode
+ implementation.
+ (struct alpha_operand): Move flags slot for better packing.
+
+Tue Oct 29 12:19:10 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850.h (V850_OPERAND_RELAX): New operand flag.
+
+Thu Oct 10 14:29:11 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (FMT_*): Move operand format definitions
+ here.
+
+Tue Oct 8 14:48:07 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (MN10300_OPERAND_PAREN): Define.
+
+Mon Oct 7 16:52:11 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300.h (mn10300_opcode): Add "format" field.
+ (MN10300_OPERAND_*): Define.
+
+Thu Oct 3 10:33:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10x00.h: Delete.
+ * mn10200.h, mn10300.h: New files.
+
+Wed Oct 2 21:31:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10x00.h: New file.
+
+Fri Sep 27 18:26:46 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850.h: Add new flag to indicate this instruction uses a PC
+ displacement.
+
+Fri Sep 13 14:58:13 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (stmac): Add missing instruction.
+
+Sat Aug 31 16:02:03 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850.h (v850_opcode): Remove "size" field. Add "memop"
+ field.
+
+Fri Aug 23 10:39:08 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850.h (V850_OPERAND_EP): Define.
+
+ * v850.h (v850_opcode): Add size field.
+
+Thu Aug 22 16:51:25 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * v850.h (v850_operands): Add insert and extract fields, pointers
+ to functions used to handle unusual operand encoding.
+ (V850_OPERAND_REG, V850_OPERAND_SRG, V850_OPERAND_CC,
+ V850_OPERAND_SIGNED): Defined.
+
+Wed Aug 21 17:45:10 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * v850.h (v850_operands): Add flags field.
+ (OPERAND_REG, OPERAND_NUM): Defined.
+
+Tue Aug 20 14:52:02 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * v850.h: New file.
+
+Fri Aug 16 14:44:15 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * mips.h (OP_SH_LOCC, OP_SH_HICC, OP_MASK_CC, OP_SH_COP1NORM,
+ OP_MASK_COP1NORM, OP_SH_COP1SPEC, OP_MASK_COP1SPEC,
+ OP_MASK_COP1SCLR, OP_MASK_COP1CMP, OP_SH_COP1CMP, OP_SH_FORMAT,
+ OP_MASK_FORMAT, OP_SH_TRUE, OP_MASK_TRUE, OP_SH_GE, OP_MASK_GE,
+ OP_SH_UNSIGNED, OP_MASK_UNSIGNED, OP_SH_HINT, OP_MASK_HINT):
+ Defined.
+
+Fri Aug 16 00:15:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * hppa.h (pitlb, pitlbe, iitlba, iitlbp, fic, fice): Accept
+ a 3 bit space id instead of a 2 bit space id.
+
+Thu Aug 15 13:11:46 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h: Add some additional defines to support the
+ assembler in determining which operations can be done in parallel.
+
+Tue Aug 6 11:13:22 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (SN): Define.
+ (eepmov.b): Renamed from "eepmov"
+ (nop, bpt, rte, rts, sleep, clrmac): These have no size associated
+ with them.
+
+Fri Jul 26 11:47:10 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h (OPERAND_SHIFT): New operand flag.
+
+Thu Jul 25 12:06:22 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h: Changes for divs, parallel-only instructions, and
+ signed numbers.
+
+Mon Jul 22 11:21:15 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h (pd_reg): Define. Putting the definition here allows
+ the assembler and disassembler to share the same struct.
+
+Mon Jul 22 12:15:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i960.h (i960_opcodes): "halt" takes an argument. From Stephen
+ Williams <steve@icarus.com>.
+
+Wed Jul 17 14:46:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v.h: New file.
+
+Thu Jul 11 12:09:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (band, bclr): Force high bit of immediate nibble to zero.
+
+Wed Jul 3 14:30:12 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * m68k.h (mcf5200): New macro.
+ Document names of coldfire control registers.
+
+Tue Jul 2 23:05:45 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (SRC_IN_DST): Define.
+
+ * h8300.h (UNOP3): Mark the register operand in this insn
+ as a source operand, not a destination operand.
+ (SHIFT_2, SHIFT_IMM): Remove. Eliminate all references.
+ (UNOP3): Change SHIFT_IMM to IMM for H8/S bitops. Mark
+ register operand with SRC_IN_DST.
+
+Fri Jun 21 13:52:17 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha.h: New file.
+
+Thu Jun 20 15:02:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * rs6k.h: Remove obsolete file.
+
+Wed Jun 19 15:29:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Correct opcode values for faddp, fsubp, fsubrp, fmulp,
+ fdivp, and fdivrp. Add ffreep.
+
+Tue Jun 18 16:06:00 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * h8300.h: Reorder various #defines for readability.
+ (ABS32SRC, ABS32DST, DSP32LIST, ABS32LIST, A32LIST): Define.
+ (BITOP): Accept additional (unused) argument. All callers changed.
+ (EBITOP): Likewise.
+ (O_LAST): Bump.
+ (ldc, stc, movb, movw, movl): Use 32bit offsets and absolutes.
+
+ * h8300.h (EXR, SHIFT_2, MACREG, SHIFT_IMM, RDINC): Define.
+ (O_TAS, O_CLRMAC, O_LDMAC, O_MAC, O_LDM, O_STM): Define.
+ (BITOP, EBITOP): Handle new H8/S addressing modes for
+ bit insns.
+ (UNOP3): Handle new shift/rotate insns on the H8/S.
+ (insns using exr): New instructions.
+ (tas, mac, ldmac, clrmac, ldm, stm): New instructions.
+
+Thu May 23 16:56:48 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (add.l): Undo Apr 5th change. The manual I had
+ was incorrect.
+
+Mon May 6 23:38:22 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (START): Remove.
+ (MEMRELAX): Define. Mark absolute memory operands in mov.b, mov.w
+ and mov.l insns that can be relaxed.
+
+Tue Apr 30 18:30:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386.h: Remove Abs32 from lcall.
+
+Mon Apr 22 17:09:23 1996 Doug Evans <dje@blues.cygnus.com>
+
+ * sparc.h (SPARC_OPCODE_ARCH_V9_P): New macro.
+ (SLCPOP): New macro.
+ Mark X,Y opcode letters as in use.
+
+Thu Apr 11 17:28:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc.h (F_FLOAT, F_FBR): Define.
+
+Fri Apr 5 16:55:34 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300.h (ABS8MEM): Renamed from ABSMOV. Remove ABSMOV
+ from all insns.
+ (ABS8SRC,ABS8DST): Add ABS8MEM.
+ (add.l): Fix reg+reg variant.
+ (eepmov.w): Renamed from eepmovw.
+ (ldc,stc): Fix many cases.
+
+Sun Mar 31 13:30:03 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (SPARC_OPCODE_ARCH_MASK): New macro.
+
+Thu Mar 7 15:08:23 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (O): Mark operand letter as in use.
+
+Tue Feb 20 20:46:21 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (sparc_{encode,decode}_sparclet_cpreg): Declare.
+ Mark operand letters uU as in use.
+
+Mon Feb 19 01:59:08 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (sparc_opcode_arch_val): Add SPARC_OPCODE_ARCH_SPARCLET.
+ (sparc_opcode_arch): Delete member `conflicts'. Add `supported'.
+ (SPARC_OPCODE_SUPPORTED): New macro.
+ (SPARC_OPCODE_CONFLICT_P): Rewrite.
+ (F_NOTV9): Delete.
+
+Fri Feb 16 12:23:34 1996 Jeffrey A Law (law@cygnus.com)
+
+ * sparc.h (sparc_opcode_lookup_arch) Make return type in
+ declaration consistent with return type in definition.
+
+Wed Feb 14 18:14:11 1996 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386.h (i386_optab): Remove Data32 from pushf and popf.
+
+Thu Feb 8 14:27:21 1996 James Carlson <carlson@xylogics.com>
+
+ * i386.h (i386_regtab): Add 80486 test registers.
+
+Mon Feb 5 18:35:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i960.h (I_HX): Define.
+ (i960_opcodes): Add HX instruction.
+
+Mon Jan 29 12:43:39 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ * i386.h: Fix waiting forms of finit, fstenv, fsave, fstsw, fstcw,
+ and fclex.
+
+Wed Jan 24 22:36:59 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (enum sparc_opcode_arch_val): Replaces sparc_architecture.
+ (SPARC_OPCODE_CONFLICT_P): Renamed from ARCHITECTURES_CONFLICT_P.
+ (bfd_* defines): Delete.
+ (sparc_opcode_archs): Replaces architecture_pname.
+ (sparc_opcode_lookup_arch): Declare.
+ (NUMOPCODES): Delete.
+
+Mon Jan 22 08:24:32 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc.h (enum sparc_architecture): Add v9a.
+ (ARCHITECTURES_CONFLICT_P): Update.
+
+Thu Dec 28 13:27:53 1995 John Hassey <hassey@rtp.dg.com>
+
+ * i386.h: Added Pentium Pro instructions.
+
+Thu Nov 2 22:59:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k.h: Document new 'W' operand place.
+
+Tue Oct 24 10:49:10 1995 Jeffrey A Law (law@cygnus.com)
+
+ * hppa.h: Add lci and syncdma instructions.
+
+Mon Oct 23 11:09:16 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * mips.h: Added INSN_4100 flag to mark NEC VR4100 specific
+ instructions.
+
+Mon Oct 16 10:28:15 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc.h (PPC_OPCODE_{COMMON,ANY}): New opcode flags for
+ assembler's -mcom and -many switches.
+
+Wed Oct 11 16:56:33 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * i386.h: Fix cmpxchg8b extension opcode description.
+
+Thu Oct 5 18:03:36 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * i386.h: Add Pentium instructions wrmsr, rdtsc, rdmsr, cmpxchg8b,
+ and register cr4.
+
+Tue Sep 19 15:26:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k.h: Change comment: split type P into types 0, 1 and 2.
+
+Wed Aug 30 13:50:55 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (sparc_{encode,decode}_prefetch): Declare.
+
+Tue Aug 29 15:34:58 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (sparc_{encode,decode}_{asi,membar}): Declare.
+
+Wed Aug 2 18:32:19 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68kmri.h: Remove.
+
+ * m68k.h: Move tables into opcodes/m68k-opc.c, leaving just the
+ declarations. Remove F_ALIAS and flag field of struct
+ m68k_opcode. Change arch field of struct m68k_opcode to unsigned
+ int. Make name and args fields of struct m68k_opcode const.
+
+Wed Aug 2 08:16:46 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc.h (F_NOTV9): Define.
+
+Tue Jul 11 14:20:42 1995 Jeff Spiegel <jeffs@lsil.com>
+
+ * mips.h (INSN_4010): Define.
+
+Wed Jun 21 18:49:51 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * m68k.h (TBL1): Reverse sense of "round" argument in result.
+
+ Changes from Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>:
+ * m68k.h: Fix argument descriptions of coprocessor
+ instructions to allow only alterable operands where appropriate.
+ [!NO_DEFAULT_SIZES]: An omitted size defaults to `w'.
+ (m68k_opcode_aliases): Add more aliases.
+
+Fri Apr 14 22:15:34 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * m68k.h: Added explcitly short-sized conditional branches, and a
+ bunch of aliases (fmov*, ftest*, tdivul) to support gcc's
+ svr4-based configurations.
+
+Mon Mar 13 21:30:01 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Mon Feb 27 08:36:39 1995 Bryan Ford <baford@cs.utah.edu>
+ * i386.h: added missing Data16/Data32 flags to a few instructions.
+
+Wed Mar 8 15:19:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (OP_MASK_FR, OP_SH_FR): Define.
+ (OP_MASK_BCC, OP_SH_BCC): Define.
+ (OP_MASK_PREFX, OP_SH_PREFX): Define.
+ (OP_MASK_CCC, OP_SH_CCC): Define.
+ (INSN_READ_FPR_R): Define.
+ (INSN_RFE): Delete.
+
+Wed Mar 8 03:13:23 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * m68k.h (enum m68k_architecture): Deleted.
+ (struct m68k_opcode_alias): New type.
+ (m68k_opcodes): Now const. Deleted opcode aliases with exactly
+ matching constraints, values and flags. As a side effect of this,
+ the MOTOROLA_SYNTAX_ONLY and MIT_SYNTAX_ONLY macros, which so far
+ as I know were never used, now may need re-examining.
+ (numopcodes): Now const.
+ (m68k_opcode_aliases, numaliases): New variables.
+ (endop): Deleted.
+ [DONT_DEFINE_TABLE]: Declare numopcodes, numaliases, and
+ m68k_opcode_aliases; update declaration of m68k_opcodes.
+
+Mon Mar 6 10:02:00 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa.h (delay_type): Delete unused enumeration.
+ (pa_opcode): Replace unused delayed field with an architecture
+ field.
+ (pa_opcodes): Mark each instruction as either PA1.0 or PA1.1.
+
+Fri Mar 3 16:10:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (INSN_ISA4): Define.
+
+Fri Feb 24 19:13:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (M_DLA_AB, M_DLI): Define.
+
+Thu Feb 23 17:33:09 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa.h (fstwx): Fix single-bit error.
+
+Wed Feb 15 12:19:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips.h (M_ULD, M_ULD_A, M_USD, M_USD_A): Define.
+
+Mon Feb 6 10:35:23 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386.h: added cpuid instruction , and dr[0-7] aliases for the
+ debug registers. From Charles Hannum (mycroft@netbsd.org).
+
+Mon Feb 6 03:31:54 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Changes from Bryan Ford <baford@schirf.cs.utah.edu> for 16-bit
+ i386 support:
+ * i386.h (MOV_AX_DISP32): New macro.
+ (i386_optab): Added Data16 and Data32 as needed. Added "w" forms
+ of several call/return instructions.
+ (ADDR_PREFIX_OPCODE): New macro.
+
+Mon Jan 23 16:45:43 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sat Jan 21 17:50:38 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * ../include/opcode/vax.h (struct vot_wot, field `args'): make
+ it pointer to const char;
+ (struct vot, field `name'): ditto.
+
+Thu Jan 19 14:47:53 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * vax.h: Supply and properly group all values in end sentinel.
+
+Tue Jan 17 10:55:30 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * mips.h (INSN_ISA, INSN_4650): Define.
+
+Wed Oct 19 13:34:17 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * a29k.h: Add operand type 'I' for `inv' and `iretinv'. On
+ systems with a separate instruction and data cache, such as the
+ 29040, these instructions take an optional argument.
+
+Wed Sep 14 17:44:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mips.h (INSN_STORE_MEMORY): Correct value to not conflict with
+ INSN_TRAP.
+
+Tue Sep 6 11:39:08 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mips.h (INSN_STORE_MEMORY): Define.
+
+Thu Jul 28 19:28:07 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * sparc.h: Document new operand type 'x'.
+
+Tue Jul 26 17:48:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i960.h (I_CX2): New instruction category. It includes
+ instructions available on Cx and Jx processors.
+ (I_JX): New instruction category, for JX-only instructions.
+ (i960_opcodes): Put eshro and sysctl in I_CX2 category. Added
+ Jx-only instructions, in I_JX category.
+
+Wed Jul 13 18:43:47 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ns32k.h (endop): Made pointer const too.
+
+Sun Jul 10 11:01:09 1994 Ian Dall (dall@hfrd.dsto.gov.au)
+
+ * ns32k.h: Drop Q operand type as there is no correct use
+ for it. Add I and Z operand types which allow better checking.
+
+Thu Jul 7 12:34:48 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * h8300.h (xor.l) :fix bit pattern.
+ (L_2): New size of operand.
+ (trapa): Use it.
+
+Fri Jun 10 16:38:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m68k.h: Move "trap" before "tpcc" to change disassembly.
+
+Fri Jun 3 15:57:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * sparc.h: Include v9 definitions.
+
+Thu Jun 2 12:23:17 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * m68k.h (m68060): Defined.
+ (m68040up, mfloat, mmmu): Include it.
+ (struct m68k_opcode): Widen `arch' field.
+ (m68k_opcodes): Updated for M68060. Removed comments that were
+ instructions commented out by "JF" years ago.
+
+Thu Apr 28 18:31:14 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * m68k.h (struct m68k_opcode): Shorten `arch' field to 8 bits, and
+ add a one-bit `flags' field.
+ (F_ALIAS): New macro.
+
+Wed Apr 27 11:29:52 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * h8300.h (dec, inc): Get encoding right.
+
+Mon Apr 4 13:12:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc.h (struct powerpc_operand): Removed signedp field; just use
+ a flag instead.
+ (PPC_OPERAND_SIGNED): Define.
+ (PPC_OPERAND_SIGNOPT): Define.
+
+Thu Mar 31 19:34:08 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i386.h (IS_JUMP_ON_ECX_ZERO, "jcxz" pattern): Operand size
+ prefix is 0x66, not 0x67. Patch from H.J. Lu (hlu@nynexst.com).
+
+Thu Mar 3 15:51:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i386.h: Reverse last change. It'll be handled in gas instead.
+
+Thu Feb 24 15:29:05 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i386.h (sar): Disabled the two-operand Imm1 form, since it was
+ slower on the 486 and used the implicit shift count despite the
+ explicit operand. The one-operand form is still available to get
+ the shorter form with the implicit shift count.
+
+Thu Feb 17 12:27:52 1994 Torbjorn Granlund (tege@mexican.cygnus.com)
+
+ * hppa.h: Fix typo in fstws arg string.
+
+Wed Feb 9 21:23:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc.h (struct powerpc_opcode): Make operands field unsigned.
+
+Mon Feb 7 19:14:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc.h (PPC_OPCODE_601): Define.
+
+Fri Feb 4 23:43:50 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa.h (addb): Use '@' for addb and addib pseudo ops.
+ (so we can determine valid completers for both addb and addb[tf].)
+
+ * hppa.h (xmpyu): No floating point format specifier for the
+ xmpyu instruction.
+
+Fri Feb 4 23:36:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc.h (PPC_OPERAND_NEXT): Define.
+ (PPC_OPERAND_NEGATIVE): Change value to make room for above.
+ (struct powerpc_macro): Define.
+ (powerpc_macros, powerpc_num_macros): Declare.
+
+Fri Jan 21 19:13:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc.h: New file. Header file for PowerPC opcode table.
+
+Mon Jan 17 00:14:23 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa.h: More minor template fixes for sfu and copr (to allow
+ for easier disassembly).
+
+ * hppa.h: Fix templates for all the sfu and copr instructions.
+
+Wed Dec 15 15:12:42 1993 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i386.h (push): Permit Imm16 operand too.
+
+Sat Dec 11 16:14:06 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * h8300.h (andc): Exists in base arch.
+
+Wed Dec 1 12:15:32 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * From Hisashi MINAMINO <minamino@sramhc.sra.co.jp>
+ * hppa.h: #undef NONE to avoid conflict with hiux include files.
+
+Sun Nov 21 22:06:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa.h: Add FP quadword store instructions.
+
+Wed Nov 17 17:13:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h: (M_J_A): Added.
+ (M_LA): Removed.
+
+Mon Nov 8 12:12:47 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (OP_MASK_CACHE, OP_SH_CACHE): Define. From Ted Lemon
+ <mellon@pepper.ncd.com>.
+
+Sun Nov 7 00:30:11 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa.h: Immediate field in probei instructions is unsigned,
+ not low-sign extended.
+
+Wed Nov 3 10:30:00 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m88k.h (RRI10MASK): Change from 0xfc00ffe0 to 0xfc00fc00.
+
+Tue Nov 2 12:41:30 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * i386.h: Add "fxch" without operand.
+
+Mon Nov 1 18:13:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (M_JAL_1, M_JAL_2, M_JAL_A): Added.
+
+Sat Oct 2 22:26:11 1993 Jeffrey A Law (law@snake.cs.utah.edu)
+
+ * hppa.h: Add gfw and gfr to the opcode table.
+
+Wed Sep 29 16:23:00 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * m88k.h: extended to handle m88110.
+
+Tue Sep 28 19:19:08 1993 Jeffrey A Law (law@snake.cs.utah.edu)
+
+ * hppa.h (be, ble): Use operand type 'z' to denote absolute branch
+ addresses.
+
+Tue Sep 14 14:04:35 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i960.h (i960_opcodes): Properly bracket initializers.
+
+Mon Sep 13 12:50:52 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * m88k.h (BOFLAG): rewrite to avoid nested comment.
+
+Mon Sep 13 15:46:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m68k.h (two): Protect second argument with parentheses.
+
+Fri Sep 10 16:29:47 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * i386.h (i386_optab): Added new instruction "rsm" (for i386sl).
+ Deleted old in/out instructions in "#if 0" section.
+
+Thu Sep 9 17:42:19 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i386.h (i386_optab): Properly bracket initializers.
+
+Wed Aug 25 13:50:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hppa.h (pa_opcode): Use '|' for movb and movib insns. (From
+ Jeff Law, law@cs.utah.edu).
+
+Mon Aug 23 16:55:03 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * i386.h (lcall): Accept Imm32 operand also.
+
+Mon Aug 23 12:43:11 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (M_ABSU): Removed (absolute value of unsigned number??).
+ (M_DABS): Added.
+
+Thu Aug 19 15:08:37 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h (INSN_*): Changed values. Removed unused definitions.
+ Added INSN_COND_BRANCH_LIKELY, INSN_ISA2 and INSN_ISA3. Split
+ INSN_LOAD_DELAY into INSN_LOAD_MEMORY_DELAY and
+ INSN_LOAD_COPROC_DELAY. Split INSN_COPROC_DELAY into
+ INSN_COPROC_MOVE_DELAY and INSN_COPROC_MEMORY_DELAY.
+ (M_*): Added new values for r6000 and r4000 macros.
+ (ANY_DELAY): Removed.
+
+Wed Aug 18 15:37:48 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h: Added M_LI_S and M_LI_SS.
+
+Tue Aug 17 07:08:08 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * h8300.h: Get some rare mov.bs correct.
+
+Thu Aug 5 09:15:17 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sparc.h: Don't define const ourself; rely on ansidecl.h having
+ been included.
+
+Fri Jul 30 18:41:11 1993 John Gilmore (gnu@cygnus.com)
+
+ * sparc.h (F_JSR, F_UNBR, F_CONDBR): Add new flags to mark
+ jump instructions, for use in disassemblers.
+
+Thu Jul 22 07:25:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * m88k.h: Make bitfields just unsigned, not unsigned long or
+ unsigned short.
+
+Wed Jul 21 11:55:31 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * hppa.h: New argument type 'y'. Use in various float instructions.
+
+Mon Jul 19 17:17:03 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * hppa.h (break): First immediate field is unsigned.
+
+ * hppa.h: Add rfir instruction.
+
+Sun Jul 18 16:28:08 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * mips.h: Split the actual table out into ../../opcodes/mips-opc.c.
+
+Fri Jul 16 09:59:29 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h: Reworked the hazard information somewhat, and fixed some
+ bugs in the instruction hazard descriptions.
+
+Thu Jul 15 12:42:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m88k.h: Corrected a couple of opcodes.
+
+Tue Jul 6 15:17:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.h: Replaced with version from Ralph Campbell and OSF. The
+ new version includes instruction hazard information, but is
+ otherwise reasonably similar.
+
+Thu Jul 1 20:36:17 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * h8300.h: Fix typo in UNOP3 (affected sh[al][lr].l).
+
+Fri Jun 11 18:38:44 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ Patches from Jeff Law, law@cs.utah.edu:
+ * hppa.h: Clean up some of the OLD_TABLE, non-OLD_TABLE braindamage.
+ Make the tables be the same for the following instructions:
+ "bb", "addb[tf]", "addib[tf]", "add", "add[loc]", "addco",
+ "sh[123]add", "sh[123]add[lo]", "sub", "sub[obt]", "sub[bt]o",
+ "ds", "comclr", "addi", "addi[ot]", "addito", "subi", "subio",
+ "comiclr", "fadd", "fsub", "fmpy", "fdiv", "fsqrt", "fabs",
+ "frnd", "fcpy", "fcnvff", "fcnvxf", "fcnvfx", "fcnvfxt",
+ "fcmp", and "ftest".
+
+ * hppa.h: Make new and old tables the same for "break", "mtctl",
+ "mfctl", "bb", "ssm", "rsm", "xmpyu", "fmpyadd", "fmpysub".
+ Fix typo in last patch. Collapse several #ifdefs into a
+ single #ifdef.
+
+ * hppa.h: Delete remaining OLD_TABLE code. Bring some
+ of the comments up-to-date.
+
+ * hppa.h: Update "free list" of letters and update
+ comments describing each letter's function.
+
+Fri Jun 4 15:41:37 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * h8300.h: checkpoint, includes H8/300-H opcodes.
+
+Thu Jun 3 15:42:59 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Patches from Jeffrey Law <law@cs.utah.edu>.
+ * hppa.h: Rework single precision FP
+ instructions so that they correctly disassemble code
+ PA1.1 code.
+
+Thu May 27 19:21:22 1993 Bruce Bauman (boot@osf.org)
+
+ * i386.h (i386_optab, mov pattern): Remove Mem16 restriction from
+ mov to allow instructions like mov ss,xyz(ecx) to assemble.
+
+Tue May 25 00:39:40 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * hppa.h: Use new version from Utah if OLD_TABLE isn't defined;
+ gdb will define it for now.
+
+Mon May 24 15:20:06 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * sparc.h: Don't end enumerator list with comma.
+
+Fri May 14 15:15:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Based on patches from davidj@ICSI.Berkeley.EDU (David Johnson):
+ * mips.h (OP_MASK_COPZ, OP_SH_COPZ): Define.
+ ("bc2t"): Correct typo.
+ ("[ls]wc[023]"): Use T rather than t.
+ ("c[0123]"): Define general coprocessor instructions.
+
+Mon May 10 06:02:25 1993 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * m68k.h: Move split point for gcc compilation more towards
+ middle.
+
+Fri Apr 9 13:26:16 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * rs6k.h: Clean up instructions for primary opcode 19 (many were
+ simply wrong, ics, rfi, & rfsvc were missing).
+ Add "a" to opr_ext for "bb". Doc fix.
+
+Thu Mar 18 13:45:31 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * i386.h: 486 extensions from John Hassey (hassey@dg-rtp.dg.com).
+ * mips.h: Add casts, to suppress warnings about shifting too much.
+ * m68k.h: Document the placement code '9'.
+
+Thu Feb 18 02:03:14 1993 John Gilmore (gnu@cygnus.com)
+
+ * m68k.h (BREAK_UP_BIG_DECL, AND_OTHER_PART): Add kludge which
+ allows callers to break up the large initialized struct full of
+ opcodes into two half-sized ones. This permits GCC to compile
+ this module, since it takes exponential space for initializers.
+ (numopcodes, endop): Revise to use AND_OTHER_PART in size calcs.
+
+Thu Feb 4 02:06:56 1993 John Gilmore (gnu@cygnus.com)
+
+ * a29k.h: Remove RCS crud, update GPL to v2, update copyrights.
+ * convex.h: Added, from GDB's convx-opcode.h. Added CONST to all
+ initialized structs in it.
+
+Thu Jan 28 21:32:22 1993 John Gilmore (gnu@cygnus.com)
+
+ Delta 88 changes inspired by Carl Greco, <cgreco@Creighton.Edu>:
+ * m88k.h (PMEM): Avoid previous definition from <sys/param.h>.
+ (AND): Change to AND_ to avoid ansidecl.h `AND' conflict.
+
+Sat Jan 23 18:10:49 PST 1993 Ralph Campbell (ralphc@pyramid.com)
+
+ * mips.h: document "i" and "j" operands correctly.
+
+Thu Jan 7 15:58:13 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips.h: Removed endianness dependency.
+
+Sun Jan 3 14:13:35 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * h8300.h: include info on number of cycles per instruction.
+
+Mon Dec 21 21:29:08 1992 Stu Grossman (grossman at cygnus.com)
+
+ * hppa.h: Move handy aliases to the front. Fix masks for extract
+ and deposit instructions.
+
+Sat Dec 12 16:09:48 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * i386.h: accept shld and shrd both with and without the shift
+ count argument, which is always %cl.
+
+Fri Nov 27 17:13:18 1992 Ken Raeburn (raeburn at cygnus.com)
+
+ * i386.h (i386_optab_end, i386_regtab_end): Now const.
+ (one_byte_segment_defaults, two_byte_segment_defaults,
+ i386_prefixtab_end): Ditto.
+
+Mon Nov 23 10:47:25 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * vax.h (bb*): Use "v" (bitfield type), not "a" (address operand)
+ for operand 2; from John Carr, jfc@dsg.dec.com.
+
+Wed Nov 4 07:36:49 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * m68k.h: Define FIXED_SIZE_BRANCH, so bsr and bra instructions
+ always use 16-bit offsets. Makes calculated-size jump tables
+ feasible.
+
+Fri Oct 16 22:52:43 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * i386.h: Fix one-operand forms of in* and out* patterns.
+
+Tue Sep 22 14:08:14 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * m68k.h: Added CPU32 support.
+
+Tue Sep 22 00:38:41 1992 John Gilmore (gnu@cygnus.com)
+
+ * mips.h (break): Disassemble the argument. Patch from
+ jonathan@cs.stanford.edu (Jonathan Stone).
+
+Wed Sep 9 11:25:28 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68k.h: merged Motorola and MIT syntax.
+
+Thu Sep 3 09:33:22 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * m68k.h (pmove): make the tests less strict, the 68k book is
+ wrong.
+
+Tue Aug 25 23:25:19 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * m68k.h (m68ec030): Defined as alias for 68030.
+ (m68k_opcodes): New type characters "3" for 68030 MMU regs and "t"
+ for immediate 0-7 added. Set up some opcodes (ptest, bkpt) to use
+ them. Tightened description of "fmovex" to distinguish it from
+ some "pmove" encodings. Added "pmove" for 68030 MMU regs, cleaned
+ up descriptions that claimed versions were available for chips not
+ supporting them. Added "pmovefd".
+
+Mon Aug 24 12:04:51 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * m68k.h: fix where the . goes in divull
+
+Wed Aug 19 11:22:24 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68k.h: the cas2 instruction is supposed to be written with
+ indirection on the last two operands, which can be either data or
+ address registers. Added a new operand type 'r' which accepts
+ either register type. Added new cases for cas2l and cas2w which
+ use them. Corrected masks for cas2 which failed to recognize use
+ of address register.
+
+Fri Aug 14 14:20:38 1992 Per Bothner (bothner@cygnus.com)
+
+ * m68k.h: Merged in patches (mostly m68040-specific) from
+ Colin Smith <colin@wrs.com>.
+
+ * m68k.h: Merged m68kmri.h and m68k.h (using the former as a
+ base). Also cleaned up duplicates, re-ordered instructions for
+ the sake of dis-assembling (so aliases come after standard names).
+ * m68kmri.h: Now just defines some macros, and #includes m68k.h.
+
+Wed Aug 12 16:38:15 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * m68kmri.h: added various opcodes. Moved jbxx to bxxes. Filled in
+ all missing .s
+
+Mon Aug 10 23:22:33 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * sparc.h: Moved tables to BFD library.
+
+ * i386.h (i386_optab): Add fildq, fistpq aliases used by gcc.
+
+Sun Jun 28 13:29:03 1992 Fred Fish (fnf@cygnus.com)
+
+ * h8300.h: Finish filling in all the holes in the opcode table,
+ so that the Lucid C compiler can digest this as well...
+
+Fri Jun 26 21:27:17 1992 John Gilmore (gnu at cygnus.com)
+
+ * i386.h: Add setc, setnc, addr16, data16, repz, repnz aliases.
+ Fix opcodes on various sizes of fild/fist instructions
+ (16bit=no suffix, 32bit="l" suffix, 64bit="ll" suffix).
+ Use tabs to indent for comments. Fixes suggested by Minh Tran-Le.
+
+Thu Jun 25 16:13:26 1992 Stu Grossman (grossman at cygnus.com)
+
+ * h8300.h: Fill in all the holes in the opcode table so that the
+ losing HPUX C compiler can digest this...
+
+Thu Jun 11 12:15:25 1992 John Gilmore (gnu at cygnus.com)
+
+ * mips.h: Fix decoding of coprocessor instructions, somewhat.
+ (Fix by Eric Anderson, 3jean@maas-neotek.arc.nasa.gov.)
+
+Thu May 28 11:17:44 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * sparc.h: Add new architecture variant sparclite; add its scan
+ and divscc opcodes. Define ARCHITECTURES_CONFLICT_P macro.
+
+Tue May 5 14:23:27 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * mips.h: Add some more opcode synonyms (from Frank Yellin,
+ fy@lucid.com).
+
+Thu Apr 16 18:25:26 1992 Per Bothner (bothner@cygnus.com)
+
+ * rs6k.h: New version from IBM (Metin).
+
+Thu Apr 9 00:31:19 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * rs6k.h: Fix incorrect extended opcode for instructions `fm'
+ and `fd'. (From metin@ibmpa.awdpa.ibm.com (Metin G. Ozisik).)
+
+Tue Apr 7 13:38:47 1992 Stu Grossman (grossman at cygnus.com)
+
+ * rs6k.h: Move from ../../gdb/rs6k-opcode.h.
+
+Fri Apr 3 11:30:20 1992 Fred Fish (fnf@cygnus.com)
+
+ * m68k.h (one, two): Cast macro args to unsigned to suppress
+ complaints from compiler and lint about integer overflow during
+ shift.
+
+Sun Mar 29 12:22:08 1992 John Gilmore (gnu at cygnus.com)
+
+ * sparc.h (OP): Avoid signed overflow when shifting to high order bit.
+
+Fri Mar 6 00:22:38 1992 John Gilmore (gnu at cygnus.com)
+
+ * mips.h: Make bitfield layout depend on the HOST compiler,
+ not on the TARGET system.
+
+Fri Feb 21 01:29:51 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * i386.h: added inb, inw, outb, outw opcodes, added att syntax for
+ scmp, slod, smov, ssca, ssto. Curtesy Minh Tran-Le
+ <TRANLE@INTELLICORP.COM>.
+
+Thu Jan 30 07:31:44 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * h8300.h: turned op_type enum into #define list
+
+Thu Jan 30 01:07:24 1992 John Gilmore (gnu at cygnus.com)
+
+ * sparc.h: Remove "cypress" architecture. Remove "fitox" and
+ similar instructions -- they've been renamed to "fitoq", etc.
+ REALLY fix tsubcctv. Fix "fcmpeq" and "fcmpq" which had wrong
+ number of arguments.
+ * h8300.h: Remove extra ; which produces compiler warning.
+
+Tue Jan 28 22:59:22 1992 Stu Grossman (grossman at cygnus.com)
+
+ * sparc.h: fix opcode for tsubcctv.
+
+Tue Jan 7 17:19:39 1992 K. Richard Pixley (rich at cygnus.com)
+
+ * sparc.h: fba and cba are now aliases for fb and cb respectively.
+
+Fri Dec 27 10:55:50 1991 Per Bothner (bothner at cygnus.com)
+
+ * sparc.h (nop): Made the 'lose' field be even tighter,
+ so only a standard 'nop' is disassembled as a nop.
+
+Sun Dec 22 12:18:18 1991 Michael Tiemann (tiemann at cygnus.com)
+
+ * sparc.h (nop): Add RD_GO to `lose' so that only %g0 in dest is
+ disassembled as a nop.
+
+Tue Dec 10 00:22:20 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * sparc.h: fix a typo.
+
+Sat Nov 30 20:40:51 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * a29k.h, arm.h, h8300.h, i386.h, i860.h, i960.h , m68k.h,
+ m88k.h, mips.h , np1.h, ns32k.h, pn.h, pyr.h, sparc.h, tahoe.h,
+ vax.h, ChangeLog: renamed from ../<foo>-opcode.h
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/include/opcode/a29k.h b/include/opcode/a29k.h
new file mode 100644
index 00000000000..002e127d15e
--- /dev/null
+++ b/include/opcode/a29k.h
@@ -0,0 +1,285 @@
+/* Table of opcodes for the AMD 29000 family.
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+struct a29k_opcode {
+ /* Name of the instruction. */
+ char *name;
+
+ /* Opcode word */
+ unsigned long opcode;
+
+ /* A string of characters which describe the operands.
+ Valid characters are:
+ , Itself. The character appears in the assembly code.
+ a RA. The register number is in bits 8-15 of the instruction.
+ b RB. The register number is in bits 0-7 of the instruction.
+ c RC. The register number is in bits 16-23 of the instruction.
+ i An immediate operand is in bits 0-7 of the instruction.
+ x Bits 0-7 and 16-23 of the instruction are bits 0-7 and 8-15
+ (respectively) of the immediate operand.
+ h Same as x but the instruction contains bits 16-31 of the
+ immediate operand.
+ X Same as x but bits 16-31 of the signed immediate operand
+ are set to 1 (thus the operand is always negative).
+ P,A Bits 0-7 and 16-23 of the instruction are bits 2-9 and 10-17
+ (respectively) of the immediate operand.
+ P=PC-relative, sign-extended to 32 bits.
+ A=Absolute, zero-extended to 32 bits.
+ e CE bit (bit 23) for a load/store instruction.
+ n Control field (bits 16-22) for a load/store instruction.
+ v Immediate operand in bits 16-23 of the instruction.
+ (used for trap numbers).
+ s SA. Special-purpose register number in bits 8-15
+ of the instruction.
+ u UI--bit 7 of the instruction.
+ r RND--bits 4-6 of the instruction.
+ d FD--bits 2-3 of the instruction.
+ f FS--bits 0-1 of the instruction.
+ I ID--bits 16-17 of the instruction.
+
+ Extensions for 29050:
+
+ d FMT--bits 2-3 of the instruction (not really new).
+ f ACN--bits 0-1 of the instruction (not really new).
+ F FUNC--Special function in bits 18-21 of the instruction.
+ C ACN--bits 16-17 specifying the accumlator register. */
+ char *args;
+};
+
+#ifndef CONST
+#define CONST
+#endif /* CONST */
+
+static CONST struct a29k_opcode a29k_opcodes[] =
+{
+
+{ "add", 0x14000000, "c,a,b" },
+{ "add", 0x15000000, "c,a,i" },
+{ "addc", 0x1c000000, "c,a,b" },
+{ "addc", 0x1d000000, "c,a,i" },
+{ "addcs", 0x18000000, "c,a,b" },
+{ "addcs", 0x19000000, "c,a,i" },
+{ "addcu", 0x1a000000, "c,a,b" },
+{ "addcu", 0x1b000000, "c,a,i" },
+{ "adds", 0x10000000, "c,a,b" },
+{ "adds", 0x11000000, "c,a,i" },
+{ "addu", 0x12000000, "c,a,b" },
+{ "addu", 0x13000000, "c,a,i" },
+{ "and", 0x90000000, "c,a,b" },
+{ "and", 0x91000000, "c,a,i" },
+{ "andn", 0x9c000000, "c,a,b" },
+{ "andn", 0x9d000000, "c,a,i" },
+{ "aseq", 0x70000000, "v,a,b" },
+{ "aseq", 0x71000000, "v,a,i" },
+{ "asge", 0x5c000000, "v,a,b" },
+{ "asge", 0x5d000000, "v,a,i" },
+{ "asgeu", 0x5e000000, "v,a,b" },
+{ "asgeu", 0x5f000000, "v,a,i" },
+{ "asgt", 0x58000000, "v,a,b" },
+{ "asgt", 0x59000000, "v,a,i" },
+{ "asgtu", 0x5a000000, "v,a,b" },
+{ "asgtu", 0x5b000000, "v,a,i" },
+{ "asle", 0x54000000, "v,a,b" },
+{ "asle", 0x55000000, "v,a,i" },
+{ "asleu", 0x56000000, "v,a,b" },
+{ "asleu", 0x57000000, "v,a,i" },
+{ "aslt", 0x50000000, "v,a,b" },
+{ "aslt", 0x51000000, "v,a,i" },
+{ "asltu", 0x52000000, "v,a,b" },
+{ "asltu", 0x53000000, "v,a,i" },
+{ "asneq", 0x72000000, "v,a,b" },
+{ "asneq", 0x73000000, "v,a,i" },
+{ "call", 0xa8000000, "a,P" },
+{ "call", 0xa9000000, "a,A" },
+{ "calli", 0xc8000000, "a,b" },
+{ "class", 0xe6000000, "c,a,f" },
+{ "clz", 0x08000000, "c,b" },
+{ "clz", 0x09000000, "c,i" },
+{ "const", 0x03000000, "a,x" },
+{ "consth", 0x02000000, "a,h" },
+{ "consthz", 0x05000000, "a,h" },
+{ "constn", 0x01000000, "a,X" },
+{ "convert", 0xe4000000, "c,a,u,r,d,f" },
+{ "cpbyte", 0x2e000000, "c,a,b" },
+{ "cpbyte", 0x2f000000, "c,a,i" },
+{ "cpeq", 0x60000000, "c,a,b" },
+{ "cpeq", 0x61000000, "c,a,i" },
+{ "cpge", 0x4c000000, "c,a,b" },
+{ "cpge", 0x4d000000, "c,a,i" },
+{ "cpgeu", 0x4e000000, "c,a,b" },
+{ "cpgeu", 0x4f000000, "c,a,i" },
+{ "cpgt", 0x48000000, "c,a,b" },
+{ "cpgt", 0x49000000, "c,a,i" },
+{ "cpgtu", 0x4a000000, "c,a,b" },
+{ "cpgtu", 0x4b000000, "c,a,i" },
+{ "cple", 0x44000000, "c,a,b" },
+{ "cple", 0x45000000, "c,a,i" },
+{ "cpleu", 0x46000000, "c,a,b" },
+{ "cpleu", 0x47000000, "c,a,i" },
+{ "cplt", 0x40000000, "c,a,b" },
+{ "cplt", 0x41000000, "c,a,i" },
+{ "cpltu", 0x42000000, "c,a,b" },
+{ "cpltu", 0x43000000, "c,a,i" },
+{ "cpneq", 0x62000000, "c,a,b" },
+{ "cpneq", 0x63000000, "c,a,i" },
+{ "dadd", 0xf1000000, "c,a,b" },
+{ "ddiv", 0xf7000000, "c,a,b" },
+{ "deq", 0xeb000000, "c,a,b" },
+{ "dge", 0xef000000, "c,a,b" },
+{ "dgt", 0xed000000, "c,a,b" },
+{ "div", 0x6a000000, "c,a,b" },
+{ "div", 0x6b000000, "c,a,i" },
+{ "div0", 0x68000000, "c,b" },
+{ "div0", 0x69000000, "c,i" },
+{ "divide", 0xe1000000, "c,a,b" },
+{ "dividu", 0xe3000000, "c,a,b" },
+{ "divl", 0x6c000000, "c,a,b" },
+{ "divl", 0x6d000000, "c,a,i" },
+{ "divrem", 0x6e000000, "c,a,b" },
+{ "divrem", 0x6f000000, "c,a,i" },
+{ "dmac", 0xd9000000, "F,C,a,b" },
+{ "dmsm", 0xdb000000, "c,a,b" },
+{ "dmul", 0xf5000000, "c,a,b" },
+{ "dsub", 0xf3000000, "c,a,b" },
+{ "emulate", 0xd7000000, "v,a,b" },
+{ "exbyte", 0x0a000000, "c,a,b" },
+{ "exbyte", 0x0b000000, "c,a,i" },
+{ "exhw", 0x7c000000, "c,a,b" },
+{ "exhw", 0x7d000000, "c,a,i" },
+{ "exhws", 0x7e000000, "c,a" },
+{ "extract", 0x7a000000, "c,a,b" },
+{ "extract", 0x7b000000, "c,a,i" },
+{ "fadd", 0xf0000000, "c,a,b" },
+{ "fdiv", 0xf6000000, "c,a,b" },
+{ "fdmul", 0xf9000000, "c,a,b" },
+{ "feq", 0xea000000, "c,a,b" },
+{ "fge", 0xee000000, "c,a,b" },
+{ "fgt", 0xec000000, "c,a,b" },
+{ "fmac", 0xd8000000, "F,C,a,b" },
+{ "fmsm", 0xda000000, "c,a,b" },
+{ "fmul", 0xf4000000, "c,a,b" },
+{ "fsub", 0xf2000000, "c,a,b" },
+{ "halt", 0x89000000, "" },
+{ "inbyte", 0x0c000000, "c,a,b" },
+{ "inbyte", 0x0d000000, "c,a,i" },
+{ "inhw", 0x78000000, "c,a,b" },
+{ "inhw", 0x79000000, "c,a,i" },
+{ "inv", 0x9f000000, "I" },
+{ "iret", 0x88000000, "" },
+{ "iretinv", 0x8c000000, "I" },
+{ "jmp", 0xa0000000, "P" },
+{ "jmp", 0xa1000000, "A" },
+{ "jmpf", 0xa4000000, "a,P" },
+{ "jmpf", 0xa5000000, "a,A" },
+{ "jmpfdec", 0xb4000000, "a,P" },
+{ "jmpfdec", 0xb5000000, "a,A" },
+{ "jmpfi", 0xc4000000, "a,b" },
+{ "jmpi", 0xc0000000, "b" },
+{ "jmpt", 0xac000000, "a,P" },
+{ "jmpt", 0xad000000, "a,A" },
+{ "jmpti", 0xcc000000, "a,b" },
+{ "load", 0x16000000, "e,n,a,b" },
+{ "load", 0x17000000, "e,n,a,i" },
+{ "loadl", 0x06000000, "e,n,a,b" },
+{ "loadl", 0x07000000, "e,n,a,i" },
+{ "loadm", 0x36000000, "e,n,a,b" },
+{ "loadm", 0x37000000, "e,n,a,i" },
+{ "loadset", 0x26000000, "e,n,a,b" },
+{ "loadset", 0x27000000, "e,n,a,i" },
+{ "mfacc", 0xe9000100, "c,d,f" },
+{ "mfsr", 0xc6000000, "c,s" },
+{ "mftlb", 0xb6000000, "c,a" },
+{ "mtacc", 0xe8010000, "a,d,f" },
+{ "mtsr", 0xce000000, "s,b" },
+{ "mtsrim", 0x04000000, "s,x" },
+{ "mttlb", 0xbe000000, "a,b" },
+{ "mul", 0x64000000, "c,a,b" },
+{ "mul", 0x65000000, "c,a,i" },
+{ "mull", 0x66000000, "c,a,b" },
+{ "mull", 0x67000000, "c,a,i" },
+{ "multiplu", 0xe2000000, "c,a,b" },
+{ "multiply", 0xe0000000, "c,a,b" },
+{ "multm", 0xde000000, "c,a,b" },
+{ "multmu", 0xdf000000, "c,a,b" },
+{ "mulu", 0x74000000, "c,a,b" },
+{ "mulu", 0x75000000, "c,a,i" },
+{ "nand", 0x9a000000, "c,a,b" },
+{ "nand", 0x9b000000, "c,a,i" },
+{ "nop", 0x70400101, "" },
+{ "nor", 0x98000000, "c,a,b" },
+{ "nor", 0x99000000, "c,a,i" },
+{ "or", 0x92000000, "c,a,b" },
+{ "or", 0x93000000, "c,a,i" },
+{ "orn", 0xaa000000, "c,a,b" },
+{ "orn", 0xab000000, "c,a,i" },
+
+/* The description of "setip" in Chapter 8 ("instruction set") of the user's
+ manual claims that these are absolute register numbers. But section
+ 7.2.1 explains that they are not. The latter is correct, so print
+ these normally ("lr0", "lr5", etc.). */
+{ "setip", 0x9e000000, "c,a,b" },
+
+{ "sll", 0x80000000, "c,a,b" },
+{ "sll", 0x81000000, "c,a,i" },
+{ "sqrt", 0xe5000000, "c,a,f" },
+{ "sra", 0x86000000, "c,a,b" },
+{ "sra", 0x87000000, "c,a,i" },
+{ "srl", 0x82000000, "c,a,b" },
+{ "srl", 0x83000000, "c,a,i" },
+{ "store", 0x1e000000, "e,n,a,b" },
+{ "store", 0x1f000000, "e,n,a,i" },
+{ "storel", 0x0e000000, "e,n,a,b" },
+{ "storel", 0x0f000000, "e,n,a,i" },
+{ "storem", 0x3e000000, "e,n,a,b" },
+{ "storem", 0x3f000000, "e,n,a,i" },
+{ "sub", 0x24000000, "c,a,b" },
+{ "sub", 0x25000000, "c,a,i" },
+{ "subc", 0x2c000000, "c,a,b" },
+{ "subc", 0x2d000000, "c,a,i" },
+{ "subcs", 0x28000000, "c,a,b" },
+{ "subcs", 0x29000000, "c,a,i" },
+{ "subcu", 0x2a000000, "c,a,b" },
+{ "subcu", 0x2b000000, "c,a,i" },
+{ "subr", 0x34000000, "c,a,b" },
+{ "subr", 0x35000000, "c,a,i" },
+{ "subrc", 0x3c000000, "c,a,b" },
+{ "subrc", 0x3d000000, "c,a,i" },
+{ "subrcs", 0x38000000, "c,a,b" },
+{ "subrcs", 0x39000000, "c,a,i" },
+{ "subrcu", 0x3a000000, "c,a,b" },
+{ "subrcu", 0x3b000000, "c,a,i" },
+{ "subrs", 0x30000000, "c,a,b" },
+{ "subrs", 0x31000000, "c,a,i" },
+{ "subru", 0x32000000, "c,a,b" },
+{ "subru", 0x33000000, "c,a,i" },
+{ "subs", 0x20000000, "c,a,b" },
+{ "subs", 0x21000000, "c,a,i" },
+{ "subu", 0x22000000, "c,a,b" },
+{ "subu", 0x23000000, "c,a,i" },
+{ "xnor", 0x96000000, "c,a,b" },
+{ "xnor", 0x97000000, "c,a,i" },
+{ "xor", 0x94000000, "c,a,b" },
+{ "xor", 0x95000000, "c,a,i" },
+
+{ "", 0x0, "" } /* Dummy entry, not included in NUM_OPCODES. This
+ lets code examine entry i+1 without checking
+ if we've run off the end of the table. */
+};
+
+CONST unsigned int num_opcodes = (((sizeof a29k_opcodes) / (sizeof a29k_opcodes[0])) - 1);
diff --git a/include/opcode/alpha.h b/include/opcode/alpha.h
new file mode 100644
index 00000000000..d18eb04451e
--- /dev/null
+++ b/include/opcode/alpha.h
@@ -0,0 +1,238 @@
+/* alpha.h -- Header file for Alpha opcode table
+ Copyright 1996, 1999 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@tamu.edu>,
+ patterned after the PPC opcode table written by Ian Lance Taylor.
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef OPCODE_ALPHA_H
+#define OPCODE_ALPHA_H
+
+/* The opcode table is an array of struct alpha_opcode. */
+
+struct alpha_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* The opcode itself. Those bits which will be filled in with
+ operands are zeroes. */
+ unsigned opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a
+ mask containing ones indicating those bits which must match the
+ opcode field, and zeroes indicating those bits which need not
+ match (and are presumably filled in by operands). */
+ unsigned mask;
+
+ /* One bit flags for the opcode. These are primarily used to
+ indicate specific processors and environments support the
+ instructions. The defined values are listed below. */
+ unsigned flags;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ unsigned char operands[4];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+ in the order in which the disassembler should consider
+ instructions. */
+extern const struct alpha_opcode alpha_opcodes[];
+extern const int alpha_num_opcodes;
+
+/* Values defined for the flags field of a struct alpha_opcode. */
+
+/* CPU Availability */
+#define AXP_OPCODE_BASE 0x0001 /* Base architecture -- all cpus. */
+#define AXP_OPCODE_EV4 0x0002 /* EV4 specific PALcode insns. */
+#define AXP_OPCODE_EV5 0x0004 /* EV5 specific PALcode insns. */
+#define AXP_OPCODE_EV6 0x0008 /* EV6 specific PALcode insns. */
+#define AXP_OPCODE_BWX 0x0100 /* Byte/word extension (amask bit 0). */
+#define AXP_OPCODE_CIX 0x0200 /* "Count" extension (amask bit 1). */
+#define AXP_OPCODE_MAX 0x0400 /* Multimedia extension (amask bit 8). */
+
+#define AXP_OPCODE_NOPAL (~(AXP_OPCODE_EV4|AXP_OPCODE_EV5|AXP_OPCODE_EV6))
+
+/* A macro to extract the major opcode from an instruction. */
+#define AXP_OP(i) (((i) >> 26) & 0x3F)
+
+/* The total number of major opcodes. */
+#define AXP_NOPS 0x40
+
+
+/* The operands table is an array of struct alpha_operand. */
+
+struct alpha_operand
+{
+ /* The number of bits in the operand. */
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+ int shift;
+
+ /* The default relocation type for this operand. */
+ int default_reloc;
+
+ /* One bit syntax flags. */
+ unsigned flags;
+
+ /* Insertion function. This is used by the assembler. To insert an
+ operand value into an instruction, check this field.
+
+ If it is NULL, execute
+ i |= (op & ((1 << o->bits) - 1)) << o->shift;
+ (i is the instruction which we are filling in, o is a pointer to
+ this structure, and op is the opcode value; this assumes twos
+ complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction and the operand value. It will return the new value
+ of the instruction. If the ERRMSG argument is not NULL, then if
+ the operand value is illegal, *ERRMSG will be set to a warning
+ string (the operand will be inserted in any case). If the
+ operand value is legal, *ERRMSG will be unchanged (most operands
+ can accept any value). */
+ unsigned (*insert) PARAMS ((unsigned instruction, int op,
+ const char **errmsg));
+
+ /* Extraction function. This is used by the disassembler. To
+ extract this operand type from an instruction, check this field.
+
+ If it is NULL, compute
+ op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+ if ((o->flags & AXP_OPERAND_SIGNED) != 0
+ && (op & (1 << (o->bits - 1))) != 0)
+ op -= 1 << o->bits;
+ (i is the instruction, o is a pointer to this structure, and op
+ is the result; this assumes twos complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction value. It will return the value of the operand. If
+ the INVALID argument is not NULL, *INVALID will be set to
+ non-zero if this operand type can not actually be extracted from
+ this operand (i.e., the instruction does not match). If the
+ operand is valid, *INVALID will not be changed. */
+ int (*extract) PARAMS ((unsigned instruction, int *invalid));
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the alpha_opcodes table. */
+
+extern const struct alpha_operand alpha_operands[];
+extern const int alpha_num_operands;
+
+/* Values defined for the flags field of a struct alpha_operand. */
+
+/* Mask for selecting the type for typecheck purposes */
+#define AXP_OPERAND_TYPECHECK_MASK \
+ (AXP_OPERAND_PARENS | AXP_OPERAND_COMMA | AXP_OPERAND_IR | \
+ AXP_OPERAND_FPR | AXP_OPERAND_RELATIVE | AXP_OPERAND_SIGNED | \
+ AXP_OPERAND_UNSIGNED)
+
+/* This operand does not actually exist in the assembler input. This
+ is used to support extended mnemonics, for which two operands fields
+ are identical. The assembler should call the insert function with
+ any op value. The disassembler should call the extract function,
+ ignore the return value, and check the value placed in the invalid
+ argument. */
+#define AXP_OPERAND_FAKE 01
+
+/* The operand should be wrapped in parentheses rather than separated
+ from the previous by a comma. This is used for the load and store
+ instructions which want their operands to look like "Ra,disp(Rb)". */
+#define AXP_OPERAND_PARENS 02
+
+/* Used in combination with PARENS, this supresses the supression of
+ the comma. This is used for "jmp Ra,(Rb),hint". */
+#define AXP_OPERAND_COMMA 04
+
+/* This operand names an integer register. */
+#define AXP_OPERAND_IR 010
+
+/* This operand names a floating point register. */
+#define AXP_OPERAND_FPR 020
+
+/* This operand is a relative branch displacement. The disassembler
+ prints these symbolically if possible. */
+#define AXP_OPERAND_RELATIVE 040
+
+/* This operand takes signed values. */
+#define AXP_OPERAND_SIGNED 0100
+
+/* This operand takes unsigned values. This exists primarily so that
+ a flags value of 0 can be treated as end-of-arguments. */
+#define AXP_OPERAND_UNSIGNED 0200
+
+/* Supress overflow detection on this field. This is used for hints. */
+#define AXP_OPERAND_NOOVERFLOW 0400
+
+/* Mask for optional argument default value. */
+#define AXP_OPERAND_OPTIONAL_MASK 07000
+
+/* This operand defaults to zero. This is used for jump hints. */
+#define AXP_OPERAND_DEFAULT_ZERO 01000
+
+/* This operand should default to the first (real) operand and is used
+ in conjunction with AXP_OPERAND_OPTIONAL. This allows
+ "and $0,3,$0" to be written as "and $0,3", etc. I don't like
+ it, but it's what DEC does. */
+#define AXP_OPERAND_DEFAULT_FIRST 02000
+
+/* Similarly, this operand should default to the second (real) operand.
+ This allows "negl $0" instead of "negl $0,$0". */
+#define AXP_OPERAND_DEFAULT_SECOND 04000
+
+
+/* Register common names */
+
+#define AXP_REG_V0 0
+#define AXP_REG_T0 1
+#define AXP_REG_T1 2
+#define AXP_REG_T2 3
+#define AXP_REG_T3 4
+#define AXP_REG_T4 5
+#define AXP_REG_T5 6
+#define AXP_REG_T6 7
+#define AXP_REG_T7 8
+#define AXP_REG_S0 9
+#define AXP_REG_S1 10
+#define AXP_REG_S2 11
+#define AXP_REG_S3 12
+#define AXP_REG_S4 13
+#define AXP_REG_S5 14
+#define AXP_REG_FP 15
+#define AXP_REG_A0 16
+#define AXP_REG_A1 17
+#define AXP_REG_A2 18
+#define AXP_REG_A3 19
+#define AXP_REG_A4 20
+#define AXP_REG_A5 21
+#define AXP_REG_T8 22
+#define AXP_REG_T9 23
+#define AXP_REG_T10 24
+#define AXP_REG_T11 25
+#define AXP_REG_RA 26
+#define AXP_REG_PV 27
+#define AXP_REG_T12 27
+#define AXP_REG_AT 28
+#define AXP_REG_GP 29
+#define AXP_REG_SP 30
+#define AXP_REG_ZERO 31
+
+#endif /* OPCODE_ALPHA_H */
diff --git a/include/opcode/arc.h b/include/opcode/arc.h
new file mode 100644
index 00000000000..a1e0ca15263
--- /dev/null
+++ b/include/opcode/arc.h
@@ -0,0 +1,274 @@
+/* Opcode table for the ARC.
+ Copyright 1994, 1995, 1997 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and
+the GNU Binutils.
+
+GAS/GDB 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, or (at your option)
+any later version.
+
+GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* List of the various cpu types.
+ The tables currently use bit masks to say whether the instruction or
+ whatever is supported by a particular cpu. This lets us have one entry
+ apply to several cpus.
+
+ This duplicates bfd_mach_arc_xxx. For now I wish to isolate this from bfd
+ and bfd from this. Also note that these numbers are bit values as we want
+ to allow for things available on more than one ARC (but not necessarily all
+ ARCs). */
+
+/* The `base' cpu must be 0 (table entries are omitted for the base cpu).
+ The cpu type is treated independently of endianness.
+ The complete `mach' number includes endianness.
+ These values are internal to opcodes/bfd/binutils/gas. */
+#define ARC_MACH_BASE 0
+#define ARC_MACH_UNUSED1 1
+#define ARC_MACH_UNUSED2 2
+#define ARC_MACH_UNUSED4 4
+/* Additional cpu values can be inserted here and ARC_MACH_BIG moved down. */
+#define ARC_MACH_BIG 8
+
+/* Mask of number of bits necessary to record cpu type. */
+#define ARC_MACH_CPU_MASK 7
+/* Mask of number of bits necessary to record cpu type + endianness. */
+#define ARC_MACH_MASK 15
+
+/* Type to denote an ARC instruction (at least a 32 bit unsigned int). */
+typedef unsigned int arc_insn;
+
+struct arc_opcode {
+ char *syntax; /* syntax of insn */
+ unsigned long mask, value; /* recognize insn if (op&mask)==value */
+ int flags; /* various flag bits */
+
+/* Values for `flags'. */
+
+/* Return CPU number, given flag bits. */
+#define ARC_OPCODE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK)
+/* Return MACH number, given flag bits. */
+#define ARC_OPCODE_MACH(bits) ((bits) & ARC_MACH_MASK)
+/* First opcode flag bit available after machine mask. */
+#define ARC_OPCODE_FLAG_START ((ARC_MACH_MASK + 1) << 0)
+/* This insn is a conditional branch. */
+#define ARC_OPCODE_COND_BRANCH (ARC_OPCODE_FLAG_START)
+
+ /* These values are used to optimize assembly and disassembly. Each insn is
+ on a list of related insns (same first letter for assembly, same insn code
+ for disassembly). */
+ struct arc_opcode *next_asm; /* Next instruction to try during assembly. */
+ struct arc_opcode *next_dis; /* Next instruction to try during disassembly. */
+
+ /* Macros to create the hash values for the lists. */
+#define ARC_HASH_OPCODE(string) \
+ ((string)[0] >= 'a' && (string)[0] <= 'z' ? (string)[0] - 'a' : 26)
+#define ARC_HASH_ICODE(insn) \
+ ((unsigned int) (insn) >> 27)
+
+ /* Macros to access `next_asm', `next_dis' so users needn't care about the
+ underlying mechanism. */
+#define ARC_OPCODE_NEXT_ASM(op) ((op)->next_asm)
+#define ARC_OPCODE_NEXT_DIS(op) ((op)->next_dis)
+};
+
+struct arc_operand_value {
+ char *name; /* eg: "eq" */
+ short value; /* eg: 1 */
+ unsigned char type; /* index into `arc_operands' */
+ unsigned char flags; /* various flag bits */
+
+/* Values for `flags'. */
+
+/* Return CPU number, given flag bits. */
+#define ARC_OPVAL_CPU(bits) ((bits) & ARC_MACH_CPU_MASK)
+/* Return MACH number, given flag bits. */
+#define ARC_OPVAL_MACH(bits) ((bits) & ARC_MACH_MASK)
+};
+
+struct arc_operand {
+ /* One of the insn format chars. */
+ unsigned char fmt;
+
+ /* The number of bits in the operand (may be unused for a modifier). */
+ unsigned char bits;
+
+ /* How far the operand is left shifted in the instruction, or
+ the modifier's flag bit (may be unused for a modifier. */
+ unsigned char shift;
+
+ /* Various flag bits. */
+ int flags;
+
+/* Values for `flags'. */
+
+/* This operand is a suffix to the opcode. */
+#define ARC_OPERAND_SUFFIX 1
+
+/* This operand is a relative branch displacement. The disassembler
+ prints these symbolically if possible. */
+#define ARC_OPERAND_RELATIVE_BRANCH 2
+
+/* This operand is an absolute branch address. The disassembler
+ prints these symbolically if possible. */
+#define ARC_OPERAND_ABSOLUTE_BRANCH 4
+
+/* This operand is an address. The disassembler
+ prints these symbolically if possible. */
+#define ARC_OPERAND_ADDRESS 8
+
+/* This operand is a long immediate value. */
+#define ARC_OPERAND_LIMM 0x10
+
+/* This operand takes signed values. */
+#define ARC_OPERAND_SIGNED 0x20
+
+/* This operand takes signed values, but also accepts a full positive
+ range of values. That is, if bits is 16, it takes any value from
+ -0x8000 to 0xffff. */
+#define ARC_OPERAND_SIGNOPT 0x40
+
+/* This operand should be regarded as a negative number for the
+ purposes of overflow checking (i.e., the normal most negative
+ number is disallowed and one more than the normal most positive
+ number is allowed). This flag will only be set for a signed
+ operand. */
+#define ARC_OPERAND_NEGATIVE 0x80
+
+/* This operand doesn't really exist. The program uses these operands
+ in special ways. */
+#define ARC_OPERAND_FAKE 0x100
+
+/* Modifier values. */
+/* A dot is required before a suffix. Eg: .le */
+#define ARC_MOD_DOT 0x1000
+
+/* A normal register is allowed (not used, but here for completeness). */
+#define ARC_MOD_REG 0x2000
+
+/* An auxiliary register name is expected. */
+#define ARC_MOD_AUXREG 0x4000
+
+/* Sum of all ARC_MOD_XXX bits. */
+#define ARC_MOD_BITS 0x7000
+
+/* Non-zero if the operand type is really a modifier. */
+#define ARC_MOD_P(X) ((X) & ARC_MOD_BITS)
+
+ /* Insertion function. This is used by the assembler. To insert an
+ operand value into an instruction, check this field.
+
+ If it is NULL, execute
+ i |= (p & ((1 << o->bits) - 1)) << o->shift;
+ (I is the instruction which we are filling in, O is a pointer to
+ this structure, and OP is the opcode value; this assumes twos
+ complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction and the operand value. It will return the new value
+ of the instruction. If the ERRMSG argument is not NULL, then if
+ the operand value is illegal, *ERRMSG will be set to a warning
+ string (the operand will be inserted in any case). If the
+ operand value is legal, *ERRMSG will be unchanged.
+
+ REG is non-NULL when inserting a register value. */
+
+ arc_insn (*insert) PARAMS ((arc_insn insn,
+ const struct arc_operand *operand, int mods,
+ const struct arc_operand_value *reg, long value,
+ const char **errmsg));
+
+ /* Extraction function. This is used by the disassembler. To
+ extract this operand type from an instruction, check this field.
+
+ If it is NULL, compute
+ op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+ if ((o->flags & ARC_OPERAND_SIGNED) != 0
+ && (op & (1 << (o->bits - 1))) != 0)
+ op -= 1 << o->bits;
+ (I is the instruction, O is a pointer to this structure, and OP
+ is the result; this assumes twos complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction value. It will return the value of the operand. If
+ the INVALID argument is not NULL, *INVALID will be set to
+ non-zero if this operand type can not actually be extracted from
+ this operand (i.e., the instruction does not match). If the
+ operand is valid, *INVALID will not be changed.
+
+ INSN is a pointer to an array of two `arc_insn's. The first element is
+ the insn, the second is the limm if present.
+
+ Operands that have a printable form like registers and suffixes have
+ their struct arc_operand_value pointer stored in OPVAL. */
+
+ long (*extract) PARAMS ((arc_insn *insn,
+ const struct arc_operand *operand,
+ int mods, const struct arc_operand_value **opval,
+ int *invalid));
+};
+
+/* Bits that say what version of cpu we have.
+ These should be passed to arc_init_opcode_tables.
+ At present, all there is is the cpu type. */
+
+/* CPU number, given value passed to `arc_init_opcode_tables'. */
+#define ARC_HAVE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK)
+/* MACH number, given value passed to `arc_init_opcode_tables'. */
+#define ARC_HAVE_MACH(bits) ((bits) & ARC_MACH_MASK)
+
+/* Special register values: */
+#define ARC_REG_SHIMM_UPDATE 61
+#define ARC_REG_SHIMM 63
+#define ARC_REG_LIMM 62
+
+/* Non-zero if REG is a constant marker. */
+#define ARC_REG_CONSTANT_P(REG) ((REG) >= 61)
+
+/* Positions and masks of various fields: */
+#define ARC_SHIFT_REGA 21
+#define ARC_SHIFT_REGB 15
+#define ARC_SHIFT_REGC 9
+#define ARC_MASK_REG 63
+
+/* Delay slot types. */
+#define ARC_DELAY_NONE 0 /* no delay slot */
+#define ARC_DELAY_NORMAL 1 /* delay slot in both cases */
+#define ARC_DELAY_JUMP 2 /* delay slot only if branch taken */
+
+/* Non-zero if X will fit in a signed 9 bit field. */
+#define ARC_SHIMM_CONST_P(x) ((long) (x) >= -256 && (long) (x) <= 255)
+
+extern const struct arc_operand arc_operands[];
+extern const int arc_operand_count;
+extern /*const*/ struct arc_opcode arc_opcodes[];
+extern const int arc_opcodes_count;
+extern const struct arc_operand_value arc_suffixes[];
+extern const int arc_suffixes_count;
+extern const struct arc_operand_value arc_reg_names[];
+extern const int arc_reg_names_count;
+extern unsigned char arc_operand_map[];
+
+/* Utility fns in arc-opc.c. */
+int arc_get_opcode_mach PARAMS ((int, int));
+/* `arc_opcode_init_tables' must be called before `arc_xxx_supported'. */
+void arc_opcode_init_tables PARAMS ((int));
+void arc_opcode_init_insert PARAMS ((void));
+void arc_opcode_init_extract PARAMS ((void));
+const struct arc_opcode *arc_opcode_lookup_asm PARAMS ((const char *));
+const struct arc_opcode *arc_opcode_lookup_dis PARAMS ((unsigned int));
+int arc_opcode_limm_p PARAMS ((long *));
+const struct arc_operand_value *arc_opcode_lookup_suffix PARAMS ((const struct arc_operand *type, int value));
+int arc_opcode_supported PARAMS ((const struct arc_opcode *));
+int arc_opval_supported PARAMS ((const struct arc_operand_value *));
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
new file mode 100644
index 00000000000..c7087eb9ed4
--- /dev/null
+++ b/include/opcode/arm.h
@@ -0,0 +1,294 @@
+/* ARM opcode list.
+ Copyright (C) 1989, Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+GDB and GAS are 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 1, or (at your option)
+any later version.
+
+GDB and GAS are 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 GDB or GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* types of instruction (encoded in bits 26 and 27 of the instruction) */
+
+#define TYPE_ARITHMETIC 0
+#define TYPE_LDR_STR 1
+#define TYPE_BLOCK_BRANCH 2
+#define TYPE_SWI 3
+
+/* bit 25 decides whether an instruction is a block move or a branch */
+#define SUBTYPE_BLOCK 0
+#define SUBTYPE_BRANCH 1
+
+/* codes to distinguish the arithmetic instructions */
+
+#define OPCODE_AND 0
+#define OPCODE_EOR 1
+#define OPCODE_SUB 2
+#define OPCODE_RSB 3
+#define OPCODE_ADD 4
+#define OPCODE_ADC 5
+#define OPCODE_SBC 6
+#define OPCODE_RSC 7
+#define OPCODE_TST 8
+#define OPCODE_TEQ 9
+#define OPCODE_CMP 10
+#define OPCODE_CMN 11
+#define OPCODE_ORR 12
+#define OPCODE_MOV 13
+#define OPCODE_BIC 14
+#define OPCODE_MVN 15
+
+/* condition codes */
+
+#define COND_EQ 0
+#define COND_NE 1
+#define COND_CS 2
+#define COND_CC 3
+#define COND_MI 4
+#define COND_PL 5
+#define COND_VS 6
+#define COND_VC 7
+#define COND_HI 8
+#define COND_LS 9
+#define COND_GE 10
+#define COND_LT 11
+#define COND_GT 12
+#define COND_LE 13
+#define COND_AL 14
+#define COND_NV 15
+
+/* Describes the format of an ARM machine instruction */
+
+struct generic_fmt {
+ unsigned rest :25; /* the rest of the instruction */
+ unsigned subtype :1; /* used to decide between block and branch */
+ unsigned type :2; /* one of TYPE_* */
+ unsigned cond :4; /* one of COND_* defined above */
+};
+
+struct arith_fmt {
+ unsigned operand2 :12; /* #nn or rn or rn shift #m or rn shift rm */
+ unsigned dest :4; /* place where the answer goes */
+ unsigned operand1 :4; /* first operand to instruction */
+ unsigned set :1; /* == 1 means set processor flags */
+ unsigned opcode :4; /* one of OPCODE_* defined above */
+ unsigned immed :1; /* operand2 is an immediate value */
+ unsigned type :2; /* == TYPE_ARITHMETIC */
+ unsigned cond :4; /* one of COND_* defined above */
+};
+
+struct ldr_str_fmt {
+ unsigned offset :12; /* #nn or rn or rn shift #m */
+ unsigned reg :4; /* destination for LDR, source for STR */
+ unsigned base :4; /* base register */
+ unsigned is_load :1; /* == 1 for LDR */
+ unsigned writeback :1; /* == 1 means write back (base+offset) into base */
+ unsigned byte :1; /* == 1 means byte access else word */
+ unsigned up :1; /* == 1 means add offset else subtract it */
+ unsigned pre_index :1; /* == 1 means [a,b] form else [a],b form */
+ unsigned immed :1; /* == 0 means immediate offset */
+ unsigned type :2; /* == TYPE_LDR_STR */
+ unsigned cond :4; /* one of COND_* defined above */
+};
+
+struct block_fmt {
+ unsigned mask :16; /* register mask */
+ unsigned base :4; /* register used as base of move */
+ unsigned is_load :1; /* == 1 for LDM */
+ unsigned writeback :1; /* == 1 means update base after move */
+ unsigned set :1; /* == 1 means set flags in pc if included in mask */
+ unsigned increment :1; /* == 1 means increment base register */
+ unsigned before :1; /* == 1 means inc/dec before each move */
+ unsigned is_block :1; /* == SUBTYPE_BLOCK */
+ unsigned type :2; /* == TYPE_BLOCK_BRANCH */
+ unsigned cond :4; /* one of COND_* defined above */
+};
+
+struct branch_fmt {
+ unsigned dest :24; /* destination of the branch */
+ unsigned link :1; /* branch with link (function call) */
+ unsigned is_branch :1; /* == SUBTYPE_BRANCH */
+ unsigned type :2; /* == TYPE_BLOCK_BRANCH */
+ unsigned cond :4; /* one of COND_* defined above */
+};
+
+#define ROUND_N 0
+#define ROUND_P 1
+#define ROUND_M 2
+#define ROUND_Z 3
+
+#define FLOAT2_MVF 0
+#define FLOAT2_MNF 1
+#define FLOAT2_ABS 2
+#define FLOAT2_RND 3
+#define FLOAT2_SQT 4
+#define FLOAT2_LOG 5
+#define FLOAT2_LGN 6
+#define FLOAT2_EXP 7
+#define FLOAT2_SIN 8
+#define FLOAT2_COS 9
+#define FLOAT2_TAN 10
+#define FLOAT2_ASN 11
+#define FLOAT2_ACS 12
+#define FLOAT2_ATN 13
+
+#define FLOAT3_ADF 0
+#define FLOAT3_MUF 1
+#define FLOAT3_SUF 2
+#define FLOAT3_RSF 3
+#define FLOAT3_DVF 4
+#define FLOAT3_RDF 5
+#define FLOAT3_POW 6
+#define FLOAT3_RPW 7
+#define FLOAT3_RMF 8
+#define FLOAT3_FML 9
+#define FLOAT3_FDV 10
+#define FLOAT3_FRD 11
+#define FLOAT3_POL 12
+
+struct float2_fmt {
+ unsigned operand2 :3; /* second operand */
+ unsigned immed :1; /* == 1 if second operand is a constant */
+ unsigned pad1 :1; /* == 0 */
+ unsigned rounding :2; /* ROUND_* */
+ unsigned is_double :1; /* == 1 if precision is double (only if not extended) */
+ unsigned pad2 :4; /* == 1 */
+ unsigned dest :3; /* destination */
+ unsigned is_2_op :1; /* == 1 if 2 operand ins */
+ unsigned operand1 :3; /* first operand (only of is_2_op == 0) */
+ unsigned is_extended :1; /* == 1 if precision is extended */
+ unsigned opcode :4; /* FLOAT2_* or FLOAT3_* depending on is_2_op */
+ unsigned must_be_2 :2; /* == 2 */
+ unsigned type :2; /* == TYPE_SWI */
+ unsigned cond :4; /* COND_* */
+};
+
+struct swi_fmt {
+ unsigned argument :24; /* argument to SWI (syscall number) */
+ unsigned must_be_3 :2; /* == 3 */
+ unsigned type :2; /* == TYPE_SWI */
+ unsigned cond :4; /* one of COND_* defined above */
+};
+
+union insn_fmt {
+ struct generic_fmt generic;
+ struct arith_fmt arith;
+ struct ldr_str_fmt ldr_str;
+ struct block_fmt block;
+ struct branch_fmt branch;
+ struct swi_fmt swi;
+ unsigned long ins;
+};
+
+struct opcode {
+ unsigned long value, mask; /* recognise instruction if (op&mask)==value */
+ char *assembler; /* how to disassemble this instruction */
+};
+
+/* format of the assembler string :
+
+ %% %
+ %<bitfield>d print the bitfield in decimal
+ %<bitfield>x print the bitfield in hex
+ %<bitfield>r print as an ARM register
+ %<bitfield>f print a floating point constant if >7 else an fp register
+ %c print condition code (always bits 28-31)
+ %P print floating point precision in arithmetic insn
+ %Q print floating point precision in ldf/stf insn
+ %R print floating point rounding mode
+ %<bitnum>'c print specified char iff bit is one
+ %<bitnum>`c print specified char iff bit is zero
+ %<bitnum>?ab print a if bit is one else print b
+ %p print 'p' iff bits 12-15 are 15
+ %o print operand2 (immediate or register + shift)
+ %a print address for ldr/str instruction
+ %b print branch destination
+ %A print address for ldc/stc/ldf/stf instruction
+ %m print register mask for ldm/stm instruction
+*/
+
+static struct opcode opcodes[] = {
+ /* ARM instructions */
+ 0x00000090, 0x0fe000f0, "mul%20's %12-15r, %16-19r, %0-3r",
+ 0x00200090, 0x0fe000f0, "mla%20's %12-15r, %16-19r, %0-3r, %8-11r",
+ 0x00000000, 0x0de00000, "and%c%20's %12-15r, %16-19r, %o",
+ 0x00200000, 0x0de00000, "eor%c%20's %12-15r, %16-19r, %o",
+ 0x00400000, 0x0de00000, "sub%c%20's %12-15r, %16-19r, %o",
+ 0x00600000, 0x0de00000, "rsb%c%20's %12-15r, %16-19r, %o",
+ 0x00800000, 0x0de00000, "add%c%20's %12-15r, %16-19r, %o",
+ 0x00a00000, 0x0de00000, "adc%c%20's %12-15r, %16-19r, %o",
+ 0x00c00000, 0x0de00000, "sbc%c%20's %12-15r, %16-19r, %o",
+ 0x00e00000, 0x0de00000, "rsc%c%20's %12-15r, %16-19r, %o",
+ 0x01000000, 0x0de00000, "tst%c%p %16-19r, %o",
+ 0x01200000, 0x0de00000, "teq%c%p %16-19r, %o",
+ 0x01400000, 0x0de00000, "cmp%c%p %16-19r, %o",
+ 0x01600000, 0x0de00000, "cmn%c%p %16-19r, %o",
+ 0x01800000, 0x0de00000, "orr%c%20's %12-15r, %16-19r, %o",
+ 0x01a00000, 0x0de00000, "mov%c%20's %12-15r, %o",
+ 0x01c00000, 0x0de00000, "bic%c%20's %12-15r, %16-19r, %o",
+ 0x01e00000, 0x0de00000, "mvn%c%20's %12-15r, %o",
+ 0x04000000, 0x0c100000, "str%c%22'b %12-15r, %a",
+ 0x04100000, 0x0c100000, "ldr%c%22'b %12-15r, %a",
+ 0x08000000, 0x0e100000, "stm%c%23?id%24?ba %16-19r%22`!, %m",
+ 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba %16-19r%22`!, %m%22'^",
+ 0x0a000000, 0x0e000000, "b%c%24'l %b",
+ 0x0f000000, 0x0f000000, "swi%c %0-23x",
+ /* Floating point coprocessor instructions */
+ 0x0e000100, 0x0ff08f10, "adf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e100100, 0x0ff08f10, "muf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e200100, 0x0ff08f10, "suf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e300100, 0x0ff08f10, "rsf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e400100, 0x0ff08f10, "dvf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e500100, 0x0ff08f10, "rdf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e600100, 0x0ff08f10, "pow%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e700100, 0x0ff08f10, "rpw%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e800100, 0x0ff08f10, "rmf%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e900100, 0x0ff08f10, "fml%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0ea00100, 0x0ff08f10, "fdv%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0eb00100, 0x0ff08f10, "frd%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0ec00100, 0x0ff08f10, "pol%c%P%R %12-14f, %16-18f, %0-3f",
+ 0x0e008100, 0x0ff08f10, "mvf%c%P%R %12-14f, %0-3f",
+ 0x0e108100, 0x0ff08f10, "mnf%c%P%R %12-14f, %0-3f",
+ 0x0e208100, 0x0ff08f10, "abs%c%P%R %12-14f, %0-3f",
+ 0x0e308100, 0x0ff08f10, "rnd%c%P%R %12-14f, %0-3f",
+ 0x0e408100, 0x0ff08f10, "sqt%c%P%R %12-14f, %0-3f",
+ 0x0e508100, 0x0ff08f10, "log%c%P%R %12-14f, %0-3f",
+ 0x0e608100, 0x0ff08f10, "lgn%c%P%R %12-14f, %0-3f",
+ 0x0e708100, 0x0ff08f10, "exp%c%P%R %12-14f, %0-3f",
+ 0x0e808100, 0x0ff08f10, "sin%c%P%R %12-14f, %0-3f",
+ 0x0e908100, 0x0ff08f10, "cos%c%P%R %12-14f, %0-3f",
+ 0x0ea08100, 0x0ff08f10, "tan%c%P%R %12-14f, %0-3f",
+ 0x0eb08100, 0x0ff08f10, "asn%c%P%R %12-14f, %0-3f",
+ 0x0ec08100, 0x0ff08f10, "acs%c%P%R %12-14f, %0-3f",
+ 0x0ed08100, 0x0ff08f10, "atn%c%P%R %12-14f, %0-3f",
+ 0x0e000110, 0x0ff00f1f, "flt%c%P%R %16-18f, %12-15r",
+ 0x0e100110, 0x0fff0f98, "fix%c%R %12-15r, %0-2f",
+ 0x0e200110, 0x0fff0fff, "wfs%c %12-15r",
+ 0x0e300110, 0x0fff0fff, "rfs%c %12-15r",
+ 0x0e400110, 0x0fff0fff, "wfc%c %12-15r",
+ 0x0e500110, 0x0fff0fff, "rfc%c %12-15r",
+ 0x0e90f110, 0x0ff8fff0, "cmf%c %16-18f, %0-3f",
+ 0x0eb0f110, 0x0ff8fff0, "cnf%c %16-18f, %0-3f",
+ 0x0ed0f110, 0x0ff8fff0, "cmfe%c %16-18f, %0-3f",
+ 0x0ef0f110, 0x0ff8fff0, "cnfe%c %16-18f, %0-3f",
+ 0x0c000100, 0x0e100f00, "stf%c%Q %12-14f, %A",
+ 0x0c100100, 0x0e100f00, "ldf%c%Q %12-14f, %A",
+ /* Generic coprocessor instructions */
+ 0x0e000000, 0x0f000010, "cdp%c %8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}",
+ 0x0e000010, 0x0f100010, "mrc%c %8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}",
+ 0x0e100010, 0x0f100010, "mcr%c %8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}",
+ 0x0c000000, 0x0e100000, "stc%c%22`l %8-11d, cr%12-15d, %A",
+ 0x0c100000, 0x0e100000, "ldc%c%22`l %8-11d, cr%12-15d, %A",
+ /* the rest */
+ 0x00000000, 0x00000000, "undefined instruction %0-31x",
+};
+#define N_OPCODES (sizeof opcodes / sizeof opcodes[0])
diff --git a/include/opcode/cgen.h b/include/opcode/cgen.h
new file mode 100644
index 00000000000..84542a37ce1
--- /dev/null
+++ b/include/opcode/cgen.h
@@ -0,0 +1,1380 @@
+/* Header file for targets using CGEN: Cpu tools GENerator.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB, the GNU debugger, and the 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef CGEN_H
+#define CGEN_H
+
+/* ??? This file requires bfd.h but only to get bfd_vma.
+ Seems like an awful lot to require just to get such a fundamental type.
+ Perhaps the definition of bfd_vma can be moved outside of bfd.h.
+ Or perhaps one could duplicate its definition in another file.
+ Until such time, this file conditionally compiles definitions that require
+ bfd_vma using BFD_VERSION. */
+
+/* Enums must be defined before they can be used.
+ Allow them to be used in struct definitions, even though the enum must
+ be defined elsewhere.
+ If CGEN_ARCH isn't defined, this file is being included by something other
+ than <arch>-desc.h. */
+
+/* Prepend the arch name, defined in <arch>-desc.h, and _cgen_ to symbol S.
+ The lack of spaces in the arg list is important for non-stdc systems.
+ This file is included by <arch>-desc.h.
+ It can be included independently of <arch>-desc.h, in which case the arch
+ dependent portions will be declared as "unknown_cgen_foo". */
+
+#ifndef CGEN_SYM
+#define CGEN_SYM(s) CONCAT3 (unknown,_cgen_,s)
+#endif
+
+/* This file contains the static (unchanging) pieces and as much other stuff
+ as we can reasonably put here. It's generally cleaner to put stuff here
+ rather than having it machine generated if possible. */
+
+/* The assembler syntax is made up of expressions (duh...).
+ At the lowest level the values are mnemonics, register names, numbers, etc.
+ Above that are subexpressions, if any (an example might be the
+ "effective address" in m68k cpus). Subexpressions are wip.
+ At the second highest level are the insns themselves. Above that are
+ pseudo-insns, synthetic insns, and macros, if any. */
+
+/* Lots of cpu's have a fixed insn size, or one which rarely changes,
+ and it's generally easier to handle these by treating the insn as an
+ integer type, rather than an array of characters. So we allow targets
+ to control this. When an integer type the value is in host byte order,
+ when an array of characters the value is in target byte order. */
+
+typedef unsigned int CGEN_INSN_INT;
+#if CGEN_INT_INSN_P
+typedef CGEN_INSN_INT CGEN_INSN_BYTES;
+typedef CGEN_INSN_INT *CGEN_INSN_BYTES_PTR;
+#else
+typedef unsigned char *CGEN_INSN_BYTES;
+typedef unsigned char *CGEN_INSN_BYTES_PTR;
+#endif
+
+#ifdef __GNUC__
+#define CGEN_INLINE __inline__
+#else
+#define CGEN_INLINE
+#endif
+
+enum cgen_endian
+{
+ CGEN_ENDIAN_UNKNOWN,
+ CGEN_ENDIAN_LITTLE,
+ CGEN_ENDIAN_BIG
+};
+
+/* Forward decl. */
+
+typedef struct cgen_insn CGEN_INSN;
+
+/* Opaque pointer version for use by external world. */
+
+typedef struct cgen_cpu_desc *CGEN_CPU_DESC;
+
+/* Attributes.
+ Attributes are used to describe various random things associated with
+ an object (ifield, hardware, operand, insn, whatever) and are specified
+ as name/value pairs.
+ Integer attributes computed at compile time are currently all that's
+ supported, though adding string attributes and run-time computation is
+ straightforward. Integer attribute values are always host int's
+ (signed or unsigned). For portability, this means 32 bits.
+ Integer attributes are further categorized as boolean, bitset, integer,
+ and enum types. Boolean attributes appear frequently enough that they're
+ recorded in one host int. This limits the maximum number of boolean
+ attributes to 32, though that's a *lot* of attributes. */
+
+/* Type of attribute values. */
+
+typedef int CGEN_ATTR_VALUE_TYPE;
+
+/* Struct to record attribute information. */
+
+typedef struct
+{
+ /* Boolean attributes. */
+ unsigned int bool;
+ /* Non-boolean integer attributes. */
+ CGEN_ATTR_VALUE_TYPE nonbool[1];
+} CGEN_ATTR;
+
+/* Define a structure member for attributes with N non-boolean entries.
+ There is no maximum number of non-boolean attributes.
+ There is a maximum of 32 boolean attributes (since they are all recorded
+ in one host int). */
+
+#define CGEN_ATTR_TYPE(n) \
+struct { unsigned int bool; \
+ CGEN_ATTR_VALUE_TYPE nonbool[(n) ? (n) : 1]; }
+
+/* Return the boolean attributes. */
+
+#define CGEN_ATTR_BOOLS(a) ((a)->bool)
+
+/* Non-boolean attribute numbers are offset by this much. */
+
+#define CGEN_ATTR_NBOOL_OFFSET 32
+
+/* Given a boolean attribute number, return its mask. */
+
+#define CGEN_ATTR_MASK(attr) (1 << (attr))
+
+/* Return the value of boolean attribute ATTR in ATTRS. */
+
+#define CGEN_BOOL_ATTR(attrs, attr) ((CGEN_ATTR_MASK (attr) & (attrs)) != 0)
+
+/* Return value of attribute ATTR in ATTR_TABLE for OBJ.
+ OBJ is a pointer to the entity that has the attributes
+ (??? not used at present but is reserved for future purposes - eventually
+ the goal is to allow recording attributes in source form and computing
+ them lazily at runtime, not sure of the details yet). */
+
+#define CGEN_ATTR_VALUE(obj, attr_table, attr) \
+((unsigned int) (attr) < CGEN_ATTR_NBOOL_OFFSET \
+ ? ((CGEN_ATTR_BOOLS (attr_table) & CGEN_ATTR_MASK (attr)) != 0) \
+ : ((attr_table)->nonbool[(attr) - CGEN_ATTR_NBOOL_OFFSET]))
+
+/* Attribute name/value tables.
+ These are used to assist parsing of descriptions at run-time. */
+
+typedef struct
+{
+ const char * name;
+ CGEN_ATTR_VALUE_TYPE value;
+} CGEN_ATTR_ENTRY;
+
+/* For each domain (ifld,hw,operand,insn), list of attributes. */
+
+typedef struct
+{
+ const char * name;
+ const CGEN_ATTR_ENTRY * dfault;
+ const CGEN_ATTR_ENTRY * vals;
+} CGEN_ATTR_TABLE;
+
+/* Instruction set variants. */
+
+typedef struct {
+ const char *name;
+
+ /* Default instruction size (in bits).
+ This is used by the assembler when it encounters an unknown insn. */
+ unsigned int default_insn_bitsize;
+
+ /* Base instruction size (in bits).
+ For non-LIW cpus this is generally the length of the smallest insn.
+ For LIW cpus its wip (work-in-progress). For the m32r its 32. */
+ unsigned int base_insn_bitsize;
+
+ /* Minimum/maximum instruction size (in bits). */
+ unsigned int min_insn_bitsize;
+ unsigned int max_insn_bitsize;
+} CGEN_ISA;
+
+/* Machine variants. */
+
+typedef struct {
+ const char *name;
+ /* The argument to bfd_arch_info->scan. */
+ const char *bfd_name;
+ /* one of enum mach_attr */
+ int num;
+} CGEN_MACH;
+
+/* Parse result (also extraction result).
+
+ The result of parsing an insn is stored here.
+ To generate the actual insn, this is passed to the insert handler.
+ When printing an insn, the result of extraction is stored here.
+ To print the insn, this is passed to the print handler.
+
+ It is machine generated so we don't define it here,
+ but we do need a forward decl for the handler fns.
+
+ There is one member for each possible field in the insn.
+ The type depends on the field.
+ Also recorded here is the computed length of the insn for architectures
+ where it varies.
+*/
+
+typedef struct cgen_fields CGEN_FIELDS;
+
+/* Total length of the insn, as recorded in the `fields' struct. */
+/* ??? The field insert handler has lots of opportunities for optimization
+ if it ever gets inlined. On architectures where insns all have the same
+ size, may wish to detect that and make this macro a constant - to allow
+ further optimizations. */
+
+#define CGEN_FIELDS_BITSIZE(fields) ((fields)->length)
+
+/* Extraction support for variable length insn sets. */
+
+/* When disassembling we don't know the number of bytes to read at the start.
+ So the first CGEN_BASE_INSN_SIZE bytes are read at the start and the rest
+ are read when needed. This struct controls this. It is basically the
+ disassemble_info stuff, except that we provide a cache for values already
+ read (since bytes can typically be read several times to fetch multiple
+ operands that may be in them), and that extraction of fields is needed
+ in contexts other than disassembly. */
+
+typedef struct {
+ /* A pointer to the disassemble_info struct.
+ We don't require dis-asm.h so we use PTR for the type here.
+ If NULL, BYTES is full of valid data (VALID == -1). */
+ PTR dis_info;
+ /* Points to a working buffer of sufficient size. */
+ unsigned char *insn_bytes;
+ /* Mask of bytes that are valid in INSN_BYTES. */
+ unsigned int valid;
+} CGEN_EXTRACT_INFO;
+
+/* Associated with each insn or expression is a set of "handlers" for
+ performing operations like parsing, printing, etc. These require a bfd_vma
+ value to be passed around but we don't want all applications to need bfd.h.
+ So this stuff is only provided if bfd.h has been included. */
+
+/* Parse handler.
+ CD is a cpu table descriptor.
+ INSN is a pointer to a struct describing the insn being parsed.
+ STRP is a pointer to a pointer to the text being parsed.
+ FIELDS is a pointer to a cgen_fields struct in which the results are placed.
+ If the expression is successfully parsed, *STRP is updated.
+ If not it is left alone.
+ The result is NULL if success or an error message. */
+typedef const char * (cgen_parse_fn)
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *insn_,
+ const char **strp_, CGEN_FIELDS *fields_));
+
+/* Insert handler.
+ CD is a cpu table descriptor.
+ INSN is a pointer to a struct describing the insn being parsed.
+ FIELDS is a pointer to a cgen_fields struct from which the values
+ are fetched.
+ INSNP is a pointer to a buffer in which to place the insn.
+ PC is the pc value of the insn.
+ The result is an error message or NULL if success. */
+
+#ifdef BFD_VERSION
+typedef const char * (cgen_insert_fn)
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *insn_,
+ CGEN_FIELDS *fields_, CGEN_INSN_BYTES_PTR insnp_,
+ bfd_vma pc_));
+#else
+typedef const char * (cgen_insert_fn) ();
+#endif
+
+/* Extract handler.
+ CD is a cpu table descriptor.
+ INSN is a pointer to a struct describing the insn being parsed.
+ The second argument is a pointer to a struct controlling extraction
+ (only used for variable length insns).
+ EX_INFO is a pointer to a struct for controlling reading of further
+ bytes for the insn.
+ BASE_INSN is the first CGEN_BASE_INSN_SIZE bytes (host order).
+ FIELDS is a pointer to a cgen_fields struct in which the results are placed.
+ PC is the pc value of the insn.
+ The result is the length of the insn in bits or zero if not recognized. */
+
+#ifdef BFD_VERSION
+typedef int (cgen_extract_fn)
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *insn_,
+ CGEN_EXTRACT_INFO *ex_info_, CGEN_INSN_INT base_insn_,
+ CGEN_FIELDS *fields_, bfd_vma pc_));
+#else
+typedef int (cgen_extract_fn) ();
+#endif
+
+/* Print handler.
+ CD is a cpu table descriptor.
+ INFO is a pointer to the disassembly info.
+ Eg: disassemble_info. It's defined as `PTR' so this file can be included
+ without dis-asm.h.
+ INSN is a pointer to a struct describing the insn being printed.
+ FIELDS is a pointer to a cgen_fields struct.
+ PC is the pc value of the insn.
+ LEN is the length of the insn, in bits. */
+
+#ifdef BFD_VERSION
+typedef void (cgen_print_fn)
+ PARAMS ((CGEN_CPU_DESC, PTR info_, const CGEN_INSN *insn_,
+ CGEN_FIELDS *fields_, bfd_vma pc_, int len_));
+#else
+typedef void (cgen_print_fn) ();
+#endif
+
+/* Parse/insert/extract/print handlers.
+
+ Indices into the handler tables.
+ We could use pointers here instead, but 90% of them are generally identical
+ and that's a lot of redundant data. Making these unsigned char indices
+ into tables of pointers saves a bit of space.
+ Using indices also keeps assembler code out of the disassembler and
+ vice versa. */
+
+struct cgen_opcode_handler
+{
+ unsigned char parse, insert, extract, print;
+};
+
+/* Assembler interface.
+
+ The interface to the assembler is intended to be clean in the sense that
+ libopcodes.a is a standalone entity and could be used with any assembler.
+ Not that one would necessarily want to do that but rather that it helps
+ keep a clean interface. The interface will obviously be slanted towards
+ GAS, but at least it's a start.
+ ??? Note that one possible user of the assembler besides GAS is GDB.
+
+ Parsing is controlled by the assembler which calls
+ CGEN_SYM (assemble_insn). If it can parse and build the entire insn
+ it doesn't call back to the assembler. If it needs/wants to call back
+ to the assembler, cgen_parse_operand_fn is called which can either
+
+ - return a number to be inserted in the insn
+ - return a "register" value to be inserted
+ (the register might not be a register per pe)
+ - queue the argument and return a marker saying the expression has been
+ queued (eg: a fix-up)
+ - return an error message indicating the expression wasn't recognizable
+
+ The result is an error message or NULL for success.
+ The parsed value is stored in the bfd_vma *. */
+
+/* Values for indicating what the caller wants. */
+
+enum cgen_parse_operand_type
+{
+ CGEN_PARSE_OPERAND_INIT,
+ CGEN_PARSE_OPERAND_INTEGER,
+ CGEN_PARSE_OPERAND_ADDRESS
+};
+
+/* Values for indicating what was parsed. */
+
+enum cgen_parse_operand_result
+{
+ CGEN_PARSE_OPERAND_RESULT_NUMBER,
+ CGEN_PARSE_OPERAND_RESULT_REGISTER,
+ CGEN_PARSE_OPERAND_RESULT_QUEUED,
+ CGEN_PARSE_OPERAND_RESULT_ERROR
+};
+
+#ifdef BFD_VERSION /* Don't require bfd.h unnecessarily. */
+typedef const char * (cgen_parse_operand_fn)
+ PARAMS ((CGEN_CPU_DESC,
+ enum cgen_parse_operand_type, const char **, int, int,
+ enum cgen_parse_operand_result *, bfd_vma *));
+#else
+typedef const char * (cgen_parse_operand_fn) ();
+#endif
+
+/* Set the cgen_parse_operand_fn callback. */
+
+extern void cgen_set_parse_operand_fn
+ PARAMS ((CGEN_CPU_DESC, cgen_parse_operand_fn));
+
+/* Called before trying to match a table entry with the insn. */
+
+extern void cgen_init_parse_operand PARAMS ((CGEN_CPU_DESC));
+
+/* Operand values (keywords, integers, symbols, etc.) */
+
+/* Types of assembler elements. */
+
+enum cgen_asm_type
+{
+ CGEN_ASM_NONE, CGEN_ASM_KEYWORD, CGEN_ASM_MAX
+};
+
+#ifndef CGEN_ARCH
+enum cgen_hw_type { CGEN_HW_MAX };
+#endif
+
+/* List of hardware elements. */
+
+typedef struct
+{
+ char *name;
+ enum cgen_hw_type type;
+ /* There is currently no example where both index specs and value specs
+ are required, so for now both are clumped under "asm_data". */
+ enum cgen_asm_type asm_type;
+ PTR asm_data;
+#ifndef CGEN_HW_NBOOL_ATTRS
+#define CGEN_HW_NBOOL_ATTRS 1
+#endif
+ CGEN_ATTR_TYPE (CGEN_HW_NBOOL_ATTRS) attrs;
+#define CGEN_HW_ATTRS(hw) (&(hw)->attrs)
+} CGEN_HW_ENTRY;
+
+/* Return value of attribute ATTR in HW. */
+
+#define CGEN_HW_ATTR_VALUE(hw, attr) \
+CGEN_ATTR_VALUE ((hw), CGEN_HW_ATTRS (hw), (attr))
+
+/* Table of hardware elements for selected mach, computed at runtime.
+ enum cgen_hw_type is an index into this table (specifically `entries'). */
+
+typedef struct {
+ /* Pointer to null terminated table of all compiled in entries. */
+ const CGEN_HW_ENTRY *init_entries;
+ unsigned int entry_size; /* since the attribute member is variable sized */
+ /* Array of all entries, initial and run-time added. */
+ const CGEN_HW_ENTRY **entries;
+ /* Number of elements in `entries'. */
+ unsigned int num_entries;
+ /* For now, xrealloc is called each time a new entry is added at runtime.
+ ??? May wish to keep track of some slop to reduce the number of calls to
+ xrealloc, except that there's unlikely to be many and not expected to be
+ in speed critical code. */
+} CGEN_HW_TABLE;
+
+extern const CGEN_HW_ENTRY * cgen_hw_lookup_by_name
+ PARAMS ((CGEN_CPU_DESC, const char *));
+extern const CGEN_HW_ENTRY * cgen_hw_lookup_by_num
+ PARAMS ((CGEN_CPU_DESC, int));
+
+/* This struct is used to describe things like register names, etc. */
+
+typedef struct cgen_keyword_entry
+{
+ /* Name (as in register name). */
+ char * name;
+
+ /* Value (as in register number).
+ The value cannot be -1 as that is used to indicate "not found".
+ IDEA: Have "FUNCTION" attribute? [function is called to fetch value]. */
+ int value;
+
+ /* Attributes.
+ This should, but technically needn't, appear last. It is a variable sized
+ array in that one architecture may have 1 nonbool attribute and another
+ may have more. Having this last means the non-architecture specific code
+ needn't care. The goal is to eventually record
+ attributes in their raw form, evaluate them at run-time, and cache the
+ values, so this worry will go away anyway. */
+ /* ??? Moving this last should be done by treating keywords like insn lists
+ and moving the `next' fields into a CGEN_KEYWORD_LIST struct. */
+ /* FIXME: Not used yet. */
+#ifndef CGEN_KEYWORD_NBOOL_ATTRS
+#define CGEN_KEYWORD_NBOOL_ATTRS 1
+#endif
+ CGEN_ATTR_TYPE (CGEN_KEYWORD_NBOOL_ATTRS) attrs;
+
+ /* ??? Putting these here means compiled in entries can't be const.
+ Not a really big deal, but something to consider. */
+ /* Next name hash table entry. */
+ struct cgen_keyword_entry *next_name;
+ /* Next value hash table entry. */
+ struct cgen_keyword_entry *next_value;
+} CGEN_KEYWORD_ENTRY;
+
+/* Top level struct for describing a set of related keywords
+ (e.g. register names).
+
+ This struct supports run-time entry of new values, and hashed lookups. */
+
+typedef struct cgen_keyword
+{
+ /* Pointer to initial [compiled in] values. */
+ CGEN_KEYWORD_ENTRY *init_entries;
+
+ /* Number of entries in `init_entries'. */
+ unsigned int num_init_entries;
+
+ /* Hash table used for name lookup. */
+ CGEN_KEYWORD_ENTRY **name_hash_table;
+
+ /* Hash table used for value lookup. */
+ CGEN_KEYWORD_ENTRY **value_hash_table;
+
+ /* Number of entries in the hash_tables. */
+ unsigned int hash_table_size;
+
+ /* Pointer to null keyword "" entry if present. */
+ const CGEN_KEYWORD_ENTRY *null_entry;
+} CGEN_KEYWORD;
+
+/* Structure used for searching. */
+
+typedef struct
+{
+ /* Table being searched. */
+ const CGEN_KEYWORD *table;
+
+ /* Specification of what is being searched for. */
+ const char *spec;
+
+ /* Current index in hash table. */
+ unsigned int current_hash;
+
+ /* Current element in current hash chain. */
+ CGEN_KEYWORD_ENTRY *current_entry;
+} CGEN_KEYWORD_SEARCH;
+
+/* Lookup a keyword from its name. */
+
+const CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_name
+ PARAMS ((CGEN_KEYWORD *, const char *));
+
+/* Lookup a keyword from its value. */
+
+const CGEN_KEYWORD_ENTRY *cgen_keyword_lookup_value
+ PARAMS ((CGEN_KEYWORD *, int));
+
+/* Add a keyword. */
+
+void cgen_keyword_add PARAMS ((CGEN_KEYWORD *, CGEN_KEYWORD_ENTRY *));
+
+/* Keyword searching.
+ This can be used to retrieve every keyword, or a subset. */
+
+CGEN_KEYWORD_SEARCH cgen_keyword_search_init
+ PARAMS ((CGEN_KEYWORD *, const char *));
+const CGEN_KEYWORD_ENTRY *cgen_keyword_search_next
+ PARAMS ((CGEN_KEYWORD_SEARCH *));
+
+/* Operand value support routines. */
+
+extern const char *cgen_parse_keyword
+ PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
+#ifdef BFD_VERSION /* Don't require bfd.h unnecessarily. */
+extern const char *cgen_parse_signed_integer
+ PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
+extern const char *cgen_parse_unsigned_integer
+ PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
+extern const char *cgen_parse_address
+ PARAMS ((CGEN_CPU_DESC, const char **, int, int,
+ enum cgen_parse_operand_result *, bfd_vma *));
+extern const char *cgen_validate_signed_integer
+ PARAMS ((long, long, long));
+extern const char *cgen_validate_unsigned_integer
+ PARAMS ((unsigned long, unsigned long, unsigned long));
+#endif
+
+/* Operand modes. */
+
+/* ??? This duplicates the values in arch.h. Revisit.
+ These however need the CGEN_ prefix [as does everything in this file]. */
+/* ??? Targets may need to add their own modes so we may wish to move this
+ to <arch>-opc.h, or add a hook. */
+
+enum cgen_mode {
+ CGEN_MODE_VOID, /* ??? rename simulator's VM to VOID? */
+ CGEN_MODE_BI, CGEN_MODE_QI, CGEN_MODE_HI, CGEN_MODE_SI, CGEN_MODE_DI,
+ CGEN_MODE_UBI, CGEN_MODE_UQI, CGEN_MODE_UHI, CGEN_MODE_USI, CGEN_MODE_UDI,
+ CGEN_MODE_SF, CGEN_MODE_DF, CGEN_MODE_XF, CGEN_MODE_TF,
+ CGEN_MODE_TARGET_MAX,
+ CGEN_MODE_INT, CGEN_MODE_UINT,
+ CGEN_MODE_MAX
+};
+
+/* FIXME: Until simulator is updated. */
+
+#define CGEN_MODE_VM CGEN_MODE_VOID
+
+/* Operands. */
+
+#ifndef CGEN_ARCH
+enum cgen_operand_type { CGEN_OPERAND_MAX };
+#endif
+
+/* "nil" indicator for the operand instance table */
+#define CGEN_OPERAND_NIL CGEN_OPERAND_MAX
+
+/* This struct defines each entry in the operand table. */
+
+typedef struct
+{
+ /* Name as it appears in the syntax string. */
+ char *name;
+
+ /* Operand type. */
+ enum cgen_operand_type type;
+
+ /* The hardware element associated with this operand. */
+ enum cgen_hw_type hw_type;
+
+ /* FIXME: We don't yet record ifield definitions, which we should.
+ When we do it might make sense to delete start/length (since they will
+ be duplicated in the ifield's definition) and replace them with a
+ pointer to the ifield entry. */
+
+ /* Bit position.
+ This is just a hint, and may be unused in more complex operands.
+ May be unused for a modifier. */
+ unsigned char start;
+
+ /* The number of bits in the operand.
+ This is just a hint, and may be unused in more complex operands.
+ May be unused for a modifier. */
+ unsigned char length;
+
+#if 0 /* ??? Interesting idea but relocs tend to get too complicated,
+ and ABI dependent, for simple table lookups to work. */
+ /* Ideally this would be the internal (external?) reloc type. */
+ int reloc_type;
+#endif
+
+ /* Attributes.
+ This should, but technically needn't, appear last. It is a variable sized
+ array in that one architecture may have 1 nonbool attribute and another
+ may have more. Having this last means the non-architecture specific code
+ needn't care, now or tomorrow. The goal is to eventually record
+ attributes in their raw form, evaluate them at run-time, and cache the
+ values, so this worry will go away anyway. */
+#ifndef CGEN_OPERAND_NBOOL_ATTRS
+#define CGEN_OPERAND_NBOOL_ATTRS 1
+#endif
+ CGEN_ATTR_TYPE (CGEN_OPERAND_NBOOL_ATTRS) attrs;
+#define CGEN_OPERAND_ATTRS(operand) (&(operand)->attrs)
+} CGEN_OPERAND;
+
+/* Return value of attribute ATTR in OPERAND. */
+
+#define CGEN_OPERAND_ATTR_VALUE(operand, attr) \
+CGEN_ATTR_VALUE ((operand), CGEN_OPERAND_ATTRS (operand), (attr))
+
+/* Table of operands for selected mach/isa, computed at runtime.
+ enum cgen_operand_type is an index into this table (specifically
+ `entries'). */
+
+typedef struct {
+ /* Pointer to null terminated table of all compiled in entries. */
+ const CGEN_OPERAND *init_entries;
+ unsigned int entry_size; /* since the attribute member is variable sized */
+ /* Array of all entries, initial and run-time added. */
+ const CGEN_OPERAND **entries;
+ /* Number of elements in `entries'. */
+ unsigned int num_entries;
+ /* For now, xrealloc is called each time a new entry is added at runtime.
+ ??? May wish to keep track of some slop to reduce the number of calls to
+ xrealloc, except that there's unlikely to be many and not expected to be
+ in speed critical code. */
+} CGEN_OPERAND_TABLE;
+
+extern const CGEN_OPERAND * cgen_operand_lookup_by_name
+ PARAMS ((CGEN_CPU_DESC, const char *));
+extern const CGEN_OPERAND * cgen_operand_lookup_by_num
+ PARAMS ((CGEN_CPU_DESC, int));
+
+/* Instruction operand instances.
+
+ For each instruction, a list of the hardware elements that are read and
+ written are recorded. */
+
+/* The type of the instance. */
+
+enum cgen_opinst_type {
+ /* End of table marker. */
+ CGEN_OPINST_END = 0,
+ CGEN_OPINST_INPUT, CGEN_OPINST_OUTPUT
+};
+
+typedef struct
+{
+ /* Input or output indicator. */
+ enum cgen_opinst_type type;
+
+ /* Name of operand. */
+ const char *name;
+
+ /* The hardware element referenced. */
+ enum cgen_hw_type hw_type;
+
+ /* The mode in which the operand is being used. */
+ enum cgen_mode mode;
+
+ /* The operand table entry CGEN_OPERAND_NIL if there is none
+ (i.e. an explicit hardware reference). */
+ enum cgen_operand_type op_type;
+
+ /* If `operand' is "nil", the index (e.g. into array of registers). */
+ int index;
+
+ /* Attributes.
+ ??? This perhaps should be a real attribute struct but there's
+ no current need, so we save a bit of space and just have a set of
+ flags. The interface is such that this can easily be made attributes
+ should it prove useful. */
+ unsigned int attrs;
+#define CGEN_OPINST_ATTRS(opinst) ((opinst)->attrs)
+/* Return value of attribute ATTR in OPINST. */
+#define CGEN_OPINST_ATTR(opinst, attr) \
+((CGEN_OPINST_ATTRS (opinst) & (attr)) != 0)
+/* Operand is conditionally referenced (read/written). */
+#define CGEN_OPINST_COND_REF 1
+} CGEN_OPINST;
+
+/* Syntax string.
+
+ Each insn format and subexpression has one of these.
+
+ The syntax "string" consists of characters (n > 0 && n < 128), and operand
+ values (n >= 128), and is terminated by 0. Operand values are 128 + index
+ into the operand table. The operand table doesn't exist in C, per se, as
+ the data is recorded in the parse/insert/extract/print switch statements. */
+
+#ifndef CGEN_MAX_SYNTAX_BYTES
+#define CGEN_MAX_SYNTAX_BYTES 16
+#endif
+
+typedef struct
+{
+ unsigned char syntax[CGEN_MAX_SYNTAX_BYTES];
+} CGEN_SYNTAX;
+
+#define CGEN_SYNTAX_STRING(syn) (syn->syntax)
+#define CGEN_SYNTAX_CHAR_P(c) ((c) < 128)
+#define CGEN_SYNTAX_CHAR(c) (c)
+#define CGEN_SYNTAX_FIELD(c) ((c) - 128)
+#define CGEN_SYNTAX_MAKE_FIELD(c) ((c) + 128)
+
+/* ??? I can't currently think of any case where the mnemonic doesn't come
+ first [and if one ever doesn't building the hash tables will be tricky].
+ However, we treat mnemonics as just another operand of the instruction.
+ A value of 1 means "this is where the mnemonic appears". 1 isn't
+ special other than it's a non-printable ASCII char. */
+
+#define CGEN_SYNTAX_MNEMONIC 1
+#define CGEN_SYNTAX_MNEMONIC_P(ch) ((ch) == CGEN_SYNTAX_MNEMONIC)
+
+/* Instruction fields.
+
+ ??? We currently don't allow adding fields at run-time.
+ Easy to fix when needed. */
+
+typedef struct cgen_ifld {
+ /* Enum of ifield. */
+ int num;
+#define CGEN_IFLD_NUM(f) ((f)->num)
+
+ /* Name of the field, distinguishes it from all other fields. */
+ const char *name;
+#define CGEN_IFLD_NAME(f) ((f)->name)
+
+ /* Default offset, in bits, from the start of the insn to the word
+ containing the field. */
+ int word_offset;
+#define CGEN_IFLD_WORD_OFFSET(f) ((f)->word_offset)
+
+ /* Default length of the word containing the field. */
+ int word_size;
+#define CGEN_IFLD_WORD_SIZE(f) ((f)->word_size)
+
+ /* Default starting bit number.
+ Whether lsb=0 or msb=0 is determined by CGEN_INSN_LSB0_P. */
+ int start;
+#define CGEN_IFLD_START(f) ((f)->start)
+
+ /* Length of the field, in bits. */
+ int length;
+#define CGEN_IFLD_LENGTH(f) ((f)->length)
+
+#ifndef CGEN_IFLD_NBOOL_ATTRS
+#define CGEN_IFLD_NBOOL_ATTRS 1
+#endif
+ CGEN_ATTR_TYPE (CGEN_IFLD_NBOOL_ATTRS) attrs;
+#define CGEN_IFLD_ATTRS(f) (&(f)->attrs)
+} CGEN_IFLD;
+
+/* Return value of attribute ATTR in IFLD. */
+#define CGEN_IFLD_ATTR_VALUE(ifld, attr) \
+CGEN_ATTR_VALUE ((ifld), CGEN_IFLD_ATTRS (ifld), (attr))
+
+/* Instruction data. */
+
+/* Instruction formats.
+
+ Instructions are grouped by format. Associated with an instruction is its
+ format. Each insn's opcode table entry contains a format table entry.
+ ??? There is usually very few formats compared with the number of insns,
+ so one can reduce the size of the opcode table by recording the format table
+ as a separate entity. Given that we currently don't, format table entries
+ are also distinguished by their operands. This increases the size of the
+ table, but reduces the number of tables. It's all minutiae anyway so it
+ doesn't really matter [at this point in time].
+
+ ??? Support for variable length ISA's is wip. */
+
+/* Accompanying each iformat description is a list of its fields. */
+
+typedef struct {
+ const CGEN_IFLD *ifld;
+#define CGEN_IFMT_IFLD_IFLD(ii) ((ii)->ifld)
+} CGEN_IFMT_IFLD;
+
+#ifndef CGEN_MAX_IFMT_OPERANDS
+#define CGEN_MAX_IFMT_OPERANDS 1
+#endif
+
+typedef struct
+{
+ /* Length that MASK and VALUE have been calculated to
+ [VALUE is recorded elsewhere].
+ Normally it is base_insn_bitsize. On [V]LIW architectures where the base
+ insn size may be larger than the size of an insn, this field is less than
+ base_insn_bitsize. */
+ unsigned char mask_length;
+#define CGEN_IFMT_MASK_LENGTH(ifmt) ((ifmt)->mask_length)
+
+ /* Total length of instruction, in bits. */
+ unsigned char length;
+#define CGEN_IFMT_LENGTH(ifmt) ((ifmt)->length)
+
+ /* Mask to apply to the first MASK_LENGTH bits.
+ Each insn's value is stored with the insn.
+ The first step in recognizing an insn for disassembly is
+ (opcode & mask) == value. */
+ CGEN_INSN_INT mask;
+#define CGEN_IFMT_MASK(ifmt) ((ifmt)->mask)
+
+ /* Instruction fields.
+ +1 for trailing NULL. */
+ CGEN_IFMT_IFLD iflds[CGEN_MAX_IFMT_OPERANDS + 1];
+#define CGEN_IFMT_IFLDS(ifmt) ((ifmt)->iflds)
+} CGEN_IFMT;
+
+/* Instruction values. */
+
+typedef struct
+{
+ /* The opcode portion of the base insn. */
+ CGEN_INSN_INT base_value;
+
+#ifdef CGEN_MAX_EXTRA_OPCODE_OPERANDS
+ /* Extra opcode values beyond base_value. */
+ unsigned long ifield_values[CGEN_MAX_EXTRA_OPCODE_OPERANDS];
+#endif
+} CGEN_IVALUE;
+
+/* Instruction opcode table.
+ This contains the syntax and format data of an instruction. */
+
+/* ??? Some ports already have an opcode table yet still need to use the rest
+ of what cgen_insn has. Plus keeping the opcode data with the operand
+ instance data can create a pretty big file. So we keep them separately.
+ Not sure this is a good idea in the long run. */
+
+typedef struct
+{
+ /* Indices into parse/insert/extract/print handler tables. */
+ struct cgen_opcode_handler handlers;
+#define CGEN_OPCODE_HANDLERS(opc) (& (opc)->handlers)
+
+ /* Syntax string. */
+ CGEN_SYNTAX syntax;
+#define CGEN_OPCODE_SYNTAX(opc) (& (opc)->syntax)
+
+ /* Format entry. */
+ const CGEN_IFMT *format;
+#define CGEN_OPCODE_FORMAT(opc) ((opc)->format)
+#define CGEN_OPCODE_MASK_BITSIZE(opc) CGEN_IFMT_MASK_LENGTH (CGEN_OPCODE_FORMAT (opc))
+#define CGEN_OPCODE_BITSIZE(opc) CGEN_IFMT_LENGTH (CGEN_OPCODE_FORMAT (opc))
+#define CGEN_OPCODE_IFLDS(opc) CGEN_IFMT_IFLDS (CGEN_OPCODE_FORMAT (opc))
+
+ /* Instruction opcode value. */
+ CGEN_IVALUE value;
+#define CGEN_OPCODE_VALUE(opc) (& (opc)->value)
+#define CGEN_OPCODE_BASE_VALUE(opc) (CGEN_OPCODE_VALUE (opc)->base_value)
+#define CGEN_OPCODE_BASE_MASK(opc) CGEN_IFMT_MASK (CGEN_OPCODE_FORMAT (opc))
+} CGEN_OPCODE;
+
+/* Instruction attributes.
+ This is made a published type as applications can cache a pointer to
+ the attributes for speed. */
+
+#ifndef CGEN_INSN_NBOOL_ATTRS
+#define CGEN_INSN_NBOOL_ATTRS 1
+#endif
+typedef CGEN_ATTR_TYPE (CGEN_INSN_NBOOL_ATTRS) CGEN_INSN_ATTR_TYPE;
+
+/* Enum of architecture independent attributes. */
+
+#ifndef CGEN_ARCH
+/* ??? Numbers here are recorded in two places. */
+typedef enum cgen_insn_attr {
+ CGEN_INSN_ALIAS = 0
+} CGEN_INSN_ATTR;
+#endif
+
+/* This struct defines each entry in the instruction table. */
+
+typedef struct
+{
+ /* Each real instruction is enumerated. */
+ /* ??? This may go away in time. */
+ int num;
+#define CGEN_INSN_NUM(insn) ((insn)->base->num)
+
+ /* Name of entry (that distinguishes it from all other entries). */
+ /* ??? If mnemonics have operands, try to print full mnemonic. */
+ const char *name;
+#define CGEN_INSN_NAME(insn) ((insn)->base->name)
+
+ /* Mnemonic. This is used when parsing and printing the insn.
+ In the case of insns that have operands on the mnemonics, this is
+ only the constant part. E.g. for conditional execution of an `add' insn,
+ where the full mnemonic is addeq, addne, etc., and the condition is
+ treated as an operand, this is only "add". */
+ const char *mnemonic;
+#define CGEN_INSN_MNEMONIC(insn) ((insn)->base->mnemonic)
+
+ /* Total length of instruction, in bits. */
+ int bitsize;
+#define CGEN_INSN_BITSIZE(insn) ((insn)->base->bitsize)
+
+#if 0 /* ??? Disabled for now as there is a problem with embedded newlines
+ and the table is already pretty big. Should perhaps be moved
+ to a file of its own. */
+ /* Semantics, as RTL. */
+ /* ??? Plain text or bytecodes? */
+ /* ??? Note that the operand instance table could be computed at run-time
+ if we parse this and cache the results. Something to eventually do. */
+ const char *rtx;
+#define CGEN_INSN_RTX(insn) ((insn)->base->rtx)
+#endif
+
+ /* Attributes.
+ This must appear last. It is a variable sized array in that one
+ architecture may have 1 nonbool attribute and another may have more.
+ Having this last means the non-architecture specific code needn't
+ care. The goal is to eventually record attributes in their raw form,
+ evaluate them at run-time, and cache the values, so this worry will go
+ away anyway. */
+ CGEN_INSN_ATTR_TYPE attrs;
+#define CGEN_INSN_ATTRS(insn) (&(insn)->base->attrs)
+/* Return value of attribute ATTR in INSN. */
+#define CGEN_INSN_ATTR_VALUE(insn, attr) \
+CGEN_ATTR_VALUE ((insn), CGEN_INSN_ATTRS (insn), (attr))
+} CGEN_IBASE;
+
+/* Return non-zero if INSN is the "invalid" insn marker. */
+
+#define CGEN_INSN_INVALID_P(insn) (CGEN_INSN_MNEMONIC (insn) == 0)
+
+/* Main struct contain instruction information.
+ BASE is always present, the rest is present only if asked for. */
+
+struct cgen_insn
+{
+ /* ??? May be of use to put a type indicator here.
+ Then this struct could different info for different classes of insns. */
+ /* ??? A speedup can be had by moving `base' into this struct.
+ Maybe later. */
+ const CGEN_IBASE *base;
+ const CGEN_OPCODE *opcode;
+ const CGEN_OPINST *opinst;
+};
+
+/* Instruction lists.
+ This is used for adding new entries and for creating the hash lists. */
+
+typedef struct cgen_insn_list
+{
+ struct cgen_insn_list *next;
+ const CGEN_INSN *insn;
+} CGEN_INSN_LIST;
+
+/* Table of instructions. */
+
+typedef struct
+{
+ const CGEN_INSN *init_entries;
+ unsigned int entry_size; /* since the attribute member is variable sized */
+ unsigned int num_init_entries;
+ CGEN_INSN_LIST *new_entries;
+} CGEN_INSN_TABLE;
+
+/* Return number of instructions. This includes any added at run-time. */
+
+extern int cgen_insn_count PARAMS ((CGEN_CPU_DESC));
+extern int cgen_macro_insn_count PARAMS ((CGEN_CPU_DESC));
+
+/* Macros to access the other insn elements not recorded in CGEN_IBASE. */
+
+/* Fetch INSN's operand instance table. */
+/* ??? Doesn't handle insns added at runtime. */
+#define CGEN_INSN_OPERANDS(insn) ((insn)->opinst)
+
+/* Return INSN's opcode table entry. */
+#define CGEN_INSN_OPCODE(insn) ((insn)->opcode)
+
+/* Return INSN's handler data. */
+#define CGEN_INSN_HANDLERS(insn) CGEN_OPCODE_HANDLERS (CGEN_INSN_OPCODE (insn))
+
+/* Return INSN's syntax. */
+#define CGEN_INSN_SYNTAX(insn) CGEN_OPCODE_SYNTAX (CGEN_INSN_OPCODE (insn))
+
+/* Return size of base mask in bits. */
+#define CGEN_INSN_MASK_BITSIZE(insn) \
+ CGEN_OPCODE_MASK_BITSIZE (CGEN_INSN_OPCODE (insn))
+
+/* Return mask of base part of INSN. */
+#define CGEN_INSN_BASE_MASK(insn) \
+ CGEN_OPCODE_BASE_MASK (CGEN_INSN_OPCODE (insn))
+
+/* Return value of base part of INSN. */
+#define CGEN_INSN_BASE_VALUE(insn) \
+ CGEN_OPCODE_BASE_VALUE (CGEN_INSN_OPCODE (insn))
+
+/* Macro instructions.
+ Macro insns aren't real insns, they map to one or more real insns.
+ E.g. An architecture's "nop" insn may actually be an "mv r0,r0" or
+ some such.
+
+ Macro insns can expand to nothing (e.g. a nop that is optimized away).
+ This is useful in multi-insn macros that build a constant in a register.
+ Of course this isn't the default behaviour and must be explicitly enabled.
+
+ Assembly of macro-insns is relatively straightforward. Disassembly isn't.
+ However, disassembly of at least some kinds of macro insns is important
+ in order that the disassembled code preserve the readability of the original
+ insn. What is attempted here is to disassemble all "simple" macro-insns,
+ where "simple" is currently defined to mean "expands to one real insn".
+
+ Simple macro-insns are handled specially. They are emitted as ALIAS's
+ of real insns. This simplifies their handling since there's usually more
+ of them than any other kind of macro-insn, and proper disassembly of them
+ falls out for free. */
+
+/* For each macro-insn there may be multiple expansion possibilities,
+ depending on the arguments. This structure is accessed via the `data'
+ member of CGEN_INSN. */
+
+typedef struct cgen_minsn_expansion {
+ /* Function to do the expansion.
+ If the expansion fails (e.g. "no match") NULL is returned.
+ Space for the expansion is obtained with malloc.
+ It is up to the caller to free it. */
+ const char * (* fn) PARAMS ((const struct cgen_minsn_expansion *,
+ const char *, const char **, int *,
+ CGEN_OPERAND **));
+#define CGEN_MIEXPN_FN(ex) ((ex)->fn)
+
+ /* Instruction(s) the macro expands to.
+ The format of STR is defined by FN.
+ It is typically the assembly code of the real insn, but it could also be
+ the original Scheme expression or a tokenized form of it (with FN being
+ an appropriate interpreter). */
+ const char * str;
+#define CGEN_MIEXPN_STR(ex) ((ex)->str)
+} CGEN_MINSN_EXPANSION;
+
+/* Normal expander.
+ When supported, this function will convert the input string to another
+ string and the parser will be invoked recursively. The output string
+ may contain further macro invocations. */
+
+extern const char * cgen_expand_macro_insn
+ PARAMS ((CGEN_CPU_DESC, const struct cgen_minsn_expansion *,
+ const char *, const char **, int *, CGEN_OPERAND **));
+
+/* The assembler insn table is hashed based on some function of the mnemonic
+ (the actually hashing done is up to the target, but we provide a few
+ examples like the first letter or a function of the entire mnemonic). */
+
+extern CGEN_INSN_LIST * cgen_asm_lookup_insn
+ PARAMS ((CGEN_CPU_DESC, const char *));
+#define CGEN_ASM_LOOKUP_INSN(cd, string) cgen_asm_lookup_insn ((cd), (string))
+#define CGEN_ASM_NEXT_INSN(insn) ((insn)->next)
+
+/* The disassembler insn table is hashed based on some function of machine
+ instruction (the actually hashing done is up to the target). */
+
+extern CGEN_INSN_LIST * cgen_dis_lookup_insn
+ PARAMS ((CGEN_CPU_DESC, const char *, CGEN_INSN_INT));
+/* FIXME: delete these two */
+#define CGEN_DIS_LOOKUP_INSN(cd, buf, value) cgen_dis_lookup_insn ((cd), (buf), (value))
+#define CGEN_DIS_NEXT_INSN(insn) ((insn)->next)
+
+/* The CPU description.
+ A copy of this is created when the cpu table is "opened".
+ All global state information is recorded here.
+ Access macros are provided for "public" members. */
+
+typedef struct cgen_cpu_desc
+{
+ /* Bitmap of selected machine(s) (a la BFD machine number). */
+ int machs;
+
+ /* Bitmap of selected isa(s).
+ ??? Simultaneous multiple isas might not make sense, but it's not (yet)
+ precluded. */
+ int isas;
+
+ /* Current endian. */
+ enum cgen_endian endian;
+#define CGEN_CPU_ENDIAN(cd) ((cd)->endian)
+
+ /* Current insn endian. */
+ enum cgen_endian insn_endian;
+#define CGEN_CPU_INSN_ENDIAN(cd) ((cd)->insn_endian)
+
+ /* Word size (in bits). */
+ /* ??? Or maybe maximum word size - might we ever need to allow a cpu table
+ to be opened for both sparc32/sparc64?
+ ??? Another alternative is to create a table of selected machs and
+ lazily fetch the data from there. */
+ unsigned int word_bitsize;
+
+ /* Indicator if sizes are unknown.
+ This is used by default_insn_bitsize,base_insn_bitsize if there is a
+ difference between the selected isa's. */
+#define CGEN_SIZE_UNKNOWN 65535
+
+ /* Default instruction size (in bits).
+ This is used by the assembler when it encounters an unknown insn. */
+ unsigned int default_insn_bitsize;
+
+ /* Base instruction size (in bits).
+ For non-LIW cpus this is generally the length of the smallest insn.
+ For LIW cpus its wip (work-in-progress). For the m32r its 32. */
+ unsigned int base_insn_bitsize;
+
+ /* Minimum/maximum instruction size (in bits). */
+ unsigned int min_insn_bitsize;
+ unsigned int max_insn_bitsize;
+
+ /* Instruction set variants. */
+ const CGEN_ISA *isa_table;
+
+ /* Machine variants. */
+ const CGEN_MACH *mach_table;
+
+ /* Hardware elements. */
+ CGEN_HW_TABLE hw_table;
+
+ /* Instruction fields. */
+ const CGEN_IFLD *ifld_table;
+
+ /* Operands. */
+ CGEN_OPERAND_TABLE operand_table;
+
+ /* Main instruction table. */
+ CGEN_INSN_TABLE insn_table;
+#define CGEN_CPU_INSN_TABLE(cd) (& (cd)->insn_table)
+
+ /* Macro instructions are defined separately and are combined with real
+ insns during hash table computation. */
+ CGEN_INSN_TABLE macro_insn_table;
+
+ /* Copy of CGEN_INT_INSN_P. */
+ int int_insn_p;
+
+ /* Called to rebuild the tables after something has changed. */
+ void (*rebuild_tables) PARAMS ((CGEN_CPU_DESC));
+
+ /* Operand parser callback. */
+ cgen_parse_operand_fn * parse_operand_fn;
+
+ /* Parse/insert/extract/print cover fns for operands. */
+ const char * (*parse_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, const char **,
+ CGEN_FIELDS *fields_));
+#ifdef BFD_VERSION
+ const char * (*insert_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_,
+ CGEN_INSN_BYTES_PTR, bfd_vma pc_));
+ int (*extract_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
+ CGEN_FIELDS *fields_, bfd_vma pc_));
+ void (*print_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, PTR info_, CGEN_FIELDS * fields_,
+ void const *attrs_, bfd_vma pc_, int length_));
+#else
+ const char * (*insert_operand) ();
+ int (*extract_operand) ();
+ void (*print_operand) ();
+#endif
+#define CGEN_CPU_PARSE_OPERAND(cd) ((cd)->parse_operand)
+#define CGEN_CPU_INSERT_OPERAND(cd) ((cd)->insert_operand)
+#define CGEN_CPU_EXTRACT_OPERAND(cd) ((cd)->extract_operand)
+#define CGEN_CPU_PRINT_OPERAND(cd) ((cd)->print_operand)
+
+ /* Size of CGEN_FIELDS struct. */
+ unsigned int sizeof_fields;
+#define CGEN_CPU_SIZEOF_FIELDS(cd) ((cd)->sizeof_fields)
+
+ /* Set the bitsize field. */
+ void (*set_fields_bitsize) PARAMS ((CGEN_FIELDS *fields_, int size_));
+#define CGEN_CPU_SET_FIELDS_BITSIZE(cd) ((cd)->set_fields_bitsize)
+
+ /* CGEN_FIELDS accessors. */
+ int (*get_int_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_));
+ void (*set_int_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, int value_));
+#ifdef BFD_VERSION
+ bfd_vma (*get_vma_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, const CGEN_FIELDS *fields_));
+ void (*set_vma_operand)
+ PARAMS ((CGEN_CPU_DESC, int opindex_, CGEN_FIELDS *fields_, bfd_vma value_));
+#else
+ long (*get_vma_operand) ();
+ void (*set_vma_operand) ();
+#endif
+#define CGEN_CPU_GET_INT_OPERAND(cd) ((cd)->get_int_operand)
+#define CGEN_CPU_SET_INT_OPERAND(cd) ((cd)->set_int_operand)
+#define CGEN_CPU_GET_VMA_OPERAND(cd) ((cd)->get_vma_operand)
+#define CGEN_CPU_SET_VMA_OPERAND(cd) ((cd)->set_vma_operand)
+
+ /* Instruction parse/insert/extract/print handlers. */
+ /* FIXME: make these types uppercase. */
+ cgen_parse_fn * const *parse_handlers;
+ cgen_insert_fn * const *insert_handlers;
+ cgen_extract_fn * const *extract_handlers;
+ cgen_print_fn * const *print_handlers;
+#define CGEN_PARSE_FN(cd, insn) (cd->parse_handlers[(insn)->opcode->handlers.parse])
+#define CGEN_INSERT_FN(cd, insn) (cd->insert_handlers[(insn)->opcode->handlers.insert])
+#define CGEN_EXTRACT_FN(cd, insn) (cd->extract_handlers[(insn)->opcode->handlers.extract])
+#define CGEN_PRINT_FN(cd, insn) (cd->print_handlers[(insn)->opcode->handlers.print])
+
+ /* Return non-zero if insn should be added to hash table. */
+ int (* asm_hash_p) PARAMS ((const CGEN_INSN *));
+
+ /* Assembler hash function. */
+ unsigned int (* asm_hash) PARAMS ((const char *));
+
+ /* Number of entries in assembler hash table. */
+ unsigned int asm_hash_size;
+
+ /* Return non-zero if insn should be added to hash table. */
+ int (* dis_hash_p) PARAMS ((const CGEN_INSN *));
+
+ /* Disassembler hash function. */
+ unsigned int (* dis_hash) PARAMS ((const char *, CGEN_INSN_INT));
+
+ /* Number of entries in disassembler hash table. */
+ unsigned int dis_hash_size;
+
+ /* Assembler instruction hash table. */
+ CGEN_INSN_LIST **asm_hash_table;
+ CGEN_INSN_LIST *asm_hash_table_entries;
+
+ /* Disassembler instruction hash table. */
+ CGEN_INSN_LIST **dis_hash_table;
+ CGEN_INSN_LIST *dis_hash_table_entries;
+} CGEN_CPU_TABLE;
+
+/* wip */
+#ifndef CGEN_WORD_ENDIAN
+#define CGEN_WORD_ENDIAN(cd) CGEN_CPU_ENDIAN (cd)
+#endif
+#ifndef CGEN_INSN_WORD_ENDIAN
+#define CGEN_INSN_WORD_ENDIAN(cd) CGEN_CPU_INSN_ENDIAN (cd)
+#endif
+
+/* Prototypes of major functions. */
+/* FIXME: Move more CGEN_SYM-defined functions into CGEN_CPU_DESC.
+ Not the init fns though, as that would drag in things that mightn't be
+ used and might not even exist. */
+
+/* Argument types to cpu_open. */
+
+enum cgen_cpu_open_arg {
+ CGEN_CPU_OPEN_END,
+ /* Select instruction set(s), arg is bitmap or 0 meaning "unspecified". */
+ CGEN_CPU_OPEN_ISAS,
+ /* Select machine(s), arg is bitmap or 0 meaning "unspecified". */
+ CGEN_CPU_OPEN_MACHS,
+ /* Select machine, arg is mach's bfd name.
+ Multiple machines can be specified by repeated use. */
+ CGEN_CPU_OPEN_BFDMACH,
+ /* Select endian, arg is CGEN_ENDIAN_*. */
+ CGEN_CPU_OPEN_ENDIAN
+};
+
+/* Open a cpu descriptor table for use.
+ ??? We only support ISO C stdargs here, not K&R.
+ Laziness, plus experiment to see if anything requires K&R - eventually
+ K&R will no longer be supported - e.g. GDB is currently trying this. */
+
+extern CGEN_CPU_DESC CGEN_SYM (cpu_open) (enum cgen_cpu_open_arg, ...);
+
+/* Cover fn to handle simple case. */
+
+extern CGEN_CPU_DESC CGEN_SYM (cpu_open_1) PARAMS ((const char *mach_name_,
+ enum cgen_endian endian_));
+
+/* Close it. */
+
+extern void CGEN_SYM (cpu_close) PARAMS ((CGEN_CPU_DESC));
+
+/* Initialize the opcode table for use.
+ Called by init_asm/init_dis. */
+
+extern void CGEN_SYM (init_opcode_table) PARAMS ((CGEN_CPU_DESC cd_));
+
+/* Initialize the ibld table for use.
+ Called by init_asm/init_dis. */
+
+extern void CGEN_SYM (init_ibld_table) PARAMS ((CGEN_CPU_DESC cd_));
+
+/* Initialize an cpu table for assembler or disassembler use.
+ These must be called immediately after cpu_open. */
+
+extern void CGEN_SYM (init_asm) PARAMS ((CGEN_CPU_DESC));
+extern void CGEN_SYM (init_dis) PARAMS ((CGEN_CPU_DESC));
+
+/* Initialize the operand instance table for use. */
+
+extern void CGEN_SYM (init_opinst_table) PARAMS ((CGEN_CPU_DESC cd_));
+
+/* Assemble an instruction. */
+
+extern const CGEN_INSN * CGEN_SYM (assemble_insn)
+ PARAMS ((CGEN_CPU_DESC, const char *, CGEN_FIELDS *,
+ CGEN_INSN_BYTES_PTR, char **));
+
+extern const CGEN_KEYWORD CGEN_SYM (operand_mach);
+extern int CGEN_SYM (get_mach) PARAMS ((const char *));
+
+/* Operand index computation. */
+extern const CGEN_INSN * cgen_lookup_insn
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN * insn_,
+ CGEN_INSN_INT int_value_, unsigned char *bytes_value_,
+ int length_, CGEN_FIELDS *fields_, int alias_p_));
+extern void cgen_get_insn_operands
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN * insn_,
+ const CGEN_FIELDS *fields_, int *indices_));
+extern const CGEN_INSN * cgen_lookup_get_insn_operands
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *insn_,
+ CGEN_INSN_INT int_value_, unsigned char *bytes_value_,
+ int length_, int *indices_, CGEN_FIELDS *fields_));
+
+/* Cover fns to bfd_get/set. */
+
+extern CGEN_INSN_INT cgen_get_insn_value
+ PARAMS ((CGEN_CPU_DESC, unsigned char *, int));
+extern void cgen_put_insn_value
+ PARAMS ((CGEN_CPU_DESC, unsigned char *, int, CGEN_INSN_INT));
+
+/* Read in a cpu description file.
+ ??? For future concerns, including adding instructions to the assembler/
+ disassembler at run-time. */
+
+extern const char * cgen_read_cpu_file
+ PARAMS ((CGEN_CPU_DESC, const char * filename_));
+
+#endif /* CGEN_H */
diff --git a/include/opcode/convex.h b/include/opcode/convex.h
new file mode 100644
index 00000000000..efaeebb65a5
--- /dev/null
+++ b/include/opcode/convex.h
@@ -0,0 +1,1711 @@
+/* Information for instruction disassembly on the Convex.
+ Copyright 1989, 1993 Free Software Foundation.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef CONST
+#define CONST
+#endif /* CONST */
+
+#define xxx 0
+#define rrr 1
+#define rr 2
+#define rxr 3
+#define r 4
+#define nops 5
+#define nr 6
+#define pcrel 7
+#define lr 8
+#define rxl 9
+#define rlr 10
+#define rrl 11
+#define iml 12
+#define imr 13
+#define a1r 14
+#define a1l 15
+#define a2r 16
+#define a2l 17
+#define a3 18
+#define a4 19
+#define a5 20
+#define V 1
+#define S 2
+#define VM 3
+#define A 4
+#define VL 5
+#define VS 6
+#define VLS 7
+#define PSW 8
+/* Prevent an error during "make depend". */
+#if !defined (PC)
+#define PC 9
+#endif
+#define ITR 10
+#define VV 11
+#define ITSR 12
+#define TOC 13
+#define CIR 14
+#define TTR 15
+#define VMU 16
+#define VML 17
+#define ICR 18
+#define TCPU 19
+#define CPUID 20
+#define TID 21
+
+CONST char *op[] = {
+ "",
+ "v0\0v1\0v2\0v3\0v4\0v5\0v6\0v7",
+ "s0\0s1\0s2\0s3\0s4\0s5\0s6\0s7",
+ "vm",
+ "sp\0a1\0a2\0a3\0a4\0a5\0ap\0fp",
+ "vl",
+ "vs",
+ "vls",
+ "psw",
+ "pc",
+ "itr",
+ "vv",
+ "itsr",
+ "toc",
+ "cir",
+ "ttr",
+ "vmu",
+ "vml",
+ "icr",
+ "tcpu",
+ "cpuid",
+ "tid",
+};
+
+CONST struct formstr format0[] = {
+ {0,0,rrr,V,S,S}, /* mov */
+ {0,0,rrr,S,S,V}, /* mov */
+ {1,1,rrr,V,V,V}, /* merg.t */
+ {2,1,rrr,V,V,V}, /* mask.t */
+ {1,2,rrr,V,S,V}, /* merg.f */
+ {2,2,rrr,V,S,V}, /* mask.f */
+ {1,1,rrr,V,S,V}, /* merg.t */
+ {2,1,rrr,V,S,V}, /* mask.t */
+ {3,3,rrr,V,V,V}, /* mul.s */
+ {3,4,rrr,V,V,V}, /* mul.d */
+ {4,3,rrr,V,V,V}, /* div.s */
+ {4,4,rrr,V,V,V}, /* div.d */
+ {3,3,rrr,V,S,V}, /* mul.s */
+ {3,4,rrr,V,S,V}, /* mul.d */
+ {4,3,rrr,V,S,V}, /* div.s */
+ {4,4,rrr,V,S,V}, /* div.d */
+ {5,0,rrr,V,V,V}, /* and */
+ {6,0,rrr,V,V,V}, /* or */
+ {7,0,rrr,V,V,V}, /* xor */
+ {8,0,rrr,V,V,V}, /* shf */
+ {5,0,rrr,V,S,V}, /* and */
+ {6,0,rrr,V,S,V}, /* or */
+ {7,0,rrr,V,S,V}, /* xor */
+ {8,0,rrr,V,S,V}, /* shf */
+ {9,3,rrr,V,V,V}, /* add.s */
+ {9,4,rrr,V,V,V}, /* add.d */
+ {10,3,rrr,V,V,V}, /* sub.s */
+ {10,4,rrr,V,V,V}, /* sub.d */
+ {9,3,rrr,V,S,V}, /* add.s */
+ {9,4,rrr,V,S,V}, /* add.d */
+ {10,3,rrr,V,S,V}, /* sub.s */
+ {10,4,rrr,V,S,V}, /* sub.d */
+ {9,5,rrr,V,V,V}, /* add.b */
+ {9,6,rrr,V,V,V}, /* add.h */
+ {9,7,rrr,V,V,V}, /* add.w */
+ {9,8,rrr,V,V,V}, /* add.l */
+ {9,5,rrr,V,S,V}, /* add.b */
+ {9,6,rrr,V,S,V}, /* add.h */
+ {9,7,rrr,V,S,V}, /* add.w */
+ {9,8,rrr,V,S,V}, /* add.l */
+ {10,5,rrr,V,V,V}, /* sub.b */
+ {10,6,rrr,V,V,V}, /* sub.h */
+ {10,7,rrr,V,V,V}, /* sub.w */
+ {10,8,rrr,V,V,V}, /* sub.l */
+ {10,5,rrr,V,S,V}, /* sub.b */
+ {10,6,rrr,V,S,V}, /* sub.h */
+ {10,7,rrr,V,S,V}, /* sub.w */
+ {10,8,rrr,V,S,V}, /* sub.l */
+ {3,5,rrr,V,V,V}, /* mul.b */
+ {3,6,rrr,V,V,V}, /* mul.h */
+ {3,7,rrr,V,V,V}, /* mul.w */
+ {3,8,rrr,V,V,V}, /* mul.l */
+ {3,5,rrr,V,S,V}, /* mul.b */
+ {3,6,rrr,V,S,V}, /* mul.h */
+ {3,7,rrr,V,S,V}, /* mul.w */
+ {3,8,rrr,V,S,V}, /* mul.l */
+ {4,5,rrr,V,V,V}, /* div.b */
+ {4,6,rrr,V,V,V}, /* div.h */
+ {4,7,rrr,V,V,V}, /* div.w */
+ {4,8,rrr,V,V,V}, /* div.l */
+ {4,5,rrr,V,S,V}, /* div.b */
+ {4,6,rrr,V,S,V}, /* div.h */
+ {4,7,rrr,V,S,V}, /* div.w */
+ {4,8,rrr,V,S,V}, /* div.l */
+};
+
+CONST struct formstr format1[] = {
+ {11,0,xxx,0,0,0}, /* exit */
+ {12,0,a3,0,0,0}, /* jmp */
+ {13,2,a3,0,0,0}, /* jmpi.f */
+ {13,1,a3,0,0,0}, /* jmpi.t */
+ {14,2,a3,0,0,0}, /* jmpa.f */
+ {14,1,a3,0,0,0}, /* jmpa.t */
+ {15,2,a3,0,0,0}, /* jmps.f */
+ {15,1,a3,0,0,0}, /* jmps.t */
+ {16,0,a3,0,0,0}, /* tac */
+ {17,0,a1r,A,0,0}, /* ldea */
+ {18,8,a1l,VLS,0,0}, /* ld.l */
+ {18,9,a1l,VM,0,0}, /* ld.x */
+ {19,0,a3,0,0,0}, /* tas */
+ {20,0,a3,0,0,0}, /* pshea */
+ {21,8,a2l,VLS,0,0}, /* st.l */
+ {21,9,a2l,VM,0,0}, /* st.x */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {22,0,a3,0,0,0}, /* call */
+ {23,0,a3,0,0,0}, /* calls */
+ {24,0,a3,0,0,0}, /* callq */
+ {25,0,a1r,A,0,0}, /* pfork */
+ {26,5,a2r,S,0,0}, /* ste.b */
+ {26,6,a2r,S,0,0}, /* ste.h */
+ {26,7,a2r,S,0,0}, /* ste.w */
+ {26,8,a2r,S,0,0}, /* ste.l */
+ {18,5,a1r,A,0,0}, /* ld.b */
+ {18,6,a1r,A,0,0}, /* ld.h */
+ {18,7,a1r,A,0,0}, /* ld.w */
+ {27,7,a1r,A,0,0}, /* incr.w */
+ {21,5,a2r,A,0,0}, /* st.b */
+ {21,6,a2r,A,0,0}, /* st.h */
+ {21,7,a2r,A,0,0}, /* st.w */
+ {27,8,a1r,S,0,0}, /* incr.l */
+ {18,5,a1r,S,0,0}, /* ld.b */
+ {18,6,a1r,S,0,0}, /* ld.h */
+ {18,7,a1r,S,0,0}, /* ld.w */
+ {18,8,a1r,S,0,0}, /* ld.l */
+ {21,5,a2r,S,0,0}, /* st.b */
+ {21,6,a2r,S,0,0}, /* st.h */
+ {21,7,a2r,S,0,0}, /* st.w */
+ {21,8,a2r,S,0,0}, /* st.l */
+ {18,5,a1r,V,0,0}, /* ld.b */
+ {18,6,a1r,V,0,0}, /* ld.h */
+ {18,7,a1r,V,0,0}, /* ld.w */
+ {18,8,a1r,V,0,0}, /* ld.l */
+ {21,5,a2r,V,0,0}, /* st.b */
+ {21,6,a2r,V,0,0}, /* st.h */
+ {21,7,a2r,V,0,0}, /* st.w */
+ {21,8,a2r,V,0,0}, /* st.l */
+};
+
+CONST struct formstr format2[] = {
+ {28,5,rr,A,A,0}, /* cvtw.b */
+ {28,6,rr,A,A,0}, /* cvtw.h */
+ {29,7,rr,A,A,0}, /* cvtb.w */
+ {30,7,rr,A,A,0}, /* cvth.w */
+ {28,5,rr,S,S,0}, /* cvtw.b */
+ {28,6,rr,S,S,0}, /* cvtw.h */
+ {29,7,rr,S,S,0}, /* cvtb.w */
+ {30,7,rr,S,S,0}, /* cvth.w */
+ {28,3,rr,S,S,0}, /* cvtw.s */
+ {31,7,rr,S,S,0}, /* cvts.w */
+ {32,3,rr,S,S,0}, /* cvtd.s */
+ {31,4,rr,S,S,0}, /* cvts.d */
+ {31,8,rr,S,S,0}, /* cvts.l */
+ {32,8,rr,S,S,0}, /* cvtd.l */
+ {33,3,rr,S,S,0}, /* cvtl.s */
+ {33,4,rr,S,S,0}, /* cvtl.d */
+ {34,0,rr,A,A,0}, /* ldpa */
+ {8,0,nr,A,0,0}, /* shf */
+ {18,6,nr,A,0,0}, /* ld.h */
+ {18,7,nr,A,0,0}, /* ld.w */
+ {33,7,rr,S,S,0}, /* cvtl.w */
+ {28,8,rr,S,S,0}, /* cvtw.l */
+ {35,1,rr,S,S,0}, /* plc.t */
+ {36,0,rr,S,S,0}, /* tzc */
+ {37,6,rr,A,A,0}, /* eq.h */
+ {37,7,rr,A,A,0}, /* eq.w */
+ {37,6,nr,A,0,0}, /* eq.h */
+ {37,7,nr,A,0,0}, /* eq.w */
+ {37,5,rr,S,S,0}, /* eq.b */
+ {37,6,rr,S,S,0}, /* eq.h */
+ {37,7,rr,S,S,0}, /* eq.w */
+ {37,8,rr,S,S,0}, /* eq.l */
+ {38,6,rr,A,A,0}, /* leu.h */
+ {38,7,rr,A,A,0}, /* leu.w */
+ {38,6,nr,A,0,0}, /* leu.h */
+ {38,7,nr,A,0,0}, /* leu.w */
+ {38,5,rr,S,S,0}, /* leu.b */
+ {38,6,rr,S,S,0}, /* leu.h */
+ {38,7,rr,S,S,0}, /* leu.w */
+ {38,8,rr,S,S,0}, /* leu.l */
+ {39,6,rr,A,A,0}, /* ltu.h */
+ {39,7,rr,A,A,0}, /* ltu.w */
+ {39,6,nr,A,0,0}, /* ltu.h */
+ {39,7,nr,A,0,0}, /* ltu.w */
+ {39,5,rr,S,S,0}, /* ltu.b */
+ {39,6,rr,S,S,0}, /* ltu.h */
+ {39,7,rr,S,S,0}, /* ltu.w */
+ {39,8,rr,S,S,0}, /* ltu.l */
+ {40,6,rr,A,A,0}, /* le.h */
+ {40,7,rr,A,A,0}, /* le.w */
+ {40,6,nr,A,0,0}, /* le.h */
+ {40,7,nr,A,0,0}, /* le.w */
+ {40,5,rr,S,S,0}, /* le.b */
+ {40,6,rr,S,S,0}, /* le.h */
+ {40,7,rr,S,S,0}, /* le.w */
+ {40,8,rr,S,S,0}, /* le.l */
+ {41,6,rr,A,A,0}, /* lt.h */
+ {41,7,rr,A,A,0}, /* lt.w */
+ {41,6,nr,A,0,0}, /* lt.h */
+ {41,7,nr,A,0,0}, /* lt.w */
+ {41,5,rr,S,S,0}, /* lt.b */
+ {41,6,rr,S,S,0}, /* lt.h */
+ {41,7,rr,S,S,0}, /* lt.w */
+ {41,8,rr,S,S,0}, /* lt.l */
+ {9,7,rr,S,A,0}, /* add.w */
+ {8,0,rr,A,A,0}, /* shf */
+ {0,0,rr,A,A,0}, /* mov */
+ {0,0,rr,S,A,0}, /* mov */
+ {0,7,rr,S,S,0}, /* mov.w */
+ {8,0,rr,S,S,0}, /* shf */
+ {0,0,rr,S,S,0}, /* mov */
+ {0,0,rr,A,S,0}, /* mov */
+ {5,0,rr,A,A,0}, /* and */
+ {6,0,rr,A,A,0}, /* or */
+ {7,0,rr,A,A,0}, /* xor */
+ {42,0,rr,A,A,0}, /* not */
+ {5,0,rr,S,S,0}, /* and */
+ {6,0,rr,S,S,0}, /* or */
+ {7,0,rr,S,S,0}, /* xor */
+ {42,0,rr,S,S,0}, /* not */
+ {40,3,rr,S,S,0}, /* le.s */
+ {40,4,rr,S,S,0}, /* le.d */
+ {41,3,rr,S,S,0}, /* lt.s */
+ {41,4,rr,S,S,0}, /* lt.d */
+ {9,3,rr,S,S,0}, /* add.s */
+ {9,4,rr,S,S,0}, /* add.d */
+ {10,3,rr,S,S,0}, /* sub.s */
+ {10,4,rr,S,S,0}, /* sub.d */
+ {37,3,rr,S,S,0}, /* eq.s */
+ {37,4,rr,S,S,0}, /* eq.d */
+ {43,6,rr,A,A,0}, /* neg.h */
+ {43,7,rr,A,A,0}, /* neg.w */
+ {3,3,rr,S,S,0}, /* mul.s */
+ {3,4,rr,S,S,0}, /* mul.d */
+ {4,3,rr,S,S,0}, /* div.s */
+ {4,4,rr,S,S,0}, /* div.d */
+ {9,6,rr,A,A,0}, /* add.h */
+ {9,7,rr,A,A,0}, /* add.w */
+ {9,6,nr,A,0,0}, /* add.h */
+ {9,7,nr,A,0,0}, /* add.w */
+ {9,5,rr,S,S,0}, /* add.b */
+ {9,6,rr,S,S,0}, /* add.h */
+ {9,7,rr,S,S,0}, /* add.w */
+ {9,8,rr,S,S,0}, /* add.l */
+ {10,6,rr,A,A,0}, /* sub.h */
+ {10,7,rr,A,A,0}, /* sub.w */
+ {10,6,nr,A,0,0}, /* sub.h */
+ {10,7,nr,A,0,0}, /* sub.w */
+ {10,5,rr,S,S,0}, /* sub.b */
+ {10,6,rr,S,S,0}, /* sub.h */
+ {10,7,rr,S,S,0}, /* sub.w */
+ {10,8,rr,S,S,0}, /* sub.l */
+ {3,6,rr,A,A,0}, /* mul.h */
+ {3,7,rr,A,A,0}, /* mul.w */
+ {3,6,nr,A,0,0}, /* mul.h */
+ {3,7,nr,A,0,0}, /* mul.w */
+ {3,5,rr,S,S,0}, /* mul.b */
+ {3,6,rr,S,S,0}, /* mul.h */
+ {3,7,rr,S,S,0}, /* mul.w */
+ {3,8,rr,S,S,0}, /* mul.l */
+ {4,6,rr,A,A,0}, /* div.h */
+ {4,7,rr,A,A,0}, /* div.w */
+ {4,6,nr,A,0,0}, /* div.h */
+ {4,7,nr,A,0,0}, /* div.w */
+ {4,5,rr,S,S,0}, /* div.b */
+ {4,6,rr,S,S,0}, /* div.h */
+ {4,7,rr,S,S,0}, /* div.w */
+ {4,8,rr,S,S,0}, /* div.l */
+};
+
+CONST struct formstr format3[] = {
+ {32,3,rr,V,V,0}, /* cvtd.s */
+ {31,4,rr,V,V,0}, /* cvts.d */
+ {33,4,rr,V,V,0}, /* cvtl.d */
+ {32,8,rr,V,V,0}, /* cvtd.l */
+ {0,0,rrl,S,S,VM}, /* mov */
+ {0,0,rlr,S,VM,S}, /* mov */
+ {0,0,0,0,0,0},
+ {44,0,rr,S,S,0}, /* lop */
+ {36,0,rr,V,V,0}, /* tzc */
+ {44,0,rr,V,V,0}, /* lop */
+ {0,0,0,0,0,0},
+ {42,0,rr,V,V,0}, /* not */
+ {8,0,rr,S,V,0}, /* shf */
+ {35,1,rr,V,V,0}, /* plc.t */
+ {45,2,rr,V,V,0}, /* cprs.f */
+ {45,1,rr,V,V,0}, /* cprs.t */
+ {37,3,rr,V,V,0}, /* eq.s */
+ {37,4,rr,V,V,0}, /* eq.d */
+ {43,3,rr,V,V,0}, /* neg.s */
+ {43,4,rr,V,V,0}, /* neg.d */
+ {37,3,rr,S,V,0}, /* eq.s */
+ {37,4,rr,S,V,0}, /* eq.d */
+ {43,3,rr,S,S,0}, /* neg.s */
+ {43,4,rr,S,S,0}, /* neg.d */
+ {40,3,rr,V,V,0}, /* le.s */
+ {40,4,rr,V,V,0}, /* le.d */
+ {41,3,rr,V,V,0}, /* lt.s */
+ {41,4,rr,V,V,0}, /* lt.d */
+ {40,3,rr,S,V,0}, /* le.s */
+ {40,4,rr,S,V,0}, /* le.d */
+ {41,3,rr,S,V,0}, /* lt.s */
+ {41,4,rr,S,V,0}, /* lt.d */
+ {37,5,rr,V,V,0}, /* eq.b */
+ {37,6,rr,V,V,0}, /* eq.h */
+ {37,7,rr,V,V,0}, /* eq.w */
+ {37,8,rr,V,V,0}, /* eq.l */
+ {37,5,rr,S,V,0}, /* eq.b */
+ {37,6,rr,S,V,0}, /* eq.h */
+ {37,7,rr,S,V,0}, /* eq.w */
+ {37,8,rr,S,V,0}, /* eq.l */
+ {40,5,rr,V,V,0}, /* le.b */
+ {40,6,rr,V,V,0}, /* le.h */
+ {40,7,rr,V,V,0}, /* le.w */
+ {40,8,rr,V,V,0}, /* le.l */
+ {40,5,rr,S,V,0}, /* le.b */
+ {40,6,rr,S,V,0}, /* le.h */
+ {40,7,rr,S,V,0}, /* le.w */
+ {40,8,rr,S,V,0}, /* le.l */
+ {41,5,rr,V,V,0}, /* lt.b */
+ {41,6,rr,V,V,0}, /* lt.h */
+ {41,7,rr,V,V,0}, /* lt.w */
+ {41,8,rr,V,V,0}, /* lt.l */
+ {41,5,rr,S,V,0}, /* lt.b */
+ {41,6,rr,S,V,0}, /* lt.h */
+ {41,7,rr,S,V,0}, /* lt.w */
+ {41,8,rr,S,V,0}, /* lt.l */
+ {43,5,rr,V,V,0}, /* neg.b */
+ {43,6,rr,V,V,0}, /* neg.h */
+ {43,7,rr,V,V,0}, /* neg.w */
+ {43,8,rr,V,V,0}, /* neg.l */
+ {43,5,rr,S,S,0}, /* neg.b */
+ {43,6,rr,S,S,0}, /* neg.h */
+ {43,7,rr,S,S,0}, /* neg.w */
+ {43,8,rr,S,S,0}, /* neg.l */
+};
+
+CONST struct formstr format4[] = {
+ {46,0,nops,0,0,0}, /* nop */
+ {47,0,pcrel,0,0,0}, /* br */
+ {48,2,pcrel,0,0,0}, /* bri.f */
+ {48,1,pcrel,0,0,0}, /* bri.t */
+ {49,2,pcrel,0,0,0}, /* bra.f */
+ {49,1,pcrel,0,0,0}, /* bra.t */
+ {50,2,pcrel,0,0,0}, /* brs.f */
+ {50,1,pcrel,0,0,0}, /* brs.t */
+};
+
+CONST struct formstr format5[] = {
+ {51,5,rr,V,V,0}, /* ldvi.b */
+ {51,6,rr,V,V,0}, /* ldvi.h */
+ {51,7,rr,V,V,0}, /* ldvi.w */
+ {51,8,rr,V,V,0}, /* ldvi.l */
+ {28,3,rr,V,V,0}, /* cvtw.s */
+ {31,7,rr,V,V,0}, /* cvts.w */
+ {28,8,rr,V,V,0}, /* cvtw.l */
+ {33,7,rr,V,V,0}, /* cvtl.w */
+ {52,5,rxr,V,V,0}, /* stvi.b */
+ {52,6,rxr,V,V,0}, /* stvi.h */
+ {52,7,rxr,V,V,0}, /* stvi.w */
+ {52,8,rxr,V,V,0}, /* stvi.l */
+ {52,5,rxr,S,V,0}, /* stvi.b */
+ {52,6,rxr,S,V,0}, /* stvi.h */
+ {52,7,rxr,S,V,0}, /* stvi.w */
+ {52,8,rxr,S,V,0}, /* stvi.l */
+};
+
+CONST struct formstr format6[] = {
+ {53,0,r,A,0,0}, /* ldsdr */
+ {54,0,r,A,0,0}, /* ldkdr */
+ {55,3,r,S,0,0}, /* ln.s */
+ {55,4,r,S,0,0}, /* ln.d */
+ {56,0,nops,0,0,0}, /* patu */
+ {57,0,r,A,0,0}, /* pate */
+ {58,0,nops,0,0,0}, /* pich */
+ {59,0,nops,0,0,0}, /* plch */
+ {0,0,lr,PSW,A,0}, /* mov */
+ {0,0,rxl,A,PSW,0}, /* mov */
+ {0,0,lr,PC,A,0}, /* mov */
+ {60,0,r,S,0,0}, /* idle */
+ {0,0,lr,ITR,S,0}, /* mov */
+ {0,0,rxl,S,ITR,0}, /* mov */
+ {0,0,0,0,0,0},
+ {0,0,rxl,S,ITSR,0}, /* mov */
+ {61,0,nops,0,0,0}, /* rtnq */
+ {62,0,nops,0,0,0}, /* cfork */
+ {63,0,nops,0,0,0}, /* rtn */
+ {64,0,nops,0,0,0}, /* wfork */
+ {65,0,nops,0,0,0}, /* join */
+ {66,0,nops,0,0,0}, /* rtnc */
+ {67,3,r,S,0,0}, /* exp.s */
+ {67,4,r,S,0,0}, /* exp.d */
+ {68,3,r,S,0,0}, /* sin.s */
+ {68,4,r,S,0,0}, /* sin.d */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {69,3,r,S,0,0}, /* cos.s */
+ {69,4,r,S,0,0}, /* cos.d */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {70,7,r,A,0,0}, /* psh.w */
+ {0,0,0,0,0,0},
+ {71,7,r,A,0,0}, /* pop.w */
+ {0,0,0,0,0,0},
+ {70,7,r,S,0,0}, /* psh.w */
+ {70,8,r,S,0,0}, /* psh.l */
+ {71,7,r,S,0,0}, /* pop.w */
+ {71,8,r,S,0,0}, /* pop.l */
+ {72,0,nops,0,0,0}, /* eni */
+ {73,0,nops,0,0,0}, /* dsi */
+ {74,0,nops,0,0,0}, /* bkpt */
+ {75,0,nops,0,0,0}, /* msync */
+ {76,0,r,S,0,0}, /* mski */
+ {77,0,r,S,0,0}, /* xmti */
+ {0,0,rxl,S,VV,0}, /* mov */
+ {78,0,nops,0,0,0}, /* tstvv */
+ {0,0,lr,VS,A,0}, /* mov */
+ {0,0,rxl,A,VS,0}, /* mov */
+ {0,0,lr,VL,A,0}, /* mov */
+ {0,0,rxl,A,VL,0}, /* mov */
+ {0,7,lr,VS,S,0}, /* mov.w */
+ {0,7,rxl,S,VS,0}, /* mov.w */
+ {0,7,lr,VL,S,0}, /* mov.w */
+ {0,7,rxl,S,VL,0}, /* mov.w */
+ {79,0,r,A,0,0}, /* diag */
+ {80,0,nops,0,0,0}, /* pbkpt */
+ {81,3,r,S,0,0}, /* sqrt.s */
+ {81,4,r,S,0,0}, /* sqrt.d */
+ {82,0,nops,0,0,0}, /* casr */
+ {0,0,0,0,0,0},
+ {83,3,r,S,0,0}, /* atan.s */
+ {83,4,r,S,0,0}, /* atan.d */
+};
+
+CONST struct formstr format7[] = {
+ {84,5,r,V,0,0}, /* sum.b */
+ {84,6,r,V,0,0}, /* sum.h */
+ {84,7,r,V,0,0}, /* sum.w */
+ {84,8,r,V,0,0}, /* sum.l */
+ {85,0,r,V,0,0}, /* all */
+ {86,0,r,V,0,0}, /* any */
+ {87,0,r,V,0,0}, /* parity */
+ {0,0,0,0,0,0},
+ {88,5,r,V,0,0}, /* max.b */
+ {88,6,r,V,0,0}, /* max.h */
+ {88,7,r,V,0,0}, /* max.w */
+ {88,8,r,V,0,0}, /* max.l */
+ {89,5,r,V,0,0}, /* min.b */
+ {89,6,r,V,0,0}, /* min.h */
+ {89,7,r,V,0,0}, /* min.w */
+ {89,8,r,V,0,0}, /* min.l */
+ {84,3,r,V,0,0}, /* sum.s */
+ {84,4,r,V,0,0}, /* sum.d */
+ {90,3,r,V,0,0}, /* prod.s */
+ {90,4,r,V,0,0}, /* prod.d */
+ {88,3,r,V,0,0}, /* max.s */
+ {88,4,r,V,0,0}, /* max.d */
+ {89,3,r,V,0,0}, /* min.s */
+ {89,4,r,V,0,0}, /* min.d */
+ {90,5,r,V,0,0}, /* prod.b */
+ {90,6,r,V,0,0}, /* prod.h */
+ {90,7,r,V,0,0}, /* prod.w */
+ {90,8,r,V,0,0}, /* prod.l */
+ {35,2,lr,VM,S,0}, /* plc.f */
+ {35,1,lr,VM,S,0}, /* plc.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr formatx[] = {
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr format1a[] = {
+ {91,0,imr,A,0,0}, /* halt */
+ {92,0,a4,0,0,0}, /* sysc */
+ {18,6,imr,A,0,0}, /* ld.h */
+ {18,7,imr,A,0,0}, /* ld.w */
+ {5,0,imr,A,0,0}, /* and */
+ {6,0,imr,A,0,0}, /* or */
+ {7,0,imr,A,0,0}, /* xor */
+ {8,0,imr,A,0,0}, /* shf */
+ {9,6,imr,A,0,0}, /* add.h */
+ {9,7,imr,A,0,0}, /* add.w */
+ {10,6,imr,A,0,0}, /* sub.h */
+ {10,7,imr,A,0,0}, /* sub.w */
+ {3,6,imr,A,0,0}, /* mul.h */
+ {3,7,imr,A,0,0}, /* mul.w */
+ {4,6,imr,A,0,0}, /* div.h */
+ {4,7,imr,A,0,0}, /* div.w */
+ {18,7,iml,VL,0,0}, /* ld.w */
+ {18,7,iml,VS,0,0}, /* ld.w */
+ {0,0,0,0,0,0},
+ {8,7,imr,S,0,0}, /* shf.w */
+ {93,0,a5,0,0,0}, /* trap */
+ {0,0,0,0,0,0},
+ {37,6,imr,A,0,0}, /* eq.h */
+ {37,7,imr,A,0,0}, /* eq.w */
+ {38,6,imr,A,0,0}, /* leu.h */
+ {38,7,imr,A,0,0}, /* leu.w */
+ {39,6,imr,A,0,0}, /* ltu.h */
+ {39,7,imr,A,0,0}, /* ltu.w */
+ {40,6,imr,A,0,0}, /* le.h */
+ {40,7,imr,A,0,0}, /* le.w */
+ {41,6,imr,A,0,0}, /* lt.h */
+ {41,7,imr,A,0,0}, /* lt.w */
+};
+
+CONST struct formstr format1b[] = {
+ {18,4,imr,S,0,0}, /* ld.d */
+ {18,10,imr,S,0,0}, /* ld.u */
+ {18,8,imr,S,0,0}, /* ld.l */
+ {18,7,imr,S,0,0}, /* ld.w */
+ {5,0,imr,S,0,0}, /* and */
+ {6,0,imr,S,0,0}, /* or */
+ {7,0,imr,S,0,0}, /* xor */
+ {8,0,imr,S,0,0}, /* shf */
+ {9,6,imr,S,0,0}, /* add.h */
+ {9,7,imr,S,0,0}, /* add.w */
+ {10,6,imr,S,0,0}, /* sub.h */
+ {10,7,imr,S,0,0}, /* sub.w */
+ {3,6,imr,S,0,0}, /* mul.h */
+ {3,7,imr,S,0,0}, /* mul.w */
+ {4,6,imr,S,0,0}, /* div.h */
+ {4,7,imr,S,0,0}, /* div.w */
+ {9,3,imr,S,0,0}, /* add.s */
+ {10,3,imr,S,0,0}, /* sub.s */
+ {3,3,imr,S,0,0}, /* mul.s */
+ {4,3,imr,S,0,0}, /* div.s */
+ {40,3,imr,S,0,0}, /* le.s */
+ {41,3,imr,S,0,0}, /* lt.s */
+ {37,6,imr,S,0,0}, /* eq.h */
+ {37,7,imr,S,0,0}, /* eq.w */
+ {38,6,imr,S,0,0}, /* leu.h */
+ {38,7,imr,S,0,0}, /* leu.w */
+ {39,6,imr,S,0,0}, /* ltu.h */
+ {39,7,imr,S,0,0}, /* ltu.w */
+ {40,6,imr,S,0,0}, /* le.h */
+ {40,7,imr,S,0,0}, /* le.w */
+ {41,6,imr,S,0,0}, /* lt.h */
+ {41,7,imr,S,0,0}, /* lt.w */
+};
+
+CONST struct formstr e0_format0[] = {
+ {10,3,rrr,S,V,V}, /* sub.s */
+ {10,4,rrr,S,V,V}, /* sub.d */
+ {4,3,rrr,S,V,V}, /* div.s */
+ {4,4,rrr,S,V,V}, /* div.d */
+ {10,11,rrr,S,V,V}, /* sub.s.f */
+ {10,12,rrr,S,V,V}, /* sub.d.f */
+ {4,11,rrr,S,V,V}, /* div.s.f */
+ {4,12,rrr,S,V,V}, /* div.d.f */
+ {3,11,rrr,V,V,V}, /* mul.s.f */
+ {3,12,rrr,V,V,V}, /* mul.d.f */
+ {4,11,rrr,V,V,V}, /* div.s.f */
+ {4,12,rrr,V,V,V}, /* div.d.f */
+ {3,11,rrr,V,S,V}, /* mul.s.f */
+ {3,12,rrr,V,S,V}, /* mul.d.f */
+ {4,11,rrr,V,S,V}, /* div.s.f */
+ {4,12,rrr,V,S,V}, /* div.d.f */
+ {5,2,rrr,V,V,V}, /* and.f */
+ {6,2,rrr,V,V,V}, /* or.f */
+ {7,2,rrr,V,V,V}, /* xor.f */
+ {8,2,rrr,V,V,V}, /* shf.f */
+ {5,2,rrr,V,S,V}, /* and.f */
+ {6,2,rrr,V,S,V}, /* or.f */
+ {7,2,rrr,V,S,V}, /* xor.f */
+ {8,2,rrr,V,S,V}, /* shf.f */
+ {9,11,rrr,V,V,V}, /* add.s.f */
+ {9,12,rrr,V,V,V}, /* add.d.f */
+ {10,11,rrr,V,V,V}, /* sub.s.f */
+ {10,12,rrr,V,V,V}, /* sub.d.f */
+ {9,11,rrr,V,S,V}, /* add.s.f */
+ {9,12,rrr,V,S,V}, /* add.d.f */
+ {10,11,rrr,V,S,V}, /* sub.s.f */
+ {10,12,rrr,V,S,V}, /* sub.d.f */
+ {9,13,rrr,V,V,V}, /* add.b.f */
+ {9,14,rrr,V,V,V}, /* add.h.f */
+ {9,15,rrr,V,V,V}, /* add.w.f */
+ {9,16,rrr,V,V,V}, /* add.l.f */
+ {9,13,rrr,V,S,V}, /* add.b.f */
+ {9,14,rrr,V,S,V}, /* add.h.f */
+ {9,15,rrr,V,S,V}, /* add.w.f */
+ {9,16,rrr,V,S,V}, /* add.l.f */
+ {10,13,rrr,V,V,V}, /* sub.b.f */
+ {10,14,rrr,V,V,V}, /* sub.h.f */
+ {10,15,rrr,V,V,V}, /* sub.w.f */
+ {10,16,rrr,V,V,V}, /* sub.l.f */
+ {10,13,rrr,V,S,V}, /* sub.b.f */
+ {10,14,rrr,V,S,V}, /* sub.h.f */
+ {10,15,rrr,V,S,V}, /* sub.w.f */
+ {10,16,rrr,V,S,V}, /* sub.l.f */
+ {3,13,rrr,V,V,V}, /* mul.b.f */
+ {3,14,rrr,V,V,V}, /* mul.h.f */
+ {3,15,rrr,V,V,V}, /* mul.w.f */
+ {3,16,rrr,V,V,V}, /* mul.l.f */
+ {3,13,rrr,V,S,V}, /* mul.b.f */
+ {3,14,rrr,V,S,V}, /* mul.h.f */
+ {3,15,rrr,V,S,V}, /* mul.w.f */
+ {3,16,rrr,V,S,V}, /* mul.l.f */
+ {4,13,rrr,V,V,V}, /* div.b.f */
+ {4,14,rrr,V,V,V}, /* div.h.f */
+ {4,15,rrr,V,V,V}, /* div.w.f */
+ {4,16,rrr,V,V,V}, /* div.l.f */
+ {4,13,rrr,V,S,V}, /* div.b.f */
+ {4,14,rrr,V,S,V}, /* div.h.f */
+ {4,15,rrr,V,S,V}, /* div.w.f */
+ {4,16,rrr,V,S,V}, /* div.l.f */
+};
+
+CONST struct formstr e0_format1[] = {
+ {0,0,0,0,0,0},
+ {94,0,a3,0,0,0}, /* tst */
+ {95,0,a3,0,0,0}, /* lck */
+ {96,0,a3,0,0,0}, /* ulk */
+ {17,0,a1r,S,0,0}, /* ldea */
+ {97,0,a1r,A,0,0}, /* spawn */
+ {98,0,a1r,A,0,0}, /* ldcmr */
+ {99,0,a2r,A,0,0}, /* stcmr */
+ {100,0,a1r,A,0,0}, /* popr */
+ {101,0,a2r,A,0,0}, /* pshr */
+ {102,7,a1r,A,0,0}, /* rcvr.w */
+ {103,7,a2r,A,0,0}, /* matm.w */
+ {104,7,a2r,A,0,0}, /* sndr.w */
+ {104,8,a2r,S,0,0}, /* sndr.l */
+ {102,8,a1r,S,0,0}, /* rcvr.l */
+ {103,8,a2r,S,0,0}, /* matm.l */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {105,7,a2r,A,0,0}, /* putr.w */
+ {105,8,a2r,S,0,0}, /* putr.l */
+ {106,7,a1r,A,0,0}, /* getr.w */
+ {106,8,a1r,S,0,0}, /* getr.l */
+ {26,13,a2r,S,0,0}, /* ste.b.f */
+ {26,14,a2r,S,0,0}, /* ste.h.f */
+ {26,15,a2r,S,0,0}, /* ste.w.f */
+ {26,16,a2r,S,0,0}, /* ste.l.f */
+ {107,7,a2r,A,0,0}, /* matr.w */
+ {108,7,a2r,A,0,0}, /* mat.w */
+ {109,7,a1r,A,0,0}, /* get.w */
+ {110,7,a1r,A,0,0}, /* rcv.w */
+ {0,0,0,0,0,0},
+ {111,7,a1r,A,0,0}, /* inc.w */
+ {112,7,a2r,A,0,0}, /* put.w */
+ {113,7,a2r,A,0,0}, /* snd.w */
+ {107,8,a2r,S,0,0}, /* matr.l */
+ {108,8,a2r,S,0,0}, /* mat.l */
+ {109,8,a1r,S,0,0}, /* get.l */
+ {110,8,a1r,S,0,0}, /* rcv.l */
+ {0,0,0,0,0,0},
+ {111,8,a1r,S,0,0}, /* inc.l */
+ {112,8,a2r,S,0,0}, /* put.l */
+ {113,8,a2r,S,0,0}, /* snd.l */
+ {18,13,a1r,V,0,0}, /* ld.b.f */
+ {18,14,a1r,V,0,0}, /* ld.h.f */
+ {18,15,a1r,V,0,0}, /* ld.w.f */
+ {18,16,a1r,V,0,0}, /* ld.l.f */
+ {21,13,a2r,V,0,0}, /* st.b.f */
+ {21,14,a2r,V,0,0}, /* st.h.f */
+ {21,15,a2r,V,0,0}, /* st.w.f */
+ {21,16,a2r,V,0,0}, /* st.l.f */
+};
+
+CONST struct formstr e0_format2[] = {
+ {28,5,rr,V,V,0}, /* cvtw.b */
+ {28,6,rr,V,V,0}, /* cvtw.h */
+ {29,7,rr,V,V,0}, /* cvtb.w */
+ {30,7,rr,V,V,0}, /* cvth.w */
+ {28,13,rr,V,V,0}, /* cvtw.b.f */
+ {28,14,rr,V,V,0}, /* cvtw.h.f */
+ {29,15,rr,V,V,0}, /* cvtb.w.f */
+ {30,15,rr,V,V,0}, /* cvth.w.f */
+ {31,8,rr,V,V,0}, /* cvts.l */
+ {32,7,rr,V,V,0}, /* cvtd.w */
+ {33,3,rr,V,V,0}, /* cvtl.s */
+ {28,4,rr,V,V,0}, /* cvtw.d */
+ {31,16,rr,V,V,0}, /* cvts.l.f */
+ {32,15,rr,V,V,0}, /* cvtd.w.f */
+ {33,11,rr,V,V,0}, /* cvtl.s.f */
+ {28,12,rr,V,V,0}, /* cvtw.d.f */
+ {114,0,rr,S,S,0}, /* enal */
+ {8,7,rr,S,S,0}, /* shf.w */
+ {115,0,rr,S,S,0}, /* enag */
+ {0,0,0,0,0,0},
+ {28,4,rr,S,S,0}, /* cvtw.d */
+ {32,7,rr,S,S,0}, /* cvtd.w */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {116,3,rr,S,S,0}, /* frint.s */
+ {116,4,rr,S,S,0}, /* frint.d */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {116,3,rr,V,V,0}, /* frint.s */
+ {116,4,rr,V,V,0}, /* frint.d */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {116,11,rr,V,V,0}, /* frint.s.f */
+ {116,12,rr,V,V,0}, /* frint.d.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {81,3,rr,V,V,0}, /* sqrt.s */
+ {81,4,rr,V,V,0}, /* sqrt.d */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {81,11,rr,V,V,0}, /* sqrt.s.f */
+ {81,12,rr,V,V,0}, /* sqrt.d.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e0_format3[] = {
+ {32,11,rr,V,V,0}, /* cvtd.s.f */
+ {31,12,rr,V,V,0}, /* cvts.d.f */
+ {33,12,rr,V,V,0}, /* cvtl.d.f */
+ {32,16,rr,V,V,0}, /* cvtd.l.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {36,2,rr,V,V,0}, /* tzc.f */
+ {44,2,rr,V,V,0}, /* lop.f */
+ {117,2,rr,V,V,0}, /* xpnd.f */
+ {42,2,rr,V,V,0}, /* not.f */
+ {8,2,rr,S,V,0}, /* shf.f */
+ {35,17,rr,V,V,0}, /* plc.t.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {37,11,rr,V,V,0}, /* eq.s.f */
+ {37,12,rr,V,V,0}, /* eq.d.f */
+ {43,11,rr,V,V,0}, /* neg.s.f */
+ {43,12,rr,V,V,0}, /* neg.d.f */
+ {37,11,rr,S,V,0}, /* eq.s.f */
+ {37,12,rr,S,V,0}, /* eq.d.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {40,11,rr,V,V,0}, /* le.s.f */
+ {40,12,rr,V,V,0}, /* le.d.f */
+ {41,11,rr,V,V,0}, /* lt.s.f */
+ {41,12,rr,V,V,0}, /* lt.d.f */
+ {40,11,rr,S,V,0}, /* le.s.f */
+ {40,12,rr,S,V,0}, /* le.d.f */
+ {41,11,rr,S,V,0}, /* lt.s.f */
+ {41,12,rr,S,V,0}, /* lt.d.f */
+ {37,13,rr,V,V,0}, /* eq.b.f */
+ {37,14,rr,V,V,0}, /* eq.h.f */
+ {37,15,rr,V,V,0}, /* eq.w.f */
+ {37,16,rr,V,V,0}, /* eq.l.f */
+ {37,13,rr,S,V,0}, /* eq.b.f */
+ {37,14,rr,S,V,0}, /* eq.h.f */
+ {37,15,rr,S,V,0}, /* eq.w.f */
+ {37,16,rr,S,V,0}, /* eq.l.f */
+ {40,13,rr,V,V,0}, /* le.b.f */
+ {40,14,rr,V,V,0}, /* le.h.f */
+ {40,15,rr,V,V,0}, /* le.w.f */
+ {40,16,rr,V,V,0}, /* le.l.f */
+ {40,13,rr,S,V,0}, /* le.b.f */
+ {40,14,rr,S,V,0}, /* le.h.f */
+ {40,15,rr,S,V,0}, /* le.w.f */
+ {40,16,rr,S,V,0}, /* le.l.f */
+ {41,13,rr,V,V,0}, /* lt.b.f */
+ {41,14,rr,V,V,0}, /* lt.h.f */
+ {41,15,rr,V,V,0}, /* lt.w.f */
+ {41,16,rr,V,V,0}, /* lt.l.f */
+ {41,13,rr,S,V,0}, /* lt.b.f */
+ {41,14,rr,S,V,0}, /* lt.h.f */
+ {41,15,rr,S,V,0}, /* lt.w.f */
+ {41,16,rr,S,V,0}, /* lt.l.f */
+ {43,13,rr,V,V,0}, /* neg.b.f */
+ {43,14,rr,V,V,0}, /* neg.h.f */
+ {43,15,rr,V,V,0}, /* neg.w.f */
+ {43,16,rr,V,V,0}, /* neg.l.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e0_format4[] = {
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e0_format5[] = {
+ {51,13,rr,V,V,0}, /* ldvi.b.f */
+ {51,14,rr,V,V,0}, /* ldvi.h.f */
+ {51,15,rr,V,V,0}, /* ldvi.w.f */
+ {51,16,rr,V,V,0}, /* ldvi.l.f */
+ {28,11,rr,V,V,0}, /* cvtw.s.f */
+ {31,15,rr,V,V,0}, /* cvts.w.f */
+ {28,16,rr,V,V,0}, /* cvtw.l.f */
+ {33,15,rr,V,V,0}, /* cvtl.w.f */
+ {52,13,rxr,V,V,0}, /* stvi.b.f */
+ {52,14,rxr,V,V,0}, /* stvi.h.f */
+ {52,15,rxr,V,V,0}, /* stvi.w.f */
+ {52,16,rxr,V,V,0}, /* stvi.l.f */
+ {52,13,rxr,S,V,0}, /* stvi.b.f */
+ {52,14,rxr,S,V,0}, /* stvi.h.f */
+ {52,15,rxr,S,V,0}, /* stvi.w.f */
+ {52,16,rxr,S,V,0}, /* stvi.l.f */
+};
+
+CONST struct formstr e0_format6[] = {
+ {0,0,rxl,S,CIR,0}, /* mov */
+ {0,0,lr,CIR,S,0}, /* mov */
+ {0,0,lr,TOC,S,0}, /* mov */
+ {0,0,lr,CPUID,S,0}, /* mov */
+ {0,0,rxl,S,TTR,0}, /* mov */
+ {0,0,lr,TTR,S,0}, /* mov */
+ {118,0,nops,0,0,0}, /* ctrsl */
+ {119,0,nops,0,0,0}, /* ctrsg */
+ {0,0,rxl,S,VMU,0}, /* mov */
+ {0,0,lr,VMU,S,0}, /* mov */
+ {0,0,rxl,S,VML,0}, /* mov */
+ {0,0,lr,VML,S,0}, /* mov */
+ {0,0,rxl,S,ICR,0}, /* mov */
+ {0,0,lr,ICR,S,0}, /* mov */
+ {0,0,rxl,S,TCPU,0}, /* mov */
+ {0,0,lr,TCPU,S,0}, /* mov */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {120,0,nops,0,0,0}, /* stop */
+ {0,0,0,0,0,0},
+ {0,0,rxl,S,TID,0}, /* mov */
+ {0,0,lr,TID,S,0}, /* mov */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e0_format7[] = {
+ {84,13,r,V,0,0}, /* sum.b.f */
+ {84,14,r,V,0,0}, /* sum.h.f */
+ {84,15,r,V,0,0}, /* sum.w.f */
+ {84,16,r,V,0,0}, /* sum.l.f */
+ {85,2,r,V,0,0}, /* all.f */
+ {86,2,r,V,0,0}, /* any.f */
+ {87,2,r,V,0,0}, /* parity.f */
+ {0,0,0,0,0,0},
+ {88,13,r,V,0,0}, /* max.b.f */
+ {88,14,r,V,0,0}, /* max.h.f */
+ {88,15,r,V,0,0}, /* max.w.f */
+ {88,16,r,V,0,0}, /* max.l.f */
+ {89,13,r,V,0,0}, /* min.b.f */
+ {89,14,r,V,0,0}, /* min.h.f */
+ {89,15,r,V,0,0}, /* min.w.f */
+ {89,16,r,V,0,0}, /* min.l.f */
+ {84,11,r,V,0,0}, /* sum.s.f */
+ {84,12,r,V,0,0}, /* sum.d.f */
+ {90,11,r,V,0,0}, /* prod.s.f */
+ {90,12,r,V,0,0}, /* prod.d.f */
+ {88,11,r,V,0,0}, /* max.s.f */
+ {88,12,r,V,0,0}, /* max.d.f */
+ {89,11,r,V,0,0}, /* min.s.f */
+ {89,12,r,V,0,0}, /* min.d.f */
+ {90,13,r,V,0,0}, /* prod.b.f */
+ {90,14,r,V,0,0}, /* prod.h.f */
+ {90,15,r,V,0,0}, /* prod.w.f */
+ {90,16,r,V,0,0}, /* prod.l.f */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e1_format0[] = {
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {10,18,rrr,S,V,V}, /* sub.s.t */
+ {10,19,rrr,S,V,V}, /* sub.d.t */
+ {4,18,rrr,S,V,V}, /* div.s.t */
+ {4,19,rrr,S,V,V}, /* div.d.t */
+ {3,18,rrr,V,V,V}, /* mul.s.t */
+ {3,19,rrr,V,V,V}, /* mul.d.t */
+ {4,18,rrr,V,V,V}, /* div.s.t */
+ {4,19,rrr,V,V,V}, /* div.d.t */
+ {3,18,rrr,V,S,V}, /* mul.s.t */
+ {3,19,rrr,V,S,V}, /* mul.d.t */
+ {4,18,rrr,V,S,V}, /* div.s.t */
+ {4,19,rrr,V,S,V}, /* div.d.t */
+ {5,1,rrr,V,V,V}, /* and.t */
+ {6,1,rrr,V,V,V}, /* or.t */
+ {7,1,rrr,V,V,V}, /* xor.t */
+ {8,1,rrr,V,V,V}, /* shf.t */
+ {5,1,rrr,V,S,V}, /* and.t */
+ {6,1,rrr,V,S,V}, /* or.t */
+ {7,1,rrr,V,S,V}, /* xor.t */
+ {8,1,rrr,V,S,V}, /* shf.t */
+ {9,18,rrr,V,V,V}, /* add.s.t */
+ {9,19,rrr,V,V,V}, /* add.d.t */
+ {10,18,rrr,V,V,V}, /* sub.s.t */
+ {10,19,rrr,V,V,V}, /* sub.d.t */
+ {9,18,rrr,V,S,V}, /* add.s.t */
+ {9,19,rrr,V,S,V}, /* add.d.t */
+ {10,18,rrr,V,S,V}, /* sub.s.t */
+ {10,19,rrr,V,S,V}, /* sub.d.t */
+ {9,20,rrr,V,V,V}, /* add.b.t */
+ {9,21,rrr,V,V,V}, /* add.h.t */
+ {9,22,rrr,V,V,V}, /* add.w.t */
+ {9,23,rrr,V,V,V}, /* add.l.t */
+ {9,20,rrr,V,S,V}, /* add.b.t */
+ {9,21,rrr,V,S,V}, /* add.h.t */
+ {9,22,rrr,V,S,V}, /* add.w.t */
+ {9,23,rrr,V,S,V}, /* add.l.t */
+ {10,20,rrr,V,V,V}, /* sub.b.t */
+ {10,21,rrr,V,V,V}, /* sub.h.t */
+ {10,22,rrr,V,V,V}, /* sub.w.t */
+ {10,23,rrr,V,V,V}, /* sub.l.t */
+ {10,20,rrr,V,S,V}, /* sub.b.t */
+ {10,21,rrr,V,S,V}, /* sub.h.t */
+ {10,22,rrr,V,S,V}, /* sub.w.t */
+ {10,23,rrr,V,S,V}, /* sub.l.t */
+ {3,20,rrr,V,V,V}, /* mul.b.t */
+ {3,21,rrr,V,V,V}, /* mul.h.t */
+ {3,22,rrr,V,V,V}, /* mul.w.t */
+ {3,23,rrr,V,V,V}, /* mul.l.t */
+ {3,20,rrr,V,S,V}, /* mul.b.t */
+ {3,21,rrr,V,S,V}, /* mul.h.t */
+ {3,22,rrr,V,S,V}, /* mul.w.t */
+ {3,23,rrr,V,S,V}, /* mul.l.t */
+ {4,20,rrr,V,V,V}, /* div.b.t */
+ {4,21,rrr,V,V,V}, /* div.h.t */
+ {4,22,rrr,V,V,V}, /* div.w.t */
+ {4,23,rrr,V,V,V}, /* div.l.t */
+ {4,20,rrr,V,S,V}, /* div.b.t */
+ {4,21,rrr,V,S,V}, /* div.h.t */
+ {4,22,rrr,V,S,V}, /* div.w.t */
+ {4,23,rrr,V,S,V}, /* div.l.t */
+};
+
+CONST struct formstr e1_format1[] = {
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {26,20,a2r,S,0,0}, /* ste.b.t */
+ {26,21,a2r,S,0,0}, /* ste.h.t */
+ {26,22,a2r,S,0,0}, /* ste.w.t */
+ {26,23,a2r,S,0,0}, /* ste.l.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {18,20,a1r,V,0,0}, /* ld.b.t */
+ {18,21,a1r,V,0,0}, /* ld.h.t */
+ {18,22,a1r,V,0,0}, /* ld.w.t */
+ {18,23,a1r,V,0,0}, /* ld.l.t */
+ {21,20,a2r,V,0,0}, /* st.b.t */
+ {21,21,a2r,V,0,0}, /* st.h.t */
+ {21,22,a2r,V,0,0}, /* st.w.t */
+ {21,23,a2r,V,0,0}, /* st.l.t */
+};
+
+CONST struct formstr e1_format2[] = {
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {28,20,rr,V,V,0}, /* cvtw.b.t */
+ {28,21,rr,V,V,0}, /* cvtw.h.t */
+ {29,22,rr,V,V,0}, /* cvtb.w.t */
+ {30,22,rr,V,V,0}, /* cvth.w.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {31,23,rr,V,V,0}, /* cvts.l.t */
+ {32,22,rr,V,V,0}, /* cvtd.w.t */
+ {33,18,rr,V,V,0}, /* cvtl.s.t */
+ {28,19,rr,V,V,0}, /* cvtw.d.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {116,18,rr,V,V,0}, /* frint.s.t */
+ {116,19,rr,V,V,0}, /* frint.d.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {81,18,rr,V,V,0}, /* sqrt.s.t */
+ {81,19,rr,V,V,0}, /* sqrt.d.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e1_format3[] = {
+ {32,18,rr,V,V,0}, /* cvtd.s.t */
+ {31,19,rr,V,V,0}, /* cvts.d.t */
+ {33,19,rr,V,V,0}, /* cvtl.d.t */
+ {32,23,rr,V,V,0}, /* cvtd.l.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {36,1,rr,V,V,0}, /* tzc.t */
+ {44,1,rr,V,V,0}, /* lop.t */
+ {117,1,rr,V,V,0}, /* xpnd.t */
+ {42,1,rr,V,V,0}, /* not.t */
+ {8,1,rr,S,V,0}, /* shf.t */
+ {35,24,rr,V,V,0}, /* plc.t.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {37,18,rr,V,V,0}, /* eq.s.t */
+ {37,19,rr,V,V,0}, /* eq.d.t */
+ {43,18,rr,V,V,0}, /* neg.s.t */
+ {43,19,rr,V,V,0}, /* neg.d.t */
+ {37,18,rr,S,V,0}, /* eq.s.t */
+ {37,19,rr,S,V,0}, /* eq.d.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {40,18,rr,V,V,0}, /* le.s.t */
+ {40,19,rr,V,V,0}, /* le.d.t */
+ {41,18,rr,V,V,0}, /* lt.s.t */
+ {41,19,rr,V,V,0}, /* lt.d.t */
+ {40,18,rr,S,V,0}, /* le.s.t */
+ {40,19,rr,S,V,0}, /* le.d.t */
+ {41,18,rr,S,V,0}, /* lt.s.t */
+ {41,19,rr,S,V,0}, /* lt.d.t */
+ {37,20,rr,V,V,0}, /* eq.b.t */
+ {37,21,rr,V,V,0}, /* eq.h.t */
+ {37,22,rr,V,V,0}, /* eq.w.t */
+ {37,23,rr,V,V,0}, /* eq.l.t */
+ {37,20,rr,S,V,0}, /* eq.b.t */
+ {37,21,rr,S,V,0}, /* eq.h.t */
+ {37,22,rr,S,V,0}, /* eq.w.t */
+ {37,23,rr,S,V,0}, /* eq.l.t */
+ {40,20,rr,V,V,0}, /* le.b.t */
+ {40,21,rr,V,V,0}, /* le.h.t */
+ {40,22,rr,V,V,0}, /* le.w.t */
+ {40,23,rr,V,V,0}, /* le.l.t */
+ {40,20,rr,S,V,0}, /* le.b.t */
+ {40,21,rr,S,V,0}, /* le.h.t */
+ {40,22,rr,S,V,0}, /* le.w.t */
+ {40,23,rr,S,V,0}, /* le.l.t */
+ {41,20,rr,V,V,0}, /* lt.b.t */
+ {41,21,rr,V,V,0}, /* lt.h.t */
+ {41,22,rr,V,V,0}, /* lt.w.t */
+ {41,23,rr,V,V,0}, /* lt.l.t */
+ {41,20,rr,S,V,0}, /* lt.b.t */
+ {41,21,rr,S,V,0}, /* lt.h.t */
+ {41,22,rr,S,V,0}, /* lt.w.t */
+ {41,23,rr,S,V,0}, /* lt.l.t */
+ {43,20,rr,V,V,0}, /* neg.b.t */
+ {43,21,rr,V,V,0}, /* neg.h.t */
+ {43,22,rr,V,V,0}, /* neg.w.t */
+ {43,23,rr,V,V,0}, /* neg.l.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e1_format4[] = {
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e1_format5[] = {
+ {51,20,rr,V,V,0}, /* ldvi.b.t */
+ {51,21,rr,V,V,0}, /* ldvi.h.t */
+ {51,22,rr,V,V,0}, /* ldvi.w.t */
+ {51,23,rr,V,V,0}, /* ldvi.l.t */
+ {28,18,rr,V,V,0}, /* cvtw.s.t */
+ {31,22,rr,V,V,0}, /* cvts.w.t */
+ {28,23,rr,V,V,0}, /* cvtw.l.t */
+ {33,22,rr,V,V,0}, /* cvtl.w.t */
+ {52,20,rxr,V,V,0}, /* stvi.b.t */
+ {52,21,rxr,V,V,0}, /* stvi.h.t */
+ {52,22,rxr,V,V,0}, /* stvi.w.t */
+ {52,23,rxr,V,V,0}, /* stvi.l.t */
+ {52,20,rxr,S,V,0}, /* stvi.b.t */
+ {52,21,rxr,S,V,0}, /* stvi.h.t */
+ {52,22,rxr,S,V,0}, /* stvi.w.t */
+ {52,23,rxr,S,V,0}, /* stvi.l.t */
+};
+
+CONST struct formstr e1_format6[] = {
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+CONST struct formstr e1_format7[] = {
+ {84,20,r,V,0,0}, /* sum.b.t */
+ {84,21,r,V,0,0}, /* sum.h.t */
+ {84,22,r,V,0,0}, /* sum.w.t */
+ {84,23,r,V,0,0}, /* sum.l.t */
+ {85,1,r,V,0,0}, /* all.t */
+ {86,1,r,V,0,0}, /* any.t */
+ {87,1,r,V,0,0}, /* parity.t */
+ {0,0,0,0,0,0},
+ {88,20,r,V,0,0}, /* max.b.t */
+ {88,21,r,V,0,0}, /* max.h.t */
+ {88,22,r,V,0,0}, /* max.w.t */
+ {88,23,r,V,0,0}, /* max.l.t */
+ {89,20,r,V,0,0}, /* min.b.t */
+ {89,21,r,V,0,0}, /* min.h.t */
+ {89,22,r,V,0,0}, /* min.w.t */
+ {89,23,r,V,0,0}, /* min.l.t */
+ {84,18,r,V,0,0}, /* sum.s.t */
+ {84,19,r,V,0,0}, /* sum.d.t */
+ {90,18,r,V,0,0}, /* prod.s.t */
+ {90,19,r,V,0,0}, /* prod.d.t */
+ {88,18,r,V,0,0}, /* max.s.t */
+ {88,19,r,V,0,0}, /* max.d.t */
+ {89,18,r,V,0,0}, /* min.s.t */
+ {89,19,r,V,0,0}, /* min.d.t */
+ {90,20,r,V,0,0}, /* prod.b.t */
+ {90,21,r,V,0,0}, /* prod.h.t */
+ {90,22,r,V,0,0}, /* prod.w.t */
+ {90,23,r,V,0,0}, /* prod.l.t */
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+ {0,0,0,0,0,0},
+};
+
+char *lop[] = {
+ "mov", /* 0 */
+ "merg", /* 1 */
+ "mask", /* 2 */
+ "mul", /* 3 */
+ "div", /* 4 */
+ "and", /* 5 */
+ "or", /* 6 */
+ "xor", /* 7 */
+ "shf", /* 8 */
+ "add", /* 9 */
+ "sub", /* 10 */
+ "exit", /* 11 */
+ "jmp", /* 12 */
+ "jmpi", /* 13 */
+ "jmpa", /* 14 */
+ "jmps", /* 15 */
+ "tac", /* 16 */
+ "ldea", /* 17 */
+ "ld", /* 18 */
+ "tas", /* 19 */
+ "pshea", /* 20 */
+ "st", /* 21 */
+ "call", /* 22 */
+ "calls", /* 23 */
+ "callq", /* 24 */
+ "pfork", /* 25 */
+ "ste", /* 26 */
+ "incr", /* 27 */
+ "cvtw", /* 28 */
+ "cvtb", /* 29 */
+ "cvth", /* 30 */
+ "cvts", /* 31 */
+ "cvtd", /* 32 */
+ "cvtl", /* 33 */
+ "ldpa", /* 34 */
+ "plc", /* 35 */
+ "tzc", /* 36 */
+ "eq", /* 37 */
+ "leu", /* 38 */
+ "ltu", /* 39 */
+ "le", /* 40 */
+ "lt", /* 41 */
+ "not", /* 42 */
+ "neg", /* 43 */
+ "lop", /* 44 */
+ "cprs", /* 45 */
+ "nop", /* 46 */
+ "br", /* 47 */
+ "bri", /* 48 */
+ "bra", /* 49 */
+ "brs", /* 50 */
+ "ldvi", /* 51 */
+ "stvi", /* 52 */
+ "ldsdr", /* 53 */
+ "ldkdr", /* 54 */
+ "ln", /* 55 */
+ "patu", /* 56 */
+ "pate", /* 57 */
+ "pich", /* 58 */
+ "plch", /* 59 */
+ "idle", /* 60 */
+ "rtnq", /* 61 */
+ "cfork", /* 62 */
+ "rtn", /* 63 */
+ "wfork", /* 64 */
+ "join", /* 65 */
+ "rtnc", /* 66 */
+ "exp", /* 67 */
+ "sin", /* 68 */
+ "cos", /* 69 */
+ "psh", /* 70 */
+ "pop", /* 71 */
+ "eni", /* 72 */
+ "dsi", /* 73 */
+ "bkpt", /* 74 */
+ "msync", /* 75 */
+ "mski", /* 76 */
+ "xmti", /* 77 */
+ "tstvv", /* 78 */
+ "diag", /* 79 */
+ "pbkpt", /* 80 */
+ "sqrt", /* 81 */
+ "casr", /* 82 */
+ "atan", /* 83 */
+ "sum", /* 84 */
+ "all", /* 85 */
+ "any", /* 86 */
+ "parity", /* 87 */
+ "max", /* 88 */
+ "min", /* 89 */
+ "prod", /* 90 */
+ "halt", /* 91 */
+ "sysc", /* 92 */
+ "trap", /* 93 */
+ "tst", /* 94 */
+ "lck", /* 95 */
+ "ulk", /* 96 */
+ "spawn", /* 97 */
+ "ldcmr", /* 98 */
+ "stcmr", /* 99 */
+ "popr", /* 100 */
+ "pshr", /* 101 */
+ "rcvr", /* 102 */
+ "matm", /* 103 */
+ "sndr", /* 104 */
+ "putr", /* 105 */
+ "getr", /* 106 */
+ "matr", /* 107 */
+ "mat", /* 108 */
+ "get", /* 109 */
+ "rcv", /* 110 */
+ "inc", /* 111 */
+ "put", /* 112 */
+ "snd", /* 113 */
+ "enal", /* 114 */
+ "enag", /* 115 */
+ "frint", /* 116 */
+ "xpnd", /* 117 */
+ "ctrsl", /* 118 */
+ "ctrsg", /* 119 */
+ "stop", /* 120 */
+};
+
+char *rop[] = {
+ "", /* 0 */
+ ".t", /* 1 */
+ ".f", /* 2 */
+ ".s", /* 3 */
+ ".d", /* 4 */
+ ".b", /* 5 */
+ ".h", /* 6 */
+ ".w", /* 7 */
+ ".l", /* 8 */
+ ".x", /* 9 */
+ ".u", /* 10 */
+ ".s.f", /* 11 */
+ ".d.f", /* 12 */
+ ".b.f", /* 13 */
+ ".h.f", /* 14 */
+ ".w.f", /* 15 */
+ ".l.f", /* 16 */
+ ".t.f", /* 17 */
+ ".s.t", /* 18 */
+ ".d.t", /* 19 */
+ ".b.t", /* 20 */
+ ".h.t", /* 21 */
+ ".w.t", /* 22 */
+ ".l.t", /* 23 */
+ ".t.t", /* 24 */
+};
diff --git a/include/opcode/d10v.h b/include/opcode/d10v.h
new file mode 100644
index 00000000000..4b74c9862d4
--- /dev/null
+++ b/include/opcode/d10v.h
@@ -0,0 +1,194 @@
+/* d10v.h -- Header file for D10V opcode table
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Martin Hunt (hunt@cygnus.com), Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef D10V_H
+#define D10V_H
+
+/* Format Specifier */
+#define FM00 0
+#define FM01 0x40000000
+#define FM10 0x80000000
+#define FM11 0xC0000000
+
+#define NOP 0x5e00
+#define OPCODE_DIVS 0x14002800
+
+/* The opcode table is an array of struct d10v_opcode. */
+
+struct d10v_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* the opcode format */
+ int format;
+
+ /* These numbers were picked so we can do if( i & SHORT_OPCODE) */
+#define SHORT_OPCODE 1
+#define LONG_OPCODE 8
+#define SHORT_2 1 /* short with 2 operands */
+#define SHORT_B 3 /* short with 8-bit branch */
+#define LONG_B 8 /* long with 16-bit branch */
+#define LONG_L 10 /* long with 3 operands */
+#define LONG_R 12 /* reserved */
+
+ /* just a placeholder for variable-length instructions */
+ /* for example, "bra" will be a fake for "bra.s" and bra.l" */
+ /* which will immediately follow in the opcode table. */
+#define OPCODE_FAKE 32
+
+ /* the number of cycles */
+ int cycles;
+
+ /* the execution unit(s) used */
+ int unit;
+#define EITHER 0
+#define IU 1
+#define MU 2
+#define BOTH 3
+
+ /* execution type; parallel or sequential */
+ /* this field is used to decide if two instructions */
+ /* can be executed in parallel */
+ int exec_type;
+#define PARONLY 1 /* parallel only */
+#define SEQ 2 /* must be sequential */
+#define PAR 4 /* may be parallel */
+#define BRANCH_LINK 8 /* subroutine call. must be aligned */
+#define RMEM 16 /* reads memory */
+#define WMEM 32 /* writes memory */
+#define RF0 64 /* reads f0 */
+#define WF0 128 /* modifies f0 */
+#define WCAR 256 /* write Carry */
+#define BRANCH 512 /* branch, no link */
+
+ /* the opcode */
+ long opcode;
+
+ /* mask. if( (i & mask) == opcode ) then match */
+ long mask;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ unsigned char operands[6];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+ in the order in which the disassembler should consider
+ instructions. */
+extern const struct d10v_opcode d10v_opcodes[];
+extern const int d10v_num_opcodes;
+
+/* The operands table is an array of struct d10v_operand. */
+struct d10v_operand
+{
+ /* The number of bits in the operand. */
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+ int shift;
+
+ /* One bit syntax flags. */
+ int flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the d10v_opcodes table. */
+
+extern const struct d10v_operand d10v_operands[];
+
+/* Values defined for the flags field of a struct d10v_operand. */
+
+/* the operand must be an even number */
+#define OPERAND_EVEN (1)
+
+/* the operand must be an odd number */
+#define OPERAND_ODD (2)
+
+/* this is the destination register; it will be modified */
+/* this is used by the optimizer */
+#define OPERAND_DEST (4)
+
+/* number or symbol */
+#define OPERAND_NUM (8)
+
+/* address or label */
+#define OPERAND_ADDR (0x10)
+
+/* register */
+#define OPERAND_REG (0x20)
+
+/* postincrement + */
+#define OPERAND_PLUS (0x40)
+
+/* postdecrement - */
+#define OPERAND_MINUS (0x80)
+
+/* @ */
+#define OPERAND_ATSIGN (0x100)
+
+/* @( */
+#define OPERAND_ATPAR (0x200)
+
+/* accumulator 0 */
+#define OPERAND_ACC0 (0x400)
+
+/* accumulator 1 */
+#define OPERAND_ACC1 (0x800)
+
+/* f0 / f1 flag register */
+#define OPERAND_FFLAG (0x1000)
+
+/* c flag register */
+#define OPERAND_CFLAG (0x2000)
+
+/* control register */
+#define OPERAND_CONTROL (0x4000)
+
+/* predecrement mode '@-sp' */
+#define OPERAND_ATMINUS (0x8000)
+
+/* signed number */
+#define OPERAND_SIGNED (0x10000)
+
+/* special accumulator shifts need a 4-bit number */
+/* 1 <= x <= 16 */
+#define OPERAND_SHIFT (0x20000)
+
+/* general purpose register */
+#define OPERAND_GPR (0x40000)
+
+/* Structure to hold information about predefined registers. */
+struct pd_reg
+{
+ char *name; /* name to recognize */
+ char *pname; /* name to print for this register */
+ int value;
+};
+
+extern const struct pd_reg d10v_predefined_registers[];
+int d10v_reg_name_cnt();
+
+/* an expressionS only has one register type, so we fake it */
+/* by setting high bits to indicate type */
+#define REGISTER_MASK 0xFF
+
+#endif /* D10V_H */
diff --git a/include/opcode/d30v.h b/include/opcode/d30v.h
new file mode 100644
index 00000000000..b828dab32ae
--- /dev/null
+++ b/include/opcode/d30v.h
@@ -0,0 +1,273 @@
+/* d30v.h -- Header file for D30V opcode table
+ Copyright 1997 Free Software Foundation, Inc.
+ Written by Martin Hunt (hunt@cygnus.com), Cygnus Solutions
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef D30V_H
+#define D30V_H
+
+#define NOP 0x00F00000
+
+/* Structure to hold information about predefined registers. */
+struct pd_reg
+{
+ char *name; /* name to recognize */
+ char *pname; /* name to print for this register */
+ int value;
+};
+
+extern const struct pd_reg pre_defined_registers[];
+int reg_name_cnt();
+
+/* the number of control registers */
+#define MAX_CONTROL_REG 64
+
+/* define the format specifiers */
+#define FM00 0
+#define FM01 0x80000000
+#define FM10 0x8000000000000000LL
+#define FM11 0x8000000080000000LL
+
+/* define the opcode classes */
+#define BRA 0
+#define LOGIC 1
+#define IMEM 2
+#define IALU1 4
+#define IALU2 5
+
+/* define the execution condition codes */
+#define ECC_AL 0 /* ALways (default) */
+#define ECC_TX 1 /* F0=True, F1=Don't care */
+#define ECC_FX 2 /* F0=False, F1=Don't care */
+#define ECC_XT 3 /* F0=Don't care, F1=True */
+#define ECC_XF 4 /* F0=Don't care, F1=False */
+#define ECC_TT 5 /* F0=True, F1=True */
+#define ECC_TF 6 /* F0=True, F1=False */
+#define ECC_RESERVED 7 /* reserved */
+#define ECC_MAX ECC_RESERVED
+
+extern const char *d30v_ecc_names[];
+
+/* condition code table for CMP and CMPU */
+extern const char *d30v_cc_names[];
+
+/* The opcode table is an array of struct d30v_opcode. */
+struct d30v_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* the opcode */
+ int op1; /* first part, "IALU1" for example */
+ int op2; /* the rest of the opcode */
+
+ /* opcode format(s). These numbers correspond to entries */
+ /* in the d30v_format_table */
+ unsigned char format[4];
+
+#define SHORT_M 1
+#define SHORT_M2 5 /* for ld2w and st2w */
+#define SHORT_A 9
+#define SHORT_B1 11
+#define SHORT_B2 12
+#define SHORT_B3 13
+#define SHORT_B3b 15
+#define SHORT_D1 17
+#define SHORT_D2 19
+#define SHORT_D2B 21
+#define SHORT_U 23 /* unary SHORT_A. ABS for example */
+#define SHORT_F 25 /* SHORT_A with flag registers */
+#define SHORT_AF 27 /* SHORT_A with only the first register a flag register */
+#define SHORT_T 29 /* for trap instruction */
+#define SHORT_A5 30 /* SHORT_A with a 5-bit immediate instead of 6 */
+#define SHORT_CMP 32 /* special form for CMPcc */
+#define SHORT_CMPU 34 /* special form for CMPUcc */
+#define SHORT_A1 36 /* special form of SHORT_A for MACa opcodes where a=1 */
+#define SHORT_AA 38 /* SHORT_A with the first register an accumulator */
+#define SHORT_RA 40 /* SHORT_A with the second register an accumulator */
+#define SHORT_MODINC 42
+#define SHORT_MODDEC 43
+#define SHORT_C1 44
+#define SHORT_C2 45
+#define SHORT_UF 46
+#define SHORT_A2 47
+#define SHORT_A5S 49
+#define SHORT_NONE 51 /* no operands */
+#define LONG 52
+#define LONG_U 53 /* unary LONG */
+#define LONG_AF 54 /* LONG with the first register a flag register */
+#define LONG_CMP 55 /* special form for CMPcc and CMPUcc */
+#define LONG_M 56 /* Memory long for ldb, stb */
+#define LONG_M2 57 /* Memory long for ld2w, st2w */
+#define LONG_2 58 /* LONG with 2 operands; bratnz */
+#define LONG_2b 59 /* LONG_2 with modifier of 3 */
+#define LONG_D 60 /* for DBRAI*/
+#define LONG_Db 61 /* for repeati*/
+
+ /* the execution unit(s) used */
+ int unit;
+#define EITHER 0
+#define IU 1
+#define MU 2
+#define EITHER_BUT_PREFER_MU 3
+
+ /* this field is used to decide if two instructions */
+ /* can be executed in parallel */
+ long flags_used;
+ long flags_set;
+#define FLAG_0 (1L<<0)
+#define FLAG_1 (1L<<1)
+#define FLAG_2 (1L<<2)
+#define FLAG_3 (1L<<3)
+#define FLAG_4 (1L<<4) /* S (saturation) */
+#define FLAG_5 (1L<<5) /* V (overflow) */
+#define FLAG_6 (1L<<6) /* VA (accumulated overflow) */
+#define FLAG_7 (1L<<7) /* C (carry/borrow) */
+#define FLAG_SM (1L<<8) /* SM (stack mode) */
+#define FLAG_RP (1L<<9) /* RP (repeat enable) */
+#define FLAG_CONTROL (1L<<10) /* control registers */
+#define FLAG_A0 (1L<<11) /* A0 */
+#define FLAG_A1 (1L<<12) /* A1 */
+#define FLAG_JMP (1L<<13) /* instruction is a branch */
+#define FLAG_JSR (1L<<14) /* subroutine call. must be aligned */
+#define FLAG_MEM (1L<<15) /* reads/writes memory */
+#define FLAG_2WORD (1L<<16) /* 2 word/4 byte operation */
+#define FLAG_MUL16 (1L<<17) /* 16 bit multiply */
+#define FLAG_MUL32 (1L<<18) /* 32 bit multiply */
+#define FLAG_ADDSUBppp (1L<<19) /* ADDppp or SUBppp */
+#define FLAG_DELAY (1L<<20) /* This is a delayed branch or jump */
+#define FLAG_LKR (1L<<21) /* insn in left slot kills right slot */
+#define FLAG_CVVA (FLAG_5|FLAG_6|FLAG_7)
+#define FLAG_C FLAG_7
+#define FLAG_ALL (FLAG_0 | \
+ FLAG_1 | \
+ FLAG_2 | \
+ FLAG_3 | \
+ FLAG_4 | \
+ FLAG_5 | \
+ FLAG_6 | \
+ FLAG_7 | \
+ FLAG_SM | \
+ FLAG_RP | \
+ FLAG_CONTROL)
+
+ int reloc_flag;
+#define RELOC_PCREL 1
+#define RELOC_ABS 2
+};
+
+extern const struct d30v_opcode d30v_opcode_table[];
+extern const int d30v_num_opcodes;
+
+/* The operands table is an array of struct d30v_operand. */
+struct d30v_operand
+{
+ /* the length of the field */
+ int length;
+
+ /* The number of significant bits in the operand. */
+ int bits;
+
+ /* position relative to Ra */
+ int position;
+
+ /* syntax flags. */
+ long flags;
+};
+extern const struct d30v_operand d30v_operand_table[];
+
+/* Values defined for the flags field of a struct d30v_operand. */
+
+/* this is the destination register; it will be modified */
+/* this is used by the optimizer */
+#define OPERAND_DEST (1)
+
+/* number or symbol */
+#define OPERAND_NUM (2)
+
+/* address or label */
+#define OPERAND_ADDR (4)
+
+/* register */
+#define OPERAND_REG (8)
+
+/* postincrement + */
+#define OPERAND_PLUS (0x10)
+
+/* postdecrement - */
+#define OPERAND_MINUS (0x20)
+
+/* signed number */
+#define OPERAND_SIGNED (0x40)
+
+/* this operand must be shifted left by 3 */
+#define OPERAND_SHIFT (0x80)
+
+/* flag register */
+#define OPERAND_FLAG (0x100)
+
+/* control register */
+#define OPERAND_CONTROL (0x200)
+
+/* accumulator */
+#define OPERAND_ACC (0x400)
+
+/* @ */
+#define OPERAND_ATSIGN (0x800)
+
+/* @( */
+#define OPERAND_ATPAR (0x1000)
+
+/* predecrement mode '@-sp' */
+#define OPERAND_ATMINUS (0x2000)
+
+/* this operand changes the instruction name */
+/* for example, CPMcc, CMPUcc */
+#define OPERAND_NAME (0x4000)
+
+/* fake operand for mvtsys and mvfsys */
+#define OPERAND_SPECIAL (0x8000)
+
+/* let the optimizer know that two registers are affected */
+#define OPERAND_2REG (0x10000)
+
+/* The format table is an array of struct d30v_format. */
+struct d30v_format
+{
+ int form; /* SHORT_A, LONG, etc */
+ int modifier; /* two bit modifier following opcode */
+ unsigned char operands[5];
+};
+extern const struct d30v_format d30v_format_table[];
+
+
+/* an instruction is defined by an opcode and a format */
+/* for example, "add" has one opcode, but three different */
+/* formats, 2 SHORT_A forms and a LONG form. */
+struct d30v_insn
+{
+ struct d30v_opcode *op; /* pointer to an entry in the opcode table */
+ struct d30v_format *form; /* pointer to an entry in the format table */
+ int ecc; /* execution condition code */
+};
+
+/* an expressionS only has one register type, so we fake it */
+/* by setting high bits to indicate type */
+#define REGISTER_MASK 0xFF
+
+#endif /* D30V_H */
diff --git a/include/opcode/h8300.h b/include/opcode/h8300.h
new file mode 100644
index 00000000000..3a05e4ee21c
--- /dev/null
+++ b/include/opcode/h8300.h
@@ -0,0 +1,604 @@
+/* Opcode table for the H8-300
+ Copyright (C) 1991, 92, 93, 95, 96, 97, 1998 Free Software Foundation.
+ Written by Steve Chamberlain, sac@cygnus.com.
+
+ This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* Instructions are stored as a sequence of nibbles.
+ If the nibble has value 15 or less then the representation is complete.
+ Otherwise, we record what it contains with several flags. */
+
+typedef int op_type;
+
+#define Hex0 0
+#define Hex1 1
+#define Hex2 2
+#define Hex3 3
+#define Hex4 4
+#define Hex5 5
+#define Hex6 6
+#define Hex7 7
+#define Hex8 8
+#define Hex9 9
+#define HexA 10
+#define HexB 11
+#define HexC 12
+#define HexD 13
+#define HexE 14
+#define HexF 15
+
+#define L_8 0x01
+#define L_16 0x02
+#define L_32 0x04
+#define L_P 0x08
+#define L_24 0x10
+#define MEMRELAX 0x20 /* move insn which may relax */
+#define SRC 0x40
+#define DST 0x80
+
+#define REG 0x100
+#define EXR 0x200
+#define MACREG 0x800
+#define SRC_IN_DST 0x400
+#define IMM 0x1000
+#define DISP 0x2000
+#define IND 0x4000
+#define INC 0x8000
+#define DEC 0x10000
+#define L_3 0x20000
+#define KBIT 0x40000
+#define DBIT 0x80000
+#define DISPREG 0x100000
+#define IGNORE 0x200000
+#define E 0x400000 /* FIXME: end of nibble sequence? */
+#define L_2 0x800000
+#define B30 0x1000000 /* bit 3 must be low */
+#define B31 0x2000000 /* bit 3 must be high */
+#define CCR 0x4000000
+#define ABS 0x8000000
+#define ABSJMP 0x10000000
+#define ABS8MEM 0x20000000
+#define PCREL 0x40000000
+#define MEMIND 0x80000000
+
+#define IMM3 IMM|L_3
+#define IMM2 IMM|L_2
+
+#define SIZE (L_2|L_3|L_8|L_16|L_32|L_P|L_24)
+#define MODE (REG|IMM|DISP|IND|INC|DEC|CCR|ABS|MEMIND|EXR)
+
+#define RD8 (DST|L_8|REG)
+#define RD16 (DST|L_16|REG)
+#define RD32 (DST|L_32|REG)
+#define RS8 (SRC|L_8|REG)
+#define RS16 (SRC|L_16|REG)
+#define RS32 (SRC|L_32|REG)
+
+#define RSP (SRC|L_P|REG)
+#define RDP (DST|L_P|REG)
+
+#define IMM8 (IMM|SRC|L_8)
+#define IMM16 (IMM|SRC|L_16)
+#define IMM32 (IMM|SRC|L_32)
+
+#define ABS8SRC (SRC|ABS|L_8|ABS8MEM)
+#define ABS8DST (DST|ABS|L_8|ABS8MEM)
+
+#define DISP8 (PCREL|L_8)
+#define DISP16 (PCREL|L_16)
+
+#define DISP8SRC (DISP|L_8|SRC)
+#define DISP16SRC (DISP|L_16|SRC)
+
+#define DISP8DST (DISP|L_8|DST)
+#define DISP16DST (DISP|L_16|DST)
+
+#define ABS16SRC (SRC|ABS|L_16)
+#define ABS16DST (DST|ABS|L_16)
+#define ABS24SRC (SRC|ABS|L_24)
+#define ABS24DST (DST|ABS|L_24)
+#define ABS32SRC (SRC|ABS|L_32)
+#define ABS32DST (DST|ABS|L_32)
+
+#define RDDEC (DST|DEC)
+#define RSINC (SRC|INC)
+#define RDINC (DST|INC)
+
+#define RDIND (DST|IND)
+#define RSIND (SRC|IND)
+
+#if 1
+#define OR8 RS8 /* ??? OR as in One Register? */
+#define OR16 RS16
+#define OR32 RS32
+#else
+#define OR8 RD8
+#define OR16 RD16
+#define OR32 RD32
+#endif
+
+struct code
+{
+ op_type nib[30];
+};
+
+struct arg
+{
+ op_type nib[3];
+};
+
+struct h8_opcode
+{
+ int how;
+ int inbase;
+ int time;
+ char *name;
+ struct arg args;
+ struct code data;
+ int length;
+ int noperands;
+ int idx;
+ int size;
+};
+
+#ifdef DEFINE_TABLE
+
+#define BITOP(code, imm, name, op00, op01,op10,op11, op20,op21,op30)\
+{ code, 1, 2, name, {{imm,RD8,E}}, {{op00, op01, imm, RD8, E, 0, 0, 0, 0}}, 0, 0, 0, 0},\
+{ code, 1, 6, name, {{imm,RDIND,E}},{{op10, op11, B30|RDIND, 0, op00,op01, imm, 0, E}}, 0, 0, 0, 0},\
+{ code, 1, 6, name, {{imm,ABS8DST,E}},{{op20, op21, ABS8DST, IGNORE, op00,op01, imm, 0,E}}, 0, 0, 0, 0}\
+,{ code, 0, 6, name, {{imm,ABS16DST,E}},{{0x6,0xa,0x1,op30,ABS16DST,IGNORE,IGNORE,IGNORE, op00,op01, imm, 0,E}}, 0, 0, 0, 0},\
+{ code, 0, 6, name, {{imm,ABS32DST,E}},{{0x6,0xa,0x3,op30,ABS32DST,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE, op00,op01, imm, 0,E}}, 0, 0, 0, 0}
+
+
+#define EBITOP(code, imm, name, op00, op01,op10,op11, op20,op21,op30)\
+ BITOP(code,imm, name, op00+1, op01, op10,op11, op20,op21,op30),\
+ BITOP(code,RS8, name, op00, op01, op10,op11, op20,op21,op30)
+
+#define WTWOP(code,name, op1, op2) \
+{ code, 1, 2, name, {{RS16, RD16, E}}, {{ op1, op2, RS16, RD16, E, 0, 0, 0, 0}}, 0, 0, 0, 0}
+
+#define BRANCH(code, name, op) \
+{ code, 1, 4,name,{{DISP8,E,0}}, {{ 0x4, op, DISP8, IGNORE, E, 0, 0, 0, 0}}, 0, 0, 0, 0}, \
+{ code, 0, 6,name,{{DISP16,E,0}}, {{ 0x5, 0x8, op, 0x0, DISP16, IGNORE, IGNORE, IGNORE, E,0}}, 0, 0, 0, 0}
+
+#define SOP(code, x,name) \
+{code, 1, x, name
+
+#define NEW_SOP(code, in,x,name) \
+{code, in, x, name
+#define EOP ,0,0,0 }
+
+#define TWOOP(code, name, op1, op2,op3) \
+{ code,1, 2,name, {{IMM8, RD8, E}}, {{ op1, RD8, IMM8, IGNORE, E, 0, 0, 0, 0}}, 0, 0, 0, 0},\
+{ code, 1, 2,name, {{RS8, RD8, E}}, {{ op2, op3, RS8, RD8, E, 0, 0, 0, 0}}, 0, 0, 0, 0}
+
+#define UNOP(code,name, op1, op2) \
+{ code, 1, 2, name, {{OR8, E, 0}}, {{ op1, op2, 0, OR8, E, 0, 0, 0, 0}}, 0, 0, 0, 0}
+
+#define UNOP3(code, name, op1, op2, op3) \
+{ O(code,SB), 1, 2, name, {{OR8, E, 0}}, {{op1, op2, op3+0, OR8, E, 0, 0, 0, 0}}, 0, 0, 0, 0}, \
+{ O(code,SW), 0, 2, name, {{OR16, E, 0}}, {{op1, op2, op3+1, OR16, E, 0, 0, 0, 0}}, 0, 0, 0, 0}, \
+{ O(code,SL), 0, 2, name, {{OR32, E, 0}}, {{op1, op2, op3+3, OR32|B30, E, 0, 0, 0, 0}}, 0, 0, 0, 0} \
+,{ O(code,SB), 1, 2, name, {{IMM, OR8 | SRC_IN_DST, E}}, {{op1, op2, op3+4, OR8 | SRC_IN_DST, E, 0, 0, 0, 0}}, 0, 0, 0, 0}, \
+{ O(code,SW), 0, 2, name, {{IMM, OR16 | SRC_IN_DST, E}}, {{op1, op2, op3+5, OR16 | SRC_IN_DST, E, 0, 0, 0, 0}}, 0, 0, 0, 0}, \
+{ O(code,SL), 0, 2, name, {{IMM, OR32 | SRC_IN_DST, E}}, {{op1, op2, op3+7, OR32 | SRC_IN_DST|B30 , E, 0, 0, 0, 0}}, 0, 0, 0, 0}
+
+
+#define IMM32LIST IMM32,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define IMM24LIST IMM24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define IMM16LIST IMM16,IGNORE,IGNORE,IGNORE
+#define A16LIST L_16,IGNORE,IGNORE,IGNORE
+#define DISP24LIST DISP|L_24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define DISP32LIST DISP|L_32,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define ABS24LIST ABS|L_24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define ABS32LIST ABS|L_32,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define A24LIST L_24,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define A32LIST L_32,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE
+#define PREFIX32 0x0,0x1,0x0,0x0
+#define PREFIXLDC 0x0,0x1,0x4,0x0
+
+
+#define O(op, size) (op*4+size)
+
+#define O_RECOMPILE 0
+#define O_ADD 1
+#define O_ADDX 2
+#define O_AND 3
+#define O_BAND 4
+#define O_BRA 5
+#define O_BRN 6
+#define O_BHI 7
+#define O_BLS 8
+#define O_BCC 9
+#define O_BCS 10
+#define O_BNE 11
+#define O_BVC 12
+#define O_BVS 13
+#define O_BPL 14
+#define O_BMI 15
+#define O_BGE 16
+#define O_BLT 17
+#define O_BGT 18
+#define O_BLE 19
+#define O_ANDC 20
+#define O_BEQ 21
+#define O_BCLR 22
+#define O_BIAND 23
+#define O_BILD 24
+#define O_BIOR 25
+#define O_BIXOR 26
+#define O_BIST 27
+#define O_BLD 28
+#define O_BNOT 29
+#define O_BSET 30
+#define O_BSR 31
+#define O_BXOR 32
+#define O_CMP 33
+#define O_DAA 34
+#define O_DAS 35
+#define O_DEC 36
+#define O_DIVU 37
+#define O_DIVS 38
+#define O_INC 39
+#define O_LDC 40
+#define O_MOV_TO_MEM 41
+#define O_OR 42
+#define O_ROTL 43
+#define O_ROTR 44
+#define O_ROTXL 45
+#define O_ROTXR 46
+#define O_BPT 47
+#define O_SHAL 48
+#define O_SHAR 49
+#define O_SHLL 50
+#define O_SHLR 51
+#define O_SUB 52
+#define O_SUBS 53
+#define O_TRAPA 54
+#define O_XOR 55
+#define O_XORC 56
+#define O_BOR 57
+#define O_BST 58
+#define O_BTST 59
+#define O_EEPMOV 60
+#define O_EXTS 61
+#define O_EXTU 62
+#define O_JMP 63
+#define O_JSR 64
+#define O_MULU 65
+#define O_MULS 66
+#define O_NOP 67
+#define O_NOT 68
+#define O_ORC 69
+#define O_RTE 70
+#define O_STC 71
+#define O_SUBX 72
+#define O_NEG 73
+#define O_RTS 74
+#define O_SLEEP 75
+#define O_ILL 76
+#define O_ADDS 77
+#define O_SYSCALL 78
+#define O_MOV_TO_REG 79
+#define O_TAS 80
+#define O_CLRMAC 82
+#define O_LDMAC 83
+#define O_MAC 84
+#define O_LDM 85
+#define O_STM 86
+#define O_STMAC 87
+#define O_LAST 88
+#define SB 0
+#define SW 1
+#define SL 2
+#define SN 3
+
+
+/* FIXME: Lots of insns have "E, 0, 0, 0, 0" in the nibble code sequences.
+ Methinks the zeroes aren't necessary. Once confirmed, nuke 'em. */
+
+struct h8_opcode h8_opcodes[] =
+{
+ TWOOP(O(O_ADD,SB),"add.b", 0x8, 0x0,0x8),
+
+ NEW_SOP(O(O_ADD,SW),1,2,"add.w"),{{RS16,RD16,E}},{{0x0,0x9,RS16,RD16,E}} EOP,
+ NEW_SOP(O(O_ADD,SW),0,4,"add.w"),{{IMM16,RD16,E}},{{0x7,0x9,0x1,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}} EOP,
+ NEW_SOP(O(O_ADD,SL),0,2,"add.l"),{{RS32,RD32,E }}, {{0x0,0xA,B31|RS32,B30|RD32,E}} EOP,
+ NEW_SOP(O(O_ADD,SL),0,6,"add.l"),{{IMM32,RD32,E }},{{0x7,0xA,0x1,B30|RD32,IMM32LIST,E}} EOP,
+ NEW_SOP(O(O_ADDS,SL),1,2,"adds"), {{KBIT,RDP,E}}, {{0x0,0xB,KBIT,RDP,E,0,0,0,0}} EOP,
+
+ TWOOP(O(O_ADDX,SB),"addx",0x9,0x0,0xE),
+ TWOOP(O(O_AND,SB), "and.b",0xE,0x1,0x6),
+
+ NEW_SOP(O(O_AND,SW),0,2,"and.w"),{{RS16,RD16,E }},{{0x6,0x6,RS16,RD16,E}} EOP,
+ NEW_SOP(O(O_AND,SW),0,4,"and.w"),{{IMM16,RD16,E }},{{0x7,0x9,0x6,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}} EOP,
+
+ NEW_SOP(O(O_AND,SL),0,6,"and.l"),{{IMM32,RD32,E }},{{0x7,0xA,0x6,B30|RD32,IMM32LIST,E}} EOP,
+ NEW_SOP(O(O_AND,SL),0,2,"and.l") ,{{RS32,RD32,E }},{{0x0,0x1,0xF,0x0,0x6,0x6,B30|RS32,B30|RD32,E}} EOP,
+
+ NEW_SOP(O(O_ANDC,SB),1,2,"andc"), {{IMM8,CCR,E}},{{ 0x0,0x6,IMM8,IGNORE,E,0,0,0,0}} EOP,
+ NEW_SOP(O(O_ANDC,SB),1,2,"andc"), {{IMM8,EXR,E}},{{ 0x0,0x1,0x4,0x1,0x0,0x6,IMM8,IGNORE,E,0,0,0,0}} EOP,
+
+ BITOP(O(O_BAND,SB), IMM3|B30,"band",0x7,0x6,0x7,0xC,0x7,0xE,0x0),
+ BRANCH(O(O_BRA,SB),"bra",0x0),
+ BRANCH(O(O_BRA,SB),"bt",0x0),
+ BRANCH(O(O_BRN,SB),"brn",0x1),
+ BRANCH(O(O_BRN,SB),"bf",0x1),
+ BRANCH(O(O_BHI,SB),"bhi",0x2),
+ BRANCH(O(O_BLS,SB),"bls",0x3),
+ BRANCH(O(O_BCC,SB),"bcc",0x4),
+ BRANCH(O(O_BCC,SB),"bhs",0x4),
+ BRANCH(O(O_BCS,SB),"bcs",0x5),
+ BRANCH(O(O_BCS,SB),"blo",0x5),
+ BRANCH(O(O_BNE,SB),"bne",0x6),
+ BRANCH(O(O_BEQ,SB),"beq",0x7),
+ BRANCH(O(O_BVC,SB),"bvc",0x8),
+ BRANCH(O(O_BVS,SB),"bvs",0x9),
+ BRANCH(O(O_BPL,SB),"bpl",0xA),
+ BRANCH(O(O_BMI,SB),"bmi",0xB),
+ BRANCH(O(O_BGE,SB),"bge",0xC),
+ BRANCH(O(O_BLT,SB),"blt",0xD),
+ BRANCH(O(O_BGT,SB),"bgt",0xE),
+ BRANCH(O(O_BLE,SB),"ble",0xF),
+
+ EBITOP(O(O_BCLR,SB),IMM3|B30,"bclr", 0x6,0x2,0x7,0xD,0x7,0xF,0x8),
+ BITOP(O(O_BIAND,SB),IMM3|B31,"biand",0x7,0x6,0x7,0xC,0x7,0xE,0x0),
+ BITOP(O(O_BILD,SB), IMM3|B31,"bild", 0x7,0x7,0x7,0xC,0x7,0xE,0x0),
+ BITOP(O(O_BIOR,SB), IMM3|B31,"bior", 0x7,0x4,0x7,0xC,0x7,0xE,0x0),
+ BITOP(O(O_BIST,SB), IMM3|B31,"bist", 0x6,0x7,0x7,0xD,0x7,0xF,0x8),
+ BITOP(O(O_BIXOR,SB),IMM3|B31,"bixor",0x7,0x5,0x7,0xC,0x7,0xE,0x0),
+ BITOP(O(O_BLD,SB), IMM3|B30,"bld", 0x7,0x7,0x7,0xC,0x7,0xE,0x0),
+ EBITOP(O(O_BNOT,SB),IMM3|B30,"bnot", 0x6,0x1,0x7,0xD,0x7,0xF,0x8),
+ BITOP(O(O_BOR,SB), IMM3|B30,"bor", 0x7,0x4,0x7,0xC,0x7,0xE,0x0),
+ EBITOP(O(O_BSET,SB),IMM3|B30,"bset", 0x6,0x0,0x7,0xD,0x7,0xF,0x8),
+
+ SOP(O(O_BSR,SB),6,"bsr"),{{DISP8,E,0}},{{ 0x5,0x5,DISP8,IGNORE,E,0,0,0,0}} EOP,
+ SOP(O(O_BSR,SB),6,"bsr"),{{DISP16,E,0}},{{ 0x5,0xC,0x0,0x0,DISP16,IGNORE,IGNORE,IGNORE,E,0,0,0,0}} EOP,
+ BITOP(O(O_BST,SB), IMM3|B30,"bst",0x6,0x7,0x7,0xD,0x7,0xF,0x8),
+ EBITOP(O(O_BTST,SB), IMM3|B30,"btst",0x6,0x3,0x7,0xC,0x7,0xE,0x0),
+ BITOP(O(O_BXOR,SB), IMM3|B30,"bxor",0x7,0x5,0x7,0xC,0x7,0xE,0x0),
+
+ TWOOP(O(O_CMP,SB), "cmp.b",0xA,0x1,0xC),
+ WTWOP(O(O_CMP,SW), "cmp.w",0x1,0xD),
+
+ NEW_SOP(O(O_CMP,SW),1,2,"cmp.w"),{{RS16,RD16,E }},{{0x1,0xD,RS16,RD16,E}} EOP,
+ NEW_SOP(O(O_CMP,SW),0,4,"cmp.w"),{{IMM16,RD16,E }},{{0x7,0x9,0x2,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}} EOP,
+
+ NEW_SOP(O(O_CMP,SL),0,6,"cmp.l"),{{IMM32,RD32,E }},{{0x7,0xA,0x2,B30|RD32,IMM32LIST,E}} EOP,
+ NEW_SOP(O(O_CMP,SL),0,2,"cmp.l") ,{{RS32,RD32,E }},{{0x1,0xF,B31|RS32,B30|RD32,E}} EOP,
+
+ UNOP(O(O_DAA,SB), "daa",0x0,0xF),
+ UNOP(O(O_DAS,SB), "das",0x1,0xF),
+ UNOP(O(O_DEC,SB), "dec.b",0x1,0xA),
+
+ NEW_SOP(O(O_DEC, SW),0,2,"dec.w") ,{{DBIT,RD16,E }},{{0x1,0xB,0x5|DBIT,RD16,E}} EOP,
+ NEW_SOP(O(O_DEC, SL),0,2,"dec.l") ,{{DBIT,RD32,E }},{{0x1,0xB,0x7|DBIT,RD32|B30,E}} EOP,
+
+ NEW_SOP(O(O_DIVU,SB),1,6,"divxu.b"), {{RS8,RD16,E}}, {{0x5,0x1,RS8,RD16,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_DIVU,SW),0,20,"divxu.w"),{{RS16,RD32,E}},{{0x5,0x3,RS16,B30|RD32,E}}EOP,
+
+ NEW_SOP(O(O_DIVS,SB),0,20,"divxs.b") ,{{RS8,RD16,E }},{{0x0,0x1,0xD,0x0,0x5,0x1,RS8,RD16,E}} EOP,
+ NEW_SOP(O(O_DIVS,SW),0,02,"divxs.w") ,{{RS16,RD32,E }},{{0x0,0x1,0xD,0x0,0x5,0x3,RS16,B30|RD32,E}} EOP,
+
+ NEW_SOP(O(O_EEPMOV,SB),1,50,"eepmov.b"),{{E,0,0}},{{0x7,0xB,0x5,0xC,0x5,0x9,0x8,0xF,E}}EOP,
+ NEW_SOP(O(O_EEPMOV,SW),0,50,"eepmov.w"),{{E,0,0}},{{0x7,0xB,0xD,0x4,0x5,0x9,0x8,0xF,E}} EOP,
+
+ NEW_SOP(O(O_EXTS,SW),0,2,"exts.w"),{{OR16,E,0}},{{0x1,0x7,0xD,OR16,E }}EOP,
+ NEW_SOP(O(O_EXTS,SL),0,2,"exts.l"),{{OR32,E,0}},{{0x1,0x7,0xF,OR32|B30,E }}EOP,
+
+ NEW_SOP(O(O_EXTU,SW),0,2,"extu.w"),{{OR16,E,0}},{{0x1,0x7,0x5,OR16,E }}EOP,
+ NEW_SOP(O(O_EXTU,SL),0,2,"extu.l"),{{OR32,E,0}},{{0x1,0x7,0x7,OR32|B30,E }}EOP,
+
+ UNOP(O(O_INC,SB), "inc",0x0,0xA),
+
+ NEW_SOP(O(O_INC,SW),0,2,"inc.w") ,{{DBIT,RD16,E }},{{0x0,0xB,0x5|DBIT,RD16,E}} EOP,
+ NEW_SOP(O(O_INC,SL),0,2,"inc.l") ,{{DBIT,RD32,E }},{{0x0,0xB,0x7|DBIT,RD32|B30,E}} EOP,
+
+ SOP(O(O_JMP,SB),4,"jmp"),{{RSIND,E,0}},{{0x5,0x9,B30|RSIND,0x0,E,0,0,0,0}}EOP,
+ SOP(O(O_JMP,SB),6,"jmp"),{{SRC|ABSJMP,E,0}},{{0x5,0xA,SRC|ABSJMP,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_JMP,SB),8,"jmp"),{{SRC|MEMIND,E,0}},{{0x5,0xB,SRC|MEMIND,IGNORE,E,0,0,0,0}}EOP,
+
+ SOP(O(O_JSR,SB),6,"jsr"),{{SRC|RSIND,E,0}}, {{0x5,0xD,B30|RSIND,0x0,E,0,0,0,0}}EOP,
+ SOP(O(O_JSR,SB),8,"jsr"),{{SRC|ABSJMP,E,0}},{{0x5,0xE,SRC|ABSJMP,IGNORE,IGNORE,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_JSR,SB),8,"jsr"),{{SRC|MEMIND,E,0}},{{0x5,0xF,SRC|MEMIND,IGNORE,E,0,0,0,0}}EOP,
+
+ NEW_SOP(O(O_LDC,SB),1,2,"ldc"),{{IMM8,CCR,E}}, {{ 0x0,0x7,IMM8,IGNORE,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_LDC,SB),1,2,"ldc"),{{OR8,CCR,E}}, {{ 0x0,0x3,0x0,OR8,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{ABS16SRC,CCR,E}}, {{PREFIXLDC,0x6,0xB,0x0,0x0,ABS16SRC,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{ABS32SRC,CCR,E}}, {{PREFIXLDC,0x6,0xB,0x2,0x0,SRC|ABS32LIST,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{DISP|SRC|L_16,CCR,E}},{{PREFIXLDC,0x6,0xF,B30|DISPREG,0,DISP|L_16,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{DISP|SRC|L_32,CCR,E}},{{PREFIXLDC,0x7,0x8,B30|DISPREG,0,0x6,0xB,0x2,0x0,SRC|DISP32LIST,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{RSINC,CCR,E}}, {{PREFIXLDC,0x6,0xD,B30|RSINC,0x0,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{RSIND,CCR,E}}, {{PREFIXLDC,0x6,0x9,B30|RDIND,0x0,E}} EOP,
+
+ NEW_SOP(O(O_LDC,SB),1,2,"ldc"),{{IMM8,EXR,E}}, {{ 0x0,0x1,0x4,0x1,0x0,0x7,IMM8,IGNORE,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_LDC,SB),1,2,"ldc"),{{OR8,EXR,E}}, {{ 0x0,0x3,0x1,OR8,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{ABS16SRC,EXR,E}}, {{ 0x0,0x1,0x4,0x1,0x6,0xb,0x0,0x0,ABS16SRC,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{ABS32SRC,EXR,E}}, {{ 0x0,0x1,0x4,0x1,0x6,0xb,0x2,0x0,SRC|ABS32LIST,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{DISP|SRC|L_16,EXR,E}},{{ 0x0,0x1,0x4,0x1,0x6,0xf,B30|DISPREG,0,DISP|L_16,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{DISP|SRC|L_32,EXR,E}},{{ 0x0,0x1,0x4,0x1,0x7,0x8,B30|DISPREG,0,0x6,0xB,0x2,0x0,SRC|DISP32LIST,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{RSINC,EXR,E}}, {{ 0x0,0x1,0x4,0x1,0x6,0xd,B30|RSINC,0x0,E}}EOP,
+ NEW_SOP(O(O_LDC,SB),0,2,"ldc"),{{RSIND,EXR,E}}, {{ 0x0,0x1,0x4,0x1,0x6,0x9,B30|RDIND,0x0,E}} EOP,
+
+ SOP(O(O_MOV_TO_REG,SB),4,"mov.b"),{{ABS|SRC|L_16|MEMRELAX,RD8,E}}, {{ 0x6,0xA,0x0,RD8,SRC|ABS|MEMRELAX|A16LIST,E}}EOP,
+ SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{{ABS|SRC|L_32|MEMRELAX,RD8,E }}, {{ 0x6,0xA,0x2,RD8,SRC|ABS|MEMRELAX|A32LIST,E }}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),4,"mov.b"),{{RS8,ABS|L_16|MEMRELAX|DST,E}}, {{ 0x6,0xA,0x8,RS8,DST|ABS|MEMRELAX|A16LIST,E}}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{{RS8,ABS|DST|L_32|MEMRELAX,E }}, {{ 0x6,0xA,0xA,RS8,DST|ABS|MEMRELAX|A32LIST,E }}EOP,
+
+ SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{{DISP|L_32|SRC,RD8,E}}, {{ 0x7,0x8,B30|DISPREG,0x0,0x6,0xA,0x2,RD8,SRC|DISP32LIST,E}}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{{RS8,DISP|L_32|DST,E}}, {{ 0x7,0x8,B30|DISPREG,0x0,0x6,0xA,0xA,RS8,DST|DISP32LIST,E}}EOP,
+
+
+
+ SOP(O(O_MOV_TO_REG,SB),2,"mov.b"),{{RS8,RD8,E}}, {{ 0x0,0xC,RS8,RD8,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SB),2,"mov.b"),{{IMM8,RD8,E}}, {{ 0xF,RD8,IMM8,IGNORE,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SB),4,"mov.b"),{{RSIND,RD8,E}}, {{ 0x6,0x8,B30|RSIND,RD8,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{{DISP16SRC,RD8,E}}, {{ 0x6,0xE,B30|DISPREG,RD8,DISP16SRC,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_MOV_TO_REG,SB),6,"mov.b"),{{RSINC,RD8,E}}, {{ 0x6,0xC,B30|RSINC,RD8,E,0,0,0,0}}EOP,
+
+ SOP(O(O_MOV_TO_REG,SB),4,"mov.b"),{{ABS8SRC,RD8,E}}, {{ 0x2,RD8,ABS8SRC,IGNORE,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),4,"mov.b"),{{RS8,RDIND,E}}, {{ 0x6,0x8,RDIND|B31,RS8,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{{RS8,DISP16DST,E}}, {{ 0x6,0xE,DISPREG|B31,RS8,DISP16DST,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),6,"mov.b"),{{RS8,RDDEC|B31,E}}, {{ 0x6,0xC,RDDEC|B31,RS8,E,0,0,0,0}}EOP,
+
+ SOP(O(O_MOV_TO_MEM,SB),4,"mov.b"),{{RS8,ABS8DST,E}}, {{ 0x3,RS8,ABS8DST,IGNORE,E,0,0,0,0}}EOP,
+
+ SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{{RS16,RDIND,E}}, {{ 0x6,0x9,RDIND|B31,RS16,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{{DISP|L_32|SRC,RD16,E}},{{ 0x7,0x8,B30|DISPREG,0x0,0x6,0xB,0x2,RD16,SRC|DISP32LIST,E}}EOP,
+ SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{{RS16,DISP|L_32|DST,E}},{{ 0x7,0x8,B30|DISPREG,0x0,0x6,0xB,0xA,RS16,DST|DISP32LIST,E}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{{ABS|L_32|MEMRELAX|SRC,RD16,E }},{{ 0x6,0xB,0x2,RD16,SRC|MEMRELAX|ABS32LIST,E }}EOP,
+ SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{{RS16,ABS|L_32|MEMRELAX|DST,E }},{{ 0x6,0xB,0xA,RS16,DST|MEMRELAX|ABS32LIST,E }}EOP,
+ SOP(O(O_MOV_TO_REG,SW),2,"mov.w"),{{RS16,RD16,E}}, {{ 0x0,0xD,RS16, RD16,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),4,"mov.w"),{{IMM16,RD16,E}}, {{ 0x7,0x9,0x0,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),4,"mov.w"),{{RSIND,RD16,E}}, {{ 0x6,0x9,B30|RSIND,RD16,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{{DISP16SRC,RD16,E}}, {{ 0x6,0xF,B30|DISPREG,RD16,DISP16SRC,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{{RSINC,RD16,E}}, {{ 0x6,0xD,B30|RSINC,RD16,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_REG,SW),6,"mov.w"),{{ABS16SRC,RD16,E}}, {{ 0x6,0xB,0x0,RD16,ABS16SRC,IGNORE,IGNORE,IGNORE,E}}EOP,
+
+ SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{{RS16,DISP16DST,E}}, {{ 0x6,0xF,DISPREG|B31,RS16,DISP16DST,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{{RS16,RDDEC,E}}, {{ 0x6,0xD,RDDEC|B31,RS16,E,0,0,0,0}}EOP,
+ SOP(O(O_MOV_TO_MEM,SW),6,"mov.w"),{{RS16,ABS16DST,E}}, {{ 0x6,0xB,0x8,RS16,ABS16DST,IGNORE,IGNORE,IGNORE,E}}EOP,
+
+ SOP(O(O_MOV_TO_REG,SL),4,"mov.l"),{{IMM32,RD32,E}}, {{ 0x7,0xA,0x0,B30|RD32,IMM32LIST,E}}EOP,
+ SOP(O(O_MOV_TO_REG,SL),2,"mov.l"),{{RS32,RD32,E}}, {{ 0x0,0xF,B31|RS32,B30|RD32,E,0,0,0,0}}EOP,
+
+ SOP(O(O_MOV_TO_REG,SL),4,"mov.l"),{{RSIND,RD32,E}}, {{ PREFIX32,0x6,0x9,RSIND|B30,B30|RD32,E,0,0,0,0 }}EOP,
+ SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{{DISP16SRC,RD32,E}}, {{ PREFIX32,0x6,0xF,DISPREG|B30,B30|RD32,DISP16SRC,IGNORE,IGNORE,IGNORE,E }}EOP,
+ SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{{DISP|L_32|SRC,RD32,E}},{{ PREFIX32,0x7,0x8,B30|DISPREG,0x0,0x6,0xB,0x2,B30|RD32,SRC|DISP32LIST,E }}EOP,
+ SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{{RSINC,RD32,E}}, {{ PREFIX32,0x6,0xD,B30|RSINC,B30|RD32,E,0,0,0,0 }}EOP,
+ SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{{ABS16SRC,RD32,E}}, {{ PREFIX32,0x6,0xB,0x0,B30|RD32,ABS16SRC,IGNORE,IGNORE,IGNORE,E }}EOP,
+ SOP(O(O_MOV_TO_REG,SL),6,"mov.l"),{{ABS32SRC|MEMRELAX,RD32,E }}, {{ PREFIX32,0x6,0xB,0x2,B30|RD32,SRC|MEMRELAX|ABS32LIST,E }}EOP,
+ SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{{RS32,RDIND,E}}, {{ PREFIX32,0x6,0x9,RDIND|B31,B30|RS32,E,0,0,0,0 }}EOP,
+ SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{{RS32,DISP16DST,E}}, {{ PREFIX32,0x6,0xF,DISPREG|B31,B30|RS32,DISP16DST,IGNORE,IGNORE,IGNORE,E }}EOP,
+ SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{{RS32,DISP|L_32|DST,E}},{{ PREFIX32,0x7,0x8,B31|DISPREG,0x0,0x6,0xB,0xA,B30|RS32,DST|DISP32LIST,E }}EOP,
+ SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{{RS32,RDDEC,E}}, {{ PREFIX32,0x6,0xD,RDDEC|B31,B30|RS32,E,0,0,0,0 }}EOP,
+ SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{{RS32,ABS16DST,E}}, {{ PREFIX32,0x6,0xB,0x8,B30|RS32,ABS16DST,IGNORE,IGNORE,IGNORE,E }}EOP,
+ SOP(O(O_MOV_TO_MEM,SL),6,"mov.l"),{{RS32,ABS32DST|MEMRELAX,E }}, {{ PREFIX32,0x6,0xB,0xA,B30|RS32,DST|MEMRELAX|ABS32LIST,E }}EOP,
+
+ SOP(O(O_MOV_TO_REG,SB),10,"movfpe"),{{ABS16SRC,RD8,E}},{{ 0x6,0xA,0x4,RD8,ABS16SRC,IGNORE,IGNORE,IGNORE,E}}EOP,
+ SOP(O(O_MOV_TO_MEM,SB),10,"movtpe"),{{RS8,ABS16DST,E}},{{ 0x6,0xA,0xC,RS8,ABS16DST,IGNORE,IGNORE,IGNORE,E}}EOP,
+
+ NEW_SOP(O(O_MULU,SB),1,14,"mulxu.b"),{{RS8,RD16,E}}, {{ 0x5,0x0,RS8,RD16,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_MULU,SW),0,14,"mulxu.w"),{{RS16,RD32,E}},{{ 0x5,0x2,RS16,B30|RD32,E,0,0,0,0}}EOP,
+
+ NEW_SOP(O(O_MULS,SB),0,20,"mulxs.b"),{{RS8,RD16,E}}, {{ 0x0,0x1,0xc,0x0,0x5,0x0,RS8,RD16,E}}EOP,
+ NEW_SOP(O(O_MULS,SW),0,20,"mulxs.w"),{{RS16,RD32,E}},{{ 0x0,0x1,0xc,0x0,0x5,0x2,RS16,B30|RD32,E}}EOP,
+
+ /* ??? This can use UNOP3. */
+ NEW_SOP(O(O_NEG,SB),1,2,"neg.b"),{{ OR8,E, 0}},{{ 0x1,0x7,0x8,OR8,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_NEG,SW),0,2,"neg.w"),{{ OR16,E,0}},{{ 0x1,0x7,0x9,OR16,E}}EOP,
+ NEW_SOP(O(O_NEG,SL),0,2,"neg.l"),{{ OR32,E,0}},{{ 0x1,0x7,0xB,B30|OR32,E}}EOP,
+
+ NEW_SOP(O(O_NOP,SN),1,2,"nop"),{{E,0,0}},{{ 0x0,0x0,0x0,0x0,E,0,0,0,0}}EOP,
+
+ /* ??? This can use UNOP3. */
+ NEW_SOP(O(O_NOT,SB),1,2,"not.b"),{{ OR8,E, 0}},{{ 0x1,0x7,0x0,OR8,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_NOT,SW),0,2,"not.w"),{{ OR16,E,0}},{{ 0x1,0x7,0x1,OR16,E}}EOP,
+ NEW_SOP(O(O_NOT,SL),0,2,"not.l"),{{ OR32,E,0}},{{ 0x1,0x7,0x3,B30|OR32,E}}EOP,
+
+ TWOOP(O(O_OR, SB),"or.b",0xC,0x1,0x4),
+ NEW_SOP(O(O_OR,SW),0,4,"or.w"),{{IMM16,RD16,E }},{{0x7,0x9,0x4,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}} EOP,
+ NEW_SOP(O(O_OR,SW),0,2,"or.w"),{{RS16,RD16,E }},{{0x6,0x4,RS16,RD16,E}} EOP,
+
+ NEW_SOP(O(O_OR,SL),0,6,"or.l"),{{IMM32,RD32,E }},{{0x7,0xA,0x4,B30|RD32,IMM32LIST,E}} EOP,
+ NEW_SOP(O(O_OR,SL),0,2,"or.l"),{{RS32,RD32,E }},{{0x0,0x1,0xF,0x0,0x6,0x4,B30|RS32,B30|RD32,E}} EOP,
+
+ NEW_SOP(O(O_ORC,SB),1,2,"orc"),{{IMM8,CCR,E}},{{ 0x0,0x4,IMM8,IGNORE,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_ORC,SB),1,2,"orc"),{{IMM8,EXR,E}},{{ 0x0,0x1,0x4,0x1,0x0,0x4,IMM8,IGNORE,E,0,0,0,0}}EOP,
+
+ NEW_SOP(O(O_MOV_TO_REG,SW),1,6,"pop.w"),{{OR16,E,0}},{{ 0x6,0xD,0x7,OR16,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_MOV_TO_REG,SL),0,6,"pop.l"),{{OR32,E,0}},{{ PREFIX32,0x6,0xD,0x7,OR32|B30,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_MOV_TO_MEM,SW),1,6,"push.w"),{{OR16,E,0}},{{ 0x6,0xD,0xF,OR16,E,0,0,0,0}}EOP,
+ NEW_SOP(O(O_MOV_TO_MEM,SL),0,6,"push.l"),{{OR32,E,0}},{{ PREFIX32,0x6,0xD,0xF,OR32|B30,E,0,0,0,0}}EOP,
+
+ UNOP3(O_ROTL, "rotl", 0x1,0x2,0x8),
+ UNOP3(O_ROTR, "rotr", 0x1,0x3,0x8),
+ UNOP3(O_ROTXL, "rotxl",0x1,0x2,0x0),
+ UNOP3(O_ROTXR, "rotxr",0x1,0x3,0x0),
+
+ SOP(O(O_BPT,SN), 10,"bpt"),{{E,0,0}},{{ 0x7,0xA,0xF,0xF,E,0,0,0,0}}EOP,
+ SOP(O(O_RTE,SN), 10,"rte"),{{E,0,0}},{{ 0x5,0x6,0x7,0x0,E,0,0,0,0}}EOP,
+ SOP(O(O_RTS,SN), 8,"rts"),{{E,0,0}},{{ 0x5,0x4,0x7,0x0,E,0,0,0,0}}EOP,
+
+ UNOP3(O_SHAL, "shal",0x1,0x0,0x8),
+ UNOP3(O_SHAR, "shar",0x1,0x1,0x8),
+ UNOP3(O_SHLL, "shll",0x1,0x0,0x0),
+ UNOP3(O_SHLR, "shlr",0x1,0x1,0x0),
+
+ SOP(O(O_SLEEP,SN),2,"sleep"),{{E,0,0}},{{ 0x0,0x1,0x8,0x0,E,0,0,0,0}} EOP,
+
+ NEW_SOP(O(O_STC,SB), 1,2,"stc"),{{CCR,RD8,E}},{{ 0x0,0x2,0x0,RD8,E,0,0,0,0}} EOP,
+
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{CCR,RSIND,E}}, {{PREFIXLDC,0x6,0x9,B31|RDIND,0x0,E}} EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{CCR,DISP|DST|L_16,E}},{{PREFIXLDC,0x6,0xF,B31|DISPREG,0,DST|DISP|L_16,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{CCR,DISP|DST|L_32,E}},{{PREFIXLDC,0x7,0x8,B30|DISPREG,0,0x6,0xB,0xA,0x0,DST|DISP32LIST,E}}EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{CCR,RDDEC,E}}, {{PREFIXLDC,0x6,0xD,B31|RDDEC,0x0,E}}EOP,
+
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{CCR,ABS16SRC,E}}, {{PREFIXLDC,0x6,0xB,0x8,0x0,ABS16DST,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{CCR,ABS32SRC,E}}, {{PREFIXLDC,0x6,0xB,0xA,0x0,DST|ABS32LIST,E}}EOP,
+
+ NEW_SOP(O(O_STC,SB), 1,2,"stc"),{{EXR,RD8,E}},{{ 0x0,0x2,0x1,RD8,E,0,0,0,0}} EOP,
+
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{EXR,RSIND,E}}, {{0x0,0x1,0x4,0x1,0x6,0x9,B31|RDIND,0x0,E}} EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{EXR,DISP|DST|L_16,E}},{{0x0,0x1,0x4,0x1,0x6,0xF,B31|DISPREG,0,DST|DISP|L_16,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{EXR,DISP|DST|L_32,E}},{{0x0,0x1,0x4,0x1,0x7,0x8,B30|DISPREG,0,0x6,0xB,0xA,0x0,DST|DISP32LIST,E}}EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{EXR,RDDEC,E}}, {{0x0,0x1,0x4,0x1,0x6,0xD,B31|RDDEC,0x0,E}}EOP,
+
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{EXR,ABS16SRC,E}}, {{0x0,0x1,0x4,0x1,0x6,0xB,0x8,0x0,ABS16DST,IGNORE,IGNORE,IGNORE,E}}EOP,
+ NEW_SOP(O(O_STC,SB),0,2,"stc"),{{EXR,ABS32SRC,E}}, {{0x0,0x1,0x4,0x1,0x6,0xB,0xA,0x0,DST|ABS32LIST,E}}EOP,
+
+ SOP(O(O_SUB,SB),2,"sub.b"),{{RS8,RD8,E}},{{ 0x1,0x8,RS8,RD8,E,0,0,0,0}}EOP,
+
+ NEW_SOP(O(O_SUB,SW),1,2,"sub.w"),{{RS16,RD16,E }}, {{0x1,0x9,RS16,RD16,E}} EOP,
+ NEW_SOP(O(O_SUB,SW),0,4,"sub.w"),{{IMM16,RD16,E }}, {{0x7,0x9,0x3,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}} EOP,
+ NEW_SOP(O(O_SUB,SL),0,2,"sub.l") ,{{RS32,RD32,E }}, {{0x1,0xA,B31|RS32,B30|RD32,E}} EOP,
+ NEW_SOP(O(O_SUB,SL),0,6,"sub.l"), {{IMM32,RD32,E }},{{0x7,0xA,0x3,B30|RD32,IMM32LIST,E}} EOP,
+
+ SOP(O(O_SUBS,SL),2,"subs"),{{KBIT,RDP,E}},{{ 0x1,0xB,KBIT,RDP,E,0,0,0,0}}EOP,
+ TWOOP(O(O_SUBX,SB),"subx",0xB,0x1,0xE),
+
+ NEW_SOP(O(O_TRAPA,SB),0,2,"trapa"),{{ IMM2,E}}, {{0x5,0x7,IMM2,IGNORE,E }}EOP,
+ NEW_SOP(O(O_TAS,SB),0,2,"tas"),{{RSIND,E}}, {{0x0,0x1,0xe,0x0,0x7,0xb,B30|RSIND,0xc,E }}EOP,
+
+ TWOOP(O(O_XOR, SB),"xor",0xD,0x1,0x5),
+
+ NEW_SOP(O(O_XOR,SW),0,4,"xor.w"),{{IMM16,RD16,E }},{{0x7,0x9,0x5,RD16,IMM16,IGNORE,IGNORE,IGNORE,E}} EOP,
+ NEW_SOP(O(O_XOR,SW),0,2,"xor.w"),{{RS16,RD16,E }},{{0x6,0x5,RS16,RD16,E}} EOP,
+
+ NEW_SOP(O(O_XOR,SL),0,6,"xor.l"),{{IMM32,RD32,E }},{{0x7,0xA,0x5,B30|RD32,IMM32LIST,E}} EOP,
+ NEW_SOP(O(O_XOR,SL),0,2,"xor.l") ,{{RS32,RD32,E }},{{0x0,0x1,0xF,0x0,0x6,0x5,B30|RS32,B30|RD32,E}} EOP,
+
+ SOP(O(O_XORC,SB),2,"xorc"),{{IMM8,CCR,E}},{{ 0x0,0x5,IMM8,IGNORE,E,0,0,0,0}}EOP,
+ SOP(O(O_XORC,SB),2,"xorc"),{{IMM8,EXR,E}},{{ 0x0,0x1,0x4,0x1,0x0,0x5,IMM8,IGNORE,E,0,0,0,0}}EOP,
+
+ NEW_SOP(O(O_CLRMAC,SN),1,2,"clrmac"),{{E, 0, 0}},{{0x0,0x1,0xa,0x0,E}} EOP,
+ NEW_SOP(O(O_MAC,SL),1,2,"mac"),{{RSINC,RDINC,E}},{{0x0,0x1,0x6,0x0,0x6,0xd,B30|RSINC,B30|RDINC,E}} EOP,
+ NEW_SOP(O(O_LDMAC,SL),1,2,"ldmac"),{{RS32,MACREG,E}},{{0x0,0x3,MACREG,RS32,E}} EOP,
+ NEW_SOP(O(O_STMAC,SL),1,2,"stmac"),{{MACREG,RD32,E}},{{0x0,0x2,MACREG,RD32,E}} EOP,
+ NEW_SOP(O(O_LDM,SL),0,6,"ldm.l"),{{RSINC, RS32, E}},{{ 0x0,0x1,IGNORE,0x0,0x6,0xD,0x7,IGNORE,E}}EOP,
+ NEW_SOP(O(O_STM,SL),0,6,"stm.l"),{{RS32, RDDEC, E}},{{0x0,0x1,IGNORE,0x0,0x6,0xD,0xF,IGNORE,E}}EOP,
+ { 0 }
+};
+#else
+extern struct h8_opcode h8_opcodes[] ;
+#endif
+
+
+
+
diff --git a/include/opcode/hppa.h b/include/opcode/hppa.h
new file mode 100644
index 00000000000..30ccb6ccffc
--- /dev/null
+++ b/include/opcode/hppa.h
@@ -0,0 +1,486 @@
+/* Table of opcodes for the PA-RISC.
+ Copyright (C) 1990, 1991, 1993, 1995, 1999 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
+
+GAS/GDB 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 1, or (at your option)
+any later version.
+
+GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+
+/*
+ * Structure of an opcode table entry.
+ */
+
+/* There are two kinds of delay slot nullification: normal which is
+ * controled by the nullification bit, and conditional, which depends
+ * on the direction of the branch and its success or failure.
+ *
+ * NONE is unfortunately #defined in the hiux system include files.
+ * #undef it away.
+ */
+#undef NONE
+struct pa_opcode
+{
+ const char *name;
+ unsigned long int match; /* Bits that must be set... */
+ unsigned long int mask; /* ... in these bits. */
+ char *args;
+ enum pa_arch arch;
+};
+
+
+/*
+ All hppa opcodes are 32 bits.
+
+ The match component is a mask saying which bits must match a
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing one character
+ for each operand of the instruction.
+
+ Bit positions in this description follow HP usage of lsb = 31,
+ "at" is lsb of field.
+
+ In the args field, the following characters must match exactly:
+
+ '+,() '
+
+ In the args field, the following characters are unused:
+
+ ' "#$% *+- ./ :; '
+ ' [\] '
+ ' { } '
+
+ Here are all the characters:
+
+ ' !"#$%&'()*+-,./0123456789:;<=>?@'
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'
+ 'abcdefghijklmnopqrstuvwxyz{|}~'
+
+Kinds of operands:
+ x integer register field at 15.
+ b integer register field at 10.
+ t integer register field at 31.
+ y floating point register field at 31
+ 5 5 bit immediate at 15.
+ s 2 bit space specifier at 17.
+ S 3 bit space specifier at 18.
+ c indexed load completer.
+ C short load and store completer.
+ Y Store Bytes Short completer
+ < non-negated compare/subtract conditions.
+ a compare/subtract conditions
+ d non-negated add conditions
+ & logical instruction conditions
+ U unit instruction conditions
+ > shift/extract/deposit conditions.
+ ~ bvb,bb conditions
+ V 5 bit immediate value at 31
+ i 11 bit immediate value at 31
+ j 14 bit immediate value at 31
+ k 21 bit immediate value at 31
+ n nullification for branch instructions
+ N nullification for spop and copr instructions
+ w 12 bit branch displacement
+ W 17 bit branch displacement (PC relative)
+ z 17 bit branch displacement (just a number, not an address)
+
+Also these:
+
+ p 5 bit shift count at 26 (to support the SHD instruction) encoded as
+ 31-p
+ P 5 bit bit position at 26
+ T 5 bit field length at 31 (encoded as 32-T)
+ A 13 bit immediate at 18 (to support the BREAK instruction)
+ ^ like b, but describes a control register
+ Z System Control Completer (to support LPA, LHA, etc.)
+ D 26 bit immediate at 31 (to support the DIAG instruction)
+
+ f 3 bit Special Function Unit identifier at 25
+ O 20 bit Special Function Unit operation split between 15 bits at 20
+ and 5 bits at 31
+ o 15 bit Special Function Unit operation at 20
+ 2 22 bit Special Function Unit operation split between 17 bits at 20
+ and 5 bits at 31
+ 1 15 bit Special Function Unit operation split between 10 bits at 20
+ and 5 bits at 31
+ 0 10 bit Special Function Unit operation split between 5 bits at 20
+ and 5 bits at 31
+ u 3 bit coprocessor unit identifier at 25
+ F Source Floating Point Operand Format Completer encoded 2 bits at 20
+ I Source Floating Point Operand Format Completer encoded 1 bits at 20
+ (for 0xe format FP instructions)
+ G Destination Floating Point Operand Format Completer encoded 2 bits at 18
+ M Floating-Point Compare Conditions (encoded as 5 bits at 31)
+ ? non-negated/negated compare/subtract conditions.
+ @ non-negated/negated add conditions.
+ ! non-negated add conditions.
+
+ s 2 bit space specifier at 17.
+ b register field at 10.
+ r 5 bit immediate value at 31 (for the break instruction)
+ (very similar to V above, except the value is unsigned instead of
+ low_sign_ext)
+ R 5 bit immediate value at 15 (for the ssm, rsm, probei instructions)
+ (same as r above, except the value is in a different location)
+ Q 5 bit immediate value at 10 (a bit position specified in
+ the bb instruction. It's the same as r above, except the
+ value is in a different location)
+ | shift/extract/deposit conditions when used in a conditional branch
+
+And these (PJH) for PA-89 F.P. registers and instructions:
+
+ v a 't' operand type extended to handle L/R register halves.
+ E a 'b' operand type extended to handle L/R register halves.
+ X an 'x' operand type extended to handle L/R register halves.
+ J a 'b' operand type further extended to handle extra 1.1 registers
+ K a 'x' operand type further extended to handle extra 1.1 registers
+ 4 a variation of the 'b' operand type for 'fmpyadd' and 'fmpysub'
+ 6 a variation of the 'x' operand type for 'fmpyadd' and 'fmpysub'
+ 7 a variation of the 't' operand type for 'fmpyadd' and 'fmpysub'
+ 8 5 bit register field at 20 (used in 'fmpyadd' and 'fmpysub')
+ 9 5 bit register field at 25 (used in 'fmpyadd' and 'fmpysub')
+ H Floating Point Operand Format at 26 for 'fmpyadd' and 'fmpysub'
+ (very similar to 'F')
+*/
+
+
+/* List of characters not to put a space after. Note that
+ "," is included, as the "spopN" operations use literal
+ commas in their completer sections. */
+static const char *const completer_chars = ",CcY<>?!@+&U~FfGHINnOoZMadu|/=0123%e$m}";
+
+/* The order of the opcodes in this table is significant:
+
+ * The assembler requires that all instances of the same mnemonic must be
+ consecutive. If they aren't, the assembler will bomb at runtime.
+
+ * The disassembler should not care about the order of the opcodes. */
+
+static const struct pa_opcode pa_opcodes[] =
+{
+
+
+/* pseudo-instructions */
+
+{ "b", 0xe8000000, 0xffe0e000, "nW", pa10}, /* bl foo,r0 */
+{ "ldi", 0x34000000, 0xffe0c000, "j,x", pa10}, /* ldo val(r0),r */
+{ "comib", 0x84000000, 0xfc000000, "?n5,b,w", pa10}, /* comib{tf}*/
+{ "comb", 0x80000000, 0xfc000000, "?nx,b,w", pa10}, /* comb{tf} */
+{ "addb", 0xa0000000, 0xfc000000, "@nx,b,w", pa10}, /* addb{tf} */
+{ "addib", 0xa4000000, 0xfc000000, "@n5,b,w", pa10}, /* addib{tf}*/
+{ "nop", 0x08000240, 0xffffffff, "", pa10}, /* or 0,0,0 */
+{ "copy", 0x08000240, 0xffe0ffe0, "x,t", pa10}, /* or r,0,t */
+{ "mtsar", 0x01601840, 0xffe0ffff, "x", pa10}, /* mtctl r,cr11 */
+
+/* Loads and Stores for integer registers. */
+{ "ldw", 0x48000000, 0xfc000000, "j(s,b),x", pa10},
+{ "ldw", 0x48000000, 0xfc000000, "j(b),x", pa10},
+{ "ldh", 0x44000000, 0xfc000000, "j(s,b),x", pa10},
+{ "ldh", 0x44000000, 0xfc000000, "j(b),x", pa10},
+{ "ldb", 0x40000000, 0xfc000000, "j(s,b),x", pa10},
+{ "ldb", 0x40000000, 0xfc000000, "j(b),x", pa10},
+{ "stw", 0x68000000, 0xfc000000, "x,j(s,b)", pa10},
+{ "stw", 0x68000000, 0xfc000000, "x,j(b)", pa10},
+{ "sth", 0x64000000, 0xfc000000, "x,j(s,b)", pa10},
+{ "sth", 0x64000000, 0xfc000000, "x,j(b)", pa10},
+{ "stb", 0x60000000, 0xfc000000, "x,j(s,b)", pa10},
+{ "stb", 0x60000000, 0xfc000000, "x,j(b)", pa10},
+{ "ldwm", 0x4c000000, 0xfc000000, "j(s,b),x", pa10},
+{ "ldwm", 0x4c000000, 0xfc000000, "j(b),x", pa10},
+{ "stwm", 0x6c000000, 0xfc000000, "x,j(s,b)", pa10},
+{ "stwm", 0x6c000000, 0xfc000000, "x,j(b)", pa10},
+{ "ldwx", 0x0c000080, 0xfc001fc0, "cx(s,b),t", pa10},
+{ "ldwx", 0x0c000080, 0xfc001fc0, "cx(b),t", pa10},
+{ "ldhx", 0x0c000040, 0xfc001fc0, "cx(s,b),t", pa10},
+{ "ldhx", 0x0c000040, 0xfc001fc0, "cx(b),t", pa10},
+{ "ldbx", 0x0c000000, 0xfc001fc0, "cx(s,b),t", pa10},
+{ "ldbx", 0x0c000000, 0xfc001fc0, "cx(b),t", pa10},
+{ "ldwax", 0x0c000180, 0xfc00dfc0, "cx(b),t", pa10},
+{ "ldcwx", 0x0c0001c0, 0xfc001fc0, "cx(s,b),t", pa10},
+{ "ldcwx", 0x0c0001c0, 0xfc001fc0, "cx(b),t", pa10},
+{ "ldws", 0x0c001080, 0xfc001fc0, "C5(s,b),t", pa10},
+{ "ldws", 0x0c001080, 0xfc001fc0, "C5(b),t", pa10},
+{ "ldhs", 0x0c001040, 0xfc001fc0, "C5(s,b),t", pa10},
+{ "ldhs", 0x0c001040, 0xfc001fc0, "C5(b),t", pa10},
+{ "ldbs", 0x0c001000, 0xfc001fc0, "C5(s,b),t", pa10},
+{ "ldbs", 0x0c001000, 0xfc001fc0, "C5(b),t", pa10},
+{ "ldwas", 0x0c001180, 0xfc00dfc0, "C5(b),t", pa10},
+{ "ldcws", 0x0c0011c0, 0xfc001fc0, "C5(s,b),t", pa10},
+{ "ldcws", 0x0c0011c0, 0xfc001fc0, "C5(b),t", pa10},
+{ "stws", 0x0c001280, 0xfc001fc0, "Cx,V(s,b)", pa10},
+{ "stws", 0x0c001280, 0xfc001fc0, "Cx,V(b)", pa10},
+{ "sths", 0x0c001240, 0xfc001fc0, "Cx,V(s,b)", pa10},
+{ "sths", 0x0c001240, 0xfc001fc0, "Cx,V(b)", pa10},
+{ "stbs", 0x0c001200, 0xfc001fc0, "Cx,V(s,b)", pa10},
+{ "stbs", 0x0c001200, 0xfc001fc0, "Cx,V(b)", pa10},
+{ "stwas", 0x0c001380, 0xfc00dfc0, "Cx,V(b)", pa10},
+{ "stbys", 0x0c001300, 0xfc001fc0, "Yx,V(s,b)", pa10},
+{ "stbys", 0x0c001300, 0xfc001fc0, "Yx,V(b)", pa10},
+
+/* Immediate instructions. */
+{ "ldo", 0x34000000, 0xfc00c000, "j(b),x", pa10},
+{ "ldil", 0x20000000, 0xfc000000, "k,b", pa10},
+{ "addil", 0x28000000, 0xfc000000, "k,b", pa10},
+
+/* Branching instructions. */
+{ "bl", 0xe8000000, 0xfc00e000, "nW,b", pa10},
+{ "gate", 0xe8002000, 0xfc00e000, "nW,b", pa10},
+{ "blr", 0xe8004000, 0xfc00e001, "nx,b", pa10},
+{ "bv", 0xe800c000, 0xfc00fffd, "nx(b)", pa10},
+{ "bv", 0xe800c000, 0xfc00fffd, "n(b)", pa10},
+{ "be", 0xe0000000, 0xfc000000, "nz(S,b)", pa10},
+{ "ble", 0xe4000000, 0xfc000000, "nz(S,b)", pa10},
+{ "movb", 0xc8000000, 0xfc000000, "|nx,b,w", pa10},
+{ "movib", 0xcc000000, 0xfc000000, "|n5,b,w", pa10},
+{ "combt", 0x80000000, 0xfc000000, "<nx,b,w", pa10},
+{ "combf", 0x88000000, 0xfc000000, "<nx,b,w", pa10},
+{ "comibt", 0x84000000, 0xfc000000, "<n5,b,w", pa10},
+{ "comibf", 0x8c000000, 0xfc000000, "<n5,b,w", pa10},
+{ "addbt", 0xa0000000, 0xfc000000, "!nx,b,w", pa10},
+{ "addbf", 0xa8000000, 0xfc000000, "!nx,b,w", pa10},
+{ "addibt", 0xa4000000, 0xfc000000, "!n5,b,w", pa10},
+{ "addibf", 0xac000000, 0xfc000000, "!n5,b,w", pa10},
+{ "bb", 0xc4004000, 0xfc004000, "~nx,Q,w", pa10},
+{ "bvb", 0xc0004000, 0xffe04000, "~nx,w", pa10},
+
+/* Computation Instructions */
+
+{ "add", 0x08000600, 0xfc000fe0, "dx,b,t", pa10},
+{ "addl", 0x08000a00, 0xfc000fe0, "dx,b,t", pa10},
+{ "addo", 0x08000e00, 0xfc000fe0, "dx,b,t", pa10},
+{ "addc", 0x08000700, 0xfc000fe0, "dx,b,t", pa10},
+{ "addco", 0x08000f00, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh1add", 0x08000640, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh1addl", 0x08000a40, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh1addo", 0x08000e40, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh2add", 0x08000680, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh2addl", 0x08000a80, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh2addo", 0x08000e80, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh3add", 0x080006c0, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh3addl", 0x08000ac0, 0xfc000fe0, "dx,b,t", pa10},
+{ "sh3addo", 0x08000ec0, 0xfc000fe0, "dx,b,t", pa10},
+{ "sub", 0x08000400, 0xfc000fe0, "ax,b,t", pa10},
+{ "subo", 0x08000c00, 0xfc000fe0, "ax,b,t", pa10},
+{ "subb", 0x08000500, 0xfc000fe0, "ax,b,t", pa10},
+{ "subbo", 0x08000d00, 0xfc000fe0, "ax,b,t", pa10},
+{ "subt", 0x080004c0, 0xfc000fe0, "ax,b,t", pa10},
+{ "subto", 0x08000cc0, 0xfc000fe0, "ax,b,t", pa10},
+{ "ds", 0x08000440, 0xfc000fe0, "ax,b,t", pa10},
+{ "comclr", 0x08000880, 0xfc000fe0, "ax,b,t", pa10},
+{ "or", 0x08000240, 0xfc000fe0, "&x,b,t", pa10},
+{ "xor", 0x08000280, 0xfc000fe0, "&x,b,t", pa10},
+{ "and", 0x08000200, 0xfc000fe0, "&x,b,t", pa10},
+{ "andcm", 0x08000000, 0xfc000fe0, "&x,b,t", pa10},
+{ "uxor", 0x08000380, 0xfc000fe0, "Ux,b,t", pa10},
+{ "uaddcm", 0x08000980, 0xfc000fe0, "Ux,b,t", pa10},
+{ "uaddcmt", 0x080009c0, 0xfc000fe0, "Ux,b,t", pa10},
+{ "dcor", 0x08000b80, 0xfc1f0fe0, "Ub,t", pa10},
+{ "idcor", 0x08000bc0, 0xfc1f0fe0, "Ub,t", pa10},
+{ "addi", 0xb4000000, 0xfc000800, "di,b,x", pa10},
+{ "addio", 0xb4000800, 0xfc000800, "di,b,x", pa10},
+{ "addit", 0xb0000000, 0xfc000800, "di,b,x", pa10},
+{ "addito", 0xb0000800, 0xfc000800, "di,b,x", pa10},
+{ "subi", 0x94000000, 0xfc000800, "ai,b,x", pa10},
+{ "subio", 0x94000800, 0xfc000800, "ai,b,x", pa10},
+{ "comiclr", 0x90000000, 0xfc000800, "ai,b,x", pa10},
+
+/* Extract and Deposit Instructions */
+
+{ "vshd", 0xd0000000, 0xfc001fe0, ">x,b,t", pa10},
+{ "shd", 0xd0000800, 0xfc001c00, ">x,b,p,t", pa10},
+{ "vextru", 0xd0001000, 0xfc001fe0, ">b,T,x", pa10},
+{ "vextrs", 0xd0001400, 0xfc001fe0, ">b,T,x", pa10},
+{ "extru", 0xd0001800, 0xfc001c00, ">b,P,T,x", pa10},
+{ "extrs", 0xd0001c00, 0xfc001c00, ">b,P,T,x", pa10},
+{ "zvdep", 0xd4000000, 0xfc001fe0, ">x,T,b", pa10},
+{ "vdep", 0xd4000400, 0xfc001fe0, ">x,T,b", pa10},
+{ "zdep", 0xd4000800, 0xfc001c00, ">x,p,T,b", pa10},
+{ "dep", 0xd4000c00, 0xfc001c00, ">x,p,T,b", pa10},
+{ "zvdepi", 0xd4001000, 0xfc001fe0, ">5,T,b", pa10},
+{ "vdepi", 0xd4001400, 0xfc001fe0, ">5,T,b", pa10},
+{ "zdepi", 0xd4001800, 0xfc001c00, ">5,p,T,b", pa10},
+{ "depi", 0xd4001c00, 0xfc001c00, ">5,p,T,b", pa10},
+
+/* System Control Instructions */
+
+{ "break", 0x00000000, 0xfc001fe0, "r,A", pa10},
+{ "rfi", 0x00000c00, 0xffffffff, "", pa10},
+{ "rfir", 0x00000ca0, 0xffffffff, "", pa11},
+{ "ssm", 0x00000d60, 0xffe0ffe0, "R,t", pa10},
+{ "rsm", 0x00000e60, 0xffe0ffe0, "R,t", pa10},
+{ "mtsm", 0x00001860, 0xffe0ffff, "x", pa10},
+{ "ldsid", 0x000010a0, 0xfc1f3fe0, "(s,b),t", pa10},
+{ "ldsid", 0x000010a0, 0xfc1f3fe0, "(b),t", pa10},
+{ "mtsp", 0x00001820, 0xffe01fff, "x,S", pa10},
+{ "mtctl", 0x00001840, 0xfc00ffff, "x,^", pa10},
+{ "mfsp", 0x000004a0, 0xffff1fe0, "S,t", pa10},
+{ "mfctl", 0x000008a0, 0xfc1fffe0, "^,t", pa10},
+{ "sync", 0x00000400, 0xffffffff, "", pa10},
+{ "syncdma", 0x00100400, 0xffffffff, "", pa10},
+{ "prober", 0x04001180, 0xfc003fe0, "(s,b),x,t", pa10},
+{ "prober", 0x04001180, 0xfc003fe0, "(b),x,t", pa10},
+{ "proberi", 0x04003180, 0xfc003fe0, "(s,b),R,t", pa10},
+{ "proberi", 0x04003180, 0xfc003fe0, "(b),R,t", pa10},
+{ "probew", 0x040011c0, 0xfc003fe0, "(s,b),x,t", pa10},
+{ "probew", 0x040011c0, 0xfc003fe0, "(b),x,t", pa10},
+{ "probewi", 0x040031c0, 0xfc003fe0, "(s,b),R,t", pa10},
+{ "probewi", 0x040031c0, 0xfc003fe0, "(b),R,t", pa10},
+{ "lpa", 0x04001340, 0xfc003fc0, "Zx(s,b),t", pa10},
+{ "lpa", 0x04001340, 0xfc003fc0, "Zx(b),t", pa10},
+{ "lha", 0x04001300, 0xfc003fc0, "Zx(s,b),t", pa10},
+{ "lha", 0x04001300, 0xfc003fc0, "Zx(b),t", pa10},
+{ "lci", 0x04001300, 0xfc003fe0, "x(s,b),t", pa10},
+{ "lci", 0x04001300, 0xfc003fe0, "x(b),t", pa10},
+{ "pdtlb", 0x04001200, 0xfc003fdf, "Zx(s,b)", pa10},
+{ "pdtlb", 0x04001200, 0xfc003fdf, "Zx(b)", pa10},
+{ "pitlb", 0x04000200, 0xfc001fdf, "Zx(S,b)", pa10},
+{ "pitlb", 0x04000200, 0xfc001fdf, "Zx(b)", pa10},
+{ "pdtlbe", 0x04001240, 0xfc003fdf, "Zx(s,b)", pa10},
+{ "pdtlbe", 0x04001240, 0xfc003fdf, "Zx(b)", pa10},
+{ "pitlbe", 0x04000240, 0xfc001fdf, "Zx(S,b)", pa10},
+{ "pitlbe", 0x04000240, 0xfc001fdf, "Zx(b)", pa10},
+{ "idtlba", 0x04001040, 0xfc003fff, "x,(s,b)", pa10},
+{ "idtlba", 0x04001040, 0xfc003fff, "x,(b)", pa10},
+{ "iitlba", 0x04000040, 0xfc001fff, "x,(S,b)", pa10},
+{ "iitlba", 0x04000040, 0xfc001fff, "x,(b)", pa10},
+{ "idtlbp", 0x04001000, 0xfc003fff, "x,(s,b)", pa10},
+{ "idtlbp", 0x04001000, 0xfc003fff, "x,(b)", pa10},
+{ "iitlbp", 0x04000000, 0xfc001fff, "x,(S,b)", pa10},
+{ "iitlbp", 0x04000000, 0xfc001fff, "x,(b)", pa10},
+{ "pdc", 0x04001380, 0xfc003fdf, "Zx(s,b)", pa10},
+{ "pdc", 0x04001380, 0xfc003fdf, "Zx(b)", pa10},
+{ "fdc", 0x04001280, 0xfc003fdf, "Zx(s,b)", pa10},
+{ "fdc", 0x04001280, 0xfc003fdf, "Zx(b)", pa10},
+{ "fic", 0x04000280, 0xfc001fdf, "Zx(S,b)", pa10},
+{ "fic", 0x04000280, 0xfc001fdf, "Zx(b)", pa10},
+{ "fdce", 0x040012c0, 0xfc003fdf, "Zx(s,b)", pa10},
+{ "fdce", 0x040012c0, 0xfc003fdf, "Zx(b)", pa10},
+{ "fice", 0x040002c0, 0xfc001fdf, "Zx(S,b)", pa10},
+{ "fice", 0x040002c0, 0xfc001fdf, "Zx(b)", pa10},
+{ "diag", 0x14000000, 0xfc000000, "D", pa10},
+
+/* gfw and gfr are not in the HP PA 1.1 manual, but they are in either
+ the Timex FPU or the Mustang ERS (not sure which) manual. */
+{ "gfw", 0x04001680, 0xfc003fdf, "Zx(s,b)", pa11},
+{ "gfw", 0x04001680, 0xfc003fdf, "Zx(b)", pa11},
+{ "gfr", 0x04001a80, 0xfc003fdf, "Zx(s,b)", pa11},
+{ "gfr", 0x04001a80, 0xfc003fdf, "Zx(b)", pa11},
+
+/* Floating Point Coprocessor Instructions */
+
+{ "fldwx", 0x24000000, 0xfc001f80, "cx(s,b),v", pa10},
+{ "fldwx", 0x24000000, 0xfc001f80, "cx(b),v", pa10},
+{ "flddx", 0x2c000000, 0xfc001fc0, "cx(s,b),y", pa10},
+{ "flddx", 0x2c000000, 0xfc001fc0, "cx(b),y", pa10},
+{ "fstwx", 0x24000200, 0xfc001f80, "cv,x(s,b)", pa10},
+{ "fstwx", 0x24000200, 0xfc001f80, "cv,x(b)", pa10},
+{ "fstdx", 0x2c000200, 0xfc001fc0, "cy,x(s,b)", pa10},
+{ "fstdx", 0x2c000200, 0xfc001fc0, "cy,x(b)", pa10},
+{ "fstqx", 0x3c000200, 0xfc001fc0, "cy,x(s,b)", pa10},
+{ "fstqx", 0x3c000200, 0xfc001fc0, "cy,x(b)", pa10},
+{ "fldws", 0x24001000, 0xfc001f80, "C5(s,b),v", pa10},
+{ "fldws", 0x24001000, 0xfc001f80, "C5(b),v", pa10},
+{ "fldds", 0x2c001000, 0xfc001fc0, "C5(s,b),y", pa10},
+{ "fldds", 0x2c001000, 0xfc001fc0, "C5(b),y", pa10},
+{ "fstws", 0x24001200, 0xfc001f80, "Cv,5(s,b)", pa10},
+{ "fstws", 0x24001200, 0xfc001f80, "Cv,5(b)", pa10},
+{ "fstds", 0x2c001200, 0xfc001fc0, "Cy,5(s,b)", pa10},
+{ "fstds", 0x2c001200, 0xfc001fc0, "Cy,5(b)", pa10},
+{ "fstqs", 0x3c001200, 0xfc001fc0, "Cy,5(s,b)", pa10},
+{ "fstqs", 0x3c001200, 0xfc001fc0, "Cy,5(b)", pa10},
+{ "fadd", 0x30000600, 0xfc00e7e0, "FE,X,v", pa10},
+{ "fadd", 0x38000600, 0xfc00e720, "IJ,K,v", pa10},
+{ "fsub", 0x30002600, 0xfc00e7e0, "FE,X,v", pa10},
+{ "fsub", 0x38002600, 0xfc00e720, "IJ,K,v", pa10},
+{ "fmpy", 0x30004600, 0xfc00e7e0, "FE,X,v", pa10},
+{ "fmpy", 0x38004600, 0xfc00e720, "IJ,K,v", pa10},
+{ "fdiv", 0x30006600, 0xfc00e7e0, "FE,X,v", pa10},
+{ "fdiv", 0x38006600, 0xfc00e720, "IJ,K,v", pa10},
+{ "fsqrt", 0x30008000, 0xfc1fe7e0, "FE,v", pa10},
+{ "fsqrt", 0x38008000, 0xfc1fe720, "FJ,v", pa10},
+{ "fabs", 0x30006000, 0xfc1fe7e0, "FE,v", pa10},
+{ "fabs", 0x38006000, 0xfc1fe720, "FJ,v", pa10},
+{ "frem", 0x30008600, 0xfc00e7e0, "FE,X,v", pa10},
+{ "frem", 0x38008600, 0xfc00e720, "FJ,K,v", pa10},
+{ "frnd", 0x3000a000, 0xfc1fe7e0, "FE,v", pa10},
+{ "frnd", 0x3800a000, 0xfc1fe720, "FJ,v", pa10},
+{ "fcpy", 0x30004000, 0xfc1fe7e0, "FE,v", pa10},
+{ "fcpy", 0x38004000, 0xfc1fe720, "FJ,v", pa10},
+{ "fcnvff", 0x30000200, 0xfc1f87e0, "FGE,v", pa10},
+{ "fcnvff", 0x38000200, 0xfc1f8720, "FGJ,v", pa10},
+{ "fcnvxf", 0x30008200, 0xfc1f87e0, "FGE,v", pa10},
+{ "fcnvxf", 0x38008200, 0xfc1f8720, "FGJ,v", pa10},
+{ "fcnvfx", 0x30010200, 0xfc1f87e0, "FGE,v", pa10},
+{ "fcnvfx", 0x38010200, 0xfc1f8720, "FGJ,v", pa10},
+{ "fcnvfxt", 0x30018200, 0xfc1f87e0, "FGE,v", pa10},
+{ "fcnvfxt", 0x38018200, 0xfc1f8720, "FGJ,v", pa10},
+{ "fmpyfadd", 0xb8000000, 0xfc000020, "FE,X,3,v", pa20},
+{ "fmpynfadd", 0xb8000020, 0xfc000020, "FE,X,3,v", pa20},
+{ "fneg", 0x3000c000, 0xfc1fe7e0, "FE,v", pa20},
+{ "fneg", 0x3800c000, 0xfc1fe720, "FJ,v", pa20},
+{ "fnegabs", 0x3000e000, 0xfc1fe7e0, "FE,v", pa20},
+{ "fnegabs", 0x3800e000, 0xfc1fe720, "FJ,v", pa20},
+{ "fcmp", 0x30000400, 0xfc00e7e0, "FME,X", pa10},
+{ "fcmp", 0x38000400, 0xfc00e720, "IMJ,K", pa10},
+{ "xmpyu", 0x38004700, 0xfc00e720, "E,X,v", pa11},
+{ "fmpyadd", 0x18000000, 0xfc000000, "H4,6,7,9,8", pa11},
+{ "fmpysub", 0x98000000, 0xfc000000, "H4,6,7,9,8", pa11},
+{ "ftest", 0x30002420, 0xffffffff, "", pa10},
+{ "fid", 0x30000000, 0xffffffff, "", pa11},
+
+
+/* Assist Instructions */
+
+{ "spop0", 0x10000000, 0xfc000600, "f,ON", pa10},
+{ "spop1", 0x10000200, 0xfc000600, "f,oNt", pa10},
+{ "spop2", 0x10000400, 0xfc000600, "f,1Nb", pa10},
+{ "spop3", 0x10000600, 0xfc000600, "f,0Nx,b", pa10},
+{ "copr", 0x30000000, 0xfc000000, "u,2N", pa10},
+{ "cldwx", 0x24000000, 0xfc001e00, "ucx(s,b),t", pa10},
+{ "cldwx", 0x24000000, 0xfc001e00, "ucx(b),t", pa10},
+{ "clddx", 0x2c000000, 0xfc001e00, "ucx(s,b),t", pa10},
+{ "clddx", 0x2c000000, 0xfc001e00, "ucx(b),t", pa10},
+{ "cstwx", 0x24000200, 0xfc001e00, "uct,x(s,b)", pa10},
+{ "cstwx", 0x24000200, 0xfc001e00, "uct,x(b)", pa10},
+{ "cstdx", 0x2c000200, 0xfc001e00, "uct,x(s,b)", pa10},
+{ "cstdx", 0x2c000200, 0xfc001e00, "uct,x(b)", pa10},
+{ "cldws", 0x24001000, 0xfc001e00, "uC5(s,b),t", pa10},
+{ "cldws", 0x24001000, 0xfc001e00, "uC5(b),t", pa10},
+{ "cldds", 0x2c001000, 0xfc001e00, "uC5(s,b),t", pa10},
+{ "cldds", 0x2c001000, 0xfc001e00, "uC5(b),t", pa10},
+{ "cstws", 0x24001200, 0xfc001e00, "uCt,5(s,b)", pa10},
+{ "cstws", 0x24001200, 0xfc001e00, "uCt,5(b)", pa10},
+{ "cstds", 0x2c001200, 0xfc001e00, "uCt,5(s,b)", pa10},
+{ "cstds", 0x2c001200, 0xfc001e00, "uCt,5(b)", pa10},
+};
+
+#define NUMOPCODES ((sizeof pa_opcodes)/(sizeof pa_opcodes[0]))
+
+/* SKV 12/18/92. Added some denotations for various operands. */
+
+#define PA_IMM11_AT_31 'i'
+#define PA_IMM14_AT_31 'j'
+#define PA_IMM21_AT_31 'k'
+#define PA_DISP12 'w'
+#define PA_DISP17 'W'
+
+#define N_HPPA_OPERAND_FORMATS 5
diff --git a/include/opcode/i386.h b/include/opcode/i386.h
new file mode 100644
index 00000000000..ef8fece15e1
--- /dev/null
+++ b/include/opcode/i386.h
@@ -0,0 +1,1063 @@
+/* opcode/i386.h -- Intel 80386 opcode table
+ Copyright 1989, 91, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation.
+
+This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* The UnixWare assembler, and probably other AT&T derived ix86 Unix
+ assemblers, generate floating point instructions with reversed
+ source and destination registers in certain cases. Unfortunately,
+ gcc and possibly many other programs use this reversed syntax, so
+ we're stuck with it.
+
+ eg. `fsub %st(3),%st' results in st <- st - st(3) as expected, but
+ `fsub %st,%st(3)' results in st(3) <- st - st(3), rather than
+ the expected st(3) <- st(3) - st !
+
+ This happens with all the non-commutative arithmetic floating point
+ operations with two register operands, where the source register is
+ %st, and destination register is %st(i). Look for FloatDR below. */
+
+#ifndef UNIXWARE_COMPAT
+/* Set non-zero for broken, compatible instructions. Set to zero for
+ non-broken opcodes at your peril. gcc generates UnixWare
+ compatible instructions. */
+#define UNIXWARE_COMPAT 1
+#endif
+
+
+static const template i386_optab[] = {
+
+#define X None
+#define ReverseModrm (ReverseRegRegmem|Modrm)
+#define NoSuf (No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf)
+#define b_Suf (No_wSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf)
+#define w_Suf (No_bSuf|No_lSuf|No_sSuf|No_dSuf|No_xSuf)
+#define l_Suf (No_bSuf|No_wSuf|No_sSuf|No_dSuf|No_xSuf)
+#define d_Suf (No_bSuf|No_wSuf|No_sSuf|No_lSuf|No_xSuf)
+#define x_Suf (No_bSuf|No_wSuf|No_sSuf|No_lSuf|No_dSuf)
+#define bw_Suf (No_lSuf|No_sSuf|No_dSuf|No_xSuf)
+#define bl_Suf (No_wSuf|No_sSuf|No_dSuf|No_xSuf)
+#define wl_Suf (No_bSuf|No_sSuf|No_dSuf|No_xSuf)
+#define sl_Suf (No_bSuf|No_wSuf|No_dSuf|No_xSuf)
+#define sld_Suf (No_bSuf|No_wSuf|No_xSuf)
+#define sldx_Suf (No_bSuf|No_wSuf)
+#define bwl_Suf (No_sSuf|No_dSuf|No_xSuf)
+#define bwld_Suf (No_sSuf|No_xSuf)
+#define FP (NoSuf|IgnoreSize)
+#define l_FP (l_Suf|IgnoreSize)
+#define d_FP (d_Suf|IgnoreSize)
+#define x_FP (x_Suf|IgnoreSize)
+#define sl_FP (sl_Suf|IgnoreSize)
+#define sld_FP (sld_Suf|IgnoreSize)
+#define sldx_FP (sldx_Suf|IgnoreSize)
+#if UNIXWARE_COMPAT
+#define FloatDR FloatD
+#else
+#define FloatDR (FloatD|FloatR)
+#endif
+
+/* move instructions */
+#define MOV_AX_DISP32 0xa0
+{ "mov", 2, 0xa0, X, bwl_Suf|D|W, { Disp16|Disp32, Acc, 0 } },
+{ "mov", 2, 0x88, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0 } },
+{ "mov", 2, 0xb0, X, bwl_Suf|W|ShortForm, { Imm, Reg, 0 } },
+{ "mov", 2, 0xc6, X, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0 } },
+/* The next two instructions accept WordReg so that a segment register
+ can be copied to a 32 bit register, and vice versa, without using a
+ size prefix. When moving to a 32 bit register, the upper 16 bits
+ are set to an implementation defined value (on the Pentium Pro,
+ the implementation defined value is zero). */
+{ "mov", 2, 0x8c, X, wl_Suf|Modrm, { SReg3|SReg2, WordReg|WordMem, 0 } },
+{ "mov", 2, 0x8e, X, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg3|SReg2, 0 } },
+/* move to/from control debug registers */
+{ "mov", 2, 0x0f20, X, l_Suf|D|Modrm|IgnoreSize, { Control, Reg32, 0} },
+{ "mov", 2, 0x0f21, X, l_Suf|D|Modrm|IgnoreSize, { Debug, Reg32, 0} },
+{ "mov", 2, 0x0f24, X, l_Suf|D|Modrm|IgnoreSize, { Test, Reg32, 0} },
+
+/* move with sign extend */
+/* "movsbl" & "movsbw" must not be unified into "movsb" to avoid
+ conflict with the "movs" string move instruction. */
+{"movsbl", 2, 0x0fbe, X, NoSuf|ReverseModrm, { Reg8|ByteMem, Reg32, 0} },
+{"movsbw", 2, 0x0fbe, X, NoSuf|ReverseModrm, { Reg8|ByteMem, Reg16, 0} },
+{"movswl", 2, 0x0fbf, X, NoSuf|ReverseModrm, { Reg16|ShortMem, Reg32, 0} },
+/* Intel Syntax */
+{"movsx", 2, 0x0fbf, X, w_Suf|ReverseModrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} },
+{"movsx", 2, 0x0fbe, X, b_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} },
+
+/* move with zero extend */
+{"movzb", 2, 0x0fb6, X, wl_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} },
+{"movzwl", 2, 0x0fb7, X, NoSuf|ReverseModrm, { Reg16|ShortMem, Reg32, 0} },
+/* Intel Syntax */
+{"movzx", 2, 0x0fb7, X, w_Suf|ReverseModrm|IgnoreSize, { Reg16|ShortMem, Reg32, 0} },
+{"movzx", 2, 0x0fb6, X, b_Suf|ReverseModrm, { Reg8|ByteMem, WordReg, 0} },
+
+/* push instructions */
+{"push", 1, 0x50, X, wl_Suf|ShortForm, { WordReg,0,0 } },
+{"push", 1, 0xff, 6, wl_Suf|Modrm, { WordReg|WordMem, 0, 0 } },
+{"push", 1, 0x6a, X, wl_Suf, { Imm8S, 0, 0} },
+{"push", 1, 0x68, X, wl_Suf, { Imm16|Imm32, 0, 0} },
+{"push", 1, 0x06, X, wl_Suf|Seg2ShortForm, { SReg2,0,0 } },
+{"push", 1, 0x0fa0, X, wl_Suf|Seg3ShortForm, { SReg3,0,0 } },
+/* push all */
+{"pusha", 0, 0x60, X, wl_Suf, { 0, 0, 0 } },
+
+/* pop instructions */
+{"pop", 1, 0x58, X, wl_Suf|ShortForm, { WordReg,0,0 } },
+{"pop", 1, 0x8f, 0, wl_Suf|Modrm, { WordReg|WordMem, 0, 0 } },
+#define POP_SEG_SHORT 0x07
+{"pop", 1, 0x07, X, wl_Suf|Seg2ShortForm, { SReg2,0,0 } },
+{"pop", 1, 0x0fa1, X, wl_Suf|Seg3ShortForm, { SReg3,0,0 } },
+/* pop all */
+{"popa", 0, 0x61, X, wl_Suf, { 0, 0, 0 } },
+
+/* xchg exchange instructions
+ xchg commutes: we allow both operand orders */
+{"xchg", 2, 0x90, X, wl_Suf|ShortForm, { WordReg, Acc, 0 } },
+{"xchg", 2, 0x90, X, wl_Suf|ShortForm, { Acc, WordReg, 0 } },
+{"xchg", 2, 0x86, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
+{"xchg", 2, 0x86, X, bwl_Suf|W|Modrm, { Reg|AnyMem, Reg, 0 } },
+
+/* in/out from ports */
+{"in", 2, 0xe4, X, bwl_Suf|W, { Imm8, Acc, 0 } },
+{"in", 2, 0xec, X, bwl_Suf|W, { InOutPortReg, Acc, 0 } },
+{"in", 1, 0xe4, X, bwl_Suf|W, { Imm8, 0, 0 } },
+{"in", 1, 0xec, X, bwl_Suf|W, { InOutPortReg, 0, 0 } },
+{"out", 2, 0xe6, X, bwl_Suf|W, { Acc, Imm8, 0 } },
+{"out", 2, 0xee, X, bwl_Suf|W, { Acc, InOutPortReg, 0 } },
+{"out", 1, 0xe6, X, bwl_Suf|W, { Imm8, 0, 0 } },
+{"out", 1, 0xee, X, bwl_Suf|W, { InOutPortReg, 0, 0 } },
+
+/* load effective address */
+{"lea", 2, 0x8d, X, wl_Suf|Modrm, { WordMem, WordReg, 0 } },
+
+/* load segment registers from memory */
+{"lds", 2, 0xc5, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
+{"les", 2, 0xc4, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
+{"lfs", 2, 0x0fb4, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
+{"lgs", 2, 0x0fb5, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
+{"lss", 2, 0x0fb2, X, wl_Suf|Modrm, { WordMem, WordReg, 0} },
+
+/* flags register instructions */
+{"clc", 0, 0xf8, X, NoSuf, { 0, 0, 0} },
+{"cld", 0, 0xfc, X, NoSuf, { 0, 0, 0} },
+{"cli", 0, 0xfa, X, NoSuf, { 0, 0, 0} },
+{"clts", 0, 0x0f06, X, NoSuf, { 0, 0, 0} },
+{"cmc", 0, 0xf5, X, NoSuf, { 0, 0, 0} },
+{"lahf", 0, 0x9f, X, NoSuf, { 0, 0, 0} },
+{"sahf", 0, 0x9e, X, NoSuf, { 0, 0, 0} },
+{"pushf", 0, 0x9c, X, wl_Suf, { 0, 0, 0} },
+{"popf", 0, 0x9d, X, wl_Suf, { 0, 0, 0} },
+{"stc", 0, 0xf9, X, NoSuf, { 0, 0, 0} },
+{"std", 0, 0xfd, X, NoSuf, { 0, 0, 0} },
+{"sti", 0, 0xfb, X, NoSuf, { 0, 0, 0} },
+
+/* arithmetic */
+{"add", 2, 0x00, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"add", 2, 0x83, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"add", 2, 0x04, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"add", 2, 0x80, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"inc", 1, 0x40, X, wl_Suf|ShortForm, { WordReg, 0, 0} },
+{"inc", 1, 0xfe, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"sub", 2, 0x28, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"sub", 2, 0x83, 5, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"sub", 2, 0x2c, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"sub", 2, 0x80, 5, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"dec", 1, 0x48, X, wl_Suf|ShortForm, { WordReg, 0, 0} },
+{"dec", 1, 0xfe, 1, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"sbb", 2, 0x18, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"sbb", 2, 0x83, 3, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"sbb", 2, 0x1c, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"sbb", 2, 0x80, 3, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"cmp", 2, 0x38, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"cmp", 2, 0x83, 7, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"cmp", 2, 0x3c, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"cmp", 2, 0x80, 7, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"test", 2, 0x84, X, bwl_Suf|W|Modrm, { Reg|AnyMem, Reg, 0} },
+{"test", 2, 0x84, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"test", 2, 0xa8, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"test", 2, 0xf6, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"and", 2, 0x20, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"and", 2, 0x83, 4, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"and", 2, 0x24, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"and", 2, 0x80, 4, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"or", 2, 0x08, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"or", 2, 0x83, 1, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"or", 2, 0x0c, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"or", 2, 0x80, 1, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"xor", 2, 0x30, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"xor", 2, 0x83, 6, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"xor", 2, 0x34, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"xor", 2, 0x80, 6, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+/* iclr with 1 operand is really xor with 2 operands. */
+{"clr", 1, 0x30, X, bwl_Suf|W|Modrm|regKludge, { Reg, 0, 0 } },
+
+{"adc", 2, 0x10, X, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} },
+{"adc", 2, 0x83, 2, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} },
+{"adc", 2, 0x14, X, bwl_Suf|W, { Imm, Acc, 0} },
+{"adc", 2, 0x80, 2, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} },
+
+{"neg", 1, 0xf6, 3, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+{"not", 1, 0xf6, 2, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"aaa", 0, 0x37, X, NoSuf, { 0, 0, 0} },
+{"aas", 0, 0x3f, X, NoSuf, { 0, 0, 0} },
+{"daa", 0, 0x27, X, NoSuf, { 0, 0, 0} },
+{"das", 0, 0x2f, X, NoSuf, { 0, 0, 0} },
+{"aad", 0, 0xd50a, X, NoSuf, { 0, 0, 0} },
+{"aad", 1, 0xd5, X, NoSuf, { Imm8S, 0, 0} },
+{"aam", 0, 0xd40a, X, NoSuf, { 0, 0, 0} },
+{"aam", 1, 0xd4, X, NoSuf, { Imm8S, 0, 0} },
+
+/* conversion insns */
+/* conversion: intel naming */
+{"cbw", 0, 0x98, X, NoSuf|Size16, { 0, 0, 0} },
+{"cwde", 0, 0x98, X, NoSuf|Size32, { 0, 0, 0} },
+{"cwd", 0, 0x99, X, NoSuf|Size16, { 0, 0, 0} },
+{"cdq", 0, 0x99, X, NoSuf|Size32, { 0, 0, 0} },
+/* att naming */
+{"cbtw", 0, 0x98, X, NoSuf|Size16, { 0, 0, 0} },
+{"cwtl", 0, 0x98, X, NoSuf|Size32, { 0, 0, 0} },
+{"cwtd", 0, 0x99, X, NoSuf|Size16, { 0, 0, 0} },
+{"cltd", 0, 0x99, X, NoSuf|Size32, { 0, 0, 0} },
+
+/* Warning! the mul/imul (opcode 0xf6) must only have 1 operand! They are
+ expanding 64-bit multiplies, and *cannot* be selected to accomplish
+ 'imul %ebx, %eax' (opcode 0x0faf must be used in this case)
+ These multiplies can only be selected with single operand forms. */
+{"mul", 1, 0xf6, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+{"imul", 1, 0xf6, 5, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+{"imul", 2, 0x0faf, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"imul", 3, 0x6b, X, wl_Suf|ReverseModrm, { Imm8S, WordReg|WordMem, WordReg} },
+{"imul", 3, 0x69, X, wl_Suf|ReverseModrm, { Imm16|Imm32, WordReg|WordMem, WordReg} },
+/* imul with 2 operands mimics imul with 3 by putting the register in
+ both i.rm.reg & i.rm.regmem fields. regKludge enables this
+ transformation. */
+{"imul", 2, 0x6b, X, wl_Suf|Modrm|regKludge,{ Imm8S, WordReg, 0} },
+{"imul", 2, 0x69, X, wl_Suf|Modrm|regKludge,{ Imm16|Imm32, WordReg, 0} },
+
+{"div", 1, 0xf6, 6, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+{"div", 2, 0xf6, 6, bwl_Suf|W|Modrm, { Reg|AnyMem, Acc, 0} },
+{"idiv", 1, 0xf6, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+{"idiv", 2, 0xf6, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, Acc, 0} },
+
+{"rol", 2, 0xd0, 0, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"rol", 2, 0xc0, 0, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"rol", 2, 0xd2, 0, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"rol", 1, 0xd0, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"ror", 2, 0xd0, 1, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"ror", 2, 0xc0, 1, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"ror", 2, 0xd2, 1, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"ror", 1, 0xd0, 1, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"rcl", 2, 0xd0, 2, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"rcl", 2, 0xc0, 2, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"rcl", 2, 0xd2, 2, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"rcl", 1, 0xd0, 2, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"rcr", 2, 0xd0, 3, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"rcr", 2, 0xc0, 3, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"rcr", 2, 0xd2, 3, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"rcr", 1, 0xd0, 3, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"sal", 2, 0xd0, 4, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"sal", 2, 0xc0, 4, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"sal", 2, 0xd2, 4, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"sal", 1, 0xd0, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+{"shl", 2, 0xd0, 4, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"shl", 2, 0xc0, 4, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"shl", 2, 0xd2, 4, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"shl", 1, 0xd0, 4, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"shld", 3, 0x0fa4, X, wl_Suf|Modrm, { Imm8, WordReg, WordReg|WordMem} },
+{"shld", 3, 0x0fa5, X, wl_Suf|Modrm, { ShiftCount, WordReg, WordReg|WordMem} },
+{"shld", 2, 0x0fa5, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
+
+{"shr", 2, 0xd0, 5, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"shr", 2, 0xc0, 5, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"shr", 2, 0xd2, 5, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"shr", 1, 0xd0, 5, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+{"shrd", 3, 0x0fac, X, wl_Suf|Modrm, { Imm8, WordReg, WordReg|WordMem} },
+{"shrd", 3, 0x0fad, X, wl_Suf|Modrm, { ShiftCount, WordReg, WordReg|WordMem} },
+{"shrd", 2, 0x0fad, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
+
+{"sar", 2, 0xd0, 7, bwl_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} },
+{"sar", 2, 0xc0, 7, bwl_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} },
+{"sar", 2, 0xd2, 7, bwl_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} },
+{"sar", 1, 0xd0, 7, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} },
+
+/* control transfer instructions */
+{"call", 1, 0xe8, X, wl_Suf|JumpDword, { Disp16|Disp32, 0, 0} },
+{"call", 1, 0xff, 2, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} },
+/* Intel Syntax */
+{"call", 2, 0x9a, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
+{"lcall", 2, 0x9a, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
+{"lcall", 1, 0xff, 3, wl_Suf|Modrm, { WordMem, 0, 0} },
+
+#define JUMP_PC_RELATIVE 0xeb
+{"jmp", 1, 0xeb, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jmp", 1, 0xff, 4, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} },
+/* Intel Syntax */
+{"jmp", 2, 0xea, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
+{"jmp", 1, 0xff, 5, wl_Suf|Modrm, { WordMem, 0, 0} },
+{"ljmp", 2, 0xea, X, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} },
+{"ljmp", 1, 0xff, 5, wl_Suf|Modrm, { WordMem, 0, 0} },
+
+{"ret", 0, 0xc3, X, wl_Suf, { 0, 0, 0} },
+{"ret", 1, 0xc2, X, wl_Suf, { Imm16, 0, 0} },
+{"lret", 0, 0xcb, X, wl_Suf, { 0, 0, 0} },
+{"lret", 1, 0xca, X, wl_Suf, { Imm16, 0, 0} },
+{"enter", 2, 0xc8, X, wl_Suf, { Imm16, Imm8, 0} },
+{"leave", 0, 0xc9, X, wl_Suf, { 0, 0, 0} },
+
+/* conditional jumps */
+{"jo", 1, 0x70, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jno", 1, 0x71, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jb", 1, 0x72, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jc", 1, 0x72, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnae", 1, 0x72, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnb", 1, 0x73, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnc", 1, 0x73, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jae", 1, 0x73, X, NoSuf|Jump, { Disp, 0, 0} },
+{"je", 1, 0x74, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jz", 1, 0x74, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jne", 1, 0x75, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnz", 1, 0x75, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jbe", 1, 0x76, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jna", 1, 0x76, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnbe", 1, 0x77, X, NoSuf|Jump, { Disp, 0, 0} },
+{"ja", 1, 0x77, X, NoSuf|Jump, { Disp, 0, 0} },
+{"js", 1, 0x78, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jns", 1, 0x79, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jp", 1, 0x7a, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jpe", 1, 0x7a, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnp", 1, 0x7b, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jpo", 1, 0x7b, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jl", 1, 0x7c, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnge", 1, 0x7c, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnl", 1, 0x7d, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jge", 1, 0x7d, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jle", 1, 0x7e, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jng", 1, 0x7e, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jnle", 1, 0x7f, X, NoSuf|Jump, { Disp, 0, 0} },
+{"jg", 1, 0x7f, X, NoSuf|Jump, { Disp, 0, 0} },
+
+/* jcxz vs. jecxz is chosen on the basis of the address size prefix. */
+{"jcxz", 1, 0xe3, X, NoSuf|JumpByte|Size16, { Disp, 0, 0} },
+{"jecxz", 1, 0xe3, X, NoSuf|JumpByte|Size32, { Disp, 0, 0} },
+
+/* The loop instructions also use the address size prefix to select
+ %cx rather than %ecx for the loop count, so the `w' form of these
+ instructions emit an address size prefix rather than a data size
+ prefix. */
+{"loop", 1, 0xe2, X, wl_Suf|JumpByte, { Disp, 0, 0} },
+{"loopz", 1, 0xe1, X, wl_Suf|JumpByte, { Disp, 0, 0} },
+{"loope", 1, 0xe1, X, wl_Suf|JumpByte, { Disp, 0, 0} },
+{"loopnz", 1, 0xe0, X, wl_Suf|JumpByte, { Disp, 0, 0} },
+{"loopne", 1, 0xe0, X, wl_Suf|JumpByte, { Disp, 0, 0} },
+
+/* set byte on flag instructions */
+{"seto", 1, 0x0f90, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setno", 1, 0x0f91, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setb", 1, 0x0f92, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setc", 1, 0x0f92, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnae", 1, 0x0f92, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnb", 1, 0x0f93, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnc", 1, 0x0f93, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setae", 1, 0x0f93, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"sete", 1, 0x0f94, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setz", 1, 0x0f94, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setne", 1, 0x0f95, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnz", 1, 0x0f95, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setbe", 1, 0x0f96, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setna", 1, 0x0f96, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnbe", 1, 0x0f97, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"seta", 1, 0x0f97, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"sets", 1, 0x0f98, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setns", 1, 0x0f99, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setp", 1, 0x0f9a, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setpe", 1, 0x0f9a, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnp", 1, 0x0f9b, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setpo", 1, 0x0f9b, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setl", 1, 0x0f9c, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnge", 1, 0x0f9c, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnl", 1, 0x0f9d, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setge", 1, 0x0f9d, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setle", 1, 0x0f9e, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setng", 1, 0x0f9e, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setnle", 1, 0x0f9f, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+{"setg", 1, 0x0f9f, 0, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} },
+
+/* string manipulation */
+{"cmps", 0, 0xa6, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"cmps", 2, 0xa6, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, AnyMem, 0} },
+{"scmp", 0, 0xa6, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"scmp", 2, 0xa6, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, AnyMem, 0} },
+{"ins", 0, 0x6c, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"ins", 2, 0x6c, X, bwld_Suf|W|IsString, { InOutPortReg, AnyMem|EsSeg, 0} },
+{"outs", 0, 0x6e, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"outs", 2, 0x6e, X, bwld_Suf|W|IsString, { AnyMem, InOutPortReg, 0} },
+{"lods", 0, 0xac, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"lods", 1, 0xac, X, bwld_Suf|W|IsString, { AnyMem, 0, 0} },
+{"lods", 2, 0xac, X, bwld_Suf|W|IsString, { AnyMem, Acc, 0} },
+{"slod", 0, 0xac, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"slod", 1, 0xac, X, bwld_Suf|W|IsString, { AnyMem, 0, 0} },
+{"slod", 2, 0xac, X, bwld_Suf|W|IsString, { AnyMem, Acc, 0} },
+{"movs", 0, 0xa4, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"movs", 2, 0xa4, X, bwld_Suf|W|IsString, { AnyMem, AnyMem|EsSeg, 0} },
+{"smov", 0, 0xa4, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"smov", 2, 0xa4, X, bwld_Suf|W|IsString, { AnyMem, AnyMem|EsSeg, 0} },
+{"scas", 0, 0xae, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"scas", 1, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
+{"scas", 2, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, Acc, 0} },
+{"ssca", 0, 0xae, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"ssca", 1, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
+{"ssca", 2, 0xae, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, Acc, 0} },
+{"stos", 0, 0xaa, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"stos", 1, 0xaa, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
+{"stos", 2, 0xaa, X, bwld_Suf|W|IsString, { Acc, AnyMem|EsSeg, 0} },
+{"ssto", 0, 0xaa, X, bwld_Suf|W|IsString, { 0, 0, 0} },
+{"ssto", 1, 0xaa, X, bwld_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} },
+{"ssto", 2, 0xaa, X, bwld_Suf|W|IsString, { Acc, AnyMem|EsSeg, 0} },
+{"xlat", 0, 0xd7, X, b_Suf|IsString, { 0, 0, 0} },
+{"xlat", 1, 0xd7, X, b_Suf|IsString, { AnyMem, 0, 0} },
+
+/* bit manipulation */
+{"bsf", 2, 0x0fbc, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"bsr", 2, 0x0fbd, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"bt", 2, 0x0fa3, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
+{"bt", 2, 0x0fba, 4, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
+{"btc", 2, 0x0fbb, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
+{"btc", 2, 0x0fba, 7, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
+{"btr", 2, 0x0fb3, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
+{"btr", 2, 0x0fba, 6, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
+{"bts", 2, 0x0fab, X, wl_Suf|Modrm, { WordReg, WordReg|WordMem, 0} },
+{"bts", 2, 0x0fba, 5, wl_Suf|Modrm, { Imm8, WordReg|WordMem, 0} },
+
+/* interrupts & op. sys insns */
+/* See gas/config/tc-i386.c for conversion of 'int $3' into the special
+ int 3 insn. */
+#define INT_OPCODE 0xcd
+#define INT3_OPCODE 0xcc
+{"int", 1, 0xcd, X, NoSuf, { Imm8, 0, 0} },
+{"int3", 0, 0xcc, X, NoSuf, { 0, 0, 0} },
+{"into", 0, 0xce, X, NoSuf, { 0, 0, 0} },
+{"iret", 0, 0xcf, X, wl_Suf, { 0, 0, 0} },
+/* i386sl, i486sl, later 486, and Pentium */
+{"rsm", 0, 0x0faa, X, NoSuf, { 0, 0, 0} },
+
+{"bound", 2, 0x62, X, wl_Suf|Modrm, { WordReg, WordMem, 0} },
+
+{"hlt", 0, 0xf4, X, NoSuf, { 0, 0, 0} },
+/* nop is actually 'xchgl %eax, %eax' */
+{"nop", 0, 0x90, X, NoSuf, { 0, 0, 0} },
+
+/* protection control */
+{"arpl", 2, 0x63, X, NoSuf|Modrm|IgnoreSize,{ Reg16, Reg16|ShortMem, 0} },
+{"lar", 2, 0x0f02, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"lgdt", 1, 0x0f01, 2, wl_Suf|Modrm, { WordMem, 0, 0} },
+{"lidt", 1, 0x0f01, 3, wl_Suf|Modrm, { WordMem, 0, 0} },
+{"lldt", 1, 0x0f00, 2, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
+{"lmsw", 1, 0x0f01, 6, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
+{"lsl", 2, 0x0f03, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"ltr", 1, 0x0f00, 3, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
+
+{"sgdt", 1, 0x0f01, 0, wl_Suf|Modrm, { WordMem, 0, 0} },
+{"sidt", 1, 0x0f01, 1, wl_Suf|Modrm, { WordMem, 0, 0} },
+{"sldt", 1, 0x0f00, 0, wl_Suf|Modrm, { WordReg|WordMem, 0, 0} },
+{"smsw", 1, 0x0f01, 4, wl_Suf|Modrm, { WordReg|WordMem, 0, 0} },
+{"str", 1, 0x0f00, 1, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
+
+{"verr", 1, 0x0f00, 4, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
+{"verw", 1, 0x0f00, 5, NoSuf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
+
+/* floating point instructions */
+
+/* load */
+{"fld", 1, 0xd9c0, X, FP|ShortForm, { FloatReg, 0, 0} }, /* register */
+{"fld", 1, 0xd9, 0, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* %st0 <-- mem float/double */
+{"fld", 1, 0xd9c0, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
+/* Intel Syntax */
+{"fld", 1, 0xdb, 5, x_FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem efloat */
+{"fild", 1, 0xdf, 0, sl_Suf|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* %st0 <-- mem word(16)/dword(32) */
+/* Intel Syntax */
+{"fild", 1, 0xdf, 5, d_Suf|IgnoreSize|Modrm,{ LLongMem, 0, 0} }, /* %st0 <-- mem qword (64) */
+{"fildq", 1, 0xdf, 5, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem qword (64) */
+{"fildll", 1, 0xdf, 5, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem qword (64) */
+{"fldt", 1, 0xdb, 5, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem efloat */
+{"fbld", 1, 0xdf, 4, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 <-- mem bcd */
+
+/* store (no pop) */
+{"fst", 1, 0xddd0, X, FP|ShortForm, { FloatReg, 0, 0} }, /* register */
+{"fst", 1, 0xd9, 2, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* %st0 --> mem float/double */
+{"fst", 1, 0xddd0, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
+{"fist", 1, 0xdf, 2, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* %st0 --> mem word(16)/dword(32) */
+
+/* store (with pop) */
+{"fstp", 1, 0xddd8, X, FP|ShortForm, { FloatReg, 0, 0} }, /* register */
+{"fstp", 1, 0xd9, 3, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* %st0 --> mem float/double */
+{"fstp", 1, 0xddd8, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
+/* Intel Syntax */
+{"fstp", 1, 0xdb, 7, x_FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem efloat */
+{"fistp", 1, 0xdf, 3, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* %st0 --> mem word(16)/dword(32) */
+/* Intel Syntax */
+{"fistp", 1, 0xdf, 7, d_FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem qword (64) */
+{"fistpq", 1, 0xdf, 7, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem qword (64) */
+{"fistpll",1, 0xdf, 7, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem qword (64) */
+{"fstpt", 1, 0xdb, 7, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem efloat */
+{"fbstp", 1, 0xdf, 6, FP|Modrm, { LLongMem, 0, 0} }, /* %st0 --> mem bcd */
+
+/* exchange %st<n> with %st0 */
+{"fxch", 1, 0xd9c8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fxch", 0, 0xd9c9, X, FP, { 0, 0, 0} }, /* alias for fxch %st(1) */
+
+/* comparison (without pop) */
+{"fcom", 1, 0xd8d0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fcom", 0, 0xd8d1, X, FP, { 0, 0, 0} }, /* alias for fcom %st(1) */
+{"fcom", 1, 0xd8, 2, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* compare %st0, mem float/double */
+{"fcom", 1, 0xd8d0, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
+{"ficom", 1, 0xde, 2, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* compare %st0, mem word/dword */
+
+/* comparison (with pop) */
+{"fcomp", 1, 0xd8d8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fcomp", 0, 0xd8d9, X, FP, { 0, 0, 0} }, /* alias for fcomp %st(1) */
+{"fcomp", 1, 0xd8, 3, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, /* compare %st0, mem float/double */
+{"fcomp", 1, 0xd8d8, X, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} },
+{"ficomp", 1, 0xde, 3, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, /* compare %st0, mem word/dword */
+{"fcompp", 0, 0xded9, X, FP, { 0, 0, 0} }, /* compare %st0, %st1 & pop 2 */
+
+/* unordered comparison (with pop) */
+{"fucom", 1, 0xdde0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fucom", 0, 0xdde1, X, FP, { 0, 0, 0} }, /* alias for fucom %st(1) */
+{"fucomp", 1, 0xdde8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fucomp", 0, 0xdde9, X, FP, { 0, 0, 0} }, /* alias for fucomp %st(1) */
+{"fucompp",0, 0xdae9, X, FP, { 0, 0, 0} }, /* ucompare %st0, %st1 & pop twice */
+
+{"ftst", 0, 0xd9e4, X, FP, { 0, 0, 0} }, /* test %st0 */
+{"fxam", 0, 0xd9e5, X, FP, { 0, 0, 0} }, /* examine %st0 */
+
+/* load constants into %st0 */
+{"fld1", 0, 0xd9e8, X, FP, { 0, 0, 0} }, /* %st0 <-- 1.0 */
+{"fldl2t", 0, 0xd9e9, X, FP, { 0, 0, 0} }, /* %st0 <-- log2(10) */
+{"fldl2e", 0, 0xd9ea, X, FP, { 0, 0, 0} }, /* %st0 <-- log2(e) */
+{"fldpi", 0, 0xd9eb, X, FP, { 0, 0, 0} }, /* %st0 <-- pi */
+{"fldlg2", 0, 0xd9ec, X, FP, { 0, 0, 0} }, /* %st0 <-- log10(2) */
+{"fldln2", 0, 0xd9ed, X, FP, { 0, 0, 0} }, /* %st0 <-- ln(2) */
+{"fldz", 0, 0xd9ee, X, FP, { 0, 0, 0} }, /* %st0 <-- 0.0 */
+
+/* arithmetic */
+
+/* add */
+{"fadd", 2, 0xd8c0, X, FP|ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
+{"fadd", 1, 0xd8c0, X, FP|ShortForm, { FloatReg, 0, 0} }, /* alias for fadd %st(i), %st */
+#if UNIXWARE_COMPAT
+{"fadd", 0, 0xdec1, X, FP|Ugh, { 0, 0, 0} }, /* alias for faddp */
+#endif
+{"fadd", 1, 0xd8, 0, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
+{"fiadd", 1, 0xde, 0, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
+
+{"faddp", 2, 0xdec0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"faddp", 1, 0xdec0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"faddp", 0, 0xdec1, X, FP, { 0, 0, 0} }, /* alias for faddp %st, %st(1) */
+{"faddp", 2, 0xdec0, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
+
+/* subtract */
+{"fsub", 2, 0xd8e0, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
+{"fsub", 1, 0xd8e0, X, FP|ShortForm, { FloatReg, 0, 0} },
+#if UNIXWARE_COMPAT
+{"fsub", 0, 0xdee1, X, FP|Ugh, { 0, 0, 0} }, /* alias for fsubp */
+#endif
+{"fsub", 1, 0xd8, 4, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
+{"fisub", 1, 0xde, 4, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
+
+#if UNIXWARE_COMPAT
+{"fsubp", 2, 0xdee0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fsubp", 1, 0xdee0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fsubp", 0, 0xdee1, X, FP, { 0, 0, 0} },
+{"fsubp", 2, 0xdee0, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
+#else
+{"fsubp", 2, 0xdee8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fsubp", 1, 0xdee8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fsubp", 0, 0xdee9, X, FP, { 0, 0, 0} },
+#endif
+
+/* subtract reverse */
+{"fsubr", 2, 0xd8e8, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
+{"fsubr", 1, 0xd8e8, X, FP|ShortForm, { FloatReg, 0, 0} },
+#if UNIXWARE_COMPAT
+{"fsubr", 0, 0xdee9, X, FP|Ugh, { 0, 0, 0} }, /* alias for fsubrp */
+#endif
+{"fsubr", 1, 0xd8, 5, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
+{"fisubr", 1, 0xde, 5, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
+
+#if UNIXWARE_COMPAT
+{"fsubrp", 2, 0xdee8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fsubrp", 1, 0xdee8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fsubrp", 0, 0xdee9, X, FP, { 0, 0, 0} },
+{"fsubrp", 2, 0xdee8, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
+#else
+{"fsubrp", 2, 0xdee0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fsubrp", 1, 0xdee0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fsubrp", 0, 0xdee1, X, FP, { 0, 0, 0} },
+#endif
+
+/* multiply */
+{"fmul", 2, 0xd8c8, X, FP|ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
+{"fmul", 1, 0xd8c8, X, FP|ShortForm, { FloatReg, 0, 0} },
+#if UNIXWARE_COMPAT
+{"fmul", 0, 0xdec9, X, FP|Ugh, { 0, 0, 0} }, /* alias for fmulp */
+#endif
+{"fmul", 1, 0xd8, 1, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
+{"fimul", 1, 0xde, 1, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
+
+{"fmulp", 2, 0xdec8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fmulp", 1, 0xdec8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fmulp", 0, 0xdec9, X, FP, { 0, 0, 0} },
+{"fmulp", 2, 0xdec8, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
+
+/* divide */
+{"fdiv", 2, 0xd8f0, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
+{"fdiv", 1, 0xd8f0, X, FP|ShortForm, { FloatReg, 0, 0} },
+#if UNIXWARE_COMPAT
+{"fdiv", 0, 0xdef1, X, FP|Ugh, { 0, 0, 0} }, /* alias for fdivp */
+#endif
+{"fdiv", 1, 0xd8, 6, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
+{"fidiv", 1, 0xde, 6, sld_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
+
+#if UNIXWARE_COMPAT
+{"fdivp", 2, 0xdef0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fdivp", 1, 0xdef0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fdivp", 0, 0xdef1, X, FP, { 0, 0, 0} },
+{"fdivp", 2, 0xdef0, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
+#else
+{"fdivp", 2, 0xdef8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fdivp", 1, 0xdef8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fdivp", 0, 0xdef9, X, FP, { 0, 0, 0} },
+#endif
+
+/* divide reverse */
+{"fdivr", 2, 0xd8f8, X, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} },
+{"fdivr", 1, 0xd8f8, X, FP|ShortForm, { FloatReg, 0, 0} },
+#if UNIXWARE_COMPAT
+{"fdivr", 0, 0xdef9, X, FP|Ugh, { 0, 0, 0} }, /* alias for fdivrp */
+#endif
+{"fdivr", 1, 0xd8, 7, sld_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} },
+{"fidivr", 1, 0xde, 7, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} },
+
+#if UNIXWARE_COMPAT
+{"fdivrp", 2, 0xdef8, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fdivrp", 1, 0xdef8, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fdivrp", 0, 0xdef9, X, FP, { 0, 0, 0} },
+{"fdivrp", 2, 0xdef8, X, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} },
+#else
+{"fdivrp", 2, 0xdef0, X, FP|ShortForm, { FloatAcc, FloatReg, 0} },
+{"fdivrp", 1, 0xdef0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fdivrp", 0, 0xdef1, X, FP, { 0, 0, 0} },
+#endif
+
+{"f2xm1", 0, 0xd9f0, X, FP, { 0, 0, 0} },
+{"fyl2x", 0, 0xd9f1, X, FP, { 0, 0, 0} },
+{"fptan", 0, 0xd9f2, X, FP, { 0, 0, 0} },
+{"fpatan", 0, 0xd9f3, X, FP, { 0, 0, 0} },
+{"fxtract",0, 0xd9f4, X, FP, { 0, 0, 0} },
+{"fprem1", 0, 0xd9f5, X, FP, { 0, 0, 0} },
+{"fdecstp",0, 0xd9f6, X, FP, { 0, 0, 0} },
+{"fincstp",0, 0xd9f7, X, FP, { 0, 0, 0} },
+{"fprem", 0, 0xd9f8, X, FP, { 0, 0, 0} },
+{"fyl2xp1",0, 0xd9f9, X, FP, { 0, 0, 0} },
+{"fsqrt", 0, 0xd9fa, X, FP, { 0, 0, 0} },
+{"fsincos",0, 0xd9fb, X, FP, { 0, 0, 0} },
+{"frndint",0, 0xd9fc, X, FP, { 0, 0, 0} },
+{"fscale", 0, 0xd9fd, X, FP, { 0, 0, 0} },
+{"fsin", 0, 0xd9fe, X, FP, { 0, 0, 0} },
+{"fcos", 0, 0xd9ff, X, FP, { 0, 0, 0} },
+{"fchs", 0, 0xd9e0, X, FP, { 0, 0, 0} },
+{"fabs", 0, 0xd9e1, X, FP, { 0, 0, 0} },
+
+/* processor control */
+{"fninit", 0, 0xdbe3, X, FP, { 0, 0, 0} },
+{"finit", 0, 0xdbe3, X, FP|FWait, { 0, 0, 0} },
+{"fldcw", 1, 0xd9, 5, FP|Modrm, { ShortMem, 0, 0} },
+{"fnstcw", 1, 0xd9, 7, FP|Modrm, { ShortMem, 0, 0} },
+{"fstcw", 1, 0xd9, 7, FP|FWait|Modrm, { ShortMem, 0, 0} },
+{"fnstsw", 1, 0xdfe0, X, FP, { Acc, 0, 0} },
+{"fnstsw", 1, 0xdd, 7, FP|Modrm, { ShortMem, 0, 0} },
+{"fnstsw", 0, 0xdfe0, X, FP, { 0, 0, 0} },
+{"fstsw", 1, 0xdfe0, X, FP|FWait, { Acc, 0, 0} },
+{"fstsw", 1, 0xdd, 7, FP|FWait|Modrm, { ShortMem, 0, 0} },
+{"fstsw", 0, 0xdfe0, X, FP|FWait, { 0, 0, 0} },
+{"fnclex", 0, 0xdbe2, X, FP, { 0, 0, 0} },
+{"fclex", 0, 0xdbe2, X, FP|FWait, { 0, 0, 0} },
+/* Short forms of fldenv, fstenv use data size prefix.
+ FIXME: Are these the right suffixes? */
+{"fnstenv",1, 0xd9, 6, sl_Suf|Modrm, { LLongMem, 0, 0} },
+{"fstenv", 1, 0xd9, 6, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} },
+{"fldenv", 1, 0xd9, 4, sl_Suf|Modrm, { LLongMem, 0, 0} },
+{"fnsave", 1, 0xdd, 6, sl_Suf|Modrm, { LLongMem, 0, 0} },
+{"fsave", 1, 0xdd, 6, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} },
+{"frstor", 1, 0xdd, 4, sl_Suf|Modrm, { LLongMem, 0, 0} },
+
+{"ffree", 1, 0xddc0, X, FP|ShortForm, { FloatReg, 0, 0} },
+/* P6:free st(i), pop st */
+{"ffreep", 1, 0xdfc0, X, FP|ShortForm, { FloatReg, 0, 0} },
+{"fnop", 0, 0xd9d0, X, FP, { 0, 0, 0} },
+#define FWAIT_OPCODE 0x9b
+{"fwait", 0, 0x9b, X, FP, { 0, 0, 0} },
+
+/*
+ opcode prefixes; we allow them as seperate insns too
+*/
+#define ADDR_PREFIX_OPCODE 0x67
+{"addr16", 0, 0x67, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
+{"addr32", 0, 0x67, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
+{"aword", 0, 0x67, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
+{"adword", 0, 0x67, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
+#define DATA_PREFIX_OPCODE 0x66
+{"data16", 0, 0x66, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
+{"data32", 0, 0x66, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
+{"word", 0, 0x66, X, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} },
+{"dword", 0, 0x66, X, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} },
+#define LOCK_PREFIX_OPCODE 0xf0
+{"lock", 0, 0xf0, X, NoSuf|IsPrefix, { 0, 0, 0} },
+{"wait", 0, 0x9b, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define CS_PREFIX_OPCODE 0x2e
+{"cs", 0, 0x2e, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define DS_PREFIX_OPCODE 0x3e
+{"ds", 0, 0x3e, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define ES_PREFIX_OPCODE 0x26
+{"es", 0, 0x26, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define FS_PREFIX_OPCODE 0x64
+{"fs", 0, 0x64, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define GS_PREFIX_OPCODE 0x65
+{"gs", 0, 0x65, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define SS_PREFIX_OPCODE 0x36
+{"ss", 0, 0x36, X, NoSuf|IsPrefix, { 0, 0, 0} },
+#define REPNE_PREFIX_OPCODE 0xf2
+#define REPE_PREFIX_OPCODE 0xf3
+{"rep", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
+{"repe", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
+{"repz", 0, 0xf3, X, NoSuf|IsPrefix, { 0, 0, 0} },
+{"repne", 0, 0xf2, X, NoSuf|IsPrefix, { 0, 0, 0} },
+{"repnz", 0, 0xf2, X, NoSuf|IsPrefix, { 0, 0, 0} },
+
+/* 486 extensions */
+
+{"bswap", 1, 0x0fc8, X, NoSuf|ShortForm, { Reg32,0,0 } },
+{"xadd", 2, 0x0fc0, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
+{"cmpxchg", 2, 0x0fb0, X, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } },
+{"invd", 0, 0x0f08, X, NoSuf, { 0, 0, 0} },
+{"wbinvd", 0, 0x0f09, X, NoSuf, { 0, 0, 0} },
+{"invlpg", 1, 0x0f01, 7, NoSuf|Modrm, { AnyMem, 0, 0} },
+
+/* 586 and late 486 extensions */
+{"cpuid", 0, 0x0fa2, X, NoSuf, { 0, 0, 0} },
+
+/* Pentium extensions */
+{"wrmsr", 0, 0x0f30, X, NoSuf, { 0, 0, 0} },
+{"rdtsc", 0, 0x0f31, X, NoSuf, { 0, 0, 0} },
+{"rdmsr", 0, 0x0f32, X, NoSuf, { 0, 0, 0} },
+{"cmpxchg8b",1,0x0fc7, 1, NoSuf|Modrm, { LLongMem, 0, 0} },
+{"sysenter", 0, 0x0f34, X, NoSuf, { 0, 0, 0} },
+{"sysexit", 0, 0x0f35, X, NoSuf, { 0, 0, 0} },
+{"fxsave", 1, 0x0fae, 0, FP|Modrm, { LLongMem, 0, 0} },
+{"fxrstor", 1, 0x0fae, 1, FP|Modrm, { LLongMem, 0, 0} },
+
+/* Pentium Pro extensions */
+{"rdpmc", 0, 0x0f33, X, NoSuf, { 0, 0, 0} },
+
+{"ud2", 0, 0x0f0b, X, NoSuf, { 0, 0, 0} }, /* official undefined instr. */
+{"ud2a", 0, 0x0f0b, X, NoSuf, { 0, 0, 0} }, /* alias for ud2 */
+{"ud2b", 0, 0x0fb9, X, NoSuf, { 0, 0, 0} }, /* 2nd. official undefined instr. */
+
+{"cmovo", 2, 0x0f40, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovno", 2, 0x0f41, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovb", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovc", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnae", 2, 0x0f42, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovae", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnc", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnb", 2, 0x0f43, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmove", 2, 0x0f44, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovz", 2, 0x0f44, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovne", 2, 0x0f45, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnz", 2, 0x0f45, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovbe", 2, 0x0f46, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovna", 2, 0x0f46, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmova", 2, 0x0f47, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnbe", 2, 0x0f47, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovs", 2, 0x0f48, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovns", 2, 0x0f49, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovp", 2, 0x0f4a, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnp", 2, 0x0f4b, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovl", 2, 0x0f4c, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnge", 2, 0x0f4c, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovge", 2, 0x0f4d, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnl", 2, 0x0f4d, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovle", 2, 0x0f4e, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovng", 2, 0x0f4e, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovg", 2, 0x0f4f, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+{"cmovnle", 2, 0x0f4f, X, wl_Suf|ReverseModrm, { WordReg|WordMem, WordReg, 0} },
+
+{"fcmovb", 2, 0xdac0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovnae",2, 0xdac0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmove", 2, 0xdac8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovbe", 2, 0xdad0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovna", 2, 0xdad0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovu", 2, 0xdad8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovae", 2, 0xdbc0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovnb", 2, 0xdbc0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovne", 2, 0xdbc8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmova", 2, 0xdbd0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovnbe",2, 0xdbd0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcmovnu", 2, 0xdbd8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+
+{"fcomi", 2, 0xdbf0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcomi", 0, 0xdbf1, X, NoSuf|ShortForm, { 0, 0, 0} },
+{"fcomi", 1, 0xdbf0, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
+{"fucomi", 2, 0xdbe8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fucomi", 0, 0xdbe9, X, NoSuf|ShortForm, { 0, 0, 0} },
+{"fucomi", 1, 0xdbe8, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
+{"fcomip", 2, 0xdff0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcompi", 2, 0xdff0, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fcompi", 0, 0xdff1, X, NoSuf|ShortForm, { 0, 0, 0} },
+{"fcompi", 1, 0xdff0, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
+{"fucomip", 2, 0xdfe8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fucompi", 2, 0xdfe8, X, NoSuf|ShortForm, { FloatReg, FloatAcc, 0} },
+{"fucompi", 0, 0xdfe9, X, NoSuf|ShortForm, { 0, 0, 0} },
+{"fucompi", 1, 0xdfe8, X, NoSuf|ShortForm, { FloatReg, 0, 0} },
+
+/* MMX instructions. */
+
+{"emms", 0, 0x0f77, X, NoSuf, { 0, 0, 0 } },
+{"movd", 2, 0x0f6e, X, NoSuf|Modrm, { Reg32|LongMem, RegMMX, 0 } },
+{"movd", 2, 0x0f7e, X, NoSuf|Modrm, { RegMMX, Reg32|LongMem, 0 } },
+{"movq", 2, 0x0f6f, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"movq", 2, 0x0f7f, X, NoSuf|Modrm, { RegMMX, RegMMX|LongMem, 0 } },
+{"packssdw", 2, 0x0f6b, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"packsswb", 2, 0x0f63, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"packuswb", 2, 0x0f67, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddb", 2, 0x0ffc, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddw", 2, 0x0ffd, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddd", 2, 0x0ffe, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddsb", 2, 0x0fec, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddsw", 2, 0x0fed, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddusb", 2, 0x0fdc, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"paddusw", 2, 0x0fdd, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pand", 2, 0x0fdb, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pandn", 2, 0x0fdf, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pcmpeqb", 2, 0x0f74, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pcmpeqw", 2, 0x0f75, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pcmpeqd", 2, 0x0f76, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pcmpgtb", 2, 0x0f64, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pcmpgtw", 2, 0x0f65, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pcmpgtd", 2, 0x0f66, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pmaddwd", 2, 0x0ff5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pmulhw", 2, 0x0fe5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pmullw", 2, 0x0fd5, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"por", 2, 0x0feb, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psllw", 2, 0x0ff1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psllw", 2, 0x0f71, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"pslld", 2, 0x0ff2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pslld", 2, 0x0f72, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psllq", 2, 0x0ff3, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psllq", 2, 0x0f73, 6, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psraw", 2, 0x0fe1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psraw", 2, 0x0f71, 4, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psrad", 2, 0x0fe2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psrad", 2, 0x0f72, 4, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psrlw", 2, 0x0fd1, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psrlw", 2, 0x0f71, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psrld", 2, 0x0fd2, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psrld", 2, 0x0f72, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psrlq", 2, 0x0fd3, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psrlq", 2, 0x0f73, 2, NoSuf|Modrm, { Imm8, RegMMX, 0 } },
+{"psubb", 2, 0x0ff8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psubw", 2, 0x0ff9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psubd", 2, 0x0ffa, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psubsb", 2, 0x0fe8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psubsw", 2, 0x0fe9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psubusb", 2, 0x0fd8, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"psubusw", 2, 0x0fd9, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"punpckhbw",2, 0x0f68, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"punpckhwd",2, 0x0f69, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"punpckhdq",2, 0x0f6a, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"punpcklbw",2, 0x0f60, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"punpcklwd",2, 0x0f61, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"punpckldq",2, 0x0f62, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pxor", 2, 0x0fef, X, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+
+
+/* AMD 3DNow! instructions */
+#define AMD_3DNOW_OPCODE 0x0f0f
+
+{"prefetch", 1, 0x0f0d, 0, NoSuf|Modrm, { ByteMem, 0, 0 } },
+{"prefetchw",1, 0x0f0d, 1, NoSuf|Modrm, { ByteMem, 0, 0 } },
+{"femms", 0, 0x0f0e, X, NoSuf, { 0, 0, 0 } },
+{"pavgusb", 2, 0x0f0f, 0xbf, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pf2id", 2, 0x0f0f, 0x1d, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfacc", 2, 0x0f0f, 0xae, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfadd", 2, 0x0f0f, 0x9e, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfcmpeq", 2, 0x0f0f, 0xb0, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfcmpge", 2, 0x0f0f, 0x90, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfcmpgt", 2, 0x0f0f, 0xa0, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfmax", 2, 0x0f0f, 0xa4, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfmin", 2, 0x0f0f, 0x94, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfmul", 2, 0x0f0f, 0xb4, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfrcp", 2, 0x0f0f, 0x96, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfrcpit1", 2, 0x0f0f, 0xa6, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfrcpit2", 2, 0x0f0f, 0xb6, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfrsqit1", 2, 0x0f0f, 0xa7, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfrsqrt", 2, 0x0f0f, 0x97, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfsub", 2, 0x0f0f, 0x9a, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pfsubr", 2, 0x0f0f, 0xaa, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pi2fd", 2, 0x0f0f, 0x0d, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+{"pmulhrw", 2, 0x0f0f, 0xb7, NoSuf|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
+
+{NULL, 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */
+};
+#undef X
+#undef ReverseModrm
+#undef NoSuf
+#undef b_Suf
+#undef w_Suf
+#undef l_Suf
+#undef bw_Suf
+#undef bl_Suf
+#undef wl_Suf
+#undef sl_Suf
+#undef bwl_Suf
+#undef FP
+#undef l_FP
+#undef sl_FP
+
+#define MAX_MNEM_SIZE 16 /* for parsing insn mnemonics from input */
+
+
+/* 386 register table */
+
+static const reg_entry i386_regtab[] = {
+ /* 8 bit regs */
+ {"al", Reg8|Acc, 0},
+ {"cl", Reg8|ShiftCount, 1},
+ {"dl", Reg8, 2},
+ {"bl", Reg8, 3},
+ {"ah", Reg8, 4},
+ {"ch", Reg8, 5},
+ {"dh", Reg8, 6},
+ {"bh", Reg8, 7},
+ /* 16 bit regs */
+ {"ax", Reg16|Acc, 0},
+ {"cx", Reg16, 1},
+ {"dx", Reg16|InOutPortReg, 2},
+ {"bx", Reg16|BaseIndex, 3},
+ {"sp", Reg16, 4},
+ {"bp", Reg16|BaseIndex, 5},
+ {"si", Reg16|BaseIndex, 6},
+ {"di", Reg16|BaseIndex, 7},
+ /* 32 bit regs */
+ {"eax", Reg32|BaseIndex|Acc, 0},
+ {"ecx", Reg32|BaseIndex, 1},
+ {"edx", Reg32|BaseIndex, 2},
+ {"ebx", Reg32|BaseIndex, 3},
+ {"esp", Reg32, 4},
+ {"ebp", Reg32|BaseIndex, 5},
+ {"esi", Reg32|BaseIndex, 6},
+ {"edi", Reg32|BaseIndex, 7},
+ /* segment registers */
+ {"es", SReg2, 0},
+ {"cs", SReg2, 1},
+ {"ss", SReg2, 2},
+ {"ds", SReg2, 3},
+ {"fs", SReg3, 4},
+ {"gs", SReg3, 5},
+ /* control registers */
+ {"cr0", Control, 0},
+ {"cr1", Control, 1},
+ {"cr2", Control, 2},
+ {"cr3", Control, 3},
+ {"cr4", Control, 4},
+ {"cr5", Control, 5},
+ {"cr6", Control, 6},
+ {"cr7", Control, 7},
+ /* debug registers */
+ {"db0", Debug, 0},
+ {"db1", Debug, 1},
+ {"db2", Debug, 2},
+ {"db3", Debug, 3},
+ {"db4", Debug, 4},
+ {"db5", Debug, 5},
+ {"db6", Debug, 6},
+ {"db7", Debug, 7},
+ {"dr0", Debug, 0},
+ {"dr1", Debug, 1},
+ {"dr2", Debug, 2},
+ {"dr3", Debug, 3},
+ {"dr4", Debug, 4},
+ {"dr5", Debug, 5},
+ {"dr6", Debug, 6},
+ {"dr7", Debug, 7},
+ /* test registers */
+ {"tr0", Test, 0},
+ {"tr1", Test, 1},
+ {"tr2", Test, 2},
+ {"tr3", Test, 3},
+ {"tr4", Test, 4},
+ {"tr5", Test, 5},
+ {"tr6", Test, 6},
+ {"tr7", Test, 7},
+ /* float registers */
+ {"st(0)", FloatReg|FloatAcc, 0},
+ {"st", FloatReg|FloatAcc, 0},
+ {"st(1)", FloatReg, 1},
+ {"st(2)", FloatReg, 2},
+ {"st(3)", FloatReg, 3},
+ {"st(4)", FloatReg, 4},
+ {"st(5)", FloatReg, 5},
+ {"st(6)", FloatReg, 6},
+ {"st(7)", FloatReg, 7},
+ {"mm0", RegMMX, 0},
+ {"mm1", RegMMX, 1},
+ {"mm2", RegMMX, 2},
+ {"mm3", RegMMX, 3},
+ {"mm4", RegMMX, 4},
+ {"mm5", RegMMX, 5},
+ {"mm6", RegMMX, 6},
+ {"mm7", RegMMX, 7}
+};
+
+#define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */
+
+/* segment stuff */
+static const seg_entry cs = { "cs", 0x2e };
+static const seg_entry ds = { "ds", 0x3e };
+static const seg_entry ss = { "ss", 0x36 };
+static const seg_entry es = { "es", 0x26 };
+static const seg_entry fs = { "fs", 0x64 };
+static const seg_entry gs = { "gs", 0x65 };
+
+/* end of opcode/i386.h */
diff --git a/include/opcode/i860.h b/include/opcode/i860.h
new file mode 100644
index 00000000000..b6ebd25c648
--- /dev/null
+++ b/include/opcode/i860.h
@@ -0,0 +1,491 @@
+/* Table of opcodes for the i860.
+ Copyright (C) 1989 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
+
+GAS/GDB 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 1, or (at your option)
+any later version.
+
+GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if !defined(__STDC__) && !defined(const)
+#define const
+#endif
+
+/*
+ * Structure of an opcode table entry.
+ */
+struct i860_opcode
+{
+ const char *name;
+ unsigned long match; /* Bits that must be set. */
+ unsigned long lose; /* Bits that must not be set. */
+ const char *args;
+ /* Nonzero if this is a possible expand-instruction. */
+ char expand;
+};
+
+enum expand_type
+{
+ E_MOV = 1, E_ADDR, E_U32, E_AND, E_S32, E_DELAY
+};
+
+/*
+ All i860 opcodes are 32 bits, except for the pseudoinstructions
+ and the operations utilizing a 32-bit address expression, an
+ unsigned 32-bit constant, or a signed 32-bit constant.
+ These opcodes are expanded into a two-instruction sequence for
+ any situation where the immediate operand does not fit in 32 bits.
+ In the case of the add and subtract operations the expansion is
+ to a three-instruction sequence (ex: orh, or, adds). In cases
+ where the address is to be relocated, the instruction is
+ expanded to handle the worse case, this could be optimized at
+ the final link if the actual address were known.
+
+ The pseudoinstructions are: mov, fmov, pmov, nop, and fnop.
+ These instructions are implemented as a one or two instruction
+ sequence of other operations.
+
+ The match component is a mask saying which bits must match a
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing one character
+ for each operand of the instruction.
+
+Kinds of operands:
+ # Number used by optimizer. It is ignored.
+ 1 src1 integer register.
+ 2 src2 integer register.
+ d dest register.
+ c ctrlreg control register.
+ i 16 bit immediate.
+ I 16 bit immediate, aligned.
+ 5 5 bit immediate.
+ l lbroff 26 bit PC relative immediate.
+ r sbroff 16 bit PC relative immediate.
+ s split 16 bit immediate.
+ S split 16 bit immediate, aligned.
+ e src1 floating point register.
+ f src2 floating point register.
+ g dest floating point register.
+
+*/
+
+/* The order of the opcodes in this table is significant:
+
+ * The assembler requires that all instances of the same mnemonic must be
+ consecutive. If they aren't, the assembler will bomb at runtime.
+
+ * The disassembler should not care about the order of the opcodes. */
+
+static struct i860_opcode i860_opcodes[] =
+{
+
+/* REG-Format Instructions */
+{ "ld.c", 0x30000000, 0xcc000000, "c,d", 0 }, /* ld.c csrc2,idest */
+{ "ld.b", 0x00000000, 0xfc000000, "1(2),d", 0 }, /* ld.b isrc1(isrc2),idest */
+{ "ld.b", 0x04000000, 0xf8000000, "I(2),d", E_ADDR }, /* ld.b #const(isrc2),idest */
+{ "ld.s", 0x10000000, 0xec000001, "1(2),d", 0 }, /* ld.s isrc1(isrc2),idest */
+{ "ld.s", 0x14000001, 0xe8000000, "I(2),d", E_ADDR }, /* ld.s #const(isrc2),idest */
+{ "ld.l", 0x10000001, 0xec000000, "1(2),d", 0 }, /* ld.l isrc1(isrc2),idest */
+{ "ld.l", 0x14000001, 0xe8000000, "I(2),d", E_ADDR }, /* ld.l #const(isrc2),idest */
+
+{ "st.c", 0x38000000, 0xc4000000, "1,c", 0 }, /* st.c isrc1ni,csrc2 */
+{ "st.b", 0x0c000000, 0xf0000000, "1,S(2)", E_ADDR }, /* st.b isrc1ni,#const(isrc2) */
+{ "st.s", 0x1c000000, 0xe0000000, "1,S(2)", E_ADDR }, /* st.s isrc1ni,#const(isrc2) */
+{ "st.l", 0x1c000001, 0xe0000000, "1,S(2)", E_ADDR }, /* st.l isrc1ni,#const(isrc2) */
+
+{ "ixfr", 0x08000000, 0xf4000000, "1,g", 0 }, /* ixfr isrc1ni,fdest */
+
+{ "fld.l", 0x20000002, 0xdc000001, "1(2),g", 0 }, /* fld.l isrc1(isrc2),fdest */
+{ "fld.l", 0x24000002, 0xd8000001, "i(2),g", E_ADDR }, /* fld.l #const(isrc2),fdest */
+{ "fld.l", 0x20000003, 0xdc000000, "1(2)++,g", 0 }, /* fld.l isrc1(isrc2)++,fdest */
+{ "fld.l", 0x24000003, 0xd8000000, "i(2)++,g", E_ADDR }, /* fld.l #const(isrc2)++,fdest */
+{ "fld.d", 0x20000000, 0xdc000007, "1(2),g", 0 }, /* fld.d isrc1(isrc2),fdest */
+{ "fld.d", 0x24000000, 0xd8000007, "i(2),g", E_ADDR }, /* fld.d #const(isrc2),fdest */
+{ "fld.d", 0x20000001, 0xdc000006, "1(2)++,g", 0 }, /* fld.d isrc1(isrc2)++,fdest */
+{ "fld.d", 0x24000001, 0xd8000006, "i(2)++,g", E_ADDR }, /* fld.d #const(isrc2)++,fdest */
+{ "fld.q", 0x20000004, 0xdc000003, "1(2),g", 0 }, /* fld.q isrc1(isrc2),fdest */
+{ "fld.q", 0x24000004, 0xd8000003, "i(2),g", E_ADDR }, /* fld.q #const(isrc2),fdest */
+{ "fld.q", 0x20000005, 0xdc000002, "1(2)++,g", 0 }, /* fld.q isrc1(isrc2)++,fdest */
+{ "fld.q", 0x24000005, 0xd8000002, "i(2)++,g", E_ADDR }, /* fld.q #const(isrc2)++,fdest */
+
+{ "pfld.l", 0x60000000, 0x9c000003, "1(2),g", 0 }, /* pfld.l isrc1(isrc2),fdest */
+{ "pfld.l", 0x64000000, 0x98000003, "i(2),g", E_ADDR }, /* pfld.l #const(isrc2),fdest */
+{ "pfld.l", 0x60000001, 0x9c000002, "1(2)++,g", 0 }, /* pfld.l isrc1(isrc2)++,fdest */
+{ "pfld.l", 0x64000001, 0x98000002, "i(2)++,g", E_ADDR }, /* pfld.l #const(isrc2)++,fdest */
+{ "pfld.d", 0x60000000, 0x9c000007, "1(2),g", 0 }, /* pfld.d isrc1(isrc2),fdest */
+{ "pfld.d", 0x64000000, 0x98000007, "i(2),g", E_ADDR }, /* pfld.d #const(isrc2),fdest */
+{ "pfld.d", 0x60000001, 0x9c000006, "1(2)++,g", 0 }, /* pfld.d isrc1(isrc2)++,fdest */
+{ "pfld.d", 0x64000001, 0x98000006, "i(2)++,g", E_ADDR }, /* pfld.d #const(isrc2)++,fdest */
+
+{ "fst.l", 0x28000002, 0xd4000001, "g,1(2)", 0 }, /* fst.l fdest,isrc1(isrc2) */
+{ "fst.l", 0x2c000002, 0xd0000001, "g,i(2)", E_ADDR }, /* fst.l fdest,#const(isrc2) */
+{ "fst.l", 0x28000003, 0xd4000000, "g,1(2)++", 0 }, /* fst.l fdest,isrc1(isrc2)++ */
+{ "fst.l", 0x2c000003, 0xd0000000, "g,i(2)++", E_ADDR }, /* fst.l fdest,#const(isrc2)++ */
+{ "fst.d", 0x28000000, 0xd4000007, "g,1(2)", 0 }, /* fst.d fdest,isrc1(isrc2) */
+{ "fst.d", 0x2c000000, 0xd0000007, "g,i(2)", E_ADDR }, /* fst.d fdest,#const(isrc2) */
+{ "fst.d", 0x28000001, 0xd4000006, "g,1(2)++", 0 }, /* fst.d fdest,isrc1(isrc2)++ */
+{ "fst.d", 0x2c000001, 0xd0000006, "g,i(2)++", E_ADDR }, /* fst.d fdest,#const(isrc2)++ */
+
+{ "pst.d", 0x3c000000, 0xc0000007, "g,i(2)", E_ADDR }, /* pst.d fdest,#const(isrc2) */
+{ "pst.d", 0x3c000001, 0xc0000006, "g,i(2)++", E_ADDR }, /* pst.d fdest,#const(isrc2)++ */
+
+{ "addu", 0x80000000, 0x7c000000, "1,2,d", 0 }, /* addu isrc1,isrc2,idest */
+{ "addu", 0x84000000, 0x78000000, "i,2,d", E_S32 }, /* addu #const,isrc2,idest */
+{ "adds", 0x90000000, 0x6c000000, "1,2,d", 0 }, /* adds isrc1,isrc2,idest */
+{ "adds", 0x94000000, 0x68000000, "i,2,d", E_S32 }, /* adds #const,isrc2,idest */
+{ "subu", 0x88000000, 0x74000000, "1,2,d", 0 }, /* subu isrc1,isrc2,idest */
+{ "subu", 0x8c000000, 0x70000000, "i,2,d", E_S32 }, /* subu #const,isrc2,idest */
+{ "subs", 0x98000000, 0x64000000, "1,2,d", 0 }, /* subs isrc1,isrc2,idest */
+{ "subs", 0x9c000000, 0x60000000, "i,2,d", E_S32 }, /* subs #const,isrc2,idest */
+
+{ "shl", 0xa0000000, 0x5c000000, "1,2,d", 0 }, /* shl isrc1,isrc2,idest */
+{ "shl", 0xa4000000, 0x58000000, "i,2,d", 0 }, /* shl #const,isrc2,idest */
+{ "shr", 0xa8000000, 0x54000000, "1,2,d", 0 }, /* shr isrc1,isrc2,idest */
+{ "shr", 0xac000000, 0x50000000, "i,2,d", 0 }, /* shr #const,isrc2,idest */
+{ "shrd", 0xb0000000, 0x4c000000, "1,2,d", 0 }, /* shrd isrc1,isrc2,idest */
+{ "shra", 0xb8000000, 0x44000000, "1,2,d", 0 }, /* shra isrc1,isrc2,idest */
+{ "shra", 0xbc000000, 0x40000000, "i,2,d", 0 }, /* shra #const,isrc2,idest */
+
+{ "mov", 0xa0000000, 0x5c00f800, "2,d", 0 }, /* shl r0,isrc2,idest */
+{ "mov", 0x94000000, 0x69e00000, "i,d", E_MOV }, /* adds #const,r0,idest */
+{ "nop", 0xa0000000, 0x5ffff800, "", 0 }, /* shl r0,r0,r0 */
+{ "fnop", 0xb0000000, 0x4ffff800, "", 0 }, /* shrd r0,r0,r0 */
+
+{ "trap", 0x44000000, 0xb8000000, "1,2,d", 0 }, /* trap isrc1ni,isrc2,idest */
+
+{ "flush", 0x34000000, 0xc81f0001, "i(2)", E_ADDR }, /* flush #const(isrc2) */
+{ "flush", 0x34000001, 0xc81f0000, "i(2)++", E_ADDR }, /* flush #const(isrc2)++ */
+
+{ "and", 0xc0000000, 0x3c000000, "1,2,d", 0 }, /* and isrc1,isrc2,idest */
+{ "and", 0xc4000000, 0x38000000, "i,2,d", E_AND }, /* and #const,isrc2,idest */
+{ "andh", 0xc8000000, 0x34000000, "1,2,d", 0 }, /* andh isrc1,isrc2,idest */
+{ "andh", 0xcc000000, 0x30000000, "i,2,d", 0 }, /* andh #const,isrc2,idest */
+{ "andnot", 0xd0000000, 0x2c000000, "1,2,d", 0 }, /* andnot isrc1,isrc2,idest */
+{ "andnot", 0xd4000000, 0x28000000, "i,2,d", E_U32 }, /* andnot #const,isrc2,idest */
+{ "andnoth", 0xd8000000, 0x24000000, "1,2,d", 0 }, /* andnoth isrc1,isrc2,idest */
+{ "andnoth", 0xdc000000, 0x20000000, "i,2,d", 0 }, /* andnoth #const,isrc2,idest */
+{ "or", 0xe0000000, 0x1c000000, "1,2,d", 0 }, /* or isrc1,isrc2,idest */
+{ "or", 0xe4000000, 0x18000000, "i,2,d", E_U32 }, /* or #const,isrc2,idest */
+{ "orh", 0xe8000000, 0x14000000, "1,2,d", 0 }, /* orh isrc1,isrc2,idest */
+{ "orh", 0xec000000, 0x10000000, "i,2,d", 0 }, /* orh #const,isrc2,idest */
+{ "xor", 0xf0000000, 0x0c000000, "1,2,d", 0 }, /* xor isrc1,isrc2,idest */
+{ "xor", 0xf4000000, 0x08000000, "i,2,d", E_U32 }, /* xor #const,isrc2,idest */
+{ "xorh", 0xf8000000, 0x04000000, "1,2,d", 0 }, /* xorh isrc1,isrc2,idest */
+{ "xorh", 0xfc000000, 0x00000000, "i,2,d", 0 }, /* xorh #const,isrc2,idest */
+
+{ "bte", 0x58000000, 0xa4000000, "1,2,s", 0 }, /* bte isrc1s,isrc2,sbroff */
+{ "bte", 0x5c000000, 0xa0000000, "5,2,s", 0 }, /* bte #const5,isrc2,sbroff */
+{ "btne", 0x50000000, 0xac000000, "1,2,s", 0 }, /* btne isrc1s,isrc2,sbroff */
+{ "btne", 0x54000000, 0xa8000000, "5,2,s", 0 }, /* btne #const5,isrc2,sbroff */
+{ "bla", 0xb4000000, 0x48000000, "1,2,s", E_DELAY }, /* bla isrc1s,isrc2,sbroff */
+{ "bri", 0x40000000, 0xbc000000, "1", E_DELAY }, /* bri isrc1ni */
+
+/* Core Escape Instruction Format */
+{ "lock", 0x4c000001, 0xb000001e, "", 0 }, /* lock set BL in dirbase */
+{ "calli", 0x4c000002, 0xb000001d, "1", E_DELAY }, /* calli isrc1ni */
+{ "intovr", 0x4c000004, 0xb000001b, "", 0 }, /* intovr trap on integer overflow */
+{ "unlock", 0x4c000007, 0xb0000018, "", 0 }, /* unlock clear BL in dirbase */
+
+/* CTRL-Format Instructions */
+{ "br", 0x68000000, 0x94000000, "l", E_DELAY }, /* br lbroff */
+{ "call", 0x6c000000, 0x90000000, "l", E_DELAY }, /* call lbroff */
+{ "bc", 0x70000000, 0x8c000000, "l", 0 }, /* bc lbroff */
+{ "bc.t", 0x74000000, 0x88000000, "l", E_DELAY }, /* bc.t lbroff */
+{ "bnc", 0x78000000, 0x84000000, "l", 0 }, /* bnc lbroff */
+{ "bnc.t", 0x7c000000, 0x80000000, "l", E_DELAY }, /* bnc.t lbroff */
+
+/* Floating Point Escape Instruction Format - pfam.p fsrc1,fsrc2,fdest */
+{ "r2p1.ss", 0x48000400, 0xb40003ff, "e,f,g", 0 },
+{ "r2p1.sd", 0x48000480, 0xb400037f, "e,f,g", 0 },
+{ "r2p1.dd", 0x48000580, 0xb400027f, "e,f,g", 0 },
+{ "r2pt.ss", 0x48000401, 0xb40003fe, "e,f,g", 0 },
+{ "r2pt.sd", 0x48000481, 0xb400037e, "e,f,g", 0 },
+{ "r2pt.dd", 0x48000581, 0xb400027e, "e,f,g", 0 },
+{ "r2ap1.ss", 0x48000402, 0xb40003fd, "e,f,g", 0 },
+{ "r2ap1.sd", 0x48000482, 0xb400037d, "e,f,g", 0 },
+{ "r2ap1.dd", 0x48000582, 0xb400027d, "e,f,g", 0 },
+{ "r2apt.ss", 0x48000403, 0xb40003fc, "e,f,g", 0 },
+{ "r2apt.sd", 0x48000483, 0xb400037c, "e,f,g", 0 },
+{ "r2apt.dd", 0x48000583, 0xb400027c, "e,f,g", 0 },
+{ "i2p1.ss", 0x48000404, 0xb40003fb, "e,f,g", 0 },
+{ "i2p1.sd", 0x48000484, 0xb400037b, "e,f,g", 0 },
+{ "i2p1.dd", 0x48000584, 0xb400027b, "e,f,g", 0 },
+{ "i2pt.ss", 0x48000405, 0xb40003fa, "e,f,g", 0 },
+{ "i2pt.sd", 0x48000485, 0xb400037a, "e,f,g", 0 },
+{ "i2pt.dd", 0x48000585, 0xb400027a, "e,f,g", 0 },
+{ "i2ap1.ss", 0x48000406, 0xb40003f9, "e,f,g", 0 },
+{ "i2ap1.sd", 0x48000486, 0xb4000379, "e,f,g", 0 },
+{ "i2ap1.dd", 0x48000586, 0xb4000279, "e,f,g", 0 },
+{ "i2apt.ss", 0x48000407, 0xb40003f8, "e,f,g", 0 },
+{ "i2apt.sd", 0x48000487, 0xb4000378, "e,f,g", 0 },
+{ "i2apt.dd", 0x48000587, 0xb4000278, "e,f,g", 0 },
+{ "rat1p2.ss", 0x48000408, 0xb40003f7, "e,f,g", 0 },
+{ "rat1p2.sd", 0x48000488, 0xb4000377, "e,f,g", 0 },
+{ "rat1p2.dd", 0x48000588, 0xb4000277, "e,f,g", 0 },
+{ "m12apm.ss", 0x48000409, 0xb40003f6, "e,f,g", 0 },
+{ "m12apm.sd", 0x48000489, 0xb4000376, "e,f,g", 0 },
+{ "m12apm.dd", 0x48000589, 0xb4000276, "e,f,g", 0 },
+{ "ra1p2.ss", 0x4800040a, 0xb40003f5, "e,f,g", 0 },
+{ "ra1p2.sd", 0x4800048a, 0xb4000375, "e,f,g", 0 },
+{ "ra1p2.dd", 0x4800058a, 0xb4000275, "e,f,g", 0 },
+{ "m12ttpa.ss", 0x4800040b, 0xb40003f4, "e,f,g", 0 },
+{ "m12ttpa.sd", 0x4800048b, 0xb4000374, "e,f,g", 0 },
+{ "m12ttpa.dd", 0x4800058b, 0xb4000274, "e,f,g", 0 },
+{ "iat1p2.ss", 0x4800040c, 0xb40003f3, "e,f,g", 0 },
+{ "iat1p2.sd", 0x4800048c, 0xb4000373, "e,f,g", 0 },
+{ "iat1p2.dd", 0x4800058c, 0xb4000273, "e,f,g", 0 },
+{ "m12tpm.ss", 0x4800040d, 0xb40003f2, "e,f,g", 0 },
+{ "m12tpm.sd", 0x4800048d, 0xb4000372, "e,f,g", 0 },
+{ "m12tpm.dd", 0x4800058d, 0xb4000272, "e,f,g", 0 },
+{ "ia1p2.ss", 0x4800040e, 0xb40003f1, "e,f,g", 0 },
+{ "ia1p2.sd", 0x4800048e, 0xb4000371, "e,f,g", 0 },
+{ "ia1p2.dd", 0x4800058e, 0xb4000271, "e,f,g", 0 },
+{ "m12tpa.ss", 0x4800040f, 0xb40003f0, "e,f,g", 0 },
+{ "m12tpa.sd", 0x4800048f, 0xb4000370, "e,f,g", 0 },
+{ "m12tpa.dd", 0x4800058f, 0xb4000270, "e,f,g", 0 },
+
+/* Floating Point Escape Instruction Format - pfsm.p fsrc1,fsrc2,fdest */
+{ "r2s1.ss", 0x48000410, 0xb40003ef, "e,f,g", 0 },
+{ "r2s1.sd", 0x48000490, 0xb400036f, "e,f,g", 0 },
+{ "r2s1.dd", 0x48000590, 0xb400026f, "e,f,g", 0 },
+{ "r2st.ss", 0x48000411, 0xb40003ee, "e,f,g", 0 },
+{ "r2st.sd", 0x48000491, 0xb400036e, "e,f,g", 0 },
+{ "r2st.dd", 0x48000591, 0xb400026e, "e,f,g", 0 },
+{ "r2as1.ss", 0x48000412, 0xb40003ed, "e,f,g", 0 },
+{ "r2as1.sd", 0x48000492, 0xb400036d, "e,f,g", 0 },
+{ "r2as1.dd", 0x48000592, 0xb400026d, "e,f,g", 0 },
+{ "r2ast.ss", 0x48000413, 0xb40003ec, "e,f,g", 0 },
+{ "r2ast.sd", 0x48000493, 0xb400036c, "e,f,g", 0 },
+{ "r2ast.dd", 0x48000593, 0xb400026c, "e,f,g", 0 },
+{ "i2s1.ss", 0x48000414, 0xb40003eb, "e,f,g", 0 },
+{ "i2s1.sd", 0x48000494, 0xb400036b, "e,f,g", 0 },
+{ "i2s1.dd", 0x48000594, 0xb400026b, "e,f,g", 0 },
+{ "i2st.ss", 0x48000415, 0xb40003ea, "e,f,g", 0 },
+{ "i2st.sd", 0x48000495, 0xb400036a, "e,f,g", 0 },
+{ "i2st.dd", 0x48000595, 0xb400026a, "e,f,g", 0 },
+{ "i2as1.ss", 0x48000416, 0xb40003e9, "e,f,g", 0 },
+{ "i2as1.sd", 0x48000496, 0xb4000369, "e,f,g", 0 },
+{ "i2as1.dd", 0x48000596, 0xb4000269, "e,f,g", 0 },
+{ "i2ast.ss", 0x48000417, 0xb40003e8, "e,f,g", 0 },
+{ "i2ast.sd", 0x48000497, 0xb4000368, "e,f,g", 0 },
+{ "i2ast.dd", 0x48000597, 0xb4000268, "e,f,g", 0 },
+{ "rat1s2.ss", 0x48000418, 0xb40003e7, "e,f,g", 0 },
+{ "rat1s2.sd", 0x48000498, 0xb4000367, "e,f,g", 0 },
+{ "rat1s2.dd", 0x48000598, 0xb4000267, "e,f,g", 0 },
+{ "m12asm.ss", 0x48000419, 0xb40003e6, "e,f,g", 0 },
+{ "m12asm.sd", 0x48000499, 0xb4000366, "e,f,g", 0 },
+{ "m12asm.dd", 0x48000599, 0xb4000266, "e,f,g", 0 },
+{ "ra1s2.ss", 0x4800041a, 0xb40003e5, "e,f,g", 0 },
+{ "ra1s2.sd", 0x4800049a, 0xb4000365, "e,f,g", 0 },
+{ "ra1s2.dd", 0x4800059a, 0xb4000265, "e,f,g", 0 },
+{ "m12ttsa.ss", 0x4800041b, 0xb40003e4, "e,f,g", 0 },
+{ "m12ttsa.sd", 0x4800049b, 0xb4000364, "e,f,g", 0 },
+{ "m12ttsa.dd", 0x4800059b, 0xb4000264, "e,f,g", 0 },
+{ "iat1s2.ss", 0x4800041c, 0xb40003e3, "e,f,g", 0 },
+{ "iat1s2.sd", 0x4800049c, 0xb4000363, "e,f,g", 0 },
+{ "iat1s2.dd", 0x4800059c, 0xb4000263, "e,f,g", 0 },
+{ "m12tsm.ss", 0x4800041d, 0xb40003e2, "e,f,g", 0 },
+{ "m12tsm.sd", 0x4800049d, 0xb4000362, "e,f,g", 0 },
+{ "m12tsm.dd", 0x4800059d, 0xb4000262, "e,f,g", 0 },
+{ "ia1s2.ss", 0x4800041e, 0xb40003e1, "e,f,g", 0 },
+{ "ia1s2.sd", 0x4800049e, 0xb4000361, "e,f,g", 0 },
+{ "ia1s2.dd", 0x4800059e, 0xb4000261, "e,f,g", 0 },
+{ "m12tsa.ss", 0x4800041f, 0xb40003e0, "e,f,g", 0 },
+{ "m12tsa.sd", 0x4800049f, 0xb4000360, "e,f,g", 0 },
+{ "m12tsa.dd", 0x4800059f, 0xb4000260, "e,f,g", 0 },
+
+/* Floating Point Escape Instruction Format - pfmam.p fsrc1,fsrc2,fdest */
+{ "mr2p1.ss", 0x48000000, 0xb40007ff, "e,f,g", 0 },
+{ "mr2p1.sd", 0x48000080, 0xb400077f, "e,f,g", 0 },
+{ "mr2p1.dd", 0x48000180, 0xb400067f, "e,f,g", 0 },
+{ "mr2pt.ss", 0x48000001, 0xb40007fe, "e,f,g", 0 },
+{ "mr2pt.sd", 0x48000081, 0xb400077e, "e,f,g", 0 },
+{ "mr2pt.dd", 0x48000181, 0xb400067e, "e,f,g", 0 },
+{ "mr2mp1.ss", 0x48000002, 0xb40007fd, "e,f,g", 0 },
+{ "mr2mp1.sd", 0x48000082, 0xb400077d, "e,f,g", 0 },
+{ "mr2mp1.dd", 0x48000182, 0xb400067d, "e,f,g", 0 },
+{ "mr2mpt.ss", 0x48000003, 0xb40007fc, "e,f,g", 0 },
+{ "mr2mpt.sd", 0x48000083, 0xb400077c, "e,f,g", 0 },
+{ "mr2mpt.dd", 0x48000183, 0xb400067c, "e,f,g", 0 },
+{ "mi2p1.ss", 0x48000004, 0xb40007fb, "e,f,g", 0 },
+{ "mi2p1.sd", 0x48000084, 0xb400077b, "e,f,g", 0 },
+{ "mi2p1.dd", 0x48000184, 0xb400067b, "e,f,g", 0 },
+{ "mi2pt.ss", 0x48000005, 0xb40007fa, "e,f,g", 0 },
+{ "mi2pt.sd", 0x48000085, 0xb400077a, "e,f,g", 0 },
+{ "mi2pt.dd", 0x48000185, 0xb400067a, "e,f,g", 0 },
+{ "mi2mp1.ss", 0x48000006, 0xb40007f9, "e,f,g", 0 },
+{ "mi2mp1.sd", 0x48000086, 0xb4000779, "e,f,g", 0 },
+{ "mi2mp1.dd", 0x48000186, 0xb4000679, "e,f,g", 0 },
+{ "mi2mpt.ss", 0x48000007, 0xb40007f8, "e,f,g", 0 },
+{ "mi2mpt.sd", 0x48000087, 0xb4000778, "e,f,g", 0 },
+{ "mi2mpt.dd", 0x48000187, 0xb4000678, "e,f,g", 0 },
+{ "mrmt1p2.ss", 0x48000008, 0xb40007f7, "e,f,g", 0 },
+{ "mrmt1p2.sd", 0x48000088, 0xb4000777, "e,f,g", 0 },
+{ "mrmt1p2.dd", 0x48000188, 0xb4000677, "e,f,g", 0 },
+{ "mm12mpm.ss", 0x48000009, 0xb40007f6, "e,f,g", 0 },
+{ "mm12mpm.sd", 0x48000089, 0xb4000776, "e,f,g", 0 },
+{ "mm12mpm.dd", 0x48000189, 0xb4000676, "e,f,g", 0 },
+{ "mrm1p2.ss", 0x4800000a, 0xb40007f5, "e,f,g", 0 },
+{ "mrm1p2.sd", 0x4800008a, 0xb4000775, "e,f,g", 0 },
+{ "mrm1p2.dd", 0x4800018a, 0xb4000675, "e,f,g", 0 },
+{ "mm12ttpm.ss",0x4800000b, 0xb40007f4, "e,f,g", 0 },
+{ "mm12ttpm.sd",0x4800008b, 0xb4000774, "e,f,g", 0 },
+{ "mm12ttpm.dd",0x4800018b, 0xb4000674, "e,f,g", 0 },
+{ "mimt1p2.ss", 0x4800000c, 0xb40007f3, "e,f,g", 0 },
+{ "mimt1p2.sd", 0x4800008c, 0xb4000773, "e,f,g", 0 },
+{ "mimt1p2.dd", 0x4800018c, 0xb4000673, "e,f,g", 0 },
+{ "mm12tpm.ss", 0x4800000d, 0xb40007f2, "e,f,g", 0 },
+{ "mm12tpm.sd", 0x4800008d, 0xb4000772, "e,f,g", 0 },
+{ "mm12tpm.dd", 0x4800018d, 0xb4000672, "e,f,g", 0 },
+{ "mim1p2.ss", 0x4800000e, 0xb40007f1, "e,f,g", 0 },
+{ "mim1p2.sd", 0x4800008e, 0xb4000771, "e,f,g", 0 },
+{ "mim1p2.dd", 0x4800018e, 0xb4000671, "e,f,g", 0 },
+
+/* Floating Point Escape Instruction Format - pfmsm.p fsrc1,fsrc2,fdest */
+{ "mr2s1.ss", 0x48000010, 0xb40007ef, "e,f,g", 0 },
+{ "mr2s1.sd", 0x48000090, 0xb400076f, "e,f,g", 0 },
+{ "mr2s1.dd", 0x48000190, 0xb400066f, "e,f,g", 0 },
+{ "mr2st.ss", 0x48000011, 0xb40007ee, "e,f,g", 0 },
+{ "mr2st.sd", 0x48000091, 0xb400076e, "e,f,g", 0 },
+{ "mr2st.dd", 0x48000191, 0xb400066e, "e,f,g", 0 },
+{ "mr2ms1.ss", 0x48000012, 0xb40007ed, "e,f,g", 0 },
+{ "mr2ms1.sd", 0x48000092, 0xb400076d, "e,f,g", 0 },
+{ "mr2ms1.dd", 0x48000192, 0xb400066d, "e,f,g", 0 },
+{ "mr2mst.ss", 0x48000013, 0xb40007ec, "e,f,g", 0 },
+{ "mr2mst.sd", 0x48000093, 0xb400076c, "e,f,g", 0 },
+{ "mr2mst.dd", 0x48000193, 0xb400066c, "e,f,g", 0 },
+{ "mi2s1.ss", 0x48000014, 0xb40007eb, "e,f,g", 0 },
+{ "mi2s1.sd", 0x48000094, 0xb400076b, "e,f,g", 0 },
+{ "mi2s1.dd", 0x48000194, 0xb400066b, "e,f,g", 0 },
+{ "mi2st.ss", 0x48000015, 0xb40007ea, "e,f,g", 0 },
+{ "mi2st.sd", 0x48000095, 0xb400076a, "e,f,g", 0 },
+{ "mi2st.dd", 0x48000195, 0xb400066a, "e,f,g", 0 },
+{ "mi2ms1.ss", 0x48000016, 0xb40007e9, "e,f,g", 0 },
+{ "mi2ms1.sd", 0x48000096, 0xb4000769, "e,f,g", 0 },
+{ "mi2ms1.dd", 0x48000196, 0xb4000669, "e,f,g", 0 },
+{ "mi2mst.ss", 0x48000017, 0xb40007e8, "e,f,g", 0 },
+{ "mi2mst.sd", 0x48000097, 0xb4000768, "e,f,g", 0 },
+{ "mi2mst.dd", 0x48000197, 0xb4000668, "e,f,g", 0 },
+{ "mrmt1s2.ss", 0x48000018, 0xb40007e7, "e,f,g", 0 },
+{ "mrmt1s2.sd", 0x48000098, 0xb4000767, "e,f,g", 0 },
+{ "mrmt1s2.dd", 0x48000198, 0xb4000667, "e,f,g", 0 },
+{ "mm12msm.ss", 0x48000019, 0xb40007e6, "e,f,g", 0 },
+{ "mm12msm.sd", 0x48000099, 0xb4000766, "e,f,g", 0 },
+{ "mm12msm.dd", 0x48000199, 0xb4000666, "e,f,g", 0 },
+{ "mrm1s2.ss", 0x4800001a, 0xb40007e5, "e,f,g", 0 },
+{ "mrm1s2.sd", 0x4800009a, 0xb4000765, "e,f,g", 0 },
+{ "mrm1s2.dd", 0x4800019a, 0xb4000665, "e,f,g", 0 },
+{ "mm12ttsm.ss",0x4800001b, 0xb40007e4, "e,f,g", 0 },
+{ "mm12ttsm.sd",0x4800009b, 0xb4000764, "e,f,g", 0 },
+{ "mm12ttsm.dd",0x4800019b, 0xb4000664, "e,f,g", 0 },
+{ "mimt1s2.ss", 0x4800001c, 0xb40007e3, "e,f,g", 0 },
+{ "mimt1s2.sd", 0x4800009c, 0xb4000763, "e,f,g", 0 },
+{ "mimt1s2.dd", 0x4800019c, 0xb4000663, "e,f,g", 0 },
+{ "mm12tsm.ss", 0x4800001d, 0xb40007e2, "e,f,g", 0 },
+{ "mm12tsm.sd", 0x4800009d, 0xb4000762, "e,f,g", 0 },
+{ "mm12tsm.dd", 0x4800019d, 0xb4000662, "e,f,g", 0 },
+{ "mim1s2.ss", 0x4800001e, 0xb40007e1, "e,f,g", 0 },
+{ "mim1s2.sd", 0x4800009e, 0xb4000761, "e,f,g", 0 },
+{ "mim1s2.dd", 0x4800019e, 0xb4000661, "e,f,g", 0 },
+
+
+{ "fmul.ss", 0x48000020, 0xb40007df, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */
+{ "fmul.sd", 0x480000a0, 0xb400075f, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */
+{ "fmul.dd", 0x480001a0, 0xb400065f, "e,f,g", 0 }, /* fmul.p fsrc1,fsrc2,fdest */
+{ "pfmul.ss", 0x48000420, 0xb40003df, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */
+{ "pfmul.sd", 0x480004a0, 0xb400035f, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */
+{ "pfmul.dd", 0x480005a0, 0xb400025f, "e,f,g", 0 }, /* pfmul.p fsrc1,fsrc2,fdest */
+{ "pfmul3.dd", 0x480005a4, 0xb400025b, "e,f,g", 0 }, /* pfmul3.p fsrc1,fsrc2,fdest */
+{ "fmlow.dd", 0x480001a1, 0xb400065e, "e,f,g", 0 }, /* fmlow.dd fsrc1,fsrc2,fdest */
+{ "frcp.ss", 0x48000022, 0xb40007dd, "f,g", 0 }, /* frcp.p fsrc2,fdest */
+{ "frcp.sd", 0x480000a2, 0xb400075d, "f,g", 0 }, /* frcp.p fsrc2,fdest */
+{ "frcp.dd", 0x480001a2, 0xb400065d, "f,g", 0 }, /* frcp.p fsrc2,fdest */
+{ "frsqr.ss", 0x48000023, 0xb40007dc, "f,g", 0 }, /* frsqr.p fsrc2,fdest */
+{ "frsqr.sd", 0x480000a3, 0xb400075c, "f,g", 0 }, /* frsqr.p fsrc2,fdest */
+{ "frsqr.dd", 0x480001a3, 0xb400065c, "f,g", 0 }, /* frsqr.p fsrc2,fdest */
+{ "fadd.ss", 0x48000030, 0xb40007cf, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */
+{ "fadd.sd", 0x480000b0, 0xb400074f, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */
+{ "fadd.dd", 0x480001b0, 0xb400064f, "e,f,g", 0 }, /* fadd.p fsrc1,fsrc2,fdest */
+{ "pfadd.ss", 0x48000430, 0xb40003cf, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */
+{ "pfadd.sd", 0x480004b0, 0xb400034f, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */
+{ "pfadd.dd", 0x480005b0, 0xb400024f, "e,f,g", 0 }, /* pfadd.p fsrc1,fsrc2,fdest */
+{ "fsub.ss", 0x48000031, 0xb40007ce, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */
+{ "fsub.sd", 0x480000b1, 0xb400074e, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */
+{ "fsub.dd", 0x480001b1, 0xb400064e, "e,f,g", 0 }, /* fsub.p fsrc1,fsrc2,fdest */
+{ "pfsub.ss", 0x48000431, 0xb40003ce, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */
+{ "pfsub.sd", 0x480004b1, 0xb400034e, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */
+{ "pfsub.dd", 0x480005b1, 0xb400024e, "e,f,g", 0 }, /* pfsub.p fsrc1,fsrc2,fdest */
+{ "fix.ss", 0x48000032, 0xb40007cd, "e,g", 0 }, /* fix.p fsrc1,fdest */
+{ "fix.sd", 0x480000b2, 0xb400074d, "e,g", 0 }, /* fix.p fsrc1,fdest */
+{ "fix.dd", 0x480001b2, 0xb400064d, "e,g", 0 }, /* fix.p fsrc1,fdest */
+{ "pfix.ss", 0x48000432, 0xb40003cd, "e,g", 0 }, /* pfix.p fsrc1,fdest */
+{ "pfix.sd", 0x480004b2, 0xb400034d, "e,g", 0 }, /* pfix.p fsrc1,fdest */
+{ "pfix.dd", 0x480005b2, 0xb400024d, "e,g", 0 }, /* pfix.p fsrc1,fdest */
+{ "famov.ss", 0x48000033, 0xb40007cc, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "famov.ds", 0x48000133, 0xb40006cc, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "famov.sd", 0x480000b3, 0xb400074c, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "famov.dd", 0x480001b3, 0xb400064c, "e,g", 0 }, /* famov.p fsrc1,fdest */
+{ "pfamov.ss", 0x48000433, 0xb40003cc, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+{ "pfamov.ds", 0x48000533, 0xb40002cc, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+{ "pfamov.sd", 0x480004b3, 0xb400034c, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+{ "pfamov.dd", 0x480005b3, 0xb400024c, "e,g", 0 }, /* pfamov.p fsrc1,fdest */
+/* pfgt has R bit cleared; pfle has R bit set */
+{ "pfgt.ss", 0x48000434, 0xb40003cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */
+{ "pfgt.sd", 0x48000434, 0xb40003cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */
+{ "pfgt.dd", 0x48000534, 0xb40002cb, "e,f,g", 0 }, /* pfgt.p fsrc1,fsrc2,fdest */
+/* pfgt has R bit cleared; pfle has R bit set */
+{ "pfle.ss", 0x480004b4, 0xb400034b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */
+{ "pfle.sd", 0x480004b4, 0xb400034b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */
+{ "pfle.dd", 0x480005b4, 0xb400024b, "e,f,g", 0 }, /* pfle.p fsrc1,fsrc2,fdest */
+{ "ftrunc.ss", 0x4800003a, 0xb40007c5, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */
+{ "ftrunc.sd", 0x480000ba, 0xb4000745, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */
+{ "ftrunc.dd", 0x480001ba, 0xb4000645, "e,g", 0 }, /* ftrunc.p fsrc1,fdest */
+{ "pftrunc.ss", 0x4800043a, 0xb40003c5, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */
+{ "pftrunc.sd", 0x480004ba, 0xb4000345, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */
+{ "pftrunc.dd", 0x480005ba, 0xb4000245, "e,g", 0 }, /* pftrunc.p fsrc1,fdest */
+{ "fxfr", 0x48000040, 0xb40007bf, "e,d", 0 }, /* fxfr fsrc1,idest */
+{ "fiadd.ss", 0x48000049, 0xb40007b6, "e,f,g", 0 }, /* fiadd.w fsrc1,fsrc2,fdest */
+{ "fiadd.dd", 0x480001c9, 0xb4000636, "e,f,g", 0 }, /* fiadd.w fsrc1,fsrc2,fdest */
+{ "pfiadd.ss", 0x48000449, 0xb40003b6, "e,f,g", 0 }, /* pfiadd.w fsrc1,fsrc2,fdest */
+{ "pfiadd.dd", 0x480005c9, 0xb4000236, "e,f,g", 0 }, /* pfiadd.w fsrc1,fsrc2,fdest */
+{ "fisub.ss", 0x4800004d, 0xb40007b2, "e,f,g", 0 }, /* fisub.w fsrc1,fsrc2,fdest */
+{ "fisub.dd", 0x480001cd, 0xb4000632, "e,f,g", 0 }, /* fisub.w fsrc1,fsrc2,fdest */
+{ "pfisub.ss", 0x4800044d, 0xb40003b2, "e,f,g", 0 }, /* pfisub.w fsrc1,fsrc2,fdest */
+{ "pfisub.dd", 0x480005cd, 0xb4000232, "e,f,g", 0 }, /* pfisub.w fsrc1,fsrc2,fdest */
+{ "fzchkl", 0x48000057, 0xb40007a8, "e,f,g", 0 }, /* fzchkl fsrc1,fsrc2,fdest */
+{ "pfzchkl", 0x48000457, 0xb40003a8, "e,f,g", 0 }, /* pfzchkl fsrc1,fsrc2,fdest */
+{ "fzchks", 0x4800005f, 0xb40007a0, "e,f,g", 0 }, /* fzchks fsrc1,fsrc2,fdest */
+{ "pfzchks", 0x4800045f, 0xb40003a0, "e,f,g", 0 }, /* pfzchks fsrc1,fsrc2,fdest */
+{ "faddp", 0x48000050, 0xb40007af, "e,f,g", 0 }, /* faddp fsrc1,fsrc2,fdest */
+{ "pfaddp", 0x48000450, 0xb40003af, "e,f,g", 0 }, /* pfaddp fsrc1,fsrc2,fdest */
+{ "faddz", 0x48000051, 0xb40007ae, "e,f,g", 0 }, /* faddz fsrc1,fsrc2,fdest */
+{ "pfaddz", 0x48000451, 0xb40003ae, "e,f,g", 0 }, /* pfaddz fsrc1,fsrc2,fdest */
+{ "form", 0x4800005a, 0xb40007a5, "e,g", 0 }, /* form fsrc1,fdest */
+{ "pform", 0x4800045a, 0xb40003a5, "e,g", 0 }, /* pform fsrc1,fdest */
+
+/* Floating point pseudo-instructions */
+{ "fmov.ss", 0x48000049, 0xb7e007b6, "e,g", 0 }, /* fiadd.ss fsrc1,f0,fdest */
+{ "fmov.dd", 0x480001c9, 0xb7e00636, "e,g", 0 }, /* fiadd.dd fsrc1,f0,fdest */
+{ "fmov.sd", 0x480000b0, 0xb7e0074f, "e,g", 0 }, /* fadd.sd fsrc1,f0,fdest */
+{ "fmov.ds", 0x48000130, 0xb7e006cf, "e,g", 0 }, /* fadd.ds fsrc1,f0,fdest */
+{ "pfmov.ds", 0x48000530, 0xb73002cf, "e,g", 0 }, /* pfadd.ds fsrc1,f0,fdest */
+{ "pfmov.dd", 0x480005c9, 0xb7e00236, "e,g", 0 }, /* pfiadd.dd fsrc1,f0,fdest */
+
+
+};
+
+#define NUMOPCODES ((sizeof i860_opcodes)/(sizeof i860_opcodes[0]))
+
+
diff --git a/include/opcode/i960.h b/include/opcode/i960.h
new file mode 100644
index 00000000000..b52fc338737
--- /dev/null
+++ b/include/opcode/i960.h
@@ -0,0 +1,509 @@
+/* Basic 80960 instruction formats.
+ *
+ * The 'COJ' instructions are actually COBR instructions with the 'b' in
+ * the mnemonic replaced by a 'j'; they are ALWAYS "de-optimized" if necessary:
+ * if the displacement will not fit in 13 bits, the assembler will replace them
+ * with the corresponding compare and branch instructions.
+ *
+ * All of the 'MEMn' instructions are the same format; the 'n' in the name
+ * indicates the default index scale factor (the size of the datum operated on).
+ *
+ * The FBRA formats are not actually an instruction format. They are the
+ * "convenience directives" for branching on floating-point comparisons,
+ * each of which generates 2 instructions (a 'bno' and one other branch).
+ *
+ * The CALLJ format is not actually an instruction format. It indicates that
+ * the instruction generated (a CTRL-format 'call') should have its relocation
+ * specially flagged for link-time replacement with a 'bal' or 'calls' if
+ * appropriate.
+ */
+
+#define CTRL 0
+#define COBR 1
+#define COJ 2
+#define REG 3
+#define MEM1 4
+#define MEM2 5
+#define MEM4 6
+#define MEM8 7
+#define MEM12 8
+#define MEM16 9
+#define FBRA 10
+#define CALLJ 11
+
+/* Masks for the mode bits in REG format instructions */
+#define M1 0x0800
+#define M2 0x1000
+#define M3 0x2000
+
+/* Generate the 12-bit opcode for a REG format instruction by placing the
+ * high 8 bits in instruction bits 24-31, the low 4 bits in instruction bits
+ * 7-10.
+ */
+
+#define REG_OPC(opc) ((opc & 0xff0) << 20) | ((opc & 0xf) << 7)
+
+/* Generate a template for a REG format instruction: place the opcode bits
+ * in the appropriate fields and OR in mode bits for the operands that will not
+ * be used. I.e.,
+ * set m1=1, if src1 will not be used
+ * set m2=1, if src2 will not be used
+ * set m3=1, if dst will not be used
+ *
+ * Setting the "unused" mode bits to 1 speeds up instruction execution(!).
+ * The information is also useful to us because some 1-operand REG instructions
+ * use the src1 field, others the dst field; and some 2-operand REG instructions
+ * use src1/src2, others src1/dst. The set mode bits enable us to distinguish.
+ */
+#define R_0(opc) ( REG_OPC(opc) | M1 | M2 | M3 ) /* No operands */
+#define R_1(opc) ( REG_OPC(opc) | M2 | M3 ) /* 1 operand: src1 */
+#define R_1D(opc) ( REG_OPC(opc) | M1 | M2 ) /* 1 operand: dst */
+#define R_2(opc) ( REG_OPC(opc) | M3 ) /* 2 ops: src1/src2 */
+#define R_2D(opc) ( REG_OPC(opc) | M2 ) /* 2 ops: src1/dst */
+#define R_3(opc) ( REG_OPC(opc) ) /* 3 operands */
+
+/* DESCRIPTOR BYTES FOR REGISTER OPERANDS
+ *
+ * Interpret names as follows:
+ * R: global or local register only
+ * RS: global, local, or (if target allows) special-function register only
+ * RL: global or local register, or integer literal
+ * RSL: global, local, or (if target allows) special-function register;
+ * or integer literal
+ * F: global, local, or floating-point register
+ * FL: global, local, or floating-point register; or literal (including
+ * floating point)
+ *
+ * A number appended to a name indicates that registers must be aligned,
+ * as follows:
+ * 2: register number must be multiple of 2
+ * 4: register number must be multiple of 4
+ */
+
+#define SFR 0x10 /* Mask for the "sfr-OK" bit */
+#define LIT 0x08 /* Mask for the "literal-OK" bit */
+#define FP 0x04 /* Mask for "floating-point-OK" bit */
+
+/* This macro ors the bits together. Note that 'align' is a mask
+ * for the low 0, 1, or 2 bits of the register number, as appropriate.
+ */
+#define OP(align,lit,fp,sfr) ( align | lit | fp | sfr )
+
+#define R OP( 0, 0, 0, 0 )
+#define RS OP( 0, 0, 0, SFR )
+#define RL OP( 0, LIT, 0, 0 )
+#define RSL OP( 0, LIT, 0, SFR )
+#define F OP( 0, 0, FP, 0 )
+#define FL OP( 0, LIT, FP, 0 )
+#define R2 OP( 1, 0, 0, 0 )
+#define RL2 OP( 1, LIT, 0, 0 )
+#define F2 OP( 1, 0, FP, 0 )
+#define FL2 OP( 1, LIT, FP, 0 )
+#define R4 OP( 3, 0, 0, 0 )
+#define RL4 OP( 3, LIT, 0, 0 )
+#define F4 OP( 3, 0, FP, 0 )
+#define FL4 OP( 3, LIT, FP, 0 )
+
+#define M 0x7f /* Memory operand (MEMA & MEMB format instructions) */
+
+/* Macros to extract info from the register operand descriptor byte 'od'.
+ */
+#define SFR_OK(od) (od & SFR) /* TRUE if sfr operand allowed */
+#define LIT_OK(od) (od & LIT) /* TRUE if literal operand allowed */
+#define FP_OK(od) (od & FP) /* TRUE if floating-point op allowed */
+#define REG_ALIGN(od,n) ((od & 0x3 & n) == 0)
+ /* TRUE if reg #n is properly aligned */
+#define MEMOP(od) (od == M) /* TRUE if operand is a memory operand*/
+
+/* Description of a single i80960 instruction */
+struct i960_opcode {
+ long opcode; /* 32 bits, constant fields filled in, rest zeroed */
+ char *name; /* Assembler mnemonic */
+ short iclass; /* Class: see #defines below */
+ char format; /* REG, COBR, CTRL, MEMn, COJ, FBRA, or CALLJ */
+ char num_ops; /* Number of operands */
+ char operand[3];/* Operand descriptors; same order as assembler instr */
+};
+
+/* Classes of 960 intructions:
+ * - each instruction falls into one class.
+ * - each target architecture supports one or more classes.
+ *
+ * EACH CONSTANT MUST CONTAIN 1 AND ONLY 1 SET BIT!: see targ_has_iclass().
+ */
+#define I_BASE 0x01 /* 80960 base instruction set */
+#define I_CX 0x02 /* 80960Cx instruction */
+#define I_DEC 0x04 /* Decimal instruction */
+#define I_FP 0x08 /* Floating point instruction */
+#define I_KX 0x10 /* 80960Kx instruction */
+#define I_MIL 0x20 /* Military instruction */
+#define I_CASIM 0x40 /* CA simulator instruction */
+#define I_CX2 0x80 /* Cx/Jx/Hx instructions */
+#define I_JX 0x100 /* Jx/Hx instruction */
+#define I_HX 0x200 /* Hx instructions */
+
+/******************************************************************************
+ *
+ * TABLE OF i960 INSTRUCTION DESCRIPTIONS
+ *
+ ******************************************************************************/
+
+const struct i960_opcode i960_opcodes[] = {
+
+ /* if a CTRL instruction has an operand, it's always a displacement */
+
+ /* callj default=='call' */
+ { 0x09000000, "callj", I_BASE, CALLJ, 1, { 0, 0, 0 } },
+ { 0x08000000, "b", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x09000000, "call", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x0a000000, "ret", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x0b000000, "bal", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x10000000, "bno", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* bf same as bno */
+ { 0x10000000, "bf", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* bru same as bno */
+ { 0x10000000, "bru", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x11000000, "bg", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* brg same as bg */
+ { 0x11000000, "brg", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x12000000, "be", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* bre same as be */
+ { 0x12000000, "bre", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x13000000, "bge", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* brge same as bge */
+ { 0x13000000, "brge", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x14000000, "bl", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* brl same as bl */
+ { 0x14000000, "brl", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x15000000, "bne", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* brlg same as bne */
+ { 0x15000000, "brlg", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x16000000, "ble", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* brle same as ble */
+ { 0x16000000, "brle", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x17000000, "bo", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* bt same as bo */
+ { 0x17000000, "bt", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ /* bro same as bo */
+ { 0x17000000, "bro", I_BASE, CTRL, 1, { 0, 0, 0 } },
+ { 0x18000000, "faultno", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ /* faultf same as faultno */
+ { 0x18000000, "faultf", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x19000000, "faultg", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x1a000000, "faulte", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x1b000000, "faultge", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x1c000000, "faultl", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x1d000000, "faultne", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x1e000000, "faultle", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ { 0x1f000000, "faulto", I_BASE, CTRL, 0, { 0, 0, 0 } },
+ /* faultt syn for faulto */
+ { 0x1f000000, "faultt", I_BASE, CTRL, 0, { 0, 0, 0 } },
+
+ { 0x01000000, "syscall", I_CASIM,CTRL, 0, { 0, 0, 0 } },
+
+ /* If a COBR (or COJ) has 3 operands, the last one is always a
+ * displacement and does not appear explicitly in the table.
+ */
+
+ { 0x20000000, "testno", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x21000000, "testg", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x22000000, "teste", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x23000000, "testge", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x24000000, "testl", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x25000000, "testne", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x26000000, "testle", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x27000000, "testo", I_BASE, COBR, 1, { R, 0, 0 } },
+ { 0x30000000, "bbc", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x31000000, "cmpobg", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x32000000, "cmpobe", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x33000000, "cmpobge", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x34000000, "cmpobl", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x35000000, "cmpobne", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x36000000, "cmpoble", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x37000000, "bbs", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x38000000, "cmpibno", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x39000000, "cmpibg", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x3a000000, "cmpibe", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x3b000000, "cmpibge", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x3c000000, "cmpibl", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x3d000000, "cmpibne", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x3e000000, "cmpible", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x3f000000, "cmpibo", I_BASE, COBR, 3, { RL, RS, 0 } },
+ { 0x31000000, "cmpojg", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x32000000, "cmpoje", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x33000000, "cmpojge", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x34000000, "cmpojl", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x35000000, "cmpojne", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x36000000, "cmpojle", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x38000000, "cmpijno", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x39000000, "cmpijg", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x3a000000, "cmpije", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x3b000000, "cmpijge", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x3c000000, "cmpijl", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x3d000000, "cmpijne", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x3e000000, "cmpijle", I_BASE, COJ, 3, { RL, RS, 0 } },
+ { 0x3f000000, "cmpijo", I_BASE, COJ, 3, { RL, RS, 0 } },
+
+ { 0x80000000, "ldob", I_BASE, MEM1, 2, { M, R, 0 } },
+ { 0x82000000, "stob", I_BASE, MEM1, 2, { R, M, 0 } },
+ { 0x84000000, "bx", I_BASE, MEM1, 1, { M, 0, 0 } },
+ { 0x85000000, "balx", I_BASE, MEM1, 2, { M, R, 0 } },
+ { 0x86000000, "callx", I_BASE, MEM1, 1, { M, 0, 0 } },
+ { 0x88000000, "ldos", I_BASE, MEM2, 2, { M, R, 0 } },
+ { 0x8a000000, "stos", I_BASE, MEM2, 2, { R, M, 0 } },
+ { 0x8c000000, "lda", I_BASE, MEM1, 2, { M, R, 0 } },
+ { 0x90000000, "ld", I_BASE, MEM4, 2, { M, R, 0 } },
+ { 0x92000000, "st", I_BASE, MEM4, 2, { R, M, 0 } },
+ { 0x98000000, "ldl", I_BASE, MEM8, 2, { M, R2, 0 } },
+ { 0x9a000000, "stl", I_BASE, MEM8, 2, { R2, M, 0 } },
+ { 0xa0000000, "ldt", I_BASE, MEM12, 2, { M, R4, 0 } },
+ { 0xa2000000, "stt", I_BASE, MEM12, 2, { R4, M, 0 } },
+ { 0xb0000000, "ldq", I_BASE, MEM16, 2, { M, R4, 0 } },
+ { 0xb2000000, "stq", I_BASE, MEM16, 2, { R4, M, 0 } },
+ { 0xc0000000, "ldib", I_BASE, MEM1, 2, { M, R, 0 } },
+ { 0xc2000000, "stib", I_BASE, MEM1, 2, { R, M, 0 } },
+ { 0xc8000000, "ldis", I_BASE, MEM2, 2, { M, R, 0 } },
+ { 0xca000000, "stis", I_BASE, MEM2, 2, { R, M, 0 } },
+
+ { R_3(0x580), "notbit", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x581), "and", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x582), "andnot", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x583), "setbit", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x584), "notand", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x586), "xor", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x587), "or", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x588), "nor", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x589), "xnor", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_2D(0x58a), "not", I_BASE, REG, 2, { RSL,RS, 0 } },
+ { R_3(0x58b), "ornot", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x58c), "clrbit", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x58d), "notor", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x58e), "nand", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x58f), "alterbit", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x590), "addo", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x591), "addi", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x592), "subo", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x593), "subi", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x598), "shro", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x59a), "shrdi", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x59b), "shri", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x59c), "shlo", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x59d), "rotate", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x59e), "shli", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_2(0x5a0), "cmpo", I_BASE, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x5a1), "cmpi", I_BASE, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x5a2), "concmpo", I_BASE, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x5a3), "concmpi", I_BASE, REG, 2, { RSL,RSL, 0 } },
+ { R_3(0x5a4), "cmpinco", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x5a5), "cmpinci", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x5a6), "cmpdeco", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x5a7), "cmpdeci", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_2(0x5ac), "scanbyte", I_BASE, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x5ae), "chkbit", I_BASE, REG, 2, { RSL,RSL, 0 } },
+ { R_3(0x5b0), "addc", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x5b2), "subc", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_2D(0x5cc), "mov", I_BASE, REG, 2, { RSL,RS, 0 } },
+ { R_2D(0x5dc), "movl", I_BASE, REG, 2, { RL2,R2, 0 } },
+ { R_2D(0x5ec), "movt", I_BASE, REG, 2, { RL4,R4, 0 } },
+ { R_2D(0x5fc), "movq", I_BASE, REG, 2, { RL4,R4, 0 } },
+ { R_3(0x610), "atmod", I_BASE, REG, 3, { RS, RSL,R } },
+ { R_3(0x612), "atadd", I_BASE, REG, 3, { RS, RSL,RS } },
+ { R_2D(0x640), "spanbit", I_BASE, REG, 2, { RSL,RS, 0 } },
+ { R_2D(0x641), "scanbit", I_BASE, REG, 2, { RSL,RS, 0 } },
+ { R_3(0x645), "modac", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x650), "modify", I_BASE, REG, 3, { RSL,RSL,R } },
+ { R_3(0x651), "extract", I_BASE, REG, 3, { RSL,RSL,R } },
+ { R_3(0x654), "modtc", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x655), "modpc", I_BASE, REG, 3, { RSL,RSL,R } },
+ { R_1(0x660), "calls", I_BASE, REG, 1, { RSL, 0, 0 } },
+ { R_0(0x66b), "mark", I_BASE, REG, 0, { 0, 0, 0 } },
+ { R_0(0x66c), "fmark", I_BASE, REG, 0, { 0, 0, 0 } },
+ { R_0(0x66d), "flushreg", I_BASE, REG, 0, { 0, 0, 0 } },
+ { R_0(0x66f), "syncf", I_BASE, REG, 0, { 0, 0, 0 } },
+ { R_3(0x670), "emul", I_BASE, REG, 3, { RSL,RSL,R2 } },
+ { R_3(0x671), "ediv", I_BASE, REG, 3, { RSL,RL2,RS } },
+ { R_2D(0x672), "cvtadr", I_CASIM,REG, 2, { RL, R2, 0 } },
+ { R_3(0x701), "mulo", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x708), "remo", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x70b), "divo", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x741), "muli", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x748), "remi", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x749), "modi", I_BASE, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x74b), "divi", I_BASE, REG, 3, { RSL,RSL,RS } },
+
+ /* Floating-point instructions */
+
+ { R_2D(0x674), "cvtir", I_FP, REG, 2, { RL, F, 0 } },
+ { R_2D(0x675), "cvtilr", I_FP, REG, 2, { RL, F, 0 } },
+ { R_3(0x676), "scalerl", I_FP, REG, 3, { RL, FL2,F2 } },
+ { R_3(0x677), "scaler", I_FP, REG, 3, { RL, FL, F } },
+ { R_3(0x680), "atanr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x681), "logepr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x682), "logr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x683), "remr", I_FP, REG, 3, { FL, FL, F } },
+ { R_2(0x684), "cmpor", I_FP, REG, 2, { FL, FL, 0 } },
+ { R_2(0x685), "cmpr", I_FP, REG, 2, { FL, FL, 0 } },
+ { R_2D(0x688), "sqrtr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x689), "expr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x68a), "logbnr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x68b), "roundr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x68c), "sinr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x68d), "cosr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x68e), "tanr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_1(0x68f), "classr", I_FP, REG, 1, { FL, 0, 0 } },
+ { R_3(0x690), "atanrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_3(0x691), "logeprl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_3(0x692), "logrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_3(0x693), "remrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_2(0x694), "cmporl", I_FP, REG, 2, { FL2,FL2, 0 } },
+ { R_2(0x695), "cmprl", I_FP, REG, 2, { FL2,FL2, 0 } },
+ { R_2D(0x698), "sqrtrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x699), "exprl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x69a), "logbnrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x69b), "roundrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x69c), "sinrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x69d), "cosrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x69e), "tanrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_1(0x69f), "classrl", I_FP, REG, 1, { FL2, 0, 0 } },
+ { R_2D(0x6c0), "cvtri", I_FP, REG, 2, { FL, R, 0 } },
+ { R_2D(0x6c1), "cvtril", I_FP, REG, 2, { FL, R2, 0 } },
+ { R_2D(0x6c2), "cvtzri", I_FP, REG, 2, { FL, R, 0 } },
+ { R_2D(0x6c3), "cvtzril", I_FP, REG, 2, { FL, R2, 0 } },
+ { R_2D(0x6c9), "movr", I_FP, REG, 2, { FL, F, 0 } },
+ { R_2D(0x6d9), "movrl", I_FP, REG, 2, { FL2,F2, 0 } },
+ { R_2D(0x6e1), "movre", I_FP, REG, 2, { FL4,F4, 0 } },
+ { R_3(0x6e2), "cpysre", I_FP, REG, 3, { FL4,FL4,F4 } },
+ { R_3(0x6e3), "cpyrsre", I_FP, REG, 3, { FL4,FL4,F4 } },
+ { R_3(0x78b), "divr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x78c), "mulr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x78d), "subr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x78f), "addr", I_FP, REG, 3, { FL, FL, F } },
+ { R_3(0x79b), "divrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_3(0x79c), "mulrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_3(0x79d), "subrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+ { R_3(0x79f), "addrl", I_FP, REG, 3, { FL2,FL2,F2 } },
+
+ /* These are the floating point branch instructions. Each actually
+ * generates 2 branch instructions: the first a CTRL instruction with
+ * the indicated opcode, and the second a 'bno'.
+ */
+
+ { 0x12000000, "brue", I_FP, FBRA, 1, { 0, 0, 0 } },
+ { 0x11000000, "brug", I_FP, FBRA, 1, { 0, 0, 0 } },
+ { 0x13000000, "bruge", I_FP, FBRA, 1, { 0, 0, 0 } },
+ { 0x14000000, "brul", I_FP, FBRA, 1, { 0, 0, 0 } },
+ { 0x16000000, "brule", I_FP, FBRA, 1, { 0, 0, 0 } },
+ { 0x15000000, "brulg", I_FP, FBRA, 1, { 0, 0, 0 } },
+
+
+ /* Decimal instructions */
+
+ { R_3(0x642), "daddc", I_DEC, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x643), "dsubc", I_DEC, REG, 3, { RSL,RSL,RS } },
+ { R_2D(0x644), "dmovt", I_DEC, REG, 2, { RSL,RS, 0 } },
+
+
+ /* KX extensions */
+
+ { R_2(0x600), "synmov", I_KX, REG, 2, { R, R, 0 } },
+ { R_2(0x601), "synmovl", I_KX, REG, 2, { R, R, 0 } },
+ { R_2(0x602), "synmovq", I_KX, REG, 2, { R, R, 0 } },
+ { R_2D(0x615), "synld", I_KX, REG, 2, { R, R, 0 } },
+
+
+ /* MC extensions */
+
+ { R_3(0x603), "cmpstr", I_MIL, REG, 3, { R, R, RL } },
+ { R_3(0x604), "movqstr", I_MIL, REG, 3, { R, R, RL } },
+ { R_3(0x605), "movstr", I_MIL, REG, 3, { R, R, RL } },
+ { R_2D(0x613), "inspacc", I_MIL, REG, 2, { R, R, 0 } },
+ { R_2D(0x614), "ldphy", I_MIL, REG, 2, { R, R, 0 } },
+ { R_3(0x617), "fill", I_MIL, REG, 3, { R, RL, RL } },
+ { R_2D(0x646), "condrec", I_MIL, REG, 2, { R, R, 0 } },
+ { R_2D(0x656), "receive", I_MIL, REG, 2, { R, R, 0 } },
+ { R_3(0x662), "send", I_MIL, REG, 3, { R, RL, R } },
+ { R_1(0x663), "sendserv", I_MIL, REG, 1, { R, 0, 0 } },
+ { R_1(0x664), "resumprcs", I_MIL, REG, 1, { R, 0, 0 } },
+ { R_1(0x665), "schedprcs", I_MIL, REG, 1, { R, 0, 0 } },
+ { R_0(0x666), "saveprcs", I_MIL, REG, 0, { 0, 0, 0 } },
+ { R_1(0x668), "condwait", I_MIL, REG, 1, { R, 0, 0 } },
+ { R_1(0x669), "wait", I_MIL, REG, 1, { R, 0, 0 } },
+ { R_1(0x66a), "signal", I_MIL, REG, 1, { R, 0, 0 } },
+ { R_1D(0x673), "ldtime", I_MIL, REG, 1, { R2, 0, 0 } },
+
+
+ /* CX extensions */
+
+ { R_3(0x5d8), "eshro", I_CX2, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x630), "sdma", I_CX, REG, 3, { RSL,RSL,RL } },
+ { R_3(0x631), "udma", I_CX, REG, 0, { 0, 0, 0 } },
+ { R_3(0x659), "sysctl", I_CX2, REG, 3, { RSL,RSL,RL } },
+
+
+ /* Jx extensions. */
+ { R_3(0x780), "addono", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x790), "addog", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7a0), "addoe", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7b0), "addoge", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7c0), "addol", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7d0), "addone", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7e0), "addole", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7f0), "addoo", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x781), "addino", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x791), "addig", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7a1), "addie", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7b1), "addige", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7c1), "addil", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7d1), "addine", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7e1), "addile", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7f1), "addio", I_JX, REG, 3, { RSL,RSL,RS } },
+
+ { R_2D(0x5ad), "bswap", I_JX, REG, 2, { RSL, RS, 0 } },
+
+ { R_2(0x594), "cmpob", I_JX, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x595), "cmpib", I_JX, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x596), "cmpos", I_JX, REG, 2, { RSL,RSL, 0 } },
+ { R_2(0x597), "cmpis", I_JX, REG, 2, { RSL,RSL, 0 } },
+
+ { R_3(0x784), "selno", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x794), "selg", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7a4), "sele", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7b4), "selge", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7c4), "sell", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7d4), "selne", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7e4), "selle", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7f4), "selo", I_JX, REG, 3, { RSL,RSL,RS } },
+
+ { R_3(0x782), "subono", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x792), "subog", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7a2), "suboe", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7b2), "suboge", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7c2), "subol", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7d2), "subone", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7e2), "subole", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7f2), "suboo", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x783), "subino", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x793), "subig", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7a3), "subie", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7b3), "subige", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7c3), "subil", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7d3), "subine", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7e3), "subile", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_3(0x7f3), "subio", I_JX, REG, 3, { RSL,RSL,RS } },
+
+ { R_3(0x65c), "dcctl", I_JX, REG, 3, { RSL,RSL,RL } },
+ { R_3(0x65b), "icctl", I_JX, REG, 3, { RSL,RSL,RS } },
+ { R_2D(0x658), "intctl", I_JX, REG, 2, { RSL, RS, 0 } },
+ { R_0(0x5b4), "intdis", I_JX, REG, 0, { 0, 0, 0 } },
+ { R_0(0x5b5), "inten", I_JX, REG, 0, { 0, 0, 0 } },
+ { R_0(0x65d), "halt", I_JX, REG, 1, { RSL, 0, 0 } },
+
+ /* Hx extensions. */
+ { 0xac000000, "dcinva", I_HX, MEM1, 1, { M, 0, 0 } },
+
+ /* END OF TABLE */
+
+ { 0, NULL, 0, 0, 0, { 0, 0, 0 } }
+};
+
+ /* end of i960-opcode.h */
diff --git a/include/opcode/m68k.h b/include/opcode/m68k.h
new file mode 100644
index 00000000000..ecb3f95dd96
--- /dev/null
+++ b/include/opcode/m68k.h
@@ -0,0 +1,315 @@
+/* Opcode table header for m680[01234]0/m6888[12]/m68851.
+ Copyright 1989, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation.
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* These are used as bit flags for the arch field in the m68k_opcode
+ structure. */
+#define _m68k_undef 0
+#define m68000 0x001
+#define m68008 m68000 /* synonym for -m68000. otherwise unused. */
+#define m68010 0x002
+#define m68020 0x004
+#define m68030 0x008
+#define m68ec030 m68030 /* similar enough to -m68030 to ignore differences;
+ gas will deal with the few differences. */
+#define m68040 0x010
+/* there is no 68050 */
+#define m68060 0x020
+#define m68881 0x040
+#define m68882 m68881 /* synonym for -m68881. otherwise unused. */
+#define m68851 0x080
+#define cpu32 0x100 /* e.g., 68332 */
+#define mcf5200 0x200
+
+ /* handy aliases */
+#define m68040up (m68040 | m68060)
+#define m68030up (m68030 | m68040up)
+#define m68020up (m68020 | m68030up)
+#define m68010up (m68010 | cpu32 | m68020up)
+#define m68000up (m68000 | m68010up)
+
+#define mfloat (m68881 | m68882 | m68040 | m68060)
+#define mmmu (m68851 | m68030 | m68040 | m68060)
+
+/* The structure used to hold information for an opcode. */
+
+struct m68k_opcode
+{
+ /* The opcode name. */
+ const char *name;
+ /* The opcode itself. */
+ unsigned long opcode;
+ /* The mask used by the disassembler. */
+ unsigned long match;
+ /* The arguments. */
+ const char *args;
+ /* The architectures which support this opcode. */
+ unsigned int arch;
+};
+
+/* The structure used to hold information for an opcode alias. */
+
+struct m68k_opcode_alias
+{
+ /* The alias name. */
+ const char *alias;
+ /* The instruction for which this is an alias. */
+ const char *primary;
+};
+
+/* We store four bytes of opcode for all opcodes because that is the
+ most any of them need. The actual length of an instruction is
+ always at least 2 bytes, and is as much longer as necessary to hold
+ the operands it has.
+
+ The match field is a mask saying which bits must match particular
+ opcode in order for an instruction to be an instance of that
+ opcode.
+
+ The args field is a string containing two characters for each
+ operand of the instruction. The first specifies the kind of
+ operand; the second, the place it is stored. */
+
+/* Kinds of operands:
+ Characters used: AaBCcDdFfIJkLlMmnOopQqRrSsTtUVvWXYZ0123|*~%;@!&$?/<>#^+-
+
+ D data register only. Stored as 3 bits.
+ A address register only. Stored as 3 bits.
+ a address register indirect only. Stored as 3 bits.
+ R either kind of register. Stored as 4 bits.
+ r either kind of register indirect only. Stored as 4 bits.
+ At the moment, used only for cas2 instruction.
+ F floating point coprocessor register only. Stored as 3 bits.
+ O an offset (or width): immediate data 0-31 or data register.
+ Stored as 6 bits in special format for BF... insns.
+ + autoincrement only. Stored as 3 bits (number of the address register).
+ - autodecrement only. Stored as 3 bits (number of the address register).
+ Q quick immediate data. Stored as 3 bits.
+ This matches an immediate operand only when value is in range 1 .. 8.
+ M moveq immediate data. Stored as 8 bits.
+ This matches an immediate operand only when value is in range -128..127
+ T trap vector immediate data. Stored as 4 bits.
+
+ k K-factor for fmove.p instruction. Stored as a 7-bit constant or
+ a three bit register offset, depending on the field type.
+
+ # immediate data. Stored in special places (b, w or l)
+ which say how many bits to store.
+ ^ immediate data for floating point instructions. Special places
+ are offset by 2 bytes from '#'...
+ B pc-relative address, converted to an offset
+ that is treated as immediate data.
+ d displacement and register. Stores the register as 3 bits
+ and stores the displacement in the entire second word.
+
+ C the CCR. No need to store it; this is just for filtering validity.
+ S the SR. No need to store, just as with CCR.
+ U the USP. No need to store, just as with CCR.
+
+ I Coprocessor ID. Not printed if 1. The Coprocessor ID is always
+ extracted from the 'd' field of word one, which means that an extended
+ coprocessor opcode can be skipped using the 'i' place, if needed.
+
+ s System Control register for the floating point coprocessor.
+
+ J Misc register for movec instruction, stored in 'j' format.
+ Possible values:
+ 0x000 SFC Source Function Code reg [60, 40, 30, 20, 10]
+ 0x001 DFC Data Function Code reg [60, 40, 30, 20, 10]
+ 0x002 CACR Cache Control Register [60, 40, 30, 20]
+ 0x003 TC MMU Translation Control [60, 40]
+ 0x004 ITT0 Instruction Transparent
+ Translation reg 0 [60, 40]
+ 0x005 ITT1 Instruction Transparent
+ Translation reg 1 [60, 40]
+ 0x006 DTT0 Data Transparent
+ Translation reg 0 [60, 40]
+ 0x007 DTT1 Data Transparent
+ Translation reg 1 [60, 40]
+ 0x008 BUSCR Bus Control Register [60]
+ 0x800 USP User Stack Pointer [60, 40, 30, 20, 10]
+ 0x801 VBR Vector Base reg [60, 40, 30, 20, 10]
+ 0x802 CAAR Cache Address Register [ 30, 20]
+ 0x803 MSP Master Stack Pointer [ 40, 30, 20]
+ 0x804 ISP Interrupt Stack Pointer [ 40, 30, 20]
+ 0x805 MMUSR MMU Status reg [ 40]
+ 0x806 URP User Root Pointer [60, 40]
+ 0x807 SRP Supervisor Root Pointer [60, 40]
+ 0x808 PCR Processor Configuration reg [60]
+ 0xC00 ROMBAR ROM Base Address Register [520X]
+ 0xC04 RAMBAR0 RAM Base Address Register 0 [520X]
+ 0xC05 RAMBAR1 RAM Base Address Register 0 [520X]
+ 0xC0F MBAR0 RAM Base Address Register 0 [520X]
+
+ L Register list of the type d0-d7/a0-a7 etc.
+ (New! Improved! Can also hold fp0-fp7, as well!)
+ The assembler tries to see if the registers match the insn by
+ looking at where the insn wants them stored.
+
+ l Register list like L, but with all the bits reversed.
+ Used for going the other way. . .
+
+ c cache identifier which may be "nc" for no cache, "ic"
+ for instruction cache, "dc" for data cache, or "bc"
+ for both caches. Used in cinv and cpush. Always
+ stored in position "d".
+
+ The remainder are all stored as 6 bits using an address mode and a
+ register number; they differ in which addressing modes they match.
+
+ * all (modes 0-6,7.0-4)
+ ~ alterable memory (modes 2-6,7.0,7.1)
+ (not 0,1,7.2-4)
+ % alterable (modes 0-6,7.0,7.1)
+ (not 7.2-4)
+ ; data (modes 0,2-6,7.0-4)
+ (not 1)
+ @ data, but not immediate (modes 0,2-6,7.0-3)
+ (not 1,7.4)
+ ! control (modes 2,5,6,7.0-3)
+ (not 0,1,3,4,7.4)
+ & alterable control (modes 2,5,6,7.0,7.1)
+ (not 0,1,7.2-4)
+ $ alterable data (modes 0,2-6,7.0,7.1)
+ (not 1,7.2-4)
+ ? alterable control, or data register (modes 0,2,5,6,7.0,7.1)
+ (not 1,3,4,7.2-4)
+ / control, or data register (modes 0,2,5,6,7.0-3)
+ (not 1,3,4,7.4)
+ > *save operands (modes 2,4,5,6,7.0,7.1)
+ (not 0,1,3,7.2-4)
+ < *restore operands (modes 2,3,5,6,7.0-3)
+ (not 0,1,4,7.4)
+
+ coldfire move operands:
+ m (modes 0-4)
+ n (modes 5,7.2)
+ o (modes 6,7.0,7.1,7.3,7.4)
+ p (modes 0-5)
+
+ coldfire bset/bclr/btst/mulsl/mulul operands:
+ q (modes 0,2-5)
+ v (modes 0,2-5,7.0,7.1)
+*/
+
+/* For the 68851: */
+/*
+ I didn't use much imagination in choosing the
+ following codes, so many of them aren't very
+ mnemonic. -rab
+
+ 0 32 bit pmmu register
+ Possible values:
+ 000 TC Translation Control Register (68030, 68851)
+
+ 1 16 bit pmmu register
+ 111 AC Access Control (68851)
+
+ 2 8 bit pmmu register
+ 100 CAL Current Access Level (68851)
+ 101 VAL Validate Access Level (68851)
+ 110 SCC Stack Change Control (68851)
+
+ 3 68030-only pmmu registers (32 bit)
+ 010 TT0 Transparent Translation reg 0
+ (aka Access Control reg 0 -- AC0 -- on 68ec030)
+ 011 TT1 Transparent Translation reg 1
+ (aka Access Control reg 1 -- AC1 -- on 68ec030)
+
+ W wide pmmu registers
+ Possible values:
+ 001 DRP Dma Root Pointer (68851)
+ 010 SRP Supervisor Root Pointer (68030, 68851)
+ 011 CRP Cpu Root Pointer (68030, 68851)
+
+ f function code register (68030, 68851)
+ 0 SFC
+ 1 DFC
+
+ V VAL register only (68851)
+
+ X BADx, BACx (16 bit)
+ 100 BAD Breakpoint Acknowledge Data (68851)
+ 101 BAC Breakpoint Acknowledge Control (68851)
+
+ Y PSR (68851) (MMUSR on 68030) (ACUSR on 68ec030)
+ Z PCSR (68851)
+
+ | memory (modes 2-6, 7.*)
+
+ t address test level (68030 only)
+ Stored as 3 bits, range 0-7.
+ Also used for breakpoint instruction now.
+
+*/
+
+/* Places to put an operand, for non-general operands:
+ s source, low bits of first word.
+ d dest, shifted 9 in first word
+ 1 second word, shifted 12
+ 2 second word, shifted 6
+ 3 second word, shifted 0
+ 4 third word, shifted 12
+ 5 third word, shifted 6
+ 6 third word, shifted 0
+ 7 second word, shifted 7
+ 8 second word, shifted 10
+ 9 second word, shifted 5
+ D store in both place 1 and place 3; for divul and divsl.
+ B first word, low byte, for branch displacements
+ W second word (entire), for branch displacements
+ L second and third words (entire), for branch displacements
+ (also overloaded for move16)
+ b second word, low byte
+ w second word (entire) [variable word/long branch offset for dbra]
+ W second word (entire) (must be signed 16 bit value)
+ l second and third word (entire)
+ g variable branch offset for bra and similar instructions.
+ The place to store depends on the magnitude of offset.
+ t store in both place 7 and place 8; for floating point operations
+ c branch offset for cpBcc operations.
+ The place to store is word two if bit six of word one is zero,
+ and words two and three if bit six of word one is one.
+ i Increment by two, to skip over coprocessor extended operands. Only
+ works with the 'I' format.
+ k Dynamic K-factor field. Bits 6-4 of word 2, used as a register number.
+ Also used for dynamic fmovem instruction.
+ C floating point coprocessor constant - 7 bits. Also used for static
+ K-factors...
+ j Movec register #, stored in 12 low bits of second word.
+
+ Places to put operand, for general operands:
+ d destination, shifted 6 bits in first word
+ b source, at low bit of first word, and immediate uses one byte
+ w source, at low bit of first word, and immediate uses two bytes
+ l source, at low bit of first word, and immediate uses four bytes
+ s source, at low bit of first word.
+ Used sometimes in contexts where immediate is not allowed anyway.
+ f single precision float, low bit of 1st word, immediate uses 4 bytes
+ F double precision float, low bit of 1st word, immediate uses 8 bytes
+ x extended precision float, low bit of 1st word, immediate uses 12 bytes
+ p packed float, low bit of 1st word, immediate uses 12 bytes
+*/
+
+extern const struct m68k_opcode m68k_opcodes[];
+extern const struct m68k_opcode_alias m68k_opcode_aliases[];
+
+extern const int m68k_numopcodes, m68k_numaliases;
+
+/* end of m68k-opcode.h */
diff --git a/include/opcode/m88k.h b/include/opcode/m88k.h
new file mode 100644
index 00000000000..a17fa0361da
--- /dev/null
+++ b/include/opcode/m88k.h
@@ -0,0 +1,923 @@
+/* Table of opcodes for the motorola 88k family.
+ Copyright 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * Disassembler Instruction Table
+ *
+ * The first field of the table is the opcode field. If an opcode
+ * is specified which has any non-opcode bits on, a system error
+ * will occur when the system attempts the install it into the
+ * instruction table. The second parameter is a pointer to the
+ * instruction mnemonic. Each operand is specified by offset, width,
+ * and type. The offset is the bit number of the least significant
+ * bit of the operand with bit 0 being the least significant bit of
+ * the instruction. The width is the number of bits used to specify
+ * the operand. The type specifies the output format to be used for
+ * the operand. The valid formats are: register, register indirect,
+ * hex constant, and bit field specification. The last field is a
+ * pointer to the next instruction in the linked list. These pointers
+ * are initialized by init_disasm().
+ *
+ * Structure Format
+ *
+ * struct INSTAB {
+ * UPINT opcode;
+ * char *mnemonic;
+ * struct OPSPEC op1,op2,op3;
+ * struct SIM_FLAGS flgs;
+ * struct INSTAB *next;
+ * }
+ *
+ * struct OPSPEC {
+ * UPINT offset:5;
+ * UPINT width:6;
+ * UPINT type:5;
+ * }
+ *
+ * Revision History
+ *
+ * Revision 1.0 11/08/85 Creation date
+ * 1.1 02/05/86 Updated instruction mnemonic table MD
+ * 1.2 06/16/86 Updated SIM_FLAGS for floating point
+ * 1.3 09/20/86 Updated for new encoding
+ * 05/11/89 R. Trawick adapted from Motorola disassembler
+ */
+
+#include <stdio.h>
+
+
+/*
+ * This file contains the structures and constants needed to build the M88000
+ * simulator. It is the main include file, containing all the
+ * structures, macros and definitions except for the floating point
+ * instruction set.
+ */
+
+/*
+ * The following flag informs the Simulator as to what type of byte ordering
+ * will be used. For instance, a BOFLAG = 1 indicates a DEC VAX and IBM type
+ * of ordering shall be used.
+*/
+
+/* # define BOFLAG 1 */ /* BYTE ORDERING FLAG */
+
+/* define the number of bits in the primary opcode field of the instruction,
+ * the destination field, the source 1 and source 2 fields.
+ */
+# define OP 8 /* size of opcode field */
+# define DEST 6 /* size of destination */
+# define SOURCE1 6 /* size of source1 */
+# define SOURCE2 6 /* size of source2 */
+
+# define REGs 32 /* number of registers */
+
+# define WORD long
+# define FLAG unsigned
+# define STATE short
+
+# define TRUE 1
+# define FALSE 0
+
+# define READ 0
+# define WRITE 1
+
+/* The next four equates define the priorities that the various classes
+ * of instructions have regarding writing results back into registers and
+ * signalling exceptions.
+ */
+/* PMEM is also defined in <sys/param.h> on Delta 88's. Sigh! */
+#undef PMEM
+
+# define PINT 0 /* Integer Priority */
+# define PFLT 1 /* Floating Point Priority */
+# define PMEM 2 /* Memory Priority */
+# define NA 3 /* Not Applicable, instruction doesnt write to regs */
+# define HIPRI 3 /* highest of these priorities */
+
+/* The instruction registers are an artificial mechanism to speed up
+ * simulator execution. In the real processor, an instruction register
+ * is 32 bits wide. In the simulator, the 32 bit instruction is kept in
+ * a structure field called rawop, and the instruction is partially decoded,
+ * and split into various fields and flags which make up the other fields
+ * of the structure.
+ * The partial decode is done when the instructions are initially loaded
+ * into simulator memory. The simulator code memory is not an array of
+ * 32 bit words, but is an array of instruction register structures.
+ * Yes this wastes memory, but it executes much quicker.
+ */
+
+struct IR_FIELDS {
+ unsigned op:OP,
+ dest: DEST,
+ src1: SOURCE1,
+ src2: SOURCE2;
+ int ltncy,
+ extime,
+ wb_pri; /* writeback priority */
+ unsigned imm_flags:2,/* immediate size */
+ rs1_used:1, /* register source 1 used */
+ rs2_used:1, /* register source 2 used */
+ rsd_used:1, /* register source/dest. used */
+ c_flag:1, /* complement */
+ u_flag:1, /* upper half word */
+ n_flag:1, /* execute next */
+ wb_flag:1, /* uses writeback slot */
+ dest_64:1, /* dest size */
+ s1_64:1, /* source 1 size */
+ s2_64:1, /* source 2 size */
+ scale_flag:1, /* scaled register */
+ brk_flg:1;
+ };
+
+struct mem_segs {
+ struct mem_wrd *seg; /* pointer (returned by calloc) to segment */
+ unsigned long baseaddr; /* base load address from file headers */
+ unsigned long endaddr; /* Ending address of segment */
+ int flags; /* segment control flags (none defined 12/5/86) */
+};
+
+#define MAXSEGS (10) /* max number of segment allowed */
+#define MEMSEGSIZE (sizeof(struct mem_segs))/* size of mem_segs structure */
+
+
+#define BRK_RD (0x01) /* break on memory read */
+#define BRK_WR (0x02) /* break on memory write */
+#define BRK_EXEC (0x04) /* break on execution */
+#define BRK_CNT (0x08) /* break on terminal count */
+
+
+struct mem_wrd {
+ struct IR_FIELDS opcode; /* simulator instruction break down */
+ union {
+ unsigned long l; /* memory element break down */
+ unsigned short s[2];
+ unsigned char c[4];
+ } mem;
+};
+
+#define MEMWRDSIZE (sizeof(struct mem_wrd)) /* size of each 32 bit memory model */
+
+/* External declarations */
+
+extern struct mem_segs memory[];
+extern struct PROCESSOR m78000;
+
+struct PROCESSOR {
+ unsigned WORD
+ ip, /* execute instruction pointer */
+ vbr, /* vector base register */
+ psr; /* processor status register */
+
+ WORD S1bus, /* source 1 */
+ S2bus, /* source 2 */
+ Dbus, /* destination */
+ DAbus, /* data address bus */
+ ALU,
+ Regs[REGs], /* data registers */
+ time_left[REGs], /* max clocks before reg is available */
+ wb_pri[REGs], /* writeback priority of reg */
+ SFU0_regs[REGs], /* integer unit control regs */
+ SFU1_regs[REGs], /* floating point control regs */
+ Scoreboard[REGs],
+ Vbr;
+ unsigned WORD scoreboard,
+ Psw,
+ Tpsw;
+ FLAG jump_pending:1; /* waiting for a jump instr. */
+ };
+
+# define i26bit 1 /* size of immediate field */
+# define i16bit 2
+# define i10bit 3
+
+/* Definitions for fields in psr */
+
+# define mode 31
+# define rbo 30
+# define ser 29
+# define carry 28
+# define sf7m 11
+# define sf6m 10
+# define sf5m 9
+# define sf4m 8
+# define sf3m 7
+# define sf2m 6
+# define sf1m 5
+# define mam 4
+# define inm 3
+# define exm 2
+# define trm 1
+# define ovfm 0
+
+#define MODEMASK (1<<(mode-1))
+# define SILENT 0 /* simulate without output to crt */
+# define VERBOSE 1 /* simulate in verbose mode */
+# define PR_INSTR 2 /* only print instructions */
+
+# define RESET 16 /* reset phase */
+
+# define PHASE1 0 /* data path phases */
+# define PHASE2 1
+
+/* the 1 clock operations */
+
+# define ADDU 1
+# define ADDC 2
+# define ADDUC 3
+# define ADD 4
+
+# define SUBU ADD+1
+# define SUBB ADD+2
+# define SUBUB ADD+3
+# define SUB ADD+4
+
+# define AND_ ADD+5
+# define OR ADD+6
+# define XOR ADD+7
+# define CMP ADD+8
+
+/* the LOADS */
+
+# define LDAB CMP+1
+# define LDAH CMP+2
+# define LDA CMP+3
+# define LDAD CMP+4
+
+# define LDB LDAD+1
+# define LDH LDAD+2
+# define LD LDAD+3
+# define LDD LDAD+4
+# define LDBU LDAD+5
+# define LDHU LDAD+6
+
+/* the STORES */
+
+# define STB LDHU+1
+# define STH LDHU+2
+# define ST LDHU+3
+# define STD LDHU+4
+
+/* the exchange */
+
+# define XMEMBU LDHU+5
+# define XMEM LDHU+6
+
+/* the branches */
+# define JSR STD+1
+# define BSR STD+2
+# define BR STD+3
+# define JMP STD+4
+# define BB1 STD+5
+# define BB0 STD+6
+# define RTN STD+7
+# define BCND STD+8
+
+/* the TRAPS */
+# define TB1 BCND+1
+# define TB0 BCND+2
+# define TCND BCND+3
+# define RTE BCND+4
+# define TBND BCND+5
+
+/* the MISC instructions */
+# define MUL TBND + 1
+# define DIV MUL +2
+# define DIVU MUL +3
+# define MASK MUL +4
+# define FF0 MUL +5
+# define FF1 MUL +6
+# define CLR MUL +7
+# define SET MUL +8
+# define EXT MUL +9
+# define EXTU MUL +10
+# define MAK MUL +11
+# define ROT MUL +12
+
+/* control register manipulations */
+
+# define LDCR ROT +1
+# define STCR ROT +2
+# define XCR ROT +3
+
+# define FLDCR ROT +4
+# define FSTCR ROT +5
+# define FXCR ROT +6
+
+
+# define NOP XCR +1
+
+/* floating point instructions */
+
+# define FADD NOP +1
+# define FSUB NOP +2
+# define FMUL NOP +3
+# define FDIV NOP +4
+# define FSQRT NOP +5
+# define FCMP NOP +6
+# define FIP NOP +7
+# define FLT NOP +8
+# define INT NOP +9
+# define NINT NOP +10
+# define TRNC NOP +11
+# define FLDC NOP +12
+# define FSTC NOP +13
+# define FXC NOP +14
+
+# define UEXT(src,off,wid) ((((unsigned int)(src))>>(off)) & ((1<<(wid)) - 1))
+# define SEXT(src,off,wid) (((((int)(src))<<(32-((off)+(wid)))) >>(32-(wid))) )
+# define MAKE(src,off,wid) \
+ ((((unsigned int)(src)) & ((1<<(wid)) - 1)) << (off))
+
+# define opword(n) (unsigned long) (memaddr->mem.l)
+
+/* Constants and Masks */
+
+#define SFU0 0x80000000
+#define SFU1 0x84000000
+#define SFU7 0x9c000000
+#define RRI10 0xf0000000
+#define RRR 0xf4000000
+#define SFUMASK 0xfc00ffe0
+#define RRRMASK 0xfc00ffe0
+#define RRI10MASK 0xfc00fc00
+#define DEFMASK 0xfc000000
+#define CTRL 0x0000f000
+#define CTRLMASK 0xfc00f800
+
+/* Operands types */
+
+enum operand_type {
+ HEX = 1,
+ REG = 2,
+ CONT = 3,
+ IND = 3,
+ BF = 4,
+ REGSC = 5 /* scaled register */,
+ CRREG = 6 /* control register */,
+ FCRREG = 7 /* floating point control register */,
+ PCREL = 8,
+ CONDMASK = 9,
+ XREG = 10, /* extended register */
+ DEC = 11, /* decimal */
+};
+
+/* Hashing Specification */
+
+#define HASHVAL 79
+
+/* Type definitions */
+
+typedef unsigned int UINT;
+
+/* Structure templates */
+
+#if never
+typedef struct {
+ unsigned int offset:5;
+ unsigned int width:6;
+ unsigned int type:5;
+} OPSPEC;
+#endif
+
+typedef struct {
+ unsigned int offset;
+ unsigned int width;
+ enum operand_type type;
+} OPSPEC;
+
+ struct SIM_FLAGS {
+ int ltncy, /* latency (max number of clocks needed to execute) */
+ extime, /* execution time (min number of clocks needed to execute) */
+ wb_pri; /* writeback slot priority */
+ unsigned op:OP, /* simulator version of opcode */
+ imm_flags:2, /* 10,16 or 26 bit immediate flags */
+ rs1_used:1, /* register source 1 used */
+ rs2_used:1, /* register source 2 used */
+ rsd_used:1, /* register source/dest used */
+ c_flag:1, /* complement */
+ u_flag:1, /* upper half word */
+ n_flag:1, /* execute next */
+ wb_flag:1, /* uses writeback slot */
+ dest_64:1, /* double precision dest */
+ s1_64:1, /* double precision source 1 */
+ s2_64:1, /* double precision source 2 */
+ scale_flag:1; /* register is scaled */
+};
+
+typedef struct INSTRUCTAB {
+ unsigned int opcode;
+ char *mnemonic;
+ OPSPEC op1,op2,op3;
+ struct SIM_FLAGS flgs;
+ struct INSTRUCTAB *next;
+} INSTAB;
+
+
+#define NO_OPERAND {0,0,0}
+
+/* Opcode Mnemonic Op 1 Spec Op 2 Spec Op 3 Spec Simflags Next */
+
+static INSTAB instructions[] = {
+ {0xf400c800,"jsr ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {2,2,NA,JSR , 0,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xf400cc00,"jsr.n ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {1,1,NA,JSR , 0,0,1,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xf400c000,"jmp ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {2,2,NA,JMP , 0,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xf400c400,"jmp.n ",{0,5,REG} ,NO_OPERAND ,NO_OPERAND , {1,1,NA,JMP , 0,0,1,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xc8000000,"bsr ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {2,2,NA,BSR , i26bit,0,0,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xcc000000,"bsr.n ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {1,1,NA,BSR , i26bit,0,0,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xc0000000,"br ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {2,2,NA,BR , i26bit,0,0,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xc4000000,"br.n ",{0,26,PCREL},NO_OPERAND ,NO_OPERAND , {1,1,NA,BR , i26bit,0,0,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xd0000000,"bb0 ",{21,5,HEX} ,{16,5,REG} ,{0,16,PCREL},{2,2,NA,BB0, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xd4000000,"bb0.n ",{21,5,HEX} ,{16,5,REG} ,{0,16,PCREL},{1,1,NA,BB0, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xd8000000,"bb1 ",{21,5,HEX},{16,5,REG} ,{0,16,PCREL},{2,2,NA,BB1, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xdc000000,"bb1.n ",{21,5,HEX},{16,5,REG} ,{0,16,PCREL},{1,1,NA,BB1, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xf000d000,"tb0 ",{21,5,HEX} ,{16,5,REG} ,{0,10,HEX}, {2,2,NA,TB0 , i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xf000d800,"tb1 ",{21,5,HEX} ,{16,5,REG} ,{0,10,HEX}, {2,2,NA,TB1 , i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xe8000000,"bcnd ",{21,5,CONDMASK},{16,5,REG},{0,16,PCREL},{2,2,NA,BCND, i16bit,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xec000000,"bcnd.n ",{21,5,CONDMASK},{16,5,REG},{0,16,PCREL},{1,1,NA,BCND, i16bit,0,1,0,0,0,1,1,0,0,0,0}, NULL },
+ {0xf000e800,"tcnd ",{21,5,CONDMASK},{16,5,REG},{0,10,HEX}, {2,2,NA,TCND, i10bit,0,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xf8000000,"tbnd ",{16,5,REG} ,{0,16,HEX} ,NO_OPERAND , {2,2,NA,TBND, i10bit,1,0,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xf400f800,"tbnd ",{16,5,REG} ,{0,5,REG} ,NO_OPERAND , {2,2,NA,TBND, 0,1,1,0,0,0,0,1,0,0,0,0}, NULL },
+ {0xf400fc00,"rte ",NO_OPERAND ,NO_OPERAND ,NO_OPERAND , {2,2,NA,RTE , 0,0,0,0,0,0,0,1,0,0,0,0}, NULL },
+ {0x1c000000,"ld.b ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDB ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001c00,"ld.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDB , 0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0x0c000000,"ld.bu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDBU, i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4000c00,"ld.bu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDBU ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0x18000000,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDH ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001800,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDH ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001a00,"ld.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDH ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL },
+ {0x08000000,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDHU, i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4000800,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDHU ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4000a00,"ld.hu ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDHU ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL },
+ {0x14000000,"ld ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LD ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001400,"ld ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001600,"ld ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL },
+ {0x10000000,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,LDD ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001000,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LDD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001200,"ld.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LDD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL },
+ {0xf4001500,"ld.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4001700,"ld.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,LD ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL },
+ {0x2c000000,"st.b ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STB ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4002c00,"st.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STB ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0x28000000,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STH ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4002800,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STH ,0,1,1,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4002a00,"st.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,STH ,0,1,1,1,0,0,0,1,0,0,0,1}, NULL },
+ {0x24000000,"st ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,ST ,i16bit,1,0,1,0,0,0,1,0,0,0,0}, NULL },
+ {0xf4002400,"st ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0xf4002600,"st ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL },
+ {0x20000000,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,NA,STD ,i16bit,0,1,0,0,0,0,1,0,0,0,0} ,NULL },
+ {0xf4002000,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,STD ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0xf4002200,"st.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,STD ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL },
+ {0xf4002500,"st.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0xf4002700,"st.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,NA,ST ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL },
+/* m88100 only:
+ {0x00000000,"xmem.bu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,XMEMBU ,i16bit,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ */
+ {0xf4000000,"xmem.bu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+/* m88100 only:
+ {0x04000000,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {3,1,PMEM,XMEM ,i16bit,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ */
+ {0xf4000400,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0xf4000600,"xmem ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL },
+ {0xf4000500,"xmem.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0xf4000700,"xmem.usr ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{3,1,PMEM,XMEM ,0,1,1,1,0,0,0,1,0,0,0,1} ,NULL },
+/* m88100 only:
+ {0xf4003e00,"lda.b ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL },
+ */
+ {0xf4003e00,"lda.x ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL },
+ {0xf4003a00,"lda.h ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAH, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL },
+ {0xf4003600,"lda ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDA , 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL },
+ {0xf4003200,"lda.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REGSC},{1,1,PINT,LDAD, 0,1,1,1,0,0,0,0,0,0,0,1} ,NULL },
+
+ {0x80004000,"ldcr ",{21,5,REG} ,{5,6,CRREG} ,NO_OPERAND ,{1,1,PINT,LDCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x80008000,"stcr ",{16,5,REG} ,{5,6,CRREG} ,NO_OPERAND ,{1,1,PINT,STCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x8000c000,"xcr ",{21,5,REG} ,{16,5,REG} ,{5,6,CRREG},{1,1,PINT,XCR, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+
+ {0xf4006000,"addu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006200,"addu.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006100,"addu.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006300,"addu.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADDU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006400,"subu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006600,"subu.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006500,"subu.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006700,"subu.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUBU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006800,"divu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {32,32,PINT,DIVU, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4006900,"divu.d ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, NULL },
+ {0xf4006e00,"muls ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, NULL },
+ {0xf4006c00,"mulu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,4,PINT,MUL, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007000,"add ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007200,"add.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007100,"add.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007300,"add.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ADD , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007400,"sub ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007600,"sub.ci ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007500,"sub.co ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007700,"sub.cio ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SUB , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007800,"divs ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {32,32,PINT,DIV , 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4007c00,"cmp ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,CMP, 0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+
+ {0x60000000,"addu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,ADDU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x64000000,"subu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,SUBU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+
+ {0x68000000,"divu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {32,32,PINT,DIVU, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x6c000000,"mulu ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {4,1,PINT,MUL, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x70000000,"add ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,ADD, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x74000000,"sub ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,SUB, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x78000000,"divs ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {32,32,PINT,DIV, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x7c000000,"cmp ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,CMP, i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+
+ {0xf4004000,"and ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,AND_ ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4004400,"and.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,AND_ ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL },
+ {0xf4005800,"or ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,OR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4005c00,"or.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,OR ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL },
+ {0xf4005000,"xor ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,XOR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4005400,"xor.c ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,XOR ,0,1,1,1,1,0,0,0,0,0,0,0} ,NULL },
+ {0x40000000,"and ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,AND_ ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x44000000,"and.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,AND_ ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL },
+ {0x58000000,"or ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,OR ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x5c000000,"or.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,OR ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL },
+ {0x50000000,"xor ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,XOR ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x54000000,"xor.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,XOR ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL },
+ {0x48000000,"mask ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,MASK ,i16bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0x4c000000,"mask.u ",{21,5,REG} ,{16,5,REG} ,{0,16,HEX}, {1,1,PINT,MASK ,i16bit,1,0,1,0,1,0,0,0,0,0,0} ,NULL },
+ {0xf400ec00,"ff0 ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {1,1,PINT,FF0 ,0,0,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf400e800,"ff1 ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {1,1,PINT,FF1 ,0,0,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf0008000,"clr ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,CLR ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf0008800,"set ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,SET ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf0009000,"ext ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,EXT ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf0009800,"extu ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,EXTU ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf000a000,"mak ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,MAK ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf000a800,"rot ",{21,5,REG} ,{16,5,REG} ,{0,10,BF} , {1,1,PINT,ROT ,i10bit,1,0,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4008000,"clr ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,CLR ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4008800,"set ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,SET ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4009000,"ext ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,EXT ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf4009800,"extu ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,EXTU ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf400a000,"mak ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,MAK ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+ {0xf400a800,"rot ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {1,1,PINT,ROT ,0,1,1,1,0,0,0,0,0,0,0,0} ,NULL },
+
+ {0x84002800,"fadd.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FADD ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84002880,"fadd.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL },
+ {0x84002a00,"fadd.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL },
+ {0x84002a80,"fadd.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL },
+ {0x84002820,"fadd.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x840028a0,"fadd.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL },
+ {0x84002a20,"fadd.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL },
+ {0x84002aa0,"fadd.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FADD ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL },
+ {0x84003000,"fsub.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84003080,"fsub.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL },
+ {0x84003200,"fsub.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL },
+ {0x84003280,"fsub.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL },
+ {0x84003020,"fsub.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x840030a0,"fsub.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL },
+ {0x84003220,"fsub.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL },
+ {0x840032a0,"fsub.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,2,PFLT,FSUB ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL },
+ {0x84000000,"fmul.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84000080,"fmul.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL },
+ {0x84000200,"fmul.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL },
+ {0x84000280,"fmul.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL },
+ {0x84000020,"fmul.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x840000a0,"fmul.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL },
+ {0x84000220,"fmul.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL },
+ {0x840002a0,"fmul.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {9,2,PFLT,FMUL ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL },
+ {0x84007000,"fdiv.sss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {30,30,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84007080,"fdiv.ssd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,0,1,0} ,NULL },
+ {0x84007200,"fdiv.sds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL },
+ {0x84007280,"fdiv.sdd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,0,1,1,0} ,NULL },
+ {0x84007020,"fdiv.dss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x840070a0,"fdiv.dsd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,0,1,0} ,NULL },
+ {0x84007220,"fdiv.dds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL },
+ {0x840072a0,"fdiv.ddd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {60,60,PFLT,FDIV ,0,1,1,1,0,0,0,1,1,1,1,0} ,NULL },
+ {0x84007800,"fsqrt.ss ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84007820,"fsqrt.sd ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84007880,"fsqrt.ds ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x840078a0,"fsqrt.dd ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,FLT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x84003800,"fcmp.ss ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {5,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84003880,"fcmp.sd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,0,1,0,0} ,NULL },
+ {0x84003a00,"fcmp.ds ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x84003a80,"fcmp.dd ",{21,5,REG} ,{16,5,REG} ,{0,5,REG} , {6,1,PFLT,FCMP ,0,1,1,1,0,0,0,1,1,1,0,0} ,NULL },
+ {0x84002000,"flt.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,FLT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84002020,"flt.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,FLT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x84004800,"int.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,INT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84004880,"int.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,INT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x84005000,"nint.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,INT ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84005080,"nint.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,INT ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL },
+ {0x84005800,"trnc.s ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {5,1,PFLT,TRNC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x84005880,"trnc.d ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND , {6,1,PFLT,TRNC ,0,0,1,1,0,0,0,1,1,0,0,0} ,NULL },
+
+ {0x80004800,"fldcr ",{21,5,REG} ,{5,6,FCRREG} ,NO_OPERAND , {1,1,PFLT,FLDC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x80008800,"fstcr ",{16,5,REG} ,{5,6,FCRREG} ,NO_OPERAND , {1,1,PFLT,FSTC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+ {0x8000c800,"fxcr ",{21,5,REG} ,{16,5,REG} ,{5,6,FCRREG} , {1,1,PFLT,FXC ,0,0,1,1,0,0,0,1,0,0,0,0} ,NULL },
+
+/* The following are new for the 88110. */
+
+ {0x8400aaa0,"fadd.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400aa80,"fadd.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400aac0,"fadd.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400aa20,"fadd.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400aa00,"fadd.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400aa40,"fadd.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ab20,"fadd.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ab00,"fadd.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ab40,"fadd.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a8a0,"fadd.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a880,"fadd.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a8c0,"fadd.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a820,"fadd.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a800,"fadd.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a840,"fadd.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a920,"fadd.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a900,"fadd.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400a940,"fadd.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400aca0,"fadd.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ac80,"fadd.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400acc0,"fadd.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ac20,"fadd.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ac00,"fadd.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ac40,"fadd.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ad20,"fadd.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ad00,"fadd.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ad40,"fadd.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400ba80,"fcmp.sdd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ba00,"fcmp.sds ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bb00,"fcmp.sdx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b880,"fcmp.ssd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b800,"fcmp.sss ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b900,"fcmp.ssx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bc80,"fcmp.sxd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bc00,"fcmp.sxs ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bd00,"fcmp.sxx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400baa0,"fcmpu.sdd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400ba20,"fcmpu.sds ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bb20,"fcmpu.sdx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b8a0,"fcmpu.ssd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b820,"fcmpu.sss ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b920,"fcmpu.ssx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bca0,"fcmpu.sxd ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bc20,"fcmpu.sxs ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400bd20,"fcmpu.sxx ",{21,5,REG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x84000820,"fcvt.sd ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84000880,"fcvt.ds ",{21,5,REG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x84008880,"fcvt.ds ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x840088c0,"fcvt.dx ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008820,"fcvt.sd ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008840,"fcvt.sx ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008920,"fcvt.xd ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008900,"fcvt.xs ",{21,5,XREG} ,{0,5,XREG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400f2a0,"fdiv.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f280,"fdiv.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f2c0,"fdiv.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f220,"fdiv.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f200,"fdiv.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f240,"fdiv.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f320,"fdiv.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f300,"fdiv.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f340,"fdiv.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f0a0,"fdiv.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f080,"fdiv.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f0c0,"fdiv.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f020,"fdiv.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f000,"fdiv.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f040,"fdiv.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f120,"fdiv.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f100,"fdiv.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f140,"fdiv.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f4a0,"fdiv.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f480,"fdiv.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f4c0,"fdiv.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f420,"fdiv.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f400,"fdiv.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f440,"fdiv.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f520,"fdiv.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f500,"fdiv.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f540,"fdiv.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x84002220,"flt.ds ",{21,5,XREG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84002200,"flt.ss ",{21,5,XREG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84002240,"flt.xs ",{21,5,XREG} ,{0,5,REG} ,NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x840082a0,"fmul.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008280,"fmul.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x840082c0,"fmul.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008220,"fmul.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008200,"fmul.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008240,"fmul.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008320,"fmul.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008300,"fmul.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008340,"fmul.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x840080a0,"fmul.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008080,"fmul.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x840080c0,"fmul.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008020,"fmul.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008000,"fmul.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008040,"fmul.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008120,"fmul.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008100,"fmul.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008140,"fmul.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x840084a0,"fmul.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008480,"fmul.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x840084c0,"fmul.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008420,"fmul.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008400,"fmul.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008440,"fmul.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008520,"fmul.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008500,"fmul.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84008540,"fmul.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400f8a0,"fsqrt.dd ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f880,"fsqrt.ds ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f8c0,"fsqrt.dx ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f820,"fsqrt.sd ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f800,"fsqrt.ss ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f840,"fsqrt.sx ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f920,"fsqrt.xd ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f900,"fsqrt.xs ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400f940,"fsqrt.xx ",{21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400b2a0,"fsub.ddd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b280,"fsub.dds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b2c0,"fsub.ddx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b220,"fsub.dsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b200,"fsub.dss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b240,"fsub.dsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b320,"fsub.dxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b300,"fsub.dxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b340,"fsub.dxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b0a0,"fsub.sdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b080,"fsub.sds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b0c0,"fsub.sdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b020,"fsub.ssd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b000,"fsub.sss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b040,"fsub.ssx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b120,"fsub.sxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b100,"fsub.sxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b140,"fsub.sxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b4a0,"fsub.xdd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b480,"fsub.xds ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b4c0,"fsub.xdx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b420,"fsub.xsd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b400,"fsub.xss ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b440,"fsub.xsx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b520,"fsub.xxd ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b500,"fsub.xxs ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400b540,"fsub.xxx ",{21,5,XREG} ,{16,5,XREG} ,{0,5,XREG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400fc00,"illop", {0,2,DEC}, NO_OPERAND, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400c800,"int.ss ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400c880,"int.sd ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400c900,"int.sx ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x04000000,"ld ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x00000000,"ld.d ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x3c000000,"ld.x ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf0001400,"ld ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001000,"ld.d ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001800,"ld.x ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001500,"ld.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001100,"ld.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001900,"ld.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf0001600,"ld ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001200,"ld.d ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001a00,"ld.x ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001700,"ld.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001300,"ld.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0001b00,"ld.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400c000,"mov.s ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400c080,"mov.d ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84004200,"mov.s ", {21,5,XREG}, {0,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x84004280,"mov.d ", {21,5,XREG}, {0,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400c300,"mov ", {21,5,XREG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf4006d00,"mulu.d ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400d080,"nint.sd ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400d000,"nint.ss ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400d100,"nint.sx ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88002020,"padd.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88002040,"padd.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88002060,"padd ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x880021e0,"padds.s ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880021a0,"padds.s.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880021c0,"padds.s.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880020e0,"padds.u ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880020a0,"padds.u.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880020c0,"padds.u.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88002160,"padds.us ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88002120,"padds.us.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88002140,"padds.us.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88003860,"pcmp ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88000000,"pmul ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88006260,"ppack.16 ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88006240,"ppack.16.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88006460,"ppack.32 ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88006420,"ppack.32.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88006440,"ppack.32.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88006160,"ppack.8 ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88007200,"prot ", {21,5,REG}, {16,5,REG}, {5,6,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88007800,"prot ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88003020,"psub.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88003040,"psub.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88003060,"psub ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x880031e0,"psubs.s ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880031a0,"psubs.s.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880031c0,"psubs.s.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880030e0,"psubs.u ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880030a0,"psubs.u.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x880030c0,"psubs.u.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88003160,"psubs.us ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88003120,"psubs.us.b ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88003140,"psubs.us.h ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x88006800,"punpk.n ", {21,5,REG}, {16,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x88006820,"punpk.b ", {21,5,REG}, {16,5,REG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x34000000,"st ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x30000000,"st.d ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x38000000,"st.x ", {21,5,XREG}, {16,5,REG}, {0,16,HEX}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf4002c80,"st.b.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002880,"st.h.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002480,"st.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002080,"st.d.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002d80,"st.b.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002980,"st.h.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002580,"st.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002180,"st.d.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf0002400,"st ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002000,"st.d ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002100,"st.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002180,"st.d.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002080,"st.d.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002500,"st.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002580,"st.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002480,"st.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002800,"st.x ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002900,"st.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002980,"st.x.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002880,"st.x.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REG}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf4002f80,"st.b.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002e80,"st.b.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002380,"st.d.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002280,"st.d.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002b80,"st.h.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002a80,"st.h.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002780,"st.usr.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf4002680,"st.wt ", {21,5,REG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0xf0002600,"st ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002200,"st.d ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002300,"st.d.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002380,"st.d.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002280,"st.d.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002700,"st.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002780,"st.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002680,"st.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002a00,"st.x ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002b00,"st.x.usr ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002b80,"st.x.usr.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0xf0002a80,"st.x.wt ", {21,5,XREG}, {16,5,REG}, {0,5,REGSC}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+ {0x8400d880,"trnc.sd ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400d800,"trnc.ss ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+ {0x8400d900,"trnc.sx ", {21,5,REG}, {0,5,XREG}, NO_OPERAND, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, NULL },
+
+};
+
+/*
+ * Local Variables:
+ * fill-column: 131
+ * End:
+ */
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
new file mode 100644
index 00000000000..f0a8c7ef9f2
--- /dev/null
+++ b/include/opcode/mips.h
@@ -0,0 +1,723 @@
+/* mips.h. Mips opcode list for GDB, the GNU debugger.
+ Copyright 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Contributed by Ralph Campbell and OSF
+ Commented and modified by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _MIPS_H_
+#define _MIPS_H_
+
+/* These are bit masks and shift counts to use to access the various
+ fields of an instruction. To retrieve the X field of an
+ instruction, use the expression
+ (i >> OP_SH_X) & OP_MASK_X
+ To set the same field (to j), use
+ i = (i &~ (OP_MASK_X << OP_SH_X)) | (j << OP_SH_X)
+
+ Make sure you use fields that are appropriate for the instruction,
+ of course.
+
+ The 'i' format uses OP, RS, RT and IMMEDIATE.
+
+ The 'j' format uses OP and TARGET.
+
+ The 'r' format uses OP, RS, RT, RD, SHAMT and FUNCT.
+
+ The 'b' format uses OP, RS, RT and DELTA.
+
+ The floating point 'i' format uses OP, RS, RT and IMMEDIATE.
+
+ The floating point 'r' format uses OP, FMT, FT, FS, FD and FUNCT.
+
+ A breakpoint instruction uses OP, CODE and SPEC (10 bits of the
+ breakpoint instruction are not defined; Kane says the breakpoint
+ code field in BREAK is 20 bits; yet MIPS assemblers and debuggers
+ only use ten bits). An optional two-operand form of break/sdbbp
+ allows the lower ten bits to be set too.
+
+ The syscall instruction uses SYSCALL.
+
+ The general coprocessor instructions use COPZ. */
+
+#define OP_MASK_OP 0x3f
+#define OP_SH_OP 26
+#define OP_MASK_RS 0x1f
+#define OP_SH_RS 21
+#define OP_MASK_FR 0x1f
+#define OP_SH_FR 21
+#define OP_MASK_FMT 0x1f
+#define OP_SH_FMT 21
+#define OP_MASK_BCC 0x7
+#define OP_SH_BCC 18
+#define OP_MASK_CODE 0x3ff
+#define OP_SH_CODE 16
+#define OP_MASK_CODE2 0x3ff
+#define OP_SH_CODE2 6
+#define OP_MASK_RT 0x1f
+#define OP_SH_RT 16
+#define OP_MASK_FT 0x1f
+#define OP_SH_FT 16
+#define OP_MASK_CACHE 0x1f
+#define OP_SH_CACHE 16
+#define OP_MASK_RD 0x1f
+#define OP_SH_RD 11
+#define OP_MASK_FS 0x1f
+#define OP_SH_FS 11
+#define OP_MASK_PREFX 0x1f
+#define OP_SH_PREFX 11
+#define OP_MASK_CCC 0x7
+#define OP_SH_CCC 8
+#define OP_MASK_SYSCALL 0xfffff
+#define OP_SH_SYSCALL 6
+#define OP_MASK_SHAMT 0x1f
+#define OP_SH_SHAMT 6
+#define OP_MASK_FD 0x1f
+#define OP_SH_FD 6
+#define OP_MASK_TARGET 0x3ffffff
+#define OP_SH_TARGET 0
+#define OP_MASK_COPZ 0x1ffffff
+#define OP_SH_COPZ 0
+#define OP_MASK_IMMEDIATE 0xffff
+#define OP_SH_IMMEDIATE 0
+#define OP_MASK_DELTA 0xffff
+#define OP_SH_DELTA 0
+#define OP_MASK_FUNCT 0x3f
+#define OP_SH_FUNCT 0
+#define OP_MASK_SPEC 0x3f
+#define OP_SH_SPEC 0
+#define OP_SH_LOCC 8 /* FP condition code */
+#define OP_SH_HICC 18 /* FP condition code */
+#define OP_MASK_CC 0x7
+#define OP_SH_COP1NORM 25 /* Normal COP1 encoding */
+#define OP_MASK_COP1NORM 0x1 /* a single bit */
+#define OP_SH_COP1SPEC 21 /* COP1 encodings */
+#define OP_MASK_COP1SPEC 0xf
+#define OP_MASK_COP1SCLR 0x4
+#define OP_MASK_COP1CMP 0x3
+#define OP_SH_COP1CMP 4
+#define OP_SH_FORMAT 21 /* FP short format field */
+#define OP_MASK_FORMAT 0x7
+#define OP_SH_TRUE 16
+#define OP_MASK_TRUE 0x1
+#define OP_SH_GE 17
+#define OP_MASK_GE 0x01
+#define OP_SH_UNSIGNED 16
+#define OP_MASK_UNSIGNED 0x1
+#define OP_SH_HINT 16
+#define OP_MASK_HINT 0x1f
+#define OP_SH_MMI 0 /* Multimedia (parallel) op */
+#define OP_MASK_MMI 0x3f
+#define OP_SH_MMISUB 6
+#define OP_MASK_MMISUB 0x1f
+#define OP_MASK_PERFREG 0x1f /* Performance monitoring */
+#define OP_SH_PERFREG 1
+
+/* This structure holds information for a particular instruction. */
+
+struct mips_opcode
+{
+ /* The name of the instruction. */
+ const char *name;
+ /* A string describing the arguments for this instruction. */
+ const char *args;
+ /* The basic opcode for the instruction. When assembling, this
+ opcode is modified by the arguments to produce the actual opcode
+ that is used. If pinfo is INSN_MACRO, then this is 0. */
+ unsigned long match;
+ /* If pinfo is not INSN_MACRO, then this is a bit mask for the
+ relevant portions of the opcode when disassembling. If the
+ actual opcode anded with the match field equals the opcode field,
+ then we have found the correct instruction. If pinfo is
+ INSN_MACRO, then this field is the macro identifier. */
+ unsigned long mask;
+ /* For a macro, this is INSN_MACRO. Otherwise, it is a collection
+ of bits describing the instruction, notably any relevant hazard
+ information. */
+ unsigned long pinfo;
+ /* A collection of bits describing the instruction sets of which this
+ instruction or macro is a member. */
+ unsigned long membership;
+};
+
+/* These are the characters which may appears in the args field of an
+ instruction. They appear in the order in which the fields appear
+ when the instruction is used. Commas and parentheses in the args
+ string are ignored when assembling, and written into the output
+ when disassembling.
+
+ Each of these characters corresponds to a mask field defined above.
+
+ "<" 5 bit shift amount (OP_*_SHAMT)
+ ">" shift amount between 32 and 63, stored after subtracting 32 (OP_*_SHAMT)
+ "a" 26 bit target address (OP_*_TARGET)
+ "b" 5 bit base register (OP_*_RS)
+ "c" 10 bit breakpoint code (OP_*_CODE)
+ "d" 5 bit destination register specifier (OP_*_RD)
+ "h" 5 bit prefx hint (OP_*_PREFX)
+ "i" 16 bit unsigned immediate (OP_*_IMMEDIATE)
+ "j" 16 bit signed immediate (OP_*_DELTA)
+ "k" 5 bit cache opcode in target register position (OP_*_CACHE)
+ "o" 16 bit signed offset (OP_*_DELTA)
+ "p" 16 bit PC relative branch target address (OP_*_DELTA)
+ "q" 10 bit extra breakpoint code (OP_*_CODE2)
+ "r" 5 bit same register used as both source and target (OP_*_RS)
+ "s" 5 bit source register specifier (OP_*_RS)
+ "t" 5 bit target register (OP_*_RT)
+ "u" 16 bit upper 16 bits of address (OP_*_IMMEDIATE)
+ "v" 5 bit same register used as both source and destination (OP_*_RS)
+ "w" 5 bit same register used as both target and destination (OP_*_RT)
+ "C" 25 bit coprocessor function code (OP_*_COPZ)
+ "B" 20 bit syscall function code (OP_*_SYSCALL)
+ "x" accept and ignore register name
+ "z" must be zero register
+
+ Floating point instructions:
+ "D" 5 bit destination register (OP_*_FD)
+ "M" 3 bit compare condition code (OP_*_CCC) (only used for mips4 and up)
+ "N" 3 bit branch condition code (OP_*_BCC) (only used for mips4 and up)
+ "S" 5 bit fs source 1 register (OP_*_FS)
+ "T" 5 bit ft source 2 register (OP_*_FT)
+ "R" 5 bit fr source 3 register (OP_*_FR)
+ "V" 5 bit same register used as floating source and destination (OP_*_FS)
+ "W" 5 bit same register used as floating target and destination (OP_*_FT)
+
+ Coprocessor instructions:
+ "E" 5 bit target register (OP_*_RT)
+ "G" 5 bit destination register (OP_*_RD)
+ "P" 5 bit performance-monitor register (OP_*_PERFREG)
+
+ Macro instructions:
+ "A" General 32 bit expression
+ "I" 32 bit immediate
+ "F" 64 bit floating point constant in .rdata
+ "L" 64 bit floating point constant in .lit8
+ "f" 32 bit floating point constant
+ "l" 32 bit floating point constant in .lit4
+
+ Other:
+ "()" parens surrounding optional value
+ "," separates operands
+
+ Characters used so far, for quick reference when adding more:
+ "<>(),"
+ "ABCDEFGILMNSTRVW"
+ "abcdfhijklopqrstuvwxz"
+*/
+
+/* These are the bits which may be set in the pinfo field of an
+ instructions, if it is not equal to INSN_MACRO. */
+
+/* Modifies the general purpose register in OP_*_RD. */
+#define INSN_WRITE_GPR_D 0x00000001
+/* Modifies the general purpose register in OP_*_RT. */
+#define INSN_WRITE_GPR_T 0x00000002
+/* Modifies general purpose register 31. */
+#define INSN_WRITE_GPR_31 0x00000004
+/* Modifies the floating point register in OP_*_FD. */
+#define INSN_WRITE_FPR_D 0x00000008
+/* Modifies the floating point register in OP_*_FS. */
+#define INSN_WRITE_FPR_S 0x00000010
+/* Modifies the floating point register in OP_*_FT. */
+#define INSN_WRITE_FPR_T 0x00000020
+/* Reads the general purpose register in OP_*_RS. */
+#define INSN_READ_GPR_S 0x00000040
+/* Reads the general purpose register in OP_*_RT. */
+#define INSN_READ_GPR_T 0x00000080
+/* Reads the floating point register in OP_*_FS. */
+#define INSN_READ_FPR_S 0x00000100
+/* Reads the floating point register in OP_*_FT. */
+#define INSN_READ_FPR_T 0x00000200
+/* Reads the floating point register in OP_*_FR. */
+#define INSN_READ_FPR_R 0x00000400
+/* Modifies coprocessor condition code. */
+#define INSN_WRITE_COND_CODE 0x00000800
+/* Reads coprocessor condition code. */
+#define INSN_READ_COND_CODE 0x00001000
+/* TLB operation. */
+#define INSN_TLB 0x00002000
+/* Reads coprocessor register other than floating point register. */
+#define INSN_COP 0x00004000
+/* Instruction loads value from memory, requiring delay. */
+#define INSN_LOAD_MEMORY_DELAY 0x00008000
+/* Instruction loads value from coprocessor, requiring delay. */
+#define INSN_LOAD_COPROC_DELAY 0x00010000
+/* Instruction has unconditional branch delay slot. */
+#define INSN_UNCOND_BRANCH_DELAY 0x00020000
+/* Instruction has conditional branch delay slot. */
+#define INSN_COND_BRANCH_DELAY 0x00040000
+/* Conditional branch likely: if branch not taken, insn nullified. */
+#define INSN_COND_BRANCH_LIKELY 0x00080000
+/* Moves to coprocessor register, requiring delay. */
+#define INSN_COPROC_MOVE_DELAY 0x00100000
+/* Loads coprocessor register from memory, requiring delay. */
+#define INSN_COPROC_MEMORY_DELAY 0x00200000
+/* Reads the HI register. */
+#define INSN_READ_HI 0x00400000
+/* Reads the LO register. */
+#define INSN_READ_LO 0x00800000
+/* Modifies the HI register. */
+#define INSN_WRITE_HI 0x01000000
+/* Modifies the LO register. */
+#define INSN_WRITE_LO 0x02000000
+/* Takes a trap (easier to keep out of delay slot). */
+#define INSN_TRAP 0x04000000
+/* Instruction stores value into memory. */
+#define INSN_STORE_MEMORY 0x08000000
+/* Instruction uses single precision floating point. */
+#define FP_S 0x10000000
+/* Instruction uses double precision floating point. */
+#define FP_D 0x20000000
+/* Instruction is part of the tx39's integer multiply family. */
+#define INSN_MULT 0x40000000
+/* Instruction synchronize shared memory. */
+#define INSN_SYNC 0x80000000
+
+/* Instruction is actually a macro. It should be ignored by the
+ disassembler, and requires special treatment by the assembler. */
+#define INSN_MACRO 0xffffffff
+
+
+
+
+
+/* MIPS ISA field--CPU level at which insn is supported. */
+#define INSN_ISA 0x0000000F
+/* An instruction which is not part of any basic MIPS ISA.
+ (ie it is a chip specific instruction) */
+#define INSN_NO_ISA 0x00000000
+/* MIPS ISA 1 instruction. */
+#define INSN_ISA1 0x00000001
+/* MIPS ISA 2 instruction (R6000 or R4000). */
+#define INSN_ISA2 0x00000002
+/* MIPS ISA 3 instruction (R4000). */
+#define INSN_ISA3 0x00000003
+/* MIPS ISA 4 instruction (R8000). */
+#define INSN_ISA4 0x00000004
+
+/* Chip specific instructions. These are bitmasks. */
+/* MIPS R4650 instruction. */
+#define INSN_4650 0x00000010
+/* LSI R4010 instruction. */
+#define INSN_4010 0x00000020
+/* NEC VR4100 instruction. */
+#define INSN_4100 0x00000040
+/* Toshiba R3900 instruction. */
+#define INSN_3900 0x00000080
+
+
+/* This is a list of macro expanded instructions.
+ *
+ * _I appended means immediate
+ * _A appended means address
+ * _AB appended means address with base register
+ * _D appended means 64 bit floating point constant
+ * _S appended means 32 bit floating point constant
+ */
+enum {
+ M_ABS,
+ M_ADD_I,
+ M_ADDU_I,
+ M_AND_I,
+ M_BEQ,
+ M_BEQ_I,
+ M_BEQL_I,
+ M_BGE,
+ M_BGEL,
+ M_BGE_I,
+ M_BGEL_I,
+ M_BGEU,
+ M_BGEUL,
+ M_BGEU_I,
+ M_BGEUL_I,
+ M_BGT,
+ M_BGTL,
+ M_BGT_I,
+ M_BGTL_I,
+ M_BGTU,
+ M_BGTUL,
+ M_BGTU_I,
+ M_BGTUL_I,
+ M_BLE,
+ M_BLEL,
+ M_BLE_I,
+ M_BLEL_I,
+ M_BLEU,
+ M_BLEUL,
+ M_BLEU_I,
+ M_BLEUL_I,
+ M_BLT,
+ M_BLTL,
+ M_BLT_I,
+ M_BLTL_I,
+ M_BLTU,
+ M_BLTUL,
+ M_BLTU_I,
+ M_BLTUL_I,
+ M_BNE,
+ M_BNE_I,
+ M_BNEL_I,
+ M_DABS,
+ M_DADD_I,
+ M_DADDU_I,
+ M_DDIV_3,
+ M_DDIV_3I,
+ M_DDIVU_3,
+ M_DDIVU_3I,
+ M_DIV_3,
+ M_DIV_3I,
+ M_DIVU_3,
+ M_DIVU_3I,
+ M_DLA_AB,
+ M_DLI,
+ M_DMUL,
+ M_DMUL_I,
+ M_DMULO,
+ M_DMULO_I,
+ M_DMULOU,
+ M_DMULOU_I,
+ M_DREM_3,
+ M_DREM_3I,
+ M_DREMU_3,
+ M_DREMU_3I,
+ M_DSUB_I,
+ M_DSUBU_I,
+ M_DSUBU_I_2,
+ M_J_A,
+ M_JAL_1,
+ M_JAL_2,
+ M_JAL_A,
+ M_L_DOB,
+ M_L_DAB,
+ M_LA_AB,
+ M_LB_A,
+ M_LB_AB,
+ M_LBU_A,
+ M_LBU_AB,
+ M_LD_A,
+ M_LD_OB,
+ M_LD_AB,
+ M_LDC1_AB,
+ M_LDC2_AB,
+ M_LDC3_AB,
+ M_LDL_AB,
+ M_LDR_AB,
+ M_LH_A,
+ M_LH_AB,
+ M_LHU_A,
+ M_LHU_AB,
+ M_LI,
+ M_LI_D,
+ M_LI_DD,
+ M_LI_S,
+ M_LI_SS,
+ M_LL_AB,
+ M_LLD_AB,
+ M_LS_A,
+ M_LW_A,
+ M_LW_AB,
+ M_LWC0_A,
+ M_LWC0_AB,
+ M_LWC1_A,
+ M_LWC1_AB,
+ M_LWC2_A,
+ M_LWC2_AB,
+ M_LWC3_A,
+ M_LWC3_AB,
+ M_LWL_A,
+ M_LWL_AB,
+ M_LWR_A,
+ M_LWR_AB,
+ M_LWU_AB,
+ M_MUL,
+ M_MUL_I,
+ M_MULO,
+ M_MULO_I,
+ M_MULOU,
+ M_MULOU_I,
+ M_NOR_I,
+ M_OR_I,
+ M_REM_3,
+ M_REM_3I,
+ M_REMU_3,
+ M_REMU_3I,
+ M_ROL,
+ M_ROL_I,
+ M_ROR,
+ M_ROR_I,
+ M_S_DA,
+ M_S_DOB,
+ M_S_DAB,
+ M_S_S,
+ M_SC_AB,
+ M_SCD_AB,
+ M_SD_A,
+ M_SD_OB,
+ M_SD_AB,
+ M_SDC1_AB,
+ M_SDC2_AB,
+ M_SDC3_AB,
+ M_SDL_AB,
+ M_SDR_AB,
+ M_SEQ,
+ M_SEQ_I,
+ M_SGE,
+ M_SGE_I,
+ M_SGEU,
+ M_SGEU_I,
+ M_SGT,
+ M_SGT_I,
+ M_SGTU,
+ M_SGTU_I,
+ M_SLE,
+ M_SLE_I,
+ M_SLEU,
+ M_SLEU_I,
+ M_SLT_I,
+ M_SLTU_I,
+ M_SNE,
+ M_SNE_I,
+ M_SB_A,
+ M_SB_AB,
+ M_SH_A,
+ M_SH_AB,
+ M_SW_A,
+ M_SW_AB,
+ M_SWC0_A,
+ M_SWC0_AB,
+ M_SWC1_A,
+ M_SWC1_AB,
+ M_SWC2_A,
+ M_SWC2_AB,
+ M_SWC3_A,
+ M_SWC3_AB,
+ M_SWL_A,
+ M_SWL_AB,
+ M_SWR_A,
+ M_SWR_AB,
+ M_SUB_I,
+ M_SUBU_I,
+ M_SUBU_I_2,
+ M_TEQ_I,
+ M_TGE_I,
+ M_TGEU_I,
+ M_TLT_I,
+ M_TLTU_I,
+ M_TNE_I,
+ M_TRUNCWD,
+ M_TRUNCWS,
+ M_ULD,
+ M_ULD_A,
+ M_ULH,
+ M_ULH_A,
+ M_ULHU,
+ M_ULHU_A,
+ M_ULW,
+ M_ULW_A,
+ M_USH,
+ M_USH_A,
+ M_USW,
+ M_USW_A,
+ M_USD,
+ M_USD_A,
+ M_XOR_I,
+ M_COP0,
+ M_COP1,
+ M_COP2,
+ M_COP3,
+ M_NUM_MACROS
+};
+
+
+/* The order of overloaded instructions matters. Label arguments and
+ register arguments look the same. Instructions that can have either
+ for arguments must apear in the correct order in this table for the
+ assembler to pick the right one. In other words, entries with
+ immediate operands must apear after the same instruction with
+ registers.
+
+ Many instructions are short hand for other instructions (i.e., The
+ jal <register> instruction is short for jalr <register>). */
+
+extern const struct mips_opcode mips_builtin_opcodes[];
+extern const int bfd_mips_num_builtin_opcodes;
+extern struct mips_opcode *mips_opcodes;
+extern int bfd_mips_num_opcodes;
+#define NUMOPCODES bfd_mips_num_opcodes
+
+
+/* The rest of this file adds definitions for the mips16 TinyRISC
+ processor. */
+
+/* These are the bitmasks and shift counts used for the different
+ fields in the instruction formats. Other than OP, no masks are
+ provided for the fixed portions of an instruction, since they are
+ not needed.
+
+ The I format uses IMM11.
+
+ The RI format uses RX and IMM8.
+
+ The RR format uses RX, and RY.
+
+ The RRI format uses RX, RY, and IMM5.
+
+ The RRR format uses RX, RY, and RZ.
+
+ The RRI_A format uses RX, RY, and IMM4.
+
+ The SHIFT format uses RX, RY, and SHAMT.
+
+ The I8 format uses IMM8.
+
+ The I8_MOVR32 format uses RY and REGR32.
+
+ The IR_MOV32R format uses REG32R and MOV32Z.
+
+ The I64 format uses IMM8.
+
+ The RI64 format uses RY and IMM5.
+ */
+
+#define MIPS16OP_MASK_OP 0x1f
+#define MIPS16OP_SH_OP 11
+#define MIPS16OP_MASK_IMM11 0x7ff
+#define MIPS16OP_SH_IMM11 0
+#define MIPS16OP_MASK_RX 0x7
+#define MIPS16OP_SH_RX 8
+#define MIPS16OP_MASK_IMM8 0xff
+#define MIPS16OP_SH_IMM8 0
+#define MIPS16OP_MASK_RY 0x7
+#define MIPS16OP_SH_RY 5
+#define MIPS16OP_MASK_IMM5 0x1f
+#define MIPS16OP_SH_IMM5 0
+#define MIPS16OP_MASK_RZ 0x7
+#define MIPS16OP_SH_RZ 2
+#define MIPS16OP_MASK_IMM4 0xf
+#define MIPS16OP_SH_IMM4 0
+#define MIPS16OP_MASK_REGR32 0x1f
+#define MIPS16OP_SH_REGR32 0
+#define MIPS16OP_MASK_REG32R 0x1f
+#define MIPS16OP_SH_REG32R 3
+#define MIPS16OP_EXTRACT_REG32R(i) ((((i) >> 5) & 7) | ((i) & 0x18))
+#define MIPS16OP_MASK_MOVE32Z 0x7
+#define MIPS16OP_SH_MOVE32Z 0
+#define MIPS16OP_MASK_IMM6 0x3f
+#define MIPS16OP_SH_IMM6 5
+
+/* These are the characters which may appears in the args field of an
+ instruction. They appear in the order in which the fields appear
+ when the instruction is used. Commas and parentheses in the args
+ string are ignored when assembling, and written into the output
+ when disassembling.
+
+ "y" 3 bit register (MIPS16OP_*_RY)
+ "x" 3 bit register (MIPS16OP_*_RX)
+ "z" 3 bit register (MIPS16OP_*_RZ)
+ "Z" 3 bit register (MIPS16OP_*_MOVE32Z)
+ "v" 3 bit same register as source and destination (MIPS16OP_*_RX)
+ "w" 3 bit same register as source and destination (MIPS16OP_*_RY)
+ "0" zero register ($0)
+ "S" stack pointer ($sp or $29)
+ "P" program counter
+ "R" return address register ($ra or $31)
+ "X" 5 bit MIPS register (MIPS16OP_*_REGR32)
+ "Y" 5 bit MIPS register (MIPS16OP_*_REG32R)
+ "6" 6 bit unsigned break code (MIPS16OP_*_IMM6)
+ "a" 26 bit jump address
+ "e" 11 bit extension value
+ "l" register list for entry instruction
+ "L" register list for exit instruction
+
+ The remaining codes may be extended. Except as otherwise noted,
+ the full extended operand is a 16 bit signed value.
+ "<" 3 bit unsigned shift count * 0 (MIPS16OP_*_RZ) (full 5 bit unsigned)
+ ">" 3 bit unsigned shift count * 0 (MIPS16OP_*_RX) (full 5 bit unsigned)
+ "[" 3 bit unsigned shift count * 0 (MIPS16OP_*_RZ) (full 6 bit unsigned)
+ "]" 3 bit unsigned shift count * 0 (MIPS16OP_*_RX) (full 6 bit unsigned)
+ "4" 4 bit signed immediate * 0 (MIPS16OP_*_IMM4) (full 15 bit signed)
+ "5" 5 bit unsigned immediate * 0 (MIPS16OP_*_IMM5)
+ "H" 5 bit unsigned immediate * 2 (MIPS16OP_*_IMM5)
+ "W" 5 bit unsigned immediate * 4 (MIPS16OP_*_IMM5)
+ "D" 5 bit unsigned immediate * 8 (MIPS16OP_*_IMM5)
+ "j" 5 bit signed immediate * 0 (MIPS16OP_*_IMM5)
+ "8" 8 bit unsigned immediate * 0 (MIPS16OP_*_IMM8)
+ "V" 8 bit unsigned immediate * 4 (MIPS16OP_*_IMM8)
+ "C" 8 bit unsigned immediate * 8 (MIPS16OP_*_IMM8)
+ "U" 8 bit unsigned immediate * 0 (MIPS16OP_*_IMM8) (full 16 bit unsigned)
+ "k" 8 bit signed immediate * 0 (MIPS16OP_*_IMM8)
+ "K" 8 bit signed immediate * 8 (MIPS16OP_*_IMM8)
+ "p" 8 bit conditional branch address (MIPS16OP_*_IMM8)
+ "q" 11 bit branch address (MIPS16OP_*_IMM11)
+ "A" 8 bit PC relative address * 4 (MIPS16OP_*_IMM8)
+ "B" 5 bit PC relative address * 8 (MIPS16OP_*_IMM5)
+ "E" 5 bit PC relative address * 4 (MIPS16OP_*_IMM5)
+ */
+
+/* For the mips16, we use the same opcode table format and a few of
+ the same flags. However, most of the flags are different. */
+
+/* Modifies the register in MIPS16OP_*_RX. */
+#define MIPS16_INSN_WRITE_X 0x00000001
+/* Modifies the register in MIPS16OP_*_RY. */
+#define MIPS16_INSN_WRITE_Y 0x00000002
+/* Modifies the register in MIPS16OP_*_RZ. */
+#define MIPS16_INSN_WRITE_Z 0x00000004
+/* Modifies the T ($24) register. */
+#define MIPS16_INSN_WRITE_T 0x00000008
+/* Modifies the SP ($29) register. */
+#define MIPS16_INSN_WRITE_SP 0x00000010
+/* Modifies the RA ($31) register. */
+#define MIPS16_INSN_WRITE_31 0x00000020
+/* Modifies the general purpose register in MIPS16OP_*_REG32R. */
+#define MIPS16_INSN_WRITE_GPR_Y 0x00000040
+/* Reads the register in MIPS16OP_*_RX. */
+#define MIPS16_INSN_READ_X 0x00000080
+/* Reads the register in MIPS16OP_*_RY. */
+#define MIPS16_INSN_READ_Y 0x00000100
+/* Reads the register in MIPS16OP_*_MOVE32Z. */
+#define MIPS16_INSN_READ_Z 0x00000200
+/* Reads the T ($24) register. */
+#define MIPS16_INSN_READ_T 0x00000400
+/* Reads the SP ($29) register. */
+#define MIPS16_INSN_READ_SP 0x00000800
+/* Reads the RA ($31) register. */
+#define MIPS16_INSN_READ_31 0x00001000
+/* Reads the program counter. */
+#define MIPS16_INSN_READ_PC 0x00002000
+/* Reads the general purpose register in MIPS16OP_*_REGR32. */
+#define MIPS16_INSN_READ_GPR_X 0x00004000
+/* Is a branch insn. */
+#define MIPS16_INSN_BRANCH 0x00010000
+
+/* The following flags have the same value for the mips16 opcode
+ table:
+ INSN_UNCOND_BRANCH_DELAY
+ INSN_COND_BRANCH_DELAY
+ INSN_COND_BRANCH_LIKELY (never used)
+ INSN_READ_HI
+ INSN_READ_LO
+ INSN_WRITE_HI
+ INSN_WRITE_LO
+ INSN_TRAP
+ INSN_ISA3
+ */
+
+extern const struct mips_opcode mips16_opcodes[];
+extern const int bfd_mips16_num_opcodes;
+
+#endif /* _MIPS_H_ */
diff --git a/include/opcode/mn10200.h b/include/opcode/mn10200.h
new file mode 100644
index 00000000000..42fa94b0c6e
--- /dev/null
+++ b/include/opcode/mn10200.h
@@ -0,0 +1,110 @@
+/* mn10200.h -- Header file for Matsushita 10200 opcode table
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+ Written by Jeff Law, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef MN10200_H
+#define MN10200_H
+
+/* The opcode table is an array of struct mn10200_opcode. */
+
+struct mn10200_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* The opcode itself. Those bits which will be filled in with
+ operands are zeroes. */
+ unsigned long opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a
+ mask containing ones indicating those bits which must match the
+ opcode field, and zeroes indicating those bits which need not
+ match (and are presumably filled in by operands). */
+ unsigned long mask;
+
+ /* The format of this opcode. */
+ unsigned char format;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ unsigned char operands[8];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+ in the order in which the disassembler should consider
+ instructions. */
+extern const struct mn10200_opcode mn10200_opcodes[];
+extern const int mn10200_num_opcodes;
+
+
+/* The operands table is an array of struct mn10200_operand. */
+
+struct mn10200_operand
+{
+ /* The number of bits in the operand. */
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+ int shift;
+
+ /* One bit syntax flags. */
+ int flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the mn10200_opcodes table. */
+
+extern const struct mn10200_operand mn10200_operands[];
+
+/* Values defined for the flags field of a struct mn10200_operand. */
+#define MN10200_OPERAND_DREG 0x1
+
+#define MN10200_OPERAND_AREG 0x2
+
+#define MN10200_OPERAND_PSW 0x4
+
+#define MN10200_OPERAND_MDR 0x8
+
+#define MN10200_OPERAND_SIGNED 0x10
+
+#define MN10200_OPERAND_PROMOTE 0x20
+
+#define MN10200_OPERAND_PAREN 0x40
+
+#define MN10200_OPERAND_REPEATED 0x80
+
+#define MN10200_OPERAND_EXTENDED 0x100
+
+#define MN10200_OPERAND_NOCHECK 0x200
+
+#define MN10200_OPERAND_PCREL 0x400
+
+#define MN10200_OPERAND_MEMADDR 0x800
+
+#define MN10200_OPERAND_RELAX 0x1000
+
+#define FMT_1 1
+#define FMT_2 2
+#define FMT_3 3
+#define FMT_4 4
+#define FMT_5 5
+#define FMT_6 6
+#define FMT_7 7
+#endif /* MN10200_H */
diff --git a/include/opcode/mn10300.h b/include/opcode/mn10300.h
new file mode 100644
index 00000000000..34e4b0b438f
--- /dev/null
+++ b/include/opcode/mn10300.h
@@ -0,0 +1,138 @@
+/* mn10300.h -- Header file for Matsushita 10300 opcode table
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+ Written by Jeff Law, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef MN10300_H
+#define MN10300_H
+
+/* The opcode table is an array of struct mn10300_opcode. */
+
+#define MN10300_MAX_OPERANDS 8
+struct mn10300_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* The opcode itself. Those bits which will be filled in with
+ operands are zeroes. */
+ unsigned long opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a
+ mask containing ones indicating those bits which must match the
+ opcode field, and zeroes indicating those bits which need not
+ match (and are presumably filled in by operands). */
+ unsigned long mask;
+
+ /* A bitmask. For each operand, nonzero if it must not have the same
+ register specification as all other operands with a nonzero bit in
+ this flag. ie 0x81 would indicate that operands 7 and 0 must not
+ match. Note that we count operands from left to right as they appear
+ in the operands specification below. */
+ unsigned int no_match_operands;
+
+ /* The format of this opcode. */
+ unsigned char format;
+
+ /* Bitmask indicating what cpu variants this opcode is available on.
+ We assume mn10300 base opcodes are available everywhere, so we only
+ have to note opcodes which are available on other variants. */
+ unsigned int machine;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ unsigned char operands[MN10300_MAX_OPERANDS];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+ in the order in which the disassembler should consider
+ instructions. */
+extern const struct mn10300_opcode mn10300_opcodes[];
+extern const int mn10300_num_opcodes;
+
+
+/* The operands table is an array of struct mn10300_operand. */
+
+struct mn10300_operand
+{
+ /* The number of bits in the operand. */
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+ int shift;
+
+ /* One bit syntax flags. */
+ int flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the mn10300_opcodes table. */
+
+extern const struct mn10300_operand mn10300_operands[];
+
+/* Values defined for the flags field of a struct mn10300_operand. */
+#define MN10300_OPERAND_DREG 0x1
+
+#define MN10300_OPERAND_AREG 0x2
+
+#define MN10300_OPERAND_SP 0x4
+
+#define MN10300_OPERAND_PSW 0x8
+
+#define MN10300_OPERAND_MDR 0x10
+
+#define MN10300_OPERAND_SIGNED 0x20
+
+#define MN10300_OPERAND_PROMOTE 0x40
+
+#define MN10300_OPERAND_PAREN 0x80
+
+#define MN10300_OPERAND_REPEATED 0x100
+
+#define MN10300_OPERAND_EXTENDED 0x200
+
+#define MN10300_OPERAND_SPLIT 0x400
+
+#define MN10300_OPERAND_REG_LIST 0x800
+
+#define MN10300_OPERAND_PCREL 0x1000
+
+#define MN10300_OPERAND_MEMADDR 0x2000
+
+#define MN10300_OPERAND_RELAX 0x4000
+
+
+/* Opcode Formats. */
+#define FMT_S0 1
+#define FMT_S1 2
+#define FMT_S2 3
+#define FMT_S4 4
+#define FMT_S6 5
+#define FMT_D0 6
+#define FMT_D1 7
+#define FMT_D2 8
+#define FMT_D4 9
+#define FMT_D5 10
+
+/* Variants of the mn10300 which have additional opcodes. */
+#define MN103 300
+#define AM30 300
+
+
+#endif /* MN10300_H */
diff --git a/include/opcode/np1.h b/include/opcode/np1.h
new file mode 100644
index 00000000000..d23adc7566c
--- /dev/null
+++ b/include/opcode/np1.h
@@ -0,0 +1,422 @@
+/* Print GOULD NPL instructions for GDB, the GNU debugger.
+ Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB 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 1, or (at your option)
+any later version.
+
+GDB 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 GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+struct gld_opcode
+{
+ char *name;
+ unsigned long opcode;
+ unsigned long mask;
+ char *args;
+ int length;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+ is the most any of them need. The actual length of an instruction
+ is always at least 2 bytes, and at most four. The length of the
+ instruction is based on the opcode.
+
+ The mask component is a mask saying which bits must match
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing characters
+ that are used to format the arguments to the instruction. */
+
+/* Kinds of operands:
+ r Register in first field
+ R Register in second field
+ b Base register in first field
+ B Base register in second field
+ v Vector register in first field
+ V Vector register in first field
+ A Optional address register (base register)
+ X Optional index register
+ I Immediate data (16bits signed)
+ O Offset field (16bits signed)
+ h Offset field (15bits signed)
+ d Offset field (14bits signed)
+ S Shift count field
+
+ any other characters are printed as is...
+*/
+
+/* The assembler requires that this array be sorted as follows:
+ all instances of the same mnemonic must be consecutive.
+ All instances of the same mnemonic with the same number of operands
+ must be consecutive.
+ */
+struct gld_opcode gld_opcodes[] =
+{
+{ "lb", 0xb4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lnb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lbs", 0xec080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lh", 0xb4000001, 0xfc080001, "r,xOA,X", 4 },
+{ "lnh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "lw", 0xb4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lnw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "ld", 0xb4000002, 0xfc080002, "r,xOA,X", 4 },
+{ "lnd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "li", 0xf8000000, 0xfc7f0000, "r,I", 4 },
+{ "lpa", 0x50080000, 0xfc080000, "r,xOA,X", 4 },
+{ "la", 0x50000000, 0xfc080000, "r,xOA,X", 4 },
+{ "labr", 0x58080000, 0xfc080000, "b,xOA,X", 4 },
+{ "lbp", 0x90080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lhp", 0x90000001, 0xfc080001, "r,xOA,X", 4 },
+{ "lwp", 0x90000000, 0xfc080000, "r,xOA,X", 4 },
+{ "ldp", 0x90000002, 0xfc080002, "r,xOA,X", 4 },
+{ "suabr", 0x58000000, 0xfc080000, "b,xOA,X", 4 },
+{ "lf", 0xbc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lfbr", 0xbc080000, 0xfc080000, "b,xOA,X", 4 },
+{ "lwbr", 0x5c000000, 0xfc080000, "b,xOA,X", 4 },
+{ "stb", 0xd4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "sth", 0xd4000001, 0xfc080001, "r,xOA,X", 4 },
+{ "stw", 0xd4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "std", 0xd4000002, 0xfc080002, "r,xOA,X", 4 },
+{ "stf", 0xdc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "stfbr", 0xdc080000, 0xfc080000, "b,xOA,X", 4 },
+{ "stwbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 },
+{ "zmb", 0xd8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "zmh", 0xd8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "zmw", 0xd8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "zmd", 0xd8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "stbp", 0x94080000, 0xfc080000, "r,xOA,X", 4 },
+{ "sthp", 0x94000001, 0xfc080001, "r,xOA,X", 4 },
+{ "stwp", 0x94000000, 0xfc080000, "r,xOA,X", 4 },
+{ "stdp", 0x94000002, 0xfc080002, "r,xOA,X", 4 },
+{ "lil", 0xf80b0000, 0xfc7f0000, "r,D", 4 },
+{ "lwsl1", 0xec000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lwsl2", 0xfc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lwsl3", 0xfc080000, 0xfc080000, "r,xOA,X", 4 },
+
+{ "lvb", 0xb0080000, 0xfc080000, "v,xOA,X", 4 },
+{ "lvh", 0xb0000001, 0xfc080001, "v,xOA,X", 4 },
+{ "lvw", 0xb0000000, 0xfc080000, "v,xOA,X", 4 },
+{ "lvd", 0xb0000002, 0xfc080002, "v,xOA,X", 4 },
+{ "liv", 0x3c040000, 0xfc0f0000, "v,R", 2 },
+{ "livf", 0x3c080000, 0xfc0f0000, "v,R", 2 },
+{ "stvb", 0xd0080000, 0xfc080000, "v,xOA,X", 4 },
+{ "stvh", 0xd0000001, 0xfc080001, "v,xOA,X", 4 },
+{ "stvw", 0xd0000000, 0xfc080000, "v,xOA,X", 4 },
+{ "stvd", 0xd0000002, 0xfc080002, "v,xOA,X", 4 },
+
+{ "trr", 0x2c000000, 0xfc0f0000, "r,R", 2 },
+{ "trn", 0x2c040000, 0xfc0f0000, "r,R", 2 },
+{ "trnd", 0x2c0c0000, 0xfc0f0000, "r,R", 2 },
+{ "trabs", 0x2c010000, 0xfc0f0000, "r,R", 2 },
+{ "trabsd", 0x2c090000, 0xfc0f0000, "r,R", 2 },
+{ "trc", 0x2c030000, 0xfc0f0000, "r,R", 2 },
+{ "xcr", 0x28040000, 0xfc0f0000, "r,R", 2 },
+{ "cxcr", 0x2c060000, 0xfc0f0000, "r,R", 2 },
+{ "cxcrd", 0x2c0e0000, 0xfc0f0000, "r,R", 2 },
+{ "tbrr", 0x2c020000, 0xfc0f0000, "r,B", 2 },
+{ "trbr", 0x28030000, 0xfc0f0000, "b,R", 2 },
+{ "xcbr", 0x28020000, 0xfc0f0000, "b,B", 2 },
+{ "tbrbr", 0x28010000, 0xfc0f0000, "b,B", 2 },
+
+{ "trvv", 0x28050000, 0xfc0f0000, "v,V", 2 },
+{ "trvvn", 0x2c050000, 0xfc0f0000, "v,V", 2 },
+{ "trvvnd", 0x2c0d0000, 0xfc0f0000, "v,V", 2 },
+{ "trvab", 0x2c070000, 0xfc0f0000, "v,V", 2 },
+{ "trvabd", 0x2c0f0000, 0xfc0f0000, "v,V", 2 },
+{ "cmpv", 0x14060000, 0xfc0f0000, "v,V", 2 },
+{ "expv", 0x14070000, 0xfc0f0000, "v,V", 2 },
+{ "mrvvlt", 0x10030000, 0xfc0f0000, "v,V", 2 },
+{ "mrvvle", 0x10040000, 0xfc0f0000, "v,V", 2 },
+{ "mrvvgt", 0x14030000, 0xfc0f0000, "v,V", 2 },
+{ "mrvvge", 0x14040000, 0xfc0f0000, "v,V", 2 },
+{ "mrvveq", 0x10050000, 0xfc0f0000, "v,V", 2 },
+{ "mrvvne", 0x10050000, 0xfc0f0000, "v,V", 2 },
+{ "mrvrlt", 0x100d0000, 0xfc0f0000, "v,R", 2 },
+{ "mrvrle", 0x100e0000, 0xfc0f0000, "v,R", 2 },
+{ "mrvrgt", 0x140d0000, 0xfc0f0000, "v,R", 2 },
+{ "mrvrge", 0x140e0000, 0xfc0f0000, "v,R", 2 },
+{ "mrvreq", 0x100f0000, 0xfc0f0000, "v,R", 2 },
+{ "mrvrne", 0x140f0000, 0xfc0f0000, "v,R", 2 },
+{ "trvr", 0x140b0000, 0xfc0f0000, "r,V", 2 },
+{ "trrv", 0x140c0000, 0xfc0f0000, "v,R", 2 },
+
+{ "bu", 0x40000000, 0xff880000, "xOA,X", 4 },
+{ "bns", 0x70080000, 0xff880000, "xOA,X", 4 },
+{ "bnco", 0x70880000, 0xff880000, "xOA,X", 4 },
+{ "bge", 0x71080000, 0xff880000, "xOA,X", 4 },
+{ "bne", 0x71880000, 0xff880000, "xOA,X", 4 },
+{ "bunge", 0x72080000, 0xff880000, "xOA,X", 4 },
+{ "bunle", 0x72880000, 0xff880000, "xOA,X", 4 },
+{ "bgt", 0x73080000, 0xff880000, "xOA,X", 4 },
+{ "bnany", 0x73880000, 0xff880000, "xOA,X", 4 },
+{ "bs" , 0x70000000, 0xff880000, "xOA,X", 4 },
+{ "bco", 0x70800000, 0xff880000, "xOA,X", 4 },
+{ "blt", 0x71000000, 0xff880000, "xOA,X", 4 },
+{ "beq", 0x71800000, 0xff880000, "xOA,X", 4 },
+{ "buge", 0x72000000, 0xff880000, "xOA,X", 4 },
+{ "bult", 0x72800000, 0xff880000, "xOA,X", 4 },
+{ "ble", 0x73000000, 0xff880000, "xOA,X", 4 },
+{ "bany", 0x73800000, 0xff880000, "xOA,X", 4 },
+{ "brlnk", 0x44000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bib", 0x48000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bih", 0x48080000, 0xfc080000, "r,xOA,X", 4 },
+{ "biw", 0x4c000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bid", 0x4c080000, 0xfc080000, "r,xOA,X", 4 },
+{ "bivb", 0x60000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bivh", 0x60080000, 0xfc080000, "r,xOA,X", 4 },
+{ "bivw", 0x64000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bivd", 0x64080000, 0xfc080000, "r,xOA,X", 4 },
+{ "bvsb", 0x68000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bvsh", 0x68080000, 0xfc080000, "r,xOA,X", 4 },
+{ "bvsw", 0x6c000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bvsd", 0x6c080000, 0xfc080000, "r,xOA,X", 4 },
+
+{ "camb", 0x80080000, 0xfc080000, "r,xOA,X", 4 },
+{ "camh", 0x80000001, 0xfc080001, "r,xOA,X", 4 },
+{ "camw", 0x80000000, 0xfc080000, "r,xOA,X", 4 },
+{ "camd", 0x80000002, 0xfc080002, "r,xOA,X", 4 },
+{ "car", 0x10000000, 0xfc0f0000, "r,R", 2 },
+{ "card", 0x14000000, 0xfc0f0000, "r,R", 2 },
+{ "ci", 0xf8050000, 0xfc7f0000, "r,I", 4 },
+{ "chkbnd", 0x5c080000, 0xfc080000, "r,xOA,X", 4 },
+
+{ "cavv", 0x10010000, 0xfc0f0000, "v,V", 2 },
+{ "cavr", 0x10020000, 0xfc0f0000, "v,R", 2 },
+{ "cavvd", 0x10090000, 0xfc0f0000, "v,V", 2 },
+{ "cavrd", 0x100b0000, 0xfc0f0000, "v,R", 2 },
+
+{ "anmb", 0x84080000, 0xfc080000, "r,xOA,X", 4 },
+{ "anmh", 0x84000001, 0xfc080001, "r,xOA,X", 4 },
+{ "anmw", 0x84000000, 0xfc080000, "r,xOA,X", 4 },
+{ "anmd", 0x84000002, 0xfc080002, "r,xOA,X", 4 },
+{ "anr", 0x04000000, 0xfc0f0000, "r,R", 2 },
+{ "ani", 0xf8080000, 0xfc7f0000, "r,I", 4 },
+{ "ormb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "ormh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "ormw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "ormd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "orr", 0x08000000, 0xfc0f0000, "r,R", 2 },
+{ "oi", 0xf8090000, 0xfc7f0000, "r,I", 4 },
+{ "eomb", 0x8c080000, 0xfc080000, "r,xOA,X", 4 },
+{ "eomh", 0x8c000001, 0xfc080001, "r,xOA,X", 4 },
+{ "eomw", 0x8c000000, 0xfc080000, "r,xOA,X", 4 },
+{ "eomd", 0x8c000002, 0xfc080002, "r,xOA,X", 4 },
+{ "eor", 0x0c000000, 0xfc0f0000, "r,R", 2 },
+{ "eoi", 0xf80a0000, 0xfc7f0000, "r,I", 4 },
+
+{ "anvv", 0x04010000, 0xfc0f0000, "v,V", 2 },
+{ "anvr", 0x04020000, 0xfc0f0000, "v,R", 2 },
+{ "orvv", 0x08010000, 0xfc0f0000, "v,V", 2 },
+{ "orvr", 0x08020000, 0xfc0f0000, "v,R", 2 },
+{ "eovv", 0x0c010000, 0xfc0f0000, "v,V", 2 },
+{ "eovr", 0x0c020000, 0xfc0f0000, "v,R", 2 },
+
+{ "sacz", 0x100c0000, 0xfc0f0000, "r,R", 2 },
+{ "sla", 0x1c400000, 0xfc600000, "r,S", 2 },
+{ "sll", 0x1c600000, 0xfc600000, "r,S", 2 },
+{ "slc", 0x24400000, 0xfc600000, "r,S", 2 },
+{ "slad", 0x20400000, 0xfc600000, "r,S", 2 },
+{ "slld", 0x20600000, 0xfc600000, "r,S", 2 },
+{ "sra", 0x1c000000, 0xfc600000, "r,S", 2 },
+{ "srl", 0x1c200000, 0xfc600000, "r,S", 2 },
+{ "src", 0x24000000, 0xfc600000, "r,S", 2 },
+{ "srad", 0x20000000, 0xfc600000, "r,S", 2 },
+{ "srld", 0x20200000, 0xfc600000, "r,S", 2 },
+{ "sda", 0x3c030000, 0xfc0f0000, "r,R", 2 },
+{ "sdl", 0x3c020000, 0xfc0f0000, "r,R", 2 },
+{ "sdc", 0x3c010000, 0xfc0f0000, "r,R", 2 },
+{ "sdad", 0x3c0b0000, 0xfc0f0000, "r,R", 2 },
+{ "sdld", 0x3c0a0000, 0xfc0f0000, "r,R", 2 },
+
+{ "svda", 0x3c070000, 0xfc0f0000, "v,R", 2 },
+{ "svdl", 0x3c060000, 0xfc0f0000, "v,R", 2 },
+{ "svdc", 0x3c050000, 0xfc0f0000, "v,R", 2 },
+{ "svdad", 0x3c0e0000, 0xfc0f0000, "v,R", 2 },
+{ "svdld", 0x3c0d0000, 0xfc0f0000, "v,R", 2 },
+
+{ "sbm", 0xac080000, 0xfc080000, "f,xOA,X", 4 },
+{ "zbm", 0xac000000, 0xfc080000, "f,xOA,X", 4 },
+{ "tbm", 0xa8080000, 0xfc080000, "f,xOA,X", 4 },
+{ "incmb", 0xa0000000, 0xfc080000, "xOA,X", 4 },
+{ "incmh", 0xa0080000, 0xfc080000, "xOA,X", 4 },
+{ "incmw", 0xa4000000, 0xfc080000, "xOA,X", 4 },
+{ "incmd", 0xa4080000, 0xfc080000, "xOA,X", 4 },
+{ "sbmd", 0x7c080000, 0xfc080000, "r,xOA,X", 4 },
+{ "zbmd", 0x7c000000, 0xfc080000, "r,xOA,X", 4 },
+{ "tbmd", 0x78080000, 0xfc080000, "r,xOA,X", 4 },
+
+{ "ssm", 0x9c080000, 0xfc080000, "f,xOA,X", 4 },
+{ "zsm", 0x9c000000, 0xfc080000, "f,xOA,X", 4 },
+{ "tsm", 0x98080000, 0xfc080000, "f,xOA,X", 4 },
+
+{ "admb", 0xc8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "admh", 0xc8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "admw", 0xc8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "admd", 0xc8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "adr", 0x38000000, 0xfc0f0000, "r,R", 2 },
+{ "armb", 0xe8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "armh", 0xe8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "armw", 0xe8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "armd", 0xe8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "adi", 0xf8010000, 0xfc0f0000, "r,I", 4 },
+{ "sumb", 0xcc080000, 0xfc080000, "r,xOA,X", 4 },
+{ "sumh", 0xcc000001, 0xfc080001, "r,xOA,X", 4 },
+{ "sumw", 0xcc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "sumd", 0xcc000002, 0xfc080002, "r,xOA,X", 4 },
+{ "sur", 0x3c000000, 0xfc0f0000, "r,R", 2 },
+{ "sui", 0xf8020000, 0xfc0f0000, "r,I", 4 },
+{ "mpmb", 0xc0080000, 0xfc080000, "r,xOA,X", 4 },
+{ "mpmh", 0xc0000001, 0xfc080001, "r,xOA,X", 4 },
+{ "mpmw", 0xc0000000, 0xfc080000, "r,xOA,X", 4 },
+{ "mpr", 0x38020000, 0xfc0f0000, "r,R", 2 },
+{ "mprd", 0x3c0f0000, 0xfc0f0000, "r,R", 2 },
+{ "mpi", 0xf8030000, 0xfc0f0000, "r,I", 4 },
+{ "dvmb", 0xc4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "dvmh", 0xc4000001, 0xfc080001, "r,xOA,X", 4 },
+{ "dvmw", 0xc4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "dvr", 0x380a0000, 0xfc0f0000, "r,R", 2 },
+{ "dvi", 0xf8040000, 0xfc0f0000, "r,I", 4 },
+{ "exs", 0x38080000, 0xfc0f0000, "r,R", 2 },
+
+{ "advv", 0x30000000, 0xfc0f0000, "v,V", 2 },
+{ "advvd", 0x30080000, 0xfc0f0000, "v,V", 2 },
+{ "adrv", 0x34000000, 0xfc0f0000, "v,R", 2 },
+{ "adrvd", 0x34080000, 0xfc0f0000, "v,R", 2 },
+{ "suvv", 0x30010000, 0xfc0f0000, "v,V", 2 },
+{ "suvvd", 0x30090000, 0xfc0f0000, "v,V", 2 },
+{ "surv", 0x34010000, 0xfc0f0000, "v,R", 2 },
+{ "survd", 0x34090000, 0xfc0f0000, "v,R", 2 },
+{ "mpvv", 0x30020000, 0xfc0f0000, "v,V", 2 },
+{ "mprv", 0x34020000, 0xfc0f0000, "v,R", 2 },
+
+{ "adfw", 0xe0080000, 0xfc080000, "r,xOA,X", 4 },
+{ "adfd", 0xe0080002, 0xfc080002, "r,xOA,X", 4 },
+{ "adrfw", 0x38010000, 0xfc0f0000, "r,R", 2 },
+{ "adrfd", 0x38090000, 0xfc0f0000, "r,R", 2 },
+{ "surfw", 0xe0000000, 0xfc080000, "r,xOA,X", 4 },
+{ "surfd", 0xe0000002, 0xfc080002, "r,xOA,X", 4 },
+{ "surfw", 0x38030000, 0xfc0f0000, "r,R", 2 },
+{ "surfd", 0x380b0000, 0xfc0f0000, "r,R", 2 },
+{ "mpfw", 0xe4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "mpfd", 0xe4080002, 0xfc080002, "r,xOA,X", 4 },
+{ "mprfw", 0x38060000, 0xfc0f0000, "r,R", 2 },
+{ "mprfd", 0x380e0000, 0xfc0f0000, "r,R", 2 },
+{ "rfw", 0xe4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "rfd", 0xe4000002, 0xfc080002, "r,xOA,X", 4 },
+{ "rrfw", 0x0c0e0000, 0xfc0f0000, "r", 2 },
+{ "rrfd", 0x0c0f0000, 0xfc0f0000, "r", 2 },
+
+{ "advvfw", 0x30040000, 0xfc0f0000, "v,V", 2 },
+{ "advvfd", 0x300c0000, 0xfc0f0000, "v,V", 2 },
+{ "adrvfw", 0x34040000, 0xfc0f0000, "v,R", 2 },
+{ "adrvfd", 0x340c0000, 0xfc0f0000, "v,R", 2 },
+{ "suvvfw", 0x30050000, 0xfc0f0000, "v,V", 2 },
+{ "suvvfd", 0x300d0000, 0xfc0f0000, "v,V", 2 },
+{ "survfw", 0x34050000, 0xfc0f0000, "v,R", 2 },
+{ "survfd", 0x340d0000, 0xfc0f0000, "v,R", 2 },
+{ "mpvvfw", 0x30060000, 0xfc0f0000, "v,V", 2 },
+{ "mpvvfd", 0x300e0000, 0xfc0f0000, "v,V", 2 },
+{ "mprvfw", 0x34060000, 0xfc0f0000, "v,R", 2 },
+{ "mprvfd", 0x340e0000, 0xfc0f0000, "v,R", 2 },
+{ "rvfw", 0x30070000, 0xfc0f0000, "v", 2 },
+{ "rvfd", 0x300f0000, 0xfc0f0000, "v", 2 },
+
+{ "fltw", 0x38070000, 0xfc0f0000, "r,R", 2 },
+{ "fltd", 0x380f0000, 0xfc0f0000, "r,R", 2 },
+{ "fixw", 0x38050000, 0xfc0f0000, "r,R", 2 },
+{ "fixd", 0x380d0000, 0xfc0f0000, "r,R", 2 },
+{ "cfpds", 0x3c090000, 0xfc0f0000, "r,R", 2 },
+
+{ "fltvw", 0x080d0000, 0xfc0f0000, "v,V", 2 },
+{ "fltvd", 0x080f0000, 0xfc0f0000, "v,V", 2 },
+{ "fixvw", 0x080c0000, 0xfc0f0000, "v,V", 2 },
+{ "fixvd", 0x080e0000, 0xfc0f0000, "v,V", 2 },
+{ "cfpvds", 0x0c0d0000, 0xfc0f0000, "v,V", 2 },
+
+{ "orvrn", 0x000a0000, 0xfc0f0000, "r,V", 2 },
+{ "andvrn", 0x00080000, 0xfc0f0000, "r,V", 2 },
+{ "frsteq", 0x04090000, 0xfc0f0000, "r,V", 2 },
+{ "sigma", 0x0c080000, 0xfc0f0000, "r,V", 2 },
+{ "sigmad", 0x0c0a0000, 0xfc0f0000, "r,V", 2 },
+{ "sigmf", 0x08080000, 0xfc0f0000, "r,V", 2 },
+{ "sigmfd", 0x080a0000, 0xfc0f0000, "r,V", 2 },
+{ "prodf", 0x04080000, 0xfc0f0000, "r,V", 2 },
+{ "prodfd", 0x040a0000, 0xfc0f0000, "r,V", 2 },
+{ "maxv", 0x10080000, 0xfc0f0000, "r,V", 2 },
+{ "maxvd", 0x100a0000, 0xfc0f0000, "r,V", 2 },
+{ "minv", 0x14080000, 0xfc0f0000, "r,V", 2 },
+{ "minvd", 0x140a0000, 0xfc0f0000, "r,V", 2 },
+
+{ "lpsd", 0xf0000000, 0xfc080000, "xOA,X", 4 },
+{ "ldc", 0xf0080000, 0xfc080000, "xOA,X", 4 },
+{ "spm", 0x040c0000, 0xfc0f0000, "r", 2 },
+{ "rpm", 0x040d0000, 0xfc0f0000, "r", 2 },
+{ "tritr", 0x00070000, 0xfc0f0000, "r", 2 },
+{ "trrit", 0x00060000, 0xfc0f0000, "r", 2 },
+{ "rpswt", 0x04080000, 0xfc0f0000, "r", 2 },
+{ "exr", 0xf8070000, 0xfc0f0000, "", 4 },
+{ "halt", 0x00000000, 0xfc0f0000, "", 2 },
+{ "wait", 0x00010000, 0xfc0f0000, "", 2 },
+{ "nop", 0x00020000, 0xfc0f0000, "", 2 },
+{ "eiae", 0x00030000, 0xfc0f0000, "", 2 },
+{ "efae", 0x000d0000, 0xfc0f0000, "", 2 },
+{ "diae", 0x000e0000, 0xfc0f0000, "", 2 },
+{ "dfae", 0x000f0000, 0xfc0f0000, "", 2 },
+{ "spvc", 0xf8060000, 0xfc0f0000, "r,T,N", 4 },
+{ "rdsts", 0x00090000, 0xfc0f0000, "r", 2 },
+{ "setcpu", 0x000c0000, 0xfc0f0000, "r", 2 },
+{ "cmc", 0x000b0000, 0xfc0f0000, "r", 2 },
+{ "trrcu", 0x00040000, 0xfc0f0000, "r", 2 },
+{ "attnio", 0x00050000, 0xfc0f0000, "", 2 },
+{ "fudit", 0x28080000, 0xfc0f0000, "", 2 },
+{ "break", 0x28090000, 0xfc0f0000, "", 2 },
+{ "frzss", 0x280a0000, 0xfc0f0000, "", 2 },
+{ "ripi", 0x04040000, 0xfc0f0000, "r,R", 2 },
+{ "xcp", 0x04050000, 0xfc0f0000, "r", 2 },
+{ "block", 0x04060000, 0xfc0f0000, "", 2 },
+{ "unblock", 0x04070000, 0xfc0f0000, "", 2 },
+{ "trsc", 0x08060000, 0xfc0f0000, "r,R", 2 },
+{ "tscr", 0x08070000, 0xfc0f0000, "r,R", 2 },
+{ "fq", 0x04080000, 0xfc0f0000, "r", 2 },
+{ "flupte", 0x2c080000, 0xfc0f0000, "r", 2 },
+{ "rviu", 0x040f0000, 0xfc0f0000, "", 2 },
+{ "ldel", 0x280c0000, 0xfc0f0000, "r,R", 2 },
+{ "ldu", 0x280d0000, 0xfc0f0000, "r,R", 2 },
+{ "stdecc", 0x280b0000, 0xfc0f0000, "r,R", 2 },
+{ "trpc", 0x08040000, 0xfc0f0000, "r", 2 },
+{ "tpcr", 0x08050000, 0xfc0f0000, "r", 2 },
+{ "ghalt", 0x0c050000, 0xfc0f0000, "r", 2 },
+{ "grun", 0x0c040000, 0xfc0f0000, "", 2 },
+{ "tmpr", 0x2c0a0000, 0xfc0f0000, "r,R", 2 },
+{ "trmp", 0x2c0b0000, 0xfc0f0000, "r,R", 2 },
+
+{ "trrve", 0x28060000, 0xfc0f0000, "r", 2 },
+{ "trver", 0x28070000, 0xfc0f0000, "r", 2 },
+{ "trvlr", 0x280f0000, 0xfc0f0000, "r", 2 },
+
+{ "linkfl", 0x18000000, 0xfc0f0000, "r,R", 2 },
+{ "linkbl", 0x18020000, 0xfc0f0000, "r,R", 2 },
+{ "linkfp", 0x18010000, 0xfc0f0000, "r,R", 2 },
+{ "linkbp", 0x18030000, 0xfc0f0000, "r,R", 2 },
+{ "linkpl", 0x18040000, 0xfc0f0000, "r,R", 2 },
+{ "ulinkl", 0x18080000, 0xfc0f0000, "r,R", 2 },
+{ "ulinkp", 0x18090000, 0xfc0f0000, "r,R", 2 },
+{ "ulinktl", 0x180a0000, 0xfc0f0000, "r,R", 2 },
+{ "ulinktp", 0x180b0000, 0xfc0f0000, "r,R", 2 },
+};
+
+int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
+
+struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
+ sizeof(gld_opcodes[0]);
diff --git a/include/opcode/ns32k.h b/include/opcode/ns32k.h
new file mode 100644
index 00000000000..42bb8b87aad
--- /dev/null
+++ b/include/opcode/ns32k.h
@@ -0,0 +1,491 @@
+/* ns32k-opcode.h -- Opcode table for National Semi 32k processor
+ Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS 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 1, or (at your option)
+any later version.
+
+GAS 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 GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#ifdef SEQUENT_COMPATABILITY
+#define DEF_MODEC 20
+#define DEF_MODEL 21
+#endif
+
+#ifndef DEF_MODEC
+#define DEF_MODEC 20
+#endif
+
+#ifndef DEF_MODEL
+#define DEF_MODEL 20
+#endif
+/*
+ After deciding the instruction entry (via hash.c) the instruction parser
+ will try to match the operands after the instruction to the required set
+ given in the entry operandfield. Every operand will result in a change in
+ the opcode or the addition of data to the opcode.
+ The operands in the source instruction are checked for inconsistent
+ semantics.
+
+ F : 32 bit float general form
+ L : 64 bit float "
+ B : byte "
+ W : word "
+ D : double-word "
+ A : double-word gen-address-form ie no regs, no immediate
+ I : integer writeable gen int except immediate (A + reg)
+ Z : floating writeable gen float except immediate (Z + freg)
+ d : displacement
+ b : displacement - pc relative addressing acb
+ p : displacement - pc relative addressing br bcond bsr cxp
+ q : quick
+ i : immediate (8 bits)
+ This is not a standard ns32k operandtype, it is used to build
+ instructions like svc arg1,arg2
+ Svc is the instruction SuperVisorCall and is sometimes used to
+ call OS-routines from usermode. Some args might be handy!
+ r : register number (3 bits)
+ O : setcfg instruction optionslist
+ C : cinv instruction optionslist
+ S : stringinstruction optionslist
+ U : registerlist save,enter
+ u : registerlist restore,exit
+ M : mmu register
+ P : cpu register
+ g : 3:rd operand of inss or exts instruction
+ G : 4:th operand of inss or exts instruction
+ Those operands are encoded in the same byte.
+ This byte is placed last in the instruction.
+ f : operand of sfsr
+ H : sequent-hack for bsr (Warning)
+
+column 1 instructions
+ 2 number of bits in opcode.
+ 3 number of bits in opcode explicitly
+ determined by the instruction type.
+ 4 opcodeseed, the number we build our opcode
+ from.
+ 5 operandtypes, used by operandparser.
+ 6 size in bytes of immediate
+*/
+struct ns32k_opcode {
+ char *name;
+ unsigned char opcode_id_size; /* not used by the assembler */
+ unsigned char opcode_size;
+ unsigned long opcode_seed;
+ char *operands;
+ unsigned char im_size; /* not used by dissassembler */
+ char *default_args; /* default to those args when none given */
+ char default_modec; /* default to this addr-mode when ambigous
+ ie when the argument of a general addr-mode
+ is a plain constant */
+ char default_model; /* is a plain label */
+};
+
+#ifdef comment
+/* This section was from the gdb version of this file. */
+
+#ifndef ns32k_opcodeT
+#define ns32k_opcodeT int
+#endif /* no ns32k_opcodeT */
+
+struct not_wot /* ns32k opcode table: wot to do with this */
+ /* particular opcode */
+{
+ int obits; /* number of opcode bits */
+ int ibits; /* number of instruction bits */
+ ns32k_opcodeT code; /* op-code (may be > 8 bits!) */
+ char *args; /* how to compile said opcode */
+};
+
+struct not /* ns32k opcode text */
+{
+ char * name; /* opcode name: lowercase string [key] */
+ struct not_wot detail; /* rest of opcode table [datum] */
+};
+
+/* Instructions look like this:
+
+ basic instruction--1, 2, or 3 bytes
+ index byte for operand A, if operand A is indexed--1 byte
+ index byte for operand B, if operand B is indexed--1 byte
+ addressing extension for operand A
+ addressing extension for operand B
+ implied operands
+
+ Operand A is the operand listed first in the following opcode table.
+ Operand B is the operand listed second in the following opcode table.
+ All instructions have at most 2 general operands, so this is enough.
+ The implied operands are associated with operands other than A and B.
+
+ Each operand has a digit and a letter.
+
+ The digit gives the position in the assembly language. The letter,
+ one of the following, tells us what kind of operand it is. */
+
+/* F : 32 bit float
+ * L : 64 bit float
+ * B : byte
+ * W : word
+ * D : double-word
+ * I : integer not immediate
+ * Z : floating not immediate
+ * d : displacement
+ * q : quick
+ * i : immediate (8 bits)
+ * r : register number (3 bits)
+ * p : displacement - pc relative addressing
+*/
+
+
+#endif /* comment */
+
+static const struct ns32k_opcode ns32k_opcodes[]=
+{
+ { "absf", 14,24, 0x35be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "absl", 14,24, 0x34be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "absb", 14,24, 0x304e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "absw", 14,24, 0x314e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "absd", 14,24, 0x334e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "acbb", 7,16, 0x4c, "2I1q3p", 1, "", DEF_MODEC,DEF_MODEL },
+ { "acbw", 7,16, 0x4d, "2I1q3p", 2, "", DEF_MODEC,DEF_MODEL },
+ { "acbd", 7,16, 0x4f, "2I1q3p", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addf", 14,24, 0x01be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addl", 14,24, 0x00be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "addb", 6,16, 0x00, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addw", 6,16, 0x01, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addd", 6,16, 0x03, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addcb", 6,16, 0x10, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addcw", 6,16, 0x11, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addcd", 6,16, 0x13, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addpb", 14,24, 0x3c4e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addpw", 14,24, 0x3d4e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addpd", 14,24, 0x3f4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addqb", 7,16, 0x0c, "2I1q", 1, "", DEF_MODEC,DEF_MODEL },
+ { "addqw", 7,16, 0x0d, "2I1q", 2, "", DEF_MODEC,DEF_MODEL },
+ { "addqd", 7,16, 0x0f, "2I1q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "addr", 6,16, 0x27, "1A2I", 4, "", 21,21 },
+ { "adjspb", 11,16, 0x057c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "adjspw", 11,16, 0x057d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "adjspd", 11,16, 0x057f, "1D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "andb", 6,16, 0x28, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "andw", 6,16, 0x29, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "andd", 6,16, 0x2b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "ashb", 14,24, 0x044e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ashw", 14,24, 0x054e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ashd", 14,24, 0x074e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "beq", 8,8, 0x0a, "1p", 0, "", 21,21 },
+ { "bne", 8,8, 0x1a, "1p", 0, "", 21,21 },
+ { "bcs", 8,8, 0x2a, "1p", 0, "", 21,21 },
+ { "bcc", 8,8, 0x3a, "1p", 0, "", 21,21 },
+ { "bhi", 8,8, 0x4a, "1p", 0, "", 21,21 },
+ { "bls", 8,8, 0x5a, "1p", 0, "", 21,21 },
+ { "bgt", 8,8, 0x6a, "1p", 0, "", 21,21 },
+ { "ble", 8,8, 0x7a, "1p", 0, "", 21,21 },
+ { "bfs", 8,8, 0x8a, "1p", 0, "", 21,21 },
+ { "bfc", 8,8, 0x9a, "1p", 0, "", 21,21 },
+ { "blo", 8,8, 0xaa, "1p", 0, "", 21,21 },
+ { "bhs", 8,8, 0xba, "1p", 0, "", 21,21 },
+ { "blt", 8,8, 0xca, "1p", 0, "", 21,21 },
+ { "bge", 8,8, 0xda, "1p", 0, "", 21,21 },
+ { "but", 8,8, 0xea, "1p", 0, "", 21,21 },
+ { "buf", 8,8, 0xfa, "1p", 0, "", 21,21 },
+ { "bicb", 6,16, 0x08, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "bicw", 6,16, 0x09, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "bicd", 6,16, 0x0b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "bicpsrb", 11,16, 0x17c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "bicpsrw", 11,16, 0x17d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "bispsrb", 11,16, 0x37c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "bispsrw", 11,16, 0x37d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "bpt", 8,8, 0xf2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "br", 8,8, 0xea, "1p", 0, "", 21,21 },
+#ifdef SEQUENT_COMPATABILITY
+ { "bsr", 8,8, 0x02, "1H", 0, "", 21,21 },
+#else
+ { "bsr", 8,8, 0x02, "1p", 0, "", 21,21 },
+#endif
+ { "caseb", 11,16, 0x77c, "1B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "casew", 11,16, 0x77d, "1W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cased", 11,16, 0x77f, "1D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cbitb", 14,24, 0x084e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cbitw", 14,24, 0x094e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cbitd", 14,24, 0x0b4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cbitib", 14,24, 0x0c4e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cbitiw", 14,24, 0x0d4e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cbitid", 14,24, 0x0f4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "checkb", 11,24, 0x0ee, "2A3B1r", 1, "", DEF_MODEC,DEF_MODEL },
+ { "checkw", 11,24, 0x1ee, "2A3W1r", 2, "", DEF_MODEC,DEF_MODEL },
+ { "checkd", 11,24, 0x3ee, "2A3D1r", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cinv", 14,24, 0x271e, "2D1C", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpf", 14,24, 0x09be, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpl", 14,24, 0x08be, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "cmpb", 6,16, 0x04, "1B2B", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cmpw", 6,16, 0x05, "1W2W", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cmpd", 6,16, 0x07, "1D2D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpmb", 14,24, 0x04ce, "1A2A3b", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cmpmw", 14,24, 0x05ce, "1A2A3b", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cmpmd", 14,24, 0x07ce, "1A2A3b", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpqb", 7,16, 0x1c, "2B1q", 1, "", DEF_MODEC,DEF_MODEL },
+ { "cmpqw", 7,16, 0x1d, "2W1q", 2, "", DEF_MODEC,DEF_MODEL },
+ { "cmpqd", 7,16, 0x1f, "2D1q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cmpsb", 16,24, 0x040e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "cmpsw", 16,24, 0x050e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "cmpsd", 16,24, 0x070e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "cmpst", 16,24, 0x840e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "comb", 14,24, 0x344e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "comw", 14,24, 0x354e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "comd", 14,24, 0x374e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cvtp", 11,24, 0x036e, "2A3D1r", 4, "", DEF_MODEC,DEF_MODEL },
+ { "cxp", 8,8, 0x22, "1p", 0, "", 21,21 },
+ { "cxpd", 11,16, 0x07f, "1A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "deib", 14,24, 0x2cce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "deiw", 14,24, 0x2dce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "deid", 14,24, 0x2fce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "dia", 8,8, 0xc2, "", 1, "", DEF_MODEC,DEF_MODEL },
+ { "divf", 14,24, 0x21be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "divl", 14,24, 0x20be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "divb", 14,24, 0x3cce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "divw", 14,24, 0x3dce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "divd", 14,24, 0x3fce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "enter", 8,8, 0x82, "1U2d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "exit", 8,8, 0x92, "1u", 0, "", DEF_MODEC,DEF_MODEL },
+ { "extb", 11,24, 0x02e, "2I3B1r4d", 1, "", DEF_MODEC,DEF_MODEL },
+ { "extw", 11,24, 0x12e, "2I3W1r4d", 2, "", DEF_MODEC,DEF_MODEL },
+ { "extd", 11,24, 0x32e, "2I3D1r4d", 4, "", DEF_MODEC,DEF_MODEL },
+ { "extsb", 14,24, 0x0cce, "1I2I4G3g", 1, "", DEF_MODEC,DEF_MODEL },
+ { "extsw", 14,24, 0x0dce, "1I2I4G3g", 2, "", DEF_MODEC,DEF_MODEL },
+ { "extsd", 14,24, 0x0fce, "1I2I4G3g", 4, "", DEF_MODEC,DEF_MODEL },
+ { "ffsb", 14,24, 0x046e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ffsw", 14,24, 0x056e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "ffsd", 14,24, 0x076e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "flag", 8,8, 0xd2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "floorfb", 14,24, 0x3c3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "floorfw", 14,24, 0x3d3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "floorfd", 14,24, 0x3f3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "floorlb", 14,24, 0x383e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "floorlw", 14,24, 0x393e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "floorld", 14,24, 0x3b3e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "ibitb", 14,24, 0x384e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "ibitw", 14,24, 0x394e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "ibitd", 14,24, 0x3b4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "indexb", 11,24, 0x42e, "2B3B1r", 1, "", DEF_MODEC,DEF_MODEL },
+ { "indexw", 11,24, 0x52e, "2W3W1r", 2, "", DEF_MODEC,DEF_MODEL },
+ { "indexd", 11,24, 0x72e, "2D3D1r", 4, "", DEF_MODEC,DEF_MODEL },
+ { "insb", 11,24, 0x0ae, "2B3I1r4d", 1, "", DEF_MODEC,DEF_MODEL },
+ { "insw", 11,24, 0x1ae, "2W3I1r4d", 2, "", DEF_MODEC,DEF_MODEL },
+ { "insd", 11,24, 0x3ae, "2D3I1r4d", 4, "", DEF_MODEC,DEF_MODEL },
+ { "inssb", 14,24, 0x08ce, "1B2I4G3g", 1, "", DEF_MODEC,DEF_MODEL },
+ { "inssw", 14,24, 0x09ce, "1W2I4G3g", 2, "", DEF_MODEC,DEF_MODEL },
+ { "inssd", 14,24, 0x0bce, "1D2I4G3g", 4, "", DEF_MODEC,DEF_MODEL },
+ { "jsr", 11,16, 0x67f, "1A", 4, "", 21,21 },
+ { "jump", 11,16, 0x27f, "1A", 4, "", 21,21 },
+ { "lfsr", 19,24, 0x00f3e,"1D", 4, "", DEF_MODEC,DEF_MODEL },
+ { "lmr", 15,24, 0x0b1e, "2D1M", 4, "", DEF_MODEC,DEF_MODEL },
+ { "lprb", 7,16, 0x6c, "2B1P", 1, "", DEF_MODEC,DEF_MODEL },
+ { "lprw", 7,16, 0x6d, "2W1P", 2, "", DEF_MODEC,DEF_MODEL },
+ { "lprd", 7,16, 0x6f, "2D1P", 4, "", DEF_MODEC,DEF_MODEL },
+ { "lshb", 14,24, 0x144e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "lshw", 14,24, 0x154e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "lshd", 14,24, 0x174e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "meib", 14,24, 0x24ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "meiw", 14,24, 0x25ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "meid", 14,24, 0x27ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "modb", 14,24, 0x38ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "modw", 14,24, 0x39ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "modd", 14,24, 0x3bce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movf", 14,24, 0x05be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movl", 14,24, 0x04be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "movb", 6,16, 0x14, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movw", 6,16, 0x15, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movd", 6,16, 0x17, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movbf", 14,24, 0x043e, "1B2Z", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movwf", 14,24, 0x053e, "1W2Z", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movdf", 14,24, 0x073e, "1D2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movbl", 14,24, 0x003e, "1B2Z", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movwl", 14,24, 0x013e, "1W2Z", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movdl", 14,24, 0x033e, "1D2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movfl", 14,24, 0x1b3e, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movlf", 14,24, 0x163e, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "movmb", 14,24, 0x00ce, "1A2A3b", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movmw", 14,24, 0x01ce, "1A2A3b", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movmd", 14,24, 0x03ce, "1A2A3b", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movqb", 7,16, 0x5c, "2I1q", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movqw", 7,16, 0x5d, "2I1q", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movqd", 7,16, 0x5f, "2I1q", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movsb", 16,24, 0x000e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movsw", 16,24, 0x010e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movsd", 16,24, 0x030e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movst", 16,24, 0x800e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "movsub", 14,24, 0x0cae, "1A2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movsuw", 14,24, 0x0dae, "1A2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movsud", 14,24, 0x0fae, "1A2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movusb", 14,24, 0x1cae, "1A2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movusw", 14,24, 0x1dae, "1A2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movusd", 14,24, 0x1fae, "1A2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "movxbd", 14,24, 0x1cce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movxwd", 14,24, 0x1dce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movxbw", 14,24, 0x10ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movzbd", 14,24, 0x18ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "movzwd", 14,24, 0x19ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "movzbw", 14,24, 0x14ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "mulf", 14,24, 0x31be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "mull", 14,24, 0x30be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "mulb", 14,24, 0x20ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "mulw", 14,24, 0x21ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "muld", 14,24, 0x23ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "negf", 14,24, 0x15be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "negl", 14,24, 0x14be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "negb", 14,24, 0x204e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "negw", 14,24, 0x214e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "negd", 14,24, 0x234e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "nop", 8,8, 0xa2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "notb", 14,24, 0x244e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "notw", 14,24, 0x254e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "notd", 14,24, 0x274e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "orb", 6,16, 0x18, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "orw", 6,16, 0x19, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "ord", 6,16, 0x1b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "quob", 14,24, 0x30ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "quow", 14,24, 0x31ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "quod", 14,24, 0x33ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "rdval", 19,24, 0x0031e,"1A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "remb", 14,24, 0x34ce, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "remw", 14,24, 0x35ce, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "remd", 14,24, 0x37ce, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "restore", 8,8, 0x72, "1u", 0, "", DEF_MODEC,DEF_MODEL },
+ { "ret", 8,8, 0x12, "1d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "reti", 8,8, 0x52, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "rett", 8,8, 0x42, "1d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "rotb", 14,24, 0x004e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "rotw", 14,24, 0x014e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "rotd", 14,24, 0x034e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "roundfb", 14,24, 0x243e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "roundfw", 14,24, 0x253e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "roundfd", 14,24, 0x273e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "roundlb", 14,24, 0x203e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "roundlw", 14,24, 0x213e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "roundld", 14,24, 0x233e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "rxp", 8,8, 0x32, "1d", 0, "", DEF_MODEC,DEF_MODEL },
+ { "seqb", 11,16, 0x3c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "seqw", 11,16, 0x3d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "seqd", 11,16, 0x3f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sneb", 11,16, 0xbc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "snew", 11,16, 0xbd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sned", 11,16, 0xbf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "scsb", 11,16, 0x13c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "scsw", 11,16, 0x13d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "scsd", 11,16, 0x13f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sccb", 11,16, 0x1bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sccw", 11,16, 0x1bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sccd", 11,16, 0x1bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shib", 11,16, 0x23c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shiw", 11,16, 0x23d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shid", 11,16, 0x23f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slsb", 11,16, 0x2bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slsw", 11,16, 0x2bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slsd", 11,16, 0x2bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgtb", 11,16, 0x33c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgtw", 11,16, 0x33d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgtd", 11,16, 0x33f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sleb", 11,16, 0x3bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slew", 11,16, 0x3bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sled", 11,16, 0x3bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsb", 11,16, 0x43c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsw", 11,16, 0x43d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsd", 11,16, 0x43f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfcb", 11,16, 0x4bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfcw", 11,16, 0x4bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfcd", 11,16, 0x4bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slob", 11,16, 0x53c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slow", 11,16, 0x53d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "slod", 11,16, 0x53f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shsb", 11,16, 0x5bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shsw", 11,16, 0x5bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "shsd", 11,16, 0x5bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sltb", 11,16, 0x63c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sltw", 11,16, 0x63d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sltd", 11,16, 0x63f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgeb", 11,16, 0x6bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sgew", 11,16, 0x6bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sged", 11,16, 0x6bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sutb", 11,16, 0x73c, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sutw", 11,16, 0x73d, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sutd", 11,16, 0x73f, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sufb", 11,16, 0x7bc, "1B", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sufw", 11,16, 0x7bd, "1W", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sufd", 11,16, 0x7bf, "1D", 0, "", DEF_MODEC,DEF_MODEL },
+ { "save", 8,8, 0x62, "1U", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sbitb", 14,24, 0x184e, "1B2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "sbitw", 14,24, 0x194e, "1W2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "sbitd", 14,24, 0x1b4e, "1D2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "sbitib", 14,24, 0x1c4e, "1B2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "sbitiw", 14,24, 0x1d4e, "1W2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "sbitid", 14,24, 0x1f4e, "1D2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "setcfg", 15,24, 0x0b0e, "1O", 0, "", DEF_MODEC,DEF_MODEL },
+ { "sfsr", 14,24, 0x373e, "1f", 0, "", DEF_MODEC,DEF_MODEL },
+ { "skpsb", 16,24, 0x0c0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "skpsw", 16,24, 0x0d0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "skpsd", 16,24, 0x0f0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "skpst", 16,24, 0x8c0e, "1S", 0, "[]", DEF_MODEC,DEF_MODEL },
+ { "smr", 15,24, 0x0f1e, "2I1M", 4, "", DEF_MODEC,DEF_MODEL },
+ { "sprb", 7,16, 0x2c, "2I1P", 1, "", DEF_MODEC,DEF_MODEL },
+ { "sprw", 7,16, 0x2d, "2I1P", 2, "", DEF_MODEC,DEF_MODEL },
+ { "sprd", 7,16, 0x2f, "2I1P", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subf", 14,24, 0x11be, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subl", 14,24, 0x10be, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "subb", 6,16, 0x20, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "subw", 6,16, 0x21, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "subd", 6,16, 0x23, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subcb", 6,16, 0x30, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "subcw", 6,16, 0x31, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "subcd", 6,16, 0x33, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "subpb", 14,24, 0x2c4e, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "subpw", 14,24, 0x2d4e, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "subpd", 14,24, 0x2f4e, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+#ifdef NS32K_SVC_IMMED_OPERANDS
+ { "svc", 8,8, 0xe2, "2i1i", 1, "", DEF_MODEC,DEF_MODEL }, /* not really, but some unix uses it */
+#else
+ { "svc", 8,8, 0xe2, "", 0, "", DEF_MODEC,DEF_MODEL },
+#endif
+ { "tbitb", 6,16, 0x34, "1B2A", 1, "", DEF_MODEC,DEF_MODEL },
+ { "tbitw", 6,16, 0x35, "1W2A", 2, "", DEF_MODEC,DEF_MODEL },
+ { "tbitd", 6,16, 0x37, "1D2A", 4, "", DEF_MODEC,DEF_MODEL },
+ { "truncfb", 14,24, 0x2c3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "truncfw", 14,24, 0x2d3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "truncfd", 14,24, 0x2f3e, "1F2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "trunclb", 14,24, 0x283e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "trunclw", 14,24, 0x293e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "truncld", 14,24, 0x2b3e, "1L2I", 8, "", DEF_MODEC,DEF_MODEL },
+ { "wait", 8,8, 0xb2, "", 0, "", DEF_MODEC,DEF_MODEL },
+ { "wrval", 19,24, 0x0071e,"1A", 0, "", DEF_MODEC,DEF_MODEL },
+ { "xorb", 6,16, 0x38, "1B2I", 1, "", DEF_MODEC,DEF_MODEL },
+ { "xorw", 6,16, 0x39, "1W2I", 2, "", DEF_MODEC,DEF_MODEL },
+ { "xord", 6,16, 0x3b, "1D2I", 4, "", DEF_MODEC,DEF_MODEL },
+ { "dotf", 14,24, 0x0dfe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "dotl", 14,24, 0x0cfe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "logbf", 14,24, 0x15fe, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "logbl", 14,24, 0x14fe, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+ { "polyf", 14,24, 0x09fe, "1F2F", 4, "", DEF_MODEC,DEF_MODEL },
+ { "polyl", 14,24, 0x08fe, "1L2L", 8, "", DEF_MODEC,DEF_MODEL },
+ { "scalbf", 14,24, 0x11fe, "1F2Z", 4, "", DEF_MODEC,DEF_MODEL },
+ { "scalbl", 14,24, 0x10fe, "1L2Z", 8, "", DEF_MODEC,DEF_MODEL },
+};
+
+static const int numopcodes=sizeof(ns32k_opcodes)/sizeof(ns32k_opcodes[0]);
+
+static const struct ns32k_opcode *const endop = ns32k_opcodes+sizeof(ns32k_opcodes)/sizeof(ns32k_opcodes[0]);
+
+#define MAX_ARGS 4
+#define ARG_LEN 50
+
diff --git a/include/opcode/pn.h b/include/opcode/pn.h
new file mode 100644
index 00000000000..0f59a2a53ce
--- /dev/null
+++ b/include/opcode/pn.h
@@ -0,0 +1,282 @@
+/* Print GOULD PN (PowerNode) instructions for GDB, the GNU debugger.
+ Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+GDB 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 1, or (at your option)
+any later version.
+
+GDB 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 GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+struct gld_opcode
+{
+ char *name;
+ unsigned long opcode;
+ unsigned long mask;
+ char *args;
+ int length;
+};
+
+/* We store four bytes of opcode for all opcodes because that
+ is the most any of them need. The actual length of an instruction
+ is always at least 2 bytes, and at most four. The length of the
+ instruction is based on the opcode.
+
+ The mask component is a mask saying which bits must match
+ particular opcode in order for an instruction to be an instance
+ of that opcode.
+
+ The args component is a string containing characters
+ that are used to format the arguments to the instruction. */
+
+/* Kinds of operands:
+ r Register in first field
+ R Register in second field
+ b Base register in first field
+ B Base register in second field
+ v Vector register in first field
+ V Vector register in first field
+ A Optional address register (base register)
+ X Optional index register
+ I Immediate data (16bits signed)
+ O Offset field (16bits signed)
+ h Offset field (15bits signed)
+ d Offset field (14bits signed)
+ S Shift count field
+
+ any other characters are printed as is...
+*/
+
+/* The assembler requires that this array be sorted as follows:
+ all instances of the same mnemonic must be consecutive.
+ All instances of the same mnemonic with the same number of operands
+ must be consecutive.
+ */
+struct gld_opcode gld_opcodes[] =
+{
+{ "abm", 0xa0080000, 0xfc080000, "f,xOA,X", 4 },
+{ "abr", 0x18080000, 0xfc0c0000, "r,f", 2 },
+{ "aci", 0xfc770000, 0xfc7f8000, "r,I", 4 },
+{ "adfd", 0xe0080002, 0xfc080002, "r,xOA,X", 4 },
+{ "adfw", 0xe0080000, 0xfc080000, "r,xOA,X", 4 },
+{ "adi", 0xc8010000, 0xfc7f0000, "r,I", 4 },
+{ "admb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "admd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "admh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "admw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "adr", 0x38000000, 0xfc0f0000, "r,R", 2 },
+{ "adrfd", 0x38090000, 0xfc0f0000, "r,R", 2 },
+{ "adrfw", 0x38010000, 0xfc0f0000, "r,R", 2 },
+{ "adrm", 0x38080000, 0xfc0f0000, "r,R", 2 },
+{ "ai", 0xfc030000, 0xfc07ffff, "I", 4 },
+{ "anmb", 0x84080000, 0xfc080000, "r,xOA,X", 4 },
+{ "anmd", 0x84000002, 0xfc080002, "r,xOA,X", 4 },
+{ "anmh", 0x84000001, 0xfc080001, "r,xOA,X", 4 },
+{ "anmw", 0x84000000, 0xfc080000, "r,xOA,X", 4 },
+{ "anr", 0x04000000, 0xfc0f0000, "r,R", 2 },
+{ "armb", 0xe8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "armd", 0xe8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "armh", 0xe8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "armw", 0xe8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "bcf", 0xf0000000, 0xfc080000, "I,xOA,X", 4 },
+{ "bct", 0xec000000, 0xfc080000, "I,xOA,X", 4 },
+{ "bei", 0x00060000, 0xffff0000, "", 2 },
+{ "bft", 0xf0000000, 0xff880000, "xOA,X", 4 },
+{ "bib", 0xf4000000, 0xfc780000, "r,xOA", 4 },
+{ "bid", 0xf4600000, 0xfc780000, "r,xOA", 4 },
+{ "bih", 0xf4200000, 0xfc780000, "r,xOA", 4 },
+{ "biw", 0xf4400000, 0xfc780000, "r,xOA", 4 },
+{ "bl", 0xf8800000, 0xff880000, "xOA,X", 4 },
+{ "bsub", 0x5c080000, 0xff8f0000, "", 2 },
+{ "bsubm", 0x28080000, 0xfc080000, "", 4 },
+{ "bu", 0xec000000, 0xff880000, "xOA,X", 4 },
+{ "call", 0x28080000, 0xfc0f0000, "", 2 },
+{ "callm", 0x5c080000, 0xff880000, "", 4 },
+{ "camb", 0x90080000, 0xfc080000, "r,xOA,X", 4 },
+{ "camd", 0x90000002, 0xfc080002, "r,xOA,X", 4 },
+{ "camh", 0x90000001, 0xfc080001, "r,xOA,X", 4 },
+{ "camw", 0x90000000, 0xfc080000, "r.xOA,X", 4 },
+{ "car", 0x10000000, 0xfc0f0000, "r,R", 2 },
+{ "cd", 0xfc060000, 0xfc070000, "r,f", 4 },
+{ "cea", 0x000f0000, 0xffff0000, "", 2 },
+{ "ci", 0xc8050000, 0xfc7f0000, "r,I", 4 },
+{ "cmc", 0x040a0000, 0xfc7f0000, "r", 2 },
+{ "cmmb", 0x94080000, 0xfc080000, "r,xOA,X", 4 },
+{ "cmmd", 0x94000002, 0xfc080002, "r,xOA,X", 4 },
+{ "cmmh", 0x94000001, 0xfc080001, "r,xOA,X", 4 },
+{ "cmmw", 0x94000000, 0xfc080000, "r,xOA,X", 4 },
+{ "cmr", 0x14000000, 0xfc0f0000, "r,R", 2 },
+{ "daci", 0xfc7f0000, 0xfc7f8000, "r,I", 4 },
+{ "dae", 0x000e0000, 0xffff0000, "", 2 },
+{ "dai", 0xfc040000, 0xfc07ffff, "I", 4 },
+{ "dci", 0xfc6f0000, 0xfc7f8000, "r,I", 4 },
+{ "di", 0xfc010000, 0xfc07ffff, "I", 4 },
+{ "dvfd", 0xe4000002, 0xfc080002, "r,xOA,X", 4 },
+{ "dvfw", 0xe4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "dvi", 0xc8040000, 0xfc7f0000, "r,I", 4 },
+{ "dvmb", 0xc4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "dvmh", 0xc4000001, 0xfc080001, "r,xOA,X", 4 },
+{ "dvmw", 0xc4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "dvr", 0x380a0000, 0xfc0f0000, "r,R", 2 },
+{ "dvrfd", 0x380c0000, 0xfc0f0000, "r,R", 4 },
+{ "dvrfw", 0x38040000, 0xfc0f0000, "r,xOA,X", 4 },
+{ "eae", 0x00080000, 0xffff0000, "", 2 },
+{ "eci", 0xfc670000, 0xfc7f8080, "r,I", 4 },
+{ "ecwcs", 0xfc4f0000, 0xfc7f8000, "", 4 },
+{ "ei", 0xfc000000, 0xfc07ffff, "I", 4 },
+{ "eomb", 0x8c080000, 0xfc080000, "r,xOA,X", 4 },
+{ "eomd", 0x8c000002, 0xfc080002, "r,xOA,X", 4 },
+{ "eomh", 0x8c000001, 0xfc080001, "r,xOA,X", 4 },
+{ "eomw", 0x8c000000, 0xfc080000, "r,xOA,X", 4 },
+{ "eor", 0x0c000000, 0xfc0f0000, "r,R", 2 },
+{ "eorm", 0x0c080000, 0xfc0f0000, "r,R", 2 },
+{ "es", 0x00040000, 0xfc7f0000, "r", 2 },
+{ "exm", 0xa8000000, 0xff880000, "xOA,X", 4 },
+{ "exr", 0xc8070000, 0xfc7f0000, "r", 2 },
+{ "exrr", 0xc8070002, 0xfc7f0002, "r", 2 },
+{ "fixd", 0x380d0000, 0xfc0f0000, "r,R", 2 },
+{ "fixw", 0x38050000, 0xfc0f0000, "r,R", 2 },
+{ "fltd", 0x380f0000, 0xfc0f0000, "r,R", 2 },
+{ "fltw", 0x38070000, 0xfc0f0000, "r,R", 2 },
+{ "grio", 0xfc3f0000, 0xfc7f8000, "r,I", 4 },
+{ "halt", 0x00000000, 0xffff0000, "", 2 },
+{ "hio", 0xfc370000, 0xfc7f8000, "r,I", 4 },
+{ "jwcs", 0xfa080000, 0xff880000, "xOA,X", 4 },
+{ "la", 0x50000000, 0xfc000000, "r,xOA,X", 4 },
+{ "labr", 0x58080000, 0xfc080000, "b,xOA,X", 4 },
+{ "lb", 0xac080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lcs", 0x00030000, 0xfc7f0000, "r", 2 },
+{ "ld", 0xac000002, 0xfc080002, "r,xOA,X", 4 },
+{ "lear", 0x80000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lf", 0xcc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lfbr", 0xcc080000, 0xfc080000, "b,xOA,X", 4 },
+{ "lh", 0xac000001, 0xfc080001, "r,xOA,X", 4 },
+{ "li", 0xc8000000, 0xfc7f0000, "r,I", 4 },
+{ "lmap", 0x2c070000, 0xfc7f0000, "r", 2 },
+{ "lmb", 0xb0080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lmd", 0xb0000002, 0xfc080002, "r,xOA,X", 4 },
+{ "lmh", 0xb0000001, 0xfc080001, "r,xOA,X", 4 },
+{ "lmw", 0xb0000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lnb", 0xb4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "lnd", 0xb4000002, 0xfc080002, "r,xOA,X", 4 },
+{ "lnh", 0xb4000001, 0xfc080001, "r,xOA,X", 4 },
+{ "lnw", 0xb4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lpsd", 0xf9800000, 0xff880000, "r,xOA,X", 4 },
+{ "lpsdcm", 0xfa800000, 0xff880000, "r,xOA,X", 4 },
+{ "lw", 0xac000000, 0xfc080000, "r,xOA,X", 4 },
+{ "lwbr", 0x5c000000, 0xfc080000, "b,xOA,X", 4 },
+{ "mpfd", 0xe4080002, 0xfc080002, "r,xOA,X", 4 },
+{ "mpfw", 0xe4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "mpi", 0xc8030000, 0xfc7f0000, "r,I", 4 },
+{ "mpmb", 0xc0080000, 0xfc080000, "r,xOA,X", 4 },
+{ "mpmh", 0xc0000001, 0xfc080001, "r,xOA,X", 4 },
+{ "mpmw", 0xc0000000, 0xfc080000, "r,xOA,X", 4 },
+{ "mpr", 0x38020000, 0xfc0f0000, "r,R", 2 },
+{ "mprfd", 0x380e0000, 0xfc0f0000, "r,R", 2 },
+{ "mprfw", 0x38060000, 0xfc0f0000, "r,R", 2 },
+{ "nop", 0x00020000, 0xffff0000, "", 2 },
+{ "ormb", 0x88080000, 0xfc080000, "r,xOA,X", 4 },
+{ "ormd", 0x88000002, 0xfc080002, "r,xOA,X", 4 },
+{ "ormh", 0x88000001, 0xfc080001, "r,xOA,X", 4 },
+{ "ormw", 0x88000000, 0xfc080000, "r,xOA,X", 4 },
+{ "orr", 0x08000000, 0xfc0f0000, "r,R", 2 },
+{ "orrm", 0x08080000, 0xfc0f0000, "r,R", 2 },
+{ "rdsts", 0x00090000, 0xfc7f0000, "r", 2 },
+{ "return", 0x280e0000, 0xfc7f0000, "", 2 },
+{ "ri", 0xfc020000, 0xfc07ffff, "I", 4 },
+{ "rnd", 0x00050000, 0xfc7f0000, "r", 2 },
+{ "rpswt", 0x040b0000, 0xfc7f0000, "r", 2 },
+{ "rschnl", 0xfc2f0000, 0xfc7f8000, "r,I", 4 },
+{ "rsctl", 0xfc470000, 0xfc7f8000, "r,I", 4 },
+{ "rwcs", 0x000b0000, 0xfc0f0000, "r,R", 2 },
+{ "sacz", 0x10080000, 0xfc0f0000, "r,R", 2 },
+{ "sbm", 0x98080000, 0xfc080000, "f,xOA,X", 4 },
+{ "sbr", 0x18000000, 0xfc0c0000, "r,f", 4 },
+{ "sea", 0x000d0000, 0xffff0000, "", 2 },
+{ "setcpu", 0x2c090000, 0xfc7f0000, "r", 2 },
+{ "sio", 0xfc170000, 0xfc7f8000, "r,I", 4 },
+{ "sipu", 0x000a0000, 0xffff0000, "", 2 },
+{ "sla", 0x1c400000, 0xfc600000, "r,S", 2 },
+{ "slad", 0x20400000, 0xfc600000, "r,S", 2 },
+{ "slc", 0x24400000, 0xfc600000, "r,S", 2 },
+{ "sll", 0x1c600000, 0xfc600000, "r,S", 2 },
+{ "slld", 0x20600000, 0xfc600000, "r,S", 2 },
+{ "smc", 0x04070000, 0xfc070000, "", 2 },
+{ "sra", 0x1c000000, 0xfc600000, "r,S", 2 },
+{ "srad", 0x20000000, 0xfc600000, "r,S", 2 },
+{ "src", 0x24000000, 0xfc600000, "r,S", 2 },
+{ "srl", 0x1c200000, 0xfc600000, "r,S", 2 },
+{ "srld", 0x20200000, 0xfc600000, "r,S", 2 },
+{ "stb", 0xd4080000, 0xfc080000, "r,xOA,X", 4 },
+{ "std", 0xd4000002, 0xfc080002, "r,xOA,X", 4 },
+{ "stf", 0xdc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "stfbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 },
+{ "sth", 0xd4000001, 0xfc080001, "r,xOA,X", 4 },
+{ "stmb", 0xd8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "stmd", 0xd8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "stmh", 0xd8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "stmw", 0xd8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "stpio", 0xfc270000, 0xfc7f8000, "r,I", 4 },
+{ "stw", 0xd4000000, 0xfc080000, "r,xOA,X", 4 },
+{ "stwbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 },
+{ "suabr", 0x58000000, 0xfc080000, "b,xOA,X", 4 },
+{ "sufd", 0xe0000002, 0xfc080002, "r,xOA,X", 4 },
+{ "sufw", 0xe0000000, 0xfc080000, "r,xOA,X", 4 },
+{ "sui", 0xc8020000, 0xfc7f0000, "r,I", 4 },
+{ "sumb", 0xbc080000, 0xfc080000, "r,xOA,X", 4 },
+{ "sumd", 0xbc000002, 0xfc080002, "r,xOA,X", 4 },
+{ "sumh", 0xbc000001, 0xfc080001, "r,xOA,X", 4 },
+{ "sumw", 0xbc000000, 0xfc080000, "r,xOA,X", 4 },
+{ "sur", 0x3c000000, 0xfc0f0000, "r,R", 2 },
+{ "surfd", 0x380b0000, 0xfc0f0000, "r,xOA,X", 4 },
+{ "surfw", 0x38030000, 0xfc0f0000, "r,R", 2 },
+{ "surm", 0x3c080000, 0xfc0f0000, "r,R", 2 },
+{ "svc", 0xc8060000, 0xffff0000, "", 4 },
+{ "tbm", 0xa4080000, 0xfc080000, "f,xOA,X", 4 },
+{ "tbr", 0x180c0000, 0xfc0c0000, "r,f", 2 },
+{ "tbrr", 0x2c020000, 0xfc0f0000, "r,B", 2 },
+{ "tccr", 0x28040000, 0xfc7f0000, "", 2 },
+{ "td", 0xfc050000, 0xfc070000, "r,f", 4 },
+{ "tio", 0xfc1f0000, 0xfc7f8000, "r,I", 4 },
+{ "tmapr", 0x2c0a0000, 0xfc0f0000, "r,R", 2 },
+{ "tpcbr", 0x280c0000, 0xfc7f0000, "r", 2 },
+{ "trbr", 0x2c010000, 0xfc0f0000, "b,R", 2 },
+{ "trc", 0x2c030000, 0xfc0f0000, "r,R", 2 },
+{ "trcc", 0x28050000, 0xfc7f0000, "", 2 },
+{ "trcm", 0x2c0b0000, 0xfc0f0000, "r,R", 2 },
+{ "trn", 0x2c040000, 0xfc0f0000, "r,R", 2 },
+{ "trnm", 0x2c0c0000, 0xfc0f0000, "r,R", 2 },
+{ "trr", 0x2c000000, 0xfc0f0000, "r,R", 2 },
+{ "trrm", 0x2c080000, 0xfc0f0000, "r,R", 2 },
+{ "trsc", 0x2c0e0000, 0xfc0f0000, "r,R", 2 },
+{ "trsw", 0x28000000, 0xfc7f0000, "r", 2 },
+{ "tscr", 0x2c0f0000, 0xfc0f0000, "r,R", 2 },
+{ "uei", 0x00070000, 0xffff0000, "", 2 },
+{ "wait", 0x00010000, 0xffff0000, "", 2 },
+{ "wcwcs", 0xfc5f0000, 0xfc7f8000, "", 4 },
+{ "wwcs", 0x000c0000, 0xfc0f0000, "r,R", 2 },
+{ "xcbr", 0x28020000, 0xfc0f0000, "b,B", 2 },
+{ "xcr", 0x2c050000, 0xfc0f0000, "r,R", 2 },
+{ "xcrm", 0x2c0d0000, 0xfc0f0000, "r,R", 2 },
+{ "zbm", 0x9c080000, 0xfc080000, "f,xOA,X", 4 },
+{ "zbr", 0x18040000, 0xfc0c0000, "r,f", 2 },
+{ "zmb", 0xf8080000, 0xfc080000, "r,xOA,X", 4 },
+{ "zmd", 0xf8000002, 0xfc080002, "r,xOA,X", 4 },
+{ "zmh", 0xf8000001, 0xfc080001, "r,xOA,X", 4 },
+{ "zmw", 0xf8000000, 0xfc080000, "r,xOA,X", 4 },
+{ "zr", 0x0c000000, 0xfc0f0000, "r", 2 },
+};
+
+int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
+
+struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
+ sizeof(gld_opcodes[0]);
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
new file mode 100644
index 00000000000..a9e3b24ab30
--- /dev/null
+++ b/include/opcode/ppc.h
@@ -0,0 +1,248 @@
+/* ppc.h -- Header file for PowerPC opcode table
+ Copyright 1994, 1995 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef PPC_H
+#define PPC_H
+
+/* The opcode table is an array of struct powerpc_opcode. */
+
+struct powerpc_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* The opcode itself. Those bits which will be filled in with
+ operands are zeroes. */
+ unsigned long opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a
+ mask containing ones indicating those bits which must match the
+ opcode field, and zeroes indicating those bits which need not
+ match (and are presumably filled in by operands). */
+ unsigned long mask;
+
+ /* One bit flags for the opcode. These are used to indicate which
+ specific processors support the instructions. The defined values
+ are listed below. */
+ unsigned long flags;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ unsigned char operands[8];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+ in the order in which the disassembler should consider
+ instructions. */
+extern const struct powerpc_opcode powerpc_opcodes[];
+extern const int powerpc_num_opcodes;
+
+/* Values defined for the flags field of a struct powerpc_opcode. */
+
+/* Opcode is defined for the PowerPC architecture. */
+#define PPC_OPCODE_PPC (01)
+
+/* Opcode is defined for the POWER (RS/6000) architecture. */
+#define PPC_OPCODE_POWER (02)
+
+/* Opcode is defined for the POWER2 (Rios 2) architecture. */
+#define PPC_OPCODE_POWER2 (04)
+
+/* Opcode is only defined on 32 bit architectures. */
+#define PPC_OPCODE_32 (010)
+
+/* Opcode is only defined on 64 bit architectures. */
+#define PPC_OPCODE_64 (020)
+
+/* Opcode is supported by the Motorola PowerPC 601 processor. The 601
+ is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
+ but it also supports many additional POWER instructions. */
+#define PPC_OPCODE_601 (040)
+
+/* Opcode is supported in both the Power and PowerPC architectures
+ (ie, compiler's -mcpu=common or assembler's -mcom). */
+#define PPC_OPCODE_COMMON (0100)
+
+/* Opcode is supported for any Power or PowerPC platform (this is
+ for the assembler's -many option, and it eliminates duplicates). */
+#define PPC_OPCODE_ANY (0200)
+
+/* A macro to extract the major opcode from an instruction. */
+#define PPC_OP(i) (((i) >> 26) & 0x3f)
+
+/* The operands table is an array of struct powerpc_operand. */
+
+struct powerpc_operand
+{
+ /* The number of bits in the operand. */
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+ int shift;
+
+ /* Insertion function. This is used by the assembler. To insert an
+ operand value into an instruction, check this field.
+
+ If it is NULL, execute
+ i |= (op & ((1 << o->bits) - 1)) << o->shift;
+ (i is the instruction which we are filling in, o is a pointer to
+ this structure, and op is the opcode value; this assumes twos
+ complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction and the operand value. It will return the new value
+ of the instruction. If the ERRMSG argument is not NULL, then if
+ the operand value is illegal, *ERRMSG will be set to a warning
+ string (the operand will be inserted in any case). If the
+ operand value is legal, *ERRMSG will be unchanged (most operands
+ can accept any value). */
+ unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
+ const char **errmsg));
+
+ /* Extraction function. This is used by the disassembler. To
+ extract this operand type from an instruction, check this field.
+
+ If it is NULL, compute
+ op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+ if ((o->flags & PPC_OPERAND_SIGNED) != 0
+ && (op & (1 << (o->bits - 1))) != 0)
+ op -= 1 << o->bits;
+ (i is the instruction, o is a pointer to this structure, and op
+ is the result; this assumes twos complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction value. It will return the value of the operand. If
+ the INVALID argument is not NULL, *INVALID will be set to
+ non-zero if this operand type can not actually be extracted from
+ this operand (i.e., the instruction does not match). If the
+ operand is valid, *INVALID will not be changed. */
+ long (*extract) PARAMS ((unsigned long instruction, int *invalid));
+
+ /* One bit syntax flags. */
+ unsigned long flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the powerpc_opcodes table. */
+
+extern const struct powerpc_operand powerpc_operands[];
+
+/* Values defined for the flags field of a struct powerpc_operand. */
+
+/* This operand takes signed values. */
+#define PPC_OPERAND_SIGNED (01)
+
+/* This operand takes signed values, but also accepts a full positive
+ range of values when running in 32 bit mode. That is, if bits is
+ 16, it takes any value from -0x8000 to 0xffff. In 64 bit mode,
+ this flag is ignored. */
+#define PPC_OPERAND_SIGNOPT (02)
+
+/* This operand does not actually exist in the assembler input. This
+ is used to support extended mnemonics such as mr, for which two
+ operands fields are identical. The assembler should call the
+ insert function with any op value. The disassembler should call
+ the extract function, ignore the return value, and check the value
+ placed in the valid argument. */
+#define PPC_OPERAND_FAKE (04)
+
+/* The next operand should be wrapped in parentheses rather than
+ separated from this one by a comma. This is used for the load and
+ store instructions which want their operands to look like
+ reg,displacement(reg)
+ */
+#define PPC_OPERAND_PARENS (010)
+
+/* This operand may use the symbolic names for the CR fields, which
+ are
+ lt 0 gt 1 eq 2 so 3 un 3
+ cr0 0 cr1 1 cr2 2 cr3 3
+ cr4 4 cr5 5 cr6 6 cr7 7
+ These may be combined arithmetically, as in cr2*4+gt. These are
+ only supported on the PowerPC, not the POWER. */
+#define PPC_OPERAND_CR (020)
+
+/* This operand names a register. The disassembler uses this to print
+ register names with a leading 'r'. */
+#define PPC_OPERAND_GPR (040)
+
+/* This operand names a floating point register. The disassembler
+ prints these with a leading 'f'. */
+#define PPC_OPERAND_FPR (0100)
+
+/* This operand is a relative branch displacement. The disassembler
+ prints these symbolically if possible. */
+#define PPC_OPERAND_RELATIVE (0200)
+
+/* This operand is an absolute branch address. The disassembler
+ prints these symbolically if possible. */
+#define PPC_OPERAND_ABSOLUTE (0400)
+
+/* This operand is optional, and is zero if omitted. This is used for
+ the optional BF and L fields in the comparison instructions. The
+ assembler must count the number of operands remaining on the line,
+ and the number of operands remaining for the opcode, and decide
+ whether this operand is present or not. The disassembler should
+ print this operand out only if it is not zero. */
+#define PPC_OPERAND_OPTIONAL (01000)
+
+/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
+ is omitted, then for the next operand use this operand value plus
+ 1, ignoring the next operand field for the opcode. This wretched
+ hack is needed because the Power rotate instructions can take
+ either 4 or 5 operands. The disassembler should print this operand
+ out regardless of the PPC_OPERAND_OPTIONAL field. */
+#define PPC_OPERAND_NEXT (02000)
+
+/* This operand should be regarded as a negative number for the
+ purposes of overflow checking (i.e., the normal most negative
+ number is disallowed and one more than the normal most positive
+ number is allowed). This flag will only be set for a signed
+ operand. */
+#define PPC_OPERAND_NEGATIVE (04000)
+
+/* The POWER and PowerPC assemblers use a few macros. We keep them
+ with the operands table for simplicity. The macro table is an
+ array of struct powerpc_macro. */
+
+struct powerpc_macro
+{
+ /* The macro name. */
+ const char *name;
+
+ /* The number of operands the macro takes. */
+ unsigned int operands;
+
+ /* One bit flags for the opcode. These are used to indicate which
+ specific processors support the instructions. The values are the
+ same as those for the struct powerpc_opcode flags field. */
+ unsigned long flags;
+
+ /* A format string to turn the macro into a normal instruction.
+ Each %N in the string is replaced with operand number N (zero
+ based). */
+ const char *format;
+};
+
+extern const struct powerpc_macro powerpc_macros[];
+extern const int powerpc_num_macros;
+
+#endif /* PPC_H */
diff --git a/include/opcode/pyr.h b/include/opcode/pyr.h
new file mode 100644
index 00000000000..06632b8d919
--- /dev/null
+++ b/include/opcode/pyr.h
@@ -0,0 +1,287 @@
+/* pyramid.opcode.h -- gdb initial attempt. */
+
+/* pyramid opcode table: wot to do with this
+ particular opcode */
+
+struct pyr_datum
+{
+ char nargs;
+ char * args; /* how to compile said opcode */
+ unsigned long mask; /* Bit vector: which operand modes are valid
+ for this opcode */
+ unsigned char code; /* op-code (always 6(?) bits */
+};
+
+typedef struct pyr_insn_format {
+ unsigned int mode :4;
+ unsigned int operator :8;
+ unsigned int index_scale :2;
+ unsigned int index_reg :6;
+ unsigned int operand_1 :6;
+ unsigned int operand_2:6;
+} pyr_insn_format;
+
+
+/* We store four bytes of opcode for all opcodes.
+ Pyramid is sufficiently RISCy that:
+ - insns are always an integral number of words;
+ - the length of any insn can be told from the first word of
+ the insn. (ie, if there are zero, one, or two words of
+ immediate operand/offset).
+
+
+ The args component is a string containing two characters for each
+ operand of the instruction. The first specifies the kind of operand;
+ the second, the place it is stored. */
+
+/* Kinds of operands:
+ mask assembler syntax description
+ 0x0001: movw Rn,Rn register to register
+ 0x0002: movw K,Rn quick immediate to register
+ 0x0004: movw I,Rn long immediate to register
+ 0x0008: movw (Rn),Rn register indirect to register
+ movw (Rn)[x],Rn register indirect to register
+ 0x0010: movw I(Rn),Rn offset register indirect to register
+ movw I(Rn)[x],Rn offset register indirect, indexed, to register
+
+ 0x0020: movw Rn,(Rn) register to register indirect
+ 0x0040: movw K,(Rn) quick immediate to register indirect
+ 0x0080: movw I,(Rn) long immediate to register indirect
+ 0x0100: movw (Rn),(Rn) register indirect to-register indirect
+ 0x0100: movw (Rn),(Rn) register indirect to-register indirect
+ 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect
+ 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect
+
+ 0x0400: movw Rn,I(Rn) register to register indirect+offset
+ 0x0800: movw K,I(Rn) quick immediate to register indirect+offset
+ 0x1000: movw I,I(Rn) long immediate to register indirect+offset
+ 0x1000: movw (Rn),I(Rn) register indirect to-register indirect+offset
+ 0x1000: movw I(Rn),I(Rn) register indirect+offset to register indirect
+ +offset
+ 0x0000: (irregular) ???
+
+
+ Each insn has a four-bit field encoding the type(s) of its operands.
+*/
+
+/* Some common combinations
+ */
+
+/* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/
+#define GEN_TO_REG (31)
+
+#define UNKNOWN ((unsigned long)-1)
+#define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15))
+
+#define CONVERT (1|8|0x10|0x20|0x200)
+
+#define K_TO_REG (2)
+#define I_TO_REG (4)
+#define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG)
+#define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG)
+
+/* The assembler requires that this array be sorted as follows:
+ all instances of the same mnemonic must be consecutive.
+ All instances of the same mnemonic with the same number of operands
+ must be consecutive.
+ */
+
+struct pyr_opcode /* pyr opcode text */
+{
+ char * name; /* opcode name: lowercase string [key] */
+ struct pyr_datum datum; /* rest of opcode table [datum] */
+};
+
+#define pyr_how args
+#define pyr_nargs nargs
+#define pyr_mask mask
+#define pyr_name name
+
+struct pyr_opcode pyr_opcodes[] =
+{
+ {"movb", { 2, "", UNKNOWN, 0x11}, },
+ {"movh", { 2, "", UNKNOWN, 0x12} },
+ {"movw", { 2, "", ANY, 0x10} },
+ {"movl", { 2, "", ANY, 0x13} },
+ {"mnegw", { 2, "", (0x1|0x8|0x10), 0x14} },
+ {"mnegf", { 2, "", 0x1, 0x15} },
+ {"mnegd", { 2, "", 0x1, 0x16} },
+ {"mcomw", { 2, "", (0x1|0x8|0x10), 0x17} },
+ {"mabsw", { 2, "", (0x1|0x8|0x10), 0x18} },
+ {"mabsf", { 2, "", 0x1, 0x19} },
+ {"mabsd", { 2, "", 0x1, 0x1a} },
+ {"mtstw", { 2, "", (0x1|0x8|0x10), 0x1c} },
+ {"mtstf", { 2, "", 0x1, 0x1d} },
+ {"mtstd", { 2, "", 0x1, 0x1e} },
+ {"mova", { 2, "", 0x8|0x10, 0x1f} },
+ {"movzbw", { 2, "", (0x1|0x8|0x10), 0x20} },
+ {"movzhw", { 2, "", (0x1|0x8|0x10), 0x21} },
+ /* 2 insns out of order here */
+ {"movbl", { 2, "", 1, 0x4f} },
+ {"filbl", { 2, "", 1, 0x4e} },
+
+ {"cvtbw", { 2, "", CONVERT, 0x22} },
+ {"cvthw", { 2, "", CONVERT, 0x23} },
+ {"cvtwb", { 2, "", CONVERT, 0x24} },
+ {"cvtwh", { 2, "", CONVERT, 0x25} },
+ {"cvtwf", { 2, "", CONVERT, 0x26} },
+ {"cvtwd", { 2, "", CONVERT, 0x27} },
+ {"cvtfw", { 2, "", CONVERT, 0x28} },
+ {"cvtfd", { 2, "", CONVERT, 0x29} },
+ {"cvtdw", { 2, "", CONVERT, 0x2a} },
+ {"cvtdf", { 2, "", CONVERT, 0x2b} },
+
+ {"addw", { 2, "", GEN_TO_REG, 0x40} },
+ {"addwc", { 2, "", GEN_TO_REG, 0x41} },
+ {"subw", { 2, "", GEN_TO_REG, 0x42} },
+ {"subwb", { 2, "", GEN_TO_REG, 0x43} },
+ {"rsubw", { 2, "", GEN_TO_REG, 0x44} },
+ {"mulw", { 2, "", GEN_TO_REG, 0x45} },
+ {"emul", { 2, "", GEN_TO_REG, 0x47} },
+ {"umulw", { 2, "", GEN_TO_REG, 0x46} },
+ {"divw", { 2, "", GEN_TO_REG, 0x48} },
+ {"ediv", { 2, "", GEN_TO_REG, 0x4a} },
+ {"rdivw", { 2, "", GEN_TO_REG, 0x4b} },
+ {"udivw", { 2, "", GEN_TO_REG, 0x49} },
+ {"modw", { 2, "", GEN_TO_REG, 0x4c} },
+ {"umodw", { 2, "", GEN_TO_REG, 0x4d} },
+
+
+ {"addf", { 2, "", 1, 0x50} },
+ {"addd", { 2, "", 1, 0x51} },
+ {"subf", { 2, "", 1, 0x52} },
+ {"subd", { 2, "", 1, 0x53} },
+ {"mulf", { 2, "", 1, 0x56} },
+ {"muld", { 2, "", 1, 0x57} },
+ {"divf", { 2, "", 1, 0x58} },
+ {"divd", { 2, "", 1, 0x59} },
+
+
+ {"cmpb", { 2, "", UNKNOWN, 0x61} },
+ {"cmph", { 2, "", UNKNOWN, 0x62} },
+ {"cmpw", { 2, "", UNKNOWN, 0x60} },
+ {"ucmpb", { 2, "", UNKNOWN, 0x66} },
+ /* WHY no "ucmph"??? */
+ {"ucmpw", { 2, "", UNKNOWN, 0x65} },
+ {"xchw", { 2, "", UNKNOWN, 0x0f} },
+
+
+ {"andw", { 2, "", GEN_TO_REG, 0x30} },
+ {"orw", { 2, "", GEN_TO_REG, 0x31} },
+ {"xorw", { 2, "", GEN_TO_REG, 0x32} },
+ {"bicw", { 2, "", GEN_TO_REG, 0x33} },
+ {"lshlw", { 2, "", GEN_TO_REG, 0x38} },
+ {"ashlw", { 2, "", GEN_TO_REG, 0x3a} },
+ {"ashll", { 2, "", GEN_TO_REG, 0x3c} },
+ {"ashrw", { 2, "", GEN_TO_REG, 0x3b} },
+ {"ashrl", { 2, "", GEN_TO_REG, 0x3d} },
+ {"rotlw", { 2, "", GEN_TO_REG, 0x3e} },
+ {"rotrw", { 2, "", GEN_TO_REG, 0x3f} },
+
+ /* push and pop insns are "going away next release". */
+ {"pushw", { 2, "", GEN_TO_REG, 0x0c} },
+ {"popw", { 2, "", (0x1|0x8|0x10), 0x0d} },
+ {"pusha", { 2, "", (0x8|0x10), 0x0e} },
+
+ {"bitsw", { 2, "", UNKNOWN, 0x35} },
+ {"bitcw", { 2, "", UNKNOWN, 0x36} },
+ /* some kind of ibra/dbra insns??*/
+ {"icmpw", { 2, "", UNKNOWN, 0x67} },
+ {"dcmpw", { 2, "", (1|4|0x20|0x80|0x400|0x1000), 0x69} },/*FIXME*/
+ {"acmpw", { 2, "", 1, 0x6b} },
+
+ /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op
+ insn with a 2nd op of tr14. The assembler will have to grok this. */
+ {"call", { 2, "", GEN_TO_REG, 0x04} },
+ {"call", { 1, "", GEN_TO_REG, 0x04} },
+
+ {"callk", { 1, "", UNKNOWN, 0x06} },/* system call?*/
+ /* Ret is usually written as a 0-op insn, but gets disassembled as a
+ 1-op insn. The operand is always tr15. */
+ {"ret", { 0, "", UNKNOWN, 0x09} },
+ {"ret", { 1, "", UNKNOWN, 0x09} },
+ {"adsf", { 2, "", (1|2|4), 0x08} },
+ {"retd", { 2, "", UNKNOWN, 0x0a} },
+ {"btc", { 2, "", UNKNOWN, 0x01} },
+ {"bfc", { 2, "", UNKNOWN, 0x02} },
+ /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */
+ {"jump", { 1, "", UNKNOWN, 0x00} },
+ {"btp", { 2, "", UNKNOWN, 0xf00} },
+ /* read control-stack pointer is another 1-or-2 operand insn. */
+ {"rcsp", { 2, "", UNKNOWN, 0x01f} },
+ {"rcsp", { 1, "", UNKNOWN, 0x01f} }
+};
+
+/* end: pyramid.opcode.h */
+/* One day I will have to take the time to find out what operands
+ are valid for these insns, and guess at what they mean.
+
+ I can't imagine what the "I???" insns (iglob, etc) do.
+
+ the arithmetic-sounding insns ending in "p" sound awfully like BCD
+ arithmetic insns:
+ dshlp -> Decimal SHift Left Packed
+ dshrp -> Decimal SHift Right Packed
+ and cvtlp would be convert long to packed.
+ I have no idea how the operands are interpreted; but having them be
+ a long register with (address, length) of an in-memory packed BCD operand
+ would not be surprising.
+ They are unlikely to be a packed bcd string: 64 bits of long give
+ is only 15 digits+sign, which isn't enough for COBOL.
+ */
+#if 0
+ {"wcsp", { 2, "", UNKNOWN, 0x00} }, /*write csp?*/
+ /* The OSx Operating System Porting Guide claims SSL does things
+ with tr12 (a register reserved to it) to do with static block-structure
+ references. SSL=Set Static Link? It's "Going away next release". */
+ {"ssl", { 2, "", UNKNOWN, 0x00} },
+ {"ccmps", { 2, "", UNKNOWN, 0x00} },
+ {"lcd", { 2, "", UNKNOWN, 0x00} },
+ {"uemul", { 2, "", UNKNOWN, 0x00} }, /*unsigned emul*/
+ {"srf", { 2, "", UNKNOWN, 0x00} }, /*Gidget time???*/
+ {"mnegp", { 2, "", UNKNOWN, 0x00} }, /move-neg phys?*/
+ {"ldp", { 2, "", UNKNOWN, 0x00} }, /*load phys?*/
+ {"ldti", { 2, "", UNKNOWN, 0x00} },
+ {"ldb", { 2, "", UNKNOWN, 0x00} },
+ {"stp", { 2, "", UNKNOWN, 0x00} },
+ {"stti", { 2, "", UNKNOWN, 0x00} },
+ {"stb", { 2, "", UNKNOWN, 0x00} },
+ {"stu", { 2, "", UNKNOWN, 0x00} },
+ {"addp", { 2, "", UNKNOWN, 0x00} },
+ {"subp", { 2, "", UNKNOWN, 0x00} },
+ {"mulp", { 2, "", UNKNOWN, 0x00} },
+ {"divp", { 2, "", UNKNOWN, 0x00} },
+ {"dshlp", { 2, "", UNKNOWN, 0x00} }, /* dec shl packed? */
+ {"dshrp", { 2, "", UNKNOWN, 0x00} }, /* dec shr packed? */
+ {"movs", { 2, "", UNKNOWN, 0x00} }, /*move (string?)?*/
+ {"cmpp", { 2, "", UNKNOWN, 0x00} }, /* cmp phys?*/
+ {"cmps", { 2, "", UNKNOWN, 0x00} }, /* cmp (string?)?*/
+ {"cvtlp", { 2, "", UNKNOWN, 0x00} }, /* cvt long to p??*/
+ {"cvtpl", { 2, "", UNKNOWN, 0x00} }, /* cvt p to l??*/
+ {"dintr", { 2, "", UNKNOWN, 0x00} }, /* ?? intr ?*/
+ {"rphysw", { 2, "", UNKNOWN, 0x00} }, /* read phys word?*/
+ {"wphysw", { 2, "", UNKNOWN, 0x00} }, /* write phys word?*/
+ {"cmovs", { 2, "", UNKNOWN, 0x00} },
+ {"rsubw", { 2, "", UNKNOWN, 0x00} },
+ {"bicpsw", { 2, "", UNKNOWN, 0x00} }, /* clr bit in psw? */
+ {"bispsw", { 2, "", UNKNOWN, 0x00} }, /* set bit in psw? */
+ {"eio", { 2, "", UNKNOWN, 0x00} }, /* ?? ?io ? */
+ {"callp", { 2, "", UNKNOWN, 0x00} }, /* call phys?*/
+ {"callr", { 2, "", UNKNOWN, 0x00} },
+ {"lpcxt", { 2, "", UNKNOWN, 0x00} }, /*load proc context*/
+ {"rei", { 2, "", UNKNOWN, 0x00} }, /*ret from intrpt*/
+ {"rport", { 2, "", UNKNOWN, 0x00} }, /*read-port?*/
+ {"rtod", { 2, "", UNKNOWN, 0x00} }, /*read-time-of-day?*/
+ {"ssi", { 2, "", UNKNOWN, 0x00} },
+ {"vtpa", { 2, "", UNKNOWN, 0x00} }, /*virt-to-phys-addr?*/
+ {"wicl", { 2, "", UNKNOWN, 0x00} }, /* write icl ? */
+ {"wport", { 2, "", UNKNOWN, 0x00} }, /*write-port?*/
+ {"wtod", { 2, "", UNKNOWN, 0x00} }, /*write-time-of-day?*/
+ {"flic", { 2, "", UNKNOWN, 0x00} },
+ {"iglob", { 2, "", UNKNOWN, 0x00} }, /* I global? */
+ {"iphys", { 2, "", UNKNOWN, 0x00} }, /* I physical? */
+ {"ipid", { 2, "", UNKNOWN, 0x00} }, /* I pid? */
+ {"ivect", { 2, "", UNKNOWN, 0x00} }, /* I vector? */
+ {"lamst", { 2, "", UNKNOWN, 0x00} },
+ {"tio", { 2, "", UNKNOWN, 0x00} },
+#endif
diff --git a/include/opcode/sparc.h b/include/opcode/sparc.h
new file mode 100644
index 00000000000..4f159bd896f
--- /dev/null
+++ b/include/opcode/sparc.h
@@ -0,0 +1,240 @@
+/* Definitions for opcode table for the sparc.
+ Copyright (C) 1989, 91, 92, 93, 94, 95, 96, 1997
+ Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and
+the GNU Binutils.
+
+GAS/GDB 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, or (at your option)
+any later version.
+
+GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <ansidecl.h>
+
+/* The SPARC opcode table (and other related data) is defined in
+ the opcodes library in sparc-opc.c. If you change anything here, make
+ sure you fix up that file, and vice versa. */
+
+ /* FIXME-someday: perhaps the ,a's and such should be embedded in the
+ instruction's name rather than the args. This would make gas faster, pinsn
+ slower, but would mess up some macros a bit. xoxorich. */
+
+/* List of instruction sets variations.
+ These values are such that each element is either a superset of a
+ preceding each one or they conflict in which case SPARC_OPCODE_CONFLICT_P
+ returns non-zero.
+ The values are indices into `sparc_opcode_archs' defined in sparc-opc.c.
+ Don't change this without updating sparc-opc.c. */
+
+enum sparc_opcode_arch_val {
+ SPARC_OPCODE_ARCH_V6 = 0,
+ SPARC_OPCODE_ARCH_V7,
+ SPARC_OPCODE_ARCH_V8,
+ SPARC_OPCODE_ARCH_SPARCLET,
+ SPARC_OPCODE_ARCH_SPARCLITE,
+ /* v9 variants must appear last */
+ SPARC_OPCODE_ARCH_V9,
+ SPARC_OPCODE_ARCH_V9A, /* v9 with ultrasparc additions */
+ SPARC_OPCODE_ARCH_BAD /* error return from sparc_opcode_lookup_arch */
+};
+
+/* The highest architecture in the table. */
+#define SPARC_OPCODE_ARCH_MAX (SPARC_OPCODE_ARCH_BAD - 1)
+
+/* Given an enum sparc_opcode_arch_val, return the bitmask to use in
+ insn encoding/decoding. */
+#define SPARC_OPCODE_ARCH_MASK(arch) (1 << (arch))
+
+/* Given a valid sparc_opcode_arch_val, return non-zero if it's v9. */
+#define SPARC_OPCODE_ARCH_V9_P(arch) ((arch) >= SPARC_OPCODE_ARCH_V9)
+
+/* Table of cpu variants. */
+
+struct sparc_opcode_arch {
+ const char *name;
+ /* Mask of sparc_opcode_arch_val's supported.
+ EG: For v7 this would be
+ (SPARC_OPCODE_ARCH_MASK (..._V6) | SPARC_OPCODE_ARCH_MASK (..._V7)).
+ These are short's because sparc_opcode.architecture is. */
+ short supported;
+};
+
+extern const struct sparc_opcode_arch sparc_opcode_archs[];
+
+/* Given architecture name, look up it's sparc_opcode_arch_val value. */
+extern enum sparc_opcode_arch_val sparc_opcode_lookup_arch
+ PARAMS ((const char *));
+
+/* Return the bitmask of supported architectures for ARCH. */
+#define SPARC_OPCODE_SUPPORTED(ARCH) (sparc_opcode_archs[ARCH].supported)
+
+/* Non-zero if ARCH1 conflicts with ARCH2.
+ IE: ARCH1 as a supported bit set that ARCH2 doesn't, and vice versa. */
+#define SPARC_OPCODE_CONFLICT_P(ARCH1, ARCH2) \
+(((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \
+ != SPARC_OPCODE_SUPPORTED (ARCH1)) \
+ && ((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \
+ != SPARC_OPCODE_SUPPORTED (ARCH2)))
+
+/* Structure of an opcode table entry. */
+
+struct sparc_opcode {
+ const char *name;
+ unsigned long match; /* Bits that must be set. */
+ unsigned long lose; /* Bits that must not be set. */
+ const char *args;
+ /* This was called "delayed" in versions before the flags. */
+ char flags;
+ short architecture; /* Bitmask of sparc_opcode_arch_val's. */
+};
+
+#define F_DELAYED 1 /* Delayed branch */
+#define F_ALIAS 2 /* Alias for a "real" instruction */
+#define F_UNBR 4 /* Unconditional branch */
+#define F_CONDBR 8 /* Conditional branch */
+#define F_JSR 16 /* Subroutine call */
+#define F_FLOAT 32 /* Floating point instruction (not a branch) */
+#define F_FBR 64 /* Floating point branch */
+/* FIXME: Add F_ANACHRONISTIC flag for v9. */
+
+/*
+
+All sparc opcodes are 32 bits, except for the `set' instruction (really a
+macro), which is 64 bits. It is handled as a special case.
+
+The match component is a mask saying which bits must match a particular
+opcode in order for an instruction to be an instance of that opcode.
+
+The args component is a string containing one character for each operand of the
+instruction.
+
+Kinds of operands:
+ # Number used by optimizer. It is ignored.
+ 1 rs1 register.
+ 2 rs2 register.
+ d rd register.
+ e frs1 floating point register.
+ v frs1 floating point register (double/even).
+ V frs1 floating point register (quad/multiple of 4).
+ f frs2 floating point register.
+ B frs2 floating point register (double/even).
+ R frs2 floating point register (quad/multiple of 4).
+ g frsd floating point register.
+ H frsd floating point register (double/even).
+ J frsd floating point register (quad/multiple of 4).
+ b crs1 coprocessor register
+ c crs2 coprocessor register
+ D crsd coprocessor register
+ m alternate space register (asr) in rd
+ M alternate space register (asr) in rs1
+ h 22 high bits.
+ X 5 bit unsigned immediate
+ Y 6 bit unsigned immediate
+ K MEMBAR mask (7 bits). (v9)
+ j 10 bit Immediate. (v9)
+ I 11 bit Immediate. (v9)
+ i 13 bit Immediate.
+ n 22 bit immediate.
+ k 2+14 bit PC relative immediate. (v9)
+ G 19 bit PC relative immediate. (v9)
+ l 22 bit PC relative immediate.
+ L 30 bit PC relative immediate.
+ a Annul. The annul bit is set.
+ A Alternate address space. Stored as 8 bits.
+ C Coprocessor state register.
+ F floating point state register.
+ p Processor state register.
+ N Branch predict clear ",pn" (v9)
+ T Branch predict set ",pt" (v9)
+ z %icc. (v9)
+ Z %xcc. (v9)
+ q Floating point queue.
+ r Single register that is both rs1 and rd.
+ O Single register that is both rs2 and rd.
+ Q Coprocessor queue.
+ S Special case.
+ t Trap base register.
+ w Window invalid mask register.
+ y Y register.
+ u sparclet coprocessor registers in rd position
+ U sparclet coprocessor registers in rs1 position
+ E %ccr. (v9)
+ s %fprs. (v9)
+ P %pc. (v9)
+ W %tick. (v9)
+ o %asi. (v9)
+ 6 %fcc0. (v9)
+ 7 %fcc1. (v9)
+ 8 %fcc2. (v9)
+ 9 %fcc3. (v9)
+ ! Privileged Register in rd (v9)
+ ? Privileged Register in rs1 (v9)
+ * Prefetch function constant. (v9)
+ x OPF field (v9 impdep).
+ 0 32/64 bit immediate for set or setx (v9) insns
+ _ Ancillary state register in rd (v9a)
+ / Ancillary state register in rs1 (v9a)
+
+The following chars are unused: (note: ,[] are used as punctuation)
+[345]
+
+*/
+
+#define OP2(x) (((x)&0x7) << 22) /* op2 field of format2 insns */
+#define OP3(x) (((x)&0x3f) << 19) /* op3 field of format3 insns */
+#define OP(x) ((unsigned)((x)&0x3) << 30) /* op field of all insns */
+#define OPF(x) (((x)&0x1ff) << 5) /* opf field of float insns */
+#define OPF_LOW5(x) OPF((x)&0x1f) /* v9 */
+#define F3F(x, y, z) (OP(x) | OP3(y) | OPF(z)) /* format3 float insns */
+#define F3I(x) (((x)&0x1) << 13) /* immediate field of format 3 insns */
+#define F2(x, y) (OP(x) | OP2(y)) /* format 2 insns */
+#define F3(x, y, z) (OP(x) | OP3(y) | F3I(z)) /* format3 insns */
+#define F1(x) (OP(x))
+#define DISP30(x) ((x)&0x3fffffff)
+#define ASI(x) (((x)&0xff) << 5) /* asi field of format3 insns */
+#define RS2(x) ((x)&0x1f) /* rs2 field */
+#define SIMM13(x) ((x)&0x1fff) /* simm13 field */
+#define RD(x) (((x)&0x1f) << 25) /* destination register field */
+#define RS1(x) (((x)&0x1f) << 14) /* rs1 field */
+#define ASI_RS2(x) (SIMM13(x))
+#define MEMBAR(x) ((x)&0x7f)
+#define SLCPOP(x) (((x)&0x7f) << 6) /* sparclet cpop */
+
+#define ANNUL (1<<29)
+#define BPRED (1<<19) /* v9 */
+#define IMMED F3I(1)
+#define RD_G0 RD(~0)
+#define RS1_G0 RS1(~0)
+#define RS2_G0 RS2(~0)
+
+extern const struct sparc_opcode sparc_opcodes[];
+extern const int sparc_num_opcodes;
+
+extern int sparc_encode_asi PARAMS ((const char *));
+extern const char *sparc_decode_asi PARAMS ((int));
+extern int sparc_encode_membar PARAMS ((const char *));
+extern const char *sparc_decode_membar PARAMS ((int));
+extern int sparc_encode_prefetch PARAMS ((const char *));
+extern const char *sparc_decode_prefetch PARAMS ((int));
+extern int sparc_encode_sparclet_cpreg PARAMS ((const char *));
+extern const char *sparc_decode_sparclet_cpreg PARAMS ((int));
+
+/*
+ * Local Variables:
+ * fill-column: 131
+ * comment-column: 0
+ * End:
+ */
+
+/* end of sparc.h */
diff --git a/include/opcode/tahoe.h b/include/opcode/tahoe.h
new file mode 100644
index 00000000000..b5cee249ee4
--- /dev/null
+++ b/include/opcode/tahoe.h
@@ -0,0 +1,213 @@
+/*
+ * Ported by the State University of New York at Buffalo by the Distributed
+ * Computer Systems Lab, Department of Computer Science, 1991.
+ */
+
+#ifndef tahoe_opcodeT
+#define tahoe_opcodeT int
+#endif /* no tahoe_opcodeT */
+
+struct vot_wot /* tahoe opcode table: wot to do with this */
+ /* particular opcode */
+{
+ char * args; /* how to compile said opcode */
+ tahoe_opcodeT code; /* op-code (may be > 8 bits!) */
+};
+
+struct vot /* tahoe opcode text */
+{
+ char * name; /* opcode name: lowercase string [key] */
+ struct vot_wot detail; /* rest of opcode table [datum] */
+};
+
+#define vot_how args
+#define vot_code code
+#define vot_detail detail
+#define vot_name name
+
+static struct vot
+votstrs[] =
+{
+{ "halt", {"", 0x00 } },
+{ "sinf", {"", 0x05 } },
+{ "ldf", {"rl", 0x06 } },
+{ "ldd", {"rq", 0x07 } },
+{ "addb2", {"rbmb", 0x08 } },
+{ "movb", {"rbwb", 0x09 } },
+{ "addw2", {"rwmw", 0x0a } },
+{ "movw", {"rwww", 0x0b } },
+{ "addl2", {"rlml", 0x0c } },
+{ "movl", {"rlwl", 0x0d } },
+{ "bbs", {"rlvlbw", 0x0e } },
+{ "nop", {"", 0x10 } },
+{ "brb", {"bb", 0x11 } },
+{ "brw", {"bw", 0x13 } },
+{ "cosf", {"", 0x15 } },
+{ "lnf", {"rl", 0x16 } },
+{ "lnd", {"rq", 0x17 } },
+{ "addb3", {"rbrbwb", 0x18 } },
+{ "cmpb", {"rbwb", 0x19 } },
+{ "addw3", {"rwrwww", 0x1a } },
+{ "cmpw", {"rwww", 0x1b } },
+{ "addl3", {"rlrlwl", 0x1c } },
+{ "cmpl", {"rlwl", 0x1d } },
+{ "bbc", {"rlvlbw", 0x1e } },
+{ "rei", {"", 0x20 } },
+{ "bneq", {"bb", 0x21 } },
+{ "bnequ", {"bb", 0x21 } },
+{ "cvtwl", {"rwwl", 0x23 } },
+{ "stf", {"wl", 0x26 } },
+{ "std", {"wq", 0x27 } },
+{ "subb2", {"rbmb", 0x28 } },
+{ "mcomb", {"rbwb", 0x29 } },
+{ "subw2", {"rwmw", 0x2a } },
+{ "mcomw", {"rwww", 0x2b } },
+{ "subl2", {"rlml", 0x2c } },
+{ "mcoml", {"rlwl", 0x2d } },
+{ "emul", {"rlrlrlwq", 0x2e } },
+{ "aoblss", {"rlmlbw", 0x2f } },
+{ "bpt", {"", 0x30 } },
+{ "beql", {"bb", 0x31 } },
+{ "beqlu", {"bb", 0x31 } },
+{ "cvtwb", {"rwwb", 0x33 } },
+{ "logf", {"", 0x35 } },
+{ "cmpf", {"rl", 0x36 } },
+{ "cmpd", {"rq", 0x37 } },
+{ "subb3", {"rbrbwb", 0x38 } },
+{ "bitb", {"rbrb", 0x39 } },
+{ "subw3", {"rwrwww", 0x3a } },
+{ "bitw", {"rwrw", 0x3b } },
+{ "subl3", {"rlrlwl", 0x3c } },
+{ "bitl", {"rlrl", 0x3d } },
+{ "ediv", {"rlrqwlwl", 0x3e } },
+{ "aobleq", {"rlmlbw", 0x3f } },
+{ "ret", {"", 0x40 } },
+{ "bgtr", {"bb", 0x41 } },
+{ "sqrtf", {"", 0x45 } },
+{ "cmpf2", {"rl", 0x46 } },
+{ "cmpd2", {"rqrq", 0x47 } },
+{ "shll", {"rbrlwl", 0x48 } },
+{ "clrb", {"wb", 0x49 } },
+{ "shlq", {"rbrqwq", 0x4a } },
+{ "clrw", {"ww", 0x4b } },
+{ "mull2", {"rlml", 0x4c } },
+{ "clrl", {"wl", 0x4d } },
+{ "shal", {"rbrlwl", 0x4e } },
+{ "bleq", {"bb", 0x51 } },
+{ "expf", {"", 0x55 } },
+{ "tstf", {"", 0x56 } },
+{ "tstd", {"", 0x57 } },
+{ "shrl", {"rbrlwl", 0x58 } },
+{ "tstb", {"rb", 0x59 } },
+{ "shrq", {"rbrqwq", 0x5a } },
+{ "tstw", {"rw", 0x5b } },
+{ "mull3", {"rlrlwl", 0x5c } },
+{ "tstl", {"rl", 0x5d } },
+{ "shar", {"rbrlwl", 0x5e } },
+{ "bbssi", {"rlmlbw", 0x5f } },
+{ "ldpctx", {"", 0x60 } },
+{ "pushd", {"", 0x67 } },
+{ "incb", {"mb", 0x69 } },
+{ "incw", {"mw", 0x6b } },
+{ "divl2", {"rlml", 0x6c } },
+{ "incl", {"ml", 0x6d } },
+{ "cvtlb", {"rlwb", 0x6f } },
+{ "svpctx", {"", 0x70 } },
+{ "jmp", {"ab", 0x71 } },
+{ "cvlf", {"rl", 0x76 } },
+{ "cvld", {"rl", 0x77 } },
+{ "decb", {"mb", 0x79 } },
+{ "decw", {"mw", 0x7b } },
+{ "divl3", {"rlrlwl", 0x7c } },
+{ "decl", {"ml", 0x7d } },
+{ "cvtlw", {"rlww", 0x7f } },
+{ "bgeq", {"bb", 0x81 } },
+{ "movs2", {"abab", 0x82 } },
+{ "cvfl", {"wl", 0x86 } },
+{ "cvdl", {"wl", 0x87 } },
+{ "orb2", {"rbmb", 0x88 } },
+{ "cvtbl", {"rbwl", 0x89 } },
+{ "orw2", {"rwmw", 0x8a } },
+{ "bispsw", {"rw", 0x8b } },
+{ "orl2", {"rlml", 0x8c } },
+{ "adwc", {"rlml", 0x8d } },
+{ "adda", {"rlml", 0x8e } },
+{ "blss", {"bb", 0x91 } },
+{ "cmps2", {"abab", 0x92 } },
+{ "ldfd", {"rl", 0x97 } },
+{ "orb3", {"rbrbwb", 0x98 } },
+{ "cvtbw", {"rbww", 0x99 } },
+{ "orw3", {"rwrwww", 0x9a } },
+{ "bicpsw", {"rw", 0x9b } },
+{ "orl3", {"rlrlwl", 0x9c } },
+{ "sbwc", {"rlml", 0x9d } },
+{ "suba", {"rlml", 0x9e } },
+{ "bgtru", {"bb", 0xa1 } },
+{ "cvdf", {"", 0xa6 } },
+{ "andb2", {"rbmb", 0xa8 } },
+{ "movzbl", {"rbwl", 0xa9 } },
+{ "andw2", {"rwmw", 0xaa } },
+{ "loadr", {"rwal", 0xab } },
+{ "andl2", {"rlml", 0xac } },
+{ "mtpr", {"rlrl", 0xad } },
+{ "ffs", {"rlwl", 0xae } },
+{ "blequ", {"bb", 0xb1 } },
+{ "negf", {"", 0xb6 } },
+{ "negd", {"", 0xb7 } },
+{ "andb3", {"rbrbwb", 0xb8 } },
+{ "movzbw", {"rbww", 0xb9 } },
+{ "andw3", {"rwrwww", 0xba } },
+{ "storer", {"rwal", 0xbb } },
+{ "andl3", {"rlrlwl", 0xbc } },
+{ "mfpr", {"rlwl", 0xbd } },
+{ "ffc", {"rlwl", 0xbe } },
+{ "calls", {"rbab", 0xbf } },
+{ "prober", {"rbabrl", 0xc0 } },
+{ "bvc", {"bb", 0xc1 } },
+{ "movs3", {"ababrw", 0xc2 } },
+{ "movzwl", {"rwwl", 0xc3 } },
+{ "addf", {"rl", 0xc6 } },
+{ "addd", {"rq", 0xc7 } },
+{ "xorb2", {"rbmb", 0xc8 } },
+{ "movob", {"rbwb", 0xc9 } },
+{ "xorw2", {"rwmw", 0xca } },
+{ "movow", {"rwww", 0xcb } },
+{ "xorl2", {"rlml", 0xcc } },
+{ "movpsl", {"wl", 0xcd } },
+{ "kcall", {"rw", 0xcf } },
+{ "probew", {"rbabrl", 0xd0 } },
+{ "bvs", {"bb", 0xd1 } },
+{ "cmps3", {"ababrw", 0xd2 } },
+{ "subf", {"rq", 0xd6 } },
+{ "subd", {"rq", 0xd7 } },
+{ "xorb3", {"rbrbwb", 0xd8 } },
+{ "pushb", {"rb", 0xd9 } },
+{ "xorw3", {"rwrwww", 0xda } },
+{ "pushw", {"rw", 0xdb } },
+{ "xorl3", {"rlrlwl", 0xdc } },
+{ "pushl", {"rl", 0xdd } },
+{ "insque", {"abab", 0xe0 } },
+{ "bcs", {"bb", 0xe1 } },
+{ "bgequ", {"bb", 0xe1 } },
+{ "mulf", {"rq", 0xe6 } },
+{ "muld", {"rq", 0xe7 } },
+{ "mnegb", {"rbwb", 0xe8 } },
+{ "movab", {"abwl", 0xe9 } },
+{ "mnegw", {"rwww", 0xea } },
+{ "movaw", {"awwl", 0xeb } },
+{ "mnegl", {"rlwl", 0xec } },
+{ "moval", {"alwl", 0xed } },
+{ "remque", {"ab", 0xf0 } },
+{ "bcc", {"bb", 0xf1 } },
+{ "blssu", {"bb", 0xf1 } },
+{ "divf", {"rq", 0xf6 } },
+{ "divd", {"rq", 0xf7 } },
+{ "movblk", {"alalrw", 0xf8 } },
+{ "pushab", {"ab", 0xf9 } },
+{ "pushaw", {"aw", 0xfb } },
+{ "casel", {"rlrlrl", 0xfc } },
+{ "pushal", {"al", 0xfd } },
+{ "callf", {"rbab", 0xfe } },
+{ "" , "" } /* empty is end sentinel */
+
+};
diff --git a/include/opcode/tic30.h b/include/opcode/tic30.h
new file mode 100644
index 00000000000..a7002759118
--- /dev/null
+++ b/include/opcode/tic30.h
@@ -0,0 +1,691 @@
+/* tic30.h -- Header file for TI TMS320C30 opcode table
+ Copyright 1998 Free Software Foundation, Inc.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* FIXME: The opcode table should be in opcodes/tic30-opc.c, not in a
+ header file. */
+
+#ifndef _TMS320_H_
+#define _TMS320_H_
+
+struct _register
+{
+ char *name;
+ unsigned char opcode;
+ unsigned char regtype;
+};
+
+typedef struct _register reg;
+
+#define REG_Rn 0x01
+#define REG_ARn 0x02
+#define REG_DP 0x03
+#define REG_OTHER 0x04
+
+static const reg tic30_regtab[] = {
+ { "r0", 0x00, REG_Rn },
+ { "r1", 0x01, REG_Rn },
+ { "r2", 0x02, REG_Rn },
+ { "r3", 0x03, REG_Rn },
+ { "r4", 0x04, REG_Rn },
+ { "r5", 0x05, REG_Rn },
+ { "r6", 0x06, REG_Rn },
+ { "r7", 0x07, REG_Rn },
+ { "ar0",0x08, REG_ARn },
+ { "ar1",0x09, REG_ARn },
+ { "ar2",0x0A, REG_ARn },
+ { "ar3",0x0B, REG_ARn },
+ { "ar4",0x0C, REG_ARn },
+ { "ar5",0x0D, REG_ARn },
+ { "ar6",0x0E, REG_ARn },
+ { "ar7",0x0F, REG_ARn },
+ { "dp", 0x10, REG_DP },
+ { "ir0",0x11, REG_OTHER },
+ { "ir1",0x12, REG_OTHER },
+ { "bk", 0x13, REG_OTHER },
+ { "sp", 0x14, REG_OTHER },
+ { "st", 0x15, REG_OTHER },
+ { "ie", 0x16, REG_OTHER },
+ { "if", 0x17, REG_OTHER },
+ { "iof",0x18, REG_OTHER },
+ { "rs", 0x19, REG_OTHER },
+ { "re", 0x1A, REG_OTHER },
+ { "rc", 0x1B, REG_OTHER },
+ { "R0", 0x00, REG_Rn },
+ { "R1", 0x01, REG_Rn },
+ { "R2", 0x02, REG_Rn },
+ { "R3", 0x03, REG_Rn },
+ { "R4", 0x04, REG_Rn },
+ { "R5", 0x05, REG_Rn },
+ { "R6", 0x06, REG_Rn },
+ { "R7", 0x07, REG_Rn },
+ { "AR0",0x08, REG_ARn },
+ { "AR1",0x09, REG_ARn },
+ { "AR2",0x0A, REG_ARn },
+ { "AR3",0x0B, REG_ARn },
+ { "AR4",0x0C, REG_ARn },
+ { "AR5",0x0D, REG_ARn },
+ { "AR6",0x0E, REG_ARn },
+ { "AR7",0x0F, REG_ARn },
+ { "DP", 0x10, REG_DP },
+ { "IR0",0x11, REG_OTHER },
+ { "IR1",0x12, REG_OTHER },
+ { "BK", 0x13, REG_OTHER },
+ { "SP", 0x14, REG_OTHER },
+ { "ST", 0x15, REG_OTHER },
+ { "IE", 0x16, REG_OTHER },
+ { "IF", 0x17, REG_OTHER },
+ { "IOF",0x18, REG_OTHER },
+ { "RS", 0x19, REG_OTHER },
+ { "RE", 0x1A, REG_OTHER },
+ { "RC", 0x1B, REG_OTHER },
+ { "", 0, 0 }
+};
+
+static const reg *const tic30_regtab_end
+ = tic30_regtab + sizeof(tic30_regtab)/sizeof(tic30_regtab[0]);
+
+/* Indirect Addressing Modes Modification Fields */
+/* Indirect Addressing with Displacement */
+#define PreDisp_Add 0x00
+#define PreDisp_Sub 0x01
+#define PreDisp_Add_Mod 0x02
+#define PreDisp_Sub_Mod 0x03
+#define PostDisp_Add_Mod 0x04
+#define PostDisp_Sub_Mod 0x05
+#define PostDisp_Add_Circ 0x06
+#define PostDisp_Sub_Circ 0x07
+/* Indirect Addressing with Index Register IR0 */
+#define PreIR0_Add 0x08
+#define PreIR0_Sub 0x09
+#define PreIR0_Add_Mod 0x0A
+#define PreIR0_Sub_Mod 0x0B
+#define PostIR0_Add_Mod 0x0C
+#define PostIR0_Sub_Mod 0x0D
+#define PostIR0_Add_Circ 0x0E
+#define PostIR0_Sub_Circ 0x0F
+/* Indirect Addressing with Index Register IR1 */
+#define PreIR1_Add 0x10
+#define PreIR1_Sub 0x11
+#define PreIR1_Add_Mod 0x12
+#define PreIR1_Sub_Mod 0x13
+#define PostIR1_Add_Mod 0x14
+#define PostIR1_Sub_Mod 0x15
+#define PostIR1_Add_Circ 0x16
+#define PostIR1_Sub_Circ 0x17
+/* Indirect Addressing (Special Cases) */
+#define IndirectOnly 0x18
+#define PostIR0_Add_BitRev 0x19
+
+typedef struct {
+ char *syntax;
+ unsigned char modfield;
+ unsigned char displacement;
+} ind_addr_type;
+
+#define IMPLIED_DISP 0x01
+#define DISP_REQUIRED 0x02
+#define NO_DISP 0x03
+
+static const ind_addr_type tic30_indaddr_tab[] = {
+ { "*+ar", PreDisp_Add, IMPLIED_DISP },
+ { "*-ar", PreDisp_Sub, IMPLIED_DISP },
+ { "*++ar", PreDisp_Add_Mod, IMPLIED_DISP },
+ { "*--ar", PreDisp_Sub_Mod, IMPLIED_DISP },
+ { "*ar++", PostDisp_Add_Mod, IMPLIED_DISP },
+ { "*ar--", PostDisp_Sub_Mod, IMPLIED_DISP },
+ { "*ar++%", PostDisp_Add_Circ, IMPLIED_DISP },
+ { "*ar--%", PostDisp_Sub_Circ, IMPLIED_DISP },
+ { "*+ar()", PreDisp_Add, DISP_REQUIRED },
+ { "*-ar()", PreDisp_Sub, DISP_REQUIRED },
+ { "*++ar()", PreDisp_Add_Mod, DISP_REQUIRED },
+ { "*--ar()", PreDisp_Sub_Mod, DISP_REQUIRED },
+ { "*ar++()", PostDisp_Add_Mod, DISP_REQUIRED },
+ { "*ar--()", PostDisp_Sub_Mod, DISP_REQUIRED },
+ { "*ar++()%", PostDisp_Add_Circ, DISP_REQUIRED },
+ { "*ar--()%", PostDisp_Sub_Circ, DISP_REQUIRED },
+ { "*+ar(ir0)", PreIR0_Add, NO_DISP },
+ { "*-ar(ir0)", PreIR0_Sub, NO_DISP },
+ { "*++ar(ir0)", PreIR0_Add_Mod, NO_DISP },
+ { "*--ar(ir0)", PreIR0_Sub_Mod, NO_DISP },
+ { "*ar++(ir0)", PostIR0_Add_Mod, NO_DISP },
+ { "*ar--(ir0)", PostIR0_Sub_Mod, NO_DISP },
+ { "*ar++(ir0)%",PostIR0_Add_Circ, NO_DISP },
+ { "*ar--(ir0)%",PostIR0_Sub_Circ, NO_DISP },
+ { "*+ar(ir1)", PreIR1_Add, NO_DISP },
+ { "*-ar(ir1)", PreIR1_Sub, NO_DISP },
+ { "*++ar(ir1)", PreIR1_Add_Mod, NO_DISP },
+ { "*--ar(ir1)", PreIR1_Sub_Mod, NO_DISP },
+ { "*ar++(ir1)", PostIR1_Add_Mod, NO_DISP },
+ { "*ar--(ir1)", PostIR1_Sub_Mod, NO_DISP },
+ { "*ar++(ir1)%",PostIR1_Add_Circ, NO_DISP },
+ { "*ar--(ir1)%",PostIR1_Sub_Circ, NO_DISP },
+ { "*ar", IndirectOnly, NO_DISP },
+ { "*ar++(ir0)b",PostIR0_Add_BitRev, NO_DISP },
+ { "", 0,0 }
+};
+
+static const ind_addr_type *const tic30_indaddrtab_end
+ = tic30_indaddr_tab + sizeof(tic30_indaddr_tab)/sizeof(tic30_indaddr_tab[0]);
+
+/* Possible operand types */
+/* Register types */
+#define Rn 0x0001
+#define ARn 0x0002
+#define DPReg 0x0004
+#define OtherReg 0x0008
+/* Addressing mode types */
+#define Direct 0x0010
+#define Indirect 0x0020
+#define Imm16 0x0040
+#define Disp 0x0080
+#define Imm24 0x0100
+#define Abs24 0x0200
+/* 3 operand addressing mode types */
+#define op3T1 0x0400
+#define op3T2 0x0800
+/* Interrupt vector */
+#define IVector 0x1000
+/* Not required */
+#define NotReq 0x2000
+
+#define GAddr1 Rn | Direct | Indirect | Imm16
+#define GAddr2 GAddr1 | AllReg
+#define TAddr1 op3T1 | Rn | Indirect
+#define TAddr2 op3T2 | Rn | Indirect
+#define Reg Rn | ARn
+#define AllReg Reg | DPReg | OtherReg
+
+typedef struct _template
+{
+ char *name;
+ unsigned int operands; /* how many operands */
+ unsigned int base_opcode; /* base_opcode is the fundamental opcode byte */
+ /* the bits in opcode_modifier are used to generate the final opcode from
+ the base_opcode. These bits also are used to detect alternate forms of
+ the same instruction */
+ unsigned int opcode_modifier;
+
+ /* opcode_modifier bits: */
+#define AddressMode 0x00600000
+#define PCRel 0x02000000
+#define StackOp 0x001F0000
+#define Rotate StackOp
+
+ /* operand_types[i] describes the type of operand i. This is made
+ by OR'ing together all of the possible type masks. (e.g.
+ 'operand_types[i] = Reg|Imm' specifies that operand i can be
+ either a register or an immediate operand */
+ unsigned int operand_types[3];
+ /* This defines the number type of an immediate argument to an instruction. */
+ int imm_arg_type;
+#define Imm_None 0
+#define Imm_Float 1
+#define Imm_SInt 2
+#define Imm_UInt 3
+}
+template;
+
+static const template tic30_optab[] = {
+ { "absf" ,2,0x00000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "absi" ,2,0x00800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "addc" ,2,0x01000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "addc3" ,3,0x20000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "addf" ,2,0x01800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "addf3" ,3,0x20800000,AddressMode, { TAddr1, TAddr2, Rn }, Imm_None },
+ { "addi" ,2,0x02000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "addi3" ,3,0x21000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "and" ,2,0x02800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "and3" ,3,0x21800000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "andn" ,2,0x03000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "andn3" ,3,0x22000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "ash" ,2,0x03800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ash3" ,3,0x22800000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "b" ,1,0x68000000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bu" ,1,0x68000000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blo" ,1,0x68010000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bls" ,1,0x68020000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bhi" ,1,0x68030000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bhs" ,1,0x68040000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "beq" ,1,0x68050000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bne" ,1,0x68060000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blt" ,1,0x68070000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "ble" ,1,0x68080000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bgt" ,1,0x68090000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bge" ,1,0x680A0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bz" ,1,0x68050000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnz" ,1,0x68060000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bp" ,1,0x68090000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bn" ,1,0x68070000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnn" ,1,0x680A0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnv" ,1,0x680C0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bv" ,1,0x680D0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnuf" ,1,0x680E0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "buf" ,1,0x680F0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnc" ,1,0x68040000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bc" ,1,0x68010000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnlv" ,1,0x68100000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blv" ,1,0x68110000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnluf" ,1,0x68120000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bluf" ,1,0x68130000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bzuf" ,1,0x68140000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bd" ,1,0x68200000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bud" ,1,0x68200000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blod" ,1,0x68210000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blsd" ,1,0x68220000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bhid" ,1,0x68230000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bhsd" ,1,0x68240000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "beqd" ,1,0x68250000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bned" ,1,0x68260000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bltd" ,1,0x68270000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bled" ,1,0x68280000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bgtd" ,1,0x68290000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bged" ,1,0x682A0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bzd" ,1,0x68250000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnzd" ,1,0x68260000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bpd" ,1,0x68290000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnd" ,1,0x68270000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnnd" ,1,0x682A0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnvd" ,1,0x682C0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bvd" ,1,0x682D0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnufd" ,1,0x682E0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bufd" ,1,0x682F0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bncd" ,1,0x68240000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bcd" ,1,0x68210000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnlvd" ,1,0x68300000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blvd" ,1,0x68310000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bnlufd" ,1,0x68320000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "blufd" ,1,0x68330000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "bzufd" ,1,0x68340000,PCRel, { AllReg|Disp, 0, 0 }, Imm_None },
+ { "br" ,1,0x60000000,0, { Imm24, 0, 0 }, Imm_UInt },
+ { "brd" ,1,0x61000000,0, { Imm24, 0, 0 }, Imm_UInt },
+ { "call" ,1,0x62000000,0, { Imm24, 0, 0 }, Imm_UInt },
+ { "callu" ,1,0x70000000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "calllo" ,1,0x70010000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callls" ,1,0x70020000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callhi" ,1,0x70030000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callhs" ,1,0x70040000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "calleq" ,1,0x70050000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callne" ,1,0x70060000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "calllt" ,1,0x70070000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callle" ,1,0x70080000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callgt" ,1,0x70090000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callge" ,1,0x700A0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callz" ,1,0x70050000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnz" ,1,0x70060000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callp" ,1,0x70090000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "calln" ,1,0x70070000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnn" ,1,0x700A0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnv" ,1,0x700C0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callv" ,1,0x700D0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnuf",1,0x700E0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "calluf" ,1,0x700F0000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnc" ,1,0x70040000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callc" ,1,0x70010000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnlv",1,0x70100000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "calllv" ,1,0x70110000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callnluf",1,0x70120000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callluf",1,0x70130000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "callzuf",1,0x70140000,PCRel, { AllReg|Disp, 0, 0 }, Imm_UInt },
+ { "cmpf" ,2,0x04000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "cmpf3" ,2,0x23000000,AddressMode, { TAddr1, TAddr2, 0 }, Imm_None },
+ { "cmpi" ,2,0x04800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "cmpi3" ,2,0x23800000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, 0 }, Imm_None },
+ { "db" ,2,0x6C000000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbu" ,2,0x6C000000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblo" ,2,0x6C010000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbls" ,2,0x6C020000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbhi" ,2,0x6C030000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbhs" ,2,0x6C040000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbeq" ,2,0x6C050000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbne" ,2,0x6C060000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblt" ,2,0x6C070000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dble" ,2,0x6C080000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbgt" ,2,0x6C090000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbge" ,2,0x6C0A0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbz" ,2,0x6C050000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnz" ,2,0x6C060000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbp" ,2,0x6C090000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbn" ,2,0x6C070000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnn" ,2,0x6C0A0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnv" ,2,0x6C0C0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbv" ,2,0x6C0D0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnuf" ,2,0x6C0E0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbuf" ,2,0x6C0F0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnc" ,2,0x6C040000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbc" ,2,0x6C010000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnlv" ,2,0x6C100000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblv" ,2,0x6C110000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnluf" ,2,0x6C120000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbluf" ,2,0x6C130000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbzuf" ,2,0x6C140000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbd" ,2,0x6C200000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbud" ,2,0x6C200000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblod" ,2,0x6C210000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblsd" ,2,0x6C220000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbhid" ,2,0x6C230000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbhsd" ,2,0x6C240000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbeqd" ,2,0x6C250000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbned" ,2,0x6C260000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbltd" ,2,0x6C270000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbled" ,2,0x6C280000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbgtd" ,2,0x6C290000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbged" ,2,0x6C2A0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbzd" ,2,0x6C250000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnzd" ,2,0x6C260000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbpd" ,2,0x6C290000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnd" ,2,0x6C270000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnnd" ,2,0x6C2A0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnvd" ,2,0x6C2C0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbvd" ,2,0x6C2D0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnufd" ,2,0x6C2E0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbufd" ,2,0x6C2F0000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbncd" ,2,0x6C240000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbcd" ,2,0x6C210000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnlvd" ,2,0x6C300000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblvd" ,2,0x6C310000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbnlufd",2,0x6C320000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dblufd" ,2,0x6C330000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "dbzufd" ,2,0x6C340000,PCRel, { ARn, AllReg|Disp, 0 }, Imm_None },
+ { "fix" ,2,0x05000000,AddressMode, { GAddr1, AllReg, 0 }, Imm_Float },
+ { "float" ,2,0x05800000,AddressMode, { GAddr2, Rn, 0 }, Imm_SInt },
+ { "iack" ,1,0x1B000000,AddressMode, { Direct|Indirect, 0, 0 }, Imm_None },
+ { "idle" ,0,0x06000000,0, { 0, 0, 0 }, Imm_None },
+ { "idle2" ,0,0x06000001,0, { 0, 0, 0 }, Imm_None }, /* LC31 Only */
+ { "lde" ,2,0x06800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldf" ,2,0x07000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfu" ,2,0x40000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldflo" ,2,0x40800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfls" ,2,0x41000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfhi" ,2,0x41800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfhs" ,2,0x42000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfeq" ,2,0x42800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfne" ,2,0x43000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldflt" ,2,0x43800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfle" ,2,0x44000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfgt" ,2,0x44800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfge" ,2,0x45000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfz" ,2,0x42800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnz" ,2,0x43000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfp" ,2,0x44800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfn" ,2,0x43800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnn" ,2,0x45000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnv" ,2,0x46000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfv" ,2,0x46800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnuf" ,2,0x47000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfuf" ,2,0x47800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnc" ,2,0x42000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfc" ,2,0x40800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnlv" ,2,0x48000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldflv" ,2,0x48800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfnluf",2,0x49000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfluf" ,2,0x49800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfzuf" ,2,0x4A000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldfi" ,2,0x07800000,AddressMode, { Direct|Indirect, Rn, 0 }, Imm_None },
+ { "ldi" ,2,0x08000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldiu" ,2,0x50000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldilo" ,2,0x50800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldils" ,2,0x51000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldihi" ,2,0x51800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldihs" ,2,0x52000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldieq" ,2,0x52800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldine" ,2,0x53000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldilt" ,2,0x53800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldile" ,2,0x54000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldigt" ,2,0x54800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldige" ,2,0x55000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldiz" ,2,0x52800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinz" ,2,0x53000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldip" ,2,0x54800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldin" ,2,0x53800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinn" ,2,0x55000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinv" ,2,0x56000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldiv" ,2,0x56800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinuf" ,2,0x57000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldiuf" ,2,0x57800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinc" ,2,0x52000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldic" ,2,0x50800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinlv" ,2,0x58000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldilv" ,2,0x58800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldinluf",2,0x59000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldiluf" ,2,0x59800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldizuf" ,2,0x5A000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "ldii" ,2,0x08800000,AddressMode, { Direct|Indirect, AllReg, 0 }, Imm_None },
+ { "ldm" ,2,0x09000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "ldp" ,2,0x08700000,0, { Abs24|Direct, DPReg|NotReq, 0 }, Imm_UInt },
+ { "lopower",0,0x10800001,0, { 0, 0, 0 }, Imm_None }, /* LC31 Only */
+ { "lsh" ,2,0x09800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "lsh3" ,3,0x24000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "maxspeed",0,0x10800000,0, { 0, 0, 0 }, Imm_None }, /* LC31 Only */
+ { "mpyf" ,2,0x0A000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "mpyf3" ,3,0x24800000,AddressMode, { TAddr1, TAddr2, Rn }, Imm_None },
+ { "mpyi" ,2,0x0A800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "mpyi3" ,3,0x25000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "negb" ,2,0x0B000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "negf" ,2,0x0B800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "negi" ,2,0x0C000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "nop" ,1,0x0C800000,AddressMode, { AllReg|Indirect|NotReq, 0, 0 }, Imm_None },
+ { "norm" ,2,0x0D000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float }, /*Check another source*/
+ { "not" ,2,0x0D800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "or" ,2,0x10000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "or3" ,3,0x25800000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "pop" ,1,0x0E200000,StackOp, { AllReg, 0, 0 }, Imm_None },
+ { "popf" ,1,0x0EA00000,StackOp, { Rn, 0, 0 }, Imm_None },
+ { "push" ,1,0x0F200000,StackOp, { AllReg, 0, 0 }, Imm_None },
+ { "pushf" ,1,0x0FA00000,StackOp, { Rn, 0, 0 }, Imm_None },
+ { "reti" ,0,0x78000000,0, { 0, 0, 0 }, Imm_None },
+ { "retiu" ,0,0x78000000,0, { 0, 0, 0 }, Imm_None },
+ { "retilo" ,0,0x78010000,0, { 0, 0, 0 }, Imm_None },
+ { "retils" ,0,0x78020000,0, { 0, 0, 0 }, Imm_None },
+ { "retihi" ,0,0x78030000,0, { 0, 0, 0 }, Imm_None },
+ { "retihs" ,0,0x78040000,0, { 0, 0, 0 }, Imm_None },
+ { "retieq" ,0,0x78050000,0, { 0, 0, 0 }, Imm_None },
+ { "retine" ,0,0x78060000,0, { 0, 0, 0 }, Imm_None },
+ { "retilt" ,0,0x78070000,0, { 0, 0, 0 }, Imm_None },
+ { "retile" ,0,0x78080000,0, { 0, 0, 0 }, Imm_None },
+ { "retigt" ,0,0x78090000,0, { 0, 0, 0 }, Imm_None },
+ { "retige" ,0,0x780A0000,0, { 0, 0, 0 }, Imm_None },
+ { "retiz" ,0,0x78050000,0, { 0, 0, 0 }, Imm_None },
+ { "retinz" ,0,0x78060000,0, { 0, 0, 0 }, Imm_None },
+ { "retip" ,0,0x78090000,0, { 0, 0, 0 }, Imm_None },
+ { "retin" ,0,0x78070000,0, { 0, 0, 0 }, Imm_None },
+ { "retinn" ,0,0x780A0000,0, { 0, 0, 0 }, Imm_None },
+ { "retinv" ,0,0x780C0000,0, { 0, 0, 0 }, Imm_None },
+ { "retiv" ,0,0x780D0000,0, { 0, 0, 0 }, Imm_None },
+ { "retinuf",0,0x780E0000,0, { 0, 0, 0 }, Imm_None },
+ { "retiuf" ,0,0x780F0000,0, { 0, 0, 0 }, Imm_None },
+ { "retinc" ,0,0x78040000,0, { 0, 0, 0 }, Imm_None },
+ { "retic" ,0,0x78010000,0, { 0, 0, 0 }, Imm_None },
+ { "retinlv",0,0x78100000,0, { 0, 0, 0 }, Imm_None },
+ { "retilv" ,0,0x78110000,0, { 0, 0, 0 }, Imm_None },
+ { "retinluf",0,0x78120000,0, { 0, 0, 0 }, Imm_None },
+ { "retiluf",0,0x78130000,0, { 0, 0, 0 }, Imm_None },
+ { "retizuf",0,0x78140000,0, { 0, 0, 0 }, Imm_None },
+ { "rets" ,0,0x78800000,0, { 0, 0, 0 }, Imm_None },
+ { "retsu" ,0,0x78800000,0, { 0, 0, 0 }, Imm_None },
+ { "retslo" ,0,0x78810000,0, { 0, 0, 0 }, Imm_None },
+ { "retsls" ,0,0x78820000,0, { 0, 0, 0 }, Imm_None },
+ { "retshi" ,0,0x78830000,0, { 0, 0, 0 }, Imm_None },
+ { "retshs" ,0,0x78840000,0, { 0, 0, 0 }, Imm_None },
+ { "retseq" ,0,0x78850000,0, { 0, 0, 0 }, Imm_None },
+ { "retsne" ,0,0x78860000,0, { 0, 0, 0 }, Imm_None },
+ { "retslt" ,0,0x78870000,0, { 0, 0, 0 }, Imm_None },
+ { "retsle" ,0,0x78880000,0, { 0, 0, 0 }, Imm_None },
+ { "retsgt" ,0,0x78890000,0, { 0, 0, 0 }, Imm_None },
+ { "retsge" ,0,0x788A0000,0, { 0, 0, 0 }, Imm_None },
+ { "retsz" ,0,0x78850000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnz" ,0,0x78860000,0, { 0, 0, 0 }, Imm_None },
+ { "retsp" ,0,0x78890000,0, { 0, 0, 0 }, Imm_None },
+ { "retsn" ,0,0x78870000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnn" ,0,0x788A0000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnv" ,0,0x788C0000,0, { 0, 0, 0 }, Imm_None },
+ { "retsv" ,0,0x788D0000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnuf",0,0x788E0000,0, { 0, 0, 0 }, Imm_None },
+ { "retsuf" ,0,0x788F0000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnc" ,0,0x78840000,0, { 0, 0, 0 }, Imm_None },
+ { "retsc" ,0,0x78810000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnlv",0,0x78900000,0, { 0, 0, 0 }, Imm_None },
+ { "retslv" ,0,0x78910000,0, { 0, 0, 0 }, Imm_None },
+ { "retsnluf",0,0x78920000,0, { 0, 0, 0 }, Imm_None },
+ { "retsluf",0,0x78930000,0, { 0, 0, 0 }, Imm_None },
+ { "retszuf",0,0x78940000,0, { 0, 0, 0 }, Imm_None },
+ { "rnd" ,2,0x11000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "rol" ,1,0x11E00001,Rotate, { AllReg, 0, 0 }, Imm_None },
+ { "rolc" ,1,0x12600001,Rotate, { AllReg, 0, 0 }, Imm_None },
+ { "ror" ,1,0x12E0FFFF,Rotate, { AllReg, 0, 0 }, Imm_None },
+ { "rorc" ,1,0x1360FFFF,Rotate, { AllReg, 0, 0 }, Imm_None },
+ { "rptb" ,1,0x64000000,0, { Imm24, 0, 0 }, Imm_UInt },
+ { "rpts" ,1,0x139B0000,AddressMode, { GAddr2, 0, 0 }, Imm_UInt },
+ { "sigi" ,0,0x16000000,0, { 0, 0, 0 }, Imm_None },
+ { "stf" ,2,0x14000000,AddressMode, { Rn, Direct|Indirect, 0 }, Imm_Float },
+ { "stfi" ,2,0x14800000,AddressMode, { Rn, Direct|Indirect, 0 }, Imm_Float },
+ { "sti" ,2,0x15000000,AddressMode, { AllReg, Direct|Indirect, 0 }, Imm_SInt },
+ { "stii" ,2,0x15800000,AddressMode, { AllReg, Direct|Indirect, 0 }, Imm_SInt },
+ { "subb" ,2,0x16800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "subb3" ,3,0x26000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "subc" ,2,0x17000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "subf" ,2,0x17800000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "subf3" ,3,0x26800000,AddressMode, { TAddr1, TAddr2, Rn }, Imm_None },
+ { "subi" ,2,0x18000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "subi3" ,3,0x27000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "subrb" ,2,0x18800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "subrf" ,2,0x19000000,AddressMode, { GAddr1, Rn, 0 }, Imm_Float },
+ { "subri" ,2,0x19800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_SInt },
+ { "swi" ,0,0x66000000,0, { 0, 0, 0 }, Imm_None },
+ { "trap" ,1,0x74800020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapu" ,1,0x74800020,0, { IVector, 0, 0 }, Imm_None },
+ { "traplo" ,1,0x74810020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapls" ,1,0x74820020,0, { IVector, 0, 0 }, Imm_None },
+ { "traphi" ,1,0x74830020,0, { IVector, 0, 0 }, Imm_None },
+ { "traphs" ,1,0x74840020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapeq" ,1,0x74850020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapne" ,1,0x74860020,0, { IVector, 0, 0 }, Imm_None },
+ { "traplt" ,1,0x74870020,0, { IVector, 0, 0 }, Imm_None },
+ { "traple" ,1,0x74880020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapgt" ,1,0x74890020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapge" ,1,0x748A0020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapz" ,1,0x74850020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnz" ,1,0x74860020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapp" ,1,0x74890020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapn" ,1,0x74870020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnn" ,1,0x748A0020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnv" ,1,0x748C0020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapv" ,1,0x748D0020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnuf",1,0x748E0020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapuf" ,1,0x748F0020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnc" ,1,0x74840020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapc" ,1,0x74810020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnlv",1,0x74900020,0, { IVector, 0, 0 }, Imm_None },
+ { "traplv" ,1,0x74910020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapnluf",1,0x74920020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapluf",1,0x74930020,0, { IVector, 0, 0 }, Imm_None },
+ { "trapzuf",1,0x74940020,0, { IVector, 0, 0 }, Imm_None },
+ { "tstb" ,2,0x1A000000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "tstb3" ,2,0x27800000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, 0 }, Imm_None },
+ { "xor" ,2,0x1A800000,AddressMode, { GAddr2, AllReg, 0 }, Imm_UInt },
+ { "xor3" ,3,0x28000000,AddressMode, { TAddr1|AllReg, TAddr2|AllReg, AllReg }, Imm_None },
+ { "" ,0,0x00000000,0, { 0, 0, 0 }, 0 }
+};
+
+static const template *const tic30_optab_end =
+ tic30_optab + sizeof(tic30_optab)/sizeof(tic30_optab[0]);
+
+typedef struct {
+ char *name;
+ unsigned int operands_1;
+ unsigned int operands_2;
+ unsigned int base_opcode;
+ unsigned int operand_types[2][3];
+ /* Which operand fits into which part of the final opcode word. */
+ int oporder;
+} partemplate;
+
+/* oporder defines - not very descriptive. */
+#define OO_4op1 0
+#define OO_4op2 1
+#define OO_4op3 2
+#define OO_5op1 3
+#define OO_5op2 4
+#define OO_PField 5
+
+static const partemplate tic30_paroptab[] = {
+ { "q_absf_stf", 2,2,0xC8000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_absi_sti", 2,2,0xCA000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_addf3_stf", 3,2,0xCC000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "q_addi3_sti", 3,2,0xCE000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "q_and3_sti", 3,2,0xD0000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "q_ash3_sti", 3,2,0xD2000000, { { Rn, Indirect, Rn }, { Rn, Indirect, 0 } },
+ OO_5op2 },
+ { "q_fix_sti", 2,2,0xD4000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_float_stf", 2,2,0xD6000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_ldf_ldf", 2,2,0xC4000000, { { Indirect, Rn, 0 }, { Indirect, Rn, 0 } },
+ OO_4op2 },
+ { "q_ldf_stf", 2,2,0xD8000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_ldi_ldi", 2,2,0xC6000000, { { Indirect, Rn, 0 }, { Indirect, Rn, 0 } },
+ OO_4op2 },
+ { "q_ldi_sti", 2,2,0xDA000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_lsh3_sti", 3,2,0xDC000000, { { Rn, Indirect, Rn }, { Rn, Indirect, 0 } },
+ OO_5op2 },
+ { "q_mpyf3_addf3",3,3,0x80000000, { { Rn | Indirect, Rn | Indirect, Rn },
+ { Rn | Indirect, Rn | Indirect, Rn } }, OO_PField },
+ { "q_mpyf3_stf", 3,2,0xDE000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "q_mpyf3_subf3",3,3,0x84000000, { { Rn | Indirect, Rn | Indirect, Rn },
+ { Rn | Indirect, Rn | Indirect, Rn } }, OO_PField },
+ { "q_mpyi3_addi3",3,3,0x88000000, { { Rn | Indirect, Rn | Indirect, Rn },
+ { Rn | Indirect, Rn | Indirect, Rn } }, OO_PField },
+ { "q_mpyi3_sti", 3,2,0xE0000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "q_mpyi3_subi3",3,3,0x8C000000, { { Rn | Indirect, Rn | Indirect, Rn },
+ { Rn | Indirect, Rn | Indirect, Rn } }, OO_PField },
+ { "q_negf_stf", 2,2,0xE2000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_negi_sti", 2,2,0xE4000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_not_sti", 2,2,0xE6000000, { { Indirect, Rn, 0 }, { Rn, Indirect, 0 } },
+ OO_4op1 },
+ { "q_or3_sti", 3,2,0xE8000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "q_stf_stf", 2,2,0xC0000000, { { Rn, Indirect, 0 }, { Rn, Indirect, 0 } },
+ OO_4op3 },
+ { "q_sti_sti", 2,2,0xC2000000, { { Rn, Indirect, 0 }, { Rn, Indirect, 0 } },
+ OO_4op3 },
+ { "q_subf3_stf", 3,2,0xEA000000, { { Rn, Indirect, Rn }, { Rn, Indirect, 0 } },
+ OO_5op2 },
+ { "q_subi3_sti", 3,2,0xEC000000, { { Rn, Indirect, Rn }, { Rn, Indirect, 0 } },
+ OO_5op2 },
+ { "q_xor3_sti", 3,2,0xEE000000, { { Indirect, Rn, Rn }, { Rn, Indirect, 0 } },
+ OO_5op1 },
+ { "", 0,0,0x00000000, { { 0, 0, 0 }, { 0, 0, 0 } }, 0 }
+};
+
+static const partemplate *const tic30_paroptab_end =
+ tic30_paroptab + sizeof(tic30_paroptab)/sizeof(tic30_paroptab[0]);
+
+#endif
diff --git a/include/opcode/tic80.h b/include/opcode/tic80.h
new file mode 100644
index 00000000000..b99bc30b818
--- /dev/null
+++ b/include/opcode/tic80.h
@@ -0,0 +1,277 @@
+/* tic80.h -- Header file for TI TMS320C80 (MV) opcode table
+ Copyright 1996, 1997, 1999 Free Software Foundation, Inc.
+ Written by Fred Fish (fnf@cygnus.com), Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TIC80_H
+#define TIC80_H
+
+/* The opcode table is an array of struct tic80_opcode. */
+
+struct tic80_opcode
+{
+ /* The opcode name. */
+
+ const char *name;
+
+ /* The opcode itself. Those bits which will be filled in with operands
+ are zeroes. */
+
+ unsigned long opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a mask
+ containing ones indicating those bits which must match the opcode
+ field, and zeroes indicating those bits which need not match (and are
+ presumably filled in by operands). */
+
+ unsigned long mask;
+
+ /* Special purpose flags for this opcode. */
+
+ unsigned char flags;
+
+ /* An array of operand codes. Each code is an index into the operand
+ table. They appear in the order which the operands must appear in
+ assembly code, and are terminated by a zero. FIXME: Adjust size to
+ match actual requirements when TIc80 support is complete */
+
+ unsigned char operands[8];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise in
+ the order in which the disassembler should consider instructions.
+ FIXME: This isn't currently true. */
+
+extern const struct tic80_opcode tic80_opcodes[];
+extern const int tic80_num_opcodes;
+
+
+/* The operands table is an array of struct tic80_operand. */
+
+struct tic80_operand
+{
+ /* The number of bits in the operand. */
+
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+
+ int shift;
+
+ /* Insertion function. This is used by the assembler. To insert an
+ operand value into an instruction, check this field.
+
+ If it is NULL, execute
+ i |= (op & ((1 << o->bits) - 1)) << o->shift;
+ (i is the instruction which we are filling in, o is a pointer to
+ this structure, and op is the opcode value; this assumes twos
+ complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction and the operand value. It will return the new value
+ of the instruction. If the ERRMSG argument is not NULL, then if
+ the operand value is illegal, *ERRMSG will be set to a warning
+ string (the operand will be inserted in any case). If the
+ operand value is legal, *ERRMSG will be unchanged (most operands
+ can accept any value). */
+
+ unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
+ const char **errmsg));
+
+ /* Extraction function. This is used by the disassembler. To
+ extract this operand type from an instruction, check this field.
+
+ If it is NULL, compute
+ op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+ if ((o->flags & TIC80_OPERAND_SIGNED) != 0
+ && (op & (1 << (o->bits - 1))) != 0)
+ op -= 1 << o->bits;
+ (i is the instruction, o is a pointer to this structure, and op
+ is the result; this assumes twos complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction value. It will return the value of the operand. If
+ the INVALID argument is not NULL, *INVALID will be set to
+ non-zero if this operand type can not actually be extracted from
+ this operand (i.e., the instruction does not match). If the
+ operand is valid, *INVALID will not be changed. */
+
+ long (*extract) PARAMS ((unsigned long instruction, int *invalid));
+
+ /* One bit syntax flags. */
+
+ unsigned long flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the tic80_opcodes table. */
+
+extern const struct tic80_operand tic80_operands[];
+
+
+/* Values defined for the flags field of a struct tic80_operand.
+
+ Note that flags for all predefined symbols, such as the general purpose
+ registers (ex: r10), control registers (ex: FPST), condition codes (ex:
+ eq0.b), bit numbers (ex: gt.b), etc are large enough that they can be
+ or'd into an int where the lower bits contain the actual numeric value
+ that correponds to this predefined symbol. This way a single int can
+ contain both the value of the symbol and it's type.
+ */
+
+/* This operand must be an even register number. Floating point numbers
+ for example are stored in even/odd register pairs. */
+
+#define TIC80_OPERAND_EVEN (1 << 0)
+
+/* This operand must be an odd register number and must be one greater than
+ the register number of the previous operand. I.E. the second register in
+ an even/odd register pair. */
+
+#define TIC80_OPERAND_ODD (1 << 1)
+
+/* This operand takes signed values. */
+
+#define TIC80_OPERAND_SIGNED (1 << 2)
+
+/* This operand may be either a predefined constant name or a numeric value.
+ An example would be a condition code like "eq0.b" which has the numeric
+ value 0x2. */
+
+#define TIC80_OPERAND_NUM (1 << 3)
+
+/* This operand should be wrapped in parentheses rather than separated
+ from the previous one by a comma. This is used for various
+ instructions, like the load and store instructions, which want
+ their operands to look like "displacement(reg)" */
+
+#define TIC80_OPERAND_PARENS (1 << 4)
+
+/* This operand is a PC relative branch offset. The disassembler prints
+ these symbolically if possible. Note that the offsets are taken as word
+ offsets. */
+
+#define TIC80_OPERAND_PCREL (1 << 5)
+
+/* This flag is a hint to the disassembler for using hex as the prefered
+ printing format, even for small positive or negative immediate values.
+ Normally values in the range -999 to 999 are printed as signed decimal
+ values and other values are printed in hex. */
+
+#define TIC80_OPERAND_BITFIELD (1 << 6)
+
+/* This operand may have a ":m" modifier specified by bit 17 in a short
+ immediate form instruction. */
+
+#define TIC80_OPERAND_M_SI (1 << 7)
+
+/* This operand may have a ":m" modifier specified by bit 15 in a long
+ immediate or register form instruction. */
+
+#define TIC80_OPERAND_M_LI (1 << 8)
+
+/* This operand may have a ":s" modifier specified in bit 11 in a long
+ immediate or register form instruction. */
+
+#define TIC80_OPERAND_SCALED (1 << 9)
+
+/* This operand is a floating point value */
+
+#define TIC80_OPERAND_FLOAT (1 << 10)
+
+/* This operand is an byte offset from a base relocation. The lower
+ two bits of the final relocated address are ignored when the value is
+ written to the program counter. */
+
+#define TIC80_OPERAND_BASEREL (1 << 11)
+
+/* This operand is an "endmask" field for a shift instruction.
+ It is treated special in that it can have values of 0-32,
+ where 0 and 32 result in the same instruction. The assembler
+ must be able to accept both endmask values. This disassembler
+ has no way of knowing from the instruction which value was
+ given at assembly time, so it just uses '0'. */
+
+#define TIC80_OPERAND_ENDMASK (1 << 12)
+
+/* This operand is one of the 32 general purpose registers.
+ The disassembler prints these with a leading 'r'. */
+
+#define TIC80_OPERAND_GPR (1 << 27)
+
+/* This operand is a floating point accumulator register.
+ The disassembler prints these with a leading 'a'. */
+
+#define TIC80_OPERAND_FPA ( 1 << 28)
+
+/* This operand is a control register number, either numeric or
+ symbolic (like "EIF", "EPC", etc).
+ The disassembler prints these symbolically. */
+
+#define TIC80_OPERAND_CR (1 << 29)
+
+/* This operand is a condition code, either numeric or
+ symbolic (like "eq0.b", "ne0.w", etc).
+ The disassembler prints these symbolically. */
+
+#define TIC80_OPERAND_CC (1 << 30)
+
+/* This operand is a bit number, either numeric or
+ symbolic (like "eq.b", "or.f", etc).
+ The disassembler prints these symbolically.
+ Note that they appear in the instruction in 1's complement relative
+ to the values given in the manual. */
+
+#define TIC80_OPERAND_BITNUM (1 << 31)
+
+/* This mask is used to strip operand bits from an int that contains
+ both operand bits and a numeric value in the lsbs. */
+
+#define TIC80_OPERAND_MASK (TIC80_OPERAND_GPR | TIC80_OPERAND_FPA | TIC80_OPERAND_CR | TIC80_OPERAND_CC | TIC80_OPERAND_BITNUM)
+
+
+/* Flag bits for the struct tic80_opcode flags field. */
+
+#define TIC80_VECTOR 01 /* Is a vector instruction */
+#define TIC80_NO_R0_DEST 02 /* Register r0 cannot be a destination register */
+
+
+/* The opcodes library contains a table that allows translation from predefined
+ symbol names to numeric values, and vice versa. */
+
+/* Structure to hold information about predefined symbols. */
+
+struct predefined_symbol
+{
+ char *name; /* name to recognize */
+ int value;
+};
+
+#define PDS_NAME(pdsp) ((pdsp) -> name)
+#define PDS_VALUE(pdsp) ((pdsp) -> value)
+
+extern const struct predefined_symbol tic80_predefined_symbols[]; /* Translation array */
+extern const int tic80_num_predefined_symbols; /* How many members in the array */
+
+const char *tic80_value_to_symbol PARAMS ((int val, int class)); /* Translate value to symbolic name */
+int tic80_symbol_to_value PARAMS ((char *name, int class)); /* Translate symbolic name to value */
+
+const struct predefined_symbol *
+tic80_next_predefined_symbol PARAMS ((const struct predefined_symbol *));
+
+#endif /* TIC80_H */
diff --git a/include/opcode/v850.h b/include/opcode/v850.h
new file mode 100644
index 00000000000..88916f1b848
--- /dev/null
+++ b/include/opcode/v850.h
@@ -0,0 +1,166 @@
+/* v850.h -- Header file for NEC V850 opcode table
+ Copyright 1996 Free Software Foundation, Inc.
+ Written by J.T. Conklin, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef V850_H
+#define V850_H
+
+/* The opcode table is an array of struct v850_opcode. */
+
+struct v850_opcode
+{
+ /* The opcode name. */
+ const char *name;
+
+ /* The opcode itself. Those bits which will be filled in with
+ operands are zeroes. */
+ unsigned long opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a
+ mask containing ones indicating those bits which must match the
+ opcode field, and zeroes indicating those bits which need not
+ match (and are presumably filled in by operands). */
+ unsigned long mask;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ unsigned char operands[8];
+
+ /* Which (if any) operand is a memory operand. */
+ unsigned int memop;
+
+ /* Target processor(s). A bit field of processors which support
+ this instruction. Note a bit field is used as some instructions
+ are available on multiple, different processor types, whereas
+ other instructions are only available on one specific type. */
+ unsigned int processors;
+};
+
+/* Values for the processors field in the v850_opcode structure. */
+#define PROCESSOR_V850 (1 << 0) /* Just the V850. */
+#define PROCESSOR_ALL -1 /* Any processor. */
+#define PROCESSOR_V850E (1 << 1) /* Just the V850E. */
+#define PROCESSOR_NOT_V850 (~ PROCESSOR_V850) /* Any processor except the V850. */
+#define PROCESSOR_V850EA (1 << 2) /* Just the V850EA. */
+
+/* The table itself is sorted by major opcode number, and is otherwise
+ in the order in which the disassembler should consider
+ instructions. */
+extern const struct v850_opcode v850_opcodes[];
+extern const int v850_num_opcodes;
+
+
+/* The operands table is an array of struct v850_operand. */
+
+struct v850_operand
+{
+ /* The number of bits in the operand. */
+ /* If this value is -1 then the operand's bits are in a discontinous distribution in the instruction. */
+ int bits;
+
+ /* (bits >= 0): How far the operand is left shifted in the instruction. */
+ /* (bits == -1): Bit mask of the bits in the operand. */
+ int shift;
+
+ /* Insertion function. This is used by the assembler. To insert an
+ operand value into an instruction, check this field.
+
+ If it is NULL, execute
+ i |= (op & ((1 << o->bits) - 1)) << o->shift;
+ (i is the instruction which we are filling in, o is a pointer to
+ this structure, and op is the opcode value; this assumes twos
+ complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction and the operand value. It will return the new value
+ of the instruction. If the ERRMSG argument is not NULL, then if
+ the operand value is illegal, *ERRMSG will be set to a warning
+ string (the operand will be inserted in any case). If the
+ operand value is legal, *ERRMSG will be unchanged (most operands
+ can accept any value). */
+ unsigned long (* insert) PARAMS ((unsigned long instruction, long op,
+ const char ** errmsg));
+
+ /* Extraction function. This is used by the disassembler. To
+ extract this operand type from an instruction, check this field.
+
+ If it is NULL, compute
+ op = o->bits == -1 ? ((i) & o->shift) : ((i) >> o->shift) & ((1 << o->bits) - 1);
+ if (o->flags & V850_OPERAND_SIGNED)
+ op = (op << (32 - o->bits)) >> (32 - o->bits);
+ (i is the instruction, o is a pointer to this structure, and op
+ is the result; this assumes twos complement arithmetic).
+
+ If this field is not NULL, then simply call it with the
+ instruction value. It will return the value of the operand. If
+ the INVALID argument is not NULL, *INVALID will be set to
+ non-zero if this operand type can not actually be extracted from
+ this operand (i.e., the instruction does not match). If the
+ operand is valid, *INVALID will not be changed. */
+ unsigned long (* extract) PARAMS ((unsigned long instruction, int * invalid));
+
+ /* One bit syntax flags. */
+ int flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+ the operands field of the v850_opcodes table. */
+
+extern const struct v850_operand v850_operands[];
+
+/* Values defined for the flags field of a struct v850_operand. */
+
+/* This operand names a general purpose register */
+#define V850_OPERAND_REG 0x01
+
+/* This operand names a system register */
+#define V850_OPERAND_SRG 0x02
+
+/* This operand names a condition code used in the setf instruction */
+#define V850_OPERAND_CC 0x04
+
+/* This operand takes signed values */
+#define V850_OPERAND_SIGNED 0x08
+
+/* This operand is the ep register. */
+#define V850_OPERAND_EP 0x10
+
+/* This operand is a PC displacement */
+#define V850_OPERAND_DISP 0x20
+
+/* This is a relaxable operand. Only used for D9->D22 branch relaxing
+ right now. We may need others in the future (or maybe handle them like
+ promoted operands on the mn10300?) */
+#define V850_OPERAND_RELAX 0x40
+
+/* The register specified must not be r0 */
+#define V850_NOT_R0 0x80
+
+/* CYGNUS LOCAL v850e */
+/* push/pop type instruction, V850E specific. */
+#define V850E_PUSH_POP 0x100
+
+/* 16 bit immediate follows instruction, V850E specific. */
+#define V850E_IMMEDIATE16 0x200
+
+/* 32 bit immediate follows instruction, V850E specific. */
+#define V850E_IMMEDIATE32 0x400
+
+#endif /* V850_H */
diff --git a/include/opcode/vax.h b/include/opcode/vax.h
new file mode 100644
index 00000000000..f3afebde7e3
--- /dev/null
+++ b/include/opcode/vax.h
@@ -0,0 +1,382 @@
+/* Vax opcde list.
+ Copyright (C) 1989, 1995 Free Software Foundation, Inc.
+
+This file is part of GDB and GAS.
+
+GDB and GAS are 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 1, or (at your option)
+any later version.
+
+GDB and GAS are 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 GDB or GAS; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef vax_opcodeT
+#define vax_opcodeT int
+#endif /* no vax_opcodeT */
+
+struct vot_wot /* vax opcode table: wot to do with this */
+ /* particular opcode */
+{
+ const char *args; /* how to compile said opcode */
+ vax_opcodeT code; /* op-code (may be > 8 bits!) */
+};
+
+struct vot /* vax opcode text */
+{
+ const char *name; /* opcode name: lowercase string [key] */
+ struct vot_wot detail; /* rest of opcode table [datum] */
+};
+
+#define vot_how args
+#define vot_code code
+#define vot_detail detail
+#define vot_name name
+
+static const struct vot
+votstrs[] =
+{
+{ "halt", {"", 0x00 } },
+{ "nop", {"", 0x01 } },
+{ "rei", {"", 0x02 } },
+{ "bpt", {"", 0x03 } },
+{ "ret", {"", 0x04 } },
+{ "rsb", {"", 0x05 } },
+{ "ldpctx", {"", 0x06 } },
+{ "svpctx", {"", 0x07 } },
+{ "cvtps", {"rwabrwab", 0x08 } },
+{ "cvtsp", {"rwabrwab", 0x09 } },
+{ "index", {"rlrlrlrlrlwl", 0x0a } },
+{ "crc", {"abrlrwab", 0x0b } },
+{ "prober", {"rbrwab", 0x0c } },
+{ "probew", {"rbrwab", 0x0d } },
+{ "insque", {"abab", 0x0e } },
+{ "remque", {"abwl", 0x0f } },
+{ "bsbb", {"bb", 0x10 } },
+{ "brb", {"bb", 0x11 } },
+{ "bneq", {"bb", 0x12 } },
+{ "bnequ", {"bb", 0x12 } },
+{ "beql", {"bb", 0x13 } },
+{ "beqlu", {"bb", 0x13 } },
+{ "bgtr", {"bb", 0x14 } },
+{ "bleq", {"bb", 0x15 } },
+{ "jsb", {"ab", 0x16 } },
+{ "jmp", {"ab", 0x17 } },
+{ "bgeq", {"bb", 0x18 } },
+{ "blss", {"bb", 0x19 } },
+{ "bgtru", {"bb", 0x1a } },
+{ "blequ", {"bb", 0x1b } },
+{ "bvc", {"bb", 0x1c } },
+{ "bvs", {"bb", 0x1d } },
+{ "bcc", {"bb", 0x1e } },
+{ "bgequ", {"bb", 0x1e } },
+{ "blssu", {"bb", 0x1f } },
+{ "bcs", {"bb", 0x1f } },
+{ "addp4", {"rwabrwab", 0x20 } },
+{ "addp6", {"rwabrwabrwab", 0x21 } },
+{ "subp4", {"rwabrwab", 0x22 } },
+{ "subp6", {"rwabrwabrwab", 0x23 } },
+{ "cvtpt", {"rwababrwab", 0x24 } },
+{ "mulp", {"rwabrwabrwab", 0x25 } },
+{ "cvttp", {"rwababrwab", 0x26 } },
+{ "divp", {"rwabrwabrwab", 0x27 } },
+{ "movc3", {"rwabab", 0x28 } },
+{ "cmpc3", {"rwabab", 0x29 } },
+{ "scanc", {"rwababrb", 0x2a } },
+{ "spanc", {"rwababrb", 0x2b } },
+{ "movc5", {"rwabrbrwab", 0x2c } },
+{ "cmpc5", {"rwabrbrwab", 0x2d } },
+{ "movtc", {"rwabrbabrwab", 0x2e } },
+{ "movtuc", {"rwabrbabrwab", 0x2f } },
+{ "bsbw", {"bw", 0x30 } },
+{ "brw", {"bw", 0x31 } },
+{ "cvtwl", {"rwwl", 0x32 } },
+{ "cvtwb", {"rwwb", 0x33 } },
+{ "movp", {"rwabab", 0x34 } },
+{ "cmpp3", {"rwabab", 0x35 } },
+{ "cvtpl", {"rwabwl", 0x36 } },
+{ "cmpp4", {"rwabrwab", 0x37 } },
+{ "editpc", {"rwababab", 0x38 } },
+{ "matchc", {"rwabrwab", 0x39 } },
+{ "locc", {"rbrwab", 0x3a } },
+{ "skpc", {"rbrwab", 0x3b } },
+{ "movzwl", {"rwwl", 0x3c } },
+{ "acbw", {"rwrwmwbw", 0x3d } },
+{ "movaw", {"awwl", 0x3e } },
+{ "pushaw", {"aw", 0x3f } },
+{ "addf2", {"rfmf", 0x40 } },
+{ "addf3", {"rfrfwf", 0x41 } },
+{ "subf2", {"rfmf", 0x42 } },
+{ "subf3", {"rfrfwf", 0x43 } },
+{ "mulf2", {"rfmf", 0x44 } },
+{ "mulf3", {"rfrfwf", 0x45 } },
+{ "divf2", {"rfmf", 0x46 } },
+{ "divf3", {"rfrfwf", 0x47 } },
+{ "cvtfb", {"rfwb", 0x48 } },
+{ "cvtfw", {"rfww", 0x49 } },
+{ "cvtfl", {"rfwl", 0x4a } },
+{ "cvtrfl", {"rfwl", 0x4b } },
+{ "cvtbf", {"rbwf", 0x4c } },
+{ "cvtwf", {"rwwf", 0x4d } },
+{ "cvtlf", {"rlwf", 0x4e } },
+{ "acbf", {"rfrfmfbw", 0x4f } },
+{ "movf", {"rfwf", 0x50 } },
+{ "cmpf", {"rfrf", 0x51 } },
+{ "mnegf", {"rfwf", 0x52 } },
+{ "tstf", {"rf", 0x53 } },
+{ "emodf", {"rfrbrfwlwf", 0x54 } },
+{ "polyf", {"rfrwab", 0x55 } },
+{ "cvtfd", {"rfwd", 0x56 } },
+ /* opcode 57 is not defined yet */
+{ "adawi", {"rwmw", 0x58 } },
+ /* opcode 59 is not defined yet */
+ /* opcode 5a is not defined yet */
+ /* opcode 5b is not defined yet */
+{ "insqhi", {"abaq", 0x5c } },
+{ "insqti", {"abaq", 0x5d } },
+{ "remqhi", {"aqwl", 0x5e } },
+{ "remqti", {"aqwl", 0x5f } },
+{ "addd2", {"rdmd", 0x60 } },
+{ "addd3", {"rdrdwd", 0x61 } },
+{ "subd2", {"rdmd", 0x62 } },
+{ "subd3", {"rdrdwd", 0x63 } },
+{ "muld2", {"rdmd", 0x64 } },
+{ "muld3", {"rdrdwd", 0x65 } },
+{ "divd2", {"rdmd", 0x66 } },
+{ "divd3", {"rdrdwd", 0x67 } },
+{ "cvtdb", {"rdwb", 0x68 } },
+{ "cvtdw", {"rdww", 0x69 } },
+{ "cvtdl", {"rdwl", 0x6a } },
+{ "cvtrdl", {"rdwl", 0x6b } },
+{ "cvtbd", {"rbwd", 0x6c } },
+{ "cvtwd", {"rwwd", 0x6d } },
+{ "cvtld", {"rlwd", 0x6e } },
+{ "acbd", {"rdrdmdbw", 0x6f } },
+{ "movd", {"rdwd", 0x70 } },
+{ "cmpd", {"rdrd", 0x71 } },
+{ "mnegd", {"rdwd", 0x72 } },
+{ "tstd", {"rd", 0x73 } },
+{ "emodd", {"rdrbrdwlwd", 0x74 } },
+{ "polyd", {"rdrwab", 0x75 } },
+{ "cvtdf", {"rdwf", 0x76 } },
+ /* opcode 77 is not defined yet */
+{ "ashl", {"rbrlwl", 0x78 } },
+{ "ashq", {"rbrqwq", 0x79 } },
+{ "emul", {"rlrlrlwq", 0x7a } },
+{ "ediv", {"rlrqwlwl", 0x7b } },
+{ "clrd", {"wd", 0x7c } },
+{ "clrg", {"wg", 0x7c } },
+{ "clrq", {"wd", 0x7c } },
+{ "movq", {"rqwq", 0x7d } },
+{ "movaq", {"aqwl", 0x7e } },
+{ "movad", {"adwl", 0x7e } },
+{ "pushaq", {"aq", 0x7f } },
+{ "pushad", {"ad", 0x7f } },
+{ "addb2", {"rbmb", 0x80 } },
+{ "addb3", {"rbrbwb", 0x81 } },
+{ "subb2", {"rbmb", 0x82 } },
+{ "subb3", {"rbrbwb", 0x83 } },
+{ "mulb2", {"rbmb", 0x84 } },
+{ "mulb3", {"rbrbwb", 0x85 } },
+{ "divb2", {"rbmb", 0x86 } },
+{ "divb3", {"rbrbwb", 0x87 } },
+{ "bisb2", {"rbmb", 0x88 } },
+{ "bisb3", {"rbrbwb", 0x89 } },
+{ "bicb2", {"rbmb", 0x8a } },
+{ "bicb3", {"rbrbwb", 0x8b } },
+{ "xorb2", {"rbmb", 0x8c } },
+{ "xorb3", {"rbrbwb", 0x8d } },
+{ "mnegb", {"rbwb", 0x8e } },
+{ "caseb", {"rbrbrb", 0x8f } },
+{ "movb", {"rbwb", 0x90 } },
+{ "cmpb", {"rbrb", 0x91 } },
+{ "mcomb", {"rbwb", 0x92 } },
+{ "bitb", {"rbrb", 0x93 } },
+{ "clrb", {"wb", 0x94 } },
+{ "tstb", {"rb", 0x95 } },
+{ "incb", {"mb", 0x96 } },
+{ "decb", {"mb", 0x97 } },
+{ "cvtbl", {"rbwl", 0x98 } },
+{ "cvtbw", {"rbww", 0x99 } },
+{ "movzbl", {"rbwl", 0x9a } },
+{ "movzbw", {"rbww", 0x9b } },
+{ "rotl", {"rbrlwl", 0x9c } },
+{ "acbb", {"rbrbmbbw", 0x9d } },
+{ "movab", {"abwl", 0x9e } },
+{ "pushab", {"ab", 0x9f } },
+{ "addw2", {"rwmw", 0xa0 } },
+{ "addw3", {"rwrwww", 0xa1 } },
+{ "subw2", {"rwmw", 0xa2 } },
+{ "subw3", {"rwrwww", 0xa3 } },
+{ "mulw2", {"rwmw", 0xa4 } },
+{ "mulw3", {"rwrwww", 0xa5 } },
+{ "divw2", {"rwmw", 0xa6 } },
+{ "divw3", {"rwrwww", 0xa7 } },
+{ "bisw2", {"rwmw", 0xa8 } },
+{ "bisw3", {"rwrwww", 0xa9 } },
+{ "bicw2", {"rwmw", 0xaa } },
+{ "bicw3", {"rwrwww", 0xab } },
+{ "xorw2", {"rwmw", 0xac } },
+{ "xorw3", {"rwrwww", 0xad } },
+{ "mnegw", {"rwww", 0xae } },
+{ "casew", {"rwrwrw", 0xaf } },
+{ "movw", {"rwww", 0xb0 } },
+{ "cmpw", {"rwrw", 0xb1 } },
+{ "mcomw", {"rwww", 0xb2 } },
+{ "bitw", {"rwrw", 0xb3 } },
+{ "clrw", {"ww", 0xb4 } },
+{ "tstw", {"rw", 0xb5 } },
+{ "incw", {"mw", 0xb6 } },
+{ "decw", {"mw", 0xb7 } },
+{ "bispsw", {"rw", 0xb8 } },
+{ "bicpsw", {"rw", 0xb9 } },
+{ "popr", {"rw", 0xba } },
+{ "pushr", {"rw", 0xbb } },
+{ "chmk", {"rw", 0xbc } },
+{ "chme", {"rw", 0xbd } },
+{ "chms", {"rw", 0xbe } },
+{ "chmu", {"rw", 0xbf } },
+{ "addl2", {"rlml", 0xc0 } },
+{ "addl3", {"rlrlwl", 0xc1 } },
+{ "subl2", {"rlml", 0xc2 } },
+{ "subl3", {"rlrlwl", 0xc3 } },
+{ "mull2", {"rlml", 0xc4 } },
+{ "mull3", {"rlrlwl", 0xc5 } },
+{ "divl2", {"rlml", 0xc6 } },
+{ "divl3", {"rlrlwl", 0xc7 } },
+{ "bisl2", {"rlml", 0xc8 } },
+{ "bisl3", {"rlrlwl", 0xc9 } },
+{ "bicl2", {"rlml", 0xca } },
+{ "bicl3", {"rlrlwl", 0xcb } },
+{ "xorl2", {"rlml", 0xcc } },
+{ "xorl3", {"rlrlwl", 0xcd } },
+{ "mnegl", {"rlwl", 0xce } },
+{ "casel", {"rlrlrl", 0xcf } },
+{ "movl", {"rlwl", 0xd0 } },
+{ "cmpl", {"rlrl", 0xd1 } },
+{ "mcoml", {"rlwl", 0xd2 } },
+{ "bitl", {"rlrl", 0xd3 } },
+{ "clrf", {"wf", 0xd4 } },
+{ "clrl", {"wl", 0xd4 } },
+{ "tstl", {"rl", 0xd5 } },
+{ "incl", {"ml", 0xd6 } },
+{ "decl", {"ml", 0xd7 } },
+{ "adwc", {"rlml", 0xd8 } },
+{ "sbwc", {"rlml", 0xd9 } },
+{ "mtpr", {"rlrl", 0xda } },
+{ "mfpr", {"rlwl", 0xdb } },
+{ "movpsl", {"wl", 0xdc } },
+{ "pushl", {"rl", 0xdd } },
+{ "moval", {"alwl", 0xde } },
+{ "movaf", {"afwl", 0xde } },
+{ "pushal", {"al", 0xdf } },
+{ "pushaf", {"af", 0xdf } },
+{ "bbs", {"rlvbbb", 0xe0 } },
+{ "bbc", {"rlvbbb", 0xe1 } },
+{ "bbss", {"rlvbbb", 0xe2 } },
+{ "bbcs", {"rlvbbb", 0xe3 } },
+{ "bbsc", {"rlvbbb", 0xe4 } },
+{ "bbcc", {"rlvbbb", 0xe5 } },
+{ "bbssi", {"rlvbbb", 0xe6 } },
+{ "bbcci", {"rlvbbb", 0xe7 } },
+{ "blbs", {"rlbb", 0xe8 } },
+{ "blbc", {"rlbb", 0xe9 } },
+{ "ffs", {"rlrbvbwl", 0xea } },
+{ "ffc", {"rlrbvbwl", 0xeb } },
+{ "cmpv", {"rlrbvbrl", 0xec } },
+{ "cmpzv", {"rlrbvbrl", 0xed } },
+{ "extv", {"rlrbvbwl", 0xee } },
+{ "extzv", {"rlrbvbwl", 0xef } },
+{ "insv", {"rlrlrbvb", 0xf0 } },
+{ "acbl", {"rlrlmlbw", 0xf1 } },
+{ "aoblss", {"rlmlbb", 0xf2 } },
+{ "aobleq", {"rlmlbb", 0xf3 } },
+{ "sobgeq", {"mlbb", 0xf4 } },
+{ "sobgtr", {"mlbb", 0xf5 } },
+{ "cvtlb", {"rlwb", 0xf6 } },
+{ "cvtlw", {"rlww", 0xf7 } },
+{ "ashp", {"rbrwabrbrwab", 0xf8 } },
+{ "cvtlp", {"rlrwab", 0xf9 } },
+{ "callg", {"abab", 0xfa } },
+{ "calls", {"rlab", 0xfb } },
+{ "xfc", {"", 0xfc } },
+ /* undefined opcodes here */
+{ "cvtdh", {"rdwh", 0x32fd } },
+{ "cvtgf", {"rgwh", 0x33fd } },
+{ "addg2", {"rgmg", 0x40fd } },
+{ "addg3", {"rgrgwg", 0x41fd } },
+{ "subg2", {"rgmg", 0x42fd } },
+{ "subg3", {"rgrgwg", 0x43fd } },
+{ "mulg2", {"rgmg", 0x44fd } },
+{ "mulg3", {"rgrgwg", 0x45fd } },
+{ "divg2", {"rgmg", 0x46fd } },
+{ "divg3", {"rgrgwg", 0x47fd } },
+{ "cvtgb", {"rgwb", 0x48fd } },
+{ "cvtgw", {"rgww", 0x49fd } },
+{ "cvtgl", {"rgwl", 0x4afd } },
+{ "cvtrgl", {"rgwl", 0x4bfd } },
+{ "cvtbg", {"rbwg", 0x4cfd } },
+{ "cvtwg", {"rwwg", 0x4dfd } },
+{ "cvtlg", {"rlwg", 0x4efd } },
+{ "acbg", {"rgrgmgbw", 0x4ffd } },
+{ "movg", {"rgwg", 0x50fd } },
+{ "cmpg", {"rgrg", 0x51fd } },
+{ "mnegg", {"rgwg", 0x52fd } },
+{ "tstg", {"rg", 0x53fd } },
+{ "emodg", {"rgrwrgwlwg", 0x54fd } },
+{ "polyg", {"rgrwab", 0x55fd } },
+{ "cvtgh", {"rgwh", 0x56fd } },
+ /* undefined opcodes here */
+{ "addh2", {"rhmh", 0x60fd } },
+{ "addh3", {"rhrhwh", 0x61fd } },
+{ "subh2", {"rhmh", 0x62fd } },
+{ "subh3", {"rhrhwh", 0x63fd } },
+{ "mulh2", {"rhmh", 0x64fd } },
+{ "mulh3", {"rhrhwh", 0x65fd } },
+{ "divh2", {"rhmh", 0x66fd } },
+{ "divh3", {"rhrhwh", 0x67fd } },
+{ "cvthb", {"rhwb", 0x68fd } },
+{ "cvthw", {"rhww", 0x69fd } },
+{ "cvthl", {"rhwl", 0x6afd } },
+{ "cvtrhl", {"rhwl", 0x6bfd } },
+{ "cvtbh", {"rbwh", 0x6cfd } },
+{ "cvtwh", {"rwwh", 0x6dfd } },
+{ "cvtlh", {"rlwh", 0x6efd } },
+{ "acbh", {"rhrhmhbw", 0x6ffd } },
+{ "movh", {"rhwh", 0x70fd } },
+{ "cmph", {"rhrh", 0x71fd } },
+{ "mnegh", {"rhwh", 0x72fd } },
+{ "tsth", {"rh", 0x73fd } },
+{ "emodh", {"rhrwrhwlwh", 0x74fd } },
+{ "polyh", {"rhrwab", 0x75fd } },
+{ "cvthg", {"rhwg", 0x76fd } },
+ /* undefined opcodes here */
+{ "clrh", {"wh", 0x7cfd } },
+{ "clro", {"wo", 0x7cfd } },
+{ "movo", {"rowo", 0x7dfd } },
+{ "movah", {"ahwl", 0x7efd } },
+{ "movao", {"aowl", 0x7efd } },
+{ "pushah", {"ah", 0x7ffd } },
+{ "pushao", {"ao", 0x7ffd } },
+ /* undefined opcodes here */
+{ "cvtfh", {"rfwh", 0x98fd } },
+{ "cvtfg", {"rfwg", 0x99fd } },
+ /* undefined opcodes here */
+{ "cvthf", {"rhwf", 0xf6fd } },
+{ "cvthd", {"rhwd", 0xf7fd } },
+ /* undefined opcodes here */
+{ "bugl", {"rl", 0xfdff } },
+{ "bugw", {"rw", 0xfeff } },
+ /* undefined opcodes here */
+
+{ "", {"", 0} } /* empty is end sentinel */
+
+}; /* votstrs */
+
+/* end: vax.opcode.h */
diff --git a/include/os9k.h b/include/os9k.h
new file mode 100644
index 00000000000..0f2eed2d3b1
--- /dev/null
+++ b/include/os9k.h
@@ -0,0 +1,169 @@
+#if !defined(_MODULE_H)
+#define _MODULE_H
+
+/* OS-9000 i386 module header definitions */
+#define _MPF386
+
+/* sizeof common header less parity field */
+#define N_M_PARITY (sizeof(mh_com)-sizeof(unisgned short))
+#define OLD_M_PARITY 46
+#define M_PARITY N_M_PARITY
+
+#ifdef _MPF68K
+#define MODSYNC 0x4afd /* module header sync code for 680x0 processors */
+#endif
+
+#ifdef _MPF386
+#define MODSYNC 0x4afc /* module header sync code for 80386 processors */
+#endif
+
+#define MODREV 1 /* module format revision 1 */
+#define CRCCON 0x800fe3 /* crc polynomial constant */
+
+/* Module access permission values */
+#define MP_OWNER_READ 0x0001
+#define MP_OWNER_WRITE 0x0002
+#define MP_OWNER_EXEC 0x0004
+#define MP_GROUP_READ 0x0010
+#define MP_GROUP_WRITE 0x0020
+#define MP_GROUP_EXEC 0x0040
+#define MP_WORLD_READ 0x0100
+#define MP_WORLD_WRITE 0x0200
+#define MP_WORLD_EXEC 0x0400
+#define MP_WORLD_ACCESS 0x0777
+#define MP_OWNER_MASK 0x000f
+#define MP_GROUP_MASK 0x00f0
+#define MP_WORLD_MASK 0x0f00
+#define MP_SYSTM_MASK 0xf000
+
+/* Module Type/Language values */
+#define MT_ANY 0
+#define MT_PROGRAM 0x0001
+#define MT_SUBROUT 0x0002
+#define MT_MULTI 0x0003
+#define MT_DATA 0x0004
+#define MT_TRAPLIB 0x000b
+#define MT_SYSTEM 0x000c
+#define MT_FILEMAN 0x000d
+#define MT_DEVDRVR 0x000e
+#define MT_DEVDESC 0x000f
+#define MT_MASK 0xff00
+
+#define ML_ANY 0
+#define ML_OBJECT 1
+#define ML_ICODE 2
+#define ML_PCODE 3
+#define ML_CCODE 4
+#define ML_CBLCODE 5
+#define ML_FRTNCODE 6
+#define ML_MASK 0x00ff
+
+#define mktypelang(type,lang) (((type)<<8)|(lang))
+
+/* Module Attribute values */
+#define MA_REENT 0x80
+#define MA_GHOST 0x40
+#define MA_SUPER 0x20
+#define MA_MASK 0xff00
+#define MR_MASK 0x00ff
+
+#define mkattrevs(attr, revs) (((attr)<<8)|(revs))
+
+#define m_user m_owner.grp_usr.usr
+#define m_group m_owner.grp_usr.grp
+#define m_group_user m_owner.group_user
+
+/* macro definitions for accessing module header fields */
+#define MODNAME(mod) ((u_char*)((u_char*)mod + ((Mh_com)mod)->m_name))
+#if 0
+/* Appears not to be used, and the u_int32 typedef is gone (because it
+ conflicted with a Mach header. */
+#define MODSIZE(mod) ((u_int32)((Mh_com)mod)->m_size)
+#endif /* 0 */
+#define MHCOM_BYTES_SIZE 80
+#define N_BADMAG(a) (((a).a_info) != MODSYNC)
+
+typedef struct mh_com {
+ /* sync bytes ($4afc). */
+ unsigned char m_sync[2];
+ unsigned char m_sysrev[2]; /* system revision check value */
+ unsigned char
+ m_size[4]; /* module size */
+ unsigned char
+ m_owner[4]; /* group/user id */
+ unsigned char
+ m_name[4]; /* offset to module name */
+ unsigned char
+ m_access[2], /* access permissions */
+ m_tylan[2], /* type/lang */
+ m_attrev[2], /* rev/attr */
+ m_edit[2]; /* edition */
+ unsigned char
+ m_needs[4], /* module hardware requirements flags. (reserved) */
+ m_usage[4], /* comment string offset */
+ m_symbol[4], /* symbol table offset */
+ m_exec[4], /* offset to execution entry point */
+ m_excpt[4], /* offset to exception entry point */
+ m_data[4], /* data storage requirement */
+ m_stack[4], /* stack size */
+ m_idata[4], /* offset to initialized data */
+ m_idref[4], /* offset to data reference lists */
+ m_init[4], /* initialization routine offset */
+ m_term[4]; /* termination routine offset */
+ unsigned char
+ m_ident[2]; /* ident code for ident program */
+ char
+ m_spare[8]; /* reserved bytes */
+ unsigned char
+ m_parity[2]; /* header parity */
+} mh_com,*Mh_com;
+
+/* Executable memory module */
+typedef mh_com *Mh_exec,mh_exec;
+
+/* Data memory module */
+typedef mh_com *Mh_data,mh_data;
+
+/* File manager memory module */
+typedef mh_com *Mh_fman,mh_fman;
+
+/* device driver module */
+typedef mh_com *Mh_drvr,mh_drvr;
+
+/* trap handler module */
+typedef mh_com mh_trap, *Mh_trap;
+
+/* Device descriptor module */
+typedef mh_com *Mh_dev,mh_dev;
+
+/* Configuration module */
+typedef mh_com *Mh_config, mh_config;
+
+#if 0
+
+#if !defined(_MODDIR_H)
+/* go get _os_fmod (and others) */
+#include <moddir.h>
+#endif
+
+error_code _os_crc(void *, u_int32, int *);
+error_code _os_datmod(char *, u_int32, u_int16 *, u_int16 *, u_int32, void **, mh_data **);
+error_code _os_get_moddir(void *, u_int32 *);
+error_code _os_initdata(mh_com *, void *);
+error_code _os_link(char **, mh_com **, void **, u_int16 *, u_int16 *);
+error_code _os_linkm(mh_com *, void **, u_int16 *, u_int16 *);
+error_code _os_load(char *, mh_com **, void **, u_int32, u_int16 *, u_int16 *, u_int32);
+error_code _os_mkmodule(char *, u_int32, u_int16 *, u_int16 *, u_int32, void **, mh_com **, u_int32);
+error_code _os_modaddr(void *, mh_com **);
+error_code _os_setcrc(mh_com *);
+error_code _os_slink(u_int32, char *, void **, void **, mh_com **);
+error_code _os_slinkm(u_int32, mh_com *, void **, void **);
+error_code _os_unlink(mh_com *);
+error_code _os_unload(char *, u_int32);
+error_code _os_tlink(u_int32, char *, void **, mh_trap **, void *, u_int32);
+error_code _os_tlinkm(u_int32, mh_com *, void **, void *, u_int32);
+error_code _os_iodel(mh_com *);
+error_code _os_vmodul(mh_com *, mh_com *, u_int32);
+#endif /* 0 */
+
+#endif
diff --git a/include/progress.h b/include/progress.h
new file mode 100644
index 00000000000..f18318a4514
--- /dev/null
+++ b/include/progress.h
@@ -0,0 +1,37 @@
+/* Default definitions for progress macros.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* The default definitions below are intended to be replaced by real
+ definitions, if building the tools for an interactive programming
+ environment. */
+
+#ifndef _PROGRESS_H
+#define _PROGRESS_H
+
+#ifndef START_PROGRESS
+#define START_PROGRESS(STR,N)
+#endif
+
+#ifndef PROGRESS
+#define PROGRESS(X)
+#endif
+
+#ifndef END_PROGRESS
+#define END_PROGRESS(STR)
+#endif
+
+#endif /* _PROGRESS_H */
diff --git a/include/regs/ChangeLog b/include/regs/ChangeLog
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/include/regs/ChangeLog
diff --git a/include/remote-sim.h b/include/remote-sim.h
new file mode 100644
index 00000000000..a4480b49ca5
--- /dev/null
+++ b/include/remote-sim.h
@@ -0,0 +1,321 @@
+/* This file defines the interface between the simulator and gdb.
+ Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if !defined (REMOTE_SIM_H)
+#define REMOTE_SIM_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This file is used when building stand-alone simulators, so isolate this
+ file from gdb. */
+
+/* Pick up CORE_ADDR_TYPE if defined (from gdb), otherwise use same value as
+ gdb does (unsigned int - from defs.h). */
+
+#ifndef CORE_ADDR_TYPE
+typedef unsigned int SIM_ADDR;
+#else
+typedef CORE_ADDR_TYPE SIM_ADDR;
+#endif
+
+
+/* Semi-opaque type used as result of sim_open and passed back to all
+ other routines. "desc" is short for "descriptor".
+ It is up to each simulator to define `sim_state'. */
+
+typedef struct sim_state *SIM_DESC;
+
+
+/* Values for `kind' arg to sim_open. */
+
+typedef enum {
+ SIM_OPEN_STANDALONE, /* simulator used standalone (run.c) */
+ SIM_OPEN_DEBUG /* simulator used by debugger (gdb) */
+} SIM_OPEN_KIND;
+
+
+/* Return codes from various functions. */
+
+typedef enum {
+ SIM_RC_FAIL = 0,
+ SIM_RC_OK = 1,
+ SIM_RC_UNKNOWN_BREAKPOINT = 2,
+ SIM_RC_INSUFFICIENT_RESOURCES = 3,
+ SIM_RC_DUPLICATE_BREAKPOINT = 4
+} SIM_RC;
+
+
+/* The bfd struct, as an opaque type. */
+
+struct _bfd;
+
+
+/* Main simulator entry points. */
+
+
+/* Create a fully initialized simulator instance.
+
+ (This function is called when the simulator is selected from the
+ gdb command line.)
+
+ KIND specifies how the simulator shall be used. Currently there
+ are only two kinds: stand-alone and debug.
+
+ CALLBACK specifies a standard host callback (defined in callback.h).
+
+ ABFD, when non NULL, designates a target program. The program is
+ not loaded.
+
+ ARGV is a standard ARGV pointer such as that passed from the
+ command line. The syntax of the argument list is is assumed to be
+ ``SIM-PROG { SIM-OPTION } [ TARGET-PROGRAM { TARGET-OPTION } ]''.
+ The trailing TARGET-PROGRAM and args are only valid for a
+ stand-alone simulator.
+
+ On success, the result is a non NULL descriptor that shall be
+ passed to the other sim_foo functions. While the simulator
+ configuration can be parameterized by (in decreasing precedence)
+ ARGV's SIM-OPTION, ARGV's TARGET-PROGRAM and the ABFD argument, the
+ successful creation of the simulator shall not dependent on the
+ presence of any of these arguments/options.
+
+ Hardware simulator: The created simulator shall be sufficiently
+ initialized to handle, with out restrictions any client requests
+ (including memory reads/writes, register fetch/stores and a
+ resume).
+
+ Process simulator: that process is not created until a call to
+ sim_create_inferior. FIXME: What should the state of the simulator
+ be? */
+
+SIM_DESC sim_open PARAMS ((SIM_OPEN_KIND kind, struct host_callback_struct *callback, struct _bfd *abfd, char **argv));
+
+
+/* Destory a simulator instance.
+
+ QUITTING is non-zero if we cannot hang on errors.
+
+ This may involve freeing target memory and closing any open files
+ and mmap'd areas. You cannot assume sim_kill has already been
+ called. */
+
+void sim_close PARAMS ((SIM_DESC sd, int quitting));
+
+
+/* Load program PROG into the simulators memory.
+
+ If ABFD is non-NULL, the bfd for the file has already been opened.
+ The result is a return code indicating success.
+
+ Hardware simulator: Normally, each program section is written into
+ memory according to that sections LMA using physical (direct)
+ addressing. The exception being systems, such as PPC/CHRP, which
+ support more complicated program loaders. A call to this function
+ should not effect the state of the processor registers. Multiple
+ calls to this function are permitted and have an accumulative
+ effect.
+
+ Process simulator: Calls to this function may be ignored.
+
+ FIXME: Most hardware simulators load the image at the VMA using
+ virtual addressing.
+
+ FIXME: For some hardware targets, before a loaded program can be
+ executed, it requires the manipulation of VM registers and tables.
+ Such manipulation should probably (?) occure in
+ sim_create_inferior. */
+
+SIM_RC sim_load PARAMS ((SIM_DESC sd, char *prog, struct _bfd *abfd, int from_tty));
+
+
+/* Prepare to run the simulated program.
+
+ ABFD, if not NULL, provides initial processor state information.
+ ARGV and ENV, if non NULL, are NULL terminated lists of pointers.
+
+ Hardware simulator: This function shall initialize the processor
+ registers to a known value. The program counter and possibly stack
+ pointer shall be set using information obtained from ABFD (or
+ hardware reset defaults). ARGV and ENV, dependant on the target
+ ABI, may be written to memory.
+
+ Process simulator: After a call to this function, a new process
+ instance shall exist. The TEXT, DATA, BSS and stack regions shall
+ all be initialized, ARGV and ENV shall be written to process
+ address space (according to the applicable ABI) and the program
+ counter and stack pointer set accordingly. */
+
+SIM_RC sim_create_inferior PARAMS ((SIM_DESC sd, struct _bfd *abfd, char **argv, char **env));
+
+
+/* Fetch LENGTH bytes of the simulated program's memory. Start fetch
+ at virtual address MEM and store in BUF. Result is number of bytes
+ read, or zero if error. */
+
+int sim_read PARAMS ((SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length));
+
+
+/* Store LENGTH bytes from BUF into the simulated program's
+ memory. Store bytes starting at virtual address MEM. Result is
+ number of bytes write, or zero if error. */
+
+int sim_write PARAMS ((SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length));
+
+
+/* Fetch register REGNO storing its raw (target endian) value in the
+ LENGTH byte buffer BUF. Return the actual size of the register or
+ zero if REGNO is not applicable.
+
+ Legacy implementations ignore LENGTH and always return -1.
+
+ If LENGTH does not match the size of REGNO no data is transfered
+ (the actual register size is still returned). */
+
+int sim_fetch_register PARAMS ((SIM_DESC sd, int regno, unsigned char *buf, int length));
+
+
+/* Store register REGNO from the raw (target endian) value in BUF.
+ Return the actual size of the register or zero if REGNO is not
+ applicable.
+
+ Legacy implementations ignore LENGTH and always return -1.
+
+ If LENGTH does not match the size of REGNO no data is transfered
+ (the actual register size is still returned). */
+
+int sim_store_register PARAMS ((SIM_DESC sd, int regno, unsigned char *buf, int length));
+
+
+/* Print whatever statistics the simulator has collected.
+
+ VERBOSE is currently unused and must always be zero. */
+
+void sim_info PARAMS ((SIM_DESC sd, int verbose));
+
+
+/* Run (or resume) the simulated program. */
+
+void sim_resume PARAMS ((SIM_DESC sd, int step, int siggnal));
+
+
+/* Asynchronous request to stop the simulation.
+ A nonzero return indicates that the simulator is able to handle
+ the request */
+
+int sim_stop PARAMS ((SIM_DESC sd));
+
+
+/* Fetch the REASON why the program stopped.
+
+ SIM_EXITED: The program has terminated. SIGRC indicates the target
+ dependant exit status.
+
+ SIM_STOPPED: The program has stopped. SIGRC uses the host's signal
+ numbering as a way of identifying the reaon: program interrupted by
+ user via a sim_stop request (SIGINT); a breakpoint instruction
+ (SIGTRAP); a completed single step (SIGTRAP); an internal error
+ condition (SIGABRT); an illegal instruction (SIGILL); Access to an
+ undefined memory region (SIGSEGV); Mis-aligned memory access
+ (SIGBUS).
+
+ SIM_SIGNALLED: The program has stopped. The simulator has
+ encountered target code that requires the (HOST) signal SIGRC to be
+ delivered to the simulated program. Ex: `kill (getpid (),
+ TARGET_SIGxxx)'. Where TARGET_SIGxxx has been translated into a
+ host signal. FIXME: This is not always possible..
+
+ SIM_RUNNING, SIM_POLLING: The return of one of these values
+ indicates a problem internal to the simulator. */
+
+enum sim_stop { sim_running, sim_polling, sim_exited, sim_stopped, sim_signalled };
+
+void sim_stop_reason PARAMS ((SIM_DESC sd, enum sim_stop *reason, int *sigrc));
+
+
+/* Passthru for other commands that the simulator might support.
+ Simulators should be prepared to deal with any combination of NULL
+ or empty CMD. */
+
+void sim_do_command PARAMS ((SIM_DESC sd, char *cmd));
+
+/* Call these functions to set and clear breakpoints at ADDR. */
+
+SIM_RC sim_set_breakpoint PARAMS ((SIM_DESC sd, SIM_ADDR addr));
+SIM_RC sim_clear_breakpoint PARAMS ((SIM_DESC sd, SIM_ADDR addr));
+SIM_RC sim_clear_all_breakpoints PARAMS ((SIM_DESC sd));
+
+/* These functions are used to enable and disable breakpoints. */
+
+SIM_RC sim_enable_breakpoint PARAMS ((SIM_DESC sd, SIM_ADDR addr));
+SIM_RC sim_disable_breakpoint PARAMS ((SIM_DESC sd, SIM_ADDR addr));
+SIM_RC sim_enable_all_breakpoints PARAMS ((SIM_DESC sd));
+SIM_RC sim_disable_all_breakpoints PARAMS ((SIM_DESC sd));
+
+
+/* Provide simulator with a default (global) host_callback_struct.
+ THIS PROCEDURE IS DEPRECIATED.
+ GDB and NRUN do not use this interface.
+ This procedure does not take a SIM_DESC argument as it is
+ used before sim_open. */
+
+void sim_set_callbacks PARAMS ((struct host_callback_struct *));
+
+
+/* Set the size of the simulator memory array.
+ THIS PROCEDURE IS DEPRECIATED.
+ GDB and NRUN do not use this interface.
+ This procedure does not take a SIM_DESC argument as it is
+ used before sim_open. */
+
+void sim_size PARAMS ((int i));
+
+
+/* Run a simulation with tracing enabled.
+ THIS PROCEDURE IS DEPRECIATED.
+ GDB and NRUN do not use this interface.
+ This procedure does not take a SIM_DESC argument as it is
+ used before sim_open. */
+
+int sim_trace PARAMS ((SIM_DESC sd));
+
+
+/* Configure the size of the profile buffer.
+ THIS PROCEDURE IS DEPRECIATED.
+ GDB and NRUN do not use this interface.
+ This procedure does not take a SIM_DESC argument as it is
+ used before sim_open. */
+
+void sim_set_profile_size PARAMS ((int n));
+
+
+/* Kill the running program.
+ THIS PROCEDURE IS DEPRECIATED.
+ GDB and NRUN do not use this interface.
+ This procedure will be replaced as part of the introduction of
+ multi-cpu simulators. */
+
+void sim_kill PARAMS ((SIM_DESC sd));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined (REMOTE_SIM_H) */
diff --git a/include/splay-tree.h b/include/splay-tree.h
new file mode 100644
index 00000000000..e828fe7e907
--- /dev/null
+++ b/include/splay-tree.h
@@ -0,0 +1,116 @@
+/* A splay-tree datatype.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* For an easily readable description of splay-trees, see:
+
+ Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
+ Algorithms. Harper-Collins, Inc. 1991.
+
+ The major feature of splay trees is that all basic tree operations
+ are amortized O(log n) time for a tree with n nodes. */
+
+#ifndef _SPLAY_TREE_H
+#define _SPLAY_TREE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <ansidecl.h>
+
+/* Use typedefs for the key and data types to facilitate changing
+ these types, if necessary. These types should be sufficiently wide
+ that any pointer or scalar can be cast to these types, and then
+ cast back, without loss of precision. */
+typedef unsigned long int splay_tree_key;
+typedef unsigned long int splay_tree_value;
+
+/* Forward declaration for a node in the tree. */
+typedef struct splay_tree_node *splay_tree_node;
+
+/* The type of a function which compares two splay-tree keys. The
+ function should return values as for qsort. */
+typedef int (*splay_tree_compare_fn) PARAMS((splay_tree_key, splay_tree_key));
+
+/* The type of a function used to deallocate any resources associated
+ with the key. */
+typedef void (*splay_tree_delete_key_fn) PARAMS((splay_tree_key));
+
+/* The type of a function used to deallocate any resources associated
+ with the value. */
+typedef void (*splay_tree_delete_value_fn) PARAMS((splay_tree_value));
+
+/* The type of a function used to iterate over the tree. */
+typedef int (*splay_tree_foreach_fn) PARAMS((splay_tree_node, void*));
+
+/* The nodes in the splay tree. */
+struct splay_tree_node
+{
+ /* The key. */
+ splay_tree_key key;
+
+ /* The value. */
+ splay_tree_value value;
+
+ /* The left and right children, respectively. */
+ splay_tree_node left;
+ splay_tree_node right;
+};
+
+/* The splay tree itself. */
+typedef struct splay_tree
+{
+ /* The root of the tree. */
+ splay_tree_node root;
+
+ /* The comparision function. */
+ splay_tree_compare_fn comp;
+
+ /* The deallocate-key function. NULL if no cleanup is necessary. */
+ splay_tree_delete_key_fn delete_key;
+
+ /* The deallocate-value function. NULL if no cleanup is necessary. */
+ splay_tree_delete_value_fn delete_value;
+} *splay_tree;
+
+extern splay_tree splay_tree_new PARAMS((splay_tree_compare_fn,
+ splay_tree_delete_key_fn,
+ splay_tree_delete_value_fn));
+extern void splay_tree_delete PARAMS((splay_tree));
+extern void splay_tree_insert PARAMS((splay_tree,
+ splay_tree_key,
+ splay_tree_value));
+extern splay_tree_node splay_tree_lookup
+ PARAMS((splay_tree,
+ splay_tree_key));
+extern int splay_tree_foreach PARAMS((splay_tree,
+ splay_tree_foreach_fn,
+ void*));
+extern int splay_tree_compare_ints PARAMS((splay_tree_key,
+ splay_tree_key));
+extern int splay_tree_compare_pointers PARAMS((splay_tree_key,
+ splay_tree_key));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _SPLAY_TREE_H */
diff --git a/include/symcat.h b/include/symcat.h
new file mode 100644
index 00000000000..01efada2618
--- /dev/null
+++ b/include/symcat.h
@@ -0,0 +1,40 @@
+/* Symbol concatenation utilities.
+
+ Copyright (C) 1998, Free Software Foundation, Inc.
+
+ 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.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef SYM_CAT_H
+#define SYM_CAT_H
+
+#if defined (__STDC__) || defined (ALMOST_STDC)
+#define CONCAT2(a,b) a##b
+#define CONCAT3(a,b,c) a##b##c
+#define CONCAT4(a,b,c,d) a##b##c##d
+#define STRINGX(s) #s
+#else
+#define CONCAT2(a,b) a/**/b
+#define CONCAT3(a,b,c) a/**/b/**/c
+#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d
+#define STRINGX(s) "?"
+#endif
+
+#define XCONCAT2(a,b) CONCAT2(a,b)
+#define XCONCAT3(a,b,c) CONCAT3(a,b,c)
+#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d)
+
+#define XSTRING(s) STRINGX(s)
+
+#endif SYM_CAT_H
diff --git a/include/wait.h b/include/wait.h
new file mode 100644
index 00000000000..fa3c9ccb1d7
--- /dev/null
+++ b/include/wait.h
@@ -0,0 +1,63 @@
+/* Define how to access the int that the wait system call stores.
+ This has been compatible in all Unix systems since time immemorial,
+ but various well-meaning people have defined various different
+ words for the same old bits in the same old int (sometimes claimed
+ to be a struct). We just know it's an int and we use these macros
+ to access the bits. */
+
+/* The following macros are defined equivalently to their definitions
+ in POSIX.1. We fail to define WNOHANG and WUNTRACED, which POSIX.1
+ <sys/wait.h> defines, since our code does not use waitpid(). We
+ also fail to declare wait() and waitpid(). */
+
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w)&0377) == 0)
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#endif
+
+#ifndef WIFSTOPPED
+#ifdef IBM6000
+
+/* Unfortunately, the above comment (about being compatible in all Unix
+ systems) is not quite correct for AIX, sigh. And AIX 3.2 can generate
+ status words like 0x57c (sigtrap received after load), and gdb would
+ choke on it. */
+
+#define WIFSTOPPED(w) ((w)&0x40)
+
+#else
+#define WIFSTOPPED(w) (((w)&0377) == 0177)
+#endif
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) >> 8) & 0377) /* same as WRETCODE */
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0177)
+#endif
+
+#ifndef WSTOPSIG
+#define WSTOPSIG WEXITSTATUS
+#endif
+
+/* These are not defined in POSIX, but are used by our programs. */
+
+#define WAITTYPE int
+
+#ifndef WCOREDUMP
+#define WCOREDUMP(w) (((w)&0200) != 0)
+#endif
+
+#ifndef WSETEXIT
+#define WSETEXIT(w,status) ((w) = (0 | ((status) << 8)))
+#endif
+
+#ifndef WSETSTOP
+#define WSETSTOP(w,sig) ((w) = (0177 | ((sig) << 8)))
+#endif
+
diff --git a/install-sh b/install-sh
new file mode 100755
index 00000000000..e9de23842dc
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/intl/ChangeLog b/intl/ChangeLog
new file mode 100644
index 00000000000..ecff6f6b2cd
--- /dev/null
+++ b/intl/ChangeLog
@@ -0,0 +1,1022 @@
+1997-09-06 02:10 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in: Reformat copyright.
+
+1997-08-19 15:22 Ulrich Drepper <drepper@cygnus.com>
+
+ * dcgettext.c (DCGETTEXT): Remove wrong comment.
+
+1997-08-16 00:13 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install-data): Don't change directory to install.
+
+1997-08-01 14:30 Ulrich Drepper <drepper@cygnus.com>
+
+ * cat-compat.c: Fix copyright.
+
+ * localealias.c: Don't define strchr unless !HAVE_STRCHR.
+
+ * loadmsgcat.c: Update copyright. Fix typos.
+
+ * l10nflist.c: Don't define strchr unless !HAVE_STRCHR.
+ (_nl_make_l10nflist): Handle sponsor and revision correctly.
+
+ * gettext.c: Update copyright.
+ * gettext.h: Likewise.
+ * hash-string.h: Likewise.
+
+ * finddomain.c: Remoave dead code. Define strchr only if
+ !HAVE_STRCHR.
+
+ * explodename.c: Include <sys/types.h>.
+
+ * explodename.c: Reformat copyright text.
+ (_nl_explode_name): Fix typo.
+
+ * dcgettext.c: Define and use __set_errno.
+ (guess_category_value): Don't use setlocale if HAVE_LC_MESSAGES is
+ not defined.
+
+ * bindtextdom.c: Pretty printing.
+
+1997-05-01 02:25 Ulrich Drepper <drepper@cygnus.com>
+
+ * dcgettext.c (guess_category_value): Don't depend on
+ HAVE_LC_MESSAGES. We don't need the macro here.
+ Patch by Bruno Haible <haible@ilog.fr>.
+
+ * cat-compat.c (textdomain): DoN't refer to HAVE_SETLOCALE_NULL
+ macro. Instead use HAVE_LOCALE_NULL and define it when using
+ glibc, as in dcgettext.c.
+ Patch by Bruno Haible <haible@ilog.fr>.
+
+ * Makefile.in (CPPFLAGS): New variable. Reported by Franc,ois
+ Pinard.
+
+Mon Mar 10 06:51:17 1997 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in: Implement handling of libtool.
+
+ * gettextP.h: Change data structures for use of generic lowlevel
+ i18n file handling.
+
+Wed Dec 4 20:21:18 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * textdomain.c: Put parentheses around arguments of memcpy macro
+ definition.
+ * localealias.c: Likewise.
+ * l10nflist.c: Likewise.
+ * finddomain.c: Likewise.
+ * bindtextdom.c: Likewise.
+ Reported by Thomas Esken.
+
+Mon Nov 25 22:57:51 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * textdomain.c: Move definition of `memcpy` macro to right
+ position.
+
+Fri Nov 22 04:01:58 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * finddomain.c [!HAVE_STRING_H && !_LIBC]: Define memcpy using
+ bcopy if not already defined. Reported by Thomas Esken.
+ * bindtextdom.c: Likewise.
+ * l10nflist.c: Likewise.
+ * localealias.c: Likewise.
+ * textdomain.c: Likewise.
+
+Tue Oct 29 11:10:27 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (libdir): Change to use exec_prefix instead of
+ prefix. Reported by Knut-HåvardAksnes <etokna@eto.ericsson.se>.
+
+Sat Aug 31 03:07:09 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c (_nl_normalize_codeset): We convert to lower case,
+ so don't prepend uppercase `ISO' for only numeric arg.
+
+Fri Jul 19 00:15:46 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c: Move inclusion of argz.h, ctype.h, stdlib.h after
+ definition of _GNU_SOURCE. Patch by Roland McGrath.
+
+ * Makefile.in (uninstall): Fix another bug with `for' loop and
+ empty arguments. Patch by Jim Meyering. Correct name os
+ uninstalled files: no intl- prefix anymore.
+
+ * Makefile.in (install-data): Again work around shells which
+ cannot handle mpty for list. Reported by Jim Meyering.
+
+Sat Jul 13 18:11:35 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install): Split goal. Now depend on install-exec
+ and install-data.
+ (install-exec, install-data): New goals. Created from former
+ install goal.
+ Reported by Karl Berry.
+
+Sat Jun 22 04:58:14 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (MKINSTALLDIRS): New variable. Path to
+ mkinstalldirs script.
+ (install): use MKINSTALLDIRS variable or if the script is not present
+ try to find it in the $top_scrdir).
+
+Wed Jun 19 02:56:56 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c: Linux libc *partly* includes the argz_* functions.
+ Grr. Work around by renaming the static version and use macros
+ for renaming.
+
+Tue Jun 18 20:11:17 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c: Correct presence test macros of __argz_* functions.
+
+ * l10nflist.c: Include <argz.h> based on test of it instead when
+ __argz_* functions are available.
+ Reported by Andreas Schwab.
+
+Thu Jun 13 15:17:44 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * explodename.c, l10nflist.c: Define NULL for dumb systems.
+
+Tue Jun 11 17:05:13 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in, libgettext.h (dcgettext): Rename local variable
+ result to __result to prevent name clash.
+
+ * l10nflist.c, localealias.c, dcgettext.c: Define _GNU_SOURCE to
+ get prototype for stpcpy and strcasecmp.
+
+ * intlh.inst.in, libgettext.h: Move declaration of
+ `_nl_msg_cat_cntr' outside __extension__ block to prevent warning
+ from gcc's -Wnested-extern option.
+
+Fri Jun 7 01:58:00 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install): Remove comment.
+
+Thu Jun 6 17:28:17 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (install): Work around for another Buglix stupidity.
+ Always use an `else' close for `if's. Reported by Nelson Beebe.
+
+ * Makefile.in (intlh.inst): Correct typo in phony rule.
+ Reported by Nelson Beebe.
+
+Thu Jun 6 01:49:52 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * dcgettext.c (read_alias_file): Rename variable alloca_list to
+ block_list as the macro calls assume.
+ Patch by Eric Backus.
+
+ * localealias.c [!HAVE_ALLOCA]: Define alloca as macro using
+ malloc.
+ (read_alias_file): Rename varriabe alloca_list to block_list as the
+ macro calls assume.
+ Patch by Eric Backus.
+
+ * l10nflist.c: Correct conditional for <argz.h> inclusion.
+ Reported by Roland McGrath.
+
+ * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not
+ all-@USE_NLS@.
+
+ * Makefile.in (install): intlh.inst comes from local dir, not
+ $(srcdir).
+
+ * Makefile.in (intlh.inst): Special handling of this goal. If
+ used in gettext, this is really a rul to construct this file. If
+ used in any other package it is defined as a .PHONY rule with
+ empty body.
+
+ * finddomain.c: Extract locale file information handling into
+ l10nfile.c. Rename local stpcpy__ function to stpcpy.
+
+ * dcgettext.c (stpcpy): Add local definition.
+
+ * l10nflist.c: Solve some portability problems. Patches partly by
+ Thomas Esken. Add local definition of stpcpy.
+
+Tue Jun 4 02:47:49 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * intlh.inst.in: Don't depend including <locale.h> on
+ HAVE_LOCALE_H. Instead configure must rewrite this fiile
+ depending on the result of the configure run.
+
+ * Makefile.in (install): libintl.inst is now called intlh.inst.
+ Add rules for updating intlh.inst from intlh.inst.in.
+
+ * libintl.inst: Renamed to intlh.inst.in.
+
+ * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1
+ because gcc has __buitlin_alloca.
+ Reported by Roland McGrath.
+
+Mon Jun 3 00:32:16 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.in (installcheck): New goal to fulfill needs of
+ automake's distcheck.
+
+ * Makefile.in (install): Reorder commands so that VERSION is
+ found.
+
+ * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in
+ @datadir@/gettext.
+ (COMSRCS): Add l10nfile.c.
+ (OBJECTS): Add l10nfile.o.
+ (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common).
+ (DISTFILE.gettext): Remove $(DISTFILES.common).
+ (all-gettext): Remove goal.
+ (install): If $(PACKAGE) = gettext install, otherwose do nothing. No
+ package but gettext itself should install libintl.h + headers.
+ (dist): Extend goal to work for gettext, too.
+ (dist-gettext): Remove goal.
+
+ * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc.
+
+Sun Jun 2 17:33:06 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * loadmsgcat.c (_nl_load_domain): Parameter is now comes from
+ find_l10nfile.
+
+Sat Jun 1 02:23:03 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * l10nflist.c (__argz_next): Add definition.
+
+ * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca
+ code. Use new l10nfile handling.
+
+ * localealias.c [!HAVE_ALLOCA]: Add code for handling missing
+ alloca code.
+
+ * l10nflist.c: Initial revision.
+
+Tue Apr 2 18:51:18 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all-gettext): New goal. Same as all-yes.
+
+Thu Mar 28 23:01:22 1996 Karl Eichwalder <ke@ke.central.de>
+
+ * Makefile.in (gettextsrcdir): Define using @datadir@.
+
+Tue Mar 26 12:39:14 1996 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c: Include <ctype.h>. Reported by Roland McGrath.
+
+Sat Mar 23 02:00:35 1996 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (stpcpy): Rename to stpcpy__ to prevent clashing
+ with external declaration.
+
+Sat Mar 2 00:47:09 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all-no): Rename from all_no.
+
+Sat Feb 17 00:25:59 1996 Ulrich Drepper <drepper@myware>
+
+ * gettextP.h [loaded_domain]: Array `successor' must now contain up
+ to 63 elements (because of codeset name normalization).
+
+ * finddomain.c: Implement codeset name normalization.
+
+Thu Feb 15 04:39:09 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all): Define to `all-@USE_NLS@'.
+ (all-yes, all_no): New goals. `all-no' is noop, `all-yes'
+ is former all.
+
+Mon Jan 15 21:46:01 1996 Howard Gayle <howard@hal.com>
+
+ * localealias.c (alias_compare): Increment string pointers in loop
+ of strcasecmp replacement.
+
+Fri Dec 29 21:16:34 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src): Who commented this goal out ? :-)
+
+Fri Dec 29 15:08:16 1995 Ulrich Drepper <drepper@myware>
+
+ * dcgettext.c (DCGETTEXT): Save `errno'. Failing system calls
+ should not effect it because a missing catalog is no error.
+ Reported by Harald K<o:>nig <koenig@tat.physik.uni-tuebingen.de>.
+
+Tue Dec 19 22:09:13 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (Makefile): Explicitly use $(SHELL) for running
+ shell scripts.
+
+Fri Dec 15 17:34:59 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Makefile.in (install-src): Only install library and header when
+ we use the own implementation. Don't do it when using the
+ system's gettext or catgets functions.
+
+ * dcgettext.c (find_msg): Must not swap domain->hash_size here.
+
+Sat Dec 9 16:24:37 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c, libintl.inst, libgettext.h, hash-string.h,
+ gettextP.h, finddomain.c, dcgettext.c, cat-compat.c:
+ Use PARAMS instead of __P. Suggested by Roland McGrath.
+
+Tue Dec 5 11:39:14 1995 Larry Schwimmer <rosebud@cyclone.stanford.edu>
+
+ * libgettext.h: Use `#if !defined (_LIBINTL_H)' instead of `#if
+ !_LIBINTL_H' because Solaris defines _LIBINTL_H as empty.
+
+Mon Dec 4 15:42:07 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src):
+ Install libintl.inst instead of libintl.h.install.
+
+Sat Dec 2 22:51:38 1995 Marcus Daniels <marcus@sysc.pdx.edu>
+
+ * cat-compat.c (textdomain):
+ Reverse order in which files are tried you load. First
+ try local file, when this failed absolute path.
+
+Wed Nov 29 02:03:53 1995 Nelson H. F. Beebe <beebe@math.utah.edu>
+
+ * cat-compat.c (bindtextdomain): Add missing { }.
+
+Sun Nov 26 18:21:41 1995 Ulrich Drepper <drepper@myware>
+
+ * libintl.inst: Add missing __P definition. Reported by Nelson Beebe.
+
+ * Makefile.in:
+ Add dummy `all' and `dvi' goals. Reported by Tom Tromey.
+
+Sat Nov 25 16:12:01 1995 Franc,ois Pinard <pinard@iro.umontreal.ca>
+
+ * hash-string.h: Capitalize arguments of macros.
+
+Sat Nov 25 12:01:36 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Prevent files names longer than 13
+ characters. libintl.h.glibc->libintl.glibc,
+ libintl.h.install->libintl.inst. Reported by Joshua R. Poulson.
+
+Sat Nov 25 11:31:12 1995 Eric Backus <ericb@lsid.hp.com>
+
+ * dcgettext.c: Fix bug in preprocessor conditionals.
+
+Sat Nov 25 02:35:27 1995 Nelson H. F. Beebe <beebe@math.utah.edu>
+
+ * libgettext.h: Solaris cc does not understand
+ #if !SYMBOL1 && !SYMBOL2. Sad but true.
+
+Thu Nov 23 16:22:14 1995 Ulrich Drepper <drepper@myware>
+
+ * hash-string.h (hash_string):
+ Fix for machine with >32 bit `unsigned long's.
+
+ * dcgettext.c (DCGETTEXT):
+ Fix horrible bug in loop for alternative translation.
+
+Thu Nov 23 01:45:29 1995 Ulrich Drepper <drepper@myware>
+
+ * po2tbl.sed.in, linux-msg.sed, xopen-msg.sed:
+ Some further simplifications in message number generation.
+
+Mon Nov 20 21:08:43 1995 Ulrich Drepper <drepper@myware>
+
+ * libintl.h.glibc: Use __const instead of const in prototypes.
+
+ * Makefile.in (install-src):
+ Install libintl.h.install instead of libintl.h. This
+ is a stripped-down version. Suggested by Peter Miller.
+
+ * libintl.h.install, libintl.h.glibc: Initial revision.
+
+ * localealias.c (_nl_expand_alias, read_alias_file):
+ Protect prototypes in type casts by __P.
+
+Tue Nov 14 16:43:58 1995 Ulrich Drepper <drepper@myware>
+
+ * hash-string.h: Correct prototype for hash_string.
+
+Sun Nov 12 12:42:30 1995 Ulrich Drepper <drepper@myware>
+
+ * hash-string.h (hash_string): Add prototype.
+
+ * gettextP.h: Fix copyright.
+ (SWAP): Add prototype.
+
+Wed Nov 8 22:56:33 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (read_alias_file): Forgot sizeof.
+ Avoid calling *printf function. This introduces a big overhead.
+ Patch by Roland McGrath.
+
+Tue Nov 7 14:21:08 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c, cat-compat.c: Wrong indentation in #if for stpcpy.
+
+ * finddomain.c (stpcpy):
+ Define substitution function local. The macro was to flaky.
+
+ * cat-compat.c: Fix typo.
+
+ * xopen-msg.sed, linux-msg.sed:
+ While bringing message number to right place only accept digits.
+
+ * linux-msg.sed, xopen-msg.sed: Now that the counter does not have
+ leading 0s we don't need to remove them. Reported by Marcus
+ Daniels.
+
+ * Makefile.in (../po/cat-id-tbl.o): Use $(top_srdir) in
+ dependency. Reported by Marcus Daniels.
+
+ * cat-compat.c: (stpcpy) [!_LIBC && !HAVE_STPCPY]: Define replacement.
+ Generally cleanup using #if instead of #ifndef.
+
+ * Makefile.in: Correct typos in comment. By Franc,ois Pinard.
+
+Mon Nov 6 00:27:02 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src): Don't install libintl.h and libintl.a
+ if we use an available gettext implementation.
+
+Sun Nov 5 22:02:08 1995 Ulrich Drepper <drepper@myware>
+
+ * libgettext.h: Fix typo: HAVE_CATGETTS -> HAVE_CATGETS. Reported
+ by Franc,ois Pinard.
+
+ * libgettext.h: Use #if instead of #ifdef/#ifndef.
+
+ * finddomain.c:
+ Comments describing what has to be done should start with FIXME.
+
+Sun Nov 5 19:38:01 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Split. Use DISTFILES with normal meaning.
+ DISTFILES.common names the files common to both dist goals.
+ DISTFILES.gettext are the files only distributed in GNU gettext.
+
+Sun Nov 5 17:32:54 1995 Ulrich Drepper <drepper@myware>
+
+ * dcgettext.c (DCGETTEXT): Correct searching in derived locales.
+ This was necessary since a change in _nl_find_msg several weeks
+ ago. I really don't know this is still not fixed.
+
+Sun Nov 5 12:43:12 1995 Ulrich Drepper <drepper@myware>
+
+ * loadmsgcat.c (_nl_load_domain): Test for FILENAME == NULL. This
+ might mark a special condition.
+
+ * finddomain.c (make_entry_rec): Don't make illegal entry as decided.
+
+ * Makefile.in (dist): Suppress error message when ln failed.
+ Get files from $(srcdir) explicitly.
+
+ * libgettext.h (gettext_const): Rename to gettext_noop.
+
+Fri Nov 3 07:36:50 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (make_entry_rec):
+ Protect against wrong locale names by testing mask.
+
+ * libgettext.h (gettext_const): Add macro definition.
+ Capitalize macro arguments.
+
+Thu Nov 2 23:15:51 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (_nl_find_domain):
+ Test for pointer != NULL before accessing value.
+ Reported by Tom Tromey.
+
+ * gettext.c (NULL):
+ Define as (void*)0 instad of 0. Reported by Franc,ois Pinard.
+
+Mon Oct 30 21:28:52 1995 Ulrich Drepper <drepper@myware>
+
+ * po2tbl.sed.in: Serious typo bug fixed by Jim Meyering.
+
+Sat Oct 28 23:20:47 1995 Ulrich Drepper <drepper@myware>
+
+ * libgettext.h: Disable dcgettext optimization for Solaris 2.3.
+
+ * localealias.c (alias_compare):
+ Peter Miller reported that tolower in some systems is
+ even dumber than I thought. Protect call by `isupper'.
+
+Fri Oct 27 22:22:51 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (libdir, includedir): New variables.
+ (install-src): Install libintl.a and libintl.h in correct dirs.
+
+Fri Oct 27 22:07:29 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (SOURCES): Fix typo: intrl.compat.c -> intl-compat.c.
+
+ * po2tbl.sed.in: Patch for buggy SEDs by Christian von Roques.
+
+ * localealias.c:
+ Fix typo and superflous test. Reported by Christian von Roques.
+
+Fri Oct 6 11:52:05 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (_nl_find_domain):
+ Correct some remainder from the pre-CEN syntax. Now
+ we don't have a constant number of successors anymore.
+
+Wed Sep 27 21:41:13 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Add libintl.h.glibc.
+
+ * Makefile.in (dist-libc): Add goal for packing sources for glibc.
+ (COMSRCS, COMHDRS): Splitted to separate sources shared with glibc.
+
+ * loadmsgcat.c: Forget to continue #if line.
+
+ * localealias.c:
+ [_LIBC]: Rename strcasecmp to __strcasecmp to keep ANSI C name
+ space clean.
+
+ * dcgettext.c, finddomain.c: Better comment to last change.
+
+ * loadmsgcat.c:
+ [_LIBC]: Rename fstat, open, close, read, mmap, and munmap to
+ __fstat, __open, __close, __read, __mmap, and __munmap resp
+ to keep ANSI C name space clean.
+
+ * finddomain.c:
+ [_LIBC]: Rename stpcpy to __stpcpy to keep ANSI C name space clean.
+
+ * dcgettext.c:
+ [_LIBC]: Rename getced and stpcpy to __getcwd and __stpcpy resp to
+ keep ANSI C name space clean.
+
+ * libgettext.h:
+ Include sys/types.h for those old SysV systems out there.
+ Reported by Francesco Potorti`.
+
+ * loadmsgcat.c (use_mmap): Define if compiled for glibc.
+
+ * bindtextdom.c: Include all those standard headers
+ unconditionally if _LIBC is defined.
+
+ * finddomain.c: Fix 2 times defiend -> defined.
+
+ * textdomain.c: Include libintl.h instead of libgettext.h when
+ compiling for glibc. Include all those standard headers
+ unconditionally if _LIBC is defined.
+
+ * localealias.c, loadmsgcat.c: Prepare to be compiled in glibc.
+
+ * gettext.c:
+ Include libintl.h instead of libgettext.h when compiling for glibc.
+ Get NULL from stddef.h if we compile for glibc.
+
+ * finddomain.c: Include libintl.h instead of libgettext.h when
+ compiling for glibc. Include all those standard headers
+ unconditionally if _LIBC is defined.
+
+ * dcgettext.c: Include all those standard headers unconditionally
+ if _LIBC is defined.
+
+ * dgettext.c: If compiled in glibc include libintl.h instead of
+ libgettext.h.
+ (locale.h): Don't rely on HAVE_LOCALE_H when compiling for glibc.
+
+ * dcgettext.c: If compiled in glibc include libintl.h instead of
+ libgettext.h.
+ (getcwd): Don't rely on HAVE_GETCWD when compiling for glibc.
+
+ * bindtextdom.c:
+ If compiled in glibc include libintl.h instead of libgettext.h.
+
+Mon Sep 25 22:23:06 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (_nl_expand_alias): Don't call bsearch if NMAP <= 0.
+ Reported by Marcus Daniels.
+
+ * cat-compat.c (bindtextdomain):
+ String used in putenv must not be recycled.
+ Reported by Marcus Daniels.
+
+ * libgettext.h (__USE_GNU_GETTEXT):
+ Additional symbol to signal that we use GNU gettext
+ library.
+
+ * cat-compat.c (bindtextdomain):
+ Fix bug with the strange stpcpy replacement.
+ Reported by Nelson Beebe.
+
+Sat Sep 23 08:23:51 1995 Ulrich Drepper <drepper@myware>
+
+ * cat-compat.c: Include <string.h> for stpcpy prototype.
+
+ * localealias.c (read_alias_file):
+ While expand strdup code temporary variable `cp' hided
+ higher level variable with same name. Rename to `tp'.
+
+ * textdomain.c (textdomain):
+ Avoid warning by using temporary variable in strdup code.
+
+ * finddomain.c (_nl_find_domain): Remove unused variable `application'.
+
+Thu Sep 21 15:51:44 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (alias_compare):
+ Use strcasecmp() only if available. Else use
+ implementation in place.
+
+ * intl-compat.c:
+ Wrapper functions now call *__ functions instead of __*.
+
+ * libgettext.h: Declare prototypes for *__ functions instead for __*.
+
+ * cat-compat.c, loadmsgcat.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+
+ * bindtextdom.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+ Rename to bindtextdomain__ if not used in GNU C Library.
+
+ * dgettext.c:
+ Rename function to dgettext__ if not used in GNU C Library.
+
+ * gettext.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+ Functions now called gettext__ if not used in GNU C Library.
+
+ * dcgettext.c, localealias.c, textdomain.c, finddomain.c:
+ Don't use xmalloc, xstrdup, and stpcpy. These functions are not part
+ of the standard libc and so prevent libintl.a from being used
+ standalone.
+
+Sun Sep 17 23:14:49 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c: Correct some bugs in handling of CEN standard
+ locale definitions.
+
+Thu Sep 7 01:49:28 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c: Implement CEN syntax.
+
+ * gettextP.h (loaded_domain): Extend number of successors to 31.
+
+Sat Aug 19 19:25:29 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (aliaspath): Remove path to X11 locale dir.
+
+ * Makefile.in: Make install-src depend on install. This helps
+ gettext to install the sources and other packages can use the
+ install goal.
+
+Sat Aug 19 15:19:33 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (uninstall): Remove stuff installed by install-src.
+
+Tue Aug 15 13:13:53 1995 Ulrich Drepper <drepper@myware>
+
+ * VERSION.in: Initial revision.
+
+ * Makefile.in (DISTFILES):
+ Add VERSION file. This is not necessary for gettext, but
+ for other packages using this library.
+
+Tue Aug 15 06:16:44 1995 Ulrich Drepper <drepper@myware>
+
+ * gettextP.h (_nl_find_domain):
+ New prototype after changing search strategy.
+
+ * finddomain.c (_nl_find_domain):
+ We now try only to find a specified catalog. Fall back to other
+ catalogs listed in the locale list is now done in __dcgettext.
+
+ * dcgettext.c (__dcgettext):
+ Now we provide message fall back even to different languages.
+ I.e. if a message is not available in one language all the other
+ in the locale list a tried. Formerly fall back was only possible
+ within one language. Implemented by moving one loop from
+ _nl_find_domain to here.
+
+Mon Aug 14 23:45:50 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (gettextsrcdir):
+ Directory where source of GNU gettext library are made
+ available.
+ (INSTALL, INSTALL_DATA): Programs used for installing sources.
+ (gettext-src): New. Rule to install GNU gettext sources for use in
+ gettextize shell script.
+
+Sun Aug 13 14:40:48 1995 Ulrich Drepper <drepper@myware>
+
+ * loadmsgcat.c (_nl_load_domain):
+ Use mmap for loading only when munmap function is
+ also available.
+
+ * Makefile.in (install): Depend on `all' goal.
+
+Wed Aug 9 11:04:33 1995 Ulrich Drepper <drepper@myware>
+
+ * localealias.c (read_alias_file):
+ Do not overwrite '\n' when terminating alias value string.
+
+ * localealias.c (read_alias_file):
+ Handle long lines. Ignore the rest not fitting in
+ the buffer after the initial `fgets' call.
+
+Wed Aug 9 00:54:29 1995 Ulrich Drepper <drepper@myware>
+
+ * gettextP.h (_nl_load_domain):
+ Add prototype, replacing prototype for _nl_load_msg_cat.
+
+ * finddomain.c (_nl_find_domain):
+ Remove unneeded variable filename and filename_len.
+ (expand_alias): Remove prototype because functions does not
+ exist anymore.
+
+ * localealias.c (read_alias_file):
+ Change type of fname_len parameter to int.
+ (xmalloc): Add prototype.
+
+ * loadmsgcat.c: Better prototypes for xmalloc.
+
+Tue Aug 8 22:30:39 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (_nl_find_domain):
+ Allow alias name to be constructed from the four components.
+
+ * Makefile.in (aliaspath): New variable. Set to preliminary value.
+ (SOURCES): Add localealias.c.
+ (OBJECTS): Add localealias.o.
+
+ * gettextP.h: Add prototype for _nl_expand_alias.
+
+ * finddomain.c: Aliasing handled in intl/localealias.c.
+
+ * localealias.c: Aliasing for locale names.
+
+ * bindtextdom.c: Better prototypes for xmalloc and xstrdup.
+
+Mon Aug 7 23:47:42 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): gettext.perl is now found in misc/.
+
+ * cat-compat.c (bindtextdomain):
+ Correct implementation. dirname parameter was not used.
+ Reported by Marcus Daniels.
+
+ * gettextP.h (loaded_domain):
+ New fields `successor' and `decided' for oo, lazy
+ message handling implementation.
+
+ * dcgettext.c:
+ Adopt for oo, lazy message handliing.
+ Now we can inherit translations from less specific locales.
+ (find_msg): New function.
+
+ * loadmsgcat.c, finddomain.c:
+ Complete rewrite. Implement oo, lazy message handling :-).
+ We now have an additional environment variable `LANGUAGE' with
+ a higher priority than LC_ALL for the LC_MESSAGE locale.
+ Here we can set a colon separated list of specifications each
+ of the form `language[_territory[.codeset]][@modifier]'.
+
+Sat Aug 5 09:55:42 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (unistd.h):
+ Include to get _PC_PATH_MAX defined on system having it.
+
+Fri Aug 4 22:42:00 1995 Ulrich Drepper <drepper@myware>
+
+ * finddomain.c (stpcpy): Include prototype.
+
+ * Makefile.in (dist): Remove `copying instead' message.
+
+Wed Aug 2 18:52:03 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (ID, TAGS): Do not use $^.
+
+Tue Aug 1 20:07:11 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (TAGS, ID): Use $^ as command argument.
+ (TAGS): Give etags -o option t write to current directory,
+ not $(srcdir).
+ (ID): Use $(srcdir) instead os $(top_srcdir)/src.
+ (distclean): Remove ID.
+
+Sun Jul 30 11:51:46 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (gnulocaledir):
+ New variable, always using share/ for data directory.
+ (DEFS): Add GNULOCALEDIR, used in finddomain.c.
+
+ * finddomain.c (_nl_default_dirname):
+ Set to GNULOCALEDIR, because it always has to point
+ to the directory where GNU gettext Library writes it to.
+
+ * intl-compat.c (textdomain, bindtextdomain):
+ Undefine macros before function definition.
+
+Sat Jul 22 01:10:02 1995 Ulrich Drepper <drepper@myware>
+
+ * libgettext.h (_LIBINTL_H):
+ Protect definition in case where this file is included as
+ libgettext.h on Solaris machines. Add comment about this.
+
+Wed Jul 19 02:36:42 1995 Ulrich Drepper <drepper@myware>
+
+ * intl-compat.c (textdomain): Correct typo.
+
+Wed Jul 19 01:51:35 1995 Ulrich Drepper <drepper@myware>
+
+ * dcgettext.c (dcgettext): Function now called __dcgettext.
+
+ * dgettext.c (dgettext): Now called __dgettext and calls
+ __dcgettext.
+
+ * gettext.c (gettext):
+ Function now called __gettext and calls __dgettext.
+
+ * textdomain.c (textdomain): Function now called __textdomain.
+
+ * bindtextdom.c (bindtextdomain): Function now called
+ __bindtextdomain.
+
+ * intl-compat.c: Initial revision.
+
+ * Makefile.in (SOURCES): Add intl-compat.c.
+ (OBJECTS): We always compile the GNU gettext library functions.
+ OBJECTS contains all objects but cat-compat.o, ../po/cat-if-tbl.o,
+ and intl-compat.o.
+ (GETTOBJS): Contains now only intl-compat.o.
+
+ * libgettext.h:
+ Re-include protection matches dualistic character of libgettext.h.
+ For all functions in GNU gettext library define __ counter part.
+
+ * finddomain.c (strchr): Define as index if not found in C library.
+ (_nl_find_domain): For relative paths paste / in between.
+
+Tue Jul 18 16:37:45 1995 Ulrich Drepper <drepper@myware>
+
+ * loadmsgcat.c, finddomain.c: Add inclusion of sys/types.h.
+
+ * xopen-msg.sed: Fix bug with `msgstr ""' lines.
+ A little bit better comments.
+
+Tue Jul 18 01:18:27 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in:
+ po-mode.el, makelinks, combine-sh are now found in ../misc.
+
+ * po-mode.el, makelinks, combine-sh, elisp-comp:
+ Moved to ../misc/.
+
+ * libgettext.h, gettextP.h, gettext.h: Uniform test for __STDC__.
+
+Sun Jul 16 22:33:02 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (INSTALL, INSTALL_DATA): New variables.
+ (install-data, uninstall): Install/uninstall .elc file.
+
+ * po-mode.el (Installation comment):
+ Add .pox as possible extension of .po files.
+
+Sun Jul 16 13:23:27 1995 Ulrich Drepper <drepper@myware>
+
+ * elisp-comp: Complete new version by Franc,ois: This does not
+ fail when not compiling in the source directory.
+
+Sun Jul 16 00:12:17 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (../po/cat-id-tbl.o):
+ Use $(MAKE) instead of make for recursive make.
+
+ * Makefile.in (.el.elc): Use $(SHELL) instead of /bin/sh.
+ (install-exec): Add missing dummy goal.
+ (install-data, uninstall): @ in multi-line shell command at
+ beginning, not in front of echo. Reported by Eric Backus.
+
+Sat Jul 15 00:21:28 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES):
+ Rename libgettext.perl to gettext.perl to fit in 14 chars
+ file systems.
+
+ * gettext.perl:
+ Rename to gettext.perl to fit in 14 chars file systems.
+
+Thu Jul 13 23:17:20 1995 Ulrich Drepper <drepper@myware>
+
+ * cat-compat.c: If !STDC_HEADERS try to include malloc.h.
+
+Thu Jul 13 20:55:02 1995 Ulrich Drepper <drepper@myware>
+
+ * po2tbl.sed.in: Pretty printing.
+
+ * linux-msg.sed, xopen-msg.sed:
+ Correct bugs with handling substitute flags in branches.
+
+ * hash-string.h (hash_string):
+ Old K&R compilers don't under stand `unsigned char'.
+
+ * gettext.h (nls_uint32):
+ Some old K&R compilers (eg HP) don't understand `unsigned int'.
+
+ * cat-compat.c (msg_to_cat_id): De-ANSI-fy prototypes.
+
+Thu Jul 13 01:34:33 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (ELCFILES): New variable.
+ (DISTFILES): Add elisp-comp.
+ Add implicit rule for .el -> .elc compilation.
+ (install-data): install $ELCFILES
+ (clean): renamed po-to-tbl and po-to-msg to po2tbl and po2msg resp.
+
+ * elisp-comp: Initial revision
+
+Wed Jul 12 16:14:52 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in:
+ cat-id-tbl.c is now found in po/. This enables us to use an identical
+ intl/ directory in all packages.
+
+ * dcgettext.c (dcgettext): hashing does not work for table size <= 2.
+
+ * textdomain.c: fix typo (#if def -> #if defined)
+
+Tue Jul 11 18:44:43 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (stamp-cat-id): use top_srcdir to address source files
+ (DISTFILES,distclean): move tupdate.perl to src/
+
+ * po-to-tbl.sed.in:
+ add additional jump to clear change flag to recognize multiline strings
+
+Tue Jul 11 01:32:50 1995 Ulrich Drepper <drepper@myware>
+
+ * textdomain.c: Protect inclusion of stdlib.h and string.h.
+
+ * loadmsgcat.c: Protect inclusion of stdlib.h.
+
+ * libgettext.h: Protect inclusion of locale.h.
+ Allow use in C++ programs.
+ Define NULL is not happened already.
+
+ * Makefile.in (DISTFILES): ship po-to-tbl.sed.in instead of
+ po-to-tbl.sed.
+ (distclean): remove po-to-tbl.sed and tupdate.perl.
+
+ * tupdate.perl.in: Substitute Perl path even in exec line.
+ Don't include entries without translation from old .po file.
+
+Tue Jul 4 00:41:51 1995 Ulrich Drepper <drepper@myware>
+
+ * tupdate.perl.in: use "Updated: " in msgid "".
+
+ * cat-compat.c: Fix typo (LOCALDIR -> LOCALEDIR).
+ Define getenv if !__STDC__.
+
+ * bindtextdom.c: Protect stdlib.h and string.h inclusion.
+ Define free if !__STDC__.
+
+ * finddomain.c: Change DEF_MSG_DOM_DIR to LOCALEDIR.
+ Define free if !__STDC__.
+
+ * cat-compat.c: Change DEF_MSG_DOM_DIR to LOCALEDIR.
+
+Mon Jul 3 23:56:30 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in: Use LOCALEDIR instead of DEF_MSG_DOM_DIR.
+ Remove unneeded $(srcdir) from Makefile.in dependency.
+
+ * makelinks: Add copyright and short description.
+
+ * po-mode.el: Last version for 0.7.
+
+ * tupdate.perl.in: Fix die message.
+
+ * dcgettext.c: Protect include of string.h.
+
+ * gettext.c: Protect include of stdlib.h and further tries to get NULL.
+
+ * finddomain.c: Some corrections in includes.
+
+ * Makefile.in (INCLUDES): Prune list correct path to Makefile.in.
+
+ * po-to-tbl.sed: Adopt for new .po file format.
+
+ * linux-msg.sed, xopen-msg.sed: Adopt for new .po file format.
+
+Sun Jul 2 23:55:03 1995 Ulrich Drepper <drepper@myware>
+
+ * tupdate.perl.in: Complete rewrite for new .po file format.
+
+Sun Jul 2 02:06:50 1995 Ulrich Drepper <drepper@myware>
+
+ * First official release. This directory contains all the code
+ needed to internationalize own packages. It provides functions
+ which allow to use the X/Open catgets function with an interface
+ like the Uniforum gettext function. For system which does not
+ have neither of those a complete implementation is provided.
diff --git a/intl/ChangeLog.Cygnus b/intl/ChangeLog.Cygnus
new file mode 100644
index 00000000000..6d32da6bba1
--- /dev/null
+++ b/intl/ChangeLog.Cygnus
@@ -0,0 +1,30 @@
+Tue May 26 18:29:09 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Remove config.log.
+
+Sun May 10 22:35:54 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Makefile.in (install-info): New target.
+
+Sun Apr 19 19:20:00 1998 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Rebuilt.
+ * configure.in: Call AC_LINK_FILES so that <libintl.h> will
+ always exist.
+
+Fri Mar 27 16:37:25 1998 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Rebuilt with new cygettext.m4.
+
+Wed Mar 25 15:00:14 1998 Tom Tromey <tromey@cygnus.com>
+
+ * configure.in: Build config.h from config.in.
+ * config.h.in: Removed.
+ * config.in: New file.
+
+ * config.h.in: New file.
+
+ * configure.in, configure, acconfig.h, aclocal.m4: New files.
+ * Makefile.in (OBJECTS): Depend on config.h, not ../config.h.
+ (Makefile): Rebuild Makefile here, not in `..'.
+
diff --git a/intl/Makefile.in b/intl/Makefile.in
new file mode 100644
index 00000000000..09647ded8eb
--- /dev/null
+++ b/intl/Makefile.in
@@ -0,0 +1,214 @@
+# Makefile for directory with message catalog handling in GNU NLS Utilities.
+# Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+#
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = ..
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+transform = @program_transform_name@
+libdir = $(exec_prefix)/lib
+includedir = $(prefix)/include
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = @datadir@/gettext/intl
+aliaspath = $(localedir):.
+subdir = intl
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+l = @l@
+
+AR = ar
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+RANLIB = @RANLIB@
+
+DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \
+-DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@
+CPPFLAGS = @CPPFLAGS@
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+HEADERS = $(COMHDRS) libgettext.h loadinfo.h
+COMHDRS = gettext.h gettextP.h hash-string.h
+SOURCES = $(COMSRCS) intl-compat.c cat-compat.c
+COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \
+finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \
+explodename.c
+OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \
+finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \
+explodename.$lo
+CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo
+GETTOBJS = intl-compat.$lo
+DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \
+xopen-msg.sed $(HEADERS) $(SOURCES)
+DISTFILES.normal = VERSION
+DISTFILES.gettext = libintl.glibc intlh.inst.in
+
+.SUFFIXES:
+.SUFFIXES: .c .o .lo
+.c.o:
+ $(COMPILE) $<
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) $<
+
+INCLUDES = -I. -I$(srcdir)
+
+all: all-@USE_INCLUDED_LIBINTL@
+
+all-yes: libintl.$la intlh.inst
+all-no:
+install-info:
+
+libintl.a: $(OBJECTS)
+ rm -f $@
+ $(AR) cru $@ $(OBJECTS)
+ $(RANLIB) $@
+
+libintl.la: $(OBJECTS)
+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \
+ -version-info 1:0 -rpath $(libdir)
+
+../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot
+ cd ../po && $(MAKE) cat-id-tbl.$lo
+
+check: all
+
+# This installation goal is only used in GNU gettext. Packages which
+# only use the library should use install instead.
+
+# We must not install the libintl.h/libintl.a files if we are on a
+# system which has the gettext() function in its C library or in a
+# separate library or use the catgets interface. A special case is
+# where configure found a previously installed GNU gettext library.
+# If you want to use the one which comes with this version of the
+# package, you have to use `configure --with-included-gettext'.
+install: install-exec install-data
+install-exec: all
+ if test "$(PACKAGE)" = "gettext" \
+ && test '@INTLOBJS@' = '$(GETTOBJS)'; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(libdir) $(includedir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \
+ fi; \
+ $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \
+ $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \
+ else \
+ : ; \
+ fi
+install-data: all
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \
+ dists="$(DISTFILES.common)"; \
+ for file in $$dists; do \
+ $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ dists="$(DISTFILES.common)"; \
+ for file in $$dists; do \
+ rm -f $(gettextsrcdir)/$$file; \
+ done
+
+info dvi:
+
+$(OBJECTS): config.h libgettext.h
+bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h
+dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h
+
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES)
+ here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES)
+
+id: ID
+
+ID: $(HEADERS) $(SOURCES)
+ here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES)
+
+
+mostlyclean:
+ rm -f *.a *.o *.lo core core.*
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile ID TAGS po2msg.sed po2tbl.sed libintl.h config.log
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+
+# GNU gettext needs not contain the file `VERSION' but contains some
+# other files which should not be distributed in other packages.
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: Makefile $(DISTFILES)
+ if test "$(PACKAGE)" = gettext; then \
+ additional="$(DISTFILES.gettext)"; \
+ else \
+ additional="$(DISTFILES.normal)"; \
+ fi; \
+ for file in $(DISTFILES.common) $$additional; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+dist-libc:
+ tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc
+
+Makefile: Makefile.in config.status
+ CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# The dependency for intlh.inst is different in gettext and all other
+# packages. Because we cannot you GNU make features we have to solve
+# the problem while rewriting Makefile.in.
+@GT_YES@intlh.inst: intlh.inst.in ../config.status
+@GT_YES@ cd .. \
+@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \
+@GT_YES@ $(SHELL) ./config.status
+@GT_NO@.PHONY: intlh.inst
+@GT_NO@intlh.inst:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/intl/acconfig.h b/intl/acconfig.h
new file mode 100644
index 00000000000..70f81f80898
--- /dev/null
+++ b/intl/acconfig.h
@@ -0,0 +1,14 @@
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
diff --git a/intl/aclocal.m4 b/intl/aclocal.m4
new file mode 100644
index 00000000000..225439f2125
--- /dev/null
+++ b/intl/aclocal.m4
@@ -0,0 +1,387 @@
+dnl aclocal.m4 generated automatically by aclocal 1.3
+
+dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+dnl This Makefile.in is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS)
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT)
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY)
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES)
+ fi
+ fi])
+
diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c
new file mode 100644
index 00000000000..9fcb8d9f29b
--- /dev/null
+++ b/intl/bindtextdom.c
@@ -0,0 +1,199 @@
+/* Implementation of the bindtextdomain(3) function
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+#include "gettext.h"
+#include "gettextP.h"
+
+/* @@ end of prolog @@ */
+
+/* Contains the default location of the message catalogs. */
+extern const char _nl_default_dirname[];
+
+/* List with bindings of specific domains. */
+extern struct binding *_nl_domain_bindings;
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define BINDTEXTDOMAIN __bindtextdomain
+# define strdup(str) __strdup (str)
+#else
+# define BINDTEXTDOMAIN bindtextdomain__
+#endif
+
+/* Specify that the DOMAINNAME message catalog will be found
+ in DIRNAME rather than in the system locale data base. */
+char *
+BINDTEXTDOMAIN (domainname, dirname)
+ const char *domainname;
+ const char *dirname;
+{
+ struct binding *binding;
+
+ /* Some sanity checks. */
+ if (domainname == NULL || domainname[0] == '\0')
+ return NULL;
+
+ for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
+ {
+ int compare = strcmp (domainname, binding->domainname);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It is not in the list. */
+ binding = NULL;
+ break;
+ }
+ }
+
+ if (dirname == NULL)
+ /* The current binding has be to returned. */
+ return binding == NULL ? (char *) _nl_default_dirname : binding->dirname;
+
+ if (binding != NULL)
+ {
+ /* The domain is already bound. If the new value and the old
+ one are equal we simply do nothing. Otherwise replace the
+ old binding. */
+ if (strcmp (dirname, binding->dirname) != 0)
+ {
+ char *new_dirname;
+
+ if (strcmp (dirname, _nl_default_dirname) == 0)
+ new_dirname = (char *) _nl_default_dirname;
+ else
+ {
+#if defined _LIBC || defined HAVE_STRDUP
+ new_dirname = strdup (dirname);
+ if (new_dirname == NULL)
+ return NULL;
+#else
+ size_t len = strlen (dirname) + 1;
+ new_dirname = (char *) malloc (len);
+ if (new_dirname == NULL)
+ return NULL;
+
+ memcpy (new_dirname, dirname, len);
+#endif
+ }
+
+ if (binding->dirname != _nl_default_dirname)
+ free (binding->dirname);
+
+ binding->dirname = new_dirname;
+ }
+ }
+ else
+ {
+ /* We have to create a new binding. */
+ size_t len;
+ struct binding *new_binding =
+ (struct binding *) malloc (sizeof (*new_binding));
+
+ if (new_binding == NULL)
+ return NULL;
+
+#if defined _LIBC || defined HAVE_STRDUP
+ new_binding->domainname = strdup (domainname);
+ if (new_binding->domainname == NULL)
+ return NULL;
+#else
+ len = strlen (domainname) + 1;
+ new_binding->domainname = (char *) malloc (len);
+ if (new_binding->domainname == NULL)
+ return NULL;
+ memcpy (new_binding->domainname, domainname, len);
+#endif
+
+ if (strcmp (dirname, _nl_default_dirname) == 0)
+ new_binding->dirname = (char *) _nl_default_dirname;
+ else
+ {
+#if defined _LIBC || defined HAVE_STRDUP
+ new_binding->dirname = strdup (dirname);
+ if (new_binding->dirname == NULL)
+ return NULL;
+#else
+ len = strlen (dirname) + 1;
+ new_binding->dirname = (char *) malloc (len);
+ if (new_binding->dirname == NULL)
+ return NULL;
+ memcpy (new_binding->dirname, dirname, len);
+#endif
+ }
+
+ /* Now enqueue it. */
+ if (_nl_domain_bindings == NULL
+ || strcmp (domainname, _nl_domain_bindings->domainname) < 0)
+ {
+ new_binding->next = _nl_domain_bindings;
+ _nl_domain_bindings = new_binding;
+ }
+ else
+ {
+ binding = _nl_domain_bindings;
+ while (binding->next != NULL
+ && strcmp (domainname, binding->next->domainname) > 0)
+ binding = binding->next;
+
+ new_binding->next = binding->next;
+ binding->next = new_binding;
+ }
+
+ binding = new_binding;
+ }
+
+ return binding->dirname;
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__bindtextdomain, bindtextdomain);
+#endif
diff --git a/intl/cat-compat.c b/intl/cat-compat.c
new file mode 100644
index 00000000000..867d901b8ff
--- /dev/null
+++ b/intl/cat-compat.c
@@ -0,0 +1,262 @@
+/* Compatibility code for gettext-using-catgets interface.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+char *getenv ();
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef HAVE_NL_TYPES_H
+# include <nl_types.h>
+#endif
+
+#include "libgettext.h"
+
+/* @@ end of prolog @@ */
+
+/* XPG3 defines the result of `setlocale (category, NULL)' as:
+ ``Directs `setlocale()' to query `category' and return the current
+ setting of `local'.''
+ However it does not specify the exact format. And even worse: POSIX
+ defines this not at all. So we can use this feature only on selected
+ system (e.g. those using GNU C Library). */
+#ifdef _LIBC
+# define HAVE_LOCALE_NULL
+#endif
+
+/* The catalog descriptor. */
+static nl_catd catalog = (nl_catd) -1;
+
+/* Name of the default catalog. */
+static const char default_catalog_name[] = "messages";
+
+/* Name of currently used catalog. */
+static const char *catalog_name = default_catalog_name;
+
+/* Get ID for given string. If not found return -1. */
+static int msg_to_cat_id PARAMS ((const char *msg));
+
+/* Substitution for systems lacking this function in their C library. */
+#if !_LIBC && !HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+#endif
+
+
+/* Set currently used domain/catalog. */
+char *
+textdomain (domainname)
+ const char *domainname;
+{
+ nl_catd new_catalog;
+ char *new_name;
+ size_t new_name_len;
+ char *lang;
+
+#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \
+ && defined HAVE_LOCALE_NULL
+ lang = setlocale (LC_MESSAGES, NULL);
+#else
+ lang = getenv ("LC_ALL");
+ if (lang == NULL || lang[0] == '\0')
+ {
+ lang = getenv ("LC_MESSAGES");
+ if (lang == NULL || lang[0] == '\0')
+ lang = getenv ("LANG");
+ }
+#endif
+ if (lang == NULL || lang[0] == '\0')
+ lang = "C";
+
+ /* See whether name of currently used domain is asked. */
+ if (domainname == NULL)
+ return (char *) catalog_name;
+
+ if (domainname[0] == '\0')
+ domainname = default_catalog_name;
+
+ /* Compute length of added path element. */
+ new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang)
+ + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1
+ + sizeof (".cat");
+
+ new_name = (char *) malloc (new_name_len);
+ if (new_name == NULL)
+ return NULL;
+
+ strcpy (new_name, PACKAGE);
+ new_catalog = catopen (new_name, 0);
+
+ if (new_catalog == (nl_catd) -1)
+ {
+ /* NLSPATH search didn't work, try absolute path */
+ sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang,
+ PACKAGE);
+ new_catalog = catopen (new_name, 0);
+
+ if (new_catalog == (nl_catd) -1)
+ {
+ free (new_name);
+ return (char *) catalog_name;
+ }
+ }
+
+ /* Close old catalog. */
+ if (catalog != (nl_catd) -1)
+ catclose (catalog);
+ if (catalog_name != default_catalog_name)
+ free ((char *) catalog_name);
+
+ catalog = new_catalog;
+ catalog_name = new_name;
+
+ return (char *) catalog_name;
+}
+
+char *
+bindtextdomain (domainname, dirname)
+ const char *domainname;
+ const char *dirname;
+{
+#if HAVE_SETENV || HAVE_PUTENV
+ char *old_val, *new_val, *cp;
+ size_t new_val_len;
+
+ /* This does not make much sense here but to be compatible do it. */
+ if (domainname == NULL)
+ return NULL;
+
+ /* Compute length of added path element. If we use setenv we don't need
+ the first byts for NLSPATH=, but why complicate the code for this
+ peanuts. */
+ new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname)
+ + sizeof ("/%L/LC_MESSAGES/%N.cat");
+
+ old_val = getenv ("NLSPATH");
+ if (old_val == NULL || old_val[0] == '\0')
+ {
+ old_val = NULL;
+ new_val_len += 1 + sizeof (LOCALEDIR) - 1
+ + sizeof ("/%L/LC_MESSAGES/%N.cat");
+ }
+ else
+ new_val_len += strlen (old_val);
+
+ new_val = (char *) malloc (new_val_len);
+ if (new_val == NULL)
+ return NULL;
+
+# if HAVE_SETENV
+ cp = new_val;
+# else
+ cp = stpcpy (new_val, "NLSPATH=");
+# endif
+
+ cp = stpcpy (cp, dirname);
+ cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:");
+
+ if (old_val == NULL)
+ {
+# if __STDC__
+ stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat");
+# else
+
+ cp = stpcpy (cp, LOCALEDIR);
+ stpcpy (cp, "/%L/LC_MESSAGES/%N.cat");
+# endif
+ }
+ else
+ stpcpy (cp, old_val);
+
+# if HAVE_SETENV
+ setenv ("NLSPATH", new_val, 1);
+ free (new_val);
+# else
+ putenv (new_val);
+ /* Do *not* free the environment entry we just entered. It is used
+ from now on. */
+# endif
+
+#endif
+
+ return (char *) domainname;
+}
+
+#undef gettext
+char *
+gettext (msg)
+ const char *msg;
+{
+ int msgid;
+
+ if (msg == NULL || catalog == (nl_catd) -1)
+ return (char *) msg;
+
+ /* Get the message from the catalog. We always use set number 1.
+ The message ID is computed by the function `msg_to_cat_id'
+ which works on the table generated by `po-to-tbl'. */
+ msgid = msg_to_cat_id (msg);
+ if (msgid == -1)
+ return (char *) msg;
+
+ return catgets (catalog, 1, msgid, (char *) msg);
+}
+
+/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries
+ for the one equal to msg. If it is found return the ID. In case when
+ the string is not found return -1. */
+static int
+msg_to_cat_id (msg)
+ const char *msg;
+{
+ int cnt;
+
+ for (cnt = 0; cnt < _msg_tbl_length; ++cnt)
+ if (strcmp (msg, _msg_tbl[cnt]._msg) == 0)
+ return _msg_tbl[cnt]._msg_number;
+
+ return -1;
+}
+
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
diff --git a/intl/config.in b/intl/config.in
new file mode 100644
index 00000000000..8a9049b80de
--- /dev/null
+++ b/intl/config.in
@@ -0,0 +1,128 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if NLS is requested. */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have catgets and don't want to use GNU gettext. */
+#undef HAVE_CATGETS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Define as 1 if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Define if you have the i library (-li). */
+#undef HAVE_LIBI
diff --git a/intl/configure b/intl/configure
new file mode 100755
index 00000000000..341eea019ae
--- /dev/null
+++ b/intl/configure
@@ -0,0 +1,2950 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=dgettext.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:562: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:616: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 631 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:637: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 648 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:654: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:677: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:706: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:735: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:783: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 793 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:797: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:817: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:822: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:831: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:846: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:876: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:903: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:924: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 929 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:937: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 954 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 972 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 993 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1028: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1033 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1082: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1103: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1110 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1117: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:1143: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1148 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1176: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1181 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1211: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1216 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1244: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1249 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.o
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:1304: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1309 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1334: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1339 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:1389: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1397 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:1416: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1441: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1446 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1451: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1480: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1485 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:1533: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1541 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:1681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1709: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1714 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1719: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1749: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1754 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1806: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1811 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:1868: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1873 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:1880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:1901: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:1921: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:1940: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1945 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1950: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:1967: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1972 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:1979: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:1995: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2003 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:2014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:2030: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2035 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2070: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2104: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2109 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2159: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2194: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 2226 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2266: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2300: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2335: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:2425: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:2453: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2458 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+ac_sources="$nls_cv_header_libgt"
+ac_dests="$nls_cv_header_intl"
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+srcdir=$ac_given_srcdir
+while test -n "$ac_sources"; do
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+ set $ac_sources; ac_source=$1; shift; ac_sources=$*
+
+ echo "linking $srcdir/$ac_source to $ac_dest"
+
+ if test ! -r $srcdir/$ac_source; then
+ { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
+ fi
+ rm -f $ac_dest
+
+ # Make relative symlinks.
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
+ # The dest file is in a subdirectory.
+ test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
+ ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dest_dir_suffix.
+ ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dest_dir_suffix= ac_dots=
+ fi
+
+ case "$srcdir" in
+ [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
+ *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
+ esac
+
+ # Make a symlink if possible; otherwise try a hard link.
+ if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+ ln $srcdir/$ac_source $ac_dest; then :
+ else
+ { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
+ fi
+done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/intl/configure.in b/intl/configure.in
new file mode 100644
index 00000000000..4ba9c244efa
--- /dev/null
+++ b/intl/configure.in
@@ -0,0 +1,10 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(dgettext.c)
+AM_CONFIG_HEADER(config.h:config.in)
+
+AM_PROG_INSTALL
+CY_GNU_GETTEXT
+AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+
+AC_OUTPUT(Makefile)
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
new file mode 100644
index 00000000000..a316bfd1086
--- /dev/null
+++ b/intl/dcgettext.c
@@ -0,0 +1,593 @@
+/* Implementation of the dcgettext(3) function
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
+#else
+# if defined HAVE_ALLOCA_H || defined _LIBC
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+#ifndef __set_errno
+# define __set_errno(val) errno = (val)
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+char *getenv ();
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+# endif
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+#include "hash-string.h"
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define getcwd __getcwd
+# define stpcpy __stpcpy
+#else
+# if !defined HAVE_GETCWD
+char *getwd ();
+# define getcwd(buf, max) getwd (buf)
+# else
+char *getcwd ();
+# endif
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
+#endif
+
+/* Amount to increase buffer size by in each try. */
+#define PATH_INCR 32
+
+/* The following is from pathmax.h. */
+/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
+ PATH_MAX but might cause redefinition warnings when sys/param.h is
+ later included (as on MORE/BSD 4.3). */
+#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
+# include <limits.h>
+#endif
+
+#ifndef _POSIX_PATH_MAX
+# define _POSIX_PATH_MAX 255
+#endif
+
+#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
+# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
+#endif
+
+/* Don't include sys/param.h if it already has been. */
+#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
+# include <sys/param.h>
+#endif
+
+#if !defined(PATH_MAX) && defined(MAXPATHLEN)
+# define PATH_MAX MAXPATHLEN
+#endif
+
+#ifndef PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+#endif
+
+/* XPG3 defines the result of `setlocale (category, NULL)' as:
+ ``Directs `setlocale()' to query `category' and return the current
+ setting of `local'.''
+ However it does not specify the exact format. And even worse: POSIX
+ defines this not at all. So we can use this feature only on selected
+ system (e.g. those using GNU C Library). */
+#ifdef _LIBC
+# define HAVE_LOCALE_NULL
+#endif
+
+/* Name of the default domain used for gettext(3) prior any call to
+ textdomain(3). The default value for this is "messages". */
+const char _nl_default_default_domain[] = "messages";
+
+/* Value used as the default domain for gettext(3). */
+const char *_nl_current_default_domain = _nl_default_default_domain;
+
+/* Contains the default location of the message catalogs. */
+const char _nl_default_dirname[] = GNULOCALEDIR;
+
+/* List with bindings of specific domains created by bindtextdomain()
+ calls. */
+struct binding *_nl_domain_bindings;
+
+/* Prototypes for local functions. */
+static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
+ const char *msgid));
+static const char *category_to_name PARAMS ((int category));
+static const char *guess_category_value PARAMS ((int category,
+ const char *categoryname));
+
+
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old); \
+ } \
+ } while (0)
+# undef alloca
+# define alloca(size) (malloc (size))
+#endif /* have alloca */
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define DCGETTEXT __dcgettext
+#else
+# define DCGETTEXT dcgettext__
+#endif
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+ locale. */
+char *
+DCGETTEXT (domainname, msgid, category)
+ const char *domainname;
+ const char *msgid;
+ int category;
+{
+#ifndef HAVE_ALLOCA
+ struct block_list *block_list = NULL;
+#endif
+ struct loaded_l10nfile *domain;
+ struct binding *binding;
+ const char *categoryname;
+ const char *categoryvalue;
+ char *dirname, *xdomainname;
+ char *single_locale;
+ char *retval;
+ int saved_errno = errno;
+
+ /* If no real MSGID is given return NULL. */
+ if (msgid == NULL)
+ return NULL;
+
+ /* If DOMAINNAME is NULL, we are interested in the default domain. If
+ CATEGORY is not LC_MESSAGES this might not make much sense but the
+ defintion left this undefined. */
+ if (domainname == NULL)
+ domainname = _nl_current_default_domain;
+
+ /* First find matching binding. */
+ for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
+ {
+ int compare = strcmp (domainname, binding->domainname);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It is not in the list. */
+ binding = NULL;
+ break;
+ }
+ }
+
+ if (binding == NULL)
+ dirname = (char *) _nl_default_dirname;
+ else if (binding->dirname[0] == '/')
+ dirname = binding->dirname;
+ else
+ {
+ /* We have a relative path. Make it absolute now. */
+ size_t dirname_len = strlen (binding->dirname) + 1;
+ size_t path_max;
+ char *ret;
+
+ path_max = (unsigned) PATH_MAX;
+ path_max += 2; /* The getcwd docs say to do this. */
+
+ dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
+
+ __set_errno (0);
+ while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE)
+ {
+ path_max += PATH_INCR;
+ dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
+ __set_errno (0);
+ }
+
+ if (ret == NULL)
+ {
+ /* We cannot get the current working directory. Don't signal an
+ error but simply return the default string. */
+ FREE_BLOCKS (block_list);
+ __set_errno (saved_errno);
+ return (char *) msgid;
+ }
+
+ stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
+ }
+
+ /* Now determine the symbolic name of CATEGORY and its value. */
+ categoryname = category_to_name (category);
+ categoryvalue = guess_category_value (category, categoryname);
+
+ xdomainname = (char *) alloca (strlen (categoryname)
+ + strlen (domainname) + 5);
+ ADD_BLOCK (block_list, xdomainname);
+
+ stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
+ domainname),
+ ".mo");
+
+ /* Creating working area. */
+ single_locale = (char *) alloca (strlen (categoryvalue) + 1);
+ ADD_BLOCK (block_list, single_locale);
+
+
+ /* Search for the given string. This is a loop because we perhaps
+ got an ordered list of languages to consider for th translation. */
+ while (1)
+ {
+ /* Make CATEGORYVALUE point to the next element of the list. */
+ while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
+ ++categoryvalue;
+ if (categoryvalue[0] == '\0')
+ {
+ /* The whole contents of CATEGORYVALUE has been searched but
+ no valid entry has been found. We solve this situation
+ by implicitly appending a "C" entry, i.e. no translation
+ will take place. */
+ single_locale[0] = 'C';
+ single_locale[1] = '\0';
+ }
+ else
+ {
+ char *cp = single_locale;
+ while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
+ *cp++ = *categoryvalue++;
+ *cp = '\0';
+ }
+
+ /* If the current locale value is C (or POSIX) we don't load a
+ domain. Return the MSGID. */
+ if (strcmp (single_locale, "C") == 0
+ || strcmp (single_locale, "POSIX") == 0)
+ {
+ FREE_BLOCKS (block_list);
+ __set_errno (saved_errno);
+ return (char *) msgid;
+ }
+
+
+ /* Find structure describing the message catalog matching the
+ DOMAINNAME and CATEGORY. */
+ domain = _nl_find_domain (dirname, single_locale, xdomainname);
+
+ if (domain != NULL)
+ {
+ retval = find_msg (domain, msgid);
+
+ if (retval == NULL)
+ {
+ int cnt;
+
+ for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
+ {
+ retval = find_msg (domain->successor[cnt], msgid);
+
+ if (retval != NULL)
+ break;
+ }
+ }
+
+ if (retval != NULL)
+ {
+ FREE_BLOCKS (block_list);
+ __set_errno (saved_errno);
+ return retval;
+ }
+ }
+ }
+ /* NOTREACHED */
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__dcgettext, dcgettext);
+#endif
+
+
+static char *
+find_msg (domain_file, msgid)
+ struct loaded_l10nfile *domain_file;
+ const char *msgid;
+{
+ size_t top, act, bottom;
+ struct loaded_domain *domain;
+
+ if (domain_file->decided == 0)
+ _nl_load_domain (domain_file);
+
+ if (domain_file->data == NULL)
+ return NULL;
+
+ domain = (struct loaded_domain *) domain_file->data;
+
+ /* Locate the MSGID and its translation. */
+ if (domain->hash_size > 2 && domain->hash_tab != NULL)
+ {
+ /* Use the hashing table. */
+ nls_uint32 len = strlen (msgid);
+ nls_uint32 hash_val = hash_string (msgid);
+ nls_uint32 idx = hash_val % domain->hash_size;
+ nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
+ nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
+
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
+ && strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset)) == 0)
+ return (char *) domain->data + W (domain->must_swap,
+ domain->trans_tab[nstr - 1].offset);
+
+ while (1)
+ {
+ if (idx >= domain->hash_size - incr)
+ idx -= domain->hash_size - incr;
+ else
+ idx += incr;
+
+ nstr = W (domain->must_swap, domain->hash_tab[idx]);
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
+ && strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset))
+ == 0)
+ return (char *) domain->data
+ + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
+ }
+ /* NOTREACHED */
+ }
+
+ /* Now we try the default method: binary search in the sorted
+ array of messages. */
+ bottom = 0;
+ top = domain->nstrings;
+ while (bottom < top)
+ {
+ int cmp_val;
+
+ act = (bottom + top) / 2;
+ cmp_val = strcmp (msgid, domain->data
+ + W (domain->must_swap,
+ domain->orig_tab[act].offset));
+ if (cmp_val < 0)
+ top = act;
+ else if (cmp_val > 0)
+ bottom = act + 1;
+ else
+ break;
+ }
+
+ /* If an translation is found return this. */
+ return bottom >= top ? NULL : (char *) domain->data
+ + W (domain->must_swap,
+ domain->trans_tab[act].offset);
+}
+
+
+/* Return string representation of locale CATEGORY. */
+static const char *
+category_to_name (category)
+ int category;
+{
+ const char *retval;
+
+ switch (category)
+ {
+#ifdef LC_COLLATE
+ case LC_COLLATE:
+ retval = "LC_COLLATE";
+ break;
+#endif
+#ifdef LC_CTYPE
+ case LC_CTYPE:
+ retval = "LC_CTYPE";
+ break;
+#endif
+#ifdef LC_MONETARY
+ case LC_MONETARY:
+ retval = "LC_MONETARY";
+ break;
+#endif
+#ifdef LC_NUMERIC
+ case LC_NUMERIC:
+ retval = "LC_NUMERIC";
+ break;
+#endif
+#ifdef LC_TIME
+ case LC_TIME:
+ retval = "LC_TIME";
+ break;
+#endif
+#ifdef LC_MESSAGES
+ case LC_MESSAGES:
+ retval = "LC_MESSAGES";
+ break;
+#endif
+#ifdef LC_RESPONSE
+ case LC_RESPONSE:
+ retval = "LC_RESPONSE";
+ break;
+#endif
+#ifdef LC_ALL
+ case LC_ALL:
+ /* This might not make sense but is perhaps better than any other
+ value. */
+ retval = "LC_ALL";
+ break;
+#endif
+ default:
+ /* If you have a better idea for a default value let me know. */
+ retval = "LC_XXX";
+ }
+
+ return retval;
+}
+
+/* Guess value of current locale from value of the environment variables. */
+static const char *
+guess_category_value (category, categoryname)
+ int category;
+ const char *categoryname;
+{
+ const char *retval;
+
+ /* The highest priority value is the `LANGUAGE' environment
+ variable. This is a GNU extension. */
+ retval = getenv ("LANGUAGE");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* `LANGUAGE' is not set. So we have to proceed with the POSIX
+ methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some
+ systems this can be done by the `setlocale' function itself. */
+#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL
+ return setlocale (category, NULL);
+#else
+ /* Setting of LC_ALL overwrites all other. */
+ retval = getenv ("LC_ALL");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* Next comes the name of the desired category. */
+ retval = getenv (categoryname);
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* Last possibility is the LANG environment variable. */
+ retval = getenv ("LANG");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* We use C as the default domain. POSIX says this is implementation
+ defined. */
+ return "C";
+#endif
+}
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
diff --git a/intl/dgettext.c b/intl/dgettext.c
new file mode 100644
index 00000000000..2fde6770f79
--- /dev/null
+++ b/intl/dgettext.c
@@ -0,0 +1,59 @@
+/* dgettext.c -- implementation of the dgettext(3) function
+ Copyright (C) 1995 Software Foundation, Inc.
+
+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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined HAVE_LOCALE_H || defined _LIBC
+# include <locale.h>
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define DGETTEXT __dgettext
+# define DCGETTEXT __dcgettext
+#else
+# define DGETTEXT dgettext__
+# define DCGETTEXT dcgettext__
+#endif
+
+/* Look up MSGID in the DOMAINNAME message catalog of the current
+ LC_MESSAGES locale. */
+char *
+DGETTEXT (domainname, msgid)
+ const char *domainname;
+ const char *msgid;
+{
+ return DCGETTEXT (domainname, msgid, LC_MESSAGES);
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__dgettext, dgettext);
+#endif
diff --git a/intl/explodename.c b/intl/explodename.c
new file mode 100644
index 00000000000..37c46e9d7b8
--- /dev/null
+++ b/intl/explodename.c
@@ -0,0 +1,181 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "loadinfo.h"
+
+/* On some strange systems still no definition of NULL is found. Sigh! */
+#ifndef NULL
+# if defined __STDC__ && __STDC__
+# define NULL ((void *) 0)
+# else
+# define NULL 0
+# endif
+#endif
+
+/* @@ end of prolog @@ */
+
+int
+_nl_explode_name (name, language, modifier, territory, codeset,
+ normalized_codeset, special, sponsor, revision)
+ char *name;
+ const char **language;
+ const char **modifier;
+ const char **territory;
+ const char **codeset;
+ const char **normalized_codeset;
+ const char **special;
+ const char **sponsor;
+ const char **revision;
+{
+ enum { undecided, xpg, cen } syntax;
+ char *cp;
+ int mask;
+
+ *modifier = NULL;
+ *territory = NULL;
+ *codeset = NULL;
+ *normalized_codeset = NULL;
+ *special = NULL;
+ *sponsor = NULL;
+ *revision = NULL;
+
+ /* Now we determine the single parts of the locale name. First
+ look for the language. Termination symbols are `_' and `@' if
+ we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
+ mask = 0;
+ syntax = undecided;
+ *language = cp = name;
+ while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
+ && cp[0] != '+' && cp[0] != ',')
+ ++cp;
+
+ if (*language == cp)
+ /* This does not make sense: language has to be specified. Use
+ this entry as it is without exploding. Perhaps it is an alias. */
+ cp = strchr (*language, '\0');
+ else if (cp[0] == '_')
+ {
+ /* Next is the territory. */
+ cp[0] = '\0';
+ *territory = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
+ && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= TERRITORY;
+
+ if (cp[0] == '.')
+ {
+ /* Next is the codeset. */
+ syntax = xpg;
+ cp[0] = '\0';
+ *codeset = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '@')
+ ++cp;
+
+ mask |= XPG_CODESET;
+
+ if (*codeset != cp && (*codeset)[0] != '\0')
+ {
+ *normalized_codeset = _nl_normalize_codeset (*codeset,
+ cp - *codeset);
+ if (strcmp (*codeset, *normalized_codeset) == 0)
+ free ((char *) *normalized_codeset);
+ else
+ mask |= XPG_NORM_CODESET;
+ }
+ }
+ }
+
+ if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
+ {
+ /* Next is the modifier. */
+ syntax = cp[0] == '@' ? xpg : cen;
+ cp[0] = '\0';
+ *modifier = ++cp;
+
+ while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
+ && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= XPG_MODIFIER | CEN_AUDIENCE;
+ }
+
+ if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
+ {
+ syntax = cen;
+
+ if (cp[0] == '+')
+ {
+ /* Next is special application (CEN syntax). */
+ cp[0] = '\0';
+ *special = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
+ ++cp;
+
+ mask |= CEN_SPECIAL;
+ }
+
+ if (cp[0] == ',')
+ {
+ /* Next is sponsor (CEN syntax). */
+ cp[0] = '\0';
+ *sponsor = ++cp;
+
+ while (cp[0] != '\0' && cp[0] != '_')
+ ++cp;
+
+ mask |= CEN_SPONSOR;
+ }
+
+ if (cp[0] == '_')
+ {
+ /* Next is revision (CEN syntax). */
+ cp[0] = '\0';
+ *revision = ++cp;
+
+ mask |= CEN_REVISION;
+ }
+ }
+
+ /* For CEN syntax values it might be important to have the
+ separator character in the file name, not for XPG syntax. */
+ if (syntax == xpg)
+ {
+ if (*territory != NULL && (*territory)[0] == '\0')
+ mask &= ~TERRITORY;
+
+ if (*codeset != NULL && (*codeset)[0] == '\0')
+ mask &= ~XPG_CODESET;
+
+ if (*modifier != NULL && (*modifier)[0] == '\0')
+ mask &= ~XPG_MODIFIER;
+ }
+
+ return mask;
+}
diff --git a/intl/finddomain.c b/intl/finddomain.c
new file mode 100644
index 00000000000..ec85d4de4d1
--- /dev/null
+++ b/intl/finddomain.c
@@ -0,0 +1,189 @@
+/* Handle list of needed message catalogs
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+/* List of already loaded domains. */
+static struct loaded_l10nfile *_nl_loaded_domains;
+
+
+/* Return a data structure describing the message catalog described by
+ the DOMAINNAME and CATEGORY parameters with respect to the currently
+ established bindings. */
+struct loaded_l10nfile *
+_nl_find_domain (dirname, locale, domainname)
+ const char *dirname;
+ char *locale;
+ const char *domainname;
+{
+ struct loaded_l10nfile *retval;
+ const char *language;
+ const char *modifier;
+ const char *territory;
+ const char *codeset;
+ const char *normalized_codeset;
+ const char *special;
+ const char *sponsor;
+ const char *revision;
+ const char *alias_value;
+ int mask;
+
+ /* LOCALE can consist of up to four recognized parts for the XPG syntax:
+
+ language[_territory[.codeset]][@modifier]
+
+ and six parts for the CEN syntax:
+
+ language[_territory][+audience][+special][,[sponsor][_revision]]
+
+ Beside the first all of them are allowed to be missing. If the
+ full specified locale is not found, the less specific one are
+ looked for. The various part will be stripped of according to
+ the following order:
+ (1) revision
+ (2) sponsor
+ (3) special
+ (4) codeset
+ (5) normalized codeset
+ (6) territory
+ (7) audience/modifier
+ */
+
+ /* If we have already tested for this locale entry there has to
+ be one data set in the list of loaded domains. */
+ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ strlen (dirname) + 1, 0, locale, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, domainname, 0);
+ if (retval != NULL)
+ {
+ /* We know something about this locale. */
+ int cnt;
+
+ if (retval->decided == 0)
+ _nl_load_domain (retval);
+
+ if (retval->data != NULL)
+ return retval;
+
+ for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
+ {
+ if (retval->successor[cnt]->decided == 0)
+ _nl_load_domain (retval->successor[cnt]);
+
+ if (retval->successor[cnt]->data != NULL)
+ break;
+ }
+ return cnt >= 0 ? retval : NULL;
+ /* NOTREACHED */
+ }
+
+ /* See whether the locale value is an alias. If yes its value
+ *overwrites* the alias name. No test for the original value is
+ done. */
+ alias_value = _nl_expand_alias (locale);
+ if (alias_value != NULL)
+ {
+ size_t len = strlen (alias_value) + 1;
+ locale = (char *) malloc (len);
+ if (locale == NULL)
+ return NULL;
+
+ memcpy (locale, alias_value, len);
+ }
+
+ /* Now we determine the single parts of the locale name. First
+ look for the language. Termination symbols are `_' and `@' if
+ we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
+ mask = _nl_explode_name (locale, &language, &modifier, &territory,
+ &codeset, &normalized_codeset, &special,
+ &sponsor, &revision);
+
+ /* Create all possible locale entries which might be interested in
+ generalization. */
+ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+ strlen (dirname) + 1, mask, language, territory,
+ codeset, normalized_codeset, modifier, special,
+ sponsor, revision, domainname, 1);
+ if (retval == NULL)
+ /* This means we are out of core. */
+ return NULL;
+
+ if (retval->decided == 0)
+ _nl_load_domain (retval);
+ if (retval->data == NULL)
+ {
+ int cnt;
+ for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
+ {
+ if (retval->successor[cnt]->decided == 0)
+ _nl_load_domain (retval->successor[cnt]);
+ if (retval->successor[cnt]->data != NULL)
+ break;
+ }
+ }
+
+ /* The room for an alias was dynamically allocated. Free it now. */
+ if (alias_value != NULL)
+ free (locale);
+
+ return retval;
+}
diff --git a/intl/gettext.c b/intl/gettext.c
new file mode 100644
index 00000000000..1336d21e7c9
--- /dev/null
+++ b/intl/gettext.c
@@ -0,0 +1,70 @@
+/* Implementation of gettext(3) function
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _LIBC
+# define __need_NULL
+# include <stddef.h>
+#else
+# ifdef STDC_HEADERS
+# include <stdlib.h> /* Just for NULL. */
+# else
+# ifdef HAVE_STRING_H
+# include <string.h>
+# else
+# define NULL ((void *) 0)
+# endif
+# endif
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define GETTEXT __gettext
+# define DGETTEXT __dgettext
+#else
+# define GETTEXT gettext__
+# define DGETTEXT dgettext__
+#endif
+
+/* Look up MSGID in the current default message catalog for the current
+ LC_MESSAGES locale. If not found, returns MSGID itself (the default
+ text). */
+char *
+GETTEXT (msgid)
+ const char *msgid;
+{
+ return DGETTEXT (NULL, msgid);
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__gettext, gettext);
+#endif
diff --git a/intl/gettext.h b/intl/gettext.h
new file mode 100644
index 00000000000..6b4b9e3316c
--- /dev/null
+++ b/intl/gettext.h
@@ -0,0 +1,105 @@
+/* Internal header for GNU gettext internationalization functions
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ 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, 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 Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _GETTEXT_H
+#define _GETTEXT_H 1
+
+#include <stdio.h>
+
+#if HAVE_LIMITS_H || _LIBC
+# include <limits.h>
+#endif
+
+/* @@ end of prolog @@ */
+
+/* The magic number of the GNU message catalog format. */
+#define _MAGIC 0x950412de
+#define _MAGIC_SWAPPED 0xde120495
+
+/* Revision number of the currently used .mo (binary) file format. */
+#define MO_REVISION_NUMBER 0
+
+/* The following contortions are an attempt to use the C preprocessor
+ to determine an unsigned integral type that is 32 bits wide. An
+ alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+ doing that would require that the configure script compile and *run*
+ the resulting executable. Locally running cross-compiled executables
+ is usually not possible. */
+
+#if __STDC__
+# define UINT_MAX_32_BITS 4294967295U
+#else
+# define UINT_MAX_32_BITS 0xFFFFFFFF
+#endif
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+ This should be valid for all systems GNU cares about because
+ that doesn't include 16-bit systems, and only modern systems
+ (that certainly have <limits.h>) have 64+-bit integral types. */
+
+#ifndef UINT_MAX
+# define UINT_MAX UINT_MAX_32_BITS
+#endif
+
+#if UINT_MAX == UINT_MAX_32_BITS
+typedef unsigned nls_uint32;
+#else
+# if USHRT_MAX == UINT_MAX_32_BITS
+typedef unsigned short nls_uint32;
+# else
+# if ULONG_MAX == UINT_MAX_32_BITS
+typedef unsigned long nls_uint32;
+# else
+ /* The following line is intended to throw an error. Using #error is
+ not portable enough. */
+ "Cannot determine unsigned 32-bit data type."
+# endif
+# endif
+#endif
+
+
+/* Header for binary .mo file format. */
+struct mo_file_header
+{
+ /* The magic number. */
+ nls_uint32 magic;
+ /* The revision number of the file format. */
+ nls_uint32 revision;
+ /* The number of strings pairs. */
+ nls_uint32 nstrings;
+ /* Offset of table with start offsets of original strings. */
+ nls_uint32 orig_tab_offset;
+ /* Offset of table with start offsets of translation strings. */
+ nls_uint32 trans_tab_offset;
+ /* Size of hashing table. */
+ nls_uint32 hash_tab_size;
+ /* Offset of first hashing entry. */
+ nls_uint32 hash_tab_offset;
+};
+
+struct string_desc
+{
+ /* Length of addressed string. */
+ nls_uint32 length;
+ /* Offset of string in file. */
+ nls_uint32 offset;
+};
+
+/* @@ begin of epilog @@ */
+
+#endif /* gettext.h */
diff --git a/intl/gettextP.h b/intl/gettextP.h
new file mode 100644
index 00000000000..bb8d55235ad
--- /dev/null
+++ b/intl/gettextP.h
@@ -0,0 +1,73 @@
+/* Header describing internals of gettext library
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _GETTEXTP_H
+#define _GETTEXTP_H
+
+#include "loadinfo.h"
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+#ifndef W
+# define W(flag, data) ((flag) ? SWAP (data) : (data))
+#endif
+
+
+static nls_uint32 SWAP PARAMS ((nls_uint32 i));
+
+static inline nls_uint32
+SWAP (i)
+ nls_uint32 i;
+{
+ return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
+}
+
+
+struct loaded_domain
+{
+ const char *data;
+ int must_swap;
+ nls_uint32 nstrings;
+ struct string_desc *orig_tab;
+ struct string_desc *trans_tab;
+ nls_uint32 hash_size;
+ nls_uint32 *hash_tab;
+};
+
+struct binding
+{
+ struct binding *next;
+ char *domainname;
+ char *dirname;
+};
+
+struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
+ char *__locale,
+ const char *__domainname));
+void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
+
+/* @@ begin of epilog @@ */
+
+#endif /* gettextP.h */
diff --git a/intl/hash-string.h b/intl/hash-string.h
new file mode 100644
index 00000000000..e66e8417a97
--- /dev/null
+++ b/intl/hash-string.h
@@ -0,0 +1,63 @@
+/* Implements a string hashing function.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+
+ 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, 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 Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_VALUES_H
+# include <values.h>
+#endif
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(Args) Args
+# else
+# define PARAMS(Args) ()
+# endif
+#endif
+
+/* We assume to have `unsigned long int' value with at least 32 bits. */
+#define HASHWORDBITS 32
+
+
+/* Defines the so called `hashpjw' function by P.J. Weinberger
+ [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
+ 1986, 1987 Bell Telephone Laboratories, Inc.] */
+static unsigned long hash_string PARAMS ((const char *__str_param));
+
+static inline unsigned long
+hash_string (str_param)
+ const char *str_param;
+{
+ unsigned long int hval, g;
+ const char *str = str_param;
+
+ /* Compute the hash value for the given string. */
+ hval = 0;
+ while (*str != '\0')
+ {
+ hval <<= 4;
+ hval += (unsigned long) *str++;
+ g = hval & ((unsigned long) 0xf << (HASHWORDBITS - 4));
+ if (g != 0)
+ {
+ hval ^= g >> (HASHWORDBITS - 8);
+ hval ^= g;
+ }
+ }
+ return hval;
+}
diff --git a/intl/intl-compat.c b/intl/intl-compat.c
new file mode 100644
index 00000000000..503efa0fa9c
--- /dev/null
+++ b/intl/intl-compat.c
@@ -0,0 +1,76 @@
+/* intl-compat.c - Stub functions to call gettext functions from GNU gettext
+ Library.
+ Copyright (C) 1995 Software Foundation, Inc.
+
+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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libgettext.h"
+
+/* @@ end of prolog @@ */
+
+
+#undef gettext
+#undef dgettext
+#undef dcgettext
+#undef textdomain
+#undef bindtextdomain
+
+
+char *
+bindtextdomain (domainname, dirname)
+ const char *domainname;
+ const char *dirname;
+{
+ return bindtextdomain__ (domainname, dirname);
+}
+
+
+char *
+dcgettext (domainname, msgid, category)
+ const char *domainname;
+ const char *msgid;
+ int category;
+{
+ return dcgettext__ (domainname, msgid, category);
+}
+
+
+char *
+dgettext (domainname, msgid)
+ const char *domainname;
+ const char *msgid;
+{
+ return dgettext__ (domainname, msgid);
+}
+
+
+char *
+gettext (msgid)
+ const char *msgid;
+{
+ return gettext__ (msgid);
+}
+
+
+char *
+textdomain (domainname)
+ const char *domainname;
+{
+ return textdomain__ (domainname);
+}
diff --git a/intl/intlh.inst.in b/intl/intlh.inst.in
new file mode 100644
index 00000000000..62d323cd8c1
--- /dev/null
+++ b/intl/intlh.inst.in
@@ -0,0 +1,111 @@
+/* Message catalogs for internationalization.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#ifndef _LIBINTL_H
+#define _LIBINTL_H 1
+
+@INCLUDE_LOCALE_H@
+
+/* We define an additional symbol to signal that we use the GNU
+ implementation of gettext. */
+#define __USE_GNU_GETTEXT 1
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Look up MSGID in the current default message catalog for the current
+ LC_MESSAGES locale. If not found, returns MSGID itself (the default
+ text). */
+extern char *gettext PARAMS ((const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current
+ LC_MESSAGES locale. */
+extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+ locale. */
+extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid,
+ int __category));
+
+
+/* Set the current default message catalog to DOMAINNAME.
+ If DOMAINNAME is null, return the current default.
+ If DOMAINNAME is "", reset to the default of "messages". */
+extern char *textdomain PARAMS ((const char *__domainname));
+
+/* Specify that the DOMAINNAME message catalog will be found
+ in DIRNAME rather than in the system locale data base. */
+extern char *bindtextdomain PARAMS ((const char *__domainname,
+ const char *__dirname));
+
+
+/* Optimized version of the functions above. */
+#if defined __OPTIMIZED
+/* These must be a macro. Inlined functions are useless because the
+ `__builtin_constant_p' predicate in dcgettext would always return
+ false. */
+
+# define gettext(msgid) dgettext ((char *) 0, msgid)
+
+# define dgettext(domainname, msgid) \
+ dcgettext (domainname, msgid, LC_MESSAGES)
+
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+/* This global variable is defined in loadmsgcat.c. We need a sign,
+ whether a new catalog was loaded, which can be associated with all
+ translations. */
+extern int _nl_msg_cat_cntr;
+
+# define dcgettext(domainname, msgid, category) \
+ (__extension__ \
+ ({ \
+ char *__result; \
+ if (__builtin_constant_p (msgid)) \
+ { \
+ static char *__translation__; \
+ static int __catalog_counter__; \
+ if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
+ { \
+ __translation__ = \
+ (dcgettext) ((domainname), (msgid), (category)); \
+ __catalog_counter__ = _nl_msg_cat_cntr; \
+ } \
+ __result = __translation__; \
+ } \
+ else \
+ __result = (dcgettext) ((domainname), (msgid), (category)); \
+ __result; \
+ }))
+# endif
+#endif /* Optimizing. */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* libintl.h */
diff --git a/intl/l10nflist.c b/intl/l10nflist.c
new file mode 100644
index 00000000000..4e2bc130950
--- /dev/null
+++ b/intl/l10nflist.c
@@ -0,0 +1,409 @@
+/* Handle list of needed message catalogs
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#if defined HAVE_STRING_H || defined _LIBC
+# ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+# endif
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#if defined _LIBC || defined HAVE_ARGZ_H
+# include <argz.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#include "loadinfo.h"
+
+/* On some strange systems still no definition of NULL is found. Sigh! */
+#ifndef NULL
+# if defined __STDC__ && __STDC__
+# define NULL ((void *) 0)
+# else
+# define NULL 0
+# endif
+#endif
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define stpcpy(dest, src) __stpcpy(dest, src)
+#else
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
+#endif
+
+/* Define function which are usually not available. */
+
+#if !defined _LIBC && !defined HAVE___ARGZ_COUNT
+/* Returns the number of strings in ARGZ. */
+static size_t argz_count__ PARAMS ((const char *argz, size_t len));
+
+static size_t
+argz_count__ (argz, len)
+ const char *argz;
+ size_t len;
+{
+ size_t count = 0;
+ while (len > 0)
+ {
+ size_t part_len = strlen (argz);
+ argz += part_len + 1;
+ len -= part_len + 1;
+ count++;
+ }
+ return count;
+}
+# undef __argz_count
+# define __argz_count(argz, len) argz_count__ (argz, len)
+#endif /* !_LIBC && !HAVE___ARGZ_COUNT */
+
+#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY
+/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+ except the last into the character SEP. */
+static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep));
+
+static void
+argz_stringify__ (argz, len, sep)
+ char *argz;
+ size_t len;
+ int sep;
+{
+ while (len > 0)
+ {
+ size_t part_len = strlen (argz);
+ argz += part_len;
+ len -= part_len + 1;
+ if (len > 0)
+ *argz++ = sep;
+ }
+}
+# undef __argz_stringify
+# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep)
+#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */
+
+#if !defined _LIBC && !defined HAVE___ARGZ_NEXT
+static char *argz_next__ PARAMS ((char *argz, size_t argz_len,
+ const char *entry));
+
+static char *
+argz_next__ (argz, argz_len, entry)
+ char *argz;
+ size_t argz_len;
+ const char *entry;
+{
+ if (entry)
+ {
+ if (entry < argz + argz_len)
+ entry = strchr (entry, '\0') + 1;
+
+ return entry >= argz + argz_len ? NULL : (char *) entry;
+ }
+ else
+ if (argz_len > 0)
+ return argz;
+ else
+ return 0;
+}
+# undef __argz_next
+# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry)
+#endif /* !_LIBC && !HAVE___ARGZ_NEXT */
+
+
+/* Return number of bits set in X. */
+static int pop PARAMS ((int x));
+
+static inline int
+pop (x)
+ int x;
+{
+ /* We assume that no more than 16 bits are used. */
+ x = ((x & ~0x5555) >> 1) + (x & 0x5555);
+ x = ((x & ~0x3333) >> 2) + (x & 0x3333);
+ x = ((x >> 4) + x) & 0x0f0f;
+ x = ((x >> 8) + x) & 0xff;
+
+ return x;
+}
+
+
+struct loaded_l10nfile *
+_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
+ territory, codeset, normalized_codeset, modifier, special,
+ sponsor, revision, filename, do_allocate)
+ struct loaded_l10nfile **l10nfile_list;
+ const char *dirlist;
+ size_t dirlist_len;
+ int mask;
+ const char *language;
+ const char *territory;
+ const char *codeset;
+ const char *normalized_codeset;
+ const char *modifier;
+ const char *special;
+ const char *sponsor;
+ const char *revision;
+ const char *filename;
+ int do_allocate;
+{
+ char *abs_filename;
+ struct loaded_l10nfile *last = NULL;
+ struct loaded_l10nfile *retval;
+ char *cp;
+ size_t entries;
+ int cnt;
+
+ /* Allocate room for the full file name. */
+ abs_filename = (char *) malloc (dirlist_len
+ + strlen (language)
+ + ((mask & TERRITORY) != 0
+ ? strlen (territory) + 1 : 0)
+ + ((mask & XPG_CODESET) != 0
+ ? strlen (codeset) + 1 : 0)
+ + ((mask & XPG_NORM_CODESET) != 0
+ ? strlen (normalized_codeset) + 1 : 0)
+ + (((mask & XPG_MODIFIER) != 0
+ || (mask & CEN_AUDIENCE) != 0)
+ ? strlen (modifier) + 1 : 0)
+ + ((mask & CEN_SPECIAL) != 0
+ ? strlen (special) + 1 : 0)
+ + (((mask & CEN_SPONSOR) != 0
+ || (mask & CEN_REVISION) != 0)
+ ? (1 + ((mask & CEN_SPONSOR) != 0
+ ? strlen (sponsor) + 1 : 0)
+ + ((mask & CEN_REVISION) != 0
+ ? strlen (revision) + 1 : 0)) : 0)
+ + 1 + strlen (filename) + 1);
+
+ if (abs_filename == NULL)
+ return NULL;
+
+ retval = NULL;
+ last = NULL;
+
+ /* Construct file name. */
+ memcpy (abs_filename, dirlist, dirlist_len);
+ __argz_stringify (abs_filename, dirlist_len, ':');
+ cp = abs_filename + (dirlist_len - 1);
+ *cp++ = '/';
+ cp = stpcpy (cp, language);
+
+ if ((mask & TERRITORY) != 0)
+ {
+ *cp++ = '_';
+ cp = stpcpy (cp, territory);
+ }
+ if ((mask & XPG_CODESET) != 0)
+ {
+ *cp++ = '.';
+ cp = stpcpy (cp, codeset);
+ }
+ if ((mask & XPG_NORM_CODESET) != 0)
+ {
+ *cp++ = '.';
+ cp = stpcpy (cp, normalized_codeset);
+ }
+ if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
+ {
+ /* This component can be part of both syntaces but has different
+ leading characters. For CEN we use `+', else `@'. */
+ *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
+ cp = stpcpy (cp, modifier);
+ }
+ if ((mask & CEN_SPECIAL) != 0)
+ {
+ *cp++ = '+';
+ cp = stpcpy (cp, special);
+ }
+ if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0)
+ {
+ *cp++ = ',';
+ if ((mask & CEN_SPONSOR) != 0)
+ cp = stpcpy (cp, sponsor);
+ if ((mask & CEN_REVISION) != 0)
+ {
+ *cp++ = '_';
+ cp = stpcpy (cp, revision);
+ }
+ }
+
+ *cp++ = '/';
+ stpcpy (cp, filename);
+
+ /* Look in list of already loaded domains whether it is already
+ available. */
+ last = NULL;
+ for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
+ if (retval->filename != NULL)
+ {
+ int compare = strcmp (retval->filename, abs_filename);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It's not in the list. */
+ retval = NULL;
+ break;
+ }
+
+ last = retval;
+ }
+
+ if (retval != NULL || do_allocate == 0)
+ {
+ free (abs_filename);
+ return retval;
+ }
+
+ retval = (struct loaded_l10nfile *)
+ malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
+ * (1 << pop (mask))
+ * sizeof (struct loaded_l10nfile *)));
+ if (retval == NULL)
+ return NULL;
+
+ retval->filename = abs_filename;
+ retval->decided = (__argz_count (dirlist, dirlist_len) != 1
+ || ((mask & XPG_CODESET) != 0
+ && (mask & XPG_NORM_CODESET) != 0));
+ retval->data = NULL;
+
+ if (last == NULL)
+ {
+ retval->next = *l10nfile_list;
+ *l10nfile_list = retval;
+ }
+ else
+ {
+ retval->next = last->next;
+ last->next = retval;
+ }
+
+ entries = 0;
+ /* If the DIRLIST is a real list the RETVAL entry corresponds not to
+ a real file. So we have to use the DIRLIST separation mechanism
+ of the inner loop. */
+ cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
+ for (; cnt >= 0; --cnt)
+ if ((cnt & ~mask) == 0
+ && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
+ && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
+ {
+ /* Iterate over all elements of the DIRLIST. */
+ char *dir = NULL;
+
+ while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
+ != NULL)
+ retval->successor[entries++]
+ = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
+ language, territory, codeset,
+ normalized_codeset, modifier, special,
+ sponsor, revision, filename, 1);
+ }
+ retval->successor[entries] = NULL;
+
+ return retval;
+}
+
+/* Normalize codeset name. There is no standard for the codeset
+ names. Normalization allows the user to use any of the common
+ names. */
+const char *
+_nl_normalize_codeset (codeset, name_len)
+ const char *codeset;
+ size_t name_len;
+{
+ int len = 0;
+ int only_digit = 1;
+ char *retval;
+ char *wp;
+ size_t cnt;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalnum (codeset[cnt]))
+ {
+ ++len;
+
+ if (isalpha (codeset[cnt]))
+ only_digit = 0;
+ }
+
+ retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
+
+ if (retval != NULL)
+ {
+ if (only_digit)
+ wp = stpcpy (retval, "iso");
+ else
+ wp = retval;
+
+ for (cnt = 0; cnt < name_len; ++cnt)
+ if (isalpha (codeset[cnt]))
+ *wp++ = tolower (codeset[cnt]);
+ else if (isdigit (codeset[cnt]))
+ *wp++ = codeset[cnt];
+
+ *wp = '\0';
+ }
+
+ return (const char *) retval;
+}
+
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
diff --git a/intl/libgettext.h b/intl/libgettext.h
new file mode 100644
index 00000000000..0d4de4d0ee1
--- /dev/null
+++ b/intl/libgettext.h
@@ -0,0 +1,182 @@
+/* Message catalogs for internationalization.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Because on some systems (e.g. Solaris) we sometimes have to include
+ the systems libintl.h as well as this file we have more complex
+ include protection above. But the systems header might perhaps also
+ define _LIBINTL_H and therefore we have to protect the definition here. */
+
+#if !defined (_LIBINTL_H) || !defined (_LIBGETTEXT_H)
+#if !defined (_LIBINTL_H)
+# define _LIBINTL_H 1
+#endif
+#define _LIBGETTEXT_H 1
+
+/* We define an additional symbol to signal that we use the GNU
+ implementation of gettext. */
+#define __USE_GNU_GETTEXT 1
+
+#include <sys/types.h>
+
+#if HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* @@ end of prolog @@ */
+
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+#ifndef NULL
+# if !defined __cplusplus || defined __GNUC__
+# define NULL ((void *) 0)
+# else
+# define NULL (0)
+# endif
+#endif
+
+#if !HAVE_LC_MESSAGES
+/* This value determines the behaviour of the gettext() and dgettext()
+ function. But some system does not have this defined. Define it
+ to a default value. */
+# define LC_MESSAGES (-1)
+#endif
+
+
+/* Declarations for gettext-using-catgets interface. Derived from
+ Jim Meyering's libintl.h. */
+struct _msg_ent
+{
+ const char *_msg;
+ int _msg_number;
+};
+
+
+#if HAVE_CATGETS
+/* These two variables are defined in the automatically by po-to-tbl.sed
+ generated file `cat-id-tbl.c'. */
+extern const struct _msg_ent _msg_tbl[];
+extern int _msg_tbl_length;
+#endif
+
+
+/* For automatical extraction of messages sometimes no real
+ translation is needed. Instead the string itself is the result. */
+#define gettext_noop(Str) (Str)
+
+/* Look up MSGID in the current default message catalog for the current
+ LC_MESSAGES locale. If not found, returns MSGID itself (the default
+ text). */
+extern char *gettext PARAMS ((const char *__msgid));
+extern char *gettext__ PARAMS ((const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current
+ LC_MESSAGES locale. */
+extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid));
+extern char *dgettext__ PARAMS ((const char *__domainname,
+ const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+ locale. */
+extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid,
+ int __category));
+extern char *dcgettext__ PARAMS ((const char *__domainname,
+ const char *__msgid, int __category));
+
+
+/* Set the current default message catalog to DOMAINNAME.
+ If DOMAINNAME is null, return the current default.
+ If DOMAINNAME is "", reset to the default of "messages". */
+extern char *textdomain PARAMS ((const char *__domainname));
+extern char *textdomain__ PARAMS ((const char *__domainname));
+
+/* Specify that the DOMAINNAME message catalog will be found
+ in DIRNAME rather than in the system locale data base. */
+extern char *bindtextdomain PARAMS ((const char *__domainname,
+ const char *__dirname));
+extern char *bindtextdomain__ PARAMS ((const char *__domainname,
+ const char *__dirname));
+
+#if ENABLE_NLS
+
+/* Solaris 2.3 has the gettext function but dcgettext is missing.
+ So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4
+ has dcgettext. */
+# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT)
+
+# define gettext(Msgid) \
+ dgettext (NULL, Msgid)
+
+# define dgettext(Domainname, Msgid) \
+ dcgettext (Domainname, Msgid, LC_MESSAGES)
+
+# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+/* This global variable is defined in loadmsgcat.c. We need a sign,
+ whether a new catalog was loaded, which can be associated with all
+ translations. */
+extern int _nl_msg_cat_cntr;
+
+# define dcgettext(Domainname, Msgid, Category) \
+ (__extension__ \
+ ({ \
+ char *__result; \
+ if (__builtin_constant_p (Msgid)) \
+ { \
+ static char *__translation__; \
+ static int __catalog_counter__; \
+ if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
+ { \
+ __translation__ = \
+ dcgettext__ (Domainname, Msgid, Category); \
+ __catalog_counter__ = _nl_msg_cat_cntr; \
+ } \
+ __result = __translation__; \
+ } \
+ else \
+ __result = dcgettext__ (Domainname, Msgid, Category); \
+ __result; \
+ }))
+# endif
+# endif
+
+#else
+
+# define gettext(Msgid) (Msgid)
+# define dgettext(Domainname, Msgid) (Msgid)
+# define dcgettext(Domainname, Msgid, Category) (Msgid)
+# define textdomain(Domainname) while (0) /* nothing */
+# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */
+
+#endif
+
+/* @@ begin of epilog @@ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/intl/libintl.glibc b/intl/libintl.glibc
new file mode 100644
index 00000000000..8e5b8f9e694
--- /dev/null
+++ b/intl/libintl.glibc
@@ -0,0 +1,111 @@
+/* libgettext.h -- Message catalogs for internationalization.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper.
+This file is derived from the file libgettext.h in the GNU gettext package.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef _LIBINTL_H
+#define _LIBINTL_H 1
+#include <features.h>
+
+#include <locale.h>
+
+#define __need_NULL
+#include <stddef.h>
+
+/* We define an additional symbol to signal that we use the GNU
+ implementation of gettext. */
+#define __USE_GNU_GETTEXT 1
+
+__BEGIN_DECLS
+
+/* Look up MSGID in the current default message catalog for the current
+ LC_MESSAGES locale. If not found, returns MSGID itself (the default
+ text). */
+extern char *gettext __P ((__const char *__msgid));
+extern char *__gettext __P ((__const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current
+ LC_MESSAGES locale. */
+extern char *dgettext __P ((__const char *__domainname,
+ __const char *__msgid));
+extern char *__dgettext __P ((__const char *__domainname,
+ __const char *__msgid));
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
+ locale. */
+extern char *dcgettext __P ((__const char *__domainname,
+ __const char *__msgid, int __category));
+extern char *__dcgettext __P ((__const char *__domainname,
+ __const char *__msgid, int __category));
+
+
+/* Set the current default message catalog to DOMAINNAME.
+ If DOMAINNAME is null, return the current default.
+ If DOMAINNAME is "", reset to the default of "messages". */
+extern char *textdomain __P ((__const char *__domainname));
+extern char *__textdomain __P ((__const char *__domainname));
+
+/* Specify that the DOMAINNAME message catalog will be found
+ in DIRNAME rather than in the system locale data base. */
+extern char *bindtextdomain __P ((__const char *__domainname,
+ __const char *__dirname));
+extern char *__bindtextdomain __P ((__const char *__domainname,
+ __const char *__dirname));
+
+
+/* Optimized version of the function above. */
+#if defined __OPTIMIZED
+/* These must be a macro. Inlined functions are useless because the
+ `__builtin_constant_p' predicate in dcgettext would always return
+ false. */
+
+# define gettext(msgid) dgettext (NULL, msgid)
+
+# define dgettext(domainname, msgid) \
+ dcgettext (domainname, msgid, LC_MESSAGES)
+
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+# define dcgettext(domainname, msgid, category) \
+ (__extension__ \
+ ({ \
+ char *result; \
+ if (__builtin_constant_p (msgid)) \
+ { \
+ extern int _nl_msg_cat_cntr; \
+ static char *__translation__; \
+ static int __catalog_counter__; \
+ if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
+ { \
+ __translation__ = \
+ __dcgettext ((domainname), (msgid), (category)); \
+ __catalog_counter__ = _nl_msg_cat_cntr; \
+ } \
+ result = __translation__; \
+ } \
+ else \
+ result = __dcgettext ((domainname), (msgid), (category)); \
+ result; \
+ }))
+# endif
+#endif /* Optimizing. */
+
+
+__END_DECLS
+
+#endif /* libintl.h */
diff --git a/intl/linux-msg.sed b/intl/linux-msg.sed
new file mode 100644
index 00000000000..5918e720a9a
--- /dev/null
+++ b/intl/linux-msg.sed
@@ -0,0 +1,100 @@
+# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+#
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+# The first directive in the .msg should be the definition of the
+# message set number. We use always set number 1.
+#
+1 {
+ i\
+$set 1 # Automatically created by po2msg.sed
+ h
+ s/.*/0/
+ x
+}
+#
+# Mitch's old catalog format does not allow comments.
+#
+# We copy the original message as a comment into the .msg file.
+#
+/^msgid/ {
+ s/msgid[ ]*"//
+#
+# This does not work now with the new format.
+# /"$/! {
+# s/\\$//
+# s/$/ ... (more lines following)"/
+# }
+ x
+# The following nice solution is by
+# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
+ td
+# Increment a decimal number in pattern space.
+# First hide trailing `9' digits.
+ :d
+ s/9\(_*\)$/_\1/
+ td
+# Assure at least one digit is available.
+ s/^\(_*\)$/0\1/
+# Increment the last digit.
+ s/8\(_*\)$/9\1/
+ s/7\(_*\)$/8\1/
+ s/6\(_*\)$/7\1/
+ s/5\(_*\)$/6\1/
+ s/4\(_*\)$/5\1/
+ s/3\(_*\)$/4\1/
+ s/2\(_*\)$/3\1/
+ s/1\(_*\)$/2\1/
+ s/0\(_*\)$/1\1/
+# Convert the hidden `9' digits to `0's.
+ s/_/0/g
+ x
+ G
+ s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p
+}
+#
+# The .msg file contains, other then the .po file, only the translations
+# but each given a unique ID. Starting from 1 and incrementing by 1 for
+# each message we assign them to the messages.
+# It is important that the .po file used to generate the cat-id-tbl.c file
+# (with po-to-tbl) is the same as the one used here. (At least the order
+# of declarations must not be changed.)
+#
+/^msgstr/ {
+ s/msgstr[ ]*"\(.*\)"/# \1/
+# Clear substitution flag.
+ tb
+# Append the next line.
+ :b
+ N
+# Look whether second part is continuation line.
+ s/\(.*\n\)"\(.*\)"/\1\2/
+# Yes, then branch.
+ ta
+ P
+ D
+# Note that D includes a jump to the start!!
+# We found a continuation line. But before printing insert '\'.
+ :a
+ s/\(.*\)\(\n.*\)/\1\\\2/
+ P
+# We cannot use D here.
+ s/.*\n\(.*\)/\1/
+ tb
+}
+d
diff --git a/intl/loadinfo.h b/intl/loadinfo.h
new file mode 100644
index 00000000000..c67c2eb2e8e
--- /dev/null
+++ b/intl/loadinfo.h
@@ -0,0 +1,58 @@
+#ifndef PARAMS
+# if __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+/* Encoding of locale name parts. */
+#define CEN_REVISION 1
+#define CEN_SPONSOR 2
+#define CEN_SPECIAL 4
+#define XPG_NORM_CODESET 8
+#define XPG_CODESET 16
+#define TERRITORY 32
+#define CEN_AUDIENCE 64
+#define XPG_MODIFIER 128
+
+#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
+#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
+
+
+struct loaded_l10nfile
+{
+ const char *filename;
+ int decided;
+
+ const void *data;
+
+ struct loaded_l10nfile *next;
+ struct loaded_l10nfile *successor[1];
+};
+
+
+extern const char *_nl_normalize_codeset PARAMS ((const char *codeset,
+ size_t name_len));
+
+extern struct loaded_l10nfile *
+_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list,
+ const char *dirlist, size_t dirlist_len, int mask,
+ const char *language, const char *territory,
+ const char *codeset,
+ const char *normalized_codeset,
+ const char *modifier, const char *special,
+ const char *sponsor, const char *revision,
+ const char *filename, int do_allocate));
+
+
+extern const char *_nl_expand_alias PARAMS ((const char *name));
+
+extern int _nl_explode_name PARAMS ((char *name, const char **language,
+ const char **modifier,
+ const char **territory,
+ const char **codeset,
+ const char **normalized_codeset,
+ const char **special,
+ const char **sponsor,
+ const char **revision));
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
new file mode 100644
index 00000000000..73e90a9190f
--- /dev/null
+++ b/intl/loadmsgcat.c
@@ -0,0 +1,199 @@
+/* Load needed message catalogs
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC
+# include <sys/mman.h>
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ISO C functions. This is required by the standard
+ because some ISO C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define fstat __fstat
+# define open __open
+# define close __close
+# define read __read
+# define mmap __mmap
+# define munmap __munmap
+#endif
+
+/* We need a sign, whether a new catalog was loaded, which can be associated
+ with all translations. This is important if the translations are
+ cached by one of GCC's features. */
+int _nl_msg_cat_cntr = 0;
+
+
+/* Load the message catalogs specified by FILENAME. If it is no valid
+ message catalog do nothing. */
+void
+_nl_load_domain (domain_file)
+ struct loaded_l10nfile *domain_file;
+{
+ int fd;
+ struct stat st;
+ struct mo_file_header *data = (struct mo_file_header *) -1;
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+ || defined _LIBC
+ int use_mmap = 0;
+#endif
+ struct loaded_domain *domain;
+
+ domain_file->decided = 1;
+ domain_file->data = NULL;
+
+ /* If the record does not represent a valid locale the FILENAME
+ might be NULL. This can happen when according to the given
+ specification the locale file name is different for XPG and CEN
+ syntax. */
+ if (domain_file->filename == NULL)
+ return;
+
+ /* Try to open the addressed file. */
+ fd = open (domain_file->filename, O_RDONLY);
+ if (fd == -1)
+ return;
+
+ /* We must know about the size of the file. */
+ if (fstat (fd, &st) != 0
+ && st.st_size < (off_t) sizeof (struct mo_file_header))
+ {
+ /* Something went wrong. */
+ close (fd);
+ return;
+ }
+
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+ || defined _LIBC
+ /* Now we are ready to load the file. If mmap() is available we try
+ this first. If not available or it failed we try to load it. */
+ data = (struct mo_file_header *) mmap (NULL, st.st_size, PROT_READ,
+ MAP_PRIVATE, fd, 0);
+
+ if (data != (struct mo_file_header *) -1)
+ {
+ /* mmap() call was successful. */
+ close (fd);
+ use_mmap = 1;
+ }
+#endif
+
+ /* If the data is not yet available (i.e. mmap'ed) we try to load
+ it manually. */
+ if (data == (struct mo_file_header *) -1)
+ {
+ off_t to_read;
+ char *read_ptr;
+
+ data = (struct mo_file_header *) malloc (st.st_size);
+ if (data == NULL)
+ return;
+
+ to_read = st.st_size;
+ read_ptr = (char *) data;
+ do
+ {
+ long int nb = (long int) read (fd, read_ptr, to_read);
+ if (nb == -1)
+ {
+ close (fd);
+ return;
+ }
+
+ read_ptr += nb;
+ to_read -= nb;
+ }
+ while (to_read > 0);
+
+ close (fd);
+ }
+
+ /* Using the magic number we can test whether it really is a message
+ catalog file. */
+ if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
+ {
+ /* The magic number is wrong: not a message catalog file. */
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+ || defined _LIBC
+ if (use_mmap)
+ munmap ((caddr_t) data, st.st_size);
+ else
+#endif
+ free (data);
+ return;
+ }
+
+ domain_file->data
+ = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
+ if (domain_file->data == NULL)
+ return;
+
+ domain = (struct loaded_domain *) domain_file->data;
+ domain->data = (char *) data;
+ domain->must_swap = data->magic != _MAGIC;
+
+ /* Fill in the information about the available tables. */
+ switch (W (domain->must_swap, data->revision))
+ {
+ case 0:
+ domain->nstrings = W (domain->must_swap, data->nstrings);
+ domain->orig_tab = (struct string_desc *)
+ ((char *) data + W (domain->must_swap, data->orig_tab_offset));
+ domain->trans_tab = (struct string_desc *)
+ ((char *) data + W (domain->must_swap, data->trans_tab_offset));
+ domain->hash_size = W (domain->must_swap, data->hash_tab_size);
+ domain->hash_tab = (nls_uint32 *)
+ ((char *) data + W (domain->must_swap, data->hash_tab_offset));
+ break;
+ default:
+ /* This is an illegal revision. */
+#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
+ || defined _LIBC
+ if (use_mmap)
+ munmap ((caddr_t) data, st.st_size);
+ else
+#endif
+ free (data);
+ free (domain);
+ domain_file->data = NULL;
+ return;
+ }
+
+ /* Show that one domain is changed. This might make some cached
+ translations invalid. */
+ ++_nl_msg_cat_cntr;
+}
diff --git a/intl/localealias.c b/intl/localealias.c
new file mode 100644
index 00000000000..00d91941b9b
--- /dev/null
+++ b/intl/localealias.c
@@ -0,0 +1,378 @@
+/* Handle aliases for locale names
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
+#else
+# if defined HAVE_ALLOCA_H || defined _LIBC
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#else
+char *getenv ();
+# ifdef HAVE_MALLOC_H
+# include <malloc.h>
+# else
+void free ();
+# endif
+#endif
+
+#if defined HAVE_STRING_H || defined _LIBC
+# ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+# endif
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+#if !HAVE_STRCHR && !defined _LIBC
+# ifndef strchr
+# define strchr index
+# endif
+#endif
+
+#include "gettext.h"
+#include "gettextP.h"
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define strcasecmp __strcasecmp
+#endif
+
+
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old); \
+ } \
+ } while (0)
+# undef alloca
+# define alloca(size) (malloc (size))
+#endif /* have alloca */
+
+
+struct alias_map
+{
+ const char *alias;
+ const char *value;
+};
+
+
+static struct alias_map *map;
+static size_t nmap = 0;
+static size_t maxmap = 0;
+
+
+/* Prototypes for local functions. */
+static size_t read_alias_file PARAMS ((const char *fname, int fname_len));
+static void extend_alias_table PARAMS ((void));
+static int alias_compare PARAMS ((const struct alias_map *map1,
+ const struct alias_map *map2));
+
+
+const char *
+_nl_expand_alias (name)
+ const char *name;
+{
+ static const char *locale_alias_path = LOCALE_ALIAS_PATH;
+ struct alias_map *retval;
+ size_t added;
+
+ do
+ {
+ struct alias_map item;
+
+ item.alias = name;
+
+ if (nmap > 0)
+ retval = (struct alias_map *) bsearch (&item, map, nmap,
+ sizeof (struct alias_map),
+ (int (*) PARAMS ((const void *,
+ const void *))
+ ) alias_compare);
+ else
+ retval = NULL;
+
+ /* We really found an alias. Return the value. */
+ if (retval != NULL)
+ return retval->value;
+
+ /* Perhaps we can find another alias file. */
+ added = 0;
+ while (added == 0 && locale_alias_path[0] != '\0')
+ {
+ const char *start;
+
+ while (locale_alias_path[0] == ':')
+ ++locale_alias_path;
+ start = locale_alias_path;
+
+ while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':')
+ ++locale_alias_path;
+
+ if (start < locale_alias_path)
+ added = read_alias_file (start, locale_alias_path - start);
+ }
+ }
+ while (added != 0);
+
+ return NULL;
+}
+
+
+static size_t
+read_alias_file (fname, fname_len)
+ const char *fname;
+ int fname_len;
+{
+#ifndef HAVE_ALLOCA
+ struct block_list *block_list = NULL;
+#endif
+ FILE *fp;
+ char *full_fname;
+ size_t added;
+ static const char aliasfile[] = "/locale.alias";
+
+ full_fname = (char *) alloca (fname_len + sizeof aliasfile);
+ ADD_BLOCK (block_list, full_fname);
+ memcpy (full_fname, fname, fname_len);
+ memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
+
+ fp = fopen (full_fname, "r");
+ if (fp == NULL)
+ {
+ FREE_BLOCKS (block_list);
+ return 0;
+ }
+
+ added = 0;
+ while (!feof (fp))
+ {
+ /* It is a reasonable approach to use a fix buffer here because
+ a) we are only interested in the first two fields
+ b) these fields must be usable as file names and so must not
+ be that long
+ */
+ char buf[BUFSIZ];
+ char *alias;
+ char *value;
+ char *cp;
+
+ if (fgets (buf, BUFSIZ, fp) == NULL)
+ /* EOF reached. */
+ break;
+
+ cp = buf;
+ /* Ignore leading white space. */
+ while (isspace (cp[0]))
+ ++cp;
+
+ /* A leading '#' signals a comment line. */
+ if (cp[0] != '\0' && cp[0] != '#')
+ {
+ alias = cp++;
+ while (cp[0] != '\0' && !isspace (cp[0]))
+ ++cp;
+ /* Terminate alias name. */
+ if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ /* Now look for the beginning of the value. */
+ while (isspace (cp[0]))
+ ++cp;
+
+ if (cp[0] != '\0')
+ {
+ char *tp;
+ size_t len;
+
+ value = cp++;
+ while (cp[0] != '\0' && !isspace (cp[0]))
+ ++cp;
+ /* Terminate value. */
+ if (cp[0] == '\n')
+ {
+ /* This has to be done to make the following test
+ for the end of line possible. We are looking for
+ the terminating '\n' which do not overwrite here. */
+ *cp++ = '\0';
+ *cp = '\n';
+ }
+ else if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ if (nmap >= maxmap)
+ extend_alias_table ();
+
+ /* We cannot depend on strdup available in the libc. Sigh! */
+ len = strlen (alias) + 1;
+ tp = (char *) malloc (len);
+ if (tp == NULL)
+ {
+ FREE_BLOCKS (block_list);
+ return added;
+ }
+ memcpy (tp, alias, len);
+ map[nmap].alias = tp;
+
+ len = strlen (value) + 1;
+ tp = (char *) malloc (len);
+ if (tp == NULL)
+ {
+ FREE_BLOCKS (block_list);
+ return added;
+ }
+ memcpy (tp, value, len);
+ map[nmap].value = tp;
+
+ ++nmap;
+ ++added;
+ }
+ }
+
+ /* Possibly not the whole line fits into the buffer. Ignore
+ the rest of the line. */
+ while (strchr (cp, '\n') == NULL)
+ {
+ cp = buf;
+ if (fgets (buf, BUFSIZ, fp) == NULL)
+ /* Make sure the inner loop will be left. The outer loop
+ will exit at the `feof' test. */
+ *cp = '\n';
+ }
+ }
+
+ /* Should we test for ferror()? I think we have to silently ignore
+ errors. --drepper */
+ fclose (fp);
+
+ if (added > 0)
+ qsort (map, nmap, sizeof (struct alias_map),
+ (int (*) PARAMS ((const void *, const void *))) alias_compare);
+
+ FREE_BLOCKS (block_list);
+ return added;
+}
+
+
+static void
+extend_alias_table ()
+{
+ size_t new_size;
+ struct alias_map *new_map;
+
+ new_size = maxmap == 0 ? 100 : 2 * maxmap;
+ new_map = (struct alias_map *) malloc (new_size
+ * sizeof (struct alias_map));
+ if (new_map == NULL)
+ /* Simply don't extend: we don't have any more core. */
+ return;
+
+ memcpy (new_map, map, nmap * sizeof (struct alias_map));
+
+ if (maxmap != 0)
+ free (map);
+
+ map = new_map;
+ maxmap = new_size;
+}
+
+
+static int
+alias_compare (map1, map2)
+ const struct alias_map *map1;
+ const struct alias_map *map2;
+{
+#if defined _LIBC || defined HAVE_STRCASECMP
+ return strcasecmp (map1->alias, map2->alias);
+#else
+ const unsigned char *p1 = (const unsigned char *) map1->alias;
+ const unsigned char *p2 = (const unsigned char *) map2->alias;
+ unsigned char c1, c2;
+
+ if (p1 == p2)
+ return 0;
+
+ do
+ {
+ /* I know this seems to be odd but the tolower() function in
+ some systems libc cannot handle nonalpha characters. */
+ c1 = isupper (*p1) ? tolower (*p1) : *p1;
+ c2 = isupper (*p2) ? tolower (*p2) : *p2;
+ if (c1 == '\0')
+ break;
+ ++p1;
+ ++p2;
+ }
+ while (c1 == c2);
+
+ return c1 - c2;
+#endif
+}
diff --git a/intl/po2tbl.sed.in b/intl/po2tbl.sed.in
new file mode 100644
index 00000000000..b3bcca4d730
--- /dev/null
+++ b/intl/po2tbl.sed.in
@@ -0,0 +1,102 @@
+# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+#
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+1 {
+ i\
+/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\
+\
+#if HAVE_CONFIG_H\
+# include <config.h>\
+#endif\
+\
+#include "libgettext.h"\
+\
+const struct _msg_ent _msg_tbl[] = {
+ h
+ s/.*/0/
+ x
+}
+#
+# Write msgid entries in C array form.
+#
+/^msgid/ {
+ s/msgid[ ]*\(".*"\)/ {\1/
+ tb
+# Append the next line
+ :b
+ N
+# Look whether second part is continuation line.
+ s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/
+# Yes, then branch.
+ ta
+# Because we assume that the input file correctly formed the line
+# just read cannot be again be a msgid line. So it's safe to ignore
+# it.
+ s/\(.*\)\n.*/\1/
+ bc
+# We found a continuation line. But before printing insert '\'.
+ :a
+ s/\(.*\)\(\n.*\)/\1\\\2/
+ P
+# We cannot use D here.
+ s/.*\n\(.*\)/\1/
+# Some buggy seds do not clear the `successful substitution since last ``t'''
+# flag on `N', so we do a `t' here to clear it.
+ tb
+# Not reached
+ :c
+ x
+# The following nice solution is by
+# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
+ td
+# Increment a decimal number in pattern space.
+# First hide trailing `9' digits.
+ :d
+ s/9\(_*\)$/_\1/
+ td
+# Assure at least one digit is available.
+ s/^\(_*\)$/0\1/
+# Increment the last digit.
+ s/8\(_*\)$/9\1/
+ s/7\(_*\)$/8\1/
+ s/6\(_*\)$/7\1/
+ s/5\(_*\)$/6\1/
+ s/4\(_*\)$/5\1/
+ s/3\(_*\)$/4\1/
+ s/2\(_*\)$/3\1/
+ s/1\(_*\)$/2\1/
+ s/0\(_*\)$/1\1/
+# Convert the hidden `9' digits to `0's.
+ s/_/0/g
+ x
+ G
+ s/\(.*\)\n\([0-9]*\)/\1, \2},/
+ s/\(.*\)"$/\1/
+ p
+}
+#
+# Last line.
+#
+$ {
+ i\
+};\
+
+ g
+ s/0*\(.*\)/int _msg_tbl_length = \1;/p
+}
+d
diff --git a/intl/textdomain.c b/intl/textdomain.c
new file mode 100644
index 00000000000..55d93406a8a
--- /dev/null
+++ b/intl/textdomain.c
@@ -0,0 +1,106 @@
+/* Implementation of the textdomain(3) function
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+#endif
+
+#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
+# endif
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgettext.h"
+#endif
+
+/* @@ end of prolog @@ */
+
+/* Name of the default text domain. */
+extern const char _nl_default_default_domain[];
+
+/* Default text domain in which entries for gettext(3) are to be found. */
+extern const char *_nl_current_default_domain;
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define TEXTDOMAIN __textdomain
+# define strdup(str) __strdup (str)
+#else
+# define TEXTDOMAIN textdomain__
+#endif
+
+/* Set the current default message catalog to DOMAINNAME.
+ If DOMAINNAME is null, return the current default.
+ If DOMAINNAME is "", reset to the default of "messages". */
+char *
+TEXTDOMAIN (domainname)
+ const char *domainname;
+{
+ char *old;
+
+ /* A NULL pointer requests the current setting. */
+ if (domainname == NULL)
+ return (char *) _nl_current_default_domain;
+
+ old = (char *) _nl_current_default_domain;
+
+ /* If domain name is the null string set to default domain "messages". */
+ if (domainname[0] == '\0'
+ || strcmp (domainname, _nl_default_default_domain) == 0)
+ _nl_current_default_domain = _nl_default_default_domain;
+ else
+ {
+ /* If the following malloc fails `_nl_current_default_domain'
+ will be NULL. This value will be returned and so signals we
+ are out of core. */
+#if defined _LIBC || defined HAVE_STRDUP
+ _nl_current_default_domain = strdup (domainname);
+#else
+ size_t len = strlen (domainname) + 1;
+ char *cp = (char *) malloc (len);
+ if (cp != NULL)
+ memcpy (cp, domainname, len);
+ _nl_current_default_domain = cp;
+#endif
+ }
+
+ if (old != _nl_default_default_domain)
+ free (old);
+
+ return (char *) _nl_current_default_domain;
+}
+
+#ifdef _LIBC
+/* Alias for function name in GNU C Library. */
+weak_alias (__textdomain, textdomain);
+#endif
diff --git a/intl/xopen-msg.sed b/intl/xopen-msg.sed
new file mode 100644
index 00000000000..b19c0bbd0ec
--- /dev/null
+++ b/intl/xopen-msg.sed
@@ -0,0 +1,104 @@
+# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file
+# Copyright (C) 1995 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+#
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#
+# The first directive in the .msg should be the definition of the
+# message set number. We use always set number 1.
+#
+1 {
+ i\
+$set 1 # Automatically created by po2msg.sed
+ h
+ s/.*/0/
+ x
+}
+#
+# We copy all comments into the .msg file. Perhaps they can help.
+#
+/^#/ s/^#[ ]*/$ /p
+#
+# We copy the original message as a comment into the .msg file.
+#
+/^msgid/ {
+# Does not work now
+# /"$/! {
+# s/\\$//
+# s/$/ ... (more lines following)"/
+# }
+ s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/
+ p
+}
+#
+# The .msg file contains, other then the .po file, only the translations
+# but each given a unique ID. Starting from 1 and incrementing by 1 for
+# each message we assign them to the messages.
+# It is important that the .po file used to generate the cat-id-tbl.c file
+# (with po-to-tbl) is the same as the one used here. (At least the order
+# of declarations must not be changed.)
+#
+/^msgstr/ {
+ s/msgstr[ ]*"\(.*\)"/\1/
+ x
+# The following nice solution is by
+# Bruno <Haible@ma2s2.mathematik.uni-karlsruhe.de>
+ td
+# Increment a decimal number in pattern space.
+# First hide trailing `9' digits.
+ :d
+ s/9\(_*\)$/_\1/
+ td
+# Assure at least one digit is available.
+ s/^\(_*\)$/0\1/
+# Increment the last digit.
+ s/8\(_*\)$/9\1/
+ s/7\(_*\)$/8\1/
+ s/6\(_*\)$/7\1/
+ s/5\(_*\)$/6\1/
+ s/4\(_*\)$/5\1/
+ s/3\(_*\)$/4\1/
+ s/2\(_*\)$/3\1/
+ s/1\(_*\)$/2\1/
+ s/0\(_*\)$/1\1/
+# Convert the hidden `9' digits to `0's.
+ s/_/0/g
+ x
+# Bring the line in the format `<number> <message>'
+ G
+ s/^[^\n]*$/& /
+ s/\(.*\)\n\([0-9]*\)/\2 \1/
+# Clear flag from last substitution.
+ tb
+# Append the next line.
+ :b
+ N
+# Look whether second part is a continuation line.
+ s/\(.*\n\)"\(.*\)"/\1\2/
+# Yes, then branch.
+ ta
+ P
+ D
+# Note that `D' includes a jump to the start!!
+# We found a continuation line. But before printing insert '\'.
+ :a
+ s/\(.*\)\(\n.*\)/\1\\\2/
+ P
+# We cannot use the sed command `D' here
+ s/.*\n\(.*\)/\1/
+ tb
+}
+d
diff --git a/ld/ChangeLog b/ld/ChangeLog
new file mode 100644
index 00000000000..2302da3a89a
--- /dev/null
+++ b/ld/ChangeLog
@@ -0,0 +1,8933 @@
+1999-04-29 Nick Clifton <nickc@cygnus.com>
+
+ * emulparams/elf32mcore.sh (OTHER_BSS_SYMBOLS): Define.
+ (OTHER_BSS_END_SYMBOLS): Define.
+
+ * scripttempl/mcorepe.sc: New file: Duplicte of pe.sc with stack
+ section added.
+
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-22 Nick Clifton <nickc@cygnus.com>
+
+ * emulparams/elf32mcore.sh (OTHER_RELOCATING_SECTIONS): Define to
+ generate _stack section.
+
+1999-04-12 Philip Blundell <pb@nexus.co.uk>
+
+ * emulparams/armelf_linux.sh: New file. Support for ARM
+ GNU/Linux ELF ABI.
+ * emulparams/armelf_linux26.sh: New file. APCS-26 version of above.
+ * configure.tgt: For arm*-*-linux-gnu*, set default emulation to
+ `armelf_linux', and also include `armelf_linux26' and `armelf'.
+ * Makefile.am: Add rules to make earmlinux.c and earmlinux26.c.
+ (ALL_EMULATIONS): Add earmlinux.o and earmlinux26.o.
+ * Makefile.in: Regenerate.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.am (ALL_EMULATIONS): Add elf_i386_be.o.
+ * configure.tgt (i[3456]86-*-beos*): Use it.
+ * emulparams/elf_i386_be.sh: New file.
+ * Makefile.in: Rebuild.
+
+ * configure.in (environ): Detect declaration.
+ * ldmain.c (main): Don't declare environ.
+ * sysdep.h (environ): Declare if needed.
+ * configure, config.in: Rebuild.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * ldgram.y (ldgram_vers_current_lang): New.
+ (vers_defns): Accept `extern "lang" { }' syntax.
+ * ldlex.l (vers_node_nesting): New.
+ (V_IDENTIFIER): Accept . and $ in symbols.
+ (VERS_NODE): Accept `extern "lang" { }' tokens. Nest VERS_NODE states.
+ * ldlang.c (lang_new_vers_regex): New `lang' argument. Update callers.
+ (lang_vers_match_lang_c): New function.
+ (lang_vers_match_lang_cplusplus): New function.
+ (lang_vers_match_lang_java): New function.
+ (lang_do_version_exports_section): Fix iteration. Don't free
+ section contents, as it is still in use by the patterns.
+
+1999-04-10 Richard Henderson <rth@cygnus.com>
+
+ * ldmain.c (main): Init link_info.no_undefined.
+ * lexsup.c: Add command-line option --no-undefined.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt: Add support for MCore targets.
+ * Makefile.am: Add support for MCore targets.
+ * Makefile.in: Regenerate.
+
+ * emulparams/elf32mcore.sh: New file: Definitions for mcore-elf
+ target.
+ * emulparams/mcorepe.sh: New file: Definitions for mcore-pe
+ target.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * ld.h (LC_MESSAGES): Never define.
+ * ldmain.c (main): Don't pass LC_MESSAGES to setlocale if the
+ system does not define it.
+
+1999-04-06 H.J. Lu <hjl@gnu.org>
+
+ * ldmain.h (demangling): Declare.
+ * ldmain.c (demangling): New global variable.
+ (main): Initialize demangling.
+ * ldmisc.c (vfinfo): Don't demangle symbol if ! demangling.
+ * lexsup.c (ld_options, parse_args): Handle --demangle and
+ --no-demangle.
+ * ld.texinfo, ld.1: Document --demangle/--no-demangle.
+
+ * ldlex.l (V_IDENTIFIER): Allow '.' in symbol.
+
+1999-04-05 Chris Torek <torek@BSDI.COM>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_search_dir): Check that
+ a shared library really exists, avoiding broken symlinks.
+
+ * ldfile.c (ldfile_open_file): Generate a better error message if
+ we can't find a -l file.
+
+1999-04-05 DJ Delorie <dj@cygnus.com>
+
+ * configure.tgt (i386-*-pe): add targ_extra_ofiles for other PE
+ targets (i386-pe and i386-winnt)
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * deffilep.y: Include "sysdep.h" and "ldmisc.h".
+ (def_file_add_directive): Change return type to void. Remove
+ unused locals sh_reserve, sh_commit, and j.
+ (def_ungetc): Always return a value.
+ (def_lex): Correct parenthesization of || within &&.
+ * deffile.h (def_file_add_directive): Update declaration.
+ * pe-dll.c: Include <time.h>, <ctype.h>, and "ldemul.h".
+ (generate_edata): Remove unused local i.
+ (quoteput): Add cast to avoid warning.
+ (pe_dll_generate_def_file): Fix type in format string.
+ (quick_symbol): Remove unused local blhe.
+ (pe_dll_generate_implib): Add cast to avoid warning.
+ (pe_process_import_defs): Remove unused locals ar_head, ar_tail,
+ and n.
+ (pe_as16): Comment out.
+
+1999-04-04 Don Bowman <don@pixsci.com>
+
+ * configure.tgt: Add mips*-*-vxworks* target.
+
+1999-03-31 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.in (ALL_EMULATIONS): Add earm_epoc_pe.o
+ Add build rule and dependencies for earm_epoc_pe.c.
+
+ * emulparams/arm_epoc_pe.sh: New file.
+
+ * configure.tgt: Add 'targ_extra_ofiles' for ARM based PE
+ targets.
+
+1999-03-31 Philip Blundell <pb@nexus.co.uk>
+
+ * configure.tgt: Match `arm*-*-linux-gnu*' not
+ `armv*-*-linux-gnu'.
+
+1999-03-26 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * scripttempl/elf.sc: Put the .eh_frame and .gcc_except_table
+ sections in the data segment.
+
+Fri Mar 26 12:05:51 1999 Catherine Moore <clm@cygnus.com>
+
+ * ld.h (wildcard_spec): Add exclude_name.
+ * ldgram.y (EXCLUDE_FILE): New token.
+ (wildcard_spec): Set exclude_name.
+ (file_NAME_list): Recognize EXCLUDE_FILE.
+ * ldlang.c (wild_section): Check for excluded files.
+ (print_wild_statement): Print excluded files.
+ (lang_add_wild): New argument exclude_filename.
+ Set exclude_filename.
+ * ldlang.h (lang_wild_statement_type): Add exclude_filename.
+ * ldlex.l: New token EXCLUDE_FILE.
+ * mri.c (mri_draw_tree): Add argument to lang_add_wild.
+ * scripttempl/elf.sc (CTOR, DTOR): Exclude crtend.o from ctor wildcard.
+ Reorder sorted and unsorted ctors.
+ * scripttempl/elfd10v.sc (CTOR, DTOR): Likewise.
+ * scripttempl/elfd30v.sc (CTOR, DTOR): Likewise.
+ * scripttempl/elfppc.sc (CTOR, DTOR): Likewise.
+
+1999-03-26 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_gc_sections): If entry_symbol is not defined,
+ default to "start".
+
+1999-03-03 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/elf.sc: Add explicit placements for the .eh_frame
+ and .gcc_except_table sections.
+
+Wed Mar 3 09:13:34 1999 Catherine Moore <clm@cygnus.clm>
+
+ * scripttempl/elf.sc: Remove .end.ctors and .end.dtors
+ sections. Reorder .ctors section entries.
+ * scripttempl/elfd10v.sc: Likewise.
+ * scripttempl/elfd30v.sc: Likewise.
+ * scripttempl/elfppc.sc: Likewise.
+
+1999-02-26 Jim Lemke <jlemke@cygnus.com>
+
+ * ldmain.c (main): Wrong error msg for -r and --mpc860c0.
+
+1999-02-25 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_check_section_addresses): Remove extraneous
+ backslash.
+
+Thu Feb 25 15:07:24 1999 Catherine Moore <clm@cygnus.com>
+
+ * scripttempl/elf.sc: Don't gather .ctor and .dtor sections
+ for relocateable links.
+ * scripttempl/elfd10v.sc: Likewise.
+ * scripttempl/elfd30v.sc: Likewise.
+ * scripttempl/elfppc.sc: Likewise.
+
+1999-02-22 Jim Lemke <jlemke@cygnus.com>
+
+ * ldint.texinfo: remove extraneous right brace.
+ * ldmain.c (main): initialize and check option "mpc860c0".
+ * lexsup.c (ld_options, parse_args): add option "mpc860c0".
+
+Wed Feb 17 12:10:06 1999 Stan Cox <scox@cygnus.com>
+
+ * mpw-elfmips.c (gldelf32ebmip_before_allocation): Remove special
+ .reginfo section handling.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Likewise.
+ * emulparams/elf32elmip.sh (INITIAL_READONLY_SECTIONS): Removed
+ * emulparams/elf32ebmip.sh (INITIAL_READONLY_SECTIONS): Removed
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ Patch from: Scott Bambrough <scottb@corelcomputer.com>
+
+ * configure.tgt: Added armv*-*-linux-gnu to $targ_emul
+ recognition.
+
+Wed Feb 17 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * emultempl/armelf_oabi.em
+ (bfd_elf32_arm_allocate_interworking_sections,
+ bfd_elf32_arm_get_bfd_for_interworking,
+ bfd_elf32_arm_process_before_allocation): Define them to use the
+ old ABI versions of the functions.
+
+Tue Feb 16 16:48:19 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change AC_PREREQ to 2.13. Change AM_PROG_INSTALL
+ to AC_PROG_INSTALL. Change AM_EXEEXT to AC_EXEEXT.
+ * Makefile.am (earmelf_oabi.c): Changes spaces to tab.
+ * acconfig.h: Remove.
+ * aclocal.m4: Rebuild.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+
+Mon Feb 15 18:21:48 1999 Vladimir N. Makarov <vmakarov@cygnus.com>
+
+ * ldexp.h (struct etree_value_type): Change valid onto valid_p.
+
+ * ldexp.c (new_abs): Ditto.
+ (new_rel, new_rel_from_section, fold_binary, invalid, fold_name,
+ exp_fold_tree, exp_binop, exp_trinop, stat_alloc,
+ exp_get_abs_int): Ditto
+
+ * ldlang.c (print_assignment, lang_size_sections,
+ lang_do_assignments): Ditto.
+
+1999-02-11 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_check_section_addresses): New function: Check
+ addresses assigned to section for overlaps.
+ (lang_process): Call lang_check_section_addresses if suitable.
+
+ * ld.h: Add new boolean field to args_type structure:
+ 'check_section_addresses'.
+
+ * ldmain.c: Initialise check_section_addresses field to true.
+
+ * lexsup.c: Add new command line options '--no-check-sections' and
+ '--check-sections'.
+
+ * ld.texinfo: Document new command line options '--check-sections'
+ and '--no-check-sections'.
+
+1999-02-08 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt: Add support for StrongARM target.
+
+Wed Feb 3 19:41:01 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldctor.c (ldctor_build_sets): Just set SEC_KEEP once. Check for
+ an owner of a section before using it to look up a reloc type.
+ Don't set SEC_KEEP for the absolute section.
+
+Mon Feb 1 11:39:46 1999 Catherine Moore <clm@cygnus.com>
+
+ * Makefile.am (earmelf_oabi.o): New.
+ * Makefile.in: Regenerate.
+ * configure.tgt (arm-*-oabi): New.
+ (thumb-*-oabi): New.
+ * emulparams/armelf_oabi.sh: New.
+ * emultempl/armelf_oabi.em: New.
+
+1999-01-31 17:57:31 1998 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfppc.sc: Add support for -fleading-underscores
+ switch in all linker generated symbols.
+
+ * configure.tgt (powerpc{,le}*-*-vxworks): Add as aliases for
+ powerpc{,le}-*-eabi.
+
+Wed Jan 20 17:01:48 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (i[3456]86-*-solaris2*): New target. From Pavel
+ Roskin <pavel_roskin@geocities.com>.
+
+1999-01-19 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_size_sections): Count loadable sections as
+ contributing to the size of the current segment.
+
+1999-01-15 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_size_sections): Only update the current
+ address of a region if the section just placed into it is an
+ allocated section.
+
+1999-01-12 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Replace efr30.o with eelf32fr30.o.
+ * Makefile.in: Regenerate.
+
+ * configure.tgt: Replace fr30 with elf32fr30.
+
+ * emulparams/elf32fr30.sh: New file: Replaces fr30.sh, and uses
+ generic elf.sc script. Also replaces the .stack section with a
+ user definable symbol __stack.
+
+1999-01-11 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/fr30.sc: Fill .init and .fini sections with NOP
+ pattern.
+
+1999-01-03 Ken Raeburn <raeburn@cygnus.com>
+
+ * Makefile.am (check-DEJAGNU): No longer provide HOSTING_EMU,
+ HOSTING_CRT0, HOSTING_LIBS; the test suite can extract them from
+ configure.host and configure.tgt now.
+ * Makefile.in: Rebuild.
+
+1998-12-27 Ulrich Drepper <drepper@cygnus.com>
+
+ * lexsup.c (parse_args, case OPTION_RPATH): Avoid adding duplicate
+ elements to rpath.
+
+Thu Dec 10 11:12:28 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * Makefile.am (ALL_EMULATIONS): Remove pe-dll.o and deffilep.o.
+ (ALL_EMUL_EXTRA_OFILES): New variable. Put them here instead.
+ * configure.in: Set EMUL_EXTRA_OFILES to $(ALL_EMUL_EXTRA_OFILES)
+ if configuring with all targets.
+ * configure, Makefile.in, aclocal.m4: Rebuild.
+
+ * emultempl/pe.em (pe_enable_stdcall_fixup): Make static.
+ (pe_dll_do_default_excludes): Removed, unused.
+ (pe_def_file, pe_dll_export_everything, pe_dll_kill_ats,
+ pe_dll_stdcall_aliases): Don't initialize them, this file may be
+ compiled more than once.
+ * pe-dll.c (pe_def_file, pe_dll_export_everything,
+ pe_dll_do_default_excludes, pe_dll_kill_ats,
+ pe_dll_stdcall_aliases): Define and initialize them here instead.
+ (generate_reloc): Fix allocation of reloc_addresses array to use
+ bfd_vma instead of unsigned long. Fix element size in qsort call.
+ (reloc_sort): Compare pointers to bfd_vma instead of unsigned
+ long.
+
+Mon Dec 7 21:10:09 1998 J.J. van der Heijden <j.j.vanderheijden@student.utwente.nl>
+
+ * configure.tgt (i[3456]86-*-mingw32*): Add cygwin target specific
+ files.
+
+Sun Dec 6 16:33:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (m68*-*-gnu*): New target. From Aymeric Vincent
+ <aymeric.vincent@emi.u-bordeaux.fr>.
+
+1998-12-04 Nick Clifton <nickc@cygnus.com>
+
+ * emulparams/fr30.sh (TEXT_START_ADDR): Change TEXT_START_ADDR
+ from 0x100000 to 0x10000 so that it fits in 20 bits.
+
+Sat Nov 28 22:32:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldemul.h (ldemul_recognized_file): Declare.
+
+Sat Nov 28 22:30:55 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * ldlang.c (lang_add_wild): Don't pretend that there is an input
+ file if the filename is a wildcard pattern.
+
+1998-11-25 DJ Delorie <dj@cygnus.com>
+
+ * ldemul.h (ld_emulation_xfer_struct): new hook "recognized_file"
+ * ldemul.c (ldemul_recognized_file): new function, new hook
+ * ldint.texinfo: document new hook.
+ * ldlang.c (load_symbols): call recognized_hook for all objects we
+ do recognize, in case the emulation needs to handle them
+ specially. PE DLLs use this.
+ * pe-dll.c (pe_dll_generate_def_file): take out hack and debug
+ printfs
+ * emultempl/pe.em (gld_i386_recognized_file): new function
+ (gld_i486_unrecognized_file): take out hack
+
+1998-11-23 DJ Delorie <dj@cygnus.com>
+
+ * pe-dll.c (fill_edata): fill in timestamp
+ (make_head): name object files sequentially to ensure
+ they link in the right order.
+ (make_tail): same here
+ (pe_process_import_defs): use sequential names for bfds to ensure
+ proper link order.
+ (pe_implied_import_dll): new function; handles linking directly
+ against DLLs by simulating IMPORTS directives. * emultempl/pe.em
+ (gld_i386pe_before_parse): hack bfd to not recognize .dll files
+ via bfd_pe_dll_not_recognized_hack
+
+1998-11-23 DJ Delorie <dj@cygnus.com>
+
+ * emultempl/pe.em (gld_i386pe_parse_args): Conditionalize call to
+ pe_dll_add_excludes
+
+Mon Nov 23 14:36:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * emultempl/pe.em (after_parse): Only create an undefined entry
+ symbol if one has been specified.
+
+1998-11-23 DJ Delorie <dj@cygnus.com>
+
+ * emultempl/pe.em (gld_i386pe_after_open): call
+ pe_process_import_defs
+ * pe-dll.c (pe_dll_generate_def_file): calculate BASE from
+ pe_data, only print if actually set. Print version only if
+ set.
+ (save_relocs): save relocs for both input and output.
+ (make_one): support internal/external different names.
+ (pe_dll_generate_implib): support new make_one
+ (pe_process_import_defs): new function; handles IMPORT
+ directives in .def files.
+
+Fri Nov 20 13:06:49 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ldmisc.c (vfinfo): Cope with empty symbol names.
+
+Thu Nov 19 13:31:15 1998 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/pe.sc: Add provision of '_end' symbol.
+
+Wed Nov 18 18:18:43 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.tgt: change refs from cygwin32* to cygwin*.
+ * aclocal.m4: regenerate
+ * configure.in: don't need to call AM_CYGWIN32.
+ * configure: regenerate
+
+Mon Nov 16 22:14:07 1998 DJ Delorie <dj@cygnus.com>
+
+ * emultempl/pe.em (gld_i386_finish): generate import library
+ * deffile.h: add hint member.
+ * pe-dll.c (pe_dll_generate_implib): New function with helpers;
+ generates the import library directly from the export table.
+ (fill_edata): remember the actual hint for the import library.
+
+Sat Nov 14 14:36:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.1: Some cleanups from NOKUBI Hirotaka <hnokubi@yyy.or.jp>.
+
+Thu Nov 12 19:21:57 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/ld.pot: Regenerated.
+ * po/POTFILES.in: Regenerated.
+ * configure: Regenerated.
+ * aclocal.m4: Regenerated.
+ * Makefile.in: Regenerated.
+
+Wed Nov 11 18:10:15 1998 DJ Delorie <dj@cygnus.com>
+
+ * pe-dll.c (generate_reloc): don't output PE relocs for sections
+ that won't be loaded.
+
+Wed Nov 11 13:44:54 1998 DJ Delorie <dj@cygnus.com>
+
+ * pe-dll.c (fill_edata): don't strip underscores
+
+Tue Nov 10 21:28:19 1998 DJ Delorie <dj@cygnus.com>
+
+ * ld.texinfo: added i386pe option summary
+
+Tue Nov 10 17:53:17 1998 DJ Delorie <dj@cygnus.com>
+
+ * pe-dll.c (process_def_file): properly note undefined exported
+ symbols, clean up old code.
+ (pe_dll_generate_def_file): don't crash if pe_def_file is NULL
+ * emultempl/pe.em (gld_i386_parse_args): add
+ (en/dis)able-stdcall-fixups
+ (pe_fixup_stdcalls): warn about stdcall fixups
+ (gld_i386_unrecognized_file): make exported symbols undefs so that
+ archive members get pulled in
+
+Tue Nov 10 14:50:51 1998 Catherine Moore <clm@cygnus.com>
+
+ * scripttempl/elfd10v.sc: Add KEEP attribute to .init,
+ .fini, .dtors and .ctors. Add .data and .text
+ wildcards to support section garbage collection.
+
+Mon Nov 9 22:52:50 1998 DJ Delorie <dj@indy.delorie.com>
+
+ * deffilep.y: properly handle relocs with multiple def_files,
+ cache import module names
+
+Mon Nov 9 22:44:58 1998 DJ Delorie <dj@cygnus.com>
+
+ * pe-dll.c (process_def_file): don't assume exports won't move
+ during a realloc
+
+Mon Nov 9 16:41:30 1998 DJ Delorie <dj@cygnus.com>
+
+ * pe-dll.c: New file; direct support for PE DLLs
+ * deffile.h: New file; direct support for PE DLLs
+ * deffilep.y: New file; direct support for PE DLLs
+ * emultempl/pe.em: add direct support for PE DLLs
+ * configure.tgt: allow target-specific extra files
+ * configure.in: allow target-specific extra files
+ * ldlang.c (lang_add_assignment): return the assignment so that
+ one can change the value later based on the object files (pe-dll
+ DEF files do this)
+ * ldint.texinfo: add section for emulation walkthrough
+ * Makefile.am: add new files and target-specific extra files
+ * emultempl/pe.em (gld_i386_list_options): list dll-specific
+ options.
+ * pe-dll.c (process_def_file): auto-export everything if
+ nothing is otherwise exported.
+
+Wed Nov 4 16:39:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Add support for FR30 target.
+ * configure.tgt: Add support for FR30 target.
+ * Makefile.in: Regenerate.
+ * emulparams/fr30.sh: New file.
+ * scripttemp/fr30.sc: New file.
+
+Mon Nov 2 14:47:15 1998 Catherine Moore <clm@cygnus.com>
+
+ * ldmain.c (main): Don't report error for dynamic links and
+ --gc-sections.
+
+1998-10-26 16:05 Ulrich Drepper <drepper@cygnus.com>
+
+ * lexsup.c (ld_options): Change text of -O to Optimize output file".
+ (parse_args): Set link_info.optimize based on -O argument.
+ * ldmain.c (main): Initialize link_info.optimze to false.
+ * ld.texinfo: Describe -O option.
+ * ld.1: Likewise.
+
+Mon Oct 12 14:29:56 1998 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/v850.sc: Move .sbss and .scommon sections into their
+ own segment, so that they can be next to the .bss section and so
+ initialised by the same piece of code.
+
+Fri Oct 9 15:59:52 1998 Catherine Moore <clm@cygnus.com>
+
+ * scripttempl/elf.sc: Merge .sdata.* etc sections.
+ * ldctor.c (ldctor_build_sets): Set SEC_KEEP for
+ ctor sections.
+
+Mon Oct 5 09:40:43 1998 Catherine Moore <clm@cygnus.com>
+
+ * ldmain.c (main): Error if --gc-sections and
+ dyanmic linking.
+ * scripttempl/v850.sc: Add KEEP attribute to .init,
+ .fini, .dtors and .ctors. Add .data and .text
+ wildcards to support section garbage collection.
+
+Wed Sep 30 11:19:15 1998 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/v850.sc: Rename .call_table section to
+ .call_table_data and create a new section called
+ .call_table_text.
+
+Sun Sep 20 00:43:26 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elf.sc: Add alignment at the end of the .bss
+ section, so that it is included in the memsize of the segment.
+
+Fri Sep 18 13:42:42 1998 Catherine Moore <clm@cygnus.com>
+
+ * emultempl/elf32.em (gld_place_orphan): Don't process for
+ sections with SEC_EXCLUDE flag.
+
+Fri Sep 4 09:24:02 1998 Nick Clifton <nickc@cygnus.com>
+
+ * emulparams/d30velf.sh (TEXT_SIZE): Increased to 2000K.
+ (DATA_SIZE): Increased to 2000K.
+
+Thu Sep 3 17:30:58 1998 Richard Henderson <rth@cygnus.com>
+
+ * emulparams/d10velf.sh (TEMPLATE_NAME): Use elf32.
+
+Mon Aug 31 01:06:00 1998 Catherine Moore <clm@cygnus.com>
+
+ * Makefile.am: Change armelf.sc to elf.sc
+ * Makefile.in: Regenerate.
+
+Mon Aug 31 11:12:04 1998 Catherine Moore <clm@cygnus.com>
+
+ * emulparams/armelf.sh: Change SCRIPT_NAME to
+ elf. Change TEXT_START_ADDR to 0x8000. Define
+ OTHER_TEXT_SECTIONS, OTHER_BSS_SYMBOLS and
+ OTHER_BSS_END_SYMBOLS.
+ * scripttempl/elf.sc: Modify to use
+ OTHER_BSS_END_SYMBOLS.
+ * scripttempl/elfarm.sc: Remove file.
+
+Tue Aug 18 12:05:34 1998 Catherine Moore <clm@cygnus.com>
+
+ * emultempl/armelf.em (gld_armelf_before_allocation):
+ Add bfd_ prefix to elf32_arm_process_before_allocation
+ and elf32_arm_allocate_interworking_sections.
+ (gld_armelf_after_open): Add bfd_ prefix to
+ elf32_arm_get_bfd_for_interworking.
+
+Fri Aug 14 15:34:29 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+ * ldgram.y: Include "ldctor.h".
+ (statement): Accept SORT around CONSTRUCTORS.
+ * ldctor.c: Include <ctype.h>.
+ (constructors_sorted): New global variable.
+ (ctor_prio, ctor_cmp): New static functions.
+ (ldctor_build_sets): Sort constructors if requested.
+ * ldctor.h (constructors_sorted): Declare.
+ * ldlang.c (print_statement): Print sorted CONSTRUCTORS
+ correctly.
+ * scripttempl/elf.sc: Add sort around CONSTRUCTORS.
+ * ld.texinfo (Output Section Keywords): Document SORT
+ (CONSTRUCTORS).
+
+Thu Aug 13 12:20:39 1998 Catherine Moore <clm@cygnus.com>
+
+ * emulparams/armelf.sh: Define TEMPLATE_NAME to armelf.
+ * scripttempl/elfarm.sc: Include .glue_7t and .glue7
+ sections.
+ * emultempl/armelf.em: New file.
+
+Thu Aug 13 12:52:45 1998 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (ld.dvi): Use " instead of ' for MAKEINFO.
+ * Makefile.in: Rebuild.
+
+Tue Aug 11 16:17:01 1998 Catherine Moore <clm@cygnus.com>
+
+ * scripttempl/elfarm.sc: Change text start address
+ back to zero.
+
+Tue Aug 11 10:01:12 1998 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/mn10200.sh (MAX_PAGESIZE): Define to 1.
+ * emulparms/mn10300.sh (MAX_PAGESIZE): Define to 1.
+
+Sun Aug 9 20:31:27 1998 Catherine Moore <clm@cygnus.com>
+
+ * scripttempl/elfarm.sc: Set text start address to
+ 0x8000. Add __bss_end definition.
+
+Sat Aug 1 11:47:37 1998 Catherine Moore <clm@cygnus.com>
+
+ * scripttempl/elfarm.sc: New file.
+ * emulparams/armelf.sh: Set SCRIPT_NAME to elfarm.
+
+Fri Jul 31 15:56:16 1998 Catherine Moore <clm@cygnus.com>
+
+ * emulparams/armelf.sh: New file.
+ * configure.tgt: Recognize thumb-elf and arm-elf.
+ * Makefile.am (earmelf.o): New.
+ * Makefile.in: Rebuild.
+
+Fri Jul 24 12:00:57 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (install-exec-local): Don't remove the file before
+ checking whether $(bindir) == $(tooldir)/bin. From Maciej
+ W. Rozycki <macro@ds2.pg.gda.pl>.
+ * Makefile.in: Rebuild.
+
+ * configure.tgt: Recognize h8[35]00*-coff* as well as -hms*.
+
+Thu Jul 23 11:15:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/aout.sc: If ALIGNMENT is defined, use it to set
+ alignment of end symbol.
+ * scripttempl/elf.sc: Likewise.
+ * emulparams/sun4.sh (ALIGNMENT): Define.
+ * emulparams/elf32_sparc.sh (ALIGNMENT): Define.
+ * ldint.texinfo (emulation parameters): Document ALIGNMENT.
+
+ * lexsup.c (parse_args): Add missing break statement.
+
+ * ldlang.c (lang_gc_sections_1): Add default case to switch to
+ avoid warnings.
+
+Tue Jul 14 15:42:17 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.tgt (i?86-*-beos{pe,elf,}*): Recognize.
+ * Makefile.am (ei386beos.o): New.
+ * emulparams/i386beos.sh: New file.
+ * emultempl/beos.em, scripttempl/i386beos.sc: New file.
+
+Tue Jul 14 15:35:42 1998 Richard Henderson <rth@cygnus.com>
+
+ * lexsup.c: New option --version-exports-section.
+ * ld.h (struct args_type): Add version_exports_section.
+ * ldlang.c (lang_do_version_exports_section): New function.
+ (lang_process): Call it.
+
+Mon Jul 13 13:20:23 1998 Steve Chamberlain <sac@transmeta.com>
+
+ * ldlex.l: Accept ASSERT.
+ * ldgram.y (exp): Add ASSERT_K case.
+ * ldexp.h (node_type): Add etree_assert to node_class enum.
+ (etree_type): Add assert_s field.
+ (exp_assert): Declare.
+ * ldexp.c (exp_fold_tree): Handle etree_assert.
+ (exp_assert): New function.
+ (exp_print_tree): Handle etree_assert.
+ * ld.texinfo (Miscellaneous Commands): Document ASSERT.
+
+Wed Jul 8 14:03:12 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y: Change MAX to MAX_K and MIN to MIN_K, to avoid
+ conflicts with system header files. Change all uses.
+
+ * Makefile.am (MAINTAINERCLEANFILES): Define.
+ * Makefile.in: Rebuild.
+
+Tue Jul 7 18:03:22 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (ldver.texi): New target.
+ (ld.info, ld.dvi): Depend upon ldver.texi.
+ * ld.texinfo: Include ldver.texi. Mention version number on title
+ page and in top node.
+ * Makefile.in: Rebuild.
+
+Mon Jul 6 14:55:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (i[3456]86-*-solaris*): New target.
+
+Fri Jul 3 14:19:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (wild_section): Don't get an assertion failure if the
+ section is discarded.
+
+ * scripttempl/pe.sc: Use SORT to sort sections appropriately.
+ * emultempl/pe.em (sort_by_file_name): Remove.
+ (sort_by_section_name): Remove.
+ (sort_sections_1, sort_sections): Remove.
+ (gld_${EMULATION_NAME}_before_allocation): Don't call
+ sort_sections.
+ (hold_section, hold_section_name): New static variables.
+ (hold_use, hold_text, hold_rdata, hold_data, hold_bss): Likewise.
+ (gld_${EMULATION_NAME}_place_orphan): Rewrite. Look for a good
+ place to put the section. Align the section. Sort the input
+ sections by name.
+ (gld_${EMULATION_NAME}_place_section): New static function.
+
+ * ldlang.c (wild_sort): When sorting by file name, sort by archive
+ name first.
+
+ * emultempl/pe.em (set_pe_subsystem): Don't call
+ ldlang_add_undef.
+ (gld_${EMULATION_NAME}_after_parse): New static function.
+ (ld_${EMULATION_NAME}_emulation): Use new after_parse function
+ rather than after_parse_default.
+
+ * ldgram.y (extern_name_list): Do not require symbols to be
+ separated by commas.
+ (ifile_p1): Add EXTERN.
+ * ldlex.l: Accept EXTERN in BOTH and SCRIPT mode as well as MRI
+ mode.
+ * ld.texinfo (Options): Mention that EXTERN is equivalent to -u.
+ (Miscellaneous Commands): Document EXTERN.
+
+Wed Jul 1 19:40:34 1998 Richard Henderson <rth@cygnus.com>
+
+ * ld.h (args_type): Add gc_sections.
+ * ldgram.y (ldgram_had_keep, KEEP): New.
+ (input_section_spec_no_keep): Rename from old input_section_spec.
+ (input_section_spec): New. Recognize KEEP.
+ * ldlang.c (wild_section): Handle keep sections.
+ (lang_gc_wild_section, lang_gc_wild_file, lang_gc_wild): New.
+ (lang_gc_sections_1, lang_gc_sections): New.
+ (lang_process): Invoke lang_gc_sections.
+ (lang_add_wild): Add keep argument. Update all callers.
+ * ldlang.h (lang_wild_statement_struct): Add keep_sections.
+ * ldlex.l (KEEP): Match it.
+ * ldmain.c (main): Error on -r and --gc-sections.
+ * lexsup.c: Add --gc-sections.
+
+ * scripttempl/elf.sc: Merge .text.* etc sections appropriately.
+ Mark startup sections with KEEP.
+ * scripttempl/elfppc.sc: Likewise.
+
+ * ld.texinfo: Update for --gc-sections and KEEP.
+
+Wed Jul 1 15:21:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Peter Jordan <pjordan@chla.usc.edu>:
+ * scripttempl/i386go32.sc: Correct constructor handling for -u.
+
+Tue Jun 23 15:17:27 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (install-data-local): Make ldscripts subdirectory.
+ * Makefile.in: Rebuild.
+
+Tue Jun 23 15:17:04 1998 Mike Stump <mrs@wrs.com>
+
+ * Makefile.am (install-exec-local): Don't let EXEEXT interfere
+ with the program transform name.
+ * Makefile.in: Rebuild.
+
+Sun Jun 21 23:55:16 1998 Jeffrey A Law (law@cygnus.com)
+
+ * ld.texinfo: Note that -relax may make symbolic debugging
+ impossible on some platforms.
+
+Tue Jun 16 12:51:13 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * Makefile.am (Makefile): Remove target.
+ (config.status): New target.
+ * Makefile.in: Rebuild.
+
+ * configure.host (powerpc*-*-linux-gnu*): New host.
+
+Fri Jun 12 17:38:07 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * scripttempl/elf.sc (INPUT_FILES): Optional INPUT spec.
+
+ * emulparams/m32relf.sh (OTHER_RELOCATING_SECTIONS): Change top of
+ stack to 8MB.
+
+Fri Jun 12 19:33:17 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (HFILES): Remove config.h.
+ (EMULATION_OFILES, POTFILES): Move patch of May 14 from
+ Makefile.in to Makefile.am.
+ (earmcoff.c): Depend upon armcoff.em, not generic.em.
+ * po/Make-in (all-yes): Correct misspelling in $(PACKAGE).
+ ($(srcdir)/$(PACKAGE).pot): Pass -C to $(XGETTEXT).
+ * Makefile.in, po/POTFILES.in, po/ld.pot: Rebuild.
+
+Fri Jun 12 13:43:17 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): If maintainer mode, depend on .pot file.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+Tue Jun 9 09:36:48 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_finish): Add CONST type modifier to declaration
+ of 'send'.
+
+Fri Jun 5 18:19:59 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_before_parse): Set
+ config.has_shared to true.
+ * emultempl/linux.em (gld${EMULATION_NAME}_before_parse):
+ Likewise.
+ * emultempl/sunos.em (gld${EMULATION_NAME}_before_parse):
+ Likewise.
+
+Tue Jun 2 12:55:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_finish): If the entry symbol is not found, try
+ parsing it as a number.
+ * ld.texinfo (Options): Document this.
+
+Mon Jun 1 14:01:20 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Input Section Wildcards): Document SORT keyword.
+
+Mon May 18 12:42:53 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * ld.h (ld_config_type): New member has_shared.
+ * ldmain.c (main): Initialize it.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Set it.
+ * lexsup.c (parse_args): Treat -shared as error if not supported.
+
+Mon May 18 13:14:43 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Jason Merrill <jason@cygnus.com>:
+ * ldlang.c (wild_sort): Correct order of sort.
+ * scripttempl/elf.sc: Put *crtbegin.o before other .ctors and
+ .dtors.
+ * scripttempl/elfd10v.sc: Likewise.
+ * scripttempl/elfd30v.sc: Likewise.
+ * scripttempl/elfppc.sc: Likewise.
+
+Fri May 15 00:22:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlex.l: Recognize keyword SORT.
+ * ldgram.y (current_file): Change to struct wildcard_spec.
+ (%union): Add new fields cname and wildcard.
+ (wildcard_name, wildcard_spec): New nonterminals.
+ (file_NAME_list): Use wildcard_spec.
+ (input_section_spec): Change current_file usage.
+ * ld.h (struct wildcard_spec): Define.
+ * ldlang.h (lang_wild_statement_struct): Add new fields
+ sections_sorted and filenames_sorted.
+ (lang_add_wild): Update declaration.
+ * ldlang.c (wild_sort): New static function.
+ (wild_section): Use wild_sort.
+ (print_wild_statement): Print sorting information.
+ (lang_add_wild): Add new parameters sections_sorted and
+ filenames_sorted. Change all callers.
+ * mri.c (mri_draw_tree): Update calls to lang_add_wild.
+ * scripttempl/elf.sc: Sort .ctors.* and .dtors.* by section name.
+ * scripttempl/elfd10v.sc: Likewise.
+ * scripttempl/elfd30v.sc: Likewise.
+ * scripttempl/elfppc.sc: Likewise.
+
+Thu May 14 18:39:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * emulparams/m32relf.sh (TEMPLATE_NAME): Define.
+
+Thu May 14 14:51:24 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ldemul.h: Add new prototype: ldemul_list_emulation_options.
+ (ld_emulation_xfer_struct): Add new field: list_options.
+ * ldemul.c (ldemul_list_options): New function. Call the
+ list_options field of the ld_emulation_xfer_struct for each
+ supported emulation, if such a function is present.
+ * lexsup.c (help): Call ldemul_list_emulation_options.
+ * emultempl/pe.em (gld_<>_list_options): New function. Describe
+ the pe emulation specific command line options.
+ * emultempl/armcoff.em (gld<>_list_options): New function.
+ Describe the armcoff emulation specific command line options.
+
+ * emultempl/pe.em: Add a new command line option:
+ --support-old-code.
+ * emultempl/armcoff.em: Ditto.
+ * ld.texinfo: Document the --support-old-code option.
+
+ * Makefile.in: Add emulation files for POTFILES.in target.
+ * emultempl/pe.em: Internationalise suitable strings.
+ * emultempl/armcoff.em: Internationalise suitable strings.
+ * po/POTFILES.in: Rebuilt.
+
+Sun May 10 22:36:30 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Tue Apr 28 19:18:30 1998 Tom Tromey <tromey@cygnus.com>
+
+ * ldmain.c (main): Conditionally call setlocale.
+ * ld.h: Include <locale.h> if HAVE_LOCALE_H.
+ (LC_MESSAGES): Now can be defined even when ENABLE_NLS.
+
+Mon Apr 27 11:56:21 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Change version number to 2.9.4
+ * configure: Rebuild.
+
+ * ld.texinfo (Options) [-rpath-link]: Mention ld.so.conf.
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * emultempl/elf32.em (global_vercheck_needed): New file static
+ variable.
+ (global_vercheck_failed): New file static variable.
+ (gld${EMULATION_NAME}_after_open): Check for shared libraries
+ twice, once with force set to 0 and once with it set to 1.
+ (gld${EMULATION_NAME}_check_ld_so_conf): Add force parameter.
+ Change all callers.
+ (gld${EMULATION_NAME}_search_needed): Likewise.
+ (gld${EMULATION_NAME}_try_needed): Likewise. If not force, check
+ whether the libraries needs any incompatible versions.
+ (gld${EMULATION_NAME}_vercheck): New static function.
+
+Wed Apr 22 16:01:35 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (MKINSTALLDIRS): Don't look in $(top_srcdir).
+
+Wed Apr 22 12:40:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (check-DEJAGNU): Add $(INTLLIBS) to LIBIBERTY when
+ invoking runtest.
+ * Makefile.in: Rebuild.
+
+ * lexsup.c (parse_args): Change -l options into --library options
+ to avoid confusion between -li and -library.
+
+ * ld.texinfo (MEMORY): Clarify use of >REGION.
+
+Tue Apr 21 23:12:40 1998 Tom Tromey <tromey@scribbles.cygnus.com>
+
+ * Many files: Added gettext invocations around user-visible
+ strings.
+ * ld.h: Added gettext-related includes and defines.
+ * ldmain.c: Call setlocale, bindtextdomain, textdomain.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_STPCPY,
+ HAVE_LC_MESSAGES): Define.
+ * configure.in: Call CY_GNU_GETTEXT. Create po/Makefile.in and
+ po/Makefile. Use AM_PROG_LEX.
+ (TDIRS): AC_SUBST early on, to avoid having value split when it
+ happens to cross line 90 of the generated sed script.
+ * Makefile.am (SUBDIRS): New macro.
+ (POTFILES): Likewise.
+ (po/POTFILES.in): New target.
+ (ld_new_LDADD): Added INTLLIBS.
+ (ld_new_DEPENDENCIES): Added INTLDEPS.
+ * po/Make-in, po/POTFILES.in, po/gas.pot: New files.
+
+Tue Apr 21 23:07:07 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Simple Example): Rewrite a few things as suggested
+ by Nick Clifton <nickc@cygnus.com>.
+ (PROVIDE): Likewise.
+
+Tue Apr 21 09:55:06 1998 Nick Clifton <nickc@cygnus.com>
+
+ * emultempl/pe.em: Rename external arm interworking functions
+ to conform to BFD naming conventions. Add code to _after_open()
+ function to obtain a bfd for use by the interworking code.
+
+ * emultempl/armcoff.em: Rename external arm interworking functions
+ to conform to BFD naming conventions. Add new _after_open()
+ function to obtain a bfd for use by the interworking code.
+
+Sun Apr 19 19:23:09 1998 Richard Henderson <rth@cygnus.com>
+
+ * ldlang.c (lang_size_sections) [case lang_assignment_statement_enum]:
+ Update dot and the default memory section even when relaxing.
+
+Sat Apr 18 18:41:12 1998 Richard Henderson <rth@cygnus.com>
+
+ * ldlang.c (lang_one_common): Manipulate the section's cooked size
+ rather than its raw size.
+
+Tue Apr 7 13:35:29 1998 H.J. Lu <hjl@gnu.org>
+
+ * configure.in (TESTBFDLIB): New. Defined and substituted.
+ * Makefile.am (TESTBFDLIB): Changed to @TESTBFDLIB@.
+ * configure, Makefile.in: Rebuild.
+
+Mon Apr 6 15:33:39 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (ld.info): Invoke makeinfo with -I options directly
+ rather than relying on default rule. Don't depend upon
+ bfdsumm.texi.
+ (ld.dvi): Likewise.
+ (bfdsumm.texi): Remove target.
+ (CLEANFILES): Take bfdsumm.texi out of value.
+ * Makefile.in: Rebuild.
+
+Sun Apr 5 13:07:57 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/pe.sc: Use shell variables to avoid depending upon
+ how $ is handled when expanding a shell substitution.
+
+Fri Apr 3 00:56:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (MOSTLYCLEANFILES): Add ld.log and ld.sum.
+ (DISTCLEANFILES): Add site.exp and site.bak.
+ * Makefile.in: Rebuild.
+
+ * configure.in: Put the tdirs in a file and use AC_SUBST_FILE,
+ rather than in a shell variable and using AC_SUBST.
+ * Makefile.am (DISTCLEANFILES): Remove ldscripts. Add tdirs.
+ (distclean-local): New target.
+ * configure, Makefile.in: Rebuild.
+
+ * ld.texinfo: Completely rewrite linker script documentation.
+
+Mon Mar 30 12:47:33 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set version to 2.9.1.
+ * configure: Rebuild.
+
+ * Branched binutils 2.9.
+
+Sat Mar 28 16:48:19 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (MOSTLYCLEANFILES): Remove tmpdir.
+ (mostlyclean-local): New target to remove tmpdir.
+ * Makefile.in: Rebuild.
+
+ Fix some gcc -Wall warnings:
+ * ldcref.c (output_cref): Add casts to avoid warnings.
+ * ldfile.c (ldfile_add_arch): Likewise.
+ * ldlang.c (lang_leave_overlay_section): Likewise.
+ * lexsup.c (OPTION_COUNT): Likewise.
+ (parse_args): Likewise.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan):
+ Likewise.
+ * emultempl/sunos.em (gld${EMULATION_NAME}_search_dir): Likewise.
+ * ldlang.c (lang_check): Initialize variables to avoid warnings.
+ * ldwrite.c (build_link_order): Likewise.
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Likewise.
+ * emultempl/armcoff.em (gld${EMULATION_NAME}_before_allocation):
+ Remove unused variables.
+
+ * Makefile.am (MOSTLYCLEANFILES): Correct name (was
+ MOSTCLEANFILES).
+ * Makefile.in: Rebuild.
+
+Fri Mar 27 16:39:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): Put
+ ARM code inside ifdef TARGET_IS_armpe.
+
+Wed Mar 25 11:34:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * Makefile.am (LDDISTSTUFF): New variable.
+ (diststuff): New target.
+ * Makefile.in: Rebuild.
+
+ * scripttempl/pe.sc: Only include .idata\$[0-7] in .idata when
+ relocating.
+
+Tue Mar 24 15:59:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/pe.sc (.text): Add .glue_7 and .glue_7t sections to
+ hold Arm/Thumb stubs.
+
+ * emultempl/pe.em (gld_pe_before_allocation): Call
+ arm_process_before_allocation (for ARM/Thumb targets) in order to
+ gather interworking stb information.
+
+Mon Mar 23 18:54:15 1998 Joel Sherrill <joel@OARcorp.com>
+
+ * configure.tgt: (sh*-*-rtems*): Switched from ELF to COFF.
+
+Fri Mar 20 19:17:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Thu Mar 19 14:54:45 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * scripttempl/pe.sc: The Cygwin32 library uses a .data$nocopy
+ section to avoid copying certain data on fork. The linker used to
+ include this between __data_start__ and __data_end__, but that
+ breaks building the cygwin32 dll. The fix is to rename the
+ section ".data_cygwin_nocopy" and explictly include it after
+ __data_end__.
+
+Wed Mar 18 09:42:24 1998 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt (targ_extra_emuls): Add thumb-pe target.
+
+Sun Mar 8 23:34:14 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * configure.tgt (sparclite*-*-elf): Added.
+
+Mon Mar 2 19:24:08 1998 Michael Meissner <meissner@cygnus.com>
+
+ * ldlang.c (lang_size_sections): If the default memory region is
+ *default*, see if there is a memory region that could be used.
+
+Thu Feb 26 17:09:53 1998 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfd30v.sc: Add support for .eit_v section and put
+ it at 0xfffff020.
+ * emulparams/d30v{elf,_o,_e}.sh: Ditto.
+
+Mon Feb 23 17:46:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (sort_sections): Permit the wildcard to include
+ a trailing '*' when sorting grouped sections.
+ * scripttempl/pe.sc: Include grouped sections using NAME\$*. Only
+ include them when relocating.
+
+Wed Feb 18 23:39:46 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.am (install-exec-local): Install properly when ln
+ fails or tooldir == prefix.
+
+Fri Feb 13 15:24:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e.
+
+Thu Feb 12 14:10:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elf.sc: Align the _end symbol according to the ELF
+ format size. From Gordon W. Ross <gwr@mc.com>.
+
+ NetBSD patches from Gordon W. Ross <gwr@mc.com>:
+ * configure.host (alpha*-*-netbsd*): New host.
+ * configure.tgt (alpha*-*-netbsd*, powerpc-*-netbsd*): New
+ targets.
+
+ * lexsup.c (help): Update bug-gnu-utils address.
+ * ld.texinfo (Bug Reporting): Likewise.
+
+Tue Feb 10 18:05:56 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_size_sections): Warn if some memory regions were
+ defined, but a loadable section is going into the default memory
+ region.
+
+Tue Feb 10 16:17:20 1998 H.J. Lu <hjl@gnu.org>
+
+ * ldlex.l (V_IDENTIFIER): Allow '.' as symbol prefix.
+
+Tue Feb 10 15:09:45 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (Makefile): Add target, for dependencies on
+ configure.host and configure.tgt.
+ * configure.host, configure.tgt: Change -linux* to -linux-gnu*.
+ * Makefile.in: Rebuild.
+
+Mon Feb 9 13:44:40 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * scripttempl/elfd10v.sc (.stack): Move stack to 0x00..7FFE.
+
+ * emulparams/d10velf.sh (READONLY_START_ADDR): Read only section
+ moved to 0x00.....4.
+
+Sat Feb 7 15:41:26 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Thu Feb 5 12:16:11 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/pe.sc: Remove ${RELOCATING-0} from all sections.
+ From Thomas de Lellis <tdel@wrs.com>.
+
+ * configure, Makefile.in, aclocal.m4: Rebuild with new libtool.
+
+Wed Feb 4 13:02:32 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (ld_new_LDADD): Remove @LEXLIB@.
+ * Makefile.in: Rebuild.
+
+Mon Feb 2 19:34:54 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ Add tms320c30 support:
+ * configure.tgt (tic30-*-*aout*, tic30-*-*coff*): New targets.
+ * emulparams/tic30aout.sh: New file.
+ * emulparams/tic30coff.sh: New file.
+ * scripttempl/tic30aout.sc: New file.
+ * scripttempl/tic30coff.sc: New file.
+ * Makefile.am (ALL_EMULATIONS): Add etic30aout.o and
+ etic30coff.o.
+ (etic30aout.c, etic30coff.c): New targets.
+ * Makefile.in: Rebuild.
+
+Mon Feb 2 14:10:59 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Correct HOSTING_CRT0 in alpha*-*-linux* case to
+ accept either ld.so or ld-linux.so.
+
+Fri Jan 30 19:16:28 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.am ({CC,CXX}_FOR_TARGET): Change program_transform_name
+ to transform.
+ * Makefile.in: Regenerate.
+
+Fri Jan 30 19:15:17 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * scripttempl/elfppc.sc: Put .dynsbss in .sbss.
+
+Fri Jan 30 11:43:49 1998 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * Makefile.am (eelf32bsmip.c, eelf32lsmip.c): New targets.
+ * Makefile.in: Rebuild.
+
+Thu Jan 29 16:04:21 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * ldfile.c (slash): Set to backslash if _WIN32 but not
+ __CYGWIN32__.
+ (ldfile_open_file_search): If __MSDOS__ or _WIN32, accept a
+ leading backslash or a leading x: as an absolute path.
+ (ldfile_find_command_file): Use slash rather than / when
+ generating name to try.
+ * lexsup.c (PATH_SEPARATOR): Define.
+ (set_default_dirlist): Use PATH_SEPARATOR rather than ':'.
+
+Wed Jan 28 14:06:30 1998 Richard Henderson <rth@cygnus.com>
+
+ * emulparams/elf64_sparc.sh (ELFSIZE): 64
+ (TEXT_START_ADDR): Round off, since SIZEOF_HEADERS is added later.
+ (DATA_PLT): Needed by v9 abi.
+
+Wed Jan 28 16:37:27 1998 J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl>
+
+ * configure.tgt (i[3456]86-*-mingw32*): New entry.
+
+Wed Jan 28 15:51:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elf.sc: Only include linkonce sections in final
+ sections when relocating.
+
+Wed Jan 28 14:10:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Options): Add a brief description of the types of
+ information included in a link map.
+
+ * ld.texinfo (Options): Mention LDEMULATION in description of -m.
+ (Environment): Mention LDEMULATION.
+
+ * ld.texinfo (Options): Clarify --export-dynamic a bit.
+
+Thu Jan 22 16:07:23 1998 Richard Henderson <rth@cygnus.com>
+
+ * ldlex.l (<SCRIPT>{WILDCHAR}*): Take care for the comments this
+ pattern could match.
+
+Wed Jan 21 22:26:46 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): When doing
+ a relocateable link, set the image base to 0, and don't define the
+ various symbols.
+ * emulparams/i386pe.sh (RELOCATEABLE_OUTPUT_FORMAT): Define.
+ * scripttempl/pe.sc: Swap the .data and .bss sections so that
+ .data comes first. If doing a relocateable link, use
+ RELOCATEABLE_OUTPUT_FORMAT if it is defined, and start the
+ sections at 0, and don't define any symbols.
+
+ * ldlang.c (lang_memory_default): Correct parenthisization of
+ expression.
+
+Wed Jan 21 21:20:32 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * emultempl/sunos.em: Don't include sys/types.h and sys/stat.h
+ here; they are included already via sysdep.h.
+
+Tue Jan 6 13:40:02 1998 Richard Henderson <rth@cygnus.com>
+
+ * scripttempl/i960.sc: Don't explicitly set .data and .bss start.
+
+Fri Jan 2 20:15:37 1998 Michael Meissner <meissner@cygnus.com>
+
+ * ldgram.y (attributes_opt): Pass region pointer to
+ lang_set_flags, not &region->flags.
+
+ * ldlang.c (lang_memory_default): New function to figure out a
+ default memory region for a section if it was not specified.
+ (lang_memory_region_lookup): Zero flags, not_flags field.
+ (lang_map{,_flags}): Print attribute flags in memory map.
+ (lang_size_sections): Call lang_memory_default to get default
+ memory region.
+ (lang_set_flags): Implement attribute flags for real. Take new
+ argument to give the flags we are to skip for this region.
+
+ * ldlang.h (memory_region_struct): Add not_flags field, make both
+ flags fields flagword type.
+ (lang_output_section_state): Make flags field flagword type.
+ (lang_set_flags): Update prototype to match new calling sequence.
+ (lang_memory_region_default): Add prototype.
+
+ * emulparams/d30v{_e,_o,elf}.sh ({TEXT,DATA,EMEM}_DEF_SECTION):
+ Define whether or not the region gets default sections, and if so,
+ what sections.
+
+ * scripttempl/elfd30v.sc (MEMORY): Set up which of the regions get
+ default sections.
+
+Thu Jan 1 22:58:04 1998 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfd30v.sc (.eh_frame): Link into the data section.
+
+Thu Jan 1 18:04:51 1998 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/h8300h.sc: Fix typo.
+ * scripttempl/h8300s.sc: Likewise.
+
+Sun Dec 21 12:51:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldexp.c (fold_name): Don't crash if the symbol is defined in a
+ section with no output section, such as a shared library section.
+
+Wed Dec 17 12:14:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (parse_args): Keep track of where we are in the option
+ parsing before calling ldemul_parse_args, so that we don't call it
+ multiple times on the same argument and confuse the getopt
+ internals.
+
+Thu Dec 11 09:00:15 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.tgt (d30v-elf-*): Rename d30velf_e to d30v_e and
+ d30velf_o to d30v_o to work in DOS environments.
+ * Makefile.{am,in}: Ditto.
+
+ * emulparams/d30v_{o,e}: Rename from d30velf_{o,e}.
+ * emulparams/d30velf_{o,e}: Deleted.
+
+Wed Dec 10 17:40:08 1997 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/armcoff.sc: Add glue sections (code taken from Arm
+ branch).
+
+ * emulparams/armcoff.sh (TEMPLATE_NAME): Set to armcoff.
+
+ * emultempl/armcoff.em: New file, imported from Arm branch.
+
+Wed Dec 10 14:10:44 1997 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfd30v.sc: Add .rel and .rela sections for all
+ defined sections. Set up __{D,C}TOR_{LIST,END}__. Add onchip and
+ external memory sections for rodata. Delete .string, .rodata1,
+ and .data1 sections.
+
+Tue Dec 9 15:28:17 1997 Michael Meissner <meissner@cygnus.com>
+
+ * Makefile.am: Add Oct 23 changes to Makefile.in here.
+
+ * Makefile.{am,in}: (ALL_EMULATIONS): Add ed10velf.o.
+
+ * Makefile.{am,in}: (ALL_EMULATIONS): Add etic80coff.o.
+
+ * Makefile.{am,in}: (ALL_EMULATIONS): Add ed30velf{,_e,_o}.o.
+ (ed30velf_e.c): Like d30velf, except .text/.data/etc always go in
+ external memory.
+ (ed30velf_o.c): Like d30velf, except .text/.data/etc always go in
+ onchip memory.
+
+ * emulparams/d30velf.sh (STACK_START_ADDR): Top of default
+ stack.
+ ({TEXT,DATA,EMEM}_SIZE): Sizes of the 3 memory areas.
+ ({TEXT,DATA,BSS}_MEMORY): Which memory region .text, .data, and
+ .bss should go in.
+
+ * emulparams/d30velf_{e,o}.sh: New files to be explicit whether
+ .text, .data, etc go in external memory or onchip memory.
+
+ * configure.tgt (d30v-*-*ext*): New configuration to default
+ .text, .data, etc. in external memory.
+ (d30v-*-*onchip*): New configuration to default .text, .data,
+ etc. in onchip memory.
+ (d30v-*-*): Add d30velf_{e,o} emulations.
+
+ * scripttempl/elfd30v.sc: Allow .text, .data, .bss to be put in
+ either the onchip text/data areas or the external memory area.
+ (MEMORY): Get sizes from d30velf.sh.
+ (.e{data,text,bss}): Put sections in the external memory region.
+ (.stext): Put section in the onchip text region.
+ (.s{data,bss}): Put sections in the onchip data region.
+ (__stack): Assign from ${STACK_START_ADDR}.
+ (.text): Put in ${TEXT_MEMORY} memory region.
+ (.data{,1}/.strings/.rodata{,1}): Put in ${DATA_MEMORY} memory
+ region.
+ (.bss): Put in ${BSS_MEMORY} memory region.
+
+Tue Dec 2 10:14:47 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt (targ_extra_emuls): Add support for Thumb target.
+
+Sat Nov 22 15:23:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlex.l: Don't define hex_mode. Correct number regexp to not
+ accept hex digits without a leading $ or 0x. Handle leading $
+ correctly. Pass 0 rather than hex_mode to bfd_scan_vma.
+ * ldlex.h (hex_mode): Don't declare.
+
+Sun Nov 16 20:16:45 1997 Michael Meissner <meissner@cygnus.com>
+
+ * emulparams/d30velf.sh ({DATA,EMEM}_START_ADDR): Define as start
+ of internal data area and external memory on chip.
+
+ * scripttempl/elfd30v.sc: Define a MEMORY region that describes
+ the 3 regions of memory on the chip. Put .text/.init/.fini into
+ the text memory region, put other segments into the data memory
+ region. Add more of the standard elf sections. Default __stack
+ to be 0x20008000, which is 1 byte beyond end of the internal data
+ region.
+
+Thu Nov 13 13:45:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.tgt (targ_extra_emuls): Make FreeBSD a i386bsd
+ variant.
+
+Sun Nov 2 14:51:36 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * configure.host (alpha*-*-linux*): Correct HOSTING_CRT0. Set
+ HOSTING_LIBS.
+
+Thu Oct 30 12:25:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (args_type): Add warn_mismatch field.
+ * ldmain.c (main): Initialize warn_mismatch field.
+ * lexsup.c (parse_args): Handle --no-warn-mismatch option.
+ * ldlang.c (ignore_bfd_error): New static function.
+ (lang_check): If warn_mismatch is false, don't warn about
+ mismatched input files.
+ * ld.texinfo, ld.1: Document new option.
+
+Thu Oct 23 14:38:18 1997 Nick Clifton <nickc@cygnus.com>
+
+ * scripttempl/v850.sc: Rename linker symbol '_stack' to '__stack'
+ to avoid conflicts with C code which is defining a variable called
+ 'stack'.
+
+Thu Oct 23 00:57:45 1997 Richard Henderson <rth@dot.cygnus.com>
+
+ * Makefile.in (ALL_EMULATIONS): Move eelf64_sparc.o ...
+ (ALL_64_EMULATIONS): ... here.
+ (eelf64_sparc.c): Template should be elf32 not generic.
+ * emulparams/elf64_sparc.sh (TEMPLATE_NAME): New definition.
+
+Thu Oct 23 00:44:20 1997 Richard Henderson <rth@dot.cygnus.com>
+
+ * configure.tgt: Add sparc64-*-linux*.
+ * emulparams/elf64_sparc.sh (GENERATE_SHLIB_SCRIPT, NOP): New.
+
+Wed Oct 22 11:29:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/pe.sc: Put .eh_frame in .rdata.
+
+Fri Oct 17 00:00:13 1997 Richard Henderson <rth@cygnus.com>
+
+ * ldlang.c (lang_register_vers_node): Only check globals<=>locals,
+ since we need to be able to export different versions of the same
+ symbol.
+
+Wed Oct 15 14:52:36 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/pe.sc: Put .stab and .stabstr sections at end.
+
+Wed Oct 8 12:37:05 1997 Richard Henderson <rth@cygnus.com>
+
+ * configure.tgt, configure.host: Change alpha-*-* to alpha*-*-*;
+ config.guess now recognizes alphaev5 etc.
+
+Fri Oct 3 14:23:02 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Don't treat
+ -s and -u as -static and -unix.
+
+Thu Oct 2 18:40:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (wild_doit): Rewrite flag handling for clarity. If we
+ are not adding the first input section, and SEC_READONLY is clear
+ on the output section, then don't copy it from the input section.
+ If SEC_READONLY is not set on the input section, then clear it on
+ the output section.
+
+ * configure.tgt (mips*-sgi-irix[56]*): Use elf32bsmip rather than
+ elf32bmip.
+ (mips*el-*-linux*): Change elf32lmip to elf32lsmip and elf32bmip
+ to elf32bsmip.
+ (mips*-*-linux*): Likewise.
+ * emulparams/elf32bsmip.sh: New file; just like elf32bmip.sh, but
+ setting ENTRY to __start.
+ * emulparams/elf32lsmip.sh: New file; just like elf32lmip.sh, but
+ setting ENTRY to __start.
+ * scripttempl/elf.sc: Always set ENTRY to _start if it was not
+ already set.
+
+Wed Oct 1 16:41:00 1997 Nick Clifton <nickc@cygnus.com>
+
+ * emulparams/v850.sh (ROZDATA_START_ADDR, ROSDATA_START_ADDR): New
+ Variables.
+
+ * scripttempl/v850.sc: Move read only areas out of zero and small
+ data sections and into their own sections.
+
+Wed Sep 24 16:59:15 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.tgt (sh*-*-rtems*): New target, like sh-*-elf*.
+
+Wed Sep 24 11:33:14 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Section Options): Improve documentation of NOLOAD
+ directive.
+
+ * aclocal.m4: Rebuild with new libtool.
+ * configure: Rebuild.
+
+Mon Sep 22 17:24:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (wild_doit): Revert patch of September 3.
+
+Wed Sep 17 16:45:34 1997 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am, Makefile.in: Add rule for ev850.c
+ * configure.tgt (targ_extra_emuls): Add v850 target.
+
+Wed Sep 17 16:43:39 1997 Nick Clifton <nickc@cygnus.com>
+
+ * emulparams/v850.sh (CALL_TABLE_START_ADDR): New entry.
+ * scripttempl/v850.sc: Add call table data area
+
+Mon Sep 15 11:29:13 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merge change from Martin Hunt:
+
+ * scripttempl/elfd30v.sc: Put .rodata in the .text section.
+
+Tue Sep 9 07:49:56 1997 Fred Fish <fnf@ninemoons.com>
+
+ * ldlang.c (lang_memory_region_lookup): Remove extraneous
+ initialization of p.
+
+Thu Sep 4 09:03:33 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): In
+ expression produced for -bpT and -bpD options, align to a 32 byte
+ boundary rather than an 8 byte boundary.
+ * scripttempl/aix.sc: Put .tocbss at start of .bss section.
+
+ * ldmisc.h, ldmisc.c, ldcref.c: Rename finfo to lfinfo, to avoid
+ function name conflict with AIX 4.2 unistd.h header file.
+
+Wed Sep 3 15:12:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (wild_doit): Clear SEC_HAS_CONTENTS from a
+ noload_section.
+
+Fri Aug 29 00:32:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (ld_new_DEPENDENCIES): Remove @LEXLIB@.
+ * Makefile.in: Rebuild.
+
+Thu Aug 28 10:12:10 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.tgt (arc-*-elf*): Recognize.
+ * Makefile.am (ALL_EMULATIONS): Add earcelf.o.
+ * Makefile.in: Regenerate.
+ * emulparams/arcelf.sh: New file.
+
+Wed Aug 20 11:14:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (wildcardp): Don't let a backslash by itself cause a
+ pattern to be treated as a wildcard pattern.
+
+ * ldgram.y (atype): Accept parentheses with no type.
+
+ * ld.texinfo (Section Definition): Clarify use of whitespace.
+ (Section Placement): Likewise.
+
+Mon Aug 18 11:12:03 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt (targ_extra_emuls): Add support for v850e target.
+
+Mon Aug 18 11:12:03 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure.tgt (targ_extra_emuls): Add support for v850e target.
+
+Sat Aug 9 00:42:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (ld.info): Change dependency from
+ $(BFDDIR)/doc/bfdsumm.texi to bfdsumm.texi.
+ (ld.dvi): Likewise.
+ (bfdsumm.texi): New target.
+ (CLEANFILES): Add bfdsumm.texi.
+ * Makefile.in: Rebuild.
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * acinclude.m4: New file, from old aclocal.m4.
+ * configure.in: Call AM_INIT_AUTOMAKE and AM_PROG_LIBTOOL. Remove
+ shared library handling; now handled by libtool. Replace
+ AC_CONFIG_HEADER with AM_CONFIG_HEADER. Call AC_PROG_YACC,
+ AC_PROG_LEX, and AC_DECL_YYTEXT. Call AM_MAINTAINER_MODE,
+ AM_CYGWIN32, and AM_EXEEXT. Don't call CY_CYGWIN32 or CY_EXEEXT.
+ * configure.host: Don't set HLDFLAGS, HLDENV, or RPATH_ENVVAR.
+ * acconfig.h: Mention PACKAGE and VERSION.
+ * stamp-h.in: New file.
+ * ldver.c (ld_program_version): Set ld_program_version from
+ VERSION.
+ * ldgram.y, ldlex.l: Replace VERSION with VERSIONK.
+ * Makefile.in: Now built with automake.
+ * aclocal.m4: Now built with aclocal.
+ * configure, config.in: Rebuild.
+
+Mon Jul 28 19:04:50 1997 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * configure.in: Use CYGWIN and EXEEXT autoconf macro to look for
+ win32 dependencies.
+ * configure: Regenerated with autoconf 2.12.
+ * Makefile.in: Add $(EXEEXT) to executable.
+
+Tue Jul 22 18:50:38 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * emulparams/i386go32.sh (OUTPUT_FORMAT): Set to "coff-go32".
+ (SEGMENT_SIZE): Set to 0x200.
+ * scripttempl/i386go32.sc: Rewrite.
+ * configure.tgt (i[3456]86-*-msdosdjgpp*): New target.
+
+Mon Jul 7 12:39:42 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Manfred Hollstein <manfred@s-direktnet.de>:
+ * configure.host (i[3456]86-*-linux*libc1*): Renamed from
+ i[3456]86-*-linux*.
+ (i[3456]86-*-linux*): New host.
+
+Thu Jun 26 13:54:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/pe.sc: Put .rsrc after .reloc. Put input .rsrc
+ sections in the output .rsrc section.
+
+Wed Jun 25 12:48:41 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.host (m68*-*-linux*libc1*): Renamed from
+ `m68*-*-linux*'.
+ (m68*-*-linux*): New configuration for use with GNU libc 2.
+
+Mon Jun 16 19:18:21 1997 Geoff Keating <geoffk@ozemail.com.au>
+
+ * scripttempl/elfppc.sc: Correct .rela.sdata entries.
+
+ * scripttempl/elfppc.sc: Put the PLT between the small and large
+ BSS segments.
+ * emulparams/elf32ppc.sh (TEXT_START_ADDR): The ABI says `A
+ program base of 0x02000000 is recommended...' because otherwise
+ shared libraries are less efficient. We use 0x01800000 because
+ otherwise it's impossible to branch to location 0, for instance if
+ you have an undefined weak symbol.
+
+Mon Jun 16 12:49:36 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * ldlang.c (lang_place_undefineds): Add \n in einfo call.
+ (lang_size_sections): Likewise.
+ * ldlex.l: Likewise.
+ * emultempl/aix.em (gld${EMULATION_NAME}_read_file): Likewise.
+ * emultempl/mipsecoff.em (gld${EMULATION_NAME}_after_open):
+ Likewise.
+ (check_sections): Likewise.
+ (gld${EMULATION_NAME}_after_allocation): Likewise.
+ * emultempl/pe.em (gld_$${EMULATION_NAME}_before_allocation):
+ Likewise.
+ * mpw-eppcmac.c (gldppcmacos_read_file): Likewise.
+ * mpw-idtmips.c (gldmipsidt_after_open): Likewise.
+ (check_sections): Likewise.
+ (gldmipsidt_after_allocation): Likewise.
+
+ * ldemul.c (ldemul_choose_mode): Remove unused einfo argument.
+
+Fri Jun 6 23:47:42 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/pe.sc: Add zeroes after .idata$3 to mark the end of
+ the import list.
+
+Thu May 29 13:13:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Don't
+ crash if an output section has no BFD section.
+
+Fri May 23 15:23:25 1997 Fred Fish <fnf@cygnus.com>
+
+ * lexsup.c (ld_options): Add entry for the new "task-link" option.
+ (parse_args): Handle the "task-link" option.
+ (OPTION_TASK_LINK): Add define.
+
+Wed May 21 17:44:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): Correct check of fclose return value when
+ handling --force-exe-suffix.
+
+Thu May 15 11:35:29 1997 Nick Clifton <nickc@cygnus.com>
+
+ * ldlang.c (lang_check): Add test of the return value from the
+ call to bfd_merge_private_bfd_data().
+
+Mon May 12 23:22:58 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elfmips.sc: Remove.
+ * scripttempl/elf.sc: Set ENTRY based on target. Permit
+ TEXT_DYNAMIC to control .dynamic segment. Permit
+ SHLIB_TEXT_START_ADDR to set start of shared object. Support
+ INITIAL_READONLY_SECTIONS. Put .stub in .text. Only put
+ .gnu.linkonce.t* in .text when relocating. Support
+ OTHER_TEXT_SECTIONS. Support SHLIB_DATA_ADDR as well as
+ DATA_ADDR. Support OTHER_GOT_SYMBOLS and OTHER_GOT_SECTIONS.
+ * emulparams/elf32b4300.sh (SCRIPT_NAME): Set to elf.
+ (DATA_ADDR): Don't set.
+ (INITIAL_READONLY_SECTIONS): Rename from OTHER_READONLY_SECTIONS.
+ (OTHER_TEXT_SECTIONS): Set.
+ (OTHER_GOT_SECTIONS): Rename from OTHER_READWRITE_SECTIONS.
+ (MACHINE): Set to empty string.
+ * emulparams/elf32l4300.sh: Likewise.
+ * emulparams/elf32ebmip.sh: Likewise.
+ * emulparams/elf32elmip.sh: Likewise.
+ * emulparams/elf32bmip.sh: Likewise. Also:
+ (TEXT_DYNAMIC): Set.
+ * emulparams/elf32lmips.sh: Likewise.
+ * Makefile.in (eelf32bmips.c): Depend upon elf.sc rather than
+ elfmips.sc.
+ (eelf32ebmips.c, eelf32elmips.c, eelf32lmip.c): Likewise.
+
+Mon May 12 11:11:06 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * scripttempl/elf.sc: Don't align the data segment on the next 8
+ byte boundary, instead let the linker use whatever the individual
+ sections require.
+
+Fri May 9 17:45:46 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (i[3456]86-*-gnu*): Don't include Mach support.
+
+Tue May 6 13:21:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Sean McNeil <sean@mcneil.com>:
+ * emultempl/pe.em (sort_by_file_name): Sort by archive name
+ first.
+ (sort_sections): Sort all sections, not just sections in the same
+ archive.
+
+Mon May 5 18:19:55 1997 Philip Blundell <pjb27@cam.ac.uk>
+
+ * configure.tgt, configure.host: cope with '*-*-linux-gnuaout'
+ targets.
+
+Fri May 2 15:54:28 1997 Mike Meissner <meissner@cygnus.com>
+
+ * scripttempl/tic80coff.sc (.text): Add a leading underscore to
+ __{D,C}TOR_{LIST,END}__ definations. Rearrange the order of items
+ in the .text section. Move .const, .ctors, .dtors into separate
+ sections.
+
+Wed Apr 30 12:23:21 1997 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * scripttempl/m88kbcs.sc (__.initp.end, _etext): Added whitespace
+ around assignment of current location pointer.
+
+Thu Apr 17 13:07:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldctor.c (ldctor_build_sets): Make sure the set is aligned
+ appropriately.
+
+Tue Apr 15 13:19:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL): Set to @INSTALL@.
+ (INSTALL_XFORM, INSTALL_XFORM1): Remove.
+ (install): Depend upon ld.new and installdirs. Use
+ $(program_transform_name) directly, rather than using
+ $(INSTALL_XFORM) and $(INSTALL_XFORM1).
+ (installdirs): New target.
+ (install-info): Run mkinstalldirs.
+
+Mon Apr 14 12:06:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (INSTALL): Change install.sh to install-sh.
+
+ From Thomas Graichen <graichen@rzpd.de>:
+ * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub.
+ * configure: Rebuild.
+
+Fri Apr 4 11:42:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em: Include "libiberty.h".
+ (sort_sections_1): Use xmalloc rather than alloca.
+
+ * ldlex.l: Recognize SQUAD.
+ * ldgram.y (length): Add SQUAD.
+ * ldctor.c (ldctor_build_sets): Use SQUAD for a signed 8 byte
+ reloc.
+ * ldlang.c (print_data_statement): Handle SQUAD.
+ (lang_size_sections, lang_do_assignments): Likewise.
+ * ldexp.c (exp_print_token): Add SQUAD to table.
+ * ldwrite.c (build_link_order): Handle SQUAD.
+ * ld.texinfo (Section Data Expressions): Document SQUAD.
+
+Thu Apr 3 13:19:40 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldver.c (ld_program_version): Set to 2.8.1.
+
+ * Branched binutils 2.8.
+
+Wed Apr 2 11:55:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mpw-idtmips.c: Rename from mpw-emipsidt.c.
+ * mpw-elfmips.c: Rename from mpw-emipself.c.
+ * mpw-config.in: Update accordingly.
+
+ * ldlang.c (lang_process): Call lang_check immediately after
+ opening the input files, rather than at the end of the link.
+
+Mon Mar 31 23:44:00 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (init): Fully bracket initializer.
+ (set_pe_stack_heap): Remove locals begin_commit and end.
+ (gld_${EMULATION_NAME}_after_open): Remove unused local i.
+ (gld${EMULATION_NAME}_place_orphan): Remove unused local ptr.
+
+Mon Mar 31 16:35:51 1997 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.tgt (hppa*-*-rtems*): New target, like hppa-*-*elf*.
+
+Fri Mar 28 15:29:23 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ Contributed by David S. Miller <davem@caip.rutgers.edu>:
+ * configure.tgt (sparc*-*-linuxaout*): New target.
+ (sparc*-*-linux*): New target.
+ * emulparams/sparclinux.sh: New file.
+ * Makefile.in (ALL_EMULATIONS): Add esparclinux.o.
+ (esparclinux.c): New target.
+
+Fri Mar 28 14:30:12 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Ralf Baechle <ralf@gnu.ai.mit.edu>:
+ * configure.tgt: Set targ_extra_emuls for mips*el-*-linux* and
+ mips*-*-linux*. Use elf32bmip and elf32lmip, not elf32ebmip and
+ elf32elmip.
+
+Thu Mar 27 17:14:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (parse_args): Update copyright date in version
+ message.
+
+Fri Mar 21 12:28:41 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * emulparams/delta68.sh (OUTPUT_FORMAT): Set to "coff-m68k-sysv".
+
+Tue Mar 18 11:16:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild dependencies.
+
+ * emultempl/aix.em: Include "obstack.h".
+
+Mon Mar 17 19:26:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c: Include "obstack.h".
+
+Sat Mar 15 23:23:46 1997 Fred Fish <fnf@cygnus.com>
+
+ * configure.tgt (powerpc-*-beos*): Use aixppc for targ_emul.
+
+Sat Mar 15 18:10:38 1997 H.J. Lu <hjl@lucon.org>
+
+ * ldemul.h (ldemul_list_emulations): Use full prototype.
+ * ldlang.c (print_one_symbol): Add declaration.
+ * ldlang.h (dprint_statements): Declare.
+ * ldmain.c (remove_output): Declare.
+ * ldmisc.c (vfinfo): Declare.
+ * ldwrite.c (clone_section): Declare.
+ (split_sections): Make static. Declare.
+ * mri.c: Include libiberty.h.
+ (strdup): Don't declare.
+ (mri_alias): Use xstrdup rather than strdup.
+
+Fri Mar 14 21:30:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elfmips.sc: Change handling of data area when
+ generating a shared library to not skip a large block of memory.
+ From Per Fogelstrom <pefo@cvs.openbsd.org>.
+
+Wed Mar 12 21:33:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (multiple_definition): Only skip the warning if the
+ output section is absolute when the input section is not
+ absolute.
+
+ * ldlex.l: Accept whitespace in VERS_START state. Warn about
+ invalid characters in VERS_* states.
+
+Tue Mar 11 13:51:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_read_file): Don't let a
+ trailing space lead us to think that there is a zero address.
+
+Sun Mar 9 23:06:35 1997 Eric Youngdale <eric@andante.jic.com>
+
+ * ldgram.y (vers_node): Correct typo of '(' for '{'.
+
+Fri Mar 7 18:40:12 1997 Fred Fish <fnf@cygnus.com>
+
+ * scripttempl/tic80coff.sc (ENTRY): Entry symbol is __start
+ rather than _start.
+ (__edata): Define this rather than "edata".
+ (__end): Define this rather than "end".
+
+Tue Mar 4 17:18:35 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure.tgt (tic80-*-*): Allow dropping of -coff.
+
+Sun Mar 2 22:59:49 1997 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (ld.dvi): Set MAKEINFO environment variable as well
+ as TEXINPUTS. Needed for building in separate build dir.
+ * ldint.texinfo (SCRIPT_NAME): Fix typo.
+ * emulparams/tic80coff.sh: Rewrite to include internal documentation
+ about each shell variable that is set (or not set).
+ * scripttempl/tic80coff.sc: Complete rewrite.
+
+Fri Feb 28 17:42:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): Call bfd_set_default_target.
+ * Makefile.in (ldmain.o): Define TARGET when compiling.
+
+Thu Feb 27 11:41:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): Don't initialize link_info.lprefix or
+ link_info.lprefix_len.
+ * emultempl/hppaelf.em (hppaelf_before_parse): Likewise.
+
+ * emultempl/m88kbcs.em: Remove.
+ * emulparams/m88kbcs.sh (TEMPLATE_NAME): Don't set.
+ * Makefile.in (em88kbcs.c): Depend upon generic.em rather than
+ m88kbcs.em.
+
+ * mri.c (mri_draw_tree): Pass noload_section, not SEC_NEVER_LOAD,
+ to lang_enter_output_section_statement. From Mark Rasin
+ <mark.rasin@telrad.co.il>.
+
+Wed Feb 26 11:51:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_one_common): Clear SEC_IS_COMMON from common
+ section.
+
+Tue Feb 25 20:38:11 1997 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (mips*-*-lnews*): New target.
+ * Makefile.in (emipslnews.c): New target.
+ * emulparams/mipslnews.sh: New file.
+
+Tue Feb 25 16:04:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (hold_interp): New static variable.
+ (gld${EMULATION_NAME}_place_orphan): Put loadable .note sections
+ after hold_interp. Choose a unique output section name.
+ (gld${EMULATION_NAME}_place_section): Don't set hold_use if the
+ SEC_LOAD or SEC_ALLOC flags differ. Set hold_interp.
+
+Mon Feb 24 18:16:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Eric Youngdale <eric@andante.jic.com>:
+ * ldlex.l (V_TAG, V_IDENTIFIER): New macros.
+ (VERS_START, VERS_SCRIPT, VERS_NODE): New states to parse version
+ information.
+ (ldlex_version_script, ldlex_version_file): New functions.
+ * ldlex.h (enum input_enum): Add input_version_script.
+ (ldlex_version_script): Declare.
+ (ldlex_version_file): Declare.
+ * ldgram.y (%union): Add deflist, versyms, and versnode.
+ (VERS_TAG, VERS_IDENTIFIER): New terminals.
+ (GLOBAL, LOCAL, VERSION, INPUT_VERSION_SCRIPT): New terminals.
+ (file): Accept INPUT_VERSION_SCRIPT.
+ (ifile_p1): Accept version.
+ (version_script_file): New nonterminal.
+ (version, vers_nodes, vers_node): Likewise.
+ (verdep, vers_tag, ver_defns): Likewise.
+ * ldlang.c (lang_elf_version_info): New global variable.
+ (lang_new_vers_regex): New function.
+ (lang_new_vers_node): New function.
+ (version_index): New static variable.
+ (lang_register_vers_node): New function.
+ (lang_add_vers_depend): New function.
+ * ldlang.h (lang_elf_version_info): Declare.
+ (lang_new_vers_regex, lang_new_vers_node): Declare.
+ (lang_add_vers_depend, lang_register_vers_node): Declare.
+ * lexsup.c (OPTION_VERSION_SCRIPT): Define.
+ (ld_options): Add "version-script".
+ (parse_args): Handle OPTION_VERSION_SCRIPT.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Pass lang_elf_version_info to size_dynamic_sections.
+ * scripttempl/elf.sc: Add .gnu.version sections.
+ * ld.texinfo: Document symbol versioning.
+
+Fri Feb 21 17:37:51 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * Makefile.in (ed30velf.c): New target.
+ * configure.tgt (d30v-*-*): New target.
+ * emulparams/d30velf.sh: New file.
+ * scripttempl/elfd30v.sc: New file.
+
+Fri Feb 14 18:28:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Option Commands): Document the INCLUDE command.
+
+Thu Feb 13 20:31:37 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * configure.in: Call BFD_NEED_DECLARATION on getenv.
+ * acconfig.h (NEED_DECLARATION_GETENV): New macro.
+ * sysdep.h (getenv): Declare if NEED_DECLARATION_GETENV.
+ * ldemul.c (ld_emul_default_target): Do not cast getenv return
+ value.
+ * ldmain.c (get_emulation): Likewise.
+ * configure, config.in: Rebuild.
+
+Tue Feb 11 15:34:26 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elfmips.sc: When relocating, put .mips16.fn.* and
+ .mips16.call.* in .text.
+
+Sun Feb 9 18:09:13 1997 Fred Fish <fnf@cygnus.com>
+
+ * emulparams/tic80coff.sh: New (dummy) file for TIc80.
+ * scripttempl/tic80coff.sc: New (dummy) file for TIc80.
+ * Makefile.in (etic80coff.c): Add target and rule to build it.
+ * configure.tgt (tic80-*-coff): Set targ_emul to tic80coff.
+
+Fri Jan 31 13:16:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Search for
+ ".so" in the name, not ".so.".
+ (gld${EMULATION_NAME}_search_dir): Accept a plain .so file.
+
+ * Makefile.in (ld.info): Add -I$(srcdir). From Alan Modra
+ <alan@spri.levels.unisa.edu.au>.
+
+Thu Jan 30 11:31:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em: Include <ctype.h>.
+ (gld${EMULATION_NAME}_find_so): Skip the directory name when
+ searching for ".so.".
+ (gld${EMULATION_NAME}_search_dir): Make sure that the library name
+ has a version number, and that only version numbers follow .so.
+
+Wed Jan 29 18:15:00 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * scripttempl/pe.sc:
+ * scripttempl/ppcpe.sc: add *(.gcc_except_table) to the text
+ section so Win32 executables are valid.
+
+Mon Jan 27 12:28:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elf.sc: Put linkonce reloc section in other
+ appropriate reloc sections.
+ * scripttempl/elfmips.sc: Add linkonce support.
+ * scripttempl/elfppc.sc: Likewise.
+
+Fri Jan 24 10:44:09 1997 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/mn10200.sh (OTHER_RELOCATING_SECTIONS): Move the
+ stack up to 0x80000.
+ * emulparms/mn10300.sh (OTHER_RELOCATING_SECTIONS): Likewise.
+
+Tue Jan 21 12:11:10 1997 Doug Evans <dje@seba.cygnus.com>
+
+ * emulparams/m32relf.sh (OTHER_RELOCATING_SECTIONS): Use PROVIDE
+ to define `_stack'.
+
+Thu Jan 16 17:07:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (args_type): Rename auxiliary_filter_shlib to
+ auxiliary_filters, and make it char **.
+ * lexsup.c (parse_args): Handle -f by setting up an array.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Use
+ new name of auxiliary_filters.
+
+ * ld.texinfo (Options): Improve documentation of --filter and
+ --auxiliary.
+
+Tue Jan 14 15:44:28 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Options): Clarify that the normal usage is -T.
+ (Commands): Likewise.
+
+Thu Jan 9 11:26:27 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/armcoff.sc: Correct mask used for .data address.
+
+Wed Jan 8 15:14:59 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * emultempl/pe.em: make default executable a.exe instead of
+ a.out
+
+Fri Jan 3 17:33:34 1997 Richard Henderson <rth@tamu.edu>
+
+ * scripttempl/elf.sc: Move .got closer to .sdata and .sbss by
+ shifting .plt back. Rumour has it that the NetBSD ld.so depends
+ on .dynamic being after .got, so we leave that.
+
+Fri Jan 3 14:04:40 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (clean): Don't remove configdoc.texi.
+ (maintainer-clean): Do remove configdoc.texi.
+
+ * ld.texinfo (Operators): Remove '@' from @smallexmple in comment
+ to avoid confusing texi2roff.
+
+Fri Jan 3 11:27:02 1997 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/v850.sc (.zdata): Add .zcommon section.
+ (.tdata): Add .tcommon and .tcommon_byte sections.
+
+Thu Jan 2 18:14:32 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (mips*el-*-linux*, mips*-*-linux*): New targets.
+ * scripttempl/elfmips.sc: Use __start as the entry address for
+ mips*-*-linux*.
+
+Tue Dec 31 14:48:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE.
+
+ * ld.h (args_type): Add filter_shlib and auxiliary_filter_shlib
+ fields.
+ * lexsup.c (parse_args): Recognize --auxiliary/-f and
+ --filter/-F.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Pass filter_shlib and auxiliary_filter_shlib to
+ size_dynamic_sections.
+ * ld.texinfo, ld.1: Document --filter/-F and --auxiliary/-f.
+
+Mon Dec 30 13:55:57 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/v850.sc (.tdata) Add .tbss and .tbyte sections.
+
+Wed Dec 18 22:57:35 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Use NewFolderRecursive for installation.
+
+Fri Dec 13 14:08:50 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/v850.sc: Make sure __{e,g}p start relative to the
+ {s,t}data sections. Do not emit any linker generated symbols if
+ -r. Use {TEXT,{Z,S,T}DATA}_START_ADDR variables to initialize
+ where the different sections go. Change some whitespace.
+
+ * emulparams/v850.sh ({TEXT,{Z,S,T}DATA}_START_ADDR): Define
+ appropriately. Remove crud not used anymore.
+
+Fri Dec 13 10:19:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (emn10200.c): Add dependencies.
+ * configure.tgt: Handle mn10200.
+ * emulparms/mn10200.sh: New file.
+
+Thu Dec 12 17:04:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/gld960c.em: Include <ctype.h>.
+ (gld960_set_output_arch): Get the machine type from the -A option
+ if there is one, rather than always using core.
+
+Sat Dec 7 10:07:51 1996 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/mn10300.sh: Handle leading underscores.
+
+Thu Dec 5 13:45:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_section): Only
+ set hold_rel if SEC_ALLOC is set.
+
+Tue Dec 3 11:29:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (section_already_linked): Set the output_offset as well
+ as the output_section when only reading symbols from a file.
+
+Mon Dec 2 11:43:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emulparams/*.sh: Make sure that each set of parameters which
+ uses the elf.sc script sets MACHINE.
+
+Wed Nov 27 03:22:05 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * scripttempl/elf{,mips,ppc}.sc: Add the remaining DWARF sections.
+ * scripttempl/elfd10v.sc: Likewise.
+ * scripttempl/v850.sc: Likewise.
+
+Tue Nov 26 16:58:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.
+
+Mon Nov 25 12:17:55 1996 Jim Wilson <wilson@cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): Add case
+ for bfd_vma to init loop.
+
+Mon Nov 25 09:55:07 1996 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/mn10300.sh: Remove bogus '_' prefix for
+ entry symbol and ctor/dtor stuff.
+
+Fri Nov 15 13:00:18 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (emn10300.c): Add dependencies.
+ * configure.tgt: Handle mn10300.
+ * emulparms/mn10300.sh: New file.
+
+Tue Nov 5 10:57:50 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * emulparams/d10velf.sh (READONLY_START_ADDR): Changed to 0x2000004.
+ (EMBEDDED): Define.
+
+Fri Nov 1 10:01:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo: Add section on reporting bugs.
+
+ * scripttempl/m68kcoff.sc: Make sure the etext and __CTOR_LIST__
+ symbols are correctly aligned.
+
+Thu Oct 31 09:28:59 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scriptempl/v850.sc (zdata): Handle reszdata, romzdata and
+ romzbss too.
+
+Tue Oct 29 12:33:05 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * emulparams/d10velf.sh: Changes needed for D10V-EVA board.
+ Set TEXT_START_ADDR to 0x1000000. Set READONLY_START_ADDR to
+ 0x2000000.
+
+ * scripttempl/elfd10v.sc: Fix calculation of .text. Change
+ .stack to start at 0x2007ffe.
+
+Mon Oct 28 15:37:00 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.tgt (sparclet*-*-aout*): Delete, use sparc*-*-aout*.
+
+Wed Oct 23 16:17:22 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scriptempl/v850.sc (zdata): Fix typo "zrodata" -> "rozdata".
+
+ * scriptempl/v850.sc (zdata): Make sure this stays
+ in lo-memory.
+
+Tue Oct 22 11:36:47 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/v850.sc (__ep): Put it at the start
+ of the tda section.
+
+ * scriptempl/v850.sc: Move all "normal" sections into
+ the external memory region (0x100000 - 0x200000).
+
+Mon Oct 21 17:16:59 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * scripttempl/elfd10v.sc: Clone from elf.sc, move .text to
+ 0x10000, so that is more room for data.
+
+ * emulparams/d10velf.sh (TEXT_START_ADDR): Now 0x100000.
+ (READONLY_START_ADDR): Now 0x0.
+ (SCRIPT_NAME): Now elfd10v.
+
+ * Makefile.in (ed10velf.c): Depend on elfd10v.sc, not elf.sc.
+
+Fri Oct 18 22:12:49 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * emulparams/m32relf.sh (TEXT_START_ADDR): Change from 0 to 0x100.
+
+Fri Oct 18 15:43:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALL_EMULATIONS): Remove eelf64alpha.o.
+ (ALL_64_EMULATIONS): New variable.
+ * configure.in: Accept --enable-64-bit-bfd option. If it is set
+ with --enable-targets=all, include ALL_64_EMULATIONS in
+ EMULATION_OFILES.
+ * configure: Rebuild.
+
+Fri Oct 18 12:58:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/v850.sc (__gp, __ep): Define.
+
+Thu Oct 17 18:14:07 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo: Try to consistently use a single or a double dash
+ for each option.
+
+Thu Oct 17 10:17:20 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * emulparams/m32relf.sh (EMBEDDED): Define.
+
+Thu Oct 17 10:56:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/v850.sc (.zdata): Add this before .text.
+ (.sdata): Also include .rosdata as part of the .sdata.
+ (.tdata): Include this just before .sdata.
+
+ * emulparms/v850.sh (SCRIPT_NAME): Use "v850" not "elf".
+ * scripttempl/v850.sc: Wrap script with a "cat << EOF".
+
+Wed Oct 16 23:10:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/v850.sc: New linker script for the V850.
+ * Makefile.in: Use it.
+
+Thu Oct 10 17:57:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emulparams/elf32b4300.sh: Define _gp in OTHER_GOT_SYMBOLS, not
+ OTHER_READWRITE_SECTIONS.
+ * emulparams/elf32l4300.sh: Likewise.
+
+Wed Oct 9 14:36:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (ld_config_type): Add warn_section_align field.
+ * lexsup.c (OPTION_WARN_SECTION_ALIGN): Define.
+ (ld_options): Add --warn-section-align.
+ (parse_args): Handle --warn-section-align.
+ * ldlang.c (lang_size_sections): If warn_section_align, warn if
+ the start of a section changes due to alignment.
+ * ld.texinfo, ld.1: Document --warn-section-align.
+ * ld.texinfo: Change some single dashes to double dashes.
+
+ * emultempl/pe.em (set_pe_subsystem): Record entry symbol for each
+ subsystem type. Ifdef out os2 type. Recognize a version number.
+
+Tue Oct 8 12:07:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (set_pe_subsystem): When setting the subsystem
+ to windows, set the entry point.
+
+ * Makefile.in (ldlex.c): Don't pass any options to $(LEX).
+
+Mon Oct 7 17:29:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Options): Mention .so extensions for shared
+ libraries.
+
+Sun Oct 6 22:35:36 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * scripttempl/elf{,mips,ppc}.sc: Add DWARF 2 sections.
+
+Fri Oct 4 18:49:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/m68kcoff.sc: Only set the address of .text if
+ RELOCATING.
+
+Fri Oct 4 10:59:52 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * emulparams/sparcaout.sh ({BIG,LITTLE}_OUTPUT_FORMAT): Define.
+ * scripttempl/aout.sc ({BIG,LITTLE}_OUTPUT_FORMAT): Provide default.
+ (OUTPUT_FORMAT): Support bi-endian targets.
+
+Thu Oct 3 13:52:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * fnmatch.h, fnmatch.c: Remove (now in libiberty).
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Remove fnmatch.c.
+ (HFILES): Remove fnmatch.h.
+ (OFILES): Remove fnmatch.o.
+
+Thu Oct 3 15:41:24 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (mostlyclean): Move config.log to distclean.
+
+Wed Oct 2 23:45:25 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * emultmpl/pe.em: increase size of stack reserve to 0x2000000
+ (necessary in order to compile parse.c in gcc sources under NT)
+
+Wed Oct 2 14:49:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (ld_options): Fix typo in --rpath-link description.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Suggest
+ --rpath if a needed library is not found.
+
+Tue Oct 1 16:17:33 1996 Joel Sherrill <joel@oarcorp.com>
+
+ * configure.tgt (mips*-*-rtems*): New target, like mips*-*-elf*.
+
+Tue Oct 1 15:50:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo (Options): Give more detail on -l option.
+
+ * scripttempl/elfmips.sc: Handle CREATE_SHLIB the same way that
+ elf.sc does, so that glibc works better.
+
+ * ldver.c (ld_program_version): New variable.
+ (ldversion): Use it.
+ * ldver.h (ld_program_version): Declare.
+ * lexsup.c (ld_options): Handle --dll-verbose like --verbose, not
+ --version. Change --version handling to match current GNU
+ standards.
+ (help): Print bug report address.
+
+Mon Sep 30 12:14:43 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (em32relf.c): Add rule for.
+ * configure.tgt (m32r-*-*): Recognize.
+ * emulparams/m32relf.sh: New file.
+
+Thu Sep 26 13:58:47 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Add symbolic doublequoting to ldmain compile edit.
+ * mpw-config.in: Add mips-*-* case as mips-elf, and use more
+ wildcards in matching.
+ * mpw-emipself.c: New file, pregenerated mips elf emulation.
+
+Tue Sep 17 12:18:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldint.texinfo: Rewrote.
+
+ * configure.tgt: Add cases for MIPS 5000 like MIPS 4300.
+
+Mon Sep 16 17:55:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/armcoff.sc: Only define symbols if RELOCATING. Fix
+ syntax error on __end__ line.
+
+ * scripttempl/armcoff.sc: For -N or -n, don't align .data. From
+ Chris Hadley <Christopher.Hadley@cl.cam.ac.uk>
+
+Sun Sep 15 22:09:56 1996 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/v850.sh: Fix OTHER_RELOCATING_SECTIONS.
+
+Sun Sep 15 10:38:16 1996 Mark Alexander <marka@cygnus.com>
+
+ * emulparms/d10v.sh: Set OTHER_RELOCATING_SECTIONS to put
+ stack at top of simulator memory.
+
+Fri Sep 13 15:49:45 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlex.l (SYMBOLCHARN): Add $, _, and ~.
+
+Wed Sep 11 23:30:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (get_emulation): Check for -mips4 like -mips1, et. al.
+
+Thu Sep 5 15:24:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (section_already_linked): Accept a lang_input_statement
+ as the PTR argument. If the file is symbols only, discard all
+ input sections.
+ (ldlang_add_file): Pass entry to bfd_map_over_sections.
+
+Wed Sep 4 15:53:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (alpha-*-gnu*): New target. From Fila Kolodny
+ <fila@ibi.com>.
+
+Tue Sep 3 00:52:54 1996 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/v850.sh: Set OTHER_RELOCATING_SECTIONS
+
+Sun Sep 1 21:48:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/v850.sh: Set EMBEDDED.
+
+Fri Aug 30 22:30:30 1996 Jeffrey A Law (law@cygnus.com)
+
+ * emulparms/v850.sh: Entry symbol is "_start", tweak
+ ctor/dtor support.
+
+Fri Aug 30 18:32:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (sh-*-elf*): New target.
+ * emulparams/shelf.sh: New file.
+ * emulparams/shlelf.sh: New file.
+ * Makefile.in (ALL_EMULATIONS): Add eshelf.o and eshlelf.o.
+ (eshelf.c, eshlelf.c): New targets.
+ * scripttempl/elf.sc: If EMBEDDED is defined, then don't add
+ SIZEOF_HEADERS to TEXT_START_ADDR. Expand CTOR_START and CTOR_END
+ around .ctors, and DTOR_START and DTOR_END around .dtors. Expand
+ OTHER_RELOCATING_SECTIONS if RELOCATING.
+
+Thu Aug 29 16:57:46 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.{host,tgt} (i[345]86-*-*): Recognize i686 for pentium
+ pro.
+
+Mon Aug 26 12:58:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y (section): Add opt_nocrossrefs; pass value to
+ lang_enter_overlay.
+ (opt_nocrossrefs): New nonterminal.
+ * ldlex.l: Recognize NOCROSSREFS keyword in EXPRESSION mode.
+ * ldlang.c (overlay_nocrossrefs): New static variable.
+ (lang_enter_overlay): Add nocrossrefs parameter.
+ (lang_leave_overlay): Only add nocrossrefs if overlay_nocrossrefs
+ is set. Initialize overlay_nocrossrefs.
+ * ldlang.h (lang_enter_overlay): Update declaration.
+ * ld.texinfo (Overlays): Update documentation.
+
+ * ldver.c (ldversion): Print GNU ld in the version message.
+
+Thu Aug 22 17:10:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Set HLDENV.
+ * configure.in: Substitute HLDENV.
+ * configure: Rebuild.
+ * Makefile.in (HLDENV): New variable.
+ ($(LD_PROG)): Use $(HLDENV).
+
+Thu Aug 22 16:29:28 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (ev850.c): New target.
+ * configure.tgt (v850-*-*): New target.
+ * emulparams/v850.sh: New file.
+
+Thu Aug 22 11:16:02 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Add @DASH_C_FLAG@ to compiler edit.
+
+Wed Aug 21 11:26:37 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elf.sc: Put .gnu.linkonce* sections in appropriate
+ containing sections.
+
+Mon Aug 19 13:01:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * fnmatch.c: Include sysdep.h.
+
+Mon Aug 19 11:28:29 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * genscripts.sh: Undo 8/16 change.
+
+ * emulparams/d10velf.sh (MACHINE): Explicitly set to nothing.
+
+Fri Aug 16 19:18:08 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * genscripts.sh: Explicitly reset any shell variables set or used
+ by the various .sc scripts to allow inadvertant use of these
+ names as normal environment variables by the person running
+ configure.
+
+ * Makefile.in (ed10velf.c): Use tdir_d10v, not tdir_arcelf.
+
+Fri Aug 16 14:15:41 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * scripttempl/armcoff.sc (__bss_start__, __bss_end__,
+ __data_start__, __data_end__): Added to keep in sync. with the
+ default ARM crt0.s. Added __CTOR_LIST__ and __DTOR_LIST__ support.
+
+Thu Aug 8 14:24:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldcref.c (check_reloc_refs): If info->same, look for any symbol
+ defined in info->defsec, not just the section symbol.
+
+Wed Aug 7 14:40:48 1996 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * configure.in: Call BFD_NEED_DECLARATION on strstr and sbrk.
+ * acconfig.h (NEED_DECLARATION_STRSTR): New macro.
+ (NEED_DECLARATION_SBRK): New macro.
+ * configure, config.in: Rebuild.
+ * sysdep.h (strstr): Declare if NEED_DECLARATION_STRSTR.
+ * ldmain.c (sbrk): Declare if HAVE_SBRK and
+ NEED_DECLARATION_SBRK.
+
+ * ldlang.c (lang_record_phdrs): Cast xmalloc and xrealloc return.
+
+Mon Aug 5 16:26:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlex.l: Recognize OVERLAY.
+ * ldgram.y: Add section_phdr field to %union.
+ (section): Handle phdr_opt result. Add OVERLAY case.
+ (opt_exp_without_type): New nonterminal.
+ (phdr_opt): Return list of phdrs.
+ (overlay_section): New nonterminal.
+ * ldlang.c: Include <ctype.h>.
+ (lang_leave_output_section_statement): Add phdrs parameter.
+ Change all callers.
+ (lang_section_in_phdr): Remove.
+ (overlay_vma, overlay_lmn, overlay_max): New static variables.
+ (struct overlay_list): Define.
+ (overlay_list): New static variable.
+ (lang_enter_overlay, lang_enter_overlay_section): New functions.
+ (lang_leave_overlay_section, lang_leave_overlay): New functions.
+ * ldlang.h (lang_leave_output_section_statement): Update
+ declaration for new parameter.
+ (lang_section_in_phdr): Don't declare.
+ (lang_enter_overlay, lang_enter_overlay_section): Declare.
+ (lang_leave_overlay_section, lang_leave_overlay): Declare.
+ * ld.texinfo (Overlays): New node under SECTIONS, documenting
+ overlays.
+
+ * ldlex.l: Recognize MAX and MIN.
+ * ldgram.y (MAX, MIN): New terminals.
+ (exp): Recognize MAX and MIN.
+ * ldexp.c (fold_binary): Handle MAX and MIN.
+ * ld.texinfo (Arithmetic Functions): Document MAX and MIN.
+
+ * ld.texinfo (PHDRS): Use @cindex, not @kindex, for program header
+ index entries.
+
+ * ldgram.y (SIZEOF, ADDR): Do not specify type.
+
+ * ldcref.c (check_nocrossref): Skip symbols with no output
+ sections.
+
+Fri Aug 2 14:57:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y (LOADADDR): New terminal.
+ (exp): Handle LOADADDR.
+ * ldlex.l: Recognize LOADADDR.
+ * ldexp.c (exp_print_token): Add LOADADDR.
+ (fold_name): Implement LOADADDR.
+ * ldlang.c (exp_init_os): Treat LOADADDR like ADDR.
+ * ld.texinfo (Arithmetic Functions): Document LOADADDR.
+
+Thu Aug 1 12:52:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (check_nocrossrefs): Declare.
+ * ldlang.h (struct lang_nocrossref): Define.
+ (struct lang_nocrossrefs): Define.
+ (nocrossref_list): Declare.
+ (lang_add_nocrossref): Declare.
+ * ldlex.l: Recognize NOCROSSREFS keyword.
+ * ldgram.y (%union): Add nocrossref field.
+ (NOCROSSREFS): New terminal.
+ (ifile_p1): Recognize NOCROSSREFS.
+ (nocrossref_list): New nonterminal.
+ * ldlang.c (nocrossref_list): Define.
+ (lang_add_nocrossref): New function.
+ * ldmain.c (main): If nocrossref_list is not NULL, call
+ check_nocrossrefs.
+ (warning_callback): Free symbols if there is no place to store
+ them.
+ (notice): Call add_cref if nocrossref_list is not NULL.
+ * ldcref.c: Include "ldexp.h" and "ldlang.h".
+ (check_nocrossrefs): New function.
+ (check_nocrossref): New static function.
+ (struct check_refs_info): Define.
+ (check_refs, check_reloc_refs): New static functions.
+ * Makefile.in: Rebuild dependencies.
+ * ld.texinfo (Option Commands): Document NOCROSSREFS.
+
+ * ld.texinfo (Section Placement): Improve the wording of the
+ wildcard documentation. Mention that wildcards are only searched
+ for on the command line, not in the file system.
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_after_open): Move
+ definition of lib_path inside condition where it is used.
+
+Wed Jul 31 13:17:10 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * emulparams/d10velf.sh: Now works with elf.sc.
+
+Wed Jul 31 11:52:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * emulparams/d10velf.sh (SCRIPT_NAME): Change to vanilla.
+
+Tue Jul 30 14:46:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_size_sections): Add the section VMA to the result
+ value when computing the address of a section.
+
+ * ld.h (args_type): Add cref field.
+ * lexsup.c (parse_args): Set command_line.cref.
+ * ldmain.c (main): Check command_line.cref rather than
+ link_info.notice_all.
+ (notice): Likewise.
+
+ * ldcref.c (output_one_cref): Don't crash if a symbol is defined
+ in a section without an owner.
+
+Mon Jul 29 17:23:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * fnmatch.h, fnmatch.c: New files.
+ * ldlex.l: Remove unused definition of FILENAME. Add definition
+ of WILDCHAR. In SCRIPT mode, accept any sequence of WILDCHAR as a
+ NAME.
+ * ldgram.y (file_NAME_list): Accept '*' and '?' specially.
+ (input_section_spec): Accept '?' specially.
+ (statement): Change exp to mustbe_exp in length and FILL cases.
+ (section): Call ldlex_script before section statements, and call
+ ldlex_popstate after them.
+ * ldlang.c: Include "fnmatch.h".
+ (wildcardp): New static function.
+ (wild_section): Permit the section name to be a wildcard.
+ (wild_file): New static function, broken out of wild.
+ (wild): Call wild_file. Permit the file name to be a wildcard.
+ (open_input_bfds): Don't call lookup_name for a wildcard pattern.
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Add fnmatch.c.
+ (HFILES): Add fnmatch.h.
+ (OFILES): Add fnmatch.o.
+ * ld.texinfo: Document that file and section names can now be
+ wildcard patterns.
+
+ * ldlang.c (lang_place_orphans): Correct condition: place a common
+ section if not relocateable or if common definitions are forced.
+
+Wed Jul 24 12:16:38 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * emulparams/d10velf.sh (SCRIPT_NAME): Change to elf.
+
+Wed Jul 24 13:38:22 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * configure.tgt (d10v-*-*): Don't require the -elf, allow plain d10v.
+
+Tue Jul 23 10:36:19 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * Makefile.in (ed10velf.c): New target.
+ * configure.tgt (d10v-*-elf*): New target.
+ * emulparams/d10velf.sh: New file.
+
+Thu Jul 18 16:25:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (sparc*-*-sysv4*): New target. From Andrew Gierth
+ <ANDREWG@microlise.co.uk>.
+
+ * configure.host: Change irix5 to irix[56]*.
+ * configure.tgt: Likewise.
+
+Wed Jul 17 10:52:46 1996 Kim Knuttila <krk@cygnus.com>
+
+ * emultempl/pe.em (sort_sections): Pay attention to return code.
+
+ * ldmisc.c (demangle): Remove all prefix '.'s from a name.
+
+Mon Jul 15 11:49:49 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Round
+ the value of __start_SECNAME to the alignment required by the
+ section to be placed.
+
+Tue Jul 9 12:09:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (mips*el-*-elf*): Use elf32elmip.
+ (mips*-*-elf*): Use elf32ebmip.
+ * emulparams/elf32bmip.sh (EMBEDDED): Don't define.
+ * emulparams/elf32lmip.sh (EMBEDDED): Don't define.
+ * emulparams/elf32elmip.sh: New file; copy of elf32lmip.sh with
+ EMBEDDED defined.
+ * emulparams/elf32ebmip.sh: New file; copy of elf32bmip.sh with
+ EMBEDDED defined.
+ * emulparams/elf32b4300.sh (EMBEDDED): Define.
+ * emulparams/elf32l4300.sh (EMBEDDED): Define.
+ * Makefile.in (ALL_EMULATIONS): Add eelf32ebmip.o eelf32elmip.o.
+ (eelf32ebmip.c, eelf32elmip.c): New targets.
+
+Thu Jul 4 12:01:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldver.c (ldversion): Set version to cygnus-2.7.1.
+
+ * Released binutils 2.7.
+
+ * emulparams/pc532macha.sh: Rename from pc532machaout.sh to avoid
+ System V file name limitations.
+ * configure.tgt (nc32k-pc532-mach*, ns32k-pc532-ux*): Use
+ pc532macha rather than pc532machaout.
+ * Makefile.in (ALL_EMULATIONS): Change epc532machaout.o to
+ epc532macha.o.
+ (epc532macha.c): Rename target from epc532machaout.c.
+
+Wed Jul 3 11:40:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (print_padding_statement): Use %u, not %x, to print
+ fill value.
+
+Sun Jun 30 11:16:43 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-eppcmac.c: Update to reflect May 23 change to aix.em.
+
+Thu Jun 27 14:03:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Put the .sa
+ file just before the .so file, rather than just after.
+
+ * configure.host: Use -print-file-name=FILE rather than piping
+ -print-libgcc-file-name through sed.
+ (i[345]86*-*-sco*, i[345]86-*-isc*): Create crtbegin.o and
+ crtend.o files, in case gcc doesn't use them.
+ * Makefile.in (mostlyclean): Remove crtbegin.o and crtend.o.
+
+Wed Jun 26 15:57:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (mips*-dec-osf*): New target.
+
+Tue Jun 25 22:15:29 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ (AC_PROG_INSTALL): Added.
+ * configure: Rebuilt.
+
+Mon Jun 24 18:48:16 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc (_GLOBAL_OFFSET_TABLE_): Don't do a
+ PROVIDE of _GLOBAL_OFFSET_TABLE_, since it needs to be at a
+ non-fixed location.
+
+Mon Jun 24 17:55:31 1996 Jouke Numan <jnuman@bazis.nl>
+
+ * ldlang.h (enum section_type): Define.
+ (lang_output_section_statement_type): Remove loadable field. Add
+ sectype field.
+ (lang_enter_output_section_statement): Change flags parameter in
+ prototype to sectype.
+ * ldgram.y (typebits): Remove.
+ (sectype): New static variable.
+ (opt_at): Use sectype rather than typebits.
+ (type): Set sectype rather than typebits.
+ (atype): Likewise.
+ * ldlex.l: Recognize DSECT, COPY, INFO, and OVERLAY in
+ EXPRESSION mode.
+ * ldlang.c (lang_output_section_statement_lookup): Set sectype
+ field rather than loadable field.
+ (wild_doit): Check sectype rather than loadable.
+ (lang_record_phdrs): Likewise.
+ (lang_enter_output_section_statement): Rename flags parameter to
+ sectype. Set sectype field rather than loadable field. Set flags
+ field based on sectype.
+
+Mon Jun 24 12:00:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elf.sc: Force .stab* and .comment sections to start
+ at 0.
+
+ * configure.in: On alpha*-*-osf*, link against libbfd.a if not
+ using shared libraries.
+ * configure: Rebuild with autoconf 2.10.
+
+Fri Jun 21 17:40:56 1996 Joel Sherrill <joel@merlin.gcs.redstone.army.mil>
+
+ * configure.tgt: Add support for *-*-rtems* configurations.
+
+Fri Jun 21 13:05:51 1996 Richard Henderson <rth@tamu.edu>
+
+ * configure.tgt (alpha-*-linuxecoff*): New target.
+ (alpha-*-linux*): Use elf64alpha.
+ * emulparams/elf64alpha.sh: New file.
+ * emultempl/elf32.em: If ELFSIZE is not set, set it to 32. Use
+ ${ELFSIZE} rather than 32 when calling BFD routines.
+ (hold_rodata): New static variable.
+ (gld${EMULATION_NAME}_place_orphan): Use hold_rodata for a
+ readonly section that is not code.
+ (gld${EMULATION_NAME}_place_section): Set hold_rodata. Don't use
+ a .rel section unless its bfd_section field is not NULL.
+ * Makefile.in (ALL_EMULATIONS): Add eelf64alpha.o.
+ (eelf64alpha.c): New target.
+
+Fri Jun 21 12:45:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmisc.c (vfinfo): Correct handling of 0 in %W case.
+
+Thu Jun 20 13:55:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Add enough support to understand the gcc svr3.ifile script:
+ * ldlex.l: Recognize BLOCK and GROUP in EXPRESSION context. Add
+ BIND keyword.
+ * ldgram.y: Add BIND token.
+ (section): Recognize GROUP.
+ (opt_ext_with_type): Recognize a couple of cases of BIND.
+ * ldlang.c (init_os): Don't do anything if section is already
+ initialized. Call exp_init_os on addr_tree field.
+ (exp_init_os): New static function.
+ (map_input_to_output_sections): Call exp_init_os on assignment
+ expression.
+ (lang_place_orphans): Check for common sections by name COMMON
+ rather than by common_section field. Don't warn about absence of
+ [COMMON] command.
+
+ * ldlang.h (lang_input_statement_type): Remove useless fields
+ common_section, common_output_section, and complained, as well as
+ all references to them.
+
+ * ldexp.c: Reindent a lot of code.
+ (exp_fold_tree): Call FAIL rather than einfo in default case.
+
+Wed Jun 19 11:40:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host (m88*-*-dgux*): Quote HOSTING_CRT0. From
+ <randall.hron@medaphis.com>.
+
+Tue Jun 18 15:53:09 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * scripttempl/h8300s.sc: New file for H8/S.
+ * emulpararms/h8300s.sh: New file for H8/S.
+ * Makefile.in (ALL_EMULATIONS): Add H8/S.
+ (e_h8300s.c): Add dependencies.
+ * configure.tgt: Add H8/S to targ_extra_emuls.
+
+Tue Jun 18 17:55:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (i[345]86*-*-isc*): New target. From
+ <uddeborg@carmen.se>.
+
+Wed Jun 12 12:46:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c: Include "libiberty.h".
+ (parse_args): Copy the -Y argument into memory.
+ (set_default_dirlist): Don't put the ':' back into the directory
+ list.
+
+Fri Jun 7 11:27:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em: Include libiberty.h.
+ (gld${EMULATION_NAME}_set_symbols): New static function to add
+ LD_LIBRARY_PATH to the list of search directories.
+ (ld_${EMULATION_NAME}_emulation): Add new set_symbols routine.
+
+Thu Jun 6 11:50:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emulparams/elf32bmip.sh (OTHER_GOT_SYMBOLS): Use ALIGN(16)
+ rather than . when computing _gp value. From Per Fogelstrom.
+ * emulparams/elf32lmip.sh (OTHER_GOT_SYMBOLS): Likewise.
+
+ * ldmain.c (main): Don't close and unlink the file on error, since
+ remove_output will do it anyhow.
+ * ldlang.c (open_output): Set boolean variable to true, not 1.
+
+Wed Jun 5 18:34:14 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * emulparams/{elf32b4300.sh,elf32l4300.sh} (SCRIPT_NAME): Use
+ elfmips instead of elf.
+
+Tue Jun 4 18:43:07 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldcref.c: New file.
+ * ld.h (add_cref, output_cref): Declare.
+ * ldmain.c (main): Initialize notice_all field. If it is set at
+ end of link, call output_cref.
+ (notice): Rename from notice_ysym. Check notice_all.
+ * ldmisc.c (finfo): Make globally visible.
+ * ldmisc.h (finfo): Declare.
+ * lexsup.c (OPTION_CREF): Define.
+ (ld_options): Add "cref".
+ (parse_args): Handle OPTION_CREF.
+ * Makefile.in: Rebuild dependencies.
+ (CFILES): Add ldcref.c.
+ (OFILES): Add ldcref.o.
+ * ld.texinfo, ld.1: Document --cref.
+
+Tue Jun 4 12:12:25 1996 Tom Tromey <tromey@csk3.cygnus.com>
+
+ * Makefile.in (install): Make $(tooldir) and $(tooldir)/bin.
+
+Fri May 31 12:40:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (sort_sections): Don't assume that a
+ wild_statement has a section name.
+
+Wed May 29 13:13:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/elfmips.sc: Quote test -z argument.
+
+ * ld.texinfo: Clarify the CONSTRUCTORS command.
+
+Thu May 23 16:07:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_read_file): Initialize
+ file, not impfile.
+
+Wed May 22 11:31:30 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * ldlang.c (wild_doit): Don't copy over SEC_LINK_{ONCE,DUPLICATES}
+ if final link.
+ * emultempl/pe.em (sfunc): Renamed to sort_by_file_name.
+ (sort_by_section_name, sort_sections_1): New functions.
+ (sort_sections): Only sort by file name sections in .idata.
+ Add "Grouped Sections" support.
+ (gld${EMULATION_NAME}_place_orphan): Rewrite to support Grouped
+ Sections.
+ (gld${EMULATION_NAME}_place_section): Delete.
+ * scripttempl/pe.sc (.text,.data,.rdata): Add *(.foo\$).
+ (.CRT,.rsrc): Rewrite to use Grouped Section support.
+
+Tue May 21 14:31:48 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-eppcmac.c: Update to reflect changes to aix.em.
+
+Sun May 19 16:59:44 1996 Doug Evans <dje@seba.cygnus.com>
+
+ * ldlang.c (dprint_statement): Stop printing at end of list.
+
+Sat May 18 13:12:05 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Support for --force-exe-suffix
+ * ld.h (args_type): Add force_exe_suffix.
+ * ld.texinfo: Add documentation.
+ * ldmain.c (main): Add support for option.
+ * lexsup.c (OPTION_FORCE_EXE_SUFFIX): New.
+ (ld_options, parse_args): Add support for option.
+
+Wed May 15 12:50:25 1996 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * emultempl/pe.em (set_pe_value): Pass 0 not 16 to strtoul call.
+
+Fri May 10 16:28:44 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc (__stack): Make __stack 0 if it was
+ referenced but not defined.
+
+Thu May 9 08:52:23 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * emulparams/{elf32bmip.sh,elf32lmip.sh,mipsidt.sh,mipsidtl.sh}:
+ Set a new variable to signify if the final target is an embedded
+ system.
+ * scripttempl/{mips.sc,elfmips.sc}: Don't add SIZEOF_HEADERS to
+ .text for an embedded system.
+
+Tue May 7 10:56:11 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/pe.em (gld${EMULATION_NAME}_place_orphan): New function.
+ (gld${EMULATION_NAME}_place_section): New function.
+ (hold_{section,use,text,rdata,data}): New static locals.
+ (ld_${EMULATION_NAME}_emulation): Update orphan field.
+ * scripttempl/pe.sc: Whitespace cleanup. Semicolon usage cleanup.
+ (INIT,FINI): Delete, unused.
+ (.text): Document orphan .text.foo sections.
+ (.rdata): Document orphan .rdata.foo sections.
+ (.data): Document orphan .data.foo sections.
+
+Tue May 7 11:35:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/h8300.sc: Place ".tiny" sections right
+ after ".data" sections.
+ * scripttempl/h8300h.sc: Place ".tiny" sections into
+ the "tiny" memory region, 0xff8000 through 0xffff00.
+
+ * scripttempl/h8300.sc: Set the entry point to the value of
+ "_start" rather than the start of the text segment.
+ * scripttempl/h8300h.sc: Likewise.
+
+ * scripttempl/h8300.sc: Place .rodata sections before .text
+ sections in main ram.
+ * scripttempl/h8300h.sc: Likewise.
+
+Mon May 6 23:32:30 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/h8300h.sc: Use "eight", not "eightbit" for the
+ 8-bit region and 8-bit sections.
+
+Wed May 1 17:50:06 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * ldlang.c (section_already_linked): Fix typos.
+
+Mon Apr 29 20:31:06 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/pe.sc (.endjunk): Define __end__.
+
+Mon Apr 29 17:05:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (longest_section_name): Remove.
+ (SECTION_NAME_MAP_LENGTH): Define.
+ (print_size, print_alignment, print_fill, print_section): Remove.
+ (print_flags): Remove.
+ (lang_map): Rewrite.
+ (print_output_section_statement): Rewrite.
+ (print_assignment): Rewrite.
+ (print_one_symbol): Rewrite.
+ (print_input_section): Rewrite.
+ (print_fill_statement): Rewrite.
+ (print_data_statement): Rewrite.
+ (print_address_statement): New static function.
+ (print_reloc_statement): Rewrite.
+ (print_padding_statement): Rewrite.
+ (print_wild_statement): Rewrite.
+ (print_statement_list): Clean up.
+ (print_statement): Clean up. Some minor output changes.
+ (print_statements): Clean up.
+ (load_symbols): Put another - before -whole-archive.
+ * ldexp.c (exp_print_tree): Change etree_value and etree_rel to
+ print 0x and to omit leading zeroes. For etree_rel, use %B to
+ print the BFD. For etree_assign, remove the space after the
+ destination name.
+ * ldwrite.c: Include "libiberty.h".
+ (clone_section): Call xstrdup, not strdup.
+ (ldwrite): Don't print any map information.
+ (print_symbol_table, print_file_stuff, print_symbol): Remove.
+ * ldmain.c (main): Call lang_map when appropriate.
+ * ldmisc.c (vfinfo): Add support for %W.
+ (print_address): Remove.
+ * ldmisc.h (print_address): Don't declare.
+ * Makefile.in: Rebuild dependencies.
+
+Mon Apr 29 10:29:07 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.host (m68*-*-linux*): Add -dynamic-linker to
+ HOSTING_CRT0. Search -lgcc both before and after -lc in
+ HOSTING_LIBS. Look for crt{begin,end}.o in the compiler directory
+ at first.
+ (i[345]86-*-linux*): Look for crt{begin,end}.o in the compiler
+ directory at first.
+
+Fri Apr 26 14:42:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmisc.h (demangle): Declare.
+ * ldmisc.c: Include "libiberty.h". Include demangle.h with "",
+ not <>.
+ (demangle): Make non-static. Remove remove_underscore paramter.
+ Always return an allocated string.
+ (vfinfo): Free result of demangle. Add case 'G'. Use %T to print
+ functionname, rather than calling demangle. Print a colon between
+ the BFD(section+offset) and the line number.
+ * ldmain.c (add_archive_element): Improve format of archive
+ information in map file.
+ (constructor_callback): Don't print anything to the map file.
+ * ldlang.c (lang_one_common): Improve format of common symbol
+ information in map file.
+ * ldctor.c (ldctor_build_sets): If producing a map file, print set
+ information.
+ * ldwrite.c (print_symbol_table): Print a newline before the
+ header in the map file.
+ * Makefile.in: Rebuild dependencies.
+
+ * ldmisc.c (vfinfo): Reindent.
+
+Mon Apr 22 12:07:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_size_sections): If _cooked_size is not 0, then
+ don't clobber it when not relaxing.
+
+ * ld.h (ld_config_type): Remove traditional_format field.
+ * ldmain.c (main): Use link_info.traditional_format rather than
+ config.traditional_format.
+ * ldlang.c (ldlang_open_output): Likewise.
+ * lexsup.c (parse_args): Likewise.
+ * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Likewise.
+ * mpw-eppcmac.c (gldppcmacos_parse_args): Likewise.
+
+ * ldlang.c (wild_doit): Discard debugging sections if we are
+ stripping debugging information.
+
+ * emulparams/z8002.sh (ARCH): Set to z8002, not z8k.
+
+Tue Apr 16 16:38:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldexp.c (fold_binary): Correct handling of subtraction with
+ absolute values.
+ (fold_name): Permit symbols in lang_allocating_phase_enum.
+
+ * scripttempl/aout.sc: Only PROVIDE __stack when RELOCATING. Undo
+ accidental changes in last patch.
+
+Tue Apr 16 10:25:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.tgt (powerpc*-*-{sysv,linux}): Add aliases.
+ (powerpcle*-*-{sysv,solaris}): Ditto.
+
+Mon Apr 15 14:50:56 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * scripttempl/aout.sc: Add PROVIDE (__stack = 0) so I can use it
+ in m68k/crt0.S without things blowing up.
+
+Fri Apr 12 16:40:56 1996 Rob Savoye <rob@chinadoll.cygnus.com>
+
+ * scripttempl/m68kcoff.sc: Remove default address for .data so
+ .text, .data, and .bss are all sequential.
+
+Thu Apr 11 12:05:35 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/m68kcoff.sc: Remove regions and simplify.
+
+Wed Apr 10 14:41:53 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/h8300.sc: Add the "8-bit area" in the upper 256
+ bytes of the address space. Put data from the ".eight" sections
+ into the 8-bit area.
+ * scripttempl/h8300h.sc: Likewise.
+
+Tue Apr 9 14:10:42 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * emultempl/generic.em (gld${EMULATION_NAME}_before_parse):
+ Pass $ARCH to ldfile_set_output_arch instead of setting
+ ldfile_output_architecture directly.
+
+Tue Apr 9 14:22:15 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc (.init,.fini): Put .init, .fini section
+ next to .text. Put _etext after .text, .init, .fini, and
+ .rodata{,2} sections.
+
+Tue Apr 9 12:18:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo: Rearrange option documentation.
+
+ * lexsup.c (ld_options): New static array.
+ (parse_args): Build shortopts and longopts from ld_options array.
+ (help): New static function.
+ * ldver.h (help): Don't declare.
+ * ldver.c (ldversion): Reindent.
+ (help): Remove.
+
+ * ld.texinfo, ld.1: Mention -E as a synonym for -export-dynamic.
+
+Mon Apr 8 11:56:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em: When checking for a native emulation, check
+ that the current emulation is the default emulation.
+ * emultempl/sunos.em: Likewise.
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories.
+ * configure: Rebuild.
+
+ * lexsup.c (parse_args): Add -E as a synonym for -export-dynamic,
+ for HP/UX compatibility.
+
+Fri Apr 5 14:30:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_check_ld_so_conf): New
+ static function, if ${host} = ${target}.
+ (gld${EMULATION_NAME}_after_open): Call check_ld_so_conf to find a
+ needed shared library if ${host} = $[target}.
+
+ * configure.host (i[345]86-*-linux*): Add -dynamic-linker to
+ HOSTING_CRT0. Search -lgcc both before and after -lc in
+ HOSTING_LIBS.
+
+ * configure.tgt: Add i[345]86-*-freebsdelf* target; from John
+ Polstra <jdp@polstra.com>.
+
+Fri Apr 5 18:11:25 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * emulparams/elf32{b,l}4300.sh (MACHINE): Add explicit
+ architecture number.
+ * scripttempl/elf.sc: Use $MACHINE definition if present.
+ * configure.tgt (targ_extra_emuls): Force 4100 build to use same
+ template as 4300.
+
+Mon Apr 1 17:35:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_size_sections): Change region check to handle
+ regions which end at the highest possible address correctly.
+ From Roland Weber <roweber@ira.uka.de>.
+
+ * ldlang.c (section_already_linked): New static function.
+ (wild_doit): Discard sections with SEC_EXCLUDE set if not doing a
+ relocateable link. Don't worry about section being NULL, since it
+ never should be. Don't call init_os unless the section is going
+ to be added.
+ (ldlang_add_file): Call section_already_linked for each section.
+ * ldmain.c (multiple_definition): Don't warn about multiple
+ definitions in sections which are being discarded.
+
+Sun Mar 31 00:30:47 1996 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttempl/{ppcpe.sc, pe.sc} (.junk): Remove and use /DISCARD/.
+ * emultempl/pe.em (init): Remove special case PPC code.
+
+Fri Mar 29 00:01:29 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/h8300.sc: Make vectors section 0xc4 bytes long
+ so as not to overwrite the magic syscall entry at 0xc4.
+ * scripttempl/h8300h.sc: Likewise.
+
+Thu Mar 28 11:05:47 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.tgt (sparc64-*-solaris2*): Delete.
+ Stick with sparc-*-solaris2*.
+
+Wed Mar 27 12:33:24 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (DISCARD_SECTION_NAME): Define to "/DISCARD/".
+ * ldlang.c (init_os): Fail on an attempt to initialize any section
+ named DISCARD_SECTION_NAME.
+ (wild_doit): Discard input sections assigned to an output section
+ named DISCARD_SECTION_NAME.
+ * ld.texinfo: Document use of /DISCARD/.
+
+ * ldlang.c: Fix some indentation and comments.
+
+Tue Mar 26 18:14:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): Call bfd_set_error_program_name.
+
+Thu Mar 21 13:17:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo: Fix a couple of indexing entries. Mention that
+ --verbose displays builtin linker scripts.
+
+ * ldmisc.c (vfinfo): case 'I': If the file is not in an archive,
+ and the local symbol name does not match the filename, print the
+ filename as well.
+
+ Patches from John Polstra <jdp@polstra.com> for FreeBSD ELF:
+ * lexsup.c (parse_args): -Bshareable is a synonym for -shared.
+ * emulparams/elf_i386.sh (NONPAGED_TEXT_START_ADDR): Make the same
+ as TEXT_START_ADDR.
+
+Wed Mar 20 18:18:25 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ld.texinfo: Fix typos. Use @pxref only inside parentheses.
+
+Wed Mar 20 16:56:15 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (add_wrap): New function.
+ * ldmain.h (add_wrap): Declare.
+ * lexsup.c (parse_args): Call add_wrap.
+
+Tue Mar 19 16:44:20 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.host (sparc*-*-solaris2* host): Accept any sparc variant.
+
+Wed Mar 13 17:47:31 1996 Jeffrey A Law (law@cygnus.com)
+
+ * scripttempl/h8300.sc: Change name of page zero memory
+ from "null" to "vectors". Create an output section for
+ vectors. Add comments on how to explicitly place items
+ in the vector table.
+ * scripttempl/h8300h.sc: Likewise.
+
+Wed Mar 13 12:40:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/lnk960.em (machine_table): Add jx and hx.
+
+ * genscripts.sh: Don't use ${9:-xx}, since Ultrix /bin/sh doesn't
+ support it.
+
+Tue Mar 12 12:43:59 1996 David Mosberger-Tang <davidm@koala.azstarnet.com>
+
+ * ld.h (ld_config_type): Add warn_multiple_gp field.
+ * lexsup.c (parse_args): Handle --warn-multiple-gp.
+ * ldmain.c (warning_callback): Suppress multiple gp values warning
+ if --warn_multiple_gp was not used.
+ * ld.texinfo, ld.1: Document --warn-multiple-gp.
+
+Tue Mar 12 12:02:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (parse_args): Handle --wrap.
+ * ldmain.c (main): Initialize link_info.wrap_hash.
+ * ldexp.c (fold_name): Use bfd_wrapped_link_hash_lookup in DEFINED
+ and NAME cases.
+ * ld.texinfo, ld.1: Document --wrap.
+
+ * configure: Rebuild with autoconf 2.8.
+
+ Don't do SunOS style dynamic linking for sparc-aout:
+ * configure.tgt (sparc64-*-aout*): Use sparcaout, not sun4.
+ (sparclite*-fujitsu-*, sparc*-*-aout): Likewise.
+ (sparc*-wrs-vxworks*): Likewise.
+ * emulparams/sparcaout.sh: New file.
+ * Makefile.in (ALL_EMULATIONS): Add esparcaout.o.
+ (esparcaout.c): New target.
+
+Wed Mar 6 16:06:52 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * scripttempl/elfppc.sc (.sdata2, .sbss2): Implement Feb 2 change
+ in a different manner to work around differences in shell variable
+ expansion.
+
+Wed Mar 6 18:08:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldemul.h (ldemul_unrecognized_file): Declare.
+ (ldemulation_xfer_type): Add unrecognized_file field.
+ * ldemul.c (ldemul_unrecognized_file): New function.
+ * ldlang.c (load_symbols): If a file can not be recognized, call
+ ldemul_unrecognized_file before trying it as a linker script.
+ * aix.em (gld${EMULATION_NAME}_unrecognized_file): New static
+ function.
+ (gld${EMULATION_NAME}_read_file): Use FOPEN_RT, not "r".
+ (ld_${EMULATION_NAME}_emulation): Initialize unrecognized_file.
+
+Mon Mar 4 14:11:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (wild): Handle foo.a(.text) by mapping each included
+ member of foo.a separately. From Jouke Numan <jnuman@bazis.nl>.
+
+Fri Mar 1 10:24:59 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_find_exp_assignment):
+ Search trinary.cond rather than searching trinary.lhs twice.
+
+Tue Feb 27 15:08:43 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit out shared library support.
+ (@TDIRS@): Edit out, can't use genscripts.
+
+Tue Feb 27 15:09:21 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.tgt (m68k-*-linuxaout*, m68k-*-linux*): New targets.
+ * emulparams/m68klinux.sh: New file.
+ * emultempl/linux.em (gld${EMULATION_NAME}_before_allocation):
+ Call bfd_${EMULATION_NAME}_size_dynamic_sections instead of
+ bfd_linux_size_dynamic_sections.
+ * Makefile.in (ALL_EMULATIONS): Add em68klinux.o.
+ (em68klinux.c): New target.
+ * configure.host (m68*-*-linuxaout*, m68*-*-linux*): New hosts.
+
+Tue Feb 27 12:55:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALL_EMULATIONS): Sort into alphabetical order.
+ Fill in missing entries.
+
+ * lexsup.c (parse_args): Recognize --no-whole-archive.
+ * ldlang.h (lang_input_statement_type): Add whole_archive field.
+ * ldlang.c (new_afile): Set whole_archive field.
+ (load_symbols): Check input file specific whole_archive field
+ rather than global variable.
+ * ld.texinfo, ld.1: Document --no-whole-archive.
+
+Tue Feb 20 16:07:00 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt: Correct gldi960 to gld960.
+
+Mon Feb 19 11:16:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Check
+ the SONAME if it is available.
+ (gld${EMULATION_NAME}_stat_needed): Use the SONAME, not the
+ filename, when checking for conflicting library versions. Don't
+ assume that the suffix is only numbers and dots.
+
+ * ld.texinfo: Mention that -R can be used for -rpath.
+
+Sun Feb 18 15:05:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Check for 'do not mix' from native linker before
+ trying to use -rpath.
+
+Thu Feb 15 13:58:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Remove explicit substitution of CFLAGS; autoconf
+ does it anyhow.
+ * configure: Rebuild.
+ * Makefile.in (LDFLAGS): Set to @LDFLAGS@.
+
+ * configure.in: Call AC_PROG_CC before configure.host.
+ * configure: Rebuild.
+ * configure.host: Remove go32 host, since it should no longer be
+ necessary. Don't set CC for romp host.
+
+ * scripttempl/elf.sc: Don't skip a page in virtual memory space if
+ the text segment ends exactly on a page boundary.
+
+ * configure.in: Substitute RPATH_ENVVAR.
+ * configure: Rebuild.
+ * configure.host: Set RPATH_ENVVAR.
+ * Makefile.in (RPATH_ENVVAR): New variable.
+ (check): Use $(RPATH_ENVVAR) rather than LD_LIBRARY_PATH.
+
+Wed Feb 14 18:49:01 1996 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * configure.in: Redo emulation handling so that each emulation
+ searches the correct tool directory, based on the target alias.
+ For example, "configure --enable-targets=m68k-coff i386-linux"
+ will search /usr/local/i386-linux/lib for linux and
+ /usr/local/m68k-coff/lib for m68k-coff.
+ * configure: Rebuild.
+ * configure.tgt: Add special tdir settings for Linux.
+ * Makefile.in: Add @TDIRS@. Pass "$(tdir_EMUL)" to ${GENSCRIPTS}
+ for each eEMUL.c target.
+ * genscripts.sh: Accept specific alias as 9th argument, and use it
+ in LIB_PATH.
+
+Wed Feb 14 16:38:36 1996 Martin Anantharaman <martin@mail.imech.uni-duisburg.de>
+
+ * ldlang.c (lang_set_startof): Don't do anything for a
+ relocateable link.
+
+ * ldgram.y (mri_script_file): Call mri_draw_tree.
+ * mri.c (mri_draw_tree): Make globally visible. Don't bother to
+ create memory regions.
+ (mri_load): Don't call mri_draw_tree.
+ * mri.h (mri_draw_tree): Declare.
+
+ * configure.tgt (m68*-*-psos): New target.
+ * emulparams/m68kpsos.sh: New file.
+ * scripttempl/psos.sc: New file.
+ * Makefile.in (ALL_EMULATIONS): Add em68kpsos.o.
+ (em68kpsos.c): New target.
+
+Wed Feb 14 11:09:25 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.tgt (*-*-ieee*): New target; use vanilla.
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Strip
+ `:foo' from ${ARCH}.
+
+Tue Feb 13 15:58:58 1996 Bryan Ford <baford@snake.cs.utah.edu>
+
+ * scripttempl/i386msdos.sc: Don't pad the .text section. Put
+ .rodata in .data.
+
+Tue Feb 13 14:04:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Set HDLFLAGS for *-*-hpux with --enable-shared.
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_stat_needed): Warn if
+ it looks like we might be linking in two different versions of the
+ same shared library. Based on a patch from H J Lu <hjl@zoom.com>.
+
+Thu Feb 8 19:25:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_size_sections): Increment the section size when a
+ padding statement is encountered.
+
+Wed Feb 7 14:01:33 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Look for --enable-shared. Change the value of
+ BFDLIB when linking against a shared library on SunOS.
+ * configure: Rebuild.
+ * configure.host: If using a shared BFD library, try to pass a
+ reasonable -rpath option when linking.
+ * Makefile.in (BFDLIB): Set to @BFDLIB@.
+
+Tue Feb 6 12:29:14 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * emulparams/elf64_sparc.sh (ARCH): Change to `sparc:v9'.
+ * emultempl/generic.em: Strip `:foo' from ${ARCH}.
+
+Mon Feb 5 16:25:30 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Support for building bfd and opcodes as shared libraries, based on
+ patches from Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in (HLDFLAGS): New substitution.
+ * configure: Rebuild.
+ * configure.host: Set HLDFLAGS on SunOS.
+ * Makefile.in (HLDFLAGS): New variable.
+ (BFDDEP): New variable.
+ (BFDLIB): Change to -L../bfd -lbfd.
+ ($(LD_PROG)): Depend upon $(BFDDEP) rathern than $(BFDLIB). Use
+ $(HLDFLAGS) in link.
+ (check): Set LD_LIBRARY_PATH in the environment.
+
+Fri Feb 2 19:26:25 1996 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * scripttempl/elfppc.sc (.sdata2, .sbss2): Put .sdata2 and .sbss
+ in the read-only section, not read/write unless we are making a
+ shared library.
+ (.debug*): Add dwarf debug sections.
+ (.rela.{sdata*,sbss*}): Add sections.
+
+Fri Feb 2 16:50:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Regenerate.
+
+Thu Feb 1 10:50:46 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emulparams/elf_i386.sh (TEXT_START_ADDR): Change to 0x8048000,
+ for SVR4 compatibility.
+
+ * ldexp.c (exp_fold_tree): Correct handling of ABSOLUTE.
+
+Wed Jan 31 17:30:19 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.tgt (i[345]86-*-cygwin32, powerpcle-*-cygwin32): New.
+ * emultempl/pe.em (definfo init): Make the default stack reserve
+ of a PPC larger.
+
+Wed Jan 31 14:34:23 1996 Richard Henderson <rth@tamu.edu>
+
+ * configure.tgt (m68*-apple-aux*): New target.
+ * emulparams/m68kaux.sh: New file.
+ * scripttempl/m68kaux.sc: New file.
+ * Makefile.in (ALL_EMULATIONS): Add em68kaux.o.
+ (em68kaux.c): New target.
+
+Tue Jan 30 13:18:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Ignore
+ -bnoentry, since the right thing tends to happen anyhow.
+
+Mon Jan 29 12:29:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo, ld.1: Document -export-dynamic.
+
+Fri Jan 26 11:11:55 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * emultempl/sunos.em: Check for native compile by comparing
+ ${target} and ${host}.
+
+Thu Jan 25 16:46:58 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * emulparams/{elf32b4300.sh, elf32l4300.sh}: Changed
+ TEXT_START_ADDR to allow use on IDT and PMON systems.
+
+Wed Jan 24 20:59:40 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args):
+ correct spelling.
+
+Wed Jan 24 16:59:19 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * configure.tgt (sparc64-*-solaris2*): New configuration.
+ (sparc64-*-aout*): Renamed from sparc64*.
+
+Mon Jan 22 13:01:35 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Makefile.in (GENSCRIPTS): Pass @host@ @target@ @target_alias@.
+ * genscripts.sh: Set host, target and target_alias variables.
+ Check for native compile by comparing ${target} and ${host}.
+ * emultempl/elf32.em: Likewise.
+ * scripttempl/elfmips.sc: Test ${target}, not ${target_alias}.
+
+Mon Jan 22 11:03:23 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc: Refine eabi support to better support
+ .sdata, .sdata2, .sbss, etc. sections.
+
+Tue Jan 16 15:16:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y (%union): Add phdr field.
+ (phdr): Use phdr_qualifiers rather than opt_hdrs and opt_at.
+ (phdr_qualifiers): New nonterminal. Add support for FLAGS.
+ (opt_hdrs, hdr): Remove.
+ (phdr_val): New nonterminal.
+ * ldlang.c (lang_new_phdr): Replace hdrs parameter with filehdr
+ and phdrs parameters. Add flags parameter.
+ (lang_record_phdrs): Update for changes to lang_phdr. Pass flags
+ to bfd_record_phdr.
+ * ldlang.h (struct lang_phdr): Replace hdrs field with filehdr and
+ phdrs fields. Add flags field.
+ (LANG_PHDR_FILEHDR, LANG_PHDR_PHDRS): Remove.
+ (lang_new_phdr): Update declaration.
+ * ld.texinfo: Document FLAGS.
+
+Mon Jan 15 15:07:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation):
+ Don't make a shared library because of an undefined reference to
+ __GLOBAL_OFFSET_TABLE_.
+
+ Add some Irix 5 support, mostly from Kazumoto Kojima
+ <kkojima@info.kanagawa-u.ac.jp>:
+ * emulparams/elf32bmip.sh (SCRIPT_NAME): Change to elfmips.
+ (SHLIB_TEXT_START_ADDR): Define.
+ (OTHER_GOT_SYMBOLS): Define.
+ (OTHER_READWRITE_SECTIONS): Remove initialization of _gp.
+ (EXECUTABLE_SYMBOLS): Don't define.
+ (DYNAMIC_LINK): Don't define.
+ * emulparams/elf32lmip.sh: Same changes as elf32bmip.sh.
+ * scripttempl/elfmips.sc: New file.
+ * configure.host (mips*-dec-bsd*): Change mips to mips*.
+ (mips*-sgi-irix4*): Likewise.
+ (mips*-sgi-irix5*): New entry.
+ * Makefile.in (eelf32bmip.c): Depend upon elfmips.sc rather than
+ elf.sc.
+ (eelf32lmip.c): Likewise.
+
+Sat Jan 13 09:41:43 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc: Remove support for .rel.* sections. Add
+ .rela.got.neg section.
+
+Fri Jan 12 14:56:19 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/sh.sc: Only build constructors when CONSTRUCTING.
+
+ * ldmisc.c: Include <stdarg.h> rather than <varargs.h> if
+ ANSI_PROTOTYPES is defined. Remove special handling of
+ WINDOWS_NT. Various indendation fixes.
+ (vfinfo): Change fmt parameter to const char *.
+ (info_msg): Write <stdarg.h> version.
+ (einfo, minfo, finfo): Likewise.
+ (info_assert): Change file parameter to const char *.
+ * ldmisc.h (einfo, minfo, info_msg): If ANSI_PROTOTYPES is
+ defined, use a real prototype.
+ (info_assert): Change first parameter to be const char *.
+
+Fri Jan 12 13:29:55 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc: Add support for .sdata2/.sbss2, etc. Add
+ in old support that 2.7.2 needs, but the current compiler does
+ not.
+
+ * Makefile.in (eelf32{,l}ppc.c): Fix up dependencies to use the
+ correct Linker script template.
+
+ * emulparams/elf32{,l}ppc.sh (TEXT_START_ADDR): Set to 0x40000,
+ not 0x400000.
+ (DATA_ADDR,NONPAGED_TEXT_START_ADDR): Delete.
+
+Tue Jan 9 15:53:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/alpha.sc: Put .rconst right after .rdata.
+
+Fri Jan 5 14:07:45 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation):
+ sort using right pointer.
+
+Fri Jan 5 12:25:47 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc: Remove support for creating special
+ labels for eabi section begin/end here. The compiler now uses
+ crt{i,n}.o to create these symbols.
+
+Thu Jan 4 17:08:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.host: Change existing Linux HOSTING_CRT0 to be used
+ for a.out only, and put in appropriate HOSTING_CRT0 and
+ HOSTING_LIBS values for Linux ELF.
+
+Thu Jan 4 12:02:05 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/h8300.sc: Use all 64K for ram.
+ * scripttempl/h8300h.sc: Define 256K ram size.
+
+Thu Dec 21 15:57:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_before_allocation): Pass
+ export_defines as true to bfd_xcoff_size_dynamic_sections if -unix
+ was used, regardless of whether -bE was used.
+
+Tue Dec 19 17:35:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_after_open): Only set
+ relocateable before calling ldctor_build_sets if the output file
+ is in an XCOFF format.
+
+Fri Dec 15 16:34:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldwrite.c (build_link_order): When handling a data statement, if
+ the endianness of the output file is unknown, use the endianness
+ of the input file.
+
+Tue Dec 12 13:55:41 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Recognize mips-*-* as equivalent to
+ mips-idt-ecoff.
+ * mpw-eppcmacos.c: Rename to shorter mpw-eppcmac.c.
+ * mpw-ld.r: Add version resources.
+ (cfrg): Use symbolic instead of literal name for executable.
+
+Mon Dec 11 15:13:41 1995 Kim Knuttila <krk@cygnus.com>
+
+ * scripttempl/ppcpe.sc (FINI): Moved the .reloc section.
+
+Wed Dec 6 14:33:50 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * ldlang.c (print_statement{,s}): Delete duplicate prototype.
+ (print_statement_list): Renamed from print_statement. All callers
+ updated.
+ (print_statement): New function to print just one statement.
+ (print_{data,reloc,padding}_statement): Don't crash if
+ output_section == NULL.
+ (dprint_statement): New function.
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): Fix
+ call to sort_sections.
+
+Wed Dec 6 14:59:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (unix_ld): New static variable.
+ (gld${EMULATION_NAME}_parse_args): Handle -unix.
+ (gld${EMULATION_NAME}_before_allocation): If unix_ld, pass
+ gc as false and export_defineds as true to size_dynamic_sections.
+
+ * ldexp.c (exp_fold_tree): Permit assignments to dot in the final
+ phase if the current section is abs_output_section.
+
+
+Tue Dec 5 09:49:39 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_before_allocation): Fix call
+ to sort_sections.
+
+Fri Dec 1 16:48:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y (PHDRS): New token.
+ (ifile_p1): Accept phdrs.
+ (section): Accept phdr_opt at the end of the section definition.
+ (phdr_op): New nonterminal.
+ (phdrs, phdr_list, phdr, phdr_type, opt_hdrs, hdr): Likewise.
+ * ldlex.l: Accept PHDRS.
+ * ldlang.h (struct lang_output_section_phdr_list): Define.
+ (lang_output_section_statement_type): Add phdrs field.
+ (struct lang_phdr): Define.
+ (LANG_PHDR_FILEHDR, LANG_PHDR_PHDRS): Define.
+ (lang_new_phdr): Declare.
+ * ldlang.c (lang_phdr_list): New static variable.
+ (lang_output_section_statement_lookup): Initialize phdrs field.
+ (lang_process): Call lang_record_phdrs.
+ (lang_new_phdr): New function.
+ (lang_section_in_phdr): New function.
+ (lang_record_phdrs): New static function.
+ * ld.texinfo: Document PHDRS.
+
+Thu Nov 30 13:14:30 1995 Kim Knuttila <krk@cygnus.com>
+
+ * scripttempl/ppcpe.sc: Moved .edata into its own section to
+ expose it.
+
+Thu Nov 30 11:32:34 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * configure.host (m68*-motorola-sysv): Define HOSTING_CRT0 and
+ HOSTING_LIBS for testing.
+ (m88*-motorola-sysv3): Define HOSTING_CRT0 and HOSTING_LIBS for
+ testing.
+
+Tue Nov 28 12:14:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (parse_args): Set config.dynamic_link to false for -N
+ and -n.
+
+Mon Nov 27 13:12:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.7.
+
+Fri Nov 24 18:35:35 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/pe.sc: Two .junk's is too much junk.
+
+Tue Nov 21 16:14:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use BFD_NEED_DECLARATION.
+ * acconfig.h: Put NEED_DECLARATION_FREE in @TOP@ section.
+ * configure, config.in: Rebuild with autoconf 2.6.
+
+ * ldmain.c (constructor_callback): Don't warn about BFD_RELOC_CTOR
+ being unsupported if this is not a relocateable link and the input
+ BFD supports it, since ldctor_build_sets can cope with that case.
+
+Fri Nov 17 16:23:15 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * configure.tgt (powerpc-*-macos*): New target.
+ * emulparams/ppcmacos.sh: New file, PowerMac emulation.
+ * Makefile.in (ALL_EMULATIONS): Add eppcmacos.o.
+ (eppcmacos.c): New target.
+ * mpw-eppcmacos.c: Update.
+ * mpw-make.sed: Edit out attempts to use {GENSCRIPTS}.
+
+Fri Nov 17 10:37:27 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): Use @host@ and @target@, not
+ $(host_canonical) and $(target_canonical).
+ (CXX_FOR_TARGET): Likewise.
+
+Thu Nov 16 11:23:42 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/pe.sc (.endjunk): Move definition of `end' to here
+ so the malloc heap begins at a sane place.
+
+Thu Nov 16 03:09:32 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Version 2.6 released.
+ * ldver.c (ldversion): Update to 2.6.
+
+ * Makefile.in (mostlyclean): Delete ldemul-list.h here, but not
+ $(GENERATED_*FILES), since they need to be retained by distclean.
+ (maintainer-clean, realclean): Delete them here.
+
+Tue Nov 14 17:08:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args): Open the
+ base file with FOPEN_WB, not "w".
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Use the
+ environment variable LD_RUN_PATH if neither -rpath nor -rpath-link
+ were used.
+ (gld${EMULATION_NAME}_before_allocation): Use the environment
+ variable LD_RUN_PATH if -rpath was not used.
+ * ld.texinfo, ld.1: Document LD_RUN_PATH.
+
+Thu Nov 9 13:09:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Recognize
+ -bl and -bloadmap options.
+
+ * ldfile.c (ldfile_try_open_bfd): If bfd_error_invalid_target,
+ report a better error.
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_before_allocation): Add
+ new local variable special_sections, and pass it to
+ size_dynamic_sections. Look through the results, and move the
+ sections around in the mapping so that they are defined correctly.
+
+Wed Nov 8 11:40:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldemul.c (ldemul_default_target): Cast getenv return value.
+
+Tue Nov 7 11:15:36 1995 Kim Knuttila <krk@cygnus.com>
+
+ * emulparams/ppcpe.sh (ARCH): New file for PowerPC Portable
+ Executable support.
+ * scripttempl/ppcpe.sc: New file for PowerPC Portable Executable
+ support.
+
+ * configure.tgt (targ_extra_emuls): Added powerpcle-pe target.
+ * Makefile.in (ALL_EMULATIONS): Added eppcpe.o target.
+
+ * emultempl/pe.em (TARGET_IS_ppcpe): file tailoring macro
+ (gld_$_before_allocation): added hooks for toc construction based
+ on the above macro.
+
+Tue Nov 7 11:47:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.texinfo: The linker does not use _main as an entry point.
+
+Tue Nov 7 11:46:11 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * scripttempl/m88kbcs.sc (.data): Calculate next boundary modulo
+ 0x2000 not 0x200.
+
+Mon Nov 6 10:59:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add test for whether free must be declared.
+ * sysdep.h: Declare free if necessary. Include "ansidecl.h".
+ * acconfig.h: Explain NEED_DECLARATION_FREE.
+ * configure, config.in: Rebuild.
+
+ * lexsup.c (parse_args): Take B:: out of shortopts.
+
+Sun Nov 5 03:08:28 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * emulparams/i386nbsd.sh (EXECUTABLE_SYMBOLS): Set __DYNAMIC to 0
+ for now, as with m68k4kbsd, until shared library support gets
+ done.
+
+ * configure.host: For i386 BSD variants, crt0.o lives in
+ /usr/lib. (True for NetBSD at least, unconfirmed for others.)
+
+Wed Nov 1 15:42:45 1995 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * Makefile.in (ALL_EMULATIONS): Add edelta68.o.
+ (edelta68.c): New target.
+ * configure.tgt (m68*-motorola-sysv*): New target.
+ * emulparams/delta68.sh: New file.
+ * scripttempl/delta68.sc: New file.
+
+ * scripttempl/m88kbcs.sc: Handle .init and .fini. Change section
+ addresses.
+
+Wed Nov 1 11:41:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y (mri_script_command): Accept ',' as well as '=' in
+ ALIGN and ALIGNMOD statements.
+
+ * emultempl/aix.em: Include ldgram.h.
+ (gld${EMULATION_NAME}_parse_args): Handle -pD and -pT, as used on
+ AIX 4.1.
+ * Makefile.in ($(EMULATION_OFILES)): Depend upon ldgram.h.
+
+Tue Oct 31 18:22:24 1995 David Mosberger-Tang <davidm@azstarnet.com>
+
+ * configure.host (alpha-*-linux*): New host.
+ * configure.tgt (alpha-*-linux*): New target.
+
+Tue Oct 31 12:36:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (export_files): Remove.
+ (import_files): Make static.
+ (struct export_symbol_list): Define.
+ (export_symbols): New static variable.
+ (gld${EMULATION_NAME}_parse_args): Handle an initial -b option
+ correctly. Call read_file for an export file.
+ (gld${EMULATION_NAME}_before_allocation): Call
+ bfd_xcoff_export_symbol for each export symbol, rather than
+ calling read_file for each export file.
+ (gld${EMULATION_NAME}_read_file): For an export file, make the
+ exported symbols undefined, and store them on the export_symbols
+ list.
+
+Sat Oct 28 00:10:03 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args):
+ Don't hang if last option is unrecognised.
+ (gld_${EMULATION_NAME}_set_symbols): Insert created
+ symbols into ABS output section.
+
+Fri Oct 27 18:03:17 1995 Niklas Hallqvist <niklas@appli.se>
+
+ * Makefile.in (ALL_EMULATIONS): Added support for the NetBSD
+ m68k4k arch.
+ (em68k4knbsd.c): New rule.
+
+ * configure.tgt: Added support for the NetBSD m68k4k arch.
+
+ * genscripts.sh, ldint.texinfo,
+ emulparams/{a29k,armaoutb,armaoutl,coff_sparc,ebmon29k,gld960,
+ gld960coff,go32,h8300,h8300h,h8500,h8500b,h8500c,h8500m,h8500s,
+ hp300bsd,hp3hpux,hppaelf.sh,i386aout,i386bsd,i386coff,i386go32,
+ i386linux,i386lynx,i386nbsd,lnk960,m68kaout,m68kcoff,m68klynx,
+ m88kbcs,mipsbig,mipsbsd,mipsidt,mipsidtl,mipslit,news,ns32knbsd,
+ pc532machaout,riscix,sa29200,sh,shl,sparclynx,sparcnbsd,
+ st2000,sun3,sun4,vanilla,vax,vsta,w65,z8001,z8002}.sh: Changed
+ PAGE_SIZE to TARGET_PAGE_SIZE.
+
+ * emulparams/m68knbsd.h: Ditto.
+ (TEXT_START_ADDR, NONPAGED_TEXT_START_ADDR): We have 8K pagesize.
+ (EXECUTABLE_SYMBOLS): Hardcode __DYNAMIC to zero for the time
+ being.
+
+ * emulparams/m68k4knbsd.sh: New file.
+
+ * scripttempl/aout.sc: Expand EXECUTABLE_SYMBOLS if relocating.
+
+Fri Oct 27 17:59:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em: Include ldctor.h.
+ (gld${EMULATION_NAME}_after_open): New static function.
+ (gld${EMULATION_NAME}_before_allocation): Call find_relocs.
+ (gld${EMULATION_NAME}_find_relocs): New static function.
+ (gld${EMULATION_NAME}_find_exp_assignment): New static function.
+ (ld_${EMULATION_NAME}_emulation): Use new after_open function.
+ * scripttempl/aix.sc: Use CONSTRUCTORS in .data.
+ * ldctor.c (struct set_info): Move definition into ldctor.h.
+ (struct set_element): Likewise.
+ (sets): Make non-static.
+ (ldctor_add_set_entry): Add name parameter. Save it in the new
+ set element.
+ (ldctor_build_sets): Avoid being called twice. Pass set element
+ name to lang_add_reloc.
+ * ldctor.h (struct set_info): Move definition here from ldctor.c.
+ (struct set_element): Likewise. Add new field name.
+ (sets): Declare.
+ (ldctor_add_set_entry): Declare new name parameter.
+ * ldwrite.c (build_link_order): Don't insist that either name or
+ section be NULL in a lang_reloc_statement.
+ * ldmain.c (add_to_set): Pass NULL to ldctor_add_new_set_entry for
+ new name parameter.
+ (constructor_callback): Pass name to ldctor_add_new_set_entry for
+ new name parameter.
+
+ * ldmisc.c (demangle): Fix indentation. Remove a leading period.
+
+Thu Oct 26 22:22:49 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add PowerMac target support, generate config.h.
+ * mac-ld.r: New file, Mac resources.
+ * mpw-make.sed: New file, edits Makefile.in into MPW syntax.
+ * mpw-make.in: Remove.
+ * mpw-eppcmacos.c: Prebuilt version of PowerMac linking script.
+
+Thu Oct 26 14:11:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em (gld${EMULATION_NAME}_parse_args): Treat
+ -static as a synonym for -bnso.
+
+ * scripttempl/aix.sc: Move special symbols inside sections.
+ Always start .data at 0.
+
+Wed Oct 25 11:52:12 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (diststuff): Also make info.
+ (maintainer-clean realclean): Also delete *.info*.
+
+Wed Oct 25 11:27:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/aix.em: Add support for various AIX linker options,
+ for AIX import and export files, and for AIX shared objects.
+ * scripttempl/aix.sc: Add .pad. Put .ds just before the TOC.
+
+ * ldmain.c (main): Initialize new field link_info.static_link.
+
+ * ldmain.c (add_keepsyms_file): Add \n at end of einfo calls.
+ (constructor_callback): Likewise.
+ * ldmisc.c (vfinfo): Likewise.
+ * ldwrite.c (build_link_order): Likewise.
+
+ * ld.texinfo: The MRI ALIGN directive is supported.
+
+Mon Oct 23 11:46:43 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * emulparams/elf32vr4300.sh: Deleted.
+ * emulparams/elf32vr4300el.sh: Deleted.
+ * emulparams/elf32b4300.sh: Added.
+ * emulparams/elf32l4300.sh: Added.
+ * configure.tgt, Makefile.in: Updated the build to use the
+ new 8.3 unique names.
+
+Thu Oct 19 17:41:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (entry_symbol): Make non-static.
+ * ldlang.h (entry_symbol): Declare.
+
+ * ldlex.l: Treat PROVIDE as a keyword in expression state.
+
+Wed Oct 18 17:34:06 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttempl/pe.sc (.bss): Move to be after .text
+
+Tue Oct 17 12:22:05 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_exp_assignment):
+ Search trinary.cond rather than searching trinary.lhs twice. From
+ linli@ihp.PHys.ethz.CH.
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Move
+ directory searching code into gld${EMULATION_NAME}_search_dir.
+ (gld${EMULATION_NAME}_search_dir): New static function, extracted
+ from gld${EMULATION_NAME}_find_so.
+ (global_needed, global_found): New static variables.
+ (gld${EMULATION_NAME}_after_open): New static function.
+ (gld${EMULATION_NAME}_search_needed): New static function.
+ (gld${EMULATION_NAME}_try_needed): New static function.
+ (gld${EMULATION_NAME}_check_needed): New static function.
+ (ld_${EMULATION_NAME}_emulation): Use new after_open function.
+ * ld.texinfo, ld.1: Mention -rpath-link on SunOS.
+
+ * Makefile.in (eelf32ppc.c): Depend upon elf32.em, not generic.em.
+ (eelf32lppc.c): Likewise.
+ * emulparams/elf32lppc.sh (TEMPLATE_NAME): Define as elf32.
+ (GENERATE_SHLIB_SCRIPT): Define as yes.
+
+Mon Oct 16 19:11:13 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em: Struct bfd_elf_link_needed_list is now named
+ bfd_link_needed-list; make appropriate changes.
+
+ * configure.tgt (powerpc-*-aix*): New target; use aixppc.
+ (rs6000-*-aix*): New target; use aixrs6.
+ * emulparams/aixppc.sh, emulparams/aixrs6.sh: New files.
+ * emultempl/aix.em: New file.
+ * scripttempl/aix.sc: New file.
+ * Makefile.in (ALL_EMULATIONS): Add eaixppc.o and eaixrs6.o.
+ (eaixppc.c, eaixrs6.c): New targets.
+
+Fri Oct 13 14:00:37 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttemp/pe.sc (.reloc): Move to the end.
+
+Tue Oct 10 17:53:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_finish): Don't try to use an entry_symbol from a
+ section which was not linked into the final output.
+
+Tue Oct 10 10:17:22 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * emultempl/pe.em (gld_${EMULATION_NAME}_parse_args): Fix
+ fatal typos.
+
+Tue Oct 10 01:01:51 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (args_type): Add rpath_link field.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Search for
+ required dependencies in rpath_link path. Only search
+ LD_LIBRARY_PATH when configured native.
+ * lexsup.c (parse_args): Recognize -rpath-link.
+ * ld.1, ld.texinfo: Document -rpath-link.
+
+Sat Oct 7 17:07:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Don't
+ bother searching for needed libraries unless doing a final link.
+
+Fri Oct 6 16:26:16 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ld/ld.1: Fix formatting bugs.
+
+Wed Oct 4 17:37:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldexp.c (exp_get_abs_int): Return bfd_vma, not int.
+ * ldexp.h (exp_get_abs_int): Update declaration.
+ * ldlang.c (print_output_section_statement): Use fprintf_vma to
+ print return value of exp_get_abs_int.
+
+Mon Oct 2 13:56:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (global_stat): New file static variable.
+ (gld${EMULATION_NAME}_try_needed): Call stat_needed to make sure
+ that the file has not already been included under another name.
+ (gld${EMULATION_NAME}_stat_needed): New static function.
+
+Fri Sep 29 12:00:18 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * scripttempl/armcoff.sc: Start .text at 0x8000.
+ Start .data at 0x40000.
+
+Fri Sep 29 11:09:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): If
+ command_line.rpath is set, use it, rather than the -L options, to
+ build the rules section.
+ * ld.texinfo: Document this use of -rpath.
+
+ * lexsup.c (parse_args): Don't set link_info.shared for -assert
+ pure-text. Pass true, not 1, to lang_add_entry.
+ * emultempl/sunos.em (find_assign): New static variable.
+ (found_assign): New static variable.
+ (gld${EMULATION_NAME}_before_allocation): Rename local h to hdyn.
+ If not a relocateable link, and no start symbol was specified on
+ the command line, and there are any undefined symbols, set
+ link_info.shared. If link_info.shared is set, set the address of
+ the .text section to 0x20.
+ (gld${EMULATION_NAME}_find_assignment): Rename from
+ gld${EMULATION_NAME}_find_statement_assignment. If find_assign is
+ set, then just set found_assign based on whether an assignment is
+ found to find_assign.
+ (gld${EMULATION_NAME}_get_script): Don't use a special script when
+ producing a shared library.
+ * emulparams/sun4.sh (GENERATE_SHLIB_SCRIPT): Remove.
+ * scripttempl/aout.sc: Remove CREATE_SHLIB tests.
+ * ldlang.c (entry_from_cmdline): New global variable.
+ (lang_add_entry): Change cmdline parameter from int to boolean.
+ Use global entry_from_cmdline rather than function static
+ from_cmdline.
+ * ldlang.h (entry_from_cmdline): Declare.
+ (lang_add_entry): Change declaration of second parameter from int
+ to boolean.
+ * ldgram.y: Pass false, not 0, to lang_add_entry.
+
+Thu Sep 28 12:34:13 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (parsing_defsym): Declare.
+ * ldlex.h (lex_string): Declare.
+ * ldlex.l (lex_string): Define.
+ * lexsup.c (parsing_defsym): Define.
+ (parse_args): In OPTION_DEFSYM case, set lex_string before calling
+ lex_redirect, and clear it after calling yyparse. Set
+ parsing_defsym around call to yyparse.
+ * ldmain.c (main): Set lex_string before calling lex_redirect, and
+ clear it after calling yyparse.
+ * ldmisc.c (vfinfo): For %S, handle --defsym arguments and built
+ in linker scripts correctly.
+
+ * scripttempl/sparccoff.sc: Add .ctors/.dtors handling like other
+ COFF targets, allowing for the leading underscore used on SPARC
+ COFF.
+
+ * lexsup.c (parse_args): Handle -assert.
+ * emulparams/sun4.sh (GENERATE_SHLIB_SCRIPT): Define.
+ * emultempl/sunos.em (gld${EMULATION_NAME}_get_script): Use the
+ shared library script when appropriate.
+ * scripttempl/aout.sc: If CREATE_SHLIB is set, start the .text
+ section at SIZEOF_HEADERS.
+
+Thu Sep 28 01:40:37 1995 Doug Evans <dje@deneb.cygnus.com>
+
+ * Makefile.in (earmcoff.c): Build.
+ * configure.tgt (arm-*-coff): New target
+ * emulparms/armcoff.sh: New file.
+ * scripttempl/armcoff.sc: New file.
+
+Tue Sep 26 10:59:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/i386coff.sc: Remove .data2; no longer needed.
+
+Fri Sep 22 18:09:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldfile.c (ldfile_set_output_arch): Make arch const.
+
+Thu Sep 21 17:55:24 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc: Correctly locate __bss_start at the
+ beginning of the .bss area, not at the end of data. Add
+ __sbss_{start,end} symbols.
+
+Wed Sep 20 12:29:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET): Quote $(program_transform_name).
+ (CXX_FOR_TARGET, install): Likewise.
+
+Mon Sep 18 14:53:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches by Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * Makefile.in (CC_FOR_TARGET): Remove brokensed stuff.
+ (CXX_FOR_TARGET): Likewise.
+ (install): Likewise.
+ (GENERATED_HFILES): Remove config.h.
+ (.dep): Depend upon config.h.
+
+Mon Sep 18 14:39:38 1995 Arne H. Juul <arnej@pvv.unit.no>
+
+ * configure.tgt (mips*-dec-netbsd*): New target.
+
+Fri Sep 15 20:01:52 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.host (m88*-*-dgux*): Fix another shell syntax error.
+
+Fri Sep 15 23:28:05 1995 Andrew Cagney <cagney@highland.com.au>
+
+ * configure.host (i[345]86-*-bsd*): Fix shell syntax error.
+
+Thu Sep 12 12:50:49 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttemp/pe.sc: Allow both spellings of .ctors/.dtors.
+ Start .text section on the right boundary. Always align
+ stabs.
+
+Tue Sep 12 12:24:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target.
+
+ * ldmain.c (struct warning_callback_info): Define.
+ (warning_callback): Add new parameter symbol. Call
+ warning_find_reloc to try to find the section and VMA.
+ (warning_find_reloc): New static function.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Pass NULL as symbol parameter to warning callback.
+
+ * ld.texinfo: Clarify -L option.
+
+ * ldlang.c (lang_one_common): Add cast to avoid warning.
+ (topower): Likewise. Also, reindent.
+ * ldwrite.c (clone_section): Change i to unsigned int.
+ * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): Add
+ cast to avoid warning.
+
+Fri Sep 8 16:32:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (config.status): Depend upon configure.tgt.
+
+ * ldemul.h (ldemul_set_symbols): Declare.
+ (ldemul_parse_args): Declare.
+ * ldemul.c (ldemul_parse_args): Fix indentation.
+
+ * configure.in: Call AC_HEADER_DIRENT.
+ * configure, config.in: Rebuild.
+ * emultempl/sunos.em: Use autoconf recommend mechanism to define
+ DIR and struct dirent.
+
+ * configure.tgt (mips*-*-bsd*): New case.
+
+ * configure.host (i[345]86-sequent-ptx* | i[345]86-sequent-sysv*)
+ New case.
+ * configure.tgt (i[345]86-*-ptx*): New case.
+
+Thu Sep 7 10:48:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.in: Rename from config.h.in.
+ * configure.in: Call AC_CONFIG_HEADER with config.h:config.in.
+ Check for config.h:config.in when creating stamp-h.
+ * configure: Rebuild.
+ * Makefile.in (stamp-h): Depend upon config.in rather than
+ config.h.in. Set CONFIG_HEADERS to config.h:config.in when
+ calling config.status.
+
+ * Makefile.in (distclean): Remove config.h and stamp-h.
+
+ * configure.host (sparc-*-sunos64*): Remove.
+ * ldlang.c (lang_map): Check BFD64, not HOST_64_BIT.
+
+ * ldexp.c (exp_fold_tree): Don't warn about moving the location
+ counter backward in the absolute section.
+
+Wed Sep 6 14:42:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Rewrite to use autoconf.
+ * configure.host: New file.
+ * configure.tgt: New file.
+ * aclocal.m4: New file.
+ * configure: New file, built by autoconf.
+ * acconfig.h: New file.
+ * config.h.in: New file, built by autoheader.
+ * sysdep.h: New file.
+ * ld.h: Incorporate old contents of config.h.
+ * config.h: Remove.
+ * Makefile.in: Various changes for new configure script. Also:
+ (CC_FOR_BUILD): Remove.
+ (ldmain.o): Don't bother to ensure that EMUL is non-empty.
+ (dep.sed): Use @SRCDIR@, not @srcdir@.
+ * dep-in.sed: Use @SRCDIR@, not @srcdir@.
+ * genscripts.sh: Create ldscripts if it does not exist.
+ * ldemul.c, lexsup.c, mpw-emipsidt.c: Don't include "config.h".
+ * mpw-esh.c, emultemp/*.em: Likewise.
+ * ldmain.c: Likewise. Include <ctype.h>. Don't try to set
+ HAVE_SBRK here.
+ * config/*.mt, config/*.mh: Remove.
+
+Tue Sep 5 14:55:24 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: Treat ns32k-pc532-ux* like ns32k-pc532-mach*, and
+ ns32k-pc532-lites* like ns32k-pc532-netbsd*. From Ian Dall.
+
+Fri Sep 1 22:29:52 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/pe.sc: Fix typo in spelling of .ctors/.dtors.
+
+Fri Sep 1 13:13:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (warning_callback): Add abfd, section, and address
+ parameters.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Change call to warning accordingly.
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): If not
+ relocateable and not shared, put .gnu.warning.SYMBOL sections into
+ the .text section.
+
+Fri Sep 1 08:35:16 1995 James G. Smith <jsmith@beauty.cygnus.com>
+
+ * configure.in: Added mips*vr4300-idt-elf* and
+ mips*vr4300el-idt-elf* targets.
+ * Makefile.in: Added eelf32vr4300* targets.
+ * emulparams/{elf32vr4300.sh, elf32vr4300el.sh}: Added.
+ * config/{mips-vr4300.mt, mips-vr4300el.mt}: Added.
+
+Fri Sep 1 10:51:45 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/a29k.sc: Fix to be reasonable. From Brendan Kehoe
+ <brendan@cygnus.com>.
+
+Thu Aug 31 16:37:07 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * ldemul.c (ldemul_parse_args): New.
+ * ldemul.h (ld_emulation_xfer_struct): Add parse_args.
+ * lexsup.c (all pe stuff): Moved into pe.em
+ (parse_args): Call emulation arg parser.
+ * emultempl/pe.em (parse_args): handle PE specfic args.
+
+Thu Aug 31 17:01:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_memory_region_lookup): Don't use the first region
+ as the default region. Create a new region instead.
+
+Tue Aug 29 14:21:41 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * ldemul.c (ldemul_set_symbols): New function.
+ * ldemul.h (ld_emulation_xfer_struct): Add set_symbols.
+ * ldmain.c (main): Add call to ldemul_set_symbols.
+ * lexsup.c (set_pe_value): New args.
+ (set_pe_name): New.
+ (parse_args): Cope with new set_pe_value args.
+ * emultempl/pe.em (set_symbols): New function.
+ (ld_emulation_xfer_struct): Add set_symbols.
+ * scripttempl/pe.sc: Use new symbols.
+
+Thu Aug 24 18:12:18 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * lexsup.c (parse_args): Don't call set_default_dirlist for -O.
+ For -Y, ignore a leading `P,', and only call set_default_dirlist
+ after processing all the other arguments.
+
+Tue Aug 22 07:36:58 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttempl/pe.sc: Keep .edata, don't base stabs at 0.
+ * emulparams/armpe.sh: Run PE script.
+
+Mon Aug 21 18:30:42 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * ldmain.c (main): Remove PE stuff.
+ * lexsup.c (options): Load more PE options.
+ (set_pe_value): New function.
+
+Thu Aug 17 13:35:49 1995 steve chamberlain <sac@slash.cygnus.com>
+
+
+ * emultempl/{armpe.sc, i386pe.sc}: Deleted.
+ * emultempl/pe.sc: New file performs generic PE support and sorts
+ archive members.
+ * emulparams/{armpe.sh,i386pe.sh}: Use new file.
+ * scripttempl/{armpe.sc, i386pe.sc}: Deleted
+ * scripttempl/pe.sc: New.
+ * Makefile.in: Use new files.
+
+Thu Aug 17 14:46:34 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/h8500s.sc (.rdata): All data must go in data segment.
+ (.strings,.ctors,.dtors): Likewise.
+
+Wed Aug 16 11:38:59 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttempl/armpe.sc: Always start code at 0x401000, even
+ if -r.
+ * ldwrite.c (strdup): New extern declaration.
+ * ldgram.y (atype): New rule to clarify type parsing.
+ * ldlang.c (init_os): Remove commented out code.
+ (lang_size_sections): Set SEC_ALLOC and SEC_LOAD bits
+ unless told not to by the link script.
+
+Wed Aug 16 11:45:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_set_startof): New static function.
+ (lang_process): Call it.
+
+ * ldgram.y: Tweak casesymlist to avoid bison errors.
+
+ * lexsup.c (parse_args): Accept -h as a synonym for --soname, for
+ Solaris compatibility.
+
+Tue Aug 15 17:31:16 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldgram.y (YYDEBUG): If not defined, define as 1.
+ (CASE, EXTERN, START): New tokens.
+ (mri_script_command): Handle CASE, EXTERN, INCLUDE, START.
+ (casesymlist): New nonterminal.
+ (extern_name_list): New nonterminal.
+ * ldlex.l: Accept lower case trailing base specifiers. Don't
+ ignore the first digit when the base is a suffix. Accept many
+ EXPRESSION state tokens in MRI state. Support MRI continuation
+ lines and MRI semicolon comments. Accept all MRI keywords in
+ lower case. Add CASE, EXTERN, and START MRI keywords.
+
+Tue Aug 8 19:14:58 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Use xmalloc
+ instead of alloca.
+
+Tue Aug 8 15:24:05 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * Makefile.in (CC_FOR_TARGET, CXX_FOR_TARGET): Don't use
+ $r/../gcc/xgcc unless it is present.
+
+Thu Aug 3 11:56:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * scripttempl/m68kcoff.sc: Only put .ctors and .dtors in .text
+ when CONSTRUCTING.
+ * scripttempl/m68klynx.sc: Likewise.
+ * scripttempl/nw.sc: Likewise.
+ * scripttempl/sa29200.sc: Likewise.
+ * scripttempl/sparclynx.sc: Likewise.
+
+Fri Jul 28 12:02:23 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * emulparams/{z8001.sh, z8002.sh}: Fix typo.
+
+Thu Jul 27 21:06:21 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in (i[345]86-*-linuxoldld): Treat like linuxaout*.
+
+Thu Jul 27 15:26:28 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * scripttempl/i386pe.sc: Cope with constructors.
+ * scripttempl/z8ksim.sc: Deleted.
+ * scripttempl/z8000.sc: Resurrected as this, but
+ can handle z8001 and z8002 formats.
+ * emulparams/z8ksim.sh: Deleted.
+ * emulparams/{z8001.sh, z8002.sh}: New files.
+ * config/z8ksim.mt: Deleted
+ * config/z8k-coff.mt: New, generates both emulations.
+
+Tue Jul 25 14:53:02 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmisc.c (vfinfo): In %C and %D case, always print the BFD using
+ %B, in case it is in an archive.
+
+Mon Jul 24 15:23:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_process): Call reset_memory_regions for each
+ relaxation pass.
+
+Fri Jul 21 22:49:44 1995 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfppc.sc: Add support for .sdata, .sbss, and
+ _SDA_BASE.
+
+Thu Jul 20 16:26:55 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * ldmain.c (constructor_callback): Allocate set_name in stack
+ frame, rather than always calling alloca with a fixed size.
+
+Wed Jul 19 16:21:43 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * emulparams/armpe.sh (OUTPUT_FORMAT): Change to pei-arm-little.
+ (LITTLE_OUTPUT_FORMAT, BIG_OUTPUT_FORMAT): Define.
+
+Mon Jul 17 13:57:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldwrite.c (clone_section): Set the alignment of the clone
+ section to that of the section being cloned.
+
+ * ldwrite.c (split_sections): Don't split the first input section
+ into a new output section.
+
+Sat Jul 15 00:26:35 1995 Michael Meissner <meissner@cygnus.com>
+
+ * emulparams/elf32ppc.sh (TEMPLATE_NAME): Define as elf32.
+ (GENERATE_SHLIB_SCRIPT): Define as yes.
+
+Fri Jul 14 12:11:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/mipsecoff.em (check_sections): Use %P, not %F.
+
+ * ldver.c (help): Update list of options to match currently
+ supported list.
+
+Thu Jul 13 13:52:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/lnk960.em (ld_lnk960_emulation): Initialize
+ after_open field.
+
+ * ldexp.c (exp_intop): Don't cast stat_alloc arg to bfd_size_type;
+ it takes a size_t anyhow.
+ (exp_binop): Likewise.
+ (exp_trinop): Likewise.
+ (exp_unop): Likewise.
+ (exp_nameop): Likewise.
+ (exp_assop): Likewise.
+ * ldlang.c (lang_memory_region_lookup): Likewise.
+ (init_os): Likewise.
+ (ldlang_add_undef): Likewise.
+ (insert_pad): Likewise.
+ * ldfile.c (ldfile_add_arch): Don't cast xmalloc arg to
+ bfd_size_type.
+
+ * Makefile.in (ALL_EMULATIONS): It's earmaoutb.o, not earmoutb.o.
+
+Wed Jul 12 11:32:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldemul.h (ldemul_open_dynamic_archive): Add search parameter to
+ declaration.
+ (ld_emulation_xfer_type): Add search parameter to
+ open_dynamic_archive entry point.
+ * ldemul.c (ldemul_open_dynamic_archive): Add search parameter.
+ * ldfile.c (ldfile_try_open_bfd): Rename from try_open_bfd, and
+ make non-static. Change all callers to use new name.
+ (ldfile_open_file_search): Make static. If entry is dynamic, call
+ ldemul_open_dynamic_archive.
+ (ldfile_open_file): Don't call ldemul_open_dynamic_archive.
+ * ldfile.h (ldfile_open_file_search): Don't declare.
+ (ldfile_try_open_bfd): Declare.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_open_dynamic_archive):
+ Accept search parameter. Don't search for a library, just look in
+ a single place.
+ * emultempl/linux.em (gld${EMULATION_NAME}_open_dynamic_archive):
+ Likewise.
+
+Tue Jul 11 16:44:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (set_scripts_dir): Don't base script directory on
+ current directory.
+
+Tue Jul 11 12:29:02 1995 Rick Sladkey <jrs@world.std.com>
+
+ * ldmisc.c (vfinfo): Don't print the line number if it isn't
+ meaningful.
+
+Mon Jul 10 13:38:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld.h (ld_config_type): Add field warn_constructors.
+ * ldmain.c (add_to_set): Warn if config.warn_constructors.
+ (constructor_callback): Likewise.
+ * lexsup.c (parse_args): Handle -warn-constructors.
+ * ld.texinfo, ld.1: Document -warn-constructors.
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Don't
+ get confused by directory names if we searched for the file.
+
+ Based on patches from H.J. Lu <hjl@nynexst.com>:
+ * ldlang.h (lang_input_statement_type): Add new field dynamic.
+ * ldlang.c (new_afile): Set dynamic from config.dynamic_link.
+ * ldfile.c: Include bfdlink.h.
+ (ldfile_open_file): Check dynamic field of entry, not global
+ dynamic_link field. Don't do a dynamic search when doing a
+ relocateable link.
+ * ldmain.c (main): Don't warn about dynamic_link for a
+ relocateable link.
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Skip file if
+ dynamic is false.
+ (gld${EMULATION_NAME}_create_output_section_statements): Always
+ loop over input files.
+ * Makefile.in: Rebuild dependencies.
+
+ * ld.texinfo, ld.1: Document -Bstatic, -Bdynamic, -Bshared, and
+ -shared.
+
+Mon Jul 10 13:29:43 1995 Eric Youngdale <eric@aib.com>
+
+ * ldmain.c (main): Set link_info.symbolic to false.
+ * lexsup.c (parse_args): Handle -Bsymbolic.
+
+Wed Jul 5 00:12:11 1995 Fred Fish (fnf@cygnus.com)
+
+ * ldmain.c (HAVE_SBRK): Define for everything except
+ specific systems that are known to not support sbrk.
+ (main): Use HAVE_SBRK to decide whether or not to use sbrk.
+
+Tue Jul 4 12:55:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_find_exp_assignment):
+ Handle etree_provide.
+
+ * emultempl/elf32.em (global_needed): New static variable.
+ (global_found): Likewise.
+ (gld${EMULATION_NAME}_after_open): New static function.
+ (gld${EMULATION_NAME}_search_needed): Likewise.
+ (gld${EMULATION_NAME}_try_needed): Likewise.
+ (gld${EMULATION_NAME}_check_needed): Likewise.
+ (ld_${EMULATION_NAME}_emulation): Replace after_open_default with
+ gld${EMULATION_NAME}_after_open.
+
+Mon Jul 3 14:26:37 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * configure.in (i386-*-win32): New target.
+
+Mon Jul 3 14:39:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (parse_args): Let -G either set the small data size or
+ be equivalent to --shared, depending on the next argument. Accept
+ and ignore -z for Solaris compatibility.
+
+Sun Jul 2 17:52:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lexsup.c (parse_args): Cast fopen result to PTR before storing
+ it in link_info.base_file. Fix indentation.
+
+Wed Jun 28 17:11:25 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * ldmain.c (main): Always initialize PE info in link_info.
+ * lexsup.c (OPTION_BASE_FILE): New option.
+ (parse_args): Handle new option.
+ * emulparams/armpe.sh: Output pei.
+ * emultempl/i386pe.em: Add newline to end.
+ * scripttempl/armpe.sc: Change output and quote the $s.
+ * scripttempl/i386pe.sc: Change output and quote the $s.
+
+Thu Jun 22 19:55:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ Sun May 7 11:53:41 MDT 1995 Bryan Ford <baford@cs.utah.edu>
+
+ * configure.in (i386-*-msdos*, i386-*-moss*): New targets.
+ * Makefile.in (ALL_EMULATIONS): Added i386msdos.o.
+ (i386msdos.o): New target.
+ * config/i386-msdos.mt: Created.
+ * emulparams/i386msdos.sh: Created.
+ * scripttempl/i386msdos.sc: Created.
+
+Thu Jun 22 15:06:35 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * scripttempl/elfppc.sc (.fixup): Add support for a .fixup section
+ that contains pointers to be relocated.
+
+Tue Jun 20 17:47:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-esh.c: New file, modified for MPW from esh.c.
+ * scripttempl/sh.sc: Reformatted to simplify MPWification,
+ use *() to concat stab sections instead of [].
+
+Thu Jun 15 08:48:16 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * scripttempl/armpe.sc: Add constructor support.
+
+Tue Jun 13 09:11:20 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * ldlang.c (lang_size_sections): Any section with a DATA
+ statement has contents.
+
+Sun Jun 11 15:20:46 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * emulparams/m68kelf.sh (NOP): Define.
+ (DYNAMIC_LINK): Don't define.
+ (TEXT_START_ADDR): Set to 0x80000000; the extra 0x100 for headers
+ will come from the linker script.
+
+Thu Jun 8 14:17:33 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * emulparams/armpe.sh, scriptempl/armpe.sc: Add end and stack.
+
+Mon Jun 5 02:16:24 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * configure.in (i[345]86-*-gnu*): Use GNU elf config.
+
+Thu May 25 11:49:28 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ From Andrew Cagney <cagney@highland.com.au>
+ * Makefile.in: Fixup more gotchas from renaming elf32ppcle to
+ elf32lppc.
+
+Wed May 24 11:23:21 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ Add support for ARM-PE.
+ * Makefile.in (ALL_EMULATIONS): Add armpe.o
+ * configure.in: Recognize armpe.
+ * config/arm-pe.mt: New file.
+ * emulparams/armpe.sh: New file.
+ * scripttempl/armpe.sc: New file.
+
+
+Mon May 22 15:19:26 1995 Doug Evans <dje@chestnut.cygnus.com>
+
+ * configure.in (h8300h-*-hms): Deleted
+ * config/cf-h8300h.mt: Deleted.
+
+Thu May 18 04:26:10 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ From David Taylor (dtaylor@armltd.co.uk)
+ * Makefile.in (ALL_EMULATIONS): Add earmout[lb].o
+ * configure.in: Recognize arm{,e[lb]-*-aout.
+ * config/arm[lb]-aout.mt: New files.
+ * emulparams/armaout[lb].sh: New files.
+ * scripttempl/armaout.sc: New file.
+
+Tue May 16 18:27:11 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config/ppcle-elf32.mt (EMUL): Use elf32lppc, not elf32ppcle, to
+ be unique in 8 characters for DOS.
+
+ * emulparams/elf32lppc.sh: New file, renamed from elf32ppcle.sh.
+ * emulparams/elf32ppcle.sh: Deleted.
+
+Fri May 12 11:03:55 1995 Steve Chamberlain <sac@slash.cygnus.com>
+ Tom Griest <griest@cs.yale.edu>
+
+ Initial support for PE executables (eg NT, win32)
+
+ * Makefile.in (configure.in, ei386pe): Add support.
+ * ldmain.c (main): Initialize PE argument info.
+ * ldwrite.c (print_file_stuff): Don't print out .drectve
+ and .debug section info.
+ * lexsup.c (set_subsystem, set_stack_heap, OPTION_HEAP,
+ OPTION_SUBSYSTEM, parse_argsm set_subsystem, set_stack_heap):
+ Handle new arguments.
+ * config/i386-pe.mt, emultempl/i386pe.em, scripttempl/i386pe.sc:
+ New files
+
+Wed May 10 18:37:59 1995 Stu Grossman (grossman@andros.cygnus.com)
+
+ * scripttempl/hppaelf.sc: Remove .PARISC.unwind section from text
+ segment. This allows ld -r to preserve unwind sections.
+
+Tue May 9 17:19:57 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add little endian PowerPC support.
+
+ * Makefile.in (ALL_EMULATIONS): Add eelf32ppcle.o.
+ (eelf32ppcle.c): Support for little endian PowerPC.
+
+ * config/ppcle-elf32.mt: New file for little endian PowerPC.
+ * emulparams/elf32ppcle.sh: Ditto.
+
+Wed May 3 12:56:32 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ldlang.c (print_output_section_statement): Check
+ subsection_alignment, instead of checking section_alignment twice.
+ Noticed by Alan Modra <alan@spri.levels.unisa.edu.au>.
+
+Tue May 2 16:36:07 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-lites*): Handle like hppa*-*-*elf*.
+
+Mon Apr 24 19:21:02 1995 Michael Meissner <meissner@cygnus.com>
+
+ * ldwrite.c (ldwrite): Before doing anything, reset the error
+ code. If bfd_final_link returns an error, but the error code is
+ unset, don't issue an extra message. Assume a correct error
+ message was already set.
+
+Fri Apr 14 16:31:24 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (ALL_EMULATIONS): Added em68kelf.o.
+ (em68kelf.o): New target.
+ * config/m68k-elf.mt, emulparams/m68kelf.sh: New files.
+ * configure.in: Use them for m68*-*-elf.
+
+Tue Apr 11 12:02:03 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Merge in support for Mac MPW as a host.
+ (Old change descriptions retained for informational value.)
+
+ * mpw-config.in (i386-unknown-aout): Change to i386-unknown-go32.
+ (i386-unknown-coff): Remove.
+ (sh-hitachi-hms): New target.
+ (emulation_ofiles): Set correctly for each target.
+ (version, TDEFINES): Add to makefile fragment.
+ * mpw-make.in (BISON): Use byacc instead of bison.
+ (em_*.c): Replace with e*.c everywhere.
+ (ldgram.h): Separate action from ldgram.c generation.
+ (LD_PROG): Depend on Version.r.
+ (Version.r): generate from version info.
+ * mpw-emipsidt.c: New file, modified for MPW from emipsidt.c.
+
+ * mpw-config.in (m68k-apple-macos, ppc-apple-macos,
+ i386-unknown-aout, i386-unknown-coff): New targets.
+ (m68k-aout, m68k-coff): Remove targets.
+ (mk.tmp): Add definition of EMUL.
+
+ * mpw-config.in (emulname): Set based on target.
+ (ldemul-list.h): Construct.
+ * mpw-make.in (install-only): New target.
+ (install): Depend on install-only.
+
+ * mpw-make.in (bindir): Fix pathname.
+ (install): Move here from mpw-build.in.
+
+ * mpw-config.in: New file, MPW configuration fragment.
+ * mpw-make.in: New file, MPW makefile fragment.
+ (This file is semi-automatically generated from Makefile.in.)
+ * ldfile.c (slash): If MPW, set to `:'.
+ * ldlex.l (TRUE_FALSE_ALREADY_DEFINED): If MPW, set this to
+ prevent redefinition errors.
+
+Tue Apr 4 17:55:18 1995 Steve Chamberlain <sac@bang.hack.com>
+
+ * ldwrite.c (clone_section): Align clone sections on even
+ boundaries.
+
+Thu Mar 30 14:32:26 1995 H.J. Lu (hjl@nynexst.com)
+
+ * configure.in: Change linux to default to elf. Using
+ i[345]86-*-linuxaout will build a linker which defaults to a.out.
+ * config/i386-laout.mt: Rename from old config/i386-linux.mt.
+ * config/i386-linux.mt: Rename from old config/i386-lelf.mt.
+ * config/i386-lelf.mt: Remove.
+
+Thu Mar 30 13:09:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): If opening the map file fails, call
+ bfd_set_error before calling einfo.
+
+ * ld.texinfo, ld.1: Document the -no-keep-memory option.
+
+Mon Mar 27 11:10:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): Revert patch of March 10, since the SVR4 linker
+ does mark shared libraries as executable.
+
+Tue Mar 21 15:15:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_common): Change power to int. Pass larger values
+ before smaller values.
+ (lang_one_common): Treat info as int *. Don't bother to check for
+ last value, since it is now zero.
+
+Sat Mar 18 01:49:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (load_symbols): An empty archive is OK.
+
+Fri Mar 17 16:15:31 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * ldmain.c (progress.h): Include.
+ (main): Call START_PROGRESS and END_PROGRESS.
+
+Thu Mar 16 17:17:33 1995 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfppc.sc: Move _GOT2_END_ after the .ctors and
+ .dtors sections, so that these pointers get relocated also.
+ Define the symbols __{C,D}TOR_{LIST,END}__ to mark the beginning
+ and end of the constructors/destructors.
+
+Thu Mar 16 13:59:14 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
+
+ * ldlang.c (load_symbols): If whole_archive is true and ENTRY
+ describes an archive, call bfd_link_add_symbols on each member.
+ * ldmain.c (whole_archive): New variable.
+ (main): Initialize it to false.
+ * ldmain.h: Declare whole_archive.
+ * lexsup.c (parse_args): Grok --whole-archive switch.
+ * ld.texinfo, ld.1: Document --whole-archive.
+
+Thu Mar 16 11:38:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * genscripts.sh (EMULATION_NAME): Set LIB_PATH to empty when not
+ using the default emulation.
+
+ * config/dgux.mh (HOSTING_EMU): Use -m rather than trying to set
+ LDEMULATION.
+ * config/hppaelf.mh (HOSTING_EMU): Likewise.
+
+Tue Mar 14 12:28:03 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Set force_maj
+ for -lc.N. From H.J. Lu <hjl@nynexst.com>.
+
+Fri Mar 10 14:43:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): Don't set EXEC_P if link_info.shared is set.
+
+ * ldlex.l: Return -lFILENAME as the token LNAME.
+ * ldgram.y: Add token LNAME.
+ (input_list): Treat LNAME like NAME, but pass it to
+ lang_add_input_file as lang_input_file_is_l_enum.
+ * ld.texinfo: Document using -lFILENAME in INPUT.
+
+Thu Mar 9 12:21:51 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ldlang.c (lang_check): If the architectures are compatible call
+ bfd_merge_private_bfd_data to let the backend do additional
+ checks.
+
+Tue Mar 7 00:53:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldemul.c (ldemul_choose_mode): If emulation not recognized, list
+ all supported emulations.
+
+Mon Mar 6 14:03:50 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldemul.c (ldemul_list_emulations): New function.
+ * ldemul.h (ldemul_list_emulations): Declare.
+ * ldver.c (help): List supported targets and emulations.
+
+Fri Mar 3 15:40:36 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * scripttempl/elf.sc (.debug): Relocate to address 0.
+ (.debug_srcinfo, .debug_aranges, .debug_pubnames,
+ .debug_sfnames, .line): Likewise.
+
+Fri Mar 3 17:07:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (hold_rel): New static variable.
+ (gld${EMULATION_NAME}_place_orphan): Place readonly sections with
+ contents whose names begin with ".rel" after hold_rel. Remove the
+ assertion which checked for unplaced .rel sections. Don't try to
+ sort the section into place if place->bfd_section is NULL.
+ (gld${EMULATION_NAME}_place_section): Set hold_rel to the first
+ section beginning with ".rel".
+
+Thu Mar 2 14:34:43 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ Doc note from pierre@phi.la.tce.com (Pierre Willard):
+ * ld.texinfo: -X and -x work even if -s or -S are not specified.
+ * ld.1: Similar change.
+
+Wed Mar 1 13:51:16 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emulparams/gld960coff.sh (COFF_CTORS): Define.
+ * scripttempl/i960.sc: Use COFF_CTORS if CONSTRUCTING.
+
+Tue Feb 28 12:42:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (i[345]86-*-linuxelf*): New target. Use i386-lelf.
+ (i[345]86-*-gnuelf*): New target. Use i386-gelf.
+ * config/i386-lelf.mt: New file.
+ * config/i386-gelf.mt: New file.
+
+Tue Feb 28 10:27:54 1995 Rob Savoye <rob@darkstar.cygnus.com>
+
+ * configure.in: Match on mips-ecoff, and default to the IDT
+ configuration.
+
+Fri Feb 17 13:06:47 1995 Michael Meissner <meissner@cygnus.com>
+
+ * scripttempl/elfppc.sc: Add support for .got1 and .got2 sections.
+ Offset _GLOBAL_OFFSET_TABLE_ 32768 from the start of the GOT area
+ to double the size of the table.
+
+Thu Feb 9 18:29:43 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (distclean): Do recursive deletion, since ldscripts
+ is a directory.
+
+Thu Feb 9 11:38:22 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (main): If trace_file_tries is true, and we are using
+ an internal linker script, print out the script.
+ * ldfile.c (try_open): Reindent function. Make the messages about
+ opening script files more informative.
+
+ * lexsup.c (parse_args): For -V, call ldversion with 1, not 0.
+ * ld.texinfo, ld.1: Update accordingly.
+
+Wed Feb 8 17:34:45 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldlang.c (lang_one_common): Adjust references to common symbol
+ information for new structure.
+
+Mon Feb 6 12:17:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldmain.c (undefined_symbol): Handle section being NULL.
+
+ * ldctor.c (ldctor_build_sets): Handle bfd_link_hash_defweak.
+ * ldexp.c (fold_name): Likewise.
+ * ldlang.c (print_one_symbol): Likewise.
+ (lang_finish): Likewise.
+ * ldmain.c (multiple_common): Likewise.
+ * ldwrite.c (print_symbol): Likewise. Also, bfd_link_hash_weak
+ renamed to bfd_link_hash_undefweak.
+
+ * scripttempl/alpha.sc: Set address of .data section correctly
+ when -n or -N is used. Patch from Chris G Demetriou
+ <Chris_G_Demetriou@LAGAVULIN.PDL.CS.CMU.EDU>.
+ * scripttempl/mips.sc: Similar change.
+
+Tue Jan 31 16:20:52 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * ldlang.c (lang_size_sections): Clarify error message when user
+ specified start addr conflicts with region. Fix resetting of
+ region pointer.
+
+Tue Jan 31 12:37:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ldexp.c (fold_name): In case NAME, permit an absolute symbol
+ in lang_allocating_phase_enum.
+
+Mon Jan 30 11:33:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Depend upon clean. Don't bother to
+ remove files which will be removed by clean. From patch by
+ alan@SPRI.Levels.UniSA.Edu.Au (Alan Modra).
+
+Fri Jan 27 16:27:34 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): For
+ a MIPS target, clobber the size of all but the first input
+ .reginfo section to be 0, so that lang_size_sections sets the
+ correct size for the output .reginfo section.
+
+Thu Jan 26 19:53:37 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Remove unused variable is.
+
+Thu Jan 26 12:33:05 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * configure.in: Add support for powerpc-*-eabi.
+
+ * scripttempl/elfppc.sc: New file for PowerPC embedded ABI
+ support.
+
+ * emulparams/elf32ppc.sh (SCRIPT_NAME): Use elfppc.sc instead of
+ elf.sc, which defines some new symbols PowerPC elf needs.
+
+Tue Jan 24 10:32:15 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldctor.c (ldctor_add_set_entry): Don't dump core if a
+ constructor entry is in the absolute section.
+
+Mon Jan 23 13:58:13 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * configure.in (i[345]86-*-gnu*): Set ld_target to i386-gnu.
+ * config/i386-gnu.mt: New file. Include ELF support.
+
+Thu Jan 19 16:22:11 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): If
+ there are any input sections named .gnu.warning, treat them as
+ containing a warning message to be printed by the linker, and
+ clobber the size so that the message is not copied into the output
+ file.
+ * scripttempl/elf.sc: Put .gnu.warning sections into the .text
+ section.
+
+Sun Jan 15 16:45:00 1995 Steve Chamberlain <sac@splat>
+
+ * configure.in (w65-*-*): New target.
+ * Makefile.in: Update.
+ * scripttempl/w65.sc: New.
+ * config/coff-w65.mt: New.
+
+Thu Jan 12 01:32:25 1995 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * ldlang.c (lang_place_orphans): Don't ignore files with
+ just_syms_flag set. Instead, put all their sections in
+ bfd_abs_section_ptr, using the section VMA as the output_offset.
+
+Wed Jan 11 22:59:09 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ldctor.c (ldctor_build_sets): Don't use `const' with typedef
+ name `reloc_howto_type', since it's now defined to be const.
+ * ldlang.c (lang_add_reloc): Ditto.
+ * ldlang.h (lang_reloc_statement_type, lang_add_reloc): Ditto.
+
+Wed Jan 11 11:24:45 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldexp.c (fold_binary): Adding or subtracting an absolute value
+ to a relative value does not require forcing the relative value to
+ be absolute. Also, reindent function.
+
+Wed Dec 28 22:05:52 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ldwrite.c (clone_section): Create a symbol with the
+ same name as the section.
+
+Mon Dec 19 14:02:13 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ld.h (split_by_reloc, split_by_file): New flags.
+ * ldwrite.c (clone_section, split_sections): New functions.
+ * lexsup.c (parse_args): Understand new split options.
+
+Fri Dec 9 17:22:55 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * scripttempl/elf.sc: Move .ctors and .dtors from .text segment to
+ .data segment. They must be writable when creating a shared
+ library. From H.J. Lu <hjl@nynexst.com>.
+
+Fri Dec 2 14:09:00 1994 Ian Lance Taylor <ian@rtl.cygnus.com>
+
+ * emultempl/miposecoff.em: New file.
+ * emulparams/mipsidt.sh (TEMPLATE_NAME): Set to mipsecoff.
+ * emulparams/mipsidtl.sh (TEMPLATE_NAME): Likewise.
+ * scripttempl/mips.sc: Put .rel.sdata sections in .text, and
+ provide __runtime_reloc_start and __runtime_reloc_stop if they are
+ used. Align _fdata to a 16 byte boundary.
+ * Makefile.in (emipsidt.c): Depend upon mipsecoff.em rather than
+ generic.em.
+ (emipsidtl.c): Likewise.
+ (check): Pass CC_FOR_HOST and CFLAGS_FOR_HOST to runtest.
+
+ * ld.h (args_type): Add new field embedded_relocs.
+ * ldemul.h (ldemul_after_open, after_open_default): Declare.
+ (ld_emulation_xfer_struct): Add new field after_open.
+ * ldemul.c (ldemul_after_open): New function.
+ (after_open_default): New function.
+ * ldlang.c (lang_process): Call ldemul_after_open.
+ * lexsup.c (parse_args): Handle --embedded-relocs.
+ * emultempl/elf32.em (ld_${EMULATION_NAME}_emulation): Initialize
+ new after_open field to after_open_default.
+ * emultempl/generic.em, emultempl/gld960.em: Likewise.
+ * emultempl/gld960c.em, emultempl/hppaelf.em: Likewise.
+ * emultempl/linux.em, emultempl/m88kbcs.em: Likewise.
+ * emultempl/sunos.em, emultempl/vanilla.em: Likewise.
+ * ld.texinfo, ld.1: Mention -embedded-relocs.
+
+Wed Nov 23 22:04:47 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * Makefile.in: Add eshl.o.
+ * config/coff-sh.mt: Add shl emulation.
+
+Tue Nov 22 11:55:37 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * scripttempl/elf.sc: Fill .text section with NOPS. From Eric
+ Youngdale <eric@aib.com>.
+
+Thu Nov 17 14:39:48 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ Patches from pirker@eiunix.tuwien.ac.at (Martin Pirker).
+ * config/i386linux.mh: New file; set HOSTING_CRT0.
+ * genscripts.sh: Don't put ${libdir} in LIB_PATH if it is
+ /usr/lib, since that is already in LIB_PATH.
+
+Wed Nov 16 10:03:03 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * scripttempl/hppaelf.sc (.text): Handle a use rdefined text start
+ address.
+ (.data, .bss): If "-N", then place the data/bss just after the end
+ of the .text section rather than at the default 0x40000000.
+
+ * scripttempl/hppaelf.sc (.text): Place unwind descriptors in the
+ text segment.
+
+Sat Nov 12 15:55:56 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Patches from Eric Youngdale <eric@aib.com>:
+ * ldlang.c (lang_finish): Don't warn if entry symbol not found
+ when generating a shared library.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Warn if
+ attempting to place an orphaned relocation section when generating
+ a dynamically linked object.
+
+ * scripttempl/elf.sc: Add ENTRY(${ENTRY}), and default ${ENTRY} to
+ _start.
+
+Fri Nov 11 14:27:23 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ld.h (args_type): Add field export_dynamic.
+ * lexsup.c (parse_args): Recognize --export-dynamic.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Pass export_dynamic argument to bfd_elf32_size_dynamic_sections.
+
+Wed Nov 9 12:47:11 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldlang.c (lang_one_common): Set SEC_ALLOC in any section where
+ we allocate common symbols.
+
+Tue Nov 8 17:50:43 1994 Eric Youngdale (eric@aib.com)
+
+ * scripttempl/elf.sc: Add .rel.init, .rela.init, .rel.fini, and
+ .rela.fini to the list of .rel* sections.
+
+Tue Nov 8 17:47:45 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldlang.c (load_symbols): Add new argument place. Only accept
+ linker scripts if place is not NULL. Put commands found in an
+ assumed linker script into place.
+ (lookup_name): Pass NULL as place argument to load_symbols.
+ (open_input_bfds): In lang_input_statement_enum case, pass a place
+ argument to load_symbols, and store any new statements after the
+ current one.
+
+Mon Nov 7 15:53:02 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ldver.c (ldversion): Bump to 2.5.3.
+
+Fri Nov 4 15:11:26 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (e*nbsd.c): Fix typo in dependencies.
+
+Thu Nov 3 19:35:44 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * Makefile.in (check): Add missing "else true" clause.
+
+ * emulparams/vax.sh (OUTPUT_FORMAT): Use "a.out".
+
+ * scripttempl/go32coff.sc: Changes from DJ Delorie: Change default
+ entry point to "start". Align at end of each section to 0x200.
+ Start .text section 0x1000 later. Add _etext, _edata, _end
+ symbols.
+
+Wed Nov 2 12:17:49 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldctor.c (ldctor_add_set_entry): Don't permit a set to be
+ composed of different object file formats.
+ (ldctor_build_sets): If the output format does not support the
+ reloc, and we are not generating a relocateable link, try getting
+ the reloc from the input format.
+
+Tue Nov 1 10:30:19 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * Makefile.in (ALL_EMULATIONS): Added em68knbsd.o.
+ (em68knbsd.c): New target.
+
+ * config/m68k-nbsd.mt: New file.
+ * emulparams/m68knbsd.sh: New file.
+ * configure.in (m68*-*-netbsd*): Use above configs.
+
+Mon Oct 31 19:35:17 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_find_so): If we find an
+ appropriately named static library, stop the search at that
+ directory.
+
+Wed Oct 26 13:59:12 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * Makefile.in (ALL_EMULATIONS): Added ei386nbsd.o, ens32knbsd.o
+ and esparcnbsd.o; sorted entries.
+ (ei386nbsd.c,ens32knbsd.c,esparcnbsd.c): New targets.
+
+ * config/netbsd532.mt: Removed.
+ * emulparams/netbsd532.sh: Removed.
+
+ * config/{i386-nbsd.mt,ns32k-nbsd.mt,sparc-nbsd.mt}: New files.
+ * emulparams/{i386nbsd.sh,ns32knbsd.sh,sparcnbsd.sh}: New files.
+ * configure.in (i[345]86-*-netbsd*, ns32k-pc532-netbsd*,
+ sparc*-*-netbsd*): Use above configs.
+
+Tue Oct 25 11:47:10 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldmain.c (multiple_common): One of the types may now be
+ bfd_link_hash_indirect. The old BFD argument may be NULL.
+
+Thu Oct 20 22:01:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Add * at the end of m68k-hp-hpux.
+
+Tue Oct 18 15:58:39 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ldlex.l: Cast assignment to yy_ch_buf field to char *, not to
+ YY_CHAR *.
+
+Mon Oct 17 14:53:16 1994 J.T. Conklin (jtc@phishhead.cygnus.com)
+
+ * scripttempl/nw.sc: Gather constructors and destructors and
+ define __CTOR__LIST__ and __DTOR_LIST__ appropriately.
+
+Fri Oct 14 14:35:38 1994 J.T. Conklin (jtc@rtl.cygnus.com)
+
+ * Makefile.in (ALL_EMULATIONS): Add ei386nw.o and eppcnw.o.
+ (ei386nw.c, eppcnw.c): New targets.
+
+ * config/{i386,ppc}-nw.mt, emulparams/{i386,ppc}nw.sh,
+ scripttempl/nw.sc: New files, for i386 and powerpc netware.
+
+ * configure.in: Changed netware ld_target name to be {i386,ppc}-nw
+ instead of {i386,ppc}-elf.
+
+ * configure.in (sparc*-*-netware): Removed. There is no such
+ thing anymore.
+
+ * ldint.texinfo: Move misplaced `@end iftex'.
+
+Fri Oct 14 12:02:18 1994 Eric Youngdale (eric@aib.com)
+
+ * scripttempl/elf.sc: Add .rel.ctors, .rela.ctors, .rel.dtors, and
+ .rela.dtors to the list of .rel* sections.
+
+Thu Oct 13 14:16:27 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ldver.c (ldversion): Update to version 2.5.
+ * Version 2.5 released.
+
+ * configure.in (all_targets): Handle i386-linux*.
+
+Thu Oct 13 11:24:33 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * scripttempl/aout.sc: Set _etext and __etext to ., not
+ ${DATA_ALIGNMENT}. This is compatible with SunOS, and, with luck,
+ will not break any other system. From Eric Valette
+ <ev@chorus.fr>.
+
+Wed Oct 12 16:22:58 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * lexsup.c (parse_args): Change -V to be a synonym for -v. Add
+ --verbose to get the old -V behaviour.
+ * ld.1, ld.texinfo: Document this change.
+
+Tue Sep 27 14:56:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Remove
+ assertion, since it could fail with a user defined linker script.
+
+ * ldexp.c (fold_name): For DEFINED case, don't try to look up the
+ name in the hash table during the first phase--the hash table does
+ not even exist at that point, much less have the right value.
+
+ * Makefile.in (CC): Define.
+ (CXX): Move definition, change from g++ to gcc.
+ (EXPECT, RUNTEST): Copy definitions from top level Makefile.in.
+ (RUNTEST_CC, RUNTEST_CFLAGS): Remove.
+ (RUNTEST_CXX, RUNTEST_CXXFLAGS): Remove.
+ (CC_FOR_TARGET, CXX_FOR_TARGET): Copy from top level Makefile.in.
+ (.cc.o): Comment out.
+ (testdir): Remove.
+ (site.exp): Don't create testdir or set tmpdir.
+ (check): Run checks even if not running native. Use CC_FOR_TARGET
+ instead of RUNTEST_CC, and likewise for CXX.
+ (cdtest targets): Comment out.
+ * config/solaris2.mh (HOSTING_LIBS): Only mention crtend.o once.
+ * cdtest-bar.cc, cdtest-foo.cc, cdtest-foo.h: Remove.
+ * cdtest-main.cc, cdtest.exp: Remove.
+
+Mon Sep 26 11:40:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * emulparams/elf32bmip.sh: Rename from elf32mipb.sh to avoid DOS
+ file naming problems.
+ * emulparams/elf32lmip.sh: Rename from elf32mipl.sh.
+ * Makefile.in (ALL_EMULATIONS): Rename eelf32mipb.o to
+ eelf32bmip.o and eelf32mipl.o to eelf32lmip.o.
+ (eelf32bmip.c): Rename from eelf32mipb.c. Use elf32bmip.sh.
+ (eelf32lmip.c): Rename from eelf32mipl.c. Use elf32lmip.sh.
+ * config/mipsb-elf32.mt (EMUL): Use elf32bmip, not elf32mipb.
+ * config/mipsl-elf32.mt (EMUL): Use elf32lmip, not elf32mipl.
+
+ * genscripts.sh: Always search /usr/local/TARGET/lib.
+
+ * scripttempl/elf.sc: If -N is set, force DATA_ADDR to be ".".
+
+Fri Sep 23 15:05:49 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * configure.in: Handle i386-bsdi* targets like i386-bsd.
+
+Fri Sep 23 00:06:59 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * lexsup.c (parse_args): Add support for -a for HP/UX
+ compatibility.
+
+ * lexsup.c (parse_args): -c takes an argument.
+
+Tue Sep 20 14:35:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ld.h (args_type): Add new field endian.
+ * lexsup.c (parse_args): Handle -EB and -EL by setting
+ command_line.endian.
+ * ldgram.y (ifile_p1): Accept OUTPUT_FORMAT with three arguments.
+ * ldlang.c (lang_add_output_format): Add arguments big and little.
+ If command_line.endian is set, use it to select big or little
+ rather than the default. Changed all callers.
+ * ldlang.h (lang_add_output_format): Update declaration.
+ * emulparams/elf32mipb.sh: Define BIG_OUTPUT_FORMAT and
+ LITTLE_OUTPUT_FORMAT.
+ * emulparams/elf32mipl.sh: Likewise.
+ * emulparams/mipsbig.sh: Likewise.
+ * emulparams/mipsbsd.sh: Likewise.
+ * emulparams/mipsidt.sh: Likewise.
+ * emulparams/mipsidtl.sh: Likewise.
+ * emulparams/mipslit.sh: Likewise.
+ * scripttempl/elf.sc: Define BIG_OUTPUT_FORMAT and
+ LITTLE_OUTPUT_FORMAT if not already defined. Pass them to
+ OUTPUT_FORMAT.
+ * scripttempl/mips.sc: Pass BIG_OUTPUT_FORMAT and
+ LITTLE_OUTPUT_FORMAT to OUTPUT_FORMAT.
+ * scripttempl/mipsbsd.sc: Likewise.
+
+ * Makefile.in (ldgram.h): Make separate target from ldgram.c,
+ depending upon ldgram.c, so that a parallel make does not try to
+ build both at once.
+
+ * configure.in (mips*el-elf*): New target.
+ * Makefile.in (ALL_EMULATIONS): Add eelf32mipb.o and eelf32mipl.o.
+ (eelf32mipl.c): New target.
+
+ * config/mipsl-elf32.mt: New file.
+ * emulparams/elf32mipl.sh: New file.
+
+Fri Sep 16 12:16:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldmain.c (main): Rather than prohibiting ld -r -s, treat it as
+ ld -r -S -x.
+
+Thu Sep 15 13:05:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldmisc.c (vfinfo): Print BFD file name as well as file name
+ returned by find_nearest_line, in case the file name is something
+ unhelpful such as a .h file. Handle %u.
+
+Wed Sep 14 12:49:12 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ldlang.c (lang_do_assignments): Make sure output statement
+ has an attached bfd_section before trying to dereference it.
+
+Wed Sep 14 12:48:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ld.h (ld_config_type): Add new field warn_once.
+ * ldmain.c (undefined_symbol): Handle -warn-once.
+ * lexsup.c (parse_args): Recognize -warn-once.
+ * ld.texinfo (Options): Document -warn-once.
+ * ld.1: Likewise.
+
+ * ldmisc.c (vfinfo): Handle %D as %C, but never print the function
+ name. For %C, print the function name on a separate line, to keep
+ the length of error messages under control.
+ * ldmain.c (multiple_definition): Use %D for ``first defined
+ here.''
+ (undefined_symbol): Use %D for ``more undefined references
+ follow''.
+
+ * ldmisc.c (multiple_warn): Remove; no longer used.
+ * ldmisc.h (multiple_warn): Don't declare.
+
+Tue Sep 13 20:47:58 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ldlang.c (print_output_section_statement): Print all lines
+ to the map file.
+
+Tue Sep 13 16:30:11 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldlang.c (load_symbols): Check for archive before object. Use
+ bfd_check_format_matches, and, if ambiguous, print a list of
+ matching formats. If file format is not recognized, treat file as
+ a linker script.
+ * ldgram.y (yyerror): If assuming an object file is a script,
+ mention that. Tweak the format of the error messages.
+ * ldlex.l (lex_warn_invalid): If assuming an object is a script,
+ guess that this is not actually a script, and just report that the
+ file format was not recognized.
+ * ld.texinfo (Options): Admit that -( may be used more than once.
+ Add note that unrecognized object files are now treated as linker
+ scripts.
+
+ * ldfile.c (ldfile_input_filename): Make const.
+ (ldfile_assumed_script): New variable.
+ (try_open): Change arguments types to const.
+ (ldfile_find_command_file): Likewise.
+ (ldfile_open_command_file): Likewise. Also, set lineno to 1.
+ * ldfile.h: Update declarations for ldfile.c changes.
+ * ldlex.l: Include <ctype.h>.
+ (file_name_stack): Change to be const char *.
+ (lineno_stack): New static variable.
+ (<<EOF>>): Set lineno as well as ldfile_input_filename.
+ (lex_push_file): Make name argument const. Initialize
+ lineno_stack entry.
+ (lex_redirect): Initialize lineno_stack entry.
+ (lex_warn_invalid): Handle non printable characters nicely.
+ * ldlex.h (lex_push_file): Declare second argument as const.
+
+ * ldgram.y (ifile_p1): Recognize GROUP.
+ * ldlex.l: Recognize GROUP.
+ * ld.texinfo (Option Commands): Document GROUP.
+
+Mon Sep 12 17:04:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/m68klynx.mh: New file.
+
+Mon Sep 12 01:50:03 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * emultempl/hppaelf.em: Add newlines to the error messages.
+
+Sat Sep 10 16:05:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/i386lynx.mh: New file.
+ * scripttempl/i386lynx.sc: Don't put .ctors and .dtors in .text
+ unless CONSTRUCTING.
+
+Thu Sep 8 13:25:24 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * emulparams/elf32mipb.sh (TEMPLATE_NAME): Define as elf32.
+ (GENERATE_SHLIB_SCRIPT): Define as yes.
+ (DYNAMIC_LINK): Define as false.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse):
+ Initialize config.dynamic_link to DYNAMIC_LINK if it is defined.
+ (gld${EMULATION_NAME}_place_orphan): Reset stat_ptr at end.
+ * Makefile.in (eelf32mipb.c): Depend upon elf32.em rather than
+ generic.em.
+
+Thu Sep 8 16:30:37 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * scripttempl/h8500b.sc: Put rdata stuff into own segment.
+
+Thu Sep 8 13:25:24 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * emulparams/elf32ppc.sh (OTHER_READWRITE_SECTIONS): Don't define;
+ .got section is now explicitly handled in elf.sc.
+
+Wed Sep 7 13:08:34 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * scripttempl/alpha.sc: Redo script to set . outside of sections
+ and not bother to explicitly specify section addresses.
+ Explicitly place .sdata section.
+
+Tue Sep 6 23:51:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/m68kcoff.sc: Put .bss in data segment.
+
+ * scripttempl/h8300.sc: Change .stab and .stabstr to use a VMA of
+ 0, and to only be marked as NOLOAD if relocating.
+ * scripttempl/h8500.sc, scripttempl/h8500b.sc: Likewise.
+ * scripttempl/h8500c.sc, scripttempl/h8500m.sc: Likewise.
+ * scripttempl/h8500s.sc, scripttempl/i386coff.sc: Likewise.
+ * scripttempl/i386go32.sc, scripttempl/i386lynx.sc: Likewise.
+ * scripttempl/m68kcoff.sc, scripttempl/m68klynx.sc: Likewise.
+ * scripttempl/sh.sc, scripttempl/sparccoff.sc: Likewise.
+ * scripttempl/sparclynx.sc: Likewise.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * Makefile.in, configure.in: Add support (disabled) the ARM/RISCiX.
+ * config/riscix.mt, emulparams/riscix.sh, scripttempl/riscix.sc:
+ New files.
+
+Tue Aug 30 11:48:08 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * ld.h (args_type): Add field soname.
+ * lexsup.c (parse_args): Handle -soname argument.
+ * emultempl/elf32.em: In call to bfd_elf32_size_dynamic_sections,
+ pass soname.
+ * ld.texinfo: Document -soname.
+
+Mon Aug 29 15:21:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldlang.c (lang_check): Don't try to set the architecture if the
+ input and output files are incompatible. Just warn.
+
+Wed Aug 24 12:52:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * configure.in: Change i[34]86 to i[345]86.
+
+Sun Aug 21 16:17:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * emulparams/hp3hpux.sh: Define __DYNAMIC to be 0.
+
+Thu Aug 18 15:37:45 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ Make the ELF linker handle orphaned sections reasonably. Also,
+ define __start_SECNAME and __stop_SECNAME around sections whose
+ names can be represented in C, for the benefit of symbol sets in
+ glibc.
+ * ldemul.h (ldemul_place_orphan): Declare.
+ (ld_emulation_xfer_type): Add place_orphan field.
+ * ldemul.c (ldemul_place_orphan): New function.
+ * ldlang.h (wild_doit): Declare.
+ * ldlang.c (wild_doit): Make nonstatic.
+ (lang_place_orphans): Call ldemul_place_orphan.
+ * emultempl/elf32.em: Include <ctype.h> and "ldgram.h".
+ (hold_section, hold_use, hold_text, hold_data, hold_bss): New
+ static variables.
+ (gld${EMULATION_NAME}_place_orphan): New static function.
+ (gld${EMULATION_NAME}_place_section): New static function.
+ (ld_${EMULATION_NAME}_emulation): Initialize place_orphan field.
+
+Tue Aug 16 00:17:20 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * scripttempl/aout.sc: Add .linux-dynamic after .data.
+
+Tue Aug 16 00:08:22 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * lexsup.c (parse_args) Treat --dll-verbose as --version, for
+ Linux compatibility. From hjl@nynexst.com (H.J. Lu).
+
+Mon Aug 15 17:17:33 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldexp.h (exp_get_abs_int): Declare.
+
+Sat Aug 6 01:45:39 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ldlang.c (lang_do_assignments): Handle complex AT's better.
+ * ldexp.c (exp_get_abs_int): New function.
+
+Fri Aug 5 20:55:55 1994 Jason Molenda (crash@phydeaux.cygnus.com)
+
+ * configure.in: add i960-nindy-coff support.
+
+Thu Aug 4 14:45:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldlex.l (yy_create_string_buffer): Handle change to internal
+ interface in flex 2.4.7.
+
+Tue Aug 2 11:52:06 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * emultempl/linux.em (gld${EMULATION_NAME}_find_address_statement):
+ New function; add 0x20 to any use of -Ttext.
+ (gld${EMULATION_NAME}_create_output_section_statements): New
+ function.
+ (ld_${EMULATION_NAME}_emulation): Use the new function
+ gld${EMULATION_NAME}_create_output_section_statements.
+
+Mon Aug 1 15:50:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * scripttempl/mips.sc: Redo script to set . outside of sections
+ and not bother to explicitly specify section addresses.
+
+Tue Jul 26 11:02:35 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * scripttempl/elf.sc: Copy several more relocation sections into
+ the output. Put .got.plt sections into .got.
+
+Fri Jul 22 12:15:36 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * scripttempl/elf.sc: Use PROVIDE to define etext, edata, and end.
+
+ Add a new script operator, PROVIDE, to define a symbol only if it
+ is needed.
+ * ldgram.y (PROVIDE): New token.
+ (assignment): Accept PROVIDE.
+ * ldlex.l (PROVIDE): New token.
+ * ldexp.h (node_type): Add etree_provide to node_class enum.
+ (exp_provide): Declare.
+ * ldexp.c (exp_fold_tree): Handle etree_provide.
+ (exp_provide): New function.
+ (exp_print_tree): Handle etree_provide.
+ * ld.texinfo: Document PROVIDE.
+
+ * ldlang.c (lang_common): Pass desired alignment to
+ lang_one_common as power of two.
+ (lang_one_common): Get common symbol alignment from linker hash
+ table entry. Treat desired alignment as a power of two.
+
+ * ldlang.c (wild_section): Attach all section with the given name,
+ not just the first one. If there is no name, attach all sections
+ even if the SEC_IS_COMMON flag is set.
+
+Wed Jul 20 15:49:27 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ld.h (args_type): Add field rpath.
+ * lexsup.c (S_ISDIR): Define if not already defined.
+ (parse_args): Add support for -rpath. If -R is used to name a
+ directory, treat it as -rpath for Solaris compatibility.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
+ Pass command_line.rpath to bfd_elf32_size_dynamic_sections.
+ * ldmain.c (main): Initialize command_line.rpath to NULL.
+ * ld.texinfo: Document -rpath option.
+
+Sun Jul 10 00:33:24 1994 Ian Dall (dall@hfrd.dsto.gov.au)
+
+ * emulparams/pc532machaout.sh: New file. Pc532 mach script
+ parameters.
+
+ * emulparams/netbsd532.sh: New file. Netbsd 532 script parameters.
+
+ * config/pc532mach.mt: New file. Pc532 mach target support.
+
+ * config/pc532mach.mh: New file. Pc532 mach host support.
+
+ * config/netbsd532.mt: New file. Netbsd 532 target support.
+
+ * configure.in: Add ns32k-pc532-mach and ns32k-pc532-netbsd support.
+
+ * Makefile.in: Add epcmachaout.c dependency and enetbsd532.c
+ dependency.
+
+Fri Jul 8 10:57:02 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * emultempl/sunos.em (gld${EMULATION_NAME}_before_allocation): Use
+ bfd_abs_section_ptr, not &bfd_abs_section.
+
+ * lexsup.c (parse_args): Changed "retain-symbols-file" from
+ no_argument to required_argument. From djm.
+
+Thu Jul 7 12:29:53 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * scripttempl/elf.sc: Explicitly mention .stab and .stabstr
+ sections to force a VMA of 0; needed for ELF backends which have
+ not been converted to the new linker style.
+
+Mon Jul 4 19:35:45 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * scripttempl/hppaelf.sc (__stack_zero): Don't define this name,
+ it was for the HPUX dynamic loader's use and it creates problems
+ with ELF GDB.
+
+Fri Jul 1 12:53:47 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * ldlang.c (lang_do_assignments): No longer static. Delete decl.
+ * ldlang.h (lang_do_assignments): Put external decl here.
+ * emultempl/hppaelf.em: Minor cleanups throughout file.
+ (hppa_elf_create_output_section_statements): Rewrite.
+ (hppaelf_finish): Rewrite.
+
+Wed Jun 29 16:50:00 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/solaris2.mh (NATIVE_LIB_DIRS): Define as /usr/ccs/lib.
+
+ * lexsup.c (parse_args): Accept -Bstatic and -Bdynamic. Do not
+ accept plain -B.
+ * ld.texinfo: -Bstatic is not ignored.
+
+Tue Jun 28 12:13:34 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * ldlex.l: Recognize \r the same as \n.
+
+Thu Jun 23 17:53:04 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ Preliminary support for generating shared libraries, from Eric
+ Youngdale <ericy@cais.cais.com>.
+ * genscripts.sh: If the emulation parameter file sets
+ GENERATE_SHLIB_SCRIPT, generate a .xs script file with
+ CREATE_SHLIB defined.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_get_script): If
+ link_info.shared is set, use the .xs script file.
+ * scripttempl/elf.sc: If CREATE_SHLIB is set, don't create a
+ .interp section, and don't include TEXT_START_ADDR in the starting
+ address of the first section.
+ * emulparams/elf_i386.sh (GENERATE_SHLIB_SCRIPT): Likewise.
+ * emulparams/elf32_sparc.sh (GENERATE_SHLIB_SCRIPT): Define.
+
+Thu Jun 23 12:52:22 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.in: Change --with-targets to --enable-targets.
+
+Wed Jun 22 13:42:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * lexsup.c (parse_args): Add support for new options -( -) with
+ synonyms --start-group --end-group.
+ * ldlang.h (enum statement_enum): Add lang_group_statement_enum.
+ (lang_group_statement_type): Define new struct.
+ (lang_statement_union_type): Add group_statement field.
+ (lang_enter_group, lang_leave_group): Declare.
+ * ldlang.c (lang_for_each_statement_worker): Handle
+ lang_group_statement_enum.
+ (map_input_to_output_sections, print_statement): Likewise.
+ (lang_size_sections, lang_do_assignments): Likewise.
+ (open_input_bfds): Completely rewrite. Now does its own looping,
+ rather than using lang_for_each_statement. Handle groups.
+ (lang_process): Update call to open_input_bfds.
+ (print_group): New static function.
+ (lang_enter_group, lang_leave_group): New static functions.
+ * ldfile.c (ldfile_open_file): If the file has already been
+ opened, just return rather than taking an assertion failure.
+ * ldver.c (help): Mention new options.
+ * ld.texinfo: Document new options.
+
+ * ldlang.c (end_of_data_section_statement_list): Don't define.
+ (lang_leave_output_section_statement): Don't set obsolete variable
+ end_of_data_section_statement_list.
+
+ * scripttempl/go32coff.sc: Don't put ${DATA_ALIGNMENT} inside an
+ ALIGN.
+
+ * ldlang.c (lang_size_sections): Adjust current region address
+ even for sections with an explicit address. From
+ ralphc@pyramid.com (Ralph Campbell).
+
+ * emulparams/i386linux.sh (NONPAGED_TEXT_START_ADDR): Set to 0.
+ From jrs@world.std.com (Rick Sladkey).
+
+ * scripttempl/mipsbsd.sc: Let sections align to their natural
+ boundaries.
+
+Tue Jun 21 11:27:04 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ldlang.c (lang_init): Use new bfd_abs_section_ptr, not
+ &bfd_abs_section.
+ (lang_abs_symbol_at_beginning_of): Likewise.
+ (lang_abs_symbol_at_end_of): Likewise.
+ (lang_size_sections): Use bfd_is_abs_section to check for the
+ absolute section. Don't try to set the VMA or output_offset or
+ size of the absolute section.
+ * ldmain.c (notice_ysym): Use bfd_is_und_section to check for the
+ undefined section.
+
+Thu Jun 16 22:48:41 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * scripttempl/hppaelf.sc: Place .data and .bss at 0x40000000
+ when generating relocatable objects.
+
+Thu Jun 16 14:25:22 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * emultempl/linux.em: New file providing support for linking
+ against Linux shared libraries.
+ * config/i386-linux.mt (ei386linux.c): Depend upon linux.em.
+ * emulparams/i386linux.sh (TEMPLATE_NAME): Define as linux.
+
+Thu Jun 16 12:22:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * lexsup.c (parse_args): Add -shared to longopts, and handle it.
+ * ldmain.c (main): Initialize link_info.shared to false. Give
+ error if link_info.relocateable and link_info.shared are both set.
+
+ * configure.in: If EMUL_EXTRA* is defined in a config file, treat
+ it as naming an emulation to be added to EMULATION_OFILES.
+ * config/i386-linux.mt (EMUL_EXTRA1): Define as elf_i386.
+
+ * Makefile.in: Rebuilt dependencies.
+ (ALL_EMULATIONS): Add ei386linux.o, eelf32_sparc.o,
+ eelf64_sparc.o. Remove $(OTHER_EMULATIONS).
+ (ei386linux.c, eelf32_sparc.c, eelf64_sparc.c): New targets.
+ * config/i386-linux.mt (OTHER_EMULATIONS): Don't define.
+ (ei386linux.c): Remove; now in Makefile.in.
+ * config/i386-lynx.mt (OTHER_EMULATIONS): Don't define.
+ * config/m68k-lynx.mt (OTHER_EMULATIONS): Don't define.
+ * config/sparc-lynx.mt (OTHER_EMULATIONS): Don't define.
+ * config/sparc64-elf.mt (OTHER_EMULATIONS): Don't define.
+ (eelf64_sparc.c): Remove; now in Makefile.in.
+ * config/sun4sol2.mt (OTHER_EMULATIONS): Don't define.
+ (eelf32_sparc.c): Remove; now in Makefile.in.
+
+ * ldexp.c (exp_print_tree): Don't crash if etree_rel section has
+ no owner--it might be bfd_abs_section. From Eric Youngdale
+ <ericy@cais.cais.com>.
+
+ * scripttempl/aout.sc: Let sections align to their natural
+ boundaries.
+
+Wed Jun 15 01:54:54 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldemul.h (ldemul_open_dynamic_archive): Declare.
+ (ld_emulation_xfer_type): Add new field open_dynamic_archive.
+ * ldemul.c: Include ldexp.h and ldlang.h.
+ (ldemul_open_dynamic_archive): New function.
+ * ldfile.h (ldfile_open_file_search): Declare.
+ * ldfile.c: Include ldemul.h.
+ (try_open_bfd): Rename from cache_bfd_openr. Return boolean
+ argument, not bfd *. Change all callers.
+ (ldfile_open_file_search): Rename from open_a. Return boolean
+ argument, not bfd *. Clean up. Change all callers.
+ (ldfile_open_file): If doing a dynamic link, call
+ ldemul_open_dynamic_archive rather than assuming the extension of
+ a dynamic object is ".so".
+ * emultempl/elf32.em (gld${EMULATION_NAME}_open_dynamic_archive):
+ New function.
+ (ld_${EMULATION_NAME}_emulation): Initialize open_dynamic_archive
+ field.
+ * emultempl/sunos.em (ld_${EMULATION_NAME}_emulation): Likewise.
+
+ * ldmain.c (get_emulation): Ignore -m486 for Linux compatibility.
+ * lexsup.c (parse_args): Ignore -qmagic for Linux compatibility.
+ Accept -static as a synonym for -non_shared.
+
+ Let the user change the dynamic linker used by ELF code.
+ * ld.h (args_type): Add new field interpreter.
+ * lexsup.c (parse_args): Add dynamic-linker to longopts, and
+ handle it.
+ * ldmain.c (main): Initialize command_line.interpreter to NULL.
+ * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Get
+ the ELF backend to return the .interp section. If
+ command_line.interpreter is not NULL, set the contents of .interp
+ to it.
+ * ld.texinfo: Mention -dynamic-linker.
+
+ * config/sun4sol2.mt (eelf32_sparc.c): Depend upon elf32.em, not
+ generic.em.
+
+ * lexsup.c (parse_args): Sort out the option macros and change the
+ definitions to make it easier to add a new option.
+
+ * scripttempl/aout.sc: Define __etext and __edata to go along with
+ _etext and _edata.
+
+ * ld.h (ld_config_type): Add new field traditional_format.
+ * lexsup.c (parse_args): Add traditional-format to longopts, and
+ handle it.
+ * ldmain.c (main): Initialize config.traditional_format to false.
+ * ldlang.c (ldlang_open_output): Set BFD_TRADITIONAL_FORMAT in BFD
+ flags of output_bfd according to config.traditional_format.
+ * ldver.c (help): Mention -traditional-format.
+ * ld.texinfo: Document -traditional-format.
+
+Tue Jun 14 23:10:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldctor.c (ldctor_add_entry): Add entries to a set in the order
+ they are encountered.
+
+Tue Jun 14 18:05:09 1994 Eric Youngdale (ericy@cais.cais.com)
+
+ * emulparams/i386linux.sh (TEXT_START_ADDR): Define as 0x1000.
+ (NONPAGED_TEXT_START_ADDR): Define as 0x20.
+
+Mon Jun 13 15:46:09 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/alpha.sc: Define _ftext, _etext and _fdata insted of
+ _FTEXT, _ETEXT and _FDATA. Dont define _END.
+
+ * ldfile.c (open_a): If this is not an archive, try to open it in
+ the current directory before searching for it.
+
+ * lexsup.c (parse_args): Treat -i as a synonym for -r.
+
+ * ldgram.y (exp): Treat BLOCK as a synonym for ALIGN, so that
+ BLOCK works in a section address as documented.
+
+ * ldgram.y (YYDEBUG): Don't define.
+
+Fri Jun 10 16:45:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * emultempl/gld960.em: Pass false for new argument to
+ ldfile_add_library_path.
+ * emultempl/gld960c.em, emultempl/lnk960.em: Likewise.
+
+ * emultempl/sunos.em: Only look for .so files if doing a dynamic
+ link.
+
+Thu Jun 9 08:35:17 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * scripttempl/i960.sc: Add CONSTRUCTORS to .data.
+
+Thu Jun 9 06:52:29 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in (check): Delete ld.new dependency so that a regression
+ test doesn't trigger a rebuild of the linker.
+
+Thu Jun 9 00:17:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (map_input_to_output_sections): For lang_address, call
+ init_os if it hasn't already been called.
+
+Thu Jun 2 17:24:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add support for SunOS shared libraries.
+ * aout.sc: Don't define __DYNAMIC here. Add new sections used by
+ shared library support code.
+ * emultempl/sunos.em: New file.
+ * emulparams/sun4.sh (TEMPLATE_NAME): Define as sunos.
+ * emulparams/sun3.sh (TEMPLATE_NAME): Likewise.
+ * Makefile.in (esun4.c): Depend upon sunos.em, not generic.em.
+ (esun3.c): Likewise.
+
+ * ldlang.c: Minor formatting cleanups.
+ (lang_for_each_input_file): New function.
+ * ldlang.h (lang_for_each_input_file): Declare.
+
+ * ldfile.h (search_dirs_type): Move from ldfile.c, and add cmdline
+ field.
+ (search_head): Declare.
+ (ldfile_add_library_path): Add new cmdline argument in prototype.
+ * ldfile.c (search_head): Make non-static.
+ (search_dirs_type): Move to ldfile.h.
+ (ldfile_add_library_path): Accept cmdline argument, and save it.
+ * lexsup.c (parse_args): Pass true for new cmdline argument of
+ ldfile_add_library_path.
+ (set_default_dirlist): Likewise.
+ * ldmain.c (check_for_scripts_dir): Pass false for new cmdline
+ argument of ldfile_add_library_path.
+ * ldgram.y (ifile_p1): Likewise.
+
+Wed Jun 1 14:24:08 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.h (lang_input_statement_type): Remove fields subfiles,
+ total_size, superfile and chain.
+ * ldfile.c (open_a): Don't clear search_dirs_flag.
+ (ldfile_open_file): Don't try to open superfile. Assert that file
+ has not already been opened.
+ * ldlang.c (new_afile): Don't initialize superfile.
+ * ldmain.c (add_archive_element): Don't initialize subfiles or
+ chain or superfile. Initialize search_dirs_flag to false.
+
+Fri May 27 12:25:33 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ldver.c (ldversion): Changed version to "cygnus-2.4.1".
+
+ Changes from binutils-2.4 release:
+
+ * genscripts.sh (RELOCATING, CONSTRUCTING): When setting
+ variables, use whitespace, so scripts don't break.
+
+ * config/alphaosf.mh (HDEFINES, CFLAGS): Deleted.
+
+ * emultempl/generic.em: Find emultempl/stringify.sed in ${srcdir}.
+
+ * cdtest-bar.cc: Renamed from cdtest-func.cc.
+ * Makefile.in: Noted change.
+
+ * scripttempl/a29k.sc: Don't include /lab3/u3/..../segments.o; I
+ don't know where that's supposed to come from, or why it's
+ necessary.
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: update to latest makefile.in
+ * emulpara/go32.sh: set to coff-go32 not aout
+ * emultemp/generic.em: strength-reduce the structure of
+ this shell script, since the only available shell for
+ DOS can't handle complex syntax.
+ * emultemp/stringify.sed: for "sed -f" instead of inline.
+ * makefile.in: depend on stringify.sed as well as genscripts.sh
+ * scripttemp/go32coff.sc: correct for djgpp 1.11's COFF format
+ * genscripts.sh: empty variables aren't always considered "set",
+ so set them to "y" instead.
+
+Fri May 27 01:08:14 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (entry_symbol): Make static.
+ (lang_add_entry): Add cmdline argument.
+ * ldlang.h (lang_add_entry): Change prototype.
+ * ldgram.y (statement_anywhere): Change lang_add_entry call.
+ * lexsup.c (parse_args): Likewise.
+
+Tue May 24 16:13:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * emulparams/elf32mipb.sh (OTHER_READONLY_SECTIONS): Don't give
+ .reginfo an address.
+ (OTHER_READWRITE_SECTIONS): Don't give .lit4 or .lit8 an address.
+ (OTHER_SECTIONS): Define for .gptab.sdata and .gptab.sbss.
+ * scripttempl/elf.sc: Use OTHER_SECTIONS at end of script.
+
+Thu May 19 13:31:33 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Add support for ELF shared libraries.
+ * ld.h (ld_config_type): Add field dynamic_link.
+ * ldmain.c (main): Initialize config.dynamic_link to false. Warn
+ on attempts to use -r with -relax, -call_shared or -s.
+ * lexsup.c (longopts): Separate OPTION_CALL_SHARED from
+ OPTION_NON_SHARED. Add OPTION_IGNORE. Adjust macro values
+ accordingly. Add "dy" and "non_shared" options. Change "Qy" to
+ OPTION_IGNORE for now. Handle OPTION_CALL_SHARED and
+ OPTION_NON_SHARED by setting dynamic_link field accordingly.
+ Handle OPTION_IGNORE by ignoring it. Clear dynamic_link field for
+ -r and -Ur.
+ * ldfile.c (ldfile_open_file): If config.dynamic_link is true, try
+ opening a file with a .so extension first.
+ * emultempl/elf32.em: New file.
+ * emulparams/elf32_sparc.sh (TEXT_START_ADDR): Change to 0x10000.
+ (NONPAGED_TEXT_START_ADDR): Likewise.
+ (TEMPLATE_NAME): Define as elf32.
+ (DATA_PLT): Define.
+ * emulparams/elf_i386.sh (TEMPLATE_NAME): Define as elf32.
+ * scripttempl/elf.sc: Add placement for new dynamic sections.
+ Don't use CREATE_OBJECT_SYMBOLS. Define _etext, _edata and _end
+ outside of any section. Don't use ALIGN(8); just let one section
+ VMA follow another. Put .dynbss in .bss. Don't mention debugging
+ sections; they'll be handled correctly anyhow.
+ * Makefile.in (eelf_i386.c): Depend upon elf32.em, not generic.em.
+
+Wed May 18 10:15:39 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): Redirect output of ln to /dev/null.
+
+Mon May 16 13:35:08 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * emultempl/hppaelf.em: Change all references of
+ .hppa_linker_stubs to .PARISC.stubs.
+ * scripttempl/hppaelf.sc: Likewise.
+
+Fri May 13 13:00:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (print_output_section_statement): Change ``no attached
+ output section'' message slightly.
+ (lang_do_assignments): Don't recurse down if there is no real
+ section.
+
+ * config/i386-linux.mt (OTHER_EMULATIONS): Change em_ to e to
+ match corresponding change in emulation templates.
+ * config/i386-lynx.mt, config/m68k-lynx.mt: Likewise.
+ * config/sparc-lynx.mt, config/sun4sol2.mt: Likewise.
+
+Wed May 11 18:16:46 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ldver.c (ldversion): Updated version number.
+
+ * cdtest-foo.cc: Use explicit "#pragma implementation".
+ * cdtest-bar.cc: Renamed from cdtest-func.cc.
+ * Makefile.in: References to cdtest-func.o changed to
+ cdtest-bar.o.
+
+Wed May 11 16:24:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Don't create unnecessary output sections.
+ * ldlang.c (out_bfd_get_section_by_name): Remove.
+ (wild_section): Call bfd_get_section_by_name rather than
+ our_bfd_get_section_by_name. Don't call wild_doit if there is no
+ section.
+ (lang_create_output_section_statements): Remove.
+ (map_input_to_output_sections): For several cases, call init_os if
+ it has not already been called.
+ (lang_size_sections): If output section was not created, skip it.
+ (lang_process): Don't call lan_create_output_section_statements.
+ (lang_place_orphans): Skip files with just_syms_flags set to true.
+ * ld.texinfo: Document change.
+
+Tue May 10 14:31:16 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (wild_doit): Don't bother initializing the vma and
+ section size. Don't special case SEC_SHARED_LIBRARY.
+ (lang_size_sections): Handle SEC_COFF_SHARED_LIBRARY sections
+ specially.
+
+Fri May 6 12:24:27 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config/go32.mh : New file for Xgo32X.
+
+Fri May 6 15:15:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldfile.c (ldfile_open_command_file): Set bfd_error_system_call
+ before calling einfo, since we are reporting an fopen failure.
+ From jrs@world.std.com (Rick Sladkey).
+
+ * configure.in: Use "e" rather than "em_" as prefix for
+ emulations.
+
+Fri May 6 01:08:14 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ * emultempl/generic.em: Use "e" rather than "em_" as prefix for
+ filename.
+ * emultempl/gld960.em, emultempl/gld960c.em, emultempl/lnk960.em,
+ emultempl/hppaelf.em, emultempl/m88kbcs.em, emultempl/vanilla.em:
+ Ditto.
+ * Makefile.in: Changed all generated file names.
+ (ldemul-list.h): Depend on Makefile, not config.status. Changed
+ sed patterns to handle new filenames.
+
+ * config/mipsl-idt.mt: Renamed from mips-idtl.mt.
+ * configure.in: Adjusted.
+
+Thu May 5 15:07:32 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (install-info): Don't use "$<*", it doesn't always
+ work. Instead, check build dir and $srcdir explicitly, and use
+ `echo' to get all the filenames.
+
+ * configure.in (h8300h-*-hms): Changed ld_target name to
+ cf-h8300h.
+ * config/cf-h8300h.mt: Renamed from coff-h8300h.mt, to make it
+ unique in 8.3.
+
+ * config/i960coff.mt: New file.
+ * emulparams/gld960coff.sh: New file.
+ * emultempl/gld960c.em: New file.
+ * configure.in (i960-*-vxworks5* except -vxworks5.0*): Use
+ i960coff configuration.
+ * Makefile.in (em_gld960coff.c): Added dependencies, build rule.
+
+ * Makefile.in (ALL_EMULATIONS): Remove em_delta68.o, since the
+ code isn't included in FSF releases, and it can still be
+ explicitly selected.
+ (distclean): Remove site.bak and tmpdir.
+ (STAGESTUFF): Removed $(GENERATED_CFILES) $(GENERATED_HFILES).
+ (mostlyclean): Delete them explicitly here. Also remove tmpdir.
+
+ Patches from Ralph Campbell:
+ * config/mipsbsd.mh: New file.
+ * Makefile.in (em_mipsbsd.c): Use mipsbsd.sc, not aout.sc.
+ * scripttempl/mipsbsd.sc: Don't define __DYNAMIC.
+ * emulparams/mipsbsd.sh (OUTPUT_FORMAT): Fix name to have `a.out'
+ instead of `aout'.
+
+ * configure.in (i386-*-gnu*): Treat like i386-*-mach*.
+
+Wed May 4 11:59:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * config/m68k.mt (EMUL): Set to m68kaout.
+ * emulparams/m68kaout.sh: New file.
+ * Makefile.in (ALL_EMULATIONS): Add em_m68kaout.o.
+ (em_m68kaout.c): New target.
+
+ * ldlang.c (lang_size_sections): If dot moves because of an
+ assignment, don't try to insert a pad into the absolute output
+ section, just change the address of the default memory region
+ instead.
+
+ * Makefile.in (mostlyclean): Remove cdtest.tmp, cdtest-ur,
+ cdtest-ur.out, and cdtest-ur.tmp.
+
+Wed Apr 27 16:03:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/sa29200.sc: Align all sections to four byte
+ boundaries.
+
+Wed Apr 27 10:48:03 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in, configure.in: Support for go32 coff.
+ * config/i386-go32.mt: New file
+ * emulparams/i386go32.sh: New file
+ * scripttempl/i386go32.sc: New file
+
+Tue Apr 26 17:20:03 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (em_m68klynx.c, em_i386lynx.c, em_sparclynx.c): Use
+ Lynx-specific script templates.
+ * configure.in (sparclite*-*-coff): Use coff-sparc.
+ * emulparams/i386lynx.sh (SCRIPT_NAME): Set to i386lynx.
+ * emulparams/sparclynx.sh (SCRIPT_NAME): Set to sparclynx.
+ (ENTRY): Set to __main.
+ * scripttempl/i386lynx.sc: New file, script for I386 Lynx.
+ * scripttempl/m68klynx.sc: Add insertion of ctor/dtor sections.
+ * scripttempl/sparclynx.sc: New file, script for uSparc Lynx.
+
+Tue Apr 26 12:41:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/mips.sc: Force _gp and .lit8 to be aligned to a 16
+ byte boundary, in case the global constructors do not take up an
+ even 16 bytes.
+
+ * config/i386v4.mh (HOSTING_CRT0): If ../gcc/crtbegin.o does not
+ exist, get crtbegin based on gcc -print-libgcc-file-name.
+ (HOSTING_LIBS): Similar change for ../gcc/crtend.o.
+
+Mon Apr 25 15:27:52 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (lang_size_sections): When no address is given for a
+ section, align it according to its requirements.
+
+Thu Apr 21 17:24:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (clean, distclean): Remove configdoc.texi.
+
+Tue Apr 19 12:12:15 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * configure.in: Add i[34]86-*-bsd386 to the patterns recognized.
+
+Fri Apr 15 14:35:42 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (lang_size_sections): When relaxing, adjust the
+ position of a padding statement, and adjust dot accordingly.
+
+Mon Apr 11 17:37:09 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in (EXPECT, RUNTEST): Set these for the check goal.
+
+Mon Apr 11 12:32:57 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/i386coff.sc: If relocating, don't put .init and
+ .fini sections into .text; keep them separate.
+ * config/i386sco.mh (HOSTING_CRT0): If ../gcc/crtbegin.o does not
+ exist, get crtbegin based on gcc -print-libgcc-file-name.
+ (HOSTING_LIBS): Similar change for ../gcc/crtend.o.
+
+Mon Apr 11 10:31:00 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * Makefile.in (check): Set TCL_LIBRARY for runtest.
+
+Wed Apr 6 00:09:37 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * configure.in (hppa*-*-*elf*): Don't require "-hp-" for the
+ manufacturer.
+
+ * emultempl/hppaelf.em (hppaelf_finish): Only resize sections
+ if building a final executable.
+
+Tue Apr 5 12:17:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (main): Check the return value of bfd_close.
+
+Thu Mar 31 18:07:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/alpha.sc: Clean up section alignment to ensure that
+ sections never overlap when using -r.
+
+Wed Mar 30 15:51:15 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmisc.c (vfinfo): Change symbol reading slightly for recent BFD
+ changes: get_symtab_upper_bound renamed and returns long,
+ bfd_canonicalize_symtab returns long, check for error indications.
+
+Fri Mar 25 17:20:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (print_input_section): For section size, use
+ _cooked_size if it is non-zero, size otherwise.
+ (size_input_section): Likewise.
+ (lang_do_assignments): Likewise (case lang_input_section_enum).
+
+Thu Mar 24 15:20:47 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (new_afile): Add new argument add_to_list. Don't set
+ real to true for lang_input_file_is_marker_enum. Clear the_bfd.
+ (lang_add_input_file): Pass true to new_afile for add_to_list.
+ (lookup_name): Remove force_load argument. Changed all callers.
+ Pass false to new_afile for add_to_list. Split loading of symbols
+ out into separate function.
+ (load_symbols): New function split out of lookup_name. Don't load
+ the symbols if they are already loaded.
+ (open_input_bfds): For lang_input_statement_enum call load_symbols
+ rather than lookup_name.
+ (lang_process): Pass abs_output_section rather than NULL to
+ lang_size_sections.
+ (lang_startup): Set real field of first_file to true.
+
+Wed Mar 23 14:15:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (had_relax): Removed.
+ (relax_again): New static variable.
+ (lang_size_sections): Change call to bfd_relax_section to
+ correspond to BFD changes. Set relax_again appropriately.
+ (lang_process): Remove #if 0 code. When relaxing, keep calling
+ lang_do_assignments and lang_size_sections until relax_again
+ becomes false.
+
+ * emultemp/gld960.em: Include libiberty.h
+ (gld960_before_parse): Pass NULL as final argument to concat.
+
+Tue Mar 22 13:08:28 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/aout.sc: Force _end and __end to be aligned to a
+ four byte boundary.
+
+ * ldwrite.c (build_link_order): Handle lang_data_statement_enum by
+ building a bfd_data_link_order, rather than by setting the section
+ contents immediately.
+
+Mon Mar 21 18:28:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Changes to make -Ur work again.
+ * ldmain.c (add_to_set): Now takes reloc argument rather than
+ bitsize. Check config.build_constructors here. If an new hash
+ table entry is created, mark it as undefined.
+ (constructor_callback): No longer takes bitsize argument. Pass
+ BFD_RELOC_CTOR to ldctor_add_set_entry, but first make sure the
+ BFD backend supports it.
+ (reloc_overflow): Handle a NULL abfd argument.
+ (reloc_dangerous, unattached_reloc): Likewise.
+ * ldctor.c: Include ldmain.h.
+ (struct set_info): Change bitsize field to reloc.
+ (ldctor_add_set_entry): Now takes reloc argument rather than
+ bitsize. Don't bother to check config.build_constructors here.
+ (ldctor_build_sets): Get the size from the reloc howto. If
+ generating relocateable output, call lang_add_reloc rather than
+ lang_add_data.
+ * ldctor.h (ldctor_add_set_entry): Change declaration to use reloc
+ instead of bitsize.
+ * ldlang.h (statement_enum): Add lang_reloc_statement_enum.
+ (lang_reloc_statement_type): New structure.
+ (lang_statement_union_type): Add reloc_statement field.
+ (lang_add_reloc): Declare new function.
+ * ldlang.c (lang_for_each_statement_worker): Handle
+ lang_reloc_statement_enum.
+ (map_input_to_output_sections, print_statement): Likewise.
+ (lang_size_sections, lang_do_assignments): Likewise.
+ (print_reloc_statement): New function.
+ (lang_add_reloc): New function.
+ * ldwrite.c (build_link_order): Handle lang_reloc_statement_enum.
+
+ * Makefile.in (cdtest.out, cdtest-ur.o): New targets.
+ (cdtest-ur, cdtest-ur.out): New targets.
+ (check-cdtest): Now also check that -Ur works correctly.
+
+ * scripttemp/alpha.sc: Align all sections to 16 byte boundaries.
+
+Thu Mar 17 12:45:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (lang_process): Move lang_common call before
+ map_input_to_output_sections, to ensure that any alignment
+ constraints set by common symbols are copied over to the output
+ sections.
+
+Fri Mar 11 22:17:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * emulparams/elf32ppc.sh (TEMPLATE_NAME): Don't define.
+ (OTHER_READWRITE_SECTIONS): Rename .toc to .got.
+ * Makefile.in (em_elf32ppc.c): Depend upon generic.em, not ppc.em.
+ * emultempl/ppc.em: Remove ugly stub code; turns out not to be
+ needed for ELF.
+
+Tue Mar 8 04:22:27 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * config/i386bsd.mh: New file.
+
+Mon Mar 7 15:23:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf.sc: Permit TEXT_START_SYMBOLS and DATA_START_SYMBOLS to be
+ defined.
+ * emulparams/elf32mipb.s (TEXT_START_SYMBOLS): Define _ftext.
+ (DATA_START_SYMBOLS): Define _fdata.
+
+Mon Feb 28 10:59:14 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * ldlang.c (cat): Define using ANSI style if ALMOST_STDC defined.
+
+Sun Feb 27 16:29:38 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * emultempl/hppaelf.em (hppaelf_finish): Update comments. This
+ works again. Attach some output symbols to the stub file bfd.
+
+ * emultempl/hppaelf.em: Include elf32-hppa.h.
+ (file_chain): Add decl.
+ (hppa_look_for_stubs_in_section): Delete decl.
+ (hppaelf_finish): Reenable code. Do not pass symbols
+ down to hppa_look_for_stubs_in_section.
+
+Sat Feb 26 10:58:25 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldmain.c (write_map): Don't define. Removed all references.
+ Just use map_file or map_filename instead.
+ (add_archive_element): Use minfo to write map information, not
+ info_msg.
+ (constructor_callback): Use fprintf to write map information, not
+ info_msg.
+ * ldmain.h (write_map): Don't declare.
+ * ldgram.y (mri_script_command): Removed reference to write_map.
+ * ldlang.c (lang_one_common): Likewise.
+ * lexsup.c (parse_args): Likewise.
+
+Fri Feb 25 19:12:03 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * scripttempl/elf.sc: Force all sections to be aligned.
+
+ * ldgram.y (section): Reverse the order of memspec_opt and
+ fill_opt to avoid an ambiguity when both are used.
+ * ld.texinfo: Changed accordingly.
+
+ * ldgram.y: Move include of ldlex.h back with other includes.
+ * ldlex.h (input_type): Don't initialize enum constants to
+ particular values.
+ * ldlex.l: Use a switch to return the right token based on
+ input_type, rather than knowing that input_type has a value based
+ on a token type.
+
+ * ldgram.y (dirlist_ptr): Removed; not used.
+ * lexsup.c: Include ldver.h.
+ * Makefile.in: Rebuilt dependencies.
+
+Fri Feb 25 18:55:54 1994 Ted Lemon (mellon@pepper.ncd.com)
+
+ * ldlang.c (lookup_name): don't call bfd_set_gp_size.
+ (ldlang_add_file): call it here instead.
+
+Fri Feb 25 18:13:46 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * ldgram.y: Include ldlex.h after %token decls, for byacc.
+
+Fri Feb 25 10:47:25 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * emultempl/hppaelf.em: First attempt to clean this file up.
+ Add comments in several functions as to their purpose and
+ how they function (or my current best guess). Clean up horrible
+ spacing and indention that never should have been accepted in the
+ first place. Add FIXMEs for issues which need to be resolved.
+ Disable linker-stub generation until it gets fixed. This allows
+ the linker to at least work on simple code for testing purposes.
+
+ * ldlang.c (lang_size_sections): No longer static (PA ELF calls
+ it via hppaelf_finish). Prototype moved into ldlang.h.
+ (lang_process): Move problematic extra call to lang_size_sections
+ into the PA ELF specific code.
+ * emultempl/hppaelf.em (hppaelf_finish): Extra call to
+ lang_size_sections moved here.
+
+Thu Feb 24 16:47:33 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (powerpc-*-elf*): New target; use ppc-elf32.
+ * config/ppc-elf32.mt: New file.
+ * emulparams/elf32ppc.sh: New file.
+ * emultempl/ppc.em: New file.
+ * Makefile.in (ALL_EMULATIONS): Added em_elf32ppc.o.
+ (em_elf32ppc.c): New target; uses elf32ppc.sh, ppc.em and elf.sc.
+ (EMULATION_OFILES): Added dependencies on ldexp.h and ldlang.h.
+
+Thu Feb 24 12:27:07 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * lexsup.c (parse_args): Use symbolic numbers for long options.
+ Fix misunderstanding in -Y and -call_shared et al.
+
+ Use getopt instead of lex and yacc to parse the command line.
+
+ * ld.texinfo (Options): Document changes to option syntax.
+ * Makefile.in: Update dependencies.
+ * ldver.c (help): Tweak dashes in usage message.
+ * ldgram.y (%union): Remove unused members.
+ Remove %tokens for command line options; add ones for input types.
+ (command_line): Rules removed.
+ (file): Instead of command line, recognize an
+ input type indicator, then use the nonterminal for that type.
+ (defsym_expr): New nonterminal from code formerly in command_line.
+ * ldlex.h: Declare parser input type enum and variable.
+ Don't declare parse_line.
+ * ldlex.l: Remove unused variables. Make some used ones static
+ and comment them.
+ (COMMAND): Start state and its rules removed.
+ At start of yylex, return input state token if at start of input.
+ (lex_redirect): Don't need to set yyout.
+ (ldlex_command): Function removed.
+ * ldmain.c (main): Instead of calling parse_line, set up the
+ redirections and call yyparse directly.
+ * ldmisc.c (vfinfo): If there's no input filename, print nothing, not
+ "command line".
+ * lexsup.c: Remove #if 0'd code.
+ (parse_line): Function removed.
+ (parse_args): Rewrite to use getopt_long_only.
+ (set_default_dirlist): New function from code formerly in
+ ldgram.y:command_line.
+ (set_section_start): New function.
+ * emultempl/generic.em, emultempl/gld960.em, emultempl/hppaelf.em,
+ emultempl/lnk960.em, emultempl/m88kbcs.em: Don't enclose
+ compiled-in link scripts in "{" and "}", as the grammar no longer
+ wants them to be.
+
+Thu Feb 24 08:43:26 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * Makefile.in (ld.dvi): Depend on configdoc.texi, but don't
+ require that it be in $(srcdir).
+
+Tue Feb 22 09:21:18 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (lang_size_sections): Only align section to alignment
+ required by linker script, not to maximum alignment of input
+ sections.
+
+ * ldlang.h (largest_section): Don't declare.
+ * ldlang.c (largest_section): Don't define.
+ (size_input_section): Don't set largest_section; not used.
+
+Mon Feb 21 15:15:29 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (new_afile): Pass NULL as last argument to concat.
+
+Thu Feb 17 15:51:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c, ldmain.c: Include libiberty.h.
+
+ * ldmisc.h (concat): Don't declare.
+ * ldmisc.c (concat): Don't define; just use the one in libiberty.
+
+ * ld.h (as_output_section_statement): Removed; not used.
+
+Thu Feb 17 09:32:14 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldlang.c, ldmain.c, ldmisc.c: Use bfd_get_error and
+ bfd_set_error and new error names.
+
+Tue Feb 15 20:14:53 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ldwrite.c (build_link_order): If the cooked size of the section
+ has been set, use it, for determining link_order size.
+ (ldwrite): In the error message displayed if bfd_final_link fails,
+ indicate that it was in fact the final link step that failed.
+
+ * ldlang.c (lang_size_sections): Clear bfd_error before calling
+ bfd_relax_section, in case it returns false but doesn't flag an
+ error. If an error is returned, indicate which one it is in the
+ error message.
+
+ * Makefile.in (install-info): Depend on ld.info, and use "$<*" so
+ it'll get picked up from $(srcdir) if appropriate.
+
+Tue Feb 15 16:32:04 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * scripttempl/aout.sc: Only pad .text if PAD_TEXT is set.
+ * emulparams/i386mach.sh (PAD_TEXT): Set PAD_TEXT.
+
+Fri Feb 11 17:02:49 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldlex.l (comment): Increment line number when newline is read.
+
+Fri Feb 11 17:36:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (lookup_name): Take new argument, force_load. If true,
+ reload the file even if it is already loaded.
+ (wild): Call lookup_name with force_load argument of 0.
+ (open_input_bfds): Call lookup_name with force_load argument of 1.
+ (print_symbol): Remove declaration of non-existent function.
+ (print_one_symbol): Return true rather than falling off end.
+
+Thu Feb 10 11:52:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (main): Use %ld when printing long values.
+
+ * scripttempl/elf.sc: Move _edata after the .sdata section.
+ Permit OTHER_BSS_SYMBOLS to be defined.
+ * emulparams/elf32mipb.s (OTHER_BSS_SYMBOLS): Define _fbss.
+
+Mon Feb 7 16:31:15 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * Rename all "hppaosf" files to "hppaelf".
+ * Change all "osf" references to "elf" in hppaelf files.
+ * Makefile.in: Likewise.
+ * configure.in: Likewise.
+
+Sun Feb 6 20:31:56 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldmain.c (main): Call xatexit, not atexit.
+ Call xmalloc_set_program_name.
+
+ * ldlang.c (lang_size_sections): Check if bfd_relax_section set
+ bfd_errno.
+
+Sat Feb 5 03:54:34 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * emultempl/lnk960.em (append), emultempl/hppaosf.em
+ (hppaosf_finish): Call xmalloc, not ldmalloc.
+ * ldmain.c (preserve_output): Function removed.
+ (main): Do it here instead.
+
+Fri Feb 4 23:02:19 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * ldlang.h (LANG_FOR_EACH_{INPUT,OUTPUT}_SECTION): Delete (unused)
+ GNU C specific macros.
+
+ * emultempl/hppaosf.em (hppaosf_finish): Expand the only remaining
+ call to LANG_FOR_EACH_INPUT_SECTION.
+
+Fri Feb 4 16:26:08 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldmisc.c (ldmalloc, xmalloc, ldrealloc, xrealloc): Functions
+ deleted; will use libiberty versions instead.
+ * ldctor.c ldfile.c ldlang.c ldmain.c ldmisc.c ldmisc.h lexsup.c
+ mri.c Makefile.in: Change callers.
+
+ * ldmisc.c (vfinfo): Remove cleanup code.
+ * ldmain.c (remove_output): Put it here (new function).
+ (preserve_output): New function.
+ (main): Register remove_output and preserve_output with atexit.
+ * ldmain.c ldgram.y: Call xexit instead of exit.
+ * ldmisc.h: Declare xexit.
+
+Fri Feb 4 15:19:01 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * Makefile.in: Lots of new H8/500 memory models.
+
+Sun Jan 30 14:33:40 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ldlex.l: Removed duplicate rules.
+ (yywrap): Provide default definition, needed with some versions of
+ flex.
+
+Fri Jan 28 09:12:56 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldmisc.c (vfinfo): For `%I', if the file is in an archive, print
+ the archive filename too.
+
+ * ldlex.l: Add rule to catch invalid input characters instead of
+ printing them. Include "ldmain.h" for program_name decl.
+ (lex_warn_invalid): New function.
+ * Makefile.in: Add dependency.
+
+Fri Jan 28 12:58:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * Makefile.in (check): Don't bother running any tests of
+ cross-linker until the test suite no longer assumes native mode.
+
+Thu Jan 27 17:19:54 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * ldlang.c (print_one_symbol, print_input_section): Print
+ global symbols in symbol table again.
+
+Thu Jan 27 12:35:01 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldmain.c ldmain.h ldgram.y: If -v -V or --version was given,
+ exit successfully instead of complaining if no input files are
+ given.
+
+Tue Jan 25 13:19:41 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in: Format variable definitions consistently.
+ (LD_PROG): Remove unnecessary variables from link command,
+ change variable LOADLIBES to EXTRALIBS.
+
+ * ldmain.c (main): Compute and display total execution time.
+ * ld.texinfo (-stats): Document the option.
+
+Mon Jan 24 12:56:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (reloc_overflow): Added name, reloc_name and addend
+ arguments.
+
+ * ldlang.c (lookup_name): Set BFD GP size to -G argument value
+ after opening BFD.
+
+ * ldlang.c (relaxing): Removed global variable.
+ (lang_size_sections): If the canonical symbols have not already
+ been read in, read them in before relaxing.
+ * ldlang.h (relaxing): Removed declaration.
+
+Fri Jan 21 00:44:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (new_afile): Initialize loaded field to false.
+ (lookup_name): If file was already loaded, don't call the
+ add_symbols entry point again.
+
+Wed Jan 19 13:57:00 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ld.texinfo: Clarify what -T option does.
+
+Tue Jan 18 16:18:15 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * scripttempl/m88kbcs.sc: Don't use CREATE_OBJECT_SYMBOLS, that's
+ for a.out.
+
+Tue Jan 11 13:22:04 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (add_archive_element): If trace_files or
+ trace_file_tries, print file name.
+ * ldlang.c (lookup_name): Likewise.
+ (ldlang_add_file): Don't put files on input_bfds list in reverse
+ order.
+
+ * scripttempl/elf.sc: Correct typo.
+
+Mon Jan 10 19:49:05 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldgram.y, ldlex.l: Make the space between -e, -u, and -y and
+ their arguments optional, for compatibility with the old GNU ld.
+
+Fri Jan 7 20:00:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/elf.c: Define __bss_start before the .sbss section.
+
+Thu Jan 6 00:13:10 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (add_to_set): Add bitsize argument.
+ (constructor_callback): New function.
+ (link_callbacks): Add constructor_callback.
+ * ldctor.c (struct set_info): Add bitsize field.
+ (ldctor_add_set_entry): Add bitsize argument.
+ (ldctor_build_sets): Base the size of the elements of the set on
+ the bitsize, rather than always using LONG.
+ * ldctor.h (ldctor_add_set_entry): Add bitsize to declaration.
+
+ * ld.h (QUAD_SIZE): Define.
+ * ldgram.y (QUAD): New token.
+ (length): Handle it.
+ * ldlex.l: Return QUAD.
+ * lexsup.c (keywords): Add QUAD.
+ * ldwrite.c (build_link_order): Handle QUAD.
+ * ldlang.c (print_data_statement): Handle QUAD.
+ (lang_size_sections): Likewise.
+ (lang_do_assignments): Likewise.
+ * ldexp.c (exp_print_token): Add QUAD to table.
+ * ld.texinfo: Describe QUAD.
+
+ * scripttempl/alpha.sc: Don't create .lit4 or .sdata sections,
+ since the Alpha doesn't use them.
+
+Wed Jan 5 17:42:16 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldemul.h (ld_emulation_xfer_struct): Comment the members.
+
+Sat Jan 1 13:39:31 1994 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * Makefile.in, configure.in: Add support for VSTa micro-kernel.
+ * config/vsta.mt, emulparams/vsta.sh: New files for VSTa.
+
+Sat Jan 1 10:53:35 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * scripttempl/aout.sc: Pad .text to DATA_ALIGNMENT if relocating;
+ needed for i386mach. (Should be a no-op on other systems.)
+
+ * emulparams/i386mach.sh (SEGMENT_SIZE): Fix again.
+ (PAGE_SIZE): Don't define; not used.
+
+Fri Dec 31 16:12:06 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldgram.y (yyerror): Make argument const char *, and actually
+ print it out rather than assuming it is a syntax error.
+ * ldmisc.h: Change declaration of yyerror.
+ * ldemul.c, ldwrite.c: Add /*ARGSUSED*/ as appropriate.
+
+Fri Dec 31 11:37:28 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * emulparams/i386mach.sh (NONPAGED_TEXT_START_ADDR): Don't include
+ exec header offset, since the exec header isn't loaded.
+ (PAGE_SIZE, SEGMENT_SIZE): Agree with bfd/i386mach3.c.
+
+Thu Dec 30 13:01:43 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ A major rewrite to move the bulk of the linker into BFD so that
+ more efficient backend code can be written for specific object
+ files.
+ * lderror.c, lderror.h, ldindr.c, ldindr.h, ldsym.c, ldsym.h,
+ ldwarn.c, ldwarn.h, relax.c, relax.h: Removed.
+ * ldctor.c, ldctor.h: Complete rewrite.
+ * ldwrite.c, ldwrite.h: Complete rewrite.
+ * ld.h (strip_symbols_type, strip_symbols): Removed. Use
+ link_info.strip instead. Changed all uses.
+ (discard_locals_type, discard_locals): Removed. Use
+ link_info.discard instead. Changed all uses.
+ (ld_config_type): Removed relocateable_output field; use
+ link_info.relocateable instead; changed all uses. Added stats
+ field.
+ (set_asymbol_chain, get_asymbol_chain, get_loader_symbol,
+ set_loader_symbol): Removed.
+ * ldexp.h (node_class): Added etree_rel.
+ (etree_type): Added rel field.
+ * ldexp.c (exp_print_token): Bracketed table initialization.
+ (exp_relop): New function.
+ (fold_name): Use linker hash table rather than ldsym functions.
+ (exp_fold_tree): Likewise. Also, handle etree_rel case.
+ (exp_print_tree): Handle etree_rel.
+ * ldgram.y (strip_symbols, discard_locals): Removed.
+ (OPTION_stats, OPTION_no_keep_memory): New tokens. Handle them.
+ (REL): New token. Does not appear in grammar, but needed for
+ expression code.
+ (file): Don't call lang_final; it's called by main anyhow.
+ * ldlex.l: Accept -stats and -no-keep-memory options.
+ * ldlang.h (fill_type): Make unsigned int, not unsigned short.
+ * ldlang.c: Consistently use fill_type for fill argument.
+ (lang_init_script_file, script_file): Removed.
+ (create_object_symbols): Removed. Use
+ link_info.create_object_symbols_section instead. Changed all
+ uses.
+ (lang_add_keepsyms_file): Removed.
+ (lookup_name): Call bfd_link_add_symbols instead of
+ ldmain_open_file_read_symbol.
+ (wild): Don't iterate over script_file.
+ (open_output): Create link hash table.
+ (lang_place_undefineds): Rewrote.
+ (lang_size_sections): Handle relaxing (doesn't work yet).
+ (lang_relocate_globals): Removed.
+ (lang_finish): Use link hash table rather than ldsym functions.
+ (lang_common): Rewrote.
+ (lang_one_common): New function.
+ (ldlang_add_file): Add file to link_info.input_bfds list. Set
+ usrdata.
+ (create_symbol): Removed.
+ (lang_process): Don't call lang_init_script_file. Call
+ ldctor_build_sets rather than find_constructors. Don't call
+ lang_relocate_globals.
+ (lang_abs_symbol_at_beginning_of): Rewrote.
+ (lang_abs_symbol_at_end_of): Rewrote.
+ * ldmain.c (had_y): Removed.
+ (lprefix, lprefix_len): Removed; use link_info fields instead.
+ Changed all uses.
+ (multiple_def_count, commons_pending, undefined_global_sym_count,
+ total_symbols_seen, total_files_seen): Removed.
+ (link_callbacks, link_info): New variables.
+ (main): Initialize link_info. Don't call init_bfd_error_vector or
+ ldsym_init. Don't set now unused variables. Handle -stats.
+ (get_emulation): Removed obsolete and nonfunctional GNU960 code.
+ (add_ysym): Rewrote.
+ (read_entry_symbols, refize, enter_global_ref, enter_file_symbols,
+ search_library, gnu960_check_format, decode_library_subfile,
+ linear_library, symdef_library, clear_syms, subfile_wanted_p):
+ Removed.
+ (add_keepsyms_file, add_archive_element, multiple_definition,
+ multiple_common, add_to_set, warning_callback, undefined_symbol,
+ reloc_overflow, reloc_dangerous, unattached_reloc, notice_ysym):
+ New functions.
+ * ldmisc.c (vfinfo): Accept a string for %T, not a symbol. Don't
+ require symbols for %C; look them up instead.
+ * emultempl/hppaosf.em: Pass link_info to
+ hppa_look_for_stubs_in_section.
+ * Makefile.in: Rebuilt dependencies.
+ (CFILES): Removed lderror.c, ldindr.c, ldsym.c, ldwarn.c, and
+ relax.c.
+ (HFILES): Removed lderror.h, ldindr.h, ldsym.h, ldwarn.h, and
+ relax.h.
+ (EMULATION_OFILES): Depend on bfdlink.h, ldmain.h, ldexp.h,
+ ldlang.h and ldctor.h.
+
+ * Makefile.in (ldlex.c): Don't depend on ldgram.h. Remove
+ declarations of free and malloc from flex output. Change malloc
+ to ldmalloc in flex output.
+
+Thu Dec 16 21:19:57 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * ldmain.c (lprefix): Change default from a char to a string
+ with only one character.
+ (lprefix_len): Set default to one.
+
+ * ldmain.h (lprefix_len): Declare.
+
+ * ldsym.c (write_file_locals): Use strncmp rather than a character
+ comparison for lprefix.
+
+ * emultmpl/m88kbcs.em (before_parse): Set lprefix and lprefix_len
+ correctly.
+
+ * emultmpl/hppaosf.em: Include ldexp.h.
+ (before_parse): Set lprefix and lprefix_len correctly.
+
+Tue Dec 14 17:19:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlex.h: Don't declare yywrap if it is a macro.
+ * ldlex.l: Include sysdep.h.
+ * ldlang.c (lang_for_each_statement_worker,
+ lang_for_each_statement): Forgot to use PARAMS.
+
+Mon Dec 13 14:30:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in: Added .PHONY targets where appropriate. Added some
+ comments. Also:
+ (gcclibdir, version): Removed unused variables.
+ (DEP): New variable, set to mkdep.
+ (ALL_CFLAGS): New variable. Used in .c.o target.
+ (CFILES, HFILES, GENERATED_CFILES, GENERATED_HFILES): New
+ variables.
+ (HEADERS, MANSOURCES, LDCSOURCES, GENERATED_SOURCES,
+ GENERATED_HEADERS, LDSOURCES, BFD_SOURCES, SOURCES): Removed
+ mostly obsolete variables. Adjusted remaining uses.
+ (DEF_EMUL): Removed variable.
+ (ldmain.o): Handle undefined EMUL error correctly.
+ (ldemul-list.h): Depend on config.status rather than Makefile.
+ Create via temporary file.
+ (ver960.c, roll, make): Removed obsolete targets.
+ (.dep, .dep1, dep.sed, dep, dep-in): New targets. Used to rebuild
+ dependencies.
+ * dep-in.sed: New file, used when rebuilding dependencies.
+
+Sat Dec 11 14:43:44 1993 Ian Lance Taylor (ian@deneb.cygnus.com)
+
+ Made many changes to eliminate gcc warnings. Made various
+ cosmetic changes, declared various things in header files, removed
+ various extern declarations from .c files. No substantive
+ changes.
+
+ * ldlang.c (lang_process): Ifdef out final call to
+ lang_size_sections again (reverting change of Nove 2), since it
+ breaks the Sun4 linker.
+
+Thu Dec 2 16:31:47 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (alpha-*-netware*): New target; use alpha.
+
+Wed Dec 1 14:04:20 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * configure.in: Group targets by CPU. Merge some m68k target
+ entries with different CPU specs that use the same ld_target
+ values.
+
+ * configure.in: Add sparc*-*-coff.
+ * config/coff-sparc.mt, emulparams/coff_sparc.sh: New files.
+ * Makefile.in (ALL_EMULATIONS): Add em_coff_sparc.o.
+ (em_coff_sparc.c): Add dependencies and build rules.
+
+ * ldmisc.c (errno, sys_nerr, sys_errlist): Don't declare.
+
+Wed Dec 1 12:19:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldgram.y (OPTION_call_shared, OPTION_non_shared, OPTION_Oval):
+ New tokens.
+ (command_line_option): Accept and ignore them (for now).
+ * ldlex.l (<COMMAND>): Handle -non_shared, -call_shared, and -On
+ where n is a number.
+
+Mon Nov 22 14:14:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (subfile_wanted_p): If merging a common symbol which is
+ not in bfd_com_section, create the section in the BFD so that it
+ can be placed in the right output section.
+
+Fri Nov 19 14:12:39 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (mips*-sgi-irix5*): New target. Use mipsb-elf32.
+ * emulparams/elf32mipsb.sh (DATA_ADDR): Define.
+ (OTHER_READONLY_SECTIONS): Define for .reginfo.
+ (EXECUTABLE_SYMBOLS): Define for _DYNAMIC_LINK.
+ * scripttempl/elf.sc: Use EXECUTABLE_SYMBOLS when not relocating.
+ Move OTHER_READONLY_SECTIONS after all the other readonly
+ sections. Don't use DATA_ADDR twice.
+
+ * ldmain.c (enter_file_symbols): Removed duplicate tests of p. If
+ p is in a common section, make sure the BFD has a section of that
+ name.
+
+ * ldlang.c (lang_common): Add newline to error message.
+
+Thu Nov 11 15:54:41 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * emulparams/m68klynx.sh (SCRIPT_NAME): Define to use a
+ Lynx-specific script instead of m68kcoff.
+ (OUTPUT_FORMAT): Define as "coff-m68k-lynx".
+ (ENTRY): Define as __main.
+ (TEXT_START_ADDR): Define as 0.
+ (PAGE_SIZE): Define as 0x1000.
+ * emulparams/i386lynx.sh, emulparams/sparclynx.sh: Fix comment.
+ * scripttempl/m68klynx.sc: New file.
+
+Mon Nov 8 12:00:16 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (get_emulation): Ignore -mips1, -mips2 and -mips3
+ arguments rather than treating them as emulation names.
+
+Fri Nov 5 09:02:52 1993 D. V. Henkel-Wallace (gumby@blues.cygnus.com)
+
+ * configure.in: Support x86 unixware and netware plus generic netware.
+
+Fri Nov 5 21:47:55 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * emulparams/i386mach.sh (TEXT_START_ADDR, NONPAGED_TEXT_START_ADDR):
+ Correct values (?).
+
+Wed Nov 3 15:10:15 1993 Ken Raeburn (raeburn@rover.cygnus.com)
+
+ * Makefile.in (distclean): Don't delete dvi or info files.
+ (ld.info): Update dependency list.
+ (ld.dvi): Ditto. Extend TEXINPUTS to get bfdsumm.texi.
+
+Wed Nov 3 12:07:39 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldlang.c (lang_add_output): Take new arg, FROM_SCRIPT.
+ Set output_filename instead of creating a new node.
+ (open_output): Don't set output_filename.
+ (lang_final): Create the new node here.
+ * ldlang.c, ldlang.h, ldgram.y, mri.c: pass FROM_SCRIPT.
+
+Tue Nov 2 15:45:51 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ From Pete Hoogenboom (hoogen@cs.utah.edu):
+
+ * scripttempl/hppaosf.sc: (___stack_zero, etext, _etext,
+ edata, _edata, end): Add definitions of these symbols.
+ (__end): Remove definition of this symbol.
+ (__data_start): Move definition of this symbol.
+
+ * emultempl/hppaosf.em: Various fixes and support for linker stub
+ generation.
+ (hppaosf_finish, hppaosf_search_for_padding_statements,
+ hppaosf_create_output_section_statements): New functions in
+ support of linker stub generation.
+ (ld_hppaosf_emulation): Redefine to include new
+ emulation-specific routines.
+
+ * ldlang.c (lang_process): Re-enable last call lang_size_sections.
+ Pass abs_output_section rather than NULL to avoid invalidating
+ absolute symbols.
+
+Thu Oct 28 21:16:42 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (ALL_EMULATIONS): Add em_i386mach.o.
+ (em_i386mach.c): New rule.
+ * configure.in (i[34]86-*-mach*): New case.
+ * config/i386-mach.mt: New file.
+ * emulparams/i386mach.sh: New file.
+
+Fri Oct 29 14:55:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ld.h (flag_is_*): Removed macros.
+ * ldmain.c (enter_global_ref), ldsym.c (write_file_locals):
+ Consistently check the BFD symbol flags directly, rather than
+ using file_is_* macros.
+
+Thu Oct 28 19:08:42 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in (sparc*-*-lynxos*): New target.
+ * Makefile.in: Add rule for em_sparclynx.c.
+ (ALL_EMULATIONS): Add Lynx emulations.
+ * config/sparc-lynx.mt: New file.
+ * emulparams/sparclynx.sh: New file.
+ * scripttempl/sparccoff.sc: New file.
+
+Thu Oct 28 13:50:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in: Add dependency for $(EMULATION_OFILES).
+
+Mon Oct 25 16:09:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * relax.c (write_relax): Check return value of bfd_seclet_link.
+
+Mon Oct 25 09:31:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * ldlang.c (delete_output_file_on_failure): New variable.
+ (open_output): Set it after bfd open succeeds.
+ * ldmisc.c (vfinfo): Test it.
+
+ Changes from Peter Hoogenboom, hoogen@cs.utah.edu:
+
+ * ldsym.c (write_file_locals): Set the BSF_FILE flag for object
+ symbols.
+
+ * ldemul.c: Support was added to allow emulation-specific
+ processing to occur. This support was added primarily for linker
+ stub generation in the elf32-hppa gld.
+ (ldemul_finish, ldemul_create_output_section_statements): New
+ functions.
+ * ldemul.h: Support was added to allow emulation-specific
+ processing to occur. (As described above.) Added finish and
+ create_output_section_statements fields to
+ ld_emulation_xfer_struct structure.
+ * ldlang.c: Add calls to emulation-specific routines.
+ (lang_process): Add call to
+ ldemul_create_output_section_statements function.
+ (lang_process): Add call to a emulation-specific routine (and
+ some processing after the call).
+
+Fri Oct 22 20:54:13 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: mips*- instead of mips-, mips*el changes
+
+Tue Oct 19 15:46:28 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (alpha-*-osf*): New target; use alpha.mt.
+ * Makefile.in (ALL_EMULATIONS): Added em_alpha.o.
+ (em_alpha.c): New target; use alpha.sh and alpha.sc.
+ * config/alphaosf.mh (NATIVE_LIB_DIRS, HOSTING_CRT0): Define.
+ * config/alpha.mt: New file.
+ * emulparams/alpha.sh: New file.
+ * scripttempl/alpha.sc: New file.
+
+Fri Oct 15 02:20:04 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * ldlang.c (lang_size_sections, lang_common): ALIGN_N can't handle
+ types of different sizes (eg: 64 and 32 bits), so coerce.
+ * ld.h (ALIGN_N): Add warning about usage.
+
+Wed Oct 13 16:02:39 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldmain.c (enter_global_ref): Just ignore any weak symbol for
+ which we already have a definition, rather than checking in
+ several different places whether the symbol is weak.
+
+Tue Oct 12 17:30:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (mips-*-elf*): New target; use mipsb-elf32.
+ * scripttempl/elf.sc: Only use OTHER_READONLY_SECTIONS and
+ OTHER_READWRITE_SECTIONS if relocating. Shell variables are not
+ expanded within them.
+ * config/mipsb-elf32.mt: New file.
+ * emulparams/elf32mipb.sh: New file.
+ * Makefile.in (em_elf32mipb.c): New target.
+
+Thu Sep 30 17:00:36 1993 Rob Savoye (rob@darkstar.cygnus.com)
+
+ * ldgram.y: In input_list, change lang_input_file_is_file_enum to
+ lang_input_file_is_search_file_enum so objects brought in using
+ INPUT() do a path lookup.
+
+Tue Sep 28 13:31:23 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: Change Lynx ld_target to be {i386,m68k}-lynx
+ instead of {i386,m68k}-coff.
+ * Makefile.in (em_i386lynx.c, em_m68klynx.c): New targets.
+ * config/i386-lynx.mt: New file.
+ * config/m68k-lynx.mt: New file.
+ * emulparams/i386lynx.sh: New file.
+ * emulparams/m68klynx.sh: New file.
+
+ * scripttempl/i386coff.sc: Make ENTRY get its value from ${ENTRY},
+ but defaulting to _start.
+
+ * ldemul.c, ldfile.c, ldlang.c, ldmain.c, ldmisc.c, ldmisc.h,
+ ldsym.c, ldwarn.c: Rename info to info_msg, to avoid conflict with
+ LynxOS libc.
+
+Thu Sep 23 14:51:03 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/solaris2.mh: New file. Define HOSTING_CRT0 and
+ HOSTING_LIBS for testing.
+
+Fri Sep 17 17:52:24 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ Finish up support for i386-sysv4 (without shared libraries):
+ * ld.h (flag_is_weak): Define.
+ * ldlang.c (print_symbol): Mention whether symbol is weak.
+ (print_input_section): Print weak symbols as globals.
+ * ldmain.c (refize): Do not zero out BSF_WEAK flag.
+ (enter_global_ref): Do not warn if a weak symbol redefines a
+ global symbol. Do not let a weak symbol redefine a common symbol.
+ (enter_file_symbols): Treat weak symbols as global symbols.
+ (subfile_wanted_p): Do not pull in an object file from a archive
+ just to resolve an undefined weak symbol.
+ * ldmisc.c (vfinfo): Don't needlessly malloc space after a fatal
+ error; the error might be that malloc has run out of space.
+ * ldsym.c (write_file_locals): Treat weak symbols as global.
+ * configure.in (i[34]86-*-sysv4*, i[34]86-*-elf*): New targets;
+ use i386-elf.
+ * config/i386v4.mh: New file; set NATIVE_LIB_DIRS to /usr/ccs/lib.
+ * config/i386-elf.mt: New file; set EMUL to elf_i386.
+ * emulparams/elf_i386.sh: New file.
+ * scripttempl/elf.sc: Use ${NOP} as filler (defaults to 0).
+ * Makefile.in (NATIVE_LIB_DIRS): Define to be empty.
+ (ALL_EMULATIONS): Add em_elf_i386.o.
+ (GENSCRIPTS): Pass NATIVE_LIB_DIRS as sixth argument.
+ (em_elf_i386.c): New target, like other em_*.c targets.
+ ($(LD_PROG)): Pass $(CFLAGS) to $(CC).
+ * genscripts.sh: Accept NATIVE_LIB_DIRS as sixth argument. If
+ nonempty, and configured for native, add it to LIB_PATH.
+
+Fri Sep 17 13:07:39 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * scripttempl/{h8300.sc,h8500.sc,i386coff.sc,m68kcoff.sc,sh.sc}:
+ Added statements to pass stab and stabstr sections through and
+ mark them as NOLOAD, which makes GDB happier.
+
+Wed Sep 15 16:02:29 1993 Stan Shebs (shebs@rtl.cygnus.com)
+
+ * configure.in: Accept m68k-lynx-lynxos config.
+
+ * Makefile.in: Use $(SHELL) to run genscripts.sh.
+
+Sun Sep 12 16:04:40 1993 Doug Evans (dje@cygnus.com)
+
+ * config/coff-h8300.mt: Add EMUL=h8300h.
+
+ * ldmain.c (main): Call set_scripts_dir after argv has been processed.
+
+Fri Sep 10 09:36:29 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Changed CXX back to g++.
+
+Fri Sep 10 09:34:29 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: Fixed RUNTEST* CXX CXXFLAGS macros and check rule.
+
+Fri Sep 10 07:26:57 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (TAGS): Use shell wildcards.
+
+Tue Sep 7 18:04:54 1993 Jeffrey Osier (jeffrey@cygnus.com)
+
+ * Makefile.in: add TEXINPUTS variable and use it in ld.dvi target
+
+Fri Sep 3 16:46:41 1993 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * ld.texinfo: re-enable included config file; conditionalize doc
+ for -oformat to interact properly with SingleFormat doc config
+ var; rename @up/@down to @raisesections/@lowersections.
+
+Wed Aug 25 16:29:56 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * configure.in: recognize m88110.
+
+Tue Aug 24 18:49:40 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ From Peter Hoogenboom <hoogen@shafer.cs.utah.edu>:
+ * emultempl/hppaosf.em (ld_hppaosf_emulation): Correct name for PA
+ ELF emulation is "elf32-hppa" not "elf-big".
+ (hppaosf_before_parse): Remove unneeded processing of environment
+ variables.
+ * scripttempl/hppaosf.sc: Include .hppa_linker_stubs sections in
+ .text segment of output file.
+ * emulparams/hppaosf.sh (OUTPUT_FORMAT): Use elf32-hppa.
+
+Tue Aug 24 16:17:00 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * ld.h: define BYTE_SIZE, SHORT_SIZE, and LONG_SIZE which are no
+ longer in bfd.h.
+
+ * ldlang.c, ld.h: updated copyright.
+
+Tue Aug 17 15:22:03 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldlang.c (open_output, lang_check): Check return value of
+ bfd_set_arch_mach.
+
+Tue Aug 17 07:02:19 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * scripttempl/h8500.sc: Start all sections in a different segment.
+ * scripttempl/z8ksim.sc: Handle constructors
+
+Thu Aug 12 16:05:37 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: revert earlier changes back to execute runtest
+ with make check. cdtest and bootstrap now function as they
+ did within the Makefile.
+
+Thu Aug 12 10:20:05 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in: Update dependencies.
+
+ * configure.in: Set EMULATION_OFILES in Makefile based on
+ --with-targets option.
+
+Thu Aug 12 08:52:29 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * Makefile.in: check targets reimplemented to old way.
+
+Wed Aug 11 08:26:11 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * config/i386v.mh, config/irix4.mh: Use gcc
+ -print-libgcc-file-name rather than $(libdir)/libgcc.a.
+ * config/i386sco.mh: New file; copy of i386v.mh to correspond to
+ bfd/configure.host change.
+
+Mon Aug 9 14:25:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * scripttempl/elf.sc: Handle .line and .debug* sections.
+
+ * ldlex.l: Use bfd_scan_vma, not strtoul.
+
+Fri Aug 6 08:57:39 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldexp.c, ldfile.c, ldlang.c, lexsup.c, ldmain.c, ldemul.c:
+ Remove inital caps in some error messages, change "can't" to
+ "cannot", add missing colons.
+ * ldmisc.c (vfinfo): Print "%%" as a single %.
+ For '%' followed by unrecognized character, print them both
+ verbatim instead of expecting a char * arg.
+ For '%C', don't put the function name in parens.
+
+ * ldexp.c (invalid): Pass "%%", not "% ".
+
+Fri Aug 6 14:31:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * scripttempl/mips.sc: Always define _ftext, _fdata, _fbss.
+ (BSS_VAR): Removed; now always define _fbss.
+ * emulparams/mipsidt.sh, emulparams/mipsidtl.sh (BSS_VAR):
+ Removed.
+
+Thu Aug 5 15:55:19 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * configure.in: z8k-coff is the same as z8k-sim
+
+Wed Aug 4 21:00:18 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * testsuite/lib/ld.exp: new file
+ * testsuite/config/unix-ld.exp: new file
+ * testsuite/ld.bootstrap/bootstrap.exp: new file
+ * Makefile.in: add dejagnu support for make check
+
+Wed Aug 4 17:52:32 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldlex.l (comment): Add missing newline in message.
+ * ldindr.c (add_indirect): Ditto.
+ * ldexp.c (exp_fold_tree): Ditto.
+
+Tue Aug 3 10:57:41 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldgram.y, ldlex.l, mri.c, ldwrite.c: Change multiple commons
+ into externs.
+
+ * ldmisc.c (multiple_warn): New function.
+ * ldmisc.h: Declare it.
+ * ldmain.c (enter_global_ref): Call it.
+ * ld.h (ld_config_type): Add warn_common.
+ * ldlex.l, ldgram.y: Set it with -warn-common option.
+ * ldver.c (help): Document it.
+
+Mon Aug 2 12:04:36 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * scripttempl/elf.sc: Add hooks for .sdata, .sbss, and
+ target-specific sections, and for changing data section vma.
+
+Mon Jul 26 14:00:02 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * ldgram.y (OPTION_Qy, OPTION_Y, OPTION_dn, OPTION_YP): New
+ terminals, for Solaris.
+ (dirlist_ptr): New static variable.
+ (command_line_option): Accept new options.
+
+ * ldlex.l: Accept command-line options "-Qy", "-dn", "-Y", and
+ "-YP,...".
+
+ * config/sun4sol2.mt: Pass emulation name without ".sh".
+
+ * emulparams/elf32_sparc.c: Renamed from elf32-sparc.c.
+ * config/sun4sol2.mt (em_elf32_sparc.c): Adjusted accordingly.
+
+Fri Jul 23 13:51:09 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * scripttempl/elf.sc: Add support for .init, .fini, .ctors,
+ .dtors, .data1, .rodata1 sections, instead of combining them into
+ other sections. For `-r', set all section start addresses to
+ zero.
+
+ * emulparams/elf32-sparc.sh (TEXT_START_ADDR,
+ NONPAGED_TEXT_START_ADDR): Value should be 0x10100.
+ (MAXPAGESIZE): Renamed from PAGE_SIZE.
+
+Wed Jul 21 14:28:42 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * genscripts.sh: If this is the default emulation, set
+ COMPILE_IN.
+ * emultempl/*.em: Use it to determine whether to compile in the
+ scripts.
+
+ * Makefile.in (GENSCRIPTS): Pass the default emulation name to
+ genscripts.sh. Pass the current emulation name without ".sh" on
+ the end.
+ * genscripts.sh: Take an default emulation arg.
+ Use the current emulation name as EMULATION_NAME.
+ Make default lib path for cross-compiling ':', not null.
+ * emulparams/*.sh: Don't set EMULATION_NAME.
+ * ldemul.c (ldemul_get_script): Take isfile arg.
+ Pass it to emulation's get_script function.
+ * ldemul.h: Adjust get_script prototypes.
+ * ldfile.c (ldfile_find_command_file): Renamed from find_a_name.
+ No longer static.
+ * ldfile.h: Declare it.
+ * ldgram.y: Accept a script on the command line again,
+ for parsing compiled-in scripts.
+ * ldmain.c (main): If ld script is a file, parse it as a -T
+ option, otherwise parse it directly.
+ * emultempl/*.em (*get_script): Return the scripts themselves if
+ this is the default emulation; otherwise return their file names.
+ * emultempl/m88kbcs.em: New file, to take m88kbcs #ifdef out of
+ generic.em.
+ * emulparams/m88kbcs.sh: Use it.
+
+ * ld.h (ld_config_type::unix_relocate): Remove unused element.
+
+Tue Jul 20 12:01:49 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (ALL_EMULATIONS): Delete em_i386linux.o (for which
+ there's no change log entry yet, tsk tsk) from the list of
+ emulations compiled in until Mark gets around to checking in
+ emulparams/i386linux.sh.
+ (ldemul-list.h): Depend on Makefile, so if EMULATION_OFILES is
+ changed, this file gets updated.
+
+Fri Jul 16 14:14:32 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldgram.y (OPTION_Lfile): New token.
+ (command_line_option): Accept OPTION_L NAME (whitespace after -L).
+ * ldlex.l (<COMMAND>): Accept -L without FILENAME.
+
+Fri Jul 16 13:44:26 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: h8/300h support needs own .mt file.
+ config/coff-h8300h.mt: New file.
+
+Thu Jul 15 12:44:35 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldmain.c: Don't include sys/stat.h; it already got included
+ somewhere along the way.
+
+Thu Jul 15 14:43:34 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * Makefile.in: Add h8300h support.
+ emulparams/h8300h.sh: New file.
+ scripttempl/h8300h.sc: New file.
+
+Thu Jul 15 12:44:35 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldfile.c (ldfile_open_file): In error message, use the name the
+ user gave (e.g., "-lc"), rather than the base file name.
+
+ * ldexp.c (exp_fold_tree): Don't assign an int to an enum.
+
+ * ldmain.[ch]: Remove initial Q_ from function names.
+ * ldexp.c, ldindr.c, ldlang.c: Change callers.
+
+ * ldfile.c, ldmain.c, ldgram.y: Rename option_v to trace_file_tries.
+
+ * ldlang.c (lang_process): Move loading of default script from
+ here to main. Add a "/" to start of script name to prevent
+ finding it in "." first.
+
+ * ldmain.c (set_scripts_dir): Don't look in "." first.
+
+ * ldgram.y, ldlang.c, ldsym.c: Remove traces of unused var
+ option_longmap.
+
+Thu Jul 15 10:55:59 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (em_m88kbcs.c): Correct dependency.
+ * scripttempl/m88kbcs.sc: It's ARCH, not arch. Removed TARGET
+ statement. Changed OUTPUT_FORMAT to use ${OUTPUT_FORMAT}.
+ * emulparams/m88kbcs.sh: It's coff-m88kbcs, not m88kbcs.
+
+Wed Jul 14 21:42:53 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldfile.c (ldlang_open_file, ldfile_open_command_file),
+ main.c (main): Print the errno string in the error message.
+
+Tue Jul 13 20:00:30 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * configure.in: Accept h8300h for target cpu.
+
+ * ldmisc.c (vfinfo): Have demangle remove leading underscore if
+ present (demangle is smart enough to know whether to do it or not).
+
+Mon Jul 12 11:45:48 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldmain.c (set_scripts_dir): Check . and <ld bin dir>/../lib for
+ ldscripts, as well as <ld bin dir> and SCRIPTDIR.
+
+ * ldlang.c (lang_process): Use sizeof instead of magic constant.
+
+ * ldmain.c (get_emulation, check_for_scripts_dir,
+ set_scripts_dir): New functions.
+ (main): Call them.
+
+Mon Jul 12 10:57:03 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * scripttempl/elf.sc: Include .init, .fini, .rodata sections.
+ Create symbol "end" instead of "__end". Comment out some parts
+ that may not be needed (yet) for elf.
+
+ * configure.in: Accept sparc-elf and sparc-solaris2 configs.
+
+Thu Jul 8 15:33:32 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (ALL_EMULATIONS): Include $(OTHER_EMULATIONS).
+
+ * ldmisc.h (einfo, minfo, info): Don't bother with PARAMS macro
+ when no prototype is being supplied.
+ (ldmalloc, ldrealloc): Size argument is now size_t.
+
+ * ldmisc.c (finfo): New function, accepts FILE* argument.
+ (vfinfo, case 'v'): New format character; displays bfd_vma in hex
+ without leading zeros.
+ (vfinfo, cases 'R' and 'C'): Use finfo(%v) when displaying a
+ bfd_vma value, instead of fprintf(%x) which won't hold a long long
+ value.
+ (concat, buystring): String lengths are size_t.
+ (ldmalloc, ldrealloc, xrealloc): Size argument is now size_t.
+
+ * ldlang.c (new_statement): Size argument is now size_t. Added
+ forward declaration with prototype.
+
+Thu Jul 8 10:53:47 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldgram.y (OPTION_v): Don't turn on verbose output.
+
+Wed Jul 7 17:10:45 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * ldlex.l: Get rid of local typedef for bfd_vma! Get it from
+ bfd.h instead.
+
+Wed Jul 7 11:33:12 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): Don't install as $(tooldir)/bin/gld;
+ collect2 doesn't look for gld any more anyhow.
+
+Mon Jul 5 14:29:48 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (lang_relocate_globals): Skip indirect symbols, which
+ now have a non NULL srefs_chain.
+
+ * config/hp300hpux.mt: Use emulation hp3hpux rather than
+ hp300hpux, since the latter does not exist.
+
+Fri Jul 2 18:06:05 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * genscripts.sh: Put the scripts in the ldscripts directory, not
+ emulations.
+ * configure.in (ldscripts): Make, instead of emulations.
+ * Makefile.in (scriptdir): Take off the "ld" part.
+ (install, clean, distclean): Use ldscripts, not emulations.
+ In tests, don't pass -Lemulations.
+ Don't pass tooldir/lib to genscripts.sh.
+ * genscripts.sh: Don't take tooldir/lib arg.
+ * ldlang.c (lang_process): Add "ldscripts/" to the name of the
+ default script file.
+
+Fri Jul 2 17:13:35 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * scripttempl/h8300.sc: Add .tors section for constructor/destructors.
+
+Thu Jul 1 16:38:45 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * config/coff-h8300.mt: EMUL=h8300hms -> h8300.
+
+Wed Jun 30 15:45:55 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in (.y.c): skip default .y.c rules. gnu make can now
+ run in parallel without colliding on yacc's static file names.
+ Without the stub rule, make will try to start two yacc's
+ concurrently which fails because of yacc's static file names.
+
+Tue Jun 29 12:20:36 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldmain.c (subfile_wanted_p): Don't dump core if there are no
+ symbols.
+
+Mon Jun 28 12:22:11 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * genscripts.sh (LIB_PATH): Only add /usr/local/lib if it's
+ different from libdir.
+
+ * Makefile.in (scriptdir): Base on tooldir, not datadir.
+
+Sat Jun 26 12:03:57 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldver.c (help): New function.
+ * ldver.h: Declare it.
+ * ldlex.l, ldgram.y: Recognize new options --help and --version.
+
+Mon Jun 21 20:39:48 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * Makefile.in (INCLUDES): Don't need ../include any more.
+
+Mon Jun 21 16:38:35 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldlex.l, ldgram.y: Support new -oformat option.
+ Remove attempt at supporting script fragments on the command line.
+ * ldlang.c (lang_add_output_format): Take new arg, FROM_SCRIPT.
+ * mri.c (mri_format), ldgram.y: Change callers.
+ * ldlang.h: Change prototype.
+
+Thu Jun 17 16:53:56 1993 david d `zoo' zuhn (zoo@cygnus.com)
+
+ * Makefile.in: canonicalize install.sh; for use within
+ this directory (and subdirs)
+
+Thu Jun 17 14:33:09 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldgram.y: Tweak grammar to make reporting of invalid options work.
+
+ * Makefile.in (.cc.o): Restore .SUFFIXES entry for .cc
+ and .cc.o rule.
+
+Wed Jun 16 11:45:32 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldfile.c (ldfile_open_command): Don't try .ld extension.
+ It wasn't documented (or likely used) and wastes time.
+ (try_open): If EXTEN is empty, don't try it.
+
+ * ldctor.c, lderror.c, ldexp.c, ldfile.c, ldindr.c, ldlang.c,
+ ldlex.l, ldmain.c, ldmisc.c, ldsym.c, ldver.c, ldwarn.c,
+ ldwrite.c, lexsup.c, mri.c, relax.c: Replace DEFUN macro calls
+ with normal function declarations.
+
+ * Move *.em to emultempl/*.em. Move *.sh to emulparams/*.sh.
+ Move *.sc-sh to scripttempl/*.sc.
+ * {emultempl,emulparams,scripttempl}/README: New files.
+ * sh.em, st2000.em, z8ksim.em, h8300hms.em, h8500hms.em: Files
+ removed, replaced with generic.em.
+ * h8300.sh, h8500.sh, h8300.sc, h8500.sc: Renamed from
+ h8[35]00hms.s[ch]. Change their contents to omit the "hms".
+
+ * *.em (*_get_script): Return script name instead of script contents.
+ * ldlang.c (lang_process): Change caller.
+
+ * ldlex.l, ldgram.y: Recognize -m option.
+ Check for input files after *all* options in grammar.
+ * ldmain.c (main): Check for -m options. Add default directory
+ for -m.
+
+ * mkscript.c: File removed.
+ * genscripts.sh: Take two more parameters, tooldirlib and libdir,
+ to add to the default LIB_PATH.
+ Look for input files in the new subdirectories.
+ Create the scripts in emulations subdirectory and don't filter
+ them through mkscript.
+ * configure.in: Make the emulations subdirectory.
+
+ * Makefile.in: Account for all of the above changes.
+ Remove unused .SUFFIXES. Get libgcc.a path with gcc
+ -print-libgcc-file-name instead of $(libdir)/libgcc.a.
+ Put CFLAGS last in the compilation rules.
+ Add -I../bfd to INCLUDES so sysdep.h is found.
+
+Tue Jun 15 23:04:46 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (INCLUDES): Look in ../include, not ../bfd.
+
+ * aout.sc-sh: Add SHLIB_PATH like STACKZERO. Make STACKZERO
+ dependent on RELOCATING, not RELOCATION.
+ * hp3hpux.sh (SHLIB_PATH): Define it.
+
+Mon Jun 14 19:06:15 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * ldfile.c (try_open): If opening without the extension fails,
+ try with the extension even if -v or -V was given.
+ had_script is imported (from ldgram.y), not exported.
+
+Mon Jun 14 16:26:10 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in: remove parentdir support, use INSTALL_XFORM
+
+Thu Jun 10 14:00:06 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldexp.c (exp_fold_tree): Don't lose the old flag bits.
+ * ldgram.y (statement_list_opt): New nonterminal, either empty or
+ statement_list.
+ (section): Use statement_list_opt, not statement_list.
+ * m68kcoff.sc-sh: Gather constructors and destructors and define
+ __CTOR_LIST__ and __DTOR_LIST__ appropriately.
+ * sa29200.sc-sh: Gather constructors and destructors and define
+ ___CTOR_LIST__ and ___DTOR_LIST__ appropriately.
+
+Mon Jun 7 12:53:28 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (INCLUDES): Add -I../bfd for sysdep.h and bfd.h.
+ * configure.in: No longer need to configure to get sysdep.h.
+
+Fri Jun 4 16:18:24 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: remove install:all and install-info:info
+ dependencies (these cause some spurious rebuilds at 'make install'
+ time)
+
+Fri Jun 4 08:50:14 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in (mips-idt-ecoffl*): New target; use mips-idtl.
+ (mips-idt-ecoff*): Added trailing '*'.
+ * config/mips-idtl.mt: New file; use EMUL of mipsidtl.
+ * mipsidtl.sh: New file; like mipsidt.sh, but little endian.
+ * Makefile.in (ALL_EMULATIONS): Added em_mipsidtl.o.
+
+ * config/sun3.mh (HOSTING_LIBS, HOSTING_EMU): Removed obsolete and
+ incorrect definitions.
+
+Tue Jun 1 14:56:10 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldsym.c (write_file_locals): Write BSF_CONSTRUCTOR
+ symbols, unless stripping.
+
+Tue May 25 15:34:25 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: configure looks for ####, so remove lines with many
+ '#' characters.
+ * config/irix4.mh, config/i386v.mh: New files; set HOSTING_CRT0
+ and HOSTING_LIBS correctly so that ``make check'' will work.
+
+Thu May 20 13:56:16 1993 Per Bothner (bothner@deneb.cygnus.com)
+
+ * mips.sc-sh: Define _etext, _edata, and _end, in addition
+ to etext, edata, and end. Needed for IRIX 4.0.5F.
+ Patch from mwp@iconix.oz.au (Michael Paddon).
+
+ * Version 2.2.1 released.
+
+Thu May 20 11:42:06 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * mipsbsd.sc-sh: Renamed from aout-mipsbsd.sc-sh.
+ * mipsbsd.sh (EMULATION_NAME): Use new file name.
+
+Tue May 18 17:10:24 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (LDDISTSTUFF): Remove ld.mm since we can't build it
+ properly right now.
+
+ * Version 2.2 released.
+
+Mon May 17 15:37:28 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * ldver.c (ldversion): Bump version number to 2.2.
+
+Mon May 17 12:44:31 1993 Per Bothner (bothner@cygnus.com)
+
+ * NEWS: New file.
+
+Fri May 14 11:26:24 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.sc-sh: Don't define BSS_VAR unless relocating.
+
+Wed May 12 13:33:29 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (mkscript.o, mkscript): Build mkscript via
+ mkscript.o, rather than directly from mkscript.c.
+
+Tue May 4 21:58:56 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * configure.in: Look for ${target_makefile_frag} relative to
+ ${srcdir}, not relative to build directory.
+
+ * hppaosf.em, hppaosf.sc-sh, hppaosf.sh: New files.
+ * configure.in: Recognize hppa*-hp-osf.
+ * Makefile.in (ALL_EMULATIONS): Include hppaosf emulation.
+ (em_hppaosf.c): Build it.
+ * config/hppaosf.mh, hppaosf.mt: New files.
+
+ * ld.h (ALIGN_N): Renamed from ALIGN, because that conflicted with
+ some system header files. All uses changed.
+
+ * configure.in: Recognize i386-aix configurations as i386-coff
+ targets.
+
+ * configure.in: Recognize m68*-*-hpux.
+ * aout.sc-sh: If STACKZERO and RELOCATING are both defined, output
+ the value of STACKZERO.
+ * Makefile.in (ALL_EMULATIONS): Include hp300-hpux emulation.
+ (em_hp3hpux.c): Build it.
+ * hp3hpux.sh, config/hp300hpux.mt: New files.
+
+Tue May 4 12:37:35 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.sc-sh: Put constructors in the .data section.
+ * Makefile.in (cdtest): Added dependency on ld.new.
+
+Mon May 3 19:43:39 1993 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Change definition of $(tooldir) to match FSF.
+ * vax.sh, config/vax.mt, configure.in, Makefile.in:
+ Support VAX Ultrix and BSD.
+
+Mon Apr 26 18:35:47 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * sh.em, sh.sh, sh.sc-sh: New files supporting Hitachi SH.
+
+Wed Apr 14 21:01:51 1993 John Gilmore (gnu@cygnus.com)
+
+ * ldlang.h (struct memory_region): Change `length' and
+ `old_length' fields to bfd_size_type. Eliminate use of bfd_offset.
+ * ldlang.c, mri.c: Corresponding changes, plus lint.
+
+Thu Apr 8 22:08:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: For all i386 targets, accept i486 as well.
+
+Mon Apr 5 17:33:39 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (wild_doit): Preserve all flags for a
+ SEC_SHARED_LIBRARY section.
+ (size_input_section): Consider any SEC_HAS_CONTENTS section when
+ computing largest_section.
+
+Fri Apr 2 14:33:52 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (lang_output_section_statement_lookup): Initialize all
+ fields of newly created structure.
+
+Wed Mar 31 18:19:15 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldmain.c (g_switch_value): New variable.
+ * ldgram.y (OPTION_G, OPTION_Gval): New tokens.
+ (command_line_option): Accept -G and set g_switch_value.
+ * ldlex.l (COMMAND): Accept -G.
+ * ldlang.c (open_output): Call bfd_set_gp_size on new BFD.
+
+Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Support for linking and loading at different places:
+
+ * ldlex.l: Add "AT" keyword.
+ * ldgram.y: Cleanup, and parse AT.
+ * ldlang.c (print_output_section_statement): Print output address
+ of section in map. (lang_size_sections): Fill sections' lma with
+ load address.
+ * ldlang.h (lang_output_section_statement_type): Add load_base
+ information.
+
+ * ldindr.c (add_indirect): Keep more information in the alias
+ symbol chain.
+ * ldlang.c (wild_doit): Don't inherit NEVER_LOAD section
+ attribute from an input section.
+ * ldmain.c (Q_enter_file_symbols): Common section is NEVER_LOAD by
+ default. (Q_enter_file_symbos): Indirect symbols now are known by
+ their section, not a special symbol flag.
+ * ldsym.c (write_file_locals): Indirect symbols aren't local.
+ (write_file_globals): Write the mapping for an indirect symbol.
+ * relax.c (build_it): When forced to write a NEVER_LOAD section,
+ fill it with zeros.
+
+Tue Mar 23 13:24:10 1993 Jeffrey Osier (jeffrey@fowanton.cygnus.com)
+
+ * ld.texinfo: changes for q1
+
+Tue Mar 23 00:13:29 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: add dvi target, define & use TEXI2DVI, add installcheck
+
+Mon Mar 8 20:30:35 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: rename HOST_CC to CC_FOR_BUILD
+
+Thu Mar 4 12:44:33 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.sc-sh: Added variables which may be overridden by a
+ specific emulation.
+ * mipsidt.sh: New file; emulation for IDT MIPS board.
+ * Makefile.in (ALL_EMULATIONS): Added em_mipsidt.o.
+ (em_mipsidt.c): New target. Uses mipsidt.sh and mips.sc-sh.
+ * config/mips-idt.mt: New file; sets EMUL to mipsidt.
+ * configure.in (mips-idt-ecoff): New target; uses mips-idt.
+
+Sat Feb 27 00:00:14 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * aout-mipsbsd.sc-sh, mipsbsd.sh: New files from Ralph Campbell,
+ ralphc@pyramid.com.
+ * i386bsd.sh, config/i386bsd.mt: New files.
+ * configure.in, Makefile.in: Added support for mipsbsd and 386bsd.
+
+Thu Feb 25 15:33:10 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * mri.c: Add extern declaration of strdup.
+ * ldsym.c (KEEP macro): Add spaces around '=' for the
+ sake of old (e.g. PCC) compilers.
+
+Wed Feb 24 19:49:31 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldver.c: Bump to version 2.1.
+
+Fri Feb 12 08:09:11 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldgram.y: allow section types without address expressions.
+ * ldlang.c (lang_relocate_globals): avoid possible hang with
+ undefined but unreferenced symbols.
+ * relax.c (relax_section): don't complain if the script file isn't
+ relaxable but -relax is set
+
+Thu Feb 18 17:58:45 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: go32 is the 3rd part of the triple, not the 2nd
+
+Wed Feb 3 09:05:56 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mipsbig.sh: New file. Big endian MIPS emulation.
+ * config/mips-big.mt: New file. Use mipsbig emulation.
+ * configure.in (mips-sgi-irix*): Use target mips-big.
+ * Makefile.in (ALL_EMULATIONS): Added em_mipsbig.o.
+ (em_mipsbig.c): New target. Uses mipsbig.sh.
+
+Tue Feb 2 11:32:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.sc-sh: Put .scommon sections into .sbss section.
+
+ * ldmain.c (subfile_wanted_p): Preserve section of common symbols,
+ rather than always putting them in bfd_com_section.
+ * ldlang.c (lang_common): If a common symbol is not in
+ bfd_com_section, put in a section of the same name, rather than
+ always putting it in section COMMON.
+
+Fri Jan 29 09:57:58 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldmain.c (subfile_wanted_p): If we already have a common
+ definition of a symbol, don't necessarily pull in an object file
+ that provides a non-common definition.
+
+ * ldlex.l (COMMAND): Accept -EB and -EL command line arguments,
+ returning OPTION_EB and OPTION_EL. gcc passes these to a MIPS
+ linker.
+ * ldgram.y (OPTION_EB, OPTION_EL): New tokens.
+ (command_line_option): Accept and ignore OPTION_EB and OPTION_EL.
+
+Thu Jan 28 15:12:04 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): Remove $(tooldir)/bin/gld before creating
+ the link to it.
+
+Tue Jan 26 11:49:50 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldmain.c, ldsym.c: Use new bfd_is_com_section macro rather than
+ checking for equality to bfd_com_section.
+
+Fri Jan 22 14:22:44 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips.sc-sh: New file. Ultrix, and hopefully other MIPS ECOFF
+ targets, linker script.
+ * mipslit.sh: New file. Little endian MIPS emulation.
+ * config/mips-lit.mt: New file. Use mipslit emulation.
+ * configure.in (mips-dec-ultrix*): Use target mips-lit.
+ * Makefile.in (ALL_EMULATIONS): Added em_mipslit.o.
+ (em_mipslit.c): New target. Uses mipslit.sh.
+
+Thu Jan 14 15:30:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): Install ld as both $(tooldir)/bin/ld and
+ $(tooldir)/bin/gld, so that gcc can find it with or without
+ collect2.
+
+Mon Jan 11 18:50:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ldwrite.c: Removed perform_relocation, copy_and_relocate, and
+ write_norel. All linking is now done via write_relax. Call
+ ldsym_write before calling write_relax.
+ * relax.c: Added copyright.
+ (write_relax): Renamed from write_relaxnorel. Added relocateable
+ argument. seclet_dump renamed to bfd_seclet_link.
+ * relax.h: Added copyright.
+
+Mon Jan 11 15:41:56 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldmain.c (decode_library_subfile): Patch from
+ hoogen@shafer.cs.utah.edu, don't reread library symbol tables.
+
+Fri Jan 8 18:04:33 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * config/vxworks960.mt renamed to config/i960.mt
+
+ * configure.in: sparc-aout emulates a sun4, as does
+ sparc*-vxworks, i960-nindy uses gld960 emulation
+
+Fri Jan 8 14:39:07 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Fix support for NOLOAD, add INCLUDE
+ * ldfile.c (ldfile_open_command_file): pass file name to
+ lex_push_file.
+ * ldlex.l, ldgram.y: tidy up, parse INCLUDE and NOLOAD
+ * ldlang.c (wild_doit): make output sections inherit NEVER_LOAD
+ attribute.
+
+Thu Jan 7 10:22:19 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in, config.h: no more default emulation. Make the lack
+ of emulation a compile time error
+
+Wed Jan 6 01:08:37 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognise all sparclite variants, not just 'sparclite'
+
+Mon Dec 28 11:15:35 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68kcoff.sc-sh: define _end as well as end, for consistency with
+ aout.sc-sh.
+
+ * configure.in: accept *-ericsson-ose for any m68k CPU.
+
+ * ldwrite.c (write_rel): don't always set SEC_HAS_CONTENTS flag
+ for each output section.
+
+Mon Dec 21 16:06:59 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldexp.c, ldlang.c, ldmain.c, ldsym.c, ldwarn.c: Use new
+ macro bfd_asymbol_bfd as appropriate.
+ * Makefile.in: Un-duplicate ldlex.c dependency.
+ * condigure.in: Replace my_host case table by sourcing
+ ../bfd/configure.host. Allow std-host as the default.
+ * ldmisc.c: Change logic for C++ name demangling: There is
+ no initial '_' to remove from stab-derived function names.
+
+Sun Dec 13 16:31:26 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlang.c (lang_init_script_file): don't attach the output file
+ sections to the script file.
+
+Wed Dec 9 08:38:05 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+ * ldlang.c (wild): run expansion loop over command line bfd too.
+ (lang_ini_script_file): initialize more parts of the command line
+ bfd.
+ * ldlex.l: fix DEFINED start states.
+
+Mon Dec 7 08:43:41 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+ -y support
+ * ld.texinfo: new doc.
+ * ldgram.y, ldlex.l: understand -y<symbol>
+ * ldmain.c (Q_enter_file_symbols): if had -y, lookup symbol and
+ print info. (add_ysym): new function.
+ * ldsym.h: (ldsym_type): new define SYM_Y.
+
+Sat Nov 21 03:15:27 1992 John Gilmore (gnu@cygnus.com)
+
+ * ldctor.h, lderror.h, ldexp.h, ldfile.h, ldindr.h, ldlang.c,
+ ldlang.h, ldlex.h, ldmain.h, ldmisc.h, ldsym.h, ldver.h, ldwarn.h,
+ ldwrite.h, relax.h: Replace all uses of EXFUN and PROTO ansi-glue
+ macros with PARAMS. Recreational cleanup. Update copyrights.
+
+Tue Nov 10 00:23:37 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: pass down the bfd source directory for includes
+
+Thu Nov 5 15:41:55 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (lang_size_sections): don't change size and address for
+ SEC_SHARED_LIBRARY sections rather than for SEC_NEVER_LOAD
+ sections.
+
+Thu Nov 5 11:33:57 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * relax.c (build_it): re-enable the processing of data_statements
+ in scripts, makes counted contructor lists work again.
+
+Thu Nov 5 05:43:01 1992 John Gilmore (gnu@cygnus.com)
+
+ * ldemul.h: Remove uses of SDEF and PROTO macros (use PARAMS).
+
+Tue Oct 20 10:56:06 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * m68kcoff.sc-sh: don't use initial underscores for etext, edata
+ and end.
+
+Mon Oct 19 09:45:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Support for i386-sysv.
+ configure.in: check for i386-*-sysv* and i386-*-sco*.
+ i386coff.sc-sh: rewrote to support SVR3 by default.
+ ldctor.c (find_constructors): preserve stat_ptr.
+ ldlang.c (wild_doit): initialize vma and size of new output
+ section to corresponding input section. This is required for
+ shared library support.
+ (lang_size_sections): don't modify vma and size of sections which
+ are never loaded (for shared libraries).
+ ldwrite.c (copy_and_relocate): copy the contents of any section
+ which has contents, not just sections which are loaded (for shared
+ libraries).
+
+Thu Oct 15 15:20:26 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlang.c (size_input_section): count the sizes of all sections
+ we allocate.
+
+Thu Oct 8 09:05:25 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldmisc.c (demangle,vfinfo): use the new underscore in bfd to
+ to demangle symbols better
+
+Tue Oct 6 13:08:54 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * ldlang.c (lang_finish): don't warn if -e start symbol does not
+ exist when linking with -r.
+
+Mon Oct 5 14:07:37 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * aout.sc-sh, m68kcoff.sc-sh: set __bss_start to the start of the
+ .bss segment.
+
+Mon Oct 5 08:55:14 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldmain.c (linear_library): don't even think about processing
+ an object file if it's already been done
+
+Thu Oct 1 23:14:59 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: the hp9000/300 config file is now hp300
+
+Wed Sep 30 07:34:09 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/z8ksim.mt: new file
+
+Fri Sep 25 13:49:52 1992 Ken Raeburn (raeburn@kyriath.cygnus.com)
+
+ * Makefile.in (ldexp.o, ldctor.o, ldlang.o, ldmain.o, ldwrite.o,
+ lexsup.o, mri.o, relax.o): Indicate dependence on ldgram.h.
+
+ * ld.h (strip_symbols_type): Add value STRIP_SOME.
+ * ldgram.y (OPTION_RETAIN_SYMBOLS_FILE): New terminal token.
+ * ldlang.c (lang_add_keepsyms_file): New function.
+ * ldlex.l: Handle "-retain-symbols-file".
+ * ldsym.c (keepsyms_file, kept_syms): New vars.
+ (process_keepsyms): New functihon; reads file, marks symbols for
+ saving.
+ (write_file_locals): File symbols should always be kept.
+ (ldsym_write): Warn about "-retain-symbols-file" overriding "-S"
+ and "-s". Process retain-symbols file before setting symtab.
+ * ldsym.h (SYM_KEEP): New flag for ldsym_type flags.
+ (keepsyms_file, kept_syms): Declare them.
+
+ * ldmain.c (main): Non-fatal errors should still cause non-zero
+ exit status even with -r.
+
+Fri Sep 25 11:08:01 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ Added initial support for the z8k
+ * z8ksim.em, z8ksim.sc-sh, z8ksim.sh: new files
+ * configure.in, Makefile.in: modified to reflect above
+
+ * ldlang.c (lang_check): when linking conflicting architectures,
+ make the output file reflect at least one of the bad inputs.
+
+Tue Sep 15 15:35:38 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (install): if $(tooldir) exists, install ld in
+ $(tooldir)/bin.
+
+Fri Sep 11 10:24:22 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * Makefile.in, configure.in: modified to support i386-coff
+ * i386coff.sh: new file
+
+Wed Sep 9 11:52:58 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in, m68kcoff.sh, m68kcoff.sc-sh, config/m68k-coff.mt:
+ added m68k-coff emulation mode, stolen from a29k emulation.
+ Almost certainly wrong, but perhaps better than sun3.
+
+Thu Sep 3 14:19:30 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in, Makefile.dos, generic.em, genscripts.sh,
+ gld960.em, h8300hms.em, h8300xray.em, lnk960.em, st2000.em,
+ vanilla.em: Rename all (generated) ld__*.c files to em_.c.
+ This is one character shorter, and lets people build on
+ SVR3 system. (ld__h8300xray.[co] was the killer there;
+ h8300xray.sc-sh is also overlong, but seems harmless.)
+ Based on a patch from Jonathan Ryshpan <hitachi!amito!jon>.
+ * Makefile.in (clean): Fix typo mostclean -> mostlyclean.
+ * configure.in: Add host isc.
+
+ * ldver.c: Call it version 2.0.
+
+Wed Sep 2 00:21:33 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldver.c: Bump to version 0.98.
+ * TODO: New file.
+
+ * Makefile.in: Added mostlyclean, distclean, realclean rules.
+
+Tue Sep 1 23:42:16 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldmisc.c (xrealloc): New (needed by ../libiberty/cplus.dem.c).
+ * ldlex.l: Moved comment() to end, since some compilers
+ otherwise have problems with input() used before it is defined.
+
+Tue Sep 1 17:45:51 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: added Solaris 2 and Irix 4 host support.
+
+Mon Aug 31 19:27:11 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: remove -S flag from the FLEX definition
+
+ * configure.in: rewrote, using new style case statement. use
+ m68k.mt for m68k-aout systems
+
+Sun Aug 30 21:38:53 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: map "ld" through program_transform_name when
+ installing.
+
+Sun Aug 30 18:12:13 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cplus-dem.c: Removed. Use the version in libiberty now.
+ * ldmisc.c: Use new libiberty version of cplus_demangle().
+
+Thu Aug 27 16:38:42 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * gld960.em (gld960_choose_target): default to little endian, not
+ big endian.
+
+Wed Aug 26 17:28:51 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlang.c (lang_process): don't pass null pointers when
+ abs_output_section is what is required.
+ * ldwrite.c (ldwrite): use malloc to allocate the largest space
+ used, and pass that down.
+ * relax.c,relax.h (write_relaxnorel): use the passed malloc area rather
+ than alloca.
+
+Mon Aug 24 14:42:06 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in, config/ose68.mt: renamed OSE to ose.
+
+Thu Aug 20 19:55:22 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * ldsym.c (write_file_locals): Reorder check for common or
+ undefined symbols so that it works.
+
+Tue Aug 18 13:41:36 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * configure.in: accept all m68K family members.
+
+ * Makefile.in: always create installation directories.
+
+Thu Aug 13 11:49:34 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlex.l: now parses comment correctly, added ~ to acceptable
+ chars in filenames
+
+ * ldexp.c (exp_unop): pass down abs_output_section - now can have
+ unary -ve constants.
+
+ * ldlang.c (lang_finish): warn when an entry symbol supplied on
+ the command line can't be found.
+
+Fri Aug 7 12:31:10 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlang.h: add new field "loadable" to output_section_statement.
+ * ldlang.c (lang_output_section_statement_lookup): initilize new
+ field. (wild_doit): if new field is not set, then stop output
+ section from being loadable.
+ (lang_enter_output_section_statement): set the field from the
+ NOLOAD keyword
+ * ldgram.y: new synax for NOLOAD. Removes a shift/reduce too.
+ * h8300hms.sc-sh, h8300hms.em: get -r right.
+
+Thu Aug 6 18:35:21 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldint.texinfo: New internals manual (beginnings thereof).
+ * PORTING: Removed, merged into ldint.texinfo.
+
+Tue Aug 4 21:12:29 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cdtest-main.cc, cdtest-func.cc, cdtest-foo.h, cdtest-foo.cc,
+ cdtest.exp: A test program (copied from libg++/test-install)
+ that tests that constructor and destructors are handled
+ corrrectly.
+
+Mon Aug 3 14:58:19 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in (install): install from ld.new, renaming during the
+ copy, or else the next 'make install' needs to re-link ld.
+
+Mon Jul 20 03:37:06 1992 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * configure.in: generalise hp recognition (from sef).
+
+Sat Jul 18 14:46:04 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: recognize bsd and hpux hppa configurations.
+ error messages echo to stderr, not stdout
+
+Fri Jul 17 22:06:11 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.dos, gld.1, ld.texinfo, ldemul.c, ldfile.c, ldlang.c,
+ ldmisc.c: removed rcsid's.
+
+Tue Jul 14 08:34:34 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlang.c (lang_map): print changes in sizes due to relaxing
+ (size_input_section): maintain the delta information.
+ * ldlang.h: add new field to struct to contain delta info.
+ * relax.c (relax_section): complain if input not relaxable.
+ * ldlex.l : add '_', ',' and '$' to chars which can appear at the
+ start of a filename
+
+Mon Jul 13 17:33:00 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldmain.c(main): prevent -r and -relax from being on at the same
+ time.
+
+Wed Jul 1 17:51:19 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldmain.c (Q_enter_global_ref), ldindr.c (add_indirect): fix for
+ aliasing problems
+
+
+Thu Jun 18 09:38:56 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * h8300hms.em, h8300hms.sc-sh: do the right thing for -r
+ * ldexp.c: lint
+ * ldlang.c(open_output): set the target arch and machine as soon
+ as we can. (lang_size_sections): use new macros for setting vma
+ * ldwrite.c: lint
+
+Mon Jun 15 08:47:43 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * configure.in (my_target): Accept m680?0 for wrs as vxworks68.
+ Also deleted an unreachable path to wrs.
+
+Wed May 27 23:24:19 1992 Michael Tiemann (tiemann@rtl.cygnus.com)
+
+ * Makefile.in (install): use -d test for $tooldir before
+ installing ld there so that $tooldir can be inherited from
+ top-level Makefile.
+
+Wed May 27 16:56:48 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldlang.c: Two non-substantial changes for the sake of
+ the old Portable C Compiler.
+
+Wed May 27 15:15:58 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldgram.y, ldlex.l: parse ABSOLUTE
+ * ldexp.c: add support for ABSOLUTE
+
+Wed May 27 13:07:20 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Added default definitions for HOSTING_CRT0,
+ HOSTING_LIBS, and HOSTING_EMU, based on those in config/*.mh.
+ * config/*.mh: Miscellaneous clean-up: Removed definitions
+ of YACC (since it is not longer used in the Makefile).
+ Remove HOSTING_* definitions that are subsumed by the
+ ones added to Makefile.in. Removed most definitions of CC.
+ * config/{sparc,news,hp300bsd,decstation}.mh: Removed;
+ These are no longer needed.
+
+Fri May 22 13:47:19 1992 Per Bothner (bothner@cygnus.com)
+
+ * Makefile.in: Use srcdir instead of VPATH in ldgram/ldlex
+ rules, since these are used when building a distribution.
+ * Makefile.in (ldlex.c): Don't re-direct output, since that
+ leaves a bogus output files if it fails.
+
+ * config/sparc.mh: Fix HOSTING_LIBS so it has a chance of working.
+ * ldlex.c: Fix some unnecessary flex-specific-isms.
+
+Fri May 8 11:49:43 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldgram.y: move spurious semicolon
+ * ldexp.h: fix prototype
+
+Thu May 7 17:01:12 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * ld.texinfo: references to linker now say "ld" not "gld".
+
+Wed May 6 13:26:19 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ changed calling convention for Q_enter_global_ref
+ * ldexp.c, ldlang.c, ldmain.c: reflect this
+ * ldver.c: bump version to 1.97.1
+ * ldindr.c (add_indirect): when an edict declaring an indirect
+ symbol is found, make sure that any ideas about the symbol being
+ common are changed if it now known to be defined.
+ * ldmain.c (linear_library): complain once if archive isn't
+ ranlibbed.
+ * ldlang.h, ldlang.c: make room for and initialize the complain
+ once field.
+
+Wed May 6 11:07:35 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: use flex & bison from ../ if they exist.
+
+Tue May 5 17:47:33 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * relax.c (build_it): don't allocate space in the output file for
+ stuff if -R flag applys to it.
+ * ldfile.c: merge in VMS filename support
+ * ldmain.c (main): take out ./ from library path, and close file
+ before unlinking. Make multiple defs of a symbol create an
+ unexecable file.
+ * ldmisc.c: fatal errosrs delete output file
+
+Tue May 5 14:05:05 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ldver.c: Increase version number to 1.97, for consistency
+ with ../binutils.
+
+Tue May 5 12:12:24 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: FLEX -> LEX.
+
+ * ld.texinfo: {} -> @{@}.
+
+Mon May 4 17:52:41 1992 Roland H. Pesch (pesch@fowanton.cygnus.com)
+
+ * ld.texinfo: describe alternate, MRI-compatible linker scripts
+ (and associated change in -c option, now used for these scripts)
+
+Mon May 4 16:10:10 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldver.c: Bumped version to 1.96 - new release, resync with the
+ bfd too #.
+ * ldexp.c, ldlang.c: now build memory shape tree in obstacks
+ rather than with raw malloc, makes it easier to track where memory
+ is going.
+ * ldsym.h, ldsym.c: create obstack for all global symbols too.
+ * ldwrite.c (ldwrite): moved malloc so only used when needed.
+ * sa29200-sc.sh: added support for .lit, data1 and data2 sections.
+
+
+Fri May 1 18:17:52 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * config/sparc.mh: use ../gcc/libgcc.a on check if it exists.
+
+ * Makefile.in: use bootstrap for check.
+
+Fri May 1 13:03:41 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldgram.y, ldlex.c, mri.c: added more compatible words; BASE, ALIAS and
+ PUBLIC.
+ * Makefile.in: now use flex, not lex
+ * ldlex.l, ldlang.c, ldctor.c: lint
+
+Wed Apr 22 12:48:42 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlex.l: added CMDFILENAMECHAR state so that you can lex
+ different sorts of filenames on the command line than in a script.
+
+Mon Apr 20 22:37:04 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: rework CFLAGS so that they can be passed on the
+ make command line. Remove MINUS_G. Default CFLAGS to -g.
+
+Fri Apr 17 08:57:17 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * relax.c: added handling for new "padding" seclet type, used to
+ fill out gaps between section.
+ * ldgram.y, ldlex.l: now -defsym on the command line is done
+ properly.
+
+Wed Apr 15 21:20:07 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: the tooldir copy of ld goes directly in tooldir.
+
+Wed Apr 15 16:09:33 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * mri.c, ldgram.y, ldlex.l: added support for minimal strange link
+ scripts.
+
+Thu Apr 9 05:52:02 1992 Ken Raeburn (Raeburn@Cygnus.COM)
+
+ * Makefile.in (install): Install second copy in $(tooldir)/bin
+ without $(program_prefix), since that's what gcc expects.
+
+Sat Apr 4 17:44:06 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldlex.l, ldgram.y, ldlex.h: Rewrote lexer. Now it's much nicer.
+ * h8300*: fix bit rot and add support for h8300xray target
+ * go32.sh: target emulation for go32.
+
+Mon Mar 16 14:53:29 1992 Steve Chamberlain (sac@rtl.cygnus.com)
+
+ * gld960.em, i960.sc-sh. Fix i960 bit rot
+
+Fri Mar 13 19:47:22 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: install man page.
+
+Fri Mar 13 08:23:59 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * config/mt-<foo> renamed to <foo>.mt
+ * config/mh-<foo> renamed to <foo>.mt
+ * configure.in changed to reflect this
+ * genscripts.sh now make .xbn files rather than .xN files
+
+Sat Mar 7 03:40:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * ldver.h: fix decl of ldversion.
+
+Fri Mar 6 22:00:35 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added check target.
+
+Fri Mar 6 06:59:04 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldmain.c (Q_enter_file_symbols): now aliases work again
+
+Thu Mar 5 21:39:29 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: added clean-info target.
+
+Thu Mar 5 16:55:56 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * ldexp.c (exp_print_tree): don't try and follow null pointers
+ around.
+ * ldgram.y: remove 11 shift reduce errors
+
+Tue Mar 3 15:46:39 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: added tooldir and program_prefix.
+
+Fri Feb 28 08:17:45 1992 Steve Chamberlain (sac at thepub.cygnus.com)
+
+ * ldlang.c (size_input_section): don't move absolute sections
+ around!
+
+
+Thu Feb 27 09:20:41 1992 Steve Chamberlain (sac at thepub.cygnus.com)
+
+ * cplus-dem.c: yet another copy of this - maybe it should go into
+ libiberty ?
+ * ldgram.y: now -V and -v have different actions
+ * ldver.c: if -V, prints list of emulations compiled in
+ * ldmisc.c: support for cplus demangling
+
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Thu Feb 20 17:43:46 1992 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Change mkscript rule into one for ./mkscript
+ (for the sake of makes that don't realize they're the same).
+ * PORTING: Add more details.
+ * genscripts.sh: Add more tailorability of DATA_ALIGNMENT.
+
+Mon Feb 17 12:04:36 1992 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, and new files hp300bsd.sh, config/mh-hp300bsd,
+ config/mt-hp300bsd: New port to hp300 running BSD.
+
+Sat Feb 15 13:59:54 1992 Per Bothner (bothner at cygnus.com)
+
+ Major rewrite of how ld is configured. The major idea
+ is to use shell scripts to generate everything.
+ * generic.em replaces ldtemplate.
+ * Other *.em files replace various *.c files.
+ A *.em file is a shell script that generates the corresponding
+ ld__*.c file that implements an emulation. This is usually
+ a straight 'cat' of a here-document, possibly with substitutions.
+ * Script files (*.sc) are places by *.sc-sh scripts.
+ Again, these are simple shell scripts that 'cat'
+ here-documents, usually with some substitutions.
+ The output a *.sc-sh is a script file.
+ * Each emulation is defined by a short shell script with
+ extension *.sh that specifies the emulation-specific
+ parameters (such as the name of the *.sh-sc and *.em
+ files to use).
+ * genscript.sh is the master shell script used to generate
+ an emulation. It is passed various argument, including
+ the name a the emulation-speciic *.sh file that it
+ "sources" to set variables to emulation-specifc parameters.
+ * config/mt-foo: Changed EMUL=GLDFOO_EMULATION_NAME
+ to EMUL=foo. (The GLDFOO_EMULATION_NAMEs have bee removed.)
+ * config/mh-foo: Rename LDEMULATION names as appropriate
+ (usually 'gldfoo' -> plain 'foo').
+ * ldwrite.c: Fixed a typo in a comment.
+ * Makefile.in: Major changes. Removed some the sed
+ magic to converts scripts, since that is now handled
+ by genscripts.sh and the *.sc-sh scipt generators.
+ * config.h: Remove a bunch of macros defining emulations
+ and targets. This becomes one less file to edit when
+ adding emulations or targets.
+ * ldemul.h (struct ld_emulation_xfer_struct): Add
+ emulation_name and target_name fields.
+ * ldemul.c, ldemul.h: Define some default functions used
+ by most emulations (and remove from the *.em scripts).
+ * ldemul.c (ldemul_choose_target): Search the new
+ ld_emulations array using a loop (instead of a hardwired
+ nested if statement).
+ Define the ld_emulation from the automatically-geenrated
+ ldemul-list.h. This means you no longer have to edit ldemul.c
+ to add a new emulation.
+ * ldmain.c: Replace {GLD,LNK}960_EMULATION_NAME by
+ their expansions, since the former no longer exist.
+ * PORTING: A very rough first draft of a porting guide.
+
+ * ldgram.y, ldlex.l, lexsup.c: Changes to allow an assignment
+ to be terminated by a new-line (instead of requiring a semicolon).
+
+Mon Feb 10 16:21:02 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * ldexp.c, ldlang.c: added new idea "abs_output_section", removes
+ tests for NULL pointers all over the place.
+ * ldlang.c (lang_process): remember to relocate global symbols
+ *after* relaxing has done it stuff.
+
+Thu Feb 6 11:40:15 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * config/mt-coff-h8300: use EMUL like everything else
+ * ldlang.c: (print_padding_statement): print the right address.
+ * Makefile.in, config.h, ldemul.c: renamed h8300hds to h8300hms
+
+
+Tue Feb 4 15:28:01 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * ldlex.l: Put pack -noinhibit-exec and -sort-common
+ * ldlang.c (print_data_statement): print the right address.
+
+Thu Jan 30 17:51:53 1992 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: The rule for testing ld by re-linking itself
+ via an intermediate -r link was moved to the ld1 rule
+ instead of the ld2 rule. This allows ld2 and ld3 to be identical,
+ which allows the bootstrap rule to work.
+ * ldctor.c (find_constructors): Don't create a constructor
+ list if it is already defined (as would happen if ld is
+ invoked by collect).
+
+Wed Jan 29 08:35:39 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * config/mh-sparc.h: now uses libgcc.a
+ * ldmain.c: quit using exit
+ * *sc: use *(COMMON) rather than [COMMON]
+ * ldlex.l, lexsup.c: much thinking moved from .l and put into .c,
+ to allow preprocessing of .l file.
+ * Makefile.in: New ldlex.l mangling
+ * ldexp.c (fold_binary): perform expressions with % and / in
+ integer.
+ * ldfile.c (open_a): open archives on VMS in a special way
+
+
+Tue Jan 28 10:18:16 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * ldgram.y: map -M behave in the same way as -Map (sets file name
+ to be "-".
+ * ldsym.c, ldlang.c: remember that size of a section is dependent on
+ whether or not relaxing has been done.
+ * ldmain.c: don't open a map file if it doesn't have a name
+ * relax.c: all the brains have moved into bfd.
+ * ldwrite.c: ammend comment
+
+Fri Jan 24 14:23:46 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * Makefile.in: added relax, also made three stage go through a
+ partial link stage.
+ * relax.c : added
+ * config.h: if GNU960 defined, then default emulation mode is
+ GLD960
+ * ldexp.h, ldexp.c: map to file hooks
+ * ldlang.c: map to file hooks
+ * ldgram.y: added -Map -relax
+ * ldlex.l: added -relax, -Map
+ * ldmain.c: open map file
+ * ldmisc.c: support for map file
+ * ldwrite.c: new relax magic
+
+Thu Dec 19 18:49:51 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in, config/tm-*.h: Clean up make output, only
+ pass DEFAULT_EMULATION to ldmain.c.
+
+Wed Dec 18 15:02:47 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldver.c: Bump to version 1.94.
+
+Tue Dec 10 04:07:23 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Mon Dec 9 16:26:43 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Pass -y to bison. (Again;
+ accidentally deleted by Rich.)
+ * news.sc, ldgld68k.sc: Define __end as well as _end.
+
+Sat Dec 7 17:19:26 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * ldindr.h: added to contain prototypes of ldindr.c
+ * ldfile.c: include ctype.h
+ * ldmain.c: include the requried prototype headers
+ * ldwrite.c: get_reloc_upper_bound has been renamed
+ bfd_get_reloc_upper_bound
+
+Fri Dec 6 23:29:26 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: punt "fundamental" mode because it breaks my emacs
+ macros. install using INSTALL_PROGRAM and INSTALL_DATA. remove
+ spaces following hyphens, bsd make can't cope. added
+ standards.text support and made it look like all the other
+ makefiles.
+
+ * configure.in: configure now runs entirely in objdir so make file
+ existence checks against ${srcdir}. Mark this directory as
+ target dependent.
+
+Thu Dec 5 22:46:16 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+Wed Dec 4 23:36:55 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldver.c: Bumped version to 1.93.
+ * Makefile.in: Pass -y to bison.
+
+Mon Nov 25 18:28:40 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * config.h: h8 is now coff, not ieee
+ * h8300hds.sc: reflect the same
+
+Thu Nov 14 19:55:09 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldver.c (ldversion()): Update to 1.92.
+ * ldctor.c: There are two places constructor sets
+ can be defined. One of them checked for an existing
+ duplicate, the other didn't. Unfortunately, the latter
+ was called after the former ...
+ So, factor out code for inserting a new element into
+ constructor_name_list (after checking for a duplicate)
+ into a new function add_constructor_name, and call
+ it from both aforementioned places (ldlang_add_constructor
+ and ldlang_check_for_constructors).
+
+Wed Nov 13 15:17:43 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Rename .c files generated from ldtemplate
+ to have names starting with ld__. This helps 'make clean'.
+
+Tue Nov 12 18:36:50 1991 Steve Chamberlain (sac at cygnus.com)
+
+ * Makefile.in: Take out the version number for install
+ * m88kbcs.sc: put in contructor blocks.
+
+Mon Nov 11 18:47:33 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldmisc.c, ldmisc.h: Re-write info() to take a filename
+ parameter, a format, and an arg pointer, and rename it to
+ vfinfo(). Write info() in terms of new vfinfo().
+ New einfo() is the same as info(), except it writes to stderr.
+ * ldemul.c, ldexp.c, ldlang.c, ldlnk960.c, ldmain.c, ldwrite.c,
+ ldmisc.c: Replace "error" calls to info() by new einfo().
+
+Mon Nov 11 09:57:32 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * ldlex.l ldgram.y: made -V option do same as -v
+ * Makefile.in: Added $(MINUS_G) flag so debugging can be
+ turned off
+
+Sun Nov 3 16:37:37 1991 Steve Chamberlain (steve at cygnus.com)
+ i386 aout changes from Bob Kukura
+ * Makefile.in, config.h: added i386aout support
+ * configure.in: fixed /h-{myhost} typo
+ * ldgram.y: -MM now gives more boring map.
+ * ldlang.c: now does D_PAGED flag the right way.
+ * ldsym.c: -MM flags does the right thing.
+
+Sun Nov 3 15:00:03 1991 Per Bothner (bothner at cygnus.com)
+
+ * configure.in: Fixed typo. Also, a fix for hp300bsd.
+ * ldlang.c (init_os): Compensate for BFD change,
+ where bfd_make_section now returns NULL for a duplicate
+ section request, instead of the old section.
+
+Thu Oct 17 15:27:13 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldver.c: Bump to version 1.91 (consistent with binutils).
+
+Wed Oct 16 12:27:08 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, config.h, ld.h, ldemul.c, ldexp.c, ldexp.h,
+ ldgram.y, ldlex.l, ldlnk960.c, ldmain.c, ldmisc.c, ldmisc.h,
+ ldsym.c, ldsym.h, ldtemplate, ldvanilla.c, ldver.c, ldver.h,
+ ldwarn.c, ldwarn.h, ldwrite.c, ldwrite.h, mkscript.c:
+ Add or update copyright notices.
+
+Mon Oct 14 23:55:27 1991 Per Bothner (bothner at cygnus.com)
+
+ * README: New file.
+ * Makefile.in: Changed installation directory name scheme
+ to be consistent with gcc. Also changed 'install'.
+
+Mon Oct 14 17:30:02 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * Makefile.in: new targets ld.mm, ld.me
+
+Mon Oct 14 17:27:24 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, ldtemplate: Need to use separate scripts
+ for -n and -N options. Yet more complication.
+
+Fri Oct 11 22:40:46 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Avoid using $< in explicit Make rules (it doesn't
+ work). Add some lines to avoid Sun Make VPATH bugs.
+
+Fri Oct 11 16:42:22 1991 Per Bothner (bothner at cygnus.com)
+
+ * news.sc: Add alignment for data segment.
+ * ldtemplate: Add (yet another) script to get for -n or -N
+ options. (These need different alignment than ZMAGIC files.)
+ * Makefile.in: Add stuff for new foo.xn scripts.
+ These are generated by replacing "ALIGN(0x...00)" by ".".
+
+Fri Oct 11 15:43:04 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * Makefile.in: new targets ld.ms, ld-index.ms
+ ld.texinfo: remove tabs, other cleanups for texi2roff
+
+Fri Oct 11 13:51:54 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldmain.c (main): Make config.magic_demand_paged be true
+ by default. Don't the WP_TEXT and D_PAGED flags of
+ output_bfd here; it's too late, so set it when output_bfd
+ is created (in ldlang.c). Also fix setting of EXEC_P flag
+ * ldlang.c (ldlang_open_output): Set output_bfd->flags here.
+ * ldlang.c: Remove some duplicate extern declarations.
+ * ldgram.y: Fixes to -N and -n options.
+ * Makefile.in: Recognize upper case letters in sed script
+ to remove assignments from script files.
+ * ldtemplate: Don't assukme that -N or -n options
+ imply use of -r script.
+ * mkscript.c: Tweaking to correctly handle \n and \\ in input.
+
+Fri Oct 11 10:29:27 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * ldtemplate: include bfd.h before sysdep.h.
+
+Fri Oct 11 04:24:45 1991 John Gilmore (gnu at cygnus.com)
+
+ Restructure configuration scheme for bfd, binutils, ld.
+
+ * include/sys/h-*.h: Move to bfd/hosts/h-*.h.
+ * configure.in: Revise to symlink sysdep.h to ../bfd/hosts/h-xxx.h.
+ Change some config names to match other dirs.
+ * *.c: Include bfd.h before sysdep.h, so ansidecl and PROTO()
+ get defined first.
+ * config/: Rename some config files to match up h-*.h names.
+ Remove all the HOST_SYS definitions from the config files.
+
+Tue Oct 8 16:00:57 1991 Per Bothner (bothner at cygnus.com)
+
+ * ldexp.h, ldlang.h: Change enum boolean -> enum bfd_boolean.
+ * ldtemplate: Remove ldfile_add_library_path calls;
+ just use the SEARCH_DIR commands in the script files.
+ * Makefile.in: Add LIB_PATH macro, which if set is used to replace
+ the SEARCH_DIR commands in the scripts (using ugly sed magic).
+ This is primarily intended for cross-linking, where you would
+ place libaries in a different place than native libraries.
+ Also, emulations made from ldtemplate now use $(srcdir).
+ * ldglda29k.sc: Change SEARCH_DIR commands to a conventional
+ form; people can use the Makefile's LIB_PATH to override.
+
+Tue Oct 8 14:51:21 1991 Roland H. Pesch (pesch at cygnus.com)
+
+ * Makefile.in: fix target ld.dvi, add target ld.info
+ ld.texinfo: make info filename ld.info
+
+Fri Oct 4 21:51:58 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Avoid using $< in non-suffix rules (breaks on Sun
+ Make).
+ * ldfile.c, ldlang.c, ldmain.c, ldwrite.c: Cope with renames of a
+ few BFD types & enums.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/ld/Makefile.am b/ld/Makefile.am
new file mode 100644
index 00000000000..1f02098730d
--- /dev/null
+++ b/ld/Makefile.am
@@ -0,0 +1,863 @@
+## Process this file with automake to generate Makefile.in
+
+## FIXME: work around apparent automake bug.
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+SUBDIRS = po
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi`
+YFLAGS = -d
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi`
+
+# We put the scripts in the directory $(scriptdir)/ldscripts.
+# We can't put the scripts in $(datadir) because the SEARCH_DIR
+# directives need to be different for native and cross linkers.
+scriptdir = $(tooldir)/lib
+
+EMUL = @EMUL@
+EMULATION_OFILES = @EMULATION_OFILES@
+EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@
+
+# Search path to override the default search path for -lfoo libraries.
+# If LIB_PATH is empty, the ones in the script (if any) are left alone.
+# (The default is usually /lib:/usr/lib:/usr/local/lib, unless building
+# a cross-linker, in which case the default is empty. See genscripts.sh.)
+# Otherwise, they are replaced with the ones given in LIB_PATH,
+# which may have the form: LIB_PATH=/lib:/usr/local/lib
+LIB_PATH =
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+DEP = mkdep
+
+# What version of the manual to build
+DOCVER = gen
+
+#stuff for self hosting (can be overridden in config file).
+HOSTING_CRT0 = @HOSTING_CRT0@
+HOSTING_LIBS = @HOSTING_LIBS@
+HOSTING_EMU = -m $(EMUL)
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $$r/../expect/expect ] ; \
+ then echo $$r/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $${srcroot}/../dejagnu/runtest ] ; \
+ then echo $${srcroot}/../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+RUNTESTFLAGS =
+
+CC_FOR_TARGET = ` \
+ if [ -f $$r/../gcc/xgcc ] ; then \
+ if [ -f $$r/../newlib/Makefile ] ; then \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+ else \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+ fi; \
+ else \
+ if [ "@host@" = "@target@" ] ; then \
+ echo $(CC); \
+ else \
+ echo gcc | sed '$(transform)'; \
+ fi; \
+ fi`
+
+CXX = gcc
+CXX_FOR_TARGET = ` \
+ if [ -f $$r/../gcc/xgcc ] ; then \
+ if [ -f $$r/../newlib/Makefile ] ; then \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+ else \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+ fi; \
+ else \
+ if [ "@host@" = "@target@" ] ; then \
+ echo $(CXX); \
+ else \
+ echo gcc | sed '$(transform)'; \
+ fi; \
+ fi`
+
+noinst_PROGRAMS = ld-new
+info_TEXINFOS = ld.texinfo
+noinst_TEXINFOS = ldint.texinfo
+man_MANS = ld.1
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) -I$(top_srcdir)/../intl -I../intl $(HDEFINES) $(CFLAGS) -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+BFDLIB = ../bfd/libbfd.la
+LIBIBERTY = ../libiberty/libiberty.a
+
+ALL_EMULATIONS = \
+ ea29k.o \
+ eaixppc.o \
+ eaixrs6.o \
+ ealpha.o \
+ earcelf.o \
+ earmelf.o \
+ earmelf_oabi.o \
+ earmlinux.o \
+ earm26linux.o \
+ earmaoutb.o \
+ earmaoutl.o \
+ earmcoff.o \
+ earmpe.o \
+ ecoff_sparc.o \
+ ed10velf.o \
+ ed30velf.o \
+ ed30v_e.o \
+ ed30v_o.o \
+ edelta68.o \
+ eebmon29k.o \
+ eelf32_sparc.o \
+ eelf32b4300.o \
+ eelf32bmip.o \
+ eelf32ebmip.o \
+ eelf32elmip.o \
+ eelf32l4300.o \
+ eelf32lmip.o \
+ eelf32lppc.o \
+ eelf32ppc.o \
+ eelf_i386.o \
+ eelf_i386_be.o \
+ egld960.o \
+ egld960coff.o \
+ eelf32fr30.o \
+ eelf32mcore.o \
+ ego32.o \
+ eh8300.o \
+ eh8300h.o \
+ eh8300s.o \
+ eh8500.o \
+ eh8500b.o \
+ eh8500c.o \
+ eh8500m.o \
+ eh8500s.o \
+ ehp300bsd.o \
+ ehp3hpux.o \
+ ehppaelf.o \
+ ei386aout.o \
+ ei386beos.o \
+ ei386bsd.o \
+ ei386coff.o \
+ ei386go32.o \
+ ei386linux.o \
+ ei386lynx.o \
+ ei386mach.o \
+ ei386moss.o \
+ ei386msdos.o \
+ ei386nbsd.o \
+ ei386nw.o \
+ ei386pe.o \
+ elnk960.o \
+ em68k4knbsd.o \
+ em68kaout.o \
+ em68kaux.o \
+ em68kcoff.o \
+ em68kelf.o \
+ em68klinux.o \
+ em68klynx.o \
+ em68knbsd.o \
+ em68kpsos.o \
+ em88kbcs.o \
+ emcorepe.o \
+ emipsbig.o \
+ emipsbsd.o \
+ emipsidt.o \
+ emipsidtl.o \
+ emipslit.o \
+ emipslnews.o \
+ enews.o \
+ ens32knbsd.o \
+ epc532macha.o \
+ eppcmacos.o \
+ eppcnw.o \
+ eppcpe.o \
+ eriscix.o \
+ esa29200.o \
+ esh.o \
+ eshelf.o \
+ eshlelf.o \
+ eshl.o \
+ esparcaout.o \
+ esparclinux.o \
+ esparclynx.o \
+ esparcnbsd.o \
+ est2000.o \
+ esun3.o \
+ esun4.o \
+ etic30aout.o \
+ etic30coff.o \
+ etic80coff.o \
+ evanilla.o \
+ evax.o \
+ evsta.o \
+ ew65.o \
+ ez8001.o \
+ ez8002.o
+
+ALL_64_EMULATIONS = \
+ eelf64_sparc.o \
+ eelf64alpha.o
+
+ALL_EMUL_EXTRA_OFILES = \
+ pe-dll.o \
+ deffilep.o
+
+CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
+ ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
+ mri.c ldcref.c pe-dll.c
+
+HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
+ ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
+ ldwrite.h mri.h deffile.h
+
+GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
+GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
+
+OFILES = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o \
+ ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o \
+ ldfile.o ldcref.o ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES}
+
+STAGESTUFF = *.o ldscripts/* e*.c
+
+# At the moment this is just a list of those emulation template files
+# that contain internationalised strings.
+EMULATION_FILES = emultempl/pe.em emultempl/armcoff.em
+
+POTFILES = $(CFILES) $(HFILES) $(EMULATION_FILES)
+
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+ldmain.o: ldmain.c config.status
+ $(COMPILE) -c -DDEFAULT_EMULATION='"$(EMUL)"' -DSCRIPTDIR='"$(scriptdir)"' -DTARGET='"@target@"' $(srcdir)/ldmain.c
+
+ldemul-list.h: Makefile
+ (echo "/* This file is automatically generated. DO NOT EDIT! */";\
+ for f in `echo " " ${EMULATION_OFILES} "" \
+ | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \
+ echo "extern ld_emulation_xfer_type ld_$${f}_emulation;"; \
+ done;\
+ echo "";\
+ echo "#define EMULATION_LIST \\";\
+ for f in `echo " " ${EMULATION_OFILES} "" \
+ | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \
+ echo " &ld_$${f}_emulation, \\"; \
+ done;\
+ echo " 0") >ldemul-tmp.h
+ mv ldemul-tmp.h ldemul-list.h
+
+# These all start with e so 'make clean' can find them.
+
+GENSCRIPTS = $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} @host@ @target@ @target_alias@ ${EMUL} "@NATIVE_LIB_DIRS@"
+GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed
+@TDIRS@
+
+ea29k.c: $(srcdir)/emulparams/a29k.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/a29k.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} a29k "$(tdir_a29k)"
+eaixppc.c: $(srcdir)/emulparams/aixppc.sh \
+ $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} aixppc "$(tdir_aixppc)"
+eaixrs6.c: $(srcdir)/emulparams/aixrs6.sh \
+ $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} aixrs6 "$(tdir_aixrs6)"
+ealpha.c: $(srcdir)/emulparams/alpha.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/alpha.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} alpha "$(tdir_alpha)"
+earcelf.c: $(srcdir)/emulparams/arcelf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} arcelf "$(tdir_arcelf)"
+earmelf.c: $(srcdir)/emulparams/armelf.sh \
+ $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf "$(tdir_armelf)"
+earmelf_oabi.c: $(srcdir)/emulparams/armelf_oabi.sh \
+ $(srcdir)/emultempl/armelf_oabi.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf_oabi "$(tdir_armelf)"
+earmelf_linux.c: $(srcdir)/emulparams/armelf_linux.sh \
+ $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf_linux "$(tdir_armelf_linux)"
+earmelf_linux26.c: $(srcdir)/emulparams/armelf_linux26.sh \
+ $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf_linux26 "$(tdir_armelf_linux26)"
+earmaoutb.c: $(srcdir)/emulparams/armaoutb.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armaoutb "$(tdir_armaoutb)"
+earmaoutl.c: $(srcdir)/emulparams/armaoutl.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armaoutl "$(tdir_armaoutl)"
+earmcoff.c: $(srcdir)/emulparams/armcoff.sh \
+ $(srcdir)/emultempl/armcoff.em $(srcdir)/scripttempl/armcoff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armcoff "$(tdir_armcoff)"
+earmpe.c: $(srcdir)/emulparams/armpe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armpe "$(tdir_armpe)"
+ecoff_sparc.c: $(srcdir)/emulparams/coff_sparc.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparccoff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} coff_sparc "$(tdir_coff_sparc)"
+ed10velf.c: $(srcdir)/emulparams/d10velf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd10v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d10velf "$(tdir_d10v)"
+ed30velf.c: $(srcdir)/emulparams/d30velf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d30velf "$(tdir_d30v)"
+ed30v_o.c: $(srcdir)/emulparams/d30v_o.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d30v_o "$(tdir_d30v)"
+ed30v_e.c: $(srcdir)/emulparams/d30v_e.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d30v_e "$(tdir_d30v)"
+edelta68.c: $(srcdir)/emulparams/delta68.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/delta68.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} delta68 "$(tdir_delta68)"
+eebmon29k.c: $(srcdir)/emulparams/ebmon29k.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/ebmon29k.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ebmon29k "$(tdir_ebmon29k)"
+eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32fr30 "$(tdir_fr30)"
+eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32mcore "$(tdir_mcore)"
+em32relf.c: $(srcdir)/emulparams/m32relf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m32relf "$(tdir_m32r)"
+eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)"
+eelf32b4300.c: $(srcdir)/emulparams/elf32b4300.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32b4300 "$(tdir_elf32b4300)"
+eelf32bmip.c: $(srcdir)/emulparams/elf32bmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32bmip "$(tdir_elf32bmip)"
+eelf32bsmip.c: $(srcdir)/emulparams/elf32bsmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32bsmip "$(tdir_elf32bsmip)"
+eelf32ebmip.c: $(srcdir)/emulparams/elf32ebmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32ebmip "$(tdir_elf32ebmip)"
+eelf32elmip.c: $(srcdir)/emulparams/elf32elmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32elmip "$(tdir_elf32elmip)"
+eelf32l4300.c: $(srcdir)/emulparams/elf32l4300.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32l4300 "$(tdir_elf32l4300)"
+eelf32lmip.c: $(srcdir)/emulparams/elf32lmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32lmip "$(tdir_elf32lmip)"
+eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)"
+eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32lsmip "$(tdir_elf32lsmip)"
+eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)"
+eelf64alpha.c: $(srcdir)/emulparams/elf64alpha.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf64alpha "$(tdir_elf64alpha)"
+eelf64_sparc.c: $(srcdir)/emulparams/elf64_sparc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf64_sparc "$(tdir_elf64_sparc)"
+eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf_i386 "$(tdir_elf_i386)"
+eelf_i386_be.c: $(srcdir)/emulparams/elf_i386_be.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf_i386_be "$(tdir_elf_i386_be)"
+egld960.c: $(srcdir)/emulparams/gld960.sh \
+ $(srcdir)/emultempl/gld960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} gld960 "$(tdir_gld960)"
+egld960coff.c: $(srcdir)/emulparams/gld960coff.sh \
+ $(srcdir)/emultempl/gld960c.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} gld960coff "$(tdir_gld960coff)"
+ego32.c: $(srcdir)/emulparams/go32.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} go32 "$(tdir_go32)"
+eh8300.c: $(srcdir)/emulparams/h8300.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8300 "$(tdir_h8300)"
+eh8300h.c: $(srcdir)/emulparams/h8300h.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300h.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8300h "$(tdir_h8300h)"
+eh8300s.c: $(srcdir)/emulparams/h8300s.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300s.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8300s "$(tdir_h8300s)"
+eh8500.c: $(srcdir)/emulparams/h8500.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500 "$(tdir_h8500)"
+eh8500b.c: $(srcdir)/emulparams/h8500b.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500b.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500b "$(tdir_h8500b)"
+eh8500c.c: $(srcdir)/emulparams/h8500c.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500c.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500c "$(tdir_h8500c)"
+eh8500m.c: $(srcdir)/emulparams/h8500m.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500m.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500m "$(tdir_h8500m)"
+eh8500s.c: $(srcdir)/emulparams/h8500s.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500s.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500s "$(tdir_h8500s)"
+ehp300bsd.c: $(srcdir)/emulparams/hp300bsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} hp300bsd "$(tdir_hp300bsd)"
+ehp3hpux.c: $(srcdir)/emulparams/hp3hpux.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} hp3hpux "$(tdir_hp3hpux)"
+ehppaelf.c: $(srcdir)/emulparams/hppaelf.sh \
+ $(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/hppaelf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} hppaelf "$(tdir_hppaelf)"
+ei386aout.c: $(srcdir)/emulparams/i386aout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386aout "$(tdir_i386aout)"
+ei386beos.c: $(srcdir)/emulparams/i386beos.sh \
+ $(srcdir)/emultempl/beos.em $(srcdir)/scripttempl/i386beos.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386beos "$(tdir_i386beos)"
+ei386bsd.c: $(srcdir)/emulparams/i386bsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386bsd "$(tdir_i386bsd)"
+ei386coff.c: $(srcdir)/emulparams/i386coff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386coff "$(tdir_i386coff)"
+ei386go32.c: $(srcdir)/emulparams/i386go32.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386go32 "$(tdir_i386go32)"
+ei386linux.c: $(srcdir)/emulparams/i386linux.sh \
+ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386linux "$(tdir_i386linux)"
+ei386lynx.c: $(srcdir)/emulparams/i386lynx.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386lynx.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386lynx "$(tdir_i386lynx)"
+ei386mach.c: $(srcdir)/emulparams/i386mach.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386mach "$(tdir_i386mach)"
+ei386moss.c: $(srcdir)/emulparams/i386moss.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386moss "$(tdir_i386moss)"
+ei386msdos.c: $(srcdir)/emulparams/i386msdos.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386msdos.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386msdos "$(tdir_i386msdos)"
+ei386nbsd.c: $(srcdir)/emulparams/i386nbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386nbsd "$(tdir_i386nbsd)"
+ei386nw.c: $(srcdir)/emulparams/i386nw.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386nw "$(tdir_i386nw)"
+ei386pe.c: $(srcdir)/emulparams/i386pe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386pe "$(tdir_i386pe)"
+elnk960.c: $(srcdir)/emulparams/lnk960.sh \
+ $(srcdir)/emultempl/lnk960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} lnk960 "$(tdir_lnk960)"
+em68k4knbsd.c: $(srcdir)/emulparams/m68k4knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68k4knbsd "$(tdir_m68k4knbsd)"
+em68kaout.c: $(srcdir)/emulparams/m68kaout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kaout "$(tdir_m68kaout)"
+em68kaux.c: $(srcdir)/emulparams/m68kaux.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kaux.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kaux "$(tdir_m68kaux)"
+em68kcoff.c: $(srcdir)/emulparams/m68kcoff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kcoff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kcoff "$(tdir_m68kcoff)"
+em68kelf.c: $(srcdir)/emulparams/m68kelf.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kelf "$(tdir_m68kelf)"
+em68klinux.c: $(srcdir)/emulparams/m68klinux.sh \
+ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68klinux "$(tdir_m68klinux)"
+em68klynx.c: $(srcdir)/emulparams/m68klynx.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68klynx.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68klynx "$(tdir_m68klynx)"
+em68knbsd.c: $(srcdir)/emulparams/m68knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68knbsd "$(tdir_m68knbsd)"
+em68kpsos.c: $(srcdir)/emulparams/m68kpsos.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/psos.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kpsos "$(tdir_m68kpsos)"
+em88kbcs.c: $(srcdir)/emulparams/m88kbcs.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m88kbcs.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m88kbcs "$(tdir_m88kbcs)"
+emcorepe.c: $(srcdir)/emulparams/mcorepe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mcorepe "$(tdir_mcorepe)"
+emipsbig.c: $(srcdir)/emulparams/mipsbig.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsbig
+emipsbsd.c: $(srcdir)/emulparams/mipsbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mipsbsd.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsbsd
+emipsidt.c: $(srcdir)/emulparams/mipsidt.sh \
+ $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsidt "$(tdir_mipsidt)"
+emipsidtl.c: $(srcdir)/emulparams/mipsidtl.sh \
+ $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsidtl "$(tdir_mipsidtl)"
+emipslit.c: $(srcdir)/emulparams/mipslit.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipslit "$(tdir_mipslit)"
+emipslnews.c: $(srcdir)/emulparams/mipslnews.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipslnews
+emn10300.c: $(srcdir)/emulparams/mn10300.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mn10300 "$(tdir_mn10300)"
+emn10200.c: $(srcdir)/emulparams/mn10200.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mn10200 "$(tdir_mn10200)"
+enews.c: $(srcdir)/emulparams/news.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} news "$(tdir_news)"
+ens32knbsd.c: $(srcdir)/emulparams/ns32knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ns32knbsd "$(tdir_ns32knbsd)"
+epc532macha.c: $(srcdir)/emulparams/pc532macha.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} pc532macha "$(tdir_pc532macha)"
+eppcmacos.c: $(srcdir)/emulparams/ppcmacos.sh \
+ $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ppcmacos "$(tdir_ppcmacos)"
+eppcnw.c: $(srcdir)/emulparams/ppcnw.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ppcnw "$(tdir_ppcnw)"
+eppcpe.c: $(srcdir)/emulparams/ppcpe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/ppcpe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ppcpe "$(tdir_ppcpe)"
+eriscix.c: $(srcdir)/emulparams/riscix.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} riscix "$(tdir_riscix)"
+esa29200.c: $(srcdir)/emulparams/sa29200.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sa29200.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sa29200 "$(tdir_sa29200)"
+esh.c: $(srcdir)/emulparams/sh.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sh "$(tdir_sh)"
+eshelf.c: $(srcdir)/emulparams/shelf.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} shelf "$(tdir_shelf)"
+eshlelf.c: $(srcdir)/emulparams/shlelf.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} shlelf "$(tdir_shlelf)"
+eshl.c: $(srcdir)/emulparams/shl.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} shl "$(tdir_shl)"
+esparcaout.c: $(srcdir)/emulparams/sparcaout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparcaout "$(tdir_sparcaout)"
+esparclinux.c: $(srcdir)/emulparams/sparclinux.sh \
+ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparclinux "$(tdir_sparclinux)"
+esparclynx.c: $(srcdir)/emulparams/sparclynx.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparclynx.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparclynx "$(tdir_sparclynx)"
+esparcnbsd.c: $(srcdir)/emulparams/sparcnbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparcnbsd "$(tdir_sparcnbsd)"
+est2000.c: $(srcdir)/emulparams/st2000.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/st2000.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} st2000 "$(tdir_st2000)"
+esun3.c: $(srcdir)/emulparams/sun3.sh \
+ $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sun3 "$(tdir_sun3)"
+esun4.c: $(srcdir)/emulparams/sun4.sh \
+ $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sun4 "$(tdir_sun4)"
+etic30aout.c: $(srcdir)/emulparams/tic30aout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} tic30aout "$(tdir_tic30aout)"
+etic30coff.c: $(srcdir)/emulparams/tic30coff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30coff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} tic30coff "$(tdir_tic30coff)"
+etic80coff.c: $(srcdir)/emulparams/tic80coff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic80coff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} tic80coff "$(tdir_tic80coff)"
+evanilla.c: $(srcdir)/emulparams/vanilla.sh \
+ $(srcdir)/emultempl/vanilla.em $(srcdir)/scripttempl/vanilla.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} vanilla "$(tdir_vanilla)"
+evax.c: $(srcdir)/emulparams/vax.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} vax "$(tdir_vax)"
+evsta.c: $(srcdir)/emulparams/vsta.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} vsta "$(tdir_vsta)"
+ev850.c: $(srcdir)/emulparams/v850.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/v850.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} v850 "$(tdir_v850)"
+ew65.c: $(srcdir)/emulparams/w65.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} w65 "$(tdir_w65)"
+ez8001.c: $(srcdir)/emulparams/z8001.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} z8001 "$(tdir_z8001)"
+ez8002.c: $(srcdir)/emulparams/z8002.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} z8002 "$(tdir_z8002)"
+
+ld_new_SOURCES = ldgram.y ldlex.l lexsup.c ldlang.c mri.c ldctor.c ldmain.c \
+ ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c
+ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLDEPS)
+ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS)
+
+# The generated emulation files mostly have the same dependencies.
+$(EMULATION_OFILES): ../bfd/bfd.h sysdep.h config.h $(INCDIR)/bfdlink.h \
+ ld.h ldmain.h ldemul.h ldfile.h ldmisc.h ldexp.h ldlang.h \
+ ldctor.h ldexp.h ldlang.h ldgram.h
+
+# This is the real libbfd.a created by libtool.
+TESTBFDLIB = @TESTBFDLIB@
+
+check-DEJAGNU: site.exp
+ srcroot=`cd $(srcdir) && pwd`; export srcroot; \
+ r=`pwd`; export r; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \
+ CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS)" \
+ CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS)" \
+ CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \
+ OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \
+ LIBIBERTY="$(LIBIBERTY) $(INTLLIBS)" \
+ $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+# Rules for testing by relinking ld itself.
+# A similar test is in the testsuite. This target is for ease of use
+# when porting ld.
+
+ld-partial.o: ld-new$(EXEEXT)
+ ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld-partial.o -r $(OFILES)
+ld1$(EXEEXT): ld-partial.o
+ ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1$(EXEEXT) $(HOSTING_CRT0) ld-partial.o $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+ld1-full$(EXEEXT): ld-new
+ ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1-full$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+ld2$(EXEEXT): ld1$(EXEEXT)
+ ./ld1$(EXEEXT) $(HOSTING_EMU) -o ld2$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+ld3$(EXEEXT): ld2$(EXEEXT)
+ ./ld2$(EXEEXT) $(HOSTING_EMU) -o ld3$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+bootstrap: ld3$(EXEEXT)
+ cmp ld2$(EXEEXT) ld3$(EXEEXT)
+
+.PHONY: bootstrap
+
+# A test program for C++ constructors and destructors.
+# This test is now in the testsuite.
+#
+#cdtest: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new
+# ./ld.new $(HOSTING_EMU) -o cdtest $(HOSTING_CRT0) \
+# cdtest-main.o cdtest-bar.o cdtest-foo.o $(HOSTING_LIBS)
+#
+#cdtest.out: cdtest
+# ./cdtest > cdtest.tmp
+# mv cdtest.tmp cdtest.out
+#
+#cdtest-ur.o: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new
+# ./ld.new $(HOSTING_EMU) -o cdtest-ur.o -Ur cdtest-main.o \
+# cdtest-bar.o cdtest-foo.o
+#
+#cdtest-ur: cdtest-ur.o
+# ./ld.new $(HOSTING_EMU) -o cdtest-ur $(HOSTING_CRT0) cdtest-ur.o \
+# $(HOSTING_LIBS)
+#
+#cdtest-ur.out: cdtest-ur
+# ./cdtest-ur > cdtest-ur.tmp
+# mv cdtest-ur.tmp cdtest-ur.out
+#
+#check-cdtest: cdtest.out cdtest-ur.out $(srcdir)/cdtest.exp
+# diff $(srcdir)/cdtest.exp cdtest.out
+# diff $(srcdir)/cdtest.exp cdtest-ur.out
+#
+#.PHONY: check-cdtest
+
+# END OF CHECK TARGETS
+
+# DOCUMENTATION TARGETS
+# Manual configuration file; not usually attached to normal configuration,
+# because almost all configs use "gen" version of manual.
+# Set DOCVER above to change.
+configdoc.texi: ${DOCVER}-doc.texi
+ ln -s ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \
+ || ln ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \
+ || cp ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi
+
+ldver.texi: Makefile
+ rm -f $@
+ echo '@set VERSION $(VERSION)' > $@
+
+ld.info: $(srcdir)/ld.texinfo configdoc.texi ldver.texi
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc $(srcdir)/ld.texinfo
+
+ld.dvi: $(srcdir)/ld.texinfo configdoc.texi ldver.texi
+ TEXINPUTS=$(top_srcdir)/../texinfo:$$TEXINPUTS \
+ MAKEINFO="$(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc" $(TEXI2DVI) $(srcdir)/ld.texinfo
+
+MAINTAINERCLEANFILES = ldver.texi
+
+# We want to reconfigure if configure.host or configure.tgt changes.
+config.status: $(srcdir)/configure $(srcdir)/configure.host $(srcdir)/configure.tgt
+ $(SHELL) ./config.status --recheck
+
+MOSTLYCLEANFILES = $(STAGESTUFF) ld1$(EXEEXT) ld2$(EXEEXT) ld3$(EXEEXT) \
+ ldemul-list.h crtbegin.o crtend.o ld.log ld.sum
+mostlyclean-local:
+ -rm -rf tmpdir
+CLEANFILES = dep.sed .dep .dep1
+
+.PHONY: install-exec-local install-data-local
+
+install-exec-local: ld-new$(EXEEXT)
+ $(mkinstalldirs) $(bindir) $(tooldir)/bin
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+ n=`echo ld | sed '$(transform)'`; \
+ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \
+ rm -f $(tooldir)/bin/ld$(EXEEXT); \
+ ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT); \
+ fi
+
+install-data-local:
+ $(mkinstalldirs) $(scriptdir)/ldscripts
+ for f in ldscripts/*; do \
+ $(INSTALL_DATA) $$f $(scriptdir)/$$f ; \
+ done
+
+# Stuff that should be included in a distribution. The diststuff
+# target is run by the taz target in ../Makefile.in.
+LDDISTSTUFF = ldgram.c ldgram.h ldlex.c
+diststuff: $(LDDISTSTUFF) info
+
+DISTCLEANFILES = tdirs site.exp site.bak
+distclean-local:
+ rm -rf ldscripts
+
+# Targets to rebuild dependencies in this Makefile.
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(GENERATED_CFILES)
+ rm -f .dep2
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ $(DEP) -f .dep2 $(INCLUDES) $?
+ $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+ldctor.o: ldctor.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldexp.h ldlang.h ldmisc.h ldgram.h ldmain.h ldctor.h
+ldemul.o: ldemul.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldemul.h \
+ ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldemul-list.h
+ldexp.o: ldexp.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldmain.h ldmisc.h ldexp.h ldgram.h ldlang.h
+ldfile.o: ldfile.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldgram.h \
+ ldlex.h ldemul.h
+ldlang.o: ldlang.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/obstack.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
+ ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.h \
+ ldctor.h ldfile.h $(INCDIR)/fnmatch.h
+ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/progress.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
+ ldmisc.h ldwrite.h ldgram.h ldexp.h ldlang.h ldemul.h \
+ ldlex.h ldfile.h ldctor.h
+ldmisc.o: ldmisc.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/demangle.h ld.h ldmisc.h ldexp.h ldlang.h \
+ ldgram.h ldlex.h ldmain.h ldfile.h
+ldver.o: ldver.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldver.h \
+ ldemul.h ldmain.h
+ldwrite.o: ldwrite.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \
+ ldmisc.h ldgram.h ldmain.h
+lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/getopt.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
+ ldmisc.h ldexp.h ldlang.h ldgram.h ldlex.h ldfile.h \
+ ldver.h ldemul.h
+mri.o: mri.c ../bfd/bfd.h $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/fopen-same.h ld.h ldexp.h ldlang.h \
+ ldmisc.h mri.h ldgram.h $(INCDIR)/libiberty.h
+ldcref.o: ldcref.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/libiberty.h ld.h ldmain.h ldmisc.h ldexp.h \
+ ldlang.h
+pe-dll.o: pe-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \
+ ldmisc.h ldgram.h ldmain.h ldemul.h $(INCDIR)/coff/internal.h \
+ ../bfd/libcoff.h deffile.h
+ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldexp.h ldver.h ldlang.h ldemul.h ldfile.h ldmisc.h \
+ ldmain.h mri.h ldctor.h ldlex.h
+ldlex.o: ldlex.c ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \
+ ld.h ldgram.h ldmisc.h ldexp.h ldlang.h ldfile.h ldlex.h \
+ ldmain.h
+deffilep.o: deffilep.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+ ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \
+ ld.h ldmisc.h deffile.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/ld/Makefile.in b/ld/Makefile.in
new file mode 100644
index 00000000000..e5961ae226f
--- /dev/null
+++ b/ld/Makefile.in
@@ -0,0 +1,1546 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+HDEFINES = @HDEFINES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NATIVE_LIB_DIRS = @NATIVE_LIB_DIRS@
+NM = @NM@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
+VERSION = @VERSION@
+l = @l@
+
+INTLLIBS = @INTLLIBS@
+
+AUTOMAKE_OPTIONS = cygnus dejagnu
+
+SUBDIRS = po
+
+tooldir = $(exec_prefix)/$(target_alias)
+
+YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L$(srcdir)/../bison/ ; else echo bison -y ; fi`
+YFLAGS = -d
+LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ; else echo flex ; fi`
+
+# We put the scripts in the directory $(scriptdir)/ldscripts.
+# We can't put the scripts in $(datadir) because the SEARCH_DIR
+# directives need to be different for native and cross linkers.
+scriptdir = $(tooldir)/lib
+
+EMUL = @EMUL@
+EMULATION_OFILES = @EMULATION_OFILES@
+EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@
+
+# Search path to override the default search path for -lfoo libraries.
+# If LIB_PATH is empty, the ones in the script (if any) are left alone.
+# (The default is usually /lib:/usr/lib:/usr/local/lib, unless building
+# a cross-linker, in which case the default is empty. See genscripts.sh.)
+# Otherwise, they are replaced with the ones given in LIB_PATH,
+# which may have the form: LIB_PATH=/lib:/usr/local/lib
+LIB_PATH =
+
+BASEDIR = $(srcdir)/..
+BFDDIR = $(BASEDIR)/bfd
+INCDIR = $(BASEDIR)/include
+DEP = mkdep
+
+# What version of the manual to build
+DOCVER = gen
+
+#stuff for self hosting (can be overridden in config file).
+HOSTING_CRT0 = @HOSTING_CRT0@
+HOSTING_LIBS = @HOSTING_LIBS@
+HOSTING_EMU = -m $(EMUL)
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $$r/../expect/expect ] ; \
+ then echo $$r/../expect/expect ; \
+ else echo expect ; fi`
+
+
+RUNTEST = `if [ -f $${srcroot}/../dejagnu/runtest ] ; \
+ then echo $${srcroot}/../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+
+RUNTESTFLAGS =
+
+CC_FOR_TARGET = ` \
+ if [ -f $$r/../gcc/xgcc ] ; then \
+ if [ -f $$r/../newlib/Makefile ] ; then \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+ else \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+ fi; \
+ else \
+ if [ "@host@" = "@target@" ] ; then \
+ echo $(CC); \
+ else \
+ echo gcc | sed '$(transform)'; \
+ fi; \
+ fi`
+
+
+CXX = gcc
+CXX_FOR_TARGET = ` \
+ if [ -f $$r/../gcc/xgcc ] ; then \
+ if [ -f $$r/../newlib/Makefile ] ; then \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/ -idirafter $$r/../newlib/targ-include -idirafter $${srcroot}/../newlib/libc/include -nostdinc; \
+ else \
+ echo $$r/../gcc/xgcc -B$$r/../gcc/; \
+ fi; \
+ else \
+ if [ "@host@" = "@target@" ] ; then \
+ echo $(CXX); \
+ else \
+ echo gcc | sed '$(transform)'; \
+ fi; \
+ fi`
+
+
+noinst_PROGRAMS = ld-new
+info_TEXINFOS = ld.texinfo
+noinst_TEXINFOS = ldint.texinfo
+man_MANS = ld.1
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) -I$(top_srcdir)/../intl -I../intl $(HDEFINES) $(CFLAGS) -DLOCALEDIR="\"$(prefix)/share/locale\""
+
+BFDLIB = ../bfd/libbfd.la
+LIBIBERTY = ../libiberty/libiberty.a
+
+ALL_EMULATIONS = \
+ ea29k.o \
+ eaixppc.o \
+ eaixrs6.o \
+ ealpha.o \
+ earcelf.o \
+ earmelf.o \
+ earmelf_oabi.o \
+ earmlinux.o \
+ earm26linux.o \
+ earmaoutb.o \
+ earmaoutl.o \
+ earmcoff.o \
+ earmpe.o \
+ ecoff_sparc.o \
+ ed10velf.o \
+ ed30velf.o \
+ ed30v_e.o \
+ ed30v_o.o \
+ edelta68.o \
+ eebmon29k.o \
+ eelf32_sparc.o \
+ eelf32b4300.o \
+ eelf32bmip.o \
+ eelf32ebmip.o \
+ eelf32elmip.o \
+ eelf32l4300.o \
+ eelf32lmip.o \
+ eelf32lppc.o \
+ eelf32ppc.o \
+ eelf_i386.o \
+ eelf_i386_be.o \
+ egld960.o \
+ egld960coff.o \
+ eelf32fr30.o \
+ eelf32mcore.o \
+ ego32.o \
+ eh8300.o \
+ eh8300h.o \
+ eh8300s.o \
+ eh8500.o \
+ eh8500b.o \
+ eh8500c.o \
+ eh8500m.o \
+ eh8500s.o \
+ ehp300bsd.o \
+ ehp3hpux.o \
+ ehppaelf.o \
+ ei386aout.o \
+ ei386beos.o \
+ ei386bsd.o \
+ ei386coff.o \
+ ei386go32.o \
+ ei386linux.o \
+ ei386lynx.o \
+ ei386mach.o \
+ ei386moss.o \
+ ei386msdos.o \
+ ei386nbsd.o \
+ ei386nw.o \
+ ei386pe.o \
+ elnk960.o \
+ em68k4knbsd.o \
+ em68kaout.o \
+ em68kaux.o \
+ em68kcoff.o \
+ em68kelf.o \
+ em68klinux.o \
+ em68klynx.o \
+ em68knbsd.o \
+ em68kpsos.o \
+ em88kbcs.o \
+ emcorepe.o \
+ emipsbig.o \
+ emipsbsd.o \
+ emipsidt.o \
+ emipsidtl.o \
+ emipslit.o \
+ emipslnews.o \
+ enews.o \
+ ens32knbsd.o \
+ epc532macha.o \
+ eppcmacos.o \
+ eppcnw.o \
+ eppcpe.o \
+ eriscix.o \
+ esa29200.o \
+ esh.o \
+ eshelf.o \
+ eshlelf.o \
+ eshl.o \
+ esparcaout.o \
+ esparclinux.o \
+ esparclynx.o \
+ esparcnbsd.o \
+ est2000.o \
+ esun3.o \
+ esun4.o \
+ etic30aout.o \
+ etic30coff.o \
+ etic80coff.o \
+ evanilla.o \
+ evax.o \
+ evsta.o \
+ ew65.o \
+ ez8001.o \
+ ez8002.o
+
+
+ALL_64_EMULATIONS = \
+ eelf64_sparc.o \
+ eelf64alpha.o
+
+
+ALL_EMUL_EXTRA_OFILES = \
+ pe-dll.o \
+ deffilep.o
+
+
+CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
+ ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
+ mri.c ldcref.c pe-dll.c
+
+
+HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
+ ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
+ ldwrite.h mri.h deffile.h
+
+
+GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
+GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
+
+OFILES = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o \
+ ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o \
+ ldfile.o ldcref.o ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES}
+
+
+STAGESTUFF = *.o ldscripts/* e*.c
+
+# At the moment this is just a list of those emulation template files
+# that contain internationalised strings.
+EMULATION_FILES = emultempl/pe.em emultempl/armcoff.em
+
+POTFILES = $(CFILES) $(HFILES) $(EMULATION_FILES)
+
+# These all start with e so 'make clean' can find them.
+
+GENSCRIPTS = $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} @host@ @target@ @target_alias@ ${EMUL} "@NATIVE_LIB_DIRS@"
+GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed
+
+ld_new_SOURCES = ldgram.y ldlex.l lexsup.c ldlang.c mri.c ldctor.c ldmain.c \
+ ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c
+
+ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLDEPS)
+ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(INTLLIBS)
+
+# This is the real libbfd.a created by libtool.
+TESTBFDLIB = @TESTBFDLIB@
+
+MAINTAINERCLEANFILES = ldver.texi
+
+MOSTLYCLEANFILES = $(STAGESTUFF) ld1$(EXEEXT) ld2$(EXEEXT) ld3$(EXEEXT) \
+ ldemul-list.h crtbegin.o crtend.o ld.log ld.sum
+
+CLEANFILES = dep.sed .dep .dep1
+
+# Stuff that should be included in a distribution. The diststuff
+# target is run by the taz target in ../Makefile.in.
+LDDISTSTUFF = ldgram.c ldgram.h ldlex.c
+
+DISTCLEANFILES = tdirs site.exp site.bak
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+noinst_PROGRAMS = ld-new$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+ld_new_OBJECTS = ldgram.o ldlex.o lexsup.o ldlang.o mri.o ldctor.o \
+ldmain.o ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o ldfile.o ldcref.o
+ld_new_LDFLAGS =
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LEXLIB = @LEXLIB@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then echo $(top_srcdir)/../texinfo/util/texi2dvi; else echo texi2dvi; fi`
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+INFO_DEPS = ld.info
+DVIS = ld.dvi
+TEXINFOS = ld.texinfo
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+
+NROFF = nroff
+DIST_COMMON = README ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+NEWS TODO acinclude.m4 aclocal.m4 config.in configure configure.in \
+ldgram.c ldlex.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(ld_new_SOURCES)
+OBJECTS = $(ld_new_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .dvi .info .l .lo .o .ps .s .texi .texinfo .txi .y
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+ld-new$(EXEEXT): $(ld_new_OBJECTS) $(ld_new_DEPENDENCIES)
+ @rm -f ld-new$(EXEEXT)
+ $(LINK) $(ld_new_LDFLAGS) $(ld_new_OBJECTS) $(ld_new_LDADD) $(LIBS)
+.l.c:
+ $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
+.y.c:
+ $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+ldgram.h: ldgram.c
+
+
+ld.info: ld.texinfo
+ld.dvi: ld.texinfo
+
+
+DVIPS = dvips
+
+.texi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.texinfo.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+
+.txi.dvi:
+ TEXINPUTS=$(top_srcdir)/../texinfo/texinfo.tex:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f ld.aux ld.cp ld.cps ld.dvi ld.fn ld.fns ld.ky ld.kys ld.ps \
+ ld.log ld.pg ld.toc ld.tp ld.tps ld.vr ld.vrs ld.op ld.tr \
+ ld.cv ld.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+clean-info: mostlyclean-aminfo
+
+install-man1:
+ $(mkinstalldirs) $(DESTDIR)$(man1dir)
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
+ done
+
+uninstall-man1:
+ @list='$(man1_MANS)'; \
+ l2='$(man_MANS)'; for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man1dir)/$$inst; \
+ done
+install-man: $(MANS)
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-man1
+uninstall-man:
+ @$(NORMAL_UNINSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-man1
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+
+DEJATOOL = $(PACKAGE)
+
+RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @test ! -f site.bak || rm -f site.bak
+ @echo '## these variables are automatically generated by make ##' > $@-t
+ @echo '# Do not edit here. If you wish to override these values' >> $@-t
+ @echo '# edit the last section' >> $@-t
+ @echo 'set tool $(DEJATOOL)' >> $@-t
+ @echo 'set srcdir $(srcdir)' >> $@-t
+ @echo 'set objdir' `pwd` >> $@-t
+ @echo 'set host_alias $(host_alias)' >> $@-t
+ @echo 'set host_triplet $(host_triplet)' >> $@-t
+ @echo 'set target_alias $(target_alias)' >> $@-t
+ @echo 'set target_triplet $(target_triplet)' >> $@-t
+ @echo 'set build_alias $(build_alias)' >> $@-t
+ @echo 'set build_triplet $(build_triplet)' >> $@-t
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t
+ @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv $@-t site.exp
+info-am: $(INFO_DEPS)
+info: info-recursive
+dvi-am: $(DVIS)
+dvi: dvi-recursive
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-exec-local
+install-exec: install-exec-recursive
+
+install-data-am: install-man install-data-local
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-man
+uninstall: uninstall-recursive
+all-am: Makefile $(PROGRAMS) $(MANS) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(mandir)/man1
+
+
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ -test -z "ldlexlldgramhldgramc$(MAINTAINERCLEANFILES)" || rm -f ldlexl ldgramh ldgramc $(MAINTAINERCLEANFILES)
+mostlyclean-am: mostlyclean-hdr mostlyclean-noinstPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-aminfo mostlyclean-tags mostlyclean-generic \
+ mostlyclean-local
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \
+ clean-aminfo clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-noinstPROGRAMS distclean-compile \
+ distclean-libtool distclean-aminfo distclean-tags \
+ distclean-generic clean-am distclean-local
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-aminfo maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-info-am uninstall-info \
+mostlyclean-aminfo distclean-aminfo clean-aminfo \
+maintainer-clean-aminfo install-man1 uninstall-man1 install-man \
+uninstall-man install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir check-DEJAGNU \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-info-am install-info all-recursive-am install-exec-local \
+install-exec-am install-exec install-data-local install-data-am \
+install-data install-am install uninstall-am uninstall all-redirect \
+all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+ldmain.o: ldmain.c config.status
+ $(COMPILE) -c -DDEFAULT_EMULATION='"$(EMUL)"' -DSCRIPTDIR='"$(scriptdir)"' -DTARGET='"@target@"' $(srcdir)/ldmain.c
+
+ldemul-list.h: Makefile
+ (echo "/* This file is automatically generated. DO NOT EDIT! */";\
+ for f in `echo " " ${EMULATION_OFILES} "" \
+ | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \
+ echo "extern ld_emulation_xfer_type ld_$${f}_emulation;"; \
+ done;\
+ echo "";\
+ echo "#define EMULATION_LIST \\";\
+ for f in `echo " " ${EMULATION_OFILES} "" \
+ | sed -e 's/ e/ ld/g' -e 's/ ld/ /g' -e 's/[.]o//g'`; do \
+ echo " &ld_$${f}_emulation, \\"; \
+ done;\
+ echo " 0") >ldemul-tmp.h
+ mv ldemul-tmp.h ldemul-list.h
+@TDIRS@
+
+ea29k.c: $(srcdir)/emulparams/a29k.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/a29k.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} a29k "$(tdir_a29k)"
+eaixppc.c: $(srcdir)/emulparams/aixppc.sh \
+ $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} aixppc "$(tdir_aixppc)"
+eaixrs6.c: $(srcdir)/emulparams/aixrs6.sh \
+ $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} aixrs6 "$(tdir_aixrs6)"
+ealpha.c: $(srcdir)/emulparams/alpha.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/alpha.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} alpha "$(tdir_alpha)"
+earcelf.c: $(srcdir)/emulparams/arcelf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} arcelf "$(tdir_arcelf)"
+earmelf.c: $(srcdir)/emulparams/armelf.sh \
+ $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf "$(tdir_armelf)"
+earmelf_oabi.c: $(srcdir)/emulparams/armelf_oabi.sh \
+ $(srcdir)/emultempl/armelf_oabi.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf_oabi "$(tdir_armelf)"
+earmelf_linux.c: $(srcdir)/emulparams/armelf_linux.sh \
+ $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf_linux "$(tdir_armelf_linux)"
+earmelf_linux26.c: $(srcdir)/emulparams/armelf_linux26.sh \
+ $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armelf_linux26 "$(tdir_armelf_linux26)"
+earmaoutb.c: $(srcdir)/emulparams/armaoutb.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armaoutb "$(tdir_armaoutb)"
+earmaoutl.c: $(srcdir)/emulparams/armaoutl.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/armaout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armaoutl "$(tdir_armaoutl)"
+earmcoff.c: $(srcdir)/emulparams/armcoff.sh \
+ $(srcdir)/emultempl/armcoff.em $(srcdir)/scripttempl/armcoff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armcoff "$(tdir_armcoff)"
+earmpe.c: $(srcdir)/emulparams/armpe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} armpe "$(tdir_armpe)"
+ecoff_sparc.c: $(srcdir)/emulparams/coff_sparc.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparccoff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} coff_sparc "$(tdir_coff_sparc)"
+ed10velf.c: $(srcdir)/emulparams/d10velf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd10v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d10velf "$(tdir_d10v)"
+ed30velf.c: $(srcdir)/emulparams/d30velf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d30velf "$(tdir_d30v)"
+ed30v_o.c: $(srcdir)/emulparams/d30v_o.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d30v_o "$(tdir_d30v)"
+ed30v_e.c: $(srcdir)/emulparams/d30v_e.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elfd30v.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} d30v_e "$(tdir_d30v)"
+edelta68.c: $(srcdir)/emulparams/delta68.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/delta68.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} delta68 "$(tdir_delta68)"
+eebmon29k.c: $(srcdir)/emulparams/ebmon29k.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/ebmon29k.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ebmon29k "$(tdir_ebmon29k)"
+eelf32fr30.c: $(srcdir)/emulparams/elf32fr30.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32fr30 "$(tdir_fr30)"
+eelf32mcore.c: $(srcdir)/emulparams/elf32mcore.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32mcore "$(tdir_mcore)"
+em32relf.c: $(srcdir)/emulparams/m32relf.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m32relf "$(tdir_m32r)"
+eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)"
+eelf32b4300.c: $(srcdir)/emulparams/elf32b4300.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32b4300 "$(tdir_elf32b4300)"
+eelf32bmip.c: $(srcdir)/emulparams/elf32bmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32bmip "$(tdir_elf32bmip)"
+eelf32bsmip.c: $(srcdir)/emulparams/elf32bsmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32bsmip "$(tdir_elf32bsmip)"
+eelf32ebmip.c: $(srcdir)/emulparams/elf32ebmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32ebmip "$(tdir_elf32ebmip)"
+eelf32elmip.c: $(srcdir)/emulparams/elf32elmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32elmip "$(tdir_elf32elmip)"
+eelf32l4300.c: $(srcdir)/emulparams/elf32l4300.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32l4300 "$(tdir_elf32l4300)"
+eelf32lmip.c: $(srcdir)/emulparams/elf32lmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32lmip "$(tdir_elf32lmip)"
+eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)"
+eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32lsmip "$(tdir_elf32lsmip)"
+eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elfppc.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)"
+eelf64alpha.c: $(srcdir)/emulparams/elf64alpha.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf64alpha "$(tdir_elf64alpha)"
+eelf64_sparc.c: $(srcdir)/emulparams/elf64_sparc.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf64_sparc "$(tdir_elf64_sparc)"
+eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf_i386 "$(tdir_elf_i386)"
+eelf_i386_be.c: $(srcdir)/emulparams/elf_i386_be.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf_i386_be "$(tdir_elf_i386_be)"
+egld960.c: $(srcdir)/emulparams/gld960.sh \
+ $(srcdir)/emultempl/gld960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} gld960 "$(tdir_gld960)"
+egld960coff.c: $(srcdir)/emulparams/gld960coff.sh \
+ $(srcdir)/emultempl/gld960c.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} gld960coff "$(tdir_gld960coff)"
+ego32.c: $(srcdir)/emulparams/go32.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} go32 "$(tdir_go32)"
+eh8300.c: $(srcdir)/emulparams/h8300.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8300 "$(tdir_h8300)"
+eh8300h.c: $(srcdir)/emulparams/h8300h.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300h.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8300h "$(tdir_h8300h)"
+eh8300s.c: $(srcdir)/emulparams/h8300s.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8300s.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8300s "$(tdir_h8300s)"
+eh8500.c: $(srcdir)/emulparams/h8500.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500 "$(tdir_h8500)"
+eh8500b.c: $(srcdir)/emulparams/h8500b.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500b.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500b "$(tdir_h8500b)"
+eh8500c.c: $(srcdir)/emulparams/h8500c.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500c.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500c "$(tdir_h8500c)"
+eh8500m.c: $(srcdir)/emulparams/h8500m.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500m.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500m "$(tdir_h8500m)"
+eh8500s.c: $(srcdir)/emulparams/h8500s.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/h8500s.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} h8500s "$(tdir_h8500s)"
+ehp300bsd.c: $(srcdir)/emulparams/hp300bsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} hp300bsd "$(tdir_hp300bsd)"
+ehp3hpux.c: $(srcdir)/emulparams/hp3hpux.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} hp3hpux "$(tdir_hp3hpux)"
+ehppaelf.c: $(srcdir)/emulparams/hppaelf.sh \
+ $(srcdir)/emultempl/hppaelf.em $(srcdir)/scripttempl/hppaelf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} hppaelf "$(tdir_hppaelf)"
+ei386aout.c: $(srcdir)/emulparams/i386aout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386aout "$(tdir_i386aout)"
+ei386beos.c: $(srcdir)/emulparams/i386beos.sh \
+ $(srcdir)/emultempl/beos.em $(srcdir)/scripttempl/i386beos.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386beos "$(tdir_i386beos)"
+ei386bsd.c: $(srcdir)/emulparams/i386bsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386bsd "$(tdir_i386bsd)"
+ei386coff.c: $(srcdir)/emulparams/i386coff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386coff "$(tdir_i386coff)"
+ei386go32.c: $(srcdir)/emulparams/i386go32.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386go32 "$(tdir_i386go32)"
+ei386linux.c: $(srcdir)/emulparams/i386linux.sh \
+ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386linux "$(tdir_i386linux)"
+ei386lynx.c: $(srcdir)/emulparams/i386lynx.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386lynx.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386lynx "$(tdir_i386lynx)"
+ei386mach.c: $(srcdir)/emulparams/i386mach.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386mach "$(tdir_i386mach)"
+ei386moss.c: $(srcdir)/emulparams/i386moss.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386moss "$(tdir_i386moss)"
+ei386msdos.c: $(srcdir)/emulparams/i386msdos.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386msdos.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386msdos "$(tdir_i386msdos)"
+ei386nbsd.c: $(srcdir)/emulparams/i386nbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386nbsd "$(tdir_i386nbsd)"
+ei386nw.c: $(srcdir)/emulparams/i386nw.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386nw "$(tdir_i386nw)"
+ei386pe.c: $(srcdir)/emulparams/i386pe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386pe "$(tdir_i386pe)"
+elnk960.c: $(srcdir)/emulparams/lnk960.sh \
+ $(srcdir)/emultempl/lnk960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} lnk960 "$(tdir_lnk960)"
+em68k4knbsd.c: $(srcdir)/emulparams/m68k4knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68k4knbsd "$(tdir_m68k4knbsd)"
+em68kaout.c: $(srcdir)/emulparams/m68kaout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kaout "$(tdir_m68kaout)"
+em68kaux.c: $(srcdir)/emulparams/m68kaux.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kaux.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kaux "$(tdir_m68kaux)"
+em68kcoff.c: $(srcdir)/emulparams/m68kcoff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68kcoff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kcoff "$(tdir_m68kcoff)"
+em68kelf.c: $(srcdir)/emulparams/m68kelf.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kelf "$(tdir_m68kelf)"
+em68klinux.c: $(srcdir)/emulparams/m68klinux.sh \
+ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68klinux "$(tdir_m68klinux)"
+em68klynx.c: $(srcdir)/emulparams/m68klynx.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m68klynx.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68klynx "$(tdir_m68klynx)"
+em68knbsd.c: $(srcdir)/emulparams/m68knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68knbsd "$(tdir_m68knbsd)"
+em68kpsos.c: $(srcdir)/emulparams/m68kpsos.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/psos.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m68kpsos "$(tdir_m68kpsos)"
+em88kbcs.c: $(srcdir)/emulparams/m88kbcs.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/m88kbcs.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} m88kbcs "$(tdir_m88kbcs)"
+emcorepe.c: $(srcdir)/emulparams/mcorepe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mcorepe "$(tdir_mcorepe)"
+emipsbig.c: $(srcdir)/emulparams/mipsbig.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsbig
+emipsbsd.c: $(srcdir)/emulparams/mipsbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mipsbsd.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsbsd
+emipsidt.c: $(srcdir)/emulparams/mipsidt.sh \
+ $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsidt "$(tdir_mipsidt)"
+emipsidtl.c: $(srcdir)/emulparams/mipsidtl.sh \
+ $(srcdir)/emultempl/mipsecoff.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipsidtl "$(tdir_mipsidtl)"
+emipslit.c: $(srcdir)/emulparams/mipslit.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipslit "$(tdir_mipslit)"
+emipslnews.c: $(srcdir)/emulparams/mipslnews.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/mips.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mipslnews
+emn10300.c: $(srcdir)/emulparams/mn10300.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mn10300 "$(tdir_mn10300)"
+emn10200.c: $(srcdir)/emulparams/mn10200.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} mn10200 "$(tdir_mn10200)"
+enews.c: $(srcdir)/emulparams/news.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} news "$(tdir_news)"
+ens32knbsd.c: $(srcdir)/emulparams/ns32knbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ns32knbsd "$(tdir_ns32knbsd)"
+epc532macha.c: $(srcdir)/emulparams/pc532macha.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} pc532macha "$(tdir_pc532macha)"
+eppcmacos.c: $(srcdir)/emulparams/ppcmacos.sh \
+ $(srcdir)/emultempl/aix.em $(srcdir)/scripttempl/aix.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ppcmacos "$(tdir_ppcmacos)"
+eppcnw.c: $(srcdir)/emulparams/ppcnw.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/nw.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ppcnw "$(tdir_ppcnw)"
+eppcpe.c: $(srcdir)/emulparams/ppcpe.sh \
+ $(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/ppcpe.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} ppcpe "$(tdir_ppcpe)"
+eriscix.c: $(srcdir)/emulparams/riscix.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} riscix "$(tdir_riscix)"
+esa29200.c: $(srcdir)/emulparams/sa29200.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sa29200.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sa29200 "$(tdir_sa29200)"
+esh.c: $(srcdir)/emulparams/sh.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sh "$(tdir_sh)"
+eshelf.c: $(srcdir)/emulparams/shelf.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} shelf "$(tdir_shelf)"
+eshlelf.c: $(srcdir)/emulparams/shlelf.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} shlelf "$(tdir_shlelf)"
+eshl.c: $(srcdir)/emulparams/shl.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sh.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} shl "$(tdir_shl)"
+esparcaout.c: $(srcdir)/emulparams/sparcaout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparcaout "$(tdir_sparcaout)"
+esparclinux.c: $(srcdir)/emulparams/sparclinux.sh \
+ $(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparclinux "$(tdir_sparclinux)"
+esparclynx.c: $(srcdir)/emulparams/sparclynx.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/sparclynx.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparclynx "$(tdir_sparclynx)"
+esparcnbsd.c: $(srcdir)/emulparams/sparcnbsd.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sparcnbsd "$(tdir_sparcnbsd)"
+est2000.c: $(srcdir)/emulparams/st2000.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/st2000.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} st2000 "$(tdir_st2000)"
+esun3.c: $(srcdir)/emulparams/sun3.sh \
+ $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sun3 "$(tdir_sun3)"
+esun4.c: $(srcdir)/emulparams/sun4.sh \
+ $(srcdir)/emultempl/sunos.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} sun4 "$(tdir_sun4)"
+etic30aout.c: $(srcdir)/emulparams/tic30aout.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} tic30aout "$(tdir_tic30aout)"
+etic30coff.c: $(srcdir)/emulparams/tic30coff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic30coff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} tic30coff "$(tdir_tic30coff)"
+etic80coff.c: $(srcdir)/emulparams/tic80coff.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/tic80coff.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} tic80coff "$(tdir_tic80coff)"
+evanilla.c: $(srcdir)/emulparams/vanilla.sh \
+ $(srcdir)/emultempl/vanilla.em $(srcdir)/scripttempl/vanilla.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} vanilla "$(tdir_vanilla)"
+evax.c: $(srcdir)/emulparams/vax.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} vax "$(tdir_vax)"
+evsta.c: $(srcdir)/emulparams/vsta.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} vsta "$(tdir_vsta)"
+ev850.c: $(srcdir)/emulparams/v850.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/v850.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} v850 "$(tdir_v850)"
+ew65.c: $(srcdir)/emulparams/w65.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/w65.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} w65 "$(tdir_w65)"
+ez8001.c: $(srcdir)/emulparams/z8001.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} z8001 "$(tdir_z8001)"
+ez8002.c: $(srcdir)/emulparams/z8002.sh \
+ $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/z8000.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} z8002 "$(tdir_z8002)"
+
+# The generated emulation files mostly have the same dependencies.
+$(EMULATION_OFILES): ../bfd/bfd.h sysdep.h config.h $(INCDIR)/bfdlink.h \
+ ld.h ldmain.h ldemul.h ldfile.h ldmisc.h ldexp.h ldlang.h \
+ ldctor.h ldexp.h ldlang.h ldgram.h
+
+check-DEJAGNU: site.exp
+ srcroot=`cd $(srcdir) && pwd`; export srcroot; \
+ r=`pwd`; export r; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if [ -f $(top_builddir)/../expect/expect ]; then \
+ TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
+ export TCL_LIBRARY; \
+ fi; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest --tool $(DEJATOOL) --srcdir $${srcroot}/testsuite \
+ CC="$(CC_FOR_TARGET)" CFLAGS="$(CFLAGS)" \
+ CXX="$(CXX_FOR_TARGET)" CXXFLAGS="$(CXXFLAGS)" \
+ CC_FOR_HOST="$(CC)" CFLAGS_FOR_HOST="$(CFLAGS)" \
+ OFILES="$(OFILES)" BFDLIB="$(TESTBFDLIB)" \
+ LIBIBERTY="$(LIBIBERTY) $(INTLLIBS)" \
+ $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+
+# Rules for testing by relinking ld itself.
+# A similar test is in the testsuite. This target is for ease of use
+# when porting ld.
+
+ld-partial.o: ld-new$(EXEEXT)
+ ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld-partial.o -r $(OFILES)
+ld1$(EXEEXT): ld-partial.o
+ ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1$(EXEEXT) $(HOSTING_CRT0) ld-partial.o $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+ld1-full$(EXEEXT): ld-new
+ ./ld-new$(EXEEXT) $(HOSTING_EMU) -o ld1-full$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+ld2$(EXEEXT): ld1$(EXEEXT)
+ ./ld1$(EXEEXT) $(HOSTING_EMU) -o ld2$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+ld3$(EXEEXT): ld2$(EXEEXT)
+ ./ld2$(EXEEXT) $(HOSTING_EMU) -o ld3$(EXEEXT) $(HOSTING_CRT0) $(OFILES) $(TESTBFDLIB) $(LIBIBERTY) $(HOSTING_LIBS)
+
+bootstrap: ld3$(EXEEXT)
+ cmp ld2$(EXEEXT) ld3$(EXEEXT)
+
+.PHONY: bootstrap
+
+# A test program for C++ constructors and destructors.
+# This test is now in the testsuite.
+#
+#cdtest: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new
+# ./ld.new $(HOSTING_EMU) -o cdtest $(HOSTING_CRT0) \
+# cdtest-main.o cdtest-bar.o cdtest-foo.o $(HOSTING_LIBS)
+#
+#cdtest.out: cdtest
+# ./cdtest > cdtest.tmp
+# mv cdtest.tmp cdtest.out
+#
+#cdtest-ur.o: cdtest-main.o cdtest-bar.o cdtest-foo.o ld.new
+# ./ld.new $(HOSTING_EMU) -o cdtest-ur.o -Ur cdtest-main.o \
+# cdtest-bar.o cdtest-foo.o
+#
+#cdtest-ur: cdtest-ur.o
+# ./ld.new $(HOSTING_EMU) -o cdtest-ur $(HOSTING_CRT0) cdtest-ur.o \
+# $(HOSTING_LIBS)
+#
+#cdtest-ur.out: cdtest-ur
+# ./cdtest-ur > cdtest-ur.tmp
+# mv cdtest-ur.tmp cdtest-ur.out
+#
+#check-cdtest: cdtest.out cdtest-ur.out $(srcdir)/cdtest.exp
+# diff $(srcdir)/cdtest.exp cdtest.out
+# diff $(srcdir)/cdtest.exp cdtest-ur.out
+#
+#.PHONY: check-cdtest
+
+# END OF CHECK TARGETS
+
+# DOCUMENTATION TARGETS
+# Manual configuration file; not usually attached to normal configuration,
+# because almost all configs use "gen" version of manual.
+# Set DOCVER above to change.
+configdoc.texi: ${DOCVER}-doc.texi
+ ln -s ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \
+ || ln ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi >/dev/null 2>&1 \
+ || cp ${srcdir}/${DOCVER}-doc.texi ./configdoc.texi
+
+ldver.texi: Makefile
+ rm -f $@
+ echo '@set VERSION $(VERSION)' > $@
+
+ld.info: $(srcdir)/ld.texinfo configdoc.texi ldver.texi
+ @rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ $(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc $(srcdir)/ld.texinfo
+
+ld.dvi: $(srcdir)/ld.texinfo configdoc.texi ldver.texi
+ TEXINPUTS=$(top_srcdir)/../texinfo:$$TEXINPUTS \
+ MAKEINFO="$(MAKEINFO) -I $(srcdir) -I $(BFDDIR)/doc" $(TEXI2DVI) $(srcdir)/ld.texinfo
+
+# We want to reconfigure if configure.host or configure.tgt changes.
+config.status: $(srcdir)/configure $(srcdir)/configure.host $(srcdir)/configure.tgt
+ $(SHELL) ./config.status --recheck
+mostlyclean-local:
+ -rm -rf tmpdir
+
+.PHONY: install-exec-local install-data-local
+
+install-exec-local: ld-new$(EXEEXT)
+ $(mkinstalldirs) $(bindir) $(tooldir)/bin
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed -e 's/$(EXEEXT)$$//' -e 's/-new//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+ n=`echo ld | sed '$(transform)'`; \
+ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \
+ rm -f $(tooldir)/bin/ld$(EXEEXT); \
+ ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \
+ || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT); \
+ fi
+
+install-data-local:
+ $(mkinstalldirs) $(scriptdir)/ldscripts
+ for f in ldscripts/*; do \
+ $(INSTALL_DATA) $$f $(scriptdir)/$$f ; \
+ done
+diststuff: $(LDDISTSTUFF) info
+distclean-local:
+ rm -rf ldscripts
+
+# Targets to rebuild dependencies in this Makefile.
+# Have to get rid of .dep1 here so that "$?" later includes all of $(CFILES).
+.dep: dep.sed $(CFILES) $(HFILES) $(GENERATED_CFILES) $(GENERATED_HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed <.dep1 >.dep
+
+# This rule really wants a mkdep that runs "gcc -MM".
+.dep1: $(CFILES) $(GENERATED_CFILES)
+ rm -f .dep2
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ $(DEP) -f .dep2 $(INCLUDES) $?
+ $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+ldctor.o: ldctor.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldexp.h ldlang.h ldmisc.h ldgram.h ldmain.h ldctor.h
+ldemul.o: ldemul.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldemul.h \
+ ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldemul-list.h
+ldexp.o: ldexp.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldmain.h ldmisc.h ldexp.h ldgram.h ldlang.h
+ldfile.o: ldfile.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldmisc.h ldexp.h ldlang.h ldfile.h ldmain.h ldgram.h \
+ ldlex.h ldemul.h
+ldlang.o: ldlang.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/obstack.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
+ ldgram.h ldexp.h ldlang.h ldemul.h ldlex.h ldmisc.h \
+ ldctor.h ldfile.h $(INCDIR)/fnmatch.h
+ldmain.o: ldmain.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/progress.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
+ ldmisc.h ldwrite.h ldgram.h ldexp.h ldlang.h ldemul.h \
+ ldlex.h ldfile.h ldctor.h
+ldmisc.o: ldmisc.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/demangle.h ld.h ldmisc.h ldexp.h ldlang.h \
+ ldgram.h ldlex.h ldmain.h ldfile.h
+ldver.o: ldver.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h ld.h ldver.h \
+ ldemul.h ldmain.h
+ldwrite.o: ldwrite.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \
+ ldmisc.h ldgram.h ldmain.h
+lexsup.o: lexsup.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/libiberty.h \
+ $(INCDIR)/getopt.h $(INCDIR)/bfdlink.h ld.h ldmain.h \
+ ldmisc.h ldexp.h ldlang.h ldgram.h ldlex.h ldfile.h \
+ ldver.h ldemul.h
+mri.o: mri.c ../bfd/bfd.h $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/fopen-same.h ld.h ldexp.h ldlang.h \
+ ldmisc.h mri.h ldgram.h $(INCDIR)/libiberty.h
+ldcref.o: ldcref.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/libiberty.h ld.h ldmain.h ldmisc.h ldexp.h \
+ ldlang.h
+pe-dll.o: pe-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/libiberty.h ld.h ldexp.h ldlang.h ldwrite.h \
+ ldmisc.h ldgram.h ldmain.h ldemul.h $(INCDIR)/coff/internal.h \
+ ../bfd/libcoff.h deffile.h
+ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/fopen-same.h $(INCDIR)/bfdlink.h \
+ ld.h ldexp.h ldver.h ldlang.h ldemul.h ldfile.h ldmisc.h \
+ ldmain.h mri.h ldctor.h ldlex.h
+ldlex.o: ldlex.c ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \
+ ld.h ldgram.h ldmisc.h ldexp.h ldlang.h ldfile.h ldlex.h \
+ ldmain.h
+deffilep.o: deffilep.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+ ../bfd/bfd.h sysdep.h config.h $(INCDIR)/fopen-same.h \
+ ld.h ldmisc.h deffile.h
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ld/NEWS b/ld/NEWS
new file mode 100644
index 00000000000..aa2e8452c2b
--- /dev/null
+++ b/ld/NEWS
@@ -0,0 +1,190 @@
+-*- text -*-
+
+Changes in version 2.10:
+
+* Added garbage collection of unused sections, enabled by --gc-sections.
+ It does require a bit of backend support; currently implemented are
+ ppc-elf, mips-elf, and mn10300-elf. Others will ignore the option.
+
+* Added SORT to the linker script language to permit sorting sections by file
+ name or section name.
+
+* Added EXTERN to the linker script language as an equivalent to the -u
+ command-line option.
+
+* Added ASSERT to the linker script language.
+
+* Added -O option to optimize linker output (as of this writing, this only
+affects ELF shared library generation).
+
+* The -e option now accepts a number as well as a symbol name.
+
+* Added --demangle and --no-demangle options.
+
+Changes in version 2.9:
+
+* Added SQUAD to the linker script language.
+
+* New option --no-warn-mismatch.
+
+* The MEMORY command now parses the attributes to determine where sections that
+ are not placed in a specific memory region are placed.
+
+Changes in version 2.8:
+
+* Linker scripts may now contain shell wildcard characters for file and section
+ names.
+
+* The linker now supports symbol versions in ELF.
+
+* The NOCROSSREFS command was added to the linker script language.
+
+* The LOADADDR expression was added to the linker script language.
+
+* MAX and MIN functions were added to the linker script language.
+
+* The OVERLAY construct was added to the linker script language.
+
+* New option --warn-section-align to warn when the address of an output section
+ changes due to alignment of an input section.
+
+* New options --filter/-F and --auxiliary/-f.
+
+Changes in version 2.7:
+
+* New option --cref to print out a cross reference table.
+
+* New option --wrap SYMBOL.
+
+* New option --no-whole-archive, to turn off the effect of --whole-archive.
+
+* Input sections assigned to the output section /DISCARD/ in the linker script
+ are not included in the output file.
+
+* The SunOS and ELF linkers now merge stabs debugging information which uses
+ the N_BINCL and N_EINCL stab types. This reduces the amount of debugging
+ information generated.
+
+Changes in version 2.6:
+
+* When an ELF section name is representable as a C identifier (this is not true
+of most ELF section names), the linker will automatically define symbols
+__start_SECNAME and __stop_SECNAME, where SECNAME is the section name, at the
+beginning and the end of the section. This is used by glibc.
+
+* When an ELF section named .gnu.warning is encountered in an input file, the
+contents of the section are displayed as an error message, and the section is
+not copied into the output file. This is used by glibc.
+
+* When an ELF section named .gnu.warning.SYMBOL is encountered in an input
+file, and the symbol SYMBOL is referenced by some object file, the contents of
+the section are displayed as an error message. The section is not copied into
+the output file, unless doing a relocateable or shared link. This is used by
+glibc.
+
+* New options -split-by-reloc and -split-by-file.
+
+* The linker now supports linking PIC compiled code on SPARC SunOS. It can
+also create SPARC SunOS shared libraries, and, like the native SunOS linker,
+will do so whenever there is an undefined symbol in the link and neither the -e
+nor the -r option was used.
+
+* The -rpath option may be used on SunOS to set the list of directories to be
+searched at run time. This overrides the default of building the list from the
+-L options.
+
+* The COFF linker now combines debugging information for structs, unions, and
+enums, so that even if the same type is defined in multiple input files it will
+only be defined once in the output file. The --traditional-format switch will
+prevent this optimization.
+
+Changes in version 2.5:
+
+* The linker now supports linking against SunOS shared libraries. It still can
+not link SunOS PIC (Position Independent Code) files, so it can not be used to
+generate shared libaries.
+
+* The linker now supports linking against ELF shared libraries for the i386
+(UnixWare) and SPARC (Solaris). It can also link ELF PIC files, and can be
+used to generate shared libraries. Shared library generation is not well
+tested; please report any problems encountered. The linker is now enabled for
+Solaris again.
+
+* Eric Youngdale has contributed Linux support code, including linking against
+Linux a.out shared libraries. The linker produces Linux QMAGIC binaries.
+
+* The ELF backend has been converted to the new linker code. To use the new
+ELF linker, each particular target requires a relocation function. So far,
+this function has been written for i386 (UnixWare), SPARC (Solaris) MIPS (Irix
+5), and HPPA ELF targets.
+
+* The -( (--start-group) and -) (--end-group) options have been added to
+support searching a group of archives as though they were a single archive.
+This can also be used in a linker script, as GROUP ( files ).
+
+* When a file is named on the command line, and the linker does not recognize
+it as an object file, the linker will now treat the file as a linker script
+file. A linker script named in this way augments, but does not replace, the
+default linker script.
+
+* The -warn-once option was added. It causes the linker to only warn once per
+undefined symbol, rather than once per reference.
+
+* The COFF backend has been converted to the new linker code. As with ELF, to
+use the new linker, each particular target requires a relocation function. So
+far, this function has been written for the i386, m68k, a29k and SH targets.
+
+* The -V flag was made a synonym for -v, for SVR4 compatibility. The old -V
+behaviour is available via --verbose.
+
+Changes in version 2.4:
+
+* New linker code, by Steve Chamberlain and Ian Taylor. For a.out and ecoff
+ formats (so far), this should result in considerable savings in time
+ and memory used while linking; slightly poorer performance than
+ before for formats not converted yet.
+
+* Command-line parsing is no longer done with flex. This means
+ oddball characters in filenames won't get treated as argument
+ separators.
+
+* HP-PA ELF support, by Jeff Law. (No SOM support yet.)
+
+* Mach i386 support, by David Mackenzie.
+
+* Irix 4 shared libraries are now supported (Irix 5 uses ELF, and ELF shared
+ libraries are not yet supported).
+
+* COFF shared libraries (as on SCO) should work as well.
+
+* The linker is disabled for Solaris. (Actually, it was in 2.3 also, I just
+ forgot to note it.) Some of their C library routines don't work when
+ statically linked, and the GNU linker doesn't support dynamic linking yet.
+
+Changes in version 2.3:
+
+* Weak symbols are now supported.
+
+* ELF support has been added. The linker has been bootstrapped on
+ UnixWare and Solaris.
+
+* Alpha OSF/1 support has been added (non dynamic linking only).
+
+Changes in version 2.2:
+
+* The `bfd' library has been updated to reduce a.out-format string
+ table size. The effect of this is that files linked from many input
+ files with duplicate symbols (`-g' debugging records, or identical
+ static symbols) should be much smaller.
+
+Changes in version 2.1:
+
+* The ld -ySYMBOL flag (to trace references to SYMBOL) is now implemented.
+
+* There is now support for writing ECOFF files, so ld and the
+ other utilities should work on Risc/Ultrix and Irix.
+
+
+Local variables:
+fill-column: 79
+End:
diff --git a/ld/README b/ld/README
new file mode 100644
index 00000000000..8947d04156b
--- /dev/null
+++ b/ld/README
@@ -0,0 +1,64 @@
+This is the GNU linker. It is distributed with other "binary
+utilities" which should be in ../binutils. See ../binutils/README for
+more general notes, including where to send bug reports.
+
+There are many features of the linker:
+
+* The linker uses a Binary File Descriptor library (../bfd)
+ that it uses to read and write object files. This helps
+ insulate the linker itself from the format of object files.
+
+* The linker supports a number of different object file
+ formats. It can even handle multiple formats at once:
+ Read two input formats and write a third.
+
+* The linker can be configured for cross-linking.
+
+* The linker supports a control language.
+
+* There is a user manual (ld.texinfo), as well as the
+ beginnings of an internals manual (ldint.texinfo).
+
+Installation
+============
+
+See ../binutils/README.
+
+If you want to make a cross-linker, you may want to specify
+a different search path of -lfoo libraries than the default.
+You can do this by setting the LIB_PATH variable in ./Makefile.
+
+To build just the linker, make the target all-ld from the top level
+directory (one directory above this one).
+
+Porting to a new target
+=======================
+
+See the ldint.texinfo manual.
+
+Reporting bugs etc
+===========================
+
+See ../binutils/README.
+
+Known problems
+==============
+
+The Solaris linker normally exports all dynamic symbols from an
+executable. The GNU linker does not do this by default. This is
+because the GNU linker tries to present the same interface for all
+similar targets (in this case, all native ELF targets). This does not
+matter for normal programs, but it can make a difference for programs
+which try to dlopen an executable, such as PERL or Tcl. You can make
+the GNU linker export all dynamic symbols with the -E or
+--export-dynamic command line option.
+
+HP/UX 9.01 has a shell bug that causes the linker scripts to be
+generated incorrectly. The symptom of this appears to be "fatal error
+- scanner input buffer overflow" error messages. There are various
+workarounds to this:
+ * Build and install bash, and build with "make SHELL=bash".
+ * Update to a version of HP/UX with a working shell (e.g., 9.05).
+ * Replace "(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc)" in
+ genscripts.sh with "sh ${srcdir}..." (no parens) and make sure the
+ emulparams script used exports any shell variables it sets.
diff --git a/ld/TODO b/ld/TODO
new file mode 100644
index 00000000000..31cd98ba236
--- /dev/null
+++ b/ld/TODO
@@ -0,0 +1,9 @@
+Volunteers to tackle some of the following would be welcome:
+
+Support the "traditional" BSD -A flag (incremental loading).
+(There is a -A flag in ld now, but it is used to specify the
+architecture. That should probably be changed.)
+
+Support for dynamic loading (a la dld, but bfd-based) would be nice.
+
+Avoid re-open (and re-seeking) output bfd and archives.
diff --git a/ld/acinclude.m4 b/ld/acinclude.m4
new file mode 100644
index 00000000000..71b09b9f6ac
--- /dev/null
+++ b/ld/acinclude.m4
@@ -0,0 +1 @@
+sinclude(../bfd/acinclude.m4)
diff --git a/ld/aclocal.m4 b/ld/aclocal.m4
new file mode 100644
index 00000000000..11934b0a67d
--- /dev/null
+++ b/ld/aclocal.m4
@@ -0,0 +1,1120 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+sinclude(../bfd/acinclude.m4)
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+# serial 35 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_REQUIRE([AC_SYS_SYMBOL_UNDERSCORE])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ AC_SYS_LIBTOOL_CYGWIN
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+AC_ARG_ENABLE(libtool-lock,
+[ --disable-libtool-lock force libtool not to do file locking],
+need_locks=$enableval,
+need_locks=yes)
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+])
+
+# AC_LIBTOOL_DLOPEN - check for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [lt_dlopen=yes])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED,
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED,
+[AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC,
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC,
+[AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL,
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL,
+[AC_ENABLE_FAST_INSTALL(no)])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_SYS_NM_PARSE - Check for command to grab the raw symbol name followed
+# by C symbol name from nm.
+AC_DEFUN(AC_SYS_NM_PARSE,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+changequote([,])dnl
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+changequote(,)dnl
+lt_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+])
+
+# AC_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin
+AC_DEFUN(AC_SYS_LIBTOOL_CYGWIN,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# AC_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
+# with an underscore?
+AC_DEFUN(AC_SYS_SYMBOL_UNDERSCORE,
+[AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+AC_SUBST(USE_SYMBOL_UNDERSCORE)dnl
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM, [
+AC_CHECK_LIB(mw, _mwvalidcheckl)
+AC_CHECK_LIB(m, cos)
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [
+ AC_CHECK_LIB(ltdl, main, LIBLTDL="-lltdl", [
+ case "$enable_ltdl_install" in
+ no) AC_MSG_WARN([libltdl not installed, but installation disabled]) ;;
+ "") enable_ltdl_install=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-install" ;;
+ esac
+ ])
+ if test x"$enable_ltdl_install" != x"no"; then
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+AC_DEFUN(AM_SYS_NM_PARSE, [indir([AC_SYS_NM_PARSE])])dnl
+AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE, [indir([AC_SYS_SYMBOL_UNDERSCORE])])dnl
+AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN, [indir([AC_SYS_LIBTOOL_CYGWIN])])dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
+
+dnl AM_PROG_LEX
+dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT
+AC_DEFUN(AM_PROG_LEX,
+[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1)
+AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex")
+AC_PROG_LEX
+AC_DECL_YYTEXT])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/ld/config.in b/ld/config.in
new file mode 100644
index 00000000000..a415046f435
--- /dev/null
+++ b/ld/config.in
@@ -0,0 +1,171 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the sbrk function. */
+#undef HAVE_SBRK
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
+/* Use b modifier when opening binary files? */
+#undef USE_BINARY_FOPEN
+
+/* Define if strstr is not declared in system header files. */
+#undef NEED_DECLARATION_STRSTR
+
+/* Define if free is not declared in system header files. */
+#undef NEED_DECLARATION_FREE
+
+/* Define if sbrk is not declared in system header files. */
+#undef NEED_DECLARATION_SBRK
+
+/* Define if getenv is not declared in system header files. */
+#undef NEED_DECLARATION_GETENV
+
+/* Define if environ is not declared in system header files. */
+#undef NEED_DECLARATION_ENVIRON
+
diff --git a/ld/configure b/ld/configure
new file mode 100755
index 00000000000..9d573b2192a
--- /dev/null
+++ b/ld/configure
@@ -0,0 +1,5214 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock force libtool not to do file locking"
+ac_help="$ac_help
+ --enable-targets alternative target configurations"
+ac_help="$ac_help
+ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=ldmain.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:594: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:615: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:633: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:668: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:721: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:778: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=ld
+
+VERSION=2.9.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:824: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:837: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:850: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:863: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:876: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:962: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:992: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1022: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1073: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1105: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1116 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1147: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1152: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1180: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1223: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1247: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1250: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1286: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1302: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:1340: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* \($ac_symcode\) *\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if { (eval echo configure:1407: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:1459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+echo "$ac_t""$ac_result" 1>&6
+
+echo $ac_n "checking for _ prefix in compiled symbols""... $ac_c" 1>&6
+echo "configure:1505: checking for _ prefix in compiled symbols" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_symbol_underscore'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if { (eval echo configure:1514: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { (eval echo configure:1517: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -rf conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_sys_symbol_underscore" 1>&6
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1543: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1585 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1586: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1607: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1612 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1642: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1674: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ DLLTOOL="false"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1709: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1741: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ AS="false"
+fi
+fi
+
+
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ need_locks=$enableval
+else
+ need_locks=yes
+fi
+
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+ case "${enableval}" in
+ yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; }
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi
+# Check whether --enable-64-bit-bfd or --disable-64-bit-bfd was given.
+if test "${enable_64_bit_bfd+set}" = set; then
+ enableval="$enable_64_bit_bfd"
+ case "${enableval}" in
+ yes) want64=true ;;
+ no) want64=false ;;
+ *) { echo "configure: error: bad value ${enableval} for 64-bit-bfd option" 1>&2; exit 1; } ;;
+esac
+else
+ want64=false
+fi
+
+
+
+
+
+if test -z "$target" ; then
+ { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; }
+fi
+if test -z "$host" ; then
+ { echo "configure: error: Unrecognized host system type; please check config.sub." 1>&2; exit 1; }
+fi
+
+# host-specific stuff:
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1910: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1940: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1991: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2023: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2034 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2065: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2070: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2079: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2098: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:2141: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+ALL_LINGUAS=
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2196: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2211 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2228 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2234: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2245 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:2276: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2297: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2302 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2310: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2327 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2345 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2366 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2401: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2406 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2455: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2476: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 2483 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2490: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2516: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2521 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2549: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2554 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:2584: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2589 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:2596: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:2617: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2622 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:2650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2682: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2687 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2712: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2717 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2767: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2775 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2819: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2824 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2829: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2858: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2863 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:2911: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2919 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:3059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3087: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3092 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3097: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3127: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3132 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3184: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3189 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3212: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:3246: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3251 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:3258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:3279: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:3299: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:3318: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3323 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3328: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:3345: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3350 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3357: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:3373: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3381 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:3392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:3408: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3413 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3448: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3482: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3487 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3537: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3573: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 3605 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:3613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3645: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3679: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3715: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:3805: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:3833: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3838 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:3906: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3911 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:3922: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:3939: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3944 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:3951: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:3970: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:3980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4006: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+missing_dir=`cd $ac_aux_dir && pwd`
+for ac_prog in flex lex
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4042: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=""$missing_dir/missing flex""
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:4075: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:4109: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4117 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:4128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:4151: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # The minimal lex program is just a single line: %%. But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:4172: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 4184 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:4191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+ cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:4214: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+. ${srcdir}/configure.host
+
+
+
+
+
+
+for ac_hdr in string.h strings.h stdlib.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4248: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4253 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4258: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in sbrk
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:4287: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4292 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:4344: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4349 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:4357: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:4382: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4390 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:4401: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:4423: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4431 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:4442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+
+case "${host}" in
+*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows)
+ cat >> confdefs.h <<\EOF
+#define USE_BINARY_FOPEN 1
+EOF
+ ;;
+esac
+
+echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6
+echo "configure:4475: checking whether strstr must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4480 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) strstr
+; return 0; }
+EOF
+if { (eval echo configure:4501: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_strstr=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_strstr" 1>&6
+if test $bfd_cv_decl_needed_strstr = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_STRSTR 1
+EOF
+
+fi
+
+echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
+echo "configure:4522: checking whether free must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4527 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) free
+; return 0; }
+EOF
+if { (eval echo configure:4548: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_free=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6
+if test $bfd_cv_decl_needed_free = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_FREE 1
+EOF
+
+fi
+
+echo $ac_n "checking whether sbrk must be declared""... $ac_c" 1>&6
+echo "configure:4569: checking whether sbrk must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_sbrk'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4574 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) sbrk
+; return 0; }
+EOF
+if { (eval echo configure:4595: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_sbrk=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_sbrk=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_sbrk" 1>&6
+if test $bfd_cv_decl_needed_sbrk = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_SBRK 1
+EOF
+
+fi
+
+echo $ac_n "checking whether getenv must be declared""... $ac_c" 1>&6
+echo "configure:4616: checking whether getenv must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_getenv'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4621 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) getenv
+; return 0; }
+EOF
+if { (eval echo configure:4642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_getenv=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_getenv=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_getenv" 1>&6
+if test $bfd_cv_decl_needed_getenv = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_GETENV 1
+EOF
+
+fi
+
+echo $ac_n "checking whether environ must be declared""... $ac_c" 1>&6
+echo "configure:4663: checking whether environ must be declared" >&5
+if eval "test \"`echo '$''{'bfd_cv_decl_needed_environ'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4668 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+int main() {
+char *(*pfn) = (char *(*)) environ
+; return 0; }
+EOF
+if { (eval echo configure:4689: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ bfd_cv_decl_needed_environ=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ bfd_cv_decl_needed_environ=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$bfd_cv_decl_needed_environ" 1>&6
+if test $bfd_cv_decl_needed_environ = yes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_DECLARATION_ENVIRON 1
+EOF
+
+fi
+
+
+# target-specific stuff:
+
+all_targets=
+EMUL=
+all_emuls=
+all_emul_extras=
+
+rm -f tdirs
+
+for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'`
+do
+ if test "$targ_alias" = "all"; then
+ all_targets=true
+ else
+ # Canonicalize the secondary target names.
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ_alias 2>/dev/null`
+ if test -n "$result"; then
+ targ=$result
+ else
+ targ=$targ_alias
+ fi
+
+ . ${srcdir}/configure.tgt
+
+ if test "$targ" = "$target"; then
+ EMUL=$targ_emul
+ fi
+
+ for i in $targ_emul $targ_extra_emuls; do
+ case " $all_emuls " in
+ *" e${i}.o "*) ;;
+ *)
+ all_emuls="$all_emuls e${i}.o"
+ eval result=\$tdir_$i
+ test -z "$result" && result=$targ_alias
+ echo tdir_$i=$result >> tdirs
+ ;;
+ esac
+ done
+
+ for i in $targ_extra_ofiles; do
+ case " $all_emul_extras " in
+ *" ${i} "*) ;;
+ *)
+ all_emul_extras="$all_emul_extras ${i}"
+ ;;
+ esac
+ done
+ fi
+done
+
+
+
+TDIRS=tdirs
+
+
+if test x${all_targets} = xtrue; then
+ if test x${want64} = xtrue; then
+ EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)'
+ else
+ EMULATION_OFILES='$(ALL_EMULATIONS)'
+ fi
+ EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)'
+else
+ EMULATION_OFILES=$all_emuls
+ EMUL_EXTRA_OFILES=$all_emul_extras
+fi
+
+
+
+if test x${enable_static} = xno; then
+ TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so"
+else
+ TESTBFDLIB="../bfd/.libs/libbfd.a"
+fi
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile po/Makefile.in:po/Make-in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@USE_SYMBOL_UNDERSCORE@%$USE_SYMBOL_UNDERSCORE%g
+s%@LN_S@%$LN_S%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@EXEEXT@%$EXEEXT%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@HDEFINES@%$HDEFINES%g
+s%@HOSTING_CRT0@%$HOSTING_CRT0%g
+s%@HOSTING_LIBS@%$HOSTING_LIBS%g
+s%@NATIVE_LIB_DIRS@%$NATIVE_LIB_DIRS%g
+s%@EMUL@%$EMUL%g
+/@TDIRS@/r $TDIRS
+s%@TDIRS@%%g
+s%@EMULATION_OFILES@%$EMULATION_OFILES%g
+s%@EMUL_EXTRA_OFILES@%$EMUL_EXTRA_OFILES%g
+s%@TESTBFDLIB@%$TESTBFDLIB%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile po/Makefile.in:po/Make-in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/ld/configure.bat b/ld/configure.bat
new file mode 100644
index 00000000000..4643bdb5540
--- /dev/null
+++ b/ld/configure.bat
@@ -0,0 +1,72 @@
+@echo off
+echo Configuring ld for go32
+echo This makefile will be built for GNUISH make
+rem This batch file assumes a unix-type "sed" program
+
+update ..\bfd\hosts\go32.h sysdep.h
+
+echo # Makefile generated by "configure.bat"> Makefile
+echo LONGARGS = gcc:ar >> Makefile
+echo CC=gcc >> Makefile
+echo host_alias=go32 >> Makefile
+echo target_alias=go32 >> Makefile
+
+update ../bfd/hosts/go32.h sysdep.h
+
+if exist config.sed del config.sed
+
+echo "s/^ \$(srcdir)\/move-if-change/ update/ ">> config.sed
+echo "s/:\([^ ]\)/: \1/g ">> config.sed
+echo "s/^ \ *\.\// go32 / ">> config.sed
+echo "s/`echo \$(srcdir)\///g ">> config.sed
+echo "s/ | sed 's,\^\\\.\/,,'`//g ">> config.sed
+echo "s/^ cd \$(srcdir)[ ]*;// ">> config.sed
+
+echo "/^####$/ i\ ">> config.sed
+echo "CC = gcc\ ">> config.sed
+echo "EMUL=go32\ ">> config.sed
+echo "EMULATION_OFILES=ego32.o ei386aout.o ">> config.sed
+
+echo "/^SHELL *=/ d ">> config.sed
+echo "s/$(SHELL)/sh.exe/g ">> config.sed
+
+echo "s/'"/\\"/g ">> config.sed
+echo "s/"'/\\"/g ">> config.sed
+
+echo "/^ldmain.o: ldmain.c/,/fi/ { ">> config.sed
+echo " s/; *\\$// ">> config.sed
+echo " s/-DSCRIPTDIR[^ ]*/-DSCRIPTDIR=\\".\\"/ ">> config.sed
+echo " s/config.status// ">> config.sed
+echo " /ldmain.o:/ p ">> config.sed
+echo " /(CC)/ p ">> config.sed
+echo " d ">> config.sed
+echo "} ">> config.sed
+
+echo "s/^SHELL.*$/SHELL=sh.exe/ ">> config.sed
+echo "s/genscripts.sh/genscripts.dos/g ">> config.sed
+
+echo "s/^ldemul-list.h/not-ldemul-list.h/ ">> config.sed
+
+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
+sed -f config2.sed Makefile.in >> Makefile
+del config.sed
+del config2.sed
+
+echo set -a > genscripts.dj
+sed -e "/^[a-zA-Z0-9_]*=/ s/^/export /" -e "s/(. \(.*\))/sh \1/" -e "/\.em/ d" genscripts.sh >> genscripts.dj
+type emultempl\generic.em >> genscripts.dj
+update genscripts.dj genscripts.dos
+
+echo extern ld_emulation_xfer_type ld_go32_emulation; > ldemul-list.h2
+echo extern ld_emulation_xfer_type ld_i386aout_emulation; >> ldemul-list.h2
+echo #define EMULATION_LIST \>>ldemul-list.h2
+echo &ld_go32_emulation,\>>ldemul-list.h2
+echo &ld_i386aout_emulation,\>>ldemul-list.h2
+echo 0>>ldemul-list.h2
+
+update ldemul-list.h2 ldemul-list.h
+
+if exist ldscripts\dostest goto ldscripts
+mkdir ldscripts
+dir > ldscripts\dostest
+:ldscripts
diff --git a/ld/configure.host b/ld/configure.host
new file mode 100644
index 00000000000..88eb311c49a
--- /dev/null
+++ b/ld/configure.host
@@ -0,0 +1,171 @@
+# This is the linker host specific file. This is invoked by the
+# autoconf generated configure script. Putting it in a separate shell
+# file lets us skip running autoconf when modifying host specific
+# information.
+
+# This file sets the following shell variables:
+# HDEFINES host specific compiler flags
+# HOSTING_CRT0 crt0.o file used for bootstrapping
+# HOSTING_LIBS libraries used for bootstrapping
+# NATIVE_LIB_DIRS library directories to search on this host
+
+HDEFINES=
+HOSTING_CRT0=/lib/crt0.o
+HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc'
+NATIVE_LIB_DIRS=
+
+case "${host}" in
+
+alpha*-*-linux-gnu*)
+ HOSTING_CRT0='-dynamic-linker `egrep "ld[^ ]*\.so" \`gcc --print-file-name=specs\` | sed -e "s,.*-dynamic-linker[ ][ ]*\(.*/ld[^ ]*.so..\).*,\1,"` `gcc --print-file-name=crt1.o` `gcc --print-file-name=crti.o` `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -L`dirname \`gcc --print-file-name=libc.so\`` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` `gcc --print-file-name=crtn.o`'
+ ;;
+
+alpha*-*-netbsd*)
+ # The new BSD `make' has a bug: it doesn't pass empty arguments in
+ # shell commands. So we need to make this value non-empty in order
+ # for the genscripts.sh call to work. There's nothing magic about
+ # the value `/lib'; it's just a dummy.
+ NATIVE_LIB_DIRS=/lib
+ HOSTING_CRT0=/usr/lib/crt0.o
+ ;;
+
+alpha*-*-*)
+ HOSTING_CRT0=/usr/ccs/lib/crt0.o
+ NATIVE_LIB_DIRS=/usr/ccs/lib
+ ;;
+
+i[3456]86-*-bsd* | i[3456]86-*-freebsd* | i[3456]86-*-netbsd*)
+ # The new BSD `make' has a bug: it doesn't pass empty arguments in
+ # shell commands. So we need to make this value non-empty in order
+ # for the genscripts.sh call to work. There's nothing magic about
+ # the value `/lib'; it's just a dummy.
+ NATIVE_LIB_DIRS=/lib
+ HOSTING_CRT0=/usr/lib/crt0.o
+ ;;
+
+i[3456]86-*-sysv4*)
+ HOSTING_CRT0='/usr/ccs/lib/crt1.o /usr/ccs/lib/crti.o /usr/ccs/lib/values-Xa.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` /usr/ccs/lib/crtn.o'
+ NATIVE_LIB_DIRS=/usr/ccs/lib
+ ;;
+
+i[3456]86-sequent-ptx* | i[3456]86-sequent-sysv*)
+ HOSTING_CRT0='/lib/crt0.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi`'
+ ;;
+
+i[3456]86-*-sysv*)
+ HOSTING_CRT0='/lib/crt1.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; fi` /lib/crtn.o'
+ ;;
+
+i[3456]86-*-solaris*)
+ HOSTING_CRT0='`if [ -f ../gcc/crt1.o ]; then echo ../gcc/crt1.o; else gcc -print-file-name=crt1.o; fi` `if [ -f ../gcc/crti.o ]; then echo ../gcc/crti.o; else gcc -print-file-name=crti.o; fi` /usr/ccs/lib/values-Xa.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` `if [ -f ../gcc/crtn.o ]; then echo ../gcc/crtn.o; else gcc -print-file-name=crtn.o; fi`'
+ NATIVE_LIB_DIRS=/usr/ccs/lib
+ ;;
+
+i[3456]86-*-sco* | i[3456]86-*-isc*)
+ # In some configurations gcc does not use crtbegin.o and crtend.o.
+ # In that case gcc -print-file-name=crtbegin.o will simply print
+ # crtbegin.o. We create dummy crtbegin.o and crtend.o files to
+ # handle this.
+ echo "int dummy_crtbegin () { return 0; }" > crtbegin.c
+ ${CC} -c crtbegin.c -o crtbegin.o
+ rm -f crtbegin.c
+ echo "int dummy_crteng () { return 0; }" > crtend.c
+ ${CC} -c crtend.c -o crtend.o
+ rm -f crtend.c
+ HOSTING_CRT0='/lib/crt1.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` /lib/crtn.o'
+ ;;
+
+i[3456]86-*-linux*aout* | i[3456]86-*-linuxoldld)
+ HOSTING_CRT0=/usr/lib/crt0.o
+ ;;
+
+i[3456]86-*-linux*libc1*)
+ HOSTING_CRT0='-dynamic-linker /lib/ld-linux.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; elif [ -f /usr/lib/crtbegin.o ]; then echo /usr/lib/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; elif [ -f /usr/lib/crtend.o ]; then echo /usr/lib/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o'
+ ;;
+
+i[3456]86-*-linux-gnu*)
+ HOSTING_CRT0='-dynamic-linker `fgrep ld-linux.so \`gcc --print-file-name=specs\` | sed -e "s,.*-dynamic-linker[ ][ ]*\(.*/ld-linux.so..\).*,\1,"` `gcc --print-file-name=crt1.o` `gcc --print-file-name=crti.o` `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -L`dirname \`gcc --print-file-name=libc.so\`` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` `gcc --print-file-name=crtn.o`'
+ ;;
+
+i[3456]86-*-lynxos*)
+ HOSTING_CRT0=/lib/init1.o
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc -lm /lib/initn.o'
+ ;;
+
+mips*-dec-bsd*)
+ HOSTING_CRT0=/usr/lib/crt0.o
+ ;;
+
+mips*-sgi-irix4*)
+ HOSTING_CRT0=/usr/lib/crt1.o
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc /usr/lib/crtn.o'
+ ;;
+
+mips*-sgi-irix[56]*)
+ HOSTING_CRT0=/usr/lib/crt1.o
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc /usr/lib/crtn.o'
+ ;;
+
+m68*-*-linux*aout*)
+ HOSTING_CRT0=/usr/lib/crt0.o
+ ;;
+
+m68*-*-linux*libc1*)
+ HOSTING_CRT0='-dynamic-linker /lib/ld-linux.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; elif [ -f /usr/lib/crtbegin.o ]; then echo /usr/lib/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; elif [ -f /usr/lib/crtend.o ]; then echo /usr/lib/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o'
+ ;;
+
+m68*-*-linux-gnu*)
+ HOSTING_CRT0='-dynamic-linker /lib/ld.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o'
+ ;;
+
+m68*-*-lynxos*)
+ HOSTING_CRT0=/lib/init1.o
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc -lm /lib/initn.o'
+ ;;
+
+m68*-motorola-sysv)
+ HOSTING_CRT0='`if [ -f ../gcc/crt0.o ]; then echo ../gcc/crt0.o; elif [ -f \`gcc -print-file-name=\`crt0.o ]; then echo \`gcc -print-file-name=\`crt0.o; else echo /lib/crt0.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc881 `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi`'
+ ;;
+
+m68*-sun-*)
+ HOSTING_CRT0='/usr/lib/crt0.o /usr/lib/Fcrt1.o -L/usr/lib/fsoft.o'
+ ;;
+
+m88*-*-dgux*)
+ HDEFINES=-D__using_DGUX
+ HOSTING_CRT0='/lib/crt0.o -X'
+ HOSTING_LIBS=/usr/sde/m88kbcs/lib/libc.a
+ ;;
+
+m88*-motorola-sysv3)
+ HOSTING_CRT0='/lib/crt0.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi`'
+ ;;
+
+powerpc*-*-linux-gnu*)
+ HOSTING_CRT0='-dynamic-linker /lib/ld.so.1 /usr/lib/crt1.o /usr/lib/crti.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc --print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc --print-file-name=crtend.o; fi` /usr/lib/crtn.o'
+ ;;
+
+romp-*-*)
+ HDEFINES=-DNO_VARARGS
+ ;;
+
+sparc*-*-solaris2*)
+ HOSTING_CRT0='`if [ -f ../gcc/crt1.o ]; then echo ../gcc/crt1.o; else gcc -print-file-name=crt1.o; fi` `if [ -f ../gcc/crti.o ]; then echo ../gcc/crti.o; else gcc -print-file-name=crti.o; fi` /usr/ccs/lib/values-Xa.o `if [ -f ../gcc/crtbegin.o ]; then echo ../gcc/crtbegin.o; else gcc -print-file-name=crtbegin.o; fi`'
+ HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else gcc -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/crtend.o ]; then echo ../gcc/crtend.o; else gcc -print-file-name=crtend.o; fi` `if [ -f ../gcc/crtn.o ]; then echo ../gcc/crtn.o; else gcc -print-file-name=crtn.o; fi`'
+ NATIVE_LIB_DIRS=/usr/ccs/lib
+ ;;
+
+esac
diff --git a/ld/configure.in b/ld/configure.in
new file mode 100644
index 00000000000..7f3c1da51cd
--- /dev/null
+++ b/ld/configure.in
@@ -0,0 +1,156 @@
+dnl Process this file with autoconf to produce a configure script
+dnl
+AC_PREREG(2.13)
+AC_INIT(ldmain.c)
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE(ld, 2.9.4)
+
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(targets,
+[ --enable-targets alternative target configurations],
+[case "${enableval}" in
+ yes | "") AC_ERROR(enable-targets option must specify target names or 'all')
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac])dnl
+AC_ARG_ENABLE(64-bit-bfd,
+[ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)],
+[case "${enableval}" in
+ yes) want64=true ;;
+ no) want64=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for 64-bit-bfd option) ;;
+esac],[want64=false])dnl
+
+AM_CONFIG_HEADER(config.h:config.in)
+
+if test -z "$target" ; then
+ AC_MSG_ERROR(Unrecognized target system type; please check config.sub.)
+fi
+if test -z "$host" ; then
+ AC_MSG_ERROR(Unrecognized host system type; please check config.sub.)
+fi
+
+# host-specific stuff:
+
+AC_PROG_CC
+AC_PROG_INSTALL
+
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+AC_EXEEXT
+
+AC_PROG_YACC
+AM_PROG_LEX
+
+AM_MAINTAINER_MODE
+
+. ${srcdir}/configure.host
+
+AC_SUBST(HDEFINES)
+AC_SUBST(HOSTING_CRT0)
+AC_SUBST(HOSTING_LIBS)
+AC_SUBST(NATIVE_LIB_DIRS)
+
+AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h)
+AC_CHECK_FUNCS(sbrk)
+AC_HEADER_DIRENT
+
+BFD_BINARY_FOPEN
+
+BFD_NEED_DECLARATION(strstr)
+BFD_NEED_DECLARATION(free)
+BFD_NEED_DECLARATION(sbrk)
+BFD_NEED_DECLARATION(getenv)
+BFD_NEED_DECLARATION(environ)
+
+# target-specific stuff:
+
+all_targets=
+EMUL=
+all_emuls=
+all_emul_extras=
+
+dnl We need to get an arbitrary number of tdir definitions into
+dnl Makefile. We can't do it using AC_SUBST, because autoconf does
+dnl not permit literal newlines in an AC_SUBST variables. So we use a
+dnl file.
+rm -f tdirs
+
+for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'`
+do
+ if test "$targ_alias" = "all"; then
+ all_targets=true
+ else
+ # Canonicalize the secondary target names.
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ_alias 2>/dev/null`
+ if test -n "$result"; then
+ targ=$result
+ else
+ targ=$targ_alias
+ fi
+
+ . ${srcdir}/configure.tgt
+
+ if test "$targ" = "$target"; then
+ EMUL=$targ_emul
+ fi
+
+ for i in $targ_emul $targ_extra_emuls; do
+ case " $all_emuls " in
+ *" e${i}.o "*) ;;
+ *)
+ all_emuls="$all_emuls e${i}.o"
+ eval result=\$tdir_$i
+ test -z "$result" && result=$targ_alias
+ echo tdir_$i=$result >> tdirs
+ ;;
+ esac
+ done
+
+ for i in $targ_extra_ofiles; do
+ case " $all_emul_extras " in
+ *" ${i} "*) ;;
+ *)
+ all_emul_extras="$all_emul_extras ${i}"
+ ;;
+ esac
+ done
+ fi
+done
+
+AC_SUBST(EMUL)
+
+TDIRS=tdirs
+AC_SUBST_FILE(TDIRS)
+
+dnl FIXME: We will build a 64 bit BFD for a 64 bit host or a 64 bit
+dnl target, and in those cases we should also build the 64 bit
+dnl emulations.
+if test x${all_targets} = xtrue; then
+ if test x${want64} = xtrue; then
+ EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)'
+ else
+ EMULATION_OFILES='$(ALL_EMULATIONS)'
+ fi
+ EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES)'
+else
+ EMULATION_OFILES=$all_emuls
+ EMUL_EXTRA_OFILES=$all_emul_extras
+fi
+AC_SUBST(EMULATION_OFILES)
+AC_SUBST(EMUL_EXTRA_OFILES)
+
+if test x${enable_static} = xno; then
+ TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so"
+else
+ TESTBFDLIB="../bfd/.libs/libbfd.a"
+fi
+AC_SUBST(TESTBFDLIB)
+
+AC_OUTPUT(Makefile po/Makefile.in:po/Make-in,
+[sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile])
diff --git a/ld/configure.tgt b/ld/configure.tgt
new file mode 100644
index 00000000000..d0555cebab2
--- /dev/null
+++ b/ld/configure.tgt
@@ -0,0 +1,249 @@
+# This is the linker target specific file. This is invoked by the
+# autoconf generated configure script. Putting it in a separate shell
+# file lets us skip running autoconf when modifying target specific
+# information.
+
+# This file switches on the shell variable ${targ}, and sets the
+# following shell variables:
+# targ_emul name of linker emulation to use
+# targ_extra_emuls additional linker emulations to provide
+# targ_extra_ofiles additional objects needed by the emulation
+
+targ_extra_emuls=
+targ_extra_ofiles=
+
+case "${targ}" in
+arm-epoc-pe) targ_emul=arm_epoc_pe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+arm-*-pe) targ_emul=armpe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+arc-*-elf*) targ_emul=arcelf ;;
+d10v-*-*) targ_emul=d10velf ;;
+d30v-*-*ext*) targ_emul=d30v_e; targ_extra_emuls="d30velf d30v_o" ;;
+d30v-*-*onchip*) targ_emul=d30v_o; targ_extra_emuls="d30velf d30v_e" ;;
+d30v-*-*) targ_emul=d30velf; targ_extra_emuls="d30v_e d30v_o" ;;
+sparc64-*-aout*) targ_emul=sparcaout ;;
+sparc64-*-elf*) targ_emul=elf64_sparc ;;
+sparc-sun-sunos4*) targ_emul=sun4 ;;
+sparclite*-*-elf) targ_emul=elf32_sparc ;;
+sparclite*-*-coff) targ_emul=coff_sparc ;;
+sparclite*-fujitsu-*) targ_emul=sparcaout ;;
+sparc*-*-aout) targ_emul=sparcaout ;;
+sparc*-*-coff) targ_emul=coff_sparc ;;
+sparc*-*-elf) targ_emul=elf32_sparc ;;
+sparc*-*-sysv4*) targ_emul=elf32_sparc ;;
+sparc*-*-linux*aout*) targ_emul=sparclinux
+ targ_extra_emuls="elf32_sparc sun4"
+ tdir_elf32_sparc=`echo ${targ_alias} | sed -e 's/aout//'`
+ tdir_sun4=sparc-sun-sunos4
+ ;;
+sparc64-*-linux-gnu*) targ_emul=elf64_sparc
+ targ_extra_emuls="elf32_sparc sparclinux sun4"
+ tdir_elf32_sparc=`echo ${targ_alias} | sed -e 's/64//'`
+ tdir_sparclinux=${tdir_elf32_sparc}aout
+ tdir_sun4=sparc-sun-sunos4
+ ;;
+sparc*-*-linux-gnu*) targ_emul=elf32_sparc
+ targ_extra_emuls="sparclinux sun4"
+ tdir_sparclinux=${targ_alias}aout
+ tdir_sun4=sparc-sun-sunos4
+ ;;
+sparc*-*-lynxos*) targ_emul=sparclynx ;;
+sparc*-*-netbsd*) targ_emul=sparcnbsd ;;
+sparc*-*-solaris2*) targ_emul=elf32_sparc ;;
+sparc*-wrs-vxworks*) targ_emul=sparcaout ;;
+sparc*-*-rtems*) targ_emul=sparcaout ;;
+i960-wrs-vxworks5.0*) targ_emul=gld960 ;;
+i960-wrs-vxworks5*) targ_emul=gld960coff ;;
+i960-wrs-vxworks*) targ_emul=gld960 ;;
+i960-*-coff) targ_emul=gld960coff ;;
+i960-intel-nindy) targ_emul=gld960 ;;
+i960-*-rtems*) targ_emul=gld960coff ;;
+m32r-*-*) targ_emul=m32relf ;;
+m68*-sun-sunos[34]*) targ_emul=sun3 ;;
+m68*-wrs-vxworks*) targ_emul=sun3 ;;
+m68*-ericsson-ose) targ_emul=sun3 ;;
+m68*-apple-aux*) targ_emul=m68kaux ;;
+*-tandem-none) targ_emul=st2000 ;;
+i[3456]86-*-vsta) targ_emul=vsta ;;
+i[3456]86-go32-rtems*) targ_emul=i386go32 ;;
+i[3456]86-*-go32) targ_emul=i386go32 ;;
+i[3456]86-*-msdosdjgpp*) targ_emul=i386go32 ;;
+i[3456]86-*-aix*) targ_emul=i386coff ;;
+i[3456]86-*-sco*) targ_emul=i386coff ;;
+i[3456]86-*-isc*) targ_emul=i386coff ;;
+i[3456]86-*-lynxos*) targ_emul=i386lynx ;;
+i[3456]86-*-coff) targ_emul=i386coff ;;
+i[3456]86-*-rtems*) targ_emul=i386coff ;;
+i[3456]86-*-bsd) targ_emul=i386bsd ;;
+i[3456]86-*-bsd386) targ_emul=i386bsd ;;
+i[3456]86-*-bsdi*) targ_emul=i386bsd ;;
+i[3456]86-*-aout) targ_emul=i386aout ;;
+i[3456]86-*-linux*aout*) targ_emul=i386linux
+ targ_extra_emuls=elf_i386
+ tdir_elf_i386=`echo ${targ_alias} | sed -e 's/aout//'`
+ ;;
+i[3456]86-*-linuxoldld) targ_emul=i386linux; targ_extra_emuls=elf_i386 ;;
+i[3456]86-*-linux-gnu*) targ_emul=elf_i386
+ targ_extra_emuls=i386linux
+ tdir_i386linux=${targ_alias}aout
+ ;;
+i[3456]86-*-sysv4*) targ_emul=elf_i386 ;;
+i[3456]86-*-solaris2*) targ_emul=elf_i386 ;;
+i[3456]86-*-unixware) targ_emul=elf_i386 ;;
+i[3456]86-*-solaris*) targ_emul=elf_i386 ;;
+i[3456]86-*-netbsd*) targ_emul=i386nbsd ;;
+i[3456]86-*-netware) targ_emul=i386nw ;;
+i[3456]86-*-elf*) targ_emul=elf_i386 ;;
+i[3456]86-*-freebsdelf*) targ_emul=elf_i386 ;;
+i[3456]86-*-freebsd*) targ_emul=i386bsd ;;
+i[3456]86-*-sysv*) targ_emul=i386coff ;;
+i[3456]86-*-ptx*) targ_emul=i386coff ;;
+i[3456]86-*-mach*) targ_emul=i386mach ;;
+i[3456]86-*-gnu*) targ_emul=elf_i386 ;;
+i[3456]86-*-msdos*) targ_emul=i386msdos; targ_extra_emuls=i386aout ;;
+i[3456]86-*-moss*) targ_emul=i386moss; targ_extra_emuls=i386msdos ;;
+i[3456]86-*-winnt*) targ_emul=i386pe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+i[3456]86-*-pe) targ_emul=i386pe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+i[3456]86-*-cygwin*) targ_emul=i386pe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+i[3456]86-*-mingw32*) targ_emul=i386pe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+i[3456]86-*-beospe*) targ_emul=i386beos ;;
+i[3456]86-*-beos*) targ_emul=elf_i386_be ;;
+m8*-*-*) targ_emul=m88kbcs ;;
+a29k-*-udi) targ_emul=sa29200 ;;
+a29k-*-ebmon) targ_emul=ebmon29k ;;
+a29k-*-*) targ_emul=a29k ;;
+# arm-*-riscix*) targ_emul=riscix ;;
+arm-*-aout | armel-*-aout) targ_emul=armaoutl ;;
+armeb-*-aout) targ_emul=armaoutb ;;
+arm-*-coff) targ_emul=armcoff ;;
+arm-*-elf) targ_emul=armelf ;;
+arm-*-oabi) targ_emul=armelf_oabi ;;
+arm*-*-linux-gnu*) targ_emul=armelf_linux; targ_extra_emuls="armelf_linux26 armelf";;
+strongarm-*-coff) targ_emul=armcoff ;;
+strongarm-*-elf) targ_emul=armelf ;;
+thumb-*-coff) targ_emul=armcoff ;;
+thumb-*-elf) targ_emul=armelf ;;
+thumb-*-oabi) targ_emul=armelf_oabi ;;
+thumb-epoc-pe) targ_emul=arm_epoc_pe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+thumb-*-pe) targ_emul=armpe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+h8300-*-hms* | h8300-*-coff*)
+ targ_emul=h8300; targ_extra_emuls="h8300h h8300s"
+ ;;
+h8500-*-hms* | h8500-*-coff*)
+ targ_emul=h8500
+ targ_extra_emuls="h8500s h8500b h8500m h8500c"
+ ;;
+sh-*-elf*) targ_emul=shelf
+ targ_extra_emuls="shlelf sh shl"
+ ;;
+sh-*-*|sh-*-rtems*) targ_emul=sh; targ_extra_emuls=shl ;;
+m68k-sony-*) targ_emul=news ;;
+m68k-hp-bsd*) targ_emul=hp300bsd ;;
+m68*-motorola-sysv*) targ_emul=delta68 ;;
+m68*-*-aout) targ_emul=m68kaout ;;
+m68*-*-coff) targ_emul=m68kcoff ;;
+m68*-*-elf) targ_emul=m68kelf ;;
+m68*-*-hpux*) targ_emul=hp3hpux ;;
+m68k-*-linux*aout*) targ_emul=m68klinux
+ targ_extra_emuls=m68kelf
+ tdir_m68kelf=`echo ${targ_alias} | sed -e 's/aout//'`
+ ;;
+m68k-*-linux-gnu*) targ_emul=m68kelf
+ targ_extra_emuls=m68klinux
+ tdir_m68klinux=`echo ${targ_alias} | sed -e 's/linux/linuxaout/'`
+ ;;
+m68*-*-gnu*) targ_emul=m68kelf ;;
+m68*-*-lynxos*) targ_emul=m68klynx ;;
+m68*-hp*-netbsd*) targ_emul=m68k4knbsd ;;
+m68*-*-netbsd*) targ_emul=m68knbsd ;;
+m68*-*-psos*) targ_emul=m68kpsos ;;
+m68*-*-rtems*) targ_emul=m68kcoff ;;
+hppa*-*-*elf*) targ_emul=hppaelf ;;
+hppa*-*-lites*) targ_emul=hppaelf ;;
+hppa*-*-rtems*) targ_emul=hppaelf ;;
+vax-dec-ultrix* | vax-dec-bsd*) targ_emul=vax ;;
+mips*-dec-ultrix*) targ_emul=mipslit ;;
+mips*-dec-osf*) targ_emul=mipslit ;;
+mips*-sgi-irix[56]*) targ_emul=elf32bsmip ;;
+mips*-sgi-irix*) targ_emul=mipsbig ;;
+mips*el-*-ecoff*) targ_emul=mipsidtl ;;
+mips*-*-ecoff*) targ_emul=mipsidt ;;
+mips*-dec-bsd*) targ_emul=mipsbsd ;;
+mips*-dec-netbsd*) targ_emul=elf32lmip ;;
+mips*-*-bsd*) targ_emul=mipsbig ;;
+mips*vr4300el-*-elf*) targ_emul=elf32l4300 ;;
+mips*vr4300-*-elf*) targ_emul=elf32b4300 ;;
+mips*vr4100el-*-elf*) targ_emul=elf32l4300 ;;
+mips*vr4100-*-elf*) targ_emul=elf32b4300 ;;
+mips*vr5000el-*-elf*) targ_emul=elf32l4300 ;;
+mips*vr5000-*-elf*) targ_emul=elf32b4300 ;;
+mips*el-*-elf*) targ_emul=elf32elmip ;;
+mips*-*-elf*) targ_emul=elf32ebmip ;;
+mips*-*-rtems*) targ_emul=elf32ebmip ;;
+mips*-*-vxworks*) targ_emul=elf32ebmip ;;
+mips*el-*-linux-gnu*) targ_emul=elf32lsmip
+ targ_extra_emuls="elf32bsmip mipslit mipsbig"
+ ;;
+mips*-*-linux-gnu*) targ_emul=elf32bsmip
+ targ_extra_emuls="elf32lsmip mipsbig mipslit"
+ ;;
+mips*-*-lnews*) targ_emul=mipslnews ;;
+mn10200-*-*) targ_emul=mn10200 ;;
+mn10300-*-*) targ_emul=mn10300 ;;
+alpha*-*-linuxecoff*) targ_emul=alpha targ_extra_emuls=elf64alpha
+ tdir_elf64alpha=`echo ${targ_alias} | sed -e 's/ecoff//'`
+ ;;
+alpha*-*-linux-gnu*) targ_emul=elf64alpha targ_extra_emuls=alpha
+ tdir_alpha=`echo ${targ_alias} | sed -e 's/linux/linuxecoff/'`
+ ;;
+alpha*-*-osf*) targ_emul=alpha ;;
+alpha*-*-gnu*) targ_emul=elf64alpha ;;
+alpha*-*-netware*) targ_emul=alpha ;;
+alpha*-*-netbsd*) targ_emul=elf64alpha ;;
+z8k-*-coff) targ_emul=z8002; targ_extra_emuls=z8001 ;;
+ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;;
+ns32k-pc532-netbsd* | ns32k-pc532-lites*) targ_emul=ns32knbsd ;;
+powerpc-*-elf* | powerpc-*-eabi* | powerpc-*-linux-gnu* | powerpc-*-sysv* \
+ | powerpc-*-netbsd* | powerpc-*-vxworks*)
+ targ_emul=elf32ppc ;;
+powerpcle-*-elf* | powerpcle-*-eabi* | powerpcle-*-solaris* \
+ | powerpcle-*-sysv* | powerpcle-*-vxworks*)
+ targ_emul=elf32lppc ;;
+powerpc-*-rtems*) targ_emul=elf32ppc ;;
+powerpc-*-macos*) targ_emul=ppcmacos ;;
+powerpc-*-netware*) targ_emul=ppcnw ;;
+powerpcle-*-pe) targ_emul=ppcpe ;;
+powerpcle-*-winnt*) targ_emul=ppcpe ;;
+powerpcle-*-cygwin*) targ_emul=ppcpe ;;
+powerpc-*-aix*) targ_emul=aixppc ;;
+powerpc-*-beos*) targ_emul=aixppc ;;
+rs6000-*-aix*) targ_emul=aixrs6 ;;
+tic30-*-*aout*) targ_emul=tic30aout ;;
+tic30-*-*coff*) targ_emul=tic30coff ;;
+tic80-*-*) targ_emul=tic80coff ;;
+v850-*-*) targ_emul=v850 ;;
+v850e-*-*) targ_emul=v850 ;;
+v850ea-*-*) targ_emul=v850 ;;
+w65-*-*) targ_emul=w65 ;;
+fr30-*-*) targ_emul=elf32fr30 ;;
+mcore-*-pe) targ_emul=mcorepe ;
+ targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+mcore-*-elf) targ_emul=elf32mcore ;;
+*-*-aout) targ_emul=${target_cpu}-${target_vendor} ;;
+*-*-coff) targ_emul=${target_cpu}-${target_vendor} ;;
+*-*-netware) targ_emul=${target_cpu}-nw ;;
+*-*-ieee*) targ_emul=vanilla ;;
+
+*)
+ echo 2>&1 "*** ld does not support target ${targ}"
+ echo 2>&1 "*** see ld/configure.tgt for supported targets"
+ exit 1
+
+esac
diff --git a/ld/deffile.h b/ld/deffile.h
new file mode 100644
index 00000000000..3c6c1cee918
--- /dev/null
+++ b/ld/deffile.h
@@ -0,0 +1,123 @@
+/* deffile.h - header for .DEF file parser
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Written by DJ Delorie dj@cygnus.com
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "ansidecl.h"
+
+/* DEF storage definitions. Note that any ordinal may be zero, and
+ any pointer may be NULL, if not defined by the DEF file. */
+
+typedef struct def_file_section
+ {
+ char *name; /* always set */
+ char *class; /* may be NULL */
+ char flag_read, flag_write, flag_execute, flag_shared;
+ }
+def_file_section;
+
+typedef struct def_file_export
+ {
+ char *name; /* always set */
+ char *internal_name; /* always set, may == name */
+ int ordinal; /* -1 if not specified */
+ int hint;
+ char flag_private, flag_constant, flag_noname, flag_data;
+ }
+def_file_export;
+
+typedef struct def_file_module
+ {
+ struct def_file_module *next;
+ void *user_data;
+ char name[1]; /* extended via malloc */
+ }
+def_file_module;
+
+typedef struct def_file_import
+ {
+ char *internal_name; /* always set */
+ def_file_module *module; /* always set */
+ char *name; /* may be NULL; either this or ordinal will be set */
+ int ordinal; /* may be -1 */
+ }
+def_file_import;
+
+typedef struct def_file
+ {
+
+ /* from the NAME or LIBRARY command */
+ char *name;
+ int is_dll; /* -1 if NAME/LIBRARY not given */
+ bfd_vma base_address; /* (bfd_vma)(-1) if unspecified */
+
+ /* from the DESCRIPTION command */
+ char *description;
+
+ /* from the STACK/HEAP command, -1 if unspecified */
+ int stack_reserve, stack_commit;
+ int heap_reserve, heap_commit;
+
+ /* from the SECTION/SEGMENT commands */
+ int num_section_defs;
+ def_file_section *section_defs;
+
+ /* from the EXPORTS commands */
+ int num_exports;
+ def_file_export *exports;
+
+ /* used by imports for module names */
+ def_file_module *modules;
+
+ /* from the IMPORTS commands */
+ int num_imports;
+ def_file_import *imports;
+
+ /* from the VERSION command, -1 if not specified */
+ int version_major, version_minor;
+ }
+def_file;
+
+extern def_file *def_file_empty PARAMS ((void));
+
+/* add_to may be NULL. If not, this .def is appended to it */
+extern def_file *def_file_parse PARAMS ((const char *_filename,
+ def_file * _add_to));
+
+extern void def_file_free PARAMS ((def_file * _def));
+
+extern def_file_export *def_file_add_export PARAMS ((def_file * _def,
+ const char *_name,
+ const char *_internal_name,
+ int _ordinal));
+
+extern def_file_import *def_file_add_import PARAMS ((def_file * _def,
+ const char *_name,
+ const char *_from,
+ int _ordinal,
+ const char *_imported_name));
+
+extern void def_file_add_directive PARAMS ((def_file * _def,
+ const char *param,
+ int len));
+
+#ifdef DEF_FILE_PRINT
+extern void def_file_print PARAMS ((FILE * _file,
+ def_file * _def));
+#endif
diff --git a/ld/deffilep.y b/ld/deffilep.y
new file mode 100644
index 00000000000..aacde6b989e
--- /dev/null
+++ b/ld/deffilep.y
@@ -0,0 +1,1004 @@
+%{ /* deffilep.y - parser for .def files */
+
+/* Copyright (C) 1995, 1997, 1998, 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "libiberty.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "ld.h"
+#include "ldmisc.h"
+#include "deffile.h"
+
+#define TRACE 0
+
+#define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
+ as well as gratuitiously global symbol names, so we can have multiple
+ yacc generated parsers in ld. Note that these are only the variables
+ produced by yacc. If other parser generators (bison, byacc, etc) produce
+ additional global names that conflict at link time, then those parser
+ generators need to be fixed instead of adding those names to this list. */
+
+#define yymaxdepth def_maxdepth
+#define yyparse def_parse
+#define yylex def_lex
+#define yyerror def_error
+#define yylval def_lval
+#define yychar def_char
+#define yydebug def_debug
+#define yypact def_pact
+#define yyr1 def_r1
+#define yyr2 def_r2
+#define yydef def_def
+#define yychk def_chk
+#define yypgo def_pgo
+#define yyact def_act
+#define yyexca def_exca
+#define yyerrflag def_errflag
+#define yynerrs def_nerrs
+#define yyps def_ps
+#define yypv def_pv
+#define yys def_s
+#define yy_yys def_yys
+#define yystate def_state
+#define yytmp def_tmp
+#define yyv def_v
+#define yy_yyv def_yyv
+#define yyval def_val
+#define yylloc def_lloc
+#define yyreds def_reds /* With YYDEBUG defined */
+#define yytoks def_toks /* With YYDEBUG defined */
+#define yylhs def_yylhs
+#define yylen def_yylen
+#define yydefred def_yydefred
+#define yydgoto def_yydgoto
+#define yysindex def_yysindex
+#define yyrindex def_yyrindex
+#define yygindex def_yygindex
+#define yytable def_yytable
+#define yycheck def_yycheck
+
+static int def_lex ();
+
+static void def_description PARAMS ((const char *));
+static void def_exports PARAMS ((const char *, const char *, int, int));
+static void def_heapsize PARAMS ((int, int));
+static void def_import
+ PARAMS ((const char *, const char *, const char *, const char *, int));
+static void def_library PARAMS ((const char *, int));
+static void def_name PARAMS ((const char *, int));
+static void def_section PARAMS ((const char *, int));
+static void def_section_alt PARAMS ((const char *, const char *));
+static void def_stacksize PARAMS ((int, int));
+static void def_version PARAMS ((int, int));
+static void def_directive PARAMS ((char *));
+static int def_parse PARAMS ((void));
+static int def_error PARAMS ((const char *));
+static int def_debug;
+static int def_lex PARAMS ((void));
+
+static int lex_forced_token = 0;
+static const char *lex_parse_string = 0;
+static const char *lex_parse_string_end = 0;
+
+%}
+
+%union {
+ char *id;
+ int number;
+};
+
+%token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA
+%token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE
+%token READ WRITE EXECUTE SHARED NONAME DIRECTIVE
+%token <id> ID
+%token <number> NUMBER
+%type <number> opt_base opt_ordinal
+%type <number> attr attr_list opt_number exp_opt_list exp_opt
+%type <id> opt_name opt_equal_name
+
+%%
+
+start: start command
+ | command
+ ;
+
+command:
+ NAME opt_name opt_base { def_name ($2, $3); }
+ | LIBRARY opt_name opt_base { def_library ($2, $3); }
+ | DESCRIPTION ID { def_description ($2);}
+ | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
+ | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
+ | CODE attr_list { def_section ("CODE", $2);}
+ | DATA attr_list { def_section ("DATA", $2);}
+ | SECTIONS seclist
+ | EXPORTS explist
+ | IMPORTS implist
+ | VERSIONK NUMBER { def_version ($2, 0);}
+ | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
+ | DIRECTIVE ID { def_directive ($2);}
+ ;
+
+
+explist:
+ /* EMPTY */
+ | expline
+ | explist expline
+ ;
+
+expline:
+ ID opt_equal_name opt_ordinal exp_opt_list
+ { def_exports ($1, $2, $3, $4); }
+ ;
+exp_opt_list:
+ exp_opt exp_opt_list { $$ = $1 | $2; }
+ | { $$ = 0; }
+ ;
+exp_opt:
+ NONAME { $$ = 1; }
+ | CONSTANT { $$ = 2; }
+ | DATA { $$ = 4; }
+ | PRIVATE { $$ = 8; }
+ ;
+implist:
+ implist impline
+ | impline
+ ;
+
+impline:
+ ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
+ | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
+ | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
+ | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
+ | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
+ | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
+;
+
+seclist:
+ seclist secline
+ | secline
+ ;
+
+secline:
+ ID attr_list { def_section ($1, $2);}
+ | ID ID { def_section_alt ($1, $2);}
+ ;
+
+attr_list:
+ attr_list opt_comma attr { $$ = $1 | $3; }
+ | attr { $$ = $1; }
+ ;
+
+opt_comma:
+ ','
+ |
+ ;
+opt_number: ',' NUMBER { $$=$2;}
+ | { $$=-1;}
+ ;
+
+attr:
+ READ { $$ = 1;}
+ | WRITE { $$ = 2;}
+ | EXECUTE { $$=4;}
+ | SHARED { $$=8;}
+ ;
+
+opt_name: ID { $$ = $1; }
+ | { $$ = 0; }
+ ;
+
+opt_ordinal:
+ '@' NUMBER { $$ = $2;}
+ | { $$ = -1;}
+ ;
+
+opt_equal_name:
+ '=' ID { $$ = $2; }
+ | { $$ = 0; }
+ ;
+
+opt_base: BASE '=' NUMBER { $$ = $3;}
+ | { $$ = 0;}
+ ;
+
+
+
+%%
+
+/*****************************************************************************
+ API
+ *****************************************************************************/
+
+static FILE *the_file;
+static const char *def_filename;
+static int linenumber;
+static def_file *def;
+static int saw_newline;
+
+struct directive
+ {
+ struct directive *next;
+ char *name;
+ int len;
+ };
+
+static struct directive *directives = 0;
+
+def_file *
+def_file_empty ()
+{
+ def_file *rv = (def_file *) xmalloc (sizeof (def_file));
+ memset (rv, 0, sizeof (def_file));
+ rv->is_dll = -1;
+ rv->base_address = (bfd_vma) (-1);
+ rv->stack_reserve = rv->stack_commit = -1;
+ rv->heap_reserve = rv->heap_commit = -1;
+ rv->version_major = rv->version_minor = -1;
+ return rv;
+}
+
+def_file *
+def_file_parse (filename, add_to)
+ const char *filename;
+ def_file *add_to;
+{
+ struct directive *d;
+
+ the_file = fopen (filename, "r");
+ def_filename = filename;
+ linenumber = 1;
+ if (!the_file)
+ {
+ perror (filename);
+ return 0;
+ }
+ if (add_to)
+ {
+ def = add_to;
+ }
+ else
+ {
+ def = def_file_empty ();
+ }
+
+ saw_newline = 1;
+ if (def_parse ())
+ {
+ def_file_free (def);
+ fclose (the_file);
+ return 0;
+ }
+
+ fclose (the_file);
+
+ for (d = directives; d; d = d->next)
+ {
+#if TRACE
+ printf ("Adding directive %08x `%s'\n", d->name, d->name);
+#endif
+ def_file_add_directive (def, d->name, d->len);
+ }
+
+ return def;
+}
+
+void
+def_file_free (def)
+ def_file *def;
+{
+ int i;
+ if (!def)
+ return;
+ if (def->name)
+ free (def->name);
+ if (def->description)
+ free (def->description);
+
+ if (def->section_defs)
+ {
+ for (i = 0; i < def->num_section_defs; i++)
+ {
+ if (def->section_defs[i].name)
+ free (def->section_defs[i].name);
+ if (def->section_defs[i].class)
+ free (def->section_defs[i].class);
+ }
+ free (def->section_defs);
+ }
+
+ if (def->exports)
+ {
+ for (i = 0; i < def->num_exports; i++)
+ {
+ if (def->exports[i].internal_name
+ && def->exports[i].internal_name != def->exports[i].name)
+ free (def->exports[i].internal_name);
+ if (def->exports[i].name)
+ free (def->exports[i].name);
+ }
+ free (def->exports);
+ }
+
+ if (def->imports)
+ {
+ for (i = 0; i < def->num_imports; i++)
+ {
+ if (def->imports[i].internal_name
+ && def->imports[i].internal_name != def->imports[i].name)
+ free (def->imports[i].internal_name);
+ if (def->imports[i].name)
+ free (def->imports[i].name);
+ }
+ free (def->imports);
+ }
+
+ while (def->modules)
+ {
+ def_file_module *m = def->modules;
+ def->modules = def->modules->next;
+ free (m);
+ }
+
+ free (def);
+}
+
+#ifdef DEF_FILE_PRINT
+void
+def_file_print (file, def)
+ FILE *file;
+ def_file *def;
+{
+ int i;
+ fprintf (file, ">>>> def_file at 0x%08x\n", def);
+ if (def->name)
+ fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
+ if (def->is_dll != -1)
+ fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
+ if (def->base_address != (bfd_vma) (-1))
+ fprintf (file, " base address: 0x%08x\n", def->base_address);
+ if (def->description)
+ fprintf (file, " description: `%s'\n", def->description);
+ if (def->stack_reserve != -1)
+ fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
+ if (def->stack_commit != -1)
+ fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
+ if (def->heap_reserve != -1)
+ fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
+ if (def->heap_commit != -1)
+ fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
+
+ if (def->num_section_defs > 0)
+ {
+ fprintf (file, " section defs:\n");
+ for (i = 0; i < def->num_section_defs; i++)
+ {
+ fprintf (file, " name: `%s', class: `%s', flags:",
+ def->section_defs[i].name, def->section_defs[i].class);
+ if (def->section_defs[i].flag_read)
+ fprintf (file, " R");
+ if (def->section_defs[i].flag_write)
+ fprintf (file, " W");
+ if (def->section_defs[i].flag_execute)
+ fprintf (file, " X");
+ if (def->section_defs[i].flag_shared)
+ fprintf (file, " S");
+ fprintf (file, "\n");
+ }
+ }
+
+ if (def->num_exports > 0)
+ {
+ fprintf (file, " exports:\n");
+ for (i = 0; i < def->num_exports; i++)
+ {
+ fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
+ def->exports[i].name, def->exports[i].internal_name,
+ def->exports[i].ordinal);
+ if (def->exports[i].flag_private)
+ fprintf (file, " P");
+ if (def->exports[i].flag_constant)
+ fprintf (file, " C");
+ if (def->exports[i].flag_noname)
+ fprintf (file, " N");
+ if (def->exports[i].flag_data)
+ fprintf (file, " D");
+ fprintf (file, "\n");
+ }
+ }
+
+ if (def->num_imports > 0)
+ {
+ fprintf (file, " imports:\n");
+ for (i = 0; i < def->num_imports; i++)
+ {
+ fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
+ def->imports[i].internal_name,
+ def->imports[i].module,
+ def->imports[i].name,
+ def->imports[i].ordinal);
+ }
+ }
+ if (def->version_major != -1)
+ fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
+ fprintf (file, "<<<< def_file at 0x%08x\n", def);
+}
+#endif
+
+def_file_export *
+def_file_add_export (def, external_name, internal_name, ordinal)
+ def_file *def;
+ const char *external_name;
+ const char *internal_name;
+ int ordinal;
+{
+ def_file_export *e;
+ int max_exports = ROUND_UP(def->num_exports, 32);
+ if (def->num_exports >= max_exports)
+ {
+ max_exports = ROUND_UP(def->num_exports+1, 32);
+ if (def->exports)
+ def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export));
+ else
+ def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export));
+ }
+ e = def->exports + def->num_exports;
+ memset (e, 0, sizeof (def_file_export));
+ if (internal_name && !external_name)
+ external_name = internal_name;
+ if (external_name && !internal_name)
+ internal_name = external_name;
+ e->name = xstrdup (external_name);
+ e->internal_name = xstrdup (internal_name);
+ e->ordinal = ordinal;
+ def->num_exports++;
+ return e;
+}
+
+static def_file_module *
+def_stash_module (def, name)
+ def_file *def;
+ char *name;
+{
+ def_file_module *s;
+ for (s=def->modules; s; s=s->next)
+ if (strcmp (s->name, name) == 0)
+ return s;
+ s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
+ s->next = def->modules;
+ def->modules = s;
+ s->user_data = 0;
+ strcpy (s->name, name);
+ return s;
+}
+
+def_file_import *
+def_file_add_import (def, name, module, ordinal, internal_name)
+ def_file *def;
+ const char *name;
+ const char *module;
+ int ordinal;
+ const char *internal_name;
+{
+ def_file_import *i;
+ int max_imports = ROUND_UP(def->num_imports, 16);
+ if (def->num_imports >= max_imports)
+ {
+ max_imports = ROUND_UP(def->num_imports+1, 16);
+ if (def->imports)
+ def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import));
+ else
+ def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import));
+ }
+ i = def->imports + def->num_imports;
+ memset (i, 0, sizeof (def_file_import));
+ if (name)
+ i->name = xstrdup (name);
+ if (module)
+ i->module = def_stash_module(def, module);
+ i->ordinal = ordinal;
+ if (internal_name)
+ i->internal_name = xstrdup (internal_name);
+ else
+ i->internal_name = i->name;
+ def->num_imports++;
+ return i;
+}
+
+struct
+{
+ char *param;
+ int token;
+}
+diropts[] =
+{
+ { "-heap", HEAPSIZE },
+ { "-stack", STACKSIZE },
+ { "-attr", SECTIONS },
+ { "-export", EXPORTS },
+ { 0, 0 }
+};
+
+void
+def_file_add_directive (my_def, param, len)
+ def_file *my_def;
+ const char *param;
+ int len;
+{
+ def_file *save_def = def;
+ const char *pend = param + len;
+ const char *tend = param;
+ int i;
+
+ def = my_def;
+
+ while (param < pend)
+ {
+ while (param < pend && isspace (*param))
+ param++;
+ for (tend = param + 1;
+ tend < pend && !(isspace (tend[-1]) && *tend == '-');
+ tend++);
+
+ for (i = 0; diropts[i].param; i++)
+ {
+ int len = strlen (diropts[i].param);
+ if (tend - param >= len
+ && strncmp (param, diropts[i].param, len) == 0
+ && (param[len] == ':' || param[len] == ' '))
+ {
+ lex_parse_string_end = tend;
+ lex_parse_string = param + len + 1;
+ lex_forced_token = diropts[i].token;
+ saw_newline = 0;
+ def_parse ();
+ break;
+ }
+ }
+
+ if (!diropts[i].param)
+ {
+ /* xgettext:c-format */
+ einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
+ tend - param, param);
+ }
+ lex_parse_string = 0;
+ param = tend;
+ }
+
+ def = save_def;
+}
+
+/*****************************************************************************
+ Parser Callbacks
+ *****************************************************************************/
+
+static void
+def_name (name, base)
+ const char *name;
+ int base;
+{
+ if (def->name)
+ free (def->name);
+ def->name = xstrdup (name);
+ def->base_address = base;
+ def->is_dll = 0;
+}
+
+static void
+def_library (name, base)
+ const char *name;
+ int base;
+{
+ if (def->name)
+ free (def->name);
+ def->name = xstrdup (name);
+ def->base_address = base;
+ def->is_dll = 1;
+}
+
+static void
+def_description (text)
+ const char *text;
+{
+ int len = def->description ? strlen (def->description) : 0;
+ len += strlen (text) + 1;
+ if (def->description)
+ {
+ def->description = (char *) xrealloc (def->description, len);
+ strcat (def->description, text);
+ }
+ else
+ {
+ def->description = (char *) xmalloc (len);
+ strcpy (def->description, text);
+ }
+}
+
+static void
+def_stacksize (reserve, commit)
+ int reserve;
+ int commit;
+{
+ def->stack_reserve = reserve;
+ def->stack_commit = commit;
+}
+
+static void
+def_heapsize (reserve, commit)
+ int reserve;
+ int commit;
+{
+ def->heap_reserve = reserve;
+ def->heap_commit = commit;
+}
+
+static void
+def_section (name, attr)
+ const char *name;
+ int attr;
+{
+ def_file_section *s;
+ int max_sections = ROUND_UP(def->num_section_defs, 4);
+ if (def->num_section_defs >= max_sections)
+ {
+ max_sections = ROUND_UP(def->num_section_defs+1, 4);
+ if (def->section_defs)
+ def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
+ else
+ def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
+ }
+ s = def->section_defs + def->num_section_defs;
+ memset (s, 0, sizeof (def_file_section));
+ s->name = xstrdup (name);
+ if (attr & 1)
+ s->flag_read = 1;
+ if (attr & 2)
+ s->flag_write = 1;
+ if (attr & 4)
+ s->flag_execute = 1;
+ if (attr & 8)
+ s->flag_shared = 1;
+
+ def->num_section_defs++;
+}
+
+static void
+def_section_alt (name, attr)
+ const char *name;
+ const char *attr;
+{
+ int aval = 0;
+ for (; *attr; attr++)
+ {
+ switch (*attr)
+ {
+ case 'R':
+ case 'r':
+ aval |= 1;
+ break;
+ case 'W':
+ case 'w':
+ aval |= 2;
+ break;
+ case 'X':
+ case 'x':
+ aval |= 4;
+ break;
+ case 'S':
+ case 's':
+ aval |= 8;
+ break;
+ }
+ }
+ def_section (name, aval);
+}
+
+static void
+def_exports (external_name, internal_name, ordinal, flags)
+ const char *external_name;
+ const char *internal_name;
+ int ordinal;
+ int flags;
+{
+ def_file_export *dfe;
+
+ if (!internal_name && external_name)
+ internal_name = external_name;
+#if TRACE
+ printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
+#endif
+
+ dfe = def_file_add_export (def, external_name, internal_name, ordinal);
+ if (flags & 1)
+ dfe->flag_noname = 1;
+ if (flags & 2)
+ dfe->flag_constant = 1;
+ if (flags & 4)
+ dfe->flag_data = 1;
+ if (flags & 8)
+ dfe->flag_private = 1;
+}
+
+static void
+def_import (internal_name, module, dllext, name, ordinal)
+ const char *internal_name;
+ const char *module;
+ const char *dllext;
+ const char *name;
+ int ordinal;
+{
+ char *buf = 0;
+
+ if (dllext != NULL)
+ {
+ buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
+ sprintf (buf, "%s.%s", module, dllext);
+ module = buf;
+ }
+
+ def_file_add_import (def, name, module, ordinal, internal_name);
+ if (buf)
+ free (buf);
+}
+
+static void
+def_version (major, minor)
+ int major;
+ int minor;
+{
+ def->version_major = major;
+ def->version_minor = minor;
+}
+
+static void
+def_directive (str)
+ char *str;
+{
+ struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
+ d->next = directives;
+ directives = d;
+ d->name = xstrdup (str);
+ d->len = strlen (str);
+}
+
+static int
+def_error (err)
+ const char *err;
+{
+ einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
+
+ return 0;
+}
+
+
+/*****************************************************************************
+ Lexical Scanner
+ *****************************************************************************/
+
+#undef TRACE
+#define TRACE 0
+
+/* Never freed, but always reused as needed, so no real leak */
+static char *buffer = 0;
+static int buflen = 0;
+static int bufptr = 0;
+
+static void
+put_buf (c)
+ char c;
+{
+ if (bufptr == buflen)
+ {
+ buflen += 50; /* overly reasonable, eh? */
+ if (buffer)
+ buffer = (char *) xrealloc (buffer, buflen + 1);
+ else
+ buffer = (char *) xmalloc (buflen + 1);
+ }
+ buffer[bufptr++] = c;
+ buffer[bufptr] = 0; /* not optimal, but very convenient */
+}
+
+static struct
+{
+ char *name;
+ int token;
+}
+tokens[] =
+{
+ { "BASE", BASE },
+ { "CODE", CODE },
+ { "CONSTANT", CONSTANT },
+ { "DATA", DATA },
+ { "DESCRIPTION", DESCRIPTION },
+ { "DIRECTIVE", DIRECTIVE },
+ { "EXECUTE", EXECUTE },
+ { "EXPORTS", EXPORTS },
+ { "HEAPSIZE", HEAPSIZE },
+ { "IMPORTS", IMPORTS },
+ { "LIBRARY", LIBRARY },
+ { "NAME", NAME },
+ { "NONAME", NONAME },
+ { "PRIVATE", PRIVATE },
+ { "READ", READ },
+ { "SECTIONS", SECTIONS },
+ { "SEGMENTS", SECTIONS },
+ { "SHARED", SHARED },
+ { "STACKSIZE", STACKSIZE },
+ { "VERSION", VERSIONK },
+ { "WRITE", WRITE },
+ { 0, 0 }
+};
+
+static int
+def_getc ()
+{
+ int rv;
+ if (lex_parse_string)
+ {
+ if (lex_parse_string >= lex_parse_string_end)
+ rv = EOF;
+ else
+ rv = *lex_parse_string++;
+ }
+ else
+ {
+ rv = fgetc (the_file);
+ }
+ if (rv == '\n')
+ saw_newline = 1;
+ return rv;
+}
+
+static int
+def_ungetc (c)
+ int c;
+{
+ if (lex_parse_string)
+ {
+ lex_parse_string--;
+ return c;
+ }
+ else
+ return ungetc (c, the_file);
+}
+
+static int
+def_lex ()
+{
+ int c, i, q;
+
+ if (lex_forced_token)
+ {
+ i = lex_forced_token;
+ lex_forced_token = 0;
+#if TRACE
+ printf ("lex: forcing token %d\n", i);
+#endif
+ return i;
+ }
+
+ c = def_getc ();
+
+ /* trim leading whitespace */
+ while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
+ c = def_getc ();
+
+ if (c == EOF)
+ {
+#if TRACE
+ printf ("lex: EOF\n");
+#endif
+ return 0;
+ }
+
+ if (saw_newline && c == ';')
+ {
+ do
+ {
+ c = def_getc ();
+ }
+ while (c != EOF && c != '\n');
+ if (c == '\n')
+ return def_lex ();
+ return 0;
+ }
+ /* must be something else */
+ saw_newline = 0;
+
+ if (isdigit (c))
+ {
+ bufptr = 0;
+ while (c != EOF && (isxdigit (c) || (c == 'x')))
+ {
+ put_buf (c);
+ c = def_getc ();
+ }
+ if (c != EOF)
+ def_ungetc (c);
+ yylval.number = strtoul (buffer, 0, 0);
+#if TRACE
+ printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
+#endif
+ return NUMBER;
+ }
+
+ if (isalpha (c) || strchr ("$:-_?", c))
+ {
+ bufptr = 0;
+ while (c != EOF && (isalnum (c) || strchr ("$:-_?/@", c)))
+ {
+ put_buf (c);
+ c = def_getc ();
+ }
+ if (c != EOF)
+ def_ungetc (c);
+ for (i = 0; tokens[i].name; i++)
+ if (strcmp (tokens[i].name, buffer) == 0)
+ {
+#if TRACE
+ printf ("lex: `%s' is a string token\n", buffer);
+#endif
+ return tokens[i].token;
+ }
+#if TRACE
+ printf ("lex: `%s' returns ID\n", buffer);
+#endif
+ yylval.id = xstrdup (buffer);
+ return ID;
+ }
+
+ if (c == '\'' || c == '"')
+ {
+ q = c;
+ c = def_getc ();
+ bufptr = 0;
+ while (c != EOF && c != q)
+ {
+ put_buf (c);
+ c = def_getc ();
+ }
+ yylval.id = xstrdup (buffer);
+#if TRACE
+ printf ("lex: `%s' returns ID\n", buffer);
+#endif
+ return ID;
+ }
+
+ if (c == '=' || c == '.' || c == '@' || c == ',')
+ {
+#if TRACE
+ printf ("lex: `%c' returns itself\n", c);
+#endif
+ return c;
+ }
+
+ if (c == '\n')
+ {
+ linenumber++;
+ saw_newline = 1;
+ }
+
+ /*printf ("lex: 0x%02x ignored\n", c); */
+ return def_lex ();
+}
diff --git a/ld/dep-in.sed b/ld/dep-in.sed
new file mode 100644
index 00000000000..8c80eb06a20
--- /dev/null
+++ b/ld/dep-in.sed
@@ -0,0 +1,16 @@
+:loop
+/\\$/N
+/\\$/b loop
+
+s!@INCDIR@!$(INCDIR)!g
+s!@SRCDIR@/!!g
+s!\.\./bfd/hosts/[^ ]*\.h ! !g
+
+s/\\\n */ /g
+
+s/ *$//
+s/ */ /g
+/:$/d
+
+s/\(.\{50\}[^ ]*\) /\1 \\\
+ /g
diff --git a/ld/emulparams/README b/ld/emulparams/README
new file mode 100644
index 00000000000..b3d6d26c4e0
--- /dev/null
+++ b/ld/emulparams/README
@@ -0,0 +1,2 @@
+The files in this directory are read by genscripts.sh as shell commands.
+They set parameters for the emulations.
diff --git a/ld/emulparams/a29k.sh b/ld/emulparams/a29k.sh
new file mode 100644
index 00000000000..89c8e85c1c8
--- /dev/null
+++ b/ld/emulparams/a29k.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=a29k
+OUTPUT_FORMAT="coff-a29k-big"
+TEXT_START_ADDR=0x1000000
+TARGET_PAGE_SIZE=0x1000000
+ARCH=a29k
diff --git a/ld/emulparams/aixppc.sh b/ld/emulparams/aixppc.sh
new file mode 100644
index 00000000000..f92e686dd6d
--- /dev/null
+++ b/ld/emulparams/aixppc.sh
@@ -0,0 +1,4 @@
+TEMPLATE_NAME=aix
+SCRIPT_NAME=aix
+OUTPUT_FORMAT="aixcoff-rs6000"
+ARCH=powerpc
diff --git a/ld/emulparams/aixrs6.sh b/ld/emulparams/aixrs6.sh
new file mode 100644
index 00000000000..733c3f7ab0f
--- /dev/null
+++ b/ld/emulparams/aixrs6.sh
@@ -0,0 +1,4 @@
+TEMPLATE_NAME=aix
+SCRIPT_NAME=aix
+OUTPUT_FORMAT="aixcoff-rs6000"
+ARCH=rs6000
diff --git a/ld/emulparams/alpha.sh b/ld/emulparams/alpha.sh
new file mode 100644
index 00000000000..141923f7170
--- /dev/null
+++ b/ld/emulparams/alpha.sh
@@ -0,0 +1,3 @@
+SCRIPT_NAME=alpha
+OUTPUT_FORMAT="ecoff-littlealpha"
+ARCH=alpha
diff --git a/ld/emulparams/arcelf.sh b/ld/emulparams/arcelf.sh
new file mode 100644
index 00000000000..b1c9c1760ce
--- /dev/null
+++ b/ld/emulparams/arcelf.sh
@@ -0,0 +1,11 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlearc"
+LITTLE_OUTPUT_FORMAT="elf32-littlearc"
+BIG_OUTPUT_FORMAT="elf32-bigarc"
+TEXT_START_ADDR=0x0
+MAXPAGESIZE=0x1000
+NONPAGED_TEXT_START_ADDR=0x0
+ARCH=arc
+MACHINE=
+ENTRY=start
+#TEMPLATE_NAME=elf32
diff --git a/ld/emulparams/arm_epoc_pe.sh b/ld/emulparams/arm_epoc_pe.sh
new file mode 100644
index 00000000000..816fa2a6094
--- /dev/null
+++ b/ld/emulparams/arm_epoc_pe.sh
@@ -0,0 +1,6 @@
+ARCH=arm
+SCRIPT_NAME=pe
+OUTPUT_FORMAT="epoc-pei-arm-little"
+LITTLE_OUTPUT_FORMAT="epoc-pei-arm-little"
+BIG_OUTPUT_FORMAT="epoc-pei-arm-big"
+TEMPLATE_NAME=pe
diff --git a/ld/emulparams/armaoutb.sh b/ld/emulparams/armaoutb.sh
new file mode 100644
index 00000000000..59ab6f14f60
--- /dev/null
+++ b/ld/emulparams/armaoutb.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=armaout
+OUTPUT_FORMAT="a.out-arm-big"
+HEADER_START_ADDR=0x8000
+TEXT_START_ADDR=0x8000
+NONPAGED_TEXT_START_ADDRESS=0x8000
+TARGET_PAGE_SIZE=32768
+ARCH=arm
diff --git a/ld/emulparams/armaoutl.sh b/ld/emulparams/armaoutl.sh
new file mode 100644
index 00000000000..9501f33ec2a
--- /dev/null
+++ b/ld/emulparams/armaoutl.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=armaout
+OUTPUT_FORMAT="a.out-arm-little"
+HEADER_START_ADDR=0x8000
+TEXT_START_ADDR=0x8000
+NONPAGED_TEXT_START_ADDRESS=0x8000
+TARGET_PAGE_SIZE=32768
+ARCH=arm
diff --git a/ld/emulparams/armcoff.sh b/ld/emulparams/armcoff.sh
new file mode 100644
index 00000000000..91df7d3c41d
--- /dev/null
+++ b/ld/emulparams/armcoff.sh
@@ -0,0 +1,6 @@
+ARCH=arm
+SCRIPT_NAME=armcoff
+OUTPUT_FORMAT="coff-arm-little"
+LITTLE_OUTPUT_FORMAT="coff-arm-little"
+BIG_OUTPUT_FORMAT="coff-arm-big"
+TEMPLATE_NAME=armcoff
diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh
new file mode 100644
index 00000000000..2b8b02bec81
--- /dev/null
+++ b/ld/emulparams/armelf.sh
@@ -0,0 +1,21 @@
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlearm"
+BIG_OUTPUT_FORMAT="elf32-bigarm"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm"
+TEXT_START_ADDR=0x8000
+TEMPLATE_NAME=armelf
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
+OTHER_BSS_SYMBOLS='__bss_start__ = .;'
+OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
+
+
+ARCH=arm
+MACHINE=
+MAXPAGESIZE=256
+ENTRY=_start
+EMBEDDED=yes
+
+# Hmmm, there's got to be a better way. This sets the stack to the
+# top of the simulator memory (2^19 bytes).
+OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }'
diff --git a/ld/emulparams/armelf_linux.sh b/ld/emulparams/armelf_linux.sh
new file mode 100644
index 00000000000..2d7d57bed25
--- /dev/null
+++ b/ld/emulparams/armelf_linux.sh
@@ -0,0 +1,17 @@
+ARCH=arm
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlearm"
+BIG_OUTPUT_FORMAT="elf32-bigarm"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm"
+MAXPAGESIZE=0x8000
+TEMPLATE_NAME=armelf
+
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
+OTHER_BSS_SYMBOLS='__bss_start__ = .;'
+OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
+
+# This needs to be high enough so that we can load ld.so below it,
+# yet low enough to stay away from the mmap area 0x40000000.
+# Also, it is small enough so that relocs which are pointing
+# at absolute 0 will still be fixed up.
+TEXT_START_ADDR=0x02000000
diff --git a/ld/emulparams/armelf_linux26.sh b/ld/emulparams/armelf_linux26.sh
new file mode 100644
index 00000000000..7153ddcb508
--- /dev/null
+++ b/ld/emulparams/armelf_linux26.sh
@@ -0,0 +1,16 @@
+ARCH=arm
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlearm"
+BIG_OUTPUT_FORMAT="elf32-bigarm"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm"
+MAXPAGESIZE=0x8000
+TEMPLATE_NAME=armelf
+GENERATE_SHLIB_SCRIPT=yes
+
+# This needs to be high enough so that we can load ld.so below it,
+# yet low enough to stay away from the mmap area at 0x01100000.
+# Also, it is small enough so that relocs which are pointing
+# at absolute 0 will still be fixed up.
+# These values give us about 0.5MB for ld.so, 16.5MB for user
+# programs, and 15MB for mmap which seems a reasonable compromise.
+TEXT_START_ADDR=0x00080000
diff --git a/ld/emulparams/armelf_oabi.sh b/ld/emulparams/armelf_oabi.sh
new file mode 100644
index 00000000000..257753ec88c
--- /dev/null
+++ b/ld/emulparams/armelf_oabi.sh
@@ -0,0 +1,21 @@
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlearm-oabi"
+BIG_OUTPUT_FORMAT="elf32-bigarm-oabi"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm-oabi"
+TEXT_START_ADDR=0x8000
+TEMPLATE_NAME=armelf
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
+OTHER_BSS_SYMBOLS='__bss_start__ = .;'
+OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
+
+
+ARCH=arm
+MACHINE=
+MAXPAGESIZE=256
+ENTRY=_start
+EMBEDDED=yes
+
+# Hmmm, there's got to be a better way. This sets the stack to the
+# top of the simulator memory (2^19 bytes).
+OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }'
diff --git a/ld/emulparams/armpe.sh b/ld/emulparams/armpe.sh
new file mode 100644
index 00000000000..22468050e54
--- /dev/null
+++ b/ld/emulparams/armpe.sh
@@ -0,0 +1,6 @@
+ARCH=arm
+SCRIPT_NAME=pe
+OUTPUT_FORMAT="pei-arm-little"
+LITTLE_OUTPUT_FORMAT="pei-arm-little"
+BIG_OUTPUT_FORMAT="pei-arm-big"
+TEMPLATE_NAME=pe
diff --git a/ld/emulparams/coff_sparc.sh b/ld/emulparams/coff_sparc.sh
new file mode 100644
index 00000000000..0cf852a7b21
--- /dev/null
+++ b/ld/emulparams/coff_sparc.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=sparccoff
+OUTPUT_FORMAT="coff-sparc"
+# following are dubious (borrowed from sparc lynx)
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0
+NONPAGED_TEXT_START_ADDR=0x1000
+ARCH=sparc
diff --git a/ld/emulparams/d10velf.sh b/ld/emulparams/d10velf.sh
new file mode 100644
index 00000000000..bcce51fdb43
--- /dev/null
+++ b/ld/emulparams/d10velf.sh
@@ -0,0 +1,9 @@
+MACHINE=
+SCRIPT_NAME=elfd10v
+OUTPUT_FORMAT="elf32-d10v"
+TEXT_START_ADDR=0x01000000
+READONLY_START_ADDR=0x00000004
+ARCH=d10v
+MAXPAGESIZE=32
+EMBEDDED=t
+TEMPLATE_NAME=elf32
diff --git a/ld/emulparams/d30v_e.sh b/ld/emulparams/d30v_e.sh
new file mode 100644
index 00000000000..a8ab5a25dbd
--- /dev/null
+++ b/ld/emulparams/d30v_e.sh
@@ -0,0 +1,20 @@
+MACHINE=
+SCRIPT_NAME=elfd30v
+OUTPUT_FORMAT="elf32-d30v"
+TEXT_START_ADDR=0x00000000
+DATA_START_ADDR=0x20000000
+EMEM_START_ADDR=0x80000000
+STACK_START_ADDR=0x20008000
+EIT_START_ADDR=0xfffff020
+TEXT_SIZE=64K
+DATA_SIZE=32K
+EMEM_SIZE=8M
+EIT_SIZE=320
+TEXT_MEMORY=emem
+DATA_MEMORY=emem
+BSS_MEMORY=emem
+TEXT_DEF_SECTION=""
+DATA_DEF_SECTION=""
+EMEM_DEF_SECTION="(rwx)"
+ARCH=d30v
+EMBEDDED=t
diff --git a/ld/emulparams/d30v_o.sh b/ld/emulparams/d30v_o.sh
new file mode 100644
index 00000000000..6cbcb42abdb
--- /dev/null
+++ b/ld/emulparams/d30v_o.sh
@@ -0,0 +1,20 @@
+MACHINE=
+SCRIPT_NAME=elfd30v
+OUTPUT_FORMAT="elf32-d30v"
+TEXT_START_ADDR=0x00000000
+DATA_START_ADDR=0x20000000
+EMEM_START_ADDR=0x80000000
+STACK_START_ADDR=0x20008000
+EIT_START_ADDR=0xfffff020
+TEXT_SIZE=64K
+DATA_SIZE=32K
+EMEM_SIZE=8M
+EIT_SIZE=320
+TEXT_MEMORY=text
+DATA_MEMORY=data
+BSS_MEMORY=data
+TEXT_DEF_SECTION="(x)"
+DATA_DEF_SECTION="(rw)"
+EMEM_DEF_SECTION=""
+ARCH=d30v
+EMBEDDED=t
diff --git a/ld/emulparams/d30velf.sh b/ld/emulparams/d30velf.sh
new file mode 100644
index 00000000000..949de78655a
--- /dev/null
+++ b/ld/emulparams/d30velf.sh
@@ -0,0 +1,20 @@
+MACHINE=
+SCRIPT_NAME=elfd30v
+OUTPUT_FORMAT="elf32-d30v"
+TEXT_START_ADDR=0x00000000
+DATA_START_ADDR=0x20000000
+EMEM_START_ADDR=0x80000000
+STACK_START_ADDR=0x20008000
+EIT_START_ADDR=0xfffff020
+TEXT_SIZE=2000K
+DATA_SIZE=2000K
+EMEM_SIZE=8M
+EIT_SIZE=320
+TEXT_MEMORY=text
+DATA_MEMORY=data
+BSS_MEMORY=data
+TEXT_DEF_SECTION="(x)"
+DATA_DEF_SECTION="(rw)"
+EMEM_DEF_SECTION=""
+ARCH=d30v
+EMBEDDED=t
diff --git a/ld/emulparams/delta68.sh b/ld/emulparams/delta68.sh
new file mode 100644
index 00000000000..e3c59099199
--- /dev/null
+++ b/ld/emulparams/delta68.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=delta68
+OUTPUT_FORMAT="coff-m68k-sysv"
+TEXT_START_ADDR=0x2000
+PAGE_SIZE=0x1000000
+ARCH=m68k
diff --git a/ld/emulparams/ebmon29k.sh b/ld/emulparams/ebmon29k.sh
new file mode 100644
index 00000000000..fbc2bd1e464
--- /dev/null
+++ b/ld/emulparams/ebmon29k.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=ebmon29k
+OUTPUT_FORMAT="coff-a29k-big"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=0x1000
+ARCH=a29k
diff --git a/ld/emulparams/elf32_sparc.sh b/ld/emulparams/elf32_sparc.sh
new file mode 100644
index 00000000000..74e2326d53e
--- /dev/null
+++ b/ld/emulparams/elf32_sparc.sh
@@ -0,0 +1,11 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-sparc"
+TEXT_START_ADDR=0x10000
+MAXPAGESIZE=0x10000
+NONPAGED_TEXT_START_ADDR=0x10000
+ALIGNMENT=8
+ARCH=sparc
+MACHINE=
+TEMPLATE_NAME=elf32
+DATA_PLT=
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/elf32b4300.sh b/ld/emulparams/elf32b4300.sh
new file mode 100644
index 00000000000..24f8d98eab0
--- /dev/null
+++ b/ld/emulparams/elf32b4300.sh
@@ -0,0 +1,29 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-bigmips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0xa0020000
+MAXPAGESIZE=0x40000
+INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+EXECUTABLE_SYMBOLS='_DYNAMIC_LINK = 0;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+DYNAMIC_LINK=false
+EMBEDDED=yes
diff --git a/ld/emulparams/elf32bmip.sh b/ld/emulparams/elf32bmip.sh
new file mode 100644
index 00000000000..473c41169e0
--- /dev/null
+++ b/ld/emulparams/elf32bmip.sh
@@ -0,0 +1,30 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-bigmips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0x0400000
+DATA_ADDR=0x10000000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+SHLIB_TEXT_START_ADDR=0x5ffe0000
+TEXT_DYNAMIC=
+INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/elf32bsmip.sh b/ld/emulparams/elf32bsmip.sh
new file mode 100644
index 00000000000..09f13076437
--- /dev/null
+++ b/ld/emulparams/elf32bsmip.sh
@@ -0,0 +1,31 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-bigmips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0x0400000
+DATA_ADDR=0x10000000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+SHLIB_TEXT_START_ADDR=0x5ffe0000
+TEXT_DYNAMIC=
+INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+ENTRY=__start
diff --git a/ld/emulparams/elf32ebmip.sh b/ld/emulparams/elf32ebmip.sh
new file mode 100644
index 00000000000..00ea8fd9c96
--- /dev/null
+++ b/ld/emulparams/elf32ebmip.sh
@@ -0,0 +1,28 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-bigmips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0x0400000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+SHLIB_TEXT_START_ADDR=0x5ffe0000
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+EMBEDDED=yes
diff --git a/ld/emulparams/elf32elmip.sh b/ld/emulparams/elf32elmip.sh
new file mode 100644
index 00000000000..cf008c8f117
--- /dev/null
+++ b/ld/emulparams/elf32elmip.sh
@@ -0,0 +1,28 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlemips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0x0400000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+SHLIB_TEXT_START_ADDR=0x5ffe0000
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+EMBEDDED=yes
diff --git a/ld/emulparams/elf32fr30.sh b/ld/emulparams/elf32fr30.sh
new file mode 100755
index 00000000000..1be1f534b11
--- /dev/null
+++ b/ld/emulparams/elf32fr30.sh
@@ -0,0 +1,10 @@
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-fr30"
+TEXT_START_ADDR=0x10000
+ARCH=fr30
+MAXPAGESIZE=256
+ENTRY=_start
+EMBEDDED=yes
+NOP=0x9fa0
+OTHER_RELOCATING_SECTIONS='PROVIDE (__stack = 0x200000);' \ No newline at end of file
diff --git a/ld/emulparams/elf32l4300.sh b/ld/emulparams/elf32l4300.sh
new file mode 100644
index 00000000000..690de88b3aa
--- /dev/null
+++ b/ld/emulparams/elf32l4300.sh
@@ -0,0 +1,29 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlemips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0xa0020000
+MAXPAGESIZE=0x40000
+INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+EXECUTABLE_SYMBOLS='_DYNAMIC_LINK = 0;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+DYNAMIC_LINK=false
+EMBEDDED=yes
diff --git a/ld/emulparams/elf32lmip.sh b/ld/emulparams/elf32lmip.sh
new file mode 100644
index 00000000000..23312f44aca
--- /dev/null
+++ b/ld/emulparams/elf32lmip.sh
@@ -0,0 +1,30 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlemips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0x0400000
+DATA_ADDR=0x10000000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+SHLIB_TEXT_START_ADDR=0x5ffe0000
+TEXT_DYNAMIC=
+INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/elf32lppc.sh b/ld/emulparams/elf32lppc.sh
new file mode 100644
index 00000000000..edffc610d49
--- /dev/null
+++ b/ld/emulparams/elf32lppc.sh
@@ -0,0 +1,8 @@
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+SCRIPT_NAME=elfppc
+OUTPUT_FORMAT="elf32-powerpcle"
+TEXT_START_ADDR=0x40000
+MAXPAGESIZE=0x40000
+ARCH=powerpc
+MACHINE=
diff --git a/ld/emulparams/elf32lsmip.sh b/ld/emulparams/elf32lsmip.sh
new file mode 100644
index 00000000000..4bdc8a10e69
--- /dev/null
+++ b/ld/emulparams/elf32lsmip.sh
@@ -0,0 +1,31 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlemips"
+BIG_OUTPUT_FORMAT="elf32-bigmips"
+LITTLE_OUTPUT_FORMAT="elf32-littlemips"
+TEXT_START_ADDR=0x0400000
+DATA_ADDR=0x10000000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+SHLIB_TEXT_START_ADDR=0x5ffe0000
+TEXT_DYNAMIC=
+INITIAL_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
+OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
+OTHER_GOT_SYMBOLS='
+ _gp = ALIGN(16) + 0x7ff0;
+'
+OTHER_GOT_SECTIONS='
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+'
+TEXT_START_SYMBOLS='_ftext = . ;'
+DATA_START_SYMBOLS='_fdata = . ;'
+OTHER_BSS_SYMBOLS='_fbss = .;'
+OTHER_SECTIONS='
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+'
+ARCH=mips
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+ENTRY=__start
diff --git a/ld/emulparams/elf32mcore.sh b/ld/emulparams/elf32mcore.sh
new file mode 100644
index 00000000000..47d960f2413
--- /dev/null
+++ b/ld/emulparams/elf32mcore.sh
@@ -0,0 +1,20 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-mcore-big"
+BIG_OUTPUT_FORMAT="elf32-mcore-big"
+LITTLE_OUTPUT_FORMAT="elf32-mcore-little"
+PAGE_SIZE=0x1000
+TARGET_PAGE_SIZE=0x400
+MAXPAGESIZE=0x1000
+TEXT_START_ADDR=0
+NONPAGED_TEXT_START_ADDR=0
+ARCH=mcore
+# 1211 == mov r1,r1
+NOP=0x1211
+EMBEDDED=yes
+
+OTHER_BSS_SYMBOLS="__bss_start__ = . ;"
+OTHER_BSS_END_SYMBOLS="__bss_end__ = . ;"
+
+# Hmmm, there's got to be a better way. This sets the stack to the
+# top of the simulator memory (2^19 bytes).
+OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }'
diff --git a/ld/emulparams/elf32ppc.sh b/ld/emulparams/elf32ppc.sh
new file mode 100644
index 00000000000..8af42f1ddfd
--- /dev/null
+++ b/ld/emulparams/elf32ppc.sh
@@ -0,0 +1,8 @@
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+SCRIPT_NAME=elfppc
+OUTPUT_FORMAT="elf32-powerpc"
+TEXT_START_ADDR=0x01800000
+MAXPAGESIZE=0x40000
+ARCH=powerpc
+MACHINE=
diff --git a/ld/emulparams/elf64_sparc.sh b/ld/emulparams/elf64_sparc.sh
new file mode 100644
index 00000000000..d0fbdfda3ce
--- /dev/null
+++ b/ld/emulparams/elf64_sparc.sh
@@ -0,0 +1,12 @@
+SCRIPT_NAME=elf
+ELFSIZE=64
+TEMPLATE_NAME=elf32
+OUTPUT_FORMAT="elf64-sparc"
+TEXT_START_ADDR=0x100000
+MAXPAGESIZE=0x100000
+NONPAGED_TEXT_START_ADDR=0x100000
+ARCH="sparc:v9"
+MACHINE=
+DATA_PLT=
+GENERATE_SHLIB_SCRIPT=yes
+NOP=0x01000000
diff --git a/ld/emulparams/elf64alpha.sh b/ld/emulparams/elf64alpha.sh
new file mode 100644
index 00000000000..afa21f22717
--- /dev/null
+++ b/ld/emulparams/elf64alpha.sh
@@ -0,0 +1,15 @@
+ENTRY=__start
+SCRIPT_NAME=elf
+ELFSIZE=64
+TEMPLATE_NAME=elf32
+OUTPUT_FORMAT="elf64-alpha"
+TEXT_START_ADDR="0x120000000"
+MAXPAGESIZE=0x100000
+NONPAGED_TEXT_START_ADDR="0x120000000"
+ARCH=alpha
+MACHINE=
+GENERATE_SHLIB_SCRIPT=yes
+DATA_PLT=
+NOP=0x47ff041f
+
+OTHER_READONLY_SECTIONS='.reginfo : { *(.reginfo) }'
diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh
new file mode 100644
index 00000000000..dff567bffbc
--- /dev/null
+++ b/ld/emulparams/elf_i386.sh
@@ -0,0 +1,10 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-i386"
+TEXT_START_ADDR=0x08048000
+MAXPAGESIZE=0x1000
+NONPAGED_TEXT_START_ADDR=0x08048000
+ARCH=i386
+MACHINE=
+NOP=0x9090
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/elf_i386_be.sh b/ld/emulparams/elf_i386_be.sh
new file mode 100644
index 00000000000..9977a069a4a
--- /dev/null
+++ b/ld/emulparams/elf_i386_be.sh
@@ -0,0 +1,11 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-i386"
+TEXT_START_ADDR=0x80000000
+#SHLIB_TEXT_START_ADDR=0x80000000
+NONPAGED_TEXT_START_ADDR=0x80000000
+MAXPAGESIZE=0x1000
+ARCH=i386
+MACHINE=
+NOP=0x9090
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/gld960.sh b/ld/emulparams/gld960.sh
new file mode 100644
index 00000000000..ef81a78a10e
--- /dev/null
+++ b/ld/emulparams/gld960.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=i960
+OUTPUT_FORMAT=""
+TEXT_START_ADDR=??
+TARGET_PAGE_SIZE=??
+ARCH=i960
+TEMPLATE_NAME=gld960
+GLD_STYLE=1
diff --git a/ld/emulparams/gld960coff.sh b/ld/emulparams/gld960coff.sh
new file mode 100644
index 00000000000..78202208b4f
--- /dev/null
+++ b/ld/emulparams/gld960coff.sh
@@ -0,0 +1,19 @@
+SCRIPT_NAME=i960
+OUTPUT_FORMAT=""
+TEXT_START_ADDR=??
+TARGET_PAGE_SIZE=??
+ARCH=i960
+TEMPLATE_NAME=gld960c
+GLD_STYLE=1
+COFF_CTORS='
+ ___CTOR_LIST__ = .;
+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ ___CTOR_END__ = .;
+ ___DTOR_LIST__ = .;
+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ ___DTOR_END__ = .;
+'
diff --git a/ld/emulparams/go32.sh b/ld/emulparams/go32.sh
new file mode 100644
index 00000000000..d13357fda7a
--- /dev/null
+++ b/ld/emulparams/go32.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=go32coff
+OUTPUT_FORMAT="coff-go32"
+TEXT_START_ADDR=0x10a8
+TARGET_PAGE_SIZE=0x1000
+SEGMENT_SIZE=0x1000
+NONPAGED_TEXT_START_ADDR=0x0
+ARCH=i386
diff --git a/ld/emulparams/h8300.sh b/ld/emulparams/h8300.sh
new file mode 100644
index 00000000000..49eb3c453db
--- /dev/null
+++ b/ld/emulparams/h8300.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8300
+OUTPUT_FORMAT="coff-h8300"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8300
diff --git a/ld/emulparams/h8300h.sh b/ld/emulparams/h8300h.sh
new file mode 100644
index 00000000000..3ab794e1107
--- /dev/null
+++ b/ld/emulparams/h8300h.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8300h
+OUTPUT_FORMAT="coff-h8300"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8300
diff --git a/ld/emulparams/h8300s.sh b/ld/emulparams/h8300s.sh
new file mode 100644
index 00000000000..e27b4f523f1
--- /dev/null
+++ b/ld/emulparams/h8300s.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8300s
+OUTPUT_FORMAT="coff-h8300"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8300
diff --git a/ld/emulparams/h8500.sh b/ld/emulparams/h8500.sh
new file mode 100644
index 00000000000..6f4ca802862
--- /dev/null
+++ b/ld/emulparams/h8500.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8500
+OUTPUT_FORMAT="coff-h8500"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8500
diff --git a/ld/emulparams/h8500b.sh b/ld/emulparams/h8500b.sh
new file mode 100644
index 00000000000..d2d3fee2171
--- /dev/null
+++ b/ld/emulparams/h8500b.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8500b
+OUTPUT_FORMAT="coff-h8500"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8500
diff --git a/ld/emulparams/h8500c.sh b/ld/emulparams/h8500c.sh
new file mode 100644
index 00000000000..240a06579ea
--- /dev/null
+++ b/ld/emulparams/h8500c.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8500c
+OUTPUT_FORMAT="coff-h8500"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8500
diff --git a/ld/emulparams/h8500m.sh b/ld/emulparams/h8500m.sh
new file mode 100644
index 00000000000..cd9f7b66cf5
--- /dev/null
+++ b/ld/emulparams/h8500m.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8500m
+OUTPUT_FORMAT="coff-h8500"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8500
diff --git a/ld/emulparams/h8500s.sh b/ld/emulparams/h8500s.sh
new file mode 100644
index 00000000000..b9e294aac0d
--- /dev/null
+++ b/ld/emulparams/h8500s.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=h8500s
+OUTPUT_FORMAT="coff-h8500"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=h8500
diff --git a/ld/emulparams/hp300bsd.sh b/ld/emulparams/hp300bsd.sh
new file mode 100644
index 00000000000..8f5c50b3ee5
--- /dev/null
+++ b/ld/emulparams/hp300bsd.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-hp300bsd"
+TEXT_START_ADDR=0
+TARGET_PAGE_SIZE=4096
+ARCH=m68k
diff --git a/ld/emulparams/hp3hpux.sh b/ld/emulparams/hp3hpux.sh
new file mode 100644
index 00000000000..b7badd8b806
--- /dev/null
+++ b/ld/emulparams/hp3hpux.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-hp300hpux"
+TEXT_START_ADDR=0
+TARGET_PAGE_SIZE=4096
+ARCH=m68k
+STACKZERO="___stack_zero = 0x2000; __DYNAMIC = 0;"
+# This is needed for HPUX 9.0; it is unnecessary but harmless for 8.0.
+SHLIB_PATH="___dld_shlib_path = 0;"
diff --git a/ld/emulparams/hppaelf.sh b/ld/emulparams/hppaelf.sh
new file mode 100644
index 00000000000..47b89ea92aa
--- /dev/null
+++ b/ld/emulparams/hppaelf.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=hppaelf
+OUTPUT_FORMAT="elf32-hppa"
+TEXT_START_ADDR=0x1000
+TARGET_PAGE_SIZE=4096
+ARCH=hppa
+START="$START$"
+TEMPLATE_NAME=hppaelf
diff --git a/ld/emulparams/i386aout.sh b/ld/emulparams/i386aout.sh
new file mode 100644
index 00000000000..dc9e5546145
--- /dev/null
+++ b/ld/emulparams/i386aout.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-i386"
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0
+NONPAGED_TEXT_START_ADDR=0x1000
+ARCH=i386
diff --git a/ld/emulparams/i386beos.sh b/ld/emulparams/i386beos.sh
new file mode 100755
index 00000000000..869da5f41ba
--- /dev/null
+++ b/ld/emulparams/i386beos.sh
@@ -0,0 +1,5 @@
+ARCH=i386
+SCRIPT_NAME=i386beos
+OUTPUT_FORMAT="pei-i386"
+RELOCATEABLE_OUTPUT_FORMAT="pe-i386"
+TEMPLATE_NAME=beos
diff --git a/ld/emulparams/i386bsd.sh b/ld/emulparams/i386bsd.sh
new file mode 100644
index 00000000000..e0c0e2fab6c
--- /dev/null
+++ b/ld/emulparams/i386bsd.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-i386-bsd"
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0
+NONPAGED_TEXT_START_ADDR=0x1000
+ARCH=i386
diff --git a/ld/emulparams/i386coff.sh b/ld/emulparams/i386coff.sh
new file mode 100644
index 00000000000..3417b7d3e99
--- /dev/null
+++ b/ld/emulparams/i386coff.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=i386coff
+OUTPUT_FORMAT="coff-i386"
+TEXT_START_ADDR=0x1000000
+TARGET_PAGE_SIZE=0x1000000
+ARCH=i386
diff --git a/ld/emulparams/i386go32.sh b/ld/emulparams/i386go32.sh
new file mode 100644
index 00000000000..0ef16c4d37c
--- /dev/null
+++ b/ld/emulparams/i386go32.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=i386go32
+OUTPUT_FORMAT="coff-go32"
+TEXT_START_ADDR=0x10a8
+TARGET_PAGE_SIZE=0x1000
+SEGMENT_SIZE=0x200
+NONPAGED_TEXT_START_ADDR=0x0
+ARCH=i386
+
diff --git a/ld/emulparams/i386linux.sh b/ld/emulparams/i386linux.sh
new file mode 100644
index 00000000000..a416422d92f
--- /dev/null
+++ b/ld/emulparams/i386linux.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-i386-linux"
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0x1020
+NONPAGED_TEXT_START_ADDR=0
+ARCH=i386
+TEMPLATE_NAME=linux
diff --git a/ld/emulparams/i386lynx.sh b/ld/emulparams/i386lynx.sh
new file mode 100644
index 00000000000..988c1751b08
--- /dev/null
+++ b/ld/emulparams/i386lynx.sh
@@ -0,0 +1,9 @@
+SCRIPT_NAME=i386lynx
+OUTPUT_FORMAT="coff-i386-lynx"
+# This is what LynxOS /lib/init1.o wants.
+ENTRY=_main
+# following are dubious
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0
+NONPAGED_TEXT_START_ADDR=0x1000
+ARCH=i386
diff --git a/ld/emulparams/i386mach.sh b/ld/emulparams/i386mach.sh
new file mode 100644
index 00000000000..b7cb2764f59
--- /dev/null
+++ b/ld/emulparams/i386mach.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-mach3"
+TEXT_START_ADDR=0x10020
+NONPAGED_TEXT_START_ADDR=0x10000
+SEGMENT_SIZE=0x1000
+PAD_TEXT=t
+ARCH=i386
diff --git a/ld/emulparams/i386moss.sh b/ld/emulparams/i386moss.sh
new file mode 100644
index 00000000000..a5e0e05eb22
--- /dev/null
+++ b/ld/emulparams/i386moss.sh
@@ -0,0 +1,10 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-i386"
+TEXT_START_ADDR=0x00002000
+MAXPAGESIZE=0x1000
+NONPAGED_TEXT_START_ADDR=0x00002000
+ARCH=i386
+MACHINE=
+NOP=0x9090
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/i386msdos.sh b/ld/emulparams/i386msdos.sh
new file mode 100644
index 00000000000..9311fa1fe5a
--- /dev/null
+++ b/ld/emulparams/i386msdos.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=i386msdos
+OUTPUT_FORMAT="msdos"
+TEXT_START_ADDR=0x0
+NONPAGED_TEXT_START_ADDR=0x0
+SEGMENT_SIZE=0x10
+PAD_TEXT=t
+ARCH=i386
diff --git a/ld/emulparams/i386nbsd.sh b/ld/emulparams/i386nbsd.sh
new file mode 100644
index 00000000000..a9e6a38303d
--- /dev/null
+++ b/ld/emulparams/i386nbsd.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x1020
+OUTPUT_FORMAT="a.out-i386-netbsd"
+TARGET_PAGE_SIZE=0x1000
+ARCH=i386
+EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'
diff --git a/ld/emulparams/i386nw.sh b/ld/emulparams/i386nw.sh
new file mode 100644
index 00000000000..e70ed678f3e
--- /dev/null
+++ b/ld/emulparams/i386nw.sh
@@ -0,0 +1,9 @@
+SCRIPT_NAME=nw
+OUTPUT_FORMAT="elf32-i386"
+TEXT_START_ADDR=0x08000000
+MAXPAGESIZE=0x1000
+NONPAGED_TEXT_START_ADDR=0x08000000
+ARCH=i386
+NOP=0x9090
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/i386pe.sh b/ld/emulparams/i386pe.sh
new file mode 100644
index 00000000000..188a8addf0f
--- /dev/null
+++ b/ld/emulparams/i386pe.sh
@@ -0,0 +1,5 @@
+ARCH=i386
+SCRIPT_NAME=pe
+OUTPUT_FORMAT="pei-i386"
+RELOCATEABLE_OUTPUT_FORMAT="pe-i386"
+TEMPLATE_NAME=pe
diff --git a/ld/emulparams/lnk960.sh b/ld/emulparams/lnk960.sh
new file mode 100644
index 00000000000..3cf3fc49769
--- /dev/null
+++ b/ld/emulparams/lnk960.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=i960
+OUTPUT_FORMAT=""
+TEXT_START_ADDR=??
+TARGET_PAGE_SIZE=??
+ARCH=i960
+TEMPLATE_NAME=lnk960
diff --git a/ld/emulparams/m32relf.sh b/ld/emulparams/m32relf.sh
new file mode 100644
index 00000000000..cd7705afff6
--- /dev/null
+++ b/ld/emulparams/m32relf.sh
@@ -0,0 +1,13 @@
+MACHINE=
+SCRIPT_NAME=elf
+TEMPLATE_NAME=elf32
+OUTPUT_FORMAT="elf32-m32r"
+TEXT_START_ADDR=0x100
+ARCH=m32r
+MACHINE=
+MAXPAGESIZE=32
+EMBEDDED=yes
+
+# Hmmm, there's got to be a better way. This sets the stack to the
+# top of simulator memory (8MB).
+OTHER_RELOCATING_SECTIONS='PROVIDE (_stack = 0x800000);'
diff --git a/ld/emulparams/m68k4knbsd.sh b/ld/emulparams/m68k4knbsd.sh
new file mode 100644
index 00000000000..1bc24c0e9b9
--- /dev/null
+++ b/ld/emulparams/m68k4knbsd.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x1020
+NONPAGED_TEXT_START_ADDR=0x1000
+OUTPUT_FORMAT="a.out-m68k4k-netbsd"
+TARGET_PAGE_SIZE=0x1000
+ARCH=m68k
+EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'
diff --git a/ld/emulparams/m68kaout.sh b/ld/emulparams/m68kaout.sh
new file mode 100644
index 00000000000..9bfaaf719a3
--- /dev/null
+++ b/ld/emulparams/m68kaout.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-zero-big"
+TEXT_START_ADDR=0x2020
+TARGET_PAGE_SIZE=0x2000
+SEGMENT_SIZE=0x20000
+NONPAGED_TEXT_START_ADDR=0x2000
+ARCH=m68k
diff --git a/ld/emulparams/m68kaux.sh b/ld/emulparams/m68kaux.sh
new file mode 100644
index 00000000000..19e86cc6cd1
--- /dev/null
+++ b/ld/emulparams/m68kaux.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=m68kaux
+OUTPUT_FORMAT="coff-m68k-aux"
+SEGMENT_SIZE=0x40000
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR="$SEGMENT_SIZE + SIZEOF_HEADERS"
+NON_PAGED_TEXT_START_ADDR=SIZEOF_HEADERS
+DATA_ALIGNMENT_="(. & (-$SEGMENT_SIZE | $TARGET_PAGE_SIZE-1)) + $SEGMENT_SIZE"
+ARCH=m68k
diff --git a/ld/emulparams/m68kcoff.sh b/ld/emulparams/m68kcoff.sh
new file mode 100644
index 00000000000..b417c0da45c
--- /dev/null
+++ b/ld/emulparams/m68kcoff.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=m68kcoff
+OUTPUT_FORMAT="coff-m68k"
+TEXT_START_ADDR=0x1000000
+TARGET_PAGE_SIZE=0x1000000
+ARCH=m68k
diff --git a/ld/emulparams/m68kelf.sh b/ld/emulparams/m68kelf.sh
new file mode 100644
index 00000000000..ad352c585b3
--- /dev/null
+++ b/ld/emulparams/m68kelf.sh
@@ -0,0 +1,10 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-m68k"
+TEXT_START_ADDR=0x80000000
+MAXPAGESIZE=0x2000
+NONPAGED_TEXT_START_ADDR=${TEXT_START_ADDR}
+ARCH=m68k
+MACHINE=
+NOP=0x4e75
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
diff --git a/ld/emulparams/m68klinux.sh b/ld/emulparams/m68klinux.sh
new file mode 100644
index 00000000000..56c3dad9bfc
--- /dev/null
+++ b/ld/emulparams/m68klinux.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-m68k-linux"
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0x1020
+NONPAGED_TEXT_START_ADDR=0
+ARCH=m68k
+TEMPLATE_NAME=linux
diff --git a/ld/emulparams/m68klynx.sh b/ld/emulparams/m68klynx.sh
new file mode 100644
index 00000000000..b020febaaaa
--- /dev/null
+++ b/ld/emulparams/m68klynx.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=m68klynx
+OUTPUT_FORMAT="coff-m68k-lynx"
+# This is what LynxOS /lib/init1.o wants.
+ENTRY=__main
+# following are dubious
+TEXT_START_ADDR=0
+TARGET_PAGE_SIZE=0x1000
+ARCH=m68k
diff --git a/ld/emulparams/m68knbsd.sh b/ld/emulparams/m68knbsd.sh
new file mode 100644
index 00000000000..a742807ddd9
--- /dev/null
+++ b/ld/emulparams/m68knbsd.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x2020
+NONPAGED_TEXT_START_ADDR=0x2000
+OUTPUT_FORMAT="a.out-m68k-netbsd"
+TARGET_PAGE_SIZE=0x2000
+ARCH=m68k
+EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'
diff --git a/ld/emulparams/m68kpsos.sh b/ld/emulparams/m68kpsos.sh
new file mode 100644
index 00000000000..34eb8ca549c
--- /dev/null
+++ b/ld/emulparams/m68kpsos.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=psos
+OUTPUT_FORMAT="elf32-m68k"
+TEXT_START_ADDR=0x20000
+MAXPAGESIZE=0x1000
+ARCH=m68k
+TEMPLATE_NAME=elf32
diff --git a/ld/emulparams/m88kbcs.sh b/ld/emulparams/m88kbcs.sh
new file mode 100644
index 00000000000..6c6737c3329
--- /dev/null
+++ b/ld/emulparams/m88kbcs.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=m88kbcs
+OUTPUT_FORMAT="coff-m88kbcs"
+TEXT_START_ADDR=??
+TARGET_PAGE_SIZE=??
+ARCH=m88k
diff --git a/ld/emulparams/mcorepe.sh b/ld/emulparams/mcorepe.sh
new file mode 100644
index 00000000000..b5baee9ea70
--- /dev/null
+++ b/ld/emulparams/mcorepe.sh
@@ -0,0 +1,6 @@
+ARCH=mcore
+SCRIPT_NAME=mcorepe
+OUTPUT_FORMAT="pei-mcore-big"
+LITTLE_OUTPUT_FORMAT="pei-mcore-little"
+BIG_OUTPUT_FORMAT="pei-mcore-big"
+TEMPLATE_NAME=pe
diff --git a/ld/emulparams/mipsbig.sh b/ld/emulparams/mipsbig.sh
new file mode 100644
index 00000000000..9fe29538f45
--- /dev/null
+++ b/ld/emulparams/mipsbig.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=mips
+OUTPUT_FORMAT="ecoff-bigmips"
+BIG_OUTPUT_FORMAT="ecoff-bigmips"
+LITTLE_OUTPUT_FORMAT="ecoff-littlemips"
+TARGET_PAGE_SIZE=0x1000000
+ARCH=mips
diff --git a/ld/emulparams/mipsbsd.sh b/ld/emulparams/mipsbsd.sh
new file mode 100644
index 00000000000..e8fb35beca6
--- /dev/null
+++ b/ld/emulparams/mipsbsd.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=mipsbsd
+OUTPUT_FORMAT="a.out-mips-little"
+BIG_OUTPUT_FORMAT="a.out-mips-big"
+LITTLE_OUTPUT_FORMAT="a.out-mips-little"
+TEXT_START_ADDR=0x1020
+TARGET_PAGE_SIZE=4096
+ARCH=mips
diff --git a/ld/emulparams/mipsidt.sh b/ld/emulparams/mipsidt.sh
new file mode 100644
index 00000000000..63176f5fdea
--- /dev/null
+++ b/ld/emulparams/mipsidt.sh
@@ -0,0 +1,11 @@
+SCRIPT_NAME=mips
+OUTPUT_FORMAT="ecoff-bigmips"
+BIG_OUTPUT_FORMAT="ecoff-bigmips"
+LITTLE_OUTPUT_FORMAT="ecoff-littlemips"
+TARGET_PAGE_SIZE=0x1000000
+ARCH=mips
+ENTRY=start
+TEXT_START_ADDR=0xa0012000
+DATA_ADDR=.
+TEMPLATE_NAME=mipsecoff
+EMBEDDED=yes
diff --git a/ld/emulparams/mipsidtl.sh b/ld/emulparams/mipsidtl.sh
new file mode 100644
index 00000000000..02279ded635
--- /dev/null
+++ b/ld/emulparams/mipsidtl.sh
@@ -0,0 +1,11 @@
+SCRIPT_NAME=mips
+OUTPUT_FORMAT="ecoff-littlemips"
+BIG_OUTPUT_FORMAT="ecoff-bigmips"
+LITTLE_OUTPUT_FORMAT="ecoff-littlemips"
+TARGET_PAGE_SIZE=0x1000000
+ARCH=mips
+ENTRY=start
+TEXT_START_ADDR=0xa0012000
+DATA_ADDR=.
+TEMPLATE_NAME=mipsecoff
+EMBEDDED=yes
diff --git a/ld/emulparams/mipslit.sh b/ld/emulparams/mipslit.sh
new file mode 100644
index 00000000000..acb234464be
--- /dev/null
+++ b/ld/emulparams/mipslit.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=mips
+OUTPUT_FORMAT="ecoff-littlemips"
+BIG_OUTPUT_FORMAT="ecoff-bigmips"
+LITTLE_OUTPUT_FORMAT="ecoff-littlemips"
+TARGET_PAGE_SIZE=0x1000000
+ARCH=mips
diff --git a/ld/emulparams/mipslnews.sh b/ld/emulparams/mipslnews.sh
new file mode 100644
index 00000000000..d0bb91c1dc2
--- /dev/null
+++ b/ld/emulparams/mipslnews.sh
@@ -0,0 +1,9 @@
+SCRIPT_NAME=mips
+OUTPUT_FORMAT="ecoff-littlemips"
+BIG_OUTPUT_FORMAT="ecoff-bigmips"
+LITTLE_OUTPUT_FORMAT="ecoff-littlemips"
+TARGET_PAGE_SIZE=0x1000000
+ARCH=mips
+TEXT_START_ADDR=0x80080000
+DATA_ADDR=.
+EMBEDDED=yes
diff --git a/ld/emulparams/mn10200.sh b/ld/emulparams/mn10200.sh
new file mode 100644
index 00000000000..63243225e37
--- /dev/null
+++ b/ld/emulparams/mn10200.sh
@@ -0,0 +1,20 @@
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-mn10200"
+TEXT_START_ADDR=0x0
+ARCH=mn10200
+MACHINE=
+MAXPAGESIZE=1
+ENTRY=_start
+EMBEDDED=yes
+
+# Hmmm, there's got to be a better way. This sets the stack to the
+# top of the simulator memory (2^19 bytes).
+OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }'
+
+# These are for compatibility with the COFF toolchain.
+# XXX These should definitely disappear.
+CTOR_START='___ctors = .;'
+CTOR_END='___ctors_end = .;'
+DTOR_START='___dtors = .;'
+DTOR_END='___dtors_end = .;'
diff --git a/ld/emulparams/mn10300.sh b/ld/emulparams/mn10300.sh
new file mode 100644
index 00000000000..44a40e5a764
--- /dev/null
+++ b/ld/emulparams/mn10300.sh
@@ -0,0 +1,20 @@
+MACHINE=
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-mn10300"
+TEXT_START_ADDR=0x0
+ARCH=mn10300
+MACHINE=
+MAXPAGESIZE=1
+ENTRY=_start
+EMBEDDED=yes
+
+# Hmmm, there's got to be a better way. This sets the stack to the
+# top of the simulator memory (2^19 bytes).
+OTHER_RELOCATING_SECTIONS='.stack 0x80000 : { _stack = .; *(.stack) }'
+
+# These are for compatibility with the COFF toolchain.
+# XXX These should definitely disappear.
+CTOR_START='___ctors = .;'
+CTOR_END='___ctors_end = .;'
+DTOR_START='___dtors = .;'
+DTOR_END='___dtors_end = .;'
diff --git a/ld/emulparams/news.sh b/ld/emulparams/news.sh
new file mode 100644
index 00000000000..310ddf9212e
--- /dev/null
+++ b/ld/emulparams/news.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-newsos3"
+TEXT_START_ADDR=0
+TARGET_PAGE_SIZE=0x1000
+ARCH=m68k
diff --git a/ld/emulparams/ns32knbsd.sh b/ld/emulparams/ns32knbsd.sh
new file mode 100644
index 00000000000..1c4fdf3449c
--- /dev/null
+++ b/ld/emulparams/ns32knbsd.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x1020
+OUTPUT_FORMAT="a.out-ns32k-netbsd"
+TARGET_PAGE_SIZE=0x1000
+ARCH=ns32k
diff --git a/ld/emulparams/pc532macha.sh b/ld/emulparams/pc532macha.sh
new file mode 100644
index 00000000000..9c1d0791c8d
--- /dev/null
+++ b/ld/emulparams/pc532macha.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-pc532-mach"
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR="0x10020"
+NONPAGED_TEXT_START_ADDR=0x10000
+ARCH=ns32k
diff --git a/ld/emulparams/ppcmacos.sh b/ld/emulparams/ppcmacos.sh
new file mode 100644
index 00000000000..b6b800c2c6c
--- /dev/null
+++ b/ld/emulparams/ppcmacos.sh
@@ -0,0 +1,4 @@
+TEMPLATE_NAME=aix
+SCRIPT_NAME=aix
+OUTPUT_FORMAT="xcoff-powermac"
+ARCH=powerpc
diff --git a/ld/emulparams/ppcnw.sh b/ld/emulparams/ppcnw.sh
new file mode 100644
index 00000000000..c3ead43675b
--- /dev/null
+++ b/ld/emulparams/ppcnw.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=nw
+OUTPUT_FORMAT="elf32-powerpc"
+TEXT_START_ADDR=0x0400000
+DATA_ADDR=0x10000000
+MAXPAGESIZE=0x40000
+NONPAGED_TEXT_START_ADDR=0x0400000
+ARCH=powerpc
diff --git a/ld/emulparams/ppcpe.sh b/ld/emulparams/ppcpe.sh
new file mode 100644
index 00000000000..655282d3fc3
--- /dev/null
+++ b/ld/emulparams/ppcpe.sh
@@ -0,0 +1,4 @@
+ARCH=powerpc
+SCRIPT_NAME=ppcpe
+OUTPUT_FORMAT="pei-powerpcle"
+TEMPLATE_NAME=pe
diff --git a/ld/emulparams/riscix.sh b/ld/emulparams/riscix.sh
new file mode 100644
index 00000000000..e7f6d92f304
--- /dev/null
+++ b/ld/emulparams/riscix.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=riscix
+OUTPUT_FORMAT="a.out-riscix"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=0x8000
+ARCH=arm
diff --git a/ld/emulparams/sa29200.sh b/ld/emulparams/sa29200.sh
new file mode 100644
index 00000000000..8b52f92968d
--- /dev/null
+++ b/ld/emulparams/sa29200.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=sa29200
+OUTPUT_FORMAT="coff-a29k-big"
+TEXT_START_ADDR=0x40004000
+TARGET_PAGE_SIZE=0x1000
+ARCH=a29k
diff --git a/ld/emulparams/sh.sh b/ld/emulparams/sh.sh
new file mode 100644
index 00000000000..38844fb18ee
--- /dev/null
+++ b/ld/emulparams/sh.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=sh
+OUTPUT_FORMAT="coff-sh"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=sh
diff --git a/ld/emulparams/shelf.sh b/ld/emulparams/shelf.sh
new file mode 100644
index 00000000000..95db5877d7f
--- /dev/null
+++ b/ld/emulparams/shelf.sh
@@ -0,0 +1,17 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-sh"
+TEXT_START_ADDR=0x1000
+MAXPAGESIZE=128
+ARCH=sh
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+EMBEDDED=yes
+
+# These are for compatibility with the COFF toolchain.
+ENTRY=start
+CTOR_START='___ctors = .;'
+CTOR_END='___ctors_end = .;'
+DTOR_START='___dtors = .;'
+DTOR_END='___dtors_end = .;'
+OTHER_RELOCATING_SECTIONS='.stack 0x30000 : { _stack = .; *(.stack) }'
diff --git a/ld/emulparams/shl.sh b/ld/emulparams/shl.sh
new file mode 100644
index 00000000000..360aac8905c
--- /dev/null
+++ b/ld/emulparams/shl.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=sh
+OUTPUT_FORMAT="coff-shl"
+TEXT_START_ADDR=0x8000
+TARGET_PAGE_SIZE=128
+ARCH=sh
diff --git a/ld/emulparams/shlelf.sh b/ld/emulparams/shlelf.sh
new file mode 100644
index 00000000000..bb27f86af6c
--- /dev/null
+++ b/ld/emulparams/shlelf.sh
@@ -0,0 +1,17 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-shl"
+TEXT_START_ADDR=0x1000
+MAXPAGESIZE=128
+ARCH=sh
+MACHINE=
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+EMBEDDED=yes
+
+# These are for compatibility with the COFF toolchain.
+ENTRY=start
+CTOR_START='___ctors = .;'
+CTOR_END='___ctors_end = .;'
+DTOR_START='___dtors = .;'
+DTOR_END='___dtors_end = .;'
+OTHER_RELOCATING_SECTIONS='.stack 0x30000 : { _stack = .; *(.stack) }'
diff --git a/ld/emulparams/sparcaout.sh b/ld/emulparams/sparcaout.sh
new file mode 100644
index 00000000000..429b925c18c
--- /dev/null
+++ b/ld/emulparams/sparcaout.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-sunos-big"
+BIG_OUTPUT_FORMAT="a.out-sunos-big"
+LITTLE_OUTPUT_FORMAT="a.out-sparc-little"
+TEXT_START_ADDR=0x2020
+TARGET_PAGE_SIZE=0x2000
+NONPAGED_TEXT_START_ADDR=0x2000
+ARCH=sparc
diff --git a/ld/emulparams/sparclinux.sh b/ld/emulparams/sparclinux.sh
new file mode 100644
index 00000000000..7ccb0bec90c
--- /dev/null
+++ b/ld/emulparams/sparclinux.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-sparc-linux"
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0x1020
+NONPAGED_TEXT_START_ADDR=0
+ARCH=sparc
+TEMPLATE_NAME=linux
diff --git a/ld/emulparams/sparclynx.sh b/ld/emulparams/sparclynx.sh
new file mode 100644
index 00000000000..9aeb30b1334
--- /dev/null
+++ b/ld/emulparams/sparclynx.sh
@@ -0,0 +1,9 @@
+SCRIPT_NAME=sparclynx
+OUTPUT_FORMAT="coff-sparc-lynx"
+# This is what LynxOS /lib/init1.o wants.
+ENTRY=__main
+# following are dubious
+TARGET_PAGE_SIZE=0x1000
+TEXT_START_ADDR=0
+NONPAGED_TEXT_START_ADDR=0x1000
+ARCH=sparc
diff --git a/ld/emulparams/sparcnbsd.sh b/ld/emulparams/sparcnbsd.sh
new file mode 100644
index 00000000000..f27daf3c342
--- /dev/null
+++ b/ld/emulparams/sparcnbsd.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x1020
+OUTPUT_FORMAT="a.out-sparc-netbsd"
+TARGET_PAGE_SIZE=0x1000
+ARCH=sparc
diff --git a/ld/emulparams/st2000.sh b/ld/emulparams/st2000.sh
new file mode 100644
index 00000000000..0498832823e
--- /dev/null
+++ b/ld/emulparams/st2000.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=st2000
+OUTPUT_FORMAT="coff-m68k"
+TEXT_START_ADDR=0x0
+TARGET_PAGE_SIZE=128
+ARCH=m68k
diff --git a/ld/emulparams/sun3.sh b/ld/emulparams/sun3.sh
new file mode 100644
index 00000000000..db0f71f3abd
--- /dev/null
+++ b/ld/emulparams/sun3.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-sunos-big"
+TEXT_START_ADDR=0x2020
+TARGET_PAGE_SIZE=0x2000
+SEGMENT_SIZE=0x20000
+NONPAGED_TEXT_START_ADDR=0x2000
+ARCH=m68k
+TEMPLATE_NAME=sunos
diff --git a/ld/emulparams/sun4.sh b/ld/emulparams/sun4.sh
new file mode 100644
index 00000000000..bd42775331b
--- /dev/null
+++ b/ld/emulparams/sun4.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-sunos-big"
+TEXT_START_ADDR=0x2020
+TARGET_PAGE_SIZE=0x2000
+NONPAGED_TEXT_START_ADDR=0x2000
+ALIGNMENT=8
+ARCH=sparc
+TEMPLATE_NAME=sunos
diff --git a/ld/emulparams/tic30aout.sh b/ld/emulparams/tic30aout.sh
new file mode 100644
index 00000000000..2a4c13f598f
--- /dev/null
+++ b/ld/emulparams/tic30aout.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=tic30aout
+OUTPUT_FORMAT="a.out-tic30"
+OUTPUT_ARCH="tms320c30"
+TEXT_START_ADDR=0x0
+TARGET_PAGE_SIZE=128
+ARCH=tms320c30
+BIG=1
diff --git a/ld/emulparams/tic30coff.sh b/ld/emulparams/tic30coff.sh
new file mode 100644
index 00000000000..df779437337
--- /dev/null
+++ b/ld/emulparams/tic30coff.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=tic30coff
+OUTPUT_FORMAT="coff-tic30"
+OUTPUT_ARCH="tms320c30"
+TEXT_START_ADDR=0x0
+TARGET_PAGE_SIZE=128
+ARCH=tms320c30
+BIG=1
diff --git a/ld/emulparams/tic80coff.sh b/ld/emulparams/tic80coff.sh
new file mode 100644
index 00000000000..70703231fd5
--- /dev/null
+++ b/ld/emulparams/tic80coff.sh
@@ -0,0 +1,56 @@
+# This file is sourced by the genscripts.sh script.
+# These are shell variables that are used later by either genscripts
+# or on of the scripts that it sources.
+
+# The name of the scripttempl script to use. In this case, genscripts
+# uses scripttempl/tic80coff.sc
+#
+SCRIPT_NAME=tic80coff
+
+# The name of the emultempl script to use. If set to "template" then
+# genscripts.sh will use the script emultempl/template.em. If not set,
+# then the default value is "generic".
+#
+# TEMPLATE_NAME=
+
+# If this is set to an nonempty string, genscripts.sh will invoke the
+# scripttempl script an extra time to create a shared library script.
+#
+# GENERATE_SHLIB_SCRIPT=
+
+# The BFD output format to use. The scripttempl script will use it in
+# an OUTPUT_FORMAT expression in the linker script.
+#
+OUTPUT_FORMAT="coff-tic80"
+
+# This is normally set to indicate the architecture to use, such as
+# "sparc". The scripttempl script will normally use it in an OUTPUT_ARCH
+# expression in the linker script.
+#
+ARCH=tic80
+
+# Some scripttempl scripts use this to set the entry address in an ENTRY
+# expression in the linker script.
+#
+# ENTRY=
+
+# The scripttempl script uses this to set the start address of the
+# ".text" section.
+#
+TEXT_START_ADDR=0x2000000
+
+# If this is defined, the genscripts.sh script sets TEXT_START_ADDR to
+# its value before running the scripttempl script for the -n and -N
+# options.
+#
+# NONPAGED_TEXT_START_ADDR=
+
+# The genscripts.sh script uses this to set the default value of
+# DATA_ALIGNMENT when running the scripttempl script.
+#
+# SEGMENT_SIZE=
+
+# If SEGMENT_SIZE is not defined, the genscripts.sh script uses this
+# to define it.
+#
+TARGET_PAGE_SIZE=0x1000
diff --git a/ld/emulparams/v850.sh b/ld/emulparams/v850.sh
new file mode 100644
index 00000000000..78bfbd3882d
--- /dev/null
+++ b/ld/emulparams/v850.sh
@@ -0,0 +1,14 @@
+MACHINE=
+SCRIPT_NAME=v850
+OUTPUT_FORMAT="elf32-v850"
+TEXT_START_ADDR=0x100000
+ZDATA_START_ADDR=0x160
+ROZDATA_START_ADDR="ALIGN (4)"
+SDATA_START_ADDR="ALIGN (4)"
+ROSDATA_START_ADDR="ALIGN (4)"
+TDATA_START_ADDR="ALIGN (4)"
+CALL_TABLE_START_ADDR="ALIGN (4)"
+ARCH=v850
+MAXPAGESIZE=256
+ENTRY=_start
+EMBEDDED=yes
diff --git a/ld/emulparams/vanilla.sh b/ld/emulparams/vanilla.sh
new file mode 100644
index 00000000000..d8a3b72dbf9
--- /dev/null
+++ b/ld/emulparams/vanilla.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=vanilla
+TEXT_START_ADDR=??
+TARGET_PAGE_SIZE=??
+ARCH=unknown
+TEMPLATE_NAME=vanilla
diff --git a/ld/emulparams/vax.sh b/ld/emulparams/vax.sh
new file mode 100644
index 00000000000..97854831041
--- /dev/null
+++ b/ld/emulparams/vax.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out"
+TEXT_START_ADDR=0
+TARGET_PAGE_SIZE=1024
+ARCH=vax
diff --git a/ld/emulparams/vsta.sh b/ld/emulparams/vsta.sh
new file mode 100644
index 00000000000..cc6249bea43
--- /dev/null
+++ b/ld/emulparams/vsta.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=aout
+OUTPUT_FORMAT="a.out-i386"
+TEXT_START_ADDR=0x1020
+TARGET_PAGE_SIZE=0x1000
+SEGMENT_SIZE=0x400000
+NONPAGED_TEXT_START_ADDR=0x0
+ARCH=i386
+
diff --git a/ld/emulparams/w65.sh b/ld/emulparams/w65.sh
new file mode 100644
index 00000000000..6f02b2326f5
--- /dev/null
+++ b/ld/emulparams/w65.sh
@@ -0,0 +1,5 @@
+SCRIPT_NAME=w65
+OUTPUT_FORMAT="coff-w65"
+TEXT_START_ADDR=0x1000
+TARGET_PAGE_SIZE=64
+ARCH=w65
diff --git a/ld/emulparams/z8001.sh b/ld/emulparams/z8001.sh
new file mode 100644
index 00000000000..63645c342c2
--- /dev/null
+++ b/ld/emulparams/z8001.sh
@@ -0,0 +1,7 @@
+SCRIPT_NAME=z8000
+OUTPUT_FORMAT="coff-z8k"
+OUTPUT_ARCH="z8001"
+TEXT_START_ADDR=0x0
+TARGET_PAGE_SIZE=128
+ARCH=z8k
+BIG=1
diff --git a/ld/emulparams/z8002.sh b/ld/emulparams/z8002.sh
new file mode 100644
index 00000000000..299b5f5a45d
--- /dev/null
+++ b/ld/emulparams/z8002.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=z8000
+OUTPUT_FORMAT="coff-z8k"
+OUTPUT_ARCH="z8002"
+TEXT_START_ADDR=0x0
+TARGET_PAGE_SIZE=128
+ARCH=z8002
diff --git a/ld/emultempl/README b/ld/emultempl/README
new file mode 100644
index 00000000000..30ec0abf379
--- /dev/null
+++ b/ld/emultempl/README
@@ -0,0 +1,3 @@
+The files in this directory are sourced by genscripts.sh, after
+setting some variables to substitute in, to produce
+C source files that contain jump tables for each emulation.
diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em
new file mode 100644
index 00000000000..c77857f822d
--- /dev/null
+++ b/ld/emultempl/aix.em
@@ -0,0 +1,1054 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* AIX emulation code for ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+ AIX support by Ian Lance Taylor <ian@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "getopt.h"
+#include "obstack.h"
+#include "bfdlink.h"
+
+#include <ctype.h>
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldctor.h"
+#include "ldgram.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static int gld${EMULATION_NAME}_parse_args PARAMS ((int, char **));
+static void gld${EMULATION_NAME}_after_open PARAMS ((void));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static void gld${EMULATION_NAME}_read_file PARAMS ((const char *, boolean));
+static void gld${EMULATION_NAME}_free PARAMS ((PTR));
+static void gld${EMULATION_NAME}_find_relocs
+ PARAMS ((lang_statement_union_type *));
+static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+/* The file alignment required for each section. */
+static unsigned long file_align;
+
+/* The maximum size the stack is permitted to grow. This is stored in
+ the a.out header. */
+static unsigned long maxstack;
+
+/* The maximum data size. This is stored in the a.out header. */
+static unsigned long maxdata;
+
+/* Whether to perform garbage collection. */
+static int gc = 1;
+
+/* The module type to use. */
+static unsigned short modtype = ('1' << 8) | 'L';
+
+/* Whether the .text section must be read-only (i.e., no relocs
+ permitted). */
+static int textro;
+
+/* Whether to implement Unix like linker semantics. */
+static int unix_ld;
+
+/* Structure used to hold import file list. */
+
+struct filelist
+{
+ struct filelist *next;
+ const char *name;
+};
+
+/* List of import files. */
+static struct filelist *import_files;
+
+/* List of export symbols read from the export files. */
+
+struct export_symbol_list
+{
+ struct export_symbol_list *next;
+ const char *name;
+ boolean syscall;
+};
+
+static struct export_symbol_list *export_symbols;
+
+/* This routine is called before anything else is done. */
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_output_architecture = bfd_arch_${ARCH};
+#endif /* not TARGET_ */
+ config.has_shared = true;
+}
+
+/* Handle AIX specific options. */
+
+static int
+gld${EMULATION_NAME}_parse_args (argc, argv)
+ int argc;
+ char **argv;
+{
+ int prevoptind = optind;
+ int prevopterr = opterr;
+ int indx;
+ int longind;
+ int optc;
+ long val;
+ char *end;
+
+#define OPTION_IGNORE (300)
+#define OPTION_AUTOIMP (OPTION_IGNORE + 1)
+#define OPTION_ERNOTOK (OPTION_AUTOIMP + 1)
+#define OPTION_EROK (OPTION_ERNOTOK + 1)
+#define OPTION_EXPORT (OPTION_EROK + 1)
+#define OPTION_IMPORT (OPTION_EXPORT + 1)
+#define OPTION_LOADMAP (OPTION_IMPORT + 1)
+#define OPTION_MAXDATA (OPTION_LOADMAP + 1)
+#define OPTION_MAXSTACK (OPTION_MAXDATA + 1)
+#define OPTION_MODTYPE (OPTION_MAXSTACK + 1)
+#define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1)
+#define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1)
+#define OPTION_PD (OPTION_NOSTRCMPCT + 1)
+#define OPTION_PT (OPTION_PD + 1)
+#define OPTION_STRCMPCT (OPTION_PT + 1)
+#define OPTION_UNIX (OPTION_STRCMPCT + 1)
+
+ static struct option longopts[] = {
+ {"basis", no_argument, NULL, OPTION_IGNORE},
+ {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
+ {"bcomprld", no_argument, NULL, OPTION_IGNORE},
+ {"bcrld", no_argument, NULL, OPTION_IGNORE},
+ {"bcror31", no_argument, NULL, OPTION_IGNORE},
+ {"bD", required_argument, NULL, OPTION_MAXDATA},
+ {"bE", required_argument, NULL, OPTION_EXPORT},
+ {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
+ {"berok", no_argument, NULL, OPTION_EROK},
+ {"berrmsg", no_argument, NULL, OPTION_IGNORE},
+ {"bexport", required_argument, NULL, OPTION_EXPORT},
+ {"bf", no_argument, NULL, OPTION_ERNOTOK},
+ {"bgc", no_argument, &gc, 1},
+ {"bh", required_argument, NULL, OPTION_IGNORE},
+ {"bhalt", required_argument, NULL, OPTION_IGNORE},
+ {"bI", required_argument, NULL, OPTION_IMPORT},
+ {"bimport", required_argument, NULL, OPTION_IMPORT},
+ {"bl", required_argument, NULL, OPTION_LOADMAP},
+ {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
+ {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
+ {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
+ {"bM", required_argument, NULL, OPTION_MODTYPE},
+ {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
+ {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
+ {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
+ {"bnoentry", no_argument, NULL, OPTION_IGNORE},
+ {"bnogc", no_argument, &gc, 0},
+ {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
+ {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
+ {"bnotextro", no_argument, &textro, 0},
+ {"bnro", no_argument, &textro, 0},
+ {"bpD", required_argument, NULL, OPTION_PD},
+ {"bpT", required_argument, NULL, OPTION_PT},
+ {"bro", no_argument, &textro, 1},
+ {"bS", required_argument, NULL, OPTION_MAXSTACK},
+ {"bso", no_argument, NULL, OPTION_AUTOIMP},
+ {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
+ {"btextro", no_argument, &textro, 1},
+ {"static", no_argument, NULL, OPTION_NOAUTOIMP},
+ {"unix", no_argument, NULL, OPTION_UNIX},
+ {NULL, no_argument, NULL, 0}
+ };
+
+ /* Options supported by the AIX linker which we do not support: -f,
+ -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
+ -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
+ -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
+ -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
+ -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
+ -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
+ -bx, -bX, -bxref. */
+
+ /* If the current option starts with -b, change the first : to an =.
+ The AIX linker uses : to separate the option from the argument;
+ changing it to = lets us treat it as a getopt option. */
+ indx = optind;
+ if (indx == 0)
+ indx = 1;
+ if (indx < argc && strncmp (argv[indx], "-b", 2) == 0)
+ {
+ char *s;
+
+ for (s = argv[indx]; *s != '\0'; s++)
+ {
+ if (*s == ':')
+ {
+ *s = '=';
+ break;
+ }
+ }
+ }
+
+ /* We add s and u so to the short options list so that -s and -u on
+ the command line do not match -static and -unix. */
+
+ opterr = 0;
+ optc = getopt_long_only (argc, argv, "-D:H:KT:zsu", longopts, &longind);
+ opterr = prevopterr;
+
+ switch (optc)
+ {
+ case 's':
+ case 'u':
+ default:
+ optind = prevoptind;
+ return 0;
+
+ case 0:
+ /* Long option which just sets a flag. */
+ break;
+
+ case 'D':
+ val = strtol (optarg, &end, 0);
+ if (*end != '\0')
+ einfo ("%P: warning: ignoring invalid -D number %s\n", optarg);
+ else if (val != -1)
+ lang_section_start (".data", exp_intop (val));
+ break;
+
+ case 'H':
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0'
+ || (val & (val - 1)) != 0)
+ einfo ("%P: warning: ignoring invalid -H number %s\n", optarg);
+ else
+ file_align = val;
+ break;
+
+ case 'K':
+ case 'z':
+ /* FIXME: This should use the page size for the target system. */
+ file_align = 4096;
+ break;
+
+ case 'T':
+ /* On AIX this is the same as GNU ld -Ttext. When we see -T
+ number, we assume the AIX option is intended. Otherwise, we
+ assume the usual GNU ld -T option is intended. We can't just
+ ignore the AIX option, because gcc passes it to the linker. */
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ {
+ optind = prevoptind;
+ return 0;
+ }
+ lang_section_start (".text", exp_intop (val));
+ break;
+
+ case OPTION_IGNORE:
+ break;
+
+ case OPTION_AUTOIMP:
+ link_info.static_link = false;
+ break;
+
+ case OPTION_ERNOTOK:
+ force_make_executable = false;
+ break;
+
+ case OPTION_EROK:
+ force_make_executable = true;
+ break;
+
+ case OPTION_EXPORT:
+ gld${EMULATION_NAME}_read_file (optarg, false);
+ break;
+
+ case OPTION_IMPORT:
+ {
+ struct filelist *n;
+ struct filelist **flpp;
+
+ n = (struct filelist *) xmalloc (sizeof (struct filelist));
+ n->next = NULL;
+ n->name = optarg;
+ flpp = &import_files;
+ while (*flpp != NULL)
+ flpp = &(*flpp)->next;
+ *flpp = n;
+ }
+ break;
+
+ case OPTION_LOADMAP:
+ config.map_filename = optarg;
+ break;
+
+ case OPTION_MAXDATA:
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo ("%P: warning: ignoring invalid -bmaxdata number %s\n",
+ optarg);
+ else
+ maxdata = val;
+ break;
+
+ case OPTION_MAXSTACK:
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo ("%P: warning: ignoring invalid -bmaxstack number %s\n",
+ optarg);
+ else
+ maxstack = val;
+ break;
+
+ case OPTION_MODTYPE:
+ if (*optarg == 'S')
+ {
+ link_info.shared = true;
+ ++optarg;
+ }
+ if (*optarg == '\0' || optarg[1] == '\0')
+ einfo ("%P: warning: ignoring invalid module type %s\n", optarg);
+ else
+ modtype = (*optarg << 8) | optarg[1];
+ break;
+
+ case OPTION_NOAUTOIMP:
+ link_info.static_link = true;
+ break;
+
+ case OPTION_NOSTRCMPCT:
+ link_info.traditional_format = true;
+ break;
+
+ case OPTION_PD:
+ /* This sets the page that the .data section is supposed to
+ start on. The offset within the page should still be the
+ offset within the file, so we need to build an appropriate
+ expression. */
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo ("%P: warning: ignoring invalid -pD number %s\n", optarg);
+ else
+ {
+ etree_type *t;
+
+ t = exp_binop ('+',
+ exp_intop (val),
+ exp_binop ('&',
+ exp_nameop (NAME, "."),
+ exp_intop (0xfff)));
+ t = exp_binop ('&',
+ exp_binop ('+', t, exp_intop (31)),
+ exp_intop (~ (bfd_vma) 31));
+ lang_section_start (".data", t);
+ }
+ break;
+
+ case OPTION_PT:
+ /* This set the page that the .text section is supposed to start
+ on. The offset within the page should still be the offset
+ within the file. */
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo ("%P: warning: ignoring invalid -pT number %s\n", optarg);
+ else
+ {
+ etree_type *t;
+
+ t = exp_binop ('+',
+ exp_intop (val),
+ exp_nameop (SIZEOF_HEADERS, NULL));
+ t = exp_binop ('&',
+ exp_binop ('+', t, exp_intop (31)),
+ exp_intop (~ (bfd_vma) 31));
+ lang_section_start (".text", t);
+ }
+ break;
+
+ case OPTION_STRCMPCT:
+ link_info.traditional_format = false;
+ break;
+
+ case OPTION_UNIX:
+ unix_ld = true;
+ break;
+ }
+
+ return 1;
+}
+
+/* This is called when an input file can not be recognized as a BFD
+ object or an archive. If the file starts with #!, we must treat it
+ as an import file. This is for AIX compatibility. */
+
+static boolean
+gld${EMULATION_NAME}_unrecognized_file (entry)
+ lang_input_statement_type *entry;
+{
+ FILE *e;
+ boolean ret;
+
+ e = fopen (entry->filename, FOPEN_RT);
+ if (e == NULL)
+ return false;
+
+ ret = false;
+
+ if (getc (e) == '#' && getc (e) == '!')
+ {
+ struct filelist *n;
+ struct filelist **flpp;
+
+ n = (struct filelist *) xmalloc (sizeof (struct filelist));
+ n->next = NULL;
+ n->name = entry->filename;
+ flpp = &import_files;
+ while (*flpp != NULL)
+ flpp = &(*flpp)->next;
+ *flpp = n;
+
+ ret = true;
+ entry->loaded = true;
+ }
+
+ fclose (e);
+
+ return ret;
+}
+
+/* This is called after the input files have been opened. */
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+ boolean r;
+ struct set_info *p;
+
+ /* Call ldctor_build_sets, after pretending that this is a
+ relocateable link. We do this because AIX requires relocation
+ entries for all references to symbols, even in a final
+ executable. Of course, we only want to do this if we are
+ producing an XCOFF output file. */
+ r = link_info.relocateable;
+ if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL)
+ link_info.relocateable = true;
+ ldctor_build_sets ();
+ link_info.relocateable = r;
+
+ /* For each set, record the size, so that the XCOFF backend can
+ output the correct csect length. */
+ for (p = sets; p != (struct set_info *) NULL; p = p->next)
+ {
+ bfd_size_type size;
+
+ /* If the symbol is defined, we may have been invoked from
+ collect, and the sets may already have been built, so we do
+ not do anything. */
+ if (p->h->type == bfd_link_hash_defined
+ || p->h->type == bfd_link_hash_defweak)
+ continue;
+
+ if (p->reloc != BFD_RELOC_CTOR)
+ {
+ /* Handle this if we need to. */
+ abort ();
+ }
+
+ size = (p->count + 2) * 4;
+ if (! bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size))
+ einfo ("%F%P: bfd_xcoff_link_record_set failed: %E\n");
+ }
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ struct filelist *fl;
+ struct export_symbol_list *el;
+ char *libpath;
+ asection *special_sections[6];
+ int i;
+
+ /* Handle the import and export files, if any. */
+ for (fl = import_files; fl != NULL; fl = fl->next)
+ gld${EMULATION_NAME}_read_file (fl->name, true);
+ for (el = export_symbols; el != NULL; el = el->next)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false);
+ if (h == NULL)
+ einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n");
+ if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall))
+ einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n");
+ }
+
+ /* Track down all relocations called for by the linker script (these
+ are typically constructor/destructor entries created by
+ CONSTRUCTORS) and let the backend know it will need to create
+ .loader relocs for them. */
+ lang_for_each_statement (gld${EMULATION_NAME}_find_relocs);
+
+ /* We need to build LIBPATH from the -L arguments. If any -rpath
+ arguments were used, though, we use -rpath instead, as a GNU
+ extension. */
+ if (command_line.rpath != NULL)
+ libpath = command_line.rpath;
+ else if (search_head == NULL)
+ libpath = (char *) "";
+ else
+ {
+ size_t len;
+ search_dirs_type *search;
+
+ len = strlen (search_head->name);
+ libpath = xmalloc (len + 1);
+ strcpy (libpath, search_head->name);
+ for (search = search_head->next; search != NULL; search = search->next)
+ {
+ size_t nlen;
+
+ nlen = strlen (search->name);
+ libpath = xrealloc (libpath, len + nlen + 2);
+ libpath[len] = ':';
+ strcpy (libpath + len + 1, search->name);
+ len += nlen + 1;
+ }
+ }
+
+ /* Let the XCOFF backend set up the .loader section. */
+ if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath,
+ entry_symbol, file_align,
+ maxstack, maxdata,
+ gc && ! unix_ld ? true : false,
+ modtype,
+ textro ? true : false,
+ unix_ld,
+ special_sections))
+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+ /* Look through the special sections, and put them in the right
+ place in the link ordering. This is especially magic. */
+ for (i = 0; i < 6; i++)
+ {
+ asection *sec;
+ lang_output_section_statement_type *os;
+ lang_statement_union_type **pls;
+ lang_input_section_type *is;
+ const char *oname;
+ boolean start;
+
+ sec = special_sections[i];
+ if (sec == NULL)
+ continue;
+
+ /* Remove this section from the list of the output section.
+ This assumes we know what the script looks like. */
+ is = NULL;
+ os = lang_output_section_find (sec->output_section->name);
+ if (os == NULL)
+ einfo ("%P%F: can't find output section %s\n",
+ sec->output_section->name);
+ for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->next)
+ {
+ if ((*pls)->header.type == lang_input_section_enum
+ && (*pls)->input_section.section == sec)
+ {
+ is = (lang_input_section_type *) *pls;
+ *pls = (*pls)->next;
+ break;
+ }
+ if ((*pls)->header.type == lang_wild_statement_enum)
+ {
+ lang_statement_union_type **pwls;
+
+ for (pwls = &(*pls)->wild_statement.children.head;
+ *pwls != NULL;
+ pwls = &(*pwls)->next)
+ {
+ if ((*pwls)->header.type == lang_input_section_enum
+ && (*pwls)->input_section.section == sec)
+ {
+ is = (lang_input_section_type *) *pwls;
+ *pwls = (*pwls)->next;
+ break;
+ }
+ }
+ if (is != NULL)
+ break;
+ }
+ }
+
+ if (is == NULL)
+ einfo ("%P%F: can't find %s in output section\n",
+ bfd_get_section_name (sec->owner, sec));
+
+ /* Now figure out where the section should go. */
+ switch (i)
+ {
+ default: /* to avoid warnings */
+ case 0:
+ /* _text */
+ oname = ".text";
+ start = true;
+ break;
+ case 1:
+ /* _etext */
+ oname = ".text";
+ start = false;
+ break;
+ case 2:
+ /* _data */
+ oname = ".data";
+ start = true;
+ break;
+ case 3:
+ /* _edata */
+ oname = ".data";
+ start = false;
+ break;
+ case 4:
+ case 5:
+ /* _end and end */
+ oname = ".bss";
+ start = false;
+ break;
+ }
+
+ os = lang_output_section_find (oname);
+
+ if (start)
+ {
+ is->header.next = os->children.head;
+ os->children.head = (lang_statement_union_type *) is;
+ }
+ else
+ {
+ is->header.next = NULL;
+ lang_statement_append (&os->children,
+ (lang_statement_union_type *) is,
+ &is->header.next);
+ }
+ }
+}
+
+/* Read an import or export file. For an import file, this is called
+ by the before_allocation emulation routine. For an export file,
+ this is called by the parse_args emulation routine. */
+
+static void
+gld${EMULATION_NAME}_read_file (filename, import)
+ const char *filename;
+ boolean import;
+{
+ struct obstack *o;
+ FILE *f;
+ int lineno;
+ int c;
+ boolean keep;
+ const char *imppath;
+ const char *impfile;
+ const char *impmember;
+
+ o = (struct obstack *) xmalloc (sizeof (struct obstack));
+ obstack_specify_allocation (o, 0, 0, xmalloc, gld${EMULATION_NAME}_free);
+
+ f = fopen (filename, FOPEN_RT);
+ if (f == NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ einfo ("%F%s: %E\n", filename);
+ }
+
+ keep = false;
+
+ imppath = NULL;
+ impfile = NULL;
+ impmember = NULL;
+
+ lineno = 0;
+ while ((c = getc (f)) != EOF)
+ {
+ char *s;
+ char *symname;
+ boolean syscall;
+ bfd_vma address;
+ struct bfd_link_hash_entry *h;
+
+ if (c != '\n')
+ {
+ obstack_1grow (o, c);
+ continue;
+ }
+
+ obstack_1grow (o, '\0');
+ ++lineno;
+
+ s = (char *) obstack_base (o);
+ while (isspace ((unsigned char) *s))
+ ++s;
+ if (*s == '\0'
+ || *s == '*'
+ || (*s == '#' && s[1] == ' ')
+ || (! import && *s == '#' && s[1] == '!'))
+ {
+ obstack_free (o, obstack_base (o));
+ continue;
+ }
+
+ if (*s == '#' && s[1] == '!')
+ {
+ s += 2;
+ while (isspace ((unsigned char) *s))
+ ++s;
+ if (*s == '\0')
+ {
+ imppath = NULL;
+ impfile = NULL;
+ impmember = NULL;
+ obstack_free (o, obstack_base (o));
+ }
+ else if (*s == '(')
+ einfo ("%F%s%d: #! ([member]) is not supported in import files\n",
+ filename, lineno);
+ else
+ {
+ char cs;
+ char *file;
+
+ (void) obstack_finish (o);
+ keep = true;
+ imppath = s;
+ file = NULL;
+ while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0')
+ {
+ if (*s == '/')
+ file = s + 1;
+ ++s;
+ }
+ if (file != NULL)
+ {
+ file[-1] = '\0';
+ impfile = file;
+ if (imppath == file - 1)
+ imppath = "/";
+ }
+ else
+ {
+ impfile = imppath;
+ imppath = "";
+ }
+ cs = *s;
+ *s = '\0';
+ while (isspace ((unsigned char) cs))
+ {
+ ++s;
+ cs = *s;
+ }
+ if (cs != '(')
+ {
+ impmember = "";
+ if (cs != '\0')
+ einfo ("%s:%d: warning: syntax error in import file\n",
+ filename, lineno);
+ }
+ else
+ {
+ ++s;
+ impmember = s;
+ while (*s != ')' && *s != '\0')
+ ++s;
+ if (*s == ')')
+ *s = '\0';
+ else
+ einfo ("%s:%d: warning: syntax error in import file\n",
+ filename, lineno);
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a symbol to be imported or exported. */
+ symname = s;
+ syscall = false;
+ address = (bfd_vma) -1;
+
+ while (! isspace ((unsigned char) *s) && *s != '\0')
+ ++s;
+ if (*s != '\0')
+ {
+ char *se;
+
+ *s++ = '\0';
+
+ while (isspace ((unsigned char) *s))
+ ++s;
+
+ se = s;
+ while (! isspace ((unsigned char) *se) && *se != '\0')
+ ++se;
+ if (*se != '\0')
+ {
+ *se++ = '\0';
+ while (isspace ((unsigned char) *se))
+ ++se;
+ if (*se != '\0')
+ einfo ("%s%d: warning: syntax error in import/export file\n",
+ filename, lineno);
+ }
+
+ if (s == se)
+ {
+ /* There was no address after all. */
+ }
+ else if (strcasecmp (s, "svc") == 0
+ || strcasecmp (s, "syscall") == 0)
+ syscall = true;
+ else
+ {
+ char *end;
+
+ address = strtoul (s, &end, 0);
+ if (*end != '\0')
+ einfo ("%s:%d: warning: syntax error in import/export file\n",
+ filename, lineno);
+ }
+ }
+
+ if (! import)
+ {
+ struct export_symbol_list *n;
+
+ ldlang_add_undef (symname);
+ n = ((struct export_symbol_list *)
+ xmalloc (sizeof (struct export_symbol_list)));
+ n->next = export_symbols;
+ n->name = buystring (symname);
+ n->syscall = syscall;
+ export_symbols = n;
+ }
+ else
+ {
+ h = bfd_link_hash_lookup (link_info.hash, symname, false, false,
+ true);
+ if (h == NULL || h->type == bfd_link_hash_new)
+ {
+ /* We can just ignore attempts to import an unreferenced
+ symbol. */
+ }
+ else
+ {
+ if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h,
+ address, imppath, impfile,
+ impmember))
+ einfo ("%X%s:%d: failed to import symbol %s: %E\n",
+ filename, lineno, symname);
+ }
+ }
+
+ obstack_free (o, obstack_base (o));
+ }
+
+ if (obstack_object_size (o) > 0)
+ {
+ einfo ("%s:%d: warning: ignoring unterminated last line\n",
+ filename, lineno);
+ obstack_free (o, obstack_base (o));
+ }
+
+ if (! keep)
+ {
+ obstack_free (o, NULL);
+ free (o);
+ }
+}
+
+/* This routine saves us from worrying about declaring free. */
+
+static void
+gld${EMULATION_NAME}_free (p)
+ PTR p;
+{
+ free (p);
+}
+
+/* This is called by the before_allocation routine via
+ lang_for_each_statement. It looks for relocations and assignments
+ to symbols. */
+
+static void
+gld${EMULATION_NAME}_find_relocs (s)
+ lang_statement_union_type *s;
+{
+ if (s->header.type == lang_reloc_statement_enum)
+ {
+ lang_reloc_statement_type *rs;
+
+ rs = &s->reloc_statement;
+ if (rs->name == NULL)
+ einfo ("%F%P: only relocations against symbols are permitted\n");
+ if (! bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name))
+ einfo ("%F%P: bfd_xcoff_link_count_reloc failed: %E\n");
+ }
+
+ if (s->header.type == lang_assignment_statement_enum)
+ gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
+}
+
+/* Look through an expression for an assignment statement. */
+
+static void
+gld${EMULATION_NAME}_find_exp_assignment (exp)
+ etree_type *exp;
+{
+ struct bfd_link_hash_entry *h;
+
+ switch (exp->type.node_class)
+ {
+ case etree_provide:
+ h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
+ false, false, false);
+ if (h == NULL)
+ break;
+ /* Fall through. */
+ case etree_assign:
+ if (strcmp (exp->assign.dst, ".") != 0)
+ {
+ if (! bfd_xcoff_record_link_assignment (output_bfd, &link_info,
+ exp->assign.dst))
+ einfo ("%P%F: failed to record assignment to %s: %E\n",
+ exp->assign.dst);
+ }
+ gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
+ break;
+
+ case etree_binary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
+ break;
+
+ case etree_trinary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
+ break;
+
+ case etree_unary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static char *
+gld${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ 0, /* finish */
+ 0, /* create_output_section_statements */
+ 0, /* open_dynamic_archive */
+ 0, /* place_orphan */
+ 0, /* set_symbols */
+ gld${EMULATION_NAME}_parse_args,
+ gld${EMULATION_NAME}_unrecognized_file
+};
+EOF
diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em
new file mode 100644
index 00000000000..9955fdad643
--- /dev/null
+++ b/ld/emultempl/armcoff.em
@@ -0,0 +1,226 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* emulate the original gld for the given ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "getopt.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+#include "ldexp.h"
+#include "ldlang.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+static int gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
+static void gld_${EMULATION_NAME}_list_options PARAMS ((FILE *));
+
+/* If true, then interworking stubs which support calls to old, non-interworking
+ aware ARM code should be generated. */
+
+static int support_old_code = 0;
+
+#define OPTION_SUPPORT_OLD_CODE 300
+
+static struct option longopts[] =
+{
+ {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
+ {NULL, no_argument, NULL, 0}
+};
+
+static void
+gld${EMULATION_NAME}_list_options (file)
+ FILE * file;
+{
+ fprintf (file, _(" --support-old-code Support interworking with old code\n"));
+}
+
+static int
+gld${EMULATION_NAME}_parse_args (argc, argv)
+ int argc;
+ char ** argv;
+{
+ int longind;
+ int optc;
+ int prevoptind = optind;
+ int prevopterr = opterr;
+ int wanterror;
+ static int lastoptind = -1;
+
+ if (lastoptind != optind)
+ opterr = 0;
+
+ wanterror = opterr;
+ lastoptind = optind;
+
+ optc = getopt_long_only (argc, argv, "-", longopts, & longind);
+ opterr = prevopterr;
+
+ switch (optc)
+ {
+ default:
+ if (wanterror)
+ xexit (1);
+ optind = prevoptind;
+ return 0;
+
+ case OPTION_SUPPORT_OLD_CODE:
+ support_old_code = 1;
+ break;
+ }
+
+ return 1;
+}
+
+static void
+gld${EMULATION_NAME}_before_parse ()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_set_output_arch ("`echo ${ARCH}`");
+#endif /* not TARGET_ */
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ /* we should be able to set the size of the interworking stub section */
+
+ /* Here we rummage through the found bfds to collect glue information */
+ /* FIXME: should this be based on a command line option? krk@cygnus.com */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (! bfd_arm_process_before_allocation
+ (is->the_bfd, & link_info, support_old_code))
+ {
+ /* xgettext:c-format */
+ einfo (_("Errors encountered processing file %s"), is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ bfd_arm_allocate_interworking_sections (& link_info);
+}
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
+ break;
+ }
+}
+
+static char *
+gld${EMULATION_NAME}_get_script (isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL, /* finish */
+ NULL, /* create output section statements */
+ NULL, /* open dynamic archive */
+ NULL, /* place orphan */
+ NULL, /* set_symbols */
+ gld${EMULATION_NAME}_parse_args,
+ NULL, /* unrecognised file */
+ gld${EMULATION_NAME}_list_options
+};
+EOF
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
new file mode 100644
index 00000000000..d9409f2ac7c
--- /dev/null
+++ b/ld/emultempl/armelf.em
@@ -0,0 +1,168 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* emulate the original gld for the given ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "getopt.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+#include "ldexp.h"
+#include "ldlang.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse ()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_set_output_arch ("`echo ${ARCH}`");
+#endif /* not TARGET_ */
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ /* we should be able to set the size of the interworking stub section */
+
+ /* Here we rummage through the found bfds to collect glue information */
+ /* FIXME: should this be based on a command line option? krk@cygnus.com */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (!bfd_elf32_arm_process_before_allocation (is->the_bfd, &link_info))
+ {
+ /* xgettext:c-format */
+ einfo (_("Errors encountered processing file %s"), is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ bfd_elf32_arm_allocate_interworking_sections (& link_info);
+}
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ /* The interworking bfd must be the last one to be processed */
+ if (!is->next)
+ bfd_elf32_arm_get_bfd_for_interworking (is->the_bfd, & link_info);
+ }
+}
+
+static char *
+gld${EMULATION_NAME}_get_script (isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL, /* finish */
+ NULL, /* create output section statements */
+ NULL, /* open dynamic archive */
+ NULL, /* place orphan */
+ NULL, /* set_symbols */
+ NULL,
+ NULL, /* unrecognised file */
+ NULL
+};
+EOF
diff --git a/ld/emultempl/armelf_oabi.em b/ld/emultempl/armelf_oabi.em
new file mode 100644
index 00000000000..c0526e5d6f7
--- /dev/null
+++ b/ld/emultempl/armelf_oabi.em
@@ -0,0 +1,175 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* emulate the original gld for the given ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#define bfd_elf32_arm_allocate_interworking_sections \
+ bfd_elf32_arm_oabi_allocate_interworking_sections
+#define bfd_elf32_arm_get_bfd_for_interworking \
+ bfd_elf32_arm_oabi_get_bfd_for_interworking
+#define bfd_elf32_arm_process_before_allocation \
+ bfd_elf32_arm_oabi_process_before_allocation
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "getopt.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+#include "ldexp.h"
+#include "ldlang.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse ()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_set_output_arch ("`echo ${ARCH}`");
+#endif /* not TARGET_ */
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ /* we should be able to set the size of the interworking stub section */
+
+ /* Here we rummage through the found bfds to collect glue information */
+ /* FIXME: should this be based on a command line option? krk@cygnus.com */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (!bfd_elf32_arm_process_before_allocation (is->the_bfd, &link_info))
+ {
+ /* xgettext:c-format */
+ einfo (_("Errors encountered processing file %s"), is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ bfd_elf32_arm_allocate_interworking_sections (& link_info);
+}
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ /* The interworking bfd must be the last one to be processed */
+ if (!is->next)
+ bfd_elf32_arm_get_bfd_for_interworking (is->the_bfd, & link_info);
+ }
+}
+
+static char *
+gld${EMULATION_NAME}_get_script (isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL, /* finish */
+ NULL, /* create output section statements */
+ NULL, /* open dynamic archive */
+ NULL, /* place orphan */
+ NULL, /* set_symbols */
+ NULL,
+ NULL, /* unrecognised file */
+ NULL
+};
+EOF
diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em
new file mode 100644
index 00000000000..c2b3ec21a09
--- /dev/null
+++ b/ld/emultempl/beos.em
@@ -0,0 +1,837 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is part of GLD, the Gnu Linker.
+ Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* For WINDOWS_NT */
+/* The original file generated returned different default scripts depending
+ on whether certain switches were set, but these switches pertain to the
+ Linux system and that particular version of coff. In the NT case, we
+ only determine if the subsystem is console or windows in order to select
+ the correct entry point by default. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "getopt.h"
+#include "libiberty.h"
+#include "ld.h"
+#include "ldmain.h"
+#include "ldgram.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldemul.h"
+#include "ldlex.h"
+#include "ldmisc.h"
+#include "ldctor.h"
+#include "ldfile.h"
+#include "coff/internal.h"
+#include "../bfd/libcoff.h"
+
+#define TARGET_IS_${EMULATION_NAME}
+
+static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
+static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
+static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
+static boolean gld${EMULATION_NAME}_place_orphan
+ PARAMS ((lang_input_statement_type *, asection *));
+static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
+static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
+
+#if 0 /* argument to qsort so don't prototype */
+static int sort_by_file_name PARAMS ((void *, void *));
+static int sort_by_section_name PARAMS ((void *, void *));
+#endif
+static lang_statement_union_type **sort_sections_1
+ PARAMS ((lang_statement_union_type **, lang_statement_union_type *, int,
+ int (*)()));
+static void sort_sections PARAMS ((lang_statement_union_type *));
+
+static struct internal_extra_pe_aouthdr pe;
+static int dll;
+
+extern const char *output_filename;
+
+static void
+gld_${EMULATION_NAME}_before_parse()
+{
+ output_filename = "a.exe";
+ ldfile_output_architecture = bfd_arch_${ARCH};
+}
+
+/* PE format extra command line options. */
+
+/* Used for setting flags in the PE header. */
+#define OPTION_BASE_FILE (300 + 1)
+#define OPTION_DLL (OPTION_BASE_FILE + 1)
+#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
+#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
+#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
+#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
+#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
+#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
+#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
+#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
+#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
+#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
+#define OPTION_SUBSYSTEM (OPTION_STACK + 1)
+#define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
+
+static struct option longopts[] = {
+ /* PE options */
+ {"base-file", required_argument, NULL, OPTION_BASE_FILE},
+ {"dll", no_argument, NULL, OPTION_DLL},
+ {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
+ {"heap", required_argument, NULL, OPTION_HEAP},
+ {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
+ {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
+ {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
+ {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
+ {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
+ {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
+ {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
+ {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
+ {"stack", required_argument, NULL, OPTION_STACK},
+ {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
+ {NULL, no_argument, NULL, 0}
+ };
+
+
+/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
+ parameters which may be input from the command line */
+
+typedef struct {
+ void *ptr;
+ int size;
+ int value;
+ char *symbol;
+ int inited;
+} definfo;
+
+#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
+
+static definfo init[] =
+{
+ /* imagebase must be first */
+#define IMAGEBASEOFF 0
+ D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE),
+#define DLLOFF 1
+ {&dll, sizeof(dll), 0, "__dll__"},
+ D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
+ D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
+ D(MajorOperatingSystemVersion,"__major_os_version__", 4),
+ D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
+ D(MajorImageVersion,"__major_image_version__", 1),
+ D(MinorImageVersion,"__minor_image_version__", 0),
+ D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
+ D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
+ D(Subsystem,"__subsystem__", 3),
+ D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
+ D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
+ D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
+ D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
+ D(LoaderFlags,"__loader_flags__", 0x0),
+ { NULL, 0, 0, NULL, 0 }
+};
+
+
+static void
+set_pe_name (name, val)
+ char *name;
+ long val;
+{
+ int i;
+ /* Find the name and set it. */
+ for (i = 0; init[i].ptr; i++)
+ {
+ if (strcmp (name, init[i].symbol) == 0)
+ {
+ init[i].value = val;
+ init[i].inited = 1;
+ return;
+ }
+ }
+ abort();
+}
+
+
+static void
+set_pe_subsystem ()
+{
+ const char *sver;
+ int len;
+ int i;
+ static const struct
+ {
+ const char *name;
+ const int value;
+ const char *entry;
+ }
+ v[] =
+ {
+ { "native", 1, "_NtProcessStartup" },
+ { "windows", 2, "_WinMainCRTStartup" },
+ { "wwindows", 2, "_wWinMainCRTStartup" },
+ { "console", 3, "_mainCRTStartup" },
+ { "wconsole", 3, "_wmainCRTStartup" },
+#if 0
+ /* The Microsoft linker does not recognize this. */
+ { "os2", 5, "" },
+#endif
+ { "posix", 7, "___PosixProcessStartup"},
+ { 0, 0, 0 }
+ };
+
+ sver = strchr (optarg, ':');
+ if (sver == NULL)
+ len = strlen (optarg);
+ else
+ {
+ char *end;
+
+ len = sver - optarg;
+ set_pe_name ("__major_subsystem_version__",
+ strtoul (sver + 1, &end, 0));
+ if (*end == '.')
+ set_pe_name ("__minor_subsystem_version__",
+ strtoul (end + 1, &end, 0));
+ if (*end != '\0')
+ einfo ("%P: warning: bad version number in -subsystem option\n");
+ }
+
+ for (i = 0; v[i].name; i++)
+ {
+ if (strncmp (optarg, v[i].name, len) == 0
+ && v[i].name[len] == '\0')
+ {
+ set_pe_name ("__subsystem__", v[i].value);
+
+ /* If the subsystem is windows, we use a different entry
+ point. We also register the entry point as an undefined
+ symbol. from lang_add_entry() The reason we do
+ this is so that the user
+ doesn't have to because they would have to use the -u
+ switch if they were specifying an entry point other than
+ _mainCRTStartup. Specifically, if creating a windows
+ application, entry point _WinMainCRTStartup must be
+ specified. What I have found for non console
+ applications (entry not _mainCRTStartup) is that the .obj
+ that contains mainCRTStartup is brought in since it is
+ the first encountered in libc.lib and it has other
+ symbols in it which will be pulled in by the link
+ process. To avoid this, adding -u with the entry point
+ name specified forces the correct .obj to be used. We
+ can avoid making the user do this by always adding the
+ entry point name as an undefined symbol. */
+ lang_add_entry (v[i].entry, 1);
+
+ return;
+ }
+ }
+ einfo ("%P%F: invalid subsystem type %s\n", optarg);
+}
+
+
+
+static void
+set_pe_value (name)
+ char *name;
+
+{
+ char *end;
+ set_pe_name (name, strtoul (optarg, &end, 0));
+ if (end == optarg)
+ {
+ einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
+ }
+
+ optarg = end;
+}
+
+static void
+set_pe_stack_heap (resname, comname)
+ char *resname;
+ char *comname;
+{
+ set_pe_value (resname);
+ if (*optarg == ',')
+ {
+ optarg++;
+ set_pe_value (comname);
+ }
+ else if (*optarg)
+ {
+ einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
+ }
+}
+
+
+
+static int
+gld_${EMULATION_NAME}_parse_args(argc, argv)
+ int argc;
+ char **argv;
+{
+ int longind;
+ int optc;
+ int prevoptind = optind;
+ int prevopterr = opterr;
+ int wanterror;
+ static int lastoptind = -1;
+
+ if (lastoptind != optind)
+ opterr = 0;
+ wanterror = opterr;
+
+ lastoptind = optind;
+
+ optc = getopt_long_only (argc, argv, "-", longopts, &longind);
+ opterr = prevopterr;
+
+ switch (optc)
+ {
+ default:
+ if (wanterror)
+ xexit (1);
+ optind = prevoptind;
+ return 0;
+
+ case OPTION_BASE_FILE:
+ link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
+ if (link_info.base_file == NULL)
+ {
+ fprintf (stderr, "%s: Can't open base file %s\n",
+ program_name, optarg);
+ xexit (1);
+ }
+ break;
+
+ /* PE options */
+ case OPTION_HEAP:
+ set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
+ break;
+ case OPTION_STACK:
+ set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
+ break;
+ case OPTION_SUBSYSTEM:
+ set_pe_subsystem ();
+ break;
+ case OPTION_MAJOR_OS_VERSION:
+ set_pe_value ("__major_os_version__");
+ break;
+ case OPTION_MINOR_OS_VERSION:
+ set_pe_value ("__minor_os_version__");
+ break;
+ case OPTION_MAJOR_SUBSYSTEM_VERSION:
+ set_pe_value ("__major_subsystem_version__");
+ break;
+ case OPTION_MINOR_SUBSYSTEM_VERSION:
+ set_pe_value ("__minor_subsystem_version__");
+ break;
+ case OPTION_MAJOR_IMAGE_VERSION:
+ set_pe_value ("__major_image_version__");
+ break;
+ case OPTION_MINOR_IMAGE_VERSION:
+ set_pe_value ("__minor_image_version__");
+ break;
+ case OPTION_FILE_ALIGNMENT:
+ set_pe_value ("__file_alignment__");
+ break;
+ case OPTION_SECTION_ALIGNMENT:
+ set_pe_value ("__section_alignment__");
+ break;
+ case OPTION_DLL:
+ set_pe_name ("__dll__", 1);
+ break;
+ case OPTION_IMAGE_BASE:
+ set_pe_value ("__image_base__");
+ break;
+ }
+ return 1;
+}
+
+/* Assign values to the special symbols before the linker script is
+ read. */
+
+static void
+gld_${EMULATION_NAME}_set_symbols()
+{
+ /* Run through and invent symbols for all the
+ names and insert the defaults. */
+ int j;
+ lang_statement_list_type *save;
+
+ if (!init[IMAGEBASEOFF].inited)
+ {
+ if (link_info.relocateable)
+ init[IMAGEBASEOFF].value = 0;
+ else if (init[DLLOFF].value)
+ init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE;
+ else
+ init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE;
+ }
+
+ /* Don't do any symbol assignments if this is a relocateable link. */
+ if (link_info.relocateable)
+ return;
+
+ /* Glue the assignments into the abs section */
+ save = stat_ptr;
+
+ stat_ptr = &(abs_output_section->children);
+
+ for (j = 0; init[j].ptr; j++)
+ {
+ long val = init[j].value;
+ lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
+ if (init[j].size == sizeof(short))
+ *(short *)init[j].ptr = val;
+ else if (init[j].size == sizeof(int))
+ *(int *)init[j].ptr = val;
+ else if (init[j].size == sizeof(long))
+ *(long *)init[j].ptr = val;
+ /* This might be a long long or other special type. */
+ else if (init[j].size == sizeof(bfd_vma))
+ *(bfd_vma *)init[j].ptr = val;
+ else abort();
+ }
+ /* Restore the pointer. */
+ stat_ptr = save;
+
+ if (pe.FileAlignment >
+ pe.SectionAlignment)
+ {
+ einfo ("%P: warning, file alignment > section alignment.\n");
+ }
+}
+
+static void
+gld_${EMULATION_NAME}_after_open()
+{
+ /* Pass the wacky PE command line options into the output bfd.
+ FIXME: This should be done via a function, rather than by
+ including an internal BFD header. */
+ if (!coff_data(output_bfd)->pe)
+ {
+ einfo ("%F%P: PE operations on non PE file.\n");
+ }
+
+ pe_data(output_bfd)->pe_opthdr = pe;
+ pe_data(output_bfd)->dll = init[DLLOFF].value;
+
+}
+
+/* Callback functions for qsort in sort_sections. */
+
+static int
+sort_by_file_name (a, b)
+ void *a;
+ void *b;
+{
+ lang_statement_union_type **ra = a;
+ lang_statement_union_type **rb = b;
+ int i, a_sec, b_sec;
+
+ i = strcmp ((*ra)->input_section.ifile->the_bfd->my_archive->filename,
+ (*rb)->input_section.ifile->the_bfd->my_archive->filename);
+ if (i != 0)
+ return i;
+
+ i = strcmp ((*ra)->input_section.ifile->filename,
+ (*rb)->input_section.ifile->filename);
+ if (i != 0)
+ return i;
+ /* the tail idata4/5 are the only ones without relocs to an
+ idata$6 section unless we are importing by ordinal,
+ so sort them to last to terminate the IAT
+ and HNT properly. if no reloc this one is import by ordinal
+ so we have to sort by section contents */
+
+ if ( ((*ra)->input_section.section->reloc_count + (*rb)->input_section.section->reloc_count) )
+ {
+ i = (((*ra)->input_section.section->reloc_count >
+ (*rb)->input_section.section->reloc_count) ? -1 : 0);
+ if ( i != 0)
+ return i;
+
+ return (((*ra)->input_section.section->reloc_count >
+ (*rb)->input_section.section->reloc_count) ? 0 : 1);
+ }
+ else
+ {
+ if ( (strcmp( (*ra)->input_section.section->name, ".idata$6") == 0) )
+ return 0; /* don't sort .idata$6 or .idata$7 FIXME dlltool eliminate .idata$7 */
+
+ if (! bfd_get_section_contents ((*ra)->input_section.ifile->the_bfd,
+ (*ra)->input_section.section, &a_sec, (file_ptr) 0, (bfd_size_type)sizeof(a_sec)))
+ einfo ("%F%B: Can't read contents of section .idata: %E\n",
+ (*ra)->input_section.ifile->the_bfd);
+
+ if (! bfd_get_section_contents ((*rb)->input_section.ifile->the_bfd,
+ (*rb)->input_section.section, &b_sec, (file_ptr) 0, (bfd_size_type)sizeof(b_sec) ))
+ einfo ("%F%B: Can't read contents of section .idata: %E\n",
+ (*rb)->input_section.ifile->the_bfd);
+
+ i = ((a_sec < b_sec) ? -1 : 0);
+ if ( i != 0)
+ return i;
+ return ((a_sec < b_sec) ? 0 : 1);
+ }
+return 0;
+}
+
+static int
+sort_by_section_name (a, b)
+ void *a;
+ void *b;
+{
+ lang_statement_union_type **ra = a;
+ lang_statement_union_type **rb = b;
+ int i;
+ i = strcmp ((*ra)->input_section.section->name,
+ (*rb)->input_section.section->name);
+/* this is a hack to make .stab and .stabstr last, so we don't have
+ to fix strip/objcopy for .reloc sections.
+ FIXME stripping images with a .rsrc section still needs to be fixed */
+ if ( i != 0)
+ {
+ if ((strncmp ((*ra)->input_section.section->name, ".stab", 5) == 0)
+ && (strncmp ((*rb)->input_section.section->name, ".stab", 5) != 0))
+ return 1;
+ return i;
+ }
+ return i;
+}
+
+/* Subroutine of sort_sections to a contiguous subset of a list of sections.
+ NEXT_AFTER is the element after the last one to sort.
+ The result is a pointer to the last element's "next" pointer. */
+
+static lang_statement_union_type **
+sort_sections_1 (startptr, next_after, count, sort_func)
+ lang_statement_union_type **startptr,*next_after;
+ int count;
+ int (*sort_func) ();
+{
+ lang_statement_union_type **vec;
+ lang_statement_union_type *p;
+ int i;
+ lang_statement_union_type **ret;
+
+ if (count == 0)
+ return startptr;
+
+ vec = ((lang_statement_union_type **)
+ xmalloc (count * sizeof (lang_statement_union_type *)));
+
+ for (p = *startptr, i = 0; i < count; i++, p = p->next)
+ vec[i] = p;
+
+ qsort (vec, count, sizeof (vec[0]), sort_func);
+
+ /* Fill in the next pointers again. */
+ *startptr = vec[0];
+ for (i = 0; i < count - 1; i++)
+ vec[i]->header.next = vec[i + 1];
+ vec[i]->header.next = next_after;
+ ret = &vec[i]->header.next;
+ free (vec);
+ return ret;
+}
+
+/* Sort the .idata\$foo input sections of archives into filename order.
+ The reason is so dlltool can arrange to have the pe dll import information
+ generated correctly - the head of the list goes into dh.o, the tail into
+ dt.o, and the guts into ds[nnnn].o. Note that this is only needed for the
+ .idata section.
+ FIXME: This may no longer be necessary with grouped sections. Instead of
+ sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
+ .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
+ This would have to be elaborated upon to handle multiple dll's
+ [assuming such an eloboration is possible of course].
+
+ We also sort sections in '\$' wild statements. These are created by the
+ place_orphans routine to implement grouped sections. */
+
+static void
+sort_sections (s)
+ lang_statement_union_type *s;
+{
+ for (; s ; s = s->next)
+ switch (s->header.type)
+ {
+ case lang_output_section_statement_enum:
+ sort_sections (s->output_section_statement.children.head);
+ break;
+ case lang_wild_statement_enum:
+ {
+ lang_statement_union_type **p = &s->wild_statement.children.head;
+
+ /* Is this the .idata section? */
+ if (s->wild_statement.section_name != NULL
+ && strncmp (s->wild_statement.section_name, ".idata", 6) == 0)
+ {
+ /* Sort the children. We want to sort any objects in
+ the same archive. In order to handle the case of
+ including a single archive multiple times, we sort
+ all the children by archive name and then by object
+ name. After sorting them, we re-thread the pointer
+ chain. */
+
+ while (*p)
+ {
+ lang_statement_union_type *start = *p;
+ if (start->header.type != lang_input_section_enum
+ || !start->input_section.ifile->the_bfd->my_archive)
+ p = &(start->header.next);
+ else
+ {
+ lang_statement_union_type *end;
+ int count;
+
+ for (end = start, count = 0;
+ end && end->header.type == lang_input_section_enum;
+ end = end->next)
+ count++;
+
+ p = sort_sections_1 (p, end, count, sort_by_file_name);
+ }
+ }
+ break;
+ }
+
+ /* If this is a collection of grouped sections, sort them.
+ The linker script must explicitly mention "*(.foo\$)" or
+ "*(.foo\$*)". Don't sort them if \$ is not the last
+ character (not sure if this is really useful, but it
+ allows explicitly mentioning some \$ sections and letting
+ the linker handle the rest). */
+ if (s->wild_statement.section_name != NULL)
+ {
+ char *q = strchr (s->wild_statement.section_name, '\$');
+
+ if (q != NULL
+ && (q[1] == '\0'
+ || (q[1] == '*' && q[2] == '\0')))
+ {
+ lang_statement_union_type *end;
+ int count;
+
+ for (end = *p, count = 0; end; end = end->next)
+ {
+ if (end->header.type != lang_input_section_enum)
+ abort ();
+ count++;
+ }
+ (void) sort_sections_1 (p, end, count, sort_by_section_name);
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gld_${EMULATION_NAME}_before_allocation()
+{
+ extern lang_statement_list_type *stat_ptr;
+
+#ifdef TARGET_IS_ppcpe
+ /* Here we rummage through the found bfds to collect toc information */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (!ppc_process_before_allocation(is->the_bfd, &link_info))
+ {
+ einfo("Errors encountered processing file %s\n", is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ ppc_allocate_toc_section (&link_info);
+#else
+#ifdef TARGET_IS_armpe
+ /* FIXME: we should be able to set the size of the interworking stub
+ section.
+
+ Here we rummage through the found bfds to collect glue
+ information. FIXME: should this be based on a command line
+ option? krk@cygnus.com */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (!arm_process_before_allocation (is->the_bfd, & link_info))
+ {
+ einfo ("Errors encountered processing file %s", is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ arm_allocate_interworking_sections (& link_info);
+#endif /* TARGET_IS_armpe */
+#endif /* TARGET_IS_ppcpe */
+
+ sort_sections (stat_ptr->head);
+}
+
+/* Place an orphan section. We use this to put sections with a '\$' in them
+ into the right place. Any section with a '\$' in them (e.g. .text\$foo)
+ gets mapped to the output section with everything from the '\$' on stripped
+ (e.g. .text).
+ See the Microsoft Portable Executable and Common Object File Format
+ Specification 4.1, section 4.2, Grouped Sections.
+
+ FIXME: This is now handled by the linker script using wildcards,
+ but I'm leaving this here in case we want to enable it for sections
+ which are not mentioned in the linker script. */
+
+/*ARGSUSED*/
+static boolean
+gld${EMULATION_NAME}_place_orphan (file, s)
+ lang_input_statement_type *file;
+ asection *s;
+{
+ const char *secname;
+ char *output_secname, *ps;
+ lang_output_section_statement_type *os;
+ lang_statement_union_type *l;
+
+ if ((s->flags & SEC_ALLOC) == 0)
+ return false;
+
+ /* Don't process grouped sections unless doing a final link.
+ If they're marked as COMDAT sections, we don't want .text\$foo to
+ end up in .text and then have .text disappear because it's marked
+ link-once-discard. */
+ if (link_info.relocateable)
+ return false;
+
+ secname = bfd_get_section_name (s->owner, s);
+
+ /* Everything from the '\$' on gets deleted so don't allow '\$' as the
+ first character. */
+ if (*secname == '\$')
+ einfo ("%P%F: section %s has '\$' as first character\n", secname);
+ if (strchr (secname + 1, '\$') == NULL)
+ return false;
+
+ /* Look up the output section. The Microsoft specs say sections names in
+ image files never contain a '\$'. Fortunately, lang_..._lookup creates
+ the section if it doesn't exist. */
+ output_secname = buystring (secname);
+ ps = strchr (output_secname + 1, '\$');
+ *ps = 0;
+ os = lang_output_section_statement_lookup (output_secname);
+
+ /* Find the '\$' wild statement for this section. We currently require the
+ linker script to explicitly mention "*(.foo\$)".
+ FIXME: ppcpe.sc has .CRT\$foo in the .rdata section. According to the
+ Microsoft docs this isn't correct so it's not (currently) handled. */
+
+ ps[0] = '\$';
+ ps[1] = 0;
+ for (l = os->children.head; l; l = l->next)
+ {
+ if (l->header.type == lang_wild_statement_enum
+ && strcmp (l->wild_statement.section_name, output_secname) == 0)
+ break;
+ }
+ ps[0] = 0;
+ if (l == NULL)
+#if 1
+ einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname);
+#else /* FIXME: This block is untried. It exists to convey the intent,
+ should one decide to not require *(.foo\$) to appear in the linker
+ script. */
+ {
+ lang_wild_statement_type *new = new_stat (lang_wild_statement,
+ &os->children);
+ new->section_name = xmalloc (strlen (output_secname) + 2);
+ sprintf (new->section_name, "%s\$", output_secname);
+ new->filename = NULL;
+ lang_list_init (&new->children);
+ l = new;
+ }
+#endif
+
+ /* Link the input section in and we're done for now.
+ The sections still have to be sorted, but that has to wait until
+ all such sections have been processed by us. The sorting is done by
+ sort_sections. */
+ wild_doit (&l->wild_statement.children, s, os, file);
+
+ return true;
+}
+
+static char *
+gld_${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+# Scripts compiled in.
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld_${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld_${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld_${EMULATION_NAME}_before_allocation,
+ gld_${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL, /* finish */
+ NULL, /* create output section statements */
+ NULL, /* open dynamic archive */
+ gld${EMULATION_NAME}_place_orphan,
+ gld_${EMULATION_NAME}_set_symbols,
+ gld_${EMULATION_NAME}_parse_args
+};
+EOF
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
new file mode 100644
index 00000000000..03586761e7b
--- /dev/null
+++ b/ld/emultempl/elf32.em
@@ -0,0 +1,1143 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+# This file is now misnamed, because it supports both 32 bit and 64 bit
+# ELF emulations.
+test -z "${ELFSIZE}" && ELFSIZE=32
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+ ELF support by Ian Lance Taylor <ian@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#include <ctype.h>
+
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldgram.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static boolean gld${EMULATION_NAME}_open_dynamic_archive
+ PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
+static void gld${EMULATION_NAME}_after_open PARAMS ((void));
+static void gld${EMULATION_NAME}_check_needed
+ PARAMS ((lang_input_statement_type *));
+static void gld${EMULATION_NAME}_stat_needed
+ PARAMS ((lang_input_statement_type *));
+static boolean gld${EMULATION_NAME}_search_needed
+ PARAMS ((const char *, const char *, int));
+static boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int));
+static void gld${EMULATION_NAME}_vercheck
+ PARAMS ((lang_input_statement_type *));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static void gld${EMULATION_NAME}_find_statement_assignment
+ PARAMS ((lang_statement_union_type *));
+static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
+static boolean gld${EMULATION_NAME}_place_orphan
+ PARAMS ((lang_input_statement_type *, asection *));
+static void gld${EMULATION_NAME}_place_section
+ PARAMS ((lang_statement_union_type *));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+ ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
+ config.dynamic_link = ${DYNAMIC_LINK-true};
+ config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
+}
+
+/* Try to open a dynamic archive. This is where we know that ELF
+ dynamic libraries have an extension of .so. */
+
+static boolean
+gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
+ const char *arch;
+ search_dirs_type *search;
+ lang_input_statement_type *entry;
+{
+ const char *filename;
+ char *string;
+
+ if (! entry->is_archive)
+ return false;
+
+ filename = entry->filename;
+
+ string = (char *) xmalloc (strlen (search->name)
+ + strlen (filename)
+ + strlen (arch)
+ + sizeof "/lib.so");
+
+ sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
+
+ if (! ldfile_try_open_bfd (string, entry))
+ {
+ free (string);
+ return false;
+ }
+
+ entry->filename = string;
+
+ /* We have found a dynamic object to include in the link. The ELF
+ backend linker will create a DT_NEEDED entry in the .dynamic
+ section naming this file. If this file includes a DT_SONAME
+ entry, it will be used. Otherwise, the ELF linker will just use
+ the name of the file. For an archive found by searching, like
+ this one, the DT_NEEDED entry should consist of just the name of
+ the file, without the path information used to find it. Note
+ that we only need to do this if we have a dynamic object; an
+ archive will never be referenced by a DT_NEEDED entry.
+
+ FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
+ very pretty. I haven't been able to think of anything that is
+ pretty, though. */
+ if (bfd_check_format (entry->the_bfd, bfd_object)
+ && (entry->the_bfd->flags & DYNAMIC) != 0)
+ {
+ char *needed_name;
+
+ ASSERT (entry->is_archive && entry->search_dirs_flag);
+ needed_name = (char *) xmalloc (strlen (filename)
+ + strlen (arch)
+ + sizeof "lib.so");
+ sprintf (needed_name, "lib%s%s.so", filename, arch);
+ bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
+ }
+
+ return true;
+}
+
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+ if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+
+/* For a native linker, check the file /etc/ld.so.conf for directories
+ in which we may find shared libraries. /etc/ld.so.conf is really
+ only meaningful on Linux, but we check it on other systems anyhow. */
+
+static boolean gld${EMULATION_NAME}_check_ld_so_conf
+ PARAMS ((const char *, int));
+
+static boolean
+gld${EMULATION_NAME}_check_ld_so_conf (name, force)
+ const char *name;
+ int force;
+{
+ static boolean initialized;
+ static char *ld_so_conf;
+
+ if (! initialized)
+ {
+ FILE *f;
+
+ f = fopen ("/etc/ld.so.conf", FOPEN_RT);
+ if (f != NULL)
+ {
+ char *b;
+ size_t len, alloc;
+ int c;
+
+ len = 0;
+ alloc = 100;
+ b = (char *) xmalloc (alloc);
+
+ while ((c = getc (f)) != EOF)
+ {
+ if (len + 1 >= alloc)
+ {
+ alloc *= 2;
+ b = (char *) xrealloc (b, alloc);
+ }
+ if (c != ':'
+ && c != ' '
+ && c != '\t'
+ && c != '\n'
+ && c != ',')
+ {
+ b[len] = c;
+ ++len;
+ }
+ else
+ {
+ if (len > 0 && b[len - 1] != ':')
+ {
+ b[len] = ':';
+ ++len;
+ }
+ }
+ }
+
+ if (len > 0 && b[len - 1] == ':')
+ --len;
+
+ if (len > 0)
+ b[len] = '\0';
+ else
+ {
+ free (b);
+ b = NULL;
+ }
+
+ fclose (f);
+
+ ld_so_conf = b;
+ }
+
+ initialized = true;
+ }
+
+ if (ld_so_conf == NULL)
+ return false;
+
+ return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force);
+}
+
+EOF
+ fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+
+/* These variables are required to pass information back and forth
+ between after_open and check_needed and stat_needed and vercheck. */
+
+static struct bfd_link_needed_list *global_needed;
+static struct stat global_stat;
+static boolean global_found;
+static struct bfd_link_needed_list *global_vercheck_needed;
+static boolean global_vercheck_failed;
+
+/* This is called after all the input files have been opened. */
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+ struct bfd_link_needed_list *needed, *l;
+
+ /* We only need to worry about this when doing a final link. */
+ if (link_info.relocateable || link_info.shared)
+ return;
+
+ /* Get the list of files which appear in DT_NEEDED entries in
+ dynamic objects included in the link (often there will be none).
+ For each such file, we want to track down the corresponding
+ library, and include the symbol table in the link. This is what
+ the runtime dynamic linker will do. Tracking the files down here
+ permits one dynamic object to include another without requiring
+ special action by the person doing the link. Note that the
+ needed list can actually grow while we are stepping through this
+ loop. */
+ needed = bfd_elf_get_needed_list (output_bfd, &link_info);
+ for (l = needed; l != NULL; l = l->next)
+ {
+ struct bfd_link_needed_list *ll;
+ int force;
+
+ /* If we've already seen this file, skip it. */
+ for (ll = needed; ll != l; ll = ll->next)
+ if (strcmp (ll->name, l->name) == 0)
+ break;
+ if (ll != l)
+ continue;
+
+ /* See if this file was included in the link explicitly. */
+ global_needed = l;
+ global_found = false;
+ lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
+ if (global_found)
+ continue;
+
+ /* We need to find this file and include the symbol table. We
+ want to search for the file in the same way that the dynamic
+ linker will search. That means that we want to use
+ rpath_link, rpath, then the environment variable
+ LD_LIBRARY_PATH (native only), then the linker script
+ LIB_SEARCH_DIRS. We do not search using the -L arguments.
+
+ We search twice. The first time, we skip objects which may
+ introduce version mismatches. The second time, we force
+ their use. See gld${EMULATION_NAME}_vercheck comment. */
+ for (force = 0; force < 2; force++)
+ {
+ const char *lib_path;
+ size_t len;
+ search_dirs_type *search;
+
+ if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
+ l->name, force))
+ break;
+ if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
+ l->name, force))
+ break;
+ if (command_line.rpath_link == NULL
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
+ if (gld${EMULATION_NAME}_search_needed (lib_path, l->name,
+ force))
+ break;
+ }
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+ if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+ lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
+ if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
+ break;
+EOF
+ fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+ len = strlen (l->name);
+ for (search = search_head; search != NULL; search = search->next)
+ {
+ char *filename;
+
+ if (search->cmdline)
+ continue;
+ filename = (char *) xmalloc (strlen (search->name) + len + 2);
+ sprintf (filename, "%s/%s", search->name, l->name);
+ if (gld${EMULATION_NAME}_try_needed (filename, force))
+ break;
+ free (filename);
+ }
+ if (search != NULL)
+ break;
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+ if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+ if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
+ break;
+EOF
+ fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+ }
+
+ if (force < 2)
+ continue;
+
+ einfo ("%P: warning: %s, needed by %B, not found (try using --rpath)\n",
+ l->name, l->by);
+ }
+}
+
+/* Search for a needed file in a path. */
+
+static boolean
+gld${EMULATION_NAME}_search_needed (path, name, force)
+ const char *path;
+ const char *name;
+ int force;
+{
+ const char *s;
+ size_t len;
+
+ if (path == NULL || *path == '\0')
+ return false;
+ len = strlen (name);
+ while (1)
+ {
+ char *filename, *sset;
+
+ s = strchr (path, ':');
+ if (s == NULL)
+ s = path + strlen (path);
+
+ filename = (char *) xmalloc (s - path + len + 2);
+ if (s == path)
+ sset = filename;
+ else
+ {
+ memcpy (filename, path, s - path);
+ filename[s - path] = '/';
+ sset = filename + (s - path) + 1;
+ }
+ strcpy (sset, name);
+
+ if (gld${EMULATION_NAME}_try_needed (filename, force))
+ return true;
+
+ free (filename);
+
+ if (*s == '\0')
+ break;
+ path = s + 1;
+ }
+
+ return false;
+}
+
+/* This function is called for each possible name for a dynamic object
+ named by a DT_NEEDED entry. The FORCE parameter indicates whether
+ to skip the check for a conflicting version. */
+
+static boolean
+gld${EMULATION_NAME}_try_needed (name, force)
+ const char *name;
+ int force;
+{
+ bfd *abfd;
+
+ abfd = bfd_openr (name, bfd_get_target (output_bfd));
+ if (abfd == NULL)
+ return false;
+ if (! bfd_check_format (abfd, bfd_object))
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+ if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+
+ /* Check whether this object would include any conflicting library
+ versions. If FORCE is set, then we skip this check; we use this
+ the second time around, if we couldn't find any compatible
+ instance of the shared library. */
+
+ if (! force)
+ {
+ struct bfd_link_needed_list *needed;
+
+ if (! bfd_elf_get_bfd_needed_list (abfd, &needed))
+ einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
+
+ if (needed != NULL)
+ {
+ global_vercheck_needed = needed;
+ global_vercheck_failed = false;
+ lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
+ if (global_vercheck_failed)
+ {
+ (void) bfd_close (abfd);
+ /* Return false to force the caller to move on to try
+ another file on the search path. */
+ return false;
+ }
+
+ /* But wait! It gets much worse. On Linux, if a shared
+ library does not use libc at all, we are supposed to skip
+ it the first time around in case we encounter a shared
+ library later on with the same name which does use the
+ version of libc that we want. This is much too horrible
+ to use on any system other than Linux. */
+
+EOF
+case ${target} in
+ *-*-linux-gnu*)
+ cat >>e${EMULATION_NAME}.c <<EOF
+ {
+ struct bfd_link_needed_list *l;
+
+ for (l = needed; l != NULL; l = l->next)
+ if (strncmp (l->name, "libc.so", 7) == 0)
+ break;
+ if (l == NULL)
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+ }
+
+EOF
+ ;;
+esac
+cat >>e${EMULATION_NAME}.c <<EOF
+ }
+ }
+
+ /* We've found a dynamic object matching the DT_NEEDED entry. */
+
+ /* We have already checked that there is no other input file of the
+ same name. We must now check again that we are not including the
+ same file twice. We need to do this because on many systems
+ libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will
+ reference libc.so.1. If we have already included libc.so, we
+ don't want to include libc.so.1 if they are the same file, and we
+ can only check that using stat. */
+
+ if (bfd_stat (abfd, &global_stat) != 0)
+ einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
+ global_found = false;
+ lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
+ if (global_found)
+ {
+ /* Return true to indicate that we found the file, even though
+ we aren't going to do anything with it. */
+ return true;
+ }
+
+ /* Tell the ELF backend that don't want the output file to have a
+ DT_NEEDED entry for this file. */
+ bfd_elf_set_dt_needed_name (abfd, "");
+
+ /* Add this file into the symbol table. */
+ if (! bfd_link_add_symbols (abfd, &link_info))
+ einfo ("%F%B: could not read symbols: %E\n", abfd);
+
+ return true;
+}
+
+/* See if an input file matches a DT_NEEDED entry by name. */
+
+static void
+gld${EMULATION_NAME}_check_needed (s)
+ lang_input_statement_type *s;
+{
+ if (global_found)
+ return;
+
+ if (s->filename != NULL
+ && strcmp (s->filename, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+
+ if (s->the_bfd != NULL)
+ {
+ const char *soname;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname != NULL
+ && strcmp (soname, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+ }
+
+ if (s->search_dirs_flag
+ && s->filename != NULL
+ && strchr (global_needed->name, '/') == NULL)
+ {
+ const char *f;
+
+ f = strrchr (s->filename, '/');
+ if (f != NULL
+ && strcmp (f + 1, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+ }
+}
+
+/* See if an input file matches a DT_NEEDED entry by running stat on
+ the file. */
+
+static void
+gld${EMULATION_NAME}_stat_needed (s)
+ lang_input_statement_type *s;
+{
+ struct stat st;
+ const char *suffix;
+ const char *soname;
+ const char *f;
+
+ if (global_found)
+ return;
+ if (s->the_bfd == NULL)
+ return;
+
+ if (bfd_stat (s->the_bfd, &st) != 0)
+ {
+ einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
+ return;
+ }
+
+ if (st.st_dev == global_stat.st_dev
+ && st.st_ino == global_stat.st_ino)
+ {
+ global_found = true;
+ return;
+ }
+
+ /* We issue a warning if it looks like we are including two
+ different versions of the same shared library. For example,
+ there may be a problem if -lc picks up libc.so.6 but some other
+ shared library has a DT_NEEDED entry of libc.so.5. This is a
+ hueristic test, and it will only work if the name looks like
+ NAME.so.VERSION. FIXME: Depending on file names is error-prone.
+ If we really want to issue warnings about mixing version numbers
+ of shared libraries, we need to find a better way. */
+
+ if (strchr (global_needed->name, '/') != NULL)
+ return;
+ suffix = strstr (global_needed->name, ".so.");
+ if (suffix == NULL)
+ return;
+ suffix += sizeof ".so." - 1;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname == NULL)
+ soname = s->filename;
+
+ f = strrchr (soname, '/');
+ if (f != NULL)
+ ++f;
+ else
+ f = soname;
+
+ if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
+ einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
+ global_needed->name, global_needed->by, f);
+}
+
+/* On Linux, it's possible to have different versions of the same
+ shared library linked against different versions of libc. The
+ dynamic linker somehow tags which libc version to use in
+ /etc/ld.so.cache, and, based on the libc that it sees in the
+ executable, chooses which version of the shared library to use.
+
+ We try to do a similar check here by checking whether this shared
+ library needs any other shared libraries which may conflict with
+ libraries we have already included in the link. If it does, we
+ skip it, and try to find another shared library farther on down the
+ link path.
+
+ This is called via lang_for_each_input_file.
+ GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
+ which we ar checking. This sets GLOBAL_VERCHECK_FAILED if we find
+ a conflicting version. */
+
+static void
+gld${EMULATION_NAME}_vercheck (s)
+ lang_input_statement_type *s;
+{
+ const char *soname, *f;
+ struct bfd_link_needed_list *l;
+
+ if (global_vercheck_failed)
+ return;
+ if (s->the_bfd == NULL
+ || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
+ return;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname == NULL)
+ soname = bfd_get_filename (s->the_bfd);
+
+ f = strrchr (soname, '/');
+ if (f != NULL)
+ ++f;
+ else
+ f = soname;
+
+ for (l = global_vercheck_needed; l != NULL; l = l->next)
+ {
+ const char *suffix;
+
+ if (strcmp (f, l->name) == 0)
+ {
+ /* Probably can't happen, but it's an easy check. */
+ continue;
+ }
+
+ if (strchr (l->name, '/') != NULL)
+ continue;
+
+ suffix = strstr (l->name, ".so.");
+ if (suffix == NULL)
+ continue;
+
+ suffix += sizeof ".so." - 1;
+
+ if (strncmp (f, l->name, suffix - l->name) == 0)
+ {
+ /* Here we know that S is a dynamic object FOO.SO.VER1, and
+ the object we are considering needs a dynamic object
+ FOO.SO.VER2, and VER1 and VER2 are different. This
+ appears to be a version mismatch, so we tell the caller
+ to try a different version of this library. */
+ global_vercheck_failed = true;
+ return;
+ }
+ }
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ const char *rpath;
+ asection *sinterp;
+
+ /* If we are going to make any variable assignments, we need to let
+ the ELF backend know about them in case the variables are
+ referred to by dynamic objects. */
+ lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
+
+ /* Let the ELF backend work out the sizes of any sections required
+ by dynamic linking. */
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
+ if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
+ (output_bfd, command_line.soname, rpath,
+ command_line.export_dynamic, command_line.filter_shlib,
+ (const char * const *) command_line.auxiliary_filters,
+ &link_info, &sinterp, lang_elf_version_info)))
+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+ /* Let the user override the dynamic linker we are using. */
+ if (command_line.interpreter != NULL
+ && sinterp != NULL)
+ {
+ sinterp->contents = (bfd_byte *) command_line.interpreter;
+ sinterp->_raw_size = strlen (command_line.interpreter) + 1;
+ }
+
+ /* Look for any sections named .gnu.warning. As a GNU extensions,
+ we treat such sections as containing warning messages. We print
+ out the warning message, and then zero out the section size so
+ that it does not get copied into the output file. */
+
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ asection *s;
+ bfd_size_type sz;
+ char *msg;
+ boolean ret;
+
+ if (is->just_syms_flag)
+ continue;
+
+ s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
+ if (s == NULL)
+ continue;
+
+ sz = bfd_section_size (is->the_bfd, s);
+ msg = xmalloc ((size_t) sz + 1);
+ if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
+ einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
+ is->the_bfd);
+ msg[sz] = '\0';
+ ret = link_info.callbacks->warning (&link_info, msg,
+ (const char *) NULL,
+ is->the_bfd, (asection *) NULL,
+ (bfd_vma) 0);
+ ASSERT (ret);
+ free (msg);
+
+ /* Clobber the section size, so that we don't waste copying the
+ warning into the output file. */
+ s->_raw_size = 0;
+ }
+ }
+}
+
+/* This is called by the before_allocation routine via
+ lang_for_each_statement. It locates any assignment statements, and
+ tells the ELF backend about them, in case they are assignments to
+ symbols which are referred to by dynamic objects. */
+
+static void
+gld${EMULATION_NAME}_find_statement_assignment (s)
+ lang_statement_union_type *s;
+{
+ if (s->header.type == lang_assignment_statement_enum)
+ gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
+}
+
+/* Look through an expression for an assignment statement. */
+
+static void
+gld${EMULATION_NAME}_find_exp_assignment (exp)
+ etree_type *exp;
+{
+ struct bfd_link_hash_entry *h;
+
+ switch (exp->type.node_class)
+ {
+ case etree_provide:
+ h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
+ false, false, false);
+ if (h == NULL)
+ break;
+
+ /* We call record_link_assignment even if the symbol is defined.
+ This is because if it is defined by a dynamic object, we
+ actually want to use the value defined by the linker script,
+ not the value from the dynamic object (because we are setting
+ symbols like etext). If the symbol is defined by a regular
+ object, then, as it happens, calling record_link_assignment
+ will do no harm. */
+
+ /* Fall through. */
+ case etree_assign:
+ if (strcmp (exp->assign.dst, ".") != 0)
+ {
+ if (! (bfd_elf${ELFSIZE}_record_link_assignment
+ (output_bfd, &link_info, exp->assign.dst,
+ exp->type.node_class == etree_provide ? true : false)))
+ einfo ("%P%F: failed to record assignment to %s: %E\n",
+ exp->assign.dst);
+ }
+ gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
+ break;
+
+ case etree_binary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
+ break;
+
+ case etree_trinary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
+ break;
+
+ case etree_unary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Place an orphan section. We use this to put random SHF_ALLOC
+ sections in the right segment. */
+
+static asection *hold_section;
+static lang_output_section_statement_type *hold_use;
+static lang_output_section_statement_type *hold_text;
+static lang_output_section_statement_type *hold_rodata;
+static lang_output_section_statement_type *hold_data;
+static lang_output_section_statement_type *hold_bss;
+static lang_output_section_statement_type *hold_rel;
+static lang_output_section_statement_type *hold_interp;
+
+/*ARGSUSED*/
+static boolean
+gld${EMULATION_NAME}_place_orphan (file, s)
+ lang_input_statement_type *file;
+ asection *s;
+{
+ lang_output_section_statement_type *place;
+ asection *snew, **pps;
+ lang_statement_list_type *old;
+ lang_statement_list_type add;
+ etree_type *address;
+ const char *secname, *ps;
+ const char *outsecname;
+ lang_output_section_statement_type *os;
+
+ if ((s->flags & SEC_ALLOC) == 0)
+ return false;
+
+ /* Look through the script to see where to place this section. */
+ hold_section = s;
+ hold_use = NULL;
+ lang_for_each_statement (gld${EMULATION_NAME}_place_section);
+
+ if (hold_use != NULL)
+ {
+ /* We have already placed a section with this name. */
+ wild_doit (&hold_use->children, s, hold_use, file);
+ return true;
+ }
+
+ secname = bfd_get_section_name (s->owner, s);
+
+ /* If this is a final link, then always put .gnu.warning.SYMBOL
+ sections into the .text section to get them out of the way. */
+ if (! link_info.shared
+ && ! link_info.relocateable
+ && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
+ && hold_text != NULL)
+ {
+ wild_doit (&hold_text->children, s, hold_text, file);
+ return true;
+ }
+
+ /* Decide which segment the section should go in based on the
+ section name and section flags. We put loadable .note sections
+ right after the .interp section, so that the PT_NOTE segment is
+ stored right after the program headers where the OS can read it
+ in the first page. */
+ place = NULL;
+ if (s->flags & SEC_EXCLUDE)
+ return false;
+ else if ((s->flags & SEC_LOAD) != 0
+ && strncmp (secname, ".note", 4) == 0
+ && hold_interp != NULL)
+ place = hold_interp;
+ else if ((s->flags & SEC_HAS_CONTENTS) == 0
+ && hold_bss != NULL)
+ place = hold_bss;
+ else if ((s->flags & SEC_READONLY) == 0
+ && hold_data != NULL)
+ place = hold_data;
+ else if (strncmp (secname, ".rel", 4) == 0
+ && hold_rel != NULL)
+ place = hold_rel;
+ else if ((s->flags & SEC_CODE) == 0
+ && (s->flags & SEC_READONLY) != 0
+ && hold_rodata != NULL)
+ place = hold_rodata;
+ else if ((s->flags & SEC_READONLY) != 0
+ && hold_text != NULL)
+ place = hold_text;
+ if (place == NULL)
+ return false;
+
+ /* Choose a unique name for the section. This will be needed if the
+ same section name appears in the input file with different
+ loadable or allocateable characteristics. */
+ outsecname = secname;
+ if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
+ {
+ unsigned int len;
+ char *newname;
+ unsigned int i;
+
+ len = strlen (outsecname);
+ newname = xmalloc (len + 5);
+ strcpy (newname, outsecname);
+ i = 0;
+ do
+ {
+ sprintf (newname + len, "%d", i);
+ ++i;
+ }
+ while (bfd_get_section_by_name (output_bfd, newname) != NULL);
+
+ outsecname = newname;
+ }
+
+ /* Create the section in the output file, and put it in the right
+ place. This shuffling is to make the output file look neater. */
+ snew = bfd_make_section (output_bfd, outsecname);
+ if (snew == NULL)
+ einfo ("%P%F: output format %s cannot represent section called %s\n",
+ output_bfd->xvec->name, outsecname);
+ if (place->bfd_section != NULL)
+ {
+ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+ ;
+ *pps = snew->next;
+ snew->next = place->bfd_section->next;
+ place->bfd_section->next = snew;
+ }
+
+ /* Start building a list of statements for this section. */
+ old = stat_ptr;
+ stat_ptr = &add;
+ lang_list_init (stat_ptr);
+
+ /* If the name of the section is representable in C, then create
+ symbols to mark the start and the end of the section. */
+ for (ps = outsecname; *ps != '\0'; ps++)
+ if (! isalnum ((unsigned char) *ps) && *ps != '_')
+ break;
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+
+ symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
+ sprintf (symname, "__start_%s", outsecname);
+ lang_add_assignment (exp_assop ('=', symname,
+ exp_unop (ALIGN_K,
+ exp_intop ((bfd_vma) 1
+ << s->alignment_power))));
+ }
+
+ if (! link_info.relocateable)
+ address = NULL;
+ else
+ address = exp_intop ((bfd_vma) 0);
+
+ lang_enter_output_section_statement (outsecname, address, 0,
+ (bfd_vma) 0,
+ (etree_type *) NULL,
+ (etree_type *) NULL,
+ (etree_type *) NULL);
+
+ os = lang_output_section_statement_lookup (outsecname);
+ wild_doit (&os->children, s, os, file);
+
+ lang_leave_output_section_statement
+ ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL);
+ stat_ptr = &add;
+
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+
+ symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
+ sprintf (symname, "__stop_%s", outsecname);
+ lang_add_assignment (exp_assop ('=', symname,
+ exp_nameop (NAME, ".")));
+ }
+
+ /* Now stick the new statement list right after PLACE. */
+ *add.tail = place->header.next;
+ place->header.next = add.head;
+
+ stat_ptr = old;
+
+ return true;
+}
+
+static void
+gld${EMULATION_NAME}_place_section (s)
+ lang_statement_union_type *s;
+{
+ lang_output_section_statement_type *os;
+
+ if (s->header.type != lang_output_section_statement_enum)
+ return;
+
+ os = &s->output_section_statement;
+
+ if (strcmp (os->name, hold_section->name) == 0
+ && os->bfd_section != NULL
+ && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
+ == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
+ hold_use = os;
+
+ if (strcmp (os->name, ".text") == 0)
+ hold_text = os;
+ else if (strcmp (os->name, ".rodata") == 0)
+ hold_rodata = os;
+ else if (strcmp (os->name, ".data") == 0)
+ hold_data = os;
+ else if (strcmp (os->name, ".bss") == 0)
+ hold_bss = os;
+ else if (hold_rel == NULL
+ && os->bfd_section != NULL
+ && (os->bfd_section->flags & SEC_ALLOC) != 0
+ && strncmp (os->name, ".rel", 4) == 0)
+ hold_rel = os;
+ else if (strcmp (os->name, ".interp") == 0)
+ hold_interp = os;
+}
+
+static char *
+gld${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+EOF
+
+if test -n "$GENERATE_SHLIB_SCRIPT" ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+ else if (link_info.shared)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`;
+EOF
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else if (link_info.shared)
+ return "ldscripts/${EMULATION_NAME}.xs";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL,
+ NULL,
+ gld${EMULATION_NAME}_open_dynamic_archive,
+ gld${EMULATION_NAME}_place_orphan
+};
+EOF
diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em
new file mode 100644
index 00000000000..1c0c8eb214d
--- /dev/null
+++ b/ld/emultempl/generic.em
@@ -0,0 +1,118 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* emulate the original gld for the given ${EMULATION_NAME}
+ Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_set_output_arch ("`echo ${ARCH}`");
+#endif /* not TARGET_ */
+}
+
+static char *
+gld${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ before_allocation_default,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}"
+};
+EOF
diff --git a/ld/emultempl/gld960.em b/ld/emultempl/gld960.em
new file mode 100644
index 00000000000..df998fb74a8
--- /dev/null
+++ b/ld/emultempl/gld960.em
@@ -0,0 +1,176 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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 1, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * emulate the Intels port of gld
+ */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldmain.h"
+
+#ifdef GNU960
+
+static void
+gld960_before_parse()
+{
+ static char *env_variables[] = { "G960LIB", "G960BASE", 0 };
+ char **p;
+ char *env ;
+
+ for ( p = env_variables; *p; p++ ){
+ env = (char *) getenv(*p);
+ if (env) {
+ ldfile_add_library_path (concat (env,
+ "/lib/libbout",
+ (const char *) NULL),
+ false);
+ }
+ }
+ ldfile_output_architecture = bfd_arch_i960;
+}
+
+#else /* not GNU960 */
+
+static void gld960_before_parse()
+{
+ char *env ;
+ env = getenv("G960LIB");
+ if (env) {
+ ldfile_add_library_path(env, false);
+ }
+ env = getenv("G960BASE");
+ if (env)
+ ldfile_add_library_path (concat (env, "/lib", (const char *) NULL), false);
+ ldfile_output_architecture = bfd_arch_i960;
+}
+
+#endif /* GNU960 */
+
+
+static void
+gld960_set_output_arch()
+{
+ bfd_set_arch_mach(output_bfd, ldfile_output_architecture, bfd_mach_i960_core);
+}
+
+static char *
+gld960_choose_target()
+{
+#ifdef GNU960
+
+ output_filename = "b.out";
+ return bfd_make_targ_name(BFD_BOUT_FORMAT, 0);
+
+#else
+
+ char *from_outside = getenv(TARGET_ENVIRON);
+ output_filename = "b.out";
+
+ if (from_outside != (char *)NULL)
+ return from_outside;
+
+ return "b.out.little";
+
+#endif
+}
+
+static char *
+gld960_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_gld960_emulation =
+{
+ gld960_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ gld960_set_output_arch,
+ gld960_choose_target,
+ before_allocation_default,
+ gld960_get_script,
+ "960",
+ ""
+};
+EOF
diff --git a/ld/emultempl/gld960c.em b/ld/emultempl/gld960c.em
new file mode 100644
index 00000000000..20cb5eda4ef
--- /dev/null
+++ b/ld/emultempl/gld960c.em
@@ -0,0 +1,192 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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 1, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/*
+ * emulate the Intels port of gld
+ */
+
+
+#include <ctype.h>
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldmain.h"
+
+#ifdef GNU960
+
+static void
+gld960_before_parse()
+{
+ static char *env_variables[] = { "G960LIB", "G960BASE", 0 };
+ char **p;
+ char *env ;
+
+ for ( p = env_variables; *p; p++ ){
+ env = (char *) getenv(*p);
+ if (env) {
+ ldfile_add_library_path (concat (env,
+ "/lib/libcoff",
+ (const char *) NULL),
+ false);
+ }
+ }
+ ldfile_output_architecture = bfd_arch_i960;
+}
+
+#else /* not GNU960 */
+
+static void gld960_before_parse()
+{
+ char *env ;
+ env = getenv("G960LIB");
+ if (env) {
+ ldfile_add_library_path(env, false);
+ }
+ env = getenv("G960BASE");
+ if (env)
+ ldfile_add_library_path (concat (env, "/lib", (const char *) NULL),
+ false);
+ ldfile_output_architecture = bfd_arch_i960;
+}
+
+#endif /* GNU960 */
+
+
+static void
+gld960_set_output_arch()
+{
+ if (ldfile_output_machine_name != NULL
+ && *ldfile_output_machine_name != '\0')
+ {
+ char *s, *s1;
+
+ s = concat ("i960:", ldfile_output_machine_name, (char *) NULL);
+ for (s1 = s; *s1 != '\0'; s1++)
+ if (isupper ((unsigned char) *s1))
+ *s1 = tolower ((unsigned char) *s1);
+ ldfile_set_output_arch (s);
+ free (s);
+ }
+
+ set_output_arch_default ();
+}
+
+static char *
+gld960_choose_target()
+{
+#ifdef GNU960
+
+ output_filename = "b.out";
+ return bfd_make_targ_name(BFD_BOUT_FORMAT, 0);
+
+#else
+
+ char *from_outside = getenv(TARGET_ENVIRON);
+ output_filename = "b.out";
+
+ if (from_outside != (char *)NULL)
+ return from_outside;
+
+ return "coff-Intel-little";
+
+#endif
+}
+
+static char *
+gld960_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_gld960coff_emulation =
+{
+ gld960_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ gld960_set_output_arch,
+ gld960_choose_target,
+ before_allocation_default,
+ gld960_get_script,
+ "960coff",
+ ""
+};
+EOF
diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em
new file mode 100644
index 00000000000..c0ca113db46
--- /dev/null
+++ b/ld/emultempl/hppaelf.em
@@ -0,0 +1,283 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* An emulation for HP PA-RISC ELF linkers.
+ Copyright (C) 1991, 93, 94, 95, 1997 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldmisc.h"
+#include "ldmain.h"
+#include "ldctor.h"
+
+/* Section in which we build stubs. */
+static asection *stub_sec;
+static lang_input_statement_type *stub_file;
+
+
+/* FIXME. This doesn't belong here. */
+extern lang_statement_list_type file_chain;
+
+/* Perform some emulation specific initialization. For PA ELF we set
+ up the local label prefix and the output architecture. */
+
+static void
+hppaelf_before_parse ()
+{
+ ldfile_output_architecture = bfd_arch_hppa;
+}
+
+/* Set the output architecture and machine. */
+
+static void
+hppaelf_set_output_arch()
+{
+ unsigned long machine = 0;
+
+ bfd_set_arch_mach (output_bfd, ldfile_output_architecture, machine);
+}
+
+/* This is called before the input files are opened. We create a new
+ fake input file to hold the stub section. */
+
+static void
+hppaelf_create_output_section_statements ()
+{
+ stub_file = lang_add_input_file ("linker stubs",
+ lang_input_file_is_fake_enum,
+ NULL);
+ stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
+ if (stub_file->the_bfd == NULL
+ || ! bfd_set_arch_mach (stub_file->the_bfd,
+ bfd_get_arch (output_bfd),
+ bfd_get_mach (output_bfd)))
+ {
+ einfo ("%X%P: can not create BFD %E\n");
+ return;
+ }
+
+ stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text");
+ /* Don't set SEC_RELOC until we actually have relocations in this
+ section. */
+ if (stub_sec == NULL
+ || ! bfd_set_section_flags (stub_file->the_bfd, stub_sec,
+ (SEC_HAS_CONTENTS
+ | SEC_ALLOC
+ | SEC_LOAD
+ | SEC_CODE
+ | SEC_IN_MEMORY)))
+ {
+ einfo ("%X%P: can not create stub section: %E\n");
+ return;
+ }
+
+ ldlang_add_file (stub_file);
+}
+
+/* Walk all the lang statements splicing out any padding statements from
+ the list. */
+
+static void
+hppaelf_delete_padding_statements (s, prev)
+ lang_statement_union_type *s;
+ lang_statement_union_type **prev;
+{
+ lang_statement_union_type *sprev = NULL;
+ for (; s != NULL; s = s->next)
+ {
+ switch (s->header.type)
+ {
+
+ /* We want recursively walk these sections. */
+ case lang_constructors_statement_enum:
+ hppaelf_delete_padding_statements (constructor_list.head,
+ &constructor_list.head);
+ break;
+
+ case lang_output_section_statement_enum:
+ hppaelf_delete_padding_statements (s->output_section_statement.
+ children.head,
+ &s->output_section_statement.
+ children.head);
+ break;
+
+ /* Huh? What is a lang_wild_statement? */
+ case lang_wild_statement_enum:
+ hppaelf_delete_padding_statements (s->wild_statement.
+ children.head,
+ &s->wild_statement.
+ children.head);
+ break;
+
+ /* Here's what we are really looking for. Splice these out of
+ the list. */
+ case lang_padding_statement_enum:
+ if (sprev)
+ sprev->header.next = s->header.next;
+ else
+ **prev = *s;
+ break;
+
+ /* We don't care about these cases. */
+ case lang_data_statement_enum:
+ case lang_object_symbols_statement_enum:
+ case lang_output_statement_enum:
+ case lang_target_statement_enum:
+ case lang_input_section_enum:
+ case lang_input_statement_enum:
+ case lang_assignment_statement_enum:
+ case lang_address_statement_enum:
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+ sprev = s;
+ }
+}
+
+/* Final emulation specific call. For the PA we use this opportunity
+ to build linker stubs. */
+
+static void
+hppaelf_finish ()
+{
+ /* Call into the BFD backend to do the real work. */
+ if (elf32_hppa_size_stubs (stub_file->the_bfd, output_bfd, &link_info)
+ == false)
+ {
+ einfo ("%X%P: can not size stub section: %E\n");
+ return;
+ }
+
+ /* If the size of the stub section is nonzero, then we need
+ to resize the sections, recompute the assignments, and finally
+ build the stubs. */
+ if (bfd_section_size (stub_file->the_bfd, stub_file->the_bfd->sections) != 0)
+ {
+ /* Delete all the padding statements, they're no longer valid. */
+ hppaelf_delete_padding_statements (stat_ptr->head, &stat_ptr->head);
+
+ /* Resize the sections. */
+ lang_size_sections (stat_ptr->head, abs_output_section,
+ &stat_ptr->head, 0, (bfd_vma) 0, false);
+
+ /* Redo special stuff. */
+ ldemul_after_allocation ();
+
+ /* Do the assignments again. */
+ lang_do_assignments (stat_ptr->head,
+ abs_output_section,
+ (fill_type) 0, (bfd_vma) 0);
+
+ /* Now build the linker stubs. */
+ if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false)
+ {
+ einfo ("%X%P: can not build stubs: %E\n");
+ return;
+ }
+ }
+}
+
+/* The script itself gets inserted here. */
+
+static char *
+hppaelf_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_hppaelf_emulation =
+{
+ hppaelf_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ hppaelf_set_output_arch,
+ ldemul_default_target,
+ before_allocation_default,
+ hppaelf_get_script,
+ "hppaelf",
+ "elf32-hppa",
+ hppaelf_finish,
+ hppaelf_create_output_section_statements,
+};
+EOF
diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em
new file mode 100644
index 00000000000..dc0855dd8e9
--- /dev/null
+++ b/ld/emultempl/linux.em
@@ -0,0 +1,208 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* Linux a.out emulation code for ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+ Linux support by Eric Youngdale <ericy@cais.cais.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static boolean gld${EMULATION_NAME}_open_dynamic_archive
+ PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
+static void gld${EMULATION_NAME}_find_address_statement
+ PARAMS ((lang_statement_union_type *));
+static void gld${EMULATION_NAME}_create_output_section_statements
+ PARAMS ((void));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+ ldfile_output_architecture = bfd_arch_${ARCH};
+ config.dynamic_link = true;
+ config.has_shared = true;
+}
+
+/* Try to open a dynamic archive. This is where we know that Linux
+ dynamic libraries have an extension of .sa. */
+
+static boolean
+gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
+ const char *arch;
+ search_dirs_type *search;
+ lang_input_statement_type *entry;
+{
+ char *string;
+
+ if (! entry->is_archive)
+ return false;
+
+ string = (char *) xmalloc (strlen (search->name)
+ + strlen (entry->filename)
+ + strlen (arch)
+ + sizeof "/lib.sa");
+
+ sprintf (string, "%s/lib%s%s.sa", search->name, entry->filename, arch);
+
+ if (! ldfile_try_open_bfd (string, entry))
+ {
+ free (string);
+ return false;
+ }
+
+ entry->filename = string;
+
+ return true;
+}
+
+/* This is called by the create_output_section_statements routine via
+ lang_for_each_statement. It locates any address assignment to
+ .text, and modifies it to include the size of the headers. This
+ causes -Ttext to mean the starting address of the header, rather
+ than the starting address of .text, which is compatible with other
+ Linux tools. */
+
+static void
+gld${EMULATION_NAME}_find_address_statement (s)
+ lang_statement_union_type *s;
+{
+ if (s->header.type == lang_address_statement_enum
+ && strcmp (s->address_statement.section_name, ".text") == 0)
+ {
+ ASSERT (s->address_statement.address->type.node_class == etree_value);
+ s->address_statement.address->value.value += 0x20;
+ }
+}
+
+/* This is called before opening the input BFD's. */
+
+static void
+gld${EMULATION_NAME}_create_output_section_statements ()
+{
+ lang_for_each_statement (gld${EMULATION_NAME}_find_address_statement);
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ if (link_info.relocateable)
+ return;
+
+ /* Let the backend work out the sizes of any sections required by
+ dynamic linking. */
+ if (! bfd_${EMULATION_NAME}_size_dynamic_sections (output_bfd, &link_info))
+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+}
+
+static char *
+gld${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL,
+ gld${EMULATION_NAME}_create_output_section_statements,
+ gld${EMULATION_NAME}_open_dynamic_archive
+};
+EOF
diff --git a/ld/emultempl/lnk960.em b/ld/emultempl/lnk960.em
new file mode 100644
index 00000000000..066d46bb328
--- /dev/null
+++ b/ld/emultempl/lnk960.em
@@ -0,0 +1,327 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* intel coff loader emulation specific stuff
+ Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "libiberty.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+/*#include "archures.h"*/
+#include "ld.h"
+#include "ldemul.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldfile.h"
+#include "ldmain.h"
+
+typedef struct lib_list {
+ char *name;
+ struct lib_list *next;
+} lib_list_type;
+
+static lib_list_type *hll_list;
+static lib_list_type **hll_list_tail = &hll_list;
+
+static lib_list_type *syslib_list;
+static lib_list_type **syslib_list_tail = &syslib_list;
+
+
+static void
+append(list, name)
+ lib_list_type ***list;
+ char *name;
+{
+ lib_list_type *element =
+ (lib_list_type *)(xmalloc(sizeof(lib_list_type)));
+
+ element->name = name;
+ element->next = (lib_list_type *)NULL;
+ **list = element;
+ *list = &element->next;
+
+}
+
+static boolean had_hll = false;
+static boolean had_hll_name = false;
+
+static void
+lnk960_hll(name)
+ char *name;
+{
+ had_hll = true;
+ if (name != (char *)NULL) {
+ had_hll_name = true;
+ append(&hll_list_tail, name);
+ }
+}
+
+static void
+lnk960_syslib(name)
+ char *name;
+{
+ append(&syslib_list_tail,name);
+}
+
+
+#ifdef GNU960
+
+static void
+lnk960_before_parse()
+{
+ static char *env_variables[] = { "G960LIB", "G960BASE", 0 };
+ char **p;
+ char *env ;
+
+ for ( p = env_variables; *p; p++ ){
+ env = (char *) getenv(*p);
+ if (env) {
+ ldfile_add_library_path(concat(env,"/lib/libcoff",""), false);
+ }
+ }
+
+ env= (char *) getenv("I960BASE");
+ if ( env ) {
+ ldfile_add_library_path(concat(env,"/lib",""), false);
+ }
+
+ ldfile_output_architecture = bfd_arch_i960;
+ ldfile_output_machine = bfd_mach_i960_core;
+}
+
+#else /* not GNU960 */
+
+static void
+lnk960_before_parse()
+{
+ char *name = getenv("I960BASE");
+
+ if (name == (char *)NULL) {
+ name = getenv("G960BASE");
+ if (name == (char *)NULL) {
+ einfo("%P%F I960BASE and G960BASE not set\n");
+ }
+ }
+
+
+ ldfile_add_library_path(concat(name,"/lib",""), false);
+ ldfile_output_architecture = bfd_arch_i960;
+ ldfile_output_machine = bfd_mach_i960_core;
+}
+
+#endif /* GNU960 */
+
+
+static void
+add_on(list, search)
+ lib_list_type *list;
+ lang_input_file_enum_type search;
+{
+ while (list) {
+ lang_add_input_file(list->name,
+ search,
+ (char *)NULL);
+ list = list->next;
+ }
+}
+static void
+lnk960_after_parse()
+{
+ /* If there has been no arch, default to -KB */
+ if (ldfile_output_machine_name[0] ==0) {
+ ldfile_add_arch("KB");
+ }
+
+ /* if there has been no hll list then add our own */
+
+ if(had_hll && !had_hll_name) {
+ append(&hll_list_tail,"cg");
+ if (ldfile_output_machine == bfd_mach_i960_ka_sa ||
+ ldfile_output_machine == bfd_mach_i960_ca) {
+ {
+ append(&hll_list_tail,"fpg");
+ }
+ }
+ }
+
+ add_on(hll_list, lang_input_file_is_l_enum);
+ add_on(syslib_list, lang_input_file_is_search_file_enum);
+}
+
+static void
+lnk960_before_allocation()
+{
+}
+
+static void
+lnk960_after_allocation()
+{
+ if (link_info.relocateable == false) {
+ lang_abs_symbol_at_end_of(".text","_etext");
+ lang_abs_symbol_at_end_of(".data","_edata");
+ lang_abs_symbol_at_beginning_of(".bss","_bss_start");
+ lang_abs_symbol_at_end_of(".bss","_end");
+ }
+}
+
+
+static struct
+ {
+ unsigned long number;
+ char *name;
+ }
+machine_table[] =
+{
+ { bfd_mach_i960_core ,"CORE" },
+ { bfd_mach_i960_kb_sb ,"KB" },
+ { bfd_mach_i960_kb_sb ,"SB" },
+ { bfd_mach_i960_mc ,"MC" },
+ { bfd_mach_i960_xa ,"XA" },
+ { bfd_mach_i960_ca ,"CA" },
+ { bfd_mach_i960_ka_sa ,"KA" },
+ { bfd_mach_i960_ka_sa ,"SA" },
+ { bfd_mach_i960_jx ,"JX" },
+ { bfd_mach_i960_hx ,"HX" },
+
+ { bfd_mach_i960_core ,"core" },
+ { bfd_mach_i960_kb_sb ,"kb" },
+ { bfd_mach_i960_kb_sb ,"sb" },
+ { bfd_mach_i960_mc ,"mc" },
+ { bfd_mach_i960_xa ,"xa" },
+ { bfd_mach_i960_ca ,"ca" },
+ { bfd_mach_i960_ka_sa ,"ka" },
+ { bfd_mach_i960_ka_sa ,"sa" },
+ { bfd_mach_i960_jx ,"jx" },
+ { bfd_mach_i960_hx ,"hx" },
+
+ { 0, (char *) NULL }
+};
+
+static void
+lnk960_set_output_arch()
+{
+ /* Set the output architecture and machine if possible */
+ unsigned int i;
+ ldfile_output_machine = bfd_mach_i960_core;
+ for (i= 0; machine_table[i].name != (char*)NULL; i++) {
+ if (strcmp(ldfile_output_machine_name,machine_table[i].name)==0) {
+ ldfile_output_machine = machine_table[i].number;
+ break;
+ }
+ }
+ bfd_set_arch_mach(output_bfd, ldfile_output_architecture, ldfile_output_machine);
+}
+
+static char *
+lnk960_choose_target()
+{
+#ifdef GNU960
+
+ return bfd_make_targ_name(BFD_COFF_FORMAT, 0);
+
+#else
+
+ char *from_outside = getenv(TARGET_ENVIRON);
+ if (from_outside != (char *)NULL)
+ return from_outside;
+#ifdef LNK960_LITTLE
+ return "coff-Intel-little";
+#else
+ return "coff-Intel-big";
+#endif
+#endif
+
+}
+
+static char *
+lnk960_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_lnk960_emulation =
+{
+ lnk960_before_parse,
+ lnk960_syslib,
+ lnk960_hll,
+ lnk960_after_parse,
+ NULL, /* after_open */
+ lnk960_after_allocation,
+ lnk960_set_output_arch,
+ lnk960_choose_target,
+ lnk960_before_allocation,
+ lnk960_get_script,
+ "lnk960",
+ ""
+};
+EOF
diff --git a/ld/emultempl/mipsecoff.em b/ld/emultempl/mipsecoff.em
new file mode 100644
index 00000000000..d1200c46d70
--- /dev/null
+++ b/ld/emultempl/mipsecoff.em
@@ -0,0 +1,229 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* Handle embedded relocs for MIPS.
+ Copyright 1994 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com> based on generic.em.
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld${EMULATION_NAME}_after_open PARAMS ((void));
+static void check_sections PARAMS ((bfd *, asection *, PTR));
+static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_output_architecture = bfd_arch_${ARCH};
+#endif /* not TARGET_ */
+}
+
+/* This function is run after all the input files have been opened.
+ We create a .rel.sdata section for each input file with a non zero
+ .sdata section. The BFD backend will fill in these sections with
+ magic numbers which can be used to relocate the data section at run
+ time. This will only do the right thing if all the input files
+ have been compiled using -membedded-pic. */
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+ bfd *abfd;
+
+ if (! command_line.embedded_relocs
+ || link_info.relocateable)
+ return;
+
+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+ {
+ asection *datasec;
+
+ datasec = bfd_get_section_by_name (abfd, ".sdata");
+
+ /* Note that we assume that the reloc_count field has already
+ been set up. We could call bfd_get_reloc_upper_bound, but
+ that returns the size of a memory buffer rather than a reloc
+ count. We do not want to call bfd_canonicalize_reloc,
+ because although it would always work it would force us to
+ read in the relocs into BFD canonical form, which would waste
+ a significant amount of time and memory. */
+ if (datasec != NULL && datasec->reloc_count > 0)
+ {
+ asection *relsec;
+
+ relsec = bfd_make_section (abfd, ".rel.sdata");
+ if (relsec == NULL
+ || ! bfd_set_section_flags (abfd, relsec,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY))
+ || ! bfd_set_section_alignment (abfd, relsec, 2)
+ || ! bfd_set_section_size (abfd, relsec,
+ datasec->reloc_count * 4))
+ einfo ("%F%B: can not create .rel.sdata section: %E\n");
+ }
+
+ /* Double check that all other data sections are empty, as is
+ required for embedded PIC code. */
+ bfd_map_over_sections (abfd, check_sections, (PTR) datasec);
+ }
+}
+
+/* Check that of the data sections, only the .sdata section has
+ relocs. This is called via bfd_map_over_sections. */
+
+static void
+check_sections (abfd, sec, sdatasec)
+ bfd *abfd;
+ asection *sec;
+ PTR sdatasec;
+{
+ if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0
+ && sec != (asection *) sdatasec
+ && sec->reloc_count != 0)
+ einfo ("%P%X: section %s has relocs; can not use --embedded-relocs\n",
+ abfd, bfd_get_section_name (abfd, sec));
+}
+
+/* This function is called after the section sizes and offsets have
+ been set. If we are generating embedded relocs, it calls a special
+ BFD backend routine to do the work. */
+
+static void
+gld${EMULATION_NAME}_after_allocation ()
+{
+ bfd *abfd;
+
+ if (! command_line.embedded_relocs
+ || link_info.relocateable)
+ return;
+
+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+ {
+ asection *datasec, *relsec;
+ char *errmsg;
+
+ datasec = bfd_get_section_by_name (abfd, ".sdata");
+
+ if (datasec == NULL || datasec->reloc_count == 0)
+ continue;
+
+ relsec = bfd_get_section_by_name (abfd, ".rel.sdata");
+ ASSERT (relsec != NULL);
+
+ if (! bfd_mips_ecoff_create_embedded_relocs (abfd, &link_info,
+ datasec, relsec,
+ &errmsg))
+ {
+ if (errmsg == NULL)
+ einfo ("%B%X: can not create runtime reloc information: %E\n",
+ abfd);
+ else
+ einfo ("%X%B: can not create runtime reloc information: %s\n",
+ abfd, errmsg);
+ }
+ }
+}
+
+static char *
+gld${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ gld${EMULATION_NAME}_after_allocation,
+ set_output_arch_default,
+ ldemul_default_target,
+ before_allocation_default,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}"
+};
+EOF
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
new file mode 100644
index 00000000000..46ebbe99865
--- /dev/null
+++ b/ld/emultempl/pe.em
@@ -0,0 +1,1104 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is part of GLD, the Gnu Linker.
+ Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* For WINDOWS_NT */
+/* The original file generated returned different default scripts depending
+ on whether certain switches were set, but these switches pertain to the
+ Linux system and that particular version of coff. In the NT case, we
+ only determine if the subsystem is console or windows in order to select
+ the correct entry point by default. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "getopt.h"
+#include "libiberty.h"
+#include "ld.h"
+#include "ldmain.h"
+#include "ldgram.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldemul.h"
+#include "ldlex.h"
+#include "ldmisc.h"
+#include "ldctor.h"
+#include "ldfile.h"
+#include "coff/internal.h"
+#include "../bfd/libcoff.h"
+#include "deffile.h"
+
+#define TARGET_IS_${EMULATION_NAME}
+
+static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
+static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
+static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld_${EMULATION_NAME}_after_parse PARAMS ((void));
+static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
+static boolean gld_${EMULATION_NAME}_place_orphan
+ PARAMS ((lang_input_statement_type *, asection *));
+static void gld${EMULATION_NAME}_place_section
+ PARAMS ((lang_statement_union_type *));
+static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
+static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
+
+static struct internal_extra_pe_aouthdr pe;
+static int dll;
+static int support_old_code = 0;
+extern def_file *pe_def_file;
+static lang_assignment_statement_type *image_base_statement = 0;
+
+static char *pe_out_def_filename = 0;
+extern int pe_dll_export_everything;
+extern int pe_dll_kill_ats;
+extern int pe_dll_stdcall_aliases;
+static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */
+static char *pe_implib_filename = 0;
+
+extern const char *output_filename;
+
+static void
+gld_${EMULATION_NAME}_before_parse()
+{
+ output_filename = "a.exe";
+ ldfile_output_architecture = bfd_arch_${ARCH};
+#ifdef TARGET_IS_i386pe
+ config.has_shared = 1;
+#endif
+}
+
+/* PE format extra command line options. */
+
+/* Used for setting flags in the PE header. */
+#define OPTION_BASE_FILE (300 + 1)
+#define OPTION_DLL (OPTION_BASE_FILE + 1)
+#define OPTION_FILE_ALIGNMENT (OPTION_DLL + 1)
+#define OPTION_IMAGE_BASE (OPTION_FILE_ALIGNMENT + 1)
+#define OPTION_MAJOR_IMAGE_VERSION (OPTION_IMAGE_BASE + 1)
+#define OPTION_MAJOR_OS_VERSION (OPTION_MAJOR_IMAGE_VERSION + 1)
+#define OPTION_MAJOR_SUBSYSTEM_VERSION (OPTION_MAJOR_OS_VERSION + 1)
+#define OPTION_MINOR_IMAGE_VERSION (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
+#define OPTION_MINOR_OS_VERSION (OPTION_MINOR_IMAGE_VERSION + 1)
+#define OPTION_MINOR_SUBSYSTEM_VERSION (OPTION_MINOR_OS_VERSION + 1)
+#define OPTION_SECTION_ALIGNMENT (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
+#define OPTION_STACK (OPTION_SECTION_ALIGNMENT + 1)
+#define OPTION_SUBSYSTEM (OPTION_STACK + 1)
+#define OPTION_HEAP (OPTION_SUBSYSTEM + 1)
+#define OPTION_SUPPORT_OLD_CODE (OPTION_HEAP + 1)
+#define OPTION_OUT_DEF (OPTION_SUPPORT_OLD_CODE + 1)
+#define OPTION_EXPORT_ALL (OPTION_OUT_DEF + 1)
+#define OPTION_EXCLUDE_SYMBOLS (OPTION_EXPORT_ALL + 1)
+#define OPTION_KILL_ATS (OPTION_EXCLUDE_SYMBOLS + 1)
+#define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1)
+#define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1)
+#define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1)
+#define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_STDCALL_FIXUP + 1)
+
+static struct option longopts[] =
+{
+ /* PE options */
+ {"base-file", required_argument, NULL, OPTION_BASE_FILE},
+ {"dll", no_argument, NULL, OPTION_DLL},
+ {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
+ {"heap", required_argument, NULL, OPTION_HEAP},
+ {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
+ {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
+ {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
+ {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
+ {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
+ {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
+ {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
+ {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
+ {"stack", required_argument, NULL, OPTION_STACK},
+ {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
+ {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
+#ifdef TARGET_IS_i386pe
+ /* getopt allows abbreviations, so we do this to stop it from treating -o
+ as an abbreviation for this option */
+ {"output-def", required_argument, NULL, OPTION_OUT_DEF},
+ {"output-def", required_argument, NULL, OPTION_OUT_DEF},
+ {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL},
+ {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
+ {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
+ {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
+ {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
+ {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
+ {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME},
+#endif
+ {NULL, no_argument, NULL, 0}
+};
+
+
+/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
+ parameters which may be input from the command line */
+
+typedef struct
+{
+ void *ptr;
+ int size;
+ int value;
+ char *symbol;
+ int inited;
+} definfo;
+
+#define D(field,symbol,def) {&pe.field,sizeof(pe.field), def, symbol,0}
+
+static definfo init[] =
+{
+ /* imagebase must be first */
+#define IMAGEBASEOFF 0
+ D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
+#define DLLOFF 1
+ {&dll, sizeof(dll), 0, "__dll__"},
+ D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
+ D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
+ D(MajorOperatingSystemVersion,"__major_os_version__", 4),
+ D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
+ D(MajorImageVersion,"__major_image_version__", 1),
+ D(MinorImageVersion,"__minor_image_version__", 0),
+ D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
+ D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
+ D(Subsystem,"__subsystem__", 3),
+ D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
+ D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
+ D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
+ D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
+ D(LoaderFlags,"__loader_flags__", 0x0),
+ { NULL, 0, 0, NULL, 0 }
+};
+
+static void
+gld_${EMULATION_NAME}_list_options (file)
+ FILE * file;
+{
+ fprintf (file, _(" --base_file <basefile> Generate a base file for relocatable DLLs\n"));
+ fprintf (file, _(" --dll Set image base to the default for DLLs\n"));
+ fprintf (file, _(" --file-alignment <size> Set file alignment\n"));
+ fprintf (file, _(" --heap <size> Set initial size of the heap\n"));
+ fprintf (file, _(" --image-base <address> Set start address of the executable\n"));
+ fprintf (file, _(" --major-image-version <number> Set version number of the executable\n"));
+ fprintf (file, _(" --major-os-version <number> Set minimum required OS version\n"));
+ fprintf (file, _(" --major-subsystem-version <number> Set minimum required OS subsystem version\n"));
+ fprintf (file, _(" --minor-image-version <number> Set revision number of the executable\n"));
+ fprintf (file, _(" --minor-os-version <number> Set minimum required OS revision\n"));
+ fprintf (file, _(" --minor-subsystem-version <number> Set minimum required OS subsystem revision\n"));
+ fprintf (file, _(" --section-alignment <size> Set section alignment\n"));
+ fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
+ fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
+ fprintf (file, _(" --support-old-code Support interworking with old code\n"));
+#ifdef TARGET_IS_i386pe
+ fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n"));
+ fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
+ fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"));
+ fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"));
+ fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n"));
+ fprintf (file, _(" --kill-at Remove @nn from exported symbols\n"));
+ fprintf (file, _(" --out-implib <file> Generate import library\n"));
+ fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n"));
+#endif
+}
+
+static void
+set_pe_name (name, val)
+ char *name;
+ long val;
+{
+ int i;
+ /* Find the name and set it. */
+ for (i = 0; init[i].ptr; i++)
+ {
+ if (strcmp (name, init[i].symbol) == 0)
+ {
+ init[i].value = val;
+ init[i].inited = 1;
+ return;
+ }
+ }
+ abort();
+}
+
+
+static void
+set_pe_subsystem ()
+{
+ const char *sver;
+ int len;
+ int i;
+ static const struct
+ {
+ const char *name;
+ const int value;
+ const char *entry;
+ }
+ v[] =
+ {
+ { "native", 1, "_NtProcessStartup" },
+ { "windows", 2, "_WinMainCRTStartup" },
+ { "console", 3, "_mainCRTStartup" },
+#if 0
+ /* The Microsoft linker does not recognize this. */
+ { "os2", 5, "" },
+#endif
+ { "posix", 7, "___PosixProcessStartup"},
+ { 0, 0, 0 }
+ };
+
+ sver = strchr (optarg, ':');
+ if (sver == NULL)
+ len = strlen (optarg);
+ else
+ {
+ char *end;
+
+ len = sver - optarg;
+ set_pe_name ("__major_subsystem_version__",
+ strtoul (sver + 1, &end, 0));
+ if (*end == '.')
+ set_pe_name ("__minor_subsystem_version__",
+ strtoul (end + 1, &end, 0));
+ if (*end != '\0')
+ einfo (_("%P: warning: bad version number in -subsystem option\n"));
+ }
+
+ for (i = 0; v[i].name; i++)
+ {
+ if (strncmp (optarg, v[i].name, len) == 0
+ && v[i].name[len] == '\0')
+ {
+ set_pe_name ("__subsystem__", v[i].value);
+
+ lang_add_entry (v[i].entry, 1);
+
+ return;
+ }
+ }
+
+ einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
+}
+
+
+
+static void
+set_pe_value (name)
+ char *name;
+
+{
+ char *end;
+
+ set_pe_name (name, strtoul (optarg, &end, 0));
+
+ if (end == optarg)
+ einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
+
+ optarg = end;
+}
+
+static void
+set_pe_stack_heap (resname, comname)
+ char *resname;
+ char *comname;
+{
+ set_pe_value (resname);
+
+ if (*optarg == ',')
+ {
+ optarg++;
+ set_pe_value (comname);
+ }
+ else if (*optarg)
+ einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
+}
+
+
+
+static int
+gld_${EMULATION_NAME}_parse_args(argc, argv)
+ int argc;
+ char **argv;
+{
+ int longind;
+ int optc;
+ int prevoptind = optind;
+ int prevopterr = opterr;
+ int wanterror;
+ static int lastoptind = -1;
+
+ if (lastoptind != optind)
+ opterr = 0;
+ wanterror = opterr;
+
+ lastoptind = optind;
+
+ optc = getopt_long_only (argc, argv, "-", longopts, &longind);
+ opterr = prevopterr;
+
+ switch (optc)
+ {
+ default:
+ if (wanterror)
+ xexit (1);
+ optind = prevoptind;
+ return 0;
+
+ case OPTION_BASE_FILE:
+ link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
+ if (link_info.base_file == NULL)
+ {
+ /* xgettext:c-format */
+ fprintf (stderr, _("%s: Can't open base file %s\n"),
+ program_name, optarg);
+ xexit (1);
+ }
+ break;
+
+ /* PE options */
+ case OPTION_HEAP:
+ set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
+ break;
+ case OPTION_STACK:
+ set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
+ break;
+ case OPTION_SUBSYSTEM:
+ set_pe_subsystem ();
+ break;
+ case OPTION_MAJOR_OS_VERSION:
+ set_pe_value ("__major_os_version__");
+ break;
+ case OPTION_MINOR_OS_VERSION:
+ set_pe_value ("__minor_os_version__");
+ break;
+ case OPTION_MAJOR_SUBSYSTEM_VERSION:
+ set_pe_value ("__major_subsystem_version__");
+ break;
+ case OPTION_MINOR_SUBSYSTEM_VERSION:
+ set_pe_value ("__minor_subsystem_version__");
+ break;
+ case OPTION_MAJOR_IMAGE_VERSION:
+ set_pe_value ("__major_image_version__");
+ break;
+ case OPTION_MINOR_IMAGE_VERSION:
+ set_pe_value ("__minor_image_version__");
+ break;
+ case OPTION_FILE_ALIGNMENT:
+ set_pe_value ("__file_alignment__");
+ break;
+ case OPTION_SECTION_ALIGNMENT:
+ set_pe_value ("__section_alignment__");
+ break;
+ case OPTION_DLL:
+ set_pe_name ("__dll__", 1);
+ break;
+ case OPTION_IMAGE_BASE:
+ set_pe_value ("__image_base__");
+ break;
+ case OPTION_SUPPORT_OLD_CODE:
+ support_old_code = 1;
+ break;
+ case OPTION_OUT_DEF:
+ pe_out_def_filename = xstrdup (optarg);
+ break;
+ case OPTION_EXPORT_ALL:
+ pe_dll_export_everything = 1;
+ break;
+ case OPTION_EXCLUDE_SYMBOLS:
+#ifdef TARGET_IS_i386pe
+ pe_dll_add_excludes (optarg);
+#endif
+ break;
+ case OPTION_KILL_ATS:
+ pe_dll_kill_ats = 1;
+ break;
+ case OPTION_STDCALL_ALIASES:
+ pe_dll_stdcall_aliases = 1;
+ break;
+ case OPTION_ENABLE_STDCALL_FIXUP:
+ pe_enable_stdcall_fixup = 1;
+ break;
+ case OPTION_DISABLE_STDCALL_FIXUP:
+ pe_enable_stdcall_fixup = 0;
+ break;
+ case OPTION_IMPLIB_FILENAME:
+ pe_implib_filename = xstrdup (optarg);
+ break;
+ }
+ return 1;
+}
+
+/* Assign values to the special symbols before the linker script is
+ read. */
+
+static void
+gld_${EMULATION_NAME}_set_symbols ()
+{
+ /* Run through and invent symbols for all the
+ names and insert the defaults. */
+ int j;
+ lang_statement_list_type *save;
+
+ if (!init[IMAGEBASEOFF].inited)
+ {
+ if (link_info.relocateable)
+ init[IMAGEBASEOFF].value = 0;
+ else if (init[DLLOFF].value || link_info.shared)
+ init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
+ else
+ init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
+ }
+
+ /* Don't do any symbol assignments if this is a relocateable link. */
+ if (link_info.relocateable)
+ return;
+
+ /* Glue the assignments into the abs section */
+ save = stat_ptr;
+
+ stat_ptr = &(abs_output_section->children);
+
+ for (j = 0; init[j].ptr; j++)
+ {
+ long val = init[j].value;
+ lang_assignment_statement_type *rv;
+ rv = lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
+ if (init[j].size == sizeof(short))
+ *(short *)init[j].ptr = val;
+ else if (init[j].size == sizeof(int))
+ *(int *)init[j].ptr = val;
+ else if (init[j].size == sizeof(long))
+ *(long *)init[j].ptr = val;
+ /* This might be a long long or other special type. */
+ else if (init[j].size == sizeof(bfd_vma))
+ *(bfd_vma *)init[j].ptr = val;
+ else abort();
+ if (j == IMAGEBASEOFF)
+ image_base_statement = rv;
+ }
+ /* Restore the pointer. */
+ stat_ptr = save;
+
+ if (pe.FileAlignment >
+ pe.SectionAlignment)
+ {
+ einfo (_("%P: warning, file alignment > section alignment.\n"));
+ }
+}
+
+/* This is called after the linker script and the command line options
+ have been read. */
+
+static void
+gld_${EMULATION_NAME}_after_parse ()
+{
+ /* The Windows libraries are designed for the linker to treat the
+ entry point as an undefined symbol. Otherwise, the .obj that
+ defines mainCRTStartup is brought in because it is the first
+ encountered in libc.lib and it has other symbols in it which will
+ be pulled in by the link process. To avoid this, we act as
+ though the user specified -u with the entry point symbol.
+
+ This function is called after the linker script and command line
+ options have been read, so at this point we know the right entry
+ point. This function is called before the input files are
+ opened, so registering the symbol as undefined will make a
+ difference. */
+
+ if (entry_symbol)
+ ldlang_add_undef (entry_symbol);
+}
+
+static struct bfd_link_hash_entry *pe_undef_found_sym;
+
+static boolean
+pe_undef_cdecl_match (h, string)
+ struct bfd_link_hash_entry *h;
+ PTR string;
+{
+ int sl = strlen (string);
+ if (h->type == bfd_link_hash_defined
+ && strncmp (h->root.string, string, sl) == 0
+ && h->root.string[sl] == '@')
+ {
+ pe_undef_found_sym = h;
+ return false;
+ }
+ return true;
+}
+
+static void
+pe_fixup_stdcalls ()
+{
+ static int gave_warning_message = 0;
+ struct bfd_link_hash_entry *undef, *sym;
+ char *at;
+ for (undef = link_info.hash->undefs; undef; undef=undef->next)
+ if (undef->type == bfd_link_hash_undefined)
+ {
+ at = strchr (undef->root.string, '@');
+ if (at)
+ {
+ /* The symbol is a stdcall symbol, so let's look for a cdecl
+ symbol with the same name and resolve to that */
+ char *cname = xstrdup (undef->root.string);
+ at = strchr (cname, '@');
+ *at = 0;
+ sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1);
+ if (sym && sym->type == bfd_link_hash_defined)
+ {
+ undef->type = bfd_link_hash_defined;
+ undef->u.def.value = sym->u.def.value;
+ undef->u.def.section = sym->u.def.section;
+ if (pe_enable_stdcall_fixup == -1)
+ {
+ einfo (_("Warning: resolving %s by linking to %s\n"),
+ undef->root.string, cname);
+ if (! gave_warning_message)
+ {
+ gave_warning_message = 1;
+ einfo(_("Use --enable-stdcall-fixup to disable these warnings\n"));
+ einfo(_("Use --disable-stdcall-fixup to disable these fixups\n"));
+ }
+ }
+ }
+ }
+ else
+ {
+ /* The symbol is a cdecl symbol, so we look for stdcall
+ symbols - which means scanning the whole symbol table */
+ pe_undef_found_sym = 0;
+ bfd_link_hash_traverse (link_info.hash, pe_undef_cdecl_match,
+ (PTR) undef->root.string);
+ sym = pe_undef_found_sym;
+ if (sym)
+ {
+ undef->type = bfd_link_hash_defined;
+ undef->u.def.value = sym->u.def.value;
+ undef->u.def.section = sym->u.def.section;
+ if (pe_enable_stdcall_fixup == -1)
+ {
+ einfo (_("Warning: resolving %s by linking to %s\n"),
+ undef->root.string, sym->root.string);
+ if (! gave_warning_message)
+ {
+ gave_warning_message = 1;
+ einfo(_("Use --enable-stdcall-fixup to disable these warnings\n"));
+ einfo(_("Use --disable-stdcall-fixup to disable these fixups\n"));
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+gld_${EMULATION_NAME}_after_open ()
+{
+ /* Pass the wacky PE command line options into the output bfd.
+ FIXME: This should be done via a function, rather than by
+ including an internal BFD header. */
+
+ if (!coff_data (output_bfd)->pe)
+ einfo (_("%F%P: PE operations on non PE file.\n"));
+
+ pe_data (output_bfd)->pe_opthdr = pe;
+ pe_data (output_bfd)->dll = init[DLLOFF].value;
+
+#ifdef TARGET_IS_i386pe
+ if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */
+ pe_fixup_stdcalls ();
+
+ pe_process_import_defs(output_bfd, &link_info);
+ if (link_info.shared)
+ pe_dll_build_sections (output_bfd, &link_info);
+#endif
+
+#ifdef TARGET_IS_armpe
+ {
+ /* Find a BFD that can hold the interworking stubs. */
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
+ break;
+ }
+ }
+#endif
+}
+
+static void
+gld_${EMULATION_NAME}_before_allocation()
+{
+#ifdef TARGET_IS_ppcpe
+ /* Here we rummage through the found bfds to collect toc information */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (!ppc_process_before_allocation (is->the_bfd, &link_info))
+ {
+ /* xgettext:c-format */
+ einfo (_("Errors encountered processing file %s\n"), is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ ppc_allocate_toc_section (&link_info);
+#endif /* TARGET_IS_ppcpe */
+
+#ifdef TARGET_IS_armpe
+ /* FIXME: we should be able to set the size of the interworking stub
+ section.
+
+ Here we rummage through the found bfds to collect glue
+ information. FIXME: should this be based on a command line
+ option? krk@cygnus.com */
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (! bfd_arm_process_before_allocation
+ (is->the_bfd, & link_info, support_old_code))
+ {
+ /* xgettext:c-format */
+ einfo (_("Errors encountered processing file %s for interworking"),
+ is->filename);
+ }
+ }
+ }
+
+ /* We have seen it all. Allocate it, and carry on */
+ bfd_arm_allocate_interworking_sections (& link_info);
+#endif /* TARGET_IS_armpe */
+}
+
+
+/* This is called when an input file isn't recognized as a BFD. We
+ check here for .DEF files and pull them in automatically. */
+
+static int
+saw_option(char *option)
+{
+ int i;
+ for (i=0; init[i].ptr; i++)
+ if (strcmp (init[i].symbol, option) == 0)
+ return init[i].inited;
+ return 0;
+}
+
+static boolean
+gld_${EMULATION_NAME}_unrecognized_file(entry)
+ lang_input_statement_type *entry;
+{
+#ifdef TARGET_IS_i386pe
+ const char *ext = entry->filename + strlen (entry->filename) - 4;
+
+ if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)
+ {
+ if (pe_def_file == 0)
+ pe_def_file = def_file_empty ();
+ def_file_parse (entry->filename, pe_def_file);
+ if (pe_def_file)
+ {
+ int i, buflen=0, len;
+ char *buf;
+ for (i=0; i<pe_def_file->num_exports; i++)
+ {
+ len = strlen(pe_def_file->exports[i].internal_name);
+ if (buflen < len+2)
+ buflen = len+2;
+ }
+ buf = (char *) xmalloc (buflen);
+ for (i=0; i<pe_def_file->num_exports; i++)
+ {
+ struct bfd_link_hash_entry *h;
+ sprintf(buf, "_%s", pe_def_file->exports[i].internal_name);
+
+ h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+ if (h->type == bfd_link_hash_new)
+ {
+ h->type = bfd_link_hash_undefined;
+ h->u.undef.abfd = NULL;
+ bfd_link_add_undef (link_info.hash, h);
+ }
+ }
+ free (buf);
+
+ /* def_file_print (stdout, pe_def_file); */
+ if (pe_def_file->is_dll == 1)
+ link_info.shared = 1;
+
+ if (pe_def_file->base_address != (bfd_vma)(-1))
+ {
+ pe.ImageBase =
+ pe_data (output_bfd)->pe_opthdr.ImageBase =
+ init[IMAGEBASEOFF].value = pe_def_file->base_address;
+ init[IMAGEBASEOFF].inited = 1;
+ if (image_base_statement)
+ image_base_statement->exp =
+ exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase));
+ }
+
+#if 0
+ /* Not sure if these *should* be set */
+ if (pe_def_file->version_major != -1)
+ {
+ pe.MajorImageVersion = pe_def_file->version_major;
+ pe.MinorImageVersion = pe_def_file->version_minor;
+ }
+#endif
+ if (pe_def_file->stack_reserve != -1
+ && ! saw_option ("__size_of_stack_reserve__"))
+ {
+ pe.SizeOfStackReserve = pe_def_file->stack_reserve;
+ if (pe_def_file->stack_commit != -1)
+ pe.SizeOfStackCommit = pe_def_file->stack_commit;
+ }
+ if (pe_def_file->heap_reserve != -1
+ && ! saw_option ("__size_of_heap_reserve__"))
+ {
+ pe.SizeOfHeapReserve = pe_def_file->heap_reserve;
+ if (pe_def_file->heap_commit != -1)
+ pe.SizeOfHeapCommit = pe_def_file->heap_commit;
+ }
+ return true;
+ }
+ }
+#endif
+ return false;
+
+}
+
+static boolean
+gld_${EMULATION_NAME}_recognized_file(entry)
+ lang_input_statement_type *entry;
+{
+#ifdef TARGET_IS_i386pe
+ if (bfd_get_format (entry->the_bfd) == bfd_object)
+ {
+ const char *ext = entry->filename + strlen (entry->filename) - 4;
+ if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0)
+ return pe_implied_import_dll (entry->filename);
+ }
+#endif
+ return false;
+}
+
+static void
+gld_${EMULATION_NAME}_finish ()
+{
+#ifdef TARGET_IS_i386pe
+ if (link_info.shared)
+ {
+ pe_dll_fill_sections (output_bfd, &link_info);
+ if (pe_implib_filename)
+ pe_dll_generate_implib (pe_def_file, pe_implib_filename);
+ }
+ if (pe_out_def_filename)
+ pe_dll_generate_def_file (pe_out_def_filename);
+#endif
+}
+
+
+/* Place an orphan section.
+
+ We use this to put sections in a reasonable place in the file, and
+ to ensure that they are aligned as required.
+
+ We handle grouped sections here as well. A section named .foo$nn
+ goes into the output section .foo. All grouped sections are sorted
+ by name.
+
+ Grouped sections for the default sections are handled by the
+ default linker script using wildcards, and are sorted by
+ sort_sections. */
+
+static asection *hold_section;
+static char *hold_section_name;
+static lang_output_section_statement_type *hold_use;
+static lang_output_section_statement_type *hold_text;
+static lang_output_section_statement_type *hold_rdata;
+static lang_output_section_statement_type *hold_data;
+static lang_output_section_statement_type *hold_bss;
+
+/* Place an orphan section. We use this to put random SHF_ALLOC
+ sections in the right segment. */
+
+/*ARGSUSED*/
+static boolean
+gld_${EMULATION_NAME}_place_orphan (file, s)
+ lang_input_statement_type *file;
+ asection *s;
+{
+ const char *secname;
+ char *dollar;
+
+ if ((s->flags & SEC_ALLOC) == 0)
+ return false;
+
+ secname = bfd_get_section_name (s->owner, s);
+
+ /* Look through the script to see where to place this section. */
+
+ hold_section = s;
+
+ hold_section_name = xstrdup (secname);
+ dollar = strchr (hold_section_name, '$');
+ if (dollar != NULL)
+ *dollar = '\0';
+
+ hold_use = NULL;
+ lang_for_each_statement (gld${EMULATION_NAME}_place_section);
+
+ if (hold_use == NULL)
+ {
+ lang_output_section_statement_type *place;
+ char *outsecname;
+ asection *snew, **pps;
+ lang_statement_list_type *old;
+ lang_statement_list_type add;
+ etree_type *address;
+
+ /* Try to put the new output section in a reasonable place based
+ on the section name and section flags. */
+ place = NULL;
+ if ((s->flags & SEC_HAS_CONTENTS) == 0
+ && hold_bss != NULL)
+ place = hold_bss;
+ else if ((s->flags & SEC_READONLY) == 0
+ && hold_data != NULL)
+ place = hold_data;
+ else if ((s->flags & SEC_CODE) == 0
+ && (s->flags & SEC_READONLY) != 0
+ && hold_rdata != NULL)
+ place = hold_rdata;
+ else if ((s->flags & SEC_READONLY) != 0
+ && hold_text != NULL)
+ place = hold_text;
+
+ /* Choose a unique name for the section. This will be needed if
+ the same section name appears in the input file with
+ different loadable or allocateable characteristics. */
+ outsecname = xstrdup (hold_section_name);
+ if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
+ {
+ unsigned int len;
+ char *newname;
+ unsigned int i;
+
+ len = strlen (outsecname);
+ newname = xmalloc (len + 5);
+ strcpy (newname, outsecname);
+ i = 0;
+ do
+ {
+ sprintf (newname + len, "%d", i);
+ ++i;
+ }
+ while (bfd_get_section_by_name (output_bfd, newname) != NULL);
+
+ free (outsecname);
+ outsecname = newname;
+ }
+
+ /* We don't want to free OUTSECNAME, as it may get attached to
+ the output section statement. */
+
+ /* Create the section in the output file, and put it in the
+ right place. This shuffling is to make the output file look
+ neater. */
+ snew = bfd_make_section (output_bfd, outsecname);
+ if (snew == NULL)
+ einfo ("%P%F: output format %s cannot represent section called %s\n",
+ output_bfd->xvec->name, outsecname);
+ if (place != NULL && place->bfd_section != NULL)
+ {
+ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+ ;
+ *pps = snew->next;
+ snew->next = place->bfd_section->next;
+ place->bfd_section->next = snew;
+ }
+
+ /* Start building a list of statements for this section. */
+ old = stat_ptr;
+ stat_ptr = &add;
+ lang_list_init (stat_ptr);
+
+ if (link_info.relocateable)
+ address = NULL;
+ else
+ {
+ /* All sections in an executable must be aligned to a page
+ boundary. */
+ address = exp_unop (ALIGN_K,
+ exp_nameop (NAME, "__section_alignment__"));
+ }
+
+ lang_enter_output_section_statement (outsecname, address, 0,
+ (bfd_vma) 0,
+ (etree_type *) NULL,
+ (etree_type *) NULL,
+ (etree_type *) NULL);
+
+ hold_use = lang_output_section_statement_lookup (outsecname);
+
+ lang_leave_output_section_statement
+ ((bfd_vma) 0, "*default*",
+ (struct lang_output_section_phdr_list *) NULL);
+
+ /* Now stick the new statement list right after PLACE. */
+ if (place != NULL)
+ {
+ *add.tail = place->header.next;
+ place->header.next = add.head;
+ }
+
+ stat_ptr = old;
+ }
+
+ if (dollar == NULL)
+ wild_doit (&hold_use->children, s, hold_use, file);
+ else
+ {
+ lang_statement_union_type **pl;
+ boolean found_dollar;
+ lang_statement_list_type list;
+
+ /* The section name has a '$'. Sort it with the other '$'
+ sections. */
+
+ found_dollar = false;
+ for (pl = &hold_use->children.head; *pl != NULL; pl = &(*pl)->next)
+ {
+ lang_input_section_type *ls;
+ const char *lname;
+
+ if ((*pl)->header.type != lang_input_section_enum)
+ continue;
+
+ ls = &(*pl)->input_section;
+
+ lname = bfd_get_section_name (ls->ifile->the_bfd, ls->section);
+ if (strchr (lname, '$') == NULL)
+ {
+ if (found_dollar)
+ break;
+ }
+ else
+ {
+ found_dollar = true;
+ if (strcmp (secname, lname) < 0)
+ break;
+ }
+ }
+
+ lang_list_init (&list);
+ wild_doit (&list, s, hold_use, file);
+ if (list.head != NULL)
+ {
+ ASSERT (list.head->next == NULL);
+ list.head->next = *pl;
+ *pl = list.head;
+ }
+ }
+
+ free (hold_section_name);
+
+ return true;
+}
+
+static void
+gld${EMULATION_NAME}_place_section (s)
+ lang_statement_union_type *s;
+{
+ lang_output_section_statement_type *os;
+
+ if (s->header.type != lang_output_section_statement_enum)
+ return;
+
+ os = &s->output_section_statement;
+
+ if (strcmp (os->name, hold_section_name) == 0
+ && os->bfd_section != NULL
+ && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
+ == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
+ hold_use = os;
+
+ if (strcmp (os->name, ".text") == 0)
+ hold_text = os;
+ else if (strcmp (os->name, ".rdata") == 0)
+ hold_rdata = os;
+ else if (strcmp (os->name, ".data") == 0)
+ hold_data = os;
+ else if (strcmp (os->name, ".bss") == 0)
+ hold_bss = os;
+}
+
+static char *
+gld_${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+# Scripts compiled in.
+# sed commands to quote an ld script as a C string.
+sc="-f ${srcdir}/emultempl/stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld_${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ gld_${EMULATION_NAME}_after_parse,
+ gld_${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld_${EMULATION_NAME}_before_allocation,
+ gld_${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ gld_${EMULATION_NAME}_finish, /* finish */
+ NULL, /* create output section statements */
+ NULL, /* open dynamic archive */
+ gld_${EMULATION_NAME}_place_orphan,
+ gld_${EMULATION_NAME}_set_symbols,
+ gld_${EMULATION_NAME}_parse_args,
+ gld_${EMULATION_NAME}_unrecognized_file,
+ gld_${EMULATION_NAME}_list_options,
+ gld_${EMULATION_NAME}_recognized_file
+};
+EOF
diff --git a/ld/emultempl/stringify.sed b/ld/emultempl/stringify.sed
new file mode 100644
index 00000000000..a526d3ffc4c
--- /dev/null
+++ b/ld/emultempl/stringify.sed
@@ -0,0 +1,4 @@
+s/["\\]/\\&/g
+s/$/\\n\\/
+1 s/^/"/
+$ s/$/n"/
diff --git a/ld/emultempl/sunos.em b/ld/emultempl/sunos.em
new file mode 100644
index 00000000000..8e9599c5558
--- /dev/null
+++ b/ld/emultempl/sunos.em
@@ -0,0 +1,1037 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* SunOS emulation code for ${EMULATION_NAME}
+ Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+ SunOS shared library support by Ian Lance Taylor <ian@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include <ctype.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libiberty.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# define dirent direct
+# ifdef HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld${EMULATION_NAME}_set_symbols PARAMS ((void));
+static void gld${EMULATION_NAME}_create_output_section_statements
+ PARAMS ((void));
+static void gld${EMULATION_NAME}_find_so
+ PARAMS ((lang_input_statement_type *));
+static char *gld${EMULATION_NAME}_search_dir
+ PARAMS ((const char *, const char *, boolean *));
+static void gld${EMULATION_NAME}_after_open PARAMS ((void));
+static void gld${EMULATION_NAME}_check_needed
+ PARAMS ((lang_input_statement_type *));
+static boolean gld${EMULATION_NAME}_search_needed
+ PARAMS ((const char *, const char *));
+static boolean gld${EMULATION_NAME}_try_needed
+ PARAMS ((const char *, const char *));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static void gld${EMULATION_NAME}_find_assignment
+ PARAMS ((lang_statement_union_type *));
+static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
+static void gld${EMULATION_NAME}_count_need
+ PARAMS ((lang_input_statement_type *));
+static void gld${EMULATION_NAME}_set_need
+ PARAMS ((lang_input_statement_type *));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+ ldfile_output_architecture = bfd_arch_${ARCH};
+ config.dynamic_link = true;
+ config.has_shared = true;
+}
+
+/* This is called after the command line arguments have been parsed,
+ but before the linker script has been read. If this is a native
+ linker, we add the directories in LD_LIBRARY_PATH to the search
+ list. */
+
+static void
+gld${EMULATION_NAME}_set_symbols ()
+{
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+ if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+ const char *env;
+
+ env = (const char *) getenv ("LD_LIBRARY_PATH");
+ if (env != NULL)
+ {
+ char *l;
+
+ l = xstrdup (env);
+ while (1)
+ {
+ char *c;
+
+ c = strchr (l, ':');
+ if (c != NULL)
+ *c++ = '\0';
+ if (*l != '\0')
+ ldfile_add_library_path (l, false);
+ if (c == NULL)
+ break;
+ l = c;
+ }
+ }
+EOF
+ fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+}
+
+/* Despite the name, we use this routine to search for dynamic
+ libraries. On SunOS this requires a directory search. We need to
+ find the .so file with the highest version number. The user may
+ restrict the major version by saying, e.g., -lc.1. Also, if we
+ find a .so file, we need to look for a the same file after
+ replacing .so with .sa; if it exists, it will be an archive which
+ provide some initializations for data symbols, and we need to
+ search it after including the .so file. */
+
+static void
+gld${EMULATION_NAME}_create_output_section_statements ()
+{
+ lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
+}
+
+/* Search the directory for a .so file for each library search. */
+
+static void
+gld${EMULATION_NAME}_find_so (inp)
+ lang_input_statement_type *inp;
+{
+ search_dirs_type *search;
+ char *found = NULL;
+ char *alc;
+ struct stat st;
+
+ if (! inp->search_dirs_flag
+ || ! inp->is_archive
+ || ! inp->dynamic)
+ return;
+
+ ASSERT (strncmp (inp->local_sym_name, "-l", 2) == 0);
+
+ for (search = search_head; search != NULL; search = search->next)
+ {
+ boolean found_static;
+
+ found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename,
+ &found_static);
+ if (found != NULL || found_static)
+ break;
+ }
+
+ if (found == NULL)
+ {
+ /* We did not find a matching .so file. This isn't an error,
+ since there might still be a matching .a file, which will be
+ found by the usual search. */
+ return;
+ }
+
+ /* Replace the filename with the one we have found. */
+ alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
+ sprintf (alc, "%s/%s", search->name, found);
+ inp->filename = alc;
+
+ /* Turn off the search_dirs_flag to prevent ldfile_open_file from
+ searching for this file again. */
+ inp->search_dirs_flag = false;
+
+ free (found);
+
+ /* Now look for the same file name, but with .sa instead of .so. If
+ found, add it to the list of input files. */
+ alc = (char *) xmalloc (strlen (inp->filename) + 1);
+ strcpy (alc, inp->filename);
+ strstr (alc + strlen (search->name), ".so")[2] = 'a';
+ if (stat (alc, &st) != 0)
+ free (alc);
+ else
+ {
+ lang_input_statement_type *sa;
+
+ /* Add the .sa file to the statement list just before the .so
+ file. This is really a hack. */
+ sa = ((lang_input_statement_type *)
+ xmalloc (sizeof (lang_input_statement_type)));
+ *sa = *inp;
+
+ inp->filename = alc;
+ inp->local_sym_name = alc;
+
+ inp->header.next = (lang_statement_union_type *) sa;
+ inp->next_real_file = (lang_statement_union_type *) sa;
+ }
+}
+
+/* Search a directory for a .so file. */
+
+static char *
+gld${EMULATION_NAME}_search_dir (dirname, filename, found_static)
+ const char *dirname;
+ const char *filename;
+ boolean *found_static;
+{
+ int force_maj, force_min;
+ const char *dot;
+ unsigned int len;
+ char *alc;
+ char *found;
+ int max_maj, max_min;
+ DIR *dir;
+ struct dirent *entry;
+ unsigned int dirnamelen;
+ char *full_path;
+ int statval;
+ struct stat st;
+
+ *found_static = false;
+
+ force_maj = -1;
+ force_min = -1;
+ dot = strchr (filename, '.');
+ if (dot == NULL)
+ {
+ len = strlen (filename);
+ alc = NULL;
+ }
+ else
+ {
+ force_maj = atoi (dot + 1);
+
+ len = dot - filename;
+ alc = (char *) xmalloc (len + 1);
+ strncpy (alc, filename, len);
+ alc[len] = '\0';
+ filename = alc;
+
+ dot = strchr (dot + 1, '.');
+ if (dot != NULL)
+ force_min = atoi (dot + 1);
+ }
+
+ found = NULL;
+ max_maj = max_min = 0;
+
+ dir = opendir (dirname);
+ if (dir == NULL)
+ return NULL;
+ dirnamelen = strlen (dirname);
+
+ while ((entry = readdir (dir)) != NULL)
+ {
+ const char *s;
+ int found_maj, found_min;
+
+ if (strncmp (entry->d_name, "lib", 3) != 0
+ || strncmp (entry->d_name + 3, filename, len) != 0)
+ continue;
+
+ if (dot == NULL
+ && strcmp (entry->d_name + 3 + len, ".a") == 0)
+ {
+ *found_static = true;
+ continue;
+ }
+
+ /* We accept libfoo.so without a version number, even though the
+ native linker does not. This is more convenient for packages
+ which just generate .so files for shared libraries, as on ELF
+ systems. */
+ if (strncmp (entry->d_name + 3 + len, ".so", 3) != 0)
+ continue;
+ if (entry->d_name[6 + len] == '\0')
+ ;
+ else if (entry->d_name[6 + len] == '.'
+ && isdigit ((unsigned char) entry->d_name[7 + len]))
+ ;
+ else
+ continue;
+
+ for (s = entry->d_name + 6 + len; *s != '\0'; s++)
+ if (*s != '.' && ! isdigit ((unsigned char) *s))
+ break;
+ if (*s != '\0')
+ continue;
+
+ /* We've found a .so file. Work out the major and minor
+ version numbers. */
+ found_maj = 0;
+ found_min = 0;
+ sscanf (entry->d_name + 3 + len, ".so.%d.%d",
+ &found_maj, &found_min);
+
+ if ((force_maj != -1 && force_maj != found_maj)
+ || (force_min != -1 && force_min != found_min))
+ continue;
+
+ /* Make sure the file really exists (ignore broken symlinks). */
+ full_path = xmalloc (dirnamelen + 1 + strlen (entry->d_name) + 1);
+ sprintf (full_path, "%s/%s", dirname, entry->d_name);
+ statval = stat (full_path, &st);
+ free (full_path);
+ if (statval != 0)
+ continue;
+
+ /* We've found a match for the name we are searching for. See
+ if this is the version we should use. If the major and minor
+ versions match, we use the last entry in alphabetical order;
+ I don't know if this is how SunOS distinguishes libc.so.1.8
+ from libc.so.1.8.1, but it ought to suffice. */
+ if (found == NULL
+ || (found_maj > max_maj)
+ || (found_maj == max_maj
+ && (found_min > max_min
+ || (found_min == max_min
+ && strcmp (entry->d_name, found) > 0))))
+ {
+ if (found != NULL)
+ free (found);
+ found = (char *) xmalloc (strlen (entry->d_name) + 1);
+ strcpy (found, entry->d_name);
+ max_maj = found_maj;
+ max_min = found_min;
+ }
+ }
+
+ closedir (dir);
+
+ if (alc != NULL)
+ free (alc);
+
+ return found;
+}
+
+/* These variables are required to pass information back and forth
+ between after_open and check_needed. */
+
+static struct bfd_link_needed_list *global_needed;
+static boolean global_found;
+
+/* This is called after all the input files have been opened. */
+
+static void
+gld${EMULATION_NAME}_after_open ()
+{
+ struct bfd_link_needed_list *needed, *l;
+
+ /* We only need to worry about this when doing a final link. */
+ if (link_info.relocateable || link_info.shared)
+ return;
+
+ /* Get the list of files which appear in ld_need entries in dynamic
+ objects included in the link. For each such file, we want to
+ track down the corresponding library, and include the symbol
+ table in the link. This is what the runtime dynamic linker will
+ do. Tracking the files down here permits one dynamic object to
+ include another without requiring special action by the person
+ doing the link. Note that the needed list can actually grow
+ while we are stepping through this loop. */
+ needed = bfd_sunos_get_needed_list (output_bfd, &link_info);
+ for (l = needed; l != NULL; l = l->next)
+ {
+ struct bfd_link_needed_list *ll;
+ const char *lname;
+ search_dirs_type *search;
+
+ lname = l->name;
+
+ /* If we've already seen this file, skip it. */
+ for (ll = needed; ll != l; ll = ll->next)
+ if (strcmp (ll->name, lname) == 0)
+ break;
+ if (ll != l)
+ continue;
+
+ /* See if this file was included in the link explicitly. */
+ global_needed = l;
+ global_found = false;
+ lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
+ if (global_found)
+ continue;
+
+ if (strncmp (lname, "-l", 2) != 0)
+ {
+ bfd *abfd;
+
+ abfd = bfd_openr (lname, bfd_get_target (output_bfd));
+ if (abfd != NULL)
+ {
+ if (! bfd_check_format (abfd, bfd_object))
+ {
+ (void) bfd_close (abfd);
+ abfd = NULL;
+ }
+ }
+ if (abfd != NULL)
+ {
+ if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
+ {
+ (void) bfd_close (abfd);
+ abfd = NULL;
+ }
+ }
+ if (abfd != NULL)
+ {
+ /* We've found the needed dynamic object. */
+ if (! bfd_link_add_symbols (abfd, &link_info))
+ einfo ("%F%B: could not read symbols: %E\n", abfd);
+ }
+ else
+ {
+ einfo ("%P: warning: %s, needed by %B, not found\n",
+ lname, l->by);
+ }
+
+ continue;
+ }
+
+ lname += 2;
+
+ /* We want to search for the file in the same way that the
+ dynamic linker will search. That means that we want to use
+ rpath_link, rpath or -L, then the environment variable
+ LD_LIBRARY_PATH (native only), then (if rpath was used) the
+ linker script LIB_SEARCH_DIRS. */
+ if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
+ lname))
+ continue;
+ if (command_line.rpath != NULL)
+ {
+ if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname))
+ continue;
+ }
+ else
+ {
+ for (search = search_head; search != NULL; search = search->next)
+ if (gld${EMULATION_NAME}_try_needed (search->name, lname))
+ break;
+ if (search != NULL)
+ continue;
+ }
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+ if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+ {
+ const char *lib_path;
+
+ lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
+ if (gld${EMULATION_NAME}_search_needed (lib_path, lname))
+ continue;
+ }
+EOF
+ fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+ if (command_line.rpath != NULL)
+ {
+ for (search = search_head; search != NULL; search = search->next)
+ {
+ if (search->cmdline)
+ continue;
+ if (gld${EMULATION_NAME}_try_needed (search->name, lname))
+ break;
+ }
+ if (search != NULL)
+ continue;
+ }
+
+ einfo ("%P: warning: %s, needed by %B, not found\n",
+ l->name, l->by);
+ }
+}
+
+/* Search for a needed file in a path. */
+
+static boolean
+gld${EMULATION_NAME}_search_needed (path, name)
+ const char *path;
+ const char *name;
+{
+ const char *s;
+
+ if (path == NULL || *path == '\0')
+ return false;
+ while (1)
+ {
+ const char *dir;
+ char *dircopy;
+
+ s = strchr (path, ':');
+ if (s == NULL)
+ {
+ dircopy = NULL;
+ dir = path;
+ }
+ else
+ {
+ dircopy = (char *) xmalloc (s - path + 1);
+ memcpy (dircopy, path, s - path);
+ dircopy[s - path] = '\0';
+ dir = dircopy;
+ }
+
+ if (gld${EMULATION_NAME}_try_needed (dir, name))
+ return true;
+
+ if (dircopy != NULL)
+ free (dircopy);
+
+ if (s == NULL)
+ break;
+ path = s + 1;
+ }
+
+ return false;
+}
+
+/* This function is called for each possible directory for a needed
+ dynamic object. */
+
+static boolean
+gld${EMULATION_NAME}_try_needed (dir, name)
+ const char *dir;
+ const char *name;
+{
+ char *file;
+ char *alc;
+ boolean ignore;
+ bfd *abfd;
+
+ file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore);
+ if (file == NULL)
+ return false;
+
+ alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2);
+ sprintf (alc, "%s/%s", dir, file);
+ free (file);
+ abfd = bfd_openr (alc, bfd_get_target (output_bfd));
+ if (abfd == NULL)
+ return false;
+ if (! bfd_check_format (abfd, bfd_object))
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+ if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+
+ /* We've found the needed dynamic object. */
+
+ /* Add this file into the symbol table. */
+ if (! bfd_link_add_symbols (abfd, &link_info))
+ einfo ("%F%B: could not read symbols: %E\n", abfd);
+
+ return true;
+}
+
+/* See if we have already included a needed object in the link. This
+ does not have to be precise, as it does no harm to include a
+ dynamic object more than once. */
+
+static void
+gld${EMULATION_NAME}_check_needed (s)
+ lang_input_statement_type *s;
+{
+ if (s->filename == NULL)
+ return;
+ if (strncmp (global_needed->name, "-l", 2) != 0)
+ {
+ if (strcmp (s->filename, global_needed->name) == 0)
+ global_found = true;
+ }
+ else
+ {
+ const char *sname, *lname;
+ const char *sdot, *ldot;
+ int lmaj, lmin, smaj, smin;
+
+ lname = global_needed->name + 2;
+
+ sname = strrchr (s->filename, '/');
+ if (sname == NULL)
+ sname = s->filename;
+ else
+ ++sname;
+
+ if (strncmp (sname, "lib", 3) != 0)
+ return;
+ sname += 3;
+
+ ldot = strchr (lname, '.');
+ if (ldot == NULL)
+ ldot = lname + strlen (lname);
+
+ sdot = strstr (sname, ".so.");
+ if (sdot == NULL)
+ return;
+
+ if (sdot - sname != ldot - lname
+ || strncmp (lname, sname, sdot - sname) != 0)
+ return;
+
+ lmaj = lmin = -1;
+ sscanf (ldot, ".%d.%d", &lmaj, &lmin);
+ smaj = smin = -1;
+ sscanf (sdot, ".so.%d.%d", &smaj, &smin);
+ if ((smaj != lmaj && smaj != -1 && lmaj != -1)
+ || (smin != lmin && smin != -1 && lmin != -1))
+ return;
+
+ global_found = true;
+ }
+}
+
+/* We need to use static variables to pass information around the call
+ to lang_for_each_statement. Ick. */
+
+static const char *find_assign;
+static boolean found_assign;
+
+/* We need to use static variables to pass information around the call
+ to lang_for_each_input_file. Ick. */
+
+static bfd_size_type need_size;
+static bfd_size_type need_entries;
+static bfd_byte *need_contents;
+static bfd_byte *need_pinfo;
+static bfd_byte *need_pnames;
+
+/* The size of one entry in the .need section, not including the file
+ name. */
+
+#define NEED_ENTRY_SIZE (16)
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gld${EMULATION_NAME}_before_allocation ()
+{
+ struct bfd_link_hash_entry *hdyn = NULL;
+ asection *sneed;
+ asection *srules;
+ asection *sdyn;
+
+ /* The SunOS native linker creates a shared library whenever there
+ are any undefined symbols in a link, unless -e is used. This is
+ pretty weird, but we are compatible. */
+ if (! link_info.shared && ! link_info.relocateable && ! entry_from_cmdline)
+ {
+ struct bfd_link_hash_entry *h;
+
+ for (h = link_info.hash->undefs; h != NULL; h = h->next)
+ {
+ if (h->type == bfd_link_hash_undefined
+ && h->u.undef.abfd != NULL
+ && (h->u.undef.abfd->flags & DYNAMIC) == 0
+ && strcmp (h->root.string, "__DYNAMIC") != 0
+ && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0)
+ {
+ find_assign = h->root.string;
+ found_assign = false;
+ lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
+ if (! found_assign)
+ {
+ link_info.shared = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (link_info.shared)
+ {
+ lang_output_section_statement_type *os;
+
+ /* Set the .text section to start at 0x20, not 0x2020. FIXME:
+ This is too magical. */
+ os = lang_output_section_statement_lookup (".text");
+ if (os->addr_tree == NULL)
+ os->addr_tree = exp_intop (0x20);
+ }
+
+ /* We need to create a __DYNAMIC symbol. We don't do this in the
+ linker script because we want to set the value to the start of
+ the dynamic section if there is one, or to zero if there isn't
+ one. We need to create the symbol before calling
+ size_dynamic_sections, although we can't set the value until
+ afterward. */
+ if (! link_info.relocateable)
+ {
+ hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", true, false,
+ false);
+ if (hdyn == NULL)
+ einfo ("%P%F: bfd_link_hash_lookup: %E\n");
+ if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
+ "__DYNAMIC"))
+ einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
+ }
+
+ /* If we are going to make any variable assignments, we need to let
+ the backend linker know about them in case the variables are
+ referred to by dynamic objects. */
+ lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
+
+ /* Let the backend linker work out the sizes of any sections
+ required by dynamic linking. */
+ if (! bfd_sunos_size_dynamic_sections (output_bfd, &link_info, &sdyn,
+ &sneed, &srules))
+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+ if (sneed != NULL)
+ {
+ /* Set up the .need section. See the description of the ld_need
+ field in include/aout/sun4.h. */
+
+ need_entries = 0;
+ need_size = 0;
+
+ lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
+
+ /* We should only have a .need section if we have at least one
+ dynamic object. */
+ ASSERT (need_entries != 0);
+
+ sneed->_raw_size = need_size;
+ sneed->contents = (bfd_byte *) xmalloc (need_size);
+
+ need_contents = sneed->contents;
+ need_pinfo = sneed->contents;
+ need_pnames = sneed->contents + need_entries * 16;
+
+ lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
+
+ ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
+ }
+
+ if (srules != NULL)
+ {
+ /* Set up the .rules section. This is just a PATH like string
+ of the -L arguments given on the command line. We permit the
+ user to specify the directories using the -rpath command line
+ option. */
+ if (command_line.rpath)
+ {
+ srules->_raw_size = strlen (command_line.rpath);
+ srules->contents = (bfd_byte *) command_line.rpath;
+ }
+ else
+ {
+ unsigned int size;
+ search_dirs_type *search;
+
+ size = 0;
+ for (search = search_head; search != NULL; search = search->next)
+ if (search->cmdline)
+ size += strlen (search->name) + 1;
+ srules->_raw_size = size;
+ if (size > 0)
+ {
+ char *p;
+
+ srules->contents = (bfd_byte *) xmalloc (size);
+ p = (char *) srules->contents;
+ *p = '\0';
+ for (search = search_head; search != NULL; search = search->next)
+ {
+ if (search->cmdline)
+ {
+ if (p != (char *) srules->contents)
+ *p++ = ':';
+ strcpy (p, search->name);
+ p += strlen (p);
+ }
+ }
+ }
+ }
+ }
+
+ /* We must assign a value to __DYNAMIC. It should be zero if we are
+ not doing a dynamic link, or the start of the .dynamic section if
+ we are doing one. */
+ if (! link_info.relocateable)
+ {
+ hdyn->type = bfd_link_hash_defined;
+ hdyn->u.def.value = 0;
+ if (sdyn != NULL)
+ hdyn->u.def.section = sdyn;
+ else
+ hdyn->u.def.section = bfd_abs_section_ptr;
+ }
+}
+
+/* This is called by the before_allocation routine via
+ lang_for_each_statement. It does one of two things: if the
+ variable find_assign is set, it sets found_assign if it finds an
+ assignment to that variable; otherwise it tells the backend linker
+ about all assignment statements, in case they are assignments to
+ symbols which are referred to by dynamic objects. */
+
+static void
+gld${EMULATION_NAME}_find_assignment (s)
+ lang_statement_union_type *s;
+{
+ if (s->header.type == lang_assignment_statement_enum
+ && (find_assign == NULL || ! found_assign))
+ gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
+}
+
+/* Look through an expression for an assignment statement. */
+
+static void
+gld${EMULATION_NAME}_find_exp_assignment (exp)
+ etree_type *exp;
+{
+ switch (exp->type.node_class)
+ {
+ case etree_assign:
+ if (find_assign != NULL)
+ {
+ if (strcmp (find_assign, exp->assign.dst) == 0)
+ found_assign = true;
+ return;
+ }
+
+ if (strcmp (exp->assign.dst, ".") != 0)
+ {
+ if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
+ exp->assign.dst))
+ einfo ("%P%F: failed to record assignment to %s: %E\n",
+ exp->assign.dst);
+ }
+ gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
+ break;
+
+ case etree_binary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
+ break;
+
+ case etree_trinary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
+ break;
+
+ case etree_unary:
+ gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Work out the size of the .need section, and the number of entries.
+ The backend will set the ld_need field of the dynamic linking
+ information to point to the .need section. See include/aout/sun4.h
+ for more information. */
+
+static void
+gld${EMULATION_NAME}_count_need (inp)
+ lang_input_statement_type *inp;
+{
+ if (inp->the_bfd != NULL
+ && (inp->the_bfd->flags & DYNAMIC) != 0)
+ {
+ ++need_entries;
+ need_size += NEED_ENTRY_SIZE;
+ if (! inp->is_archive)
+ need_size += strlen (inp->filename) + 1;
+ else
+ {
+ ASSERT (inp->local_sym_name[0] == '-'
+ && inp->local_sym_name[1] == 'l');
+ need_size += strlen (inp->local_sym_name + 2) + 1;
+ }
+ }
+}
+
+/* Fill in the contents of the .need section. */
+
+static void
+gld${EMULATION_NAME}_set_need (inp)
+ lang_input_statement_type *inp;
+{
+ if (inp->the_bfd != NULL
+ && (inp->the_bfd->flags & DYNAMIC) != 0)
+ {
+ bfd_size_type c;
+
+ /* To really fill in the .need section contents, we need to know
+ the final file position of the section, but we don't.
+ Instead, we use offsets, and rely on the BFD backend to
+ finish the section up correctly. FIXME: Talk about lack of
+ referential locality. */
+ bfd_put_32 (output_bfd, need_pnames - need_contents, need_pinfo);
+ if (! inp->is_archive)
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 4);
+ bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 8);
+ bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 10);
+ strcpy (need_pnames, inp->filename);
+ }
+ else
+ {
+ char *verstr;
+ int maj, min;
+
+ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, need_pinfo + 4);
+ maj = 0;
+ min = 0;
+ verstr = strstr (inp->filename, ".so.");
+ if (verstr != NULL)
+ sscanf (verstr, ".so.%d.%d", &maj, &min);
+ bfd_put_16 (output_bfd, (bfd_vma) maj, need_pinfo + 8);
+ bfd_put_16 (output_bfd, (bfd_vma) min, need_pinfo + 10);
+ strcpy (need_pnames, inp->local_sym_name + 2);
+ }
+
+ c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
+ if (c + 1 >= need_entries)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 12);
+ else
+ bfd_put_32 (output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
+ need_pinfo + 12);
+
+ need_pinfo += NEED_ENTRY_SIZE;
+ need_pnames += strlen (need_pnames) + 1;
+ }
+}
+
+static char *
+gld${EMULATION_NAME}_get_script(isfile)
+ int *isfile;
+EOF
+
+if test -n "$COMPILE_IN"
+then
+# Scripts compiled in.
+
+# sed commands to quote an ld script as a C string.
+sc='s/["\\]/\\&/g
+s/$/\\n\\/
+1s/^/"/
+$s/$/n"/
+'
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
+ else if (link_info.relocateable == true)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
+ else if (!config.text_read_only)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
+ else if (!config.magic_demand_paged)
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
+ else
+ return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
+}
+EOF
+
+else
+# Scripts read from the filesystem.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 1;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "ldscripts/${EMULATION_NAME}.xu";
+ else if (link_info.relocateable == true)
+ return "ldscripts/${EMULATION_NAME}.xr";
+ else if (!config.text_read_only)
+ return "ldscripts/${EMULATION_NAME}.xbn";
+ else if (!config.magic_demand_paged)
+ return "ldscripts/${EMULATION_NAME}.xn";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+}
+EOF
+
+fi
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gld${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld${EMULATION_NAME}_before_allocation,
+ gld${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ NULL, /* finish */
+ gld${EMULATION_NAME}_create_output_section_statements,
+ NULL, /* open_dynamic_library */
+ NULL, /* place_orphan */
+ gld${EMULATION_NAME}_set_symbols
+};
+EOF
diff --git a/ld/emultempl/vanilla.em b/ld/emultempl/vanilla.em
new file mode 100644
index 00000000000..04e36fbc947
--- /dev/null
+++ b/ld/emultempl/vanilla.em
@@ -0,0 +1,69 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* A vanilla emulation with no defaults
+ Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+
+#include "ld.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldmain.h"
+
+static void vanilla_before_parse()
+{
+}
+
+static void
+vanilla_set_output_arch()
+{
+ /* Set the output architecture and machine if possible */
+ unsigned long machine = 0;
+ bfd_set_arch_mach(output_bfd, ldfile_output_architecture, machine);
+}
+
+static char *
+vanilla_get_script(isfile)
+ int *isfile;
+{
+ *isfile = 0;
+ return "";
+}
+
+struct ld_emulation_xfer_struct ld_vanilla_emulation =
+{
+ vanilla_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ vanilla_set_output_arch,
+ ldemul_default_target,
+ before_allocation_default,
+ vanilla_get_script,
+ "vanilla",
+ "a.out-sunos-big"
+};
+EOF
diff --git a/ld/gen-doc.texi b/ld/gen-doc.texi
new file mode 100644
index 00000000000..3a367277e50
--- /dev/null
+++ b/ld/gen-doc.texi
@@ -0,0 +1,13 @@
+@c ------------------------------ CONFIGURATION VARS:
+@c 1. Inclusiveness of this manual
+@set GENERIC
+
+@c 2. Specific target machines
+@set H8300
+@set I960
+
+@c 3. Properties of this configuration
+@clear SingleFormat
+@set UsesEnvVars
+@c ------------------------------ end CONFIGURATION VARS
+
diff --git a/ld/genscripts.sh b/ld/genscripts.sh
new file mode 100755
index 00000000000..eea5401515b
--- /dev/null
+++ b/ld/genscripts.sh
@@ -0,0 +1,133 @@
+#!/bin/sh
+# genscripts.sh - generate the ld-emulation-target specific files
+#
+# Usage: genscripts.sh srcdir libdir host target target_alias \
+# default_emulation native_lib_dirs this_emulation tool_dir
+#
+# Sample usage:
+# genscripts.sh /djm/ld-devo/devo/ld /usr/local/lib sparc-sun-sunos4.1.3 \
+# sparc-sun-sunos4.1.3 sparc-sun-sunos4.1.3 sun4 "" sun3 sparc-sun-sunos4.1.3
+# produces sun3.x sun3.xbn sun3.xn sun3.xr sun3.xu em_sun3.c
+
+srcdir=$1
+libdir=$2
+host=$3
+target=$4
+target_alias=$5
+DEFAULT_EMULATION=$6
+NATIVE_LIB_DIRS=$7
+EMULATION_NAME=$8
+tool_lib=`echo ${libdir} | sed -e 's|/lib$||'`/${9-$target_alias}/lib
+
+# Include the emulation-specific parameters:
+. ${srcdir}/emulparams/${EMULATION_NAME}.sh
+
+if test -d ldscripts; then
+ true
+else
+ mkdir ldscripts
+fi
+
+# Set the library search path, for libraries named by -lfoo.
+# If LIB_PATH is defined (e.g., by Makefile) and non-empty, it is used.
+# Otherwise, the default is set here.
+#
+# The format is the usual list of colon-separated directories.
+# To force a logically empty LIB_PATH, do LIBPATH=":".
+
+if [ "x${LIB_PATH}" = "x" ] ; then
+ if [ "x${host}" = "x${target}" ] ; then
+ if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+ # Native.
+ LIB_PATH=/lib:/usr/lib
+ if [ -n "${NATIVE_LIB_DIRS}" ]; then
+ LIB_PATH=${LIB_PATH}:${NATIVE_LIB_DIRS}
+ fi
+ if [ "${libdir}" != /usr/lib ]; then
+ LIB_PATH=${LIB_PATH}:${libdir}
+ fi
+ if [ "${libdir}" != /usr/local/lib ] ; then
+ LIB_PATH=${LIB_PATH}:/usr/local/lib
+ fi
+ else
+ # Native, but not default emulation.
+ LIB_PATH=
+ fi
+ else
+ # Cross.
+ LIB_PATH=
+ fi
+fi
+
+# Always search $(tooldir)/lib, aka /usr/local/TARGET/lib.
+LIB_PATH=${LIB_PATH}:${tool_lib}
+
+LIB_SEARCH_DIRS=`echo ${LIB_PATH} | tr ':' ' ' | sed -e 's/\([^ ][^ ]*\)/SEARCH_DIR(\1);/g'`
+
+# Generate 5 or 6 script files from a master script template in
+# ${srcdir}/scripttempl/${SCRIPT_NAME}.sh. Which one of the 5 or 6
+# script files is actually used depends on command line options given
+# to ld. (SCRIPT_NAME was set in the emulparams_file.)
+#
+# A .x script file is the default script.
+# A .xr script is for linking without relocation (-r flag).
+# A .xu script is like .xr, but *do* create constructors (-Ur flag).
+# A .xn script is for linking with -n flag (mix text and data on same page).
+# A .xbn script is for linking with -N flag (mix text and data on same page).
+# A .xs script is for generating a shared library with the --shared
+# flag; it is only generated if $GENERATE_SHLIB_SCRIPT is set by the
+# emulation parameters.
+
+SEGMENT_SIZE=${SEGMENT_SIZE-${TARGET_PAGE_SIZE}}
+
+# Determine DATA_ALIGNMENT for the 5 variants, using
+# values specified in the emulparams/<emulation>.sh file or default.
+
+DATA_ALIGNMENT_="${DATA_ALIGNMENT_-${DATA_ALIGNMENT-ALIGN(${SEGMENT_SIZE})}}"
+DATA_ALIGNMENT_n="${DATA_ALIGNMENT_n-${DATA_ALIGNMENT_}}"
+DATA_ALIGNMENT_N="${DATA_ALIGNMENT_N-${DATA_ALIGNMENT-.}}"
+DATA_ALIGNMENT_r="${DATA_ALIGNMENT_r-${DATA_ALIGNMENT-}}"
+DATA_ALIGNMENT_u="${DATA_ALIGNMENT_u-${DATA_ALIGNMENT_r}}"
+
+LD_FLAG=r
+DATA_ALIGNMENT=${DATA_ALIGNMENT_r}
+DEFAULT_DATA_ALIGNMENT="ALIGN(${SEGMENT_SIZE})"
+(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \
+ ldscripts/${EMULATION_NAME}.xr
+
+LD_FLAG=u
+DATA_ALIGNMENT=${DATA_ALIGNMENT_u}
+CONSTRUCTING=" "
+(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \
+ ldscripts/${EMULATION_NAME}.xu
+
+LD_FLAG=
+DATA_ALIGNMENT=${DATA_ALIGNMENT_}
+RELOCATING=" "
+(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \
+ ldscripts/${EMULATION_NAME}.x
+
+LD_FLAG=n
+DATA_ALIGNMENT=${DATA_ALIGNMENT_n}
+TEXT_START_ADDR=${NONPAGED_TEXT_START_ADDR-${TEXT_START_ADDR}}
+(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \
+ ldscripts/${EMULATION_NAME}.xn
+
+LD_FLAG=N
+DATA_ALIGNMENT=${DATA_ALIGNMENT_N}
+(. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \
+ ldscripts/${EMULATION_NAME}.xbn
+
+if test -n "$GENERATE_SHLIB_SCRIPT"; then
+ LD_FLAG=shared
+ DATA_ALIGNMENT=${DATA_ALIGNMENT_s-${DATA_ALIGNMENT_}}
+ CREATE_SHLIB=" "
+ # Note that TEXT_START_ADDR is set to NONPAGED_TEXT_START_ADDR.
+ (. ${srcdir}/scripttempl/${SCRIPT_NAME}.sc) | sed -e '/^ *$/d' > \
+ ldscripts/${EMULATION_NAME}.xs
+fi
+
+test "$DEFAULT_EMULATION" = "$EMULATION_NAME" && COMPILE_IN=true
+
+# Generate e${EMULATION_NAME}.c.
+. ${srcdir}/emultempl/${TEMPLATE_NAME-generic}.em
diff --git a/ld/h8-doc.texi b/ld/h8-doc.texi
new file mode 100644
index 00000000000..f3c62a1cc0b
--- /dev/null
+++ b/ld/h8-doc.texi
@@ -0,0 +1,14 @@
+@c ------------------------------ CONFIGURATION VARS:
+@c 1. Inclusiveness of this manual
+@clear GENERIC
+
+@c 2. Specific target machines
+@set H8300
+@set Hitachi
+@clear I960
+
+@c 3. Properties of this configuration
+@set SingleFormat
+@clear UsesEnvVars
+@c ------------------------------ end CONFIGURATION VARS
+
diff --git a/ld/ld.1 b/ld/ld.1
new file mode 100644
index 00000000000..58516b979b2
--- /dev/null
+++ b/ld/ld.1
@@ -0,0 +1,1115 @@
+.\" Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation
+.\" See section COPYING for conditions for redistribution
+.TH ld 1 "17 August 1992" "cygnus support" "GNU Development Tools"
+.de BP
+.sp
+.ti \-.2i
+\(**
+..
+
+.SH NAME
+ld \- the GNU linker
+
+.SH SYNOPSIS
+.hy 0
+.na
+.TP
+.B ld
+.RB "[\|" \-o "
+.I output\c
+\&\|] \c
+.I objfile\c
+\&.\|.\|.
+.br
+.RB "[\|" \-A\c
+.I architecture\c
+\&\|]
+.RB "[\|" "\-b\ "\c
+.I input-format\c
+\&\|]
+.RB "[\|" \-Bstatic "\|]"
+.RB "[\|" \-Bdynamic "\|]"
+.RB "[\|" \-Bsymbolic "\|]"
+.RB "[\|" "\-c\ "\c
+.I commandfile\c
+\&\|]
+.RB "[\|" \-\-cref "\|]"
+.RB "[\|" \-d | \-dc | \-dp\c
+\|]
+.br
+.RB "[\|" "\-defsym\ "\c
+.I symbol\c
+\& = \c
+.I expression\c
+\&\|]
+.RB "[\|" \-\-demangle "\|]"
+.RB "[\|" \-\-no\-demangle "\|]"
+.RB "[\|" "\-e\ "\c
+.I entry\c
+\&\|]
+.RB "[\|" \-embedded\-relocs "\|]"
+.RB "[\|" \-E "\|]"
+.RB "[\|" \-export\-dynamic "\|]"
+.RB "[\|" "\-f\ "\c
+.I name\c
+\&\|]
+.RB "[\|" "\-\-auxiliary\ "\c
+.I name\c
+\&\|]
+.RB "[\|" "\-F\ "\c
+.I name\c
+\&\|]
+.RB "[\|" "\-\-filter\ "\c
+.I name\c
+\&\|]
+.RB "[\|" "\-format\ "\c
+.I input-format\c
+\&\|]
+.RB "[\|" \-g "\|]"
+.RB "[\|" \-G
+.I size\c
+\&\|]
+.RB "[\|" "\-h\ "\c
+.I name\c
+\&\|]
+.RB "[\|" "\-soname\ "\c
+.I name\c
+\&\|]
+.RB "[\|" \-\-help "\|]"
+.RB "[\|" \-i "\|]"
+.RB "[\|" \-l\c
+.I ar\c
+\&\|]
+.RB "[\|" \-L\c
+.I searchdir\c
+\&\|]
+.RB "[\|" \-M "\|]"
+.RB "[\|" \-Map
+.I mapfile\c
+\&\|]
+.RB "[\|" \-m
+.I emulation\c
+\&\|]
+.RB "[\|" \-n | \-N "\|]"
+.RB "[\|" \-noinhibit-exec "\|]"
+.RB "[\|" \-no\-keep\-memory "\|]"
+.RB "[\|" \-no\-warn\-mismatch "\|]"
+.RB "[\|" \-O\c
+.I level\c
+\&\|]
+.RB "[\|" "\-oformat\ "\c
+.I output-format\c
+\&\|]
+.RB "[\|" "\-R\ "\c
+.I filename\c
+\&\|]
+.RB "[\|" \-relax "\|]"
+.RB "[\|" \-r | \-Ur "\|]"
+.RB "[\|" "\-rpath\ "\c
+.I directory\c
+\&\|]
+.RB "[\|" "\-rpath\-link\ "\c
+.I directory\c
+\&\|]
+.RB "[\|" \-S "\|]"
+.RB "[\|" \-s "\|]"
+.RB "[\|" \-shared "\|]"
+.RB "[\|" \-sort\-common "\|]"
+.RB "[\|" "\-split\-by\-reloc\ "\c
+.I count\c
+\&\|]
+.RB "[\|" \-split\-by\-file "\|]"
+.RB "[\|" "\-T\ "\c
+.I commandfile\c
+\&\|]
+.RB "[\|" "\-Ttext\ "\c
+.I textorg\c
+\&\|]
+.RB "[\|" "\-Tdata\ "\c
+.I dataorg\c
+\&\|]
+.RB "[\|" "\-Tbss\ "\c
+.I bssorg\c
+\&\|]
+.RB "[\|" \-t "\|]"
+.RB "[\|" "\-u\ "\c
+.I sym\c
+\&]
+.RB "[\|" \-V "\|]"
+.RB "[\|" \-v "\|]"
+.RB "[\|" \-\-verbose "\|]"
+.RB "[\|" \-\-version "\|]"
+.RB "[\|" \-warn\-common "\|]"
+.RB "[\|" \-warn\-constructors "\|]"
+.RB "[\|" \-warn\-multiple\-gp "\|]"
+.RB "[\|" \-warn\-once "\|]"
+.RB "[\|" \-warn\-section\-align "\|]"
+.RB "[\|" \-\-whole\-archive "\|]"
+.RB "[\|" \-\-no\-whole\-archive "\|]"
+.RB "[\|" "\-\-wrap\ "\c
+.I symbol\c
+\&\|]
+.RB "[\|" \-X "\|]"
+.RB "[\|" \-x "\|]"
+.ad b
+.hy 1
+.SH DESCRIPTION
+\c
+.B ld\c
+\& combines a number of object and archive files, relocates
+their data and ties up symbol references. Often the last step in
+building a new compiled program to run is a call to \c
+.B ld\c
+\&.
+
+\c
+.B ld\c
+\& accepts Linker Command Language files
+to provide explicit and total control over the linking process.
+This man page does not describe the command language; see the `\|\c
+.B ld\c
+\|' entry in `\|\c
+.B info\c
+\|', or the manual
+.I
+ld: the GNU linker
+\&, for full details on the command language and on other aspects of
+the GNU linker.
+
+This version of \c
+.B ld\c
+\& uses the general purpose BFD libraries
+to operate on object files. This allows \c
+.B ld\c
+\& to read, combine, and
+write object files in many different formats\(em\&for example, COFF or
+\c
+.B a.out\c
+\&. Different formats may be linked together to produce any
+available kind of object file. You can use `\|\c
+.B objdump \-i\c
+\|' to get a list of formats supported on various architectures; see
+.BR objdump ( 1 ).
+
+Aside from its flexibility, the GNU linker is more helpful than other
+linkers in providing diagnostic information. Many linkers abandon
+execution immediately upon encountering an error; whenever possible,
+\c
+.B ld\c
+\& continues executing, allowing you to identify other errors
+(or, in some cases, to get an output file in spite of the error).
+
+The GNU linker \c
+.B ld\c
+\& is meant to cover a broad range of situations,
+and to be as compatible as possible with other linkers. As a result,
+you have many choices to control its behavior through the command line,
+and through environment variables.
+
+.SH OPTIONS
+The plethora of command-line options may seem intimidating, but in
+actual practice few of them are used in any particular context.
+For instance, a frequent use of \c
+.B ld\c
+\& is to link standard Unix
+object files on a standard, supported Unix system. On such a system, to
+link a file \c
+.B hello.o\c
+\&:
+.sp
+.br
+$\ ld\ \-o\ output\ /lib/crt0.o\ hello.o\ \-lc
+.br
+.sp
+This tells \c
+.B ld\c
+\& to produce a file called \c
+.B output\c
+\& as the
+result of linking the file \c
+.B /lib/crt0.o\c
+\& with \c
+.B hello.o\c
+\& and
+the library \c
+.B libc.a\c
+\& which will come from the standard search
+directories.
+
+The command-line options to \c
+.B ld\c
+\& may be specified in any order, and
+may be repeated at will. For the most part, repeating an option with a
+different argument will either have no further effect, or override prior
+occurrences (those further to the left on the command line) of an
+option.
+
+The exceptions\(em\&which may meaningfully be used more than once\(em\&are
+\c
+.B \-A\c
+\&, \c
+.B \-b\c
+\& (or its synonym \c
+.B \-format\c
+\&), \c
+.B \-defsym\c
+\&,
+\c
+.B \-L\c
+\&, \c
+.B \-l\c
+\&, \c
+.B \-R\c
+\&, and \c
+.B \-u\c
+\&.
+
+The list of object files to be linked together, shown as \c
+.I objfile\c
+\&,
+may follow, precede, or be mixed in with command-line options; save that
+an \c
+.I objfile\c
+\& argument may not be placed between an option flag and
+its argument.
+
+Usually the linker is invoked with at least one object file, but other
+forms of binary input files can also be specified with \c
+.B \-l\c
+\&,
+\c
+.B \-R\c
+\&, and the script command language. If \c
+.I no\c
+\& binary input
+files at all are specified, the linker does not produce any output, and
+issues the message `\|\c
+.B No input files\c
+\|'.
+
+Option arguments must either follow the option letter without intervening
+whitespace, or be given as separate arguments immediately following the
+option that requires them.
+
+.TP
+.BI "-A" "architecture"
+In the current release of \c
+.B ld\c
+\&, this option is useful only for the
+Intel 960 family of architectures. In that \c
+.B ld\c
+\& configuration, the
+\c
+.I architecture\c
+\& argument is one of the two-letter names identifying
+members of the 960 family; the option specifies the desired output
+target, and warns of any incompatible instructions in the input files.
+It also modifies the linker's search strategy for archive libraries, to
+support the use of libraries specific to each particular
+architecture, by including in the search loop names suffixed with the
+string identifying the architecture.
+
+For example, if your \c
+.B ld\c
+\& command line included `\|\c
+.B \-ACA\c
+\|' as
+well as `\|\c
+.B \-ltry\c
+\|', the linker would look (in its built-in search
+paths, and in any paths you specify with \c
+.B \-L\c
+\&) for a library with
+the names
+.sp
+.br
+try
+.br
+libtry.a
+.br
+tryca
+.br
+libtryca.a
+.br
+.sp
+
+The first two possibilities would be considered in any event; the last
+two are due to the use of `\|\c
+.B \-ACA\c
+\|'.
+
+Future releases of \c
+.B ld\c
+\& may support similar functionality for
+other architecture families.
+
+You can meaningfully use \c
+.B \-A\c
+\& more than once on a command line, if
+an architecture family allows combination of target architectures; each
+use will add another pair of name variants to search for when \c
+.B \-l
+specifies a library.
+
+.TP
+.BI "\-b " "input-format"
+Specify the binary format for input object files that follow this option
+on the command line. You don't usually need to specify this, as
+\c
+.B ld\c
+\& is configured to expect as a default input format the most
+usual format on each machine. \c
+.I input-format\c
+\& is a text string, the
+name of a particular format supported by the BFD libraries.
+\c
+.B \-format \c
+.I input-format\c
+\&\c
+\& has the same effect, as does the script command
+.BR TARGET .
+
+You may want to use this option if you are linking files with an unusual
+binary format. You can also use \c
+.B \-b\c
+\& to switch formats explicitly (when
+linking object files of different formats), by including
+\c
+.B \-b \c
+.I input-format\c
+\&\c
+\& before each group of object files in a
+particular format.
+
+The default format is taken from the environment variable
+.B GNUTARGET\c
+\&. You can also define the input
+format from a script, using the command \c
+.B TARGET\c
+\&.
+
+.TP
+.B \-Bstatic
+Do not link against shared libraries. This is only meaningful on
+platforms for which shared libraries are supported.
+
+.TP
+.B \-Bdynamic
+Link against dynamic libraries. This is only meaningful on platforms
+for which shared libraries are supported. This option is normally the
+default on such platforms.
+
+.TP
+.B \-Bsymbolic
+When creating a shared library, bind references to global symbols to
+the definition within the shared library, if any. Normally, it is
+possible for a program linked against a shared library to override the
+definition within the shared library. This option is only meaningful
+on ELF platforms which support shared libraries.
+
+.TP
+.BI "\-c " "commandfile"
+Directs \c
+.B ld\c
+\& to read link commands from the file
+\c
+.I commandfile\c
+\&. These commands will completely override \c
+.B ld\c
+\&'s
+default link format (rather than adding to it); \c
+.I commandfile\c
+\& must
+specify everything necessary to describe the target format.
+
+
+You may also include a script of link commands directly in the command
+line by bracketing it between `\|\c
+.B {\c
+\|' and `\|\c
+.B }\c
+\|' characters.
+
+.TP
+.B \-\-cref
+Output a cross reference table. If a linker map file is being
+generated, the cross reference table is printed to the map file.
+Otherwise, it is printed on the standard output.
+
+.TP
+.B \-d
+.TP
+.B \-dc
+.TP
+.B \-dp
+These three options are equivalent; multiple forms are supported for
+compatibility with other linkers. Use any of them to make \c
+.B ld
+assign space to common symbols even if a relocatable output file is
+specified (\c
+.B \-r\c
+\&). The script command
+\c
+.B FORCE_COMMON_ALLOCATION\c
+\& has the same effect.
+
+.TP
+.BI "-defsym " "symbol" "\fR = \fP" expression
+Create a global symbol in the output file, containing the absolute
+address given by \c
+.I expression\c
+\&. You may use this option as many
+times as necessary to define multiple symbols in the command line. A
+limited form of arithmetic is supported for the \c
+.I expression\c
+\& in this
+context: you may give a hexadecimal constant or the name of an existing
+symbol, or use \c
+.B +\c
+\& and \c
+.B \-\c
+\& to add or subtract hexadecimal
+constants or symbols. If you need more elaborate expressions, consider
+using the linker command language from a script.
+
+.TP
+.B \-\-demangle
+.TP
+.B \-\-no\-demangle
+These options control whether to demangle symbol names in error
+messages and other output. When the linker is told to demangle, it
+tries to present symbol names in a readable fashion: it strips leading
+underscores if they are used by the object file format, and converts
+C++ mangled symbol names into user readable names. The linker will
+demangle by default unless the environment variable
+.B COLLECT_NO_DEMANGLE
+is set. These options may be used to override the default.
+
+.TP
+.BI "-e " "entry"\c
+\&
+Use \c
+.I entry\c
+\& as the explicit symbol for beginning execution of your
+program, rather than the default entry point. See the `\|\c
+.B ld\c
+\|' entry in `\|\c
+.B info\c
+\|' for a
+discussion of defaults and other ways of specifying the
+entry point.
+
+.TP
+.B \-embedded\-relocs
+This option is only meaningful when linking MIPS embedded PIC code,
+generated by the
+.B \-membedded\-pic
+option to the GNU compiler and assembler. It causes the linker to
+create a table which may be used at runtime to relocate any data which
+was statically initialized to pointer values. See the code in
+testsuite/ld-empic for details.
+
+.TP
+.B \-E
+.TP
+.B \-export\-dynamic
+When creating an ELF file, add all symbols to the dynamic symbol table.
+Normally, the dynamic symbol table contains only symbols which are used
+by a dynamic object. This option is needed for some uses of
+.I dlopen.
+
+.TP
+.BI "-f " "name"
+.TP
+.BI "--auxiliary " "name"
+When creating an ELF shared object, set the internal DT_AUXILIARY field
+to the specified name. This tells the dynamic linker that the symbol
+table of the shared object should be used as an auxiliary filter on the
+symbol table of the shared object
+.I name.
+
+.TP
+.BI "-F " "name"
+.TP
+.BI "--filter " "name"
+When creating an ELF shared object, set the internal DT_FILTER field to
+the specified name. This tells the dynamic linker that the symbol table
+of the shared object should be used as a filter on the symbol table of
+the shared object
+.I name.
+
+.TP
+.BI "\-format " "input\-format"
+Synonym for \c
+.B \-b\c
+\& \c
+.I input\-format\c
+\&.
+
+.TP
+.B \-g
+Accepted, but ignored; provided for compatibility with other tools.
+
+.TP
+.BI "\-G " "size"\c
+Set the maximum size of objects to be optimized using the GP register
+to
+.I size
+under MIPS ECOFF. Ignored for other object file formats.
+
+.TP
+.BI "-h " "name"
+.TP
+.BI "-soname " "name"
+When creating an ELF shared object, set the internal DT_SONAME field to
+the specified name. When an executable is linked with a shared object
+which has a DT_SONAME field, then when the executable is run the dynamic
+linker will attempt to load the shared object specified by the DT_SONAME
+field rather than the using the file name given to the linker.
+
+.TP
+.B \-\-help
+Print a summary of the command-line options on the standard output and exit.
+This option and
+.B \-\-version
+begin with two dashes instead of one
+for compatibility with other GNU programs. The other options start with
+only one dash for compatibility with other linkers.
+
+.TP
+.B \-i
+Perform an incremental link (same as option \c
+.B \-r\c
+\&).
+
+.TP
+.BI "\-l" "ar"\c
+\&
+Add an archive file \c
+.I ar\c
+\& to the list of files to link. This
+option may be used any number of times. \c
+.B ld\c
+\& will search its
+path-list for occurrences of \c
+.B lib\c
+.I ar\c
+\&.a\c
+\& for every \c
+.I ar
+specified.
+
+.TP
+.BI "\-L" "searchdir"
+This command adds path \c
+.I searchdir\c
+\& to the list of paths that
+\c
+.B ld\c
+\& will search for archive libraries. You may use this option
+any number of times.
+
+The default set of paths searched (without being specified with
+\c
+.B \-L\c
+\&) depends on what emulation mode \c
+.B ld\c
+\& is using, and in
+some cases also on how it was configured. The
+paths can also be specified in a link script with the \c
+.B SEARCH_DIR
+command.
+
+.TP
+.B \-M
+Print (to the standard output file) a link map\(em\&diagnostic information
+about where symbols are mapped by \c
+.B ld\c
+\&, and information on global
+common storage allocation.
+
+.TP
+.BI "\-Map " "mapfile"\c
+Print to the file
+.I mapfile
+a link map\(em\&diagnostic information
+about where symbols are mapped by \c
+.B ld\c
+\&, and information on global
+common storage allocation.
+
+.TP
+.BI "\-m " "emulation"\c
+Emulate the
+.I emulation
+linker. You can list the available emulations with the
+.I \-\-verbose
+or
+.I \-V
+options. This option overrides the compiled-in default, which is the
+system for which you configured
+.BR ld .
+
+.TP
+.B \-N
+specifies readable and writable \c
+.B text\c
+\& and \c
+.B data\c
+\& sections. If
+the output format supports Unix style magic numbers, the output is
+marked as \c
+.B OMAGIC\c
+\&.
+
+When you use the `\|\c
+.B \-N\c
+\&\|' option, the linker does not page-align the
+data segment.
+
+.TP
+.B \-n
+sets the text segment to be read only, and \c
+.B NMAGIC\c
+\& is written
+if possible.
+
+.TP
+.B \-noinhibit\-exec
+Normally, the linker will not produce an output file if it encounters
+errors during the link process. With this flag, you can specify that
+you wish the output file retained even after non-fatal errors.
+
+.TP
+.B \-no\-keep\-memory
+The linker normally optimizes for speed over memory usage by caching
+the symbol tables of input files in memory. This option tells the
+linker to instead optimize for memory usage, by rereading the symbol
+tables as necessary. This may be required if the linker runs out of
+memory space while linking a large executable.
+
+.TP
+.B \-no\-warn\-mismatch
+Normally the linker will give an error if you try to link together
+input files that are mismatched for some reason, perhaps because they
+have been compiled for different processors or for different
+endiannesses. This option tells the linker that it should silently
+permit such possible errors. This option should only be used with
+care, in cases when you have taken some special action that ensures
+that the linker errors are inappropriate.
+
+.TP
+.BI "\-o " "output"
+.I output\c
+\& is a name for the program produced by \c
+.B ld\c
+\&; if this
+option is not specified, the name `\|\c
+.B a.out\c
+\|' is used by default. The
+script command \c
+.B OUTPUT\c
+\& can also specify the output file name.
+
+.TP
+.BI "\-O" "level"
+Generate optimized output files. This might use significantly more
+time and therefore probably should be enabled only for generating the
+final binary.
+\c
+.I level\c
+\& is supposed to be a numeric value. Any value greater than zero enables
+the optimizations.
+
+.TP
+.BI "\-oformat " "output\-format"
+Specify the binary format for the output object file.
+You don't usually need to specify this, as
+\c
+.B ld\c
+\& is configured to produce as a default output format the most
+usual format on each machine. \c
+.I output-format\c
+\& is a text string, the
+name of a particular format supported by the BFD libraries.
+The script command
+.B OUTPUT_FORMAT
+can also specify the output format, but this option overrides it.
+
+.TP
+.BI "\-R " "filename"
+Read symbol names and their addresses from \c
+.I filename\c
+\&, but do not
+relocate it or include it in the output. This allows your output file
+to refer symbolically to absolute locations of memory defined in other
+programs.
+
+.TP
+.B \-relax
+An option with machine dependent effects. Currently this option is only
+supported on the H8/300.
+
+On some platforms, use this option to perform global optimizations that
+become possible when the linker resolves addressing in your program, such
+as relaxing address modes and synthesizing new instructions in the
+output object file.
+
+On platforms where this is not supported, `\|\c
+.B \-relax\c
+\&\|' is accepted, but has no effect.
+
+.TP
+.B \-r
+Generates relocatable output\(em\&i.e., generate an output file that can in
+turn serve as input to \c
+.B ld\c
+\&. This is often called \c
+.I partial
+linking\c
+\&. As a side effect, in environments that support standard Unix
+magic numbers, this option also sets the output file's magic number to
+\c
+.B OMAGIC\c
+\&.
+If this option is not specified, an absolute file is produced. When
+linking C++ programs, this option \c
+.I will not\c
+\& resolve references to
+constructors; \c
+.B \-Ur\c
+\& is an alternative.
+
+This option does the same as \c
+.B \-i\c
+\&.
+
+.TP
+.B \-rpath\ \fIdirectory
+Add a directory to the runtime library search path. This is used when
+linking an ELF executable with shared objects. All
+.B \-rpath
+arguments are concatenated and passed to the runtime linker, which uses
+them to locate shared objects at runtime. The
+.B \-rpath
+option is also used when locating shared objects which are needed by
+shared objects explicitly included in the link; see the description of
+the
+.B \-rpath\-link
+option. If
+.B \-rpath
+is not used when linking an ELF executable, the contents of the
+environment variable
+.B LD_RUN_PATH
+will be used if it is defined.
+
+The
+.B \-rpath
+option may also be used on SunOS. By default, on SunOS, the linker
+will form a runtime search path out of all the
+.B \-L
+options it is given. If a
+.B \-rpath
+option is used, the runtime search path will be formed exclusively
+using the
+.B \-rpath
+options, ignoring
+the
+.B \-L
+options. This can be useful when using gcc, which adds many
+.B \-L
+options which may be on NFS mounted filesystems.
+
+.TP
+.B \-rpath\-link\ \fIdirectory
+When using ELF or SunOS, one shared library may require another. This
+happens when an
+.B ld\ \-shared
+link includes a shared library as one of the input files.
+
+When the linker encounters such a dependency when doing a non-shared,
+non-relocateable link, it will automatically try to locate the required
+shared library and include it in the link, if it is not included
+explicitly. In such a case, the
+.B \-rpath\-link
+option specifies the first set of directories to search. The
+.B \-rpath\-link
+option may specify a sequence of directory names either by specifying
+a list of names separated by colons, or by appearing multiple times.
+
+If the required shared library is not found, the linker will issue a
+warning and continue with the link.
+
+.TP
+.B \-S
+Omits debugger symbol information (but not all symbols) from the output file.
+
+.TP
+.B \-s
+Omits all symbol information from the output file.
+
+.TP
+.B \-shared
+Create a shared library. This is currently only supported on ELF and
+SunOS platforms (on SunOS it is not required, as the linker will
+automatically create a shared library when there are undefined symbols
+and the
+.B \-e
+option is not used).
+
+.TP
+.B \-sort\-common
+Normally, when
+.B ld
+places the global common symbols in the appropriate output sections,
+it sorts them by size. First come all the one byte symbols, then all
+the two bytes, then all the four bytes, and then everything else.
+This is to prevent gaps between symbols due to
+alignment constraints. This option disables that sorting.
+
+.TP
+.B \-split\-by\-reloc\ \fIcount
+Trys to creates extra sections in the output file so that no single
+output section in the file contains more than
+.I count
+relocations.
+This is useful when generating huge relocatable for downloading into
+certain real time kernels with the COFF object file format; since COFF
+cannot represent more than 65535 relocations in a single section.
+Note that this will fail to work with object file formats which do not
+support arbitrary sections. The linker will not split up individual
+input sections for redistribution, so if a single input section
+contains more than
+.I count
+relocations one output section will contain that many relocations.
+
+.TP
+.B \-split\-by\-file
+Similar to
+.B \-split\-by\-reloc
+but creates a new output section for each input file.
+
+.TP
+.BI "\-Tbss " "org"\c
+.TP
+.BI "\-Tdata " "org"\c
+.TP
+.BI "\-Ttext " "org"\c
+Use \c
+.I org\c
+\& as the starting address for\(em\&respectively\(em\&the
+\c
+.B bss\c
+\&, \c
+.B data\c
+\&, or the \c
+.B text\c
+\& segment of the output file.
+\c
+.I org\c
+\& must be a hexadecimal integer.
+
+.TP
+.BI "\-T " "commandfile"
+Equivalent to \c
+.B \-c \c
+.I commandfile\c
+\&\c
+\&; supported for compatibility with
+other tools.
+
+.TP
+.B \-t
+Prints names of input files as \c
+.B ld\c
+\& processes them.
+
+.TP
+.BI "\-u " "sym"
+Forces \c
+.I sym\c
+\& to be entered in the output file as an undefined symbol.
+This may, for example, trigger linking of additional modules from
+standard libraries. \c
+.B \-u\c
+\& may be repeated with different option
+arguments to enter additional undefined symbols.
+
+.TP
+.B \-Ur
+For anything other than C++ programs, this option is equivalent to
+\c
+.B \-r\c
+\&: it generates relocatable output\(em\&i.e., an output file that can in
+turn serve as input to \c
+.B ld\c
+\&. When linking C++ programs, \c
+.B \-Ur
+.I will\c
+\& resolve references to constructors, unlike \c
+.B \-r\c
+\&.
+
+.TP
+.B \-\-verbose
+Display the version number for \c
+.B ld
+and list the supported emulations.
+Display which input files can and can not be opened.
+
+.TP
+.B \-v, \-V
+Display the version number for \c
+.B ld\c
+\&.
+The
+.B \-V
+option also lists the supported emulations.
+
+.TP
+.B \-\-version
+Display the version number for \c
+.B ld
+and exit.
+
+.TP
+.B \-warn\-common
+Warn when a common symbol is combined with another common symbol or with
+a symbol definition. Unix linkers allow this somewhat sloppy practice,
+but linkers on some other operating systems do not. This option allows
+you to find potential problems from combining global symbols.
+
+.TP
+.B \-warn\-constructors
+Warn if any global constructors are used. This is only useful for a
+few object file formats. For formats like COFF or ELF, the linker can
+not detect the use of global constructors.
+
+.TP
+.B \-warn\-multiple\-gp
+Warn if the output file requires multiple global-pointer values. This
+option is only meaningful for certain processors, such as the Alpha.
+
+.TP
+.B \-warn\-once
+Only warn once for each undefined symbol, rather than once per module
+which refers to it.
+
+.TP
+.B \-warn\-section\-align
+Warn if the address of an output section is changed because of
+alignment. Typically, the alignment will be set by an input section.
+The address will only be changed if it not explicitly specified; that
+is, if the SECTIONS command does not specify a start address for the
+section.
+
+.TP
+.B \-\-whole\-archive
+For each archive mentioned on the command line after the
+.B \-\-whole\-archive
+option, include every object file in the archive in the link, rather
+than searching the archive for the required object files. This is
+normally used to turn an archive file into a shared library, forcing
+every object to be included in the resulting shared library.
+
+.TP
+.B \-\-no\-whole\-archive
+Turn off the effect of the
+.B \-\-whole\-archive
+option for archives which appear later on the command line.
+
+.TP
+.BI "--wrap " "symbol"
+Use a wrapper function for
+.I symbol.
+Any undefined reference to
+.I symbol
+will be resolved to
+.BI "__wrap_" "symbol".
+Any undefined reference to
+.BI "__real_" "symbol"
+will be resolved to
+.I symbol.
+
+.TP
+.B \-X
+Delete all temporary local symbols. For most targets, this is all local
+symbols whose names begin with `\|\c
+.B L\c
+\|'.
+
+.TP
+.B \-x
+Delete all local symbols.
+
+.PP
+
+.SH ENVIRONMENT
+\c
+You can change the behavior of
+.B ld\c
+\& with the environment variable \c
+.B GNUTARGET\c
+\&.
+
+\c
+.B GNUTARGET\c
+\& determines the input-file object format if you don't
+use \c
+.B \-b\c
+\& (or its synonym \c
+.B \-format\c
+\&). Its value should be one
+of the BFD names for an input format. If there is no
+\c
+.B GNUTARGET\c
+\& in the environment, \c
+.B ld\c
+\& uses the natural format
+of the host. If \c
+.B GNUTARGET\c
+\& is set to \c
+.B default\c
+\& then BFD attempts to discover the
+input format by examining binary input files; this method often
+succeeds, but there are potential ambiguities, since there is no method
+of ensuring that the magic number used to flag object-file formats is
+unique. However, the configuration procedure for BFD on each system
+places the conventional format for that system first in the search-list,
+so ambiguities are resolved in favor of convention.
+
+.PP
+
+.SH "SEE ALSO"
+
+.BR objdump ( 1 )
+.br
+.br
+.RB "`\|" ld "\|' and `\|" binutils "\|'"
+entries in
+.B info\c
+.br
+.I
+ld: the GNU linker\c
+, Steve Chamberlain and Roland Pesch;
+.I
+The GNU Binary Utilities\c
+, Roland H. Pesch.
+
+.SH COPYING
+Copyright (c) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+.PP
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+.PP
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+.PP
+Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be included in
+translations approved by the Free Software Foundation instead of in
+the original English.
diff --git a/ld/ld.h b/ld/ld.h
new file mode 100644
index 00000000000..bca7462dc4f
--- /dev/null
+++ b/ld/ld.h
@@ -0,0 +1,226 @@
+/* ld.h -- general linker header file
+ Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef LD_H
+#define LD_H
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+/* Look in this environment name for the linker to pretend to be */
+#define EMULATION_ENVIRON "LDEMULATION"
+/* If in there look for the strings: */
+
+/* Look in this variable for a target format */
+#define TARGET_ENVIRON "GNUTARGET"
+
+/* Input sections which are put in a section of this name are actually
+ discarded. */
+#define DISCARD_SECTION_NAME "/DISCARD/"
+
+/* A wildcard specification. This is only used in ldgram.y, but it
+ winds up in ldgram.h, so we need to define it outside. */
+
+struct wildcard_spec
+{
+ const char *name;
+ const char *exclude_name;
+ boolean sorted;
+};
+
+/* Extra information we hold on sections */
+typedef struct user_section_struct
+{
+ /* Pointer to the section where this data will go */
+ struct lang_input_statement_struct *file;
+} section_userdata_type;
+
+
+#define get_userdata(x) ((x)->userdata)
+
+#define BYTE_SIZE (1)
+#define SHORT_SIZE (2)
+#define LONG_SIZE (4)
+#define QUAD_SIZE (8)
+
+/* ALIGN macro changed to ALIGN_N to avoid */
+/* conflict in /usr/include/machine/machparam.h */
+/* WARNING: If THIS is a 64 bit address and BOUNDARY is a 32 bit int,
+ you must coerce boundary to the same type as THIS.
+ ??? Is there a portable way to avoid this. */
+#define ALIGN_N(this, boundary) \
+ ((( (this) + ((boundary) -1)) & (~((boundary)-1))))
+
+typedef struct
+{
+ /* 1 => assign space to common symbols even if `relocatable_output'. */
+ boolean force_common_definition;
+ boolean relax;
+
+ /* Name of runtime interpreter to invoke. */
+ char *interpreter;
+
+ /* Name to give runtime libary from the -soname argument. */
+ char *soname;
+
+ /* Runtime library search path from the -rpath argument. */
+ char *rpath;
+
+ /* Link time runtime library search path from the -rpath-link
+ argument. */
+ char *rpath_link;
+
+ /* Big or little endian as set on command line. */
+ enum { ENDIAN_UNSET = 0, ENDIAN_BIG, ENDIAN_LITTLE } endian;
+
+ /* If true, export all symbols in the dynamic symbol table of an ELF
+ executable. */
+ boolean export_dynamic;
+
+ /* If true, build MIPS embedded PIC relocation tables in the output
+ file. */
+ boolean embedded_relocs;
+
+ /* If true, force generation of a file with a .exe file. */
+ boolean force_exe_suffix;
+
+ /* If true, generate a cross reference report. */
+ boolean cref;
+
+ /* If true (which is the default), warn about mismatched input
+ files. */
+ boolean warn_mismatch;
+
+ /* Remove unreferenced sections? */
+ boolean gc_sections;
+
+ /* Name of shared object whose symbol table should be filtered with
+ this shared object. From the --filter option. */
+ char *filter_shlib;
+
+ /* Name of shared object for whose symbol table this shared object
+ is an auxiliary filter. From the --auxiliary option. */
+ char **auxiliary_filters;
+
+ /* A version symbol to be applied to the symbol names found in the
+ .exports sections. */
+ char *version_exports_section;
+
+ /* If true (the default) check section addresses, once compute,
+ fpor overlaps. */
+ boolean check_section_addresses;
+
+} args_type;
+
+extern args_type command_line;
+
+typedef int token_code_type;
+
+typedef struct
+{
+ bfd_size_type specified_data_size;
+ boolean magic_demand_paged;
+ boolean make_executable;
+
+ /* If true, doing a dynamic link. */
+ boolean dynamic_link;
+
+ /* If true, -shared is supported. */
+ /* ??? A better way to do this is perhaps to define this in the
+ ld_emulation_xfer_struct since this is really a target dependent
+ parameter. */
+ boolean has_shared;
+
+ /* If true, build constructors. */
+ boolean build_constructors;
+
+ /* If true, warn about any constructors. */
+ boolean warn_constructors;
+
+ /* If true, warn about merging common symbols with others. */
+ boolean warn_common;
+
+ /* If true, only warn once about a particular undefined symbol. */
+ boolean warn_once;
+
+ /* If true, warn if multiple global-pointers are needed (Alpha
+ only). */
+ boolean warn_multiple_gp;
+
+ /* If true, warn if the starting address of an output section
+ changes due to the alignment of an input section. */
+ boolean warn_section_align;
+
+ boolean sort_common;
+
+ boolean text_read_only;
+
+ char *map_filename;
+ FILE *map_file;
+
+ boolean stats;
+
+ int split_by_reloc;
+ boolean split_by_file;
+} ld_config_type;
+
+extern ld_config_type config;
+
+typedef enum
+{
+ lang_first_phase_enum,
+ lang_allocating_phase_enum,
+ lang_final_phase_enum
+} lang_phase_type;
+
+extern boolean had_script;
+extern boolean force_make_executable;
+
+/* Non-zero if we are processing a --defsym from the command line. */
+extern int parsing_defsym;
+
+extern int yyparse PARAMS ((void));
+
+extern void add_cref PARAMS ((const char *, bfd *, asection *, bfd_vma));
+extern void output_cref PARAMS ((FILE *));
+extern void check_nocrossrefs PARAMS ((void));
+
+#endif
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
new file mode 100644
index 00000000000..027f196d599
--- /dev/null
+++ b/ld/ld.texinfo
@@ -0,0 +1,4305 @@
+\input texinfo
+@setfilename ld.info
+@syncodeindex ky cp
+@include configdoc.texi
+@c (configdoc.texi is generated by the Makefile)
+@include ldver.texi
+
+@c @smallbook
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Ld: (ld). The GNU linker.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This file documents the @sc{gnu} linker LD version @value{VERSION}.
+
+Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+@end ifinfo
+@iftex
+@finalout
+@setchapternewpage odd
+@settitle Using LD, the GNU linker
+@titlepage
+@title Using ld
+@subtitle The GNU linker
+@sp 1
+@subtitle @code{ld} version 2
+@subtitle Version @value{VERSION}
+@author Steve Chamberlain
+@author Ian Lance Taylor
+@author Cygnus Solutions
+@page
+
+@tex
+{\parskip=0pt
+\hfill Cygnus Solutions\par
+\hfill ian\@cygnus.com, doc\@cygnus.com\par
+\hfill {\it Using LD, the GNU linker}\par
+\hfill Edited by Jeffrey Osier (jeffrey\@cygnus.com)\par
+}
+\global\parindent=0pt % Steve likes it this way.
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+@end iftex
+@c FIXME: Talk about importance of *order* of args, cmds to linker!
+
+@ifinfo
+@node Top
+@top Using ld
+This file documents the @sc{gnu} linker ld version @value{VERSION}.
+
+@menu
+* Overview:: Overview
+* Invocation:: Invocation
+* Scripts:: Linker Scripts
+@ifset GENERIC
+* Machine Dependent:: Machine Dependent Features
+@end ifset
+@ifclear GENERIC
+@ifset H8300
+* H8/300:: ld and the H8/300
+@end ifset
+@ifset Hitachi
+* Hitachi:: ld and other Hitachi micros
+@end ifset
+@ifset I960
+* i960:: ld and the Intel 960 family
+@end ifset
+@end ifclear
+@ifclear SingleFormat
+* BFD:: BFD
+@end ifclear
+@c Following blank line required for remaining bug in makeinfo conds/menus
+
+* Reporting Bugs:: Reporting Bugs
+* MRI:: MRI Compatible Script Files
+* Index:: Index
+@end menu
+@end ifinfo
+
+@node Overview
+@chapter Overview
+
+@cindex @sc{gnu} linker
+@cindex what is this?
+@code{ld} combines a number of object and archive files, relocates
+their data and ties up symbol references. Usually the last step in
+compiling a program is to run @code{ld}.
+
+@code{ld} accepts Linker Command Language files written in
+a superset of AT&T's Link Editor Command Language syntax,
+to provide explicit and total control over the linking process.
+
+@ifclear SingleFormat
+This version of @code{ld} uses the general purpose BFD libraries
+to operate on object files. This allows @code{ld} to read, combine, and
+write object files in many different formats---for example, COFF or
+@code{a.out}. Different formats may be linked together to produce any
+available kind of object file. @xref{BFD}, for more information.
+@end ifclear
+
+Aside from its flexibility, the @sc{gnu} linker is more helpful than other
+linkers in providing diagnostic information. Many linkers abandon
+execution immediately upon encountering an error; whenever possible,
+@code{ld} continues executing, allowing you to identify other errors
+(or, in some cases, to get an output file in spite of the error).
+
+@node Invocation
+@chapter Invocation
+
+The @sc{gnu} linker @code{ld} is meant to cover a broad range of situations,
+and to be as compatible as possible with other linkers. As a result,
+you have many choices to control its behavior.
+
+@ifset UsesEnvVars
+@menu
+* Options:: Command Line Options
+* Environment:: Environment Variables
+@end menu
+
+@node Options
+@section Command Line Options
+@end ifset
+
+@cindex command line
+@cindex options
+The linker supports a plethora of command-line options, but in actual
+practice few of them are used in any particular context.
+@cindex standard Unix system
+For instance, a frequent use of @code{ld} is to link standard Unix
+object files on a standard, supported Unix system. On such a system, to
+link a file @code{hello.o}:
+
+@smallexample
+ld -o @var{output} /lib/crt0.o hello.o -lc
+@end smallexample
+
+This tells @code{ld} to produce a file called @var{output} as the
+result of linking the file @code{/lib/crt0.o} with @code{hello.o} and
+the library @code{libc.a}, which will come from the standard search
+directories. (See the discussion of the @samp{-l} option below.)
+
+The command-line options to @code{ld} may be specified in any order, and
+may be repeated at will. Repeating most options with a different
+argument will either have no further effect, or override prior
+occurrences (those further to the left on the command line) of that
+option. Options which may be meaningfully specified more than once are
+noted in the descriptions below.
+
+@cindex object files
+Non-option arguments are objects files which are to be linked together.
+They may follow, precede, or be mixed in with command-line options,
+except that an object file argument may not be placed between an option
+and its argument.
+
+Usually the linker is invoked with at least one object file, but you can
+specify other forms of binary input files using @samp{-l}, @samp{-R},
+and the script command language. If @emph{no} binary input files at all
+are specified, the linker does not produce any output, and issues the
+message @samp{No input files}.
+
+If the linker can not recognize the format of an object file, it will
+assume that it is a linker script. A script specified in this way
+augments the main linker script used for the link (either the default
+linker script or the one specified by using @samp{-T}). This feature
+permits the linker to link against a file which appears to be an object
+or an archive, but actually merely defines some symbol values, or uses
+@code{INPUT} or @code{GROUP} to load other objects. Note that
+specifying a script in this way should only be used to augment the main
+linker script; if you want to use some command that logically can only
+appear once, such as the @code{SECTIONS} or @code{MEMORY} command, you
+must replace the default linker script using the @samp{-T} option.
+@xref{Scripts}.
+
+For options whose names are a single letter,
+option arguments must either follow the option letter without intervening
+whitespace, or be given as separate arguments immediately following the
+option that requires them.
+
+For options whose names are multiple letters, either one dash or two can
+precede the option name; for example, @samp{--oformat} and
+@samp{--oformat} are equivalent. Arguments to multiple-letter options
+must either be separated from the option name by an equals sign, or be
+given as separate arguments immediately following the option that
+requires them. For example, @samp{--oformat srec} and
+@samp{--oformat=srec} are equivalent. Unique abbreviations of the names
+of multiple-letter options are accepted.
+
+@table @code
+@kindex -a@var{keyword}
+@item -a@var{keyword}
+This option is supported for HP/UX compatibility. The @var{keyword}
+argument must be one of the strings @samp{archive}, @samp{shared}, or
+@samp{default}. @samp{-aarchive} is functionally equivalent to
+@samp{-Bstatic}, and the other two keywords are functionally equivalent
+to @samp{-Bdynamic}. This option may be used any number of times.
+
+@ifset I960
+@cindex architectures
+@kindex -A@var{arch}
+@item -A@var{architecture}
+@kindex --architecture=@var{arch}
+@itemx --architecture=@var{architecture}
+In the current release of @code{ld}, this option is useful only for the
+Intel 960 family of architectures. In that @code{ld} configuration, the
+@var{architecture} argument identifies the particular architecture in
+the 960 family, enabling some safeguards and modifying the
+archive-library search path. @xref{i960,,@code{ld} and the Intel 960
+family}, for details.
+
+Future releases of @code{ld} may support similar functionality for
+other architecture families.
+@end ifset
+
+@ifclear SingleFormat
+@cindex binary input format
+@kindex -b @var{format}
+@kindex --format=@var{format}
+@cindex input format
+@cindex input format
+@item -b @var{input-format}
+@itemx --format=@var{input-format}
+@code{ld} may be configured to support more than one kind of object
+file. If your @code{ld} is configured this way, you can use the
+@samp{-b} option to specify the binary format for input object files
+that follow this option on the command line. Even when @code{ld} is
+configured to support alternative object formats, you don't usually need
+to specify this, as @code{ld} should be configured to expect as a
+default input format the most usual format on each machine.
+@var{input-format} is a text string, the name of a particular format
+supported by the BFD libraries. (You can list the available binary
+formats with @samp{objdump -i}.)
+@xref{BFD}.
+
+You may want to use this option if you are linking files with an unusual
+binary format. You can also use @samp{-b} to switch formats explicitly (when
+linking object files of different formats), by including
+@samp{-b @var{input-format}} before each group of object files in a
+particular format.
+
+The default format is taken from the environment variable
+@code{GNUTARGET}.
+@ifset UsesEnvVars
+@xref{Environment}.
+@end ifset
+You can also define the input format from a script, using the command
+@code{TARGET}; see @ref{Format Commands}.
+@end ifclear
+
+@kindex -c @var{MRI-cmdfile}
+@kindex --mri-script=@var{MRI-cmdfile}
+@cindex compatibility, MRI
+@item -c @var{MRI-commandfile}
+@itemx --mri-script=@var{MRI-commandfile}
+For compatibility with linkers produced by MRI, @code{ld} accepts script
+files written in an alternate, restricted command language, described in
+@ref{MRI,,MRI Compatible Script Files}. Introduce MRI script files with
+the option @samp{-c}; use the @samp{-T} option to run linker
+scripts written in the general-purpose @code{ld} scripting language.
+If @var{MRI-cmdfile} does not exist, @code{ld} looks for it in the directories
+specified by any @samp{-L} options.
+
+@cindex common allocation
+@kindex -d
+@kindex -dc
+@kindex -dp
+@item -d
+@itemx -dc
+@itemx -dp
+These three options are equivalent; multiple forms are supported for
+compatibility with other linkers. They assign space to common symbols
+even if a relocatable output file is specified (with @samp{-r}). The
+script command @code{FORCE_COMMON_ALLOCATION} has the same effect.
+@xref{Miscellaneous Commands}.
+
+@cindex entry point, from command line
+@kindex -e @var{entry}
+@kindex --entry=@var{entry}
+@item -e @var{entry}
+@itemx --entry=@var{entry}
+Use @var{entry} as the explicit symbol for beginning execution of your
+program, rather than the default entry point. If there is no symbol
+named @var{entry}, the linker will try to parse @var{entry} as a number,
+and use that as the entry address (the number will be interpreted in
+base 10; you may use a leading @samp{0x} for base 16, or a leading
+@samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults
+and other ways of specifying the entry point.
+
+@cindex dynamic symbol table
+@kindex -E
+@kindex --export-dynamic
+@item -E
+@itemx --export-dynamic
+When creating a dynamically linked executable, add all symbols to the
+dynamic symbol table. The dynamic symbol table is the set of symbols
+which are visible from dynamic objects at run time.
+
+If you do not use this option, the dynamic symbol table will normally
+contain only those symbols which are referenced by some dynamic object
+mentioned in the link.
+
+If you use @code{dlopen} to load a dynamic object which needs to refer
+back to the symbols defined by the program, rather than some other
+dynamic object, then you will probably need to use this option when
+linking the program itself.
+
+@cindex big-endian objects
+@cindex endianness
+@kindex -EB
+@item -EB
+Link big-endian objects. This affects the default output format.
+
+@cindex little-endian objects
+@kindex -EL
+@item -EL
+Link little-endian objects. This affects the default output format.
+
+@kindex -f
+@kindex --auxiliary
+@item -f
+@itemx --auxiliary @var{name}
+When creating an ELF shared object, set the internal DT_AUXILIARY field
+to the specified name. This tells the dynamic linker that the symbol
+table of the shared object should be used as an auxiliary filter on the
+symbol table of the shared object @var{name}.
+
+If you later link a program against this filter object, then, when you
+run the program, the dynamic linker will see the DT_AUXILIARY field. If
+the dynamic linker resolves any symbols from the filter object, it will
+first check whether there is a definition in the shared object
+@var{name}. If there is one, it will be used instead of the definition
+in the filter object. The shared object @var{name} need not exist.
+Thus the shared object @var{name} may be used to provide an alternative
+implementation of certain functions, perhaps for debugging or for
+machine specific performance.
+
+This option may be specified more than once. The DT_AUXILIARY entries
+will be created in the order in which they appear on the command line.
+
+@kindex -F
+@kindex --filter
+@item -F @var{name}
+@itemx --filter @var{name}
+When creating an ELF shared object, set the internal DT_FILTER field to
+the specified name. This tells the dynamic linker that the symbol table
+of the shared object which is being created should be used as a filter
+on the symbol table of the shared object @var{name}.
+
+If you later link a program against this filter object, then, when you
+run the program, the dynamic linker will see the DT_FILTER field. The
+dynamic linker will resolve symbols according to the symbol table of the
+filter object as usual, but it will actually link to the definitions
+found in the shared object @var{name}. Thus the filter object can be
+used to select a subset of the symbols provided by the object
+@var{name}.
+
+Some older linkers used the @code{-F} option throughout a compilation
+toolchain for specifying object-file format for both input and output
+object files. The @sc{gnu} linker uses other mechanisms for this
+purpose: the @code{-b}, @code{--format}, @code{--oformat} options, the
+@code{TARGET} command in linker scripts, and the @code{GNUTARGET}
+environment variable. The @sc{gnu} linker will ignore the @code{-F}
+option when not creating an ELF shared object.
+
+@kindex -g
+@item -g
+Ignored. Provided for compatibility with other tools.
+
+@kindex -G
+@kindex --gpsize
+@cindex object size
+@item -G@var{value}
+@itemx --gpsize=@var{value}
+Set the maximum size of objects to be optimized using the GP register to
+@var{size}. This is only meaningful for object file formats such as
+MIPS ECOFF which supports putting large and small objects into different
+sections. This is ignored for other object file formats.
+
+@cindex runtime library name
+@kindex -h@var{name}
+@kindex -soname=@var{name}
+@item -h@var{name}
+@itemx -soname=@var{name}
+When creating an ELF shared object, set the internal DT_SONAME field to
+the specified name. When an executable is linked with a shared object
+which has a DT_SONAME field, then when the executable is run the dynamic
+linker will attempt to load the shared object specified by the DT_SONAME
+field rather than the using the file name given to the linker.
+
+@kindex -i
+@cindex incremental link
+@item -i
+Perform an incremental link (same as option @samp{-r}).
+
+@cindex archive files, from cmd line
+@kindex -l@var{archive}
+@kindex --library=@var{archive}
+@item -l@var{archive}
+@itemx --library=@var{archive}
+Add archive file @var{archive} to the list of files to link. This
+option may be used any number of times. @code{ld} will search its
+path-list for occurrences of @code{lib@var{archive}.a} for every
+@var{archive} specified.
+
+On systems which support shared libraries, @code{ld} may also search for
+libraries with extensions other than @code{.a}. Specifically, on ELF
+and SunOS systems, @code{ld} will search a directory for a library with
+an extension of @code{.so} before searching for one with an extension of
+@code{.a}. By convention, a @code{.so} extension indicates a shared
+library.
+
+The linker will search an archive only once, at the location where it is
+specified on the command line. If the archive defines a symbol which
+was undefined in some object which appeared before the archive on the
+command line, the linker will include the appropriate file(s) from the
+archive. However, an undefined symbol in an object appearing later on
+the command line will not cause the linker to search the archive again.
+
+See the @code{-(} option for a way to force the linker to search
+archives multiple times.
+
+You may list the same archive multiple times on the command line.
+
+@ifset GENERIC
+This type of archive searching is standard for Unix linkers. However,
+if you are using @code{ld} on AIX, note that it is different from the
+behaviour of the AIX linker.
+@end ifset
+
+@cindex search directory, from cmd line
+@kindex -L@var{dir}
+@kindex --library-path=@var{dir}
+@item -L@var{searchdir}
+@itemx --library-path=@var{searchdir}
+Add path @var{searchdir} to the list of paths that @code{ld} will search
+for archive libraries and @code{ld} control scripts. You may use this
+option any number of times. The directories are searched in the order
+in which they are specified on the command line. Directories specified
+on the command line are searched before the default directories. All
+@code{-L} options apply to all @code{-l} options, regardless of the
+order in which the options appear.
+
+@ifset UsesEnvVars
+The default set of paths searched (without being specified with
+@samp{-L}) depends on which emulation mode @code{ld} is using, and in
+some cases also on how it was configured. @xref{Environment}.
+@end ifset
+
+The paths can also be specified in a link script with the
+@code{SEARCH_DIR} command. Directories specified this way are searched
+at the point in which the linker script appears in the command line.
+
+@cindex emulation
+@kindex -m @var{emulation}
+@item -m@var{emulation}
+Emulate the @var{emulation} linker. You can list the available
+emulations with the @samp{--verbose} or @samp{-V} options.
+
+If the @samp{-m} option is not used, the emulation is taken from the
+@code{LDEMULATION} environment variable, if that is defined.
+
+Otherwise, the default emulation depends upon how the linker was
+configured.
+
+@cindex link map
+@kindex -M
+@kindex --print-map
+@item -M
+@itemx --print-map
+Print a link map to the standard output. A link map provides
+information about the link, including the following:
+
+@itemize @bullet
+@item
+Where object files and symbols are mapped into memory.
+@item
+How common symbols are allocated.
+@item
+All archive members included in the link, with a mention of the symbol
+which caused the archive member to be brought in.
+@end itemize
+
+@kindex -n
+@cindex read-only text
+@cindex NMAGIC
+@kindex --nmagic
+@item -n
+@itemx --nmagic
+Set the text segment to be read only, and mark the output as
+@code{NMAGIC} if possible.
+
+@kindex -N
+@kindex --omagic
+@cindex read/write from cmd line
+@cindex OMAGIC
+@item -N
+@itemx --omagic
+Set the text and data sections to be readable and writable. Also, do
+not page-align the data segment. If the output format supports Unix
+style magic numbers, mark the output as @code{OMAGIC}.
+
+@kindex -o @var{output}
+@kindex --output=@var{output}
+@cindex naming the output file
+@item -o @var{output}
+@itemx --output=@var{output}
+Use @var{output} as the name for the program produced by @code{ld}; if this
+option is not specified, the name @file{a.out} is used by default. The
+script command @code{OUTPUT} can also specify the output file name.
+
+@kindex -O @var{level}
+@cindex generating optimized output
+@item -O @var{level}
+If @var{level} is a numeric values greater than zero @code{ld} optimizes
+the output. This might take significantly longer and therefore probably
+should only be enabled for the final binary.
+
+@cindex partial link
+@cindex relocatable output
+@kindex -r
+@kindex --relocateable
+@item -r
+@itemx --relocateable
+Generate relocatable output---i.e., generate an output file that can in
+turn serve as input to @code{ld}. This is often called @dfn{partial
+linking}. As a side effect, in environments that support standard Unix
+magic numbers, this option also sets the output file's magic number to
+@code{OMAGIC}.
+@c ; see @code{-N}.
+If this option is not specified, an absolute file is produced. When
+linking C++ programs, this option @emph{will not} resolve references to
+constructors; to do that, use @samp{-Ur}.
+
+This option does the same thing as @samp{-i}.
+
+@kindex -R @var{file}
+@kindex --just-symbols=@var{file}
+@cindex symbol-only input
+@item -R @var{filename}
+@itemx --just-symbols=@var{filename}
+Read symbol names and their addresses from @var{filename}, but do not
+relocate it or include it in the output. This allows your output file
+to refer symbolically to absolute locations of memory defined in other
+programs. You may use this option more than once.
+
+For compatibility with other ELF linkers, if the @code{-R} option is
+followed by a directory name, rather than a file name, it is treated as
+the @code{-rpath} option.
+
+@kindex -s
+@kindex --strip-all
+@cindex strip all symbols
+@item -s
+@itemx --strip-all
+Omit all symbol information from the output file.
+
+@kindex -S
+@kindex --strip-debug
+@cindex strip debugger symbols
+@item -S
+@itemx --strip-debug
+Omit debugger symbol information (but not all symbols) from the output file.
+
+@kindex -t
+@kindex --trace
+@cindex input files, displaying
+@item -t
+@itemx --trace
+Print the names of the input files as @code{ld} processes them.
+
+@kindex -T @var{script}
+@kindex --script=@var{script}
+@cindex script files
+@item -T @var{scriptfile}
+@itemx --script=@var{scriptfile}
+Use @var{scriptfile} as the linker script. This script replaces
+@code{ld}'s default linker script (rather than adding to it), so
+@var{commandfile} must specify everything necessary to describe the
+output file. You must use this option if you want to use a command
+which can only appear once in a linker script, such as the
+@code{SECTIONS} or @code{MEMORY} command. @xref{Scripts}. If
+@var{scriptfile} does not exist in the current directory, @code{ld}
+looks for it in the directories specified by any preceding @samp{-L}
+options. Multiple @samp{-T} options accumulate.
+
+@kindex -u @var{symbol}
+@kindex --undefined=@var{symbol}
+@cindex undefined symbol
+@item -u @var{symbol}
+@itemx --undefined=@var{symbol}
+Force @var{symbol} to be entered in the output file as an undefined
+symbol. Doing this may, for example, trigger linking of additional
+modules from standard libraries. @samp{-u} may be repeated with
+different option arguments to enter additional undefined symbols. This
+option is equivalent to the @code{EXTERN} linker script command.
+
+@kindex -Ur
+@cindex constructors
+@item -Ur
+For anything other than C++ programs, this option is equivalent to
+@samp{-r}: it generates relocatable output---i.e., an output file that can in
+turn serve as input to @code{ld}. When linking C++ programs, @samp{-Ur}
+@emph{does} resolve references to constructors, unlike @samp{-r}.
+It does not work to use @samp{-Ur} on files that were themselves linked
+with @samp{-Ur}; once the constructor table has been built, it cannot
+be added to. Use @samp{-Ur} only for the last partial link, and
+@samp{-r} for the others.
+
+@kindex -v
+@kindex -V
+@kindex --version
+@cindex version
+@item -v
+@itemx --version
+@itemx -V
+Display the version number for @code{ld}. The @code{-V} option also
+lists the supported emulations.
+
+@kindex -x
+@kindex --discard-all
+@cindex deleting local symbols
+@item -x
+@itemx --discard-all
+Delete all local symbols.
+
+@kindex -X
+@kindex --discard-locals
+@cindex local symbols, deleting
+@cindex L, deleting symbols beginning
+@item -X
+@itemx --discard-locals
+Delete all temporary local symbols. For most targets, this is all local
+symbols whose names begin with @samp{L}.
+
+@kindex -y @var{symbol}
+@kindex --trace-symbol=@var{symbol}
+@cindex symbol tracing
+@item -y @var{symbol}
+@itemx --trace-symbol=@var{symbol}
+Print the name of each linked file in which @var{symbol} appears. This
+option may be given any number of times. On many systems it is necessary
+to prepend an underscore.
+
+This option is useful when you have an undefined symbol in your link but
+don't know where the reference is coming from.
+
+@kindex -Y @var{path}
+@item -Y @var{path}
+Add @var{path} to the default library search path. This option exists
+for Solaris compatibility.
+
+@kindex -z @var{keyword}
+@item -z @var{keyword}
+This option is ignored for Solaris compatibility.
+
+@kindex -(
+@cindex groups of archives
+@item -( @var{archives} -)
+@itemx --start-group @var{archives} --end-group
+The @var{archives} should be a list of archive files. They may be
+either explicit file names, or @samp{-l} options.
+
+The specified archives are searched repeatedly until no new undefined
+references are created. Normally, an archive is searched only once in
+the order that it is specified on the command line. If a symbol in that
+archive is needed to resolve an undefined symbol referred to by an
+object in an archive that appears later on the command line, the linker
+would not be able to resolve that reference. By grouping the archives,
+they all be searched repeatedly until all possible references are
+resolved.
+
+Using this option has a significant performance cost. It is best to use
+it only when there are unavoidable circular references between two or
+more archives.
+
+@kindex -assert @var{keyword}
+@item -assert @var{keyword}
+This option is ignored for SunOS compatibility.
+
+@kindex -Bdynamic
+@kindex -dy
+@kindex -call_shared
+@item -Bdynamic
+@itemx -dy
+@itemx -call_shared
+Link against dynamic libraries. This is only meaningful on platforms
+for which shared libraries are supported. This option is normally the
+default on such platforms. The different variants of this option are
+for compatibility with various systems. You may use this option
+multiple times on the command line: it affects library searching for
+@code{-l} options which follow it.
+
+@kindex -Bstatic
+@kindex -dn
+@kindex -non_shared
+@kindex -static
+@item -Bstatic
+@itemx -dn
+@itemx -non_shared
+@itemx -static
+Do not link against shared libraries. This is only meaningful on
+platforms for which shared libraries are supported. The different
+variants of this option are for compatibility with various systems. You
+may use this option multiple times on the command line: it affects
+library searching for @code{-l} options which follow it.
+
+@kindex -Bsymbolic
+@item -Bsymbolic
+When creating a shared library, bind references to global symbols to the
+definition within the shared library, if any. Normally, it is possible
+for a program linked against a shared library to override the definition
+within the shared library. This option is only meaningful on ELF
+platforms which support shared libraries.
+
+@kindex --check-sections
+@kindex --no-check-sections
+@item --check-sections
+@item --no-check-sections
+Asks the linker @emph{not} to check section addresses after they have
+been assigned to see if there any overlaps. Normally the linker will
+perform this check, and if it finds any overlaps it will produce
+suitable error messages. The linker does know about, and does make
+allowances for sections in overlays. The default behaviour can be
+restored by using the command line switch @samp{--check-sections}.
+
+@cindex cross reference table
+@kindex --cref
+@item --cref
+Output a cross reference table. If a linker map file is being
+generated, the cross reference table is printed to the map file.
+Otherwise, it is printed on the standard output.
+
+The format of the table is intentionally simple, so that it may be
+easily processed by a script if necessary. The symbols are printed out,
+sorted by name. For each symbol, a list of file names is given. If the
+symbol is defined, the first file listed is the location of the
+definition. The remaining files contain references to the symbol.
+
+@cindex symbols, from command line
+@kindex --defsym @var{symbol}=@var{exp}
+@item --defsym @var{symbol}=@var{expression}
+Create a global symbol in the output file, containing the absolute
+address given by @var{expression}. You may use this option as many
+times as necessary to define multiple symbols in the command line. A
+limited form of arithmetic is supported for the @var{expression} in this
+context: you may give a hexadecimal constant or the name of an existing
+symbol, or use @code{+} and @code{-} to add or subtract hexadecimal
+constants or symbols. If you need more elaborate expressions, consider
+using the linker command language from a script (@pxref{Assignments,,
+Assignment: Symbol Definitions}). @emph{Note:} there should be no white
+space between @var{symbol}, the equals sign (``@key{=}''), and
+@var{expression}.
+
+@cindex demangling, from command line
+@kindex --demangle
+@kindex --no-demangle
+@item --demangle
+@itemx --no-demangle
+These options control whether to demangle symbol names in error messages
+and other output. When the linker is told to demangle, it tries to
+present symbol names in a readable fashion: it strips leading
+underscores if they are used by the object file format, and converts C++
+mangled symbol names into user readable names. The linker will demangle
+by default unless the environment variable @samp{COLLECT_NO_DEMANGLE} is
+set. These options may be used to override the default.
+
+@cindex dynamic linker, from command line
+@kindex --dynamic-linker @var{file}
+@item --dynamic-linker @var{file}
+Set the name of the dynamic linker. This is only meaningful when
+generating dynamically linked ELF executables. The default dynamic
+linker is normally correct; don't use this unless you know what you are
+doing.
+
+@cindex MIPS embedded PIC code
+@kindex --embedded-relocs
+@item --embedded-relocs
+This option is only meaningful when linking MIPS embedded PIC code,
+generated by the -membedded-pic option to the @sc{gnu} compiler and
+assembler. It causes the linker to create a table which may be used at
+runtime to relocate any data which was statically initialized to pointer
+values. See the code in testsuite/ld-empic for details.
+
+@kindex --force-exe-suffix
+@item --force-exe-suffix
+Make sure that an output file has a .exe suffix.
+
+If a successfully built fully linked output file does not have a
+@code{.exe} or @code{.dll} suffix, this option forces the linker to copy
+the output file to one of the same name with a @code{.exe} suffix. This
+option is useful when using unmodified Unix makefiles on a Microsoft
+Windows host, since some versions of Windows won't run an image unless
+it ends in a @code{.exe} suffix.
+
+@kindex --gc-sections
+@kindex --no-gc-sections
+@cindex garbage collection
+@item --no-gc-sections
+@itemx --gc-sections
+Enable garbage collection of unused input sections. It is ignored on
+targets that do not support this option. This option is not compatible
+with @samp{-r}, nor should it be used with dynamic linking. The default
+behaviour (of not performing this garbage collection) can be restored by
+specifying @samp{--no-gc-sections} on the command line.
+
+@cindex help
+@cindex usage
+@kindex --help
+@item --help
+Print a summary of the command-line options on the standard output and exit.
+
+@kindex -Map
+@item -Map @var{mapfile}
+Print a link map to the file @var{mapfile}. See the description of the
+@samp{-M} option, above.
+
+@cindex memory usage
+@kindex --no-keep-memory
+@item --no-keep-memory
+@code{ld} normally optimizes for speed over memory usage by caching the
+symbol tables of input files in memory. This option tells @code{ld} to
+instead optimize for memory usage, by rereading the symbol tables as
+necessary. This may be required if @code{ld} runs out of memory space
+while linking a large executable.
+
+@kindex --no-undefined
+@item --no-undefined
+Normally when creating a non-symbolic shared library, undefined symbols
+are allowed and left to be resolved by the runtime loader. This option
+disallows such undefined symbols.
+
+@kindex --no-warn-mismatch
+@item --no-warn-mismatch
+Normally @code{ld} will give an error if you try to link together input
+files that are mismatched for some reason, perhaps because they have
+been compiled for different processors or for different endiannesses.
+This option tells @code{ld} that it should silently permit such possible
+errors. This option should only be used with care, in cases when you
+have taken some special action that ensures that the linker errors are
+inappropriate.
+
+@kindex --no-whole-archive
+@item --no-whole-archive
+Turn off the effect of the @code{--whole-archive} option for subsequent
+archive files.
+
+@cindex output file after errors
+@kindex --noinhibit-exec
+@item --noinhibit-exec
+Retain the executable output file whenever it is still usable.
+Normally, the linker will not produce an output file if it encounters
+errors during the link process; it exits without writing an output file
+when it issues any error whatsoever.
+
+@ifclear SingleFormat
+@kindex --oformat
+@item --oformat @var{output-format}
+@code{ld} may be configured to support more than one kind of object
+file. If your @code{ld} is configured this way, you can use the
+@samp{--oformat} option to specify the binary format for the output
+object file. Even when @code{ld} is configured to support alternative
+object formats, you don't usually need to specify this, as @code{ld}
+should be configured to produce as a default output format the most
+usual format on each machine. @var{output-format} is a text string, the
+name of a particular format supported by the BFD libraries. (You can
+list the available binary formats with @samp{objdump -i}.) The script
+command @code{OUTPUT_FORMAT} can also specify the output format, but
+this option overrides it. @xref{BFD}.
+@end ifclear
+
+@kindex -qmagic
+@item -qmagic
+This option is ignored for Linux compatibility.
+
+@kindex -Qy
+@item -Qy
+This option is ignored for SVR4 compatibility.
+
+@kindex --relax
+@cindex synthesizing linker
+@cindex relaxing addressing modes
+@item --relax
+An option with machine dependent effects.
+@ifset GENERIC
+This option is only supported on a few targets.
+@end ifset
+@ifset H8300
+@xref{H8/300,,@code{ld} and the H8/300}.
+@end ifset
+@ifset I960
+@xref{i960,, @code{ld} and the Intel 960 family}.
+@end ifset
+
+
+On some platforms, the @samp{--relax} option performs global
+optimizations that become possible when the linker resolves addressing
+in the program, such as relaxing address modes and synthesizing new
+instructions in the output object file.
+
+On some platforms these link time global optimizations may make symbolic
+debugging of the resulting executable impossible.
+@ifset GENERIC
+This is known to be
+the case for the Matsushita MN10200 and MN10300 family of processors.
+@end ifset
+
+@ifset GENERIC
+On platforms where this is not supported, @samp{--relax} is accepted,
+but ignored.
+@end ifset
+
+@cindex retaining specified symbols
+@cindex stripping all but some symbols
+@cindex symbols, retaining selectively
+@item --retain-symbols-file @var{filename}
+Retain @emph{only} the symbols listed in the file @var{filename},
+discarding all others. @var{filename} is simply a flat file, with one
+symbol name per line. This option is especially useful in environments
+@ifset GENERIC
+(such as VxWorks)
+@end ifset
+where a large global symbol table is accumulated gradually, to conserve
+run-time memory.
+
+@samp{--retain-symbols-file} does @emph{not} discard undefined symbols,
+or symbols needed for relocations.
+
+You may only specify @samp{--retain-symbols-file} once in the command
+line. It overrides @samp{-s} and @samp{-S}.
+
+@ifset GENERIC
+@item -rpath @var{dir}
+@cindex runtime library search path
+@kindex -rpath
+Add a directory to the runtime library search path. This is used when
+linking an ELF executable with shared objects. All @code{-rpath}
+arguments are concatenated and passed to the runtime linker, which uses
+them to locate shared objects at runtime. The @code{-rpath} option is
+also used when locating shared objects which are needed by shared
+objects explicitly included in the link; see the description of the
+@code{-rpath-link} option. If @code{-rpath} is not used when linking an
+ELF executable, the contents of the environment variable
+@code{LD_RUN_PATH} will be used if it is defined.
+
+The @code{-rpath} option may also be used on SunOS. By default, on
+SunOS, the linker will form a runtime search patch out of all the
+@code{-L} options it is given. If a @code{-rpath} option is used, the
+runtime search path will be formed exclusively using the @code{-rpath}
+options, ignoring the @code{-L} options. This can be useful when using
+gcc, which adds many @code{-L} options which may be on NFS mounted
+filesystems.
+
+For compatibility with other ELF linkers, if the @code{-R} option is
+followed by a directory name, rather than a file name, it is treated as
+the @code{-rpath} option.
+@end ifset
+
+@ifset GENERIC
+@cindex link-time runtime library search path
+@kindex -rpath-link
+@item -rpath-link @var{DIR}
+When using ELF or SunOS, one shared library may require another. This
+happens when an @code{ld -shared} link includes a shared library as one
+of the input files.
+
+When the linker encounters such a dependency when doing a non-shared,
+non-relocatable link, it will automatically try to locate the required
+shared library and include it in the link, if it is not included
+explicitly. In such a case, the @code{-rpath-link} option
+specifies the first set of directories to search. The
+@code{-rpath-link} option may specify a sequence of directory names
+either by specifying a list of names separated by colons, or by
+appearing multiple times.
+
+The linker uses the following search paths to locate required shared
+libraries.
+@enumerate
+@item
+Any directories specified by @code{-rpath-link} options.
+@item
+Any directories specified by @code{-rpath} options. The difference
+between @code{-rpath} and @code{-rpath-link} is that directories
+specified by @code{-rpath} options are included in the executable and
+used at runtime, whereas the @code{-rpath-link} option is only effective
+at link time.
+@item
+On an ELF system, if the @code{-rpath} and @code{rpath-link} options
+were not used, search the contents of the environment variable
+@code{LD_RUN_PATH}.
+@item
+On SunOS, if the @code{-rpath} option was not used, search any
+directories specified using @code{-L} options.
+@item
+For a native linker, the contents of the environment variable
+@code{LD_LIBRARY_PATH}.
+@item
+The default directories, normally @file{/lib} and @file{/usr/lib}.
+@item
+For a native linker on an ELF system, if the file @file{/etc/ld.so.conf}
+exists, the list of directories found in that file.
+@end enumerate
+
+If the required shared library is not found, the linker will issue a
+warning and continue with the link.
+@end ifset
+
+@kindex -shared
+@kindex -Bshareable
+@item -shared
+@itemx -Bshareable
+@cindex shared libraries
+Create a shared library. This is currently only supported on ELF, XCOFF
+and SunOS platforms. On SunOS, the linker will automatically create a
+shared library if the @code{-e} option is not used and there are
+undefined symbols in the link.
+
+@item --sort-common
+@kindex --sort-common
+This option tells @code{ld} to sort the common symbols by size when it
+places them in the appropriate output sections. First come all the one
+byte symbols, then all the two bytes, then all the four bytes, and then
+everything else. This is to prevent gaps between symbols due to
+alignment constraints.
+
+@kindex --split-by-file
+@item --split-by-file
+Similar to @code{--split-by-reloc} but creates a new output section for
+each input file.
+
+@kindex --split-by-reloc
+@item --split-by-reloc @var{count}
+Trys to creates extra sections in the output file so that no single
+output section in the file contains more than @var{count} relocations.
+This is useful when generating huge relocatable for downloading into
+certain real time kernels with the COFF object file format; since COFF
+cannot represent more than 65535 relocations in a single section. Note
+that this will fail to work with object file formats which do not
+support arbitrary sections. The linker will not split up individual
+input sections for redistribution, so if a single input section contains
+more than @var{count} relocations one output section will contain that
+many relocations.
+
+@kindex --stats
+@item --stats
+Compute and display statistics about the operation of the linker, such
+as execution time and memory usage.
+
+@kindex --traditional-format
+@cindex traditional format
+@item --traditional-format
+For some targets, the output of @code{ld} is different in some ways from
+the output of some existing linker. This switch requests @code{ld} to
+use the traditional format instead.
+
+@cindex dbx
+For example, on SunOS, @code{ld} combines duplicate entries in the
+symbol string table. This can reduce the size of an output file with
+full debugging information by over 30 percent. Unfortunately, the SunOS
+@code{dbx} program can not read the resulting program (@code{gdb} has no
+trouble). The @samp{--traditional-format} switch tells @code{ld} to not
+combine duplicate entries.
+
+@kindex -Tbss @var{org}
+@kindex -Tdata @var{org}
+@kindex -Ttext @var{org}
+@cindex segment origins, cmd line
+@item -Tbss @var{org}
+@itemx -Tdata @var{org}
+@itemx -Ttext @var{org}
+Use @var{org} as the starting address for---respectively---the
+@code{bss}, @code{data}, or the @code{text} segment of the output file.
+@var{org} must be a single hexadecimal integer;
+for compatibility with other linkers, you may omit the leading
+@samp{0x} usually associated with hexadecimal values.
+
+@kindex --verbose
+@cindex verbose
+@item --dll-verbose
+@item --verbose
+Display the version number for @code{ld} and list the linker emulations
+supported. Display which input files can and cannot be opened. Display
+the linker script if using a default builtin script.
+
+@kindex --version-script=@var{version-scriptfile}
+@cindex version script, symbol versions
+@itemx --version-script=@var{version-scriptfile}
+Specify the name of a version script to the linker. This is typically
+used when creating shared libraries to specify additional information
+about the version heirarchy for the library being created. This option
+is only meaningful on ELF platforms which support shared libraries.
+@xref{VERSION}.
+
+@kindex --warn-comon
+@cindex warnings, on combining symbols
+@cindex combining symbols, warnings on
+@item --warn-common
+Warn when a common symbol is combined with another common symbol or with
+a symbol definition. Unix linkers allow this somewhat sloppy practice,
+but linkers on some other operating systems do not. This option allows
+you to find potential problems from combining global symbols.
+Unfortunately, some C libraries use this practice, so you may get some
+warnings about symbols in the libraries as well as in your programs.
+
+There are three kinds of global symbols, illustrated here by C examples:
+
+@table @samp
+@item int i = 1;
+A definition, which goes in the initialized data section of the output
+file.
+
+@item extern int i;
+An undefined reference, which does not allocate space.
+There must be either a definition or a common symbol for the
+variable somewhere.
+
+@item int i;
+A common symbol. If there are only (one or more) common symbols for a
+variable, it goes in the uninitialized data area of the output file.
+The linker merges multiple common symbols for the same variable into a
+single symbol. If they are of different sizes, it picks the largest
+size. The linker turns a common symbol into a declaration, if there is
+a definition of the same variable.
+@end table
+
+The @samp{--warn-common} option can produce five kinds of warnings.
+Each warning consists of a pair of lines: the first describes the symbol
+just encountered, and the second describes the previous symbol
+encountered with the same name. One or both of the two symbols will be
+a common symbol.
+
+@enumerate
+@item
+Turning a common symbol into a reference, because there is already a
+definition for the symbol.
+@smallexample
+@var{file}(@var{section}): warning: common of `@var{symbol}'
+ overridden by definition
+@var{file}(@var{section}): warning: defined here
+@end smallexample
+
+@item
+Turning a common symbol into a reference, because a later definition for
+the symbol is encountered. This is the same as the previous case,
+except that the symbols are encountered in a different order.
+@smallexample
+@var{file}(@var{section}): warning: definition of `@var{symbol}'
+ overriding common
+@var{file}(@var{section}): warning: common is here
+@end smallexample
+
+@item
+Merging a common symbol with a previous same-sized common symbol.
+@smallexample
+@var{file}(@var{section}): warning: multiple common
+ of `@var{symbol}'
+@var{file}(@var{section}): warning: previous common is here
+@end smallexample
+
+@item
+Merging a common symbol with a previous larger common symbol.
+@smallexample
+@var{file}(@var{section}): warning: common of `@var{symbol}'
+ overridden by larger common
+@var{file}(@var{section}): warning: larger common is here
+@end smallexample
+
+@item
+Merging a common symbol with a previous smaller common symbol. This is
+the same as the previous case, except that the symbols are
+encountered in a different order.
+@smallexample
+@var{file}(@var{section}): warning: common of `@var{symbol}'
+ overriding smaller common
+@var{file}(@var{section}): warning: smaller common is here
+@end smallexample
+@end enumerate
+
+@kindex --warn-constructors
+@item --warn-constructors
+Warn if any global constructors are used. This is only useful for a few
+object file formats. For formats like COFF or ELF, the linker can not
+detect the use of global constructors.
+
+@kindex --warn-multiple-gp
+@item --warn-multiple-gp
+Warn if multiple global pointer values are required in the output file.
+This is only meaningful for certain processors, such as the Alpha.
+Specifically, some processors put large-valued constants in a special
+section. A special register (the global pointer) points into the middle
+of this section, so that constants can be loaded efficiently via a
+base-register relative addressing mode. Since the offset in
+base-register relative mode is fixed and relatively small (e.g., 16
+bits), this limits the maximum size of the constant pool. Thus, in
+large programs, it is often necessary to use multiple global pointer
+values in order to be able to address all possible constants. This
+option causes a warning to be issued whenever this case occurs.
+
+@kindex --warn-once
+@cindex warnings, on undefined symbols
+@cindex undefined symbols, warnings on
+@item --warn-once
+Only warn once for each undefined symbol, rather than once per module
+which refers to it.
+
+@kindex --warn-section-align
+@cindex warnings, on section alignment
+@cindex section alignment, warnings on
+@item --warn-section-align
+Warn if the address of an output section is changed because of
+alignment. Typically, the alignment will be set by an input section.
+The address will only be changed if it not explicitly specified; that
+is, if the @code{SECTIONS} command does not specify a start address for
+the section (@pxref{SECTIONS}).
+
+@kindex --whole-archive
+@cindex including an entire archive
+@item --whole-archive
+For each archive mentioned on the command line after the
+@code{--whole-archive} option, include every object file in the archive
+in the link, rather than searching the archive for the required object
+files. This is normally used to turn an archive file into a shared
+library, forcing every object to be included in the resulting shared
+library. This option may be used more than once.
+
+@kindex --wrap
+@item --wrap @var{symbol}
+Use a wrapper function for @var{symbol}. Any undefined reference to
+@var{symbol} will be resolved to @code{__wrap_@var{symbol}}. Any
+undefined reference to @code{__real_@var{symbol}} will be resolved to
+@var{symbol}.
+
+This can be used to provide a wrapper for a system function. The
+wrapper function should be called @code{__wrap_@var{symbol}}. If it
+wishes to call the system function, it should call
+@code{__real_@var{symbol}}.
+
+Here is a trivial example:
+
+@smallexample
+void *
+__wrap_malloc (int c)
+@{
+ printf ("malloc called with %ld\n", c);
+ return __real_malloc (c);
+@}
+@end smallexample
+
+If you link other code with this file using @code{--wrap malloc}, then
+all calls to @code{malloc} will call the function @code{__wrap_malloc}
+instead. The call to @code{__real_malloc} in @code{__wrap_malloc} will
+call the real @code{malloc} function.
+
+You may wish to provide a @code{__real_malloc} function as well, so that
+links without the @code{--wrap} option will succeed. If you do this,
+you should not put the definition of @code{__real_malloc} in the same
+file as @code{__wrap_malloc}; if you do, the assembler may resolve the
+call before the linker has a chance to wrap it to @code{malloc}.
+
+@end table
+
+@subsection Options specific to i386 PE targets
+
+The i386 PE linker supports the @code{-shared} option, which causes
+the output to be a dynamically linked library (DLL) instead of a
+normal executable. You should name the output @code{*.dll} when you
+use this option. In addition, the linker fully supports the standard
+@code{*.def} files, which may be specified on the linker command line
+like an object file (in fact, it should precede archives it exports
+symbols from, to ensure that they get linked in, just like a normal
+object file).
+
+In addition to the options common to all targets, the i386 PE linker
+support additional command line options that are specific to the i386
+PE target. Options that take values may be separated from their
+values by either a space or an equals sign.
+
+@table @code
+
+@kindex --add-stdcall-alias
+@item --add-stdcall-alias
+If given, symbols with a stdcall suffix (@@@var{nn}) will be exported
+as-is and also with the suffix stripped.
+
+@kindex --base-file
+@item --base-file @var{file}
+Use @var{file} as the name of a file in which to save the base
+addresses of all the relocations needed for generating DLLs with
+@file{dlltool}.
+
+@kindex --dll
+@item --dll
+Create a DLL instead of a regular executable. You may also use
+@code{-shared} or specify a @code{LIBRARY} in a given @code{.def}
+file.
+
+@kindex --enable-stdcall-fixup
+@kindex --disable-stdcall-fixup
+@item --enable-stdcall-fixup
+@itemx --disable-stdcall-fixup
+If the link finds a symbol that it cannot resolve, it will attempt to
+do "fuzzy linking" by looking for another defined symbol that differs
+only in the format of the symbol name (cdecl vs stdcall) and will
+resolve that symbol by linking to the match. For example, the
+undefined symbol @code{_foo} might be linked to the function
+@code{_foo@@12}, or the undefined symbol @code{_bar@@16} might be linked
+to the function @code{_bar}. When the linker does this, it prints a
+warning, since it normally should have failed to link, but sometimes
+import libraries generated from third-party dlls may need this feature
+to be usable. If you specify @code{--enable-stdcall-fixup}, this
+feature is fully enabled and warnings are not printed. If you specify
+@code{--disable-stdcall-fixup}, this feature is disabled and such
+mismatches are considered to be errors.
+
+@cindex DLLs, creating
+@kindex --export-all-symbols
+@item --export-all-symbols
+If given, all global symbols in the objects used to build a DLL will
+be exported by the DLL. Note that this is the default if there
+otherwise wouldn't be any exported symbols. When symbols are
+explicitly exported via DEF files or implicitly exported via function
+attributes, the default is to not export anything else unless this
+option is given. Note that the symbols @code{DllMain@@12},
+@code{DllEntryPoint@@0}, and @code{impure_ptr} will not be automatically
+exported.
+
+@kindex --exclude-symbols
+@item --exclude-symbols @var{symbol,symbol,...}
+Specifies a list of symbols which should not be automatically
+exported. The symbol names may be delimited by commas or colons.
+
+@kindex --file-alignment
+@item --file-alignment
+Specify the file alignment. Sections in the file will always begin at
+file offsets which are multiples of this number. This defaults to
+512.
+
+@cindex heap size
+@kindex --heap
+@item --heap @var{reserve}
+@itemx --heap @var{reserve},@var{commit}
+Specify the amount of memory to reserve (and optionally commit) to be
+used as heap for this program. The default is 1Mb reserved, 4K
+committed.
+
+@cindex image base
+@kindex --image-base
+@item --image-base @var{value}
+Use @var{value} as the base address of your program or dll. This is
+the lowest memory location that will be used when your program or dll
+is loaded. To reduce the need to relocate and improve performance of
+your dlls, each should have a unique base address and not overlap any
+other dlls. The default is 0x400000 for executables, and 0x10000000
+for dlls.
+
+@kindex --kill-at
+@item --kill-at
+If given, the stdcall suffixes (@@@var{nn}) will be stripped from
+symbols before they are exported.
+
+@kindex --major-image-version
+@item --major-image-version @var{value}
+Sets the major number of the "image version". Defaults to 1.
+
+@kindex --major-os-version
+@item --major-os-version @var{value}
+Sets the major number of the "os version". Defaults to 4.
+
+@kindex --major-subsystem-version
+@item --major-subsystem-version @var{value}
+Sets the major number of the "subsystem version". Defaults to 4.
+
+@kindex --minor-image-version
+@item --minor-image-version @var{value}
+Sets the minor number of the "image version". Defaults to 0.
+
+@kindex --minor-os-version
+@item --minor-os-version @var{value}
+Sets the minor number of the "os version". Defaults to 0.
+
+@kindex --minor-subsystem-version
+@item --minor-subsystem-version @var{value}
+Sets the minor number of the "subsystem version". Defaults to 0.
+
+@cindex DEF files, creating
+@cindex DLLs, creating
+@kindex --output-def
+@item --output-def @var{file}
+The linker will create the file @var{file} which will contain a DEF
+file corresponding to the DLL the linker is generating. This DEF file
+(which should be called @code{*.def}) may be used to create an import
+library with @code{dlltool} or may be used as a reference to
+automatically or implicitly exported symbols.
+
+@kindex --section-alignment
+@item --section-alignment
+Sets the section alignment. Sections in memory will always begin at
+addresses which are a multiple of this number. Defaults to 0x1000.
+
+@cindex stack size
+@kindex --stack
+@item --stack @var{reserve}
+@itemx --stack @var{reserve},@var{commit}
+Specify the amount of memory to reserve (and optionally commit) to be
+used as stack for this program. The default is 32Mb reserved, 4K
+committed.
+
+@kindex --subsystem
+@item --subsystem @var{which}
+@itemx --subsystem @var{which}:@var{major}
+@itemx --subsystem @var{which}:@var{major}.@var{minor}
+Specifies the subsystem under which your program will execute. The
+legal values for @var{which} are @code{native}, @code{windows},
+@code{console}, and @code{posix}. You may optionally set the
+subsystem version also.
+
+@end table
+
+@ifset UsesEnvVars
+@node Environment
+@section Environment Variables
+
+You can change the behavior of @code{ld} with the environment variables
+@code{GNUTARGET}, @code{LDEMULATION}, and @code{COLLECT_NO_DEMANGLE}.
+
+@kindex GNUTARGET
+@cindex default input format
+@code{GNUTARGET} determines the input-file object format if you don't
+use @samp{-b} (or its synonym @samp{--format}). Its value should be one
+of the BFD names for an input format (@pxref{BFD}). If there is no
+@code{GNUTARGET} in the environment, @code{ld} uses the natural format
+of the target. If @code{GNUTARGET} is set to @code{default} then BFD
+attempts to discover the input format by examining binary input files;
+this method often succeeds, but there are potential ambiguities, since
+there is no method of ensuring that the magic number used to specify
+object-file formats is unique. However, the configuration procedure for
+BFD on each system places the conventional format for that system first
+in the search-list, so ambiguities are resolved in favor of convention.
+
+@kindex LDEMULATION
+@cindex default emulation
+@cindex emulation, default
+@code{LDEMULATION} determines the default emulation if you don't use the
+@samp{-m} option. The emulation can affect various aspects of linker
+behaviour, particularly the default linker script. You can list the
+available emulations with the @samp{--verbose} or @samp{-V} options. If
+the @samp{-m} option is not used, and the @code{LDEMULATION} environment
+variable is not defined, the default emulation depends upon how the
+linker was configured.
+@end ifset
+
+@kindex COLLECT_NO_DEMANGLE
+@cindex demangling, default
+Normally, the linker will default to demangling symbols. However, if
+@code{COLLECT_NO_DEMANGLE} is set in the environment, then it will
+default to not demangling symbols. This environment variable is used in
+a similar fashion by the @code{gcc} linker wrapper program. The default
+may be overridden by the @samp{--demangle} and @samp{--no-demangle}
+options.
+
+@node Scripts
+@chapter Linker Scripts
+
+@cindex scripts
+@cindex linker scripts
+@cindex command files
+Every link is controlled by a @dfn{linker script}. This script is
+written in the linker command language.
+
+The main purpose of the linker script is to describe how the sections in
+the input files should be mapped into the output file, and to control
+the memory layout of the output file. Most linker scripts do nothing
+more than this. However, when necessary, the linker script can also
+direct the linker to perform many other operations, using the commands
+described below.
+
+The linker always uses a linker script. If you do not supply one
+yourself, the linker will use a default script that is compiled into the
+linker executable. You can use the @samp{--verbose} command line option
+to display the default linker script. Certain command line options,
+such as @samp{-r} or @samp{-N}, will affect the default linker script.
+
+You may supply your own linker script by using the @samp{-T} command
+line option. When you do this, your linker script will replace the
+default linker script.
+
+You may also use linker scripts implicitly by naming them as input files
+to the linker, as though they were files to be linked. @xref{Implicit
+Linker Scripts}.
+
+@menu
+* Basic Script Concepts:: Basic Linker Script Concepts
+* Script Format:: Linker Script Format
+* Simple Example:: Simple Linker Script Example
+* Simple Commands:: Simple Linker Script Commands
+* Assignments:: Assigning Values to Symbols
+* SECTIONS:: SECTIONS Command
+* MEMORY:: MEMORY Command
+* PHDRS:: PHDRS Command
+* VERSION:: VERSION Command
+* Expressions:: Expressions in Linker Scripts
+* Implicit Linker Scripts:: Implicit Linker Scripts
+@end menu
+
+@node Basic Script Concepts
+@section Basic Linker Script Concepts
+@cindex linker script concepts
+We need to define some basic concepts and vocabulary in order to
+describe the linker script language.
+
+The linker combines input files into a single output file. The output
+file and each input file are in a special data format known as an
+@dfn{object file format}. Each file is called an @dfn{object file}.
+The output file is often called an @dfn{executable}, but for our
+purposes we will also call it an object file. Each object file has,
+among other things, a list of @dfn{sections}. We sometimes refer to a
+section in an input file as an @dfn{input section}; similarly, a section
+in the output file is an @dfn{output section}.
+
+Each section in an object file has a name and a size. Most sections
+also have an associated block of data, known as the @dfn{section
+contents}. A section may be marked as @dfn{loadable}, which mean that
+the contents should be loaded into memory when the output file is run.
+A section with no contents may be @dfn{allocatable}, which means that an
+area in memory should be set aside, but nothing in particular should be
+loaded there (in some cases this memory must be zeroed out). A section
+which is neither loadable nor allocatable typically contains some sort
+of debugging information.
+
+Every loadable or allocatable output section has two addresses. The
+first is the @dfn{VMA}, or virtual memory address. This is the address
+the section will have when the output file is run. The second is the
+@dfn{LMA}, or load memory address. This is the address at which the
+section will be loaded. In most cases the two addresses will be the
+same. An example of when they might be different is when a data section
+is loaded into ROM, and then copied into RAM when the program starts up
+(this technique is often used to initialize global variables in a ROM
+based system). In this case the ROM address would be the LMA, and the
+RAM address would be the VMA.
+
+You can see the sections in an object file by using the @code{objdump}
+program with the @samp{-h} option.
+
+Every object file also has a list of @dfn{symbols}, known as the
+@dfn{symbol table}. A symbol may be defined or undefined. Each symbol
+has a name, and each defined symbol has an address, among other
+information. If you compile a C or C++ program into an object file, you
+will get a defined symbol for every defined function and global or
+static variable. Every undefined function or global variable which is
+referenced in the input file will become an undefined symbol.
+
+You can see the symbols in an object file by using the @code{nm}
+program, or by using the @code{objdump} program with the @samp{-t}
+option.
+
+@node Script Format
+@section Linker Script Format
+@cindex linker script format
+Linker scripts are text files.
+
+You write a linker script as a series of commands. Each command is
+either a keyword, possibly followed by arguments, or an assignment to a
+symbol. You may separate commands using semicolons. Whitespace is
+generally ignored.
+
+Strings such as file or format names can normally be entered directly.
+If the file name contains a character such as a comma which would
+otherwise serve to separate file names, you may put the file name in
+double quotes. There is no way to use a double quote character in a
+file name.
+
+You may include comments in linker scripts just as in C, delimited by
+@samp{/*} and @samp{*/}. As in C, comments are syntactically equivalent
+to whitespace.
+
+@node Simple Example
+@section Simple Linker Script Example
+@cindex linker script example
+@cindex example of linker script
+Many linker scripts are fairly simple.
+
+The simplest possible linker script has just one command:
+@samp{SECTIONS}. You use the @samp{SECTIONS} command to describe the
+memory layout of the output file.
+
+The @samp{SECTIONS} command is a powerful command. Here we will
+describe a simple use of it. Let's assume your program consists only of
+code, initialized data, and uninitialized data. These will be in the
+@samp{.text}, @samp{.data}, and @samp{.bss} sections, respectively.
+Let's assume further that these are the only sections which appear in
+your input files.
+
+For this example, let's say that the code should be loaded at address
+0x10000, and that the data should start at address 0x8000000. Here is a
+linker script which will do that:
+@smallexample
+SECTIONS
+@{
+ . = 0x10000;
+ .text : @{ *(.text) @}
+ . = 0x8000000;
+ .data : @{ *(.data) @}
+ .bss : @{ *(.bss) @}
+@}
+@end smallexample
+
+You write the @samp{SECTIONS} command as the keyword @samp{SECTIONS},
+followed by a series of symbol assignments and output section
+descriptions enclosed in curly braces.
+
+The first line in the above example sets the special symbol @samp{.},
+which is the location counter. If you do not specify the address of an
+output section in some other way (other ways are described later), the
+address is set from the current value of the location counter. The
+location counter is then incremented by the size of the output section.
+
+The first line inside the @samp{SECTIONS} command of the above example
+sets the value of the special symbol @samp{.}, which is the location
+counter. If you do not specify the address of an output section in some
+other way (other ways are described later), the address is set from the
+current value of the location counter. The location counter is then
+incremented by the size of the output section. At the start of the
+@samp{SECTIONS} command, the location counter has the value @samp{0}.
+
+The second line defines an output section, @samp{.text}. The colon is
+required syntax which may be ignored for now. Within the curly braces
+after the output section name, you list the names of the input sections
+which should be placed into this output section. The @samp{*} is a
+wildcard which matches any file name. The expression @samp{*(.text)}
+means all @samp{.text} input sections in all input files.
+
+Since the location counter is @samp{0x10000} when the output section
+@samp{.text} is defined, the linker will set the address of the
+@samp{.text} section in the output file to be @samp{0x10000}.
+
+The remaining lines define the @samp{.data} and @samp{.bss} sections in
+the output file. The linker will place the @samp{.data} output section
+at address @samp{0x8000000}. After the linker places the @samp{.data}
+output section, the value of the location counter will be
+@samp{0x8000000} plus the size of the @samp{.data} output section. The
+effect is that the linker will place the @samp{.bss} output section
+immediately after the @samp{.data} output section in memory
+
+The linker will ensure that each output section has the required
+alignment, by increasing the location counter if necessary. In this
+example, the specified addresses for the @samp{.text} and @samp{.data}
+sections will probably satisfy any alignment constraints, but the linker
+may have to create a small gap between the @samp{.data} and @samp{.bss}
+sections.
+
+That's it! That's a simple and complete linker script.
+
+@node Simple Commands
+@section Simple Linker Script Commands
+@cindex linker script simple commands
+In this section we describe the simple linker script commands.
+
+@menu
+* Entry Point:: Setting the entry point
+* File Commands:: Commands dealing with files
+@ifclear SingleFormat
+* Format Commands:: Commands dealing with object file formats
+@end ifclear
+
+* Miscellaneous Commands:: Other linker script commands
+@end menu
+
+@node Entry Point
+@subsection Setting the entry point
+@kindex ENTRY(@var{symbol})
+@cindex start of execution
+@cindex first instruction
+@cindex entry point
+The first instruction to execute in a program is called the @dfn{entry
+point}. You can use the @code{ENTRY} linker script command to set the
+entry point. The argument is a symbol name:
+@smallexample
+ENTRY(@var{symbol})
+@end smallexample
+
+There are several ways to set the entry point. The linker will set the
+entry point by trying each of the following methods in order, and
+stopping when one of them succeeds:
+@itemize @bullet
+@item
+the @samp{-e} @var{entry} command-line option;
+@item
+the @code{ENTRY(@var{symbol})} command in a linker script;
+@item
+the value of the symbol @code{start}, if defined;
+@item
+the address of the first byte of the @samp{.text} section, if present;
+@item
+The address @code{0}.
+@end itemize
+
+@node File Commands
+@subsection Commands dealing with files
+@cindex linker script file commands
+Several linker script commands deal with files.
+
+@table @code
+@item INCLUDE @var{filename}
+@kindex INCLUDE @var{filename}
+@cindex including a linker script
+Include the linker script @var{filename} at this point. The file will
+be searched for in the current directory, and in any directory specified
+with the @code{-L} option. You can nest calls to @code{INCLUDE} up to
+10 levels deep.
+
+@item INPUT(@var{file}, @var{file}, @dots{})
+@itemx INPUT(@var{file} @var{file} @dots{})
+@kindex INPUT(@var{files})
+@cindex input files in linker scripts
+@cindex input object files in linker scripts
+@cindex linker script input object files
+The @code{INPUT} command directs the linker to include the named files
+in the link, as though they were named on the command line.
+
+For example, if you always want to include @file{subr.o} any time you do
+a link, but you can't be bothered to put it on every link command line,
+then you can put @samp{INPUT (subr.o)} in your linker script.
+
+In fact, if you like, you can list all of your input files in the linker
+script, and then invoke the linker with nothing but a @samp{-T} option.
+
+The linker will first try to open the file in the current directory. If
+it is not found, the linker will search through the archive library
+search path. See the description of @samp{-L} in @ref{Options,,Command
+Line Options}.
+
+If you use @samp{INPUT (-l@var{file})}, @code{ld} will transform the
+name to @code{lib@var{file}.a}, as with the command line argument
+@samp{-l}.
+
+When you use the @code{INPUT} command in an implicit linker script, the
+files will be included in the link at the point at which the linker
+script file is included. This can affect archive searching.
+
+@item GROUP(@var{file}, @var{file}, @dots{})
+@itemx GROUP(@var{file} @var{file} @dots{})
+@kindex GROUP(@var{files})
+@cindex grouping input files
+The @code{GROUP} command is like @code{INPUT}, except that the named
+files should all be archives, and they are searched repeatedly until no
+new undefined references are created. See the description of @samp{-(}
+in @ref{Options,,Command Line Options}.
+
+@item OUTPUT(@var{filename})
+@kindex OUTPUT(@var{filename})
+@cindex output file name in linker scripot
+The @code{OUTPUT} command names the output file. Using
+@code{OUTPUT(@var{filename})} in the linker script is exactly like using
+@samp{-o @var{filename}} on the command line (@pxref{Options,,Command
+Line Options}). If both are used, the command line option takes
+precedence.
+
+You can use the @code{OUTPUT} command to define a default name for the
+output file other than the usual default of @file{a.out}.
+
+@item SEARCH_DIR(@var{path})
+@kindex SEARCH_DIR(@var{path})
+@cindex library search path in linker script
+@cindex archive search path in linker script
+@cindex search path in linker script
+The @code{SEARCH_DIR} command adds @var{path} to the list of paths where
+@code{ld} looks for archive libraries. Using
+@code{SEARCH_DIR(@var{path})} is exactly like using @samp{-L @var{path}}
+on the command line (@pxref{Options,,Command Line Options}). If both
+are used, then the linker will search both paths. Paths specified using
+the command line option are searched first.
+
+@item STARTUP(@var{filename})
+@kindex STARTUP(@var{filename})
+@cindex first input file
+The @code{STARTUP} command is just like the @code{INPUT} command, except
+that @var{filename} will become the first input file to be linked, as
+though it were specified first on the command line. This may be useful
+when using a system in which the entry point is always the start of the
+first file.
+@end table
+
+@ifclear SingleFormat
+@node Format Commands
+@subsection Commands dealing with object file formats
+A couple of linker script commands deal with object file formats.
+
+@table @code
+@item OUTPUT_FORMAT(@var{bfdname})
+@itemx OUTPUT_FORMAT(@var{default}, @var{big}, @var{little})
+@kindex OUTPUT_FORMAT(@var{bfdname})
+@cindex output file format in linker script
+The @code{OUTPUT_FORMAT} command names the BFD format to use for the
+output file (@pxref{BFD}). Using @code{OUTPUT_FORMAT(@var{bfdname})} is
+exactly like using @samp{-oformat @var{bfdname}} on the command line
+(@pxref{Options,,Command Line Options}). If both are used, the command
+line option takes precedence.
+
+You can use @code{OUTPUT_FORMAT} with three arguments to use different
+formats based on the @samp{-EB} and @samp{-EL} command line options.
+This permits the linker script to set the output format based on the
+desired endianness.
+
+If neither @samp{-EB} nor @samp{-EL} are used, then the output format
+will be the first argument, @var{default}. If @samp{-EB} is used, the
+output format will be the second argument, @var{big}. If @samp{-EL} is
+used, the output format will be the third argument, @var{little}.
+
+For example, the default linker script for the MIPS ELF target uses this
+command:
+@smallexample
+OUTPUT_FORMAT(elf32-bigmips, elf32-bigmips, elf32-littlemips)
+@end smallexample
+This says that the default format for the output file is
+@samp{elf32-bigmips}, but if the user uses the @samp{-EL} command line
+option, the output file will be created in the @samp{elf32-littlemips}
+format.
+
+@item TARGET(@var{bfdname})
+@kindex TARGET(@var{bfdname})
+@cindex input file format in linker script
+The @code{TARGET} command names the BFD format to use when reading input
+files. It affects subsequent @code{INPUT} and @code{GROUP} commands.
+This command is like using @samp{-b @var{bfdname}} on the command line
+(@pxref{Options,,Command Line Options}). If the @code{TARGET} command
+is used but @code{OUTPUT_FORMAT} is not, then the last @code{TARGET}
+command is also used to set the format for the output file. @xref{BFD}.
+@end table
+@end ifclear
+
+@node Miscellaneous Commands
+@subsection Other linker script commands
+There are a few other linker scripts commands.
+
+@table @code
+@item ASSERT(@var{exp}, @var{message})
+@kindex ASSERT
+@cindex assertion in linker script
+Ensure that @var{exp} is non-zero. If it is zero, then exit the linker
+with an error code, and print @var{message}.
+
+@item EXTERN(@var{symbol} @var{symbol} @dots{})
+@kindex EXTERN
+@cindex undefined symbol in linker script
+Force @var{symbol} to be entered in the output file as an undefined
+symbol. Doing this may, for example, trigger linking of additional
+modules from standard libraries. You may list several @var{symbol}s for
+each @code{EXTERN}, and you may use @code{EXTERN} multiple times. This
+command has the same effect as the @samp{-u} command-line option.
+
+@item FORCE_COMMON_ALLOCATION
+@kindex FORCE_COMMON_ALLOCATION
+@cindex common allocation in linker script
+This command has the same effect as the @samp{-d} command-line option:
+to make @code{ld} assign space to common symbols even if a relocatable
+output file is specified (@samp{-r}).
+
+@item NOCROSSREFS(@var{section} @var{section} @dots{})
+@kindex NOCROSSREFS(@var{sections})
+@cindex cross references
+This command may be used to tell @code{ld} to issue an error about any
+references among certain output sections.
+
+In certain types of programs, particularly on embedded systems when
+using overlays, when one section is loaded into memory, another section
+will not be. Any direct references between the two sections would be
+errors. For example, it would be an error if code in one section called
+a function defined in the other section.
+
+The @code{NOCROSSREFS} command takes a list of output section names. If
+@code{ld} detects any cross references between the sections, it reports
+an error and returns a non-zero exit status. Note that the
+@code{NOCROSSREFS} command uses output section names, not input section
+names.
+
+@ifclear SingleFormat
+@item OUTPUT_ARCH(@var{bfdarch})
+@kindex OUTPUT_ARCH(@var{bfdarch})
+@cindex machine architecture
+@cindex architecture
+Specify a particular output machine architecture. The argument is one
+of the names used by the BFD library (@pxref{BFD}). You can see the
+architecture of an object file by using the @code{objdump} program with
+the @samp{-f} option.
+@end ifclear
+@end table
+
+@node Assignments
+@section Assigning Values to Symbols
+@cindex assignment in scripts
+@cindex symbol definition, scripts
+@cindex variables, defining
+You may assign a value to a symbol in a linker script. This will define
+the symbol as a global symbol.
+
+@menu
+* Simple Assignments:: Simple Assignments
+* PROVIDE:: PROVIDE
+@end menu
+
+@node Simple Assignments
+@subsection Simple Assignments
+
+You may assign to a symbol using any of the C assignment operators:
+
+@table @code
+@item @var{symbol} = @var{expression} ;
+@itemx @var{symbol} += @var{expression} ;
+@itemx @var{symbol} -= @var{expression} ;
+@itemx @var{symbol} *= @var{expression} ;
+@itemx @var{symbol} /= @var{expression} ;
+@itemx @var{symbol} <<= @var{expression} ;
+@itemx @var{symbol} >>= @var{expression} ;
+@itemx @var{symbol} &= @var{expression} ;
+@itemx @var{symbol} |= @var{expression} ;
+@end table
+
+The first case will define @var{symbol} to the value of
+@var{expression}. In the other cases, @var{symbol} must already be
+defined, and the value will be adjusted accordingly.
+
+The special symbol name @samp{.} indicates the location counter. You
+may only use this within a @code{SECTIONS} command.
+
+The semicolon after @var{expression} is required.
+
+Expressions are defined below; see @ref{Expressions}.
+
+You may write symbol assignments as commands in their own right, or as
+statements within a @code{SECTIONS} command, or as part of an output
+section description in a @code{SECTIONS} command.
+
+The section of the symbol will be set from the section of the
+expression; for more information, see @ref{Expression Section}.
+
+Here is an example showing the three different places that symbol
+assignments may be used:
+
+@smallexample
+floating_point = 0;
+SECTIONS
+@{
+ .text :
+ @{
+ *(.text)
+ _etext = .;
+ @}
+ _bdata = (. + 3) & ~ 4;
+ .data : @{ *(.data) @}
+@}
+@end smallexample
+@noindent
+In this example, the symbol @samp{floating_point} will be defined as
+zero. The symbol @samp{_etext} will be defined as the address following
+the last @samp{.text} input section. The symbol @samp{_bdata} will be
+defined as the address following the @samp{.text} output section aligned
+upward to a 4 byte boundary.
+
+@node PROVIDE
+@subsection PROVIDE
+@cindex PROVIDE
+In some cases, it is desirable for a linker script to define a symbol
+only if it is referenced and is not defined by any object included in
+the link. For example, traditional linkers defined the symbol
+@samp{etext}. However, ANSI C requires that the user be able to use
+@samp{etext} as a function name without encountering an error. The
+@code{PROVIDE} keyword may be used to define a symbol, such as
+@samp{etext}, only if it is referenced but not defined. The syntax is
+@code{PROVIDE(@var{symbol} = @var{expression})}.
+
+Here is an example of using @code{PROVIDE} to define @samp{etext}:
+@smallexample
+SECTIONS
+@{
+ .text :
+ @{
+ *(.text)
+ _etext = .;
+ PROVIDE(etext = .);
+ @}
+@}
+@end smallexample
+
+In this example, if the program defines @samp{_etext} (with a leading
+underscore), the linker will give a multiple definition error. If, on
+the other hand, the program defines @samp{etext} (with no leading
+underscore), the linker will silently use the definition in the program.
+If the program references @samp{etext} but does not define it, the
+linker will use the definition in the linker script.
+
+@node SECTIONS
+@section SECTIONS command
+@kindex SECTIONS
+The @code{SECTIONS} command tells the linker how to map input sections
+into output sections, and how to place the output sections in memory.
+
+The format of the @code{SECTIONS} command is:
+@smallexample
+SECTIONS
+@{
+ @var{sections-command}
+ @var{sections-command}
+ @dots{}
+@}
+@end smallexample
+
+Each @var{sections-command} may of be one of the following:
+
+@itemize @bullet
+@item
+an @code{ENTRY} command (@pxref{Entry Point,,Entry command})
+@item
+a symbol assignment (@pxref{Assignments})
+@item
+an output section description
+@item
+an overlay description
+@end itemize
+
+The @code{ENTRY} command and symbol assignments are permitted inside the
+@code{SECTIONS} command for convenience in using the location counter in
+those commands. This can also make the linker script easier to
+understand because you can use those commands at meaningful points in
+the layout of the output file.
+
+Output section descriptions and overlay descriptions are described
+below.
+
+If you do not use a @code{SECTIONS} command in your linker script, the
+linker will place each input section into an identically named output
+section in the order that the sections are first encountered in the
+input files. If all input sections are present in the first file, for
+example, the order of sections in the output file will match the order
+in the first input file. The first section will be at address zero.
+
+@menu
+* Output Section Description:: Output section description
+* Output Section Name:: Output section name
+* Output Section Address:: Output section address
+* Input Section:: Input section description
+* Output Section Data:: Output section data
+* Output Section Keywords:: Output section keywords
+* Output Section Discarding:: Output section discarding
+* Output Section Attributes:: Output section attributes
+* Overlay Description:: Overlay description
+@end menu
+
+@node Output Section Description
+@subsection Output section description
+The full description of an output section looks like this:
+@smallexample
+@group
+@var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})]
+ @{
+ @var{output-section-command}
+ @var{output-section-command}
+ @dots{}
+ @} [>@var{region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}]
+@end group
+@end smallexample
+
+Most output sections do not use most of the optional section attributes.
+
+The whitespace around @var{section} is required, so that the section
+name is unambiguous. The colon and the curly braces are also required.
+The line breaks and other white space are optional.
+
+Each @var{output-section-command} may be one of the following:
+
+@itemize @bullet
+@item
+a symbol assignment (@pxref{Assignments})
+@item
+an input section description (@pxref{Input Section})
+@item
+data values to include directly (@pxref{Output Section Data})
+@item
+a special output section keyword (@pxref{Output Section Keywords})
+@end itemize
+
+@node Output Section Name
+@subsection Output section name
+@cindex name, section
+@cindex section name
+The name of the output section is @var{section}. @var{section} must
+meet the constraints of your output format. In formats which only
+support a limited number of sections, such as @code{a.out}, the name
+must be one of the names supported by the format (@code{a.out}, for
+example, allows only @samp{.text}, @samp{.data} or @samp{.bss}). If the
+output format supports any number of sections, but with numbers and not
+names (as is the case for Oasys), the name should be supplied as a
+quoted numeric string. A section name may consist of any sequence of
+characters, but a name which contains any unusual characters such as
+commas must be quoted.
+
+The output section name @samp{/DISCARD/} is special; @ref{Output Section
+Discarding}.
+
+@node Output Section Address
+@subsection Output section address
+@cindex address, section
+@cindex section address
+The @var{address} is an expression for the VMA (the virtual memory
+address) of the output section. If you do not provide @var{address},
+the linker will set it based on @var{region} if present, or otherwise
+based on the current value of the location counter.
+
+If you provide @var{address}, the address of the output section will be
+set to precisely that. If you provide neither @var{address} nor
+@var{region}, then the address of the output section will be set to the
+current value of the location counter aligned to the alignment
+requirements of the output section. The alignment requirement of the
+output section is the strictest alignment of any input section contained
+within the output section.
+
+For example,
+@smallexample
+.text . : @{ *(.text) @}
+@end smallexample
+@noindent
+and
+@smallexample
+.text : @{ *(.text) @}
+@end smallexample
+@noindent
+are subtly different. The first will set the address of the
+@samp{.text} output section to the current value of the location
+counter. The second will set it to the current value of the location
+counter aligned to the strictest alignment of a @samp{.text} input
+section.
+
+The @var{address} may be an arbitrary expression; @ref{Expressions}.
+For example, if you want to align the section on a 0x10 byte boundary,
+so that the lowest four bits of the section address are zero, you could
+do something like this:
+@smallexample
+.text ALIGN(0x10) : @{ *(.text) @}
+@end smallexample
+@noindent
+This works because @code{ALIGN} returns the current location counter
+aligned upward to the specified value.
+
+Specifying @var{address} for a section will change the value of the
+location counter.
+
+@node Input Section
+@subsection Input section description
+@cindex input sections
+@cindex mapping input sections to output sections
+The most common output section command is an input section description.
+
+The input section description is the most basic linker script operation.
+You use output sections to tell the linker how to lay out your program
+in memory. You use input section descriptions to tell the linker how to
+map the input files into your memory layout.
+
+@menu
+* Input Section Basics:: Input section basics
+* Input Section Wildcards:: Input section wildcard patterns
+* Input Section Common:: Input section for common symbols
+* Input Section Keep:: Input section and garbage collection
+* Input Section Example:: Input section example
+@end menu
+
+@node Input Section Basics
+@subsubsection Input section basics
+@cindex input section basics
+An input section description consists of a file name optionally followed
+by a list of section names in parentheses.
+
+The file name and the section name may be wildcard patterns, which we
+describe further below (@pxref{Input Section Wildcards}).
+
+The most common input section description is to include all input
+sections with a particular name in the output section. For example, to
+include all input @samp{.text} sections, you would write:
+@smallexample
+*(.text)
+@end smallexample
+@noindent
+Here the @samp{*} is a wildcard which matches any file name. To exclude a file
+from matching the file name wildcard, EXCLUDE_FILE may be used to match all files
+except the one specified by EXCLUDE_FILE. For example:
+@smallexample
+(*(EXCLUDE_FILE (*crtend.o) .ctors))
+@end smallexample
+will cause all .ctors sections from all files except crtend.o to be included.
+
+There are two ways to include more than one section:
+@smallexample
+*(.text .rdata)
+*(.text) *(.rdata)
+@end smallexample
+@noindent
+The difference between these is the order in which the @samp{.text} and
+@samp{.rdata} input sections will appear in the output section. In the
+first example, they will be intermingled. In the second example, all
+@samp{.text} input sections will appear first, followed by all
+@samp{.rdata} input sections.
+
+You can specify a file name to include sections from a particular file.
+You would do this if one or more of your files contain special data that
+needs to be at a particular location in memory. For example:
+@smallexample
+data.o(.data)
+@end smallexample
+
+If you use a file name without a list of sections, then all sections in
+the input file will be included in the output section. This is not
+commonly done, but it may by useful on occasion. For example:
+@smallexample
+data.o
+@end smallexample
+
+When you use a file name which does not contain any wild card
+characters, the linker will first see if you also specified the file
+name on the linker command line or in an @code{INPUT} command. If you
+did not, the linker will attempt to open the file as an input file, as
+though it appeared on the command line. Note that this differs from an
+@code{INPUT} command, because the linker will not search for the file in
+the archive search path.
+
+@node Input Section Wildcards
+@subsubsection Input section wildcard patterns
+@cindex input section wildcards
+@cindex wildcard file name patterns
+@cindex file name wildcard patterns
+@cindex section name wildcard patterns
+In an input section description, either the file name or the section
+name or both may be wildcard patterns.
+
+The file name of @samp{*} seen in many examples is a simple wildcard
+pattern for the file name.
+
+The wildcard patterns are like those used by the Unix shell.
+
+@table @samp
+@item *
+matches any number of characters
+@item ?
+matches any single character
+@item [@var{chars}]
+matches a single instance of any of the @var{chars}; the @samp{-}
+character may be used to specify a range of characters, as in
+@samp{[a-z]} to match any lower case letter
+@item \
+quotes the following character
+@end table
+
+When a file name is matched with a wildcard, the wildcard characters
+will not match a @samp{/} character (used to separate directory names on
+Unix). A pattern consisting of a single @samp{*} character is an
+exception; it will always match any file name, whether it contains a
+@samp{/} or not. In a section name, the wildcard characters will match
+a @samp{/} character.
+
+File name wildcard patterns only match files which are explicitly
+specified on the command line or in an @code{INPUT} command. The linker
+does not search directories to expand wildcards.
+
+If a file name matches more than one wildcard pattern, or if a file name
+appears explicitly and is also matched by a wildcard pattern, the linker
+will use the first match in the linker script. For example, this
+sequence of input section descriptions is probably in error, because the
+@file{data.o} rule will not be used:
+@smallexample
+.data : @{ *(.data) @}
+.data1 : @{ data.o(.data) @}
+@end smallexample
+
+@cindex SORT
+Normally, the linker will place files and sections matched by wildcards
+in the order in which they are seen during the link. You can change
+this by using the @code{SORT} keyword, which appears before a wildcard
+pattern in parentheses (e.g., @code{SORT(.text*)}). When the
+@code{SORT} keyword is used, the linker will sort the files or sections
+into ascending order by name before placing them in the output file.
+
+If you ever get confused about where input sections are going, use the
+@samp{-M} linker option to generate a map file. The map file shows
+precisely how input sections are mapped to output sections.
+
+This example shows how wildcard patterns might be used to partition
+files. This linker script directs the linker to place all @samp{.text}
+sections in @samp{.text} and all @samp{.bss} sections in @samp{.bss}.
+The linker will place the @samp{.data} section from all files beginning
+with an upper case character in @samp{.DATA}; for all other files, the
+linker will place the @samp{.data} section in @samp{.data}.
+@smallexample
+@group
+SECTIONS @{
+ .text : @{ *(.text) @}
+ .DATA : @{ [A-Z]*(.data) @}
+ .data : @{ *(.data) @}
+ .bss : @{ *(.bss) @}
+@}
+@end group
+@end smallexample
+
+@node Input Section Common
+@subsubsection Input section for common symbols
+@cindex common symbol placement
+@cindex uninitialized data placement
+A special notation is needed for common symbols, because in many object
+file formats common symbols do not have a particular input section. The
+linker treats common symbols as though they are in an input section
+named @samp{COMMON}.
+
+You may use file names with the @samp{COMMON} section just as with any
+other input sections. You can use this to place common symbols from a
+particular input file in one section while common symbols from other
+input files are placed in another section.
+
+In most cases, common symbols in input files will be placed in the
+@samp{.bss} section in the output file. For example:
+@smallexample
+.bss @{ *(.bss) *(COMMON) @}
+@end smallexample
+
+@cindex scommon section
+@cindex small common symbols
+Some object file formats have more than one type of common symbol. For
+example, the MIPS ELF object file format distinguishes standard common
+symbols and small common symbols. In this case, the linker will use a
+different special section name for other types of common symbols. In
+the case of MIPS ELF, the linker uses @samp{COMMON} for standard common
+symbols and @samp{.scommon} for small common symbols. This permits you
+to map the different types of common symbols into memory at different
+locations.
+
+@cindex [COMMON]
+You will sometimes see @samp{[COMMON]} in old linker scripts. This
+notation is now considered obsolete. It is equivalent to
+@samp{*(COMMON)}.
+
+@node Input Section Keep
+@subsubsection Input section and garbage collection
+@cindex KEEP
+@cindex garbage collection
+When link-time garbage collection is in use (@samp{--gc-sections}),
+it is often useful to mark sections that should not be eliminated.
+This is accomplished by surrounding an input section's wildcard entry
+with @code{KEEP()}, as in @code{KEEP(*(.init))} or
+@code{KEEP(SORT(*)(.ctors))}.
+
+@node Input Section Example
+@subsubsection Input section example
+The following example is a complete linker script. It tells the linker
+to read all of the sections from file @file{all.o} and place them at the
+start of output section @samp{outputa} which starts at location
+@samp{0x10000}. All of section @samp{.input1} from file @file{foo.o}
+follows immediately, in the same output section. All of section
+@samp{.input2} from @file{foo.o} goes into output section
+@samp{outputb}, followed by section @samp{.input1} from @file{foo1.o}.
+All of the remaining @samp{.input1} and @samp{.input2} sections from any
+files are written to output section @samp{outputc}.
+
+@smallexample
+@group
+SECTIONS @{
+ outputa 0x10000 :
+ @{
+ all.o
+ foo.o (.input1)
+ @}
+ outputb :
+ @{
+ foo.o (.input2)
+ foo1.o (.input1)
+ @}
+ outputc :
+ @{
+ *(.input1)
+ *(.input2)
+ @}
+@}
+@end group
+@end smallexample
+
+@node Output Section Data
+@subsection Output section data
+@cindex data
+@cindex section data
+@cindex output section data
+@kindex BYTE(@var{expression})
+@kindex SHORT(@var{expression})
+@kindex LONG(@var{expression})
+@kindex QUAD(@var{expression})
+@kindex SQUAD(@var{expression})
+You can include explicit bytes of data in an output section by using
+@code{BYTE}, @code{SHORT}, @code{LONG}, @code{QUAD}, or @code{SQUAD} as
+an output section command. Each keyword is followed by an expression in
+parentheses providing the value to store (@pxref{Expressions}). The
+value of the expression is stored at the current value of the location
+counter.
+
+The @code{BYTE}, @code{SHORT}, @code{LONG}, and @code{QUAD} commands
+store one, two, four, and eight bytes (respectively). After storing the
+bytes, the location counter is incremented by the number of bytes
+stored.
+
+For example, this will store the byte 1 followed by the four byte value
+of the symbol @samp{addr}:
+@smallexample
+BYTE(1)
+LONG(addr)
+@end smallexample
+
+When using a 64 bit host or target, @code{QUAD} and @code{SQUAD} are the
+same; they both store an 8 byte, or 64 bit, value. When both host and
+target are 32 bits, an expression is computed as 32 bits. In this case
+@code{QUAD} stores a 32 bit value zero extended to 64 bits, and
+@code{SQUAD} stores a 32 bit value sign extended to 64 bits.
+
+If the object file format of the output file has an explicit endianness,
+which is the normal case, the value will be stored in that endianness.
+When the object file format does not have an explicit endianness, as is
+true of, for example, S-records, the value will be stored in the
+endianness of the first input object file.
+
+@kindex FILL(@var{expression})
+@cindex holes, filling
+@cindex unspecified memory
+You may use the @code{FILL} command to set the fill pattern for the
+current section. It is followed by an expression in parentheses. Any
+otherwise unspecified regions of memory within the section (for example,
+gaps left due to the required alignment of input sections) are filled
+with the two least significant bytes of the expression, repeated as
+necessary. A @code{FILL} statement covers memory locations after the
+point at which it occurs in the section definition; by including more
+than one @code{FILL} statement, you can have different fill patterns in
+different parts of an output section.
+
+This example shows how to fill unspecified regions of memory with the
+value @samp{0x9090}:
+@smallexample
+FILL(0x9090)
+@end smallexample
+
+The @code{FILL} command is similar to the @samp{=@var{fillexp}} output
+section attribute (@pxref{Output Section Fill}), but it only affects the
+part of the section following the @code{FILL} command, rather than the
+entire section. If both are used, the @code{FILL} command takes
+precedence.
+
+@node Output Section Keywords
+@subsection Output section keywords
+There are a couple of keywords which can appear as output section
+commands.
+
+@table @code
+@kindex CREATE_OBJECT_SYMBOLS
+@cindex input filename symbols
+@cindex filename symbols
+@item CREATE_OBJECT_SYMBOLS
+The command tells the linker to create a symbol for each input file.
+The name of each symbol will be the name of the corresponding input
+file. The section of each symbol will be the output section in which
+the @code{CREATE_OBJECT_SYMBOLS} command appears.
+
+This is conventional for the a.out object file format. It is not
+normally used for any other object file format.
+
+@kindex CONSTRUCTORS
+@cindex C++ constructors, arranging in link
+@cindex constructors, arranging in link
+@item CONSTRUCTORS
+When linking using the a.out object file format, the linker uses an
+unusual set construct to support C++ global constructors and
+destructors. When linking object file formats which do not support
+arbitrary sections, such as ECOFF and XCOFF, the linker will
+automatically recognize C++ global constructors and destructors by name.
+For these object file formats, the @code{CONSTRUCTORS} command tells the
+linker to place constructor information in the output section where the
+@code{CONSTRUCTORS} command appears. The @code{CONSTRUCTORS} command is
+ignored for other object file formats.
+
+The symbol @w{@code{__CTOR_LIST__}} marks the start of the global
+constructors, and the symbol @w{@code{__DTOR_LIST}} marks the end. The
+first word in the list is the number of entries, followed by the address
+of each constructor or destructor, followed by a zero word. The
+compiler must arrange to actually run the code. For these object file
+formats @sc{gnu} C++ normally calls constructors from a subroutine
+@code{__main}; a call to @code{__main} is automatically inserted into
+the startup code for @code{main}. @sc{gnu} C++ normally runs
+destructors either by using @code{atexit}, or directly from the function
+@code{exit}.
+
+For object file formats such as @code{COFF} or @code{ELF} which support
+arbitrary section names, @sc{gnu} C++ will normally arrange to put the
+addresses of global constructors and destructors into the @code{.ctors}
+and @code{.dtors} sections. Placing the following sequence into your
+linker script will build the sort of table which the @sc{gnu} C++
+runtime code expects to see.
+
+@smallexample
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+@end smallexample
+
+If you are using the @sc{gnu} C++ support for initialization priority,
+which provides some control over the order in which global constructors
+are run, you must sort the constructors at link time to ensure that they
+are executed in the correct order. When using the @code{CONSTRUCTORS}
+command, use @samp{SORT(CONSTRUCTORS)} instead. When using the
+@code{.ctors} and @code{.dtors} sections, use @samp{*(SORT(.ctors))} and
+@samp{*(SORT(.dtors))} instead of just @samp{*(.ctors)} and
+@samp{*(.dtors)}.
+
+Normally the compiler and linker will handle these issues automatically,
+and you will not need to concern yourself with them. However, you may
+need to consider this if you are using C++ and writing your own linker
+scripts.
+
+@end table
+
+@node Output Section Discarding
+@subsection Output section discarding
+@cindex discarding sections
+@cindex sections, discarding
+@cindex removing sections
+The linker will not create output section which do not have any
+contents. This is for convenience when referring to input sections that
+may or may not be present in any of the input files. For example:
+@smallexample
+.foo @{ *(.foo) @}
+@end smallexample
+@noindent
+will only create a @samp{.foo} section in the output file if there is a
+@samp{.foo} section in at least one input file.
+
+If you use anything other than an input section description as an output
+section command, such as a symbol assignment, then the output section
+will always be created, even if there are no matching input sections.
+
+@cindex /DISCARD/
+The special output section name @samp{/DISCARD/} may be used to discard
+input sections. Any input sections which are assigned to an output
+section named @samp{/DISCARD/} are not included in the output file.
+
+@node Output Section Attributes
+@subsection Output section attributes
+@cindex output section attributes
+We showed above that the full description of an output section looked
+like this:
+@smallexample
+@group
+@var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})]
+ @{
+ @var{output-section-command}
+ @var{output-section-command}
+ @dots{}
+ @} [>@var{region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}]
+@end group
+@end smallexample
+We've already described @var{section}, @var{address}, and
+@var{output-section-command}. In this section we will describe the
+remaining section attributes.
+
+@menu
+* Output Section Type:: Output section type
+* Output Section LMA:: Output section LMA
+* Output Section Region:: Output section region
+* Output Section Phdr:: Output section phdr
+* Output Section Fill:: Output section fill
+@end menu
+
+@node Output Section Type
+@subsubsection Output section type
+Each output section may have a type. The type is a keyword in
+parentheses. The following types are defined:
+
+@table @code
+@item NOLOAD
+The section should be marked as not loadable, so that it will not be
+loaded into memory when the program is run.
+@item DSECT
+@itemx COPY
+@itemx INFO
+@itemx OVERLAY
+These type names are supported for backward compatibility, and are
+rarely used. They all have the same effect: the section should be
+marked as not allocatable, so that no memory is allocated for the
+section when the program is run.
+@end table
+
+@kindex NOLOAD
+@cindex prevent unnecessary loading
+@cindex loading, preventing
+The linker normally sets the attributes of an output section based on
+the input sections which map into it. You can override this by using
+the section type. For example, in the script sample below, the
+@samp{ROM} section is addressed at memory location @samp{0} and does not
+need to be loaded when the program is run. The contents of the
+@samp{ROM} section will appear in the linker output file as usual.
+@smallexample
+@group
+SECTIONS @{
+ ROM 0 (NOLOAD) : @{ @dots{} @}
+ @dots{}
+@}
+@end group
+@end smallexample
+
+@node Output Section LMA
+@subsubsection Output section LMA
+@kindex AT(@var{lma})
+@cindex load address
+@cindex section load address
+Every section has a virtual address (VMA) and a load address (LMA); see
+@ref{Basic Script Concepts}. The address expression which may appear in
+an output section description sets the VMA (@pxref{Output Section
+Address}).
+
+The linker will normally set the LMA equal to the VMA. You can change
+that by using the @code{AT} keyword. The expression @var{lma} that
+follows the @code{AT} keyword specifies the load address of the section.
+
+@cindex ROM initialized data
+@cindex initialized data in ROM
+This feature is designed to make it easy to build a ROM image. For
+example, the following linker script creates three output sections: one
+called @samp{.text}, which starts at @code{0x1000}, one called
+@samp{.mdata}, which is loaded at the end of the @samp{.text} section
+even though its VMA is @code{0x2000}, and one called @samp{.bss} to hold
+uninitialized data at address @code{0x3000}. The symbol @code{_data} is
+defined with the value @code{0x2000}, which shows that the location
+counter holds the VMA value, not the LMA value.
+
+@smallexample
+@group
+SECTIONS
+ @{
+ .text 0x1000 : @{ *(.text) _etext = . ; @}
+ .mdata 0x2000 :
+ AT ( ADDR (.text) + SIZEOF (.text) )
+ @{ _data = . ; *(.data); _edata = . ; @}
+ .bss 0x3000 :
+ @{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;@}
+@}
+@end group
+@end smallexample
+
+The run-time initialization code for use with a program generated with
+this linker script would include something like the following, to copy
+the initialized data from the ROM image to its runtime address. Notice
+how this code takes advantage of the symbols defined by the linker
+script.
+
+@smallexample
+@group
+extern char _etext, _data, _edata, _bstart, _bend;
+char *src = &_etext;
+char *dst = &_data;
+
+/* ROM has data at end of text; copy it. */
+while (dst < &_edata) @{
+ *dst++ = *src++;
+@}
+
+/* Zero bss */
+for (dst = &_bstart; dst< &_bend; dst++)
+ *dst = 0;
+@end group
+@end smallexample
+
+@node Output Section Region
+@subsubsection Output section region
+@kindex >@var{region}
+@cindex section, assigning to memory region
+@cindex memory regions and sections
+You can assign a section to a previously defined region of memory by
+using @samp{>@var{region}}. @xref{MEMORY}.
+
+Here is a simple example:
+@smallexample
+@group
+MEMORY @{ rom : ORIGIN = 0x1000, LENGTH = 0x1000 @}
+SECTIONS @{ ROM : @{ *(.text) @} >rom @}
+@end group
+@end smallexample
+
+@node Output Section Phdr
+@subsubsection Output section phdr
+@kindex :@var{phdr}
+@cindex section, assigning to program header
+@cindex program headers and sections
+You can assign a section to a previously defined program segment by
+using @samp{:@var{phdr}}. @xref{PHDRS}. If a section is assigned to
+one or more segments, then all subsequent allocated sections will be
+assigned to those segments as well, unless they use an explicitly
+@code{:@var{phdr}} modifier. You can use @code{:NONE} to tell the
+linker to not put the section in any segment at all.
+
+Here is a simple example:
+@smallexample
+@group
+PHDRS @{ text PT_LOAD ; @}
+SECTIONS @{ .text : @{ *(.text) @} :text @}
+@end group
+@end smallexample
+
+@node Output Section Fill
+@subsubsection Output section fill
+@kindex =@var{fillexp}
+@cindex section fill pattern
+@cindex fill pattern, entire section
+You can set the fill pattern for an entire section by using
+@samp{=@var{fillexp}}. @var{fillexp} is an expression
+(@pxref{Expressions}). Any otherwise unspecified regions of memory
+within the output section (for example, gaps left due to the required
+alignment of input sections) will be filled with the two least
+significant bytes of the value, repeated as necessary.
+
+You can also change the fill value with a @code{FILL} command in the
+output section commands; see @ref{Output Section Data}.
+
+Here is a simple example:
+@smallexample
+@group
+SECTIONS @{ .text : @{ *(.text) @} =0x9090 @}
+@end group
+@end smallexample
+
+@node Overlay Description
+@subsection Overlay description
+@kindex OVERLAY
+@cindex overlays
+An overlay description provides an easy way to describe sections which
+are to be loaded as part of a single memory image but are to be run at
+the same memory address. At run time, some sort of overlay manager will
+copy the overlaid sections in and out of the runtime memory address as
+required, perhaps by simply manipulating addressing bits. This approach
+can be useful, for example, when a certain region of memory is faster
+than another.
+
+Overlays are described using the @code{OVERLAY} command. The
+@code{OVERLAY} command is used within a @code{SECTIONS} command, like an
+output section description. The full syntax of the @code{OVERLAY}
+command is as follows:
+@smallexample
+@group
+OVERLAY [@var{start}] : [NOCROSSREFS] [AT ( @var{ldaddr} )]
+ @{
+ @var{secname1}
+ @{
+ @var{output-section-command}
+ @var{output-section-command}
+ @dots{}
+ @} [:@var{phdr}@dots{}] [=@var{fill}]
+ @var{secname2}
+ @{
+ @var{output-section-command}
+ @var{output-section-command}
+ @dots{}
+ @} [:@var{phdr}@dots{}] [=@var{fill}]
+ @dots{}
+ @} [>@var{region}] [:@var{phdr}@dots{}] [=@var{fill}]
+@end group
+@end smallexample
+
+Everything is optional except @code{OVERLAY} (a keyword), and each
+section must have a name (@var{secname1} and @var{secname2} above). The
+section definitions within the @code{OVERLAY} construct are identical to
+those within the general @code{SECTIONS} contruct (@pxref{SECTIONS}),
+except that no addresses and no memory regions may be defined for
+sections within an @code{OVERLAY}.
+
+The sections are all defined with the same starting address. The load
+addresses of the sections are arranged such that they are consecutive in
+memory starting at the load address used for the @code{OVERLAY} as a
+whole (as with normal section definitions, the load address is optional,
+and defaults to the start address; the start address is also optional,
+and defaults to the current value of the location counter).
+
+If the @code{NOCROSSREFS} keyword is used, and there any references
+among the sections, the linker will report an error. Since the sections
+all run at the same address, it normally does not make sense for one
+section to refer directly to another. @xref{Miscellaneous Commands,
+NOCROSSREFS}.
+
+For each section within the @code{OVERLAY}, the linker automatically
+defines two symbols. The symbol @code{__load_start_@var{secname}} is
+defined as the starting load address of the section. The symbol
+@code{__load_stop_@var{secname}} is defined as the final load address of
+the section. Any characters within @var{secname} which are not legal
+within C identifiers are removed. C (or assembler) code may use these
+symbols to move the overlaid sections around as necessary.
+
+At the end of the overlay, the value of the location counter is set to
+the start address of the overlay plus the size of the largest section.
+
+Here is an example. Remember that this would appear inside a
+@code{SECTIONS} construct.
+@smallexample
+@group
+ OVERLAY 0x1000 : AT (0x4000)
+ @{
+ .text0 @{ o1/*.o(.text) @}
+ .text1 @{ o2/*.o(.text) @}
+ @}
+@end group
+@end smallexample
+@noindent
+This will define both @samp{.text0} and @samp{.text1} to start at
+address 0x1000. @samp{.text0} will be loaded at address 0x4000, and
+@samp{.text1} will be loaded immediately after @samp{.text0}. The
+following symbols will be defined: @code{__load_start_text0},
+@code{__load_stop_text0}, @code{__load_start_text1},
+@code{__load_stop_text1}.
+
+C code to copy overlay @code{.text1} into the overlay area might look
+like the following.
+
+@smallexample
+@group
+ extern char __load_start_text1, __load_stop_text1;
+ memcpy ((char *) 0x1000, &__load_start_text1,
+ &__load_stop_text1 - &__load_start_text1);
+@end group
+@end smallexample
+
+Note that the @code{OVERLAY} command is just syntactic sugar, since
+everything it does can be done using the more basic commands. The above
+example could have been written identically as follows.
+
+@smallexample
+@group
+ .text0 0x1000 : AT (0x4000) @{ o1/*.o(.text) @}
+ __load_start_text0 = LOADADDR (.text0);
+ __load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0);
+ .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) @{ o2/*.o(.text) @}
+ __load_start_text1 = LOADADDR (.text1);
+ __load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1);
+ . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1));
+@end group
+@end smallexample
+
+@node MEMORY
+@section MEMORY command
+@kindex MEMORY
+@cindex memory regions
+@cindex regions of memory
+@cindex allocating memory
+@cindex discontinuous memory
+The linker's default configuration permits allocation of all available
+memory. You can override this by using the @code{MEMORY} command.
+
+The @code{MEMORY} command describes the location and size of blocks of
+memory in the target. You can use it to describe which memory regions
+may be used by the linker, and which memory regions it must avoid. You
+can then assign sections to particular memory regions. The linker will
+set section addresses based on the memory regions, and will warn about
+regions that become too full. The linker will not shuffle sections
+around to fit into the available regions.
+
+A linker script may contain at most one use of the @code{MEMORY}
+command. However, you can define as many blocks of memory within it as
+you wish. The syntax is:
+@smallexample
+@group
+MEMORY
+ @{
+ @var{name} [(@var{attr})] : ORIGIN = @var{origin}, LENGTH = @var{len}
+ @dots{}
+ @}
+@end group
+@end smallexample
+
+The @var{name} is a name used in the linker script to refer to the
+region. The region name has no meaning outside of the linker script.
+Region names are stored in a separate name space, and will not conflict
+with symbol names, file names, or section names. Each memory region
+must have a distinct name.
+
+@cindex memory region attributes
+The @var{attr} string is an optional list of attributes that specify
+whether to use a particular memory region for an input section which is
+not explicitly mapped in the linker script. As described in
+@ref{SECTIONS}, if you do not specify an output section for some input
+section, the linker will create an output section with the same name as
+the input section. If you define region attributes, the linker will use
+them to select the memory region for the output section that it creates.
+
+The @var{attr} string must consist only of the following characters:
+@table @samp
+@item R
+Read-only section
+@item W
+Read/write section
+@item X
+Executable section
+@item A
+Allocatable section
+@item I
+Initialized section
+@item L
+Same as @samp{I}
+@item !
+Invert the sense of any of the preceding attributes
+@end table
+
+If a unmapped section matches any of the listed attributes other than
+@samp{!}, it will be placed in the memory region. The @samp{!}
+attribute reverses this test, so that an unmapped section will be placed
+in the memory region only if it does not match any of the listed
+attributes.
+
+@kindex ORIGIN =
+@kindex o =
+@kindex org =
+The @var{origin} is an expression for the start address of the memory
+region. The expression must evaluate to a constant before memory
+allocation is performed, which means that you may not use any section
+relative symbols. The keyword @code{ORIGIN} may be abbreviated to
+@code{org} or @code{o} (but not, for example, @code{ORG}).
+
+@kindex LENGTH =
+@kindex len =
+@kindex l =
+The @var{len} is an expression for the size in bytes of the memory
+region. As with the @var{origin} expression, the expression must
+evaluate to a constant before memory allocation is performed. The
+keyword @code{LENGTH} may be abbreviated to @code{len} or @code{l}.
+
+In the following example, we specify that there are two memory regions
+available for allocation: one starting at @samp{0} for 256 kilobytes,
+and the other starting at @samp{0x40000000} for four megabytes. The
+linker will place into the @samp{rom} memory region every section which
+is not explicitly mapped into a memory region, and is either read-only
+or executable. The linker will place other sections which are not
+explicitly mapped into a memory region into the @samp{ram} memory
+region.
+
+@smallexample
+@group
+MEMORY
+ @{
+ rom (rx) : ORIGIN = 0, LENGTH = 256K
+ ram (!rx) : org = 0x40000000, l = 4M
+ @}
+@end group
+@end smallexample
+
+Once you define a memory region, you can direct the linker to place
+specific output sections into that memory region by using the
+@samp{>@var{region}} output section attribute. For example, if you have
+a memory region named @samp{mem}, you would use @samp{>mem} in the
+output section definition. @xref{Output Section Region}. If no address
+was specified for the output section, the linker will set the address to
+the next available address within the memory region. If the combined
+output sections directed to a memory region are too large for the
+region, the linker will issue an error message.
+
+@node PHDRS
+@section PHDRS Command
+@kindex PHDRS
+@cindex program headers
+@cindex ELF program headers
+@cindex program segments
+@cindex segments, ELF
+The ELF object file format uses @dfn{program headers}, also knows as
+@dfn{segments}. The program headers describe how the program should be
+loaded into memory. You can print them out by using the @code{objdump}
+program with the @samp{-p} option.
+
+When you run an ELF program on a native ELF system, the system loader
+reads the program headers in order to figure out how to load the
+program. This will only work if the program headers are set correctly.
+This manual does not describe the details of how the system loader
+interprets program headers; for more information, see the ELF ABI.
+
+The linker will create reasonable program headers by default. However,
+in some cases, you may need to specify the program headers more
+precisely. You may use the @code{PHDRS} command for this purpose. When
+the linker sees the @code{PHDRS} command in the linker script, it will
+not create any program headers other than the ones specified.
+
+The linker only pays attention to the @code{PHDRS} command when
+generating an ELF output file. In other cases, the linker will simply
+ignore @code{PHDRS}.
+
+This is the syntax of the @code{PHDRS} command. The words @code{PHDRS},
+@code{FILEHDR}, @code{AT}, and @code{FLAGS} are keywords.
+
+@smallexample
+@group
+PHDRS
+@{
+ @var{name} @var{type} [ FILEHDR ] [ PHDRS ] [ AT ( @var{address} ) ]
+ [ FLAGS ( @var{flags} ) ] ;
+@}
+@end group
+@end smallexample
+
+The @var{name} is used only for reference in the @code{SECTIONS} command
+of the linker script. It is not put into the output file. Program
+header names are stored in a separate name space, and will not conflict
+with symbol names, file names, or section names. Each program header
+must have a distinct name.
+
+Certain program header types describe segments of memory which the
+system loader will load from the file. In the linker script, you
+specify the contents of these segments by placing allocatable output
+sections in the segments. You use the @samp{:@var{phdr}} output section
+attribute to place a section in a particular segment. @xref{Output
+Section Phdr}.
+
+It is normal to put certain sections in more than one segment. This
+merely implies that one segment of memory contains another. You may
+repeat @samp{:@var{phdr}}, using it once for each segment which should
+contain the section.
+
+If you place a section in one or more segments using @samp{:@var{phdr}},
+then the linker will place all subsequent allocatable sections which do
+not specify @samp{:@var{phdr}} in the same segments. This is for
+convenience, since generally a whole set of contiguous sections will be
+placed in a single segment. You can use @code{:NONE} to override the
+default segment and tell the linker to not put the section in any
+segment at all.
+
+@kindex FILEHDR
+@kindex PHDRS
+You may use the @code{FILEHDR} and @code{PHDRS} keywords appear after
+the program header type to further describe the contents of the segment.
+The @code{FILEHDR} keyword means that the segment should include the ELF
+file header. The @code{PHDRS} keyword means that the segment should
+include the ELF program headers themselves.
+
+The @var{type} may be one of the following. The numbers indicate the
+value of the keyword.
+
+@table @asis
+@item @code{PT_NULL} (0)
+Indicates an unused program header.
+
+@item @code{PT_LOAD} (1)
+Indicates that this program header describes a segment to be loaded from
+the file.
+
+@item @code{PT_DYNAMIC} (2)
+Indicates a segment where dynamic linking information can be found.
+
+@item @code{PT_INTERP} (3)
+Indicates a segment where the name of the program interpreter may be
+found.
+
+@item @code{PT_NOTE} (4)
+Indicates a segment holding note information.
+
+@item @code{PT_SHLIB} (5)
+A reserved program header type, defined but not specified by the ELF
+ABI.
+
+@item @code{PT_PHDR} (6)
+Indicates a segment where the program headers may be found.
+
+@item @var{expression}
+An expression giving the numeric type of the program header. This may
+be used for types not defined above.
+@end table
+
+You can specify that a segment should be loaded at a particular address
+in memory by using an @code{AT} expression. This is identical to the
+@code{AT} command used as an output section attribute (@pxref{Output
+Section LMA}). The @code{AT} command for a program header overrides the
+output section attribute.
+
+The linker will normally set the segment flags based on the sections
+which comprise the segment. You may use the @code{FLAGS} keyword to
+explicitly specify the segment flags. The value of @var{flags} must be
+an integer. It is used to set the @code{p_flags} field of the program
+header.
+
+Here is an example of @code{PHDRS}. This shows a typical set of program
+headers used on a native ELF system.
+
+@example
+@group
+PHDRS
+@{
+ headers PT_PHDR PHDRS ;
+ interp PT_INTERP ;
+ text PT_LOAD FILEHDR PHDRS ;
+ data PT_LOAD ;
+ dynamic PT_DYNAMIC ;
+@}
+
+SECTIONS
+@{
+ . = SIZEOF_HEADERS;
+ .interp : @{ *(.interp) @} :text :interp
+ .text : @{ *(.text) @} :text
+ .rodata : @{ *(.rodata) @} /* defaults to :text */
+ @dots{}
+ . = . + 0x1000; /* move to a new page in memory */
+ .data : @{ *(.data) @} :data
+ .dynamic : @{ *(.dynamic) @} :data :dynamic
+ @dots{}
+@}
+@end group
+@end example
+
+@node VERSION
+@section VERSION Command
+@kindex VERSION @{script text@}
+@cindex symbol versions
+@cindex version script
+@cindex versions of symbols
+The linker supports symbol versions when using ELF. Symbol versions are
+only useful when using shared libraries. The dynamic linker can use
+symbol versions to select a specific version of a function when it runs
+a program that may have been linked against an earlier version of the
+shared library.
+
+You can include a version script directly in the main linker script, or
+you can supply the version script as an implicit linker script. You can
+also use the @samp{--version-script} linker option.
+
+The syntax of the @code{VERSION} command is simply
+@smallexample
+VERSION @{ version-script-commands @}
+@end smallexample
+
+The format of the version script commands is identical to that used by
+Sun's linker in Solaris 2.5. The version script defines a tree of
+version nodes. You specify the node names and interdependencies in the
+version script. You can specify which symbols are bound to which
+version nodes, and you can reduce a specified set of symbols to local
+scope so that they are not globally visible outside of the shared
+library.
+
+The easiest way to demonstrate the version script language is with a few
+examples.
+
+@smallexample
+VERS_1.1 @{
+ global:
+ foo1;
+ local:
+ old*;
+ original*;
+ new*;
+@};
+
+VERS_1.2 @{
+ foo2;
+@} VERS_1.1;
+
+VERS_2.0 @{
+ bar1; bar2;
+@} VERS_1.2;
+@end smallexample
+
+This example version script defines three version nodes. The first
+version node defined is @samp{VERS_1.1}; it has no other dependencies.
+The script binds the symbol @samp{foo1} to @samp{VERS_1.1}. It reduces
+a number of symbols to local scope so that they are not visible outside
+of the shared library.
+
+Next, the version script defines node @samp{VERS_1.2}. This node
+depends upon @samp{VERS_1.1}. The script binds the symbol @samp{foo2}
+to the version node @samp{VERS_1.2}.
+
+Finally, the version script defines node @samp{VERS_2.0}. This node
+depends upon @samp{VERS_1.2}. The scripts binds the symbols @samp{bar1}
+and @samp{bar2} are bound to the version node @samp{VERS_2.0}.
+
+When the linker finds a symbol defined in a library which is not
+specifically bound to a version node, it will effectively bind it to an
+unspecified base version of the library. You can bind all otherwise
+unspecified symbols to a given version node by using @samp{global: *}
+somewhere in the version script.
+
+The names of the version nodes have no specific meaning other than what
+they might suggest to the person reading them. The @samp{2.0} version
+could just as well have appeared in between @samp{1.1} and @samp{1.2}.
+However, this would be a confusing way to write a version script.
+
+When you link an application against a shared library that has versioned
+symbols, the application itself knows which version of each symbol it
+requires, and it also knows which version nodes it needs from each
+shared library it is linked against. Thus at runtime, the dynamic
+loader can make a quick check to make sure that the libraries you have
+linked against do in fact supply all of the version nodes that the
+application will need to resolve all of the dynamic symbols. In this
+way it is possible for the dynamic linker to know with certainty that
+all external symbols that it needs will be resolvable without having to
+search for each symbol reference.
+
+The symbol versioning is in effect a much more sophisticated way of
+doing minor version checking that SunOS does. The fundamental problem
+that is being addressed here is that typically references to external
+functions are bound on an as-needed basis, and are not all bound when
+the application starts up. If a shared library is out of date, a
+required interface may be missing; when the application tries to use
+that interface, it may suddenly and unexpectedly fail. With symbol
+versioning, the user will get a warning when they start their program if
+the libraries being used with the application are too old.
+
+There are several GNU extensions to Sun's versioning approach. The
+first of these is the ability to bind a symbol to a version node in the
+source file where the symbol is defined instead of in the versioning
+script. This was done mainly to reduce the burden on the library
+maintainer. You can do this by putting something like:
+@smallexample
+__asm__(".symver original_foo,foo@@VERS_1.1");
+@end smallexample
+@noindent
+in the C source file. This renames the function @samp{original_foo} to
+be an alias for @samp{foo} bound to the version node @samp{VERS_1.1}.
+The @samp{local:} directive can be used to prevent the symbol
+@samp{original_foo} from being exported.
+
+The second GNU extension is to allow multiple versions of the same
+function to appear in a given shared library. In this way you can make
+an incompatible change to an interface without increasing the major
+version number of the shared library, while still allowing applications
+linked against the old interface to continue to function.
+
+To do this, you must use multiple @samp{.symver} directives in the
+source file. Here is an example:
+
+@smallexample
+__asm__(".symver original_foo,foo@@");
+__asm__(".symver old_foo,foo@@VERS_1.1");
+__asm__(".symver old_foo1,foo@@VERS_1.2");
+__asm__(".symver new_foo,foo@@@@VERS_2.0");
+@end smallexample
+
+In this example, @samp{foo@@} represents the symbol @samp{foo} bound to the
+unspecified base version of the symbol. The source file that contains this
+example would define 4 C functions: @samp{original_foo}, @samp{old_foo},
+@samp{old_foo1}, and @samp{new_foo}.
+
+When you have multiple definitions of a given symbol, there needs to be
+some way to specify a default version to which external references to
+this symbol will be bound. You can do this with the
+@samp{foo@@@@VERS_2.0} type of @samp{.symver} directive. You can only
+declare one version of a symbol as the default in this manner; otherwise
+you would effectively have multiple definitions of the same symbol.
+
+If you wish to bind a reference to a specific version of the symbol
+within the shared library, you can use the aliases of convenience
+(i.e. @samp{old_foo}), or you can use the @samp{.symver} directive to
+specifically bind to an external version of the function in question.
+
+@node Expressions
+@section Expressions in Linker Scripts
+@cindex expressions
+@cindex arithmetic
+The syntax for expressions in the linker script language is identical to
+that of C expressions. All expressions are evaluated as integers. All
+expressions are evaluated in the same size, which is 32 bits if both the
+host and target are 32 bits, and is otherwise 64 bits.
+
+You can use and set symbol values in expressions.
+
+The linker defines several special purpose builtin functions for use in
+expressions.
+
+@menu
+* Constants:: Constants
+* Symbols:: Symbol Names
+* Location Counter:: The Location Counter
+* Operators:: Operators
+* Evaluation:: Evaluation
+* Expression Section:: The Section of an Expression
+* Builtin Functions:: Builtin Functions
+@end menu
+
+@node Constants
+@subsection Constants
+@cindex integer notation
+@cindex constants in linker scripts
+All constants are integers.
+
+As in C, the linker considers an integer beginning with @samp{0} to be
+octal, and an integer beginning with @samp{0x} or @samp{0X} to be
+hexadecimal. The linker considers other integers to be decimal.
+
+@cindex scaled integers
+@cindex K and M integer suffixes
+@cindex M and K integer suffixes
+@cindex suffixes for integers
+@cindex integer suffixes
+In addition, you can use the suffixes @code{K} and @code{M} to scale a
+constant by
+@c TEXI2ROFF-KILL
+@ifinfo
+@c END TEXI2ROFF-KILL
+@code{1024} or @code{1024*1024}
+@c TEXI2ROFF-KILL
+@end ifinfo
+@tex
+${\rm 1024}$ or ${\rm 1024}^2$
+@end tex
+@c END TEXI2ROFF-KILL
+respectively. For example, the following all refer to the same quantity:
+@smallexample
+ _fourk_1 = 4K;
+ _fourk_2 = 4096;
+ _fourk_3 = 0x1000;
+@end smallexample
+
+@node Symbols
+@subsection Symbol Names
+@cindex symbol names
+@cindex names
+@cindex quoted symbol names
+@kindex "
+Unless quoted, symbol names start with a letter, underscore, or period
+and may include letters, digits, underscores, periods, and hyphens.
+Unquoted symbol names must not conflict with any keywords. You can
+specify a symbol which contains odd characters or has the same name as a
+keyword by surrounding the symbol name in double quotes:
+@smallexample
+ "SECTION" = 9;
+ "with a space" = "also with a space" + 10;
+@end smallexample
+
+Since symbols can contain many non-alphabetic characters, it is safest
+to delimit symbols with spaces. For example, @samp{A-B} is one symbol,
+whereas @samp{A - B} is an expression involving subtraction.
+
+@node Location Counter
+@subsection The Location Counter
+@kindex .
+@cindex dot
+@cindex location counter
+@cindex current output location
+The special linker variable @dfn{dot} @samp{.} always contains the
+current output location counter. Since the @code{.} always refers to a
+location in an output section, it may only appear in an expression
+within a @code{SECTIONS} command. The @code{.} symbol may appear
+anywhere that an ordinary symbol is allowed in an expression.
+
+@cindex holes
+Assigning a value to @code{.} will cause the location counter to be
+moved. This may be used to create holes in the output section. The
+location counter may never be moved backwards.
+
+@smallexample
+SECTIONS
+@{
+ output :
+ @{
+ file1(.text)
+ . = . + 1000;
+ file2(.text)
+ . += 1000;
+ file3(.text)
+ @} = 0x1234;
+@}
+@end smallexample
+@noindent
+In the previous example, the @samp{.text} section from @file{file1} is
+located at the beginning of the output section @samp{output}. It is
+followed by a 1000 byte gap. Then the @samp{.text} section from
+@file{file2} appears, also with a 1000 byte gap following before the
+@samp{.text} section from @file{file3}. The notation @samp{= 0x1234}
+specifies what data to write in the gaps (@pxref{Output Section Fill}).
+
+@need 2000
+@node Operators
+@subsection Operators
+@cindex operators for arithmetic
+@cindex arithmetic operators
+@cindex precedence in expressions
+The linker recognizes the standard C set of arithmetic operators, with
+the standard bindings and precedence levels:
+@c TEXI2ROFF-KILL
+@ifinfo
+@c END TEXI2ROFF-KILL
+@smallexample
+precedence associativity Operators Notes
+(highest)
+1 left ! - ~ (1)
+2 left * / %
+3 left + -
+4 left >> <<
+5 left == != > < <= >=
+6 left &
+7 left |
+8 left &&
+9 left ||
+10 right ? :
+11 right &= += -= *= /= (2)
+(lowest)
+@end smallexample
+Notes:
+(1) Prefix operators
+(2) @xref{Assignments}.
+@c TEXI2ROFF-KILL
+@end ifinfo
+@tex
+\vskip \baselineskip
+%"lispnarrowing" is the extra indent used generally for smallexample
+\hskip\lispnarrowing\vbox{\offinterlineskip
+\hrule
+\halign
+{\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ {\tt #}\ \hfil&\vrule#\cr
+height2pt&\omit&&\omit&&\omit&\cr
+&Precedence&& Associativity &&{\rm Operators}&\cr
+height2pt&\omit&&\omit&&\omit&\cr
+\noalign{\hrule}
+height2pt&\omit&&\omit&&\omit&\cr
+&highest&&&&&\cr
+% '176 is tilde, '~' in tt font
+&1&&left&&\qquad- \char'176\ !\qquad\dag&\cr
+&2&&left&&* / \%&\cr
+&3&&left&&+ -&\cr
+&4&&left&&>> <<&\cr
+&5&&left&&== != > < <= >=&\cr
+&6&&left&&\&&\cr
+&7&&left&&|&\cr
+&8&&left&&{\&\&}&\cr
+&9&&left&&||&\cr
+&10&&right&&? :&\cr
+&11&&right&&\qquad\&= += -= *= /=\qquad\ddag&\cr
+&lowest&&&&&\cr
+height2pt&\omit&&\omit&&\omit&\cr}
+\hrule}
+@end tex
+@iftex
+{
+@obeylines@parskip=0pt@parindent=0pt
+@dag@quad Prefix operators.
+@ddag@quad @xref{Assignments}.
+}
+@end iftex
+@c END TEXI2ROFF-KILL
+
+@node Evaluation
+@subsection Evaluation
+@cindex lazy evaluation
+@cindex expression evaluation order
+The linker evaluates expressions lazily. It only computes the value of
+an expression when absolutely necessary.
+
+The linker needs some information, such as the value of the start
+address of the first section, and the origins and lengths of memory
+regions, in order to do any linking at all. These values are computed
+as soon as possible when the linker reads in the linker script.
+
+However, other values (such as symbol values) are not known or needed
+until after storage allocation. Such values are evaluated later, when
+other information (such as the sizes of output sections) is available
+for use in the symbol assignment expression.
+
+The sizes of sections cannot be known until after allocation, so
+assignments dependent upon these are not performed until after
+allocation.
+
+Some expressions, such as those depending upon the location counter
+@samp{.}, must be evaluated during section allocation.
+
+If the result of an expression is required, but the value is not
+available, then an error results. For example, a script like the
+following
+@smallexample
+@group
+SECTIONS
+ @{
+ .text 9+this_isnt_constant :
+ @{ *(.text) @}
+ @}
+@end group
+@end smallexample
+@noindent
+will cause the error message @samp{non constant expression for initial
+address}.
+
+@node Expression Section
+@subsection The Section of an Expression
+@cindex expression sections
+@cindex absolute expressions
+@cindex relative expressions
+@cindex absolute and relocatable symbols
+@cindex relocatable and absolute symbols
+@cindex symbols, relocatable and absolute
+When the linker evaluates an expression, the result is either absolute
+or relative to some section. A relative expression is expressed as a
+fixed offset from the base of a section.
+
+The position of the expression within the linker script determines
+whether it is absolute or relative. An expression which appears within
+an output section definition is relative to the base of the output
+section. An expression which appears elsewhere will be absolute.
+
+A symbol set to a relative expression will be relocatable if you request
+relocatable output using the @samp{-r} option. That means that a
+further link operation may change the value of the symbol. The symbol's
+section will be the section of the relative expression.
+
+A symbol set to an absolute expression will retain the same value
+through any further link operation. The symbol will be absolute, and
+will not have any particular associated section.
+
+You can use the builtin function @code{ABSOLUTE} to force an expression
+to be absolute when it would otherwise be relative. For example, to
+create an absolute symbol set to the address of the end of the output
+section @samp{.data}:
+@smallexample
+SECTIONS
+ @{
+ .data : @{ *(.data) _edata = ABSOLUTE(.); @}
+ @}
+@end smallexample
+@noindent
+If @samp{ABSOLUTE} were not used, @samp{_edata} would be relative to the
+@samp{.data} section.
+
+@node Builtin Functions
+@subsection Builtin Functions
+@cindex functions in expressions
+The linker script language includes a number of builtin functions for
+use in linker script expressions.
+
+@table @code
+@item ABSOLUTE(@var{exp})
+@kindex ABSOLUTE(@var{exp})
+@cindex expression, absolute
+Return the absolute (non-relocatable, as opposed to non-negative) value
+of the expression @var{exp}. Primarily useful to assign an absolute
+value to a symbol within a section definition, where symbol values are
+normally section relative. @xref{Expression Section}.
+
+@item ADDR(@var{section})
+@kindex ADDR(@var{section})
+@cindex section address in expression
+Return the absolute address (the VMA) of the named @var{section}. Your
+script must previously have defined the location of that section. In
+the following example, @code{symbol_1} and @code{symbol_2} are assigned
+identical values:
+@smallexample
+@group
+SECTIONS @{ @dots{}
+ .output1 :
+ @{
+ start_of_output_1 = ABSOLUTE(.);
+ @dots{}
+ @}
+ .output :
+ @{
+ symbol_1 = ADDR(.output1);
+ symbol_2 = start_of_output_1;
+ @}
+@dots{} @}
+@end group
+@end smallexample
+
+@item ALIGN(@var{exp})
+@kindex ALIGN(@var{exp})
+@cindex round up location counter
+@cindex align location counter
+Return the location counter (@code{.}) aligned to the next @var{exp}
+boundary. @var{exp} must be an expression whose value is a power of
+two. This is equivalent to
+@smallexample
+(. + @var{exp} - 1) & ~(@var{exp} - 1)
+@end smallexample
+
+@code{ALIGN} doesn't change the value of the location counter---it just
+does arithmetic on it. Here is an example which aligns the output
+@code{.data} section to the next @code{0x2000} byte boundary after the
+preceding section and sets a variable within the section to the next
+@code{0x8000} boundary after the input sections:
+@smallexample
+@group
+SECTIONS @{ @dots{}
+ .data ALIGN(0x2000): @{
+ *(.data)
+ variable = ALIGN(0x8000);
+ @}
+@dots{} @}
+@end group
+@end smallexample
+@noindent
+The first use of @code{ALIGN} in this example specifies the location of
+a section because it is used as the optional @var{address} attribute of
+a section definition (@pxref{Output Section Address}). The second use
+of @code{ALIGN} is used to defines the value of a symbol.
+
+The builtin function @code{NEXT} is closely related to @code{ALIGN}.
+
+@item BLOCK(@var{exp})
+@kindex BLOCK(@var{exp})
+This is a synonym for @code{ALIGN}, for compatibility with older linker
+scripts. It is most often seen when setting the address of an output
+section.
+
+@item DEFINED(@var{symbol})
+@kindex DEFINED(@var{symbol})
+@cindex symbol defaults
+Return 1 if @var{symbol} is in the linker global symbol table and is
+defined, otherwise return 0. You can use this function to provide
+default values for symbols. For example, the following script fragment
+shows how to set a global symbol @samp{begin} to the first location in
+the @samp{.text} section---but if a symbol called @samp{begin} already
+existed, its value is preserved:
+
+@smallexample
+@group
+SECTIONS @{ @dots{}
+ .text : @{
+ begin = DEFINED(begin) ? begin : . ;
+ @dots{}
+ @}
+ @dots{}
+@}
+@end group
+@end smallexample
+
+@item LOADADDR(@var{section})
+@kindex LOADADDR(@var{section})
+@cindex section load address in expression
+Return the absolute LMA of the named @var{section}. This is normally
+the same as @code{ADDR}, but it may be different if the @code{AT}
+attribute is used in the output section definition (@pxref{Output
+Section LMA}).
+
+@kindex MAX
+@item MAX(@var{exp1}, @var{exp2})
+Returns the maximum of @var{exp1} and @var{exp2}.
+
+@kindex MIN
+@item MIN(@var{exp1}, @var{exp2})
+Returns the minimum of @var{exp1} and @var{exp2}.
+
+@item NEXT(@var{exp})
+@kindex NEXT(@var{exp})
+@cindex unallocated address, next
+Return the next unallocated address that is a multiple of @var{exp}.
+This function is closely related to @code{ALIGN(@var{exp})}; unless you
+use the @code{MEMORY} command to define discontinuous memory for the
+output file, the two functions are equivalent.
+
+@item SIZEOF(@var{section})
+@kindex SIZEOF(@var{section})
+@cindex section size
+Return the size in bytes of the named @var{section}, if that section has
+been allocated. If the section has not been allocated when this is
+evaluated, the linker will report an error. In the following example,
+@code{symbol_1} and @code{symbol_2} are assigned identical values:
+@smallexample
+@group
+SECTIONS@{ @dots{}
+ .output @{
+ .start = . ;
+ @dots{}
+ .end = . ;
+ @}
+ symbol_1 = .end - .start ;
+ symbol_2 = SIZEOF(.output);
+@dots{} @}
+@end group
+@end smallexample
+
+@item SIZEOF_HEADERS
+@itemx sizeof_headers
+@kindex SIZEOF_HEADERS
+@cindex header size
+Return the size in bytes of the output file's headers. This is
+information which appears at the start of the output file. You can use
+this number when setting the start address of the first section, if you
+choose, to facilitate paging.
+
+@cindex not enough room for program headers
+@cindex program headers, not enough room
+When producing an ELF output file, if the linker script uses the
+@code{SIZEOF_HEADERS} builtin function, the linker must compute the
+number of program headers before it has determined all the section
+addresses and sizes. If the linker later discovers that it needs
+additional program headers, it will report an error @samp{not enough
+room for program headers}. To avoid this error, you must avoid using
+the @code{SIZEOF_HEADERS} function, or you must rework your linker
+script to avoid forcing the linker to use additional program headers, or
+you must define the program headers yourself using the @code{PHDRS}
+command (@pxref{PHDRS}).
+@end table
+
+@node Implicit Linker Scripts
+@section Implicit Linker Scripts
+@cindex implicit linker scripts
+If you specify a linker input file which the linker can not recognize as
+an object file or an archive file, it will try to read the file as a
+linker script. If the file can not be parsed as a linker script, the
+linker will report an error.
+
+An implicit linker script will not replace the default linker script.
+
+Typically an implicit linker script would contain only symbol
+assignments, or the @code{INPUT}, @code{GROUP}, or @code{VERSION}
+commands.
+
+Any input files read because of an implicit linker script will be read
+at the position in the command line where the implicit linker script was
+read. This can affect archive searching.
+
+@ifset GENERIC
+@node Machine Dependent
+@chapter Machine Dependent Features
+
+@cindex machine dependencies
+@code{ld} has additional features on some platforms; the following
+sections describe them. Machines where @code{ld} has no additional
+functionality are not listed.
+
+@menu
+* H8/300:: @code{ld} and the H8/300
+* i960:: @code{ld} and the Intel 960 family
+* ARM:: @code{ld} and the ARM family
+@end menu
+@end ifset
+
+@c FIXME! This could use @raisesections/@lowersections, but there seems to be a conflict
+@c between those and node-defaulting.
+@ifset H8300
+@ifclear GENERIC
+@raisesections
+@end ifclear
+
+@node H8/300
+@section @code{ld} and the H8/300
+
+@cindex H8/300 support
+For the H8/300, @code{ld} can perform these global optimizations when
+you specify the @samp{--relax} command-line option.
+
+@table @emph
+@cindex relaxing on H8/300
+@item relaxing address modes
+@code{ld} finds all @code{jsr} and @code{jmp} instructions whose
+targets are within eight bits, and turns them into eight-bit
+program-counter relative @code{bsr} and @code{bra} instructions,
+respectively.
+
+@cindex synthesizing on H8/300
+@item synthesizing instructions
+@c FIXME: specifically mov.b, or any mov instructions really?
+@code{ld} finds all @code{mov.b} instructions which use the
+sixteen-bit absolute address form, but refer to the top
+page of memory, and changes them to use the eight-bit address form.
+(That is: the linker turns @samp{mov.b @code{@@}@var{aa}:16} into
+@samp{mov.b @code{@@}@var{aa}:8} whenever the address @var{aa} is in the
+top page of memory).
+@end table
+
+@ifclear GENERIC
+@lowersections
+@end ifclear
+@end ifset
+
+@ifclear GENERIC
+@ifset Hitachi
+@c This stuff is pointless to say unless you're especially concerned
+@c with Hitachi chips; don't enable it for generic case, please.
+@node Hitachi
+@chapter @code{ld} and other Hitachi chips
+
+@code{ld} also supports the H8/300H, the H8/500, and the Hitachi SH. No
+special features, commands, or command-line options are required for
+these chips.
+@end ifset
+@end ifclear
+
+@ifset I960
+@ifclear GENERIC
+@raisesections
+@end ifclear
+
+@node i960
+@section @code{ld} and the Intel 960 family
+
+@cindex i960 support
+
+You can use the @samp{-A@var{architecture}} command line option to
+specify one of the two-letter names identifying members of the 960
+family; the option specifies the desired output target, and warns of any
+incompatible instructions in the input files. It also modifies the
+linker's search strategy for archive libraries, to support the use of
+libraries specific to each particular architecture, by including in the
+search loop names suffixed with the string identifying the architecture.
+
+For example, if your @code{ld} command line included @w{@samp{-ACA}} as
+well as @w{@samp{-ltry}}, the linker would look (in its built-in search
+paths, and in any paths you specify with @samp{-L}) for a library with
+the names
+
+@smallexample
+@group
+try
+libtry.a
+tryca
+libtryca.a
+@end group
+@end smallexample
+
+@noindent
+The first two possibilities would be considered in any event; the last
+two are due to the use of @w{@samp{-ACA}}.
+
+You can meaningfully use @samp{-A} more than once on a command line, since
+the 960 architecture family allows combination of target architectures; each
+use will add another pair of name variants to search for when @w{@samp{-l}}
+specifies a library.
+
+@cindex @code{--relax} on i960
+@cindex relaxing on i960
+@code{ld} supports the @samp{--relax} option for the i960 family. If
+you specify @samp{--relax}, @code{ld} finds all @code{balx} and
+@code{calx} instructions whose targets are within 24 bits, and turns
+them into 24-bit program-counter relative @code{bal} and @code{cal}
+instructions, respectively. @code{ld} also turns @code{cal}
+instructions into @code{bal} instructions when it determines that the
+target subroutine is a leaf routine (that is, the target subroutine does
+not itself call any subroutines).
+
+@ifclear GENERIC
+@lowersections
+@end ifclear
+@end ifset
+
+@ifclear GENERIC
+@raisesections
+@end ifclear
+
+@node ARM
+@section @code{ld}'s support for interworking between ARM and Thumb code
+
+@cindex ARM interworking support
+@cindex --support-old-code
+For the ARM, @code{ld} will generate code stubs to allow functions calls
+betweem ARM and Thumb code. These stubs only work with code that has
+been compiled and assembled with the @samp{-mthumb-interwork} command
+line option. If it is necessary to link with old ARM object files or
+libraries, which have not been compiled with the -mthumb-interwork
+option then the @samp{--support-old-code} command line switch should be
+given to the linker. This will make it generate larger stub functions
+which will work with non-interworking aware ARM code. Note, however,
+the linker does not support generating stubs for function calls to
+non-interworking aware Thumb code.
+
+@ifclear GENERIC
+@lowersections
+@end ifclear
+
+@ifclear SingleFormat
+@node BFD
+@chapter BFD
+
+@cindex back end
+@cindex object file management
+@cindex object formats available
+@kindex objdump -i
+The linker accesses object and archive files using the BFD libraries.
+These libraries allow the linker to use the same routines to operate on
+object files whatever the object file format. A different object file
+format can be supported simply by creating a new BFD back end and adding
+it to the library. To conserve runtime memory, however, the linker and
+associated tools are usually configured to support only a subset of the
+object file formats available. You can use @code{objdump -i}
+(@pxref{objdump,,objdump,binutils.info,The GNU Binary Utilities}) to
+list all the formats available for your configuration.
+
+@cindex BFD requirements
+@cindex requirements for BFD
+As with most implementations, BFD is a compromise between
+several conflicting requirements. The major factor influencing
+BFD design was efficiency: any time used converting between
+formats is time which would not have been spent had BFD not
+been involved. This is partly offset by abstraction payback; since
+BFD simplifies applications and back ends, more time and care
+may be spent optimizing algorithms for a greater speed.
+
+One minor artifact of the BFD solution which you should bear in
+mind is the potential for information loss. There are two places where
+useful information can be lost using the BFD mechanism: during
+conversion and during output. @xref{BFD information loss}.
+
+@menu
+* BFD outline:: How it works: an outline of BFD
+@end menu
+
+@node BFD outline
+@section How it works: an outline of BFD
+@cindex opening object files
+@include bfdsumm.texi
+@end ifclear
+
+@node Reporting Bugs
+@chapter Reporting Bugs
+@cindex bugs in @code{ld}
+@cindex reporting bugs in @code{ld}
+
+Your bug reports play an essential role in making @code{ld} reliable.
+
+Reporting a bug may help you by bringing a solution to your problem, or
+it may not. But in any case the principal function of a bug report is
+to help the entire community by making the next version of @code{ld}
+work better. Bug reports are your contribution to the maintenance of
+@code{ld}.
+
+In order for a bug report to serve its purpose, you must include the
+information that enables us to fix the bug.
+
+@menu
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+@end menu
+
+@node Bug Criteria
+@section Have you found a bug?
+@cindex bug criteria
+
+If you are not sure whether you have found a bug, here are some guidelines:
+
+@itemize @bullet
+@cindex fatal signal
+@cindex linker crash
+@cindex crash of linker
+@item
+If the linker gets a fatal signal, for any input whatever, that is a
+@code{ld} bug. Reliable linkers never crash.
+
+@cindex error on valid input
+@item
+If @code{ld} produces an error message for valid input, that is a bug.
+
+@cindex invalid input
+@item
+If @code{ld} does not produce an error message for invalid input, that
+may be a bug. In the general case, the linker can not verify that
+object files are correct.
+
+@item
+If you are an experienced user of linkers, your suggestions for
+improvement of @code{ld} are welcome in any case.
+@end itemize
+
+@node Bug Reporting
+@section How to report bugs
+@cindex bug reports
+@cindex @code{ld} bugs, reporting
+
+A number of companies and individuals offer support for @sc{gnu}
+products. If you obtained @code{ld} from a support organization, we
+recommend you contact that organization first.
+
+You can find contact information for many support companies and
+individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
+distribution.
+
+Otherwise, send bug reports for @code{ld} to
+@samp{bug-gnu-utils@@gnu.org}.
+
+The fundamental principle of reporting bugs usefully is this:
+@strong{report all the facts}. If you are not sure whether to state a
+fact or leave it out, state it!
+
+Often people omit facts because they think they know what causes the
+problem and assume that some details do not matter. Thus, you might
+assume that the name of a symbol you use in an example does not matter.
+Well, probably it does not, but one cannot be sure. Perhaps the bug is
+a stray memory reference which happens to fetch from the location where
+that name is stored in memory; perhaps, if the name were different, the
+contents of that location would fool the linker into doing the right
+thing despite the bug. Play it safe and give a specific, complete
+example. That is the easiest thing for you to do, and the most helpful.
+
+Keep in mind that the purpose of a bug report is to enable us to fix the bug if
+it is new to us. Therefore, always write your bug reports on the assumption
+that the bug has not been reported previously.
+
+Sometimes people give a few sketchy facts and ask, ``Does this ring a
+bell?'' Those bug reports are useless, and we urge everyone to
+@emph{refuse to respond to them} except to chide the sender to report
+bugs properly.
+
+To enable us to fix the bug, you should include all these things:
+
+@itemize @bullet
+@item
+The version of @code{ld}. @code{ld} announces it if you start it with
+the @samp{--version} argument.
+
+Without this, we will not know whether there is any point in looking for
+the bug in the current version of @code{ld}.
+
+@item
+Any patches you may have applied to the @code{ld} source, including any
+patches made to the @code{BFD} library.
+
+@item
+The type of machine you are using, and the operating system name and
+version number.
+
+@item
+What compiler (and its version) was used to compile @code{ld}---e.g.
+``@code{gcc-2.7}''.
+
+@item
+The command arguments you gave the linker to link your example and
+observe the bug. To guarantee you will not omit something important,
+list them all. A copy of the Makefile (or the output from make) is
+sufficient.
+
+If we were to try to guess the arguments, we would probably guess wrong
+and then we might not encounter the bug.
+
+@item
+A complete input file, or set of input files, that will reproduce the
+bug. It is generally most helpful to send the actual object files,
+uuencoded if necessary to get them through the mail system. Making them
+available for anonymous FTP is not as good, but may be the only
+reasonable choice for large object files.
+
+If the source files were assembled using @code{gas} or compiled using
+@code{gcc}, then it may be OK to send the source files rather than the
+object files. In this case, be sure to say exactly what version of
+@code{gas} or @code{gcc} was used to produce the object files. Also say
+how @code{gas} or @code{gcc} were configured.
+
+@item
+A description of what behavior you observe that you believe is
+incorrect. For example, ``It gets a fatal signal.''
+
+Of course, if the bug is that @code{ld} gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might
+not notice unless it is glaringly wrong. You might as well not give us
+a chance to make a mistake.
+
+Even if the problem you experience is a fatal signal, you should still
+say so explicitly. Suppose something strange is going on, such as, your
+copy of @code{ld} is out of synch, or you have encountered a bug in the
+C library on your system. (This has happened!) Your copy might crash
+and ours would not. If you told us to expect a crash, then when ours
+fails to crash, we would know that the bug was not happening for us. If
+you had not told us to expect a crash, then we would not be able to draw
+any conclusion from our observations.
+
+@item
+If you wish to suggest changes to the @code{ld} source, send us context
+diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or
+@samp{-p} option. Always send diffs from the old file to the new file.
+If you even discuss something in the @code{ld} source, refer to it by
+context, not by line number.
+
+The line numbers in our development sources will not match those in your
+sources. Your line numbers would convey no useful information to us.
+@end itemize
+
+Here are some things that are not necessary:
+
+@itemize @bullet
+@item
+A description of the envelope of the bug.
+
+Often people who encounter a bug spend a lot of time investigating
+which changes to the input file will make the bug go away and which
+changes will not affect it.
+
+This is often time consuming and not very useful, because the way we
+will find the bug is by running a single example under the debugger
+with breakpoints, not by pure deduction from a series of examples.
+We recommend that you save your time for something else.
+
+Of course, if you can find a simpler example to report @emph{instead}
+of the original one, that is a convenience for us. Errors in the
+output will be easier to spot, running under the debugger will take
+less time, and so on.
+
+However, simplification is not vital; if you do not want to do this,
+report the bug anyway and send us the entire test case you used.
+
+@item
+A patch for the bug.
+
+A patch for the bug does help us if it is a good one. But do not omit
+the necessary information, such as the test case, on the assumption that
+a patch is all we need. We might see problems with your patch and decide
+to fix the problem another way, or we might not understand it at all.
+
+Sometimes with a program as complicated as @code{ld} it is very hard to
+construct an example that will make the program follow a certain path
+through the code. If you do not send us the example, we will not be
+able to construct one, so we will not be able to verify that the bug is
+fixed.
+
+And if we cannot understand what bug you are trying to fix, or why your
+patch should be an improvement, we will not install it. A test case will
+help us to understand.
+
+@item
+A guess about what the bug is or what it depends on.
+
+Such guesses are usually wrong. Even we cannot guess right about such
+things without first using the debugger to find the facts.
+@end itemize
+
+@node MRI
+@appendix MRI Compatible Script Files
+@cindex MRI compatibility
+To aid users making the transition to @sc{gnu} @code{ld} from the MRI
+linker, @code{ld} can use MRI compatible linker scripts as an
+alternative to the more general-purpose linker scripting language
+described in @ref{Scripts}. MRI compatible linker scripts have a much
+simpler command set than the scripting language otherwise used with
+@code{ld}. @sc{gnu} @code{ld} supports the most commonly used MRI
+linker commands; these commands are described here.
+
+In general, MRI scripts aren't of much use with the @code{a.out} object
+file format, since it only has three sections and MRI scripts lack some
+features to make use of them.
+
+You can specify a file containing an MRI-compatible script using the
+@samp{-c} command-line option.
+
+Each command in an MRI-compatible script occupies its own line; each
+command line starts with the keyword that identifies the command (though
+blank lines are also allowed for punctuation). If a line of an
+MRI-compatible script begins with an unrecognized keyword, @code{ld}
+issues a warning message, but continues processing the script.
+
+Lines beginning with @samp{*} are comments.
+
+You can write these commands using all upper-case letters, or all
+lower case; for example, @samp{chip} is the same as @samp{CHIP}.
+The following list shows only the upper-case form of each command.
+
+@table @code
+@cindex @code{ABSOLUTE} (MRI)
+@item ABSOLUTE @var{secname}
+@itemx ABSOLUTE @var{secname}, @var{secname}, @dots{} @var{secname}
+Normally, @code{ld} includes in the output file all sections from all
+the input files. However, in an MRI-compatible script, you can use the
+@code{ABSOLUTE} command to restrict the sections that will be present in
+your output program. If the @code{ABSOLUTE} command is used at all in a
+script, then only the sections named explicitly in @code{ABSOLUTE}
+commands will appear in the linker output. You can still use other
+input sections (whatever you select on the command line, or using
+@code{LOAD}) to resolve addresses in the output file.
+
+@cindex @code{ALIAS} (MRI)
+@item ALIAS @var{out-secname}, @var{in-secname}
+Use this command to place the data from input section @var{in-secname}
+in a section called @var{out-secname} in the linker output file.
+
+@var{in-secname} may be an integer.
+
+@cindex @code{ALIGN} (MRI)
+@item ALIGN @var{secname} = @var{expression}
+Align the section called @var{secname} to @var{expression}. The
+@var{expression} should be a power of two.
+
+@cindex @code{BASE} (MRI)
+@item BASE @var{expression}
+Use the value of @var{expression} as the lowest address (other than
+absolute addresses) in the output file.
+
+@cindex @code{CHIP} (MRI)
+@item CHIP @var{expression}
+@itemx CHIP @var{expression}, @var{expression}
+This command does nothing; it is accepted only for compatibility.
+
+@cindex @code{END} (MRI)
+@item END
+This command does nothing whatever; it's only accepted for compatibility.
+
+@cindex @code{FORMAT} (MRI)
+@item FORMAT @var{output-format}
+Similar to the @code{OUTPUT_FORMAT} command in the more general linker
+language, but restricted to one of these output formats:
+
+@enumerate
+@item
+S-records, if @var{output-format} is @samp{S}
+
+@item
+IEEE, if @var{output-format} is @samp{IEEE}
+
+@item
+COFF (the @samp{coff-m68k} variant in BFD), if @var{output-format} is
+@samp{COFF}
+@end enumerate
+
+@cindex @code{LIST} (MRI)
+@item LIST @var{anything}@dots{}
+Print (to the standard output file) a link map, as produced by the
+@code{ld} command-line option @samp{-M}.
+
+The keyword @code{LIST} may be followed by anything on the
+same line, with no change in its effect.
+
+@cindex @code{LOAD} (MRI)
+@item LOAD @var{filename}
+@itemx LOAD @var{filename}, @var{filename}, @dots{} @var{filename}
+Include one or more object file @var{filename} in the link; this has the
+same effect as specifying @var{filename} directly on the @code{ld}
+command line.
+
+@cindex @code{NAME} (MRI)
+@item NAME @var{output-name}
+@var{output-name} is the name for the program produced by @code{ld}; the
+MRI-compatible command @code{NAME} is equivalent to the command-line
+option @samp{-o} or the general script language command @code{OUTPUT}.
+
+@cindex @code{ORDER} (MRI)
+@item ORDER @var{secname}, @var{secname}, @dots{} @var{secname}
+@itemx ORDER @var{secname} @var{secname} @var{secname}
+Normally, @code{ld} orders the sections in its output file in the
+order in which they first appear in the input files. In an MRI-compatible
+script, you can override this ordering with the @code{ORDER} command. The
+sections you list with @code{ORDER} will appear first in your output
+file, in the order specified.
+
+@cindex @code{PUBLIC} (MRI)
+@item PUBLIC @var{name}=@var{expression}
+@itemx PUBLIC @var{name},@var{expression}
+@itemx PUBLIC @var{name} @var{expression}
+Supply a value (@var{expression}) for external symbol
+@var{name} used in the linker input files.
+
+@cindex @code{SECT} (MRI)
+@item SECT @var{secname}, @var{expression}
+@itemx SECT @var{secname}=@var{expression}
+@itemx SECT @var{secname} @var{expression}
+You can use any of these three forms of the @code{SECT} command to
+specify the start address (@var{expression}) for section @var{secname}.
+If you have more than one @code{SECT} statement for the same
+@var{secname}, only the @emph{first} sets the start address.
+@end table
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@tex
+% I think something like @colophon should be in texinfo. In the
+% meantime:
+\long\def\colophon{\hbox to0pt{}\vfill
+\centerline{The body of this manual is set in}
+\centerline{\fontname\tenrm,}
+\centerline{with headings in {\bf\fontname\tenbf}}
+\centerline{and examples in {\tt\fontname\tentt}.}
+\centerline{{\it\fontname\tenit\/} and}
+\centerline{{\sl\fontname\tensl\/}}
+\centerline{are used for emphasis.}\vfill}
+\page\colophon
+% Blame: doc@cygnus.com, 28mar91.
+@end tex
+
+
+@contents
+@bye
+
+
diff --git a/ld/ldcref.c b/ld/ldcref.c
new file mode 100644
index 00000000000..96e0d2d9df4
--- /dev/null
+++ b/ld/ldcref.c
@@ -0,0 +1,549 @@
+/* ldcref.c -- output a cross reference table
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file holds routines that manage the cross reference table.
+ The table is used to generate cross reference reports. It is also
+ used to implement the NOCROSSREFS command in the linker script. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libiberty.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+
+/* We keep an instance of this structure for each reference to a
+ symbol from a given object. */
+
+struct cref_ref
+{
+ /* The next reference. */
+ struct cref_ref *next;
+ /* The object. */
+ bfd *abfd;
+ /* True if the symbol is defined. */
+ unsigned int def : 1;
+ /* True if the symbol is common. */
+ unsigned int common : 1;
+ /* True if the symbol is undefined. */
+ unsigned int undef : 1;
+};
+
+/* We keep a hash table of symbols. Each entry looks like this. */
+
+struct cref_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* The demangled name. */
+ char *demangled;
+ /* References to and definitions of this symbol. */
+ struct cref_ref *refs;
+};
+
+/* This is what the hash table looks like. */
+
+struct cref_hash_table
+{
+ struct bfd_hash_table root;
+};
+
+/* Local functions. */
+
+static struct bfd_hash_entry *cref_hash_newfunc
+ PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static boolean cref_fill_array PARAMS ((struct cref_hash_entry *, PTR));
+static int cref_sort_array PARAMS ((const PTR, const PTR));
+static void output_one_cref PARAMS ((FILE *, struct cref_hash_entry *));
+static boolean check_nocrossref PARAMS ((struct cref_hash_entry *, PTR));
+static void check_refs
+ PARAMS ((struct cref_hash_entry *, struct bfd_link_hash_entry *,
+ struct lang_nocrossrefs *));
+static void check_reloc_refs PARAMS ((bfd *, asection *, PTR));
+
+/* Look up an entry in the cref hash table. */
+
+#define cref_hash_lookup(table, string, create, copy) \
+ ((struct cref_hash_entry *) \
+ bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
+
+/* Traverse the cref hash table. */
+
+#define cref_hash_traverse(table, func, info) \
+ (bfd_hash_traverse \
+ (&(table)->root, \
+ (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \
+ (info)))
+
+/* The cref hash table. */
+
+static struct cref_hash_table cref_table;
+
+/* Whether the cref hash table has been initialized. */
+
+static boolean cref_initialized;
+
+/* The number of symbols seen so far. */
+
+static size_t cref_symcount;
+
+/* Create an entry in a cref hash table. */
+
+static struct bfd_hash_entry *
+cref_hash_newfunc (entry, table, string)
+ struct bfd_hash_entry *entry;
+ struct bfd_hash_table *table;
+ const char *string;
+{
+ struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct cref_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct cref_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ if (ret != NULL)
+ {
+ /* Set local fields. */
+ ret->demangled = NULL;
+ ret->refs = NULL;
+
+ /* Keep a count of the number of entries created in the hash
+ table. */
+ ++cref_symcount;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Add a symbol to the cref hash table. This is called for every
+ symbol that is seen during the link. */
+
+/*ARGSUSED*/
+void
+add_cref (name, abfd, section, value)
+ const char *name;
+ bfd *abfd;
+ asection *section;
+ bfd_vma value;
+{
+ struct cref_hash_entry *h;
+ struct cref_ref *r;
+
+ if (! cref_initialized)
+ {
+ if (! bfd_hash_table_init (&cref_table.root, cref_hash_newfunc))
+ einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
+ cref_initialized = true;
+ }
+
+ h = cref_hash_lookup (&cref_table, name, true, false);
+ if (h == NULL)
+ einfo (_("%X%P: cref_hash_lookup failed: %E\n"));
+
+ for (r = h->refs; r != NULL; r = r->next)
+ if (r->abfd == abfd)
+ break;
+
+ if (r == NULL)
+ {
+ r = (struct cref_ref *) xmalloc (sizeof *r);
+ r->next = h->refs;
+ h->refs = r;
+ r->abfd = abfd;
+ r->def = false;
+ r->common = false;
+ r->undef = false;
+ }
+
+ if (bfd_is_und_section (section))
+ r->undef = true;
+ else if (bfd_is_com_section (section))
+ r->common = true;
+ else
+ r->def = true;
+}
+
+/* Copy the addresses of the hash table entries into an array. This
+ is called via cref_hash_traverse. We also fill in the demangled
+ name. */
+
+static boolean
+cref_fill_array (h, data)
+ struct cref_hash_entry *h;
+ PTR data;
+{
+ struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;
+
+ ASSERT (h->demangled == NULL);
+ h->demangled = demangle (h->root.string);
+
+ **pph = h;
+
+ ++*pph;
+
+ return true;
+}
+
+/* Sort an array of cref hash table entries by name. */
+
+static int
+cref_sort_array (a1, a2)
+ const PTR a1;
+ const PTR a2;
+{
+ const struct cref_hash_entry **p1 = (const struct cref_hash_entry **) a1;
+ const struct cref_hash_entry **p2 = (const struct cref_hash_entry **) a2;
+
+ return strcmp ((*p1)->demangled, (*p2)->demangled);
+}
+
+/* Write out the cref table. */
+
+#define FILECOL (50)
+
+void
+output_cref (fp)
+ FILE *fp;
+{
+ int len;
+ struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
+ const char *msg;
+
+ fprintf (fp, _("\nCross Reference Table\n\n"));
+ msg = _("Symbol");
+ fprintf (fp, msg);
+ len = strlen (msg);
+ while (len < FILECOL)
+ {
+ putc (' ' , fp);
+ ++len;
+ }
+ fprintf (fp, _("File\n"));
+
+ if (! cref_initialized)
+ {
+ fprintf (fp, _("No symbols\n"));
+ return;
+ }
+
+ csyms = ((struct cref_hash_entry **)
+ xmalloc (cref_symcount * sizeof (*csyms)));
+
+ csym_fill = csyms;
+ cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
+ ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);
+
+ qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);
+
+ csym_end = csyms + cref_symcount;
+ for (csym = csyms; csym < csym_end; csym++)
+ output_one_cref (fp, *csym);
+}
+
+/* Output one entry in the cross reference table. */
+
+static void
+output_one_cref (fp, h)
+ FILE *fp;
+ struct cref_hash_entry *h;
+{
+ int len;
+ struct bfd_link_hash_entry *hl;
+ struct cref_ref *r;
+
+ hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
+ false, true);
+ if (hl == NULL)
+ einfo ("%P: symbol `%T' missing from main hash table\n",
+ h->root.string);
+ else
+ {
+ /* If this symbol is defined in a dynamic object but never
+ referenced by a normal object, then don't print it. */
+ if (hl->type == bfd_link_hash_defined)
+ {
+ if (hl->u.def.section->output_section == NULL)
+ return;
+ if (hl->u.def.section->owner != NULL
+ && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
+ {
+ for (r = h->refs; r != NULL; r = r->next)
+ if ((r->abfd->flags & DYNAMIC) == 0)
+ break;
+ if (r == NULL)
+ return;
+ }
+ }
+ }
+
+ fprintf (fp, "%s ", h->demangled);
+ len = strlen (h->demangled) + 1;
+
+ for (r = h->refs; r != NULL; r = r->next)
+ {
+ if (r->def)
+ {
+ while (len < FILECOL)
+ {
+ putc (' ', fp);
+ ++len;
+ }
+ lfinfo (fp, "%B\n", r->abfd);
+ len = 0;
+ }
+ }
+
+ for (r = h->refs; r != NULL; r = r->next)
+ {
+ if (! r->def)
+ {
+ while (len < FILECOL)
+ {
+ putc (' ', fp);
+ ++len;
+ }
+ lfinfo (fp, "%B\n", r->abfd);
+ len = 0;
+ }
+ }
+
+ ASSERT (len == 0);
+}
+
+/* Check for prohibited cross references. */
+
+void
+check_nocrossrefs ()
+{
+ if (! cref_initialized)
+ return;
+
+ cref_hash_traverse (&cref_table, check_nocrossref, (PTR) NULL);
+}
+
+/* Check one symbol to see if it is a prohibited cross reference. */
+
+/*ARGSUSED*/
+static boolean
+check_nocrossref (h, ignore)
+ struct cref_hash_entry *h;
+ PTR ignore;
+{
+ struct bfd_link_hash_entry *hl;
+ asection *defsec;
+ const char *defsecname;
+ struct lang_nocrossrefs *ncrs;
+ struct lang_nocrossref *ncr;
+
+ hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
+ false, true);
+ if (hl == NULL)
+ {
+ einfo (_("%P: symbol `%T' missing from main hash table\n"),
+ h->root.string);
+ return true;
+ }
+
+ if (hl->type != bfd_link_hash_defined
+ && hl->type != bfd_link_hash_defweak)
+ return true;
+
+ defsec = hl->u.def.section->output_section;
+ if (defsec == NULL)
+ return true;
+ defsecname = bfd_get_section_name (defsec->owner, defsec);
+
+ for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
+ for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
+ if (strcmp (ncr->name, defsecname) == 0)
+ check_refs (h, hl, ncrs);
+
+ return true;
+}
+
+/* The struct is used to pass information from check_refs to
+ check_reloc_refs through bfd_map_over_sections. */
+
+struct check_refs_info
+{
+ struct cref_hash_entry *h;
+ asection *defsec;
+ struct lang_nocrossrefs *ncrs;
+ asymbol **asymbols;
+ boolean same;
+};
+
+/* This function is called for each symbol defined in a section which
+ prohibits cross references. We need to look through all references
+ to this symbol, and ensure that the references are not from
+ prohibited sections. */
+
+static void
+check_refs (h, hl, ncrs)
+ struct cref_hash_entry *h;
+ struct bfd_link_hash_entry *hl;
+ struct lang_nocrossrefs *ncrs;
+{
+ struct cref_ref *ref;
+
+ for (ref = h->refs; ref != NULL; ref = ref->next)
+ {
+ lang_input_statement_type *li;
+ asymbol **asymbols;
+ struct check_refs_info info;
+
+ /* We need to look through the relocations for this BFD, to see
+ if any of the relocations which refer to this symbol are from
+ a prohibited section. Note that we need to do this even for
+ the BFD in which the symbol is defined, since even a single
+ BFD might contain a prohibited cross reference; for this
+ case, we set the SAME field in INFO, which will cause
+ CHECK_RELOCS_REFS to check for relocations against the
+ section as well as against the symbol. */
+
+ li = (lang_input_statement_type *) ref->abfd->usrdata;
+ if (li != NULL && li->asymbols != NULL)
+ asymbols = li->asymbols;
+ else
+ {
+ long symsize;
+ long symbol_count;
+
+ symsize = bfd_get_symtab_upper_bound (ref->abfd);
+ if (symsize < 0)
+ einfo (_("%B%F: could not read symbols; %E\n"), ref->abfd);
+ asymbols = (asymbol **) xmalloc (symsize);
+ symbol_count = bfd_canonicalize_symtab (ref->abfd, asymbols);
+ if (symbol_count < 0)
+ einfo (_("%B%F: could not read symbols: %E\n"), ref->abfd);
+ if (li != NULL)
+ {
+ li->asymbols = asymbols;
+ li->symbol_count = symbol_count;
+ }
+ }
+
+ info.h = h;
+ info.defsec = hl->u.def.section;
+ info.ncrs = ncrs;
+ info.asymbols = asymbols;
+ if (ref->abfd == hl->u.def.section->owner)
+ info.same = true;
+ else
+ info.same = false;
+ bfd_map_over_sections (ref->abfd, check_reloc_refs, (PTR) &info);
+
+ if (li == NULL)
+ free (asymbols);
+ }
+}
+
+/* This is called via bfd_map_over_sections. INFO->H is a symbol
+ defined in INFO->DEFSECNAME. If this section maps into any of the
+ sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
+ look through the relocations. If any of the relocations are to
+ INFO->H, then we report a prohibited cross reference error. */
+
+static void
+check_reloc_refs (abfd, sec, iarg)
+ bfd *abfd;
+ asection *sec;
+ PTR iarg;
+{
+ struct check_refs_info *info = (struct check_refs_info *) iarg;
+ asection *outsec;
+ const char *outsecname;
+ asection *outdefsec;
+ const char *outdefsecname;
+ struct lang_nocrossref *ncr;
+ const char *symname;
+ long relsize;
+ arelent **relpp;
+ long relcount;
+ arelent **p, **pend;
+
+ outsec = sec->output_section;
+ outsecname = bfd_get_section_name (outsec->owner, outsec);
+
+ outdefsec = info->defsec->output_section;
+ outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec);
+
+ /* The section where the symbol is defined is permitted. */
+ if (strcmp (outsecname, outdefsecname) == 0)
+ return;
+
+ for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
+ if (strcmp (outsecname, ncr->name) == 0)
+ break;
+
+ if (ncr == NULL)
+ return;
+
+ /* This section is one for which cross references are prohibited.
+ Look through the relocations, and see if any of them are to
+ INFO->H. */
+
+ symname = info->h->root.string;
+
+ relsize = bfd_get_reloc_upper_bound (abfd, sec);
+ if (relsize < 0)
+ einfo (_("%B%F: could not read relocs: %E\n"), abfd);
+ if (relsize == 0)
+ return;
+
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
+ if (relcount < 0)
+ einfo (_("%B%F: could not read relocs: %E\n"), abfd);
+
+ p = relpp;
+ pend = p + relcount;
+ for (; p < pend && *p != NULL; p++)
+ {
+ arelent *q = *p;
+
+ if (q->sym_ptr_ptr != NULL
+ && *q->sym_ptr_ptr != NULL
+ && (strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
+ || (info->same
+ && bfd_get_section (*q->sym_ptr_ptr) == info->defsec)))
+ {
+ /* We found a reloc for the symbol. The symbol is defined
+ in OUTSECNAME. This reloc is from a section which is
+ mapped into a section from which references to OUTSECNAME
+ are prohibited. We must report an error. */
+ einfo (_("%X%C: prohibited cross reference from %s to `%T' in %s\n"),
+ abfd, sec, q->address, outsecname,
+ bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
+ }
+ }
+
+ free (relpp);
+}
diff --git a/ld/ldctor.c b/ld/ldctor.c
new file mode 100644
index 00000000000..0a434b812e1
--- /dev/null
+++ b/ld/ldctor.c
@@ -0,0 +1,383 @@
+/* ldctor.c -- constructor support routines
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ By Steve Chamberlain <sac@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include <ctype.h>
+
+#include "ld.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldmisc.h"
+#include "ldgram.h"
+#include "ldmain.h"
+#include "ldctor.h"
+
+static int ctor_prio PARAMS ((const char *));
+static int ctor_cmp PARAMS ((const PTR, const PTR));
+
+/* The list of statements needed to handle constructors. These are
+ invoked by the command CONSTRUCTORS in the linker script. */
+lang_statement_list_type constructor_list;
+
+/* Whether the constructors should be sorted. Note that this is
+ global for the entire link; we assume that there is only a single
+ CONSTRUCTORS command in the linker script. */
+boolean constructors_sorted;
+
+/* The sets we have seen. */
+struct set_info *sets;
+
+/* Add an entry to a set. H is the entry in the linker hash table.
+ RELOC is the relocation to use for an entry in the set. SECTION
+ and VALUE are the value to add. This is called during the first
+ phase of the link, when we are still gathering symbols together.
+ We just record the information now. The ldctor_find_constructors
+ function will construct the sets. */
+
+void
+ldctor_add_set_entry (h, reloc, name, section, value)
+ struct bfd_link_hash_entry *h;
+ bfd_reloc_code_real_type reloc;
+ const char *name;
+ asection *section;
+ bfd_vma value;
+{
+ struct set_info *p;
+ struct set_element *e;
+ struct set_element **epp;
+
+ for (p = sets; p != (struct set_info *) NULL; p = p->next)
+ if (p->h == h)
+ break;
+
+ if (p == (struct set_info *) NULL)
+ {
+ p = (struct set_info *) xmalloc (sizeof (struct set_info));
+ p->next = sets;
+ sets = p;
+ p->h = h;
+ p->reloc = reloc;
+ p->count = 0;
+ p->elements = NULL;
+ }
+ else
+ {
+ if (p->reloc != reloc)
+ {
+ einfo (_("%P%X: Different relocs used in set %s\n"), h->root.string);
+ return;
+ }
+
+ /* Don't permit a set to be constructed from different object
+ file formats. The same reloc may have different results. We
+ actually could sometimes handle this, but the case is
+ unlikely to ever arise. Sometimes constructor symbols are in
+ unusual sections, such as the absolute section--this appears
+ to be the case in Linux a.out--and in such cases we just
+ assume everything is OK. */
+ if (p->elements != NULL
+ && section->owner != NULL
+ && p->elements->section->owner != NULL
+ && strcmp (bfd_get_target (section->owner),
+ bfd_get_target (p->elements->section->owner)) != 0)
+ {
+ einfo (_("%P%X: Different object file formats composing set %s\n"),
+ h->root.string);
+ return;
+ }
+ }
+
+ e = (struct set_element *) xmalloc (sizeof (struct set_element));
+ e->next = NULL;
+ e->name = name;
+ e->section = section;
+ e->value = value;
+
+ for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next)
+ ;
+ *epp = e;
+
+ ++p->count;
+}
+
+/* Get the priority of a g++ global constructor or destructor from the
+ symbol name. */
+
+static int
+ctor_prio (name)
+ const char *name;
+{
+ /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
+ There might be extra leading underscores, and the $ characters
+ might be something else. The I might be a D. */
+
+ while (*name == '_')
+ ++name;
+
+ if (strncmp (name, "GLOBAL_", sizeof "GLOBAL_" - 1) != 0)
+ return -1;
+
+ name += sizeof "GLOBAL_" - 1;
+
+ if (name[0] != name[2])
+ return -1;
+ if (name[1] != 'I' && name[1] != 'D')
+ return -1;
+ if (! isdigit ((unsigned char) name[3]))
+ return -1;
+
+ return atoi (name + 3);
+}
+
+/* This function is used to sort constructor elements by priority. It
+ is called via qsort. */
+
+static int
+ctor_cmp (p1, p2)
+ const PTR p1;
+ const PTR p2;
+{
+ const struct set_element **pe1 = (const struct set_element **) p1;
+ const struct set_element **pe2 = (const struct set_element **) p2;
+ const char *n1;
+ const char *n2;
+ int prio1;
+ int prio2;
+
+ n1 = (*pe1)->name;
+ if (n1 == NULL)
+ n1 = "";
+ n2 = (*pe2)->name;
+ if (n2 == NULL)
+ n2 = "";
+
+ /* We need to sort in reverse order by priority. When two
+ constructors have the same priority, we should maintain their
+ current relative position. */
+
+ prio1 = ctor_prio (n1);
+ prio2 = ctor_prio (n2);
+
+ /* We sort in reverse order because that is what g++ expects. */
+ if (prio1 < prio2)
+ return 1;
+ else if (prio1 > prio2)
+ return -1;
+
+ /* Force a stable sort. */
+
+ if (pe1 < pe2)
+ return -1;
+ else if (pe1 > pe2)
+ return 1;
+ else
+ return 0;
+}
+
+/* This function is called after the first phase of the link and
+ before the second phase. At this point all set information has
+ been gathered. We now put the statements to build the sets
+ themselves into constructor_list. */
+
+void
+ldctor_build_sets ()
+{
+ static boolean called;
+ lang_statement_list_type *old;
+ boolean header_printed;
+ struct set_info *p;
+
+ /* The emulation code may call us directly, but we only want to do
+ this once. */
+ if (called)
+ return;
+ called = true;
+
+ if (constructors_sorted)
+ {
+ for (p = sets; p != NULL; p = p->next)
+ {
+ int c, i;
+ struct set_element *e;
+ struct set_element **array;
+
+ if (p->elements == NULL)
+ continue;
+
+ c = 0;
+ for (e = p->elements; e != NULL; e = e->next)
+ ++c;
+
+ array = (struct set_element **) xmalloc (c * sizeof *array);
+
+ i = 0;
+ for (e = p->elements; e != NULL; e = e->next)
+ {
+ array[i] = e;
+ ++i;
+ }
+
+ qsort (array, c, sizeof *array, ctor_cmp);
+
+ e = array[0];
+ p->elements = e;
+ for (i = 0; i < c - 1; i++)
+ array[i]->next = array[i + 1];
+ array[i]->next = NULL;
+
+ free (array);
+ }
+ }
+
+ old = stat_ptr;
+ stat_ptr = &constructor_list;
+
+ lang_list_init (stat_ptr);
+
+ header_printed = false;
+ for (p = sets; p != (struct set_info *) NULL; p = p->next)
+ {
+ struct set_element *e;
+ reloc_howto_type *howto;
+ int reloc_size, size;
+
+ /* If the symbol is defined, we may have been invoked from
+ collect, and the sets may already have been built, so we do
+ not do anything. */
+ if (p->h->type == bfd_link_hash_defined
+ || p->h->type == bfd_link_hash_defweak)
+ continue;
+
+ /* For each set we build:
+ set:
+ .long number_of_elements
+ .long element0
+ ...
+ .long elementN
+ .long 0
+ except that we use the right size instead of .long. When
+ generating relocateable output, we generate relocs instead of
+ addresses. */
+ howto = bfd_reloc_type_lookup (output_bfd, p->reloc);
+ if (howto == (reloc_howto_type *) NULL)
+ {
+ if (link_info.relocateable)
+ {
+ einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
+ bfd_get_target (output_bfd),
+ bfd_get_reloc_code_name (p->reloc),
+ p->h->root.string);
+ continue;
+ }
+
+ /* If this is not a relocateable link, all we need is the
+ size, which we can get from the input BFD. */
+ if (p->elements->section->owner != NULL)
+ howto = bfd_reloc_type_lookup (p->elements->section->owner,
+ p->reloc);
+ if (howto == NULL)
+ {
+ einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
+ bfd_get_target (p->elements->section->owner),
+ bfd_get_reloc_code_name (p->reloc),
+ p->h->root.string);
+ continue;
+ }
+ }
+
+ reloc_size = bfd_get_reloc_size (howto);
+ switch (reloc_size)
+ {
+ case 1: size = BYTE; break;
+ case 2: size = SHORT; break;
+ case 4: size = LONG; break;
+ case 8:
+ if (howto->complain_on_overflow == complain_overflow_signed)
+ size = SQUAD;
+ else
+ size = QUAD;
+ break;
+ default:
+ einfo (_("%P%X: Unsupported size %d for set %s\n"),
+ bfd_get_reloc_size (howto), p->h->root.string);
+ size = LONG;
+ break;
+ }
+
+ lang_add_assignment (exp_assop ('=', ".",
+ exp_unop (ALIGN_K,
+ exp_intop (reloc_size))));
+ lang_add_assignment (exp_assop ('=', p->h->root.string,
+ exp_nameop (NAME, ".")));
+ lang_add_data (size, exp_intop ((bfd_vma) p->count));
+
+ for (e = p->elements; e != (struct set_element *) NULL; e = e->next)
+ {
+ if (config.map_file != NULL)
+ {
+ int len;
+
+ if (! header_printed)
+ {
+ minfo (_("\nSet Symbol\n\n"));
+ header_printed = true;
+ }
+
+ minfo ("%s", p->h->root.string);
+ len = strlen (p->h->root.string);
+
+ if (len >= 19)
+ {
+ print_nl ();
+ len = 0;
+ }
+ while (len < 20)
+ {
+ print_space ();
+ ++len;
+ }
+
+ if (e->name != NULL)
+ minfo ("%T\n", e->name);
+ else
+ minfo ("%G\n", e->section->owner, e->section, e->value);
+ }
+
+ /* Need SEC_KEEP for --gc-sections */
+ if (! bfd_is_abs_section (e->section))
+ e->section->flags |= SEC_KEEP;
+
+ if (link_info.relocateable)
+ lang_add_reloc (p->reloc, howto, e->section, e->name,
+ exp_intop (e->value));
+ else
+ lang_add_data (size, exp_relop (e->section, e->value));
+ }
+
+ lang_add_data (size, exp_intop (0));
+ }
+
+ stat_ptr = old;
+}
diff --git a/ld/ldctor.h b/ld/ldctor.h
new file mode 100644
index 00000000000..d873f77f327
--- /dev/null
+++ b/ld/ldctor.h
@@ -0,0 +1,60 @@
+/* ldctor.h - linker constructor support
+ Copyright 1991, 92, 93, 94, 95, 1998 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef LDCTOR_H
+#define LDCTOR_H
+
+/* List of statements needed to handle constructors */
+extern lang_statement_list_type constructor_list;
+
+/* Whether the constructors should be sorted. Note that this is
+ global for the entire link; we assume that there is only a single
+ CONSTRUCTORS command in the linker script. */
+extern boolean constructors_sorted;
+
+/* We keep a list of these structures for each set we build. */
+
+struct set_info
+{
+ struct set_info *next; /* Next set. */
+ struct bfd_link_hash_entry *h; /* Hash table entry. */
+ bfd_reloc_code_real_type reloc; /* Reloc to use for an entry. */
+ size_t count; /* Number of elements. */
+ struct set_element *elements; /* Elements in set. */
+};
+
+struct set_element
+{
+ struct set_element *next; /* Next element. */
+ const char *name; /* Name in set (may be NULL). */
+ asection *section; /* Section of value in set. */
+ bfd_vma value; /* Value in set. */
+};
+
+/* The sets we have seen. */
+
+extern struct set_info *sets;
+
+extern void ldctor_add_set_entry PARAMS ((struct bfd_link_hash_entry *,
+ bfd_reloc_code_real_type,
+ const char *, asection *, bfd_vma));
+extern void ldctor_build_sets PARAMS ((void));
+
+#endif
diff --git a/ld/ldemul.c b/ld/ldemul.c
new file mode 100644
index 00000000000..eab0432da3a
--- /dev/null
+++ b/ld/ldemul.c
@@ -0,0 +1,298 @@
+/* ldemul.c -- clearing house for ld emulation states
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#include "ld.h"
+#include "ldemul.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldfile.h"
+#include "ldmain.h"
+#include "ldemul-list.h"
+
+ld_emulation_xfer_type *ld_emulation;
+
+void
+ldemul_hll(name)
+ char *name;
+{
+ ld_emulation->hll(name);
+}
+
+
+void ldemul_syslib(name)
+ char *name;
+{
+ ld_emulation->syslib(name);
+}
+
+void
+ldemul_after_parse()
+{
+ ld_emulation->after_parse();
+}
+
+void
+ldemul_before_parse()
+{
+ ld_emulation->before_parse();
+}
+
+void
+ldemul_after_open ()
+{
+ ld_emulation->after_open ();
+}
+
+void
+ldemul_after_allocation()
+{
+ ld_emulation->after_allocation();
+}
+
+void
+ldemul_before_allocation()
+{
+ if (ld_emulation->before_allocation)
+ ld_emulation->before_allocation();
+}
+
+
+void
+ldemul_set_output_arch()
+{
+ ld_emulation->set_output_arch();
+}
+
+void
+ldemul_finish()
+{
+ if (ld_emulation->finish)
+ ld_emulation->finish();
+}
+
+void
+ldemul_set_symbols()
+{
+ if (ld_emulation->set_symbols)
+ ld_emulation->set_symbols();
+}
+
+void
+ldemul_create_output_section_statements()
+{
+ if (ld_emulation->create_output_section_statements)
+ ld_emulation->create_output_section_statements();
+}
+
+char *
+ldemul_get_script(isfile)
+ int *isfile;
+{
+ return ld_emulation->get_script(isfile);
+}
+
+boolean
+ldemul_open_dynamic_archive (arch, search, entry)
+ const char *arch;
+ search_dirs_type *search;
+ lang_input_statement_type *entry;
+{
+ if (ld_emulation->open_dynamic_archive)
+ return (*ld_emulation->open_dynamic_archive) (arch, search, entry);
+ return false;
+}
+
+boolean
+ldemul_place_orphan (file, s)
+ lang_input_statement_type *file;
+ asection *s;
+{
+ if (ld_emulation->place_orphan)
+ return (*ld_emulation->place_orphan) (file, s);
+ return false;
+}
+
+int
+ldemul_parse_args (argc, argv)
+ int argc;
+ char **argv;
+{
+ /* Try and use the emulation parser if there is one. */
+ if (ld_emulation->parse_args)
+ {
+ return ld_emulation->parse_args (argc, argv);
+ }
+ return 0;
+}
+
+/* Let the emulation code handle an unrecognized file. */
+
+boolean
+ldemul_unrecognized_file (entry)
+ lang_input_statement_type *entry;
+{
+ if (ld_emulation->unrecognized_file)
+ return (*ld_emulation->unrecognized_file) (entry);
+ return false;
+}
+
+/* Let the emulation code handle a recognized file. */
+
+boolean
+ldemul_recognized_file (entry)
+ lang_input_statement_type *entry;
+{
+ if (ld_emulation->recognized_file)
+ return (*ld_emulation->recognized_file) (entry);
+ return false;
+}
+
+char *
+ldemul_choose_target()
+{
+ return ld_emulation->choose_target();
+}
+
+/* The default choose_target function. */
+
+char *
+ldemul_default_target()
+{
+ char *from_outside = getenv (TARGET_ENVIRON);
+ if (from_outside != (char *)NULL)
+ return from_outside;
+ return ld_emulation->target_name;
+}
+
+void
+after_parse_default()
+{
+
+}
+
+void
+after_open_default ()
+{
+}
+
+void
+after_allocation_default()
+{
+
+}
+
+void
+before_allocation_default()
+{
+
+}
+
+void
+set_output_arch_default()
+{
+ /* Set the output architecture and machine if possible */
+ bfd_set_arch_mach(output_bfd,
+ ldfile_output_architecture, ldfile_output_machine);
+}
+
+/*ARGSUSED*/
+void
+syslib_default(ignore)
+ char *ignore;
+{
+ info_msg (_("%S SYSLIB ignored\n"));
+}
+
+/*ARGSUSED*/
+void
+hll_default(ignore)
+ char *ignore;
+{
+ info_msg (_("%S HLL ignored\n"));
+}
+
+ld_emulation_xfer_type *ld_emulations[] = { EMULATION_LIST };
+
+void
+ldemul_choose_mode(target)
+ char *target;
+{
+ ld_emulation_xfer_type **eptr = ld_emulations;
+ /* Ignore "gld" prefix. */
+ if (target[0] == 'g' && target[1] == 'l' && target[2] == 'd')
+ target += 3;
+ for (; *eptr; eptr++)
+ {
+ if (strcmp(target, (*eptr)->emulation_name) == 0)
+ {
+ ld_emulation = *eptr;
+ return;
+ }
+ }
+ einfo (_("%P: unrecognised emulation mode: %s\n"), target);
+ einfo (_("Supported emulations: "));
+ ldemul_list_emulations (stderr);
+ einfo ("%F\n");
+}
+
+void
+ldemul_list_emulations (f)
+ FILE *f;
+{
+ ld_emulation_xfer_type **eptr = ld_emulations;
+ boolean first = true;
+
+ for (; *eptr; eptr++)
+ {
+ if (first)
+ first = false;
+ else
+ fprintf (f, " ");
+ fprintf (f, "%s", (*eptr)->emulation_name);
+ }
+}
+
+void
+ldemul_list_emulation_options (f)
+ FILE * f;
+{
+ ld_emulation_xfer_type ** eptr;
+ int options_found = 0;
+
+ for (eptr = ld_emulations; * eptr; eptr ++)
+ {
+ ld_emulation_xfer_type * emul = * eptr;
+
+ if (emul->list_options)
+ {
+ fprintf (f, "%s: \n", emul->emulation_name);
+
+ emul->list_options (f);
+
+ options_found = 1;
+ }
+ }
+
+ if (! options_found)
+ fprintf (f, _(" no emulation specific options.\n"));
+}
diff --git a/ld/ldemul.h b/ld/ldemul.h
new file mode 100644
index 00000000000..350de06af33
--- /dev/null
+++ b/ld/ldemul.h
@@ -0,0 +1,149 @@
+/* ld-emul.h - Linker emulation header file
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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 1, or (at your option)
+ any later version.
+
+ GLD 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. */
+
+#ifndef LDEMUL_H
+#define LDEMUL_H
+
+#if ANSI_PROTOTYPES
+struct lang_input_statement_struct;
+struct search_dirs;
+#endif
+
+extern void ldemul_hll PARAMS ((char *));
+extern void ldemul_syslib PARAMS ((char *));
+extern void ldemul_after_parse PARAMS ((void));
+extern void ldemul_before_parse PARAMS ((void));
+extern void ldemul_after_open PARAMS ((void));
+extern void ldemul_after_allocation PARAMS ((void));
+extern void ldemul_before_allocation PARAMS ((void));
+extern void ldemul_set_output_arch PARAMS ((void));
+extern char *ldemul_choose_target PARAMS ((void));
+extern void ldemul_choose_mode PARAMS ((char *));
+extern void ldemul_list_emulations PARAMS ((FILE *));
+extern void ldemul_list_emulation_options PARAMS ((FILE *));
+extern char *ldemul_get_script PARAMS ((int *isfile));
+extern void ldemul_finish PARAMS ((void));
+extern void ldemul_set_symbols PARAMS ((void));
+extern void ldemul_create_output_section_statements PARAMS ((void));
+extern boolean ldemul_place_orphan
+ PARAMS ((struct lang_input_statement_struct *, asection *));
+extern int ldemul_parse_args PARAMS ((int, char **));
+extern boolean ldemul_unrecognized_file
+ PARAMS ((struct lang_input_statement_struct *));
+extern boolean ldemul_recognized_file
+ PARAMS ((struct lang_input_statement_struct *));
+extern boolean ldemul_open_dynamic_archive
+ PARAMS ((const char *, struct search_dirs *,
+ struct lang_input_statement_struct *));
+extern char *ldemul_default_target PARAMS ((void));
+extern void after_parse_default PARAMS ((void));
+extern void after_open_default PARAMS ((void));
+extern void after_allocation_default PARAMS ((void));
+extern void before_allocation_default PARAMS ((void));
+extern void set_output_arch_default PARAMS ((void));
+extern void syslib_default PARAMS ((char*));
+extern void hll_default PARAMS ((char*));
+
+typedef struct ld_emulation_xfer_struct
+{
+ /* Run before parsing the command line and script file.
+ Set the architecture, maybe other things. */
+ void (*before_parse) PARAMS ((void));
+
+ /* Handle the SYSLIB (low level library) script command. */
+ void (*syslib) PARAMS ((char *));
+
+ /* Handle the HLL (high level library) script command. */
+ void (*hll) PARAMS ((char *));
+
+ /* Run after parsing the command line and script file. */
+ void (*after_parse) PARAMS ((void));
+
+ /* Run after opening all input files, and loading the symbols. */
+ void (*after_open) PARAMS ((void));
+
+ /* Run after allocating output sections. */
+ void (*after_allocation) PARAMS ( (void));
+
+ /* Set the output architecture and machine if possible. */
+ void (*set_output_arch) PARAMS ((void));
+
+ /* Decide which target name to use. */
+ char * (*choose_target) PARAMS ((void));
+
+ /* Run before allocating output sections. */
+ void (*before_allocation) PARAMS ((void));
+
+ /* Return the appropriate linker script. */
+ char * (*get_script) PARAMS ((int *isfile));
+
+ /* The name of this emulation. */
+ char *emulation_name;
+
+ /* The output format. */
+ char *target_name;
+
+ /* Run after assigning values from the script. */
+ void (*finish) PARAMS ((void));
+
+ /* Create any output sections needed by the target. */
+ void (*create_output_section_statements) PARAMS ((void));
+
+ /* Try to open a dynamic library. ARCH is an architecture name, and
+ is normally the empty string. ENTRY is the lang_input_statement
+ that should be opened. */
+ boolean (*open_dynamic_archive)
+ PARAMS ((const char *arch, struct search_dirs *,
+ struct lang_input_statement_struct *entry));
+
+ /* Place an orphan section. Return true if it was placed, false if
+ the default action should be taken. This field may be NULL, in
+ which case the default action will always be taken. */
+ boolean (*place_orphan)
+ PARAMS ((struct lang_input_statement_struct *, asection *));
+
+ /* Run after assigning parsing with the args, but before
+ reading the script. Used to initialize symbols used in the script. */
+ void (*set_symbols) PARAMS ((void));
+
+ /* Run to parse args which the base linker doesn't
+ understand. Return non zero on sucess. */
+ int (*parse_args) PARAMS ((int, char **));
+
+ /* Run to handle files which are not recognized as object files or
+ archives. Return true if the file was handled. */
+ boolean (*unrecognized_file)
+ PARAMS ((struct lang_input_statement_struct *));
+
+ /* Run to list the command line options which parse_args handles. */
+ void (* list_options) PARAMS ((FILE *));
+
+ /* Run to specially handle files which *are* recognized as object
+ files or archives. Return true if the file was handled. */
+ boolean (*recognized_file)
+ PARAMS ((struct lang_input_statement_struct *));
+
+} ld_emulation_xfer_type;
+
+typedef enum
+{
+ intel_ic960_ld_mode_enum,
+ default_mode_enum ,
+ intel_gld960_ld_mode_enum
+} lang_emulation_mode_enum_type;
+
+extern ld_emulation_xfer_type *ld_emulations[];
+
+#endif
diff --git a/ld/ldexp.c b/ld/ldexp.c
new file mode 100644
index 00000000000..6c9d726ec19
--- /dev/null
+++ b/ld/ldexp.c
@@ -0,0 +1,985 @@
+/* This module handles expression trees.
+Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/*
+This module is in charge of working out the contents of expressions.
+
+It has to keep track of the relative/absness of a symbol etc. This is
+done by keeping all values in a struct (an etree_value_type) which
+contains a value, a section to which it is relative and a valid bit.
+
+*/
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldgram.h"
+#include "ldlang.h"
+
+static void exp_print_token PARAMS ((token_code_type code));
+static void make_abs PARAMS ((etree_value_type *ptr));
+static etree_value_type new_abs PARAMS ((bfd_vma value));
+static void check PARAMS ((lang_output_section_statement_type *os,
+ const char *name, const char *op));
+static etree_value_type new_rel
+ PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
+static etree_value_type new_rel_from_section
+ PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
+static etree_value_type fold_binary
+ PARAMS ((etree_type *tree,
+ lang_output_section_statement_type *current_section,
+ lang_phase_type allocation_done,
+ bfd_vma dot, bfd_vma *dotp));
+static etree_value_type fold_name
+ PARAMS ((etree_type *tree,
+ lang_output_section_statement_type *current_section,
+ lang_phase_type allocation_done,
+ bfd_vma dot));
+static etree_value_type exp_fold_tree_no_dot
+ PARAMS ((etree_type *tree,
+ lang_output_section_statement_type *current_section,
+ lang_phase_type allocation_done));
+
+static void
+exp_print_token (code)
+ token_code_type code;
+{
+ static CONST struct
+ {
+ token_code_type code;
+ char *name;
+ } table[] =
+ {
+ { INT, "int" },
+ { REL, "relocateable" },
+ { NAME,"NAME" },
+ { PLUSEQ,"+=" },
+ { MINUSEQ,"-=" },
+ { MULTEQ,"*=" },
+ { DIVEQ,"/=" },
+ { LSHIFTEQ,"<<=" },
+ { RSHIFTEQ,">>=" },
+ { ANDEQ,"&=" },
+ { OREQ,"|=" },
+ { OROR,"||" },
+ { ANDAND,"&&" },
+ { EQ,"==" },
+ { NE,"!=" },
+ { LE,"<=" },
+ { GE,">=" },
+ { LSHIFT,"<<" },
+ { RSHIFT,">>=" },
+ { ALIGN_K,"ALIGN" },
+ { BLOCK,"BLOCK" },
+ { SECTIONS,"SECTIONS" },
+ { SIZEOF_HEADERS,"SIZEOF_HEADERS" },
+ { NEXT,"NEXT" },
+ { SIZEOF,"SIZEOF" },
+ { ADDR,"ADDR" },
+ { LOADADDR,"LOADADDR" },
+ { MEMORY,"MEMORY" },
+ { DEFINED,"DEFINED" },
+ { TARGET_K,"TARGET" },
+ { SEARCH_DIR,"SEARCH_DIR" },
+ { MAP,"MAP" },
+ { QUAD,"QUAD" },
+ { SQUAD,"SQUAD" },
+ { LONG,"LONG" },
+ { SHORT,"SHORT" },
+ { BYTE,"BYTE" },
+ { ENTRY,"ENTRY" },
+ { 0,(char *)NULL }
+ };
+ unsigned int idx;
+
+ for (idx = 0; table[idx].name != (char*)NULL; idx++) {
+ if (table[idx].code == code) {
+ fprintf(config.map_file, "%s", table[idx].name);
+ return;
+ }
+ }
+ /* Not in table, just print it alone */
+ fprintf(config.map_file, "%c",code);
+}
+
+static void
+make_abs (ptr)
+ etree_value_type *ptr;
+{
+ asection *s = ptr->section->bfd_section;
+ ptr->value += s->vma;
+ ptr->section = abs_output_section;
+}
+
+static etree_value_type
+new_abs (value)
+ bfd_vma value;
+{
+ etree_value_type new;
+ new.valid_p = true;
+ new.section = abs_output_section;
+ new.value = value;
+ return new;
+}
+
+static void
+check (os, name, op)
+ lang_output_section_statement_type *os;
+ const char *name;
+ const char *op;
+{
+ if (os == NULL)
+ einfo (_("%F%P: %s uses undefined section %s\n"), op, name);
+ if (! os->processed)
+ einfo (_("%F%P: %s forward reference of section %s\n"), op, name);
+}
+
+etree_type *
+exp_intop (value)
+ bfd_vma value;
+{
+ etree_type *new = (etree_type *) stat_alloc(sizeof(new->value));
+ new->type.node_code = INT;
+ new->value.value = value;
+ new->type.node_class = etree_value;
+ return new;
+
+}
+
+/* Build an expression representing an unnamed relocateable value. */
+
+etree_type *
+exp_relop (section, value)
+ asection *section;
+ bfd_vma value;
+{
+ etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
+ new->type.node_code = REL;
+ new->type.node_class = etree_rel;
+ new->rel.section = section;
+ new->rel.value = value;
+ return new;
+}
+
+static etree_value_type
+new_rel (value, section)
+ bfd_vma value;
+ lang_output_section_statement_type *section;
+{
+ etree_value_type new;
+ new.valid_p = true;
+ new.value = value;
+ new.section = section;
+ return new;
+}
+
+static etree_value_type
+new_rel_from_section (value, section)
+ bfd_vma value;
+ lang_output_section_statement_type *section;
+{
+ etree_value_type new;
+ new.valid_p = true;
+ new.value = value;
+ new.section = section;
+
+ new.value -= section->bfd_section->vma;
+
+ return new;
+}
+
+static etree_value_type
+fold_binary (tree, current_section, allocation_done, dot, dotp)
+ etree_type *tree;
+ lang_output_section_statement_type *current_section;
+ lang_phase_type allocation_done;
+ bfd_vma dot;
+ bfd_vma *dotp;
+{
+ etree_value_type result;
+
+ result = exp_fold_tree (tree->binary.lhs, current_section,
+ allocation_done, dot, dotp);
+ if (result.valid_p)
+ {
+ etree_value_type other;
+
+ other = exp_fold_tree (tree->binary.rhs,
+ current_section,
+ allocation_done, dot,dotp) ;
+ if (other.valid_p)
+ {
+ /* If the values are from different sections, or this is an
+ absolute expression, make both the source arguments
+ absolute. However, adding or subtracting an absolute
+ value from a relative value is meaningful, and is an
+ exception. */
+ if (current_section != abs_output_section
+ && (other.section == abs_output_section
+ || (result.section == abs_output_section
+ && tree->type.node_code == '+'))
+ && (tree->type.node_code == '+'
+ || tree->type.node_code == '-'))
+ {
+ etree_value_type hold;
+
+ /* If there is only one absolute term, make sure it is the
+ second one. */
+ if (other.section != abs_output_section)
+ {
+ hold = result;
+ result = other;
+ other = hold;
+ }
+ }
+ else if (result.section != other.section
+ || current_section == abs_output_section)
+ {
+ make_abs(&result);
+ make_abs(&other);
+ }
+
+ switch (tree->type.node_code)
+ {
+ case '%':
+ if (other.value == 0)
+ einfo (_("%F%S %% by zero\n"));
+ result.value = ((bfd_signed_vma) result.value
+ % (bfd_signed_vma) other.value);
+ break;
+
+ case '/':
+ if (other.value == 0)
+ einfo (_("%F%S / by zero\n"));
+ result.value = ((bfd_signed_vma) result.value
+ / (bfd_signed_vma) other.value);
+ break;
+
+#define BOP(x,y) case x : result.value = result.value y other.value; break;
+ BOP('+',+);
+ BOP('*',*);
+ BOP('-',-);
+ BOP(LSHIFT,<<);
+ BOP(RSHIFT,>>);
+ BOP(EQ,==);
+ BOP(NE,!=);
+ BOP('<',<);
+ BOP('>',>);
+ BOP(LE,<=);
+ BOP(GE,>=);
+ BOP('&',&);
+ BOP('^',^);
+ BOP('|',|);
+ BOP(ANDAND,&&);
+ BOP(OROR,||);
+
+ case MAX_K:
+ if (result.value < other.value)
+ result = other;
+ break;
+
+ case MIN_K:
+ if (result.value > other.value)
+ result = other;
+ break;
+
+ default:
+ FAIL();
+ }
+ }
+ else
+ {
+ result.valid_p = false;
+ }
+ }
+
+ return result;
+}
+
+etree_value_type
+invalid ()
+{
+ etree_value_type new;
+ new.valid_p = false;
+ return new;
+}
+
+static etree_value_type
+fold_name (tree, current_section, allocation_done, dot)
+ etree_type *tree;
+ lang_output_section_statement_type *current_section;
+ lang_phase_type allocation_done;
+ bfd_vma dot;
+{
+ etree_value_type result;
+ switch (tree->type.node_code)
+ {
+ case SIZEOF_HEADERS:
+ if (allocation_done != lang_first_phase_enum)
+ {
+ result = new_abs ((bfd_vma)
+ bfd_sizeof_headers (output_bfd,
+ link_info.relocateable));
+ }
+ else
+ {
+ result.valid_p = false;
+ }
+ break;
+ case DEFINED:
+ if (allocation_done == lang_first_phase_enum)
+ result.valid_p = false;
+ else
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
+ tree->name.name,
+ false, false, true);
+ result.value = (h != (struct bfd_link_hash_entry *) NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak
+ || h->type == bfd_link_hash_common));
+ result.section = 0;
+ result.valid_p = true;
+ }
+ break;
+ case NAME:
+ result.valid_p = false;
+ if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
+ {
+ if (allocation_done != lang_first_phase_enum)
+ result = new_rel_from_section(dot, current_section);
+ else
+ result = invalid();
+ }
+ else if (allocation_done != lang_first_phase_enum)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
+ tree->name.name,
+ false, false, true);
+ if (h != NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ {
+ if (bfd_is_abs_section (h->u.def.section))
+ result = new_abs (h->u.def.value);
+ else if (allocation_done == lang_final_phase_enum
+ || allocation_done == lang_allocating_phase_enum)
+ {
+ asection *output_section;
+
+ output_section = h->u.def.section->output_section;
+ if (output_section == NULL)
+ einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
+ tree->name.name);
+ else
+ {
+ lang_output_section_statement_type *os;
+
+ os = (lang_output_section_statement_lookup
+ (bfd_get_section_name (output_bfd,
+ output_section)));
+
+ /* FIXME: Is this correct if this section is
+ being linked with -R? */
+ result = new_rel ((h->u.def.value
+ + h->u.def.section->output_offset),
+ os);
+ }
+ }
+ }
+ else if (allocation_done == lang_final_phase_enum)
+ einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
+ tree->name.name);
+ }
+ break;
+
+ case ADDR:
+ if (allocation_done != lang_first_phase_enum)
+ {
+ lang_output_section_statement_type *os;
+
+ os = lang_output_section_find (tree->name.name);
+ check (os, tree->name.name, "ADDR");
+ result = new_rel (0, os);
+ }
+ else
+ result = invalid ();
+ break;
+
+ case LOADADDR:
+ if (allocation_done != lang_first_phase_enum)
+ {
+ lang_output_section_statement_type *os;
+
+ os = lang_output_section_find (tree->name.name);
+ check (os, tree->name.name, "LOADADDR");
+ if (os->load_base == NULL)
+ result = new_rel (0, os);
+ else
+ result = exp_fold_tree_no_dot (os->load_base,
+ abs_output_section,
+ allocation_done);
+ }
+ else
+ result = invalid ();
+ break;
+
+ case SIZEOF:
+ if (allocation_done != lang_first_phase_enum)
+ {
+ lang_output_section_statement_type *os;
+
+ os = lang_output_section_find (tree->name.name);
+ check (os, tree->name.name, "SIZEOF");
+ result = new_abs (os->bfd_section->_raw_size);
+ }
+ else
+ result = invalid ();
+ break;
+
+ default:
+ FAIL();
+ break;
+ }
+
+ return result;
+}
+etree_value_type
+exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
+ etree_type *tree;
+ lang_output_section_statement_type *current_section;
+ lang_phase_type allocation_done;
+ bfd_vma dot;
+ bfd_vma *dotp;
+{
+ etree_value_type result;
+
+ if (tree == NULL)
+ {
+ result.valid_p = false;
+ return result;
+ }
+
+ switch (tree->type.node_class)
+ {
+ case etree_value:
+ result = new_rel (tree->value.value, current_section);
+ break;
+
+ case etree_rel:
+ if (allocation_done != lang_final_phase_enum)
+ result.valid_p = false;
+ else
+ result = new_rel ((tree->rel.value
+ + tree->rel.section->output_section->vma
+ + tree->rel.section->output_offset),
+ current_section);
+ break;
+
+ case etree_assert:
+ result = exp_fold_tree (tree->assert_s.child,
+ current_section,
+ allocation_done, dot, dotp);
+ if (result.valid_p)
+ {
+ if (! result.value)
+ einfo ("%F%P: %s\n", tree->assert_s.message);
+ return result;
+ }
+ break;
+
+ case etree_unary:
+ result = exp_fold_tree (tree->unary.child,
+ current_section,
+ allocation_done, dot, dotp);
+ if (result.valid_p)
+ {
+ switch (tree->type.node_code)
+ {
+ case ALIGN_K:
+ if (allocation_done != lang_first_phase_enum)
+ result = new_rel_from_section (ALIGN_N (dot, result.value),
+ current_section);
+ else
+ result.valid_p = false;
+ break;
+
+ case ABSOLUTE:
+ if (allocation_done != lang_first_phase_enum && result.valid_p)
+ {
+ result.value += result.section->bfd_section->vma;
+ result.section = abs_output_section;
+ }
+ else
+ result.valid_p = false;
+ break;
+
+ case '~':
+ make_abs (&result);
+ result.value = ~result.value;
+ break;
+
+ case '!':
+ make_abs (&result);
+ result.value = !result.value;
+ break;
+
+ case '-':
+ make_abs (&result);
+ result.value = -result.value;
+ break;
+
+ case NEXT:
+ /* Return next place aligned to value. */
+ if (allocation_done == lang_allocating_phase_enum)
+ {
+ make_abs (&result);
+ result.value = ALIGN_N (dot, result.value);
+ }
+ else
+ result.valid_p = false;
+ break;
+
+ default:
+ FAIL ();
+ break;
+ }
+ }
+ break;
+
+ case etree_trinary:
+ result = exp_fold_tree (tree->trinary.cond, current_section,
+ allocation_done, dot, dotp);
+ if (result.valid_p)
+ result = exp_fold_tree ((result.value
+ ? tree->trinary.lhs
+ : tree->trinary.rhs),
+ current_section,
+ allocation_done, dot, dotp);
+ break;
+
+ case etree_binary:
+ result = fold_binary (tree, current_section, allocation_done,
+ dot, dotp);
+ break;
+
+ case etree_assign:
+ case etree_provide:
+ if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
+ {
+ /* Assignment to dot can only be done during allocation */
+ if (tree->type.node_class == etree_provide)
+ einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
+ if (allocation_done == lang_allocating_phase_enum
+ || (allocation_done == lang_final_phase_enum
+ && current_section == abs_output_section))
+ {
+ result = exp_fold_tree (tree->assign.src,
+ current_section,
+ lang_allocating_phase_enum, dot,
+ dotp);
+ if (! result.valid_p)
+ einfo (_("%F%S invalid assignment to location counter\n"));
+ else
+ {
+ if (current_section == NULL)
+ einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
+ else
+ {
+ bfd_vma nextdot;
+
+ nextdot = (result.value
+ + current_section->bfd_section->vma);
+ if (nextdot < dot
+ && current_section != abs_output_section)
+ {
+ einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
+ dot, nextdot);
+ }
+ else
+ *dotp = nextdot;
+ }
+ }
+ }
+ }
+ else
+ {
+ result = exp_fold_tree (tree->assign.src,
+ current_section, allocation_done,
+ dot, dotp);
+ if (result.valid_p)
+ {
+ boolean create;
+ struct bfd_link_hash_entry *h;
+
+ if (tree->type.node_class == etree_assign)
+ create = true;
+ else
+ create = false;
+ h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
+ create, false, false);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ {
+ if (tree->type.node_class == etree_assign)
+ einfo (_("%P%F:%s: hash creation failed\n"),
+ tree->assign.dst);
+ }
+ else if (tree->type.node_class == etree_provide
+ && h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common)
+ {
+ /* Do nothing. The symbol was defined by some
+ object. */
+ }
+ else
+ {
+ /* FIXME: Should we worry if the symbol is already
+ defined? */
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = result.value;
+ h->u.def.section = result.section->bfd_section;
+ }
+ }
+ }
+ break;
+
+ case etree_name:
+ result = fold_name (tree, current_section, allocation_done, dot);
+ break;
+
+ default:
+ FAIL ();
+ break;
+ }
+
+ return result;
+}
+
+static etree_value_type
+exp_fold_tree_no_dot (tree, current_section, allocation_done)
+ etree_type *tree;
+ lang_output_section_statement_type *current_section;
+ lang_phase_type allocation_done;
+{
+return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
+ 0, (bfd_vma *)NULL);
+}
+
+etree_type *
+exp_binop (code, lhs, rhs)
+ int code;
+ etree_type *lhs;
+ etree_type *rhs;
+{
+ etree_type value, *new;
+ etree_value_type r;
+
+ value.type.node_code = code;
+ value.binary.lhs = lhs;
+ value.binary.rhs = rhs;
+ value.type.node_class = etree_binary;
+ r = exp_fold_tree_no_dot(&value,
+ abs_output_section,
+ lang_first_phase_enum );
+ if (r.valid_p)
+ {
+ return exp_intop(r.value);
+ }
+ new = (etree_type *) stat_alloc (sizeof (new->binary));
+ memcpy((char *)new, (char *)&value, sizeof(new->binary));
+ return new;
+}
+
+etree_type *
+exp_trinop (code, cond, lhs, rhs)
+ int code;
+ etree_type *cond;
+ etree_type *lhs;
+ etree_type *rhs;
+{
+ etree_type value, *new;
+ etree_value_type r;
+ value.type.node_code = code;
+ value.trinary.lhs = lhs;
+ value.trinary.cond = cond;
+ value.trinary.rhs = rhs;
+ value.type.node_class = etree_trinary;
+ r= exp_fold_tree_no_dot(&value, (lang_output_section_statement_type
+ *)NULL,lang_first_phase_enum);
+ if (r.valid_p) {
+ return exp_intop(r.value);
+ }
+ new = (etree_type *) stat_alloc (sizeof (new->trinary));
+ memcpy((char *)new,(char *) &value, sizeof(new->trinary));
+ return new;
+}
+
+
+etree_type *
+exp_unop (code, child)
+ int code;
+ etree_type *child;
+{
+ etree_type value, *new;
+
+ etree_value_type r;
+ value.unary.type.node_code = code;
+ value.unary.child = child;
+ value.unary.type.node_class = etree_unary;
+ r = exp_fold_tree_no_dot(&value,abs_output_section,
+ lang_first_phase_enum);
+ if (r.valid_p) {
+ return exp_intop(r.value);
+ }
+ new = (etree_type *) stat_alloc (sizeof (new->unary));
+ memcpy((char *)new, (char *)&value, sizeof(new->unary));
+ return new;
+}
+
+
+etree_type *
+exp_nameop (code, name)
+ int code;
+ CONST char *name;
+{
+ etree_type value, *new;
+ etree_value_type r;
+ value.name.type.node_code = code;
+ value.name.name = name;
+ value.name.type.node_class = etree_name;
+
+
+ r = exp_fold_tree_no_dot(&value,
+ (lang_output_section_statement_type *)NULL,
+ lang_first_phase_enum);
+ if (r.valid_p) {
+ return exp_intop(r.value);
+ }
+ new = (etree_type *) stat_alloc (sizeof (new->name));
+ memcpy((char *)new, (char *)&value, sizeof(new->name));
+ return new;
+
+}
+
+
+
+
+etree_type *
+exp_assop (code, dst, src)
+ int code;
+ CONST char *dst;
+ etree_type *src;
+{
+ etree_type value, *new;
+
+ value.assign.type.node_code = code;
+
+
+ value.assign.src = src;
+ value.assign.dst = dst;
+ value.assign.type.node_class = etree_assign;
+
+#if 0
+ if (exp_fold_tree_no_dot(&value, &result)) {
+ return exp_intop(result);
+ }
+#endif
+ new = (etree_type*) stat_alloc (sizeof (new->assign));
+ memcpy((char *)new, (char *)&value, sizeof(new->assign));
+ return new;
+}
+
+/* Handle PROVIDE. */
+
+etree_type *
+exp_provide (dst, src)
+ const char *dst;
+ etree_type *src;
+{
+ etree_type *n;
+
+ n = (etree_type *) stat_alloc (sizeof (n->assign));
+ n->assign.type.node_code = '=';
+ n->assign.type.node_class = etree_provide;
+ n->assign.src = src;
+ n->assign.dst = dst;
+ return n;
+}
+
+/* Handle ASSERT. */
+
+etree_type *
+exp_assert (exp, message)
+ etree_type *exp;
+ const char *message;
+{
+ etree_type *n;
+
+ n = (etree_type *) stat_alloc (sizeof (n->assert_s));
+ n->assert_s.type.node_code = '!';
+ n->assert_s.type.node_class = etree_assert;
+ n->assert_s.child = exp;
+ n->assert_s.message = message;
+ return n;
+}
+
+void
+exp_print_tree (tree)
+ etree_type *tree;
+{
+ switch (tree->type.node_class) {
+ case etree_value:
+ minfo ("0x%v", tree->value.value);
+ return;
+ case etree_rel:
+ if (tree->rel.section->owner != NULL)
+ minfo ("%B:", tree->rel.section->owner);
+ minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
+ return;
+ case etree_assign:
+#if 0
+ if (tree->assign.dst->sdefs != (asymbol *)NULL){
+ fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
+ tree->assign.dst->sdefs->value);
+ }
+ else {
+ fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
+ }
+#endif
+ fprintf(config.map_file,"%s",tree->assign.dst);
+ exp_print_token(tree->type.node_code);
+ exp_print_tree(tree->assign.src);
+ break;
+ case etree_provide:
+ fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
+ exp_print_tree (tree->assign.src);
+ fprintf (config.map_file, ")");
+ break;
+ case etree_binary:
+ fprintf(config.map_file,"(");
+ exp_print_tree(tree->binary.lhs);
+ exp_print_token(tree->type.node_code);
+ exp_print_tree(tree->binary.rhs);
+ fprintf(config.map_file,")");
+ break;
+ case etree_trinary:
+ exp_print_tree(tree->trinary.cond);
+ fprintf(config.map_file,"?");
+ exp_print_tree(tree->trinary.lhs);
+ fprintf(config.map_file,":");
+ exp_print_tree(tree->trinary.rhs);
+ break;
+ case etree_unary:
+ exp_print_token(tree->unary.type.node_code);
+ if (tree->unary.child)
+ {
+ fprintf(config.map_file,"(");
+ exp_print_tree(tree->unary.child);
+ fprintf(config.map_file,")");
+ }
+
+ break;
+
+ case etree_assert:
+ fprintf (config.map_file, "ASSERT (");
+ exp_print_tree (tree->assert_s.child);
+ fprintf (config.map_file, ", %s)", tree->assert_s.message);
+ break;
+
+ case etree_undef:
+ fprintf(config.map_file,"????????");
+ break;
+ case etree_name:
+ if (tree->type.node_code == NAME) {
+ fprintf(config.map_file,"%s", tree->name.name);
+ }
+ else {
+ exp_print_token(tree->type.node_code);
+ if (tree->name.name)
+ fprintf(config.map_file,"(%s)", tree->name.name);
+ }
+ break;
+ default:
+ FAIL();
+ break;
+ }
+}
+
+bfd_vma
+exp_get_vma (tree, def, name, allocation_done)
+ etree_type *tree;
+ bfd_vma def;
+ char *name;
+ lang_phase_type allocation_done;
+{
+ etree_value_type r;
+
+ if (tree != NULL)
+ {
+ r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
+ if (! r.valid_p && name != NULL)
+ einfo (_("%F%S nonconstant expression for %s\n"), name);
+ return r.value;
+ }
+ else
+ return def;
+}
+
+int
+exp_get_value_int (tree,def,name, allocation_done)
+ etree_type *tree;
+ int def;
+ char *name;
+ lang_phase_type allocation_done;
+{
+ return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
+}
+
+
+bfd_vma
+exp_get_abs_int (tree, def, name, allocation_done)
+ etree_type *tree;
+ int def;
+ char *name;
+ lang_phase_type allocation_done;
+{
+ etree_value_type res;
+ res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
+
+ if (res.valid_p)
+ {
+ res.value += res.section->bfd_section->vma;
+ }
+ else {
+ einfo (_("%F%S non constant expression for %s\n"),name);
+ }
+ return res.value;
+}
diff --git a/ld/ldexp.h b/ld/ldexp.h
new file mode 100644
index 00000000000..b8e8ddf6f82
--- /dev/null
+++ b/ld/ldexp.h
@@ -0,0 +1,116 @@
+/* ldexp.h -
+ Copyright 1991, 92, 93, 94, 95, 1998 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef LDEXP_H
+#define LDEXP_H
+
+/* The result of an expression tree */
+typedef struct
+{
+ bfd_vma value;
+ struct lang_output_section_statement_struct *section;
+ boolean valid_p;
+} etree_value_type;
+
+
+
+typedef struct
+{
+ int node_code;
+ enum { etree_binary,
+ etree_trinary,
+ etree_unary,
+ etree_name,
+ etree_assign,
+ etree_provide,
+ etree_undef,
+ etree_unspec,
+ etree_value,
+ etree_assert,
+ etree_rel } node_class;
+} node_type;
+
+
+
+typedef union etree_union
+{
+ node_type type;
+ struct {
+ node_type type;
+ union etree_union *lhs;
+ union etree_union *rhs;
+ } binary;
+ struct {
+ node_type type;
+ union etree_union *cond;
+ union etree_union *lhs;
+ union etree_union *rhs;
+ } trinary;
+ struct {
+ node_type type;
+ CONST char *dst;
+ union etree_union *src;
+ } assign;
+
+ struct {
+ node_type type;
+ union etree_union *child;
+ } unary;
+ struct {
+ node_type type;
+ CONST char *name;
+ } name;
+ struct {
+ node_type type;
+ bfd_vma value;
+ } value;
+ struct {
+ node_type type;
+ asection *section;
+ bfd_vma value;
+ } rel;
+ struct {
+ node_type type;
+ union etree_union *child;
+ const char *message;
+ } assert_s;
+} etree_type;
+
+
+etree_type *exp_intop PARAMS ((bfd_vma));
+etree_type *exp_relop PARAMS ((asection *, bfd_vma));
+etree_value_type invalid PARAMS ((void));
+etree_value_type exp_fold_tree PARAMS ((etree_type *, struct
+ lang_output_section_statement_struct *,
+ lang_phase_type,
+ bfd_vma, bfd_vma *));
+etree_type *exp_binop PARAMS ((int, etree_type *, etree_type *));
+etree_type *exp_trinop PARAMS ((int,etree_type *, etree_type *, etree_type *));
+etree_type *exp_unop PARAMS ((int, etree_type *));
+etree_type *exp_nameop PARAMS ((int, CONST char *));
+etree_type *exp_assop PARAMS ((int, CONST char *, etree_type *));
+etree_type *exp_provide PARAMS ((const char *, etree_type *));
+etree_type *exp_assert PARAMS ((etree_type *, const char *));
+void exp_print_tree PARAMS ((etree_type *));
+bfd_vma exp_get_vma PARAMS ((etree_type *, bfd_vma, char *, lang_phase_type));
+int exp_get_value_int PARAMS ((etree_type *, int, char *,lang_phase_type));
+bfd_vma exp_get_abs_int PARAMS ((etree_type *, int, char *,lang_phase_type));
+
+#endif
diff --git a/ld/ldfile.c b/ld/ldfile.c
new file mode 100644
index 00000000000..1dfa31f2192
--- /dev/null
+++ b/ld/ldfile.c
@@ -0,0 +1,416 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 98, 1999 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/*
+ ldfile.c
+
+ look after all the file stuff
+
+ */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "ld.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldfile.h"
+#include "ldmain.h"
+#include "ldgram.h"
+#include "ldlex.h"
+#include "ldemul.h"
+
+#include <ctype.h>
+
+const char *ldfile_input_filename;
+boolean ldfile_assumed_script = false;
+const char *ldfile_output_machine_name = "";
+unsigned long ldfile_output_machine;
+enum bfd_architecture ldfile_output_architecture;
+search_dirs_type *search_head;
+
+#ifndef MPW
+#ifdef VMS
+char *slash = "";
+#else
+#if defined (_WIN32) && ! defined (__CYGWIN32__)
+char *slash = "\\";
+#else
+char *slash = "/";
+#endif
+#endif
+#else /* MPW */
+/* The MPW path char is a colon. */
+char *slash = ":";
+#endif /* MPW */
+
+/* LOCAL */
+
+static search_dirs_type **search_tail_ptr = &search_head;
+
+typedef struct search_arch
+{
+ char *name;
+ struct search_arch *next;
+} search_arch_type;
+
+static search_arch_type *search_arch_head;
+static search_arch_type **search_arch_tail_ptr = &search_arch_head;
+
+static boolean ldfile_open_file_search
+ PARAMS ((const char *arch, lang_input_statement_type *,
+ const char *lib, const char *suffix));
+static FILE *try_open PARAMS ((const char *name, const char *exten));
+
+void
+ldfile_add_library_path (name, cmdline)
+ const char *name;
+ boolean cmdline;
+{
+ search_dirs_type *new;
+
+ new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type));
+ new->next = NULL;
+ new->name = name;
+ new->cmdline = cmdline;
+ *search_tail_ptr = new;
+ search_tail_ptr = &new->next;
+}
+
+/* Try to open a BFD for a lang_input_statement. */
+
+boolean
+ldfile_try_open_bfd (attempt, entry)
+ const char *attempt;
+ lang_input_statement_type *entry;
+{
+ entry->the_bfd = bfd_openr (attempt, entry->target);
+
+ if (trace_file_tries)
+ {
+ if (entry->the_bfd == NULL)
+ info_msg (_("attempt to open %s failed\n"), attempt);
+ else
+ info_msg (_("attempt to open %s succeeded\n"), attempt);
+ }
+
+ if (entry->the_bfd != NULL)
+ return true;
+ else
+ {
+ if (bfd_get_error () == bfd_error_invalid_target)
+ einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
+ return false;
+ }
+}
+
+/* Search for and open the file specified by ENTRY. If it is an
+ archive, use ARCH, LIB and SUFFIX to modify the file name. */
+
+static boolean
+ldfile_open_file_search (arch, entry, lib, suffix)
+ const char *arch;
+ lang_input_statement_type *entry;
+ const char *lib;
+ const char *suffix;
+{
+ search_dirs_type *search;
+
+ /* If this is not an archive, try to open it in the current
+ directory first. */
+ if (! entry->is_archive)
+ {
+ if (ldfile_try_open_bfd (entry->filename, entry))
+ return true;
+ }
+
+ for (search = search_head;
+ search != (search_dirs_type *)NULL;
+ search = search->next)
+ {
+ char *string;
+
+ if (entry->dynamic && ! link_info.relocateable)
+ {
+ if (ldemul_open_dynamic_archive (arch, search, entry))
+ return true;
+ }
+
+ string = (char *) xmalloc (strlen (search->name)
+ + strlen (slash)
+ + strlen (lib)
+ + strlen (entry->filename)
+ + strlen (arch)
+ + strlen (suffix)
+ + 1);
+
+ if (entry->is_archive)
+ sprintf (string, "%s%s%s%s%s%s", search->name, slash,
+ lib, entry->filename, arch, suffix);
+ else if (entry->filename[0] == '/' || entry->filename[0] == '.'
+#if defined (__MSDOS__) || defined (_WIN32)
+ || entry->filename[0] == '\\'
+ || (isalpha (entry->filename[0])
+ && entry->filename[1] == ':')
+#endif
+ )
+ strcpy (string, entry->filename);
+ else
+ sprintf (string, "%s%s%s", search->name, slash, entry->filename);
+
+ if (ldfile_try_open_bfd (string, entry))
+ {
+ entry->filename = string;
+ return true;
+ }
+
+ free (string);
+ }
+
+ return false;
+}
+
+/* Open the input file specified by ENTRY. */
+
+void
+ldfile_open_file (entry)
+ lang_input_statement_type *entry;
+{
+ if (entry->the_bfd != NULL)
+ return;
+
+ if (! entry->search_dirs_flag)
+ {
+ if (ldfile_try_open_bfd (entry->filename, entry))
+ return;
+ if (strcmp (entry->filename, entry->local_sym_name) != 0)
+ einfo (_("%F%P: cannot open %s for %s: %E\n"),
+ entry->filename, entry->local_sym_name);
+ else
+ einfo(_("%F%P: cannot open %s: %E\n"), entry->local_sym_name);
+ }
+ else
+ {
+ search_arch_type *arch;
+
+ /* Try to open <filename><suffix> or lib<filename><suffix>.a */
+ for (arch = search_arch_head;
+ arch != (search_arch_type *) NULL;
+ arch = arch->next)
+ {
+ if (ldfile_open_file_search (arch->name, entry, "lib", ".a"))
+ return;
+#ifdef VMS
+ if (ldfile_open_file_search (arch->name, entry, ":lib", ".a"))
+ return;
+#endif
+ }
+ einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
+ }
+}
+
+/* Try to open NAME; if that fails, try NAME with EXTEN appended to it. */
+
+static FILE *
+try_open (name, exten)
+ const char *name;
+ const char *exten;
+{
+ FILE *result;
+ char buff[1000];
+
+ result = fopen (name, "r");
+ if (trace_file_tries)
+ {
+ if (result == NULL)
+ info_msg (_("cannot find script file %s\n"), name);
+ else
+ info_msg (_("opened script file %s\n"), name);
+ }
+
+ if (result != NULL)
+ return result;
+
+ if (*exten)
+ {
+ sprintf (buff, "%s%s", name, exten);
+ result = fopen (buff, "r");
+ if (trace_file_tries)
+ {
+ if (result == NULL)
+ info_msg (_("cannot find script file %s\n"), buff);
+ else
+ info_msg (_("opened script file %s\n"), buff);
+ }
+ }
+
+ return result;
+}
+
+/* Try to open NAME; if that fails, look for it in any directories
+ specified with -L, without and with EXTEND apppended. */
+
+FILE *
+ldfile_find_command_file (name, extend)
+ const char *name;
+ const char *extend;
+{
+ search_dirs_type *search;
+ FILE *result;
+ char buffer[1000];
+
+ /* First try raw name */
+ result = try_open(name,"");
+ if (result == (FILE *)NULL) {
+ /* Try now prefixes */
+ for (search = search_head;
+ search != (search_dirs_type *)NULL;
+ search = search->next) {
+ sprintf(buffer,"%s%s%s", search->name, slash, name);
+ result = try_open(buffer, extend);
+ if (result)break;
+ }
+ }
+ return result;
+}
+
+void
+ldfile_open_command_file (name)
+ const char *name;
+{
+ FILE *ldlex_input_stack;
+ ldlex_input_stack = ldfile_find_command_file(name, "");
+
+ if (ldlex_input_stack == (FILE *)NULL) {
+ bfd_set_error (bfd_error_system_call);
+ einfo(_("%P%F: cannot open linker script file %s: %E\n"),name);
+ }
+ lex_push_file(ldlex_input_stack, name);
+
+ ldfile_input_filename = name;
+ lineno = 1;
+ had_script = true;
+}
+
+
+
+
+
+#ifdef GNU960
+static
+char *
+gnu960_map_archname( name )
+char *name;
+{
+ struct tabentry { char *cmd_switch; char *arch; };
+ static struct tabentry arch_tab[] = {
+ "", "",
+ "KA", "ka",
+ "KB", "kb",
+ "KC", "mc", /* Synonym for MC */
+ "MC", "mc",
+ "CA", "ca",
+ "SA", "ka", /* Functionally equivalent to KA */
+ "SB", "kb", /* Functionally equivalent to KB */
+ NULL, ""
+ };
+ struct tabentry *tp;
+
+
+ for ( tp = arch_tab; tp->cmd_switch != NULL; tp++ ){
+ if ( !strcmp(name,tp->cmd_switch) ){
+ break;
+ }
+ }
+
+ if ( tp->cmd_switch == NULL ){
+ einfo(_("%P%F: unknown architecture: %s\n"),name);
+ }
+ return tp->arch;
+}
+
+
+
+void
+ldfile_add_arch(name)
+char *name;
+{
+ search_arch_type *new =
+ (search_arch_type *)xmalloc((bfd_size_type)(sizeof(search_arch_type)));
+
+
+ if (*name != '\0') {
+ if (ldfile_output_machine_name[0] != '\0') {
+ einfo(_("%P%F: target architecture respecified\n"));
+ return;
+ }
+ ldfile_output_machine_name = name;
+ }
+
+ new->next = (search_arch_type*)NULL;
+ new->name = gnu960_map_archname( name );
+ *search_arch_tail_ptr = new;
+ search_arch_tail_ptr = &new->next;
+
+}
+
+#else /* not GNU960 */
+
+
+void
+ldfile_add_arch (in_name)
+ CONST char * in_name;
+{
+ char *name = buystring(in_name);
+ search_arch_type *new =
+ (search_arch_type *) xmalloc (sizeof (search_arch_type));
+
+ ldfile_output_machine_name = in_name;
+
+ new->name = name;
+ new->next = (search_arch_type*)NULL;
+ while (*name)
+ {
+ if (isupper ((unsigned char) *name))
+ *name = tolower ((unsigned char) *name);
+ name++;
+ }
+ *search_arch_tail_ptr = new;
+ search_arch_tail_ptr = &new->next;
+
+}
+#endif
+
+/* Set the output architecture */
+void
+ldfile_set_output_arch (string)
+ CONST char *string;
+{
+ const bfd_arch_info_type *arch = bfd_scan_arch(string);
+
+ if (arch) {
+ ldfile_output_architecture = arch->arch;
+ ldfile_output_machine = arch->mach;
+ ldfile_output_machine_name = arch->printable_name;
+ }
+ else {
+ einfo(_("%P%F: cannot represent machine `%s'\n"), string);
+ }
+}
diff --git a/ld/ldfile.h b/ld/ldfile.h
new file mode 100644
index 00000000000..f33c9ce9462
--- /dev/null
+++ b/ld/ldfile.h
@@ -0,0 +1,53 @@
+/* ldfile.h -
+ Copyright 1991, 1992 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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 1, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern const char *ldfile_input_filename;
+extern boolean ldfile_assumed_script;
+extern unsigned long ldfile_output_machine;
+extern enum bfd_architecture ldfile_output_architecture;
+extern const char *ldfile_output_machine_name;
+
+/* Structure used to hold the list of directories to search for
+ libraries. */
+
+typedef struct search_dirs
+{
+ /* Next directory on list. */
+ struct search_dirs *next;
+ /* Name of directory. */
+ const char *name;
+ /* true if this is from the command line. */
+ boolean cmdline;
+} search_dirs_type;
+
+extern search_dirs_type *search_head;
+
+#if ANSI_PROTOTYPES
+struct lang_input_statement_struct;
+#endif
+
+extern void ldfile_add_arch PARAMS ((CONST char *));
+extern void ldfile_add_library_path PARAMS ((const char *, boolean cmdline));
+extern void ldfile_open_command_file PARAMS ((const char *name));
+extern void ldfile_open_file PARAMS ((struct lang_input_statement_struct *));
+extern boolean ldfile_try_open_bfd
+ PARAMS ((const char *, struct lang_input_statement_struct *));
+extern FILE *ldfile_find_command_file
+ PARAMS ((const char *name, const char *extend));
+extern void ldfile_set_output_arch PARAMS ((CONST char *));
diff --git a/ld/ldgram.y b/ld/ldgram.y
new file mode 100644
index 00000000000..a1f3ed60c22
--- /dev/null
+++ b/ld/ldgram.y
@@ -0,0 +1,1094 @@
+/* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
+
+This file is part of GNU ld.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+%{
+/*
+
+ */
+
+#define DONTDECLARE_MALLOC
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "ld.h"
+#include "ldexp.h"
+#include "ldver.h"
+#include "ldlang.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldmain.h"
+#include "mri.h"
+#include "ldctor.h"
+#include "ldlex.h"
+
+#ifndef YYDEBUG
+#define YYDEBUG 1
+#endif
+
+static enum section_type sectype;
+
+lang_memory_region_type *region;
+
+struct wildcard_spec current_file;
+boolean ldgram_want_filename = true;
+boolean had_script = false;
+boolean force_make_executable = false;
+
+boolean ldgram_in_script = false;
+boolean ldgram_had_equals = false;
+boolean ldgram_had_keep = false;
+char *ldgram_vers_current_lang = NULL;
+
+#define ERROR_NAME_MAX 20
+static char *error_names[ERROR_NAME_MAX];
+static int error_index;
+#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
+#define POP_ERROR() error_index--;
+%}
+%union {
+ bfd_vma integer;
+ char *name;
+ const char *cname;
+ struct wildcard_spec wildcard;
+ int token;
+ union etree_union *etree;
+ struct phdr_info
+ {
+ boolean filehdr;
+ boolean phdrs;
+ union etree_union *at;
+ union etree_union *flags;
+ } phdr;
+ struct lang_nocrossref *nocrossref;
+ struct lang_output_section_phdr_list *section_phdr;
+ struct bfd_elf_version_deps *deflist;
+ struct bfd_elf_version_expr *versyms;
+ struct bfd_elf_version_tree *versnode;
+}
+
+%type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val
+%type <etree> opt_exp_without_type
+%type <integer> fill_opt
+%type <name> memspec_opt casesymlist
+%type <cname> wildcard_name
+%type <wildcard> wildcard_spec
+%token <integer> INT
+%token <name> NAME LNAME
+%type <integer> length
+%type <phdr> phdr_qualifiers
+%type <nocrossref> nocrossref_list
+%type <section_phdr> phdr_opt
+%type <integer> opt_nocrossrefs
+
+%right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ
+%right <token> '?' ':'
+%left <token> OROR
+%left <token> ANDAND
+%left <token> '|'
+%left <token> '^'
+%left <token> '&'
+%left <token> EQ NE
+%left <token> '<' '>' LE GE
+%left <token> LSHIFT RSHIFT
+
+%left <token> '+' '-'
+%left <token> '*' '/' '%'
+
+%right UNARY
+%token END
+%left <token> '('
+%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
+%token SECTIONS PHDRS SORT
+%token '{' '}'
+%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
+%token SIZEOF_HEADERS
+%token INCLUDE
+%token MEMORY DEFSYMEND
+%token NOLOAD DSECT COPY INFO OVERLAY
+%token NAME LNAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY
+%token <integer> NEXT
+%token SIZEOF ADDR LOADADDR MAX_K MIN_K
+%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS
+%token ORIGIN FILL
+%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS
+%token ALIGNMOD AT PROVIDE
+%type <token> assign_op atype
+%type <name> filename
+%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
+%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
+%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
+%token <name> VERS_TAG VERS_IDENTIFIER
+%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
+%token KEEP
+%token EXCLUDE_FILE
+%type <versyms> vers_defns
+%type <versnode> vers_tag
+%type <deflist> verdep
+
+%%
+
+file:
+ INPUT_SCRIPT script_file
+ | INPUT_MRI_SCRIPT mri_script_file
+ | INPUT_VERSION_SCRIPT version_script_file
+ | INPUT_DEFSYM defsym_expr
+ ;
+
+
+filename: NAME;
+
+
+defsym_expr:
+ { ldlex_defsym(); }
+ NAME '=' exp
+ {
+ ldlex_popstate();
+ lang_add_assignment(exp_assop($3,$2,$4));
+ }
+
+/* SYNTAX WITHIN AN MRI SCRIPT FILE */
+mri_script_file:
+ {
+ ldlex_mri_script ();
+ PUSH_ERROR (_("MRI style script"));
+ }
+ mri_script_lines
+ {
+ ldlex_popstate ();
+ mri_draw_tree ();
+ POP_ERROR ();
+ }
+ ;
+
+mri_script_lines:
+ mri_script_lines mri_script_command NEWLINE
+ |
+ ;
+
+mri_script_command:
+ CHIP exp
+ | CHIP exp ',' exp
+ | NAME {
+ einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1);
+ }
+ | LIST {
+ config.map_filename = "-";
+ }
+ | ORDER ordernamelist
+ | ENDWORD
+ | PUBLIC NAME '=' exp
+ { mri_public($2, $4); }
+ | PUBLIC NAME ',' exp
+ { mri_public($2, $4); }
+ | PUBLIC NAME exp
+ { mri_public($2, $3); }
+ | FORMAT NAME
+ { mri_format($2); }
+ | SECT NAME ',' exp
+ { mri_output_section($2, $4);}
+ | SECT NAME exp
+ { mri_output_section($2, $3);}
+ | SECT NAME '=' exp
+ { mri_output_section($2, $4);}
+ | ALIGN_K NAME '=' exp
+ { mri_align($2,$4); }
+ | ALIGN_K NAME ',' exp
+ { mri_align($2,$4); }
+ | ALIGNMOD NAME '=' exp
+ { mri_alignmod($2,$4); }
+ | ALIGNMOD NAME ',' exp
+ { mri_alignmod($2,$4); }
+ | ABSOLUTE mri_abs_name_list
+ | LOAD mri_load_name_list
+ | NAMEWORD NAME
+ { mri_name($2); }
+ | ALIAS NAME ',' NAME
+ { mri_alias($2,$4,0);}
+ | ALIAS NAME ',' INT
+ { mri_alias($2,0,(int) $4);}
+ | BASE exp
+ { mri_base($2); }
+ | TRUNCATE INT
+ { mri_truncate((unsigned int) $2); }
+ | CASE casesymlist
+ | EXTERN extern_name_list
+ | INCLUDE filename
+ { ldfile_open_command_file ($2); } mri_script_lines END
+ | START NAME
+ { lang_add_entry ($2, false); }
+ |
+ ;
+
+ordernamelist:
+ ordernamelist ',' NAME { mri_order($3); }
+ | ordernamelist NAME { mri_order($2); }
+ |
+ ;
+
+mri_load_name_list:
+ NAME
+ { mri_load($1); }
+ | mri_load_name_list ',' NAME { mri_load($3); }
+ ;
+
+mri_abs_name_list:
+ NAME
+ { mri_only_load($1); }
+ | mri_abs_name_list ',' NAME
+ { mri_only_load($3); }
+ ;
+
+casesymlist:
+ /* empty */ { $$ = NULL; }
+ | NAME
+ | casesymlist ',' NAME
+ ;
+
+extern_name_list:
+ NAME
+ { ldlang_add_undef ($1); }
+ | extern_name_list NAME
+ { ldlang_add_undef ($2); }
+ | extern_name_list ',' NAME
+ { ldlang_add_undef ($3); }
+ ;
+
+script_file:
+ {
+ ldlex_both();
+ }
+ ifile_list
+ {
+ ldlex_popstate();
+ }
+ ;
+
+
+ifile_list:
+ ifile_list ifile_p1
+ |
+ ;
+
+
+
+ifile_p1:
+ memory
+ | sections
+ | phdrs
+ | startup
+ | high_level_library
+ | low_level_library
+ | floating_point_support
+ | statement_anywhere
+ | version
+ | ';'
+ | TARGET_K '(' NAME ')'
+ { lang_add_target($3); }
+ | SEARCH_DIR '(' filename ')'
+ { ldfile_add_library_path ($3, false); }
+ | OUTPUT '(' filename ')'
+ { lang_add_output($3, 1); }
+ | OUTPUT_FORMAT '(' NAME ')'
+ { lang_add_output_format ($3, (char *) NULL,
+ (char *) NULL, 1); }
+ | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')'
+ { lang_add_output_format ($3, $5, $7, 1); }
+ | OUTPUT_ARCH '(' NAME ')'
+ { ldfile_set_output_arch($3); }
+ | FORCE_COMMON_ALLOCATION
+ { command_line.force_common_definition = true ; }
+ | INPUT '(' input_list ')'
+ | GROUP
+ { lang_enter_group (); }
+ '(' input_list ')'
+ { lang_leave_group (); }
+ | MAP '(' filename ')'
+ { lang_add_map($3); }
+ | INCLUDE filename
+ { ldfile_open_command_file($2); } ifile_list END
+ | NOCROSSREFS '(' nocrossref_list ')'
+ {
+ lang_add_nocrossref ($3);
+ }
+ | EXTERN '(' extern_name_list ')'
+ ;
+
+input_list:
+ NAME
+ { lang_add_input_file($1,lang_input_file_is_search_file_enum,
+ (char *)NULL); }
+ | input_list ',' NAME
+ { lang_add_input_file($3,lang_input_file_is_search_file_enum,
+ (char *)NULL); }
+ | input_list NAME
+ { lang_add_input_file($2,lang_input_file_is_search_file_enum,
+ (char *)NULL); }
+ | LNAME
+ { lang_add_input_file($1,lang_input_file_is_l_enum,
+ (char *)NULL); }
+ | input_list ',' LNAME
+ { lang_add_input_file($3,lang_input_file_is_l_enum,
+ (char *)NULL); }
+ | input_list LNAME
+ { lang_add_input_file($2,lang_input_file_is_l_enum,
+ (char *)NULL); }
+ ;
+
+sections:
+ SECTIONS '{' sec_or_group_p1 '}'
+ ;
+
+sec_or_group_p1:
+ sec_or_group_p1 section
+ | sec_or_group_p1 statement_anywhere
+ |
+ ;
+
+statement_anywhere:
+ ENTRY '(' NAME ')'
+ { lang_add_entry ($3, false); }
+ | assignment end
+ ;
+
+/* The '*' and '?' cases are there because the lexer returns them as
+ separate tokens rather than as NAME. */
+wildcard_name:
+ NAME
+ {
+ $$ = $1;
+ }
+ | '*'
+ {
+ $$ = "*";
+ }
+ | '?'
+ {
+ $$ = "?";
+ }
+ ;
+
+wildcard_spec:
+ wildcard_name
+ {
+ $$.name = $1;
+ $$.sorted = false;
+ $$.exclude_name = NULL;
+ }
+ | EXCLUDE_FILE '(' wildcard_name ')' wildcard_name
+ {
+ $$.name = $5;
+ $$.sorted = false;
+ $$.exclude_name = $3;
+ }
+ | SORT '(' wildcard_name ')'
+ {
+ $$.name = $3;
+ $$.sorted = true;
+ $$.exclude_name = NULL;
+ }
+ | SORT '(' EXCLUDE_FILE '(' wildcard_name ')' wildcard_name ')'
+ {
+ $$.name = $7;
+ $$.sorted = true;
+ $$.exclude_name = $5;
+ }
+ ;
+
+
+file_NAME_list:
+ wildcard_spec
+ {
+ lang_add_wild ($1.name, $1.sorted,
+ current_file.name,
+ current_file.sorted,
+ ldgram_had_keep, $1.exclude_name);
+ }
+ | file_NAME_list opt_comma wildcard_spec
+ {
+ lang_add_wild ($3.name, $3.sorted,
+ current_file.name,
+ current_file.sorted,
+ ldgram_had_keep, $3.exclude_name);
+ }
+ ;
+
+input_section_spec_no_keep:
+ NAME
+ {
+ lang_add_wild (NULL, false, $1, false,
+ ldgram_had_keep, NULL);
+ }
+ | '['
+ {
+ current_file.name = NULL;
+ current_file.sorted = false;
+ }
+ file_NAME_list ']'
+ | wildcard_spec
+ {
+ current_file = $1;
+ /* '*' matches any file name. */
+ if (strcmp (current_file.name, "*") == 0)
+ current_file.name = NULL;
+ }
+ '(' file_NAME_list ')'
+ ;
+
+input_section_spec:
+ input_section_spec_no_keep
+ | KEEP '('
+ { ldgram_had_keep = true; }
+ input_section_spec_no_keep ')'
+ { ldgram_had_keep = false; }
+ ;
+
+statement:
+ assignment end
+ | CREATE_OBJECT_SYMBOLS
+ {
+ lang_add_attribute(lang_object_symbols_statement_enum);
+ }
+ | ';'
+ | CONSTRUCTORS
+ {
+
+ lang_add_attribute(lang_constructors_statement_enum);
+ }
+ | SORT '(' CONSTRUCTORS ')'
+ {
+ constructors_sorted = true;
+ lang_add_attribute (lang_constructors_statement_enum);
+ }
+ | input_section_spec
+ | length '(' mustbe_exp ')'
+ {
+ lang_add_data((int) $1,$3);
+ }
+
+ | FILL '(' mustbe_exp ')'
+ {
+ lang_add_fill
+ (exp_get_value_int($3,
+ 0,
+ "fill value",
+ lang_first_phase_enum));
+ }
+ ;
+
+statement_list:
+ statement_list statement
+ | statement
+ ;
+
+statement_list_opt:
+ /* empty */
+ | statement_list
+ ;
+
+length:
+ QUAD
+ { $$ = $1; }
+ | SQUAD
+ { $$ = $1; }
+ | LONG
+ { $$ = $1; }
+ | SHORT
+ { $$ = $1; }
+ | BYTE
+ { $$ = $1; }
+ ;
+
+fill_opt:
+ '=' mustbe_exp
+ {
+ $$ = exp_get_value_int($2,
+ 0,
+ "fill value",
+ lang_first_phase_enum);
+ }
+ | { $$ = 0; }
+ ;
+
+
+
+assign_op:
+ PLUSEQ
+ { $$ = '+'; }
+ | MINUSEQ
+ { $$ = '-'; }
+ | MULTEQ
+ { $$ = '*'; }
+ | DIVEQ
+ { $$ = '/'; }
+ | LSHIFTEQ
+ { $$ = LSHIFT; }
+ | RSHIFTEQ
+ { $$ = RSHIFT; }
+ | ANDEQ
+ { $$ = '&'; }
+ | OREQ
+ { $$ = '|'; }
+
+ ;
+
+end: ';' | ','
+ ;
+
+
+assignment:
+ NAME '=' mustbe_exp
+ {
+ lang_add_assignment (exp_assop ($2, $1, $3));
+ }
+ | NAME assign_op mustbe_exp
+ {
+ lang_add_assignment (exp_assop ('=', $1,
+ exp_binop ($2,
+ exp_nameop (NAME,
+ $1),
+ $3)));
+ }
+ | PROVIDE '(' NAME '=' mustbe_exp ')'
+ {
+ lang_add_assignment (exp_provide ($3, $5));
+ }
+ ;
+
+
+opt_comma:
+ ',' | ;
+
+
+memory:
+ MEMORY '{' memory_spec memory_spec_list '}'
+ ;
+
+memory_spec_list:
+ memory_spec_list memory_spec
+ | memory_spec_list ',' memory_spec
+ |
+ ;
+
+
+memory_spec: NAME
+ { region = lang_memory_region_lookup($1); }
+ attributes_opt ':'
+ origin_spec opt_comma length_spec
+
+ ; origin_spec:
+ ORIGIN '=' mustbe_exp
+ { region->current =
+ region->origin =
+ exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
+}
+ ;
+
+length_spec:
+ LENGTH '=' mustbe_exp
+ { region->length = exp_get_vma($3,
+ ~((bfd_vma)0),
+ "length",
+ lang_first_phase_enum);
+ }
+
+
+attributes_opt:
+ '(' NAME ')'
+ {
+ lang_set_flags(region, $2);
+ }
+ |
+
+ ;
+
+startup:
+ STARTUP '(' filename ')'
+ { lang_startup($3); }
+ ;
+
+high_level_library:
+ HLL '(' high_level_library_NAME_list ')'
+ | HLL '(' ')'
+ { ldemul_hll((char *)NULL); }
+ ;
+
+high_level_library_NAME_list:
+ high_level_library_NAME_list opt_comma filename
+ { ldemul_hll($3); }
+ | filename
+ { ldemul_hll($1); }
+
+ ;
+
+low_level_library:
+ SYSLIB '(' low_level_library_NAME_list ')'
+ ; low_level_library_NAME_list:
+ low_level_library_NAME_list opt_comma filename
+ { ldemul_syslib($3); }
+ |
+ ;
+
+floating_point_support:
+ FLOAT
+ { lang_float(true); }
+ | NOFLOAT
+ { lang_float(false); }
+ ;
+
+nocrossref_list:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | NAME nocrossref_list
+ {
+ struct lang_nocrossref *n;
+
+ n = (struct lang_nocrossref *) xmalloc (sizeof *n);
+ n->name = $1;
+ n->next = $2;
+ $$ = n;
+ }
+ | NAME ',' nocrossref_list
+ {
+ struct lang_nocrossref *n;
+
+ n = (struct lang_nocrossref *) xmalloc (sizeof *n);
+ n->name = $1;
+ n->next = $3;
+ $$ = n;
+ }
+ ;
+
+mustbe_exp: { ldlex_expression(); }
+ exp
+ { ldlex_popstate(); $$=$2;}
+ ;
+
+exp :
+ '-' exp %prec UNARY
+ { $$ = exp_unop('-', $2); }
+ | '(' exp ')'
+ { $$ = $2; }
+ | NEXT '(' exp ')' %prec UNARY
+ { $$ = exp_unop((int) $1,$3); }
+ | '!' exp %prec UNARY
+ { $$ = exp_unop('!', $2); }
+ | '+' exp %prec UNARY
+ { $$ = $2; }
+ | '~' exp %prec UNARY
+ { $$ = exp_unop('~', $2);}
+
+ | exp '*' exp
+ { $$ = exp_binop('*', $1, $3); }
+ | exp '/' exp
+ { $$ = exp_binop('/', $1, $3); }
+ | exp '%' exp
+ { $$ = exp_binop('%', $1, $3); }
+ | exp '+' exp
+ { $$ = exp_binop('+', $1, $3); }
+ | exp '-' exp
+ { $$ = exp_binop('-' , $1, $3); }
+ | exp LSHIFT exp
+ { $$ = exp_binop(LSHIFT , $1, $3); }
+ | exp RSHIFT exp
+ { $$ = exp_binop(RSHIFT , $1, $3); }
+ | exp EQ exp
+ { $$ = exp_binop(EQ , $1, $3); }
+ | exp NE exp
+ { $$ = exp_binop(NE , $1, $3); }
+ | exp LE exp
+ { $$ = exp_binop(LE , $1, $3); }
+ | exp GE exp
+ { $$ = exp_binop(GE , $1, $3); }
+ | exp '<' exp
+ { $$ = exp_binop('<' , $1, $3); }
+ | exp '>' exp
+ { $$ = exp_binop('>' , $1, $3); }
+ | exp '&' exp
+ { $$ = exp_binop('&' , $1, $3); }
+ | exp '^' exp
+ { $$ = exp_binop('^' , $1, $3); }
+ | exp '|' exp
+ { $$ = exp_binop('|' , $1, $3); }
+ | exp '?' exp ':' exp
+ { $$ = exp_trinop('?' , $1, $3, $5); }
+ | exp ANDAND exp
+ { $$ = exp_binop(ANDAND , $1, $3); }
+ | exp OROR exp
+ { $$ = exp_binop(OROR , $1, $3); }
+ | DEFINED '(' NAME ')'
+ { $$ = exp_nameop(DEFINED, $3); }
+ | INT
+ { $$ = exp_intop($1); }
+ | SIZEOF_HEADERS
+ { $$ = exp_nameop(SIZEOF_HEADERS,0); }
+
+ | SIZEOF '(' NAME ')'
+ { $$ = exp_nameop(SIZEOF,$3); }
+ | ADDR '(' NAME ')'
+ { $$ = exp_nameop(ADDR,$3); }
+ | LOADADDR '(' NAME ')'
+ { $$ = exp_nameop(LOADADDR,$3); }
+ | ABSOLUTE '(' exp ')'
+ { $$ = exp_unop(ABSOLUTE, $3); }
+ | ALIGN_K '(' exp ')'
+ { $$ = exp_unop(ALIGN_K,$3); }
+ | BLOCK '(' exp ')'
+ { $$ = exp_unop(ALIGN_K,$3); }
+ | NAME
+ { $$ = exp_nameop(NAME,$1); }
+ | MAX_K '(' exp ',' exp ')'
+ { $$ = exp_binop (MAX_K, $3, $5 ); }
+ | MIN_K '(' exp ',' exp ')'
+ { $$ = exp_binop (MIN_K, $3, $5 ); }
+ | ASSERT_K '(' exp ',' NAME ')'
+ { $$ = exp_assert ($3, $5); }
+ ;
+
+
+opt_at:
+ AT '(' exp ')' { $$ = $3; }
+ | { $$ = 0; }
+ ;
+
+section: NAME { ldlex_expression(); }
+ opt_exp_with_type
+ opt_at { ldlex_popstate (); ldlex_script (); }
+ '{'
+ {
+ lang_enter_output_section_statement($1, $3,
+ sectype,
+ 0, 0, 0, $4);
+ }
+ statement_list_opt
+ '}' { ldlex_popstate (); ldlex_expression (); }
+ memspec_opt phdr_opt fill_opt
+ {
+ ldlex_popstate ();
+ lang_leave_output_section_statement ($13, $11, $12);
+ }
+ opt_comma
+ | OVERLAY
+ { ldlex_expression (); }
+ opt_exp_without_type opt_nocrossrefs opt_at
+ { ldlex_popstate (); ldlex_script (); }
+ '{'
+ {
+ lang_enter_overlay ($3, $5, (int) $4);
+ }
+ overlay_section
+ '}'
+ { ldlex_popstate (); ldlex_expression (); }
+ memspec_opt phdr_opt fill_opt
+ {
+ ldlex_popstate ();
+ lang_leave_overlay ($14, $12, $13);
+ }
+ opt_comma
+ | /* The GROUP case is just enough to support the gcc
+ svr3.ifile script. It is not intended to be full
+ support. I'm not even sure what GROUP is supposed
+ to mean. */
+ GROUP { ldlex_expression (); }
+ opt_exp_with_type
+ {
+ ldlex_popstate ();
+ lang_add_assignment (exp_assop ('=', ".", $3));
+ }
+ '{' sec_or_group_p1 '}'
+ ;
+
+type:
+ NOLOAD { sectype = noload_section; }
+ | DSECT { sectype = dsect_section; }
+ | COPY { sectype = copy_section; }
+ | INFO { sectype = info_section; }
+ | OVERLAY { sectype = overlay_section; }
+ ;
+
+atype:
+ '(' type ')'
+ | /* EMPTY */ { sectype = normal_section; }
+ | '(' ')' { sectype = normal_section; }
+ ;
+
+opt_exp_with_type:
+ exp atype ':' { $$ = $1; }
+ | atype ':' { $$ = (etree_type *)NULL; }
+ | /* The BIND cases are to support the gcc svr3.ifile
+ script. They aren't intended to implement full
+ support for the BIND keyword. I'm not even sure
+ what BIND is supposed to mean. */
+ BIND '(' exp ')' atype ':' { $$ = $3; }
+ | BIND '(' exp ')' BLOCK '(' exp ')' atype ':'
+ { $$ = $3; }
+ ;
+
+opt_exp_without_type:
+ exp ':' { $$ = $1; }
+ | ':' { $$ = (etree_type *) NULL; }
+ ;
+
+opt_nocrossrefs:
+ /* empty */
+ { $$ = 0; }
+ | NOCROSSREFS
+ { $$ = 1; }
+ ;
+
+memspec_opt:
+ '>' NAME
+ { $$ = $2; }
+ | { $$ = "*default*"; }
+ ;
+
+phdr_opt:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | phdr_opt ':' NAME
+ {
+ struct lang_output_section_phdr_list *n;
+
+ n = ((struct lang_output_section_phdr_list *)
+ xmalloc (sizeof *n));
+ n->name = $3;
+ n->used = false;
+ n->next = $1;
+ $$ = n;
+ }
+ ;
+
+overlay_section:
+ /* empty */
+ | overlay_section
+ NAME
+ {
+ ldlex_script ();
+ lang_enter_overlay_section ($2);
+ }
+ '{' statement_list_opt '}'
+ { ldlex_popstate (); ldlex_expression (); }
+ phdr_opt fill_opt
+ {
+ ldlex_popstate ();
+ lang_leave_overlay_section ($9, $8);
+ }
+ opt_comma
+ ;
+
+phdrs:
+ PHDRS '{' phdr_list '}'
+ ;
+
+phdr_list:
+ /* empty */
+ | phdr_list phdr
+ ;
+
+phdr:
+ NAME { ldlex_expression (); }
+ phdr_type phdr_qualifiers { ldlex_popstate (); }
+ ';'
+ {
+ lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at,
+ $4.flags);
+ }
+ ;
+
+phdr_type:
+ exp
+ {
+ $$ = $1;
+
+ if ($1->type.node_class == etree_name
+ && $1->type.node_code == NAME)
+ {
+ const char *s;
+ unsigned int i;
+ static const char * const phdr_types[] =
+ {
+ "PT_NULL", "PT_LOAD", "PT_DYNAMIC",
+ "PT_INTERP", "PT_NOTE", "PT_SHLIB",
+ "PT_PHDR"
+ };
+
+ s = $1->name.name;
+ for (i = 0;
+ i < sizeof phdr_types / sizeof phdr_types[0];
+ i++)
+ if (strcmp (s, phdr_types[i]) == 0)
+ {
+ $$ = exp_intop (i);
+ break;
+ }
+ }
+ }
+ ;
+
+phdr_qualifiers:
+ /* empty */
+ {
+ memset (&$$, 0, sizeof (struct phdr_info));
+ }
+ | NAME phdr_val phdr_qualifiers
+ {
+ $$ = $3;
+ if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL)
+ $$.filehdr = true;
+ else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL)
+ $$.phdrs = true;
+ else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL)
+ $$.flags = $2;
+ else
+ einfo (_("%X%P:%S: PHDRS syntax error at `%s'\n"), $1);
+ }
+ | AT '(' exp ')' phdr_qualifiers
+ {
+ $$ = $5;
+ $$.at = $3;
+ }
+ ;
+
+phdr_val:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | '(' exp ')'
+ {
+ $$ = $2;
+ }
+ ;
+
+/* This syntax is used within an external version script file. */
+
+version_script_file:
+ {
+ ldlex_version_file ();
+ PUSH_ERROR (_("VERSION script"));
+ }
+ vers_nodes
+ {
+ ldlex_popstate ();
+ POP_ERROR ();
+ }
+ ;
+
+/* This is used within a normal linker script file. */
+
+version:
+ {
+ ldlex_version_script ();
+ }
+ VERSIONK '{' vers_nodes '}'
+ {
+ ldlex_popstate ();
+ }
+ ;
+
+vers_nodes:
+ vers_node
+ | vers_nodes vers_node
+ ;
+
+vers_node:
+ VERS_TAG '{' vers_tag '}' ';'
+ {
+ lang_register_vers_node ($1, $3, NULL);
+ }
+ | VERS_TAG '{' vers_tag '}' verdep ';'
+ {
+ lang_register_vers_node ($1, $3, $5);
+ }
+ ;
+
+verdep:
+ VERS_TAG
+ {
+ $$ = lang_add_vers_depend (NULL, $1);
+ }
+ | verdep VERS_TAG
+ {
+ $$ = lang_add_vers_depend ($1, $2);
+ }
+ ;
+
+vers_tag:
+ /* empty */
+ {
+ $$ = lang_new_vers_node (NULL, NULL);
+ }
+ | vers_defns ';'
+ {
+ $$ = lang_new_vers_node ($1, NULL);
+ }
+ | GLOBAL ':' vers_defns ';'
+ {
+ $$ = lang_new_vers_node ($3, NULL);
+ }
+ | LOCAL ':' vers_defns ';'
+ {
+ $$ = lang_new_vers_node (NULL, $3);
+ }
+ | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';'
+ {
+ $$ = lang_new_vers_node ($3, $7);
+ }
+ ;
+
+vers_defns:
+ VERS_IDENTIFIER
+ {
+ $$ = lang_new_vers_regex (NULL, $1, ldgram_vers_current_lang);
+ }
+ | vers_defns ';' VERS_IDENTIFIER
+ {
+ $$ = lang_new_vers_regex ($1, $3, ldgram_vers_current_lang);
+ }
+ | EXTERN NAME '{'
+ {
+ $<name>$ = ldgram_vers_current_lang;
+ ldgram_vers_current_lang = $2;
+ }
+ vers_defns '}'
+ {
+ ldgram_vers_current_lang = $<name>4;
+ }
+ ;
+
+%%
+void
+yyerror(arg)
+ const char *arg;
+{
+ if (ldfile_assumed_script)
+ einfo (_("%P:%s: file format not recognized; treating as linker script\n"),
+ ldfile_input_filename);
+ if (error_index > 0 && error_index < ERROR_NAME_MAX)
+ einfo ("%P%F:%S: %s in %s\n", arg, error_names[error_index-1]);
+ else
+ einfo ("%P%F:%S: %s\n", arg);
+}
diff --git a/ld/ldint.texinfo b/ld/ldint.texinfo
new file mode 100644
index 00000000000..58ea788f62a
--- /dev/null
+++ b/ld/ldint.texinfo
@@ -0,0 +1,564 @@
+\input texinfo
+@setfilename ldint.info
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Ld-Internals: (ldint). The GNU linker internals.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This file documents the internals of the GNU linker ld.
+
+Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+Contributed by Cygnus Support.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy or distribute modified versions of this
+manual under the terms of the GPL (for which purpose this text may be
+regarded as a program in the language TeX).
+@end ifinfo
+
+@iftex
+@finalout
+@setchapternewpage off
+@settitle GNU Linker Internals
+@titlepage
+@title{A guide to the internals of the GNU linker}
+@author Per Bothner, Steve Chamberlain, Ian Lance Taylor, DJ Delorie
+@author Cygnus Support
+@page
+
+@tex
+\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
+\xdef\manvers{\$Revision$} % For use in headers, footers too
+{\parskip=0pt
+\hfill Cygnus Support\par
+\hfill \manvers\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1992, 93, 94, 95, 96, 97, 1998
+Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@end titlepage
+@end iftex
+
+@node Top
+@top
+
+This file documents the internals of the GNU linker @code{ld}. It is a
+collection of miscellaneous information with little form at this point.
+Mostly, it is a repository into which you can put information about
+GNU @code{ld} as you discover it (or as you design changes to @code{ld}).
+
+@menu
+* README:: The README File
+* Emulations:: How linker emulations are generated
+* Emulation Walkthrough:: A Walkthrough of a Typical Emulation
+@end menu
+
+@node README
+@chapter The @file{README} File
+
+Check the @file{README} file; it often has useful information that does not
+appear anywhere else in the directory.
+
+@node Emulations
+@chapter How linker emulations are generated
+
+Each linker target has an @dfn{emulation}. The emulation includes the
+default linker script, and certain emulations also modify certain types
+of linker behaviour.
+
+Emulations are created during the build process by the shell script
+@file{genscripts.sh}.
+
+The @file{genscripts.sh} script starts by reading a file in the
+@file{emulparams} directory. This is a shell script which sets various
+shell variables used by @file{genscripts.sh} and the other shell scripts
+it invokes.
+
+The @file{genscripts.sh} script will invoke a shell script in the
+@file{scripttempl} directory in order to create default linker scripts
+written in the linker command language. The @file{scripttempl} script
+will be invoked 5 (or, in some cases, 6) times, with different
+assignments to shell variables, to create different default scripts.
+The choice of script is made based on the command line options.
+
+After creating the scripts, @file{genscripts.sh} will invoke yet another
+shell script, this time in the @file{emultempl} directory. That shell
+script will create the emulation source file, which contains C code.
+This C code permits the linker emulation to override various linker
+behaviours. Most targets use the generic emulation code, which is in
+@file{emultempl/generic.em}.
+
+To summarize, @file{genscripts.sh} reads three shell scripts: an
+emulation parameters script in the @file{emulparams} directory, a linker
+script generation script in the @file{scripttempl} directory, and an
+emulation source file generation script in the @file{emultempl}
+directory.
+
+For example, the Sun 4 linker sets up variables in
+@file{emulparams/sun4.sh}, creates linker scripts using
+@file{scripttempl/aout.sc}, and creates the emulation code using
+@file{emultempl/sunos.em}.
+
+Note that the linker can support several emulations simultaneously,
+depending upon how it is configured. An emulation can be selected with
+the @code{-m} option. The @code{-V} option will list all supported
+emulations.
+
+@menu
+* emulation parameters:: @file{emulparams} scripts
+* linker scripts:: @file{scripttempl} scripts
+* linker emulations:: @file{emultempl} scripts
+@end menu
+
+@node emulation parameters
+@section @file{emulparams} scripts
+
+Each target selects a particular file in the @file{emulparams} directory
+by setting the shell variable @code{targ_emul} in @file{configure.tgt}.
+This shell variable is used by the @file{configure} script to control
+building an emulation source file.
+
+Certain conventions are enforced. Suppose the @code{targ_emul} variable
+is set to @var{emul} in @file{configure.tgt}. The name of the emulation
+shell script will be @file{emulparams/@var{emul}.sh}. The
+@file{Makefile} must have a target named @file{e@var{emul}.c}; this
+target must depend upon @file{emulparams/@var{emul}.sh}, as well as the
+appropriate scripts in the @file{scripttempl} and @file{emultempl}
+directories. The @file{Makefile} target must invoke @code{GENSCRIPTS}
+with two arguments: @var{emul}, and the value of the make variable
+@code{tdir_@var{emul}}. The value of the latter variable will be set by
+the @file{configure} script, and is used to set the default target
+directory to search.
+
+By convention, the @file{emulparams/@var{emul}.sh} shell script should
+only set shell variables. It may set shell variables which are to be
+interpreted by the @file{scripttempl} and the @file{emultempl} scripts.
+Certain shell variables are interpreted directly by the
+@file{genscripts.sh} script.
+
+Here is a list of shell variables interpreted by @file{genscripts.sh},
+as well as some conventional shell variables interpreted by the
+@file{scripttempl} and @file{emultempl} scripts.
+
+@table @code
+@item SCRIPT_NAME
+This is the name of the @file{scripttempl} script to use. If
+@code{SCRIPT_NAME} is set to @var{script}, @file{genscripts.sh} will use
+the script @file{scriptteml/@var{script}.sc}.
+
+@item TEMPLATE_NAME
+This is the name of the @file{emultemlp} script to use. If
+@code{TEMPLATE_NAME} is set to @var{template}, @file{genscripts.sh} will
+use the script @file{emultempl/@var{template}.em}. If this variable is
+not set, the default value is @samp{generic}.
+
+@item GENERATE_SHLIB_SCRIPT
+If this is set to a nonempty string, @file{genscripts.sh} will invoke
+the @file{scripttempl} script an extra time to create a shared library
+script. @ref{linker scripts}.
+
+@item OUTPUT_FORMAT
+This is normally set to indicate the BFD output format use (e.g.,
+@samp{"a.out-sunos-big"}. The @file{scripttempl} script will normally
+use it in an @code{OUTPUT_FORMAT} expression in the linker script.
+
+@item ARCH
+This is normally set to indicate the architecture to use (e.g.,
+@samp{sparc}). The @file{scripttempl} script will normally use it in an
+@code{OUTPUT_ARCH} expression in the linker script.
+
+@item ENTRY
+Some @file{scripttempl} scripts use this to set the entry address, in an
+@code{ENTRY} expression in the linker script.
+
+@item TEXT_START_ADDR
+Some @file{scripttempl} scripts use this to set the start address of the
+@samp{.text} section.
+
+@item NONPAGED_TEXT_START_ADDR
+If this is defined, the @file{genscripts.sh} script sets
+@code{TEXT_START_ADDR} to its value before running the
+@file{scripttempl} script for the @code{-n} and @code{-N} options
+(@pxref{linker scripts}).
+
+@item SEGMENT_SIZE
+The @file{genscripts.sh} script uses this to set the default value of
+@code{DATA_ALIGNMENT} when running the @file{scripttempl} script.
+
+@item TARGET_PAGE_SIZE
+If @code{SEGMENT_SIZE} is not defined, the @file{genscripts.sh} script
+uses this to define it.
+
+@item ALIGNMENT
+Some @file{scripttempl} scripts set this to a number to pass to
+@code{ALIGN} to set the required alignment for the @code{end} symbol.
+@end table
+
+@node linker scripts
+@section @file{scripttempl} scripts
+
+Each linker target uses a @file{scripttempl} script to generate the
+default linker scripts. The name of the @file{scripttempl} script is
+set by the @code{SCRIPT_NAME} variable in the @file{emulparams} script.
+If @code{SCRIPT_NAME} is set to @var{script}, @code{genscripts.sh} will
+invoke @file{scripttempl/@var{script}.sc}.
+
+The @file{genscripts.sh} script will invoke the @file{scripttempl}
+script 5 or 6 times. Each time it will set the shell variable
+@code{LD_FLAG} to a different value. When the linker is run, the
+options used will direct it to select a particular script. (Script
+selection is controlled by the @code{get_script} emulation entry point;
+this describes the conventional behaviour).
+
+The @file{scripttempl} script should just write a linker script, written
+in the linker command language, to standard output. If the emulation
+name--the name of the @file{emulparams} file without the @file{.sc}
+extension--is @var{emul}, then the output will be directed to
+@file{ldscripts/@var{emul}.@var{extension}} in the build directory,
+where @var{extension} changes each time the @file{scripttempl} script is
+invoked.
+
+Here is the list of values assigned to @code{LD_FLAG}.
+
+@table @code
+@item (empty)
+The script generated is used by default (when none of the following
+cases apply). The output has an extension of @file{.x}.
+@item n
+The script generated is used when the linker is invoked with the
+@code{-n} option. The output has an extension of @file{.xn}.
+@item N
+The script generated is used when the linker is invoked with the
+@code{-N} option. The output has an extension of @file{.xbn}.
+@item r
+The script generated is used when the linker is invoked with the
+@code{-r} option. The output has an extension of @file{.xr}.
+@item u
+The script generated is used when the linker is invoked with the
+@code{-Ur} option. The output has an extension of @file{.xu}.
+@item shared
+The @file{scripttempl} script is only invoked with @code{LD_FLAG} set to
+this value if @code{GENERATE_SHLIB_SCRIPT} is defined in the
+@file{emulparams} file. The @file{emultempl} script must arrange to use
+this script at the appropriate time, normally when the linker is invoked
+with the @code{-shared} option. The output has an extension of
+@file{.xs}.
+@end table
+
+Besides the shell variables set by the @file{emulparams} script, and the
+@code{LD_FLAG} variable, the @file{genscripts.sh} script will set
+certain variables for each run of the @file{scripttempl} script.
+
+@table @code
+@item RELOCATING
+This will be set to a non-empty string when the linker is doing a final
+relocation (e.g., all scripts other than @code{-r} and @code{-Ur}).
+
+@item CONSTRUCTING
+This will be set to a non-empty string when the linker is building
+global constructor and destructor tables (e.g., all scripts other than
+@code{-r}).
+
+@item DATA_ALIGNMENT
+This will be set to an @code{ALIGN} expression when the output should be
+page aligned, or to @samp{.} when generating the @code{-N} script.
+
+@item CREATE_SHLIB
+This will be set to a non-empty string when generating a @code{-shared}
+script.
+@end table
+
+The conventional way to write a @file{scripttempl} script is to first
+set a few shell variables, and then write out a linker script using
+@code{cat} with a here document. The linker script will use variable
+substitutions, based on the above variables and those set in the
+@file{emulparams} script, to control its behaviour.
+
+When there are parts of the @file{scripttempl} script which should only
+be run when doing a final relocation, they should be enclosed within a
+variable substitution based on @code{RELOCATING}. For example, on many
+targets special symbols such as @code{_end} should be defined when doing
+a final link. Naturally, those symbols should not be defined when doing
+a relocateable link using @code{-r}. The @file{scripttempl} script
+could use a construct like this to define those symbols:
+@smallexample
+ $@{RELOCATING+ _end = .;@}
+@end smallexample
+This will do the symbol assignment only if the @code{RELOCATING}
+variable is defined.
+
+The basic job of the linker script is to put the sections in the correct
+order, and at the correct memory addresses. For some targets, the
+linker script may have to do some other operations.
+
+For example, on most MIPS platforms, the linker is responsible for
+defining the special symbol @code{_gp}, used to initialize the
+@code{$gp} register. It must be set to the start of the small data
+section plus @code{0x8000}. Naturally, it should only be defined when
+doing a final relocation. This will typically be done like this:
+@smallexample
+ $@{RELOCATING+ _gp = ALIGN(16) + 0x8000;@}
+@end smallexample
+This line would appear just before the sections which compose the small
+data section (@samp{.sdata}, @samp{.sbss}). All those sections would be
+contiguous in memory.
+
+Many COFF systems build constructor tables in the linker script. The
+compiler will arrange to output the address of each global constructor
+in a @samp{.ctor} section, and the address of each global destructor in
+a @samp{.dtor} section (this is done by defining
+@code{ASM_OUTPUT_CONSTRUCTOR} and @code{ASM_OUTPUT_DESTRUCTOR} in the
+@code{gcc} configuration files). The @code{gcc} runtime support
+routines expect the constructor table to be named @code{__CTOR_LIST__}.
+They expect it to be a list of words, with the first word being the
+count of the number of entries. There should be a trailing zero word.
+(Actually, the count may be -1 if the trailing word is present, and the
+trailing word may be omitted if the count is correct, but, as the
+@code{gcc} behaviour has changed slightly over the years, it is safest
+to provide both). Here is a typical way that might be handled in a
+@file{scripttempl} file.
+@smallexample
+ $@{CONSTRUCTING+ __CTOR_LIST__ = .;@}
+ $@{CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)@}
+ $@{CONSTRUCTING+ *(.ctors)@}
+ $@{CONSTRUCTING+ LONG(0)@}
+ $@{CONSTRUCTING+ __CTOR_END__ = .;@}
+ $@{CONSTRUCTING+ __DTOR_LIST__ = .;@}
+ $@{CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)@}
+ $@{CONSTRUCTING+ *(.dtors)@}
+ $@{CONSTRUCTING+ LONG(0)@}
+ $@{CONSTRUCTING+ __DTOR_END__ = .;@}
+@end smallexample
+The use of @code{CONSTRUCTING} ensures that these linker script commands
+will only appear when the linker is supposed to be building the
+constructor and destructor tables. This example is written for a target
+which uses 4 byte pointers.
+
+Embedded systems often need to set a stack address. This is normally
+best done by using the @code{PROVIDE} construct with a default stack
+address. This permits the user to easily override the stack address
+using the @code{--defsym} option. Here is an example:
+@smallexample
+ $@{RELOCATING+ PROVIDE (__stack = 0x80000000);@}
+@end smallexample
+The value of the symbol @code{__stack} would then be used in the startup
+code to initialize the stack pointer.
+
+@node linker emulations
+@section @file{emultempl} scripts
+
+Each linker target uses an @file{emultempl} script to generate the
+emulation code. The name of the @file{emultempl} script is set by the
+@code{TEMPLATE_NAME} variable in the @file{emulparams} script. If the
+@code{TEMPLATE_NAME} variable is not set, the default is
+@samp{generic}. If the value of @code{TEMPLATE_NAME} is @var{template},
+@file{genscripts.sh} will use @file{emultempl/@var{template}.em}.
+
+Most targets use the generic @file{emultempl} script,
+@file{emultempl/generic.em}. A different @file{emultempl} script is
+only needed if the linker must support unusual actions, such as linking
+against shared libraries.
+
+The @file{emultempl} script is normally written as a simple invocation
+of @code{cat} with a here document. The document will use a few
+variable substitutions. Typically each function names uses a
+substitution involving @code{EMULATION_NAME}, for ease of debugging when
+the linker supports multiple emulations.
+
+Every function and variable in the emitted file should be static. The
+only globally visible object must be named
+@code{ld_@var{EMULATION_NAME}_emulation}, where @var{EMULATION_NAME} is
+the name of the emulation set in @file{configure.tgt} (this is also the
+name of the @file{emulparams} file without the @file{.sh} extension).
+The @file{genscripts.sh} script will set the shell variable
+@code{EMULATION_NAME} before invoking the @file{emultempl} script.
+
+The @code{ld_@var{EMULATION_NAME}_emulation} variable must be a
+@code{struct ld_emulation_xfer_struct}, as defined in @file{ldemul.h}.
+It defines a set of function pointers which are invoked by the linker,
+as well as strings for the emulation name (normally set from the shell
+variable @code{EMULATION_NAME} and the default BFD target name (normally
+set from the shell variable @code{OUTPUT_FORMAT} which is normally set
+by the @file{emulparams} file).
+
+The @file{genscripts.sh} script will set the shell variable
+@code{COMPILE_IN} when it invokes the @file{emultempl} script for the
+default emulation. In this case, the @file{emultempl} script should
+include the linker scripts directly, and return them from the
+@code{get_scripts} entry point. When the emulation is not the default,
+the @code{get_scripts} entry point should just return a file name. See
+@file{emultempl/generic.em} for an example of how this is done.
+
+At some point, the linker emulation entry points should be documented.
+
+@node Emulation Walkthrough
+@chapter A Walkthrough of a Typical Emulation
+
+This chapter is to help people who are new to the way emulations
+interact with the linker, or who are suddenly thrust into the position
+of having to work with existing emulations. It will discuss the files
+you need to be aware of. It will tell you when the given "hooks" in
+the emulation will be called. It will, hopefully, give you enough
+information about when and how things happen that you'll be able to
+get by. As always, the source is the definitive reference to this.
+
+The starting point for the linker is in @file{ldmain.c} where
+@code{main} is defined. The bulk of the code that's emulation
+specific will initially be in @code{emultempl/@var{emulation}.em} but
+will end up in @code{e@var{emulation}.c} when the build is done.
+Most of the work to select and interface with emulations is in
+@code{ldemul.h} and @code{ldemul.c}. Specifically, @code{ldemul.h}
+defines the @code{ld_emulation_xfer_struct} structure your emulation
+exports.
+
+Your emulation file exports a symbol
+@code{ld_@var{EMULATION_NAME}_emulation}. If your emulation is
+selected (it usually is, since usually there's only one),
+@code{ldemul.c} sets the variable @var{ld_emulation} to point to it.
+@code{ldemul.c} also defines a number of API functions that interface
+to your emulation, like @code{ldemul_after_parse} which simply calls
+your @code{ld_@var{EMULATION}_emulation.after_parse} function. For
+the rest of this section, the functions will be mentioned, but you
+should assume the indirect reference to your emulation also.
+
+We will also skip or gloss over parts of the link process that don't
+relate to emulations, like setting up internationalization.
+
+After initialization, @code{main} selects an emulation by pre-scanning
+the command line arguments. It calls @code{ldemul_choose_target} to
+choose a target. If you set @code{choose_target} to
+@code{ldemul_default_target}, it picks your @code{target_name} by
+default.
+
+@code{main} calls @code{ldemul_before_parse}, then @code{parse_args}.
+@code{parse_args} calls @code{ldemul_parse_args} for each arg, which
+must update the @code{getopt} globals if it recognizes the argument.
+If the emulation doesn't recognize it, then parse_args checks to see
+if it recognizes it.
+
+Now that the emulation has had access to all its command-line options,
+@code{main} calls @code{ldemul_set_symbols}. This can be used for any
+initialization that may be affected by options. It is also supposed
+to set up any variables needed by the emulation script.
+
+@code{main} now calls @code{ldemul_get_script} to get the emulation
+script to use (based on arguments, no doubt, @pxref{Emulations}) and
+runs it. While parsing, @code{ldgram.y} may call @code{ldemul_hll} or
+@code{ldemul_syslib} to handle the @code{HLL} or @code{SYSLIB}
+commands. It may call @code{ldemul_unrecognized_file} if you asked
+the linker to link a file it doesn't recognize. It will call
+@code{ldemul_recognized_file} for each file it does recognize, in case
+the emulation wants to handle some files specially. All the while,
+it's loading the files (possibly calling
+@code{ldemul_open_dynamic_archive}) and symbols and stuff. After it's
+done reading the script, @code{main} calls @code{ldemul_after_parse}.
+Use the after-parse hook to set up anything that depends on stuff the
+script might have set up, like the entry point.
+
+@code{main} next calls @code{lang_process} in @code{ldlang.c}. This
+appears to be the main core of the linking itself, as far as emulation
+hooks are concerned(*). It first opens the output file's BFD, calling
+@code{ldemul_set_output_arch}, and calls
+@code{ldemul_create_output_section_statements} in case you need to use
+other means to find or create object files (i.e. shared libraries
+found on a path, or fake stub objects). Despite the name, nobody
+creates output sections here.
+
+(*) In most cases, the BFD library does the bulk of the actual
+linking, handling symbol tables, symbol resolution, relocations, and
+building the final output file. See the BFD reference for all the
+details. Your emulation is usually concerned more with managing
+things at the file and section level, like "put this here, add this
+section", etc.
+
+Next, the objects to be linked are opened and BFDs created for them,
+and @code{ldemul_after_open} is called. At this point, you have all
+the objects and symbols loaded, but none of the data has been placed
+yet.
+
+Next comes the Big Linking Thingy (except for the parts BFD does).
+All input sections are mapped to output sections according to the
+script. If a section doesn't get mapped by default,
+@code{ldemul_place_orphan} will get called to figure out where it goes.
+Next it figures out the offsets for each section, calling
+@code{ldemul_before_allocation} before and
+@code{ldemul_after_allocation} after deciding where each input section
+ends up in the output sections.
+
+The last part of @code{lang_process} is to figure out all the symbols'
+values. After assigning final values to the symbols,
+@code{ldemul_finish} is called, and after that, any undefined symbols
+are turned into fatal errors.
+
+OK, back to @code{main}, which calls @code{ldwrite} in
+@file{ldwrite.c}. @code{ldwrite} calls BFD's final_link, which does
+all the relocation fixups and writes the output bfd to disk, and we're
+done.
+
+In summary,
+
+@itemize @bullet
+
+@item @code{main()} in @file{ldmain.c}
+@item @file{emultempl/@var{EMULATION}.em} has your code
+@item @code{ldemul_choose_target} (defaults to your @code{target_name})
+@item @code{ldemul_before_parse}
+@item Parse argv, calls @code{ldemul_parse_args} for each
+@item @code{ldemul_set_symbols}
+@item @code{ldemul_get_script}
+@item parse script
+
+@itemize @bullet
+@item may call @code{ldemul_hll} or @code{ldemul_syslib}
+@item may call @code{ldemul_open_dynamic_archive}
+@end itemize
+
+@item @code{ldemul_after_parse}
+@item @code{lang_process()} in @file{ldlang.c}
+
+@itemize @bullet
+@item create @code{output_bfd}
+@item @code{ldemul_set_output_arch}
+@item @code{ldemul_create_output_section_statements}
+@item read objects, create input bfds - all symbols exist, but have no values
+@item may call @code{ldemul_unrecognized_file}
+@item will call @code{ldemul_recognized_file}
+@item @code{ldemul_after_open}
+@item map input sections to output sections
+@item may call @code{ldemul_place_orphan} for remaining sections
+@item @code{ldemul_before_allocation}
+@item gives input sections offsets into output sections, places output sections
+@item @code{ldemul_after_allocation} - section addresses valid
+@item assigns values to symbols
+@item @code{ldemul_finish} - symbol values valid
+@end itemize
+
+@item output bfd is written to disk
+
+@end itemize
+
+@contents
+@bye
diff --git a/ld/ldlang.c b/ld/ldlang.c
new file mode 100644
index 00000000000..aa5c68131dd
--- /dev/null
+++ b/ld/ldlang.c
@@ -0,0 +1,4703 @@
+/* Linker command language support.
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "obstack.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldgram.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldemul.h"
+#include "ldlex.h"
+#include "ldmisc.h"
+#include "ldctor.h"
+#include "ldfile.h"
+#include "fnmatch.h"
+#include "demangle.h"
+
+#include <ctype.h>
+
+/* FORWARDS */
+static lang_statement_union_type *new_statement PARAMS ((enum statement_enum,
+ size_t,
+ lang_statement_list_type*));
+
+
+/* LOCALS */
+static struct obstack stat_obstack;
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+static CONST char *startup_file;
+static lang_statement_list_type input_file_chain;
+static boolean placed_commons = false;
+static lang_output_section_statement_type *default_common_section;
+static boolean map_option_f;
+static bfd_vma print_dot;
+static lang_input_statement_type *first_file;
+static lang_statement_list_type lang_output_section_statement;
+static CONST char *current_target;
+static CONST char *output_target;
+static lang_statement_list_type statement_list;
+static struct lang_phdr *lang_phdr_list;
+
+static void lang_for_each_statement_worker
+ PARAMS ((void (*func) (lang_statement_union_type *),
+ lang_statement_union_type *s));
+static lang_input_statement_type *new_afile
+ PARAMS ((const char *name, lang_input_file_enum_type file_type,
+ const char *target, boolean add_to_list));
+static void init_os PARAMS ((lang_output_section_statement_type *s));
+static void exp_init_os PARAMS ((etree_type *));
+static void section_already_linked PARAMS ((bfd *, asection *, PTR));
+static boolean wildcardp PARAMS ((const char *));
+static lang_statement_union_type *wild_sort
+ PARAMS ((lang_wild_statement_type *, lang_input_statement_type *,
+ asection *));
+static void wild_section PARAMS ((lang_wild_statement_type *ptr,
+ const char *section,
+ lang_input_statement_type *file,
+ lang_output_section_statement_type *output));
+static lang_input_statement_type *lookup_name PARAMS ((const char *name));
+static void load_symbols PARAMS ((lang_input_statement_type *entry,
+ lang_statement_list_type *));
+static void wild_file PARAMS ((lang_wild_statement_type *, const char *,
+ lang_input_statement_type *,
+ lang_output_section_statement_type *));
+static void wild PARAMS ((lang_wild_statement_type *s,
+ const char *section, const char *file,
+ const char *target,
+ lang_output_section_statement_type *output));
+static bfd *open_output PARAMS ((const char *name));
+static void ldlang_open_output PARAMS ((lang_statement_union_type *statement));
+static void open_input_bfds
+ PARAMS ((lang_statement_union_type *statement, boolean));
+static void lang_reasonable_defaults PARAMS ((void));
+static void lang_place_undefineds PARAMS ((void));
+static void map_input_to_output_sections
+ PARAMS ((lang_statement_union_type *s,
+ const char *target,
+ lang_output_section_statement_type *output_section_statement));
+static void print_output_section_statement
+ PARAMS ((lang_output_section_statement_type *output_section_statement));
+static void print_assignment
+ PARAMS ((lang_assignment_statement_type *assignment,
+ lang_output_section_statement_type *output_section));
+static void print_input_statement PARAMS ((lang_input_statement_type *statm));
+static boolean print_one_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
+static void print_input_section PARAMS ((lang_input_section_type *in));
+static void print_fill_statement PARAMS ((lang_fill_statement_type *fill));
+static void print_data_statement PARAMS ((lang_data_statement_type *data));
+static void print_address_statement PARAMS ((lang_address_statement_type *));
+static void print_reloc_statement PARAMS ((lang_reloc_statement_type *reloc));
+static void print_padding_statement PARAMS ((lang_padding_statement_type *s));
+static void print_wild_statement
+ PARAMS ((lang_wild_statement_type *w,
+ lang_output_section_statement_type *os));
+static void print_group
+ PARAMS ((lang_group_statement_type *, lang_output_section_statement_type *));
+static void print_statement PARAMS ((lang_statement_union_type *s,
+ lang_output_section_statement_type *os));
+static void print_statement_list PARAMS ((lang_statement_union_type *s,
+ lang_output_section_statement_type *os));
+static void print_statements PARAMS ((void));
+static bfd_vma insert_pad PARAMS ((lang_statement_union_type **this_ptr,
+ fill_type fill, unsigned int power,
+ asection *output_section_statement,
+ bfd_vma dot));
+static bfd_vma size_input_section
+ PARAMS ((lang_statement_union_type **this_ptr,
+ lang_output_section_statement_type *output_section_statement,
+ fill_type fill, bfd_vma dot, boolean relax));
+static void lang_finish PARAMS ((void));
+static void ignore_bfd_errors PARAMS ((const char *, ...));
+static void lang_check PARAMS ((void));
+static void lang_common PARAMS ((void));
+static boolean lang_one_common PARAMS ((struct bfd_link_hash_entry *, PTR));
+static void lang_place_orphans PARAMS ((void));
+static int topower PARAMS ((int));
+static void lang_set_startof PARAMS ((void));
+static void reset_memory_regions PARAMS ((void));
+static void lang_record_phdrs PARAMS ((void));
+static void lang_gc_wild_section
+ PARAMS ((lang_wild_statement_type *, const char *,
+ lang_input_statement_type *));
+static void lang_gc_wild_file
+ PARAMS ((lang_wild_statement_type *, const char *,
+ lang_input_statement_type *));
+static void lang_gc_wild
+ PARAMS ((lang_wild_statement_type *, const char *, const char *));
+static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *));
+static void lang_gc_sections PARAMS ((void));
+static void lang_do_version_exports_section PARAMS ((void));
+static void lang_check_section_addresses PARAMS ((void));
+
+
+/* EXPORTS */
+lang_output_section_statement_type *abs_output_section;
+lang_statement_list_type *stat_ptr = &statement_list;
+lang_statement_list_type file_chain = { 0 };
+const char *entry_symbol = NULL;
+boolean entry_from_cmdline;
+boolean lang_has_input_file = false;
+boolean had_output_filename = false;
+boolean lang_float_flag = false;
+boolean delete_output_file_on_failure = false;
+struct lang_nocrossrefs *nocrossref_list;
+
+etree_type *base; /* Relocation base - or null */
+
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+#define cat(a,b) a##b
+#else
+#define cat(a,b) a/**/b
+#endif
+
+#define new_stat(x,y) (cat(x,_type)*) new_statement(cat(x,_enum), sizeof(cat(x,_type)),y)
+
+#define outside_section_address(q) ( (q)->output_offset + (q)->output_section->vma)
+
+#define outside_symbol_address(q) ((q)->value + outside_section_address(q->section))
+
+#define SECTION_NAME_MAP_LENGTH (16)
+
+PTR
+stat_alloc (size)
+ size_t size;
+{
+ return obstack_alloc (&stat_obstack, size);
+}
+
+/*----------------------------------------------------------------------
+ lang_for_each_statement walks the parse tree and calls the provided
+ function for each node
+*/
+
+static void
+lang_for_each_statement_worker (func, s)
+ void (*func) PARAMS ((lang_statement_union_type *));
+ lang_statement_union_type *s;
+{
+ for (; s != (lang_statement_union_type *) NULL; s = s->next)
+ {
+ func (s);
+
+ switch (s->header.type)
+ {
+ case lang_constructors_statement_enum:
+ lang_for_each_statement_worker (func, constructor_list.head);
+ break;
+ case lang_output_section_statement_enum:
+ lang_for_each_statement_worker
+ (func,
+ s->output_section_statement.children.head);
+ break;
+ case lang_wild_statement_enum:
+ lang_for_each_statement_worker
+ (func,
+ s->wild_statement.children.head);
+ break;
+ case lang_group_statement_enum:
+ lang_for_each_statement_worker (func,
+ s->group_statement.children.head);
+ break;
+ case lang_data_statement_enum:
+ case lang_reloc_statement_enum:
+ case lang_object_symbols_statement_enum:
+ case lang_output_statement_enum:
+ case lang_target_statement_enum:
+ case lang_input_section_enum:
+ case lang_input_statement_enum:
+ case lang_assignment_statement_enum:
+ case lang_padding_statement_enum:
+ case lang_address_statement_enum:
+ case lang_fill_statement_enum:
+ break;
+ default:
+ FAIL ();
+ break;
+ }
+ }
+}
+
+void
+lang_for_each_statement (func)
+ void (*func) PARAMS ((lang_statement_union_type *));
+{
+ lang_for_each_statement_worker (func,
+ statement_list.head);
+}
+
+/*----------------------------------------------------------------------*/
+void
+lang_list_init (list)
+ lang_statement_list_type *list;
+{
+ list->head = (lang_statement_union_type *) NULL;
+ list->tail = &list->head;
+}
+
+/*----------------------------------------------------------------------
+
+ build a new statement node for the parse tree
+
+ */
+
+static
+lang_statement_union_type *
+new_statement (type, size, list)
+ enum statement_enum type;
+ size_t size;
+ lang_statement_list_type * list;
+{
+ lang_statement_union_type *new = (lang_statement_union_type *)
+ stat_alloc (size);
+
+ new->header.type = type;
+ new->header.next = (lang_statement_union_type *) NULL;
+ lang_statement_append (list, new, &new->header.next);
+ return new;
+}
+
+/*
+ Build a new input file node for the language. There are several ways
+ in which we treat an input file, eg, we only look at symbols, or
+ prefix it with a -l etc.
+
+ We can be supplied with requests for input files more than once;
+ they may, for example be split over serveral lines like foo.o(.text)
+ foo.o(.data) etc, so when asked for a file we check that we havn't
+ got it already so we don't duplicate the bfd.
+
+ */
+static lang_input_statement_type *
+new_afile (name, file_type, target, add_to_list)
+ CONST char *name;
+ lang_input_file_enum_type file_type;
+ CONST char *target;
+ boolean add_to_list;
+{
+ lang_input_statement_type *p;
+
+ if (add_to_list)
+ p = new_stat (lang_input_statement, stat_ptr);
+ else
+ {
+ p = ((lang_input_statement_type *)
+ stat_alloc (sizeof (lang_input_statement_type)));
+ p->header.next = NULL;
+ }
+
+ lang_has_input_file = true;
+ p->target = target;
+ switch (file_type)
+ {
+ case lang_input_file_is_symbols_only_enum:
+ p->filename = name;
+ p->is_archive = false;
+ p->real = true;
+ p->local_sym_name = name;
+ p->just_syms_flag = true;
+ p->search_dirs_flag = false;
+ break;
+ case lang_input_file_is_fake_enum:
+ p->filename = name;
+ p->is_archive = false;
+ p->real = false;
+ p->local_sym_name = name;
+ p->just_syms_flag = false;
+ p->search_dirs_flag = false;
+ break;
+ case lang_input_file_is_l_enum:
+ p->is_archive = true;
+ p->filename = name;
+ p->real = true;
+ p->local_sym_name = concat ("-l", name, (const char *) NULL);
+ p->just_syms_flag = false;
+ p->search_dirs_flag = true;
+ break;
+ case lang_input_file_is_marker_enum:
+ p->filename = name;
+ p->is_archive = false;
+ p->real = false;
+ p->local_sym_name = name;
+ p->just_syms_flag = false;
+ p->search_dirs_flag = true;
+ break;
+ case lang_input_file_is_search_file_enum:
+ p->filename = name;
+ p->is_archive = false;
+ p->real = true;
+ p->local_sym_name = name;
+ p->just_syms_flag = false;
+ p->search_dirs_flag = true;
+ break;
+ case lang_input_file_is_file_enum:
+ p->filename = name;
+ p->is_archive = false;
+ p->real = true;
+ p->local_sym_name = name;
+ p->just_syms_flag = false;
+ p->search_dirs_flag = false;
+ break;
+ default:
+ FAIL ();
+ }
+ p->the_bfd = (bfd *) NULL;
+ p->asymbols = (asymbol **) NULL;
+ p->next_real_file = (lang_statement_union_type *) NULL;
+ p->next = (lang_statement_union_type *) NULL;
+ p->symbol_count = 0;
+ p->dynamic = config.dynamic_link;
+ p->whole_archive = whole_archive;
+ p->loaded = false;
+ lang_statement_append (&input_file_chain,
+ (lang_statement_union_type *) p,
+ &p->next_real_file);
+ return p;
+}
+
+lang_input_statement_type *
+lang_add_input_file (name, file_type, target)
+ CONST char *name;
+ lang_input_file_enum_type file_type;
+ CONST char *target;
+{
+ lang_has_input_file = true;
+ return new_afile (name, file_type, target, true);
+}
+
+/* Build enough state so that the parser can build its tree */
+void
+lang_init ()
+{
+ obstack_begin (&stat_obstack, 1000);
+
+ stat_ptr = &statement_list;
+
+ lang_list_init (stat_ptr);
+
+ lang_list_init (&input_file_chain);
+ lang_list_init (&lang_output_section_statement);
+ lang_list_init (&file_chain);
+ first_file = lang_add_input_file ((char *) NULL,
+ lang_input_file_is_marker_enum,
+ (char *) NULL);
+ abs_output_section = lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
+
+ abs_output_section->bfd_section = bfd_abs_section_ptr;
+
+}
+
+/*----------------------------------------------------------------------
+ A region is an area of memory declared with the
+ MEMORY { name:org=exp, len=exp ... }
+ syntax.
+
+ We maintain a list of all the regions here
+
+ If no regions are specified in the script, then the default is used
+ which is created when looked up to be the entire data space
+*/
+
+static lang_memory_region_type *lang_memory_region_list;
+static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list;
+
+lang_memory_region_type *
+lang_memory_region_lookup (name)
+ CONST char *CONST name;
+{
+ lang_memory_region_type *p;
+
+ for (p = lang_memory_region_list;
+ p != (lang_memory_region_type *) NULL;
+ p = p->next)
+ {
+ if (strcmp (p->name, name) == 0)
+ {
+ return p;
+ }
+ }
+
+#if 0
+ /* This code used to always use the first region in the list as the
+ default region. I changed it to instead use a region
+ encompassing all of memory as the default region. This permits
+ NOLOAD sections to work reasonably without requiring a region.
+ People should specify what region they mean, if they really want
+ a region. */
+ if (strcmp (name, "*default*") == 0)
+ {
+ if (lang_memory_region_list != (lang_memory_region_type *) NULL)
+ {
+ return lang_memory_region_list;
+ }
+ }
+#endif
+
+ {
+ lang_memory_region_type *new =
+ (lang_memory_region_type *) stat_alloc (sizeof (lang_memory_region_type));
+
+ new->name = buystring (name);
+ new->next = (lang_memory_region_type *) NULL;
+
+ *lang_memory_region_list_tail = new;
+ lang_memory_region_list_tail = &new->next;
+ new->origin = 0;
+ new->flags = 0;
+ new->not_flags = 0;
+ new->length = ~(bfd_size_type)0;
+ new->current = 0;
+ new->had_full_message = false;
+
+ return new;
+ }
+}
+
+
+lang_memory_region_type *
+lang_memory_default (section)
+ asection *section;
+{
+ lang_memory_region_type *p;
+
+ flagword sec_flags = section->flags;
+
+ /* Override SEC_DATA to mean a writable section. */
+ if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC)
+ sec_flags |= SEC_DATA;
+
+ for (p = lang_memory_region_list;
+ p != (lang_memory_region_type *) NULL;
+ p = p->next)
+ {
+ if ((p->flags & sec_flags) != 0
+ && (p->not_flags & sec_flags) == 0)
+ {
+ return p;
+ }
+ }
+ return lang_memory_region_lookup ("*default*");
+}
+
+lang_output_section_statement_type *
+lang_output_section_find (name)
+ CONST char *CONST name;
+{
+ lang_statement_union_type *u;
+ lang_output_section_statement_type *lookup;
+
+ for (u = lang_output_section_statement.head;
+ u != (lang_statement_union_type *) NULL;
+ u = lookup->next)
+ {
+ lookup = &u->output_section_statement;
+ if (strcmp (name, lookup->name) == 0)
+ {
+ return lookup;
+ }
+ }
+ return (lang_output_section_statement_type *) NULL;
+}
+
+lang_output_section_statement_type *
+lang_output_section_statement_lookup (name)
+ CONST char *CONST name;
+{
+ lang_output_section_statement_type *lookup;
+
+ lookup = lang_output_section_find (name);
+ if (lookup == (lang_output_section_statement_type *) NULL)
+ {
+
+ lookup = (lang_output_section_statement_type *)
+ new_stat (lang_output_section_statement, stat_ptr);
+ lookup->region = (lang_memory_region_type *) NULL;
+ lookup->fill = 0;
+ lookup->block_value = 1;
+ lookup->name = name;
+
+ lookup->next = (lang_statement_union_type *) NULL;
+ lookup->bfd_section = (asection *) NULL;
+ lookup->processed = false;
+ lookup->sectype = normal_section;
+ lookup->addr_tree = (etree_type *) NULL;
+ lang_list_init (&lookup->children);
+
+ lookup->memspec = (CONST char *) NULL;
+ lookup->flags = 0;
+ lookup->subsection_alignment = -1;
+ lookup->section_alignment = -1;
+ lookup->load_base = (union etree_union *) NULL;
+ lookup->phdrs = NULL;
+
+ lang_statement_append (&lang_output_section_statement,
+ (lang_statement_union_type *) lookup,
+ &lookup->next);
+ }
+ return lookup;
+}
+
+static void
+lang_map_flags (flag)
+ flagword flag;
+{
+ if (flag & SEC_ALLOC)
+ minfo ("a");
+
+ if (flag & SEC_CODE)
+ minfo ("x");
+
+ if (flag & SEC_READONLY)
+ minfo ("r");
+
+ if (flag & SEC_DATA)
+ minfo ("w");
+
+ if (flag & SEC_LOAD)
+ minfo ("l");
+}
+
+void
+lang_map ()
+{
+ lang_memory_region_type *m;
+
+ minfo (_("\nMemory Configuration\n\n"));
+ fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
+ _("Name"), _("Origin"), _("Length"), _("Attributes"));
+
+ for (m = lang_memory_region_list;
+ m != (lang_memory_region_type *) NULL;
+ m = m->next)
+ {
+ char buf[100];
+ int len;
+
+ fprintf (config.map_file, "%-16s ", m->name);
+
+ sprintf_vma (buf, m->origin);
+ minfo ("0x%s ", buf);
+ len = strlen (buf);
+ while (len < 16)
+ {
+ print_space ();
+ ++len;
+ }
+
+ minfo ("0x%V", m->length);
+ if (m->flags || m->not_flags)
+ {
+#ifndef BFD64
+ minfo (" ");
+#endif
+ if (m->flags)
+ {
+ print_space ();
+ lang_map_flags (m->flags);
+ }
+
+ if (m->not_flags)
+ {
+ minfo (" !");
+ lang_map_flags (m->not_flags);
+ }
+ }
+
+ print_nl ();
+ }
+
+ fprintf (config.map_file, _("\nLinker script and memory map\n\n"));
+
+ print_statements ();
+}
+
+/* Initialize an output section. */
+
+static void
+init_os (s)
+ lang_output_section_statement_type *s;
+{
+ section_userdata_type *new;
+
+ if (s->bfd_section != NULL)
+ return;
+
+ if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
+ einfo (_("%P%F: Illegal use of `%s' section"), DISCARD_SECTION_NAME);
+
+ new = ((section_userdata_type *)
+ stat_alloc (sizeof (section_userdata_type)));
+
+ s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
+ if (s->bfd_section == (asection *) NULL)
+ s->bfd_section = bfd_make_section (output_bfd, s->name);
+ if (s->bfd_section == (asection *) NULL)
+ {
+ einfo (_("%P%F: output format %s cannot represent section called %s\n"),
+ output_bfd->xvec->name, s->name);
+ }
+ s->bfd_section->output_section = s->bfd_section;
+
+ /* We initialize an output sections output offset to minus its own */
+ /* vma to allow us to output a section through itself */
+ s->bfd_section->output_offset = 0;
+ get_userdata (s->bfd_section) = (PTR) new;
+
+ /* If there is a base address, make sure that any sections it might
+ mention are initialized. */
+ if (s->addr_tree != NULL)
+ exp_init_os (s->addr_tree);
+}
+
+/* Make sure that all output sections mentioned in an expression are
+ initialized. */
+
+static void
+exp_init_os (exp)
+ etree_type *exp;
+{
+ switch (exp->type.node_class)
+ {
+ case etree_assign:
+ exp_init_os (exp->assign.src);
+ break;
+
+ case etree_binary:
+ exp_init_os (exp->binary.lhs);
+ exp_init_os (exp->binary.rhs);
+ break;
+
+ case etree_trinary:
+ exp_init_os (exp->trinary.cond);
+ exp_init_os (exp->trinary.lhs);
+ exp_init_os (exp->trinary.rhs);
+ break;
+
+ case etree_unary:
+ exp_init_os (exp->unary.child);
+ break;
+
+ case etree_name:
+ switch (exp->type.node_code)
+ {
+ case ADDR:
+ case LOADADDR:
+ case SIZEOF:
+ {
+ lang_output_section_statement_type *os;
+
+ os = lang_output_section_find (exp->name.name);
+ if (os != NULL && os->bfd_section == NULL)
+ init_os (os);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Sections marked with the SEC_LINK_ONCE flag should only be linked
+ once into the output. This routine checks each sections, and
+ arranges to discard it if a section of the same name has already
+ been linked. This code assumes that all relevant sections have the
+ SEC_LINK_ONCE flag set; that is, it does not depend solely upon the
+ section name. This is called via bfd_map_over_sections. */
+
+/*ARGSUSED*/
+static void
+section_already_linked (abfd, sec, data)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+{
+ lang_input_statement_type *entry = (lang_input_statement_type *) data;
+ struct sec_link_once
+ {
+ struct sec_link_once *next;
+ asection *sec;
+ };
+ static struct sec_link_once *sec_link_once_list;
+ flagword flags;
+ const char *name;
+ struct sec_link_once *l;
+
+ /* If we are only reading symbols from this object, then we want to
+ discard all sections. */
+ if (entry->just_syms_flag)
+ {
+ sec->output_section = bfd_abs_section_ptr;
+ sec->output_offset = sec->vma;
+ return;
+ }
+
+ flags = bfd_get_section_flags (abfd, sec);
+
+ if ((flags & SEC_LINK_ONCE) == 0)
+ return;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ for (l = sec_link_once_list; l != NULL; l = l->next)
+ {
+ if (strcmp (name, bfd_get_section_name (l->sec->owner, l->sec)) == 0)
+ {
+ /* The section has already been linked. See if we should
+ issue a warning. */
+ switch (flags & SEC_LINK_DUPLICATES)
+ {
+ default:
+ abort ();
+
+ case SEC_LINK_DUPLICATES_DISCARD:
+ break;
+
+ case SEC_LINK_DUPLICATES_ONE_ONLY:
+ einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"),
+ abfd, name);
+ break;
+
+ case SEC_LINK_DUPLICATES_SAME_CONTENTS:
+ /* FIXME: We should really dig out the contents of both
+ sections and memcmp them. The COFF/PE spec says that
+ the Microsoft linker does not implement this
+ correctly, so I'm not going to bother doing it
+ either. */
+ /* Fall through. */
+ case SEC_LINK_DUPLICATES_SAME_SIZE:
+ if (bfd_section_size (abfd, sec)
+ != bfd_section_size (l->sec->owner, l->sec))
+ einfo (_("%P: %B: warning: duplicate section `%s' has different size\n"),
+ abfd, name);
+ break;
+ }
+
+ /* Set the output_section field so that wild_doit does not
+ create a lang_input_section structure for this section. */
+ sec->output_section = bfd_abs_section_ptr;
+
+ return;
+ }
+ }
+
+ /* This is the first section with this name. Record it. */
+
+ l = (struct sec_link_once *) xmalloc (sizeof *l);
+ l->sec = sec;
+ l->next = sec_link_once_list;
+ sec_link_once_list = l;
+}
+
+/* The wild routines.
+
+ These expand statements like *(.text) and foo.o to a list of
+ explicit actions, like foo.o(.text), bar.o(.text) and
+ foo.o(.text, .data). */
+
+/* Return true if the PATTERN argument is a wildcard pattern.
+ Although backslashes are treated specially if a pattern contains
+ wildcards, we do not consider the mere presence of a backslash to
+ be enough to cause the the pattern to be treated as a wildcard.
+ That lets us handle DOS filenames more naturally. */
+
+static boolean
+wildcardp (pattern)
+ const char *pattern;
+{
+ const char *s;
+
+ for (s = pattern; *s != '\0'; ++s)
+ if (*s == '?'
+ || *s == '*'
+ || *s == '[')
+ return true;
+ return false;
+}
+
+/* Add SECTION to the output section OUTPUT. Do this by creating a
+ lang_input_section statement which is placed at PTR. FILE is the
+ input file which holds SECTION. */
+
+void
+wild_doit (ptr, section, output, file)
+ lang_statement_list_type *ptr;
+ asection *section;
+ lang_output_section_statement_type *output;
+ lang_input_statement_type *file;
+{
+ flagword flags;
+ boolean discard;
+
+ flags = bfd_get_section_flags (section->owner, section);
+
+ discard = false;
+
+ /* If we are doing a final link, discard sections marked with
+ SEC_EXCLUDE. */
+ if (! link_info.relocateable
+ && (flags & SEC_EXCLUDE) != 0)
+ discard = true;
+
+ /* Discard input sections which are assigned to a section named
+ DISCARD_SECTION_NAME. */
+ if (strcmp (output->name, DISCARD_SECTION_NAME) == 0)
+ discard = true;
+
+ /* Discard debugging sections if we are stripping debugging
+ information. */
+ if ((link_info.strip == strip_debugger || link_info.strip == strip_all)
+ && (flags & SEC_DEBUGGING) != 0)
+ discard = true;
+
+ if (discard)
+ {
+ if (section->output_section == NULL)
+ {
+ /* This prevents future calls from assigning this section. */
+ section->output_section = bfd_abs_section_ptr;
+ }
+ return;
+ }
+
+ if (section->output_section == NULL)
+ {
+ boolean first;
+ lang_input_section_type *new;
+ flagword flags;
+
+ if (output->bfd_section == NULL)
+ {
+ init_os (output);
+ first = true;
+ }
+ else
+ first = false;
+
+ /* Add a section reference to the list */
+ new = new_stat (lang_input_section, ptr);
+
+ new->section = section;
+ new->ifile = file;
+ section->output_section = output->bfd_section;
+
+ flags = section->flags;
+
+ /* We don't copy the SEC_NEVER_LOAD flag from an input section
+ to an output section, because we want to be able to include a
+ SEC_NEVER_LOAD section in the middle of an otherwise loaded
+ section (I don't know why we want to do this, but we do).
+ build_link_order in ldwrite.c handles this case by turning
+ the embedded SEC_NEVER_LOAD section into a fill. */
+
+ flags &= ~ SEC_NEVER_LOAD;
+
+ /* If final link, don't copy the SEC_LINK_ONCE flags, they've
+ already been processed. One reason to do this is that on pe
+ format targets, .text$foo sections go into .text and it's odd
+ to see .text with SEC_LINK_ONCE set. */
+
+ if (! link_info.relocateable)
+ flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES);
+
+ /* If this is not the first input section, and the SEC_READONLY
+ flag is not currently set, then don't set it just because the
+ input section has it set. */
+
+ if (! first && (section->output_section->flags & SEC_READONLY) == 0)
+ flags &= ~ SEC_READONLY;
+
+ section->output_section->flags |= flags;
+
+ /* If SEC_READONLY is not set in the input section, then clear
+ it from the output section. */
+ if ((section->flags & SEC_READONLY) == 0)
+ section->output_section->flags &= ~SEC_READONLY;
+
+ switch (output->sectype)
+ {
+ case normal_section:
+ break;
+ case dsect_section:
+ case copy_section:
+ case info_section:
+ case overlay_section:
+ output->bfd_section->flags &= ~SEC_ALLOC;
+ break;
+ case noload_section:
+ output->bfd_section->flags &= ~SEC_LOAD;
+ output->bfd_section->flags |= SEC_NEVER_LOAD;
+ break;
+ }
+
+ if (section->alignment_power > output->bfd_section->alignment_power)
+ output->bfd_section->alignment_power = section->alignment_power;
+
+ /* If supplied an aligment, then force it. */
+ if (output->section_alignment != -1)
+ output->bfd_section->alignment_power = output->section_alignment;
+ }
+}
+
+/* Handle wildcard sorting. This returns the lang_input_section which
+ should follow the one we are going to create for SECTION and FILE,
+ based on the sorting requirements of WILD. It returns NULL if the
+ new section should just go at the end of the current list. */
+
+static lang_statement_union_type *
+wild_sort (wild, file, section)
+ lang_wild_statement_type *wild;
+ lang_input_statement_type *file;
+ asection *section;
+{
+ const char *section_name;
+ lang_statement_union_type *l;
+
+ if (! wild->filenames_sorted && ! wild->sections_sorted)
+ return NULL;
+
+ section_name = bfd_get_section_name (file->the_bfd, section);
+ for (l = wild->children.head; l != NULL; l = l->next)
+ {
+ lang_input_section_type *ls;
+
+ if (l->header.type != lang_input_section_enum)
+ continue;
+ ls = &l->input_section;
+
+ /* Sorting by filename takes precedence over sorting by section
+ name. */
+
+ if (wild->filenames_sorted)
+ {
+ const char *fn, *ln;
+ boolean fa, la;
+ int i;
+
+ /* The PE support for the .idata section as generated by
+ dlltool assumes that files will be sorted by the name of
+ the archive and then the name of the file within the
+ archive. */
+
+ if (file->the_bfd != NULL
+ && bfd_my_archive (file->the_bfd) != NULL)
+ {
+ fn = bfd_get_filename (bfd_my_archive (file->the_bfd));
+ fa = true;
+ }
+ else
+ {
+ fn = file->filename;
+ fa = false;
+ }
+
+ if (ls->ifile->the_bfd != NULL
+ && bfd_my_archive (ls->ifile->the_bfd) != NULL)
+ {
+ ln = bfd_get_filename (bfd_my_archive (ls->ifile->the_bfd));
+ la = true;
+ }
+ else
+ {
+ ln = ls->ifile->filename;
+ la = false;
+ }
+
+ i = strcmp (fn, ln);
+ if (i > 0)
+ continue;
+ else if (i < 0)
+ break;
+
+ if (fa || la)
+ {
+ if (fa)
+ fn = file->filename;
+ if (la)
+ ln = ls->ifile->filename;
+
+ i = strcmp (fn, ln);
+ if (i > 0)
+ continue;
+ else if (i < 0)
+ break;
+ }
+ }
+
+ /* Here either the files are not sorted by name, or we are
+ looking at the sections for this file. */
+
+ if (wild->sections_sorted)
+ {
+ if (strcmp (section_name,
+ bfd_get_section_name (ls->ifile->the_bfd,
+ ls->section))
+ < 0)
+ break;
+ }
+ }
+
+ return l;
+}
+
+/* Expand a wild statement for a particular FILE. SECTION may be
+ NULL, in which case it is a wild card. */
+
+static void
+wild_section (ptr, section, file, output)
+ lang_wild_statement_type *ptr;
+ const char *section;
+ lang_input_statement_type *file;
+ lang_output_section_statement_type *output;
+{
+
+ /* Don't process sections from files which were excluded. */
+ if (ptr->exclude_filename != NULL)
+ {
+ boolean match;
+
+ if (wildcardp (ptr->exclude_filename))
+ match = fnmatch (ptr->exclude_filename, file->filename, 0) == 0 ? true : false;
+ else
+ match = strcmp (ptr->exclude_filename, file->filename) == 0 ? true : false;
+
+ if (match)
+ return;
+ }
+
+ if (file->just_syms_flag == false)
+ {
+ register asection *s;
+ boolean wildcard;
+
+ if (section == NULL)
+ wildcard = false;
+ else
+ wildcard = wildcardp (section);
+
+ for (s = file->the_bfd->sections; s != NULL; s = s->next)
+ {
+ boolean match;
+
+ /* Attach all sections named SECTION. If SECTION is NULL,
+ then attach all sections.
+
+ Previously, if SECTION was NULL, this code did not call
+ wild_doit if the SEC_IS_COMMON flag was set for the
+ section. I did not understand that, and I took it out.
+ --ian@cygnus.com. */
+
+ if (section == NULL)
+ match = true;
+ else
+ {
+ const char *name;
+
+ name = bfd_get_section_name (file->the_bfd, s);
+ if (wildcard)
+ match = fnmatch (section, name, 0) == 0 ? true : false;
+ else
+ match = strcmp (section, name) == 0 ? true : false;
+ }
+
+ if (match)
+ {
+ lang_statement_union_type *before;
+
+ /* If the wild pattern was marked KEEP, the member sections
+ should be as well. */
+ if (ptr->keep_sections)
+ s->flags |= SEC_KEEP;
+
+ before = wild_sort (ptr, file, s);
+
+ /* Here BEFORE points to the lang_input_section which
+ should follow the one we are about to add. If BEFORE
+ is NULL, then the section should just go at the end
+ of the current list. */
+
+ if (before == NULL)
+ wild_doit (&ptr->children, s, output, file);
+ else
+ {
+ lang_statement_list_type list;
+ lang_statement_union_type **pp;
+
+ lang_list_init (&list);
+ wild_doit (&list, s, output, file);
+
+ /* If we are discarding the section, LIST.HEAD will
+ be NULL. */
+ if (list.head != NULL)
+ {
+ ASSERT (list.head->next == NULL);
+
+ for (pp = &ptr->children.head;
+ *pp != before;
+ pp = &(*pp)->next)
+ ASSERT (*pp != NULL);
+
+ list.head->next = *pp;
+ *pp = list.head;
+ }
+ }
+ }
+ }
+ }
+}
+
+/* This is passed a file name which must have been seen already and
+ added to the statement tree. We will see if it has been opened
+ already and had its symbols read. If not then we'll read it. */
+
+static lang_input_statement_type *
+lookup_name (name)
+ const char *name;
+{
+ lang_input_statement_type *search;
+
+ for (search = (lang_input_statement_type *) input_file_chain.head;
+ search != (lang_input_statement_type *) NULL;
+ search = (lang_input_statement_type *) search->next_real_file)
+ {
+ if (search->filename == (char *) NULL && name == (char *) NULL)
+ return search;
+ if (search->filename != (char *) NULL
+ && name != (char *) NULL
+ && strcmp (search->filename, name) == 0)
+ break;
+ }
+
+ if (search == (lang_input_statement_type *) NULL)
+ search = new_afile (name, lang_input_file_is_file_enum, default_target,
+ false);
+
+ /* If we have already added this file, or this file is not real
+ (FIXME: can that ever actually happen?) or the name is NULL
+ (FIXME: can that ever actually happen?) don't add this file. */
+ if (search->loaded
+ || ! search->real
+ || search->filename == (const char *) NULL)
+ return search;
+
+ load_symbols (search, (lang_statement_list_type *) NULL);
+
+ return search;
+}
+
+/* Get the symbols for an input file. */
+
+static void
+load_symbols (entry, place)
+ lang_input_statement_type *entry;
+ lang_statement_list_type *place;
+{
+ char **matching;
+
+ if (entry->loaded)
+ return;
+
+ ldfile_open_file (entry);
+
+ if (! bfd_check_format (entry->the_bfd, bfd_archive)
+ && ! bfd_check_format_matches (entry->the_bfd, bfd_object, &matching))
+ {
+ bfd_error_type err;
+ lang_statement_list_type *hold;
+
+ err = bfd_get_error ();
+ if (err == bfd_error_file_ambiguously_recognized)
+ {
+ char **p;
+
+ einfo (_("%B: file not recognized: %E\n"), entry->the_bfd);
+ einfo (_("%B: matching formats:"), entry->the_bfd);
+ for (p = matching; *p != NULL; p++)
+ einfo (" %s", *p);
+ einfo ("%F\n");
+ }
+ else if (err != bfd_error_file_not_recognized
+ || place == NULL)
+ einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd);
+
+ bfd_close (entry->the_bfd);
+ entry->the_bfd = NULL;
+
+ /* See if the emulation has some special knowledge. */
+
+ if (ldemul_unrecognized_file (entry))
+ return;
+
+ /* Try to interpret the file as a linker script. */
+
+ ldfile_open_command_file (entry->filename);
+
+ hold = stat_ptr;
+ stat_ptr = place;
+
+ ldfile_assumed_script = true;
+ parser_input = input_script;
+ yyparse ();
+ ldfile_assumed_script = false;
+
+ stat_ptr = hold;
+
+ return;
+ }
+
+ if (ldemul_recognized_file (entry))
+ return;
+
+ /* We don't call ldlang_add_file for an archive. Instead, the
+ add_symbols entry point will call ldlang_add_file, via the
+ add_archive_element callback, for each element of the archive
+ which is used. */
+ switch (bfd_get_format (entry->the_bfd))
+ {
+ default:
+ break;
+
+ case bfd_object:
+ ldlang_add_file (entry);
+ if (trace_files || trace_file_tries)
+ info_msg ("%I\n", entry);
+ break;
+
+ case bfd_archive:
+ if (entry->whole_archive)
+ {
+ bfd *member = bfd_openr_next_archived_file (entry->the_bfd,
+ (bfd *) NULL);
+ while (member != NULL)
+ {
+ if (! bfd_check_format (member, bfd_object))
+ einfo (_("%F%B: object %B in archive is not object\n"),
+ entry->the_bfd, member);
+ if (! ((*link_info.callbacks->add_archive_element)
+ (&link_info, member, "--whole-archive")))
+ abort ();
+ if (! bfd_link_add_symbols (member, &link_info))
+ einfo (_("%F%B: could not read symbols: %E\n"), member);
+ member = bfd_openr_next_archived_file (entry->the_bfd,
+ member);
+ }
+
+ entry->loaded = true;
+
+ return;
+ }
+ }
+
+ if (! bfd_link_add_symbols (entry->the_bfd, &link_info))
+ einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd);
+
+ entry->loaded = true;
+}
+
+/* Handle a wild statement for a single file F. */
+
+static void
+wild_file (s, section, f, output)
+ lang_wild_statement_type *s;
+ const char *section;
+ lang_input_statement_type *f;
+ lang_output_section_statement_type *output;
+{
+ if (f->the_bfd == NULL
+ || ! bfd_check_format (f->the_bfd, bfd_archive))
+ wild_section (s, section, f, output);
+ else
+ {
+ bfd *member;
+
+ /* This is an archive file. We must map each member of the
+ archive separately. */
+ member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL);
+ while (member != NULL)
+ {
+ /* When lookup_name is called, it will call the add_symbols
+ entry point for the archive. For each element of the
+ archive which is included, BFD will call ldlang_add_file,
+ which will set the usrdata field of the member to the
+ lang_input_statement. */
+ if (member->usrdata != NULL)
+ {
+ wild_section (s, section,
+ (lang_input_statement_type *) member->usrdata,
+ output);
+ }
+
+ member = bfd_openr_next_archived_file (f->the_bfd, member);
+ }
+ }
+}
+
+/* Handle a wild statement. SECTION or FILE or both may be NULL,
+ indicating that it is a wildcard. Separate lang_input_section
+ statements are created for each part of the expansion; they are
+ added after the wild statement S. OUTPUT is the output section. */
+
+static void
+wild (s, section, file, target, output)
+ lang_wild_statement_type *s;
+ const char *section;
+ const char *file;
+ const char *target;
+ lang_output_section_statement_type *output;
+{
+ lang_input_statement_type *f;
+
+ if (file == (char *) NULL)
+ {
+ /* Perform the iteration over all files in the list */
+ for (f = (lang_input_statement_type *) file_chain.head;
+ f != (lang_input_statement_type *) NULL;
+ f = (lang_input_statement_type *) f->next)
+ {
+ wild_file (s, section, f, output);
+ }
+ }
+ else if (wildcardp (file))
+ {
+ for (f = (lang_input_statement_type *) file_chain.head;
+ f != (lang_input_statement_type *) NULL;
+ f = (lang_input_statement_type *) f->next)
+ {
+ if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0)
+ wild_file (s, section, f, output);
+ }
+ }
+ else
+ {
+ /* Perform the iteration over a single file */
+ f = lookup_name (file);
+ wild_file (s, section, f, output);
+ }
+
+ if (section != (char *) NULL
+ && strcmp (section, "COMMON") == 0
+ && default_common_section == NULL)
+ {
+ /* Remember the section that common is going to in case we later
+ get something which doesn't know where to put it. */
+ default_common_section = output;
+ }
+}
+
+/* Open the output file. */
+
+static bfd *
+open_output (name)
+ const char *name;
+{
+ bfd *output;
+
+ if (output_target == (char *) NULL)
+ {
+ if (current_target != (char *) NULL)
+ output_target = current_target;
+ else
+ output_target = default_target;
+ }
+ output = bfd_openw (name, output_target);
+
+ if (output == (bfd *) NULL)
+ {
+ if (bfd_get_error () == bfd_error_invalid_target)
+ {
+ einfo (_("%P%F: target %s not found\n"), output_target);
+ }
+ einfo (_("%P%F: cannot open output file %s: %E\n"), name);
+ }
+
+ delete_output_file_on_failure = true;
+
+ /* output->flags |= D_PAGED;*/
+
+ if (! bfd_set_format (output, bfd_object))
+ einfo (_("%P%F:%s: can not make object file: %E\n"), name);
+ if (! bfd_set_arch_mach (output,
+ ldfile_output_architecture,
+ ldfile_output_machine))
+ einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
+
+ link_info.hash = bfd_link_hash_table_create (output);
+ if (link_info.hash == (struct bfd_link_hash_table *) NULL)
+ einfo (_("%P%F: can not create link hash table: %E\n"));
+
+ bfd_set_gp_size (output, g_switch_value);
+ return output;
+}
+
+
+
+
+static void
+ldlang_open_output (statement)
+ lang_statement_union_type * statement;
+{
+ switch (statement->header.type)
+ {
+ case lang_output_statement_enum:
+ ASSERT (output_bfd == (bfd *) NULL);
+ output_bfd = open_output (statement->output_statement.name);
+ ldemul_set_output_arch ();
+ if (config.magic_demand_paged && !link_info.relocateable)
+ output_bfd->flags |= D_PAGED;
+ else
+ output_bfd->flags &= ~D_PAGED;
+ if (config.text_read_only)
+ output_bfd->flags |= WP_TEXT;
+ else
+ output_bfd->flags &= ~WP_TEXT;
+ if (link_info.traditional_format)
+ output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
+ else
+ output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
+ break;
+
+ case lang_target_statement_enum:
+ current_target = statement->target_statement.target;
+ break;
+ default:
+ break;
+ }
+}
+
+/* Open all the input files. */
+
+static void
+open_input_bfds (s, force)
+ lang_statement_union_type *s;
+ boolean force;
+{
+ for (; s != (lang_statement_union_type *) NULL; s = s->next)
+ {
+ switch (s->header.type)
+ {
+ case lang_constructors_statement_enum:
+ open_input_bfds (constructor_list.head, force);
+ break;
+ case lang_output_section_statement_enum:
+ open_input_bfds (s->output_section_statement.children.head, force);
+ break;
+ case lang_wild_statement_enum:
+ /* Maybe we should load the file's symbols */
+ if (s->wild_statement.filename
+ && ! wildcardp (s->wild_statement.filename))
+ (void) lookup_name (s->wild_statement.filename);
+ open_input_bfds (s->wild_statement.children.head, force);
+ break;
+ case lang_group_statement_enum:
+ {
+ struct bfd_link_hash_entry *undefs;
+
+ /* We must continually search the entries in the group
+ until no new symbols are added to the list of undefined
+ symbols. */
+
+ do
+ {
+ undefs = link_info.hash->undefs_tail;
+ open_input_bfds (s->group_statement.children.head, true);
+ }
+ while (undefs != link_info.hash->undefs_tail);
+ }
+ break;
+ case lang_target_statement_enum:
+ current_target = s->target_statement.target;
+ break;
+ case lang_input_statement_enum:
+ if (s->input_statement.real == true)
+ {
+ lang_statement_list_type add;
+
+ s->input_statement.target = current_target;
+
+ /* If we are being called from within a group, and this
+ is an archive which has already been searched, then
+ force it to be researched. */
+ if (force
+ && s->input_statement.loaded
+ && bfd_check_format (s->input_statement.the_bfd,
+ bfd_archive))
+ s->input_statement.loaded = false;
+
+ lang_list_init (&add);
+
+ load_symbols (&s->input_statement, &add);
+
+ if (add.head != NULL)
+ {
+ *add.tail = s->next;
+ s->next = add.head;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/* If there are [COMMONS] statements, put a wild one into the bss section */
+
+static void
+lang_reasonable_defaults ()
+{
+#if 0
+ lang_output_section_statement_lookup (".text");
+ lang_output_section_statement_lookup (".data");
+
+ default_common_section =
+ lang_output_section_statement_lookup (".bss");
+
+
+ if (placed_commons == false)
+ {
+ lang_wild_statement_type *new =
+ new_stat (lang_wild_statement,
+ &default_common_section->children);
+
+ new->section_name = "COMMON";
+ new->filename = (char *) NULL;
+ lang_list_init (&new->children);
+ }
+#endif
+
+}
+
+/*
+ Add the supplied name to the symbol table as an undefined reference.
+ Remove items from the chain as we open input bfds
+ */
+typedef struct ldlang_undef_chain_list
+{
+ struct ldlang_undef_chain_list *next;
+ char *name;
+} ldlang_undef_chain_list_type;
+
+static ldlang_undef_chain_list_type *ldlang_undef_chain_list_head;
+
+void
+ldlang_add_undef (name)
+ CONST char *CONST name;
+{
+ ldlang_undef_chain_list_type *new =
+ ((ldlang_undef_chain_list_type *)
+ stat_alloc (sizeof (ldlang_undef_chain_list_type)));
+
+ new->next = ldlang_undef_chain_list_head;
+ ldlang_undef_chain_list_head = new;
+
+ new->name = buystring (name);
+}
+
+/* Run through the list of undefineds created above and place them
+ into the linker hash table as undefined symbols belonging to the
+ script file.
+*/
+static void
+lang_place_undefineds ()
+{
+ ldlang_undef_chain_list_type *ptr;
+
+ for (ptr = ldlang_undef_chain_list_head;
+ ptr != (ldlang_undef_chain_list_type *) NULL;
+ ptr = ptr->next)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, ptr->name, true, false, true);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+ if (h->type == bfd_link_hash_new)
+ {
+ h->type = bfd_link_hash_undefined;
+ h->u.undef.abfd = NULL;
+ bfd_link_add_undef (link_info.hash, h);
+ }
+ }
+}
+
+/* Open input files and attatch to output sections */
+static void
+map_input_to_output_sections (s, target, output_section_statement)
+ lang_statement_union_type * s;
+ CONST char *target;
+ lang_output_section_statement_type * output_section_statement;
+{
+ for (; s != (lang_statement_union_type *) NULL; s = s->next)
+ {
+ switch (s->header.type)
+ {
+
+
+ case lang_wild_statement_enum:
+ wild (&s->wild_statement, s->wild_statement.section_name,
+ s->wild_statement.filename, target,
+ output_section_statement);
+
+ break;
+ case lang_constructors_statement_enum:
+ map_input_to_output_sections (constructor_list.head,
+ target,
+ output_section_statement);
+ break;
+ case lang_output_section_statement_enum:
+ map_input_to_output_sections (s->output_section_statement.children.head,
+ target,
+ &s->output_section_statement);
+ break;
+ case lang_output_statement_enum:
+ break;
+ case lang_target_statement_enum:
+ target = s->target_statement.target;
+ break;
+ case lang_group_statement_enum:
+ map_input_to_output_sections (s->group_statement.children.head,
+ target,
+ output_section_statement);
+ break;
+ case lang_fill_statement_enum:
+ case lang_input_section_enum:
+ case lang_object_symbols_statement_enum:
+ case lang_data_statement_enum:
+ case lang_reloc_statement_enum:
+ case lang_padding_statement_enum:
+ case lang_input_statement_enum:
+ if (output_section_statement != NULL
+ && output_section_statement->bfd_section == NULL)
+ init_os (output_section_statement);
+ break;
+ case lang_assignment_statement_enum:
+ if (output_section_statement != NULL
+ && output_section_statement->bfd_section == NULL)
+ init_os (output_section_statement);
+
+ /* Make sure that any sections mentioned in the assignment
+ are initialized. */
+ exp_init_os (s->assignment_statement.exp);
+ break;
+ case lang_afile_asection_pair_statement_enum:
+ FAIL ();
+ break;
+ case lang_address_statement_enum:
+ /* Mark the specified section with the supplied address */
+ {
+ lang_output_section_statement_type *os =
+ lang_output_section_statement_lookup
+ (s->address_statement.section_name);
+
+ if (os->bfd_section == NULL)
+ init_os (os);
+ os->addr_tree = s->address_statement.address;
+ }
+ break;
+ }
+ }
+}
+
+static void
+print_output_section_statement (output_section_statement)
+ lang_output_section_statement_type * output_section_statement;
+{
+ asection *section = output_section_statement->bfd_section;
+ int len;
+
+ if (output_section_statement != abs_output_section)
+ {
+ minfo ("\n%s", output_section_statement->name);
+
+ if (section != NULL)
+ {
+ print_dot = section->vma;
+
+ len = strlen (output_section_statement->name);
+ if (len >= SECTION_NAME_MAP_LENGTH - 1)
+ {
+ print_nl ();
+ len = 0;
+ }
+ while (len < SECTION_NAME_MAP_LENGTH)
+ {
+ print_space ();
+ ++len;
+ }
+
+ minfo ("0x%V %W", section->vma, section->_raw_size);
+
+ if (output_section_statement->load_base != NULL)
+ {
+ bfd_vma addr;
+
+ addr = exp_get_abs_int (output_section_statement->load_base, 0,
+ "load base", lang_final_phase_enum);
+ minfo (_(" load address 0x%V"), addr);
+ }
+ }
+
+ print_nl ();
+ }
+
+ print_statement_list (output_section_statement->children.head,
+ output_section_statement);
+}
+
+static void
+print_assignment (assignment, output_section)
+ lang_assignment_statement_type * assignment;
+ lang_output_section_statement_type * output_section;
+{
+ int i;
+ etree_value_type result;
+
+ for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
+ print_space ();
+
+ result = exp_fold_tree (assignment->exp->assign.src, output_section,
+ lang_final_phase_enum, print_dot, &print_dot);
+ if (result.valid_p)
+ minfo ("0x%V", result.value + result.section->bfd_section->vma);
+ else
+ {
+ minfo ("*undef* ");
+#ifdef BFD64
+ minfo (" ");
+#endif
+ }
+
+ minfo (" ");
+
+ exp_print_tree (assignment->exp);
+
+ print_nl ();
+}
+
+static void
+print_input_statement (statm)
+ lang_input_statement_type * statm;
+{
+ if (statm->filename != (char *) NULL)
+ {
+ fprintf (config.map_file, "LOAD %s\n", statm->filename);
+ }
+}
+
+/* Print all symbols defined in a particular section. This is called
+ via bfd_link_hash_traverse. */
+
+static boolean
+print_one_symbol (hash_entry, ptr)
+ struct bfd_link_hash_entry *hash_entry;
+ PTR ptr;
+{
+ asection *sec = (asection *) ptr;
+
+ if ((hash_entry->type == bfd_link_hash_defined
+ || hash_entry->type == bfd_link_hash_defweak)
+ && sec == hash_entry->u.def.section)
+ {
+ int i;
+
+ for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
+ print_space ();
+ minfo ("0x%V ",
+ (hash_entry->u.def.value
+ + hash_entry->u.def.section->output_offset
+ + hash_entry->u.def.section->output_section->vma));
+
+ minfo (" %T\n", hash_entry->root.string);
+ }
+
+ return true;
+}
+
+/* Print information about an input section to the map file. */
+
+static void
+print_input_section (in)
+ lang_input_section_type * in;
+{
+ asection *i = in->section;
+ bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
+
+ if (size != 0)
+ {
+ print_space ();
+
+ minfo ("%s", i->name);
+
+ if (i->output_section != NULL)
+ {
+ int len;
+
+ len = 1 + strlen (i->name);
+ if (len >= SECTION_NAME_MAP_LENGTH - 1)
+ {
+ print_nl ();
+ len = 0;
+ }
+ while (len < SECTION_NAME_MAP_LENGTH)
+ {
+ print_space ();
+ ++len;
+ }
+
+ minfo ("0x%V %W %B\n",
+ i->output_section->vma + i->output_offset, size,
+ i->owner);
+
+ if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size)
+ {
+ len = SECTION_NAME_MAP_LENGTH + 3;
+#ifdef BFD64
+ len += 16;
+#else
+ len += 8;
+#endif
+ while (len > 0)
+ {
+ print_space ();
+ --len;
+ }
+
+ minfo (_("%W (size before relaxing)\n"), i->_raw_size);
+ }
+
+ bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i);
+
+ print_dot = i->output_section->vma + i->output_offset + size;
+ }
+ }
+}
+
+static void
+print_fill_statement (fill)
+ lang_fill_statement_type * fill;
+{
+ fprintf (config.map_file, " FILL mask 0x%x\n", fill->fill);
+}
+
+static void
+print_data_statement (data)
+ lang_data_statement_type * data;
+{
+ int i;
+ bfd_vma addr;
+ bfd_size_type size;
+ const char *name;
+
+ for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
+ print_space ();
+
+ addr = data->output_vma;
+ if (data->output_section != NULL)
+ addr += data->output_section->vma;
+
+ switch (data->type)
+ {
+ default:
+ abort ();
+ case BYTE:
+ size = BYTE_SIZE;
+ name = "BYTE";
+ break;
+ case SHORT:
+ size = SHORT_SIZE;
+ name = "SHORT";
+ break;
+ case LONG:
+ size = LONG_SIZE;
+ name = "LONG";
+ break;
+ case QUAD:
+ size = QUAD_SIZE;
+ name = "QUAD";
+ break;
+ case SQUAD:
+ size = QUAD_SIZE;
+ name = "SQUAD";
+ break;
+ }
+
+ minfo ("0x%V %W %s 0x%v", addr, size, name, data->value);
+
+ if (data->exp->type.node_class != etree_value)
+ {
+ print_space ();
+ exp_print_tree (data->exp);
+ }
+
+ print_nl ();
+
+ print_dot = addr + size;
+}
+
+/* Print an address statement. These are generated by options like
+ -Ttext. */
+
+static void
+print_address_statement (address)
+ lang_address_statement_type *address;
+{
+ minfo (_("Address of section %s set to "), address->section_name);
+ exp_print_tree (address->address);
+ print_nl ();
+}
+
+/* Print a reloc statement. */
+
+static void
+print_reloc_statement (reloc)
+ lang_reloc_statement_type *reloc;
+{
+ int i;
+ bfd_vma addr;
+ bfd_size_type size;
+
+ for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
+ print_space ();
+
+ addr = reloc->output_vma;
+ if (reloc->output_section != NULL)
+ addr += reloc->output_section->vma;
+
+ size = bfd_get_reloc_size (reloc->howto);
+
+ minfo ("0x%V %W RELOC %s ", addr, size, reloc->howto->name);
+
+ if (reloc->name != NULL)
+ minfo ("%s+", reloc->name);
+ else
+ minfo ("%s+", reloc->section->name);
+
+ exp_print_tree (reloc->addend_exp);
+
+ print_nl ();
+
+ print_dot = addr + size;
+}
+
+static void
+print_padding_statement (s)
+ lang_padding_statement_type *s;
+{
+ int len;
+ bfd_vma addr;
+
+ minfo (" *fill*");
+
+ len = sizeof " *fill*" - 1;
+ while (len < SECTION_NAME_MAP_LENGTH)
+ {
+ print_space ();
+ ++len;
+ }
+
+ addr = s->output_offset;
+ if (s->output_section != NULL)
+ addr += s->output_section->vma;
+ minfo ("0x%V %W", addr, s->size);
+
+ if (s->fill != 0)
+ minfo (" %u", s->fill);
+
+ print_nl ();
+
+ print_dot = addr + s->size;
+}
+
+static void
+print_wild_statement (w, os)
+ lang_wild_statement_type * w;
+ lang_output_section_statement_type * os;
+{
+ print_space ();
+
+ if (w->filenames_sorted)
+ minfo ("SORT(");
+ if (w->exclude_filename != NULL)
+ minfo ("EXCLUDE_FILE ( %s )", w->exclude_filename);
+ if (w->filename != NULL)
+ minfo ("%s", w->filename);
+ else
+ minfo ("*");
+ if (w->filenames_sorted)
+ minfo (")");
+
+ minfo ("(");
+ if (w->sections_sorted)
+ minfo ("SORT(");
+ if (w->section_name != NULL)
+ minfo ("%s", w->section_name);
+ else
+ minfo ("*");
+ if (w->sections_sorted)
+ minfo (")");
+ minfo (")");
+
+ print_nl ();
+
+ print_statement_list (w->children.head, os);
+}
+
+/* Print a group statement. */
+
+static void
+print_group (s, os)
+ lang_group_statement_type *s;
+ lang_output_section_statement_type *os;
+{
+ fprintf (config.map_file, "START GROUP\n");
+ print_statement_list (s->children.head, os);
+ fprintf (config.map_file, "END GROUP\n");
+}
+
+/* Print the list of statements in S.
+ This can be called for any statement type. */
+
+static void
+print_statement_list (s, os)
+ lang_statement_union_type *s;
+ lang_output_section_statement_type *os;
+{
+ while (s != NULL)
+ {
+ print_statement (s, os);
+ s = s->next;
+ }
+}
+
+/* Print the first statement in statement list S.
+ This can be called for any statement type. */
+
+static void
+print_statement (s, os)
+ lang_statement_union_type *s;
+ lang_output_section_statement_type *os;
+{
+ switch (s->header.type)
+ {
+ default:
+ fprintf (config.map_file, _("Fail with %d\n"), s->header.type);
+ FAIL ();
+ break;
+ case lang_constructors_statement_enum:
+ if (constructor_list.head != NULL)
+ {
+ if (constructors_sorted)
+ minfo (" SORT (CONSTRUCTORS)\n");
+ else
+ minfo (" CONSTRUCTORS\n");
+ print_statement_list (constructor_list.head, os);
+ }
+ break;
+ case lang_wild_statement_enum:
+ print_wild_statement (&s->wild_statement, os);
+ break;
+ case lang_address_statement_enum:
+ print_address_statement (&s->address_statement);
+ break;
+ case lang_object_symbols_statement_enum:
+ minfo (" CREATE_OBJECT_SYMBOLS\n");
+ break;
+ case lang_fill_statement_enum:
+ print_fill_statement (&s->fill_statement);
+ break;
+ case lang_data_statement_enum:
+ print_data_statement (&s->data_statement);
+ break;
+ case lang_reloc_statement_enum:
+ print_reloc_statement (&s->reloc_statement);
+ break;
+ case lang_input_section_enum:
+ print_input_section (&s->input_section);
+ break;
+ case lang_padding_statement_enum:
+ print_padding_statement (&s->padding_statement);
+ break;
+ case lang_output_section_statement_enum:
+ print_output_section_statement (&s->output_section_statement);
+ break;
+ case lang_assignment_statement_enum:
+ print_assignment (&s->assignment_statement, os);
+ break;
+ case lang_target_statement_enum:
+ fprintf (config.map_file, "TARGET(%s)\n", s->target_statement.target);
+ break;
+ case lang_output_statement_enum:
+ minfo ("OUTPUT(%s", s->output_statement.name);
+ if (output_target != NULL)
+ minfo (" %s", output_target);
+ minfo (")\n");
+ break;
+ case lang_input_statement_enum:
+ print_input_statement (&s->input_statement);
+ break;
+ case lang_group_statement_enum:
+ print_group (&s->group_statement, os);
+ break;
+ case lang_afile_asection_pair_statement_enum:
+ FAIL ();
+ break;
+ }
+}
+
+static void
+print_statements ()
+{
+ print_statement_list (statement_list.head, abs_output_section);
+}
+
+/* Print the first N statements in statement list S to STDERR.
+ If N == 0, nothing is printed.
+ If N < 0, the entire list is printed.
+ Intended to be called from GDB. */
+
+void
+dprint_statement (s, n)
+ lang_statement_union_type * s;
+ int n;
+{
+ FILE *map_save = config.map_file;
+
+ config.map_file = stderr;
+
+ if (n < 0)
+ print_statement_list (s, abs_output_section);
+ else
+ {
+ while (s && --n >= 0)
+ {
+ print_statement (s, abs_output_section);
+ s = s->next;
+ }
+ }
+
+ config.map_file = map_save;
+}
+
+static bfd_vma
+insert_pad (this_ptr, fill, power, output_section_statement, dot)
+ lang_statement_union_type ** this_ptr;
+ fill_type fill;
+ unsigned int power;
+ asection * output_section_statement;
+ bfd_vma dot;
+{
+ /* Align this section first to the
+ input sections requirement, then
+ to the output section's requirement.
+ If this alignment is > than any seen before,
+ then record it too. Perform the alignment by
+ inserting a magic 'padding' statement.
+ */
+
+ unsigned int alignment_needed = align_power (dot, power) - dot;
+
+ if (alignment_needed != 0)
+ {
+ lang_statement_union_type *new =
+ ((lang_statement_union_type *)
+ stat_alloc (sizeof (lang_padding_statement_type)));
+
+ /* Link into existing chain */
+ new->header.next = *this_ptr;
+ *this_ptr = new;
+ new->header.type = lang_padding_statement_enum;
+ new->padding_statement.output_section = output_section_statement;
+ new->padding_statement.output_offset =
+ dot - output_section_statement->vma;
+ new->padding_statement.fill = fill;
+ new->padding_statement.size = alignment_needed;
+ }
+
+
+ /* Remember the most restrictive alignment */
+ if (power > output_section_statement->alignment_power)
+ {
+ output_section_statement->alignment_power = power;
+ }
+ output_section_statement->_raw_size += alignment_needed;
+ return alignment_needed + dot;
+
+}
+
+/* Work out how much this section will move the dot point */
+static bfd_vma
+size_input_section (this_ptr, output_section_statement, fill, dot, relax)
+ lang_statement_union_type ** this_ptr;
+ lang_output_section_statement_type * output_section_statement;
+ fill_type fill;
+ bfd_vma dot;
+ boolean relax;
+{
+ lang_input_section_type *is = &((*this_ptr)->input_section);
+ asection *i = is->section;
+
+ if (is->ifile->just_syms_flag == false)
+ {
+ if (output_section_statement->subsection_alignment != -1)
+ i->alignment_power =
+ output_section_statement->subsection_alignment;
+
+ dot = insert_pad (this_ptr, fill, i->alignment_power,
+ output_section_statement->bfd_section, dot);
+
+ /* Remember where in the output section this input section goes */
+
+ i->output_offset = dot - output_section_statement->bfd_section->vma;
+
+ /* Mark how big the output section must be to contain this now
+ */
+ if (i->_cooked_size != 0)
+ dot += i->_cooked_size;
+ else
+ dot += i->_raw_size;
+ output_section_statement->bfd_section->_raw_size = dot - output_section_statement->bfd_section->vma;
+ }
+ else
+ {
+ i->output_offset = i->vma - output_section_statement->bfd_section->vma;
+ }
+
+ return dot;
+}
+
+/* Check to see if any allocated sections overlap with other allocated
+ sections. This can happen when the linker script specifically specifies
+ the output section addresses of the two sections. */
+static void
+lang_check_section_addresses ()
+{
+ asection * s;
+
+ /* Scan all sections in the output list. */
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ /* Ignore sections which are not loaded or which have no contents. */
+ if ((bfd_get_section_flags (output_bfd, s) & (SEC_ALLOC | SEC_LOAD))
+ && bfd_section_size (output_bfd, s) != 0)
+ {
+ asection * os;
+
+ /* Once we reach section 's' stop our seach. This prevents two
+ warning messages from being produced, one for 'section A overlaps
+ section B' and one for 'section B overlaps section A'. */
+ for (os = output_bfd->sections; os != s; os = os->next)
+ {
+ bfd_vma s_start;
+ bfd_vma s_end;
+ bfd_vma os_start;
+ bfd_vma os_end;
+
+ /* Only consider loadable sections with real contents. */
+ if (((bfd_get_section_flags (output_bfd, os)
+ & (SEC_ALLOC | SEC_LOAD)) == 0)
+ || bfd_section_size (output_bfd, os) == 0)
+ continue;
+
+ /* We must check the sections' LMA addresses not their
+ VMA addresses because overlay sections can have
+ overlapping VMAs but they must have distinct LMAs. */
+ s_start = bfd_section_lma (output_bfd, s);
+ os_start = bfd_section_lma (output_bfd, os);
+ s_end = s_start + bfd_section_size (output_bfd, s) - 1;
+ os_end = os_start + bfd_section_size (output_bfd, os) - 1;
+
+ /* Look for an overlap. */
+ if ((s_end < os_start) || (s_start > os_end))
+ continue;
+
+ einfo (
+_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
+ s->name, s_start, s_end, os->name, os_start, os_end);
+
+ /* Once we have found one overlap for this section,
+ stop looking for others. */
+ break;
+ }
+ }
+}
+
+/* This variable indicates whether bfd_relax_section should be called
+ again. */
+
+static boolean relax_again;
+
+/* Set the sizes for all the output sections. */
+
+bfd_vma
+lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
+ lang_statement_union_type * s;
+ lang_output_section_statement_type * output_section_statement;
+ lang_statement_union_type ** prev;
+ fill_type fill;
+ bfd_vma dot;
+ boolean relax;
+{
+ /* Size up the sections from their constituent parts. */
+ for (; s != (lang_statement_union_type *) NULL; s = s->next)
+ {
+ switch (s->header.type)
+ {
+ case lang_output_section_statement_enum:
+ {
+ bfd_vma after;
+ lang_output_section_statement_type *os = &s->output_section_statement;
+
+ if (os->bfd_section == NULL)
+ /* This section was never actually created. */
+ break;
+
+ /* If this is a COFF shared library section, use the size and
+ address from the input section. FIXME: This is COFF
+ specific; it would be cleaner if there were some other way
+ to do this, but nothing simple comes to mind. */
+ if ((os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
+ {
+ asection * input;
+
+ if (os->children.head == NULL
+ || os->children.head->next != NULL
+ || os->children.head->header.type != lang_input_section_enum)
+ einfo (_("%P%X: Internal error on COFF shared library section %s\n"),
+ os->name);
+
+ input = os->children.head->input_section.section;
+ bfd_set_section_vma (os->bfd_section->owner,
+ os->bfd_section,
+ bfd_section_vma (input->owner, input));
+ os->bfd_section->_raw_size = input->_raw_size;
+ break;
+ }
+
+ if (bfd_is_abs_section (os->bfd_section))
+ {
+ /* No matter what happens, an abs section starts at zero. */
+ ASSERT (os->bfd_section->vma == 0);
+ }
+ else
+ {
+ if (os->addr_tree == (etree_type *) NULL)
+ {
+ /* No address specified for this section, get one
+ from the region specification. */
+ if (os->region == (lang_memory_region_type *) NULL
+ || (((bfd_get_section_flags (output_bfd, os->bfd_section)
+ & (SEC_ALLOC | SEC_LOAD)) != 0)
+ && os->region->name[0] == '*'
+ && strcmp (os->region->name, "*default*") == 0))
+ {
+ os->region = lang_memory_default (os->bfd_section);
+ }
+
+ /* If a loadable section is using the default memory
+ region, and some non default memory regions were
+ defined, issue a warning. */
+ if ((bfd_get_section_flags (output_bfd, os->bfd_section)
+ & (SEC_ALLOC | SEC_LOAD)) != 0
+ && ! link_info.relocateable
+ && strcmp (os->region->name, "*default*") == 0
+ && lang_memory_region_list != NULL
+ && (strcmp (lang_memory_region_list->name, "*default*") != 0
+ || lang_memory_region_list->next != NULL))
+ einfo (_("%P: warning: no memory region specified for section `%s'\n"),
+ bfd_get_section_name (output_bfd, os->bfd_section));
+
+ dot = os->region->current;
+
+ if (os->section_alignment == -1)
+ {
+ bfd_vma olddot;
+
+ olddot = dot;
+ dot = align_power (dot, os->bfd_section->alignment_power);
+
+ if (dot != olddot && config.warn_section_align)
+ einfo (_("%P: warning: changing start of section %s by %u bytes\n"),
+ os->name, (unsigned int) (dot - olddot));
+ }
+ }
+ else
+ {
+ etree_value_type r;
+
+ r = exp_fold_tree (os->addr_tree,
+ abs_output_section,
+ lang_allocating_phase_enum,
+ dot, &dot);
+ if (r.valid_p == false)
+ {
+ einfo (_("%F%S: non constant address expression for section %s\n"),
+ os->name);
+ }
+ dot = r.value + r.section->bfd_section->vma;
+ }
+
+ /* The section starts here.
+ First, align to what the section needs. */
+
+ if (os->section_alignment != -1)
+ dot = align_power (dot, os->section_alignment);
+
+ bfd_set_section_vma (0, os->bfd_section, dot);
+
+ os->bfd_section->output_offset = 0;
+ }
+
+ (void) lang_size_sections (os->children.head, os, &os->children.head,
+ os->fill, dot, relax);
+
+ /* Ignore the size of the input sections, use the vma and size to
+ align against. */
+
+ after = ALIGN_N (os->bfd_section->vma +
+ os->bfd_section->_raw_size,
+ /* The coercion here is important, see ld.h. */
+ (bfd_vma) os->block_value);
+
+ if (bfd_is_abs_section (os->bfd_section))
+ ASSERT (after == os->bfd_section->vma);
+ else
+ os->bfd_section->_raw_size = after - os->bfd_section->vma;
+ dot = os->bfd_section->vma + os->bfd_section->_raw_size;
+ os->processed = true;
+
+ /* Update dot in the region ?
+ We only do this if the section is going to be allocated,
+ since unallocated sections do not contribute to the region's
+ overall size in memory. */
+ if (os->region != (lang_memory_region_type *) NULL
+ && (bfd_get_section_flags (output_bfd, os->bfd_section)
+ & (SEC_ALLOC | SEC_LOAD)))
+ {
+ os->region->current = dot;
+
+ /* Make sure this isn't silly. */
+ if (os->region->current < os->region->origin
+ || (os->region->current - os->region->origin
+ > os->region->length))
+ {
+ if (os->addr_tree != (etree_type *) NULL)
+ {
+ einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"),
+ os->region->current,
+ os->bfd_section->owner,
+ os->bfd_section->name,
+ os->region->name);
+ }
+ else
+ {
+ einfo (_("%X%P: region %s is full (%B section %s)\n"),
+ os->region->name,
+ os->bfd_section->owner,
+ os->bfd_section->name);
+ }
+ /* Reset the region pointer. */
+ os->region->current = os->region->origin;
+ }
+ }
+ }
+ break;
+
+ case lang_constructors_statement_enum:
+ dot = lang_size_sections (constructor_list.head,
+ output_section_statement,
+ &s->wild_statement.children.head,
+ fill,
+ dot, relax);
+ break;
+
+ case lang_data_statement_enum:
+ {
+ unsigned int size = 0;
+
+ s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma;
+ s->data_statement.output_section =
+ output_section_statement->bfd_section;
+
+ switch (s->data_statement.type)
+ {
+ case QUAD:
+ case SQUAD:
+ size = QUAD_SIZE;
+ break;
+ case LONG:
+ size = LONG_SIZE;
+ break;
+ case SHORT:
+ size = SHORT_SIZE;
+ break;
+ case BYTE:
+ size = BYTE_SIZE;
+ break;
+ }
+
+ dot += size;
+ output_section_statement->bfd_section->_raw_size += size;
+ /* The output section gets contents, and then we inspect for
+ any flags set in the input script which override any ALLOC. */
+ output_section_statement->bfd_section->flags |= SEC_HAS_CONTENTS;
+ if (!(output_section_statement->flags & SEC_NEVER_LOAD)) {
+ output_section_statement->bfd_section->flags |= SEC_ALLOC | SEC_LOAD;
+ }
+ }
+ break;
+
+ case lang_reloc_statement_enum:
+ {
+ int size;
+
+ s->reloc_statement.output_vma =
+ dot - output_section_statement->bfd_section->vma;
+ s->reloc_statement.output_section =
+ output_section_statement->bfd_section;
+ size = bfd_get_reloc_size (s->reloc_statement.howto);
+ dot += size;
+ output_section_statement->bfd_section->_raw_size += size;
+ }
+ break;
+
+ case lang_wild_statement_enum:
+
+ dot = lang_size_sections (s->wild_statement.children.head,
+ output_section_statement,
+ &s->wild_statement.children.head,
+
+ fill, dot, relax);
+
+ break;
+
+ case lang_object_symbols_statement_enum:
+ link_info.create_object_symbols_section =
+ output_section_statement->bfd_section;
+ break;
+ case lang_output_statement_enum:
+ case lang_target_statement_enum:
+ break;
+ case lang_input_section_enum:
+ {
+ asection *i;
+
+ i = (*prev)->input_section.section;
+ if (! relax)
+ {
+ if (i->_cooked_size == 0)
+ i->_cooked_size = i->_raw_size;
+ }
+ else
+ {
+ boolean again;
+
+ if (! bfd_relax_section (i->owner, i, &link_info, &again))
+ einfo (_("%P%F: can't relax section: %E\n"));
+ if (again)
+ relax_again = true;
+ }
+ dot = size_input_section (prev,
+ output_section_statement,
+ output_section_statement->fill,
+ dot, relax);
+ }
+ break;
+ case lang_input_statement_enum:
+ break;
+ case lang_fill_statement_enum:
+ s->fill_statement.output_section = output_section_statement->bfd_section;
+
+ fill = s->fill_statement.fill;
+ break;
+ case lang_assignment_statement_enum:
+ {
+ bfd_vma newdot = dot;
+
+ exp_fold_tree (s->assignment_statement.exp,
+ output_section_statement,
+ lang_allocating_phase_enum,
+ dot,
+ &newdot);
+
+ if (newdot != dot)
+ {
+ /* The assignment changed dot. Insert a pad. */
+ if (output_section_statement == abs_output_section)
+ {
+ /* If we don't have an output section, then just adjust
+ the default memory address. */
+ lang_memory_region_lookup ("*default*")->current = newdot;
+ }
+ else if (!relax)
+ {
+ lang_statement_union_type *new =
+ ((lang_statement_union_type *)
+ stat_alloc (sizeof (lang_padding_statement_type)));
+
+ /* Link into existing chain. */
+ new->header.next = *prev;
+ *prev = new;
+ new->header.type = lang_padding_statement_enum;
+ new->padding_statement.output_section =
+ output_section_statement->bfd_section;
+ new->padding_statement.output_offset =
+ dot - output_section_statement->bfd_section->vma;
+ new->padding_statement.fill = fill;
+ new->padding_statement.size = newdot - dot;
+ output_section_statement->bfd_section->_raw_size +=
+ new->padding_statement.size;
+ }
+
+ dot = newdot;
+ }
+ }
+ break;
+
+ case lang_padding_statement_enum:
+ /* If we are relaxing, and this is not the first pass, some
+ padding statements may have been inserted during previous
+ passes. We may have to move the padding statement to a new
+ location if dot has a different value at this point in this
+ pass than it did at this point in the previous pass. */
+ s->padding_statement.output_offset =
+ dot - output_section_statement->bfd_section->vma;
+ dot += s->padding_statement.size;
+ output_section_statement->bfd_section->_raw_size +=
+ s->padding_statement.size;
+ break;
+
+ case lang_group_statement_enum:
+ dot = lang_size_sections (s->group_statement.children.head,
+ output_section_statement,
+ &s->group_statement.children.head,
+ fill, dot, relax);
+ break;
+
+ default:
+ FAIL ();
+ break;
+
+ /* This can only get here when relaxing is turned on. */
+
+ case lang_address_statement_enum:
+ break;
+ }
+ prev = &s->header.next;
+ }
+ return dot;
+}
+
+bfd_vma
+lang_do_assignments (s, output_section_statement, fill, dot)
+ lang_statement_union_type * s;
+ lang_output_section_statement_type * output_section_statement;
+ fill_type fill;
+ bfd_vma dot;
+{
+ for (; s != (lang_statement_union_type *) NULL; s = s->next)
+ {
+ switch (s->header.type)
+ {
+ case lang_constructors_statement_enum:
+ dot = lang_do_assignments (constructor_list.head,
+ output_section_statement,
+ fill,
+ dot);
+ break;
+
+ case lang_output_section_statement_enum:
+ {
+ lang_output_section_statement_type *os =
+ &(s->output_section_statement);
+
+ if (os->bfd_section != NULL)
+ {
+ dot = os->bfd_section->vma;
+ (void) lang_do_assignments (os->children.head, os,
+ os->fill, dot);
+ dot = os->bfd_section->vma + os->bfd_section->_raw_size;
+ }
+ if (os->load_base)
+ {
+ /* If nothing has been placed into the output section then
+ it won't have a bfd_section. */
+ if (os->bfd_section)
+ {
+ os->bfd_section->lma
+ = exp_get_abs_int(os->load_base, 0,"load base", lang_final_phase_enum);
+ }
+ }
+ }
+ break;
+ case lang_wild_statement_enum:
+
+ dot = lang_do_assignments (s->wild_statement.children.head,
+ output_section_statement,
+ fill, dot);
+
+ break;
+
+ case lang_object_symbols_statement_enum:
+ case lang_output_statement_enum:
+ case lang_target_statement_enum:
+#if 0
+ case lang_common_statement_enum:
+#endif
+ break;
+ case lang_data_statement_enum:
+ {
+ etree_value_type value;
+
+ value = exp_fold_tree (s->data_statement.exp,
+ abs_output_section,
+ lang_final_phase_enum, dot, &dot);
+ s->data_statement.value = value.value;
+ if (value.valid_p == false)
+ einfo (_("%F%P: invalid data statement\n"));
+ }
+ switch (s->data_statement.type)
+ {
+ case QUAD:
+ case SQUAD:
+ dot += QUAD_SIZE;
+ break;
+ case LONG:
+ dot += LONG_SIZE;
+ break;
+ case SHORT:
+ dot += SHORT_SIZE;
+ break;
+ case BYTE:
+ dot += BYTE_SIZE;
+ break;
+ }
+ break;
+
+ case lang_reloc_statement_enum:
+ {
+ etree_value_type value;
+
+ value = exp_fold_tree (s->reloc_statement.addend_exp,
+ abs_output_section,
+ lang_final_phase_enum, dot, &dot);
+ s->reloc_statement.addend_value = value.value;
+ if (value.valid_p == false)
+ einfo (_("%F%P: invalid reloc statement\n"));
+ }
+ dot += bfd_get_reloc_size (s->reloc_statement.howto);
+ break;
+
+ case lang_input_section_enum:
+ {
+ asection *in = s->input_section.section;
+
+ if (in->_cooked_size != 0)
+ dot += in->_cooked_size;
+ else
+ dot += in->_raw_size;
+ }
+ break;
+
+ case lang_input_statement_enum:
+ break;
+ case lang_fill_statement_enum:
+ fill = s->fill_statement.fill;
+ break;
+ case lang_assignment_statement_enum:
+ {
+ exp_fold_tree (s->assignment_statement.exp,
+ output_section_statement,
+ lang_final_phase_enum,
+ dot,
+ &dot);
+ }
+
+ break;
+ case lang_padding_statement_enum:
+ dot += s->padding_statement.size;
+ break;
+
+ case lang_group_statement_enum:
+ dot = lang_do_assignments (s->group_statement.children.head,
+ output_section_statement,
+ fill, dot);
+
+ break;
+
+ default:
+ FAIL ();
+ break;
+ case lang_address_statement_enum:
+ break;
+ }
+
+ }
+ return dot;
+}
+
+/* Fix any .startof. or .sizeof. symbols. When the assemblers see the
+ operator .startof. (section_name), it produces an undefined symbol
+ .startof.section_name. Similarly, when it sees
+ .sizeof. (section_name), it produces an undefined symbol
+ .sizeof.section_name. For all the output sections, we look for
+ such symbols, and set them to the correct value. */
+
+static void
+lang_set_startof ()
+{
+ asection *s;
+
+ if (link_info.relocateable)
+ return;
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ const char *secname;
+ char *buf;
+ struct bfd_link_hash_entry *h;
+
+ secname = bfd_get_section_name (output_bfd, s);
+ buf = xmalloc (10 + strlen (secname));
+
+ sprintf (buf, ".startof.%s", secname);
+ h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
+ if (h != NULL && h->type == bfd_link_hash_undefined)
+ {
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = bfd_get_section_vma (output_bfd, s);
+ h->u.def.section = bfd_abs_section_ptr;
+ }
+
+ sprintf (buf, ".sizeof.%s", secname);
+ h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
+ if (h != NULL && h->type == bfd_link_hash_undefined)
+ {
+ h->type = bfd_link_hash_defined;
+ if (s->_cooked_size != 0)
+ h->u.def.value = s->_cooked_size;
+ else
+ h->u.def.value = s->_raw_size;
+ h->u.def.section = bfd_abs_section_ptr;
+ }
+
+ free (buf);
+ }
+}
+
+static void
+lang_finish ()
+{
+ struct bfd_link_hash_entry *h;
+ boolean warn;
+
+ if (link_info.relocateable || link_info.shared)
+ warn = false;
+ else
+ warn = true;
+
+ if (entry_symbol == (char *) NULL)
+ {
+ /* No entry has been specified. Look for start, but don't warn
+ if we don't find it. */
+ entry_symbol = "start";
+ warn = false;
+ }
+
+ h = bfd_link_hash_lookup (link_info.hash, entry_symbol, false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
+ && h->u.def.section->output_section != NULL)
+ {
+ bfd_vma val;
+
+ val = (h->u.def.value
+ + bfd_get_section_vma (output_bfd,
+ h->u.def.section->output_section)
+ + h->u.def.section->output_offset);
+ if (! bfd_set_start_address (output_bfd, val))
+ einfo (_("%P%F:%s: can't set start address\n"), entry_symbol);
+ }
+ else
+ {
+ bfd_vma val;
+ CONST char *send;
+
+ /* We couldn't find the entry symbol. Try parsing it as a
+ number. */
+ val = bfd_scan_vma (entry_symbol, &send, 0);
+ if (*send == '\0')
+ {
+ if (! bfd_set_start_address (output_bfd, val))
+ einfo (_("%P%F: can't set start address\n"));
+ }
+ else
+ {
+ asection *ts;
+
+ /* Can't find the entry symbol, and it's not a number. Use
+ the first address in the text section. */
+ ts = bfd_get_section_by_name (output_bfd, ".text");
+ if (ts != (asection *) NULL)
+ {
+ if (warn)
+ einfo (_("%P: warning: cannot find entry symbol %s; defaulting to %V\n"),
+ entry_symbol, bfd_get_section_vma (output_bfd, ts));
+ if (! bfd_set_start_address (output_bfd,
+ bfd_get_section_vma (output_bfd,
+ ts)))
+ einfo (_("%P%F: can't set start address\n"));
+ }
+ else
+ {
+ if (warn)
+ einfo (_("%P: warning: cannot find entry symbol %s; not setting start address\n"),
+ entry_symbol);
+ }
+ }
+ }
+}
+
+/* This is a small function used when we want to ignore errors from
+ BFD. */
+
+static void
+#ifdef ANSI_PROTOTYPES
+ignore_bfd_errors (const char *s, ...)
+#else
+ignore_bfd_errors (s)
+ const char *s;
+#endif
+{
+ /* Don't do anything. */
+}
+
+/* Check that the architecture of all the input files is compatible
+ with the output file. Also call the backend to let it do any
+ other checking that is needed. */
+
+static void
+lang_check ()
+{
+ lang_statement_union_type *file;
+ bfd *input_bfd;
+ CONST bfd_arch_info_type *compatible;
+
+ for (file = file_chain.head;
+ file != (lang_statement_union_type *) NULL;
+ file = file->input_statement.next)
+ {
+ input_bfd = file->input_statement.the_bfd;
+ compatible = bfd_arch_get_compatible (input_bfd,
+ output_bfd);
+ if (compatible == NULL)
+ {
+ if (command_line.warn_mismatch)
+ einfo (_("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n"),
+ bfd_printable_name (input_bfd), input_bfd,
+ bfd_printable_name (output_bfd));
+ }
+ else
+ {
+ bfd_error_handler_type pfn = NULL;
+
+ /* If we aren't supposed to warn about mismatched input
+ files, temporarily set the BFD error handler to a
+ function which will do nothing. We still want to call
+ bfd_merge_private_bfd_data, since it may set up
+ information which is needed in the output file. */
+ if (! command_line.warn_mismatch)
+ pfn = bfd_set_error_handler (ignore_bfd_errors);
+ if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
+ {
+ if (command_line.warn_mismatch)
+ einfo (_("%E%X: failed to merge target specific data of file %B\n"),
+ input_bfd);
+ }
+ if (! command_line.warn_mismatch)
+ bfd_set_error_handler (pfn);
+ }
+ }
+}
+
+/* Look through all the global common symbols and attach them to the
+ correct section. The -sort-common command line switch may be used
+ to roughly sort the entries by size. */
+
+static void
+lang_common ()
+{
+ if (link_info.relocateable
+ && ! command_line.force_common_definition)
+ return;
+
+ if (! config.sort_common)
+ bfd_link_hash_traverse (link_info.hash, lang_one_common, (PTR) NULL);
+ else
+ {
+ int power;
+
+ for (power = 4; power >= 0; power--)
+ bfd_link_hash_traverse (link_info.hash, lang_one_common,
+ (PTR) &power);
+ }
+}
+
+/* Place one common symbol in the correct section. */
+
+static boolean
+lang_one_common (h, info)
+ struct bfd_link_hash_entry *h;
+ PTR info;
+{
+ unsigned int power_of_two;
+ bfd_vma size;
+ asection *section;
+
+ if (h->type != bfd_link_hash_common)
+ return true;
+
+ size = h->u.c.size;
+ power_of_two = h->u.c.p->alignment_power;
+
+ if (config.sort_common
+ && power_of_two < (unsigned int) *(int *) info)
+ return true;
+
+ section = h->u.c.p->section;
+
+ /* Increase the size of the section. */
+ section->_cooked_size = ALIGN_N (section->_cooked_size,
+ (bfd_size_type) (1 << power_of_two));
+
+ /* Adjust the alignment if necessary. */
+ if (power_of_two > section->alignment_power)
+ section->alignment_power = power_of_two;
+
+ /* Change the symbol from common to defined. */
+ h->type = bfd_link_hash_defined;
+ h->u.def.section = section;
+ h->u.def.value = section->_cooked_size;
+
+ /* Increase the size of the section. */
+ section->_cooked_size += size;
+
+ /* Make sure the section is allocated in memory, and make sure that
+ it is no longer a common section. */
+ section->flags |= SEC_ALLOC;
+ section->flags &= ~ SEC_IS_COMMON;
+
+ if (config.map_file != NULL)
+ {
+ static boolean header_printed;
+ int len;
+ char *name;
+ char buf[50];
+
+ if (! header_printed)
+ {
+ minfo (_("\nAllocating common symbols\n"));
+ minfo (_("Common symbol size file\n\n"));
+ header_printed = true;
+ }
+
+ name = demangle (h->root.string);
+ minfo ("%s", name);
+ len = strlen (name);
+ free (name);
+
+ if (len >= 19)
+ {
+ print_nl ();
+ len = 0;
+ }
+ while (len < 20)
+ {
+ print_space ();
+ ++len;
+ }
+
+ minfo ("0x");
+ if (size <= 0xffffffff)
+ sprintf (buf, "%lx", (unsigned long) size);
+ else
+ sprintf_vma (buf, size);
+ minfo ("%s", buf);
+ len = strlen (buf);
+
+ while (len < 16)
+ {
+ print_space ();
+ ++len;
+ }
+
+ minfo ("%B\n", section->owner);
+ }
+
+ return true;
+}
+
+/*
+run through the input files and ensure that every input
+section has somewhere to go. If one is found without
+a destination then create an input request and place it
+into the statement tree.
+*/
+
+static void
+lang_place_orphans ()
+{
+ lang_input_statement_type *file;
+
+ for (file = (lang_input_statement_type *) file_chain.head;
+ file != (lang_input_statement_type *) NULL;
+ file = (lang_input_statement_type *) file->next)
+ {
+ asection *s;
+
+ for (s = file->the_bfd->sections;
+ s != (asection *) NULL;
+ s = s->next)
+ {
+ if (s->output_section == (asection *) NULL)
+ {
+ /* This section of the file is not attatched, root
+ around for a sensible place for it to go */
+
+ if (file->just_syms_flag)
+ {
+ /* We are only retrieving symbol values from this
+ file. We want the symbols to act as though the
+ values in the file are absolute. */
+ s->output_section = bfd_abs_section_ptr;
+ s->output_offset = s->vma;
+ }
+ else if (strcmp (s->name, "COMMON") == 0)
+ {
+ /* This is a lonely common section which must have
+ come from an archive. We attach to the section
+ with the wildcard. */
+ if (! link_info.relocateable
+ || command_line.force_common_definition)
+ {
+ if (default_common_section == NULL)
+ {
+#if 0
+ /* This message happens when using the
+ svr3.ifile linker script, so I have
+ disabled it. */
+ info_msg (_("%P: no [COMMON] command, defaulting to .bss\n"));
+#endif
+ default_common_section =
+ lang_output_section_statement_lookup (".bss");
+
+ }
+ wild_doit (&default_common_section->children, s,
+ default_common_section, file);
+ }
+ }
+ else if (ldemul_place_orphan (file, s))
+ ;
+ else
+ {
+ lang_output_section_statement_type *os =
+ lang_output_section_statement_lookup (s->name);
+
+ wild_doit (&os->children, s, os, file);
+ }
+ }
+ }
+ }
+}
+
+
+void
+lang_set_flags (ptr, flags)
+ lang_memory_region_type *ptr;
+ CONST char *flags;
+{
+ flagword *ptr_flags = &ptr->flags;
+
+ ptr->flags = ptr->not_flags = 0;
+ while (*flags)
+ {
+ switch (*flags)
+ {
+ case '!':
+ ptr_flags = (ptr_flags == &ptr->flags) ? &ptr->not_flags : &ptr->flags;
+ break;
+
+ case 'A': case 'a':
+ *ptr_flags |= SEC_ALLOC;
+ break;
+
+ case 'R': case 'r':
+ *ptr_flags |= SEC_READONLY;
+ break;
+
+ case 'W': case 'w':
+ *ptr_flags |= SEC_DATA;
+ break;
+
+ case 'X': case 'x':
+ *ptr_flags |= SEC_CODE;
+ break;
+
+ case 'L': case 'l':
+ case 'I': case 'i':
+ *ptr_flags |= SEC_LOAD;
+ break;
+
+ default:
+ einfo (_("%P%F: invalid syntax in flags\n"));
+ break;
+ }
+ flags++;
+ }
+}
+
+/* Call a function on each input file. This function will be called
+ on an archive, but not on the elements. */
+
+void
+lang_for_each_input_file (func)
+ void (*func) PARAMS ((lang_input_statement_type *));
+{
+ lang_input_statement_type *f;
+
+ for (f = (lang_input_statement_type *) input_file_chain.head;
+ f != NULL;
+ f = (lang_input_statement_type *) f->next_real_file)
+ func (f);
+}
+
+/* Call a function on each file. The function will be called on all
+ the elements of an archive which are included in the link, but will
+ not be called on the archive file itself. */
+
+void
+lang_for_each_file (func)
+ void (*func) PARAMS ((lang_input_statement_type *));
+{
+ lang_input_statement_type *f;
+
+ for (f = (lang_input_statement_type *) file_chain.head;
+ f != (lang_input_statement_type *) NULL;
+ f = (lang_input_statement_type *) f->next)
+ {
+ func (f);
+ }
+}
+
+#if 0
+
+/* Not used. */
+
+void
+lang_for_each_input_section (func)
+ void (*func) PARAMS ((bfd * ab, asection * as));
+{
+ lang_input_statement_type *f;
+
+ for (f = (lang_input_statement_type *) file_chain.head;
+ f != (lang_input_statement_type *) NULL;
+ f = (lang_input_statement_type *) f->next)
+ {
+ asection *s;
+
+ for (s = f->the_bfd->sections;
+ s != (asection *) NULL;
+ s = s->next)
+ {
+ func (f->the_bfd, s);
+ }
+ }
+}
+
+#endif
+
+void
+ldlang_add_file (entry)
+ lang_input_statement_type * entry;
+{
+ bfd **pp;
+
+ lang_statement_append (&file_chain,
+ (lang_statement_union_type *) entry,
+ &entry->next);
+
+ /* The BFD linker needs to have a list of all input BFDs involved in
+ a link. */
+ ASSERT (entry->the_bfd->link_next == (bfd *) NULL);
+ ASSERT (entry->the_bfd != output_bfd);
+ for (pp = &link_info.input_bfds;
+ *pp != (bfd *) NULL;
+ pp = &(*pp)->link_next)
+ ;
+ *pp = entry->the_bfd;
+ entry->the_bfd->usrdata = (PTR) entry;
+ bfd_set_gp_size (entry->the_bfd, g_switch_value);
+
+ /* Look through the sections and check for any which should not be
+ included in the link. We need to do this now, so that we can
+ notice when the backend linker tries to report multiple
+ definition errors for symbols which are in sections we aren't
+ going to link. FIXME: It might be better to entirely ignore
+ symbols which are defined in sections which are going to be
+ discarded. This would require modifying the backend linker for
+ each backend which might set the SEC_LINK_ONCE flag. If we do
+ this, we should probably handle SEC_EXCLUDE in the same way. */
+
+ bfd_map_over_sections (entry->the_bfd, section_already_linked, (PTR) entry);
+}
+
+void
+lang_add_output (name, from_script)
+ CONST char *name;
+ int from_script;
+{
+ /* Make -o on command line override OUTPUT in script. */
+ if (had_output_filename == false || !from_script)
+ {
+ output_filename = name;
+ had_output_filename = true;
+ }
+}
+
+
+static lang_output_section_statement_type *current_section;
+
+static int
+topower (x)
+ int x;
+{
+ unsigned int i = 1;
+ int l;
+
+ if (x < 0)
+ return -1;
+
+ for (l = 0; l < 32; l++)
+ {
+ if (i >= (unsigned int) x)
+ return l;
+ i <<= 1;
+ }
+
+ return 0;
+}
+
+void
+lang_enter_output_section_statement (output_section_statement_name,
+ address_exp, sectype, block_value,
+ align, subalign, ebase)
+ const char *output_section_statement_name;
+ etree_type * address_exp;
+ enum section_type sectype;
+ bfd_vma block_value;
+ etree_type *align;
+ etree_type *subalign;
+ etree_type *ebase;
+{
+ lang_output_section_statement_type *os;
+
+ current_section =
+ os =
+ lang_output_section_statement_lookup (output_section_statement_name);
+
+
+
+ /* Add this statement to tree */
+ /* add_statement(lang_output_section_statement_enum,
+ output_section_statement);*/
+ /* Make next things chain into subchain of this */
+
+ if (os->addr_tree ==
+ (etree_type *) NULL)
+ {
+ os->addr_tree =
+ address_exp;
+ }
+ os->sectype = sectype;
+ if (sectype != noload_section)
+ os->flags = SEC_NO_FLAGS;
+ else
+ os->flags = SEC_NEVER_LOAD;
+ os->block_value = block_value ? block_value : 1;
+ stat_ptr = &os->children;
+
+ os->subsection_alignment = topower(
+ exp_get_value_int(subalign, -1,
+ "subsection alignment",
+ 0));
+ os->section_alignment = topower(
+ exp_get_value_int(align, -1,
+ "section alignment", 0));
+
+ os->load_base = ebase;
+}
+
+
+void
+lang_final ()
+{
+ lang_output_statement_type *new =
+ new_stat (lang_output_statement, stat_ptr);
+
+ new->name = output_filename;
+}
+
+/* Reset the current counters in the regions */
+static void
+reset_memory_regions ()
+{
+ lang_memory_region_type *p = lang_memory_region_list;
+
+ for (p = lang_memory_region_list;
+ p != (lang_memory_region_type *) NULL;
+ p = p->next)
+ {
+ p->old_length = (bfd_size_type) (p->current - p->origin);
+ p->current = p->origin;
+ }
+}
+
+/* ??? At some point this traversal for GC should share code with the
+ traversal for manipulating the output file. */
+
+/* Expand a wild statement for a particular FILE, marking its sections KEEP
+ as needed. SECTION may be NULL, in which case it is a wild card. */
+
+static void
+lang_gc_wild_section (ptr, section, file)
+ lang_wild_statement_type *ptr;
+ const char *section;
+ lang_input_statement_type *file;
+{
+ if (file->just_syms_flag == false)
+ {
+ register asection *s;
+ boolean wildcard;
+
+ if (section == NULL)
+ wildcard = false;
+ else
+ wildcard = wildcardp (section);
+
+ for (s = file->the_bfd->sections; s != NULL; s = s->next)
+ {
+ boolean match;
+
+ if (section == NULL)
+ match = true;
+ else
+ {
+ const char *name;
+
+ name = bfd_get_section_name (file->the_bfd, s);
+ if (wildcard)
+ match = fnmatch (section, name, 0) == 0 ? true : false;
+ else
+ match = strcmp (section, name) == 0 ? true : false;
+ }
+
+ if (match)
+ {
+ /* If the wild pattern was marked KEEP, the member sections
+ should be as well. */
+ if (ptr->keep_sections)
+ s->flags |= SEC_KEEP;
+ }
+ }
+ }
+}
+
+/* Handle a wild statement for a single file F. */
+
+static void
+lang_gc_wild_file (s, section, f)
+ lang_wild_statement_type *s;
+ const char *section;
+ lang_input_statement_type *f;
+{
+ if (f->the_bfd == NULL
+ || ! bfd_check_format (f->the_bfd, bfd_archive))
+ lang_gc_wild_section (s, section, f);
+ else
+ {
+ bfd *member;
+
+ /* This is an archive file. We must map each member of the
+ archive separately. */
+ member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL);
+ while (member != NULL)
+ {
+ /* When lookup_name is called, it will call the add_symbols
+ entry point for the archive. For each element of the
+ archive which is included, BFD will call ldlang_add_file,
+ which will set the usrdata field of the member to the
+ lang_input_statement. */
+ if (member->usrdata != NULL)
+ {
+ lang_gc_wild_section (s, section,
+ (lang_input_statement_type *) member->usrdata);
+ }
+
+ member = bfd_openr_next_archived_file (f->the_bfd, member);
+ }
+ }
+}
+
+/* Handle a wild statement, marking it against GC. SECTION or FILE or both
+ may be NULL, indicating that it is a wildcard. */
+
+static void
+lang_gc_wild (s, section, file)
+ lang_wild_statement_type *s;
+ const char *section;
+ const char *file;
+{
+ lang_input_statement_type *f;
+
+ if (file == (char *) NULL)
+ {
+ /* Perform the iteration over all files in the list */
+ for (f = (lang_input_statement_type *) file_chain.head;
+ f != (lang_input_statement_type *) NULL;
+ f = (lang_input_statement_type *) f->next)
+ {
+ lang_gc_wild_file (s, section, f);
+ }
+ }
+ else if (wildcardp (file))
+ {
+ for (f = (lang_input_statement_type *) file_chain.head;
+ f != (lang_input_statement_type *) NULL;
+ f = (lang_input_statement_type *) f->next)
+ {
+ if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0)
+ lang_gc_wild_file (s, section, f);
+ }
+ }
+ else
+ {
+ /* Perform the iteration over a single file */
+ f = lookup_name (file);
+ lang_gc_wild_file (s, section, f);
+ }
+}
+
+/* Iterate over sections marking them against GC. */
+
+static void
+lang_gc_sections_1 (s)
+ lang_statement_union_type * s;
+{
+ for (; s != (lang_statement_union_type *) NULL; s = s->next)
+ {
+ switch (s->header.type)
+ {
+ case lang_wild_statement_enum:
+ lang_gc_wild (&s->wild_statement,
+ s->wild_statement.section_name,
+ s->wild_statement.filename);
+ break;
+ case lang_constructors_statement_enum:
+ lang_gc_sections_1 (constructor_list.head);
+ break;
+ case lang_output_section_statement_enum:
+ lang_gc_sections_1 (s->output_section_statement.children.head);
+ break;
+ case lang_group_statement_enum:
+ lang_gc_sections_1 (s->group_statement.children.head);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+lang_gc_sections ()
+{
+ struct bfd_link_hash_entry *h;
+ ldlang_undef_chain_list_type *ulist, fake_list_start;
+
+ /* Keep all sections so marked in the link script. */
+
+ lang_gc_sections_1 (statement_list.head);
+
+ /* Keep all sections containing symbols undefined on the command-line.
+ Handle the entry symbol at the same time. */
+
+ fake_list_start.next = ldlang_undef_chain_list_head;
+ if (entry_symbol == NULL)
+ fake_list_start.name = "start";
+ else
+ fake_list_start.name = (char *) entry_symbol;
+
+ for (ulist = &fake_list_start; ulist; ulist = ulist->next)
+ {
+ h = bfd_link_hash_lookup (link_info.hash, ulist->name,
+ false, false, false);
+
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
+ && ! bfd_is_abs_section (h->u.def.section))
+ {
+ h->u.def.section->flags |= SEC_KEEP;
+ }
+ }
+
+ bfd_gc_sections (output_bfd, &link_info);
+}
+
+void
+lang_process ()
+{
+ lang_reasonable_defaults ();
+ current_target = default_target;
+
+ lang_for_each_statement (ldlang_open_output); /* Open the output file */
+
+ ldemul_create_output_section_statements ();
+
+ /* Add to the hash table all undefineds on the command line */
+ lang_place_undefineds ();
+
+ /* Create a bfd for each input file */
+ current_target = default_target;
+ open_input_bfds (statement_list.head, false);
+
+ ldemul_after_open ();
+
+ /* Make sure that we're not mixing architectures. We call this
+ after all the input files have been opened, but before we do any
+ other processing, so that any operations merge_private_bfd_data
+ does on the output file will be known during the rest of the
+ link. */
+ lang_check ();
+
+ /* Handle .exports instead of a version script if we're told to do so. */
+ if (command_line.version_exports_section)
+ lang_do_version_exports_section ();
+
+ /* Build all sets based on the information gathered from the input
+ files. */
+ ldctor_build_sets ();
+
+ /* Remove unreferenced sections if asked to. */
+ if (command_line.gc_sections)
+ lang_gc_sections ();
+
+ /* Size up the common data */
+ lang_common ();
+
+ /* Run through the contours of the script and attach input sections
+ to the correct output sections
+ */
+ map_input_to_output_sections (statement_list.head, (char *) NULL,
+ (lang_output_section_statement_type *) NULL);
+
+
+ /* Find any sections not attached explicitly and handle them */
+ lang_place_orphans ();
+
+ ldemul_before_allocation ();
+
+ /* We must record the program headers before we try to fix the
+ section positions, since they will affect SIZEOF_HEADERS. */
+ lang_record_phdrs ();
+
+ /* Now run around and relax if we can */
+ if (command_line.relax)
+ {
+ /* First time round is a trial run to get the 'worst case'
+ addresses of the objects if there was no relaxing. */
+ lang_size_sections (statement_list.head,
+ abs_output_section,
+ &(statement_list.head), 0, (bfd_vma) 0, false);
+
+ /* Keep relaxing until bfd_relax_section gives up. */
+ do
+ {
+ reset_memory_regions ();
+
+ relax_again = false;
+
+ /* Note: pe-dll.c does something like this also. If you find
+ you need to change this code, you probably need to change
+ pe-dll.c also. DJ */
+
+ /* Do all the assignments with our current guesses as to
+ section sizes. */
+ lang_do_assignments (statement_list.head,
+ abs_output_section,
+ (fill_type) 0, (bfd_vma) 0);
+
+ /* Perform another relax pass - this time we know where the
+ globals are, so can make better guess. */
+ lang_size_sections (statement_list.head,
+ abs_output_section,
+ &(statement_list.head), 0, (bfd_vma) 0, true);
+ }
+ while (relax_again);
+ }
+ else
+ {
+ /* Size up the sections. */
+ lang_size_sections (statement_list.head,
+ abs_output_section,
+ &(statement_list.head), 0, (bfd_vma) 0, false);
+ }
+
+ /* See if anything special should be done now we know how big
+ everything is. */
+ ldemul_after_allocation ();
+
+ /* Fix any .startof. or .sizeof. symbols. */
+ lang_set_startof ();
+
+ /* Do all the assignments, now that we know the final restingplaces
+ of all the symbols */
+
+ lang_do_assignments (statement_list.head,
+ abs_output_section,
+ (fill_type) 0, (bfd_vma) 0);
+
+ /* Make sure that the section addresses make sense. */
+ if (! link_info.relocateable
+ && command_line.check_section_addresses)
+ lang_check_section_addresses ();
+
+ /* Final stuffs */
+
+ ldemul_finish ();
+ lang_finish ();
+}
+
+/* EXPORTED TO YACC */
+
+void
+lang_add_wild (section_name, sections_sorted, filename, filenames_sorted,
+ keep_sections, exclude_filename)
+ const char *const section_name;
+ boolean sections_sorted;
+ const char *const filename;
+ boolean filenames_sorted;
+ boolean keep_sections;
+ const char *exclude_filename;
+{
+ lang_wild_statement_type *new = new_stat (lang_wild_statement,
+ stat_ptr);
+
+ if (section_name != (char *) NULL && strcmp (section_name, "COMMON") == 0)
+ {
+ placed_commons = true;
+ }
+ if (filename != NULL && ! wildcardp (filename))
+ {
+ lang_has_input_file = true;
+ }
+ new->section_name = section_name;
+ new->sections_sorted = sections_sorted;
+ new->filename = filename;
+ new->filenames_sorted = filenames_sorted;
+ new->keep_sections = keep_sections;
+ new->exclude_filename = exclude_filename;
+ lang_list_init (&new->children);
+}
+
+void
+lang_section_start (name, address)
+ CONST char *name;
+ etree_type * address;
+{
+ lang_address_statement_type *ad = new_stat (lang_address_statement, stat_ptr);
+
+ ad->section_name = name;
+ ad->address = address;
+}
+
+/* Set the start symbol to NAME. CMDLINE is nonzero if this is called
+ because of a -e argument on the command line, or zero if this is
+ called by ENTRY in a linker script. Command line arguments take
+ precedence. */
+
+void
+lang_add_entry (name, cmdline)
+ CONST char *name;
+ boolean cmdline;
+{
+ if (entry_symbol == NULL
+ || cmdline
+ || ! entry_from_cmdline)
+ {
+ entry_symbol = name;
+ entry_from_cmdline = cmdline;
+ }
+}
+
+void
+lang_add_target (name)
+ CONST char *name;
+{
+ lang_target_statement_type *new = new_stat (lang_target_statement,
+ stat_ptr);
+
+ new->target = name;
+
+}
+
+void
+lang_add_map (name)
+ CONST char *name;
+{
+ while (*name)
+ {
+ switch (*name)
+ {
+ case 'F':
+ map_option_f = true;
+ break;
+ }
+ name++;
+ }
+}
+
+void
+lang_add_fill (exp)
+ int exp;
+{
+ lang_fill_statement_type *new = new_stat (lang_fill_statement,
+ stat_ptr);
+
+ new->fill = exp;
+}
+
+void
+lang_add_data (type, exp)
+ int type;
+ union etree_union *exp;
+{
+
+ lang_data_statement_type *new = new_stat (lang_data_statement,
+ stat_ptr);
+
+ new->exp = exp;
+ new->type = type;
+
+}
+
+/* Create a new reloc statement. RELOC is the BFD relocation type to
+ generate. HOWTO is the corresponding howto structure (we could
+ look this up, but the caller has already done so). SECTION is the
+ section to generate a reloc against, or NAME is the name of the
+ symbol to generate a reloc against. Exactly one of SECTION and
+ NAME must be NULL. ADDEND is an expression for the addend. */
+
+void
+lang_add_reloc (reloc, howto, section, name, addend)
+ bfd_reloc_code_real_type reloc;
+ reloc_howto_type *howto;
+ asection *section;
+ const char *name;
+ union etree_union *addend;
+{
+ lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr);
+
+ p->reloc = reloc;
+ p->howto = howto;
+ p->section = section;
+ p->name = name;
+ p->addend_exp = addend;
+
+ p->addend_value = 0;
+ p->output_section = NULL;
+ p->output_vma = 0;
+}
+
+lang_assignment_statement_type *
+lang_add_assignment (exp)
+ etree_type * exp;
+{
+ lang_assignment_statement_type *new = new_stat (lang_assignment_statement,
+ stat_ptr);
+
+ new->exp = exp;
+ return new;
+}
+
+void
+lang_add_attribute (attribute)
+ enum statement_enum attribute;
+{
+ new_statement (attribute, sizeof (lang_statement_union_type), stat_ptr);
+}
+
+void
+lang_startup (name)
+ CONST char *name;
+{
+ if (startup_file != (char *) NULL)
+ {
+ einfo (_("%P%Fmultiple STARTUP files\n"));
+ }
+ first_file->filename = name;
+ first_file->local_sym_name = name;
+ first_file->real = true;
+
+ startup_file = name;
+}
+
+void
+lang_float (maybe)
+ boolean maybe;
+{
+ lang_float_flag = maybe;
+}
+
+void
+lang_leave_output_section_statement (fill, memspec, phdrs)
+ bfd_vma fill;
+ const char *memspec;
+ struct lang_output_section_phdr_list *phdrs;
+{
+ current_section->fill = fill;
+ current_section->region = lang_memory_region_lookup (memspec);
+ current_section->phdrs = phdrs;
+ stat_ptr = &statement_list;
+}
+
+/*
+ Create an absolute symbol with the given name with the value of the
+ address of first byte of the section named.
+
+ If the symbol already exists, then do nothing.
+*/
+void
+lang_abs_symbol_at_beginning_of (secname, name)
+ const char *secname;
+ const char *name;
+{
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, name, true, true, true);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+
+ if (h->type == bfd_link_hash_new
+ || h->type == bfd_link_hash_undefined)
+ {
+ asection *sec;
+
+ h->type = bfd_link_hash_defined;
+
+ sec = bfd_get_section_by_name (output_bfd, secname);
+ if (sec == (asection *) NULL)
+ h->u.def.value = 0;
+ else
+ h->u.def.value = bfd_get_section_vma (output_bfd, sec);
+
+ h->u.def.section = bfd_abs_section_ptr;
+ }
+}
+
+/*
+ Create an absolute symbol with the given name with the value of the
+ address of the first byte after the end of the section named.
+
+ If the symbol already exists, then do nothing.
+*/
+void
+lang_abs_symbol_at_end_of (secname, name)
+ const char *secname;
+ const char *name;
+{
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, name, true, true, true);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+
+ if (h->type == bfd_link_hash_new
+ || h->type == bfd_link_hash_undefined)
+ {
+ asection *sec;
+
+ h->type = bfd_link_hash_defined;
+
+ sec = bfd_get_section_by_name (output_bfd, secname);
+ if (sec == (asection *) NULL)
+ h->u.def.value = 0;
+ else
+ h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
+ + bfd_section_size (output_bfd, sec));
+
+ h->u.def.section = bfd_abs_section_ptr;
+ }
+}
+
+void
+lang_statement_append (list, element, field)
+ lang_statement_list_type * list;
+ lang_statement_union_type * element;
+ lang_statement_union_type ** field;
+{
+ *(list->tail) = element;
+ list->tail = field;
+}
+
+/* Set the output format type. -oformat overrides scripts. */
+
+void
+lang_add_output_format (format, big, little, from_script)
+ const char *format;
+ const char *big;
+ const char *little;
+ int from_script;
+{
+ if (output_target == NULL || !from_script)
+ {
+ if (command_line.endian == ENDIAN_BIG
+ && big != NULL)
+ format = big;
+ else if (command_line.endian == ENDIAN_LITTLE
+ && little != NULL)
+ format = little;
+
+ output_target = format;
+ }
+}
+
+/* Enter a group. This creates a new lang_group_statement, and sets
+ stat_ptr to build new statements within the group. */
+
+void
+lang_enter_group ()
+{
+ lang_group_statement_type *g;
+
+ g = new_stat (lang_group_statement, stat_ptr);
+ lang_list_init (&g->children);
+ stat_ptr = &g->children;
+}
+
+/* Leave a group. This just resets stat_ptr to start writing to the
+ regular list of statements again. Note that this will not work if
+ groups can occur inside anything else which can adjust stat_ptr,
+ but currently they can't. */
+
+void
+lang_leave_group ()
+{
+ stat_ptr = &statement_list;
+}
+
+/* Add a new program header. This is called for each entry in a PHDRS
+ command in a linker script. */
+
+void
+lang_new_phdr (name, type, filehdr, phdrs, at, flags)
+ const char *name;
+ etree_type *type;
+ boolean filehdr;
+ boolean phdrs;
+ etree_type *at;
+ etree_type *flags;
+{
+ struct lang_phdr *n, **pp;
+
+ n = (struct lang_phdr *) stat_alloc (sizeof (struct lang_phdr));
+ n->next = NULL;
+ n->name = name;
+ n->type = exp_get_value_int (type, 0, "program header type",
+ lang_final_phase_enum);
+ n->filehdr = filehdr;
+ n->phdrs = phdrs;
+ n->at = at;
+ n->flags = flags;
+
+ for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = n;
+}
+
+/* Record the program header information in the output BFD. FIXME: We
+ should not be calling an ELF specific function here. */
+
+static void
+lang_record_phdrs ()
+{
+ unsigned int alc;
+ asection **secs;
+ struct lang_output_section_phdr_list *last;
+ struct lang_phdr *l;
+ lang_statement_union_type *u;
+
+ alc = 10;
+ secs = (asection **) xmalloc (alc * sizeof (asection *));
+ last = NULL;
+ for (l = lang_phdr_list; l != NULL; l = l->next)
+ {
+ unsigned int c;
+ flagword flags;
+ bfd_vma at;
+
+ c = 0;
+ for (u = lang_output_section_statement.head;
+ u != NULL;
+ u = u->output_section_statement.next)
+ {
+ lang_output_section_statement_type *os;
+ struct lang_output_section_phdr_list *pl;
+
+ os = &u->output_section_statement;
+
+ pl = os->phdrs;
+ if (pl != NULL)
+ last = pl;
+ else
+ {
+ if (os->sectype == noload_section
+ || os->bfd_section == NULL
+ || (os->bfd_section->flags & SEC_ALLOC) == 0)
+ continue;
+ pl = last;
+ }
+
+ if (os->bfd_section == NULL)
+ continue;
+
+ for (; pl != NULL; pl = pl->next)
+ {
+ if (strcmp (pl->name, l->name) == 0)
+ {
+ if (c >= alc)
+ {
+ alc *= 2;
+ secs = ((asection **)
+ xrealloc (secs, alc * sizeof (asection *)));
+ }
+ secs[c] = os->bfd_section;
+ ++c;
+ pl->used = true;
+ }
+ }
+ }
+
+ if (l->flags == NULL)
+ flags = 0;
+ else
+ flags = exp_get_vma (l->flags, 0, "phdr flags",
+ lang_final_phase_enum);
+
+ if (l->at == NULL)
+ at = 0;
+ else
+ at = exp_get_vma (l->at, 0, "phdr load address",
+ lang_final_phase_enum);
+
+ if (! bfd_record_phdr (output_bfd, l->type,
+ l->flags == NULL ? false : true,
+ flags,
+ l->at == NULL ? false : true,
+ at, l->filehdr, l->phdrs, c, secs))
+ einfo (_("%F%P: bfd_record_phdr failed: %E\n"));
+ }
+
+ free (secs);
+
+ /* Make sure all the phdr assignments succeeded. */
+ for (u = lang_output_section_statement.head;
+ u != NULL;
+ u = u->output_section_statement.next)
+ {
+ struct lang_output_section_phdr_list *pl;
+
+ if (u->output_section_statement.bfd_section == NULL)
+ continue;
+
+ for (pl = u->output_section_statement.phdrs;
+ pl != NULL;
+ pl = pl->next)
+ if (! pl->used && strcmp (pl->name, "NONE") != 0)
+ einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"),
+ u->output_section_statement.name, pl->name);
+ }
+}
+
+/* Record a list of sections which may not be cross referenced. */
+
+void
+lang_add_nocrossref (l)
+ struct lang_nocrossref *l;
+{
+ struct lang_nocrossrefs *n;
+
+ n = (struct lang_nocrossrefs *) xmalloc (sizeof *n);
+ n->next = nocrossref_list;
+ n->list = l;
+ nocrossref_list = n;
+
+ /* Set notice_all so that we get informed about all symbols. */
+ link_info.notice_all = true;
+}
+
+/* Overlay handling. We handle overlays with some static variables. */
+
+/* The overlay virtual address. */
+static etree_type *overlay_vma;
+
+/* The overlay load address. */
+static etree_type *overlay_lma;
+
+/* Whether nocrossrefs is set for this overlay. */
+static int overlay_nocrossrefs;
+
+/* An expression for the maximum section size seen so far. */
+static etree_type *overlay_max;
+
+/* A list of all the sections in this overlay. */
+
+struct overlay_list
+{
+ struct overlay_list *next;
+ lang_output_section_statement_type *os;
+};
+
+static struct overlay_list *overlay_list;
+
+/* Start handling an overlay. */
+
+void
+lang_enter_overlay (vma_expr, lma_expr, nocrossrefs)
+ etree_type *vma_expr;
+ etree_type *lma_expr;
+ int nocrossrefs;
+{
+ /* The grammar should prevent nested overlays from occurring. */
+ ASSERT (overlay_vma == NULL
+ && overlay_lma == NULL
+ && overlay_list == NULL
+ && overlay_max == NULL);
+
+ overlay_vma = vma_expr;
+ overlay_lma = lma_expr;
+ overlay_nocrossrefs = nocrossrefs;
+}
+
+/* Start a section in an overlay. We handle this by calling
+ lang_enter_output_section_statement with the correct VMA and LMA. */
+
+void
+lang_enter_overlay_section (name)
+ const char *name;
+{
+ struct overlay_list *n;
+ etree_type *size;
+
+ lang_enter_output_section_statement (name, overlay_vma, normal_section,
+ 0, 0, 0, overlay_lma);
+
+ /* If this is the first section, then base the VMA and LMA of future
+ sections on this one. This will work correctly even if `.' is
+ used in the addresses. */
+ if (overlay_list == NULL)
+ {
+ overlay_vma = exp_nameop (ADDR, name);
+ overlay_lma = exp_nameop (LOADADDR, name);
+ }
+
+ /* Remember the section. */
+ n = (struct overlay_list *) xmalloc (sizeof *n);
+ n->os = current_section;
+ n->next = overlay_list;
+ overlay_list = n;
+
+ size = exp_nameop (SIZEOF, name);
+
+ /* Adjust the LMA for the next section. */
+ overlay_lma = exp_binop ('+', overlay_lma, size);
+
+ /* Arrange to work out the maximum section end address. */
+ if (overlay_max == NULL)
+ overlay_max = size;
+ else
+ overlay_max = exp_binop (MAX_K, overlay_max, size);
+}
+
+/* Finish a section in an overlay. There isn't any special to do
+ here. */
+
+void
+lang_leave_overlay_section (fill, phdrs)
+ bfd_vma fill;
+ struct lang_output_section_phdr_list *phdrs;
+{
+ const char *name;
+ char *clean, *s2;
+ const char *s1;
+ char *buf;
+
+ name = current_section->name;
+
+ lang_leave_output_section_statement (fill, "*default*", phdrs);
+
+ /* Define the magic symbols. */
+
+ clean = xmalloc (strlen (name) + 1);
+ s2 = clean;
+ for (s1 = name; *s1 != '\0'; s1++)
+ if (isalnum ((unsigned char) *s1) || *s1 == '_')
+ *s2++ = *s1;
+ *s2 = '\0';
+
+ buf = xmalloc (strlen (clean) + sizeof "__load_start_");
+ sprintf (buf, "__load_start_%s", clean);
+ lang_add_assignment (exp_assop ('=', buf,
+ exp_nameop (LOADADDR, name)));
+
+ buf = xmalloc (strlen (clean) + sizeof "__load_stop_");
+ sprintf (buf, "__load_stop_%s", clean);
+ lang_add_assignment (exp_assop ('=', buf,
+ exp_binop ('+',
+ exp_nameop (LOADADDR, name),
+ exp_nameop (SIZEOF, name))));
+
+ free (clean);
+}
+
+/* Finish an overlay. If there are any overlay wide settings, this
+ looks through all the sections in the overlay and sets them. */
+
+void
+lang_leave_overlay (fill, memspec, phdrs)
+ bfd_vma fill;
+ const char *memspec;
+ struct lang_output_section_phdr_list *phdrs;
+{
+ lang_memory_region_type *region;
+ struct overlay_list *l;
+ struct lang_nocrossref *nocrossref;
+
+ if (memspec == NULL)
+ region = NULL;
+ else
+ region = lang_memory_region_lookup (memspec);
+
+ nocrossref = NULL;
+
+ l = overlay_list;
+ while (l != NULL)
+ {
+ struct overlay_list *next;
+
+ if (fill != 0 && l->os->fill == 0)
+ l->os->fill = fill;
+ if (region != NULL && l->os->region == NULL)
+ l->os->region = region;
+ if (phdrs != NULL && l->os->phdrs == NULL)
+ l->os->phdrs = phdrs;
+
+ if (overlay_nocrossrefs)
+ {
+ struct lang_nocrossref *nc;
+
+ nc = (struct lang_nocrossref *) xmalloc (sizeof *nc);
+ nc->name = l->os->name;
+ nc->next = nocrossref;
+ nocrossref = nc;
+ }
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ if (nocrossref != NULL)
+ lang_add_nocrossref (nocrossref);
+
+ /* Update . for the end of the overlay. */
+ lang_add_assignment (exp_assop ('=', ".",
+ exp_binop ('+', overlay_vma, overlay_max)));
+
+ overlay_vma = NULL;
+ overlay_lma = NULL;
+ overlay_nocrossrefs = 0;
+ overlay_list = NULL;
+ overlay_max = NULL;
+}
+
+/* Version handling. This is only useful for ELF. */
+
+/* This global variable holds the version tree that we build. */
+
+struct bfd_elf_version_tree *lang_elf_version_info;
+
+static int
+lang_vers_match_lang_c (expr, sym)
+ struct bfd_elf_version_expr *expr;
+ const char *sym;
+{
+ if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
+ return 1;
+ return fnmatch (expr->pattern, sym, 0) == 0;
+}
+
+static int
+lang_vers_match_lang_cplusplus (expr, sym)
+ struct bfd_elf_version_expr *expr;
+ const char *sym;
+{
+ char *alt_sym;
+ int result;
+
+ if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
+ return 1;
+
+ alt_sym = cplus_demangle(sym, /* DMGL_NO_TPARAMS */ 0);
+ if (!alt_sym)
+ {
+ /* cplus_demangle (also) returns NULL when it is not a C++ symbol.
+ Should we early out false in this case? */
+ result = fnmatch (expr->pattern, sym, 0) == 0;
+ }
+ else
+ {
+ result = fnmatch (expr->pattern, alt_sym, 0) == 0;
+ free (alt_sym);
+ }
+
+ return result;
+}
+
+static int
+lang_vers_match_lang_java (expr, sym)
+ struct bfd_elf_version_expr *expr;
+ const char *sym;
+{
+ char *alt_sym;
+ int result;
+
+ if (expr->pattern[0] == '*' && expr->pattern[1] == '\0')
+ return 1;
+
+ alt_sym = cplus_demangle(sym, DMGL_JAVA);
+ if (!alt_sym)
+ {
+ /* cplus_demangle (also) returns NULL when it is not a Java symbol.
+ Should we early out false in this case? */
+ result = fnmatch (expr->pattern, sym, 0) == 0;
+ }
+ else
+ {
+ result = fnmatch (expr->pattern, alt_sym, 0) == 0;
+ free (alt_sym);
+ }
+
+ return result;
+}
+
+/* This is called for each variable name or match expression. */
+
+struct bfd_elf_version_expr *
+lang_new_vers_regex (orig, new, lang)
+ struct bfd_elf_version_expr *orig;
+ const char *new;
+ const char *lang;
+{
+ struct bfd_elf_version_expr *ret;
+
+ ret = (struct bfd_elf_version_expr *) xmalloc (sizeof *ret);
+ ret->next = orig;
+ ret->pattern = new;
+
+ if (lang == NULL || strcasecmp (lang, "C") == 0)
+ ret->match = lang_vers_match_lang_c;
+ else if (strcasecmp (lang, "C++") == 0)
+ ret->match = lang_vers_match_lang_cplusplus;
+ else if (strcasecmp (lang, "Java") == 0)
+ ret->match = lang_vers_match_lang_java;
+ else
+ {
+ einfo (_("%X%P: unknown language `%s' in version information\n"),
+ lang);
+ ret->match = lang_vers_match_lang_c;
+ }
+
+ return ret;
+}
+
+/* This is called for each set of variable names and match
+ expressions. */
+
+struct bfd_elf_version_tree *
+lang_new_vers_node (globals, locals)
+ struct bfd_elf_version_expr *globals;
+ struct bfd_elf_version_expr *locals;
+{
+ struct bfd_elf_version_tree *ret;
+
+ ret = (struct bfd_elf_version_tree *) xmalloc (sizeof *ret);
+ ret->next = NULL;
+ ret->name = NULL;
+ ret->vernum = 0;
+ ret->globals = globals;
+ ret->locals = locals;
+ ret->deps = NULL;
+ ret->name_indx = (unsigned int) -1;
+ ret->used = 0;
+ return ret;
+}
+
+/* This static variable keeps track of version indices. */
+
+static int version_index;
+
+/* This is called when we know the name and dependencies of the
+ version. */
+
+void
+lang_register_vers_node (name, version, deps)
+ const char *name;
+ struct bfd_elf_version_tree *version;
+ struct bfd_elf_version_deps *deps;
+{
+ struct bfd_elf_version_tree *t, **pp;
+ struct bfd_elf_version_expr *e1;
+
+ /* Make sure this node has a unique name. */
+ for (t = lang_elf_version_info; t != NULL; t = t->next)
+ if (strcmp (t->name, name) == 0)
+ einfo (_("%X%P: duplicate version tag `%s'\n"), name);
+
+ /* Check the global and local match names, and make sure there
+ aren't any duplicates. */
+
+ for (e1 = version->globals; e1 != NULL; e1 = e1->next)
+ {
+ for (t = lang_elf_version_info; t != NULL; t = t->next)
+ {
+ struct bfd_elf_version_expr *e2;
+
+ for (e2 = t->locals; e2 != NULL; e2 = e2->next)
+ if (strcmp (e1->pattern, e2->pattern) == 0)
+ einfo (_("%X%P: duplicate expression `%s' in version information\n"),
+ e1->pattern);
+ }
+ }
+
+ for (e1 = version->locals; e1 != NULL; e1 = e1->next)
+ {
+ for (t = lang_elf_version_info; t != NULL; t = t->next)
+ {
+ struct bfd_elf_version_expr *e2;
+
+ for (e2 = t->globals; e2 != NULL; e2 = e2->next)
+ if (strcmp (e1->pattern, e2->pattern) == 0)
+ einfo (_("%X%P: duplicate expression `%s' in version information\n"),
+ e1->pattern);
+ }
+ }
+
+ version->deps = deps;
+ version->name = name;
+ ++version_index;
+ version->vernum = version_index;
+
+ for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next)
+ ;
+ *pp = version;
+}
+
+/* This is called when we see a version dependency. */
+
+struct bfd_elf_version_deps *
+lang_add_vers_depend (list, name)
+ struct bfd_elf_version_deps *list;
+ const char *name;
+{
+ struct bfd_elf_version_deps *ret;
+ struct bfd_elf_version_tree *t;
+
+ ret = (struct bfd_elf_version_deps *) xmalloc (sizeof *ret);
+ ret->next = list;
+
+ for (t = lang_elf_version_info; t != NULL; t = t->next)
+ {
+ if (strcmp (t->name, name) == 0)
+ {
+ ret->version_needed = t;
+ return ret;
+ }
+ }
+
+ einfo (_("%X%P: unable to find version dependency `%s'\n"), name);
+
+ return ret;
+}
+
+static void
+lang_do_version_exports_section ()
+{
+ struct bfd_elf_version_expr *greg = NULL, *lreg;
+
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports");
+ char *contents, *p;
+ bfd_size_type len;
+
+ if (sec == NULL)
+ continue;
+
+ len = bfd_section_size (is->the_bfd, sec);
+ contents = xmalloc (len);
+ if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len))
+ einfo (_("%X%P: unable to read .exports section contents"), sec);
+
+ p = contents;
+ while (p < contents+len)
+ {
+ greg = lang_new_vers_regex (greg, p, NULL);
+ p = strchr (p, '\0') + 1;
+ }
+
+ /* Do not free the contents, as we used them creating the regex. */
+
+ /* Do not include this section in the link. */
+ bfd_set_section_flags (is->the_bfd, sec,
+ bfd_get_section_flags (is->the_bfd, sec) | SEC_EXCLUDE);
+ }
+
+ lreg = lang_new_vers_regex (NULL, "*", NULL);
+ lang_register_vers_node (command_line.version_exports_section,
+ lang_new_vers_node (greg, lreg), NULL);
+}
diff --git a/ld/ldlang.h b/ld/ldlang.h
new file mode 100644
index 00000000000..7bd79720228
--- /dev/null
+++ b/ld/ldlang.h
@@ -0,0 +1,490 @@
+/* ldlang.h - linker command language support
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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 1, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef LDLANG_H
+#define LDLANG_H
+
+typedef enum
+{
+ lang_input_file_is_l_enum,
+ lang_input_file_is_symbols_only_enum,
+ lang_input_file_is_marker_enum,
+ lang_input_file_is_fake_enum,
+ lang_input_file_is_search_file_enum,
+ lang_input_file_is_file_enum
+} lang_input_file_enum_type;
+
+typedef unsigned int fill_type;
+typedef struct statement_list
+{
+ union lang_statement_union *head;
+ union lang_statement_union **tail;
+} lang_statement_list_type;
+
+
+typedef struct memory_region_struct
+{
+ char *name;
+ struct memory_region_struct *next;
+ bfd_vma origin;
+ bfd_size_type length;
+ bfd_vma current;
+ bfd_size_type old_length;
+ flagword flags;
+ flagword not_flags;
+ boolean had_full_message;
+} lang_memory_region_type ;
+
+typedef struct lang_statement_header_struct
+{
+ union lang_statement_union *next;
+ enum statement_enum
+ {
+ lang_output_section_statement_enum,
+ lang_assignment_statement_enum,
+ lang_input_statement_enum,
+ lang_address_statement_enum,
+ lang_wild_statement_enum,
+ lang_input_section_enum,
+ lang_object_symbols_statement_enum,
+ lang_fill_statement_enum,
+ lang_data_statement_enum,
+ lang_reloc_statement_enum,
+ lang_target_statement_enum,
+ lang_output_statement_enum,
+ lang_padding_statement_enum,
+ lang_group_statement_enum,
+
+ lang_afile_asection_pair_statement_enum,
+ lang_constructors_statement_enum
+ } type;
+} lang_statement_header_type;
+
+
+typedef struct
+{
+ lang_statement_header_type header;
+ union etree_union *exp;
+} lang_assignment_statement_type;
+
+
+typedef struct lang_target_statement_struct
+{
+ lang_statement_header_type header;
+ const char *target;
+} lang_target_statement_type;
+
+
+typedef struct lang_output_statement_struct
+{
+ lang_statement_header_type header;
+ const char *name;
+} lang_output_statement_type;
+
+/* Section types specified in a linker script. */
+
+enum section_type
+{
+ normal_section,
+ dsect_section,
+ copy_section,
+ noload_section,
+ info_section,
+ overlay_section
+};
+
+/* This structure holds a list of program headers describing segments
+ in which this section should be placed. */
+
+struct lang_output_section_phdr_list
+{
+ struct lang_output_section_phdr_list *next;
+ const char *name;
+ boolean used;
+};
+
+typedef struct lang_output_section_statement_struct
+{
+ lang_statement_header_type header;
+ union etree_union *addr_tree;
+ lang_statement_list_type children;
+ const char *memspec;
+ union lang_statement_union *next;
+ const char *name;
+
+ boolean processed;
+
+ asection *bfd_section;
+ flagword flags; /* Or together of all input sections */
+ enum section_type sectype;
+ struct memory_region_struct *region;
+ size_t block_value;
+ fill_type fill;
+
+ int subsection_alignment; /* alignment of components */
+ int section_alignment; /* alignment of start of section */
+
+ union etree_union *load_base;
+
+ struct lang_output_section_phdr_list *phdrs;
+} lang_output_section_statement_type;
+
+
+typedef struct
+{
+ lang_statement_header_type header;
+} lang_common_statement_type;
+
+typedef struct
+{
+ lang_statement_header_type header;
+} lang_object_symbols_statement_type;
+
+typedef struct
+{
+ lang_statement_header_type header;
+ fill_type fill;
+ int size;
+ asection *output_section;
+} lang_fill_statement_type;
+
+typedef struct
+{
+ lang_statement_header_type header;
+ unsigned int type;
+ union etree_union *exp;
+ bfd_vma value;
+ asection *output_section;
+ bfd_vma output_vma;
+} lang_data_statement_type;
+
+/* Generate a reloc in the output file. */
+
+typedef struct
+{
+ lang_statement_header_type header;
+
+ /* Reloc to generate. */
+ bfd_reloc_code_real_type reloc;
+
+ /* Reloc howto structure. */
+ reloc_howto_type *howto;
+
+ /* Section to generate reloc against. Exactly one of section and
+ name must be NULL. */
+ asection *section;
+
+ /* Name of symbol to generate reloc against. Exactly one of section
+ and name must be NULL. */
+ const char *name;
+
+ /* Expression for addend. */
+ union etree_union *addend_exp;
+
+ /* Resolved addend. */
+ bfd_vma addend_value;
+
+ /* Output section where reloc should be performed. */
+ asection *output_section;
+
+ /* VMA within output section. */
+ bfd_vma output_vma;
+} lang_reloc_statement_type;
+
+typedef struct lang_input_statement_struct
+{
+ lang_statement_header_type header;
+ /* Name of this file. */
+ const char *filename;
+ /* Name to use for the symbol giving address of text start */
+ /* Usually the same as filename, but for a file spec'd with -l
+ this is the -l switch itself rather than the filename. */
+ const char *local_sym_name;
+
+ bfd *the_bfd;
+
+ boolean closed;
+ file_ptr passive_position;
+
+ /* Symbol table of the file. */
+ asymbol **asymbols;
+ unsigned int symbol_count;
+
+ /* Point to the next file - whatever it is, wanders up and down
+ archives */
+
+ union lang_statement_union *next;
+ /* Point to the next file, but skips archive contents */
+ union lang_statement_union *next_real_file;
+
+ boolean is_archive;
+
+ /* 1 means search a set of directories for this file. */
+ boolean search_dirs_flag;
+
+ /* 1 means this is base file of incremental load.
+ Do not load this file's text or data.
+ Also default text_start to after this file's bss. */
+
+ boolean just_syms_flag;
+
+ /* Whether to search for this entry as a dynamic archive. */
+ boolean dynamic;
+
+ /* Whether to include the entire contents of an archive. */
+ boolean whole_archive;
+
+ boolean loaded;
+
+ /* unsigned int globals_in_this_file;*/
+ const char *target;
+ boolean real;
+} lang_input_statement_type;
+
+typedef struct
+{
+ lang_statement_header_type header;
+ asection *section;
+ lang_input_statement_type *ifile;
+
+} lang_input_section_type;
+
+
+typedef struct
+{
+ lang_statement_header_type header;
+ asection *section;
+ union lang_statement_union *file;
+} lang_afile_asection_pair_statement_type;
+
+typedef struct lang_wild_statement_struct
+{
+ lang_statement_header_type header;
+ const char *section_name;
+ boolean sections_sorted;
+ const char *filename;
+ boolean filenames_sorted;
+ boolean keep_sections;
+ const char *exclude_filename;
+ lang_statement_list_type children;
+} lang_wild_statement_type;
+
+typedef struct lang_address_statement_struct
+{
+ lang_statement_header_type header;
+ const char *section_name;
+ union etree_union *address;
+} lang_address_statement_type;
+
+typedef struct
+{
+ lang_statement_header_type header;
+ bfd_vma output_offset;
+ size_t size;
+ asection *output_section;
+ fill_type fill;
+} lang_padding_statement_type;
+
+/* A group statement collects a set of libraries together. The
+ libraries are searched multiple times, until no new undefined
+ symbols are found. The effect is to search a group of libraries as
+ though they were a single library. */
+
+typedef struct
+{
+ lang_statement_header_type header;
+ lang_statement_list_type children;
+} lang_group_statement_type;
+
+typedef union lang_statement_union
+{
+ lang_statement_header_type header;
+ union lang_statement_union *next;
+ lang_wild_statement_type wild_statement;
+ lang_data_statement_type data_statement;
+ lang_reloc_statement_type reloc_statement;
+ lang_address_statement_type address_statement;
+ lang_output_section_statement_type output_section_statement;
+ lang_afile_asection_pair_statement_type afile_asection_pair_statement;
+ lang_assignment_statement_type assignment_statement;
+ lang_input_statement_type input_statement;
+ lang_target_statement_type target_statement;
+ lang_output_statement_type output_statement;
+ lang_input_section_type input_section;
+ lang_common_statement_type common_statement;
+ lang_object_symbols_statement_type object_symbols_statement;
+ lang_fill_statement_type fill_statement;
+ lang_padding_statement_type padding_statement;
+ lang_group_statement_type group_statement;
+} lang_statement_union_type;
+
+/* This structure holds information about a program header, from the
+ PHDRS command in the linker script. */
+
+struct lang_phdr
+{
+ struct lang_phdr *next;
+ const char *name;
+ unsigned long type;
+ boolean filehdr;
+ boolean phdrs;
+ etree_type *at;
+ etree_type *flags;
+};
+
+/* This structure is used to hold a list of sections which may not
+ cross reference each other. */
+
+struct lang_nocrossref
+{
+ struct lang_nocrossref *next;
+ const char *name;
+};
+
+/* The list of nocrossref lists. */
+
+struct lang_nocrossrefs
+{
+ struct lang_nocrossrefs *next;
+ struct lang_nocrossref *list;
+};
+
+extern struct lang_nocrossrefs *nocrossref_list;
+
+extern lang_output_section_statement_type *abs_output_section;
+extern boolean lang_has_input_file;
+extern etree_type *base;
+extern lang_statement_list_type *stat_ptr;
+extern boolean delete_output_file_on_failure;
+
+extern const char *entry_symbol;
+extern boolean entry_from_cmdline;
+
+extern void lang_init PARAMS ((void));
+extern struct memory_region_struct *lang_memory_region_lookup
+ PARAMS ((const char *const));
+extern struct memory_region_struct *lang_memory_region_default
+ PARAMS ((asection *));
+extern void lang_map PARAMS ((void));
+extern void lang_set_flags PARAMS ((lang_memory_region_type *, const char *));
+extern void lang_add_output PARAMS ((const char *, int from_script));
+extern void lang_enter_output_section_statement
+ PARAMS ((const char *output_section_statement_name,
+ etree_type * address_exp,
+ enum section_type sectype,
+ bfd_vma block_value,
+ etree_type *align,
+ etree_type *subalign,
+ etree_type *));
+extern void lang_final PARAMS ((void));
+extern void lang_process PARAMS ((void));
+extern void lang_section_start PARAMS ((const char *, union etree_union *));
+extern void lang_add_entry PARAMS ((const char *, boolean));
+extern void lang_add_target PARAMS ((const char *));
+extern void lang_add_wild
+ PARAMS ((const char *, boolean, const char *, boolean, boolean, const char *));
+extern void lang_add_map PARAMS ((const char *));
+extern void lang_add_fill PARAMS ((int));
+extern lang_assignment_statement_type * lang_add_assignment PARAMS ((union etree_union *));
+extern void lang_add_attribute PARAMS ((enum statement_enum));
+extern void lang_startup PARAMS ((const char *));
+extern void lang_float PARAMS ((enum bfd_boolean));
+extern void lang_leave_output_section_statement
+ PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *));
+extern void lang_abs_symbol_at_end_of PARAMS ((const char *, const char *));
+extern void lang_abs_symbol_at_beginning_of PARAMS ((const char *,
+ const char *));
+extern void lang_statement_append PARAMS ((struct statement_list *,
+ union lang_statement_union *,
+ union lang_statement_union **));
+extern void lang_for_each_input_file
+ PARAMS ((void (*dothis) (lang_input_statement_type *)));
+extern void lang_for_each_file
+ PARAMS ((void (*dothis) (lang_input_statement_type *)));
+extern bfd_vma lang_do_assignments
+ PARAMS ((lang_statement_union_type * s,
+ lang_output_section_statement_type *output_section_statement,
+ fill_type fill,
+ bfd_vma dot));
+
+#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \
+ extern lang_statement_list_type file_chain; \
+ lang_input_statement_type *statement; \
+ for (statement = (lang_input_statement_type *)file_chain.head;\
+ statement != (lang_input_statement_type *)NULL; \
+ statement = (lang_input_statement_type *)statement->next)\
+
+extern void lang_process PARAMS ((void));
+extern void ldlang_add_file PARAMS ((lang_input_statement_type *));
+extern lang_output_section_statement_type *lang_output_section_find
+ PARAMS ((const char * const));
+extern lang_input_statement_type *lang_add_input_file
+ PARAMS ((const char *name, lang_input_file_enum_type file_type,
+ const char *target));
+extern void lang_add_keepsyms_file PARAMS ((const char *filename));
+extern lang_output_section_statement_type *
+ lang_output_section_statement_lookup PARAMS ((const char * const name));
+extern void ldlang_add_undef PARAMS ((const char *const name));
+extern void lang_add_output_format PARAMS ((const char *, const char *,
+ const char *, int from_script));
+extern void lang_list_init PARAMS ((lang_statement_list_type*));
+extern void lang_add_data PARAMS ((int type, union etree_union *));
+extern void lang_add_reloc
+ PARAMS ((bfd_reloc_code_real_type reloc, reloc_howto_type *howto,
+ asection *section, const char *name, union etree_union *addend));
+extern void lang_for_each_statement
+ PARAMS ((void (*func) (lang_statement_union_type *)));
+extern PTR stat_alloc PARAMS ((size_t size));
+extern void dprint_statement PARAMS ((lang_statement_union_type *, int));
+extern bfd_vma lang_size_sections
+ PARAMS ((lang_statement_union_type *s,
+ lang_output_section_statement_type *output_section_statement,
+ lang_statement_union_type **prev, fill_type fill,
+ bfd_vma dot, boolean relax));
+extern void lang_enter_group PARAMS ((void));
+extern void lang_leave_group PARAMS ((void));
+extern void wild_doit
+ PARAMS ((lang_statement_list_type *ptr, asection *section,
+ lang_output_section_statement_type *output,
+ lang_input_statement_type *file));
+extern void lang_new_phdr
+ PARAMS ((const char *, etree_type *, boolean, boolean, etree_type *,
+ etree_type *));
+extern void lang_add_nocrossref PARAMS ((struct lang_nocrossref *));
+extern void lang_enter_overlay PARAMS ((etree_type *, etree_type *, int));
+extern void lang_enter_overlay_section PARAMS ((const char *));
+extern void lang_leave_overlay_section
+ PARAMS ((bfd_vma, struct lang_output_section_phdr_list *));
+extern void lang_leave_overlay
+ PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *));
+
+extern struct bfd_elf_version_tree *lang_elf_version_info;
+
+extern struct bfd_elf_version_expr *lang_new_vers_regex
+ PARAMS ((struct bfd_elf_version_expr *, const char *, const char *));
+extern struct bfd_elf_version_tree *lang_new_vers_node
+ PARAMS ((struct bfd_elf_version_expr *, struct bfd_elf_version_expr *));
+extern struct bfd_elf_version_deps *lang_add_vers_depend
+ PARAMS ((struct bfd_elf_version_deps *, const char *));
+extern void lang_register_vers_node
+ PARAMS ((const char *, struct bfd_elf_version_tree *,
+ struct bfd_elf_version_deps *));
+
+#endif
diff --git a/ld/ldlex.h b/ld/ldlex.h
new file mode 100644
index 00000000000..53444cacad7
--- /dev/null
+++ b/ld/ldlex.h
@@ -0,0 +1,62 @@
+/* ldlex.h -
+ Copyright 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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 1, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef LDLEX_H
+#define LDLEX_H
+
+#include <stdio.h>
+
+/* The initial parser states. */
+typedef enum input_enum {
+ input_selected, /* We've set the initial state. */
+ input_script,
+ input_mri_script,
+ input_version_script,
+ input_defsym
+} input_type;
+
+extern input_type parser_input;
+
+extern unsigned int lineno;
+extern const char *lex_string;
+
+/* In ldlex.l. */
+extern int yylex PARAMS ((void));
+extern void lex_push_file PARAMS ((FILE *, const char *));
+extern void lex_redirect PARAMS ((const char *));
+extern void ldlex_script PARAMS ((void));
+extern void ldlex_mri_script PARAMS ((void));
+extern void ldlex_version_script PARAMS ((void));
+extern void ldlex_version_file PARAMS ((void));
+extern void ldlex_defsym PARAMS ((void));
+extern void ldlex_expression PARAMS ((void));
+extern void ldlex_both PARAMS ((void));
+extern void ldlex_command PARAMS ((void));
+extern void ldlex_popstate PARAMS ((void));
+
+/* In lexsup.c. */
+extern int lex_input PARAMS ((void));
+extern void lex_unput PARAMS ((int));
+#ifndef yywrap
+extern int yywrap PARAMS ((void));
+#endif
+extern void parse_args PARAMS ((int, char **));
+
+#endif
diff --git a/ld/ldlex.l b/ld/ldlex.l
new file mode 100644
index 00000000000..2eef80f1fe2
--- /dev/null
+++ b/ld/ldlex.l
@@ -0,0 +1,662 @@
+%{
+
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/*
+This was written by steve chamberlain
+ sac@cygnus.com
+*/
+
+
+#include <ansidecl.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef MPW
+/* Prevent enum redefinition problems. */
+#define TRUE_FALSE_ALREADY_DEFINED
+#endif /* MPW */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "ld.h"
+#include "ldgram.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldfile.h"
+#include "ldlex.h"
+#include "ldmain.h"
+
+/* The type of top-level parser input.
+ yylex and yyparse (indirectly) both check this. */
+input_type parser_input;
+
+/* Line number in the current input file.
+ (FIXME Actually, it doesn't appear to get reset for each file?) */
+unsigned int lineno = 1;
+
+/* The string we are currently lexing, or NULL if we are reading a
+ file. */
+const char *lex_string = NULL;
+
+/* Support for flex reading from more than one input file (stream).
+ `include_stack' is flex's input state for each open file;
+ `file_name_stack' is the file names. `lineno_stack' is the current
+ line numbers.
+
+ If `include_stack_ptr' is 0, we haven't started reading anything yet.
+ Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) yy_input(buf, &result, max_size)
+
+#define MAX_INCLUDE_DEPTH 10
+static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+static const char *file_name_stack[MAX_INCLUDE_DEPTH];
+static unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
+static unsigned int include_stack_ptr = 0;
+static int vers_node_nesting = 0;
+
+static YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string,
+ size_t size));
+static void yy_input PARAMS ((char *, int *result, int max_size));
+
+static void comment PARAMS ((void));
+static void lex_warn_invalid PARAMS ((char *where, char *what));
+
+/* STATES
+ EXPRESSION definitely in an expression
+ SCRIPT definitely in a script
+ BOTH either EXPRESSION or SCRIPT
+ DEFSYMEXP in an argument to -defsym
+ MRI in an MRI script
+ VERS_START starting a Sun style mapfile
+ VERS_SCRIPT a Sun style mapfile
+ VERS_NODE a node within a Sun style mapfile
+*/
+#define RTOKEN(x) { yylval.token = x; return x; }
+
+/* Some versions of flex want this. */
+#ifndef yywrap
+int yywrap () { return 1; }
+#endif
+%}
+
+%a 4000
+%o 5000
+
+CMDFILENAMECHAR [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\-\~]
+CMDFILENAMECHAR1 [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\~]
+FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~]
+SYMBOLCHARN [_a-zA-Z\/\.\\\$\_\~0-9]
+FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~]
+WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*]
+WHITE [ \t\n\r]+
+
+NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
+
+V_TAG [.$_a-zA-Z][._a-zA-Z0-9]*
+V_IDENTIFIER [*?.$_a-zA-Z][*?.$_a-zA-Z0-9]*
+
+%s SCRIPT
+%s EXPRESSION
+%s BOTH
+%s DEFSYMEXP
+%s MRI
+%s VERS_START
+%s VERS_SCRIPT
+%s VERS_NODE
+%%
+
+ if (parser_input != input_selected)
+ {
+ /* The first token of the input determines the initial parser state. */
+ input_type t = parser_input;
+ parser_input = input_selected;
+ switch (t)
+ {
+ case input_script: return INPUT_SCRIPT; break;
+ case input_mri_script: return INPUT_MRI_SCRIPT; break;
+ case input_version_script: return INPUT_VERSION_SCRIPT; break;
+ case input_defsym: return INPUT_DEFSYM; break;
+ default: abort ();
+ }
+ }
+
+<BOTH,SCRIPT,EXPRESSION>"/*" { comment(); }
+
+
+<DEFSYMEXP>"-" { RTOKEN('-');}
+<DEFSYMEXP>"+" { RTOKEN('+');}
+<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}* { yylval.name = buystring(yytext); return NAME; }
+<DEFSYMEXP>"=" { RTOKEN('='); }
+
+<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
+ yylval.integer = bfd_scan_vma (yytext+1, 0,16);
+ return INT;
+ }
+
+<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) {
+ int ibase ;
+ switch (yytext[yyleng-1]) {
+ case 'X':
+ case 'x':
+ case 'H':
+ case 'h':
+ ibase = 16;
+ break;
+ case 'O':
+ case 'o':
+ ibase = 8;
+ break;
+ case 'B':
+ case 'b':
+ ibase = 2;
+ break;
+ default:
+ ibase = 10;
+ }
+ yylval.integer = bfd_scan_vma (yytext, 0,
+ ibase);
+ return INT;
+ }
+<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>((("$"|"0x")([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? {
+ char *s = yytext;
+
+ if (*s == '$')
+ ++s;
+ yylval.integer = bfd_scan_vma (s, 0, 0);
+ if (yytext[yyleng-1] == 'M'
+ || yytext[yyleng-1] == 'm')
+ yylval.integer *= 1024 * 1024;
+ if (yytext[yyleng-1] == 'K'
+ || yytext[yyleng-1]=='k')
+ yylval.integer *= 1024;
+ return INT;
+ }
+<BOTH,SCRIPT,EXPRESSION,MRI>"]" { RTOKEN(']');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"[" { RTOKEN('[');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<<=" { RTOKEN(LSHIFTEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">>=" { RTOKEN(RSHIFTEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"||" { RTOKEN(OROR);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"==" { RTOKEN(EQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"!=" { RTOKEN(NE);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">=" { RTOKEN(GE);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<=" { RTOKEN(LE);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<<" { RTOKEN(LSHIFT);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">>" { RTOKEN(RSHIFT);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"+=" { RTOKEN(PLUSEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"-=" { RTOKEN(MINUSEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"*=" { RTOKEN(MULTEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"/=" { RTOKEN(DIVEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"&=" { RTOKEN(ANDEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"|=" { RTOKEN(OREQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"&&" { RTOKEN(ANDAND);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"," { RTOKEN(',');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"&" { RTOKEN('&');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"|" { RTOKEN('|');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"!" { RTOKEN('!');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"?" { RTOKEN('?');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"*" { RTOKEN('*');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"+" { RTOKEN('+');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"-" { RTOKEN('-');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"/" { RTOKEN('/');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"%" { RTOKEN('%');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<" { RTOKEN('<');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"=" { RTOKEN('=');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"}" { RTOKEN('}') ; }
+<BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); }
+<BOTH,SCRIPT,EXPRESSION,MRI>")" { RTOKEN(')');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"(" { RTOKEN('(');}
+<BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
+<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
+<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
+<BOTH,SCRIPT>"ORIGIN" { RTOKEN(ORIGIN);}
+<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
+<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
+<EXPRESSION,BOTH,SCRIPT>"BIND" { RTOKEN(BIND);}
+<BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);}
+<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);}
+<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
+<EXPRESSION,BOTH,SCRIPT>"LOADADDR" { RTOKEN(LOADADDR);}
+<EXPRESSION,BOTH>"MAX" { RTOKEN(MAX_K); }
+<EXPRESSION,BOTH>"MIN" { RTOKEN(MIN_K); }
+<EXPRESSION,BOTH>"ASSERT" { RTOKEN(ASSERT_K); }
+<BOTH,SCRIPT>"ENTRY" { RTOKEN(ENTRY);}
+<BOTH,SCRIPT,MRI>"EXTERN" { RTOKEN(EXTERN);}
+<EXPRESSION,BOTH,SCRIPT>"NEXT" { RTOKEN(NEXT);}
+<EXPRESSION,BOTH,SCRIPT>"sizeof_headers" { RTOKEN(SIZEOF_HEADERS);}
+<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);}
+<BOTH,SCRIPT>"MAP" { RTOKEN(MAP);}
+<EXPRESSION,BOTH,SCRIPT>"SIZEOF" { RTOKEN(SIZEOF);}
+<BOTH,SCRIPT>"TARGET" { RTOKEN(TARGET_K);}
+<BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);}
+<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
+<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
+<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);}
+<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
+<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
+<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
+<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
+<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
+<BOTH,SCRIPT>"FILL" { RTOKEN(FILL);}
+<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);}
+<BOTH,SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);}
+<BOTH,SCRIPT>"OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);}
+<BOTH,SCRIPT>"HLL" { RTOKEN(HLL);}
+<BOTH,SCRIPT>"SYSLIB" { RTOKEN(SYSLIB);}
+<BOTH,SCRIPT>"FLOAT" { RTOKEN(FLOAT);}
+<BOTH,SCRIPT>"QUAD" { RTOKEN( QUAD);}
+<BOTH,SCRIPT>"SQUAD" { RTOKEN( SQUAD);}
+<BOTH,SCRIPT>"LONG" { RTOKEN( LONG);}
+<BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);}
+<BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);}
+<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);}
+<EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS" { RTOKEN(NOCROSSREFS);}
+<BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY); }
+<BOTH,SCRIPT>"SORT" { RTOKEN(SORT); }
+<EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);}
+<EXPRESSION,BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);}
+<EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
+<EXPRESSION,BOTH,SCRIPT>"INFO" { RTOKEN(INFO);}
+<EXPRESSION,BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);}
+<BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);}
+<BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);}
+<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}
+<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
+<BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);}
+<BOTH,SCRIPT>"PHDRS" { RTOKEN (PHDRS); }
+<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);}
+<EXPRESSION,BOTH,SCRIPT>"PROVIDE" { RTOKEN(PROVIDE); }
+<EXPRESSION,BOTH,SCRIPT>"KEEP" { RTOKEN(KEEP); }
+<EXPRESSION,BOTH,SCRIPT>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); }
+<MRI>"#".*\n? { ++ lineno; }
+<MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); }
+<MRI>"*".* { /* Mri comment line */ }
+<MRI>";".* { /* Mri comment line */ }
+<MRI>"END" { RTOKEN(ENDWORD); }
+<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
+<MRI>"ALIGN" { RTOKEN(ALIGN_K);}
+<MRI>"CHIP" { RTOKEN(CHIP); }
+<MRI>"BASE" { RTOKEN(BASE); }
+<MRI>"ALIAS" { RTOKEN(ALIAS); }
+<MRI>"TRUNCATE" { RTOKEN(TRUNCATE); }
+<MRI>"LOAD" { RTOKEN(LOAD); }
+<MRI>"PUBLIC" { RTOKEN(PUBLIC); }
+<MRI>"ORDER" { RTOKEN(ORDER); }
+<MRI>"NAME" { RTOKEN(NAMEWORD); }
+<MRI>"FORMAT" { RTOKEN(FORMAT); }
+<MRI>"CASE" { RTOKEN(CASE); }
+<MRI>"START" { RTOKEN(START); }
+<MRI>"LIST".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
+<MRI>"SECT" { RTOKEN(SECT); }
+<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); }
+<MRI>"end" { RTOKEN(ENDWORD); }
+<MRI>"alignmod" { RTOKEN(ALIGNMOD);}
+<MRI>"align" { RTOKEN(ALIGN_K);}
+<MRI>"chip" { RTOKEN(CHIP); }
+<MRI>"base" { RTOKEN(BASE); }
+<MRI>"alias" { RTOKEN(ALIAS); }
+<MRI>"truncate" { RTOKEN(TRUNCATE); }
+<MRI>"load" { RTOKEN(LOAD); }
+<MRI>"public" { RTOKEN(PUBLIC); }
+<MRI>"order" { RTOKEN(ORDER); }
+<MRI>"name" { RTOKEN(NAMEWORD); }
+<MRI>"format" { RTOKEN(FORMAT); }
+<MRI>"case" { RTOKEN(CASE); }
+<MRI>"extern" { RTOKEN(EXTERN); }
+<MRI>"start" { RTOKEN(START); }
+<MRI>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
+<MRI>"sect" { RTOKEN(SECT); }
+<EXPRESSION,BOTH,SCRIPT,MRI>"absolute" { RTOKEN(ABSOLUTE); }
+
+<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* {
+/* Filename without commas, needed to parse mri stuff */
+ yylval.name = buystring(yytext);
+ return NAME;
+ }
+
+
+<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* {
+ yylval.name = buystring(yytext);
+ return NAME;
+ }
+<BOTH,EXPRESSION>"-l"{FILENAMECHAR}+ {
+ yylval.name = buystring (yytext + 2);
+ return LNAME;
+ }
+<SCRIPT>{WILDCHAR}* {
+ /* Annoyingly, this pattern can match comments, and we have
+ longest match issues to consider. So if the first two
+ characters are a comment opening, put the input back and
+ try again. */
+ if (yytext[0] == '/' && yytext[1] == '*')
+ {
+ yyless(2);
+ comment ();
+ }
+ else
+ {
+ yylval.name = buystring(yytext);
+ return NAME;
+ }
+ }
+
+<EXPRESSION,BOTH,SCRIPT,VERS_NODE>"\""[^\"]*"\"" {
+ /* No matter the state, quotes
+ give what's inside */
+ yylval.name = buystring(yytext+1);
+ yylval.name[yyleng-2] = 0;
+ return NAME;
+ }
+<BOTH,SCRIPT,EXPRESSION>"\n" { lineno++;}
+<MRI,BOTH,SCRIPT,EXPRESSION>[ \t\r]+ { }
+
+<VERS_NODE,VERS_SCRIPT>[:,;] { return *yytext; }
+
+<VERS_NODE>global { RTOKEN(GLOBAL); }
+
+<VERS_NODE>local { RTOKEN(LOCAL); }
+
+<VERS_NODE>extern { RTOKEN(EXTERN); }
+
+<VERS_NODE>{V_IDENTIFIER} { yylval.name = buystring (yytext);
+ return VERS_IDENTIFIER; }
+
+<VERS_SCRIPT>{V_TAG} { yylval.name = buystring (yytext);
+ return VERS_TAG; }
+
+<VERS_START>"{" { BEGIN(VERS_SCRIPT); return *yytext; }
+
+<VERS_SCRIPT>"{" { BEGIN(VERS_NODE);
+ vers_node_nesting = 0;
+ return *yytext;
+ }
+<VERS_SCRIPT>"}" { return *yytext; }
+<VERS_NODE>"{" { vers_node_nesting++; return *yytext; }
+<VERS_NODE>"}" { if (--vers_node_nesting < 0)
+ BEGIN(VERS_SCRIPT);
+ return *yytext;
+ }
+
+<VERS_START,VERS_NODE,VERS_SCRIPT>[\n] { lineno++; }
+
+<VERS_START,VERS_NODE,VERS_SCRIPT>#.* { /* Eat up comments */ }
+
+<VERS_START,VERS_NODE,VERS_SCRIPT>[ \t\r]+ { /* Eat up whitespace */ }
+
+<<EOF>> {
+ include_stack_ptr--;
+
+ if (include_stack_ptr == 0)
+ {
+ yyterminate();
+ }
+ else
+ {
+ yy_switch_to_buffer(include_stack[include_stack_ptr]);
+
+ }
+ BEGIN(SCRIPT);
+ ldfile_input_filename = file_name_stack[include_stack_ptr - 1];
+ lineno = lineno_stack[include_stack_ptr - 1];
+
+ return END;
+}
+
+<SCRIPT,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>. lex_warn_invalid(" in script", yytext);
+<EXPRESSION,DEFSYMEXP,BOTH>. lex_warn_invalid(" in expression", yytext);
+
+%%
+
+
+/* Switch flex to reading script file NAME, open on FILE,
+ saving the current input info on the include stack. */
+
+void
+lex_push_file (file, name)
+ FILE *file;
+ const char *name;
+{
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ {
+ einfo("%F:includes nested too deeply\n");
+ }
+ file_name_stack[include_stack_ptr] = name;
+ lineno_stack[include_stack_ptr] = 1;
+ include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
+
+ include_stack_ptr++;
+ yyin = file;
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ BEGIN (SCRIPT);
+}
+
+/* Return a newly created flex input buffer containing STRING,
+ which is SIZE bytes long. */
+
+static YY_BUFFER_STATE
+yy_create_string_buffer (string, size)
+ CONST char *string;
+ size_t size;
+{
+ YY_BUFFER_STATE b;
+
+ /* Calls to m-alloc get turned by sed into xm-alloc. */
+ b = (YY_BUFFER_STATE) malloc (sizeof (struct yy_buffer_state));
+ b->yy_input_file = 0;
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ we need to put in 2 end-of-buffer characters. */
+ b->yy_ch_buf = (char *) malloc ((unsigned) (b->yy_buf_size + 3));
+
+ b->yy_ch_buf[0] = '\n';
+ strcpy (b->yy_ch_buf+1, string);
+ b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR;
+ b->yy_n_chars = size+1;
+ b->yy_buf_pos = &b->yy_ch_buf[1];
+
+ /* flex 2.4.7 changed the interface. FIXME: We should not be using
+ a flex internal interface in the first place! */
+#ifdef YY_BUFFER_NEW
+ b->yy_buffer_status = YY_BUFFER_NEW;
+#else
+ b->yy_eof_status = EOF_NOT_SEEN;
+#endif
+
+ return b;
+}
+
+/* Switch flex to reading from STRING, saving the current input info
+ on the include stack. */
+
+void
+lex_redirect (string)
+ CONST char *string;
+{
+ YY_BUFFER_STATE tmp;
+
+ yy_init = 0;
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ {
+ einfo("%F: macros nested too deeply\n");
+ }
+ file_name_stack[include_stack_ptr] = "redirect";
+ lineno_stack[include_stack_ptr] = 0;
+ include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
+ include_stack_ptr++;
+ tmp = yy_create_string_buffer (string, strlen (string));
+ yy_switch_to_buffer (tmp);
+ BEGIN (SCRIPT);
+}
+
+/* Functions to switch to a different flex start condition,
+ saving the current start condition on `state_stack'. */
+
+static int state_stack[MAX_INCLUDE_DEPTH * 2];
+static int *state_stack_p = state_stack;
+
+void
+ldlex_script ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (SCRIPT);
+}
+
+void
+ldlex_mri_script ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (MRI);
+}
+
+void
+ldlex_version_script ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (VERS_START);
+}
+
+void
+ldlex_version_file ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (VERS_SCRIPT);
+}
+
+void
+ldlex_defsym ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (DEFSYMEXP);
+}
+
+void
+ldlex_expression ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (EXPRESSION);
+}
+
+void
+ldlex_both ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (BOTH);
+}
+
+void
+ldlex_popstate ()
+{
+ yy_start = *(--state_stack_p);
+}
+
+
+/* Place up to MAX_SIZE characters in BUF and return in *RESULT
+ either the number of characters read, or 0 to indicate EOF. */
+
+static void
+yy_input (buf, result, max_size)
+ char *buf;
+ int *result;
+ int max_size;
+{
+ *result = 0;
+ if (yy_current_buffer->yy_input_file)
+ {
+ if (yyin)
+ {
+ *result = read (fileno (yyin), (char *) buf, max_size);
+ if (*result < 0)
+ einfo ("%F%P: read in flex scanner failed\n");
+ }
+ }
+}
+
+/* Eat the rest of a C-style comment. */
+
+static void
+comment ()
+{
+ int c;
+
+ while (1)
+ {
+ c = input();
+ while (c != '*' && c != EOF)
+ {
+ if (c == '\n')
+ lineno++;
+ c = input();
+ }
+
+ if (c == '*')
+ {
+ c = input();
+ while (c == '*')
+ c = input();
+ if (c == '/')
+ break; /* found the end */
+ }
+
+ if (c == '\n')
+ lineno++;
+
+ if (c == EOF)
+ {
+ einfo( "%F%P: EOF in comment\n");
+ break;
+ }
+ }
+}
+
+/* Warn the user about a garbage character WHAT in the input
+ in context WHERE. */
+
+static void
+lex_warn_invalid (where, what)
+ char *where, *what;
+{
+ char buf[5];
+
+ /* If we have found an input file whose format we do not recognize,
+ and we are therefore treating it as a linker script, and we find
+ an invalid character, then most likely this is a real object file
+ of some different format. Treat it as such. */
+ if (ldfile_assumed_script)
+ {
+ bfd_set_error (bfd_error_file_not_recognized);
+ einfo ("%F%s: file not recognized: %E\n", ldfile_input_filename);
+ }
+
+ if (! isprint ((unsigned char) *what))
+ {
+ sprintf (buf, "\\%03o", (unsigned int) *what);
+ what = buf;
+ }
+
+ einfo ("%P:%S: ignoring invalid character `%s'%s\n", what, where);
+}
diff --git a/ld/ldmain.c b/ld/ldmain.c
new file mode 100644
index 00000000000..1e710dbb650
--- /dev/null
+++ b/ld/ldmain.c
@@ -0,0 +1,1300 @@
+/* Main program of GNU linker.
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include <stdio.h>
+#include <ctype.h>
+#include "libiberty.h"
+#include "progress.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldmisc.h"
+#include "ldwrite.h"
+#include "ldgram.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldemul.h"
+#include "ldlex.h"
+#include "ldfile.h"
+#include "ldctor.h"
+
+/* Somewhere above, sys/stat.h got included . . . . */
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#include <string.h>
+
+#ifdef HAVE_SBRK
+#ifdef NEED_DECLARATION_SBRK
+extern PTR sbrk ();
+#endif
+#endif
+
+static char *get_emulation PARAMS ((int, char **));
+static void set_scripts_dir PARAMS ((void));
+
+/* EXPORTS */
+
+char *default_target;
+const char *output_filename = "a.out";
+
+/* Name this program was invoked by. */
+char *program_name;
+
+/* The file that we're creating */
+bfd *output_bfd = 0;
+
+/* Set by -G argument, for MIPS ECOFF target. */
+int g_switch_value = 8;
+
+/* Nonzero means print names of input files as processed. */
+boolean trace_files;
+
+/* Nonzero means same, but note open failures, too. */
+boolean trace_file_tries;
+
+/* Nonzero means version number was printed, so exit successfully
+ instead of complaining if no input files are given. */
+boolean version_printed;
+
+/* Nonzero means link in every member of an archive. */
+boolean whole_archive;
+
+/* True if we should demangle symbol names. */
+boolean demangling;
+
+args_type command_line;
+
+ld_config_type config;
+
+static void remove_output PARAMS ((void));
+static boolean check_for_scripts_dir PARAMS ((char *dir));
+static boolean add_archive_element PARAMS ((struct bfd_link_info *, bfd *,
+ const char *));
+static boolean multiple_definition PARAMS ((struct bfd_link_info *,
+ const char *,
+ bfd *, asection *, bfd_vma,
+ bfd *, asection *, bfd_vma));
+static boolean multiple_common PARAMS ((struct bfd_link_info *,
+ const char *, bfd *,
+ enum bfd_link_hash_type, bfd_vma,
+ bfd *, enum bfd_link_hash_type,
+ bfd_vma));
+static boolean add_to_set PARAMS ((struct bfd_link_info *,
+ struct bfd_link_hash_entry *,
+ bfd_reloc_code_real_type,
+ bfd *, asection *, bfd_vma));
+static boolean constructor_callback PARAMS ((struct bfd_link_info *,
+ boolean constructor,
+ const char *name,
+ bfd *, asection *, bfd_vma));
+static boolean warning_callback PARAMS ((struct bfd_link_info *,
+ const char *, const char *, bfd *,
+ asection *, bfd_vma));
+static void warning_find_reloc PARAMS ((bfd *, asection *, PTR));
+static boolean undefined_symbol PARAMS ((struct bfd_link_info *,
+ const char *, bfd *,
+ asection *, bfd_vma));
+static boolean reloc_overflow PARAMS ((struct bfd_link_info *, const char *,
+ const char *, bfd_vma,
+ bfd *, asection *, bfd_vma));
+static boolean reloc_dangerous PARAMS ((struct bfd_link_info *, const char *,
+ bfd *, asection *, bfd_vma));
+static boolean unattached_reloc PARAMS ((struct bfd_link_info *,
+ const char *, bfd *, asection *,
+ bfd_vma));
+static boolean notice PARAMS ((struct bfd_link_info *, const char *,
+ bfd *, asection *, bfd_vma));
+
+static struct bfd_link_callbacks link_callbacks =
+{
+ add_archive_element,
+ multiple_definition,
+ multiple_common,
+ add_to_set,
+ constructor_callback,
+ warning_callback,
+ undefined_symbol,
+ reloc_overflow,
+ reloc_dangerous,
+ unattached_reloc,
+ notice
+};
+
+struct bfd_link_info link_info;
+
+static void
+remove_output ()
+{
+ if (output_filename)
+ {
+ if (output_bfd && output_bfd->iostream)
+ fclose((FILE *)(output_bfd->iostream));
+ if (delete_output_file_on_failure)
+ unlink (output_filename);
+ }
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *emulation;
+ long start_time = get_run_time ();
+
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ program_name = argv[0];
+ xmalloc_set_program_name (program_name);
+
+ START_PROGRESS (program_name, 0);
+
+ bfd_init ();
+
+ bfd_set_error_program_name (program_name);
+
+ xatexit (remove_output);
+
+ /* Set the default BFD target based on the configured target. Doing
+ this permits the linker to be configured for a particular target,
+ and linked against a shared BFD library which was configured for
+ a different target. The macro TARGET is defined by Makefile. */
+ if (! bfd_set_default_target (TARGET))
+ {
+ einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
+ xexit (1);
+ }
+
+ /* Initialize the data about options. */
+ trace_files = trace_file_tries = version_printed = false;
+ whole_archive = false;
+ config.build_constructors = true;
+ config.dynamic_link = false;
+ config.has_shared = false;
+ command_line.force_common_definition = false;
+ command_line.interpreter = NULL;
+ command_line.rpath = NULL;
+ command_line.warn_mismatch = true;
+ command_line.check_section_addresses = true;
+
+ /* We initialize DEMANGLING based on the environment variable
+ COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the
+ output of the linker, unless COLLECT_NO_DEMANGLE is set in the
+ environment. Acting the same way here lets us provide the same
+ interface by default. */
+ demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;
+
+ link_info.callbacks = &link_callbacks;
+ link_info.relocateable = false;
+ link_info.shared = false;
+ link_info.symbolic = false;
+ link_info.static_link = false;
+ link_info.traditional_format = false;
+ link_info.optimize = false;
+ link_info.no_undefined = false;
+ link_info.strip = strip_none;
+ link_info.discard = discard_none;
+ link_info.keep_memory = true;
+ link_info.input_bfds = NULL;
+ link_info.create_object_symbols_section = NULL;
+ link_info.hash = NULL;
+ link_info.keep_hash = NULL;
+ link_info.notice_all = false;
+ link_info.notice_hash = NULL;
+ link_info.wrap_hash = NULL;
+ link_info.mpc860c0 = 0;
+
+ ldfile_add_arch ("");
+
+ config.make_executable = true;
+ force_make_executable = false;
+ config.magic_demand_paged = true;
+ config.text_read_only = true;
+ config.make_executable = true;
+
+ emulation = get_emulation (argc, argv);
+ ldemul_choose_mode (emulation);
+ default_target = ldemul_choose_target ();
+ lang_init ();
+ ldemul_before_parse ();
+ lang_has_input_file = false;
+ parse_args (argc, argv);
+
+ ldemul_set_symbols ();
+
+ if (link_info.relocateable)
+ {
+ if (command_line.gc_sections)
+ einfo ("%P%F: --gc-sections and -r may not be used together\n");
+ if (link_info.mpc860c0)
+ einfo (_("%P%F: -r and --mpc860c0 may not be used together\n"));
+ else if (command_line.relax)
+ einfo (_("%P%F: --relax and -r may not be used together\n"));
+ if (link_info.shared)
+ einfo (_("%P%F: -r and -shared may not be used together\n"));
+ }
+
+ /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I
+ don't see how else this can be handled, since in this case we
+ must preserve all externally visible symbols. */
+ if (link_info.relocateable && link_info.strip == strip_all)
+ {
+ link_info.strip = strip_debugger;
+ if (link_info.discard == discard_none)
+ link_info.discard = discard_all;
+ }
+
+ /* This essentially adds another -L directory so this must be done after
+ the -L's in argv have been processed. */
+ set_scripts_dir ();
+
+ if (had_script == false)
+ {
+ /* Read the emulation's appropriate default script. */
+ int isfile;
+ char *s = ldemul_get_script (&isfile);
+
+ if (isfile)
+ ldfile_open_command_file (s);
+ else
+ {
+ if (trace_file_tries)
+ {
+ info_msg (_("using internal linker script:\n"));
+ info_msg ("==================================================\n");
+ info_msg (s);
+ info_msg ("\n==================================================\n");
+ }
+ lex_string = s;
+ lex_redirect (s);
+ }
+ parser_input = input_script;
+ yyparse ();
+ lex_string = NULL;
+ }
+
+ lang_final ();
+
+ if (lang_has_input_file == false)
+ {
+ if (version_printed)
+ xexit (0);
+ einfo (_("%P%F: no input files\n"));
+ }
+
+ if (trace_files)
+ {
+ info_msg (_("%P: mode %s\n"), emulation);
+ }
+
+ ldemul_after_parse ();
+
+
+ if (config.map_filename)
+ {
+ if (strcmp (config.map_filename, "-") == 0)
+ {
+ config.map_file = stdout;
+ }
+ else
+ {
+ config.map_file = fopen (config.map_filename, FOPEN_WT);
+ if (config.map_file == (FILE *) NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ einfo (_("%P%F: cannot open map file %s: %E\n"),
+ config.map_filename);
+ }
+ }
+ }
+
+
+ lang_process ();
+
+ /* Print error messages for any missing symbols, for any warning
+ symbols, and possibly multiple definitions */
+
+
+ if (config.text_read_only)
+ {
+ /* Look for a text section and mark the readonly attribute in it */
+ asection *found = bfd_get_section_by_name (output_bfd, ".text");
+
+ if (found != (asection *) NULL)
+ {
+ found->flags |= SEC_READONLY;
+ }
+ }
+
+ if (link_info.relocateable)
+ output_bfd->flags &= ~EXEC_P;
+ else
+ output_bfd->flags |= EXEC_P;
+
+ ldwrite ();
+
+ if (config.map_file != NULL)
+ lang_map ();
+ if (command_line.cref)
+ output_cref (config.map_file != NULL ? config.map_file : stdout);
+ if (nocrossref_list != NULL)
+ check_nocrossrefs ();
+
+ /* Even if we're producing relocateable output, some non-fatal errors should
+ be reported in the exit status. (What non-fatal errors, if any, do we
+ want to ignore for relocateable output?) */
+
+ if (config.make_executable == false && force_make_executable == false)
+ {
+ if (trace_files == true)
+ {
+ einfo (_("%P: link errors found, deleting executable `%s'\n"),
+ output_filename);
+ }
+
+ /* The file will be removed by remove_output. */
+
+ xexit (1);
+ }
+ else
+ {
+ if (! bfd_close (output_bfd))
+ einfo (_("%F%B: final close failed: %E\n"), output_bfd);
+
+ /* If the --force-exe-suffix is enabled, and we're making an
+ executable file and it doesn't end in .exe, copy it to one which does. */
+
+ if (! link_info.relocateable && command_line.force_exe_suffix)
+ {
+ int len = strlen (output_filename);
+ if (len < 4
+ || (strcasecmp (output_filename + len - 4, ".exe") != 0
+ && strcasecmp (output_filename + len - 4, ".dll") != 0))
+ {
+ FILE *src;
+ FILE *dst;
+ const int bsize = 4096;
+ char *buf = xmalloc (bsize);
+ int l;
+ char *dst_name = xmalloc (len + 5);
+ strcpy (dst_name, output_filename);
+ strcat (dst_name, ".exe");
+ src = fopen (output_filename, FOPEN_RB);
+ dst = fopen (dst_name, FOPEN_WB);
+
+ if (!src)
+ einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename);
+ if (!dst)
+ einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name);
+ while ((l = fread (buf, 1, bsize, src)) > 0)
+ {
+ int done = fwrite (buf, 1, l, dst);
+ if (done != l)
+ {
+ einfo (_("%P: Error writing file `%s'\n"), dst_name);
+ }
+ }
+ fclose (src);
+ if (fclose (dst) == EOF)
+ {
+ einfo (_("%P: Error closing file `%s'\n"), dst_name);
+ }
+ free (dst_name);
+ free (buf);
+ }
+ }
+ }
+
+ END_PROGRESS (program_name);
+
+ if (config.stats)
+ {
+#ifdef HAVE_SBRK
+ char *lim = (char *) sbrk (0);
+#endif
+ long run_time = get_run_time () - start_time;
+
+ fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
+ program_name, run_time / 1000000, run_time % 1000000);
+#ifdef HAVE_SBRK
+ fprintf (stderr, _("%s: data size %ld\n"), program_name,
+ (long) (lim - (char *) &environ));
+#endif
+ }
+
+ /* Prevent remove_output from doing anything, after a successful link. */
+ output_filename = NULL;
+
+ xexit (0);
+ return 0;
+}
+
+/* We need to find any explicitly given emulation in order to initialize the
+ state that's needed by the lex&yacc argument parser (parse_args). */
+
+static char *
+get_emulation (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *emulation;
+ int i;
+
+ emulation = getenv (EMULATION_ENVIRON);
+ if (emulation == NULL)
+ emulation = DEFAULT_EMULATION;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (!strncmp (argv[i], "-m", 2))
+ {
+ if (argv[i][2] == '\0')
+ {
+ /* -m EMUL */
+ if (i < argc - 1)
+ {
+ emulation = argv[i + 1];
+ i++;
+ }
+ else
+ {
+ einfo(_("%P%F: missing argument to -m\n"));
+ }
+ }
+ else if (strcmp (argv[i], "-mips1") == 0
+ || strcmp (argv[i], "-mips2") == 0
+ || strcmp (argv[i], "-mips3") == 0
+ || strcmp (argv[i], "-mips4") == 0)
+ {
+ /* FIXME: The arguments -mips1, -mips2 and -mips3 are
+ passed to the linker by some MIPS compilers. They
+ generally tell the linker to use a slightly different
+ library path. Perhaps someday these should be
+ implemented as emulations; until then, we just ignore
+ the arguments and hope that nobody ever creates
+ emulations named ips1, ips2 or ips3. */
+ }
+ else if (strcmp (argv[i], "-m486") == 0)
+ {
+ /* FIXME: The argument -m486 is passed to the linker on
+ some Linux systems. Hope that nobody creates an
+ emulation named 486. */
+ }
+ else
+ {
+ /* -mEMUL */
+ emulation = &argv[i][2];
+ }
+ }
+ }
+
+ return emulation;
+}
+
+/* If directory DIR contains an "ldscripts" subdirectory,
+ add DIR to the library search path and return true,
+ else return false. */
+
+static boolean
+check_for_scripts_dir (dir)
+ char *dir;
+{
+ size_t dirlen;
+ char *buf;
+ struct stat s;
+ boolean res;
+
+ dirlen = strlen (dir);
+ /* sizeof counts the terminating NUL. */
+ buf = (char *) xmalloc (dirlen + sizeof("/ldscripts"));
+ sprintf (buf, "%s/ldscripts", dir);
+
+ res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
+ free (buf);
+ if (res)
+ ldfile_add_library_path (dir, false);
+ return res;
+}
+
+/* Set the default directory for finding script files.
+ Libraries will be searched for here too, but that's ok.
+ We look for the "ldscripts" directory in:
+
+ SCRIPTDIR (passed from Makefile)
+ the dir where this program is (for using it from the build tree)
+ the dir where this program is/../lib (for installing the tool suite elsewhere) */
+
+static void
+set_scripts_dir ()
+{
+ char *end, *dir;
+ size_t dirlen;
+
+ if (check_for_scripts_dir (SCRIPTDIR))
+ return; /* We've been installed normally. */
+
+ /* Look for "ldscripts" in the dir where our binary is. */
+ end = strrchr (program_name, '/');
+
+ if (end == NULL)
+ {
+ /* Don't look for ldscripts in the current directory. There is
+ too much potential for confusion. */
+ return;
+ }
+
+ dirlen = end - program_name;
+ /* Make a copy of program_name in dir.
+ Leave room for later "/../lib". */
+ dir = (char *) xmalloc (dirlen + 8);
+ strncpy (dir, program_name, dirlen);
+ dir[dirlen] = '\0';
+
+ if (check_for_scripts_dir (dir))
+ return; /* Don't free dir. */
+
+ /* Look for "ldscripts" in <the dir where our binary is>/../lib. */
+ strcpy (dir + dirlen, "/../lib");
+ if (check_for_scripts_dir (dir))
+ return;
+
+ free (dir); /* Well, we tried. */
+}
+
+void
+add_ysym (name)
+ const char *name;
+{
+ if (link_info.notice_hash == (struct bfd_hash_table *) NULL)
+ {
+ link_info.notice_hash = ((struct bfd_hash_table *)
+ xmalloc (sizeof (struct bfd_hash_table)));
+ if (! bfd_hash_table_init_n (link_info.notice_hash,
+ bfd_hash_newfunc,
+ 61))
+ einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
+ }
+
+ if (bfd_hash_lookup (link_info.notice_hash, name, true, true)
+ == (struct bfd_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
+}
+
+/* Record a symbol to be wrapped, from the --wrap option. */
+
+void
+add_wrap (name)
+ const char *name;
+{
+ if (link_info.wrap_hash == NULL)
+ {
+ link_info.wrap_hash = ((struct bfd_hash_table *)
+ xmalloc (sizeof (struct bfd_hash_table)));
+ if (! bfd_hash_table_init_n (link_info.wrap_hash,
+ bfd_hash_newfunc,
+ 61))
+ einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
+ }
+ if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL)
+ einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
+}
+
+/* Handle the -retain-symbols-file option. */
+
+void
+add_keepsyms_file (filename)
+ const char *filename;
+{
+ FILE *file;
+ char *buf;
+ size_t bufsize;
+ int c;
+
+ if (link_info.strip == strip_some)
+ einfo (_("%X%P: error: duplicate retain-symbols-file\n"));
+
+ file = fopen (filename, "r");
+ if (file == (FILE *) NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ einfo ("%X%P: %s: %E\n", filename);
+ return;
+ }
+
+ link_info.keep_hash = ((struct bfd_hash_table *)
+ xmalloc (sizeof (struct bfd_hash_table)));
+ if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc))
+ einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
+
+ bufsize = 100;
+ buf = (char *) xmalloc (bufsize);
+
+ c = getc (file);
+ while (c != EOF)
+ {
+ while (isspace (c))
+ c = getc (file);
+
+ if (c != EOF)
+ {
+ size_t len = 0;
+
+ while (! isspace (c) && c != EOF)
+ {
+ buf[len] = c;
+ ++len;
+ if (len >= bufsize)
+ {
+ bufsize *= 2;
+ buf = xrealloc (buf, bufsize);
+ }
+ c = getc (file);
+ }
+
+ buf[len] = '\0';
+
+ if (bfd_hash_lookup (link_info.keep_hash, buf, true, true)
+ == (struct bfd_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n"));
+ }
+ }
+
+ if (link_info.strip != strip_none)
+ einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"));
+
+ link_info.strip = strip_some;
+}
+
+/* Callbacks from the BFD linker routines. */
+
+/* This is called when BFD has decided to include an archive member in
+ a link. */
+
+/*ARGSUSED*/
+static boolean
+add_archive_element (info, abfd, name)
+ struct bfd_link_info *info;
+ bfd *abfd;
+ const char *name;
+{
+ lang_input_statement_type *input;
+
+ input = ((lang_input_statement_type *)
+ xmalloc (sizeof (lang_input_statement_type)));
+ input->filename = abfd->filename;
+ input->local_sym_name = abfd->filename;
+ input->the_bfd = abfd;
+ input->asymbols = NULL;
+ input->next = NULL;
+ input->just_syms_flag = false;
+ input->loaded = false;
+ input->search_dirs_flag = false;
+
+ /* FIXME: The following fields are not set: header.next,
+ header.type, closed, passive_position, symbol_count,
+ next_real_file, is_archive, target, real. This bit of code is
+ from the old decode_library_subfile function. I don't know
+ whether any of those fields matters. */
+
+ ldlang_add_file (input);
+
+ if (config.map_file != (FILE *) NULL)
+ {
+ static boolean header_printed;
+ struct bfd_link_hash_entry *h;
+ bfd *from;
+ int len;
+
+ h = bfd_link_hash_lookup (link_info.hash, name, false, false, true);
+
+ if (h == NULL)
+ from = NULL;
+ else
+ {
+ switch (h->type)
+ {
+ default:
+ from = NULL;
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ from = h->u.def.section->owner;
+ break;
+
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ from = h->u.undef.abfd;
+ break;
+
+ case bfd_link_hash_common:
+ from = h->u.c.p->section->owner;
+ break;
+ }
+ }
+
+ if (! header_printed)
+ {
+ char buf[100];
+
+ sprintf (buf, "%-29s %s\n\n", _("Archive member included"),
+ _("because of file (symbol)"));
+ minfo ("%s", buf);
+ header_printed = true;
+ }
+
+ if (bfd_my_archive (abfd) == NULL)
+ {
+ minfo ("%s", bfd_get_filename (abfd));
+ len = strlen (bfd_get_filename (abfd));
+ }
+ else
+ {
+ minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)),
+ bfd_get_filename (abfd));
+ len = (strlen (bfd_get_filename (bfd_my_archive (abfd)))
+ + strlen (bfd_get_filename (abfd))
+ + 2);
+ }
+
+ if (len >= 29)
+ {
+ print_nl ();
+ len = 0;
+ }
+ while (len < 30)
+ {
+ print_space ();
+ ++len;
+ }
+
+ if (from != NULL)
+ minfo ("%B ", from);
+ if (h != NULL)
+ minfo ("(%T)\n", h->root.string);
+ else
+ minfo ("(%s)\n", name);
+ }
+
+ if (trace_files || trace_file_tries)
+ info_msg ("%I\n", input);
+
+ return true;
+}
+
+/* This is called when BFD has discovered a symbol which is defined
+ multiple times. */
+
+/*ARGSUSED*/
+static boolean
+multiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval)
+ struct bfd_link_info *info;
+ const char *name;
+ bfd *obfd;
+ asection *osec;
+ bfd_vma oval;
+ bfd *nbfd;
+ asection *nsec;
+ bfd_vma nval;
+{
+ /* If either section has the output_section field set to
+ bfd_abs_section_ptr, it means that the section is being
+ discarded, and this is not really a multiple definition at all.
+ FIXME: It would be cleaner to somehow ignore symbols defined in
+ sections which are being discarded. */
+ if ((osec->output_section != NULL
+ && ! bfd_is_abs_section (osec)
+ && bfd_is_abs_section (osec->output_section))
+ || (nsec->output_section != NULL
+ && ! bfd_is_abs_section (nsec)
+ && bfd_is_abs_section (nsec->output_section)))
+ return true;
+
+ einfo (_("%X%C: multiple definition of `%T'\n"),
+ nbfd, nsec, nval, name);
+ if (obfd != (bfd *) NULL)
+ einfo (_("%D: first defined here\n"), obfd, osec, oval);
+ return true;
+}
+
+/* This is called when there is a definition of a common symbol, or
+ when a common symbol is found for a symbol that is already defined,
+ or when two common symbols are found. We only do something if
+ -warn-common was used. */
+
+/*ARGSUSED*/
+static boolean
+multiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
+ struct bfd_link_info *info;
+ const char *name;
+ bfd *obfd;
+ enum bfd_link_hash_type otype;
+ bfd_vma osize;
+ bfd *nbfd;
+ enum bfd_link_hash_type ntype;
+ bfd_vma nsize;
+{
+ if (! config.warn_common)
+ return true;
+
+ if (ntype == bfd_link_hash_defined
+ || ntype == bfd_link_hash_defweak
+ || ntype == bfd_link_hash_indirect)
+ {
+ ASSERT (otype == bfd_link_hash_common);
+ einfo (_("%B: warning: definition of `%T' overriding common\n"),
+ nbfd, name);
+ if (obfd != NULL)
+ einfo (_("%B: warning: common is here\n"), obfd);
+ }
+ else if (otype == bfd_link_hash_defined
+ || otype == bfd_link_hash_defweak
+ || otype == bfd_link_hash_indirect)
+ {
+ ASSERT (ntype == bfd_link_hash_common);
+ einfo (_("%B: warning: common of `%T' overridden by definition\n"),
+ nbfd, name);
+ if (obfd != NULL)
+ einfo (_("%B: warning: defined here\n"), obfd);
+ }
+ else
+ {
+ ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common);
+ if (osize > nsize)
+ {
+ einfo (_("%B: warning: common of `%T' overridden by larger common\n"),
+ nbfd, name);
+ if (obfd != NULL)
+ einfo (_("%B: warning: larger common is here\n"), obfd);
+ }
+ else if (nsize > osize)
+ {
+ einfo (_("%B: warning: common of `%T' overriding smaller common\n"),
+ nbfd, name);
+ if (obfd != NULL)
+ einfo (_("%B: warning: smaller common is here\n"), obfd);
+ }
+ else
+ {
+ einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name);
+ if (obfd != NULL)
+ einfo (_("%B: warning: previous common is here\n"), obfd);
+ }
+ }
+
+ return true;
+}
+
+/* This is called when BFD has discovered a set element. H is the
+ entry in the linker hash table for the set. SECTION and VALUE
+ represent a value which should be added to the set. */
+
+/*ARGSUSED*/
+static boolean
+add_to_set (info, h, reloc, abfd, section, value)
+ struct bfd_link_info *info;
+ struct bfd_link_hash_entry *h;
+ bfd_reloc_code_real_type reloc;
+ bfd *abfd;
+ asection *section;
+ bfd_vma value;
+{
+ if (config.warn_constructors)
+ einfo (_("%P: warning: global constructor %s used\n"),
+ h->root.string);
+
+ if (! config.build_constructors)
+ return true;
+
+ ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value);
+
+ if (h->type == bfd_link_hash_new)
+ {
+ h->type = bfd_link_hash_undefined;
+ h->u.undef.abfd = abfd;
+ /* We don't call bfd_link_add_undef to add this to the list of
+ undefined symbols because we are going to define it
+ ourselves. */
+ }
+
+ return true;
+}
+
+/* This is called when BFD has discovered a constructor. This is only
+ called for some object file formats--those which do not handle
+ constructors in some more clever fashion. This is similar to
+ adding an element to a set, but less general. */
+
+static boolean
+constructor_callback (info, constructor, name, abfd, section, value)
+ struct bfd_link_info *info;
+ boolean constructor;
+ const char *name;
+ bfd *abfd;
+ asection *section;
+ bfd_vma value;
+{
+ char *s;
+ struct bfd_link_hash_entry *h;
+ char set_name[1 + sizeof "__CTOR_LIST__"];
+
+ if (config.warn_constructors)
+ einfo (_("%P: warning: global constructor %s used\n"), name);
+
+ if (! config.build_constructors)
+ return true;
+
+ /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
+ useful error message. */
+ if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL
+ && (link_info.relocateable
+ || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
+ einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
+
+ s = set_name;
+ if (bfd_get_symbol_leading_char (abfd) != '\0')
+ *s++ = bfd_get_symbol_leading_char (abfd);
+ if (constructor)
+ strcpy (s, "__CTOR_LIST__");
+ else
+ strcpy (s, "__DTOR_LIST__");
+
+ h = bfd_link_hash_lookup (info->hash, set_name, true, true, true);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+ if (h->type == bfd_link_hash_new)
+ {
+ h->type = bfd_link_hash_undefined;
+ h->u.undef.abfd = abfd;
+ /* We don't call bfd_link_add_undef to add this to the list of
+ undefined symbols because we are going to define it
+ ourselves. */
+ }
+
+ ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value);
+ return true;
+}
+
+/* A structure used by warning_callback to pass information through
+ bfd_map_over_sections. */
+
+struct warning_callback_info
+{
+ boolean found;
+ const char *warning;
+ const char *symbol;
+ asymbol **asymbols;
+};
+
+/* This is called when there is a reference to a warning symbol. */
+
+/*ARGSUSED*/
+static boolean
+warning_callback (info, warning, symbol, abfd, section, address)
+ struct bfd_link_info *info;
+ const char *warning;
+ const char *symbol;
+ bfd *abfd;
+ asection *section;
+ bfd_vma address;
+{
+ /* This is a hack to support warn_multiple_gp. FIXME: This should
+ have a cleaner interface, but what? */
+ if (! config.warn_multiple_gp
+ && strcmp (warning, "using multiple gp values") == 0)
+ return true;
+
+ if (section != NULL)
+ einfo ("%C: %s\n", abfd, section, address, warning);
+ else if (abfd == NULL)
+ einfo ("%P: %s\n", warning);
+ else if (symbol == NULL)
+ einfo ("%B: %s\n", abfd, warning);
+ else
+ {
+ lang_input_statement_type *entry;
+ asymbol **asymbols;
+ struct warning_callback_info info;
+
+ /* Look through the relocs to see if we can find a plausible
+ address. */
+
+ entry = (lang_input_statement_type *) abfd->usrdata;
+ if (entry != NULL && entry->asymbols != NULL)
+ asymbols = entry->asymbols;
+ else
+ {
+ long symsize;
+ long symbol_count;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ einfo (_("%B%F: could not read symbols: %E\n"), abfd);
+ asymbols = (asymbol **) xmalloc (symsize);
+ symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
+ if (symbol_count < 0)
+ einfo (_("%B%F: could not read symbols: %E\n"), abfd);
+ if (entry != NULL)
+ {
+ entry->asymbols = asymbols;
+ entry->symbol_count = symbol_count;
+ }
+ }
+
+ info.found = false;
+ info.warning = warning;
+ info.symbol = symbol;
+ info.asymbols = asymbols;
+ bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info);
+
+ if (! info.found)
+ einfo ("%B: %s\n", abfd, warning);
+
+ if (entry == NULL)
+ free (asymbols);
+ }
+
+ return true;
+}
+
+/* This is called by warning_callback for each section. It checks the
+ relocs of the section to see if it can find a reference to the
+ symbol which triggered the warning. If it can, it uses the reloc
+ to give an error message with a file and line number. */
+
+static void
+warning_find_reloc (abfd, sec, iarg)
+ bfd *abfd;
+ asection *sec;
+ PTR iarg;
+{
+ struct warning_callback_info *info = (struct warning_callback_info *) iarg;
+ long relsize;
+ arelent **relpp;
+ long relcount;
+ arelent **p, **pend;
+
+ if (info->found)
+ return;
+
+ relsize = bfd_get_reloc_upper_bound (abfd, sec);
+ if (relsize < 0)
+ einfo (_("%B%F: could not read relocs: %E\n"), abfd);
+ if (relsize == 0)
+ return;
+
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
+ if (relcount < 0)
+ einfo (_("%B%F: could not read relocs: %E\n"), abfd);
+
+ p = relpp;
+ pend = p + relcount;
+ for (; p < pend && *p != NULL; p++)
+ {
+ arelent *q = *p;
+
+ if (q->sym_ptr_ptr != NULL
+ && *q->sym_ptr_ptr != NULL
+ && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
+ {
+ /* We found a reloc for the symbol we are looking for. */
+ einfo ("%C: %s\n", abfd, sec, q->address, info->warning);
+ info->found = true;
+ break;
+ }
+ }
+
+ free (relpp);
+}
+
+/* This is called when an undefined symbol is found. */
+
+/*ARGSUSED*/
+static boolean
+undefined_symbol (info, name, abfd, section, address)
+ struct bfd_link_info *info;
+ const char *name;
+ bfd *abfd;
+ asection *section;
+ bfd_vma address;
+{
+ static char *error_name;
+ static unsigned int error_count;
+
+#define MAX_ERRORS_IN_A_ROW 5
+
+ if (config.warn_once)
+ {
+ static struct bfd_hash_table *hash;
+
+ /* Only warn once about a particular undefined symbol. */
+
+ if (hash == NULL)
+ {
+ hash = ((struct bfd_hash_table *)
+ xmalloc (sizeof (struct bfd_hash_table)));
+ if (! bfd_hash_table_init (hash, bfd_hash_newfunc))
+ einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
+ }
+
+ if (bfd_hash_lookup (hash, name, false, false) != NULL)
+ return true;
+
+ if (bfd_hash_lookup (hash, name, true, true) == NULL)
+ einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
+ }
+
+ /* We never print more than a reasonable number of errors in a row
+ for a single symbol. */
+ if (error_name != (char *) NULL
+ && strcmp (name, error_name) == 0)
+ ++error_count;
+ else
+ {
+ error_count = 0;
+ if (error_name != (char *) NULL)
+ free (error_name);
+ error_name = buystring (name);
+ }
+
+ if (section != NULL)
+ {
+ if (error_count < MAX_ERRORS_IN_A_ROW)
+ einfo (_("%X%C: undefined reference to `%T'\n"),
+ abfd, section, address, name);
+ else if (error_count == MAX_ERRORS_IN_A_ROW)
+ einfo (_("%D: more undefined references to `%T' follow\n"),
+ abfd, section, address, name);
+ }
+ else
+ {
+ if (error_count < MAX_ERRORS_IN_A_ROW)
+ einfo (_("%X%B: undefined reference to `%T'\n"),
+ abfd, name);
+ else if (error_count == MAX_ERRORS_IN_A_ROW)
+ einfo (_("%B: more undefined references to `%T' follow\n"),
+ abfd, name);
+ }
+
+ return true;
+}
+
+/* This is called when a reloc overflows. */
+
+/*ARGSUSED*/
+static boolean
+reloc_overflow (info, name, reloc_name, addend, abfd, section, address)
+ struct bfd_link_info *info;
+ const char *name;
+ const char *reloc_name;
+ bfd_vma addend;
+ bfd *abfd;
+ asection *section;
+ bfd_vma address;
+{
+ if (abfd == (bfd *) NULL)
+ einfo (_("%P%X: generated"));
+ else
+ einfo ("%X%C:", abfd, section, address);
+ einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name);
+ if (addend != 0)
+ einfo ("+%v", addend);
+ einfo ("\n");
+ return true;
+}
+
+/* This is called when a dangerous relocation is made. */
+
+/*ARGSUSED*/
+static boolean
+reloc_dangerous (info, message, abfd, section, address)
+ struct bfd_link_info *info;
+ const char *message;
+ bfd *abfd;
+ asection *section;
+ bfd_vma address;
+{
+ if (abfd == (bfd *) NULL)
+ einfo (_("%P%X: generated"));
+ else
+ einfo ("%X%C:", abfd, section, address);
+ einfo (_("dangerous relocation: %s\n"), message);
+ return true;
+}
+
+/* This is called when a reloc is being generated attached to a symbol
+ that is not being output. */
+
+/*ARGSUSED*/
+static boolean
+unattached_reloc (info, name, abfd, section, address)
+ struct bfd_link_info *info;
+ const char *name;
+ bfd *abfd;
+ asection *section;
+ bfd_vma address;
+{
+ if (abfd == (bfd *) NULL)
+ einfo (_("%P%X: generated"));
+ else
+ einfo ("%X%C:", abfd, section, address);
+ einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name);
+ return true;
+}
+
+/* This is called if link_info.notice_all is set, or when a symbol in
+ link_info.notice_hash is found. Symbols are put in notice_hash
+ using the -y option. */
+
+static boolean
+notice (info, name, abfd, section, value)
+ struct bfd_link_info *info;
+ const char *name;
+ bfd *abfd;
+ asection *section;
+ bfd_vma value;
+{
+ if (! info->notice_all
+ || (info->notice_hash != NULL
+ && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL))
+ {
+ if (bfd_is_und_section (section))
+ einfo ("%B: reference to %s\n", abfd, name);
+ else
+ einfo ("%B: definition of %s\n", abfd, name);
+ }
+
+ if (command_line.cref || nocrossref_list != NULL)
+ add_cref (name, abfd, section, value);
+
+ return true;
+}
diff --git a/ld/ldmain.h b/ld/ldmain.h
new file mode 100644
index 00000000000..041bf3d31fb
--- /dev/null
+++ b/ld/ldmain.h
@@ -0,0 +1,40 @@
+/* ldmain.h -
+ Copyright 1991, 92, 93, 94, 95, 96, 1999 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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 1, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef LDMAIN_H
+#define LDMAIN_H
+
+extern char *program_name;
+extern bfd *output_bfd;
+extern char *default_target;
+extern boolean trace_files;
+extern boolean trace_file_tries;
+extern boolean version_printed;
+extern boolean whole_archive;
+extern boolean demangling;
+extern int g_switch_value;
+extern const char *output_filename;
+extern struct bfd_link_info link_info;
+
+extern void add_ysym PARAMS ((const char *));
+extern void add_wrap PARAMS ((const char *));
+extern void add_keepsyms_file PARAMS ((const char *filename));
+
+#endif
diff --git a/ld/ldmisc.c b/ld/ldmisc.c
new file mode 100644
index 00000000000..8fab22825f7
--- /dev/null
+++ b/ld/ldmisc.c
@@ -0,0 +1,538 @@
+/* ldmisc.c
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain of Cygnus Support.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "demangle.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#define USE_STDARG 1
+#else
+#include <varargs.h>
+#define USE_STDARG 0
+#endif
+
+#include "ld.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldgram.h"
+#include "ldlex.h"
+#include "ldmain.h"
+#include "ldfile.h"
+
+static void vfinfo PARAMS ((FILE *, const char *, va_list));
+
+/*
+ %% literal %
+ %F error is fatal
+ %P print program name
+ %S print script file and linenumber
+ %E current bfd error or errno
+ %I filename from a lang_input_statement_type
+ %B filename from a bfd
+ %T symbol name
+ %X no object output, fail return
+ %V hex bfd_vma
+ %v hex bfd_vma, no leading zeros
+ %W hex bfd_vma with 0x with no leading zeros taking up 8 spaces
+ %C clever filename:linenumber with function
+ %D like %C, but no function name
+ %G like %D, but only function name
+ %R info about a relent
+ %s arbitrary string, like printf
+ %d integer, like printf
+ %u integer, like printf
+*/
+
+char *
+demangle (string)
+ const char *string;
+{
+ char *res;
+
+ if (output_bfd != NULL
+ && bfd_get_symbol_leading_char (output_bfd) == string[0])
+ ++string;
+
+ /* This is a hack for better error reporting on XCOFF, or the MS PE */
+ /* format. Xcoff has a single '.', while the NT PE for PPC has '..'. */
+ /* So we remove all of them. */
+ while(string[0] == '.')
+ ++string;
+
+ res = cplus_demangle (string, DMGL_ANSI | DMGL_PARAMS);
+ return res ? res : xstrdup (string);
+}
+
+static void
+vfinfo (fp, fmt, arg)
+ FILE *fp;
+ const char *fmt;
+ va_list arg;
+{
+ boolean fatal = false;
+
+ while (*fmt != '\0')
+ {
+ while (*fmt != '%' && *fmt != '\0')
+ {
+ putc (*fmt, fp);
+ fmt++;
+ }
+
+ if (*fmt == '%')
+ {
+ fmt ++;
+ switch (*fmt++)
+ {
+ default:
+ fprintf (fp,"%%%c", fmt[-1]);
+ break;
+
+ case '%':
+ /* literal % */
+ putc ('%', fp);
+ break;
+
+ case 'X':
+ /* no object output, fail return */
+ config.make_executable = false;
+ break;
+
+ case 'V':
+ /* hex bfd_vma */
+ {
+ bfd_vma value = va_arg (arg, bfd_vma);
+ fprintf_vma (fp, value);
+ }
+ break;
+
+ case 'v':
+ /* hex bfd_vma, no leading zeros */
+ {
+ char buf[100];
+ char *p = buf;
+ bfd_vma value = va_arg (arg, bfd_vma);
+ sprintf_vma (p, value);
+ while (*p == '0')
+ p++;
+ if (!*p)
+ p--;
+ fputs (p, fp);
+ }
+ break;
+
+ case 'W':
+ /* hex bfd_vma with 0x with no leading zeroes taking up
+ 8 spaces. */
+ {
+ char buf[100];
+ bfd_vma value;
+ char *p;
+ int len;
+
+ value = va_arg (arg, bfd_vma);
+ sprintf_vma (buf, value);
+ for (p = buf; *p == '0'; ++p)
+ ;
+ if (*p == '\0')
+ --p;
+ len = strlen (p);
+ while (len < 8)
+ {
+ putc (' ', fp);
+ ++len;
+ }
+ fprintf (fp, "0x%s", p);
+ }
+ break;
+
+ case 'T':
+ /* Symbol name. */
+ {
+ const char *name = va_arg (arg, const char *);
+
+ if (name == (const char *) NULL || *name == 0)
+ fprintf (fp, _("no symbol"));
+ else if (! demangling)
+ fprintf (fp, "%s", name);
+ else
+ {
+ char *demangled;
+
+ demangled = demangle (name);
+ fprintf (fp, "%s", demangled);
+ free (demangled);
+ }
+ }
+ break;
+
+ case 'B':
+ /* filename from a bfd */
+ {
+ bfd *abfd = va_arg (arg, bfd *);
+ if (abfd->my_archive)
+ fprintf (fp, "%s(%s)", abfd->my_archive->filename,
+ abfd->filename);
+ else
+ fprintf (fp, "%s", abfd->filename);
+ }
+ break;
+
+ case 'F':
+ /* error is fatal */
+ fatal = true;
+ break;
+
+ case 'P':
+ /* print program name */
+ fprintf (fp, "%s", program_name);
+ break;
+
+ case 'E':
+ /* current bfd error or errno */
+ fprintf (fp, bfd_errmsg (bfd_get_error ()));
+ break;
+
+ case 'I':
+ /* filename from a lang_input_statement_type */
+ {
+ lang_input_statement_type *i;
+
+ i = va_arg (arg, lang_input_statement_type *);
+ if (bfd_my_archive (i->the_bfd) != NULL)
+ fprintf (fp, "(%s)",
+ bfd_get_filename (bfd_my_archive (i->the_bfd)));
+ fprintf (fp, "%s", i->local_sym_name);
+ if (bfd_my_archive (i->the_bfd) == NULL
+ && strcmp (i->local_sym_name, i->filename) != 0)
+ fprintf (fp, " (%s)", i->filename);
+ }
+ break;
+
+ case 'S':
+ /* print script file and linenumber */
+ if (parsing_defsym)
+ fprintf (fp, "--defsym %s", lex_string);
+ else if (ldfile_input_filename != NULL)
+ fprintf (fp, "%s:%u", ldfile_input_filename, lineno);
+ else
+ fprintf (fp, _("built in linker script:%u"), lineno);
+ break;
+
+ case 'R':
+ /* Print all that's interesting about a relent */
+ {
+ arelent *relent = va_arg (arg, arelent *);
+
+ lfinfo (fp, "%s+0x%v (type %s)",
+ (*(relent->sym_ptr_ptr))->name,
+ relent->addend,
+ relent->howto->name);
+ }
+ break;
+
+ case 'C':
+ case 'D':
+ case 'G':
+ /* Clever filename:linenumber with function name if possible,
+ or section name as a last resort. The arguments are a BFD,
+ a section, and an offset. */
+ {
+ static bfd *last_bfd;
+ static char *last_file = NULL;
+ static char *last_function = NULL;
+ bfd *abfd;
+ asection *section;
+ bfd_vma offset;
+ lang_input_statement_type *entry;
+ asymbol **asymbols;
+ const char *filename;
+ const char *functionname;
+ unsigned int linenumber;
+ boolean discard_last;
+
+ abfd = va_arg (arg, bfd *);
+ section = va_arg (arg, asection *);
+ offset = va_arg (arg, bfd_vma);
+
+ entry = (lang_input_statement_type *) abfd->usrdata;
+ if (entry != (lang_input_statement_type *) NULL
+ && entry->asymbols != (asymbol **) NULL)
+ asymbols = entry->asymbols;
+ else
+ {
+ long symsize;
+ long symbol_count;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ einfo (_("%B%F: could not read symbols\n"), abfd);
+ asymbols = (asymbol **) xmalloc (symsize);
+ symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
+ if (symbol_count < 0)
+ einfo (_("%B%F: could not read symbols\n"), abfd);
+ if (entry != (lang_input_statement_type *) NULL)
+ {
+ entry->asymbols = asymbols;
+ entry->symbol_count = symbol_count;
+ }
+ }
+
+ discard_last = true;
+ if (bfd_find_nearest_line (abfd, section, asymbols, offset,
+ &filename, &functionname,
+ &linenumber))
+ {
+ if (functionname != NULL && fmt[-1] == 'G')
+ {
+ lfinfo (fp, "%B:", abfd);
+ if (filename != NULL
+ && strcmp (filename, bfd_get_filename (abfd)) != 0)
+ fprintf (fp, "%s:", filename);
+ lfinfo (fp, "%T", functionname);
+ }
+ else if (functionname != NULL && fmt[-1] == 'C')
+ {
+ if (filename == (char *) NULL)
+ filename = abfd->filename;
+
+ if (last_bfd == NULL
+ || last_file == NULL
+ || last_function == NULL
+ || last_bfd != abfd
+ || strcmp (last_file, filename) != 0
+ || strcmp (last_function, functionname) != 0)
+ {
+ /* We use abfd->filename in this initial line,
+ in case filename is a .h file or something
+ similarly unhelpful. */
+ lfinfo (fp, _("%B: In function `%T':\n"),
+ abfd, functionname);
+
+ last_bfd = abfd;
+ if (last_file != NULL)
+ free (last_file);
+ last_file = buystring (filename);
+ if (last_function != NULL)
+ free (last_function);
+ last_function = buystring (functionname);
+ }
+ discard_last = false;
+ if (linenumber != 0)
+ fprintf (fp, "%s:%u", filename, linenumber);
+ else
+ lfinfo (fp, "%s(%s+0x%v)", filename, section->name,
+ offset);
+ }
+ else if (filename == NULL
+ || strcmp (filename, abfd->filename) == 0)
+ {
+ lfinfo (fp, "%B(%s+0x%v)", abfd, section->name,
+ offset);
+ if (linenumber != 0)
+ lfinfo (fp, ":%u", linenumber);
+ }
+ else if (linenumber != 0)
+ lfinfo (fp, "%B:%s:%u", abfd, filename, linenumber);
+ else
+ lfinfo (fp, "%B(%s+0x%v):%s", abfd, section->name,
+ offset, filename);
+ }
+ else
+ lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
+
+ if (discard_last)
+ {
+ last_bfd = NULL;
+ if (last_file != NULL)
+ {
+ free (last_file);
+ last_file = NULL;
+ }
+ if (last_function != NULL)
+ {
+ free (last_function);
+ last_function = NULL;
+ }
+ }
+ }
+ break;
+
+ case 's':
+ /* arbitrary string, like printf */
+ fprintf (fp, "%s", va_arg (arg, char *));
+ break;
+
+ case 'd':
+ /* integer, like printf */
+ fprintf (fp, "%d", va_arg (arg, int));
+ break;
+
+ case 'u':
+ /* unsigned integer, like printf */
+ fprintf (fp, "%u", va_arg (arg, unsigned int));
+ break;
+ }
+ }
+ }
+
+ if (fatal == true)
+ xexit(1);
+}
+
+/* Format info message and print on stdout. */
+
+/* (You would think this should be called just "info", but then you
+ would hosed by LynxOS, which defines that name in its libc.) */
+
+void
+#if USE_STDARG
+info_msg (const char *fmt, ...)
+#else
+info_msg (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+
+#if ! USE_STDARG
+ const char *fmt;
+
+ va_start (arg);
+ fmt = va_arg (arg, const char *);
+#else
+ va_start (arg, fmt);
+#endif
+
+ vfinfo (stdout, fmt, arg);
+ va_end (arg);
+}
+
+/* ('e' for error.) Format info message and print on stderr. */
+
+void
+#if USE_STDARG
+einfo (const char *fmt, ...)
+#else
+einfo (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+
+#if ! USE_STDARG
+ const char *fmt;
+
+ va_start (arg);
+ fmt = va_arg (arg, const char *);
+#else
+ va_start (arg, fmt);
+#endif
+
+ vfinfo (stderr, fmt, arg);
+ va_end (arg);
+}
+
+void
+info_assert (file, line)
+ const char *file;
+ unsigned int line;
+{
+ einfo (_("%F%P: internal error %s %d\n"), file, line);
+}
+
+char *
+buystring (x)
+ CONST char *CONST x;
+{
+ size_t l = strlen(x)+1;
+ char *r = xmalloc(l);
+ memcpy(r, x,l);
+ return r;
+}
+
+/* ('m' for map) Format info message and print on map. */
+
+void
+#if USE_STDARG
+minfo (const char *fmt, ...)
+#else
+minfo (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+
+#if ! USE_STDARG
+ const char *fmt;
+ va_start (arg);
+ fmt = va_arg (arg, const char *);
+#else
+ va_start (arg, fmt);
+#endif
+
+ vfinfo (config.map_file, fmt, arg);
+ va_end (arg);
+}
+
+void
+#if USE_STDARG
+lfinfo (FILE *file, const char *fmt, ...)
+#else
+lfinfo (va_alist)
+ va_dcl
+#endif
+{
+ va_list arg;
+
+#if ! USE_STDARG
+ FILE *file;
+ const char *fmt;
+
+ va_start (arg);
+ file = va_arg (arg, FILE *);
+ fmt = va_arg (arg, const char *);
+#else
+ va_start (arg, fmt);
+#endif
+
+ vfinfo (file, fmt, arg);
+ va_end (arg);
+}
+
+/* Functions to print the link map. */
+
+void
+print_space ()
+{
+ fprintf (config.map_file, " ");
+}
+
+void
+print_nl ()
+{
+ fprintf (config.map_file, "\n");
+}
diff --git a/ld/ldmisc.h b/ld/ldmisc.h
new file mode 100644
index 00000000000..f5b3b4f35af
--- /dev/null
+++ b/ld/ldmisc.h
@@ -0,0 +1,56 @@
+/* ldmisc.h -
+ Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef LDMISC_H
+#define LDMISC_H
+
+#ifdef ANSI_PROTOTYPES
+extern void einfo PARAMS ((const char *, ...));
+extern void minfo PARAMS ((const char *, ...));
+extern void info_msg PARAMS ((const char *, ...));
+extern void lfinfo PARAMS ((FILE *, const char *, ...));
+#else
+/* VARARGS*/
+extern void einfo ();
+/* VARARGS*/
+extern void minfo ();
+/* VARARGS*/
+extern void info_msg ();
+/*VARARGS*/
+extern void lfinfo ();
+#endif
+
+extern void info_assert PARAMS ((const char *, unsigned int));
+extern void yyerror PARAMS ((const char *));
+extern PTR xmalloc PARAMS ((size_t));
+extern PTR xrealloc PARAMS ((PTR, size_t));
+extern void xexit PARAMS ((int));
+extern char *buystring PARAMS ((CONST char *CONST));
+
+#define ASSERT(x) \
+do { if (!(x)) info_assert(__FILE__,__LINE__); } while (0)
+
+#define FAIL() \
+do { info_assert(__FILE__,__LINE__); } while (0)
+
+extern void print_space PARAMS ((void));
+extern void print_nl PARAMS ((void));
+extern char *demangle PARAMS ((const char *));
+
+#endif
diff --git a/ld/ldver.c b/ld/ldver.c
new file mode 100644
index 00000000000..5b600a2bbd0
--- /dev/null
+++ b/ld/ldver.c
@@ -0,0 +1,49 @@
+/* ldver.c -- Print linker version.
+ Copyright (C) 1991, 92, 93, 94, 95, 1996, 1998 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "bfd.h"
+#include "sysdep.h"
+
+#include "ld.h"
+#include "ldver.h"
+#include "ldemul.h"
+#include "ldmain.h"
+
+const char *ld_program_version = VERSION;
+
+void
+ldversion (noisy)
+ int noisy;
+{
+ fprintf (stdout, _("GNU ld version %s (with BFD %s)\n"),
+ ld_program_version, BFD_VERSION);
+
+ if (noisy)
+ {
+ ld_emulation_xfer_type **ptr = ld_emulations;
+
+ printf (_(" Supported emulations:\n"));
+ while (*ptr)
+ {
+ printf (" %s\n", (*ptr)->emulation_name);
+ ptr++;
+ }
+ }
+}
diff --git a/ld/ldver.h b/ld/ldver.h
new file mode 100644
index 00000000000..697b6bc31b3
--- /dev/null
+++ b/ld/ldver.h
@@ -0,0 +1,22 @@
+/* ldver.h -- Header file for ldver.c.
+ Copyright (C) 1991, 92, 93, 95, 1996 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern const char *ld_program_version;
+
+void ldversion PARAMS ((int));
diff --git a/ld/ldwrite.c b/ld/ldwrite.c
new file mode 100644
index 00000000000..b56119a39ac
--- /dev/null
+++ b/ld/ldwrite.c
@@ -0,0 +1,530 @@
+/* ldwrite.c -- write out the linked file
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+ Written by Steve Chamberlain sac@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libiberty.h"
+
+#include "ld.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldwrite.h"
+#include "ldmisc.h"
+#include "ldgram.h"
+#include "ldmain.h"
+
+static void build_link_order PARAMS ((lang_statement_union_type *));
+static asection *clone_section PARAMS ((bfd *, asection *, int *));
+static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Build link_order structures for the BFD linker. */
+
+static void
+build_link_order (statement)
+ lang_statement_union_type *statement;
+{
+ switch (statement->header.type)
+ {
+ case lang_data_statement_enum:
+ {
+ asection *output_section;
+ struct bfd_link_order *link_order;
+ bfd_vma value;
+ boolean big_endian = false;
+
+ output_section = statement->data_statement.output_section;
+ ASSERT (output_section->owner == output_bfd);
+
+ link_order = bfd_new_link_order (output_bfd, output_section);
+ if (link_order == NULL)
+ einfo (_("%P%F: bfd_new_link_order failed\n"));
+
+ link_order->type = bfd_data_link_order;
+ link_order->offset = statement->data_statement.output_vma;
+ link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
+
+ value = statement->data_statement.value;
+
+ /* If the endianness of the output BFD is not known, then we
+ base the endianness of the data on the first input file.
+ By convention, the bfd_put routines for an unknown
+ endianness are big endian, so we must swap here if the
+ input file is little endian. */
+ if (bfd_big_endian (output_bfd))
+ big_endian = true;
+ else if (bfd_little_endian (output_bfd))
+ big_endian = false;
+ else
+ {
+ boolean swap;
+
+ swap = false;
+ if (command_line.endian == ENDIAN_BIG)
+ big_endian = true;
+ else if (command_line.endian == ENDIAN_LITTLE)
+ {
+ big_endian = false;
+ swap = true;
+ }
+ else if (command_line.endian == ENDIAN_UNSET)
+ {
+ big_endian = true;
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (s)
+ {
+ if (s->the_bfd != NULL)
+ {
+ if (bfd_little_endian (s->the_bfd))
+ {
+ big_endian = false;
+ swap = true;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (swap)
+ {
+ bfd_byte buffer[8];
+
+ switch (statement->data_statement.type)
+ {
+ case QUAD:
+ case SQUAD:
+ if (sizeof (bfd_vma) >= QUAD_SIZE)
+ {
+ bfd_putl64 (value, buffer);
+ value = bfd_getb64 (buffer);
+ break;
+ }
+ /* Fall through. */
+ case LONG:
+ bfd_putl32 (value, buffer);
+ value = bfd_getb32 (buffer);
+ break;
+ case SHORT:
+ bfd_putl16 (value, buffer);
+ value = bfd_getb16 (buffer);
+ break;
+ case BYTE:
+ break;
+ default:
+ abort ();
+ }
+ }
+ }
+
+ ASSERT (output_section->owner == output_bfd);
+ switch (statement->data_statement.type)
+ {
+ case QUAD:
+ case SQUAD:
+ if (sizeof (bfd_vma) >= QUAD_SIZE)
+ bfd_put_64 (output_bfd, value, link_order->u.data.contents);
+ else
+ {
+ bfd_vma high;
+
+ if (statement->data_statement.type == QUAD)
+ high = 0;
+ else if ((value & 0x80000000) == 0)
+ high = 0;
+ else
+ high = (bfd_vma) -1;
+ bfd_put_32 (output_bfd, high,
+ (link_order->u.data.contents
+ + (big_endian ? 0 : 4)));
+ bfd_put_32 (output_bfd, value,
+ (link_order->u.data.contents
+ + (big_endian ? 4 : 0)));
+ }
+ link_order->size = QUAD_SIZE;
+ break;
+ case LONG:
+ bfd_put_32 (output_bfd, value, link_order->u.data.contents);
+ link_order->size = LONG_SIZE;
+ break;
+ case SHORT:
+ bfd_put_16 (output_bfd, value, link_order->u.data.contents);
+ link_order->size = SHORT_SIZE;
+ break;
+ case BYTE:
+ bfd_put_8 (output_bfd, value, link_order->u.data.contents);
+ link_order->size = BYTE_SIZE;
+ break;
+ default:
+ abort ();
+ }
+ }
+ break;
+
+ case lang_reloc_statement_enum:
+ {
+ lang_reloc_statement_type *rs;
+ asection *output_section;
+ struct bfd_link_order *link_order;
+
+ rs = &statement->reloc_statement;
+
+ output_section = rs->output_section;
+ ASSERT (output_section->owner == output_bfd);
+
+ link_order = bfd_new_link_order (output_bfd, output_section);
+ if (link_order == NULL)
+ einfo (_("%P%F: bfd_new_link_order failed\n"));
+
+ link_order->offset = rs->output_vma;
+ link_order->size = bfd_get_reloc_size (rs->howto);
+
+ link_order->u.reloc.p =
+ ((struct bfd_link_order_reloc *)
+ xmalloc (sizeof (struct bfd_link_order_reloc)));
+
+ link_order->u.reloc.p->reloc = rs->reloc;
+ link_order->u.reloc.p->addend = rs->addend_value;
+
+ if (rs->name == NULL)
+ {
+ link_order->type = bfd_section_reloc_link_order;
+ if (rs->section->owner == output_bfd)
+ link_order->u.reloc.p->u.section = rs->section;
+ else
+ {
+ link_order->u.reloc.p->u.section = rs->section->output_section;
+ link_order->u.reloc.p->addend += rs->section->output_offset;
+ }
+ }
+ else
+ {
+ link_order->type = bfd_symbol_reloc_link_order;
+ link_order->u.reloc.p->u.name = rs->name;
+ }
+ }
+ break;
+
+ case lang_input_section_enum:
+ /* Create a new link_order in the output section with this
+ attached */
+ if (statement->input_section.ifile->just_syms_flag == false)
+ {
+ asection *i = statement->input_section.section;
+ asection *output_section = i->output_section;
+
+ ASSERT (output_section->owner == output_bfd);
+
+ if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
+ {
+ struct bfd_link_order *link_order;
+
+ link_order = bfd_new_link_order (output_bfd, output_section);
+
+ if (i->flags & SEC_NEVER_LOAD)
+ {
+ /* We've got a never load section inside one which
+ is going to be output, we'll change it into a
+ fill link_order */
+ link_order->type = bfd_fill_link_order;
+ link_order->u.fill.value = 0;
+ }
+ else
+ {
+ link_order->type = bfd_indirect_link_order;
+ link_order->u.indirect.section = i;
+ ASSERT (i->output_section == output_section);
+ }
+ if (i->_cooked_size)
+ link_order->size = i->_cooked_size;
+ else
+ link_order->size = bfd_get_section_size_before_reloc (i);
+ link_order->offset = i->output_offset;
+ }
+ }
+ break;
+
+ case lang_padding_statement_enum:
+ /* Make a new link_order with the right filler */
+ {
+ asection *output_section;
+ struct bfd_link_order *link_order;
+
+ output_section = statement->padding_statement.output_section;
+ ASSERT (statement->padding_statement.output_section->owner
+ == output_bfd);
+ if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
+ {
+ link_order = bfd_new_link_order (output_bfd, output_section);
+ link_order->type = bfd_fill_link_order;
+ link_order->size = statement->padding_statement.size;
+ link_order->offset = statement->padding_statement.output_offset;
+ link_order->u.fill.value = statement->padding_statement.fill;
+ }
+ }
+ break;
+
+ default:
+ /* All the other ones fall through */
+ break;
+ }
+}
+
+/* Call BFD to write out the linked file. */
+
+
+/**********************************************************************/
+
+
+/* Wander around the input sections, make sure that
+ we'll never try and create an output section with more relocs
+ than will fit.. Do this by always assuming the worst case, and
+ creating new output sections with all the right bits */
+#define TESTIT 1
+static asection *
+clone_section (abfd, s, count)
+ bfd *abfd;
+ asection *s;
+ int *count;
+{
+#define SSIZE 8
+ char sname[SSIZE]; /* ?? find the name for this size */
+ asection *n;
+ struct bfd_link_hash_entry *h;
+ /* Invent a section name - use first five
+ chars of base section name and a digit suffix */
+ do
+ {
+ unsigned int i;
+ char b[6];
+ for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
+ b[i] = s->name[i];
+ b[i] = 0;
+ sprintf (sname, "%s%d", b, (*count)++);
+ }
+ while (bfd_get_section_by_name (abfd, sname));
+
+ n = bfd_make_section_anyway (abfd, xstrdup (sname));
+
+ /* Create a symbol of the same name */
+
+ h = bfd_link_hash_lookup (link_info.hash,
+ sname, true, true, false);
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = 0;
+ h->u.def.section = n ;
+
+
+ n->flags = s->flags;
+ n->vma = s->vma;
+ n->user_set_vma = s->user_set_vma;
+ n->lma = s->lma;
+ n->_cooked_size = 0;
+ n->_raw_size = 0;
+ n->output_offset = s->output_offset;
+ n->output_section = n;
+ n->orelocation = 0;
+ n->reloc_count = 0;
+ n->alignment_power = s->alignment_power;
+ return n;
+}
+
+#if TESTING
+static void
+ds (s)
+ asection *s;
+{
+ struct bfd_link_order *l = s->link_order_head;
+ printf ("vma %x size %x\n", s->vma, s->_raw_size);
+ while (l)
+ {
+ if (l->type == bfd_indirect_link_order)
+ {
+ printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
+ }
+ else
+ {
+ printf (_("%8x something else\n"), l->offset);
+ }
+ l = l->next;
+ }
+ printf ("\n");
+}
+dump (s, a1, a2)
+ char *s;
+ asection *a1;
+ asection *a2;
+{
+ printf ("%s\n", s);
+ ds (a1);
+ ds (a2);
+}
+
+static void
+sanity_check (abfd)
+ bfd *abfd;
+{
+ asection *s;
+ for (s = abfd->sections; s; s = s->next)
+ {
+ struct bfd_link_order *p;
+ bfd_vma prev = 0;
+ for (p = s->link_order_head; p; p = p->next)
+ {
+ if (p->offset > 100000)
+ abort ();
+ if (p->offset < prev)
+ abort ();
+ prev = p->offset;
+ }
+ }
+}
+#else
+#define sanity_check(a)
+#define dump(a, b, c)
+#endif
+
+static void
+split_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ asection *original_sec;
+ int nsecs = abfd->section_count;
+ sanity_check (abfd);
+ /* look through all the original sections */
+ for (original_sec = abfd->sections;
+ original_sec && nsecs;
+ original_sec = original_sec->next, nsecs--)
+ {
+ boolean first = true;
+ int count = 0;
+ int lines = 0;
+ int relocs = 0;
+ struct bfd_link_order **pp;
+ bfd_vma vma = original_sec->vma;
+ bfd_vma shift_offset = 0;
+ asection *cursor = original_sec;
+
+ /* count up the relocations and line entries to see if
+ anything would be too big to fit */
+ for (pp = &(cursor->link_order_head); *pp; pp = &((*pp)->next))
+ {
+ struct bfd_link_order *p = *pp;
+ int thislines = 0;
+ int thisrelocs = 0;
+ if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+
+ if (info->strip == strip_none
+ || info->strip == strip_some)
+ thislines = sec->lineno_count;
+
+ if (info->relocateable)
+ thisrelocs = sec->reloc_count;
+
+ }
+ else if (info->relocateable
+ && (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order))
+ thisrelocs++;
+
+ if (! first
+ && (thisrelocs + relocs > config.split_by_reloc
+ || thislines + lines > config.split_by_reloc
+ || config.split_by_file))
+ {
+ /* create a new section and put this link order and the
+ following link orders into it */
+ struct bfd_link_order *l = p;
+ asection *n = clone_section (abfd, cursor, &count);
+ *pp = NULL; /* Snip off link orders from old section */
+ n->link_order_head = l; /* attach to new section */
+ pp = &n->link_order_head;
+
+ /* change the size of the original section and
+ update the vma of the new one */
+
+ dump ("before snip", cursor, n);
+
+ n->_raw_size = cursor->_raw_size - l->offset;
+ cursor->_raw_size = l->offset;
+
+ vma += cursor->_raw_size;
+ n->lma = n->vma = vma;
+
+ shift_offset = l->offset;
+
+ /* run down the chain and change the output section to
+ the right one, update the offsets too */
+
+ while (l)
+ {
+ l->offset -= shift_offset;
+ if (l->type == bfd_indirect_link_order)
+ {
+ l->u.indirect.section->output_section = n;
+ l->u.indirect.section->output_offset = l->offset;
+ }
+ l = l->next;
+ }
+ dump ("after snip", cursor, n);
+ cursor = n;
+ relocs = thisrelocs;
+ lines = thislines;
+ }
+ else
+ {
+ relocs += thisrelocs;
+ lines += thislines;
+ }
+
+ first = false;
+ }
+ }
+ sanity_check (abfd);
+}
+/**********************************************************************/
+void
+ldwrite ()
+{
+ /* Reset error indicator, which can typically something like invalid
+ format from openning up the .o files */
+ bfd_set_error (bfd_error_no_error);
+ lang_for_each_statement (build_link_order);
+
+ if (config.split_by_reloc || config.split_by_file)
+ split_sections (output_bfd, &link_info);
+ if (!bfd_final_link (output_bfd, &link_info))
+ {
+ /* If there was an error recorded, print it out. Otherwise assume
+ an appropriate error message like unknown symbol was printed
+ out. */
+
+ if (bfd_get_error () != bfd_error_no_error)
+ einfo (_("%F%P: final link failed: %E\n"), output_bfd);
+ else
+ xexit(1);
+ }
+}
diff --git a/ld/ldwrite.h b/ld/ldwrite.h
new file mode 100644
index 00000000000..68d8b52db0a
--- /dev/null
+++ b/ld/ldwrite.h
@@ -0,0 +1,20 @@
+/* ldwrite.h -
+ Copyright 1991, 1992, 1993 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+void ldwrite PARAMS ((void));
diff --git a/ld/lexsup.c b/ld/lexsup.c
new file mode 100644
index 00000000000..7ee5087f1ac
--- /dev/null
+++ b/ld/lexsup.c
@@ -0,0 +1,1140 @@
+/* Parse options for the GNU linker.
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "getopt.h"
+#include "bfdlink.h"
+#include "ld.h"
+#include "ldmain.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldgram.h"
+#include "ldlex.h"
+#include "ldfile.h"
+#include "ldver.h"
+#include "ldemul.h"
+
+#ifndef PATH_SEPARATOR
+#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__))
+#define PATH_SEPARATOR ';'
+#else
+#define PATH_SEPARATOR ':'
+#endif
+#endif
+
+/* Somewhere above, sys/stat.h got included . . . . */
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+/* Omit args to avoid the possibility of clashing with a system header
+ that might disagree about consts. */
+unsigned long strtoul ();
+
+static void set_default_dirlist PARAMS ((char *dirlist_ptr));
+static void set_section_start PARAMS ((char *sect, char *valstr));
+static void help PARAMS ((void));
+
+/* Non-zero if we are processing a --defsym from the command line. */
+int parsing_defsym = 0;
+
+/* Codes used for the long options with no short synonyms. 150 isn't
+ special; it's just an arbitrary non-ASCII char value. */
+
+#define OPTION_ASSERT 150
+#define OPTION_CALL_SHARED (OPTION_ASSERT + 1)
+#define OPTION_CREF (OPTION_CALL_SHARED + 1)
+#define OPTION_DEFSYM (OPTION_CREF + 1)
+#define OPTION_DEMANGLE (OPTION_DEFSYM + 1)
+#define OPTION_DYNAMIC_LINKER (OPTION_DEMANGLE + 1)
+#define OPTION_EB (OPTION_DYNAMIC_LINKER + 1)
+#define OPTION_EL (OPTION_EB + 1)
+#define OPTION_EMBEDDED_RELOCS (OPTION_EL + 1)
+#define OPTION_EXPORT_DYNAMIC (OPTION_EMBEDDED_RELOCS + 1)
+#define OPTION_HELP (OPTION_EXPORT_DYNAMIC + 1)
+#define OPTION_IGNORE (OPTION_HELP + 1)
+#define OPTION_MAP (OPTION_IGNORE + 1)
+#define OPTION_NO_DEMANGLE (OPTION_MAP + 1)
+#define OPTION_NO_KEEP_MEMORY (OPTION_NO_DEMANGLE + 1)
+#define OPTION_NO_WARN_MISMATCH (OPTION_NO_KEEP_MEMORY + 1)
+#define OPTION_NOINHIBIT_EXEC (OPTION_NO_WARN_MISMATCH + 1)
+#define OPTION_NON_SHARED (OPTION_NOINHIBIT_EXEC + 1)
+#define OPTION_NO_WHOLE_ARCHIVE (OPTION_NON_SHARED + 1)
+#define OPTION_OFORMAT (OPTION_NO_WHOLE_ARCHIVE + 1)
+#define OPTION_RELAX (OPTION_OFORMAT + 1)
+#define OPTION_RETAIN_SYMBOLS_FILE (OPTION_RELAX + 1)
+#define OPTION_RPATH (OPTION_RETAIN_SYMBOLS_FILE + 1)
+#define OPTION_RPATH_LINK (OPTION_RPATH + 1)
+#define OPTION_SHARED (OPTION_RPATH_LINK + 1)
+#define OPTION_SONAME (OPTION_SHARED + 1)
+#define OPTION_SORT_COMMON (OPTION_SONAME + 1)
+#define OPTION_STATS (OPTION_SORT_COMMON + 1)
+#define OPTION_SYMBOLIC (OPTION_STATS + 1)
+#define OPTION_TASK_LINK (OPTION_SYMBOLIC + 1)
+#define OPTION_TBSS (OPTION_TASK_LINK + 1)
+#define OPTION_TDATA (OPTION_TBSS + 1)
+#define OPTION_TTEXT (OPTION_TDATA + 1)
+#define OPTION_TRADITIONAL_FORMAT (OPTION_TTEXT + 1)
+#define OPTION_UR (OPTION_TRADITIONAL_FORMAT + 1)
+#define OPTION_VERBOSE (OPTION_UR + 1)
+#define OPTION_VERSION (OPTION_VERBOSE + 1)
+#define OPTION_VERSION_SCRIPT (OPTION_VERSION + 1)
+#define OPTION_VERSION_EXPORTS_SECTION (OPTION_VERSION_SCRIPT + 1)
+#define OPTION_WARN_COMMON (OPTION_VERSION_EXPORTS_SECTION + 1)
+#define OPTION_WARN_CONSTRUCTORS (OPTION_WARN_COMMON + 1)
+#define OPTION_WARN_MULTIPLE_GP (OPTION_WARN_CONSTRUCTORS + 1)
+#define OPTION_WARN_ONCE (OPTION_WARN_MULTIPLE_GP + 1)
+#define OPTION_WARN_SECTION_ALIGN (OPTION_WARN_ONCE + 1)
+#define OPTION_SPLIT_BY_RELOC (OPTION_WARN_SECTION_ALIGN + 1)
+#define OPTION_SPLIT_BY_FILE (OPTION_SPLIT_BY_RELOC + 1)
+#define OPTION_WHOLE_ARCHIVE (OPTION_SPLIT_BY_FILE + 1)
+#define OPTION_WRAP (OPTION_WHOLE_ARCHIVE + 1)
+#define OPTION_FORCE_EXE_SUFFIX (OPTION_WRAP + 1)
+#define OPTION_GC_SECTIONS (OPTION_FORCE_EXE_SUFFIX + 1)
+#define OPTION_NO_GC_SECTIONS (OPTION_GC_SECTIONS + 1)
+#define OPTION_CHECK_SECTIONS (OPTION_NO_GC_SECTIONS + 1)
+#define OPTION_NO_CHECK_SECTIONS (OPTION_CHECK_SECTIONS + 1)
+#define OPTION_MPC860C0 (OPTION_NO_CHECK_SECTIONS + 1)
+#define OPTION_NO_UNDEFINED (OPTION_MPC860C0 + 1)
+
+/* The long options. This structure is used for both the option
+ parsing and the help text. */
+
+struct ld_option
+{
+ /* The long option information. */
+ struct option opt;
+ /* The short option with the same meaning ('\0' if none). */
+ char shortopt;
+ /* The name of the argument (NULL if none). */
+ const char *arg;
+ /* The documentation string. If this is NULL, this is a synonym for
+ the previous option. */
+ const char *doc;
+ enum
+ {
+ /* Use one dash before long option name. */
+ ONE_DASH,
+ /* Use two dashes before long option name. */
+ TWO_DASHES,
+ /* Don't mention this option in --help output. */
+ NO_HELP
+ } control;
+};
+
+static const struct ld_option ld_options[] =
+{
+ { {NULL, required_argument, NULL, '\0'},
+ 'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"),
+ ONE_DASH },
+ { {"architecture", required_argument, NULL, 'A'},
+ 'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES },
+ { {"format", required_argument, NULL, 'b'},
+ 'b', N_("TARGET"), N_("Specify target for following input files"), TWO_DASHES },
+ { {"mri-script", required_argument, NULL, 'c'},
+ 'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES },
+ { {"dc", no_argument, NULL, 'd'},
+ 'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
+ { {"dp", no_argument, NULL, 'd'},
+ '\0', NULL, NULL, ONE_DASH },
+ { {"entry", required_argument, NULL, 'e'},
+ 'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES },
+ { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC},
+ 'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES },
+ { {"EB", no_argument, NULL, OPTION_EB},
+ '\0', NULL, N_("Link big-endian objects"), ONE_DASH },
+ { {"EL", no_argument, NULL, OPTION_EL},
+ '\0', NULL, N_("Link little-endian objects"), ONE_DASH },
+ { {"auxiliary", required_argument, NULL, 'f'},
+ 'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"),
+ TWO_DASHES },
+ { {"filter", required_argument, NULL, 'F'},
+ 'F', N_("SHLIB"), N_("Filter for shared object symbol table"), TWO_DASHES },
+ { {NULL, no_argument, NULL, '\0'},
+ 'g', NULL, N_("Ignored"), ONE_DASH },
+ { {"gpsize", required_argument, NULL, 'G'},
+ 'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"),
+ TWO_DASHES },
+ { {"soname", required_argument, NULL, OPTION_SONAME},
+ 'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH },
+ { {"library", required_argument, NULL, 'l'},
+ 'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES },
+ { {"library-path", required_argument, NULL, 'L'},
+ 'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"), TWO_DASHES },
+ { {NULL, required_argument, NULL, '\0'},
+ 'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH },
+ { {"print-map", no_argument, NULL, 'M'},
+ 'M', NULL, N_("Print map file on standard output"), TWO_DASHES },
+ { {"nmagic", no_argument, NULL, 'n'},
+ 'n', NULL, N_("Do not page align data"), TWO_DASHES },
+ { {"omagic", no_argument, NULL, 'N'},
+ 'N', NULL, N_("Do not page align data, do not make text readonly"),
+ TWO_DASHES },
+ { {"output", required_argument, NULL, 'o'},
+ 'o', N_("FILE"), N_("Set output file name"), TWO_DASHES },
+ { {NULL, required_argument, NULL, '\0'},
+ 'O', NULL, N_("Optimize output file"), ONE_DASH },
+ { {"Qy", no_argument, NULL, OPTION_IGNORE},
+ '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
+ { {"relocateable", no_argument, NULL, 'r'},
+ 'r', NULL, N_("Generate relocateable output"), TWO_DASHES },
+ { {NULL, no_argument, NULL, '\0'},
+ 'i', NULL, NULL, ONE_DASH },
+ { {"just-symbols", required_argument, NULL, 'R'},
+ 'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"),
+ TWO_DASHES },
+ { {"strip-all", no_argument, NULL, 's'},
+ 's', NULL, N_("Strip all symbols"), TWO_DASHES },
+ { {"strip-debug", no_argument, NULL, 'S'},
+ 'S', NULL, N_("Strip debugging symbols"), TWO_DASHES },
+ { {"trace", no_argument, NULL, 't'},
+ 't', NULL, N_("Trace file opens"), TWO_DASHES },
+ { {"script", required_argument, NULL, 'T'},
+ 'T', N_("FILE"), N_("Read linker script"), TWO_DASHES },
+ { {"undefined", required_argument, NULL, 'u'},
+ 'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), TWO_DASHES },
+ { {"Ur", no_argument, NULL, OPTION_UR},
+ '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH },
+ { {"version", no_argument, NULL, OPTION_VERSION},
+ 'v', NULL, N_("Print version information"), TWO_DASHES },
+ { {NULL, no_argument, NULL, '\0'},
+ 'V', NULL, N_("Print version and emulation information"), ONE_DASH },
+ { {"discard-all", no_argument, NULL, 'x'},
+ 'x', NULL, N_("Discard all local symbols"), TWO_DASHES },
+ { {"discard-locals", no_argument, NULL, 'X'},
+ 'X', NULL, N_("Discard temporary local symbols"), TWO_DASHES },
+ { {"trace-symbol", required_argument, NULL, 'y'},
+ 'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES },
+ { {NULL, required_argument, NULL, '\0'},
+ 'Y', N_("PATH"), N_("Default search path for Solaris compatibility"), ONE_DASH },
+ { {NULL, required_argument, NULL, '\0'},
+ 'z', N_("KEYWORD"), N_("Ignored for Solaris compatibility"), ONE_DASH },
+ { {"start-group", no_argument, NULL, '('},
+ '(', NULL, N_("Start a group"), TWO_DASHES },
+ { {"end-group", no_argument, NULL, ')'},
+ ')', NULL, N_("End a group"), TWO_DASHES },
+ { {"assert", required_argument, NULL, OPTION_ASSERT},
+ '\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH },
+ { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED},
+ '\0', NULL, N_("Link against shared libraries"), ONE_DASH },
+ { {"dy", no_argument, NULL, OPTION_CALL_SHARED},
+ '\0', NULL, NULL, ONE_DASH },
+ { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},
+ '\0', NULL, NULL, ONE_DASH },
+ { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED},
+ '\0', NULL, N_("Do not link against shared libraries"), ONE_DASH },
+ { {"dn", no_argument, NULL, OPTION_NON_SHARED},
+ '\0', NULL, NULL, ONE_DASH },
+ { {"non_shared", no_argument, NULL, OPTION_NON_SHARED},
+ '\0', NULL, NULL, ONE_DASH },
+ { {"static", no_argument, NULL, OPTION_NON_SHARED},
+ '\0', NULL, NULL, ONE_DASH },
+ { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC},
+ '\0', NULL, N_("Bind global references locally"), ONE_DASH },
+ { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS},
+ '\0', NULL, N_("Check section addresses for overlaps (default)"), TWO_DASHES },
+ { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS},
+ '\0', NULL, N_("Do not check section addresses for overlaps"),
+ TWO_DASHES },
+ { {"cref", no_argument, NULL, OPTION_CREF},
+ '\0', NULL, N_("Output cross reference table"), TWO_DASHES },
+ { {"defsym", required_argument, NULL, OPTION_DEFSYM},
+ '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES },
+ { {"demangle", no_argument, NULL, OPTION_DEMANGLE},
+ '\0', NULL, N_("Demangle symbol names"), TWO_DASHES },
+ { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER},
+ '\0', N_("PROGRAM"), N_("Set the dynamic linker to use"), TWO_DASHES },
+ { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS},
+ '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES},
+ { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX},
+ '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES},
+ { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS},
+ '\0', NULL, N_("Remove unused sections (on some targets)"),
+ TWO_DASHES },
+ { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
+ '\0', NULL, N_("Don't remove unused sections (default)"),
+ TWO_DASHES },
+ { {"help", no_argument, NULL, OPTION_HELP},
+ '\0', NULL, N_("Print option help"), TWO_DASHES },
+ { {"Map", required_argument, NULL, OPTION_MAP},
+ '\0', N_("FILE"), N_("Write a map file"), ONE_DASH },
+ { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE },
+ '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES },
+ { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY},
+ '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES },
+ { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
+ '\0', NULL, N_("Allow no undefined symbols"), TWO_DASHES },
+ { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH},
+ '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES},
+ { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE},
+ '\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES },
+ { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
+ '\0', NULL, N_("Create an output file even if errors occur"), TWO_DASHES },
+ { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC},
+ '\0', NULL, NULL, NO_HELP },
+ { {"oformat", required_argument, NULL, OPTION_OFORMAT},
+ '\0', N_("TARGET"), N_("Specify target of output file"), TWO_DASHES },
+ { {"qmagic", no_argument, NULL, OPTION_IGNORE},
+ '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH },
+ { {"relax", no_argument, NULL, OPTION_RELAX},
+ '\0', NULL, N_("Relax branches on certain targets"), TWO_DASHES },
+ { {"retain-symbols-file", required_argument, NULL,
+ OPTION_RETAIN_SYMBOLS_FILE},
+ '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
+ { {"rpath", required_argument, NULL, OPTION_RPATH},
+ '\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH },
+ { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK},
+ '\0', N_("PATH"), N_("Set link time shared library search path"), ONE_DASH },
+ { {"shared", no_argument, NULL, OPTION_SHARED},
+ '\0', NULL, N_("Create a shared library"), ONE_DASH },
+ { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD. */
+ '\0', NULL, NULL, ONE_DASH },
+ { {"sort-common", no_argument, NULL, OPTION_SORT_COMMON},
+ '\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
+ { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
+ '\0', NULL, NULL, NO_HELP },
+ { {"split-by-file", no_argument, NULL, OPTION_SPLIT_BY_FILE},
+ '\0', NULL, N_("Split output sections for each file"), TWO_DASHES },
+ { {"split-by-reloc", required_argument, NULL, OPTION_SPLIT_BY_RELOC},
+ '\0', N_("COUNT"), N_("Split output sections every COUNT relocs"), TWO_DASHES },
+ { {"stats", no_argument, NULL, OPTION_STATS},
+ '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES },
+ { {"task-link", required_argument, NULL, OPTION_TASK_LINK},
+ '\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES },
+ { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
+ '\0', NULL, N_("Use same format as native linker"), TWO_DASHES },
+ { {"Tbss", required_argument, NULL, OPTION_TBSS},
+ '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH },
+ { {"Tdata", required_argument, NULL, OPTION_TDATA},
+ '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH },
+ { {"Ttext", required_argument, NULL, OPTION_TTEXT},
+ '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH },
+ { {"verbose", no_argument, NULL, OPTION_VERBOSE},
+ '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
+ { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux. */
+ '\0', NULL, NULL, NO_HELP },
+ { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
+ '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES },
+ { {"version-exports-section", required_argument, NULL,
+ OPTION_VERSION_EXPORTS_SECTION },
+ '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using SYMBOL as the version."),
+ TWO_DASHES },
+ { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
+ '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
+ { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
+ '\0', NULL, N_("Warn if global constructors/destructors are seen"),
+ TWO_DASHES },
+ { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP},
+ '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES },
+ { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE},
+ '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES },
+ { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN},
+ '\0', NULL, N_("Warn if start of section changes due to alignment"),
+ TWO_DASHES },
+ { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE},
+ '\0', NULL, N_("Include all objects from following archives"), TWO_DASHES },
+ { {"wrap", required_argument, NULL, OPTION_WRAP},
+ '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
+ { {"mpc860c0", optional_argument, NULL, OPTION_MPC860C0},
+ '\0', N_("[=WORDS]"), N_("Modify problematic branches in last WORDS (1-10, default 5) words of a page"), TWO_DASHES }
+};
+
+#define OPTION_COUNT ((int) (sizeof ld_options / sizeof ld_options[0]))
+
+/* Test "string" for containing a string of digits that form a number
+between "min" and "max". The return value is the number or "err". */
+static
+int is_num( char *string, int min, int max, int err)
+{
+ int result = 0;
+
+ for ( ; *string; ++string)
+ {
+ if (!isdigit(*string))
+ {
+ result = err;
+ break;
+ }
+ result = result * 10 + (*string - '0');
+ }
+ if (result < min || result > max)
+ result = err;
+
+ return result;
+}
+
+void
+parse_args (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i, is, il;
+ int ingroup = 0;
+ char *default_dirlist = NULL;
+ char shortopts[OPTION_COUNT * 3 + 2];
+ struct option longopts[OPTION_COUNT + 1];
+ int last_optind;
+
+ /* Starting the short option string with '-' is for programs that
+ expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1. */
+ shortopts[0] = '-';
+ is = 1;
+ il = 0;
+ for (i = 0; i < OPTION_COUNT; i++)
+ {
+ if (ld_options[i].shortopt != '\0')
+ {
+ shortopts[is] = ld_options[i].shortopt;
+ ++is;
+ if (ld_options[i].opt.has_arg == required_argument
+ || ld_options[i].opt.has_arg == optional_argument)
+ {
+ shortopts[is] = ':';
+ ++is;
+ if (ld_options[i].opt.has_arg == optional_argument)
+ {
+ shortopts[is] = ':';
+ ++is;
+ }
+ }
+ }
+ if (ld_options[i].opt.name != NULL)
+ {
+ longopts[il] = ld_options[i].opt;
+ ++il;
+ }
+ }
+ shortopts[is] = '\0';
+ longopts[il].name = NULL;
+
+ /* The -G option is ambiguous on different platforms. Sometimes it
+ specifies the largest data size to put into the small data
+ section. Sometimes it is equivalent to --shared. Unfortunately,
+ the first form takes an argument, while the second does not.
+
+ We need to permit the --shared form because on some platforms,
+ such as Solaris, gcc -shared will pass -G to the linker.
+
+ To permit either usage, we look through the argument list. If we
+ find -G not followed by a number, we change it into --shared.
+ This will work for most normal cases. */
+ for (i = 1; i < argc; i++)
+ if (strcmp (argv[i], "-G") == 0
+ && (i + 1 >= argc
+ || ! isdigit ((unsigned char) argv[i + 1][0])))
+ argv[i] = (char *) "--shared";
+
+ /* Because we permit long options to start with a single dash, and
+ we have a --library option, and the -l option is conventionally
+ used with an immediately following argument, we can have bad
+ results if somebody tries to use -l with a library whose name
+ happens to start with "ibrary", as in -li. We avoid problems by
+ simply turning -l into --library. This means that users will
+ have to use two dashes in order to use --library, which is OK
+ since that's how it is documented.
+
+ FIXME: It's possible that this problem can arise for other short
+ options as well, although the user does always have the recourse
+ of adding a space between the option and the argument. */
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == '-'
+ && argv[i][1] == 'l'
+ && argv[i][2] != '\0')
+ {
+ char *n;
+
+ n = (char *) xmalloc (strlen (argv[i]) + 20);
+ sprintf (n, "--library=%s", argv[i] + 2);
+ argv[i] = n;
+ }
+ }
+
+ last_optind = -1;
+ while (1)
+ {
+ int longind;
+ int optc;
+
+ /* Using last_optind lets us avoid calling ldemul_parse_args
+ multiple times on a single option, which would lead to
+ confusion in the internal static variables maintained by
+ getopt. This could otherwise happen for an argument like
+ -nx, in which the -n is parsed as a single option, and we
+ loop around to pick up the -x. */
+ if (optind != last_optind)
+ {
+ if (ldemul_parse_args (argc, argv))
+ continue;
+ last_optind = optind;
+ }
+
+ /* getopt_long_only is like getopt_long, but '-' as well as '--'
+ can indicate a long option. */
+ optc = getopt_long_only (argc, argv, shortopts, longopts, &longind);
+
+ if (optc == -1)
+ break;
+ switch (optc)
+ {
+ default:
+ xexit (1);
+ case 1: /* File name. */
+ lang_add_input_file (optarg, lang_input_file_is_file_enum,
+ (char *) NULL);
+ break;
+
+ case OPTION_IGNORE:
+ break;
+ case 'a':
+ /* For HP/UX compatibility. Actually -a shared should mean
+ ``use only shared libraries'' but, then, we don't
+ currently support shared libraries on HP/UX anyhow. */
+ if (strcmp (optarg, "archive") == 0)
+ config.dynamic_link = false;
+ else if (strcmp (optarg, "shared") == 0
+ || strcmp (optarg, "default") == 0)
+ config.dynamic_link = true;
+ else
+ einfo (_("%P%F: unrecognized -a option `%s'\n"), optarg);
+ break;
+ case OPTION_ASSERT:
+ /* FIXME: We just ignore these, but we should handle them. */
+ if (strcmp (optarg, "definitions") == 0)
+ ;
+ else if (strcmp (optarg, "nodefinitions") == 0)
+ ;
+ else if (strcmp (optarg, "nosymbolic") == 0)
+ ;
+ else if (strcmp (optarg, "pure-text") == 0)
+ ;
+ else
+ einfo (_("%P%F: unrecognized -assert option `%s'\n"), optarg);
+ break;
+ case 'A':
+ ldfile_add_arch (optarg);
+ break;
+ case 'b':
+ lang_add_target (optarg);
+ break;
+ case 'c':
+ ldfile_open_command_file (optarg);
+ parser_input = input_mri_script;
+ yyparse ();
+ break;
+ case OPTION_CALL_SHARED:
+ config.dynamic_link = true;
+ break;
+ case OPTION_NON_SHARED:
+ config.dynamic_link = false;
+ break;
+ case OPTION_CREF:
+ command_line.cref = true;
+ link_info.notice_all = true;
+ break;
+ case 'd':
+ command_line.force_common_definition = true;
+ break;
+ case OPTION_DEFSYM:
+ lex_string = optarg;
+ lex_redirect (optarg);
+ parser_input = input_defsym;
+ parsing_defsym = 1;
+ yyparse ();
+ parsing_defsym = 0;
+ lex_string = NULL;
+ break;
+ case OPTION_DEMANGLE:
+ demangling = true;
+ break;
+ case OPTION_DYNAMIC_LINKER:
+ command_line.interpreter = optarg;
+ break;
+ case OPTION_EB:
+ command_line.endian = ENDIAN_BIG;
+ break;
+ case OPTION_EL:
+ command_line.endian = ENDIAN_LITTLE;
+ break;
+ case OPTION_EMBEDDED_RELOCS:
+ command_line.embedded_relocs = true;
+ break;
+ case OPTION_EXPORT_DYNAMIC:
+ case 'E': /* HP/UX compatibility. */
+ command_line.export_dynamic = true;
+ break;
+ case 'e':
+ lang_add_entry (optarg, true);
+ break;
+ case 'f':
+ if (command_line.auxiliary_filters == NULL)
+ {
+ command_line.auxiliary_filters =
+ (char **) xmalloc (2 * sizeof (char *));
+ command_line.auxiliary_filters[0] = optarg;
+ command_line.auxiliary_filters[1] = NULL;
+ }
+ else
+ {
+ int c;
+ char **p;
+
+ c = 0;
+ for (p = command_line.auxiliary_filters; *p != NULL; p++)
+ ++c;
+ command_line.auxiliary_filters =
+ (char **) xrealloc (command_line.auxiliary_filters,
+ (c + 2) * sizeof (char *));
+ command_line.auxiliary_filters[c] = optarg;
+ command_line.auxiliary_filters[c + 1] = NULL;
+ }
+ break;
+ case 'F':
+ command_line.filter_shlib = optarg;
+ break;
+ case OPTION_FORCE_EXE_SUFFIX:
+ command_line.force_exe_suffix = true;
+ break;
+ case 'G':
+ {
+ char *end;
+ g_switch_value = strtoul (optarg, &end, 0);
+ if (*end)
+ einfo (_("%P%F: invalid number `%s'\n"), optarg);
+ }
+ break;
+ case 'g':
+ /* Ignore. */
+ break;
+ case OPTION_GC_SECTIONS:
+ command_line.gc_sections = true;
+ break;
+ case OPTION_HELP:
+ help ();
+ xexit (0);
+ break;
+ case 'L':
+ ldfile_add_library_path (optarg, true);
+ break;
+ case 'l':
+ lang_add_input_file (optarg, lang_input_file_is_l_enum,
+ (char *) NULL);
+ break;
+ case 'M':
+ config.map_filename = "-";
+ break;
+ case 'm':
+ /* Ignore. Was handled in a pre-parse. */
+ break;
+ case OPTION_MAP:
+ config.map_filename = optarg;
+ break;
+ case 'N':
+ config.text_read_only = false;
+ config.magic_demand_paged = false;
+ config.dynamic_link = false;
+ break;
+ case 'n':
+ config.magic_demand_paged = false;
+ config.dynamic_link = false;
+ break;
+ case OPTION_NO_DEMANGLE:
+ demangling = false;
+ break;
+ case OPTION_NO_GC_SECTIONS:
+ command_line.gc_sections = false;
+ break;
+ case OPTION_NO_KEEP_MEMORY:
+ link_info.keep_memory = false;
+ break;
+ case OPTION_NO_UNDEFINED:
+ link_info.no_undefined = true;
+ break;
+ case OPTION_NO_WARN_MISMATCH:
+ command_line.warn_mismatch = false;
+ break;
+ case OPTION_NOINHIBIT_EXEC:
+ force_make_executable = true;
+ break;
+ case OPTION_NO_WHOLE_ARCHIVE:
+ whole_archive = false;
+ break;
+ case 'O':
+ /* FIXME "-O<non-digits> <value>" used to set the address of
+ section <non-digits>. Was this for compatibility with
+ something, or can we create a new option to do that
+ (with a syntax similar to -defsym)?
+ getopt can't handle two args to an option without kludges. */
+
+ /* Enable optimizations of output files. */
+ link_info.optimize = strtoul (optarg, NULL, 0) ? true : false;
+ break;
+ case 'o':
+ lang_add_output (optarg, 0);
+ break;
+ case OPTION_OFORMAT:
+ lang_add_output_format (optarg, (char *) NULL, (char *) NULL, 0);
+ break;
+ case 'i':
+ case 'r':
+ link_info.relocateable = true;
+ config.build_constructors = false;
+ config.magic_demand_paged = false;
+ config.text_read_only = false;
+ config.dynamic_link = false;
+ break;
+ case 'R':
+ /* The GNU linker traditionally uses -R to mean to include
+ only the symbols from a file. The Solaris linker uses -R
+ to set the path used by the runtime linker to find
+ libraries. This is the GNU linker -rpath argument. We
+ try to support both simultaneously by checking the file
+ named. If it is a directory, rather than a regular file,
+ we assume -rpath was meant. */
+ {
+ struct stat s;
+
+ if (stat (optarg, &s) >= 0
+ && ! S_ISDIR (s.st_mode))
+ {
+ lang_add_input_file (optarg,
+ lang_input_file_is_symbols_only_enum,
+ (char *) NULL);
+ break;
+ }
+ }
+ /* Fall through. */
+ case OPTION_RPATH:
+ if (command_line.rpath == NULL)
+ command_line.rpath = buystring (optarg);
+ else
+ {
+ size_t rpath_len = strlen (command_line.rpath);
+ size_t optarg_len = strlen (optarg);
+ char *buf;
+ char *cp = command_line.rpath;
+
+ /* First see whether OPTARG is already in the path. */
+ do
+ {
+ size_t idx = 0;
+ while (optarg[idx] != '\0' && optarg[idx] == cp[idx])
+ ++idx;
+ if (optarg[idx] == '\0'
+ && (cp[idx] == '\0' || cp[idx] == ':'))
+ /* We found it. */
+ break;
+
+ /* Not yet found. */
+ cp = strchr (cp, ':');
+ if (cp != NULL)
+ ++cp;
+ }
+ while (cp != NULL);
+
+ if (cp == NULL)
+ {
+ buf = xmalloc (rpath_len + optarg_len + 2);
+ sprintf (buf, "%s:%s", command_line.rpath, optarg);
+ free (command_line.rpath);
+ command_line.rpath = buf;
+ }
+ }
+ break;
+ case OPTION_RPATH_LINK:
+ if (command_line.rpath_link == NULL)
+ command_line.rpath_link = buystring (optarg);
+ else
+ {
+ char *buf;
+
+ buf = xmalloc (strlen (command_line.rpath_link)
+ + strlen (optarg)
+ + 2);
+ sprintf (buf, "%s:%s", command_line.rpath_link, optarg);
+ free (command_line.rpath_link);
+ command_line.rpath_link = buf;
+ }
+ break;
+ case OPTION_RELAX:
+ command_line.relax = true;
+ break;
+ case OPTION_RETAIN_SYMBOLS_FILE:
+ add_keepsyms_file (optarg);
+ break;
+ case 'S':
+ link_info.strip = strip_debugger;
+ break;
+ case 's':
+ link_info.strip = strip_all;
+ break;
+ case OPTION_SHARED:
+ if (config.has_shared)
+ link_info.shared = true;
+ else
+ einfo (_("%P%F: -shared not supported\n"));
+ break;
+ case 'h': /* Used on Solaris. */
+ case OPTION_SONAME:
+ command_line.soname = optarg;
+ break;
+ case OPTION_SORT_COMMON:
+ config.sort_common = true;
+ break;
+ case OPTION_STATS:
+ config.stats = true;
+ break;
+ case OPTION_SYMBOLIC:
+ link_info.symbolic = true;
+ break;
+ case 't':
+ trace_files = true;
+ break;
+ case 'T':
+ ldfile_open_command_file (optarg);
+ parser_input = input_script;
+ yyparse ();
+ break;
+ case OPTION_TBSS:
+ set_section_start (".bss", optarg);
+ break;
+ case OPTION_TDATA:
+ set_section_start (".data", optarg);
+ break;
+ case OPTION_TTEXT:
+ set_section_start (".text", optarg);
+ break;
+ case OPTION_TRADITIONAL_FORMAT:
+ link_info.traditional_format = true;
+ break;
+ case OPTION_TASK_LINK:
+ link_info.task_link = true;
+ /* Fall through - do an implied -r option. */
+ case OPTION_UR:
+ link_info.relocateable = true;
+ config.build_constructors = true;
+ config.magic_demand_paged = false;
+ config.text_read_only = false;
+ config.dynamic_link = false;
+ break;
+ case 'u':
+ ldlang_add_undef (optarg);
+ break;
+ case OPTION_VERBOSE:
+ ldversion (1);
+ version_printed = true;
+ trace_file_tries = true;
+ break;
+ case 'v':
+ ldversion (0);
+ version_printed = true;
+ break;
+ case 'V':
+ ldversion (1);
+ version_printed = true;
+ break;
+ case OPTION_VERSION:
+ /* This output is intended to follow the GNU standards document. */
+ printf ("GNU ld %s\n", ld_program_version);
+ printf (_("Copyright 1997 Free Software Foundation, Inc.\n"));
+ printf (_("\
+This program is free software; you may redistribute it under the terms of\n\
+the GNU General Public License. This program has absolutely no warranty.\n"));
+ {
+ ld_emulation_xfer_type **ptr = ld_emulations;
+
+ printf (_(" Supported emulations:\n"));
+ while (*ptr)
+ {
+ printf (" %s\n", (*ptr)->emulation_name);
+ ptr++;
+ }
+ }
+ xexit (0);
+ break;
+ case OPTION_VERSION_SCRIPT:
+ /* This option indicates a small script that only specifies
+ version information. Read it, but don't assume that
+ we've seen a linker script. */
+ {
+ boolean hold_had_script;
+
+ hold_had_script = had_script;
+ ldfile_open_command_file (optarg);
+ had_script = hold_had_script;
+ parser_input = input_version_script;
+ yyparse ();
+ }
+ break;
+ case OPTION_VERSION_EXPORTS_SECTION:
+ /* This option records a version symbol to be applied to the
+ symbols listed for export to be found in the object files
+ .exports sections. */
+ command_line.version_exports_section = optarg;
+ break;
+ case OPTION_WARN_COMMON:
+ config.warn_common = true;
+ break;
+ case OPTION_WARN_CONSTRUCTORS:
+ config.warn_constructors = true;
+ break;
+ case OPTION_WARN_MULTIPLE_GP:
+ config.warn_multiple_gp = true;
+ break;
+ case OPTION_WARN_ONCE:
+ config.warn_once = true;
+ break;
+ case OPTION_WARN_SECTION_ALIGN:
+ config.warn_section_align = true;
+ break;
+ case OPTION_WHOLE_ARCHIVE:
+ whole_archive = true;
+ break;
+ case OPTION_WRAP:
+ add_wrap (optarg);
+ break;
+ case 'X':
+ link_info.discard = discard_l;
+ break;
+ case 'x':
+ link_info.discard = discard_all;
+ break;
+ case 'Y':
+ if (strncmp (optarg, "P,", 2) == 0)
+ optarg += 2;
+ default_dirlist = xstrdup (optarg);
+ break;
+ case 'y':
+ add_ysym (optarg);
+ break;
+ case 'z':
+ /* We accept and ignore this option for Solaris
+ compatibility. Actually, on Solaris, optarg is not
+ ignored. Someday we should handle it correctly. FIXME. */
+ break;
+ case OPTION_SPLIT_BY_RELOC:
+ config.split_by_reloc = atoi (optarg);
+ break;
+ case OPTION_SPLIT_BY_FILE:
+ config.split_by_file = true;
+ break;
+ case OPTION_CHECK_SECTIONS:
+ command_line.check_section_addresses = true;
+ break;
+ case OPTION_NO_CHECK_SECTIONS:
+ command_line.check_section_addresses = false;
+ break;
+ case '(':
+ if (ingroup)
+ {
+ fprintf (stderr,
+ _("%s: may not nest groups (--help for usage)\n"),
+ program_name);
+ xexit (1);
+ }
+ lang_enter_group ();
+ ingroup = 1;
+ break;
+ case ')':
+ if (! ingroup)
+ {
+ fprintf (stderr,
+ _("%s: group ended before it began (--help for usage)\n"),
+ program_name);
+ xexit (1);
+ }
+ lang_leave_group ();
+ ingroup = 0;
+ break;
+ case OPTION_MPC860C0:
+ link_info.mpc860c0 = 20; /* default value (in bytes) */
+ if (optarg)
+ {
+ unsigned words;
+
+ words = is_num (optarg, 1, 10, 0);
+ if (words == 0)
+ {
+ fprintf (stderr, _("Invalid argument to option \"mpc860c0\"\n"));
+ xexit (1);
+ }
+ link_info.mpc860c0 = words * 4; /* convert words to bytes */
+ }
+ command_line.relax = true;
+ break;
+ }
+ }
+
+ if (ingroup)
+ lang_leave_group ();
+
+ if (default_dirlist != NULL)
+ set_default_dirlist (default_dirlist);
+
+}
+
+/* Add the (colon-separated) elements of DIRLIST_PTR to the
+ library search path. */
+
+static void
+set_default_dirlist (dirlist_ptr)
+ char *dirlist_ptr;
+{
+ char *p;
+
+ while (1)
+ {
+ p = strchr (dirlist_ptr, PATH_SEPARATOR);
+ if (p != NULL)
+ *p = '\0';
+ if (*dirlist_ptr != '\0')
+ ldfile_add_library_path (dirlist_ptr, true);
+ if (p == NULL)
+ break;
+ dirlist_ptr = p + 1;
+ }
+}
+
+static void
+set_section_start (sect, valstr)
+ char *sect, *valstr;
+{
+ char *end;
+ unsigned long val = strtoul (valstr, &end, 16);
+ if (*end)
+ einfo (_("%P%F: invalid hex number `%s'\n"), valstr);
+ lang_section_start (sect, exp_intop (val));
+}
+
+/* Print help messages for the options. */
+
+static void
+help ()
+{
+ int i;
+ const char **targets, **pp;
+
+ printf (_("Usage: %s [options] file...\n"), program_name);
+
+ printf (_("Options:\n"));
+ for (i = 0; i < OPTION_COUNT; i++)
+ {
+ if (ld_options[i].doc != NULL)
+ {
+ boolean comma;
+ int len;
+ int j;
+
+ printf (" ");
+
+ comma = false;
+ len = 2;
+
+ j = i;
+ do
+ {
+ if (ld_options[j].shortopt != '\0'
+ && ld_options[j].control != NO_HELP)
+ {
+ printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt);
+ len += (comma ? 2 : 0) + 2;
+ if (ld_options[j].arg != NULL)
+ {
+ if (ld_options[j].opt.has_arg != optional_argument)
+ {
+ printf (" ");
+ ++len;
+ }
+ printf ("%s", _(ld_options[j].arg));
+ len += strlen (_(ld_options[j].arg));
+ }
+ comma = true;
+ }
+ ++j;
+ }
+ while (j < OPTION_COUNT && ld_options[j].doc == NULL);
+
+ j = i;
+ do
+ {
+ if (ld_options[j].opt.name != NULL
+ && ld_options[j].control != NO_HELP)
+ {
+ printf ("%s-%s%s",
+ comma ? ", " : "",
+ ld_options[j].control == TWO_DASHES ? "-" : "",
+ ld_options[j].opt.name);
+ len += ((comma ? 2 : 0)
+ + 1
+ + (ld_options[j].control == TWO_DASHES ? 1 : 0)
+ + strlen (ld_options[j].opt.name));
+ if (ld_options[j].arg != NULL)
+ {
+ printf (" %s", _(ld_options[j].arg));
+ len += 1 + strlen (_(ld_options[j].arg));
+ }
+ comma = true;
+ }
+ ++j;
+ }
+ while (j < OPTION_COUNT && ld_options[j].doc == NULL);
+
+ if (len >= 30)
+ {
+ printf ("\n");
+ len = 0;
+ }
+
+ for (; len < 30; len++)
+ putchar (' ');
+
+ printf ("%s\n", _(ld_options[i].doc));
+ }
+ }
+
+ /* xgettext:c-format */
+ printf (_("%s: supported targets:"), program_name);
+ targets = bfd_target_list ();
+ for (pp = targets; *pp != NULL; pp++)
+ printf (" %s", *pp);
+ free (targets);
+ printf ("\n");
+
+ /* xgettext:c-format */
+ printf (_("%s: supported emulations: "), program_name);
+ ldemul_list_emulations (stdout);
+ printf ("\n");
+
+ /* xgettext:c-format */
+ printf (_("%s: emulation specific options:\n"), program_name);
+ ldemul_list_emulation_options (stdout);
+ printf ("\n");
+
+ printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n"));
+}
diff --git a/ld/mac-ld.r b/ld/mac-ld.r
new file mode 100644
index 00000000000..b316fc5f193
--- /dev/null
+++ b/ld/mac-ld.r
@@ -0,0 +1,42 @@
+/* Resources for GNU LD. */
+
+#include "SysTypes.r"
+
+/* Version resources. */
+
+resource 'vers' (1) {
+ 0,
+ 0,
+ 0,
+ 0,
+ verUs,
+ VERSION_STRING,
+ VERSION_STRING " (C) 1986-95 FSF, Inc."
+};
+
+resource 'vers' (2, purgeable) {
+ 0,
+ 0,
+ 0,
+ 0,
+ verUs,
+ VERSION_STRING,
+ "GLD " VERSION_STRING " for MPW"
+};
+
+#ifdef WANT_CFRG
+
+#include "CodeFragmentTypes.r"
+
+resource 'cfrg' (0) {
+ {
+ kPowerPC,
+ kFullLib,
+ kNoVersionNum, kNoVersionNum,
+ 0, 0,
+ kIsApp, kOnDiskFlat, kZeroOffset, kWholeFork,
+ PROG_NAME
+ }
+};
+
+#endif /* WANT_CFRG */
diff --git a/ld/mpw-config.in b/ld/mpw-config.in
new file mode 100644
index 00000000000..b2542cc612c
--- /dev/null
+++ b/ld/mpw-config.in
@@ -0,0 +1,52 @@
+# Configuration fragment for LD.
+
+If "{target_canonical}" =~ /m68k-apple-macos/
+ Set emulname m68kcoff
+ forward-include "{srcdir}"mpw-em68kcoff.c em68kcoff.c
+ Set emulation_ofiles "{o}"em68kcoff.c.o
+
+Else If "{target_canonical}" =~ /powerpc-apple-macos/
+ Set emulname ppcmacos
+ forward-include "{srcdir}"mpw-eppcmac.c eppcmacos.c
+ Set emulation_ofiles "{o}"eppcmacos.c.o
+
+Else If "{target_canonical}" =~ /i386-\Option-x-go32/
+ Set emulname i386go32
+ forward-include "{srcdir}"mpw-ei386go32.c ei386go32.c
+ Set emulation_ofiles "{o}"ei386go32.c.o
+
+Else If "{target_canonical}" =~ /mips-\Option-x-ecoff/
+ Set emulname mipsidt
+ forward-include "{srcdir}"mpw-idtmips.c emipsidt.c
+ Set emulation_ofiles "{o}"emipsidt.c.o
+
+Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/
+ Set emulname elf32ebmip
+ forward-include "{srcdir}"mpw-elfmips.c eelf32ebmip.c
+ Set emulation_ofiles "{o}"eelf32ebmip.c.o
+
+Else If "{target_canonical}" =~ /sh-\Option-x-hms/
+ Set emulname sh
+ forward-include "{srcdir}"mpw-esh.c esh.c
+ Set emulation_ofiles "{o}"esh.c.o
+End If
+
+Echo '/* This file is automatically generated. DO NOT EDIT! */' > "{o}"ldemul-tmp.h
+Echo "extern ld_emulation_xfer_type ld_{emulname}_emulation;" >> "{o}"ldemul-tmp.h
+Echo '#define EMULATION_LIST \' >> "{o}"ldemul-tmp.h
+Echo " &ld_{emulname}_emulation, \" >> "{o}"ldemul-tmp.h
+Echo ' 0' >> "{o}"ldemul-tmp.h
+
+MoveIfChange "{o}"ldemul-tmp.h "{o}"ldemul-list.h
+
+Echo '# From mpw-config.in' > "{o}"mk.tmp
+Echo "EMUL = " {emulname} >> "{o}"mk.tmp
+Echo "EMULATION_OFILES = " {emulation_ofiles} >> "{o}"mk.tmp
+Echo 'version = ' `Search 'ld version ' {srcdir}ldver.c | sed -e 's/.*ld version \([^ ]*\).*/\1/'` >> "{o}"mk.tmp
+Echo "TDEFINES = " >> "{o}"mk.tmp
+Echo '# End from mpw-config.in' >> "{o}"mk.tmp
+
+Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new
+Echo '#include "mpw.h"' >> "{o}"config.new
+
+MoveIfChange "{o}"config.new "{o}"config.h
diff --git a/ld/mpw-elfmips.c b/ld/mpw-elfmips.c
new file mode 100644
index 00000000000..e8ab0560aa8
--- /dev/null
+++ b/ld/mpw-elfmips.c
@@ -0,0 +1,1439 @@
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* 32 bit ELF emulation code for elf32ebmip
+ Copyright (C) 1991, 93, 94, 95, 1996, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+ ELF support by Ian Lance Taylor <ian@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_elf32ebmip
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#include <ctype.h>
+
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldgram.h"
+
+static void gldelf32ebmip_before_parse PARAMS ((void));
+static boolean gldelf32ebmip_open_dynamic_archive
+ PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
+static void gldelf32ebmip_after_open PARAMS ((void));
+static void gldelf32ebmip_check_needed
+ PARAMS ((lang_input_statement_type *));
+static void gldelf32ebmip_stat_needed
+ PARAMS ((lang_input_statement_type *));
+static boolean gldelf32ebmip_search_needed
+ PARAMS ((const char *, const char *));
+static boolean gldelf32ebmip_try_needed PARAMS ((const char *));
+static void gldelf32ebmip_before_allocation PARAMS ((void));
+static void gldelf32ebmip_find_statement_assignment
+ PARAMS ((lang_statement_union_type *));
+static void gldelf32ebmip_find_exp_assignment PARAMS ((etree_type *));
+static boolean gldelf32ebmip_place_orphan
+ PARAMS ((lang_input_statement_type *, asection *));
+static void gldelf32ebmip_place_section
+ PARAMS ((lang_statement_union_type *));
+static char *gldelf32ebmip_get_script PARAMS ((int *isfile));
+
+static void
+gldelf32ebmip_before_parse()
+{
+ ldfile_output_architecture = bfd_arch_mips;
+ config.dynamic_link = true;
+}
+
+/* Try to open a dynamic archive. This is where we know that ELF
+ dynamic libraries have an extension of .so. */
+
+static boolean
+gldelf32ebmip_open_dynamic_archive (arch, search, entry)
+ const char *arch;
+ search_dirs_type *search;
+ lang_input_statement_type *entry;
+{
+ const char *filename;
+ char *string;
+
+ if (! entry->is_archive)
+ return false;
+
+ filename = entry->filename;
+
+ string = (char *) xmalloc (strlen (search->name)
+ + strlen (filename)
+ + strlen (arch)
+ + sizeof "/lib.so");
+
+ sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
+
+ if (! ldfile_try_open_bfd (string, entry))
+ {
+ free (string);
+ return false;
+ }
+
+ entry->filename = string;
+
+ /* We have found a dynamic object to include in the link. The ELF
+ backend linker will create a DT_NEEDED entry in the .dynamic
+ section naming this file. If this file includes a DT_SONAME
+ entry, it will be used. Otherwise, the ELF linker will just use
+ the name of the file. For an archive found by searching, like
+ this one, the DT_NEEDED entry should consist of just the name of
+ the file, without the path information used to find it. Note
+ that we only need to do this if we have a dynamic object; an
+ archive will never be referenced by a DT_NEEDED entry.
+
+ FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
+ very pretty. I haven't been able to think of anything that is
+ pretty, though. */
+ if (bfd_check_format (entry->the_bfd, bfd_object)
+ && (entry->the_bfd->flags & DYNAMIC) != 0)
+ {
+ char *needed_name;
+
+ ASSERT (entry->is_archive && entry->search_dirs_flag);
+ needed_name = (char *) xmalloc (strlen (filename)
+ + strlen (arch)
+ + sizeof "lib.so");
+ sprintf (needed_name, "lib%s%s.so", filename, arch);
+ bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
+ }
+
+ return true;
+}
+
+
+/* These variables are required to pass information back and forth
+ between after_open and check_needed and stat_needed. */
+
+static struct bfd_link_needed_list *global_needed;
+static struct stat global_stat;
+static boolean global_found;
+
+/* This is called after all the input files have been opened. */
+
+static void
+gldelf32ebmip_after_open ()
+{
+ struct bfd_link_needed_list *needed, *l;
+
+ /* We only need to worry about this when doing a final link. */
+ if (link_info.relocateable || link_info.shared)
+ return;
+
+ /* Get the list of files which appear in DT_NEEDED entries in
+ dynamic objects included in the link (often there will be none).
+ For each such file, we want to track down the corresponding
+ library, and include the symbol table in the link. This is what
+ the runtime dynamic linker will do. Tracking the files down here
+ permits one dynamic object to include another without requiring
+ special action by the person doing the link. Note that the
+ needed list can actually grow while we are stepping through this
+ loop. */
+ needed = bfd_elf_get_needed_list (output_bfd, &link_info);
+ for (l = needed; l != NULL; l = l->next)
+ {
+ struct bfd_link_needed_list *ll;
+ const char *lib_path;
+ size_t len;
+ search_dirs_type *search;
+
+ /* If we've already seen this file, skip it. */
+ for (ll = needed; ll != l; ll = ll->next)
+ if (strcmp (ll->name, l->name) == 0)
+ break;
+ if (ll != l)
+ continue;
+
+ /* See if this file was included in the link explicitly. */
+ global_needed = l;
+ global_found = false;
+ lang_for_each_input_file (gldelf32ebmip_check_needed);
+ if (global_found)
+ continue;
+
+ /* We need to find this file and include the symbol table. We
+ want to search for the file in the same way that the dynamic
+ linker will search. That means that we want to use
+ rpath_link, rpath, then the environment variable
+ LD_LIBRARY_PATH (native only), then the linker script
+ LIB_SEARCH_DIRS. We do not search using the -L arguments. */
+ if (gldelf32ebmip_search_needed (command_line.rpath_link,
+ l->name))
+ continue;
+ if (gldelf32ebmip_search_needed (command_line.rpath, l->name))
+ continue;
+ if (command_line.rpath_link == NULL
+ && command_line.rpath == NULL)
+ {
+ lib_path = (const char *) getenv ("LD_RUN_PATH");
+ if (gldelf32ebmip_search_needed (lib_path, l->name))
+ continue;
+ }
+ len = strlen (l->name);
+ for (search = search_head; search != NULL; search = search->next)
+ {
+ char *filename;
+
+ if (search->cmdline)
+ continue;
+ filename = (char *) xmalloc (strlen (search->name) + len + 2);
+ sprintf (filename, "%s/%s", search->name, l->name);
+ if (gldelf32ebmip_try_needed (filename))
+ break;
+ free (filename);
+ }
+ if (search != NULL)
+ continue;
+
+ einfo (_("%P: warning: %s, needed by %B, not found\n"),
+ l->name, l->by);
+ }
+}
+
+/* Search for a needed file in a path. */
+
+static boolean
+gldelf32ebmip_search_needed (path, name)
+ const char *path;
+ const char *name;
+{
+ const char *s;
+ size_t len;
+
+ if (path == NULL || *path == '\0')
+ return false;
+ len = strlen (name);
+ while (1)
+ {
+ char *filename, *sset;
+
+ s = strchr (path, ':');
+ if (s == NULL)
+ s = path + strlen (path);
+
+ filename = (char *) xmalloc (s - path + len + 2);
+ if (s == path)
+ sset = filename;
+ else
+ {
+ memcpy (filename, path, s - path);
+ filename[s - path] = '/';
+ sset = filename + (s - path) + 1;
+ }
+ strcpy (sset, name);
+
+ if (gldelf32ebmip_try_needed (filename))
+ return true;
+
+ free (filename);
+
+ if (*s == '\0')
+ break;
+ path = s + 1;
+ }
+
+ return false;
+}
+
+/* This function is called for each possible name for a dynamic object
+ named by a DT_NEEDED entry. */
+
+static boolean
+gldelf32ebmip_try_needed (name)
+ const char *name;
+{
+ bfd *abfd;
+
+ abfd = bfd_openr (name, bfd_get_target (output_bfd));
+ if (abfd == NULL)
+ return false;
+ if (! bfd_check_format (abfd, bfd_object))
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+ if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
+ {
+ (void) bfd_close (abfd);
+ return false;
+ }
+
+ /* We've found a dynamic object matching the DT_NEEDED entry. */
+
+ /* We have already checked that there is no other input file of the
+ same name. We must now check again that we are not including the
+ same file twice. We need to do this because on many systems
+ libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will
+ reference libc.so.1. If we have already included libc.so, we
+ don't want to include libc.so.1 if they are the same file, and we
+ can only check that using stat. */
+
+ if (bfd_stat (abfd, &global_stat) != 0)
+ einfo (_("%F%P:%B: bfd_stat failed: %E\n"), abfd);
+ global_found = false;
+ lang_for_each_input_file (gldelf32ebmip_stat_needed);
+ if (global_found)
+ {
+ /* Return true to indicate that we found the file, even though
+ we aren't going to do anything with it. */
+ return true;
+ }
+
+ /* Tell the ELF backend that don't want the output file to have a
+ DT_NEEDED entry for this file. */
+ bfd_elf_set_dt_needed_name (abfd, "");
+
+ /* Add this file into the symbol table. */
+ if (! bfd_link_add_symbols (abfd, &link_info))
+ einfo (_("%F%B: could not read symbols: %E\n"), abfd);
+
+ return true;
+}
+
+/* See if an input file matches a DT_NEEDED entry by name. */
+
+static void
+gldelf32ebmip_check_needed (s)
+ lang_input_statement_type *s;
+{
+ if (global_found)
+ return;
+
+ if (s->filename != NULL
+ && strcmp (s->filename, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+
+ if (s->the_bfd != NULL)
+ {
+ const char *soname;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname != NULL
+ && strcmp (soname, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+ }
+
+ if (s->search_dirs_flag
+ && s->filename != NULL
+ && strchr (global_needed->name, '/') == NULL)
+ {
+ const char *f;
+
+ f = strrchr (s->filename, '/');
+ if (f != NULL
+ && strcmp (f + 1, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+ }
+}
+
+/* See if an input file matches a DT_NEEDED entry by running stat on
+ the file. */
+
+static void
+gldelf32ebmip_stat_needed (s)
+ lang_input_statement_type *s;
+{
+ struct stat st;
+ const char *suffix;
+ const char *soname;
+ const char *f;
+
+ if (global_found)
+ return;
+ if (s->the_bfd == NULL)
+ return;
+
+ if (bfd_stat (s->the_bfd, &st) != 0)
+ {
+ einfo (_("%P:%B: bfd_stat failed: %E\n"), s->the_bfd);
+ return;
+ }
+
+ if (st.st_dev == global_stat.st_dev
+ && st.st_ino == global_stat.st_ino)
+ {
+ global_found = true;
+ return;
+ }
+
+ /* We issue a warning if it looks like we are including two
+ different versions of the same shared library. For example,
+ there may be a problem if -lc picks up libc.so.6 but some other
+ shared library has a DT_NEEDED entry of libc.so.5. This is a
+ hueristic test, and it will only work if the name looks like
+ NAME.so.VERSION. FIXME: Depending on file names is error-prone.
+ If we really want to issue warnings about mixing version numbers
+ of shared libraries, we need to find a better way. */
+
+ if (strchr (global_needed->name, '/') != NULL)
+ return;
+ suffix = strstr (global_needed->name, ".so.");
+ if (suffix == NULL)
+ return;
+ suffix += sizeof ".so." - 1;
+
+ soname = bfd_elf_get_dt_soname (s->the_bfd);
+ if (soname == NULL)
+ soname = s->filename;
+
+ f = strrchr (soname, '/');
+ if (f != NULL)
+ ++f;
+ else
+ f = soname;
+
+ if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
+ einfo (_("%P: warning: %s, needed by %B, may conflict with %s\n"),
+ global_needed->name, global_needed->by, f);
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gldelf32ebmip_before_allocation ()
+{
+ const char *rpath;
+ asection *sinterp;
+
+ /* If we are going to make any variable assignments, we need to let
+ the ELF backend know about them in case the variables are
+ referred to by dynamic objects. */
+ lang_for_each_statement (gldelf32ebmip_find_statement_assignment);
+
+ /* Let the ELF backend work out the sizes of any sections required
+ by dynamic linking. */
+ rpath = command_line.rpath;
+ if (rpath == NULL)
+ rpath = (const char *) getenv ("LD_RUN_PATH");
+ if (! bfd_elf32_size_dynamic_sections (output_bfd,
+ command_line.soname,
+ rpath,
+ command_line.export_dynamic,
+ &link_info,
+ &sinterp))
+ einfo (_("%P%F: failed to set dynamic section sizes: %E\n"));
+
+ /* Let the user override the dynamic linker we are using. */
+ if (command_line.interpreter != NULL
+ && sinterp != NULL)
+ {
+ sinterp->contents = (bfd_byte *) command_line.interpreter;
+ sinterp->_raw_size = strlen (command_line.interpreter) + 1;
+ }
+
+ /* Look for any sections named .gnu.warning. As a GNU extensions,
+ we treat such sections as containing warning messages. We print
+ out the warning message, and then zero out the section size so
+ that it does not get copied into the output file. */
+
+ {
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ asection *s;
+ bfd_size_type sz;
+ char *msg;
+ boolean ret;
+
+ if (is->just_syms_flag)
+ continue;
+
+ s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
+ if (s == NULL)
+ continue;
+
+ sz = bfd_section_size (is->the_bfd, s);
+ msg = xmalloc ((size_t) sz + 1);
+ if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
+ einfo (_("%F%B: Can't read contents of section .gnu.warning: %E\n"),
+ is->the_bfd);
+ msg[sz] = '\0';
+ ret = link_info.callbacks->warning (&link_info, msg,
+ (const char *) NULL,
+ is->the_bfd, (asection *) NULL,
+ (bfd_vma) 0);
+ ASSERT (ret);
+ free (msg);
+
+ /* Clobber the section size, so that we don't waste copying the
+ warning into the output file. */
+ s->_raw_size = 0;
+ }
+ }
+}
+
+/* This is called by the before_allocation routine via
+ lang_for_each_statement. It locates any assignment statements, and
+ tells the ELF backend about them, in case they are assignments to
+ symbols which are referred to by dynamic objects. */
+
+static void
+gldelf32ebmip_find_statement_assignment (s)
+ lang_statement_union_type *s;
+{
+ if (s->header.type == lang_assignment_statement_enum)
+ gldelf32ebmip_find_exp_assignment (s->assignment_statement.exp);
+}
+
+/* Look through an expression for an assignment statement. */
+
+static void
+gldelf32ebmip_find_exp_assignment (exp)
+ etree_type *exp;
+{
+ struct bfd_link_hash_entry *h;
+
+ switch (exp->type.node_class)
+ {
+ case etree_provide:
+ h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
+ false, false, false);
+ if (h == NULL)
+ break;
+
+ /* We call record_link_assignment even if the symbol is defined.
+ This is because if it is defined by a dynamic object, we
+ actually want to use the value defined by the linker script,
+ not the value from the dynamic object (because we are setting
+ symbols like etext). If the symbol is defined by a regular
+ object, then, as it happens, calling record_link_assignment
+ will do no harm. */
+
+ /* Fall through. */
+ case etree_assign:
+ if (strcmp (exp->assign.dst, ".") != 0)
+ {
+ if (! (bfd_elf32_record_link_assignment
+ (output_bfd, &link_info, exp->assign.dst,
+ exp->type.node_class == etree_provide ? true : false)))
+ einfo (_("%P%F: failed to record assignment to %s: %E\n"),
+ exp->assign.dst);
+ }
+ gldelf32ebmip_find_exp_assignment (exp->assign.src);
+ break;
+
+ case etree_binary:
+ gldelf32ebmip_find_exp_assignment (exp->binary.lhs);
+ gldelf32ebmip_find_exp_assignment (exp->binary.rhs);
+ break;
+
+ case etree_trinary:
+ gldelf32ebmip_find_exp_assignment (exp->trinary.cond);
+ gldelf32ebmip_find_exp_assignment (exp->trinary.lhs);
+ gldelf32ebmip_find_exp_assignment (exp->trinary.rhs);
+ break;
+
+ case etree_unary:
+ gldelf32ebmip_find_exp_assignment (exp->unary.child);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Place an orphan section. We use this to put random SHF_ALLOC
+ sections in the right segment. */
+
+static asection *hold_section;
+static lang_output_section_statement_type *hold_use;
+static lang_output_section_statement_type *hold_text;
+static lang_output_section_statement_type *hold_rodata;
+static lang_output_section_statement_type *hold_data;
+static lang_output_section_statement_type *hold_bss;
+static lang_output_section_statement_type *hold_rel;
+
+/*ARGSUSED*/
+static boolean
+gldelf32ebmip_place_orphan (file, s)
+ lang_input_statement_type *file;
+ asection *s;
+{
+ lang_output_section_statement_type *place;
+ asection *snew, **pps;
+ lang_statement_list_type *old;
+ lang_statement_list_type add;
+ etree_type *address;
+ const char *secname, *ps;
+ lang_output_section_statement_type *os;
+
+ if ((s->flags & SEC_ALLOC) == 0)
+ return false;
+
+ /* Look through the script to see where to place this section. */
+ hold_section = s;
+ hold_use = NULL;
+ lang_for_each_statement (gldelf32ebmip_place_section);
+
+ if (hold_use != NULL)
+ {
+ /* We have already placed a section with this name. */
+ wild_doit (&hold_use->children, s, hold_use, file);
+ return true;
+ }
+
+ secname = bfd_get_section_name (s->owner, s);
+
+ /* If this is a final link, then always put .gnu.warning.SYMBOL
+ sections into the .text section to get them out of the way. */
+ if (! link_info.shared
+ && ! link_info.relocateable
+ && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
+ && hold_text != NULL)
+ {
+ wild_doit (&hold_text->children, s, hold_text, file);
+ return true;
+ }
+
+ /* Decide which segment the section should go in based on the
+ section name and section flags. */
+ place = NULL;
+ if ((s->flags & SEC_HAS_CONTENTS) == 0
+ && hold_bss != NULL)
+ place = hold_bss;
+ else if ((s->flags & SEC_READONLY) == 0
+ && hold_data != NULL)
+ place = hold_data;
+ else if (strncmp (secname, ".rel", 4) == 0
+ && hold_rel != NULL)
+ place = hold_rel;
+ else if ((s->flags & SEC_CODE) == 0
+ && (s->flags & SEC_READONLY) != 0
+ && hold_rodata != NULL)
+ place = hold_rodata;
+ else if ((s->flags & SEC_READONLY) != 0
+ && hold_text != NULL)
+ place = hold_text;
+ if (place == NULL)
+ return false;
+
+ /* Create the section in the output file, and put it in the right
+ place. This shuffling is to make the output file look neater. */
+ snew = bfd_make_section (output_bfd, secname);
+ if (snew == NULL)
+ einfo (_("%P%F: output format %s cannot represent section called %s\n"),
+ output_bfd->xvec->name, secname);
+ if (place->bfd_section != NULL)
+ {
+ for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+ ;
+ *pps = snew->next;
+ snew->next = place->bfd_section->next;
+ place->bfd_section->next = snew;
+ }
+
+ /* Start building a list of statements for this section. */
+ old = stat_ptr;
+ stat_ptr = &add;
+ lang_list_init (stat_ptr);
+
+ /* If the name of the section is representable in C, then create
+ symbols to mark the start and the end of the section. */
+ for (ps = secname; *ps != '\0'; ps++)
+ if (! isalnum (*ps) && *ps != '_')
+ break;
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+
+ symname = (char *) xmalloc (ps - secname + sizeof "__start_");
+ sprintf (symname, "__start_%s", secname);
+ lang_add_assignment (exp_assop ('=', symname,
+ exp_unop (ALIGN_K,
+ exp_intop ((bfd_vma) 1
+ << s->alignment_power))));
+ }
+
+ if (! link_info.relocateable)
+ address = NULL;
+ else
+ address = exp_intop ((bfd_vma) 0);
+
+ lang_enter_output_section_statement (secname, address, 0,
+ (bfd_vma) 0,
+ (etree_type *) NULL,
+ (etree_type *) NULL,
+ (etree_type *) NULL);
+
+ os = lang_output_section_statement_lookup (secname);
+ wild_doit (&os->children, s, os, file);
+
+ lang_leave_output_section_statement ((bfd_vma) 0, "*default*");
+ stat_ptr = &add;
+
+ if (*ps == '\0' && config.build_constructors)
+ {
+ char *symname;
+
+ symname = (char *) xmalloc (ps - secname + sizeof "__stop_");
+ sprintf (symname, "__stop_%s", secname);
+ lang_add_assignment (exp_assop ('=', symname,
+ exp_nameop (NAME, ".")));
+ }
+
+ /* Now stick the new statement list right after PLACE. */
+ *add.tail = place->header.next;
+ place->header.next = add.head;
+
+ stat_ptr = old;
+
+ return true;
+}
+
+static void
+gldelf32ebmip_place_section (s)
+ lang_statement_union_type *s;
+{
+ lang_output_section_statement_type *os;
+
+ if (s->header.type != lang_output_section_statement_enum)
+ return;
+
+ os = &s->output_section_statement;
+
+ if (strcmp (os->name, hold_section->name) == 0)
+ hold_use = os;
+
+ if (strcmp (os->name, ".text") == 0)
+ hold_text = os;
+ else if (strcmp (os->name, ".rodata") == 0)
+ hold_rodata = os;
+ else if (strcmp (os->name, ".data") == 0)
+ hold_data = os;
+ else if (strcmp (os->name, ".bss") == 0)
+ hold_bss = os;
+ else if (hold_rel == NULL
+ && os->bfd_section != NULL
+ && strncmp (os->name, ".rel", 4) == 0)
+ hold_rel = os;
+}
+
+static char *
+gldelf32ebmip_get_script(isfile)
+ int *isfile;
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
+ \"elf32-littlemips\")\n\
+OUTPUT_ARCH(mips)\n\
+ENTRY(_start)\n\
+ /* For some reason, the Solaris linker makes bad executables\n\
+ if gld -r is used and the intermediate file has sections starting\n\
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld\n\
+ bug. But for now assigning the zero vmas works. */\n\
+SECTIONS\n\
+{\n\
+ /* Read-only sections, merged into text segment: */\n\
+ .interp 0 : { *(.interp) }\n\
+ .reginfo 0 : { *(.reginfo) }\n\
+ .dynamic 0 : { *(.dynamic) }\n\
+ .dynstr 0 : { *(.dynstr) }\n\
+ .dynsym 0 : { *(.dynsym) }\n\
+ .hash 0 : { *(.hash) }\n\
+ .rel.text 0 : { *(.rel.text) }\n\
+ .rela.text 0 : { *(.rela.text) }\n\
+ .rel.data 0 : { *(.rel.data) }\n\
+ .rela.data 0 : { *(.rela.data) }\n\
+ .rel.rodata 0 : { *(.rel.rodata) }\n\
+ .rela.rodata 0 : { *(.rela.rodata) }\n\
+ .rel.got 0 : { *(.rel.got) }\n\
+ .rela.got 0 : { *(.rela.got) }\n\
+ .rel.ctors 0 : { *(.rel.ctors) }\n\
+ .rela.ctors 0 : { *(.rela.ctors) }\n\
+ .rel.dtors 0 : { *(.rel.dtors) }\n\
+ .rela.dtors 0 : { *(.rela.dtors) }\n\
+ .rel.init 0 : { *(.rel.init) }\n\
+ .rela.init 0 : { *(.rela.init) }\n\
+ .rel.fini 0 : { *(.rel.fini) }\n\
+ .rela.fini 0 : { *(.rela.fini) }\n\
+ .rel.bss 0 : { *(.rel.bss) }\n\
+ .rela.bss 0 : { *(.rela.bss) }\n\
+ .rel.plt 0 : { *(.rel.plt) }\n\
+ .rela.plt 0 : { *(.rela.plt) }\n\
+ .rodata 0 : { *(.rodata) }\n\
+ .rodata1 0 : { *(.rodata1) }\n\
+ .init 0 : { *(.init) } =0\n\
+ .text 0 :\n\
+ {\n\
+ *(.text)\n\
+ *(.stub)\n\
+ /* .gnu.warning sections are handled specially by elf32.em. */\n\
+ *(.gnu.warning)\n\
+ } =0\n\
+ .fini 0 : { *(.fini) } =0\n\
+ /* Adjust the address for the data segment. We want to adjust up to\n\
+ the same address within the page on the next page up. It would\n\
+ be more correct to do this:\n\
+ The current expression does not correctly handle the case of a\n\
+ text segment ending precisely at the end of a page; it causes the\n\
+ data segment to skip a page. The above expression does not have\n\
+ this problem, but it will currently (2/95) cause BFD to allocate\n\
+ a single segment, combining both text and data, for this case.\n\
+ This will prevent the text segment from being shared among\n\
+ multiple executions of the program; I think that is more\n\
+ important than losing a page of the virtual address space (note\n\
+ that no actual memory is lost; the page which is skipped can not\n\
+ be referenced). */\n\
+ .data 0 :\n\
+ {\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ .data1 0 : { *(.data1) }\n\
+ .ctors 0 : { *(.ctors) }\n\
+ .dtors 0 : { *(.dtors) }\n\
+ .got 0 :\n\
+ {\n\
+ *(.got.plt) *(.got)\n\
+ }\n\
+ /* We want the small data sections together, so single-instruction offsets\n\
+ can access them all, and initialized data all before uninitialized, so\n\
+ we can shorten the on-disk segment size. */\n\
+ .sdata 0 : { *(.sdata) }\n\
+ .sbss 0 : { *(.sbss) *(.scommon) }\n\
+ .bss 0 :\n\
+ {\n\
+ *(.dynbss)\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ /* These are needed for ELF backends which have not yet been\n\
+ converted to the new style linker. */\n\
+ .stab 0 : { *(.stab) }\n\
+ .stabstr 0 : { *(.stabstr) }\n\
+ /* DWARF debug sections.\n\
+ Symbols in the .debug DWARF section are relative to the beginning of the\n\
+ section so we begin .debug at 0. It's not clear yet what needs to happen\n\
+ for the others. */\n\
+ .debug 0 : { *(.debug) }\n\
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
+ .debug_aranges 0 : { *(.debug_aranges) }\n\
+ .debug_pubnames 0 : { *(.debug_pubnames) }\n\
+ .debug_sfnames 0 : { *(.debug_sfnames) }\n\
+ .line 0 : { *(.line) }\n\
+ /* These must appear regardless of . */\n\
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
+}\n\n";
+ else if (link_info.relocateable == true)
+ return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
+ \"elf32-littlemips\")\n\
+OUTPUT_ARCH(mips)\n\
+ENTRY(_start)\n\
+ /* For some reason, the Solaris linker makes bad executables\n\
+ if gld -r is used and the intermediate file has sections starting\n\
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld\n\
+ bug. But for now assigning the zero vmas works. */\n\
+SECTIONS\n\
+{\n\
+ /* Read-only sections, merged into text segment: */\n\
+ .interp 0 : { *(.interp) }\n\
+ .reginfo 0 : { *(.reginfo) }\n\
+ .dynamic 0 : { *(.dynamic) }\n\
+ .dynstr 0 : { *(.dynstr) }\n\
+ .dynsym 0 : { *(.dynsym) }\n\
+ .hash 0 : { *(.hash) }\n\
+ .rel.text 0 : { *(.rel.text) }\n\
+ .rela.text 0 : { *(.rela.text) }\n\
+ .rel.data 0 : { *(.rel.data) }\n\
+ .rela.data 0 : { *(.rela.data) }\n\
+ .rel.rodata 0 : { *(.rel.rodata) }\n\
+ .rela.rodata 0 : { *(.rela.rodata) }\n\
+ .rel.got 0 : { *(.rel.got) }\n\
+ .rela.got 0 : { *(.rela.got) }\n\
+ .rel.ctors 0 : { *(.rel.ctors) }\n\
+ .rela.ctors 0 : { *(.rela.ctors) }\n\
+ .rel.dtors 0 : { *(.rel.dtors) }\n\
+ .rela.dtors 0 : { *(.rela.dtors) }\n\
+ .rel.init 0 : { *(.rel.init) }\n\
+ .rela.init 0 : { *(.rela.init) }\n\
+ .rel.fini 0 : { *(.rel.fini) }\n\
+ .rela.fini 0 : { *(.rela.fini) }\n\
+ .rel.bss 0 : { *(.rel.bss) }\n\
+ .rela.bss 0 : { *(.rela.bss) }\n\
+ .rel.plt 0 : { *(.rel.plt) }\n\
+ .rela.plt 0 : { *(.rela.plt) }\n\
+ .rodata 0 : { *(.rodata) }\n\
+ .rodata1 0 : { *(.rodata1) }\n\
+ .init 0 : { *(.init) } =0\n\
+ .text 0 :\n\
+ {\n\
+ *(.text)\n\
+ *(.stub)\n\
+ /* .gnu.warning sections are handled specially by elf32.em. */\n\
+ *(.gnu.warning)\n\
+ } =0\n\
+ .fini 0 : { *(.fini) } =0\n\
+ /* Adjust the address for the data segment. We want to adjust up to\n\
+ the same address within the page on the next page up. It would\n\
+ be more correct to do this:\n\
+ The current expression does not correctly handle the case of a\n\
+ text segment ending precisely at the end of a page; it causes the\n\
+ data segment to skip a page. The above expression does not have\n\
+ this problem, but it will currently (2/95) cause BFD to allocate\n\
+ a single segment, combining both text and data, for this case.\n\
+ This will prevent the text segment from being shared among\n\
+ multiple executions of the program; I think that is more\n\
+ important than losing a page of the virtual address space (note\n\
+ that no actual memory is lost; the page which is skipped can not\n\
+ be referenced). */\n\
+ .data 0 :\n\
+ {\n\
+ *(.data)\n\
+ }\n\
+ .data1 0 : { *(.data1) }\n\
+ .ctors 0 : { *(.ctors) }\n\
+ .dtors 0 : { *(.dtors) }\n\
+ .got 0 :\n\
+ {\n\
+ *(.got.plt) *(.got)\n\
+ }\n\
+ /* We want the small data sections together, so single-instruction offsets\n\
+ can access them all, and initialized data all before uninitialized, so\n\
+ we can shorten the on-disk segment size. */\n\
+ .sdata 0 : { *(.sdata) }\n\
+ .sbss 0 : { *(.sbss) *(.scommon) }\n\
+ .bss 0 :\n\
+ {\n\
+ *(.dynbss)\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ /* These are needed for ELF backends which have not yet been\n\
+ converted to the new style linker. */\n\
+ .stab 0 : { *(.stab) }\n\
+ .stabstr 0 : { *(.stabstr) }\n\
+ /* DWARF debug sections.\n\
+ Symbols in the .debug DWARF section are relative to the beginning of the\n\
+ section so we begin .debug at 0. It's not clear yet what needs to happen\n\
+ for the others. */\n\
+ .debug 0 : { *(.debug) }\n\
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
+ .debug_aranges 0 : { *(.debug_aranges) }\n\
+ .debug_pubnames 0 : { *(.debug_pubnames) }\n\
+ .debug_sfnames 0 : { *(.debug_sfnames) }\n\
+ .line 0 : { *(.line) }\n\
+ /* These must appear regardless of . */\n\
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
+}\n\n";
+ else if (!config.text_read_only)
+ return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
+ \"elf32-littlemips\")\n\
+OUTPUT_ARCH(mips)\n\
+ENTRY(_start)\n\
+ SEARCH_DIR(/usr/local/mips-elf/lib);\n\
+/* Do we need any of these for elf?\n\
+ __DYNAMIC = 0; */\n\
+SECTIONS\n\
+{\n\
+ /* Read-only sections, merged into text segment: */\n\
+ . = 0x0400000;\n\
+ .interp : { *(.interp) }\n\
+ .reginfo : { *(.reginfo) }\n\
+ .dynamic : { *(.dynamic) }\n\
+ .dynstr : { *(.dynstr) }\n\
+ .dynsym : { *(.dynsym) }\n\
+ .hash : { *(.hash) }\n\
+ .rel.text : { *(.rel.text) }\n\
+ .rela.text : { *(.rela.text) }\n\
+ .rel.data : { *(.rel.data) }\n\
+ .rela.data : { *(.rela.data) }\n\
+ .rel.rodata : { *(.rel.rodata) }\n\
+ .rela.rodata : { *(.rela.rodata) }\n\
+ .rel.got : { *(.rel.got) }\n\
+ .rela.got : { *(.rela.got) }\n\
+ .rel.ctors : { *(.rel.ctors) }\n\
+ .rela.ctors : { *(.rela.ctors) }\n\
+ .rel.dtors : { *(.rel.dtors) }\n\
+ .rela.dtors : { *(.rela.dtors) }\n\
+ .rel.init : { *(.rel.init) }\n\
+ .rela.init : { *(.rela.init) }\n\
+ .rel.fini : { *(.rel.fini) }\n\
+ .rela.fini : { *(.rela.fini) }\n\
+ .rel.bss : { *(.rel.bss) }\n\
+ .rela.bss : { *(.rela.bss) }\n\
+ .rel.plt : { *(.rel.plt) }\n\
+ .rela.plt : { *(.rela.plt) }\n\
+ .rodata : { *(.rodata) }\n\
+ .rodata1 : { *(.rodata1) }\n\
+ .init : { *(.init) } =0\n\
+ .text :\n\
+ {\n\
+ _ftext = . ;\n\
+ *(.text)\n\
+ *(.stub)\n\
+ /* .gnu.warning sections are handled specially by elf32.em. */\n\
+ *(.gnu.warning)\n\
+ } =0\n\
+ _etext = .;\n\
+ PROVIDE (etext = .);\n\
+ .fini : { *(.fini) } =0\n\
+ /* Adjust the address for the data segment. We want to adjust up to\n\
+ the same address within the page on the next page up. It would\n\
+ be more correct to do this:\n\
+ . = .;\n\
+ The current expression does not correctly handle the case of a\n\
+ text segment ending precisely at the end of a page; it causes the\n\
+ data segment to skip a page. The above expression does not have\n\
+ this problem, but it will currently (2/95) cause BFD to allocate\n\
+ a single segment, combining both text and data, for this case.\n\
+ This will prevent the text segment from being shared among\n\
+ multiple executions of the program; I think that is more\n\
+ important than losing a page of the virtual address space (note\n\
+ that no actual memory is lost; the page which is skipped can not\n\
+ be referenced). */\n\
+ . += . - 0x0400000;\n\
+ .data :\n\
+ {\n\
+ _fdata = . ;\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ .data1 : { *(.data1) }\n\
+ .ctors : { *(.ctors) }\n\
+ .dtors : { *(.dtors) }\n\
+ _gp = ALIGN(16) + 0x7ff0;\n\
+ .got :\n\
+ {\n\
+ *(.got.plt) *(.got)\n\
+ }\n\
+ /* We want the small data sections together, so single-instruction offsets\n\
+ can access them all, and initialized data all before uninitialized, so\n\
+ we can shorten the on-disk segment size. */\n\
+ .sdata : { *(.sdata) }\n\
+ .lit8 : { *(.lit8) }\n\
+ .lit4 : { *(.lit4) }\n\
+ _edata = .;\n\
+ PROVIDE (edata = .);\n\
+ __bss_start = .;\n\
+ _fbss = .;\n\
+ .sbss : { *(.sbss) *(.scommon) }\n\
+ .bss :\n\
+ {\n\
+ *(.dynbss)\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ _end = . ;\n\
+ PROVIDE (end = .);\n\
+ /* These are needed for ELF backends which have not yet been\n\
+ converted to the new style linker. */\n\
+ .stab 0 : { *(.stab) }\n\
+ .stabstr 0 : { *(.stabstr) }\n\
+ /* DWARF debug sections.\n\
+ Symbols in the .debug DWARF section are relative to the beginning of the\n\
+ section so we begin .debug at 0. It's not clear yet what needs to happen\n\
+ for the others. */\n\
+ .debug 0 : { *(.debug) }\n\
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
+ .debug_aranges 0 : { *(.debug_aranges) }\n\
+ .debug_pubnames 0 : { *(.debug_pubnames) }\n\
+ .debug_sfnames 0 : { *(.debug_sfnames) }\n\
+ .line 0 : { *(.line) }\n\
+ /* These must appear regardless of . */\n\
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
+}\n\n";
+ else if (!config.magic_demand_paged)
+ return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
+ \"elf32-littlemips\")\n\
+OUTPUT_ARCH(mips)\n\
+ENTRY(_start)\n\
+ SEARCH_DIR(/usr/local/mips-elf/lib);\n\
+/* Do we need any of these for elf?\n\
+ __DYNAMIC = 0; */\n\
+SECTIONS\n\
+{\n\
+ /* Read-only sections, merged into text segment: */\n\
+ . = 0x0400000;\n\
+ .interp : { *(.interp) }\n\
+ .reginfo : { *(.reginfo) }\n\
+ .dynamic : { *(.dynamic) }\n\
+ .dynstr : { *(.dynstr) }\n\
+ .dynsym : { *(.dynsym) }\n\
+ .hash : { *(.hash) }\n\
+ .rel.text : { *(.rel.text) }\n\
+ .rela.text : { *(.rela.text) }\n\
+ .rel.data : { *(.rel.data) }\n\
+ .rela.data : { *(.rela.data) }\n\
+ .rel.rodata : { *(.rel.rodata) }\n\
+ .rela.rodata : { *(.rela.rodata) }\n\
+ .rel.got : { *(.rel.got) }\n\
+ .rela.got : { *(.rela.got) }\n\
+ .rel.ctors : { *(.rel.ctors) }\n\
+ .rela.ctors : { *(.rela.ctors) }\n\
+ .rel.dtors : { *(.rel.dtors) }\n\
+ .rela.dtors : { *(.rela.dtors) }\n\
+ .rel.init : { *(.rel.init) }\n\
+ .rela.init : { *(.rela.init) }\n\
+ .rel.fini : { *(.rel.fini) }\n\
+ .rela.fini : { *(.rela.fini) }\n\
+ .rel.bss : { *(.rel.bss) }\n\
+ .rela.bss : { *(.rela.bss) }\n\
+ .rel.plt : { *(.rel.plt) }\n\
+ .rela.plt : { *(.rela.plt) }\n\
+ .rodata : { *(.rodata) }\n\
+ .rodata1 : { *(.rodata1) }\n\
+ .init : { *(.init) } =0\n\
+ .text :\n\
+ {\n\
+ _ftext = . ;\n\
+ *(.text)\n\
+ *(.stub)\n\
+ /* .gnu.warning sections are handled specially by elf32.em. */\n\
+ *(.gnu.warning)\n\
+ } =0\n\
+ _etext = .;\n\
+ PROVIDE (etext = .);\n\
+ .fini : { *(.fini) } =0\n\
+ /* Adjust the address for the data segment. We want to adjust up to\n\
+ the same address within the page on the next page up. It would\n\
+ be more correct to do this:\n\
+ . = 0x10000000;\n\
+ The current expression does not correctly handle the case of a\n\
+ text segment ending precisely at the end of a page; it causes the\n\
+ data segment to skip a page. The above expression does not have\n\
+ this problem, but it will currently (2/95) cause BFD to allocate\n\
+ a single segment, combining both text and data, for this case.\n\
+ This will prevent the text segment from being shared among\n\
+ multiple executions of the program; I think that is more\n\
+ important than losing a page of the virtual address space (note\n\
+ that no actual memory is lost; the page which is skipped can not\n\
+ be referenced). */\n\
+ . += 0x10000000 - 0x0400000;\n\
+ .data :\n\
+ {\n\
+ _fdata = . ;\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ .data1 : { *(.data1) }\n\
+ .ctors : { *(.ctors) }\n\
+ .dtors : { *(.dtors) }\n\
+ _gp = ALIGN(16) + 0x7ff0;\n\
+ .got :\n\
+ {\n\
+ *(.got.plt) *(.got)\n\
+ }\n\
+ /* We want the small data sections together, so single-instruction offsets\n\
+ can access them all, and initialized data all before uninitialized, so\n\
+ we can shorten the on-disk segment size. */\n\
+ .sdata : { *(.sdata) }\n\
+ .lit8 : { *(.lit8) }\n\
+ .lit4 : { *(.lit4) }\n\
+ _edata = .;\n\
+ PROVIDE (edata = .);\n\
+ __bss_start = .;\n\
+ _fbss = .;\n\
+ .sbss : { *(.sbss) *(.scommon) }\n\
+ .bss :\n\
+ {\n\
+ *(.dynbss)\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ _end = . ;\n\
+ PROVIDE (end = .);\n\
+ /* These are needed for ELF backends which have not yet been\n\
+ converted to the new style linker. */\n\
+ .stab 0 : { *(.stab) }\n\
+ .stabstr 0 : { *(.stabstr) }\n\
+ /* DWARF debug sections.\n\
+ Symbols in the .debug DWARF section are relative to the beginning of the\n\
+ section so we begin .debug at 0. It's not clear yet what needs to happen\n\
+ for the others. */\n\
+ .debug 0 : { *(.debug) }\n\
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
+ .debug_aranges 0 : { *(.debug_aranges) }\n\
+ .debug_pubnames 0 : { *(.debug_pubnames) }\n\
+ .debug_sfnames 0 : { *(.debug_sfnames) }\n\
+ .line 0 : { *(.line) }\n\
+ /* These must appear regardless of . */\n\
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
+}\n\n";
+ else if (link_info.shared)
+ return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
+ \"elf32-littlemips\")\n\
+OUTPUT_ARCH(mips)\n\
+ENTRY(_start)\n\
+ SEARCH_DIR(/usr/local/mips-elf/lib);\n\
+/* Do we need any of these for elf?\n\
+ __DYNAMIC = 0; */\n\
+SECTIONS\n\
+{\n\
+ /* Read-only sections, merged into text segment: */\n\
+ . = 0x5ffe0000 + SIZEOF_HEADERS;\n\
+ .reginfo : { *(.reginfo) }\n\
+ .dynamic : { *(.dynamic) }\n\
+ .dynstr : { *(.dynstr) }\n\
+ .dynsym : { *(.dynsym) }\n\
+ .hash : { *(.hash) }\n\
+ .rel.text : { *(.rel.text) }\n\
+ .rela.text : { *(.rela.text) }\n\
+ .rel.data : { *(.rel.data) }\n\
+ .rela.data : { *(.rela.data) }\n\
+ .rel.rodata : { *(.rel.rodata) }\n\
+ .rela.rodata : { *(.rela.rodata) }\n\
+ .rel.got : { *(.rel.got) }\n\
+ .rela.got : { *(.rela.got) }\n\
+ .rel.ctors : { *(.rel.ctors) }\n\
+ .rela.ctors : { *(.rela.ctors) }\n\
+ .rel.dtors : { *(.rel.dtors) }\n\
+ .rela.dtors : { *(.rela.dtors) }\n\
+ .rel.init : { *(.rel.init) }\n\
+ .rela.init : { *(.rela.init) }\n\
+ .rel.fini : { *(.rel.fini) }\n\
+ .rela.fini : { *(.rela.fini) }\n\
+ .rel.bss : { *(.rel.bss) }\n\
+ .rela.bss : { *(.rela.bss) }\n\
+ .rel.plt : { *(.rel.plt) }\n\
+ .rela.plt : { *(.rela.plt) }\n\
+ .rodata : { *(.rodata) }\n\
+ .rodata1 : { *(.rodata1) }\n\
+ .init : { *(.init) } =0\n\
+ .text :\n\
+ {\n\
+ *(.text)\n\
+ *(.stub)\n\
+ /* .gnu.warning sections are handled specially by elf32.em. */\n\
+ *(.gnu.warning)\n\
+ } =0\n\
+ .fini : { *(.fini) } =0\n\
+ /* Adjust the address for the data segment. We want to adjust up to\n\
+ the same address within the page on the next page up. It would\n\
+ be more correct to do this:\n\
+ . = 0x10000000;\n\
+ The current expression does not correctly handle the case of a\n\
+ text segment ending precisely at the end of a page; it causes the\n\
+ data segment to skip a page. The above expression does not have\n\
+ this problem, but it will currently (2/95) cause BFD to allocate\n\
+ a single segment, combining both text and data, for this case.\n\
+ This will prevent the text segment from being shared among\n\
+ multiple executions of the program; I think that is more\n\
+ important than losing a page of the virtual address space (note\n\
+ that no actual memory is lost; the page which is skipped can not\n\
+ be referenced). */\n\
+ . += 0x10000;\n\
+ .data :\n\
+ {\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ .data1 : { *(.data1) }\n\
+ .ctors : { *(.ctors) }\n\
+ .dtors : { *(.dtors) }\n\
+ _gp = ALIGN(16) + 0x7ff0;\n\
+ .got :\n\
+ {\n\
+ *(.got.plt) *(.got)\n\
+ }\n\
+ /* We want the small data sections together, so single-instruction offsets\n\
+ can access them all, and initialized data all before uninitialized, so\n\
+ we can shorten the on-disk segment size. */\n\
+ .sdata : { *(.sdata) }\n\
+ .lit8 : { *(.lit8) }\n\
+ .lit4 : { *(.lit4) }\n\
+ .sbss : { *(.sbss) *(.scommon) }\n\
+ .bss :\n\
+ {\n\
+ *(.dynbss)\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ /* These are needed for ELF backends which have not yet been\n\
+ converted to the new style linker. */\n\
+ .stab 0 : { *(.stab) }\n\
+ .stabstr 0 : { *(.stabstr) }\n\
+ /* DWARF debug sections.\n\
+ Symbols in the .debug DWARF section are relative to the beginning of the\n\
+ section so we begin .debug at 0. It's not clear yet what needs to happen\n\
+ for the others. */\n\
+ .debug 0 : { *(.debug) }\n\
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
+ .debug_aranges 0 : { *(.debug_aranges) }\n\
+ .debug_pubnames 0 : { *(.debug_pubnames) }\n\
+ .debug_sfnames 0 : { *(.debug_sfnames) }\n\
+ .line 0 : { *(.line) }\n\
+ /* These must appear regardless of . */\n\
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
+}\n\n";
+ else
+ return "OUTPUT_FORMAT(\"elf32-bigmips\", \"elf32-bigmips\",\n\
+ \"elf32-littlemips\")\n\
+OUTPUT_ARCH(mips)\n\
+ENTRY(_start)\n\
+ SEARCH_DIR(/usr/local/mips-elf/lib);\n\
+/* Do we need any of these for elf?\n\
+ __DYNAMIC = 0; */\n\
+SECTIONS\n\
+{\n\
+ /* Read-only sections, merged into text segment: */\n\
+ . = 0x0400000;\n\
+ .interp : { *(.interp) }\n\
+ .reginfo : { *(.reginfo) }\n\
+ .dynamic : { *(.dynamic) }\n\
+ .dynstr : { *(.dynstr) }\n\
+ .dynsym : { *(.dynsym) }\n\
+ .hash : { *(.hash) }\n\
+ .rel.text : { *(.rel.text) }\n\
+ .rela.text : { *(.rela.text) }\n\
+ .rel.data : { *(.rel.data) }\n\
+ .rela.data : { *(.rela.data) }\n\
+ .rel.rodata : { *(.rel.rodata) }\n\
+ .rela.rodata : { *(.rela.rodata) }\n\
+ .rel.got : { *(.rel.got) }\n\
+ .rela.got : { *(.rela.got) }\n\
+ .rel.ctors : { *(.rel.ctors) }\n\
+ .rela.ctors : { *(.rela.ctors) }\n\
+ .rel.dtors : { *(.rel.dtors) }\n\
+ .rela.dtors : { *(.rela.dtors) }\n\
+ .rel.init : { *(.rel.init) }\n\
+ .rela.init : { *(.rela.init) }\n\
+ .rel.fini : { *(.rel.fini) }\n\
+ .rela.fini : { *(.rela.fini) }\n\
+ .rel.bss : { *(.rel.bss) }\n\
+ .rela.bss : { *(.rela.bss) }\n\
+ .rel.plt : { *(.rel.plt) }\n\
+ .rela.plt : { *(.rela.plt) }\n\
+ .rodata : { *(.rodata) }\n\
+ .rodata1 : { *(.rodata1) }\n\
+ .init : { *(.init) } =0\n\
+ .text :\n\
+ {\n\
+ _ftext = . ;\n\
+ *(.text)\n\
+ *(.stub)\n\
+ /* .gnu.warning sections are handled specially by elf32.em. */\n\
+ *(.gnu.warning)\n\
+ } =0\n\
+ _etext = .;\n\
+ PROVIDE (etext = .);\n\
+ .fini : { *(.fini) } =0\n\
+ /* Adjust the address for the data segment. We want to adjust up to\n\
+ the same address within the page on the next page up. It would\n\
+ be more correct to do this:\n\
+ . = 0x10000000;\n\
+ The current expression does not correctly handle the case of a\n\
+ text segment ending precisely at the end of a page; it causes the\n\
+ data segment to skip a page. The above expression does not have\n\
+ this problem, but it will currently (2/95) cause BFD to allocate\n\
+ a single segment, combining both text and data, for this case.\n\
+ This will prevent the text segment from being shared among\n\
+ multiple executions of the program; I think that is more\n\
+ important than losing a page of the virtual address space (note\n\
+ that no actual memory is lost; the page which is skipped can not\n\
+ be referenced). */\n\
+ . += 0x10000000 - 0x0400000;\n\
+ .data :\n\
+ {\n\
+ _fdata = . ;\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ .data1 : { *(.data1) }\n\
+ .ctors : { *(.ctors) }\n\
+ .dtors : { *(.dtors) }\n\
+ _gp = ALIGN(16) + 0x7ff0;\n\
+ .got :\n\
+ {\n\
+ *(.got.plt) *(.got)\n\
+ }\n\
+ /* We want the small data sections together, so single-instruction offsets\n\
+ can access them all, and initialized data all before uninitialized, so\n\
+ we can shorten the on-disk segment size. */\n\
+ .sdata : { *(.sdata) }\n\
+ .lit8 : { *(.lit8) }\n\
+ .lit4 : { *(.lit4) }\n\
+ _edata = .;\n\
+ PROVIDE (edata = .);\n\
+ __bss_start = .;\n\
+ _fbss = .;\n\
+ .sbss : { *(.sbss) *(.scommon) }\n\
+ .bss :\n\
+ {\n\
+ *(.dynbss)\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ _end = . ;\n\
+ PROVIDE (end = .);\n\
+ /* These are needed for ELF backends which have not yet been\n\
+ converted to the new style linker. */\n\
+ .stab 0 : { *(.stab) }\n\
+ .stabstr 0 : { *(.stabstr) }\n\
+ /* DWARF debug sections.\n\
+ Symbols in the .debug DWARF section are relative to the beginning of the\n\
+ section so we begin .debug at 0. It's not clear yet what needs to happen\n\
+ for the others. */\n\
+ .debug 0 : { *(.debug) }\n\
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }\n\
+ .debug_aranges 0 : { *(.debug_aranges) }\n\
+ .debug_pubnames 0 : { *(.debug_pubnames) }\n\
+ .debug_sfnames 0 : { *(.debug_sfnames) }\n\
+ .line 0 : { *(.line) }\n\
+ /* These must appear regardless of . */\n\
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }\n\
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }\n\
+}\n\n";
+}
+
+struct ld_emulation_xfer_struct ld_elf32ebmip_emulation =
+{
+ gldelf32ebmip_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gldelf32ebmip_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gldelf32ebmip_before_allocation,
+ gldelf32ebmip_get_script,
+ "elf32ebmip",
+ "elf32-bigmips",
+ NULL,
+ NULL,
+ gldelf32ebmip_open_dynamic_archive,
+ gldelf32ebmip_place_orphan
+};
diff --git a/ld/mpw-eppcmac.c b/ld/mpw-eppcmac.c
new file mode 100644
index 00000000000..ba09a410df2
--- /dev/null
+++ b/ld/mpw-eppcmac.c
@@ -0,0 +1,1224 @@
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* AIX emulation code for ppcmacos
+ Copyright (C) 1991, 1993, 1995, 1998 Free Software Foundation, Inc.
+ Written by Steve Chamberlain <sac@cygnus.com>
+ AIX support by Ian Lance Taylor <ian@cygnus.com>
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_ppcmacos
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#include "getopt.h"
+#include "bfdlink.h"
+
+#include <ctype.h>
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldctor.h"
+#include "ldgram.h"
+
+static void gldppcmacos_before_parse PARAMS ((void));
+static int gldppcmacos_parse_args PARAMS ((int, char **));
+static void gldppcmacos_after_open PARAMS ((void));
+static void gldppcmacos_before_allocation PARAMS ((void));
+static void gldppcmacos_read_file PARAMS ((const char *, boolean));
+static void gldppcmacos_free PARAMS ((PTR));
+static void gldppcmacos_find_relocs
+ PARAMS ((lang_statement_union_type *));
+static void gldppcmacos_find_exp_assignment PARAMS ((etree_type *));
+static char *gldppcmacos_get_script PARAMS ((int *isfile));
+
+/* The file alignment required for each section. */
+static unsigned long file_align;
+
+/* The maximum size the stack is permitted to grow. This is stored in
+ the a.out header. */
+static unsigned long maxstack;
+
+/* The maximum data size. This is stored in the a.out header. */
+static unsigned long maxdata;
+
+/* Whether to perform garbage collection. */
+static int gc = 1;
+
+/* The module type to use. */
+static unsigned short modtype = ('1' << 8) | 'L';
+
+/* Whether the .text section must be read-only (i.e., no relocs
+ permitted). */
+static int textro;
+
+/* Whether to implement Unix like linker semantics. */
+static int unix_ld;
+
+/* Structure used to hold import file list. */
+
+struct filelist
+{
+ struct filelist *next;
+ const char *name;
+};
+
+/* List of import files. */
+static struct filelist *import_files;
+
+/* List of export symbols read from the export files. */
+
+struct export_symbol_list
+{
+ struct export_symbol_list *next;
+ const char *name;
+ boolean syscall;
+};
+
+static struct export_symbol_list *export_symbols;
+
+/* This routine is called before anything else is done. */
+
+static void
+gldppcmacos_before_parse()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_output_architecture = bfd_arch_powerpc;
+#endif /* not TARGET_ */
+}
+
+/* Handle AIX specific options. */
+
+static int
+gldppcmacos_parse_args (argc, argv)
+ int argc;
+ char **argv;
+{
+ int prevoptind = optind;
+ int prevopterr = opterr;
+ int indx;
+ int longind;
+ int optc;
+ long val;
+ char *end;
+
+#define OPTION_IGNORE (300)
+#define OPTION_AUTOIMP (OPTION_IGNORE + 1)
+#define OPTION_ERNOTOK (OPTION_AUTOIMP + 1)
+#define OPTION_EROK (OPTION_ERNOTOK + 1)
+#define OPTION_EXPORT (OPTION_EROK + 1)
+#define OPTION_IMPORT (OPTION_EXPORT + 1)
+#define OPTION_LOADMAP (OPTION_IMPORT + 1)
+#define OPTION_MAXDATA (OPTION_LOADMAP + 1)
+#define OPTION_MAXSTACK (OPTION_MAXDATA + 1)
+#define OPTION_MODTYPE (OPTION_MAXSTACK + 1)
+#define OPTION_NOAUTOIMP (OPTION_MODTYPE + 1)
+#define OPTION_NOSTRCMPCT (OPTION_NOAUTOIMP + 1)
+#define OPTION_PD (OPTION_NOSTRCMPCT + 1)
+#define OPTION_PT (OPTION_PD + 1)
+#define OPTION_STRCMPCT (OPTION_PT + 1)
+#define OPTION_UNIX (OPTION_STRCMPCT + 1)
+
+ static struct option longopts[] = {
+ {"basis", no_argument, NULL, OPTION_IGNORE},
+ {"bautoimp", no_argument, NULL, OPTION_AUTOIMP},
+ {"bcomprld", no_argument, NULL, OPTION_IGNORE},
+ {"bcrld", no_argument, NULL, OPTION_IGNORE},
+ {"bcror31", no_argument, NULL, OPTION_IGNORE},
+ {"bD", required_argument, NULL, OPTION_MAXDATA},
+ {"bE", required_argument, NULL, OPTION_EXPORT},
+ {"bernotok", no_argument, NULL, OPTION_ERNOTOK},
+ {"berok", no_argument, NULL, OPTION_EROK},
+ {"berrmsg", no_argument, NULL, OPTION_IGNORE},
+ {"bexport", required_argument, NULL, OPTION_EXPORT},
+ {"bf", no_argument, NULL, OPTION_ERNOTOK},
+ {"bgc", no_argument, &gc, 1},
+ {"bh", required_argument, NULL, OPTION_IGNORE},
+ {"bhalt", required_argument, NULL, OPTION_IGNORE},
+ {"bI", required_argument, NULL, OPTION_IMPORT},
+ {"bimport", required_argument, NULL, OPTION_IMPORT},
+ {"bl", required_argument, NULL, OPTION_LOADMAP},
+ {"bloadmap", required_argument, NULL, OPTION_LOADMAP},
+ {"bmaxdata", required_argument, NULL, OPTION_MAXDATA},
+ {"bmaxstack", required_argument, NULL, OPTION_MAXSTACK},
+ {"bM", required_argument, NULL, OPTION_MODTYPE},
+ {"bmodtype", required_argument, NULL, OPTION_MODTYPE},
+ {"bnoautoimp", no_argument, NULL, OPTION_NOAUTOIMP},
+ {"bnodelcsect", no_argument, NULL, OPTION_IGNORE},
+ {"bnoentry", no_argument, NULL, OPTION_IGNORE},
+ {"bnogc", no_argument, &gc, 0},
+ {"bnso", no_argument, NULL, OPTION_NOAUTOIMP},
+ {"bnostrcmpct", no_argument, NULL, OPTION_NOSTRCMPCT},
+ {"bnotextro", no_argument, &textro, 0},
+ {"bnro", no_argument, &textro, 0},
+ {"bpD", required_argument, NULL, OPTION_PD},
+ {"bpT", required_argument, NULL, OPTION_PT},
+ {"bro", no_argument, &textro, 1},
+ {"bS", required_argument, NULL, OPTION_MAXSTACK},
+ {"bso", no_argument, NULL, OPTION_AUTOIMP},
+ {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT},
+ {"btextro", no_argument, &textro, 1},
+ {"static", no_argument, NULL, OPTION_NOAUTOIMP},
+ {"unix", no_argument, NULL, OPTION_UNIX},
+ {NULL, no_argument, NULL, 0}
+ };
+
+ /* Options supported by the AIX linker which we do not support: -f,
+ -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
+ -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
+ -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
+ -bnobind, -bnocomprld, -bnocrld, -bnoerrmsg, -bnoglink,
+ -bnoloadmap, -bnl, -bnoobjreorder, -bnoquiet, -bnoreorder,
+ -bnotypchk, -bnox, -bquiet, -bR, -brename, -breorder, -btypchk,
+ -bx, -bX, -bxref. */
+
+ /* If the current option starts with -b, change the first : to an =.
+ The AIX linker uses : to separate the option from the argument;
+ changing it to = lets us treat it as a getopt option. */
+ indx = optind;
+ if (indx == 0)
+ indx = 1;
+ if (indx < argc && strncmp (argv[indx], "-b", 2) == 0)
+ {
+ char *s;
+
+ for (s = argv[indx]; *s != '\0'; s++)
+ {
+ if (*s == ':')
+ {
+ *s = '=';
+ break;
+ }
+ }
+ }
+
+ opterr = 0;
+ optc = getopt_long_only (argc, argv, "-D:H:KT:z", longopts, &longind);
+ opterr = prevopterr;
+
+ switch (optc)
+ {
+ default:
+ optind = prevoptind;
+ return 0;
+
+ case 0:
+ /* Long option which just sets a flag. */
+ break;
+
+ case 'D':
+ val = strtol (optarg, &end, 0);
+ if (*end != '\0')
+ einfo (_("%P: warning: ignoring invalid -D number %s\n"), optarg);
+ else if (val != -1)
+ lang_section_start (".data", exp_intop (val));
+ break;
+
+ case 'H':
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0'
+ || (val & (val - 1)) != 0)
+ einfo (_("%P: warning: ignoring invalid -H number %s\n"), optarg);
+ else
+ file_align = val;
+ break;
+
+ case 'K':
+ case 'z':
+ /* FIXME: This should use the page size for the target system. */
+ file_align = 4096;
+ break;
+
+ case 'T':
+ /* On AIX this is the same as GNU ld -Ttext. When we see -T
+ number, we assume the AIX option is intended. Otherwise, we
+ assume the usual GNU ld -T option is intended. We can't just
+ ignore the AIX option, because gcc passes it to the linker. */
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ {
+ optind = prevoptind;
+ return 0;
+ }
+ lang_section_start (".text", exp_intop (val));
+ break;
+
+ case OPTION_IGNORE:
+ break;
+
+ case OPTION_AUTOIMP:
+ link_info.static_link = false;
+ break;
+
+ case OPTION_ERNOTOK:
+ force_make_executable = false;
+ break;
+
+ case OPTION_EROK:
+ force_make_executable = true;
+ break;
+
+ case OPTION_EXPORT:
+ gldppcmacos_read_file (optarg, false);
+ break;
+
+ case OPTION_IMPORT:
+ {
+ struct filelist *n;
+ struct filelist **flpp;
+
+ n = (struct filelist *) xmalloc (sizeof (struct filelist));
+ n->next = NULL;
+ n->name = optarg;
+ flpp = &import_files;
+ while (*flpp != NULL)
+ flpp = &(*flpp)->next;
+ *flpp = n;
+ }
+ break;
+
+ case OPTION_LOADMAP:
+ config.map_filename = optarg;
+ break;
+
+ case OPTION_MAXDATA:
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo (_("%P: warning: ignoring invalid -bmaxdata number %s\n"),
+ optarg);
+ else
+ maxdata = val;
+ break;
+
+ case OPTION_MAXSTACK:
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo (_("%P: warning: ignoring invalid -bmaxstack number %s\n"),
+ optarg);
+ else
+ maxstack = val;
+ break;
+
+ case OPTION_MODTYPE:
+ if (*optarg == 'S')
+ {
+ link_info.shared = true;
+ ++optarg;
+ }
+ if (*optarg == '\0' || optarg[1] == '\0')
+ einfo (_("%P: warning: ignoring invalid module type %s\n"), optarg);
+ else
+ modtype = (*optarg << 8) | optarg[1];
+ break;
+
+ case OPTION_NOAUTOIMP:
+ link_info.static_link = true;
+ break;
+
+ case OPTION_NOSTRCMPCT:
+ link_info.traditional_format = true;
+ break;
+
+ case OPTION_PD:
+ /* This sets the page that the .data section is supposed to
+ start on. The offset within the page should still be the
+ offset within the file, so we need to build an appropriate
+ expression. */
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo (_("%P: warning: ignoring invalid -pD number %s\n"), optarg);
+ else
+ {
+ etree_type *t;
+
+ t = exp_binop ('+',
+ exp_intop (val),
+ exp_binop ('&',
+ exp_nameop (NAME, "."),
+ exp_intop (0xfff)));
+ t = exp_binop ('&',
+ exp_binop ('+', t, exp_intop (7)),
+ exp_intop (~ (bfd_vma) 7));
+ lang_section_start (".data", t);
+ }
+ break;
+
+ case OPTION_PT:
+ /* This set the page that the .text section is supposed to start
+ on. The offset within the page should still be the offset
+ within the file. */
+ val = strtoul (optarg, &end, 0);
+ if (*end != '\0')
+ einfo (_("%P: warning: ignoring invalid -pT number %s\n"), optarg);
+ else
+ {
+ etree_type *t;
+
+ t = exp_binop ('+',
+ exp_intop (val),
+ exp_nameop (SIZEOF_HEADERS, NULL));
+ t = exp_binop ('&',
+ exp_binop ('+', t, exp_intop (7)),
+ exp_intop (~ (bfd_vma) 7));
+ lang_section_start (".text", t);
+ }
+ break;
+
+ case OPTION_STRCMPCT:
+ link_info.traditional_format = false;
+ break;
+
+ case OPTION_UNIX:
+ unix_ld = true;
+ break;
+ }
+
+ return 1;
+}
+
+/* This is called when an input file can not be recognized as a BFD
+ object or an archive. If the file starts with #!, we must treat it
+ as an import file. This is for AIX compatibility. */
+
+static boolean
+gldppcmacos_unrecognized_file (entry)
+ lang_input_statement_type *entry;
+{
+ FILE *e;
+ boolean ret;
+
+ e = fopen (entry->filename, FOPEN_RT);
+ if (e == NULL)
+ return false;
+
+ ret = false;
+
+ if (getc (e) == '#' && getc (e) == '!')
+ {
+ struct filelist *n;
+ struct filelist **flpp;
+
+ n = (struct filelist *) xmalloc (sizeof (struct filelist));
+ n->next = NULL;
+ n->name = entry->filename;
+ flpp = &import_files;
+ while (*flpp != NULL)
+ flpp = &(*flpp)->next;
+ *flpp = n;
+
+ ret = true;
+ entry->loaded = true;
+ }
+
+ fclose (e);
+
+ return ret;
+}
+
+/* This is called after the input files have been opened. */
+
+static void
+gldppcmacos_after_open ()
+{
+ boolean r;
+ struct set_info *p;
+
+ /* Call ldctor_build_sets, after pretending that this is a
+ relocateable link. We do this because AIX requires relocation
+ entries for all references to symbols, even in a final
+ executable. Of course, we only want to do this if we are
+ producing an XCOFF output file. */
+ r = link_info.relocateable;
+ if (strstr (bfd_get_target (output_bfd), "xcoff") != NULL)
+ link_info.relocateable = true;
+ ldctor_build_sets ();
+ link_info.relocateable = r;
+
+ /* For each set, record the size, so that the XCOFF backend can
+ output the correct csect length. */
+ for (p = sets; p != (struct set_info *) NULL; p = p->next)
+ {
+ bfd_size_type size;
+
+ /* If the symbol is defined, we may have been invoked from
+ collect, and the sets may already have been built, so we do
+ not do anything. */
+ if (p->h->type == bfd_link_hash_defined
+ || p->h->type == bfd_link_hash_defweak)
+ continue;
+
+ if (p->reloc != BFD_RELOC_CTOR)
+ {
+ /* Handle this if we need to. */
+ abort ();
+ }
+
+ size = (p->count + 2) * 4;
+ if (! bfd_xcoff_link_record_set (output_bfd, &link_info, p->h, size))
+ einfo (_("%F%P: bfd_xcoff_link_record_set failed: %E\n"));
+ }
+}
+
+/* This is called after the sections have been attached to output
+ sections, but before any sizes or addresses have been set. */
+
+static void
+gldppcmacos_before_allocation ()
+{
+ struct filelist *fl;
+ struct export_symbol_list *el;
+ char *libpath;
+ asection *special_sections[6];
+ int i;
+
+ /* Handle the import and export files, if any. */
+ for (fl = import_files; fl != NULL; fl = fl->next)
+ gldppcmacos_read_file (fl->name, true);
+ for (el = export_symbols; el != NULL; el = el->next)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false);
+ if (h == NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n"));
+ if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall))
+ einfo (_("%P%F: bfd_xcoff_export_symbol failed: %E\n"));
+ }
+
+ /* Track down all relocations called for by the linker script (these
+ are typically constructor/destructor entries created by
+ CONSTRUCTORS) and let the backend know it will need to create
+ .loader relocs for them. */
+ lang_for_each_statement (gldppcmacos_find_relocs);
+
+ /* We need to build LIBPATH from the -L arguments. If any -rpath
+ arguments were used, though, we use -rpath instead, as a GNU
+ extension. */
+ if (command_line.rpath != NULL)
+ libpath = command_line.rpath;
+ else if (search_head == NULL)
+ libpath = (char *) "";
+ else
+ {
+ size_t len;
+ search_dirs_type *search;
+
+ len = strlen (search_head->name);
+ libpath = xmalloc (len + 1);
+ strcpy (libpath, search_head->name);
+ for (search = search_head->next; search != NULL; search = search->next)
+ {
+ size_t nlen;
+
+ nlen = strlen (search->name);
+ libpath = xrealloc (libpath, len + nlen + 2);
+ libpath[len] = ':';
+ strcpy (libpath + len + 1, search->name);
+ len += nlen + 1;
+ }
+ }
+
+ /* Let the XCOFF backend set up the .loader section. */
+ if (! bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath,
+ entry_symbol, file_align,
+ maxstack, maxdata,
+ gc && ! unix_ld ? true : false,
+ modtype,
+ textro ? true : false,
+ unix_ld,
+ special_sections))
+ einfo (_("%P%F: failed to set dynamic section sizes: %E\n"));
+
+ /* Look through the special sections, and put them in the right
+ place in the link ordering. This is especially magic. */
+ for (i = 0; i < 6; i++)
+ {
+ asection *sec;
+ lang_output_section_statement_type *os;
+ lang_statement_union_type **pls;
+ lang_input_section_type *is;
+ const char *oname;
+ boolean start;
+
+ sec = special_sections[i];
+ if (sec == NULL)
+ continue;
+
+ /* Remove this section from the list of the output section.
+ This assumes we know what the script looks like. */
+ is = NULL;
+ os = lang_output_section_find (sec->output_section->name);
+ if (os == NULL)
+ einfo (_("%P%F: can't find output section %s\n"),
+ sec->output_section->name);
+ for (pls = &os->children.head; *pls != NULL; pls = &(*pls)->next)
+ {
+ if ((*pls)->header.type == lang_input_section_enum
+ && (*pls)->input_section.section == sec)
+ {
+ is = (lang_input_section_type *) *pls;
+ *pls = (*pls)->next;
+ break;
+ }
+ if ((*pls)->header.type == lang_wild_statement_enum)
+ {
+ lang_statement_union_type **pwls;
+
+ for (pwls = &(*pls)->wild_statement.children.head;
+ *pwls != NULL;
+ pwls = &(*pwls)->next)
+ {
+ if ((*pwls)->header.type == lang_input_section_enum
+ && (*pwls)->input_section.section == sec)
+ {
+ is = (lang_input_section_type *) *pwls;
+ *pwls = (*pwls)->next;
+ break;
+ }
+ }
+ if (is != NULL)
+ break;
+ }
+ }
+
+ if (is == NULL)
+ einfo (_("%P%F: can't find %s in output section\n"),
+ bfd_get_section_name (sec->owner, sec));
+
+ /* Now figure out where the section should go. */
+ switch (i)
+ {
+ default: /* to avoid warnings */
+ case 0:
+ /* _text */
+ oname = ".text";
+ start = true;
+ break;
+ case 1:
+ /* _etext */
+ oname = ".text";
+ start = false;
+ break;
+ case 2:
+ /* _data */
+ oname = ".data";
+ start = true;
+ break;
+ case 3:
+ /* _edata */
+ oname = ".data";
+ start = false;
+ break;
+ case 4:
+ case 5:
+ /* _end and end */
+ oname = ".bss";
+ start = false;
+ break;
+ }
+
+ os = lang_output_section_find (oname);
+
+ if (start)
+ {
+ is->header.next = os->children.head;
+ os->children.head = (lang_statement_union_type *) is;
+ }
+ else
+ {
+ is->header.next = NULL;
+ lang_statement_append (&os->children,
+ (lang_statement_union_type *) is,
+ &is->header.next);
+ }
+ }
+}
+
+/* Read an import or export file. For an import file, this is called
+ by the before_allocation emulation routine. For an export file,
+ this is called by the parse_args emulation routine. */
+
+static void
+gldppcmacos_read_file (filename, import)
+ const char *filename;
+ boolean import;
+{
+ struct obstack *o;
+ FILE *f;
+ int lineno;
+ int c;
+ boolean keep;
+ const char *imppath;
+ const char *impfile;
+ const char *impmember;
+
+ o = (struct obstack *) xmalloc (sizeof (struct obstack));
+ obstack_specify_allocation (o, 0, 0, xmalloc, gldppcmacos_free);
+
+ f = fopen (filename, FOPEN_RT);
+ if (f == NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ einfo ("%F%s: %E\n", filename);
+ }
+
+ keep = false;
+
+ imppath = NULL;
+ impfile = NULL;
+ impmember = NULL;
+
+ lineno = 0;
+ while ((c = getc (f)) != EOF)
+ {
+ char *s;
+ char *symname;
+ boolean syscall;
+ bfd_vma address;
+ struct bfd_link_hash_entry *h;
+
+ if (c != '\n')
+ {
+ obstack_1grow (o, c);
+ continue;
+ }
+
+ obstack_1grow (o, '\0');
+ ++lineno;
+
+ s = (char *) obstack_base (o);
+ while (isspace ((unsigned char) *s))
+ ++s;
+ if (*s == '\0'
+ || *s == '*'
+ || (*s == '#' && s[1] == ' ')
+ || (! import && *s == '#' && s[1] == '!'))
+ {
+ obstack_free (o, obstack_base (o));
+ continue;
+ }
+
+ if (*s == '#' && s[1] == '!')
+ {
+ s += 2;
+ while (isspace ((unsigned char) *s))
+ ++s;
+ if (*s == '\0')
+ {
+ imppath = NULL;
+ impfile = NULL;
+ impmember = NULL;
+ obstack_free (o, obstack_base (o));
+ }
+ else if (*s == '(')
+ einfo (_("%F%s%d: #! ([member]) is not supported in import files\n"),
+ filename, lineno);
+ else
+ {
+ char cs;
+ char *file;
+
+ (void) obstack_finish (o);
+ keep = true;
+ imppath = s;
+ file = NULL;
+ while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0')
+ {
+ if (*s == '/')
+ file = s + 1;
+ ++s;
+ }
+ if (file != NULL)
+ {
+ file[-1] = '\0';
+ impfile = file;
+ if (imppath == file - 1)
+ imppath = "/";
+ }
+ else
+ {
+ impfile = imppath;
+ imppath = "";
+ }
+ cs = *s;
+ *s = '\0';
+ while (isspace ((unsigned char) cs))
+ {
+ ++s;
+ cs = *s;
+ }
+ if (cs != '(')
+ {
+ impmember = "";
+ if (cs != '\0')
+ einfo (_("%s:%d: warning: syntax error in import file\n"),
+ filename, lineno);
+ }
+ else
+ {
+ ++s;
+ impmember = s;
+ while (*s != ')' && *s != '\0')
+ ++s;
+ if (*s == ')')
+ *s = '\0';
+ else
+ einfo (_("%s:%d: warning: syntax error in import file\n"),
+ filename, lineno);
+ }
+ }
+
+ continue;
+ }
+
+ /* This is a symbol to be imported or exported. */
+ symname = s;
+ syscall = false;
+ address = (bfd_vma) -1;
+
+ while (! isspace ((unsigned char) *s) && *s != '\0')
+ ++s;
+ if (*s != '\0')
+ {
+ char *se;
+
+ *s++ = '\0';
+
+ while (isspace ((unsigned char) *s))
+ ++s;
+
+ se = s;
+ while (! isspace ((unsigned char) *se) && *se != '\0')
+ ++se;
+ if (*se != '\0')
+ {
+ *se++ = '\0';
+ while (isspace ((unsigned char) *se))
+ ++se;
+ if (*se != '\0')
+ einfo (_("%s%d: warning: syntax error in import/export file\n"),
+ filename, lineno);
+ }
+
+ if (strcasecmp (s, "svc") == 0
+ || strcasecmp (s, "syscall") == 0)
+ syscall = true;
+ else
+ {
+ char *end;
+
+ address = strtoul (s, &end, 0);
+ if (*end != '\0')
+ einfo (_("%s:%d: warning: syntax error in import/export file\n"),
+ filename, lineno);
+ }
+ }
+
+ if (! import)
+ {
+ struct export_symbol_list *n;
+
+ ldlang_add_undef (symname);
+ n = ((struct export_symbol_list *)
+ xmalloc (sizeof (struct export_symbol_list)));
+ n->next = export_symbols;
+ n->name = buystring (symname);
+ n->syscall = syscall;
+ export_symbols = n;
+ }
+ else
+ {
+ h = bfd_link_hash_lookup (link_info.hash, symname, false, false,
+ true);
+ if (h == NULL || h->type == bfd_link_hash_new)
+ {
+ /* We can just ignore attempts to import an unreferenced
+ symbol. */
+ }
+ else
+ {
+ if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h,
+ address, imppath, impfile,
+ impmember))
+ einfo (_("%X%s:%d: failed to import symbol %s: %E\n"),
+ filename, lineno, symname);
+ }
+ }
+
+ obstack_free (o, obstack_base (o));
+ }
+
+ if (obstack_object_size (o) > 0)
+ {
+ einfo (_("%s:%d: warning: ignoring unterminated last line\n"),
+ filename, lineno);
+ obstack_free (o, obstack_base (o));
+ }
+
+ if (! keep)
+ {
+ obstack_free (o, NULL);
+ free (o);
+ }
+}
+
+/* This routine saves us from worrying about declaring free. */
+
+static void
+gldppcmacos_free (p)
+ PTR p;
+{
+ free (p);
+}
+
+/* This is called by the before_allocation routine via
+ lang_for_each_statement. It looks for relocations and assignments
+ to symbols. */
+
+static void
+gldppcmacos_find_relocs (s)
+ lang_statement_union_type *s;
+{
+ if (s->header.type == lang_reloc_statement_enum)
+ {
+ lang_reloc_statement_type *rs;
+
+ rs = &s->reloc_statement;
+ if (rs->name == NULL)
+ einfo (_("%F%P: only relocations against symbols are permitted\n"));
+ if (! bfd_xcoff_link_count_reloc (output_bfd, &link_info, rs->name))
+ einfo (_("%F%P: bfd_xcoff_link_count_reloc failed: %E\n"));
+ }
+
+ if (s->header.type == lang_assignment_statement_enum)
+ gldppcmacos_find_exp_assignment (s->assignment_statement.exp);
+}
+
+/* Look through an expression for an assignment statement. */
+
+static void
+gldppcmacos_find_exp_assignment (exp)
+ etree_type *exp;
+{
+ struct bfd_link_hash_entry *h;
+
+ switch (exp->type.node_class)
+ {
+ case etree_provide:
+ h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
+ false, false, false);
+ if (h == NULL)
+ break;
+ /* Fall through. */
+ case etree_assign:
+ if (strcmp (exp->assign.dst, ".") != 0)
+ {
+ if (! bfd_xcoff_record_link_assignment (output_bfd, &link_info,
+ exp->assign.dst))
+ einfo (_("%P%F: failed to record assignment to %s: %E\n"),
+ exp->assign.dst);
+ }
+ gldppcmacos_find_exp_assignment (exp->assign.src);
+ break;
+
+ case etree_binary:
+ gldppcmacos_find_exp_assignment (exp->binary.lhs);
+ gldppcmacos_find_exp_assignment (exp->binary.rhs);
+ break;
+
+ case etree_trinary:
+ gldppcmacos_find_exp_assignment (exp->trinary.cond);
+ gldppcmacos_find_exp_assignment (exp->trinary.lhs);
+ gldppcmacos_find_exp_assignment (exp->trinary.rhs);
+ break;
+
+ case etree_unary:
+ gldppcmacos_find_exp_assignment (exp->unary.child);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static char *
+gldppcmacos_get_script(isfile)
+ int *isfile;
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+"OUTPUT_FORMAT(\"xcoff-powermac\")\n\
+OUTPUT_ARCH(powerpc)\n\
+ENTRY(__start)\n\
+SECTIONS\n\
+{\n\
+ .pad 0 : { *(.pad) }\n\
+ .text 0 : {\n\
+ *(.text)\n\
+ *(.pr)\n\
+ *(.ro)\n\
+ *(.db)\n\
+ *(.gl)\n\
+ *(.xo)\n\
+ *(.ti)\n\
+ *(.tb)\n\
+ }\n\
+ .data 0 : {\n\
+ *(.data)\n\
+ *(.rw)\n\
+ *(.sv)\n\
+ *(.ua)\n\
+ . = ALIGN(4);\n\
+ CONSTRUCTORS\n\
+ *(.ds)\n\
+ *(.tc0)\n\
+ *(.tc)\n\
+ *(.td)\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(.bs)\n\
+ *(.uc)\n\
+ *(COMMON)\n\
+ }\n\
+ .loader 0 : {\n\
+ *(.loader)\n\
+ }\n\
+ .debug 0 : {\n\
+ *(.debug)\n\
+ }\n\
+}\n\n"
+ ; else if (link_info.relocateable == true) return
+"OUTPUT_FORMAT(\"xcoff-powermac\")\n\
+OUTPUT_ARCH(powerpc)\n\
+ENTRY(__start)\n\
+SECTIONS\n\
+{\n\
+ .pad 0 : { *(.pad) }\n\
+ .text 0 : {\n\
+ *(.text)\n\
+ *(.pr)\n\
+ *(.ro)\n\
+ *(.db)\n\
+ *(.gl)\n\
+ *(.xo)\n\
+ *(.ti)\n\
+ *(.tb)\n\
+ }\n\
+ .data 0 : {\n\
+ *(.data)\n\
+ *(.rw)\n\
+ *(.sv)\n\
+ *(.ua)\n\
+ . = ALIGN(4);\n\
+ *(.ds)\n\
+ *(.tc0)\n\
+ *(.tc)\n\
+ *(.td)\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(.bs)\n\
+ *(.uc)\n\
+ *(COMMON)\n\
+ }\n\
+ .loader 0 : {\n\
+ *(.loader)\n\
+ }\n\
+ .debug 0 : {\n\
+ *(.debug)\n\
+ }\n\
+}\n\n"
+ ; else if (!config.text_read_only) return
+"OUTPUT_FORMAT(\"xcoff-powermac\")\n\
+OUTPUT_ARCH(powerpc)\n\
+ SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\
+ENTRY(__start)\n\
+SECTIONS\n\
+{\n\
+ .pad 0 : { *(.pad) }\n\
+ .text : {\n\
+ PROVIDE (_text = .);\n\
+ *(.text)\n\
+ *(.pr)\n\
+ *(.ro)\n\
+ *(.db)\n\
+ *(.gl)\n\
+ *(.xo)\n\
+ *(.ti)\n\
+ *(.tb)\n\
+ PROVIDE (_etext = .);\n\
+ }\n\
+ .data 0 : {\n\
+ PROVIDE (_data = .);\n\
+ *(.data)\n\
+ *(.rw)\n\
+ *(.sv)\n\
+ *(.ua)\n\
+ . = ALIGN(4);\n\
+ CONSTRUCTORS\n\
+ *(.ds)\n\
+ *(.tc0)\n\
+ *(.tc)\n\
+ *(.td)\n\
+ PROVIDE (_edata = .);\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(.bs)\n\
+ *(.uc)\n\
+ *(COMMON)\n\
+ PROVIDE (_end = .);\n\
+ PROVIDE (end = .);\n\
+ }\n\
+ .loader 0 : {\n\
+ *(.loader)\n\
+ }\n\
+ .debug 0 : {\n\
+ *(.debug)\n\
+ }\n\
+}\n\n"
+ ; else if (!config.magic_demand_paged) return
+"OUTPUT_FORMAT(\"xcoff-powermac\")\n\
+OUTPUT_ARCH(powerpc)\n\
+ SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\
+ENTRY(__start)\n\
+SECTIONS\n\
+{\n\
+ .pad 0 : { *(.pad) }\n\
+ .text : {\n\
+ PROVIDE (_text = .);\n\
+ *(.text)\n\
+ *(.pr)\n\
+ *(.ro)\n\
+ *(.db)\n\
+ *(.gl)\n\
+ *(.xo)\n\
+ *(.ti)\n\
+ *(.tb)\n\
+ PROVIDE (_etext = .);\n\
+ }\n\
+ .data 0 : {\n\
+ PROVIDE (_data = .);\n\
+ *(.data)\n\
+ *(.rw)\n\
+ *(.sv)\n\
+ *(.ua)\n\
+ . = ALIGN(4);\n\
+ CONSTRUCTORS\n\
+ *(.ds)\n\
+ *(.tc0)\n\
+ *(.tc)\n\
+ *(.td)\n\
+ PROVIDE (_edata = .);\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(.bs)\n\
+ *(.uc)\n\
+ *(COMMON)\n\
+ PROVIDE (_end = .);\n\
+ PROVIDE (end = .);\n\
+ }\n\
+ .loader 0 : {\n\
+ *(.loader)\n\
+ }\n\
+ .debug 0 : {\n\
+ *(.debug)\n\
+ }\n\
+}\n\n"
+ ; else return
+"OUTPUT_FORMAT(\"xcoff-powermac\")\n\
+OUTPUT_ARCH(powerpc)\n\
+ SEARCH_DIR(/usr/local/powerpc-apple-macos/lib);\n\
+ENTRY(__start)\n\
+SECTIONS\n\
+{\n\
+ .pad 0 : { *(.pad) }\n\
+ .text : {\n\
+ PROVIDE (_text = .);\n\
+ *(.text)\n\
+ *(.pr)\n\
+ *(.ro)\n\
+ *(.db)\n\
+ *(.gl)\n\
+ *(.xo)\n\
+ *(.ti)\n\
+ *(.tb)\n\
+ PROVIDE (_etext = .);\n\
+ }\n\
+ .data 0 : {\n\
+ PROVIDE (_data = .);\n\
+ *(.data)\n\
+ *(.rw)\n\
+ *(.sv)\n\
+ *(.ua)\n\
+ . = ALIGN(4);\n\
+ CONSTRUCTORS\n\
+ *(.ds)\n\
+ *(.tc0)\n\
+ *(.tc)\n\
+ *(.td)\n\
+ PROVIDE (_edata = .);\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(.bs)\n\
+ *(.uc)\n\
+ *(COMMON)\n\
+ PROVIDE (_end = .);\n\
+ PROVIDE (end = .);\n\
+ }\n\
+ .loader 0 : {\n\
+ *(.loader)\n\
+ }\n\
+ .debug 0 : {\n\
+ *(.debug)\n\
+ }\n\
+}\n\n"
+; }
+
+struct ld_emulation_xfer_struct ld_ppcmacos_emulation =
+{
+ gldppcmacos_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gldppcmacos_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gldppcmacos_before_allocation,
+ gldppcmacos_get_script,
+ "ppcmacos",
+ "xcoff-powermac",
+ 0, /* finish */
+ 0, /* create_output_section_statements */
+ 0, /* open_dynamic_archive */
+ 0, /* place_orphan */
+ 0, /* set_symbols */
+ gldppcmacos_parse_args,
+ gldppcmacos_unrecognized_file
+};
diff --git a/ld/mpw-esh.c b/ld/mpw-esh.c
new file mode 100644
index 00000000000..93bc5f54c72
--- /dev/null
+++ b/ld/mpw-esh.c
@@ -0,0 +1,315 @@
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* emulate the original gld for the given sh
+ Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+ Written by Steve Chamberlain steve@cygnus.com
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_sh
+
+#include "libiberty.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+static void gldsh_before_parse PARAMS ((void));
+static char *gldsh_get_script PARAMS ((int *isfile));
+
+static void
+gldsh_before_parse()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_output_architecture = bfd_arch_sh;
+#endif /* not TARGET_ */
+}
+
+static char *
+gldsh_get_script(isfile)
+ int *isfile;
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+concat(
+"OUTPUT_FORMAT(\"coff-sh\")\n\
+OUTPUT_ARCH(sh)\n\
+MEMORY\n\
+{\n\
+ ram : o = 0x1000, l = 512k\n\
+}\n\
+ "," SECTIONS\n\
+{\n\
+ "," .text :\n\
+ {\n\
+ *(.text)\n\
+ *(.strings)\n\
+ } \n\
+ .tors :\n\
+ {\n\
+ ___ctors = . ;\n\
+ *(.ctors)\n\
+ ___ctors_end = . ;\n\
+ ___dtors = . ;\n\
+ *(.dtors)\n\
+ ___dtors_end = . ;\n\
+ } \n\
+ "," .data :\n\
+ {\n\
+ *(.data)\n\
+ } \n\
+ "," .bss :\n\
+ {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ } \n\
+ "," .stack :\n\
+ {\n\
+ *(.stack)\n\
+ } \n\
+ "," .stab 0 :\n\
+ {\n\
+ *(.stab)\n\
+ }\n\
+ "," .stabstr 0 :\n\
+ {\n\
+ *(.stabstr)\n\
+ }\n\
+}\n\n", NULL)
+ ; else if (link_info.relocateable == true) return
+concat (
+"OUTPUT_FORMAT(\"coff-sh\")\n\
+OUTPUT_ARCH(sh)\n\
+ "," MEMORY\n\
+{\n\
+ ram : o = 0x1000, l = 512k\n\
+}\n\
+ "," SECTIONS\n\
+{\n\
+ "," .text :\n\
+ {\n\
+ *(.text)\n\
+ *(.strings)\n\
+ } \n\
+ "," .tors :\n\
+ {\n\
+ ___ctors = . ;\n\
+ *(.ctors)\n\
+ ___ctors_end = . ;\n\
+ ___dtors = . ;\n\
+ *(.dtors)\n\
+ ___dtors_end = . ;\n\
+ } \n\
+ "," .data :\n\
+ {\n\
+ *(.data)\n\
+ } \n\
+ "," .bss :\n\
+ {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ } \n\
+ "," .stack :\n\
+ {\n\
+ *(.stack)\n\
+ } \n\
+ "," .stab 0 :\n\
+ {\n\
+ *(.stab)\n\
+ }\n\
+ "," .stabstr 0 :\n\
+ {\n\
+ *(.stabstr)\n\
+ }\n\
+}\n\n", NULL)
+ ; else if (!config.text_read_only) return
+concat (
+"OUTPUT_FORMAT(\"coff-sh\")\n\
+OUTPUT_ARCH(sh)\n\
+MEMORY\n\
+{\n\
+ ram : o = 0x1000, l = 512k\n\
+}\n\
+SECTIONS\n\
+{\n\
+ "," .text :\n\
+ {\n\
+ *(.text)\n\
+ *(.strings)\n\
+ _etext = . ; \n\
+ } > ram\n\
+ "," .tors :\n\
+ {\n\
+ ___ctors = . ;\n\
+ *(.ctors)\n\
+ ___ctors_end = . ;\n\
+ ___dtors = . ;\n\
+ *(.dtors)\n\
+ ___dtors_end = . ;\n\
+ } > ram\n\
+ "," .data :\n\
+ {\n\
+ *(.data)\n\
+ _edata = . ; \n\
+ } > ram\n\
+ "," .bss :\n\
+ {\n\
+ _bss_start = . ; \n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ _end = . ; \n\
+ } > ram\n\
+ "," .stack 0x30000 :\n\
+ {\n\
+ _stack = . ; \n\
+ *(.stack)\n\
+ } > ram\n\
+ "," .stab 0 (NOLOAD) :\n\
+ {\n\
+ *(.stab)\n\
+ }\n\
+ "," .stabstr 0 (NOLOAD) :\n\
+ {\n\
+ *(.stabstr)\n\
+ }\n\
+}\n\n", NULL)
+ ; else if (!config.magic_demand_paged) return
+concat (
+"OUTPUT_FORMAT(\"coff-sh\")\n\
+OUTPUT_ARCH(sh)\n\
+MEMORY\n\
+{\n\
+ ram : o = 0x1000, l = 512k\n\
+}\n\
+SECTIONS\n\
+{\n\
+ "," .text :\n\
+ {\n\
+ *(.text)\n\
+ *(.strings)\n\
+ _etext = . ; \n\
+ } > ram\n\
+ "," .tors :\n\
+ {\n\
+ ___ctors = . ;\n\
+ *(.ctors)\n\
+ ___ctors_end = . ;\n\
+ ___dtors = . ;\n\
+ *(.dtors)\n\
+ ___dtors_end = . ;\n\
+ } > ram\n\
+ "," .data :\n\
+ {\n\
+ *(.data)\n\
+ _edata = . ; \n\
+ } > ram\n\
+ "," .bss :\n\
+ {\n\
+ _bss_start = . ; \n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ _end = . ; \n\
+ } > ram\n\
+ "," .stack 0x30000 :\n\
+ {\n\
+ _stack = . ; \n\
+ *(.stack)\n\
+ } > ram\n\
+ "," .stab 0 (NOLOAD) :\n\
+ {\n\
+ *(.stab)\n\
+ }\n\
+ "," .stabstr 0 (NOLOAD) :\n\
+ {\n\
+ *(.stabstr)\n\
+ }\n\
+}\n\n", NULL)
+ ; else return
+concat (
+"OUTPUT_FORMAT(\"coff-sh\")\n\
+OUTPUT_ARCH(sh)\n\
+MEMORY\n\
+{\n\
+ ram : o = 0x1000, l = 512k\n\
+}\n\
+SECTIONS\n\
+{\n\
+ "," .text :\n\
+ {\n\
+ *(.text)\n\
+ *(.strings)\n\
+ _etext = . ; \n\
+ } > ram\n\
+ "," .tors :\n\
+ {\n\
+ ___ctors = . ;\n\
+ *(.ctors)\n\
+ ___ctors_end = . ;\n\
+ ___dtors = . ;\n\
+ *(.dtors)\n\
+ ___dtors_end = . ;\n\
+ } > ram\n\
+ "," .data :\n\
+ {\n\
+ *(.data)\n\
+ _edata = . ; \n\
+ } > ram\n\
+ "," .bss :\n\
+ {\n\
+ _bss_start = . ; \n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ _end = . ; \n\
+ } > ram\n\
+ "," .stack 0x30000 :\n\
+ {\n\
+ _stack = . ; \n\
+ *(.stack)\n\
+ } > ram\n\
+ "," .stab 0 (NOLOAD) :\n\
+ {\n\
+ *(.stab)\n\
+ }\n\
+ "," .stabstr 0 (NOLOAD) :\n\
+ {\n\
+ *(.stabstr)\n\
+ }\n\
+}\n\n", NULL)
+; }
+
+struct ld_emulation_xfer_struct ld_sh_emulation =
+{
+ gldsh_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ after_open_default,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ before_allocation_default,
+ gldsh_get_script,
+ "sh",
+ "coff-sh"
+};
diff --git a/ld/mpw-idtmips.c b/ld/mpw-idtmips.c
new file mode 100644
index 00000000000..08ddc70393a
--- /dev/null
+++ b/ld/mpw-idtmips.c
@@ -0,0 +1,430 @@
+/* This file is is generated by a shell script. DO NOT EDIT! */
+
+/* Handle embedded relocs for MIPS.
+ Copyright 1994 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@cygnus.com> based on generic.em.
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define TARGET_IS_mipsidt
+
+#include "libiberty.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+
+static void gldmipsidt_before_parse PARAMS ((void));
+static void gldmipsidt_after_open PARAMS ((void));
+static void check_sections PARAMS ((bfd *, asection *, PTR));
+static void gldmipsidt_after_allocation PARAMS ((void));
+static char *gldmipsidt_get_script PARAMS ((int *isfile));
+
+static void
+gldmipsidt_before_parse()
+{
+#ifndef TARGET_ /* I.e., if not generic. */
+ ldfile_output_architecture = bfd_arch_mips;
+#endif /* not TARGET_ */
+}
+
+/* This function is run after all the input files have been opened.
+ We create a .rel.sdata section for each input file with a non zero
+ .sdata section. The BFD backend will fill in these sections with
+ magic numbers which can be used to relocate the data section at run
+ time. This will only do the right thing if all the input files
+ have been compiled using -membedded-pic. */
+
+static void
+gldmipsidt_after_open ()
+{
+ bfd *abfd;
+
+ if (! command_line.embedded_relocs
+ || link_info.relocateable)
+ return;
+
+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+ {
+ asection *datasec;
+
+ datasec = bfd_get_section_by_name (abfd, ".sdata");
+
+ /* Note that we assume that the reloc_count field has already
+ been set up. We could call bfd_get_reloc_upper_bound, but
+ that returns the size of a memory buffer rather than a reloc
+ count. We do not want to call bfd_canonicalize_reloc,
+ because although it would always work it would force us to
+ read in the relocs into BFD canonical form, which would waste
+ a significant amount of time and memory. */
+ if (datasec != NULL && datasec->reloc_count > 0)
+ {
+ asection *relsec;
+
+ relsec = bfd_make_section (abfd, ".rel.sdata");
+ if (relsec == NULL
+ || ! bfd_set_section_flags (abfd, relsec,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY))
+ || ! bfd_set_section_alignment (abfd, relsec, 2)
+ || ! bfd_set_section_size (abfd, relsec,
+ datasec->reloc_count * 4))
+ einfo (_("%F%B: can not create .rel.sdata section: %E\n"));
+ }
+
+ /* Double check that all other data sections are empty, as is
+ required for embedded PIC code. */
+ bfd_map_over_sections (abfd, check_sections, (PTR) datasec);
+ }
+}
+
+/* Check that of the data sections, only the .sdata section has
+ relocs. This is called via bfd_map_over_sections. */
+
+static void
+check_sections (abfd, sec, sdatasec)
+ bfd *abfd;
+ asection *sec;
+ PTR sdatasec;
+{
+ if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0
+ && sec != (asection *) sdatasec
+ && sec->reloc_count != 0)
+ einfo (_("%F%X: section %s has relocs; can not use --embedded-relocs\n"),
+ abfd, bfd_get_section_name (abfd, sec));
+}
+
+/* This function is called after the section sizes and offsets have
+ been set. If we are generating embedded relocs, it calls a special
+ BFD backend routine to do the work. */
+
+static void
+gldmipsidt_after_allocation ()
+{
+ bfd *abfd;
+
+ if (! command_line.embedded_relocs
+ || link_info.relocateable)
+ return;
+
+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
+ {
+ asection *datasec, *relsec;
+ char *errmsg;
+
+ datasec = bfd_get_section_by_name (abfd, ".sdata");
+
+ if (datasec == NULL || datasec->reloc_count == 0)
+ continue;
+
+ relsec = bfd_get_section_by_name (abfd, ".rel.sdata");
+ ASSERT (relsec != NULL);
+
+ if (! bfd_mips_ecoff_create_embedded_relocs (abfd, &link_info,
+ datasec, relsec,
+ &errmsg))
+ {
+ if (errmsg == NULL)
+ einfo (_("%B%X: can not create runtime reloc information: %E\n"),
+ abfd);
+ else
+ einfo (_("%X%B: can not create runtime reloc information: %s\n"),
+ abfd, errmsg);
+ }
+ }
+}
+
+static char *
+gldmipsidt_get_script(isfile)
+ int *isfile;
+{
+ *isfile = 0;
+
+ if (link_info.relocateable == true && config.build_constructors == true)
+ return
+concat(
+"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\
+ \"ecoff-littlemips\")\n\
+ SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\
+ENTRY(start)\n\
+SECTIONS\n\
+{\n\
+ .text : {\n\
+ ;\n\
+ *(.init)\n\
+ ;\n\
+ *(.text)\n\
+ *(.rel.sdata)\n\
+ *(.fini)\n\
+ ;\n\
+ ;\n\
+ }\n\
+ "," .rdata : {\n\
+ *(.rdata)\n\
+ }\n\
+ .data : {\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ .lit8 : {\n\
+ *(.lit8)\n\
+ }\n\
+ .lit4 : {\n\
+ *(.lit4)\n\
+ }\n\
+ "," .sdata : {\n\
+ *(.sdata)\n\
+ }\n\
+ .sbss : {\n\
+ *(.sbss)\n\
+ *(.scommon)\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+}\n\n", NULL)
+ ; else if (link_info.relocateable == true) return
+"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\
+ \"ecoff-littlemips\")\n\
+ SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\
+ENTRY(start)\n\
+SECTIONS\n\
+{\n\
+ .text : {\n\
+ ;\n\
+ *(.init)\n\
+ ;\n\
+ *(.text)\n\
+ *(.rel.sdata)\n\
+ *(.fini)\n\
+ ;\n\
+ ;\n\
+ }\n\
+ .rdata : {\n\
+ *(.rdata)\n\
+ }\n\
+ .data : {\n\
+ *(.data)\n\
+ }\n\
+ .lit8 : {\n\
+ *(.lit8)\n\
+ }\n\
+ .lit4 : {\n\
+ *(.lit4)\n\
+ }\n\
+ .sdata : {\n\
+ *(.sdata)\n\
+ }\n\
+ .sbss : {\n\
+ *(.sbss)\n\
+ *(.scommon)\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+}\n\n"
+ ; else if (!config.text_read_only) return
+concat(
+"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\
+ \"ecoff-littlemips\")\n\
+ SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\
+ENTRY(start)\n\
+SECTIONS\n\
+{\n\
+ . = 0xa0012000;\n\
+ .text : {\n\
+ _ftext = . ;\n\
+ *(.init)\n\
+ eprol = .;\n\
+ *(.text)\n\
+ PROVIDE (__runtime_reloc_start = .);\n\
+ *(.rel.sdata)\n\
+ PROVIDE (__runtime_reloc_stop = .);\n\
+ *(.fini)\n\
+ etext = .;\n\
+ _etext = .;\n\
+"," }\n\
+ . = .;\n\
+ .rdata : {\n\
+ *(.rdata)\n\
+ }\n\
+ _fdata = ALIGN(16);\n\
+ .data : {\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ _gp = ALIGN(16) + 0x8000;\n\
+ .lit8 : {\n\
+ *(.lit8)\n\
+ }\n\
+ .lit4 : {\n\
+ *(.lit4)\n\
+ }\n\
+ .sdata : {\n\
+ *(.sdata)\n\
+ }\n\
+"," edata = .;\n\
+ _edata = .;\n\
+ _fbss = .;\n\
+ .sbss : {\n\
+ *(.sbss)\n\
+ *(.scommon)\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ end = .;\n\
+ _end = .;\n\
+}\n\n"
+, NULL)
+ ; else if (!config.magic_demand_paged) return
+concat (
+"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\
+ \"ecoff-littlemips\")\n\
+ SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\
+ENTRY(start)\n\
+SECTIONS\n\
+{\n\
+ . = 0xa0012000;\n\
+ .text : {\n\
+ _ftext = . ;\n\
+ *(.init)\n\
+ eprol = .;\n\
+ *(.text)\n\
+ PROVIDE (__runtime_reloc_start = .);\n\
+ *(.rel.sdata)\n\
+ PROVIDE (__runtime_reloc_stop = .);\n\
+ *(.fini)\n\
+ etext = .;\n\
+ _etext = .;\n\
+ "," }\n\
+ . = .;\n\
+ .rdata : {\n\
+ *(.rdata)\n\
+ }\n\
+ _fdata = ALIGN(16);\n\
+ .data : {\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ _gp = ALIGN(16) + 0x8000;\n\
+ .lit8 : {\n\
+ *(.lit8)\n\
+ "," }\n\
+ .lit4 : {\n\
+ *(.lit4)\n\
+ }\n\
+ .sdata : {\n\
+ *(.sdata)\n\
+ }\n\
+ edata = .;\n\
+ _edata = .;\n\
+ _fbss = .;\n\
+ .sbss : {\n\
+ *(.sbss)\n\
+ *(.scommon)\n\
+ "," }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ end = .;\n\
+ _end = .;\n\
+}\n\n"
+, NULL)
+ ; else return
+concat (
+"OUTPUT_FORMAT(\"ecoff-bigmips\", \"ecoff-bigmips\",\n\
+ \"ecoff-littlemips\")\n\
+ SEARCH_DIR(/usr/local/mips-idt-ecoff/lib);\n\
+ENTRY(start)\n\
+SECTIONS\n\
+{\n\
+ . = 0xa0012000;\n\
+ .text : {\n\
+ _ftext = . ;\n\
+ *(.init)\n\
+ eprol = .;\n\
+ *(.text)\n\
+ PROVIDE (__runtime_reloc_start = .);\n\
+ *(.rel.sdata)\n\
+ PROVIDE (__runtime_reloc_stop = .);\n\
+ *(.fini)\n\
+ etext = .;\n\
+ _etext = .;\n\
+ "," }\n\
+ . = .;\n\
+ .rdata : {\n\
+ *(.rdata)\n\
+ }\n\
+ _fdata = ALIGN(16);\n\
+ .data : {\n\
+ *(.data)\n\
+ CONSTRUCTORS\n\
+ }\n\
+ _gp = ALIGN(16) + 0x8000;\n\
+ .lit8 : {\n\
+ *(.lit8)\n\
+ }\n\
+ .lit4 : {\n\
+ *(.lit4)\n\
+ "," }\n\
+ .sdata : {\n\
+ *(.sdata)\n\
+ }\n\
+ edata = .;\n\
+ _edata = .;\n\
+ _fbss = .;\n\
+ .sbss : {\n\
+ *(.sbss)\n\
+ *(.scommon)\n\
+ }\n\
+ .bss : {\n\
+ *(.bss)\n\
+ *(COMMON)\n\
+ }\n\
+ end = .;\n\
+ _end = .;\n\
+}\n\n"
+, NULL)
+; }
+
+struct ld_emulation_xfer_struct ld_mipsidt_emulation =
+{
+ gldmipsidt_before_parse,
+ syslib_default,
+ hll_default,
+ after_parse_default,
+ gldmipsidt_after_open,
+ gldmipsidt_after_allocation,
+ set_output_arch_default,
+ ldemul_default_target,
+ before_allocation_default,
+ gldmipsidt_get_script,
+ "mipsidt",
+ "ecoff-bigmips"
+};
diff --git a/ld/mpw-make.sed b/ld/mpw-make.sed
new file mode 100644
index 00000000000..c91970839a9
--- /dev/null
+++ b/ld/mpw-make.sed
@@ -0,0 +1,95 @@
+# Sed commands to finish translating the ld Makefile.in into MPW syntax.
+
+/HDEFINES/s/@HDEFINES@//
+
+/^target_alias = @target_alias@/s/^/#/
+
+/^EMUL = @EMUL@/s/^/#/
+
+/^EMULATION_OFILES = @EMULATION_OFILES@/s/^/#/
+
+# Fixadd to the include paths.
+/^INCLUDES = .*$/s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/
+/BFDDIR/s/-i {BFDDIR} /-i "{BFDDIR}": /
+/INCDIR/s/-i {INCDIR} /-i "{INCDIR}": /
+
+# Use byacc instead of bison (for now anyway).
+/BISON/s/^BISON =.*$/BISON = byacc/
+#/BISONFLAGS/s/^BISONFLAGS =.*$/BISONFLAGS = /
+
+# Suppress the suppression of smart makes.
+/^\.y\.c/d
+
+# Hack up ldmain compile.
+/^"{o}"ldmain.c.o \\Option-f .* config.status$/,/^$/c\
+"{o}"ldmain.c.o \\Option-f "{s}"ldmain.c\
+ {CC} @DASH_C_FLAG@ -d DEFAULT_EMULATION={dq}{EMUL}{dq} -d SCRIPTDIR={dq}{scriptdir}{dq} {ALL_CFLAGS} "{s}"ldmain.c -o "{o}"ldmain.c.o\
+
+
+# Remove ldemul-list.h build, rely on configure to make one.
+/^ldemul-list.h /,/Rename -y "{s}"ldemul-tmp.h /d
+
+# Fix pathnames to generated files.
+/config.h/s/"{s}"config\.h/"{o}"config.h/g
+/config.h/s/^config\.h/"{o}"config.h/
+
+/y.tab.c/s/"{s}"y\.tab\.c/"{o}"y.tab.c/g
+/y.tab.c/s/^y\.tab\.c/"{o}"y.tab.c/
+/y.tab.h/s/"{s}"y\.tab\.h/"{o}"y.tab.h/g
+/y.tab.h/s/^y\.tab\.h/"{o}"y.tab.h/
+
+/ldgram.c/s/"{s}"ldgram\.c/"{o}"ldgram.c/g
+/ldgram.c/s/^ldgram\.c/"{o}"ldgram.c/
+
+/ldgram.h/s/"{s}"ldgram\.h/"{o}"ldgram.h/g
+/ldgram.h/s/^ldgram\.h/"{o}"ldgram.h/
+
+/ldlex.c/s/"{s}"ldlex\.c/"{o}"ldlex.c/g
+/ldlex.c/s/^ldlex\.c/"{o}"ldlex.c/
+
+/ldlex.c.new/s/"{s}"ldlex\.c\.new/"{o}"ldlex.c.new/g
+
+/lex.yy.c/s/"{s}"lex\.yy\.c/"{o}"lex.yy.c/g
+
+/ldemul-list.h/s/"{s}"ldemul-list\.h/"{o}"ldemul-list.h/g
+/ldemul-list.h/s/^ldemul-list\.h/"{o}"ldemul-list.h/
+
+# Edit pathnames to emulation files.
+/"{s}"e.*\.c/s/"{s}"e\([-_a-z0-9]*\)\.c/"{o}"e\1.c/g
+/^e.*\.c/s/^e\([-_a-z0-9]*\)\.c/"{o}"e\1.c/
+
+# We can't run genscripts, so don't try.
+/{GENSCRIPTS}/s/{GENSCRIPTS}/null-command/
+
+# Comment out the TDIRS bits.
+/^TDIRS@/s/^/#/
+
+# Point at the BFD library directly.
+/@BFDLIB@/s/@BFDLIB@/::bfd:libbfd.o/
+
+# Don't need this.
+/@HLDFLAGS@/s/@HLDFLAGS@//
+
+#/sed.*free/,/> "{o}"ldlex.c.new/c\
+# \ Catenate "{o}"lex.yy.c >"{o}"ldlex.c.new
+
+# The resource file is called mac-ld.r.
+/{LD_PROG}.r/s/{LD_PROG}\.r/mac-ld.r/
+
+/^install \\Option-f /,/^$/c\
+install \\Option-f all install-only\
+\
+install-only \\Option-f\
+ NewFolderRecursive "{bindir}"\
+ Duplicate -y :ld.new "{bindir}"ld\
+
+
+# Remove dependency rebuilding crud.
+/^.dep /,/# .PHONY /d
+
+# Remove the lintlog action, pipe symbols in column 1 lose.
+/^lintlog \\Option-f/,/^$/d
+
+/^Makefile \\Option-f/,/^$/d
+/^"{o}"config.h \\Option-f/,/^$/d
+/^config.status \\Option-f/,/^$/d
diff --git a/ld/mri.c b/ld/mri.c
new file mode 100644
index 00000000000..54aaea29407
--- /dev/null
+++ b/ld/mri.c
@@ -0,0 +1,377 @@
+/* mri.c -- handle MRI style linker scripts
+ Copyright (C) 1991, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+GLD 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, or (at your option)
+any later version.
+
+GLD 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 GLD; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* This bit does the tree decoration when MRI style link scripts are parsed */
+
+/*
+ contributed by Steve Chamberlain
+ sac@cygnus.com
+
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "ld.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldmisc.h"
+#include "mri.h"
+#include "ldgram.h"
+#include "libiberty.h"
+
+struct section_name_struct {
+ struct section_name_struct *next;
+ CONST char *name;
+ CONST char *alias;
+ etree_type *vma;
+ etree_type *align;
+ etree_type *subalign;
+ int ok_to_load;
+} ;
+
+unsigned int symbol_truncate = 10000;
+struct section_name_struct *order;
+struct section_name_struct *only_load;
+struct section_name_struct *address;
+struct section_name_struct *alias;
+
+struct section_name_struct *alignment;
+struct section_name_struct *subalignment;
+
+static struct section_name_struct **lookup
+ PARAMS ((const char *name, struct section_name_struct **list));
+static void mri_add_to_list PARAMS ((struct section_name_struct **list,
+ const char *name, etree_type *vma,
+ const char *zalias, etree_type *align,
+ etree_type *subalign));
+
+static struct section_name_struct **
+lookup (name, list)
+ CONST char *name;
+ struct section_name_struct **list;
+{
+
+ struct section_name_struct **ptr = list;
+ while (*ptr)
+ {
+ if (strcmp(name, (*ptr)->name) == 0) {
+ /* If this is a match, delete it, we only keep the last instance
+ of any name */
+ *ptr = (*ptr)->next;
+ }
+ else {
+ ptr = &((*ptr)->next);
+ }
+ }
+
+ *ptr = (struct section_name_struct *)xmalloc(sizeof(struct section_name_struct));
+ return ptr;
+}
+
+static void
+mri_add_to_list (list, name, vma, zalias, align, subalign)
+ struct section_name_struct **list;
+ CONST char *name;
+ etree_type *vma;
+ CONST char *zalias;
+ etree_type *align;
+ etree_type *subalign;
+{
+ struct section_name_struct **ptr = lookup(name,list);
+ (*ptr)->name = name;
+ (*ptr)->vma = vma;
+ (*ptr)->next = (struct section_name_struct *)NULL;
+ (*ptr)->ok_to_load = 0;
+ (*ptr)->alias = zalias;
+ (*ptr)->align = align;
+ (*ptr)->subalign = subalign;
+}
+
+
+void
+mri_output_section (name, vma)
+ CONST char *name;
+ etree_type *vma;
+{
+ mri_add_to_list(&address, name, vma, 0,0,0);
+}
+
+/* if any ABSOLUTE <name> are in the script, only load those files
+marked thus */
+
+void
+mri_only_load (name)
+ CONST char *name;
+{
+ mri_add_to_list(&only_load, name, 0, 0,0,0);
+}
+
+
+void
+mri_base (exp)
+ etree_type *exp;
+{
+ base = exp;
+}
+
+static int done_tree = 0;
+
+void
+mri_draw_tree ()
+{
+ if (done_tree) return;
+
+ /* We don't bother with memory regions. */
+#if 0
+ /* Create the regions */
+ {
+ lang_memory_region_type *r;
+ r = lang_memory_region_lookup("long");
+ r->current = r->origin = exp_get_vma(base, (bfd_vma)0, "origin",
+ lang_first_phase_enum);
+ r->length = (bfd_size_type) exp_get_vma(0, (bfd_vma) ~((bfd_size_type)0),
+ "length", lang_first_phase_enum);
+ }
+#endif
+
+ /* Now build the statements for the ldlang machine */
+
+
+ /* Attatch the addresses of any which have addresses, and add the
+ ones not mentioned */
+ if (address != (struct section_name_struct *)NULL) {
+ struct section_name_struct *alist;
+ struct section_name_struct *olist;
+ if (order == (struct section_name_struct *)NULL) {
+ order = address;
+ }
+
+ for (alist = address;
+ alist != (struct section_name_struct*)NULL;
+ alist = alist->next)
+ {
+ int done = 0;
+ for (olist = order;
+ done == 0 &&
+ olist != (struct section_name_struct *)NULL;
+ olist = olist->next)
+ {
+ if (strcmp(alist->name, olist->name) == 0)
+ {
+ olist->vma = alist->vma;
+ done = 1;
+ }
+ }
+ if (!done) {
+ /* add this onto end of order list */
+ mri_add_to_list(&order, alist->name, alist->vma, 0,0,0);
+ }
+
+ }
+
+ }
+
+ /* If we're only supposed to load a subset of them in, then prune
+ the list. */
+
+ if (only_load != (struct section_name_struct *)NULL)
+ {
+ struct section_name_struct *ptr1;
+ struct section_name_struct *ptr2;
+ if (order == (struct section_name_struct*)NULL)
+ order = only_load;
+
+ /* See if this name is in the list, if it is then we can load it
+ */
+ for (ptr1 = only_load; ptr1; ptr1 = ptr1->next)
+ {
+ for (ptr2= order; ptr2; ptr2=ptr2->next)
+ {
+ if (strcmp(ptr2->name, ptr1->name)==0) {
+ ptr2->ok_to_load = 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* No only load list, so everything is ok to load */
+ struct section_name_struct *ptr;
+ for (ptr = order; ptr; ptr=ptr->next) {
+ ptr->ok_to_load = 1;
+ }
+ }
+
+
+
+ /* Create the order of sections to load */
+ if (order != (struct section_name_struct *)NULL)
+ {
+ /* Been told to output the sections in a certain order */
+ struct section_name_struct *p = order;
+ while (p)
+ {
+ struct section_name_struct *aptr;
+ etree_type *align = 0;
+ etree_type *subalign = 0;
+ /* See if an alignment has been specified */
+
+ for (aptr = alignment; aptr; aptr= aptr->next)
+ {
+ if (strcmp(aptr->name, p->name)==0) {
+ align = aptr->align;
+ }
+ }
+
+ for (aptr = subalignment; aptr; aptr= aptr->next)
+ {
+ if (strcmp(aptr->name, p->name)==0) {
+ subalign = aptr->subalign;
+ }
+ }
+
+ if (base == 0) {
+ base = p->vma ? p->vma :exp_nameop(NAME, ".");
+ }
+ lang_enter_output_section_statement (p->name, base,
+ p->ok_to_load ? 0 : noload_section,
+ 1, align, subalign,
+ (etree_type *) NULL);
+ base = 0;
+ lang_add_wild (p->name, false, (char *)NULL, false, false, NULL);
+ /* If there is an alias for this section, add it too */
+ for (aptr = alias; aptr; aptr = aptr->next) {
+
+ if (strcmp(aptr->alias, p->name)== 0) {
+ lang_add_wild (aptr->name, false, (char *)NULL, false, false, NULL);
+ }
+ }
+
+ lang_leave_output_section_statement
+ (0, "*default*", (struct lang_output_section_phdr_list *) NULL);
+
+ p = p->next;
+ }
+ }
+
+
+ done_tree = 1;
+
+}
+void
+mri_load (name)
+ CONST char *name;
+{
+ base = 0;
+ lang_add_input_file(name,
+ lang_input_file_is_file_enum, (char *)NULL);
+ /* lang_leave_output_section_statement(0,"*default*");*/
+}
+
+
+void
+mri_order (name)
+ CONST char *name;
+{
+ mri_add_to_list(&order, name, 0, 0,0,0);
+}
+
+void
+mri_alias (want, is, isn)
+ CONST char *want;
+ CONST char *is;
+ int isn;
+{
+ if (!is) {
+ /* Some sections are digits - */
+ char buf[20];
+ sprintf(buf, "%d", isn);
+ is = xstrdup (buf);
+ if (is == NULL)
+ abort ();
+ }
+ mri_add_to_list(&alias, is, 0, want,0,0);
+
+}
+
+
+void
+mri_name (name)
+ CONST char *name;
+{
+ lang_add_output(name, 1);
+
+}
+
+
+void
+mri_format (name)
+ CONST char *name;
+{
+ if (strcmp(name, "S") == 0)
+ {
+ lang_add_output_format("srec", (char *) NULL, (char *) NULL, 1);
+ }
+ else if (strcmp(name, "IEEE") == 0)
+ {
+ lang_add_output_format("ieee", (char *) NULL, (char *) NULL, 1);
+ }
+ else if (strcmp(name, "COFF") == 0)
+ {
+ lang_add_output_format("coff-m68k", (char *) NULL, (char *) NULL, 1);
+ }
+ else {
+ einfo(_("%P%F: unknown format type %s\n"), name);
+ }
+}
+
+
+void
+mri_public (name, exp)
+ CONST char *name;
+ etree_type *exp;
+{
+ lang_add_assignment(exp_assop('=', name, exp));
+}
+
+void
+mri_align (name, exp)
+ CONST char *name;
+ etree_type *exp;
+{
+ mri_add_to_list(&alignment, name,0,0,exp,0);
+}
+
+void
+mri_alignmod (name, exp)
+ CONST char *name;
+ etree_type *exp;
+{
+ mri_add_to_list(&subalignment, name,0,0,0,exp);
+}
+
+
+void
+mri_truncate (exp)
+ unsigned int exp;
+{
+ symbol_truncate = exp;
+}
diff --git a/ld/mri.h b/ld/mri.h
new file mode 100644
index 00000000000..dc3f0f3a190
--- /dev/null
+++ b/ld/mri.h
@@ -0,0 +1,39 @@
+/* mri.h -- header file for MRI scripting functions
+ Copyright 1993, 95, 1996 Free Software Foundation, Inc.
+
+This file is part of GLD, the Gnu Linker.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef MRI_H
+#define MRI_H
+
+extern unsigned int symbol_truncate;
+
+extern void mri_output_section PARAMS ((const char *name, etree_type *vma));
+extern void mri_only_load PARAMS ((const char *name));
+extern void mri_base PARAMS ((etree_type *exp));
+extern void mri_load PARAMS ((const char *name));
+extern void mri_order PARAMS ((const char *name));
+extern void mri_alias PARAMS ((const char *want, const char *is, int isn));
+extern void mri_name PARAMS ((const char *name));
+extern void mri_format PARAMS ((const char *name));
+extern void mri_public PARAMS ((const char *name, etree_type *exp));
+extern void mri_align PARAMS ((const char *name, etree_type *exp));
+extern void mri_alignmod PARAMS ((const char *name, etree_type *exp));
+extern void mri_truncate PARAMS ((unsigned int exp));
+extern void mri_draw_tree PARAMS ((void));
+
+#endif
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
new file mode 100644
index 00000000000..6d7306c03c5
--- /dev/null
+++ b/ld/pe-dll.c
@@ -0,0 +1,1651 @@
+/* Routines to help build PEI-format DLLs (Win32 etc)
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Written by DJ Delorie <dj@cygnus.com>
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libiberty.h"
+
+#include <time.h>
+#include <ctype.h>
+
+#include "ld.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldwrite.h"
+#include "ldmisc.h"
+#include "ldgram.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "coff/internal.h"
+#include "../bfd/libcoff.h"
+#include "deffile.h"
+
+/************************************************************************
+
+ This file turns a regular Windows PE image into a DLL. Because of
+ the complexity of this operation, it has been broken down into a
+ number of separate modules which are all called by the main function
+ at the end of this file. This function is not re-entrant and is
+ normally only called once, so static variables are used to reduce
+ the number of parameters and return values required.
+
+ See also: ld/emultempl/pe.em
+
+ ************************************************************************/
+
+/* for emultempl/pe.em */
+
+def_file *pe_def_file = 0;
+int pe_dll_export_everything = 0;
+int pe_dll_do_default_excludes = 1;
+int pe_dll_kill_ats = 0;
+int pe_dll_stdcall_aliases = 0;
+
+/************************************************************************
+
+ static variables and types
+
+ ************************************************************************/
+
+static bfd_vma image_base;
+
+static bfd *filler_bfd;
+static struct sec *edata_s, *reloc_s;
+static unsigned char *edata_d, *reloc_d;
+static int edata_sz, reloc_sz;
+
+/************************************************************************
+
+ Helper functions for qsort. Relocs must be sorted so that we can write
+ them out by pages.
+
+ ************************************************************************/
+
+static int
+reloc_sort (va, vb)
+ const void *va, *vb;
+{
+ bfd_vma a = *(bfd_vma *) va;
+ bfd_vma b = *(bfd_vma *) vb;
+ return (a > b) - (a < b);
+}
+
+static int
+pe_export_sort (va, vb)
+ const void *va, *vb;
+{
+ def_file_export *a = (def_file_export *) va;
+ def_file_export *b = (def_file_export *) vb;
+ return strcmp (a->name, b->name);
+}
+
+/************************************************************************
+
+ Read and process the .DEF file
+
+ ************************************************************************/
+
+/* These correspond to the entries in pe_def_file->exports[]. I use
+ exported_symbol_sections[i] to tag whether or not the symbol was
+ defined, since we can't export symbols we don't have. */
+
+static bfd_vma *exported_symbol_offsets;
+static struct sec **exported_symbol_sections;
+
+static int export_table_size;
+static int count_exported;
+static int count_exported_byname;
+static int count_with_ordinals;
+static const char *dll_name;
+static int min_ordinal, max_ordinal;
+static int *exported_symbols;
+
+typedef struct exclude_list_struct
+ {
+ char *string;
+ struct exclude_list_struct *next;
+ }
+exclude_list_struct;
+static struct exclude_list_struct *excludes = 0;
+
+void
+pe_dll_add_excludes (new_excludes)
+ const char *new_excludes;
+{
+ char *local_copy;
+ char *exclude_string;
+
+ local_copy = xstrdup (new_excludes);
+
+ exclude_string = strtok (local_copy, ",:");
+ for (; exclude_string; exclude_string = strtok (NULL, ",:"))
+ {
+ struct exclude_list_struct *new_exclude;
+
+ new_exclude = ((struct exclude_list_struct *)
+ xmalloc (sizeof (struct exclude_list_struct)));
+ new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 1);
+ strcpy (new_exclude->string, exclude_string);
+ new_exclude->next = excludes;
+ excludes = new_exclude;
+ }
+
+ free (local_copy);
+}
+
+static int
+auto_export (d, n)
+ def_file *d;
+ const char *n;
+{
+ int i;
+ struct exclude_list_struct *ex;
+ for (i = 0; i < d->num_exports; i++)
+ if (strcmp (d->exports[i].name, n) == 0)
+ return 0;
+ if (pe_dll_do_default_excludes)
+ {
+ if (strcmp (n, "DllMain@12") == 0)
+ return 0;
+ if (strcmp (n, "DllEntryPoint@0") == 0)
+ return 0;
+ if (strcmp (n, "impure_ptr") == 0)
+ return 0;
+ }
+ for (ex = excludes; ex; ex = ex->next)
+ if (strcmp (n, ex->string) == 0)
+ return 0;
+ return 1;
+}
+
+static void
+process_def_file (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ int i, j;
+ struct bfd_link_hash_entry *blhe;
+ bfd *b;
+ struct sec *s;
+ def_file_export *e=0;
+
+ if (!pe_def_file)
+ pe_def_file = def_file_empty ();
+
+ /* First, run around to all the objects looking for the .drectve
+ sections, and push those into the def file too */
+
+ for (b = info->input_bfds; b; b = b->link_next)
+ {
+ s = bfd_get_section_by_name (b, ".drectve");
+ if (s)
+ {
+ int size = bfd_get_section_size_before_reloc (s);
+ char *buf = xmalloc (size);
+ bfd_get_section_contents (b, s, buf, 0, size);
+ def_file_add_directive (pe_def_file, buf, size);
+ free (buf);
+ }
+ }
+
+ /* Now, maybe export everything else the default way */
+
+ if (pe_dll_export_everything || pe_def_file->num_exports == 0)
+ {
+ for (b = info->input_bfds; b; b = b->link_next)
+ {
+ asymbol **symbols;
+ int nsyms, symsize;
+
+ symsize = bfd_get_symtab_upper_bound (b);
+ symbols = (asymbol **) xmalloc (symsize);
+ nsyms = bfd_canonicalize_symtab (b, symbols);
+
+ for (j = 0; j < nsyms; j++)
+ {
+ if ((symbols[j]->flags & (BSF_FUNCTION | BSF_GLOBAL))
+ == (BSF_FUNCTION | BSF_GLOBAL))
+ {
+ const char *sn = symbols[j]->name;
+ if (*sn == '_')
+ sn++;
+ if (auto_export (pe_def_file, sn))
+ def_file_add_export (pe_def_file, sn, 0, -1);
+ }
+ }
+ }
+ }
+
+#undef NE
+#define NE pe_def_file->num_exports
+
+ /* Canonicalize the export list */
+
+ if (pe_dll_kill_ats)
+ {
+ for (i = 0; i < NE; i++)
+ {
+ if (strchr (pe_def_file->exports[i].name, '@'))
+ {
+ /* This will preserve internal_name, which may have been pointing
+ to the same memory as name, or might not have */
+ char *tmp = xstrdup (pe_def_file->exports[i].name);
+ *(strchr (tmp, '@')) = 0;
+ pe_def_file->exports[i].name = tmp;
+ }
+ }
+ }
+
+ if (pe_dll_stdcall_aliases)
+ {
+ for (i = 0; i < NE; i++)
+ {
+ if (strchr (pe_def_file->exports[i].name, '@'))
+ {
+ char *tmp = xstrdup (pe_def_file->exports[i].name);
+ *(strchr (tmp, '@')) = 0;
+ if (auto_export (pe_def_file, tmp))
+ def_file_add_export (pe_def_file, tmp,
+ pe_def_file->exports[i].internal_name, -1);
+ else
+ free (tmp);
+ }
+ }
+ }
+
+ e = pe_def_file->exports; /* convenience, but watch out for it changing */
+
+ exported_symbol_offsets = (bfd_vma *) xmalloc (NE * sizeof (bfd_vma));
+ exported_symbol_sections = (struct sec **) xmalloc (NE * sizeof (struct sec *));
+
+ memset (exported_symbol_sections, 0, NE * sizeof (struct sec *));
+ max_ordinal = 0;
+ min_ordinal = 65536;
+ count_exported = 0;
+ count_exported_byname = 0;
+ count_with_ordinals = 0;
+
+ qsort (pe_def_file->exports, NE, sizeof (pe_def_file->exports[0]), pe_export_sort);
+ for (i = 0, j = 0; i < NE; i++)
+ {
+ if (i > 0 && strcmp (e[i].name, e[i - 1].name) == 0)
+ {
+ /* This is a duplicate */
+ if (e[j - 1].ordinal != -1
+ && e[i].ordinal != -1
+ && e[j - 1].ordinal != e[i].ordinal)
+ {
+ /* xgettext:c-format */
+ einfo (_("%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n"),
+ e[j - 1].name, e[j - 1].ordinal, e[i].ordinal);
+ }
+ else
+ {
+ /* xgettext:c-format */
+ einfo (_("Warning, duplicate EXPORT: %s\n"),
+ e[j - 1].name);
+ }
+ if (e[i].ordinal)
+ e[j - 1].ordinal = e[i].ordinal;
+ e[j - 1].flag_private |= e[i].flag_private;
+ e[j - 1].flag_constant |= e[i].flag_constant;
+ e[j - 1].flag_noname |= e[i].flag_noname;
+ e[j - 1].flag_data |= e[i].flag_data;
+ }
+ else
+ {
+ if (i != j)
+ e[j] = e[i];
+ j++;
+ }
+ }
+ pe_def_file->num_exports = j; /* == NE */
+
+ for (i = 0; i < NE; i++)
+ {
+ char *name = (char *) xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
+ *name = '_';
+ strcpy (name + 1, pe_def_file->exports[i].internal_name);
+
+ blhe = bfd_link_hash_lookup (info->hash,
+ name,
+ false, false, true);
+
+ if (blhe && (blhe->type == bfd_link_hash_defined))
+ {
+ count_exported++;
+ if (!pe_def_file->exports[i].flag_noname)
+ count_exported_byname++;
+ exported_symbol_offsets[i] = blhe->u.def.value;
+ exported_symbol_sections[i] = blhe->u.def.section;
+ if (pe_def_file->exports[i].ordinal != -1)
+ {
+ if (max_ordinal < pe_def_file->exports[i].ordinal)
+ max_ordinal = pe_def_file->exports[i].ordinal;
+ if (min_ordinal > pe_def_file->exports[i].ordinal)
+ min_ordinal = pe_def_file->exports[i].ordinal;
+ count_with_ordinals++;
+ }
+ }
+ else if (blhe && blhe->type == bfd_link_hash_undefined)
+ {
+ /* xgettext:c-format */
+ einfo (_("%XCannot export %s: symbol not defined\n"),
+ pe_def_file->exports[i].internal_name);
+ }
+ else if (blhe)
+ {
+ /* xgettext:c-format */
+ einfo (_("%XCannot export %s: symbol wrong type (%d vs %d)\n"),
+ pe_def_file->exports[i].internal_name,
+ blhe->type, bfd_link_hash_defined);
+ }
+ else
+ {
+ /* xgettext:c-format */
+ einfo (_("%XCannot export %s: symbol not found\n"),
+ pe_def_file->exports[i].internal_name);
+ }
+ free (name);
+ }
+}
+
+/************************************************************************
+
+ Build the bfd that will contain .edata and .reloc sections
+
+ ************************************************************************/
+
+static void
+build_filler_bfd ()
+{
+ lang_input_statement_type *filler_file;
+ filler_file = lang_add_input_file ("dll stuff",
+ lang_input_file_is_fake_enum,
+ NULL);
+ filler_file->the_bfd = filler_bfd = bfd_create ("dll stuff", output_bfd);
+ if (filler_bfd == NULL
+ || !bfd_set_arch_mach (filler_bfd,
+ bfd_get_arch (output_bfd),
+ bfd_get_mach (output_bfd)))
+ {
+ einfo ("%X%P: can not create BFD %E\n");
+ return;
+ }
+
+ edata_s = bfd_make_section_old_way (filler_bfd, ".edata");
+ if (edata_s == NULL
+ || !bfd_set_section_flags (filler_bfd, edata_s,
+ (SEC_HAS_CONTENTS
+ | SEC_ALLOC
+ | SEC_LOAD
+ | SEC_KEEP
+ | SEC_IN_MEMORY)))
+ {
+ einfo ("%X%P: can not create .edata section: %E\n");
+ return;
+ }
+ bfd_set_section_size (filler_bfd, edata_s, edata_sz);
+
+ reloc_s = bfd_make_section_old_way (filler_bfd, ".reloc");
+ if (reloc_s == NULL
+ || !bfd_set_section_flags (filler_bfd, reloc_s,
+ (SEC_HAS_CONTENTS
+ | SEC_ALLOC
+ | SEC_LOAD
+ | SEC_KEEP
+ | SEC_IN_MEMORY)))
+ {
+ einfo ("%X%P: can not create .reloc section: %E\n");
+ return;
+ }
+ bfd_set_section_size (filler_bfd, reloc_s, 0);
+
+ ldlang_add_file (filler_file);
+}
+
+/************************************************************************
+
+ Gather all the exported symbols and build the .edata section
+
+ ************************************************************************/
+
+static void
+generate_edata (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ int i, next_ordinal;
+ int name_table_size = 0;
+ const char *dlnp;
+
+ /* First, we need to know how many exported symbols there are,
+ and what the range of ordinals is. */
+
+ if (pe_def_file->name)
+ {
+ dll_name = pe_def_file->name;
+ }
+ else
+ {
+ dll_name = abfd->filename;
+ for (dlnp = dll_name; *dlnp; dlnp++)
+ {
+ if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':')
+ dll_name = dlnp + 1;
+ }
+ }
+
+ if (count_with_ordinals && max_ordinal > count_exported)
+ {
+ if (min_ordinal > max_ordinal - count_exported + 1)
+ min_ordinal = max_ordinal - count_exported + 1;
+ }
+ else
+ {
+ min_ordinal = 1;
+ max_ordinal = count_exported;
+ }
+ export_table_size = max_ordinal - min_ordinal + 1;
+
+ exported_symbols = (int *) xmalloc (export_table_size * sizeof (int));
+ for (i = 0; i < export_table_size; i++)
+ exported_symbols[i] = -1;
+
+ /* Now we need to assign ordinals to those that don't have them */
+ for (i = 0; i < NE; i++)
+ {
+ if (exported_symbol_sections[i])
+ {
+ if (pe_def_file->exports[i].ordinal != -1)
+ {
+ int ei = pe_def_file->exports[i].ordinal - min_ordinal;
+ int pi = exported_symbols[ei];
+ if (pi != -1)
+ {
+ /* xgettext:c-format */
+ einfo (_("%XError, oridinal used twice: %d (%s vs %s)\n"),
+ pe_def_file->exports[i].ordinal,
+ pe_def_file->exports[i].name,
+ pe_def_file->exports[pi].name);
+ }
+ exported_symbols[ei] = i;
+ }
+ name_table_size += strlen (pe_def_file->exports[i].name) + 1;
+ }
+ }
+
+ next_ordinal = min_ordinal;
+ for (i = 0; i < NE; i++)
+ if (exported_symbol_sections[i])
+ if (pe_def_file->exports[i].ordinal == -1)
+ {
+ while (exported_symbols[next_ordinal - min_ordinal] != -1)
+ next_ordinal++;
+ exported_symbols[next_ordinal - min_ordinal] = i;
+ pe_def_file->exports[i].ordinal = next_ordinal;
+ }
+
+ /* OK, now we can allocate some memory */
+
+ edata_sz = (40 /* directory */
+ + 4 * export_table_size /* addresses */
+ + 4 * count_exported_byname /* name ptrs */
+ + 2 * count_exported_byname /* ordinals */
+ + name_table_size + strlen (dll_name) + 1);
+}
+
+static void
+fill_edata (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ int i, hint;
+ unsigned char *edirectory;
+ unsigned long *eaddresses;
+ unsigned long *enameptrs;
+ unsigned short *eordinals;
+ unsigned char *enamestr;
+ time_t now;
+
+ time (&now);
+
+ edata_d = (unsigned char *) xmalloc (edata_sz);
+
+ /* Note use of array pointer math here */
+ edirectory = edata_d;
+ eaddresses = (unsigned long *) (edata_d + 40);
+ enameptrs = eaddresses + export_table_size;
+ eordinals = (unsigned short *) (enameptrs + count_exported_byname);
+ enamestr = (char *) (eordinals + count_exported_byname);
+
+#define ERVA(ptr) (((unsigned char *)(ptr) - edata_d) + edata_s->output_section->vma - image_base)
+
+ memset (edata_d, 0, 40);
+ bfd_put_32 (abfd, now, edata_d + 4);
+ if (pe_def_file->version_major != -1)
+ {
+ bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8);
+ bfd_put_16 (abfd, pe_def_file->version_minor, edata_d + 10);
+ }
+ bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12);
+ strcpy (enamestr, dll_name);
+ enamestr += strlen (enamestr) + 1;
+ bfd_put_32 (abfd, min_ordinal, edata_d + 16);
+ bfd_put_32 (abfd, export_table_size, edata_d + 20);
+ bfd_put_32 (abfd, count_exported_byname, edata_d + 24);
+ bfd_put_32 (abfd, ERVA (eaddresses), edata_d + 28);
+ bfd_put_32 (abfd, ERVA (enameptrs), edata_d + 32);
+ bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36);
+
+ /* Ok, now for the filling in part */
+ hint = 0;
+ for (i = 0; i < export_table_size; i++)
+ {
+ int s = exported_symbols[i];
+ if (s != -1)
+ {
+ struct sec *ssec = exported_symbol_sections[s];
+ unsigned long srva = (exported_symbol_offsets[s]
+ + ssec->output_section->vma
+ + ssec->output_offset);
+
+ bfd_put_32 (abfd, srva - image_base, (void *) (eaddresses + i));
+ if (!pe_def_file->exports[s].flag_noname)
+ {
+ char *ename = pe_def_file->exports[s].name;
+ bfd_put_32 (abfd, ERVA (enamestr), (void *) enameptrs);
+ strcpy (enamestr, ename);
+ enamestr += strlen (enamestr) + 1;
+ bfd_put_16 (abfd, i, (void *) eordinals);
+ enameptrs++;
+ pe_def_file->exports[s].hint = hint++;
+ }
+ eordinals++;
+ }
+ }
+}
+
+/************************************************************************
+
+ Gather all the relocations and build the .reloc section
+
+ ************************************************************************/
+
+static void
+generate_reloc (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+
+ /* for .reloc stuff */
+ bfd_vma *reloc_addresses;
+ int total_relocs = 0;
+ int i;
+ unsigned long sec_page = (unsigned long) (-1);
+ unsigned long page_ptr, page_count;
+ int bi;
+ bfd *b;
+ struct sec *s;
+
+ total_relocs = 0;
+ for (b = info->input_bfds; b; b = b->link_next)
+ for (s = b->sections; s; s = s->next)
+ total_relocs += s->reloc_count;
+
+ reloc_addresses = (bfd_vma *) xmalloc (total_relocs * sizeof (bfd_vma));
+
+ total_relocs = 0;
+ bi = 0;
+ for (bi = 0, b = info->input_bfds; b; bi++, b = b->link_next)
+ {
+ arelent **relocs;
+ int relsize, nrelocs, i;
+
+ for (s = b->sections; s; s = s->next)
+ {
+ unsigned long sec_vma = s->output_section->vma + s->output_offset;
+ asymbol **symbols;
+ int nsyms, symsize;
+
+ /* if it's not loaded, we don't need to relocate it this way */
+ if (!(s->output_section->flags & SEC_LOAD))
+ continue;
+
+ /* I don't know why there would be a reloc for these, but I've
+ seen it happen - DJ */
+ if (s->output_section == &bfd_abs_section)
+ continue;
+
+ if (s->output_section->vma == 0)
+ {
+ /* Huh? Shouldn't happen, but punt if it does */
+ einfo ("DJ: zero vma section reloc detected: `%s' #%d f=%d\n",
+ s->output_section->name, s->output_section->index,
+ s->output_section->flags);
+ continue;
+ }
+
+ symsize = bfd_get_symtab_upper_bound (b);
+ symbols = (asymbol **) xmalloc (symsize);
+ nsyms = bfd_canonicalize_symtab (b, symbols);
+
+ relsize = bfd_get_reloc_upper_bound (b, s);
+ relocs = (arelent **) xmalloc ((size_t) relsize);
+ nrelocs = bfd_canonicalize_reloc (b, s, relocs, symbols);
+
+ for (i = 0; i < nrelocs; i++)
+ {
+ if (!relocs[i]->howto->pc_relative
+ && relocs[i]->howto->type != R_IMAGEBASE)
+ {
+ switch (relocs[i]->howto->bitsize)
+ {
+ case 32:
+ reloc_addresses[total_relocs++] = sec_vma + relocs[i]->address;
+ break;
+ default:
+ /* xgettext:c-format */
+ einfo (_("%XError: %d-bit reloc in dll\n"),
+ relocs[i]->howto->bitsize);
+ break;
+ }
+ }
+ }
+ free (relocs);
+ /* Warning: the allocated symbols are remembered in BFD and reused
+ later, so don't free them! */
+ /* free (symbols); */
+ }
+ }
+
+ /* At this point, we have total_relocs relocation addresses in
+ reloc_addresses, which are all suitable for the .reloc section.
+ We must now create the new sections. */
+
+ qsort (reloc_addresses, total_relocs, sizeof (bfd_vma), reloc_sort);
+
+ for (i = 0; i < total_relocs; i++)
+ {
+ unsigned long this_page = (reloc_addresses[i] >> 12);
+ if (this_page != sec_page)
+ {
+ reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
+ reloc_sz += 8;
+ sec_page = this_page;
+ }
+ reloc_sz += 2;
+ }
+ reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align */
+
+ reloc_d = (unsigned char *) xmalloc (reloc_sz);
+
+ sec_page = (unsigned long) (-1);
+ reloc_sz = 0;
+ page_ptr = (unsigned long) (-1);
+ page_count = 0;
+ for (i = 0; i < total_relocs; i++)
+ {
+ unsigned long rva = reloc_addresses[i] - image_base;
+ unsigned long this_page = (rva & ~0xfff);
+ if (this_page != sec_page)
+ {
+ while (reloc_sz & 3)
+ reloc_d[reloc_sz++] = 0;
+ if (page_ptr != (unsigned long) (-1))
+ bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
+ bfd_put_32 (abfd, this_page, reloc_d + reloc_sz);
+ page_ptr = reloc_sz;
+ reloc_sz += 8;
+ sec_page = this_page;
+ page_count = 0;
+ }
+ bfd_put_16 (abfd, (rva & 0xfff) + 0x3000, reloc_d + reloc_sz);
+ reloc_sz += 2;
+ page_count++;
+ }
+ while (reloc_sz & 3)
+ reloc_d[reloc_sz++] = 0;
+ if (page_ptr != (unsigned long) (-1))
+ bfd_put_32 (abfd, reloc_sz - page_ptr, reloc_d + page_ptr + 4);
+ while (reloc_sz < reloc_s->_raw_size)
+ reloc_d[reloc_sz++] = 0;
+}
+
+/************************************************************************
+
+ Given the exiting def_file structure, print out a .DEF file that
+ corresponds to it.
+
+ ************************************************************************/
+
+static void
+quoteput (s, f, needs_quotes)
+ char *s;
+ FILE * f;
+ int needs_quotes;
+{
+ char *cp;
+ for (cp = s; *cp; cp++)
+ if (*cp == '\''
+ || *cp == '"'
+ || *cp == '\\'
+ || isspace ((unsigned char) *cp)
+ || *cp == ','
+ || *cp == ';')
+ needs_quotes = 1;
+ if (needs_quotes)
+ {
+ putc ('"', f);
+ while (*s)
+ {
+ if (*s == '"' || *s == '\\')
+ putc ('\\', f);
+ putc (*s, f);
+ s++;
+ }
+ putc ('"', f);
+ }
+ else
+ fputs (s, f);
+}
+
+void
+pe_dll_generate_def_file (pe_out_def_filename)
+ char *pe_out_def_filename;
+{
+ int i;
+ FILE *out = fopen (pe_out_def_filename, "w");
+ if (out == NULL)
+ {
+ /* xgettext:c-format */
+ einfo (_("%s: Can't open output def file %s\n"),
+ program_name, pe_out_def_filename);
+ }
+
+ if (pe_def_file)
+ {
+ if (pe_def_file->name)
+ {
+ if (pe_def_file->is_dll)
+ fprintf (out, "LIBRARY ");
+ else
+ fprintf (out, "NAME ");
+ quoteput (pe_def_file->name, out, 1);
+ if (pe_data (output_bfd)->pe_opthdr.ImageBase)
+ fprintf (out, " BASE=0x%lx",
+ (unsigned long) pe_data (output_bfd)->pe_opthdr.ImageBase);
+ fprintf (out, "\n");
+ }
+
+ if (pe_def_file->description)
+ {
+ fprintf (out, "DESCRIPTION ");
+ quoteput (pe_def_file->description, out, 1);
+ fprintf (out, "\n");
+ }
+
+ if (pe_def_file->version_minor != -1)
+ fprintf (out, "VERSION %d.%d\n", pe_def_file->version_major,
+ pe_def_file->version_minor);
+ else if (pe_def_file->version_major != -1)
+ fprintf (out, "VERSION %d\n", pe_def_file->version_major);
+
+ if (pe_def_file->stack_reserve != -1 || pe_def_file->heap_reserve != -1)
+ fprintf (out, "\n");
+
+ if (pe_def_file->stack_commit != -1)
+ fprintf (out, "STACKSIZE 0x%x,0x%x\n",
+ pe_def_file->stack_reserve, pe_def_file->stack_commit);
+ else if (pe_def_file->stack_reserve != -1)
+ fprintf (out, "STACKSIZE 0x%x\n", pe_def_file->stack_reserve);
+ if (pe_def_file->heap_commit != -1)
+ fprintf (out, "HEAPSIZE 0x%x,0x%x\n",
+ pe_def_file->heap_reserve, pe_def_file->heap_commit);
+ else if (pe_def_file->heap_reserve != -1)
+ fprintf (out, "HEAPSIZE 0x%x\n", pe_def_file->heap_reserve);
+
+ if (pe_def_file->num_section_defs > 0)
+ {
+ fprintf (out, "\nSECTIONS\n\n");
+ for (i = 0; i < pe_def_file->num_section_defs; i++)
+ {
+ fprintf (out, " ");
+ quoteput (pe_def_file->section_defs[i].name, out, 0);
+ if (pe_def_file->section_defs[i].class)
+ {
+ fprintf (out, " CLASS ");
+ quoteput (pe_def_file->section_defs[i].class, out, 0);
+ }
+ if (pe_def_file->section_defs[i].flag_read)
+ fprintf (out, " READ");
+ if (pe_def_file->section_defs[i].flag_write)
+ fprintf (out, " WRITE");
+ if (pe_def_file->section_defs[i].flag_execute)
+ fprintf (out, " EXECUTE");
+ if (pe_def_file->section_defs[i].flag_shared)
+ fprintf (out, " SHARED");
+ fprintf (out, "\n");
+ }
+ }
+
+ if (pe_def_file->num_exports > 0)
+ {
+ fprintf (out, "\nEXPORTS\n\n");
+ for (i = 0; i < pe_def_file->num_exports; i++)
+ {
+ def_file_export *e = pe_def_file->exports + i;
+ fprintf (out, " ");
+ quoteput (e->name, out, 0);
+ if (e->internal_name && strcmp (e->internal_name, e->name))
+ {
+ fprintf (out, " = ");
+ quoteput (e->internal_name, out, 0);
+ }
+ if (e->ordinal != -1)
+ fprintf (out, " @%d", e->ordinal);
+ if (e->flag_private)
+ fprintf (out, " PRIVATE");
+ if (e->flag_constant)
+ fprintf (out, " CONSTANT");
+ if (e->flag_noname)
+ fprintf (out, " NONAME");
+ if (e->flag_data)
+ fprintf (out, " DATA");
+
+ fprintf (out, "\n");
+ }
+ }
+
+ if (pe_def_file->num_imports > 0)
+ {
+ fprintf (out, "\nIMPORTS\n\n");
+ for (i = 0; i < pe_def_file->num_imports; i++)
+ {
+ def_file_import *im = pe_def_file->imports + i;
+ fprintf (out, " ");
+ if (im->internal_name
+ && (!im->name || strcmp (im->internal_name, im->name)))
+ {
+ quoteput (im->internal_name, out, 0);
+ fprintf (out, " = ");
+ }
+ quoteput (im->module->name, out, 0);
+ fprintf (out, ".");
+ if (im->name)
+ quoteput (im->name, out, 0);
+ else
+ fprintf (out, "%d", im->ordinal);
+ fprintf (out, "\n");
+ }
+ }
+ }
+ else
+ fprintf (out, _("; no contents available\n"));
+
+ if (fclose (out) == EOF)
+ {
+ /* xgettext:c-format */
+ einfo (_("%P: Error closing file `%s'\n"), pe_out_def_filename);
+ }
+}
+
+/************************************************************************
+
+ Generate the import library
+
+ ************************************************************************/
+
+static asymbol **symtab;
+static int symptr;
+static int tmp_seq;
+static const char *dll_filename;
+static char *dll_symname;
+
+#define UNDSEC (asection *) &bfd_und_section
+
+static asection *
+quick_section(abfd, name, flags, align)
+ bfd *abfd;
+ const char *name;
+ int flags;
+ int align;
+{
+ asection *sec;
+ asymbol *sym;
+
+ sec = bfd_make_section_old_way (abfd, name);
+ bfd_set_section_flags (abfd, sec, flags
+ | SEC_ALLOC
+ | SEC_LOAD
+ | SEC_KEEP
+ );
+ bfd_set_section_alignment (abfd, sec, align);
+ /* remember to undo this before trying to link internally! */
+ sec->output_section = sec;
+
+ sym = bfd_make_empty_symbol (abfd);
+ symtab[symptr++] = sym;
+ sym->name = sec->name;
+ sym->section = sec;
+ sym->flags = BSF_LOCAL;
+ sym->value = 0;
+
+ return sec;
+}
+
+static void
+quick_symbol (abfd, n1, n2, n3, sec, flags, addr)
+ bfd *abfd;
+ char *n1;
+ char *n2;
+ char *n3;
+ asection *sec;
+ int flags;
+ int addr;
+{
+ asymbol *sym;
+ char *name = (char *) xmalloc (strlen (n1) + strlen (n2) + strlen (n3) + 1);
+ strcpy (name, n1);
+ strcat (name, n2);
+ strcat (name, n3);
+ sym = bfd_make_empty_symbol (abfd);
+ sym->name = name;
+ sym->section = sec;
+ sym->flags = flags;
+ sym->value = addr;
+ symtab[symptr++] = sym;
+}
+
+static arelent *reltab = 0;
+static int relcount = 0, relsize = 0;
+
+static void
+quick_reloc (abfd, address, which_howto, symidx)
+ bfd *abfd;
+ int address;
+ int which_howto;
+ int symidx;
+{
+ if (relcount >= (relsize-1))
+ {
+ relsize += 10;
+ if (reltab)
+ reltab = (arelent *) xrealloc (reltab, relsize * sizeof (arelent));
+ else
+ reltab = (arelent *) xmalloc (relsize * sizeof (arelent));
+ }
+ reltab[relcount].address = address;
+ reltab[relcount].addend = 0;
+ reltab[relcount].howto = bfd_reloc_type_lookup (abfd, which_howto);
+ reltab[relcount].sym_ptr_ptr = symtab + symidx;
+ relcount++;
+}
+
+static void
+save_relocs (asection *sec)
+{
+ int i;
+ sec->relocation = reltab;
+ sec->reloc_count = relcount;
+ sec->orelocation = (arelent **) xmalloc ((relcount+1) * sizeof (arelent *));
+ for (i=0; i<relcount; i++)
+ sec->orelocation[i] = sec->relocation + i;
+ sec->orelocation[relcount] = 0;
+ sec->flags |= SEC_RELOC;
+ reltab = 0;
+ relcount = relsize = 0;
+}
+
+/*
+ * .section .idata$2
+ * .global __head_my_dll
+ * __head_my_dll:
+ * .rva hname
+ * .long 0
+ * .long 0
+ * .rva __my_dll_iname
+ * .rva fthunk
+ *
+ * .section .idata$5
+ * .long 0
+ * fthunk:
+ *
+ * .section .idata$4
+ * .long 0
+ * hname:
+ */
+
+static bfd *
+make_head (parent)
+ bfd *parent;
+{
+ asection *id2, *id5, *id4;
+ unsigned char *d2, *d5, *d4;
+ char *oname;
+ bfd *abfd;
+
+ oname = (char *) xmalloc (20);
+ sprintf (oname, "d%06d.o", tmp_seq);
+ tmp_seq++;
+
+ abfd = bfd_create (oname, parent);
+ bfd_find_target ("pe-i386", abfd);
+ bfd_make_writable (abfd);
+
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
+
+ symptr = 0;
+ symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *));
+ id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
+ id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
+ id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
+ quick_symbol (abfd, "__head_", dll_symname, "", id2, BSF_GLOBAL, 0);
+ quick_symbol (abfd, "_", dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
+
+ bfd_set_section_size (abfd, id2, 20);
+ d2 = (unsigned char *) xmalloc (20);
+ id2->contents = d2;
+ memset (d2, 0, 20);
+ d2[0] = d2[16] = 4; /* reloc addend */
+ quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
+ quick_reloc (abfd, 12, BFD_RELOC_RVA, 4);
+ quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
+ save_relocs (id2);
+
+ bfd_set_section_size (abfd, id5, 4);
+ d5 = (unsigned char *) xmalloc (4);
+ id5->contents = d5;
+ memset (d5, 0, 4);
+
+ bfd_set_section_size (abfd, id4, 4);
+ d4 = (unsigned char *) xmalloc (4);
+ id4->contents = d4;
+ memset (d4, 0, 4);
+
+ bfd_set_symtab (abfd, symtab, symptr);
+
+ bfd_set_section_contents (abfd, id2, d2, 0, 20);
+ bfd_set_section_contents (abfd, id5, d5, 0, 4);
+ bfd_set_section_contents (abfd, id4, d4, 0, 4);
+
+ bfd_make_readable (abfd);
+ return abfd;
+}
+
+/*
+ * .section .idata$4
+ * .long 0
+ * .section .idata$5
+ * .long 0
+ * .section idata$7
+ * .global __my_dll_iname
+ *__my_dll_iname:
+ * .asciz "my.dll"
+ */
+
+static bfd *
+make_tail (parent)
+ bfd *parent;
+{
+ asection *id4, *id5, *id7;
+ unsigned char *d4, *d5, *d7;
+ int len;
+ char *oname;
+ bfd *abfd;
+
+ oname = (char *) xmalloc (20);
+ sprintf (oname, "d%06d.o", tmp_seq);
+ tmp_seq++;
+
+ abfd = bfd_create (oname, parent);
+ bfd_find_target ("pe-i386", abfd);
+ bfd_make_writable (abfd);
+
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
+
+ symptr = 0;
+ symtab = (asymbol **) xmalloc (5 * sizeof (asymbol *));
+ id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
+ id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
+ id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
+ quick_symbol (abfd, "_", dll_symname, "_iname", id7, BSF_GLOBAL, 0);
+
+ bfd_set_section_size (abfd, id4, 4);
+ d4 = (unsigned char *) xmalloc (4);
+ id4->contents = d4;
+ memset (d4, 0, 4);
+
+ bfd_set_section_size (abfd, id5, 4);
+ d5 = (unsigned char *) xmalloc (4);
+ id5->contents = d5;
+ memset (d5, 0, 4);
+
+ len = strlen (dll_filename)+1;
+ if (len & 1)
+ len ++;
+ bfd_set_section_size (abfd, id7, len);
+ d7 = (unsigned char *) xmalloc (len);
+ id7->contents = d7;
+ strcpy (d7, dll_filename);
+
+ bfd_set_symtab (abfd, symtab, symptr);
+
+ bfd_set_section_contents (abfd, id4, d4, 0, 4);
+ bfd_set_section_contents (abfd, id5, d5, 0, 4);
+ bfd_set_section_contents (abfd, id7, d7, 0, len);
+
+ bfd_make_readable (abfd);
+ return abfd;
+}
+
+/*
+ * .text
+ * .global _function
+ * .global ___imp_function
+ * .global __imp__function
+ *_function:
+ * jmp *__imp__function:
+ *
+ * .section idata$7
+ * .long __head_my_dll
+ *
+ * .section .idata$5
+ *___imp_function:
+ *__imp__function:
+ *iat?
+ * .section .idata$4
+ *iat?
+ * .section .idata$6
+ *ID<ordinal>:
+ * .short <hint>
+ * .asciz "function" xlate? (add underscore, kill at)
+ */
+
+static unsigned char jmp_ix86_bytes[] = {
+ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
+};
+
+
+static bfd *
+make_one (exp, parent)
+ def_file_export *exp;
+ bfd *parent;
+{
+ asection *tx, *id7, *id5, *id4, *id6;
+ unsigned char *td, *d7, *d5, *d4, *d6;
+ int len;
+ char *oname;
+ bfd *abfd;
+
+ oname = (char *) xmalloc (20);
+ sprintf (oname, "d%06d.o", tmp_seq);
+ tmp_seq++;
+
+ abfd = bfd_create (oname, parent);
+ bfd_find_target ("pe-i386", abfd);
+ bfd_make_writable (abfd);
+
+ bfd_set_format (abfd, bfd_object);
+ bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
+
+ symptr = 0;
+ symtab = (asymbol **) xmalloc (10 * sizeof (asymbol *));
+ tx = quick_section (abfd, ".text", SEC_CODE|SEC_HAS_CONTENTS, 2);
+ id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
+ id5 = quick_section (abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
+ id4 = quick_section (abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
+ id6 = quick_section (abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
+ quick_symbol (abfd, "_", exp->internal_name, "", tx, BSF_GLOBAL, 0);
+ quick_symbol (abfd, "__head_", dll_symname, "", UNDSEC, BSF_GLOBAL, 0);
+ quick_symbol (abfd, "___imp_", exp->internal_name, "", id5, BSF_GLOBAL, 0);
+ quick_symbol (abfd, "__imp__", exp->internal_name, "", id5, BSF_GLOBAL, 0);
+
+ bfd_set_section_size (abfd, tx, 8);
+ td = (unsigned char *) xmalloc (8);
+ tx->contents = td;
+ memcpy (td, jmp_ix86_bytes, 8);
+ quick_reloc (abfd, 2, BFD_RELOC_32, 2);
+ save_relocs (tx);
+
+ bfd_set_section_size (abfd, id7, 4);
+ d7 = (unsigned char *) xmalloc (4);
+ id7->contents = d7;
+ memset (d7, 0, 4);
+ quick_reloc (abfd, 0, BFD_RELOC_RVA, 6);
+ save_relocs (id7);
+
+ bfd_set_section_size (abfd, id5, 4);
+ d5 = (unsigned char *) xmalloc (4);
+ id5->contents = d5;
+ memset (d5, 0, 4);
+ if (exp->flag_noname)
+ {
+ d5[0] = exp->ordinal;
+ d5[1] = exp->ordinal >> 8;
+ d5[3] = 0x80;
+ }
+ else
+ {
+ quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
+ save_relocs (id5);
+ }
+
+ bfd_set_section_size (abfd, id4, 4);
+ d4 = (unsigned char *) xmalloc (4);
+ id4->contents = d4;
+ memset (d4, 0, 4);
+ if (exp->flag_noname)
+ {
+ d5[0] = exp->ordinal;
+ d5[1] = exp->ordinal >> 8;
+ d5[3] = 0x80;
+ }
+ else
+ {
+ quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
+ save_relocs (id4);
+ }
+
+ if (exp->flag_noname)
+ {
+ len = 0;
+ bfd_set_section_size (abfd, id6, 0);
+ }
+ else
+ {
+ len = strlen (exp->name) + 3;
+ if (len & 1)
+ len++;
+ bfd_set_section_size (abfd, id6, len);
+ d6 = (unsigned char *) xmalloc (len);
+ id6->contents = d6;
+ memset (d6, 0, len);
+ d6[0] = exp->hint & 0xff;
+ d6[1] = exp->hint >> 8;
+ strcpy (d6+2, exp->name);
+ }
+
+ bfd_set_symtab (abfd, symtab, symptr);
+
+ bfd_set_section_contents (abfd, tx, td, 0, 4);
+ bfd_set_section_contents (abfd, id7, d7, 0, 4);
+ bfd_set_section_contents (abfd, id5, d5, 0, 4);
+ bfd_set_section_contents (abfd, id4, d4, 0, 4);
+ if (!exp->flag_noname)
+ bfd_set_section_contents (abfd, id6, d6, 0, len);
+
+ bfd_make_readable (abfd);
+ return abfd;
+}
+
+void
+pe_dll_generate_implib (def, impfilename)
+ def_file *def;
+ char *impfilename;
+{
+ int i;
+ bfd *ar_head;
+ bfd *ar_tail;
+ bfd *outarch;
+ bfd *head = 0;
+
+ dll_filename = def->name;
+ if (dll_filename == 0)
+ {
+ dll_filename = dll_name;
+ for (i=0; impfilename[i]; i++)
+ if (impfilename[i] == '/' || impfilename[i] == '\\')
+ dll_filename = impfilename+1;
+ }
+ dll_symname = xstrdup (dll_filename);
+ for (i=0; dll_symname[i]; i++)
+ if (!isalnum ((unsigned char) dll_symname[i]))
+ dll_symname[i] = '_';
+
+ unlink (impfilename);
+
+ outarch = bfd_openw (impfilename, 0);
+
+ if (!outarch)
+ {
+ /* xgettext:c-format */
+ einfo (_("%XCan't open .lib file: %s\n"), impfilename);
+ return;
+ }
+
+ /* xgettext:c-format */
+ einfo (_("Creating library file: %s\n"), impfilename);
+
+ bfd_set_format (outarch, bfd_archive);
+ outarch->has_armap = 1;
+
+ /* Work out a reasonable size of things to put onto one line. */
+
+ ar_head = make_head (outarch);
+ ar_tail = make_tail (outarch);
+
+ if (ar_head == NULL || ar_tail == NULL)
+ return;
+
+ for (i = 0; i<def->num_exports; i++)
+ {
+ /* The import library doesn't know about the internal name */
+ char *internal = def->exports[i].internal_name;
+ bfd *n;
+ def->exports[i].internal_name = def->exports[i].name;
+ n = make_one (def->exports+i, outarch);
+ n->next = head;
+ head = n;
+ def->exports[i].internal_name = internal;
+ }
+
+ /* Now stick them all into the archive */
+
+ ar_head->next = head;
+ ar_tail->next = ar_head;
+ head = ar_tail;
+
+ if (! bfd_set_archive_head (outarch, head))
+ einfo ("%Xbfd_set_archive_head: %s\n", bfd_errmsg (bfd_get_error ()));
+
+ if (! bfd_close (outarch))
+ einfo ("%Xbfd_close %s: %s\n", impfilename, bfd_errmsg (bfd_get_error ()));
+
+ while (head != NULL)
+ {
+ bfd *n = head->next;
+ bfd_close (head);
+ head = n;
+ }
+}
+
+static void
+add_bfd_to_link (abfd, name, link_info)
+ bfd *abfd;
+ char *name;
+ struct bfd_link_info *link_info;
+{
+ lang_input_statement_type *fake_file;
+ fake_file = lang_add_input_file (name,
+ lang_input_file_is_fake_enum,
+ NULL);
+ fake_file->the_bfd = abfd;
+ ldlang_add_file (fake_file);
+ if (!bfd_link_add_symbols (abfd, link_info))
+ einfo ("%Xaddsym %s: %s\n", name, bfd_errmsg (bfd_get_error ()));
+}
+
+void
+pe_process_import_defs (output_bfd, link_info)
+ bfd *output_bfd;
+ struct bfd_link_info *link_info;
+{
+ def_file_module *module;
+
+ if (!pe_def_file)
+ return;
+
+ for (module = pe_def_file->modules; module; module = module->next)
+ {
+ int i, do_this_dll;
+
+ dll_filename = module->name;
+ dll_symname = xstrdup (module->name);
+ for (i=0; dll_symname[i]; i++)
+ if (!isalnum (dll_symname[i]))
+ dll_symname[i] = '_';
+
+ do_this_dll = 0;
+
+ for (i=0; i<pe_def_file->num_imports; i++)
+ if (pe_def_file->imports[i].module == module)
+ {
+ def_file_export exp;
+ struct bfd_link_hash_entry *blhe;
+
+ /* see if we need this import */
+ char *name = (char *) xmalloc (strlen (pe_def_file->imports[i].internal_name) + 2);
+ sprintf (name, "_%s", pe_def_file->imports[i].internal_name);
+ blhe = bfd_link_hash_lookup (link_info->hash, name,
+ false, false, false);
+ free (name);
+ if (blhe && blhe->type == bfd_link_hash_undefined)
+ {
+ bfd *one;
+ /* we do */
+ if (!do_this_dll)
+ {
+ bfd *ar_head = make_head (output_bfd);
+ add_bfd_to_link (ar_head, ar_head->filename, link_info);
+ do_this_dll = 1;
+ }
+ exp.internal_name = pe_def_file->imports[i].internal_name;
+ exp.name = pe_def_file->imports[i].name;
+ exp.ordinal = pe_def_file->imports[i].ordinal;
+ exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0;
+ exp.flag_private = 0;
+ exp.flag_constant = 0;
+ exp.flag_data = 0;
+ exp.flag_noname = exp.name ? 0 : 1;
+ one = make_one (&exp, output_bfd);
+ add_bfd_to_link (one, one->filename, link_info);
+ }
+ }
+ if (do_this_dll)
+ {
+ bfd *ar_tail = make_tail (output_bfd);
+ add_bfd_to_link (ar_tail, ar_tail->filename, link_info);
+ }
+
+ free (dll_symname);
+ }
+}
+
+/************************************************************************
+
+ We were handed a *.DLL file. Parse it and turn it into a set of
+ IMPORTS directives in the def file. Return true if the file was
+ handled, false if not.
+
+ ************************************************************************/
+
+static unsigned int
+pe_get16 (abfd, where)
+ bfd *abfd;
+ int where;
+{
+ unsigned char b[2];
+ bfd_seek (abfd, where, SEEK_SET);
+ bfd_read (b, 1, 2, abfd);
+ return b[0] + (b[1]<<8);
+}
+
+static unsigned int
+pe_get32 (abfd, where)
+ bfd *abfd;
+ int where;
+{
+ unsigned char b[4];
+ bfd_seek (abfd, where, SEEK_SET);
+ bfd_read (b, 1, 4, abfd);
+ return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+}
+
+#if 0 /* This is not currently used. */
+
+static unsigned int
+pe_as16 (ptr)
+ void *ptr;
+{
+ unsigned char *b = ptr;
+ return b[0] + (b[1]<<8);
+}
+
+#endif
+
+static unsigned int
+pe_as32 (ptr)
+ void *ptr;
+{
+ unsigned char *b = ptr;
+ return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+}
+
+boolean
+pe_implied_import_dll (filename)
+ char *filename;
+{
+ bfd *dll;
+ unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+ unsigned long export_rva, export_size, nsections, secptr, expptr;
+ unsigned char *expdata, *erva;
+ unsigned long name_rvas, ordinals, nexp, ordbase;
+ char *dll_name;
+
+ /* No, I can't use bfd here. kernel32.dll puts its export table in
+ the middle of the .rdata section. */
+
+ dll = bfd_openr (filename, "pei-i386");
+ if (!dll)
+ {
+ einfo ("%Xopen %s: %s\n", filename, bfd_errmsg (bfd_get_error ()));
+ return false;
+ }
+ /* PEI dlls seem to be bfd_objects */
+ if (!bfd_check_format (dll, bfd_object))
+ {
+ einfo ("%X%s: this doesn't appear to be a DLL\n", filename);
+ return false;
+ }
+
+ dll_name = filename;
+ for (i=0; filename[i]; i++)
+ if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+ dll_name = filename + i + 1;
+
+ pe_header_offset = pe_get32 (dll, 0x3c);
+ opthdr_ofs = pe_header_offset + 4 + 20;
+ num_entries = pe_get32 (dll, opthdr_ofs + 92);
+ if (num_entries < 1) /* no exports */
+ return false;
+ export_rva = pe_get32 (dll, opthdr_ofs + 96);
+ export_size = pe_get32 (dll, opthdr_ofs + 100);
+ nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
+ secptr = (pe_header_offset + 4 + 20 +
+ pe_get16 (dll, pe_header_offset + 4 + 16));
+ expptr = 0;
+ for (i=0; i<nsections; i++)
+ {
+ char sname[8];
+ unsigned long secptr1 = secptr + 40 * i;
+ unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+ unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+ unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+ bfd_seek(dll, secptr1, SEEK_SET);
+ bfd_read(sname, 1, 8, dll);
+ if (vaddr <= export_rva && vaddr+vsize > export_rva)
+ {
+ expptr = fptr + (export_rva - vaddr);
+ if (export_rva + export_size > vaddr + vsize)
+ export_size = vsize - (export_rva - vaddr);
+ break;
+ }
+ }
+
+ expdata = (unsigned char *) xmalloc (export_size);
+ bfd_seek (dll, expptr, SEEK_SET);
+ bfd_read (expdata, 1, export_size, dll);
+ erva = expdata - export_rva;
+
+ if (pe_def_file == 0)
+ pe_def_file = def_file_empty();
+
+ nexp = pe_as32 (expdata+24);
+ name_rvas = pe_as32 (expdata+32);
+ ordinals = pe_as32 (expdata+36);
+ ordbase = pe_as32 (expdata+16);
+ for (i=0; i<nexp; i++)
+ {
+ unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+ def_file_import *imp;
+ imp = def_file_add_import (pe_def_file, erva+name_rva, dll_name,
+ i, 0);
+ }
+
+ return true;
+}
+
+/************************************************************************
+
+ These are the main functions, called from the emulation. The first
+ is called after the bfds are read, so we can guess at how much space
+ we need. The second is called after everything is placed, so we
+ can put the right values in place.
+
+ ************************************************************************/
+
+void
+pe_dll_build_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ process_def_file (abfd, info);
+
+ generate_edata (abfd, info);
+ build_filler_bfd ();
+}
+
+void
+pe_dll_fill_sections (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ image_base = pe_data (abfd)->pe_opthdr.ImageBase;
+
+ generate_reloc (abfd, info);
+ if (reloc_sz > 0)
+ {
+ bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
+
+ /* Resize the sections. */
+ lang_size_sections (stat_ptr->head, abs_output_section,
+ &stat_ptr->head, 0, (bfd_vma) 0, false);
+
+ /* Redo special stuff. */
+ ldemul_after_allocation ();
+
+ /* Do the assignments again. */
+ lang_do_assignments (stat_ptr->head,
+ abs_output_section,
+ (fill_type) 0, (bfd_vma) 0);
+ }
+
+ fill_edata (abfd, info);
+
+ pe_data (abfd)->dll = 1;
+
+ edata_s->contents = edata_d;
+ reloc_s->contents = reloc_d;
+}
diff --git a/ld/po/Make-in b/ld/po/Make-in
new file mode 100644
index 00000000000..4291090c000
--- /dev/null
+++ b/ld/po/Make-in
@@ -0,0 +1,251 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments -C --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ld/po/POTFILES.in b/ld/po/POTFILES.in
new file mode 100644
index 00000000000..468a8a62c78
--- /dev/null
+++ b/ld/po/POTFILES.in
@@ -0,0 +1,64 @@
+deffile.h
+ld.h
+ldcref.c
+ldctor.c
+ldctor.h
+ldemul.c
+ldemul.h
+ldexp.c
+ldexp.h
+ldfile.c
+ldfile.h
+ldlang.c
+ldlang.h
+ldlex.h
+ldmain.c
+ldmain.h
+ldmisc.c
+ldmisc.h
+ldver.c
+ldver.h
+ldwrite.c
+ldwrite.h
+lexsup.c
+mpw-elfmips.c
+mpw-eppcmac.c
+mpw-esh.c
+mpw-idtmips.c
+mri.c
+mri.h
+pe-dll.c
+sysdep.h
+testsuite/ld-cdtest/cdtest-foo.h
+testsuite/ld-elfvers/vers1.c
+testsuite/ld-elfvers/vers15.c
+testsuite/ld-elfvers/vers16.c
+testsuite/ld-elfvers/vers16a.c
+testsuite/ld-elfvers/vers2.c
+testsuite/ld-elfvers/vers3.c
+testsuite/ld-elfvers/vers4.c
+testsuite/ld-elfvers/vers5.c
+testsuite/ld-elfvers/vers6.c
+testsuite/ld-elfvers/vers7.c
+testsuite/ld-elfvers/vers7a.c
+testsuite/ld-elfvers/vers8.c
+testsuite/ld-elfvers/vers9.c
+testsuite/ld-empic/relax1.c
+testsuite/ld-empic/relax2.c
+testsuite/ld-empic/relax3.c
+testsuite/ld-empic/relax4.c
+testsuite/ld-empic/run.c
+testsuite/ld-empic/runtest1.c
+testsuite/ld-empic/runtest2.c
+testsuite/ld-scripts/cross1.c
+testsuite/ld-scripts/cross2.c
+testsuite/ld-scripts/cross3.c
+testsuite/ld-selective/1.c
+testsuite/ld-selective/2.c
+testsuite/ld-sh/sh2.c
+testsuite/ld-shared/main.c
+testsuite/ld-shared/sh1.c
+testsuite/ld-shared/sh2.c
+testsuite/ld-srec/sr1.c
+testsuite/ld-srec/sr2.c
+testsuite/ld-undefined/undefined.c
diff --git a/ld/po/ld.pot b/ld/po/ld.pot
new file mode 100644
index 00000000000..faaaeb08923
--- /dev/null
+++ b/ld/po/ld.pot
@@ -0,0 +1,1372 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1999-02-11 21:00+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: emultempl/armcoff.em:65
+msgid " --support-old-code Support interworking with old code\n"
+msgstr ""
+
+#: emultempl/armcoff.em:130
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr ""
+
+#: emultempl/pe.em:190
+msgid ""
+" --base_file <basefile> Generate a base file for relocatable "
+"DLLs\n"
+msgstr ""
+
+#: emultempl/pe.em:191
+msgid ""
+" --dll Set image base to the default for DLLs\n"
+msgstr ""
+
+#: emultempl/pe.em:192
+msgid " --file-alignment <size> Set file alignment\n"
+msgstr ""
+
+#: emultempl/pe.em:193
+msgid " --heap <size> Set initial size of the heap\n"
+msgstr ""
+
+#: emultempl/pe.em:194
+msgid ""
+" --image-base <address> Set start address of the executable\n"
+msgstr ""
+
+#: emultempl/pe.em:195
+msgid ""
+" --major-image-version <number> Set version number of the executable\n"
+msgstr ""
+
+#: emultempl/pe.em:196
+msgid " --major-os-version <number> Set minimum required OS version\n"
+msgstr ""
+
+#: emultempl/pe.em:197
+msgid ""
+" --major-subsystem-version <number> Set minimum required OS subsystem "
+"version\n"
+msgstr ""
+
+#: emultempl/pe.em:198
+msgid ""
+" --minor-image-version <number> Set revision number of the executable\n"
+msgstr ""
+
+#: emultempl/pe.em:199
+msgid " --minor-os-version <number> Set minimum required OS revision\n"
+msgstr ""
+
+#: emultempl/pe.em:200
+msgid ""
+" --minor-subsystem-version <number> Set minimum required OS subsystem "
+"revision\n"
+msgstr ""
+
+#: emultempl/pe.em:201
+msgid " --section-alignment <size> Set section alignment\n"
+msgstr ""
+
+#: emultempl/pe.em:202
+msgid " --stack <size> Set size of the initial stack\n"
+msgstr ""
+
+#: emultempl/pe.em:203
+msgid ""
+" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"
+msgstr ""
+
+#: emultempl/pe.em:204
+msgid ""
+" --support-old-code Support interworking with old code\n"
+msgstr ""
+
+#: emultempl/pe.em:206
+msgid ""
+" --add-stdcall-alias Export symbols with and without @nn\n"
+msgstr ""
+
+#: emultempl/pe.em:207
+msgid " --disable-stdcall-fixup Don't link _sym to _sym@nn\n"
+msgstr ""
+
+#: emultempl/pe.em:208
+msgid ""
+" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"
+msgstr ""
+
+#: emultempl/pe.em:209
+msgid ""
+" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"
+msgstr ""
+
+#: emultempl/pe.em:210
+msgid ""
+" --export-all-symbols Automatically export all globals to "
+"DLL\n"
+msgstr ""
+
+#: emultempl/pe.em:211
+msgid " --kill-at Remove @nn from exported symbols\n"
+msgstr ""
+
+#: emultempl/pe.em:212
+msgid " --out-implib <file> Generate import library\n"
+msgstr ""
+
+#: emultempl/pe.em:213
+msgid ""
+" --output-def <file> Generate a .DEF file for the built DLL\n"
+msgstr ""
+
+#: emultempl/pe.em:276
+msgid "%P: warning: bad version number in -subsystem option\n"
+msgstr ""
+
+#: emultempl/pe.em:292
+msgid "%P%F: invalid subsystem type %s\n"
+msgstr ""
+
+#: emultempl/pe.em:307
+msgid "%P%F: invalid hex number for PE parameter '%s'\n"
+msgstr ""
+
+#: emultempl/pe.em:325
+msgid "%P%F: strange hex info for PE parameter '%s'\n"
+msgstr ""
+
+#: emultempl/pe.em:364
+#, c-format
+msgid "%s: Can't open base file %s\n"
+msgstr ""
+
+#: emultempl/pe.em:497
+msgid "%P: warning, file alignment > section alignment.\n"
+msgstr ""
+
+#: emultempl/pe.em:567 emultempl/pe.em:593
+#, c-format
+msgid "Warning: resolving %s by linking to %s\n"
+msgstr ""
+
+#: emultempl/pe.em:572 emultempl/pe.em:598
+msgid "Use --enable-stdcall-fixup to disable these warnings\n"
+msgstr ""
+
+#: emultempl/pe.em:573 emultempl/pe.em:599
+msgid "Use --disable-stdcall-fixup to disable these fixups\n"
+msgstr ""
+
+#: emultempl/pe.em:615
+msgid "%F%P: PE operations on non PE file.\n"
+msgstr ""
+
+#: emultempl/pe.em:652
+#, c-format
+msgid "Errors encountered processing file %s\n"
+msgstr ""
+
+#: emultempl/pe.em:675
+#, c-format
+msgid "Errors encountered processing file %s for interworking"
+msgstr ""
+
+#: emultempl/pe.em:730 ldlang.c:1623 ldlang.c:3990 ldlang.c:4024 ldmain.c:978
+msgid "%P%F: bfd_link_hash_lookup failed: %E\n"
+msgstr ""
+
+#: ldcref.c:162
+msgid "%X%P: bfd_hash_table_init of cref table failed: %E\n"
+msgstr ""
+
+#: ldcref.c:168
+msgid "%X%P: cref_hash_lookup failed: %E\n"
+msgstr ""
+
+#: ldcref.c:239
+msgid ""
+"\n"
+"Cross Reference Table\n"
+"\n"
+msgstr ""
+
+#: ldcref.c:240
+msgid "Symbol"
+msgstr ""
+
+#: ldcref.c:248
+msgid "File\n"
+msgstr ""
+
+#: ldcref.c:252
+msgid "No symbols\n"
+msgstr ""
+
+#: ldcref.c:369
+msgid "%P: symbol `%T' missing from main hash table\n"
+msgstr ""
+
+#: ldcref.c:441
+msgid "%B%F: could not read symbols; %E\n"
+msgstr ""
+
+#: ldcref.c:445 ldmain.c:1046 ldmain.c:1050
+msgid "%B%F: could not read symbols: %E\n"
+msgstr ""
+
+#: ldcref.c:517 ldcref.c:524 ldmain.c:1096 ldmain.c:1103
+msgid "%B%F: could not read relocs: %E\n"
+msgstr ""
+
+#. We found a reloc for the symbol. The symbol is defined
+#. in OUTSECNAME. This reloc is from a section which is
+#. mapped into a section from which references to OUTSECNAME
+#. are prohibited. We must report an error.
+#: ldcref.c:542
+msgid "%X%C: prohibited cross reference from %s to `%T' in %s\n"
+msgstr ""
+
+#: ldctor.c:89
+msgid "%P%X: Different relocs used in set %s\n"
+msgstr ""
+
+#: ldctor.c:106
+msgid "%P%X: Different object file formats composing set %s\n"
+msgstr ""
+
+#: ldctor.c:288 ldctor.c:302
+msgid "%P%X: %s does not support reloc %s for set %s\n"
+msgstr ""
+
+#: ldctor.c:323
+msgid "%P%X: Unsupported size %d for set %s\n"
+msgstr ""
+
+#: ldctor.c:344
+msgid ""
+"\n"
+"Set Symbol\n"
+"\n"
+msgstr ""
+
+#: ldemul.c:223
+msgid "%S SYSLIB ignored\n"
+msgstr ""
+
+#: ldemul.c:231
+msgid "%S HLL ignored\n"
+msgstr ""
+
+#: ldemul.c:252
+msgid "%P: unrecognised emulation mode: %s\n"
+msgstr ""
+
+#: ldemul.c:253
+msgid "Supported emulations: "
+msgstr ""
+
+#: ldemul.c:297
+msgid " no emulation specific options.\n"
+msgstr ""
+
+#: ldexp.c:156
+msgid "%F%P: %s uses undefined section %s\n"
+msgstr ""
+
+#: ldexp.c:158
+msgid "%F%P: %s forward reference of section %s\n"
+msgstr ""
+
+#: ldexp.c:270
+msgid "%F%S %% by zero\n"
+msgstr ""
+
+#: ldexp.c:277
+msgid "%F%S / by zero\n"
+msgstr ""
+
+#: ldexp.c:400
+msgid "%X%S: unresolvable symbol `%s' referenced in expression\n"
+msgstr ""
+
+#: ldexp.c:419
+msgid "%F%S: undefined symbol `%s' referenced in expression\n"
+msgstr ""
+
+#: ldexp.c:600
+msgid "%F%S can not PROVIDE assignment to location counter\n"
+msgstr ""
+
+#: ldexp.c:610
+msgid "%F%S invalid assignment to location counter\n"
+msgstr ""
+
+#: ldexp.c:614
+msgid "%F%S assignment to location counter invalid outside of SECTION\n"
+msgstr ""
+
+#: ldexp.c:624
+msgid "%F%S cannot move location counter backwards (from %V to %V)\n"
+msgstr ""
+
+#: ldexp.c:652
+msgid "%P%F:%s: hash creation failed\n"
+msgstr ""
+
+#: ldexp.c:949
+msgid "%F%S nonconstant expression for %s\n"
+msgstr ""
+
+#: ldexp.c:982
+msgid "%F%S non constant expression for %s\n"
+msgstr ""
+
+#: ldfile.c:109
+#, c-format
+msgid "attempt to open %s failed\n"
+msgstr ""
+
+#: ldfile.c:111
+#, c-format
+msgid "attempt to open %s succeeded\n"
+msgstr ""
+
+#: ldfile.c:119
+msgid "%F%P: invalid BFD target `%s'\n"
+msgstr ""
+
+#: ldfile.c:222
+msgid "%F%P: cannot open %s: %E\n"
+msgstr ""
+
+#: ldfile.c:239 ldfile.c:254
+#, c-format
+msgid "cannot find script file %s\n"
+msgstr ""
+
+#: ldfile.c:241 ldfile.c:256
+#, c-format
+msgid "opened script file %s\n"
+msgstr ""
+
+#: ldfile.c:299
+msgid "%P%F: cannot open linker script file %s: %E\n"
+msgstr ""
+
+#: ldfile.c:340
+msgid "%P%F: unknown architecture: %s\n"
+msgstr ""
+
+#: ldfile.c:357
+msgid "%P%F: target architecture respecified\n"
+msgstr ""
+
+#: ldfile.c:410
+msgid "%P%F: cannot represent machine `%s'\n"
+msgstr ""
+
+#: ldlang.c:590
+msgid ""
+"\n"
+"Memory Configuration\n"
+"\n"
+msgstr ""
+
+#: ldlang.c:592
+msgid "Name"
+msgstr ""
+
+#: ldlang.c:592
+msgid "Origin"
+msgstr ""
+
+#: ldlang.c:592
+msgid "Length"
+msgstr ""
+
+#: ldlang.c:592
+msgid "Attributes"
+msgstr ""
+
+#: ldlang.c:634
+msgid ""
+"\n"
+"Linker script and memory map\n"
+"\n"
+msgstr ""
+
+#: ldlang.c:651
+msgid "%P%F: Illegal use of `%s' section"
+msgstr ""
+
+#: ldlang.c:661
+msgid "%P%F: output format %s cannot represent section called %s\n"
+msgstr ""
+
+#: ldlang.c:782
+msgid "%P: %B: warning: ignoring duplicate section `%s'\n"
+msgstr ""
+
+#: ldlang.c:796
+msgid "%P: %B: warning: duplicate section `%s' has different size\n"
+msgstr ""
+
+#: ldlang.c:1223
+msgid "%B: file not recognized: %E\n"
+msgstr ""
+
+#: ldlang.c:1224
+msgid "%B: matching formats:"
+msgstr ""
+
+#: ldlang.c:1231
+msgid "%F%B: file not recognized: %E\n"
+msgstr ""
+
+#: ldlang.c:1284
+msgid "%F%B: object %B in archive is not object\n"
+msgstr ""
+
+#: ldlang.c:1290 ldlang.c:1302
+msgid "%F%B: could not read symbols: %E\n"
+msgstr ""
+
+#: ldlang.c:1418
+msgid "%P%F: target %s not found\n"
+msgstr ""
+
+#: ldlang.c:1420
+msgid "%P%F: cannot open output file %s: %E\n"
+msgstr ""
+
+#: ldlang.c:1428
+msgid "%P%F:%s: can not make object file: %E\n"
+msgstr ""
+
+#: ldlang.c:1432
+msgid "%P%F:%s: can not set architecture: %E\n"
+msgstr ""
+
+#: ldlang.c:1436
+msgid "%P%F: can not create link hash table: %E\n"
+msgstr ""
+
+#: ldlang.c:1746
+msgid " load address 0x%V"
+msgstr ""
+
+#: ldlang.c:1875
+msgid "%W (size before relaxing)\n"
+msgstr ""
+
+#: ldlang.c:1954
+#, c-format
+msgid "Address of section %s set to "
+msgstr ""
+
+#: ldlang.c:2091
+#, c-format
+msgid "Fail with %d\n"
+msgstr ""
+
+#: ldlang.c:2320
+msgid "%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"
+msgstr ""
+
+#: ldlang.c:2372
+msgid "%P%X: Internal error on COFF shared library section %s\n"
+msgstr ""
+
+#: ldlang.c:2413
+msgid "%P: warning: no memory region specified for section `%s'\n"
+msgstr ""
+
+#: ldlang.c:2426
+msgid "%P: warning: changing start of section %s by %u bytes\n"
+msgstr ""
+
+#: ldlang.c:2440
+msgid "%F%S: non constant address expression for section %s\n"
+msgstr ""
+
+#: ldlang.c:2492
+msgid "%X%P: address 0x%v of %B section %s is not within region %s\n"
+msgstr ""
+
+#: ldlang.c:2500
+msgid "%X%P: region %s is full (%B section %s)\n"
+msgstr ""
+
+#: ldlang.c:2602
+msgid "%P%F: can't relax section: %E\n"
+msgstr ""
+
+#: ldlang.c:2763
+msgid "%F%P: invalid data statement\n"
+msgstr ""
+
+#: ldlang.c:2792
+msgid "%F%P: invalid reloc statement\n"
+msgstr ""
+
+#: ldlang.c:2926
+msgid "%P%F:%s: can't set start address\n"
+msgstr ""
+
+#: ldlang.c:2939 ldlang.c:2956
+msgid "%P%F: can't set start address\n"
+msgstr ""
+
+#: ldlang.c:2951
+msgid "%P: warning: cannot find entry symbol %s; defaulting to %V\n"
+msgstr ""
+
+#: ldlang.c:2961
+msgid "%P: warning: cannot find entry symbol %s; not setting start address\n"
+msgstr ""
+
+#: ldlang.c:3003
+msgid ""
+"%P: warning: %s architecture of input file `%B' is incompatible with %s "
+"output\n"
+msgstr ""
+
+#: ldlang.c:3021
+msgid "%E%X: failed to merge target specific data of file %B\n"
+msgstr ""
+
+#: ldlang.c:3106
+msgid ""
+"\n"
+"Allocating common symbols\n"
+msgstr ""
+
+#: ldlang.c:3107
+msgid ""
+"Common symbol size file\n"
+"\n"
+msgstr ""
+
+#. This message happens when using the
+#. svr3.ifile linker script, so I have
+#. disabled it.
+#: ldlang.c:3196
+msgid "%P: no [COMMON] command, defaulting to .bss\n"
+msgstr ""
+
+#: ldlang.c:3259
+msgid "%P%F: invalid syntax in flags\n"
+msgstr ""
+
+#: ldlang.c:3947
+msgid "%P%Fmultiple STARTUP files\n"
+msgstr ""
+
+#: ldlang.c:4209
+msgid "%F%P: bfd_record_phdr failed: %E\n"
+msgstr ""
+
+#: ldlang.c:4228
+msgid "%X%P: section `%s' assigned to non-existent phdr `%s'\n"
+msgstr ""
+
+#: ldlang.c:4497
+msgid "%X%P: duplicate version tag `%s'\n"
+msgstr ""
+
+#: ldlang.c:4510 ldlang.c:4523
+msgid "%X%P: duplicate expression `%s' in version information\n"
+msgstr ""
+
+#: ldlang.c:4560
+msgid "%X%P: unable to find version dependency `%s'\n"
+msgstr ""
+
+#: ldlang.c:4582
+msgid "%X%P: unable to read .exports section contents"
+msgstr ""
+
+#: ldmain.c:188
+msgid "%X%P: can't set BFD default target to `%s': %E\n"
+msgstr ""
+
+#: ldmain.c:245
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr ""
+
+#: ldmain.c:247
+msgid "%P%F: -r and -shared may not be used together\n"
+msgstr ""
+
+#: ldmain.c:276
+msgid "using internal linker script:\n"
+msgstr ""
+
+#: ldmain.c:295
+msgid "%P%F: no input files\n"
+msgstr ""
+
+#: ldmain.c:300
+msgid "%P: mode %s\n"
+msgstr ""
+
+#: ldmain.c:318
+msgid "%P%F: cannot open map file %s: %E\n"
+msgstr ""
+
+#: ldmain.c:364
+msgid "%P: link errors found, deleting executable `%s'\n"
+msgstr ""
+
+#: ldmain.c:375
+msgid "%F%B: final close failed: %E\n"
+msgstr ""
+
+#: ldmain.c:399
+msgid "%X%P: unable to open for source of copy `%s'\n"
+msgstr ""
+
+#: ldmain.c:401
+msgid "%X%P: unable to open for destination of copy `%s'\n"
+msgstr ""
+
+#: ldmain.c:407
+msgid "%P: Error writing file `%s'\n"
+msgstr ""
+
+#: ldmain.c:413 pe-dll.c:899
+#, c-format
+msgid "%P: Error closing file `%s'\n"
+msgstr ""
+
+#: ldmain.c:431
+#, c-format
+msgid "%s: total time in link: %ld.%06ld\n"
+msgstr ""
+
+#: ldmain.c:434
+#, c-format
+msgid "%s: data size %ld\n"
+msgstr ""
+
+#: ldmain.c:475
+msgid "%P%F: missing argument to -m\n"
+msgstr ""
+
+#: ldmain.c:589 ldmain.c:610 ldmain.c:641
+msgid "%P%F: bfd_hash_table_init failed: %E\n"
+msgstr ""
+
+#: ldmain.c:594 ldmain.c:613
+msgid "%P%F: bfd_hash_lookup failed: %E\n"
+msgstr ""
+
+#: ldmain.c:628
+msgid "%X%P: error: duplicate retain-symbols-file\n"
+msgstr ""
+
+#: ldmain.c:672
+msgid "%P%F: bfd_hash_lookup for insertion failed: %E\n"
+msgstr ""
+
+#: ldmain.c:677
+msgid "%P: `-retain-symbols-file' overrides `-s' and `-S'\n"
+msgstr ""
+
+#: ldmain.c:754
+msgid "Archive member included"
+msgstr ""
+
+#: ldmain.c:755
+msgid "because of file (symbol)"
+msgstr ""
+
+#: ldmain.c:827
+msgid "%X%C: multiple definition of `%T'\n"
+msgstr ""
+
+#: ldmain.c:830
+msgid "%D: first defined here\n"
+msgstr ""
+
+#: ldmain.c:859
+msgid "%B: warning: definition of `%T' overriding common\n"
+msgstr ""
+
+#: ldmain.c:862
+msgid "%B: warning: common is here\n"
+msgstr ""
+
+#: ldmain.c:869
+msgid "%B: warning: common of `%T' overridden by definition\n"
+msgstr ""
+
+#: ldmain.c:872
+msgid "%B: warning: defined here\n"
+msgstr ""
+
+#: ldmain.c:879
+msgid "%B: warning: common of `%T' overridden by larger common\n"
+msgstr ""
+
+#: ldmain.c:882
+msgid "%B: warning: larger common is here\n"
+msgstr ""
+
+#: ldmain.c:886
+msgid "%B: warning: common of `%T' overriding smaller common\n"
+msgstr ""
+
+#: ldmain.c:889
+msgid "%B: warning: smaller common is here\n"
+msgstr ""
+
+#: ldmain.c:893
+msgid "%B: warning: multiple common of `%T'\n"
+msgstr ""
+
+#: ldmain.c:895
+msgid "%B: warning: previous common is here\n"
+msgstr ""
+
+#: ldmain.c:917 ldmain.c:956
+msgid "%P: warning: global constructor %s used\n"
+msgstr ""
+
+#: ldmain.c:966
+msgid "%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"
+msgstr ""
+
+#: ldmain.c:1152
+msgid "%F%P: bfd_hash_table_init failed: %E\n"
+msgstr ""
+
+#: ldmain.c:1159
+msgid "%F%P: bfd_hash_lookup failed: %E\n"
+msgstr ""
+
+#: ldmain.c:1178
+msgid "%X%C: undefined reference to `%T'\n"
+msgstr ""
+
+#: ldmain.c:1181
+msgid "%D: more undefined references to `%T' follow\n"
+msgstr ""
+
+#: ldmain.c:1187
+msgid "%X%B: undefined reference to `%T'\n"
+msgstr ""
+
+#: ldmain.c:1190
+msgid "%B: more undefined references to `%T' follow\n"
+msgstr ""
+
+#: ldmain.c:1211 ldmain.c:1233 ldmain.c:1253
+msgid "%P%X: generated"
+msgstr ""
+
+#: ldmain.c:1214
+msgid " relocation truncated to fit: %s %T"
+msgstr ""
+
+#: ldmain.c:1236
+#, c-format
+msgid "dangerous relocation: %s\n"
+msgstr ""
+
+#: ldmain.c:1256
+msgid " reloc refers to symbol `%T' which is not being output\n"
+msgstr ""
+
+#: ldmisc.c:177
+msgid "no symbol"
+msgstr ""
+
+#: ldmisc.c:239
+#, c-format
+msgid "built in linker script:%u"
+msgstr ""
+
+#: ldmisc.c:289 ldmisc.c:293
+msgid "%B%F: could not read symbols\n"
+msgstr ""
+
+#. We use abfd->filename in this initial line,
+#. in case filename is a .h file or something
+#. similarly unhelpful.
+#: ldmisc.c:329
+msgid "%B: In function `%T':\n"
+msgstr ""
+
+#: ldmisc.c:461
+msgid "%F%P: internal error %s %d\n"
+msgstr ""
+
+#: ldver.c:35
+#, c-format
+msgid "GNU ld version %s (with BFD %s)\n"
+msgstr ""
+
+#: ldver.c:42 lexsup.c:829
+msgid " Supported emulations:\n"
+msgstr ""
+
+#: ldwrite.c:59 ldwrite.c:195
+msgid "%P%F: bfd_new_link_order failed\n"
+msgstr ""
+
+#: ldwrite.c:365
+#, c-format
+msgid "%8x something else\n"
+msgstr ""
+
+#: ldwrite.c:526
+msgid "%F%P: final link failed: %E\n"
+msgstr ""
+
+#: lexsup.c:148 lexsup.c:231 lexsup.c:237
+msgid "KEYWORD"
+msgstr ""
+
+#: lexsup.c:148
+msgid "Shared library control for HP/UX compatibility"
+msgstr ""
+
+#: lexsup.c:151
+msgid "ARCH"
+msgstr ""
+
+#: lexsup.c:151
+msgid "Set architecture"
+msgstr ""
+
+#: lexsup.c:153 lexsup.c:290
+msgid "TARGET"
+msgstr ""
+
+#: lexsup.c:153
+msgid "Specify target for following input files"
+msgstr ""
+
+#: lexsup.c:155 lexsup.c:194 lexsup.c:204 lexsup.c:213 lexsup.c:278
+#: lexsup.c:297 lexsup.c:331
+msgid "FILE"
+msgstr ""
+
+#: lexsup.c:155
+msgid "Read MRI format linker script"
+msgstr ""
+
+#: lexsup.c:157
+msgid "Force common symbols to be defined"
+msgstr ""
+
+#: lexsup.c:161 lexsup.c:321 lexsup.c:323 lexsup.c:325
+msgid "ADDRESS"
+msgstr ""
+
+#: lexsup.c:161
+msgid "Set start address"
+msgstr ""
+
+#: lexsup.c:163
+msgid "Export all dynamic symbols"
+msgstr ""
+
+#: lexsup.c:165
+msgid "Link big-endian objects"
+msgstr ""
+
+#: lexsup.c:167
+msgid "Link little-endian objects"
+msgstr ""
+
+#: lexsup.c:169 lexsup.c:172
+msgid "SHLIB"
+msgstr ""
+
+#: lexsup.c:169
+msgid "Auxiliary filter for shared object symbol table"
+msgstr ""
+
+#: lexsup.c:172
+msgid "Filter for shared object symbol table"
+msgstr ""
+
+#: lexsup.c:174
+msgid "Ignored"
+msgstr ""
+
+#: lexsup.c:176
+msgid "SIZE"
+msgstr ""
+
+#: lexsup.c:176
+msgid "Small data size (if no size, same as --shared)"
+msgstr ""
+
+#: lexsup.c:179
+msgid "FILENAME"
+msgstr ""
+
+#: lexsup.c:179
+msgid "Set internal name of shared library"
+msgstr ""
+
+#: lexsup.c:181
+msgid "LIBNAME"
+msgstr ""
+
+#: lexsup.c:181
+msgid "Search for library LIBNAME"
+msgstr ""
+
+#: lexsup.c:183
+msgid "DIRECTORY"
+msgstr ""
+
+#: lexsup.c:183
+msgid "Add DIRECTORY to library search path"
+msgstr ""
+
+#: lexsup.c:185
+msgid "EMULATION"
+msgstr ""
+
+#: lexsup.c:185
+msgid "Set emulation"
+msgstr ""
+
+#: lexsup.c:187
+msgid "Print map file on standard output"
+msgstr ""
+
+#: lexsup.c:189
+msgid "Do not page align data"
+msgstr ""
+
+#: lexsup.c:191
+msgid "Do not page align data, do not make text readonly"
+msgstr ""
+
+#: lexsup.c:194
+msgid "Set output file name"
+msgstr ""
+
+#: lexsup.c:196
+msgid "Optimize output file"
+msgstr ""
+
+#: lexsup.c:198
+msgid "Ignored for SVR4 compatibility"
+msgstr ""
+
+#: lexsup.c:200
+msgid "Generate relocateable output"
+msgstr ""
+
+#: lexsup.c:204
+msgid "Just link symbols (if directory, same as --rpath)"
+msgstr ""
+
+#: lexsup.c:207
+msgid "Strip all symbols"
+msgstr ""
+
+#: lexsup.c:209
+msgid "Strip debugging symbols"
+msgstr ""
+
+#: lexsup.c:211
+msgid "Trace file opens"
+msgstr ""
+
+#: lexsup.c:213
+msgid "Read linker script"
+msgstr ""
+
+#: lexsup.c:215 lexsup.c:227 lexsup.c:317 lexsup.c:334 lexsup.c:351
+msgid "SYMBOL"
+msgstr ""
+
+#: lexsup.c:215
+msgid "Start with undefined reference to SYMBOL"
+msgstr ""
+
+#: lexsup.c:217
+msgid "Build global constructor/destructor tables"
+msgstr ""
+
+#: lexsup.c:219
+msgid "Print version information"
+msgstr ""
+
+#: lexsup.c:221
+msgid "Print version and emulation information"
+msgstr ""
+
+#: lexsup.c:223
+msgid "Discard all local symbols"
+msgstr ""
+
+#: lexsup.c:225
+msgid "Discard temporary local symbols"
+msgstr ""
+
+#: lexsup.c:227
+msgid "Trace mentions of SYMBOL"
+msgstr ""
+
+#: lexsup.c:229 lexsup.c:299 lexsup.c:301
+msgid "PATH"
+msgstr ""
+
+#: lexsup.c:229
+msgid "Default search path for Solaris compatibility"
+msgstr ""
+
+#: lexsup.c:231
+msgid "Ignored for Solaris compatibility"
+msgstr ""
+
+#: lexsup.c:233
+msgid "Start a group"
+msgstr ""
+
+#: lexsup.c:235
+msgid "End a group"
+msgstr ""
+
+#: lexsup.c:237
+msgid "Ignored for SunOS compatibility"
+msgstr ""
+
+#: lexsup.c:239
+msgid "Link against shared libraries"
+msgstr ""
+
+#: lexsup.c:245
+msgid "Do not link against shared libraries"
+msgstr ""
+
+#: lexsup.c:253
+msgid "Bind global references locally"
+msgstr ""
+
+#: lexsup.c:255
+msgid "Check section addresses for overlaps (default)"
+msgstr ""
+
+#: lexsup.c:257
+msgid "Do not check section addresses for overlaps"
+msgstr ""
+
+#: lexsup.c:260
+msgid "Output cross reference table"
+msgstr ""
+
+#: lexsup.c:262
+msgid "SYMBOL=EXPRESSION"
+msgstr ""
+
+#: lexsup.c:262
+msgid "Define a symbol"
+msgstr ""
+
+#: lexsup.c:264
+msgid "PROGRAM"
+msgstr ""
+
+#: lexsup.c:264
+msgid "Set the dynamic linker to use"
+msgstr ""
+
+#: lexsup.c:266
+msgid "Generate embedded relocs"
+msgstr ""
+
+#: lexsup.c:268
+msgid "Force generation of file with .exe suffix"
+msgstr ""
+
+#: lexsup.c:270
+msgid "Remove unused sections (on some targets)"
+msgstr ""
+
+#: lexsup.c:273
+msgid "Don't remove unused sections (default)"
+msgstr ""
+
+#: lexsup.c:276
+msgid "Print option help"
+msgstr ""
+
+#: lexsup.c:278
+msgid "Write a map file"
+msgstr ""
+
+#: lexsup.c:280
+msgid "Use less memory and more disk I/O"
+msgstr ""
+
+#: lexsup.c:282
+msgid "Don't warn about mismatched input files"
+msgstr ""
+
+#: lexsup.c:284
+msgid "Turn off --whole-archive"
+msgstr ""
+
+#: lexsup.c:286
+msgid "Create an output file even if errors occur"
+msgstr ""
+
+#: lexsup.c:290
+msgid "Specify target of output file"
+msgstr ""
+
+#: lexsup.c:292
+msgid "Ignored for Linux compatibility"
+msgstr ""
+
+#: lexsup.c:294
+msgid "Relax branches on certain targets"
+msgstr ""
+
+#: lexsup.c:297
+msgid "Keep only symbols listed in FILE"
+msgstr ""
+
+#: lexsup.c:299
+msgid "Set runtime shared library search path"
+msgstr ""
+
+#: lexsup.c:301
+msgid "Set link time shared library search path"
+msgstr ""
+
+#: lexsup.c:303
+msgid "Create a shared library"
+msgstr ""
+
+#: lexsup.c:307
+msgid "Sort common symbols by size"
+msgstr ""
+
+#: lexsup.c:311
+msgid "Split output sections for each file"
+msgstr ""
+
+#: lexsup.c:313
+msgid "COUNT"
+msgstr ""
+
+#: lexsup.c:313
+msgid "Split output sections every COUNT relocs"
+msgstr ""
+
+#: lexsup.c:315
+msgid "Print memory usage statistics"
+msgstr ""
+
+#: lexsup.c:317
+msgid "Do task level linking"
+msgstr ""
+
+#: lexsup.c:319
+msgid "Use same format as native linker"
+msgstr ""
+
+#: lexsup.c:321
+msgid "Set address of .bss section"
+msgstr ""
+
+#: lexsup.c:323
+msgid "Set address of .data section"
+msgstr ""
+
+#: lexsup.c:325
+msgid "Set address of .text section"
+msgstr ""
+
+#: lexsup.c:327
+msgid "Output lots of information during link"
+msgstr ""
+
+#: lexsup.c:331
+msgid "Read version information script"
+msgstr ""
+
+#: lexsup.c:334
+msgid "Take export symbols list from .exports, using SYMBOL as the version."
+msgstr ""
+
+#: lexsup.c:337
+msgid "Warn about duplicate common symbols"
+msgstr ""
+
+#: lexsup.c:339
+msgid "Warn if global constructors/destructors are seen"
+msgstr ""
+
+#: lexsup.c:342
+msgid "Warn if the multiple GP values are used"
+msgstr ""
+
+#: lexsup.c:344
+msgid "Warn only once per undefined symbol"
+msgstr ""
+
+#: lexsup.c:346
+msgid "Warn if start of section changes due to alignment"
+msgstr ""
+
+#: lexsup.c:349
+msgid "Include all objects from following archives"
+msgstr ""
+
+#: lexsup.c:351
+msgid "Use wrapper functions for SYMBOL"
+msgstr ""
+
+#: lexsup.c:491
+msgid "%P%F: unrecognized -a option `%s'\n"
+msgstr ""
+
+#: lexsup.c:504
+msgid "%P%F: unrecognized -assert option `%s'\n"
+msgstr ""
+
+#: lexsup.c:592
+msgid "%P%F: invalid number `%s'\n"
+msgstr ""
+
+#: lexsup.c:758
+msgid "%P%F: -shared not supported\n"
+msgstr ""
+
+#: lexsup.c:822
+msgid "Copyright 1997 Free Software Foundation, Inc.\n"
+msgstr ""
+
+#: lexsup.c:823
+msgid ""
+"This program is free software; you may redistribute it under the terms of\n"
+"the GNU General Public License. This program has absolutely no warranty.\n"
+msgstr ""
+
+#: lexsup.c:914
+#, c-format
+msgid "%s: may not nest groups (--help for usage)\n"
+msgstr ""
+
+#: lexsup.c:925
+#, c-format
+msgid "%s: group ended before it began (--help for usage)\n"
+msgstr ""
+
+#: lexsup.c:973
+msgid "%P%F: invalid hex number `%s'\n"
+msgstr ""
+
+#: lexsup.c:985
+#, c-format
+msgid "Usage: %s [options] file...\n"
+msgstr ""
+
+#: lexsup.c:987
+msgid "Options:\n"
+msgstr ""
+
+#: lexsup.c:1064
+#, c-format
+msgid "%s: supported targets:"
+msgstr ""
+
+#: lexsup.c:1072
+#, c-format
+msgid "%s: supported emulations: "
+msgstr ""
+
+#: lexsup.c:1077
+#, c-format
+msgid "%s: emulation specific options:\n"
+msgstr ""
+
+#: lexsup.c:1081
+msgid ""
+"\n"
+"Report bugs to bug-gnu-utils@gnu.org\n"
+msgstr ""
+
+#: mri.c:342
+msgid "%P%F: unknown format type %s\n"
+msgstr ""
+
+#: pe-dll.c:294
+#, c-format
+msgid "%XError, duplicate EXPORT with oridinals: %s (%d vs %d)\n"
+msgstr ""
+
+#: pe-dll.c:300
+#, c-format
+msgid "Warning, duplicate EXPORT: %s\n"
+msgstr ""
+
+#: pe-dll.c:348
+#, c-format
+msgid "%XCannot export %s: symbol not defined\n"
+msgstr ""
+
+#: pe-dll.c:354
+#, c-format
+msgid "%XCannot export %s: symbol wrong type (%d vs %d)\n"
+msgstr ""
+
+#: pe-dll.c:361
+#, c-format
+msgid "%XCannot export %s: symbol not found\n"
+msgstr ""
+
+#: pe-dll.c:482
+#, c-format
+msgid "%XError, oridinal used twice: %d (%s vs %s)\n"
+msgstr ""
+
+#: pe-dll.c:664
+#, c-format
+msgid "%XError: %d-bit reloc in dll\n"
+msgstr ""
+
+#: pe-dll.c:773
+#, c-format
+msgid "%s: Can't open output def file %s\n"
+msgstr ""
+
+#: pe-dll.c:894
+msgid "; no contents available\n"
+msgstr ""
+
+#: pe-dll.c:1326
+#, c-format
+msgid "%XCan't open .lib file: %s\n"
+msgstr ""
+
+#: pe-dll.c:1331
+#, c-format
+msgid "Creating library file: %s\n"
+msgstr ""
diff --git a/ld/scripttempl/README b/ld/scripttempl/README
new file mode 100644
index 00000000000..26ad2e934e2
--- /dev/null
+++ b/ld/scripttempl/README
@@ -0,0 +1,4 @@
+The files in this directory are linker script templates.
+genscripts.sh sets some shell variables, then sources
+EMULATION.sc, to generate EMULATION.{x,xr,xu,xn,xbn} -- the script
+files for default, -r, -Ur, -n, -N.
diff --git a/ld/scripttempl/a29k.sc b/ld/scripttempl/a29k.sc
new file mode 100644
index 00000000000..2825b1e83ea
--- /dev/null
+++ b/ld/scripttempl/a29k.sc
@@ -0,0 +1,37 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+SECTIONS
+{
+ .text : {
+ *(.text)
+ ${RELOCATING+ __etext = .};
+ ${CONSTRUCTING+ __CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __CTOR_END__ = .;}
+ ${CONSTRUCTING+ __DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __DTOR_END__ = .;}
+ *(.lit)
+ *(.shdata)
+ }
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .data : {
+ *(.data)
+ ${RELOCATING+ __edata = .};
+ }
+ .bss SIZEOF(.data) + ADDR(.data) :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ __end = ALIGN(0x8)};
+ }
+}
+EOF
diff --git a/ld/scripttempl/aix.sc b/ld/scripttempl/aix.sc
new file mode 100644
index 00000000000..3f4b6175906
--- /dev/null
+++ b/ld/scripttempl/aix.sc
@@ -0,0 +1,55 @@
+# AIX linker script.
+# AIX always uses shared libraries. The section VMA appears to be
+# unimportant. The native linker aligns the sections on boundaries
+# specified by the -H option.
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+${RELOCATING+${LIB_SEARCH_DIRS}}
+ENTRY(__start)
+SECTIONS
+{
+ .pad 0 : { *(.pad) }
+ .text ${RELOCATING-0} : {
+ ${RELOCATING+PROVIDE (_text = .);}
+ *(.text)
+ *(.pr)
+ *(.ro)
+ *(.db)
+ *(.gl)
+ *(.xo)
+ *(.ti)
+ *(.tb)
+ ${RELOCATING+PROVIDE (_etext = .);}
+ }
+ .data 0 : {
+ ${RELOCATING+PROVIDE (_data = .);}
+ *(.data)
+ *(.rw)
+ *(.sv)
+ *(.ua)
+ . = ALIGN(4);
+ ${CONSTRUCTING+CONSTRUCTORS}
+ *(.ds)
+ *(.tc0)
+ *(.tc)
+ *(.td)
+ ${RELOCATING+PROVIDE (_edata = .);}
+ }
+ .bss : {
+ *(.tocbss)
+ *(.bss)
+ *(.bs)
+ *(.uc)
+ *(COMMON)
+ ${RELOCATING+PROVIDE (_end = .);}
+ ${RELOCATING+PROVIDE (end = .);}
+ }
+ .loader 0 : {
+ *(.loader)
+ }
+ .debug 0 : {
+ *(.debug)
+ }
+}
+EOF
diff --git a/ld/scripttempl/alpha.sc b/ld/scripttempl/alpha.sc
new file mode 100644
index 00000000000..44a10c469cd
--- /dev/null
+++ b/ld/scripttempl/alpha.sc
@@ -0,0 +1,74 @@
+# Linker script for Alpha systems.
+# Ian Lance Taylor <ian@cygnus.com>.
+# These variables may be overridden by the emulation file. The
+# defaults are appropriate for an Alpha running OSF/1.
+test -z "$ENTRY" && ENTRY=__start
+test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x120000000 + SIZEOF_HEADERS"
+if test "x$LD_FLAG" = "xn" -o "x$LD_FLAG" = "xN"; then
+ DATA_ADDR=.
+else
+ test -z "$DATA_ADDR" && DATA_ADDR=0x140000000
+fi
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ ${RELOCATING+. = ${TEXT_START_ADDR};}
+ .text : {
+ ${RELOCATING+ _ftext = . };
+ ${RELOCATING+ __istart = . };
+ ${RELOCATING+ *(.init) }
+ ${RELOCATING+ LONG (0x6bfa8001)}
+ ${RELOCATING+ eprol = .};
+ *(.text)
+ ${RELOCATING+ __fstart = . };
+ ${RELOCATING+ *(.fini)}
+ ${RELOCATING+ LONG (0x6bfa8001)}
+ ${RELOCATING+ _etext = .};
+ }
+ .rdata : {
+ *(.rdata)
+ }
+ .rconst : {
+ *(.rconst)
+ }
+ .pdata : {
+ ${RELOCATING+ _fpdata = .;}
+ *(.pdata)
+ }
+ ${RELOCATING+. = ${DATA_ADDR};}
+ .data : {
+ ${RELOCATING+ _fdata = .;}
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ }
+ .xdata : {
+ *(.xdata)
+ }
+ ${RELOCATING+ _gp = ALIGN (16) + 0x8000;}
+ .lit8 : {
+ *(.lit8)
+ }
+ .lita : {
+ *(.lita)
+ }
+ .sdata : {
+ *(.sdata)
+ }
+ ${RELOCATING+ _EDATA = .;}
+ ${RELOCATING+ _FBSS = .;}
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ ${RELOCATING+ _end = .;}
+}
+EOF
diff --git a/ld/scripttempl/aout.sc b/ld/scripttempl/aout.sc
new file mode 100644
index 00000000000..80dbb379633
--- /dev/null
+++ b/ld/scripttempl/aout.sc
@@ -0,0 +1,57 @@
+test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${ALIGNMENT}" && ALIGNMENT="4"
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${STACKZERO+${RELOCATING+${STACKZERO}}}
+${SHLIB_PATH+${RELOCATING+${SHLIB_PATH}}}
+${RELOCATING+${EXECUTABLE_SYMBOLS}}
+${RELOCATING+PROVIDE (__stack = 0);}
+SECTIONS
+{
+ ${RELOCATING+. = ${TEXT_START_ADDR};}
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ /* The next six sections are for SunOS dynamic linking. The order
+ is important. */
+ *(.dynrel)
+ *(.hash)
+ *(.dynsym)
+ *(.dynstr)
+ *(.rules)
+ *(.need)
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+__etext = .;}
+ ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}}
+ }
+ ${RELOCATING+. = ${DATA_ALIGNMENT};}
+ .data :
+ {
+ /* The first three sections are for SunOS dynamic linking. */
+ *(.dynamic)
+ *(.got)
+ *(.plt)
+ *(.data)
+ *(.linux-dynamic) /* For Linux dynamic linking. */
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+__edata = .;}
+ }
+ .bss :
+ {
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+ ${RELOCATING+_end = . };
+ ${RELOCATING+__end = . };
+ }
+}
+EOF
diff --git a/ld/scripttempl/armaout.sc b/ld/scripttempl/armaout.sc
new file mode 100644
index 00000000000..e9276a877e1
--- /dev/null
+++ b/ld/scripttempl/armaout.sc
@@ -0,0 +1,35 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${STACKZERO+${RELOCATING+${STACKZERO}}}
+SECTIONS
+{
+ .text ${RELOCATING+${TEXT_START_ADDR}} :
+ {
+ CREATE_OBJECT_SYMBOLS
+ ${RELOCATING+__stext_ = .;}
+ *(.text)
+ ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}}
+ ${RELOCATING+_etext = ${DATA_ALIGNMENT};}
+ ${RELOCATING+__etext = ${DATA_ALIGNMENT};}
+ }
+ .data ${RELOCATING+${DATA_ALIGNMENT}} :
+ {
+ ${RELOCATING+__sdata_ = .;}
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+__edata = .;}
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR (.data)} :
+ {
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+_end = ALIGN(4) };
+ ${RELOCATING+__end = ALIGN(4) };
+ }
+}
+EOF
diff --git a/ld/scripttempl/armcoff.sc b/ld/scripttempl/armcoff.sc
new file mode 100644
index 00000000000..8e07169d560
--- /dev/null
+++ b/ld/scripttempl/armcoff.sc
@@ -0,0 +1,62 @@
+# Linker script for ARM COFF.
+# Based on i386coff.sc by Ian Taylor <ian@cygnus.com>.
+test -z "$ENTRY" && ENTRY=_start
+if test -z "${DATA_ADDR}"; then
+ if test "$LD_FLAG" = "N" || test "$LD_FLAG" = "n"; then
+ DATA_ADDR=.
+ fi
+fi
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ /* We start at 0x8000 because gdb assumes it (see FRAME_CHAIN).
+ This is an artifact of the ARM Demon monitor using the bottom 32k
+ as workspace (shared with the FP instruction emulator if
+ present): */
+ .text ${RELOCATING+ 0x8000} : {
+ *(.init)
+ *(.text)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.rdata)
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1); *(.ctors); *(.ctor); LONG (0); }
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); LONG (0); }
+ *(.fini)
+ ${RELOCATING+ etext = .;}
+ }
+ .data ${RELOCATING+${DATA_ADDR-0x40000 + (. & 0xfffc0fff)}} : {
+ ${RELOCATING+ __data_start__ = . ;}
+ *(.data)
+ ${RELOCATING+ __data_end__ = . ;}
+ ${RELOCATING+ edata = .;}
+ ${RELOCATING+ _edata = .;}
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ ${RELOCATING+ __bss_start__ = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ __bss_end__ = . ;}
+ }
+
+ ${RELOCATING+ end = .;}
+ ${RELOCATING+ _end = .;}
+ ${RELOCATING+ __end__ = .;}
+
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/delta68.sc b/ld/scripttempl/delta68.sc
new file mode 100644
index 00000000000..d9963054e76
--- /dev/null
+++ b/ld/scripttempl/delta68.sc
@@ -0,0 +1,49 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+ENTRY(_start)
+${RELOCATING+${LIB_SEARCH_DIRS}}
+
+SECTIONS
+{
+ .text ${RELOCATING+ 0x2000 + SIZEOF_HEADERS} :
+ {
+ ${RELOCATING+ __.text.start = .};
+ *(.text)
+ ${RELOCATING+ etext = .;}
+ ${RELOCATING+ _etext = .;}
+ ${RELOCATING+ __.text.end = .};
+ ${CONSTRUCTING+ __CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __CTOR_END__ = .;}
+ ${CONSTRUCTING+ __DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __DTOR_END__ = .;}
+ }
+ .data ${RELOCATING+ SIZEOF(.text) + ADDR(.text) + 0x400000} :
+ {
+ ${RELOCATING+ __.data.start = .};
+ *(.data)
+ ${RELOCATING+ edata = .};
+ ${RELOCATING+ _edata = .};
+ ${RELOCATING+ __.data.end = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ ${RELOCATING+ __.bss.start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ __.bss.end = .};
+ ${RELOCATING+ end = ALIGN(0x8)};
+ ${RELOCATING+ _end = ALIGN(0x8)};
+ }
+ .comment ${RELOCATING+ 0} :
+ {
+ *(.comment)
+ }
+}
+EOF
diff --git a/ld/scripttempl/ebmon29k.sc b/ld/scripttempl/ebmon29k.sc
new file mode 100644
index 00000000000..62050ee2170
--- /dev/null
+++ b/ld/scripttempl/ebmon29k.sc
@@ -0,0 +1,27 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+ENTRY(start)
+
+SECTIONS {
+ .text ${RELOCATING+${TEXT_START_ADDR}} :
+ {
+ *(.text);
+ ${RELOCATING+_etext = .};
+ }
+ data ${RELOCATING+0x80002000} :
+ {
+ *(.data);
+ *(.mstack);
+ *(.shbss);
+ *(.rstack);
+ *(.mstack);
+ ${CONSTRUCTING+CONSTRUCTORS}
+ }
+ .bss . :
+ {
+ *(COMMON)
+ *(.bss);
+ ${RELOCATING+_end = .};
+ }
+}
+EOF
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
new file mode 100644
index 00000000000..e1fea97d791
--- /dev/null
+++ b/ld/scripttempl/elf.sc
@@ -0,0 +1,286 @@
+#
+# Unusual variables checked by this code:
+# NOP - two byte opcode for no-op (defaults to 0)
+# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+# INITIAL_READONLY_SECTIONS - at start of text segment
+# OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
+# (e.g., .PARISC.milli)
+# OTHER_TEXT_SECTIONS - these get put in .text when relocating
+# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
+# (e.g., .PARISC.global)
+# OTHER_SECTIONS - at the end
+# EXECUTABLE_SYMBOLS - symbols that must be defined for an
+# executable (e.g., _DYNAMIC_LINK)
+# TEXT_START_SYMBOLS - symbols that appear at the start of the
+# .text section.
+# DATA_START_SYMBOLS - symbols that appear at the start of the
+# .data section.
+# OTHER_GOT_SYMBOLS - symbols defined just before .got.
+# OTHER_GOT_SECTIONS - sections just after .got and .sdata.
+# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+# .bss section besides __bss_start.
+# DATA_PLT - .plt should be in data segment, not text segment.
+# TEXT_DYNAMIC - .dynamic in text segment, not data segment.
+# EMBEDDED - whether this is for an embedded system.
+# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set
+# start address of shared library.
+# INPUT_FILES - INPUT command of files to always include
+#
+# When adding sections, do note that the names of some sections are used
+# when specifying the start address of the next.
+#
+
+test -z "$ENTRY" && ENTRY=_start
+test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
+test -z "${ELFSIZE}" && ELFSIZE=32
+test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8"
+test "$LD_FLAG" = "N" && DATA_ADDR=.
+INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+PLT=".plt ${RELOCATING-0} : { *(.plt) }"
+DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }"
+
+CTOR=".ctors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+${CTOR_START}}
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+
+ KEEP (*crtbegin.o(.ctors))
+
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ ${CONSTRUCTING+${CTOR_END}}
+ }"
+
+DTOR=" .dtors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+${DTOR_START}}
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ ${CONSTRUCTING+${DTOR_END}}
+ }"
+
+# if this is for an embedded system, don't add SIZEOF_HEADERS.
+if [ -z "$EMBEDDED" ]; then
+ test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR} + SIZEOF_HEADERS"
+else
+ test -z "${TEXT_BASE_ADDRESS}" && TEXT_BASE_ADDRESS="${TEXT_START_ADDR}"
+fi
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${OUTPUT_ARCH})
+ENTRY(${ENTRY})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${RELOCATING+/* Do we need any of these for elf?
+ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
+${RELOCATING+${EXECUTABLE_SYMBOLS}}
+${RELOCATING+${INPUT_FILES}}
+${RELOCATING- /* For some reason, the Solaris linker makes bad executables
+ if gld -r is used and the intermediate file has sections starting
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
+ bug. But for now assigning the zero vmas works. */}
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_BASE_ADDRESS};}}
+ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB-${INTERP}}
+ ${INITIAL_READONLY_SECTIONS}
+ ${TEXT_DYNAMIC+${DYNAMIC}}
+ .hash ${RELOCATING-0} : { *(.hash) }
+ .dynsym ${RELOCATING-0} : { *(.dynsym) }
+ .dynstr ${RELOCATING-0} : { *(.dynstr) }
+ .gnu.version ${RELOCATING-0} : { *(.gnu.version) }
+ .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
+ .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
+ .rel.text ${RELOCATING-0} :
+ {
+ *(.rel.text)
+ ${RELOCATING+*(.rel.text.*)}
+ ${RELOCATING+*(.rel.gnu.linkonce.t*)}
+ }
+ .rela.text ${RELOCATING-0} :
+ {
+ *(.rela.text)
+ ${RELOCATING+*(.rela.text.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.t*)}
+ }
+ .rel.data ${RELOCATING-0} :
+ {
+ *(.rel.data)
+ ${RELOCATING+*(.rel.data.*)}
+ ${RELOCATING+*(.rel.gnu.linkonce.d*)}
+ }
+ .rela.data ${RELOCATING-0} :
+ {
+ *(.rela.data)
+ ${RELOCATING+*(.rela.data.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.d*)}
+ }
+ .rel.rodata ${RELOCATING-0} :
+ {
+ *(.rel.rodata)
+ ${RELOCATING+*(.rel.rodata.*)}
+ ${RELOCATING+*(.rel.gnu.linkonce.r*)}
+ }
+ .rela.rodata ${RELOCATING-0} :
+ {
+ *(.rela.rodata)
+ ${RELOCATING+*(.rela.rodata.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.r*)}
+ }
+ .rel.got ${RELOCATING-0} : { *(.rel.got) }
+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
+ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
+ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
+ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
+ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
+ .rel.init ${RELOCATING-0} : { *(.rel.init) }
+ .rela.init ${RELOCATING-0} : { *(.rela.init) }
+ .rel.fini ${RELOCATING-0} : { *(.rel.fini) }
+ .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
+ .rel.bss ${RELOCATING-0} : { *(.rel.bss) }
+ .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
+ .rel.plt ${RELOCATING-0} : { *(.rel.plt) }
+ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
+ .init ${RELOCATING-0} : { KEEP (*(.init)) } =${NOP-0}
+ ${DATA_PLT-${PLT}}
+ .text ${RELOCATING-0} :
+ {
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ *(.text)
+ ${RELOCATING+*(.text.*)}
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ ${RELOCATING+*(.gnu.linkonce.t*)}
+ ${RELOCATING+${OTHER_TEXT_SECTIONS}}
+ } =${NOP-0}
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+ .fini ${RELOCATING-0} : { KEEP (*(.fini)) } =${NOP-0}
+ .rodata ${RELOCATING-0} :
+ {
+ *(.rodata)
+ ${RELOCATING+*(.rodata.*)}
+ ${RELOCATING+*(.gnu.linkonce.r*)}
+ }
+ .rodata1 ${RELOCATING-0} : { *(.rodata1) }
+ ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ ${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};}}
+ ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};}}
+
+ .data ${RELOCATING-0} :
+ {
+ ${RELOCATING+${DATA_START_SYMBOLS}}
+ *(.data)
+ ${RELOCATING+*(.data.*)}
+ ${RELOCATING+*(.gnu.linkonce.d*)}
+ ${CONSTRUCTING+SORT(CONSTRUCTORS)}
+ }
+ .data1 ${RELOCATING-0} : { *(.data1) }
+ .eh_frame : { *(.eh_frame) }
+ .gcc_except_table : { *(.gcc_except_table) }
+ ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
+ ${RELOCATING+${CTOR}}
+ ${RELOCATING+${DTOR}}
+ ${DATA_PLT+${PLT}}
+ ${RELOCATING+${OTHER_GOT_SYMBOLS}}
+ .got ${RELOCATING-0} : { *(.got.plt) *(.got) }
+ ${TEXT_DYNAMIC-${DYNAMIC}}
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata ${RELOCATING-0} : { *(.sdata) *(.sdata.*) }
+ ${RELOCATING+${OTHER_GOT_SECTIONS}}
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+PROVIDE (edata = .);}
+ ${RELOCATING+__bss_start = .;}
+ ${RELOCATING+${OTHER_BSS_SYMBOLS}}
+ .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) }
+ .bss ${RELOCATING-0} :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+ }
+ ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+ ${RELOCATING+_end = . ;}
+ ${RELOCATING+${OTHER_BSS_END_SYMBOLS}}
+ ${RELOCATING+PROVIDE (end = .);}
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+
+ .comment 0 : { *(.comment) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ ${RELOCATING+${OTHER_RELOCATING_SECTIONS}}
+
+ /* These must appear regardless of ${RELOCATING}. */
+ ${OTHER_SECTIONS}
+}
+EOF
diff --git a/ld/scripttempl/elfd10v.sc b/ld/scripttempl/elfd10v.sc
new file mode 100644
index 00000000000..322eef49e29
--- /dev/null
+++ b/ld/scripttempl/elfd10v.sc
@@ -0,0 +1,226 @@
+#
+# Unusual variables checked by this code:
+# NOP - two byte opcode for no-op (defaults to 0)
+# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+# OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
+# (e.g., .PARISC.milli)
+# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
+# (e.g., .PARISC.global)
+# OTHER_SECTIONS - at the end
+# EXECUTABLE_SYMBOLS - symbols that must be defined for an
+# executable (e.g., _DYNAMIC_LINK)
+# TEXT_START_SYMBOLS - symbols that appear at the start of the
+# .text section.
+# DATA_START_SYMBOLS - symbols that appear at the start of the
+# .data section.
+# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+# .bss section besides __bss_start.
+# DATA_PLT - .plt should be in data segment, not text segment.
+# EMBEDDED - whether this is for an embedded system.
+#
+# When adding sections, do note that the names of some sections are used
+# when specifying the start address of the next.
+#
+test -z "$ENTRY" && ENTRY=_start
+test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
+test "$LD_FLAG" = "N" && DATA_ADDR=.
+INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+PLT=".plt ${RELOCATING-0} : { *(.plt) }"
+
+
+CTOR=".ctors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+${CTOR_START}}
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+
+ KEEP (*crtbegin.o(.ctors))
+
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ ${CONSTRUCTING+${CTOR_END}}
+ }"
+
+DTOR=" .dtors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+${DTOR_START}}
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ ${CONSTRUCTING+${DTOR_END}}
+ }"
+
+
+# if this is for an embedded system, don't add SIZEOF_HEADERS.
+if [ -z "$EMBEDDED" ]; then
+ test -z "${READONLY_BASE_ADDRESS}" && READONLY_BASE_ADDRESS="${READONLY_START_ADDR} + SIZEOF_HEADERS"
+else
+ test -z "${READONLY_BASE_ADDRESS}" && READONLY_BASE_ADDRESS="${READONLY_START_ADDR}"
+fi
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${OUTPUT_ARCH})
+ENTRY(${ENTRY})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${RELOCATING+/* Do we need any of these for elf?
+ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
+${RELOCATING+${EXECUTABLE_SYMBOLS}}
+${RELOCATING- /* For some reason, the Solaris linker makes bad executables
+ if gld -r is used and the intermediate file has sections starting
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
+ bug. But for now assigning the zero vmas works. */}
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ ${CREATE_SHLIB-${RELOCATING+. = ${READONLY_BASE_ADDRESS};}}
+ ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB-${INTERP}}
+ .hash ${RELOCATING-0} : { *(.hash) }
+ .dynsym ${RELOCATING-0} : { *(.dynsym) }
+ .dynstr ${RELOCATING-0} : { *(.dynstr) }
+ .rel.text ${RELOCATING-0} : { *(.rel.text) }
+ .rela.text ${RELOCATING-0} : { *(.rela.text) }
+ .rel.data ${RELOCATING-0} : { *(.rel.data) }
+ .rela.data ${RELOCATING-0} : { *(.rela.data) }
+ .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) }
+ .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) }
+ .rel.got ${RELOCATING-0} : { *(.rel.got) }
+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
+ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
+ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
+ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
+ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
+ .rel.init ${RELOCATING-0} : { *(.rel.init) }
+ .rela.init ${RELOCATING-0} : { *(.rela.init) }
+ .rel.fini ${RELOCATING-0} : { *(.rel.fini) }
+ .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
+ .rel.bss ${RELOCATING-0} : { *(.rel.bss) }
+ .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
+ .rel.plt ${RELOCATING-0} : { *(.rel.plt) }
+ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
+ ${DATA_PLT-${PLT}}
+ .rodata ${RELOCATING-0} : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 ${RELOCATING-0} : { *(.rodata1) }
+ ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+ /* Adjust the address for the data segment. */
+ ${RELOCATING+. = ${DATA_ADDR-ALIGN(4);}}
+
+ .data ${RELOCATING-0} :
+ {
+ ${RELOCATING+${DATA_START_SYMBOLS}}
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ }
+ .data1 ${RELOCATING-0} : { *(.data1) }
+ ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
+ ${RELOCATING+${CTOR}}
+ ${RELOCATING+${DTOR}}
+ .got ${RELOCATING-0} : { *(.got.plt) *(.got) }
+ .dynamic ${RELOCATING-0} : { *(.dynamic) }
+ ${DATA_PLT+${PLT}}
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata ${RELOCATING-0} : { *(.sdata) }
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+PROVIDE (edata = .);}
+ ${RELOCATING+__bss_start = .;}
+ ${RELOCATING+${OTHER_BSS_SYMBOLS}}
+ .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) }
+ .bss ${RELOCATING-0} :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ ${RELOCATING+_end = . ;}
+ ${RELOCATING+PROVIDE (end = .);}
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+
+ .comment 0 : { *(.comment) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ ${RELOCATING+${OTHER_RELOCATING_SECTIONS}}
+
+ /* These must appear regardless of ${RELOCATING}. */
+ ${OTHER_SECTIONS}
+
+
+ /* Hmmm, there's got to be a better way. This sets the stack to the
+ top of the simulator memory (i.e. top of 64K data space). */
+ .stack 0x00007FFE : { _stack = .; *(.stack) }
+
+ .text ${RELOCATING+${TEXT_START_ADDR}} :
+ {
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ KEEP (*(.init))
+ KEEP (*(.fini))
+ *(.text)
+ *(.text.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =${NOP-0}
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+}
+EOF
diff --git a/ld/scripttempl/elfd30v.sc b/ld/scripttempl/elfd30v.sc
new file mode 100644
index 00000000000..0ff928345be
--- /dev/null
+++ b/ld/scripttempl/elfd30v.sc
@@ -0,0 +1,219 @@
+
+CTOR=".ctors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+ __CTOR_LIST__ = .; }
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+
+ KEEP (*crtbegin.o(.ctors))
+
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ ${CONSTRUCTING+ __CTOR_END__ = .; }
+ } ${RELOCATING+ > ${DATA_MEMORY}}"
+
+DTOR=" .dtors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+ __DTOR_LIST__ = .; }
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ ${CONSTRUCTING+ __DTOR_END__ = .; }
+ } ${RELOCATING+ > ${DATA_MEMORY}}"
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+MEMORY
+{
+ text ${TEXT_DEF_SECTION} : ORIGIN = ${TEXT_START_ADDR}, LENGTH = ${TEXT_SIZE}
+ data ${DATA_DEF_SECTION} : ORIGIN = ${DATA_START_ADDR}, LENGTH = ${DATA_SIZE}
+ emem ${EMEM_DEF_SECTION} : ORIGIN = ${EMEM_START_ADDR}, LENGTH = ${EMEM_SIZE}
+ eit : ORIGIN = ${EIT_START_ADDR}, LENGTH = ${EIT_SIZE}
+}
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ ${TEXT_DYNAMIC+${DYNAMIC}}
+ .hash ${RELOCATING-0} : { *(.hash) }
+ .dynsym ${RELOCATING-0} : { *(.dynsym) }
+ .dynstr ${RELOCATING-0} : { *(.dynstr) }
+ .gnu.version ${RELOCATING-0} : { *(.gnu.version) }
+ .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
+ .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
+
+ .rela.text ${RELOCATING-0} : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rela.data ${RELOCATING-0} : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rela.stext ${RELOCATING-0} : { *(.rela.stest) }
+ .rela.etext ${RELOCATING-0} : { *(.rela.etest) }
+ .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) }
+ .rela.edata ${RELOCATING-0} : { *(.rela.edata) }
+ .rela.eit_v ${RELOCATING-0} : { *(.rela.eit_v) }
+ .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) }
+ .rela.ebss ${RELOCATING-0} : { *(.rela.ebss) }
+ .rela.srodata ${RELOCATING-0} : { *(.rela.srodata) }
+ .rela.erodata ${RELOCATING-0} : { *(.rela.erodata) }
+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
+ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
+ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
+ .rela.init ${RELOCATING-0} : { *(.rela.init) }
+ .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
+ .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
+ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
+
+ .rel.data ${RELOCATING-0} : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+ .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+ .rel.stext ${RELOCATING-0} : { *(.rel.stest) }
+ .rel.etext ${RELOCATING-0} : { *(.rel.etest) }
+ .rel.sdata ${RELOCATING-0} : { *(.rel.sdata) }
+ .rel.edata ${RELOCATING-0} : { *(.rel.edata) }
+ .rel.sbss ${RELOCATING-0} : { *(.rel.sbss) }
+ .rel.ebss ${RELOCATING-0} : { *(.rel.ebss) }
+ .rel.eit_v ${RELOCATING-0} : { *(.rel.eit_v) }
+ .rel.srodata ${RELOCATING-0} : { *(.rel.srodata) }
+ .rel.erodata ${RELOCATING-0} : { *(.rel.erodata) }
+ .rel.got ${RELOCATING-0} : { *(.rel.got) }
+ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
+ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
+ .rel.init ${RELOCATING-0} : { *(.rel.init) }
+ .rel.fini ${RELOCATING-0} : { *(.rel.fini) }
+ .rel.bss ${RELOCATING-0} : { *(.rel.bss) }
+ .rel.plt ${RELOCATING-0} : { *(.rel.plt) }
+
+ .init ${RELOCATING-0} : { *(.init) } =${NOP-0}
+ ${DATA_PLT-${PLT}}
+
+ /* Internal text space */
+ .stext ${RELOCATING-0} : { *(.stext) } ${RELOCATING+ > text}
+
+ /* Internal text space or external memory */
+ .text :
+ {
+ *(.text)
+ *(.gnu.linkonce.t*)
+ *(.init)
+ *(.fini)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ${TEXT_MEMORY}}
+
+ /* Internal data space */
+ .srodata ${RELOCATING-0} : { *(.srodata) } ${RELOCATING+ > data}
+ .sdata ${RELOCATING-0} : { *(.sdata) } ${RELOCATING+ > data}
+
+ /* Internal data space or external memory */
+ .rodata ${RELOCATING-0} : { *(.rodata) } ${RELOCATING+ > ${DATA_MEMORY}}
+
+ /* C++ exception support. */
+ .eh_frame ${RELOCATING-0} : { *(.eh_frame) } ${RELOCATING+ > ${DATA_MEMORY}}
+
+ ${RELOCATING+${CTOR}}
+ ${RELOCATING+${DTOR}}
+
+ .data ${RELOCATING-0} :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ${DATA_MEMORY}}
+
+ /* External memory */
+ .etext ${RELOCATING-0} :
+ {
+ ${RELOCATING+ PROVIDE (__etext_start = .) ; }
+ *(.etext)
+ ${RELOCATING+ PROVIDE (__etext_end = .) ; }
+ } ${RELOCATING+ > emem}
+
+ .erodata ${RELOCATING-0} : { *(.erodata) } ${RELOCATING+ > emem}
+ .edata ${RELOCATING-0} : { *(.edata) } ${RELOCATING+ > emem}
+
+ .sbss ${RELOCATING-0} :
+ {
+ ${RELOCATING+ PROVIDE (__sbss_start = .) ; }
+ *(.sbss)
+ ${RELOCATING+ PROVIDE (__sbss_end = .) ; }
+ } ${RELOCATING+ > data}
+
+ .ebss ${RELOCATING-0} :
+ {
+ ${RELOCATING+ PROVIDE (__ebss_start = .) ; }
+ *(.ebss)
+ ${RELOCATING+ PROVIDE (__ebss_end = .) ; }
+ } ${RELOCATING+ > data}
+
+ .bss ${RELOCATING-0} :
+ {
+ ${RELOCATING+ PROVIDE (__bss_start = .) ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ PROVIDE (__bss_end = .) ; }
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ > ${DATA_MEMORY}}
+
+ .eit_v ${RELOCATING-0} :
+ {
+ ${RELOCATING+ PROVIDE (__eit_start = .) ; }
+ *(.eit_v)
+ ${RELOCATING+ PROVIDE (__eit_end = .) ; }
+ } ${RELOCATING+ > eit}
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+
+ .comment 0 : { *(.comment) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ PROVIDE (__stack = ${STACK_START_ADDR});
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/elfppc.sc b/ld/scripttempl/elfppc.sc
new file mode 100644
index 00000000000..ddab8f80f81
--- /dev/null
+++ b/ld/scripttempl/elfppc.sc
@@ -0,0 +1,288 @@
+#
+# Unusual variables checked by this code:
+# NOP - two byte opcode for no-op (defaults to 0)
+# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+# OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
+# (e.g., .PARISC.milli)
+# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
+# (e.g., .PARISC.global)
+# OTHER_SECTIONS - at the end
+# EXECUTABLE_SYMBOLS - symbols that must be defined for an
+# executable (e.g., _DYNAMIC_LINK)
+# TEXT_START_SYMBOLS - symbols that appear at the start of the
+# .text section.
+# DATA_START_SYMBOLS - symbols that appear at the start of the
+# .data section.
+# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+# .bss section besides __bss_start.
+#
+# When adding sections, do note that the names of some sections are used
+# when specifying the start address of the next.
+#
+test -z "$ENTRY" && ENTRY=_start
+test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test "$LD_FLAG" = "N" && DATA_ADDR=.
+SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2) }"
+SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2) }"
+INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+PLT=".plt ${RELOCATING-0} : { *(.plt) }"
+CTOR=".ctors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+${CTOR_START}}
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+
+ KEEP (*crtbegin.o(.ctors))
+
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ ${CONSTRUCTING+${CTOR_END}}
+ }"
+
+DTOR=" .dtors ${CONSTRUCTING-0} :
+ {
+ ${CONSTRUCTING+${DTOR_START}}
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ ${CONSTRUCTING+${DTOR_END}}
+ }"
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+ENTRY(${ENTRY})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${RELOCATING+/* Do we need any of these for elf?
+ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
+${RELOCATING+${EXECUTABLE_SYMBOLS}}
+${RELOCATING- /* For some reason, the Solaris linker makes bad executables
+ if gld -r is used and the intermediate file has sections starting
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
+ bug. But for now assigning the zero vmas works. */}
+
+${RELOCATING+PROVIDE (__stack = 0);}
+${RELOCATING+PROVIDE (___stack = 0);}
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB-${INTERP}}
+ .hash ${RELOCATING-0} : { *(.hash) }
+ .dynsym ${RELOCATING-0} : { *(.dynsym) }
+ .dynstr ${RELOCATING-0} : { *(.dynstr) }
+ .gnu.version ${RELOCATING-0} : { *(.gnu.version) }
+ .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
+ .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
+ .rela.text ${RELOCATING-0} :
+ {
+ *(.rela.text)
+ ${RELOCATING+*(.rela.text.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.t*)}
+ }
+ .rela.data ${RELOCATING-0} :
+ {
+ *(.rela.data)
+ ${RELOCATING+*(.rela.data.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.d*)}
+ }
+ .rela.rodata ${RELOCATING-0} :
+ {
+ *(.rela.rodata)
+ ${RELOCATING+*(.rela.rodata.*)}
+ ${RELOCATING+*(.rela.gnu.linkonce.r*)}
+ }
+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
+ .rela.got1 ${RELOCATING-0} : { *(.rela.got1) }
+ .rela.got2 ${RELOCATING-0} : { *(.rela.got2) }
+ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
+ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
+ .rela.init ${RELOCATING-0} : { *(.rela.init) }
+ .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
+ .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
+ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
+ .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) }
+ .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) }
+ .rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2) }
+ .rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2) }
+ .text ${RELOCATING-0} :
+ {
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ *(.text)
+ ${RELOCATING+*(.text.*)}
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ ${RELOCATING+*(.gnu.linkonce.t*)}
+ } =${NOP-0}
+ .init ${RELOCATING-0} : { KEEP (*(.init)) } =${NOP-0}
+ .fini ${RELOCATING-0} : { KEEP (*(.fini)) } =${NOP-0}
+ .rodata ${RELOCATING-0} :
+ {
+ *(.rodata)
+ ${RELOCATING+*(.rodata.*)}
+ ${RELOCATING+*(.gnu.linkonce.r*)}
+ }
+ .rodata1 ${RELOCATING-0} : { *(.rodata1) }
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+ ${RELOCATING+PROVIDE (__etext = .);}
+ ${CREATE_SHLIB-${SDATA2}}
+ ${CREATE_SHLIB-${SBSS2}}
+ ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ ${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (ALIGN(8) & (${MAXPAGESIZE} - 1))};}
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
+
+ .data ${RELOCATING-0} :
+ {
+ ${RELOCATING+${DATA_START_SYMBOLS}}
+ *(.data)
+ ${RELOCATING+*(.data.*)}
+ ${RELOCATING+*(.gnu.linkonce.d*)}
+ ${CONSTRUCTING+CONSTRUCTORS}
+ }
+ .data1 ${RELOCATING-0} : { *(.data1) }
+ ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
+
+ .got1 ${RELOCATING-0} : { *(.got1) }
+ .dynamic ${RELOCATING-0} : { *(.dynamic) }
+
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+
+ ${RELOCATING+PROVIDE (_GOT2_START_ = .);}
+ ${RELOCATING+PROVIDE (__GOT2_START_ = .);}
+ .got2 ${RELOCATING-0} : { *(.got2) }
+
+ ${RELOCATING+PROVIDE (__CTOR_LIST__ = .);}
+ ${RELOCATING+PROVIDE (___CTOR_LIST__ = .);}
+ ${RELOCATING+${CTOR}}
+ ${RELOCATING+PROVIDE (__CTOR_END__ = .);}
+ ${RELOCATING+PROVIDE (___CTOR_END__ = .);}
+
+ ${RELOCATING+PROVIDE (__DTOR_LIST__ = .);}
+ ${RELOCATING+PROVIDE (___DTOR_LIST__ = .);}
+ ${RELOCATING+${DTOR}}
+ ${RELOCATING+PROVIDE (__DTOR_END__ = .);}
+ ${RELOCATING+PROVIDE (___DTOR_END__ = .);}
+
+ ${RELOCATING+PROVIDE (_FIXUP_START_ = .);}
+ ${RELOCATING+PROVIDE (__FIXUP_START_ = .);}
+ .fixup ${RELOCATING-0} : { *(.fixup) }
+ ${RELOCATING+PROVIDE (_FIXUP_END_ = .);}
+ ${RELOCATING+PROVIDE (__FIXUP_END_ = .);}
+ ${RELOCATING+PROVIDE (_GOT2_END_ = .);}
+ ${RELOCATING+PROVIDE (__GOT2_END_ = .);}
+
+ ${RELOCATING+PROVIDE (_GOT_START_ = .);}
+ ${RELOCATING+PROVIDE (__GOT_START_ = .);}
+ .got ${RELOCATING-0} : { *(.got) }
+ .got.plt ${RELOCATING-0} : { *(.got.plt) }
+ ${CREATE_SHLIB+${SDATA2}}
+ ${CREATE_SHLIB+${SBSS2}}
+ ${RELOCATING+PROVIDE (_GOT_END_ = .);}
+ ${RELOCATING+PROVIDE (__GOT_END_ = .);}
+
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata ${RELOCATING-0} : { *(.sdata) }
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+PROVIDE (edata = .);}
+ ${RELOCATING+PROVIDE (__edata = .);}
+ .sbss ${RELOCATING-0} :
+ {
+ ${RELOCATING+PROVIDE (__sbss_start = .);}
+ ${RELOCATING+PROVIDE (___sbss_start = .);}
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+ ${RELOCATING+PROVIDE (__sbss_end = .);}
+ ${RELOCATING+PROVIDE (___sbss_end = .);}
+ }
+ ${PLT}
+ .bss ${RELOCATING-0} :
+ {
+ ${RELOCATING+${OTHER_BSS_SYMBOLS}}
+ ${RELOCATING+PROVIDE (__bss_start = .);}
+ ${RELOCATING+PROVIDE (___bss_start = .);}
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ ${RELOCATING+_end = . ;}
+ ${RELOCATING+PROVIDE (end = .);}
+ ${RELOCATING+PROVIDE (__end = .);}
+
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /* These must appear regardless of ${RELOCATING}. */
+ ${OTHER_SECTIONS}
+}
+EOF
diff --git a/ld/scripttempl/go32coff.sc b/ld/scripttempl/go32coff.sc
new file mode 100644
index 00000000000..40f6076345a
--- /dev/null
+++ b/ld/scripttempl/go32coff.sc
@@ -0,0 +1,33 @@
+# Linker script for 386 go32
+# DJ Delorie (dj@ctron.com)
+
+test -z "$ENTRY" && ENTRY=start
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ 0x1000+SIZEOF_HEADERS} : {
+ *(.text)
+ ${RELOCATING+ etext = . ; _etext = .};
+ ${RELOCATING+ . = ALIGN(0x200);}
+ }
+ .data ${RELOCATING+ ${DATA_ALIGNMENT}} : {
+ ${RELOCATING+ *(.ctor)}
+ ${RELOCATING+ *(.dtor)}
+ *(.data)
+ ${RELOCATING+ edata = . ; _edata = .};
+ ${RELOCATING+ . = ALIGN(0x200);}
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = . ; _end = .};
+ ${RELOCATING+ . = ALIGN(0x200);}
+ }
+}
+EOF
diff --git a/ld/scripttempl/h8300.sc b/ld/scripttempl/h8300.sc
new file mode 100644
index 00000000000..f2f876e2835
--- /dev/null
+++ b/ld/scripttempl/h8300.sc
@@ -0,0 +1,69 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+ENTRY("_start")
+
+MEMORY
+{
+ /* 0xc4 is a magic entry. We should have the linker just
+ skip over it one day... */
+ vectors : o = 0x0000, l = 0xc4
+ magicvectors : o = 0xc4, l = 0x3c
+ ram : o = 0x0100, l = 0xfdfc
+ /* The stack starts at the top of main ram. */
+ topram : o = 0xfefc, l = 0x4
+ /* At the very to of the address space is the 8-bit area. */
+ eight : o = 0xff00, l = 0x100
+}
+
+SECTIONS
+{
+.vectors : {
+ /* Use something like this to place a specific function's address
+ into the vector table.
+
+ SHORT(ABSOLUTE(_foobar)) */
+
+ *(.vectors)
+ } ${RELOCATING+ > vectors}
+
+.text : {
+ *(.rodata)
+ *(.text)
+ *(.strings)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ram}
+.tors : {
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+ } ${RELOCATING+ > ram}
+.data : {
+ *(.data)
+ *(.tiny)
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ram}
+.bss : {
+ ${RELOCATING+ _bss_start = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ >ram}
+.stack : {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ } ${RELOCATING+ > topram}
+.eight : {
+ *(.eight)
+ } ${RELOCATING+ > eight}
+.stab 0 ${RELOCATING+(NOLOAD)} : {
+ [ .stab ]
+ }
+.stabstr 0 ${RELOCATING+(NOLOAD)} : {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/h8300h.sc b/ld/scripttempl/h8300h.sc
new file mode 100644
index 00000000000..d1cfd860b65
--- /dev/null
+++ b/ld/scripttempl/h8300h.sc
@@ -0,0 +1,76 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(h8300h)
+ENTRY("_start")
+
+/* The memory size is 256KB to coincide with the simulator.
+ Don't change either without considering the other. */
+
+MEMORY
+{
+ /* 0xc4 is a magic entry. We should have the linker just
+ skip over it one day... */
+ vectors : o = 0x0000, l = 0xc4
+ magicvectors : o = 0xc4, l = 0x3c
+ /* We still only use 256k as the main ram size. */
+ ram : o = 0x0100, l = 0x3fefc
+ /* The stack starts at the top of main ram. */
+ topram : o = 0x3fffc, l = 0x4
+ /* This holds variables in the "tiny" sections. */
+ tiny : o = 0xff8000, l = 0x7f00
+ /* At the very top of the address space is the 8-bit area. */
+ eight : o = 0xffff00, l = 0x100
+}
+
+SECTIONS
+{
+.vectors : {
+ /* Use something like this to place a specific function's address
+ into the vector table.
+
+ LONG(ABSOLUTE(_foobar)) */
+
+ *(.vectors)
+ } ${RELOCATING+ > vectors}
+.text : {
+ *(.rodata)
+ *(.text)
+ *(.strings)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ram}
+.tors : {
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+ } ${RELOCATING+ > ram}
+.data : {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ram}
+.bss : {
+ ${RELOCATING+ _bss_start = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ >ram}
+.stack : {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ } ${RELOCATING+ > topram}
+.tiny : {
+ *(.tiny)
+ } ${RELOCATING+ > tiny}
+.eight : {
+ *(.eight)
+ } ${RELOCATING+ > eight}
+.stab 0 ${RELOCATING+(NOLOAD)} : {
+ [ .stab ]
+ }
+.stabstr 0 ${RELOCATING+(NOLOAD)} : {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/h8300s.sc b/ld/scripttempl/h8300s.sc
new file mode 100644
index 00000000000..45474fc51ce
--- /dev/null
+++ b/ld/scripttempl/h8300s.sc
@@ -0,0 +1,76 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(h8300s)
+ENTRY("_start")
+
+/* The memory size is 256KB to coincide with the simulator.
+ Don't change either without considering the other. */
+
+MEMORY
+{
+ /* 0xc4 is a magic entry. We should have the linker just
+ skip over it one day... */
+ vectors : o = 0x0000, l = 0xc4
+ magicvectors : o = 0xc4, l = 0x3c
+ /* We still only use 256k as the main ram size. */
+ ram : o = 0x0100, l = 0x3fefc
+ /* The stack starts at the top of main ram. */
+ topram : o = 0x3fffc, l = 0x4
+ /* This holds variables in the "tiny" sections. */
+ tiny : o = 0xff8000, l = 0x7f00
+ /* At the very top of the address space is the 8-bit area. */
+ eight : o = 0xffff00, l = 0x100
+}
+
+SECTIONS
+{
+.vectors : {
+ /* Use something like this to place a specific function's address
+ into the vector table.
+
+ LONG(ABSOLUTE(_foobar)) */
+
+ *(.vectors)
+ } ${RELOCATING+ > vectors}
+.text : {
+ *(.rodata)
+ *(.text)
+ *(.strings)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ram}
+.tors : {
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+ } ${RELOCATING+ > ram}
+.data : {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ram}
+.bss : {
+ ${RELOCATING+ _bss_start = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ >ram}
+.stack : {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ } ${RELOCATING+ > topram}
+.tiny : {
+ *(.tiny)
+ } ${RELOCATING+ > tiny}
+.eight : {
+ *(.eight)
+ } ${RELOCATING+ > eight}
+.stab 0 ${RELOCATING+(NOLOAD)} : {
+ [ .stab ]
+ }
+.stabstr 0 ${RELOCATING+(NOLOAD)} : {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/h8500.sc b/ld/scripttempl/h8500.sc
new file mode 100644
index 00000000000..d6a39eec38c
--- /dev/null
+++ b/ld/scripttempl/h8500.sc
@@ -0,0 +1,62 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+/* Code and data 64k total */
+
+SECTIONS
+{
+.text ${RELOCATING+ 0x0000 } :
+ {
+ *(.text)
+
+ ${RELOCATING+ _etext = . ; }
+ }
+
+
+.data ${RELOCATING+ . } :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ }
+
+.rdata ${RELOCATING+ . } :
+ {
+ *(.rdata);
+ *(.strings)
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+}
+
+.bss ${RELOCATING+ . } :
+ {
+ ${RELOCATING+ __start_bss = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ }
+
+.stack ${RELOCATING+ 0xfff0} :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ }
+
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/h8500b.sc b/ld/scripttempl/h8500b.sc
new file mode 100644
index 00000000000..ef5fa2c488a
--- /dev/null
+++ b/ld/scripttempl/h8500b.sc
@@ -0,0 +1,62 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+/* Code and data, both larger than 64k */
+
+SECTIONS
+{
+.text ${RELOCATING+ 0x10000} :
+ {
+ *(.text)
+
+ ${RELOCATING+ _etext = . ; }
+ }
+
+
+.data ${RELOCATING+ 0x20000} :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ }
+
+.rdata ${RELOCATING+ 0x30000} :
+ {
+ *(.rdata);
+ *(.strings)
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+}
+
+.bss ${RELOCATING+ 0x40000} :
+ {
+ ${RELOCATING+ __start_bss = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ }
+
+.stack ${RELOCATING+ 0x50000} :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ }
+
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/h8500c.sc b/ld/scripttempl/h8500c.sc
new file mode 100644
index 00000000000..03880e3f068
--- /dev/null
+++ b/ld/scripttempl/h8500c.sc
@@ -0,0 +1,59 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+/* Compact model - code < 64k, data > 64k */
+
+SECTIONS
+{
+.text 0x10000 :
+ {
+ *(.text)
+ *(.strings)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ram}
+
+
+.data 0x20000 :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ram}
+
+.rdata 0x30000 : {
+ *(.rdata);
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+} ${RELOCATING+ > ram}
+
+.bss 0x40000 :
+ {
+ ${RELOCATING+ __start_bss = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ >ram}
+.stack 0x5fff0 :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ } ${RELOCATING+ > topram}
+
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/h8500m.sc b/ld/scripttempl/h8500m.sc
new file mode 100644
index 00000000000..040a4a7c637
--- /dev/null
+++ b/ld/scripttempl/h8500m.sc
@@ -0,0 +1,61 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+/* Code and data, both larger than 64k */
+
+SECTIONS
+{
+.text ${RELOCATING+ 0x10000} :
+ {
+ *(.text)
+ ${RELOCATING+ _etext = . ; }
+ }
+
+
+.data ${RELOCATING+ 0x20000} :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ }
+
+.rdata ${RELOCATING+ . } :
+ {
+ *(.rdata);
+ *(.strings)
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+ }
+
+.bss ${RELOCATING+ . } :
+ {
+ ${RELOCATING+ __start_bss = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ }
+
+.stack ${RELOCATING+ 0x2fff0} :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ }
+
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/h8500s.sc b/ld/scripttempl/h8500s.sc
new file mode 100644
index 00000000000..11615d8afe9
--- /dev/null
+++ b/ld/scripttempl/h8500s.sc
@@ -0,0 +1,60 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+/* Code and data, both 64k */
+
+SECTIONS
+{
+.text ${RELOCATING+ 0x10000 } :
+ {
+ *(.text)
+ ${RELOCATING+ _etext = . ; }
+ }
+
+.rdata ${RELOCATING+ 0x20000 } :
+ {
+ *(.rdata);
+ *(.strings)
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+ }
+
+.data ${RELOCATING+ . } :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ }
+
+.bss ${RELOCATING+ .} :
+ {
+ ${RELOCATING+ __start_bss = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ }
+
+.stack ${RELOCATING+ 0x2fff0} :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ }
+
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/hppaelf.sc b/ld/scripttempl/hppaelf.sc
new file mode 100644
index 00000000000..941ce08998c
--- /dev/null
+++ b/ld/scripttempl/hppaelf.sc
@@ -0,0 +1,38 @@
+DATA_ADDR=0x40000000
+test "$LD_FLAG" = "N" && DATA_ADDR=.
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+ENTRY("\$START\$")
+${RELOCATING+${LIB_SEARCH_DIRS}}
+SECTIONS
+{
+ .text 0x1000 ${RELOCATING++${TEXT_START_ADDR}}:
+ {
+ ${RELOCATING+__text_start = .};
+ CREATE_OBJECT_SYMBOLS
+ *(.PARISC.stubs)
+ *(.text)
+ ${RELOCATING+etext = .};
+ ${RELOCATING+_etext = .};
+ }
+ ${RELOCATING+. = ${DATA_ADDR};}
+ .data :
+ {
+ ${RELOCATING+ . = . + 0x1000 };
+ ${RELOCATING+__data_start = .};
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+edata = .};
+ ${RELOCATING+_edata = .};
+ }
+ ${RELOCATING+. = ${DATA_ADDR} + SIZEOF(.data);}
+ .bss :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+end = . };
+ ${RELOCATING+_end = . };
+ }
+}
+EOF
diff --git a/ld/scripttempl/i386beos.sc b/ld/scripttempl/i386beos.sc
new file mode 100644
index 00000000000..83ffde16407
--- /dev/null
+++ b/ld/scripttempl/i386beos.sc
@@ -0,0 +1,194 @@
+# Linker script for PE.
+
+if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then
+ RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+fi
+
+# We can't easily and portably get an unquoted $ in a shell
+# substitution, so we do this instead.
+if test "${RELOCATING}"; then
+ R_TEXT='*(.text$*)'
+ R_DATA='*(.data$*)'
+ R_RDATA='*(.rdata$*)'
+ R_IDATA='
+ *(.idata$2)
+ *(.idata$3)
+ /* These zeroes mark the end of the import list. */
+ LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
+ *(.idata$4)
+ *(.idata$5)
+ *(.idata$6)
+ *(.idata$7)'
+ R_CRT='*(.CRT$*)'
+ R_RSRC='*(.rsrc$*)'
+ R_EXC='*(.exc$*)'
+else
+ R_TEXT=
+ R_DATA=
+ R_RDATA=
+ R_IDATA=
+ R_CRT=
+ R_RSRC=
+ R_EXC=
+fi
+
+cat <<EOF
+${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})}
+${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})}
+
+${LIB_SEARCH_DIRS}
+
+ENTRY(__start)
+${RELOCATING+header = .;}
+${RELOCATING+__fltused = .; /* set up floating pt for MS .obj\'s */}
+${RELOCATING+__ldused = .;}
+SECTIONS
+{
+ .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
+ {
+ ${RELOCATING+ __text_start__ = . ;}
+ ${RELOCATING+ *(.init)}
+ *(.text)
+ ${R_TEXT}
+ *(.glue_7t)
+ *(.glue_7)
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1); *(.ctors); *(.ctor); LONG (0); }
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); LONG (0); }
+ ${RELOCATING+ *(.fini)}
+ /* ??? Why is .gcc_exc here? */
+ ${RELOCATING+ *(.gcc_exc)}
+ ${RELOCATING+ etext = .;}
+ ${RELOCATING+ __text_end__ = .;}
+ *(.gcc_except_table)
+ }
+
+ /* The Cygwin32 library uses a section to avoid copying certain data
+ on fork. This used to be named ".data$nocopy". The linker used
+ to include this between __data_start__ and __data_end__, but that
+ breaks building the cygwin32 dll. Instead, we name the section
+ ".data_cygwin_nocopy" and explictly include it after __data_end__. */
+
+ .data ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__data_start__ = . ;}
+ *(.data)
+ *(.data2)
+ ${R_DATA}
+ ${RELOCATING+__data_end__ = . ;}
+ ${RELOCATING+*(.data_cygwin_nocopy)}
+ }
+
+ .bss ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__bss_start__ = . ;}
+ *(.bss)
+ *(COMMON)
+ /* link.exe apparently pulls in .obj's because of UNDEF common
+ symbols, which is not the coff way, but that's MS for you. */
+ *(.CRT\$XCA)
+ *(.CRT\$XCZ)
+ *(.CRT\$XIA)
+ *(.CRT\$XIZ)
+ ${RELOCATING+__bss_end__ = . ;}
+ }
+
+ .rdata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rdata)
+ ${R_RDATA}
+ *(.eh_frame)
+ }
+
+ .edata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.edata)
+ }
+
+ /DISCARD/ :
+ {
+ *(.debug\$S)
+ *(.debug\$T)
+ *(.debug\$F)
+ *(.drectve)
+ *(.debug*)
+ }
+
+ .idata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pe.em:sort_sections. */
+ ${R_IDATA}
+ }
+ .CRT ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${R_CRT}
+ }
+
+ .endjunk ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* end is deprecated, don't use it */
+ ${RELOCATING+ end = .;}
+ ${RELOCATING+ _end = .;}
+ ${RELOCATING+ __end__ = .;}
+ }
+
+ .reloc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.reloc)
+ }
+
+ .rsrc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rsrc)
+ ${R_RSRC}
+ }
+
+ .exc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.exc)
+ ${R_EXC}
+ }
+
+ .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+
+ .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 ${RELOCATING+(NOLOAD)} : { *(.debug) }
+ .line 0 ${RELOCATING+(NOLOAD)} : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 ${RELOCATING+(NOLOAD)} : { *(.debug_srcinfo) }
+ .debug_sfnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 ${RELOCATING+(NOLOAD)} : { *(.debug_aranges) }
+ .debug_pubnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 ${RELOCATING+(NOLOAD)} : { *(.debug_info) }
+ .debug_abbrev 0 ${RELOCATING+(NOLOAD)} : { *(.debug_abbrev) }
+ .debug_line 0 ${RELOCATING+(NOLOAD)} : { *(.debug_line) }
+ .debug_frame 0 ${RELOCATING+(NOLOAD)} : { *(.debug_frame) }
+ .debug_str 0 ${RELOCATING+(NOLOAD)} : { *(.debug_str) }
+ .debug_loc 0 ${RELOCATING+(NOLOAD)} : { *(.debug_loc) }
+ .debug_macinfo 0 ${RELOCATING+(NOLOAD)} : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_weaknames) }
+ .debug_funcnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_funcnames) }
+ .debug_typenames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_typenames) }
+ .debug_varnames 0 ${RELOCATING+(NOLOAD)} : { *(.debug_varnames) }
+}
+EOF
diff --git a/ld/scripttempl/i386coff.sc b/ld/scripttempl/i386coff.sc
new file mode 100644
index 00000000000..fbb1b7918c7
--- /dev/null
+++ b/ld/scripttempl/i386coff.sc
@@ -0,0 +1,43 @@
+# Linker script for 386 COFF. This works on SVR3.2 and SCO Unix 3.2.2.
+# Ian Taylor <ian@cygnus.com>.
+test -z "$ENTRY" && ENTRY=_start
+# These are substituted in as variables in order to get '}' in a shell
+# conditional expansion.
+INIT='.init : { *(.init) }'
+FINI='.fini : { *(.fini) }'
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ SIZEOF_HEADERS} : {
+ ${RELOCATING+ *(.init)}
+ *(.text)
+ ${RELOCATING+ *(.fini)}
+ ${RELOCATING+ etext = .};
+ }
+ .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : {
+ *(.data)
+ ${RELOCATING+ edata = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = .};
+ }
+ ${RELOCATING- ${INIT}}
+ ${RELOCATING- ${FINI}}
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/i386go32.sc b/ld/scripttempl/i386go32.sc
new file mode 100644
index 00000000000..6bd3d09ff57
--- /dev/null
+++ b/ld/scripttempl/i386go32.sc
@@ -0,0 +1,46 @@
+# Linker script for i386 go32 (DJGPP)
+
+test -z "$ENTRY" && ENTRY=start
+EXE=${CONSTRUCTING+${RELOCATING+-exe}}
+
+# These are substituted in as variables in order to get '}' in a shell
+# conditional expansion.
+CTOR='.ctor : { *(.ctor) }'
+DTOR='.dtor : { *(.dtor) }'
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}${EXE}")
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ ${TARGET_PAGE_SIZE}+SIZEOF_HEADERS} : {
+ *(.text)
+ *(.const*)
+ *(.ro*)
+ ${RELOCATING+etext = . ; _etext = .};
+ ${RELOCATING+. = ALIGN(${SEGMENT_SIZE});}
+ }
+ .data ${RELOCATING+ ${DATA_ALIGNMENT}} : {
+ ${RELOCATING+djgpp_first_ctor = . ;
+ *(.ctor)
+ djgpp_last_ctor = . ;}
+ ${RELOCATING+djgpp_first_dtor = . ;
+ *(.dtor)
+ djgpp_last_dtor = . ;}
+ *(.data)
+ ${RELOCATING+ edata = . ; _edata = .};
+ ${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});}
+ }
+ ${CONSTRUCTING+${RELOCATING-$CTOR}}
+ ${CONSTRUCTING+${RELOCATING-$DTOR}}
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = . ; _end = .};
+ ${RELOCATING+ . = ALIGN(${SEGMENT_SIZE});}
+ }
+}
+EOF
diff --git a/ld/scripttempl/i386lynx.sc b/ld/scripttempl/i386lynx.sc
new file mode 100644
index 00000000000..16b72a43c75
--- /dev/null
+++ b/ld/scripttempl/i386lynx.sc
@@ -0,0 +1,46 @@
+test -z "$ENTRY" && ENTRY=_start
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ SIZEOF_HEADERS} : {
+ *(.init)
+ *(.text)
+ ${RELOCATING+ etext = .;}
+ ${CONSTRUCTING+ __CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __CTOR_END__ = .;}
+ ${CONSTRUCTING+ __DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __DTOR_END__ = .;}
+ *(.fini)
+ ${RELOCATING+ etext = .};
+ }
+ .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : {
+ *(.data)
+ ${RELOCATING+ edata = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = .};
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/i386msdos.sc b/ld/scripttempl/i386msdos.sc
new file mode 100644
index 00000000000..4d312e7ff92
--- /dev/null
+++ b/ld/scripttempl/i386msdos.sc
@@ -0,0 +1,38 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${STACKZERO+${RELOCATING+${STACKZERO}}}
+SECTIONS
+{
+ ${RELOCATING+. = ${TEXT_START_ADDR};}
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ ${RELOCATING+etext = .;}
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+__etext = .;}
+ }
+ .data :
+ {
+ *(.rodata)
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+edata = .;}
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+__edata = .;}
+ }
+ .bss :
+ {
+ ${RELOCATING+ _bss_start = .};
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+end = ALIGN(4) };
+ ${RELOCATING+_end = ALIGN(4) };
+ ${RELOCATING+__end = ALIGN(4) };
+ }
+}
+EOF
diff --git a/ld/scripttempl/i960.sc b/ld/scripttempl/i960.sc
new file mode 100644
index 00000000000..dc335555d7d
--- /dev/null
+++ b/ld/scripttempl/i960.sc
@@ -0,0 +1,25 @@
+cat <<EOF
+SECTIONS
+{
+ .text :
+ {
+ ${GLD_STYLE+ CREATE_OBJECT_SYMBOLS}
+ *(.text)
+ ${RELOCATING+ _etext = .};
+ ${CONSTRUCTING+${COFF_CTORS}}
+ }
+ .data :
+ {
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+ _edata = .};
+ }
+ .bss :
+ {
+ ${RELOCATING+ _bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = .};
+ }
+}
+EOF
diff --git a/ld/scripttempl/m68kaux.sc b/ld/scripttempl/m68kaux.sc
new file mode 100644
index 00000000000..404280e1272
--- /dev/null
+++ b/ld/scripttempl/m68kaux.sc
@@ -0,0 +1,46 @@
+# Linker script for A/UX.
+test -z "$ENTRY" && ENTRY=_start
+INIT='.init : { *(.init) }'
+FINI='.fini : { *(.fini) }'
+CTORS='.ctors : { *(.ctors) }'
+DTORS='.dtors : { *(.dtors) }'
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ $TEXT_START_ADDR} : {
+ ${RELOCATING+ *(.init)}
+ ${RELOCATING+ *(.fini)}
+ *(.text)
+ ${RELOCATING+ . = ALIGN(4);}
+ ${RELOCATING+ *(.ctors)}
+ ${RELOCATING+ *(.dtors)}
+ ${RELOCATING+ etext = .;}
+ ${RELOCATING+ _etext = .;}
+ } =0x4E714E71
+ .data ${RELOCATING+ $DATA_ALIGNMENT} : {
+ *(.data)
+ ${RELOCATING+ edata = .;}
+ ${RELOCATING+ _edata = .;}
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = .;}
+ ${RELOCATING+ _end = .;}
+ }
+ ${RELOCATING- ${INIT}}
+ ${RELOCATING- ${FINI}}
+ ${RELOCATING- ${CTORS}}
+ ${RELOCATING- ${DTORS}}
+
+ .comment 0 ${RELOCATING+(NOLOAD)} : { [ .comment ] [ .ident ] }
+ .stab 0 ${RELOCATING+(NOLOAD)} : { [ .stab ] }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} : { [ .stabstr ] }
+}
+EOF
diff --git a/ld/scripttempl/m68kcoff.sc b/ld/scripttempl/m68kcoff.sc
new file mode 100644
index 00000000000..f268c6f9060
--- /dev/null
+++ b/ld/scripttempl/m68kcoff.sc
@@ -0,0 +1,42 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+PROVIDE (__stack = 0);
+SECTIONS
+{
+ .text ${RELOCATING+ 0x1000000} : {
+ *(.text)
+ ${CONSTRUCTING+ . = ALIGN(4);}
+ ${RELOCATING+ etext = .;}
+ ${CONSTRUCTING+ __CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __CTOR_END__ = .;}
+ ${CONSTRUCTING+ __DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __DTOR_END__ = .;}
+ }
+ .data : {
+ *(.data)
+ ${RELOCATING+ edata = .};
+ }
+ .bss : {
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = ALIGN(0x8)};
+ ${RELOCATING+ _end = ALIGN(0x8)};
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/m68klynx.sc b/ld/scripttempl/m68klynx.sc
new file mode 100644
index 00000000000..81d2245885a
--- /dev/null
+++ b/ld/scripttempl/m68klynx.sc
@@ -0,0 +1,46 @@
+test -z "$ENTRY" && ENTRY=_start
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ SIZEOF_HEADERS} : {
+ *(.init)
+ *(.text)
+ ${RELOCATING+ etext = .;}
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___CTOR_END__ = .;}
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___DTOR_END__ = .;}
+ *(.fini)
+ ${RELOCATING+ etext = .};
+ }
+ .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : {
+ *(.data .data2)
+ ${RELOCATING+ edata = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = .};
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/m88kbcs.sc b/ld/scripttempl/m88kbcs.sc
new file mode 100644
index 00000000000..f52b14dc0ce
--- /dev/null
+++ b/ld/scripttempl/m88kbcs.sc
@@ -0,0 +1,49 @@
+# These are substituted in as variables in order to get '}' in a shell
+# conditional expansion.
+INIT='.init : { *(.init) }'
+FINI='.fini : { *(.fini) }'
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+ENTRY(__start)
+${RELOCATING+${LIB_SEARCH_DIRS}}
+
+SECTIONS
+{
+ .text ${RELOCATING+ (0x20007 + SIZEOF_HEADERS) &~ 7} :
+ {
+ ${RELOCATING+ __.text.start = .};
+ ${RELOCATING+ __.init.start = .};
+ ${RELOCATING+ *(.init)}
+ ${RELOCATING+ __.init.end = .};
+ *(.text)
+ ${RELOCATING+ __.tdesc_start = .};
+ ${RELOCATING+ *(.tdesc)}
+ ${RELOCATING+ __.text_end = .} ;
+ ${RELOCATING+ __.initp.start = .};
+ ${RELOCATING+ __.initp.end = .};
+ ${RELOCATING+ __.fini_start = .};
+ ${RELOCATING+ *(.fini) }
+ ${RELOCATING+ __.fini_end = .};
+ ${RELOCATING+_etext = .};
+ }
+ .data ${RELOCATING+ NEXT (0x400000) + ((SIZEOF(.text) + ADDR(.text)) % 0x2000)} :
+ {
+ *(.data)
+ ${RELOCATING+_edata = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = .};
+ ${RELOCATING+ __end = .};
+ }
+ ${RELOCATING- ${INIT}}
+ ${RELOCATING- ${FINI}}
+ .comment 0 ${RELOCATING+(NOLOAD)} :
+ {
+ *(.comment)
+ }
+}
+EOF
diff --git a/ld/scripttempl/mcorepe.sc b/ld/scripttempl/mcorepe.sc
new file mode 100644
index 00000000000..8111bf211ee
--- /dev/null
+++ b/ld/scripttempl/mcorepe.sc
@@ -0,0 +1,156 @@
+# Linker script for PE.
+
+if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then
+ RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+fi
+
+# We can't easily and portably get an unquoted $ in a shell
+# substitution, so we do this instead.
+# Sorting of the .foo$* sections is required by the definition of
+# grouped sections in PE.
+# Sorting of the file names in R_IDATA is required by the
+# current implementation of dlltool (this could probably be changed to
+# use grouped sections instead).
+if test "${RELOCATING}"; then
+ R_TEXT='*(SORT(.text$*))'
+ R_DATA='*(SORT(.data$*))'
+ R_RDATA='*(SORT(.rdata$*))'
+ R_IDATA='
+ SORT(*)(.idata$2)
+ SORT(*)(.idata$3)
+ /* These zeroes mark the end of the import list. */
+ LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
+ SORT(*)(.idata$4)
+ SORT(*)(.idata$5)
+ SORT(*)(.idata$6)
+ SORT(*)(.idata$7)'
+ R_CRT='*(SORT(.CRT$*))'
+ R_RSRC='*(SORT(.rsrc$*))'
+else
+ R_TEXT=
+ R_DATA=
+ R_RDATA=
+ R_IDATA=
+ R_CRT=
+ R_RSRC=
+fi
+
+cat <<EOF
+${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})}
+${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})}
+
+${LIB_SEARCH_DIRS}
+
+ENTRY(_mainCRTStartup)
+
+SECTIONS
+{
+ .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
+ {
+ ${RELOCATING+ *(.init)}
+ *(.text)
+ ${R_TEXT}
+ *(.glue_7t)
+ *(.glue_7)
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1); *(.ctors); *(.ctor); LONG (0); }
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); LONG (0); }
+ ${RELOCATING+ *(.fini)}
+ /* ??? Why is .gcc_exc here? */
+ ${RELOCATING+ *(.gcc_exc)}
+ ${RELOCATING+ etext = .;}
+ *(.gcc_except_table)
+ }
+
+ /* The Cygwin32 library uses a section to avoid copying certain data
+ on fork. This used to be named ".data$nocopy". The linker used
+ to include this between __data_start__ and __data_end__, but that
+ breaks building the cygwin32 dll. Instead, we name the section
+ ".data_cygwin_nocopy" and explictly include it after __data_end__. */
+
+ .data ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__data_start__ = . ;}
+ *(.data)
+ *(.data2)
+ ${R_DATA}
+ ${RELOCATING+__data_end__ = . ;}
+ ${RELOCATING+*(.data_cygwin_nocopy)}
+ }
+
+ .bss ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__bss_start__ = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+__bss_end__ = . ;}
+ }
+
+ .rdata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rdata)
+ ${R_RDATA}
+ *(.eh_frame)
+ }
+
+ .edata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.edata)
+ }
+
+ /DISCARD/ :
+ {
+ *(.debug\$S)
+ *(.debug\$T)
+ *(.debug\$F)
+ *(.drectve)
+ }
+
+ .idata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pe.em:sort_sections. */
+ ${R_IDATA}
+ }
+ .CRT ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${R_CRT}
+ }
+
+ .endjunk ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* end is deprecated, don't use it */
+ ${RELOCATING+ end = .;}
+ ${RELOCATING+ _end = .;}
+ ${RELOCATING+ __end__ = .;}
+ }
+
+ .reloc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.reloc)
+ }
+
+ .rsrc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rsrc)
+ ${R_RSRC}
+ }
+
+ .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+
+ .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+
+ .stack 0x80000 :
+ {
+ _stack = .;
+ *(.stack)
+ }
+}
+EOF
diff --git a/ld/scripttempl/mips.sc b/ld/scripttempl/mips.sc
new file mode 100644
index 00000000000..d60aeedfeeb
--- /dev/null
+++ b/ld/scripttempl/mips.sc
@@ -0,0 +1,72 @@
+# Linker script for MIPS systems.
+# Ian Lance Taylor <ian@cygnus.com>.
+# These variables may be overridden by the emulation file. The
+# defaults are appropriate for a DECstation running Ultrix.
+test -z "$ENTRY" && ENTRY=__start
+
+if [ -z "$EMBEDDED" ]; then
+ test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x400000 + SIZEOF_HEADERS"
+else
+ test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x400000"
+fi
+if test "x$LD_FLAG" = "xn" -o "x$LD_FLAG" = "xN"; then
+ DATA_ADDR=.
+else
+ test -z "$DATA_ADDR" && DATA_ADDR=0x10000000
+fi
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ ${RELOCATING+. = ${TEXT_START_ADDR};}
+ .text : {
+ ${RELOCATING+ _ftext = . };
+ *(.init)
+ ${RELOCATING+ eprol = .};
+ *(.text)
+ ${RELOCATING+PROVIDE (__runtime_reloc_start = .);}
+ *(.rel.sdata)
+ ${RELOCATING+PROVIDE (__runtime_reloc_stop = .);}
+ *(.fini)
+ ${RELOCATING+ etext = .};
+ ${RELOCATING+ _etext = .};
+ }
+ ${RELOCATING+. = ${DATA_ADDR};}
+ .rdata : {
+ *(.rdata)
+ }
+ ${RELOCATING+ _fdata = ALIGN(16);}
+ .data : {
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ }
+ ${RELOCATING+ _gp = ALIGN(16) + 0x8000;}
+ .lit8 : {
+ *(.lit8)
+ }
+ .lit4 : {
+ *(.lit4)
+ }
+ .sdata : {
+ *(.sdata)
+ }
+ ${RELOCATING+ edata = .;}
+ ${RELOCATING+ _edata = .;}
+ ${RELOCATING+ _fbss = .;}
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ ${RELOCATING+ end = .;}
+ ${RELOCATING+ _end = .;}
+}
+EOF
diff --git a/ld/scripttempl/mipsbsd.sc b/ld/scripttempl/mipsbsd.sc
new file mode 100644
index 00000000000..b222b335600
--- /dev/null
+++ b/ld/scripttempl/mipsbsd.sc
@@ -0,0 +1,30 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+SECTIONS
+{
+ ${RELOCATING+. = ${TEXT_START_ADDR};}
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ ${RELOCATING+etext = ${DATA_ALIGNMENT};}
+ }
+ ${RELOCATING+. = ${DATA_ALIGNMENT};}
+ .data :
+ {
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+edata = .;}
+ }
+ .bss :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+end = . };
+ }
+}
+EOF
diff --git a/ld/scripttempl/nw.sc b/ld/scripttempl/nw.sc
new file mode 100644
index 00000000000..725522c7895
--- /dev/null
+++ b/ld/scripttempl/nw.sc
@@ -0,0 +1,131 @@
+#
+# Unusual variables checked by this code:
+# NOP - two byte opcode for no-op (defaults to 0)
+# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+# OTHER_READONLY_SECTIONS - other than .text .init .ctors .rodata ...
+# (e.g., .PARISC.milli)
+# OTHER_READWRITE_SECTIONS - other than .data .bss .sdata ...
+# (e.g., .PARISC.global)
+# OTHER_SECTIONS - at the end
+# EXECUTABLE_SYMBOLS - symbols that must be defined for an
+# executable (e.g., _DYNAMIC_LINK)
+# TEXT_START_SYMBOLS - symbols that appear at the start of the
+# .text section.
+# DATA_START_SYMBOLS - symbols that appear at the start of the
+# .data section.
+# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+# .bss section besides __bss_start.
+# DATA_PLT - .plt should be in data segment, not text segment.
+#
+# When adding sections, do note that the names of some sections are used
+# when specifying the start address of the next.
+#
+test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+test "$LD_FLAG" = "N" && DATA_ADDR=.
+INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+PLT=".plt ${RELOCATING-0} : { *(.plt) }"
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${RELOCATING+/* Do we need any of these for elf?
+ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
+${RELOCATING+${EXECUTABLE_SYMBOLS}}
+${RELOCATING- /* For some reason, the Solaris linker makes bad executables
+ if gld -r is used and the intermediate file has sections starting
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
+ bug. But for now assigning the zero vmas works. */}
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB-${INTERP}}
+ .hash ${RELOCATING-0} : { *(.hash) }
+ .dynsym ${RELOCATING-0} : { *(.dynsym) }
+ .dynstr ${RELOCATING-0} : { *(.dynstr) }
+ .rel.text ${RELOCATING-0} : { *(.rel.text) }
+ .rela.text ${RELOCATING-0} : { *(.rela.text) }
+ .rel.data ${RELOCATING-0} : { *(.rel.data) }
+ .rela.data ${RELOCATING-0} : { *(.rela.data) }
+ .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) }
+ .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) }
+ .rel.got ${RELOCATING-0} : { *(.rel.got) }
+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
+ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
+ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
+ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
+ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
+ .rel.bss ${RELOCATING-0} : { *(.rel.bss) }
+ .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
+ .rel.plt ${RELOCATING-0} : { *(.rel.plt) }
+ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
+ .init ${RELOCATING-0} : { *(.init) } =${NOP-0}
+ ${DATA_PLT-${PLT}}
+ .text ${RELOCATING-0} :
+ {
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ *(.text)
+ ${CONSTRUCTING+ __CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __CTOR_END__ = .;}
+ ${CONSTRUCTING+ __DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ __DTOR_END__ = .;}
+ }
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+ .fini ${RELOCATING-0} : { *(.fini) } =${NOP-0}
+ .ctors ${RELOCATING-0} : { *(.ctors) }
+ .dtors ${RELOCATING-0} : { *(.dtors) }
+ .rodata ${RELOCATING-0} : { *(.rodata) }
+ .rodata1 ${RELOCATING-0} : { *(.rodata1) }
+ ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+ /* Read-write section, merged into data segment: */
+ ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
+ .data ${RELOCATING-0} :
+ {
+ ${RELOCATING+${DATA_START_SYMBOLS}}
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ }
+ .data1 ${RELOCATING-0} : { *(.data1) }
+ ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
+ .got ${RELOCATING-0} : { *(.got.plt) *(.got) }
+ .dynamic ${RELOCATING-0} : { *(.dynamic) }
+ ${DATA_PLT+${PLT}}
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata ${RELOCATING-0} : { *(.sdata) }
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+PROVIDE (edata = .);}
+ ${RELOCATING+__bss_start = .;}
+ ${RELOCATING+${OTHER_BSS_SYMBOLS}}
+ .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) }
+ .bss ${RELOCATING-0} :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ ${RELOCATING+_end = . ;}
+ ${RELOCATING+PROVIDE (end = .);}
+
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+
+ /* These must appear regardless of ${RELOCATING}. */
+ ${OTHER_SECTIONS}
+}
+EOF
diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc
new file mode 100644
index 00000000000..7926bfe8776
--- /dev/null
+++ b/ld/scripttempl/pe.sc
@@ -0,0 +1,151 @@
+# Linker script for PE.
+
+if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then
+ RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+fi
+
+# We can't easily and portably get an unquoted $ in a shell
+# substitution, so we do this instead.
+# Sorting of the .foo$* sections is required by the definition of
+# grouped sections in PE.
+# Sorting of the file names in R_IDATA is required by the
+# current implementation of dlltool (this could probably be changed to
+# use grouped sections instead).
+if test "${RELOCATING}"; then
+ R_TEXT='*(SORT(.text$*))'
+ R_DATA='*(SORT(.data$*))'
+ R_RDATA='*(SORT(.rdata$*))'
+ R_IDATA='
+ SORT(*)(.idata$2)
+ SORT(*)(.idata$3)
+ /* These zeroes mark the end of the import list. */
+ LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
+ SORT(*)(.idata$4)
+ SORT(*)(.idata$5)
+ SORT(*)(.idata$6)
+ SORT(*)(.idata$7)'
+ R_CRT='*(SORT(.CRT$*))'
+ R_RSRC='*(SORT(.rsrc$*))'
+else
+ R_TEXT=
+ R_DATA=
+ R_RDATA=
+ R_IDATA=
+ R_CRT=
+ R_RSRC=
+fi
+
+cat <<EOF
+${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})}
+${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})}
+
+${LIB_SEARCH_DIRS}
+
+ENTRY(_mainCRTStartup)
+
+SECTIONS
+{
+ .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
+ {
+ ${RELOCATING+ *(.init)}
+ *(.text)
+ ${R_TEXT}
+ *(.glue_7t)
+ *(.glue_7)
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1); *(.ctors); *(.ctor); LONG (0); }
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); LONG (0); }
+ ${RELOCATING+ *(.fini)}
+ /* ??? Why is .gcc_exc here? */
+ ${RELOCATING+ *(.gcc_exc)}
+ ${RELOCATING+ etext = .;}
+ *(.gcc_except_table)
+ }
+
+ /* The Cygwin32 library uses a section to avoid copying certain data
+ on fork. This used to be named ".data$nocopy". The linker used
+ to include this between __data_start__ and __data_end__, but that
+ breaks building the cygwin32 dll. Instead, we name the section
+ ".data_cygwin_nocopy" and explictly include it after __data_end__. */
+
+ .data ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__data_start__ = . ;}
+ *(.data)
+ *(.data2)
+ ${R_DATA}
+ ${RELOCATING+__data_end__ = . ;}
+ ${RELOCATING+*(.data_cygwin_nocopy)}
+ }
+
+ .bss ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__bss_start__ = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+__bss_end__ = . ;}
+ }
+
+ .rdata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rdata)
+ ${R_RDATA}
+ *(.eh_frame)
+ }
+
+ .edata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.edata)
+ }
+
+ /DISCARD/ :
+ {
+ *(.debug\$S)
+ *(.debug\$T)
+ *(.debug\$F)
+ *(.drectve)
+ }
+
+ .idata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pe.em:sort_sections. */
+ ${R_IDATA}
+ }
+ .CRT ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${R_CRT}
+ }
+
+ .endjunk ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* end is deprecated, don't use it */
+ ${RELOCATING+ end = .;}
+ ${RELOCATING+ _end = .;}
+ ${RELOCATING+ __end__ = .;}
+ }
+
+ .reloc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.reloc)
+ }
+
+ .rsrc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rsrc)
+ ${R_RSRC}
+ }
+
+ .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+
+ .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+
+}
+EOF
diff --git a/ld/scripttempl/ppcpe.sc b/ld/scripttempl/ppcpe.sc
new file mode 100644
index 00000000000..40fbe33bb79
--- /dev/null
+++ b/ld/scripttempl/ppcpe.sc
@@ -0,0 +1,198 @@
+# A PE linker script for PowerPC.
+# Loosely based on Steve Chamberlain's pe.sc.
+# All new mistakes should be credited to Kim Knuttila (krk@cygnus.com)
+#
+# These are substituted in as variables in order to get '}' in a shell
+# conditional expansion.
+INIT='.init : { *(.init) }'
+FINI='.fini : { *(.fini) }'
+cat <<EOF
+OUTPUT_FORMAT(${OUTPUT_FORMAT})
+${LIB_SEARCH_DIRS}
+
+/* Much of this layout was determined by delving into .exe files for
+ the box generated by other compilers/linkers/etc. This means that
+ if a particular feature did not happen to appear in one of the
+ subject files, then it may not be yet supported.
+*/
+
+/* It's "mainCRTStartup", not "_mainCRTStartup", and it's located in
+ one of the two .lib files (libc.lib and kernel32.lib) that currently
+ must be present on the link line. This means that you must use
+ "-u mainCRTStartup" to make sure it gets included in the link.
+*/
+
+ENTRY(mainCRTStartup)
+
+SECTIONS
+{
+
+ /* text - the usual meaning */
+ .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
+ {
+ ${RELOCATING+ *(.init);}
+ *(.text)
+ *(.gcc_except_table)
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1); *(.ctors); *(.ctor); LONG (0); }
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); LONG (0); }
+ ${RELOCATING+ *(.fini);}
+ ${RELOCATING+ etext = .};
+ }
+
+ /* rdata - Read Only Runtime Data
+ CTR sections: All of the CRT (read only C runtime data) sections
+ appear at the start of the .rdata (read only runtime data)
+ section, in the following order. Don't know if it matters or not.
+ Not all sections are always present either.
+ .rdata: compiler generated read only data
+ .xdata: compiler generated exception handling table. (Most docs
+ seem to suggest that this section is now deprecated infavor
+ of the ydata section)
+ .edata: The exported names table.
+ */
+ .rdata BLOCK(__section_alignment__) :
+ {
+ *(.CRT\$XCA);
+ *(.CRT\$XCC);
+ *(.CRT\$XCZ);
+ *(.CRT\$XIA);
+ *(.CRT\$XIC);
+ *(.CRT\$XIZ);
+ *(.CRT\$XLA);
+ *(.CRT\$XLZ);
+ *(.CRT\$XPA);
+ *(.CRT\$XPX);
+ *(.CRT\$XPZ);
+ *(.CRT\$XTA);
+ *(.CRT\$XTZ);
+ *(.rdata);
+ *(.xdata);
+ }
+
+ .edata BLOCK(__section_alignment__) :
+ {
+ *(.edata);
+ }
+
+ /* data - initialized data
+ .ydata: exception handling information.
+ .data: the usual meaning.
+ .data2: more of the same.
+ .bss: For some reason, bss appears to be included in the data
+ section, as opposed to being given a section of it's own.
+ COMMON:
+ */
+ .data BLOCK(__section_alignment__) :
+ {
+ __data_start__ = . ;
+ *(.ydata);
+ *(.data);
+ *(.data2);
+ __bss_start__ = . ;
+ *(.bss) ;
+ *(COMMON);
+ __bss_end__ = . ;
+ ${RELOCATING+ end = .};
+ __data_end__ = . ;
+ }
+
+ /* The exception handling table. A sequence of 5 word entries. Section
+ address and extent are placed in the DataDirectory.
+ */
+ .pdata BLOCK(__section_alignment__) :
+ {
+ *(.pdata)
+ ;
+ }
+
+ /* The idata section is chock full of magic bits.
+ 1. Boundaries around various idata parts are used to initialize
+ some of the fields of the DataDirectory. In particular, the
+ magic for 2, 4 and 5 are known to be used. Some compilers
+ appear to generate magic section symbols for this purpose.
+ Where we can, we catch such symbols and use our own. This of
+ course is something less than a perfect strategy.
+ 2. The table of contents is placed immediately after idata4.
+ The ".private.toc" sections are generated by the ppc bfd. The
+ .toc variable is generated by gas, and resolved here. It is
+ used to initialized function descriptors (and anyone else who
+ needs the address of the module's toc). The only thing
+ interesting about it at all? Most ppc instructions using it
+ have a 16bit displacement field. The convention for addressing
+ is to initialize the .toc value to 32K past the start of the
+ actual toc, and subtract 32K from all references, thus using
+ the entire 64K range. Naturally, the reloc code must agree
+ on this number or you get pretty stupid results.
+ */
+ .idata BLOCK(__section_alignment__) :
+ {
+ __idata2_magic__ = .;
+ *(.idata\$2);
+ __idata3_magic__ = .;
+ *(.idata\$3);
+ __idata4_magic__ = .;
+ *(.idata\$4);
+ . = ALIGN(4);
+ .toc = . + 32768;
+ *(.private.toc);
+ __idata5_magic__ = .;
+ *(.idata\$5);
+ __idata6_magic__ = .;
+ *(.idata\$6);
+ __idata7_magic__ = .;
+ *(.idata\$7);
+ ;
+ }
+
+ /* reldata -- data that requires relocation
+ */
+ .reldata BLOCK(__section_alignment__) :
+ {
+ *(.reldata)
+ ;
+ }
+
+
+ /* Resources */
+ .rsrc BLOCK(__section_alignment__) :
+ {
+ *(.rsrc\$01)
+ *(.rsrc\$02)
+ ;
+ }
+
+ .stab BLOCK(__section_alignment__) ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+
+ .stabstr BLOCK(__section_alignment__) ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+
+ /* The .reloc section is currently generated by the dlltool from Steve
+ Chamberlain in a second pass of linking. Section address and extent
+ are placed in the DataDirectory.
+ */
+ .reloc BLOCK(__section_alignment__) :
+ {
+ *(.reloc)
+ ;
+ }
+
+ /* We don't do anything useful with codeview debugger support or the
+ directive section (yet). Hopefully, we junk them correctly.
+ */
+ /DISCARD/ BLOCK(__section_alignment__) :
+ {
+ *(.debug\$S)
+ *(.debug\$T)
+ *(.debug\$F)
+ *(.drectve)
+ ;
+ }
+}
+EOF
diff --git a/ld/scripttempl/psos.sc b/ld/scripttempl/psos.sc
new file mode 100644
index 00000000000..ab8c6c7e3c8
--- /dev/null
+++ b/ld/scripttempl/psos.sc
@@ -0,0 +1,61 @@
+cat <<EOF
+OUTPUT_FORMAT(${OUTPUT_FORMAT})
+OUTPUT_ARCH(${ARCH})
+${RELOCATING+${LIB_SEARCH_DIRS}}
+
+SECTIONS
+{
+ .text ${RELOCATING:-0} ${RELOCATING+${TEXT_START_ADDR}} : {
+ ${RELOCATING+ start = DEFINED(_START) ? _START : DEFINED(_start) ? _start : .;}
+ ${RELOCATING+ PROVIDE(__text = .);}
+ *(.text);
+ *(code);
+ *(const);
+ *(strings);
+ *(pSOS);
+ *(pROBE);
+ *(pNA);
+ *(pHILE);
+ *(pREPC);
+ *(pRPC);
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0);}
+ ${CONSTRUCTING+ ___CTOR_END__ = .;}
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2);}
+ ${CONSTRUCTING+ *(.dtors);}
+ ${CONSTRUCTING+ LONG(0);}
+ ${CONSTRUCTING+ ___DTOR_END__ = .;}
+ ${RELOCATING+ PROVIDE(__etext = .);}
+ ${RELOCATING+ PROVIDE(_etext = .);}
+ }
+ .data ${RELOCATING:-0} : ${RELOCATING+ AT(ADDR(.text) + SIZEOF(.text))} {
+ ${RELOCATING+ PROVIDE(__data = .);}
+ *(.data);
+ *(vars);
+ ${RELOCATING+ PROVIDE(__edata = .);}
+ ${RELOCATING+ PROVIDE(_edata = .);}
+ }
+ .bss ${RELOCATING:-0} :
+ {
+ ${RELOCATING+ PROVIDE(__bss = .);}
+ *(.bss);
+ *(zerovars);
+ *(COMMON);
+ ${RELOCATING+ PROVIDE(__ebss = .);}
+ ${RELOCATING+ PROVIDE(__end = .);}
+ ${RELOCATING+ PROVIDE(_end = .);}
+ ${RELOCATING+ PROVIDE(_FreeMemStart = .);}
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ *(.stab);
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ *(.stabstr);
+ }
+}
+EOF
diff --git a/ld/scripttempl/riscix.sc b/ld/scripttempl/riscix.sc
new file mode 100644
index 00000000000..c801a0c4a99
--- /dev/null
+++ b/ld/scripttempl/riscix.sc
@@ -0,0 +1,35 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${RELOCATING+${LIB_SEARCH_DIRS}}
+${RELOCATING+__DYNAMIC = 0;}
+${STACKZERO+${RELOCATING+${STACKZERO}}}
+${SHLIB_PATH+${RELOCATING+${SHLIB_PATH}}}
+SECTIONS
+{
+ .text ${RELOCATING+${TEXT_START_ADDR}}:
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}}
+ ${RELOCATING+_etext = ${DATA_ALIGNMENT};}
+ ${RELOCATING+__etext = ${DATA_ALIGNMENT};}
+ }
+ .data ${RELOCATING+${DATA_ALIGNMENT}} :
+ {
+ *(.data)
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+__edata = .;}
+ }
+ .bss ${RELOCATING+SIZEOF(.data) + ADDR(.data)} :
+ {
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+_end = ALIGN(4) };
+ ${RELOCATING+__end = ALIGN(4) };
+ }
+}
+EOF
diff --git a/ld/scripttempl/sa29200.sc b/ld/scripttempl/sa29200.sc
new file mode 100644
index 00000000000..a2f267e649d
--- /dev/null
+++ b/ld/scripttempl/sa29200.sc
@@ -0,0 +1,44 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+ENTRY(start)
+
+SECTIONS {
+ .text ${RELOCATING+${TEXT_START_ADDR}} :
+ {
+ *(.text);
+ *(.text1);
+ *(.text2);
+ ${RELOCATING+_etext = .};
+ }
+ .lit ALIGN(4) :
+ {
+ *(.lit);
+ ${RELOCATING+_elit = .};
+ }
+ .data ALIGN(4) :
+ {
+ *(.data);
+ *(.data1);
+ *(.data2);
+ ${RELOCATING+_edata = .};
+ ${CONSTRUCTING+CONSTRUCTORS}
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___CTOR_END__ = .;}
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___DTOR_END__ = .;}
+ }
+
+ .bss ALIGN(4) :
+ {
+ *(COMMON)
+ *(.bss)
+ ${RELOCATING+_end = .};
+ }
+}
+EOF
diff --git a/ld/scripttempl/sh.sc b/ld/scripttempl/sh.sc
new file mode 100644
index 00000000000..036dd216db2
--- /dev/null
+++ b/ld/scripttempl/sh.sc
@@ -0,0 +1,59 @@
+TORS=".tors :
+ {
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+ } > ram"
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+MEMORY
+{
+ ram : o = 0x1000, l = 512k
+}
+
+SECTIONS
+{
+ .text :
+ {
+ *(.text)
+ *(.strings)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ram}
+ ${CONSTRUCTING+${TORS}}
+ .data :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ram}
+ .bss :
+ {
+ ${RELOCATING+ _bss_start = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ > ram}
+ .stack ${RELOCATING+ 0x30000 } :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ } ${RELOCATING+ > ram}
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ *(.stab)
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ *(.stabstr)
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/sparccoff.sc b/ld/scripttempl/sparccoff.sc
new file mode 100644
index 00000000000..6bbb7ad6e90
--- /dev/null
+++ b/ld/scripttempl/sparccoff.sc
@@ -0,0 +1,48 @@
+# Linker script for Sparc COFF.
+# Based on i386coff.sc by Ian Taylor <ian@cygnus.com>.
+test -z "$ENTRY" && ENTRY=_start
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ SIZEOF_HEADERS} : {
+ *(.init)
+ *(.text)
+ ${RELOCATING+ etext = .;}
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___CTOR_END__ = .;}
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___DTOR_END__ = .;}
+ *(.fini)
+ ${RELOCATING+ etext = .};
+ }
+ .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : {
+ *(.data)
+ ${RELOCATING+ edata = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = .};
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/sparclynx.sc b/ld/scripttempl/sparclynx.sc
new file mode 100644
index 00000000000..c2b1e1d327d
--- /dev/null
+++ b/ld/scripttempl/sparclynx.sc
@@ -0,0 +1,47 @@
+# Linker script for Sparc LynxOS.
+test -z "$ENTRY" && ENTRY=_start
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ SIZEOF_HEADERS} : {
+ *(.init)
+ *(.text)
+ ${RELOCATING+ etext = .;}
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.ctors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___CTOR_END__ = .;}
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ LONG(0)}
+ ${CONSTRUCTING+ ___DTOR_END__ = .;}
+ *(.fini)
+ ${RELOCATING+ etext = .};
+ }
+ .data ${RELOCATING+ 0x400000 + (. & 0xffc00fff)} : {
+ *(.data)
+ ${RELOCATING+ edata = .};
+ }
+ .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
+ {
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ end = .};
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/st2000.sc b/ld/scripttempl/st2000.sc
new file mode 100644
index 00000000000..7ee132a8b26
--- /dev/null
+++ b/ld/scripttempl/st2000.sc
@@ -0,0 +1,26 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+
+SECTIONS
+{
+.text :
+ {
+ *(.text)
+ *(.strings)
+ _etext = .;
+ *(.data)
+ _edata = .;
+ *(.bss)
+ *(COMMON)
+ _end = .;
+
+}
+
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/tic30aout.sc b/ld/scripttempl/tic30aout.sc
new file mode 100644
index 00000000000..28baed37e61
--- /dev/null
+++ b/ld/scripttempl/tic30aout.sc
@@ -0,0 +1,34 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+${STACKZERO+${RELOCATING+${STACKZERO}}}
+${RELOCATING+PROVIDE (__stack = 0);}
+SECTIONS
+{
+ ${RELOCATING+. = ${TEXT_START_ADDR};}
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+__etext = .;}
+ ${PAD_TEXT+${RELOCATING+. = ${DATA_ALIGNMENT};}}
+ }
+ ${RELOCATING+. = ${DATA_ALIGNMENT};}
+ .data :
+ {
+ *(.data)
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+__edata = .;}
+ }
+ .bss :
+ {
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+_end = ALIGN(4) };
+ ${RELOCATING+__end = ALIGN(4) };
+ }
+}
+EOF
diff --git a/ld/scripttempl/tic30coff.sc b/ld/scripttempl/tic30coff.sc
new file mode 100644
index 00000000000..df2d4f737cd
--- /dev/null
+++ b/ld/scripttempl/tic30coff.sc
@@ -0,0 +1,58 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH("${OUTPUT_ARCH}")
+
+MEMORY
+{
+ rom : ORIGIN = 0x00000300, LENGTH = 16k
+ ram : ORIGIN = 0x00000300 + 16k, LENGTH = 16k
+ ramblk0 : ORIGIN = 0x02026000, LENGTH = 0x1000
+ ramblk1 : ORIGIN = 0x02027000, LENGTH = 0x1000
+}
+
+SECTIONS
+{
+.vectors 0x00000000 :
+{
+ *(vectors)
+}
+
+.text :
+{
+ *(.text)
+} > rom
+
+.const :
+{
+ *(.const)
+ __etext = . ;
+} > rom
+
+.mdata : AT( ADDR(.const) + SIZEOF(.const) )
+{
+ __data = . ;
+ *(.data);
+ __edata = . ;
+} > ram
+
+.bss :
+{
+ __bss = . ;
+ *(.bss);
+ *(COMMON);
+ __ebss = . ;
+} > ram
+
+.ram0 :
+{
+ *(ram0)
+} > ramblk0
+
+.ram1 :
+{
+ *(ram1)
+} > ramblk1
+
+}
+
+EOF
diff --git a/ld/scripttempl/tic80coff.sc b/ld/scripttempl/tic80coff.sc
new file mode 100644
index 00000000000..2b6f6534aab
--- /dev/null
+++ b/ld/scripttempl/tic80coff.sc
@@ -0,0 +1,74 @@
+# Linker script for TI TMS320C80 (tic80) COFF.
+#
+# Besides the shell variables set by the emulparams script, and the LD_FLAG
+# variable, the genscripts.sh script will set the following variables for each
+# time this script is run to generate one of the linker scripts for ldscripts:
+#
+# RELOCATING: Set to a non-empty string when the linker is going to be doing
+# a final relocation.
+#
+# CONSTRUCTING: Set to a non-empty string when the linker is going to be
+# building global constructor and destructor tables.
+#
+# DATA_ALIGNMENT: Set to an ALIGN expression when the output should be page
+# aligned, or to "." when generating the -N script.
+#
+# CREATE_SHLIB: Set to a non-empty string when generating a script for
+# the -shared linker arg.
+
+test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x80000 + SIZEOF_HEADERS"
+test -z "$ENTRY" && ENTRY=__start
+
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+${LIB_SEARCH_DIRS}
+
+ENTRY(${ENTRY})
+
+SECTIONS
+{
+ .text ${RELOCATING+ $TEXT_START_ADDR} : {
+ *(.init)
+ *(.fini)
+ *(.text)
+ }
+ .const ALIGN(4) : {
+ *(.const)
+ }
+ .ctors ALIGN(4) : {
+ ${CONSTRUCTING+ . = ALIGN(4);}
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG(-1)}
+ *(.ctors)
+ ${CONSTRUCTING+ ___CTOR_END__ = .;}
+ ${CONSTRUCTING+ LONG(0)}
+ }
+ .dtors ALIGN(4) : {
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .;}
+ ${CONSTRUCTING+ LONG(-1)}
+ ${CONSTRUCTING+ *(.dtors)}
+ ${CONSTRUCTING+ ___DTOR_END__ = .;}
+ ${CONSTRUCTING+ LONG(0)}
+ }
+ ${RELOCATING+ etext = .;}
+ .data : {
+ *(.data)
+ ${RELOCATING+ __edata = .};
+ }
+ .bss : {
+ ${RELOCATING+ __bss_start = .};
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = ALIGN(0x8)};
+ ${RELOCATING+ __end = ALIGN(0x8)};
+ }
+ .stab 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 ${RELOCATING+(NOLOAD)} :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
diff --git a/ld/scripttempl/v850.sc b/ld/scripttempl/v850.sc
new file mode 100644
index 00000000000..6b2f7e54564
--- /dev/null
+++ b/ld/scripttempl/v850.sc
@@ -0,0 +1,204 @@
+cat << EOF
+OUTPUT_FORMAT("elf32-v850", "elf32-v850",
+ "elf32-v850")
+OUTPUT_ARCH(v850)
+ENTRY(_start)
+SEARCH_DIR(.);
+/*/critters/slug/grossman/install/sun4/v850-elf/lib*/
+SECTIONS
+{
+ /* This saves a little space in the ELF file, since the zda starts
+ at a higher location that the ELF headers take up. */
+
+ .zdata ${ZDATA_START_ADDR} : {
+ *(.zdata)
+ *(.zbss)
+ *(reszdata)
+ *(.zcommon)
+ }
+
+ /* This is the read only part of the zero data area.
+ Having it as a seperate section prevents its
+ attributes from being inherited by the zdata
+ section. Specifically it prevents the zdata
+ section from being marked READONLY. */
+
+ .rozdata ${ROZDATA_START_ADDR} : {
+ *(.rozdata)
+ *(romzdata)
+ *(romzbss)
+ }
+
+ /* Read-only sections, merged into text segment: */
+ . = ${TEXT_START_ADDR};
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { KEEP (*(.init)) } =0
+ .plt : { *(.plt) }
+
+ .text : {
+ *(.text)
+ ${RELOCATING+*(.text.*)}
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+
+ /* This is special code area at the end of the normal text section.
+ It contains a small lookup table at the start followed by the
+ code pointed to by entries in the lookup table. */
+
+ .call_table_data ${CALL_TABLE_START_ADDR} : {
+ ${RELOCATING+PROVIDE(__ctbp = .);}
+ *(.call_table_data)
+ } = 0xff /* fill gaps with 0xff */
+ .call_table_text : {
+ *(.call_table_text)
+ }
+
+ .fini : { KEEP (*(.fini)) } =0
+ .rodata : { *(.rodata) ${RELOCATING+*(.rodata.*)} *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+
+ .data : {
+ *(.data)
+ ${RELOCATING+*(.data.*)}
+ *(.gnu.linkonce.d*)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ .ctors : {
+ ${RELOCATING+___ctors = .;}
+ KEEP (*(.ctors))
+ ${RELOCATING+___ctors_end = .;}
+ }
+
+ .dtors : {
+ ${RELOCATING+___dtors = .;}
+ KEEP (*(.dtors))
+ ${RELOCATING+___dtors_end = .;}
+ }
+
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+
+ .tdata ${TDATA_START_ADDR} : {
+ ${RELOCATING+PROVIDE (__ep = .);}
+ *(.tbyte)
+ *(.tcommon_byte)
+ *(.tdata)
+ *(.tbss)
+ *(.tcommon)
+ }
+
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata ${SDATA_START_ADDR} : {
+ ${RELOCATING+PROVIDE (__gp = . + 0x8000);}
+ *(.sdata)
+ }
+
+ /* See comment about .rozdata. */
+ .rosdata ${ROSDATA_START_ADDR} : {
+ *(.rosdata)
+ }
+
+ /* We place the .sbss data section AFTER the .rosdata section, so that
+ it can directly preceed the .bss section. This allows runtime startup
+ code to initialise all the zero-data sections by simply taking the
+ value of '_edata' and zeroing until it reaches '_end' */
+ .sbss : {
+ ${RELOCATING+__sbss_start = .;}
+ *(.sbss)
+ *(.scommon)
+ }
+
+ ${RELOCATING+_edata = DEFINED (__sbss_start) ? __sbss_start : . ;}
+ ${RELOCATING+PROVIDE (edata = _edata);}
+
+ .bss :
+ {
+ ${RELOCATING+__bss_start = DEFINED (__sbss_start) ? __sbss_start : . ;}
+ ${RELOCATING+__real_bss_start = . ;}
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+
+ ${RELOCATING+_end = . ;}
+ ${RELOCATING+PROVIDE (end = .);}
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /* User stack */
+ .stack 0x200000 : {
+ ${RELOCATING+__stack = .;}
+ *(.stack)
+ }
+ /* These must appear regardless of . */
+}
+EOF
diff --git a/ld/scripttempl/vanilla.sc b/ld/scripttempl/vanilla.sc
new file mode 100644
index 00000000000..1798480e69b
--- /dev/null
+++ b/ld/scripttempl/vanilla.sc
@@ -0,0 +1 @@
+# Nothing to do.
diff --git a/ld/scripttempl/w65.sc b/ld/scripttempl/w65.sc
new file mode 100644
index 00000000000..f9044952952
--- /dev/null
+++ b/ld/scripttempl/w65.sc
@@ -0,0 +1,58 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+MEMORY {
+ ram : o = 0x1000, l = 512k
+ }
+
+SECTIONS
+{
+.text :
+ {
+ *(.text)
+ *(.strings)
+ ${RELOCATING+ _etext = . ; }
+ } ${RELOCATING+ > ram}
+
+
+.tors : {
+ ___ctors = . ;
+ *(.ctors)
+ ___ctors_end = . ;
+ ___dtors = . ;
+ *(.dtors)
+ ___dtors_end = . ;
+} ${RELOCATING+ > ram}
+
+.data :
+ {
+ *(.data)
+ ${RELOCATING+ _edata = . ; }
+ } ${RELOCATING+ > ram}
+.bss :
+ {
+ ${RELOCATING+ _bss_start = . ; }
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+ _end = . ; }
+ } ${RELOCATING+ >ram}
+.stack ${RELOCATING+ 0x30000 } :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ } ${RELOCATING+ > ram}
+ .stab . (NOLOAD) :
+ {
+ [ .stab ]
+ }
+ .stabstr . (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+}
+EOF
+
+
+
+
diff --git a/ld/scripttempl/z8000.sc b/ld/scripttempl/z8000.sc
new file mode 100644
index 00000000000..2b87930100e
--- /dev/null
+++ b/ld/scripttempl/z8000.sc
@@ -0,0 +1,54 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
+OUTPUT_ARCH("${OUTPUT_ARCH}")
+ENTRY(_start)
+
+SECTIONS
+{
+.text ${BIG+ ${RELOCATING+ 0x0000000}} : {
+ *(.text)
+ *(.strings)
+ *(.rdata)
+ }
+
+.ctors ${BIG+ ${RELOCATING+ 0x2000000}} :
+ {
+ ${RELOCATING+ ___ctors = . ; }
+ *(.ctors);
+ ${RELOCATING+ ___ctors_end = . ; }
+ ___dtors = . ;
+ *(.dtors);
+ ${RELOCATING+ ___dtors_end = . ; }
+ }
+
+.data ${BIG+ ${RELOCATING+ 0x3000000}} : {
+ *(.data)
+ }
+
+.bss ${BIG+ ${RELOCATING+ 0x4000000}} :
+ {
+ ${RELOCATING+ __start_bss = . ; }
+ *(.bss);
+ *(COMMON);
+ ${RELOCATING+ __end_bss = . ; }
+ }
+
+.heap ${BIG+ ${RELOCATING+ 0x5000000}} : {
+ ${RELOCATING+ __start_heap = . ; }
+ ${RELOCATING+ . = . + 20k ; }
+ ${RELOCATING+ __end_heap = . ; }
+ }
+
+.stack ${RELOCATING+ 0xf000 } :
+ {
+ ${RELOCATING+ _stack = . ; }
+ *(.stack)
+ ${RELOCATING+ __stack_top = . ; }
+ }
+
+}
+EOF
+
+
+
+
diff --git a/ld/stamp-h.in b/ld/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/ld/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/ld/sysdep.h b/ld/sysdep.h
new file mode 100644
index 00000000000..2ccc12279ad
--- /dev/null
+++ b/ld/sysdep.h
@@ -0,0 +1,73 @@
+/* sysdep.h -- handle host dependencies for the GNU linker
+ Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc.
+
+ This file is part of GLD, the Gnu Linker.
+
+ GLD 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, or (at your option)
+ any later version.
+
+ GLD 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 GLD; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef LD_SYSDEP_H
+#define LD_SYSDEP_H
+
+#include "ansidecl.h"
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#else
+extern char *strchr ();
+extern char *strrchr ();
+#endif
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef USE_BINARY_FOPEN
+#include "fopen-bin.h"
+#else
+#include "fopen-same.h"
+#endif
+
+#ifdef NEED_DECLARATION_STRSTR
+extern char *strstr ();
+#endif
+
+#ifdef NEED_DECLARATION_FREE
+extern void free ();
+#endif
+
+#ifdef NEED_DECLARATION_GETENV
+extern char *getenv ();
+#endif
+
+#ifdef NEED_DECLARATION_ENVIRON
+extern char **environ;
+#endif
+
+#endif /* ! defined (LD_SYSDEP_H) */
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
new file mode 100644
index 00000000000..6610cbfb3e6
--- /dev/null
+++ b/ld/testsuite/ChangeLog
@@ -0,0 +1,731 @@
+1999-03-05 Nick Clifton <nickc@cygnus.com>
+
+ * ld-selective/selective.exp: Do not run tests for COFF or PE
+ based ports.
+
+1999-02-17 Nick Clifton <nickc@cygnus.com>
+
+ * ld-undefined/undefined.exp: Add expected failures for StrongARM
+ targets.
+
+ * ld-srec/srec.exp: Add expected failures for StrongARM targets.
+
+ * ld-selective/selective.exp: Add expected failure for ARM-COFF
+ targets.
+
+1999-02-16 Nick Clifton <nickc@cygnus.com>
+
+ * ld-checks/asm.s: Use .long instead of .word.
+ Replace custom section names with .text, .data and .bss.
+ * ld-checks/script: Replace custom section names with .text, .data
+ and .bss.
+ * ld-checks/checks.exp: Replace custom section names with .text,
+ .data and .bss.
+
+1999-02-11 Nick Clifton <nickc@cygnus.com>
+
+ * ld-checks: New directory: Tests for the linker's
+ --check-sections option.
+ * ld-checks/checks.exp: New file.
+ * ld-checks/script: Bogus linker script.
+ * ld-checks/asm.s: Simple test assembler file.
+
+Tue Feb 2 19:15:02 1999 Catherine Moore <clm@cygnus.com>
+
+ * ld-selective/selective.exp: Disable test for unsupported
+ targets. Change tests to check for absence of symbols instead
+ of address zero.
+
+Mon Jan 18 03:44:52 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp (get_link_files): Quote target_triplet and CC
+ when invoking shell.
+ (get_target_emul): Likewise.
+
+1999-01-03 Ken Raeburn <raeburn@cygnus.com>
+
+ * config/default.exp (get_link_files, get_target_emul): New procs;
+ run shell commands to extract information from configure.host and
+ configure.tgt in the source tree.
+ (top level): Use them to get information needed to run tests, if
+ not otherwise provided.
+
+ * ld-shared/elf-offset.ld: New file. Builds a shared library, but
+ gives non-zero addresses for memory region.
+ * ld-shared/shared.exp: Run the non-PIC non-AIX test again using
+ the new linker script.
+
+Tue Dec 8 22:56:05 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * ld-srec/srec.exp: Delete xfails for PPC Linux targets,
+ newer glibc lets link succeed.
+
+Sun Dec 6 12:59:37 1998 H.J. Lu <hjl@gnu.org>
+
+ * ld-elfvers/vers1.c: Add missing return types and values.
+ * ld-elfvers/vers2.c: Likewise.
+ * ld-elfvers/vers3.c: Likewise.
+ * ld-elfvers/vers4.c: Likewise.
+ * ld-elfvers/vers5.c: Likewise.
+ * ld-elfvers/vers6.c: Likewise.
+ * ld-elfvers/vers7.c: Likewise.
+ * ld-elfvers/vers9.c: Likewise.
+ * ld-elfvers/vers15.c: Likewise.
+
+Fri Oct 23 16:28:29 1998 Catherine Moore <clm@cygnus.com>
+
+ * ld-selective: New directory with new files to test
+ selective linking.
+
+ * lib/ld-lib.exp (ld_nm): Strip leading underscore from $name.
+
+Sun Oct 4 22:17:05 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-elfvers/vers16.dsym: Work correctly on a system without
+ versioned system libraries.
+
+Mon Sep 28 21:31:12 1998 Richard Henderson <rth@cygnus.com>
+
+ * ld-elfvers/vers.exp: Run tests on alpha-linux.
+ * ld-elfvers/*.sym, ld-elfvers/*.dsym: Adjust patters to match
+ Alpha's use of st_other.
+
+1998-09-27 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ld-elfvers/vers.exp (vers16, vers16a): New tests.
+ * ld-elfvers/{vers16.*, vers16a.*}: New files.
+
+Thu Sep 17 17:18:19 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ld-undefined/undefined.exp: Make undefined line test be an xfail
+ for arm/thunb elf toolchains.
+
+Wed Sep 9 14:10:15 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ld-undefined/undefined.exp: change test for elf/dwarf2 targets.
+
+ * ld-srec/srec.exp: Arm-elf now passes this test.
+
+Wed Aug 19 11:59:19 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ld-srec/srec.exp: Add arm/thumb-elf expected failures.
+
+Thu Aug 13 12:41:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: Don't run the --static bootstrap
+ test if we don't have a static libbfd.a.
+
+Wed Aug 12 15:19:35 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * ld-srec/srec.exp: Add xfails for Alpha ELF targets.
+
+Mon Aug 10 15:42:20 1998 Richard Henderson <rth@cygnus.com>
+
+ * ld-scripts/weak.t (.text, .data): Focus data to be used.
+ (/DISCARD/): All the rest.
+ * ld-scripts/weak1.s, ld-scripts/weak2.s: Put stuff in .data.
+
+Fri Jul 24 18:37:17 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Create tmpdir/gas subdirectory, add a
+ symlink to as-new, and set gcc_gas_flag variable.
+ * lib/ld-lib.exp (default_ld_compile): If the compiler appears to
+ be gcc, use gcc_gas_flag when compiling.
+
+Thu Jul 23 12:23:29 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-elfvers/vers.exp: Just check for i?86 rather than checking
+ for i386, i486, and i586.
+ (objdump_versionstuff): If we can't find the line, dump the file.
+
+Fri Jul 3 00:27:41 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/phdrs.exp: Run test on *-*-eabi*.
+ * ld-scripts/weak.exp: Likewise.
+
+Wed Jul 1 10:51:46 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ld-srec/srec.exp: Add xfail for v850.
+
+ * ld-undefined/undefined.exp: arm and thumb PE toolchains now pass
+ these tests.
+
+Fri Jun 19 17:12:52 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/weak.exp: New test.
+ * ld-scripts/weak.t: New file.
+ * ld-scripts/weak1.s: New file.
+ * ld-scripts/weak2.s: New file.
+
+Tue Jun 16 12:40:38 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * ld-elfvers/vers.exp: Run tests on powerpc ELF targets.
+ * ld-shared/shared.exp: Likewise.
+ * ld-elfvers/vers1.dsym: Allow for .sdata.
+ * ld-srec/srec.exp: Add setup_xfails for PowerPC Linux.
+
+Fri May 29 15:02:50 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Add xfails for powerpc*-*-eabi.
+ (run_srec_test): On mn10200, define __truncsipsi2_do_d2.
+ * ld-srec/sr1.c (__main): Change return type to void.
+ * ld-srec/sr3.cc (__main): Likewise.
+ (__builtin_delete, __builtin_new): Likewise.
+ (__get_dynamic_handler_chain): Return 0.
+ (__get_eh_context): Likewise.
+
+Thu May 21 15:21:33 1998 Nick Clifton <nickc@cygnus.com>
+
+ * ld-undefined/undefined.exp: Add support for thumb-pe target.
+ * ld-srec/srec.exp: Add support for arm-pe and thumb-pe targets.
+
+Mon May 4 17:54:20 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ld-shared/shared.exp: Remove setup_xfails for m68k-linux.
+
+Mon May 4 17:12:06 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-shared/main.c (shlib_overriddencall2): New function.
+ (main): Call shlib_shlibcall2.
+ * ld-shared/sh1.c (shlib_shlibcall2): New function.
+ (shlib_overriddencall2): New function.
+ * ld-shared/shared.dat: Add output line for new test.
+ * ld-shared/sun4.dat: Likewise.
+
+ * ld-srec/sr3.cc (__get_eh_context): New function.
+
+Tue Apr 7 12:50:17 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * ld-cdtest/cdtest-foo.h (class Foo): Declare len to be static to
+ avoid compiler warning.
+ * ld-srec/sr3.cc (class Foo): Likewise.
+
+Tue Feb 10 16:42:40 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/sr3.cc (__get_dynamic_handler_chain): New function.
+
+Mon Feb 2 14:17:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/phdrs.exp: Adjust phdrs_regexp for a 64 bit target.
+
+Thu Dec 18 11:13:28 1997 Nick Clifton <nickc@cygnus.com>
+
+ * ld-srec/srec.exp: Duplicated Arm patch for Thumb targets.
+
+Tue Dec 2 09:50:19 1997 Nick Clifton <nickc@cygnus.com>
+
+ * ld-srec/srec.exp: Applied patch from Tony.Thompson@arm.com which
+ fixes ARM tests.
+
+Mon Dec 1 16:12:05 1997 Nick Clifton <nickc@cygnus.com>
+
+ * ld-srec/srec.exp: Add expected failures of tests 1 and 2 for ARM
+ coff targets.
+
+Wed Nov 12 14:18:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-cdtest/cdtest-foo.h (class Foo): Declare len to be int to
+ avoid compiler warning.
+ * ld-srec/sr3.cc (class Foo): Likewise.
+
+Mon Nov 10 14:25:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/ld-lib.exp (default_ld_simple_link): Permit the linker to
+ have any name when looking for entry symbol warnings.
+
+ * ld-srec/sr3.cc (__eh_pc): Define.
+
+Mon Oct 20 14:36:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/sr3.cc: Add definitions for terminate, __terminate, and
+ __throw, since the current g++ expects them to be defined.
+
+Fri Oct 3 12:24:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-elfvers/vers.exp (objdump_emptyverstuff): Accept the output
+ file if the string libc appears in it.
+ (objdump_versionstuff): Accept unexpected lines in the output
+ file. Compare lines using string match.
+ * ld-elfvers/vers6.ver: Permit any value in the vna_other field.
+
+Tue Aug 12 16:01:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/crossref.exp: Correct string quoting.
+
+Sat Aug 9 00:56:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Change ld, as, nm and strip from .new to
+ -new. Load ld-lib.exp rather than ld.exp.
+ * ld-bootstrap/bootstrap.exp: Use ld-new rather than ld.new.
+ * lib/ld-lib.exp: Rename from lib/ld.exp, for the benefit of
+ DejaGnu changes.
+
+Thu Jun 26 12:07:03 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-elfvers/vers.exp: Use egrep rather than grep when looking for
+ an alternation. From Greg Margo <gmargo@dl.com>.
+
+Wed Jun 25 12:47:22 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ld-shared/shared.exp: Add setup_xfail for m68k-linux on tests
+ with non PIC shared libraries.
+
+Fri Jun 6 17:35:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-elfvers/vers6.ver: Update for recent elflink.h patch to
+ version handling.
+
+Wed Jun 4 12:06:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Define ___get_dynamic_handler_chain as well.
+
+Fri May 30 12:21:39 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Define __get_dynamic_handler_chain when
+ linking.
+
+Mon May 12 11:17:55 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Use $base_dir rather than $objdir when
+ setting ld. From John David Anglin <dave@hiauly1.hia.nrc.ca>.
+
+Fri Apr 25 09:07:00 1997 Jeffrey A Law (law@cygnus.com)
+
+ * ld-srec/srec.exp: Define various out of line prologue/epilogue
+ functions for the mn10200 to avoid needing libgcc.a.
+
+Wed Mar 26 13:56:10 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Don't expect failures on mips*-*-elf*.
+
+Mon Mar 17 19:27:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-elfvers/vers.exp: Don't run on SunOS or AIX.
+
+Wed Mar 12 21:44:19 1997 Eric Youngdale <eric@andante.jic.com>
+
+ * ld-elfvers/vers.exp, *: New tests for symbol versioning.
+ * config/default.exp: Set ar and strip.
+
+Fri Feb 7 16:47:02 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: Use prune_warnings instead of
+ prune_system_crud.
+ * ld-cdtest/cdtest.exp: Ditto.
+ * ld-scripts/crossref.exp: Ditto.
+ * ld-sh/sh.exp: Ditto.
+ * ld-shared/shared.exp: Ditto.
+ * ld-srec/srec.exp: Ditto.
+ * lib/ld.exp: Ditto.
+
+Wed Jan 29 00:47:29 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * ld-cdtest/cdtest.exp: Put a slash between $srcdir/$subdir.
+ * ld-scripts/script.exp: Ditto.
+ * ld-sh/sh.exp: Ditto.
+ * ld-undefined/undefined.exp: Ditto.
+ * ld-versados/versados.exp: Ditto.
+ * lib/ld.exp: Ditto.
+
+Mon Dec 30 17:08:04 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/crossref.exp: Fix quoting for --defsym $global$.
+
+Tue Oct 1 15:52:31 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/ld.exp (default_ld_version): Fix for current version
+ printing.
+
+Fri Sep 13 15:51:45 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/crossref.exp: Define $global$ for hppa-elf.
+
+Thu Aug 8 14:29:32 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/cross2.t: Map XCOFF sections to .text or .data.
+
+ * lib/ld.exp: Use verbose -log instead of calling both verbose and
+ send_log.
+
+Wed Aug 7 18:00:58 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/phdrs.exp: New test.
+ * ld-scripts/phdrs.s, ld-scripts/phdrs.t: New files.
+
+Sun Aug 4 21:58:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/crossref.exp: On a29k targets, use --defsym to define
+ V_SPILL and V_FILL.
+
+Thu Aug 1 14:10:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/crossref.exp: New test.
+ * ld-scripts/{cross1.c, cross2.c, cross3.c}: New files.
+ * ld-scripts/{cross1.t, cross2.t}: New files.
+
+Sat Jun 29 13:40:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-sh/sh.exp: Fix debugging messages.
+ * ld-sh/sh1.s: Use .align 4.
+
+Wed May 1 16:45:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-sh/sh.exp: Use -O when compiling with -mrelax.
+
+Mon Apr 29 10:33:10 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ld-shared/shared.exp: Run the shared library tests on
+ Linux/m68k.
+
+Fri Apr 5 16:20:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-shared/shared.exp: Run the shared library tests on Linux.
+
+Mon Feb 26 12:45:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-shared/shared.exp: Don't use -fpic on MIPS targets.
+
+Wed Jan 31 15:09:57 1996 Jeffrey A Law (law@cygnus.com)
+
+ * ld-srec/srec.exp: Add xfails for hppa*-*-*elf*.
+ * ld-undefined/undefined.exp: Likewise.
+
+Fri Jan 26 18:43:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-undefined/undefined.exp: ELF targets should now pass the
+ undefined line test.
+
+Thu Jan 25 15:36:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-empic/empic.exp: Update for change to MIPS disassembler.
+
+Mon Jan 15 15:05:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: Expect failure for mips*-*-irix5*
+ when doing the --static test.
+ * ld-shared/shared.exp: Run tests on mips*-*-irix5*.
+
+Fri Dec 29 12:33:09 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: On AIX, don't pass the -bI option
+ when creating ld-partial.o.
+
+Tue Dec 26 17:37:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: If powerpc*-*-eabi*, use --defsym to define
+ __eabi.
+
+Tue Dec 19 18:01:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Add setup_xfails for XCOFF targets.
+
+Fri Dec 15 16:36:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: On a29k targets, use --defsym to define
+ V_SPILL and V_FILL.
+ * ld-srec/sr1.c (V_SPILL, V_FILL): Remove definitions.
+ * ld-srec/sr3.cc: Likewise.
+
+ * ld-srec/srec.exp: Remove i960 COFF setup_xfail.
+
+Sat Dec 2 01:20:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Don't use [] in setup_xfail expressions.
+
+Fri Dec 1 13:18:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Add setup_xfails for MIPS ELF targets.
+
+Wed Nov 29 13:01:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Add setup_xfail for i960 COFF targets.
+
+Mon Nov 27 14:36:11 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: Add setup_xfail calls for i[345]86-*-aout*.
+
+ * ld-srec/sr1.c (V_SPILL, V_FILL): Define.
+ * ld-srec/sr3.cc: Likewise.
+
+Tue Nov 21 16:05:53 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-empic/empic.exp: Update for changes in objdump output.
+
+Wed Nov 15 17:42:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-srec/srec.exp: New tests.
+ * ld-srec/sr1.c, ld-srec/sr2.c, ld-srec/sr3.cc: New files.
+ * lib/ld.exp (ld_simple_link): Discard warnings about not being
+ able to find the entry symbol.
+
+Tue Nov 14 20:03:54 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-sh/sh2.c (__main): Define.
+
+Mon Nov 6 14:39:18 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-empic/empic.exp: Accept a . in the address symbol.
+
+ * ld-shared/shared.exp: Run tests on rs6000*-*-aix* and
+ powerpc*-*-aix*. Add code to create appropriate exports files,
+ and pass appropriate compilation flags, and test against
+ appropriate expected output.
+ * ld-shared/xcoff.dat: New file.
+ * ld-shared/main.c: Put #ifndef XCOFF_TEST around tests that can
+ not be linked using XCOFF. Use shlib_shlibvar1 as a sample
+ function pointer, rather than shlib_mainvar.
+ * ld-shared/sh1.c: Likewise.
+ * ld-shared/shared.dat: Update for change from using shlib_mainvar
+ to using shlib_shlibvar1.
+ * ld-shared/sun4.dat: Likewise.
+
+Sat Oct 28 01:54:25 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/script.t: Put .pr in .text, and .rw in .data, for
+ convenience when testing XCOFF.
+
+Thu Oct 26 22:53:17 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: On AIX, pass -bI/lib/syscalls.exp
+ along with --static.
+
+ * ld-scripts/script.s: Make symbols global.
+
+Fri Oct 20 12:22:16 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-undefined/undefined.exp: Add setup_xfails for arm*-*-pe*.
+
+Fri Sep 29 11:06:10 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-undefined/undefined.exp: Use -e when invoking the linker, to
+ prevent the SunOS linker from trying to create a shared library.
+
+Thu Sep 28 12:37:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-shared/shared.exp: Run the tests on sparc*-*-sunos4*. Add
+ appropriate modifications and setup_xfails.
+ * ld-shared/sun4.dat: New file.
+
+Mon Sep 18 14:12:56 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * lib/ld.exp (default_ld_version): Call prune_system_crud.
+ (default_ld_relocate, default_ld_link): Likewise.
+ (default_ld_simple_link, default_ld_compile): Likewise.
+ (default_ld_assemble, default_ld_nm): Likewise.
+
+Fri Sep 8 17:15:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-cdtest/cdtest.exp: If the compiler does not exist, mark the
+ tests as untested rather than unresolved.
+
+Wed Aug 23 10:46:38 1995 Ian Lance Taylor (ian@cygnus.com)
+
+ * ld-sh/sh.exp: Call prune_system_crud on the output of cmp.
+
+Tue Aug 15 17:35:35 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/script.exp: Split script verification into a proc.
+ Add simple test of MRI script.
+ * ld-scripts/scriptm.t: New file.
+
+Wed Jul 26 11:38:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-sh/sh.exp: Mark `SH confirm relaxing' test unresolved when
+ appropriate.
+
+Mon Jul 24 15:34:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/default.exp: Define objcopy if it is not defined.
+ * ld-sh/*: New tests for SH relaxing.
+
+ * ld-empic/empic.exp: If $CC does not exist, call untested rather
+ than unresolved.
+
+Thu Jul 20 15:09:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-undefined/undefined.exp: If $CC does not exist, mark the
+ tests as untested rather than unresolved. Clear ELF xfails for
+ mips*, not just mips.
+
+Tue Jul 18 12:00:41 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-undefined/undefined.exp: Add setup_xfail for sh-*-* for
+ undefined line test.
+
+Fri Jul 14 13:07:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-undefined/undefined.exp: New test, to check reporting of
+ undefined symbols.
+ * ld-undefined/undefined.c: New file.
+
+Mon Jul 10 11:13:39 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-versados/versados.exp: If a test fails, report it correctly:
+ don't try to run the next test, and don't report a pass as well as
+ a fail.
+
+Mon Jul 3 14:26:37 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * ld/testsuite/versados/(t1,t2).ld: End in newlines.
+
+Mon May 22 20:19:38 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * lib/ld.exp (default_ld_compile): If cc argument is multiple
+ words, use only the first when trying to verify the availability
+ of the compiler.
+
+Mon Feb 6 11:46:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ld-scripts/defined.t: Mention .data and .bss explicitly.
+
+Tue Jan 24 14:51:48 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: If not in the ld build directory,
+ call untested for each test, rather than ignoring it. If one test
+ fails, go on to the next one instead of returning.
+ * ld-cdtest/cdtest.exp: If compilations fail, mark tests as
+ unresolved.
+ * ld-empic/empic.exp: Likewise. Also, always pass the same test
+ name to pass or fail.
+ * ld-shared/shared.exp: Likewise. Also, always run all tests.
+ * ld-scripts/defined.exp: If as or nm fail, mark test as
+ unresolved. Always pass the same test name to pass or fail.
+ * ld-scripts/script.exp: Likewise.
+ * ld-scripts/sizeof.exp: Likewise.
+
+Wed Jan 11 11:48:31 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ld-scripts/sizeof.exp: New test, based on bug report from
+ anders.blomdell@control.lth.se.
+ * ld-scripts/sizeof.s: New file.
+ * ld-scripts/sizeof.t: New file.
+
+Wed Jan 4 18:56:27 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * lib/ld.exp: Use [which $ld] rather than [file exists $ld] to see
+ if the linker exists.
+
+Wed Dec 14 16:39:03 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * lib/ld.exp (prune_system_crud): Define if not already defined,
+ in case the user isn't using the newest DejaGnu version that we
+ haven't released to the net yet.
+
+Fri Dec 2 14:17:02 1994 Ian Lance Taylor <ian@rtl.cygnus.com>
+
+ * config/default.exp: Define objdump if it is not defined.
+ * ld-empic/*: New tests to test -membedded-pic code.
+
+Mon Nov 28 11:24:36 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ld-bootstrap/bootstrap.exp: Pass cmp output through
+ prune_system_crud.
+ * ld-cdtest/cdtest.exp: Pass diff output through
+ prune_system_crud.
+ * ld-shared/shared.exp: Likewise.
+
+ * config/default.exp: Remove unused and useless proc ld_load.
+
+Sun Oct 30 13:02:34 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * lib/ld.exp (default_ld_compile): Remove the output file before
+ compiling.
+
+ * ld-shared/shared.exp: Move common test code into a procedure.
+ Add tests for compiling the non shared code PIC.
+ * ld-shared/main.c (main): Call main_called, and print the result.
+ * ld-shared/shared.dat: Adjust accordingly.
+
+Thu Oct 27 17:30:12 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * ld-shared: New directory, with new files to test generating ELF
+ shared libraries.
+
+ * lib/ld.exp (default_ld_compile): If the compilation worked, but
+ no object file was created, check to see if the compiler foolishly
+ ignored the -o switch when compiling, and move the resulting
+ object if it did.
+
+Thu Sep 29 12:36:51 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * VMS does not permits `.' in directory names. Renamed
+ ld.bootstrap to ld-bootstrap, ld.cdtest to ld-cdtest, and
+ ld.scripts to ld-scripts.
+
+Wed Sep 28 12:18:54 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/default.exp: Set variables as and nm. Create tmpdir if
+ it does not already exist.
+ * ld.bootstrap/bootstrap.exp: Don't create tmpdir here.
+ * ld.cdtest/cdtest.exp: Likewise.
+ * ld.scripts/defined.exp: Likewise. Also, don't set as and nm
+ here. Change perror for no variables found to fail.
+ * ld.scripts/script.exp: New test.
+ * ld.scripts/script.t, ld.scripts/script.s: New files.
+
+Tue Sep 27 14:59:51 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * ld.scripts: New directory.
+ * ld.scripts/defined.exp, ld.scripts/defined.s: New files.
+ * ld.scripts/defined.t: New file.
+ * lib/ld.exp (default_ld_simple_link): New function.
+ (default_ld_assemble, default_ld_nm): New functions.
+ * config/default.exp: Rename from unix-ld.exp.
+ (ld_simple_link, ld_assemble, ld_nm): New functions.
+
+ * config/unix-ld.exp: Set ld using findfile.
+ * lib/ld.exp (default_ld_relocate): Return a value. Change format
+ of log messages.
+ (default_ld_compile): Likewise.
+ (default_ld_link): Likewise. Also, don't include $BFDLIB and
+ $LIBIBERTY in link.
+ * ld.bootstrap/bootstrap.exp: Rewrite.
+ * ld.cdtest/cdtest.exp: Rewrite.
+ * ld.cdtest/cdtest-foo.cc: Update from top level ld directory.
+ * ld.cdtest/cdtest-foo.h: Likewise.
+ * ld.cdtest/cdtest-main.cc: Likewise.
+
+Fri May 27 09:35:04 1994 Ken Raeburn (raeburn@cygnus.com)
+
+ * ld.cdtest/cdtest.exp: Don't look for $result before it's
+ defined.
+
+Tue May 17 15:06:49 1994 Bill Cox (bill@rtl.cygnus.com)
+
+ * ld.bootstrap/bootstrap.exp, lib/ld.exp: Replace error proc
+ calls with perror calls.
+
+Wed May 11 16:47:46 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * ld.cdtest/cdtest-bar.cc: Renamed from cdtest-func.cc.
+ * ld.cdtest/cdtest.exp: Adjusted.
+
+Fri Jan 28 13:25:41 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * lib/ld.exp (simple_diff): Indicate failure if files have
+ different numbers of lines. Don't muck with $differences to avoid
+ indicating a pass, just return.
+
+ * testsuite/ld.cdtest/{cdtest-foo.h,cdtest-foo.cc,cdtest-main.cc}:
+ Fix test case to be valid ANSI C++. Don't require use of header
+ files, so "../gcc/xgcc -B../gcc/" can be used for CXX.
+ * testsuite/ld.cdtest/cdtest.exp: Combine "rm" lines. Add some
+ commentary on things that are still broken with this test case.
+
+Fri Sep 10 09:58:23 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * testsuite/ld.cdtest/cdtest.exp: Added CXXFLAGS to compile stage.
+
+Thu Aug 12 16:05:37 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * testsuite/lib/ld.exp: add compiler and linker support
+ * testsuite/config/unix-ld.exp: add compiler and linker support
+ * testsuite/ld.bootstrap/bootstrap.exp: fixed to do partial links
+ * testsuite/ld.cdtest/cdtest.exp: constructor/destructor testscase
+
+Wed Aug 4 21:00:18 1993 Jeffrey Wheat (cassidy@cygnus.com)
+
+ * testsuite/lib/ld.exp: new file
+ * testsuite/config/unix-ld.exp: new file
+ * testsuite/ld.bootstrap/bootstrap.exp: new file
diff --git a/ld/testsuite/config/default.exp b/ld/testsuite/config/default.exp
new file mode 100644
index 00000000000..0a0fdea16d5
--- /dev/null
+++ b/ld/testsuite/config/default.exp
@@ -0,0 +1,171 @@
+# Basic expect script for LD Regression Tests
+# Copyright (C) 1993, 94, 95, 97, 98, 1999 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Jeffrey Wheat (cassidy@cygnus.com)
+#
+
+if ![info exists ld] then {
+ set ld [findfile $base_dir/ld-new $base_dir/ld-new [transform ld]]
+}
+
+if ![info exists as] then {
+ set as [findfile $base_dir/../gas/as-new $base_dir/../gas/as-new [transform as]]
+}
+
+if ![info exists nm] then {
+ set nm [findfile $base_dir/../binutils/nm-new $base_dir/../binutils/nm-new [transform nm]]
+}
+
+if ![info exists objdump] then {
+ set objdump [findfile $base_dir/../binutils/objdump]
+}
+
+if ![info exists objcopy] then {
+ set objcopy [findfile $base_dir/../binutils/objcopy]
+}
+
+if ![info exists ar] then {
+ set ar [findfile $base_dir/../binutils/ar]
+}
+
+if ![info exists strip] then {
+ set strip [findfile $base_dir/../binutils/strip-new $base_dir/../binutils/strip-new [transform strip]]
+}
+
+if {![file isdirectory tmpdir]} then {
+ catch "exec mkdir tmpdir" status
+}
+
+# Make a symlink from tmpdir/as to the assembler in the build tree, so
+# that we can use a -B option to gcc to force it to use the newly
+# built assembler.
+if {![file isdirectory tmpdir/gas]} then {
+ catch "exec mkdir tmpdir/gas" status
+ catch "exec ln -s ../../../gas/as-new tmpdir/gas/as" status
+}
+set gcc_gas_flag "-B[pwd]/tmpdir/gas/"
+
+# load the utility procedures
+load_lib ld-lib.exp
+
+proc get_link_files {varname} {
+ global $varname
+ global target_triplet
+ global srcdir
+ global CC
+ if ![info exists $varname] {
+ set status [catch "exec sh -c \"host='$target_triplet' && CC='$CC' && . $srcdir/../configure.host && eval echo \\$$varname\"" result]
+ if $status { error "Error getting native link files: $result" }
+ set $varname $result
+ }
+}
+
+proc get_target_emul {} {
+ global target_triplet
+ global srcdir
+ set status [catch "exec sh -c \"targ='$target_triplet' && . $srcdir/../configure.tgt && echo \\\$targ_emul\"" result]
+ if $status { error "Error getting emulation name: $result" }
+ return $result
+}
+
+if [isnative] {
+ foreach x {HOSTING_CRT0 HOSTING_LIBS} {
+ get_link_files $x
+ }
+} else {
+ foreach x {HOSTING_CRT0 HOSTING_LIBS} { set $x "" }
+}
+if ![info exists HOSTING_EMU] { set HOSTING_EMU "-m [get_target_emul]" }
+
+#
+# ld_version -- extract and print the version number of ld compiler (GCC)
+#
+proc ld_version {} {
+ global ld
+ default_ld_version $ld
+}
+
+#
+# ld_exit -- just a stub for ld
+#
+proc ld_exit {} {
+}
+
+#
+# ld_start
+# relink the linker
+#
+proc ld_start { ld target } {
+ #
+}
+
+#
+# ld_relocate
+# link an object using relocation
+#
+proc ld_relocate { ld target objects } {
+ default_ld_relocate $ld $target $objects
+}
+
+#
+# ld_link
+# link a program using ld
+#
+proc ld_link { ld target objects } {
+ default_ld_link $ld $target $objects
+}
+
+#
+# ld_simple_link
+# link a program using ld, without including any libraries
+#
+proc ld_simple_link { ld target objects } {
+ default_ld_simple_link $ld $target $objects
+}
+
+#
+# ld_compile
+# compile an object using $cc
+#
+proc ld_compile { cc source object } {
+ default_ld_compile $cc $source $object
+}
+
+#
+# ld_assemble
+# assemble a file
+#
+proc ld_assemble { as source object } {
+ default_ld_assemble $as $source $object
+}
+
+#
+# ld_nm
+# run nm on a file
+#
+proc ld_nm { nm object } {
+ default_ld_nm $nm $object
+}
+
+#
+# ld_exec
+# execute ithe target
+#
+proc ld_exec { target output } {
+ default_ld_exec $target $output
+}
+
diff --git a/ld/testsuite/ld-bootstrap/bootstrap.exp b/ld/testsuite/ld-bootstrap/bootstrap.exp
new file mode 100644
index 00000000000..0e4b820cb20
--- /dev/null
+++ b/ld/testsuite/ld-bootstrap/bootstrap.exp
@@ -0,0 +1,103 @@
+# Expect script for LD Bootstrap Tests
+# Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Jeffrey Wheat (cassidy@cygnus.com)
+# Rewritten by Ian Lance Taylor (ian@cygnus.com)
+#
+
+# Make sure that ld can bootstrap itself.
+
+# This test can only be run if ld generates native executables.
+if ![isnative] {
+ return
+}
+
+# Bootstrap ld. First link the object files together using -r, in
+# order to test -r. Then link the result into an executable, ld1, to
+# really test -r. Use ld1 to link a fresh ld, ld2. Use ld2 to link a
+# new ld, ld3. ld2 and ld3 should be identical.
+
+foreach flags {"" "--static" "--traditional-format" "--no-keep-memory"} {
+ if {"$flags" != ""} {
+ set testname "bootstrap with $flags"
+ } else {
+ set testname "bootstrap"
+ }
+
+ # This test can only be run if we have the ld build directory,
+ # since we need the object files.
+ if {$ld != "$objdir/ld-new"} {
+ untested $testname
+ continue
+ }
+
+ # If we only have a shared libbfd, we probably can't run the
+ # --static test.
+ if { $flags == "--static" && ! [string match "*libbfd.a*" $BFDLIB] } then {
+ untested $testname
+ continue
+ }
+
+ if ![ld_relocate $ld tmpdir/ld-partial.o "$flags $OFILES"] {
+ fail $testname
+ continue
+ }
+
+ # On AIX, you need to specify an import list when using --static.
+ # You only want the import list when creating the final
+ # executable.
+ if [istarget "*-*-aix*"] {
+ if {"$flags" == "--static"} {
+ set flags "--static -bI:/lib/syscalls.exp"
+ }
+ }
+
+ # On Irix 5, linking with --static only works if all the files are
+ # compiled using -non_shared.
+ if {"$flags" == "--static"} {
+ setup_xfail "mips*-*-irix5*"
+ }
+
+ if ![ld_link $ld tmpdir/ld1 "$flags tmpdir/ld-partial.o $BFDLIB $LIBIBERTY"] {
+ fail $testname
+ continue
+ }
+
+ if ![ld_link tmpdir/ld1 tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY"] {
+ fail $testname
+ continue
+ }
+
+ if ![ld_link tmpdir/ld2 tmpdir/ld3 "$flags $OFILES $BFDLIB $LIBIBERTY"] {
+ fail $testname
+ continue
+ }
+
+ send_log "cmp tmpdir/ld2 tmpdir/ld3\n"
+ verbose "cmp tmpdir/ld2 tmpdir/ld3"
+ catch "exec cmp tmpdir/ld2 tmpdir/ld3" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ if [string match "" $exec_output] then {
+ pass $testname
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output" 1
+
+ fail $testname
+ }
+}
diff --git a/ld/testsuite/ld-cdtest/cdtest-bar.cc b/ld/testsuite/ld-cdtest/cdtest-bar.cc
new file mode 100644
index 00000000000..79000e33954
--- /dev/null
+++ b/ld/testsuite/ld-cdtest/cdtest-bar.cc
@@ -0,0 +1,17 @@
+// test program for Class Foo
+
+#include "cdtest-foo.h"
+
+static Foo static_foo( "static_foo");
+
+Foo f()
+{
+ Foo x;
+ return x;
+}
+
+void g()
+{
+ Foo other_foo1 = Foo( "other_foo1"), other_foo2 = Foo( "other_foo2");
+ other_foo2 = other_foo1;
+}
diff --git a/ld/testsuite/ld-cdtest/cdtest-foo.cc b/ld/testsuite/ld-cdtest/cdtest-foo.cc
new file mode 100644
index 00000000000..615e33cea78
--- /dev/null
+++ b/ld/testsuite/ld-cdtest/cdtest-foo.cc
@@ -0,0 +1,89 @@
+// Class Foo
+#pragma implementation
+
+
+// We don't use header files, since we only want to see, whether the
+// compiler is installed properly.
+//
+#if (__GNUG__ == 2)
+typedef __SIZE_TYPE__ size_t;
+#else
+typedef unsigned int size_t;
+#endif
+
+extern "C" {
+ char *strncpy (char* dest, const char* dest, size_t len);
+ int printf (const char*, ...);
+};
+
+#include "cdtest-foo.h"
+
+int Foo::foos = 0;
+
+void Foo::init_foo ()
+{
+ printf ("BROKENLY calling Foo::init_foo from __init_start; size_of(Foo) = %d\n", sizeof(Foo));
+ foos = FOOLISH_NUMBER;
+}
+
+
+Foo::Foo ()
+{
+ i = ++foos;
+ strncpy (message, "default-foo", len);
+#ifdef WITH_ADDR
+ printf ("Constructing Foo(%d) \"default-foo\" at %08x\n", i, this);
+#else
+ printf ("Constructing Foo(%d) \"default-foo\"\n", i);
+#endif
+}
+
+Foo::Foo (char* msg)
+{
+ i = ++foos;
+ strncpy( message, msg, len);
+#ifdef WITH_ADDR
+ printf ( "Constructing Foo(%d) \"%s\" at %08x\n", i, message, this);
+#else
+ printf ( "Constructing Foo(%d) \"%s\"\n", i, message);
+#endif
+}
+
+
+Foo::Foo (const Foo& foo)
+{
+ i = ++foos;
+#ifdef WITH_ADDR
+ printf ("Initializing Foo(%d) \"%s\" at %08x with Foo(%d) %08x\n",
+ i, foo.message, this, foo.i, &foo);
+#else
+ printf ("Initializing Foo(%d) \"%s\" with Foo(%d)\n",i, foo.message, foo.i);
+#endif
+ for ( int k = 0; k < FOO_MSG_LEN; k++) message[k] = foo.message[k];
+}
+
+
+Foo& Foo::operator= (const Foo& foo)
+{
+#ifdef WITH_ADDR
+ printf ("Copying Foo(%d) \"%s\" at %08x to Foo(%d) %08x\n",
+ foo.i, foo.message, &foo, i, this);
+#else
+ printf ("Copying Foo(%d) \"%s\" to Foo(%d)\n", foo.i, foo.message, i);
+#endif
+ for ( int k = 0; k < FOO_MSG_LEN; k++) message[k] = foo.message[k];
+ return *this;
+}
+
+
+Foo::~Foo ()
+{
+ foos--;
+#ifdef WITH_ADDR
+ printf ("Destructing Foo(%d) \"%s\" at %08x (remaining foos: %d)\n",
+ i, message, this, foos);
+#else
+ printf ("Destructing Foo(%d) \"%s\" (remaining foos: %d)\n",
+ i, message, foos);
+#endif
+}
diff --git a/ld/testsuite/ld-cdtest/cdtest-foo.h b/ld/testsuite/ld-cdtest/cdtest-foo.h
new file mode 100644
index 00000000000..0afe52a829f
--- /dev/null
+++ b/ld/testsuite/ld-cdtest/cdtest-foo.h
@@ -0,0 +1,24 @@
+// Class Foo
+
+#pragma interface
+
+#define FOOLISH_NUMBER -4711
+
+#ifndef FOO_MSG_LEN
+#define FOO_MSG_LEN 80
+#endif
+
+class Foo {
+ static int foos;
+ int i;
+ static const int len = FOO_MSG_LEN;
+ char message[len];
+public:
+ static void init_foo ();
+ static int nb_foos() { return foos; }
+ Foo();
+ Foo( char* message);
+ Foo(const Foo&);
+ Foo & operator= (const Foo&);
+ ~Foo ();
+};
diff --git a/ld/testsuite/ld-cdtest/cdtest-main.cc b/ld/testsuite/ld-cdtest/cdtest-main.cc
new file mode 100644
index 00000000000..4b99b5c5f0f
--- /dev/null
+++ b/ld/testsuite/ld-cdtest/cdtest-main.cc
@@ -0,0 +1,40 @@
+// main program for Class Foo
+
+extern "C" {
+// Some <assert.h> implementations (e.g. SUNOS 4.1) are broken,
+// in that they require <stdio.h>. But, if gcc/g++ is installed
+// correctly, you should get gcc's assert.h.
+// If the compile fails, it means the wrong include files are in use!
+#include <assert.h>
+};
+#include "cdtest-foo.h"
+
+extern "C" void __init_start();
+
+extern Foo f(void);
+extern void g(void);
+
+/* This function should *not* be called by the environment. There is
+ no way in C++ to ``run something after the initializers but before main()''.
+ The library that depends on this (NIHCL) is broken. -- John Gilmore
+ We leave this here to test that future changes to the compiler
+ do not re-introduce this losing ``feature''. */
+void
+__init_start()
+{
+ Foo::init_foo();
+}
+
+static Foo static_foo( "static_foo");
+
+main()
+{
+ assert (Foo::nb_foos() == 2);
+ Foo automatic_foo( "automatic_foo");
+ Foo bla_foo = f();
+ assert (Foo::nb_foos() == 4);
+ g();
+ assert (Foo::nb_foos() == 4);
+ // `automatic_foo' and `bla_foo' are destructed here
+}
+
diff --git a/ld/testsuite/ld-cdtest/cdtest.dat b/ld/testsuite/ld-cdtest/cdtest.dat
new file mode 100644
index 00000000000..39be0dbc2c7
--- /dev/null
+++ b/ld/testsuite/ld-cdtest/cdtest.dat
@@ -0,0 +1,15 @@
+Constructing Foo(1) "static_foo"
+Constructing Foo(2) "static_foo"
+Constructing Foo(3) "automatic_foo"
+Constructing Foo(4) "default-foo"
+Initializing Foo(5) "default-foo" with Foo(4)
+Destructing Foo(4) "default-foo" (remaining foos: 4)
+Constructing Foo(5) "other_foo1"
+Constructing Foo(6) "other_foo2"
+Copying Foo(5) "other_foo1" to Foo(6)
+Destructing Foo(6) "other_foo1" (remaining foos: 5)
+Destructing Foo(5) "other_foo1" (remaining foos: 4)
+Destructing Foo(5) "default-foo" (remaining foos: 3)
+Destructing Foo(3) "automatic_foo" (remaining foos: 2)
+Destructing Foo(2) "static_foo" (remaining foos: 1)
+Destructing Foo(1) "static_foo" (remaining foos: 0)
diff --git a/ld/testsuite/ld-cdtest/cdtest.exp b/ld/testsuite/ld-cdtest/cdtest.exp
new file mode 100644
index 00000000000..ccbe35e3709
--- /dev/null
+++ b/ld/testsuite/ld-cdtest/cdtest.exp
@@ -0,0 +1,100 @@
+# Expect script for LD cdtest Tests
+# Copyright (C) 1993,1994,1995, 1997 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Jeffrey Wheat (cassidy@cygnus.com)
+# Rewritten by Ian Lance Taylor (ian@cygnus.com)
+#
+
+# Make sure that constructors are handled correctly.
+
+set test1 "cdtest"
+set test2 "cdtest with -Ur"
+
+# This test requires running the executable generated by ld.
+if ![isnative] {
+ return
+}
+
+if { [which $CXX] == 0 } {
+ untested $test1
+ untested $test2
+ return
+}
+
+if { ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/cdtest-foo.cc tmpdir/cdtest-foo.o]
+ || ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/cdtest-bar.cc tmpdir/cdtest-bar.o]
+ || ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/cdtest-main.cc tmpdir/cdtest-main.o] } {
+ unresolved $test1
+ unresolved $test2
+ return
+}
+
+if ![ld_link $ld tmpdir/cdtest {tmpdir/cdtest-foo.o tmpdir/cdtest-bar.o tmpdir/cdtest-main.o}] {
+ fail $test1
+} else {
+ send_log "tmpdir/cdtest >tmpdir/cdtest.out\n"
+ verbose "tmpdir/cdtest >tmpdir/cdtest.out"
+ catch "exec tmpdir/cdtest >tmpdir/cdtest.out" exec_output
+ if ![string match "" $exec_output] then {
+ send_log "$exec_output\n"
+ verbose "$exec_output" 1
+ fail $test1
+ } else {
+ send_log "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat\n"
+ verbose "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat"
+ catch "exec diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ if [string match "" $exec_output] then {
+ pass $test1
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output" 1
+ fail $test1
+ }
+ }
+}
+
+if ![ld_relocate $ld tmpdir/cdtest.o {-Ur tmpdir/cdtest-foo.o tmpdir/cdtest-bar.o tmpdir/cdtest-main.o}] {
+ fail $test2
+} else {
+ if ![ld_link $ld tmpdir/cdtest tmpdir/cdtest.o] {
+ fail $test2
+ } else {
+ send_log "tmpdir/cdtest >tmpdir/cdtest.out\n"
+ verbose "tmpdir/cdtest >tmpdir/cdtest.out"
+ catch "exec tmpdir/cdtest >tmpdir/cdtest.out" exec_output
+ if ![string match "" $exec_output] then {
+ send_log "$exec_output\n"
+ verbose "$exec_output" 1
+ fail $test2
+ } else {
+ send_log "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat\n"
+ verbose "diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat"
+ catch "exec diff tmpdir/cdtest.out $srcdir/$subdir/cdtest.dat" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ if [string match "" $exec_output] then {
+ pass $test2
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output" 1
+ fail $test2
+ }
+ }
+ }
+}
diff --git a/ld/testsuite/ld-checks/asm.s b/ld/testsuite/ld-checks/asm.s
new file mode 100644
index 00000000000..e4e0c332470
--- /dev/null
+++ b/ld/testsuite/ld-checks/asm.s
@@ -0,0 +1,14 @@
+.text
+ .global foo
+foo:
+ .long 0x12345678
+
+.data
+ .global bar
+bar:
+ .long 0x87654321
+
+ .lcomm 0x12
+
+
+ \ No newline at end of file
diff --git a/ld/testsuite/ld-checks/checks.exp b/ld/testsuite/ld-checks/checks.exp
new file mode 100644
index 00000000000..af3ef7d70a4
--- /dev/null
+++ b/ld/testsuite/ld-checks/checks.exp
@@ -0,0 +1,72 @@
+# Expect script for LD section checks tests
+# Copyright (C) 1999 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Nick Clifton (nickc@cygnus.com)
+
+proc section_check {} {
+ global ld_flags
+ global as
+ global ld
+ global srcdir
+ global subdir
+
+ set test "check sections"
+
+ set ldflags "--check-sections"
+
+ if { ![ld_assemble $as $srcdir/$subdir/asm.s tmpdir/asm.o]} {
+ unresolved $test
+ return
+ }
+
+ if ![ld_simple_link $ld tmpdir/asm.x "$ldflags tmpdir/asm.o"] {
+ fail "$test : using default linker script"
+ } else {
+ pass $test
+ }
+
+ # Change the linker flags so that our "buggy" linker
+ # script is used.
+ set ldflags "--check-sections -T $srcdir/$subdir/script -e foo"
+
+ # Perform the equivalent of invoking ld_simple_link
+ # except that we need to massage the output futher.
+
+ catch "exec $ld -o tmpdir/asm.x $ldflags tmpdir/asm.o" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ # Make sure that we got some output from the linker
+ if [string match "" $exec_output] then {
+ fail "$test - error message expected but not found"
+ }
+
+ # Now remove our expected error message
+ regsub -all ".*: section .data .* overlaps section .text .*" $exec_output "" exec_output
+
+ # And check to see if anything else, (unexpected) was left
+ if [string match "" $exec_output] then {
+ pass $test
+ } else {
+ verbose -log "Unexpected linker message(s): $exec_output"
+
+ fail "$test - using erroneous linker script"
+ }
+}
+
+section_check
+
+
diff --git a/ld/testsuite/ld-checks/script b/ld/testsuite/ld-checks/script
new file mode 100644
index 00000000000..44c6a08420a
--- /dev/null
+++ b/ld/testsuite/ld-checks/script
@@ -0,0 +1,6 @@
+SECTIONS {
+ .text 0x100 : { *(.text) }
+ .data 0x100 : AT (0x100) { *(.data) }
+ .bss 0x100 : AT (0x4000) { *(.bss) }
+}
+
diff --git a/ld/testsuite/ld-elfvers/vers.exp b/ld/testsuite/ld-elfvers/vers.exp
new file mode 100644
index 00000000000..5dfaa93346e
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers.exp
@@ -0,0 +1,808 @@
+# Expect script for ld-version tests
+# Copyright (C) 1997, 1998 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Eric Youngdale (eric@andante.jic.com)
+
+#
+
+# This test can only be run if ld generates native executables.
+if ![isnative] then {return}
+
+# This test can only be run on a couple of ELF platforms.
+# Square bracket expressions seem to confuse istarget.
+# This is similar to the test that is used in ld-shared, BTW.
+if { ![istarget i?86-*-sysv4*] \
+ && ![istarget i?86-*-unixware] \
+ && ![istarget i?86-*-elf*] \
+ && ![istarget i?86-*-linux*] \
+ && ![istarget m68k-*-linux*] \
+ && ![istarget mips*-*-irix5*] \
+ && ![istarget powerpc-*-elf*] \
+ && ![istarget powerpc-*-linux*] \
+ && ![istarget powerpc-*-sysv4*] \
+ && ![istarget sparc*-*-elf] \
+ && ![istarget sparc*-*-solaris2*]
+ && ![istarget alpha*-*-linux*] } {
+ return
+}
+
+if { [istarget i?86-*-linuxaout*] \
+ || [istarget i?86-*-linuxoldld*] \
+ || [istarget m68k-*-linuxaout*] } {
+ return
+}
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ return
+}
+
+set diff diff
+set tmpdir tmpdir
+set VOBJDUMP_FLAGS --private-headers
+set DOBJDUMP_FLAGS --dynamic-syms
+set SOBJDUMP_FLAGS --syms
+set shared --shared
+set script --version-script
+
+proc test_ar { test lib object expect } {
+ global ar
+ global nm
+ global tmpdir
+ global srcdir
+ global subdir
+ global diff
+
+ verbose -log "$ar -cr $tmpdir/$lib $tmpdir/$object"
+ catch "exec $ar -cr $tmpdir/$lib $tmpdir/$object" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if ![string match "" $exec_output] {
+ verbose -log "$exec_output"
+ unresolved "$test"
+ return
+ }
+
+ verbose -log "$nm --print-armap $tmpdir/$lib | grep \" in \" | egrep \"VERS\\|bar\\|foo\" | sort > $tmpdir/nm.out"
+
+ catch "exec $nm --print-armap $tmpdir/$lib | grep \\\ in\\\ | egrep VERS\\\|bar\\\|foo | sort > $tmpdir/nm.out" exec_output
+ if [string match "" $exec_output] then {
+ catch "exec $diff -q $tmpdir/nm.out $srcdir/$subdir/$expect" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ pass $test
+ return
+ } else {
+ verbose -log "$exec_output"
+ fail "$test"
+ return
+ }
+ } else {
+ verbose -log "$exec_output"
+ fail "$test"
+ }
+}
+
+#
+# objdump_emptysymstuff
+# Check non-dynamic symbols and make sure there are none with '@'.
+#
+proc objdump_emptysymstuff { objdump object } {
+ global SOBJDUMP_FLAGS
+ global version_output
+ global diff
+
+ if ![info exists SOBJDUMP_FLAGS] { set SOBJDUMP_FLAGS "" }
+
+ verbose -log "$objdump $SOBJDUMP_FLAGS $object | sed -n /\@/p"
+
+ catch "exec $objdump $SOBJDUMP_FLAGS $object | sed -n /\@/p" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+# We shouldn't get anything here.
+ return 1
+ } else {
+# it is not normal to come here - we have no output to compare.
+ verbose -log "$exec_output"
+ verbose -log "objdump_emptysymstuff: did not expect any output from objdump"
+ return 0
+ }
+
+}
+
+#
+# objdump_emptydynsymstuff
+# Check dynamic symbols and make sure there are none with '@'.
+#
+proc objdump_emptydynsymstuff { objdump object } {
+ global DOBJDUMP_FLAGS
+ global version_output
+ global diff
+
+ if ![info exists VOBJDUMP_FLAGS] { set VOBJDUMP_FLAGS "" }
+
+ verbose -log "$objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p"
+
+ catch "exec $objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+# We shouldn't get anything here.
+ return 1
+ } else { if [string match "*objdump: *: not a dynamic object" $exec_output] then {
+ return 1
+ } else {
+# it is not normal to come here - we have no output to compare.
+ verbose -log "$exec_output"
+ verbose -log "objdump_emptydynsymstuff: did not expect any output from objdump"
+ return 0
+ } }
+}
+
+#
+# objdump_emptyverstuff
+# Make sure there is no version information
+#
+proc objdump_emptyverstuff { objdump object } {
+ global VOBJDUMP_FLAGS
+ global version_output
+ global diff
+ global tmpdir
+
+ if {[which $objdump] == 0} then {
+ perror "$objdump does not exist"
+ return 0
+ }
+
+ if ![info exists VOBJDUMP_FLAGS] { set VOBJDUMP_FLAGS "" }
+
+ verbose -log "$objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p > $tmpdir/objdump.out"
+
+ catch "exec $objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+# it is normal to fail here - we have no output to compare.
+ return 1
+ } else { if { [string match "*libc*" $exec_output] } then {
+# this probably means that there is version information in libc, so we
+# can't really perform this test.
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ verbose -log "objdump_emptyverstuff: did not expect any output from objdump"
+ return 0
+ } }
+
+}
+
+#
+# objdump_symstuff
+# Dump non-dynamic symbol stuff and make sure that it is sane.
+#
+proc objdump_symstuff { objdump object expectfile } {
+ global SOBJDUMP_FLAGS
+ global version_output
+ global diff
+ global tmpdir
+
+ if ![info exists SOBJDUMP_FLAGS] { set SOBJDUMP_FLAGS "" }
+
+ verbose -log "$objdump $SOBJDUMP_FLAGS $object | grep \@ | sort > $tmpdir/objdump.out"
+
+ catch "exec $objdump $SOBJDUMP_FLAGS $object | grep \@ | sort > $tmpdir/objdump.out" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+
+# Now do a line-by-line comparison to effectively diff the darned things
+# The stuff coming from the expectfile is actually a regex, so we can
+# skip over the actual addresses and so forth. This is currently very
+# simpleminded - it expects a one-to-one correspondence in terms of line
+# numbers.
+
+ if [file exists $expectfile] then {
+ set file_a [open $expectfile r]
+ } else {
+ perror "$expectfile doesn't exist"
+ return 0
+ }
+
+ if [file exists $tmpdir/objdump.out] then {
+ set file_b [open $tmpdir/objdump.out r]
+ } else {
+ perror "$tmpdir/objdump.out doesn't exist"
+ return 0
+ }
+
+ verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2
+
+ set eof -1
+ set differences 0
+
+ while { [gets $file_a line] != $eof } {
+ if [regexp "^#.*$" $line] then {
+ continue
+ } else {
+ lappend list_a $line
+ }
+ }
+ close $file_a
+
+ while { [gets $file_b line] != $eof } {
+ if [regexp "^#.*$" $line] then {
+ continue
+ } else {
+ lappend list_b $line
+ }
+ }
+ close $file_b
+
+ for { set i 0 } { $i < [llength $list_a] } { incr i } {
+ set line_a [lindex $list_a $i]
+ set line_b [lindex $list_b $i]
+
+
+ verbose "\t$expectfile: $i: $line_a" 3
+ verbose "\t/tmp/objdump.out: $i: $line_b" 3
+ if [regexp $line_a $line_b] then {
+ continue
+ } else {
+ verbose -log "\t$expectfile: $i: $line_a"
+ verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
+
+ return 0
+ }
+ }
+
+ if { [llength $list_a] != [llength $list_b] } {
+ verbose -log "Line count"
+ return 0
+ }
+
+ if $differences<1 then {
+ return 1
+ }
+
+ return 0
+ } else {
+ verbose -log "$exec_output"
+ return 0
+ }
+
+}
+
+#
+# objdump_dymsymstuff
+# Dump dynamic symbol stuff and make sure that it is sane.
+#
+proc objdump_dynsymstuff { objdump object expectfile } {
+ global DOBJDUMP_FLAGS
+ global version_output
+ global diff
+ global tmpdir
+
+ if ![info exists DOBJDUMP_FLAGS] { set DOBJDUMP_FLAGS "" }
+
+ verbose -log "$objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p | sort | uniq > $tmpdir/objdump.out"
+
+ catch "exec $objdump $DOBJDUMP_FLAGS $object | sed -n /VERS/p\\\;/show/p | sort | uniq > $tmpdir/objdump.out" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+
+# Now do a line-by-line comparison to effectively diff the darned things
+# The stuff coming from the expectfile is actually a regex, so we can
+# skip over the actual addresses and so forth. This is currently very
+# simpleminded - it expects a one-to-one correspondence in terms of line
+# numbers.
+
+ if [file exists $expectfile] then {
+ set file_a [open $expectfile r]
+ } else {
+ warning "$expectfile doesn't exist"
+ return 0
+ }
+
+ if [file exists $tmpdir/objdump.out] then {
+ set file_b [open $tmpdir/objdump.out r]
+ } else {
+ fail "$tmpdir/objdump.out doesn't exist"
+ return 0
+ }
+
+ verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2
+
+ set eof -1
+ set differences 0
+
+ while { [gets $file_a line] != $eof } {
+ if [regexp "^#.*$" $line] then {
+ continue
+ } else {
+ lappend list_a $line
+ }
+ }
+ close $file_a
+
+ while { [gets $file_b line] != $eof } {
+ if [regexp "^#.*$" $line] then {
+ continue
+ } else {
+ lappend list_b $line
+ }
+ }
+ close $file_b
+
+ for { set i 0 } { $i < [llength $list_b] } { incr i } {
+ set line_b [lindex $list_b $i]
+
+# The tests are rigged so that we should never export a symbol with the
+# word 'hide' in it. Thus we just search for it, and bail if we find it.
+ if [regexp "hide" $line_b] then {
+ verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
+
+ return 0
+ }
+
+ verbose "\t$expectfile: $i: $line_b" 3
+
+ # We can't assume that the sort is consistent across
+ # systems, so we must check each regexp. When we find a
+ # regexp, we null it out, so we don't match it twice.
+ for { set j 0 } { $j < [llength $list_a] } { incr j } {
+ set line_a [lindex $list_a $j]
+
+ if [regexp $line_a $line_b] then {
+ lreplace $list_a $j $j "CAN NOT MATCH"
+ break
+ }
+ }
+
+ if { $j >= [llength $list_a] } {
+ verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
+
+ return 0
+ }
+ }
+
+ if { [llength $list_a] != [llength $list_b] } {
+ verbose -log "Line count"
+ return 0
+ }
+
+ if $differences<1 then {
+ return 1
+ }
+
+ return 0
+ } else {
+ verbose -log "$exec_output"
+ return 0
+ }
+
+}
+
+#
+# objdump_versionstuff
+# Dump version definitions/references and make sure that it is sane.
+#
+proc objdump_versionstuff { objdump object expectfile } {
+ global VOBJDUMP_FLAGS
+ global version_output
+ global diff
+ global tmpdir
+
+ if {[which $objdump] == 0} then {
+ perror "$objdump does not exist"
+ return 0
+ }
+
+ if ![info exists VOBJDUMP_FLAGS] { set VOBJDUMP_FLAGS "" }
+
+ verbose -log "$objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p > $tmpdir/objdump.out"
+
+ catch "exec $objdump $VOBJDUMP_FLAGS $object | sed -n /Version/,\\\$p > $tmpdir/objdump.out" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+
+ # It's OK if there are extra lines in the actual output; they
+ # may come from version information in libc. We require that
+ # every line in EXPECTFILE appear in the output in order.
+
+ set f1 [open $tmpdir/objdump.out r]
+ set f2 [open $expectfile r]
+ gets $f2 l2
+ while { [gets $f1 l1] != -1 } {
+ if { [string match $l2 $l1] } then {
+ if { [gets $f2 l2] == -1 } then {
+ close $f1
+ close $f2
+ return 1
+ }
+ }
+ }
+
+ # We reached the end of the output without seeing the line we
+ # expected. This is a test failure.
+
+ close $f1
+ close $f2
+
+ verbose -log "Did not find \"$l2\""
+ set f1 [open $tmpdir/objdump.out r]
+ while { [gets $f1 l1] != -1 } {
+ verbose -log $l1
+ }
+
+ verbose -log "$exec_output"
+ return 0
+ } else {
+ verbose -log "$exec_output"
+ return 0
+ }
+}
+
+proc build_vers_lib { test source libname other mapfile verexp versymexp symexp } {
+ global ld
+ global srcdir
+ global subdir
+ global exec_output
+ global host_triplet
+ global tmpdir
+ global as
+ global objdump
+ global CC
+ global CFLAGS
+ global shared
+ global script
+
+ if ![ld_compile "$CC -S $CFLAGS" $srcdir/$subdir/$source $tmpdir/$libname.s] {
+ unresolved "$test"
+ return
+ }
+
+ if ![ld_assemble $as $tmpdir/$libname.s $tmpdir/$libname.o ] {
+ unresolved "$test"
+ return
+ }
+
+ if [string match "" $other] then {
+ set other_lib ""
+ } else {
+ set other_lib $tmpdir/$other
+ }
+
+ if [string match "" $mapfile] then {
+ set script_arg ""
+ } else {
+ set script_arg "$script $srcdir/$subdir/$mapfile"
+ }
+
+ if {![ld_simple_link $ld $tmpdir/$libname.so "$shared $tmpdir/$libname.o $other_lib $script_arg"]} {
+ fail "$test"
+ return
+ }
+
+ if {![objdump_versionstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$verexp ]} {
+ fail "$test"
+ return
+ }
+
+ if {![objdump_dynsymstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$versymexp ]} {
+ fail "$test"
+ return
+ }
+
+ if [string match "" $symexp] then {
+ if {![objdump_emptysymstuff $objdump $tmpdir/$libname.o ]} {
+ fail "$test"
+ return
+ }
+ } else {
+ if {![objdump_symstuff $objdump $tmpdir/$libname.o $srcdir/$subdir/$symexp ]} {
+ fail "$test"
+ return
+ }
+ }
+
+ pass $test
+
+}
+
+proc test_ldfail { test flag source execname other mapfile whyfail } {
+ global ld
+ global srcdir
+ global subdir
+ global exec_output
+ global host_triplet
+ global tmpdir
+ global as
+ global objdump
+ global CC
+ global CFLAGS
+ global script
+
+ if [string match "" $other] then {
+ set other_lib ""
+ } else {
+ set other_lib $tmpdir/$other
+ }
+
+ if ![ld_compile "$CC -S $flag $CFLAGS" $srcdir/$subdir/$source $tmpdir/$execname.s] {
+ unresolved "$test"
+ return
+ }
+
+ if ![ld_assemble $as $tmpdir/$execname.s $tmpdir/$execname.o ] {
+ unresolved "$test"
+ return
+ }
+
+ verbose -log "This link should fail because of $whyfail"
+
+ if [string match "" $mapfile] then {
+ set script_arg ""
+ } else {
+ set script_arg "$script $srcdir/$subdir/$mapfile"
+ }
+
+ if {![ld_link $ld $tmpdir/$execname "$tmpdir/$execname.o $other_lib $script_arg"]} {
+ pass "$test"
+ return
+ }
+ fail "$test"
+}
+
+proc test_asfail { test flag source execname whyfail } {
+ global srcdir
+ global subdir
+ global tmpdir
+ global as
+ global CC
+ global CFLAGS
+
+ if ![ld_compile "$CC -S $flag $CFLAGS" $srcdir/$subdir/$source $tmpdir/$execname.s] {
+ unresolved "$test"
+ return
+ }
+
+ verbose -log "This assemble should fail because of $whyfail"
+ catch "exec $as -o $tmpdir/$execname.o $tmpdir/$execname.s" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ fail "$test"
+ return
+ }
+ verbose -log "$exec_output"
+ pass "$test"
+}
+
+proc test_strip_vers_lib { test srclib libname verexp versymexp } {
+ global strip
+ global srcdir
+ global subdir
+ global exec_output
+ global host_triplet
+ global tmpdir
+ global objdump
+
+ verbose -log "cp $tmpdir/$srclib $tmpdir/$libname.so"
+ exec cp $tmpdir/$srclib $tmpdir/$libname.so
+
+ verbose -log "$strip $tmpdir/$libname.so"
+ catch "exec $strip $tmpdir/$libname.so" exec_output
+ if [string match "" $exec_output] then {
+
+# If strip went OK, then run the usual tests on the thing to make sure that
+# it is sane.
+ if {![objdump_versionstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$verexp ]} {
+ fail "$test"
+ return
+ }
+
+ if {![objdump_dynsymstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$versymexp ]} {
+ fail "$test"
+ return
+ }
+
+ } else {
+ verbose -log "$exec_output"
+ fail "$test"
+ return
+ }
+ pass $test
+}
+
+
+proc build_exec { test source execname flags solibname verexp versymexp symexp } {
+ global ld
+ global srcdir
+ global subdir
+ global exec_output
+ global host_triplet
+ global tmpdir
+ global as
+ global objdump
+ global CC
+ global CFLAGS
+
+ set shared --shared
+ set script --version-script
+ if ![ld_compile "$CC -S $CFLAGS" $srcdir/$subdir/$source $tmpdir/$execname.s] {
+ unresolved "$test"
+ return
+ }
+
+ if ![ld_assemble $as $tmpdir/$execname.s $tmpdir/$execname.o ] {
+ unresolved "$test"
+ return
+ }
+
+ if [string match "" $solibname] then {
+ set solibname_lib ""
+ } else {
+ set solibname_lib $tmpdir/$solibname
+ }
+
+ if {![ld_link $ld $tmpdir/$execname "$flags $tmpdir/$execname.o $solibname_lib"]} {
+ fail "$test"
+ return
+ }
+
+ if [string match "" $verexp] then {
+#
+# Make sure we get nothing back.
+#
+ if {![objdump_emptyverstuff $objdump $tmpdir/$execname ]} {
+ fail "$test"
+ return
+ }
+ } else {
+ if {![objdump_versionstuff $objdump $tmpdir/$execname $srcdir/$subdir/$verexp ]} {
+ fail "$test"
+ return
+ }
+ }
+
+ if [string match "" $versymexp] then {
+ if {![objdump_emptydynsymstuff $objdump $tmpdir/$execname ]} {
+ fail "$test"
+ return
+ }
+ } else {
+ if {![objdump_dynsymstuff $objdump $tmpdir/$execname $srcdir/$subdir/$versymexp ]} {
+ fail "$test"
+ return
+ }
+ }
+
+ if [string match "" $symexp] then {
+ if {![objdump_emptysymstuff $objdump $tmpdir/$execname.o ]} {
+ fail "$test"
+ return
+ }
+ } else {
+ if {![objdump_symstuff $objdump $tmpdir/$execname.o $srcdir/$subdir/$symexp ]} {
+ fail "$test"
+ return
+ }
+ }
+
+ pass $test
+}
+
+
+#
+# Basic test - build a library with versioned symbols.
+#
+build_vers_lib "vers1" vers1.c vers1 "" vers1.map vers1.ver vers1.dsym vers1.sym
+
+
+#
+# Test #2 - build a library, and link it against the library we built in step
+# 1.
+#
+build_vers_lib "vers2" vers2.c vers2 vers1.so vers2.map vers2.ver vers2.dsym ""
+
+#
+# Test #3 - build an executable, and link it against vers1.so.
+#
+build_exec "vers3" vers3.c vers3 "" vers1.so vers3.ver vers3.dsym ""
+
+#
+# Test #4 - Make sure a version implicitly defined in an executable
+# causes a version node to be created. Verify this both with and without
+# --export-dynamic.
+#
+
+# This test fails on MIPS. On the MIPS we must put foo in the dynamic
+# symbol table, which the test does not expect.
+setup_xfail "mips*-*-*"
+build_exec "vers4" vers4.c vers4 "" "" "" "" vers4.sym
+
+build_exec "vers4a" vers4.c vers4a "-export-dynamic" "" vers4a.ver vers4a.dsym vers4a.sym
+
+
+#
+# Try multiple definitions foo@BAR and foo@@BAR and make sure the linker
+# complains.
+#
+test_ldfail "vers5" "" vers5.c vers5 "" "" "multiple definition of foo@VERS_1.2"
+
+#
+#
+# Now build a test that should reference a bunch of versioned symbols.
+# All of them should be correctly referenced.
+#
+build_exec "vers6" vers6.c vers6 "" vers1.so vers6.ver vers6.dsym vers6.sym
+
+#
+# Another test to verify that something made local via 'local' is truly not
+# accessible.
+#
+build_vers_lib "vers7a" vers7a.c vers7a "" vers7.map vers7a.ver vers7a.dsym vers7a.sym
+
+test_ldfail "vers7" "" vers7.c vers7 vers7a.so "" "undefined reference to hide_a"
+
+
+#
+# This test is designed to verify that we can pass a linker script on the
+# command line as if it were a normal .o file.
+#
+catch "exec cp $srcdir/$subdir/vers8.map $tmpdir/" ignore_output
+build_vers_lib "vers8" vers1.c vers8 vers8.map "" vers8.ver vers1.dsym vers1.sym
+
+#
+# This test tries to make sure that version references to versioned symbols
+# don't collide with default definitions with the same symbol.
+#
+build_exec "vers9" vers9.c vers9 "-export-dynamic" "" vers9.ver vers9.dsym vers9.sym
+
+
+#
+# Try and use a non-existant version node. The linker should fail with
+# an error message.
+#
+test_ldfail "vers10" "-DDO_TEST10" vers1.c vers10 "" "vers1.map --shared" "invalid version"
+
+#
+# Try and some things the assembler should complain about.
+#
+test_asfail "vers11" "-DDO_TEST11" vers1.c vers11 "no @ in symver"
+
+test_asfail "vers12" "-DDO_TEST12" vers1.c vers12 "extern version definition"
+
+#
+# Put a shared library in an archive library, and make sure the global
+# archive symbol table is sane.
+#
+test_ar "ar with versioned solib" vers13.a vers1.so vers13.asym
+
+#
+# Strip a shared library, and make sure we didn't screw something up in there.
+#
+test_strip_vers_lib "vers14" vers1.so vers14 vers1.ver vers1.dsym
+
+
+#
+# Build another test with some versioned symbols. Here we are going to
+# try and override something from the library, and we shouldn't get
+# any errors.
+#
+build_exec "vers15" vers15.c vers15 "" vers1.so vers15.ver vers15.dsym vers15.sym
+
+#
+# Test that when we override a versioned symbol from the library this
+# symbol appears in the dynamic symbol table of the executable.
+#
+build_vers_lib "vers16a" vers16a.c vers16a "" vers16.map vers16a.ver vers16a.dsym ""
+build_exec "vers16" vers16.c vers16 "" vers16a.so "" vers16.dsym ""
diff --git a/ld/testsuite/ld-elfvers/vers1.c b/ld/testsuite/ld-elfvers/vers1.c
new file mode 100644
index 00000000000..1d41fd9d04b
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers1.c
@@ -0,0 +1,98 @@
+/*
+ * Basic test of versioning. The idea with this is that we define
+ * a bunch of definitions of the same symbol, and we can theoretically
+ * then link applications against varying sets of these.
+ */
+const char * show_bar1 = "asdf";
+const char * show_bar2 = "asdf";
+
+int
+bar()
+{
+ return 3;
+}
+
+/*
+ * The 'hide' prefix is something so that we can automatically search the
+ * symbol table and verify that none of these symbols were actually exported.
+ */
+int
+hide_original_foo()
+{
+ return 1+bar();
+
+}
+
+int
+hide_old_foo()
+{
+ return 10+bar();
+
+}
+
+int
+hide_old_foo1()
+{
+ return 100+bar();
+
+}
+
+int
+hide_new_foo()
+{
+ return 1000+bar();
+
+}
+
+__asm__(".symver hide_original_foo,show_foo@");
+__asm__(".symver hide_old_foo,show_foo@VERS_1.1");
+__asm__(".symver hide_old_foo1,show_foo@VERS_1.2");
+__asm__(".symver hide_new_foo,show_foo@@VERS_2.0");
+
+
+
+#ifdef DO_TEST10
+/* In test 10, we try and define a non-existant version node. The linker
+ * should catch this and complain. */
+int
+hide_new_bogus_foo()
+{
+ return 1000+bar();
+
+}
+__asm__(".symver hide_new_bogus_foo,show_foo@VERS_2.2");
+#endif
+
+
+
+
+#ifdef DO_TEST11
+/*
+ * This test is designed to catch a couple of syntactic errors. The assembler
+ * should complain about both of the directives below.
+ */
+int
+xyzzz()
+{
+ new2_foo();
+ bar33();
+}
+
+__asm__(".symver new2_foo,fooVERS_2.0");
+__asm__(".symver bar33,bar@@VERS_2.0");
+#endif
+
+#ifdef DO_TEST12
+/*
+ * This test is designed to catch a couple of syntactic errors. The assembler
+ * should complain about both of the directives below.
+ */
+int
+xyzzz()
+{
+ new2_foo();
+ bar33();
+}
+
+__asm__(".symver bar33,bar@@VERS_2.0");
+#endif
diff --git a/ld/testsuite/ld-elfvers/vers1.dsym b/ld/testsuite/ld-elfvers/vers1.dsym
new file mode 100644
index 00000000000..834434bc7f4
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers1.dsym
@@ -0,0 +1,9 @@
+[0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1
+[0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2
+[0]* g DO \*ABS\* [0]* VERS_2.0 VERS_2.0
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(Base\) (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.2\) (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* g DO (.s?data|\*ABS\*) [0-9a-f]* VERS_2.0 show_bar1
+[0-9a-f]* g DO (.s?data|\*ABS\*) [0-9a-f]* VERS_2.0 show_bar2
diff --git a/ld/testsuite/ld-elfvers/vers1.map b/ld/testsuite/ld-elfvers/vers1.map
new file mode 100644
index 00000000000..8fc37bcaf0f
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers1.map
@@ -0,0 +1,16 @@
+VERS_1.1 {
+ global:
+ foo1;
+ local:
+ hide_old*;
+ hide_original*;
+ hide_new*;
+};
+
+VERS_1.2 {
+ foo2;
+} VERS_1.1;
+
+VERS_2.0 {
+ show_bar1; show_bar2;
+} VERS_1.2;
diff --git a/ld/testsuite/ld-elfvers/vers1.sym b/ld/testsuite/ld-elfvers/vers1.sym
new file mode 100644
index 00000000000..70ff85571fe
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers1.sym
@@ -0,0 +1,4 @@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@VERS_1.1
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@VERS_1.2
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@@VERS_2.0
diff --git a/ld/testsuite/ld-elfvers/vers1.ver b/ld/testsuite/ld-elfvers/vers1.ver
new file mode 100644
index 00000000000..3e7312b643e
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers1.ver
@@ -0,0 +1,8 @@
+Version definitions:
+1 0x01 0x0a26881f tmpdir/vers1.so
+2 0x00 0x0a7927b1 VERS_1.1
+3 0x00 0x0a7927b2 VERS_1.2
+ VERS_1.1
+4 0x00 0x0a7922b0 VERS_2.0
+ VERS_1.2
+
diff --git a/ld/testsuite/ld-elfvers/vers13.asym b/ld/testsuite/ld-elfvers/vers13.asym
new file mode 100644
index 00000000000..d446144e2d2
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers13.asym
@@ -0,0 +1,10 @@
+VERS_1.1 in vers1.so
+VERS_1.2 in vers1.so
+VERS_2.0 in vers1.so
+bar in vers1.so
+show_bar1 in vers1.so
+show_bar2 in vers1.so
+show_foo@ in vers1.so
+show_foo@@VERS_2.0 in vers1.so
+show_foo@VERS_1.1 in vers1.so
+show_foo@VERS_1.2 in vers1.so
diff --git a/ld/testsuite/ld-elfvers/vers15.c b/ld/testsuite/ld-elfvers/vers15.c
new file mode 100644
index 00000000000..d32be3ffd55
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers15.c
@@ -0,0 +1,35 @@
+/*
+ * Testcase to make sure that if we externally reference a versioned symbol
+ * that we always get the right one.
+ */
+
+int
+foo_1()
+{
+ return 1034;
+}
+
+int
+foo_2()
+{
+ return 1343;
+}
+
+int
+foo_3()
+{
+ return 1334;
+}
+
+int
+main()
+{
+ printf("Expect 4, get %d\n", foo_1());
+ printf("Expect 13, get %d\n", foo_2());
+ printf("Expect 103, get %d\n", foo_3());
+ return 0;
+}
+
+__asm__(".symver foo_1,show_foo@");
+__asm__(".symver foo_2,show_foo@VERS_1.1");
+__asm__(".symver foo_3,show_foo@@VERS_1.2");
diff --git a/ld/testsuite/ld-elfvers/vers15.dsym b/ld/testsuite/ld-elfvers/vers15.dsym
new file mode 100644
index 00000000000..1f5e15c4af0
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers15.dsym
@@ -0,0 +1,5 @@
+[0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1
+[0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(Base\) (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_1.2 (0x[0-9a-f][0-9a-f] )?show_foo
diff --git a/ld/testsuite/ld-elfvers/vers15.sym b/ld/testsuite/ld-elfvers/vers15.sym
new file mode 100644
index 00000000000..87bab62c9e4
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers15.sym
@@ -0,0 +1,3 @@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@VERS_1.1
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo@@VERS_1.2
diff --git a/ld/testsuite/ld-elfvers/vers15.ver b/ld/testsuite/ld-elfvers/vers15.ver
new file mode 100644
index 00000000000..3d2ec588ffc
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers15.ver
@@ -0,0 +1,5 @@
+Version definitions:
+1 0x01 0x0d8a2605 tmpdir/vers15
+2 0x00 0x0a7927b2 VERS_1.2
+3 0x00 0x0a7927b1 VERS_1.1
+
diff --git a/ld/testsuite/ld-elfvers/vers16.c b/ld/testsuite/ld-elfvers/vers16.c
new file mode 100644
index 00000000000..6668bc60621
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers16.c
@@ -0,0 +1,10 @@
+int show_bar ()
+{
+ return 0;
+}
+extern int show_foo ();
+
+int main ()
+{
+ return show_foo ();
+}
diff --git a/ld/testsuite/ld-elfvers/vers16.dsym b/ld/testsuite/ld-elfvers/vers16.dsym
new file mode 100644
index 00000000000..6c424c31738
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers16.dsym
@@ -0,0 +1,2 @@
+[0-9a-f]* g DF (\.text|\*ABS\*) [0-9a-f]*( Base )? (0x[0-9a-f][0-9a-f] )?show_bar
+[0-9a-f]* DF \*UND\* [0-9a-f]*( )? (0x[0-9a-f][0-9a-f] )?show_foo
diff --git a/ld/testsuite/ld-elfvers/vers16.map b/ld/testsuite/ld-elfvers/vers16.map
new file mode 100644
index 00000000000..766332fcfb2
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers16.map
@@ -0,0 +1,3 @@
+VERS_1.1 {
+ global: show_bar;
+};
diff --git a/ld/testsuite/ld-elfvers/vers16a.c b/ld/testsuite/ld-elfvers/vers16a.c
new file mode 100644
index 00000000000..153b1fdc779
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers16a.c
@@ -0,0 +1,8 @@
+int show_bar ()
+{
+ return 1;
+}
+int show_foo ()
+{
+ return show_bar ();
+}
diff --git a/ld/testsuite/ld-elfvers/vers16a.dsym b/ld/testsuite/ld-elfvers/vers16a.dsym
new file mode 100644
index 00000000000..058df47ee8e
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers16a.dsym
@@ -0,0 +1,3 @@
+[0-9a-f]* g DO (\.text|\*ABS\*) [0-9a-f]* VERS_1\.1 VERS_1\.1
+[0-9a-f]* g DF (\.text|\*ABS\*) [0-9a-f]* VERS_1\.1 (0x[0-9a-f][0-9a-f] )?show_bar
+[0-9a-f]* g DF (\.text|\*ABS\*) [0-9a-f]* Base (0x[0-9a-f][0-9a-f] )?show_foo
diff --git a/ld/testsuite/ld-elfvers/vers16a.ver b/ld/testsuite/ld-elfvers/vers16a.ver
new file mode 100644
index 00000000000..bccf1df7cc9
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers16a.ver
@@ -0,0 +1,3 @@
+Version definitions:
+1 0x01 0x0601cfbf tmpdir/vers16a.so
+2 0x00 0x0a7927b1 VERS_1.1
diff --git a/ld/testsuite/ld-elfvers/vers2.c b/ld/testsuite/ld-elfvers/vers2.c
new file mode 100644
index 00000000000..d6a537ea4fa
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers2.c
@@ -0,0 +1,10 @@
+/*
+ * Test function. This is built into a shared library, and references a
+ * versioned symbol foo that is in test.so.
+ */
+
+void
+show_xyzzy()
+{
+ printf("%d", show_foo());
+}
diff --git a/ld/testsuite/ld-elfvers/vers2.dsym b/ld/testsuite/ld-elfvers/vers2.dsym
new file mode 100644
index 00000000000..99985c237a3
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers2.dsym
@@ -0,0 +1,3 @@
+[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo
+[0]* g DO \*ABS\* [0]* VERS_XXX_1.1 VERS_XXX_1.1
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_XXX_1.1 (0x[0-9a-f][0-9a-f] )?show_xyzzy
diff --git a/ld/testsuite/ld-elfvers/vers2.map b/ld/testsuite/ld-elfvers/vers2.map
new file mode 100644
index 00000000000..cd57d7e53bb
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers2.map
@@ -0,0 +1,4 @@
+
+VERS_XXX_1.1 {
+ show_xyzzy;
+};
diff --git a/ld/testsuite/ld-elfvers/vers2.ver b/ld/testsuite/ld-elfvers/vers2.ver
new file mode 100644
index 00000000000..b52634359b6
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers2.ver
@@ -0,0 +1,8 @@
+Version definitions:
+1 0x01 0x0a26181f tmpdir/vers2.so
+2 0x00 0x08785b51 VERS_XXX_1.1
+
+Version References:
+ required from tmpdir/vers1.so:
+ 0x0a7922b0 0x00 03 VERS_2.0
+
diff --git a/ld/testsuite/ld-elfvers/vers3.c b/ld/testsuite/ld-elfvers/vers3.c
new file mode 100644
index 00000000000..b006d7717e9
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers3.c
@@ -0,0 +1,10 @@
+/*
+ * Main program for test1, test2.
+ */
+
+int
+main()
+{
+ printf("%d\n", show_foo());
+ return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/vers3.dsym b/ld/testsuite/ld-elfvers/vers3.dsym
new file mode 100644
index 00000000000..c9c2642389f
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers3.dsym
@@ -0,0 +1 @@
+[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo
diff --git a/ld/testsuite/ld-elfvers/vers3.ver b/ld/testsuite/ld-elfvers/vers3.ver
new file mode 100644
index 00000000000..aa230eea3ee
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers3.ver
@@ -0,0 +1,4 @@
+Version References:
+ required from tmpdir/vers1.so:
+ 0x0a7922b0 0x00 02 VERS_2.0
+
diff --git a/ld/testsuite/ld-elfvers/vers4.c b/ld/testsuite/ld-elfvers/vers4.c
new file mode 100644
index 00000000000..15497cacc81
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers4.c
@@ -0,0 +1,27 @@
+/*
+ * Testcase to make sure that a versioned symbol definition in an
+ * application correctly defines the version node, if and only if
+ * the actual symbol is exported. This is built both with and without
+ * -export-dynamic.
+ */
+int
+bar()
+{
+ return 3;
+}
+
+int
+new_foo()
+{
+ return 1000+bar();
+
+}
+
+__asm__(".symver new_foo,foo@@VERS_2.0");
+
+int
+main()
+{
+ printf("%d\n", foo());
+ return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/vers4.sym b/ld/testsuite/ld-elfvers/vers4.sym
new file mode 100644
index 00000000000..7449446e803
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers4.sym
@@ -0,0 +1 @@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@@VERS_2.0
diff --git a/ld/testsuite/ld-elfvers/vers4a.dsym b/ld/testsuite/ld-elfvers/vers4a.dsym
new file mode 100644
index 00000000000..f7f9fdacfd6
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers4a.dsym
@@ -0,0 +1,2 @@
+[0]* g DO \*ABS\* [0]* VERS_2.0 VERS_2.0
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?foo
diff --git a/ld/testsuite/ld-elfvers/vers4a.sym b/ld/testsuite/ld-elfvers/vers4a.sym
new file mode 100644
index 00000000000..7449446e803
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers4a.sym
@@ -0,0 +1 @@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@@VERS_2.0
diff --git a/ld/testsuite/ld-elfvers/vers4a.ver b/ld/testsuite/ld-elfvers/vers4a.ver
new file mode 100644
index 00000000000..876cedc87b3
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers4a.ver
@@ -0,0 +1,4 @@
+Version definitions:
+1 0x01 0x0d8a26e1 tmpdir/vers4a
+2 0x00 0x0a7922b0 VERS_2.0
+
diff --git a/ld/testsuite/ld-elfvers/vers5.c b/ld/testsuite/ld-elfvers/vers5.c
new file mode 100644
index 00000000000..cc6ea40b678
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers5.c
@@ -0,0 +1,51 @@
+/*
+ * Testcase to verify that foo@BAR and foo@@BAR are correctly detected
+ * as a multiply defined symbol.
+ */
+const char * bar1 = "asdf";
+const char * bar2 = "asdf";
+
+int
+bar()
+{
+ return 3;
+}
+
+int
+original_foo()
+{
+ return 1+bar();
+
+}
+
+int
+old_foo()
+{
+ return 10+bar();
+
+}
+
+int
+old_foo1()
+{
+ return 100+bar();
+
+}
+
+int
+new_foo()
+{
+ return 1000+bar();
+
+}
+
+__asm__(".symver original_foo,foo@");
+__asm__(".symver old_foo,foo@VERS_1.1");
+__asm__(".symver old_foo1,foo@VERS_1.2");
+__asm__(".symver new_foo,foo@@VERS_1.2");
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/vers6.c b/ld/testsuite/ld-elfvers/vers6.c
new file mode 100644
index 00000000000..b5868bf3794
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers6.c
@@ -0,0 +1,19 @@
+/*
+ * Testcase to make sure that if we externally reference a versioned symbol
+ * that we always get the right one.
+ */
+
+int
+main()
+{
+ printf("Expect 4, get %d\n", foo_1());
+ printf("Expect 13, get %d\n", foo_2());
+ printf("Expect 103, get %d\n", foo_3());
+ printf("Expect 1003, get %d\n", foo_4());
+ return 0;
+}
+
+__asm__(".symver foo_1,show_foo@");
+__asm__(".symver foo_2,show_foo@VERS_1.1");
+__asm__(".symver foo_3,show_foo@VERS_1.2");
+__asm__(".symver foo_4,show_foo@VERS_2.0");
diff --git a/ld/testsuite/ld-elfvers/vers6.dsym b/ld/testsuite/ld-elfvers/vers6.dsym
new file mode 100644
index 00000000000..7e851d457ab
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers6.dsym
@@ -0,0 +1,4 @@
+[0-9a-f]* DF \*UND\* [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_1.2 (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]* DF \*UND\* [0-9a-f]* VERS_1.1 (0x[0-9a-f][0-9a-f] )?show_foo
diff --git a/ld/testsuite/ld-elfvers/vers6.sym b/ld/testsuite/ld-elfvers/vers6.sym
new file mode 100644
index 00000000000..d7b5cc75bbe
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers6.sym
@@ -0,0 +1,4 @@
+[0]* *F? *\*UND\* [0]* show_foo@
+[0]* *F? *\*UND\* [0]* show_foo@VERS_1.1
+[0]* *F? *\*UND\* [0]* show_foo@VERS_1.2
+[0]* *F? *\*UND\* [0]* show_foo@VERS_2.0
diff --git a/ld/testsuite/ld-elfvers/vers6.ver b/ld/testsuite/ld-elfvers/vers6.ver
new file mode 100644
index 00000000000..48a2b465f4c
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers6.ver
@@ -0,0 +1,6 @@
+Version References:
+ required from tmpdir/vers1.so:
+ 0x0a7927b1 0x00 ?? VERS_1.1
+ 0x0a7927b2 0x00 ?? VERS_1.2
+ 0x0a7922b0 0x00 ?? VERS_2.0
+
diff --git a/ld/testsuite/ld-elfvers/vers7.c b/ld/testsuite/ld-elfvers/vers7.c
new file mode 100644
index 00000000000..d25b7e00628
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers7.c
@@ -0,0 +1,11 @@
+/*
+ * Test program that goes with test7.so
+ */
+
+
+int
+main()
+{
+ return hide_a(1) + show_b(1);
+ return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/vers7.map b/ld/testsuite/ld-elfvers/vers7.map
new file mode 100644
index 00000000000..65fd501d2c3
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers7.map
@@ -0,0 +1,6 @@
+VERS_1 {
+ global:
+ show_b ;
+ local:
+ hide_a;
+};
diff --git a/ld/testsuite/ld-elfvers/vers7a.c b/ld/testsuite/ld-elfvers/vers7a.c
new file mode 100644
index 00000000000..7bee8c70bfe
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers7a.c
@@ -0,0 +1,18 @@
+/*
+ * Test supplied by Ulrich. Verify that we can correctly force 'a'
+ * to local scope.
+ */
+int
+__a_internal (int e)
+{
+ return e + 10;
+}
+
+int
+__b_internal (int e)
+{
+ return e + 42;
+}
+
+asm (".symver __a_internal,hide_a@@VERS_1");
+asm (".symver __b_internal,show_b@@VERS_1");
diff --git a/ld/testsuite/ld-elfvers/vers7a.dsym b/ld/testsuite/ld-elfvers/vers7a.dsym
new file mode 100644
index 00000000000..06696c75358
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers7a.dsym
@@ -0,0 +1,2 @@
+[0]* g DO \*ABS\* [0]* VERS_1 VERS_1
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_1 (0x[0-9a-f][0-9a-f] )?show_b
diff --git a/ld/testsuite/ld-elfvers/vers7a.sym b/ld/testsuite/ld-elfvers/vers7a.sym
new file mode 100644
index 00000000000..b99bd61cc3c
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers7a.sym
@@ -0,0 +1,2 @@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?hide_a@@VERS_1
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?show_b@@VERS_1
diff --git a/ld/testsuite/ld-elfvers/vers7a.ver b/ld/testsuite/ld-elfvers/vers7a.ver
new file mode 100644
index 00000000000..37ef8a824cc
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers7a.ver
@@ -0,0 +1,4 @@
+Version definitions:
+1 0x01 0x0269fd3f tmpdir/vers7a.so
+2 0x00 0x05aa7921 VERS_1
+
diff --git a/ld/testsuite/ld-elfvers/vers8.c b/ld/testsuite/ld-elfvers/vers8.c
new file mode 100644
index 00000000000..a14586cbc8a
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers8.c
@@ -0,0 +1,5 @@
+int
+main()
+{
+ return a(1) + b(1);
+}
diff --git a/ld/testsuite/ld-elfvers/vers8.map b/ld/testsuite/ld-elfvers/vers8.map
new file mode 100644
index 00000000000..26359559d9f
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers8.map
@@ -0,0 +1,18 @@
+VERSION {
+ VERS_1.1 {
+ global:
+ foo1;
+ local:
+ hide_old*;
+ hide_original*;
+ hide_new*;
+ };
+
+ VERS_1.2 {
+ foo2;
+ } VERS_1.1;
+
+ VERS_2.0 {
+ show_bar1; show_bar2;
+ } VERS_1.2;
+}
diff --git a/ld/testsuite/ld-elfvers/vers8.ver b/ld/testsuite/ld-elfvers/vers8.ver
new file mode 100644
index 00000000000..ef59023ccee
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers8.ver
@@ -0,0 +1,8 @@
+Version definitions:
+1 0x01 0x0a26f81f tmpdir/vers8.so
+2 0x00 0x0a7927b1 VERS_1.1
+3 0x00 0x0a7927b2 VERS_1.2
+ VERS_1.1
+4 0x00 0x0a7922b0 VERS_2.0
+ VERS_1.2
+
diff --git a/ld/testsuite/ld-elfvers/vers9.c b/ld/testsuite/ld-elfvers/vers9.c
new file mode 100644
index 00000000000..432fddb19b3
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers9.c
@@ -0,0 +1,45 @@
+/*
+ * Testcase to verify that reference to foo@BAR and a definition of foo@@BAR
+ * are not treated as a multiple def.
+ */
+const char * bar1 = "asdf";
+const char * bar2 = "asdf";
+
+int
+bar()
+{
+ return 3;
+}
+
+int
+original_foo()
+{
+ return 1+bar();
+
+}
+
+int
+old_foo()
+{
+ return 10+bar();
+
+}
+
+int
+new_foo()
+{
+ return 1000+bar();
+
+}
+
+int
+main()
+{
+ old_foo1();
+ return 0;
+}
+
+__asm__(".symver original_foo,foo@");
+__asm__(".symver old_foo,foo@VERS_1.1");
+__asm__(".symver old_foo1,foo@VERS_1.2");
+__asm__(".symver new_foo,foo@@VERS_1.2");
diff --git a/ld/testsuite/ld-elfvers/vers9.dsym b/ld/testsuite/ld-elfvers/vers9.dsym
new file mode 100644
index 00000000000..97930025842
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers9.dsym
@@ -0,0 +1,4 @@
+[0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1
+[0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?foo
+[0-9a-f]* g DF (.text|\*ABS\*) [0-9a-f]* VERS_1.2 (0x[0-9a-f][0-9a-f] )?foo
diff --git a/ld/testsuite/ld-elfvers/vers9.sym b/ld/testsuite/ld-elfvers/vers9.sym
new file mode 100644
index 00000000000..8231516bfc9
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers9.sym
@@ -0,0 +1,4 @@
+[0]* *F? *\*UND\* [0]* foo@VERS_1.2
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@VERS_1.1
+[0-9a-f]* g F .text [0-9a-f]* (0x[0-9a-f][0-9a-f] )?foo@@VERS_1.2
diff --git a/ld/testsuite/ld-elfvers/vers9.ver b/ld/testsuite/ld-elfvers/vers9.ver
new file mode 100644
index 00000000000..673ba72ab45
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/vers9.ver
@@ -0,0 +1,5 @@
+Version definitions:
+1 0x01 0x04d8a269 tmpdir/vers9
+2 0x00 0x0a7927b1 VERS_1.1
+3 0x00 0x0a7927b2 VERS_1.2
+
diff --git a/ld/testsuite/ld-empic/empic.exp b/ld/testsuite/ld-empic/empic.exp
new file mode 100644
index 00000000000..2d528bef1f6
--- /dev/null
+++ b/ld/testsuite/ld-empic/empic.exp
@@ -0,0 +1,263 @@
+# Expect script for ld-empic tests
+# Copyright (C) 1994,1995, 1996, 1997 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Ian Lance Taylor (ian@cygnus.com)
+#
+
+# Test the handling of MIPS embedded PIC code. This test essentially
+# tests the compiler and assembler as well as the linker, since MIPS
+# embedded PIC is a GNU enhancement to standard MIPS tools.
+
+# Embedded PIC is only supported for MIPS ECOFF targets.
+if ![istarget mips*-*-ecoff*] {
+ return
+}
+
+set testname relax
+
+if { [which $CC] == 0 } {
+ untested $testname
+ return
+}
+
+# Test that relaxation works correctly. This testsuite was composed
+# (by experimentation) to force the linker to relax twice--that is,
+# the first relaxation pass will force another call to be out of
+# range, requiring a second relaxation pass.
+if { ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax1.c tmpdir/relax1.o]
+ || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax2.c tmpdir/relax2.o]
+ || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax3.c tmpdir/relax3.o]
+ || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/relax4.c tmpdir/relax4.o] } {
+ unresolved $testname
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/relax "--relax -T $srcdir/$subdir/relax.t tmpdir/relax1.o tmpdir/relax2.o tmpdir/relax3.o tmpdir/relax4.o"] {
+ fail $testname
+} else {
+ # Check that the relaxation produced the correct result. Check
+ # each bal instruction. Some will go directly to the start of a
+ # function, which is OK. Some will form part of the five
+ # instruction expanded call sequence, in which case we compute the
+ # real destination and make sure it is the start of a function.
+ # Some bal instructions are used to locate the start of the
+ # function in order to do position independent addressing into the
+ # text section, in which case we just check that it correctly
+ # computes the start of the function.
+
+ # Get the symbol table.
+ if ![ld_nm $nm tmpdir/relax] {
+ unresolved $testname
+ return
+ }
+
+ # Get a disassembly.
+ send_log "$objdump -d tmpdir/relax >tmpdir/relax.dis\n"
+ verbose "$objdump -d tmpdir/relax >tmpdir/relax.dis"
+ catch "exec $objdump -d tmpdir/relax >tmpdir/relax.dis" exec_output
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose $exec_output
+ unresolved $testname
+ return
+ }
+
+ set balcnt 0
+ set file [open tmpdir/relax.dis r]
+ while { [gets $file line] != -1 } {
+ verbose "$line" 2
+
+ if ![string match "*bal*" $line] {
+ continue
+ }
+
+ verbose "$line"
+
+ incr balcnt
+
+ if ![regexp "^(\[0-9a-fA-F\]+) (<\[a-z+0-9A-Z.\]+>)? bal (\[0-9a-fA-F\]+)" $line whole addr label dest] {
+ perror "unrecognized format for $line"
+ unresolved $testname
+ return
+ }
+
+ if "0x$addr + 8 != 0x$dest" {
+ # This is a straight function call. All function calls in
+ # this example are to either foo or bar.
+ if "0x$dest != $nm_output(foo) && 0x$dest != $nm_output(bar)" {
+ send_log "fail 1\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ } else {
+ # Pick up the next line. If it is sll, this is a switch
+ # prologue, and there is not much we can do to test it.
+ # Otherwise, it should be lui, and the next instruction
+ # should be an addiu, followed by an addu to $31.
+ if { [gets $file l] == -1 } {
+ send_log "fail 2\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ verbose $l
+
+ if [string match "*sll*" $l] {
+ continue
+ }
+ if ![regexp "lui (\[\$a-z0-9\]+),(\[0-9a-fA-Fx\]+)" $l whole reg upper] {
+ send_log "fail 3\n"
+ send_log "$line\n"
+ send_log "$l\n"
+ fail $testname
+ return
+ }
+
+ if { [gets $file l] == -1 } {
+ send_log "fail 4\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ verbose "$l"
+ if ![regexp "addiu \\$reg,\\$reg,(\[-0-9\]+)" $l whole lower] {
+ send_log "fail 5\n"
+ send_log "$line\n"
+ send_log "$l\n"
+ send_log "addiu \\$reg,\\$reg,(\[-0-9\]+)\n"
+ fail $testname
+ return
+ }
+
+ if { [gets $file l] == -1 } {
+ send_log "fail 6\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ verbose "$l"
+ if ![regexp "addu \\$reg,\\$reg,\\\$ra" $l] {
+ send_log "fail 7\n"
+ send_log "$line\n"
+ send_log "$l\n"
+ fail $testname
+ return
+ }
+
+ # The next line will be jalr in the case of an expanded
+ # call. Otherwise, the code is getting the start of the
+ # function, and the next line can be anything.
+
+ if { [gets $file l] == -1 } {
+ send_log "fail 8\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ verbose "$l"
+ if [string match "*jalr*" $l] {
+ set dest [expr 0x$addr + 8 + ($upper << 16) + $lower]
+ if { $dest != $nm_output(foo) && $dest != $nm_output(bar) } {
+ send_log "fail 9\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ } else {
+ set dest [expr ($upper << 16) + $lower]
+ if ![regexp "<(\[.a-z\]+)\\+(\[0-9a-fA-F\]+)>" $label whole base offset] {
+ send_log "fail 10\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ set offset 0x$offset
+ if { $base == ".foo" } {
+ set offset [expr $offset - ($nm_output(foo) - 0x30)]
+ }
+ if { $offset + 8 != - $dest } {
+ send_log "fail 11\n"
+ send_log "$line\n"
+ fail $testname
+ return
+ }
+ }
+ }
+ }
+
+ close $file
+
+ if {$balcnt < 10} {
+ send_log "fail 12\n"
+ fail $testname
+ } else {
+ verbose "$balcnt bal instructions"
+ pass $testname
+ }
+}
+
+# We now test actually running embedded MIPS PIC code. This can only
+# be done on a MIPS host with the same endianness as our target.
+if [istarget mipsel-*-*] {
+ if ![ishost mips*-*-ultrix*] {
+ return
+ }
+} else {
+ if ![ishost mips*-*-irix*] {
+ return
+ }
+}
+
+set testname "run embedded PIC code"
+
+# Compile the program which will run the test. This code must be
+# compiled for the host, not the target.
+send_log "$CC_FOR_HOST $CFLAGS_FOR_HOST -o tmpdir/run $srcdir/$subdir/run.c\n"
+verbose "$CC_FOR_HOST $CFLAGS_FOR_HOST -o tmpdir/run $srcdir/$subdir/run.c"
+catch "exec $CC_FOR_HOST $CFLAGS_FOR_HOST -o tmpdir/run $srcdir/$subdir/run.c" exec_output
+if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ unresolved $testname
+ return
+}
+
+# Compile and link the test.
+if { ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/runtesti.s tmpdir/runtesti.o]
+ || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/runtest1.c tmpdir/runtest1.o]
+ || ![ld_compile "$CC $CFLAGS -membedded-pic" $srcdir/$subdir/runtest2.c tmpdir/runtest2.o] } {
+ unresolved $testname
+ return
+}
+if ![ld_simple_link $ld tmpdir/runtest "--embedded-relocs tmpdir/runtesti.o tmpdir/runtest1.o tmpdir/runtest2.o"] {
+ fail $testname
+} else {
+ # Now run the test.
+ send_log "tmpdir/run tmpdir/runtest\n"
+ verbose "tmpdir/run tmpdir/runtest"
+ catch "exec tmpdir/run tmpdir/runtest" exec_output
+ if [string match "*ran and returned 0*" $exec_output] {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ pass $testname
+ } else {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ fail $testname
+ }
+}
diff --git a/ld/testsuite/ld-empic/relax.t b/ld/testsuite/ld-empic/relax.t
new file mode 100644
index 00000000000..8c18b69a86e
--- /dev/null
+++ b/ld/testsuite/ld-empic/relax.t
@@ -0,0 +1,49 @@
+OUTPUT_FORMAT("ecoff-bigmips")
+SECTIONS
+{
+ .foo 0x30 : {
+ tmpdir/relax3.o(.text)
+ tmpdir/relax1.o(.text)
+ }
+ .text 0x20000 : {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ tmpdir/relax4.o(.text)
+ *(.text)
+ *(.fini)
+ etext = .;
+ _etext = .;
+ }
+ .rdata . : {
+ *(.rdata)
+ }
+ _fdata = .;
+ .data . : {
+ *(.data)
+ CONSTRUCTORS
+ }
+ _gp = . + 0x8000;
+ .lit8 . : {
+ *(.lit8)
+ }
+ .lit4 . : {
+ *(.lit4)
+ }
+ .sdata . : {
+ *(.sdata)
+ }
+ edata = .;
+ _edata = .;
+ _fbss = .;
+ .sbss . : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss . : {
+ *(.bss)
+ *(COMMON)
+ }
+ end = .;
+ _end = .;
+}
diff --git a/ld/testsuite/ld-empic/relax1.c b/ld/testsuite/ld-empic/relax1.c
new file mode 100644
index 00000000000..20ec39efc9c
--- /dev/null
+++ b/ld/testsuite/ld-empic/relax1.c
@@ -0,0 +1,22 @@
+/* First source file in relaxation test. */
+
+extern int bar ();
+static int foo2 ();
+
+int foo (int i)
+{
+ switch (i)
+ {
+ case 0: bar (0); break;
+ case 1: bar (1); break;
+ case 2: bar (2); break;
+ case 3: bar (3); break;
+ case 4: bar (foo2); break;
+ case 5: bar (bar); break;
+ }
+ while (1)
+ if (i)
+ return bar ();
+}
+
+static int foo2 () { }
diff --git a/ld/testsuite/ld-empic/relax2.c b/ld/testsuite/ld-empic/relax2.c
new file mode 100644
index 00000000000..58854a03aa9
--- /dev/null
+++ b/ld/testsuite/ld-empic/relax2.c
@@ -0,0 +1,19 @@
+/* Second source file in relaxation test. */
+
+int bar2 ()
+{
+ int i;
+
+ for (i = 0; i < 100; i++)
+ foo ();
+ return foo () + foo () + foo () + foo ();
+}
+
+int bar (int i)
+{
+ while (1)
+ if (i)
+ return foo ();
+ else
+ return foo ();
+}
diff --git a/ld/testsuite/ld-empic/relax3.c b/ld/testsuite/ld-empic/relax3.c
new file mode 100644
index 00000000000..1aaa532bc2f
--- /dev/null
+++ b/ld/testsuite/ld-empic/relax3.c
@@ -0,0 +1,3 @@
+/* Third source file in relaxation test. */
+
+int quux () { return 0; }
diff --git a/ld/testsuite/ld-empic/relax4.c b/ld/testsuite/ld-empic/relax4.c
new file mode 100644
index 00000000000..21cfb05b67d
--- /dev/null
+++ b/ld/testsuite/ld-empic/relax4.c
@@ -0,0 +1,3 @@
+/* Fourth source file in relaxation test. */
+
+int xyzzy () { return 0; }
diff --git a/ld/testsuite/ld-empic/run.c b/ld/testsuite/ld-empic/run.c
new file mode 100644
index 00000000000..9a0377e02e5
--- /dev/null
+++ b/ld/testsuite/ld-empic/run.c
@@ -0,0 +1,160 @@
+/* Load and run a MIPS position independent ECOFF file.
+ Written by Ian Lance Taylor <ian@cygnus.com>
+ Public domain. */
+
+/* This program will load an ECOFF file into memory and execute it.
+ The file must have been compiled using the GNU -membedded-pic
+ switch to produce position independent code. This will only work
+ if this program is run on a MIPS system with the same endianness as
+ the ECOFF file. The ECOFF file must be complete. System calls may
+ not work correctly.
+
+ There are further restrictions on the file (they could be removed
+ by doing some additional programming). The file must be aligned
+ such that it does not require any gaps introduced in the data
+ segment; the GNU linker produces such files by default. However,
+ the file must not assume that the text or data segment is aligned
+ on a page boundary. The start address must be at the start of the
+ text segment.
+
+ The ECOFF file is run by calling it as though it were a function.
+ The address of the data segment is passed as the only argument.
+ The file is expected to return an integer value, which will be
+ printed. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* Structures used in ECOFF files. We assume that a short is two
+ bytes and an int is four bytes. This is not much of an assumption,
+ since we already assume that we are running on a MIPS host with the
+ same endianness as the file we are examining. */
+
+struct ecoff_filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ unsigned int f_timdat; /* time & date stamp */
+ unsigned int f_symptr; /* file pointer to symtab */
+ unsigned int f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+};
+
+struct ecoff_aouthdr
+{
+ unsigned short magic; /* type of file */
+ unsigned short vstamp; /* version stamp */
+ unsigned int tsize; /* text size in bytes, padded to FW bdry*/
+ unsigned int dsize; /* initialized data " " */
+ unsigned int bsize; /* uninitialized data " " */
+ unsigned int entry; /* entry pt. */
+ unsigned int text_start; /* base of text used for this file */
+ unsigned int data_start; /* base of data used for this file */
+ unsigned int bss_start; /* base of bss used for this file */
+ unsigned int gprmask; /* ?? */
+ unsigned int cprmask[4]; /* ?? */
+ unsigned int gp_value; /* value for gp register */
+};
+
+#define ECOFF_SCNHDR_SIZE (40)
+
+static void
+die (s)
+ char *s;
+{
+ perror (s);
+ exit (1);
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *f;
+ struct stat s;
+ char *z;
+ struct ecoff_filehdr *fh;
+ struct ecoff_aouthdr *ah;
+ unsigned int toff;
+ char *t, *d;
+ int (*pfn) ();
+ int ret;
+
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s file\n", argv[0]);
+ exit (1);
+ }
+
+ f = fopen (argv[1], "r");
+ if (f == NULL)
+ die (argv[1]);
+
+ if (stat (argv[1], &s) < 0)
+ die ("stat");
+
+ z = (char *) malloc (s.st_size);
+ if (z == NULL)
+ die ("malloc");
+
+ if (fread (z, 1, s.st_size, f) != s.st_size)
+ die ("fread");
+
+ /* We need to figure out the start of the text segment, which is the
+ location we are going to call, and the start of the data segment,
+ which we are going to pass as an argument. We also need the size
+ and start address of the bss segment. This information is all in
+ the ECOFF a.out header. */
+
+ fh = (struct ecoff_filehdr *) z;
+ if (fh->f_opthdr != sizeof (struct ecoff_aouthdr))
+ {
+ fprintf (stderr, "%s: unexpected opthdr size: is %u, want %u\n",
+ argv[1], (unsigned int) fh->f_opthdr,
+ (unsigned int) sizeof (struct ecoff_aouthdr));
+ exit (1);
+ }
+
+ ah = (struct ecoff_aouthdr *) (z + sizeof (struct ecoff_filehdr));
+ if (ah->magic != 0413)
+ {
+ fprintf (stderr, "%s: bad aouthdr magic number 0%o (want 0413)\n",
+ argv[1], (unsigned int) ah->magic);
+ exit (1);
+ }
+
+ /* We should clear the bss segment at this point. This is the
+ ah->bsize bytes starting at ah->bss_start, To do this correctly,
+ we would have to make sure our memory block is large enough. It
+ so happens that our test case does not have any additional pages
+ for the bss segment--it is contained within the data segment.
+ So, we don't bother. */
+ if (ah->bsize != 0)
+ {
+ fprintf (stderr,
+ "%s: bss segment is %u bytes; non-zero sizes not supported\n",
+ argv[1], ah->bsize);
+ exit (1);
+ }
+
+ /* The text section starts just after all the headers, rounded to a
+ 16 byte boundary. */
+ toff = (sizeof (struct ecoff_filehdr) + sizeof (struct ecoff_aouthdr)
+ + fh->f_nscns * ECOFF_SCNHDR_SIZE);
+ toff += 15;
+ toff &=~ 15;
+ t = z + toff;
+
+ /* The tsize field gives us the start of the data segment. */
+ d = z + ah->tsize;
+
+ /* Call the code as a function. */
+ pfn = (int (*) ()) t;
+ ret = (*pfn) (d);
+
+ printf ("%s ran and returned %d\n", argv[1], ret);
+
+ exit (0);
+}
diff --git a/ld/testsuite/ld-empic/runtest1.c b/ld/testsuite/ld-empic/runtest1.c
new file mode 100644
index 00000000000..f9ab6eb6681
--- /dev/null
+++ b/ld/testsuite/ld-empic/runtest1.c
@@ -0,0 +1,117 @@
+/* First C source file for actual execution test. */
+
+/* The main point of this test is to make sure that the code and data
+ are truly position independent. We statically initialize several
+ global variables, and make sure that they are correctly adjusted at
+ runtime. */
+
+int i = 1;
+int j = 0;
+extern int k;
+int l;
+char small_buf[] = "aaaa";
+char *small_pointer = small_buf;
+char big_buf[] = "aaaaaaaaaaaaaaaa";
+char *big_pointer = big_buf;
+
+extern int bar ();
+int (*pbar) () = bar;
+
+static int
+foo2 (arg)
+ int arg;
+{
+ l = arg;
+ return i + j;
+}
+
+int (*pfoo2) () = foo2;
+
+int
+chkstr (z, c)
+ char *z;
+ int c;
+{
+ /* Switch statements need extra effort to be position independent,
+ so we run one here, even though most of the cases will never be
+ taken. */
+ switch (c)
+ {
+ case 1:
+ case 2:
+ case 3:
+ return i - 1;
+ case 4:
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ return i * j;
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ return j;
+ case 16:
+ break;
+ default:
+ return 0;
+ }
+
+ while (c-- != 0)
+ if (*z++ != 'a')
+ return 0;
+
+ return *z == '\0';
+}
+
+/* This function is called by the assembler startup routine. It tries
+ to test that everything was correctly initialized. It returns 0 on
+ success, something else on failure. */
+
+int
+foo ()
+{
+ if (i != 1)
+ return 1;
+ if (j != 0)
+ return 2;
+ if (! chkstr (small_buf, 4))
+ return 3;
+ if (! chkstr (small_pointer, 4))
+ return 4;
+ if (! chkstr (big_buf, 16))
+ return 5;
+ if (! chkstr (big_pointer, 16))
+ return 6;
+
+ if (l != 0)
+ return 7;
+ if (foo2 (1) != 1)
+ return 8;
+ if (l != 1)
+ return 9;
+ if ((*pfoo2) (2) != 1)
+ return 10;
+ if (l != 2)
+ return 11;
+
+ if (bar (1) != 0)
+ return 12;
+ if (bar (-1) != 1)
+ return 13;
+ if ((*pbar) (0xa5a5a5a5) != -1)
+ return 14;
+ if (k != 0xa5a5a5a5)
+ return 15;
+ if ((*pbar) (0) != 0xa5a5a5a5)
+ return 16;
+ if (k != 0)
+ return 17;
+
+ return 0;
+}
diff --git a/ld/testsuite/ld-empic/runtest2.c b/ld/testsuite/ld-empic/runtest2.c
new file mode 100644
index 00000000000..000525f11ea
--- /dev/null
+++ b/ld/testsuite/ld-empic/runtest2.c
@@ -0,0 +1,26 @@
+/* Second C source file for actual execution test. */
+
+int k;
+extern int i;
+extern int j;
+extern char small_buf[];
+extern char *small_pointer;
+
+extern int chkstr ();
+
+int
+bar (n)
+ int n;
+{
+ int r;
+
+ if (i != 1
+ || j != 0
+ || ! chkstr (small_buf, 4)
+ || ! chkstr (small_pointer, 4))
+ return k + 1;
+
+ r = k;
+ k = n;
+ return r;
+}
diff --git a/ld/testsuite/ld-empic/runtesti.s b/ld/testsuite/ld-empic/runtesti.s
new file mode 100644
index 00000000000..efa195301fb
--- /dev/null
+++ b/ld/testsuite/ld-empic/runtesti.s
@@ -0,0 +1,94 @@
+# Assembler initialization code for actual execution test.
+
+# This code becomes the start of the execution test program. It is
+# responsible for initializing the static data, invoking the C code,
+# and returning the result. It is called as though it were a C
+# function with an argument of the address of the data segment.
+
+# We need to know the value of _ftext and _fdata at link time, but we
+# have no way to actually get that at runtime. This is because when
+# this code is compiled with -membedded-pic, the la instruction will
+# be turned into an addiu $gp instruction. We work around this by
+# storing the information in words in the .data section. We then load
+# the values of these words *before* doing the runtime relocation.
+ .sdata
+text_start:
+ .word _ftext
+data_start:
+ .word _fdata
+
+ .globl start
+ .text
+start:
+ # Grab some space on the stack, just as though we were a real
+ # function.
+ addiu $sp,$sp,-8
+ sw $31,0($sp)
+
+ # Save the $gp register, and set it up for our data section.
+ sw $gp,4($sp)
+
+ addu $gp,$4,0x8000 # macro
+
+ # The start of the data segment is in $4.
+
+ # Get the address of start into $5 in a position independent
+ # fashion.
+ .set noreorder
+ $LF1 = . + 8
+ bal $LF1
+ la $5,start-$LF1 # macro
+ .set reorder
+ addu $5,$5,$31
+
+ # Now get the address of _ftext into $6.
+ la $6,_ftext-start # macro
+ addu $6,$6,$5
+
+ # Get the value of _ftext used to link into $7.
+ lw $7,text_start # macro
+
+ # Get the value of _fdata used to link into $8.
+ lw $8,data_start # macro
+
+ # Get the address of __runtime_reloc_start into $9.
+ la $9,__runtime_reloc_start-start # macro
+ addu $9,$9,$5
+
+ # Get the address of __runtime_reloc_stop into $10.
+ la $10,__runtime_reloc_stop-start # macro
+ addu $10,$10,$5
+
+ # The words between $9 and $10 are the runtime initialization
+ # instructions. Step through and relocate them. First set
+ # $11 and $12 to the values to add to text and data sections,
+ # respectively.
+ subu $11,$6,$7
+ subu $12,$4,$8
+
+1:
+ bge $9,$10,3f # macro
+ lw $13,0($9)
+ and $14,$13,0xfffffffe # macro
+ move $15,$11
+ beq $13,$14,2f
+ move $15,$12
+2:
+ addu $14,$14,$4
+ lw $24,0($14)
+ addu $24,$24,$15
+ sw $24,0($14)
+ addiu $9,$9,4
+ b 1b
+3:
+
+ # Now the statically initialized data has been relocated
+ # correctly, and we can call the C code which does the actual
+ # testing.
+ bal foo
+
+ # We return the value returned by the C code.
+ lw $31,0($sp)
+ lw $gp,4($sp)
+ addu $sp,$sp,8
+ j $31
diff --git a/ld/testsuite/ld-scripts/cross1.c b/ld/testsuite/ld-scripts/cross1.c
new file mode 100644
index 00000000000..56789452a5b
--- /dev/null
+++ b/ld/testsuite/ld-scripts/cross1.c
@@ -0,0 +1,6 @@
+extern int foo ();
+int
+func ()
+{
+ return foo ();
+}
diff --git a/ld/testsuite/ld-scripts/cross1.t b/ld/testsuite/ld-scripts/cross1.t
new file mode 100644
index 00000000000..e1948c9e09f
--- /dev/null
+++ b/ld/testsuite/ld-scripts/cross1.t
@@ -0,0 +1,6 @@
+NOCROSSREFS ( .text .data )
+SECTIONS
+{
+ .text : { tmpdir/cross1.o }
+ .data : { tmpdir/cross2.o }
+}
diff --git a/ld/testsuite/ld-scripts/cross2.c b/ld/testsuite/ld-scripts/cross2.c
new file mode 100644
index 00000000000..414317712d1
--- /dev/null
+++ b/ld/testsuite/ld-scripts/cross2.c
@@ -0,0 +1,5 @@
+int
+foo ()
+{
+ return 1;
+}
diff --git a/ld/testsuite/ld-scripts/cross2.t b/ld/testsuite/ld-scripts/cross2.t
new file mode 100644
index 00000000000..cf046f6c36b
--- /dev/null
+++ b/ld/testsuite/ld-scripts/cross2.t
@@ -0,0 +1,6 @@
+NOCROSSREFS ( .text .data )
+SECTIONS
+{
+ .text : { *(.text) *(.pr) }
+ .data : { *(.data) *(.sdata) *(.rw) *(.tc0) *(.tc) }
+}
diff --git a/ld/testsuite/ld-scripts/cross3.c b/ld/testsuite/ld-scripts/cross3.c
new file mode 100644
index 00000000000..1848c32fd0b
--- /dev/null
+++ b/ld/testsuite/ld-scripts/cross3.c
@@ -0,0 +1,7 @@
+int i = 4;
+
+int
+foo ()
+{
+ return i;
+}
diff --git a/ld/testsuite/ld-scripts/crossref.exp b/ld/testsuite/ld-scripts/crossref.exp
new file mode 100644
index 00000000000..fee97595a37
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crossref.exp
@@ -0,0 +1,77 @@
+# Test NOCROSSREFS in a linker script.
+# By Ian Lance Taylor, Cygnus Support.
+
+set test1 "NOCROSSREFS 1"
+set test2 "NOCROSSREFS 2"
+
+if { [which $CC] == 0 } {
+ untested $test1
+ untested $test2
+ return
+}
+
+if { ![ld_compile $CC "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \
+ || ![ld_compile $CC "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } {
+ unresolved $test1
+ unresolved $test2
+ return
+}
+
+set flags ""
+
+# The a29k compiled code calls V_SPILL and V_FILL. Since we don't
+# need to run this code, but we don't have definitions for those
+# functions, we just define them out.
+if [istarget a29k*-*-*] {
+ set flags "$flags --defsym V_SPILL=0 --defsym V_FILL=0"
+}
+
+# hppa-elf needs a definition for $global$.
+if [istarget hppa*-*-*] {
+ set flags "$flags --defsym '\$global\$'=0"
+}
+
+verbose -log "$ld $flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o"
+
+catch "exec $ld $flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o" exec_output
+
+set exec_output [prune_warnings $exec_output]
+
+regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
+
+if [string match "" $exec_output] then {
+ fail $test1
+} else {
+ verbose -log "$exec_output"
+ if [regexp "prohibited cross reference from .* to `foo' in" $exec_output] {
+ pass $test1
+ } else {
+ fail $test1
+ }
+}
+
+# Check cross references within a single object.
+
+if { ![ld_compile $CC "$srcdir/$subdir/cross3.c" tmpdir/cross3.o] } {
+ unresolved $test2
+ return
+}
+
+verbose -log "$ld $flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o"
+
+catch "exec $ld $flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o" exec_output
+
+set exec_output [prune_warnings $exec_output]
+
+regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
+
+if [string match "" $exec_output] then {
+ fail $test2
+} else {
+ verbose -log "$exec_output"
+ if [regexp "prohibited cross reference from .* to `.*' in" $exec_output] {
+ pass $test2
+ } else {
+ fail $test2
+ }
+}
diff --git a/ld/testsuite/ld-scripts/defined.exp b/ld/testsuite/ld-scripts/defined.exp
new file mode 100644
index 00000000000..6da26bc3bc2
--- /dev/null
+++ b/ld/testsuite/ld-scripts/defined.exp
@@ -0,0 +1,39 @@
+# Test DEFINED in a linker script.
+# By Ian Lance Taylor, Cygnus Support.
+
+set testname "DEFINED"
+set prms_id 5699
+
+if ![ld_assemble $as $srcdir/$subdir/defined.s tmpdir/def.o] {
+ unresolved $testname
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/def "-T $srcdir/$subdir/defined.t tmpdir/def.o"] {
+ fail $testname
+} else {
+ if ![ld_nm $nm tmpdir/def] {
+ unresolved $testname
+ } else {
+ if {![info exists nm_output(value1)] \
+ || ![info exists nm_output(value2)]} {
+ send_log "bad output from nm\n"
+ verbose "bad output from nm"
+ fail $testname
+ } else {
+ if {$nm_output(value1) != 1} {
+ send_log "value1 == $nm_output(value1)\n"
+ verbose "value1 == $nm_output(value1)"
+ fail $testname
+ } else {
+ if {$nm_output(value2) != 2} {
+ send_log "value2 == $nm_output(value2)\n"
+ verbose "value2 == $nm_output(value2)"
+ fail $testname
+ } else {
+ pass $testname
+ }
+ }
+ }
+ }
+}
diff --git a/ld/testsuite/ld-scripts/defined.s b/ld/testsuite/ld-scripts/defined.s
new file mode 100644
index 00000000000..a364bbbbe6c
--- /dev/null
+++ b/ld/testsuite/ld-scripts/defined.s
@@ -0,0 +1,2 @@
+ .globl defined
+ defined = 1
diff --git a/ld/testsuite/ld-scripts/defined.t b/ld/testsuite/ld-scripts/defined.t
new file mode 100644
index 00000000000..c1ef1b6a798
--- /dev/null
+++ b/ld/testsuite/ld-scripts/defined.t
@@ -0,0 +1,7 @@
+SECTIONS {
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss) *(COMMON) }
+}
+value1 = DEFINED (defined) ? 1 : 2;
+value2 = DEFINED (undefined) ? 1 : 2;
diff --git a/ld/testsuite/ld-scripts/phdrs.exp b/ld/testsuite/ld-scripts/phdrs.exp
new file mode 100644
index 00000000000..34ee00f899c
--- /dev/null
+++ b/ld/testsuite/ld-scripts/phdrs.exp
@@ -0,0 +1,57 @@
+# Test PHDRS in a linker script.
+# By Ian Lance Taylor, Cygnus Support.
+
+# PHDRS is only meaningful for ELF.
+if { ![istarget *-*-sysv4*] \
+ && ![istarget *-*-unixware*] \
+ && ![istarget *-*-elf*] \
+ && ![istarget *-*-eabi*] \
+ && ![istarget *-*-linux*] \
+ && ![istarget *-*-irix5*] \
+ && ![istarget *-*-irix6*] \
+ && ![istarget *-*-solaris2*] } {
+ return
+}
+
+if { [istarget *-*-linuxaout*] \
+ || [istarget *-*-linuxoldld*] } {
+ return
+}
+
+# This is a very simplistic test.
+
+set testname "PHDRS"
+
+if ![ld_assemble $as $srcdir/$subdir/phdrs.s tmpdir/phdrs.o] {
+ unresolved $testname
+ return
+}
+
+set phdrs_regexp \
+".*Program Header:.*PHDR *off *0x00*34 *vaddr *0x00*80034 *paddr *0x00*80034.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* flags r--.*LOAD *off *0x00* *vaddr *0x00*80000 *paddr *0x00*80000.*filesz *0x00*\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags r-x.*LOAD *off *0x0\[0-9a-f\]* *vaddr *0x00*80*\[0-9a-f\]* *paddr *0x00*80*\[0-9a-f\]*.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags *rw-.*"
+
+# On a 64 bit ELF format, we need different numbers.
+if { [istarget alpha*-*-*] } then {
+ set phdrs_regexp \
+".*Program Header:.*PHDR *off *0x00*40 *vaddr *0x00*80040 *paddr *0x00*80040.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* flags r--.*LOAD *off *0x00* *vaddr *0x00*80000 *paddr *0x00*80000.*filesz *0x00*\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags r-x.*LOAD *off *0x0\[0-9a-f\]* *vaddr *0x00*80*\[0-9a-f\]* *paddr *0x00*80*\[0-9a-f\]*.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags *rw-.*"
+}
+
+if ![ld_simple_link $ld tmpdir/phdrs "-T $srcdir/$subdir/phdrs.t tmpdir/phdrs.o"] {
+ fail $testname
+} else {
+ if {[which $objdump] == 0} {
+ unresolved $testname
+ return
+ }
+
+ verbose -log "$objdump --private tmpdir/phdrs"
+ catch "exec $objdump --private tmpdir/phdrs" exec_output
+ set exec_output [prune_warnings $exec_output]
+ verbose -log $exec_output
+
+ if [regexp $phdrs_regexp $exec_output] {
+ pass $testname
+ } else {
+ fail $testname
+ }
+}
diff --git a/ld/testsuite/ld-scripts/phdrs.s b/ld/testsuite/ld-scripts/phdrs.s
new file mode 100644
index 00000000000..ec1f0d17e6e
--- /dev/null
+++ b/ld/testsuite/ld-scripts/phdrs.s
@@ -0,0 +1,8 @@
+ .text
+
+ .long 1
+
+ .data
+
+ .long 2
+
diff --git a/ld/testsuite/ld-scripts/phdrs.t b/ld/testsuite/ld-scripts/phdrs.t
new file mode 100644
index 00000000000..8f710e23fdc
--- /dev/null
+++ b/ld/testsuite/ld-scripts/phdrs.t
@@ -0,0 +1,14 @@
+PHDRS
+{
+ header PT_PHDR PHDRS ;
+ text PT_LOAD FILEHDR PHDRS ;
+ data PT_LOAD ;
+}
+
+SECTIONS
+{
+ . = 0x80000 + SIZEOF_HEADERS;
+ .text : { *(.text) } :text
+ .data : { *(.data) } :data
+ /DISCARD/ : { *(.reginfo) }
+}
diff --git a/ld/testsuite/ld-scripts/script.exp b/ld/testsuite/ld-scripts/script.exp
new file mode 100644
index 00000000000..fe0a0411188
--- /dev/null
+++ b/ld/testsuite/ld-scripts/script.exp
@@ -0,0 +1,64 @@
+# Test basic linker script functionality
+# By Ian Lance Taylor, Cygnus Support
+
+set testname "script"
+
+if ![ld_assemble $as $srcdir/$subdir/script.s tmpdir/script.o] {
+ unresolved $testname
+ return
+}
+
+proc check_script { } {
+ global nm
+ global testname
+ global nm_output
+
+ if ![ld_nm $nm tmpdir/script] {
+ unresolved $testname
+ } else {
+ if {![info exists nm_output(text_start)] \
+ || ![info exists nm_output(text_end)] \
+ || ![info exists nm_output(data_start)] \
+ || ![info exists nm_output(data_end)]} {
+ send_log "bad output from nm\n"
+ verbose "bad output from nm"
+ fail $testname
+ } else {
+ if {$nm_output(text_start) != 0x100} {
+ send_log "text_start == $nm_output(text_start)\n"
+ verbose "text_start == $nm_output(text_start)"
+ fail $testname
+ } else { if {$nm_output(text_end) < 0x104 \
+ || $nm_output(text_end) > 0x110} {
+ send_log "text_end == $nm_output(text_end)\n"
+ verbose "text_end == $nm_output(text_end)"
+ fail $testname
+ } else { if {$nm_output(data_start) != 0x1000} {
+ send_log "data_start == $nm_output(data_start)\n"
+ verbose "data_start == $nm_output(data_start)"
+ fail $testname
+ } else { if {$nm_output(data_end) < 0x1004 \
+ || $nm_output(data_end) > 0x1010} {
+ send_log "data_end == $nm_output(data_end)\n"
+ verbose "data_end == $nm_output(data_end)"
+ fail $testname
+ } else {
+ pass $testname
+ } } } }
+ }
+ }
+}
+
+if ![ld_simple_link $ld tmpdir/script "-T $srcdir/$subdir/script.t tmpdir/script.o"] {
+ fail $testname
+} else {
+ check_script
+}
+
+set testname "MRI script"
+
+if ![ld_simple_link $ld tmpdir/script "-c $srcdir/$subdir/scriptm.t"] {
+ fail $testname
+} else {
+ check_script
+}
diff --git a/ld/testsuite/ld-scripts/script.s b/ld/testsuite/ld-scripts/script.s
new file mode 100644
index 00000000000..d7b65b0df55
--- /dev/null
+++ b/ld/testsuite/ld-scripts/script.s
@@ -0,0 +1,8 @@
+ .text
+ .globl text_symbol
+text_symbol:
+ .long 1
+ .data
+ .globl data_symbol
+data_symbol:
+ .long 2
diff --git a/ld/testsuite/ld-scripts/script.t b/ld/testsuite/ld-scripts/script.t
new file mode 100644
index 00000000000..ee7a48a9f60
--- /dev/null
+++ b/ld/testsuite/ld-scripts/script.t
@@ -0,0 +1,16 @@
+SECTIONS
+{
+ .text 0x100 : {
+ text_start = .;
+ *(.text)
+ *(.pr)
+ text_end = .;
+ }
+ . = 0x1000;
+ .data : {
+ data_start = .;
+ *(.data)
+ *(.rw)
+ data_end = .;
+ }
+}
diff --git a/ld/testsuite/ld-scripts/scriptm.t b/ld/testsuite/ld-scripts/scriptm.t
new file mode 100644
index 00000000000..57ccae13662
--- /dev/null
+++ b/ld/testsuite/ld-scripts/scriptm.t
@@ -0,0 +1,10 @@
+* MRI script
+sect .text = $100 ; .text start address
+sect .data = 1000h ; .data start address
+public text_start = $100
+public text_end = # continuation line
+ text_start + 4
+public data_start = 1000h
+public data_end = data_start + 4
+
+load tmpdir/script.o
diff --git a/ld/testsuite/ld-scripts/sizeof.exp b/ld/testsuite/ld-scripts/sizeof.exp
new file mode 100644
index 00000000000..3bdefd4f0dc
--- /dev/null
+++ b/ld/testsuite/ld-scripts/sizeof.exp
@@ -0,0 +1,55 @@
+# Test SIZEOF in a linker script.
+# By Ian Lance Taylor, Cygnus Support
+# Based on a bug report from anders.blomdell@control.lth.se.
+
+set testname "SIZEOF"
+
+if ![ld_assemble $as $srcdir/$subdir/sizeof.s tmpdir/sizeof.o] {
+ unresolved $testname
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/sizeof "-T $srcdir/$subdir/sizeof.t tmpdir/sizeof.o"] {
+ fail $testname
+ return
+}
+
+if ![ld_nm $nm tmpdir/sizeof] {
+ unresolved $testname
+ return
+}
+
+if {![info exists nm_output(text_start)] \
+ || ![info exists nm_output(text_end)] \
+ || ![info exists nm_output(data_start)] \
+ || ![info exists nm_output(data_end)] \
+ || ![info exists nm_output(sizeof_text)] \
+ || ![info exists nm_output(sizeof_data)]} {
+ send_log "bad output from nm\n"
+ verbose "bad output from nm"
+ fail $testname
+ return
+}
+
+if {$nm_output(text_end) - $nm_output(text_start) != $nm_output(sizeof_text)} {
+ send_log "text_end - text_start != sizeof_text\n"
+ verbose "text_end - text_start != sizeof_text"
+ fail $testname
+ return
+}
+
+if {$nm_output(data_end) - $nm_output(data_start) != $nm_output(sizeof_data)} {
+ send_log "data_end - data_start != sizeof_data\n"
+ verbose "data_end - data_start != sizeof_data"
+ fail $testname
+ return
+}
+
+if {$nm_output(sizeof_text) != $nm_output(sizeof_data)} {
+ send_log "sizeof_text != sizeof_data\n"
+ verbose "sizeof_text != sizeof_data"
+ fail $testname
+ return
+}
+
+pass $testname
diff --git a/ld/testsuite/ld-scripts/sizeof.s b/ld/testsuite/ld-scripts/sizeof.s
new file mode 100644
index 00000000000..e221ca3c0b3
--- /dev/null
+++ b/ld/testsuite/ld-scripts/sizeof.s
@@ -0,0 +1 @@
+ .space 16
diff --git a/ld/testsuite/ld-scripts/sizeof.t b/ld/testsuite/ld-scripts/sizeof.t
new file mode 100644
index 00000000000..6244a37b7ac
--- /dev/null
+++ b/ld/testsuite/ld-scripts/sizeof.t
@@ -0,0 +1,17 @@
+SECTIONS {
+ .text :
+ {
+ text_start = .;
+ tmpdir/sizeof.o
+ text_end = .;
+ }
+ .data :
+ {
+ data_start = .;
+ . = . + SIZEOF(.text);
+ data_end = .;
+ }
+}
+
+sizeof_text = SIZEOF(.text);
+sizeof_data = SIZEOF(.data);
diff --git a/ld/testsuite/ld-scripts/weak.exp b/ld/testsuite/ld-scripts/weak.exp
new file mode 100644
index 00000000000..f69db5793cc
--- /dev/null
+++ b/ld/testsuite/ld-scripts/weak.exp
@@ -0,0 +1,57 @@
+# Test weak symbols.
+# By Ian Lance Taylor, Cygnus Solutions.
+
+set testname "weak symbols"
+
+# This test only works for ELF targets. It ought to work for some
+# a.out targets, but it doesn't.
+
+if { ![istarget *-*-sysv4*] \
+ && ![istarget *-*-unixware*] \
+ && ![istarget *-*-elf*] \
+ && ![istarget *-*-eabi*] \
+ && ![istarget *-*-linux*] \
+ && ![istarget *-*-irix5*] \
+ && ![istarget *-*-irix6*] \
+ && ![istarget *-*-solaris2*] } then {
+ return
+}
+
+if { [istarget *-*-linuxaout*] \
+ || [istarget *-*-linuxoldld*] } {
+ return
+}
+
+if {! [ld_assemble $as $srcdir/$subdir/weak1.s tmpdir/weak1.o]
+ || ! [ld_assemble $as $srcdir/$subdir/weak2.s tmpdir/weak2.o]} then {
+ # It's OK if .weak doesn't work on this target.
+ unresolved $testname
+ return
+}
+
+set weak_regexp_big \
+".*Contents of section .text:.*1000 00001008 0000200c 12121212 34343434.*Contents of section .data:.*2000 00001008 0000200c 56565656 78787878.*"
+
+set weak_regexp_little \
+".*Contents of section .text:.*1000 08100000 0c200000 12121212 34343434.*Contents of section .data:.*2000 08100000 0c200000 56565656 78787878.*"
+
+if {! [ld_simple_link $ld tmpdir/weak "-T $srcdir/$subdir/weak.t tmpdir/weak1.o tmpdir/weak2.o"] } then {
+ fail $testname
+} else {
+ if {[which $objdump] == 0} then {
+ unresolved $testname
+ return
+ }
+
+ verbose -log "$objdump -s tmpdir/weak"
+ catch "exec $objdump -s tmpdir/weak" exec_output
+ set exec_output [prune_warnings $exec_output]
+ verbose -log $exec_output
+
+ if {[regexp $weak_regexp_big $exec_output] \
+ || [regexp $weak_regexp_little $exec_output] } then {
+ pass $testname
+ } else {
+ fail $testname
+ }
+}
diff --git a/ld/testsuite/ld-scripts/weak.t b/ld/testsuite/ld-scripts/weak.t
new file mode 100644
index 00000000000..6cd013e11f7
--- /dev/null
+++ b/ld/testsuite/ld-scripts/weak.t
@@ -0,0 +1,12 @@
+SECTIONS
+{
+ .text 0x1000 : {
+ tmpdir/weak1.o(.data)
+ }
+ .data 0x2000 : {
+ tmpdir/weak2.o(.data)
+ }
+ /DISCARD/ : {
+ *(*)
+ }
+}
diff --git a/ld/testsuite/ld-scripts/weak1.s b/ld/testsuite/ld-scripts/weak1.s
new file mode 100644
index 00000000000..046fbe1fa46
--- /dev/null
+++ b/ld/testsuite/ld-scripts/weak1.s
@@ -0,0 +1,11 @@
+.data
+ .global foo1
+ .global sym1
+ .weak sym2
+foo1:
+ .long sym1
+ .long sym2
+sym1:
+ .long 0x12121212
+sym2:
+ .long 0x34343434
diff --git a/ld/testsuite/ld-scripts/weak2.s b/ld/testsuite/ld-scripts/weak2.s
new file mode 100644
index 00000000000..04edff5e541
--- /dev/null
+++ b/ld/testsuite/ld-scripts/weak2.s
@@ -0,0 +1,11 @@
+.data
+ .global foo2
+ .weak sym1
+ .global sym2
+foo2:
+ .long sym1
+ .long sym2
+sym1:
+ .long 0x56565656
+sym2:
+ .long 0x78787878
diff --git a/ld/testsuite/ld-selective/1.c b/ld/testsuite/ld-selective/1.c
new file mode 100644
index 00000000000..12023677027
--- /dev/null
+++ b/ld/testsuite/ld-selective/1.c
@@ -0,0 +1,12 @@
+/* _start should be the only thing left after GC. */
+
+void _start() __asm__("_start");
+void _start()
+{
+}
+
+void dropme1()
+{
+}
+
+int dropme2[102] = { 0 };
diff --git a/ld/testsuite/ld-selective/2.c b/ld/testsuite/ld-selective/2.c
new file mode 100644
index 00000000000..729588760c3
--- /dev/null
+++ b/ld/testsuite/ld-selective/2.c
@@ -0,0 +1,19 @@
+/* Normally we should loose foo and keep _start and _init.
+ With -u foo, we should keep that as well. */
+
+void _start() __asm__("_start");
+void _start()
+{
+}
+
+void __attribute__((section(".init")))
+_init()
+{
+}
+
+int foo() __asm__("foo");
+int foo()
+{
+ static int x = 1;
+ return x++;
+}
diff --git a/ld/testsuite/ld-selective/3.cc b/ld/testsuite/ld-selective/3.cc
new file mode 100644
index 00000000000..852bc5d0454
--- /dev/null
+++ b/ld/testsuite/ld-selective/3.cc
@@ -0,0 +1,33 @@
+struct A
+{
+ virtual void foo();
+ virtual void bar();
+};
+
+void A::foo() { } // keep
+void A::bar() { } // loose
+
+struct B : public A
+{
+ virtual void foo();
+};
+
+void B::foo() { } // keep
+
+void _start() __asm__("_start"); // keep
+
+A a; // keep
+B b;
+A *getme() { return &a; } // keep
+
+void _start()
+{
+ getme()->foo();
+}
+
+// In addition, keep A's virtual table.
+
+// We'll wind up keeping `b' and thus B's virtual table because
+// `a' and `b' are both referenced from the constructor function.
+
+extern "C" void __main() { }
diff --git a/ld/testsuite/ld-selective/4.cc b/ld/testsuite/ld-selective/4.cc
new file mode 100644
index 00000000000..9df26ac872c
--- /dev/null
+++ b/ld/testsuite/ld-selective/4.cc
@@ -0,0 +1,28 @@
+struct A
+{
+ virtual void foo();
+ virtual void bar();
+};
+
+void A::foo() { } // loose
+void A::bar() { } // keep
+
+struct B : public A
+{
+ virtual void foo();
+};
+
+void B::foo() { } // loose
+
+void _start() __asm__("_start"); // keep
+
+A a; // keep
+B b;
+A *getme() { return &a; } // keep
+
+void _start()
+{
+ getme()->bar();
+}
+
+extern "C" void __main() { }
diff --git a/ld/testsuite/ld-selective/5.cc b/ld/testsuite/ld-selective/5.cc
new file mode 100644
index 00000000000..5179d918481
--- /dev/null
+++ b/ld/testsuite/ld-selective/5.cc
@@ -0,0 +1,32 @@
+// This test currently fails because the C++ front end emits `A' as
+// the base class called rather than `B' as it ought. At least it
+// is erroring on the safe side...
+
+struct A
+{
+ virtual void foo();
+ virtual void bar();
+};
+
+void A::foo() { } // loose
+void A::bar() { } // loose
+
+struct B : public A
+{
+ virtual void foo();
+};
+
+void B::foo() { } // keep
+
+void _start() __asm__("_start"); // keep
+
+A a;
+B b; // keep
+B *getme() { return &b; } // keep
+
+void _start()
+{
+ getme()->foo();
+}
+
+extern "C" void __main() { }
diff --git a/ld/testsuite/ld-selective/selective.exp b/ld/testsuite/ld-selective/selective.exp
new file mode 100644
index 00000000000..e6a9d97fa69
--- /dev/null
+++ b/ld/testsuite/ld-selective/selective.exp
@@ -0,0 +1,208 @@
+# Expect script for LD selective linking tests
+# Copyright (C) 1998, 1999 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Catherine Moore (clm@cygnus.com)
+# Make sure that constructors are handled correctly.
+
+
+# COFF based ports do not support selective linking
+if {[istarget "*-*-coff" "*-*-pe"]} {
+ return
+}
+
+set test1 "selective1"
+set test2 "selective2"
+set test3 "selective3"
+set test4 "selective4"
+set test5 "selective5"
+set test6 "selective6"
+
+set cflags "-w -O2 -ffunction-sections -fdata-sections"
+set cxxflags "-fvtable-gc -fno-exceptions -fno-rtti"
+set ldflags "--gc-sections -Bstatic"
+
+if { [which $CXX] == 0 } {
+ untested $test1
+ untested $test2
+ untested $test3
+ untested $test4
+ untested $test5
+ untested $test6
+ return
+}
+
+if { ![ld_compile "$CC $cflags" $srcdir/$subdir/1.c tmpdir/1.o]} {
+ unresolved $test1
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/1.x "$ldflags tmpdir/1.o"] {
+ fail $test1
+} else {
+ if ![ld_nm $nm tmpdir/1.x] {
+ unresolved $test1
+ } else {
+ if {[info exists nm_output(dropme1)]} {
+ send_log "dropme1 == $nm_output(dropme1)\n"
+ verbose "dropme1 == $nm_output(dropme1)"
+ fail $test1
+ } else {
+ if {[info exists nm_output(dropme2)]} {
+ send_log "dropme2 == $nm_output(dropme2)\n"
+ verbose "dropme2 == $nm_output(dropme2)"
+ fail $test1
+ } else {
+ pass $test1
+ }
+ }
+ }
+ }
+
+if { ![ld_compile "$CC $cflags" $srcdir/$subdir/2.c tmpdir/2.o]} {
+ unresolved $test2
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/2.x "$ldflags tmpdir/2.o"] {
+ fail $test2
+} else {
+ if ![ld_nm $nm tmpdir/2.x] {
+ unresolved $test2
+ } else {
+ if {[info exists nm_output(foo)] } {
+ send_log "foo == $nm_output(foo)\n"
+ verbose "foo== $nm_output(foo)"
+ fail $test2
+ } else {
+ pass $test2
+ }
+ }
+ }
+
+if { ![ld_compile "$CC $cflags" $srcdir/$subdir/2.c tmpdir/2.o]} {
+ unresolved $test3
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/2.x "$ldflags -u foo tmpdir/2.o"] {
+ fail $test3
+} else {
+ if ![ld_nm $nm tmpdir/2.x] {
+ unresolved $test3
+ } else {
+ if {![info exists nm_output(foo)] } {
+ send_log "bad output from nm\n"
+ verbose "bad output from nm"
+ fail $test3
+ } else {
+ if {$nm_output(foo) == 0} {
+ send_log "foo == $nm_output(foo)\n"
+ verbose "foo== $nm_output(foo)"
+ fail $test3
+ } else {
+ pass $test3
+ }
+ }
+ }
+}
+
+setup_xfail "v850*-*-elf"
+
+if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/3.cc tmpdir/3.o]} {
+ unresolved $test4
+ return
+}
+
+setup_xfail "v850*-*-elf"
+
+if ![ld_simple_link $ld tmpdir/3.x "$ldflags tmpdir/3.o"] {
+ fail $test4
+} else {
+ if ![ld_nm $nm tmpdir/3.x] {
+ unresolved $test4
+ } else {
+ if {[info exists nm_output(foo__1B)]} {
+ send_log "foo__1B == $nm_output(foo__1B)\n"
+ verbose "foo__1B == $nm_output(foo__1B)"
+ fail $test4
+ } else {
+ if {[ info exists nm_output(bar__1A)]} {
+ send_log "bar__1A== $nm_output(_bar__1A)\n"
+ verbose "bar__1A == $nm_output(_bar__1A)"
+ fail $test4
+ } else {
+ pass $test4
+ }
+ }
+ }
+}
+
+if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/4.cc tmpdir/4.o]} {
+ unresolved $test5
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/4.x "$ldflags tmpdir/4.o"] {
+ fail $test5
+} else {
+ if ![ld_nm $nm tmpdir/4.x] {
+ unresolved $test5
+ } else {
+ if {[info exists nm_output(foo__1B)]} {
+ send_log "foo__1B == $nm_output(foo__1B)\n"
+ verbose "foo__1B == $nm_output(foo__1B)"
+ fail $test5
+ } else {
+ if {[info exists nm_output(foo__1A)]} {
+ send_log "foo__1A== $nm_output(foo__1A)\n"
+ verbose "foo__1A == $nm_output(foo__1A)"
+ fail $test5
+ } else {
+ pass $test5
+ }
+ }
+ }
+}
+
+setup_xfail "v850*-*-elf"
+
+if { ![ld_compile "$CC $cflags $cxxflags" $srcdir/$subdir/5.cc tmpdir/5.o]} {
+ unresolved $test6
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/5.x "$ldflags tmpdir/5.o"] {
+ fail $test6
+} else {
+ if ![ld_nm $nm tmpdir/5.x] {
+ unresolved $test6
+ } else {
+ if {[info exists nm_output(foo__1B)] } {
+ send_log "foo__1B == $nm_output(foo__1B)\n"
+ verbose "foo__1B == $nm_output(foo__1B)"
+ fail $test6
+ } else {
+ if { [info exists nm_output(foo__1A)]} {
+ send_log "foo__1A== $nm_output(foo__1A)\n"
+ verbose "foo__1A == $nm_output(foo__1A)"
+ fail $test6
+ } else {
+ pass $test6
+ }
+ }
+ }
+}
diff --git a/ld/testsuite/ld-sh/sh.exp b/ld/testsuite/ld-sh/sh.exp
new file mode 100644
index 00000000000..c646d269a89
--- /dev/null
+++ b/ld/testsuite/ld-sh/sh.exp
@@ -0,0 +1,143 @@
+# Expect script for ld-sh tests
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Ian Lance Taylor (ian@cygnus.com)
+#
+
+# Test SH relaxing. This tests the compiler and assembler as well as
+# the linker.
+
+if ![istarget sh*-*-*] {
+ return
+}
+
+set testsimple "SH simple relaxing"
+
+if ![ld_assemble $as "-relax $srcdir/$subdir/sh1.s" tmpdir/sh1.o] {
+ unresolved $testsimple
+} else { if ![ld_simple_link $ld tmpdir/sh1 "-relax tmpdir/sh1.o"] {
+ fail $testsimple
+} else {
+ if ![ld_nm $nm tmpdir/sh1] {
+ unresolved $testsimple
+ } else {
+ if {![info exists nm_output(bar)] \
+ || ![info exists nm_output(foo)]} {
+ send_log "bad output from nm\n"
+ verbose "bad output from nm"
+ fail $testsimple
+ } else {
+ if {$nm_output(bar) != $nm_output(foo) + 4} {
+ send_log "foo == $nm_output(foo)\n"
+ verbose "foo == $nm_output(foo)"
+ send_log "bar == $nm_output(bar)\n"
+ verbose "bar == $nm_output(bar)"
+ fail $testsimple
+ } else {
+ pass $testsimple
+ }
+ }
+ }
+} }
+
+set testsrec "SH relaxing to S-records"
+
+if ![ld_simple_link $ld tmpdir/sh1.s1 "-relax -oformat srec tmpdir/sh1.o"] {
+ fail $testsrec
+} else {
+ # The file name is embedded in the S-records, so create both
+ # files with the same name.
+ catch "exec rm -f tmpdir/sh1.s2" exec_output
+ send_log "mv tmpdir/sh1.s1 tmpdir/sh1.s2\n"
+ verbose "mv tmpdir/sh1.s1 tmpdir/sh1.s2"
+ catch "exec mv tmpdir/sh1.s1 tmpdir/sh1.s2" exec_output
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ unresolved $testsrec
+ } else {
+ send_log "$objcopy -O srec tmpdir/sh1 tmpdir/sh1.s1"
+ verbose "$objcopy -O srec tmpdir/sh1 tmpdir/sh1.s1"
+ catch "exec $objcopy -O srec tmpdir/sh1 tmpdir/sh1.s1" exec_output
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ unresolved $testsrec
+ } else {
+ send_log "cmp tmpdir/sh1.s1 tmpdir/sh1.s2\n"
+ verbose "cmp tmpdir/sh1.s1 tmpdir/sh1.s2"
+ catch "exec cmp tmpdir/sh1.s1 tmpdir/sh1.s2" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ fail $testsrec
+ } else {
+ pass $testsrec
+ }
+ }
+ }
+}
+
+set testlink "SH relaxing"
+set testjsr "SH confirm relaxing"
+set testrun "SH relaxing execution"
+
+if { [which $CC] == 0 } {
+ untested $testlink
+ untested $testjsr
+ untested $testrun
+ return
+}
+
+if {![ld_assemble $as "-relax $srcdir/$subdir/start.s" tmpdir/start.o] \
+ || ![ld_compile $CC "-O -mrelax $srcdir/$subdir/sh2.c" tmpdir/sh2.o]} {
+ unresolved $testlink
+ unresolved $testjsr
+ unresolved $testrun
+ return
+}
+
+if ![ld_simple_link $ld tmpdir/sh2 "-relax tmpdir/start.o tmpdir/sh2.o"] {
+ fail $testlink
+ unresolved $testjsr
+ unresolved $testrun
+ return
+}
+
+pass $testlink
+
+send_log "$objdump -d tmpdir/sh2\n"
+verbose "$objdump -d tmpdir/sh2"
+catch "exec $objdump -d tmpdir/sh2" exec_output
+if [string match "*jsr*" $exec_output] {
+ fail $testjsr
+} else {
+ pass $testjsr
+}
+
+if { ![info exists SIM] || [which $SIM] == 0 } {
+ untested $testrun
+ return
+}
+
+set status [catch "exec $SIM tmpdir/sh2" exec_output]
+if { $status == 0 } {
+ pass $testrun
+} else {
+ fail $testrun
+}
diff --git a/ld/testsuite/ld-sh/sh1.s b/ld/testsuite/ld-sh/sh1.s
new file mode 100644
index 00000000000..d18e4390dcc
--- /dev/null
+++ b/ld/testsuite/ld-sh/sh1.s
@@ -0,0 +1,13 @@
+ .text
+foo:
+L1:
+ mov.l L2,r0
+ .uses L1
+ jsr @r0
+ rts
+ .align 2
+L2:
+ .long bar
+bar:
+ rts
+ .align 4
diff --git a/ld/testsuite/ld-sh/sh2.c b/ld/testsuite/ld-sh/sh2.c
new file mode 100644
index 00000000000..527fe88ce5d
--- /dev/null
+++ b/ld/testsuite/ld-sh/sh2.c
@@ -0,0 +1,120 @@
+int global;
+
+extern void trap (int, int);
+static void quit (int);
+static int foo (int);
+
+int
+main ()
+{
+ if (foo (0) != 0 || global != 0)
+ quit (1);
+ if (foo (1) != 1 || global != 1)
+ quit (1);
+ if (foo (2) != 2 || global != 2)
+ quit (1);
+ if (foo (3) != 3 || global != 3)
+ quit (1);
+ if (foo (4) != 4 || global != 4)
+ quit (1);
+ if (foo (5) != 5 || global != 5)
+ quit (1);
+ if (foo (6) != 6 || global != 6)
+ quit (1);
+ if (foo (7) != 7 || global != 7)
+ quit (1);
+ if (foo (8) != 8 || global != 8)
+ quit (1);
+ quit (0);
+}
+
+void
+__main ()
+{
+}
+
+static void
+quit (int status)
+{
+ trap (1, status);
+}
+
+int
+bar (int i)
+{
+ global = i;
+ return i;
+}
+
+int
+bar0 (int i)
+{
+ global = 0;
+ return i;
+}
+
+int
+bar1 (int i)
+{
+ global = 1;
+ return i;
+}
+
+int
+bar2 (int i)
+{
+ global = 2;
+ return i;
+}
+
+int
+bar3 (int i)
+{
+ global = 3;
+ return i;
+}
+
+int
+bar4 (int i)
+{
+ global = 4;
+ return i;
+}
+
+int
+bar5 (int i)
+{
+ global = 5;
+ return i;
+}
+
+int
+bar6 (int i)
+{
+ global = 6;
+ return i;
+}
+
+int
+bar7 (int i)
+{
+ global = 7;
+ return i;
+}
+
+int
+foo (int i)
+{
+ switch (i)
+ {
+ case 0: bar0 (0); return 0;
+ case 1: bar1 (1); return 1;
+ case 2: bar2 (2); return 2;
+ case 3: bar3 (3); return 3;
+ case 4: bar4 (4); return 4;
+ case 5: bar5 (5); return 5;
+ case 6: bar6 (6); return 6;
+ case 7: bar7 (7); return 7;
+ default: return bar (i);
+ }
+}
diff --git a/ld/testsuite/ld-sh/start.s b/ld/testsuite/ld-sh/start.s
new file mode 100644
index 00000000000..2af4c799f33
--- /dev/null
+++ b/ld/testsuite/ld-sh/start.s
@@ -0,0 +1,27 @@
+ .section .text
+ .global start
+start:
+
+ mov.l stack_k,r15
+
+ ! call the mainline
+L1:
+ mov.l main_k,r0
+ .uses L1
+ jsr @r0
+ nop
+
+ .align 2
+stack_k:
+ .long _stack
+main_k:
+ .long _main
+
+ .global _trap
+_trap:
+ trapa #3
+ rts
+ nop
+
+ .section .stack
+_stack: .long 0xdeaddead
diff --git a/ld/testsuite/ld-shared/elf-offset.ld b/ld/testsuite/ld-shared/elf-offset.ld
new file mode 100644
index 00000000000..dfe429309a7
--- /dev/null
+++ b/ld/testsuite/ld-shared/elf-offset.ld
@@ -0,0 +1,168 @@
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x100000;
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.text :
+ {
+ *(.rel.text)
+ *(.rel.text.*)
+ *(.rel.gnu.linkonce.t*)
+ }
+ .rela.text :
+ {
+ *(.rela.text)
+ *(.rela.text.*)
+ *(.rela.gnu.linkonce.t*)
+ }
+ .rel.data :
+ {
+ *(.rel.data)
+ *(.rel.data.*)
+ *(.rel.gnu.linkonce.d*)
+ }
+ .rela.data :
+ {
+ *(.rela.data)
+ *(.rela.data.*)
+ *(.rela.gnu.linkonce.d*)
+ }
+ .rel.rodata :
+ {
+ *(.rel.rodata)
+ *(.rel.rodata.*)
+ *(.rel.gnu.linkonce.r*)
+ }
+ .rela.rodata :
+ {
+ *(.rela.rodata)
+ *(.rela.rodata.*)
+ *(.rela.gnu.linkonce.r*)
+ }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { KEEP (*(.init)) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .fini : { KEEP (*(.fini)) } =0x9090
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r*)
+ }
+ .rodata1 : { *(.rodata1) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(0x1000) + (. & (0x1000 - 1));
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of the constructors, so
+ we make sure it is first. Because this is a wildcard, it
+ doesn't matter if the user does not actually link against
+ crtbegin.o; the linker won't look for a file to match a
+ wildcard. The wildcard also means that it doesn't matter which
+ directory crtbegin.o is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) *(.sdata.*) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/ld/testsuite/ld-shared/main.c b/ld/testsuite/ld-shared/main.c
new file mode 100644
index 00000000000..4fcfdaa1271
--- /dev/null
+++ b/ld/testsuite/ld-shared/main.c
@@ -0,0 +1,81 @@
+/* This is the main program for the shared library test. */
+
+#include <stdio.h>
+
+int mainvar = 1;
+int overriddenvar = 2;
+extern int shlibvar1;
+
+extern int shlib_mainvar ();
+extern int shlib_overriddenvar ();
+extern int shlib_shlibvar1 ();
+extern int shlib_shlibvar2 ();
+extern int shlib_shlibcall ();
+extern int shlib_maincall ();
+extern int shlib_checkfunptr1 ();
+extern int shlib_checkfunptr2 ();
+extern int (*shlib_getfunptr1 ()) ();
+extern int (*shlib_getfunptr2 ()) ();
+extern int shlib_check ();
+
+/* This function is called by the shared library. */
+
+int
+main_called ()
+{
+ return 6;
+}
+
+/* This function overrides a function in the shared library. */
+
+int
+shlib_overriddencall2 ()
+{
+ return 8;
+}
+
+int
+main ()
+{
+ int (*p) ();
+
+ printf ("mainvar == %d\n", mainvar);
+ printf ("overriddenvar == %d\n", overriddenvar);
+ printf ("shlibvar1 == %d\n", shlibvar1);
+#ifndef XCOFF_TEST
+ printf ("shlib_mainvar () == %d\n", shlib_mainvar ());
+ printf ("shlib_overriddenvar () == %d\n", shlib_overriddenvar ());
+#endif
+ printf ("shlib_shlibvar1 () == %d\n", shlib_shlibvar1 ());
+ printf ("shlib_shlibvar2 () == %d\n", shlib_shlibvar2 ());
+ printf ("shlib_shlibcall () == %d\n", shlib_shlibcall ());
+#ifndef XCOFF_TEST
+ printf ("shlib_shlibcall2 () == %d\n", shlib_shlibcall2 ());
+ printf ("shlib_maincall () == %d\n", shlib_maincall ());
+#endif
+ printf ("main_called () == %d\n", main_called ());
+ printf ("shlib_checkfunptr1 (shlib_shlibvar1) == %d\n",
+ shlib_checkfunptr1 (shlib_shlibvar1));
+#ifndef XCOFF_TEST
+ printf ("shlib_checkfunptr2 (main_called) == %d\n",
+ shlib_checkfunptr2 (main_called));
+#endif
+ p = shlib_getfunptr1 ();
+ printf ("shlib_getfunptr1 () ");
+ if (p == shlib_shlibvar1)
+ printf ("==");
+ else
+ printf ("!=");
+ printf (" shlib_shlibvar1\n");
+#ifndef XCOFF_TEST
+ p = shlib_getfunptr2 ();
+ printf ("shlib_getfunptr2 () ");
+ if (p == main_called)
+ printf ("==");
+ else
+ printf ("!=");
+ printf (" main_called\n");
+#endif
+ printf ("shlib_check () == %d\n", shlib_check ());
+ return 0;
+}
diff --git a/ld/testsuite/ld-shared/sh1.c b/ld/testsuite/ld-shared/sh1.c
new file mode 100644
index 00000000000..e31e06a2594
--- /dev/null
+++ b/ld/testsuite/ld-shared/sh1.c
@@ -0,0 +1,166 @@
+/* This is part of the shared library ld test. This file becomes part
+ of a shared library. */
+
+/* This variable is supplied by the main program. */
+#ifndef XCOFF_TEST
+extern int mainvar;
+#endif
+
+/* This variable is defined in the shared library, and overridden by
+ the main program. */
+#ifndef XCOFF_TEST
+int overriddenvar = -1;
+#endif
+
+/* This variable is defined in the shared library. */
+int shlibvar1 = 3;
+
+/* This variable is defined by another object in the shared library. */
+extern int shlibvar2;
+
+/* These functions return the values of the above variables as seen in
+ the shared library. */
+
+#ifndef XCOFF_TEST
+int
+shlib_mainvar ()
+{
+ return mainvar;
+}
+#endif
+
+#ifndef XCOFF_TEST
+int
+shlib_overriddenvar ()
+{
+ return overriddenvar;
+}
+#endif
+
+int
+shlib_shlibvar1 ()
+{
+ return shlibvar1;
+}
+
+int
+shlib_shlibvar2 ()
+{
+ return shlibvar2;
+}
+
+/* This function calls a function defined by another object in the
+ shared library. */
+
+extern int shlib_shlibcalled ();
+
+int
+shlib_shlibcall ()
+{
+ return shlib_shlibcalled ();
+}
+
+#ifndef XCOFF_TEST
+/* This function calls a function defined in this object in the shared
+ library. The main program will override the called function. */
+
+extern int shlib_overiddencall2 ();
+
+int
+shlib_shlibcall2 ()
+{
+ return shlib_overriddencall2 ();
+}
+
+int
+shlib_overriddencall2 ()
+{
+ return 7;
+}
+#endif
+
+/* This function calls a function defined by the main program. */
+
+#ifndef XCOFF_TEST
+extern int main_called ();
+
+int
+shlib_maincall ()
+{
+ return main_called ();
+}
+#endif
+
+/* This function is passed a function pointer to shlib_mainvar. It
+ confirms that the pointer compares equally. */
+
+int
+shlib_checkfunptr1 (p)
+ int (*p) ();
+{
+ return p == shlib_shlibvar1;
+}
+
+/* This function is passed a function pointer to main_called. It
+ confirms that the pointer compares equally. */
+
+#ifndef XCOFF_TEST
+int
+shlib_checkfunptr2 (p)
+ int (*p) ();
+{
+ return p == main_called;
+}
+#endif
+
+/* This function returns a pointer to shlib_mainvar. */
+
+int
+(*shlib_getfunptr1 ()) ()
+{
+ return shlib_shlibvar1;
+}
+
+/* This function returns a pointer to main_called. */
+
+#ifndef XCOFF_TEST
+int
+(*shlib_getfunptr2 ()) ()
+{
+ return main_called;
+}
+#endif
+
+/* This function makes sure that constant data and local functions
+ work. */
+
+#ifndef __STDC__
+#define const
+#endif
+
+static int i = 6;
+static const char *str = "Hello, world\n";
+
+int
+shlib_check ()
+{
+ const char *s1, *s2;
+
+ if (i != 6)
+ return 0;
+
+ /* To isolate the test, don't rely on any external functions, such
+ as strcmp. */
+ s1 = "Hello, world\n";
+ s2 = str;
+ while (*s1 != '\0')
+ if (*s1++ != *s2++)
+ return 0;
+ if (*s2 != '\0')
+ return 0;
+
+ if (shlib_shlibvar1 () != 3)
+ return 0;
+
+ return 1;
+}
diff --git a/ld/testsuite/ld-shared/sh2.c b/ld/testsuite/ld-shared/sh2.c
new file mode 100644
index 00000000000..013a4e0994f
--- /dev/null
+++ b/ld/testsuite/ld-shared/sh2.c
@@ -0,0 +1,14 @@
+/* This is part of the shared library ld test. This file becomes part
+ of a shared library. */
+
+/* This variable is defined here, and referenced by another file in
+ the shared library. */
+int shlibvar2 = 4;
+
+/* This function is called by another file in the shared library. */
+
+int
+shlib_shlibcalled ()
+{
+ return 5;
+}
diff --git a/ld/testsuite/ld-shared/shared.dat b/ld/testsuite/ld-shared/shared.dat
new file mode 100644
index 00000000000..40ee37ff533
--- /dev/null
+++ b/ld/testsuite/ld-shared/shared.dat
@@ -0,0 +1,16 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_mainvar () == 1
+shlib_overriddenvar () == 2
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+shlib_shlibcall2 () == 8
+shlib_maincall () == 6
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 1
+shlib_checkfunptr2 (main_called) == 1
+shlib_getfunptr1 () == shlib_shlibvar1
+shlib_getfunptr2 () == main_called
+shlib_check () == 1
diff --git a/ld/testsuite/ld-shared/shared.exp b/ld/testsuite/ld-shared/shared.exp
new file mode 100644
index 00000000000..8939c3d1928
--- /dev/null
+++ b/ld/testsuite/ld-shared/shared.exp
@@ -0,0 +1,264 @@
+# Expect script for ld-shared tests
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Ian Lance Taylor (ian@cygnus.com)
+#
+
+# Make sure that ld can generate ELF shared libraries.
+# Note that linking against ELF shared libraries is tested by the
+# bootstrap test.
+
+# This test can only be run if ld generates native executables.
+if ![isnative] then {return}
+
+# This test can only be run on a couple of ELF platforms.
+# Square bracket expressions seem to confuse istarget.
+if { ![istarget i386-*-sysv4*] \
+ && ![istarget i486-*-sysv4*] \
+ && ![istarget i586-*-sysv4*] \
+ && ![istarget i386-*-unixware] \
+ && ![istarget i486-*-unixware] \
+ && ![istarget i586-*-unixware] \
+ && ![istarget i386-*-elf*] \
+ && ![istarget i486-*-elf*] \
+ && ![istarget i586-*-elf*] \
+ && ![istarget i386-*-linux*] \
+ && ![istarget i486-*-linux*] \
+ && ![istarget i586-*-linux*] \
+ && ![istarget m68k-*-linux*] \
+ && ![istarget mips*-*-irix5*] \
+ && ![istarget powerpc-*-elf*] \
+ && ![istarget powerpc-*-linux*] \
+ && ![istarget powerpc-*-sysv4*] \
+ && ![istarget sparc*-*-elf] \
+ && ![istarget sparc*-*-solaris2*] \
+ && ![istarget sparc*-*-sunos4*] \
+ && ![istarget rs6000*-*-aix*] \
+ && ![istarget powerpc*-*-aix*] } {
+ return
+}
+
+if { [istarget i386-*-linuxaout*] \
+ || [istarget i486-*-linuxaout*] \
+ || [istarget i586-*-linuxaout*] \
+ || [istarget i386-*-linuxoldld*] \
+ || [istarget i486-*-linuxoldld*] \
+ || [istarget i586-*-linuxoldld*] \
+ || [istarget m68k-*-linuxaout*] } {
+ return
+}
+
+set tmpdir tmpdir
+set SHCFLAG ""
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+
+ # AIX shared libraries do not seem to support useful features,
+ # like overriding the shared library function or letting the
+ # shared library refer to objects defined in the main program. We
+ # avoid testing those features.
+ set SHCFLAG "-DXCOFF_TEST"
+
+ # The AIX 3.2.5 loader appears to randomly fail when loading
+ # shared libraries from NSF mounted partitions, so we avoid any
+ # potential problems by using a local directory.
+ catch {exec /bin/sh -c "echo $$"} pid
+ set tmpdir /usr/tmp/ld.$pid
+ catch "exec mkdir $tmpdir" exec_status
+
+ # On AIX, we need to explicitly export the symbols the shared
+ # library is going to provide, and need.
+ set file [open $tmpdir/xcoff.exp w]
+ puts $file shlibvar1
+ puts $file shlibvar2
+ puts $file shlib_shlibvar1
+ puts $file shlib_shlibvar2
+ puts $file shlib_shlibcall
+ puts $file shlib_shlibcalled
+ puts $file shlib_checkfunptr1
+ puts $file shlib_getfunptr1
+ puts $file shlib_check
+ close $file
+}
+
+# The test procedure.
+proc shared_test { progname testname main sh1 sh2 dat args } {
+ global ld
+ global srcdir
+ global subdir
+ global exec_output
+ global host_triplet
+ global tmpdir
+
+ if [llength $args] { set shldflags [lindex $args 0] } else { set shldflags "" }
+
+ # Build the shared library.
+ # On AIX, we need to use an export file.
+ set shared -shared
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ set shared "-bM:SRE -bE:$tmpdir/xcoff.exp"
+ }
+ if {![ld_simple_link $ld $tmpdir/$progname.so "$shared $shldflags $tmpdir/$sh1 $tmpdir/$sh2"]} {
+ fail "$testname"
+ return
+ }
+
+ # Link against the shared library. Use -rpath so that the
+ # dynamic linker can locate the shared library at runtime.
+ # On AIX, we must include /lib in -rpath, as otherwise the loader
+ # can not find -lc.
+ set rpath $tmpdir
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ set rpath /lib:$tmpdir
+ }
+ if ![ld_link $ld $tmpdir/$progname "-rpath $rpath $tmpdir/$main $tmpdir/$progname.so"] {
+ fail "$testname"
+ return
+ }
+
+ # Run the resulting program
+ send_log "$tmpdir/$progname >$tmpdir/$progname.out\n"
+ verbose "$tmpdir/$progname >$tmpdir/$progname.out"
+ catch "exec $tmpdir/$progname >$tmpdir/$progname.out" exec_output
+ if ![string match "" $exec_output] then {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ fail "$testname"
+ return
+ }
+
+ send_log "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat\n"
+ verbose "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat"
+ catch "exec diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ if {![string match "" $exec_output]} then {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ fail "$testname"
+ return
+ }
+
+ pass "$testname"
+}
+
+if [istarget mips*-*-*] {
+ set picflag ""
+} else {
+ # Unfortunately, the gcc argument is -fpic and the cc argument is
+ # -KPIC. We have to try both.
+ set picflag "-fpic"
+ send_log "$CC $picflag\n"
+ verbose "$CC $picflag"
+ catch "exec $CC $picflag" exec_output
+ send_log "$exec_output\n"
+ verbose "--" "$exec_output"
+ if { [string match "*illegal option*" $exec_output] \
+ || [string match "*option ignored*" $exec_output] \
+ || [string match "*unrecognized option*" $exec_output] \
+ || [string match "*passed to ld*" $exec_output] } {
+ if [istarget *-*-sunos4*] {
+ set picflag "-pic"
+ } else {
+ set picflag "-KPIC"
+ }
+ }
+}
+verbose "Using $picflag to compile PIC code"
+
+# Compile the main program.
+if ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] {
+ unresolved "shared (non PIC)"
+ unresolved "shared"
+} else {
+ # The shared library is composed of two files. First compile them
+ # without using -fpic. That should work on an ELF system,
+ # although it will be less efficient because the dynamic linker
+ # will need to do more relocation work. However, note that not
+ # using -fpic will cause some of the tests to return different
+ # results.
+ if { ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh1.c $tmpdir/sh1np.o]
+ || ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh2.c $tmpdir/sh2np.o] } {
+ unresolved "shared (non PIC)"
+ } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shnp "shared (nonPIC)" mainnp.o sh1np.o sh2np.o xcoff
+ } else {
+ # SunOS non PIC shared libraries don't permit some cases of
+ # overriding.
+ setup_xfail "*-*-sunos4*"
+ shared_test shnp "shared (non PIC)" mainnp.o sh1np.o sh2np.o shared
+
+ # Test ELF shared library relocations with a non-zero load
+ # address for the library. Near as I can tell, the R_*_RELATIVE
+ # relocations for various targets are broken in the case where
+ # the load address is not zero (which is the default).
+ setup_xfail "*-*-sunos4*"
+ shared_test shnp "shared (non PIC, load offset)" \
+ mainnp.o sh1np.o sh2np.o shared \
+ "-T $srcdir/$subdir/elf-offset.ld"
+ } }
+
+ # Now compile the code using -fpic.
+
+ if { ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh1.c $tmpdir/sh1p.o]
+ || ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh2.c $tmpdir/sh2p.o] } {
+ unresolved "shared"
+ } else {
+ # SunOS can not compare function pointers correctly
+ if [istarget "*-*-sunos4*"] {
+ shared_test shp "shared" mainnp.o sh1p.o sh2p.o sun4
+ } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shp "shared" mainnp.o sh1p.o sh2p.o xcoff
+ } else {
+ shared_test shp "shared" mainnp.o sh1p.o sh2p.o shared
+ } }
+ }
+}
+
+# Now do the same tests again, but this time compile main.c PIC.
+if ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] {
+ unresolved "shared (PIC main, non PIC so)"
+ unresolved "shared (PIC main)"
+} else {
+ if { [file exists $tmpdir/sh1np.o ] && [ file exists $tmpdir/sh2np.o ] } {
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o xcoff
+ } else {
+ # SunOS non PIC shared libraries don't permit some cases of
+ # overriding.
+ setup_xfail "*-*-sunos4*"
+ shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o shared
+ }
+ } else {
+ unresolved "shared (PIC main, non PIC so)"
+ }
+
+ if { [file exists $tmpdir/sh1p.o ] && [ file exists $tmpdir/sh2p.o ] } {
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o xcoff
+ } else {
+ shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o shared
+ }
+ } else {
+ unresolved "shared (PIC main)"
+ }
+}
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ # Remove the temporary directory.
+ catch "exec rm -rf $tmpdir" exec_status
+}
diff --git a/ld/testsuite/ld-shared/sun4.dat b/ld/testsuite/ld-shared/sun4.dat
new file mode 100644
index 00000000000..be0d87d0ea2
--- /dev/null
+++ b/ld/testsuite/ld-shared/sun4.dat
@@ -0,0 +1,16 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_mainvar () == 1
+shlib_overriddenvar () == 2
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+shlib_shlibcall2 () == 8
+shlib_maincall () == 6
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 0
+shlib_checkfunptr2 (main_called) == 1
+shlib_getfunptr1 () != shlib_shlibvar1
+shlib_getfunptr2 () == main_called
+shlib_check () == 1
diff --git a/ld/testsuite/ld-shared/xcoff.dat b/ld/testsuite/ld-shared/xcoff.dat
new file mode 100644
index 00000000000..a409d96a1ec
--- /dev/null
+++ b/ld/testsuite/ld-shared/xcoff.dat
@@ -0,0 +1,10 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 1
+shlib_getfunptr1 () == shlib_shlibvar1
+shlib_check () == 1
diff --git a/ld/testsuite/ld-srec/sr1.c b/ld/testsuite/ld-srec/sr1.c
new file mode 100644
index 00000000000..d7de977412d
--- /dev/null
+++ b/ld/testsuite/ld-srec/sr1.c
@@ -0,0 +1,25 @@
+/* This file is compiled and linked into the S-record format. */
+
+extern int e1;
+extern int e2;
+int i;
+int j = 1;
+static int k;
+static int l = 1;
+static char ab[] = "This is a string constant";
+
+extern int fn1 ();
+extern int fn2 ();
+
+int
+main ()
+{
+ fn1 (ab);
+ fn2 ("static string constant");
+ return e1 + e2 + i + j + k + l;
+}
+
+void
+__main ()
+{
+}
diff --git a/ld/testsuite/ld-srec/sr2.c b/ld/testsuite/ld-srec/sr2.c
new file mode 100644
index 00000000000..5736cfa468d
--- /dev/null
+++ b/ld/testsuite/ld-srec/sr2.c
@@ -0,0 +1,18 @@
+/* This file is compiled and linked into the S-record format. */
+
+int e1;
+int e2 = 1;
+
+int
+fn1 (s)
+ char *s;
+{
+ return s[e1];
+}
+
+int
+fn2 (s)
+ char *s;
+{
+ return s[e2];
+}
diff --git a/ld/testsuite/ld-srec/sr3.cc b/ld/testsuite/ld-srec/sr3.cc
new file mode 100644
index 00000000000..8717c26f34b
--- /dev/null
+++ b/ld/testsuite/ld-srec/sr3.cc
@@ -0,0 +1,113 @@
+// This file is compiled and linked into the S-record format.
+
+#define FOO_MSG_LEN 80
+
+class Foo {
+ static int foos;
+ int i;
+ static const int len = FOO_MSG_LEN;
+ char message[len];
+public:
+ static void init_foo ();
+ static int nb_foos() { return foos; }
+ Foo();
+ Foo( char* message);
+ Foo(const Foo&);
+ Foo & operator= (const Foo&);
+ ~Foo ();
+};
+
+static Foo static_foo( "static_foo");
+
+int
+main ()
+{
+ Foo automatic_foo( "automatic_foo");
+ return 0;
+}
+
+void
+terminate(void)
+{
+ /* This recursive call prevents a compiler warning that the noreturn
+ function terminate actually does return. */
+ terminate ();
+}
+
+extern "C" {
+void
+__main ()
+{
+}
+
+void
+__builtin_delete ()
+{
+}
+
+void
+__builtin_new ()
+{
+}
+
+void
+__throw ()
+{
+}
+
+void
+__terminate ()
+{
+}
+
+void *__eh_pc;
+
+void ***
+__get_dynamic_handler_chain ()
+{
+ return 0;
+}
+
+void *
+__get_eh_context ()
+{
+ return 0;
+}
+
+}
+
+int Foo::foos = 0;
+
+void Foo::init_foo ()
+{
+ foos = 80;
+}
+
+Foo::Foo ()
+{
+ i = ++foos;
+}
+
+Foo::Foo (char* msg)
+{
+ i = ++foos;
+}
+
+Foo::Foo (const Foo& foo)
+{
+ i = ++foos;
+ for (int k = 0; k < FOO_MSG_LEN; k++)
+ message[k] = foo.message[k];
+}
+
+Foo& Foo::operator= (const Foo& foo)
+{
+ for (int k = 0; k < FOO_MSG_LEN; k++)
+ message[k] = foo.message[k];
+ return *this;
+}
+
+Foo::~Foo ()
+{
+ foos--;
+}
diff --git a/ld/testsuite/ld-srec/srec.exp b/ld/testsuite/ld-srec/srec.exp
new file mode 100644
index 00000000000..63a70ab7bcf
--- /dev/null
+++ b/ld/testsuite/ld-srec/srec.exp
@@ -0,0 +1,374 @@
+# Test linking directly to S-records.
+# By Ian Lance Taylor, Cygnus Support.
+# Public domain.
+
+# Get the offset from an S-record line to the start of the data.
+
+proc srec_off { l } {
+ if [string match "S1*" $l] {
+ return 8
+ } else { if [string match "S2*" $l] {
+ return 10
+ } else { if [string match "S3*" $l] {
+ return 12
+ } else {
+ return -1
+ } } }
+}
+
+# See if an S-record line contains only zero data.
+
+proc srec_zero { l } {
+ if [string match "S\[0789\]*" $l] {
+ return 1
+ }
+
+ # Strip the address and checksum.
+ if [string match "S\[123\]*" $l] {
+ set l [string range $l [srec_off $l] [expr [string length $l] - 3]]
+ } else {
+ return 0
+ }
+
+ # The rest must be zero.
+ return [string match "" [string trim $l "0"]]
+}
+
+# Get the address of an S-record line.
+
+proc srec_addr { l } {
+ if [string match "S\[123\]*" $l] {
+ set addr [string range $l 4 [expr [srec_off $l] - 1]]
+ } else {
+ return -1
+ }
+
+ return "0x$addr"
+}
+
+# Get the number of data bytes in an S-record line.
+
+proc srec_len { l } {
+ if ![string match "S\[123\]*" $l] {
+ return 0
+ }
+
+ return [expr "0x[string range $l 2 3]" - ([srec_off $l] - 4) / 2 - 1]
+}
+
+# Extract bytes from an S-record line.
+
+proc srec_extract { l start len } {
+ set off [srec_off $l]
+ set rlen [srec_len $l]
+ set stop [expr $start + $len]
+ if { $stop > $rlen } {
+ set stop [expr $rlen]
+ }
+ set start [expr $start * 2 + $off]
+ set stop [expr $stop * 2 + $off - 1]
+ return [string range $l $start $stop]
+}
+
+# See if a range of bytes in an S-record line is all zeroes.
+
+proc srec_zero_range { l start len } {
+ return [string match "" [string trim [srec_extract $l $start $len] "0"]]
+}
+
+# Trim an S-record line such that the specified number of bytes remain
+# at the end.
+
+proc srec_trim { l leave } {
+ set off [srec_off $l]
+ set addr [srec_addr $l]
+ set len [srec_len $l]
+
+ if { $leave >= $len } {
+ return $l
+ }
+
+ set s1 [string range $l 0 1]
+ set s2 [format "%02x" [expr ($off - 4) / 2 + $leave + 1]]
+ set s3 [format "%0[expr $off - 4]x" [expr $addr + $len - $leave]]
+ set s4 [string range $l [expr [string length $l] - ($leave * 2) - 2] end]
+ set s "${s1}${s2}${s3}${s4}"
+
+ verbose "srec_trim { '$l' $leave } returning '$s'" 2
+
+ return $s
+}
+
+# Report failure when comparing S-record lines
+
+proc srec_compare_fail { which l1 l2 } {
+ send_log "comparison failure $which:\n$l1\n$l2\n"
+ verbose "comparison failure $which:\n$l1\n$l2"
+}
+
+# Compare S-record files. We don't want to fuss about things like
+# extra zeroes. Note that BFD always sorts S-records by address.
+
+proc srec_compare { f1 f2 } {
+ set e1 [gets $f1 l1]
+ set e2 [gets $f2 l2]
+
+ while { $e1 != -1 } {
+ set l1 [string trimright $l1 "\r\n"]
+ set l2 [string trimright $l2 "\r\n"]
+ if { $e2 == -1 } {
+ # If l1 contains data, it must be zero.
+ if ![srec_zero $l1] {
+ send_log "data after EOF: $l1\n"
+ verbose "data after EOF: $l1"
+ return 0
+ }
+ } else { if { [string compare $l1 $l2] == 0 } {
+ set e1 [gets $f1 l1]
+ set e2 [gets $f2 l2]
+ } else { if { [srec_zero $l1] } {
+ set e1 [gets $f1 l1]
+ } else { if { [srec_zero $l2] } {
+ set e2 [gets $f2 l2]
+ } else {
+ # The strings are not the same, and neither is all zeroes.
+ set a1 [srec_addr $l1]
+ set n1 [srec_len $l1]
+ set a2 [srec_addr $l2]
+ set n2 [srec_len $l2]
+
+ if { $a1 < $a2 && ![srec_zero_range $l1 0 [expr $a2 - $a1]] } {
+ verbose "$a1 $a2 [srec_extract $l1 0 [expr $a2 - $a1]]" 2
+ srec_compare_fail 1 $l1 $l2
+ return 0
+ }
+ if { $a2 < $a1 && ![srec_zero_range $l2 0 [expr $a1 - $a2]] } {
+ srec_compare_fail 2 $l1 $l2
+ return 0
+ }
+
+ # Here we know that any initial data in both lines is
+ # zero. Now make sure that any overlapping data matches.
+ if { $a1 < $a2 } {
+ set os1 [expr $a2 - $a1]
+ set os2 0
+ } else {
+ set os1 0
+ set os2 [expr $a1 - $a2]
+ }
+ if { $a1 + $n1 < $a2 + $n2 } {
+ set ol [expr $n1 - $os1]
+ } else {
+ set ol [expr $n2 - $os2]
+ }
+
+ set x1 [srec_extract $l1 $os1 $ol]
+ set x2 [srec_extract $l2 $os2 $ol]
+ if { [string compare $x1 $x2] != 0 } {
+ verbose "$os1 $ol $x1" 2
+ verbose "$os2 $ol $x2" 2
+ srec_compare_fail 3 $l1 $l2
+ return 0
+ }
+
+ # These strings match. Trim the data from the larger
+ # string, read a new copy of the smaller string, and
+ # continue.
+ if { $a1 + $n1 < $a2 + $n2 } {
+ set l2 [srec_trim $l2 [expr ($a2 + $n2) - ($a1 + $n1)]]
+ set e1 [gets $f1 l1]
+ } else { if { $a1 + $n1 > $a2 + $n2 } {
+ set l1 [srec_trim $l1 [expr ($a1 + $n1) - ($a2 + $n2)]]
+ set e2 [gets $f2 l2]
+ } else {
+ set e1 [gets $f1 l1]
+ set e2 [gets $f2 l2]
+ } }
+ } } } }
+ }
+
+ # We've reached the end of the first file. The remainder of the
+ # second file must contain only zeroes.
+ while { $e2 != -1 } {
+ set l2 [string trimright $l2 "\r\n"]
+ if ![srec_zero $l2] {
+ send_log "data after EOF: $l2\n"
+ verbose "data after EOF: $l2"
+ return 0
+ }
+ set e2 [gets $f2 l2]
+ }
+
+ return 1
+}
+
+# Link twice, objcopy, and compare
+
+proc run_srec_test { test objs } {
+ global ld
+ global objcopy
+ global sizeof_headers
+ global host_triplet
+
+ set flags ""
+
+ # If the linker script uses SIZEOF_HEADERS, use a -Ttext argument
+ # to force both the normal link and the S-record link to be put in
+ # the same place. We don't always use -Ttext because it interacts
+ # poorly with a.out.
+
+ if { $sizeof_headers } {
+ set flags "$flags -Ttext 0x1000"
+ }
+
+ # The a29k compiled code calls V_SPILL and V_FILL. Since we don't
+ # need to run this code, but we don't have definitions for those
+ # functions, we just define them out.
+ if [istarget a29k*-*-*] {
+ set flags "$flags --defsym V_SPILL=0 --defsym V_FILL=0"
+ }
+
+ # ARM targets call __gccmain
+ if [istarget arm-*-*] {
+ set flags "$flags --defsym ___gccmain=0"
+ }
+
+ if [istarget strongarm-*-*] {
+ set flags "$flags --defsym __gccmain=0"
+ }
+
+ # Thumb targets call __gccmain
+ if [istarget thumb-*-*] {
+ set flags "$flags --defsym ___gccmain=0"
+ }
+
+ # PowerPC EABI code calls __eabi.
+ if [istarget powerpc*-*-eabi*] {
+ set flags "$flags --defsym __eabi=0"
+ }
+
+ # mn10200 code calls __truncsipsi2_d0_d2.
+ if {[istarget mn10200*-*-*]} then {
+ set flags "$flags --defsym __truncsipsi2_d0_d2=0"
+ }
+
+ # V850 targets need libgcc.a
+ if [istarget v850*-*-elf] {
+ set objs "$objs -L ../gcc -lgcc"
+ }
+
+ if { ![ld_simple_link $ld tmpdir/sr1 "$flags $objs"] \
+ || ![ld_simple_link $ld tmpdir/sr2.sr "$flags -oformat srec $objs"] } {
+ setup_xfail "hppa*-*-*elf*"
+ fail $test
+ return
+ }
+
+ send_log "$objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr\n"
+ verbose "$objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr"
+ catch "exec $objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ unresolved $test
+ return
+ }
+
+ set f1 [open tmpdir/sr1.sr r]
+ set f2 [open tmpdir/sr2.sr r]
+ if [srec_compare $f1 $f2] {
+ pass $test
+ } else {
+ fail $test
+ }
+ close $f1
+ close $f2
+}
+
+set test1 "S-records"
+set test2 "S-records with constructors"
+
+# See whether the default linker script uses SIZEOF_HEADERS.
+catch "exec $ld --verbose" exec_output
+set sizeof_headers [string match "*SIZEOF_HEADERS*" $exec_output]
+
+# First test linking a C program. We don't require any libraries. We
+# link it normally, and objcopy to the S-record format, and then link
+# directly to the S-record format, and require that the two files
+# contain the same data.
+
+if { [which $CC] == 0 } {
+ untested $test1
+ untested $test2
+ return
+}
+
+if { ![ld_compile $CC $srcdir/$subdir/sr1.c tmpdir/sr1.o] \
+ || ![ld_compile $CC $srcdir/$subdir/sr2.c tmpdir/sr2.o] } {
+ unresolved $test1
+ unresolved $test2
+ return
+}
+
+# The i386-aout target is confused: the linker does not put the
+# sections where objdump finds them. I don't know which is wrong.
+setup_xfail "i*86-*-aout*"
+
+# These tests fail on the native MIPS ELF targets because the GP value
+# in the .reginfo section is not updated when the S-record version is
+# written out. The mips-elf target itself does not use a .reginfo section.
+setup_xfail "mips*-*-irix5*" "mips*-*-irix6*"
+
+# The S-record linker doesn't do the magic TOC handling that XCOFF
+# linkers do.
+setup_xfail "*-*-aix*" "*-*-xcoff*"
+
+# The S-record linker doesn't build ARM/Thumb stubs.
+setup_xfail "arm-*-coff"
+setup_xfail "strongarm-*-*"
+setup_xfail "arm-*-pe*"
+# setup_xfail "arm-*elf*"
+setup_xfail "thumb-*-coff*"
+setup_xfail "thumb-*-pe*"
+setup_xfail "thumb-*-elf*"
+
+# The S-record linker doesn't build special EABI sections.
+setup_xfail "powerpc*-*-eabi*"
+
+# The S-record linker doesn't include the .{zda} sections.
+setup_xfail "v850*-*-elf"
+
+# The S-record linker doesn't handle Alpha Elf relaxation.
+setup_xfail "alpha*-*-elf*" "alpha*-*-linux-gnu*" "alpha*-*-gnu*"
+setup_xfail "alpha*-*-netbsd*"
+
+run_srec_test $test1 "tmpdir/sr1.o tmpdir/sr2.o"
+
+# Now try linking a C++ program with global constructors and
+# destructors. Note that since we are not linking against any
+# libraries, this program won't actually work or anything.
+
+if { [which $CXX] == 0 } {
+ untested $test2
+ return
+}
+
+if ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir/$subdir/sr3.cc tmpdir/sr3.o] {
+ unresolved $test2
+ return
+}
+
+# See above.
+setup_xfail "i*86-*-aout*"
+setup_xfail "mips*-*-irix5*" "mips*-*-irix6*"
+setup_xfail "*-*-aix*" "*-*-xcoff*"
+setup_xfail "arm-*-*"
+setup_xfail "strongarm-*-*"
+setup_xfail "thumb-*-*"
+setup_xfail "powerpc*-*-eabi*"
+setup_xfail "v850*-*-elf"
+setup_xfail "alpha*-*-elf*" "alpha*-*-linux-gnu*" "alpha*-*-gnu*"
+setup_xfail "alpha*-*-netbsd*"
+
+run_srec_test $test2 "tmpdir/sr3.o"
diff --git a/ld/testsuite/ld-undefined/undefined.c b/ld/testsuite/ld-undefined/undefined.c
new file mode 100644
index 00000000000..ef2aec6d6e5
--- /dev/null
+++ b/ld/testsuite/ld-undefined/undefined.c
@@ -0,0 +1,10 @@
+/* This file is used to test the linker's reporting of undefined
+ symbols. */
+
+extern int this_function_is_not_defined ();
+
+int
+function ()
+{
+ return this_function_is_not_defined ();
+}
diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp
new file mode 100644
index 00000000000..29b3bddc41d
--- /dev/null
+++ b/ld/testsuite/ld-undefined/undefined.exp
@@ -0,0 +1,126 @@
+# Test that the linker reports undefined symbol errors correctly.
+# By Ian Lance Taylor, Cygnus Support
+#
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+set testund "undefined"
+set testfn "undefined function"
+set testline "undefined line"
+
+if { [which $CC] == 0 } {
+ verbose "Could not find C compiler!" 1
+ untested $testund
+ untested $testfn
+ untested $testline
+ return
+}
+
+if ![ld_compile "$CC -g" $srcdir/$subdir/undefined.c tmpdir/undefined.o] {
+ verbose "Unable to compile test file!" 1
+ unresolved $testund
+ unresolved $testfn
+ unresolved $testline
+ return
+}
+
+catch "exec rm -f tmpdir/undefined" exec_output
+
+# Using -e start prevents the SunOS linker from trying to build a
+# shared library.
+send_log "$ld -e start -o tmpdir/undefined tmpdir/undefined.o\n"
+verbose "$ld -e start -o tmpdir/undefined tmpdir/undefined.o"
+
+catch "exec $ld -e start -o tmpdir/undefined tmpdir/undefined.o" exec_output
+send_log "$exec_output\n"
+verbose "$exec_output"
+
+proc checkund { string testname } {
+ global exec_output
+
+ if [string match "*$string*" $exec_output] {
+ pass $testname
+ } else {
+ fail $testname
+ }
+}
+
+set mu "undefined reference to `this_function_is_not_defined'"
+checkund $mu $testund
+
+# ARM PE defaults to using stabs debugging, which we can't handle for
+# a COFF file.
+#setup_xfail "arm*-*-pe*"
+#setup_xfail "thumb*-*-pe*"
+
+# Just doesn't work for PA ELF. No clue why.
+setup_xfail "hppa*-*-*elf*"
+
+set mf "tmpdir/undefined.o: In function `function':"
+checkund $mf $testfn
+
+# COFF SH gets this test wrong--it reports line 10, because although
+# the jump is at line 9, the function address, and the reloc, is
+# stored at the end of the function.
+setup_xfail "sh-*-*"
+
+# ARM PE defaults to using stabs debugging, which we can't handle for
+# a COFF file.
+#setup_xfail "arm*-*-pe*"
+#setup_xfail "thumb*-*-pe*"
+
+# Just doesn't work for PA ELF. No clue why.
+setup_xfail "hppa*-*-*elf*"
+
+set ml "undefined.c:9: undefined reference to `this_function_is_not_defined'"
+# With targets that use elf/dwarf2, such as the arm-elf and thumb-elf
+# toolchains, the code in bfd/elf.c:_bfd_elf_find_nearest_line() is called
+# in order to locate the file name/line number where the undefined
+# reference occurs. Unfortunately this tries to use the dwarf2 debug
+# information held in the .debug_info section. This section contains a series
+# of comp_unit structures, each of which has a low/high address range
+# representing the span of memory locations covered by that structure. The
+# structures also index into other structures held in the .debug_line section
+# and together they can translate memory locations back into file/function/line
+# number addresses in the source code. Since the information about the memory
+# region covered by a comp_unit is only determined at link time, the low/high
+# addresses in the .debug_info section and the line addresses in the .debug_line
+# section are computed by generating relocs against known symbols in the object
+# code.
+#
+# When the undefined reference is detected, the relocs in the dwarf2
+# debug sections have not yet been resolved, so the low/high addresses and the
+# line number address are all set at zero. Thus when _bfd_elf_find_nearest_line()
+# calls _bfd_dwarf2_find_nearest_line() no comp_unit can be found which
+# actually covers the address where the reference occured, and so
+# _bfd_elf_find_nearest_line() fails.
+#
+# The upshot of all of this, is that the error message reported by the
+# linker, instead of having a source file name & line number as in:
+#
+# undefined.c:9: undefined reference to `this_function_is_not_defined'
+#
+# has an object file & section address instead:
+#
+# undefined.0(.text+0xc): undefined reference to `this_function_is_not_defined'
+#
+# hence the xfails below.
+
+setup_xfail arm-*-elf
+setup_xfail strongarm-*-elf
+setup_xfail thumb-*-elf
+
+checkund $ml $testline
diff --git a/ld/testsuite/ld-versados/t1-1.ro b/ld/testsuite/ld-versados/t1-1.ro
new file mode 100644
index 00000000000..1d70d8091de
--- /dev/null
+++ b/ld/testsuite/ld-versados/t1-1.ro
Binary files differ
diff --git a/ld/testsuite/ld-versados/t1-2.ro b/ld/testsuite/ld-versados/t1-2.ro
new file mode 100644
index 00000000000..8d4dc591084
--- /dev/null
+++ b/ld/testsuite/ld-versados/t1-2.ro
Binary files differ
diff --git a/ld/testsuite/ld-versados/t1.ld b/ld/testsuite/ld-versados/t1.ld
new file mode 100644
index 00000000000..1a5c4e3aac0
--- /dev/null
+++ b/ld/testsuite/ld-versados/t1.ld
@@ -0,0 +1,281 @@
+OUTPUT_FORMAT("srec")
+SECTIONS
+{
+
+
+.text 0 : { *("9") *("10") *("11") *("12") *("13") *("14") *("15")
+ *("7") *("8") *("0") *("1") *("2") *("3") *("4") }
+.bss (NOLOAD) : { *("5") *("6") }
+
+.PAFI =0x00000050 ;
+.PCHIO =0x000000D0 ;
+.PCLO =0x00000054 ;
+.PCVBSV =0x0000000E ;
+.PCVTSU =0x00000012 ;
+.PCVTSV =0x00000016 ;
+.PCVTSVL =0x0000001A ;
+.PCVTUS =0x0000001E ;
+.PDIS =0x00000022 ;
+.PDISL =0x00000026 ;
+.PDVJ =0x0000002A ;
+.PEIO =0x000000CC ;
+.PEOF =0x00000058 ;
+.PEOL =0x0000005C ;
+.PEQUS =0x0000002E ;
+.PEQUV =0x00000032 ;
+.PEQUVL =0x00000036 ;
+.PEQUW =0x000000DE ;
+.PGCM =0x00000064 ;
+.PGEQS =0x0000003A ;
+.PGEQV =0x0000003E ;
+.PGEQVL =0x00000042 ;
+.PGET =0x00000060 ;
+.PGRTS =0x00000046 ;
+.PGRTV =0x0000004A ;
+.PGRTVL =0x0000004E ;
+.PIACT =0x0000006C ;
+.PIFD =0x00000068 ;
+.PINDS =0x00000052 ;
+.PINDV =0x00000056 ;
+.PINDVL =0x0000005A ;
+.PINDW =0x000000D6 ;
+.PLDCS =0x0000005E ;
+.PLDCV =0x00000062 ;
+.PLEQS =0x00000066 ;
+.PLEQV =0x0000006A ;
+.PLEQVL =0x0000006E ;
+.PLESS =0x00000072 ;
+.PLESV =0x00000076 ;
+.PLESVL =0x0000007A ;
+.PLODS =0x0000007E ;
+.PLODV =0x00000082 ;
+.PLODVL =0x00000086 ;
+.PMODJ =0x0000008A ;
+.PMOV =0x000000E2 ;
+.PMPJ =0x0000008E ;
+.PNEQS =0x00000092 ;
+.PNEQV =0x00000096 ;
+.PNEQVL =0x0000009A ;
+.PNEQW =0x000000DA ;
+.PPAGE =0x000000D4 ;
+.PPEE =0x00000070 ;
+.PPUT =0x00000074 ;
+.PRDB =0x00000078 ;
+.PRDC =0x0000007C ;
+.PRDH =0x00000080 ;
+.PRDI =0x00000084 ;
+.PRDJ =0x00000088 ;
+.PRDRS =0x000000C8 ;
+.PRDS =0x0000008C ;
+.PRDV =0x00000090 ;
+.PRLN =0x00000094 ;
+.PRRAN =0x00000098 ;
+.PRST =0x0000009C ;
+.PRWT =0x000000A0 ;
+.PSCON =0x0000009E ;
+.PSCOP =0x000000A2 ;
+.PSDEL =0x000000A6 ;
+.PSINS =0x000000AA ;
+.PSLEN =0x000000AE ;
+.PSPOS =0x000000B2 ;
+.PSTCV =0x000000B6 ;
+.PSTCVL =0x000000BA ;
+.PSTOS =0x000000BE ;
+.PSTOV =0x000000C2 ;
+.PSTOVL =0x000000C6 ;
+.PSTRS =0x000000CA ;
+.PSTRV =0x000000CE ;
+.PSTRVL =0x000000D2 ;
+.PWLN =0x000000A4 ;
+.PWRAN =0x000000A8 ;
+.PWRB =0x000000AC ;
+.PWRC =0x000000B0 ;
+.PWRH =0x000000B4 ;
+.PWRI =0x000000B8 ;
+.PWRJ =0x000000BC ;
+.PWRS =0x000000C0 ;
+.PWRV =0x000000C4 ;
+
+/*
+.PAFI=0x = 0x00;
+.PCHIO =0x 0x000000;
+.PCLO =0x 64 ;
+.PC;
+.PCVTSU =0x 0x000000;
+.PCVTSV =0x 0x000000;
+.PCVTSVL =0x 0x000000;
+.PCVTUS =0x 158 ;
+.P;
+.PDISL =0x 0x000000;
+.PDVJ =0x 0x000000;
+.PEIO =0x 0x000000;
+.PEOF =0x 0x000000;
+.PEOL =0x 0x000000;
+.PEQUS =0x 0x000000;
+.PEQUV =0x 0x000000;
+.PEQUVL =0x 0x000000;
+.PEQUW =0x 0x000000;
+.PGCM =0x 0x000000;
+.PGEQS =0x 0x000000;
+.PGEQV =0x 0x000000;
+.PGEQVL =0x 0x000000;
+.PGET =0x 0x000000;
+.PGRTS =0x 0x000000;
+.PGRTV =0x 0x000000;
+.PGRTVL =0x 0x000000;
+.PIACT =0x 0x000000;
+.PIFD =0x 126 ;
+.P;
+.PINDV =0x 0x000000;
+.PINDVL =0x 0x000000;
+.PINDW =0x 0x000000;
+.PLDCS =0x 0x000000;
+.PLDCV =0x 0x000000;
+.PLEQS =0x 0x000000;
+.PLEQV =0x 0x000000;
+.PLEQVL =0x 0x000000;
+.PLESS =0x 0x000000;
+.PLESV =0x 0x000000;
+.PLESVL =0x 0x000000;
+.PLODS =0x 0x000000;
+.PLODV =0x 0x000000;
+.PLODVL =0x 0x000000;
+.PMODJ =0x 0x000000;
+.PMOV =0x 0x000000;
+.PMPJ =0x 0x000000;
+.PNEQS =0x 0x000000;
+.PNEQV =0x 0x000000;
+.PNEQVL =0x 0x000000;
+.PNEQW =0x 0x000000;
+.PPAGE =0x 0x000000;
+.PPEE =0x 0x000000;
+.PPUT =0x 0x000000;
+.PRDB =0x 0x000000;
+.PRDC =0x 0x000000;
+.PRDH =0x 0x000000;
+.PRDI =0x 0x000000;
+.PRDJ =0x 0x000000;
+.PRDRS =0x 0x000000;
+.PRDS =0x 0x000000;
+.PRDV =0x 0x000000;
+.PRLN =0x 0x000000;
+.PRRAN =0x 0x000000;
+.PRST =0x 0x000000;
+.PRWT =0x 0x000000;
+.PSCON =0x 0x000000;
+.PSCOP =0x 0x000000;
+.PSDEL =0x 0x000000;
+.PSINS =0x 0x000000;
+.PSLEN =0x 0x000000;
+.PSPOS =0x 0x000000;
+.PSTCV =0x 0x000000;
+.PSTCVL =0x 0x000000;
+.PSTOS =0x 0x000000;
+.PSTOV =0x 0x000000;
+.PSTOVL =0x 0x000000;
+.PSTRS =0x 0x000000;
+.PSTRV =0x 0x000000;
+.PSTRVL =0x 0x000000;
+.PWLN =0x 0x000000;
+.PWRAN =0x 0x000000;
+.PWRB =0x 0x000000;
+.PWRC =0x 0x000000;
+.PWRH =0x 0x000000;
+.PWRI =0x 0x000000;
+.PWRJ =0x 0x000000;
+.PWRS =0x 0x000000;
+.PWRV =0x 0x000000;
+
+*/
+/*
+.P=0x = 0;
+.PCHIO =0x 0xfeedfa;
+.PCLO =0x 0xfeedfa;
+.PCVBSV =0x 0xfeedfa;
+.PCVTSU =0x 0xfeedfa;
+.PCVTSV =0x 0xfeedfa;
+.PCVTSVL =0x 0xfeedfa;
+.PCVTUS =0x 0xfeedfa;
+.PDIS =0x 0xfeedfa;
+.PDISL =0x 0xfeedfa;
+.PDVJ =0x 0xfeedfa;
+.PEIO =0x 0xfeedfa;
+.PEOF =0x 0xfeedfa;
+.PEOL =0x 0xfeedfa;
+.PEQUS =0x 0xfeedfa;
+.PEQUV =0x 0xfeedfa;
+.PEQUVL =0x 0xfeedfa;
+.PEQUW =0x 0xfeedfa;
+.PGCM =0x 0xfeedfa;
+.PGEQS =0x 0xfeedfa;
+.PGEQV =0x 0xfeedfa;
+.PGEQVL =0x 0xfeedfa;
+.PGET =0x 0xfeedfa;
+.PGRTS =0x 0xfeedfa;
+.PGRTV =0x 0xfeedfa;
+.PGRTVL =0x 0xfeedfa;
+.PIACT =0x 0xfeedfa;
+.PIFD =0x 0xfeedfa;
+.PINDS =0x 0xfeedfa;
+.PINDV =0x 0xfeedfa;
+.PINDVL =0x 0xfeedfa;
+.PINDW =0x 0xfeedfa;
+.PLDCS =0x 0xfeedfa;
+.PLDCV =0x 0xfeedfa;
+.PLEQS =0x 0xfeedfa;
+.PLEQV =0x 0xfeedfa;
+.PLEQVL =0x 0xfeedfa;
+.PLESS =0x 0xfeedfa;
+.PLESV =0x 0xfeedfa;
+.PLESVL =0x 0xfeedfa;
+.PLODS =0x 0xfeedfa;
+.PLODV =0x 0xfeedfa;
+.PLODVL =0x 0xfeedfa;
+.PMODJ =0x 0xfeedfa;
+.PMOV =0x 0xfeedfa;
+.PMPJ =0x 0xfeedfa;
+.PNEQS =0x 0xfeedfa;
+.PNEQV =0x 0xfeedfa;
+.PNEQVL = 0xfeedface;
+.PNEQW = 0xfeedface;
+.PPAGE = 0xfeedface;
+.PPEE = 0xfeedface;
+.PPUT = 0xfeedface;
+.PRDB = 0xfeedface;
+.PRDC = 0xfeedface;
+.PRDH = 0xfeedface;
+.PRDI = 0xfeedface;
+.PRDJ = 0xfeedface;
+.PRDRS = 0xfeedface;
+.PRDS = 0xfeedface;
+.PRDV = 0xfeedface;
+.PRLN = 0xfeedface;
+.PRRAN = 0xfeedface;
+.PRST = 0xfeedface;
+.PRWT = 0xfeedface;
+.PSCON = 0xfeedface;
+.PSCOP = 0xfeedface;
+.PSDEL = 0xfeedface;
+.PSINS = 0xfeedface;
+.PSLEN = 0xfeedface;
+.PSPOS = 0xfeedface;
+.PSTCV = 0xfeedface;
+.PSTCVL = 0xfeedface;
+.PSTOS = 0xfeedface;
+.PSTOV = 0xfeedface;
+.PSTOVL = 0xfeedface;
+.PSTRS = 0xfeedface;
+.PSTRV = 0xfeedface;
+.PSTRVL = 0xfeedface;
+.PWLN = 0xfeedface;
+.PWRAN = 0xfeedface;
+.PWRB = 0xfeedface;
+.PWRC = 0xfeedface;
+.PWRH = 0xfeedface;
+.PWRI = 0xfeedface;
+.PWRJ = 0xfeedface;
+.PWRS = 0xfeedface;
+.PWRV = 0xfeedface;
+*/
+
+}
diff --git a/ld/testsuite/ld-versados/t1.ook b/ld/testsuite/ld-versados/t1.ook
new file mode 100644
index 00000000000..3984b94ee5e
--- /dev/null
+++ b/ld/testsuite/ld-versados/t1.ook
@@ -0,0 +1,133 @@
+S00C000074312E6F75742E6F6BC0
+S118000000000A205341464553544F52452041202020202052BE
+S118001531332E33202020202020205231332E32202020202077
+S118002A202000B5E86600B5E9B11DA15B9900001F0000000A50
+S118003F640000003E0000005C00A800BA00F000040001000251
+S1180054000000000000000000000006004031CF52544C4942D0
+S1180069434F4E0004E5EC52544C4942434F4E0004E5ED5254F0
+S118007E4C4942434F4E004031D252544C4942434F4E00000A08
+S11800937D52544C49425354520010A4A852544C494246494CAD
+S11800A8000200B5E86D0000016000B5E873000002540002006A
+S11800BDB5E937534146455052494E5420000006000200080079
+S11800D20000034200B5E86E494E4954534146455354000002C9
+S11800E71800000E00000009020030000000004E56FFD8BA8FDB
+S11800FC63062E4E6100001641FA003243EEFFD8702612D85149
+S1180111C8FFFC4E5E4E752B57FFF22F3C0000000A6000000259
+S11801263B6F0002FFF62F2D00382F2D00344E4C4E4A434F50E7
+S118013B5952494748542054656C65666F6E204142204C204D6B
+S1180150204572696373736F6E2C2031393933004E56FFFCBAB5
+S11801658F63042E4E61AC202E000C06800000000C4E7656807C
+S118017A4E760280FFFFFFFC4AD56604610000B02D40FFFC200B
+S118018F6C003A2208242C003694814E7604820000000C4E76D2
+S11801A44AD566046100008EB0826E0C0CAE00000001000C6CEB
+S11801B900000C207C0000000061000060206C003A200866046C
+S11801CE610000762208D2AEFFFC68046100005C2081216E0043
+S11801E3100004216E000C0008220806810000000C68046100C2
+S11801F800402D4100142950003A206C003A24086604610000BC
+S118020D3A429042A8000442A800084E5E225F285F508F4EE922
+S118022200022B5FFFF24E5ED1DF285F2F082B48FFF2D0D04EDA
+S1180237D02B57FFF22F3C0000000E6000FEE22B57FFF22F3CD4
+S118024C000000106000FED44E56FFFCBA8F63062E4E6100FE2B
+S1180261B82D6C0032FFFC600000122B5FFFF24FEEFFFC42AEF1
+S1180276FFFC600000824AAEFFFC6700007A206EFFFC200866A7
+S118028B00000461B622280004B2AE001067000062220802810B
+S11802A0000000034A8166402208226C003A2409B2826E3426B6
+S11802B510280806840000000C68046100FF76B6846D2026101B
+S11802CA280896844E7604830000000C4E764AD566046100FFCD
+S11802DF5AB6A800086C0000046182206EFFFC20086604610077
+S11802F4FF522D50FFFC60804AAEFFFC6700002C206EFFFC2019
+S11803090866046100FF38226E000C22A80008220806810000B2
+S118031E000C68046100FF142D4100146000000C206E000C4210
+S11803339042AE00144E5E205F285F508F4ED04FEDFF00707F44
+S1180348204F425851C8FFFC486DFF081F3C00043F3C00019F49
+S118035DFC0000000C224F45FA04FE22DA22DA22DA266C00281F
+S11803722F0C286C002C4EAB0068486DFFB8486DFFB42F0C20E7
+S11803876C0000286C00044E909FFC000000522F2DFFC62F0C32
+S118039C206C0008286C000C4E907052266C00204EAB001E416A
+S11803B1FA04BE266C00204EAB007E266C00204EAB009E41EDD7
+S11803C6FFBA266C00204EAB007E266C00204EAB009E1F3C0098
+S11803DB283F3C0001266C00204EAB009E9FFC00000052302DD2
+S11803F0FFCA48C02F002F0C206C0008286C000C4E90705226BF
+S11804056C00204EAB001E266C00204EAB009E41FA045E266CC3
+S118041A00204EAB007E266C00204EAB009E41EDFF9E70162672
+S118042F6C00204EAB00CA600000162B5FFFF24FEDFF002B7C92
+S118044400000001FFB4600003E4486DFF089FFC0000005220DB
+S11804594F43EDFF9E3019725092406F024241D04130C06F0A23
+S118046E5340E24030D951C8FFFC9FFC00000052224F45FA0303
+S1180483F632DA266C00282F0C286C002C4EAB0050FFAA486D02
+S1180498FF08266C00282F0C286C002C4EAB00A0FF9642ADFF73
+S11804AD002B6C0032FF04487A03C43F3CFFFF486DFF08266C1A
+S11804C200282F0C286C002C4EAB00C0FF70486DFF08266C0088
+S11804D7282F0C286C002C4EAB00A4FF5C600000782B5FFFF29E
+S11804EC4FEDFF00487A03BA3F3CFFFF486DFF08266C00282F1F
+S11805010C286C002C4EAB00C0FF349FFC00000052206DFF04AC
+S118051620082F002F0C206C0010286C00144E902F0F3F3CFF60
+S118052BFF486DFF08266C00282F0C286C002C4EAB00C0FF008F
+S1180540DFFC00000052486DFF08266C00282F0C286C002C4EB6
+S1180555AB00A4FEE6600001F0206DFF042008660261804A902E
+S118056A6700016A22100281000000034A81664A2210242C00F1
+S118057F3604820000000C68046100FCAEB2826E3422102408F0
+S118059406820000000C68046100FC9AB2826D202210240892A6
+S11805A9824E7604810000000C4E764AD566046100FC7EB2A8E0
+S11805BE00086C0000066100FF22206DFF04200866046100FFA6
+S11805D31622280008D2ADFF0068046100FC582B41FF009FFC02
+S11805E80000005224082F022F0C206C0010286C00144E902FBF
+S11805FD0F3F3C000C486DFF08266C00282F0C286C002C4EABE5
+S118061200C0FE2ADFFC00000052206DFF04200866046100FE39
+S1180627C22F2800043F3C000C486DFF08266C00282F0C286CD1
+S118063C002C4EAB00BCFDFC206DFF04200866046100FE9A2F81
+S11806512800083F3C000C486DFF08266C00282F0C286C002C68
+S11806664EAB00BCFDD49FFC00000052206DFF04200866046185
+S118067B00FE6C22102F012F0C206C0010286C00144E902F0FFF
+S11806903F3C000C486DFF08266C00282F0C286C002C4EAB0060
+S11806A5C0FD98DFFC00000052486DFF08266C00282F0C286C75
+S11806BA002C4EAB00A4FD7E206DFF04200866046100FE1C2B1B
+S11806CF50FF046000FE8A206C003AB1EDFF046700006C487ADB
+S11806E401E83F3CFFFF486DFF08266C00282F0C286C002C4EDC
+S11806F9AB00C0FD429FFC00000052206DFF0420082F002F0C2F
+S118070E206C0010286C00144E902F0F3F3CFFFF486DFF082617
+S11807236C00282F0C286C002C4EAB00C0FD0EDFFC000000523D
+S1180738486DFF08266C00282F0C286C002C4EAB00A4FCF44862
+S118074D7A01983F3CFFFF486DFF08266C00282F0C286C002C96
+S11807624EAB00C0FCD8486DFF08266C00282F0C286C002C4E32
+S1180777AB00A4FCC4487A016A3F3CFFFF486DFF08266C00283E
+S118078C2F0C286C002C4EAB00C0FCA8486DFF08266C00282F57
+S11807A10C286C002C4EAB00A4FC94206DFF0420080680000008
+S11807B600184E76222C003692804E760281FFFFFFFC4AD566F3
+S11807CB046100FA6A2F013F3C000C486DFF08266C00282F0CE4
+S11807E0286C002C4EAB00BCFC562F2DFF003F3C000C486DFFA3
+S11807F508266C00282F0C286C002C4EAB00BCFC3A486DFF0887
+S118080A266C00282F0C286C002C4EAB00A4FC26486DFF081F86
+S118081F3C0001266C00282F0C286C002C4EAB0054486DFFB815
+S1180834486DFFB42F0C206C0018286C001C4E90486DFF0842D8
+S118084927266C00282F0C286C002C4EAB005442A72F2D0038F0
+S118085E2F2D00344E4A000A4631202020202020202000023A9C
+S11808733A0002293A0000003020202020204164647265737337
+S1180888202020204964656E746974792020202020202020533A
+S118089D697A6520202020202020204E657874001D496E7661B0
+S11808B26C6964207365676D656E74207374617274696E672035
+S11808C761743A202000185365676D656E74206C69737420637F
+S11808DC6F727275707465643A2000000018202020417661693B
+S11808F16C61626C652020202020202020557365644FEDFFF230
+S11809069FFC0000000A6100015641EC003020DF20DF30DF20F1
+S118091B2C003256804E760280FFFFFFFC4AD566046100F90A63
+S1180930294000322940003A6000003E2B5FFFF24FEDFFF2200A
+S11809452C003256804E760280FFFFFFFC4AD566046100F8E064
+S118095A2940003A206C003A220866046100F8DE429042A80094
+S118096F0442A800086000009E4A2C00306700001A206C003A8E
+S11809842008660261B2429042A8000442A800086000007E2007
+S11809996C003A20086602619A4A906700006E221002810000B0
+S11809AE00034A81664A2210242C003604820000000C6804619B
+S11809C300F874B2826E342210240806820000000C680461001A
+S11809D8F860B2826D202210240892824E7604810000000C4ED8
+S11809ED764AD566046100F844B2A800086C0000066100FF3CE5
+S1180A02206C003A200866046100FF302950003A608442A72F44
+S1180A172D00382F2D00344E4A4E560000518F42A71F3C000E63
+S1180A2C4267487A0012426742272F3C00B5E86E4E49000E50B7
+S1180A418F4E5E205F285F4EE80002207C0000000060042B5F99
+S1180A56FFF24E5ED1DF285F2F08D0D04ED043FA0004D3FC00AE
+S1180A6B02704E2F49000A43FA0004D3FC000000402F49000662
+S1180A8041FA0004D1FCFFFFF57A202800566600002222099201
+S1180A95882141005642812448D25AB5C96DFA4441D368005AAE
+S1110AAA1F7C000100044E75422F00044E759F
+S9030000FC
diff --git a/ld/testsuite/ld-versados/t2-1.ro b/ld/testsuite/ld-versados/t2-1.ro
new file mode 100644
index 00000000000..633a7cc8856
--- /dev/null
+++ b/ld/testsuite/ld-versados/t2-1.ro
Binary files differ
diff --git a/ld/testsuite/ld-versados/t2-2.ro b/ld/testsuite/ld-versados/t2-2.ro
new file mode 100644
index 00000000000..704a79d947f
--- /dev/null
+++ b/ld/testsuite/ld-versados/t2-2.ro
Binary files differ
diff --git a/ld/testsuite/ld-versados/t2-3.ro b/ld/testsuite/ld-versados/t2-3.ro
new file mode 100644
index 00000000000..d95934218d2
--- /dev/null
+++ b/ld/testsuite/ld-versados/t2-3.ro
Binary files differ
diff --git a/ld/testsuite/ld-versados/t2.ld b/ld/testsuite/ld-versados/t2.ld
new file mode 100644
index 00000000000..5e1e413d160
--- /dev/null
+++ b/ld/testsuite/ld-versados/t2.ld
@@ -0,0 +1,281 @@
+OUTPUT_FORMAT("srec")
+SECTIONS
+{
+
+
+.text 0 : { *("9") *("10") *("11") *("12") *("13") *("14") *("15")
+ *("7") *("8") *("0") *("1") *("2") *("3") *("4") }
+.bss : { *("5") *("6") }
+
+.PAFI =0x00000050 ;
+.PCHIO =0x000000D0 ;
+.PCLO =0x00000054 ;
+.PCVBSV =0x0000000E ;
+.PCVTSU =0x00000012 ;
+.PCVTSV =0x00000016 ;
+.PCVTSVL =0x0000001A ;
+.PCVTUS =0x0000001E ;
+.PDIS =0x00000022 ;
+.PDISL =0x00000026 ;
+.PDVJ =0x0000002A ;
+.PEIO =0x000000CC ;
+.PEOF =0x00000058 ;
+.PEOL =0x0000005C ;
+.PEQUS =0x0000002E ;
+.PEQUV =0x00000032 ;
+.PEQUVL =0x00000036 ;
+.PEQUW =0x000000DE ;
+.PGCM =0x00000064 ;
+.PGEQS =0x0000003A ;
+.PGEQV =0x0000003E ;
+.PGEQVL =0x00000042 ;
+.PGET =0x00000060 ;
+.PGRTS =0x00000046 ;
+.PGRTV =0x0000004A ;
+.PGRTVL =0x0000004E ;
+.PIACT =0x0000006C ;
+.PIFD =0x00000068 ;
+.PINDS =0x00000052 ;
+.PINDV =0x00000056 ;
+.PINDVL =0x0000005A ;
+.PINDW =0x000000D6 ;
+.PLDCS =0x0000005E ;
+.PLDCV =0x00000062 ;
+.PLEQS =0x00000066 ;
+.PLEQV =0x0000006A ;
+.PLEQVL =0x0000006E ;
+.PLESS =0x00000072 ;
+.PLESV =0x00000076 ;
+.PLESVL =0x0000007A ;
+.PLODS =0x0000007E ;
+.PLODV =0x00000082 ;
+.PLODVL =0x00000086 ;
+.PMODJ =0x0000008A ;
+.PMOV =0x000000E2 ;
+.PMPJ =0x0000008E ;
+.PNEQS =0x00000092 ;
+.PNEQV =0x00000096 ;
+.PNEQVL =0x0000009A ;
+.PNEQW =0x000000DA ;
+.PPAGE =0x000000D4 ;
+.PPEE =0x00000070 ;
+.PPUT =0x00000074 ;
+.PRDB =0x00000078 ;
+.PRDC =0x0000007C ;
+.PRDH =0x00000080 ;
+.PRDI =0x00000084 ;
+.PRDJ =0x00000088 ;
+.PRDRS =0x000000C8 ;
+.PRDS =0x0000008C ;
+.PRDV =0x00000090 ;
+.PRLN =0x00000094 ;
+.PRRAN =0x00000098 ;
+.PRST =0x0000009C ;
+.PRWT =0x000000A0 ;
+.PSCON =0x0000009E ;
+.PSCOP =0x000000A2 ;
+.PSDEL =0x000000A6 ;
+.PSINS =0x000000AA ;
+.PSLEN =0x000000AE ;
+.PSPOS =0x000000B2 ;
+.PSTCV =0x000000B6 ;
+.PSTCVL =0x000000BA ;
+.PSTOS =0x000000BE ;
+.PSTOV =0x000000C2 ;
+.PSTOVL =0x000000C6 ;
+.PSTRS =0x000000CA ;
+.PSTRV =0x000000CE ;
+.PSTRVL =0x000000D2 ;
+.PWLN =0x000000A4 ;
+.PWRAN =0x000000A8 ;
+.PWRB =0x000000AC ;
+.PWRC =0x000000B0 ;
+.PWRH =0x000000B4 ;
+.PWRI =0x000000B8 ;
+.PWRJ =0x000000BC ;
+.PWRS =0x000000C0 ;
+.PWRV =0x000000C4 ;
+
+/*
+.PAFI=0x = 0x00;
+.PCHIO =0x 0x000000;
+.PCLO =0x 64 ;
+.PC;
+.PCVTSU =0x 0x000000;
+.PCVTSV =0x 0x000000;
+.PCVTSVL =0x 0x000000;
+.PCVTUS =0x 158 ;
+.P;
+.PDISL =0x 0x000000;
+.PDVJ =0x 0x000000;
+.PEIO =0x 0x000000;
+.PEOF =0x 0x000000;
+.PEOL =0x 0x000000;
+.PEQUS =0x 0x000000;
+.PEQUV =0x 0x000000;
+.PEQUVL =0x 0x000000;
+.PEQUW =0x 0x000000;
+.PGCM =0x 0x000000;
+.PGEQS =0x 0x000000;
+.PGEQV =0x 0x000000;
+.PGEQVL =0x 0x000000;
+.PGET =0x 0x000000;
+.PGRTS =0x 0x000000;
+.PGRTV =0x 0x000000;
+.PGRTVL =0x 0x000000;
+.PIACT =0x 0x000000;
+.PIFD =0x 126 ;
+.P;
+.PINDV =0x 0x000000;
+.PINDVL =0x 0x000000;
+.PINDW =0x 0x000000;
+.PLDCS =0x 0x000000;
+.PLDCV =0x 0x000000;
+.PLEQS =0x 0x000000;
+.PLEQV =0x 0x000000;
+.PLEQVL =0x 0x000000;
+.PLESS =0x 0x000000;
+.PLESV =0x 0x000000;
+.PLESVL =0x 0x000000;
+.PLODS =0x 0x000000;
+.PLODV =0x 0x000000;
+.PLODVL =0x 0x000000;
+.PMODJ =0x 0x000000;
+.PMOV =0x 0x000000;
+.PMPJ =0x 0x000000;
+.PNEQS =0x 0x000000;
+.PNEQV =0x 0x000000;
+.PNEQVL =0x 0x000000;
+.PNEQW =0x 0x000000;
+.PPAGE =0x 0x000000;
+.PPEE =0x 0x000000;
+.PPUT =0x 0x000000;
+.PRDB =0x 0x000000;
+.PRDC =0x 0x000000;
+.PRDH =0x 0x000000;
+.PRDI =0x 0x000000;
+.PRDJ =0x 0x000000;
+.PRDRS =0x 0x000000;
+.PRDS =0x 0x000000;
+.PRDV =0x 0x000000;
+.PRLN =0x 0x000000;
+.PRRAN =0x 0x000000;
+.PRST =0x 0x000000;
+.PRWT =0x 0x000000;
+.PSCON =0x 0x000000;
+.PSCOP =0x 0x000000;
+.PSDEL =0x 0x000000;
+.PSINS =0x 0x000000;
+.PSLEN =0x 0x000000;
+.PSPOS =0x 0x000000;
+.PSTCV =0x 0x000000;
+.PSTCVL =0x 0x000000;
+.PSTOS =0x 0x000000;
+.PSTOV =0x 0x000000;
+.PSTOVL =0x 0x000000;
+.PSTRS =0x 0x000000;
+.PSTRV =0x 0x000000;
+.PSTRVL =0x 0x000000;
+.PWLN =0x 0x000000;
+.PWRAN =0x 0x000000;
+.PWRB =0x 0x000000;
+.PWRC =0x 0x000000;
+.PWRH =0x 0x000000;
+.PWRI =0x 0x000000;
+.PWRJ =0x 0x000000;
+.PWRS =0x 0x000000;
+.PWRV =0x 0x000000;
+
+*/
+/*
+.P=0x = 0;
+.PCHIO =0x 0xfeedfa;
+.PCLO =0x 0xfeedfa;
+.PCVBSV =0x 0xfeedfa;
+.PCVTSU =0x 0xfeedfa;
+.PCVTSV =0x 0xfeedfa;
+.PCVTSVL =0x 0xfeedfa;
+.PCVTUS =0x 0xfeedfa;
+.PDIS =0x 0xfeedfa;
+.PDISL =0x 0xfeedfa;
+.PDVJ =0x 0xfeedfa;
+.PEIO =0x 0xfeedfa;
+.PEOF =0x 0xfeedfa;
+.PEOL =0x 0xfeedfa;
+.PEQUS =0x 0xfeedfa;
+.PEQUV =0x 0xfeedfa;
+.PEQUVL =0x 0xfeedfa;
+.PEQUW =0x 0xfeedfa;
+.PGCM =0x 0xfeedfa;
+.PGEQS =0x 0xfeedfa;
+.PGEQV =0x 0xfeedfa;
+.PGEQVL =0x 0xfeedfa;
+.PGET =0x 0xfeedfa;
+.PGRTS =0x 0xfeedfa;
+.PGRTV =0x 0xfeedfa;
+.PGRTVL =0x 0xfeedfa;
+.PIACT =0x 0xfeedfa;
+.PIFD =0x 0xfeedfa;
+.PINDS =0x 0xfeedfa;
+.PINDV =0x 0xfeedfa;
+.PINDVL =0x 0xfeedfa;
+.PINDW =0x 0xfeedfa;
+.PLDCS =0x 0xfeedfa;
+.PLDCV =0x 0xfeedfa;
+.PLEQS =0x 0xfeedfa;
+.PLEQV =0x 0xfeedfa;
+.PLEQVL =0x 0xfeedfa;
+.PLESS =0x 0xfeedfa;
+.PLESV =0x 0xfeedfa;
+.PLESVL =0x 0xfeedfa;
+.PLODS =0x 0xfeedfa;
+.PLODV =0x 0xfeedfa;
+.PLODVL =0x 0xfeedfa;
+.PMODJ =0x 0xfeedfa;
+.PMOV =0x 0xfeedfa;
+.PMPJ =0x 0xfeedfa;
+.PNEQS =0x 0xfeedfa;
+.PNEQV =0x 0xfeedfa;
+.PNEQVL = 0xfeedface;
+.PNEQW = 0xfeedface;
+.PPAGE = 0xfeedface;
+.PPEE = 0xfeedface;
+.PPUT = 0xfeedface;
+.PRDB = 0xfeedface;
+.PRDC = 0xfeedface;
+.PRDH = 0xfeedface;
+.PRDI = 0xfeedface;
+.PRDJ = 0xfeedface;
+.PRDRS = 0xfeedface;
+.PRDS = 0xfeedface;
+.PRDV = 0xfeedface;
+.PRLN = 0xfeedface;
+.PRRAN = 0xfeedface;
+.PRST = 0xfeedface;
+.PRWT = 0xfeedface;
+.PSCON = 0xfeedface;
+.PSCOP = 0xfeedface;
+.PSDEL = 0xfeedface;
+.PSINS = 0xfeedface;
+.PSLEN = 0xfeedface;
+.PSPOS = 0xfeedface;
+.PSTCV = 0xfeedface;
+.PSTCVL = 0xfeedface;
+.PSTOS = 0xfeedface;
+.PSTOV = 0xfeedface;
+.PSTOVL = 0xfeedface;
+.PSTRS = 0xfeedface;
+.PSTRV = 0xfeedface;
+.PSTRVL = 0xfeedface;
+.PWLN = 0xfeedface;
+.PWRAN = 0xfeedface;
+.PWRB = 0xfeedface;
+.PWRC = 0xfeedface;
+.PWRH = 0xfeedface;
+.PWRI = 0xfeedface;
+.PWRJ = 0xfeedface;
+.PWRS = 0xfeedface;
+.PWRV = 0xfeedface;
+*/
+
+}
diff --git a/ld/testsuite/ld-versados/t2.ook b/ld/testsuite/ld-versados/t2.ook
new file mode 100644
index 00000000000..03f24a5f8f8
--- /dev/null
+++ b/ld/testsuite/ld-versados/t2.ook
@@ -0,0 +1,99 @@
+S0120000696E6974746573745F6570632E7372CF
+S118000000000000494E495454455354202050413035202052AB
+S118001531332E33202020202020205231332E32202020202077
+S118002A202000934B5B00B5E6C11B089DD600005400000005F9
+S118003F5A00000048005C00A60000010A0126000400010002CB
+S1180054009000000000000000000002004020200000494F5F8A
+S11800695245534552564152544C4942434F4E0040484501003B
+S118007E505F414C4C202020202052544C4942434F4E010000E3
+S118009300009C01000000000000085345504152415445000852
+S11800A80008004031CF52544C4942434F4E0004E5EC52544CD3
+S11800BD4942434F4E00B5E86D5341464553544F5200004F28D7
+S11800D253595354454D494D00B5E8735341464553544F520023
+S11800E74031D252544C4942434F4E00000A7D52544C49425309
+S11800FC54520010A4A852544C494246494C000100B5E6C049EC
+S11801114E495454455354202000000616020008000000023210
+S11801260048000000004E56FFF0BA8F63062E4E610000BC4159
+S118013BFA00F443EEFFF032D82D7C00000001FFFC206E000858
+S118015020086604610000BA222EFFFC53814A816C046100002E
+S11801659E2248D3E9FFFC41F01800B3C863EE4A1066000006E7
+S118017A6000006241EEFFF0266C00384EAB007E206E00082095
+S118018F0866046100007C222EFFFC53814A816C0461000060ED
+S11801A42248D3E9FFFC41F01800B3C863EE1F103F3C0001263B
+S11801B96C00384EAB009E41EEFFF0700C266C00384EAB00CACB
+S11801CE52AEFFFC0CAE0000000AFFFC6F00FF7041EEFFF0431F
+S11801E3EE000C22D822D822D84E5E205F588F4ED02B57FFF278
+S11801F82F3C0000000A6000001E2B57FFF22F3C0000000F60AE
+S118020D0000102B57FFF22F3C00000010600000023B6F0002CC
+S1180222FFF62F2D00382F2D00344E4C4E4A00004FEDFEEA2034
+S11802373C0000008A204F425851C8FFFC486DFEEA1F3C0004CF
+S118024C3F3C00019FFC0000000C224F45FA02D422DA22DA22D6
+S1180261DA266C00402F0C286C00444EAB0068486DFFB8486D43
+S1180276FFB42F0C206C0008286C000C4E909FFC000000522F53
+S118028B2DFFC62F0C206C0010286C00144E907052266C00387F
+S11802A04EAB001E41FA0294266C00384EAB007E266C00384E04
+S11802B5AB009E41EDFFBA266C00384EAB007E266C00384EABFC
+S11802CA009E1F3C00283F3C0001266C00384EAB009E9FFC0082
+S11802DF000052302DFFCA48C02F002F0C206C0010286C0014D8
+S11802F44E907052266C00384EAB001E266C00384EAB009E41CE
+S1180309FA0234266C00384EAB007E266C00384EAB009E41EDDB
+S118031EFF807016266C00384EAB00CA9FFC0000000E61000228
+S11803332841EDFF9E20DF20DF20DF30DF4A2DFF9E6700003AFD
+S1180348598F2F2DFFA02F2DFFA82F0C206C0018286C001C4ED9
+S118035D9001B82B5FFF9A2F2DFF9A2F2DFFA42F2DFFA82F0CE9
+S1180372206C0020286C00244E9060000034598F2F2DFFA04871
+S11803876DFFA82F0C206C0028286C002C4E902B5FFF962F2D41
+S118039CFFA42F2DFF962F2DFFA82F0C206C0020286C00244EC4
+S11803B190486DFEEA9FFC00000052204F43EDFF8030197250F0
+S11803C692406F024241D04130C06F0A5340E24030D951C8FF08
+S11803DBFC9FFC00000052224F45FA015C32DA266C00402F0CFA
+S11803F0286C00444EAB0050012C486DFEEA266C00402F0C28D4
+S11804056C00444EAB00A00118487A01343F3CFFFF486DFEEA6F
+S118041A266C00402F0C286C00444EAB00C000FC486DFEEA266C
+S118042F6C00402F0C286C00444EAB00A400E842ADFFB02B7C2B
+S118044400000001FFAC598F2F2DFFAC6100017E2B5FFFB02BC0
+S118045940FFB02F2DFFAC3F3C000A486DFEEA266C00402F0C65
+S118046E286C00444EAB00BC00AE9FFC0000000C2F2DFFB06127
+S118048300FCA82F0F3F3C000A486DFEEA266C00402F0C286CBB
+S118049800444EAB00C00086DFFC0000000C486DFEEA266C00B2
+S11804AD402F0C286C00444EAB00A4006C52ADFFAC0CAD000077
+S11804C2000AFFAC6F82486DFEEA1F3C0001266C00402F0C284D
+S11804D76C00444EAB0054486DFFB8486DFFB42F0C206C003044
+S11804EC286C00344E90486DFEEA4227266C00402F0C286C00AA
+S1180501444EAB005442A72F2D00382F2D00344E4A2B57FFF238
+S11805162F3C0000000C6000FD002B57FFF22F3C000000646056
+S118052B00FCF2000A4631202020202020202000023A3A0002D0
+S1180540293A000000142020202020204361736520202020521D
+S11805556573756C7441FA0004D1FCFFFFFAA02028003C43FAFB
+S118056A0004D3FC000001D645FA0004D5FC0000025E260A58D2
+S118057F8AD0885580222800566600002E2408265AD5B0B8008F
+S1180594B5C06DF6220992882141005642812648D25BB7C96D2E
+S11805A9FA4441D368005A123C00016000000442411F4100048B
+S11805BE2F68003400062F49000A96892F43000E4E754E56FFCC
+S11805D3F0202E000847FA0004D7FC000001A6220B41FA00049E
+S11805E8D1FC000001B62D58FFF02D58FFF42D58FFF82D50FF92
+S11805FDFC53807408B4806500012C41FA0004D1FC0000000EBA
+S1180612D080303008004EFB00020012002200320042004800DC
+S118062758006C00A000DC41FA0004D1FC0000011820106000C5
+S118063C010247FA0004D7FC0000010C200B600000F241FA00C5
+S118065104D1FC000001102010600000E22001600000DC47FA9E
+S11806660004D7FC00000120200B600000CC43FA0004D3FC001C
+S118067B0000FA41E9000C2010600000B8242EFFF447FA000464
+S1180690D7FC000000FEB48B6600001247FA0004D7FC000001B0
+S11806A514200B6000009447FA0004D7FC0000010A200B60005B
+S11806BA008441FA0004D1FC0000008A205047FA0004D7FC0085
+S11806CF000082B1CB6600001247FA0004D7FC000000E0200B79
+S11806E46000005847FA0004D7FC000000D2200B600000484147
+S11806F9FA0004D1FC0000004E43FA0004D3FC0000003EB3D0FE
+S118070E6600001247FA0004D7FC000000AE200B6000001E47A4
+S1180723FA0004D7FC000000A6200B6000000E47FA0004D7FC95
+S118073800000098200B4E5E4E740004000053756E65000000D8
+S118074D0007464F74746F00000000000A0000000C50656C6CFD
+S118076265000000075E5374696E61004B6172696E00000000C0
+S11807770500000768000000030000076E5075747465004B61BF
+S118078C6C6C65005374696E613100004B6172696E31000000C1
+S11807A1000033000007900000001F0000079878797A7A0000D2
+S11807B64F6C6C650000370038005065746572005376756C6C19
+S11807CB6F00003900536C75740000000000000000074C000072
+S11507E007640000077800000780000007A4000007AC34
+S9030000FC
diff --git a/ld/testsuite/ld-versados/versados.exp b/ld/testsuite/ld-versados/versados.exp
new file mode 100644
index 00000000000..2d2c0663bed
--- /dev/null
+++ b/ld/testsuite/ld-versados/versados.exp
@@ -0,0 +1,99 @@
+# Expect script for ld-versados tests
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Steve Chamberlain (sac@cygnus.com)
+#
+
+# Make sure that ld can read versados images and
+# generate binaries which are identical to the customer's
+# old method.
+
+# This test can only be run if ld generates native executables.
+
+# This test can only be run on 68k coff targets
+# Square bracket expressions seem to confuse istarget.
+if { ![istarget m68k-*-coff*] } then {
+ return
+}
+
+set testname "LD VERSADOS"
+
+
+proc inspect { whichone } {
+ global objdump
+ global exec_output
+ global srcdir
+ global subdir
+ global testname
+
+ send_log "$objdump -s tmpdir/$whichone.out >tmpdir/$whichone.dump\n"
+ catch "exec $objdump -s tmpdir/$whichone.out | grep -v srec >tmpdir/$whichone.dump" exec_output
+
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose $exec_output
+ unresolved $testname
+ return 0
+ }
+
+ send_log "$objdump -s $srcdir/$subdir/$whichone.ook >tmpdir/$whichone.dok\n"
+ catch "exec $objdump -s $srcdir/$subdir/$whichone.ook | grep -v srec >tmpdir/$whichone.dok" exec_output
+
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose $exec_output
+ unresolved $testname
+ return 0
+ }
+
+ # compare it with the correct output
+ catch "exec diff tmpdir/$whichone.dump tmpdir/$whichone.dok" exec_output
+ if ![string match "" $exec_output] {
+ send_log "$exec_output\n"
+ verbose $exec_output
+ fail $testname
+ return 0
+ }
+
+ return 1
+}
+
+if ![ld_simple_link $ld tmpdir/t1.out \
+ " -T $srcdir/$subdir/t1.ld $srcdir/$subdir/t1-1.ro $srcdir/$subdir/t1-2.ro"] {
+ fail $testname
+ return
+} else {
+ # Get a dump of what we've got, and what we should have
+ if ![inspect t1] {
+ return
+ }
+}
+
+
+if ![ld_simple_link $ld tmpdir/t2.out \
+ " -T $srcdir/$subdir/t2.ld $srcdir/$subdir/t2-2.ro \
+ $srcdir/$subdir/t2-1.ro $srcdir/$subdir/t2-3.ro"] {
+ fail $testname
+ return
+} else {
+ # Get a dump of what we've got, and what we should have
+ if ![inspect t2] {
+ return
+ }
+}
+
+pass $testname
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
new file mode 100644
index 00000000000..24a41310901
--- /dev/null
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -0,0 +1,327 @@
+#
+# default_ld_version
+# extract and print the version number of ld
+#
+proc default_ld_version { ld } {
+ global host_triplet
+
+ if { [which $ld] == 0 } then {
+ perror "$ld does not exist"
+ exit 1
+ }
+
+ catch "exec $ld --version" tmp
+ set tmp [prune_warnings $tmp]
+ regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
+ if [info exists number] then {
+ clone_output "$ld $number\n"
+ }
+}
+
+#
+# default_ld_relocate
+# link an object using relocation
+#
+proc default_ld_relocate { ld target objects } {
+ global HOSTING_EMU
+ global host_triplet
+
+ if { [which $ld] == 0 } then {
+ perror "$ld does not exist"
+ return 0
+ }
+
+ verbose -log "$ld $HOSTING_EMU -o $target -r $objects"
+
+ catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ return 0
+ }
+}
+
+
+#
+# default_ld_link
+# link a program using ld
+#
+proc default_ld_link { ld target objects } {
+ global HOSTING_EMU
+ global HOSTING_CRT0
+ global HOSTING_LIBS
+ global host_triplet
+
+ set objs "$HOSTING_CRT0 $objects"
+ set libs "$HOSTING_LIBS"
+
+ if { [which $ld] == 0 } then {
+ perror "$ld does not exist"
+ return 0
+ }
+
+ verbose -log "$ld $HOSTING_EMU -o $target $objs $libs"
+
+ catch "exec $ld $HOSTING_EMU -o $target $objs $libs" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ return 0
+ }
+}
+
+#
+# default_ld_simple_link
+# link a program using ld, without including any libraries
+#
+proc default_ld_simple_link { ld target objects } {
+ global host_triplet
+
+ if { [which $ld] == 0 } then {
+ perror "$ld does not exist"
+ return 0
+ }
+
+ verbose -log "$ld -o $target $objects"
+
+ catch "exec $ld -o $target $objects" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ # We don't care if we get a warning about a non-existent start
+ # symbol, since the default linker script might use ENTRY.
+ regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
+
+ if [string match "" $exec_output] then {
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ return 0
+ }
+}
+
+#
+# default_ld_compile
+# compile an object using cc
+#
+proc default_ld_compile { cc source object } {
+ global CFLAGS
+ global srcdir
+ global subdir
+ global host_triplet
+ global gcc_gas_flag
+
+ set cc_prog $cc
+ if {[llength $cc_prog] > 1} then {
+ set cc_prog [lindex $cc_prog 0]
+ }
+ if {[which $cc_prog] == 0} then {
+ perror "$cc_prog does not exist"
+ return 0
+ }
+
+ catch "exec rm -f $object" exec_output
+
+ set flags "-I$srcdir/$subdir $CFLAGS"
+
+ # If we are compiling with gcc, we want to add gcc_gas_flag to
+ # flags. Rather than determine this in some complex way, we guess
+ # based on the name of the compiler.
+ if {[string match "*gcc*" $cc] || [string match "*++*" $cc]} then {
+ set flags "$gcc_gas_flag $flags"
+ }
+
+ verbose -log "$cc $flags -c $source -o $object"
+
+ catch "exec $cc $flags -c $source -o $object" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ if {![file exists $object]} then {
+ regexp ".*/(\[^/\]*)$" $source all dobj
+ regsub "\\.c" $dobj ".o" realobj
+ verbose "looking for $realobj"
+ if {[file exists $realobj]} then {
+ verbose -log "mv $realobj $object"
+ catch "exec mv $realobj $object" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if {![string match "" $exec_output]} then {
+ verbose -log "$exec_output"
+ perror "could not move $realobj to $object"
+ return 0
+ }
+ } else {
+ perror "$object not found after compilation"
+ return 0
+ }
+ }
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ perror "$source: compilation failed"
+ return 0
+ }
+}
+
+#
+# default_ld_assemble
+# assemble a file
+#
+proc default_ld_assemble { as source object } {
+ global ASFLAGS
+ global host_triplet
+
+ if {[which $as] == 0} then {
+ perror "$as does not exist"
+ return 0
+ }
+
+ if ![info exists ASFLAGS] { set ASFLAGS "" }
+
+ verbose -log "$as $ASFLAGS -o $object $source"
+
+ catch "exec $as $ASFLAGS -o $object $source" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ perror "$source: assembly failed"
+ return 0
+ }
+}
+
+#
+# default_ld_nm
+# run nm on a file, putting the result in the array nm_output
+#
+proc default_ld_nm { nm object } {
+ global NMFLAGS
+ global nm_output
+ global host_triplet
+
+ if {[which $nm] == 0} then {
+ perror "$nm does not exist"
+ return 0
+ }
+
+ if ![info exists NMFLAGS] { set NMFLAGS "" }
+
+ verbose -log "$nm $NMFLAGS $object >tmpdir/nm.out"
+
+ catch "exec $nm $NMFLAGS $object >tmpdir/nm.out" exec_output
+ set exec_output [prune_warnings $exec_output]
+ if [string match "" $exec_output] then {
+ set file [open tmpdir/nm.out r]
+ while { [gets $file line] != -1 } {
+ verbose "$line" 2
+ if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] (.+)$" $line whole value name] {
+ set name [string trimleft $name "_"]
+ verbose "Setting nm_output($name) to 0x$value" 2
+ set nm_output($name) 0x$value
+ }
+ }
+ close $file
+ return 1
+ } else {
+ verbose -log "$exec_output"
+ perror "$object: nm failed"
+ return 0
+ }
+}
+
+#
+# simple_diff
+# compares two files line-by-line
+# returns differences if exist
+# returns null if file(s) cannot be opened
+#
+proc simple_diff { file_1 file_2 } {
+ global target
+
+ set eof -1
+ set differences 0
+
+ if [file exists $file_1] then {
+ set file_a [open $file_1 r]
+ } else {
+ warning "$file_1 doesn't exist"
+ return
+ }
+
+ if [file exists $file_2] then {
+ set file_b [open $file_2 r]
+ } else {
+ fail "$file_2 doesn't exist"
+ return
+ }
+
+ verbose "# Diff'ing: $file_1 $file_2\n" 2
+
+ while { [gets $file_a line] != $eof } {
+ if [regexp "^#.*$" $line] then {
+ continue
+ } else {
+ lappend list_a $line
+ }
+ }
+ close $file_a
+
+ while { [gets $file_b line] != $eof } {
+ if [regexp "^#.*$" $line] then {
+ continue
+ } else {
+ lappend list_b $line
+ }
+ }
+ close $file_b
+
+ for { set i 0 } { $i < [llength $list_a] } { incr i } {
+ set line_a [lindex $list_a $i]
+ set line_b [lindex $list_b $i]
+
+ verbose "\t$file_1: $i: $line_a\n" 3
+ verbose "\t$file_2: $i: $line_b\n" 3
+ if [string compare $line_a $line_b] then {
+ verbose -log "\t$file_1: $i: $line_a\n"
+ verbose -log "\t$file_2: $i: $line_b\n"
+
+ fail "Test: $target"
+ return
+ }
+ }
+
+ if { [llength $list_a] != [llength $list_b] } {
+ fail "Test: $target"
+ return
+ }
+
+ if $differences<1 then {
+ pass "Test: $target"
+ }
+}
+
+# This definition is taken from an unreleased version of DejaGnu. Once
+# that version gets released, and has been out in the world for a few
+# months at least, it may be safe to delete this copy.
+if ![string length [info proc prune_warnings]] {
+ #
+ # prune_warnings -- delete various system verbosities from TEXT
+ #
+ # An example is:
+ # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
+ #
+ # Sites with particular verbose os's may wish to override this in site.exp.
+ #
+ proc prune_warnings { text } {
+ # This is from sun4's. Do it for all machines for now.
+ # The "\\1" is to try to preserve a "\n" but only if necessary.
+ regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
+
+ # It might be tempting to get carried away and delete blank lines, etc.
+ # Just delete *exactly* what we're ask to, and that's it.
+ return $text
+ }
+}
diff --git a/libiberty/COPYING.LIB b/libiberty/COPYING.LIB
new file mode 100644
index 00000000000..161a3d1d47b
--- /dev/null
+++ b/libiberty/COPYING.LIB
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
new file mode 100644
index 00000000000..7032febe630
--- /dev/null
+++ b/libiberty/ChangeLog
@@ -0,0 +1,3232 @@
+1999-04-20 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ Fix from Dale Hawkins:
+ * cplus-dem.c (mop_up): Set typevec_size to zero, so it'll be
+ reallocated properly if we use it again.
+
+ * cplus-dem.c (demangle_fund_type): Check for buffer overrun. Be
+ stricter about syntax. Always null-terminate string.
+
+ Fix from Marcus Daniels:
+ * cplus-dem.c (demangle_fund_type): Don't run off the end of the
+ identifier looking for another underscore.
+
+1999-04-11 Richard Henderson <rth@cygnus.com>
+
+ * alloca-conf.h (alloca) [C_ALLOCA]: Don't use Gcc builtin
+ or <alloca.h>.
+ * clock.c (GNU_HZ): New definition.
+ (clock): Use it.
+ * getruntime.c: Likewise.
+
+ * config.table: Use mh-beos.
+ * config/mh-beos: New file.
+
+1999-04-01 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * cplus-dem.c: Attempt to handle overflows in counts with some
+ semblance of grace.
+ (consume_count): Detect overflows. Return -1 to indicate errors,
+ instead of zero.
+ (demangle_template_value_parm, demangle_template): Handle change
+ to consume_count's return convention.
+
+Thu Apr 8 14:43:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * xmalloc.c, pexecute.c: Define __CYGWIN__ when being compiled
+ with old __CYGWIN32__ compiler.
+
+1999-04-02 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.h (splay_tree_compare_pointers): Define.
+
+1999-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.c (splay_tree_compare_ints): Define.
+
+1999-03-30 Tom Tromey <tromey@cygnus.com>
+
+ * cplus-dem.c (consume_count): If `count' wraps, return 0 and
+ don't advance input pointer.
+ (demangle_class_name): If consume_count didn't find a count, do
+ nothing. Don't bother with `strlen' sanity check; consume_count
+ does it for us.
+
+1999-03-16 Stan Shebs <shebs@andros.cygnus.com>
+
+ From Art Haas <ahaas@neosoft.com>:
+ * cplus-dem.c (demangle_prefix): Don't grab all the '__' strings
+ when doing arm or hp style.
+ (demangle_nested_args): Decr forgetting_types field when done.
+
+Thu Mar 11 01:22:58 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * pexecute.c (__CYGWIN32__): Rename to
+ (__CYGWIN__): this.
+ * xmalloc.c: Likewise.
+
+ Changes to support i386-pc-uwin.
+ * configure.in (*-*-uwin*): Workaround for vfork bug.
+ * configure: Regenerate.
+ * pexecute.c (pexecute): Be like standard Unix.
+ (pwait): Likewise.
+ * xmalloc.c (first_break): Define.
+ (xmalloc_set_program_name): Use.
+ (xmalloc): Use.
+
+Thu Mar 11 01:07:55 1999 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * config.table: Cleanup and add mh-*pic handling for alpha, arm, powerpc
+
+Sun Feb 28 22:30:44 1999 Geoffrey Noer <noer@cygnus.com>
+
+ * config.table: Check cygwin*, not cygwin32*.
+
+Tue Feb 9 16:39:01 1999 Dave Brolley <brolley@cygnus.com>
+
+ * Makefile.in: Change mkstemp -> mkstemps.
+
+Tue Feb 9 01:12:27 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Makefile.in (REQUIRED_OFILES): remove mkstemp.o
+ * configure.in (funcs): Check for and conditionally add mkstemps to
+ the list of functions libiberty will provide.
+ * configure: Rebuilt.
+
+Wed Feb 3 00:01:15 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * clock.c (HZ): Define in terms of (ISO C) CLOCKS_PER_SEC on
+ platforms that don't have HZ.
+ * getruntime.c (HZ): Likewise.
+
+Sat Jan 30 13:28:04 1999 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (xstrdup.o): Depend on config.h.
+
+Wed Jan 13 07:26:44 1999 H.J. Lu (hjl@gnu.org)
+
+ * cplus-dem.c (mop_up): Set work->previous_argument to NULL after
+ freeing it.
+
+Wed Jan 13 14:16:36 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xstrdup.c (xstrdup): Switch from strcpy to memcpy for speed.
+
+Tue Jan 5 15:58:29 1999 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * Makefile.in (CFILES): fix typo, splay-tree.c instead of
+ splay-tree.o.
+
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Require autoconf 2.12.1 or higher.
+
+1998-12-30 Michael Meissner <meissner@cygnus.com>
+
+ * random.c (NULL): Don't redefine NULL if it is already defined.
+
+Tue Dec 22 09:43:35 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * argv.c (buildargv): Cast the result of alloca in assignment.
+
+ * choose-temp.c: Include stdlib.h.
+
+ * cplus-dem.c (demangle_arm_pt): Remove unused prototype.
+ (snarf_numeric_literal): Constify first parameter.
+ (code_for_qualifier): Avoid a gcc extension, make the parameter an
+ int, not a char.
+ (demangle_qualifier): Likewise.
+ (demangle_signature): Cast the argument of a ctype function to
+ unsigned char.
+ (arm_pt): Add parens around assignment used as truth value.
+ (demangle_arm_hp_template): Constify variable `args'.
+ (do_hpacc_template_const_value): Cast the argument of a ctype
+ function to unsigned char.
+ (do_hpacc_template_literal): Remove unused variable `i'.
+ (snarf_numeric_literal): Constify parameter `args'.
+ Cast the argument of a ctype function to unsigned char.
+
+ * floatformat.c (floatformat_to_double): Add explicit braces to
+ avoid ambiguous `else'.
+
+ * fnmatch.c (fnmatch): Change type of variables `c', `c1',
+ `cstart' and `cend' to unsigned char. Cast the argument of macro
+ `FOLD', which uses ctype functions, to unsigned char.
+
+ * objalloc.c (free): Add prototype.
+
+Sun Dec 20 16:03:46 1998 Hans-Peter Nilsson <hp@axis.se>
+
+ * Makefile.in (CFILES): Fix typo: splay-tree.c, not splay-tree.o
+
+Fri Dec 18 17:50:18 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * cplus-dem.c (demangle_arm_pt): remove declaration -- function
+ doesn't exist.
+ (do_hpacc_template_literal): remove unused variable `i'.
+
+Fri Dec 18 16:11:43 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cplus-dem.c (demangle_fund_type): Process CV and u codes before
+ bumping the pointer we read from. Also prepend these codes,
+ as we do in other places.
+
+1998-12-18 Nick Clifton <nickc@cygnus.com>
+
+ * cplus-dem.c (demangle_arm_hp_template): Make variable 'args' be
+ 'const char *' in order to match its usage when calling siblings.
+ (snarf_numeric_literal): Make first arg 'const char **' in order
+ to match usage.
+
+Mon Dec 14 09:55:50 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * choose-temp.c: Don't check IN_GCC anymore.
+
+ * floatformat.c (floatformat_from_double): Use `const', not `CONST'.
+ * memchr.c (memchr): Likewise.
+ * memcpy.c (memcpy): Likewise.
+ * memmove.c (memmove): Likewise.
+
+ * mkstemp.c: Don't check IN_GCC anymore.
+ * pexecute.c: Likewise.
+ * splay-tree.c: Likewise.
+
+ * strchr.c (strchr): Use `const', not `CONST'.
+ * strrchr.c (strrchr): Likewise.
+ * strtol.c (strtol): Likewise.
+ * strtoul.c (strtoul): Likewise.
+
+Fri Dec 4 13:51:04 1998 David Taylor <taylor@texas.cygnus.com>
+ Elena Zannoni <ezannoni@cygnus.com>
+ Stan Shebs <shebs@cygnus.com>
+ Edith Epstein <eepstein@cygnus.com>
+ Andres MacLeod <amacleod@cygnus.com>
+ Satish Pai <pai@apollo.hp.com>
+
+ * HP aCC demangling support.
+ * cplus-dem.c
+ (main): Remove default to HP style demangling, set to EDG
+ demangling correctly when -edg specified; set the demangling style
+ when user specifies 'edg'. Set strip_underscore to
+ prepends_underscore, if not HPUXHPPA. Set
+ current_demangling_style to hp_demangling if HPUXHPPA. Set
+ current demangling style correctly if the switch is hp. Read
+ label correctly also in the HP style case.
+ (work_stuff): add temp_start field; add field for volatile member
+ function.
+ (arm_pt): handle ARM_DEMANGLING and EDG_DEMANGLING styles; HP
+ style for this case is the same as ARM.
+ (demangle_args): handle EDG_DEMANGLING style; support HP style.
+ (demangle_arm_hp_template): new function. (It was
+ demangle_arm_pt.); check and set value of temp_start field in
+ multiple places. Also, when ceching for end of template args,
+ check to see if at end of static member of template class.
+ (demangle_class): new local variable : save_class_name_end Don't
+ include template args in string defining class.
+ (demangle_class_name): use demangel_arm_hp_template.
+ (demangle_function_name): handle case where demangling style is
+ HP_DEMANGLING and currently point at an 'X' in the mangled name.
+ Handle EDG_DEMANGLING style. Handle constructor and destructor
+ ops for HP style.
+ (demangle_prefix): handle EDG_DEMANGLING and ARM_DEMANGLING
+ styles. global destructor and constructor for HP style are same
+ as for ARM style. Same for local variables.
+ (demangle_qualified): handle EDG_DEMANGLING style.
+ (demangle_signature): add case for volatile member function. For
+ cases '1' - '9' : initialize the temp_start field to -1 and handle
+ the EDG_DEMANGLING style. for case 'F' : handle EDG_DEMANGLING
+ and AUTO_DEMANGLING styles. If expecting a function and managed
+ to demangle the funct args, then handle the LUCID_DEMANGLING,
+ ARM_DEMANGLING, and EDG_DEMANGLING styles. Add case for local
+ class name after "Lnnn_ in HP style case. HP style too needs to
+ forget types. _nnn is OK for HP style, so don't report failure.
+ (do_hpacc_template_const_value): new function. Handle template's
+ value param for HP/aCC.
+ (do_hpacc_template_literal): new function. Handle a template's
+ literal parameter for HP aCC.
+ (recursively_demangle): new function
+ (snarf_numeric_literal): new function.
+ (usage): add 'edg' to the list of demangling styles; add hp switch
+ to message.
+
+Sat Nov 28 17:25:22 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * pexecute.c: Remove obsolete ifdefed cygwin code.
+
+Fri Nov 27 13:26:06 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * choose-temp.c: Always include libiberty.h. Avoid redundancies.
+ * cplus-dem.c: Likewise. Conform to libiberty.h.
+ * pexecute.c: Likewise.
+ * splay-tree.c: Likewise.
+
+1998-11-25 Mike Stump <mrs@wrs.com>
+
+ * Makefile.in (splay-tree.o): Add config.h dependency.
+
+Mon Nov 23 16:59:49 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Use AC_PREREQ(2.12.1).
+
+1998-11-16 Benjamin Kosnik <bkoz@haight.constant.com>
+
+ * cplus-dem.c (demangle_fund_type): Add demangling for C9x types.
+
+Thu Nov 19 22:15:50 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mpw.c (mpw_access): Add missing parens.
+
+Thu Nov 19 12:59:21 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Call AC_HEADER_SYS_WAIT.
+
+ * pexecute.c: Include sys/wait.h when !IN_GCC.
+
+Thu Nov 19 14:38:20 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * pexecute.c: revert back to checking old Cygwin
+ preprocessor symbol until some time has passed.
+
+Wed Nov 18 08:52:26 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * pexecute.c: Reorganize WIN32 case to accomodate Cygwin
+ since it will now support similar constructs.
+
+Fri Nov 13 19:18:05 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Check for calloc.
+
+ * calloc.c: New file.
+
+ * xmalloc.c (xcalloc): New function.
+
+Fri Nov 13 08:51:46 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ *cplus-dem.c (demangle_prefix): Use the last "__"
+ in the mangled name when looking for the signature. This allows
+ template names to begin with "__".
+
+1998-11-08 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c (type_kind_t): Add tk_reference.
+ (demangle_template_value_parm): Handle it.
+ (do_type): Use it for references, instead of tk_pointer.
+
+ * cplus-dem.c (demangle_template_value_parm): Use cplus_demangle,
+ not internal_cplus_demangle.
+
+Sat Nov 7 16:02:10 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * choose-temp.c: Don't include gansidecl.h.
+ * mkstemp.c: Likewise.
+ * pexecute.c: Likewise.
+
+Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Mon Nov 2 10:22:01 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * pexecute.c: Check HAVE_CONFIG_H, not IN_GCC, when determining
+ whether to include config.h. Possibly include unistd.h in the
+ !IN_GCC case. Define VFORK_STRING as a printable function call
+ for error messages (either "vfork" or "fork".) If HAVE_VFORK_H is
+ defined, include vfork.h. If VMS is defined, define vfork()
+ appropriately. Remove vfork check on USG, we're using autoconf.
+ (pexecute): Set `errmsg_fmt' to VFORK_STRING instead of checking
+ locally what string to use.
+
+1998-10-26 Mark Mitchell <mark@markmitchell.com>
+
+ * splay-tree.c: Tweak include directives to make sure declarations of
+ xmalloc and free are available.
+
+1998-10-25 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c (gnu_special): Fix handling of virtual tables in
+ anonymous namespaces.
+
+1998-10-23 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c (work_stuff): Replace const_type and volatile_type
+ with type_quals.
+ (TYPE_UNQUALIFIED): New macro.
+ (TYPE_QUAL_CONST): Likewise.
+ (TYPE_QUAL_VOLATILE): Likewise.
+ (TYPE_QUAL_RESTRICT): Likewise.
+ (code_for_qualifier): New function.
+ (qualifier_string): Likewise.
+ (demangle_qualifier): Likewise.
+ (internal_cplus_demangle): Use them.
+ (demangle_signature): Likewise.
+ (demangle_template_value_parm): Likewise.
+ (do_type): Likewise.
+ (demangle_fund_type)): Likewise.
+
+Thu Oct 22 19:58:43 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * splay-tree.c (splay_tree_foreach_helper): Make definition static
+ to match prototype.
+
+1998-10-21 Mark Mitchell <mark@markmitchell.com>
+
+ * splay-tree.c: New file.
+ * Makefile.in (CFILES): Add it.
+ (REQUIRED_OFILES): Likewise.
+ (splay-tree.o): Add dependencies.
+
+Tue Oct 20 12:29:02 1998 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * cplus-dem.c (demangle_qualified): Fix off-by-one when checking
+ range of 'K' index.
+
+Thu Oct 15 18:51:12 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * choose-temp.c: Prototype mkstemps() when IN_GCC.
+
+ * cplus-dem.c (consume_count): Cast argument of ctype macro to
+ `unsigned char'.
+ (cplus_demangle_opname): Cast the result of `strlen' to (int) when
+ comparing against one.
+ (cplus_mangle_opname): Likewise.
+ (demangle_integral_value): Cast argument of ctype macro to
+ `unsigned char'.
+ (demangle_template_value_parm): Likewise.
+ (demangle_template): Initialize variable `bindex'. Cast the
+ result of `strlen' to (int) when comparing against one. Remove
+ unused variable `start_of_value_parm'.
+ (demangle_class_name): Cast the result of `strlen' to (int) when
+ comparing against one.
+ (demangle_prefix): Cast argument of ctype macro to `unsigned char'.
+ (gnu_special): Likewise. Cast the result of `strlen' to (int)
+ when comparing against one.
+ (demangle_qualified): Cast argument of ctype macro to `unsigned char'.
+ (get_count): Likewise.
+ (do_type): Likewise. Cast the result of `strlen' to (int) when
+ comparing against one.
+ (demangle_fund_type): Cast argument of ctype macro to `unsigned char'.
+ (demangle_function_name): Cast the result of `strlen' to (int)
+ when comparing against one.
+
+ * mkstemp.c (mkstemps): Cast variable `len' to (int) when
+ comparing against one.
+
+Tue Oct 13 23:51:51 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mkstemp.c: Check HAVE_SYS_TIME_H before including sys/time.h
+ * configure.in (AC_CHECK_HEADERS): Check for sys/time.h too.
+ * config.in, configure: Rebuilt.
+
+ * getopt.c: Check HAVE_STRINGS_H before including strings.h.
+ * configure.in (AC_CHECK_HEADERS): Check for strings.h too.
+ * config.in, configure: Rebuilt.
+
+Mon Oct 12 19:15:59 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: in comment, call AC_EXEEXT instead of AM_EXEEXT
+
+Sun Oct 11 17:36:06 1998 Michael Tiemann <tiemann@holodeck.cygnus.com>
+
+ * Makefile.in (cplus-dem.o, obstack.o): Depend upon config.h.
+
+Thu Oct 8 23:42:08 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Merge egcs & devo libiberty.
+
+1998-09-08 Martin von Löwis <loewis@informatik.hu-berlin.de>
+
+ * cplus-dem.c (demangle_arm_pt): Demangle anonymous namespaces.
+
+Mon Sep 7 23:29:01 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mkstemp.c: Include config.h even when not IN_GCC. Wrap header
+ inclusions inside HAVE_*_H macros. Include ansidecl.h when not
+ IN_GCC.
+
+ * vasprintf.c: Include stdarg.h/varargs.h first.
+
+ * vprintf.c: Likewise.
+
+Sat Sep 5 03:24:49 1998 Jeffrey A Law (law@cygnus.com)
+
+ * pexecute.c: Updates from gcc. Copy in gcc has been removed. This
+ is the canonical copy. Define ISSPACE if !IN_GCC.
+ * alloca.c, vfprintf.c, choose-temp.c, mkstemp.c, getopt.c: Similarly.
+ * getopt1.c, obstack.c: Similarly.
+ * Makefile.in: Build mkstemp.o
+
+Tue Sep 1 23:12:47 1998 Christopher Faylor <cgf@cygnus.com>
+
+ * configure.in: Include asprintf in list of functions known not
+ to be in newlib.
+ * configure: Rebuild.
+
+Wed Aug 19 14:05:01 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * cplus-dem.c (work_stuff): Add dllimported.
+ (demangled_prefix): Mark symbols imported from PE DLL.
+ (internal_cplus_demangled): Handle.
+
+1998-08-17 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (do_type): Fix simple array handling. If we fail,
+ stay failed.
+
+Mon Aug 17 10:40:34 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cplus-dem.c: Include config.h if it exists. Also, only
+ prototype malloc/realloc if we can't get stdlib.h.
+
+Sat Aug 15 16:15:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Switch back to checking --with-target-subdir when
+ deciding whether to check for newlib, undoing part of July 15
+ change.
+ * configure: Rebuild.
+
+Thu Aug 13 16:47:38 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c (type_kind_t): New type.
+ (demangle_template_value_parm): Add type_kind_t parameter. Rely
+ on this paramter, rather than demangling the type again.
+ (demangle_integral_value): Pass tk_integral.
+ (demangle_template_: Pass the value returned from do_type.
+ (do_type): Return a type_kind_t. Pass tk_integral to
+ demangle_template_value_parm for array bounds.
+ (demangle_fund_type): Likewise.
+
+ Also incorporate from GCC version:
+
+ Tue Jul 21 13:28:19 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (do_type): Use demangle_template_value_parm for arrays.
+
+Thu Aug 13 16:47:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cplus-dem.c (demangle_nested_args): Make function definition
+ static to match the prototype.
+
+Tue Jul 28 11:33:09 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c (type_kind_t): New type.
+ (demangle_template_value_parm): Add type_kind_t parameter. Rely
+ on this paramter, rather than demangling the type again.
+ (demangle_integral_value): Pass tk_integral.
+ (demangle_template_: Pass the value returned from do_type.
+ (do_type): Return a type_kind_t. Pass tk_integral to
+ demangle_template_value_parm for array bounds.
+ (demangle_fund_type): Likewise.
+
+ Also incorporate from GCC version:
+
+ Tue Jul 21 13:28:19 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (do_type): Use demangle_template_value_parm for arrays.
+
+Mon Jul 27 12:16:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALLOCA): New variable.
+ ($(TARGETLIB)): Add $(ALLOCA) to library.
+ (needed-list): Add $(ALLOCA).
+ ($(ALLOCA)): Depend upon stamp-picdir.
+
+Sun Jul 19 08:23:17 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cplus-dem.c (demangle_nested_args): Make function definition
+ static to match the prototype.
+
+Wed Jul 15 00:12:58 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Check --with-cross-host rather than
+ --with-target-subdir when deciding whether build uses a cross
+ compiler, and when deciding where to install the library.
+ * configure: Rebuild.
+
+Sun Jul 12 01:27:05 1998 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (demangle_nested_args): Return a value.
+
+Sat Jul 11 16:19:48 1998 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c (string): Move definition before work_stuff.
+ (work_stuff): Add volatile_type, forgetting_types,
+ previous_argument, and nrepeats fields.
+ (SCOPE_STRING): New macro.
+ (demangle_template): Add `remember' parameter. Add comment.
+ Register the `B' code type here, if remembering. Tidy. Fix crash
+ on NULL tmpl_argvec. Be consistent with use of tname/trawname.
+ (demangle_nested_args): New function.
+ (internal_cplus_demangle): Handle volatile-qualified member
+ functions.
+ (mop_up): Delete the previous_argument string if present.
+ (demangle_signature): Tidy. Handle volatile-qualified member
+ functions. Handle back-references using the `B' code. Use extra
+ parameter to demangle_template and SCOPE_STRING where appropriate.
+ (demangle_template_value_parm): Fix thinko; 'B' is not an integral
+ code.
+ (demangle_class): Use SCOPE_STRING.
+ (gnu_special): Pass additional argument to demangle_template.
+ Use SCOPE_STRING.
+ (demangle_qualified): Save qualified types for later
+ back-references. Handle constructors and destructors for template
+ types correctly.
+ (do_type): Tidy. Use SCOPE_STRING. Pass extra argument to
+ demangle_template. Use demangled_nested_args. Don't remember
+ qualified types here; that's now done in demangle_qualified.
+ Similarly for templates.
+ (do_arg): Improve commment. Handle 'n' repeat code.
+ (remember_type): Check forgetting_types.
+ (demangle_args): Deal with 'n' repeat codes. Tidy.
+
+Thu Jul 2 16:26:24 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.table: Only use mh-fbsd21 on *-*-freebsd2.2.[012], not on
+ *-*-freebsd2.2.*. From Dmitrij Tejblum <tejblum@arc.hq.cti.ru>.
+
+Mon Jun 15 16:29:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (setobjs): Correct quoting error in cygwin32 case.
+ From Chris Faylor <cgf@cygnus.com>.
+
+Mon Jun 1 13:47:55 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * obstack.c: Update to latest FSF version.
+
+Mon Jun 1 14:17:36 1998 Mike Stump <mrs@wrs.com>
+
+ * Makefile.in: Add a dependency on stamp-picdir for the
+ objects, so that we can do a parallel build.
+
+Sat May 30 22:17:13 1998 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * configure.in (checkfuncs): Add missing "'".
+
+Fri May 29 12:40:41 1998 Jason Molenda (crash@bugshack.cygnus.com)
+
+ * obstack.c (_obstack_memory_used): Elide this function if we're
+ on a system with GNU libc.
+
+Tue May 26 18:28:43 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Remove config.log.
+
+Tue May 26 15:01:52 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * Makefile.in (distclean): Don't remove alloca-conf.h.
+
+Fri May 22 01:38:07 1998 Hans-Peter Nilsson <hp@axis.se>
+
+ * cplus-dem.c (MBUF_SIZE): Bumped from 512 to 32767.
+
+1998-05-21 Mark Mitchell <mmitchell@usa.net>
+
+ * cplus-dem.c (do_type): Handle volatile qualification.
+
+1998-05-21 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * configure.in: Check for unistd.h as well.
+ * configure: Rebuild.
+ * config.in: Rebuild.
+ * getpagesize.c (GNU_OUR_PAGESIZE): Use sysconf only if _SC_PAGESIZE
+ is defined in unistd.h. Reformat conditional block for easier reading.
+
+ * config.table (shared): Default to no if ${enable_shared}
+ is unset or empty; this logic is used by the toplevel
+ configure scripts, too.
+
+Sat May 16 14:01:26 1998 Jeffrey A Law (law@cygnus.com)
+
+ * config.table: Add line to set enable_shared in the Makefile
+ as needed.
+
+Wed May 13 14:24:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cplus-dem.c (squangle_mop_up): Change return type to void.
+ (internal_cplus_demangle): Remove unused parameter `options'.
+ All callers changed.
+ (cplus_demangle_opname): Remove function wide variable `int i' and
+ replace with `size_t i' at each location where it is used.
+ (cplus_mangle_opname): change type of `i' from int to size_t.
+
+Wed May 13 13:39:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * alloca-conf.h: Include config.h. Check HAVE_ALLOCA_H rather
+ than sparc or sun.
+ * Makefile.in (argv.o): Depend upon config.h and alloca-conf.h.
+
+Fri May 8 00:23:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set libiberty_topdir correctly when srcdir is
+ "." and with_target_subdir is not set.
+ * configure: Rebuild.
+
+Thu May 7 13:01:44 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add *-*-mingw32* case.
+ * configure: Rebuild.
+
+Wed May 6 11:33:51 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.table: Never use a PIC file for *-*-cygwin32*.
+
+ * Makefile.in (config.status): Depend upon config.table.
+
+ * configure.in: On a cygwin32 host, always compile random, and
+ don't test for sys_siglist, strsignal, or psignal.
+ * configure: Rebuild.
+
+ * clock.c: Check HAVE_SYS_PARAM_H rather than NO_SYS_PARAM_H.
+ * getcwd.c: Likewise.
+ * getpagesize.c: Likewise.
+ * getruntime.c: Likewise.
+
+Tue May 5 18:08:32 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Use autoconf tests rather than the old dummy.c test:
+ * configure.in: Add AC_ARG_WITH calls for --with-target-subdir and
+ --with-newlib. Add AC_CONFIG_HEADER. Use AC_REPLACE_FUNCS for
+ most functions. Add special cases to handle newlib and VxWorks.
+ Remove target_makefile_frag. Create stamp-h in AC_OUTPUT if
+ CONFIG_HEADERS is set. Only call config-ml.in in AC_OUTPUT if
+ CONFIG_FILES is set; set ac_file before calling it.
+ * config.table (arm-*-riscix*, *-*-cygwin32): Remove.
+ (*-*-hpux*, *-*-hiux*, *-*-irix4*, *-*-solaris2*): Remove.
+ (*-*-sysv4*, *-*-go32, *-*-vxworks5*, *-*-vxworks): Remove
+ (i[3456]-*-mingw32*): Remove.
+ * Makefile.in (ERRORS_CC, CONFIG_H, NEEDED_LIST): Remove.
+ (LIBOBJS): New variable.
+ (HOST_OFILES, DO_ALSO, STAGESTUFF): Remove.
+ (all): Depend upon needed-list. Don't check RULE1.
+ (@target_makefile_frag@): Remove.
+ (COMPILE.c): Include @DEFS@.
+ (HFILES): Add alloca-conf.h.
+ (REQUIRED_OFILES): Remove basename.o.
+ ($(TARGETLIB)): New target.
+ (stamp-needed, lneeded-list, needed.awk, stamp-config): Remove.
+ (lconfig.h, needed2.awk, dummy.o, errors): Remove.
+ (needed-list, config.h): Rewrite.
+ (RULE1, $(RULE1), RULE2, $(RULE2)): Remove.
+ (.always.): Remove.
+ (Makefile): Set CONFIG_FILES and CONFIG_HEADERS.
+ (stamp-h): New target.
+ (atexit.o, clock.o, getcwd.o, getpagesize.o): New targets.
+ (basename.o): Don't depend upon config.h.
+ (getruntime.o): Depend upon config.h.
+ * atexit.c: Include config.h. Check HAVE_ON_EXIT rather than
+ NEED_on_exit.
+ * basename.c: Don't include config.h. Don't check NEED_basename.
+ * clock.c: Include config.h.
+ * getcwd.c: Likewise.
+ * getpagesize.c: Likewise.
+ * getruntime.c: Likewise. Fix checks which set HAVE_GETRUSAGE and
+ HAVE_TIMES.
+ * strerror.c: Change uses of NEED_sys_errlist to
+ HAVE_SYS_ERRLIST. Likewise for NEED_strerror and HAVE_STRERROR.
+ * strsignal.c: Likewise for NEED_sys_siglist and HAVE_SYS_SIGLIST,
+ and for NEED_strsignal and HAVE_STRSIGNAL and for NEED_psignal and
+ HAVE_PSIGNAL.
+ * acconfig.h: New file.
+ * dummy.c: Remove.
+ * functions.def: Remove.
+ * config/mh-cxux7 (HDEFINES): Remove -DHAVE_SYSCONF.
+ * config/mh-windows (HDEFINES): Remove.
+ * config/mh-cygwin32: Remove.
+ * config/mh-go32: Remove.
+ * config/mh-irix4: Remove.
+ * config/mh-riscix: Remove.
+ * config/mh-sysv4: Remove.
+ * config/mt-mingw32: Remove.
+ * config/mt-vxworks5: Remove.
+ * config.in: New file, generated using autoheader.
+ * configure: Rebuild.
+
+Mon May 4 13:00:28 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Rewrite to use autoconf.
+ * configure: Generate using autoconf.
+ * config/mh-a68bsd: Remove.
+ * config/mh-apollo68: Remove.
+ * config/mh-hpbsd: Remove.
+ * config/mh-ncr3000: Remove.
+ * config/mh-sysv: Remove.
+ * config/mh-aix (RANLIB, INSTALL): Don't define.
+ * config/mh-cxux7 (RANLIB, INSTALL): Don't define.
+ * config/mh-irix4 (CC, RANLIB, INSTALL): Don't define.
+ * config/mh-sysv4 (RANLIB, INSTALL): Don't define.
+ * config.table: Change config_shell to CONFIG_SHELL, and use
+ libiberty_topdir to find move-if-change.
+ (m68k-apollo-bsd*, m68k-apollo-sysv*): Remove.
+ (i[3456]86-ncr-sysv4*, *-*-dgux*, hppa*-hp-bsd*): Remove.
+ (*-*-irix*, *-*-m88kbcs*, *-*-sysv*): Remove.
+ * Makefile.in (srcdir): Set to @srcdir@.
+ (VPATH): Likewise.
+ (prefix, exec_prefix, bindir, libdir): Set to autoconf variables.
+ (SHELL, INSTALL, INSTALL_PROGRAM, INSTALL_DATA): Likewise.
+ (CC, CFLAGS, RANLIB)): Likewise.
+ (datadir, man*dir, infodir, includedir, MAKEINFO): Remove.
+ (target_makefile_frag, host_makefile_frag): Add substitutions.
+ (INSTALL_DEST): Set to @INSTALL_DEST@.
+ (Makefile): Depend upon config.status. Don't depend upon
+ $(host_makefile_frag) or $(target_makefile_frag).
+ (config.status): New target.
+
+Sun May 3 17:58:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/mt-sunos4: Remove. Should be handled by --with-headers
+ and --with-libraries options at top level.
+ * config.table: Never use mt-sunos4.
+
+ * alloca-conf.h: New file, combining alloca-norm.h and
+ alloca-botch.h.
+ * alloca-norm.h: Remove.
+ * alloca-botch.h: Remove.
+ * configure.in: Set shell variables files and links to empty.
+ * config.table: Don't set shell variable files.
+ * configure.bat: Don't create alloca-conf.h.
+ * makefile.vms: Likewise.
+ * mpw-config.in: Likewise.
+ * vmsbuild.com: Likewise.
+
+Fri May 1 11:41:42 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(HOST_OFILES) $(REQUIRED_OFILES)): Remove old
+ target depending upon config.h.
+ (alloca.o): Add target depending upon config.h
+ (basename.o, choose-temp.o, fnmatch.o): Likewise.
+ (getopt.o, getopt1.o, pexecute.o, strerror.o): Likewise.
+ (strsignal.o, xstrerror.o): Likewise.
+
+Fri May 1 04:26:25 1998 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * cplus-dem.c (cplus_demangle_opname): Initialize work.
+
+Mon Apr 27 15:53:30 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cplus-dem.c (demangle_qualified): Replace missing else.
+
+Sun Apr 26 15:38:50 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * cplus-dem.c (gnu_special): Fix off-by-one bug when checking the
+ length in the name of a virtual table.
+
+Wed Apr 22 10:53:49 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cplus-dem.c (struct work stuff): Add field for B and K mangle codes.
+ (cplus_demangle_opname): Call mop_up_squangle.
+ (cplus_demangle): Initialize squangle info, then call
+ internal_cplus_demangle. (Most code moved there as well)
+ (internal_cplus_demangle): New function, performs most of what use
+ to be done in cplus_demangle, but is only called with this file.
+ (squangle_mop_up): New function to clean up B and K code data.
+ (mop_up): set pointers to NULL after freeing.
+ (demangle_signature, demangle_template, demangle_class): Add
+ switch elements to handle K and B codes.
+ (demangle_prefix, gnu_special, demangle_qualified): Add
+ code to handle K and B codes.
+ (do_type, demangle_fund_type): Handle B and K codes.
+ (remember_Ktype): New function to store K info.
+ (register_Btype, remember_Btype): New functions for B codes.
+ (forget_B_and_K_types): New function to destroy B and K info.
+
+Fri Apr 10 01:49:10 1998 Jeffrey A Law (law@cygnus.com)
+
+ * COPYING.LIB, choose-temp.c, cplus-dem.c: Sync with egcs & gcc.
+
+Thu Mar 5 09:23:28 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * config.table: Make locating frag files failsafe even for the
+ special case if configuring and building in srcdir.
+
+Mon Feb 23 14:33:15 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * choose-temp.c: Fix handling of sys/file.h to work in libiberty.
+
+Sun Feb 22 18:03:23 1998 Jeffrey A Law (law@cygnus.com)
+
+ * choose-temp.c: Sync with copy in gcc.
+
+Thu Feb 12 16:29:49 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * getopt.c: Update to latest FSF version.
+ * getopt1.c: Likewise.
+
+Tue Feb 10 16:58:33 1998 Stan Shebs <shebs@andros.cygnus.com>
+
+ * cplus-dem.c (gnu_special): Don't get confused by .<digits>
+ strings that are not actually lengths.
+
+Fri Feb 6 01:35:17 1998 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (FLAGS_TO_PASS): Don't pass PICFLAG.
+ (.c.o): Check value of enable_shared, not PICFLAG.
+ (stamp-picdir): Dito.
+
+Thu Feb 5 18:48:56 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mh-cygwin32: remove vasprintf.o from EXTRA_OFILES
+ since it gets built automatically
+
+Sun Feb 1 02:52:32 1998 Mike Stump <mrs@wrs.com>
+
+ * config.table (vxworks configs): Default to VxWorks 5.x, as that is
+ the currently shipping OS.
+
+Tue Jan 27 16:08:20 1998 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmsbuild.com [REQUIRE_OFILES]: Synchronized with Makefile.in:
+ Add fnmatch.o and objalloc.o; remove vasprintf.o.
+ [config.h]: Define NEED_strsignal.
+
+Mon Jan 19 12:20:01 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * functions.def: Correct argument types for strerror and
+ strsignal. Reported by Alex Gutman <agutman@emc.com>.
+
+Sun Jan 18 15:57:28 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * vasprintf.c (int_vasprintf): Increase buffer size for float/double
+ values.
+
+Sat Jan 17 22:28:38 1998 Mumit Khan <khan@xraylith.wisc.edu>
+ J.J. VanderHeijden <J.J.vanderHeijden@student.utwente.nl>
+
+ Add mingw32 support.
+ * pexecute.c (pexecute): New function for mingw32. Supports pipes.
+ (pwait): New function for mingw32.
+
+ * config.table (i[3456]86-*-mingw32*): Support for i386-mingw32.
+ * config/mt-mingw32: New file.
+ * xmalloc.c (first_break): Not used for mingw32.
+ (xmalloc_set_program_name): Don't use sbrk on mingw32.
+ (xmalloc): Likewise.
+ (xrealloc): Likewise.
+
+Sat Jan 17 22:28:05 1998 Jeffrey A Law (law@cygnus.com)
+
+ * choose-temp.c: Sync with gcc version.
+
+Tue Jan 13 18:34:39 1998 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.in (install_to_libdir, install_to_tooldir): Add MULTISUBDIR
+ to all filenames in libdir and tooldir.
+ (distclean): Do MULTICLEAN before deleting Makefile.
+ (stamp-needed, stamp-config): Add MULTISRCTOP to
+ pathname for move-if-change.
+
+Thu Dec 4 17:25:19 1997 Jeffrey A Law (law@cygnus.com)
+
+ * strsignal.c (sys_nsig): Try NSIG and _NSIG.
+
+Wed Nov 19 13:37:06 1997 Michael Meissner <meissner@cygnus.com>
+
+ * alloca-norm.h (alloca, GCC case): Don't redefine alloca if it
+ was already defined previously.
+
+Mon Nov 10 12:48:03 1997 Philippe De Muyter <phdm@macqel.be>
+
+ * Makefile.in (INSTALL): Use ../install-sh, not install.
+
+Tue Oct 28 23:41:15 1997 Judy Goldberg <jodyg@idt.net>
+
+ * Makefile.in (CFILES): Add pexecute.c.
+
+Wed Oct 15 19:13:48 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * asprintf.c: Consistently use either stdarg or varargs.
+
+Tue Oct 14 12:01:00 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * cplus-dem.c (demangle_signature): Don't look for return types on
+ constructors. Handle member template constructors.
+
+Fri Oct 3 17:53:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * README: Fix configuration instructions.
+
+Mon Sep 29 12:28:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * pexecute.c: Update to current version from /gd/gnu/lib:
+
+ Mon Sep 29 12:27:59 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * pexecute.c: Use spawn if __CYGWIN32__.
+
+ 1997-08-08 Paul Eggert <eggert@twinsun.com>
+
+ * pexecute.c: Include "config.h" first, as per autoconf manual.
+
+ Fri Jun 27 15:20:29 1997 Scott Christley <scottc@net-community.com>
+
+ * pexecute.c (fix_argv): New function.
+ (pexecute): Win32 but not Cygwin32 needs its arguments fixed.
+ Add underscore to cwait function call.
+
+Sun Sep 28 12:00:52 1997 Mark Mitchell <mmitchell@usa.net>
+
+ * cplus-dem.c (demangle_template): Add new parameter. Handle new
+ template-function mangling.
+ (consume_count_with_underscores): New function.
+ (demangle_signature): Handle new name-mangling scheme.
+
+Wed Sep 24 00:31:59 1997 Felix Lee <flee@yin.cygnus.com>
+
+ * asprintf.c: stdarg.h when ALMOST_STDC
+ * config/mh-windows (EXTRA_OFILES): add asprintf.o and
+ strncasecmp.o.
+
+Thu Aug 28 14:27:15 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * vasprintf.c (vasprintf): Allow for _BSD_VA_LIST_.
+
+ * config.table: Add case for FreeBSD 2.1 and 2.2, needs mh-fbsd21.
+
+ * config/mh-fbsd21 (EXTRA_OFILES): Force vasprintf.o
+
+Wed Sep 10 12:43:10 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (demangle_fund_type): Change "complex" to "__complex".
+
+Fri Sep 5 16:34:42 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * asprintf.c (asprintf): New file.
+ * Makefile.in (CFILES): Add asprintf.c
+ * functions.def: Ditto.
+
+Thu Aug 28 18:53:34 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * argv.c (dupargv): New function, duplicate an argument vector.
+
+Tue Aug 19 20:28:45 1997 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mh-cygwin32: also build random.o
+
+Tue Aug 19 17:10:56 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c: Add 'extern' to prepends_underscore.
+
+Wed Jul 30 11:42:19 1997 Per Bothner <bothner@cygnus.com>
+
+ * cplus-dem.c: Various changes to produce Java output when passed
+ DMGL_JAVA. Thus "::" becomes "." and "JArray<Foo>" becomes "Foo[]".
+ (main): Support --java and -j flags to set DMGL_JAVA.
+
+Tue Jul 22 19:05:23 1997 Robert Hoehne <robert.hoehne@Mathematik.TU-Chemnitz.DE>
+
+ * config/mh-go32 (CC, AR, RANLIB): Don't define.
+
+Tue Jul 22 17:49:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (REQUIRED_OFILES): Add pexecute.o.
+ (pexecute.o): New target.
+
+ * Makefile.in (stamp-needed): New target, replacing needed-list.
+ (needed-list): Just depend upon stamp-needed.
+ (stamp-config): New target, replacing config.h.
+ (config.h): Just depend upon stamp-config.
+ (mostlyclean): Remove stamp-*.
+
+Thu Jun 12 11:00:18 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): pass INSTALL, INSTALL_PROGRAM and
+ INSTALL_DATA for multilibbed installs
+
+Tue Jun 3 13:21:05 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ Tue Dec 10 09:44:57 1996 Paul Eggert <eggert@twinsun.com>
+
+ * choose-temp.c (choose_temp_base): Don't dump core if TMPDIR is empty.
+
+ * choose-temp.c (try): Insist that temp dir be searchable.
+
+ Wed Oct 23 17:36:39 1996 Doug Rupp (rupp@gnat.com)
+
+ * choose-temp.c (choose_temp_base): On VMS, use proper syntax
+ for current directory.
+
+ Sat Feb 15 19:03:48 1997 Geoffrey Noer (noer@cygnus.com)
+
+ * pexecute.c: Remove special cases for cygwin32.
+ (pwait): Remove local definition of `pid'.
+
+ Tue Nov 12 18:26:15 1996 Doug Rupp (rupp@gnat.com)
+
+ * pexecute.c (vfork): Supply new definition for VMS.
+ (pwait): Use waitpid instead of wait for VMS.
+
+Tue May 20 14:02:20 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cplus-dem.c (do_type): Handle `J'.
+ (demangle_fund_type): Print "complex" for it.
+
+Wed Apr 30 12:15:45 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * configure.in: Don't turn on multilib here.
+
+Mon Apr 28 19:04:31 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * obstack.c: move _obstack_memory_used outside of ifdef. Cannot be
+ elided; needed by gdb and not present in libc.
+
+Thu Apr 24 19:33:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (clean): Remove tmpmulti.out.
+
+Tue Apr 22 10:25:15 1997 Fred Fish <fnf@cygnus.com>
+
+ * floatformat.c (floatformat_ieee_double_littlebyte_bigword):
+ Add new floatformat, mainly for ARM doubles.
+
+Mon Apr 14 12:11:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.table: Use ${config_shell} with ${moveifchange}. From
+ Thomas Graichen <graichen@rzpd.de>.
+
+Fri Apr 4 03:09:24 1997 Ulrich Drepper <drepper@cygnus.com>
+
+ * configure.in: Enable multilibing by default.
+ Update multilib template to read config-ml.in.
+
+Tue Apr 1 16:26:39 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Add objalloc.
+
+Mon Mar 31 23:57:51 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * cplus-dem.c (demangle_it): Add prototype declaration.
+ (usage, fatal): Likewise.
+
+ * xexit.c (_xexit_cleanup): Add prototype.
+
+ * strerror.c (init_error_tables): Declare.
+
+Fri Mar 28 11:43:20 1997 H.J. Lu <hjl@lucon.org>
+
+ * functions.def: Add DEF of vasprintf, and DEFFUNC of strsignal.
+ * strsignal.c: Only define strsignal if NEED_strsignal.
+ * Makefile.in (REQUIRED_OFILES): Remove vasprintf.o.
+ * configure.in: Add NEED_strsignal to xconfig.h. Add vasprintf.o
+ to xneeded-list.
+ * config/mh-cygwin32 (HDEFINES): Add -DNEED_strsignal.
+ (EXTRA_OFILES): Define to vasprintf.o.
+ * config/mh-windows (HDEFINES): Add -DNEED_strsignal.
+ (EXTRA_OFILES): Add vasprintf.o.
+ * config/mt-vxworks5 (vxconfig.h): Define NEED_strsignal.
+ (vxneeded-list): Add vasprintf.o.
+
+Thu Mar 20 17:02:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objalloc.c: Include <stdio.h>.
+
+Mon Mar 17 19:23:11 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * objalloc.c: New file.
+ * Makefile.in (CFILES): Add objalloc.c
+ (REQUIRED_OFILES): Add objalloc.o.
+ (objalloc.o): New target.
+
+Sat Mar 15 18:49:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * obstack.c: Update to current FSF version.
+
+Fri Mar 14 14:18:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * cplus-dem.c: Add prototypes for all static functions.
+ (mystrstr): Make static. Make arguments and result const.
+ (cplus_match): Remove; not used.
+
+Tue Mar 11 14:20:31 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cplus-dem.c (gnu_special): Call demangled_fund_type for other
+ __t* symbols.
+
+Tue Mar 11 15:41:21 1997 H.J. Lu <hjl@lucon.org>
+
+ * spaces.c: Declare malloc and free properly.
+ * strsignal.c (init_signal_tables): Add prototype.
+ * xatexit.c (_xexit_cleanup): Add parameter declarations.
+
+Wed Feb 19 15:43:24 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (lneeded-list): If alloca.o is needed, xexit.o is
+ also required because of xmalloc.o.
+
+Fri Feb 14 13:43:38 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * strsignal.c: Unconditionally redefine sys_siglist around the
+ inclusion of the system header files.
+
+Thu Feb 13 22:01:04 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Remove 8 bit characters. Update to latest
+ gcc release.
+
+Tue Feb 4 11:52:19 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * strsignal.c: Use NEED_sys_siglist instead of
+ LOSING_SYS_SIGLIST.
+ * config.table: Don't use mh-lynxos.
+ * config/mh-lynxos: Remove.
+
+Thu Jan 16 14:51:03 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * cplus-dem.c: Fix indenting; make identical to the copy
+ in GCC.
+ (do_type, case 'M'): Check for a template as well as a class.
+
+Thu Dec 19 13:51:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * config/mt-vxworks5 (vxneeded-list): Remove sigsetmask.o, since
+ vxworks 5.[0-3] all have sigsetmask in them; the one provided by
+ libiberty is incorrect, as well.
+
+Mon Dec 2 15:03:42 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * alloca.c (alloca): When compiled with an ANSI/ISO compiler,
+ alloca takes a size_t argument, not just unsigned.
+
+Mon Nov 18 15:42:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c: Note that this file also lives in GCC.
+
+Mon Nov 18 15:19:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * alloca.c: Remove include of libiberty.h for hpux.
+ * argv.c: Replace defs from libiberty.h.
+ * spaces.c: Put back externs from removed from libiberty.h.
+ * vasprintf.c: Remove include of libiberty.h for hpux.
+
+Mon Nov 18 14:08:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * cplus-dem.c: Checking in again; last checkin filed due to sticky tag.
+
+Wed Nov 13 08:22:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * cplus-dem.c: Revert last two commits due to conflicts with
+ hpux system headers.
+
+Wed Nov 13 08:22:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * alloca.c, argv.c, spaces.c, strcasecmp.c, vasprintf.c, vprintf.c:
+ Revert last commit due to conflicts with hpux system headers.
+
+Wed Nov 13 10:36:50 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * cplus-dem.c (x{m,re}alloc): Make declarations compatibile with
+ libiberty.h when compiled with a standard compiler.
+
+Tue Nov 12 16:31:00 1996 Dawn Perchik <dawn@critters.cygnus.com>
+
+ * alloca.c: Include libiberty.h for definition of xmalloc.
+ Don't redefine NULL.
+ * argv.c: Move prototypes to libiberty.h.
+ * cplus-dem.c: Include libiberty.h for definition of xmalloc.
+ Don't redefine NULL.
+ Use casts to eliminate compiler warnings.
+ * spaces.c: Remove prototypes for malloc and free which are
+ already in libibrty.h.
+ * strcasecmp.c: Use casts to eliminate compiler warnings.
+ * vasprintf.c: Include libiberty.h for definition of malloc.
+ Don't redefine NULL.
+ * vprintf.c: Include stdarg.h if __STDC__.
+
+Fri Oct 11 15:42:12 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config/mh-windows: Add strcasecmp.o to EXTRA_OFILES.
+
+Fri Oct 11 11:16:31 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.c (mpwify_filename): Rewrite to simplify, and to handle
+ upward components correctly.
+
+Tue Oct 8 08:55:34 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * config.table, config/mh-windows: Add support for building under
+ MSVC (the Microsoft build environment).
+
+Mon Oct 7 10:50:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * fnmatch.c: Undef const if not __STDC__.
+
+Thu Oct 3 13:46:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * fnmatch.c: New file.
+ * Makefile.in (CFILES): Add fnmatch.c.
+ (REQUIRED_OFILES): Add fnmatch.o.
+ (fnmatch.o): New target.
+
+Wed Sep 18 14:49:13 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (demangle_template): Fix handling of address args.
+ (gnu_special): Handle type_info stuff.
+
+Fri Sep 13 17:52:55 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.c (DebugPI): Make settable from the env var DEBUG_PATHNAMES.
+ (mpwify_filename): Handle "::/" case.
+
+Thu Sep 12 13:30:40 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * config/mh-cygwin32: new file (need -DNEED_basename and
+ -DNEED_sys_siglist for native NT rebuilding)
+ * config.table (*-*-cygwin32): new entry
+ * choose-temp.c: bring in sync with gcc (revert Aug 17 change)
+
+Thu Aug 29 16:48:45 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * config.table (i[345]86-*-*): Recognize i686 for pentium pro.
+
+Tue Aug 27 13:47:58 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * pexecute.c (pexecute) [MPW]: Remove old bogus code that
+ messed with arguments that included a '/', add escape chars
+ to double quotes, remove const decl from arg that Mac
+ compilers don't seem to like.
+
+Sat Aug 17 04:44:27 1996 Geoffrey Noer <noer@cygnus.com>
+
+ * pexecute.c: Update test for win32 (&& ! cygwin32).
+ * choose-temp.c: fix WIN32 preprocessor defines
+
+Thu Aug 15 12:26:48 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Add @DASH_C_FLAG@ and @SEGMENT_FLAG({Default})@
+ to editing of default makefile rule.
+
+Sun Aug 11 21:03:27 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * alloca-norm.h: Include <malloc.h> if _WIN32.
+ * argv.c: Include non-prototyped decls for malloc and string
+ functions if ! _WIN32 or if __GNUC__.
+
+Thu Aug 8 12:42:40 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * config.h-vms: New file.
+ * makefile.vms: Use it.
+
+Wed Aug 7 17:16:12 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * getopt.c (_getopt_internal): If argc is 0, just return (before
+ we reference *argv and segfault).
+
+Mon Aug 5 01:29:08 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * Makefile.in (distclean): Add multilib.out.
+
+Thu Jul 18 17:40:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * alloca-norm.h: Change #ifdef sparc to #if defined (sparc) &&
+ defined (sun). From Andrew Gierth <ANDREWG@microlise.co.uk>.
+
+Mon Jul 1 13:40:44 1996 Ken Raeburn <raeburn@cygnus.com>
+
+ Tue May 28 15:29:03 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmsbuild.com (REQUIRD_OFILES): Add choose-temp.o and xstrdup.o.
+
+ Thu Jan 25 18:20:04 1996 Pat Rankin <rankin@eql.caltech.edu>
+
+ * vmsbuild.com: Changes to handle DEFFUNC(on_exit).
+ (do_ofiles): Allow nonexistent source file in pass 3.
+ (chk_deffunc): New routine.
+
+Tue Jun 25 19:24:43 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * pexecute.c (PEXECUTE_VERBOSE): Define.
+ (MPW pexecute): Check flags & PEXECUTE_VERBOSE instead of verbose_flag.
+
+Tue Jun 25 23:11:48 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (docdir): Removed.
+
+Tue Jun 25 23:01:07 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (oldincludedir): Removed.
+
+Tue Jun 25 22:50:07 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (datadir): Set to $(prefix)/share.
+
+Thu Jun 20 21:17:52 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cplus-dem.c (demangle_arm_pt): Reindent. Avoid endless loop by
+ checking for errors from do_type.
+
+Tue Jun 18 14:36:19 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: New file.
+ * xmalloc.c: If VMS, include <stdlib.h> and <unixlib.h> rather
+ than declaring malloc, realloc, and sbrk.
+
+Mon Jun 10 13:17:17 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * pexecute.c: New file.
+
+Wed Jun 5 16:57:45 1996 Richard Henderson <rth@tamu.edu>
+
+ * xmalloc.c: Declare sbrk.
+
+Sat May 4 05:08:45 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alloca-norm.h: Add SPARCworks cc compatible __builtin_alloca
+ declaration.
+
+Mon Apr 22 18:41:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xstrerror.c: Include <stdio.h>.
+
+Sun Apr 21 11:55:12 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (CFILES): Add atexit.c.
+
+Sun Apr 21 09:50:09 1996 Stephen L Moshier (moshier@world.std.com)
+
+ * choose-temp.c: Include sys/types.h before sys/file.h for sco3.2v5.
+
+Wed Apr 17 11:17:55 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * choose-temp.c: Don't #include sys/file.h ifdef NO_SYS_FILE_H.
+ #include <stdio.h>
+ * config/mt-vxworks5 (HDEFINES): Define NO_SYS_FILE_H.
+
+Tue Apr 16 11:27:16 1996 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (lneeded-list): If alloca.o is needed, so is xmalloc.o.
+ Reverts Feb 8, 1995 change.
+
+Mon Apr 15 12:53:26 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * choose-temp.c: New file.
+ * Makefile.in (CFILES): Add choose-temp.c.
+ (REQUIRED_OFILES): Add choose-temp.o.
+
+Sat Apr 13 14:19:30 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * floatformat.c (floatformat_to_double): Don't bias exponent when
+ handling zero's, denorms or NaNs.
+
+Thu Apr 11 13:36:56 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * floatformat.c (floatformat_to_double): Fix bugs with handling
+ numbers with fractions < 32 bits.
+
+Mon Apr 8 14:48:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.table: Permit --enable-shared to specify a list of
+ directories.
+
+Tue Mar 19 22:02:07 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (demangle_template): Fix for non-mangled pointer
+ arguments.
+
+Fri Mar 8 17:24:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: If srcdir is `.' and with_target_subdir is not
+ `.', then set MULTISRCTOP before calling config-ml.in.
+
+Thu Mar 7 13:37:10 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.c (mpw_open): Add debugging output option.
+
+Wed Mar 6 17:36:03 1996 Jason Merrill <jason@yorick.cygnus.com>
+
+ * cplus-dem.c (demangle_template): Fix for address-of-extern arguments.
+
+Tue Feb 27 12:00:50 1996 Raymond Jou <rjou@mexican.cygnus.com>
+
+ * mpw.c (mpwify_filename): Change 6 to 5 in
+ strncmp (unixname, "/tmp/", 5).
+
+Tue Feb 20 10:55:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cplus-dem.c (demangle_template): Initialize is_bool. Correctly
+ handle 0 as a pointer value parameter.
+
+Mon Feb 5 16:41:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (all): Depend upon required-list.
+ (required-list): New target.
+ (clean): Remove required-list.
+
+Wed Jan 31 10:19:41 1996 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * win32.c: Deleted.
+ * config.table (i386-*-win32): Deleted.
+ * config/mh-i386win32: Deleted.
+
+Thu Jan 18 11:34:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * cplus-dem.c (cplus_demangle_opname): Change opname parameter to
+ const char *.
+ (cplus_mangle_opname): Change return type and opname parameter to
+ const char *. Don't cast return value.
+
+Tue Jan 16 12:13:11 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.c: Include Timer.h, in order to get m68k Microseconds trap
+ definition.
+
+Wed Jan 3 13:15:04 1996 Fred Fish <fnf@cygnus.com>
+
+ * obstack.c: Update copyright to 1996.
+ (_obstack_memory_used): Define new function. Called via
+ obstack_memory_used macro.
+
+Thu Dec 28 11:39:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * xstrdup.c: New file.
+ * Makefile.in (CFILES): Add xstrdup.c.
+ (REQUIRED_OFILES): Add xstrdup.o.
+ (xstrdup.o): New target.
+
+Mon Dec 11 18:18:52 1995 Mike Stump <mrs@cygnus.com>
+
+ * atexit.c: New stub to provide atexit on systems that have
+ on_exit, like SunOS 4.1.x systems.
+ * functions.def (on_exit, atexit): Ditto.
+
+Mon Dec 11 15:42:14 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw.c (mpw_abort): Remove decl.
+ (mpw_access): Move debugging printf.
+
+Sat Dec 2 01:25:23 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.table: Consistently use ${host} rather than ${xhost} or
+ ${target}.
+ * configure.in: Don't bother to set ${xhost} before calling
+ config.table.
+
+Tue Nov 28 14:16:57 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * Makefile.in (.c.o): Use test instead of the left bracket, to
+ avoid problems with some versions of make.
+
+Tue Nov 28 11:45:17 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Fix INCDIR edit to work with Nov 14 change.
+
+Tue Nov 21 11:26:34 1995 Fred Fish <fnf@rtl.cygnus.com>
+
+ * config/mh-hpux: Remove. It was only used to define EXTRA_OFILES,
+ which was set to just alloca.o, which is now automatically marked
+ as needed by the autoconfiguration process.
+
+Tue Nov 21 14:15:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config.table: Check ${with_cross_host} rather than comparing
+ ${host} and ${target}.
+
+Thu Nov 16 14:34:42 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: If with_target_subdir is empty, set xhost to
+ ${host} rather than ${target} before calling config.table.
+
+Tue Nov 14 01:38:30 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (MULTITOP): Deleted.
+ (MULTISRCTOP, MULTIBUILDTOP): New.
+ (FLAGS_TO_PASS): Delete INCDIR.
+ (INCDIR): Add $(MULTISRCTOP).
+ (install_to_libdir): Add $(MULTISUBDIR). Call $(MULTIDO).
+ * configure.in: Delete call to cfg-ml-com.in. Call config-ml.in
+ instead of cfg-ml-pos.in.
+ (cross-compile check): Change to test for with_target_subdir.
+ (EXTRA_LINKS): Delete.
+
+Sun Nov 12 12:13:04 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Add getpagesize.c.o to needed-list.
+ * mpw.c [USE_MW_HEADERS]: Conditionalize compiling of
+ functions that are supplied by Metrowerks libraries.
+ (fstat): Clean up descriptor->pointer conversion code.
+ (InstallConsole, etc): Empty definitions, for when linking
+ with SIOUX.
+
+Sun Nov 5 19:25:27 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * Makefile.in (FLAGS_TO_PASS): Also pass PICFLAGS.
+ (.c.o): Stylistic change.
+
+Thu Nov 2 12:06:29 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * strtol.c, strtoul.c: Don't include <stdlib.h>. From
+ phdm@info.ucl.ac.be (Philippe De Muyter).
+
+Wed Nov 1 11:59:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Correct sed call.
+
+Mon Oct 30 13:03:45 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * configure.in: Clean up / simplify for native.
+
+ * configure.in: Merge in stuff from ../xiberty/configure.in.
+ * Makefile.in (CC): Add definition (so it can be overrridden
+ by ../configure).
+
+Tue Oct 24 17:57:27 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Leave strerror.c.o in standard list of functions.
+ * mpw.c (R_OK, ENOENT, EACCESS, ENOSYS): Remove.
+ (link): Remove useless definition with error return.
+ (last_microseconds, warn_if_spin_delay, record_for_spin_delay):
+ Use UnsignedWide type for microsecond counts.
+
+Thu Oct 19 10:52:07 1995 Michael Meissner <meissner@wogglebug.tiac.net>
+
+ * memcmp.c (memcmp): Argument types are const void *, not void
+ *const.
+
+ * strncasecmp.c (strncasecmp): Include ansidecl.h/stdarg.h, not
+ sys/types.h.
+ * strcasecmp.c (strcasecmp): Ditto.
+
+Tue Oct 10 11:03:24 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (BISON): Remove macro.
+
+Tue Sep 26 15:06:46 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * Makefile.in (HFILES): Add default empty definition.
+ * mpw-config.in (config.h): Only update if changed.
+ * mpw-make.in: Remove.
+ * mpw-make.sed: New file, edits Makefile.in into MPW makefile.
+ * mpw.c: Remove semi-clone of strerror code.
+ (sys_nerr, sys_errlist): Define here.
+ (Microseconds): Only define as A-line trap if m68k Mac.
+
+Wed Sep 20 12:53:32 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New synonym for distclean.
+
+Mon Aug 28 19:47:52 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * config.table: For host, generalize rs6000-ibm-aix*
+ to *-ibm-aix* so we also include powerpc.
+
+Tue Aug 22 03:18:05 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Fri Jun 16 18:35:40 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * xstrerror.c: New file.
+ * Makefile.in, vmsbuild.com: Compile it.
+
+Mon Jul 31 12:16:32 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ * config.table (i386-*-win32): New.
+
+Fri Jul 21 11:35:52 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (MULTITOP): New variable.
+ (MULTIDIRS, MULTISUBDIR, MULTIDO, MULTICLEAN): Likewise.
+ (all): Add multilib support.
+ (install_to_tooldir, *clean): Likewise.
+
+Mon Jul 10 11:47:27 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * makefile.dos (OBJS): Add hex.o. From DJ Delorie.
+
+Fri Jun 30 17:28:59 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * vmsbuild.com: create "new-lib.olb", build libiberty under that
+ name, and then make it become "liberty.olb" when done, so that an
+ incomplete build attempt never leaves behind something which looks
+ like a complete library.
+
+Thu Jun 29 00:22:02 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * config/mh-i386pe: New file for PE hosts.
+ * config.table: Understand PE hosts.
+
+Wed Jun 28 19:13:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cplus-dem.c: Update from gcc.
+
+ * argv.c, dummy.c: If __STDC__, #include "alloca-conf.h" after
+ <stddef.h>.
+ * alloca-norm.h: If __STDC__, declare alloca with its parameter.
+
+Thu Jun 22 18:57:47 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.in (ALL_CFLAGS): Define NEED_basename.
+ * mpw.c: Only test DebugPI once whenever printing debug info.
+ (mpwify_filename): If filename is /tmp/foo, change it into :_foo,
+ also fix to not write on input filename buffer.
+ (mpw_access): Use stat() instead of open(), works for directories
+ as well as files.
+
+Mon Jun 19 00:33:22 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in: Massage broken shells that require 'else true'.
+
+Sat Jun 17 23:21:58 1995 Fred Fish <fnf@cygnus.com>
+
+ * alloca-norm.h: Declare alloca as type "PTR" to match functions.def.
+ Declare __builtin_alloca in the sparc case, as argv.c did.
+ * argv.c: Replace inline version of alloca-norm.h at start of file with
+ a #include of alloca-conf.h. Precede it with an include of ansidecl.h
+ because alloca-norm.h needs to declare alloca as "PTR".
+
+Mon Jun 12 14:24:26 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * win32.c: New file.
+
+Fri Jun 9 15:16:14 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * dummy.c: #include "alloca-conf.h".
+
+Wed Jun 7 11:46:23 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (mostlyclean): Remove stamp-picdir.
+ (clean): Don't.
+
+Mon Jun 5 18:46:06 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * config.table (frags): Use toplevel pic frags.
+
+ * Makefile.in (PICFLAG): New macro.
+ (all): Depend on stamp-picdir.
+ (needed-list): Ditto.
+ (.c.o): Also build pic object.
+ (stamp-picdir): New rule.
+ (mostlyclean): Remove pic.
+ (clean): Remove stamp-picdir.
+
+Fri Mar 24 16:55:48 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * vmsbuild.com (config.h): Add `#define NEED_basename'.
+
+Tue May 23 10:12:46 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * clock.c, getopt.c, strtod.c, vsprintf.c: Change from using LGPL
+ to libio-style copyright.
+ * getpagesize.c: Remove FSF copyright.
+
+Sat May 20 12:30:23 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Added improved VMS support from Pat Rankin:
+
+ Fri Mar 17 18:40:36 1995 Pat Rankin (rankin@eql.caltech.edu)
+
+ * vmsbuild.com: new file.
+
+ * getpagesize.c (getpagesize): implement for VMS;
+ * strerror.c (strerror, strerrno, strtoerrno): add rudimentary
+ support for EVMSERR.
+
+Thu May 18 17:01:42 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * floatformat.c (floatformat_arm_ext): Define.
+
+Tue May 16 13:30:59 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * basename.c, bcmp.c, getcwd.c, insque.c, rename.c, sigsetmask.c,
+ strerror.c, strsignal.c: Remove FSF copyright.
+ * sigsetmask.c: #include <sys/types.h> - seems to be needed by ISC.
+
+Mon May 15 19:53:17 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * bcopy.c, bzero.c, memcmp.c, memcpy.c, memset.c, strchr.c,
+ strrchr.c, strstr.c, vfork.c: Remove FSF Copyright, because this
+ might contaminate libstdc++ with the LGPL. (OK'd by RMS 11 Oct 94.)
+ * strchr.c, strrchr.c: Add cast to suppress const warning.
+
+Thu May 4 14:36:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cplus-dem.c: Use const instead of CONST. Don't include
+ ansidecl.h directly.
+
+Wed Apr 19 01:30:27 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cplus-dem.c: Don't include libiberty.h. Do declare xmalloc and
+ xrealloc.
+ (-DMAIN): Don't rely on an externally-defined version number;
+ instead, require the version number to be defined as a
+ preprocessor macro. Handle the RS/6000 leading dot. Define
+ xmalloc, xrealloc and fatal. Don't strip a leading underscore
+ if we couldn't demangle the word.
+
+Tue Apr 4 13:03:51 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ (Old mpw.c change descriptions retained for informational value.)
+ * mpw.c (warning_threshold): Default to .4 sec.
+ (overflow_count, current_progress): New globals.
+ (warn_if_spin_delay): Include current progress type,
+ such as program name, in message.
+ (mpw_start_progress): Set current_progress variable from arg.
+ (mpw_end_progress): Report spin delays by power-of-two-size
+ buckets instead of constant-size buckets.
+
+ * mpw.c: Clean up formatting, types, returns, etc.
+ (ENOSYS): Define.
+ (mpw_fread, mpw_fwrite): Define.
+ (sleep): Define correctly.
+
+ * mpw.c: New code to implement cursor spinning support.
+ (umask): New function.
+ (mpw_fopen, mpw_fseek, stat, fstat): Call PROGRESS.
+
+ * mpw.c (mpw_basename, mpw_mixed_basename): New functions, find
+ basenames for MPW and MPW/Unix filenames.
+ (mpw_special_init): New function, calls Macsbug if desired.
+
+ * mpw.c: Add GPL notice.
+ (mpwify_filename): Add more transformations.
+ (mpw_fopen): Call mpwify_filename on file names.
+ (rename): Remove.
+ (chdir, getcwd): Add simple definitions.
+
+ * mpw.c: Random cleanups, remove unused code bits.
+ Added copy of strerror.c for gcc's use.
+ (stat, fstat, _stat): New versions based on Guido van Rossum code.
+
+ * mpw.c (mpw_fseek): Make it work correctly when doing SEEK_CUR.
+
+ * mpw.c (stat): Remove hack definition, get from sys/stat.h.
+ (fork, vfork, etc): Print error messages if called.
+ (getrusage, sbrk, environ, isatty, link, utime, mkdir, rmdir,
+ rename, chown): Define.
+
+ * mpw-config.in: New file, MPW version of configure.in.
+ * mpw-make.in: New file, MPW version of Makefile.in.
+ * mpw.c: New file, MPW compatibility routines.
+
+Fri Mar 24 14:10:30 1995 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * basename.c: Include config.h before checking for NEED_basename.
+
+Thu Mar 23 19:09:54 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * functions.def: Add DEFFUNC for basename.
+
+ * basename.c: Only define basename if NEED_basename.
+
+Thu Mar 16 13:36:05 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * config.table: Fix --enable-shared logic for native builds.
+
+Mon Mar 13 11:05:11 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * cplus-dem.c (demangle_template): Demangle bool literals properly.
+
+Mon Mar 6 23:57:28 1995 Stu Grossman (grossman@cygnus.com)
+
+ * strtol.c strtoul.c: Replace these with less buggy versions from
+ NetBSD. (strtoul in particular couldn't handle base 16.)
+
+Wed Mar 1 15:59:01 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * config/mt-vxworks5 (HDEFINES): Define NO_SYS_PARAM_H.
+
+ * clock.c: If NO_SYS_PARAM_H is defined, don't include
+ <sys/param.h>.
+ * getcwd.c, getpagesize.c, getruntime.c: Likewise.
+
+Fri Feb 17 15:40:55 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * getruntime.c (get_run_time): Don't assume that CLOCKS_PER_SEC is
+ a number; ANSI appears to permit any expression, including a
+ function call.
+
+ * config.table (*-*-vxworks5*): Use mt-vxworks5 when configuring
+ xiberty.
+ * config/mt-vxworks5: New file.
+
+Thu Feb 9 14:19:45 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * basename.c (basename): Change argument to be const.
+
+Wed Feb 8 18:06:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (lneeded-list): Don't worry about xmalloc.
+
+Sun Jan 15 00:40:36 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * Makefile.in (distclean): Delete xhost-mkfrag.
+
+Thu Jan 12 16:54:18 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * Makefile.in (lneeded-list): If alloca.o is needed, so is xmalloc.o.
+
+Wed Jan 11 22:39:56 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * hex.c: New file.
+ * Makefile.in (REQUIRED_OFILES, CFILES): List it.
+ (hex.o): Add dependencies.
+
+ * cplus-dem.c (demangle_prefix): For GNU style constructor and
+ destructor names, try demangling the remainder of the string.
+
+Wed Dec 28 00:49:15 1994 Ian Lance Taylor <ian@tweedledumb.cygnus.com>
+
+ * vasprintf.c (int_vasprintf): New static function.
+ (vasprintf): Use int_vasprintf. Removes assumption that va_list
+ is assignment compatible.
+
+Sat Nov 5 19:29:12 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * Makefile.in (LIBCFLAGS): New variable.
+ (FLAGS_TO_PASS): Pass it.
+ (.c.o): Use it.
+
+Thu Nov 3 19:09:47 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * getopt.c, getopt1.c: Do compile these functions under Linux,
+ since many native versions are based on glibc but are buggy.
+
+Mon Oct 24 15:16:46 1994 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * vasprintf.c: Make 'format' arg be const, to avoid a mismatch
+ with prototype in GNU libc. Support stdarg.h as well as varargs.h.
+
+Tue Oct 11 17:48:27 1994 Jason Merrill (jason@phydeaux.cygnus.com)
+
+ * Makefile.in (REQUIRED_OFILES): Add vasprintf.o.
+ * functions.def: Remove vasprintf.
+
+Wed Sep 14 17:04:55 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * xmalloc.c (first_break): New static variable.
+ (xmalloc_set_program_name): Record sbrk (0) in first_break.
+ (xmalloc): If memory allocation fails, try to report how much
+ memory was allocated by the program up to this point.
+ (xrealloc): Likewise.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * Makefile.in (ERRORS_CC): New variable, defaulted to $(CC). Use it
+ when linking dummy.
+ * config.table: Add host RISCiX Makefile frag.
+ * config/mh-riscix: New file.
+
+Thu Aug 25 17:29:44 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * Makefile.in (FLAGS_TO_PASS): Define.
+ ($(RULE1)): Use $(FLAGS_TO_PASS).
+
+Wed Aug 24 17:08:47 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * vasprintf.c: Include <string.h>.
+ (vasprintf): Add casts to void for va_arg to avoid gcc warnings.
+ * xatexit.c: Declare malloc.
+
+Fri Aug 19 15:29:12 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle_args): Fix a bug in previous patch (the
+ one below).
+
+Thu Aug 18 14:37:14 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle args): Handle ARM repeat encoding where
+ the type index is greater than 9.
+
+Wed Aug 17 16:13:49 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle_qualified): accept optional '_' between
+ qualified name. This is baecause the template name may end with
+ numeric and can mixed up with the length of next qualified name.
+
+Wed Aug 3 05:52:14 1994 D. V. Henkel-Wallace (gumby@cygnus.com)
+
+ * config/mt-sunos4: Use our standard location for cross-includes
+ and cross-libs when the target is also a "host" environment (ie no
+ newlib; includes and such don't belong to us). This is specific
+ to the Cygnus Support environment.
+
+Tue Aug 2 15:25:12 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle_template): demangle as xxx<'Q'> not
+ xxx<ch=81>.
+
+Mon Aug 1 17:02:48 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (main): flush stdout to make pipe work.
+
+Sat Jul 16 12:56:32 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * config.table (*-*-cxux7*): Recognize.
+ * floatformat.c (floatformat_m88110_ext) [HARRIS_FLOAT_FORMAT]:
+ Harris-specific float format.
+ * config/mh-cxux7: New file.
+
+Wed Jun 29 00:26:17 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * cplus-dem.c (demangle_template): Make sure that the result of
+ consume_count doesn't index beyond the end of the string.
+
+Mon Jun 20 23:54:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * cplus-dem.c (gnu_special): Handle vtable mangling of gcc-2.4.5 and
+ earlier. Improve test for new vtable mangling. Change output back
+ to `virtual table'.
+
+Mon Jun 20 11:37:30 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * obstack.c: Always compile this code, even if using the GNU
+ library. Avoids problems with relatively recent binary
+ incompatibility.
+
+Thu Jun 16 17:54:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * cplus-dem.c: Include libiberty.h.
+ (xmalloc, xrealloc, free): Don't declare.
+ (strstr): Don't declare parameters.
+ (xmalloc, xrealloc): Don't define.
+ (long_options): Add no-strip-underscores.
+ (main): Call xmalloc_set_program_name. Pass n in short options to
+ getopt_long. Handle option 'n' to not strip underscores.
+ (usage): Mention -n and --no-strip-underscores.
+
+Sun Jun 12 01:37:09 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cplus-dem.c (demangle_template): Separate consecutive >'s with a
+ space.
+ (gnu_special): Demangle template and qualified names in a vtable name.
+
+Fri May 27 12:27:52 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ From gas-2.3 and binutils-2.4 net releases:
+
+ Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * makefile.dos: [new] Makefile for dos/go32
+ * configure.bat: update for latest files
+ * msdos.c: remove some functions now in libc.a
+
+Fri May 20 18:53:32 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * cplus-dem.c (gnu_special): Recognize thunks, as well as
+ the new naming style for vtables (when -fvtable-thunks).
+
+Wed May 18 13:34:06 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (XTRAFLAGS): Don't define.
+ (.c.o, dummy.o): Don't use XTRAFLAGS.
+ ($(RULE1)): Don't pass XTRAFLAGS down in recursive call.
+
+Fri May 13 16:02:12 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * vasprintf.c: New file.
+ * Makefile.in, functions.def: Add it.
+
+Fri May 13 16:20:28 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cplus-dem.c (demangle_fund_type): Grok bool.
+
+Fri May 6 14:44:21 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * config.table: Add go32
+ * config/mh-go32: New template.
+
+Fri May 6 11:01:59 1994 D. V. Henkel-Wallace (gumby@rtl.cygnus.com)
+
+ * config.table, config/mt-sunos4: config for when sun4 is cross target.
+
+Mon Apr 11 00:54:33 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * getopt.c [not __GNU_LIBRARY__] [__GCC__] [not __STDC__]:
+ Declare strlen to return int. Don't include stddef.h.
+
+Fri Apr 1 00:38:17 1994 Jim Wilson (wilson@mole.gnu.ai.mit.edu)
+
+ * getopt.c: Delete use of IN_GCC to control whether
+ stddef.h or gstddef.h is included.
+
+Thu Apr 14 14:00:56 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle_signature): Fix a bug in template function
+ type numbering.
+
+Wed Apr 13 17:23:03 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle_signature): Fix template function with arm
+ style argument type number, Tn.
+
+Wed Apr 13 17:11:15 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cplus-dem.c (optable): Add new[] and delete[].
+
+Fri Apr 8 11:21:42 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * argv.c (buildargv): Don't produce empty argument just because
+ there is trailing whitespace.
+
+Wed Apr 6 11:42:14 1994 Kung Hsu (kung@mexican.cygnus.com)
+
+ * cplus-dem.c (demangle_template): fix 'Q' qualified name bug.
+ Handle 'p' same as 'P'.
+ * cplus-dem.c (do_type): Handle 'p' same as 'P'.
+
+Sat Mar 26 12:00:13 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * floatformat.c (get_field, put_field): Fix off by one error in
+ little endian case.
+
+Thu Mar 24 10:40:19 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * floatformat.c (floatformat_from_double): Pass unsigned char *,
+ not char *, to put_field.
+
+Fri Mar 18 12:34:33 1994 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * memmove.c: Re-wrote; placed in public domain.
+
+Wed Mar 16 10:33:07 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * cplus-dem.c (demangle_prefix): If ARM demangling, don't treat
+ __Q* as a constructor.
+
+Mon Mar 14 12:26:02 1994 Ian Lance Taylor (ian@cygnus.com)
+
+ * ieee-float.c: Removed; no longer used.
+ * Makefile.in: Changed accordingly.
+
+Mon Mar 7 12:28:17 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * floatformat.c (get_field): Removed unused local variable i.
+ (put_field): Removed unused local variable i.
+
+Sun Feb 27 21:50:11 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * floatformat.c: New file, intended to replace ieee-float.c.
+ * Makefile.in: Change accordingly.
+
+Thu Feb 24 11:51:12 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * getopt.c: Remove #ifdef GETOPT_COMPAT and #if 0 code.
+ (_getopt_initialize): New function, broken out of _getopt_internal.
+ (_getopt_internal):
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+Thu Feb 10 14:44:16 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * getopt.c [not __GNU_LIBRARY__] [__GNUC__] [not IN_GCC]:
+ Test just __STDC__, not emacs.
+
+Wed Feb 9 00:14:00 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * getopt.c [not __GNU_LIBRARY__] [__GNUC__] [not IN_GCC]
+ [emacs] [not __STDC__]: Don't include stddef.h. Don't declare strlen.
+
+Fri Dec 24 19:43:00 1993 Noah Friedman (friedman@nutrimat.gnu.ai.mit.edu)
+
+ * getopt.c (_NO_PROTO): Define before config.h is included.
+
+Mon Sep 20 15:59:03 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * getopt.c, getopt1.c [emacs || CONFIG_BROKETS]: Include
+ <config.h> only under these, else "config.h".
+
+Thu Aug 12 18:16:49 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * getopt.c, getopt1.c [HAVE_CONFIG_H]: Include
+ <config.h> instead of "config.h".
+
+Sun Feb 20 17:17:01 1994 Ian Lance Taylor (ian@lisa.cygnus.com)
+
+ * concat.c: Check ANSI_PROTOTYPES rather than __STDC__ to decide
+ whether to use prototypes or not.
+ * strerror.c (const): Never undefine; let ansidecl.h handle it.
+ * strsignal.c (const): Likewise.
+
+Thu Feb 17 13:27:35 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * xatexit.c (_xexit_cleanup): Declare as extern; don't initialize.
+ Merging common and initialized variables need not be supported by
+ ANSI C compilers.
+ (xatexit): Initialize _xexit_cleanup if not already set.
+ * xexit.c: Comment fix.
+
+Wed Feb 16 01:15:36 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * xmalloc.c: Don't declare xexit; it's declared in libiberty.h.
+ (xrealloc): If oldmem is NULL, allocate with malloc, rather than
+ assuming that realloc works correctly.
+
+Tue Feb 15 09:26:16 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * concat.c, ieee-float.c: Replace inclusion of <string.h>
+ with explicit function declarations, as recommended by Ian Taylor.
+
+Sat Feb 12 10:31:11 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * xmalloc.c (xmalloc, xrealloc): Use PTR and size_t throughout.
+ (malloc, realloc): Declare.
+
+Thu Feb 10 17:08:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * argv.c, basename.c: Include ansidecl.h and libiberty.h.
+ * concat.c, fdmatch.c, getruntime.c, spaces.c: Likewise.
+ * strerror.c, strsignal.c, xatexit.c, xexit.c: Likewise.
+ * xmalloc.c: Likewise.
+ * concat.c: Don't declare xmalloc. If __STDC__, use <stdarg.h>
+ macros, not <varargs.h> macros.
+ * spaces.c (spaces): Make return type const. Don't crash if
+ malloc returns NULL.
+ * strerror.c (struct error_info): Make name and msg fields const.
+ (error_names): Make const.
+ (strerrno): Make const.
+ (strtoerrno): Make argument const.
+ * strsignal.c (struct signal_info): Make name and msg fields
+ const.
+ (signal_names, sys_siglist): Make const.
+ (strsignal, strsigno): Make const.
+ (strtosigno): Make argument const.
+ * xatexit.c: Declare parameter types.
+ * xmalloc.c (name): Make const.
+ (xmalloc_set_program_name): Make argument const.
+ * Makefile.in (INCDIR): Define.
+ (.c.o): Use $(INCDIR).
+ (dummy.o): Likewise.
+ (argv.o, basename.o): New targets; depend on libiberty.h.
+ (concat.o, fdmatch.o, getruntime.o, spaces.o): Likewise.
+ (strerror.o, strsignal.o, xatexit.o, xexit.o): Likewise.
+ (xmalloc.o): Likewise.
+ (cplus-dem.o): New target; depend on demangle.h.
+ (getopt.o, getopt1.o): New targets; depend on getopt.h.
+ (ieee-float.o): New target; depend on ieee-float.h.
+ (obstack.o): New target; depend on obstack.h.
+
+Tue Feb 8 05:29:08 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ Handle obstack_chunk_alloc returning NULL. This allows
+ obstacks to be used by libraries, without forcing them
+ to call exit or longjmp.
+ * obstack.c (_obstack_begin, _obstack_begin_1, _obstack_newchunk):
+ If CALL_CHUNKFUN returns NULL, set alloc_failed, else clear it.
+ (_obstack_begin, _obstack_begin_1): Return 1 if successful, 0 if not.
+
+Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * concat.c, ieee-float.c: Include <string.h>.
+
+Sun Feb 6 21:28:46 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * xmalloc.c (xmalloc_set_program_name): New function.
+ (xmalloc, xrealloc): Include the name in the error message, if set.
+
+ * Replace atexit.c with xatexit.c.
+ * Makefile.in (CFILES), functions.def: Change references.
+
+Sat Feb 5 14:02:32 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * getruntime.c (get_run_time): Use getrusage or times if
+ HAVE_GETRUSAGE or HAVE_TIMES are defined.
+
+Fri Feb 4 15:49:38 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * atexit.c: New file.
+ * Makefile.in (CFILES), functions.def: Add it.
+ * xexit.c: New file.
+ * Makefile.in (CFILES, REQUIRED_OFILES): Add it.
+ * xmalloc.c (xmalloc, xrealloc): Call xexit instead of exit.
+ Change request for 0 bytes into request for 1 byte.
+
+Wed Feb 2 11:36:49 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * xmalloc.c (xmalloc, xrealloc): Print size using %lu, and cast to
+ unsigned long, to avoid warnings.
+
+Fri Jan 28 17:49:06 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * dummy.c: Don't include time.h ever; always define clock_t as
+ "unsigned long". Until gcc/fixincludes ensures that clock_t
+ exists, __STDC__ isn't a sufficient test. And if clock() doesn't
+ exist, clock_t probably doesn't either.
+
+Mon Jan 24 11:52:31 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * clock.c, getruntime.c: New files.
+ * Makefile.in: Add to file lists.
+ * functions.def (clock): Add to list.
+ * dummy.c (time.h): Add if __STDC__.
+ (clock_t): #define as "unsigned long" if not __STDC__.
+
+Tue Jan 11 11:27:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * strtod.c: Declare atof. From edler@jan.ultra.nyu.edu (Jan
+ Edler).
+
+Tue Dec 28 14:17:30 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (errors): Use CFLAGS as well as LDFLAGS when
+ linking.
+
+Fri Dec 17 12:26:07 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c (demangle_arm_pt): New function. Common code
+ for ARM template demangling.
+ * cplus-dem.c (demangle_class_name): Use demangle_arm_pt.
+ * cplus-dem.c (demangle_prefix): Likewise.
+
+Tue Nov 30 15:47:48 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cplus-dem.c (cplus_demangle_opname): Add CONST to please gcc.
+
+Sat Nov 27 11:05:50 1993 Fred Fish (fnf@cygnus.com)
+
+ Merge changes from tom@basil.icce.rug.nl (Tom R.Hageman)
+ * strerror.c, strsignal.c: As a small space optimization, don't
+ include messages when they aren't actually used.
+
+ Merge changes from takefive.co.at!joe (Josef Leherbauer)
+ * cplus-dem.c (demangle_prefix, demangle_function_name,
+ cplus_demangle_opname): Fixes for systems where cplus_marker
+ is something other than '$'.
+
+Fri Nov 26 13:51:11 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * waitpid.c: Simple-minded approcimation to waitpid
+ using vanilla wait.
+ * functions.def, Makefile.in: Update accordingly,
+
+Thu Nov 18 18:01:15 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c(demangle_template): fix bug template instantiation
+ with value of user defined type.
+
+Wed Nov 17 18:30:21 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c(cplus_demangle_opname): add the subject new function
+ to support unified search of operator in class.
+
+Wed Nov 10 09:47:22 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ gcc -Wall lint:
+ * strtoul.c (strtoul): use "(digit = *s) != '\0'" not just
+ "digit = *s" as condition in while loop.
+
+Tue Nov 9 15:52:22 1993 Mark Eichin (eichin@cygnus.com)
+
+ * Makefile.in: pass SHELL to recursive make
+
+Thu Nov 4 12:09:26 1993 Per Bothner (bothner@kalessin.cygnus.com)
+
+ * vfprintf.c, vprintf.c, vsprintf.c: Make format arg
+ be (const char*), for ANSI (and gcc w/fixproto) consistency.
+
+Thu Nov 4 08:29:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.table: Make *-*-hiux* use mh-hpux.
+
+Fri Oct 22 07:53:15 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * config.table: Add * to end of all OS names.
+
+Tue Oct 19 17:12:01 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in (lneeded-list): ensure that object file names are
+ not duplicated, as multiple instances of the same object file in
+ a library causes problems on some machines
+
+Mon Oct 18 21:59:28 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * strcasecmp.c, strncasecmp.c: Change u_char to unsigned char.
+
+Fri Oct 15 22:17:11 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * strncasecmp.c: new file, implements strncasecmp
+ * strcasecmp.c: new file, implement strcasecmp
+
+ * Makefile.in (CFILES): list these two new source files
+
+ * functions.def: add strcasecmp and strncasecmp entries
+
+Fri Oct 15 14:53:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * strtoul.c (strtoul), strtol.c (strtol): Handle overflow
+ according to ANSI C.
+
+Thu Oct 14 16:34:19 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c: add support of ARM global constructor/destructor,
+ and 'G' for passing record or union in parameter.
+
+Wed Oct 13 13:36:19 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Fix comment to clarify that stuff in REQUIRED_OFILES
+ should not be in functions.def.
+
+Wed Oct 13 13:13:38 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * functions.def: Removed xmalloc. Stuff in REQUIRED_OFILES should
+ not be in functions.def.
+
+Mon Oct 4 18:26:39 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c: change globl constructor/destructor to proper name
+
+Tue Sep 28 18:11:07 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c: fix bug in constructor/destructor
+
+Tue Sep 28 16:20:49 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c: support both old and new _vt$... vtbl mangled names
+
+Fri Sep 24 19:07:16 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cplus-dem.c: Fix demangle_template prototype
+
+Fri Sep 24 17:32:55 1993 Kung Hsu (kung@cirdan.cygnus.com)
+
+ * cplus-dem.c: fix template demangling
+ * cplus-dem.c: fix const type demangling
+ * cplus-dem.c: fix constructor/destructor, virtual table,
+ qualifier, global constructor/destructor demangling
+
+Wed Sep 1 23:13:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * strsignal.c, strerror.c: Use fully-bracketed initializer to
+ keep gcc -Wall happy.
+
+Fri Aug 27 10:30:09 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cplus-dem.c (do_type): Add CONSTS to make gcc happy with last
+ patch.
+
+Fri Aug 27 11:24:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ Patch from Paul Flinders:
+ * cplus-dem.c (do_type): Deal with arrays.
+
+Tue Aug 24 14:23:50 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * cplus-dem.c (demangle_qualified: Deal with GNU format for more
+ than 9 classes.
+
+Wed Aug 18 19:50:29 1993 Jason Merrill (jason@deneb.cygnus.com)
+
+ * Makefile.in (dummy.o): Redirect to /dev/null to avoid "variable
+ not initialized" warnings under HP/UX
+
+Sun Aug 15 20:42:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * strerror.c: Move include of stdio.h after sys_errlist #define.
+ Also remove NULL definition (stdio.h always defines NULL, so it
+ never did anything but clutter up the code).
+
+Sat Aug 14 14:21:49 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * Makefile.in, functions.def: handle xmalloc.c
+
+ * xmalloc.c: provide xmalloc and xrealloc functions
+
+Thu Aug 12 17:38:57 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * cplus-dem.c: Fix a comment.
+
+Sat Aug 7 13:56:35 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * getopt1.c: Declare const the way getopt.c does.
+
+Fri Aug 6 17:03:13 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * obstack.c, alloca.c: Update from FSF.
+ * getopt.c, getopt1.c: Update to current FSF version, which
+ doesn't use alloca.
+
+Tue Jul 27 14:03:57 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * Makefile.in (demangle): Add the target with a message saying
+ where demangle went.
+
+Mon Jul 26 15:49:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Remove obsolete `demangle' target.
+
+Thu Jul 22 08:31:01 1993 Fred Fish (fnf@deneb.cygnus.com)
+
+ * cplus-dem.c (arm_special): Apply patch from arg@lucid.com to
+ avoid infinite loop on vtbl symbols with disambiguating "junk"
+ tacked on the end.
+
+Mon Jul 19 14:10:37 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
+
+ * strsignal.c: work around some systems losing definitions of
+ sys_siglist
+
+ * config/mh-lynxos: this system has a losing definition of
+ sys_siglist
+
+ * config.table: use mh-lynxos for *-*-lynxos
+
+Mon Jul 19 17:08:52 1993 Ken Raeburn (raeburn@rtl.cygnus.com)
+
+ * config.table: Add support for HPPA BSD hosts.
+
+ * config/mh-hpbsd: New file.
+
+Mon Jul 12 18:00:40 1993 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in (TAGS): make work when srcdir != objdir.
+
+Sun Jun 27 15:35:31 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * cplus-dem.c (main): Add long options, including --help and
+ --version.
+ (usage): New function from code in main.
+
+Tue Jun 22 11:37:38 1993 Per Bothner (bothner@deneb.cygnus.com)
+
+ * config.table: New shell scipt, sourced by both ./configure,in
+ and ../xiberty/configure.in, to avoid maintainance lossages.
+ * configure.in and ../xiberty/configure.in: Use config.table.
+
+ * configure.in: Don't use mh-aix for AIX 3.2, only for 3.1.
+ * configure.in: Map *-*-irix* (except irix4) to mh-sysv.
+ * ../xiberty/configure.in: Update from ./configure.in.
+
+Tue Jun 15 17:05:31 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: remove parentdir support
+
+Wed May 26 12:59:09 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * cplus-dem.c (xrealloc): Match definition with prototype.
+
+Tue May 25 14:27:51 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * cplus-dem.c (demangle_prefix): Demangle cfront
+ local variables as an extension to ARM demangling.
+
+Fri May 21 09:53:57 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * ieee-float.c: Don't require pointers to double to be aligned.
+
+Tue May 18 17:12:10 1993 Fred Fish (fnf@cygnus.com)
+
+ (merge changes from dlong@cse.ucsc.edu)
+ * cplus-dem.c (consume_count): Simplify.
+ * cplus-dem.c (arm_pt, demangle_class_name): New functions.
+ * cplus-dem.c (various): Calls to arm_pt, demangle_class_name.
+
+ * cplus-dem.c (xmalloc, xrealloc, strstr): Make extern decls into
+ full prototypes.
+ * cplus-dem.c (free): Add prototype.
+ * cplus-dem.c (optable): Fully bracketize initializer.
+
+Fri May 14 17:13:05 1993 Per Bothner (bothner@cygnus.com)
+
+ * cplus-dem.c: Whether initial underscores are stripped
+ depends on the external variable prepends_underscore
+ (which is generated by the binutils Makefile).
+
+Fri May 14 07:32:20 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * cplus-dem.c (mop_up, arm_special): Remove some unused variables.
+
+Tue May 4 20:31:59 1993 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (consume_count): Return zero if arg does not
+ start with digit, and don't consume any input.
+
+Tue May 4 08:10:28 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (demangle): Use ${srcdir} not $^.
+
+ * strtod.c: New file, needed at least for BSD 4.3.
+
+Sun May 2 11:30:42 1993 Fred Fish (fnf@cygnus.com)
+
+ * strsignal.c (sys_siglist): For ANSI compilations, type is
+ "const char *const". Also remove conditionalization on __STDC__
+ since const is defined away for non-ANSI.
+
+Wed Apr 28 19:29:55 1993 Ken Raeburn (raeburn@deneb.cygnus.com)
+
+ * configure.in: Recognize *-*-hpux.
+ * config/mh-hpux: New file.
+
+Tue Apr 27 15:22:19 1993 Per Bothner (bothner@cygnus.com)
+
+ * tmpnam.c: Added ANSI tmpnam() function.
+ * functions.def, Makefile.in: Update accordingly.
+
+Tue Apr 27 13:38:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * cplus-dem.c (demangle_function_name): Get the demangling of
+ stop__1A right.
+
+Fri Apr 16 23:48:24 1993 Jim Kingdon (kingdon at calvin)
+
+ * cplus-dem.c: Declare strstr return type.
+
+Fri Mar 26 12:01:26 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * strsignal.c: Add some AIX signals.
+
+Thu Mar 25 15:17:23 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in (MAKEOVERRIDES): Define to be empty.
+
+Wed Mar 24 01:59:25 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: add installcheck & dvi targets
+
+Thu Mar 18 14:05:44 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * ieee-float.c: New file, moved from ../gdb (since it is
+ needed by ../opcode/m68k-dis.c).
+
+Tue Mar 2 17:47:31 1993 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c: Replace all references to cfront with ARM.
+
+Fri Feb 26 00:17:07 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cplus-dem.c: Fix main program (when compiled with -DMAIN)
+ to be more useful as a filter.
+
+Sat Feb 20 21:41:39 1993 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * Makefile.in (install_to_libdir, install_to_tooldir): Go into the
+ destination directory before running $(RANLIB), in case that
+ program tries to create a file in the current directory as part of
+ its work.
+
+Thu Feb 18 23:00:19 1993 John Gilmore (gnu@cygnus.com)
+
+ * strsignal.c (sys_siglist): Remove yet another *%^&%&$# "const"
+ because BSD 4.4 lacks one. Isn't this fun?
+
+Thu Feb 18 11:24:25 1993 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (demangle_signature): Set func_done after
+ demangling a template.
+ * cplus-dem.c (demangle_template): Fix several small bugs
+ in demangling GNU style templates.
+ * cplus-dem.c (demangle_prefix): Fix for templates in GNU
+ style constructors.
+ * cplus-dem.c (gnu_special): Fix for templates in GNU style
+ static data members.
+
+Tue Feb 16 17:28:35 1993 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (demangle_signature): Modify to include type
+ modifiers like static and const in remembered types.
+
+Thu Feb 11 22:20:47 1993 Fred Fish (fnf@cygnus.com)
+
+ * cplus-dem.c (demangled_qualified): Add new parameter that tells
+ whether to prepend or append the qualifiers.
+ * cplus-dem.c (string_prepends): Used now, remove #if 0.
+ * cplus-dem.c (demangle_signature): Call demangle_qualified
+ with prepending.
+ * cplus_dem.c (gnu_special): Recognize static data members that
+ use qualified names.
+ * cplus-dem.c (demangle_qualified): Accumulate qualifiers in a
+ temporary buffer and the prepend or append them to the result,
+ as specified by the new "append" flag.
+ * cplus-dem.c (do_type): Call demangled_qualified with
+ appending.
+
+Mon Dec 28 10:47:19 1992 Ken Raeburn (raeburn@cygnus.com)
+
+ * strsignal.c (signal_table): Now const.
+ (init_signal_tables): Variable eip now points to const.
+
+ * strerror.c (error_table): Now const.
+ (init_error_tables): Variable eip now points to const.
+
+Tue Dec 15 15:36:50 1992 Per Bothner (bothner@cygnus.com)
+
+ * memchr.c (memchr): New (ANSI standard) function.
+ * Makefile.in, functions.def: Added memchr.
+ * Makefile.in (AR_FLAGS): Use rc instad of non-standard cq.
+
+Wed Dec 2 22:49:10 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * getopt.c: remove use of USG around <alloca.h>, which never meant
+ anything anyway
+
+ * config/mh-{aix,apollo68,ncr3000,sysv,sysv4}: removed definitions
+ of USG and USGr4
+
+Thu Nov 19 03:09:33 1992 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * cplus-dem.c (demangle_fund_type): Recognize `w', a wide character;
+ it's now a type according to the ANSI X3J16 working paper; output
+ "wchar_t" for it.
+ (demangle_template): Accept `w' as an integral type.
+ (xmalloc, xrealloc): Use `char *', not `PTR'. Cast calls to their
+ counterparts malloc and realloc to `char *'.
+ (main): Exit with a 0 status.
+ * Makefile.in (demangle): Don't expect the user to define
+ DEMANGLE, instead force to be cplus-dem.c. Look in $(srcdir)/../include
+ for demangle.h. Pass it any HDEFINES or XTRAFLAGS.
+
+Wed Nov 18 18:56:20 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (AR_FLAGS): Avoid verbosity.
+ * config/mh-sysv4: Remove AR_FLAGS override, use INSTALL=cp,
+ replace USGr4 with HAVE_SYSCONF.
+ * config/mh-solaris: Remove; mh-sysv4 works now.
+ * getpagesize.c: Replace USGr4 with HAVE_SYSCONF.
+ * configure.in: Simplify host matching table, remove separate
+ solaris config file.
+
+Sun Nov 15 09:35:16 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (i[34]86-*-solaris2*): Add, use mh-sysv4.
+
+Tue Nov 3 21:27:03 1992 Brendan Kehoe (brendan@cygnus.com)
+
+ * cplus-dem.c (xmalloc, xrealloc): Add decls.
+ (remember_type): Don't cast xmalloc.
+ (string_need): Likewise; don't cast xrealloc either.
+
+Fri Oct 23 08:52:01 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in, functions.defs, rename.c: added simple
+ implementation of rename, since some binutils programs use it.
+
+Thu Oct 15 15:18:22 1992 Per Bothner (bothner@cygnus.com)
+
+ * strsignal.c: Add appropriate 'const' to sys_siglist
+ extern declaration (if __STDC__). (Needed for Linux.)
+ * strsignal.c (strsignal): Add cast to remove const-ness.
+
+Fri Oct 9 03:22:55 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (needed.awk, needed2.awk): Remove erroneous \'s
+ before "'s, diagnosed by BSD 4.4 awk.
+
+Thu Oct 8 15:25:12 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: create config.h and needed-list through $(CONFIG_H)
+ and $(NEEDED_LIST), to give some hooks for xiberty.
+
+Thu Oct 1 23:31:42 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: use cpu-vendor-triple instead of nested cases
+
+Wed Sep 30 11:26:59 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in, argv.c, basename.c, bcmp.c, bcopy.c, bzero.c,
+ concat.c, cplus-dem.c, fdmatch.c, getcwd.c, getopt.c, getopt1.c,
+ getpagesize.c, insque.c, memcmp.c, memcpy.c, memmove.c, memset.c,
+ obstack.c, sigsetmask.c, spaces.c, strchr.c, strerror.c,
+ strrchr.c, strsignal.c, strstr.c, vfork.c, vsprintf.c:
+ Convert from using GPL to LGPL.
+
+Sat Sep 26 04:01:30 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (errors): Leave dummy.o and dummy around so that
+ we can see how the needed list was generated (it's sometimes wrong).
+ (mostlyclean): Remove them.
+
+Mon Sep 21 14:50:42 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * getcwd.c: supply a default if MAXPATHLEN is not defined.
+
+ * config/mh-irix4: set EXTRA_OFILES to alloca.o, from WRS.
+
+Wed Sep 9 12:41:48 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: Use XTRAFLAGS when compiling, so that xiberty works
+ when cross-compiling.
+
+Thu Sep 3 13:29:39 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * cplus-dem.c: (demangle_prefix): reduction in strength of strstr
+ as a time optimization.
+
+ * cplus-dem.c (cplus_demangle): remove strpbrk test. Appears to
+ be more expensive than simply demangling.
+
+ * cplus-dem.c (cplus_match): new function.
+
+Tue Sep 1 15:24:04 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cplus-dem.c: #include <stdio.h>, to define NULL.
+ Define current_demangling_style.
+
+Sun Aug 30 17:58:19 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * cplus-dem.c: New file, moved from ../gdb.
+ * cplus-dem.c (set_cplus_marker_for_demangling): New exported
+ function, to avoid compiling in target-dependency for CPLUS_MARKER.
+ * cplus-dem.c (cplus_demangle): Allow demangling style option
+ to be passed as a parameter, but using the global variable
+ current_demangling_style as a default.
+ * Makefile.in: Update for cplus-dem.c
+
+Sat Aug 29 10:44:09 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.c: Merge in comment changes from FSF version. Now
+ matches the FSF version exactly.
+
+Fri Aug 28 18:39:08 1992 John Gilmore (gnu@cygnus.com)
+
+ * obstack.c (CALL_FREEFUN): Can't use ?: with void values (at
+ least on losing DECstations!); use if-then-else instead.
+
+Wed Aug 19 14:40:34 1992 Ian Lance Taylor (ian@cygnus.com)
+
+ * Makefile.in: always create installation directories.
+
+Mon Aug 10 17:33:40 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: clean up definition of CFILES, more comments
+
+Sat Aug 8 23:10:59 1992 Fred Fish (fnf@cygnus.com)
+
+ * getopt.c (my_index): Make first arg const to match strchr,
+ which it sometimes is remapped to.
+
+Sat Aug 1 13:48:50 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.c (DEFAULT_ALIGNMENT): Update to match FSF version.
+ * obstack.c (_obstack_begin): Initialize use_extra_arg.
+ * obstack.c (_obstack_begin_1): New, from FSF version.
+
+Mon Jul 20 21:07:58 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.c (CALL_CHECKFUN, CALL_FREEFUN): Use use_extra_arg and
+ extra_arg.
+ * obstack.c (_obstack_begin): Remove area_id and flags arguments
+ (previously added for mmalloc support, interface has changed).
+ Also convert flags usage to use use_extra_arg and maybe_empty_object.
+
+Fri Jul 10 00:41:53 1992 Fred Fish (fnf@cygnus.com)
+
+ * argv.c: Move expandargv inline and eliminate static variables.
+ Rewrite to always allocate in powers of two. Fix to return an
+ argv with a single null string arg if passed a null string.
+
+Fri Jul 3 20:27:29 1992 Fred Fish (fnf@cygnus.com)
+
+ * random.c, sigsetmask.c, strerror.c, strsignal.c: Remove
+ "(void)" casts from function calls where the return value is
+ ignored, in accordance with GNU coding standards.
+
+Mon Jun 29 10:54:19 1992 Fred Fish (fnf at cygnus.com)
+
+ * bcopy.c, strerror.c, strsignal.c: Lint.
+
+Thu Jun 25 09:18:41 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * getopt.c: merge changes from make.
+
+Thu Jun 25 04:43:22 1992 John Gilmore (gnu at cygnus.com)
+
+ * alloca.c: Incorporate fixes from gdb/alloca.c.
+ FIXME: Eventually move gdb's alloca configuration files here,
+ and remove gdb/alloca.c and its Makefile.in support.
+
+Tue Jun 23 21:56:30 1992 Fred Fish (fnf@cygnus.com)
+
+ * dummy.c: Define NOTHING to /*nothing*/, change return type
+ of main to int and return zero.
+ * functions.def: Supply NOTHING as the fourth arg to macros
+ that don't have an explicit arg, to satisfy picky preprocessors.
+
+Wed Jun 17 18:13:58 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Clean up *clean rules, as per standards.texi.
+
+Tue Jun 16 16:11:59 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * getopt.c, getopt1.c: merged largely gratuitous, mostly
+ whitespace diffs from other prep distributions.
+
+Mon Jun 15 12:25:46 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/mh-ncr3000 (INSTALL): Don't use /usr/ucb/install,
+ it is broken on ncr 3000's.
+
+Mon Jun 15 01:03:26 1992 John Gilmore (gnu at cygnus.com)
+
+ * sigsetmask.c: Rewrite. Old one was very confused about its
+ arguments and result. New one can't do much, but at least knows
+ what it can't do, and it's good enough for GDB's use.
+
+Sun Jun 14 15:17:40 1992 Stu Grossman (grossman at cygnus.com)
+
+ * functions.def: Use proper prototype for strtoul.
+
+Fri Jun 12 19:22:40 1992 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Add random.c.
+ * config/mh-*: Use "true" rather than "echo >/dev/null" for ranlib.
+ * configure.in: update solaris2 config.
+
+Wed Jun 10 16:31:29 1992 Fred Fish (fnf@cygnus.com)
+
+ * random.c: Add for random() and srandom().
+ * functions.def: Add random
+
+Tue Jun 9 17:27:18 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/{mh-ncr3000, mh-sysv4}: Add definition for INSTALL
+ using /usr/ucb/install.
+
+Mon Jun 1 13:20:17 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * strerror.c: Kludge to guard against a conflict with
+ possible declaration of sys_errlist in errno.h.
+
+Sun May 31 15:07:47 1992 Mark Eichin (eichin at cygnus.com)
+
+ * configure.in, config/mh-solaris: add solaris2 config support.
+
+Fri May 29 17:23:23 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * sigsetmask.c: #ifdef out sigsetmask if SIG_SETMASK
+ is not defined (should be defined in signal.h, says Posix.).
+
+Mon May 18 17:35:04 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * getopt.c: merged changes from make-3.62.11.
+
+Fri May 8 14:53:07 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * getopt.c: merged changes from bison-1.18.
+
+Tue May 5 11:51:40 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Don't have $(EXTRA_OFILES) depend on config.h,
+ since that introduces a circular dependency.
+ ($(EXTRA_OFILES) are used to build config.h.)
+
+ * strtoul.c: Fixes to handle non-decimal bases better.
+
+Wed Apr 22 09:27:51 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/mh-ncr3000: Replace MINUS_G with CFLAGS.
+ * Makefile.dos: Finish MINUS_G eradication.
+ * Makefile.in (CFILES): Add strsignal.c.
+ * Makefile.in (REQUIRED_OFILES): Add strerror.o strsignal.o
+ * Makefile.in (needed-list): Split creation of errors file to
+ separate make target.
+ * Makefile.in (config.h, needed2.awk, errors): New targets.
+ * Makefile.in (clean): Split to multiple lines, add needed2.awk
+ and config.h.
+ * dummy.c (DEFFUNC, DEFVAR): Add defines and undefs.
+ * functions.def (strerror): Remove from optional list.
+ * functions.def (sys_nerr, sys_errlist, sys_siglist): DEFVAR's
+ * functions.def (strerror, psignal): DEFFUNC's
+ * strerror.c: Rewrite from scratch to use sys_errlist only if
+ available, add errno_max(), add strerrno(), add strtoerrno(),
+ add test driver.
+ * strsignal.c: New file, signal equivalent to strerror.c.
+ Uses sys_siglist if available, defines signo_max(), strsignal(),
+ strsigno(), strtosigno(), psignal(), and test driver.
+
+Mon Apr 20 20:49:32 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in: do not print recursion line.
+
+ * Makefile.in: allow CFLAGS to be passed in from command line.
+ Removed MINUS_G. Default CFLAGS to -g.
+
+Mon Apr 20 12:57:46 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * config/mh-aix: New. EXTRA_OFILES lists copysign.o,
+ so libg++ users don't have to be inconvenienced by a
+ libc.a bug (libc.a needs copysign, but doesn't define it!).
+ * configure.in: Use config/mh-aix.
+ * strtoul.c: Handle '-' as required by ANSI.
+ Clean up radix handling.
+ * strstr.c: Fix buggy algorithm.
+ * Makefile.in: Change so that ${EXTRA_OFILES} is
+ appended to needed-list (which is used by libg++).
+
+Fri Apr 10 22:51:41 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in: Recognize new ncr3000 config.
+ * config/mh-ncr3000: New config file.
+
+Wed Apr 1 23:31:43 1992 John Gilmore (gnu at cygnus.com)
+
+ * argv.c, dummy.c: Lint.
+
+Tue Mar 31 18:46:44 1992 Fred Fish (fnf@cygnus.com)
+
+ * config/mh-sysv4: New config file.
+ * configure.in (host_makefile_frag): Set to config/mh-sysv4 for
+ host_os == sysv4.
+ * getpagesize.c: For SVR4, use sysconf(_SC_PAGESIZE) to get
+ pagesize.
+
+Sun Mar 29 12:26:42 1992 John Gilmore (gnu at cygnus.com)
+
+ * getopt.c: Lint.
+
+Fri Mar 27 08:32:55 1992 Fred Fish (fnf@cygnus.com)
+
+ * functions.def (alloca): Fix return type and args to avoid
+ type clash with gcc's builtin alloca.
+
+Tue Mar 24 23:33:42 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * configure.in, config/mh-irix4: irix4 support.
+
+ * Makefile.in, functions.def, alloca.c: added alloca.
+
+Tue Mar 24 17:34:46 1992 Stu Grossman (grossman at cygnus.com)
+
+ * obstack.c (CALL_FREEFUN): Make it compile on DECstations.
+
+Thu Mar 19 13:57:42 1992 Fred Fish (fnf@cygnus.com)
+
+ * argv.c: Fix various external function definitions to be
+ correct in an ANSI compilation environment.
+
+Sat Mar 14 17:28:17 1992 Fred Fish (fnf@cygnus.com)
+
+ * obstack.c: Changes to support calling mmalloc functions,
+ which take an additional argument over malloc functions.
+
+Fri Mar 6 22:01:10 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * added check target.
+
+Thu Feb 27 22:19:39 1992 Per Bothner (bothner@cygnus.com)
+
+ * argv.c: #include alloca-conf.h (needed by AIX).
+
+Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com)
+
+ * Makefile.in, configure.in: removed traces of namesubdir,
+ -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced
+ copyrights to '92, changed some from Cygnus to FSF.
+
+Sat Feb 22 01:09:21 1992 Stu Grossman (grossman at cygnus.com)
+
+ * argv.c: Check in Fred's version which fixes problems with
+ alloca().
+
+Fri Feb 7 21:46:08 1992 Stu Grossman (grossman at cygnus.com)
+
+ * makefile.dos: Remove NUL to keep patch from failing.
+
+Thu Jan 30 22:48:41 1992 Stu Grossman (grossman at cygnus.com)
+
+ * getopt.c (_getopt_internal): Fix usage of enum has_arg.
+
+Mon Jan 20 18:53:23 1992 Stu Grossman (grossman at cygnus.com)
+
+ * getopt.c, getopt1.c, ../include/getopt.h: Get latest versions.
+
+Sat Jan 18 16:53:01 1992 Fred Fish (fnf at cygnus.com)
+
+ * argv.c: New file to build and destroy standard argument
+ vectors from a command string.
+
+ * Makefile.in: Add argv.c and argv.o to appropriate macros.
+
+Fri Dec 20 12:12:57 1991 Fred Fish (fnf at cygnus.com)
+
+ * configure.in: Change svr4 references to sysv4.
+
+ * rindex.c: Declare return type of externally used function
+ strrchr().
+
+Thu Dec 19 18:35:03 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Remove "***" in normal output, since Make produces
+ this on errors, and it's convenient to search for.
+
+Tue Dec 17 23:21:30 1991 Per Bothner (bothner at cygnus.com)
+
+ * memcmp.c, memcpy.c, memmove.c, memset.c, strchr.c, strrchr.c:
+ New ANSI functions. The old non-ANSI functions (such as bcopy)
+ should be avoided.
+ * bcopy.c: Fix to correctly handle overlapping regions.
+ * index.c, rindex.c: Re-write in terms of strchr() and strrchr().
+ * functions.def: Add the new functions.
+ * functions.def: Add 4th parameter to DEF macro,
+ an ansidecl.h-style prototype.
+ * dummy.c: Use expanded DEF macro to create a dummy function
+ call, with correct parameter types. (This avoids some
+ complaints from gcc about predefined builtins.)
+
+ Move the functionality of config/mh-default into Makefile.in.
+ This avoid duplication, and simplifies things slightly.
+ * Makefile.in: Tweak so we don't need config/mh-default.
+ * README: Update.
+ * configure.in: No longer need config/mh-default.
+ * config/mh-default: Deleted.
+ * config/mh-sysv: Remove lines copied from old mh-default.
+
+Tue Dec 17 05:46:46 1991 John Gilmore (gnu at cygnus.com)
+
+ * fdmatch.c (fdmatch): Don't compare st_rdev, which is for
+ 'mknod' device numbers.
+
+Mon Dec 16 12:25:34 1991 Fred Fish (fnf at cygnus.com)
+
+ * fdmatch.c, Makefile.in: Add new function that takes two
+ open file descriptors and returns nonzero if they refer to
+ the same file, zero otherwise. (used in gdb)
+
+Wed Dec 11 17:40:39 1991 Steve Chamberlain (sac at rtl.cygnus.com)
+ From DJ:
+ * msdos.c: stub functions for dos.
+ * makefile.dos, configdj.bat: new.
+ * getopt.c: Don't include alloca-conf.h in a GO32 world.
+
+
+Tue Dec 10 04:14:49 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+Fri Dec 6 23:26:45 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: remove spaces following hyphens because bsd make
+ can't cope. added standards.text support. install using
+ INSTALL_DATA.
+
+ * configure.in: remove commontargets as it is no longer a
+ recognized hook.
+
+Thu Dec 5 22:46:46 1991 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: idestdir and ddestdir go away. Added copyrights
+ and shift gpl to v2. Added ChangeLog if it didn't exist. docdir
+ and mandir now keyed off datadir by default.
+
+Fri Nov 22 19:15:29 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: find-needed.awk does not fit in 14 chars.
+
+ * Makefile.in: Suppress error checking when compiling the test
+ program, because Ultrix make/sh aborts there due to a bug.
+
+Fri Nov 22 12:23:17 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in: Re-did how EXTRA_OFILES is used to be more useful.
+ * README: Explained how the auto-configuration works,
+ and how to add new files and/or configurations.
+
+Fri Nov 22 09:45:23 1991 John Gilmore (gnu at cygnus.com)
+
+ * strtoul.c: Avoid defining ULONG_MAX if already defined;
+ cast a const char * to char * for pedants.
+
+ * getopt.c: Only define "const" after local include files get to,
+ and only if they haven't defined it.
+
+Thu Nov 21 16:58:53 1991 John Gilmore (gnu at cygnus.com)
+
+ * getcwd.c (remove getwd.c): GNU code should call getcwd(). We
+ emulate it with getwd() if available. This avoids callers having
+ to find a MAXPATHLEN or PATH_MAX value from somewhere.
+ * Makefile.in, functions.def: getwd->getcwd.
+ * configure.in: Use generic case for every system.
+ * config/mh-{delta88,mach,rs6000,svr4}: Remove.
+ * config/mh-sysv: Use default handling, just add -DUSG.
+
+Thu Nov 14 10:58:05 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, config/mh-default: Re-do make magic
+ so that for the default ("automatic") mode we only
+ compile the files we actually need. Do this using
+ a recursive make: The top-level generates the list
+ of needed files (loosely, the ones missing in libc),
+ and then passes that list to the recursive make.
+ * config/mh-mach: Remove obsolete STRERROR-{C,O} macros.
+
+Tue Nov 12 19:10:57 1991 John Gilmore (gnu at cygnus.com)
+
+ RS/6000 host support (grumble).
+
+ * configure.in: Build alloca-conf.h file from alloca-norm.h
+ (everything else) or alloca-botch.h (rs/6000).
+ * Makefile.in: Include . on the include path.
+ * getopt.c: Use alloca-conf.h.
+ * alloca-norm.h: How to declare alloca on reasonable machines.
+ * alloca-botch.h: How to declare alloca on braindead machines.
+
+Tue Nov 12 09:21:48 1991 Fred Fish (fnf at cygnus.com)
+
+ * concat.c : New file, like concat() in gdb but can take a
+ variable number of arguments rather than fixed at 3 args. For
+ now, client applications must supply an xmalloc(), which is a
+ front end function to malloc() that deals with out-of-memory
+ conditions.
+
+ * Makefile.in: Add concat.c and concat.o to appropriate macros.
+
+Sat Nov 9 13:29:59 1991 Fred Fish (fnf at cygnus.com)
+
+ * config/mh-svr4: Add sigsetmask to list of required functions.
+
+Sun Nov 3 11:57:56 1991 Per Bothner (bothner at cygnus.com)
+
+ * vsprintf.c: New file.
+ * functions.def, Makefile.in: Add vsprintf.
+
+Sun Oct 27 16:31:22 1991 John Gilmore (gnu at cygnus.com)
+
+ * configure.in, config/mh-rs6000: Add rs/6000 host support.
+ * Makefile.in: Compile with debug info.
+
+Fri Oct 25 17:01:12 1991 Per Bothner (bothner at cygnus.com)
+
+ * Makefile.in, configure.in, and new files: dummy.c, functions.def,
+ config/mf-default: Added a default configuration mode,
+ which includes into libiberty.a functions that are "missing" in libc.
+ * strdup.c, vprintf.c, vfprintf.c: New files.
+
+Thu Oct 24 02:29:26 1991 Fred Fish (fnf at cygnus.com)
+
+ * config/hmake-svr4: New file.
+
+ * config/hmake-sysv: Add HOST_CFILES and HOST_OFILES.
+
+ * basename.c, bcmp.c, bcopy.c, bzero.c, getpagesize.c getwd.c,
+ index.c, insque.c, rindex.c, spaces.c, strstr.c, vfork.c: New
+ files containing either portable C versions or emulations using
+ native library calls.
+
+ * strerror.c: Add copyright, internal documentation, etc.
+
+ * strtol.c: Replace hardwired hex constants with some more
+ portable macros. Remove illegal (according to gcc) cast.
+
+ * strtoul.c: Replace hardwired hex constant with more portable
+ macro.
+
+ * Makefile.in: Move TARGETLIB and CFLAGS where makefile fragments
+ can override them. Add new source and object file names to CFILES
+ and OFILES respectively.
+
+ * configure.in: Add support for SVR4 makefile fragments.
+
+Tue Oct 22 19:00:23 1991 Steve Chamberlain (steve at cygnus.com)
+
+ * Makefile.in: Move RANLIB, AR and AR_FLAGS to where they can be
+ over-ridden by config/hmake-*
+ * configure.in: added m88kcvs to sysv list
+
+Fri Oct 4 01:29:08 1991 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in: Most hosts need strerror, but one or two don't,
+ and they override these definitions in the host-dependent makefile
+ fragment.
+ * config/hmake-mach: The odd man out on strerror -- it's supplied.
+ * strerror.c: New file.
+
+ * strtol.c, strtoul.c: Add strtol to libiberty, since Mach lacks
+ it and bfd uses it.
+ * configure.in, Makefile.in, config/hmake-mach: Only configure
+ strtol & strotoul in on Mach.
+
+Tue Sep 3 06:36:23 1991 John Gilmore (gnu at cygint.cygnus.com)
+
+ * obstack.c: Merge with latest FSF version.
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
new file mode 100644
index 00000000000..b1689ba14fd
--- /dev/null
+++ b/libiberty/Makefile.in
@@ -0,0 +1,247 @@
+#
+# Makefile
+# Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+# Free Software Foundation
+#
+# This file is part of the libiberty library.
+# Libiberty is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# Libiberty 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with libiberty; see the file COPYING.LIB. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# This file was written by K. Richard Pixley <rich@cygnus.com>.
+
+#
+# Makefile for libiberty directory
+#
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+
+SHELL = @SHELL@
+
+# Multilib support variables.
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+AR = @AR@
+AR_FLAGS = rc
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+LIBCFLAGS = $(CFLAGS)
+RANLIB = @RANLIB@
+
+PICFLAG =
+
+MAKEOVERRIDES =
+
+TARGETLIB = libiberty.a
+
+LIBOBJS = @LIBOBJS@
+ALLOCA = @ALLOCA@
+
+# A configuration can specify extra .o files that should be included,
+# even if they are in libc. (Perhaps the libc version is buggy.)
+EXTRA_OFILES =
+
+# Flags to pass to a recursive make.
+FLAGS_TO_PASS = \
+ "AR=$(AR)" \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC=$(CC)" \
+ "CFLAGS=$(CFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "EXTRA_OFILES=$(EXTRA_OFILES)" \
+ "HDEFINES=$(HDEFINES)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LOADLIBES=$(LOADLIBES)" \
+ "RANLIB=$(RANLIB)" \
+ "SHELL=$(SHELL)"
+
+all: stamp-picdir $(TARGETLIB) needed-list required-list
+ @$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=all
+
+.PHONY: check installcheck
+check installcheck:
+
+@host_makefile_frag@
+
+INCDIR=$(srcdir)/$(MULTISRCTOP)../include
+
+COMPILE.c = $(CC) -c @DEFS@ $(LIBCFLAGS) -I. -I$(INCDIR) $(HDEFINES)
+.c.o:
+ test x"$(enable_shared)" != xyes || \
+ $(COMPILE.c) $(PICFLAG) $< -o pic/$@
+ $(COMPILE.c) $<
+
+info install-info clean-info dvi:
+
+# Include files that are in this directory.
+HFILES = alloca-conf.h
+
+# NOTE: If you add new files to the library, add them to this list
+# (alphabetical), and add them to REQUIRED_OFILES or funcs in
+# configure.in.
+CFILES = asprintf.c alloca.c argv.c atexit.c basename.c bcmp.c bcopy.c \
+ bzero.c choose-temp.c clock.c concat.c cplus-dem.c fdmatch.c \
+ fnmatch.c getcwd.c getopt.c getopt1.c getpagesize.c \
+ getruntime.c floatformat.c hex.c index.c insque.c memchr.c \
+ memcmp.c memcpy.c memmove.c memset.c mkstemps.c objalloc.c obstack.c \
+ pexecute.c random.c rename.c rindex.c sigsetmask.c spaces.c \
+ splay-tree.c strcasecmp.c strncasecmp.c strchr.c strdup.c strerror.c \
+ strrchr.c strsignal.c strstr.c strtod.c strtol.c strtoul.c \
+ tmpnam.c vasprintf.c vfork.c vfprintf.c vprintf.c vsprintf.c \
+ waitpid.c xatexit.c xexit.c xmalloc.c xstrdup.c xstrerror.c
+
+# These are always included in the library.
+REQUIRED_OFILES = argv.o choose-temp.o concat.o cplus-dem.o \
+ fdmatch.o fnmatch.o getopt.o getopt1.o getruntime.o hex.o \
+ floatformat.o objalloc.o obstack.o pexecute.o spaces.o \
+ splay-tree.o strerror.o strsignal.o xatexit.o xexit.o xmalloc.o \
+ xstrdup.o xstrerror.o
+
+$(TARGETLIB): $(REQUIRED_OFILES) $(EXTRA_OFILES) $(LIBOBJS) $(ALLOCA)
+ rm -f $(TARGETLIB)
+ $(AR) $(AR_FLAGS) $(TARGETLIB) \
+ $(REQUIRED_OFILES) $(EXTRA_OFILES) $(LIBOBJS) $(ALLOCA)
+ $(RANLIB) $(TARGETLIB)
+
+INSTALL_DEST = @INSTALL_DEST@
+install: install_to_$(INSTALL_DEST)
+
+install_to_libdir: all
+ $(INSTALL_DATA) $(TARGETLIB) $(libdir)$(MULTISUBDIR)/$(TARGETLIB).n
+ ( cd $(libdir)$(MULTISUBDIR) ; $(RANLIB) $(TARGETLIB).n )
+ mv -f $(libdir)$(MULTISUBDIR)/$(TARGETLIB).n $(libdir)$(MULTISUBDIR)/$(TARGETLIB)
+ @$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install
+
+install_to_tooldir: all
+ $(INSTALL_DATA) $(TARGETLIB) $(tooldir)/lib$(MULTISUBDIR)/$(TARGETLIB).n
+ ( cd $(tooldir)/lib$(MULTISUBDIR) ; $(RANLIB) $(TARGETLIB).n )
+ mv -f $(tooldir)/lib$(MULTISUBDIR)/$(TARGETLIB).n $(tooldir)/lib$(MULTISUBDIR)/$(TARGETLIB)
+ @$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=install
+
+# needed-list is used by libstdc++.
+needed-list: Makefile
+ f="$(LIBOBJS) $(ALLOCA) $(EXTRA_OFILES)"; \
+ case $$f in \
+ *alloca.o*) f="$$f xmalloc.o xexit.o" ;; \
+ esac; \
+ echo $$f > needed-list
+
+# required-list was used when building a shared bfd/opcodes/libiberty
+# library. I don't know if it used by anything currently.
+required-list: Makefile
+ echo $(REQUIRED_OFILES) > required-list
+
+stamp-picdir:
+ if [ x"$(enable_shared)" = xyes ] && [ ! -d pic ]; then \
+ mkdir pic; \
+ else true; fi
+ touch stamp-picdir
+
+.PHONY: all etags tags ls clean stage1 stage2
+
+etags tags: TAGS
+
+TAGS: $(CFILES) $(HFILES)
+ etags `for i in $(HFILES) $(CFILES); do echo $(srcdir)/$$i ; done`
+
+# The standalone demangler (c++filt) has been moved to binutils.
+demangle:
+ @echo "The standalone demangler, now named c++filt, is now"
+ @echo "a part of binutils."
+ @false
+
+ls:
+ @echo Makefile $(HFILES) $(CFILES)
+
+# Need to deal with profiled libraries, too.
+
+mostlyclean:
+ rm -rf *.o pic core errs \#* *.E a.out
+ rm -f needed.awk needed2.awk errors dummy needed-list config.h stamp-*
+ rm -f $(CONFIG_H) $(NEEDED_LIST) stamp-picdir
+ @$(MULTICLEAN) multi-clean DO=mostlyclean
+clean: mostlyclean
+ rm -f *.a required-list tmpmulti.out
+ @$(MULTICLEAN) multi-clean DO=clean
+distclean: clean
+ @$(MULTICLEAN) multi-clean DO=distclean
+ rm -f *~ Makefile config.status xhost-mkfrag TAGS multilib.out
+ rm -f config.log
+maintainer-clean realclean: distclean
+
+force:
+
+Makefile: $(srcdir)/Makefile.in config.status
+ CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
+
+config.h: stamp-h ; @true
+stamp-h: config.in config.status
+ CONFIG_FILES= CONFIG_HEADERS=config.h:config.in $(SHELL) ./config.status
+
+config.status: $(srcdir)/configure $(srcdir)/config.table
+ $(SHELL) ./config.status --recheck
+
+$(REQUIRED_OFILES) $(EXTRA_OFILES) $(LIBOBJS) $(ALLOCA): stamp-picdir
+
+alloca.o: config.h
+atexit.o: config.h
+argv.o: config.h alloca-conf.h $(INCDIR)/libiberty.h
+basename.o: $(INCDIR)/libiberty.h
+choose-temp.o: config.h
+clock.o: config.h
+concat.o: $(INCDIR)/libiberty.h
+cplus-dem.o: config.h $(INCDIR)/demangle.h
+fdmatch.o: $(INCDIR)/libiberty.h
+fnmatch.o: config.h $(INCDIR)/fnmatch.h
+getcwd.o: config.h
+getopt.o: config.h $(INCDIR)/getopt.h
+getopt1.o: config.h $(INCDIR)/getopt.h
+getpagesize.o: config.h
+getruntime.o: config.h $(INCDIR)/libiberty.h
+hex.o: $(INCDIR)/libiberty.h
+floatformat.o: $(INCDIR)/floatformat.h
+mkstemps.o: config.h
+objalloc.o: $(INCDIR)/objalloc.h
+obstack.o: config.h $(INCDIR)/obstack.h
+pexecute.o: config.h $(INCDIR)/libiberty.h
+spaces.o: $(INCDIR)/libiberty.h
+splay-tree.o: config.h $(INCDIR)/libiberty.h $(INCDIR)/splay-tree.h $(INCDIR)/ansidecl.h
+strerror.o: config.h $(INCDIR)/libiberty.h
+strsignal.o: config.h $(INCDIR)/libiberty.h
+xatexit.o: $(INCDIR)/libiberty.h
+xexit.o: $(INCDIR)/libiberty.h
+xmalloc.o: $(INCDIR)/libiberty.h
+xstrdup.o: config.h $(INCDIR)/libiberty.h
+xstrerror.o: config.h $(INCDIR)/libiberty.h
diff --git a/libiberty/README b/libiberty/README
new file mode 100644
index 00000000000..9f5226a6b1d
--- /dev/null
+++ b/libiberty/README
@@ -0,0 +1,65 @@
+This directory contains the -liberty library of free software.
+It is a collection of subroutines used by various GNU programs.
+Current members include:
+
+ getopt -- get options from command line
+ obstack -- stacks of arbitrarily-sized objects
+ strerror -- error message strings corresponding to errno
+ strtol -- string-to-long conversion
+ strtoul -- string-to-unsigned-long conversion
+
+We expect many of the GNU subroutines that are floating around to
+eventually arrive here.
+
+The library must be configured from the top source directory. Don't
+try to run configure in this directory. Follow the configuration
+instructions in ../README.
+
+Please report bugs and fixes to "bug-gnu-utils@prep.ai.mit.edu". Thank you.
+
+ADDING A NEW FILE
+=================
+
+There are two sets of files: Those that are "required" will be
+included in the library for all configurations, while those
+that are "optional" will be included in the library only if "needed."
+
+To add a new required file, edit Makefile to add the source file
+name to CFILES and the object file to REQUIRED_OFILES.
+
+To add a new optional file, it must provide a single function, and the
+name of the function must be the same as the name of the file.
+
+ * Add the source file name to CFILES.
+
+ * Add the function to name to the funcs shell variable in
+ configure.in.
+
+ * Add the function to the AC_CHECK_FUNCS lists just after the
+ setting of the funcs shell variable. These AC_CHECK_FUNCS calls
+ are never executed; they are there to make autoheader work
+ better.
+
+ * Consider the special cases of building libiberty; as of this
+ writing, the special cases are newlib and VxWorks. If a
+ particular special case provides the function, you do not need
+ to do anything. If it does not provide the function, add the
+ object file to LIBOBJS, and add the function name to the case
+ controlling whether to define HAVE_func.
+
+The optional file you've added (e.g. getcwd.c) should compile and work
+on all hosts where it is needed. It does not have to work or even
+compile on hosts where it is not needed.
+
+ADDING A NEW CONFIGURATION
+==========================
+
+On most hosts you should be able to use the scheme for automatically
+figuring out which files are needed. In that case, you probably
+don't need a special Makefile stub for that configuration.
+
+If the fully automatic scheme doesn't work, you may be able to get
+by with defining EXTRA_OFILES in your Makefile stub. This is
+a list of object file names that should be treated as required
+for this configuration - they will be included in libiberty.a,
+regardless of whatever might be in the C library.
diff --git a/libiberty/acconfig.h b/libiberty/acconfig.h
new file mode 100644
index 00000000000..f7c599df7ac
--- /dev/null
+++ b/libiberty/acconfig.h
@@ -0,0 +1,11 @@
+/* Define if you have the sys_errlist variable. */
+#undef HAVE_SYS_ERRLIST
+
+/* Define if you have the sys_nerr variable. */
+#undef HAVE_SYS_NERR
+
+/* Define if you have the sys_siglist variable. */
+#undef HAVE_SYS_SIGLIST
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
diff --git a/libiberty/alloca-conf.h b/libiberty/alloca-conf.h
new file mode 100644
index 00000000000..9c3eea396c1
--- /dev/null
+++ b/libiberty/alloca-conf.h
@@ -0,0 +1,24 @@
+#include "config.h"
+
+#if defined(__GNUC__) && !defined(C_ALLOCA)
+# ifndef alloca
+# define alloca __builtin_alloca
+# endif
+#else /* ! defined (__GNUC__) */
+# ifdef _AIX
+ #pragma alloca
+# else
+# if defined(HAVE_ALLOCA_H) && !defined(C_ALLOCA)
+# include <alloca.h>
+# else /* ! defined (HAVE_ALLOCA_H) */
+# ifdef __STDC__
+extern PTR alloca (size_t);
+# else /* ! defined (__STDC__) */
+extern PTR alloca ();
+# endif /* ! defined (__STDC__) */
+# endif /* ! defined (HAVE_ALLOCA_H) */
+# ifdef _WIN32
+# include <malloc.h>
+# endif
+# endif /* ! defined (_AIX) */
+#endif /* ! defined (__GNUC__) */
diff --git a/libiberty/alloca.c b/libiberty/alloca.c
new file mode 100644
index 00000000000..0f8a21511db
--- /dev/null
+++ b/libiberty/alloca.c
@@ -0,0 +1,505 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef emacs
+#include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed. Except of course if
+ the C alloca is explicitly requested. */
+#if defined (USE_C_ALLOCA) || !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Different portions of Emacs need to call different versions of
+ malloc. The Emacs executable needs alloca to call xmalloc, because
+ ordinary malloc isn't protected from input signals. On the other
+ hand, the utilities in lib-src need alloca to call malloc; some of
+ them are very simple, and don't have an xmalloc routine.
+
+ Non-Emacs programs expect this to call use xmalloc.
+
+ Callers below should use malloc. */
+
+#ifndef emacs
+#define malloc xmalloc
+#endif
+extern pointer malloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+#ifdef emacs
+ BLOCK_INPUT;
+#endif
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+
+#ifdef emacs
+ UNBLOCK_INPUT;
+#endif
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = malloc (sizeof (header) + size);
+ /* Address of header. */
+
+ if (new == 0)
+ abort();
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* not GCC version 2 */
diff --git a/libiberty/argv.c b/libiberty/argv.c
new file mode 100644
index 00000000000..85c17e930ee
--- /dev/null
+++ b/libiberty/argv.c
@@ -0,0 +1,390 @@
+/* Create and destroy argument vectors (argv's)
+ Copyright (C) 1992 Free Software Foundation, Inc.
+ Written by Fred Fish @ Cygnus Support
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* Create and destroy argument vectors. An argument vector is simply an
+ array of string pointers, terminated by a NULL pointer. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifdef isspace
+#undef isspace
+#endif
+#define isspace(ch) ((ch) == ' ' || (ch) == '\t')
+
+/* Routines imported from standard C runtime libraries. */
+
+#ifdef __STDC__
+
+#include <stddef.h>
+extern void *memcpy (void *s1, const void *s2, size_t n); /* 4.11.2.1 */
+extern size_t strlen (const char *s); /* 4.11.6.3 */
+extern void *malloc (size_t size); /* 4.10.3.3 */
+extern void *realloc (void *ptr, size_t size); /* 4.10.3.4 */
+extern void free (void *ptr); /* 4.10.3.2 */
+extern char *strdup (const char *s); /* Non-ANSI */
+
+#else /* !__STDC__ */
+
+#if !defined _WIN32 || defined __GNUC__
+extern char *memcpy (); /* Copy memory region */
+extern int strlen (); /* Count length of string */
+extern char *malloc (); /* Standard memory allocater */
+extern char *realloc (); /* Standard memory reallocator */
+extern void free (); /* Free malloc'd memory */
+extern char *strdup (); /* Duplicate a string */
+#endif
+
+#endif /* __STDC__ */
+
+#include "alloca-conf.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef EOS
+#define EOS '\0'
+#endif
+
+#define INITIAL_MAXARGC 8 /* Number of args + NULL in initial argv */
+
+
+/*
+
+NAME
+
+ dupargv -- duplicate an argument vector
+
+SYNOPSIS
+
+ char **dupargv (vector)
+ char **vector;
+
+DESCRIPTION
+
+ Duplicate an argument vector. Simply scans through the
+ vector, duplicating each argument until the
+ terminating NULL is found.
+
+RETURNS
+
+ Returns a pointer to the argument vector if
+ successful. Returns NULL if there is insufficient memory to
+ complete building the argument vector.
+
+*/
+
+char **
+dupargv (argv)
+ char **argv;
+{
+ int argc;
+ char **copy;
+
+ if (argv == NULL)
+ return NULL;
+
+ /* the vector */
+ for (argc = 0; argv[argc] != NULL; argc++);
+ copy = (char **) malloc ((argc + 1) * sizeof (char *));
+ if (copy == NULL)
+ return NULL;
+
+ /* the strings */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ {
+ int len = strlen (argv[argc]);
+ copy[argc] = malloc (sizeof (char *) * (len + 1));
+ if (copy[argc] == NULL)
+ {
+ freeargv (copy);
+ return NULL;
+ }
+ strcpy (copy[argc], argv[argc]);
+ }
+ copy[argc] = NULL;
+ return copy;
+}
+
+/*
+
+NAME
+
+ freeargv -- free an argument vector
+
+SYNOPSIS
+
+ void freeargv (vector)
+ char **vector;
+
+DESCRIPTION
+
+ Free an argument vector that was built using buildargv. Simply scans
+ through the vector, freeing the memory for each argument until the
+ terminating NULL is found, and then frees the vector itself.
+
+RETURNS
+
+ No value.
+
+*/
+
+void freeargv (vector)
+char **vector;
+{
+ register char **scan;
+
+ if (vector != NULL)
+ {
+ for (scan = vector; *scan != NULL; scan++)
+ {
+ free (*scan);
+ }
+ free (vector);
+ }
+}
+
+/*
+
+NAME
+
+ buildargv -- build an argument vector from a string
+
+SYNOPSIS
+
+ char **buildargv (sp)
+ char *sp;
+
+DESCRIPTION
+
+ Given a pointer to a string, parse the string extracting fields
+ separated by whitespace and optionally enclosed within either single
+ or double quotes (which are stripped off), and build a vector of
+ pointers to copies of the string for each field. The input string
+ remains unchanged.
+
+ All of the memory for the pointer array and copies of the string
+ is obtained from malloc. All of the memory can be returned to the
+ system with the single function call freeargv, which takes the
+ returned result of buildargv, as it's argument.
+
+ The memory for the argv array is dynamically expanded as necessary.
+
+RETURNS
+
+ Returns a pointer to the argument vector if successful. Returns NULL
+ if the input string pointer is NULL or if there is insufficient
+ memory to complete building the argument vector.
+
+NOTES
+
+ In order to provide a working buffer for extracting arguments into,
+ with appropriate stripping of quotes and translation of backslash
+ sequences, we allocate a working buffer at least as long as the input
+ string. This ensures that we always have enough space in which to
+ work, since the extracted arg is never larger than the input string.
+
+ If the input is a null string (as opposed to a NULL pointer), then
+ buildarg returns an argv that has one arg, a null string.
+
+ Argv is always kept terminated with a NULL arg pointer, so it can
+ be passed to freeargv at any time, or returned, as appropriate.
+*/
+
+char **buildargv (input)
+char *input;
+{
+ char *arg;
+ char *copybuf;
+ int squote = 0;
+ int dquote = 0;
+ int bsquote = 0;
+ int argc = 0;
+ int maxargc = 0;
+ char **argv = NULL;
+ char **nargv;
+
+ if (input != NULL)
+ {
+ copybuf = (char *) alloca (strlen (input) + 1);
+ /* Is a do{}while to always execute the loop once. Always return an
+ argv, even for null strings. See NOTES above, test case below. */
+ do
+ {
+ /* Pick off argv[argc] */
+ while (isspace (*input))
+ {
+ input++;
+ }
+ if ((maxargc == 0) || (argc >= (maxargc - 1)))
+ {
+ /* argv needs initialization, or expansion */
+ if (argv == NULL)
+ {
+ maxargc = INITIAL_MAXARGC;
+ nargv = (char **) malloc (maxargc * sizeof (char *));
+ }
+ else
+ {
+ maxargc *= 2;
+ nargv = (char **) realloc (argv, maxargc * sizeof (char *));
+ }
+ if (nargv == NULL)
+ {
+ if (argv != NULL)
+ {
+ freeargv (argv);
+ argv = NULL;
+ }
+ break;
+ }
+ argv = nargv;
+ argv[argc] = NULL;
+ }
+ /* Begin scanning arg */
+ arg = copybuf;
+ while (*input != EOS)
+ {
+ if (isspace (*input) && !squote && !dquote && !bsquote)
+ {
+ break;
+ }
+ else
+ {
+ if (bsquote)
+ {
+ bsquote = 0;
+ *arg++ = *input;
+ }
+ else if (*input == '\\')
+ {
+ bsquote = 1;
+ }
+ else if (squote)
+ {
+ if (*input == '\'')
+ {
+ squote = 0;
+ }
+ else
+ {
+ *arg++ = *input;
+ }
+ }
+ else if (dquote)
+ {
+ if (*input == '"')
+ {
+ dquote = 0;
+ }
+ else
+ {
+ *arg++ = *input;
+ }
+ }
+ else
+ {
+ if (*input == '\'')
+ {
+ squote = 1;
+ }
+ else if (*input == '"')
+ {
+ dquote = 1;
+ }
+ else
+ {
+ *arg++ = *input;
+ }
+ }
+ input++;
+ }
+ }
+ *arg = EOS;
+ argv[argc] = strdup (copybuf);
+ if (argv[argc] == NULL)
+ {
+ freeargv (argv);
+ argv = NULL;
+ break;
+ }
+ argc++;
+ argv[argc] = NULL;
+
+ while (isspace (*input))
+ {
+ input++;
+ }
+ }
+ while (*input != EOS);
+ }
+ return (argv);
+}
+
+#ifdef MAIN
+
+/* Simple little test driver. */
+
+static char *tests[] =
+{
+ "a simple command line",
+ "arg 'foo' is single quoted",
+ "arg \"bar\" is double quoted",
+ "arg \"foo bar\" has embedded whitespace",
+ "arg 'Jack said \\'hi\\'' has single quotes",
+ "arg 'Jack said \\\"hi\\\"' has double quotes",
+ "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9",
+
+ /* This should be expanded into only one argument. */
+ "trailing-whitespace ",
+
+ "",
+ NULL
+};
+
+main ()
+{
+ char **argv;
+ char **test;
+ char **targs;
+
+ for (test = tests; *test != NULL; test++)
+ {
+ printf ("buildargv(\"%s\")\n", *test);
+ if ((argv = buildargv (*test)) == NULL)
+ {
+ printf ("failed!\n\n");
+ }
+ else
+ {
+ for (targs = argv; *targs != NULL; targs++)
+ {
+ printf ("\t\"%s\"\n", *targs);
+ }
+ printf ("\n");
+ }
+ freeargv (argv);
+ }
+
+}
+
+#endif /* MAIN */
diff --git a/libiberty/asprintf.c b/libiberty/asprintf.c
new file mode 100644
index 00000000000..5aaf3200f0d
--- /dev/null
+++ b/libiberty/asprintf.c
@@ -0,0 +1,57 @@
+/* Like sprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#if defined (ANSI_PROTOTYPES) || defined (ALMOST_STDC)
+#define USE_STDARG
+#endif
+
+#ifdef USE_STDARG
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* VARARGS */
+#ifdef USE_STDARG
+int
+asprintf (char **buf, const char *fmt, ...)
+#else
+int
+asprintf (buf, fmt, va_alist)
+ char **buf;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ int status;
+ va_list ap;
+#ifdef USE_STDARG
+ va_start (ap, fmt);
+#else
+ va_start (ap);
+#endif
+ status = vasprintf (buf, fmt, ap);
+ va_end (ap);
+ return status;
+}
diff --git a/libiberty/atexit.c b/libiberty/atexit.c
new file mode 100644
index 00000000000..137d985e4cb
--- /dev/null
+++ b/libiberty/atexit.c
@@ -0,0 +1,18 @@
+/* Wrapper to implement ANSI C's atexit using SunOS's on_exit. */
+/* This function is in the public domain. --Mike Stump. */
+
+#include "config.h"
+
+#ifdef HAVE_ON_EXIT
+
+int
+atexit(f)
+ void (*f)();
+{
+ /* If the system doesn't provide a definition for atexit, use on_exit
+ if the system provides that. */
+ on_exit (f, 0);
+ return 0;
+}
+
+#endif
diff --git a/libiberty/basename.c b/libiberty/basename.c
new file mode 100644
index 00000000000..f544c853910
--- /dev/null
+++ b/libiberty/basename.c
@@ -0,0 +1,37 @@
+/* Return the basename of a pathname.
+ This file is in the public domain. */
+
+/*
+NAME
+ basename -- return pointer to last component of a pathname
+
+SYNOPSIS
+ char *basename (const char *name)
+
+DESCRIPTION
+ Given a pointer to a string containing a typical pathname
+ (/usr/src/cmd/ls/ls.c for example), returns a pointer to the
+ last component of the pathname ("ls.c" in this case).
+
+BUGS
+ Presumes a UNIX style path with UNIX style separators.
+*/
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+char *
+basename (name)
+ const char *name;
+{
+ const char *base = name;
+
+ while (*name)
+ {
+ if (*name++ == '/')
+ {
+ base = name;
+ }
+ }
+ return (char *) base;
+}
diff --git a/libiberty/bcmp.c b/libiberty/bcmp.c
new file mode 100644
index 00000000000..11e4417db15
--- /dev/null
+++ b/libiberty/bcmp.c
@@ -0,0 +1,49 @@
+/* bcmp
+ This function is in the public domain. */
+
+/*
+
+NAME
+
+ bcmp -- compare two memory regions
+
+SYNOPSIS
+
+ int bcmp (char *from, char *to, int count)
+
+DESCRIPTION
+
+ Compare two memory regions and return zero if they are identical,
+ non-zero otherwise. If count is zero, return zero.
+
+NOTES
+
+ No guarantee is made about the non-zero returned value. In
+ particular, the results may be signficantly different than
+ strcmp(), where the return value is guaranteed to be less than,
+ equal to, or greater than zero, according to lexicographical
+ sorting of the compared regions.
+
+BUGS
+
+*/
+
+
+int
+bcmp (from, to, count)
+ char *from, *to;
+ int count;
+{
+ int rtnval = 0;
+
+ while (count-- > 0)
+ {
+ if (*from++ != *to++)
+ {
+ rtnval = 1;
+ break;
+ }
+ }
+ return (rtnval);
+}
+
diff --git a/libiberty/bcopy.c b/libiberty/bcopy.c
new file mode 100644
index 00000000000..b655363d879
--- /dev/null
+++ b/libiberty/bcopy.c
@@ -0,0 +1,35 @@
+/* bcopy -- copy memory regions of arbitary length
+
+NAME
+ bcopy -- copy memory regions of arbitrary length
+
+SYNOPSIS
+ void bcopy (char *in, char *out, int length)
+
+DESCRIPTION
+ Copy LENGTH bytes from memory region pointed to by IN to memory
+ region pointed to by OUT.
+
+BUGS
+ Significant speed improvements can be made in some cases by
+ implementing copies of multiple bytes simultaneously, or unrolling
+ the copy loop.
+
+*/
+
+void
+bcopy (src, dest, len)
+ register char *src, *dest;
+ int len;
+{
+ if (dest < src)
+ while (len--)
+ *dest++ = *src++;
+ else
+ {
+ char *lasts = src + (len-1);
+ char *lastd = dest + (len-1);
+ while (len--)
+ *(char *)lastd-- = *(char *)lasts--;
+ }
+}
diff --git a/libiberty/bzero.c b/libiberty/bzero.c
new file mode 100644
index 00000000000..d01644b7f4b
--- /dev/null
+++ b/libiberty/bzero.c
@@ -0,0 +1,31 @@
+/* Portable version of bzero for systems without it.
+ This function is in the public domain. */
+
+/*
+NAME
+ bzero -- zero the contents of a specified memory region
+
+SYNOPSIS
+ void bzero (char *to, int count)
+
+DESCRIPTION
+ Zero COUNT bytes of memory pointed to by TO.
+
+BUGS
+ Significant speed enhancements may be made in some environments
+ by zeroing more than a single byte at a time, or by unrolling the
+ loop.
+
+*/
+
+
+void
+bzero (to, count)
+ char *to;
+ int count;
+{
+ while (count-- > 0)
+ {
+ *to++ = 0;
+ }
+}
diff --git a/libiberty/calloc.c b/libiberty/calloc.c
new file mode 100644
index 00000000000..c8c0a78a7a1
--- /dev/null
+++ b/libiberty/calloc.c
@@ -0,0 +1,26 @@
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+/* For systems with larger pointers than ints, this must be declared. */
+PTR malloc PARAMS ((size_t));
+
+PTR
+calloc (nelem, elsize)
+ size_t nelem, elsize;
+{
+ register PTR ptr;
+
+ if (nelem == 0 || elsize == 0)
+ nelem = elsize = 1;
+
+ ptr = malloc (nelem * elsize);
+ if (ptr) bzero (ptr, nelem * elsize);
+
+ return ptr;
+}
diff --git a/libiberty/choose-temp.c b/libiberty/choose-temp.c
new file mode 100644
index 00000000000..49c73869155
--- /dev/null
+++ b/libiberty/choose-temp.c
@@ -0,0 +1,203 @@
+/* Utility to pick a temporary filename prefix.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This file exports two functions: choose_temp_base and make_temp_file. */
+
+/* This file lives in at least two places: libiberty and gcc.
+ Don't change one without the other. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* May get P_tmpdir. */
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h> /* May get R_OK, etc. on some systems. */
+#endif
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#endif
+
+#include "libiberty.h"
+extern int mkstemps ();
+
+#ifndef IN_GCC
+#if defined (__MSDOS__) || defined (_WIN32)
+#define DIR_SEPARATOR '\\'
+#endif
+#endif
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+/* On MSDOS, write temp files in current dir
+ because there's no place else we can expect to use. */
+/* ??? Although the current directory is tried as a last resort,
+ this is left in so that on MSDOS it is preferred to /tmp on the
+ off chance that someone requires this, since that was the previous
+ behaviour. */
+#ifdef __MSDOS__
+#ifndef P_tmpdir
+#define P_tmpdir "."
+#endif
+#endif
+
+/* Name of temporary file.
+ mktemp requires 6 trailing X's. */
+#define TEMP_FILE "ccXXXXXX"
+
+/* Subroutine of choose_temp_base.
+ If BASE is non-NULL, return it.
+ Otherwise it checks if DIR is a usable directory.
+ If success, DIR is returned.
+ Otherwise NULL is returned. */
+
+static char *
+try (dir, base)
+ char *dir, *base;
+{
+ if (base != 0)
+ return base;
+ if (dir != 0
+ && access (dir, R_OK | W_OK | X_OK) == 0)
+ return dir;
+ return 0;
+}
+
+/* Return a prefix for temporary file names or NULL if unable to find one.
+ The current directory is chosen if all else fails so the program is
+ exited if a temporary directory can't be found (mktemp fails).
+ The buffer for the result is obtained with xmalloc.
+
+ This function is provided for backwards compatability only. It use
+ is not recommended. */
+
+char *
+choose_temp_base ()
+{
+ char *base = 0;
+ char *temp_filename;
+ int len;
+ static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
+ static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
+
+ base = try (getenv ("TMPDIR"), base);
+ base = try (getenv ("TMP"), base);
+ base = try (getenv ("TEMP"), base);
+
+#ifdef P_tmpdir
+ base = try (P_tmpdir, base);
+#endif
+
+ /* Try /usr/tmp, then /tmp. */
+ base = try (usrtmp, base);
+ base = try (tmp, base);
+
+ /* If all else fails, use the current directory! */
+ if (base == 0)
+ base = ".";
+
+ len = strlen (base);
+ temp_filename = xmalloc (len + 1 /*DIR_SEPARATOR*/
+ + strlen (TEMP_FILE) + 1);
+ strcpy (temp_filename, base);
+
+ if (len != 0
+ && temp_filename[len-1] != '/'
+ && temp_filename[len-1] != DIR_SEPARATOR)
+ temp_filename[len++] = DIR_SEPARATOR;
+ strcpy (temp_filename + len, TEMP_FILE);
+
+ mktemp (temp_filename);
+ if (strlen (temp_filename) == 0)
+ abort ();
+ return temp_filename;
+}
+/* Return a temporary file name (as a string) or NULL if unable to create
+ one. */
+
+char *
+make_temp_file (suffix)
+ char *suffix;
+{
+ char *base = 0;
+ char *temp_filename;
+ int base_len, suffix_len;
+ int fd;
+ static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
+ static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
+
+ base = try (getenv ("TMPDIR"), base);
+ base = try (getenv ("TMP"), base);
+ base = try (getenv ("TEMP"), base);
+
+#ifdef P_tmpdir
+ base = try (P_tmpdir, base);
+#endif
+
+ /* Try /usr/tmp, then /tmp. */
+ base = try (usrtmp, base);
+ base = try (tmp, base);
+
+ /* If all else fails, use the current directory! */
+ if (base == 0)
+ base = ".";
+
+ base_len = strlen (base);
+
+ if (suffix)
+ suffix_len = strlen (suffix);
+ else
+ suffix_len = 0;
+
+ temp_filename = xmalloc (base_len + 1 /*DIR_SEPARATOR*/
+ + strlen (TEMP_FILE)
+ + suffix_len + 1);
+ strcpy (temp_filename, base);
+
+ if (base_len != 0
+ && temp_filename[base_len-1] != '/'
+ && temp_filename[base_len-1] != DIR_SEPARATOR)
+ temp_filename[base_len++] = DIR_SEPARATOR;
+ strcpy (temp_filename + base_len, TEMP_FILE);
+
+ if (suffix)
+ strcat (temp_filename, suffix);
+
+ fd = mkstemps (temp_filename, suffix_len);
+ /* If mkstemps failed, then something bad is happening. Maybe we should
+ issue a message about a possible security attack in progress? */
+ if (fd == -1)
+ abort ();
+ /* Similarly if we can not close the file. */
+ if (close (fd))
+ abort ();
+ return temp_filename;
+}
diff --git a/libiberty/clock.c b/libiberty/clock.c
new file mode 100644
index 00000000000..db2509c17f2
--- /dev/null
+++ b/libiberty/clock.c
@@ -0,0 +1,91 @@
+/* ANSI-compatible clock function.
+ Copyright (C) 1994, 1995, 1999 Free Software Foundation, Inc.
+
+This file is part of the libiberty library. This library 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, or (at your option)
+any later version.
+
+This library 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include "config.h"
+
+#ifdef HAVE_GETRUSAGE
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_TIMES
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/times.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef _SC_CLK_TCK
+#define GNU_HZ sysconf(_SC_CLK_TCK)
+#else
+#ifdef HZ
+#define GNU_HZ HZ
+#else
+#ifdef CLOCKS_PER_SEC
+#define GNU_HZ CLOCKS_PER_SEC
+#endif
+#endif
+#endif
+
+/* FIXME: should be able to declare as clock_t. */
+
+long
+clock ()
+{
+#ifdef HAVE_GETRUSAGE
+ struct rusage rusage;
+
+ getrusage (0, &rusage);
+ return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
+ + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
+#else
+#ifdef HAVE_TIMES
+ struct tms tms;
+
+ times (&tms);
+ return (tms.tms_utime + tms.tms_stime) * (1000000 / GNU_HZ);
+#else
+#ifdef VMS
+ struct
+ {
+ int proc_user_time;
+ int proc_system_time;
+ int child_user_time;
+ int child_system_time;
+ } vms_times;
+
+ times (&vms_times);
+ return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
+#else
+ /* A fallback, if nothing else available. */
+ return 0;
+#endif /* VMS */
+#endif /* HAVE_TIMES */
+#endif /* HAVE_GETRUSAGE */
+}
+
diff --git a/libiberty/concat.c b/libiberty/concat.c
new file mode 100644
index 00000000000..5b132c85764
--- /dev/null
+++ b/libiberty/concat.c
@@ -0,0 +1,167 @@
+/* Concatenate variable number of strings.
+ Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+ Written by Fred Fish @ Cygnus Support
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/*
+
+NAME
+
+ concat -- concatenate a variable number of strings
+
+SYNOPSIS
+
+ #include <varargs.h>
+
+ char *concat (s1, s2, s3, ..., NULL)
+
+DESCRIPTION
+
+ Concatenate a variable number of strings and return the result
+ in freshly malloc'd memory.
+
+ Returns NULL if insufficient memory is available. The argument
+ list is terminated by the first NULL pointer encountered. Pointers
+ to empty strings are ignored.
+
+NOTES
+
+ This function uses xmalloc() which is expected to be a front end
+ function to malloc() that deals with low memory situations. In
+ typical use, if malloc() returns NULL then xmalloc() diverts to an
+ error handler routine which never returns, and thus xmalloc will
+ never return a NULL pointer. If the client application wishes to
+ deal with low memory situations itself, it should supply an xmalloc
+ that just directly invokes malloc and blindly returns whatever
+ malloc returns.
+*/
+
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef __STDC__
+#include <stddef.h>
+extern size_t strlen (const char *s);
+#else
+extern int strlen ();
+#endif
+
+#define NULLP (char *)0
+
+/* VARARGS */
+#ifdef ANSI_PROTOTYPES
+char *
+concat (const char *first, ...)
+#else
+char *
+concat (va_alist)
+ va_dcl
+#endif
+{
+ register int length;
+ register char *newstr;
+ register char *end;
+ register const char *arg;
+ va_list args;
+#ifndef ANSI_PROTOTYPES
+ const char *first;
+#endif
+
+ /* First compute the size of the result and get sufficient memory. */
+
+#ifdef ANSI_PROTOTYPES
+ va_start (args, first);
+#else
+ va_start (args);
+ first = va_arg (args, const char *);
+#endif
+
+ if (first == NULLP)
+ length = 0;
+ else
+ {
+ length = strlen (first);
+ while ((arg = va_arg (args, const char *)) != NULLP)
+ {
+ length += strlen (arg);
+ }
+ }
+ newstr = (char *) xmalloc (length + 1);
+ va_end (args);
+
+ /* Now copy the individual pieces to the result string. */
+
+ if (newstr != NULLP)
+ {
+#ifdef ANSI_PROTOTYPES
+ va_start (args, first);
+#else
+ va_start (args);
+ first = va_arg (args, const char *);
+#endif
+ end = newstr;
+ if (first != NULLP)
+ {
+ arg = first;
+ while (*arg)
+ {
+ *end++ = *arg++;
+ }
+ while ((arg = va_arg (args, const char *)) != NULLP)
+ {
+ while (*arg)
+ {
+ *end++ = *arg++;
+ }
+ }
+ }
+ *end = '\000';
+ va_end (args);
+ }
+
+ return (newstr);
+}
+
+#ifdef MAIN
+
+/* Simple little test driver. */
+
+#include <stdio.h>
+
+int
+main ()
+{
+ printf ("\"\" = \"%s\"\n", concat (NULLP));
+ printf ("\"a\" = \"%s\"\n", concat ("a", NULLP));
+ printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP));
+ printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP));
+ printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP));
+ printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP));
+ printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP));
+ return 0;
+}
+
+#endif
diff --git a/libiberty/config.h-vms b/libiberty/config.h-vms
new file mode 100644
index 00000000000..ccac6a2bcc7
--- /dev/null
+++ b/libiberty/config.h-vms
@@ -0,0 +1,13 @@
+#ifndef NEED_strerror
+#define NEED_strerror
+#endif
+#ifndef NEED_basename
+#define NEED_basename
+#endif
+#ifndef NEED_psignal
+#define NEED_psignal
+#endif
+#ifndef NEED_on_exit
+#define NEED_on_exit
+#endif
+
diff --git a/libiberty/config.in b/libiberty/config.in
new file mode 100644
index 00000000000..ba72d865eaf
--- /dev/null
+++ b/libiberty/config.in
@@ -0,0 +1,203 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have <vfork.h>. */
+#undef HAVE_VFORK_H
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define vfork as fork if vfork does not work. */
+#undef vfork
+
+/* Define if you have the sys_errlist variable. */
+#undef HAVE_SYS_ERRLIST
+
+/* Define if you have the sys_nerr variable. */
+#undef HAVE_SYS_NERR
+
+/* Define if you have the sys_siglist variable. */
+#undef HAVE_SYS_SIGLIST
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the asprintf function. */
+#undef HAVE_ASPRINTF
+
+/* Define if you have the atexit function. */
+#undef HAVE_ATEXIT
+
+/* Define if you have the basename function. */
+#undef HAVE_BASENAME
+
+/* Define if you have the bcmp function. */
+#undef HAVE_BCMP
+
+/* Define if you have the bcopy function. */
+#undef HAVE_BCOPY
+
+/* Define if you have the bzero function. */
+#undef HAVE_BZERO
+
+/* Define if you have the calloc function. */
+#undef HAVE_CALLOC
+
+/* Define if you have the clock function. */
+#undef HAVE_CLOCK
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getrusage function. */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the index function. */
+#undef HAVE_INDEX
+
+/* Define if you have the insque function. */
+#undef HAVE_INSQUE
+
+/* Define if you have the memchr function. */
+#undef HAVE_MEMCHR
+
+/* Define if you have the memcmp function. */
+#undef HAVE_MEMCMP
+
+/* Define if you have the memcpy function. */
+#undef HAVE_MEMCPY
+
+/* Define if you have the memmove function. */
+#undef HAVE_MEMMOVE
+
+/* Define if you have the memset function. */
+#undef HAVE_MEMSET
+
+/* Define if you have the on_exit function. */
+#undef HAVE_ON_EXIT
+
+/* Define if you have the psignal function. */
+#undef HAVE_PSIGNAL
+
+/* Define if you have the random function. */
+#undef HAVE_RANDOM
+
+/* Define if you have the rename function. */
+#undef HAVE_RENAME
+
+/* Define if you have the rindex function. */
+#undef HAVE_RINDEX
+
+/* Define if you have the sigsetmask function. */
+#undef HAVE_SIGSETMASK
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the strncasecmp function. */
+#undef HAVE_STRNCASECMP
+
+/* Define if you have the strrchr function. */
+#undef HAVE_STRRCHR
+
+/* Define if you have the strsignal function. */
+#undef HAVE_STRSIGNAL
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtod function. */
+#undef HAVE_STRTOD
+
+/* Define if you have the strtol function. */
+#undef HAVE_STRTOL
+
+/* Define if you have the strtoul function. */
+#undef HAVE_STRTOUL
+
+/* Define if you have the sysconf function. */
+#undef HAVE_SYSCONF
+
+/* Define if you have the times function. */
+#undef HAVE_TIMES
+
+/* Define if you have the tmpnam function. */
+#undef HAVE_TMPNAM
+
+/* Define if you have the vasprintf function. */
+#undef HAVE_VASPRINTF
+
+/* Define if you have the vfprintf function. */
+#undef HAVE_VFPRINTF
+
+/* Define if you have the vprintf function. */
+#undef HAVE_VPRINTF
+
+/* Define if you have the vsprintf function. */
+#undef HAVE_VSPRINTF
+
+/* Define if you have the waitpid function. */
+#undef HAVE_WAITPID
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
diff --git a/libiberty/config.table b/libiberty/config.table
new file mode 100644
index 00000000000..5913b23ad63
--- /dev/null
+++ b/libiberty/config.table
@@ -0,0 +1,60 @@
+case "${host}" in
+ rs6000-ibm-aix3.1 | rs6000-ibm-aix)
+ frag=mh-aix ;;
+ *-*-cxux7*) frag=mh-cxux7 ;;
+ *-*-freebsd2.1.*) frag=mh-fbsd21 ;;
+ *-*-freebsd2.2.[012]) frag=mh-fbsd21 ;;
+ i[345]86-*-windows*) frag=mh-windows ;;
+ *-*-beos*) frag=mh-beos ;;
+esac
+
+frags=$frag
+
+# If they didn't specify --enable-shared, don't generate shared libs.
+case "${enable_shared}" in
+ yes) shared=yes ;;
+ no) shared=no ;;
+ "") shared=no ;;
+ *) shared=yes ;;
+esac
+if [ "${shared}" = "yes" ]; then
+ case "${host}" in
+ *-*-cygwin*) ;;
+ alpha*-*-linux*) frags="${frags} ../../config/mh-elfalphapic" ;;
+ arm*-*-*) frags="${frags} ../../config/mh-armpic" ;;
+ hppa*-*-*) frags="${frags} ../../config/mh-papic" ;;
+ i[3456]86-*-*) frags="${frags} ../../config/mh-x86pic" ;;
+ powerpc*-*-aix*) ;;
+ powerpc*-*-*) frags="${frags} ../../config/mh-ppcpic" ;;
+ *-*-*) frags="${frags} ../../config/mh-${host_cpu}pic" ;;
+ esac
+fi
+
+echo "# Warning: this fragment is automatically generated" > temp-frag
+
+for frag in ${frags}; do
+ case ${frag} in
+ ../* )
+ if [ ${srcdir} = . ]; then
+ [ -n "${with_target_subdir}" ] && frag=../${frag}
+ [ -n "${with_multisrctop}" ] && frag=${with_multisrctop}${frag}
+ fi
+ ;;
+ esac
+ frag=${srcdir}/${xsrcdir}config/$frag
+ if [ -f ${frag} ]; then
+ echo "Appending ${frag} to xhost-mkfrag"
+ echo "# Following fragment copied from ${frag}" >> temp-frag
+ cat ${frag} >> temp-frag
+ fi
+done
+
+# record if we want to build shared libs.
+if [ "${shared}" = "yes" ]; then
+ echo enable_shared = yes >> temp-frag
+else
+ echo enable_shared = no >> temp-frag
+fi
+
+frag=xhost-mkfrag
+${CONFIG_SHELL} ${libiberty_topdir}/move-if-change temp-frag xhost-mkfrag
diff --git a/libiberty/config/mh-aix b/libiberty/config/mh-aix
new file mode 100644
index 00000000000..6b645058fa9
--- /dev/null
+++ b/libiberty/config/mh-aix
@@ -0,0 +1,9 @@
+# This file is only needed by AIX 3.1.
+HDEFINES = -D__IEEE_BIG_ENDIAN
+
+# Most releases of AIX 3.1 include an incorrect internal version of copysign
+# in libc.a for use by some libc public functions including modf. The public
+# version of copysign in libm.a is usable. For the sake of libg++ (which
+# uses modf), we add copysign here. Supposedly, this problem is fixed in AIX
+# 3.1.8 and above, including all releases of AIX 3.2.
+EXTRA_OFILES = copysign.o
diff --git a/libiberty/config/mh-beos b/libiberty/config/mh-beos
new file mode 100644
index 00000000000..9b75e7d3372
--- /dev/null
+++ b/libiberty/config/mh-beos
@@ -0,0 +1,7 @@
+# Host makefile fragment for BeOS
+
+# This is a temporary hack until the wimpy default 64k stack
+# limit in BeOS is either increased or made user settable somehow.
+# This probably won't happen until after the DR9 release.
+
+EXTRA_OFILES = alloca.o
diff --git a/libiberty/config/mh-cxux7 b/libiberty/config/mh-cxux7
new file mode 100644
index 00000000000..a924b0853fc
--- /dev/null
+++ b/libiberty/config/mh-cxux7
@@ -0,0 +1 @@
+HDEFINES = -DHARRIS_FLOAT_FORMAT
diff --git a/libiberty/config/mh-fbsd21 b/libiberty/config/mh-fbsd21
new file mode 100644
index 00000000000..1375a780bef
--- /dev/null
+++ b/libiberty/config/mh-fbsd21
@@ -0,0 +1 @@
+EXTRA_OFILES=vasprintf.o
diff --git a/libiberty/config/mh-windows b/libiberty/config/mh-windows
new file mode 100644
index 00000000000..3ff5f794e9f
--- /dev/null
+++ b/libiberty/config/mh-windows
@@ -0,0 +1 @@
+EXTRA_OFILES=asprintf.o strcasecmp.o strncasecmp.o vasprintf.o
diff --git a/libiberty/configure b/libiberty/configure
new file mode 100755
index 00000000000..98407e7946c
--- /dev/null
+++ b/libiberty/configure
@@ -0,0 +1,2850 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-target-subdir=SUBDIR Configuring in a subdirectory"
+ac_help="$ac_help
+ --with-cross-host=HOST Configuring with a cross compiler"
+ac_help="$ac_help
+ --with-newlib Configuring with newlib"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=pexecute.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+# Check whether --with-target-subdir or --without-target-subdir was given.
+if test "${with_target_subdir+set}" = set; then
+ withval="$with_target_subdir"
+ :
+fi
+
+# Check whether --with-cross-host or --without-cross-host was given.
+if test "${with_cross_host+set}" = set; then
+ withval="$with_cross_host"
+ :
+fi
+
+# Check whether --with-newlib or --without-newlib was given.
+if test "${with_newlib+set}" = set; then
+ withval="$with_newlib"
+ :
+fi
+
+
+if test "${srcdir}" = "."; then
+ if test -z "${with_target_subdir}"; then
+ libiberty_topdir="${srcdir}/.."
+ else
+ if test "${with_target_subdir}" != "."; then
+ libiberty_topdir="${srcdir}/${with_multisrctop}../.."
+ else
+ libiberty_topdir="${srcdir}/${with_multisrctop}.."
+ fi
+ fi
+else
+ libiberty_topdir="${srcdir}/.."
+fi
+ac_aux_dir=
+for ac_dir in $libiberty_topdir $srcdir/$libiberty_topdir; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $libiberty_topdir $srcdir/$libiberty_topdir" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:591: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:614: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:640: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:672: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:704: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+
+# FIXME: We temporarily define our own version of AC_PROG_CC. This is
+# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
+# are probably using a cross compiler, which will not be able to fully
+# link an executable. This should really be fixed in autoconf
+# itself.
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:749: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:779: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:828: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:837: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:852: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:881: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+
+
+
+
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:919: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+. ${srcdir}/config.table
+host_makefile_frag=${frag}
+
+
+# It's OK to check for header files. Although the compiler may not be
+# able to link anything, it had better be able to at least compile
+# something.
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:980: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 995 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1001: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1012 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1018: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1029 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1035: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_hdr in sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1063: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1068 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1073: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1100: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1105 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:1121: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+
+# This is the list of functions which libiberty will provide if they
+# are not available on the host.
+
+funcs="asprintf"
+funcs="$funcs atexit"
+funcs="$funcs basename"
+funcs="$funcs bcmp"
+funcs="$funcs bcopy"
+funcs="$funcs bzero"
+funcs="$funcs calloc"
+funcs="$funcs clock"
+funcs="$funcs getcwd"
+funcs="$funcs getpagesize"
+funcs="$funcs index"
+funcs="$funcs insque"
+funcs="$funcs memchr"
+funcs="$funcs memcmp"
+funcs="$funcs memcpy"
+funcs="$funcs memmove"
+funcs="$funcs memset"
+funcs="$funcs mkstemps"
+funcs="$funcs random"
+funcs="$funcs rename"
+funcs="$funcs rindex"
+funcs="$funcs sigsetmask"
+funcs="$funcs strcasecmp"
+funcs="$funcs strchr"
+funcs="$funcs strdup"
+funcs="$funcs strncasecmp"
+funcs="$funcs strrchr"
+funcs="$funcs strstr"
+funcs="$funcs strtod"
+funcs="$funcs strtol"
+funcs="$funcs strtoul"
+funcs="$funcs tmpnam"
+funcs="$funcs vasprintf"
+funcs="$funcs vfprintf"
+funcs="$funcs vprintf"
+funcs="$funcs vsprintf"
+funcs="$funcs waitpid"
+
+# Also in the old function.def file: alloca, vfork, getopt.
+
+vars="sys_errlist sys_nerr sys_siglist"
+
+checkfuncs="getrusage on_exit psignal strerror strsignal sysconf times"
+
+# These are neither executed nor required, but they help keep
+# autoheader happy without adding a bunch of text to acconfig.h.
+if test "x" = "y"; then
+ for ac_func in asprintf atexit basename bcmp bcopy bzero calloc clock getcwd
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1195: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1200 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getpagesize index insque mkstemps memchr memcmp memcpy memmove
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1250: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1255 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in memset random rename rindex sigsetmask strcasecmp
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1305: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1310 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in strchr strdup strncasecmp strrchr strstr strtod strtol
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1360: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1365 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1388: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in strtoul tmpnam vasprintf vfprintf vprintf vsprintf waitpid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1415: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1420 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_ERRLIST 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_NERR 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_SIGLIST 1
+EOF
+
+ for ac_func in getrusage on_exit psignal strerror strsignal sysconf times
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1482: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1487 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+# For each of these functions, if the host does not provide the
+# function we want to put FN.o in LIBOBJS, and if the host does
+# provide the function, we want to define HAVE_FN in config.h. Also,
+# if the host does not provide alloca, we set ALLOCA to alloca.o
+
+setobjs=
+if test -n "${with_target_subdir}"; then
+
+ # We are being configured as a target library. AC_REPLACE_FUNCS
+ # may not work correctly, because the compiler may not be able to
+ # link executables. Note that we may still be being configured
+ # native.
+
+ # If we are being configured for newlib, we know which functions
+ # newlib provide and which ones we will be expected to provide.
+
+ if test "x${with_newlib}" = "xyes"; then
+ ALLOCA="alloca.o"
+ LIBOBJS="asprintf.o basename.o insque.o random.o strdup.o vasprintf.o"
+
+ for f in $funcs; do
+ case "$f" in
+ asprintf | basename | insque | random | strdup | vasprintf)
+ ;;
+ *)
+ n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $n 1
+EOF
+
+ ;;
+ esac
+ done
+
+ # newlib doesnt provide any of the variables in $vars, so we
+ # dont have to check them here.
+
+ # Of the functions in $checkfuncs, newlib only has strerror.
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRERROR 1
+EOF
+
+
+ setobjs=yes
+
+ fi
+fi
+
+if test -z "${setobjs}"; then
+ case "${host}" in
+
+ *-*-vxworks*)
+ # Handle VxWorks configuration specially, since on VxWorks the
+ # libraries are actually on the target board, not in the file
+ # system.
+ LIBOBJS="basename.o getpagesize.o insque.o random.o strcasecmp.o"
+ LIBOBJS="$LIBOBJS strncasecmp.o strdup.o vfork.o waitpid.o vasprintf.o"
+ for f in $funcs; do
+ case "$f" in
+ basename | getpagesize | insque | random | strcasecmp)
+ ;;
+ strncasecmp | strdup | vfork | waitpid | vasprintf)
+ ;;
+ *)
+ n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $n 1
+EOF
+
+ ;;
+ esac
+ done
+
+ # VxWorks doesn't provide any of the variables in $vars, so we
+ # don't have to check them here.
+
+ # Of the functions in $checkfuncs, VxWorks only has strerror.
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRERROR 1
+EOF
+
+
+ setobjs=yes
+ ;;
+
+ esac
+fi
+
+if test -z "${setobjs}"; then
+
+ case "${host}" in
+
+ *-*-cygwin*)
+ # The Cygwin library actually uses a couple of files from
+ # libiberty when it is built. If we are building a native
+ # Cygwin, and we run the tests, we will appear to have these
+ # files. However, when we go on to build winsup, we will wind up
+ # with a library which does not have the files, since they should
+ # have come from libiberty.
+
+ # We handle this by removing the functions the winsup library
+ # provides from our shell variables, so that they appear to be
+ # missing.
+
+ funcs="`echo $funcs | sed -e 's/random//'`"
+ LIBOBJS="$LIBOBJS random.o"
+ vars="`echo $vars | sed -e 's/sys_siglist//'`"
+ checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`"
+ ;;
+
+ *-*-mingw32*)
+ # Under mingw32, sys_nerr and sys_errlist exist, but they are
+ # macros, so the test below won't find them.
+ vars="`echo $vars | sed -e 's/sys_nerr//' -e 's/sys_errlist//'`"
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_NERR 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_ERRLIST 1
+EOF
+
+ ;;
+
+ *-*-uwin*)
+ # Under some versions of uwin, vfork is notoriously buggy and the test
+ # can hang configure; on other versions, vfork exists just as a stub.
+ # FIXME: This should be removed once vfork in uwin's runtime is fixed.
+ ac_cv_func_vfork_works=no
+ ;;
+
+ esac
+
+ # We haven't set the list of objects yet. Use the standard autoconf
+ # tests. This will only work if the compiler works.
+ echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1672: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1683 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1714: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+ for ac_func in $funcs
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1721: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1726 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+ # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1778: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1783 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1790: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1811: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1816 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:1876: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1881 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1906: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1911 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1934: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:1961: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1969 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:1988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+ echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2010: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2015 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2023: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2040 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2058 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2079 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:2114: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2119 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
+echo "configure:2148: checking for vfork.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2153 "configure"
+#include "confdefs.h"
+#include <vfork.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2158: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VFORK_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for working vfork""... $ac_c" 1>&6
+echo "configure:2183: checking for working vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ echo $ac_n "checking for vfork""... $ac_c" 1>&6
+echo "configure:2189: checking for vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2194 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vfork(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vfork();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vfork) || defined (__stub___vfork)
+choke me
+#else
+vfork();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2239 "configure"
+#include "confdefs.h"
+/* Thanks to Paul Eggert for this test. */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent.
+ The compiler is told about this with #include <vfork.h>,
+ but some compilers (e.g. gcc -O) don't grok <vfork.h>.
+ Test for this by using a static variable whose address
+ is put into a register that is clobbered by the vfork. */
+static
+#ifdef __cplusplus
+sparc_address_test (int arg)
+#else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+main() {
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test ();
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems.
+ This test uses lots of local variables, at least
+ as many local variables as main has allocated so far
+ including compiler temporaries. 4 locals are enough for
+ gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
+ A buggy compiler should reuse the register of parent
+ for one of the local variables, since it will think that
+ parent can't possibly be used any more in this routine.
+ Assigning to the local variable will thus munge parent
+ in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3),
+ vfork doesn't separate parent from child file descriptors.
+ If the child closes a descriptor before it execs or exits,
+ this munges the parent's descriptor as well.
+ Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ exit(
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+EOF
+if { (eval echo configure:2334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_vfork_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_vfork_works=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
+if test $ac_cv_func_vfork_works = no; then
+ cat >> confdefs.h <<\EOF
+#define vfork fork
+EOF
+
+fi
+
+ if test $ac_cv_func_vfork_works = no; then
+ LIBOBJS="$LIBOBJS vfork.o"
+ fi
+ for v in $vars; do
+ echo $ac_n "checking for $v""... $ac_c" 1>&6
+echo "configure:2361: checking for $v" >&5
+ if eval "test \"`echo '$''{'libiberty_cv_var_$v'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2366 "configure"
+#include "confdefs.h"
+int *p;
+int main() {
+extern int $v; p = &$v;
+; return 0; }
+EOF
+if { (eval echo configure:2373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "libiberty_cv_var_$v=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "libiberty_cv_var_$v=no"
+fi
+rm -f conftest*
+fi
+
+ if eval "test \"`echo '$libiberty_cv_var_'$v`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ n=HAVE_`echo $v | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $n 1
+EOF
+
+ else
+ echo "$ac_t""no" 1>&6
+ fi
+ done
+ for ac_func in $checkfuncs
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2399: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2404 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+# Install a library built with a cross compiler in $(tooldir) rather
+# than $(libdir).
+if test -z "${with_cross_host}"; then
+ INSTALL_DEST=libdir
+else
+ INSTALL_DEST=tooldir
+fi
+
+
+# We need multilib support, but only if configuring for the target.
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+/@host_makefile_frag@/r $host_makefile_frag
+s%@host_makefile_frag@%%g
+s%@CPP@%$CPP%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@ALLOCA@%$ALLOCA%g
+s%@INSTALL_DEST@%$INSTALL_DEST%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+srcdir=${srcdir}
+host=${host}
+target=${target}
+with_target_subdir=${with_target_subdir}
+with_multisubdir=${with_multisubdir}
+ac_configure_args="--enable-multilib ${ac_configure_args}"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libiberty_topdir=${libiberty_topdir}
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+if test -n "$CONFIG_FILES"; then
+ if test -n "${with_target_subdir}"; then
+ # FIXME: We shouldn't need to set ac_file
+ ac_file=Makefile
+ . ${libiberty_topdir}/config-ml.in
+ fi
+fi
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/libiberty/configure.bat b/libiberty/configure.bat
new file mode 100644
index 00000000000..18881ac2f75
--- /dev/null
+++ b/libiberty/configure.bat
@@ -0,0 +1,14 @@
+@echo off
+if "%1" == "h8/300" goto h8300
+
+echo Configuring libiberty for go32
+copy Makefile.dos Makefile
+echo #define NEED_sys_siglist 1 >> config.h
+echo #define NEED_psignal 1 >> config.h
+goto exit
+
+:h8300
+echo Configuring libiberty for H8/300
+copy Makefile.dos Makefile
+
+:exit
diff --git a/libiberty/configure.in b/libiberty/configure.in
new file mode 100644
index 00000000000..f02f03561e5
--- /dev/null
+++ b/libiberty/configure.in
@@ -0,0 +1,341 @@
+dnl Process this file with autoconf to produce a configure script
+
+AC_PREREQ(2.12.1)
+AC_INIT(pexecute.c)
+
+dnl We use these options to decide which functions to include.
+AC_ARG_WITH(target-subdir,
+[ --with-target-subdir=SUBDIR Configuring in a subdirectory])
+AC_ARG_WITH(cross-host,
+[ --with-cross-host=HOST Configuring with a cross compiler])
+AC_ARG_WITH(newlib,
+[ --with-newlib Configuring with newlib])
+
+if test "${srcdir}" = "."; then
+ if test -z "${with_target_subdir}"; then
+ libiberty_topdir="${srcdir}/.."
+ else
+ if test "${with_target_subdir}" != "."; then
+ libiberty_topdir="${srcdir}/${with_multisrctop}../.."
+ else
+ libiberty_topdir="${srcdir}/${with_multisrctop}.."
+ fi
+ fi
+else
+ libiberty_topdir="${srcdir}/.."
+fi
+AC_CONFIG_AUX_DIR($libiberty_topdir)
+
+AC_CANONICAL_HOST
+
+dnl When we start using automake:
+dnl AM_INIT_AUTOMAKE(libiberty, 1.0)
+
+dnl These must be called before AM_PROG_LIBTOOL, because it may want
+dnl to call AC_CHECK_PROG.
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+# FIXME: We temporarily define our own version of AC_PROG_CC. This is
+# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
+# are probably using a cross compiler, which will not be able to fully
+# link an executable. This should really be fixed in autoconf
+# itself.
+
+AC_DEFUN(LIB_AC_PROG_CC,
+[AC_BEFORE([$0], [AC_PROG_CPP])dnl
+AC_PROVIDE([AC_PROG_CC])
+AC_CHECK_PROG(CC, gcc, gcc)
+if test -z "$CC"; then
+ AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
+ test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
+fi
+
+AC_PROG_CC_GNU
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+dnl Check whether -g works, even if CFLAGS is set, in case the package
+dnl plays around with CFLAGS (such as to build both debugging and
+dnl normal versions of a library), tasteless as that idea is.
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ AC_PROG_CC_G
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+])
+
+LIB_AC_PROG_CC
+
+AC_ISC_POSIX
+
+dnl When we start using libtool:
+dnl Default to a non shared library. This may be overridden by the
+dnl configure option --enable-shared.
+dnl AM_DISABLE_SHARED
+
+dnl When we start using libtool:
+dnl AM_PROG_LIBTOOL
+
+dnl When we start using automake:
+dnl AM_CONFIG_HEADER(config.h:config.in)
+AC_CONFIG_HEADER(config.h:config.in)
+
+dnl When we start using automake:
+dnl AM_MAINTAINER_MODE
+dnl AC_EXEEXT
+
+dnl When we start using automake:
+dnl AM_PROG_INSTALL
+AC_PROG_INSTALL
+
+. ${srcdir}/config.table
+host_makefile_frag=${frag}
+AC_SUBST_FILE(host_makefile_frag)
+
+# It's OK to check for header files. Although the compiler may not be
+# able to link anything, it had better be able to at least compile
+# something.
+AC_CHECK_HEADERS(sys/file.h sys/param.h stdlib.h string.h unistd.h strings.h sys/time.h)
+AC_HEADER_SYS_WAIT
+
+# This is the list of functions which libiberty will provide if they
+# are not available on the host.
+
+funcs="asprintf"
+funcs="$funcs atexit"
+funcs="$funcs basename"
+funcs="$funcs bcmp"
+funcs="$funcs bcopy"
+funcs="$funcs bzero"
+funcs="$funcs calloc"
+funcs="$funcs clock"
+funcs="$funcs getcwd"
+funcs="$funcs getpagesize"
+funcs="$funcs index"
+funcs="$funcs insque"
+funcs="$funcs memchr"
+funcs="$funcs memcmp"
+funcs="$funcs memcpy"
+funcs="$funcs memmove"
+funcs="$funcs memset"
+funcs="$funcs mkstemps"
+funcs="$funcs random"
+funcs="$funcs rename"
+funcs="$funcs rindex"
+funcs="$funcs sigsetmask"
+funcs="$funcs strcasecmp"
+funcs="$funcs strchr"
+funcs="$funcs strdup"
+funcs="$funcs strncasecmp"
+funcs="$funcs strrchr"
+funcs="$funcs strstr"
+funcs="$funcs strtod"
+funcs="$funcs strtol"
+funcs="$funcs strtoul"
+funcs="$funcs tmpnam"
+funcs="$funcs vasprintf"
+funcs="$funcs vfprintf"
+funcs="$funcs vprintf"
+funcs="$funcs vsprintf"
+funcs="$funcs waitpid"
+
+# Also in the old function.def file: alloca, vfork, getopt.
+
+vars="sys_errlist sys_nerr sys_siglist"
+
+checkfuncs="getrusage on_exit psignal strerror strsignal sysconf times"
+
+# These are neither executed nor required, but they help keep
+# autoheader happy without adding a bunch of text to acconfig.h.
+if test "x" = "y"; then
+ AC_CHECK_FUNCS(asprintf atexit basename bcmp bcopy bzero calloc clock getcwd)
+ AC_CHECK_FUNCS(getpagesize index insque mkstemps memchr memcmp memcpy memmove)
+ AC_CHECK_FUNCS(memset random rename rindex sigsetmask strcasecmp)
+ AC_CHECK_FUNCS(strchr strdup strncasecmp strrchr strstr strtod strtol)
+ AC_CHECK_FUNCS(strtoul tmpnam vasprintf vfprintf vprintf vsprintf waitpid)
+ AC_DEFINE(HAVE_SYS_ERRLIST)
+ AC_DEFINE(HAVE_SYS_NERR)
+ AC_DEFINE(HAVE_SYS_SIGLIST)
+ AC_CHECK_FUNCS(getrusage on_exit psignal strerror strsignal sysconf times)
+fi
+
+# For each of these functions, if the host does not provide the
+# function we want to put FN.o in LIBOBJS, and if the host does
+# provide the function, we want to define HAVE_FN in config.h. Also,
+# if the host does not provide alloca, we set ALLOCA to alloca.o
+
+setobjs=
+if test -n "${with_target_subdir}"; then
+
+ # We are being configured as a target library. AC_REPLACE_FUNCS
+ # may not work correctly, because the compiler may not be able to
+ # link executables. Note that we may still be being configured
+ # native.
+
+ # If we are being configured for newlib, we know which functions
+ # newlib provide and which ones we will be expected to provide.
+
+ if test "x${with_newlib}" = "xyes"; then
+ ALLOCA="alloca.o"
+ LIBOBJS="asprintf.o basename.o insque.o random.o strdup.o vasprintf.o"
+
+ for f in $funcs; do
+ case "$f" in
+ asprintf | basename | insque | random | strdup | vasprintf)
+ ;;
+ *)
+ n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ AC_DEFINE_UNQUOTED($n)
+ ;;
+ esac
+ done
+
+ # newlib doesnt provide any of the variables in $vars, so we
+ # dont have to check them here.
+
+ # Of the functions in $checkfuncs, newlib only has strerror.
+ AC_DEFINE(HAVE_STRERROR)
+
+ setobjs=yes
+
+ fi
+fi
+
+if test -z "${setobjs}"; then
+ case "${host}" in
+
+ *-*-vxworks*)
+ # Handle VxWorks configuration specially, since on VxWorks the
+ # libraries are actually on the target board, not in the file
+ # system.
+ LIBOBJS="basename.o getpagesize.o insque.o random.o strcasecmp.o"
+ LIBOBJS="$LIBOBJS strncasecmp.o strdup.o vfork.o waitpid.o vasprintf.o"
+ for f in $funcs; do
+ case "$f" in
+ basename | getpagesize | insque | random | strcasecmp)
+ ;;
+ strncasecmp | strdup | vfork | waitpid | vasprintf)
+ ;;
+ *)
+ n=HAVE_`echo $f | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ AC_DEFINE_UNQUOTED($n)
+ ;;
+ esac
+ done
+
+ # VxWorks doesn't provide any of the variables in $vars, so we
+ # don't have to check them here.
+
+ # Of the functions in $checkfuncs, VxWorks only has strerror.
+ AC_DEFINE(HAVE_STRERROR)
+
+ setobjs=yes
+ ;;
+
+ esac
+fi
+
+if test -z "${setobjs}"; then
+
+ case "${host}" in
+
+ *-*-cygwin*)
+ # The Cygwin library actually uses a couple of files from
+ # libiberty when it is built. If we are building a native
+ # Cygwin, and we run the tests, we will appear to have these
+ # files. However, when we go on to build winsup, we will wind up
+ # with a library which does not have the files, since they should
+ # have come from libiberty.
+
+ # We handle this by removing the functions the winsup library
+ # provides from our shell variables, so that they appear to be
+ # missing.
+
+ funcs="`echo $funcs | sed -e 's/random//'`"
+ LIBOBJS="$LIBOBJS random.o"
+ vars="`echo $vars | sed -e 's/sys_siglist//'`"
+ checkfuncs="`echo $checkfuncs | sed -e 's/strsignal//' -e 's/psignal//'`"
+ ;;
+
+ *-*-mingw32*)
+ # Under mingw32, sys_nerr and sys_errlist exist, but they are
+ # macros, so the test below won't find them.
+ vars="`echo $vars | sed -e 's/sys_nerr//' -e 's/sys_errlist//'`"
+ AC_DEFINE(HAVE_SYS_NERR)
+ AC_DEFINE(HAVE_SYS_ERRLIST)
+ ;;
+
+ *-*-uwin*)
+ # Under some versions of uwin, vfork is notoriously buggy and the test
+ # can hang configure; on other versions, vfork exists just as a stub.
+ # FIXME: This should be removed once vfork in uwin's runtime is fixed.
+ ac_cv_func_vfork_works=no
+ ;;
+
+ esac
+
+ # We haven't set the list of objects yet. Use the standard autoconf
+ # tests. This will only work if the compiler works.
+ AC_PROG_CC_WORKS
+ AC_REPLACE_FUNCS($funcs)
+ AC_FUNC_ALLOCA
+ AC_FUNC_VFORK
+ if test $ac_cv_func_vfork_works = no; then
+ LIBOBJS="$LIBOBJS vfork.o"
+ fi
+ for v in $vars; do
+ AC_MSG_CHECKING([for $v])
+ AC_CACHE_VAL(libiberty_cv_var_$v,
+ [AC_TRY_LINK([int *p;], [extern int $v; p = &$v;],
+ [eval "libiberty_cv_var_$v=yes"],
+ [eval "libiberty_cv_var_$v=no"])])
+ if eval "test \"`echo '$libiberty_cv_var_'$v`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ n=HAVE_`echo $v | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ AC_DEFINE_UNQUOTED($n)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ done
+ AC_CHECK_FUNCS($checkfuncs)
+fi
+
+# Install a library built with a cross compiler in $(tooldir) rather
+# than $(libdir).
+if test -z "${with_cross_host}"; then
+ INSTALL_DEST=libdir
+else
+ INSTALL_DEST=tooldir
+fi
+AC_SUBST(INSTALL_DEST)
+
+# We need multilib support, but only if configuring for the target.
+AC_OUTPUT(Makefile,
+[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+if test -n "$CONFIG_FILES"; then
+ if test -n "${with_target_subdir}"; then
+ # FIXME: We shouldn't need to set ac_file
+ ac_file=Makefile
+ . ${libiberty_topdir}/config-ml.in
+ fi
+fi],
+srcdir=${srcdir}
+host=${host}
+target=${target}
+with_target_subdir=${with_target_subdir}
+with_multisubdir=${with_multisubdir}
+ac_configure_args="--enable-multilib ${ac_configure_args}"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libiberty_topdir=${libiberty_topdir}
+)
diff --git a/libiberty/copysign.c b/libiberty/copysign.c
new file mode 100644
index 00000000000..0b5f8c3d9df
--- /dev/null
+++ b/libiberty/copysign.c
@@ -0,0 +1,140 @@
+#include <ansidecl.h>
+
+#ifdef __IEEE_BIG_ENDIAN
+
+typedef union
+{
+ double value;
+ struct
+ {
+ unsigned int sign : 1;
+ unsigned int exponent: 11;
+ unsigned int fraction0:4;
+ unsigned int fraction1:16;
+ unsigned int fraction2:16;
+ unsigned int fraction3:16;
+
+ } number;
+ struct
+ {
+ unsigned int sign : 1;
+ unsigned int exponent: 11;
+ unsigned int quiet:1;
+ unsigned int function0:3;
+ unsigned int function1:16;
+ unsigned int function2:16;
+ unsigned int function3:16;
+ } nan;
+ struct
+ {
+ unsigned long msw;
+ unsigned long lsw;
+ } parts;
+ long aslong[2];
+} __ieee_double_shape_type;
+
+#endif
+
+#ifdef __IEEE_LITTLE_ENDIAN
+
+typedef union
+{
+ double value;
+ struct
+ {
+#ifdef __SMALL_BITFIELDS
+ unsigned int fraction3:16;
+ unsigned int fraction2:16;
+ unsigned int fraction1:16;
+ unsigned int fraction0: 4;
+#else
+ unsigned int fraction1:32;
+ unsigned int fraction0:20;
+#endif
+ unsigned int exponent :11;
+ unsigned int sign : 1;
+ } number;
+ struct
+ {
+#ifdef __SMALL_BITFIELDS
+ unsigned int function3:16;
+ unsigned int function2:16;
+ unsigned int function1:16;
+ unsigned int function0:3;
+#else
+ unsigned int function1:32;
+ unsigned int function0:19;
+#endif
+ unsigned int quiet:1;
+ unsigned int exponent: 11;
+ unsigned int sign : 1;
+ } nan;
+ struct
+ {
+ unsigned long lsw;
+ unsigned long msw;
+ } parts;
+
+ long aslong[2];
+
+} __ieee_double_shape_type;
+
+#endif
+
+#ifdef __IEEE_BIG_ENDIAN
+typedef union
+{
+ float value;
+ struct
+ {
+ unsigned int sign : 1;
+ unsigned int exponent: 8;
+ unsigned int fraction0: 7;
+ unsigned int fraction1: 16;
+ } number;
+ struct
+ {
+ unsigned int sign:1;
+ unsigned int exponent:8;
+ unsigned int quiet:1;
+ unsigned int function0:6;
+ unsigned int function1:16;
+ } nan;
+ long p1;
+
+} __ieee_float_shape_type;
+#endif
+
+#ifdef __IEEE_LITTLE_ENDIAN
+typedef union
+{
+ float value;
+ struct
+ {
+ unsigned int fraction0: 7;
+ unsigned int fraction1: 16;
+ unsigned int exponent: 8;
+ unsigned int sign : 1;
+ } number;
+ struct
+ {
+ unsigned int function1:16;
+ unsigned int function0:6;
+ unsigned int quiet:1;
+ unsigned int exponent:8;
+ unsigned int sign:1;
+ } nan;
+ long p1;
+
+} __ieee_float_shape_type;
+#endif
+
+
+double DEFUN(copysign, (x, y), double x AND double y)
+{
+ __ieee_double_shape_type a,b;
+ b.value = y;
+ a.value = x;
+ a.number.sign =b.number.sign;
+ return a.value;
+}
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
new file mode 100644
index 00000000000..4be587a3bca
--- /dev/null
+++ b/libiberty/cplus-dem.c
@@ -0,0 +1,4535 @@
+/* Demangler for GNU C++
+ Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Written by James Clark (jjc@jclark.uucp)
+ Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
+ Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
+
+ This file imports xmalloc and xrealloc, which are like malloc and
+ realloc except that they generate a fatal error if there is no
+ available memory. */
+
+/* This file lives in both GCC and libiberty. When making changes, please
+ try not to break either. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#else
+char * malloc ();
+char * realloc ();
+#endif
+
+#include <demangle.h>
+#undef CURRENT_DEMANGLING_STYLE
+#define CURRENT_DEMANGLING_STYLE work->options
+
+#include "libiberty.h"
+
+static const char *mystrstr PARAMS ((const char *, const char *));
+
+static const char *
+mystrstr (s1, s2)
+ const char *s1, *s2;
+{
+ register const char *p = s1;
+ register int len = strlen (s2);
+
+ for (; (p = strchr (p, *s2)) != 0; p++)
+ {
+ if (strncmp (p, s2, len) == 0)
+ {
+ return (p);
+ }
+ }
+ return (0);
+}
+
+/* In order to allow a single demangler executable to demangle strings
+ using various common values of CPLUS_MARKER, as well as any specific
+ one set at compile time, we maintain a string containing all the
+ commonly used ones, and check to see if the marker we are looking for
+ is in that string. CPLUS_MARKER is usually '$' on systems where the
+ assembler can deal with that. Where the assembler can't, it's usually
+ '.' (but on many systems '.' is used for other things). We put the
+ current defined CPLUS_MARKER first (which defaults to '$'), followed
+ by the next most common value, followed by an explicit '$' in case
+ the value of CPLUS_MARKER is not '$'.
+
+ We could avoid this if we could just get g++ to tell us what the actual
+ cplus marker character is as part of the debug information, perhaps by
+ ensuring that it is the character that terminates the gcc<n>_compiled
+ marker symbol (FIXME). */
+
+#if !defined (CPLUS_MARKER)
+#define CPLUS_MARKER '$'
+#endif
+
+enum demangling_styles current_demangling_style = gnu_demangling;
+
+static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
+
+static char char_str[2] = { '\000', '\000' };
+
+void
+set_cplus_marker_for_demangling (ch)
+ int ch;
+{
+ cplus_markers[0] = ch;
+}
+
+typedef struct string /* Beware: these aren't required to be */
+{ /* '\0' terminated. */
+ char *b; /* pointer to start of string */
+ char *p; /* pointer after last character */
+ char *e; /* pointer after end of allocated space */
+} string;
+
+/* Stuff that is shared between sub-routines.
+ Using a shared structure allows cplus_demangle to be reentrant. */
+
+struct work_stuff
+{
+ int options;
+ char **typevec;
+ char **ktypevec;
+ char **btypevec;
+ int numk;
+ int numb;
+ int ksize;
+ int bsize;
+ int ntypes;
+ int typevec_size;
+ int constructor;
+ int destructor;
+ int static_type; /* A static member function */
+ int temp_start; /* index in demangled to start of template args */
+ int type_quals; /* The type qualifiers. */
+ int dllimported; /* Symbol imported from a PE DLL */
+ char **tmpl_argvec; /* Template function arguments. */
+ int ntmpl_args; /* The number of template function arguments. */
+ int forgetting_types; /* Nonzero if we are not remembering the types
+ we see. */
+ string* previous_argument; /* The last function argument demangled. */
+ int nrepeats; /* The number of times to repeat the previous
+ argument. */
+};
+
+#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
+#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
+
+static const struct optable
+{
+ const char *in;
+ const char *out;
+ int flags;
+} optable[] = {
+ {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
+ {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
+ {"new", " new", 0}, /* old (1.91, and 1.x) */
+ {"delete", " delete", 0}, /* old (1.91, and 1.x) */
+ {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
+ {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
+ {"as", "=", DMGL_ANSI}, /* ansi */
+ {"ne", "!=", DMGL_ANSI}, /* old, ansi */
+ {"eq", "==", DMGL_ANSI}, /* old, ansi */
+ {"ge", ">=", DMGL_ANSI}, /* old, ansi */
+ {"gt", ">", DMGL_ANSI}, /* old, ansi */
+ {"le", "<=", DMGL_ANSI}, /* old, ansi */
+ {"lt", "<", DMGL_ANSI}, /* old, ansi */
+ {"plus", "+", 0}, /* old */
+ {"pl", "+", DMGL_ANSI}, /* ansi */
+ {"apl", "+=", DMGL_ANSI}, /* ansi */
+ {"minus", "-", 0}, /* old */
+ {"mi", "-", DMGL_ANSI}, /* ansi */
+ {"ami", "-=", DMGL_ANSI}, /* ansi */
+ {"mult", "*", 0}, /* old */
+ {"ml", "*", DMGL_ANSI}, /* ansi */
+ {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
+ {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
+ {"convert", "+", 0}, /* old (unary +) */
+ {"negate", "-", 0}, /* old (unary -) */
+ {"trunc_mod", "%", 0}, /* old */
+ {"md", "%", DMGL_ANSI}, /* ansi */
+ {"amd", "%=", DMGL_ANSI}, /* ansi */
+ {"trunc_div", "/", 0}, /* old */
+ {"dv", "/", DMGL_ANSI}, /* ansi */
+ {"adv", "/=", DMGL_ANSI}, /* ansi */
+ {"truth_andif", "&&", 0}, /* old */
+ {"aa", "&&", DMGL_ANSI}, /* ansi */
+ {"truth_orif", "||", 0}, /* old */
+ {"oo", "||", DMGL_ANSI}, /* ansi */
+ {"truth_not", "!", 0}, /* old */
+ {"nt", "!", DMGL_ANSI}, /* ansi */
+ {"postincrement","++", 0}, /* old */
+ {"pp", "++", DMGL_ANSI}, /* ansi */
+ {"postdecrement","--", 0}, /* old */
+ {"mm", "--", DMGL_ANSI}, /* ansi */
+ {"bit_ior", "|", 0}, /* old */
+ {"or", "|", DMGL_ANSI}, /* ansi */
+ {"aor", "|=", DMGL_ANSI}, /* ansi */
+ {"bit_xor", "^", 0}, /* old */
+ {"er", "^", DMGL_ANSI}, /* ansi */
+ {"aer", "^=", DMGL_ANSI}, /* ansi */
+ {"bit_and", "&", 0}, /* old */
+ {"ad", "&", DMGL_ANSI}, /* ansi */
+ {"aad", "&=", DMGL_ANSI}, /* ansi */
+ {"bit_not", "~", 0}, /* old */
+ {"co", "~", DMGL_ANSI}, /* ansi */
+ {"call", "()", 0}, /* old */
+ {"cl", "()", DMGL_ANSI}, /* ansi */
+ {"alshift", "<<", 0}, /* old */
+ {"ls", "<<", DMGL_ANSI}, /* ansi */
+ {"als", "<<=", DMGL_ANSI}, /* ansi */
+ {"arshift", ">>", 0}, /* old */
+ {"rs", ">>", DMGL_ANSI}, /* ansi */
+ {"ars", ">>=", DMGL_ANSI}, /* ansi */
+ {"component", "->", 0}, /* old */
+ {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
+ {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
+ {"indirect", "*", 0}, /* old */
+ {"method_call", "->()", 0}, /* old */
+ {"addr", "&", 0}, /* old (unary &) */
+ {"array", "[]", 0}, /* old */
+ {"vc", "[]", DMGL_ANSI}, /* ansi */
+ {"compound", ", ", 0}, /* old */
+ {"cm", ", ", DMGL_ANSI}, /* ansi */
+ {"cond", "?:", 0}, /* old */
+ {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
+ {"max", ">?", 0}, /* old */
+ {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
+ {"min", "<?", 0}, /* old */
+ {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
+ {"nop", "", 0}, /* old (for operator=) */
+ {"rm", "->*", DMGL_ANSI}, /* ansi */
+ {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
+};
+
+/* These values are used to indicate the various type varieties.
+ They are all non-zero so that they can be used as `success'
+ values. */
+typedef enum type_kind_t
+{
+ tk_none,
+ tk_pointer,
+ tk_reference,
+ tk_integral,
+ tk_bool,
+ tk_char,
+ tk_real
+} type_kind_t;
+
+#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
+#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
+ string_prepend(str, " ");}
+#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
+ string_append(str, " ");}
+#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
+
+/* The scope separator appropriate for the language being demangled. */
+
+#define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
+
+#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
+#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
+
+/* Prototypes for local functions */
+
+static char *
+mop_up PARAMS ((struct work_stuff *, string *, int));
+
+static void
+squangle_mop_up PARAMS ((struct work_stuff *));
+
+#if 0
+static int
+demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
+#endif
+
+static char *
+internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
+
+static int
+demangle_template_template_parm PARAMS ((struct work_stuff *work,
+ const char **, string *));
+
+static int
+demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
+ string *, int, int));
+
+static int
+arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
+ const char **));
+
+static int
+demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
+ int, int));
+
+static int
+demangle_class PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+gnu_special PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+arm_special PARAMS ((const char **, string *));
+
+static void
+string_need PARAMS ((string *, int));
+
+static void
+string_delete PARAMS ((string *));
+
+static void
+string_init PARAMS ((string *));
+
+static void
+string_clear PARAMS ((string *));
+
+#if 0
+static int
+string_empty PARAMS ((string *));
+#endif
+
+static void
+string_append PARAMS ((string *, const char *));
+
+static void
+string_appends PARAMS ((string *, string *));
+
+static void
+string_appendn PARAMS ((string *, const char *, int));
+
+static void
+string_prepend PARAMS ((string *, const char *));
+
+static void
+string_prependn PARAMS ((string *, const char *, int));
+
+static int
+get_count PARAMS ((const char **, int *));
+
+static int
+consume_count PARAMS ((const char **));
+
+static int
+consume_count_with_underscores PARAMS ((const char**));
+
+static int
+demangle_args PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
+
+static int
+do_type PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+do_arg PARAMS ((struct work_stuff *, const char **, string *));
+
+static void
+demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
+ const char *));
+
+static void
+remember_type PARAMS ((struct work_stuff *, const char *, int));
+
+static void
+remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
+
+static int
+register_Btype PARAMS ((struct work_stuff *));
+
+static void
+remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
+
+static void
+forget_types PARAMS ((struct work_stuff *));
+
+static void
+forget_B_and_K_types PARAMS ((struct work_stuff *));
+
+static void
+string_prepends PARAMS ((string *, string *));
+
+static int
+demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
+ string*, type_kind_t));
+
+static int
+do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
+
+static int
+snarf_numeric_literal PARAMS ((const char **, string *));
+
+/* There is a TYPE_QUAL value for each type qualifier. They can be
+ combined by bitwise-or to form the complete set of qualifiers for a
+ type. */
+
+#define TYPE_UNQUALIFIED 0x0
+#define TYPE_QUAL_CONST 0x1
+#define TYPE_QUAL_VOLATILE 0x2
+#define TYPE_QUAL_RESTRICT 0x4
+
+static int
+code_for_qualifier PARAMS ((int));
+
+static const char*
+qualifier_string PARAMS ((int));
+
+static const char*
+demangle_qualifier PARAMS ((int));
+
+/* Translate count to integer, consuming tokens in the process.
+ Conversion terminates on the first non-digit character.
+
+ Trying to consume something that isn't a count results in no
+ consumption of input and a return of -1.
+
+ Overflow consumes the rest of the digits, and returns -1. */
+
+static int
+consume_count (type)
+ const char **type;
+{
+ int count = 0;
+
+ if (! isdigit ((unsigned char)**type))
+ return -1;
+
+ while (isdigit ((unsigned char)**type))
+ {
+ count *= 10;
+
+ /* Check for overflow.
+ We assume that count is represented using two's-complement;
+ no power of two is divisible by ten, so if an overflow occurs
+ when multiplying by ten, the result will not be a multiple of
+ ten. */
+ if ((count % 10) != 0)
+ {
+ while (isdigit ((unsigned char) **type))
+ (*type)++;
+ return -1;
+ }
+
+ count += **type - '0';
+ (*type)++;
+ }
+
+ return (count);
+}
+
+
+/* Like consume_count, but for counts that are preceded and followed
+ by '_' if they are greater than 10. Also, -1 is returned for
+ failure, since 0 can be a valid value. */
+
+static int
+consume_count_with_underscores (mangled)
+ const char **mangled;
+{
+ int idx;
+
+ if (**mangled == '_')
+ {
+ (*mangled)++;
+ if (!isdigit ((unsigned char)**mangled))
+ return -1;
+
+ idx = consume_count (mangled);
+ if (**mangled != '_')
+ /* The trailing underscore was missing. */
+ return -1;
+
+ (*mangled)++;
+ }
+ else
+ {
+ if (**mangled < '0' || **mangled > '9')
+ return -1;
+
+ idx = **mangled - '0';
+ (*mangled)++;
+ }
+
+ return idx;
+}
+
+/* C is the code for a type-qualifier. Return the TYPE_QUAL
+ corresponding to this qualifier. */
+
+static int
+code_for_qualifier (c)
+ int c;
+{
+ switch (c)
+ {
+ case 'C':
+ return TYPE_QUAL_CONST;
+
+ case 'V':
+ return TYPE_QUAL_VOLATILE;
+
+ case 'u':
+ return TYPE_QUAL_RESTRICT;
+
+ default:
+ break;
+ }
+
+ /* C was an invalid qualifier. */
+ abort ();
+}
+
+/* Return the string corresponding to the qualifiers given by
+ TYPE_QUALS. */
+
+static const char*
+qualifier_string (type_quals)
+ int type_quals;
+{
+ switch (type_quals)
+ {
+ case TYPE_UNQUALIFIED:
+ return "";
+
+ case TYPE_QUAL_CONST:
+ return "const";
+
+ case TYPE_QUAL_VOLATILE:
+ return "volatile";
+
+ case TYPE_QUAL_RESTRICT:
+ return "__restrict";
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
+ return "const volatile";
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
+ return "const __restrict";
+
+ case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ return "volatile __restrict";
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ return "const volatile __restrict";
+
+ default:
+ break;
+ }
+
+ /* TYPE_QUALS was an invalid qualifier set. */
+ abort ();
+}
+
+/* C is the code for a type-qualifier. Return the string
+ corresponding to this qualifier. This function should only be
+ called with a valid qualifier code. */
+
+static const char*
+demangle_qualifier (c)
+ int c;
+{
+ return qualifier_string (code_for_qualifier (c));
+}
+
+int
+cplus_demangle_opname (opname, result, options)
+ const char *opname;
+ char *result;
+ int options;
+{
+ int len, len1, ret;
+ string type;
+ struct work_stuff work[1];
+ const char *tem;
+
+ len = strlen(opname);
+ result[0] = '\0';
+ ret = 0;
+ memset ((char *) work, 0, sizeof (work));
+ work->options = options;
+
+ if (opname[0] == '_' && opname[1] == '_'
+ && opname[2] == 'o' && opname[3] == 'p')
+ {
+ /* ANSI. */
+ /* type conversion operator. */
+ tem = opname + 4;
+ if (do_type (work, &tem, &type))
+ {
+ strcat (result, "operator ");
+ strncat (result, type.b, type.p - type.b);
+ string_delete (&type);
+ ret = 1;
+ }
+ }
+ else if (opname[0] == '_' && opname[1] == '_'
+ && opname[2] >= 'a' && opname[2] <= 'z'
+ && opname[3] >= 'a' && opname[3] <= 'z')
+ {
+ if (opname[4] == '\0')
+ {
+ /* Operator. */
+ size_t i;
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ if (strlen (optable[i].in) == 2
+ && memcmp (optable[i].in, opname + 2, 2) == 0)
+ {
+ strcat (result, "operator");
+ strcat (result, optable[i].out);
+ ret = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (opname[2] == 'a' && opname[5] == '\0')
+ {
+ /* Assignment. */
+ size_t i;
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ if (strlen (optable[i].in) == 3
+ && memcmp (optable[i].in, opname + 2, 3) == 0)
+ {
+ strcat (result, "operator");
+ strcat (result, optable[i].out);
+ ret = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (len >= 3
+ && opname[0] == 'o'
+ && opname[1] == 'p'
+ && strchr (cplus_markers, opname[2]) != NULL)
+ {
+ /* see if it's an assignment expression */
+ if (len >= 10 /* op$assign_ */
+ && memcmp (opname + 3, "assign_", 7) == 0)
+ {
+ size_t i;
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ len1 = len - 10;
+ if ((int) strlen (optable[i].in) == len1
+ && memcmp (optable[i].in, opname + 10, len1) == 0)
+ {
+ strcat (result, "operator");
+ strcat (result, optable[i].out);
+ strcat (result, "=");
+ ret = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ size_t i;
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ len1 = len - 3;
+ if ((int) strlen (optable[i].in) == len1
+ && memcmp (optable[i].in, opname + 3, len1) == 0)
+ {
+ strcat (result, "operator");
+ strcat (result, optable[i].out);
+ ret = 1;
+ break;
+ }
+ }
+ }
+ }
+ else if (len >= 5 && memcmp (opname, "type", 4) == 0
+ && strchr (cplus_markers, opname[4]) != NULL)
+ {
+ /* type conversion operator */
+ tem = opname + 5;
+ if (do_type (work, &tem, &type))
+ {
+ strcat (result, "operator ");
+ strncat (result, type.b, type.p - type.b);
+ string_delete (&type);
+ ret = 1;
+ }
+ }
+ squangle_mop_up (work);
+ return ret;
+
+}
+/* Takes operator name as e.g. "++" and returns mangled
+ operator name (e.g. "postincrement_expr"), or NULL if not found.
+
+ If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
+ if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
+
+const char *
+cplus_mangle_opname (opname, options)
+ const char *opname;
+ int options;
+{
+ size_t i;
+ int len;
+
+ len = strlen (opname);
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ if ((int) strlen (optable[i].out) == len
+ && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
+ && memcmp (optable[i].out, opname, len) == 0)
+ return optable[i].in;
+ }
+ return (0);
+}
+
+/* char *cplus_demangle (const char *mangled, int options)
+
+ If MANGLED is a mangled function name produced by GNU C++, then
+ a pointer to a malloced string giving a C++ representation
+ of the name will be returned; otherwise NULL will be returned.
+ It is the caller's responsibility to free the string which
+ is returned.
+
+ The OPTIONS arg may contain one or more of the following bits:
+
+ DMGL_ANSI ANSI qualifiers such as `const' and `void' are
+ included.
+ DMGL_PARAMS Function parameters are included.
+
+ For example,
+
+ cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
+ cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
+ cplus_demangle ("foo__1Ai", 0) => "A::foo"
+
+ cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
+ cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
+ cplus_demangle ("foo__1Afe", 0) => "A::foo"
+
+ Note that any leading underscores, or other such characters prepended by
+ the compilation system, are presumed to have already been stripped from
+ MANGLED. */
+
+char *
+cplus_demangle (mangled, options)
+ const char *mangled;
+ int options;
+{
+ char *ret;
+ struct work_stuff work[1];
+ memset ((char *) work, 0, sizeof (work));
+ work -> options = options;
+ if ((work -> options & DMGL_STYLE_MASK) == 0)
+ work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
+
+ ret = internal_cplus_demangle (work, mangled);
+ squangle_mop_up (work);
+ return (ret);
+}
+
+
+/* This function performs most of what cplus_demangle use to do, but
+ to be able to demangle a name with a B, K or n code, we need to
+ have a longer term memory of what types have been seen. The original
+ now intializes and cleans up the squangle code info, while internal
+ calls go directly to this routine to avoid resetting that info. */
+
+static char *
+internal_cplus_demangle (work, mangled)
+ struct work_stuff *work;
+ const char *mangled;
+{
+
+ string decl;
+ int success = 0;
+ char *demangled = NULL;
+ int s1,s2,s3,s4;
+ s1 = work->constructor;
+ s2 = work->destructor;
+ s3 = work->static_type;
+ s4 = work->type_quals;
+ work->constructor = work->destructor = 0;
+ work->type_quals = TYPE_UNQUALIFIED;
+ work->dllimported = 0;
+
+ if ((mangled != NULL) && (*mangled != '\0'))
+ {
+ string_init (&decl);
+
+ /* First check to see if gnu style demangling is active and if the
+ string to be demangled contains a CPLUS_MARKER. If so, attempt to
+ recognize one of the gnu special forms rather than looking for a
+ standard prefix. In particular, don't worry about whether there
+ is a "__" string in the mangled string. Consider "_$_5__foo" for
+ example. */
+
+ if ((AUTO_DEMANGLING || GNU_DEMANGLING))
+ {
+ success = gnu_special (work, &mangled, &decl);
+ }
+ if (!success)
+ {
+ success = demangle_prefix (work, &mangled, &decl);
+ }
+ if (success && (*mangled != '\0'))
+ {
+ success = demangle_signature (work, &mangled, &decl);
+ }
+ if (work->constructor == 2)
+ {
+ string_prepend (&decl, "global constructors keyed to ");
+ work->constructor = 0;
+ }
+ else if (work->destructor == 2)
+ {
+ string_prepend (&decl, "global destructors keyed to ");
+ work->destructor = 0;
+ }
+ else if (work->dllimported == 1)
+ {
+ string_prepend (&decl, "import stub for ");
+ work->dllimported = 0;
+ }
+ demangled = mop_up (work, &decl, success);
+ }
+ work->constructor = s1;
+ work->destructor = s2;
+ work->static_type = s3;
+ work->type_quals = s4;
+ return (demangled);
+}
+
+
+/* Clear out and squangling related storage */
+static void
+squangle_mop_up (work)
+ struct work_stuff *work;
+{
+ /* clean up the B and K type mangling types. */
+ forget_B_and_K_types (work);
+ if (work -> btypevec != NULL)
+ {
+ free ((char *) work -> btypevec);
+ }
+ if (work -> ktypevec != NULL)
+ {
+ free ((char *) work -> ktypevec);
+ }
+}
+
+/* Clear out any mangled storage */
+
+static char *
+mop_up (work, declp, success)
+ struct work_stuff *work;
+ string *declp;
+ int success;
+{
+ char *demangled = NULL;
+
+ /* Discard the remembered types, if any. */
+
+ forget_types (work);
+ if (work -> typevec != NULL)
+ {
+ free ((char *) work -> typevec);
+ work -> typevec = NULL;
+ work -> typevec_size = 0;
+ }
+ if (work->tmpl_argvec)
+ {
+ int i;
+
+ for (i = 0; i < work->ntmpl_args; i++)
+ if (work->tmpl_argvec[i])
+ free ((char*) work->tmpl_argvec[i]);
+
+ free ((char*) work->tmpl_argvec);
+ work->tmpl_argvec = NULL;
+ }
+ if (work->previous_argument)
+ {
+ string_delete (work->previous_argument);
+ free ((char*) work->previous_argument);
+ work->previous_argument = NULL;
+ }
+
+ /* If demangling was successful, ensure that the demangled string is null
+ terminated and return it. Otherwise, free the demangling decl. */
+
+ if (!success)
+ {
+ string_delete (declp);
+ }
+ else
+ {
+ string_appendn (declp, "", 1);
+ demangled = declp -> b;
+ }
+ return (demangled);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ demangle_signature -- demangle the signature part of a mangled name
+
+SYNOPSIS
+
+ static int
+ demangle_signature (struct work_stuff *work, const char **mangled,
+ string *declp);
+
+DESCRIPTION
+
+ Consume and demangle the signature portion of the mangled name.
+
+ DECLP is the string where demangled output is being built. At
+ entry it contains the demangled root name from the mangled name
+ prefix. I.E. either a demangled operator name or the root function
+ name. In some special cases, it may contain nothing.
+
+ *MANGLED points to the current unconsumed location in the mangled
+ name. As tokens are consumed and demangling is performed, the
+ pointer is updated to continuously point at the next token to
+ be consumed.
+
+ Demangling GNU style mangled names is nasty because there is no
+ explicit token that marks the start of the outermost function
+ argument list. */
+
+static int
+demangle_signature (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ int success = 1;
+ int func_done = 0;
+ int expect_func = 0;
+ int expect_return_type = 0;
+ const char *oldmangled = NULL;
+ string trawname;
+ string tname;
+
+ while (success && (**mangled != '\0'))
+ {
+ switch (**mangled)
+ {
+ case 'Q':
+ oldmangled = *mangled;
+ success = demangle_qualified (work, mangled, declp, 1, 0);
+ if (success)
+ remember_type (work, oldmangled, *mangled - oldmangled);
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ expect_func = 1;
+ oldmangled = NULL;
+ break;
+
+ case 'K':
+ oldmangled = *mangled;
+ success = demangle_qualified (work, mangled, declp, 1, 0);
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ {
+ expect_func = 1;
+ }
+ oldmangled = NULL;
+ break;
+
+ case 'S':
+ /* Static member function */
+ if (oldmangled == NULL)
+ {
+ oldmangled = *mangled;
+ }
+ (*mangled)++;
+ work -> static_type = 1;
+ break;
+
+ case 'C':
+ case 'V':
+ case 'u':
+ work->type_quals |= code_for_qualifier (**mangled);
+
+ /* a qualified member function */
+ if (oldmangled == NULL)
+ oldmangled = *mangled;
+ (*mangled)++;
+ break;
+
+ case 'L':
+ /* Local class name follows after "Lnnn_" */
+ if (HP_DEMANGLING)
+ {
+ while (**mangled && (**mangled != '_'))
+ (*mangled)++;
+ if (!**mangled)
+ success = 0;
+ else
+ (*mangled)++;
+ }
+ else
+ success = 0;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (oldmangled == NULL)
+ {
+ oldmangled = *mangled;
+ }
+ work->temp_start = -1; /* uppermost call to demangle_class */
+ success = demangle_class (work, mangled, declp);
+ if (success)
+ {
+ remember_type (work, oldmangled, *mangled - oldmangled);
+ }
+ if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
+ {
+ /* EDG and others will have the "F", so we let the loop cycle
+ if we are looking at one. */
+ if (**mangled != 'F')
+ expect_func = 1;
+ }
+ oldmangled = NULL;
+ break;
+
+ case 'B':
+ {
+ string s;
+ success = do_type (work, mangled, &s);
+ if (success)
+ {
+ string_append (&s, SCOPE_STRING (work));
+ string_prepends (declp, &s);
+ }
+ oldmangled = NULL;
+ expect_func = 1;
+ }
+ break;
+
+ case 'F':
+ /* Function */
+ /* ARM/HP style demangling includes a specific 'F' character after
+ the class name. For GNU style, it is just implied. So we can
+ safely just consume any 'F' at this point and be compatible
+ with either style. */
+
+ oldmangled = NULL;
+ func_done = 1;
+ (*mangled)++;
+
+ /* For lucid/ARM/HP style we have to forget any types we might
+ have remembered up to this point, since they were not argument
+ types. GNU style considers all types seen as available for
+ back references. See comment in demangle_args() */
+
+ if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
+ {
+ forget_types (work);
+ }
+ success = demangle_args (work, mangled, declp);
+ /* After picking off the function args, we expect to either
+ find the function return type (preceded by an '_') or the
+ end of the string. */
+ if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
+ {
+ ++(*mangled);
+ /* At this level, we do not care about the return type. */
+ success = do_type (work, mangled, &tname);
+ string_delete (&tname);
+ }
+
+ break;
+
+ case 't':
+ /* G++ Template */
+ string_init(&trawname);
+ string_init(&tname);
+ if (oldmangled == NULL)
+ {
+ oldmangled = *mangled;
+ }
+ success = demangle_template (work, mangled, &tname,
+ &trawname, 1, 1);
+ if (success)
+ {
+ remember_type (work, oldmangled, *mangled - oldmangled);
+ }
+ string_append (&tname, SCOPE_STRING (work));
+
+ string_prepends(declp, &tname);
+ if (work -> destructor & 1)
+ {
+ string_prepend (&trawname, "~");
+ string_appends (declp, &trawname);
+ work->destructor -= 1;
+ }
+ if ((work->constructor & 1) || (work->destructor & 1))
+ {
+ string_appends (declp, &trawname);
+ work->constructor -= 1;
+ }
+ string_delete(&trawname);
+ string_delete(&tname);
+ oldmangled = NULL;
+ expect_func = 1;
+ break;
+
+ case '_':
+ if (GNU_DEMANGLING && expect_return_type)
+ {
+ /* Read the return type. */
+ string return_type;
+ string_init (&return_type);
+
+ (*mangled)++;
+ success = do_type (work, mangled, &return_type);
+ APPEND_BLANK (&return_type);
+
+ string_prepends (declp, &return_type);
+ string_delete (&return_type);
+ break;
+ }
+ else
+ /* At the outermost level, we cannot have a return type specified,
+ so if we run into another '_' at this point we are dealing with
+ a mangled name that is either bogus, or has been mangled by
+ some algorithm we don't know how to deal with. So just
+ reject the entire demangling. */
+ /* However, "_nnn" is an expected suffix for alternate entry point
+ numbered nnn for a function, with HP aCC, so skip over that
+ without reporting failure. pai/1997-09-04 */
+ if (HP_DEMANGLING)
+ {
+ (*mangled)++;
+ while (**mangled && isdigit ((unsigned char)**mangled))
+ (*mangled)++;
+ }
+ else
+ success = 0;
+ break;
+
+ case 'H':
+ if (GNU_DEMANGLING)
+ {
+ /* A G++ template function. Read the template arguments. */
+ success = demangle_template (work, mangled, declp, 0, 0,
+ 0);
+ if (!(work->constructor & 1))
+ expect_return_type = 1;
+ (*mangled)++;
+ break;
+ }
+ else
+ /* fall through */
+ {;}
+
+ default:
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ {
+ /* Assume we have stumbled onto the first outermost function
+ argument token, and start processing args. */
+ func_done = 1;
+ success = demangle_args (work, mangled, declp);
+ }
+ else
+ {
+ /* Non-GNU demanglers use a specific token to mark the start
+ of the outermost function argument tokens. Typically 'F',
+ for ARM/HP-demangling, for example. So if we find something
+ we are not prepared for, it must be an error. */
+ success = 0;
+ }
+ break;
+ }
+ /*
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ */
+ {
+ if (success && expect_func)
+ {
+ func_done = 1;
+ if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
+ {
+ forget_types (work);
+ }
+ success = demangle_args (work, mangled, declp);
+ /* Since template include the mangling of their return types,
+ we must set expect_func to 0 so that we don't try do
+ demangle more arguments the next time we get here. */
+ expect_func = 0;
+ }
+ }
+ }
+ if (success && !func_done)
+ {
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ {
+ /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
+ bar__3fooi is 'foo::bar(int)'. We get here when we find the
+ first case, and need to ensure that the '(void)' gets added to
+ the current declp. Note that with ARM/HP, the first case
+ represents the name of a static data member 'foo::bar',
+ which is in the current declp, so we leave it alone. */
+ success = demangle_args (work, mangled, declp);
+ }
+ }
+ if (success && PRINT_ARG_TYPES)
+ {
+ if (work->static_type)
+ string_append (declp, " static");
+ if (work->type_quals != TYPE_UNQUALIFIED)
+ {
+ APPEND_BLANK (declp);
+ string_append (declp, qualifier_string (work->type_quals));
+ }
+ }
+
+ return (success);
+}
+
+#if 0
+
+static int
+demangle_method_args (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ int success = 0;
+
+ if (work -> static_type)
+ {
+ string_append (declp, *mangled + 1);
+ *mangled += strlen (*mangled);
+ success = 1;
+ }
+ else
+ {
+ success = demangle_args (work, mangled, declp);
+ }
+ return (success);
+}
+
+#endif
+
+static int
+demangle_template_template_parm (work, mangled, tname)
+ struct work_stuff *work;
+ const char **mangled;
+ string *tname;
+{
+ int i;
+ int r;
+ int need_comma = 0;
+ int success = 1;
+ string temp;
+
+ string_append (tname, "template <");
+ /* get size of template parameter list */
+ if (get_count (mangled, &r))
+ {
+ for (i = 0; i < r; i++)
+ {
+ if (need_comma)
+ {
+ string_append (tname, ", ");
+ }
+
+ /* Z for type parameters */
+ if (**mangled == 'Z')
+ {
+ (*mangled)++;
+ string_append (tname, "class");
+ }
+ /* z for template parameters */
+ else if (**mangled == 'z')
+ {
+ (*mangled)++;
+ success =
+ demangle_template_template_parm (work, mangled, tname);
+ if (!success)
+ {
+ break;
+ }
+ }
+ else
+ {
+ /* temp is initialized in do_type */
+ success = do_type (work, mangled, &temp);
+ if (success)
+ {
+ string_appends (tname, &temp);
+ }
+ string_delete(&temp);
+ if (!success)
+ {
+ break;
+ }
+ }
+ need_comma = 1;
+ }
+
+ }
+ if (tname->p[-1] == '>')
+ string_append (tname, " ");
+ string_append (tname, "> class");
+ return (success);
+}
+
+static int
+demangle_integral_value (work, mangled, s)
+ struct work_stuff *work;
+ const char** mangled;
+ string* s;
+{
+ int success;
+
+ if (**mangled == 'E')
+ {
+ int need_operator = 0;
+
+ success = 1;
+ string_appendn (s, "(", 1);
+ (*mangled)++;
+ while (success && **mangled != 'W' && **mangled != '\0')
+ {
+ if (need_operator)
+ {
+ size_t i;
+ size_t len;
+
+ success = 0;
+
+ len = strlen (*mangled);
+
+ for (i = 0;
+ i < sizeof (optable) / sizeof (optable [0]);
+ ++i)
+ {
+ size_t l = strlen (optable[i].in);
+
+ if (l <= len
+ && memcmp (optable[i].in, *mangled, l) == 0)
+ {
+ string_appendn (s, " ", 1);
+ string_append (s, optable[i].out);
+ string_appendn (s, " ", 1);
+ success = 1;
+ (*mangled) += l;
+ break;
+ }
+ }
+
+ if (!success)
+ break;
+ }
+ else
+ need_operator = 1;
+
+ success = demangle_template_value_parm (work, mangled, s,
+ tk_integral);
+ }
+
+ if (**mangled != 'W')
+ success = 0;
+ else
+ {
+ string_appendn (s, ")", 1);
+ (*mangled)++;
+ }
+ }
+ else if (**mangled == 'Q' || **mangled == 'K')
+ success = demangle_qualified (work, mangled, s, 0, 1);
+ else
+ {
+ success = 0;
+
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
+ while (isdigit ((unsigned char)**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ success = 1;
+ }
+ }
+
+ return success;
+}
+
+static int
+demangle_template_value_parm (work, mangled, s, tk)
+ struct work_stuff *work;
+ const char **mangled;
+ string* s;
+ type_kind_t tk;
+{
+ int success = 1;
+
+ if (**mangled == 'Y')
+ {
+ /* The next argument is a template parameter. */
+ int idx;
+
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1
+ || (work->tmpl_argvec && idx >= work->ntmpl_args)
+ || consume_count_with_underscores (mangled) == -1)
+ return -1;
+ if (work->tmpl_argvec)
+ string_append (s, work->tmpl_argvec[idx]);
+ else
+ {
+ char buf[10];
+ sprintf(buf, "T%d", idx);
+ string_append (s, buf);
+ }
+ }
+ else if (tk == tk_integral)
+ success = demangle_integral_value (work, mangled, s);
+ else if (tk == tk_char)
+ {
+ char tmp[2];
+ int val;
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
+ string_appendn (s, "'", 1);
+ val = consume_count(mangled);
+ if (val <= 0)
+ success = 0;
+ else
+ {
+ tmp[0] = (char)val;
+ tmp[1] = '\0';
+ string_appendn (s, &tmp[0], 1);
+ string_appendn (s, "'", 1);
+ }
+ }
+ else if (tk == tk_bool)
+ {
+ int val = consume_count (mangled);
+ if (val == 0)
+ string_appendn (s, "false", 5);
+ else if (val == 1)
+ string_appendn (s, "true", 4);
+ else
+ success = 0;
+ }
+ else if (tk == tk_real)
+ {
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
+ while (isdigit ((unsigned char)**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ }
+ if (**mangled == '.') /* fraction */
+ {
+ string_appendn (s, ".", 1);
+ (*mangled)++;
+ while (isdigit ((unsigned char)**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ }
+ }
+ if (**mangled == 'e') /* exponent */
+ {
+ string_appendn (s, "e", 1);
+ (*mangled)++;
+ while (isdigit ((unsigned char)**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ }
+ }
+ }
+ else if (tk == tk_pointer || tk == tk_reference)
+ {
+ int symbol_len = consume_count (mangled);
+ if (symbol_len == -1)
+ return -1;
+ if (symbol_len == 0)
+ string_appendn (s, "0", 1);
+ else
+ {
+ char *p = xmalloc (symbol_len + 1), *q;
+ strncpy (p, *mangled, symbol_len);
+ p [symbol_len] = '\0';
+ /* We use cplus_demangle here, rather than
+ internal_cplus_demangle, because the name of the entity
+ mangled here does not make use of any of the squangling
+ or type-code information we have built up thus far; it is
+ mangled independently. */
+ q = cplus_demangle (p, work->options);
+ if (tk == tk_pointer)
+ string_appendn (s, "&", 1);
+ /* FIXME: Pointer-to-member constants should get a
+ qualifying class name here. */
+ if (q)
+ {
+ string_append (s, q);
+ free (q);
+ }
+ else
+ string_append (s, p);
+ free (p);
+ }
+ *mangled += symbol_len;
+ }
+
+ return success;
+}
+
+/* Demangle the template name in MANGLED. The full name of the
+ template (e.g., S<int>) is placed in TNAME. The name without the
+ template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
+ non-NULL. If IS_TYPE is nonzero, this template is a type template,
+ not a function template. If both IS_TYPE and REMEMBER are nonzero,
+ the tmeplate is remembered in the list of back-referenceable
+ types. */
+
+static int
+demangle_template (work, mangled, tname, trawname, is_type, remember)
+ struct work_stuff *work;
+ const char **mangled;
+ string *tname;
+ string *trawname;
+ int is_type;
+ int remember;
+{
+ int i;
+ int r;
+ int need_comma = 0;
+ int success = 0;
+ const char *start;
+ int is_java_array = 0;
+ string temp;
+ int bindex = 0;
+
+ (*mangled)++;
+ if (is_type)
+ {
+ if (remember)
+ bindex = register_Btype (work);
+ start = *mangled;
+ /* get template name */
+ if (**mangled == 'z')
+ {
+ int idx;
+ (*mangled)++;
+ (*mangled)++;
+
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1
+ || (work->tmpl_argvec && idx >= work->ntmpl_args)
+ || consume_count_with_underscores (mangled) == -1)
+ return (0);
+
+ if (work->tmpl_argvec)
+ {
+ string_append (tname, work->tmpl_argvec[idx]);
+ if (trawname)
+ string_append (trawname, work->tmpl_argvec[idx]);
+ }
+ else
+ {
+ char buf[10];
+ sprintf(buf, "T%d", idx);
+ string_append (tname, buf);
+ if (trawname)
+ string_append (trawname, buf);
+ }
+ }
+ else
+ {
+ if ((r = consume_count (mangled)) <= 0
+ || (int) strlen (*mangled) < r)
+ {
+ return (0);
+ }
+ is_java_array = (work -> options & DMGL_JAVA)
+ && strncmp (*mangled, "JArray1Z", 8) == 0;
+ if (! is_java_array)
+ {
+ string_appendn (tname, *mangled, r);
+ }
+ if (trawname)
+ string_appendn (trawname, *mangled, r);
+ *mangled += r;
+ }
+ }
+ if (!is_java_array)
+ string_append (tname, "<");
+ /* get size of template parameter list */
+ if (!get_count (mangled, &r))
+ {
+ return (0);
+ }
+ if (!is_type)
+ {
+ /* Create an array for saving the template argument values. */
+ work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
+ work->ntmpl_args = r;
+ for (i = 0; i < r; i++)
+ work->tmpl_argvec[i] = 0;
+ }
+ for (i = 0; i < r; i++)
+ {
+ if (need_comma)
+ {
+ string_append (tname, ", ");
+ }
+ /* Z for type parameters */
+ if (**mangled == 'Z')
+ {
+ (*mangled)++;
+ /* temp is initialized in do_type */
+ success = do_type (work, mangled, &temp);
+ if (success)
+ {
+ string_appends (tname, &temp);
+
+ if (!is_type)
+ {
+ /* Save the template argument. */
+ int len = temp.p - temp.b;
+ work->tmpl_argvec[i] = xmalloc (len + 1);
+ memcpy (work->tmpl_argvec[i], temp.b, len);
+ work->tmpl_argvec[i][len] = '\0';
+ }
+ }
+ string_delete(&temp);
+ if (!success)
+ {
+ break;
+ }
+ }
+ /* z for template parameters */
+ else if (**mangled == 'z')
+ {
+ int r2;
+ (*mangled)++;
+ success = demangle_template_template_parm (work, mangled, tname);
+
+ if (success
+ && (r2 = consume_count (mangled)) > 0
+ && (int) strlen (*mangled) >= r2)
+ {
+ string_append (tname, " ");
+ string_appendn (tname, *mangled, r2);
+ if (!is_type)
+ {
+ /* Save the template argument. */
+ int len = r2;
+ work->tmpl_argvec[i] = xmalloc (len + 1);
+ memcpy (work->tmpl_argvec[i], *mangled, len);
+ work->tmpl_argvec[i][len] = '\0';
+ }
+ *mangled += r2;
+ }
+ if (!success)
+ {
+ break;
+ }
+ }
+ else
+ {
+ string param;
+ string* s;
+
+ /* otherwise, value parameter */
+
+ /* temp is initialized in do_type */
+ success = do_type (work, mangled, &temp);
+ string_delete(&temp);
+ if (!success)
+ break;
+
+ if (!is_type)
+ {
+ s = &param;
+ string_init (s);
+ }
+ else
+ s = tname;
+
+ success = demangle_template_value_parm (work, mangled, s,
+ (type_kind_t) success);
+
+ if (!success)
+ {
+ if (!is_type)
+ string_delete (s);
+ success = 0;
+ break;
+ }
+
+ if (!is_type)
+ {
+ int len = s->p - s->b;
+ work->tmpl_argvec[i] = xmalloc (len + 1);
+ memcpy (work->tmpl_argvec[i], s->b, len);
+ work->tmpl_argvec[i][len] = '\0';
+
+ string_appends (tname, s);
+ string_delete (s);
+ }
+ }
+ need_comma = 1;
+ }
+ if (is_java_array)
+ {
+ string_append (tname, "[]");
+ }
+ else
+ {
+ if (tname->p[-1] == '>')
+ string_append (tname, " ");
+ string_append (tname, ">");
+ }
+
+ if (is_type && remember)
+ remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
+
+ /*
+ if (work -> static_type)
+ {
+ string_append (declp, *mangled + 1);
+ *mangled += strlen (*mangled);
+ success = 1;
+ }
+ else
+ {
+ success = demangle_args (work, mangled, declp);
+ }
+ }
+ */
+ return (success);
+}
+
+static int
+arm_pt (work, mangled, n, anchor, args)
+ struct work_stuff *work;
+ const char *mangled;
+ int n;
+ const char **anchor, **args;
+{
+ /* Check if ARM template with "__pt__" in it ("parameterized type") */
+ /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
+ if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
+ {
+ int len;
+ *args = *anchor + 6;
+ len = consume_count (args);
+ if (len == -1)
+ return 0;
+ if (*args + len == mangled + n && **args == '_')
+ {
+ ++*args;
+ return 1;
+ }
+ }
+ if (AUTO_DEMANGLING || EDG_DEMANGLING)
+ {
+ if ((*anchor = mystrstr (mangled, "__tm__"))
+ || (*anchor = mystrstr (mangled, "__ps__"))
+ || (*anchor = mystrstr (mangled, "__pt__")))
+ {
+ int len;
+ *args = *anchor + 6;
+ len = consume_count (args);
+ if (len == -1)
+ return 0;
+ if (*args + len == mangled + n && **args == '_')
+ {
+ ++*args;
+ return 1;
+ }
+ }
+ else if ((*anchor = mystrstr (mangled, "__S")))
+ {
+ int len;
+ *args = *anchor + 3;
+ len = consume_count (args);
+ if (len == -1)
+ return 0;
+ if (*args + len == mangled + n && **args == '_')
+ {
+ ++*args;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void
+demangle_arm_hp_template (work, mangled, n, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ int n;
+ string *declp;
+{
+ const char *p;
+ const char *args;
+ const char *e = *mangled + n;
+ string arg;
+
+ /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
+ template args */
+ if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
+ {
+ char *start_spec_args = NULL;
+
+ /* First check for and omit template specialization pseudo-arguments,
+ such as in "Spec<#1,#1.*>" */
+ start_spec_args = strchr (*mangled, '<');
+ if (start_spec_args && (start_spec_args - *mangled < n))
+ string_appendn (declp, *mangled, start_spec_args - *mangled);
+ else
+ string_appendn (declp, *mangled, n);
+ (*mangled) += n + 1;
+ string_init (&arg);
+ if (work->temp_start == -1) /* non-recursive call */
+ work->temp_start = declp->p - declp->b;
+ string_append (declp, "<");
+ while (1)
+ {
+ string_clear (&arg);
+ switch (**mangled)
+ {
+ case 'T':
+ /* 'T' signals a type parameter */
+ (*mangled)++;
+ if (!do_type (work, mangled, &arg))
+ goto hpacc_template_args_done;
+ break;
+
+ case 'U':
+ case 'S':
+ /* 'U' or 'S' signals an integral value */
+ if (!do_hpacc_template_const_value (work, mangled, &arg))
+ goto hpacc_template_args_done;
+ break;
+
+ case 'A':
+ /* 'A' signals a named constant expression (literal) */
+ if (!do_hpacc_template_literal (work, mangled, &arg))
+ goto hpacc_template_args_done;
+ break;
+
+ default:
+ /* Today, 1997-09-03, we have only the above types
+ of template parameters */
+ /* FIXME: maybe this should fail and return null */
+ goto hpacc_template_args_done;
+ }
+ string_appends (declp, &arg);
+ /* Check if we're at the end of template args.
+ 0 if at end of static member of template class,
+ _ if done with template args for a function */
+ if ((**mangled == '\000') || (**mangled == '_'))
+ break;
+ else
+ string_append (declp, ",");
+ }
+ hpacc_template_args_done:
+ string_append (declp, ">");
+ string_delete (&arg);
+ if (**mangled == '_')
+ (*mangled)++;
+ return;
+ }
+ /* ARM template? (Also handles HP cfront extensions) */
+ else if (arm_pt (work, *mangled, n, &p, &args))
+ {
+ string type_str;
+
+ string_init (&arg);
+ string_appendn (declp, *mangled, p - *mangled);
+ if (work->temp_start == -1) /* non-recursive call */
+ work->temp_start = declp->p - declp->b;
+ string_append (declp, "<");
+ /* should do error checking here */
+ while (args < e) {
+ string_clear (&arg);
+
+ /* Check for type or literal here */
+ switch (*args)
+ {
+ /* HP cfront extensions to ARM for template args */
+ /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
+ /* FIXME: We handle only numeric literals for HP cfront */
+ case 'X':
+ /* A typed constant value follows */
+ args++;
+ if (!do_type (work, &args, &type_str))
+ goto cfront_template_args_done;
+ string_append (&arg, "(");
+ string_appends (&arg, &type_str);
+ string_append (&arg, ")");
+ if (*args != 'L')
+ goto cfront_template_args_done;
+ args++;
+ /* Now snarf a literal value following 'L' */
+ if (!snarf_numeric_literal (&args, &arg))
+ goto cfront_template_args_done;
+ break;
+
+ case 'L':
+ /* Snarf a literal following 'L' */
+ args++;
+ if (!snarf_numeric_literal (&args, &arg))
+ goto cfront_template_args_done;
+ break;
+ default:
+ /* Not handling other HP cfront stuff */
+ if (!do_type (work, &args, &arg))
+ goto cfront_template_args_done;
+ }
+ string_appends (declp, &arg);
+ string_append (declp, ",");
+ }
+ cfront_template_args_done:
+ string_delete (&arg);
+ if (args >= e)
+ --declp->p; /* remove extra comma */
+ string_append (declp, ">");
+ }
+ else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
+ && (*mangled)[9] == 'N'
+ && (*mangled)[8] == (*mangled)[10]
+ && strchr (cplus_markers, (*mangled)[8]))
+ {
+ /* A member of the anonymous namespace. */
+ string_append (declp, "{anonymous}");
+ }
+ else
+ {
+ if (work->temp_start == -1) /* non-recursive call only */
+ work->temp_start = 0; /* disable in recursive calls */
+ string_appendn (declp, *mangled, n);
+ }
+ *mangled += n;
+}
+
+/* Extract a class name, possibly a template with arguments, from the
+ mangled string; qualifiers, local class indicators, etc. have
+ already been dealt with */
+
+static int
+demangle_class_name (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ int n;
+ int success = 0;
+
+ n = consume_count (mangled);
+ if (n == -1)
+ return 0;
+ if ((int) strlen (*mangled) >= n)
+ {
+ demangle_arm_hp_template (work, mangled, n, declp);
+ success = 1;
+ }
+
+ return (success);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ demangle_class -- demangle a mangled class sequence
+
+SYNOPSIS
+
+ static int
+ demangle_class (struct work_stuff *work, const char **mangled,
+ strint *declp)
+
+DESCRIPTION
+
+ DECLP points to the buffer into which demangling is being done.
+
+ *MANGLED points to the current token to be demangled. On input,
+ it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
+ On exit, it points to the next token after the mangled class on
+ success, or the first unconsumed token on failure.
+
+ If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
+ we are demangling a constructor or destructor. In this case
+ we prepend "class::class" or "class::~class" to DECLP.
+
+ Otherwise, we prepend "class::" to the current DECLP.
+
+ Reset the constructor/destructor flags once they have been
+ "consumed". This allows demangle_class to be called later during
+ the same demangling, to do normal class demangling.
+
+ Returns 1 if demangling is successful, 0 otherwise.
+
+*/
+
+static int
+demangle_class (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ int success = 0;
+ int btype;
+ string class_name;
+ char *save_class_name_end = 0;
+
+ string_init (&class_name);
+ btype = register_Btype (work);
+ if (demangle_class_name (work, mangled, &class_name))
+ {
+ save_class_name_end = class_name.p;
+ if ((work->constructor & 1) || (work->destructor & 1))
+ {
+ /* adjust so we don't include template args */
+ if (work->temp_start && (work->temp_start != -1))
+ {
+ class_name.p = class_name.b + work->temp_start;
+ }
+ string_prepends (declp, &class_name);
+ if (work -> destructor & 1)
+ {
+ string_prepend (declp, "~");
+ work -> destructor -= 1;
+ }
+ else
+ {
+ work -> constructor -= 1;
+ }
+ }
+ class_name.p = save_class_name_end;
+ remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
+ remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
+ string_prepend (declp, SCOPE_STRING (work));
+ string_prepends (declp, &class_name);
+ success = 1;
+ }
+ string_delete (&class_name);
+ return (success);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ demangle_prefix -- consume the mangled name prefix and find signature
+
+SYNOPSIS
+
+ static int
+ demangle_prefix (struct work_stuff *work, const char **mangled,
+ string *declp);
+
+DESCRIPTION
+
+ Consume and demangle the prefix of the mangled name.
+
+ DECLP points to the string buffer into which demangled output is
+ placed. On entry, the buffer is empty. On exit it contains
+ the root function name, the demangled operator name, or in some
+ special cases either nothing or the completely demangled result.
+
+ MANGLED points to the current pointer into the mangled name. As each
+ token of the mangled name is consumed, it is updated. Upon entry
+ the current mangled name pointer points to the first character of
+ the mangled name. Upon exit, it should point to the first character
+ of the signature if demangling was successful, or to the first
+ unconsumed character if demangling of the prefix was unsuccessful.
+
+ Returns 1 on success, 0 otherwise.
+ */
+
+static int
+demangle_prefix (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ int success = 1;
+ const char *scan;
+ int i;
+
+ if (strlen(*mangled) > 6
+ && (strncmp(*mangled, "_imp__", 6) == 0
+ || strncmp(*mangled, "__imp_", 6) == 0))
+ {
+ /* it's a symbol imported from a PE dynamic library. Check for both
+ new style prefix _imp__ and legacy __imp_ used by older versions
+ of dlltool. */
+ (*mangled) += 6;
+ work->dllimported = 1;
+ }
+ else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
+ {
+ char *marker = strchr (cplus_markers, (*mangled)[8]);
+ if (marker != NULL && *marker == (*mangled)[10])
+ {
+ if ((*mangled)[9] == 'D')
+ {
+ /* it's a GNU global destructor to be executed at program exit */
+ (*mangled) += 11;
+ work->destructor = 2;
+ if (gnu_special (work, mangled, declp))
+ return success;
+ }
+ else if ((*mangled)[9] == 'I')
+ {
+ /* it's a GNU global constructor to be executed at program init */
+ (*mangled) += 11;
+ work->constructor = 2;
+ if (gnu_special (work, mangled, declp))
+ return success;
+ }
+ }
+ }
+ else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
+ {
+ /* it's a ARM global destructor to be executed at program exit */
+ (*mangled) += 7;
+ work->destructor = 2;
+ }
+ else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
+ {
+ /* it's a ARM global constructor to be executed at program initial */
+ (*mangled) += 7;
+ work->constructor = 2;
+ }
+
+ /* This block of code is a reduction in strength time optimization
+ of:
+ scan = mystrstr (*mangled, "__"); */
+
+ {
+ scan = *mangled;
+
+ do {
+ scan = strchr (scan, '_');
+ } while (scan != NULL && *++scan != '_');
+
+ if (scan != NULL) --scan;
+ }
+
+ if (scan != NULL)
+ {
+ /* We found a sequence of two or more '_', ensure that we start at
+ the last pair in the sequence. */
+ i = strspn (scan, "_");
+ if (i > 2)
+ {
+ scan += (i - 2);
+ }
+ }
+
+ if (scan == NULL)
+ {
+ success = 0;
+ }
+ else if (work -> static_type)
+ {
+ if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
+ {
+ success = 0;
+ }
+ }
+ else if ((scan == *mangled)
+ && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
+ || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
+ {
+ /* The ARM says nothing about the mangling of local variables.
+ But cfront mangles local variables by prepending __<nesting_level>
+ to them. As an extension to ARM demangling we handle this case. */
+ if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
+ && isdigit ((unsigned char)scan[2]))
+ {
+ *mangled = scan + 2;
+ consume_count (mangled);
+ string_append (declp, *mangled);
+ *mangled += strlen (*mangled);
+ success = 1;
+ }
+ else
+ {
+ /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
+ names like __Q2_3foo3bar for nested type names. So don't accept
+ this style of constructor for cfront demangling. A GNU
+ style member-template constructor starts with 'H'. */
+ if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
+ work -> constructor += 1;
+ *mangled = scan + 2;
+ }
+ }
+ else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
+ {
+ /* Cfront-style parameterized type. Handled later as a signature. */
+ success = 1;
+
+ /* ARM template? */
+ demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
+ }
+ else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
+ || (scan[2] == 'p' && scan[3] == 's')
+ || (scan[2] == 'p' && scan[3] == 't')))
+ {
+ /* EDG-style parameterized type. Handled later as a signature. */
+ success = 1;
+
+ /* EDG template? */
+ demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
+ }
+ else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
+ && (scan[2] != 't'))
+ {
+ /* Mangled name starts with "__". Skip over any leading '_' characters,
+ then find the next "__" that separates the prefix from the signature.
+ */
+ if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
+ || (arm_special (mangled, declp) == 0))
+ {
+ while (*scan == '_')
+ {
+ scan++;
+ }
+ if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
+ {
+ /* No separator (I.E. "__not_mangled"), or empty signature
+ (I.E. "__not_mangled_either__") */
+ success = 0;
+ }
+ else
+ {
+ const char *tmp;
+
+ /* Look for the LAST occurrence of __, allowing names to
+ have the '__' sequence embedded in them. */
+ if (!(ARM_DEMANGLING || HP_DEMANGLING))
+ {
+ while ((tmp = mystrstr (scan + 2, "__")) != NULL)
+ scan = tmp;
+ }
+ if (*(scan + 2) == '\0')
+ success = 0;
+ else
+ demangle_function_name (work, mangled, declp, scan);
+ }
+ }
+ }
+ else if (*(scan + 2) != '\0')
+ {
+ /* Mangled name does not start with "__" but does have one somewhere
+ in there with non empty stuff after it. Looks like a global
+ function name. */
+ demangle_function_name (work, mangled, declp, scan);
+ }
+ else
+ {
+ /* Doesn't look like a mangled name */
+ success = 0;
+ }
+
+ if (!success && (work->constructor == 2 || work->destructor == 2))
+ {
+ string_append (declp, *mangled);
+ *mangled += strlen (*mangled);
+ success = 1;
+ }
+ return (success);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ gnu_special -- special handling of gnu mangled strings
+
+SYNOPSIS
+
+ static int
+ gnu_special (struct work_stuff *work, const char **mangled,
+ string *declp);
+
+
+DESCRIPTION
+
+ Process some special GNU style mangling forms that don't fit
+ the normal pattern. For example:
+
+ _$_3foo (destructor for class foo)
+ _vt$foo (foo virtual table)
+ _vt$foo$bar (foo::bar virtual table)
+ __vt_foo (foo virtual table, new style with thunks)
+ _3foo$varname (static data member)
+ _Q22rs2tu$vw (static data member)
+ __t6vector1Zii (constructor with template)
+ __thunk_4__$_7ostream (virtual function thunk)
+ */
+
+static int
+gnu_special (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ int n;
+ int success = 1;
+ const char *p;
+
+ if ((*mangled)[0] == '_'
+ && strchr (cplus_markers, (*mangled)[1]) != NULL
+ && (*mangled)[2] == '_')
+ {
+ /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
+ (*mangled) += 3;
+ work -> destructor += 1;
+ }
+ else if ((*mangled)[0] == '_'
+ && (((*mangled)[1] == '_'
+ && (*mangled)[2] == 'v'
+ && (*mangled)[3] == 't'
+ && (*mangled)[4] == '_')
+ || ((*mangled)[1] == 'v'
+ && (*mangled)[2] == 't'
+ && strchr (cplus_markers, (*mangled)[3]) != NULL)))
+ {
+ /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
+ and create the decl. Note that we consume the entire mangled
+ input string, which means that demangle_signature has no work
+ to do. */
+ if ((*mangled)[2] == 'v')
+ (*mangled) += 5; /* New style, with thunks: "__vt_" */
+ else
+ (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
+ while (**mangled != '\0')
+ {
+ switch (**mangled)
+ {
+ case 'Q':
+ case 'K':
+ success = demangle_qualified (work, mangled, declp, 0, 1);
+ break;
+ case 't':
+ success = demangle_template (work, mangled, declp, 0, 1,
+ 1);
+ break;
+ default:
+ if (isdigit((unsigned char)*mangled[0]))
+ {
+ n = consume_count(mangled);
+ /* We may be seeing a too-large size, or else a
+ ".<digits>" indicating a static local symbol. In
+ any case, declare victory and move on; *don't* try
+ to use n to allocate. */
+ if (n > (int) strlen (*mangled))
+ {
+ success = 1;
+ break;
+ }
+ }
+ else
+ {
+ n = strcspn (*mangled, cplus_markers);
+ }
+ string_appendn (declp, *mangled, n);
+ (*mangled) += n;
+ }
+
+ p = strpbrk (*mangled, cplus_markers);
+ if (success && ((p == NULL) || (p == *mangled)))
+ {
+ if (p != NULL)
+ {
+ string_append (declp, SCOPE_STRING (work));
+ (*mangled)++;
+ }
+ }
+ else
+ {
+ success = 0;
+ break;
+ }
+ }
+ if (success)
+ string_append (declp, " virtual table");
+ }
+ else if ((*mangled)[0] == '_'
+ && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
+ && (p = strpbrk (*mangled, cplus_markers)) != NULL)
+ {
+ /* static data member, "_3foo$varname" for example */
+ (*mangled)++;
+ switch (**mangled)
+ {
+ case 'Q':
+ case 'K':
+ success = demangle_qualified (work, mangled, declp, 0, 1);
+ break;
+ case 't':
+ success = demangle_template (work, mangled, declp, 0, 1, 1);
+ break;
+ default:
+ n = consume_count (mangled);
+ if (n < 0 || n > strlen (*mangled))
+ {
+ success = 0;
+ break;
+ }
+ string_appendn (declp, *mangled, n);
+ (*mangled) += n;
+ }
+ if (success && (p == *mangled))
+ {
+ /* Consumed everything up to the cplus_marker, append the
+ variable name. */
+ (*mangled)++;
+ string_append (declp, SCOPE_STRING (work));
+ n = strlen (*mangled);
+ string_appendn (declp, *mangled, n);
+ (*mangled) += n;
+ }
+ else
+ {
+ success = 0;
+ }
+ }
+ else if (strncmp (*mangled, "__thunk_", 8) == 0)
+ {
+ int delta;
+
+ (*mangled) += 8;
+ delta = consume_count (mangled);
+ if (delta == -1)
+ success = 0;
+ else
+ {
+ char *method = internal_cplus_demangle (work, ++*mangled);
+
+ if (method)
+ {
+ char buf[50];
+ sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
+ string_append (declp, buf);
+ string_append (declp, method);
+ free (method);
+ n = strlen (*mangled);
+ (*mangled) += n;
+ }
+ else
+ {
+ success = 0;
+ }
+ }
+ }
+ else if (strncmp (*mangled, "__t", 3) == 0
+ && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
+ {
+ p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
+ (*mangled) += 4;
+ switch (**mangled)
+ {
+ case 'Q':
+ case 'K':
+ success = demangle_qualified (work, mangled, declp, 0, 1);
+ break;
+ case 't':
+ success = demangle_template (work, mangled, declp, 0, 1, 1);
+ break;
+ default:
+ success = demangle_fund_type (work, mangled, declp);
+ break;
+ }
+ if (success && **mangled != '\0')
+ success = 0;
+ if (success)
+ string_append (declp, p);
+ }
+ else
+ {
+ success = 0;
+ }
+ return (success);
+}
+
+static void
+recursively_demangle(work, mangled, result, namelength)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+ int namelength;
+{
+ char * recurse = (char *)NULL;
+ char * recurse_dem = (char *)NULL;
+
+ recurse = (char *) xmalloc (namelength + 1);
+ memcpy (recurse, *mangled, namelength);
+ recurse[namelength] = '\000';
+
+ recurse_dem = cplus_demangle (recurse, work->options);
+
+ if (recurse_dem)
+ {
+ string_append (result, recurse_dem);
+ free (recurse_dem);
+ }
+ else
+ {
+ string_appendn (result, *mangled, namelength);
+ }
+ free (recurse);
+ *mangled += namelength;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ arm_special -- special handling of ARM/lucid mangled strings
+
+SYNOPSIS
+
+ static int
+ arm_special (const char **mangled,
+ string *declp);
+
+
+DESCRIPTION
+
+ Process some special ARM style mangling forms that don't fit
+ the normal pattern. For example:
+
+ __vtbl__3foo (foo virtual table)
+ __vtbl__3foo__3bar (bar::foo virtual table)
+
+ */
+
+static int
+arm_special (mangled, declp)
+ const char **mangled;
+ string *declp;
+{
+ int n;
+ int success = 1;
+ const char *scan;
+
+ if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
+ {
+ /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
+ and create the decl. Note that we consume the entire mangled
+ input string, which means that demangle_signature has no work
+ to do. */
+ scan = *mangled + ARM_VTABLE_STRLEN;
+ while (*scan != '\0') /* first check it can be demangled */
+ {
+ n = consume_count (&scan);
+ if (n == -1)
+ {
+ return (0); /* no good */
+ }
+ scan += n;
+ if (scan[0] == '_' && scan[1] == '_')
+ {
+ scan += 2;
+ }
+ }
+ (*mangled) += ARM_VTABLE_STRLEN;
+ while (**mangled != '\0')
+ {
+ n = consume_count (mangled);
+ if (n == -1
+ || n > strlen (*mangled))
+ return 0;
+ string_prependn (declp, *mangled, n);
+ (*mangled) += n;
+ if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
+ {
+ string_prepend (declp, "::");
+ (*mangled) += 2;
+ }
+ }
+ string_append (declp, " virtual table");
+ }
+ else
+ {
+ success = 0;
+ }
+ return (success);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ demangle_qualified -- demangle 'Q' qualified name strings
+
+SYNOPSIS
+
+ static int
+ demangle_qualified (struct work_stuff *, const char *mangled,
+ string *result, int isfuncname, int append);
+
+DESCRIPTION
+
+ Demangle a qualified name, such as "Q25Outer5Inner" which is
+ the mangled form of "Outer::Inner". The demangled output is
+ prepended or appended to the result string according to the
+ state of the append flag.
+
+ If isfuncname is nonzero, then the qualified name we are building
+ is going to be used as a member function name, so if it is a
+ constructor or destructor function, append an appropriate
+ constructor or destructor name. I.E. for the above example,
+ the result for use as a constructor is "Outer::Inner::Inner"
+ and the result for use as a destructor is "Outer::Inner::~Inner".
+
+BUGS
+
+ Numeric conversion is ASCII dependent (FIXME).
+
+ */
+
+static int
+demangle_qualified (work, mangled, result, isfuncname, append)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+ int isfuncname;
+ int append;
+{
+ int qualifiers = 0;
+ int success = 1;
+ const char *p;
+ char num[2];
+ string temp;
+ string last_name;
+ int bindex = register_Btype (work);
+
+ /* We only make use of ISFUNCNAME if the entity is a constructor or
+ destructor. */
+ isfuncname = (isfuncname
+ && ((work->constructor & 1) || (work->destructor & 1)));
+
+ string_init (&temp);
+ string_init (&last_name);
+
+ if ((*mangled)[0] == 'K')
+ {
+ /* Squangling qualified name reuse */
+ int idx;
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1 || idx >= work -> numk)
+ success = 0;
+ else
+ string_append (&temp, work -> ktypevec[idx]);
+ }
+ else
+ switch ((*mangled)[1])
+ {
+ case '_':
+ /* GNU mangled name with more than 9 classes. The count is preceded
+ by an underscore (to distinguish it from the <= 9 case) and followed
+ by an underscore. */
+ p = *mangled + 2;
+ qualifiers = atoi (p);
+ if (!isdigit ((unsigned char)*p) || *p == '0')
+ success = 0;
+
+ /* Skip the digits. */
+ while (isdigit ((unsigned char)*p))
+ ++p;
+
+ if (*p != '_')
+ success = 0;
+
+ *mangled = p + 1;
+ break;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* The count is in a single digit. */
+ num[0] = (*mangled)[1];
+ num[1] = '\0';
+ qualifiers = atoi (num);
+
+ /* If there is an underscore after the digit, skip it. This is
+ said to be for ARM-qualified names, but the ARM makes no
+ mention of such an underscore. Perhaps cfront uses one. */
+ if ((*mangled)[2] == '_')
+ {
+ (*mangled)++;
+ }
+ (*mangled) += 2;
+ break;
+
+ case '0':
+ default:
+ success = 0;
+ }
+
+ if (!success)
+ return success;
+
+ /* Pick off the names and collect them in the temp buffer in the order
+ in which they are found, separated by '::'. */
+
+ while (qualifiers-- > 0)
+ {
+ int remember_K = 1;
+ string_clear (&last_name);
+
+ if (*mangled[0] == '_')
+ (*mangled)++;
+
+ if (*mangled[0] == 't')
+ {
+ /* Here we always append to TEMP since we will want to use
+ the template name without the template parameters as a
+ constructor or destructor name. The appropriate
+ (parameter-less) value is returned by demangle_template
+ in LAST_NAME. We do not remember the template type here,
+ in order to match the G++ mangling algorithm. */
+ success = demangle_template(work, mangled, &temp,
+ &last_name, 1, 0);
+ if (!success)
+ break;
+ }
+ else if (*mangled[0] == 'K')
+ {
+ int idx;
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1 || idx >= work->numk)
+ success = 0;
+ else
+ string_append (&temp, work->ktypevec[idx]);
+ remember_K = 0;
+
+ if (!success) break;
+ }
+ else
+ {
+ if (EDG_DEMANGLING)
+ {
+ int namelength;
+ /* Now recursively demangle the qualifier
+ * This is necessary to deal with templates in
+ * mangling styles like EDG */
+ namelength = consume_count (mangled);
+ if (namelength == -1)
+ {
+ success = 0;
+ break;
+ }
+ recursively_demangle(work, mangled, &temp, namelength);
+ }
+ else
+ {
+ success = do_type (work, mangled, &last_name);
+ if (!success)
+ break;
+ string_appends (&temp, &last_name);
+ }
+ }
+
+ if (remember_K)
+ remember_Ktype (work, temp.b, LEN_STRING (&temp));
+
+ if (qualifiers > 0)
+ string_append (&temp, SCOPE_STRING (work));
+ }
+
+ remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
+
+ /* If we are using the result as a function name, we need to append
+ the appropriate '::' separated constructor or destructor name.
+ We do this here because this is the most convenient place, where
+ we already have a pointer to the name and the length of the name. */
+
+ if (isfuncname)
+ {
+ string_append (&temp, SCOPE_STRING (work));
+ if (work -> destructor & 1)
+ string_append (&temp, "~");
+ string_appends (&temp, &last_name);
+ }
+
+ /* Now either prepend the temp buffer to the result, or append it,
+ depending upon the state of the append flag. */
+
+ if (append)
+ string_appends (result, &temp);
+ else
+ {
+ if (!STRING_EMPTY (result))
+ string_append (&temp, SCOPE_STRING (work));
+ string_prepends (result, &temp);
+ }
+
+ string_delete (&last_name);
+ string_delete (&temp);
+ return (success);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ get_count -- convert an ascii count to integer, consuming tokens
+
+SYNOPSIS
+
+ static int
+ get_count (const char **type, int *count)
+
+DESCRIPTION
+
+ Assume that *type points at a count in a mangled name; set
+ *count to its value, and set *type to the next character after
+ the count. There are some weird rules in effect here.
+
+ If *type does not point at a string of digits, return zero.
+
+ If *type points at a string of digits followed by an
+ underscore, set *count to their value as an integer, advance
+ *type to point *after the underscore, and return 1.
+
+ If *type points at a string of digits not followed by an
+ underscore, consume only the first digit. Set *count to its
+ value as an integer, leave *type pointing after that digit,
+ and return 1.
+
+ The excuse for this odd behavior: in the ARM and HP demangling
+ styles, a type can be followed by a repeat count of the form
+ `Nxy', where:
+
+ `x' is a single digit specifying how many additional copies
+ of the type to append to the argument list, and
+
+ `y' is one or more digits, specifying the zero-based index of
+ the first repeated argument in the list. Yes, as you're
+ unmangling the name you can figure this out yourself, but
+ it's there anyway.
+
+ So, for example, in `bar__3fooFPiN51', the first argument is a
+ pointer to an integer (`Pi'), and then the next five arguments
+ are the same (`N5'), and the first repeat is the function's
+ second argument (`1').
+*/
+
+static int
+get_count (type, count)
+ const char **type;
+ int *count;
+{
+ const char *p;
+ int n;
+
+ if (!isdigit ((unsigned char)**type))
+ {
+ return (0);
+ }
+ else
+ {
+ *count = **type - '0';
+ (*type)++;
+ if (isdigit ((unsigned char)**type))
+ {
+ p = *type;
+ n = *count;
+ do
+ {
+ n *= 10;
+ n += *p - '0';
+ p++;
+ }
+ while (isdigit ((unsigned char)*p));
+ if (*p == '_')
+ {
+ *type = p + 1;
+ *count = n;
+ }
+ }
+ }
+ return (1);
+}
+
+/* RESULT will be initialised here; it will be freed on failure. The
+ value returned is really a type_kind_t. */
+
+static int
+do_type (work, mangled, result)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+{
+ int n;
+ int done;
+ int success;
+ string decl;
+ const char *remembered_type;
+ int type_quals;
+ string btype;
+ type_kind_t tk = tk_none;
+
+ string_init (&btype);
+ string_init (&decl);
+ string_init (result);
+
+ done = 0;
+ success = 1;
+ while (success && !done)
+ {
+ int member;
+ switch (**mangled)
+ {
+
+ /* A pointer type */
+ case 'P':
+ case 'p':
+ (*mangled)++;
+ if (! (work -> options & DMGL_JAVA))
+ string_prepend (&decl, "*");
+ if (tk == tk_none)
+ tk = tk_pointer;
+ break;
+
+ /* A reference type */
+ case 'R':
+ (*mangled)++;
+ string_prepend (&decl, "&");
+ if (tk == tk_none)
+ tk = tk_reference;
+ break;
+
+ /* An array */
+ case 'A':
+ {
+ ++(*mangled);
+ if (!STRING_EMPTY (&decl)
+ && (decl.b[0] == '*' || decl.b[0] == '&'))
+ {
+ string_prepend (&decl, "(");
+ string_append (&decl, ")");
+ }
+ string_append (&decl, "[");
+ if (**mangled != '_')
+ success = demangle_template_value_parm (work, mangled, &decl,
+ tk_integral);
+ if (**mangled == '_')
+ ++(*mangled);
+ string_append (&decl, "]");
+ break;
+ }
+
+ /* A back reference to a previously seen type */
+ case 'T':
+ (*mangled)++;
+ if (!get_count (mangled, &n) || n >= work -> ntypes)
+ {
+ success = 0;
+ }
+ else
+ {
+ remembered_type = work -> typevec[n];
+ mangled = &remembered_type;
+ }
+ break;
+
+ /* A function */
+ case 'F':
+ (*mangled)++;
+ if (!STRING_EMPTY (&decl)
+ && (decl.b[0] == '*' || decl.b[0] == '&'))
+ {
+ string_prepend (&decl, "(");
+ string_append (&decl, ")");
+ }
+ /* After picking off the function args, we expect to either find the
+ function return type (preceded by an '_') or the end of the
+ string. */
+ if (!demangle_nested_args (work, mangled, &decl)
+ || (**mangled != '_' && **mangled != '\0'))
+ {
+ success = 0;
+ break;
+ }
+ if (success && (**mangled == '_'))
+ (*mangled)++;
+ break;
+
+ case 'M':
+ case 'O':
+ {
+ type_quals = TYPE_UNQUALIFIED;
+
+ member = **mangled == 'M';
+ (*mangled)++;
+ if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
+ {
+ success = 0;
+ break;
+ }
+
+ string_append (&decl, ")");
+ string_prepend (&decl, SCOPE_STRING (work));
+ if (isdigit ((unsigned char)**mangled))
+ {
+ n = consume_count (mangled);
+ if (n == -1
+ || (int) strlen (*mangled) < n)
+ {
+ success = 0;
+ break;
+ }
+ string_prependn (&decl, *mangled, n);
+ *mangled += n;
+ }
+ else
+ {
+ string temp;
+ string_init (&temp);
+ success = demangle_template (work, mangled, &temp,
+ NULL, 1, 1);
+ if (success)
+ {
+ string_prependn (&decl, temp.b, temp.p - temp.b);
+ string_clear (&temp);
+ }
+ else
+ break;
+ }
+ string_prepend (&decl, "(");
+ if (member)
+ {
+ switch (**mangled)
+ {
+ case 'C':
+ case 'V':
+ case 'u':
+ type_quals |= code_for_qualifier (**mangled);
+ (*mangled)++;
+ break;
+
+ default:
+ break;
+ }
+
+ if (*(*mangled)++ != 'F')
+ {
+ success = 0;
+ break;
+ }
+ }
+ if ((member && !demangle_nested_args (work, mangled, &decl))
+ || **mangled != '_')
+ {
+ success = 0;
+ break;
+ }
+ (*mangled)++;
+ if (! PRINT_ANSI_QUALIFIERS)
+ {
+ break;
+ }
+ if (type_quals != TYPE_UNQUALIFIED)
+ {
+ APPEND_BLANK (&decl);
+ string_append (&decl, qualifier_string (type_quals));
+ }
+ break;
+ }
+ case 'G':
+ (*mangled)++;
+ break;
+
+ case 'C':
+ case 'V':
+ case 'u':
+ if (PRINT_ANSI_QUALIFIERS)
+ {
+ if (!STRING_EMPTY (&decl))
+ string_prepend (&decl, " ");
+
+ string_prepend (&decl, demangle_qualifier (**mangled));
+ }
+ (*mangled)++;
+ break;
+ /*
+ }
+ */
+
+ /* fall through */
+ default:
+ done = 1;
+ break;
+ }
+ }
+
+ if (success) switch (**mangled)
+ {
+ /* A qualified name, such as "Outer::Inner". */
+ case 'Q':
+ case 'K':
+ {
+ success = demangle_qualified (work, mangled, result, 0, 1);
+ break;
+ }
+
+ /* A back reference to a previously seen squangled type */
+ case 'B':
+ (*mangled)++;
+ if (!get_count (mangled, &n) || n >= work -> numb)
+ success = 0;
+ else
+ string_append (result, work->btypevec[n]);
+ break;
+
+ case 'X':
+ case 'Y':
+ /* A template parm. We substitute the corresponding argument. */
+ {
+ int idx;
+
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+
+ if (idx == -1
+ || (work->tmpl_argvec && idx >= work->ntmpl_args)
+ || consume_count_with_underscores (mangled) == -1)
+ {
+ success = 0;
+ break;
+ }
+
+ if (work->tmpl_argvec)
+ string_append (result, work->tmpl_argvec[idx]);
+ else
+ {
+ char buf[10];
+ sprintf(buf, "T%d", idx);
+ string_append (result, buf);
+ }
+
+ success = 1;
+ }
+ break;
+
+ default:
+ success = demangle_fund_type (work, mangled, result);
+ if (tk == tk_none)
+ tk = (type_kind_t) success;
+ break;
+ }
+
+ if (success)
+ {
+ if (!STRING_EMPTY (&decl))
+ {
+ string_append (result, " ");
+ string_appends (result, &decl);
+ }
+ }
+ else
+ string_delete (result);
+ string_delete (&decl);
+
+ if (success)
+ /* Assume an integral type, if we're not sure. */
+ return (int) ((tk == tk_none) ? tk_integral : tk);
+ else
+ return 0;
+}
+
+/* Given a pointer to a type string that represents a fundamental type
+ argument (int, long, unsigned int, etc) in TYPE, a pointer to the
+ string in which the demangled output is being built in RESULT, and
+ the WORK structure, decode the types and add them to the result.
+
+ For example:
+
+ "Ci" => "const int"
+ "Sl" => "signed long"
+ "CUs" => "const unsigned short"
+
+ The value returned is really a type_kind_t. */
+
+static int
+demangle_fund_type (work, mangled, result)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+{
+ int done = 0;
+ int success = 1;
+ char buf[10];
+ int dec = 0;
+ string btype;
+ type_kind_t tk = tk_integral;
+
+ string_init (&btype);
+
+ /* First pick off any type qualifiers. There can be more than one. */
+
+ while (!done)
+ {
+ switch (**mangled)
+ {
+ case 'C':
+ case 'V':
+ case 'u':
+ if (PRINT_ANSI_QUALIFIERS)
+ {
+ if (!STRING_EMPTY (result))
+ string_prepend (result, " ");
+ string_prepend (result, demangle_qualifier (**mangled));
+ }
+ (*mangled)++;
+ break;
+ case 'U':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "unsigned");
+ break;
+ case 'S': /* signed char only */
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "signed");
+ break;
+ case 'J':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "__complex");
+ break;
+ default:
+ done = 1;
+ break;
+ }
+ }
+
+ /* Now pick off the fundamental type. There can be only one. */
+
+ switch (**mangled)
+ {
+ case '\0':
+ case '_':
+ break;
+ case 'v':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "void");
+ break;
+ case 'x':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "long long");
+ break;
+ case 'l':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "long");
+ break;
+ case 'i':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "int");
+ break;
+ case 's':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "short");
+ break;
+ case 'b':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "bool");
+ tk = tk_bool;
+ break;
+ case 'c':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "char");
+ tk = tk_char;
+ break;
+ case 'w':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "wchar_t");
+ tk = tk_char;
+ break;
+ case 'r':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "long double");
+ tk = tk_real;
+ break;
+ case 'd':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "double");
+ tk = tk_real;
+ break;
+ case 'f':
+ (*mangled)++;
+ APPEND_BLANK (result);
+ string_append (result, "float");
+ tk = tk_real;
+ break;
+ case 'G':
+ (*mangled)++;
+ if (!isdigit ((unsigned char)**mangled))
+ {
+ success = 0;
+ break;
+ }
+ case 'I':
+ ++(*mangled);
+ if (**mangled == '_')
+ {
+ int i;
+ ++(*mangled);
+ for (i = 0;
+ (i < sizeof (buf) - 1 && **mangled && **mangled != '_');
+ ++(*mangled), ++i)
+ buf[i] = **mangled;
+ if (**mangled != '_')
+ {
+ success = 0;
+ break;
+ }
+ buf[i] = '\0';
+ ++(*mangled);
+ }
+ else
+ {
+ strncpy (buf, *mangled, 2);
+ buf[2] = '\0';
+ *mangled += 2;
+ }
+ sscanf (buf, "%x", &dec);
+ sprintf (buf, "int%i_t", dec);
+ APPEND_BLANK (result);
+ string_append (result, buf);
+ break;
+
+ /* fall through */
+ /* An explicit type, such as "6mytype" or "7integer" */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ int bindex = register_Btype (work);
+ string btype;
+ string_init (&btype);
+ if (demangle_class_name (work, mangled, &btype)) {
+ remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+ APPEND_BLANK (result);
+ string_appends (result, &btype);
+ }
+ else
+ success = 0;
+ string_delete (&btype);
+ break;
+ }
+ case 't':
+ {
+ success = demangle_template (work, mangled, &btype, 0, 1, 1);
+ string_appends (result, &btype);
+ break;
+ }
+ default:
+ success = 0;
+ break;
+ }
+
+ return success ? ((int) tk) : 0;
+}
+
+
+/* Handle a template's value parameter for HP aCC (extension from ARM)
+ **mangled points to 'S' or 'U' */
+
+static int
+do_hpacc_template_const_value (work, mangled, result)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+{
+ int unsigned_const;
+
+ if (**mangled != 'U' && **mangled != 'S')
+ return 0;
+
+ unsigned_const = (**mangled == 'U');
+
+ (*mangled)++;
+
+ switch (**mangled)
+ {
+ case 'N':
+ string_append (result, "-");
+ /* fall through */
+ case 'P':
+ (*mangled)++;
+ break;
+ case 'M':
+ /* special case for -2^31 */
+ string_append (result, "-2147483648");
+ (*mangled)++;
+ return 1;
+ default:
+ return 0;
+ }
+
+ /* We have to be looking at an integer now */
+ if (!(isdigit ((unsigned char)**mangled)))
+ return 0;
+
+ /* We only deal with integral values for template
+ parameters -- so it's OK to look only for digits */
+ while (isdigit ((unsigned char)**mangled))
+ {
+ char_str[0] = **mangled;
+ string_append (result, char_str);
+ (*mangled)++;
+ }
+
+ if (unsigned_const)
+ string_append (result, "U");
+
+ /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
+ with L or LL suffixes. pai/1997-09-03 */
+
+ return 1; /* success */
+}
+
+/* Handle a template's literal parameter for HP aCC (extension from ARM)
+ **mangled is pointing to the 'A' */
+
+static int
+do_hpacc_template_literal (work, mangled, result)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+{
+ int literal_len = 0;
+ char * recurse;
+ char * recurse_dem;
+
+ if (**mangled != 'A')
+ return 0;
+
+ (*mangled)++;
+
+ literal_len = consume_count (mangled);
+
+ if (literal_len <= 0)
+ return 0;
+
+ /* Literal parameters are names of arrays, functions, etc. and the
+ canonical representation uses the address operator */
+ string_append (result, "&");
+
+ /* Now recursively demangle the literal name */
+ recurse = (char *) xmalloc (literal_len + 1);
+ memcpy (recurse, *mangled, literal_len);
+ recurse[literal_len] = '\000';
+
+ recurse_dem = cplus_demangle (recurse, work->options);
+
+ if (recurse_dem)
+ {
+ string_append (result, recurse_dem);
+ free (recurse_dem);
+ }
+ else
+ {
+ string_appendn (result, *mangled, literal_len);
+ }
+ (*mangled) += literal_len;
+ free (recurse);
+
+ return 1;
+}
+
+static int
+snarf_numeric_literal (args, arg)
+ const char ** args;
+ string * arg;
+{
+ if (**args == '-')
+ {
+ char_str[0] = '-';
+ string_append (arg, char_str);
+ (*args)++;
+ }
+ else if (**args == '+')
+ (*args)++;
+
+ if (!isdigit ((unsigned char)**args))
+ return 0;
+
+ while (isdigit ((unsigned char)**args))
+ {
+ char_str[0] = **args;
+ string_append (arg, char_str);
+ (*args)++;
+ }
+
+ return 1;
+}
+
+/* Demangle the next argument, given by MANGLED into RESULT, which
+ *should be an uninitialized* string. It will be initialized here,
+ and free'd should anything go wrong. */
+
+static int
+do_arg (work, mangled, result)
+ struct work_stuff *work;
+ const char **mangled;
+ string *result;
+{
+ /* Remember where we started so that we can record the type, for
+ non-squangling type remembering. */
+ const char *start = *mangled;
+
+ string_init (result);
+
+ if (work->nrepeats > 0)
+ {
+ --work->nrepeats;
+
+ if (work->previous_argument == 0)
+ return 0;
+
+ /* We want to reissue the previous type in this argument list. */
+ string_appends (result, work->previous_argument);
+ return 1;
+ }
+
+ if (**mangled == 'n')
+ {
+ /* A squangling-style repeat. */
+ (*mangled)++;
+ work->nrepeats = consume_count(mangled);
+
+ if (work->nrepeats <= 0)
+ /* This was not a repeat count after all. */
+ return 0;
+
+ if (work->nrepeats > 9)
+ {
+ if (**mangled != '_')
+ /* The repeat count should be followed by an '_' in this
+ case. */
+ return 0;
+ else
+ (*mangled)++;
+ }
+
+ /* Now, the repeat is all set up. */
+ return do_arg (work, mangled, result);
+ }
+
+ /* Save the result in WORK->previous_argument so that we can find it
+ if it's repeated. Note that saving START is not good enough: we
+ do not want to add additional types to the back-referenceable
+ type vector when processing a repeated type. */
+ if (work->previous_argument)
+ string_clear (work->previous_argument);
+ else
+ {
+ work->previous_argument = (string*) xmalloc (sizeof (string));
+ string_init (work->previous_argument);
+ }
+
+ if (!do_type (work, mangled, work->previous_argument))
+ return 0;
+
+ string_appends (result, work->previous_argument);
+
+ remember_type (work, start, *mangled - start);
+ return 1;
+}
+
+static void
+remember_type (work, start, len)
+ struct work_stuff *work;
+ const char *start;
+ int len;
+{
+ char *tem;
+
+ if (work->forgetting_types)
+ return;
+
+ if (work -> ntypes >= work -> typevec_size)
+ {
+ if (work -> typevec_size == 0)
+ {
+ work -> typevec_size = 3;
+ work -> typevec
+ = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
+ }
+ else
+ {
+ work -> typevec_size *= 2;
+ work -> typevec
+ = (char **) xrealloc ((char *)work -> typevec,
+ sizeof (char *) * work -> typevec_size);
+ }
+ }
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> typevec[work -> ntypes++] = tem;
+}
+
+
+/* Remember a K type class qualifier. */
+static void
+remember_Ktype (work, start, len)
+ struct work_stuff *work;
+ const char *start;
+ int len;
+{
+ char *tem;
+
+ if (work -> numk >= work -> ksize)
+ {
+ if (work -> ksize == 0)
+ {
+ work -> ksize = 5;
+ work -> ktypevec
+ = (char **) xmalloc (sizeof (char *) * work -> ksize);
+ }
+ else
+ {
+ work -> ksize *= 2;
+ work -> ktypevec
+ = (char **) xrealloc ((char *)work -> ktypevec,
+ sizeof (char *) * work -> ksize);
+ }
+ }
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> ktypevec[work -> numk++] = tem;
+}
+
+/* Register a B code, and get an index for it. B codes are registered
+ as they are seen, rather than as they are completed, so map<temp<char> >
+ registers map<temp<char> > as B0, and temp<char> as B1 */
+
+static int
+register_Btype (work)
+ struct work_stuff *work;
+{
+ int ret;
+
+ if (work -> numb >= work -> bsize)
+ {
+ if (work -> bsize == 0)
+ {
+ work -> bsize = 5;
+ work -> btypevec
+ = (char **) xmalloc (sizeof (char *) * work -> bsize);
+ }
+ else
+ {
+ work -> bsize *= 2;
+ work -> btypevec
+ = (char **) xrealloc ((char *)work -> btypevec,
+ sizeof (char *) * work -> bsize);
+ }
+ }
+ ret = work -> numb++;
+ work -> btypevec[ret] = NULL;
+ return(ret);
+}
+
+/* Store a value into a previously registered B code type. */
+
+static void
+remember_Btype (work, start, len, index)
+ struct work_stuff *work;
+ const char *start;
+ int len, index;
+{
+ char *tem;
+
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> btypevec[index] = tem;
+}
+
+/* Lose all the info related to B and K type codes. */
+static void
+forget_B_and_K_types (work)
+ struct work_stuff *work;
+{
+ int i;
+
+ while (work -> numk > 0)
+ {
+ i = --(work -> numk);
+ if (work -> ktypevec[i] != NULL)
+ {
+ free (work -> ktypevec[i]);
+ work -> ktypevec[i] = NULL;
+ }
+ }
+
+ while (work -> numb > 0)
+ {
+ i = --(work -> numb);
+ if (work -> btypevec[i] != NULL)
+ {
+ free (work -> btypevec[i]);
+ work -> btypevec[i] = NULL;
+ }
+ }
+}
+/* Forget the remembered types, but not the type vector itself. */
+
+static void
+forget_types (work)
+ struct work_stuff *work;
+{
+ int i;
+
+ while (work -> ntypes > 0)
+ {
+ i = --(work -> ntypes);
+ if (work -> typevec[i] != NULL)
+ {
+ free (work -> typevec[i]);
+ work -> typevec[i] = NULL;
+ }
+ }
+}
+
+/* Process the argument list part of the signature, after any class spec
+ has been consumed, as well as the first 'F' character (if any). For
+ example:
+
+ "__als__3fooRT0" => process "RT0"
+ "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
+
+ DECLP must be already initialised, usually non-empty. It won't be freed
+ on failure.
+
+ Note that g++ differs significantly from ARM and lucid style mangling
+ with regards to references to previously seen types. For example, given
+ the source fragment:
+
+ class foo {
+ public:
+ foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
+ };
+
+ foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
+ void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
+
+ g++ produces the names:
+
+ __3fooiRT0iT2iT2
+ foo__FiR3fooiT1iT1
+
+ while lcc (and presumably other ARM style compilers as well) produces:
+
+ foo__FiR3fooT1T2T1T2
+ __ct__3fooFiR3fooT1T2T1T2
+
+ Note that g++ bases its type numbers starting at zero and counts all
+ previously seen types, while lucid/ARM bases its type numbers starting
+ at one and only considers types after it has seen the 'F' character
+ indicating the start of the function args. For lucid/ARM style, we
+ account for this difference by discarding any previously seen types when
+ we see the 'F' character, and subtracting one from the type number
+ reference.
+
+ */
+
+static int
+demangle_args (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ string arg;
+ int need_comma = 0;
+ int r;
+ int t;
+ const char *tem;
+ char temptype;
+
+ if (PRINT_ARG_TYPES)
+ {
+ string_append (declp, "(");
+ if (**mangled == '\0')
+ {
+ string_append (declp, "void");
+ }
+ }
+
+ while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
+ || work->nrepeats > 0)
+ {
+ if ((**mangled == 'N') || (**mangled == 'T'))
+ {
+ temptype = *(*mangled)++;
+
+ if (temptype == 'N')
+ {
+ if (!get_count (mangled, &r))
+ {
+ return (0);
+ }
+ }
+ else
+ {
+ r = 1;
+ }
+ if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
+ {
+ /* If we have 10 or more types we might have more than a 1 digit
+ index so we'll have to consume the whole count here. This
+ will lose if the next thing is a type name preceded by a
+ count but it's impossible to demangle that case properly
+ anyway. Eg if we already have 12 types is T12Pc "(..., type1,
+ Pc, ...)" or "(..., type12, char *, ...)" */
+ if ((t = consume_count(mangled)) <= 0)
+ {
+ return (0);
+ }
+ }
+ else
+ {
+ if (!get_count (mangled, &t))
+ {
+ return (0);
+ }
+ }
+ if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
+ {
+ t--;
+ }
+ /* Validate the type index. Protect against illegal indices from
+ malformed type strings. */
+ if ((t < 0) || (t >= work -> ntypes))
+ {
+ return (0);
+ }
+ while (work->nrepeats > 0 || --r >= 0)
+ {
+ tem = work -> typevec[t];
+ if (need_comma && PRINT_ARG_TYPES)
+ {
+ string_append (declp, ", ");
+ }
+ if (!do_arg (work, &tem, &arg))
+ {
+ return (0);
+ }
+ if (PRINT_ARG_TYPES)
+ {
+ string_appends (declp, &arg);
+ }
+ string_delete (&arg);
+ need_comma = 1;
+ }
+ }
+ else
+ {
+ if (need_comma && PRINT_ARG_TYPES)
+ string_append (declp, ", ");
+ if (!do_arg (work, mangled, &arg))
+ return (0);
+ if (PRINT_ARG_TYPES)
+ string_appends (declp, &arg);
+ string_delete (&arg);
+ need_comma = 1;
+ }
+ }
+
+ if (**mangled == 'e')
+ {
+ (*mangled)++;
+ if (PRINT_ARG_TYPES)
+ {
+ if (need_comma)
+ {
+ string_append (declp, ",");
+ }
+ string_append (declp, "...");
+ }
+ }
+
+ if (PRINT_ARG_TYPES)
+ {
+ string_append (declp, ")");
+ }
+ return (1);
+}
+
+/* Like demangle_args, but for demangling the argument lists of function
+ and method pointers or references, not top-level declarations. */
+
+static int
+demangle_nested_args (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ string* saved_previous_argument;
+ int result;
+ int saved_nrepeats;
+
+ /* The G++ name-mangling algorithm does not remember types on nested
+ argument lists, unless -fsquangling is used, and in that case the
+ type vector updated by remember_type is not used. So, we turn
+ off remembering of types here. */
+ ++work->forgetting_types;
+
+ /* For the repeat codes used with -fsquangling, we must keep track of
+ the last argument. */
+ saved_previous_argument = work->previous_argument;
+ saved_nrepeats = work->nrepeats;
+ work->previous_argument = 0;
+ work->nrepeats = 0;
+
+ /* Actually demangle the arguments. */
+ result = demangle_args (work, mangled, declp);
+
+ /* Restore the previous_argument field. */
+ if (work->previous_argument)
+ string_delete (work->previous_argument);
+ work->previous_argument = saved_previous_argument;
+ --work->forgetting_types;
+ work->nrepeats = saved_nrepeats;
+
+ return result;
+}
+
+static void
+demangle_function_name (work, mangled, declp, scan)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+ const char *scan;
+{
+ size_t i;
+ string type;
+ const char *tem;
+
+ string_appendn (declp, (*mangled), scan - (*mangled));
+ string_need (declp, 1);
+ *(declp -> p) = '\0';
+
+ /* Consume the function name, including the "__" separating the name
+ from the signature. We are guaranteed that SCAN points to the
+ separator. */
+
+ (*mangled) = scan + 2;
+ /* We may be looking at an instantiation of a template function:
+ foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
+ following _F marks the start of the function arguments. Handle
+ the template arguments first. */
+
+ if (HP_DEMANGLING && (**mangled == 'X'))
+ {
+ demangle_arm_hp_template (work, mangled, 0, declp);
+ /* This leaves MANGLED pointing to the 'F' marking func args */
+ }
+
+ if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
+ {
+
+ /* See if we have an ARM style constructor or destructor operator.
+ If so, then just record it, clear the decl, and return.
+ We can't build the actual constructor/destructor decl until later,
+ when we recover the class name from the signature. */
+
+ if (strcmp (declp -> b, "__ct") == 0)
+ {
+ work -> constructor += 1;
+ string_clear (declp);
+ return;
+ }
+ else if (strcmp (declp -> b, "__dt") == 0)
+ {
+ work -> destructor += 1;
+ string_clear (declp);
+ return;
+ }
+ }
+
+ if (declp->p - declp->b >= 3
+ && declp->b[0] == 'o'
+ && declp->b[1] == 'p'
+ && strchr (cplus_markers, declp->b[2]) != NULL)
+ {
+ /* see if it's an assignment expression */
+ if (declp->p - declp->b >= 10 /* op$assign_ */
+ && memcmp (declp->b + 3, "assign_", 7) == 0)
+ {
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ int len = declp->p - declp->b - 10;
+ if ((int) strlen (optable[i].in) == len
+ && memcmp (optable[i].in, declp->b + 10, len) == 0)
+ {
+ string_clear (declp);
+ string_append (declp, "operator");
+ string_append (declp, optable[i].out);
+ string_append (declp, "=");
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ int len = declp->p - declp->b - 3;
+ if ((int) strlen (optable[i].in) == len
+ && memcmp (optable[i].in, declp->b + 3, len) == 0)
+ {
+ string_clear (declp);
+ string_append (declp, "operator");
+ string_append (declp, optable[i].out);
+ break;
+ }
+ }
+ }
+ }
+ else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
+ && strchr (cplus_markers, declp->b[4]) != NULL)
+ {
+ /* type conversion operator */
+ tem = declp->b + 5;
+ if (do_type (work, &tem, &type))
+ {
+ string_clear (declp);
+ string_append (declp, "operator ");
+ string_appends (declp, &type);
+ string_delete (&type);
+ }
+ }
+ else if (declp->b[0] == '_' && declp->b[1] == '_'
+ && declp->b[2] == 'o' && declp->b[3] == 'p')
+ {
+ /* ANSI. */
+ /* type conversion operator. */
+ tem = declp->b + 4;
+ if (do_type (work, &tem, &type))
+ {
+ string_clear (declp);
+ string_append (declp, "operator ");
+ string_appends (declp, &type);
+ string_delete (&type);
+ }
+ }
+ else if (declp->b[0] == '_' && declp->b[1] == '_'
+ && declp->b[2] >= 'a' && declp->b[2] <= 'z'
+ && declp->b[3] >= 'a' && declp->b[3] <= 'z')
+ {
+ if (declp->b[4] == '\0')
+ {
+ /* Operator. */
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ if (strlen (optable[i].in) == 2
+ && memcmp (optable[i].in, declp->b + 2, 2) == 0)
+ {
+ string_clear (declp);
+ string_append (declp, "operator");
+ string_append (declp, optable[i].out);
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (declp->b[2] == 'a' && declp->b[5] == '\0')
+ {
+ /* Assignment. */
+ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
+ {
+ if (strlen (optable[i].in) == 3
+ && memcmp (optable[i].in, declp->b + 2, 3) == 0)
+ {
+ string_clear (declp);
+ string_append (declp, "operator");
+ string_append (declp, optable[i].out);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+/* a mini string-handling package */
+
+static void
+string_need (s, n)
+ string *s;
+ int n;
+{
+ int tem;
+
+ if (s->b == NULL)
+ {
+ if (n < 32)
+ {
+ n = 32;
+ }
+ s->p = s->b = xmalloc (n);
+ s->e = s->b + n;
+ }
+ else if (s->e - s->p < n)
+ {
+ tem = s->p - s->b;
+ n += tem;
+ n *= 2;
+ s->b = xrealloc (s->b, n);
+ s->p = s->b + tem;
+ s->e = s->b + n;
+ }
+}
+
+static void
+string_delete (s)
+ string *s;
+{
+ if (s->b != NULL)
+ {
+ free (s->b);
+ s->b = s->e = s->p = NULL;
+ }
+}
+
+static void
+string_init (s)
+ string *s;
+{
+ s->b = s->p = s->e = NULL;
+}
+
+static void
+string_clear (s)
+ string *s;
+{
+ s->p = s->b;
+}
+
+#if 0
+
+static int
+string_empty (s)
+ string *s;
+{
+ return (s->b == s->p);
+}
+
+#endif
+
+static void
+string_append (p, s)
+ string *p;
+ const char *s;
+{
+ int n;
+ if (s == NULL || *s == '\0')
+ return;
+ n = strlen (s);
+ string_need (p, n);
+ memcpy (p->p, s, n);
+ p->p += n;
+}
+
+static void
+string_appends (p, s)
+ string *p, *s;
+{
+ int n;
+
+ if (s->b != s->p)
+ {
+ n = s->p - s->b;
+ string_need (p, n);
+ memcpy (p->p, s->b, n);
+ p->p += n;
+ }
+}
+
+static void
+string_appendn (p, s, n)
+ string *p;
+ const char *s;
+ int n;
+{
+ if (n != 0)
+ {
+ string_need (p, n);
+ memcpy (p->p, s, n);
+ p->p += n;
+ }
+}
+
+static void
+string_prepend (p, s)
+ string *p;
+ const char *s;
+{
+ if (s != NULL && *s != '\0')
+ {
+ string_prependn (p, s, strlen (s));
+ }
+}
+
+static void
+string_prepends (p, s)
+ string *p, *s;
+{
+ if (s->b != s->p)
+ {
+ string_prependn (p, s->b, s->p - s->b);
+ }
+}
+
+static void
+string_prependn (p, s, n)
+ string *p;
+ const char *s;
+ int n;
+{
+ char *q;
+
+ if (n != 0)
+ {
+ string_need (p, n);
+ for (q = p->p - 1; q >= p->b; q--)
+ {
+ q[n] = q[0];
+ }
+ memcpy (p->b, s, n);
+ p->p += n;
+ }
+}
+
+/* To generate a standalone demangler program for testing purposes,
+ just compile and link this file with -DMAIN and libiberty.a. When
+ run, it demangles each command line arg, or each stdin string, and
+ prints the result on stdout. */
+
+#ifdef MAIN
+
+#include "getopt.h"
+
+static char *program_name;
+static char *program_version = VERSION;
+static int flags = DMGL_PARAMS | DMGL_ANSI;
+
+static void demangle_it PARAMS ((char *));
+static void usage PARAMS ((FILE *, int));
+static void fatal PARAMS ((char *));
+
+static void
+demangle_it (mangled_name)
+ char *mangled_name;
+{
+ char *result;
+
+ result = cplus_demangle (mangled_name, flags);
+ if (result == NULL)
+ {
+ printf ("%s\n", mangled_name);
+ }
+ else
+ {
+ printf ("%s\n", result);
+ free (result);
+ }
+}
+
+static void
+usage (stream, status)
+ FILE *stream;
+ int status;
+{
+ fprintf (stream, "\
+Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
+ [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
+ [--help] [--version] [arg...]\n",
+ program_name);
+ exit (status);
+}
+
+#define MBUF_SIZE 32767
+char mbuffer[MBUF_SIZE];
+
+/* Defined in the automatically-generated underscore.c. */
+extern int prepends_underscore;
+
+int strip_underscore = 0;
+
+static struct option long_options[] = {
+ {"strip-underscores", no_argument, 0, '_'},
+ {"format", required_argument, 0, 's'},
+ {"help", no_argument, 0, 'h'},
+ {"java", no_argument, 0, 'j'},
+ {"no-strip-underscores", no_argument, 0, 'n'},
+ {"version", no_argument, 0, 'v'},
+ {0, no_argument, 0, 0}
+};
+
+/* More 'friendly' abort that prints the line and file.
+ config.h can #define abort fancy_abort if you like that sort of thing. */
+
+void
+fancy_abort ()
+{
+ fatal ("Internal gcc abort.");
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *result;
+ int c;
+
+ program_name = argv[0];
+
+ strip_underscore = prepends_underscore;
+
+ while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
+ {
+ switch (c)
+ {
+ case '?':
+ usage (stderr, 1);
+ break;
+ case 'h':
+ usage (stdout, 0);
+ case 'n':
+ strip_underscore = 0;
+ break;
+ case 'v':
+ printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
+ exit (0);
+ case '_':
+ strip_underscore = 1;
+ break;
+ case 'j':
+ flags |= DMGL_JAVA;
+ break;
+ case 's':
+ if (strcmp (optarg, "gnu") == 0)
+ {
+ current_demangling_style = gnu_demangling;
+ }
+ else if (strcmp (optarg, "lucid") == 0)
+ {
+ current_demangling_style = lucid_demangling;
+ }
+ else if (strcmp (optarg, "arm") == 0)
+ {
+ current_demangling_style = arm_demangling;
+ }
+ else if (strcmp (optarg, "hp") == 0)
+ {
+ current_demangling_style = hp_demangling;
+ }
+ else if (strcmp (optarg, "edg") == 0)
+ {
+ current_demangling_style = edg_demangling;
+ }
+ else
+ {
+ fprintf (stderr, "%s: unknown demangling style `%s'\n",
+ program_name, optarg);
+ exit (1);
+ }
+ break;
+ }
+ }
+
+ if (optind < argc)
+ {
+ for ( ; optind < argc; optind++)
+ {
+ demangle_it (argv[optind]);
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ int i = 0;
+ c = getchar ();
+ /* Try to read a label. */
+ while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
+ c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
+ c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
+ /* the ones in the 2nd & 3rd lines were added to handle
+ HP aCC template specialization manglings */
+ {
+ if (i >= MBUF_SIZE-1)
+ break;
+ mbuffer[i++] = c;
+ c = getchar ();
+ }
+ if (i > 0)
+ {
+ int skip_first = 0;
+
+ if (mbuffer[0] == '.')
+ ++skip_first;
+ if (strip_underscore && mbuffer[skip_first] == '_')
+ ++skip_first;
+
+ if (skip_first > i)
+ skip_first = i;
+
+ mbuffer[i] = 0;
+
+ result = cplus_demangle (mbuffer + skip_first, flags);
+ if (result)
+ {
+ if (mbuffer[0] == '.')
+ putc ('.', stdout);
+ fputs (result, stdout);
+ free (result);
+ }
+ else
+ fputs (mbuffer, stdout);
+
+ fflush (stdout);
+ }
+ if (c == EOF)
+ break;
+ putchar (c);
+ }
+ }
+
+ exit (0);
+}
+
+static void
+fatal (str)
+ char *str;
+{
+ fprintf (stderr, "%s: %s\n", program_name, str);
+ exit (1);
+}
+
+PTR
+xmalloc (size)
+ size_t size;
+{
+ register PTR value = (PTR) malloc (size);
+ if (value == 0)
+ fatal ("virtual memory exhausted");
+ return value;
+}
+
+PTR
+xrealloc (ptr, size)
+ PTR ptr;
+ size_t size;
+{
+ register PTR value = (PTR) realloc (ptr, size);
+ if (value == 0)
+ fatal ("virtual memory exhausted");
+ return value;
+}
+#endif /* main */
diff --git a/libiberty/fdmatch.c b/libiberty/fdmatch.c
new file mode 100644
index 00000000000..7af039f5a2b
--- /dev/null
+++ b/libiberty/fdmatch.c
@@ -0,0 +1,73 @@
+/* Compare two open file descriptors to see if they refer to the same file.
+ Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/*
+
+NAME
+
+ fdmatch -- see if two file descriptors refer to same file
+
+SYNOPSIS
+
+ int fdmatch (int fd1, int fd2)
+
+DESCRIPTION
+
+ Check to see if two open file descriptors refer to the same file.
+ This is useful, for example, when we have an open file descriptor
+ for an unnamed file, and the name of a file that we believe to
+ correspond to that fd. This can happen when we are exec'd with
+ an already open file (stdout for example) or from the SVR4 /proc
+ calls that return open file descriptors for mapped address spaces.
+ All we have to do is open the file by name and check the two file
+ descriptors for a match, which is done by comparing major&minor
+ device numbers and inode numbers.
+
+BUGS
+
+ (FIXME: does this work for networks?)
+ It works for NFS, which assigns a device number to each mount.
+
+*/
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+int fdmatch (fd1, fd2)
+ int fd1;
+ int fd2;
+{
+ struct stat sbuf1;
+ struct stat sbuf2;
+
+ if ((fstat (fd1, &sbuf1) == 0) &&
+ (fstat (fd2, &sbuf2) == 0) &&
+ (sbuf1.st_dev == sbuf2.st_dev) &&
+ (sbuf1.st_ino == sbuf2.st_ino))
+ {
+ return (1);
+ }
+ else
+ {
+ return (0);
+ }
+}
diff --git a/libiberty/floatformat.c b/libiberty/floatformat.c
new file mode 100644
index 00000000000..c4f21e4ce89
--- /dev/null
+++ b/libiberty/floatformat.c
@@ -0,0 +1,403 @@
+/* IEEE floating point support routines, for GDB, the GNU Debugger.
+ Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "floatformat.h"
+#include <math.h> /* ldexp */
+#ifdef __STDC__
+#include <stddef.h>
+extern void *memcpy (void *s1, const void *s2, size_t n);
+extern void *memset (void *s, int c, size_t n);
+#else
+extern char *memcpy ();
+extern char *memset ();
+#endif
+
+/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
+ going to bother with trying to muck around with whether it is defined in
+ a system header, what we do if not, etc. */
+#define FLOATFORMAT_CHAR_BIT 8
+
+/* floatformats for IEEE single and double, big and little endian. */
+const struct floatformat floatformat_ieee_single_big =
+{
+ floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, floatformat_intbit_no
+};
+const struct floatformat floatformat_ieee_single_little =
+{
+ floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, floatformat_intbit_no
+};
+const struct floatformat floatformat_ieee_double_big =
+{
+ floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no
+};
+const struct floatformat floatformat_ieee_double_little =
+{
+ floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no
+};
+
+/* floatformat for IEEE double, little endian byte order, with big endian word
+ ordering, as on the ARM. */
+
+const struct floatformat floatformat_ieee_double_littlebyte_bigword =
+{
+ floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no
+};
+
+const struct floatformat floatformat_i387_ext =
+{
+ floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
+ floatformat_intbit_yes
+};
+const struct floatformat floatformat_m68881_ext =
+{
+ /* Note that the bits from 16 to 31 are unused. */
+ floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, floatformat_intbit_yes
+};
+const struct floatformat floatformat_i960_ext =
+{
+ /* Note that the bits from 0 to 15 are unused. */
+ floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
+ floatformat_intbit_yes
+};
+const struct floatformat floatformat_m88110_ext =
+{
+#ifdef HARRIS_FLOAT_FORMAT
+ /* Harris uses raw format 128 bytes long, but the number is just an ieee
+ double, and the last 64 bits are wasted. */
+ floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52,
+ floatformat_intbit_no
+#else
+ floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
+ floatformat_intbit_yes
+#endif /* HARRIS_FLOAT_FORMAT */
+};
+const struct floatformat floatformat_arm_ext =
+{
+ /* Bits 1 to 16 are unused. */
+ floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
+ floatformat_intbit_yes
+};
+
+static unsigned long get_field PARAMS ((unsigned char *,
+ enum floatformat_byteorders,
+ unsigned int,
+ unsigned int,
+ unsigned int));
+
+/* Extract a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static unsigned long
+get_field (data, order, total_len, start, len)
+ unsigned char *data;
+ enum floatformat_byteorders order;
+ unsigned int total_len;
+ unsigned int start;
+ unsigned int len;
+{
+ unsigned long result;
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ result = *(data + cur_byte) >> (-cur_bitshift);
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ /* This is the last byte; zero out the bits which are not part of
+ this field. */
+ result |=
+ (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
+ << cur_bitshift;
+ else
+ result |= *(data + cur_byte) << cur_bitshift;
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+ return result;
+}
+
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* Convert from FMT to a double.
+ FROM is the address of the extended float.
+ Store the double in *TO. */
+
+void
+floatformat_to_double (fmt, from, to)
+ const struct floatformat *fmt;
+ char *from;
+ double *to;
+{
+ unsigned char *ufrom = (unsigned char *)from;
+ double dto;
+ long exponent;
+ unsigned long mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ int special_exponent; /* It's a NaN, denorm or zero */
+
+ exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ fmt->exp_start, fmt->exp_len);
+ /* Note that if exponent indicates a NaN, we can't really do anything useful
+ (not knowing if the host has NaN's, or how to build one). So it will
+ end up as an infinity or something close; that is OK. */
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ dto = 0.0;
+
+ special_exponent = exponent == 0 || exponent == fmt->exp_nan;
+
+ /* Don't bias zero's, denorms or NaNs. */
+ if (!special_exponent)
+ exponent -= fmt->exp_bias;
+
+ /* Build the result algebraically. Might go infinite, underflow, etc;
+ who cares. */
+
+ /* If this format uses a hidden bit, explicitly add it in now. Otherwise,
+ increment the exponent by one to account for the integer bit. */
+
+ if (!special_exponent)
+ {
+ if (fmt->intbit == floatformat_intbit_no)
+ dto = ldexp (1.0, exponent);
+ else
+ exponent++;
+ }
+
+ while (mant_bits_left > 0)
+ {
+ mant_bits = min (mant_bits_left, 32);
+
+ mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits);
+
+ dto += ldexp ((double)mant, exponent - mant_bits);
+ exponent -= mant_bits;
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+
+ /* Negate it if negative. */
+ if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
+ dto = -dto;
+ *to = dto;
+}
+
+static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders,
+ unsigned int,
+ unsigned int,
+ unsigned int,
+ unsigned long));
+
+/* Set a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static void
+put_field (data, order, total_len, start, len, stuff_to_put)
+ unsigned char *data;
+ enum floatformat_byteorders order;
+ unsigned int total_len;
+ unsigned int start;
+ unsigned int len;
+ unsigned long stuff_to_put;
+{
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ *(data + cur_byte) &=
+ ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
+ *(data + cur_byte) |=
+ (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ {
+ /* This is the last byte. */
+ *(data + cur_byte) &=
+ ~((1 << (len - cur_bitshift)) - 1);
+ *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
+ }
+ else
+ *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
+ & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+}
+
+/* The converse: convert the double *FROM to an extended float
+ and store where TO points. Neither FROM nor TO have any alignment
+ restrictions. */
+
+void
+floatformat_from_double (fmt, from, to)
+ const struct floatformat *fmt;
+ double *from;
+ char *to;
+{
+ double dfrom;
+ int exponent;
+ double mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ unsigned char *uto = (unsigned char *)to;
+
+ memcpy (&dfrom, from, sizeof (dfrom));
+ memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
+ if (dfrom == 0)
+ return; /* Result is zero */
+ if (dfrom != dfrom)
+ {
+ /* From is NaN */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Be sure it's not infinity, but NaN value is irrel */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ 32, 1);
+ return;
+ }
+
+ /* If negative, set the sign bit. */
+ if (dfrom < 0)
+ {
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
+ dfrom = -dfrom;
+ }
+
+ /* How to tell an infinity from an ordinary number? FIXME-someday */
+
+ mant = frexp (dfrom, &exponent);
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
+ exponent + fmt->exp_bias - 1);
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ while (mant_bits_left > 0)
+ {
+ unsigned long mant_long;
+ mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
+
+ mant *= 4294967296.0;
+ mant_long = (unsigned long)mant;
+ mant -= mant_long;
+
+ /* If the integer bit is implicit, then we need to discard it.
+ If we are discarding a zero, we should be (but are not) creating
+ a denormalized number which means adjusting the exponent
+ (I think). */
+ if (mant_bits_left == fmt->man_len
+ && fmt->intbit == floatformat_intbit_no)
+ {
+ mant_long &= 0x7fffffff;
+ mant_bits -= 1;
+ }
+ else if (mant_bits < 32)
+ {
+ /* The bits we want are in the most significant MANT_BITS bits of
+ mant_long. Move them to the least significant. */
+ mant_long >>= 32 - mant_bits;
+ }
+
+ put_field (uto, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits, mant_long);
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+}
+
+
+#ifdef IEEE_DEBUG
+
+/* This is to be run on a host which uses IEEE floating point. */
+
+void
+ieee_test (n)
+ double n;
+{
+ double result;
+ char exten[16];
+
+ floatformat_to_double (&floatformat_ieee_double_big, &n, &result);
+ if (n != result)
+ printf ("Differ(to): %.20g -> %.20g\n", n, result);
+ floatformat_from_double (&floatformat_ieee_double_big, &n, &result);
+ if (n != result)
+ printf ("Differ(from): %.20g -> %.20g\n", n, result);
+
+ floatformat_from_double (&floatformat_m68881_ext, &n, exten);
+ floatformat_to_double (&floatformat_m68881_ext, exten, &result);
+ if (n != result)
+ printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
+
+#if IEEE_DEBUG > 1
+ /* This is to be run on a host which uses 68881 format. */
+ {
+ long double ex = *(long double *)exten;
+ if (ex != n)
+ printf ("Differ(from vs. extended): %.20g\n", n);
+ }
+#endif
+}
+
+int
+main ()
+{
+ ieee_test (0.5);
+ ieee_test (256.0);
+ ieee_test (0.12345);
+ ieee_test (234235.78907234);
+ ieee_test (-512.0);
+ ieee_test (-0.004321);
+ return 0;
+}
+#endif
diff --git a/libiberty/fnmatch.c b/libiberty/fnmatch.c
new file mode 100644
index 00000000000..0a9bfe6152b
--- /dev/null
+++ b/libiberty/fnmatch.c
@@ -0,0 +1,225 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#if defined (CONFIG_BROKETS)
+/* We use <config.h> instead of "config.h" so that a compilation
+ using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+ (which it would do because it found this file in $srcdir). */
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+/* This code to undef const added in libiberty. */
+#ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <errno.h>
+#include <fnmatch.h>
+#include <ctype.h>
+
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
+extern int errno;
+#endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ it matches, nonzero if not. */
+int
+fnmatch (pattern, string, flags)
+ const char *pattern;
+ const char *string;
+ int flags;
+{
+ register const char *p = pattern, *n = string;
+ register unsigned char c;
+
+/* Note that this evalutes C many times. */
+#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
+
+ while ((c = *p++) != '\0')
+ {
+ c = FOLD (c);
+
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_FILE_NAME) && *n == '/')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ {
+ c = *p++;
+ c = FOLD (c);
+ }
+ if (FOLD ((unsigned char)*n) != c)
+ return FNM_NOMATCH;
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
+ if (((flags & FNM_FILE_NAME) && *n == '/') ||
+ (c == '?' && *n == '\0'))
+ return FNM_NOMATCH;
+
+ if (c == '\0')
+ return 0;
+
+ {
+ unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ c1 = FOLD (c1);
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || FOLD ((unsigned char)*n) == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ return FNM_NOMATCH;
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return FNM_NOMATCH;
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ register unsigned char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ cstart = cend = *p++;
+
+ cstart = cend = FOLD (cstart);
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ c = FOLD (c);
+
+ if ((flags & FNM_FILE_NAME) && c == '/')
+ /* [/] can never match. */
+ return FNM_NOMATCH;
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return FNM_NOMATCH;
+ cend = FOLD (cend);
+
+ c = *p++;
+ }
+
+ if (FOLD ((unsigned char)*n) >= cstart
+ && FOLD ((unsigned char)*n) <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return FNM_NOMATCH;
+ break;
+
+ matched:;
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
+ if (not)
+ return FNM_NOMATCH;
+ }
+ break;
+
+ default:
+ if (c != FOLD ((unsigned char)*n))
+ return FNM_NOMATCH;
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return 0;
+
+ if ((flags & FNM_LEADING_DIR) && *n == '/')
+ /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
+ return 0;
+
+ return FNM_NOMATCH;
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
diff --git a/libiberty/getcwd.c b/libiberty/getcwd.c
new file mode 100644
index 00000000000..06d55c04f58
--- /dev/null
+++ b/libiberty/getcwd.c
@@ -0,0 +1,54 @@
+/* Emulate getcwd using getwd.
+ This function is in the public domain. */
+
+/*
+NAME
+ getcwd -- get absolute pathname for current working directory
+
+SYNOPSIS
+ char *getcwd (char pathname[len], len)
+
+DESCRIPTION
+ Copy the absolute pathname for the current working directory into
+ the supplied buffer and return a pointer to the buffer. If the
+ current directory's path doesn't fit in LEN characters, the result
+ is NULL and errno is set.
+
+BUGS
+ Emulated via the getwd() call, which is reasonable for most
+ systems that do not have getcwd().
+
+*/
+
+#include "config.h"
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+
+extern char *getwd ();
+extern int errno;
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+char *
+getcwd (buf, len)
+ char *buf;
+ int len;
+{
+ char ourbuf[MAXPATHLEN];
+ char *result;
+
+ result = getwd (ourbuf);
+ if (result) {
+ if (strlen (ourbuf) >= len) {
+ errno = ERANGE;
+ return 0;
+ }
+ strcpy (buf, ourbuf);
+ }
+ return buf;
+}
diff --git a/libiberty/getopt.c b/libiberty/getopt.c
new file mode 100644
index 00000000000..c41531e667d
--- /dev/null
+++ b/libiberty/getopt.c
@@ -0,0 +1,1056 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
+ Free Software Foundation, Inc.
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+ When compiling libc, the _ macro is predefined. */
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid) gettext (msgid)
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# if HAVE_STRINGS_H
+# include <strings.h>
+# endif
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+ is valid for the getopt call we must make sure that the ARGV passed
+ to getopt is that one passed to the process. */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+ /* XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+ original_argc = argc;
+ original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#ifdef _LIBC
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#ifdef _LIBC
+ if (posixly_correct == NULL
+ && argc == original_argc && argv == original_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#ifdef _LIBC
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (opterr)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/libiberty/getopt1.c b/libiberty/getopt1.c
new file mode 100644
index 00000000000..ff257374c33
--- /dev/null
+++ b/libiberty/getopt1.c
@@ -0,0 +1,190 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/libiberty/getpagesize.c b/libiberty/getpagesize.c
new file mode 100644
index 00000000000..564d6c02312
--- /dev/null
+++ b/libiberty/getpagesize.c
@@ -0,0 +1,96 @@
+/* Emulation of getpagesize() for systems that need it. */
+
+/*
+
+NAME
+
+ getpagesize -- return the number of bytes in page of memory
+
+SYNOPSIS
+
+ int getpagesize (void)
+
+DESCRIPTION
+
+ Returns the number of bytes in a page of memory. This is the
+ granularity of many of the system memory management routines.
+ No guarantee is made as to whether or not it is the same as the
+ basic memory management hardware page size.
+
+BUGS
+
+ Is intended as a reasonable replacement for systems where this
+ is not provided as a system call. The value of 4096 may or may
+ not be correct for the systems where it is returned as the default
+ value.
+
+*/
+
+#ifndef VMS
+
+#include "config.h"
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#undef GNU_OUR_PAGESIZE
+#if defined (HAVE_SYSCONF) && defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#ifdef _SC_PAGESIZE
+#define GNU_OUR_PAGESIZE sysconf(_SC_PAGESIZE)
+#endif
+#endif
+
+#ifndef GNU_OUR_PAGESIZE
+# ifdef PAGESIZE
+# define GNU_OUR_PAGESIZE PAGESIZE
+# else /* no PAGESIZE */
+# ifdef EXEC_PAGESIZE
+# define GNU_OUR_PAGESIZE EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define GNU_OUR_PAGESIZE (NBPG * CLSIZE)
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define GNU_OUR_PAGESIZE NBPC
+# else /* no NBPC */
+# define GNU_OUR_PAGESIZE 4096 /* Just punt and use reasonable value */
+# endif /* NBPC */
+# endif /* NBPG */
+# endif /* EXEC_PAGESIZE */
+# endif /* PAGESIZE */
+#endif /* GNU_OUR_PAGESIZE */
+
+int
+getpagesize ()
+{
+ return (GNU_OUR_PAGESIZE);
+}
+
+#else /* VMS */
+
+#if 0 /* older distributions of gcc-vms are missing <syidef.h> */
+#include <syidef.h>
+#endif
+#ifndef SYI$_PAGE_SIZE /* VMS V5.4 and earlier didn't have this yet */
+#define SYI$_PAGE_SIZE 4452
+#endif
+extern unsigned long lib$getsyi(const unsigned short *,...);
+
+int getpagesize ()
+{
+ long pagsiz = 0L;
+ unsigned short itmcod = SYI$_PAGE_SIZE;
+
+ (void) lib$getsyi (&itmcod, (void *) &pagsiz);
+ if (pagsiz == 0L)
+ pagsiz = 512L; /* VAX default */
+ return (int) pagsiz;
+}
+
+#endif /* VMS */
diff --git a/libiberty/getruntime.c b/libiberty/getruntime.c
new file mode 100644
index 00000000000..6e70773bd94
--- /dev/null
+++ b/libiberty/getruntime.c
@@ -0,0 +1,90 @@
+/* Return time used so far, in microseconds.
+ Copyright (C) 1994, 1999 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+/* There are several ways to get elapsed execution time; unfortunately no
+ single way is available for all host systems, nor are there reliable
+ ways to find out which way is correct for a given host. */
+
+#include <time.h>
+
+#ifdef HAVE_GETRUSAGE
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_TIMES
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/times.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* This is a fallback; if wrong, it will likely make obviously wrong
+ results. */
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1
+#endif
+
+#ifdef _SC_CLK_TCK
+#define GNU_HZ sysconf(_SC_CLK_TCK)
+#else
+#ifdef HZ
+#define GNU_HZ HZ
+#else
+#ifdef CLOCKS_PER_SEC
+#define GNU_HZ CLOCKS_PER_SEC
+#endif
+#endif
+#endif
+
+long
+get_run_time ()
+{
+#ifdef HAVE_GETRUSAGE
+ struct rusage rusage;
+
+ getrusage (0, &rusage);
+ return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
+ + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
+#else /* ! HAVE_GETRUSAGE */
+#ifdef HAVE_TIMES
+ struct tms tms;
+
+ times (&tms);
+ return (tms.tms_utime + tms.tms_stime) * (1000000 / GNU_HZ);
+#else /* ! HAVE_TIMES */
+ /* Fall back on clock and hope it's correctly implemented. */
+ const long clocks_per_sec = CLOCKS_PER_SEC;
+ if (clocks_per_sec <= 1000000)
+ return clock () * (1000000 / clocks_per_sec);
+ else
+ return clock () / clocks_per_sec;
+#endif /* HAVE_TIMES */
+#endif /* HAVE_GETRUSAGE */
+}
diff --git a/libiberty/hex.c b/libiberty/hex.c
new file mode 100644
index 00000000000..3a2eef03d4c
--- /dev/null
+++ b/libiberty/hex.c
@@ -0,0 +1,33 @@
+/* Hex character manipulation support.
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "libiberty.h"
+
+char _hex_value[_hex_array_size];
+
+void hex_init ()
+{
+ int i;
+ for (i = 0; i < _hex_array_size; i++)
+ _hex_value[i] = _hex_bad;
+ for (i = 0; i < 10; i++)
+ _hex_value['0' + i] = i;
+ for (i = 0; i < 6; i++)
+ _hex_value['a' + i] = _hex_value['A' + i] = 10 + i;
+}
diff --git a/libiberty/index.c b/libiberty/index.c
new file mode 100644
index 00000000000..e5a00f54d94
--- /dev/null
+++ b/libiberty/index.c
@@ -0,0 +1,11 @@
+/* Stub implementation of (obsolete) index(). */
+
+extern char * strchr();
+
+char *
+index (s, c)
+ char *s;
+ int c;
+{
+ return strchr (s, c);
+}
diff --git a/libiberty/insque.c b/libiberty/insque.c
new file mode 100644
index 00000000000..775019f8fff
--- /dev/null
+++ b/libiberty/insque.c
@@ -0,0 +1,50 @@
+/* insque(3C) routines
+ This file is in the public domain. */
+
+/*
+NAME
+ insque, remque -- insert, remove an element from a queue
+
+SYNOPSIS
+ struct qelem {
+ struct qelem *q_forw;
+ struct qelem *q_back;
+ char q_data[];
+ };
+
+ void insque (struct qelem *elem, struct qelem *pred)
+
+ void remque (struct qelem *elem)
+
+DESCRIPTION
+ Routines to manipulate queues built from doubly linked lists.
+ The insque routine inserts ELEM in the queue immediately after
+ PRED. The remque routine removes ELEM from its containing queue.
+*/
+
+
+struct qelem {
+ struct qelem *q_forw;
+ struct qelem *q_back;
+};
+
+
+void
+insque (elem, pred)
+ struct qelem *elem;
+ struct qelem *pred;
+{
+ elem -> q_forw = pred -> q_forw;
+ pred -> q_forw -> q_back = elem;
+ elem -> q_back = pred;
+ pred -> q_forw = elem;
+}
+
+
+void
+remque (elem)
+ struct qelem *elem;
+{
+ elem -> q_forw -> q_back = elem -> q_back;
+ elem -> q_back -> q_forw = elem -> q_forw;
+}
diff --git a/libiberty/makefile.dos b/libiberty/makefile.dos
new file mode 100644
index 00000000000..7eba62c3395
--- /dev/null
+++ b/libiberty/makefile.dos
@@ -0,0 +1,29 @@
+CFLAGS=-O2
+
+OBJS = \
+ argv.o \
+ basename.o \
+ concat.o \
+ cplus-dem.o \
+ fdmatch.o \
+ floatformat.o \
+ getopt.o \
+ getopt1.o \
+ getruntime.o \
+ hex.o \
+ msdos.o \
+ obstack.o \
+ spaces.o \
+ strerror.o \
+ strsignal.o \
+ xatexit.o \
+ xexit.o \
+ xmalloc.o \
+ $E
+
+.c.o:
+ gcc -I../include $(CFLAGS) -c $<
+
+libiberty.a : $(OBJS)
+ -rm libiberty.a
+ ar rvs libiberty.a $(OBJS)
diff --git a/libiberty/makefile.vms b/libiberty/makefile.vms
new file mode 100644
index 00000000000..b61b51290da
--- /dev/null
+++ b/libiberty/makefile.vms
@@ -0,0 +1,33 @@
+#
+# Makefile for libiberty under openVMS/Alpha
+#
+# For use with gnu-make for vms
+#
+# Created by Klaus K"ampf, kkaempf@progis.de
+#
+#
+
+OBJS=bcopy.obj,bcmp.obj,getopt.obj,obstack.obj,xexit.obj,xmalloc.obj,hex.obj,\
+ getopt1.obj,cplus-dem.obj,strncasecmp.obj,strcasecmp.obj,strdup.obj,\
+ concat.obj,getruntime.obj,getpagesize.obj,alloca.obj,xstrerror.obj,\
+ xstrdup.obj,xatexit.obj,choose-temp.obj,fnmatch.obj,objalloc.obj
+
+ifeq ($(CC),gcc)
+CFLAGS=/include=([],[-.include])
+else
+# assume dec c
+CFLAGS=/noopt/debug/include=([],[-.include])/define=("const=")/warnings=disable=(missingreturn,implicitfunc)
+endif
+
+libiberty.olb: config.h alloca-conf.h $(OBJS)
+ purge
+ lib/create libiberty *.obj
+
+config.h: config.h-vms
+ $(CP) $< $@
+
+clean:
+ $$ purge
+ $(RM) config.h;
+ $(RM) *.obj;
+ $(RM) libiberty.olb;
diff --git a/libiberty/memchr.c b/libiberty/memchr.c
new file mode 100644
index 00000000000..cce30039437
--- /dev/null
+++ b/libiberty/memchr.c
@@ -0,0 +1,60 @@
+/*
+FUNCTION
+ <<memchr>>---find character in memory
+
+INDEX
+ memchr
+
+ANSI_SYNOPSIS
+ #include <string.h>
+ void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
+
+TRAD_SYNOPSIS
+ #include <string.h>
+ void *memchr(<[src]>, <[c]>, <[length]>)
+ void *<[src]>;
+ void *<[c]>;
+ size_t <[length]>;
+
+DESCRIPTION
+ This function searches memory starting at <<*<[src]>>> for the
+ character <[c]>. The search only ends with the first
+ occurrence of <[c]>, or after <[length]> characters; in
+ particular, <<NULL>> does not terminate the search.
+
+RETURNS
+ If the character <[c]> is found within <[length]> characters
+ of <<*<[src]>>>, a pointer to the character is returned. If
+ <[c]> is not found, then <<NULL>> is returned.
+
+PORTABILITY
+<<memchr>> requires no supporting OS subroutines.
+
+QUICKREF
+ memchr ansi pure
+
+*/
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+PTR
+memchr (src_void, c, length)
+ register const PTR src_void;
+ int c;
+ size_t length;
+{
+ const unsigned char *src = (const unsigned char *)src_void;
+
+ while (--length >= 0)
+ {
+ if (*src == c)
+ return (PTR)src;
+ src++;
+ }
+ return NULL;
+}
diff --git a/libiberty/memcmp.c b/libiberty/memcmp.c
new file mode 100644
index 00000000000..127ae0c8019
--- /dev/null
+++ b/libiberty/memcmp.c
@@ -0,0 +1,38 @@
+/* memcmp -- compare two memory regions.
+ This function is in the public domain. */
+
+/*
+NAME
+ memcmp -- compare two memory regions
+
+SYNOPSIS
+ int memcmp (const void *from, const void *to, size_t count)
+
+DESCRIPTION
+ Compare two memory regions and return less than,
+ equal to, or greater than zero, according to lexicographical
+ ordering of the compared regions.
+*/
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+int
+DEFUN(memcmp, (str1, str2, count),
+ const PTR str1 AND const PTR str2 AND size_t count)
+{
+ register unsigned char *s1 = (unsigned char*)str1;
+ register unsigned char *s2 = (unsigned char*)str2;
+
+ while (count-- > 0)
+ {
+ if (*s1++ != *s2++)
+ return s1[-1] < s2[-1] ? -1 : 1;
+ }
+ return 0;
+}
+
diff --git a/libiberty/memcpy.c b/libiberty/memcpy.c
new file mode 100644
index 00000000000..707a9f57385
--- /dev/null
+++ b/libiberty/memcpy.c
@@ -0,0 +1,28 @@
+/* memcpy (the standard C function)
+ This function is in the public domain. */
+
+/*
+NAME
+ memcpy -- copy memory regions of arbitary length
+
+SYNOPSIS
+ void* memcpy (void *out, const void *in, size_t n);
+
+DESCRIPTION
+ Copy LENGTH bytes from memory region pointed to by IN to memory
+ region pointed to by OUT.
+*/
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+PTR
+DEFUN(memcpy, (out, in, length), PTR out AND const PTR in AND size_t length)
+{
+ bcopy(in, out, length);
+ return out;
+}
diff --git a/libiberty/memmove.c b/libiberty/memmove.c
new file mode 100644
index 00000000000..176c326ef2b
--- /dev/null
+++ b/libiberty/memmove.c
@@ -0,0 +1,18 @@
+/* Wrapper to implement ANSI C's memmove using BSD's bcopy. */
+/* This function is in the public domain. --Per Bothner. */
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+PTR
+memmove (s1, s2, n)
+ PTR s1;
+ const PTR s2;
+ size_t n;
+{
+ bcopy (s2, s1, n);
+ return s1;
+}
diff --git a/libiberty/memset.c b/libiberty/memset.c
new file mode 100644
index 00000000000..5f54831e83c
--- /dev/null
+++ b/libiberty/memset.c
@@ -0,0 +1,19 @@
+/* memset
+ This implementation is in the public domain. */
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+PTR
+DEFUN(memset, (dest, val, len),
+ PTR dest AND register int val AND register size_t len)
+{
+ register unsigned char *ptr = (unsigned char*)dest;
+ while (len-- > 0)
+ *ptr++ = val;
+ return dest;
+}
diff --git a/libiberty/mkstemps.c b/libiberty/mkstemps.c
new file mode 100644
index 00000000000..16c16a23263
--- /dev/null
+++ b/libiberty/mkstemps.c
@@ -0,0 +1,128 @@
+/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
+ This file is derived from mkstemp.c from the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include "ansidecl.h"
+
+/* We need to provide a type for gcc_uint64_t. */
+#ifdef __GNUC__
+typedef unsigned long long gcc_uint64_t;
+#else
+typedef unsigned long gcc_uint64_t;
+#endif
+
+#ifndef TMP_MAX
+#define TMP_MAX 16384
+#endif
+
+/* Generate a unique temporary file name from TEMPLATE.
+
+ TEMPLATE has the form:
+
+ <path>/ccXXXXXX<suffix>
+
+ SUFFIX_LEN tells us how long <suffix> is (it can be zero length).
+
+ The last six characters of TEMPLATE before <suffix> must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+
+ Returns a file descriptor open on the file for reading and writing. */
+int
+mkstemps (template, suffix_len)
+ char *template;
+ int suffix_len;
+{
+ static const char letters[]
+ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static gcc_uint64_t value;
+#ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+#endif
+ char *XXXXXX;
+ size_t len;
+ int count;
+
+ len = strlen (template);
+
+ if ((int) len < 6 + suffix_len
+ || strncmp (&template[len - 6 - suffix_len], "XXXXXX", 6))
+ {
+ return -1;
+ }
+
+ XXXXXX = &template[len - 6 - suffix_len];
+
+#ifdef HAVE_GETTIMEOFDAY
+ /* Get some more or less random data. */
+ gettimeofday (&tv, NULL);
+ value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
+#else
+ value += getpid ();
+#endif
+
+ for (count = 0; count < TMP_MAX; ++count)
+ {
+ gcc_uint64_t v = value;
+ int fd;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (fd >= 0)
+ /* The file does not exist. */
+ return fd;
+
+ /* This is a random value. It is only necessary that the next
+ TMP_MAX values generated by adding 7777 to VALUE are different
+ with (module 2^32). */
+ value += 7777;
+ }
+
+ /* We return the null string if we can't find a unique file name. */
+ template[0] = '\0';
+ return -1;
+}
diff --git a/libiberty/mpw-config.in b/libiberty/mpw-config.in
new file mode 100644
index 00000000000..2a21802148d
--- /dev/null
+++ b/libiberty/mpw-config.in
@@ -0,0 +1,7 @@
+# MPW configuration fragment for libiberty.
+
+Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new
+
+MoveIfChange "{o}"config.new "{o}"config.h
+
+
diff --git a/libiberty/mpw-make.sed b/libiberty/mpw-make.sed
new file mode 100644
index 00000000000..6f2a5e77b2b
--- /dev/null
+++ b/libiberty/mpw-make.sed
@@ -0,0 +1,51 @@
+# Sed commands to finish translating libiberty's Unix makefile to MPW syntax.
+
+# Comment out a useless thing.
+/^\.always\./s/^/#/
+
+# Replace the auto-generated list with the list of what we know we need.
+s/`cat needed-list`/"{o}"alloca.c.o "{o}"bcopy.c.o "{o}"getpagesize.c.o "{o}"insque.c.o "{o}"mpw.c.o "{o}"strcasecmp.c.o "{o}"strdup.c.o "{o}"strncasecmp.c.o/
+
+# Paste in some desirable definitions.
+# The default rule here completely replaces the tricky stuff in the Unix
+# Makefile.in.
+/^###$/a\
+\
+HDEFINES = -d NEED_sys_siglist -d NEED_sys_errlist -d NEED_basename -d NEED_strcasecmp -d NEED_strncasecmp\
+INCLUDES = -i : -i {INCDIR}: -i {INCDIR}:mpw: -i ::extra-include: -i "{s}"\
+\
+.c.o \\Option-f .c\
+ {CC} @DASH_C_FLAG@ {DepDir}{Default}.c {LIBCFLAGS} {INCLUDES} {HDEFINES} @SEGMENT_FLAG({Default})@ -o {TargDir}{Default}.c.o\
+
+# Remove dependency on needed-list, which we don't use.
+/DO_ALSO =/s/needed-list//
+
+/INCDIR=/s/"{srcdir}"{MULTISRCTOP}::/"{topsrcdir}"/
+
+# Whack out the COMPILE.c trickiness.
+/^COMPILE.c /,/^$/d
+
+# Remove the multido trickiness from the "all" target.
+/^all \\Option-f/,/^$/c\
+all \\Option-f {TARGETLIB}\
+
+
+# Remove the RULE1/RULE2 crud.
+/if \[/,/fi/d
+/^RULE1 =/,/RULE2 =/d
+/RULE2/s/RULE2/TARGETLIB/
+
+# Don't want fdmatch ever.
+s/ "{o}"fdmatch.c.o//
+
+# Fix paths to generated files.
+/config.h/s/"{s}"config.h/"{o}"config.h/
+
+# Whack out config rebuild rules.
+/^"{o}"config.h \\Option-f/,/^$/d
+
+
+
+
+
+
diff --git a/libiberty/mpw.c b/libiberty/mpw.c
new file mode 100644
index 00000000000..ca3ae412d25
--- /dev/null
+++ b/libiberty/mpw.c
@@ -0,0 +1,1010 @@
+/* MPW-Unix compatibility library.
+ Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This should only be compiled and linked under MPW. */
+
+#include "mpw.h"
+
+#include <stdlib.h>
+
+#ifndef USE_MW_HEADERS
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#include <Types.h>
+#include <Files.h>
+
+#include <Timer.h>
+
+/* Initialize to 0 at first, then set to errno_max() later. */
+
+int sys_nerr = 0;
+
+/* Debug flag for pathname hacking. Set this to one and rebuild. */
+
+int DebugPI = -1;
+
+void
+mpwify_filename(char *unixname, char *macname)
+{
+ int i, j;
+
+ /* (should truncate 255 chars from end of name, not beginning) */
+ if (strlen (unixname) > 255)
+ {
+ fprintf (stderr, "Pathname \"%s\" is too long for Macs, truncating\n",
+ unixname);
+ }
+ j = 0;
+ /* If you're going to end up with one or more colons in the middle of a
+ path after an all-Unix relative path is translated, you must add a
+ colon on the front, so that the first component is not thought to be
+ a disk name. */
+ if (unixname[0] != '/' && ! strchr (unixname, ':') && strchr (unixname, '/'))
+ {
+ macname[j++] = ':';
+ }
+ for (i = 0; unixname[i] != '\0' && i < 255; ++i)
+ {
+ if (i == 0 && unixname[i] == '/')
+ {
+ if (strncmp (unixname, "/tmp/", 5) == 0)
+ {
+ /* A temporary name, make a more Mac-flavored tmpname. */
+ /* A better choice would be {Boot}Trash:foo, but
+ that would require being able to identify the
+ boot disk's and trashcan's name. Another option
+ would be to have an env var, so user can point it
+ at a ramdisk. */
+ macname[j++] = ':';
+ macname[j++] = 't';
+ macname[j++] = 'm';
+ macname[j++] = 'p';
+ macname[j++] = '_';
+ i += 4;
+ }
+ else
+ {
+ /* Don't copy the leading slash. */
+ }
+ }
+ else if (unixname[i] == ':' && unixname[i+1] == '/')
+ {
+ macname[j++] = ':';
+ i += 1;
+ }
+ else if (unixname[i] == '.' && unixname[i+1] == '/')
+ {
+ macname[j++] = ':';
+ i += 1;
+ }
+ else if (unixname[i] == '.' && unixname[i+1] == '.' && unixname[i+2] == '/')
+ {
+ macname[j++] = ':';
+ macname[j++] = ':';
+ i += 2;
+ }
+ else if (unixname[i] == '/')
+ {
+ macname[j++] = ':';
+ }
+ else
+ {
+ macname[j++] = unixname[i];
+ }
+ }
+ macname[j] = '\0';
+ /* Allow for getting the debug flag from an env var; quite useful. */
+ if (DebugPI < 0)
+ DebugPI = (*(getenv ("DEBUG_PATHNAMES")) == '1' ? 1 : 0);
+ if (DebugPI)
+ {
+ fprintf (stderr, "# Made \"%s\"\n", unixname);
+ fprintf (stderr, "# into \"%s\"\n", macname);
+ }
+}
+
+/* MPW-flavored basename finder. */
+
+char *
+mpw_basename (name)
+ char *name;
+{
+ char *base = name;
+
+ while (*name)
+ {
+ if (*name++ == ':')
+ {
+ base = name;
+ }
+ }
+ return base;
+}
+
+/* Mixed MPW/Unix basename finder. This can be led astray by
+ filenames with slashes in them and come up with a basename that
+ either corresponds to no file or (worse) to some other file, so
+ should only be tried if other methods of finding a file via a
+ basename have failed. */
+
+char *
+mpw_mixed_basename (name)
+ char *name;
+{
+ char *base = name;
+
+ while (*name)
+ {
+ if (*name == '/' || *name == ':')
+ {
+ base = name + 1;
+ }
+ ++name;
+ }
+ return base;
+}
+
+/* This function is fopen() modified to create files that are type TEXT
+ or 'BIN ', and always of type 'MPS '. */
+
+FILE *
+mpw_fopen (char *name, char *mode)
+{
+#undef fopen
+ int errnum;
+ FILE *fp;
+ char tmpname[256];
+
+ mpwify_filename (name, tmpname);
+ PROGRESS (1);
+ fp = fopen (tmpname, mode);
+ errnum = errno;
+
+ /* If writing, need to set type and creator usefully. */
+ if (strchr (mode, 'w'))
+ {
+ char *pname = (char *) malloc (strlen (tmpname) + 2);
+ OSErr e;
+ struct FInfo fi;
+
+ pname[0] = strlen (tmpname);
+ strcpy (pname+1, tmpname);
+
+ e = GetFInfo ((ConstStr255Param) pname, 0, &fi);
+ /* should do spiffier error handling */
+ if (e != 0)
+ fprintf(stderr, "GetFInfo returns %d\n", e);
+ if (strchr (mode, 'b'))
+ {
+ fi.fdType = (OSType) 'BIN ';
+ }
+ else
+ {
+ fi.fdType = (OSType) 'TEXT';
+ }
+ fi.fdCreator = (OSType) 'MPS ';
+ e = SetFInfo ((ConstStr255Param) pname, 0, &fi);
+ if (e != 0)
+ fprintf(stderr, "SetFInfo returns %d\n", e);
+ free (pname);
+ }
+ if (fp == NULL)
+ errno = errnum;
+ return fp;
+}
+
+/* This is a version of fseek() modified to fill the file with zeros
+ if seeking past the end of it. */
+
+#define ZEROBLKSIZE 4096
+
+char zeros[ZEROBLKSIZE];
+
+int
+mpw_fseek (FILE *fp, int offset, int whence)
+{
+#undef fseek
+ int cursize, numleft;
+
+ PROGRESS (1);
+ if (whence == SEEK_SET)
+ {
+ fseek (fp, 0, SEEK_END);
+ cursize = ftell (fp);
+ if (offset > cursize)
+ {
+ numleft = offset - cursize;
+ while (numleft > ZEROBLKSIZE)
+ {
+ /* This might fail, should check for that. */
+ PROGRESS (1);
+ fwrite (zeros, 1, ZEROBLKSIZE, fp);
+ numleft -= ZEROBLKSIZE;
+ }
+ PROGRESS (1);
+ fwrite (zeros, 1, numleft, fp);
+ fflush (fp);
+ }
+ }
+ return fseek (fp, offset, whence);
+}
+
+int
+mpw_fread (char *ptr, int size, int nitems, FILE *stream)
+{
+#undef fread
+ int rslt;
+
+ PROGRESS (1);
+ rslt = fread (ptr, size, nitems, stream);
+ PROGRESS (1);
+ return rslt;
+}
+
+int
+mpw_fwrite (char *ptr, int size, int nitems, FILE *stream)
+{
+#undef fwrite
+ int rslt;
+
+ PROGRESS (1);
+ rslt = fwrite (ptr, size, nitems, stream);
+ PROGRESS (1);
+ return rslt;
+}
+
+int
+link ()
+{
+ fprintf (stderr, "link not available!\n");
+ mpw_abort ();
+}
+
+int
+fork ()
+{
+ fprintf (stderr, "fork not available!\n");
+ mpw_abort ();
+}
+
+int
+vfork ()
+{
+ fprintf (stderr, "vfork not available!\n");
+ mpw_abort ();
+ return (-1);
+}
+
+int
+pipe (int *fd)
+{
+ fprintf (stderr, "pipe not available!\n");
+ mpw_abort ();
+ return (-1);
+}
+
+#ifndef USE_MW_HEADERS
+int
+execvp (char *file, char **argv)
+{
+ fprintf (stderr, "execvp not available!\n");
+ mpw_abort ();
+ return (-1);
+}
+
+int
+execv (char *path, char **argv)
+{
+ fprintf (stderr, "execv not available!\n");
+ mpw_abort ();
+ return (-1);
+}
+#endif
+
+int
+kill (int pid, int sig)
+{
+ fprintf (stderr, "kill not available!\n");
+ mpw_abort ();
+ return (-1);
+}
+
+int
+wait (int *status)
+{
+ *status = 0;
+ return 0;
+}
+
+#ifndef USE_MW_HEADERS
+int
+sleep (int seconds)
+{
+ unsigned long start_time, now;
+
+ time (&start_time);
+
+ while (1)
+ {
+ PROGRESS (1);
+ time (&now);
+ if (now > start_time + seconds)
+ return 0;
+ }
+}
+#endif
+
+void
+putenv (char *str)
+{
+ /* The GCC driver calls this to do things for collect2, but we
+ don't care about collect2. */
+}
+
+int
+chmod (char *path, int mode)
+{
+ /* Pretend it was all OK. */
+ return 0;
+}
+
+#ifndef USE_MW_HEADERS
+int
+getuid ()
+{
+ /* One value is as good as another... */
+ return 0;
+}
+
+int
+getgid ()
+{
+ /* One value is as good as another... */
+ return 0;
+}
+#endif
+
+/* Instead of coredumping, which is not a normal Mac facility, we
+ drop into Macsbug. If we then "g" from Macsbug, the program will
+ exit cleanly. */
+
+void
+mpw_abort ()
+{
+ /* Make sure no output still buffered up, then zap into MacsBug. */
+ fflush(stdout);
+ fflush(stderr);
+ printf("## Abort! ##\n");
+#ifdef MPW_SADE
+ SysError(8005);
+#else
+ Debugger();
+#endif
+ /* "g" in MacsBug will then cause a regular error exit. */
+ exit (1);
+}
+
+/* Imitation getrusage based on the ANSI clock() function. */
+
+int
+getrusage (int who, struct rusage *rusage)
+{
+ int clk = clock ();
+
+#if 0
+ rusage->ru_utime.tv_sec = clk / CLOCKS_PER_SEC;
+ rusage->ru_utime.tv_usec = ((clk * 1000) / CLOCKS_PER_SEC) * 1000;
+ rusage->ru_stime.tv_sec = 0;
+ rusage->ru_stime.tv_usec = 0;
+#endif
+}
+
+int
+sbrk ()
+{
+ return 0;
+}
+
+#ifndef USE_MW_HEADERS
+int
+isatty (int fd)
+{
+ return 0;
+}
+
+/* This is inherited from Timothy Murray's Posix library. */
+
+#include "utime.h"
+
+int
+utime (char *filename, struct utimbuf *times)
+{
+ CInfoPBRec cipbr;
+ HFileInfo *fpb = (HFileInfo *) &cipbr;
+ DirInfo *dpb = (DirInfo *) &cipbr;
+ unsigned char pname[256];
+ short err;
+
+ strcpy ((char *) pname, filename);
+ c2pstr (pname);
+
+ dpb->ioDrDirID = 0L;
+ fpb->ioNamePtr = pname;
+ fpb->ioVRefNum = 0;
+ fpb->ioFDirIndex = 0;
+ fpb->ioFVersNum = 0;
+ err = PBGetCatInfo (&cipbr, 0);
+ if (err != noErr) {
+ errno = ENOENT;
+ return -1;
+ }
+ dpb->ioDrDirID = 0L;
+ fpb->ioFlMdDat = times->modtime;
+ fpb->ioFlCrDat = times->actime;
+ err = PBSetCatInfo (&cipbr, 0);
+ if (err != noErr) {
+ errno = EACCES;
+ return -1;
+ }
+ return 0;
+}
+
+int
+mkdir (char *path, int mode)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+rmdir ()
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif
+
+chown ()
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+char *myenviron[] = {NULL};
+
+char **environ = myenviron;
+
+#ifndef USE_MW_HEADERS
+
+/* Minimal 'stat' emulation: tells directories from files and
+ gives length and mtime.
+
+ Derived from code written by Guido van Rossum, CWI, Amsterdam
+ and placed by him in the public domain. */
+
+extern int __uid, __gid;
+
+int __uid = 0;
+int __gid = 0;
+
+/* Bits in ioFlAttrib: */
+#define LOCKBIT (1<<0) /* File locked */
+#define DIRBIT (1<<4) /* It's a directory */
+
+/* Macified "stat" in which filename is given relative to a directory,
+ specified by long DirID. */
+
+static int
+_stat (char *name, long dirid, struct stat *buf)
+{
+ CInfoPBRec cipbr;
+ HFileInfo *fpb = (HFileInfo*) &cipbr;
+ DirInfo *dpb = (DirInfo*) &cipbr;
+ Str255 pname;
+ short err;
+
+ /* Make a temp copy of the name and pascalize. */
+ strcpy ((char *) pname, name);
+ c2pstr (pname);
+
+ cipbr.dirInfo.ioDrDirID = dirid;
+ cipbr.hFileInfo.ioNamePtr = pname;
+ cipbr.hFileInfo.ioVRefNum = 0;
+ cipbr.hFileInfo.ioFDirIndex = 0;
+ cipbr.hFileInfo.ioFVersNum = 0;
+ err = PBGetCatInfo (&cipbr, 0);
+ if (err != noErr)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ /* Mac files are readable if they can be accessed at all. */
+ buf->st_mode = 0444;
+ /* Mark unlocked files as writeable. */
+ if (!(fpb->ioFlAttrib & LOCKBIT))
+ buf->st_mode |= 0222;
+ if (fpb->ioFlAttrib & DIRBIT)
+ {
+ /* Mark directories as "executable". */
+ buf->st_mode |= 0111 | S_IFDIR;
+ buf->st_size = dpb->ioDrNmFls;
+ buf->st_rsize = 0;
+ }
+ else
+ {
+ buf->st_mode |= S_IFREG;
+ /* Mark apps as "executable". */
+ if (fpb->ioFlFndrInfo.fdType == 'APPL')
+ buf->st_mode |= 0111;
+ /* Fill in the sizes of data and resource forks. */
+ buf->st_size = fpb->ioFlLgLen;
+ buf->st_rsize = fpb->ioFlRLgLen;
+ }
+ /* Fill in various times. */
+ buf->st_atime = fpb->ioFlCrDat;
+ buf->st_mtime = fpb->ioFlMdDat;
+ buf->st_ctime = fpb->ioFlCrDat;
+ /* Set up an imitation inode number. */
+ buf->st_ino = (unsigned short) fpb->ioDirID;
+ /* Set up an imitation device. */
+ GetVRefNum (buf->st_ino, &buf->st_dev);
+ buf->st_uid = __uid;
+ buf->st_gid = __gid;
+/* buf->st_FlFndrInfo = fpb->ioFlFndrInfo; */
+ return 0;
+}
+
+/* stat() sets up an empty dirid. */
+
+int
+stat (char *path, struct stat *buf)
+{
+ long rslt, errnum;
+ char tmpname[256];
+
+ mpwify_filename (path, tmpname);
+ if (DebugPI)
+ fprintf (stderr, "# stat (%s, %x)", tmpname, buf);
+ PROGRESS (1);
+ rslt = _stat (tmpname, 0L, buf);
+ errnum = errno;
+ if (DebugPI)
+ {
+ fprintf (stderr, " -> %d", rslt);
+ if (rslt != 0)
+ fprintf (stderr, " (errno is %d)", errnum);
+ fprintf (stderr, "\n");
+ fflush (stderr);
+ }
+ if (rslt != 0)
+ errno = errnum;
+ return rslt;
+}
+
+int
+fstat (int fd, struct stat *buf)
+{
+ FCBPBRec fcb;
+ FILE *fp;
+ Str255 pathname;
+ long dirid = 0L, temp;
+ long rslt, errnum;
+ short err;
+
+ if (DebugPI < 0)
+ DebugPI = (*(getenv ("DEBUG_PATHNAMES")) == '1' ? 1 : 0);
+ if (DebugPI)
+ fprintf (stderr, "# fstat (%d, %x)", fd, buf);
+ PROGRESS (1);
+ pathname[0] = 0;
+#ifdef FIOFNAME
+ /* Use an MPW-specific ioctl to get the pathname associated with
+ the file descriptor. */
+ ioctl (fd, FIOFNAME, (long *) pathname);
+#else
+ you lose
+#endif
+ if (DebugPI)
+ fprintf (stderr, " (name is %s)", pathname);
+ dirid = 0L /* fcb.ioFCBParID */ ;
+ rslt = _stat ((char *) pathname, dirid, buf);
+ errnum = errno;
+ if (DebugPI)
+ {
+ fprintf (stderr, " -> %d", rslt);
+ if (rslt != 0)
+ fprintf (stderr, " (errno is %d)", errnum);
+ fprintf (stderr, "\n");
+ fflush (stderr);
+ }
+ if (rslt != 0)
+ errno = errnum;
+ return rslt;
+}
+
+#endif /* n USE_MW_HEADERS */
+
+chdir ()
+{
+ errno = ENOSYS;
+ return (-1);
+}
+
+char *
+getcwd (char *buf, int size)
+{
+ if (buf == NULL)
+ buf = (char *) malloc (size);
+ strcpy(buf, ":");
+ return buf;
+}
+
+/* This should probably be more elaborate for MPW. */
+
+char *
+getpwd ()
+{
+ return ":";
+}
+
+int
+mpw_open (char *filename, int arg2, int arg3)
+{
+#undef open
+ int fd, errnum = 0;
+ char tmpname[256];
+
+ mpwify_filename (filename, tmpname);
+ fd = open (tmpname, arg2);
+ errnum = errno;
+
+ if (DebugPI)
+ {
+ fprintf (stderr, "# open (%s, %d, %d)", tmpname, arg2, arg3);
+ fprintf (stderr, " -> %d", fd);
+ if (fd == -1)
+ fprintf (stderr, " (errno is %d)", errnum);
+ fprintf (stderr, "\n");
+ }
+ if (fd == -1)
+ errno = errnum;
+ return fd;
+}
+
+int
+mpw_access (char *filename, unsigned int cmd)
+{
+#undef access
+
+ int rslt, errnum = 0;
+ struct stat st;
+ char tmpname[256];
+
+ mpwify_filename (filename, tmpname);
+ if (cmd & R_OK || cmd & X_OK)
+ {
+ rslt = stat (tmpname, &st);
+ errnum = errno;
+ if (rslt >= 0)
+ {
+ if ((((st.st_mode & 004) == 0) && (cmd & R_OK))
+ || (((st.st_mode & 002) == 0) && (cmd & W_OK))
+ || (((st.st_mode & 001) == 0) && (cmd & X_OK)))
+ {
+ rslt = -1;
+ errnum = EACCES;
+ }
+ }
+ }
+ if (DebugPI)
+ {
+ fprintf (stderr, "# mpw_access (%s, %d)", tmpname, cmd);
+ fprintf (stderr, " -> %d", rslt);
+ if (rslt != 0)
+ fprintf (stderr, " (errno is %d)", errnum);
+ fprintf (stderr, "\n");
+ }
+ if (rslt != 0)
+ errno = errnum;
+ return rslt;
+}
+
+/* The MPW library creat() has no mode argument. */
+
+int
+mpw_creat (char *path, /* mode_t */ int mode)
+{
+#undef creat
+
+#ifdef USE_MW_HEADERS
+ return creat (path, mode);
+#else
+ return creat (path);
+#endif
+}
+
+/* This is a hack to get control in an MPW tool before it crashes the
+ machine. */
+
+mpw_special_init (name)
+ char *name;
+{
+ if (strstr (name, "DEBUG"))
+ DebugStr("\pat beginning of program");
+}
+
+static int current_umask;
+
+int
+umask(int mask)
+{
+ int oldmask = current_umask;
+
+ current_umask = mask;
+ return oldmask;
+}
+
+/* Cursor-spinning stuff that includes metering of spin rate and delays. */
+
+/* Nonzero when cursor spinning has been set up properly. */
+
+int cursor_inited;
+
+/* Nonzero if spin should be measured and excessive delays reported. */
+
+int measure_spin;
+
+/* Nonzero if spin histogram and rate data should be written out. */
+
+int dump_spin_data;
+
+long warning_threshold = 400000;
+
+long bucket_size = 1024;
+
+long bucket_power = 10;
+
+long numbuckets = 300;
+
+int *delay_counts;
+
+int overflow_count;
+
+char *current_progress;
+
+static UnsignedWide last_microseconds;
+
+static char *last_spin_file = "";
+
+static int last_spin_line;
+
+void
+warn_if_spin_delay (char *file, int line)
+{
+ long diff, ix;
+ UnsignedWide now;
+
+ Microseconds(&now);
+
+ diff = now.lo - last_microseconds.lo;
+
+ if (diff > warning_threshold)
+ fprintf (stderr, "# %s: %ld.%06ld sec delay getting from %s:%d to %s:%d\n",
+ (current_progress ? current_progress : ""),
+ diff / 1000000, diff % 1000000,
+ last_spin_file, last_spin_line, file, line);
+ if (dump_spin_data)
+ {
+ if (diff >= 0)
+ {
+ ix = diff >> bucket_power;
+ if (ix >= 0 && ix < numbuckets && delay_counts != NULL)
+ ++delay_counts[ix];
+ else
+ ++overflow_count;
+ }
+ else
+ fprintf (stderr, "raw diff is %ld (?)\n", diff);
+ }
+}
+
+void
+record_for_spin_delay (char *file, int line)
+{
+ Microseconds (&last_microseconds);
+ last_spin_file = file;
+ last_spin_line = line;
+}
+
+void
+mpw_start_progress (char *str, int n, char *file, int line)
+{
+ int i;
+ char *measure, *threshold;
+
+ if (!cursor_inited)
+ {
+ InitCursorCtl (nil);
+ cursor_inited = 1;
+ record_for_spin_delay (file, line);
+ measure = getenv ("MEASURE_SPIN");
+ if (measure != NULL && measure[0] != '\0')
+ {
+ measure_spin = 1;
+ if (strcmp (measure, "all") == 0)
+ dump_spin_data = 1;
+ }
+ threshold = getenv ("SPIN_WARN_THRESHOLD");
+ if (threshold != NULL && threshold[0] != '\0')
+ warning_threshold = atol (threshold);
+ if (dump_spin_data)
+ {
+ if (delay_counts == NULL)
+ delay_counts = (int *) malloc (numbuckets * sizeof (int));
+ for (i = 0; i < numbuckets; ++i)
+ delay_counts[i] = 0;
+ overflow_count = 0;
+ }
+ }
+ current_progress = str;
+
+ sys_nerr = errno_max ();
+
+ mpw_special_init (str);
+}
+
+void
+mpw_progress (int n)
+{
+ SpinCursor (32);
+}
+
+void
+mpw_progress_measured (int n, char *file, int line)
+{
+ if (measure_spin)
+ warn_if_spin_delay (file, line);
+ SpinCursor (32);
+ if (measure_spin)
+ record_for_spin_delay (file, line);
+}
+
+void
+mpw_end_progress (char *str, char *file, int line)
+{
+ long i, delay, count = 0, sum = 0, avgdelay, spinrate;
+ long curpower = 0, curgroup = 0;
+
+ /* Warn if it's been a while since the last spin. */
+ if (measure_spin)
+ warn_if_spin_delay (file, line);
+
+ /* Dump all the nonzero delay counts and an approximation of the delay. */
+ if (dump_spin_data && delay_counts != NULL)
+ {
+ for (i = 0; i < numbuckets; ++i)
+ {
+ delay = (i + 1) * bucket_size;
+ sum += delay_counts[i] * (i + 1);
+ count += delay_counts[i];
+ if (delay <= (1 << curpower))
+ {
+ curgroup += delay_counts[i];
+ }
+ else
+ {
+ if (curgroup > 0)
+ fprintf (stderr,
+ "# %s: %d delays between %ld.%06ld and %ld.%06ld sec\n",
+ (str ? str : ""),
+ curgroup,
+ (1 << curpower) / 1000000,
+ (1 << curpower) % 1000000,
+ (1 << (curpower + 1)) / 1000000,
+ (1 << (curpower + 1)) % 1000000);
+ ++curpower;
+ curgroup = 0;
+ }
+ }
+ if (count > 0)
+ {
+ avgdelay = (sum * bucket_size) / count;
+ spinrate = 1000000 / avgdelay;
+ fprintf (stderr, "# %s: Average spin rate is %d times/sec\n",
+ (str ? str : ""), spinrate);
+ }
+ }
+}
+
+#ifdef PROGRESS_TEST
+
+/* Test program. */
+
+main ()
+{
+ int i, j;
+ double x = 1.0, y = 2.4;
+ long start = Microseconds (), tm; FIXME
+
+ START_PROGRESS ("hi", 0);
+
+ for (i = 0; i < 1000; ++i)
+ {
+ PROGRESS (1);
+
+ for (j = 0; j < (i * 100); ++j)
+ {
+ x += (x * y) / j;
+ }
+ }
+
+ END_PROGRESS ("hi");
+
+ tm = Microseconds () - start;
+
+ printf ("Total time is %d.%d secs\n", tm / 1000000, tm % 1000000);
+}
+
+#endif
+
+#ifdef USE_MW_HEADERS
+/* Empty definitions for Metrowerks' SIOUX console library. */
+
+#ifndef __CONSOLE__
+#include <console.h>
+#endif
+
+short
+InstallConsole(short fd)
+{
+#pragma unused (fd)
+ return 0;
+}
+
+void
+RemoveConsole(void)
+{
+}
+
+long
+WriteCharsToConsole(char *buf, long n)
+{
+#pragma unused (buf, n)
+ return 0;
+}
+
+long ReadCharsFromConsole(char *buf, long n)
+{
+#pragma unused (buf, n)
+ return 0;
+}
+
+extern char *
+__ttyname(long fd)
+{
+ static char *__devicename = "null device";
+
+ if (fd >= 0 && fd <= 2)
+ return (__devicename);
+ return NULL;
+}
+
+#endif
diff --git a/libiberty/msdos.c b/libiberty/msdos.c
new file mode 100644
index 00000000000..923e64d4ede
--- /dev/null
+++ b/libiberty/msdos.c
@@ -0,0 +1,15 @@
+char msg[] = "No vfork available - aborting\n";
+vfork()
+{
+ write(1, msg, sizeof(msg));
+}
+
+sigsetmask()
+{
+ /* no signals support in go32 (yet) */
+}
+
+waitpid()
+{
+ return -1;
+}
diff --git a/libiberty/objalloc.c b/libiberty/objalloc.c
new file mode 100644
index 00000000000..57754a86105
--- /dev/null
+++ b/libiberty/objalloc.c
@@ -0,0 +1,291 @@
+/* objalloc.c -- routines to allocate memory for objects
+ Copyright 1997 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Solutions.
+
+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, 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "objalloc.h"
+
+/* Get a definition for NULL. */
+#include <stdio.h>
+
+#if VMS
+#include <stdlib.h>
+#include <unixlib.h>
+#else
+
+#ifdef ANSI_PROTOTYPES
+/* Get a definition for size_t. */
+#include <stddef.h>
+#endif
+
+/* For systems with larger pointers than ints, this must be declared. */
+extern PTR malloc PARAMS ((size_t));
+extern void free PARAMS ((PTR));
+#endif
+
+/* These routines allocate space for an object. Freeing allocated
+ space may or may not free all more recently allocated space.
+
+ We handle large and small allocation requests differently. If we
+ don't have enough space in the current block, and the allocation
+ request is for more than 512 bytes, we simply pass it through to
+ malloc. */
+
+/* The objalloc structure is defined in objalloc.h. */
+
+/* This structure appears at the start of each chunk. */
+
+struct objalloc_chunk
+{
+ /* Next chunk. */
+ struct objalloc_chunk *next;
+ /* If this chunk contains large objects, this is the value of
+ current_ptr when this chunk was allocated. If this chunk
+ contains small objects, this is NULL. */
+ char *current_ptr;
+};
+
+/* The aligned size of objalloc_chunk. */
+
+#define CHUNK_HEADER_SIZE \
+ ((sizeof (struct objalloc_chunk) + OBJALLOC_ALIGN - 1) \
+ &~ (OBJALLOC_ALIGN - 1))
+
+/* We ask for this much memory each time we create a chunk which is to
+ hold small objects. */
+
+#define CHUNK_SIZE (4096 - 32)
+
+/* A request for this amount or more is just passed through to malloc. */
+
+#define BIG_REQUEST (512)
+
+/* Create an objalloc structure. */
+
+struct objalloc *
+objalloc_create ()
+{
+ struct objalloc *ret;
+ struct objalloc_chunk *chunk;
+
+ ret = (struct objalloc *) malloc (sizeof *ret);
+ if (ret == NULL)
+ return NULL;
+
+ ret->chunks = (PTR) malloc (CHUNK_SIZE);
+ if (ret->chunks == NULL)
+ {
+ free (ret);
+ return NULL;
+ }
+
+ chunk = (struct objalloc_chunk *) ret->chunks;
+ chunk->next = NULL;
+ chunk->current_ptr = NULL;
+
+ ret->current_ptr = (char *) chunk + CHUNK_HEADER_SIZE;
+ ret->current_space = CHUNK_SIZE - CHUNK_HEADER_SIZE;
+
+ return ret;
+}
+
+/* Allocate space from an objalloc structure. */
+
+PTR
+_objalloc_alloc (o, len)
+ struct objalloc *o;
+ unsigned long len;
+{
+ /* We avoid confusion from zero sized objects by always allocating
+ at least 1 byte. */
+ if (len == 0)
+ len = 1;
+
+ len = (len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);
+
+ if (len <= o->current_space)
+ {
+ o->current_ptr += len;
+ o->current_space -= len;
+ return (PTR) (o->current_ptr - len);
+ }
+
+ if (len >= BIG_REQUEST)
+ {
+ char *ret;
+ struct objalloc_chunk *chunk;
+
+ ret = (char *) malloc (CHUNK_HEADER_SIZE + len);
+ if (ret == NULL)
+ return NULL;
+
+ chunk = (struct objalloc_chunk *) ret;
+ chunk->next = (struct objalloc_chunk *) o->chunks;
+ chunk->current_ptr = o->current_ptr;
+
+ o->chunks = (PTR) chunk;
+
+ return (PTR) (ret + CHUNK_HEADER_SIZE);
+ }
+ else
+ {
+ struct objalloc_chunk *chunk;
+
+ chunk = (struct objalloc_chunk *) malloc (CHUNK_SIZE);
+ if (chunk == NULL)
+ return NULL;
+ chunk->next = (struct objalloc_chunk *) o->chunks;
+ chunk->current_ptr = NULL;
+
+ o->current_ptr = (char *) chunk + CHUNK_HEADER_SIZE;
+ o->current_space = CHUNK_SIZE - CHUNK_HEADER_SIZE;
+
+ o->chunks = (PTR) chunk;
+
+ return objalloc_alloc (o, len);
+ }
+}
+
+/* Free an entire objalloc structure. */
+
+void
+objalloc_free (o)
+ struct objalloc *o;
+{
+ struct objalloc_chunk *l;
+
+ l = (struct objalloc_chunk *) o->chunks;
+ while (l != NULL)
+ {
+ struct objalloc_chunk *next;
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ free (o);
+}
+
+/* Free a block from an objalloc structure. This also frees all more
+ recently allocated blocks. */
+
+void
+objalloc_free_block (o, block)
+ struct objalloc *o;
+ PTR block;
+{
+ struct objalloc_chunk *p, *small;
+ char *b = (char *) block;
+
+ /* First set P to the chunk which contains the block we are freeing,
+ and set Q to the last small object chunk we see before P. */
+ small = NULL;
+ for (p = (struct objalloc_chunk *) o->chunks; p != NULL; p = p->next)
+ {
+ if (p->current_ptr == NULL)
+ {
+ if (b > (char *) p && b < (char *) p + CHUNK_SIZE)
+ break;
+ small = p;
+ }
+ else
+ {
+ if (b == (char *) p + CHUNK_HEADER_SIZE)
+ break;
+ }
+ }
+
+ /* If we can't find the chunk, the caller has made a mistake. */
+ if (p == NULL)
+ abort ();
+
+ if (p->current_ptr == NULL)
+ {
+ struct objalloc_chunk *q;
+ struct objalloc_chunk *first;
+
+ /* The block is in a chunk containing small objects. We can
+ free every chunk through SMALL, because they have certainly
+ been allocated more recently. After SMALL, we will not see
+ any chunks containing small objects; we can free any big
+ chunk if the current_ptr is greater than or equal to B. We
+ can then reset the new current_ptr to B. */
+
+ first = NULL;
+ q = (struct objalloc_chunk *) o->chunks;
+ while (q != p)
+ {
+ struct objalloc_chunk *next;
+
+ next = q->next;
+ if (small != NULL)
+ {
+ if (small == q)
+ small = NULL;
+ free (q);
+ }
+ else if (q->current_ptr > b)
+ free (q);
+ else if (first == NULL)
+ first = q;
+
+ q = next;
+ }
+
+ if (first == NULL)
+ first = p;
+ o->chunks = (PTR) first;
+
+ /* Now start allocating from this small block again. */
+ o->current_ptr = b;
+ o->current_space = ((char *) p + CHUNK_SIZE) - b;
+ }
+ else
+ {
+ struct objalloc_chunk *q;
+ char *current_ptr;
+
+ /* This block is in a large chunk by itself. We can free
+ everything on the list up to and including this block. We
+ then start allocating from the next chunk containing small
+ objects, setting current_ptr from the value stored with the
+ large chunk we are freeing. */
+
+ current_ptr = p->current_ptr;
+ p = p->next;
+
+ q = (struct objalloc_chunk *) o->chunks;
+ while (q != p)
+ {
+ struct objalloc_chunk *next;
+
+ next = q->next;
+ free (q);
+ q = next;
+ }
+
+ o->chunks = (PTR) p;
+
+ while (p->current_ptr != NULL)
+ p = p->next;
+
+ o->current_ptr = current_ptr;
+ o->current_space = ((char *) p + CHUNK_SIZE) - current_ptr;
+ }
+}
diff --git a/libiberty/obstack.c b/libiberty/obstack.c
new file mode 100644
index 00000000000..bc318b37790
--- /dev/null
+++ b/libiberty/obstack.c
@@ -0,0 +1,593 @@
+/* obstack.c - subroutines used implicitly by object stack macros
+ Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@gnu.org.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "obstack.h"
+
+/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
+ incremented whenever callers compiled using an old obstack.h can no
+ longer properly call the functions in this obstack.c. */
+#define OBSTACK_INTERFACE_VERSION 1
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself, and the installed library
+ supports the same library interface we do. This code is part of the GNU
+ C Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object
+ files, it is simpler to just do this in the source for each such file. */
+
+#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
+#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
+#include <gnu-versions.h>
+#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+
+#ifndef ELIDE_CODE
+
+
+#if defined (__STDC__) && __STDC__
+#define POINTER void *
+#else
+#define POINTER char *
+#endif
+
+/* Determine default alignment. */
+struct fooalign {char x; double d;};
+#define DEFAULT_ALIGNMENT \
+ ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+ But in fact it might be less smart and round addresses to as much as
+ DEFAULT_ROUNDING. So we prepare for it to do that. */
+union fooround {long x; double d;};
+#define DEFAULT_ROUNDING (sizeof (union fooround))
+
+/* When we copy a long block of data, this is the unit to do it with.
+ On some machines, copying successive ints does not work;
+ in such a case, redefine COPYING_UNIT to `long' (if that works)
+ or `char' as a last resort. */
+#ifndef COPYING_UNIT
+#define COPYING_UNIT int
+#endif
+
+
+/* The functions allocating more room by calling `obstack_chunk_alloc'
+ jump to the handler pointed to by `obstack_alloc_failed_handler'.
+ This variable by default points to the internal function
+ `print_and_abort'. */
+#if defined (__STDC__) && __STDC__
+static void print_and_abort (void);
+void (*obstack_alloc_failed_handler) (void) = print_and_abort;
+#else
+static void print_and_abort ();
+void (*obstack_alloc_failed_handler) () = print_and_abort;
+#endif
+
+/* Exit value used when `print_and_abort' is used. */
+#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+int obstack_exit_failure = EXIT_FAILURE;
+
+/* The non-GNU-C macros copy the obstack into this global variable
+ to avoid multiple evaluation. */
+
+struct obstack *_obstack;
+
+/* Define a macro that either calls functions with the traditional malloc/free
+ calling interface, or calls functions with the mmalloc/mfree interface
+ (that adds an extra first argument), based on the state of use_extra_arg.
+ For free, do not use ?:, since some compilers, like the MIPS compilers,
+ do not allow (expr) ? void : void. */
+
+#if defined (__STDC__) && __STDC__
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#else
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) ()) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#endif
+
+
+/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
+ Objects start on multiples of ALIGNMENT (0 means use default).
+ CHUNKFUN is the function to use to allocate chunks,
+ and FREEFUN the function to free them.
+
+ Return nonzero if successful, zero if out of memory.
+ To recover from an out of memory error,
+ free up some memory, then call this again. */
+
+int
+_obstack_begin (h, size, alignment, chunkfun, freefun)
+ struct obstack *h;
+ int size;
+ int alignment;
+#if defined (__STDC__) && __STDC__
+ POINTER (*chunkfun) (long);
+ void (*freefun) (void *);
+#else
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+#endif
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = (int) DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+#if defined (__STDC__) && __STDC__
+ h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+#else
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+#endif
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->use_extra_arg = 0;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+int
+_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
+ struct obstack *h;
+ int size;
+ int alignment;
+#if defined (__STDC__) && __STDC__
+ POINTER (*chunkfun) (POINTER, long);
+ void (*freefun) (POINTER, POINTER);
+#else
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+#endif
+ POINTER arg;
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = (int) DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+#if defined(__STDC__) && __STDC__
+ h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+#else
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+#endif
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->extra_arg = arg;
+ h->use_extra_arg = 1;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+/* Allocate a new current chunk for the obstack *H
+ on the assumption that LENGTH bytes need to be added
+ to the current object, or a new object of length LENGTH allocated.
+ Copies any partial object from the end of the old chunk
+ to the beginning of the new one. */
+
+void
+_obstack_newchunk (h, length)
+ struct obstack *h;
+ int length;
+{
+ register struct _obstack_chunk *old_chunk = h->chunk;
+ register struct _obstack_chunk *new_chunk;
+ register long new_size;
+ register long obj_size = h->next_free - h->object_base;
+ register long i;
+ long already;
+
+ /* Compute size for new chunk. */
+ new_size = (obj_size + length) + (obj_size >> 3) + 100;
+ if (new_size < h->chunk_size)
+ new_size = h->chunk_size;
+
+ /* Allocate and initialize the new chunk. */
+ new_chunk = CALL_CHUNKFUN (h, new_size);
+ if (!new_chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->chunk = new_chunk;
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+ /* Move the existing object to the new chunk.
+ Word at a time is fast and is safe if the object
+ is sufficiently aligned. */
+ if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
+ {
+ for (i = obj_size / sizeof (COPYING_UNIT) - 1;
+ i >= 0; i--)
+ ((COPYING_UNIT *)new_chunk->contents)[i]
+ = ((COPYING_UNIT *)h->object_base)[i];
+ /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
+ but that can cross a page boundary on a machine
+ which does not do strict alignment for COPYING_UNITS. */
+ already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
+ }
+ else
+ already = 0;
+ /* Copy remaining bytes one by one. */
+ for (i = already; i < obj_size; i++)
+ new_chunk->contents[i] = h->object_base[i];
+
+ /* If the object just copied was the only data in OLD_CHUNK,
+ free that chunk and remove it from the chain.
+ But not if that chunk might contain an empty object. */
+ if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
+ {
+ new_chunk->prev = old_chunk->prev;
+ CALL_FREEFUN (h, old_chunk);
+ }
+
+ h->object_base = new_chunk->contents;
+ h->next_free = h->object_base + obj_size;
+ /* The new chunk certainly contains no empty object yet. */
+ h->maybe_empty_object = 0;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+ This is here for debugging.
+ If you use it in a program, you are probably losing. */
+
+#if defined (__STDC__) && __STDC__
+/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
+ obstack.h because it is just for debugging. */
+int _obstack_allocated_p (struct obstack *h, POINTER obj);
+#endif
+
+int
+_obstack_allocated_p (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = (h)->chunk;
+ /* We use >= rather than > since the object cannot be exactly at
+ the beginning of the chunk but might be an empty object exactly
+ at the end of an adjacent chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ lp = plp;
+ }
+ return lp != 0;
+}
+
+/* Free objects in obstack H, including OBJ and everything allocate
+ more recently than OBJ. If OBJ is zero, free everything in H. */
+
+#undef obstack_free
+
+/* This function has two names with identical definitions.
+ This is the first one, called from non-ANSI code. */
+
+void
+_obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+/* This function is used from ANSI code. */
+
+void
+obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+int
+_obstack_memory_used (h)
+ struct obstack *h;
+{
+ register struct _obstack_chunk* lp;
+ register int nbytes = 0;
+
+ for (lp = h->chunk; lp != 0; lp = lp->prev)
+ {
+ nbytes += lp->limit - (char *) lp;
+ }
+ return nbytes;
+}
+
+/* Define the error handler. */
+#ifndef _
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# ifndef _
+# define _(Str) gettext (Str)
+# endif
+# else
+# define _(Str) (Str)
+# endif
+#endif
+
+static void
+print_and_abort ()
+{
+ fputs (_("memory exhausted\n"), stderr);
+ exit (obstack_exit_failure);
+}
+
+#if 0
+/* These are now turned off because the applications do not use it
+ and it uses bcopy via obstack_grow, which causes trouble on sysV. */
+
+/* Now define the functional versions of the obstack macros.
+ Define them to simply use the corresponding macros to do the job. */
+
+#if defined (__STDC__) && __STDC__
+/* These function definitions do not work with non-ANSI preprocessors;
+ they won't pass through the macro names in parentheses. */
+
+/* The function names appear in parentheses in order to prevent
+ the macro-definitions of the names from being expanded there. */
+
+POINTER (obstack_base) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_base (obstack);
+}
+
+POINTER (obstack_next_free) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_next_free (obstack);
+}
+
+int (obstack_object_size) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_object_size (obstack);
+}
+
+int (obstack_room) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_room (obstack);
+}
+
+int (obstack_make_room) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_make_room (obstack, length);
+}
+
+void (obstack_grow) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow (obstack, pointer, length);
+}
+
+void (obstack_grow0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow0 (obstack, pointer, length);
+}
+
+void (obstack_1grow) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow (obstack, character);
+}
+
+void (obstack_blank) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank (obstack, length);
+}
+
+void (obstack_1grow_fast) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow_fast (obstack, character);
+}
+
+void (obstack_blank_fast) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank_fast (obstack, length);
+}
+
+POINTER (obstack_finish) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_finish (obstack);
+}
+
+POINTER (obstack_alloc) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_alloc (obstack, length);
+}
+
+POINTER (obstack_copy) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy (obstack, pointer, length);
+}
+
+POINTER (obstack_copy0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy0 (obstack, pointer, length);
+}
+
+#endif /* __STDC__ */
+
+#endif /* 0 */
+
+#endif /* !ELIDE_CODE */
diff --git a/libiberty/pexecute.c b/libiberty/pexecute.c
new file mode 100644
index 00000000000..6da97deee4b
--- /dev/null
+++ b/libiberty/pexecute.c
@@ -0,0 +1,738 @@
+/* Utilities to execute a program in a subprocess (possibly linked by pipes
+ with other subprocesses), and wait for it.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This file exports two functions: pexecute and pwait. */
+
+/* This file lives in at least two places: libiberty and gcc.
+ Don't change one without the other. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#define ISSPACE (x) isspace(x)
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef vfork /* Autoconf may define this to fork for us. */
+# define VFORK_STRING "fork"
+#else
+# define VFORK_STRING "vfork"
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+#ifdef VMS
+#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
+ lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
+#endif /* VMS */
+
+#include "libiberty.h"
+
+#if !defined (__CYGWIN__) && defined (__CYGWIN32__)
+#define __CYGWIN__ 1
+#endif
+
+/* stdin file number. */
+#define STDIN_FILE_NO 0
+
+/* stdout file number. */
+#define STDOUT_FILE_NO 1
+
+/* value of `pipe': port index for reading. */
+#define READ_PORT 0
+
+/* value of `pipe': port index for writing. */
+#define WRITE_PORT 1
+
+static char *install_error_msg = "installation problem, cannot exec `%s'";
+
+/* pexecute: execute a program.
+
+ PROGRAM and ARGV are the arguments to execv/execvp.
+
+ THIS_PNAME is name of the calling program (i.e. argv[0]).
+
+ TEMP_BASE is the path name, sans suffix, of a temporary file to use
+ if needed. This is currently only needed for MSDOS ports that don't use
+ GO32 (do any still exist?). Ports that don't need it can pass NULL.
+
+ (FLAGS & PEXECUTE_SEARCH) is non-zero if $PATH should be searched
+ (??? It's not clear that GCC passes this flag correctly).
+ (FLAGS & PEXECUTE_FIRST) is nonzero for the first process in chain.
+ (FLAGS & PEXECUTE_FIRST) is nonzero for the last process in chain.
+ FIRST_LAST could be simplified to only mark the last of a chain of processes
+ but that requires the caller to always mark the last one (and not give up
+ early if some error occurs). It's more robust to require the caller to
+ mark both ends of the chain.
+
+ The result is the pid on systems like Unix where we fork/exec and on systems
+ like WIN32 and OS2 where we use spawn. It is up to the caller to wait for
+ the child.
+
+ The result is the WEXITSTATUS on systems like MSDOS where we spawn and wait
+ for the child here.
+
+ Upon failure, ERRMSG_FMT and ERRMSG_ARG are set to the text of the error
+ message with an optional argument (if not needed, ERRMSG_ARG is set to
+ NULL), and -1 is returned. `errno' is available to the caller to use.
+
+ pwait: cover function for wait.
+
+ PID is the process id of the task to wait for.
+ STATUS is the `status' argument to wait.
+ FLAGS is currently unused (allows future enhancement without breaking
+ upward compatibility). Pass 0 for now.
+
+ The result is the pid of the child reaped,
+ or -1 for failure (errno says why).
+
+ On systems that don't support waiting for a particular child, PID is
+ ignored. On systems like MSDOS that don't really multitask pwait
+ is just a mechanism to provide a consistent interface for the caller.
+
+ pfinish: finish generation of script
+
+ pfinish is necessary for systems like MPW where a script is generated that
+ runs the requested programs.
+*/
+
+#ifdef __MSDOS__
+
+/* MSDOS doesn't multitask, but for the sake of a consistent interface
+ the code behaves like it does. pexecute runs the program, tucks the
+ exit code away, and returns a "pid". pwait must be called to fetch the
+ exit code. */
+
+#include <process.h>
+
+/* For communicating information from pexecute to pwait. */
+static int last_pid = 0;
+static int last_status = 0;
+static int last_reaped = 0;
+
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base;
+ char **errmsg_fmt, **errmsg_arg;
+ int flags;
+{
+ int rc;
+
+ last_pid++;
+ if (last_pid < 0)
+ last_pid = 1;
+
+ if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
+ abort ();
+
+#ifdef __GO32__
+ /* ??? What are the possible return values from spawnv? */
+ rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
+#else
+ char *scmd, *rf;
+ FILE *argfile;
+ int i, el = flags & PEXECUTE_SEARCH ? 4 : 0;
+
+ scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
+ rf = scmd + strlen(program) + 2 + el;
+ sprintf (scmd, "%s%s @%s.gp", program,
+ (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
+ argfile = fopen (rf, "w");
+ if (argfile == 0)
+ {
+ int errno_save = errno;
+ free (scmd);
+ errno = errno_save;
+ *errmsg_fmt = "cannot open `%s.gp'";
+ *errmsg_arg = temp_base;
+ return -1;
+ }
+
+ for (i=1; argv[i]; i++)
+ {
+ char *cp;
+ for (cp = argv[i]; *cp; cp++)
+ {
+ if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp))
+ fputc ('\\', argfile);
+ fputc (*cp, argfile);
+ }
+ fputc ('\n', argfile);
+ }
+ fclose (argfile);
+
+ rc = system (scmd);
+
+ {
+ int errno_save = errno;
+ remove (rf);
+ free (scmd);
+ errno = errno_save;
+ }
+#endif
+
+ if (rc == -1)
+ {
+ *errmsg_fmt = install_error_msg;
+ *errmsg_arg = program;
+ return -1;
+ }
+
+ /* Tuck the status away for pwait, and return a "pid". */
+ last_status = rc << 8;
+ return last_pid;
+}
+
+int
+pwait (pid, status, flags)
+ int pid;
+ int *status;
+ int flags;
+{
+ /* On MSDOS each pexecute must be followed by it's associated pwait. */
+ if (pid != last_pid
+ /* Called twice for the same child? */
+ || pid == last_reaped)
+ {
+ /* ??? ECHILD would be a better choice. Can we use it here? */
+ errno = EINVAL;
+ return -1;
+ }
+ /* ??? Here's an opportunity to canonicalize the values in STATUS.
+ Needed? */
+ *status = last_status;
+ last_reaped = last_pid;
+ return last_pid;
+}
+
+#endif /* MSDOS */
+
+#if defined (_WIN32) && ! defined (__UWIN__)
+
+#include <process.h>
+
+#ifdef __CYGWIN__
+
+#define fix_argv(argvec) (argvec)
+
+extern int _spawnv ();
+extern int _spawnvp ();
+
+#else /* ! __CYGWIN__ */
+
+/* This is a kludge to get around the Microsoft C spawn functions' propensity
+ to remove the outermost set of double quotes from all arguments. */
+
+const char * const *
+fix_argv (argvec)
+ char **argvec;
+{
+ int i;
+
+ for (i = 1; argvec[i] != 0; i++)
+ {
+ int len, j;
+ char *temp, *newtemp;
+
+ temp = argvec[i];
+ len = strlen (temp);
+ for (j = 0; j < len; j++)
+ {
+ if (temp[j] == '"')
+ {
+ newtemp = xmalloc (len + 2);
+ strncpy (newtemp, temp, j);
+ newtemp [j] = '\\';
+ strncpy (&newtemp [j+1], &temp [j], len-j);
+ newtemp [len+1] = 0;
+ temp = newtemp;
+ len++;
+ j++;
+ }
+ }
+
+ argvec[i] = temp;
+ }
+
+ return (const char * const *) argvec;
+}
+#endif /* __CYGWIN__ */
+
+#include <io.h>
+#include <fcntl.h>
+#include <signal.h>
+
+/* mingw32 headers may not define the following. */
+
+#ifndef _P_WAIT
+# define _P_WAIT 0
+# define _P_NOWAIT 1
+# define _P_OVERLAY 2
+# define _P_NOWAITO 3
+# define _P_DETACH 4
+
+# define WAIT_CHILD 0
+# define WAIT_GRANDCHILD 1
+#endif
+
+/* Win32 supports pipes */
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base;
+ char **errmsg_fmt, **errmsg_arg;
+ int flags;
+{
+ int pid;
+ int pdes[2], org_stdin, org_stdout;
+ int input_desc, output_desc;
+ int retries, sleep_interval;
+
+ /* Pipe waiting from last process, to be used as input for the next one.
+ Value is STDIN_FILE_NO if no pipe is waiting
+ (i.e. the next command is the first of a group). */
+ static int last_pipe_input;
+
+ /* If this is the first process, initialize. */
+ if (flags & PEXECUTE_FIRST)
+ last_pipe_input = STDIN_FILE_NO;
+
+ input_desc = last_pipe_input;
+
+ /* If this isn't the last process, make a pipe for its output,
+ and record it as waiting to be the input to the next process. */
+ if (! (flags & PEXECUTE_LAST))
+ {
+ if (_pipe (pdes, 256, O_BINARY) < 0)
+ {
+ *errmsg_fmt = "pipe";
+ *errmsg_arg = NULL;
+ return -1;
+ }
+ output_desc = pdes[WRITE_PORT];
+ last_pipe_input = pdes[READ_PORT];
+ }
+ else
+ {
+ /* Last process. */
+ output_desc = STDOUT_FILE_NO;
+ last_pipe_input = STDIN_FILE_NO;
+ }
+
+ if (input_desc != STDIN_FILE_NO)
+ {
+ org_stdin = dup (STDIN_FILE_NO);
+ dup2 (input_desc, STDIN_FILE_NO);
+ close (input_desc);
+ }
+
+ if (output_desc != STDOUT_FILE_NO)
+ {
+ org_stdout = dup (STDOUT_FILE_NO);
+ dup2 (output_desc, STDOUT_FILE_NO);
+ close (output_desc);
+ }
+
+ pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
+ (_P_NOWAIT, program, fix_argv(argv));
+
+ if (input_desc != STDIN_FILE_NO)
+ {
+ dup2 (org_stdin, STDIN_FILE_NO);
+ close (org_stdin);
+ }
+
+ if (output_desc != STDOUT_FILE_NO)
+ {
+ dup2 (org_stdout, STDOUT_FILE_NO);
+ close (org_stdout);
+ }
+
+ if (pid == -1)
+ {
+ *errmsg_fmt = install_error_msg;
+ *errmsg_arg = program;
+ return -1;
+ }
+
+ return pid;
+}
+
+/* MS CRTDLL doesn't return enough information in status to decide if the
+ child exited due to a signal or not, rather it simply returns an
+ integer with the exit code of the child; eg., if the child exited with
+ an abort() call and didn't have a handler for SIGABRT, it simply returns
+ with status = 3. We fix the status code to conform to the usual WIF*
+ macros. Note that WIFSIGNALED will never be true under CRTDLL. */
+
+int
+pwait (pid, status, flags)
+ int pid;
+ int *status;
+ int flags;
+{
+#ifdef __CYGWIN__
+ return wait (status);
+#else
+ int termstat;
+
+ pid = _cwait (&termstat, pid, WAIT_CHILD);
+
+ /* ??? Here's an opportunity to canonicalize the values in STATUS.
+ Needed? */
+
+ /* cwait returns the child process exit code in termstat.
+ A value of 3 indicates that the child caught a signal, but not
+ which one. Since only SIGABRT, SIGFPE and SIGINT do anything, we
+ report SIGABRT. */
+ if (termstat == 3)
+ *status = SIGABRT;
+ else
+ *status = (((termstat) & 0xff) << 8);
+
+ return pid;
+#endif /* __CYGWIN__ */
+}
+
+#endif /* _WIN32 && ! __UWIN__ */
+
+#ifdef OS2
+
+/* ??? Does OS2 have process.h? */
+extern int spawnv ();
+extern int spawnvp ();
+
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base;
+ char **errmsg_fmt, **errmsg_arg;
+ int flags;
+{
+ int pid;
+
+ if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
+ abort ();
+ /* ??? Presumably 1 == _P_NOWAIT. */
+ pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
+ if (pid == -1)
+ {
+ *errmsg_fmt = install_error_msg;
+ *errmsg_arg = program;
+ return -1;
+ }
+ return pid;
+}
+
+int
+pwait (pid, status, flags)
+ int pid;
+ int *status;
+ int flags;
+{
+ /* ??? Here's an opportunity to canonicalize the values in STATUS.
+ Needed? */
+ int pid = wait (status);
+ return pid;
+}
+
+#endif /* OS2 */
+
+#ifdef MPW
+
+/* MPW pexecute doesn't actually run anything; instead, it writes out
+ script commands that, when run, will do the actual executing.
+
+ For example, in GCC's case, GCC will write out several script commands:
+
+ cpp ...
+ cc1 ...
+ as ...
+ ld ...
+
+ and then exit. None of the above programs will have run yet. The task
+ that called GCC will then execute the script and cause cpp,etc. to run.
+ The caller must invoke pfinish before calling exit. This adds
+ the finishing touches to the generated script. */
+
+static int first_time = 1;
+
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base;
+ char **errmsg_fmt, **errmsg_arg;
+ int flags;
+{
+ char tmpprogram[255];
+ char *cp, *tmpname;
+ int i;
+
+ mpwify_filename (program, tmpprogram);
+ if (first_time)
+ {
+ printf ("Set Failed 0\n");
+ first_time = 0;
+ }
+
+ fputs ("If {Failed} == 0\n", stdout);
+ /* If being verbose, output a copy of the command. It should be
+ accurate enough and escaped enough to be "clickable". */
+ if (flags & PEXECUTE_VERBOSE)
+ {
+ fputs ("\tEcho ", stdout);
+ fputc ('\'', stdout);
+ fputs (tmpprogram, stdout);
+ fputc ('\'', stdout);
+ fputc (' ', stdout);
+ for (i=1; argv[i]; i++)
+ {
+ fputc ('\'', stdout);
+ /* See if we have an argument that needs fixing. */
+ if (strchr(argv[i], '/'))
+ {
+ tmpname = (char *) xmalloc (256);
+ mpwify_filename (argv[i], tmpname);
+ argv[i] = tmpname;
+ }
+ for (cp = argv[i]; *cp; cp++)
+ {
+ /* Write an Option-d escape char in front of special chars. */
+ if (strchr("'+", *cp))
+ fputc ('\266', stdout);
+ fputc (*cp, stdout);
+ }
+ fputc ('\'', stdout);
+ fputc (' ', stdout);
+ }
+ fputs ("\n", stdout);
+ }
+ fputs ("\t", stdout);
+ fputs (tmpprogram, stdout);
+ fputc (' ', stdout);
+
+ for (i=1; argv[i]; i++)
+ {
+ /* See if we have an argument that needs fixing. */
+ if (strchr(argv[i], '/'))
+ {
+ tmpname = (char *) xmalloc (256);
+ mpwify_filename (argv[i], tmpname);
+ argv[i] = tmpname;
+ }
+ if (strchr (argv[i], ' '))
+ fputc ('\'', stdout);
+ for (cp = argv[i]; *cp; cp++)
+ {
+ /* Write an Option-d escape char in front of special chars. */
+ if (strchr("'+", *cp))
+ fputc ('\266', stdout);
+ fputc (*cp, stdout);
+ }
+ if (strchr (argv[i], ' '))
+ fputc ('\'', stdout);
+ fputc (' ', stdout);
+ }
+
+ fputs ("\n", stdout);
+
+ /* Output commands that arrange to clean up and exit if a failure occurs.
+ We have to be careful to collect the status from the program that was
+ run, rather than some other script command. Also, we don't exit
+ immediately, since necessary cleanups are at the end of the script. */
+ fputs ("\tSet TmpStatus {Status}\n", stdout);
+ fputs ("\tIf {TmpStatus} != 0\n", stdout);
+ fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
+ fputs ("\tEnd\n", stdout);
+ fputs ("End\n", stdout);
+
+ /* We're just composing a script, can't fail here. */
+ return 0;
+}
+
+int
+pwait (pid, status, flags)
+ int pid;
+ int *status;
+ int flags;
+{
+ *status = 0;
+ return 0;
+}
+
+/* Write out commands that will exit with the correct error code
+ if something in the script failed. */
+
+void
+pfinish ()
+{
+ printf ("\tExit \"{Failed}\"\n");
+}
+
+#endif /* MPW */
+
+/* include for Unix-like environments but not for Dos-like environments */
+#if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \
+ && ! (defined (_WIN32) && ! defined (__UWIN__))
+
+extern int execv ();
+extern int execvp ();
+
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base;
+ char **errmsg_fmt, **errmsg_arg;
+ int flags;
+{
+ int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
+ int pid;
+ int pdes[2];
+ int input_desc, output_desc;
+ int retries, sleep_interval;
+ /* Pipe waiting from last process, to be used as input for the next one.
+ Value is STDIN_FILE_NO if no pipe is waiting
+ (i.e. the next command is the first of a group). */
+ static int last_pipe_input;
+
+ /* If this is the first process, initialize. */
+ if (flags & PEXECUTE_FIRST)
+ last_pipe_input = STDIN_FILE_NO;
+
+ input_desc = last_pipe_input;
+
+ /* If this isn't the last process, make a pipe for its output,
+ and record it as waiting to be the input to the next process. */
+ if (! (flags & PEXECUTE_LAST))
+ {
+ if (pipe (pdes) < 0)
+ {
+ *errmsg_fmt = "pipe";
+ *errmsg_arg = NULL;
+ return -1;
+ }
+ output_desc = pdes[WRITE_PORT];
+ last_pipe_input = pdes[READ_PORT];
+ }
+ else
+ {
+ /* Last process. */
+ output_desc = STDOUT_FILE_NO;
+ last_pipe_input = STDIN_FILE_NO;
+ }
+
+ /* Fork a subprocess; wait and retry if it fails. */
+ sleep_interval = 1;
+ for (retries = 0; retries < 4; retries++)
+ {
+ pid = vfork ();
+ if (pid >= 0)
+ break;
+ sleep (sleep_interval);
+ sleep_interval *= 2;
+ }
+
+ switch (pid)
+ {
+ case -1:
+ {
+ *errmsg_fmt = VFORK_STRING;
+ *errmsg_arg = NULL;
+ return -1;
+ }
+
+ case 0: /* child */
+ /* Move the input and output pipes into place, if necessary. */
+ if (input_desc != STDIN_FILE_NO)
+ {
+ close (STDIN_FILE_NO);
+ dup (input_desc);
+ close (input_desc);
+ }
+ if (output_desc != STDOUT_FILE_NO)
+ {
+ close (STDOUT_FILE_NO);
+ dup (output_desc);
+ close (output_desc);
+ }
+
+ /* Close the parent's descs that aren't wanted here. */
+ if (last_pipe_input != STDIN_FILE_NO)
+ close (last_pipe_input);
+
+ /* Exec the program. */
+ (*func) (program, argv);
+
+ /* Note: Calling fprintf and exit here doesn't seem right for vfork. */
+ fprintf (stderr, "%s: ", this_pname);
+ fprintf (stderr, install_error_msg, program);
+ fprintf (stderr, ": %s\n", xstrerror (errno));
+ exit (-1);
+ /* NOTREACHED */
+ return 0;
+
+ default:
+ /* In the parent, after forking.
+ Close the descriptors that we made for this child. */
+ if (input_desc != STDIN_FILE_NO)
+ close (input_desc);
+ if (output_desc != STDOUT_FILE_NO)
+ close (output_desc);
+
+ /* Return child's process number. */
+ return pid;
+ }
+}
+
+int
+pwait (pid, status, flags)
+ int pid;
+ int *status;
+ int flags;
+{
+ /* ??? Here's an opportunity to canonicalize the values in STATUS.
+ Needed? */
+#ifdef VMS
+ pid = waitpid (-1, status, 0);
+#else
+ pid = wait (status);
+#endif
+ return pid;
+}
+
+#endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! (_WIN32 && ! __UWIN__) */
diff --git a/libiberty/random.c b/libiberty/random.c
new file mode 100644
index 00000000000..0a950709fce
--- /dev/null
+++ b/libiberty/random.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ */
+
+#include <errno.h>
+
+#if 0
+
+#include <ansidecl.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#else
+
+#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF for 32-bits */
+#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits*/
+
+#ifdef __STDC__
+# define PTR void *
+# ifndef NULL
+# define NULL (void *) 0
+# endif
+#else
+# define PTR char *
+# ifndef NULL
+# define NULL (void *) 0
+# endif
+#endif
+
+#endif
+
+long int random ();
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initiallized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroeth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroeth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* For each of the currently supported random number generators, we have a
+ break value on the amount of state information (you need at least thi
+ bytes of state info to support this random number generator), a degree for
+ the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ separation between the two lower order coefficients of the trinomial. */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+
+/* Array versions of the above information to make code run faster.
+ Relies on fact that TYPE_i == i. */
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+
+
+/* Initially, everything is set up as if from:
+ initstate(1, randtbl, 128);
+ Note that this initialization takes advantage of the fact that srandom
+ advances the front and rear pointers 10*rand_deg times, and hence the
+ rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ element of the state information, which contains info about the current
+ position of the rear pointer is just
+ (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
+
+static long int randtbl[DEG_3 + 1] =
+ { TYPE_3,
+ 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
+ 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb,
+ 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
+ 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86,
+ 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7,
+ 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
+ 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b,
+ 0xf5ad9d0e, 0x8999220b, 0x27fb47b9
+ };
+
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+ pointer. These two pointers are always rand_sep places aparts, as they
+ cycle through the state information. (Yes, this does mean we could get
+ away with just one pointer, but the code for random is more efficient
+ this way). The pointers are left positioned as they would be from the call:
+ initstate(1, randtbl, 128);
+ (The position of the rear pointer, rptr, is really 0 (as explained above
+ in the initialization of randtbl) because the state table pointer is set
+ to point to randtbl[1] (as explained below).) */
+
+static long int *fptr = &randtbl[SEP_3 + 1];
+static long int *rptr = &randtbl[1];
+
+
+
+/* The following things are the pointer to the state information table,
+ the type of the current generator, the degree of the current polynomial
+ being used, and the separation between the two pointers.
+ Note that for efficiency of random, we remember the first location of
+ the state information, not the zeroeth. Hence it is valid to access
+ state[-1], which is used to store the type of the R.N.G.
+ Also, we remember the last location, since this is more efficient than
+ indexing every time to find the address of the last element to see if
+ the front and rear pointers have wrapped. */
+
+static long int *state = &randtbl[1];
+
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+
+static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+void
+srandom (x)
+ unsigned int x;
+{
+ state[0] = x;
+ if (rand_type != TYPE_0)
+ {
+ register long int i;
+ for (i = 1; i < rand_deg; ++i)
+ state[i] = (1103515145 * state[i - 1]) + 12345;
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; ++i)
+ random();
+ }
+}
+
+/* Initialize the state information in the given array of N bytes for
+ future random number generation. Based on the number of bytes we
+ are given, and the break values for the different R.N.G.'s, we choose
+ the best (largest) one we can and set things up for it. srandom is
+ then called to initialize the state information. Note that on return
+ from srandom, we set state[-1] to be the type multiplexed with the current
+ value of the rear pointer; this is so successive calls to initstate won't
+ lose this information and will be able to restart with setstate.
+ Note: The first thing we do is save the current state, if any, just like
+ setstate so that it doesn't matter when initstate is called.
+ Returns a pointer to the old state. */
+PTR
+initstate (seed, arg_state, n)
+ unsigned int seed;
+ PTR arg_state;
+ unsigned long n;
+{
+ PTR ostate = (PTR) &state[-1];
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+ if (n < BREAK_1)
+ {
+ if (n < BREAK_0)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+ rand_type = TYPE_0;
+ rand_deg = DEG_0;
+ rand_sep = SEP_0;
+ }
+ else if (n < BREAK_2)
+ {
+ rand_type = TYPE_1;
+ rand_deg = DEG_1;
+ rand_sep = SEP_1;
+ }
+ else if (n < BREAK_3)
+ {
+ rand_type = TYPE_2;
+ rand_deg = DEG_2;
+ rand_sep = SEP_2;
+ }
+ else if (n < BREAK_4)
+ {
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ }
+ else
+ {
+ rand_type = TYPE_4;
+ rand_deg = DEG_4;
+ rand_sep = SEP_4;
+ }
+
+ state = &((long int *) arg_state)[1]; /* First location. */
+ /* Must set END_PTR before srandom. */
+ end_ptr = &state[rand_deg];
+ srandom(seed);
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+
+ return ostate;
+}
+
+/* Restore the state from the given state array.
+ Note: It is important that we also remember the locations of the pointers
+ in the current state information, and restore the locations of the pointers
+ from the old state information. This is done by multiplexing the pointer
+ location into the zeroeth word of the state information. Note that due
+ to the order in which things are done, it is OK to call setstate with the
+ same state as the current state
+ Returns a pointer to the old state information. */
+
+PTR
+setstate (arg_state)
+ PTR arg_state;
+{
+ register long int *new_state = (long int *) arg_state;
+ register int type = new_state[0] % MAX_TYPES;
+ register int rear = new_state[0] / MAX_TYPES;
+ PTR ostate = (PTR) &state[-1];
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+
+ switch (type)
+ {
+ case TYPE_0:
+ case TYPE_1:
+ case TYPE_2:
+ case TYPE_3:
+ case TYPE_4:
+ rand_type = type;
+ rand_deg = degrees[type];
+ rand_sep = seps[type];
+ break;
+ default:
+ /* State info munged. */
+ errno = EINVAL;
+ return NULL;
+ }
+
+ state = &new_state[1];
+ if (rand_type != TYPE_0)
+ {
+ rptr = &state[rear];
+ fptr = &state[(rear + rand_sep) % rand_deg];
+ }
+ /* Set end_ptr too. */
+ end_ptr = &state[rand_deg];
+
+ return ostate;
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all ther other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+long int
+random ()
+{
+ if (rand_type == TYPE_0)
+ {
+ state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
+ return state[0];
+ }
+ else
+ {
+ long int i;
+ *fptr += *rptr;
+ /* Chucking least random bit. */
+ i = (*fptr >> 1) & LONG_MAX;
+ ++fptr;
+ if (fptr >= end_ptr)
+ {
+ fptr = state;
+ ++rptr;
+ }
+ else
+ {
+ ++rptr;
+ if (rptr >= end_ptr)
+ rptr = state;
+ }
+ return i;
+ }
+}
diff --git a/libiberty/rename.c b/libiberty/rename.c
new file mode 100644
index 00000000000..ae26e2d0040
--- /dev/null
+++ b/libiberty/rename.c
@@ -0,0 +1,22 @@
+/* rename -- rename a file
+ This function is in the public domain. */
+
+/* Rename a file. */
+
+#include <errno.h>
+
+int
+rename (zfrom, zto)
+ char *zfrom;
+ char *zto;
+{
+ if (link (zfrom, zto) < 0)
+ {
+ if (errno != EEXIST)
+ return -1;
+ if (unlink (zto) < 0
+ || link (zfrom, zto) < 0)
+ return -1;
+ }
+ return unlink (zfrom);
+}
diff --git a/libiberty/rindex.c b/libiberty/rindex.c
new file mode 100644
index 00000000000..061d1269f17
--- /dev/null
+++ b/libiberty/rindex.c
@@ -0,0 +1,11 @@
+/* Stub implementation of (obsolete) rindex(). */
+
+extern char *strrchr ();
+
+char *
+rindex (s, c)
+ char *s;
+ int c;
+{
+ return strrchr (s, c);
+}
diff --git a/libiberty/sigsetmask.c b/libiberty/sigsetmask.c
new file mode 100644
index 00000000000..2a09e6a6c5a
--- /dev/null
+++ b/libiberty/sigsetmask.c
@@ -0,0 +1,30 @@
+/* Version of sigsetmask.c
+ Written by Steve Chamberlain (sac@cygnus.com).
+ Contributed by Cygnus Support.
+ This file is in the public doamin. */
+
+/* Set the current signal mask to the set provided, and return the
+ previous value */
+
+#define _POSIX_SOURCE
+#include <ansidecl.h>
+/* Including <sys/types.h> seems to be needed by ISC. */
+#include <sys/types.h>
+#include <signal.h>
+
+#ifdef SIG_SETMASK
+int
+DEFUN(sigsetmask,(set),
+ int set)
+{
+ sigset_t new;
+ sigset_t old;
+
+ sigemptyset (&new);
+ if (set != 0) {
+ abort(); /* FIXME, we don't know how to translate old mask to new */
+ }
+ sigprocmask(SIG_SETMASK, &new, &old);
+ return 1; /* FIXME, we always return 1 as old value. */
+}
+#endif
diff --git a/libiberty/spaces.c b/libiberty/spaces.c
new file mode 100644
index 00000000000..ea925712e3f
--- /dev/null
+++ b/libiberty/spaces.c
@@ -0,0 +1,78 @@
+/* Allocate memory region filled with spaces.
+ Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/*
+
+NAME
+
+ spaces -- return a pointer to a buffer full of spaces
+
+SYNOPSIS
+
+ char *spaces (int count)
+
+DESCRIPTION
+
+ Returns a pointer to a memory region filled with the specified
+ number of spaces and null terminated. The returned pointer is
+ valid until at least the next call.
+
+BUGS
+
+*/
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#if VMS
+#include <stdlib.h>
+#include <unixlib.h>
+#else
+/* For systems with larger pointers than ints, these must be declared. */
+extern PTR malloc PARAMS ((size_t));
+extern void free PARAMS ((PTR));
+#endif
+
+const char *
+spaces (count)
+ int count;
+{
+ register char *t;
+ static char *buf;
+ static int maxsize;
+
+ if (count > maxsize)
+ {
+ if (buf)
+ {
+ free (buf);
+ }
+ buf = malloc (count + 1);
+ if (buf == (char *) 0)
+ return 0;
+ for (t = buf + count ; t != buf ; )
+ {
+ *--t = ' ';
+ }
+ maxsize = count;
+ buf[count] = '\0';
+ }
+ return (const char *) (buf + maxsize - count);
+}
+
diff --git a/libiberty/splay-tree.c b/libiberty/splay-tree.c
new file mode 100644
index 00000000000..b6bb5a6a8f0
--- /dev/null
+++ b/libiberty/splay-tree.c
@@ -0,0 +1,368 @@
+/* A splay-tree datatype.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Mark Mitchell (mark@markmitchell.com).
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* For an easily readable description of splay-trees, see:
+
+ Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
+ Algorithms. Harper-Collins, Inc. 1991. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "libiberty.h"
+#include "splay-tree.h"
+
+static void splay_tree_delete_helper PARAMS((splay_tree,
+ splay_tree_node));
+static void splay_tree_splay PARAMS((splay_tree,
+ splay_tree_key));
+static splay_tree_node splay_tree_splay_helper
+ PARAMS((splay_tree,
+ splay_tree_key,
+ splay_tree_node*,
+ splay_tree_node*,
+ splay_tree_node*));
+static int splay_tree_foreach_helper PARAMS((splay_tree,
+ splay_tree_node,
+ splay_tree_foreach_fn,
+ void*));
+
+/* Deallocate NODE (a member of SP), and all its sub-trees. */
+
+static void
+splay_tree_delete_helper (sp, node)
+ splay_tree sp;
+ splay_tree_node node;
+{
+ if (!node)
+ return;
+
+ splay_tree_delete_helper (sp, node->left);
+ splay_tree_delete_helper (sp, node->right);
+
+ if (sp->delete_key)
+ (*sp->delete_key)(node->key);
+ if (sp->delete_value)
+ (*sp->delete_value)(node->value);
+
+ free ((char*) node);
+}
+
+/* Help splay SP around KEY. PARENT and GRANDPARENT are the parent
+ and grandparent, respectively, of NODE. */
+
+static splay_tree_node
+splay_tree_splay_helper (sp, key, node, parent, grandparent)
+ splay_tree sp;
+ splay_tree_key key;
+ splay_tree_node *node;
+ splay_tree_node *parent;
+ splay_tree_node *grandparent;
+{
+ splay_tree_node *next;
+ splay_tree_node n;
+ int comparison;
+
+ n = *node;
+
+ if (!n)
+ return *parent;
+
+ comparison = (*sp->comp) (key, n->key);
+
+ if (comparison == 0)
+ /* We've found the target. */
+ next = 0;
+ else if (comparison < 0)
+ /* The target is to the left. */
+ next = &n->left;
+ else
+ /* The target is to the right. */
+ next = &n->right;
+
+ if (next)
+ {
+ /* Continue down the tree. */
+ n = splay_tree_splay_helper (sp, key, next, node, parent);
+
+ /* The recursive call will change the place to which NODE
+ points. */
+ if (*node != n)
+ return n;
+ }
+
+ if (!parent)
+ /* NODE is the root. We are done. */
+ return n;
+
+ /* First, handle the case where there is no grandparent (i.e.,
+ *PARENT is the root of the tree.) */
+ if (!grandparent)
+ {
+ if (n == (*parent)->left)
+ {
+ *node = n->right;
+ n->right = *parent;
+ }
+ else
+ {
+ *node = n->left;
+ n->left = *parent;
+ }
+ *parent = n;
+ return n;
+ }
+
+ /* Next handle the cases where both N and *PARENT are left children,
+ or where both are right children. */
+ if (n == (*parent)->left && *parent == (*grandparent)->left)
+ {
+ splay_tree_node p = *parent;
+
+ (*grandparent)->left = p->right;
+ p->right = *grandparent;
+ p->left = n->right;
+ n->right = p;
+ *grandparent = n;
+ return n;
+ }
+ else if (n == (*parent)->right && *parent == (*grandparent)->right)
+ {
+ splay_tree_node p = *parent;
+
+ (*grandparent)->right = p->left;
+ p->left = *grandparent;
+ p->right = n->left;
+ n->left = p;
+ *grandparent = n;
+ return n;
+ }
+
+ /* Finally, deal with the case where N is a left child, but *PARENT
+ is a right child, or vice versa. */
+ if (n == (*parent)->left)
+ {
+ (*parent)->left = n->right;
+ n->right = *parent;
+ (*grandparent)->right = n->left;
+ n->left = *grandparent;
+ *grandparent = n;
+ return n;
+ }
+ else
+ {
+ (*parent)->right = n->left;
+ n->left = *parent;
+ (*grandparent)->left = n->right;
+ n->right = *grandparent;
+ *grandparent = n;
+ return n;
+ }
+}
+
+/* Splay SP around KEY. */
+
+static void
+splay_tree_splay (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ if (sp->root == 0)
+ return;
+
+ splay_tree_splay_helper (sp, key, &sp->root,
+ /*grandparent=*/0, /*parent=*/0);
+}
+
+/* Call FN, passing it the DATA, for every node below NODE, all of
+ which are from SP, following an in-order traversal. If FN every
+ returns a non-zero value, the iteration ceases immediately, and the
+ value is returned. Otherwise, this function returns 0. */
+
+static int
+splay_tree_foreach_helper (sp, node, fn, data)
+ splay_tree sp;
+ splay_tree_node node;
+ splay_tree_foreach_fn fn;
+ void* data;
+{
+ int val;
+
+ if (!node)
+ return 0;
+
+ val = splay_tree_foreach_helper (sp, node->left, fn, data);
+ if (val)
+ return val;
+
+ val = (*fn)(node, data);
+ if (val)
+ return val;
+
+ return splay_tree_foreach_helper (sp, node->right, fn, data);
+}
+
+/* Allocate a new splay tree, using COMPARE_FN to compare nodes,
+ DELETE_KEY_FN to deallocate keys, and DELETE_VALUE_FN to deallocate
+ values. */
+
+splay_tree
+splay_tree_new (compare_fn, delete_key_fn, delete_value_fn)
+ splay_tree_compare_fn compare_fn;
+ splay_tree_delete_key_fn delete_key_fn;
+ splay_tree_delete_value_fn delete_value_fn;
+{
+ splay_tree sp = (splay_tree) xmalloc (sizeof (struct splay_tree));
+ sp->root = 0;
+ sp->comp = compare_fn;
+ sp->delete_key = delete_key_fn;
+ sp->delete_value = delete_value_fn;
+
+ return sp;
+}
+
+/* Deallocate SP. */
+
+void
+splay_tree_delete (sp)
+ splay_tree sp;
+{
+ splay_tree_delete_helper (sp, sp->root);
+ free ((char*) sp);
+}
+
+/* Insert a new node (associating KEY with DATA) into SP. If a
+ previous node with the indicated KEY exists, its data is replaced
+ with the new value. */
+
+void
+splay_tree_insert (sp, key, value)
+ splay_tree sp;
+ splay_tree_key key;
+ splay_tree_value value;
+{
+ int comparison;
+
+ splay_tree_splay (sp, key);
+
+ if (sp->root)
+ comparison = (*sp->comp)(sp->root->key, key);
+
+ if (sp->root && comparison == 0)
+ {
+ /* If the root of the tree already has the indicated KEY, just
+ replace the value with VALUE. */
+ if (sp->delete_value)
+ (*sp->delete_value)(sp->root->value);
+ sp->root->value = value;
+ }
+ else
+ {
+ /* Create a new node, and insert it at the root. */
+ splay_tree_node node;
+
+ node = (splay_tree_node) xmalloc (sizeof (struct splay_tree_node));
+ node->key = key;
+ node->value = value;
+
+ if (!sp->root)
+ node->left = node->right = 0;
+ else if (comparison < 0)
+ {
+ node->left = sp->root;
+ node->right = node->left->right;
+ node->left->right = 0;
+ }
+ else
+ {
+ node->right = sp->root;
+ node->left = node->right->left;
+ node->right->left = 0;
+ }
+
+ sp->root = node;
+ }
+}
+
+/* Lookup KEY in SP, returning VALUE if present, and NULL
+ otherwise. */
+
+splay_tree_node
+splay_tree_lookup (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ splay_tree_splay (sp, key);
+
+ if (sp->root && (*sp->comp)(sp->root->key, key) == 0)
+ return sp->root;
+ else
+ return 0;
+}
+
+/* Call FN, passing it the DATA, for every node in SP, following an
+ in-order traversal. If FN every returns a non-zero value, the
+ iteration ceases immediately, and the value is returned.
+ Otherwise, this function returns 0. */
+
+int
+splay_tree_foreach (sp, fn, data)
+ splay_tree sp;
+ splay_tree_foreach_fn fn;
+ void *data;
+{
+ return splay_tree_foreach_helper (sp, sp->root, fn, data);
+}
+
+/* Splay-tree comparison function, treating the keys as ints. */
+
+int
+splay_tree_compare_ints (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ if ((int) k1 < (int) k2)
+ return -1;
+ else if ((int) k1 > (int) k2)
+ return 1;
+ else
+ return 0;
+}
+
+/* Splay-tree comparison function, treating the keys as pointers. */
+
+int
+splay_tree_compare_pointers (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ if ((char*) k1 < (char*) k2)
+ return -1;
+ else if ((char*) k1 > (char*) k2)
+ return 1;
+ else
+ return 0;
+}
diff --git a/libiberty/strcasecmp.c b/libiberty/strcasecmp.c
new file mode 100644
index 00000000000..3aa930b696f
--- /dev/null
+++ b/libiberty/strcasecmp.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific written prior permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+typedef unsigned char uc;
+static unsigned char charmap[] = {
+ (uc)'\000',(uc)'\001',(uc)'\002',(uc)'\003',(uc)'\004',(uc)'\005',(uc)'\006',(uc)'\007',
+ (uc)'\010',(uc)'\011',(uc)'\012',(uc)'\013',(uc)'\014',(uc)'\015',(uc)'\016',(uc)'\017',
+ (uc)'\020',(uc)'\021',(uc)'\022',(uc)'\023',(uc)'\024',(uc)'\025',(uc)'\026',(uc)'\027',
+ (uc)'\030',(uc)'\031',(uc)'\032',(uc)'\033',(uc)'\034',(uc)'\035',(uc)'\036',(uc)'\037',
+ (uc)'\040',(uc)'\041',(uc)'\042',(uc)'\043',(uc)'\044',(uc)'\045',(uc)'\046',(uc)'\047',
+ (uc)'\050',(uc)'\051',(uc)'\052',(uc)'\053',(uc)'\054',(uc)'\055',(uc)'\056',(uc)'\057',
+ (uc)'\060',(uc)'\061',(uc)'\062',(uc)'\063',(uc)'\064',(uc)'\065',(uc)'\066',(uc)'\067',
+ (uc)'\070',(uc)'\071',(uc)'\072',(uc)'\073',(uc)'\074',(uc)'\075',(uc)'\076',(uc)'\077',
+ (uc)'\100',(uc)'\141',(uc)'\142',(uc)'\143',(uc)'\144',(uc)'\145',(uc)'\146',(uc)'\147',
+ (uc)'\150',(uc)'\151',(uc)'\152',(uc)'\153',(uc)'\154',(uc)'\155',(uc)'\156',(uc)'\157',
+ (uc)'\160',(uc)'\161',(uc)'\162',(uc)'\163',(uc)'\164',(uc)'\165',(uc)'\166',(uc)'\167',
+ (uc)'\170',(uc)'\171',(uc)'\172',(uc)'\133',(uc)'\134',(uc)'\135',(uc)'\136',(uc)'\137',
+ (uc)'\140',(uc)'\141',(uc)'\142',(uc)'\143',(uc)'\144',(uc)'\145',(uc)'\146',(uc)'\147',
+ (uc)'\150',(uc)'\151',(uc)'\152',(uc)'\153',(uc)'\154',(uc)'\155',(uc)'\156',(uc)'\157',
+ (uc)'\160',(uc)'\161',(uc)'\162',(uc)'\163',(uc)'\164',(uc)'\165',(uc)'\166',(uc)'\167',
+ (uc)'\170',(uc)'\171',(uc)'\172',(uc)'\173',(uc)'\174',(uc)'\175',(uc)'\176',(uc)'\177',
+ (uc)'\200',(uc)'\201',(uc)'\202',(uc)'\203',(uc)'\204',(uc)'\205',(uc)'\206',(uc)'\207',
+ (uc)'\210',(uc)'\211',(uc)'\212',(uc)'\213',(uc)'\214',(uc)'\215',(uc)'\216',(uc)'\217',
+ (uc)'\220',(uc)'\221',(uc)'\222',(uc)'\223',(uc)'\224',(uc)'\225',(uc)'\226',(uc)'\227',
+ (uc)'\230',(uc)'\231',(uc)'\232',(uc)'\233',(uc)'\234',(uc)'\235',(uc)'\236',(uc)'\237',
+ (uc)'\240',(uc)'\241',(uc)'\242',(uc)'\243',(uc)'\244',(uc)'\245',(uc)'\246',(uc)'\247',
+ (uc)'\250',(uc)'\251',(uc)'\252',(uc)'\253',(uc)'\254',(uc)'\255',(uc)'\256',(uc)'\257',
+ (uc)'\260',(uc)'\261',(uc)'\262',(uc)'\263',(uc)'\264',(uc)'\265',(uc)'\266',(uc)'\267',
+ (uc)'\270',(uc)'\271',(uc)'\272',(uc)'\273',(uc)'\274',(uc)'\275',(uc)'\276',(uc)'\277',
+ (uc)'\300',(uc)'\341',(uc)'\342',(uc)'\343',(uc)'\344',(uc)'\345',(uc)'\346',(uc)'\347',
+ (uc)'\350',(uc)'\351',(uc)'\352',(uc)'\353',(uc)'\354',(uc)'\355',(uc)'\356',(uc)'\357',
+ (uc)'\360',(uc)'\361',(uc)'\362',(uc)'\363',(uc)'\364',(uc)'\365',(uc)'\366',(uc)'\367',
+ (uc)'\370',(uc)'\371',(uc)'\372',(uc)'\333',(uc)'\334',(uc)'\335',(uc)'\336',(uc)'\337',
+ (uc)'\340',(uc)'\341',(uc)'\342',(uc)'\343',(uc)'\344',(uc)'\345',(uc)'\346',(uc)'\347',
+ (uc)'\350',(uc)'\351',(uc)'\352',(uc)'\353',(uc)'\354',(uc)'\355',(uc)'\356',(uc)'\357',
+ (uc)'\360',(uc)'\361',(uc)'\362',(uc)'\363',(uc)'\364',(uc)'\365',(uc)'\366',(uc)'\367',
+ (uc)'\370',(uc)'\371',(uc)'\372',(uc)'\373',(uc)'\374',(uc)'\375',(uc)'\376',(uc)'\377',
+};
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register unsigned char u1, u2;
+
+ for (;;) {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (charmap[u1] != charmap[u2]) {
+ return charmap[u1] - charmap[u2];
+ }
+ if (u1 == '\0') {
+ return 0;
+ }
+ }
+}
+
diff --git a/libiberty/strchr.c b/libiberty/strchr.c
new file mode 100644
index 00000000000..550480f56de
--- /dev/null
+++ b/libiberty/strchr.c
@@ -0,0 +1,34 @@
+/* Portable version of strchr()
+ This function is in the public domain. */
+
+/*
+NAME
+ strchr -- return pointer to first occurance of a character
+
+SYNOPSIS
+ char *strchr (const char *s, int c)
+
+DESCRIPTION
+ Returns a pointer to the first occurance of character C in
+ string S, or a NULL pointer if no occurance is found.
+
+BUGS
+ Behavior when character is the null character is implementation
+ dependent.
+*/
+
+#include <ansidecl.h>
+
+char *
+strchr (s, c)
+ register const char *s;
+ int c;
+{
+ do {
+ if (*s == c)
+ {
+ return (char*)s;
+ }
+ } while (*s++);
+ return (0);
+}
diff --git a/libiberty/strdup.c b/libiberty/strdup.c
new file mode 100644
index 00000000000..1785b34f274
--- /dev/null
+++ b/libiberty/strdup.c
@@ -0,0 +1,10 @@
+char *
+strdup(s)
+ char *s;
+{
+ char *result = (char*)malloc(strlen(s) + 1);
+ if (result == (char*)0)
+ return (char*)0;
+ strcpy(result, s);
+ return result;
+}
diff --git a/libiberty/strerror.c b/libiberty/strerror.c
new file mode 100644
index 00000000000..644cc75462a
--- /dev/null
+++ b/libiberty/strerror.c
@@ -0,0 +1,831 @@
+/* Extended support for using errno values.
+ Written by Fred Fish. fnf@cygnus.com
+ This file is in the public domain. --Per Bothner. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include "config.h"
+
+#ifdef HAVE_SYS_ERRLIST
+/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
+ might declare sys_errlist in a way that the compiler might consider
+ incompatible with our later declaration, perhaps by using const
+ attributes. So we hide the declaration in errno.h (if any) using a
+ macro. */
+#define sys_errlist sys_errlist__
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef HAVE_SYS_ERRLIST
+#undef sys_errlist
+#endif
+
+/* Routines imported from standard C runtime libraries. */
+
+#ifdef __STDC__
+#include <stddef.h>
+extern void *malloc (size_t size); /* 4.10.3.3 */
+extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
+#else /* !__STDC__ */
+extern char *malloc (); /* Standard memory allocater */
+extern char *memset ();
+#endif /* __STDC__ */
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+static void init_error_tables PARAMS ((void));
+
+/* Translation table for errno values. See intro(2) in most UNIX systems
+ Programmers Reference Manuals.
+
+ Note that this table is generally only accessed when it is used at runtime
+ to initialize errno name and message tables that are indexed by errno
+ value.
+
+ Not all of these errnos will exist on all systems. This table is the only
+ thing that should have to be updated as new error numbers are introduced.
+ It's sort of ugly, but at least its portable. */
+
+struct error_info
+{
+ int value; /* The numeric value from <errno.h> */
+ const char *name; /* The equivalent symbolic value */
+#ifndef HAVE_SYS_ERRLIST
+ const char *msg; /* Short message about this value */
+#endif
+};
+
+#ifndef HAVE_SYS_ERRLIST
+# define ENTRY(value, name, msg) {value, name, msg}
+#else
+# define ENTRY(value, name, msg) {value, name}
+#endif
+
+static const struct error_info error_table[] =
+{
+#if defined (EPERM)
+ ENTRY(EPERM, "EPERM", "Not owner"),
+#endif
+#if defined (ENOENT)
+ ENTRY(ENOENT, "ENOENT", "No such file or directory"),
+#endif
+#if defined (ESRCH)
+ ENTRY(ESRCH, "ESRCH", "No such process"),
+#endif
+#if defined (EINTR)
+ ENTRY(EINTR, "EINTR", "Interrupted system call"),
+#endif
+#if defined (EIO)
+ ENTRY(EIO, "EIO", "I/O error"),
+#endif
+#if defined (ENXIO)
+ ENTRY(ENXIO, "ENXIO", "No such device or address"),
+#endif
+#if defined (E2BIG)
+ ENTRY(E2BIG, "E2BIG", "Arg list too long"),
+#endif
+#if defined (ENOEXEC)
+ ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
+#endif
+#if defined (EBADF)
+ ENTRY(EBADF, "EBADF", "Bad file number"),
+#endif
+#if defined (ECHILD)
+ ENTRY(ECHILD, "ECHILD", "No child processes"),
+#endif
+#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
+ ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
+#endif
+#if defined (EAGAIN)
+ ENTRY(EAGAIN, "EAGAIN", "No more processes"),
+#endif
+#if defined (ENOMEM)
+ ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
+#endif
+#if defined (EACCES)
+ ENTRY(EACCES, "EACCES", "Permission denied"),
+#endif
+#if defined (EFAULT)
+ ENTRY(EFAULT, "EFAULT", "Bad address"),
+#endif
+#if defined (ENOTBLK)
+ ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
+#endif
+#if defined (EBUSY)
+ ENTRY(EBUSY, "EBUSY", "Device busy"),
+#endif
+#if defined (EEXIST)
+ ENTRY(EEXIST, "EEXIST", "File exists"),
+#endif
+#if defined (EXDEV)
+ ENTRY(EXDEV, "EXDEV", "Cross-device link"),
+#endif
+#if defined (ENODEV)
+ ENTRY(ENODEV, "ENODEV", "No such device"),
+#endif
+#if defined (ENOTDIR)
+ ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
+#endif
+#if defined (EISDIR)
+ ENTRY(EISDIR, "EISDIR", "Is a directory"),
+#endif
+#if defined (EINVAL)
+ ENTRY(EINVAL, "EINVAL", "Invalid argument"),
+#endif
+#if defined (ENFILE)
+ ENTRY(ENFILE, "ENFILE", "File table overflow"),
+#endif
+#if defined (EMFILE)
+ ENTRY(EMFILE, "EMFILE", "Too many open files"),
+#endif
+#if defined (ENOTTY)
+ ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
+#endif
+#if defined (ETXTBSY)
+ ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
+#endif
+#if defined (EFBIG)
+ ENTRY(EFBIG, "EFBIG", "File too large"),
+#endif
+#if defined (ENOSPC)
+ ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
+#endif
+#if defined (ESPIPE)
+ ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
+#endif
+#if defined (EROFS)
+ ENTRY(EROFS, "EROFS", "Read-only file system"),
+#endif
+#if defined (EMLINK)
+ ENTRY(EMLINK, "EMLINK", "Too many links"),
+#endif
+#if defined (EPIPE)
+ ENTRY(EPIPE, "EPIPE", "Broken pipe"),
+#endif
+#if defined (EDOM)
+ ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
+#endif
+#if defined (ERANGE)
+ ENTRY(ERANGE, "ERANGE", "Math result not representable"),
+#endif
+#if defined (ENOMSG)
+ ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
+#endif
+#if defined (EIDRM)
+ ENTRY(EIDRM, "EIDRM", "Identifier removed"),
+#endif
+#if defined (ECHRNG)
+ ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
+#endif
+#if defined (EL2NSYNC)
+ ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
+#endif
+#if defined (EL3HLT)
+ ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
+#endif
+#if defined (EL3RST)
+ ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
+#endif
+#if defined (ELNRNG)
+ ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
+#endif
+#if defined (EUNATCH)
+ ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
+#endif
+#if defined (ENOCSI)
+ ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
+#endif
+#if defined (EL2HLT)
+ ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
+#endif
+#if defined (EDEADLK)
+ ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
+#endif
+#if defined (ENOLCK)
+ ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
+#endif
+#if defined (EBADE)
+ ENTRY(EBADE, "EBADE", "Invalid exchange"),
+#endif
+#if defined (EBADR)
+ ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
+#endif
+#if defined (EXFULL)
+ ENTRY(EXFULL, "EXFULL", "Exchange full"),
+#endif
+#if defined (ENOANO)
+ ENTRY(ENOANO, "ENOANO", "No anode"),
+#endif
+#if defined (EBADRQC)
+ ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
+#endif
+#if defined (EBADSLT)
+ ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
+#endif
+#if defined (EDEADLOCK)
+ ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
+#endif
+#if defined (EBFONT)
+ ENTRY(EBFONT, "EBFONT", "Bad font file format"),
+#endif
+#if defined (ENOSTR)
+ ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
+#endif
+#if defined (ENODATA)
+ ENTRY(ENODATA, "ENODATA", "No data available"),
+#endif
+#if defined (ETIME)
+ ENTRY(ETIME, "ETIME", "Timer expired"),
+#endif
+#if defined (ENOSR)
+ ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
+#endif
+#if defined (ENONET)
+ ENTRY(ENONET, "ENONET", "Machine is not on the network"),
+#endif
+#if defined (ENOPKG)
+ ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
+#endif
+#if defined (EREMOTE)
+ ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
+#endif
+#if defined (ENOLINK)
+ ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
+#endif
+#if defined (EADV)
+ ENTRY(EADV, "EADV", "Advertise error"),
+#endif
+#if defined (ESRMNT)
+ ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
+#endif
+#if defined (ECOMM)
+ ENTRY(ECOMM, "ECOMM", "Communication error on send"),
+#endif
+#if defined (EPROTO)
+ ENTRY(EPROTO, "EPROTO", "Protocol error"),
+#endif
+#if defined (EMULTIHOP)
+ ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
+#endif
+#if defined (EDOTDOT)
+ ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
+#endif
+#if defined (EBADMSG)
+ ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
+#endif
+#if defined (ENAMETOOLONG)
+ ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
+#endif
+#if defined (EOVERFLOW)
+ ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
+#endif
+#if defined (ENOTUNIQ)
+ ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
+#endif
+#if defined (EBADFD)
+ ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
+#endif
+#if defined (EREMCHG)
+ ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
+#endif
+#if defined (ELIBACC)
+ ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"),
+#endif
+#if defined (ELIBBAD)
+ ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
+#endif
+#if defined (ELIBSCN)
+ ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
+#endif
+#if defined (ELIBMAX)
+ ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
+#endif
+#if defined (ELIBEXEC)
+ ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
+#endif
+#if defined (EILSEQ)
+ ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
+#endif
+#if defined (ENOSYS)
+ ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
+#endif
+#if defined (ELOOP)
+ ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
+#endif
+#if defined (ERESTART)
+ ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
+#endif
+#if defined (ESTRPIPE)
+ ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
+#endif
+#if defined (ENOTEMPTY)
+ ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
+#endif
+#if defined (EUSERS)
+ ENTRY(EUSERS, "EUSERS", "Too many users"),
+#endif
+#if defined (ENOTSOCK)
+ ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
+#endif
+#if defined (EDESTADDRREQ)
+ ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
+#endif
+#if defined (EMSGSIZE)
+ ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
+#endif
+#if defined (EPROTOTYPE)
+ ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
+#endif
+#if defined (ENOPROTOOPT)
+ ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
+#endif
+#if defined (EPROTONOSUPPORT)
+ ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
+#endif
+#if defined (ESOCKTNOSUPPORT)
+ ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
+#endif
+#if defined (EOPNOTSUPP)
+ ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
+#endif
+#if defined (EPFNOSUPPORT)
+ ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
+#endif
+#if defined (EAFNOSUPPORT)
+ ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
+#endif
+#if defined (EADDRINUSE)
+ ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
+#endif
+#if defined (EADDRNOTAVAIL)
+ ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
+#endif
+#if defined (ENETDOWN)
+ ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
+#endif
+#if defined (ENETUNREACH)
+ ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
+#endif
+#if defined (ENETRESET)
+ ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
+#endif
+#if defined (ECONNABORTED)
+ ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
+#endif
+#if defined (ECONNRESET)
+ ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
+#endif
+#if defined (ENOBUFS)
+ ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
+#endif
+#if defined (EISCONN)
+ ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
+#endif
+#if defined (ENOTCONN)
+ ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
+#endif
+#if defined (ESHUTDOWN)
+ ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
+#endif
+#if defined (ETOOMANYREFS)
+ ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
+#endif
+#if defined (ETIMEDOUT)
+ ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
+#endif
+#if defined (ECONNREFUSED)
+ ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
+#endif
+#if defined (EHOSTDOWN)
+ ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
+#endif
+#if defined (EHOSTUNREACH)
+ ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
+#endif
+#if defined (EALREADY)
+ ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
+#endif
+#if defined (EINPROGRESS)
+ ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
+#endif
+#if defined (ESTALE)
+ ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
+#endif
+#if defined (EUCLEAN)
+ ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
+#endif
+#if defined (ENOTNAM)
+ ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
+#endif
+#if defined (ENAVAIL)
+ ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
+#endif
+#if defined (EISNAM)
+ ENTRY(EISNAM, "EISNAM", "Is a named type file"),
+#endif
+#if defined (EREMOTEIO)
+ ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
+#endif
+ ENTRY(0, NULL, NULL)
+};
+
+#ifdef EVMSERR
+/* This is not in the table, because the numeric value of EVMSERR (32767)
+ lies outside the range of sys_errlist[]. */
+static struct { int value; const char *name, *msg; }
+ evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" };
+#endif
+
+/* Translation table allocated and initialized at runtime. Indexed by the
+ errno value to find the equivalent symbolic value. */
+
+static const char **error_names;
+static int num_error_names = 0;
+
+/* Translation table allocated and initialized at runtime, if it does not
+ already exist in the host environment. Indexed by the errno value to find
+ the descriptive string.
+
+ We don't export it for use in other modules because even though it has the
+ same name, it differs from other implementations in that it is dynamically
+ initialized rather than statically initialized. */
+
+#ifndef HAVE_SYS_ERRLIST
+
+static int sys_nerr;
+static const char **sys_errlist;
+
+#else
+
+extern int sys_nerr;
+extern char *sys_errlist[];
+
+#endif
+
+
+/*
+
+NAME
+
+ init_error_tables -- initialize the name and message tables
+
+SYNOPSIS
+
+ static void init_error_tables ();
+
+DESCRIPTION
+
+ Using the error_table, which is initialized at compile time, generate
+ the error_names and the sys_errlist (if needed) tables, which are
+ indexed at runtime by a specific errno value.
+
+BUGS
+
+ The initialization of the tables may fail under low memory conditions,
+ in which case we don't do anything particularly useful, but we don't
+ bomb either. Who knows, it might succeed at a later point if we free
+ some memory in the meantime. In any case, the other routines know
+ how to deal with lack of a table after trying to initialize it. This
+ may or may not be considered to be a bug, that we don't specifically
+ warn about this particular failure mode.
+
+*/
+
+static void
+init_error_tables ()
+{
+ const struct error_info *eip;
+ int nbytes;
+
+ /* If we haven't already scanned the error_table once to find the maximum
+ errno value, then go find it now. */
+
+ if (num_error_names == 0)
+ {
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ if (eip -> value >= num_error_names)
+ {
+ num_error_names = eip -> value + 1;
+ }
+ }
+ }
+
+ /* Now attempt to allocate the error_names table, zero it out, and then
+ initialize it from the statically initialized error_table. */
+
+ if (error_names == NULL)
+ {
+ nbytes = num_error_names * sizeof (char *);
+ if ((error_names = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (error_names, 0, nbytes);
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ error_names[eip -> value] = eip -> name;
+ }
+ }
+ }
+
+#ifndef HAVE_SYS_ERRLIST
+
+ /* Now attempt to allocate the sys_errlist table, zero it out, and then
+ initialize it from the statically initialized error_table. */
+
+ if (sys_errlist == NULL)
+ {
+ nbytes = num_error_names * sizeof (char *);
+ if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (sys_errlist, 0, nbytes);
+ sys_nerr = num_error_names;
+ for (eip = error_table; eip -> name != NULL; eip++)
+ {
+ sys_errlist[eip -> value] = eip -> msg;
+ }
+ }
+ }
+
+#endif
+
+}
+
+/*
+
+NAME
+
+ errno_max -- return the max errno value
+
+SYNOPSIS
+
+ int errno_max ();
+
+DESCRIPTION
+
+ Returns the maximum errno value for which a corresponding symbolic
+ name or message is available. Note that in the case where
+ we use the sys_errlist supplied by the system, it is possible for
+ there to be more symbolic names than messages, or vice versa.
+ In fact, the manual page for perror(3C) explicitly warns that one
+ should check the size of the table (sys_nerr) before indexing it,
+ since new error codes may be added to the system before they are
+ added to the table. Thus sys_nerr might be smaller than value
+ implied by the largest errno value defined in <errno.h>.
+
+ We return the maximum value that can be used to obtain a meaningful
+ symbolic name or message.
+
+*/
+
+int
+errno_max ()
+{
+ int maxsize;
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+ maxsize = MAX (sys_nerr, num_error_names);
+ return (maxsize - 1);
+}
+
+#ifndef HAVE_STRERROR
+
+/*
+
+NAME
+
+ strerror -- map an error number to an error message string
+
+SYNOPSIS
+
+ char *strerror (int errnoval)
+
+DESCRIPTION
+
+ Maps an errno number to an error message string, the contents of
+ which are implementation defined. On systems which have the external
+ variables sys_nerr and sys_errlist, these strings will be the same
+ as the ones used by perror().
+
+ If the supplied error number is within the valid range of indices
+ for the sys_errlist, but no message is available for the particular
+ error number, then returns the string "Error NUM", where NUM is the
+ error number.
+
+ If the supplied error number is not a valid index into sys_errlist,
+ returns NULL.
+
+ The returned string is only guaranteed to be valid only until the
+ next call to strerror.
+
+*/
+
+char *
+strerror (errnoval)
+ int errnoval;
+{
+ char *msg;
+ static char buf[32];
+
+#ifndef HAVE_SYS_ERRLIST
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+
+#endif
+
+ if ((errnoval < 0) || (errnoval >= sys_nerr))
+ {
+#ifdef EVMSERR
+ if (errnoval == evmserr.value)
+ msg = evmserr.msg;
+ else
+#endif
+ /* Out of range, just return NULL */
+ msg = NULL;
+ }
+ else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
+ {
+ /* In range, but no sys_errlist or no entry at this index. */
+ sprintf (buf, "Error %d", errnoval);
+ msg = buf;
+ }
+ else
+ {
+ /* In range, and a valid message. Just return the message. */
+ msg = (char *) sys_errlist[errnoval];
+ }
+
+ return (msg);
+}
+
+#endif /* ! HAVE_STRERROR */
+
+
+/*
+
+NAME
+
+ strerrno -- map an error number to a symbolic name string
+
+SYNOPSIS
+
+ const char *strerrno (int errnoval)
+
+DESCRIPTION
+
+ Given an error number returned from a system call (typically
+ returned in errno), returns a pointer to a string containing the
+ symbolic name of that error number, as found in <errno.h>.
+
+ If the supplied error number is within the valid range of indices
+ for symbolic names, but no name is available for the particular
+ error number, then returns the string "Error NUM", where NUM is
+ the error number.
+
+ If the supplied error number is not within the range of valid
+ indices, then returns NULL.
+
+BUGS
+
+ The contents of the location pointed to are only guaranteed to be
+ valid until the next call to strerrno.
+
+*/
+
+const char *
+strerrno (errnoval)
+ int errnoval;
+{
+ const char *name;
+ static char buf[32];
+
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+
+ if ((errnoval < 0) || (errnoval >= num_error_names))
+ {
+#ifdef EVMSERR
+ if (errnoval == evmserr.value)
+ name = evmserr.name;
+ else
+#endif
+ /* Out of range, just return NULL */
+ name = NULL;
+ }
+ else if ((error_names == NULL) || (error_names[errnoval] == NULL))
+ {
+ /* In range, but no error_names or no entry at this index. */
+ sprintf (buf, "Error %d", errnoval);
+ name = (const char *) buf;
+ }
+ else
+ {
+ /* In range, and a valid name. Just return the name. */
+ name = error_names[errnoval];
+ }
+
+ return (name);
+}
+
+/*
+
+NAME
+
+ strtoerrno -- map a symbolic errno name to a numeric value
+
+SYNOPSIS
+
+ int strtoerrno (char *name)
+
+DESCRIPTION
+
+ Given the symbolic name of a error number, map it to an errno value.
+ If no translation is found, returns 0.
+
+*/
+
+int
+strtoerrno (name)
+ const char *name;
+{
+ int errnoval = 0;
+
+ if (name != NULL)
+ {
+ if (error_names == NULL)
+ {
+ init_error_tables ();
+ }
+ for (errnoval = 0; errnoval < num_error_names; errnoval++)
+ {
+ if ((error_names[errnoval] != NULL) &&
+ (strcmp (name, error_names[errnoval]) == 0))
+ {
+ break;
+ }
+ }
+ if (errnoval == num_error_names)
+ {
+#ifdef EVMSERR
+ if (strcmp (name, evmserr.name) == 0)
+ errnoval = evmserr.value;
+ else
+#endif
+ errnoval = 0;
+ }
+ }
+ return (errnoval);
+}
+
+
+/* A simple little main that does nothing but print all the errno translations
+ if MAIN is defined and this file is compiled and linked. */
+
+#ifdef MAIN
+
+#include <stdio.h>
+
+int
+main ()
+{
+ int errn;
+ int errnmax;
+ const char *name;
+ char *msg;
+ char *strerror ();
+
+ errnmax = errno_max ();
+ printf ("%d entries in names table.\n", num_error_names);
+ printf ("%d entries in messages table.\n", sys_nerr);
+ printf ("%d is max useful index.\n", errnmax);
+
+ /* Keep printing values until we get to the end of *both* tables, not
+ *either* table. Note that knowing the maximum useful index does *not*
+ relieve us of the responsibility of testing the return pointer for
+ NULL. */
+
+ for (errn = 0; errn <= errnmax; errn++)
+ {
+ name = strerrno (errn);
+ name = (name == NULL) ? "<NULL>" : name;
+ msg = strerror (errn);
+ msg = (msg == NULL) ? "<NULL>" : msg;
+ printf ("%-4d%-18s%s\n", errn, name, msg);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/libiberty/strncasecmp.c b/libiberty/strncasecmp.c
new file mode 100644
index 00000000000..4485cac7a6a
--- /dev/null
+++ b/libiberty/strncasecmp.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific written prior permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c 5.5 (Berkeley) 11/24/87";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ansidecl.h>
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static unsigned char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ register unsigned char u1, u2;
+
+ for (; n != 0; --n) {
+ u1 = (unsigned char) *s1++;
+ u2 = (unsigned char) *s2++;
+ if (charmap[u1] != charmap[u2]) {
+ return charmap[u1] - charmap[u2];
+ }
+ if (u1 == '\0') {
+ return 0;
+ }
+ }
+ return 0;
+}
diff --git a/libiberty/strrchr.c b/libiberty/strrchr.c
new file mode 100644
index 00000000000..8c05bcbead8
--- /dev/null
+++ b/libiberty/strrchr.c
@@ -0,0 +1,34 @@
+/* Portable version of strrchr().
+ This function is in the public domain. */
+
+/*
+NAME
+ strrchr -- return pointer to last occurance of a character
+
+SYNOPSIS
+ char *strrchr (const char *s, int c)
+
+DESCRIPTION
+ Returns a pointer to the last occurance of character C in
+ string S, or a NULL pointer if no occurance is found.
+
+BUGS
+ Behavior when character is the null character is implementation
+ dependent.
+*/
+
+#include <ansidecl.h>
+
+char *
+strrchr (s, c)
+ register const char *s;
+ int c;
+{
+ char *rtnval = 0;
+
+ do {
+ if (*s == c)
+ rtnval = (char*) s;
+ } while (*s++);
+ return (rtnval);
+}
diff --git a/libiberty/strsignal.c b/libiberty/strsignal.c
new file mode 100644
index 00000000000..c7bb10c441c
--- /dev/null
+++ b/libiberty/strsignal.c
@@ -0,0 +1,644 @@
+/* Extended support for using signal values.
+ Written by Fred Fish. fnf@cygnus.com
+ This file is in the public domain. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include "config.h"
+
+/* We need to declare sys_siglist, because even if the system provides
+ it we can't assume that it is declared in <signal.h> (for example,
+ SunOS provides sys_siglist, but it does not declare it in any
+ header file). fHowever, we can't declare sys_siglist portably,
+ because on some systems it is declared with const and on some
+ systems it is declared without const. If we were using autoconf,
+ we could work out the right declaration. Until, then we just
+ ignore any declaration in the system header files, and always
+ declare it ourselves. With luck, this will always work. */
+#define sys_siglist no_such_symbol
+
+#include <stdio.h>
+#include <signal.h>
+
+/* Routines imported from standard C runtime libraries. */
+
+#ifdef __STDC__
+#include <stddef.h>
+extern void *malloc (size_t size); /* 4.10.3.3 */
+extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */
+#else /* !__STDC__ */
+extern char *malloc (); /* Standard memory allocater */
+extern char *memset ();
+#endif /* __STDC__ */
+
+/* Undefine the macro we used to hide the definition of sys_siglist
+ found in the system header files. */
+#undef sys_siglist
+
+#ifndef NULL
+# ifdef __STDC__
+# define NULL (void *) 0
+# else
+# define NULL 0
+# endif
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+static void init_signal_tables PARAMS ((void));
+
+/* Translation table for signal values.
+
+ Note that this table is generally only accessed when it is used at runtime
+ to initialize signal name and message tables that are indexed by signal
+ value.
+
+ Not all of these signals will exist on all systems. This table is the only
+ thing that should have to be updated as new signal numbers are introduced.
+ It's sort of ugly, but at least its portable. */
+
+struct signal_info
+{
+ int value; /* The numeric value from <signal.h> */
+ const char *name; /* The equivalent symbolic value */
+#ifndef HAVE_SYS_SIGLIST
+ const char *msg; /* Short message about this value */
+#endif
+};
+
+#ifndef HAVE_SYS_SIGLIST
+# define ENTRY(value, name, msg) {value, name, msg}
+#else
+# define ENTRY(value, name, msg) {value, name}
+#endif
+
+static const struct signal_info signal_table[] =
+{
+#if defined (SIGHUP)
+ ENTRY(SIGHUP, "SIGHUP", "Hangup"),
+#endif
+#if defined (SIGINT)
+ ENTRY(SIGINT, "SIGINT", "Interrupt"),
+#endif
+#if defined (SIGQUIT)
+ ENTRY(SIGQUIT, "SIGQUIT", "Quit"),
+#endif
+#if defined (SIGILL)
+ ENTRY(SIGILL, "SIGILL", "Illegal instruction"),
+#endif
+#if defined (SIGTRAP)
+ ENTRY(SIGTRAP, "SIGTRAP", "Trace/breakpoint trap"),
+#endif
+/* Put SIGIOT before SIGABRT, so that if SIGIOT==SIGABRT then SIGABRT
+ overrides SIGIOT. SIGABRT is in ANSI and POSIX.1, and SIGIOT isn't. */
+#if defined (SIGIOT)
+ ENTRY(SIGIOT, "SIGIOT", "IOT trap"),
+#endif
+#if defined (SIGABRT)
+ ENTRY(SIGABRT, "SIGABRT", "Aborted"),
+#endif
+#if defined (SIGEMT)
+ ENTRY(SIGEMT, "SIGEMT", "Emulation trap"),
+#endif
+#if defined (SIGFPE)
+ ENTRY(SIGFPE, "SIGFPE", "Arithmetic exception"),
+#endif
+#if defined (SIGKILL)
+ ENTRY(SIGKILL, "SIGKILL", "Killed"),
+#endif
+#if defined (SIGBUS)
+ ENTRY(SIGBUS, "SIGBUS", "Bus error"),
+#endif
+#if defined (SIGSEGV)
+ ENTRY(SIGSEGV, "SIGSEGV", "Segmentation fault"),
+#endif
+#if defined (SIGSYS)
+ ENTRY(SIGSYS, "SIGSYS", "Bad system call"),
+#endif
+#if defined (SIGPIPE)
+ ENTRY(SIGPIPE, "SIGPIPE", "Broken pipe"),
+#endif
+#if defined (SIGALRM)
+ ENTRY(SIGALRM, "SIGALRM", "Alarm clock"),
+#endif
+#if defined (SIGTERM)
+ ENTRY(SIGTERM, "SIGTERM", "Terminated"),
+#endif
+#if defined (SIGUSR1)
+ ENTRY(SIGUSR1, "SIGUSR1", "User defined signal 1"),
+#endif
+#if defined (SIGUSR2)
+ ENTRY(SIGUSR2, "SIGUSR2", "User defined signal 2"),
+#endif
+/* Put SIGCLD before SIGCHLD, so that if SIGCLD==SIGCHLD then SIGCHLD
+ overrides SIGCLD. SIGCHLD is in POXIX.1 */
+#if defined (SIGCLD)
+ ENTRY(SIGCLD, "SIGCLD", "Child status changed"),
+#endif
+#if defined (SIGCHLD)
+ ENTRY(SIGCHLD, "SIGCHLD", "Child status changed"),
+#endif
+#if defined (SIGPWR)
+ ENTRY(SIGPWR, "SIGPWR", "Power fail/restart"),
+#endif
+#if defined (SIGWINCH)
+ ENTRY(SIGWINCH, "SIGWINCH", "Window size changed"),
+#endif
+#if defined (SIGURG)
+ ENTRY(SIGURG, "SIGURG", "Urgent I/O condition"),
+#endif
+#if defined (SIGIO)
+ /* "I/O pending" has also been suggested, but is misleading since the
+ signal only happens when the process has asked for it, not everytime
+ I/O is pending. */
+ ENTRY(SIGIO, "SIGIO", "I/O possible"),
+#endif
+#if defined (SIGPOLL)
+ ENTRY(SIGPOLL, "SIGPOLL", "Pollable event occurred"),
+#endif
+#if defined (SIGSTOP)
+ ENTRY(SIGSTOP, "SIGSTOP", "Stopped (signal)"),
+#endif
+#if defined (SIGTSTP)
+ ENTRY(SIGTSTP, "SIGTSTP", "Stopped (user)"),
+#endif
+#if defined (SIGCONT)
+ ENTRY(SIGCONT, "SIGCONT", "Continued"),
+#endif
+#if defined (SIGTTIN)
+ ENTRY(SIGTTIN, "SIGTTIN", "Stopped (tty input)"),
+#endif
+#if defined (SIGTTOU)
+ ENTRY(SIGTTOU, "SIGTTOU", "Stopped (tty output)"),
+#endif
+#if defined (SIGVTALRM)
+ ENTRY(SIGVTALRM, "SIGVTALRM", "Virtual timer expired"),
+#endif
+#if defined (SIGPROF)
+ ENTRY(SIGPROF, "SIGPROF", "Profiling timer expired"),
+#endif
+#if defined (SIGXCPU)
+ ENTRY(SIGXCPU, "SIGXCPU", "CPU time limit exceeded"),
+#endif
+#if defined (SIGXFSZ)
+ ENTRY(SIGXFSZ, "SIGXFSZ", "File size limit exceeded"),
+#endif
+#if defined (SIGWIND)
+ ENTRY(SIGWIND, "SIGWIND", "SIGWIND"),
+#endif
+#if defined (SIGPHONE)
+ ENTRY(SIGPHONE, "SIGPHONE", "SIGPHONE"),
+#endif
+#if defined (SIGLOST)
+ ENTRY(SIGLOST, "SIGLOST", "Resource lost"),
+#endif
+#if defined (SIGWAITING)
+ ENTRY(SIGWAITING, "SIGWAITING", "Process's LWPs are blocked"),
+#endif
+#if defined (SIGLWP)
+ ENTRY(SIGLWP, "SIGLWP", "Signal LWP"),
+#endif
+#if defined (SIGDANGER)
+ ENTRY(SIGDANGER, "SIGDANGER", "Swap space dangerously low"),
+#endif
+#if defined (SIGGRANT)
+ ENTRY(SIGGRANT, "SIGGRANT", "Monitor mode granted"),
+#endif
+#if defined (SIGRETRACT)
+ ENTRY(SIGRETRACT, "SIGRETRACT", "Need to relinguish monitor mode"),
+#endif
+#if defined (SIGMSG)
+ ENTRY(SIGMSG, "SIGMSG", "Monitor mode data available"),
+#endif
+#if defined (SIGSOUND)
+ ENTRY(SIGSOUND, "SIGSOUND", "Sound completed"),
+#endif
+#if defined (SIGSAK)
+ ENTRY(SIGSAK, "SIGSAK", "Secure attention"),
+#endif
+ ENTRY(0, NULL, NULL)
+};
+
+/* Translation table allocated and initialized at runtime. Indexed by the
+ signal value to find the equivalent symbolic value. */
+
+static const char **signal_names;
+static int num_signal_names = 0;
+
+/* Translation table allocated and initialized at runtime, if it does not
+ already exist in the host environment. Indexed by the signal value to find
+ the descriptive string.
+
+ We don't export it for use in other modules because even though it has the
+ same name, it differs from other implementations in that it is dynamically
+ initialized rather than statically initialized. */
+
+#ifndef HAVE_SYS_SIGLIST
+
+static int sys_nsig;
+static const char **sys_siglist;
+
+#else
+
+#ifdef NSIG
+static int sys_nsig = NSIG;
+#else
+#ifdef _NSIG
+static int sys_nsig = _NSIG;
+#endif
+#endif
+extern const char * const sys_siglist[];
+
+#endif
+
+
+/*
+
+NAME
+
+ init_signal_tables -- initialize the name and message tables
+
+SYNOPSIS
+
+ static void init_signal_tables ();
+
+DESCRIPTION
+
+ Using the signal_table, which is initialized at compile time, generate
+ the signal_names and the sys_siglist (if needed) tables, which are
+ indexed at runtime by a specific signal value.
+
+BUGS
+
+ The initialization of the tables may fail under low memory conditions,
+ in which case we don't do anything particularly useful, but we don't
+ bomb either. Who knows, it might succeed at a later point if we free
+ some memory in the meantime. In any case, the other routines know
+ how to deal with lack of a table after trying to initialize it. This
+ may or may not be considered to be a bug, that we don't specifically
+ warn about this particular failure mode.
+
+*/
+
+static void
+init_signal_tables ()
+{
+ const struct signal_info *eip;
+ int nbytes;
+
+ /* If we haven't already scanned the signal_table once to find the maximum
+ signal value, then go find it now. */
+
+ if (num_signal_names == 0)
+ {
+ for (eip = signal_table; eip -> name != NULL; eip++)
+ {
+ if (eip -> value >= num_signal_names)
+ {
+ num_signal_names = eip -> value + 1;
+ }
+ }
+ }
+
+ /* Now attempt to allocate the signal_names table, zero it out, and then
+ initialize it from the statically initialized signal_table. */
+
+ if (signal_names == NULL)
+ {
+ nbytes = num_signal_names * sizeof (char *);
+ if ((signal_names = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (signal_names, 0, nbytes);
+ for (eip = signal_table; eip -> name != NULL; eip++)
+ {
+ signal_names[eip -> value] = eip -> name;
+ }
+ }
+ }
+
+#ifndef HAVE_SYS_SIGLIST
+
+ /* Now attempt to allocate the sys_siglist table, zero it out, and then
+ initialize it from the statically initialized signal_table. */
+
+ if (sys_siglist == NULL)
+ {
+ nbytes = num_signal_names * sizeof (char *);
+ if ((sys_siglist = (const char **) malloc (nbytes)) != NULL)
+ {
+ memset (sys_siglist, 0, nbytes);
+ sys_nsig = num_signal_names;
+ for (eip = signal_table; eip -> name != NULL; eip++)
+ {
+ sys_siglist[eip -> value] = eip -> msg;
+ }
+ }
+ }
+
+#endif
+
+}
+
+
+/*
+
+NAME
+
+ signo_max -- return the max signo value
+
+SYNOPSIS
+
+ int signo_max ();
+
+DESCRIPTION
+
+ Returns the maximum signo value for which a corresponding symbolic
+ name or message is available. Note that in the case where
+ we use the sys_siglist supplied by the system, it is possible for
+ there to be more symbolic names than messages, or vice versa.
+ In fact, the manual page for psignal(3b) explicitly warns that one
+ should check the size of the table (NSIG) before indexing it,
+ since new signal codes may be added to the system before they are
+ added to the table. Thus NSIG might be smaller than value
+ implied by the largest signo value defined in <signal.h>.
+
+ We return the maximum value that can be used to obtain a meaningful
+ symbolic name or message.
+
+*/
+
+int
+signo_max ()
+{
+ int maxsize;
+
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+ maxsize = MAX (sys_nsig, num_signal_names);
+ return (maxsize - 1);
+}
+
+
+/*
+
+NAME
+
+ strsignal -- map a signal number to a signal message string
+
+SYNOPSIS
+
+ const char *strsignal (int signo)
+
+DESCRIPTION
+
+ Maps an signal number to an signal message string, the contents of
+ which are implementation defined. On systems which have the external
+ variable sys_siglist, these strings will be the same as the ones used
+ by psignal().
+
+ If the supplied signal number is within the valid range of indices
+ for the sys_siglist, but no message is available for the particular
+ signal number, then returns the string "Signal NUM", where NUM is the
+ signal number.
+
+ If the supplied signal number is not a valid index into sys_siglist,
+ returns NULL.
+
+ The returned string is only guaranteed to be valid only until the
+ next call to strsignal.
+
+*/
+
+#ifndef HAVE_STRSIGNAL
+
+const char *
+strsignal (signo)
+ int signo;
+{
+ const char *msg;
+ static char buf[32];
+
+#ifndef HAVE_SYS_SIGLIST
+
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+
+#endif
+
+ if ((signo < 0) || (signo >= sys_nsig))
+ {
+ /* Out of range, just return NULL */
+ msg = NULL;
+ }
+ else if ((sys_siglist == NULL) || (sys_siglist[signo] == NULL))
+ {
+ /* In range, but no sys_siglist or no entry at this index. */
+ sprintf (buf, "Signal %d", signo);
+ msg = (const char *) buf;
+ }
+ else
+ {
+ /* In range, and a valid message. Just return the message. */
+ msg = (const char *) sys_siglist[signo];
+ }
+
+ return (msg);
+}
+
+#endif /* ! HAVE_STRSIGNAL */
+
+/*
+
+NAME
+
+ strsigno -- map an signal number to a symbolic name string
+
+SYNOPSIS
+
+ const char *strsigno (int signo)
+
+DESCRIPTION
+
+ Given an signal number, returns a pointer to a string containing
+ the symbolic name of that signal number, as found in <signal.h>.
+
+ If the supplied signal number is within the valid range of indices
+ for symbolic names, but no name is available for the particular
+ signal number, then returns the string "Signal NUM", where NUM is
+ the signal number.
+
+ If the supplied signal number is not within the range of valid
+ indices, then returns NULL.
+
+BUGS
+
+ The contents of the location pointed to are only guaranteed to be
+ valid until the next call to strsigno.
+
+*/
+
+const char *
+strsigno (signo)
+ int signo;
+{
+ const char *name;
+ static char buf[32];
+
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+
+ if ((signo < 0) || (signo >= num_signal_names))
+ {
+ /* Out of range, just return NULL */
+ name = NULL;
+ }
+ else if ((signal_names == NULL) || (signal_names[signo] == NULL))
+ {
+ /* In range, but no signal_names or no entry at this index. */
+ sprintf (buf, "Signal %d", signo);
+ name = (const char *) buf;
+ }
+ else
+ {
+ /* In range, and a valid name. Just return the name. */
+ name = signal_names[signo];
+ }
+
+ return (name);
+}
+
+
+/*
+
+NAME
+
+ strtosigno -- map a symbolic signal name to a numeric value
+
+SYNOPSIS
+
+ int strtosigno (char *name)
+
+DESCRIPTION
+
+ Given the symbolic name of a signal, map it to a signal number.
+ If no translation is found, returns 0.
+
+*/
+
+int
+strtosigno (name)
+ const char *name;
+{
+ int signo = 0;
+
+ if (name != NULL)
+ {
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+ for (signo = 0; signo < num_signal_names; signo++)
+ {
+ if ((signal_names[signo] != NULL) &&
+ (strcmp (name, signal_names[signo]) == 0))
+ {
+ break;
+ }
+ }
+ if (signo == num_signal_names)
+ {
+ signo = 0;
+ }
+ }
+ return (signo);
+}
+
+
+/*
+
+NAME
+
+ psignal -- print message about signal to stderr
+
+SYNOPSIS
+
+ void psignal (unsigned signo, char *message);
+
+DESCRIPTION
+
+ Print to the standard error the message, followed by a colon,
+ followed by the description of the signal specified by signo,
+ followed by a newline.
+*/
+
+#ifndef HAVE_PSIGNAL
+
+void
+psignal (signo, message)
+ unsigned signo;
+ char *message;
+{
+ if (signal_names == NULL)
+ {
+ init_signal_tables ();
+ }
+ if ((signo <= 0) || (signo >= sys_nsig))
+ {
+ fprintf (stderr, "%s: unknown signal\n", message);
+ }
+ else
+ {
+ fprintf (stderr, "%s: %s\n", message, sys_siglist[signo]);
+ }
+}
+
+#endif /* ! HAVE_PSIGNAL */
+
+
+/* A simple little main that does nothing but print all the signal translations
+ if MAIN is defined and this file is compiled and linked. */
+
+#ifdef MAIN
+
+#include <stdio.h>
+
+int
+main ()
+{
+ int signo;
+ int maxsigno;
+ const char *name;
+ const char *msg;
+
+ maxsigno = signo_max ();
+ printf ("%d entries in names table.\n", num_signal_names);
+ printf ("%d entries in messages table.\n", sys_nsig);
+ printf ("%d is max useful index.\n", maxsigno);
+
+ /* Keep printing values until we get to the end of *both* tables, not
+ *either* table. Note that knowing the maximum useful index does *not*
+ relieve us of the responsibility of testing the return pointer for
+ NULL. */
+
+ for (signo = 0; signo <= maxsigno; signo++)
+ {
+ name = strsigno (signo);
+ name = (name == NULL) ? "<NULL>" : name;
+ msg = strsignal (signo);
+ msg = (msg == NULL) ? "<NULL>" : msg;
+ printf ("%-4d%-18s%s\n", signo, name, msg);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/libiberty/strstr.c b/libiberty/strstr.c
new file mode 100644
index 00000000000..fab36e3fb3d
--- /dev/null
+++ b/libiberty/strstr.c
@@ -0,0 +1,51 @@
+/* Simple implementation of strstr for systems without it.
+ This function is in the public domain. */
+
+/*
+
+NAME
+
+ strstr -- locate first occurance of a substring
+
+SYNOPSIS
+
+ #include <string.h>
+
+ char *strstr (char *s1, char *s2)
+
+DESCRIPTION
+
+ Locates the first occurance in the string pointed to by S1 of
+ the string pointed to by S2. Returns a pointer to the substring
+ found, or a NULL pointer if not found. If S2 points to a string
+ with zero length, the function returns S1.
+
+BUGS
+
+*/
+
+
+/* FIXME: The above description is ANSI compiliant. This routine has not
+ been validated to comply with it. -fnf */
+
+char *
+strstr (s1, s2)
+ char *s1, *s2;
+{
+ register char *p = s1;
+ extern char *strchr ();
+ extern int strncmp ();
+#if __GNUC__==2
+ extern __SIZE_TYPE__ strlen ();
+#endif
+ register int len = strlen (s2);
+
+ for (; (p = strchr (p, *s2)) != 0; p++)
+ {
+ if (strncmp (p, s2, len) == 0)
+ {
+ return (p);
+ }
+ }
+ return (0);
+}
diff --git a/libiberty/strtod.c b/libiberty/strtod.c
new file mode 100644
index 00000000000..c86c73de9b3
--- /dev/null
+++ b/libiberty/strtod.c
@@ -0,0 +1,122 @@
+/* Implementation of strtod for systems with atof.
+ Copyright (C) 1991, 1995 Free Software Foundation, Inc.
+
+This file is part of the libiberty library. This library 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, or (at your option)
+any later version.
+
+This library 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <ctype.h>
+
+extern double atof ();
+
+/* Disclaimer: this is currently just used by CHILL in GDB and therefore
+ has not been tested well. It may have been tested for nothing except
+ that it compiles. */
+
+double
+strtod (str, ptr)
+ char *str;
+ char **ptr;
+{
+ char *p;
+
+ if (ptr == (char **)0)
+ return atof (str);
+
+ p = str;
+
+ while (isspace (*p))
+ ++p;
+
+ if (*p == '+' || *p == '-')
+ ++p;
+
+ /* INF or INFINITY. */
+ if ((p[0] == 'i' || p[0] == 'I')
+ && (p[1] == 'n' || p[1] == 'N')
+ && (p[2] == 'f' || p[2] == 'F'))
+ {
+ if ((p[3] == 'i' || p[3] == 'I')
+ && (p[4] == 'n' || p[4] == 'N')
+ && (p[5] == 'i' || p[5] == 'I')
+ && (p[6] == 't' || p[6] == 'T')
+ && (p[7] == 'y' || p[7] == 'Y'))
+ {
+ *ptr = p + 7;
+ return atof (str);
+ }
+ else
+ {
+ *ptr = p + 3;
+ return atof (str);
+ }
+ }
+
+ /* NAN or NAN(foo). */
+ if ((p[0] == 'n' || p[0] == 'N')
+ && (p[1] == 'a' || p[1] == 'A')
+ && (p[2] == 'n' || p[2] == 'N'))
+ {
+ p += 3;
+ if (*p == '(')
+ {
+ ++p;
+ while (*p != '\0' && *p != ')')
+ ++p;
+ if (*p == ')')
+ ++p;
+ }
+ *ptr = p;
+ return atof (str);
+ }
+
+ /* digits, with 0 or 1 periods in it. */
+ if (isdigit (*p) || *p == '.')
+ {
+ int got_dot = 0;
+ while (isdigit (*p) || (!got_dot && *p == '.'))
+ {
+ if (*p == '.')
+ got_dot = 1;
+ ++p;
+ }
+
+ /* Exponent. */
+ if (*p == 'e' || *p == 'E')
+ {
+ int i;
+ i = 1;
+ if (p[i] == '+' || p[i] == '-')
+ ++i;
+ if (isdigit (p[i]))
+ {
+ while (isdigit (p[i]))
+ ++i;
+ *ptr = p + i;
+ return atof (str);
+ }
+ }
+ *ptr = p;
+ return atof (str);
+ }
+ /* Didn't find any digits. Doesn't look like a number. */
+ *ptr = str;
+ return 0.0;
+}
diff --git a/libiberty/strtol.c b/libiberty/strtol.c
new file mode 100644
index 00000000000..37d170660f2
--- /dev/null
+++ b/libiberty/strtol.c
@@ -0,0 +1,143 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#if 0
+#include <stdlib.h>
+#endif
+#include "ansidecl.h"
+
+/* FIXME: It'd be nice to configure around these, but the include files are too
+ painful. These macros should at least be more portable than hardwired hex
+ constants. */
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */
+#endif
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long
+strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *) (any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/libiberty/strtoul.c b/libiberty/strtoul.c
new file mode 100644
index 00000000000..ff6f2d6784d
--- /dev/null
+++ b/libiberty/strtoul.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#if 0
+#include <stdlib.h>
+#endif
+#include "ansidecl.h"
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
+#endif
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long
+strtoul(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+ cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *) (any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/libiberty/tmpnam.c b/libiberty/tmpnam.c
new file mode 100644
index 00000000000..c0614677425
--- /dev/null
+++ b/libiberty/tmpnam.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+#ifndef L_tmpnam
+#define L_tmpname 100
+#endif
+#ifndef P_tmpdir
+#define P_tmpdir "/usr/tmp"
+#endif
+
+static char tmpnam_buffer[L_tmpnam];
+static int tmpnam_counter;
+
+extern int getpid ();
+
+char *
+tmpnam (s)
+ char *s;
+{
+ int pid = getpid ();
+
+ if (s == NULL)
+ s = tmpnam_buffer;
+
+ /* Generate the filename and make sure that there isn't one called
+ it already. */
+
+ while (1)
+ {
+ FILE *f;
+ sprintf (s, "%s/%s%x.%x", P_tmpdir, "t", pid, tmpnam_counter);
+ f = fopen (s, "r");
+ if (f == NULL)
+ break;
+ tmpnam_counter++;
+ fclose (f);
+ }
+
+ return s;
+}
diff --git a/libiberty/vasprintf.c b/libiberty/vasprintf.c
new file mode 100644
index 00000000000..eeb80e661f7
--- /dev/null
+++ b/libiberty/vasprintf.c
@@ -0,0 +1,172 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <ansidecl.h>
+
+#ifdef TEST
+int global_total_width;
+#endif
+
+unsigned long strtoul ();
+char *malloc ();
+
+static int
+int_vasprintf (result, format, args)
+ char **result;
+ const char *format;
+ va_list *args;
+{
+ const char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap;
+
+ memcpy ((PTR) &ap, (PTR) args, sizeof (va_list));
+
+ while (*p != '\0')
+ {
+ if (*p++ == '%')
+ {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, &p, 10);
+ if (*p == '.')
+ {
+ ++p;
+ if (*p == '*')
+ {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ }
+ else
+ total_width += strtoul (p, &p, 10);
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s and floats. */
+ total_width += 30;
+ switch (*p)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ /* Since an ieee double can have an exponent of 307, we'll
+ make the buffer wide enough to cover the gross case. */
+ total_width += 307;
+ break;
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ }
+ }
+#ifdef TEST
+ global_total_width = total_width;
+#endif
+ *result = malloc (total_width);
+ if (*result != NULL)
+ return vsprintf (*result, format, *args);
+ else
+ return 0;
+}
+
+int
+vasprintf (result, format, args)
+ char **result;
+ const char *format;
+#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
+ _BSD_VA_LIST_ args;
+#else
+ va_list args;
+#endif
+{
+ return int_vasprintf (result, format, &args);
+}
+
+#ifdef TEST
+void
+checkit
+#ifdef __STDC__
+ (const char* format, ...)
+#else
+ (va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+ char *result;
+
+#ifdef __STDC__
+ va_start (args, format);
+#else
+ char *format;
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+ vasprintf (&result, format, args);
+ if (strlen (result) < global_total_width)
+ printf ("PASS: ");
+ else
+ printf ("FAIL: ");
+ printf ("%d %s\n", global_total_width, result);
+}
+
+int
+main ()
+{
+ checkit ("%d", 0x12345678);
+ checkit ("%200d", 5);
+ checkit ("%.300d", 6);
+ checkit ("%100.150d", 7);
+ checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
+777777777777777777333333333333366666666666622222222222777777777777733333");
+ checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
+}
+#endif /* TEST */
diff --git a/libiberty/vfork.c b/libiberty/vfork.c
new file mode 100644
index 00000000000..86c45919f66
--- /dev/null
+++ b/libiberty/vfork.c
@@ -0,0 +1,8 @@
+/* Emulate vfork using just plain fork, for systems without a real vfork.
+ This function is in the public domain. */
+
+int
+vfork ()
+{
+ return (fork ());
+}
diff --git a/libiberty/vfprintf.c b/libiberty/vfprintf.c
new file mode 100644
index 00000000000..db7b2ff4c19
--- /dev/null
+++ b/libiberty/vfprintf.c
@@ -0,0 +1,21 @@
+/* Provide a version vfprintf in terms of _doprnt.
+ By Kaveh Ghazi (ghazi@caip.rutgers.edu) 3/29/98
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ */
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdio.h>
+#undef vfprintf
+
+int
+vfprintf (stream, format, ap)
+ FILE * stream;
+ const char * format;
+ va_list ap;
+{
+ return _doprnt (format, ap, stream);
+}
diff --git a/libiberty/vmsbuild.com b/libiberty/vmsbuild.com
new file mode 100644
index 00000000000..4fede380bfd
--- /dev/null
+++ b/libiberty/vmsbuild.com
@@ -0,0 +1,165 @@
+$! libiberty/vmsbuild.com -- build liberty.olb for VMS host, VMS target
+$!
+$ CC = "gcc /noVerbose/Debug/Incl=([],[-.include])"
+$ LIBR = "library /Obj"
+$ LINK = "link"
+$ DELETE= "delete /noConfirm"
+$ SEARCH= "search /Exact"
+$ ECHO = "write sys$output"
+$ ABORT = "exit %x002C"
+$!
+$ LIB_NAME = "liberty.olb" !this is what we're going to construct
+$ WORK_LIB = "new-lib.olb" !used to guard against an incomplete build
+$
+$! manually copied from Makefile.in
+$ REQUIRED_OFILES = "argv.o basename.o choose-temp.o concat.o cplus-dem.o "-
+ + "fdmatch.o fnmatch.o getopt.o getopt1.o getruntime.o hex.o "-
+ + "floatformat.o objalloc.o obstack.o spaces.o strerror.o strsignal.o "-
+ + "xatexit.o xexit.o xmalloc.o xstrdup.o xstrerror.o"
+$! anything not caught by link+search of dummy.* should be added here
+$ EXTRA_OFILES = ""
+$!
+$! move to the directory which contains this command procedure
+$ old_dir = f$environ("DEFAULT")
+$ new_dir = f$parse("_._;",f$environ("PROCEDURE")) - "_._;"
+$ set default 'new_dir'
+$
+$ ECHO "Starting libiberty build..."
+$ create config.h
+/* libiberty config.h for VMS */
+#define NEED_sys_siglist
+#define NEED_strsignal
+#define NEED_psignal
+#define NEED_basename
+$ LIBR 'WORK_LIB' /Create
+$
+$! first pass: compile "required" modules
+$ ofiles = REQUIRED_OFILES + " " + EXTRA_OFILES
+$ pass = 1
+$ gosub do_ofiles
+$
+$! second pass: process dummy.c, using the first pass' results
+$ ECHO " now checking run-time library for missing functionality"
+$ if f$search("dummy.obj").nes."" then DELETE dummy.obj;*
+$ define/noLog sys$error _NL: !can't use /User_Mode here due to gcc
+$ define/noLog sys$output _NL: ! driver's use of multiple image activation
+$ on error then continue
+$ 'CC' dummy.c
+$ deassign sys$error !restore, more or less
+$ deassign sys$output
+$ if f$search("dummy.obj").eqs."" then goto pass2_failure1
+$! link dummy.obj, capturing full linker feedback in dummy.map
+$ oldmsg = f$environ("MESSAGE")
+$ set message /Facility/Severity/Identification/Text
+$ define/User sys$output _NL:
+$ define/User sys$error _NL:
+$ LINK/Map=dummy.map/noExe dummy.obj,'WORK_LIB'/Libr,-
+ gnu_cc:[000000]gcclib.olb/Libr,sys$library:vaxcrtl.olb/Libr
+$ set message 'oldmsg'
+$ if f$search("dummy.map").eqs."" then goto pass2_failure2
+$ DELETE dummy.obj;*
+$ SEARCH dummy.map "%LINK-I-UDFSYM" /Output=dummy.list
+$ DELETE dummy.map;*
+$ ECHO " check completed"
+$! we now have a file with one entry per line of unresolvable symbols
+$ ofiles = ""
+$ if f$trnlnm("IFILE$").nes."" then close/noLog ifile$
+$ open/Read ifile$ dummy.list
+$iloop: read/End=idone ifile$ iline
+$ iline = f$edit(iline,"COMPRESS,TRIM,LOWERCASE")
+$ ofiles = ofiles + " " + f$element(1," ",iline) + ".o"
+$ goto iloop
+$idone: close ifile$
+$ DELETE dummy.list;*
+$ on error then ABORT
+$
+$! third pass: compile "missing" modules collected in pass 2
+$ pass = 3
+$ gosub do_ofiles
+$
+$! finish up
+$ LIBR 'WORK_LIB' /Compress /Output='LIB_NAME' !new-lib.olb -> liberty.olb
+$ DELETE 'WORK_LIB';*
+$
+$! all done
+$ ECHO "Completed libiberty build."
+$ type sys$input:
+
+ You many wish to do
+ $ COPY LIBERTY.OLB GNU_CC:[000000]
+ so that this run-time library resides in the same location as gcc's
+ support library. When building gas, be sure to leave the original
+ copy of liberty.olb here so that gas's build procedure can find it.
+
+$ set default 'old_dir'
+$ exit
+$
+$!
+$! compile each element of the space-delimited list 'ofiles'
+$!
+$do_ofiles:
+$ ofiles = f$edit(ofiles,"COMPRESS,TRIM")
+$ i = 0
+$oloop:
+$ f = f$element(i," ",ofiles)
+$ if f.eqs." " then goto odone
+$ f = f - ".o" !strip dummy suffix
+$ ECHO " ''f'"
+$ skip_f = 0
+$ if pass.eq.3 .and. f$search("''f'.c").eqs."" then gosub chk_deffunc
+$ if .not.skip_f
+$ then
+$ 'CC' 'f'.c
+$ LIBR 'WORK_LIB' 'f'.obj /Insert
+$ DELETE 'f'.obj;*
+$ endif
+$ i = i + 1
+$ goto oloop
+$odone:
+$ return
+$
+$!
+$! check functions.def for a DEFFUNC() entry corresponding to missing file 'f'.c
+$!
+$chk_deffunc:
+$ define/User sys$output _NL:
+$ define/User sys$error _NL:
+$ SEARCH functions.def "DEFFUNC","''f'" /Match=AND
+$ if (($status.and.%x7FFFFFFF) .eq. 1)
+$ then
+$ skip_f = 1
+$ open/Append config_h config.h
+$ write config_h "#define NEED_''f'"
+$ close config_h
+$ endif
+$ return
+$
+$!
+$pass2_failure1:
+$! if we reach here, dummy.c failed to compile and we're really stuck
+$ type sys$input:
+
+ Cannot compile the library contents checker (dummy.c + functions.def),
+ so cannot continue!
+
+$! attempt the compile again, without suppressing diagnostic messages this time
+$ on error then ABORT +0*f$verify(v)
+$ v = f$verify(1)
+$ 'CC' dummy.c
+$ ABORT +0*f$verify(v) !'f$verify(0)'
+$!
+$pass2_failure2:
+$! should never reach here..
+$ type sys$input:
+
+ Cannot link the library contents checker (dummy.obj), so cannot continue!
+
+$! attempt the link again, without suppressing diagnostic messages this time
+$ on error then ABORT +0*f$verify(v)
+$ v = f$verify(1)
+$ LINK/Map=dummy.map/noExe dummy.obj,'WORK_LIB'/Libr,-
+ gnu_cc:[000000]gcclib.olb/Libr,sys$library:vaxcrtl.olb/Libr
+$ ABORT +0*f$verify(v) !'f$verify(0)'
+$
+$! not reached
+$ exit
diff --git a/libiberty/vprintf.c b/libiberty/vprintf.c
new file mode 100644
index 00000000000..65b425a4d6b
--- /dev/null
+++ b/libiberty/vprintf.c
@@ -0,0 +1,15 @@
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <stdio.h>
+#include <ansidecl.h>
+#undef vprintf
+int
+vprintf (format, ap)
+ const char *format;
+ va_list ap;
+{
+ return vfprintf (stdout, format, ap);
+}
diff --git a/libiberty/vsprintf.c b/libiberty/vsprintf.c
new file mode 100644
index 00000000000..bf0760cf6d3
--- /dev/null
+++ b/libiberty/vsprintf.c
@@ -0,0 +1,55 @@
+/* Simple implementation of vsprintf for systems without it.
+ Highly system-dependent, but should work on most "traditional"
+ implementations of stdio; newer ones should already have vsprintf.
+ Written by Per Bothner of Cygnus Support.
+ Based on libg++'s "form" (written by Doug Lea; dl@rocky.oswego.edu).
+ Copyright (C) 1991, 1995 Free Software Foundation, Inc.
+
+This file is part of the libiberty library. This library 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, or (at your option)
+any later version.
+
+This library 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+#include <varargs.h>
+#include <stdio.h>
+#include <ansidecl.h>
+#undef vsprintf
+
+int
+vsprintf (buf, format, ap)
+ char *buf;
+ const char *format;
+ va_list ap;
+{
+ FILE b;
+ int ret;
+#ifdef VMS
+ b->_flag = _IOWRT|_IOSTRG;
+ b->_ptr = buf;
+ b->_cnt = 12000;
+#else
+ b._flag = _IOWRT|_IOSTRG;
+ b._ptr = buf;
+ b._cnt = 12000;
+#endif
+ ret = _doprnt(format, ap, &b);
+ putc('\0', &b);
+ return ret;
+
+}
diff --git a/libiberty/waitpid.c b/libiberty/waitpid.c
new file mode 100644
index 00000000000..23db0b932d2
--- /dev/null
+++ b/libiberty/waitpid.c
@@ -0,0 +1,11 @@
+int
+waitpid (pid, stat_loc, options)
+ int pid, *stat_loc, options;
+{
+ for (;;)
+ {
+ int wpid = wait(stat_loc);
+ if (wpid == pid || wpid == -1)
+ return wpid;
+ }
+}
diff --git a/libiberty/xatexit.c b/libiberty/xatexit.c
new file mode 100644
index 00000000000..31476c29ddc
--- /dev/null
+++ b/libiberty/xatexit.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ */
+
+/* Adapted from newlib/libc/stdlib/{,at}exit.[ch].
+ If you use xatexit, you must call xexit instead of exit. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include <stdio.h>
+
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#endif
+
+/* For systems with larger pointers than ints, this must be declared. */
+PTR malloc PARAMS ((size_t));
+
+static void xatexit_cleanup PARAMS ((void));
+
+/* Pointer to function run by xexit. */
+extern void (*_xexit_cleanup) PARAMS ((void));
+
+#define XATEXIT_SIZE 32
+
+struct xatexit {
+ struct xatexit *next; /* next in list */
+ int ind; /* next index in this table */
+ void (*fns[XATEXIT_SIZE]) PARAMS ((void)); /* the table itself */
+};
+
+/* Allocate one struct statically to guarantee that we can register
+ at least a few handlers. */
+static struct xatexit xatexit_first;
+
+/* Points to head of LIFO stack. */
+static struct xatexit *xatexit_head = &xatexit_first;
+
+/* Register function FN to be run by xexit.
+ Return 0 if successful, -1 if not. */
+
+int
+xatexit (fn)
+ void (*fn) PARAMS ((void));
+{
+ register struct xatexit *p;
+
+ /* Tell xexit to call xatexit_cleanup. */
+ if (!_xexit_cleanup)
+ _xexit_cleanup = xatexit_cleanup;
+
+ p = xatexit_head;
+ if (p->ind >= XATEXIT_SIZE)
+ {
+ if ((p = (struct xatexit *) malloc (sizeof *p)) == NULL)
+ return -1;
+ p->ind = 0;
+ p->next = xatexit_head;
+ xatexit_head = p;
+ }
+ p->fns[p->ind++] = fn;
+ return 0;
+}
+
+/* Call any cleanup functions. */
+
+static void
+xatexit_cleanup ()
+{
+ register struct xatexit *p;
+ register int n;
+
+ for (p = xatexit_head; p; p = p->next)
+ for (n = p->ind; --n >= 0;)
+ (*p->fns[n]) ();
+}
diff --git a/libiberty/xexit.c b/libiberty/xexit.c
new file mode 100644
index 00000000000..431bbe02991
--- /dev/null
+++ b/libiberty/xexit.c
@@ -0,0 +1,36 @@
+/* xexit.c -- Run any exit handlers, then exit.
+ Copyright (C) 1994, 95, 1997 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not, write
+to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include <stdio.h>
+
+/* This variable is set by xatexit if it is called. This way, xmalloc
+ doesn't drag xatexit into the link. */
+void (*_xexit_cleanup) PARAMS ((void));
+
+void
+xexit (code)
+ int code;
+{
+ if (_xexit_cleanup != NULL)
+ (*_xexit_cleanup) ();
+ exit (code);
+}
diff --git a/libiberty/xmalloc.c b/libiberty/xmalloc.c
new file mode 100644
index 00000000000..1083790789d
--- /dev/null
+++ b/libiberty/xmalloc.c
@@ -0,0 +1,173 @@
+/* memory allocation routines with error checking.
+ Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include <stdio.h>
+
+#ifdef __STDC__
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#define ptrdiff_t long
+#endif
+
+#if VMS
+#include <stdlib.h>
+#include <unixlib.h>
+#else
+/* For systems with larger pointers than ints, these must be declared. */
+PTR malloc PARAMS ((size_t));
+PTR realloc PARAMS ((PTR, size_t));
+PTR calloc PARAMS ((size_t, size_t));
+PTR sbrk PARAMS ((ptrdiff_t));
+#endif
+
+/* The program name if set. */
+static const char *name = "";
+
+#if !defined (__CYGWIN__) && defined (__CYGWIN32__)
+#define __CYGWIN__ 1
+#endif
+
+#if ! defined (_WIN32) || defined (__CYGWIN__) || defined (__UWIN__)
+/* The initial sbrk, set when the program name is set. Not used for win32
+ ports other than cygwin32. */
+static char *first_break = NULL;
+#endif /* ! _WIN32 || __CYGWIN __ || __UWIN__ */
+
+void
+xmalloc_set_program_name (s)
+ const char *s;
+{
+ name = s;
+#if ! defined (_WIN32) || defined (__CYGWIN__) || defined (__UWIN__)
+ /* Win32 ports other than cygwin32 don't have brk() */
+ if (first_break == NULL)
+ first_break = (char *) sbrk (0);
+#endif /* ! _WIN32 || __CYGWIN __ || __UWIN__ */
+}
+
+PTR
+xmalloc (size)
+ size_t size;
+{
+ PTR newmem;
+
+ if (size == 0)
+ size = 1;
+ newmem = malloc (size);
+ if (!newmem)
+ {
+#if ! defined (_WIN32) || defined (__CYGWIN__) || defined (__UWIN__)
+ extern char **environ;
+ size_t allocated;
+
+ if (first_break != NULL)
+ allocated = (char *) sbrk (0) - first_break;
+ else
+ allocated = (char *) sbrk (0) - (char *) &environ;
+ fprintf (stderr,
+ "\n%s%sCan not allocate %lu bytes after allocating %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) size, (unsigned long) allocated);
+#else
+ fprintf (stderr,
+ "\n%s%sCan not allocate %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) size);
+#endif /* ! _WIN32 || __CYGWIN __ || __UWIN__ */
+ xexit (1);
+ }
+ return (newmem);
+}
+
+PTR
+xcalloc (nelem, elsize)
+ size_t nelem, elsize;
+{
+ PTR newmem;
+
+ if (nelem == 0 || elsize == 0)
+ nelem = elsize = 1;
+
+ newmem = calloc (nelem, elsize);
+ if (!newmem)
+ {
+#if ! defined (_WIN32) || defined (__CYGWIN__)
+ extern char **environ;
+ size_t allocated;
+
+ if (first_break != NULL)
+ allocated = (char *) sbrk (0) - first_break;
+ else
+ allocated = (char *) sbrk (0) - (char *) &environ;
+ fprintf (stderr,
+ "\n%s%sCan not allocate %lu bytes after allocating %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) (nelem * elsize), (unsigned long) allocated);
+#else
+ fprintf (stderr,
+ "\n%s%sCan not allocate %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) (nelem * elsize));
+#endif /* ! _WIN32 || __CYGWIN __ */
+ xexit (1);
+ }
+ return (newmem);
+}
+
+PTR
+xrealloc (oldmem, size)
+ PTR oldmem;
+ size_t size;
+{
+ PTR newmem;
+
+ if (size == 0)
+ size = 1;
+ if (!oldmem)
+ newmem = malloc (size);
+ else
+ newmem = realloc (oldmem, size);
+ if (!newmem)
+ {
+#ifndef __MINGW32__
+ extern char **environ;
+ size_t allocated;
+
+ if (first_break != NULL)
+ allocated = (char *) sbrk (0) - first_break;
+ else
+ allocated = (char *) sbrk (0) - (char *) &environ;
+ fprintf (stderr,
+ "\n%s%sCan not reallocate %lu bytes after allocating %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) size, (unsigned long) allocated);
+#else
+ fprintf (stderr,
+ "\n%s%sCan not reallocate %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) size);
+#endif /* __MINGW32__ */
+ xexit (1);
+ }
+ return (newmem);
+}
diff --git a/libiberty/xstrdup.c b/libiberty/xstrdup.c
new file mode 100644
index 00000000000..e16aba08554
--- /dev/null
+++ b/libiberty/xstrdup.c
@@ -0,0 +1,22 @@
+/* xstrdup.c -- Duplicate a string in memory, using xmalloc.
+ This trivial function is in the public domain.
+ Ian Lance Taylor, Cygnus Support, December 1995. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "ansidecl.h"
+#include "libiberty.h"
+
+char *
+xstrdup (s)
+ const char *s;
+{
+ register size_t len = strlen (s) + 1;
+ register char *ret = xmalloc (len);
+ memcpy (ret, s, len);
+ return ret;
+}
diff --git a/libiberty/xstrerror.c b/libiberty/xstrerror.c
new file mode 100644
index 00000000000..770b653ba80
--- /dev/null
+++ b/libiberty/xstrerror.c
@@ -0,0 +1,56 @@
+/* xstrerror.c -- jacket routine for more robust strerror() usage.
+ Fri Jun 16 18:30:00 1995 Pat Rankin <rankin@eql.caltech.edu>
+ This code is in the public domain. */
+
+#include <stdio.h>
+
+#include "libiberty.h"
+#include "config.h"
+
+#ifdef VMS
+#include <errno.h>
+#if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES)
+extern char *strerror PARAMS ((int,...));
+#define DONT_DECLARE_STRERROR
+#endif
+#endif /* VMS */
+
+#ifndef DONT_DECLARE_STRERROR
+extern char *strerror PARAMS ((int));
+#endif
+
+/* If strerror returns NULL, we'll format the number into a static buffer. */
+
+#define ERRSTR_FMT "undocumented error #%d"
+static char xstrerror_buf[sizeof ERRSTR_FMT + 20];
+
+/* Like strerror, but result is never a null pointer. */
+
+char *
+xstrerror (errnum)
+ int errnum;
+{
+ char *errstr;
+#ifdef VMS
+ char *(*vmslib_strerror) PARAMS ((int,...));
+
+ /* Override any possibly-conflicting declaration from system header. */
+ vmslib_strerror = (char *(*) PARAMS ((int,...))) strerror;
+ /* Second argument matters iff first is EVMSERR, but it's simpler to
+ pass it unconditionally. `vaxc$errno' is declared in <errno.h>
+ and maintained by the run-time library in parallel to `errno'.
+ We assume that `errnum' corresponds to the last value assigned to
+ errno by the run-time library, hence vaxc$errno will be relevant. */
+ errstr = (*vmslib_strerror) (errnum, vaxc$errno);
+#else
+ errstr = strerror (errnum);
+#endif
+
+ /* If `errnum' is out of range, result might be NULL. We'll fix that. */
+ if (!errstr)
+ {
+ sprintf (xstrerror_buf, ERRSTR_FMT, errnum);
+ errstr = xstrerror_buf;
+ }
+ return errstr;
+}
diff --git a/ltconfig b/ltconfig
new file mode 100755
index 00000000000..ab304fd3b73
--- /dev/null
+++ b/ltconfig
@@ -0,0 +1,2822 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != "Xset"; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) PATH_SEPARATOR=';' ;;
+ *) PATH_SEPARATOR=':' ;;
+ esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != "Xset"; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+ test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH /usr/ucb; do
+ if test -f $dir/echo &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif test -f /bin/ksh && test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running ltconfig again with it.
+ ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf "%s\n"'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.2f
+TIMESTAMP=" (1.385 1999/03/15 17:24:54)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+ case "$option" in
+ -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval "$prev=\$option"
+ prev=
+ continue
+ fi
+
+ case "$option" in
+ --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+ --debug enable verbose shell tracing
+ --disable-shared do not build shared libraries
+ --disable-static do not build static libraries
+ --disable-fast-install do not optimize for fast installation
+ --enable-dlopen enable dlopen support
+ --enable-dlopen-self enable support for dlopening programs
+ --help display this help and exit
+ --no-verify do not verify that HOST is a valid host type
+-o, --output=FILE specify the output file [default=$default_ofile]
+ --quiet same as \`--silent'
+ --silent do not print informational messages
+ --srcdir=DIR find \`config.guess' in DIR
+ --version output version information and exit
+ --with-gcc assume that the GNU C compiler will be used
+ --with-gnu-ld assume that the C compiler uses the GNU linker
+ --disable-lock disable file locking
+ --cache-file=FILE configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --disable-shared) enable_shared=no ;;
+
+ --disable-static) enable_static=no ;;
+
+ --disable-fast-install) enable_fast_install=no ;;
+
+ --enable-dlopen) enable_dlopen=yes ;;
+
+ --quiet | --silent) silent=yes ;;
+
+ --srcdir) prev=srcdir ;;
+ --srcdir=*) srcdir="$optarg" ;;
+
+ --no-verify) verify_host=no ;;
+
+ --output | -o) prev=ofile ;;
+ --output=*) ofile="$optarg" ;;
+
+ --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+ --with-gcc) with_gcc=yes ;;
+ --with-gnu-ld) with_gnu_ld=yes ;;
+
+ --disable-lock) need_locks=no ;;
+
+ --cache-file=*) cache_file="$optarg" ;;
+
+ -*)
+ echo "$progname: unrecognized option \`$option'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ if test -z "$ltmain"; then
+ ltmain="$option"
+ elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+# echo "$progname: warning \`$option' is not a valid host type" 1>&2
+# fi
+ host="$option"
+ else
+ echo "$progname: too many arguments" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if test -z "$ltmain"; then
+ echo "$progname: you must specify a LTMAIN file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+if test ! -f "$ltmain"; then
+ echo "$progname: \`$ltmain' does not exist" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+ case "$arg" in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ltconfig_args="$ltconfig_args '$arg'" ;;
+ *) ltconfig_args="$ltconfig_args $arg" ;;
+ esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+ echo "loading cache $cache_file within ltconfig"
+ . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+ # Assume the source directory is the same one as the path to LTMAIN.
+ srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+ test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+ # Check for config.guess and config.sub.
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/config.guess; then
+ ac_aux_dir=$ac_dir
+ break
+ fi
+ done
+ if test -z "$ac_aux_dir"; then
+ echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+ ac_config_guess=$ac_aux_dir/config.guess
+ ac_config_sub=$ac_aux_dir/config.sub
+
+ # Make sure we can run config.sub.
+ if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+ else
+ echo "$progname: cannot run $ac_config_sub" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+ host_alias=$host
+ case "$host_alias" in
+ "")
+ if host_alias=`$SHELL $ac_config_guess`; then :
+ else
+ echo "$progname: cannot guess host type; you must specify one" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+ host=`$SHELL $ac_config_sub $host_alias`
+ echo "$ac_t$host" 1>&6
+
+ # Make sure the host verified.
+ test -z "$host" && exit 1
+
+elif test -z "$host"; then
+ echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+else
+ host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+ result=no
+
+ echo $ac_n "checking for ranlib... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/ranlib; then
+ RANLIB="ranlib"
+ result="ranlib"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL' and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+ # If CC is not set, then try to find GCC or a usable CC.
+ if test -z "$CC"; then
+ echo $ac_n "checking for gcc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ IFS="$save_ifs"
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+ fi
+
+ # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+ if test -z "$CC"; then
+ echo $ac_n "checking for cc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ cc_rejected=no
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/cc; then
+ if test "$dir/cc" = "/usr/ucb/cc"; then
+ cc_rejected=yes
+ continue
+ fi
+ CC="cc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test $cc_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same name, so the bogon will be chosen
+ # first if we set CC to just the name; use the full file name.
+ shift
+ set dummy "$dir/cc" "$@"
+ shift
+ CC="$@"
+ fi
+ fi
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$CC"; then
+ echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+ exit 1
+ fi
+ fi
+
+ # Now see if the compiler is really GCC.
+ with_gcc=no
+ echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+ echo "$progname:564: checking whether we are using GNU C" >&5
+
+ $rm conftest.c
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+ if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:572: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ with_gcc=yes
+ fi
+ $rm conftest.c
+ echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:586: checking for object suffix" >& 5
+if { (eval echo $progname:587: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+ wl='-Wl,'
+ link_static_flag='-static'
+
+ case "$host_os" in
+ beos* | irix5* | irix6* | osf3* | osf4*)
+ # PIC is the default for these OSes.
+ ;;
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # we not sure about C++ programs.
+ link_static_flag="$link_static_flag ${wl}-lC"
+ ;;
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ pic_flag='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ *)
+ pic_flag='-fPIC'
+ ;;
+ esac
+else
+ # PORTME Check for PIC flags for the system compiler.
+ case "$host_os" in
+ aix3* | aix4*)
+ # All AIX code is PIC.
+ link_static_flag='-bnso -bI:/lib/syscalls.exp'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better link_static_flag that works with the bundled CC?
+ wl='-Wl,'
+ link_static_flag="${wl}-a ${wl}archive"
+ pic_flag='+Z'
+ ;;
+
+ irix5* | irix6*)
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+
+ osf3* | osf4*)
+ # All OSF/1 code is PIC.
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ pic_flag='-Kpic'
+ link_static_flag='-dn'
+ special_shlib_compile_flags='-belf'
+ ;;
+
+ solaris*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ sunos4*)
+ pic_flag='-PIC'
+ link_static_flag='-Bstatic'
+ wl='-Qoption ld '
+ ;;
+
+ sysv4.2uw2* | sysv4.3* | sysv5*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ uts4*)
+ pic_flag='-pic'
+ link_static_flag='-Bstatic'
+ ;;
+
+ *)
+ can_build_shared=no
+ ;;
+ esac
+fi
+
+if test -n "$pic_flag"; then
+ echo "$ac_t$pic_flag" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $pic_flag -DPIC"
+ echo "$progname:717: checking if $compiler PIC flag $pic_flag works" >&5
+ if { (eval echo $progname:718: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ case "$host_os" in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+ # create non-PIC objects. So, if there were any warnings, we assume that
+ # PIC is not supported.
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ can_build_shared=no
+ pic_flag=
+ else
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ fi
+ ;;
+ *)
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ ;;
+ esac
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ can_build_shared=no
+ pic_flag=
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -c -o conftest2.o"
+echo "$progname:760: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest2.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_c_o=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_c_o=no
+ echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+$rm conftest*
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ echo "$progname:788: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:789: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_o_lo=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_o_lo=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_o_lo=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t$hard_links" 1>&6
+ $rm conftest*
+ if test "$hard_links" = no; then
+ echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+ echo "$progname:840: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ if { (eval echo $progname:841: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_rtti_exceptions=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_rtti_exceptions=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_rtti_exceptions=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+ echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then :
+ else
+ echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:884: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ echo "$ac_t$link_static_flag" 1>&6
+else
+ echo "$ac_t"none 1>&6
+ link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+ # Check to see if we can use ln -s, or we need hard links.
+ echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+ $rm conftestdata
+ if ln -s X conftestdata 2>/dev/null; then
+ $rm conftestdata
+ LN_S="ln -s"
+ else
+ LN_S=ln
+ fi
+ if test "$LN_S" = "ln -s"; then
+ echo "$ac_t"yes 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+ ac_prog=ld
+ if test "$with_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+ echo "$progname:917: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we are not using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+ echo "$progname:941: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+ echo "$progname:944: checking for non-GNU ld" >&5
+ fi
+
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ fi
+
+ if test -n "$LD"; then
+ echo "$ac_t$LD" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$LD"; then
+ echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+ exit 1
+ fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms=
+
+case "$host_os" in
+cygwin* | mingw*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$with_gcc" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+
+freebsd2* | sunos4*)
+ exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+ ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case "$host_os" in
+ aix3* | aix4*)
+ # On AIX, the GNU linker is very broken
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ export_symbols_cmds='rm -f $objdir/$soname-ltdll.c~
+ sed -e "/^# \/\* ltdll.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ (cd $objdir && $CC -c $soname-ltdll.c)~
+ $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols'
+
+ archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+ _lt_hint=1;
+ for symbol in `cat $export_symbols`; do
+ echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done~
+ $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+ old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a'
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case "$host_os" in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4*)
+ allow_undefined_flag=
+ if test "$with_gcc" = yes; then
+ if strings `${CC} -print-prog-name=collect2` | \
+ grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ fi
+ archive_cmds='$CC -shared ${wl}-bnoentry -o $objdir/$soname $libobjs $deplibs $linkopts'
+ else
+ always_export_symbols=yes
+ archive_expsym_cmds='$CC -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bM:SRE ${wl}-bnoentry'
+ hardcode_direct=yes
+ fi
+ hardcode_minus_L=yes
+ # Though LIBPATH variable hardcodes shlibpath into executable,
+ # it doesn't affect searching for -l* libraries; this confuses
+ # tests in mdemo.
+ hardcode_shlibpath_var=unsupported
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+
+ cygwin* | mingw*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+ fix_srcfile_path='`cygpath -w $srcfile`'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ can_build_shared=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=no # verified on 2.2.6
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ archive_cmds='$rm $objdir/$soname~$LD -b +s +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10* | hpux11*)
+ archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF
+ fi
+ hardcode_libdir_flag_spec='${wl}-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+ ;;
+
+ osf3* | osf4*)
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sunos4*)
+ # Why do we need -Bstatic? To avoid inter-library dependencies, maybe...
+ if test "$with_gcc" = yes; then
+ # Use -fPIC here because libgcc is multilibbed
+ archive_cmds='$CC -shared ${wl}-Bstatic -fPIC -o $lib $libobjs $deplibs $linkopts'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=no
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=no
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=no
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ can_build_shared=no
+ ;;
+ esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+ echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+ case "$NM" in
+ /* | [A-Za-z]:[/\\]*) ;; # Let the user override the test with a path.
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -p"
+ break
+ else
+ NM=${NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$NM" && NM=nm
+ ;;
+ esac
+ echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+ global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ $rm conftest*
+ cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ echo "$progname:1447: checking if global_symbol_pipe works" >&5
+ if { (eval echo $progname:1448: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { echo "$progname:1451: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$objext conftestm.$objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo $progname:1503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$save_LIBS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ global_symbol_pipe=
+ fi
+done
+echo "$ac_t$pipe_works" 1>&6
+
+if test -z "$global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no && \
+ test "$hardcode_minus_L" != no && \
+ test "$hardcode_shlibpath_var" != no; then
+
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4*)
+ version_type=linux
+ # AIX has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ # We preserve .a as extension for shared libraries though AIX4.2
+ # and later linker supports .so
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+ shlibpath_var=LIBPATH
+ deplibs_check_method=pass_all
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ library_names_spec='${libname}.so$major ${libname}.so'
+ soname_spec='${libname}.so'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ deplibs_check_method='file_magic ELF 32-bit LSB shared object'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw*)
+ version_type=windows
+ if test "$with_gcc" = yes; then
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+ else
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ fi
+ dynamic_linker='Win32 ld.exe'
+ deplibs_check_method='file_magic file format pei*-i386.*architecture: i386'
+ file_magic_cmd='objdump -f'
+ need_lib_prefix=no
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case "$version_type" in
+ freebsd-elf*)
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ deplibs_check_method=unknown
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ finish_cmds='PATH="$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+gnu*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5*)
+ version_type=irix
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" # or should it be pass_all?
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib/libc.so*`
+ shlibpath_overrides_runpath=no
+ ;;
+
+irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ case "$LD" in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ # even though /usr/local/lib is always searched, the man-page says
+ # shared libraries should not be installed there if they use an ABI
+ # different from -32, so we'd better not search for shared libraries
+ # there either
+ sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+ deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" # or should it be pass_all?
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+ if test -f /lib/ld.so.1; then
+ dynamic_linker='GNU ld.so'
+ else
+ # Only the GNU ld.so supports shared libraries on MkLinux.
+ case "$host_cpu" in
+ powerpc*) dynamic_linker=no ;;
+ *) dynamic_linker='Linux ld.so' ;;
+ esac
+ fi
+ ;;
+
+netbsd*)
+ version_type=sunos
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+openbsd*)
+ version_type=sunos
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ need_version=no
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4*)
+ version_type=osf
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ # deplibs_check_method='pass_all'
+ # Although pass_all appears to work, it copies symbols from static libraries
+ # into shared ones and exports them. So, when a program is linked with two
+ # or more libraries that have got copies of the same symbols, link fails
+ # This was only tested on osf4:
+ deplibs_check_method='file_magic COFF format alpha shared library'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/lib/libc.so
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_vendor" in
+ ncr)
+ deplibs_check_method='pass_all'
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+ case "$deplibs_check_method" in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ test "$enable_shared" = yes && enable_static=no
+ ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+ lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:1977: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1982 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2022: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2030 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2059: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2067 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2096: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2101 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for LoadLibrary""... $ac_c" 1>&6
+echo "$progname:2141: checking for LoadLibrary" >&5
+if eval "test \"`echo '$''{'ac_cv_func_LoadLibrary'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2146 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char LoadLibrary(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char LoadLibrary();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_LoadLibrary) || defined (__stub___LoadLibrary)
+choke me
+#else
+LoadLibrary();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_LoadLibrary=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_LoadLibrary=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'LoadLibrary`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="LoadLibrary"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+fi
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ fi
+
+ case "$lt_cv_dlopen" in
+ dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2210: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2215 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo $progname:2220: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ if test "x$ac_cv_header_dlfcn_h" = xyes; then
+ CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ fi
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2248: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self=cross
+ else
+ cat > conftest.c <<EOF
+#line 2256 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) exit(0); } exit(1); }
+
+EOF
+if { (eval echo $progname:2302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "$lt_cv_dlopen_self" = yes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2321: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self_static=cross
+ else
+ cat > conftest.c <<EOF
+#line 2329 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) exit(0); } exit(1); }
+
+EOF
+if { (eval echo $progname:2375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self_static=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+ ;;
+ esac
+
+ case "$lt_cv_dlopen_self" in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case "$lt_cv_dlopen_self_static" in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+ # Now quote all the things that may contain metacharacters.
+ for var in ltecho old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+ old_LN_S old_DLLTOOL old_AS AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+ file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case "$var" in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case "$ltecho" in
+ *'\$0 --fallback-echo"')
+ ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+ ;;
+ esac
+
+ trap "$rm \"$ofile\"; exit 1" 1 2 15
+ echo "creating $ofile"
+ $rm "$ofile"
+ cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+ cfgfile="$ofile"
+ ;;
+
+*)
+ # Double-quote the variables that need it (for aesthetics).
+ for var in old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+ old_LN_S old_DLLTOOL old_AS; do
+ eval "$var=\\\"\$var\\\""
+ done
+
+ # Just create a config file.
+ cfgfile="$ofile.cfg"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ echo "creating $cfgfile"
+ $rm "$cfgfile"
+ cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+ ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL="$old_DLLTOOL" AS="$old_AS" \\
+# $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required
+always_export_symbols=$always_export_symbols
+
+# The command to extract exported symbols
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+ echo '### END LIBTOOL CONFIG' >> "$ofile"
+ echo >> "$ofile"
+ case "$host_os" in
+ aix3*)
+ cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # Append the ltmain.sh script.
+ cat "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+
+ chmod +x "$ofile"
+ ;;
+
+*)
+ # Compile the libtool program.
+ echo "FIXME: would compile $ltmain"
+ ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 00000000000..878787a3c1e
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,3782 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.2f
+TIMESTAMP=" (1.33 1999/04/26 16:28:53)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \012 \040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ case "$user_target" in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case "$user_target" in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $pic_flag -DPIC $srcfile"
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ # Now arrange that obj and lo_libobj become the same file
+ $show "$LN_S $obj $lo_libobj"
+ if $run $LN_S $obj $lo_libobj; then
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ command="$base_compile $srcfile"
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ C_compiler="$CC" # save it, to compile generated C sources
+ # CYGNUS LOCAL: tromey/java
+ # Always respect the CC configured in by ltconfig.
+ # CC="$nonopt"
+ # END CYGNUS LOCAL
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+#
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (!dll)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ compile_command="$CC"
+ finalize_command="$CC"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ linkopts=
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ lib_search_path=
+ fi
+ # now prepend the system-specific ones
+ eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ module=no
+ objs=
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ dlprefiles="$dlprefiles $arg"
+ test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+ prev=
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath)
+ rpath="$rpath $arg"
+ prev=
+ continue
+ ;;
+ xrpath)
+ xrpath="$xrpath $arg"
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ dlopen_self=$dlopen_self_static
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ if test "$export_dynamic" != yes; then
+ export_dynamic=yes
+ if test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ else
+ arg=
+ fi
+ fi
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: cannot have more than one -exported-symbols"
+ exit 1
+ fi
+ if test "$arg" = "-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'`
+ case "$dir" in
+ /* | [A-Za-z]:[/\\]*)
+ # Add the corresponding hardcode_libdir_flag, if it is not identical.
+ ;;
+ *)
+ $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2
+ exit 1
+ ;;
+ esac
+ case " $deplibs " in
+ *" $arg "*) ;;
+ *) deplibs="$deplibs $arg";;
+ esac
+ case " $lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir";;
+ esac
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ case ":$dllsearchpath:" in
+ ::) dllsearchpath="$dllsearchdir";;
+ *":$dllsearchdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+ esac
+ ;;
+ esac
+ ;;
+
+ -l*)
+ deplibs="$deplibs $arg"
+ ;;
+
+ -module)
+ if test "$module" != yes; then
+ module=yes
+ if test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ else
+ arg=
+ fi
+ fi
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ xrpath="$xrpath "`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ dlopen_self=$dlopen_self_static
+ fi
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.obj | *.a | *.lib)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+ if test "X$installed" = Xyes; then
+ dir="$libdir"
+ else
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ fi
+
+ if test -n "$dependency_libs"; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for deplib in $dependency_libs; do
+ case "$deplib" in
+ -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ case " $rpath $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ -L*) case "$compile_command $temp_deplibs " in
+ *" $deplib "*) ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ if test -z "$libdir"; then
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$deplibs$dependency_libs"
+ compile_command="$compile_command $dir/$old_library$dependency_libs"
+ finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+ continue
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking statically,
+ # we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # We need an absolute path.
+ case "$dir" in
+ /* | [A-Za-z]:[/\\]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: cannot determine absolute directory name of \`$libdir'" 1>&2
+ exit 1
+ fi
+ ;;
+ esac
+
+ # This is the magic to use -rpath.
+ # Skip directories that are in the system default run-time
+ # search path, unless they have been requested with -R.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+
+ lib_linked=yes
+ case "$hardcode_action" in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ deplibs="$deplibs $dir/$linklib"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ if test -n "$dllsearchpath"; then
+ dllsearchpath="$dllsearchpath:$dllsearchdir"
+ else
+ dllsearchpath="$dllsearchdir"
+ fi
+ ;;
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case "$host" in
+ *-*-sunos*)
+ compile_shlibpath="$compile_shlibpath$dir:"
+ ;;
+ esac
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ case ":$compile_shlibpath:" in
+ *":$dir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$dir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ relink)
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $absdir/$linklib"
+ deplibs="$deplibs $absdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$compile_command " in
+ *" -L$absdir "*) ;;
+ *) compile_command="$compile_command -L$absdir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$absdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$compile_shlibpath:" in
+ *":$absdir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$absdir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ *)
+ lib_linked=no
+ ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$finalize_command " in
+ *" -L$libdir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$finalize_shlibpath:" in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$dir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *.a | *.lib)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$outputname" in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+ dependency_libs="$deplibs"
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case "$version_type" in
+ none) ;;
+
+ irix)
+ major=`expr $current - $age + 1`
+ versuffix="$major.$revision"
+ verstring="sgi$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test $loop != 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="sgi$major.$iface:$verstring"
+ done
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ windows)
+ # Like Linux, but with '-' rather than '.', since we only
+ # want one extension on Windows 95.
+ major=`expr $current - $age`
+ versuffix="-$major-$age-$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ dependency_libs="$deplibs"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *)
+ # Add libc to deplibs on all other systems.
+ deplibs="$deplibs -lc"
+ ;;
+ esac
+ fi
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $output_objdir; then
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ else
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ if test "$build_libtool_libs" = yes; then
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case "$deplibs_check_method" in
+ pass_all)
+ newdeplibs=$deplibs
+ ;; # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $C_compiler -o conftest conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ $rm conftest
+ $C_compiler -o conftest conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ deplibs=$newdeplibs
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potlib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case "$potliblink" in
+ /*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *) newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ dlname=
+ library_names=
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+ fi
+ fi
+ fi
+
+ # test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ deplibs=$newdeplibs
+ # Done checking deplibs!
+
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) incase we are running --disable-static
+ for obj in $libobjs; do
+ oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"`
+ test -f $oldobj || ${LN_S} $obj $oldobj
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ if test -n "$whole_archive_flag_spec"; then
+ if test -n "$convenience"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ fi
+ else
+ for xlib in $convenience; do
+ # Extract the objects.
+ xdir="$xlib"x
+ generated="$generated $xdir"
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x ../$xlib)"
+ $run eval "(cd \$xdir && $AR x ../\$xlib)" || exit $?
+
+ libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+
+ linkopts="$linkopts $flag"
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ *.lo | *.o | *.obj)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Create the old-style object.
+ reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ test -z "$libobj" && exit 0
+
+ if test "$build_libtool_libs" != yes; then
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ $show "$LN_S $obj $libobj"
+ $run $LN_S $obj $libobj || exit $?
+ fi
+
+ exit 0
+ ;;
+
+ # Anything else should be a program.
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ if test "$dlself" = yes && test "$export_dynamic" = no; then
+ $echo "$modename: error: \`-dlopen self' requires \`-export-dynamic'" 1>&2
+ exit 1
+ fi
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$compile_rpath " in
+ *" $libdir "*) ;;
+ *) compile_rpath="$compile_rpath $libdir" ;;
+ esac
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" = yes; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$objdir/${output}.nm"
+
+ if test -d $objdir; then
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+ else
+ $show "$mkdir $objdir"
+ $run $mkdir $objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $objdir; then
+ exit $status
+ fi
+ fi
+
+ # Parse the name list into a source file.
+ $show "creating $objdir/$dlsyms"
+
+ $echo > "$objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run $rm $export_symbols
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$objdir/$output.exp"'
+ $run eval 'grep -f "$objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \
+ -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \
+ < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case "$host" in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ exit $?
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ /* | [A-Za-z]:[/\\]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ # AGH! Flame the AIX and HP-UX people for me, will ya?
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Create the binary in the object directory, then wrap it.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $objdir; then
+ exit $status
+ fi
+ fi
+
+ # Delete the old output file.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case "$0" in
+ /* | [A-Za-z]:[/\\]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ link_against_libtool_libs='$link_against_libtool_libs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ /* | [A-Za-z]:[/\\]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if (cd \"\$thisdir\" && eval \$relink_command); then :
+ else
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ *-*-cygwin* | *-*-mingw | *-*-os2*)
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ xdir="$xlib"x
+ generated="$generated $xdir"
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x ../$xlib)"
+ $run eval "(cd \$xdir && $AR x ../\$xlib)" || exit $?
+
+ oldobjs="$oldobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ if test -n "$xrpath"; then
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ done
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ $echo > $output "\
+# $output - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=no
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+
+ $rm "$output_objdir/$outputname"i
+ sed 's/^installed=no$/installed=yes/' \
+ < "$output" > "$output_objdir/$outputname"i || exit 1
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ /* | [A-Za-z]:[/\\]*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a | *.lib)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+ test "X$dlname" = "X$realname" && dlname=
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ test "X$dlname" = "X$linkname" && dlname=
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ if test -n "$dlname"; then
+ # Install the dynamically-loadable library.
+ $show "$install_prog $dir/$dlname $destdir/$dlname"
+ $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ if test ! -f "$instname"; then
+ # Just in case it was removed...
+ $show "Creating $instname"
+ $rm "$instname"
+ sed 's/^installed=no$/installed=yes/' "$file" > "$instname"
+ fi
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.o | *.obj)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes; then
+ outputname="/tmp/$$-$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && $rm $outputname
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ test "X$n" = "X$dlname" && dlname=
+ done
+ test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/makeall.bat b/makeall.bat
new file mode 100644
index 00000000000..d2d415f0a49
--- /dev/null
+++ b/makeall.bat
@@ -0,0 +1,16 @@
+@echo off
+chdir libiberty
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\bfd
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\opcodes
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\gprof
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\binutils
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\gas
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..\ld
+make %1 %2 %3 %4 %5 %6 %7 %8 %9
+chdir ..
diff --git a/makefile.vms b/makefile.vms
new file mode 100644
index 00000000000..a9e363403b5
--- /dev/null
+++ b/makefile.vms
@@ -0,0 +1,71 @@
+#
+# makefile for bfd, binutils and gas
+#
+# Created by Klaus K"ampf (kkaempf@rmi.de)
+#
+# You must use Version 3.76 of GNU Make
+#
+#
+
+ifeq ($(ARCH),ALPHA)
+CC = gcc
+GASCC = $(CC)
+else
+CC = cc
+GASCC = gcc
+endif
+
+ifeq ($(CC),cc)
+ CHECK-COMPILER = check_compiler
+else
+ CHECK-COMPILER =
+endif
+
+all: check_cc $(CHECK-COMPILER) [.binutils]makefile.vms
+ $(CD) [.bfd]
+ @gmake "CC=$(CC)"
+ $(CD) [-.opcodes]
+ @gmake "CC=$(CC)"
+ $(CD) [-.libiberty]
+ @gmake "CC=$(CC)"
+ $(CD) [-.binutils]
+ @gmake "CC=$(CC)"
+ $(CD) [-.gas]
+ @gmake "CC=$(GASCC)"
+ $(CD) [-]
+
+check_cc:
+ifeq ($CC,)
+ @$(ECHO) "Please edit MAKEFILE.VMS and select a C Compiler."
+ stop
+endif
+
+check_compiler:
+ @$(ECHO) "Perform a '$$ @setup' before starting make"
+
+[.binutils]makefile.vms:
+ $(CD) [.binutils]
+ $$ @configure
+ $(CD) [-]
+
+install: all
+ $(CD) [.binutils]
+ @gmake "CC=$(CC)" install
+ $(CD) [-]
+ $(CD) [.gas]
+ @gmake "CC=$(GASCC)" install
+ $(CD) [-]
+
+clean:
+ $(CD) [.bfd]
+ @gmake clean
+ $(CD) [-.opcodes]
+ @gmake clean
+ $(CD) [-.libiberty]
+ @gmake clean
+ $(CD) [-.binutils]
+ @gmake clean
+ $(CD) [-.gas]
+ @gmake clean
+ $(CD) [-]
+
diff --git a/missing b/missing
new file mode 100755
index 00000000000..7789652e877
--- /dev/null
+++ b/missing
@@ -0,0 +1,190 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing - GNU libit 0.0"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`configure.in'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`configure.in'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`configure.in'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 00000000000..cc8783edce3
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,36 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
+ fi
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/move-if-change b/move-if-change
new file mode 100755
index 00000000000..ee1b348beeb
--- /dev/null
+++ b/move-if-change
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Copyright (C) 1996 Free Software Foundation, Inc.
+#
+# 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if
+test -r $2
+then
+if
+cmp $1 $2 > /dev/null
+then
+echo $2 is unchanged
+rm -f $1
+else
+mv -f $1 $2
+fi
+else
+mv -f $1 $2
+fi
diff --git a/mpw-README b/mpw-README
new file mode 100644
index 00000000000..767140b5b26
--- /dev/null
+++ b/mpw-README
@@ -0,0 +1,376 @@
+This is basic information about the Macintosh(tm) MPW(tm) port of the
+GNU tools. The information below applies to both native and cross
+compilers.
+
+(Please note that there are two versions of this file; "mpw-README"
+is the source form, and "Read Me for MPW" is the distribution form.
+"Read Me for MPW" has 8-bit chars such as \Option-d embedded in it.)
+
+INSTALLING GNU TOOLS
+
+* System Requirements
+
+To use these tools, you will need a Mac with a 68020 or better or else
+any PowerMac, System 7.1 or later, and MPW 3.3 or 3.4. You will *not*
+need any other MPW compiler unless you want to rebuild from sources,
+nor even any include files, unless you are building actual Mac
+applications. For PowerMac native you will need PPCLink, however;
+also the executables are PowerPC-only.
+
+* Automated Installation
+
+The simplest way to install GNU tools is to run the Install script.
+The script will copy things to where you want to keep them, will build
+a UserStartup file with settings corresponding to where things were
+copied, and offer to put that UserStartup file in your MPW folder.
+
+The Install script does not alter anything in the System Folder, and
+it does not take any action without confirmation.
+
+The Install script will be at the top level of the binary
+distribution, or at the top level of the object directory if
+rebuilding from source. (The sources include a file called
+"mpw-install" at the top level, but it is the source to the Install
+script and cannot be run directly.)
+
+* Manual Installation
+
+If you don't want to run the Install script, you can do installation
+manually; this section describes the steps involved.
+
+The GNU tools can go in any directory that is in your {Commands} list.
+We generally put all the tools somewhere like {Boot}Cygnus:latest:bin,
+and then add to a UserStartup file:
+
+ set Commands "{Boot}Cygnus:latest:bin:,{Commands}"
+
+However, the cpp and cc1 programs of GCC are not normally stored here.
+Instead, they will be in a "lib" directory that is alongside "bin",
+and organized by target and version underneath, with names like
+
+ :lib:gcc-lib:<target>:cygnus-<version>:
+
+If you build and install everything yourself according to the build
+instructions below, then you will not have any problems. However, you
+may discover that GCC seems unable to find the right cpp and cc1;
+usually this will be because directory names have changed. (Even
+renaming your hard disk will make this happen.) In such cases, you
+have several choices. One is just to add this directory to
+{Commands}, but then you will not be able to get any other cpp or cc1,
+such as those used by a different target or version. Another way is
+to rename your disk and directories to match the prefix used when the
+tools were compiled. Finally, you can set the variable
+GCC_EXEC_PREFIX to point to the library directory:
+
+ set GCC_EXEC_PREFIX MyDisk:Stuff:lib:gcc-lib:
+ export GCC_EXEC_PREFIX
+
+You may also want to edit MPW's HEXA 128 resource. When GCC is built
+using a native GCC, it is compiled to use a special stack allocator
+function alloca(). While this is very efficient, it means that GCC
+will need considerable stack space to run, especially when compiling
+large programs with optimization turned on. You give MPW more stack
+by editing the HEXA 128 resource of the MPW Shell. A value of "0008
+0000" gives 512K of stack size, which is usually sufficient.
+
+USING GNU TOOLS
+
+* Using Native PowerMac GCC
+
+Using a native PowerMac GCC to produce MPW tools or MacOS applications
+is more complicated than just "gC foo.c", although no more complicated
+than with other Mac compilers.
+
+To build a native PowerMac MPW tool, use this sequence, where hello.c
+is the usual "hello world" program, and genericcfrg.r is the Rez file
+with the code fragment resource:
+
+gC -I{CIncludes} -fno-builtin -Dpascal= -c -g hello.c
+PPCLink hello.o -o hello \Option-d
+ "{PPCLibraries}"StdCRuntime.o \Option-d
+ "{SharedLibraries}"InterfaceLib \Option-d
+ "{SharedLibraries}"StdCLib \Option-d
+ "{PPCLibraries}"PPCToolLibs.o \Option-d
+ "{PPCLibraries}"PPCCRuntime.o \Option-d
+ "{GCCPPCLibraries}"libgcc.xcoff
+rez -d APPNAME='"'hello'"' GenericCFRG.r -o hello
+setfile -t 'MPST' -c 'MPS ' hello
+
+The same sequence works to build a MacOS application, but you set the file
+type to 'APPL' and don't link in PPCToolLibs.o. For further details on
+using MPW to build Mac applications, see the general MPW documentation.
+
+Recent versions of PPCLink have an option to generate the code
+fragment resource and automatically set creator and file type;
+here is what GenericCFRG.r should look like if you have an older
+PPCLink or are using GNU ld:
+
+#include "CodeFragmentTypes.r"
+
+resource 'cfrg' (0) {
+ {
+ kPowerPC,
+ kFullLib,
+ kNoVersionNum,kNoVersionNum,
+ 0,0,
+ kIsApp,kOnDiskFlat,kZeroOffset,kWholeFork,
+ APPNAME // must be defined on Rez command line with -d option
+ }
+};
+
+In general this port of GCC supports the same option syntax and
+behavior as its Unix counterpart. It also has similar compilation
+rules, so it will run the assembler on .s files and so forth.
+
+The GCC manual includes full information on the available options.
+One option that may be especially useful is "-v", which shows you what
+tools and options are being used; unlike most Mac C compilers, GCC
+directs assembly and linking in addition to compilation.
+
+MPW GCC does feature two extensions to the option syntax; '-d macro=name'
+works just as '-Dmacro=name' does in Unix, and '-i directory' works the
+same as '-Idirectory'.
+
+MPW GCC supports the usual Pascal-style strings and alignment pragmas.
+
+To find standard include files you can set the variable GCCIncludes:
+
+ set GCCIncludes MyDisk:MyIncludes:
+ export GCCIncludes
+
+GCCIncludes is similar to MPW's CIncludes or CW's MWCIncludes. In
+order to use MPW's usual include files, just say:
+
+ set GCCIncludes "{CIncludes}"
+ export GCCIncludes
+
+* Using GCC as a Cross-Compiler
+
+If you have a cross-compiler, and you have all of the correct
+target-side crt0 and libraries available, then to compile and link a
+file "foo.c", you can say just
+
+ gC foo.c
+
+The output file will be an MPW binary file named "a.out"; the format
+of the contents will depend on which target is in use, so for instance
+a MIPS-targeting GCC will produce ECOFF or ELF executables.
+
+Note that using MPW include files with a cross-compiler is somewhat
+dangerous.
+
+* Using the Assembler and Friends
+
+The assembler ("as") and linker ("ld") are faithful ports of their
+Unix counterparts. Similarly, the binutils "ar", "cplusfilt", "nm",
+"objcopy", "objdump", "ranlib", "size", "strings", and "strip" are all
+like they are under Unix. (Note that "cplusfilt" is usually called
+"c++filt" under Unix.)
+
+* Using GDB
+
+There are two flavors of GDB. "gdb" is an MPW tool that works very
+much like it does in Unix; put a command into the MPW worksheet and
+type the <enter> key to send it to GDB. While "gdb" is running, you
+cannot do anything else in MPW, although you can switch to other
+Mac applications and use them.
+
+"SiowGDB" is also a Mac application, but it is GDB using the SIOW
+package to provide console emulation. Commands are exactly as for the
+MPW tool, but since this is its own application, you can switch
+between it and MPW.
+
+BUILDING GNU TOOLS
+
+This port of the GNU tools uses a configure script similar to
+that used for GNU tools under Unix, but rewritten for MPW. As with
+Unix configuration, there is an "object" directory that may be
+different from the "source" directory. In the example commands below,
+we will assume that we are currently in the object directory, and that
+the source directory is "{Boot}Cygnus:src:".
+
+* Requirements for Building
+
+In addition to the sources, you will need a set of tools that the
+configure and build scripts assume to be available. These tools
+(and their versions, if relevant) are as follows:
+
+ byacc tool
+ flex (2.3.7) tool (and Flex.skel file)
+ forward-include script
+ MoveIfChange script
+ mpw-touch script
+ mpw-true script
+ NewFolderRecursive script
+ null-command script
+ open-brace script
+ sed (1.13) tool
+ tr-7to8 script
+ true script
+
+The scripts are in the sources, under utils:mpw:. You must arrange to
+get the other tools yourself (they are readily available from the
+"usual" net sites, and are also on many CDROMS). In addition, there
+will usually be a set of these available at ftp.cygnus.com, in pub/mac.
+
+You may put the build tools in your usual Tools or Scripts
+directories, or keep them in a separate directories. We prefer to
+make a directory called "buildtools" and we put this in one of our
+UserStartup files:
+
+ set Commands "{Boot}Cygnus:buildtools:,{Commands}"
+
+Flex uses an environment variable FLEX_SKELETON to locate its skeleton
+file, so you need to do something like this, preferably in a UserStartup:
+
+ Set FLEX_SKELETON "{Boot}"Cygnus:buildtools:Flex.skel
+ Export FLEX_SKELETON
+
+* Configuring
+
+Before you can build anything, you must configure. You do this by
+creating an directory where object files will be stored, setdirectory
+to that directory and do a configure command:
+
+ {Boot}Cygnus:src:mpw-configure --target <name> --cc <compiler> --srcdir {Boot}Cygnus:src: --prefix <whatever>
+
+If the source directory is not in your {Commands} list, then you must
+supply a full pathname to mpw-configure, since mpw-configure invokes
+itself after switching into each subdirectory. Using a relative
+pathname, even something like ':mpw-configure', will therefore not work.
+
+<name> must be a known target. Valid ones include "m68k-apple-macos",
+"powerpc-apple-macos", "i386-unknown-go32", "mips-idt-ecoff", and
+"sh-hitachi-hms". Not all target types are accepted for all of the
+tools yet.
+
+<compiler> must be the name of the compiler to use. It defaults to "mpwc".
+
+ (m68k)
+ mpwc MPW C
+ sc68k Symantec C
+ mwc68k Metrowerks C (Codewarrior)
+ gcc68k GCC
+
+ (powerpc)
+ ppcc PPCC
+ mrc Macintosh on RisC (Mister C, aka(?) Frankenstein)
+ scppc Symantec C
+ mwcppc Metrowerks C (Codewarrior)
+ gccppc GCC
+
+Not all compilers will compile all tools equally well! For m68k Macs,
+MPW C has the best record so far (it has problems, but they can be
+worked around), while for PowerMacs, CodeWarrior is the only compiler
+that has successfully compiled everything into running code.
+
+<prefix> is the path that "gcc" will prepend when looking for tools
+to execute. GCC_EXEC_PREFIX overrides this value, so you need not
+include it if you plan to use GCC_EXEC_PREFIX.
+
+As an example, here is the configure line that you could use to build
+native PowerMac GCC:
+
+"{Boot}"Cygnus:src:mpw-configure --cc mwcppc --target powerpc-apple-macos --srcdir "{Boot}"Cygnus:src: --prefix "{Boot}"GNUTools:
+
+* Building
+
+If you use CodeWarrior, you *must* first set MWCIncludes to
+{CIncludes}. This is because you will be building MPW tools, and
+their standard I/O works by making references to data that is part of
+the MPW Shell, which means that the code must be compiled and linked
+with macros that refer to that data, and those macros are in
+{CIncludes}, not the default {MWCIncludes}. Without this change, you
+will encounter problems compiling libiberty/mpw.c, but tweaking that
+file only masks the real problem, and does not fix it.
+
+The command
+
+ mpw-build
+
+will build everything. Building will take over an hour on a Quadra 800
+or PowerMac 8100/110, longer if the sources are on a shared volume.
+
+You may see some warnings; these are mostly likely benign, typically
+disagreements about declarations of library and system functions.
+
+* Installing
+
+To install the just-built tools, use the command
+
+ mpw-build install
+
+This part of the installation procedure just copies files to the
+location specified at configure time by <prefix>, and, in some cases,
+renames them from temporary internal names to their usual names. This
+install process is *not* the same as what the Install script does;
+Install can copy tools from the installation location chosen at
+configuration time to a user-chosen place, and sets up a UserStartup
+file. Note that while the Install script is optional, the install
+build action performs some tasks would be very hard to replicate
+manually, so you should always do it before using the tools.
+
+* Known Problems With Using Various Compilers to Build
+
+Most versions of MPW C have problems with compiling GNU software.
+
+MPW C 3.2.x has preprocessing bugs that render it incapable of
+compiling the BFD library, so it can't be used at all for building BFD.
+
+MPW C 3.3, 3.3.1, and 3.3.2 will spontaneously claim to have found
+errors in the source code, but in fact the code is perfectly fine. If
+this happens, just set the working directory back to the top-level
+objdir (where the configure command above was performed), and type
+"mpw-build all" again. If it goes on through the supposed error, then
+you got one of the spurious errors. A full build may require a number
+of these restarts.
+
+MPW C 3.3.3 seems to work OK, at least with the aid of a number of
+workarounds that are in the sources (look for #ifdef MPW_C).
+
+Versions of MPW Make earlier than 4.0d2 have exhibited bizarre behavior,
+failure to substitute variables and the like.
+
+Metrowerks CW6 PPC linker (MWLinkPPC) seems to do bad things with memory
+if the "Modern Memory Manager" is turned on (in the Memory control panel),
+but works OK if it is turned off.
+
+Metrowerks CW6 loses bigtime compiling opcodes:ppc-opc.c, which has
+some deeply nested macros. (CW7 is OK.) There is a way to patch the
+file, by substituting constant values. If you need to do this,
+contact shebs@cygnus.com for details.
+
+<Gestalt.h> is missing from {CIncludes} in the MPW version that comes
+with CW7. You can just copy the one in CW7's {MWCIncludes}.
+
+CW8 and later have changes to headers and such that will require changes
+to the source in order to be able to use them to rebuild.
+
+KNOWN BUGS
+
+The declarations for memcpy and memcmp in some versions of header files
+may conflict with GCC's builtin definition. Either use -fno-builtin
+or ignore the warnings.
+
+This is not a bug, but - watch out for cr/nl translation! For instance,
+if config/mpw-mh-mpw is not properly translated because it has been
+copied or updated separately, then everything will almost build, but
+you will get puzzling error messages from make or the compiler.
+
+'/' or ' ' embedded in any device, directory, or file name may or may
+not work.
+
+objcopy -O srec foo.o makes random output filenames.
+
+Mac-x-mips requires -mgas but Unix hosts don't.
+
+GDB will frequently require a '/' on the front of a device name in order
+to recognize it as an absolute rather than a relative pathname.
+
+GDB doesn't seem to use the printer port correctly, although it tries.
+
+The cursor doesn't always spin as much as it should. To get elaborate
+statistics and warnings about spin rates, add this to UserStartup:
+
+ set MEASURE_SPIN all
+ export MEASURE_SPIN
diff --git a/mpw-build.in b/mpw-build.in
new file mode 100644
index 00000000000..86d9530fa3b
--- /dev/null
+++ b/mpw-build.in
@@ -0,0 +1,204 @@
+# Top-level script fragment to build everything for MPW.
+
+Set savedir "`Directory`"
+
+#Set Echo 1
+
+Set ThisScript "{0}"
+
+Set objdir ":"
+
+Set verify 0
+
+Set BuildTarget "none"
+
+# Parse arguments.
+
+Loop
+ Break If {#} == 0
+ If "{BuildTarget}" =~ /none/
+ Set BuildTarget "{1}"
+ Else
+ Echo Only one build target allowed, ignoring "{1}"
+ End If
+ Shift 1
+End Loop
+
+If "{BuildTarget}" =~ /none/
+ Set BuildTarget "all"
+End If
+
+If {verify} == 1
+ Echo "#" Doing "{ThisScript}" "{BuildTarget}" in "`Directory`" ...
+End If
+
+Set ranmake 0
+
+If "`Exists Makefile`" != ""
+ Echo "Set Echo 1" >{BuildTarget}.makeout
+ Make -f Makefile {BuildTarget} >>{BuildTarget}.makeout
+ {BuildTarget}.makeout
+ Delete {BuildTarget}.makeout
+ Set ranmake 1
+End If
+
+If "`Exists Makefile.PPC`" != ""
+ Echo "Set Echo 1" >{BuildTarget}.makeout.ppc
+ Make -f Makefile.PPC {BuildTarget} >>{BuildTarget}.makeout.ppc
+ {BuildTarget}.makeout.ppc
+ Delete {BuildTarget}.makeout.ppc
+ Set ranmake 1
+End If
+
+If {ranmake} == 1
+ Exit
+End If
+
+# Dispatch on various pseudo-targets.
+
+If "{BuildTarget}" =~ /all/
+ Echo Started `Date`
+ "{ThisScript}" all-gcc
+ "{ThisScript}" all-gdb
+ Echo Finished `Date`
+Else If "{BuildTarget}" =~ /all-libiberty/
+ "{ThisScript}" do-libiberty
+Else If "{BuildTarget}" =~ /all-bfd/
+ "{ThisScript}" do-bfd
+Else If "{BuildTarget}" =~ /all-opcodes/
+ "{ThisScript}" do-opcodes
+Else If "{BuildTarget}" =~ /all-byacc/
+ "{ThisScript}" do-byacc
+Else If "{BuildTarget}" =~ /all-flex/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" do-flex
+Else If "{BuildTarget}" =~ /all-binutils/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" all-bfd
+ "{ThisScript}" all-opcodes
+ "{ThisScript}" do-binutils
+Else If "{BuildTarget}" =~ /all-gas/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" all-bfd
+ "{ThisScript}" all-opcodes
+ "{ThisScript}" do-gas
+Else If "{BuildTarget}" =~ /all-gcc/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" all-gas
+ "{ThisScript}" all-binutils
+ "{ThisScript}" all-ld
+ "{ThisScript}" do-gcc
+Else If "{BuildTarget}" =~ /all-gdb/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" all-bfd
+ "{ThisScript}" all-opcodes
+ "{ThisScript}" do-gdb
+Else If "{BuildTarget}" =~ /all-grez/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" all-bfd
+ "{ThisScript}" do-grez
+Else If "{BuildTarget}" =~ /all-ld/
+ "{ThisScript}" all-libiberty
+ "{ThisScript}" all-bfd
+ "{ThisScript}" all-opcodes
+ "{ThisScript}" do-ld
+Else If "{BuildTarget}" =~ /do-byacc/
+ SetDirectory :byacc:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-flex/
+ SetDirectory :flex:
+ ::mpw-build _bootstrap
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-bfd/
+ SetDirectory :bfd:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-libiberty/
+ SetDirectory :libiberty:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-opcodes/
+ SetDirectory :opcodes:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-binutils/
+ SetDirectory :binutils:
+ ::mpw-build stamps
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-gas/
+ SetDirectory :gas:
+ ::mpw-build stamps
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-gcc/
+ SetDirectory :gcc:
+ :mpw-build all
+Else If "{BuildTarget}" =~ /do-gdb/
+ SetDirectory :gdb:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-grez/
+ SetDirectory :grez:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-ld/
+ SetDirectory :ld:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /do-newlib/
+ SetDirectory :newlib:
+ ::mpw-build all
+Else If "{BuildTarget}" =~ /install/
+ "{ThisScript}" install-only-top
+ "{ThisScript}" install-binutils
+ "{ThisScript}" install-gas
+ "{ThisScript}" install-gcc
+ "{ThisScript}" install-ld
+ "{ThisScript}" install-gdb
+Else If "{BuildTarget}" =~ /install-binutils/
+ SetDirectory :binutils:
+ ::mpw-build install
+Else If "{BuildTarget}" =~ /install-gas/
+ SetDirectory :gas:
+ ::mpw-build install
+Else If "{BuildTarget}" =~ /install-gcc/
+ SetDirectory :gcc:
+ :mpw-build install
+Else If "{BuildTarget}" =~ /install-gdb/
+ SetDirectory :gdb:
+ ::mpw-build install
+Else If "{BuildTarget}" =~ /install-grez/
+ SetDirectory :grez:
+ ::mpw-build install
+Else If "{BuildTarget}" =~ /install-ld/
+ SetDirectory :ld:
+ ::mpw-build install
+Else If "{BuildTarget}" =~ /install-only/
+ "{ThisScript}" install-only-top
+ "{ThisScript}" install-only-binutils
+ "{ThisScript}" install-only-gas
+ "{ThisScript}" install-only-gcc
+ "{ThisScript}" install-only-gdb
+ "{ThisScript}" install-only-ld
+Else If "{BuildTarget}" =~ /install-only-binutils/
+ SetDirectory :binutils:
+ ::mpw-build install-only
+Else If "{BuildTarget}" =~ /install-only-gas/
+ SetDirectory :gas:
+ ::mpw-build install-only
+Else If "{BuildTarget}" =~ /install-only-gcc/
+ SetDirectory :gcc:
+ :mpw-build install-only
+Else If "{BuildTarget}" =~ /install-only-gdb/
+ SetDirectory :gdb:
+ ::mpw-build install-only
+Else If "{BuildTarget}" =~ /install-only-grez/
+ SetDirectory :grez:
+ ::mpw-build install-only
+Else If "{BuildTarget}" =~ /install-only-ld/
+ SetDirectory :ld:
+ ::mpw-build install-only
+Else If "{BuildTarget}" =~ /install-only-top/
+ NewFolderRecursive "{prefix}"
+ If "{prefix}" != "`Directory`"
+ Duplicate -y 'Read Me for MPW' "{prefix}"'Read Me for MPW'
+ Duplicate -y Install "{prefix}"Install
+ End If
+Else
+ Echo {BuildTarget} not understood, ignoring
+End If
+
+SetDirectory "{savedir}"
diff --git a/mpw-config.in b/mpw-config.in
new file mode 100644
index 00000000000..8028737a8b6
--- /dev/null
+++ b/mpw-config.in
@@ -0,0 +1,113 @@
+# Configuration fragment for Cygnus source tree.
+
+# Check that we can find all the special tools that we will need.
+# The test for sed is semi-pointless, because it's already been invoked
+# by the calculation of target_cpu in the main configure script, but
+# the test will also show which one is being used.
+
+Set Exit 0
+Echo byacc is `Which byacc`
+Echo flex is `Which flex`
+Echo forward-include is `Which forward-include`
+Echo MoveIfChange is `Which MoveIfChange`
+Echo mpw-touch is `Which mpw-touch`
+Echo mpw-true is `Which mpw-true`
+Echo NewFolderRecursive is `Which NewFolderRecursive`
+Echo null-command is `Which null-command`
+Echo open-brace is `Which open-brace`
+Echo sed is `Which sed`
+Echo 'tr-7to8' is `Which tr-7to8`
+Echo true is `Which true`
+Set Exit 1
+
+Set host_libs "mmalloc libiberty opcodes bfd readline gash tcl tk tclX"
+
+Set host_tools "texinfo byacc flex bison binutils ld gas gcc gdb make patch \Option-d
+ prms send-pr gprof gdbtest tgas etc expect dejagnu sim bash \Option-d
+ m4 autoconf ispell grep diff rcs cvs fileutils shellutils time \Option-d
+ textutils wdiff find emacs emacs19 uudecode hello tar gzip indent \Option-d
+ recode release sed utils guile perl apache inet gawk"
+
+Set target_libs "newlib"
+
+Set target_tools "examples"
+
+# Configure the resource compiler if targeting Macs.
+If {target_os} =~ /macos/ || {target_os} =~ /mpw/
+ Set host_tools "{host_tools} grez"
+End If
+
+Set configdirs "{host_libs} {host_tools} {target_libs} {target_tools}"
+Export configdirs
+
+# Make up a special include directory that tools will share.
+
+If "`Exists "{objdir}"extra-include`" == ""
+ NewFolder "{objdir}"extra-include
+End If
+
+Set edir "{objdir}extra-include:"
+
+forward-include "{srcdir}"include:mpw:sys:file.h "{edir}"'sys/file.h'
+forward-include "{srcdir}"include:mpw:sys:ioctl.h "{edir}"'sys/ioctl.h'
+forward-include "{srcdir}"include:mpw:sys:param.h "{edir}"'sys/param.h'
+forward-include "{srcdir}"include:mpw:sys:resource.h "{edir}"'sys/resource.h'
+forward-include "{srcdir}"include:mpw:sys:stat.h "{edir}"'sys/stat.h'
+forward-include "{srcdir}"include:mpw:sys:time.h "{edir}"'sys/time.h'
+forward-include "{srcdir}"include:mpw:sys:types.h "{edir}"'sys/types.h'
+
+forward-include "{srcroot}"include:aout:aout64.h "{edir}"'aout/aout64.h'
+forward-include "{srcroot}"include:aout:ar.h "{edir}"'aout/ar.h'
+forward-include "{srcroot}"include:aout:ranlib.h "{edir}"'aout/ranlib.h'
+forward-include "{srcroot}"include:aout:reloc.h "{edir}"'aout/reloc.h'
+forward-include "{srcroot}"include:aout:stab.def "{edir}"'aout/stab.def'
+forward-include "{srcroot}"include:aout:stab_gnu.h "{edir}"'aout/stab_gnu.h'
+
+If "`Exists "{srcroot}"include:aout:"{target_cpu}".h`" != ""
+ forward-include "{srcroot}"include:aout:"{target_cpu}".h "{edir}"'aout/'"{target_cpu}"'.h'
+End If
+
+forward-include "{srcroot}"include:coff:ecoff.h "{edir}"'coff/ecoff.h'
+forward-include "{srcroot}"include:coff:internal.h "{edir}"'coff/internal.h'
+forward-include "{srcroot}"include:coff:sym.h "{edir}"'coff/sym.h'
+forward-include "{srcroot}"include:coff:symconst.h "{edir}"'coff/symconst.h'
+
+If "`Exists "{srcroot}"include:coff:"{target_cpu}".h`" != ""
+ forward-include "{srcroot}"include:coff:"{target_cpu}".h "{edir}"'coff/'"{target_cpu}"'.h'
+End If
+If "{target_cpu}" =~ /powerpc/
+ forward-include "{srcroot}"include:coff:rs6000.h "{edir}"'coff/rs6000.h'
+End If
+
+forward-include "{srcroot}"include:elf:common.h "{edir}"'elf/common.h'
+forward-include "{srcroot}"include:elf:dwarf.h "{edir}"'elf/dwarf.h'
+forward-include "{srcroot}"include:elf:dwarf2.h "{edir}"'elf/dwarf2.h'
+forward-include "{srcroot}"include:elf:external.h "{edir}"'elf/external.h'
+forward-include "{srcroot}"include:elf:internal.h "{edir}"'elf/internal.h'
+
+# Believe it or not, GDB needs this for all targets.
+forward-include "{srcroot}"include:elf:mips.h "{edir}"'elf/mips.h'
+
+If "`Exists "{srcroot}"include:elf:"{target_cpu}".h`" != ""
+ forward-include "{srcroot}"include:elf:"{target_cpu}".h "{edir}"'elf/'"{target_cpu}"'.h'
+End If
+If "{target_cpu}" =~ /powerpc/
+ forward-include "{srcroot}"include:elf:ppc.h "{edir}"'elf/ppc.h'
+End If
+
+If "`Exists "{srcroot}"include:opcode:"{target_cpu}".h`" != ""
+ forward-include "{srcroot}"include:opcode:"{target_cpu}".h "{edir}"'opcode/'"{target_cpu}"'.h'
+End If
+If "{target_cpu}" =~ /powerpc/
+ forward-include "{srcroot}"include:opcode:ppc.h "{edir}"'opcode/ppc.h'
+End If
+
+# Add some bfd includes that get mentioned outside the bfd dir.
+
+forward-include "{srcroot}"bfd:libcoff.h "{edir}"'bfd/libcoff.h'
+forward-include "{srcroot}"bfd:libecoff.h "{edir}"'bfd/libecoff.h'
+
+# Translate random files into MPW-only character set.
+
+tr-7to8 "{srcdir}"mpw-README > "{objdir}Read Me for MPW"
+tr-7to8 "{srcdir}"mpw-install > "{objdir}"Install
diff --git a/mpw-configure b/mpw-configure
new file mode 100644
index 00000000000..cf45148ec63
--- /dev/null
+++ b/mpw-configure
@@ -0,0 +1,448 @@
+# Configuration script
+# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+### WARNING
+### This script must NOT use any 8-bit chars!
+### WARNING
+
+# This is an MPW Shell script that sets everything up for compilation,
+# mainly creating directories, and editing copies of files.
+
+Set savedir "`Directory`"
+
+#Set Echo 1
+
+Set ThisScript "{0}"
+
+Set srcroot "--------"
+
+Set srcdir ":"
+
+Set objdir ":"
+
+Set prefix "{MPW}":GNUTools:
+
+Set exec_prefix ""
+
+Set bindir ""
+
+Set host_alias "m68k-apple-mpw"
+
+Set target_alias {host_alias}
+
+Set host_cc "mpwc"
+
+Set with_gnu_ld 0
+
+Set helpoutput 0
+
+Set recurse 1
+
+Set verify 0
+Set verifystr ""
+
+Set enable_options ""
+Set disable_options ""
+
+# Parse arguments.
+
+Loop
+ Break If {#} == 0
+ If "{1}" =~ /--cc/
+ Set host_cc "{2}"
+ Shift 1
+ Else If "{1}" =~ /--bindir/
+ Set bindir "{2}"
+ Shift 1
+ Else If "{1}" =~ /--disable-?+/
+ Set `Echo {1} | sed -e 's/--disable-/enable_/'` no
+ Set disable_options "{disable_options} '{1}'"
+ Else If "{1}" =~ /--enable-?+/
+ Set `Echo {1} | sed -e 's/--enable-/enable_/'` yes
+ Set enable_options "{enable_options} '{1}'"
+ Else If "{1}" =~ /--exec-prefix/
+ Set exec_prefix "{2}"
+ Shift 1
+ Else If "{1}" =~ /--help/
+ Set helpoutput 1
+ Else If "{1}" =~ /--host/
+ Set host_alias "{2}"
+ Shift 1
+ Else If "{1}" =~ /--norecursion/
+ Set recurse 0
+ Else If "{1}" =~ /--prefix/
+ Set prefix "{2}"
+ Shift 1
+ Else If "{1}" =~ /--srcdir/
+ Set srcdir "{2}"
+ Shift 1
+ Else If "{1}" =~ /--srcroot/
+ Set srcroot "{2}"
+ Shift 1
+ Else If "{1}" =~ /--target/
+ Set target_alias "{2}"
+ Shift 1
+ Else If "{1}" =~ /-v/
+ Set verify 1
+ Set verifystr "-v"
+ Else If "{1}" =~ /--with-gnu-ld/
+ Set with_gnu_ld 1
+ Else
+ Echo -n 'mpw-configure: Unrecognized option: "'
+ Echo -n "{1}"
+ Echo '"; use --help for usage.'
+ Exit 1
+ End If
+ Shift 1
+End Loop
+
+If {helpoutput} == 1
+ Echo "Usage: mpw-configure [OPTIONS]"
+ Echo ""
+ Echo "Options: [defaults in brackets]"
+ Echo "--bindir DIR directory for binaries []"
+ Echo "--cc CC use C compiler CC [mpwc]"
+ Echo "--disable-FOO do not include feature FOO"
+ Echo "--enable-FOO include feature FOO"
+ Echo "--exec-prefix DIR install host-dependent files into DIR []"
+ Echo "--help print this message"
+ Echo "--host HOST configure for HOST [m68k-apple-mpw]"
+ Echo "--norecursion configure this directory only [recurse]"
+ Echo "--prefix DIR install into DIR [{MPW}:GNUTools:]"
+ Echo "--srcdir DIR find the sources in DIR [:]"
+ Echo "--srcroot DIR find the toplevel sources in DIR [:]"
+ Echo "--target TARGET configure for TARGET [TARGET=HOST]"
+ Echo "-v verbose"
+ Echo "--with-gnu-ld link using GNU ld [no]"
+ Exit 0
+End If
+
+Set Exit 0
+
+# Default exec_prefix from prefix.
+
+If "{exec_prefix}" == ""
+ Set exec_prefix "{prefix}"
+End If
+
+If "{bindir}" == ""
+ Set bindir "{prefix}"bin:
+End If
+
+# Point to the correct set of tools to use with the chosen compiler.
+
+If "{host_cc}" =~ /mpwc/
+ Set host_alias "m68k-apple-mpw"
+ Set cc_name '{CC_MPW_C}'
+ Set segment_flag '-s '
+ Set ar_name '{AR_LIB}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_LINK}'
+ Set prog_ext_name '{PROG_EXT_68K}'
+ Set extralibs_name '{EXTRALIBS_C}'
+ Set makepef_name '{MAKEPEF_NULL}'
+ Set rez_name '{REZ_68K}'
+Else If "{host_cc}" =~ /sc68k/
+ Set host_alias "m68k-apple-mpw"
+ Set cc_name '{CC_SC}'
+ Set segment_flag '-s '
+ Set ar_name '{AR_LIB}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_LINK}'
+ Set prog_ext_name '{PROG_EXT_68K}'
+ Set extralibs_name '{EXTRALIBS_C}'
+ Set makepef_name '{MAKEPEF_NULL}'
+ Set rez_name '{REZ_68K}'
+Else If "{host_cc}" =~ /mwc68k/
+ Set host_alias "m68k-apple-mpw"
+ Set cc_name '{CC_MWC68K}'
+ Set segment_flag '-s '
+ Set ar_name '{AR_MWLINK68K}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_MWLINK68K}'
+ Set prog_ext_name '{PROG_EXT_68K}'
+ Set extralibs_name '{EXTRALIBS_MWC68K}'
+ Set makepef_name '{MAKEPEF_NULL}'
+ Set rez_name '{REZ_68K}'
+Else If "{host_cc}" =~ /gcc68k/
+ Set host_alias "m68k-apple-mpw"
+ Set cc_name '{CC_68K_GCC}'
+ Set segment_flag '-s '
+ Set ar_name '{AR_68K_AR}'
+ Set ranlib_name '{RANLIB_RANLIB}'
+ Set cc_ld_name '{CC_68K_GCC}'
+ Set prog_ext_name '{PROG_EXT_68K}'
+ Set extralibs_name '{EXTRALIBS_C}'
+ Set makepef_name '{MAKEPEF_NULL}'
+ Set rez_name '{REZ_68K}'
+Else If "{host_cc}" =~ /ppcc/
+ Set host_alias "powerpc-apple-mpw"
+ Set cc_name '{CC_PPCC}'
+ Set segment_flag '-d ___s_e_g___='
+ Set ar_name '{AR_PPCLINK}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_PPCLINK}'
+ Set prog_ext_name '{PROG_EXT_XCOFF}'
+ Set extralibs_name '{EXTRALIBS_PPC}'
+ Set makepef_name '{MAKEPEF_PPC}'
+ Set rez_name '{REZ_PPC}'
+Else If "{host_cc}" =~ /mrc/
+ Set host_alias "powerpc-apple-mpw"
+ Set cc_name '{CC_MRC}'
+ Set segment_flag '-d ___s_e_g___='
+ Set ar_name '{AR_PPCLINK}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_PPCLINK}'
+ Set prog_ext_name '{PROG_EXT_XCOFF}'
+ Set extralibs_name '{EXTRALIBS_PPC}'
+ Set makepef_name '{MAKEPEF_PPC}'
+ Set rez_name '{REZ_PPC}'
+Else If "{host_cc}" =~ /scppc/
+ Set host_alias "powerpc-apple-mpw"
+ Set cc_name '{CC_SC}'
+ Set segment_flag '-d ___s_e_g___='
+ Set ar_name '{AR_PPCLINK}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_PPCLINK}'
+ Set prog_ext_name '{PROG_EXT_XCOFF}'
+ Set extralibs_name '{EXTRALIBS_PPC}'
+ Set makepef_name '{MAKEPEF_PPC}'
+ Set rez_name '{REZ_PPC}'
+Else If "{host_cc}" =~ /mwcppc/
+ Set host_alias "powerpc-apple-mpw"
+ Set cc_name '{CC_MWCPPC}'
+ Set segment_flag '-d ___s_e_g___='
+ Set ar_name '{AR_MWLINKPPC}'
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_MWLINKPPC}'
+ # Misleading, but we don't need a PEF step.
+ Set prog_ext_name '{PROG_EXT_68K}'
+ Set extralibs_name '{EXTRALIBS_MWCPPC}'
+ Set makepef_name '{MAKEPEF_NULL}'
+ Set rez_name '{REZ_PPC}'
+Else If "{host_cc}" =~ /gccppc/
+ Set host_alias "powerpc-apple-mpw"
+ Set cc_name '{CC_PPC_GCC}'
+ Set segment_flag '-d ___s_e_g___='
+ Set ar_name '{AR_PPCLINK}'
+ If {with_gnu_ld} == 1
+ Set ranlib_name '{RANLIB_RANLIB}'
+ Set cc_ld_name '{CC_LD_GLD}'
+ Else
+ Set ranlib_name '{RANLIB_NULL}'
+ Set cc_ld_name '{CC_LD_PPCLINK}'
+ End If
+ Set prog_ext_name '{PROG_EXT_XCOFF}'
+ Set extralibs_name '{EXTRALIBS_PPC}'
+ Set makepef_name '{MAKEPEF_PPC}'
+ Set rez_name '{REZ_PPC}'
+Else
+ Echo "{host_cc}" is not a known MPW compiler type
+End If
+
+Set dash_c_flag ''
+If "{host_cc}" =~ /gcc68k/
+ Set dash_c_flag '-c'
+Else If "{host_cc}" =~ /gccppc/
+ Set dash_c_flag '-c'
+End If
+
+# (should interpret aliases if not in canonical form)
+
+Set host_canonical "{host_alias}"
+
+Set target_canonical "{target_alias}"
+
+Set configdirs ""
+
+If "{srcroot}" =~ /--------/
+ Set srcroot "{srcdir}"
+End If
+If "`Exists "{srcdir}"`" == ""
+ Echo Source directory {srcdir} does not exist!
+ Exit 1
+End If
+If "`Exists "{srcroot}"`" == ""
+ Echo Top-level source directory {srcroot} does not exist!
+ Exit 1
+End If
+
+Set target_cpu "`echo {target_canonical} | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`"
+Set target_vendor "`echo {target_canonical} | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`"
+Set target_os "`echo {target_canonical} | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`"
+
+# Create a file that is guaranteed to be older than any other here.
+
+If "`Exists "{objdir}"_oldest`" == ""
+ mpw-touch _oldest
+End If
+
+# Record this before creating any files, makefiles sometimes mention
+# dependencies on config.status.
+
+Echo "# This directory was configured as follows:" >config.new
+Echo "{ThisScript} --host {host_alias} --target {target_alias} --srcdir {srcdir} --srcroot {srcroot} --prefix {prefix} --cc {host_cc} {verifystr} {enable_options} {disable_options} --norecursion" >>config.new
+MoveIfChange config.new config.status
+
+If "`Exists "{srcdir}"mpw-config.in`" != ""
+ tr-7to8 "{srcdir}"mpw-config.in >"{objdir}"mpw-config.in
+ Execute "{objdir}"mpw-config.in
+End If
+
+# Start Makefile construction by defining all the variables chosen by
+# configuration.
+
+Echo "# This Makefile produced by mpw-configure. Changes may get lost!" > "{objdir}"Makefile.tem
+Echo "srcroot = " {srcroot} >> "{objdir}"Makefile.tem
+Echo "topsrcdir = " {srcroot} >> "{objdir}"Makefile.tem
+Echo "srcdir = " {srcdir} >> "{objdir}"Makefile.tem
+Echo "mpw_prefix = " {prefix} >> "{objdir}"Makefile.tem
+Echo "mpw_exec_prefix = " {exec_prefix} >> "{objdir}"Makefile.tem
+Echo "mpw_bindir = " {bindir} >> "{objdir}"Makefile.tem
+Echo "host_alias = " {host_alias} >> "{objdir}"Makefile.tem
+Echo "target_alias = " {target_alias} >> "{objdir}"Makefile.tem
+Echo "target_cpu = " {target_cpu} >> "{objdir}"Makefile.tem
+Echo "target_vendor = " {target_vendor} >> "{objdir}"Makefile.tem
+Echo "target_os = " {target_os} >> "{objdir}"Makefile.tem
+Echo "target_canonical = " {target_canonical} >> "{objdir}"Makefile.tem
+Echo "host_makefile_frag = " >> "{objdir}"Makefile.tem
+Echo "target_makefile_frag = " >> "{objdir}"Makefile.tem
+Echo "CC = " {cc_name} >> "{objdir}"Makefile.tem
+Echo "AR = " {ar_name} >> "{objdir}"Makefile.tem
+Echo "RANLIB = " {ranlib_name} >> "{objdir}"Makefile.tem
+Echo "CC_LD = " {cc_ld_name} >> "{objdir}"Makefile.tem
+Echo "PROG_EXT = " {prog_ext_name} >> "{objdir}"Makefile.tem
+Echo "EXTRALIBS = " {extralibs_name} >> "{objdir}"Makefile.tem
+Echo "MAKEPEF = " {makepef_name} >> "{objdir}"Makefile.tem
+Echo "REZ = " {rez_name} >> "{objdir}"Makefile.tem
+
+If {host_cc} =~ /gccppc/
+ Echo -n "dq =\Option-d\Option-d\Option-d" > "{objdir}"Makefile.tem0
+ Echo '"' >> "{objdir}"Makefile.tem0
+ tr-7to8 "{objdir}"Makefile.tem0 >>"{objdir}"Makefile.tem
+Else
+ Echo -n "dq ='" >> "{objdir}"Makefile.tem
+ Echo -n '"' >> "{objdir}"Makefile.tem
+ Echo "'" >> "{objdir}"Makefile.tem
+End If
+
+# Append the master set of definitions for the various compilers.
+
+If "`Exists "{srcdir}"config:mpw-mh-mpw`" != ""
+ tr-7to8 "{srcdir}"config:mpw-mh-mpw >>"{objdir}"Makefile.tem
+Else If "`Exists "{srcroot}"config:mpw-mh-mpw`" != ""
+ tr-7to8 "{srcroot}"config:mpw-mh-mpw >>"{objdir}"Makefile.tem
+Else
+ Echo "can't find a host config file!"
+ Exit 0
+End If
+
+# Append anything produced by the directory's mpw-config.in.
+
+If "`Exists "{objdir}"mk.tmp`" != ""
+ Catenate "{objdir}"mk.tmp >>"{objdir}"Makefile.tem
+ # An mpw-config.in might change so as not to create this
+ # anymore, so get rid of it now to be safe.
+ Delete -i -y "{objdir}"mk.tmp
+End If
+
+# If there are sed scripts to edit the Unix Makefile.in, use them; otherwise
+# use an mpw-make.in if present.
+
+If "`Exists "{srcdir}"mpw-make.sed`" != ""
+ If "`Exists "{objdir}"hacked_Makefile.in`" != ""
+ Set MakefileIn "{objdir}"hacked_Makefile.in
+ Else
+ Set MakefileIn "{srcdir}"Makefile.in
+ End If
+ # Find the generic makefile editing script.
+ If "`Exists "{srcroot}"config:mpw:g-mpw-make.sed`" != ""
+ sed -f "{srcroot}"config:mpw:g-mpw-make.sed "{MakefileIn}" >"{objdir}"Makefile.tem1
+ Else If "`Exists "{srcroot}"utils:mpw:g-mpw-make.sed`" != ""
+ sed -f "{srcroot}"utils:mpw:g-mpw-make.sed "{MakefileIn}" >"{objdir}"Makefile.tem1
+ Else If "`Exists "{srcdir}"g-mpw-make.sed`" != ""
+ sed -f "{srcdir}"g-mpw-make.sed "{MakefileIn}" >"{objdir}"Makefile.tem1
+ Else
+ Echo Warning: g-mpw-make.sed not found, copying "{MakefileIn}" verbatim...
+ Catenate "{MakefileIn}" >"{objdir}"Makefile.tem1
+ End If
+ sed -f "{srcdir}"mpw-make.sed "{objdir}"Makefile.tem1 >"{objdir}"Makefile.tem2
+ sed -e 's/^prefix = .*$/prefix = {mpw_prefix}/g' -e 's/^exec_prefix = .*$/exec_prefix = {mpw_exec_prefix}/g' -e 's/^bindir = @bindir@/bindir = {mpw_bindir}/g' "{objdir}"Makefile.tem2 >"{objdir}"Makefile.tem3
+ sed -e "s/@DASH_C_FLAG@/{dash_c_flag}/" -e "s/@SEGMENT_FLAG(\([^)]*\))@/{segment_flag}\1/" "{objdir}"Makefile.tem3 >"{objdir}"mpw-make.in
+ tr-7to8 "{objdir}"mpw-make.in >>"{objdir}"Makefile.tem
+ If "`Exists "{objdir}"mk.sed`" != ""
+ sed -f "{objdir}"mk.sed "{objdir}"Makefile.tem >"{objdir}"Makefile.tem2
+ Rename -y "{objdir}"Makefile.tem2 "{objdir}"Makefile.tem
+ End If
+ MoveIfChange "{objdir}"Makefile.tem "{objdir}"Makefile
+ Delete -i -y "{objdir}"Makefile.tem[12]
+ If {verify} == 1
+ Echo Created Makefile in "`Directory`"
+ End If
+Else If "`Exists "{srcdir}"mpw-make.in`" != ""
+ sed -e 's/^prefix = .*$/prefix = {mpw_prefix}/g' "{srcdir}"mpw-make.in >"{objdir}"Makefile.tem1
+ sed -e "s/@DASH_C_FLAG@/{dash_c_flag}/" -e "s/@SEGMENT_FLAG(\([^)]*\))@/{segment_flag}}\1/" "{objdir}"Makefile.tem1 >"{objdir}"Makefile.tem2
+ tr-7to8 "{objdir}"Makefile.tem2 >>"{objdir}"Makefile.tem
+ If "`Exists "{objdir}"mk.sed`" != ""
+ sed -f "{objdir}"mk.sed "{objdir}"Makefile.tem >"{objdir}"Makefile.tem2
+ Rename -y "{objdir}"Makefile.tem2 "{objdir}"Makefile.tem
+ End If
+ MoveIfChange "{objdir}"Makefile.tem "{objdir}"Makefile
+ Delete -i -y "{objdir}"Makefile.tem[12]
+ If {verify} == 1
+ Echo Created Makefile in "`Directory`"
+ End If
+End If
+
+# Produce a build script if the source is defined.
+
+If "`Exists "{srcdir}"mpw-build.in`" != ""
+ Echo "Set srcroot " {srcroot} > "{objdir}"mpw-build.tem
+ Echo "Set srcdir " {srcdir} >> "{objdir}"mpw-build.tem
+ Echo "Set target_canonical " {target_canonical} >> "{objdir}"mpw-build.tem
+ Echo "Set prefix " {prefix} >> "{objdir}"mpw-build.tem
+ tr-7to8 "{srcdir}"mpw-build.in >>"{objdir}"mpw-build.tem
+ MoveIfChange "{objdir}"mpw-build.tem "{objdir}"mpw-build
+ If {verify} == 1
+ Echo Created mpw-build in "`Directory`"
+ End If
+End If
+
+# Apply ourselves recursively to the list of subdirectories to configure.
+
+If {recurse} == 1
+ For subdir In {configdirs}
+ Set savedir "`Directory`"
+ If "`Exists "{srcdir}{subdir}:"`" == ""
+ If {verify} == 1
+ Echo No "{srcdir}{subdir}:" found, skipping
+ End If
+ Continue
+ End If
+ If {verify} == 1
+ Echo Configuring {subdir}...
+ End If
+ If "`Exists "{objdir}{subdir}:"`" == ""
+ NewFolder "{objdir}{subdir}"
+ End If
+ SetDirectory "{objdir}{subdir}:"
+ "{ThisScript}" --target "{target_canonical}" --srcdir "{srcdir}{subdir}:" --srcroot "{srcroot}" --prefix "{prefix}" --cc "{host_cc}" {verifystr} {enable_options} {disable_options}
+ SetDirectory "{savedir}"
+ End For
+End If
+
+SetDirectory "{savedir}"
diff --git a/mpw-install b/mpw-install
new file mode 100644
index 00000000000..04c5aac2a4f
--- /dev/null
+++ b/mpw-install
@@ -0,0 +1,122 @@
+# GNU Install script for MPW.
+
+Set OldExit "{Exit}"
+Set Exit 0
+
+Set TempUserStartup "{TempFolder}"__temp__UserStartup
+
+Echo '# UserStartup generated by GNU Install script' > "{TempUserStartup}"
+Echo '' >> "{TempUserStartup}"
+
+# (should) Check that disk space is sufficient for installation.
+
+# Assume that the install script is where everything else is.
+
+Set thisdir "`Directory`"
+
+# Copy the binaries to the desired place.
+
+Confirm -t "Copy the binaries to somewhere else?"
+Set TmpStatus {Status}
+If {TmpStatus} == 0
+ Set bindest "`GetFileName -d -m "Where to install the binaries?"`"
+ If {Status} == 0
+ If "`Exists "{thisdir}bin"`" != ""
+ For afile In "{thisdir}"bin:\Option-x
+ Duplicate -y "{afile}" "{bindest}"
+ End For
+ Else
+ Echo "bin directory not found, exiting"
+ Exit 1
+ End If
+ Else
+ Echo "No destination supplied, exiting"
+ Exit 1
+ End If
+Else If {TmpStatus} == 4
+ # Use the existing directory.
+ Set bindest "{thisdir}bin:"
+Else
+ # Cancelled from confirmation, escape altogether.
+ Exit 1
+End If
+
+# Copy the libraries to the desired place.
+
+Confirm -t "Copy the libraries to somewhere else?"
+Set TmpStatus {Status}
+If {TmpStatus} == 0
+ Set libdest "`GetFileName -d -m "Where to install the libraries?"`"
+ If {Status} == 0
+ If "`Exists "{thisdir}lib:"`" != ""
+ For afile In "{thisdir}"lib:\Option-x
+ Duplicate -y "{afile}" "{libdest}"
+ End For
+ Else
+ Echo "lib directory not found, exiting"
+ Exit 1
+ End If
+ Else
+ Echo "No destination supplied, exiting"
+ Exit 1
+ End If
+Else If {TmpStatus} == 4
+ # Use the existing directory.
+ Set libdest "{thisdir}lib:"
+Else
+ # Cancelled from confirmation, escape altogether.
+ Exit 1
+End If
+
+
+# Add the location of the binaries to the command path.
+
+Echo -n 'Set Commands "' >> "{TempUserStartup}"
+Echo -n "{bindest}" >> "{TempUserStartup}"
+Echo ',{Commands}"' >> "{TempUserStartup}"
+Echo '' >> "{TempUserStartup}"
+
+# Set up GCC exec prefix.
+
+Set gcclibdir "{libdest}"gcc-lib:
+
+Echo -n 'Set GCC_EXEC_PREFIX "' >> "{TempUserStartup}"
+Echo -n "{gcclibdir}" >> "{TempUserStartup}"
+Echo '"' >> "{TempUserStartup}"
+Echo "Export GCC_EXEC_PREFIX" >> "{TempUserStartup}"
+Echo '' >> "{TempUserStartup}"
+
+# Set up path to libgcc.xcoff etc.
+
+Echo -n 'Set GCCPPCLibraries "' >> "{TempUserStartup}"
+Echo -n "{libdest}" >> "{TempUserStartup}"
+Echo '"' >> "{TempUserStartup}"
+Echo "Export GCCPPCLibraries" >> "{TempUserStartup}"
+Echo '' >> "{TempUserStartup}"
+
+# Display contents of UserStartup, confirm installation.
+
+Set UserStartupName "UserStartup\Option-8GNU"
+
+Echo "Contents of" {UserStartupName} "will be:"
+Catenate "{TempUserStartup}"
+
+Confirm "Install {UserStartupName} into the MPW folder {MPW} ?"
+If {Status} == 0
+ Duplicate "{TempUserStartup}" "{MPW}{UserStartupName}"
+ Delete -y "{TempUserStartup}"
+Else
+ Echo "{UserStartupName} file not installed"
+End If
+
+# (should) Check HEXA resource, warn if low.
+
+# (should) Check for spaces in pathnames, warn if found.
+
+Echo "Installation was successful."
+Echo ""
+Echo "Be sure to review the usage notes in 'Read Me for MPW' before proceeding!"
+
+# Restore previous settings.
+
+Set Exit "{OldExit}"
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
new file mode 100644
index 00000000000..0e5ea1760cb
--- /dev/null
+++ b/opcodes/ChangeLog
@@ -0,0 +1,5033 @@
+1999-04-26 Tom Tromey <tromey@cygnus.com>
+
+ * aclocal.m4, configure: Updated for new version of libtool.
+
+1999-04-22 Nick Clifton <nickc@cygnus.com>
+
+ * mcore-dis.c (print_insn_mcore): Display locaiton of address pool
+ for LRW instructions.
+
+1999-04-18 Nick Clifton <nickc@cygnus.com>
+
+ * mcore-dis.c (print_insn_mcore): Display location of address pool
+ for JMP instructions.
+ * mcore-opc.h (mcore_table): Add 'nop'.
+
+1999-04-14 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-desc.c,fr30-desc.h,fr30-dis.c,fr30-ibld.c,fr30-opc.c: Rebuild.
+ * m32r-desc.c,m32r-desc.h,m32r-dis.c,m32r-ibld.c,m32r-opc.c: Rebuild.
+
+Mon Apr 12 23:46:17 1999 Jeffrey A Law (law@cygnus.com)
+
+ * hppa-dis.c (print_insn_hppa, case '3'): New case for PA2.0
+ instructions.
+
+1999-04-10 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-desc.c,fr30-desc.h,fr30-ibld.c: Rebuild.
+ * m32r-desc.c,m32r-desc.h,m32r-opinst.c: Rebuild.
+
+1999-04-08 Nick Clifton <nickc@cygnus.com>
+
+ * mcore-dis.c: New file: Disassemble MCore opcodes.
+ * mcore-opc.h: New file: Definitions of MCore opcodes.
+ * Makefile.am: Add Mcore source files.
+ * Makefile.in: Regenerate.
+ * configure.in: Add support for MCore targets.
+ * configure: Regenerate.
+ * disassemble.c: Add support for MCore targets.
+
+1999-04-06 Ian Lance Taylor <ian@zembu.com>
+
+ * opintl.h (LC_MESSAGES): Never define.
+
+1999-04-04 Ian Lance Taylor <ian@zembu.com>
+
+ * i386-dis.c (intel_syntax, open_char, close_char): Make static.
+ (separator_char, scale_char): Likewise.
+ (print_insn_x86): Likewise.
+ (print_insn_i386): Likewise. Add declaration.
+
+1999-03-26 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-dis.c: Rebuild.
+ * m32r-dis.c: Rebuild.
+
+1999-03-23 Ian Lance Taylor <ian@zembu.com>
+
+ * m68k-opc.c: Change compare instructions to use "@s" rather than
+ ";s" when used with an immediate operand.
+
+1999-03-22 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen-opc.c (cgen_set_cpu): Delete.
+ (cgen_lookup_insn): max_insn_size renamed to max_insn_bitsize.
+ * fr30-desc.c,fr30-desc.h,fr30-dis.c,fr30-ibld.c,fr30-opc.c,fr30-opc.h:
+ Rebuild.
+ * m32r-desc.c,m32r-desc.h,m32r-dis.c,m32r-ibld.c,m32r-opc.c,m32r-opc.h:
+ Rebuild.
+ * po/opcodes.pot: Rebuild.
+
+1999-03-16 Martin Hunt <hunt@cygnus.com>
+
+ * d30v-opc.c (mvtsys): Remove FLAG_LKR.
+
+1999-03-11 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen-opc.c (cgen_set_cpu): New arg `isa'. All callers updated.
+ (cgen_operand_lookup_by_name,cgen_operand_lookup_by_num): New fns.
+ (cgen_get_insn_operands): Rewrite test for hardcoded/operand index.
+ * fr30-asm.c,fr30-desc.c,fr30-desc.h,fr30-dis.c,fr30-ibld.c: Rebuild.
+ * m32r-asm.c,m32r-desc.c,m32r-desc.h,m32r-dis.c,m32r-ibld.c: Rebuild.
+ * m32r-opinst.c: Rebuild.
+
+1999-02-25 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen-opc.c (cgen_hw_lookup_by_name): Rewrite.
+ (cgen_hw_lookup_by_num): Rewrite.
+ * fr30-desc.c,fr30-desc.h,fr30-dis.c,fr30-ibld.c,fr30-opc.c: Rebuild.
+ * m32r-desc.c,m32r-desc.h,m32r-dis.c,m32r-ibld.c,m32r-opc.c: Rebuild.
+ * m32r-opinst.c: Rebuild.
+
+Sat Feb 13 14:06:19 1999 Richard Henderson <rth@cygnus.com>
+
+ * alpha-opc.c: Add sqrt+flags patterns. Add EV6 PALcode insns.
+ (insert_jhint): Fix insertion mask.
+ * alpha-dis.c (print_insn_alpha): Disassemble EV6 PALcode insns.
+
+1999-02-10 Doug Evans <devans@casey.cygnus.com>
+
+ * Makefile.in: Rebuild.
+
+1999-02-09 Doug Evans <devans@casey.cygnus.com>
+
+ * i960c-asm.c,i960c-dis.c,i960c-opc.c,i960c-opc.h: Delete.
+ * i960-dis.c (print_insn_i960): Rename from print_insn_i960_orig.
+ * Makefile.am: Remove references to them.
+ (HFILES): Add fr30-desc.h,m32r-desc.h.
+ (CFILES): Add fr30-desc.c,fr30-ibld.c,m32r-desc.c,m32r-ibld.c,
+ m32r-opinst.c.
+ (ALL_MACHINES): Update.
+ * configure.in: Redo handling of cgen_files.
+ (bfd_i960_arch): Delete i960c-*.lo files.
+ * configure: Regenerate.
+ * cgen-asm.c (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ (hash_insn_array): Rewrite.
+ * cgen-dis.c (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ (hash_insn_array): Rewrite.
+ * cgen-opc.c (*): CGEN_OPCODE_DESC renamed to CGEN_CPU_DESC.
+ (cgen_lookup_insn,cgen_get_insn_operands): Define here.
+ (cgen_lookup_get_insn_operands): Ditto.
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate.
+ * m32r-asm.c,m32r-dis.c,m32r-opc.c,m32r-opc.h: Regenerate.
+ * po/POTFILES.in: Rebuild.
+ * po/opcodes.pot: Rebuild.
+
+Fri Feb 5 00:04:24 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (HFILES): Add fr30-opc.h.
+ (CFILES): Add fr30-asm.c, fr30-dis.c, fr30-opc.c.
+ * Makefile.in: Rebuild.
+
+ * configure.in: Change AC_PREREQ to 2.13. Remove AM_CYGWIN32.
+ Change AM_EXEEXT to AC_EXEEXT and AM_PROG_INSTALL to
+ AC_PROG_INSTALL.
+ * acconfig.h: Remove.
+ * configure: Rebuild with current autoconf/automake.
+ * aclocal.m4: Likewise.
+ * config.in: Likewise.
+ * Makefile.in: Likewise.
+
+Thu Feb 4 13:48:52 1999 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Correct move (not movew) to status word on 5200.
+
+Mon Feb 1 20:54:36 1999 Catherine Moore <clm@cygnus.com>
+
+ * disassemble.c (disassembler): Handle bfd_mach_i386_i386_intel_syntax.
+ * i386-dis.c (x_mode): Define.
+ (dis386): Remove.
+ (dis386_att): New.
+ (dis386_intel): New.
+ (dis386_twobyte): Remove.
+ (dis386_twobyte_att): New.
+ (dis386_twobyte_intel): New.
+ (print_insn_x86): Use new arrays.
+ (float_mem): Remove.
+ (float_mem_intel): New.
+ (float_mem_att): New.
+ (dofloat): Use new float_mem arrays.
+ (print_insn_i386_att): New.
+ (print_insn_i386_intel): New.
+ (print_insn_i386): Handle bfd_mach_i386_i386_intel_syntax.
+ (putop): Handle intel syntax.
+ (OP_indirE): Handle intel syntax.
+ (OP_E): Handle intel syntax.
+ (OP_I): Handle intel syntax.
+ (OP_sI): Handle intel syntax.
+ (OP_OFF): Handle intel syntax.
+
+
+
+1999-01-27 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-opc.h,fr30-opc.c: Rebuild.
+ * i960c-opc.h,i960c-opc.c: Rebuild.
+ * m32r-opc.c: Rebuild.
+
+Tue Jan 19 18:01:54 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * hppa-dis.c: revert HP merge changes until HP gives us
+ an updated file.
+
+1999-01-19 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c (print_insn_arm): Display ARM syntax for PC relative
+ offsets as well as symbloic address.
+
+Tue Jan 19 10:51:01 1999 David Taylor <taylor@texas.cygnus.com>
+
+ * hppa-dis.c: fix comments and some indentation.
+
+1999-01-12 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-opc.c,i960c-opc.c: Regenerate.
+
+1999-01-11 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-opc.c: Regenerate.
+
+1999-01-06 Doug Evans <devans@casey.cygnus.com>
+
+ * m32r-dis.c: Regenerate.
+
+1999-01-05 Doug Evans <devans@casey.cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.h,fr30-opc.c: Regenerate.
+ * i960c-asm.c,i960c-dis.c,i960c-opc.h,i960c-opc.c: Regenerate.
+ * m32r-asm.c,m32r-dis.c,m32r-opc.h,m32r-opc.c: Regenerate.
+
+1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
+
+ * configure.in: Require autoconf 2.12.1 or higher.
+
+1998-12-30 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips16-opc.c: Mark branch insns with MIPS16_INSN_BRANCH.
+
+Wed Dec 16 16:17:49 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c: Regenerated.
+
+1998-12-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips-dis.c (set_mips_isa_type): Handle bfd_mach_mips4111.
+
+1998-12-15 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c,fr30-opc.h: Regenerated.
+
+1998-12-14 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c,fr30-opc.h: Regenerated.
+
+Thu Dec 10 18:39:46 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c,fr30-opc.h: Regenerated.
+
+Thu Dec 10 12:49:24 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.c: Regenerate.
+
+Tue Dec 8 13:56:18 1998 David Taylor <taylor@texas.cygnus.com>
+
+ * dis-buf.c (generic_strcat_address): reformat to GNU coding
+ conventions. change sprintf call to an sprintf_vma call.
+
+Tue Dec 8 13:12:44 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerated.
+
+Tue Dec 8 10:50:46 1998 David Taylor <taylor@texas.cygnus.com>
+
+ The following changes were made by
+ Elena Zannoni <ezannoni@kwikemart.cygnus.com>,
+ David Taylor <taylor@texas.cygnus.com>, and
+ Edith Epstein <eepstein@sophia.cygnus.com> as part of a project to
+ merge in changes by HP; HP did not create ChangeLog entries.
+
+ * dis-buf.c (generic_strcat_address): new function.
+
+ * hppa-dis.c: Changes to improve hppa disassembly.
+ Changed formatting in : reg_names, fp_reg_names,control_reg,
+ New variables : sign_extension_names, deposit_names, conversion_names
+ float_test_names, compare_cond_names_double, add_cond_names_double,
+ logical_cond_names_double, unit_cond_names_double,
+ branch_push_pop_names, saturation_names, shift_names, mix_names,
+ New Macros : GET_COMPL_O, GET_PUSH_POP,MERGED_REG
+ Move some definitions to libhppa.h: GET_FIELD, GET_BIT
+ (fput_const): renamed as fput_hex_const
+ (print_insn_hppa):
+ - use the macros fputs_filtered and
+ fput_decimal_const whenever possible; calls to sign_extend require
+ 2 params -- add a missing second param of 0.
+ - Some new code ifdefed for LOCAL_ONLY, all related to figuring out
+ architecture version number of current machine. HP folks are
+ trying to handle situation where the target program was compiled
+ for PA 1.x (32-bit), but is running on a PA 2.0 machine and
+ visa versa.
+ - added new cases : 'g', 'B', 'm'
+ - added cases specifically for PA 2.0
+ - changed the following cases : '"', 'n', 'N', 'p', 'Z',
+ - calls to fput_const become calls to fput_hex_const
+
+1998-12-07 James E Wilson <wilson@wilson-pc.cygnus.com>
+
+ * Makefile.am (CFILES): Add i960c-asm, i960c-dis.c, i960c-opc.c.
+ (ALL_MACHINES): Add i960c-asm.lo, i960c-dis.lo, i960-opc.lo.
+ (i960-asm.lo, i960c-dis.lo, i960c-opc.lo): New Makefile rules.
+ * Makefile.in: Rebuilt.
+ * configure.in (bfd_i960_arch): Add i960c-opc.lo, i960-asm.o,
+ i960-dis.c to ta.
+ * i960-dis.c (print_insn_i960): Rename to print_insn_i960_orig.
+ * i960c-asm.c, i960c-dis.c, i960c-opc.c, i960c-opc.h: New files.
+
+Mon Dec 7 14:33:44 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerated.
+
+Sun Dec 6 14:06:48 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c (mips_builtin_opcodes): Add dmfc2 and dmtc2.
+
+ * ppc-opc.c (powerpc_opcodes): Add PowerPC403 GC[X] instructions.
+ From Saitoh Masanobu <msaitoh@spa.is.uec.ac.jp>.
+
+Fri Dec 4 17:45:51 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * fr30-opc.c: Regenerate.
+
+Fri Dec 4 17:08:08 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerated.
+
+Thu Dec 3 14:26:20 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerated.
+
+Thu Dec 3 00:09:17 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate.
+
+1998-11-30 Doug Evans <devans@casey.cygnus.com>
+
+ * cgen-dis.c (hash_insn_array): CGEN_INSN_VALUE ->
+ CGEN_INSN_BASE_VALUE.
+ * m32r-opc.c,m32r-opc.h,m32r-asm.c,m32r-dis.c: Regenerate.
+ * fr30-opc.c,fr30-opc.h,fr30-asm.c,fr30-dis.c: Regenerate.
+
+Thu Nov 26 11:26:32 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c: Regenerated.
+
+Tue Nov 24 11:20:54 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c: Regenerated.
+
+Mon Nov 23 18:28:48 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerated.
+
+1998-11-20 Doug Evans <devans@tobor.to.cygnus.com>
+
+ * fr30-opc.c: Regenerated.
+
+Thu Nov 19 16:02:46 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c: Regenerated.
+ * fr30-opc.h: Regenerated.
+ * fr30-dis.c: Regenerated.
+ * fr30-asm.c: Regenerated.
+
+Thu Nov 19 07:54:15 1998 Doug Evans <devans@charmed.cygnus.com>
+
+ * mips-opc.c (sync.p,sync.l): Swap insn values.
+
+1998-11-19 Doug Evans <devans@tobor.to.cygnus.com>
+
+ * fr30-opc.c: Regenerate.
+
+Wed Nov 18 21:36:37 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c: Regenerated.
+ * fr30-opc.h: Regenerated.
+
+1998-11-18 Doug Evans <devans@casey.cygnus.com>
+
+ * m32r-asm.c,m32r-dis.c,m32r-opc.c: Rebuild.
+ * fr30-asm.c,fr30-dis.c,fr30-opc.c: Rebuild.
+
+Wed Nov 18 11:30:04 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c: Regenerated.
+
+Mon Nov 16 19:21:48 1998 Dave Brolley <brolley@cygnus.com>
+
+ * fr30-opc.c: Regenerated.
+ * fr30-opc.h: Regenerated.
+ * fr30-dis.c: Regenerated.
+ * fr30-asm.c: Regenerated.
+
+Thu Nov 12 19:24:18 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/opcodes.pot: Regenerated.
+ * fr30-opc.c: Regenerated.
+ * fr30-opc.h: Regenerated.
+ * fr30-dis.c: Regenerated.
+ * fr30-asm.c: Regenerated.
+
+Tue Nov 10 15:26:27 1998 Nick Clifton <nickc@cygnus.com>
+
+ * disassemble.c (disassembler): Add support for FR30 target.
+
+Tue Nov 10 11:00:04 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-dis.c,m32r-opc.c,m32r-opc.h: Rebuild.
+ * fr30-dis.c,fr30-opc.c,fr30-opc.h: Rebuild.
+
+Mon Nov 9 18:22:55 1998 Dave Brolley <brolley@cygnus.com>
+
+ * po/opcodes.pot: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * fr30-opc.c: Regenerate.
+ * fr30-opc.h: Regenerate.
+
+Fri Nov 6 17:21:38 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-asm.c: Regenerate.
+
+Wed Nov 4 18:46:47 1998 Dave Brolley <brolley@cygnus.com>
+
+ * configure.in: Added case for bfd_fr30_arch.
+ * Makefile.am (CFILES): Added fr30-asm.c, fr30-dis.c, fr30-opc.c.
+ (ALL_MACHINES): Added fr30-asm.lo, fr30-dis.lo, fr30-opc.lo.
+ (CLEANFILES): Added stamp-fr30.
+ (FR30_DEPS): Added.
+ * fr30-asm.c: New file.
+ * fr30-dis.c: New file.
+ * fr30-opc.c: New file.
+ * fr30-opc.h: New file.
+ * po/POTFILES.in: Regenerated
+ * po/opcodes.pot: Regenerated
+
+Mon Nov 2 15:05:33 1998 Geoffrey Noer <noer@cygnus.com>
+
+ * configure.in: detect cygwin* instead of cygwin32*
+ * configure: regenerate
+
+Tue Oct 27 08:58:37 1998 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips-opc.c (IS_M): Added.
+
+Mon Oct 19 13:03:19 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * m32r-opc.c,m32r-opc.h,m32r-asm.c,m32r-dis.c: Regenerate.
+
+Fri Oct 9 14:01:56 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * m32r-opc.h,m32r-opc.c: Regenerate.
+
+Sun Oct 4 21:01:44 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c (OP_3DNowSuffix): New static function.
+ (OPSUF): Define.
+ (GRP14): Define.
+ (dis386_twobyte): Add GRP14, femms, and 3DNow entries.
+ (twobyte_has_modrm): Set entries corresponding to GRP14, 3DNow.
+ (insn_codep): New static variable.
+ (print_insn_x86): Init insn_codep after prefixes.
+ (grps): Add GRP14 entries for prefetch, prefetchw.
+ (OP_REG): Reformat.
+
+ From Jeff B Epler <jepler@usgs.gov>
+ * i386-dis.c (Suffix3DNow): New table.
+
+Wed Sep 30 10:17:50 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d10v-opc.c: Treat TRAP as if it were a branch type instruction.
+
+Mon Sep 28 14:35:43 1998 Martin M. Hunt <hunt@cygnus.com>
+
+ * d10v-dis.c (print_operand): If num is nonzero, then
+ add OPERAND_ACC1, not OPERAND_ACC0.
+
+Thu Sep 24 09:20:03 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v-opc.c: Add FLAG_JSR attribute to DBT, REIT, RTD, and TRAP
+ insns.
+
+Tue Sep 22 17:55:14 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v-opc.c: Add use of EITHER_BUT_PREFER_MU execution unit
+ class.
+
+Tue Sep 15 15:14:45 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.h,m32r-opc.c: Add bbpc,bbpsw support.
+
+1998-09-09 Michael Meissner <meissner@cygnus.com>
+
+ * ppc-opc.c (powerpc_opcodes): Add support for PowerPC 750 move
+ to/from SPRs.
+
+Fri Sep 4 19:42:59 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c (print_insn_big_arm): Detect Thumb symbols in elf
+ object files.
+ (print_insn_little_arm): Detect Thumb symbols in elf object
+ files.
+
+Sat Aug 29 22:24:09 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha-dis.c (print_insn_alpha): Use the machine type to
+ decide which PALcode set to include.
+
+Sun Aug 23 02:16:18 1998 Richard Henderson <rth@cygnus.com>
+
+ * sparc-opc.c (FBRX): Fix typo in ",a,pn %fcc3" case.
+
+Fri Aug 21 16:07:52 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v-opc.c (d30v_opcode_table): Add FLAG_MUL32 to MAC, MACS,
+ MSUB and MSUBS instructions.
+
+Thu Aug 13 16:23:04 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * ppc-opc.c (powerpc_operands): Omit parens around additions in
+ operand name macros.
+
+Wed Aug 12 14:00:38 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From Peter Jeremy <peter.jeremy@auss2.alcatel.com.au>:
+ * m68k-opc.c: Correct mulsl and mulul to use q rather than D, a,
+ +, -, and d for ColdFire.
+
+ From Peter Thiemann <thiemann@informatik.uni-tuebingen.de>:
+ * ppc-opc.c (insert_mbe): Handle wrapping bitmasks.
+ (extract_mbe): Likewise.
+
+Wed Aug 12 11:11:34 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m10300-opc.c: Fix typo in udf20 .. udf25 instruction opcodes.
+
+ * m10300-opc.c: First cut at UDF instructions.
+
+Mon Aug 10 14:08:22 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.c: Regenerate (remove semantic descriptions).
+
+Mon Aug 10 12:51:12 1998 Catherine Moore <clm@cygnus.com>
+
+ * arm-dis.c (print_insn_big_arm): Fix indentation.
+ (print_insn_little_arm): Likewise.
+
+Sun Aug 9 20:17:28 1998 Catherine Moore <clm@cygnus.com>
+
+ * arm-dis.c (print_insn_big_arm): Check for thumb symbol
+ attributes.
+ (print_insn_little_arm): Likewise.
+
+Mon Aug 3 12:43:16 1998 Doug Evans <devans@seba.cygnus.com>
+
+ Move all global state data into opcode table struct, and treat
+ opcode table as something that is "opened/closed".
+ * cgen-asm.c (all fns): New first arg of opcode table descriptor.
+ (cgen_asm_init): Delete.
+ (cgen_set_parse_operand_fn): New function.
+ * cgen-dis.c (all fns): New first arg of opcode table descriptor.
+ (cgen_dis_init): Delete.
+ * cgen-opc.c (all fns): New first arg of opcode table descriptor.
+ (cgen_current_{opcode_table_mach,endian}): Delete.
+ * m32r-asm.c,m32r-dis.c,m32r-opc.c,m32r-opc.h: Regenerate.
+
+Thu Jul 30 21:41:10 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * d30v-opc.c (d30v_opcode_table): Add new "LKR" flag to some
+ instructions.
+
+Tue Jul 28 11:00:09 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m10300-opc.c: Add entries for "no_match_operands" field in
+ the opcode table.
+
+Fri Jul 24 11:41:37 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-asm.c,m32r-opc.c: Regenerate (-Wall cleanups).
+
+Tue Jul 21 13:41:07 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * m32r-opc.h,m32r-opc.c,m32r-asm.c,m32r-dis.c: Regenerate.
+
+Mon Jul 13 14:53:59 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c (ckprefix): Handle fwait specially only when it isn't
+ the first prefix.
+ (dofloat): Correct test for fnstsw. Print `fnstsw %ax' rather
+ than `fnstsw %eax'.
+ (OP_J): Remove unnecessary subtraction when 16-bit displacement
+ will be masked later.
+
+Thu Jul 2 17:11:27 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * m32r-opc.h (CGEN_MIN_INSN_SIZE): New #define.
+
+Wed Jul 1 16:11:16 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * m32r-asm.c,m32r-dis.c,m32r-opc.c,m32r-opc.h: Regenerate.
+
+Fri Jun 26 11:08:55 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m10300-dis.c: Only recognize instructions from the currently
+ selected machine.
+ * m10300-opc.c: Add field indicating the particular variant of
+ the mn10300 each instruction is available on.
+
+Fri Jun 26 12:04:21 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: For bfd_vax_arch, build vax-dis.lo.
+ * Makefile.am: Rebuild dependencies.
+ (CFILES): Add vax-dis.c.
+ (ALL_MACHINES): Add vax-dis.lo.
+ * aclocal.m4: Rebuild with current libtool.
+ * configure, Makefile.in: Rebuild.
+
+Fri Jun 26 12:03:20 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * vax-dis.c: New file, from work by Pauline Middelink
+ <middelin@polyware.iaf.nl>.
+ * disassemble.c (ARCH_vax): Define if ARCH_all.
+ (disassembler): Add case for ARCH_vax.
+ * makefile.vms: Support compilation on vms/vax.
+
+Tue Jun 23 19:42:18 1998 Mark Alexander <marka@cygnus.com>
+
+ * m10200-dis.c (print_insn_mn10200): Fix various non-portabilities
+ related to sign extension and the size of ints.
+
+Tue Jun 23 10:59:26 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m10300-opc.c: Support one operand "asr", "lsr" and "asl"
+ instructions. Support (sp) addressing mode by expanding it into
+ (0,sp).
+
+Sat Jun 20 14:46:20 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-dis.c (_print_insn_mips): Fix argument interchange typo.
+
+Fri Jun 19 09:16:42 1998 Mark Alexander <marka@cygnus.com>
+
+ * m10200-dis.c (print_insn_mn10200): Recognize 'break' pseudo-op.
+
+1998-06-18 Ulrich Drepper <drepper@cygnus.com>
+
+ * i386-dis.c: Add support for fxsave, fxrstor, sysenter and
+ sysexit.
+
+Thu Jun 18 10:22:24 1998 John Metzler <jmetzler@cygnus.com>
+
+ * mips-dis.c (print_insn_little_mips): Previously, instruction
+ printing references the symbol table to determine whether the
+ instruction resides in a block regular instructions or mips16
+ instructions. However, when the disassembler gets used in other
+ environments where the symbol table is not present, we no longer
+ rely in the symbol table, rather, use the low bit of the
+ instructions address to guess. There should be no change for usage
+ of the disassembler in host based programs, gdb, objdump.
+ (print_insn_big_mips): ditto.
+ (print_insn_mips): ditto
+
+Wed Jun 17 21:19:01 1998 Mark Alexander <marka@cygnus.com>
+
+ * m10200-dis.c (print_insn_mn10200): Don't bomb on unknown opcodes.
+
+Wed Jun 17 17:49:23 1998 Jeffrey A Law (law@cygnus.com)
+
+ * m10300-opc.c (mn10300_opcodes): Change opcode for "syscall".
+
+Tue Jun 16 13:10:51 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c (index16): Add '%' to register names. Use ','
+ instead of '+'.
+
+Sat Jun 13 11:33:55 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c: Don't print opcode suffix when we can figure out the
+ size (and gas can!) by register operands, or from the default
+ size.
+ (putop): Handle 'A', 'B', 'L', 'P', 'Q', 'R' macros. Rename 'C'
+ macro to 'E'.
+ (dis386, dis386_twobyte, grps): Use new suffix macros.
+ (dis386): Correct imul Ib to imul sIb. Change jnl to jge to be
+ consistent. Add suffix for call, jmp, lcall, ljmp, iret. Reverse
+ order of cmps operands to agree with Intel docs. Correct operand
+ of aad and aam (Ib -> sIb). Change ud2b from 0fb8 to 0fb9 to
+ agree with Intel docs.
+ (print_insn_x86): Print orphan fwait before other prefixes.
+ Return correct byte count for orphan fwait with prefixes. Don't
+ print `bound' operands in reverse order.
+ (ckprefix): Stop accumulating prefixes if we get fwait.
+ (OP_DIR): Print `$' before Ap operands of ljmp, lcall.
+
+Fri Jun 12 13:40:38 1998 Tom Tromey <tromey@cygnus.com>
+
+ * po/Make-in (all-yes): If maintainer mode, depend on .pot file.
+ ($(PACKAGE).pot): Unconditionally depend on POTFILES.
+
+Fri Jun 12 11:04:06 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ Fix problems when bfd_vma is wider than long.
+ * i386-dis.c: Make op_address and start_pc unsigned.
+ (set_op): Make parameter unsigned.
+ (print_insn_x86): Cast to bfd_vma when passing a value to
+ print_address_func.
+ * ns32k-dis.c (CORE_ADDR): Don't define.
+ (print_insn_ns32k): Change type of addr to bfd_vma. Use
+ bfd_scan_vma to read back address.
+ (print_insn_arg): Change type of addr to bfd_vma. Use sprintf_vma
+ to format it.
+ * m68k-dis.c (COERCE32): Cast to bfd_signed_vma to avoid overflow.
+ (NEXTULONG): New definition.
+ (print_insn_m68k): Avoid overflow when computing third argument of
+ print_insn_arg.
+ (print_insn_arg): Use NEXTULONG to fetch 32 bit address values.
+ Use disp instead of val to store offset values.
+ (print_indexed): Use base_disp instead of word to store base
+ displacement, to avoid overflow.
+ * m10300-dis.c (disassemble): Cast value to long when computing
+ pc-relative address, to get correct sign extension.
+
+Wed Jun 10 15:58:37 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.c: Regenerate.
+
+Tue Jun 9 14:27:57 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-opc.h (thumb_opcodes): Display 'add rx, rY, #0' insns as
+ 'mov rX, rY'. Patch courtesy of Tony Thompson <Tony.Thompson@arm.com>
+
+Mon Jun 8 18:17:21 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v-opc.c: Remove FALG_MUL32 attribyte from MULX2H insn.
+
+Fri Jun 5 23:47:55 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c: Combine aflag and dflag into sizeflag. Change OP_*
+ functions to void.
+ (OP_DSreg): Rename from OP_DSSI.
+ (OP_ESreg): Rename from OP_ESDI.
+ (Xb, Xv, Yb, Yv): Use index reg code, not b_mode or v_mode.
+ (DSBX): Define.
+ (append_seg): Rename from append_prefix.
+ (ptr_reg): New function.
+ (dis386): Add S suffix to pushf, popf, ret, lret, enter, leave.
+ Add DSBX for xlat.
+ (PREFIX_ADDR): Rename from PREFIX_ADR.
+ (float_reg): Add non-broken opcodes for people who don't want
+ UNIXWARE_COMPAT.
+
+Fri Jun 5 19:15:04 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-opc.c (tstb, tstw, tstl): Don't allow pcrel on
+ 68000/68008/68010.
+
+Wed Jun 3 18:56:22 1998 H.J. Lu <hjl@gnu.org>
+
+ * i386-dis.c (dis386): Change 0x60 to "pushaS", 0x61 to "popaS".
+
+Tue Jun 2 15:06:46 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * ppc-opc.c (powerpc_macros): Support shifts and rotates of size
+ 0; produce error message for shifts of size 32 (or 64 for 64-bit
+ shifts), because the hardware doesn't support them.
+
+Wed May 27 15:29:13 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v-opc.c: Add new operand: Ra3. Change SHORT_B3, SHORT_B3b,
+ LONG_2, LONG_2b formats to use this new operand.
+
+Tue May 26 20:47:48 1998 Stan Cox <scox@cygnus.com>
+
+ * sparc-dis.c (compute_arch_mask): Added bfd_mach_sparc_sparclite_le.
+
+Tue May 26 20:45:33 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): big endian instruction / little
+ endian data support.
+
+Tue May 26 16:14:39 1998 Nick Clifton <nickc@cygnus.com>
+
+ * d30v-opc.c (d30v_format_table): Change definition of SHORT_B3
+ and SHORT_B3b formats to use Rb instead of Ra.
+
+ Add FLAG_MUL16 to MUL2XH opcode.
+
+ Add FLAG_ADDSUBppp to SRC and SATHp opcodes to implement extension
+ to existing 1.1.1 parallelisation prohibition procedure.
+
+Fri May 22 16:00:00 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-asm.c,m32r-dis.c: Regenerate.
+
+Tue May 19 17:36:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_mips16_insn_arg): Handle type ']' correctly
+ with a shift count of 0.
+
+Fri May 15 14:58:31 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-opc.c (cgen_hw_lookup_by_name): Renamed from cgen_hw_lookup.
+ (cgen_hw_lookup_by_num): New function.
+
+Wed May 13 17:03:59 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-asm.c: Regenerate (handle uppercase HIGH/SHIGH/LOW/SDA).
+
+Wed May 13 14:34:31 1998 Mark Alexander <marka@cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): Always fetch instructions
+ as big-endian on SPARClite.
+
+Tue May 12 11:46:31 1998 Richard Henderson <rth@cygnus.com>
+
+ * d30v-opc.c (pre_defined_register): Remove alias for r0.
+
+Sun May 10 22:37:22 1998 Jeffrey A Law (law@cygnus.com)
+
+ * po/Make-in (install-info): New target.
+
+Thu May 7 17:15:59 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in (WIN32LIBADD): Add -lintl on cygwin32.
+ * configure: Rebuild.
+
+Thu May 7 12:49:46 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-opc.c (teq,tge,tgeu,tlt,tltu,tne): Added three-operand
+ variety of ISA2 instructions to set bottom ten bits of trap code.
+
+Thu May 7 11:54:25 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (config.status): Add explicit target so that
+ config.status depends upon bfd/configure.in.
+ * Makefile.in: Rebuild.
+
+Thu May 7 09:33:02 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips-opc.c (break, sdbbp): Added two-operand variety of ISA1
+ instructions to set bottom ten bits of break code.
+ * mips-dis.c (print_insn_arg): Implement 'q' operand format used
+ for above optional argument.
+
+Wed May 6 15:30:06 1998 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Run dec c with /nodebug.
+
+Mon May 4 10:19:57 1998 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Rebuilt.
+ * Makefile.am: Regenerated dependencies with mkdep.
+
+ * opintl.h (_): Define as dgettext.
+
+Tue Apr 28 14:12:12 1998 Nick Clifton <nickc@cygnus.com>
+
+ * cgen-asm.c: Internationalised.
+ * m32r-asm.c: Internationalised.
+ * m32r-dis.c: Internationalised.
+ * m32r-opc.c: Internationalised.
+
+ * aclocal.m4: Regenerated.
+ * configure: Regenerated.
+ * Makefile.am (POTFILES): Remove inclusion of BFD_H.
+ * Makefile.in: Rebuild.
+ * po/POTFILES.in: Rebuilt using rule in Makefile.in.
+ * po/opcodes.pot: Rebuilt after changing POTFILES.in.
+
+Tue Apr 28 13:13:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_ISC_POSIX near start. Move CY_GNU_GETTEXT
+ after AC_PROG_CC.
+ * aclocal.m4, configure: Rebuild with current tools.
+
+Mon Apr 27 14:31:00 1998 Nick Clifton <nickc@cygnus.com>
+
+ * opintl.h: New file - contains internationalisation macros used
+ by source files in this directory.
+ * po/: New subdirectory - contains internationalisation files.
+ * po/Make-in: New file - Makefile constructor.
+ * po/POTFILES.in: New file - list of files in opcodes directory
+ that should be scan for internationalisation macros.
+ * po/opcodes.pot: New file - list of internationisation strings
+ found in files mentioned in po/POTFILES.in.
+ * Makefile.am: Add rule to build po/POTFILES.in. Add SUBDIRS
+ entry. Add intl directory to include paths.
+ * acconfig.h: Add ENABLE_NLS, HAVE_CATGETS, HAVE_GETEXT,
+ HAVE_STRCPY, HAVE_LC_MESSAGES
+ * configure.in: Add rule to build Makefile in po subdirectory.
+ * Makefile.in: Rebuilt.
+ * aclocal.m4: Rebuilt.
+ * config.in: Rebuilt.
+ * configure: Rebuilt.
+ * alpha-opc.c: Internationalised.
+ * arc-dis.c: Internationalised.
+ * arc-opc.c: Internationalised.
+ * arm-dis.c: Internationalised.
+ * cgen-asm.c: Internationalised.
+ * d30v-dis.c: Internationalised.
+ * dis-buf.c: Internationalised.
+ * h8300-dis.c: Internationalised.
+ * h8500-dis.c: Internationalised.
+ * i386-dis.c: Internationalised.
+ * m10200-dis.c: Internationalised.
+ * m10300-dis.c: Internationalised.
+ * m68k-dis.c: Internationalised.
+ * m88k-dis.c: Internationalised.
+ * mips-dis.c: Internationalised.
+ * ns32k-dis.c: Internationalised.
+ * opintl.h: Internationalised.
+ * ppc-opc.c: Internationalised.
+ * sparc-dis.c: Internationalised.
+ * v850-dis.c: Internationalised.
+ * v850-opc.c: Internationalised.
+
+Mon Apr 27 10:33:56 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-asm.c (cgen_current_opcode_table): Renamed from ..._data.
+ (asm_hash_table_entries): New variable.
+ (cgen_asm_init): Free asm_hash_table_entries.
+ (hash_insn_array,hash_insn_list): New functions.
+ (build_asm_hash_table): Use them. Hash macro insns as well.
+ (cgen_asm_lookup_insn): Update.
+ * cgen_dis.c (cgen_current_opcode_table): Renamed from ..._data.
+ (dis_hash_table_entries): New variable.
+ (cgen_dis_init): Free dis_hash_table_entries.
+ (hash_insn_array,hash_insn_list): New functions.
+ (build_dis_hash_table): Use them. Hash macro insns as well.
+ (cgen_dis_lookup_insn): Update.
+ * cgen-opc.c (cgen_current_opcode_table): Renamed from ..._data.
+ (cgen_set_cpu,cgen_hw_lookup,cgen_insn_count): Update.
+ (cgen_macro_insn_count): New function.
+ * m32r-opc.h,m32r-opc.c,m32r-asm.c,m32r-dis.c: Regenerate.
+
+Fri Apr 24 16:07:57 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c (OP_DSSI): Print segment override.
+
+Mon Apr 13 16:59:39 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c (print_insn_arm): Add "_all" extension to 'C'
+ operator.
+
+Mon Apr 13 16:50:27 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (libopcodes_la_LIBADD): Add @WIN32LIBADD@.
+ (libopcodes_la_LDFLAGS): Add @WIN32LDFLAGS@.
+ * configure.in: Define and substitute WIN32LDFLAGS and
+ WIN32LIBADD.
+ * aclocal.m4: Rebuild with new libtool.
+ * configure, Makefile.in: Rebuild.
+
+Fri Apr 10 18:14:31 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.c: Regenerate.
+
+Sun Apr 5 16:04:39 1998 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (stamp-lib): Check that .libs/libopcodes.a exists
+ before trying to copy it.
+ * Makefile.in: Rebuild.
+
+Thu Apr 2 17:25:49 1998 Nick Clifton <nickc@cygnus.com>
+
+ * m32r-opc.c: Use signed immediate values for CMPUI instruction.
+
+Wed Apr 1 16:20:27 1998 Ian Dall <Ian.Dall@dsto.defence.gov.au>
+
+ * ns32k-dis.c (bit_extract_simple): New function to extract bits
+ from an arbitrary valid buffer instead of fetching them on demand
+ using fetch_data().
+ (invalid_float): use bit_extract_simple() instead of bit_extract().
+
+Tue Mar 31 11:09:08 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ From H.J. Lu <hjl@gnu.org>:
+ * i386-dis.c (dis386): Change 0x8c and 0x8e to movS, and change Ew
+ to Ev for both.
+
+Mon Mar 30 17:32:03 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Branched binutils 2.9.
+
+Mon Mar 30 15:18:00 1998 Ken Raeburn <raeburn@cygnus.com>
+
+ * d30v-dis.c (print_insn_d30v): Don't use uninitialized "num" when
+ disassembling last 4 bytes of a section.
+
+Fri Mar 27 18:08:13 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ Fix some gcc -Wall warnings:
+ * arc-dis.c (print_insn): Add casts to avoid warnings.
+ * cgen-opc.c (cgen_keyword_lookup_name): Likewise.
+ * d10v-dis.c (dis_long, dis_2_short): Likewise.
+ * m10200-dis.c (disassemble): Likewise.
+ * m10300-dis.c (disassemble): Likewise.
+ * ns32k-dis.c (print_insn_ns32k): Likewise.
+ * ppc-opc.c (insert_ral, insert_ram): Likewise.
+ * cgen-dis.c (build_dis_hash_table): Remove used local variables.
+ * cgen-opc.c (cgen_keyword_search_next): Likewise.
+ * d10v-dis.c (dis_long, dis_2_short): Likewise.
+ * d30v-dis.c (print_insn_d30v, lookup_opcode): Likewise.
+ * ns32k-dis.c (bit_extract, print_insn_ns32k): Likewise.
+ * tic80-dis.c (print_one_instruction): Likewise.
+ * w65-dis.c (print_operand): Likewise.
+ * z8k-dis.c (fetch_data): Likewise.
+ * a29k-dis.c: Add return type for find_byte_func_type.
+ * arc-opc.c: Include <stdio.h>. Remove declarations of
+ insert_multshift and extract_multshift.
+ * d30v-dis.c (lookup_opcode): Parenthesize assignments in
+ conditionals.
+ (extract_value): Fully parenthesize expression.
+ * h8500-dis.c (print_insn_h8500): Initialize local variables.
+ * h8500-opc.h (h8500_table): Fully bracket initializer.
+ * w65-opc.h (optable): Likewise.
+ * i386-dis.c (print_insn_x86): Declare aflag and flag parameters.
+ * i386-dis.c (OP_E): Initialize local variables.
+ * m10200-dis.c (print_insn_mn10200): Likewise.
+ * mips-dis.c (print_insn_mips16): Likewise.
+ * sh-dis.c (print_insn_shx): Likewise.
+ * v850-dis.c (print_insn_v850): Likewise.
+ * ns32k-dis.c (print_insn_arg): Declare.
+ (get_displacement, invalid_float): Declare.
+ (list_search, sign_extend, flip_bytes): Declare return type.
+ (get_displacement): Likewise.
+ (print_insn_arg): Likewise. Make d int. Fix sprintf format
+ string.
+ (print_insn_ns32k): Make i unsigned.
+ (invalid_float): Make static. Declare type of val.
+ * tic30-dis.c (print_par_insn): Make i size_t. Don't check strlen
+ on each for iteration.
+ * tic30-dis.c (get_indirect_operand): Likewise.
+ * z8k-dis.c (print_insn_z8001): Declare return type.
+ (print_insn_z8002): Likewise.
+ (unparse_instr): Fix sprintf format strings.
+
+Fri Mar 27 00:05:23 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mips-opc.c: Add "sync.l" and "sync.p".
+
+Wed Mar 25 14:32:48 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-dis.c (print_insn_m68k): Use info->mach to select the
+ default m68k variant to recognize.
+
+ * i960-dis.c (pinsn): Change type of first argument to bfd_vma.
+ (ctrl, cobr, mem, ea): Likewise.
+ (print_addr): Likewise. Remove cast.
+ (ea): Cast argument of print_addr to bfd_vma.
+
+ * cgen-asm.c (cgen_parse_signed_integer): Fix type of local
+ variable value.
+ (cgen_parse_unsigned_integer): Likewise.
+ (cgen_parse_address): Likewise.
+
+Wed Mar 25 14:31:31 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * i960-dis.c (ctrl): Add full braces to structure initialization.
+ (cobr, mem, reg): Likewise.
+ (ea): Correct parenthesization in expression.
+
+ * cgen-asm.c: Include <ctype.h>.
+ (build_asm_hash_table): Remove unused local variable i.
+ (cgen_parse_keyword): Add casts to avoid warnings.
+
+ * arm-dis.c (print_insn_big_arm): Only call coffsymbol for a COFF
+ symbol. Fix indentation.
+ (print_insn_little_arm): Likewise.
+
+Fri Mar 20 18:55:18 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use AM_DISABLE_SHARED.
+ * aclocal.m4, configure: Rebuild with libtool 1.2.
+
+Thu Mar 19 15:46:53 1998 Nick Clifton <nickc@cygnus.com>
+
+ These patches are courtesy of Jonathan Walton and Tony Thompson
+ (athompso@cambridge.arm.com).
+
+ * arm-dis.c (print_insn_thumb): Ignore bottom two bits of PC
+ relative addresses.
+
+ * arm-opc.h (thumb_opcodes): Annotate PC relative addresses with
+ both the offset and the label closest to the destination.
+
+Sat Mar 14 23:47:14 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * m32r-opc.h: Regenerate.
+
+Wed Mar 4 12:08:14 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.h,m32r-opc.c,m32r-asm.c,m32r-dis.c: Regenerate.
+
+Sat Feb 28 16:02:34 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c (print_insn_big_arm, print_insn_little_arm): Do not
+ assume that info->symbols is non-empty.
+
+Sat Feb 28 12:19:05 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha-opc.c (cvtqs) There is no such thing.
+ (cvttq): Missing most of the /*d variants.
+
+Thu Feb 26 15:53:09 1998 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-opc.c (d30v_opcode_table): Indicate which instructions are
+ delayed branches or jumps.
+
+Tue Feb 24 10:46:44 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * arm-dis.c (print_insn_{big,little}_arm): info->symbol changed
+ to *info->symbols.
+ * mips-dis.c (print_insn_{big,little}_mips): Likewise.
+ * tic30-dis.c (print_branch): Likewise.
+
+Tue Feb 24 11:06:18 1998 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c (print_insn_big_arm, print_insn_little_arm): Remove
+ saved_symbol code as it is no longer needed.
+
+Mon Feb 23 13:16:17 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-asm.c: Include symcat.h.
+ * cgen-dis.c,cgen-opc.c: Ditto.
+ * m32r-asm.c,m32r-dis.c,m32r-opc.h,m32r-opc.c: Regenerate.
+
+Mon Feb 23 10:34:58 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mips-dis.c (print_insn_arg): Do not prefix 'P' arguments with '$'.
+
+Thu Feb 19 16:51:13 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.[ch]: Regenerate.
+
+Tue Feb 17 17:14:50 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-asm.c (cgen_parse_{signed,unsigned}_integer): Delete min,max
+ arguments. Don't perform validation here.
+ * m32r-asm.c,m32r-dis.c,m32r-opc.c: Regenerate.
+
+Fri Feb 13 14:26:06 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.c: Regenerate.
+
+Fri Feb 13 14:53:02 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * configure, Makefile.in, aclocal.m4: Rebuild with automake 1.2e.
+
+Fri Feb 13 10:21:09 1998 Mark Alexander <marka@cygnus.com>
+
+ * m10300-dis.c (print_insn_mn10300): Recognize break instruction.
+
+Fri Feb 13 13:12:14 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Get the version number from BFD.
+ * configure: Rebuild.
+
+ From H.J. Lu <hjl@gnu.org>:
+ * Makefile.am (libopcodes_la_LDFLAGS): Define.
+ * Makefile.in: Rebuild.
+
+Fri Feb 13 09:50:32 1998 Nick Clifton <nickc@cygnus.com>
+
+ * m32r-opc.c: Regenerate.
+ * m32r-opc.h: Regenerate.
+
+Thu Feb 12 11:01:40 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.c: Regenerate.
+
+Thu Feb 12 03:41:00 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ Fix rac to accept only a0:
+ * d10v-opc.c (d10v_predefined_registers, d10v_operands, d10v_opcodes):
+ Split OPERAND_ACC into OPERAND_ACC0 and OPERAND_ACC1.
+ Introduce OPERAND_GPR.
+ * d10v-dis.c (print_operand): Likewise.
+
+Wed Feb 11 18:58:34 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-opc.c (cgen_set_cpu): Delete init of hw list `next' chain.
+ (cgen_hw_lookup): Make result const.
+ * m32r-opc.h, m32r-opc.c, m32r-asm.c, m32r-dis.c: Regenerate.
+
+Sat Feb 7 15:30:27 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure, aclocal.m4: Rebuild with new libtool.
+
+Thu Feb 5 17:56:10 1998 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-opc.c (repeat{,i} instructions): Repeat/repeati
+ instructions use a PC relative branch, not absolute.
+
+Wed Feb 4 19:17:37 1998 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set libtool_enable_shared rather than
+ libtool_shared. Remove diversion hack.
+ * configure, Makefile.in, aclocal.m4: Rebuild with new libtool.
+
+Tue Feb 3 17:19:40 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-opc.c (cgen_set_cpu): Initialize hardware table.
+ * m32r-opc.h, m32r-opc.c, m32r-asm.c, m32r-dis.c: Regenerate.
+
+Mon Feb 2 19:22:15 1998 Steve Haworth <steve@pm.cse.rmit.EDU.AU>
+
+ * tic30-dis.c: New file.
+ * disassemble.c (disassembler): Add bfd_arch_tic30 case.
+ * configure.in: Handle bfd_tic30_arch.
+ * Makefile.am: Rebuild dependencies.
+ (CFILES): Add tic30-dis.c
+ (ALL_MACHINES): Add tic30-dis.lo.
+ * configure, Makefile.in: Rebuild.
+
+Thu Jan 29 13:02:56 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * m32r-opc.h (HAVE_CPU_M32R): Define.
+
+Wed Jan 28 09:55:03 1998 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (insertion routines): If both alignment and size is
+ wrong then report this.
+
+Tue Jan 27 21:52:59 1998 Jeffrey A Law (law@cygnus.com)
+
+ * mips-dis.c (_print_insn_mips): Set target_processor as appropriate.
+ Only recognize instructions for the current target_processor.
+
+Thu Jan 22 16:20:17 1998 Fred Fish <fnf@cygnus.com>
+
+ * d10v-dis.c (PC_MASK): Correct value.
+ (print_operand): If there's a reloc, don't calculate the
+ address because they could be in different sections.
+
+Fri Jan 16 15:29:11 1998 Jim Blandy <jimb@zwingli.cygnus.com>
+
+ * mips-opc.c (mips_builtin_opcodes): Move 4010's "addciu"
+ instruction after the 4650's "mul" instruction; nobody's using the
+ 4010 these days. If object files someday indicate which processor
+ variant they're intended for, we can do a better job at this.
+
+Mon Jan 12 14:43:54 1998 Doug Evans <devans@seba.cygnus.com>
+
+ * cgen-asm.c (build_asm_hash_table): Traverse compiled in table using
+ table provided entry size. Use CGEN_INSN_MNEMONIC.
+ (cgen_parse_keyword): Rewrite.
+ * cgen-dis.c (build_dis_hash_table): Traverse compiled in table using
+ table provided entry size. Use CGEN_INSN_MASK_BITSIZE.
+ * cgen-opc.c: Clean up pass over `struct foo' usage.
+ (cgen_keyword_lookup_value): Handle "" entry.
+ (cgen_keyword_add): Likewise.
+
+Mon Dec 22 12:37:06 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Add FP_D to s.d instruction flags.
+
+Wed Dec 17 11:38:29 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-opc.c (halt, pulse): Enable them on the 68060.
+
+Tue Dec 16 15:22:53 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_opcodes): Revert change that put the 32 bit
+ PC relative offset forms before the 15 bit forms. An assembler command
+ line option now chooses the default.
+
+Tue Dec 16 15:22:51 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-opc.c (d30v_opcode_table): Set new flags bits
+ FLAG_{2WORD,MUL{16,32},ADDSUBppp}, in appropriate instructions.
+
+1997-12-15 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * configure: Only build libopcodes shared if --enable-shared's value
+ was `yes', or was set to `*opcodes*'.
+ * aclocal.m4: Likewise.
+ * NOTE: this really needs to be fixed in libtool/libtool.m4, the
+ original source of this bit of code. It's not clear what the best fix
+ would be, though.
+
+Fri Dec 12 11:57:04 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (OFF_SL_PC, OFF_SL_BR): Minor formatting change.
+ (tic80_opcodes): Reorder table entries to put the 32 bit PC relative
+ offset forms before the 15 bit forms, to default to the long forms.
+
+Fri Dec 12 01:32:30 1997 Richard Henderson <rth@cygnus.com>
+
+ * alpha-opc.c (cvttq/*u*): Remove, as that suffix is invalid.
+
+Wed Dec 10 17:42:35 1997 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c (print_insn_little_arm): Prevent examination of stored
+ symbol if none is present.
+ (print_insn_big_arm): Prevent examination of stored symbol if
+ none is present.
+
+Thu Oct 23 21:13:37 1997 Fred Fish <fnf@cygnus.com>
+
+ * d10v-opc.c (d10v_opcodes): Correct entry for RTE.
+
+Mon Dec 8 11:21:07 1997 Nick Clifton <nickc@cygnus.com>
+
+ * disassemble.c: Remove disasm_symaddr() function.
+
+ * arm-dis.c: Use info->symbol instead of info->flags to determine
+ if disassmbly should be in Thumb or Arm mode.
+
+Tue Dec 2 09:54:27 1997 Nick Clifton <nickc@cygnus.com>
+
+ * arm-dis.c: Add support for disassembling Thumb opcodes.
+ (print_insn_thumb): New function.
+
+ * disassemble.c (disasm_symaddr): New function.
+
+ * arm-opc.h: Display nop pseudo ops alongside equivalent disassembly.
+ (thumb_opcodes): Table of Thumb opcodes.
+
+Mon Dec 1 12:25:57 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-opc.c (btst): Change Dd@s to Dd;b.
+
+ * m68k-dis.c (print_insn_arg): Recognize 'm', 'n', 'o', 'p', 'q',
+ and 'v' as operand types.
+
+Mon Dec 1 11:56:50 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Add argument for lpstop. From Olivier Carmona
+ <olivier.carmona@di.epfl.ch>.
+ * m68k-dis.c (print_insn_m68k): Handle special case of lpstop,
+ which has a two word opcode with a one word argument.
+
+Sun Nov 23 22:25:21 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-opc.c (d30v_opcode_table, case cmpu): Immediate field is
+ unsigned, not signed.
+ (d30v_format_table): Add SHORT_CMPU cases for cmpu.
+
+Tue Nov 18 23:10:03 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * d10v-dis.c (print_operand):
+ Split OPERAND_FLAG into OPERAND_FFLAG and OPERAND_CFLAG.
+
+Tue Nov 18 18:45:14 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * d10v-opc.c (OPERAND_FLAG): Split into:
+ (OPERAND_FFLAG, OPERAND_CFLAG) .
+ (FSRC): Split into:
+ (FFSRC, CFSRC).
+
+Thu Nov 13 11:05:33 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c: Move the INSN_MACRO ISA value to the membership
+ field for all INSN_MACRO's.
+ * mips16-opc.c: same
+
+Wed Nov 12 10:16:57 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c (sync,cache): These are 3900 insns.
+
+Tue Nov 11 23:53:41 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ sh-opc.h (sh_table): Remove ftst/nan.
+
+Tue Oct 28 17:59:32 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * mips-opc.c (ffc, ffs): Fix mask.
+
+Tue Oct 28 16:34:54 1997 Michael Meissner <meissner@cygnus.com>
+
+ * d30v-opc.c (pre_defined_registers): Add eit_vb, int_s, and int_m
+ control registers.
+
+Mon Oct 27 22:34:03 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * mips-opc.c: Fix bug in mask for "not" pseudo-instruction.
+ (WR_HILO, RD_HILO, MOD_HILO): New macros.
+
+Mon Oct 27 22:34:03 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * mips-opc.c: Fix bug in mask for "not" pseudo-instruction.
+ (WR_HILO, RD_HILO, MOD_HILO): New macros.
+
+Thu Oct 23 14:57:58 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (disassemble): Replace // with /* ... */
+
+Wed Oct 22 17:33:21 1997 Richard Henderson <rth@cygnus.com>
+
+ * sparc-opc.c: Add wr & rd for v9a asr's.
+ * sparc-dis.c (print_insn_sparc): Recognize '_' and '/' for v9a asr's.
+ (v9a_asr_reg_names): New variable.
+ Patch from David Miller <davem@vger.rutgers.edu>.
+
+Wed Oct 22 17:18:02 1997 Richard Henderson <rth@cygnus.com>
+
+ * sparc-opc.c (v9notv9a): New insn type.
+ (IMPDEP): Move to the end to not conflict with edge8 et al.
+ Patch from David Miller <davem@vger.rutgers.edu>.
+
+Fri Oct 17 13:18:53 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c (bnezl,beqzl): Mark these as also tx39.
+
+Thu Oct 16 11:55:20 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c: Note that 'jalx' is (probably incorrectly) marked I1.
+
+Tue Oct 14 16:10:31 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (disassemble): Use new symbol_at_address_func() field
+ of disassemble_info structure to determine if an overlay address
+ has a matching symbol in low memory.
+
+ * dis-buf.c (generic_symbol_at_address): New (dummy) function for
+ new symbol_at_address_func field in disassemble_info structure.
+
+Fri Oct 10 16:44:52 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (extract_d22): Use signed arithmatic.
+
+Tue Oct 7 23:40:43 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c: Three op mult is not an ISA insn.
+
+Tue Oct 7 23:37:21 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c: Fix formatting.
+
+Fri Oct 3 17:26:54 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386-dis.c (OP_E): Explicitly sign extend 8 bit values, rather
+ than assuming that char is signed. Explicitly sign extend 16 bit
+ values, rather than assuming that short is 16 bits.
+ (OP_sI, OP_J, OP_DIR): Likewise.
+
+Thu Oct 2 13:36:45 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (v850_sreg_names): Use symbolic names for higher
+ system registers.
+
+Wed Oct 1 16:58:54 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c: Fix typo in comment.
+
+ * v850-dis.c (disassemble): Add test of processor type when
+ determining opcodes.
+
+Wed Oct 1 14:10:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use a diversion to set enable_shared before the
+ arguments are parsed.
+ * configure: Rebuild.
+
+Thu Sep 25 13:04:59 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c (TBL1): Use ! rather than `.
+ * m68k-dis.c (print_insn_arg): Remove ` operand specifier.
+
+Wed Sep 24 11:29:35 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Correct bchg, bclr, bset, and btst on ColdFire.
+
+ * m68k-opc.c: Accept tst{b,w,l} with immediate operands on cpu32.
+
+ * m68k-opc.c: Correct movew of an immediate operand to %sr or %ccr
+ for mcf5200.
+
+ * configure.in: Call AC_CHECK_TOOL before AM_PROG_LIBTOOL.
+ * aclocal.m4: Rebuild with new libtool.
+ * configure: Rebuild.
+
+Fri Sep 19 11:45:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * v850-opc.c ("cmov"): Order reg param r1, r2 not r2, r2.
+
+Thu Sep 18 11:21:43 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparclet_cpreg_table): Add %ccsr2, %cccrr, %ccrstr.
+
+Tue Sep 16 15:18:20 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (v850_opcodes): Further rearrangements.
+
+Tue Sep 16 16:12:11 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ * d30v-opc.c (rot2h, sra2h, srl2h insns): Revert last change.
+
+Tue Sep 16 09:48:50 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (v850_opcodes): Fields reordered to allow assembler
+ parser to work.
+
+Tue Sep 16 10:01:00 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c: Added tx39 insns sdbbp, rfe, and deret.
+
+Mon Sep 15 18:31:52 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c: Initialise processors field of v850_opcode structure.
+
+Wed Aug 27 21:42:39 1997 Ken Raeburn <raeburn@cygnus.com>
+
+ Merge changes from Martin Hunt:
+
+ * d30v-opc.c: Change mvfacc to accept 6-bit unsigned values.
+
+ * d30v-opc.c (pre_defined_registers): Add control registers from 0-63.
+ (d30v_opcode_tabel): Add dbt, rtd, srah, and srlh instructions. Fix
+ rot2h, sra2h, and srl2h to use new SHORT_A5S format.
+
+ * d30v-dis.c (print_insn): Fix disassembly of SHORT_D2 opcodes.
+
+ * d30v-dis.c (print_insn): First operand of d*i (delayed
+ branch) instructions is relative.
+
+ * d30v-opc.c (d30v_opcode_table): Change form for repeati.
+ (d30v_operand_table): Add IMM6S3 type.
+ (d30v_format_table): Change SHORT_D2. Add LONG_Db.
+
+ * d30v-dis.c: Fix bug with ".s" and ".l" extensions
+ and cmp instructions.
+
+ * d30v-opc.c: Correct entries for repeat*, and sat*.
+ Make IMM5 unsigned. Create IMM6U and IMM12S3U operand
+ types. Correct several formats.
+
+ * d30v-opc.c: (pre_defined_registers): Add dpsw and dpc.
+
+ * d30v-opc.c (pre_defined_registers): Change control registers.
+
+ * d30v-opc.c (d30v_format_table): Correct SHORT_C1 and
+ SHORT_C2. Manual was incorrect.
+
+ * d30v-dis.c (lookup_opcode): Return value now indicates
+ if an opcode has a short and a long form. Used for deciding
+ to append a ".s" or ".l".
+ (print_insn): Append a ".s" to an instruction if it is
+ the short form and ".l" if it is a long form. Do not append
+ anything if the instruction has only one possible size.
+
+ * d30v-opc.c: Change mulx2h to require an even register.
+ New form: SHORT_A2; a SHORT_A form that needs an even
+ register as the first operand.
+
+ * d30v-dis.c (print_insn_d30v): Fix problem where the last
+ instruction was not being disassembled if there were an odd
+ number of instructions.
+
+ * d30v-opc.c (SHORT_M2, LONG_M2): Two new forms.
+
+Fri Sep 12 11:43:54 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (disassemble): Improved display of register lists.
+
+Thu Sep 11 17:35:10 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Fix assembler args to
+ fzeros, fones, fsrc1, fsrc1s, fsrc2s, fnot1, fnot1s, fnot2s,
+ fors, fnors, fands, fnands, fxors, fxnors, fornot1s, fornot2s,
+ fandnot1s, fandnot2s.
+
+Tue Sep 9 10:03:49 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Fix op3 field for fcmpq/fcmpeq.
+
+Mon Sep 8 14:06:59 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen-asm.c (cgen_parse_address): New argument resultp.
+ All callers updated.
+ * m32r-asm.c (parse_h_hi16): Right shift numbers by 16.
+
+Tue Sep 2 18:39:08 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-dis.c (disassemble): PC relative instructions are
+ relative to the next instruction, not the current instruction.
+
+Tue Sep 2 15:41:55 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (disassemble): Only signed extend values that are not
+ returned by extract functions.
+ Remove use of V850_OPERAND_ADJUST_SHORT_MEMORY flag.
+
+Tue Sep 2 15:39:40 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c: Update comments. Remove use of
+ V850_OPERAND_ADJUST_SHORT_MEMORY. Fix several operand patterns.
+
+Tue Aug 26 09:42:28 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (MOVHI): Immediate parameter is unsigned.
+
+Mon Aug 25 15:58:07 1997 Christopher Provenzano <proven@cygnus.com>
+
+ * configure: Rebuilt with latest devo autoconf for NT support.
+
+Fri Aug 22 10:35:15 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (disassemble): Use curly brace syntax for register
+ lists.
+
+ * v850-opc.c (v850_opcodes[]): Add NOT_R0 flag to decect cases
+ where r0 is being used as a destination register.
+
+Thu Aug 21 11:09:09 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (v850_opcodes[]): Move divh opcodes next to each other.
+
+Tue Aug 19 10:59:59 1997 Richard Henderson <rth@cygnus.com>
+
+ * alpha-opc.c (alpha_opcodes): Fix hw_rei_stall mungage.
+
+Mon Aug 18 11:10:03 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-opc.c (v850_opcodes[]): Remove use of flag field.
+ * v850-opc.c (v850_opcodes[]): Add support for reversed short load
+ opcodes..
+
+Mon Aug 18 11:08:25 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure (cgen_files): Add support for v850e target.
+ * configure.in (cgen_files): Add support for v850e target.
+
+Mon Aug 18 11:08:25 1997 Nick Clifton <nickc@cygnus.com>
+
+ * configure (cgen_files): Add support for v850ea target.
+ * configure.in (cgen_files): Add support for v850ea target.
+
+Fri Aug 15 05:17:48 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure.in (bfd_arc_arch): Add.
+ * configure: Rebuild.
+ * Makefile.am (ALL_MACHINES): Add arc-dis.lo, arc-opc.lo.
+ * Makefile.in: Rebuild.
+ * arc-dis.c, arc-opc.c: New files.
+ * disassemble.c (ARCH_all): Define ARCH_arc.
+ (disassembler): Add ARC support.
+
+Wed Aug 13 18:52:11 1997 Nick Clifton <nickc@cygnus.com>
+
+ * v850-dis.c (disassemble): Add support for v850EA instructions.
+
+ * v850-opc.c (insert_i5div, extract_i5div): New Functions.
+ (v850_opcodes): Add v850EA instructions.
+
+ * v850-dis.c (disassemble): Add support for v850E instructions.
+
+ * v850-opc.c (insert_d5_4, extract_d5_4, insert_d16_16,
+ extract_d16_16, insert_i9, extract_i9, insert_u9, extract_u9,
+ insert_spe, extract_spe): New Functions.
+ (v850_opcodes): Add v850E instructions.
+
+ * v850-opc.c: Reorganised and re-layed out to improve readability
+ and portability.
+
+Tue Aug 5 23:09:31 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.1.
+
+Mon Aug 4 12:02:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4, configure: Rebuild with new automake patches.
+
+Fri Aug 1 13:02:04 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set enable_shared before AM_PROG_LIBTOOL.
+ * acinclude.m4: Just include acinclude.m4 from BFD.
+ * aclocal.m4, configure: Rebuild.
+
+Thu Jul 31 21:44:42 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * acconfig.h: New file.
+ * acinclude.m4: New file.
+ * stamp-h.in: New file.
+ * configure.in: Call AM_INIT_AUTOMAKE and AM_PROG_LIBTOOL.
+ Removed shared library handling; now handled by libtool. Replace
+ AC_CONFIG_HEADER with AM_CONFIG_HEADER. Call AM_MAINTAINER_MODE,
+ AM_CYGWIN32, and AM_EXEEXT. Replace AC_PROG_INSTALL with
+ AM_PROG_INSTALL. Change all .o files to .lo. Remove stamp-h
+ handling in AC_OUTPUT.
+ * dep-in.sed: Change .o to .lo.
+ * Makefile.in: Now built with automake.
+ * aclocal.m4: Now built with aclocal.
+ * config.in, configure: Rebuild.
+
+Mon Jul 28 21:52:24 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mips-opc.c: Fix typo/thinko in "eret" instruction.
+
+Thu Jul 24 13:03:26 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Fix spelling on fpaddX, fpsubX insns.
+ Make array const.
+ * sparc-dis.c (sorted_opcodes): New static local.
+ (struct opcode_hash): `opcode' is pointer to const element.
+ (build_hash): First arg is now table of sorted pointers.
+ (print_insn_sparc): Sort opcodes by sorting table of pointers.
+ (compare_opcodes): Update.
+
+Tue Jul 15 12:05:23 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen-opc.c: #include <ctype.h>.
+ (hash_keyword_name): New arg `case_sensitive_p'. Callers updated.
+ Handle case insensitive hashing.
+ (hash_keyword_value): Change type of `value' to unsigned int.
+
+Thu Jul 10 12:56:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mips-opc.c (mips_builtin_opcodes): If an insn uses single
+ precision FP, mark it as such. Likewise for double precision
+ FP. Mark ISA1 insns. Consolidate duplicate opcodes where
+ possible.
+
+Wed Jun 25 15:25:57 1997 Felix Lee <flee@cirdan.cygnus.com>
+
+ * ppc-opc.c (extract_nsi): make unsigned expression signed before
+ negating it.
+ (UNUSED): remove one level of parens, so MSVC doesn't choke on
+ nesting depth when all the macros are expanded.
+
+Tue Jun 17 17:02:17 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc-opc.c: The fcmp v9a instructions take an integer register
+ as a destination, not a floating point register. From Christian
+ Kuehnke <Christian.Kuehnke@arbi.Informatik.Uni-Oldenburg.DE>.
+
+Mon Jun 16 14:13:18 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-dis.c (print_insn_arg): Print case 7.2 using %pc@()
+ syntax. From Roman Hodek
+ <rnhodek@faui22c.informatik.uni-erlangen.de>.
+
+ * i386-dis.c (twobyte_has_modrm): Fix pand.
+
+Mon Jun 16 14:08:38 1997 Michael Taylor <mbt@mit.edu>
+
+ * i386-dis.c (dis386_twobyte): Fix pand and pandn.
+
+Tue Jun 10 11:26:47 1997 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * arm-dis.c: Add prototypes for arm_decode_shift and
+ print_insn_arm.
+
+Mon Jun 2 11:39:04 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c: Add r3900 insns.
+
+Tue May 27 15:55:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sh-dis.c (print_insn_shx): Change relmask to bfd_vma. Don't
+ print delay slot instructions on the same line. When using a PC
+ relative load, add a comment with the value being loaded if it can
+ be obtained.
+
+Tue May 27 11:02:08 1997 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c (dis386[], dis386_twobyte[]): change pushl/popl
+ to pushS/popS for segment regs and byte constant so that
+ pushw/popw printed when in 16 bit data mode.
+
+ * i386-dis.c (dis386[]): change cwtl, cltd to cWtS, cStd to
+ print cbtw, cwtd in 16 bit data mode.
+ * i386-dis.c (putop): extra case W to support above.
+
+ * i386-dis.c (print_insn_x86): print addr32 prefix when given
+ address size prefix in 16 bit address mode.
+
+Fri May 23 16:47:23 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sh-dis.c: Reindent. Rename local variable fprintf to
+ fprintf_fn.
+
+Thu May 22 14:06:02 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-opc.c (m32r_cgen_insn_table, cmpui): Undo patch of May 2.
+
+Tue May 20 11:26:27 1997 Gavin Koch <gavin@cygnus.com>
+
+ * mips-opc.c (mips_builtin_opcodes): Moved INSN_ISA field into new
+ field membership.
+ * mips16-opc.c (mip16_opcodes): same.
+
+Mon May 12 15:10:53 1997 Jim Wilson <wilson@cygnus.com>
+
+ * m68k-opc.c (moveb): Change $d to %d.
+
+Mon May 5 14:28:41 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386-dis.c: (dis386_twobyte): Add MMX instructions.
+ (twobyte_has_modrm): Likewise.
+ (grps): Likewise.
+ (OP_MMX, OP_EM, OP_MS): New static functions.
+
+ * i386-dis.c: Revert patch of April 4. The output now matches
+ what gcc generates.
+
+Fri May 2 12:48:37 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-opc.c (m32r_cgen_insn_table, cmpui): Use $uimm16 instead
+ of $simm16.
+
+Thu May 1 15:34:15 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-opc.h (CGEN_ARCH): Renamed from CGEN_CPU.
+
+Tue Apr 15 12:40:08 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install): Depend upon installdirs.
+ (installdirs): New target.
+
+Mon Apr 14 12:13:51 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ From Thomas Graichen <graichen@rzpd.de>:
+ * configure.in: Use ${CONFIG_SHELL} when running $ac_config_sub.
+ * configure: Rebuild.
+
+Sun Apr 13 17:50:41 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen-*.c, m32r-*.c: #include sysdep.h instead of config.h.
+ Delete string{,s}.h support.
+
+Thu Apr 10 14:44:56 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen-asm.c (cgen_parse_operand_fn): New global.
+ (cgen_parse_{{,un}signed_integer,address}): Update call to
+ cgen_parse_operand_fn.
+ (cgen_init_parse_operand): New function.
+ * m32r-asm.c (parse_insn_normal): cgen_init_parse_operand renamed
+ from cgen_asm_init_parse.
+ (m32r_cgen_assemble_insn): New operand `errmsg'.
+ Delete call to as_bad, return error message to caller.
+ (m32r_cgen_asm_hash_keywords): #if 0 out.
+
+Wed Apr 9 12:05:25 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-dis.c (print_insn_arg) [case 'd']: Print as address register,
+ not data register.
+ [case 'J']: Fix typo in register name.
+
+Mon Apr 7 16:48:22 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Substitute SHLIB_LIBS.
+ * configure: Rebuild.
+ * Makefile.in (SHLIB_LIBS): New variable.
+ ($(SHLIB)): Use $(SHLIB_LIBS).
+
+Mon Apr 7 11:45:44 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * cgen-dis.c (build_dis_hash_table): Fix xmalloc size computation.
+
+ * cgen-opc.c (hash_keyword_name): Improve algorithm.
+
+ * disassemble.c (disassembler): Handle m32r.
+
+Fri Apr 4 12:29:38 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * m32r-asm.c, m32r-dis.c, m32r-opc.c, m32r-opc.h: New files.
+ * cgen-asm.c, cgen-dis.c, cgen-opc.c: New files.
+ * Makefile.in (CFILES): Add them.
+ (ALL_MACHINES): Add them.
+ (dependencies): Regenerate.
+ * configure.in (cgen_files): New variable.
+ (bfd_m32r_arch): Add entry.
+ * configure: Regenerate.
+
+Fri Apr 4 14:04:16 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Correct file names for bfd_mn10[23]00_arch.
+ * configure: Rebuild.
+
+ * Makefile.in: Rebuild dependencies.
+
+ * d10v-dis.c: Include "ansidecl.h" before "opcode/d10v.h".
+
+ * i386-dis.c (float_reg): Swap fsubrp and fsubp. Swap fdivrp and
+ fdivp.
+
+Thu Apr 3 13:22:45 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Branched binutils 2.8.
+
+Wed Apr 2 12:23:53 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m10200-dis.c: Rename from mn10200-dis.c.
+ * m10200-opc.c: Rename from mn10200-opc.c.
+ * m10300-dis.c: Rename from mn10300-dis.c
+ * m10300-opc.c: Rename from mn10300-opc.c.
+ * Makefile.in: Update accordingly.
+
+ * mips16-opc.c: Add mul and dmul macros.
+
+Tue Apr 1 16:27:45 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Update CFLAGS, add clean target.
+
+Fri Mar 28 12:10:09 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Add "wait". From Ralf Baechle
+ <ralf@gnu.ai.mit.edu>.
+
+ * configure.in: Add stdlib.h to AC_CHECK_HEADERS list.
+ * configure, config.in: Rebuild.
+ * sysdep.h: Include <stdlib.h> if it exists.
+ * sparc-dis.c: Include <stdio.h> and "sysdep.h". Don't include
+ <string.h>.
+ * Makefile.in: Rebuild dependencies.
+
+Thu Mar 27 14:24:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * ppc-opc.c: Add PPC 403 instructions and extended opcodes. From
+ Andrew Bray <andy@madhouse.demon.co.uk>.
+
+ * mips-opc.c: Add cast when setting mips_opcodes.
+
+Tue Mar 25 23:04:00 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-dis.c (disassemble): Fix sign extension problem.
+ * v850-opc.c (extract_d*): Fix sign extension problems to make
+ disassembly calculate branch offsets correctly.
+
+Mon Mar 24 13:22:13 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * sh-opc.h: Add bf/s and bt/s as synonyms for bf.s and bt.s.
+
+ * mips-opc.c: Add dctr and dctw.
+
+Sun Mar 23 18:08:10 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d30v-dis.c (print_insn): Change the way signed constants
+ are displayed.
+
+Fri Mar 21 14:37:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (BFD_H): New variable.
+ (HFILES): New variable.
+ (CFILES): Add all C files.
+ (.dep, .dep1, dep.sed, dep, dep-in): New targets.
+ Delete old dependencies, and build new ones.
+ * dep-in.sed: New file.
+
+Thu Mar 20 19:03:30 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * m68k-opc.c (m68k_opcode_aliases): Added blo and blo{s,b,w,l}.
+
+Tue Mar 18 14:17:03 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c: Change "trap" to "syscall".
+ * mn10300-opc.c: Add new "syscall" instruction.
+
+Mon Mar 17 08:48:03 1997 J.T. Conklin <jtc@beauty.cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Provide correct entries for mulsl and
+ mulul insns on the coldfire.
+
+Sat Mar 15 17:13:05 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * arm-dis.c (print_insn_arm): Don't print instruction bytes.
+ (print_insn_big_arm): Set bytes_per_chunk and display_endian.
+ (print_insn_little_arm): Likewise.
+
+Fri Mar 14 15:08:59 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ Based on patches from H.J. Lu <hjl@lucon.org>:
+ * i386-dis.c (fetch_data): Add prototype.
+ * m68k-dis.c (fetch_data): Add prototype.
+ (dummy_print_address): Add prototype. Make static.
+ * ppc-opc.c (valid_bo): Add prototype.
+ * sparc-dis.c (build_hash_table): Add prototype.
+ (is_delayed_branch, compute_arch_mask): Add prototypes.
+ (print_insn_sparc): Make several local variables const.
+ (compare_opcodes): Change arguments to const PTR. Add prototype.
+ * sparc-opc.c (arg): Change name field to be const.
+ (lookup_name, lookup_value): Add prototypes. Change table and
+ name parameters to be const.
+ (sparc_encode_asi): Change name parameter to be const.
+ (sparc_encode_membar, sparc_encode_prefetch): Likewise.
+ (sparc_encode_sparclet_cpreg): Likewise.
+ (sparc_decode_asi): Change return type to be const.
+ (sparc_decode_membar, sparc_decode_prefetch): Likewise.
+ (sparc_decode_sparclet_cpreg): Likewise.
+
+Fri Mar 7 10:51:49 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(SHLINK)): Just use ln -s, not ln -sf, since
+ Solaris doesn't like the combined options, and the -f is
+ unnecessary.
+ (stamp-tshlink, install): Likewise.
+
+Thu Mar 6 16:51:11 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (IMM16_PCREL, SD8N_PCREL, D16_SHIFT): Mark these
+ as relaxable.
+
+Tue Mar 4 06:10:36 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Fix last change for the mc68010.
+
+Mon Mar 3 07:45:20 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Added entries for the tst insns on
+ the mc68000.
+
+Thu Feb 27 14:04:32 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * m68k-opc.c (m68k_opcodes): Added swbegl pseudo-instruction.
+
+Thu Feb 27 11:36:41 1997 Michael Meissner <meissner@cygnus.com>
+
+ * tic80-dis.c (print_insn_tic80): Set info->bytes_per_line to 8.
+
+Wed Feb 26 15:34:48 1997 Michael Meissner <meissner@cygnus.com>
+
+ * tic80-opc.c (tic80_predefined_symbols): Define r25 properly.
+
+Wed Feb 26 13:38:30 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-dis.c (NEXTSINGLE, NEXTDOUBLE, NEXTEXTEND): Use
+ floatformat_to_double to make portable.
+ (print_insn_arg): Use NEXTEXTEND macro when extracting extended
+ precision float.
+
+Mon Feb 24 19:26:12 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * mips-opc.c: Initialize mips_opcodes to mips_builtin_opcodes,
+ and bfd_mips_num_opcodes to bfd_mips_num_builtin_opcodes.
+
+Mon Feb 24 15:19:01 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-dis.c, d10v-opc.c: Change pre_defined_registers to
+ d10v_predefined_registers and reg_name_cnt to d10v_reg_name_cnt.
+
+Mon Feb 24 14:33:26 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (LSI_SCALED): Renamed from this ...
+ (OFF_SL_BR_SCALED): ... to this, and added the flag
+ TIC80_OPERAND_BASEREL to the flags word.
+ (tic80_opcodes): Replace all occurances of LSI_SCALED with
+ OFF_SL_BR_SCALED.
+
+Sat Feb 22 21:25:00 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * mips-opc.c: Add macros for cop0, cop1 cop2 and cop3.
+ Change mips_opcodes from const array to a pointer,
+ and change bfd_mips_num_opcodes from const int to int,
+ so that we can increase the size of the mips opcodes table
+ dynamically.
+
+Sat Feb 22 21:03:47 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_predefined_symbols): Revert change to
+ store BITNUM values in the table in one's complement form
+ to match behavior when assembler is given a raw numeric
+ value for a BITNUM operand.
+ * tic80-dis.c (print_operand_bitnum): Ditto.
+
+Fri Feb 21 16:31:18 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d30v-opc.c: Removed references to FLAG_X.
+
+Wed Feb 19 14:51:20 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Add dependencies on ../bfd/bfd.h as required.
+
+Tue Feb 18 17:43:43 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * Makefile.in: Added d30v object files.
+ * configure: (bfd_d30v_arch) Rebuilt.
+ * configure.in: (bfd_d30v_arch) Added new case.
+ * d30v-dis.c: New file.
+ * d30v-opc.c: New file.
+ * disassemble.c (disassembler) Add entry for d30v.
+
+Tue Feb 18 16:32:08 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_predefined_symbols): Add symbolic
+ representations for the floating point BITNUM values.
+
+Fri Feb 14 12:14:05 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_predefined_symbols): Store BITNUM values
+ in the table in one's complement form, as they appear in the
+ actual instruction.
+ (tic80_symbol_to_value): Use macros to access predefined
+ symbol fields.
+ (tic80_value_to_symbol): Ditto.
+ (tic80_next_predefined_symbol): New function.
+ * tic80-dis.c (print_operand_bitnum): Remove code that did
+ one's complement for BITNUM values.
+
+Thu Feb 13 21:56:51 1997 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Remove 8 bit characters. Update to latest
+ gcc release.
+
+Thu Feb 13 20:41:22 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
+
+ * m68k-opc.c (m68k_opcodes): Add swbeg pseudo-instruction.
+
+Thu Feb 13 16:30:02 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c (IMM16_PCREL): This is a signed operand.
+ (IMM24_PCREL): Likewise.
+
+Thu Feb 13 13:28:43 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_mips16_insn_arg): Use memaddr - 2 as the base
+ address for an extended PC relative instruction that is not a
+ branch.
+
+Wed Feb 12 12:27:40 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-dis.c (print_insn_m68k): Set bytes_per_chunk and
+ bytes_per_line.
+
+Tue Feb 11 16:36:31 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_operands): Fix typo '+' -> '|'.
+ (tic80_opcodes): Sort entries so that long immediate forms
+ come after short immediate forms, making it easier for
+ assembler to select the right one for a given operand.
+
+Tue Feb 11 15:26:47 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (_print_insn_mips): Set bytes_per_chunk and
+ display_endian.
+ (print_insn_mips16): Likewise.
+
+Mon Feb 10 10:12:41 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_symbol_to_value): Changed to accept
+ a symbol class that restricts translation to just that
+ class (general register, condition code, etc).
+
+Thu Feb 6 17:34:09 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_operands): Add REG_0_E, REG_22_E,
+ and REG_DEST_E for register operands that have to be
+ an even numbered register. Add REG_FPA for operands that
+ are one of the floating point accumulator registers.
+ Add TIC80_OPERAND_MASK to flags for ENDMASK operand.
+ (tic80_opcodes): Change entries that need even numbered
+ register operands to use the new operand table entries.
+ Add "or" entries that are identical to "or.tt" entries.
+
+Wed Feb 5 11:12:44 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips16-opc.c: Add new cases of exit instruction for
+ disassembler.
+ * mips-dis.c (print_mips16_insn_arg): Display floating point
+ registers in operands of exit instruction. Print `$' before
+ register names in operands of entry and exit instructions.
+
+Thu Jan 30 14:09:03 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_predefined_symbols): Table of name/value
+ pairs for all predefined symbols recognized by the assembler.
+ Also used by the disassembling routines.
+ (tic80_symbol_to_value): New function.
+ (tic80_value_to_symbol): New function.
+ * tic80-dis.c (print_operand_control_register,
+ print_operand_condition_code, print_operand_bitnum):
+ Remove private tables and use tic80_value_to_symbol function.
+
+Thu Jan 30 11:30:45 1997 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-dis.c (print_operand): Change address printing
+ to correctly handle PC wrapping. Fixes PR11490.
+
+Wed Jan 29 09:39:17 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c (mn10200_operands): Make 8 and 16 bit pc-relative
+ branches relaxable.
+
+Tue Jan 28 15:57:34 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_insn_mips16): Set insn_info information.
+ (print_mips16_insn_arg): Likewise.
+
+ * mips-dis.c (print_insn_mips16): Better handling of an extend
+ opcode followed by an instruction which can not be extended.
+
+Fri Jan 24 12:08:21 1997 J.T. Conklin <jtc@cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Changed operand specifier for the
+ coldfire moveb instruction to not allow an address register as
+ destination. Although the documentation does not indicate that
+ this is invalid, experiments uncovered unexpected behavior.
+ Added a comment explaining the situation. Thanks to Andreas
+ Schwab for pointing this out to me.
+
+Wed Jan 22 20:13:51 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_opcodes): Expand comment to note that the
+ entries are presorted so that entries with the same mnemonic are
+ adjacent to each other in the table. Sort the entries for each
+ instruction so that this is true.
+
+Mon Jan 20 12:48:57 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-dis.c: Include <libiberty.h>.
+ (print_insn_m68k): Sort the opcode table on the most significant
+ nibble of the opcode.
+
+Sat Jan 18 15:15:05 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-dis.c (tic80_opcodes): Add "wrcr", "vmpy", "vrnd",
+ "vsub", "vst", "xnor", and "xor" instructions.
+ (V_a1): Renamed from V_a, msb of accumulator reg number.
+ (V_a0): Add macro, lsb of accumulator reg number.
+
+Fri Jan 17 18:24:31 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-dis.c (print_insn_tic80): Broke excessively long
+ function up into several smaller ones and arranged for
+ the instruction printing function to be callable recursively
+ to print vector instructions that have both a load and a
+ math instruction packed into a single opcode.
+ * tic80-opc.c (tic80_opcodes): Expand comment for vld opcode
+ to explain why it comes after the other vector opcodes.
+
+Fri Jan 17 16:19:15 1997 J.T. Conklin <jtc@beauty.cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): add b, w, or l specifier to coldfire
+ move insns to handle immediate operands.
+
+Thu Jan 17 16:19:00 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-opc.c (m68k_opcodes): Delete duplicate entry for "cmpil".
+ fix operand mask in the "moveml" entries for the coldfire.
+
+Thu Jan 16 20:54:40 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (V_a, V_m, V_S, V_Z, V_p, OP_V, MASK_V):
+ New macros for building vector instruction opcodes.
+ (tic80_opcodes): Remove all uses of FMT_SI, FMT_REG, and
+ FMT_LI, which were unused. The field is now a flags field.
+ Remove some opcodes that are possible, but illegal, such
+ as long immediate instructions with doubles for immediate
+ values. Add "vadd" and "vld" instructions.
+
+Wed Jan 15 18:59:51 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (tic80_operands): Reorder some table entries to make
+ the order more logical. Move the shift alias instructions ("rotl",
+ "shl", "ins", "rotr", "extu", "exts", "srl", and "sra" to be
+ interspersed with the regular sr.x and sl.x instructions. Add
+ and test new instruction opcodes for "sl", "sli", "sr", "sri", "st",
+ "sub", "subu", "swcr", and "trap".
+
+Tue Jan 14 19:42:50 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-opc.c (OFF_SS_PC): Renamed from OFF_SS.
+ (OFF_SL_PC): Renamed from OFF_SL.
+ (OFF_SS_BR): New operand type for base relative operand.
+ (OFF_SL_BR): New operand type for base relative operand.
+ (REG_BASE): New operand type for base register operand.
+ (tic80_opcodes): Add and test "fmpy", "frndm", "frndn", "frndp",
+ "frndz", "fsqrt", "fsub", "illop0", "illopF", "ins", "jsr",
+ "ld", "ld.u", "lmo", "or", "rdcr", "rmo", "rotl", and "rotr"
+ instructions.
+ * tic80-dis.c (print_insn_tic80): Print opcode name with fixed width
+ 10 char field, padded with spaces on rhs, rather than a string
+ followed by a tab. Use renamed TIC80_OPERAND_PCREL flag bit rather
+ than old TIC80_OPERAND_RELATIVE. Add support for new
+ TIC80_OPERAND_BASEREL flag bit.
+
+Mon Jan 13 15:58:56 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-dis.c (print_insn_tic80): Print floating point operands
+ as floats.
+ * tic80-opc.c (SPFI): Add single precision floating point
+ immediate operand type.
+ (ROTATE): Add rotate operand type for shifts.
+ (ENDMASK): Add for shifts.
+ (n): Macro for the 'n' bit.
+ (i): Macro for the 'i' bit.
+ (PD): Macro for the 'PD' field.
+ (P2): Macro for the 'P2' field.
+ (P1): Macro for the 'P1' field.
+ (tic80_opcodes): Add entries for "exts", "extu", "fadd",
+ "fcmp", and "fdiv".
+
+Mon Jan 6 15:06:55 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-dis.c (disassemble): Mask off unwanted bits after
+ adding in current address for pc-relative operands.
+
+Mon Jan 6 10:56:25 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-dis.c (R_SCALED): Add macro to test for ":s" modifier bit.
+ (print_insn_tic80): If R_SCALED then print ":s" modifier for operand.
+ * tic80-opc.c (REG0, REG22, REG27, SSOFF, LSOFF): Names
+ changed to REG_0, REG_22, REG_DEST, OFF_SS, OFF_SL respectively.
+ (SICR, LICR, REGM_SI, REGM_LI): Names changed to CR_SI, CR_LI,
+ REG_BASE_M_SI, REG_BASE_M_LI respectively.
+ (REG_SCALED, LSI_SCALED): New operand types.
+ (E): New macro for 'E' bit at bit 27.
+ (tic80_opcodes): Add and test dld, dld.u, dst, estop, and etrap
+ opcodes, including the various size flavors (b,h,w,d) for
+ the direct load and store instructions.
+
+Sun Jan 5 12:18:14 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-dis.c (M_SI, M_LI): Add macros to test for ":m" modifier bit
+ in an instruction.
+ * tic80-dis.c (print_insn_tic80): Change comma and paren handling.
+ Use M_SI and M_LI macros to check for ":m" modifier for GPR operands.
+ * tic80-opc.c (tic80_operands): Add REGM_SI and REGM_LI operands.
+ (F, M_REG, M_LI, M_SI, SZ_REG, SZ_LI, SZ_SI, D, S): New bit-twiddlers.
+ (MASK_LI_M, MASK_SI_M, MASK_REG_M): Remove and replace in opcode
+ masks with "MASK_* & ~M_*" to get the M bit reset.
+ (tic80_opcodes): Add bsr, bsr.a, cmnd, cmp, dcachec, and dcachef.
+
+Sat Jan 4 19:05:05 1997 Fred Fish <fnf@cygnus.com>
+
+ * tic80-dis.c (print_insn_tic80): Print TIC80_OPERAND_RELATIVE
+ correctly. Add support for printing TIC80_OPERAND_BITNUM and
+ TIC80_OPERAND_CC, and TIC80_OPERAND_CR operands in symbolic
+ form.
+ * tic80-opc.c (tic80_operands): Add SSOFF, LSOFF, BITNUM,
+ CC, SICR, and LICR table entries.
+ (tic80_opcodes): Add and test "nop", "br", "bbo", "bbz",
+ "bcnd", and "brcr" opcodes.
+
+Fri Jan 3 18:32:11 1997 Fred Fish <fnf@cygnus.com>
+
+ * ppc-opc.c (powerpc_operands): Make comment match the
+ actual fields (no shift field).
+ * sparc-opc.c (sparc_opcodes): Document why this cannot be "const".
+ * tic80-dis.c (print_insn_tic80): Replace abort stub with a
+ partial implementation, work in progress.
+ * tic80-opc.c (tic80_operands): Begin construction operands table.
+ (tic80_opcodes): Continue populating opcodes table and start
+ filling in the operand indices.
+ (tic80_num_opcodes): Add this.
+
+Fri Jan 3 12:13:52 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Add #B case for moveq.
+
+Thu Jan 2 12:14:29 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-dis.c (disassemble): Make sure all variables are initialized
+ before they are used.
+
+Tue Dec 31 12:20:38 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_opcodes): Put curly-braces around operands
+ for "breakpoint" instruction.
+
+Tue Dec 31 15:38:13 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALL_CFLAGS): Add -D_GNU_SOURCE.
+ (dep): Use ALL_CFLAGS rather than CFLAGS.
+
+Tue Dec 31 15:09:16 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * v850-opc.c (D8_{6,7}): Set V850_OPERAND_ADJUST_SHORT_MEMORY
+ flag.
+
+Mon Dec 30 17:02:11 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (m68k-opc.o, alpha-opc.o): Remove dis-asm.h dependency.
+ (tic80-dis.o, tic80-opc.o): Add rules per comment in Makefile.in.
+
+Mon Dec 30 11:38:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips16-opc.c: Add "abs".
+
+Sun Dec 29 10:58:22 1996 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (ALL_MACHINES): Add tic80-dis.o and tic80-opc.o.
+ * disassemble.c (ARCH_tic80): Define if ARCH_all is defined.
+ (disassembler): Add bfd_arch_tic80 support to set disassemble
+ to print_insn_tic80.
+ * tic80-dis.c (print_insn_tic80): Add stub.
+
+Fri Dec 27 22:30:57 1996 Fred Fish <fnf@cygnus.com>
+
+ * configure.in (arch in $selarchs): Add bfd_tic80_arch entry.
+ * configure: Regenerate with autoconf.
+ * tic80-dis.c: Add file.
+ * tic80-opc.c: Add file.
+
+Fri Dec 20 14:30:19 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (pre_defined_registers): Add cr[0-15], dpc, dpsw, link.
+
+Mon Dec 16 13:00:15 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c (mn10200_operands): Add SIMM16N.
+ (mn10200_opcodes): Use it for some logicals and btst insns.
+ Add "break" and "trap" instructions.
+
+ * mn10300-opc.c (mn10300_opcodes): Add "break" instruction.
+
+ * mn10200-opc.c: Add pseudo-ops for "mov (an),am" and "mov an,(am)".
+
+Sat Dec 14 22:36:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_mips16_insn_arg): The base address of a PC
+ relative load or add now depends upon whether the instruction is
+ in a delay slot.
+
+Wed Dec 11 09:23:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-dis.c: Finish writing disassembler.
+ * mn10200-opc.c (mn10200_opcodes): Fix mask for "mov imm8,dn".
+ Fix mask for "jmp (an)".
+
+ * mn10300-dis.c (disassemble, print_insn_mn10300): Corrently
+ handle endianness issues for mn10300.
+
+ * mn10200-opc.c (mn10200_opcodes): Fix operands for "movb dm,(an)".
+
+Tue Dec 10 12:08:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c (mn10200_opcodes): "mov imm8,d0" is a format 2
+ instruction. Fix opcode field for "movb (imm24),dn".
+
+ * mn10200-opc.c (mn10200_operands): Fix insertion position
+ for DI operand.
+
+Mon Dec 9 16:42:43 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c: Create mn10200 opcode table.
+ * mn10200-dis.c: Flesh out mn10200 disassembler. Not ready,
+ but moving along nicely.
+
+Sun Dec 8 04:28:31 1996 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * Makefile.in (ALL_MACHINES): Add mips16-opc.o.
+
+Fri Dec 6 16:47:40 1996 J.T. Conklin <jtc@rhino.cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Revert change to use < and >
+ specifiers for fmovem* instructions.
+
+Fri Dec 6 14:48:09 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-dis.c (disassemble): Remove '$' register prefixing.
+
+Fri Dec 6 17:34:39 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips16-opc.c: Change opcode for entry/exit to avoid conflicting
+ with dsrl.
+
+Fri Dec 6 14:48:09 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c: Add some comments explaining the various
+ operands and such.
+
+ * mn10300-dis.c (disassemble): Fix minor gcc -Wall warnings.
+
+Thu Dec 5 12:09:48 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * m68k-dis.c (print_insn_arg): Handle new < and > operand
+ specifiers.
+
+ * m68k-opc.c (m68k_opcodes): Simplify table by using < and >
+ operand specifiers in fmovm* instructions.
+
+Wed Dec 4 14:52:18 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ppc-opc.c (insert_li): Give an error if the offset has the two
+ least significant bits set.
+
+Wed Nov 27 13:09:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_insn_mips16): Separate the instruction from
+ the arguments with a tab, not a space.
+
+Tue Nov 26 13:24:17 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-dis.c (disasemble): Finish conversion to '$' as
+ register prefix.
+
+ * mn10300-opc.c (mn10300_opcodes): Fix mask field for
+ mov am,(imm32,sp).
+
+Tue Nov 26 10:53:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.12.
+
+ Add support for mips16 (16 bit MIPS implementation):
+ * mips16-opc.c: New file.
+ * mips-dis.c: Include "elf-bfd.h" and "elf/mips.h".
+ (mips16_reg_names): New static array.
+ (print_insn_big_mips): Use print_insn_mips16 in 16 bit mode or
+ after seeing a 16 bit symbol.
+ (print_insn_little_mips): Likewise.
+ (print_insn_mips16): New static function.
+ (print_mips16_insn_arg): New static function.
+ * mips-opc.c: Add jalx instruction.
+ * Makefile.in (mips16-opc.o): New target.
+ * configure.in: Use mips16-opc.o for bfd_mips_arch.
+ * configure: Rebuild.
+
+Mon Nov 25 16:15:17 1996 J.T. Conklin <jtc@cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Simplify table by using < and >
+ operand specifiers in *save, *restore and movem* instructions.
+
+ * m68k-opc.c (m68k_opcodes): Fix move and movem instructions for
+ the coldfire.
+
+ * m68k-opc.c (m68k_opcodes): The coldfire (mcf5200) can only use
+ register operands for immediate arithmetic, not, neg, negx, and
+ set according to condition instructions.
+
+ * m68k-opc.c (m68k_opcodes): Consistantly Use "s" as the storage
+ specifier of the effective-address operand in immediate forms of
+ arithmetic instructions. The specifier for the immediate operand
+ notes how and where the constant will be stored.
+
+Mon Nov 25 11:17:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_opcodes): Remove redundant "lcc"
+ opcode.
+
+ * mn10300-dis.c (disassemble): Use '$' instead of '%' for
+ register prefix.
+
+ * mn10300-dis.c (disassemble): Prefix registers with '%'.
+
+Wed Nov 20 10:37:13 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-dis.c (disassemble): Handle register lists.
+
+ * mn10300-opc.c: Fix handling of register list operand for
+ "call", "ret", and "rets" instructions.
+
+ * mn10300-dis.c (disassemble): Print PC-relative and memory
+ addresses symbolically if possible.
+ * mn10300-opc.c: Distinguish between absolute memory addresses,
+ pc-relative offsets & random immediates.
+
+ * mn10300-dis.c (print_insn_mn10300): Fix fetch of last byte
+ in 7 byte insns.
+ (disassemble): Handle SPLIT and EXTENDED operands.
+
+Tue Nov 19 13:33:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-dis.c: Rough cut at printing some operands.
+
+ * mn10300-dis.c: Start working on disassembler support.
+ * mn10300-opc.c (mn10300_opcodes): Fix masks on several insns.
+
+ * mn10300-opc.c (mn10300_operands): Add "REGS" for a register
+ list.
+ (mn10300_opcodes): Use REGS for register list in "movm" instructions.
+
+Mon Nov 18 15:20:35 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * d10v-opc.c (d10v_opcodes): Add3 sets the carry.
+
+Fri Nov 15 13:43:19 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_opcodes): Demand parens around
+ register argument is calls and jmp instructions.
+
+Thu Nov 7 00:26:05 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_opcodes): Use DN01 for putx and
+ getx operand. Fix opcode for mulqu imm,dn.
+
+Wed Nov 6 13:42:32 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_operands): Hijack "bits" field
+ in MN10300_OPERAND_SPLIT operands for how many bits
+ appear in the basic insn word. Add IMM32_HIGH24,
+ IMM32_HIGH24_LOWSHIFT8, IMM8E_SHIFT8.
+ (mn10300_opcodes): Use new operands as needed.
+
+ * mn10300-opc.c (mn10300_operands): Add IMM32_LOWSHIFT8
+ for bset, bclr, btst instructions.
+ (mn10300_opcodes): Use new IMM32_LOWSHIFT8 as needed.
+
+ * mn10300-opc.c (mn10300_operands): Remove many redundant
+ operands. Update opcode table as appropriate.
+ (IMM32): Add MN10300_OPERAND_SPLIT flag.
+ (mn10300_opcodes): Fix single bit error in mov imm32,dn insn.
+
+Tue Nov 5 13:26:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_operands): Add DN2, DM2, AN2, AM2
+ operands (for indexed load/stores). Fix bitpos for DI
+ operand. Add SN8N_SHIFT8, IMM8_SHIFT8, and D16_SHIFT for the
+ few instructions that insert immediates/displacements in the
+ middle of the instruction. Add IMM8E for 8 bit immediate in
+ the extended part of an instruction.
+ (mn10300_operands): Use new opcodes as appropriate.
+
+Tue Nov 5 10:30:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (d10v_opcodes): Declare the trap instruction
+ sequential so the assembler never parallelizes it with
+ other instructions.
+
+Mon Nov 4 12:50:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_operands): Add DN01 and AN01 for
+ a data/address register that appears in register field 0
+ and register field 1.
+ (mn10300_opcodes): Use DN01 and AN01 for mov/cmp imm8,DN/AN
+
+Fri Nov 1 10:29:11 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha-dis.c (print_insn_alpha): Use new NOPAL mask for
+ standard disassembly.
+
+ * alpha-opc.c (alpha_operands): Rearrange flags slot.
+ (alpha_opcodes): Add new BWX, CIX, and MAX instructions.
+ Recategorize PALcode instructions.
+
+Wed Oct 30 16:46:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_opcodes): Add relaxing "jbr".
+
+Tue Oct 29 16:30:28 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (_print_insn_mips): Don't print a trailing tab if
+ there are no operand types.
+
+Tue Oct 29 12:22:21 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (D9_RELAX): Renamed from D9, all references
+ changed.
+ (v850_operands): Make sure D22 immediately follows D9_RELAX.
+
+Fri Oct 25 12:12:53 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386-dis.c (print_insn_x86): Set info->bytes_per_line to 5.
+
+Thu Oct 24 17:53:52 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (insert_d8_6): Fix operand insertion for sld.w
+ and sst.w instructions.
+
+ * v850-opc.c (v850_opcodes): Add "jCC" instructions (aliases for
+ "bCC"instructions).
+
+Thu Oct 24 17:21:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (_print_insn_mips): Use a tab between the instruction
+ and the arguments.
+
+Tue Oct 22 23:32:56 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * ppc-opc.c (PPCPWR2): Define.
+ (powerpc_opcodes): Use PPCPWR2 for fsqrt, rather than duplicating
+ it.
+
+Fri Oct 11 16:03:49 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_opcodes): Fix typo in opcode
+ field for movhu instruction.
+
+ * v850-dis.c (disassemble): For V850_OPERAND_SIGNED operands,
+ cast value to "long" not "signed long" to keep hpux10
+ compiler quiet.
+
+Thu Oct 10 10:25:58 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_opcodes): Fix typo in opcode field
+ for mov (abs16),DN.
+
+ * mn10300-opc.c (FMT*): Remove definitions.
+
+ * mn10300-opc.c (mn10300_opcodes): Fix destination register
+ for shift-by-register opcodes.
+
+ * mn10300-opc.c (mn10300_operands): Break DN, DM, AN, AM
+ into [AD][MN][01] for encoding the position of the register
+ in the opcode.
+
+Wed Oct 9 11:19:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_opcodes): Add "extended" instructions,
+ "putx", "getx", "mulq", "mulqu", "sat16", "sat24", "bsch".
+
+Tue Oct 8 11:55:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (mn10300_operands): Remove "REGS" operand.
+ Fix various typos. Add "PAREN" operand.
+ (MEM, MEM2): Define.
+ (mn10300_opcodes): Surround all memory addresses with "PAREN"
+ operands. Fix several typos.
+
+ * mn10300-opc.c (mn10300_opcodes): Fix typos in yesterday's
+ changes.
+
+Mon Oct 7 16:48:45 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10300-opc.c (FMT_XX): Renumber starting at one.
+ (mn10300_operands): Rough cut. Enough to parse "mov" instructions
+ at this time.
+ (mn10300_opcodes): Break opcode format out into its own field.
+ Update many operand fields to deal with signed vs unsigned
+ issues. Fix one or two typos in the "mov" instruction
+ opcode, mask and/or operand fields.
+
+Mon Oct 7 11:39:49 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-opc.c (plusha): Prefer encoding for m68040up, in case
+ m68851 wasn't reset.
+
+Thu Oct 3 17:17:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mn10300-opc.c (mn10300_opcodes): Add opcode & masks for
+ all opcodes. Very rough cut at operands for all opcodes.
+
+ * mn10300-opc.c (mn10300_opcodes): Start fleshing out the
+ opcode table.
+
+Thu Oct 3 10:06:07 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-opc.c, mn10300-opc.c: New files.
+ * mn10200-dis.c, mn10300-dis.c: New files.
+ * mn10x00-opc.c, mn10x00-dis.c: Deleted.
+ * disassemble.c: Break mn10x00 support into 10200 and 10300
+ support.
+ * configure.in: Likewise.
+ * configure: Rebuilt.
+
+Thu Oct 3 15:59:12 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (MOSTLYCLEAN): Move config.log to distclean.
+
+Wed Oct 2 23:28:42 1996 Jeffrey A Law (law@cygnus.com)
+
+ * mn10x00-opc.c, mn10x00-dis.c: New files for Matsushita
+ MN10x00 processors.
+ * disassemble (ARCH_mn10x00): Define.
+ (disassembler): Handle bfd_arch_mn10x00.
+ * configure.in: Recognize bfd_mn10x00_arch.
+ * configure: Rebuilt.
+
+Tue Oct 1 10:49:11 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386-dis.c (op_rtn): Change to be a pointer. Adjust uses
+ accordingly. Don't declare functions using op_rtn.
+
+Fri Sep 27 18:28:59 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * v850-dis.c (disassemble): Add memaddr argument. Re-arrange
+ params to be more standard.
+ * (disassemble): Print absolute addresses and symbolic names for
+ branch and jump targets.
+ * v850-opc.c (v850_operand): Add displacement flag to 9 and 22
+ bit operands.
+ * (v850_opcodes): Add breakpoint insn.
+
+Mon Sep 23 12:32:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Move the fmovemx data register cases before the
+ other cases, so that they get recognized before the data register
+ does gets treated as a degenerate register list.
+
+Tue Sep 17 12:06:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Add a case for "div" and "divu" with two registers
+ and a destination of $0.
+
+Tue Sep 10 16:12:39 1996 Fred Fish <fnf@rtl.cygnus.com>
+
+ * mips-dis.c (print_insn_arg): Add prototype.
+ (_print_insn_mips): Ditto.
+
+Mon Sep 9 14:26:26 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_insn_arg): Print condition code registers as
+ $fccN.
+
+Tue Sep 3 12:09:46 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Add setuw, setsw, setx.
+
+Tue Sep 3 12:05:25 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-dis.c (disassemble): Make static. Provide prototype.
+
+Sun Sep 1 22:30:40 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (insert_d9, insert_d22): Fix boundary case
+ in range checks.
+
+Sat Aug 31 01:27:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-dis.c (disassemble): Handle insertion of ',', '[' and
+ ']' characters into the output stream.
+ * v850-opc.c (v850_opcodes: Remove size field from all opcodes.
+ Add "memop" field to all opcodes (for the disassembler).
+ Reorder opcodes so that "nop" comes before "mov" and "jr"
+ comes before "jarl".
+
+ * v850-dis.c (print_insn_v850): Fix typo in last change.
+
+ * v850-dis.c (print_insn_v850): Properly handle disassembling
+ a two byte insn at the end of a memory region when the memory
+ region's size is only two byte aligned.
+
+ * v850-dis.c (v850_cc_names): Fix stupid thinkos.
+
+ * v850-dis.c (v850_reg_names): Define.
+ (v850_sreg_names, v850_cc_names): Likewise.
+ (disassemble): Very rough cut at printing operands (unformatted).
+
+ * v850-opc.c (BOP_MASK): Fix.
+ (v850_opcodes): Fix mask for jarl and jr.
+
+ * v850-dis.c: New file. Skeleton for disassembler support.
+ * Makefile.in Remove v850 references, they're not needed here.
+ * configure.in: Add v850-dis.o when building v850 toolchains.
+ * configure: Rebuilt.
+ * disassemble.c (disassembler): Call v850 disassembler.
+
+ * v850-opc.c (insert_d8_7, extract_d8_7): New functions.
+ (insert_d8_6, extract_d8_6): New functions.
+ (v850_operands): Rename D7S to D7; operand for D7 is unsigned.
+ Rename D8 to D8_7, use {insert,extract}_d8_7 routines.
+ Add D8_6.
+ (IF4A, IF4B): Use "D7" instead of "D7S".
+ (IF4C, IF4D): Use "D8_7" instead of "D8".
+ (IF4E, IF4F): New. Use "D8_6".
+ (v850_opcodes): Use IF4A/IF4B for sld.b/sst.b. Use IF4C/IF4D for
+ sld.h/sst.h. Use IF4E/IF4F for sld.w/sst.w.
+
+ * v850-opc.c (insert_d16_15, extract_d16_15): New functions.
+ (v850_operands): Change D16 to D16_15, use special insert/extract
+ routines. New new D16 that uses the generic insert/extract code.
+ (IF7A, IF7B): Use D16_15.
+ (IF7C, IF7D): New. Use D16.
+ (v850_opcodes): Use IF7C and IF7D for ld.b and st.b.
+
+ * v850-opc.c (insert_d9, insert_d22): Slightly improve error
+ message. Issue an error if the branch offset is odd.
+
+ * v850-opc.c: Add notes about needing special insert/extract
+ for all the load/store insns, except "ld.b" and "st.b".
+
+ * v850-opc.c (insert_d22, extract_d22): New functions.
+ (v850_operands): Use insert_d22 and extract_d22 for
+ D22 operands.
+ (insert_d9): Fix range check.
+
+Fri Aug 30 18:01:02 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * v850-opc.c (v850_operands): Add V850_OPERAND_SIGNED flag
+ and set bits field to D9 and D22 operands.
+
+Thu Aug 29 11:10:46 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_operands): Define SR2 operand.
+ (v850_opcodes): "ldsr" uses R1,SR2.
+
+ * v850-opc.c (v850_opcodes): Fix opcode specs for
+ sld.w, sst.b, sst.h, sst.w, and nop.
+
+Wed Aug 28 15:55:43 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_opcodes): Add null opcode to mark the
+ end of the opcode table.
+
+Mon Aug 26 13:35:53 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (pre_defined_registers): Added register pairs,
+ "r0-r1", "r2-r3", etc.
+
+Fri Aug 23 00:27:01 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_operands): Make I16 be a signed operand.
+ Create I16U for an unsigned 16bit mmediate operand.
+ (v850_opcodes): Use I16U for "ori", "andi" and "xori".
+
+ * v850-opc.c (v850_operands): Define EP operand.
+ (IF4A, IF4B, IF4C, IF4D): Use EP.
+
+ * v850-opc.c (v850_opcodes): Fix opcode numbers for "mov"
+ with immediate operand, "movhi". Tweak "ldsr".
+
+ * v850-opc.c (v850_opcodes): Get ld.[bhw] and st.[bhw]
+ correct. Get sld.[bhw] and sst.[bhw] closer.
+
+ * v850-opc.c (v850_operands): "not" is a two byte insn
+
+ * v850-opc.c (v850_opcodes): Correct bit pattern for setf.
+
+ * v850-opc.c (v850_operands): D16 inserts at offset 16!
+
+ * v850-opc.c (two): Get order of words correct.
+
+ * v850-opc.c (v850_operands): I16 inserts at offset 16!
+
+ * v850-opc.c (v850_operands): Add "SR1" and "SR2" for system
+ register source and destination operands.
+ (v850_opcodes): Use SR1 and SR2 for "ldsr" and "stsr".
+
+ * v850-opc.c (v850_opcodes): Fix thinko in "jmp" opcode. Fix
+ same thinko in "trap" opcode.
+
+ * v850-opc.c (v850_opcodes): Add initializer for size field
+ on all opcodes.
+
+ * v850-opc.c (v850_operands): D6 -> DS7. References changed.
+ Add D8 for 8-bit unsigned field in short load/store insns.
+ (IF4A, IF4D): These both need two registers.
+ (IF4C, IF4D): Define. Use 8-bit unsigned field.
+ (v850_opcodes): For "sld.h", "sld.w", "sst.h", "sst.w", use
+ IF4C & IF4D. For "trap" use I5U, not I5. Add IF1 operand
+ for "ldsr" and "stsr".
+ * v850-opc.c (v850_operands): 3-bit immediate for bit insns
+ is unsigned.
+
+ * v850-opc.c (v850_opcodes): Correct short store half (sst.h) and
+ short store word (sst.w).
+
+Thu Aug 22 16:57:27 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * v850-opc.c (v850_operands): Added insert and extract fields,
+ pointers to functions that handle unusual operand encodings.
+
+Thu Aug 22 01:05:24 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_opcodes): Enable "trap".
+
+ * v850-opc.c (v850_opcodes): Fix order of displacement
+ and register for "set1", "clr1", "not1", and "tst1".
+
+Wed Aug 21 18:46:26 1996 Jeffrey A Law (law@cygnus.com)
+
+ * v850-opc.c (v850_operands): Add "B3" support.
+ (v850_opcodes): Fix and enable "set1", "clr1", "not1"
+ and "tst1".
+
+ * v850-opc.c (v850_opcodes): "jmp" has only an R1 operand.
+
+ * v850-opc.c: Close unterminated comment.
+
+Wed Aug 21 17:31:26 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * v850-opc.c (v850_operands): Add flags field.
+ (v850_opcodes): add move opcodes.
+
+Tue Aug 20 14:41:03 1996 J.T. Conklin <jtc@hippo.cygnus.com>
+
+ * Makefile.in (ALL_MACHINES): Add v850-opc.o.
+ * configure: (bfd_v850v_arch) Add new case.
+ * configure.in: (bfd_v850_arch) Add new case.
+ * v850-opc.c: New file.
+
+Mon Aug 19 15:21:38 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): Handle little endian sparcs.
+
+Thu Aug 15 13:14:43 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c: Add additional information to the opcode
+ table to help determinine which instructions can be done
+ in parallel.
+
+Thu Aug 15 13:11:13 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Update editing of include pathnames to be
+ more general.
+
+Thu Aug 15 16:28:41 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * arm-opc.h: Added "bx" instruction definition.
+
+Wed Aug 14 17:00:04 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha-opc.c (EV4EXTHWINDEX): Field width should be 8 not 5.
+
+Mon Aug 12 14:30:37 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (d10v_opcodes): Minor fixes to addi and bl.l.
+
+Fri Aug 9 13:21:59 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (d10v_opcodes): Correct 'mv' unit entry to EITHER.
+
+Thu Aug 8 12:43:52 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: Update for alpha-opc changes.
+
+Wed Aug 7 11:55:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386-dis.c (print_insn_i386): Actually return the correct value.
+ (ONE, OP_ONE): #ifdef out; not used.
+
+Fri Aug 2 17:47:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (d10v_opcodes): Added 2 accumulator sub instructions.
+ Changed subi operand type to treat 0 as 16.
+
+Wed Jul 31 16:21:41 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Add cpushl for the mcf5200. From Ken Rose
+ <rose@netcom.com>.
+
+Wed Jul 31 14:39:27 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * arm-opc.h: (arm_opcodes): Added halfword and sign-extension
+ memory transfer instructions. Add new format string entries %h and %s.
+ * arm-dis.c: (print_insn_arm): Provide decoding of the new
+ formats %h and %s.
+
+Fri Jul 26 11:45:04 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c (d10v_operands): Added UNUM4S; a 4-bit accumulator shift.
+ (d10v_opcodes): Modified accumulator shift instructions to use UNUM4S.
+
+Fri Jul 26 14:01:43 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * alpha-dis.c (print_insn_alpha_osf): Remove.
+ (print_insn_alpha_vms): Remove.
+ (print_insn_alpha): Make globally visible. Chose the register
+ names based on info->flavour.
+ * disassemble.c: Always return print_insn_alpha for the alpha.
+
+Thu Jul 25 15:24:17 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-dis.c (dis_long): Handle unknown opcodes.
+
+Thu Jul 25 12:08:09 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-opc.c: Changes to support signed and unsigned numbers.
+ All instructions with the same name that have long and short forms
+ now end in ".l" or ".s". Divs added.
+ * d10v-dis.c: Changes to support signed and unsigned numbers.
+
+Tue Jul 23 11:02:53 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * d10v-dis.c: Change all functions to use info->print_address_func.
+
+Mon Jul 22 15:38:53 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-opc.c (m68k_opcodes): Make opcode masks for the ColdFire
+ move ccr/sr insns more strict so that the disassembler only
+ selects them when the addressing mode is data register.
+
+Mon Jul 22 11:25:24 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+ * d10v-opc.c (pre_defined_registers): Declare.
+ * d10v-dis.c (print_operand): Now uses pre_defined_registers
+ to pick a better name for the registers.
+
+Mon Jul 22 13:47:23 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc-opc.c: Fix opcode values for fpack16, and fpackfix. Fix
+ operands for fexpand and fpmerge. From Christian Kuehnke
+ <Christian.Kuehnke@arbi.informatik.uni-oldenburg.de>.
+
+Mon Jul 22 13:17:06 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha-dis.c (print_insn_alpha): No longer the user-visible
+ print routine. Take new regnames and cpumask arguments.
+ Kill the environment variable nonsense.
+ (print_insn_alpha_osf): New function. Do OSF/1 style regnames.
+ (print_insn_alpha_vms): New function. Do VMS style regnames.
+ * disassemble.c (disassembler): Test bfd flavour to pick
+ between OSF and VMS routines. Default to OSF.
+
+Thu Jul 18 17:19:34 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_SUBST (INSTALL_SHLIB).
+ * configure: Rebuild.
+ * Makefile.in (install): Use @INSTALL_SHLIB@.
+
+Wed Jul 17 14:39:05 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
+
+ * configure: (bfd_d10v_arch) Add new case.
+ * configure.in: (bfd_d10v_arch) Add new case.
+ * d10v-dis.c: New file.
+ * d10v-opc.c: New file.
+ * disassemble.c (disassembler) Add entry for d10v.
+
+Wed Jul 17 10:12:05 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Fix bugs in coldfire insns relating
+ to bcc, trapfl, subxl, and wddata discovered by Andreas Schwab.
+
+Mon Jul 15 16:59:55 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * i386-dis.c: Get rid of print_insn_i8086. Use info.mach to
+ distinguish between variants of the instruction set.
+ * sparc-dis.c: Get rid of print_insn_sparclite. Use info.mach to
+ distinguish between variants of the instruction set.
+
+Fri Jul 12 10:12:01 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * i386-dis.c (print_insn_i8086): New routine to disassemble using
+ the 8086 instruction set.
+ * i386-dis.c: General cleanups. Make most things static. Add
+ prototypes. Get rid of static variables aflags and dflags. Pass
+ them as args (to almost everything).
+
+Thu Jul 11 11:58:44 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300-dis.c (bfd_h8_disassemble): Handle macregs in ldmac insns.
+
+ * h8300-dis.c (bfd_h8_disassemble): Handle "ldm.l" and "stm.l".
+
+ * h8300-dis.c (bfd_h8_disassemble): "abs" is implicitly two
+ if the next arg is marked with SRC_IN_DST. Gross.
+
+ * h8300-dis.c (bfd_h8_disassemble): Print "exr" when
+ we're looking for and find EXR.
+
+ * h8300-dis.c (bfd_h8_disassemble): We don't have a match
+ if we're looking for KBIT and we don't find it.
+
+ * h8300-dis.c (bfd_h8_disassemble): Mask off unwanted bits
+ for L_3 and L_2.
+
+ * h8300-dis.c (bfd_h8_disassemble): Don't set plen for
+ 3bit immediate operands.
+
+Tue Jul 9 10:55:20 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Released binutils 2.7.
+
+ * alpha-opc.c: Add new case of "mov". From Klaus Kaempf
+ <kkaempf@progis.ac-net.de>.
+
+Thu Jul 4 11:42:51 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * alpha-opc.c: Correct second case of "mov" to use OPRL.
+
+Wed Jul 3 16:03:47 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * sparc-dis.c (print_insn_sparclite): New routine to print
+ sparclite instructions.
+
+Wed Jul 3 14:21:18 1996 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Add coldfire support.
+
+Fri Jun 28 15:53:51 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (asi_table): Add #ASI_N, #ASI_N_L, #ASI_NUCLEUS,
+ #ASI_NUCLEUS_LITTLE. Rename #ASI_AS_IF_USER_{PRIMARY,SECONDARY}_L
+ to #ASI_AS_IF_USER_{PRIMARY,SECONDARY}_LITTLE.
+
+Tue Jun 25 22:58:31 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir):
+ Use autoconf-set values.
+ (docdir, oldincludedir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+
+Fri Jun 21 13:53:36 1996 Richard Henderson <rth@tamu.edu>
+
+ * alpha-opc.c: New file.
+ * alpha-opc.h: Remove.
+ * alpha-dis.c: Complete rewrite to use new opcode table.
+ * configure.in: For bfd_alpha_arch, use alpha-opc.o.
+ * configure: Rebuild with autoconf 2.10.
+ * Makefile.in (ALL_MACHINES): Add alpha-opc.o.
+ (alpha-dis.o): Depend upon $(INCDIR)/opcode/alpha.h, not
+ alpha-opc.h.
+ (alpha-opc.o): New target.
+
+Wed Jun 19 15:55:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): Remove unused local variable i.
+ Set imm_added_to_rs1 even if the source and destination register
+ are not the same.
+
+ * sparc-opc.c: Add some two operand forms of the wr instruction.
+
+Tue Jun 18 15:58:27 1996 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * h8300-dis.c (bfd_h8_disassemble): Rename "hmode" argument
+ to just "mode".
+
+ * disassemble.c (disassembler): Handle H8/S.
+ * h8300-dis.c (print_insn_h8300s): New function for H8/S.
+
+Tue Jun 18 18:06:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc-opc.c: Add beq/teq as aliases for be/te.
+
+ * ppc-opc.c: Fix fcmpo opcode. From Sergei Steshenko
+ <sergei@msil.sps.mot.com>.
+
+Tue Jun 18 15:08:54 1996 Klaus Kaempf <kkaempf@progis.de>
+
+ * makefile.vms: New file.
+
+ * alpha-dis.c (print_insn_alpha): Print lda ra,lit(rz) as mov.
+
+Mon Jun 10 18:50:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * h8300-dis.c (bfd_h8_disassemble): Always print ABS8MEM with :8,
+ regardless of plen.
+
+Tue Jun 4 09:15:53 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * i386-dis.c (OP_OFF): Call append_prefix.
+
+Thu May 23 15:18:23 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (instruction encoding macros): Add explicit casts to
+ unsigned long to silence a warning from the Solaris PowerPC
+ compiler.
+
+Thu Apr 25 19:33:32 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Add ultrasparc vis extensions.
+
+Mon Apr 22 17:12:35 1996 Doug Evans <dje@blues.cygnus.com>
+
+ * sparc-dis.c (X_IMM,X_SIMM): New macros.
+ (X_IMM13): Delete.
+ (print_insn_sparc): Merge cases i,I,j together. New cases X,Y.
+ * sparc-opc.c (sparc_opcodes): Use X for 5 bit shift constants,
+ Y for 6 bit shift constants. Rewrite entries for crdcxt, cwrcxt,
+ cpush, cpusha, cpull sparclet insns.
+
+Wed Apr 17 14:20:22 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-dis.c (compute_arch_mask): Replace ANSI style def with K&R.
+
+Thu Apr 11 17:30:02 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * sparc-opc.c: Set F_FBR on floating point branch instructions.
+ Set F_FLOAT on other floating point instructions.
+
+Mon Apr 8 17:02:48 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (PPC860): Macro for 860/821 specific instructions and
+ registers.
+ (powerpc_opcodes): Add 860/821 specific SPRs.
+
+Mon Apr 8 14:00:44 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Permit --enable-shared to specify a list of
+ directories. Set and substitute BFD_PICLIST.
+ * configure: Rebuild.
+ * Makefile.in (BFD_PICLIST): Rename from BFD_LIST. Change all
+ uses. Set to @BFD_PICLIST@.
+
+Fri Apr 5 17:12:27 1996 Jeffrey A Law (law@cygnus.com)
+
+ * h8300-dis.c (bfd_h8_disassemble): Use "bit" for L_3 immediates,
+ not "abs", which may be needed for the absolute in something
+ like btst #0,@10:8. Print L_3 immediates separately from other
+ immediates. Change ABSMOV reference to ABS8MEM.
+
+Wed Apr 3 10:40:45 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-dis.c (opcodes_initialized): Move inside print_insn_sparc.
+ (current_arch_mask): New static global.
+ (compute_arch_mask): New static function.
+ (print_insn_sparc): Delete sparc_v9_p. New static local
+ current_mach. Resort opcode table if current_mach changes.
+ Generalize "insn not supported" test.
+ (compare_opcodes): Prefer supported opcodes to nonsupported ones.
+ Delete test for v9/!v9.
+ * sparc-opc.c (MASK_*): Use SPARC_OPCODE_ARCH_MASK.
+ (v6notlet): Define.
+ (brfc): Split into CBR and FBR for coprocessor/fp branches.
+ (brfcx): Renamed to FBRX.
+ (condfc): Renamed to CONDFC. Pass v6notlet to CBR (standard
+ coprocessor mnemonics are not supported on the sparclet).
+ (condf): Renamed to CONDF.
+ (SLCBCC2): Delete F_ALIAS flag.
+
+Sat Mar 30 21:45:59 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): rd must be 0 for
+ mov foo,{%y,%psr,%wim,%tbr}. Support mov foo,%asrX.
+
+Fri Mar 29 13:02:40 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (config.status): Depend upon BFD VERSION file, so
+ that the shared library version number is set correctly.
+
+Tue Mar 26 15:47:14 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Use AC_CHECK_TOOL to find ar and ranlib. From
+ Miles Bader <miles@gnu.ai.mit.edu>.
+ * configure: Rebuild.
+
+Sat Mar 16 13:04:07 1996 Fred Fish <fnf@cygnus.com>
+
+ * z8kgen.c (internal, gas): Call xmalloc rather than unchecked
+ malloc.
+
+Tue Mar 12 12:14:10 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.8.
+
+Thu Mar 7 15:11:10 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): Handle 'O' operand char like 'r'.
+ * sparc-opc.c (sparc_opcodes): Use 'O' operand char for `neg reg'.
+
+Tue Mar 5 15:51:57 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Don't set SHLIB or SHLINK to an empty string,
+ since they appear as targets in Makefile.in.
+ * configure: Rebuild.
+
+Mon Feb 26 13:03:40 1996 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-make.sed: Edit out shared library support bits.
+
+Tue Feb 20 20:48:28 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-opc.c (v8,v6notv9): Add MASK_SPARCLET.
+ (sparc_opcode_archs): Add MASK_V8 to sparclet entry.
+ (sparc_opcodes): Add sparclet insns.
+ (sparclet_cpreg_table): New static local.
+ (sparc_{encode,decode}_sparclet_cpreg): New functions.
+ * sparc-dis.c (print_insn_sparc): Handle sparclet cpregs.
+
+Tue Feb 20 11:02:44 1996 Alan Modra <alan@mullet.Levels.UniSA.Edu.Au>
+
+ * i386-dis.c (index16): New static variable.
+ (putop): Print jecxz for 32 bit case, jcxz for 16 bit, not the
+ other way around.
+ (OP_indirE): Return result of OP_E.
+ (OP_E): Check for 16 bit addressing mode, and disassemble
+ correctly. Optimised 32 bit case a little. Don't print
+ "(base,index,scale)" when sib specifies only an offset.
+
+Mon Feb 19 12:32:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Set and substitute SHLIB_DEP.
+ * configure: Rebuild.
+ * Makefile.in (SHLIB_DEP): New variable.
+ (LIBIBERTY_LISTS, BFD_LIST): New variables.
+ (stamp-piclist): Depend upon LIBIBERTY_LISTS and BFD_LIST. If
+ COMMON_SHLIB, add them to piclist with appropriate modifications.
+ ($(SHLIB)): Depend upon $(SHLIB_DEP). Don't check COMMON_SHLIB
+ here: just use piclist.
+
+Mon Feb 19 02:03:50 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-dis.c (MASK_V9,V9_ONLY_P,V9_P): Define.
+ (print_insn_sparc): Rewrite v9/not-v9 tests.
+ (compare_opcodes): Likewise.
+ * sparc-opc.c (MASK_<ARCH>): Define.
+ (v6,v7,v8,sparclite,v9,v9a): Redefine.
+ (sparclet,v6notv9): Define.
+ (sparc_opcode_archs): Delete member `conflicts'. Add `supported'.
+ (sparc_opcodes): Delete F_NOTV9, use v6notv9 instead.
+
+Thu Feb 15 14:45:05 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_PROG_CC before configure.host.
+ * configure: Rebuild.
+
+ * Makefile.in (SONAME): Remove leading ../bfd/ from $(SHLIB).
+
+Wed Feb 14 19:01:27 1996 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * i386-dis.c (onebyte_has_modrm): New static array.
+ (twobyte_has_modrm): New static array.
+ (print_insn_i386): Only fetch the mod/reg/rm byte if it is needed.
+
+Tue Feb 13 15:15:01 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in ($(SHLINK)): Check ts against $(SHLIB), not
+ $(SHLINK).
+
+Mon Feb 12 16:26:06 1996 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (PPC): Undef, so default defination on Windows NT
+ doesn't conflict.
+
+Wed Feb 7 13:59:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): The bkpt instruction is supported on
+ m68010up, not just m68020up | cpu32.
+
+ * Makefile.in (SONAME): New variable.
+ ($(SHLINK)): Make a link to the transformed name, as well.
+ (stamp-tshlink): New target.
+ (install): Skip stamp-tshlink during install.
+
+Tue Feb 6 12:28:54 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_ARG_PROGRAM.
+ * configure: Rebuild.
+ * Makefile.in (program_transform_name): New variable.
+ (install): Transform library name before installing it.
+
+Mon Feb 5 16:14:42 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i960-dis.c (mem): Add HX dcinva instruction.
+
+ Support for building as a shared library, based on patches from
+ Alan Modra <alan@spri.levels.unisa.edu.au>:
+ * configure.in: Add AC_ARG_ENABLE for shared and commonbfdlib.
+ New substitutions: ALLLIBS, PICFLAG, SHLIB, SHLIB_CC,
+ SHLIB_CFLAGS, COMMON_SHLIB, SHLINK.
+ * configure: Rebuild.
+ * Makefile.in (ALLLIBS): New variable.
+ (PICFLAG, SHLIB, SHLIB_CC, SHLIB_CFLAGS): New variables.
+ (COMMON_SHLIB, SHLINK): New variables.
+ (.c.o): If PICFLAG is set, compile twice, once PIC, once normal.
+ (STAGESTUFF): Remove variable.
+ (all): Depend upon $(ALLLIBS) rather than $(TARGETLIB).
+ (stamp-piclist, piclist): New targets.
+ ($(SHLIB), $(SHLINK)): New targets.
+ ($(OFILES)): Depend upon stamp-picdir.
+ (disassemble.o): Build twice if PICFLAG is set.
+ (MOSTLYCLEAN): Add pic/*.o.
+ (clean): Remove $(SHLIB), $(SHLINK), piclist, and stamp-piclist.
+ (distclean): Remove pic and stamp-picdir.
+ (install): Install shared libraries.
+ (stamp-picdir): New target.
+
+Fri Feb 2 17:15:25 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): Delete DISASM_RAW_INSN support.
+ Print unknown instruction as "unknown", rather than in hex.
+
+Tue Jan 30 14:06:08 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * dis-buf.c: Include "sysdep.h" before "dis-asm.h".
+
+Thu Jan 25 20:24:07 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-opc.c (sparc_opcode_archs): Mark v8/sparclite as conflicting.
+
+Thu Jan 25 11:56:49 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * i386-dis.c (print_insn_i386): Only fetch the mod/reg/rm byte
+ when necessary. From Ulrich Drepper
+ <drepper@myware.rz.uni-karlsruhe.de>.
+
+Thu Jan 25 03:39:10 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): NUMOPCODES replaced with
+ sparc_num_opcodes. Update architecture enum values.
+ * sparc-opc.c (sparc_opcode_archs): Replaces architecture_pname.
+ (sparc_opcode_lookup_arch): New function.
+ (sparc_num_opcodes): Renamed from bfd_sparc_num_opcodes.
+ (sparc_opcodes): Add v9a shutdown insn.
+
+Mon Jan 22 08:29:59 1996 Doug Evans <dje@charmed.cygnus.com>
+
+ * sparc-dis.c (print_insn_sparc): Renamed from print_insn.
+ If DISASM_RAW_INSN, print insn in hex. Handle v9a as opcode
+ architecture.
+ (print_insn_sparc64): Deleted.
+ * disassemble.c (disassembler, case bfd_arch_sparc): Always use
+ print_insn_sparc.
+
+ * sparc-opc.c (architecture_pname): Add v9a.
+
+Fri Jan 12 14:35:58 1996 David Mosberger-Tang <davidm@AZStarNet.com>
+
+ * alpha-opc.h (alpha_insn_set): VAX floating point opcode was
+ incorrectly defined as 0x16 when it should be 0x15.
+ (FLOAT_FORMAT_MASK): function code is 11 bits, not just 7 bits!
+ (alpha_insn_set): added cvtst and cvttq float ops. Also added
+ excb (exception barrier) which is defined in the Alpha
+ Architecture Handbook version 2.
+ * alpha-dis.c (print_insn_alpha): Fixed special-case decoding for
+ OPERATE_FORMAT_CODE type instructions. The bug caused mulq to be
+ disassembled as or, for example.
+
+Wed Jan 10 12:37:22 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-dis.c (print_insn_arg): Print cases 'i' and 'u' in hex.
+ (_print_insn_mips): Change i from int to unsigned int.
+
+Thu Jan 4 17:21:10 1996 David Edelsohn <edelsohn@mhpcc.edu>
+
+ * ppc-opc.c (powerpc_opcodes): tlbi POWER opcode form different
+ from tlbie PowerPC opcode. Add PPC603 tlbld and tlbli.
+
+Thu Dec 28 13:29:19 1995 John Hassey <hassey@rtp.dg.com>
+
+ * i386-dis.c: Added Pentium Pro instructions.
+
+Tue Dec 19 22:56:35 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (fsqrt{,.}): Duplicate for PowerPC in addition to
+ being for Power2.
+
+Fri Dec 15 14:14:15 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * sh-opc.h (sh_nibble_type): Added REG_B.
+ (sh_arg_type): Added A_REG_B.
+ (sh_table): Added pref and bank reg versions of ldc, ldc.l, stc
+ and stc.l opcodes.
+ * sh-dis.c (print_insn_shx): Added cases for REG_B and A_REG_B.
+
+Fri Dec 15 16:44:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * disassemble.c (disassembler): Use new bfd_big_endian macro.
+
+Tue Dec 12 12:22:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Remove stamp-h. From Ronald
+ F. Guilmette <rfg@monkeys.com>.
+
+Tue Dec 5 13:42:44 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ From David Mosberger-Tang <davidm@azstarnet.com>:
+ * alpha-dis.c (print_insn_alpha): fixed decoding of cpys
+ instruction.
+
+Mon Dec 4 12:29:05 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * sh-opc.h (sh_arg_type): Added A_SSR and A_SPC.
+ (sh_table): Added many SH3 opcodes.
+ * sh-dis.c (print_insn_shx): Added cases for A_SSR and A_SPC.
+
+Fri Dec 1 07:42:18 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (subfc., subfco): Mark this PPCCOM, not PPC.
+ (subco,subco.): Mark this PPC, not PPCCOM.
+
+Mon Nov 27 13:09:52 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.7.
+
+Tue Nov 21 18:28:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild with autoconf 2.6.
+
+Wed Nov 15 19:02:53 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * configure.in: Sort list of architectures. Accept but do nothing
+ for alliant, convex, pyramid, romp, and tahoe.
+
+Wed Nov 8 20:18:59 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * a29k-dis.c (print_special): Change num to unsigned int.
+
+Wed Nov 8 20:10:35 1995 Eric Freudenthal <freudenthal@nyu.edu>
+
+ * a29k-dis.c (print_insn): Cast insn24 to unsigned long when
+ shifting it.
+
+Tue Nov 7 15:21:06 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Call AC_CHECK_PROG to find and cache AR.
+ * configure: Rebuilt.
+
+Mon Nov 6 17:39:47 1995 Harry Dolan <dolan@ssd.intel.com>
+
+ * configure.in: Add case for bfd_i860_arch.
+ * configure: Rebuild.
+
+Fri Nov 3 12:45:31 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c (m68k_opcodes): Correct fmoveml operands.
+ * m68k-dis.c (NEXTSINGLE): Change i to unsigned int.
+ (NEXTDOUBLE): Likewise.
+ (print_insn_m68k): Don't match fmoveml if there is more than one
+ register in the list.
+ (print_insn_arg): Handle a place of '8' for a type of 'L'.
+
+Thu Nov 2 23:06:33 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Use #W rather than #w.
+ * m68k-dis.c (print_insn_arg): Handle new 'W' place.
+
+Wed Nov 1 13:30:24 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c (m68k_opcode_aliases): Add dbfw as an alias for dbf,
+ and likewise for all the dbxx opcodes.
+
+Mon Oct 30 20:50:40 1995 Fred Fish <fnf@cygnus.com>
+
+ * arc-dis.c: Include elf-bfd.h rather than libelf.h.
+
+Mon Oct 23 11:11:34 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * mips-opc.c: Added shorthand (V1) for INSN_4100 manifest. Added
+ the VR4100 specific instructions to the mips_opcodes structure.
+
+Thu Oct 19 11:05:23 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in, mpw-make.sed: Remove ugly workaround for
+ ugly Metrowerks bug in CW6, is fixed in CW7.
+
+Mon Oct 16 12:59:01 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (whole file): Add flags for common/any support.
+
+Tue Oct 10 11:06:07 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (BISON): Remove macro.
+ (FLAGS_TO_PASS): Remove BISON.
+
+Fri Oct 6 16:26:45 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ Mon Sep 25 22:49:32 1995 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k-dis.c (print_insn_m68k): Recognize all two-word
+ instructions that take no args by looking at the match mask.
+ (print_insn_arg): Always print "%" before register names.
+ [case 'c']: Use "nc" for the no-cache case, as recognized by gas.
+ [case '_']: Don't print "@#" before address.
+ [case 'J']: Use "%s" as format string, not register name.
+ [case 'B']: Treat place == 'C' like 'l' and 'L'.
+
+Thu Oct 5 22:16:20 1995 Ken Raeburn <raeburn@cygnus.com>
+
+ * i386-dis.c: Describe cmpxchg8b operand, and spell the opcode
+ name correctly.
+
+Tue Oct 3 08:30:20 1995 steve chamberlain <sac@slash.cygnus.com>
+
+ From David Mosberger-Tang <davidm@azstarnet.com>
+
+ * alpha-opc.h (MEMORY_FUNCTION_FORMAT_MASK): added.
+ (alpha_insn_set): added definitions for VAX floating point
+ instructions (Unix compilers don't generate these, but handcoded
+ assembly might still use them).
+
+ * alpha-dis.c (print_insn_alpha): added support for disassembling
+ the miscellaneous instructions in the Alpha instruction set.
+
+Tue Sep 26 18:47:20 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add m68k-opc.c.o to BFD_MACHINES for m68k,
+ no longer create sysdep.h, sed ppc-opc.c to work around a
+ serious Metrowerks C bug.
+ * mpw-make.in: Remove.
+ * mpw-make.sed: New file, used by mpw-configure to edit
+ Makefile.in into an MPW makefile.
+
+Wed Sep 20 12:55:28 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New synonym for realclean.
+
+Tue Sep 19 15:28:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: Split pmove patterns which use 'P' into patterns
+ which use '0', '1', and '2' instead. Specify the proper size for
+ a pmove immediate operand. Correct the pmovefd patterns to be
+ moves to a register, not from a register.
+ * m68k-dis.c (print_insn_arg): Replace 'P' with '0', '1', '2'.
+
+Thu Sep 14 11:58:22 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Mark all insns that reference
+ %psr, %wim, %tbr as F_NOTV9.
+
+Fri Sep 8 01:07:38 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (Makefile): Just rebuild Makefile when running
+ config.status.
+ (config.h, stamp-h): New targets.
+ * configure.in: Call AC_CONFIG_HEADER and AC_CANONICAL_SYSTEM
+ earlier. Don't bother to call AC_ARG_PROGRAM. Touch stamp-h when
+ rebuilding config.h.
+ * configure: Rebuild.
+
+ * mips-opc.c: Change unaligned loads and stores with "t,A"
+ operands to use "t,A(b)".
+
+Thu Sep 7 19:02:46 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-dis.c (print_insn_shx): Add F_FR0 support.
+
+Thu Sep 7 19:02:46 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-dis.c (print_insn_shx): Change loop over op->arg[n] to iterate
+ until 3 instead of until 2.
+
+Wed Sep 6 21:21:33 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (ALL_CFLAGS): Define.
+ (.c.o, disassemble.o): Use $(ALL_CFLAGS).
+ (MOSTLYCLEAN): Add config.log.
+ (distclean): Don't remove config.log.
+ * configure.in: Substitute HDEFINES.
+ * configure: Rebuild.
+
+Wed Sep 6 15:08:09 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-opc.h (sh_arg_type): Add F_FR0.
+ (sh_table, case fmac): Add F_FR0 as first argument.
+
+Wed Sep 6 15:08:09 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-opc.h (sh_opcode_info): Increase arg array size to 4.
+
+Tue Sep 5 18:28:10 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-dis.c: Remove all references to NO_V9.
+
+Tue Sep 5 20:03:26 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * aclocal.m4: Just include ../bfd/aclocal.m4.
+ * configure: Rebuild.
+
+Tue Sep 5 16:09:59 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-dis.c (X_DISP19): Define.
+ (print_insn, case 'G'): Use it.
+ (print_insn, case 'L'): Sign extend displacement.
+
+Mon Sep 4 14:28:46 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Run ../bfd/configure.host before AC_PROG_CC.
+ Subsitute CFLAGS and AR. Call AC_PROG_INSTALL. Don't substitute
+ host_makefile_frag or frags.
+ * aclocal.m4: New file.
+ * configure: Rebuild.
+ * Makefile.in (INSTALL): Set to @INSTALL@.
+ (INSTALL_PROGRAM): Set to @INSTALL_PROGRAM@.
+ (INSTALL_DATA): Set to @INSTALL_DATA@.
+ (AR): Set to @AR@.
+ (AR_FLAGS): Set to rc rather than qc.
+ (CC): Define as @CC@.
+ (CFLAGS): Set to @CFLAGS@.
+ (@host_makefile_frag@): Remove.
+ (config.status): Remove dependency upon @frags@.
+
+ * configure.in: ../bfd/config.bfd now just sets shell variables.
+ Use them rather than looking through target Makefile fragments.
+ * configure: Rebuild.
+
+Thu Aug 31 12:35:32 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-opc.h (ftrc): Change FPUL_N to FPUL_M.
+
+Wed Aug 30 13:52:28 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sparc_opcodes): Delete duplicate wr %y insn.
+ Add clrx, iprefetch, signx, clruw, cas, casl, casx, casxl synthetic
+ sparc64 insns.
+
+ * sparc-opc.c (sparc_opcodes): Fix prefetcha insn.
+ (lookup_{name,value}): New functions.
+ (prefetch_table): New static local.
+ (sparc_{encode,decode}_prefetch): New functions.
+ * sparc-dis.c (print_insn): Handle '*' arg (prefetch function).
+
+Wed Aug 30 11:11:58 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-opc.h: Add blank lines to improve readabililty of sh3e
+ instructions.
+
+Wed Aug 30 11:09:38 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-dis.c: Correct comment on first line of file.
+
+Tue Aug 29 15:37:18 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * disassemble.c (disassembler): Handle bfd_mach_sparc64.
+
+ * sparc-opc.c (asi, membar): New static locals.
+ (sparc_{encode,decode}_{asi,membar}): New functions.
+ (sparc_opcodes, membar insn): Fix.
+ * sparc-dis.c (print_insn): Call sparc_decode_asi.
+ Support decoding of membar masks.
+ (X_MEMBAR): Define.
+
+Sat Aug 26 21:22:48 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c (m68k_opcode_aliases): Add br, brs, brb, brw, brl.
+
+Mon Aug 21 17:33:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c (m68k_opcode_aliases): Add bhib as an alias for bhis,
+ and likewise for the other branches. Add bhs as an alias for bcc,
+ and likewise for the size variants. Add dbhs as an alias for
+ dbcc.
+
+Fri Aug 11 13:40:24 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * sh-opc.h (FP sts instructions): Update to match reality.
+
+Mon Aug 7 16:12:58 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-dis.c: (fpcr_names): Add % before all register names.
+ (reg_names): Likewise.
+ (print_insn_arg): Don't explicitly print % before register names.
+ Add % before register names in static array names. In case 'r',
+ print data registers as `@(Dn)', not `Dn@'. When printing a
+ memory address, don't print @# before it.
+ (print_indexed): Change base_disp and outer_disp from int to
+ bfd_vma. Print using MIT syntax, not mutant invalid Motorola
+ syntax. Sign extend 8 byte displacement correctly.
+ (print_base): Print using MIT syntax. Print zpc when appropriate.
+ Change parameter disp from int to bfd_vma.
+
+ * m68k-opc.c (m68k_opcode_aliases): Add jsrl and jsrs as aliases
+ for jsr.
+
+Mon Aug 7 02:21:40 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * sh-dis.c (print_insn_shx): Handle new operand types F_REG_N,
+ F_REG_M, FPSCR_M, FPSCR_N, FPUL_M and FPUL_N.
+ * sh-opc.h (sh_arg_type): Add new operand types.
+ (sh_table): Add new opcodes from SH3E Floating Point ISA.
+
+Sat Aug 5 16:50:14 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (distclean): Remove generated file config.h.
+
+Sat Aug 5 16:50:14 1995 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (distclean): Remove generated file config.h.
+
+Wed Aug 2 18:33:40 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * m68k-opc.c: New file, holding tables from include/opcode/m68k.h.
+ Clean up tables.
+ * m68k-dis.c: Remove BREAK_UP_BIG_DECL stuff.
+ (opcode): Remove.
+ (print_insn_m68k): Change d to be const. Use m68k_numopcodes
+ rather than numopcodes. Use m68k_opcodes rather than removed
+ opcode function. Don't check F_ALIAS.
+ (print_insn_arg): Change first parameter to be const char *.
+ * Makefile.in (ALL_MACHINES): Add m68k-opc.o.
+ (m68k-opc.o): New target.
+ * configure.in: Build m68k-opc.o for bfd_m68k_arch.
+ * configure: Rebuild.
+
+Wed Aug 2 08:23:38 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-dis.c (HASH_SIZE, HASH_INSN): Define.
+ (opcode_bits, opcode_hash_table): New variables.
+ (opcodes_initialized): Renamed from opcodes_sorted.
+ (build_hash_table): New function.
+ (is_delayed_branch): Use hash table.
+ (print_insn): Renamed from print_insn_sparc, made static.
+ Build and use hash table. If !sparc64, ignore sparc64 insns,
+ and vice-versa if sparc64.
+ (print_insn_sparc, print_insn_sparc64): New functions.
+ (compare_opcodes): Move sparc64 opcodes to end.
+ Print commutative insns with constant second.
+ * sparc-opc.c (all non-v9 insns): Use flag F_NOTV9 instead of F_ALIAS.
+
+Tue Aug 1 00:12:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * sh-dis.c (print_insn_shx): Remove unused local dslot. Use
+ print_address_func for A_BDISP12 and A_BDISP8. Correct test which
+ avoids printing a delay slot in a delay slot.
+ * sh-opc.h (sh_table): Fully bracket last entry.
+
+Mon Jul 31 12:04:47 1995 Doug Evans <dje@canuck.cygnus.com>
+
+ * sparc-opc.c (sllx, srax, srlx): Fix disassembly.
+
+Wed Jul 12 00:59:34 1995 Ken Raeburn <raeburn@kr-pc.cygnus.com>
+
+ * configure.in: Get host_makefile_frag from ${srcdir}.
+
+ * configure.in: Autoconfiscated. Check for string[s].h. Create
+ config.h from config.in. Don't set up sysdep.h link.
+ * sysdep.h: New file.
+ * configure, config.in: New files, generated from configure.in.
+ * Makefile.in: Updated to be processed autoconf-style.
+ (distclean): Keep sysdep.h. Remove config.log and config.cache.
+ (Makefile): Depend on config.status.
+ (config.status): New rule.
+ * configure.bat: Update Makefile substitutions.
+
+Tue Jul 11 14:23:37 1995 Jeff Spiegel <jeffs@lsil.com>
+
+ * mips-opc.c (L1): Define.
+ (mips_opcodes): Add R4010 instructions: flushi, flushd, flushid,
+ addciu, madd, maddu, ffc, ffs, msub, msubu, selsi, selsr, waiti,
+ and wb.
+
+Tue Jul 11 11:49:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c (mips_opcodes): For the move pseudo-op, prefer daddu
+ if ISA 3 and addu otherwise, replacing or, since some MIPS chips
+ have multiple add units but only a single logical unit.
+
+ * ppc-opc.c (powerpc_operands): Change CR to use a bitsize of 3,
+ shifted by 18, without any insertion or extraction function.
+ (insert_cr, extract_cr): Remove.
+
+Wed Jun 21 20:05:39 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * m68k-dis.c (print_insn_arg, print_indexed): Print "%" before
+ register names.
+
+Thu Jun 15 17:23:31 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * mpw-config.in: Add sh and i386 configs, remove sparc config.
+ * sh-opc.h: Add copyright.
+
+Mon Jun 5 03:30:43 1995 Ken Raeburn <raeburn@kr-laptop.cygnus.com>
+
+ * Makefile.in (crunch-m68k): Delete extra target accidentally
+ checked in a while ago.
+
+Wed May 24 16:22:13 1995 Jim Wilson <wilson@chestnut.cygnus.com>
+
+ * sh-opc.h (sh_table): Add SH3 support.
+
+Wed May 24 14:16:08 1995 Steve Chamberlain <sac@slash.cygnus.com>
+
+ * sh-opc.h: Added bsrf and braf.
+
+Wed May 10 14:28:16 1995 Richard Earnshaw (rearnsha@armltd.co.uk)
+
+ * arm-opc.h (arm_opcodes): Add 64-bit multiply patterns. Delete
+ bogus [ls]fm{ea,fd} patterns.
+
+ * arm-opc.h (arm_opcodes): Correct typos in stm, ldm, std, and ldc.
+ * arm-dis.c (print_insn_arm): Make GIVEN a parameter, don't try and
+ initialize it from memory. Make function static.
+ (print_insn_{big,little}_arm): New functions.
+ * disassemble.c (disassembler, case bfd_arch_arm): Disassemble for
+ the correct endianness.
+
+Mon Apr 24 14:18:05 1995 Jason Molenda (crash@phydeaux.cygnus.com>
+
+ * sh-opc.h (sh_nibble_type, sh_arg_type): remove trailing , from
+ enum list.
+
+Wed Apr 19 14:07:03 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * m68k-dis.c (opcode): Finish change made by Kung Hsu on April
+ 17th, so that it builds again using GCC as the compiler.
+
+Tue Apr 18 12:14:51 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * mips-dis.c (print_insn_little_mips): Cast return value from
+ bfd_getl32 from bfd_vma to unsigned long, because _print_insn_mips
+ expects an unsigned long, and that might be fewer words of
+ argument storage (e.g., if bfd_vma is long long on a 32-bit
+ machine).
+ (print_insn_big_mips): Likewise with bfd_getb32 value.
+ (_print_insn_mips): Now static.
+
+Mon Apr 17 12:23:28 1995 Kung Hsu <kung@rtl.cygnus.com>
+
+ * m68k-dis.c: Take out #define BREAK_UP_BIG_DECL kludge, because
+ gcc memory hog problem with initializer is fixed.
+
+Mon Apr 10 15:55:01 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ Merge in support for Mac MPW as a host.
+ (Old change descriptions retained for informational value.)
+
+ * mpw-config.in (archname): Compute from the config.
+ (BFD_MACHINES, ARCHDEFS): Put into mk.tmp.
+
+ * mpw-config.in (target_arch): Compute from canonical target.
+ (m68k, mips, powerpc, sparc): Add architectures.
+ * mpw-make.in (disassemble.c.o): Add.
+ (ALL_CFLAGS): Remove special flags (-mc68020 -mc68881 -model far).
+
+ * mpw-config.in (BFD_MACHINES): Set to a default value.
+ * mpw-make.in (BFD_MACHINES): Remove wired-in value.
+
+ * mpw-make.in (CSEARCH): Add extra-include to search path.
+
+ * mpw-config.in (varargs.h): Don't create.
+ (sysdep.h): Create using forward-include.
+ * mpw-make.in (CSEARCH): Add include/mpw to search path.
+
+ * mpw-config.in: New file, MPW version of configure.in.
+ * mpw-make.in: New file, MPW version of Makefile.in.
+
+Fri Mar 31 14:23:38 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * alpha-dis.c (print_insn_alpha): Put empty statement after
+ default label.
+
+Tue Mar 21 10:51:40 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-dis.c (sign_extend): Delete, redundant with libhppa.h version.
+ (low_sign_extend): Likewise.
+ (get_field): Delete unused function.
+ (set_field, deposit_14, deposit_21): Likewise.
+
+Fri Mar 17 15:55:53 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386-dis.c: Support for more pentium opcodes. From Guy Harris
+ (guy@netapp.com).
+
+Tue Mar 14 00:52:57 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com)
+
+ Sat Feb 11 17:22:41 1995 Klaus Kaempf (kkaempf@didymus.rmi.de)
+
+ * alpha-opc.h (OSF_ASMCODE): define
+ print pal-code names as defined in App C of the
+ Alpha Architecture Reference Manual
+
+ * alpha-dis.c: cleaned up output
+ print stylized code forms as defined in App A.4.3 of the
+ Alpha Architecture Reference Manual
+
+Wed Mar 8 15:21:14 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Add new mips4 instructions. Don't set INSN_RFE for
+ `rfe'.
+ * mips-dis.c (print_insn_arg): Handle new argument types 'h', 'R',
+ 'N', and 'M'.
+
+Wed Mar 8 02:54:05 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * m68k-dis.c (opcode): New function. Returns address of opcode
+ table entry given index, even if the opcode table was split to
+ work around gcc bugs.
+ (print_insn_m68k): Call opcode instead of referencing m68k_opcodes
+ directly.
+ (BREAK_UP_BIG_DECL): Make secondary array static and const.
+ (reg_names): Now const.
+ (print_insn_arg): Arrays cacheFieldName and names now const.
+ (print_indexed): Array scales now const.
+
+Tue Mar 7 16:41:21 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ppc-opc.c: Sort recently added instructions by minor opcode
+ number within major opcode number.
+
+Mon Mar 6 10:04:36 1995 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-dis.c: Include libhppa.h.
+
+Fri Feb 24 19:15:36 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Change dli to use M_DLI, and add dla.
+
+Mon Feb 20 23:54:38 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * Makefile.in (ALL_MACHINES): Add w65-dis.o.
+
+Thu Feb 16 17:34:41 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Add r4650 mul instruction.
+
+Wed Feb 15 15:45:20 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * mips-opc.c: Add uld and usd macros for unaligned double load and
+ store.
+
+Tue Feb 14 13:17:37 1995 Michael Meissner <meissner@tiktok.cygnus.com>
+
+ * ppc-opc.c (powerpc_opcodes): Add 403GA opcodes rfci, dccci,
+ mfdcr, mtdcr, icbt, iccci.
+
+Thu Feb 9 12:28:13 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * i960-dis.c (struct tabent, struct sparse_tabent): Change the
+ signed char fields to shorts, more portable.
+
+Wed Feb 8 17:29:29 1995 Stan Shebs <shebs@andros.cygnus.com>
+
+ * i960-dis.c (struct tabent, struct sparse_tabent): Declare the
+ char fields as signed chars, since they may have negative values.
+
+Mon Feb 6 10:52:06 1995 J.T. Conklin <jtc@rtl.cygnus.com>
+
+ * i386-dis.c (dis386_twobyte): Add cpuid, From Charles Hannum
+ (mycroft@netbsd.org).
+
+Mon Jan 30 12:38:00 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ From "Logg, Ed" <elogg@ea.com>:
+ * ppc-opc.c (extract_bdm): Correct parenthezisation.
+ * ppc-dis.c (print_insn_powerpc): Print .long before unrecognized
+ value.
+
+Thu Jan 26 18:32:08 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ppc-opc.c: Changes based on patch from David Edelsohn
+ <edelsohn@mhpcc.edu>.
+ (powerpc_operands): Add operands SPRBAT and SPRG. Split TBR out of
+ SPR.
+ (FXM_MASK): Define.
+ (insert_tbr): New static function.
+ (extract_tbr): New static function.
+ (XFXFXM_MASK, XFXM): Define.
+ (XSPRBAT_MASK, XSPRG_MASK): Define.
+ (powerpc_opcodes): Add instructions to access special registers by
+ name. Add mtcr and mftbu.
+
+Tue Jan 17 10:56:43 1995 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * mips-opc.c (P3): Define.
+ (mips_opcodes): Add mad and madu.
+
+Sun Jan 15 16:32:59 1995 Steve Chamberlain <sac@splat>
+
+ * configure.in: Add W65 support.
+ * disassemble.c: Likewise.
+ * w65-opc.h, w65-dis.c: New files.
+
+Wed Dec 28 22:15:33 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * h8300-dis.c (bfd_h8_disassemble): Add support for 2 bit
+ immediates.
+
+Tue Dec 20 11:25:12 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * mips-opc.c: Add dli as a synonym for li.
+
+Thu Dec 8 18:23:31 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * alpha-dis.c (print_insn_alpha): Handle call_pal instruction, and
+ print something for reserved opcode values, even if it won't
+ assemble again.
+
+ * mips-dis.c (_print_insn_mips): When initializing, shift right
+ and mask, to avoid sign extension problems on the Alpha.
+
+ * m68k-dis.c (print_insn_arg, case 'J'): Handle buscr and pcr
+ control registers.
+
+Wed Nov 23 22:34:51 1994 Steve Chamberlain (sac@jonny.cygnus.com)
+
+ * sh-opc.h (mov.l gbr): Get direction right.
+ * sh-dis.c (print_insn_shx): New function.
+ (print_insn_shl, print_insn_sh): Call print_insn_shx to
+ print opcodes with right byte order.
+
+Thu Nov 3 19:32:22 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+
+ * ns32k-dis.c (struct ns32k_option): Renamed from struct option,
+ to avoid conflicts with getopt.
+
+Mon Oct 31 18:48:10 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * hppa-dis.c (print_insn_hppa): Read the instruction using
+ bfd_getb32, so that it works on a little endian or 64 bit host.
+ Remove unused local variable op.
+
+Tue Oct 25 17:07:57 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * mips-opc.c: Use or instead of addu for pseudo-op move, since
+ addu does not work correctly if -mips3.
+
+Wed Oct 19 13:40:16 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * a29k-dis.c (print_special): Add special register names defined
+ on 29030, 29040 and 29050.
+ (print_insn): Handle new operand type 'I'.
+
+Wed Oct 12 11:59:55 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * Makefile.in (INSTALL): Use top level install.sh script.
+
+Wed Oct 5 19:16:29 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * sparc-dis.c: Rewrite to use bitfields, rather than a union, so
+ that it works on a little endian host.
+
+Tue Oct 4 12:14:21 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
+
+ * configure.in: Use ${config_shell} when running config.bfd.
+
+Wed Sep 21 18:49:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mips-opc.c (mips_opcodes): "dabs" is only available with -mips3.
+
+Thu Sep 15 16:30:22 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * a29k-dis.c (print_insn): Print the opcode.
+
+Wed Sep 14 17:52:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mips-opc.c (mips_opcodes): Set WR_t for sc and scd.
+
+Sun Sep 11 22:32:17 1994 Jeff Law (law@snake.cs.utah.edu)
+
+ * hppa-dis.c (reg_names): Use r26-r23 for arg0-arg3.
+
+Tue Sep 6 11:37:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mips-opc.c: Set INSN_STORE_MEMORY flag for all instructions
+ which store a value into memory.
+
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+
+ * configure.in, Makefile.in, disassemble.c: Add support for the ARM.
+ * arm-dis.c, arm-opc.h: New files.
+
+Fri Aug 5 14:00:05 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * Makefile.in (ns32k-dis.o): Add dependency.
+ * ns32k-dis.c (print_insn_arg): Declare initialized local as
+ string, not as array of chars.
+
+Thu Jul 28 18:14:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * sparc-dis.c (print_insn_sparc): Handle new operand type 'x'.
+
+ * sparc-opc.c: Added sparclite extended FP operations, and
+ versions of v9 impdep* instructions permitting specification of
+ the OPF field.
+
+Tue Jul 26 16:36:03 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * i960-dis.c (reg_names): Now const.
+ (struct sparse_tabent): New type, copied from array type in mem
+ function.
+ (ctrl): Local static array ctrl_tab now const.
+ (cobr): Local static array cobr_tab now const.
+ (mem): Local variables reg1, reg2, reg3 now point to const. Local
+ static variable mem_tab no longer explicitly initialized. Changed
+ mem_init to const array of struct sparse_tabent.
+ (reg): Local static variable reg_tab no longer explicitly
+ initialized. Changed reg_init to const array of struct
+ sparse_tabent.
+ (ea): Local static array scale_tab now const.
+
+ * i960-dis.c (reg): Added i960JX instructions to reg_init table.
+ (REG_MAX): Updated.
+
+Tue Jul 19 21:00:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: the disassember needs to be enabled for
+ "objdump -d" to work in djgpp.
+
+Wed Jul 13 18:01:58 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * ns32k-dis.c: Deleted all code in "#ifdef GDB".
+ (invalid_float): Enabled general version, doesn't require running
+ on ns32k host. Changed to take char* argument, and test for
+ explicitly specified sizes, instead of using sizeof() on host CPU
+ types.
+ (INVALID_FLOAT): Cast first argument.
+ (opt_u, opt_U, opt_O, opt_C, opt_S, list_P532, list_M532,
+ list_P032, list_M032): Now const.
+ (optlist, list_search): Made appropriate arguments now point to
+ const.
+ (print_insn_arg): Changed static array of one-character-string
+ pointers into a static const array of characters; fixed sprintf
+ statement accordingly.
+
+Sun Jul 10 00:27:47 1994 Ian Dall (dall@hfrd.dsto.gov.au)
+
+ * opcodes/ns32k-dis.c: Semi-new file. Had apparently been dropped
+ from distribution. A ns32k-dis.c from a previous distribution has
+ been brought up to date and supports the new interface.
+
+ * disassemble.c: define ARCH_ns32k and add case bfd_arch_ns32k.
+
+ * configure.in: add bfd_ns32k_arch target support.
+
+ * Makefile.in: add ns32k-dis.o to ALL_MACHINES.
+ Add ns32k-dis.c to CFILES. Add dependencies for ns32k-dis.o.
+
+Wed Jun 29 22:10:37 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * h8300-dis.c (bfd_h8_disassemble): Get 16bit branch
+ disassembly right.
+
+Tue Jun 28 13:22:06 1994 Stan Shebs (shebs@andros.cygnus.com)
+
+ * h8300-dis.c, mips-dis.c: Don't use true and false.
+
+Thu Jun 23 12:53:19 1994 David J. Mackenzie (djm@rtl.cygnus.com)
+
+ * configure.in: Change --with-targets to --enable-targets.
+
+Wed Jun 22 13:38:32 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * mips-dis.c (_print_insn_mips): Build a static hash table mapping
+ opcodes to the first instruction with that opcode, to speed
+ disassembly of large files. From ralphc@pyramid.com (Ralph
+ Campbell).
+
+Tue Jun 7 12:49:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * Makefile.in (mostlyclean): Fix typo (was mostyclean).
+
+Wed May 11 22:32:00 1994 DJ Delorie (dj@ctron.com)
+
+ * configure.bat: update to latest makefile.in
+
+Sat May 7 17:13:21 1994 Steve Chamberlain (sac@cygnus.com)
+
+ * a29k-dis.c (print_insn): Print 'x' type operand in hex.
+ * h8300-dis.c (bfd_h8_disassemble): Print 16bit rels correctly.
+ * sh-dis.c (print_insn_sh): Don't recur endlessly if delay
+ slot insn is in a delay slot.
+ * z8k-opc.h: (resflg): Fix patterns.
+ * h8500-opc.h Fix CR insn patterns.
+
+Fri May 6 14:34:46 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c (powerpc_opcodes): Put PowerPC versions of "cmp" and
+ "cmpl" before POWER versions, so that gas -many uses them.
+
+Thu Apr 28 18:32:36 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
+
+ * disassemble.c: New file.
+ * Makefile.in (OFILES): Add disassemble.o.
+ (disassemble.o): Provide dependencies; compile with $(ARCHDEFS).
+ * configure.in: Define ARCHDEFS in Makefile. Code taken from
+ binutils/configure.in.
+
+ * m68k-dis.c (print_insn_m68k): If F_ALIAS flag is set, skip the
+ opcode being examined.
+
+Thu Apr 21 17:08:40 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c (powerpc_operands): Added RAL, RAM and RAS.
+ (insert_ral, insert_ram, insert_ras): New functions.
+ (powerpc_opcodes): Use RAL for load with update, RAM for lmw, and
+ RAS for store with update.
+
+Sat Apr 16 23:41:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c (powerpc_opcodes): Correct fcir. From David Edelsohn
+ (edelsohn@npac.syr.edu).
+
+Wed Apr 6 17:11:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c (mips_opcodes): Correct operands of "nor" with an
+ immediate argument.
+
+Mon Apr 4 16:30:46 1994 Doug Evans (dje@canuck.cygnus.com)
+
+ * sparc-opc.c (sparc_opcodes): Fix "rd %fprs,%l0".
+
+Mon Apr 4 13:22:00 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c (powerpc_operands): The signedp field has been
+ removed, so don't initialize it. Set the PPC_OPERAND_SIGNED flag
+ instead. Add new operand SISIGNOPT.
+ (powerpc_opcodes): For lis, liu, addis, and cau use SISIGNOPT.
+ Based on patch from David Edelsohn (edelsohn@npac.syr.edu).
+ * ppc-dis.c (print_insn_powerpc): Check PPC_OPERAND_SIGNED rather
+ than signedp field.
+
+Wed Mar 30 00:31:49 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * i386-dis.c (struct private): Renamed to dis_private. `private'
+ is a reserved word for dynix cc.
+
+Mon Mar 28 13:00:15 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Change error message to refer to bfd/config.bfd
+ rather than bfd/configure.in.
+
+Mon Mar 28 12:28:30 1994 David Edelsohn (edelsohn@npac.syr.edu)
+
+ * ppc-opc.c: Define POWER2 as short alias flag.
+ (powerpc_opcodes): Add POWER/2 opcodes lfq*, stfq*, fcir[z], and
+ fsqrt.
+
+Wed Mar 23 12:23:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i960-dis.c (print_insn_i960): Don't read a second word for
+ opcodes 0, 1, 2 and 3.
+
+Wed Mar 16 15:37:58 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in: Don't build m68881-ext.o for bfd_m68k_arch.
+
+Mon Mar 14 14:53:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m68881-ext.c: Removed; no longer used.
+ * Makefile.in: Changed accordingly.
+
+ * m68k-dis.c (ext_format_68881): Don't declare.
+ (print_insn_m68k): If an instruction uses place 'i', it uses at
+ least four fixed bytes.
+ (print_insn_arg): Don't bump p by 2 for case 'I', place 'i'. For
+ extended float, convert to double using floatformat_to_double, not
+ ieee_extended_to_double, and fetch the data before converting it.
+
+Tue Mar 8 18:12:25 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: It's sqrt.s, not sqrt.w. From
+ davidj@ICSI.Berkeley.EDU (David Johnson).
+
+Tue Feb 8 16:55:27 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c (powerpc_opcodes): The POWER uses bdn[l][a] where the
+ PowerPC uses bdnz[l][a].
+
+Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * dis-buf.c, i386-dis.c: Include sysdep.h.
+
+Mon Feb 7 19:22:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * configure.in (bfd_powerpc_arch): Use ppc-dis.o and ppc-opc.o.
+
+ * ppc-opc.c (powerpc_opcodes): Mark POWER instructions supported
+ by Motorola PowerPC 601 with PPC_OPCODE_601.
+ * ppc-dis.c (print_insn_big_powerpc, print_insn_little_powerpc):
+ Disassemble Motorola PowerPC 601 instructions as well as normal
+ PowerPC instructions.
+
+Sun Feb 6 07:45:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * i960-dis.c (reg, mem): Just use a static array instead of
+ calling xmalloc.
+
+Sat Feb 5 00:04:02 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-dis.c (print_insn_hppa): For '?' and '@' only adjust the
+ condition name index if this is for a negated condition.
+
+ * hppa-dis.c (print_insn_hppa): No space before 'H' operand.
+ Floating point format for 'H' operand is backwards from normal
+ case (0 == double, 1 == single). For '4', '6', '7', '9', and '8'
+ operands (fmpyadd and fmpysub), handle bizarre register
+ translation correctly for single precision format.
+
+ * hppa-dis.c (print_insn_hppa): Do not emit a space after 'F'
+ or 'I' operands if the next format specifier is 'M' (fcmp
+ condition completer).
+
+Feb 4 23:38:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c (powerpc_operands): New operand type MBE to handle a
+ single number giving a bitmask for the MB and ME fields of an M
+ form instruction. Change NB to accept 32, and turn it into 0;
+ also turn 0 into 32 when disassembling. Seperated SH from NB.
+ (insert_mbe, extract_mbe): New functions.
+ (insert_nb, extract_nb): New functions.
+ (SC_MASK): Mask out SA and LK bits.
+ (powerpc_opcodes): Change "cal" to use RT, D, RA rather than RT,
+ RA, SI. Change "liu" and "cau" to use UI rather than SI. Mark
+ "bctr" and "bctrl" as accepted by POWER. Change "rlwimi",
+ "rlimi", "rlwimi.", "rlimi.", "rlwinm", "rlinm", "rlwinm.",
+ "rlinm.", "rlmi", "rlmi.", "rlwnm", "rlnm", "rlwnm.", "rlnm." to
+ use MBE rather than MB. Add "mfmq" and "mtmq" POWER instructions.
+ (powerpc_macros): Define table of macro definitions.
+ (powerpc_num_macros): Define.
+
+ * ppc-dis.c (print_insn_powerpc): Don't skip optional operands
+ if PPC_OPERAND_NEXT is set.
+
+Sat Jan 22 23:10:07 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * i960-dis.c (print_insn_i960): Make buffer bfd_byte instead of
+ char. Retrieve contents using bfd_getl32 instead of shifting.
+
+Fri Jan 21 19:01:39 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * ppc-opc.c: New file. Opcode table for PowerPC, including
+ opcodes for POWER (RS/6000).
+ * ppc-dis.c: New file. PowerPC and Power (RS/6000) disassembler.
+ * Makefile.in (ALL_MACHINES): Add ppc-dis.o and ppc-opc.o.
+ (CFILES): Add ppc-dis.c.
+ (ppc-dis.o, ppc-opc.o): New targets.
+ * configure.in: Build ppc-dis.o and ppc-opc.o for bfd_rs6000_arch.
+
+Mon Jan 17 20:05:49 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * hppa-dis.c (print_insn_hppa): Handle 'N' in assembler template.
+ No space before 'u', 'f', or 'N'.
+
+Sun Jan 16 14:20:16 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * i386-dis.c (print_insn_i386): Add FIXME comment regarding reading
+ farther than we should.
+
+ * i386-dis.c (dis386): Use Yb and Yv for scasb and scasS.
+
+Thu Jan 6 12:38:05 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * sparc-dis.c m68k-dis.c alpha-dis.c a29k-dis.c: Fix comments.
+
+Wed Jan 5 11:56:21 1994 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * i960-dis.c (print_insn_i960): Only read word2 if the instruction
+ needs it, to prevent reading past the end of a section.
+
+Wed Nov 17 17:20:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.h: Use macro for j instruction, to support SVR4 PIC.
+ Removed t,A case for la; always use t,A(b) case.
+
+Mon Nov 8 12:37:36 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ From Ted Lemen <mellon@pepper.ncd.com>
+ * mips-dis.c (print_insn_arg): Handle 'k'.
+ * mips-opc.c: Make cache use k, not t.
+
+Sun Nov 7 23:52:34 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-opc.h, alpha-dis.c (print_insn_alpha): Add
+ FLOAT_MEMORY_FORMAT_CODE, FLOAT_BRANCH_FORMAT_CODE, correct
+ FLOAT_FORMAT_CODE to put out floating point register names.
+
+Mon Nov 1 18:17:51 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Use macros for jal variants, to support SVR4 PIC.
+
+Thu Oct 28 17:42:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * a29k-dis.c (print_insn): Use 0x%08x, not 0x%8x.
+
+Wed Oct 27 11:48:01 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c (dsll, dsra, dsrl): Added '>' cases for shift counts
+ larger than 32. Moved dsxx32 variants first for disassembler.
+
+Mon Oct 25 11:33:14 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * z8kgen.c, z8k-opc.h: Add full lda information.
+
+Tue Oct 19 12:39:25 1993 Jeffrey A Law (law@cs.utah.edu)
+
+ * hppa-dis.c (print_insn_hppa): Do not emit a space after
+ movb instructions. Any necessary space will be emitted by
+ the code to handle nullification completers.
+
+Wed Oct 13 16:19:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Moved l.d down so that it disassembles as ldc1.
+
+Fri Oct 8 02:34:21 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-opc.h: Add ldl_l, fix typo for ldq_u.
+ * alpha-dis.c (print_insn_alpha): Add code for PAL_FORMAT_CODE.
+
+Tue Oct 5 17:47:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Correct lwu opcode value (book had it wrong).
+
+Thu Sep 30 11:26:18 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * z8k-dis.c (FETCH_DATA): get just the right amount of data.
+ (unpack_instr): Cope with ARG_IMM4M1 type instructions.
+
+Wed Sep 29 16:24:49 1993 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * m88k-dis.c (m88kdis): comment change. Remove space after
+ printing mnemonic.
+ (printop): handle new arg types DEC and XREG for m88110.
+
+Tue Sep 28 19:20:16 1993 Jeffrey A Law (law@snake.cs.utah.edu)
+
+ * hppa-dis.c (print_insn_hppa): Handle 'z' operand
+ type for absolute branch addresses. Delete special
+ "ble" and "be" code in 'W' operand code.
+
+Fri Sep 24 14:08:33 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Set hazard information correctly for branch
+ likely instructions.
+
+Fri Sep 17 04:41:17 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * alpha-dis.c (print_insn_alpha), alpha-opc.h: Fix bugs, use
+ info->fprintf_func for printing and info->print_address_func for
+ address output.
+
+Wed Sep 15 12:12:07 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Set INSN_TRAP for tXX instructions.
+
+Thu Sep 9 10:11:27 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: From davidj@ICSI.Berkeley.EDU (David Johnson):
+ Corrected second case of "b" for disassembler.
+
+Tue Sep 7 14:25:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-dis.c, m88k-dis.c: Don't include libbfd.h. Changed calls
+ to BFD swapping routines to correspond to BFD name changes.
+
+Thu Sep 2 10:35:25 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Change div machine instruction to be z,s,t rather
+ than s,t. Change div macro to be d,v,t rather than d,s,t.
+ Likewise for divu, ddiv, ddivu. Added z,s,t case for drem, dremu,
+ rem and remu which generates only the corresponding div
+ instruction. This is for compatibility with the MIPS assembler,
+ which only generates the simple machine instruction when an
+ explicit destination of $0 is used.
+ * mips-dis.c (print_insn_arg): Handle 'z' (always register zero).
+
+Thu Aug 26 17:41:44 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: From davidj@ICSI.Berkeley.EDU (David Johnson): Set
+ WR_31 hazard for bal, bgezal, bltzal.
+
+Thu Aug 26 17:20:02 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * hppa-dis.c (print_insn_hppa): Use print function
+ from within the disassemble_info, not fprintf_filtered.
+
+Wed Aug 25 13:51:40 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hppa-dis.c (print_insn_hppa): Handle '|' like '>'. (From Jeff
+ Law, law@cs.utah.edu.)
+
+Mon Aug 23 12:44:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c ("absu"): Removed.
+ ("dabs"): Added.
+
+Fri Aug 20 10:52:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Added r6000 and r4000 instructions and macros.
+ Changed hazard information to distinguish between memory load
+ delays and coprocessor load delays.
+
+Wed Aug 18 15:39:23 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: li.d uses "T,L", not "S,F". Added li.s.
+
+Tue Aug 17 09:44:42 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * configure.in: Don't pass cpu to config.bfd.
+
+Tue Aug 17 12:23:52 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m88k-dis.c (m88kdis): Make class unsigned.
+
+Thu Aug 12 15:08:18 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * alpha-dis.c (print_insn_alpha): One branch format case was
+ missing the instruction name.
+
+Wed Aug 11 19:29:39 1993 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * Makefile.in (ALL_MACHINES): Renamed from DIS_LIBS.
+ Add the arch-specific auxiliary files.
+ (OFILES): Remove the arch-specific auxiliary files
+ and use BFD_MACHINES instead of DIS_LIBS.
+ * configure.in: Set BFD_MACHINES based on --with-targets option.
+
+Thu Aug 12 12:04:53 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: Added lwc1 E,A(b) to go with lwc1 T,A(b). Similarly
+ for swc1.
+
+Sun Aug 8 15:09:30 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sparc-opc.c: Change CONST to const to deal with gcc
+ -Dconst=__const -traditional.
+
+Fri Aug 6 10:58:55 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-opc.c: From davidj@ICSI.Berkeley.EDU (David Johnson): Took
+ coprocessor instructions out of #if 0, and made them use new
+ argument type "C".
+
+Thu Aug 5 17:11:06 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * sparc-dis.c: Include ansidecl.h before opcodes/sparc.h.
+
+Fri Jul 30 18:48:15 1993 John Gilmore (gnu@cygnus.com)
+
+ * sparc-opc.c: Add F_JSR, F_UNBR, or F_CONDBR flags to each branch
+ instruction, for use by the disassembler.
+
+ * sparc-dis.c (SEX): Add sign extension macro. Replace many
+ hand-coded sign extensions that depended on 32-bit host ints.
+ FIXME, we still depend on big-endian host bitfield ordering.
+ (sparc_print_insn): Set the insn_info_valid field, and the
+ other fields that describe the instruction being printed.
+
+Tue Jul 27 17:04:58 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * sparc-opc.c (call): Accept all 6 addressing modes valid for
+ `jmp' instead of just one of them.
+
+Wed Jul 21 11:43:32 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * hppa-dis.c: Move floating registers from reg_names to fp_reg_names.
+ (fput_fp_reg_r): Renamed from fput_reg_r.
+ (fput_fp_reg): New function.
+ (print_insn_hppa): Use fput_fp_reg{,_r} where appropriate.
+
+ * hppa-dis.c (print_insn_hppa, cases 'a', 'd'): Print space afterwards.
+
+ * hppa-dis.c (print_insn_hppa, case 'd'): Use GET_COND not GET_FIELD.
+
+Mon Jul 19 13:52:21 1993 Jim Kingdon (kingdon@deneb.cygnus.com)
+
+ * hppa-dis.c (print_insn_hppa): Use extract_5r_store for 'r'.
+
+ * hppa-dis.c (print_insn_hppa, case '>'): If next character is 'n',
+ don't output a space.
+
+ * hppa-dis.c (float_format_names): 10 is undefined, and 11 is quad.
+
+Sun Jul 18 16:30:02 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
+
+ * mips-opc.c: New file, containing opcode table from
+ ../include/opcode/mips.h.
+ * Makefile.in: Add it.
+
+Thu Jul 15 12:37:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * m88k-dis.c: New file, moved in from gdb and changed to use the
+ new dis-asm.h disassembler interface.
+ * Makefile.in (DIS_LIBS): Added m88k-dis.o.
+ (m88k-dis.o): New target.
+
+Tue Jul 13 10:04:16 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips-dis.c (print_insn_arg, _print_insn_mips): Made pointer to
+ argument string const char * to correspond to opcode/mips.h.
+
+Tue Jul 6 15:18:37 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * mips-dis.c: Updated to account for name changes in new version
+ of opcode/mips.h.
+ * Makefile.in: Added header file dependencies.
+
+Sat Jul 3 23:47:56 1993 Doug Evans (dje@canuck.cygnus.com)
+
+ * h8300-dis.c (bfd_h8_disassemble): Correct fetching of instruction.
+
+Thu Jul 1 12:23:38 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * m68k-dis.c (NEXTWORD, NEXTLONG): Use ((x) ^ 0x8000) - 0x8000 to sign
+ extend, rather than shifts.
+
+Sun Jun 20 20:56:56 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
+
+ * Makefile.in: Undo 15 June change.
+
+Fri Jun 18 14:15:15 1993 Per Bothner (bothner@deneb.cygnus.com)
+
+ * m68k-dis.c (print_insn_arg): Change return value to byte count
+ or error code.
+ * m68k-dis.c: Re-write to detect invalid operands before
+ printing anything, so we can handle this the same way we
+ handle invalid opcodes.
+
+Thu Jun 17 15:01:36 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * sh-dis.c, sh-opc.h: Understand some more opcodes.
+
+Wed Jun 16 13:48:05 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * hppa-dis.c: Include <ansidecl.h> and sysdep.h before other
+ header files.
+
+Tue Jun 15 21:45:26 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * sparc-dis.c: Don't declare qsort, since sysdep.h might.
+
+ * configure.in: Do make sysdep.h link.
+ * Makefile.in: Search ../include. Don't search ../bfd.
+
+Tue Jun 15 13:36:10 1993 Stu Grossman (grossman@cygnus.com)
+
+ Changes from Jeff Law, law@cs.utah.edu:
+ * hppa-dis.c: Fix typo. 'a' and 'd' were reversed.
+ Do not print a space before the completers specified by
+ 'a' and 'd'.
+
+Fri Jun 11 18:40:21 1993 Ken Raeburn (raeburn@cygnus.com)
+
+ * mips-dis.c: No longer need to bomb out if HOST_64_BIT is
+ defined, since gdb has been fixed.
+
+ Changes from Jeff Law, law@cs.utah.edu:
+ * hppa-dis.c (print_insn_hppa): Last argument to fput_reg,
+ fput_reg_r, fput_creg, fput_const, and fputs_filtered should
+ be a *disassemble_info, not a *FILE.
+ * hppa-dis.c: Support 'd', '!', and 'a'.
+ * hppa-dis.c: Support 's' to extract a 2 bit space register.
+ * hppa-dis.c: Delete cases which are no longer needed.
+
+Fri Jun 11 07:53:48 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * m68k-dis.c (print_insn_{m68k,arg}): Add MMU codes.
+
+Tue Jun 8 12:25:01 1993 Steve Chamberlain (sac@phydeaux.cygnus.com)
+
+ * h8300-dis.c: New file, removed from bfd/cpu-h8300.c, with
+ H8/300-H opcodes.
+
+Mon Jun 7 12:58:49 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in (CSEARCH): Add -I../bfd for sysdep.h and bfd.h.
+ * configure.in: No longer need to configure to get sysdep.h.
+
+Thu Jun 3 15:56:49 1993 Stu Grossman (grossman@cygnus.com)
+
+ * Patches from Jeffrey Law <law@cs.utah.edu>.
+ * hppa-dis.c: Support 'I', 'J', and 'K' in output
+ templates for 1.1 FP computational instructions.
+
+Tue May 25 13:05:48 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * h8500-dis.c (print_insn_h8500): Address argument is type
+ bfd_vma.
+ * z8k-dis.c (print_insn_z8k, print_insn_z8001, print_insn_z8002):
+ Ditto.
+
+ * h8500-opc.h (addr_class_type): No comma at end of enumerator.
+ * sh-opc.h (sh_nibble_type, sh_arg_type): Ditto.
+
+ * sparc-dis.c (compare_opcodes): Move static declaration to
+ top-level.
+
+Fri May 21 14:17:37 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * sparc-dis.c (print_insn_sparc): Implement 'n' argument for unimp
+ instruction, remove unimp hack from 'l' argument.
+
+Wed May 19 15:35:54 1993 Stu Grossman (grossman@cygnus.com)
+
+ * z8k-dis.c (fetch_data): Use unsigned char to make ancient gcc's
+ happy.
+
+Fri May 14 15:22:46 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * Based on patches from davidj@ICSI.Berkeley.EDU (David Johnson):
+ * mips-dis.c (print_insn_arg): Handle 'C' for general coprocessor
+ instructions.
+
+Fri May 14 00:09:14 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hppa-dis.c: Include dis-asm.h before sysdep.h. Changed some
+ arrays of string pointers to 2-d arrays of chars, to save
+ space.
+
+Thu May 6 20:51:17 1993 Fred Fish (fnf@cygnus.com)
+
+ * a29k-dis.c, alpha-dis.c, i960-dis.c, sparc-dis.c, z8k-dis.c:
+ Cast second arg to read_memory_func to "bfd_byte *", as necessary.
+
+Tue May 4 20:31:10 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * hppa-dis.c: New file from Utah, adapted to new disassembler
+ calling interface.
+ * Makefile.in: Include it.
+
+Mon Apr 26 18:17:42 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * sh-dis.c, sh-opc.h: New files.
+
+Fri Apr 23 18:51:22 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * alpha-dis.c, alpha-opc.h: New files.
+
+Tue Apr 6 12:54:08 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * mips-dis.c: Sign extend 'j' and 'b' arguments, delta is a signed
+ value.
+
+Mon Apr 5 17:37:37 1993 John Gilmore (gnu@cygnus.com)
+
+ * sparc-dis.c: Make "ta" the default trap instruction, "t" the alias.
+
+Fri Apr 2 07:24:27 1993 Ian Lance Taylor (ian@cygnus.com)
+
+ * a29k-dis.c, sparc-dis.c, sparc-opc.c: Use CONST rather than
+ const.
+
+Thu Apr 1 11:20:43 1993 Jim Kingdon (kingdon@cygnus.com)
+
+ * sparc-dis.c: Use fprintf_func a few places where I forgot,
+ and double percent signs a few places.
+
+ * a29k-dis.c, i960-dis.c: New, merged from gdb and binutils.
+
+ * i386-dis.c, m68k-dis.c, mips-dis.c, sparc-dis.c:
+ Use info->print_address_func not print_address.
+
+ * dis-buf.c (generic_print_address): New function.
+
+Wed Mar 31 10:07:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * Makefile.in: Add sparc-dis.c.
+ sparc-dis.c: New file, merges binutils and gdb versions as follows:
+ From GDB:
+ Add `add' instruction to the set that get checked
+ for a preceding `sethi' in order to print an absolute address.
+ * (print_insn): Disassembly prefers real instructions.
+ (is_delayed_branch): Speed up.
+ * sparc-opcode.h: Add ALIAS bit to aliases. Fix up opcode tables.
+ Still missing some float ops, and needs testing.
+ * sparc-pinsn.c (print_insn): Eliminate 'set' test, subsumed by
+ F_ALIAS. Use printf, not fprintf, when not passing a file
+ pointer...
+ (compare_opcodes): Check that identical instructions have
+ identical opcodes, complain otherwise.
+ From binutils:
+ * New 'm' arg.
+ * Include reg_names.
+ From neither:
+ Use dis-asm.h/read_memory_func interface.
+
+Wed Mar 31 20:49:06 1993 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * h8500-dis.c, i386-dis.c, m68k-dis.c, z8k-dis.c (fetch_data):
+ deliberately return non-zero to setjmp from longjmp. Otherwise
+ this code fails to compile.
+
+Wed Mar 31 17:04:31 1993 Stu Grossman (grossman@cygnus.com)
+
+ * m68k-dis.c: Fix prototype for fetch_arg().
+
+Wed Mar 31 10:07:04 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
+
+ * dis-buf.c: New file, for new read_memory_func interface.
+ Makefile.in (OFILES): Include it.
+ m68k-dis.c, i386-dis.c, h8500-dis.c, mips-dis.c, z8k-dis.c:
+ Use new read_memory_func interface.
+
+Mon Mar 29 14:02:17 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * h8500-dis.c (print_insn_h8500): Get sign of fp offsets right.
+ * h8500-opc.h: Fix couple of opcodes.
+
+Wed Mar 24 02:03:36 1993 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: add dvi & installcheck targets
+
+Mon Mar 22 18:55:04 1993 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in: Update for h8500-dis.c.
+
+Fri Mar 19 14:27:17 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * h8500-dis.c, h8500-opc.h: New files
+
+Thu Mar 18 14:12:37 1993 Per Bothner (bothner@rtl.cygnus.com)
+
+ * mips-dis.c, z8k-dis.c: Converted to use interface defined in
+ ../include/dis-asm.h.
+ * m68k-dis.c: New file (merge of ../binutils/m68k-pinsn.c
+ and ../gdb/m68k-pinsn.c).
+ * i386-dis.c: New file (merge of ../binutils/i386-pinsn.c
+ and ../gdb/i386-pinsn.c).
+ * m68881-ext.c: New file. Moved definition of
+ ext_format ext_format_68881 from ../gdb/m68k-tdep.c.
+ * Makefile.in: Adjust for new files.
+ * i386-dis.c: Patches from John Hassey (hassey@dg-rtp.dg.com).
+ * m68k-dis.c: Recognize '9' placement code, so (say) pflush
+ can be dis-assembled.
+
+Wed Feb 17 09:19:47 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * mips-dis.c (print_insn_arg): Now returns void.
+
+Mon Jan 11 16:09:16 1993 Fred Fish (fnf@cygnus.com)
+
+ * mips-dis.c (ansidecl.h): Include for benefit of sysdep.h
+ files that use the macros.
+
+Thu Jan 7 13:15:17 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * mips-dis.c: New file, from gdb/mips-pinsn.c.
+ * Makefile.in (DIS_LIBS): Added mips-dis.o.
+ (CFILES): Added mips-dis.c.
+
+Thu Jan 7 07:36:33 1993 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * z8k-dis.c (print_insn_z8001, print_insn_z8002): new routines
+ * z8kgen.c, z8k-opc.h: fix sizes of some shifts.
+
+Tue Dec 22 15:42:44 1992 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Improve *clean rules.
+ * configure.in: Allow a default host.
+
+Tue Nov 17 19:53:54 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: also use -I$(srcdir)/../bfd, since some sysdep
+ files include other sysdep files
+
+Thu Nov 12 16:10:37 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * z8k-dis.c z8k-opc.h z8kgen.c: checkpoint
+
+Fri Oct 9 04:56:05 1992 John Gilmore (gnu@cygnus.com)
+
+ * configure.in: For host support, use ../bfd/configure.host
+ so it stays in sync with the ../bfd/hosts database.
+
+Thu Oct 1 23:38:54 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * configure.in: use cpu-vendor-os triple instead of nested cases
+
+Wed Sep 30 16:09:20 1992 Michael Werner (mtw@cygnus.com)
+
+ * z8k-dis.c (unparse_instr): fix bug where opcode returned was
+ *always* the wrong one.
+
+Wed Sep 30 07:42:17 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * z8kgen.c: added copyright info
+
+Tue Sep 29 12:20:21 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * z8k-dis.c (unparse_instr): prettier tabs
+ * z8kgen.c -> z8k-opc.h: bug fixes in tables
+
+Fri Sep 25 12:50:32 1992 Stu Grossman (grossman at cygnus.com)
+
+ * configure.in: Add ncr* configuration.
+ * z8k-dis.c (struct instr_data_s): Make instr_asmsrc char to make
+ picayune ANSI compilers happy.
+
+Sep 20 08:50:55 1992 Fred Fish (fnf@cygnus.com)
+
+ * configure.in (i386): Make i386 and i486 synonymous for now.
+ * configure.in (i[34]86-*-sysv4): Add my_host definition.
+
+Fri Sep 18 17:01:23 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (install): Fix typo.
+
+Fri Sep 18 02:04:24 1992 John Gilmore (gnu@cygnus.com)
+
+ * Makefile.in (make): Remove obsolete crud.
+ (sparc-opc.o): Avoid Sun Make VPATH bug.
+
+Tue Sep 8 17:29:27 1992 K. Richard Pixley (rich@sendai.cygnus.com)
+
+ * Makefile.in: since there are no SUBDIRS, remove rule and
+ references of subdir_do.
+
+Tue Sep 8 17:02:58 1992 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (install): Get the library name right here too.
+ Don't install bfd.h, since it's unrelated to this library. No
+ subdirs to recurse into, either.
+ (CFILES): The source file has a .c suffix, not .o.
+
+ * sparc-opc.c: New file, moved from BFD.
+ * Makefile.in (OFILES): Build it.
+
+Thu Sep 3 16:59:20 1992 Michael Werner (mtw@cygnus.com)
+
+ * z8k-dis.c: fixed forward refferences of some declarations.
+
+Mon Aug 31 16:09:45 1992 Michael Werner (mtw@cygnus.com)
+
+ * Makefile.in: get the name of the library right
+
+Mon Aug 31 13:47:35 1992 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * z8k-dis.c: knows how to disassemble z8k stuff
+ * z8k-opc.h: new file full of z8000 opcodes
+
+
+Local Variables:
+version-control: never
+End:
diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
new file mode 100644
index 00000000000..d997298d1d4
--- /dev/null
+++ b/opcodes/Makefile.am
@@ -0,0 +1,348 @@
+## Process this file with automake to generate Makefile.in
+
+AUTOMAKE_OPTIONS = cygnus
+
+SUBDIRS = po
+
+INCDIR = $(srcdir)/../include
+BFDDIR = $(srcdir)/../bfd
+DEP = mkdep
+
+lib_LTLIBRARIES = libopcodes.la
+
+# This is where bfd.h lives.
+BFD_H = ../bfd/bfd.h
+
+# Header files.
+HFILES = \
+ arm-opc.h \
+ fr30-desc.h fr30-opc.h \
+ h8500-opc.h \
+ m32r-desc.h m32r-opc.h \
+ mcore-opc.h \
+ sh-opc.h \
+ sysdep.h \
+ w65-opc.h \
+ z8k-opc.h
+
+# C source files that correspond to .o's.
+CFILES = \
+ a29k-dis.c \
+ alpha-dis.c \
+ alpha-opc.c \
+ arm-dis.c \
+ cgen-asm.c \
+ cgen-dis.c \
+ cgen-opc.c \
+ d10v-dis.c \
+ d10v-opc.c \
+ d30v-dis.c \
+ d30v-opc.c \
+ dis-buf.c \
+ disassemble.c \
+ fr30-asm.c \
+ fr30-desc.c \
+ fr30-dis.c \
+ fr30-ibld.c \
+ fr30-opc.c \
+ h8300-dis.c \
+ h8500-dis.c \
+ hppa-dis.c \
+ i386-dis.c \
+ i960-dis.c \
+ m32r-asm.c \
+ m32r-desc.c \
+ m32r-dis.c \
+ m32r-ibld.c \
+ m32r-opc.c \
+ m32r-opinst.c \
+ m68k-dis.c \
+ m68k-opc.c \
+ m88k-dis.c \
+ mcore-dis.c \
+ mips-dis.c \
+ mips-opc.c \
+ mips16-opc.c \
+ m10200-dis.c \
+ m10200-opc.c \
+ m10300-dis.c \
+ m10300-opc.c \
+ ns32k-dis.c \
+ ppc-dis.c \
+ ppc-opc.c \
+ sh-dis.c \
+ sparc-dis.c \
+ sparc-opc.c \
+ tic30-dis.c \
+ tic80-dis.c \
+ tic80-opc.c \
+ vax-dis.c \
+ w65-dis.c \
+ z8k-dis.c \
+ z8kgen.c
+
+ALL_MACHINES = \
+ a29k-dis.lo \
+ alpha-dis.lo \
+ alpha-opc.lo \
+ arc-dis.lo \
+ arc-opc.lo \
+ arm-dis.lo \
+ cgen-asm.lo \
+ cgen-dis.lo \
+ cgen-opc.lo \
+ d10v-dis.lo \
+ d10v-opc.lo \
+ d30v-dis.lo \
+ d30v-opc.lo \
+ fr30-asm.lo \
+ fr30-desc.lo \
+ fr30-dis.lo \
+ fr30-ibld.lo \
+ fr30-opc.lo \
+ h8300-dis.lo \
+ h8500-dis.lo \
+ hppa-dis.lo \
+ i386-dis.lo \
+ i960-dis.lo \
+ m32r-asm.lo \
+ m32r-desc.lo \
+ m32r-dis.lo \
+ m32r-ibld.lo \
+ m32r-opc.lo \
+ m32r-opinst.lo \
+ m68k-dis.lo \
+ m68k-opc.lo \
+ m88k-dis.lo \
+ m10200-dis.lo \
+ m10200-opc.lo \
+ m10300-dis.lo \
+ m10300-opc.lo \
+ mcore-dis.lo \
+ mips-dis.lo \
+ mips-opc.lo \
+ mips16-opc.lo \
+ ppc-dis.lo \
+ ppc-opc.lo \
+ ns32k-dis.lo \
+ sh-dis.lo \
+ sparc-dis.lo \
+ sparc-opc.lo \
+ tic30-dis.lo \
+ tic80-dis.lo \
+ tic80-opc.lo \
+ v850-dis.lo \
+ v850-opc.lo \
+ vax-dis.lo \
+ w65-dis.lo \
+ z8k-dis.lo
+
+OFILES = @BFD_MACHINES@
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(INCDIR) -I$(BFDDIR) @HDEFINES@ -I$(srcdir)/../intl -I../intl
+
+disassemble.lo: disassemble.c $(INCDIR)/dis-asm.h
+ $(LIBTOOL) --mode=compile $(COMPILE) -c @archdefs@ $(srcdir)/disassemble.c
+
+libopcodes_la_SOURCES = dis-buf.c disassemble.c
+libopcodes_la_DEPENDENCIES = $(OFILES)
+libopcodes_la_LIBADD = $(OFILES) @WIN32LIBADD@
+libopcodes_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
+
+# libtool will build .libs/libopcodes.a. We create libopcodes.a in
+# the build directory so that we don't have to convert all the
+# programs that use libopcodes.a simultaneously. This is a hack which
+# should be removed if everything else starts using libtool. FIXME.
+
+noinst_LIBRARIES = libopcodes.a
+
+stamp-lib: libopcodes.la
+ if [ -f .libs/libopcodes.a ]; then \
+ cp .libs/libopcodes.a libopcodes.tmp; \
+ $(SHELL) $(srcdir)/../move-if-change libopcodes.tmp libopcodes.a; \
+ else true; fi
+ touch stamp-lib
+
+libopcodes.a: stamp-lib ; @true
+
+POTFILES = $(HFILES) $(CFILES)
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+# We should reconfigure whenever bfd/configure.in changes, because
+# that's where the version number comes from.
+config.status: $(srcdir)/configure $(srcdir)/../bfd/configure.in
+ $(SHELL) ./config.status --recheck
+
+CLEANFILES = \
+ libopcodes.a stamp-lib dep.sed .dep .dep1
+
+
+
+# The start marker is written this way to pass through automake unscathed.
+
+
+
+
+# This dependency stuff is copied from BFD.
+
+.dep: dep.sed $(CFILES) $(HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed < .dep1 > .dep
+
+.dep1: $(CFILES)
+ rm -f .dep2 .dep2a
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ echo > .dep2a
+ $(DEP) -f .dep2a $(INCLUDES) $(CFLAGS) $?
+ sed -e '/DO NOT DELETE/d' -e '/^$$/d' < .dep2a >> .dep2
+ rm -f .dep2a
+ $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@BFD_H@!$(BFD_H)!' \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@BFDDIR@!$(BFDDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+a29k-dis.lo: a29k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/opcode/a29k.h
+alpha-dis.lo: alpha-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/alpha.h
+alpha-opc.lo: alpha-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/alpha.h \
+ $(BFD_H) opintl.h
+arm-dis.lo: arm-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h arm-opc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h opintl.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
+cgen-asm.lo: cgen-asm.c sysdep.h config.h $(INCDIR)/libiberty.h \
+ $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h \
+ opintl.h
+cgen-dis.lo: cgen-dis.c sysdep.h config.h $(INCDIR)/libiberty.h \
+ $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h
+cgen-opc.lo: cgen-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
+ $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h
+d10v-dis.lo: d10v-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+d10v-opc.lo: d10v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h
+d30v-dis.lo: d30v-dis.c $(INCDIR)/opcode/d30v.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h opintl.h
+d30v-opc.lo: d30v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d30v.h
+dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) opintl.h
+disassemble.lo: disassemble.c $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+fr30-asm.lo: fr30-asm.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-desc.lo: fr30-desc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-dis.lo: fr30-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-ibld.lo: fr30-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-opc.lo: fr30-opc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h
+h8300-dis.lo: h8300-dis.c $(INCDIR)/opcode/h8300.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h opintl.h
+h8500-dis.lo: h8500-dis.c h8500-opc.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h opintl.h
+hppa-dis.lo: hppa-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h
+i386-dis.lo: i386-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h sysdep.h config.h opintl.h
+i960-dis.lo: i960-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h
+m32r-asm.lo: m32r-asm.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-desc.lo: m32r-desc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-dis.lo: m32r-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-ibld.lo: m32r-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-opc.lo: m32r-opc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h
+m32r-opinst.lo: m32r-opinst.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h
+m68k-dis.lo: m68k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h opintl.h \
+ $(INCDIR)/opcode/m68k.h
+m68k-opc.lo: m68k-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/m68k.h
+m88k-dis.lo: m88k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/opcode/m88k.h opintl.h
+mcore-dis.lo: mcore-dis.c mcore-opc.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/opcode/mips.h opintl.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h
+mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
+mips16-opc.lo: mips16-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
+m10200-dis.lo: m10200-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) opintl.h
+m10200-opc.lo: m10200-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h
+m10300-dis.lo: m10300-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10300.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) opintl.h
+m10300-opc.lo: m10300-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10300.h
+ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ns32k.h \
+ opintl.h
+ppc-dis.lo: ppc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ppc.h
+ppc-opc.lo: ppc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/ppc.h \
+ opintl.h
+sh-dis.lo: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h
+sparc-dis.lo: sparc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/opcode/sparc.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/libiberty.h opintl.h
+sparc-opc.lo: sparc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/sparc.h
+tic30-dis.lo: tic30-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/opcode/tic30.h
+tic80-dis.lo: tic80-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/tic80.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+tic80-opc.lo: tic80-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/tic80.h
+vax-dis.lo: vax-dis.c $(INCDIR)/opcode/vax.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h
+w65-dis.lo: w65-dis.c w65-opc.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h
+z8k-dis.lo: z8k-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) z8k-opc.h
+z8kgen.lo: z8kgen.c sysdep.h config.h
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in
new file mode 100644
index 00000000000..ed8f64f9cd5
--- /dev/null
+++ b/opcodes/Makefile.in
@@ -0,0 +1,858 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AR = @AR@
+AS = @AS@
+BFD_MACHINES = @BFD_MACHINES@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+HDEFINES = @HDEFINES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+NM = @NM@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@
+VERSION = @VERSION@
+WIN32LDFLAGS = @WIN32LDFLAGS@
+WIN32LIBADD = @WIN32LIBADD@
+archdefs = @archdefs@
+cgen = @cgen@
+cgendir = @cgendir@
+l = @l@
+
+AUTOMAKE_OPTIONS = cygnus
+
+SUBDIRS = po
+
+INCDIR = $(srcdir)/../include
+BFDDIR = $(srcdir)/../bfd
+DEP = mkdep
+
+lib_LTLIBRARIES = libopcodes.la
+
+# This is where bfd.h lives.
+BFD_H = ../bfd/bfd.h
+
+# Header files.
+HFILES = \
+ arm-opc.h \
+ fr30-desc.h fr30-opc.h \
+ h8500-opc.h \
+ m32r-desc.h m32r-opc.h \
+ mcore-opc.h \
+ sh-opc.h \
+ sysdep.h \
+ w65-opc.h \
+ z8k-opc.h
+
+
+# C source files that correspond to .o's.
+CFILES = \
+ a29k-dis.c \
+ alpha-dis.c \
+ alpha-opc.c \
+ arm-dis.c \
+ cgen-asm.c \
+ cgen-dis.c \
+ cgen-opc.c \
+ d10v-dis.c \
+ d10v-opc.c \
+ d30v-dis.c \
+ d30v-opc.c \
+ dis-buf.c \
+ disassemble.c \
+ fr30-asm.c \
+ fr30-desc.c \
+ fr30-dis.c \
+ fr30-ibld.c \
+ fr30-opc.c \
+ h8300-dis.c \
+ h8500-dis.c \
+ hppa-dis.c \
+ i386-dis.c \
+ i960-dis.c \
+ m32r-asm.c \
+ m32r-desc.c \
+ m32r-dis.c \
+ m32r-ibld.c \
+ m32r-opc.c \
+ m32r-opinst.c \
+ m68k-dis.c \
+ m68k-opc.c \
+ m88k-dis.c \
+ mcore-dis.c \
+ mips-dis.c \
+ mips-opc.c \
+ mips16-opc.c \
+ m10200-dis.c \
+ m10200-opc.c \
+ m10300-dis.c \
+ m10300-opc.c \
+ ns32k-dis.c \
+ ppc-dis.c \
+ ppc-opc.c \
+ sh-dis.c \
+ sparc-dis.c \
+ sparc-opc.c \
+ tic30-dis.c \
+ tic80-dis.c \
+ tic80-opc.c \
+ vax-dis.c \
+ w65-dis.c \
+ z8k-dis.c \
+ z8kgen.c
+
+
+ALL_MACHINES = \
+ a29k-dis.lo \
+ alpha-dis.lo \
+ alpha-opc.lo \
+ arc-dis.lo \
+ arc-opc.lo \
+ arm-dis.lo \
+ cgen-asm.lo \
+ cgen-dis.lo \
+ cgen-opc.lo \
+ d10v-dis.lo \
+ d10v-opc.lo \
+ d30v-dis.lo \
+ d30v-opc.lo \
+ fr30-asm.lo \
+ fr30-desc.lo \
+ fr30-dis.lo \
+ fr30-ibld.lo \
+ fr30-opc.lo \
+ h8300-dis.lo \
+ h8500-dis.lo \
+ hppa-dis.lo \
+ i386-dis.lo \
+ i960-dis.lo \
+ m32r-asm.lo \
+ m32r-desc.lo \
+ m32r-dis.lo \
+ m32r-ibld.lo \
+ m32r-opc.lo \
+ m32r-opinst.lo \
+ m68k-dis.lo \
+ m68k-opc.lo \
+ m88k-dis.lo \
+ m10200-dis.lo \
+ m10200-opc.lo \
+ m10300-dis.lo \
+ m10300-opc.lo \
+ mcore-dis.lo \
+ mips-dis.lo \
+ mips-opc.lo \
+ mips16-opc.lo \
+ ppc-dis.lo \
+ ppc-opc.lo \
+ ns32k-dis.lo \
+ sh-dis.lo \
+ sparc-dis.lo \
+ sparc-opc.lo \
+ tic30-dis.lo \
+ tic80-dis.lo \
+ tic80-opc.lo \
+ v850-dis.lo \
+ v850-opc.lo \
+ vax-dis.lo \
+ w65-dis.lo \
+ z8k-dis.lo
+
+
+OFILES = @BFD_MACHINES@
+
+INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(INCDIR) -I$(BFDDIR) @HDEFINES@ -I$(srcdir)/../intl -I../intl
+
+libopcodes_la_SOURCES = dis-buf.c disassemble.c
+libopcodes_la_DEPENDENCIES = $(OFILES)
+libopcodes_la_LIBADD = $(OFILES) @WIN32LIBADD@
+libopcodes_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
+
+# libtool will build .libs/libopcodes.a. We create libopcodes.a in
+# the build directory so that we don't have to convert all the
+# programs that use libopcodes.a simultaneously. This is a hack which
+# should be removed if everything else starts using libtool. FIXME.
+
+noinst_LIBRARIES = libopcodes.a
+
+POTFILES = $(HFILES) $(CFILES)
+
+CLEANFILES = \
+ libopcodes.a stamp-lib dep.sed .dep .dep1
+
+
+
+
+# The start marker is written this way to pass through automake unscathed.
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libopcodes_a_LIBADD =
+libopcodes_a_SOURCES = libopcodes.a.c
+libopcodes_a_OBJECTS = libopcodes.a.o
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libopcodes_la_OBJECTS = dis-buf.lo disassemble.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+acinclude.m4 aclocal.m4 config.in configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = libopcodes.a.c $(libopcodes_la_SOURCES)
+OBJECTS = libopcodes.a.o $(libopcodes_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+libopcodes.la: $(libopcodes_la_OBJECTS) $(libopcodes_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libopcodes_la_LDFLAGS) $(libopcodes_la_OBJECTS) $(libopcodes_la_LIBADD) $(LIBS)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am:
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-info-am:
+install-info: install-info-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-libLTLIBRARIES
+uninstall: uninstall-recursive
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-noinstLIBRARIES \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-libLTLIBRARIES mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-noinstLIBRARIES clean-compile clean-libtool \
+ clean-libLTLIBRARIES clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-noinstLIBRARIES distclean-compile \
+ distclean-libtool distclean-libLTLIBRARIES \
+ distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-noinstLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-libLTLIBRARIES maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool mostlyclean-libLTLIBRARIES \
+distclean-libLTLIBRARIES clean-libLTLIBRARIES \
+maintainer-clean-libLTLIBRARIES uninstall-libLTLIBRARIES \
+install-libLTLIBRARIES install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-info-am \
+install-info all-recursive-am install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+disassemble.lo: disassemble.c $(INCDIR)/dis-asm.h
+ $(LIBTOOL) --mode=compile $(COMPILE) -c @archdefs@ $(srcdir)/disassemble.c
+
+stamp-lib: libopcodes.la
+ if [ -f .libs/libopcodes.a ]; then \
+ cp .libs/libopcodes.a libopcodes.tmp; \
+ $(SHELL) $(srcdir)/../move-if-change libopcodes.tmp libopcodes.a; \
+ else true; fi
+ touch stamp-lib
+
+libopcodes.a: stamp-lib ; @true
+po/POTFILES.in: @MAINT@ Makefile
+ for file in $(POTFILES); do echo $$file; done | sort > tmp \
+ && mv tmp $(srcdir)/po/POTFILES.in
+
+# We should reconfigure whenever bfd/configure.in changes, because
+# that's where the version number comes from.
+config.status: $(srcdir)/configure $(srcdir)/../bfd/configure.in
+ $(SHELL) ./config.status --recheck
+
+
+
+
+# This dependency stuff is copied from BFD.
+
+.dep: dep.sed $(CFILES) $(HFILES) config.h
+ rm -f .dep1
+ $(MAKE) DEP=$(DEP) .dep1
+ sed -f dep.sed < .dep1 > .dep
+
+.dep1: $(CFILES)
+ rm -f .dep2 .dep2a
+ echo '# DO NOT DELETE THIS LINE -- mkdep uses it.' > .dep2
+ echo > .dep2a
+ $(DEP) -f .dep2a $(INCLUDES) $(CFLAGS) $?
+ sed -e '/DO NOT DELETE/d' -e '/^$$/d' < .dep2a >> .dep2
+ rm -f .dep2a
+ $(srcdir)/../move-if-change .dep2 .dep1
+
+dep.sed: dep-in.sed config.status
+ sed <$(srcdir)/dep-in.sed >dep.sed \
+ -e 's!@BFD_H@!$(BFD_H)!' \
+ -e 's!@INCDIR@!$(INCDIR)!' \
+ -e 's!@BFDDIR@!$(BFDDIR)!' \
+ -e 's!@SRCDIR@!$(srcdir)!'
+
+dep: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < Makefile > tmp-Makefile
+ cat .dep >> tmp-Makefile
+ $(srcdir)/../move-if-change tmp-Makefile Makefile
+
+dep-in: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.in > tmp-Makefile.in
+ cat .dep >> tmp-Makefile.in
+ $(srcdir)/../move-if-change tmp-Makefile.in $(srcdir)/Makefile.in
+
+dep-am: .dep
+ sed -e '/^..DO NOT DELETE THIS LINE/,$$d' < $(srcdir)/Makefile.am > tmp-Makefile.am
+ cat .dep >> tmp-Makefile.am
+ $(srcdir)/../move-if-change tmp-Makefile.am $(srcdir)/Makefile.am
+
+.PHONY: dep dep-in dep-am
+
+# What appears below is generated by a hacked mkdep using gcc -MM.
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+a29k-dis.lo: a29k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/opcode/a29k.h
+alpha-dis.lo: alpha-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/alpha.h
+alpha-opc.lo: alpha-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/alpha.h \
+ $(BFD_H) opintl.h
+arm-dis.lo: arm-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h arm-opc.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h opintl.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h
+cgen-asm.lo: cgen-asm.c sysdep.h config.h $(INCDIR)/libiberty.h \
+ $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h \
+ opintl.h
+cgen-dis.lo: cgen-dis.c sysdep.h config.h $(INCDIR)/libiberty.h \
+ $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h
+cgen-opc.lo: cgen-opc.c sysdep.h config.h $(INCDIR)/libiberty.h \
+ $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/cgen.h
+d10v-dis.lo: d10v-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+d10v-opc.lo: d10v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d10v.h
+d30v-dis.lo: d30v-dis.c $(INCDIR)/opcode/d30v.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h opintl.h
+d30v-opc.lo: d30v-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/d30v.h
+dis-buf.lo: dis-buf.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) opintl.h
+disassemble.lo: disassemble.c $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+fr30-asm.lo: fr30-asm.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-desc.lo: fr30-desc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-dis.lo: fr30-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-ibld.lo: fr30-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h opintl.h
+fr30-opc.lo: fr30-opc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h fr30-desc.h $(INCDIR)/opcode/cgen.h \
+ fr30-opc.h
+h8300-dis.lo: h8300-dis.c $(INCDIR)/opcode/h8300.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h opintl.h
+h8500-dis.lo: h8500-dis.c h8500-opc.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h opintl.h
+hppa-dis.lo: hppa-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(BFDDIR)/libhppa.h $(INCDIR)/opcode/hppa.h
+i386-dis.lo: i386-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h sysdep.h config.h opintl.h
+i960-dis.lo: i960-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h
+m32r-asm.lo: m32r-asm.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-desc.lo: m32r-desc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-dis.lo: m32r-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-ibld.lo: m32r-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h opintl.h
+m32r-opc.lo: m32r-opc.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h
+m32r-opinst.lo: m32r-opinst.c sysdep.h config.h $(BFD_H) \
+ $(INCDIR)/symcat.h m32r-desc.h $(INCDIR)/opcode/cgen.h \
+ m32r-opc.h
+m68k-dis.lo: m68k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h opintl.h \
+ $(INCDIR)/opcode/m68k.h
+m68k-opc.lo: m68k-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/m68k.h
+m88k-dis.lo: m88k-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/opcode/m88k.h opintl.h
+mcore-dis.lo: mcore-dis.c mcore-opc.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/opcode/mips.h opintl.h $(BFDDIR)/elf-bfd.h \
+ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/elf/mips.h $(INCDIR)/elf/reloc-macros.h
+mips-opc.lo: mips-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
+mips16-opc.lo: mips16-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h
+m10200-dis.lo: m10200-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) opintl.h
+m10200-opc.lo: m10200-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10200.h
+m10300-dis.lo: m10300-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10300.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) opintl.h
+m10300-opc.lo: m10300-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mn10300.h
+ns32k-dis.lo: ns32k-dis.c $(BFD_H) $(INCDIR)/ansidecl.h \
+ sysdep.h config.h $(INCDIR)/dis-asm.h $(INCDIR)/opcode/ns32k.h \
+ opintl.h
+ppc-dis.lo: ppc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ppc.h
+ppc-opc.lo: ppc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/ppc.h \
+ opintl.h
+sh-dis.lo: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h
+sparc-dis.lo: sparc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
+ config.h $(INCDIR)/opcode/sparc.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/libiberty.h opintl.h
+sparc-opc.lo: sparc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/sparc.h
+tic30-dis.lo: tic30-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+ $(INCDIR)/ansidecl.h $(INCDIR)/opcode/tic30.h
+tic80-dis.lo: tic80-dis.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/tic80.h \
+ $(INCDIR)/dis-asm.h $(BFD_H)
+tic80-opc.lo: tic80-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/tic80.h
+vax-dis.lo: vax-dis.c $(INCDIR)/opcode/vax.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h
+w65-dis.lo: w65-dis.c w65-opc.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) $(INCDIR)/ansidecl.h
+z8k-dis.lo: z8k-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \
+ $(BFD_H) z8k-opc.h
+z8kgen.lo: z8kgen.c sysdep.h config.h
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/opcodes/a29k-dis.c b/opcodes/a29k-dis.c
new file mode 100644
index 00000000000..72959c975d9
--- /dev/null
+++ b/opcodes/a29k-dis.c
@@ -0,0 +1,353 @@
+/* Instruction printing code for the AMD 29000
+ Copyright (C) 1990, 93, 94, 95, 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Support. Written by Jim Kingdon.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "dis-asm.h"
+#include "opcode/a29k.h"
+
+/* Print a symbolic representation of a general-purpose
+ register number NUM on STREAM.
+ NUM is a number as found in the instruction, not as found in
+ debugging symbols; it must be in the range 0-255. */
+static void
+print_general (num, info)
+ int num;
+ struct disassemble_info *info;
+{
+ if (num < 128)
+ (*info->fprintf_func) (info->stream, "gr%d", num);
+ else
+ (*info->fprintf_func) (info->stream, "lr%d", num - 128);
+}
+
+/* Like print_general but a special-purpose register.
+
+ The mnemonics used by the AMD assembler are not quite the same
+ as the ones in the User's Manual. We use the ones that the
+ assembler uses. */
+static void
+print_special (num, info)
+ unsigned int num;
+ struct disassemble_info *info;
+{
+ /* Register names of registers 0-SPEC0_NUM-1. */
+ static char *spec0_names[] = {
+ "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
+ "pc0", "pc1", "pc2", "mmu", "lru", "rsn", "rma0", "rmc0", "rma1", "rmc1",
+ "spc0", "spc1", "spc2", "iba0", "ibc0", "iba1", "ibc1", "dba", "dbc",
+ "cir", "cdr"
+ };
+#define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
+
+ /* Register names of registers 128-128+SPEC128_NUM-1. */
+ static char *spec128_names[] = {
+ "ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
+ };
+#define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
+
+ /* Register names of registers 160-160+SPEC160_NUM-1. */
+ static char *spec160_names[] = {
+ "fpe", "inte", "fps", "sr163", "exop"
+ };
+#define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
+
+ if (num < SPEC0_NUM)
+ (*info->fprintf_func) (info->stream, spec0_names[num]);
+ else if (num >= 128 && num < 128 + SPEC128_NUM)
+ (*info->fprintf_func) (info->stream, spec128_names[num-128]);
+ else if (num >= 160 && num < 160 + SPEC160_NUM)
+ (*info->fprintf_func) (info->stream, spec160_names[num-160]);
+ else
+ (*info->fprintf_func) (info->stream, "sr%d", num);
+}
+
+/* Is an instruction with OPCODE a delayed branch? */
+static int
+is_delayed_branch (opcode)
+ int opcode;
+{
+ return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
+ || opcode == 0xa4 || opcode == 0xa5
+ || opcode == 0xb4 || opcode == 0xb5
+ || opcode == 0xc4 || opcode == 0xc0
+ || opcode == 0xac || opcode == 0xad
+ || opcode == 0xcc);
+}
+
+/* Now find the four bytes of INSN and put them in *INSN{0,8,16,24}. */
+static void
+find_bytes_big (insn, insn0, insn8, insn16, insn24)
+ char *insn;
+ unsigned char *insn0;
+ unsigned char *insn8;
+ unsigned char *insn16;
+ unsigned char *insn24;
+{
+ *insn24 = insn[0];
+ *insn16 = insn[1];
+ *insn8 = insn[2];
+ *insn0 = insn[3];
+}
+
+static void
+find_bytes_little (insn, insn0, insn8, insn16, insn24)
+ char *insn;
+ unsigned char *insn0;
+ unsigned char *insn8;
+ unsigned char *insn16;
+ unsigned char *insn24;
+{
+ *insn24 = insn[3];
+ *insn16 = insn[2];
+ *insn8 = insn[1];
+ *insn0 = insn[0];
+}
+
+typedef void (*find_byte_func_type)
+ PARAMS ((char *, unsigned char *, unsigned char *,
+ unsigned char *, unsigned char *));
+
+/* Print one instruction from MEMADDR on INFO->STREAM.
+ Return the size of the instruction (always 4 on a29k). */
+
+static int
+print_insn (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ /* The raw instruction. */
+ char insn[4];
+
+ /* The four bytes of the instruction. */
+ unsigned char insn24, insn16, insn8, insn0;
+
+ find_byte_func_type find_byte_func = (find_byte_func_type)info->private_data;
+
+ struct a29k_opcode CONST * opcode;
+
+ {
+ int status =
+ (*info->read_memory_func) (memaddr, (bfd_byte *) &insn[0], 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ }
+
+ (*find_byte_func) (insn, &insn0, &insn8, &insn16, &insn24);
+
+ printf ("%02x%02x%02x%02x ", insn24, insn16, insn8, insn0);
+
+ /* Handle the nop (aseq 0x40,gr1,gr1) specially */
+ if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) {
+ (*info->fprintf_func) (info->stream,"nop");
+ return 4;
+ }
+
+ /* The opcode is always in insn24. */
+ for (opcode = &a29k_opcodes[0];
+ opcode < &a29k_opcodes[num_opcodes];
+ ++opcode)
+ {
+ if (((unsigned long) insn24 << 24) == opcode->opcode)
+ {
+ char *s;
+
+ (*info->fprintf_func) (info->stream, "%s ", opcode->name);
+ for (s = opcode->args; *s != '\0'; ++s)
+ {
+ switch (*s)
+ {
+ case 'a':
+ print_general (insn8, info);
+ break;
+
+ case 'b':
+ print_general (insn0, info);
+ break;
+
+ case 'c':
+ print_general (insn16, info);
+ break;
+
+ case 'i':
+ (*info->fprintf_func) (info->stream, "%d", insn0);
+ break;
+
+ case 'x':
+ (*info->fprintf_func) (info->stream, "0x%x", (insn16 << 8) + insn0);
+ break;
+
+ case 'h':
+ /* This used to be %x for binutils. */
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (insn16 << 24) + (insn0 << 16));
+ break;
+
+ case 'X':
+ (*info->fprintf_func) (info->stream, "%d",
+ ((insn16 << 8) + insn0) | 0xffff0000);
+ break;
+
+ case 'P':
+ /* This output looks just like absolute addressing, but
+ maybe that's OK (it's what the GDB m68k and EBMON
+ a29k disassemblers do). */
+ /* All the shifting is to sign-extend it. p*/
+ (*info->print_address_func)
+ (memaddr +
+ (((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
+ info);
+ break;
+
+ case 'A':
+ (*info->print_address_func)
+ ((insn16 << 10) + (insn0 << 2), info);
+ break;
+
+ case 'e':
+ (*info->fprintf_func) (info->stream, "%d", insn16 >> 7);
+ break;
+
+ case 'n':
+ (*info->fprintf_func) (info->stream, "0x%x", insn16 & 0x7f);
+ break;
+
+ case 'v':
+ (*info->fprintf_func) (info->stream, "0x%x", insn16);
+ break;
+
+ case 's':
+ print_special (insn8, info);
+ break;
+
+ case 'u':
+ (*info->fprintf_func) (info->stream, "%d", insn0 >> 7);
+ break;
+
+ case 'r':
+ (*info->fprintf_func) (info->stream, "%d", (insn0 >> 4) & 7);
+ break;
+
+ case 'I':
+ if ((insn16 & 3) != 0)
+ (*info->fprintf_func) (info->stream, "%d", insn16 & 3);
+ break;
+
+ case 'd':
+ (*info->fprintf_func) (info->stream, "%d", (insn0 >> 2) & 3);
+ break;
+
+ case 'f':
+ (*info->fprintf_func) (info->stream, "%d", insn0 & 3);
+ break;
+
+ case 'F':
+ (*info->fprintf_func) (info->stream, "%d", (insn16 >> 2) & 15);
+ break;
+
+ case 'C':
+ (*info->fprintf_func) (info->stream, "%d", insn16 & 3);
+ break;
+
+ default:
+ (*info->fprintf_func) (info->stream, "%c", *s);
+ }
+ }
+
+ /* Now we look for a const,consth pair of instructions,
+ in which case we try to print the symbolic address. */
+ if (insn24 == 2) /* consth */
+ {
+ int errcode;
+ char prev_insn[4];
+ unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
+
+ errcode = (*info->read_memory_func) (memaddr - 4,
+ (bfd_byte *) &prev_insn[0],
+ 4,
+ info);
+ if (errcode == 0)
+ {
+ /* If it is a delayed branch, we need to look at the
+ instruction before the delayed brach to handle
+ things like
+
+ const _foo
+ call _printf
+ consth _foo
+ */
+ (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8,
+ &prev_insn16, &prev_insn24);
+ if (is_delayed_branch (prev_insn24))
+ {
+ errcode = (*info->read_memory_func)
+ (memaddr - 8, (bfd_byte *) &prev_insn[0], 4, info);
+ (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8,
+ &prev_insn16, &prev_insn24);
+ }
+ }
+
+ /* If there was a problem reading memory, then assume
+ the previous instruction was not const. */
+ if (errcode == 0)
+ {
+ /* Is it const to the same register? */
+ if (prev_insn24 == 3
+ && prev_insn8 == insn8)
+ {
+ (*info->fprintf_func) (info->stream, "\t; ");
+ (*info->print_address_func)
+ (((insn16 << 24) + (insn0 << 16)
+ + (prev_insn16 << 8) + (prev_insn0)),
+ info);
+ }
+ }
+ }
+
+ return 4;
+ }
+ }
+ /* This used to be %8x for binutils. */
+ (*info->fprintf_func)
+ (info->stream, ".word 0x%08x",
+ (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
+ return 4;
+}
+
+/* Disassemble an big-endian a29k instruction. */
+int
+print_insn_big_a29k (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ info->private_data = (PTR) find_bytes_big;
+ return print_insn (memaddr, info);
+}
+
+/* Disassemble a little-endian a29k instruction. */
+int
+print_insn_little_a29k (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ info->private_data = (PTR) find_bytes_little;
+ return print_insn (memaddr, info);
+}
diff --git a/opcodes/acinclude.m4 b/opcodes/acinclude.m4
new file mode 100644
index 00000000000..71b09b9f6ac
--- /dev/null
+++ b/opcodes/acinclude.m4
@@ -0,0 +1 @@
+sinclude(../bfd/acinclude.m4)
diff --git a/opcodes/aclocal.m4 b/opcodes/aclocal.m4
new file mode 100644
index 00000000000..308711dfa4e
--- /dev/null
+++ b/opcodes/aclocal.m4
@@ -0,0 +1,1111 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+sinclude(../bfd/acinclude.m4)
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+
+# serial 35 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_REQUIRE([AC_SYS_SYMBOL_UNDERSCORE])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ AC_SYS_LIBTOOL_CYGWIN
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+AC_ARG_ENABLE(libtool-lock,
+[ --disable-libtool-lock force libtool not to do file locking],
+need_locks=$enableval,
+need_locks=yes)
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+])
+
+# AC_LIBTOOL_DLOPEN - check for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [lt_dlopen=yes])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED,
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED,
+[AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC,
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC,
+[AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL,
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL,
+[AC_ENABLE_FAST_INSTALL(no)])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_SYS_NM_PARSE - Check for command to grab the raw symbol name followed
+# by C symbol name from nm.
+AC_DEFUN(AC_SYS_NM_PARSE,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+changequote([,])dnl
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+changequote(,)dnl
+lt_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+])
+
+# AC_SYS_LIBTOOL_CYGWIN - find tools needed on cygwin
+AC_DEFUN(AC_SYS_LIBTOOL_CYGWIN,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# AC_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
+# with an underscore?
+AC_DEFUN(AC_SYS_SYMBOL_UNDERSCORE,
+[AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_SYS_NM_PARSE])dnl
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+AC_SUBST(USE_SYMBOL_UNDERSCORE)dnl
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM, [
+AC_CHECK_LIB(mw, _mwvalidcheckl)
+AC_CHECK_LIB(m, cos)
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [
+ AC_CHECK_LIB(ltdl, main, LIBLTDL="-lltdl", [
+ case "$enable_ltdl_install" in
+ no) AC_MSG_WARN([libltdl not installed, but installation disabled]) ;;
+ "") enable_ltdl_install=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-install" ;;
+ esac
+ ])
+ if test x"$enable_ltdl_install" != x"no"; then
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+AC_DEFUN(AM_SYS_NM_PARSE, [indir([AC_SYS_NM_PARSE])])dnl
+AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE, [indir([AC_SYS_SYMBOL_UNDERSCORE])])dnl
+AC_DEFUN(AM_SYS_LIBTOOL_CYGWIN, [indir([AC_SYS_LIBTOOL_CYGWIN])])dnl
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
+# This file is derived from `gettext.m4'. The difference is that the
+# included macros assume Cygnus-style source and build trees.
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 3
+
+AC_DEFUN(CY_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if NLS is requested])
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CACHE_CHECK([for gettext in libintl],
+ gt_cv_func_gettext_libintl,
+ [AC_TRY_LINK([], [return (int) gettext ("")],
+ gt_cv_func_gettext_libintl=yes,
+ gt_cv_func_gettext_libintl=no)])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT, 1,
+ [Define as 1 if you have gettext and don't want to use GNU gettext.])
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ dnl In the standard gettext, we would now check for catgets.
+ dnl However, we never want to use catgets for our releases.
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext programs is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(CY_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY, 1, [Define if you have the stpcpy function])
+ fi
+
+ AM_LC_MESSAGES
+ CY_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile. But only do this if the po directory
+ dnl exists in srcdir.
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your locale.h file contains LC_MESSAGES.])
+ fi
+ fi])
+
diff --git a/opcodes/alpha-dis.c b/opcodes/alpha-dis.c
new file mode 100644
index 00000000000..db55799ee68
--- /dev/null
+++ b/opcodes/alpha-dis.c
@@ -0,0 +1,213 @@
+/* alpha-dis.c -- Disassemble Alpha AXP instructions
+ Copyright 1996, 1999 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@tamu.edu>,
+ patterned after the PPC opcode handling written by Ian Lance Taylor.
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ansidecl.h"
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "opcode/alpha.h"
+
+/* OSF register names. */
+
+static const char * const osf_regnames[64] =
+{
+ "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
+ "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
+ "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
+ "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero",
+ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
+ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
+};
+
+/* VMS register names. */
+
+static const char * const vms_regnames[64] =
+{
+ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
+ "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
+ "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
+ "R24", "AI", "RA", "PV", "AT", "FP", "SP", "RZ",
+ "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
+ "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
+ "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
+ "F24", "F25", "F26", "F27", "F28", "F29", "F30", "FZ"
+};
+
+/* Disassemble Alpha instructions. */
+
+int
+print_insn_alpha (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ static const struct alpha_opcode *opcode_index[AXP_NOPS+1];
+ const char * const * regnames;
+ const struct alpha_opcode *opcode, *opcode_end;
+ const unsigned char *opindex;
+ unsigned insn, op, isa_mask;
+ int need_comma;
+
+ /* Initialize the majorop table the first time through */
+ if (!opcode_index[0])
+ {
+ opcode = alpha_opcodes;
+ opcode_end = opcode + alpha_num_opcodes;
+
+ for (op = 0; op < AXP_NOPS; ++op)
+ {
+ opcode_index[op] = opcode;
+ while (opcode < opcode_end && op == AXP_OP (opcode->opcode))
+ ++opcode;
+ }
+ opcode_index[op] = opcode;
+ }
+
+ if (info->flavour == bfd_target_evax_flavour)
+ regnames = vms_regnames;
+ else
+ regnames = osf_regnames;
+
+ isa_mask = AXP_OPCODE_NOPAL;
+ switch (info->mach)
+ {
+ case bfd_mach_alpha_ev4:
+ isa_mask |= AXP_OPCODE_EV4;
+ break;
+ case bfd_mach_alpha_ev5:
+ isa_mask |= AXP_OPCODE_EV5;
+ break;
+ case bfd_mach_alpha_ev6:
+ isa_mask |= AXP_OPCODE_EV6;
+ break;
+ }
+
+ /* Read the insn into a host word */
+ {
+ bfd_byte buffer[4];
+ int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getl32 (buffer);
+ }
+
+ /* Get the major opcode of the instruction. */
+ op = AXP_OP (insn);
+
+ /* Find the first match in the opcode table. */
+ opcode_end = opcode_index[op+1];
+ for (opcode = opcode_index[op]; opcode < opcode_end; ++opcode)
+ {
+ if ((insn & opcode->mask) != opcode->opcode)
+ continue;
+
+ if (!(opcode->flags & isa_mask))
+ continue;
+
+ /* Make two passes over the operands. First see if any of them
+ have extraction functions, and, if they do, make sure the
+ instruction is valid. */
+ {
+ int invalid = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ const struct alpha_operand *operand = alpha_operands + *opindex;
+ if (operand->extract)
+ (*operand->extract) (insn, &invalid);
+ }
+ if (invalid)
+ continue;
+ }
+
+ /* The instruction is valid. */
+ goto found;
+ }
+
+ /* No instruction found */
+ (*info->fprintf_func) (info->stream, ".long %#08x", insn);
+
+ return 4;
+
+found:
+ (*info->fprintf_func) (info->stream, "%s", opcode->name);
+ if (opcode->operands[0] != 0)
+ (*info->fprintf_func) (info->stream, "\t");
+
+ /* Now extract and print the operands. */
+ need_comma = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ const struct alpha_operand *operand = alpha_operands + *opindex;
+ int value;
+
+ /* Operands that are marked FAKE are simply ignored. We
+ already made sure that the extract function considered
+ the instruction to be valid. */
+ if ((operand->flags & AXP_OPERAND_FAKE) != 0)
+ continue;
+
+ /* Extract the value from the instruction. */
+ if (operand->extract)
+ value = (*operand->extract) (insn, (int *) NULL);
+ else
+ {
+ value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+ if (operand->flags & AXP_OPERAND_SIGNED)
+ {
+ int signbit = 1 << (operand->bits - 1);
+ value = (value ^ signbit) - signbit;
+ }
+ }
+
+ if (need_comma &&
+ ((operand->flags & (AXP_OPERAND_PARENS|AXP_OPERAND_COMMA))
+ != AXP_OPERAND_PARENS))
+ {
+ (*info->fprintf_func) (info->stream, ",");
+ }
+ if (operand->flags & AXP_OPERAND_PARENS)
+ (*info->fprintf_func) (info->stream, "(");
+
+ /* Print the operand as directed by the flags. */
+ if (operand->flags & AXP_OPERAND_IR)
+ (*info->fprintf_func) (info->stream, "%s", regnames[value]);
+ else if (operand->flags & AXP_OPERAND_FPR)
+ (*info->fprintf_func) (info->stream, "%s", regnames[value+32]);
+ else if (operand->flags & AXP_OPERAND_RELATIVE)
+ (*info->print_address_func) (memaddr + 4 + value, info);
+ else if (operand->flags & AXP_OPERAND_SIGNED)
+ (*info->fprintf_func) (info->stream, "%d", value);
+ else
+ (*info->fprintf_func) (info->stream, "%#x", value);
+
+ if (operand->flags & AXP_OPERAND_PARENS)
+ (*info->fprintf_func) (info->stream, ")");
+ need_comma = 1;
+ }
+
+ return 4;
+}
diff --git a/opcodes/alpha-opc.c b/opcodes/alpha-opc.c
new file mode 100644
index 00000000000..cceaf798715
--- /dev/null
+++ b/opcodes/alpha-opc.c
@@ -0,0 +1,1546 @@
+/* alpha-opc.c -- Alpha AXP opcode list
+ Copyright (c) 1996, 1998, 1999 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@cygnus.com>,
+ patterned after the PPC opcode handling written by Ian Lance Taylor.
+
+ This file is part of GDB, GAS, and the GNU binutils.
+
+ GDB, GAS, and the GNU binutils are free software; you can redistribute
+ them and/or modify them under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either version
+ 2, or (at your option) any later version.
+
+ GDB, GAS, and the GNU binutils are distributed in the hope that they
+ 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 file; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/alpha.h"
+#include "bfd.h"
+#include "opintl.h"
+
+/* This file holds the Alpha AXP opcode table. The opcode table includes
+ almost all of the extended instruction mnemonics. This permits the
+ disassembler to use them, and simplifies the assembler logic, at the
+ cost of increasing the table size. The table is strictly constant
+ data, so the compiler should be able to put it in the .text section.
+
+ This file also holds the operand table. All knowledge about inserting
+ operands into instructions and vice-versa is kept in this file.
+
+ The information for the base instruction set was compiled from the
+ _Alpha Architecture Handbook_, Digital Order Number EC-QD2KB-TE,
+ version 2.
+
+ The information for the post-ev5 architecture extensions BWX, CIX and
+ MAX came from version 3 of this same document, which is also available
+ on-line at http://ftp.digital.com/pub/Digital/info/semiconductor
+ /literature/alphahb2.pdf
+
+ The information for the EV4 PALcode instructions was compiled from
+ _DECchip 21064 and DECchip 21064A Alpha AXP Microprocessors Hardware
+ Reference Manual_, Digital Order Number EC-Q9ZUA-TE, preliminary
+ revision dated June 1994.
+
+ The information for the EV5 PALcode instructions was compiled from
+ _Alpha 21164 Microprocessor Hardware Reference Manual_, Digital
+ Order Number EC-QAEQB-TE, preliminary revision dated April 1995. */
+
+/* Local insertion and extraction functions */
+
+static unsigned insert_rba PARAMS((unsigned, int, const char **));
+static unsigned insert_rca PARAMS((unsigned, int, const char **));
+static unsigned insert_za PARAMS((unsigned, int, const char **));
+static unsigned insert_zb PARAMS((unsigned, int, const char **));
+static unsigned insert_zc PARAMS((unsigned, int, const char **));
+static unsigned insert_bdisp PARAMS((unsigned, int, const char **));
+static unsigned insert_jhint PARAMS((unsigned, int, const char **));
+static unsigned insert_ev6hwjhint PARAMS((unsigned, int, const char **));
+
+static int extract_rba PARAMS((unsigned, int *));
+static int extract_rca PARAMS((unsigned, int *));
+static int extract_za PARAMS((unsigned, int *));
+static int extract_zb PARAMS((unsigned, int *));
+static int extract_zc PARAMS((unsigned, int *));
+static int extract_bdisp PARAMS((unsigned, int *));
+static int extract_jhint PARAMS((unsigned, int *));
+static int extract_ev6hwjhint PARAMS((unsigned, int *));
+
+
+/* The operands table */
+
+const struct alpha_operand alpha_operands[] =
+{
+ /* The fields are bits, shift, insert, extract, flags */
+ /* The zero index is used to indicate end-of-list */
+#define UNUSED 0
+ { 0, 0, 0, 0, 0 },
+
+ /* The plain integer register fields */
+#define RA (UNUSED + 1)
+ { 5, 21, 0, AXP_OPERAND_IR, 0, 0 },
+#define RB (RA + 1)
+ { 5, 16, 0, AXP_OPERAND_IR, 0, 0 },
+#define RC (RB + 1)
+ { 5, 0, 0, AXP_OPERAND_IR, 0, 0 },
+
+ /* The plain fp register fields */
+#define FA (RC + 1)
+ { 5, 21, 0, AXP_OPERAND_FPR, 0, 0 },
+#define FB (FA + 1)
+ { 5, 16, 0, AXP_OPERAND_FPR, 0, 0 },
+#define FC (FB + 1)
+ { 5, 0, 0, AXP_OPERAND_FPR, 0, 0 },
+
+ /* The integer registers when they are ZERO */
+#define ZA (FC + 1)
+ { 5, 21, 0, AXP_OPERAND_FAKE, insert_za, extract_za },
+#define ZB (ZA + 1)
+ { 5, 16, 0, AXP_OPERAND_FAKE, insert_zb, extract_zb },
+#define ZC (ZB + 1)
+ { 5, 0, 0, AXP_OPERAND_FAKE, insert_zc, extract_zc },
+
+ /* The RB field when it needs parentheses */
+#define PRB (ZC + 1)
+ { 5, 16, 0, AXP_OPERAND_IR|AXP_OPERAND_PARENS, 0, 0 },
+
+ /* The RB field when it needs parentheses _and_ a preceding comma */
+#define CPRB (PRB + 1)
+ { 5, 16, 0,
+ AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA, 0, 0 },
+
+ /* The RB field when it must be the same as the RA field */
+#define RBA (CPRB + 1)
+ { 5, 16, 0, AXP_OPERAND_FAKE, insert_rba, extract_rba },
+
+ /* The RC field when it must be the same as the RB field */
+#define RCA (RBA + 1)
+ { 5, 0, 0, AXP_OPERAND_FAKE, insert_rca, extract_rca },
+
+ /* The RC field when it can *default* to RA */
+#define DRC1 (RCA + 1)
+ { 5, 0, 0,
+ AXP_OPERAND_IR|AXP_OPERAND_DEFAULT_FIRST, 0, 0 },
+
+ /* The RC field when it can *default* to RB */
+#define DRC2 (DRC1 + 1)
+ { 5, 0, 0,
+ AXP_OPERAND_IR|AXP_OPERAND_DEFAULT_SECOND, 0, 0 },
+
+ /* The FC field when it can *default* to RA */
+#define DFC1 (DRC2 + 1)
+ { 5, 0, 0,
+ AXP_OPERAND_FPR|AXP_OPERAND_DEFAULT_FIRST, 0, 0 },
+
+ /* The FC field when it can *default* to RB */
+#define DFC2 (DFC1 + 1)
+ { 5, 0, 0,
+ AXP_OPERAND_FPR|AXP_OPERAND_DEFAULT_SECOND, 0, 0 },
+
+ /* The unsigned 8-bit literal of Operate format insns */
+#define LIT (DFC2 + 1)
+ { 8, 13, -LIT, AXP_OPERAND_UNSIGNED, 0, 0 },
+
+ /* The signed 16-bit displacement of Memory format insns. From here
+ we can't tell what relocation should be used, so don't use a default. */
+#define MDISP (LIT + 1)
+ { 16, 0, -MDISP, AXP_OPERAND_SIGNED, 0, 0 },
+
+ /* The signed "23-bit" aligned displacement of Branch format insns */
+#define BDISP (MDISP + 1)
+ { 21, 0, BFD_RELOC_23_PCREL_S2,
+ AXP_OPERAND_RELATIVE, insert_bdisp, extract_bdisp },
+
+ /* The 26-bit PALcode function */
+#define PALFN (BDISP + 1)
+ { 26, 0, -PALFN, AXP_OPERAND_UNSIGNED, 0, 0 },
+
+ /* The optional signed "16-bit" aligned displacement of the JMP/JSR hint */
+#define JMPHINT (PALFN + 1)
+ { 14, 0, BFD_RELOC_ALPHA_HINT,
+ AXP_OPERAND_RELATIVE|AXP_OPERAND_DEFAULT_ZERO|AXP_OPERAND_NOOVERFLOW,
+ insert_jhint, extract_jhint },
+
+ /* The optional hint to RET/JSR_COROUTINE */
+#define RETHINT (JMPHINT + 1)
+ { 14, 0, -RETHINT,
+ AXP_OPERAND_UNSIGNED|AXP_OPERAND_DEFAULT_ZERO, 0, 0 },
+
+ /* The 12-bit displacement for the ev[46] hw_{ld,st} (pal1b/pal1f) insns */
+#define EV4HWDISP (RETHINT + 1)
+#define EV6HWDISP (EV4HWDISP)
+ { 12, 0, -EV4HWDISP, AXP_OPERAND_SIGNED, 0, 0 },
+
+ /* The 5-bit index for the ev4 hw_m[ft]pr (pal19/pal1d) insns */
+#define EV4HWINDEX (EV4HWDISP + 1)
+ { 5, 0, -EV4HWINDEX, AXP_OPERAND_UNSIGNED, 0, 0 },
+
+ /* The 8-bit index for the oddly unqualified hw_m[tf]pr insns
+ that occur in DEC PALcode. */
+#define EV4EXTHWINDEX (EV4HWINDEX + 1)
+ { 8, 0, -EV4EXTHWINDEX, AXP_OPERAND_UNSIGNED, 0, 0 },
+
+ /* The 10-bit displacement for the ev5 hw_{ld,st} (pal1b/pal1f) insns */
+#define EV5HWDISP (EV4EXTHWINDEX + 1)
+ { 10, 0, -EV5HWDISP, AXP_OPERAND_SIGNED, 0, 0 },
+
+ /* The 16-bit index for the ev5 hw_m[ft]pr (pal19/pal1d) insns */
+#define EV5HWINDEX (EV5HWDISP + 1)
+ { 16, 0, -EV5HWINDEX, AXP_OPERAND_UNSIGNED, 0, 0 },
+
+ /* The 16-bit combined index/scoreboard mask for the ev6
+ hw_m[ft]pr (pal19/pal1d) insns */
+#define EV6HWINDEX (EV5HWINDEX + 1)
+ { 16, 0, -EV6HWINDEX, AXP_OPERAND_UNSIGNED, 0, 0 },
+
+ /* The 13-bit branch hint for the ev6 hw_jmp/jsr (pal1e) insn */
+#define EV6HWJMPHINT (EV6HWINDEX+ 1)
+ { 8, 0, -EV6HWJMPHINT,
+ AXP_OPERAND_RELATIVE|AXP_OPERAND_DEFAULT_ZERO|AXP_OPERAND_NOOVERFLOW,
+ insert_ev6hwjhint, extract_ev6hwjhint }
+};
+
+const int alpha_num_operands = sizeof(alpha_operands)/sizeof(*alpha_operands);
+
+/* The RB field when it is the same as the RA field in the same insn.
+ This operand is marked fake. The insertion function just copies
+ the RA field into the RB field, and the extraction function just
+ checks that the fields are the same. */
+
+/*ARGSUSED*/
+static unsigned
+insert_rba(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 21) & 0x1f) << 16);
+}
+
+static int
+extract_rba(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+
+/* The same for the RC field */
+
+/*ARGSUSED*/
+static unsigned
+insert_rca(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ return insn | ((insn >> 21) & 0x1f);
+}
+
+static int
+extract_rca(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 21) & 0x1f) != (insn & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+
+/* Fake arguments in which the registers must be set to ZERO */
+
+/*ARGSUSED*/
+static unsigned
+insert_za(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ return insn | (31 << 21);
+}
+
+static int
+extract_za(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL && ((insn >> 21) & 0x1f) != 31)
+ *invalid = 1;
+ return 0;
+}
+
+/*ARGSUSED*/
+static unsigned
+insert_zb(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ return insn | (31 << 16);
+}
+
+static int
+extract_zb(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL && ((insn >> 16) & 0x1f) != 31)
+ *invalid = 1;
+ return 0;
+}
+
+/*ARGSUSED*/
+static unsigned
+insert_zc(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ return insn | 31;
+}
+
+static int
+extract_zc(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL && (insn & 0x1f) != 31)
+ *invalid = 1;
+ return 0;
+}
+
+
+/* The displacement field of a Branch format insn. */
+
+static unsigned
+insert_bdisp(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **)NULL && (value & 3))
+ *errmsg = _("branch operand unaligned");
+ return insn | ((value / 4) & 0x1FFFFF);
+}
+
+/*ARGSUSED*/
+static int
+extract_bdisp(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ return 4 * (((insn & 0x1FFFFF) ^ 0x100000) - 0x100000);
+}
+
+
+/* The hint field of a JMP/JSR insn. */
+
+static unsigned
+insert_jhint(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **)NULL && (value & 3))
+ *errmsg = _("jump hint unaligned");
+ return insn | ((value / 4) & 0x3FFF);
+}
+
+/*ARGSUSED*/
+static int
+extract_jhint(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ return 4 * (((insn & 0x3FFF) ^ 0x2000) - 0x2000);
+}
+
+/* The hint field of an EV6 HW_JMP/JSR insn. */
+
+static unsigned
+insert_ev6hwjhint(insn, value, errmsg)
+ unsigned insn;
+ int value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **)NULL && (value & 3))
+ *errmsg = _("jump hint unaligned");
+ return insn | ((value / 4) & 0x1FFF);
+}
+
+/*ARGSUSED*/
+static int
+extract_ev6hwjhint(insn, invalid)
+ unsigned insn;
+ int *invalid;
+{
+ return 4 * (((insn & 0x1FFF) ^ 0x1000) - 0x1000);
+}
+
+
+/* Macros used to form opcodes */
+
+/* The main opcode */
+#define OP(x) (((x) & 0x3F) << 26)
+#define OP_MASK 0xFC000000
+
+/* Branch format instructions */
+#define BRA_(oo) OP(oo)
+#define BRA_MASK OP_MASK
+#define BRA(oo) BRA_(oo), BRA_MASK
+
+/* Floating point format instructions */
+#define FP_(oo,fff) (OP(oo) | (((fff) & 0x7FF) << 5))
+#define FP_MASK (OP_MASK | 0xFFE0)
+#define FP(oo,fff) FP_(oo,fff), FP_MASK
+
+/* Memory format instructions */
+#define MEM_(oo) OP(oo)
+#define MEM_MASK OP_MASK
+#define MEM(oo) MEM_(oo), MEM_MASK
+
+/* Memory/Func Code format instructions */
+#define MFC_(oo,ffff) (OP(oo) | ((ffff) & 0xFFFF))
+#define MFC_MASK (OP_MASK | 0xFFFF)
+#define MFC(oo,ffff) MFC_(oo,ffff), MFC_MASK
+
+/* Memory/Branch format instructions */
+#define MBR_(oo,h) (OP(oo) | (((h) & 3) << 14))
+#define MBR_MASK (OP_MASK | 0xC000)
+#define MBR(oo,h) MBR_(oo,h), MBR_MASK
+
+/* Operate format instructions. The OPRL variant specifies a
+ literal second argument. */
+#define OPR_(oo,ff) (OP(oo) | (((ff) & 0x7F) << 5))
+#define OPRL_(oo,ff) (OPR_((oo),(ff)) | 0x1000)
+#define OPR_MASK (OP_MASK | 0x1FE0)
+#define OPR(oo,ff) OPR_(oo,ff), OPR_MASK
+#define OPRL(oo,ff) OPRL_(oo,ff), OPR_MASK
+
+/* Generic PALcode format instructions */
+#define PCD_(oo) OP(oo)
+#define PCD_MASK OP_MASK
+#define PCD(oo) PCD_(oo), PCD_MASK
+
+/* Specific PALcode instructions */
+#define SPCD_(oo,ffff) (OP(oo) | ((ffff) & 0x3FFFFFF))
+#define SPCD_MASK 0xFFFFFFFF
+#define SPCD(oo,ffff) SPCD_(oo,ffff), SPCD_MASK
+
+/* Hardware memory (hw_{ld,st}) instructions */
+#define EV4HWMEM_(oo,f) (OP(oo) | (((f) & 0xF) << 12))
+#define EV4HWMEM_MASK (OP_MASK | 0xF000)
+#define EV4HWMEM(oo,f) EV4HWMEM_(oo,f), EV4HWMEM_MASK
+
+#define EV5HWMEM_(oo,f) (OP(oo) | (((f) & 0x3F) << 10))
+#define EV5HWMEM_MASK (OP_MASK | 0xF800)
+#define EV5HWMEM(oo,f) EV5HWMEM_(oo,f), EV5HWMEM_MASK
+
+#define EV6HWMEM_(oo,f) (OP(oo) | (((f) & 0xF) << 12))
+#define EV6HWMEM_MASK (OP_MASK | 0xF000)
+#define EV6HWMEM(oo,f) EV6HWMEM_(oo,f), EV6HWMEM_MASK
+
+#define EV6HWMBR_(oo,h) (OP(oo) | (((h) & 7) << 13))
+#define EV6HWMBR_MASK (OP_MASK | 0xE000)
+#define EV6HWMBR(oo,h) EV6HWMBR_(oo,h), EV6HWMBR_MASK
+
+/* Abbreviations for instruction subsets. */
+#define BASE AXP_OPCODE_BASE
+#define EV4 AXP_OPCODE_EV4
+#define EV5 AXP_OPCODE_EV5
+#define EV6 AXP_OPCODE_EV6
+#define BWX AXP_OPCODE_BWX
+#define CIX AXP_OPCODE_CIX
+#define MAX AXP_OPCODE_MAX
+
+/* Common combinations of arguments */
+#define ARG_NONE { 0 }
+#define ARG_BRA { RA, BDISP }
+#define ARG_FBRA { FA, BDISP }
+#define ARG_FP { FA, FB, DFC1 }
+#define ARG_FPZ1 { ZA, FB, DFC1 }
+#define ARG_MEM { RA, MDISP, PRB }
+#define ARG_FMEM { FA, MDISP, PRB }
+#define ARG_OPR { RA, RB, DRC1 }
+#define ARG_OPRL { RA, LIT, DRC1 }
+#define ARG_OPRZ1 { ZA, RB, DRC1 }
+#define ARG_OPRLZ1 { ZA, LIT, RC }
+#define ARG_PCD { PALFN }
+#define ARG_EV4HWMEM { RA, EV4HWDISP, PRB }
+#define ARG_EV4HWMPR { RA, RBA, EV4HWINDEX }
+#define ARG_EV5HWMEM { RA, EV5HWDISP, PRB }
+#define ARG_EV6HWMEM { RA, EV6HWDISP, PRB }
+
+/* The opcode table.
+
+ The format of the opcode table is:
+
+ NAME OPCODE MASK { OPERANDS }
+
+ NAME is the name of the instruction.
+
+ OPCODE is the instruction opcode.
+
+ MASK is the opcode mask; this is used to tell the disassembler
+ which bits in the actual opcode must match OPCODE.
+
+ OPERANDS is the list of operands.
+
+ The preceding macros merge the text of the OPCODE and MASK fields.
+
+ The disassembler reads the table in order and prints the first
+ instruction which matches, so this table is sorted to put more
+ specific instructions before more general instructions.
+
+ Otherwise, it is sorted by major opcode and minor function code.
+
+ There are three classes of not-really-instructions in this table:
+
+ ALIAS is another name for another instruction. Some of
+ these come from the Architecture Handbook, some
+ come from the original gas opcode tables. In all
+ cases, the functionality of the opcode is unchanged.
+
+ PSEUDO a stylized code form endorsed by Chapter A.4 of the
+ Architecture Handbook.
+
+ EXTRA a stylized code form found in the original gas tables.
+
+ And two annotations:
+
+ EV56 BUT opcodes that are officially introduced as of the ev56,
+ but with defined results on previous implementations.
+
+ EV56 UNA opcodes that were introduced as of the ev56 with
+ presumably undefined results on previous implementations
+ that were not assigned to a particular extension.
+*/
+
+const struct alpha_opcode alpha_opcodes[] = {
+ { "halt", SPCD(0x00,0x0000), BASE, ARG_NONE },
+ { "draina", SPCD(0x00,0x0002), BASE, ARG_NONE },
+ { "bpt", SPCD(0x00,0x0080), BASE, ARG_NONE },
+ { "callsys", SPCD(0x00,0x0083), BASE, ARG_NONE },
+ { "chmk", SPCD(0x00,0x0083), BASE, ARG_NONE },
+ { "imb", SPCD(0x00,0x0086), BASE, ARG_NONE },
+ { "call_pal", PCD(0x00), BASE, ARG_PCD },
+ { "pal", PCD(0x00), BASE, ARG_PCD }, /* alias */
+
+ { "lda", MEM(0x08), BASE, ARG_MEM },
+ { "ldah", MEM(0x09), BASE, ARG_MEM },
+ { "ldbu", MEM(0x0A), BWX, ARG_MEM },
+ { "unop", MEM(0x0B), BASE, { ZA } }, /* pseudo */
+ { "ldq_u", MEM(0x0B), BASE, ARG_MEM },
+ { "ldwu", MEM(0x0C), BWX, ARG_MEM },
+ { "stw", MEM(0x0D), BWX, ARG_MEM },
+ { "stb", MEM(0x0E), BWX, ARG_MEM },
+ { "stq_u", MEM(0x0F), BASE, ARG_MEM },
+
+ { "sextl", OPR(0x10,0x00), BASE, ARG_OPRZ1 }, /* pseudo */
+ { "sextl", OPRL(0x10,0x00), BASE, ARG_OPRLZ1 }, /* pseudo */
+ { "addl", OPR(0x10,0x00), BASE, ARG_OPR },
+ { "addl", OPRL(0x10,0x00), BASE, ARG_OPRL },
+ { "s4addl", OPR(0x10,0x02), BASE, ARG_OPR },
+ { "s4addl", OPRL(0x10,0x02), BASE, ARG_OPRL },
+ { "negl", OPR(0x10,0x09), BASE, ARG_OPRZ1 }, /* pseudo */
+ { "negl", OPRL(0x10,0x09), BASE, ARG_OPRLZ1 }, /* pseudo */
+ { "subl", OPR(0x10,0x09), BASE, ARG_OPR },
+ { "subl", OPRL(0x10,0x09), BASE, ARG_OPRL },
+ { "s4subl", OPR(0x10,0x0B), BASE, ARG_OPR },
+ { "s4subl", OPRL(0x10,0x0B), BASE, ARG_OPRL },
+ { "cmpbge", OPR(0x10,0x0F), BASE, ARG_OPR },
+ { "cmpbge", OPRL(0x10,0x0F), BASE, ARG_OPRL },
+ { "s8addl", OPR(0x10,0x12), BASE, ARG_OPR },
+ { "s8addl", OPRL(0x10,0x12), BASE, ARG_OPRL },
+ { "s8subl", OPR(0x10,0x1B), BASE, ARG_OPR },
+ { "s8subl", OPRL(0x10,0x1B), BASE, ARG_OPRL },
+ { "cmpult", OPR(0x10,0x1D), BASE, ARG_OPR },
+ { "cmpult", OPRL(0x10,0x1D), BASE, ARG_OPRL },
+ { "addq", OPR(0x10,0x20), BASE, ARG_OPR },
+ { "addq", OPRL(0x10,0x20), BASE, ARG_OPRL },
+ { "s4addq", OPR(0x10,0x22), BASE, ARG_OPR },
+ { "s4addq", OPRL(0x10,0x22), BASE, ARG_OPRL },
+ { "negq", OPR(0x10,0x29), BASE, ARG_OPRZ1 }, /* pseudo */
+ { "negq", OPRL(0x10,0x29), BASE, ARG_OPRLZ1 }, /* pseudo */
+ { "subq", OPR(0x10,0x29), BASE, ARG_OPR },
+ { "subq", OPRL(0x10,0x29), BASE, ARG_OPRL },
+ { "s4subq", OPR(0x10,0x2B), BASE, ARG_OPR },
+ { "s4subq", OPRL(0x10,0x2B), BASE, ARG_OPRL },
+ { "cmpeq", OPR(0x10,0x2D), BASE, ARG_OPR },
+ { "cmpeq", OPRL(0x10,0x2D), BASE, ARG_OPRL },
+ { "s8addq", OPR(0x10,0x32), BASE, ARG_OPR },
+ { "s8addq", OPRL(0x10,0x32), BASE, ARG_OPRL },
+ { "s8subq", OPR(0x10,0x3B), BASE, ARG_OPR },
+ { "s8subq", OPRL(0x10,0x3B), BASE, ARG_OPRL },
+ { "cmpule", OPR(0x10,0x3D), BASE, ARG_OPR },
+ { "cmpule", OPRL(0x10,0x3D), BASE, ARG_OPRL },
+ { "addl/v", OPR(0x10,0x40), BASE, ARG_OPR },
+ { "addl/v", OPRL(0x10,0x40), BASE, ARG_OPRL },
+ { "negl/v", OPR(0x10,0x49), BASE, ARG_OPRZ1 }, /* pseudo */
+ { "negl/v", OPRL(0x10,0x49), BASE, ARG_OPRLZ1 }, /* pseudo */
+ { "subl/v", OPR(0x10,0x49), BASE, ARG_OPR },
+ { "subl/v", OPRL(0x10,0x49), BASE, ARG_OPRL },
+ { "cmplt", OPR(0x10,0x4D), BASE, ARG_OPR },
+ { "cmplt", OPRL(0x10,0x4D), BASE, ARG_OPRL },
+ { "addq/v", OPR(0x10,0x60), BASE, ARG_OPR },
+ { "addq/v", OPRL(0x10,0x60), BASE, ARG_OPRL },
+ { "negq/v", OPR(0x10,0x69), BASE, ARG_OPRZ1 }, /* pseudo */
+ { "negq/v", OPRL(0x10,0x69), BASE, ARG_OPRLZ1 }, /* pseudo */
+ { "subq/v", OPR(0x10,0x69), BASE, ARG_OPR },
+ { "subq/v", OPRL(0x10,0x69), BASE, ARG_OPRL },
+ { "cmple", OPR(0x10,0x6D), BASE, ARG_OPR },
+ { "cmple", OPRL(0x10,0x6D), BASE, ARG_OPRL },
+
+ { "and", OPR(0x11,0x00), BASE, ARG_OPR },
+ { "and", OPRL(0x11,0x00), BASE, ARG_OPRL },
+ { "andnot", OPR(0x11,0x08), BASE, ARG_OPR }, /* alias */
+ { "andnot", OPRL(0x11,0x08), BASE, ARG_OPRL }, /* alias */
+ { "bic", OPR(0x11,0x08), BASE, ARG_OPR },
+ { "bic", OPRL(0x11,0x08), BASE, ARG_OPRL },
+ { "cmovlbs", OPR(0x11,0x14), BASE, ARG_OPR },
+ { "cmovlbs", OPRL(0x11,0x14), BASE, ARG_OPRL },
+ { "cmovlbc", OPR(0x11,0x16), BASE, ARG_OPR },
+ { "cmovlbc", OPRL(0x11,0x16), BASE, ARG_OPRL },
+ { "nop", OPR(0x11,0x20), BASE, { ZA, ZB, ZC } }, /* pseudo */
+ { "clr", OPR(0x11,0x20), BASE, { ZA, ZB, RC } }, /* pseudo */
+ { "mov", OPR(0x11,0x20), BASE, { ZA, RB, RC } }, /* pseudo */
+ { "mov", OPR(0x11,0x20), BASE, { RA, RBA, RC } }, /* pseudo */
+ { "mov", OPRL(0x11,0x20), BASE, { ZA, LIT, RC } }, /* pseudo */
+ { "or", OPR(0x11,0x20), BASE, ARG_OPR }, /* alias */
+ { "or", OPRL(0x11,0x20), BASE, ARG_OPRL }, /* alias */
+ { "bis", OPR(0x11,0x20), BASE, ARG_OPR },
+ { "bis", OPRL(0x11,0x20), BASE, ARG_OPRL },
+ { "cmoveq", OPR(0x11,0x24), BASE, ARG_OPR },
+ { "cmoveq", OPRL(0x11,0x24), BASE, ARG_OPRL },
+ { "cmovne", OPR(0x11,0x26), BASE, ARG_OPR },
+ { "cmovne", OPRL(0x11,0x26), BASE, ARG_OPRL },
+ { "not", OPR(0x11,0x28), BASE, ARG_OPRZ1 }, /* pseudo */
+ { "not", OPRL(0x11,0x28), BASE, ARG_OPRLZ1 }, /* pseudo */
+ { "ornot", OPR(0x11,0x28), BASE, ARG_OPR },
+ { "ornot", OPRL(0x11,0x28), BASE, ARG_OPRL },
+ { "xor", OPR(0x11,0x40), BASE, ARG_OPR },
+ { "xor", OPRL(0x11,0x40), BASE, ARG_OPRL },
+ { "cmovlt", OPR(0x11,0x44), BASE, ARG_OPR },
+ { "cmovlt", OPRL(0x11,0x44), BASE, ARG_OPRL },
+ { "cmovge", OPR(0x11,0x46), BASE, ARG_OPR },
+ { "cmovge", OPRL(0x11,0x46), BASE, ARG_OPRL },
+ { "eqv", OPR(0x11,0x48), BASE, ARG_OPR },
+ { "eqv", OPRL(0x11,0x48), BASE, ARG_OPRL },
+ { "xornot", OPR(0x11,0x48), BASE, ARG_OPR }, /* alias */
+ { "xornot", OPRL(0x11,0x48), BASE, ARG_OPRL }, /* alias */
+ { "amask", OPR(0x11,0x61), BASE, ARG_OPRZ1 }, /* ev56 but */
+ { "amask", OPRL(0x11,0x61), BASE, ARG_OPRLZ1 }, /* ev56 but */
+ { "cmovle", OPR(0x11,0x64), BASE, ARG_OPR },
+ { "cmovle", OPRL(0x11,0x64), BASE, ARG_OPRL },
+ { "cmovgt", OPR(0x11,0x66), BASE, ARG_OPR },
+ { "cmovgt", OPRL(0x11,0x66), BASE, ARG_OPRL },
+ { "implver", OPRL_(0x11,0x6C)|(31<<21)|(1<<13),
+ 0xFFFFFFE0, BASE, { RC } }, /* ev56 but */
+
+ { "mskbl", OPR(0x12,0x02), BASE, ARG_OPR },
+ { "mskbl", OPRL(0x12,0x02), BASE, ARG_OPRL },
+ { "extbl", OPR(0x12,0x06), BASE, ARG_OPR },
+ { "extbl", OPRL(0x12,0x06), BASE, ARG_OPRL },
+ { "insbl", OPR(0x12,0x0B), BASE, ARG_OPR },
+ { "insbl", OPRL(0x12,0x0B), BASE, ARG_OPRL },
+ { "mskwl", OPR(0x12,0x12), BASE, ARG_OPR },
+ { "mskwl", OPRL(0x12,0x12), BASE, ARG_OPRL },
+ { "extwl", OPR(0x12,0x16), BASE, ARG_OPR },
+ { "extwl", OPRL(0x12,0x16), BASE, ARG_OPRL },
+ { "inswl", OPR(0x12,0x1B), BASE, ARG_OPR },
+ { "inswl", OPRL(0x12,0x1B), BASE, ARG_OPRL },
+ { "mskll", OPR(0x12,0x22), BASE, ARG_OPR },
+ { "mskll", OPRL(0x12,0x22), BASE, ARG_OPRL },
+ { "extll", OPR(0x12,0x26), BASE, ARG_OPR },
+ { "extll", OPRL(0x12,0x26), BASE, ARG_OPRL },
+ { "insll", OPR(0x12,0x2B), BASE, ARG_OPR },
+ { "insll", OPRL(0x12,0x2B), BASE, ARG_OPRL },
+ { "zap", OPR(0x12,0x30), BASE, ARG_OPR },
+ { "zap", OPRL(0x12,0x30), BASE, ARG_OPRL },
+ { "zapnot", OPR(0x12,0x31), BASE, ARG_OPR },
+ { "zapnot", OPRL(0x12,0x31), BASE, ARG_OPRL },
+ { "mskql", OPR(0x12,0x32), BASE, ARG_OPR },
+ { "mskql", OPRL(0x12,0x32), BASE, ARG_OPRL },
+ { "srl", OPR(0x12,0x34), BASE, ARG_OPR },
+ { "srl", OPRL(0x12,0x34), BASE, ARG_OPRL },
+ { "extql", OPR(0x12,0x36), BASE, ARG_OPR },
+ { "extql", OPRL(0x12,0x36), BASE, ARG_OPRL },
+ { "sll", OPR(0x12,0x39), BASE, ARG_OPR },
+ { "sll", OPRL(0x12,0x39), BASE, ARG_OPRL },
+ { "insql", OPR(0x12,0x3B), BASE, ARG_OPR },
+ { "insql", OPRL(0x12,0x3B), BASE, ARG_OPRL },
+ { "sra", OPR(0x12,0x3C), BASE, ARG_OPR },
+ { "sra", OPRL(0x12,0x3C), BASE, ARG_OPRL },
+ { "mskwh", OPR(0x12,0x52), BASE, ARG_OPR },
+ { "mskwh", OPRL(0x12,0x52), BASE, ARG_OPRL },
+ { "inswh", OPR(0x12,0x57), BASE, ARG_OPR },
+ { "inswh", OPRL(0x12,0x57), BASE, ARG_OPRL },
+ { "extwh", OPR(0x12,0x5A), BASE, ARG_OPR },
+ { "extwh", OPRL(0x12,0x5A), BASE, ARG_OPRL },
+ { "msklh", OPR(0x12,0x62), BASE, ARG_OPR },
+ { "msklh", OPRL(0x12,0x62), BASE, ARG_OPRL },
+ { "inslh", OPR(0x12,0x67), BASE, ARG_OPR },
+ { "inslh", OPRL(0x12,0x67), BASE, ARG_OPRL },
+ { "extlh", OPR(0x12,0x6A), BASE, ARG_OPR },
+ { "extlh", OPRL(0x12,0x6A), BASE, ARG_OPRL },
+ { "mskqh", OPR(0x12,0x72), BASE, ARG_OPR },
+ { "mskqh", OPRL(0x12,0x72), BASE, ARG_OPRL },
+ { "insqh", OPR(0x12,0x77), BASE, ARG_OPR },
+ { "insqh", OPRL(0x12,0x77), BASE, ARG_OPRL },
+ { "extqh", OPR(0x12,0x7A), BASE, ARG_OPR },
+ { "extqh", OPRL(0x12,0x7A), BASE, ARG_OPRL },
+
+ { "mull", OPR(0x13,0x00), BASE, ARG_OPR },
+ { "mull", OPRL(0x13,0x00), BASE, ARG_OPRL },
+ { "mulq", OPR(0x13,0x20), BASE, ARG_OPR },
+ { "mulq", OPRL(0x13,0x20), BASE, ARG_OPRL },
+ { "umulh", OPR(0x13,0x30), BASE, ARG_OPR },
+ { "umulh", OPRL(0x13,0x30), BASE, ARG_OPRL },
+ { "mull/v", OPR(0x13,0x40), BASE, ARG_OPR },
+ { "mull/v", OPRL(0x13,0x40), BASE, ARG_OPRL },
+ { "mulq/v", OPR(0x13,0x60), BASE, ARG_OPR },
+ { "mulq/v", OPRL(0x13,0x60), BASE, ARG_OPRL },
+
+ { "itofs", FP(0x14,0x004), CIX, { RA, ZB, FC } },
+ { "sqrtf/c", FP(0x14,0x00A), CIX, ARG_FPZ1 },
+ { "sqrts/c", FP(0x14,0x00B), CIX, ARG_FPZ1 },
+ { "itoff", FP(0x14,0x014), CIX, { RA, ZB, FC } },
+ { "itoft", FP(0x14,0x024), CIX, { RA, ZB, FC } },
+ { "sqrtg/c", FP(0x14,0x02A), CIX, ARG_FPZ1 },
+ { "sqrtt/c", FP(0x14,0x02B), CIX, ARG_FPZ1 },
+ { "sqrts/m", FP(0x14,0x04B), CIX, ARG_FPZ1 },
+ { "sqrtt/m", FP(0x14,0x06B), CIX, ARG_FPZ1 },
+ { "sqrtf", FP(0x14,0x08A), CIX, ARG_FPZ1 },
+ { "sqrts", FP(0x14,0x08B), CIX, ARG_FPZ1 },
+ { "sqrtg", FP(0x14,0x0AA), CIX, ARG_FPZ1 },
+ { "sqrtt", FP(0x14,0x0AB), CIX, ARG_FPZ1 },
+ { "sqrts/d", FP(0x14,0x0CB), CIX, ARG_FPZ1 },
+ { "sqrtt/d", FP(0x14,0x0EB), CIX, ARG_FPZ1 },
+ { "sqrtf/uc", FP(0x14,0x10A), CIX, ARG_FPZ1 },
+ { "sqrts/uc", FP(0x14,0x10B), CIX, ARG_FPZ1 },
+ { "sqrtg/uc", FP(0x14,0x12A), CIX, ARG_FPZ1 },
+ { "sqrtt/uc", FP(0x14,0x12B), CIX, ARG_FPZ1 },
+ { "sqrts/um", FP(0x14,0x14B), CIX, ARG_FPZ1 },
+ { "sqrtt/um", FP(0x14,0x16B), CIX, ARG_FPZ1 },
+ { "sqrtf/u", FP(0x14,0x18A), CIX, ARG_FPZ1 },
+ { "sqrts/u", FP(0x14,0x18B), CIX, ARG_FPZ1 },
+ { "sqrtg/u", FP(0x14,0x1AA), CIX, ARG_FPZ1 },
+ { "sqrtt/u", FP(0x14,0x1AB), CIX, ARG_FPZ1 },
+ { "sqrts/ud", FP(0x14,0x1CB), CIX, ARG_FPZ1 },
+ { "sqrtt/ud", FP(0x14,0x1EB), CIX, ARG_FPZ1 },
+ { "sqrtf/sc", FP(0x14,0x40A), CIX, ARG_FPZ1 },
+ { "sqrtg/sc", FP(0x14,0x42A), CIX, ARG_FPZ1 },
+ { "sqrtf/s", FP(0x14,0x48A), CIX, ARG_FPZ1 },
+ { "sqrtg/s", FP(0x14,0x4AA), CIX, ARG_FPZ1 },
+ { "sqrtf/suc", FP(0x14,0x50A), CIX, ARG_FPZ1 },
+ { "sqrts/suc", FP(0x14,0x50B), CIX, ARG_FPZ1 },
+ { "sqrtg/suc", FP(0x14,0x52A), CIX, ARG_FPZ1 },
+ { "sqrtt/suc", FP(0x14,0x52B), CIX, ARG_FPZ1 },
+ { "sqrts/sum", FP(0x14,0x54B), CIX, ARG_FPZ1 },
+ { "sqrtt/sum", FP(0x14,0x56B), CIX, ARG_FPZ1 },
+ { "sqrtf/su", FP(0x14,0x58A), CIX, ARG_FPZ1 },
+ { "sqrts/su", FP(0x14,0x58B), CIX, ARG_FPZ1 },
+ { "sqrtg/su", FP(0x14,0x5AA), CIX, ARG_FPZ1 },
+ { "sqrtt/su", FP(0x14,0x5AB), CIX, ARG_FPZ1 },
+ { "sqrts/sud", FP(0x14,0x5CB), CIX, ARG_FPZ1 },
+ { "sqrtt/sud", FP(0x14,0x5EB), CIX, ARG_FPZ1 },
+ { "sqrts/suic", FP(0x14,0x70B), CIX, ARG_FPZ1 },
+ { "sqrtt/suic", FP(0x14,0x72B), CIX, ARG_FPZ1 },
+ { "sqrts/suim", FP(0x14,0x74B), CIX, ARG_FPZ1 },
+ { "sqrtt/suim", FP(0x14,0x76B), CIX, ARG_FPZ1 },
+ { "sqrts/sui", FP(0x14,0x78B), CIX, ARG_FPZ1 },
+ { "sqrtt/sui", FP(0x14,0x7AB), CIX, ARG_FPZ1 },
+ { "sqrts/suid", FP(0x14,0x7CB), CIX, ARG_FPZ1 },
+ { "sqrtt/suid", FP(0x14,0x7EB), CIX, ARG_FPZ1 },
+
+ { "addf/c", FP(0x15,0x000), BASE, ARG_FP },
+ { "subf/c", FP(0x15,0x001), BASE, ARG_FP },
+ { "mulf/c", FP(0x15,0x002), BASE, ARG_FP },
+ { "divf/c", FP(0x15,0x003), BASE, ARG_FP },
+ { "cvtdg/c", FP(0x15,0x01E), BASE, ARG_FPZ1 },
+ { "addg/c", FP(0x15,0x020), BASE, ARG_FP },
+ { "subg/c", FP(0x15,0x021), BASE, ARG_FP },
+ { "mulg/c", FP(0x15,0x022), BASE, ARG_FP },
+ { "divg/c", FP(0x15,0x023), BASE, ARG_FP },
+ { "cvtgf/c", FP(0x15,0x02C), BASE, ARG_FPZ1 },
+ { "cvtgd/c", FP(0x15,0x02D), BASE, ARG_FPZ1 },
+ { "cvtgq/c", FP(0x15,0x02F), BASE, ARG_FPZ1 },
+ { "cvtqf/c", FP(0x15,0x03C), BASE, ARG_FPZ1 },
+ { "cvtqg/c", FP(0x15,0x03E), BASE, ARG_FPZ1 },
+ { "addf", FP(0x15,0x080), BASE, ARG_FP },
+ { "negf", FP(0x15,0x081), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subf", FP(0x15,0x081), BASE, ARG_FP },
+ { "mulf", FP(0x15,0x082), BASE, ARG_FP },
+ { "divf", FP(0x15,0x083), BASE, ARG_FP },
+ { "cvtdg", FP(0x15,0x09E), BASE, ARG_FPZ1 },
+ { "addg", FP(0x15,0x0A0), BASE, ARG_FP },
+ { "negg", FP(0x15,0x0A1), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subg", FP(0x15,0x0A1), BASE, ARG_FP },
+ { "mulg", FP(0x15,0x0A2), BASE, ARG_FP },
+ { "divg", FP(0x15,0x0A3), BASE, ARG_FP },
+ { "cmpgeq", FP(0x15,0x0A5), BASE, ARG_FP },
+ { "cmpglt", FP(0x15,0x0A6), BASE, ARG_FP },
+ { "cmpgle", FP(0x15,0x0A7), BASE, ARG_FP },
+ { "cvtgf", FP(0x15,0x0AC), BASE, ARG_FPZ1 },
+ { "cvtgd", FP(0x15,0x0AD), BASE, ARG_FPZ1 },
+ { "cvtgq", FP(0x15,0x0AF), BASE, ARG_FPZ1 },
+ { "cvtqf", FP(0x15,0x0BC), BASE, ARG_FPZ1 },
+ { "cvtqg", FP(0x15,0x0BE), BASE, ARG_FPZ1 },
+ { "addf/uc", FP(0x15,0x100), BASE, ARG_FP },
+ { "subf/uc", FP(0x15,0x101), BASE, ARG_FP },
+ { "mulf/uc", FP(0x15,0x102), BASE, ARG_FP },
+ { "divf/uc", FP(0x15,0x103), BASE, ARG_FP },
+ { "cvtdg/uc", FP(0x15,0x11E), BASE, ARG_FPZ1 },
+ { "addg/uc", FP(0x15,0x120), BASE, ARG_FP },
+ { "subg/uc", FP(0x15,0x121), BASE, ARG_FP },
+ { "mulg/uc", FP(0x15,0x122), BASE, ARG_FP },
+ { "divg/uc", FP(0x15,0x123), BASE, ARG_FP },
+ { "cvtgf/uc", FP(0x15,0x12C), BASE, ARG_FPZ1 },
+ { "cvtgd/uc", FP(0x15,0x12D), BASE, ARG_FPZ1 },
+ { "cvtgq/vc", FP(0x15,0x12F), BASE, ARG_FPZ1 },
+ { "addf/u", FP(0x15,0x180), BASE, ARG_FP },
+ { "subf/u", FP(0x15,0x181), BASE, ARG_FP },
+ { "mulf/u", FP(0x15,0x182), BASE, ARG_FP },
+ { "divf/u", FP(0x15,0x183), BASE, ARG_FP },
+ { "cvtdg/u", FP(0x15,0x19E), BASE, ARG_FPZ1 },
+ { "addg/u", FP(0x15,0x1A0), BASE, ARG_FP },
+ { "subg/u", FP(0x15,0x1A1), BASE, ARG_FP },
+ { "mulg/u", FP(0x15,0x1A2), BASE, ARG_FP },
+ { "divg/u", FP(0x15,0x1A3), BASE, ARG_FP },
+ { "cvtgf/u", FP(0x15,0x1AC), BASE, ARG_FPZ1 },
+ { "cvtgd/u", FP(0x15,0x1AD), BASE, ARG_FPZ1 },
+ { "cvtgq/v", FP(0x15,0x1AF), BASE, ARG_FPZ1 },
+ { "addf/sc", FP(0x15,0x400), BASE, ARG_FP },
+ { "subf/sc", FP(0x15,0x401), BASE, ARG_FP },
+ { "mulf/sc", FP(0x15,0x402), BASE, ARG_FP },
+ { "divf/sc", FP(0x15,0x403), BASE, ARG_FP },
+ { "cvtdg/sc", FP(0x15,0x41E), BASE, ARG_FPZ1 },
+ { "addg/sc", FP(0x15,0x420), BASE, ARG_FP },
+ { "subg/sc", FP(0x15,0x421), BASE, ARG_FP },
+ { "mulg/sc", FP(0x15,0x422), BASE, ARG_FP },
+ { "divg/sc", FP(0x15,0x423), BASE, ARG_FP },
+ { "cvtgf/sc", FP(0x15,0x42C), BASE, ARG_FPZ1 },
+ { "cvtgd/sc", FP(0x15,0x42D), BASE, ARG_FPZ1 },
+ { "cvtgq/sc", FP(0x15,0x42F), BASE, ARG_FPZ1 },
+ { "addf/s", FP(0x15,0x480), BASE, ARG_FP },
+ { "negf/s", FP(0x15,0x481), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subf/s", FP(0x15,0x481), BASE, ARG_FP },
+ { "mulf/s", FP(0x15,0x482), BASE, ARG_FP },
+ { "divf/s", FP(0x15,0x483), BASE, ARG_FP },
+ { "cvtdg/s", FP(0x15,0x49E), BASE, ARG_FPZ1 },
+ { "addg/s", FP(0x15,0x4A0), BASE, ARG_FP },
+ { "negg/s", FP(0x15,0x4A1), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subg/s", FP(0x15,0x4A1), BASE, ARG_FP },
+ { "mulg/s", FP(0x15,0x4A2), BASE, ARG_FP },
+ { "divg/s", FP(0x15,0x4A3), BASE, ARG_FP },
+ { "cmpgeq/s", FP(0x15,0x4A5), BASE, ARG_FP },
+ { "cmpglt/s", FP(0x15,0x4A6), BASE, ARG_FP },
+ { "cmpgle/s", FP(0x15,0x4A7), BASE, ARG_FP },
+ { "cvtgf/s", FP(0x15,0x4AC), BASE, ARG_FPZ1 },
+ { "cvtgd/s", FP(0x15,0x4AD), BASE, ARG_FPZ1 },
+ { "cvtgq/s", FP(0x15,0x4AF), BASE, ARG_FPZ1 },
+ { "addf/suc", FP(0x15,0x500), BASE, ARG_FP },
+ { "subf/suc", FP(0x15,0x501), BASE, ARG_FP },
+ { "mulf/suc", FP(0x15,0x502), BASE, ARG_FP },
+ { "divf/suc", FP(0x15,0x503), BASE, ARG_FP },
+ { "cvtdg/suc", FP(0x15,0x51E), BASE, ARG_FPZ1 },
+ { "addg/suc", FP(0x15,0x520), BASE, ARG_FP },
+ { "subg/suc", FP(0x15,0x521), BASE, ARG_FP },
+ { "mulg/suc", FP(0x15,0x522), BASE, ARG_FP },
+ { "divg/suc", FP(0x15,0x523), BASE, ARG_FP },
+ { "cvtgf/suc", FP(0x15,0x52C), BASE, ARG_FPZ1 },
+ { "cvtgd/suc", FP(0x15,0x52D), BASE, ARG_FPZ1 },
+ { "cvtgq/svc", FP(0x15,0x52F), BASE, ARG_FPZ1 },
+ { "addf/su", FP(0x15,0x580), BASE, ARG_FP },
+ { "subf/su", FP(0x15,0x581), BASE, ARG_FP },
+ { "mulf/su", FP(0x15,0x582), BASE, ARG_FP },
+ { "divf/su", FP(0x15,0x583), BASE, ARG_FP },
+ { "cvtdg/su", FP(0x15,0x59E), BASE, ARG_FPZ1 },
+ { "addg/su", FP(0x15,0x5A0), BASE, ARG_FP },
+ { "subg/su", FP(0x15,0x5A1), BASE, ARG_FP },
+ { "mulg/su", FP(0x15,0x5A2), BASE, ARG_FP },
+ { "divg/su", FP(0x15,0x5A3), BASE, ARG_FP },
+ { "cvtgf/su", FP(0x15,0x5AC), BASE, ARG_FPZ1 },
+ { "cvtgd/su", FP(0x15,0x5AD), BASE, ARG_FPZ1 },
+ { "cvtgq/sv", FP(0x15,0x5AF), BASE, ARG_FPZ1 },
+
+ { "adds/c", FP(0x16,0x000), BASE, ARG_FP },
+ { "subs/c", FP(0x16,0x001), BASE, ARG_FP },
+ { "muls/c", FP(0x16,0x002), BASE, ARG_FP },
+ { "divs/c", FP(0x16,0x003), BASE, ARG_FP },
+ { "addt/c", FP(0x16,0x020), BASE, ARG_FP },
+ { "subt/c", FP(0x16,0x021), BASE, ARG_FP },
+ { "mult/c", FP(0x16,0x022), BASE, ARG_FP },
+ { "divt/c", FP(0x16,0x023), BASE, ARG_FP },
+ { "cvtts/c", FP(0x16,0x02C), BASE, ARG_FPZ1 },
+ { "cvttq/c", FP(0x16,0x02F), BASE, ARG_FPZ1 },
+ { "cvtqs/c", FP(0x16,0x03C), BASE, ARG_FPZ1 },
+ { "cvtqt/c", FP(0x16,0x03E), BASE, ARG_FPZ1 },
+ { "adds/m", FP(0x16,0x040), BASE, ARG_FP },
+ { "subs/m", FP(0x16,0x041), BASE, ARG_FP },
+ { "muls/m", FP(0x16,0x042), BASE, ARG_FP },
+ { "divs/m", FP(0x16,0x043), BASE, ARG_FP },
+ { "addt/m", FP(0x16,0x060), BASE, ARG_FP },
+ { "subt/m", FP(0x16,0x061), BASE, ARG_FP },
+ { "mult/m", FP(0x16,0x062), BASE, ARG_FP },
+ { "divt/m", FP(0x16,0x063), BASE, ARG_FP },
+ { "cvtts/m", FP(0x16,0x06C), BASE, ARG_FPZ1 },
+ { "cvttq/m", FP(0x16,0x06F), BASE, ARG_FPZ1 },
+ { "cvtqs/m", FP(0x16,0x07C), BASE, ARG_FPZ1 },
+ { "cvtqt/m", FP(0x16,0x07E), BASE, ARG_FPZ1 },
+ { "adds", FP(0x16,0x080), BASE, ARG_FP },
+ { "negs", FP(0x16,0x081), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subs", FP(0x16,0x081), BASE, ARG_FP },
+ { "muls", FP(0x16,0x082), BASE, ARG_FP },
+ { "divs", FP(0x16,0x083), BASE, ARG_FP },
+ { "addt", FP(0x16,0x0A0), BASE, ARG_FP },
+ { "negt", FP(0x16,0x0A1), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subt", FP(0x16,0x0A1), BASE, ARG_FP },
+ { "mult", FP(0x16,0x0A2), BASE, ARG_FP },
+ { "divt", FP(0x16,0x0A3), BASE, ARG_FP },
+ { "cmptun", FP(0x16,0x0A4), BASE, ARG_FP },
+ { "cmpteq", FP(0x16,0x0A5), BASE, ARG_FP },
+ { "cmptlt", FP(0x16,0x0A6), BASE, ARG_FP },
+ { "cmptle", FP(0x16,0x0A7), BASE, ARG_FP },
+ { "cvtts", FP(0x16,0x0AC), BASE, ARG_FPZ1 },
+ { "cvttq", FP(0x16,0x0AF), BASE, ARG_FPZ1 },
+ { "cvtqs", FP(0x16,0x0BC), BASE, ARG_FPZ1 },
+ { "cvtqt", FP(0x16,0x0BE), BASE, ARG_FPZ1 },
+ { "adds/d", FP(0x16,0x0C0), BASE, ARG_FP },
+ { "subs/d", FP(0x16,0x0C1), BASE, ARG_FP },
+ { "muls/d", FP(0x16,0x0C2), BASE, ARG_FP },
+ { "divs/d", FP(0x16,0x0C3), BASE, ARG_FP },
+ { "addt/d", FP(0x16,0x0E0), BASE, ARG_FP },
+ { "subt/d", FP(0x16,0x0E1), BASE, ARG_FP },
+ { "mult/d", FP(0x16,0x0E2), BASE, ARG_FP },
+ { "divt/d", FP(0x16,0x0E3), BASE, ARG_FP },
+ { "cvtts/d", FP(0x16,0x0EC), BASE, ARG_FPZ1 },
+ { "cvttq/d", FP(0x16,0x0EF), BASE, ARG_FPZ1 },
+ { "cvtqs/d", FP(0x16,0x0FC), BASE, ARG_FPZ1 },
+ { "cvtqt/d", FP(0x16,0x0FE), BASE, ARG_FPZ1 },
+ { "adds/uc", FP(0x16,0x100), BASE, ARG_FP },
+ { "subs/uc", FP(0x16,0x101), BASE, ARG_FP },
+ { "muls/uc", FP(0x16,0x102), BASE, ARG_FP },
+ { "divs/uc", FP(0x16,0x103), BASE, ARG_FP },
+ { "addt/uc", FP(0x16,0x120), BASE, ARG_FP },
+ { "subt/uc", FP(0x16,0x121), BASE, ARG_FP },
+ { "mult/uc", FP(0x16,0x122), BASE, ARG_FP },
+ { "divt/uc", FP(0x16,0x123), BASE, ARG_FP },
+ { "cvtts/uc", FP(0x16,0x12C), BASE, ARG_FPZ1 },
+ { "cvttq/vc", FP(0x16,0x12F), BASE, ARG_FPZ1 },
+ { "adds/um", FP(0x16,0x140), BASE, ARG_FP },
+ { "subs/um", FP(0x16,0x141), BASE, ARG_FP },
+ { "muls/um", FP(0x16,0x142), BASE, ARG_FP },
+ { "divs/um", FP(0x16,0x143), BASE, ARG_FP },
+ { "addt/um", FP(0x16,0x160), BASE, ARG_FP },
+ { "subt/um", FP(0x16,0x161), BASE, ARG_FP },
+ { "mult/um", FP(0x16,0x162), BASE, ARG_FP },
+ { "divt/um", FP(0x16,0x163), BASE, ARG_FP },
+ { "cvtts/um", FP(0x16,0x16C), BASE, ARG_FPZ1 },
+ { "cvttq/vm", FP(0x16,0x16F), BASE, ARG_FPZ1 },
+ { "adds/u", FP(0x16,0x180), BASE, ARG_FP },
+ { "subs/u", FP(0x16,0x181), BASE, ARG_FP },
+ { "muls/u", FP(0x16,0x182), BASE, ARG_FP },
+ { "divs/u", FP(0x16,0x183), BASE, ARG_FP },
+ { "addt/u", FP(0x16,0x1A0), BASE, ARG_FP },
+ { "subt/u", FP(0x16,0x1A1), BASE, ARG_FP },
+ { "mult/u", FP(0x16,0x1A2), BASE, ARG_FP },
+ { "divt/u", FP(0x16,0x1A3), BASE, ARG_FP },
+ { "cvtts/u", FP(0x16,0x1AC), BASE, ARG_FPZ1 },
+ { "cvttq/v", FP(0x16,0x1AF), BASE, ARG_FPZ1 },
+ { "adds/ud", FP(0x16,0x1C0), BASE, ARG_FP },
+ { "subs/ud", FP(0x16,0x1C1), BASE, ARG_FP },
+ { "muls/ud", FP(0x16,0x1C2), BASE, ARG_FP },
+ { "divs/ud", FP(0x16,0x1C3), BASE, ARG_FP },
+ { "addt/ud", FP(0x16,0x1E0), BASE, ARG_FP },
+ { "subt/ud", FP(0x16,0x1E1), BASE, ARG_FP },
+ { "mult/ud", FP(0x16,0x1E2), BASE, ARG_FP },
+ { "divt/ud", FP(0x16,0x1E3), BASE, ARG_FP },
+ { "cvtts/ud", FP(0x16,0x1EC), BASE, ARG_FPZ1 },
+ { "cvttq/vd", FP(0x16,0x1EF), BASE, ARG_FPZ1 },
+ { "cvtst", FP(0x16,0x2AC), BASE, ARG_FPZ1 },
+ { "adds/suc", FP(0x16,0x500), BASE, ARG_FP },
+ { "subs/suc", FP(0x16,0x501), BASE, ARG_FP },
+ { "muls/suc", FP(0x16,0x502), BASE, ARG_FP },
+ { "divs/suc", FP(0x16,0x503), BASE, ARG_FP },
+ { "addt/suc", FP(0x16,0x520), BASE, ARG_FP },
+ { "subt/suc", FP(0x16,0x521), BASE, ARG_FP },
+ { "mult/suc", FP(0x16,0x522), BASE, ARG_FP },
+ { "divt/suc", FP(0x16,0x523), BASE, ARG_FP },
+ { "cvtts/suc", FP(0x16,0x52C), BASE, ARG_FPZ1 },
+ { "cvttq/svc", FP(0x16,0x52F), BASE, ARG_FPZ1 },
+ { "adds/sum", FP(0x16,0x540), BASE, ARG_FP },
+ { "subs/sum", FP(0x16,0x541), BASE, ARG_FP },
+ { "muls/sum", FP(0x16,0x542), BASE, ARG_FP },
+ { "divs/sum", FP(0x16,0x543), BASE, ARG_FP },
+ { "addt/sum", FP(0x16,0x560), BASE, ARG_FP },
+ { "subt/sum", FP(0x16,0x561), BASE, ARG_FP },
+ { "mult/sum", FP(0x16,0x562), BASE, ARG_FP },
+ { "divt/sum", FP(0x16,0x563), BASE, ARG_FP },
+ { "cvtts/sum", FP(0x16,0x56C), BASE, ARG_FPZ1 },
+ { "cvttq/svm", FP(0x16,0x56F), BASE, ARG_FPZ1 },
+ { "adds/su", FP(0x16,0x580), BASE, ARG_FP },
+ { "negs/su", FP(0x16,0x581), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subs/su", FP(0x16,0x581), BASE, ARG_FP },
+ { "muls/su", FP(0x16,0x582), BASE, ARG_FP },
+ { "divs/su", FP(0x16,0x583), BASE, ARG_FP },
+ { "addt/su", FP(0x16,0x5A0), BASE, ARG_FP },
+ { "negt/su", FP(0x16,0x5A1), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subt/su", FP(0x16,0x5A1), BASE, ARG_FP },
+ { "mult/su", FP(0x16,0x5A2), BASE, ARG_FP },
+ { "divt/su", FP(0x16,0x5A3), BASE, ARG_FP },
+ { "cmptun/su", FP(0x16,0x5A4), BASE, ARG_FP },
+ { "cmpteq/su", FP(0x16,0x5A5), BASE, ARG_FP },
+ { "cmptlt/su", FP(0x16,0x5A6), BASE, ARG_FP },
+ { "cmptle/su", FP(0x16,0x5A7), BASE, ARG_FP },
+ { "cvtts/su", FP(0x16,0x5AC), BASE, ARG_FPZ1 },
+ { "cvttq/sv", FP(0x16,0x5AF), BASE, ARG_FPZ1 },
+ { "adds/sud", FP(0x16,0x5C0), BASE, ARG_FP },
+ { "subs/sud", FP(0x16,0x5C1), BASE, ARG_FP },
+ { "muls/sud", FP(0x16,0x5C2), BASE, ARG_FP },
+ { "divs/sud", FP(0x16,0x5C3), BASE, ARG_FP },
+ { "addt/sud", FP(0x16,0x5E0), BASE, ARG_FP },
+ { "subt/sud", FP(0x16,0x5E1), BASE, ARG_FP },
+ { "mult/sud", FP(0x16,0x5E2), BASE, ARG_FP },
+ { "divt/sud", FP(0x16,0x5E3), BASE, ARG_FP },
+ { "cvtts/sud", FP(0x16,0x5EC), BASE, ARG_FPZ1 },
+ { "cvttq/svd", FP(0x16,0x5EF), BASE, ARG_FPZ1 },
+ { "cvtst/s", FP(0x16,0x6AC), BASE, ARG_FPZ1 },
+ { "adds/suic", FP(0x16,0x700), BASE, ARG_FP },
+ { "subs/suic", FP(0x16,0x701), BASE, ARG_FP },
+ { "muls/suic", FP(0x16,0x702), BASE, ARG_FP },
+ { "divs/suic", FP(0x16,0x703), BASE, ARG_FP },
+ { "addt/suic", FP(0x16,0x720), BASE, ARG_FP },
+ { "subt/suic", FP(0x16,0x721), BASE, ARG_FP },
+ { "mult/suic", FP(0x16,0x722), BASE, ARG_FP },
+ { "divt/suic", FP(0x16,0x723), BASE, ARG_FP },
+ { "cvtts/suic", FP(0x16,0x72C), BASE, ARG_FPZ1 },
+ { "cvttq/svic", FP(0x16,0x72F), BASE, ARG_FPZ1 },
+ { "cvtqs/suic", FP(0x16,0x73C), BASE, ARG_FPZ1 },
+ { "cvtqt/suic", FP(0x16,0x73E), BASE, ARG_FPZ1 },
+ { "adds/suim", FP(0x16,0x740), BASE, ARG_FP },
+ { "subs/suim", FP(0x16,0x741), BASE, ARG_FP },
+ { "muls/suim", FP(0x16,0x742), BASE, ARG_FP },
+ { "divs/suim", FP(0x16,0x743), BASE, ARG_FP },
+ { "addt/suim", FP(0x16,0x760), BASE, ARG_FP },
+ { "subt/suim", FP(0x16,0x761), BASE, ARG_FP },
+ { "mult/suim", FP(0x16,0x762), BASE, ARG_FP },
+ { "divt/suim", FP(0x16,0x763), BASE, ARG_FP },
+ { "cvtts/suim", FP(0x16,0x76C), BASE, ARG_FPZ1 },
+ { "cvttq/svim", FP(0x16,0x76F), BASE, ARG_FPZ1 },
+ { "cvtqs/suim", FP(0x16,0x77C), BASE, ARG_FPZ1 },
+ { "cvtqt/suim", FP(0x16,0x77E), BASE, ARG_FPZ1 },
+ { "adds/sui", FP(0x16,0x780), BASE, ARG_FP },
+ { "negs/sui", FP(0x16,0x781), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subs/sui", FP(0x16,0x781), BASE, ARG_FP },
+ { "muls/sui", FP(0x16,0x782), BASE, ARG_FP },
+ { "divs/sui", FP(0x16,0x783), BASE, ARG_FP },
+ { "addt/sui", FP(0x16,0x7A0), BASE, ARG_FP },
+ { "negt/sui", FP(0x16,0x7A1), BASE, ARG_FPZ1 }, /* pseudo */
+ { "subt/sui", FP(0x16,0x7A1), BASE, ARG_FP },
+ { "mult/sui", FP(0x16,0x7A2), BASE, ARG_FP },
+ { "divt/sui", FP(0x16,0x7A3), BASE, ARG_FP },
+ { "cvtts/sui", FP(0x16,0x7AC), BASE, ARG_FPZ1 },
+ { "cvttq/svi", FP(0x16,0x7AF), BASE, ARG_FPZ1 },
+ { "cvtqs/sui", FP(0x16,0x7BC), BASE, ARG_FPZ1 },
+ { "cvtqt/sui", FP(0x16,0x7BE), BASE, ARG_FPZ1 },
+ { "adds/suid", FP(0x16,0x7C0), BASE, ARG_FP },
+ { "subs/suid", FP(0x16,0x7C1), BASE, ARG_FP },
+ { "muls/suid", FP(0x16,0x7C2), BASE, ARG_FP },
+ { "divs/suid", FP(0x16,0x7C3), BASE, ARG_FP },
+ { "addt/suid", FP(0x16,0x7E0), BASE, ARG_FP },
+ { "subt/suid", FP(0x16,0x7E1), BASE, ARG_FP },
+ { "mult/suid", FP(0x16,0x7E2), BASE, ARG_FP },
+ { "divt/suid", FP(0x16,0x7E3), BASE, ARG_FP },
+ { "cvtts/suid", FP(0x16,0x7EC), BASE, ARG_FPZ1 },
+ { "cvttq/svid", FP(0x16,0x7EF), BASE, ARG_FPZ1 },
+ { "cvtqs/suid", FP(0x16,0x7FC), BASE, ARG_FPZ1 },
+ { "cvtqt/suid", FP(0x16,0x7FE), BASE, ARG_FPZ1 },
+
+ { "cvtlq", FP(0x17,0x010), BASE, ARG_FPZ1 },
+ { "fnop", FP(0x17,0x020), BASE, { ZA, ZB, ZC } }, /* pseudo */
+ { "fclr", FP(0x17,0x020), BASE, { ZA, ZB, FC } }, /* pseudo */
+ { "fabs", FP(0x17,0x020), BASE, ARG_FPZ1 }, /* pseudo */
+ { "fmov", FP(0x17,0x020), BASE, { FA, RBA, FC } }, /* pseudo */
+ { "cpys", FP(0x17,0x020), BASE, ARG_FP },
+ { "fneg", FP(0x17,0x021), BASE, { FA, RBA, FC } }, /* pseudo */
+ { "cpysn", FP(0x17,0x021), BASE, ARG_FP },
+ { "cpyse", FP(0x17,0x022), BASE, ARG_FP },
+ { "mt_fpcr", FP(0x17,0x024), BASE, { FA, RBA, RCA } },
+ { "mf_fpcr", FP(0x17,0x025), BASE, { FA, RBA, RCA } },
+ { "fcmoveq", FP(0x17,0x02A), BASE, ARG_FP },
+ { "fcmovne", FP(0x17,0x02B), BASE, ARG_FP },
+ { "fcmovlt", FP(0x17,0x02C), BASE, ARG_FP },
+ { "fcmovge", FP(0x17,0x02D), BASE, ARG_FP },
+ { "fcmovle", FP(0x17,0x02E), BASE, ARG_FP },
+ { "fcmovgt", FP(0x17,0x02F), BASE, ARG_FP },
+ { "cvtql", FP(0x17,0x030), BASE, ARG_FPZ1 },
+ { "cvtql/v", FP(0x17,0x130), BASE, ARG_FPZ1 },
+ { "cvtql/sv", FP(0x17,0x530), BASE, ARG_FPZ1 },
+
+ { "trapb", MFC(0x18,0x0000), BASE, ARG_NONE },
+ { "draint", MFC(0x18,0x0000), BASE, ARG_NONE }, /* alias */
+ { "excb", MFC(0x18,0x0400), BASE, ARG_NONE },
+ { "mb", MFC(0x18,0x4000), BASE, ARG_NONE },
+ { "wmb", MFC(0x18,0x4400), BASE, ARG_NONE },
+ { "fetch", MFC(0x18,0x8000), BASE, { PRB } },
+ { "fetch_m", MFC(0x18,0xA000), BASE, { PRB } },
+ { "rpcc", MFC(0x18,0xC000), BASE, { RA } },
+ { "rc", MFC(0x18,0xE000), BASE, { RA } },
+ { "ecb", MFC(0x18,0xE800), BASE, { PRB } }, /* ev56 una */
+ { "rs", MFC(0x18,0xF000), BASE, { RA } },
+ { "wh64", MFC(0x18,0xF800), BASE, { PRB } }, /* ev56 una */
+
+ { "hw_mfpr", OPR(0x19,0x00), EV4, { RA, RBA, EV4EXTHWINDEX } },
+ { "hw_mfpr", OP(0x19), OP_MASK, EV5, { RA, RBA, EV5HWINDEX } },
+ { "hw_mfpr", OP(0x19), OP_MASK, EV6, { RA, ZB, EV6HWINDEX } },
+ { "hw_mfpr/i", OPR(0x19,0x01), EV4, ARG_EV4HWMPR },
+ { "hw_mfpr/a", OPR(0x19,0x02), EV4, ARG_EV4HWMPR },
+ { "hw_mfpr/ai", OPR(0x19,0x03), EV4, ARG_EV4HWMPR },
+ { "hw_mfpr/p", OPR(0x19,0x04), EV4, ARG_EV4HWMPR },
+ { "hw_mfpr/pi", OPR(0x19,0x05), EV4, ARG_EV4HWMPR },
+ { "hw_mfpr/pa", OPR(0x19,0x06), EV4, ARG_EV4HWMPR },
+ { "hw_mfpr/pai", OPR(0x19,0x07), EV4, ARG_EV4HWMPR },
+ { "pal19", PCD(0x19), BASE, ARG_PCD },
+
+ { "jmp", MBR(0x1A,0), BASE, { RA, CPRB, JMPHINT } },
+ { "jsr", MBR(0x1A,1), BASE, { RA, CPRB, JMPHINT } },
+ { "ret", MBR(0x1A,2), BASE, { RA, CPRB, RETHINT } },
+ { "jcr", MBR(0x1A,3), BASE, { RA, CPRB, RETHINT } }, /* alias */
+ { "jsr_coroutine", MBR(0x1A,3), BASE, { RA, CPRB, RETHINT } },
+
+ { "hw_ldl", EV4HWMEM(0x1B,0x0), EV4, ARG_EV4HWMEM },
+ { "hw_ldl", EV5HWMEM(0x1B,0x00), EV5, ARG_EV5HWMEM },
+ { "hw_ldl", EV6HWMEM(0x1B,0x8), EV6, ARG_EV6HWMEM },
+ { "hw_ldl/a", EV4HWMEM(0x1B,0x4), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/a", EV5HWMEM(0x1B,0x10), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/a", EV6HWMEM(0x1B,0xC), EV6, ARG_EV6HWMEM },
+ { "hw_ldl/al", EV5HWMEM(0x1B,0x11), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/ar", EV4HWMEM(0x1B,0x6), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/av", EV5HWMEM(0x1B,0x12), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/avl", EV5HWMEM(0x1B,0x13), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/aw", EV5HWMEM(0x1B,0x18), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/awl", EV5HWMEM(0x1B,0x19), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/awv", EV5HWMEM(0x1B,0x1a), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/awvl", EV5HWMEM(0x1B,0x1b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/l", EV5HWMEM(0x1B,0x01), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/p", EV4HWMEM(0x1B,0x8), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/p", EV5HWMEM(0x1B,0x20), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/p", EV6HWMEM(0x1B,0x0), EV6, ARG_EV6HWMEM },
+ { "hw_ldl/pa", EV4HWMEM(0x1B,0xC), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/pa", EV5HWMEM(0x1B,0x30), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pal", EV5HWMEM(0x1B,0x31), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/par", EV4HWMEM(0x1B,0xE), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/pav", EV5HWMEM(0x1B,0x32), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pavl", EV5HWMEM(0x1B,0x33), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/paw", EV5HWMEM(0x1B,0x38), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pawl", EV5HWMEM(0x1B,0x39), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pawv", EV5HWMEM(0x1B,0x3a), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pawvl", EV5HWMEM(0x1B,0x3b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pl", EV5HWMEM(0x1B,0x21), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pr", EV4HWMEM(0x1B,0xA), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/pv", EV5HWMEM(0x1B,0x22), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pvl", EV5HWMEM(0x1B,0x23), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pw", EV5HWMEM(0x1B,0x28), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pwl", EV5HWMEM(0x1B,0x29), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pwv", EV5HWMEM(0x1B,0x2a), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/pwvl", EV5HWMEM(0x1B,0x2b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/r", EV4HWMEM(0x1B,0x2), EV4, ARG_EV4HWMEM },
+ { "hw_ldl/v", EV5HWMEM(0x1B,0x02), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/v", EV6HWMEM(0x1B,0x4), EV6, ARG_EV6HWMEM },
+ { "hw_ldl/vl", EV5HWMEM(0x1B,0x03), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/w", EV5HWMEM(0x1B,0x08), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/w", EV6HWMEM(0x1B,0xA), EV6, ARG_EV6HWMEM },
+ { "hw_ldl/wa", EV6HWMEM(0x1B,0xE), EV6, ARG_EV6HWMEM },
+ { "hw_ldl/wl", EV5HWMEM(0x1B,0x09), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/wv", EV5HWMEM(0x1B,0x0a), EV5, ARG_EV5HWMEM },
+ { "hw_ldl/wvl", EV5HWMEM(0x1B,0x0b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l", EV5HWMEM(0x1B,0x01), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/a", EV5HWMEM(0x1B,0x11), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/av", EV5HWMEM(0x1B,0x13), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/aw", EV5HWMEM(0x1B,0x19), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/awv", EV5HWMEM(0x1B,0x1b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/p", EV5HWMEM(0x1B,0x21), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/p", EV6HWMEM(0x1B,0x2), EV6, ARG_EV6HWMEM },
+ { "hw_ldl_l/pa", EV5HWMEM(0x1B,0x31), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/pav", EV5HWMEM(0x1B,0x33), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/paw", EV5HWMEM(0x1B,0x39), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/pawv", EV5HWMEM(0x1B,0x3b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/pv", EV5HWMEM(0x1B,0x23), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/pw", EV5HWMEM(0x1B,0x29), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/pwv", EV5HWMEM(0x1B,0x2b), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/v", EV5HWMEM(0x1B,0x03), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/w", EV5HWMEM(0x1B,0x09), EV5, ARG_EV5HWMEM },
+ { "hw_ldl_l/wv", EV5HWMEM(0x1B,0x0b), EV5, ARG_EV5HWMEM },
+ { "hw_ldq", EV4HWMEM(0x1B,0x1), EV4, ARG_EV4HWMEM },
+ { "hw_ldq", EV5HWMEM(0x1B,0x04), EV5, ARG_EV5HWMEM },
+ { "hw_ldq", EV6HWMEM(0x1B,0x9), EV6, ARG_EV6HWMEM },
+ { "hw_ldq/a", EV4HWMEM(0x1B,0x5), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/a", EV5HWMEM(0x1B,0x14), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/a", EV6HWMEM(0x1B,0xD), EV6, ARG_EV6HWMEM },
+ { "hw_ldq/al", EV5HWMEM(0x1B,0x15), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/ar", EV4HWMEM(0x1B,0x7), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/av", EV5HWMEM(0x1B,0x16), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/avl", EV5HWMEM(0x1B,0x17), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/aw", EV5HWMEM(0x1B,0x1c), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/awl", EV5HWMEM(0x1B,0x1d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/awv", EV5HWMEM(0x1B,0x1e), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/awvl", EV5HWMEM(0x1B,0x1f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/l", EV5HWMEM(0x1B,0x05), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/p", EV4HWMEM(0x1B,0x9), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/p", EV5HWMEM(0x1B,0x24), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/p", EV6HWMEM(0x1B,0x1), EV6, ARG_EV6HWMEM },
+ { "hw_ldq/pa", EV4HWMEM(0x1B,0xD), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/pa", EV5HWMEM(0x1B,0x34), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pal", EV5HWMEM(0x1B,0x35), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/par", EV4HWMEM(0x1B,0xF), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/pav", EV5HWMEM(0x1B,0x36), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pavl", EV5HWMEM(0x1B,0x37), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/paw", EV5HWMEM(0x1B,0x3c), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pawl", EV5HWMEM(0x1B,0x3d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pawv", EV5HWMEM(0x1B,0x3e), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pawvl", EV5HWMEM(0x1B,0x3f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pl", EV5HWMEM(0x1B,0x25), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pr", EV4HWMEM(0x1B,0xB), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/pv", EV5HWMEM(0x1B,0x26), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pvl", EV5HWMEM(0x1B,0x27), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pw", EV5HWMEM(0x1B,0x2c), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pwl", EV5HWMEM(0x1B,0x2d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pwv", EV5HWMEM(0x1B,0x2e), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/pwvl", EV5HWMEM(0x1B,0x2f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/r", EV4HWMEM(0x1B,0x3), EV4, ARG_EV4HWMEM },
+ { "hw_ldq/v", EV5HWMEM(0x1B,0x06), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/v", EV6HWMEM(0x1B,0x5), EV6, ARG_EV6HWMEM },
+ { "hw_ldq/vl", EV5HWMEM(0x1B,0x07), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/w", EV5HWMEM(0x1B,0x0c), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/w", EV6HWMEM(0x1B,0xB), EV6, ARG_EV6HWMEM },
+ { "hw_ldq/wa", EV6HWMEM(0x1B,0xF), EV6, ARG_EV6HWMEM },
+ { "hw_ldq/wl", EV5HWMEM(0x1B,0x0d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/wv", EV5HWMEM(0x1B,0x0e), EV5, ARG_EV5HWMEM },
+ { "hw_ldq/wvl", EV5HWMEM(0x1B,0x0f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l", EV5HWMEM(0x1B,0x05), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/a", EV5HWMEM(0x1B,0x15), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/av", EV5HWMEM(0x1B,0x17), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/aw", EV5HWMEM(0x1B,0x1d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/awv", EV5HWMEM(0x1B,0x1f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/p", EV5HWMEM(0x1B,0x25), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/p", EV6HWMEM(0x1B,0x3), EV6, ARG_EV6HWMEM },
+ { "hw_ldq_l/pa", EV5HWMEM(0x1B,0x35), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/pav", EV5HWMEM(0x1B,0x37), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/paw", EV5HWMEM(0x1B,0x3d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/pawv", EV5HWMEM(0x1B,0x3f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/pv", EV5HWMEM(0x1B,0x27), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/pw", EV5HWMEM(0x1B,0x2d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/pwv", EV5HWMEM(0x1B,0x2f), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/v", EV5HWMEM(0x1B,0x07), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/w", EV5HWMEM(0x1B,0x0d), EV5, ARG_EV5HWMEM },
+ { "hw_ldq_l/wv", EV5HWMEM(0x1B,0x0f), EV5, ARG_EV5HWMEM },
+ { "hw_ld", EV4HWMEM(0x1B,0x0), EV4, ARG_EV4HWMEM },
+ { "hw_ld", EV5HWMEM(0x1B,0x00), EV5, ARG_EV5HWMEM },
+ { "hw_ld/a", EV4HWMEM(0x1B,0x4), EV4, ARG_EV4HWMEM },
+ { "hw_ld/a", EV5HWMEM(0x1B,0x10), EV5, ARG_EV5HWMEM },
+ { "hw_ld/al", EV5HWMEM(0x1B,0x11), EV5, ARG_EV5HWMEM },
+ { "hw_ld/aq", EV4HWMEM(0x1B,0x5), EV4, ARG_EV4HWMEM },
+ { "hw_ld/aq", EV5HWMEM(0x1B,0x14), EV5, ARG_EV5HWMEM },
+ { "hw_ld/aql", EV5HWMEM(0x1B,0x15), EV5, ARG_EV5HWMEM },
+ { "hw_ld/aqv", EV5HWMEM(0x1B,0x16), EV5, ARG_EV5HWMEM },
+ { "hw_ld/aqvl", EV5HWMEM(0x1B,0x17), EV5, ARG_EV5HWMEM },
+ { "hw_ld/ar", EV4HWMEM(0x1B,0x6), EV4, ARG_EV4HWMEM },
+ { "hw_ld/arq", EV4HWMEM(0x1B,0x7), EV4, ARG_EV4HWMEM },
+ { "hw_ld/av", EV5HWMEM(0x1B,0x12), EV5, ARG_EV5HWMEM },
+ { "hw_ld/avl", EV5HWMEM(0x1B,0x13), EV5, ARG_EV5HWMEM },
+ { "hw_ld/aw", EV5HWMEM(0x1B,0x18), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awl", EV5HWMEM(0x1B,0x19), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awq", EV5HWMEM(0x1B,0x1c), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awql", EV5HWMEM(0x1B,0x1d), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awqv", EV5HWMEM(0x1B,0x1e), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awqvl", EV5HWMEM(0x1B,0x1f), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awv", EV5HWMEM(0x1B,0x1a), EV5, ARG_EV5HWMEM },
+ { "hw_ld/awvl", EV5HWMEM(0x1B,0x1b), EV5, ARG_EV5HWMEM },
+ { "hw_ld/l", EV5HWMEM(0x1B,0x01), EV5, ARG_EV5HWMEM },
+ { "hw_ld/p", EV4HWMEM(0x1B,0x8), EV4, ARG_EV4HWMEM },
+ { "hw_ld/p", EV5HWMEM(0x1B,0x20), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pa", EV4HWMEM(0x1B,0xC), EV4, ARG_EV4HWMEM },
+ { "hw_ld/pa", EV5HWMEM(0x1B,0x30), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pal", EV5HWMEM(0x1B,0x31), EV5, ARG_EV5HWMEM },
+ { "hw_ld/paq", EV4HWMEM(0x1B,0xD), EV4, ARG_EV4HWMEM },
+ { "hw_ld/paq", EV5HWMEM(0x1B,0x34), EV5, ARG_EV5HWMEM },
+ { "hw_ld/paql", EV5HWMEM(0x1B,0x35), EV5, ARG_EV5HWMEM },
+ { "hw_ld/paqv", EV5HWMEM(0x1B,0x36), EV5, ARG_EV5HWMEM },
+ { "hw_ld/paqvl", EV5HWMEM(0x1B,0x37), EV5, ARG_EV5HWMEM },
+ { "hw_ld/par", EV4HWMEM(0x1B,0xE), EV4, ARG_EV4HWMEM },
+ { "hw_ld/parq", EV4HWMEM(0x1B,0xF), EV4, ARG_EV4HWMEM },
+ { "hw_ld/pav", EV5HWMEM(0x1B,0x32), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pavl", EV5HWMEM(0x1B,0x33), EV5, ARG_EV5HWMEM },
+ { "hw_ld/paw", EV5HWMEM(0x1B,0x38), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawl", EV5HWMEM(0x1B,0x39), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawq", EV5HWMEM(0x1B,0x3c), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawql", EV5HWMEM(0x1B,0x3d), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawqv", EV5HWMEM(0x1B,0x3e), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawqvl", EV5HWMEM(0x1B,0x3f), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawv", EV5HWMEM(0x1B,0x3a), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pawvl", EV5HWMEM(0x1B,0x3b), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pl", EV5HWMEM(0x1B,0x21), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pq", EV4HWMEM(0x1B,0x9), EV4, ARG_EV4HWMEM },
+ { "hw_ld/pq", EV5HWMEM(0x1B,0x24), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pql", EV5HWMEM(0x1B,0x25), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pqv", EV5HWMEM(0x1B,0x26), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pqvl", EV5HWMEM(0x1B,0x27), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pr", EV4HWMEM(0x1B,0xA), EV4, ARG_EV4HWMEM },
+ { "hw_ld/prq", EV4HWMEM(0x1B,0xB), EV4, ARG_EV4HWMEM },
+ { "hw_ld/pv", EV5HWMEM(0x1B,0x22), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pvl", EV5HWMEM(0x1B,0x23), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pw", EV5HWMEM(0x1B,0x28), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwl", EV5HWMEM(0x1B,0x29), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwq", EV5HWMEM(0x1B,0x2c), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwql", EV5HWMEM(0x1B,0x2d), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwqv", EV5HWMEM(0x1B,0x2e), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwqvl", EV5HWMEM(0x1B,0x2f), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwv", EV5HWMEM(0x1B,0x2a), EV5, ARG_EV5HWMEM },
+ { "hw_ld/pwvl", EV5HWMEM(0x1B,0x2b), EV5, ARG_EV5HWMEM },
+ { "hw_ld/q", EV4HWMEM(0x1B,0x1), EV4, ARG_EV4HWMEM },
+ { "hw_ld/q", EV5HWMEM(0x1B,0x04), EV5, ARG_EV5HWMEM },
+ { "hw_ld/ql", EV5HWMEM(0x1B,0x05), EV5, ARG_EV5HWMEM },
+ { "hw_ld/qv", EV5HWMEM(0x1B,0x06), EV5, ARG_EV5HWMEM },
+ { "hw_ld/qvl", EV5HWMEM(0x1B,0x07), EV5, ARG_EV5HWMEM },
+ { "hw_ld/r", EV4HWMEM(0x1B,0x2), EV4, ARG_EV4HWMEM },
+ { "hw_ld/rq", EV4HWMEM(0x1B,0x3), EV4, ARG_EV4HWMEM },
+ { "hw_ld/v", EV5HWMEM(0x1B,0x02), EV5, ARG_EV5HWMEM },
+ { "hw_ld/vl", EV5HWMEM(0x1B,0x03), EV5, ARG_EV5HWMEM },
+ { "hw_ld/w", EV5HWMEM(0x1B,0x08), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wl", EV5HWMEM(0x1B,0x09), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wq", EV5HWMEM(0x1B,0x0c), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wql", EV5HWMEM(0x1B,0x0d), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wqv", EV5HWMEM(0x1B,0x0e), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wqvl", EV5HWMEM(0x1B,0x0f), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wv", EV5HWMEM(0x1B,0x0a), EV5, ARG_EV5HWMEM },
+ { "hw_ld/wvl", EV5HWMEM(0x1B,0x0b), EV5, ARG_EV5HWMEM },
+ { "pal1b", PCD(0x1B), BASE, ARG_PCD },
+
+ { "sextb", OPR(0x1C, 0x00), BWX, ARG_OPRZ1 },
+ { "sextw", OPR(0x1C, 0x01), BWX, ARG_OPRZ1 },
+ { "ctpop", OPR(0x1C, 0x30), CIX, ARG_OPRZ1 },
+ { "perr", OPR(0x1C, 0x31), MAX, ARG_OPR },
+ { "ctlz", OPR(0x1C, 0x32), CIX, ARG_OPRZ1 },
+ { "cttz", OPR(0x1C, 0x33), CIX, ARG_OPRZ1 },
+ { "unpkbw", OPR(0x1C, 0x34), MAX, ARG_OPRZ1 },
+ { "unpkbl", OPR(0x1C, 0x35), MAX, ARG_OPRZ1 },
+ { "pkwb", OPR(0x1C, 0x36), MAX, ARG_OPRZ1 },
+ { "pklb", OPR(0x1C, 0x37), MAX, ARG_OPRZ1 },
+ { "minsb8", OPR(0x1C, 0x38), MAX, ARG_OPR },
+ { "minsb8", OPRL(0x1C, 0x38), MAX, ARG_OPRL },
+ { "minsw4", OPR(0x1C, 0x39), MAX, ARG_OPR },
+ { "minsw4", OPRL(0x1C, 0x39), MAX, ARG_OPRL },
+ { "minub8", OPR(0x1C, 0x3A), MAX, ARG_OPR },
+ { "minub8", OPRL(0x1C, 0x3A), MAX, ARG_OPRL },
+ { "minuw4", OPR(0x1C, 0x3B), MAX, ARG_OPR },
+ { "minuw4", OPRL(0x1C, 0x3B), MAX, ARG_OPRL },
+ { "maxub8", OPR(0x1C, 0x3C), MAX, ARG_OPR },
+ { "maxub8", OPRL(0x1C, 0x3C), MAX, ARG_OPRL },
+ { "maxuw4", OPR(0x1C, 0x3D), MAX, ARG_OPR },
+ { "maxuw4", OPRL(0x1C, 0x3D), MAX, ARG_OPRL },
+ { "maxsb8", OPR(0x1C, 0x3E), MAX, ARG_OPR },
+ { "maxsb8", OPRL(0x1C, 0x3E), MAX, ARG_OPRL },
+ { "maxsw4", OPR(0x1C, 0x3F), MAX, ARG_OPR },
+ { "maxsw4", OPRL(0x1C, 0x3F), MAX, ARG_OPRL },
+ { "ftoit", FP(0x1C, 0x70), CIX, { FA, ZB, RC } },
+ { "ftois", FP(0x1C, 0x78), CIX, { FA, ZB, RC } },
+
+ { "hw_mtpr", OPR(0x1D,0x00), EV4, { RA, RBA, EV4EXTHWINDEX } },
+ { "hw_mtpr", OP(0x1D), OP_MASK, EV5, { RA, RBA, EV5HWINDEX } },
+ { "hw_mtpr", OP(0x1D), OP_MASK, EV6, { ZA, RB, EV6HWINDEX } },
+ { "hw_mtpr/i", OPR(0x1D,0x01), EV4, ARG_EV4HWMPR },
+ { "hw_mtpr/a", OPR(0x1D,0x02), EV4, ARG_EV4HWMPR },
+ { "hw_mtpr/ai", OPR(0x1D,0x03), EV4, ARG_EV4HWMPR },
+ { "hw_mtpr/p", OPR(0x1D,0x04), EV4, ARG_EV4HWMPR },
+ { "hw_mtpr/pi", OPR(0x1D,0x05), EV4, ARG_EV4HWMPR },
+ { "hw_mtpr/pa", OPR(0x1D,0x06), EV4, ARG_EV4HWMPR },
+ { "hw_mtpr/pai", OPR(0x1D,0x07), EV4, ARG_EV4HWMPR },
+ { "pal1d", PCD(0x1D), BASE, ARG_PCD },
+
+ { "hw_rei", SPCD(0x1E,0x3FF8000), EV4|EV5, ARG_NONE },
+ { "hw_rei_stall", SPCD(0x1E,0x3FFC000), EV5, ARG_NONE },
+ { "hw_jmp", EV6HWMBR(0x1E,0x0), EV6, { ZA, PRB, EV6HWJMPHINT } },
+ { "hw_jsr", EV6HWMBR(0x1E,0x2), EV6, { ZA, PRB, EV6HWJMPHINT } },
+ { "hw_ret", EV6HWMBR(0x1E,0x4), EV6, { ZA, PRB } },
+ { "hw_jcr", EV6HWMBR(0x1E,0x6), EV6, { ZA, PRB } },
+ { "hw_coroutine", EV6HWMBR(0x1E,0x6), EV6, { ZA, PRB } }, /* alias */
+ { "hw_jmp/stall", EV6HWMBR(0x1E,0x1), EV6, { ZA, PRB, EV6HWJMPHINT } },
+ { "hw_jsr/stall", EV6HWMBR(0x1E,0x3), EV6, { ZA, PRB, EV6HWJMPHINT } },
+ { "hw_ret/stall", EV6HWMBR(0x1E,0x5), EV6, { ZA, PRB } },
+ { "hw_jcr/stall", EV6HWMBR(0x1E,0x7), EV6, { ZA, PRB } },
+ { "hw_coroutine/stall", EV6HWMBR(0x1E,0x7), EV6, { ZA, PRB } }, /* alias */
+ { "pal1e", PCD(0x1E), BASE, ARG_PCD },
+
+ { "hw_stl", EV4HWMEM(0x1F,0x0), EV4, ARG_EV4HWMEM },
+ { "hw_stl", EV5HWMEM(0x1F,0x00), EV5, ARG_EV5HWMEM },
+ { "hw_stl", EV6HWMEM(0x1F,0x4), EV6, ARG_EV6HWMEM }, /* ??? 8 */
+ { "hw_stl/a", EV4HWMEM(0x1F,0x4), EV4, ARG_EV4HWMEM },
+ { "hw_stl/a", EV5HWMEM(0x1F,0x10), EV5, ARG_EV5HWMEM },
+ { "hw_stl/a", EV6HWMEM(0x1F,0xC), EV6, ARG_EV6HWMEM },
+ { "hw_stl/ac", EV5HWMEM(0x1F,0x11), EV5, ARG_EV5HWMEM },
+ { "hw_stl/ar", EV4HWMEM(0x1F,0x6), EV4, ARG_EV4HWMEM },
+ { "hw_stl/av", EV5HWMEM(0x1F,0x12), EV5, ARG_EV5HWMEM },
+ { "hw_stl/avc", EV5HWMEM(0x1F,0x13), EV5, ARG_EV5HWMEM },
+ { "hw_stl/c", EV5HWMEM(0x1F,0x01), EV5, ARG_EV5HWMEM },
+ { "hw_stl/p", EV4HWMEM(0x1F,0x8), EV4, ARG_EV4HWMEM },
+ { "hw_stl/p", EV5HWMEM(0x1F,0x20), EV5, ARG_EV5HWMEM },
+ { "hw_stl/p", EV6HWMEM(0x1F,0x0), EV6, ARG_EV6HWMEM },
+ { "hw_stl/pa", EV4HWMEM(0x1F,0xC), EV4, ARG_EV4HWMEM },
+ { "hw_stl/pa", EV5HWMEM(0x1F,0x30), EV5, ARG_EV5HWMEM },
+ { "hw_stl/pac", EV5HWMEM(0x1F,0x31), EV5, ARG_EV5HWMEM },
+ { "hw_stl/pav", EV5HWMEM(0x1F,0x32), EV5, ARG_EV5HWMEM },
+ { "hw_stl/pavc", EV5HWMEM(0x1F,0x33), EV5, ARG_EV5HWMEM },
+ { "hw_stl/pc", EV5HWMEM(0x1F,0x21), EV5, ARG_EV5HWMEM },
+ { "hw_stl/pr", EV4HWMEM(0x1F,0xA), EV4, ARG_EV4HWMEM },
+ { "hw_stl/pv", EV5HWMEM(0x1F,0x22), EV5, ARG_EV5HWMEM },
+ { "hw_stl/pvc", EV5HWMEM(0x1F,0x23), EV5, ARG_EV5HWMEM },
+ { "hw_stl/r", EV4HWMEM(0x1F,0x2), EV4, ARG_EV4HWMEM },
+ { "hw_stl/v", EV5HWMEM(0x1F,0x02), EV5, ARG_EV5HWMEM },
+ { "hw_stl/vc", EV5HWMEM(0x1F,0x03), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c", EV5HWMEM(0x1F,0x01), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/a", EV5HWMEM(0x1F,0x11), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/av", EV5HWMEM(0x1F,0x13), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/p", EV5HWMEM(0x1F,0x21), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/p", EV6HWMEM(0x1F,0x2), EV6, ARG_EV6HWMEM },
+ { "hw_stl_c/pa", EV5HWMEM(0x1F,0x31), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/pav", EV5HWMEM(0x1F,0x33), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/pv", EV5HWMEM(0x1F,0x23), EV5, ARG_EV5HWMEM },
+ { "hw_stl_c/v", EV5HWMEM(0x1F,0x03), EV5, ARG_EV5HWMEM },
+ { "hw_stq", EV4HWMEM(0x1F,0x1), EV4, ARG_EV4HWMEM },
+ { "hw_stq", EV5HWMEM(0x1F,0x04), EV5, ARG_EV5HWMEM },
+ { "hw_stq", EV6HWMEM(0x1F,0x5), EV6, ARG_EV6HWMEM }, /* ??? 9 */
+ { "hw_stq/a", EV4HWMEM(0x1F,0x5), EV4, ARG_EV4HWMEM },
+ { "hw_stq/a", EV5HWMEM(0x1F,0x14), EV5, ARG_EV5HWMEM },
+ { "hw_stq/a", EV6HWMEM(0x1F,0xD), EV6, ARG_EV6HWMEM },
+ { "hw_stq/ac", EV5HWMEM(0x1F,0x15), EV5, ARG_EV5HWMEM },
+ { "hw_stq/ar", EV4HWMEM(0x1F,0x7), EV4, ARG_EV4HWMEM },
+ { "hw_stq/av", EV5HWMEM(0x1F,0x16), EV5, ARG_EV5HWMEM },
+ { "hw_stq/avc", EV5HWMEM(0x1F,0x17), EV5, ARG_EV5HWMEM },
+ { "hw_stq/c", EV5HWMEM(0x1F,0x05), EV5, ARG_EV5HWMEM },
+ { "hw_stq/p", EV4HWMEM(0x1F,0x9), EV4, ARG_EV4HWMEM },
+ { "hw_stq/p", EV5HWMEM(0x1F,0x24), EV5, ARG_EV5HWMEM },
+ { "hw_stq/p", EV6HWMEM(0x1F,0x1), EV6, ARG_EV6HWMEM },
+ { "hw_stq/pa", EV4HWMEM(0x1F,0xD), EV4, ARG_EV4HWMEM },
+ { "hw_stq/pa", EV5HWMEM(0x1F,0x34), EV5, ARG_EV5HWMEM },
+ { "hw_stq/pac", EV5HWMEM(0x1F,0x35), EV5, ARG_EV5HWMEM },
+ { "hw_stq/par", EV4HWMEM(0x1F,0xE), EV4, ARG_EV4HWMEM },
+ { "hw_stq/par", EV4HWMEM(0x1F,0xF), EV4, ARG_EV4HWMEM },
+ { "hw_stq/pav", EV5HWMEM(0x1F,0x36), EV5, ARG_EV5HWMEM },
+ { "hw_stq/pavc", EV5HWMEM(0x1F,0x37), EV5, ARG_EV5HWMEM },
+ { "hw_stq/pc", EV5HWMEM(0x1F,0x25), EV5, ARG_EV5HWMEM },
+ { "hw_stq/pr", EV4HWMEM(0x1F,0xB), EV4, ARG_EV4HWMEM },
+ { "hw_stq/pv", EV5HWMEM(0x1F,0x26), EV5, ARG_EV5HWMEM },
+ { "hw_stq/pvc", EV5HWMEM(0x1F,0x27), EV5, ARG_EV5HWMEM },
+ { "hw_stq/r", EV4HWMEM(0x1F,0x3), EV4, ARG_EV4HWMEM },
+ { "hw_stq/v", EV5HWMEM(0x1F,0x06), EV5, ARG_EV5HWMEM },
+ { "hw_stq/vc", EV5HWMEM(0x1F,0x07), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c", EV5HWMEM(0x1F,0x05), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/a", EV5HWMEM(0x1F,0x15), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/av", EV5HWMEM(0x1F,0x17), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/p", EV5HWMEM(0x1F,0x25), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/p", EV6HWMEM(0x1F,0x3), EV6, ARG_EV6HWMEM },
+ { "hw_stq_c/pa", EV5HWMEM(0x1F,0x35), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/pav", EV5HWMEM(0x1F,0x37), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/pv", EV5HWMEM(0x1F,0x27), EV5, ARG_EV5HWMEM },
+ { "hw_stq_c/v", EV5HWMEM(0x1F,0x07), EV5, ARG_EV5HWMEM },
+ { "hw_st", EV4HWMEM(0x1F,0x0), EV4, ARG_EV4HWMEM },
+ { "hw_st", EV5HWMEM(0x1F,0x00), EV5, ARG_EV5HWMEM },
+ { "hw_st/a", EV4HWMEM(0x1F,0x4), EV4, ARG_EV4HWMEM },
+ { "hw_st/a", EV5HWMEM(0x1F,0x10), EV5, ARG_EV5HWMEM },
+ { "hw_st/ac", EV5HWMEM(0x1F,0x11), EV5, ARG_EV5HWMEM },
+ { "hw_st/aq", EV4HWMEM(0x1F,0x5), EV4, ARG_EV4HWMEM },
+ { "hw_st/aq", EV5HWMEM(0x1F,0x14), EV5, ARG_EV5HWMEM },
+ { "hw_st/aqc", EV5HWMEM(0x1F,0x15), EV5, ARG_EV5HWMEM },
+ { "hw_st/aqv", EV5HWMEM(0x1F,0x16), EV5, ARG_EV5HWMEM },
+ { "hw_st/aqvc", EV5HWMEM(0x1F,0x17), EV5, ARG_EV5HWMEM },
+ { "hw_st/ar", EV4HWMEM(0x1F,0x6), EV4, ARG_EV4HWMEM },
+ { "hw_st/arq", EV4HWMEM(0x1F,0x7), EV4, ARG_EV4HWMEM },
+ { "hw_st/av", EV5HWMEM(0x1F,0x12), EV5, ARG_EV5HWMEM },
+ { "hw_st/avc", EV5HWMEM(0x1F,0x13), EV5, ARG_EV5HWMEM },
+ { "hw_st/c", EV5HWMEM(0x1F,0x01), EV5, ARG_EV5HWMEM },
+ { "hw_st/p", EV4HWMEM(0x1F,0x8), EV4, ARG_EV4HWMEM },
+ { "hw_st/p", EV5HWMEM(0x1F,0x20), EV5, ARG_EV5HWMEM },
+ { "hw_st/pa", EV4HWMEM(0x1F,0xC), EV4, ARG_EV4HWMEM },
+ { "hw_st/pa", EV5HWMEM(0x1F,0x30), EV5, ARG_EV5HWMEM },
+ { "hw_st/pac", EV5HWMEM(0x1F,0x31), EV5, ARG_EV5HWMEM },
+ { "hw_st/paq", EV4HWMEM(0x1F,0xD), EV4, ARG_EV4HWMEM },
+ { "hw_st/paq", EV5HWMEM(0x1F,0x34), EV5, ARG_EV5HWMEM },
+ { "hw_st/paqc", EV5HWMEM(0x1F,0x35), EV5, ARG_EV5HWMEM },
+ { "hw_st/paqv", EV5HWMEM(0x1F,0x36), EV5, ARG_EV5HWMEM },
+ { "hw_st/paqvc", EV5HWMEM(0x1F,0x37), EV5, ARG_EV5HWMEM },
+ { "hw_st/par", EV4HWMEM(0x1F,0xE), EV4, ARG_EV4HWMEM },
+ { "hw_st/parq", EV4HWMEM(0x1F,0xF), EV4, ARG_EV4HWMEM },
+ { "hw_st/pav", EV5HWMEM(0x1F,0x32), EV5, ARG_EV5HWMEM },
+ { "hw_st/pavc", EV5HWMEM(0x1F,0x33), EV5, ARG_EV5HWMEM },
+ { "hw_st/pc", EV5HWMEM(0x1F,0x21), EV5, ARG_EV5HWMEM },
+ { "hw_st/pq", EV4HWMEM(0x1F,0x9), EV4, ARG_EV4HWMEM },
+ { "hw_st/pq", EV5HWMEM(0x1F,0x24), EV5, ARG_EV5HWMEM },
+ { "hw_st/pqc", EV5HWMEM(0x1F,0x25), EV5, ARG_EV5HWMEM },
+ { "hw_st/pqv", EV5HWMEM(0x1F,0x26), EV5, ARG_EV5HWMEM },
+ { "hw_st/pqvc", EV5HWMEM(0x1F,0x27), EV5, ARG_EV5HWMEM },
+ { "hw_st/pr", EV4HWMEM(0x1F,0xA), EV4, ARG_EV4HWMEM },
+ { "hw_st/prq", EV4HWMEM(0x1F,0xB), EV4, ARG_EV4HWMEM },
+ { "hw_st/pv", EV5HWMEM(0x1F,0x22), EV5, ARG_EV5HWMEM },
+ { "hw_st/pvc", EV5HWMEM(0x1F,0x23), EV5, ARG_EV5HWMEM },
+ { "hw_st/q", EV4HWMEM(0x1F,0x1), EV4, ARG_EV4HWMEM },
+ { "hw_st/q", EV5HWMEM(0x1F,0x04), EV5, ARG_EV5HWMEM },
+ { "hw_st/qc", EV5HWMEM(0x1F,0x05), EV5, ARG_EV5HWMEM },
+ { "hw_st/qv", EV5HWMEM(0x1F,0x06), EV5, ARG_EV5HWMEM },
+ { "hw_st/qvc", EV5HWMEM(0x1F,0x07), EV5, ARG_EV5HWMEM },
+ { "hw_st/r", EV4HWMEM(0x1F,0x2), EV4, ARG_EV4HWMEM },
+ { "hw_st/v", EV5HWMEM(0x1F,0x02), EV5, ARG_EV5HWMEM },
+ { "hw_st/vc", EV5HWMEM(0x1F,0x03), EV5, ARG_EV5HWMEM },
+ { "pal1f", PCD(0x1F), BASE, ARG_PCD },
+
+ { "ldf", MEM(0x20), BASE, ARG_FMEM },
+ { "ldg", MEM(0x21), BASE, ARG_FMEM },
+ { "lds", MEM(0x22), BASE, ARG_FMEM },
+ { "ldt", MEM(0x23), BASE, ARG_FMEM },
+ { "stf", MEM(0x24), BASE, ARG_FMEM },
+ { "stg", MEM(0x25), BASE, ARG_FMEM },
+ { "sts", MEM(0x26), BASE, ARG_FMEM },
+ { "stt", MEM(0x27), BASE, ARG_FMEM },
+
+ { "ldl", MEM(0x28), BASE, ARG_MEM },
+ { "ldq", MEM(0x29), BASE, ARG_MEM },
+ { "ldl_l", MEM(0x2A), BASE, ARG_MEM },
+ { "ldq_l", MEM(0x2B), BASE, ARG_MEM },
+ { "stl", MEM(0x2C), BASE, ARG_MEM },
+ { "stq", MEM(0x2D), BASE, ARG_MEM },
+ { "stl_c", MEM(0x2E), BASE, ARG_MEM },
+ { "stq_c", MEM(0x2F), BASE, ARG_MEM },
+
+ { "br", BRA(0x30), BASE, { ZA, BDISP } }, /* pseudo */
+ { "br", BRA(0x30), BASE, ARG_BRA },
+ { "fbeq", BRA(0x31), BASE, ARG_FBRA },
+ { "fblt", BRA(0x32), BASE, ARG_FBRA },
+ { "fble", BRA(0x33), BASE, ARG_FBRA },
+ { "bsr", BRA(0x34), BASE, ARG_BRA },
+ { "fbne", BRA(0x35), BASE, ARG_FBRA },
+ { "fbge", BRA(0x36), BASE, ARG_FBRA },
+ { "fbgt", BRA(0x37), BASE, ARG_FBRA },
+ { "blbc", BRA(0x38), BASE, ARG_BRA },
+ { "beq", BRA(0x39), BASE, ARG_BRA },
+ { "blt", BRA(0x3A), BASE, ARG_BRA },
+ { "ble", BRA(0x3B), BASE, ARG_BRA },
+ { "blbs", BRA(0x3C), BASE, ARG_BRA },
+ { "bne", BRA(0x3D), BASE, ARG_BRA },
+ { "bge", BRA(0x3E), BASE, ARG_BRA },
+ { "bgt", BRA(0x3F), BASE, ARG_BRA },
+};
+
+const int alpha_num_opcodes = sizeof(alpha_opcodes)/sizeof(*alpha_opcodes);
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
new file mode 100644
index 00000000000..802b07b9521
--- /dev/null
+++ b/opcodes/arc-dis.c
@@ -0,0 +1,267 @@
+/* Instruction printing code for the ARC.
+ Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "dis-asm.h"
+#include "opcode/arc.h"
+#include "elf-bfd.h"
+#include "elf/arc.h"
+#include "opintl.h"
+
+static int print_insn_arc_base_little PARAMS ((bfd_vma, disassemble_info *));
+static int print_insn_arc_base_big PARAMS ((bfd_vma, disassemble_info *));
+
+static int print_insn PARAMS ((bfd_vma, disassemble_info *, int, int));
+
+/* Print one instruction from PC on INFO->STREAM.
+ Return the size of the instruction (4 or 8 for the ARC). */
+
+static int
+print_insn (pc, info, mach, big_p)
+ bfd_vma pc;
+ disassemble_info *info;
+ int mach;
+ int big_p;
+{
+ const struct arc_opcode *opcode;
+ bfd_byte buffer[4];
+ void *stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+ int status;
+ /* First element is insn, second element is limm (if present). */
+ arc_insn insn[2];
+ int got_limm_p = 0;
+ static int initialized = 0;
+ static int current_mach = 0;
+
+ if (!initialized || mach != current_mach)
+ {
+ initialized = 1;
+ current_mach = arc_get_opcode_mach (mach, big_p);
+ arc_opcode_init_tables (current_mach);
+ }
+
+ status = (*info->read_memory_func) (pc, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+ if (big_p)
+ insn[0] = bfd_getb32 (buffer);
+ else
+ insn[0] = bfd_getl32 (buffer);
+
+ (*func) (stream, "%08lx\t", insn[0]);
+
+ /* The instructions are stored in lists hashed by the insn code
+ (though we needn't care how they're hashed). */
+
+ opcode = arc_opcode_lookup_dis (insn[0]);
+ for ( ; opcode != NULL; opcode = ARC_OPCODE_NEXT_DIS (opcode))
+ {
+ char *syn;
+ int mods,invalid;
+ long value;
+ const struct arc_operand *operand;
+ const struct arc_operand_value *opval;
+
+ /* Basic bit mask must be correct. */
+ if ((insn[0] & opcode->mask) != opcode->value)
+ continue;
+
+ /* Supported by this cpu? */
+ if (! arc_opcode_supported (opcode))
+ continue;
+
+ /* Make two passes over the operands. First see if any of them
+ have extraction functions, and, if they do, make sure the
+ instruction is valid. */
+
+ arc_opcode_init_extract ();
+ invalid = 0;
+
+ /* ??? Granted, this is slower than the `ppc' way. Maybe when this is
+ done it'll be clear what the right way to do this is. */
+ /* Instructions like "add.f r0,r1,1" are tricky because the ".f" gets
+ printed first, but we don't know how to print it until we've processed
+ the regs. Since we're scanning all the args before printing the insn
+ anyways, it's actually quite easy. */
+
+ for (syn = opcode->syntax; *syn; ++syn)
+ {
+ int c;
+
+ if (*syn != '%' || *++syn == '%')
+ continue;
+ mods = 0;
+ c = *syn;
+ while (ARC_MOD_P (arc_operands[arc_operand_map[c]].flags))
+ {
+ mods |= arc_operands[arc_operand_map[c]].flags & ARC_MOD_BITS;
+ ++syn;
+ c = *syn;
+ }
+ operand = arc_operands + arc_operand_map[c];
+ if (operand->extract)
+ (*operand->extract) (insn, operand, mods,
+ (const struct arc_operand_value **) NULL,
+ &invalid);
+ }
+ if (invalid)
+ continue;
+
+ /* The instruction is valid. */
+
+ /* If we have an insn with a limm, fetch it now. Scanning the insns
+ twice lets us do this. */
+ if (arc_opcode_limm_p (NULL))
+ {
+ status = (*info->read_memory_func) (pc + 4, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+ if (big_p)
+ insn[1] = bfd_getb32 (buffer);
+ else
+ insn[1] = bfd_getl32 (buffer);
+ got_limm_p = 1;
+ }
+
+ for (syn = opcode->syntax; *syn; ++syn)
+ {
+ int c;
+
+ if (*syn != '%' || *++syn == '%')
+ {
+ (*func) (stream, "%c", *syn);
+ continue;
+ }
+
+ /* We have an operand. Fetch any special modifiers. */
+ mods = 0;
+ c = *syn;
+ while (ARC_MOD_P (arc_operands[arc_operand_map[c]].flags))
+ {
+ mods |= arc_operands[arc_operand_map[c]].flags & ARC_MOD_BITS;
+ ++syn;
+ c = *syn;
+ }
+ operand = arc_operands + arc_operand_map[c];
+
+ /* Extract the value from the instruction. */
+ opval = NULL;
+ if (operand->extract)
+ {
+ value = (*operand->extract) (insn, operand, mods,
+ &opval, (int *) NULL);
+ }
+ else
+ {
+ value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
+ if ((operand->flags & ARC_OPERAND_SIGNED)
+ && (value & (1 << (operand->bits - 1))))
+ value -= 1 << operand->bits;
+
+ /* If this is a suffix operand, set `opval'. */
+ if (operand->flags & ARC_OPERAND_SUFFIX)
+ opval = arc_opcode_lookup_suffix (operand, value);
+ }
+
+ /* Print the operand as directed by the flags. */
+ if (operand->flags & ARC_OPERAND_FAKE)
+ ; /* nothing to do (??? at least not yet) */
+ else if (operand->flags & ARC_OPERAND_SUFFIX)
+ {
+ /* Default suffixes aren't printed. Fortunately, they all have
+ zero values. Also, zero values for boolean suffixes are
+ represented by the absence of text. */
+
+ if (value != 0)
+ {
+ /* ??? OPVAL should have a value. If it doesn't just cope
+ as we want disassembly to be reasonably robust.
+ Also remember that several condition code values (16-31)
+ aren't defined yet. For these cases just print the
+ number suitably decorated. */
+ if (opval)
+ (*func) (stream, "%s%s",
+ mods & ARC_MOD_DOT ? "." : "",
+ opval->name);
+ else
+ (*func) (stream, "%s%c%d",
+ mods & ARC_MOD_DOT ? "." : "",
+ operand->fmt, value);
+ }
+ }
+ else if (operand->flags & ARC_OPERAND_RELATIVE_BRANCH)
+ (*info->print_address_func) (pc + 4 + value, info);
+ /* ??? Not all cases of this are currently caught. */
+ else if (operand->flags & ARC_OPERAND_ABSOLUTE_BRANCH)
+ (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
+ else if (operand->flags & ARC_OPERAND_ADDRESS)
+ (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
+ else if (opval)
+ /* Note that this case catches both normal and auxiliary regs. */
+ (*func) (stream, "%s", opval->name);
+ else
+ (*func) (stream, "%ld", value);
+ }
+
+ /* We have found and printed an instruction; return. */
+ return got_limm_p ? 8 : 4;
+ }
+
+ (*func) (stream, _("*unknown*"));
+ return 4;
+}
+
+/* Given MACH, one of bfd_mach_arc_xxx, return the print_insn function to use.
+ This does things a non-standard way (the "standard" way would be to copy
+ this code into disassemble.c). Since there are more than a couple of
+ variants, hiding all this crud here seems cleaner. */
+
+disassembler_ftype
+arc_get_disassembler (mach, big_p)
+ int mach;
+ int big_p;
+{
+ switch (mach)
+ {
+ case bfd_mach_arc_base:
+ return big_p ? print_insn_arc_base_big : print_insn_arc_base_little;
+ }
+ return print_insn_arc_base_little;
+}
+
+static int
+print_insn_arc_base_little (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ return print_insn (pc, info, bfd_mach_arc_base, 0);
+}
+
+static int
+print_insn_arc_base_big (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ return print_insn (pc, info, bfd_mach_arc_base, 1);
+}
diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c
new file mode 100644
index 00000000000..0f8f6895965
--- /dev/null
+++ b/opcodes/arc-opc.c
@@ -0,0 +1,1131 @@
+/* Opcode table for the ARC.
+ Copyright (c) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Doug Evans (dje@cygnus.com).
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/arc.h"
+#include "opintl.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define INSERT_FN(fn) \
+static arc_insn fn PARAMS ((arc_insn, const struct arc_operand *, \
+ int, const struct arc_operand_value *, long, \
+ const char **))
+#define EXTRACT_FN(fn) \
+static long fn PARAMS ((arc_insn *, const struct arc_operand *, \
+ int, const struct arc_operand_value **, int *))
+
+INSERT_FN (insert_reg);
+INSERT_FN (insert_shimmfinish);
+INSERT_FN (insert_limmfinish);
+INSERT_FN (insert_shimmoffset);
+INSERT_FN (insert_shimmzero);
+INSERT_FN (insert_flag);
+INSERT_FN (insert_flagfinish);
+INSERT_FN (insert_cond);
+INSERT_FN (insert_forcelimm);
+INSERT_FN (insert_reladdr);
+INSERT_FN (insert_absaddr);
+INSERT_FN (insert_unopmacro);
+
+EXTRACT_FN (extract_reg);
+EXTRACT_FN (extract_flag);
+EXTRACT_FN (extract_cond);
+EXTRACT_FN (extract_reladdr);
+EXTRACT_FN (extract_unopmacro);
+
+/* Various types of ARC operands, including insn suffixes. */
+
+/* Insn format values:
+
+ 'a' REGA register A field
+ 'b' REGB register B field
+ 'c' REGC register C field
+ 'S' SHIMMFINISH finish inserting a shimm value
+ 'L' LIMMFINISH finish inserting a limm value
+ 'd' SHIMMOFFSET shimm offset in ld,st insns
+ '0' SHIMMZERO 0 shimm value in ld,st insns
+ 'f' FLAG F flag
+ 'F' FLAGFINISH finish inserting the F flag
+ 'G' FLAGINSN insert F flag in "flag" insn
+ 'n' DELAY N field (nullify field)
+ 'q' COND condition code field
+ 'Q' FORCELIMM set `cond_p' to 1 to ensure a constant is a limm
+ 'B' BRANCH branch address (22 bit pc relative)
+ 'J' JUMP jump address (26 bit absolute)
+ 'z' SIZE1 size field in ld a,[b,c]
+ 'Z' SIZE10 size field in ld a,[b,shimm]
+ 'y' SIZE22 size field in st c,[b,shimm]
+ 'x' SIGN0 sign extend field ld a,[b,c]
+ 'X' SIGN9 sign extend field ld a,[b,shimm]
+ 'w' ADDRESS3 write-back field in ld a,[b,c]
+ 'W' ADDRESS12 write-back field in ld a,[b,shimm]
+ 'v' ADDRESS24 write-back field in st c,[b,shimm]
+ 'e' CACHEBYPASS5 cache bypass in ld a,[b,c]
+ 'E' CACHEBYPASS14 cache bypass in ld a,[b,shimm]
+ 'D' CACHEBYPASS26 cache bypass in st c,[b,shimm]
+ 'U' UNOPMACRO fake operand to copy REGB to REGC for unop macros
+
+ The following modifiers may appear between the % and char (eg: %.f):
+
+ '.' MODDOT '.' prefix must be present
+ 'r' REG generic register value, for register table
+ 'A' AUXREG auxiliary register in lr a,[b], sr c,[b]
+
+ Fields are:
+
+ CHAR BITS SHIFT FLAGS INSERT_FN EXTRACT_FN
+*/
+
+const struct arc_operand arc_operands[] =
+{
+/* place holder (??? not sure if needed) */
+#define UNUSED 0
+ { 0 },
+
+/* register A or shimm/limm indicator */
+#define REGA (UNUSED + 1)
+ { 'a', 6, ARC_SHIFT_REGA, ARC_OPERAND_SIGNED, insert_reg, extract_reg },
+
+/* register B or shimm/limm indicator */
+#define REGB (REGA + 1)
+ { 'b', 6, ARC_SHIFT_REGB, ARC_OPERAND_SIGNED, insert_reg, extract_reg },
+
+/* register C or shimm/limm indicator */
+#define REGC (REGB + 1)
+ { 'c', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED, insert_reg, extract_reg },
+
+/* fake operand used to insert shimm value into most instructions */
+#define SHIMMFINISH (REGC + 1)
+ { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish, 0 },
+
+/* fake operand used to insert limm value into most instructions. */
+#define LIMMFINISH (SHIMMFINISH + 1)
+ { 'L', 32, 32, ARC_OPERAND_ADDRESS + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE, insert_limmfinish, 0 },
+
+/* shimm operand when there is no reg indicator (ld,st) */
+#define SHIMMOFFSET (LIMMFINISH + 1)
+ { 'd', 9, 0, ARC_OPERAND_SIGNED, insert_shimmoffset, 0 },
+
+/* 0 shimm operand for ld,st insns */
+#define SHIMMZERO (SHIMMOFFSET + 1)
+ { '0', 9, 0, ARC_OPERAND_FAKE, insert_shimmzero, 0 },
+
+/* flag update bit (insertion is defered until we know how) */
+#define FLAG (SHIMMZERO + 1)
+ { 'f', 1, 8, ARC_OPERAND_SUFFIX, insert_flag, extract_flag },
+
+/* fake utility operand to finish 'f' suffix handling */
+#define FLAGFINISH (FLAG + 1)
+ { 'F', 1, 8, ARC_OPERAND_FAKE, insert_flagfinish, 0 },
+
+/* fake utility operand to set the 'f' flag for the "flag" insn */
+#define FLAGINSN (FLAGFINISH + 1)
+ { 'G', 1, 8, ARC_OPERAND_FAKE, insert_flag, 0 },
+
+/* branch delay types */
+#define DELAY (FLAGINSN + 1)
+ { 'n', 2, 5, ARC_OPERAND_SUFFIX },
+
+/* conditions */
+#define COND (DELAY + 1)
+ { 'q', 5, 0, ARC_OPERAND_SUFFIX, insert_cond, extract_cond },
+
+/* set `cond_p' to 1 to ensure a constant is treated as a limm */
+#define FORCELIMM (COND + 1)
+ { 'Q', 0, 0, ARC_OPERAND_FAKE, insert_forcelimm },
+
+/* branch address; b, bl, and lp insns */
+#define BRANCH (FORCELIMM + 1)
+ { 'B', 20, 7, ARC_OPERAND_RELATIVE_BRANCH + ARC_OPERAND_SIGNED, insert_reladdr, extract_reladdr },
+
+/* jump address; j insn (this is basically the same as 'L' except that the
+ value is right shifted by 2) */
+#define JUMP (BRANCH + 1)
+ { 'J', 24, 32, ARC_OPERAND_ABSOLUTE_BRANCH + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE, insert_absaddr },
+
+/* size field, stored in bit 1,2 */
+#define SIZE1 (JUMP + 1)
+ { 'z', 2, 1, ARC_OPERAND_SUFFIX },
+
+/* size field, stored in bit 10,11 */
+#define SIZE10 (SIZE1 + 1)
+ { 'Z', 2, 10, ARC_OPERAND_SUFFIX, },
+
+/* size field, stored in bit 22,23 */
+#define SIZE22 (SIZE10 + 1)
+ { 'y', 2, 22, ARC_OPERAND_SUFFIX, },
+
+/* sign extend field, stored in bit 0 */
+#define SIGN0 (SIZE22 + 1)
+ { 'x', 1, 0, ARC_OPERAND_SUFFIX },
+
+/* sign extend field, stored in bit 9 */
+#define SIGN9 (SIGN0 + 1)
+ { 'X', 1, 9, ARC_OPERAND_SUFFIX },
+
+/* address write back, stored in bit 3 */
+#define ADDRESS3 (SIGN9 + 1)
+ { 'w', 1, 3, ARC_OPERAND_SUFFIX },
+
+/* address write back, stored in bit 12 */
+#define ADDRESS12 (ADDRESS3 + 1)
+ { 'W', 1, 12, ARC_OPERAND_SUFFIX },
+
+/* address write back, stored in bit 24 */
+#define ADDRESS24 (ADDRESS12 + 1)
+ { 'v', 1, 24, ARC_OPERAND_SUFFIX },
+
+/* cache bypass, stored in bit 5 */
+#define CACHEBYPASS5 (ADDRESS24 + 1)
+ { 'e', 1, 5, ARC_OPERAND_SUFFIX },
+
+/* cache bypass, stored in bit 14 */
+#define CACHEBYPASS14 (CACHEBYPASS5 + 1)
+ { 'E', 1, 14, ARC_OPERAND_SUFFIX },
+
+/* cache bypass, stored in bit 26 */
+#define CACHEBYPASS26 (CACHEBYPASS14 + 1)
+ { 'D', 1, 26, ARC_OPERAND_SUFFIX },
+
+/* unop macro, used to copy REGB to REGC */
+#define UNOPMACRO (CACHEBYPASS26 + 1)
+ { 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro },
+
+/* '.' modifier ('.' required). */
+#define MODDOT (UNOPMACRO + 1)
+ { '.', 1, 0, ARC_MOD_DOT },
+
+/* Dummy 'r' modifier for the register table.
+ It's called a "dummy" because there's no point in inserting an 'r' into all
+ the %a/%b/%c occurrences in the insn table. */
+#define REG (MODDOT + 1)
+ { 'r', 6, 0, ARC_MOD_REG },
+
+/* Known auxiliary register modifier (stored in shimm field). */
+#define AUXREG (REG + 1)
+ { 'A', 9, 0, ARC_MOD_AUXREG },
+
+/* end of list place holder */
+ { 0 }
+};
+
+/* Given a format letter, yields the index into `arc_operands'.
+ eg: arc_operand_map['a'] = REGA. */
+unsigned char arc_operand_map[256];
+
+#define I(x) (((x) & 31) << 27)
+#define A(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGA)
+#define B(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGB)
+#define C(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGC)
+#define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */
+
+/* ARC instructions.
+
+ Longer versions of insns must appear before shorter ones (if gas sees
+ "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
+ junk). This isn't necessary for `ld' because of the trailing ']'.
+
+ Instructions that are really macros based on other insns must appear
+ before the real insn so they're chosen when disassembling. Eg: The `mov'
+ insn is really the `and' insn.
+
+ This table is best viewed on a wide screen (161 columns). I'd prefer to
+ keep it this way. The rest of the file, however, should be viewable on an
+ 80 column terminal. */
+
+/* ??? This table also includes macros: asl, lsl, and mov. The ppc port has
+ a more general facility for dealing with macros which could be used if
+ we need to. */
+
+/* This table can't be `const' because members `next_asm' and `next_dis' are
+ computed at run-time. We could split this into two, but that doesn't seem
+ worth it. */
+
+struct arc_opcode arc_opcodes[] = {
+
+ /* Macros appear first. */
+ /* "mov" is really an "and". */
+ { "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12) },
+ /* "asl" is really an "add". */
+ { "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
+ /* "lsl" is really an "add". */
+ { "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
+ /* "nop" is really an "xor". */
+ { "nop", 0xffffffff, 0x7fffffff },
+ /* "rlc" is really an "adc". */
+ { "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9) },
+
+ /* The rest of these needn't be sorted, but it helps to find them if they are. */
+ { "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9) },
+ { "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8) },
+ { "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12) },
+ { "asr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(1) },
+ { "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14) },
+ { "b%q%.n %B", I(-1), I(4), ARC_OPCODE_COND_BRANCH },
+ { "bl%q%.n %B", I(-1), I(5), ARC_OPCODE_COND_BRANCH },
+ { "extb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(7) },
+ { "extw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(8) },
+ { "flag%.q %b%G%S%L", I(-1)+A(-1)+C(-1), I(3)+A(ARC_REG_SHIMM_UPDATE)+C(0) },
+ /* %Q: force cond_p=1 --> no shimm values */
+ /* ??? This insn allows an optional flags spec. */
+ { "j%q%Q%.n%.f %b%J", I(-1)+A(-1)+C(-1)+R(-1,7,1), I(7)+A(0)+C(0)+R(0,7,1) },
+ /* Put opcode 1 ld insns first so shimm gets prefered over limm. */
+ /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */
+ { "ld%Z%.X%.W%.E %0%a,[%b]%L", I(-1)+R(-1,13,1)+R(-1,0,511), I(1)+R(0,13,1)+R(0,0,511) },
+ { "ld%Z%.X%.W%.E %a,[%b,%d]%S%L", I(-1)+R(-1,13,1), I(1)+R(0,13,1) },
+ { "ld%z%.x%.w%.e%Q %a,[%b,%c]%L", I(-1)+R(-1,4,1)+R(-1,6,7), I(0)+R(0,4,1)+R(0,6,7) },
+ { "lp%q%.n %B", I(-1), I(6), },
+ { "lr %a,[%Ab]%S%L", I(-1)+C(-1), I(1)+C(0x10) },
+ { "lsr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(2) },
+ { "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13) },
+ { "ror%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(3) },
+ { "rrc%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(4) },
+ { "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11) },
+ { "sexb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(5) },
+ { "sexw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(6) },
+ { "sr %c,[%Ab]%S%L", I(-1)+A(-1), I(2)+A(0x10) },
+ /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */
+ { "st%y%.v%.D%Q %0%c,[%b]%L", I(-1)+R(-1,25,1)+R(-1,21,1)+R(-1,0,511), I(2)+R(0,25,1)+R(0,21,1)+R(0,0,511) },
+ { "st%y%.v%.D %c,[%b,%d]%S%L", I(-1)+R(-1,25,1)+R(-1,21,1), I(2)+R(0,25,1)+R(0,21,1) },
+ { "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10) },
+ { "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15) }
+};
+const int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
+
+const struct arc_operand_value arc_reg_names[] =
+{
+ /* Sort this so that the first 61 entries are sequential.
+ IE: For each i (i<61), arc_reg_names[i].value == i. */
+
+ { "r0", 0, REG }, { "r1", 1, REG }, { "r2", 2, REG }, { "r3", 3, REG },
+ { "r4", 4, REG }, { "r5", 5, REG }, { "r6", 6, REG }, { "r7", 7, REG },
+ { "r8", 8, REG }, { "r9", 9, REG }, { "r10", 10, REG }, { "r11", 11, REG },
+ { "r12", 12, REG }, { "r13", 13, REG }, { "r14", 14, REG }, { "r15", 15, REG },
+ { "r16", 16, REG }, { "r17", 17, REG }, { "r18", 18, REG }, { "r19", 19, REG },
+ { "r20", 20, REG }, { "r21", 21, REG }, { "r22", 22, REG }, { "r23", 23, REG },
+ { "r24", 24, REG }, { "r25", 25, REG }, { "r26", 26, REG }, { "fp", 27, REG },
+ { "sp", 28, REG }, { "ilink1", 29, REG }, { "ilink2", 30, REG }, { "blink", 31, REG },
+ { "r32", 32, REG }, { "r33", 33, REG }, { "r34", 34, REG }, { "r35", 35, REG },
+ { "r36", 36, REG }, { "r37", 37, REG }, { "r38", 38, REG }, { "r39", 39, REG },
+ { "r40", 40, REG }, { "r41", 41, REG }, { "r42", 42, REG }, { "r43", 43, REG },
+ { "r44", 44, REG }, { "r45", 45, REG }, { "r46", 46, REG }, { "r47", 47, REG },
+ { "r48", 48, REG }, { "r49", 49, REG }, { "r50", 50, REG }, { "r51", 51, REG },
+ { "r52", 52, REG }, { "r53", 53, REG }, { "r54", 54, REG }, { "r55", 55, REG },
+ { "r56", 56, REG }, { "r57", 57, REG }, { "r58", 58, REG }, { "r59", 59, REG },
+ { "lp_count", 60, REG },
+
+ /* I'd prefer to output these as "fp" and "sp" by default, but we still need
+ to recognize the canonical values. */
+ { "r27", 27, REG }, { "r28", 28, REG },
+
+ /* Someone may wish to refer to these in this way, and it's probably a
+ good idea to reserve them as such anyway. */
+ { "r29", 29, REG }, { "r30", 30, REG }, { "r31", 31, REG }, { "r60", 60, REG },
+
+ /* Standard auxiliary registers. */
+ { "status", 0, AUXREG },
+ { "semaphore", 1, AUXREG },
+ { "lp_start", 2, AUXREG },
+ { "lp_end", 3, AUXREG },
+ { "identity", 4, AUXREG },
+ { "debug", 5, AUXREG },
+};
+const int arc_reg_names_count = sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
+
+/* The suffix table.
+ Operands with the same name must be stored together. */
+
+const struct arc_operand_value arc_suffixes[] =
+{
+ /* Entry 0 is special, default values aren't printed by the disassembler. */
+ { "", 0, -1 },
+ { "al", 0, COND },
+ { "ra", 0, COND },
+ { "eq", 1, COND },
+ { "z", 1, COND },
+ { "ne", 2, COND },
+ { "nz", 2, COND },
+ { "p", 3, COND },
+ { "pl", 3, COND },
+ { "n", 4, COND },
+ { "mi", 4, COND },
+ { "c", 5, COND },
+ { "cs", 5, COND },
+ { "lo", 5, COND },
+ { "nc", 6, COND },
+ { "cc", 6, COND },
+ { "hs", 6, COND },
+ { "v", 7, COND },
+ { "vs", 7, COND },
+ { "nv", 8, COND },
+ { "vc", 8, COND },
+ { "gt", 9, COND },
+ { "ge", 10, COND },
+ { "lt", 11, COND },
+ { "le", 12, COND },
+ { "hi", 13, COND },
+ { "ls", 14, COND },
+ { "pnz", 15, COND },
+ { "f", 1, FLAG },
+ { "nd", ARC_DELAY_NONE, DELAY },
+ { "d", ARC_DELAY_NORMAL, DELAY },
+ { "jd", ARC_DELAY_JUMP, DELAY },
+/*{ "b", 7, SIZEEXT },*/
+/*{ "b", 5, SIZESEX },*/
+ { "b", 1, SIZE1 },
+ { "b", 1, SIZE10 },
+ { "b", 1, SIZE22 },
+/*{ "w", 8, SIZEEXT },*/
+/*{ "w", 6, SIZESEX },*/
+ { "w", 2, SIZE1 },
+ { "w", 2, SIZE10 },
+ { "w", 2, SIZE22 },
+ { "x", 1, SIGN0 },
+ { "x", 1, SIGN9 },
+ { "a", 1, ADDRESS3 },
+ { "a", 1, ADDRESS12 },
+ { "a", 1, ADDRESS24 },
+ { "di", 1, CACHEBYPASS5 },
+ { "di", 1, CACHEBYPASS14 },
+ { "di", 1, CACHEBYPASS26 },
+};
+const int arc_suffixes_count = sizeof (arc_suffixes) / sizeof (arc_suffixes[0]);
+
+/* Indexed by first letter of opcode. Points to chain of opcodes with same
+ first letter. */
+static struct arc_opcode *opcode_map[26 + 1];
+
+/* Indexed by insn code. Points to chain of opcodes with same insn code. */
+static struct arc_opcode *icode_map[32];
+
+/* Configuration flags. */
+
+/* Various ARC_HAVE_XXX bits. */
+static int cpu_type;
+
+/* Translate a bfd_mach_arc_xxx value to a ARC_MACH_XXX value. */
+
+int
+arc_get_opcode_mach (bfd_mach, big_p)
+ int bfd_mach, big_p;
+{
+ static int mach_type_map[] =
+ {
+ ARC_MACH_BASE
+ };
+
+ return mach_type_map[bfd_mach] | (big_p ? ARC_MACH_BIG : 0);
+}
+
+/* Initialize any tables that need it.
+ Must be called once at start up (or when first needed).
+
+ FLAGS is a set of bits that say what version of the cpu we have,
+ and in particular at least (one of) ARC_MACH_XXX. */
+
+void
+arc_opcode_init_tables (flags)
+ int flags;
+{
+ static int init_p = 0;
+
+ cpu_type = flags;
+
+ /* We may be intentionally called more than once (for example gdb will call
+ us each time the user switches cpu). These tables only need to be init'd
+ once though. */
+ /* ??? We can remove the need for arc_opcode_supported by taking it into
+ account here, but I'm not sure I want to do that yet (if ever). */
+ if (!init_p)
+ {
+ register int i,n;
+
+ memset (arc_operand_map, 0, sizeof (arc_operand_map));
+ n = sizeof (arc_operands) / sizeof (arc_operands[0]);
+ for (i = 0; i < n; ++i)
+ arc_operand_map[arc_operands[i].fmt] = i;
+
+ memset (opcode_map, 0, sizeof (opcode_map));
+ memset (icode_map, 0, sizeof (icode_map));
+ /* Scan the table backwards so macros appear at the front. */
+ for (i = arc_opcodes_count - 1; i >= 0; --i)
+ {
+ int opcode_hash = ARC_HASH_OPCODE (arc_opcodes[i].syntax);
+ int icode_hash = ARC_HASH_ICODE (arc_opcodes[i].value);
+
+ arc_opcodes[i].next_asm = opcode_map[opcode_hash];
+ opcode_map[opcode_hash] = &arc_opcodes[i];
+
+ arc_opcodes[i].next_dis = icode_map[icode_hash];
+ icode_map[icode_hash] = &arc_opcodes[i];
+ }
+
+ init_p = 1;
+ }
+}
+
+/* Return non-zero if OPCODE is supported on the specified cpu.
+ Cpu selection is made when calling `arc_opcode_init_tables'. */
+
+int
+arc_opcode_supported (opcode)
+ const struct arc_opcode *opcode;
+{
+ if (ARC_OPCODE_CPU (opcode->flags) == 0)
+ return 1;
+ if (ARC_OPCODE_CPU (opcode->flags) & ARC_HAVE_CPU (cpu_type))
+ return 1;
+ return 0;
+}
+
+/* Return non-zero if OPVAL is supported on the specified cpu.
+ Cpu selection is made when calling `arc_opcode_init_tables'. */
+
+int
+arc_opval_supported (opval)
+ const struct arc_operand_value *opval;
+{
+ if (ARC_OPVAL_CPU (opval->flags) == 0)
+ return 1;
+ if (ARC_OPVAL_CPU (opval->flags) & ARC_HAVE_CPU (cpu_type))
+ return 1;
+ return 0;
+}
+
+/* Return the first insn in the chain for assembling INSN. */
+
+const struct arc_opcode *
+arc_opcode_lookup_asm (insn)
+ const char *insn;
+{
+ return opcode_map[ARC_HASH_OPCODE (insn)];
+}
+
+/* Return the first insn in the chain for disassembling INSN. */
+
+const struct arc_opcode *
+arc_opcode_lookup_dis (insn)
+ unsigned int insn;
+{
+ return icode_map[ARC_HASH_ICODE (insn)];
+}
+
+/* Nonzero if we've seen an 'f' suffix (in certain insns). */
+static int flag_p;
+
+/* Nonzero if we've finished processing the 'f' suffix. */
+static int flagshimm_handled_p;
+
+/* Nonzero if we've seen a 'q' suffix (condition code). */
+static int cond_p;
+
+/* Nonzero if we've inserted a shimm. */
+static int shimm_p;
+
+/* The value of the shimm we inserted (each insn only gets one but it can
+ appear multiple times. */
+static int shimm;
+
+/* Nonzero if we've inserted a limm (during assembly) or seen a limm
+ (during disassembly). */
+static int limm_p;
+
+/* The value of the limm we inserted. Each insn only gets one but it can
+ appear multiple times. */
+static long limm;
+
+/* Insertion functions. */
+
+/* Called by the assembler before parsing an instruction. */
+
+void
+arc_opcode_init_insert ()
+{
+ flag_p = 0;
+ flagshimm_handled_p = 0;
+ cond_p = 0;
+ shimm_p = 0;
+ limm_p = 0;
+}
+
+/* Called by the assembler to see if the insn has a limm operand.
+ Also called by the disassembler to see if the insn contains a limm. */
+
+int
+arc_opcode_limm_p (limmp)
+ long *limmp;
+{
+ if (limmp)
+ *limmp = limm;
+ return limm_p;
+}
+
+/* Insert a value into a register field.
+ If REG is NULL, then this is actually a constant.
+
+ We must also handle auxiliary registers for lr/sr insns. */
+
+static arc_insn
+insert_reg (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ static char buf[100];
+
+ if (reg == NULL)
+ {
+ /* We have a constant that also requires a value stored in a register
+ field. Handle these by updating the register field and saving the
+ value for later handling by either %S (shimm) or %L (limm). */
+
+ /* Try to use a shimm value before a limm one. */
+ if (ARC_SHIMM_CONST_P (value)
+ /* If we've seen a conditional suffix we have to use a limm. */
+ && !cond_p
+ /* If we already have a shimm value that is different than ours
+ we have to use a limm. */
+ && (!shimm_p || shimm == value))
+ {
+ int marker = flag_p ? ARC_REG_SHIMM_UPDATE : ARC_REG_SHIMM;
+ flagshimm_handled_p = 1;
+ shimm_p = 1;
+ shimm = value;
+ insn |= marker << operand->shift;
+ /* insn |= value & 511; - done later */
+ }
+ /* We have to use a limm. If we've already seen one they must match. */
+ else if (!limm_p || limm == value)
+ {
+ limm_p = 1;
+ limm = value;
+ insn |= ARC_REG_LIMM << operand->shift;
+ /* The constant is stored later. */
+ }
+ else
+ {
+ *errmsg = _("unable to fit different valued constants into instruction");
+ }
+ }
+ else
+ {
+ /* We have to handle both normal and auxiliary registers. */
+
+ if (reg->type == AUXREG)
+ {
+ if (!(mods & ARC_MOD_AUXREG))
+ *errmsg = _("auxiliary register not allowed here");
+ else
+ {
+ insn |= ARC_REG_SHIMM << operand->shift;
+ insn |= reg->value << arc_operands[reg->type].shift;
+ }
+ }
+ else
+ {
+ /* We should never get an invalid register number here. */
+ if ((unsigned int) reg->value > 60)
+ {
+ /* xgettext:c-format */
+ sprintf (buf, _("invalid register number `%d'"), reg->value);
+ *errmsg = buf;
+ }
+ else
+ insn |= reg->value << operand->shift;
+ }
+ }
+
+ return insn;
+}
+
+/* Called when we see an 'f' flag. */
+
+static arc_insn
+insert_flag (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ /* We can't store anything in the insn until we've parsed the registers.
+ Just record the fact that we've got this flag. `insert_reg' will use it
+ to store the correct value (ARC_REG_SHIMM_UPDATE or bit 0x100). */
+ flag_p = 1;
+
+ return insn;
+}
+
+/* Called after completely building an insn to ensure the 'f' flag gets set
+ properly. This is needed because we don't know how to set this flag until
+ we've parsed the registers. */
+
+static arc_insn
+insert_flagfinish (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ if (flag_p && !flagshimm_handled_p)
+ {
+ if (shimm_p)
+ abort ();
+ flagshimm_handled_p = 1;
+ insn |= (1 << operand->shift);
+ }
+ return insn;
+}
+
+/* Called when we see a conditional flag (eg: .eq). */
+
+static arc_insn
+insert_cond (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ cond_p = 1;
+ insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
+ return insn;
+}
+
+/* Used in the "j" instruction to prevent constants from being interpreted as
+ shimm values (which the jump insn doesn't accept). This can also be used
+ to force the use of limm values in other situations (eg: ld r0,[foo] uses
+ this).
+ ??? The mechanism is sound. Access to it is a bit klunky right now. */
+
+static arc_insn
+insert_forcelimm (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ cond_p = 1;
+ return insn;
+}
+
+/* Used in ld/st insns to handle the shimm offset field. */
+
+static arc_insn
+insert_shimmoffset (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ long minval, maxval;
+ static char buf[100];
+
+ if (reg != NULL)
+ {
+ *errmsg = "register appears where shimm value expected";
+ }
+ else
+ {
+ /* This is *way* more general than necessary, but maybe some day it'll
+ be useful. */
+ if (operand->flags & ARC_OPERAND_SIGNED)
+ {
+ minval = -(1 << (operand->bits - 1));
+ maxval = (1 << (operand->bits - 1)) - 1;
+ }
+ else
+ {
+ minval = 0;
+ maxval = (1 << operand->bits) - 1;
+ }
+ if (value < minval || value > maxval)
+ {
+ /* xgettext:c-format */
+ sprintf (buf, _("value won't fit in range %ld - %ld"),
+ minval, maxval);
+ *errmsg = buf;
+ }
+ else
+ insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
+ }
+ return insn;
+}
+
+/* Used in ld/st insns when the shimm offset is 0. */
+
+static arc_insn
+insert_shimmzero (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ shimm_p = 1;
+ shimm = 0;
+ return insn;
+}
+
+/* Called at the end of processing normal insns (eg: add) to insert a shimm
+ value (if present) into the insn. */
+
+static arc_insn
+insert_shimmfinish (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ if (shimm_p)
+ insn |= (shimm & ((1 << operand->bits) - 1)) << operand->shift;
+ return insn;
+}
+
+/* Called at the end of processing normal insns (eg: add) to insert a limm
+ value (if present) into the insn.
+
+ Note that this function is only intended to handle instructions (with 4 byte
+ immediate operands). It is not intended to handle data. */
+
+/* ??? Actually, there's nothing for us to do as we can't call frag_more, the
+ caller must do that. The extract fns take a pointer to two words. The
+ insert fns could be converted and then we could do something useful, but
+ then the reloc handlers would have to know to work on the second word of
+ a 2 word quantity. That's too much so we don't handle them. */
+
+static arc_insn
+insert_limmfinish (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ if (limm_p)
+ ; /* nothing to do, gas does it */
+ return insn;
+}
+
+/* Called at the end of unary operand macros to copy the B field to C. */
+
+static arc_insn
+insert_unopmacro (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ insn |= ((insn >> ARC_SHIFT_REGB) & ARC_MASK_REG) << operand->shift;
+ return insn;
+}
+
+/* Insert a relative address for a branch insn (b, bl, or lp). */
+
+static arc_insn
+insert_reladdr (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ if (value & 3)
+ *errmsg = _("branch address not on 4 byte boundary");
+ insn |= ((value >> 2) & ((1 << operand->bits) - 1)) << operand->shift;
+ return insn;
+}
+
+/* Insert a limm value as a 26 bit address right shifted 2 into the insn.
+
+ Note that this function is only intended to handle instructions (with 4 byte
+ immediate operands). It is not intended to handle data. */
+
+/* ??? Actually, there's nothing for us to do as we can't call frag_more, the
+ caller must do that. The extract fns take a pointer to two words. The
+ insert fns could be converted and then we could do something useful, but
+ then the reloc handlers would have to know to work on the second word of
+ a 2 word quantity. That's too much so we don't handle them. */
+
+static arc_insn
+insert_absaddr (insn, operand, mods, reg, value, errmsg)
+ arc_insn insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value *reg;
+ long value;
+ const char **errmsg;
+{
+ if (limm_p)
+ ; /* nothing to do */
+ return insn;
+}
+
+/* Extraction functions.
+
+ The suffix extraction functions' return value is redundant since it can be
+ obtained from (*OPVAL)->value. However, the boolean suffixes don't have
+ a suffix table entry for the "false" case, so values of zero must be
+ obtained from the return value (*OPVAL == NULL). */
+
+static const struct arc_operand_value *lookup_register (int type, long regno);
+
+/* Called by the disassembler before printing an instruction. */
+
+void
+arc_opcode_init_extract ()
+{
+ flag_p = 0;
+ flagshimm_handled_p = 0;
+ shimm_p = 0;
+ limm_p = 0;
+}
+
+/* As we're extracting registers, keep an eye out for the 'f' indicator
+ (ARC_REG_SHIMM_UPDATE). If we find a register (not a constant marker,
+ like ARC_REG_SHIMM), set OPVAL so our caller will know this is a register.
+
+ We must also handle auxiliary registers for lr/sr insns. They are just
+ constants with special names. */
+
+static long
+extract_reg (insn, operand, mods, opval, invalid)
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid;
+{
+ int regno;
+ long value;
+
+ /* Get the register number. */
+ regno = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
+
+ /* Is it a constant marker? */
+ if (regno == ARC_REG_SHIMM)
+ {
+ value = insn[0] & 511;
+ if ((operand->flags & ARC_OPERAND_SIGNED)
+ && (value & 256))
+ value -= 512;
+ flagshimm_handled_p = 1;
+ }
+ else if (regno == ARC_REG_SHIMM_UPDATE)
+ {
+ value = insn[0] & 511;
+ if ((operand->flags & ARC_OPERAND_SIGNED)
+ && (value & 256))
+ value -= 512;
+ flag_p = 1;
+ flagshimm_handled_p = 1;
+ }
+ else if (regno == ARC_REG_LIMM)
+ {
+ value = insn[1];
+ limm_p = 1;
+ }
+ /* It's a register, set OPVAL (that's the only way we distinguish registers
+ from constants here). */
+ else
+ {
+ const struct arc_operand_value *reg = lookup_register (REG, regno);
+
+ if (reg == NULL)
+ abort ();
+ if (opval != NULL)
+ *opval = reg;
+ value = regno;
+ }
+
+ /* If this field takes an auxiliary register, see if it's a known one. */
+ if ((mods & ARC_MOD_AUXREG)
+ && ARC_REG_CONSTANT_P (regno))
+ {
+ const struct arc_operand_value *reg = lookup_register (AUXREG, value);
+
+ /* This is really a constant, but tell the caller it has a special
+ name. */
+ if (reg != NULL && opval != NULL)
+ *opval = reg;
+ }
+
+ return value;
+}
+
+/* Return the value of the "flag update" field for shimm insns.
+ This value is actually stored in the register field. */
+
+static long
+extract_flag (insn, operand, mods, opval, invalid)
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid;
+{
+ int f;
+ const struct arc_operand_value *val;
+
+ if (flagshimm_handled_p)
+ f = flag_p != 0;
+ else
+ f = (insn[0] & (1 << operand->shift)) != 0;
+
+ /* There is no text for zero values. */
+ if (f == 0)
+ return 0;
+
+ val = arc_opcode_lookup_suffix (operand, 1);
+ if (opval != NULL && val != NULL)
+ *opval = val;
+ return val->value;
+}
+
+/* Extract the condition code (if it exists).
+ If we've seen a shimm value in this insn (meaning that the insn can't have
+ a condition code field), then we don't store anything in OPVAL and return
+ zero. */
+
+static long
+extract_cond (insn, operand, mods, opval, invalid)
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid;
+{
+ long cond;
+ const struct arc_operand_value *val;
+
+ if (flagshimm_handled_p)
+ return 0;
+
+ cond = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
+ val = arc_opcode_lookup_suffix (operand, cond);
+
+ /* Ignore NULL values of `val'. Several condition code values are
+ reserved for extensions. */
+ if (opval != NULL && val != NULL)
+ *opval = val;
+ return cond;
+}
+
+/* Extract a branch address.
+ We return the value as a real address (not right shifted by 2). */
+
+static long
+extract_reladdr (insn, operand, mods, opval, invalid)
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid;
+{
+ long addr;
+
+ addr = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
+ if ((operand->flags & ARC_OPERAND_SIGNED)
+ && (addr & (1 << (operand->bits - 1))))
+ addr -= 1 << operand->bits;
+
+ return addr << 2;
+}
+
+/* The only thing this does is set the `invalid' flag if B != C.
+ This is needed because the "mov" macro appears before it's real insn "and"
+ and we don't want the disassembler to confuse them. */
+
+static long
+extract_unopmacro (insn, operand, mods, opval, invalid)
+ arc_insn *insn;
+ const struct arc_operand *operand;
+ int mods;
+ const struct arc_operand_value **opval;
+ int *invalid;
+{
+ /* This misses the case where B == ARC_REG_SHIMM_UPDATE &&
+ C == ARC_REG_SHIMM (or vice versa). No big deal. Those insns will get
+ printed as "and"s. */
+ if (((insn[0] >> ARC_SHIFT_REGB) & ARC_MASK_REG)
+ != ((insn[0] >> ARC_SHIFT_REGC) & ARC_MASK_REG))
+ if (invalid != NULL)
+ *invalid = 1;
+
+ return 0;
+}
+
+/* Utility for the extraction functions to return the index into
+ `arc_suffixes'. */
+
+const struct arc_operand_value *
+arc_opcode_lookup_suffix (type, value)
+ const struct arc_operand *type;
+ int value;
+{
+ register const struct arc_operand_value *v,*end;
+
+ /* ??? This is a little slow and can be speeded up. */
+
+ for (v = arc_suffixes, end = arc_suffixes + arc_suffixes_count; v < end; ++v)
+ if (type == &arc_operands[v->type]
+ && value == v->value)
+ return v;
+ return 0;
+}
+
+static const struct arc_operand_value *
+lookup_register (type, regno)
+ int type;
+ long regno;
+{
+ register const struct arc_operand_value *r,*end;
+
+ if (type == REG)
+ return &arc_reg_names[regno];
+
+ /* ??? This is a little slow and can be speeded up. */
+
+ for (r = arc_reg_names, end = arc_reg_names + arc_reg_names_count;
+ r < end; ++r)
+ if (type == r->type && regno == r->value)
+ return r;
+ return 0;
+}
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
new file mode 100644
index 00000000000..4aabf7286bc
--- /dev/null
+++ b/opcodes/arm-dis.c
@@ -0,0 +1,887 @@
+/* Instruction printing code for the ARM
+ Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+ Modification by James G. Smith (jsmith@cygnus.co.uk)
+
+This file is part of libopcodes.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "dis-asm.h"
+#define DEFINE_TABLE
+#include "arm-opc.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+#include "opintl.h"
+
+/* FIXME: This shouldn't be done here */
+#include "elf-bfd.h"
+#include "elf/internal.h"
+#include "elf/arm.h"
+
+static char *arm_conditional[] =
+{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
+ "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
+
+static char *arm_regnames[] =
+{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc"};
+
+static char *arm_fp_const[] =
+{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
+
+static char *arm_shift[] =
+{"lsl", "lsr", "asr", "ror"};
+
+static int print_insn_arm PARAMS ((bfd_vma, struct disassemble_info *,
+ long));
+
+static void
+arm_decode_shift (given, func, stream)
+ long given;
+ fprintf_ftype func;
+ void *stream;
+{
+ func (stream, "%s", arm_regnames[given & 0xf]);
+ if ((given & 0xff0) != 0)
+ {
+ if ((given & 0x10) == 0)
+ {
+ int amount = (given & 0xf80) >> 7;
+ int shift = (given & 0x60) >> 5;
+ if (amount == 0)
+ {
+ if (shift == 3)
+ {
+ func (stream, ", rrx");
+ return;
+ }
+ amount = 32;
+ }
+ func (stream, ", %s #%d", arm_shift[shift], amount);
+ }
+ else
+ func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
+ arm_regnames[(given & 0xf00) >> 8]);
+ }
+}
+
+/* Print one instruction from PC on INFO->STREAM.
+ Return the size of the instruction (always 4 on ARM). */
+
+static int
+print_insn_arm (pc, info, given)
+ bfd_vma pc;
+ struct disassemble_info *info;
+ long given;
+{
+ struct arm_opcode * insn;
+ void * stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+
+ for (insn = arm_opcodes; insn->assembler; insn++)
+ {
+ if ((given & insn->mask) == insn->value)
+ {
+ char * c;
+
+ for (c = insn->assembler; *c; c++)
+ {
+ if (*c == '%')
+ {
+ switch (*++c)
+ {
+ case '%':
+ func (stream, "%%");
+ break;
+
+ case 'a':
+ if (((given & 0x000f0000) == 0x000f0000)
+ && ((given & 0x02000000) == 0))
+ {
+ int offset = given & 0xfff;
+
+ func (stream, "[pc");
+
+ if (given & 0x01000000)
+ {
+ if ((given & 0x00800000) == 0)
+ offset = - offset;
+
+ /* pre-indexed */
+ func (stream, ", #%x]", offset);
+
+ offset += pc + 8;
+
+ /* Cope with the possibility of write-back being used.
+ Probably a very dangerous thing for the programmer
+ to do, but who are we to argue ? */
+ if (given & 0x00200000)
+ func (stream, "!");
+ }
+ else
+ {
+ /* post indexed */
+ func (stream, "], #%x", offset);
+
+ offset = pc + 8; /* ie ignore the offset */
+ }
+
+ func (stream, "\t; ");
+ info->print_address_func (offset, info);
+ }
+ else
+ {
+ func (stream, "[%s",
+ arm_regnames[(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ if ((given & 0x02000000) == 0)
+ {
+ int offset = given & 0xfff;
+ if (offset)
+ func (stream, ", %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ }
+ else
+ {
+ func (stream, ", %s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""));
+ arm_decode_shift (given, func, stream);
+ }
+
+ func (stream, "]%s",
+ ((given & 0x00200000) != 0) ? "!" : "");
+ }
+ else
+ {
+ if ((given & 0x02000000) == 0)
+ {
+ int offset = given & 0xfff;
+ if (offset)
+ func (stream, "], %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ else
+ func (stream, "]");
+ }
+ else
+ {
+ func (stream, "], %s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""));
+ arm_decode_shift (given, func, stream);
+ }
+ }
+ }
+ break;
+
+ case 's':
+ if ((given & 0x004f0000) == 0x004f0000)
+ {
+ /* PC relative with immediate offset */
+ int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+ if ((given & 0x00800000) == 0)
+ offset = -offset;
+ (*info->print_address_func)
+ (offset + pc + 8, info);
+ }
+ else
+ {
+ func (stream, "[%s",
+ arm_regnames[(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ /* pre-indexed */
+ if ((given & 0x00400000) == 0x00400000)
+ {
+ /* immediate */
+ int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+ if (offset)
+ func (stream, ", %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ }
+ else
+ {
+ /* register */
+ func (stream, ", %s%s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""),
+ arm_regnames[given & 0xf]);
+ }
+
+ func (stream, "]%s",
+ ((given & 0x00200000) != 0) ? "!" : "");
+ }
+ else
+ {
+ /* post-indexed */
+ if ((given & 0x00400000) == 0x00400000)
+ {
+ /* immediate */
+ int offset = ((given & 0xf00) >> 4) | (given & 0xf);
+ if (offset)
+ func (stream, "], %s#%d",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""), offset);
+ else
+ func (stream, "]");
+ }
+ else
+ {
+ /* register */
+ func (stream, "], %s%s",
+ (((given & 0x00800000) == 0)
+ ? "-" : ""),
+ arm_regnames[given & 0xf]);
+ }
+ }
+ }
+ break;
+
+ case 'b':
+ (*info->print_address_func)
+ (BDISP (given) * 4 + pc + 8, info);
+ break;
+
+ case 'c':
+ func (stream, "%s",
+ arm_conditional [(given >> 28) & 0xf]);
+ break;
+
+ case 'm':
+ {
+ int started = 0;
+ int reg;
+
+ func (stream, "{");
+ for (reg = 0; reg < 16; reg++)
+ if ((given & (1 << reg)) != 0)
+ {
+ if (started)
+ func (stream, ", ");
+ started = 1;
+ func (stream, "%s", arm_regnames[reg]);
+ }
+ func (stream, "}");
+ }
+ break;
+
+ case 'o':
+ if ((given & 0x02000000) != 0)
+ {
+ int rotate = (given & 0xf00) >> 7;
+ int immed = (given & 0xff);
+ func (stream, "#%d",
+ ((immed << (32 - rotate))
+ | (immed >> rotate)) & 0xffffffff);
+ }
+ else
+ arm_decode_shift (given, func, stream);
+ break;
+
+ case 'p':
+ if ((given & 0x0000f000) == 0x0000f000)
+ func (stream, "p");
+ break;
+
+ case 't':
+ if ((given & 0x01200000) == 0x00200000)
+ func (stream, "t");
+ break;
+
+ case 'h':
+ if ((given & 0x00000020) == 0x00000020)
+ func (stream, "h");
+ else
+ func (stream, "b");
+ break;
+
+ case 'A':
+ func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
+ if ((given & 0x01000000) != 0)
+ {
+ int offset = given & 0xff;
+ if (offset)
+ func (stream, ", %s#%d]%s",
+ ((given & 0x00800000) == 0 ? "-" : ""),
+ offset * 4,
+ ((given & 0x00200000) != 0 ? "!" : ""));
+ else
+ func (stream, "]");
+ }
+ else
+ {
+ int offset = given & 0xff;
+ if (offset)
+ func (stream, "], %s#%d",
+ ((given & 0x00800000) == 0 ? "-" : ""),
+ offset * 4);
+ else
+ func (stream, "]");
+ }
+ break;
+
+ case 'C':
+ switch (given & 0x00090000)
+ {
+ default:
+ func (stream, "_???");
+ break;
+ case 0x90000:
+ func (stream, "_all");
+ break;
+ case 0x10000:
+ func (stream, "_ctl");
+ break;
+ case 0x80000:
+ func (stream, "_flg");
+ break;
+ }
+ break;
+
+ case 'F':
+ switch (given & 0x00408000)
+ {
+ case 0:
+ func (stream, "4");
+ break;
+ case 0x8000:
+ func (stream, "1");
+ break;
+ case 0x00400000:
+ func (stream, "2");
+ break;
+ default:
+ func (stream, "3");
+ }
+ break;
+
+ case 'P':
+ switch (given & 0x00080080)
+ {
+ case 0:
+ func (stream, "s");
+ break;
+ case 0x80:
+ func (stream, "d");
+ break;
+ case 0x00080000:
+ func (stream, "e");
+ break;
+ default:
+ func (stream, _("<illegal precision>"));
+ break;
+ }
+ break;
+ case 'Q':
+ switch (given & 0x00408000)
+ {
+ case 0:
+ func (stream, "s");
+ break;
+ case 0x8000:
+ func (stream, "d");
+ break;
+ case 0x00400000:
+ func (stream, "e");
+ break;
+ default:
+ func (stream, "p");
+ break;
+ }
+ break;
+ case 'R':
+ switch (given & 0x60)
+ {
+ case 0:
+ break;
+ case 0x20:
+ func (stream, "p");
+ break;
+ case 0x40:
+ func (stream, "m");
+ break;
+ default:
+ func (stream, "z");
+ break;
+ }
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ int bitstart = *c++ - '0';
+ int bitend = 0;
+ while (*c >= '0' && *c <= '9')
+ bitstart = (bitstart * 10) + *c++ - '0';
+
+ switch (*c)
+ {
+ case '-':
+ c++;
+ while (*c >= '0' && *c <= '9')
+ bitend = (bitend * 10) + *c++ - '0';
+ if (!bitend)
+ abort ();
+ switch (*c)
+ {
+ case 'r':
+ {
+ long reg;
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ func (stream, "%s", arm_regnames[reg]);
+ }
+ break;
+ case 'd':
+ {
+ long reg;
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ func (stream, "%d", reg);
+ }
+ break;
+ case 'x':
+ {
+ long reg;
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ func (stream, "0x%08x", reg);
+ }
+ break;
+ case 'f':
+ {
+ long reg;
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ if (reg > 7)
+ func (stream, "#%s",
+ arm_fp_const[reg & 7]);
+ else
+ func (stream, "f%d", reg);
+ }
+ break;
+ default:
+ abort ();
+ }
+ break;
+ case '`':
+ c++;
+ if ((given & (1 << bitstart)) == 0)
+ func (stream, "%c", *c);
+ break;
+ case '\'':
+ c++;
+ if ((given & (1 << bitstart)) != 0)
+ func (stream, "%c", *c);
+ break;
+ case '?':
+ ++c;
+ if ((given & (1 << bitstart)) != 0)
+ func (stream, "%c", *c++);
+ else
+ func (stream, "%c", *++c);
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ }
+ else
+ func (stream, "%c", *c);
+ }
+ return 4;
+ }
+ }
+ abort ();
+}
+
+/* Print one instruction from PC on INFO->STREAM.
+ Return the size of the instruction. */
+
+static int
+print_insn_thumb (pc, info, given)
+ bfd_vma pc;
+ struct disassemble_info *info;
+ long given;
+{
+ struct thumb_opcode *insn;
+ void *stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+
+ for (insn = thumb_opcodes; insn->assembler; insn++)
+ {
+ if ((given & insn->mask) == insn->value)
+ {
+ char *c = insn->assembler;
+
+ /* Special processing for Thumb 2 instruction BL sequence: */
+ if (!*c) /* check for empty (not NULL) assembler string */
+ {
+ info->bytes_per_chunk = 4;
+ info->bytes_per_line = 4;
+
+ func (stream, "%04x\tbl\t", given & 0xffff);
+ (*info->print_address_func)
+ (BDISP23 (given) * 2 + pc + 4, info);
+ return 4;
+ }
+ else
+ {
+ info->bytes_per_chunk = 2;
+ info->bytes_per_line = 4;
+
+ given &= 0xffff;
+ func (stream, "%04x\t", given);
+ for (; *c; c++)
+ {
+ if (*c == '%')
+ {
+ int domaskpc = 0;
+ int domasklr = 0;
+ switch (*++c)
+ {
+ case '%':
+ func (stream, "%%");
+ break;
+
+ case 'S':
+ {
+ long reg;
+ reg = (given >> 3) & 0x7;
+ if (given & (1 << 6))
+ reg += 8;
+ func (stream, "%s", arm_regnames[reg]);
+ }
+ break;
+
+ case 'D':
+ {
+ long reg;
+ reg = given & 0x7;
+ if (given & (1 << 7))
+ reg += 8;
+ func (stream, "%s", arm_regnames[reg]);
+ }
+ break;
+
+ case 'T':
+ func (stream, "%s",
+ arm_conditional [(given >> 8) & 0xf]);
+ break;
+
+ case 'N':
+ if (given & (1 << 8))
+ domasklr = 1;
+ /* fall through */
+ case 'O':
+ if (*c == 'O' && (given & (1 << 8)))
+ domaskpc = 1;
+ /* fall through */
+ case 'M':
+ {
+ int started = 0;
+ int reg;
+ func (stream, "{");
+ /* It would be nice if we could spot
+ ranges, and generate the rS-rE format: */
+ for (reg = 0; (reg < 8); reg++)
+ if ((given & (1 << reg)) != 0)
+ {
+ if (started)
+ func (stream, ", ");
+ started = 1;
+ func (stream, "%s", arm_regnames[reg]);
+ }
+
+ if (domasklr)
+ {
+ if (started)
+ func (stream, ", ");
+ started = 1;
+ func (stream, "lr");
+ }
+
+ if (domaskpc)
+ {
+ if (started)
+ func (stream, ", ");
+ func (stream, "pc");
+ }
+
+ func (stream, "}");
+ }
+ break;
+
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ int bitstart = *c++ - '0';
+ int bitend = 0;
+ while (*c >= '0' && *c <= '9')
+ bitstart = (bitstart * 10) + *c++ - '0';
+
+ switch (*c)
+ {
+ case '-':
+ {
+ long reg;
+ c++;
+ while (*c >= '0' && *c <= '9')
+ bitend = (bitend * 10) + *c++ - '0';
+ if (!bitend)
+ abort ();
+ reg = given >> bitstart;
+ reg &= (2 << (bitend - bitstart)) - 1;
+ switch (*c)
+ {
+ case 'r':
+ func (stream, "%s", arm_regnames[reg]);
+ break;
+
+ case 'd':
+ func (stream, "%d", reg);
+ break;
+
+ case 'H':
+ func (stream, "%d", reg << 1);
+ break;
+
+ case 'W':
+ func (stream, "%d", reg << 2);
+ break;
+
+ case 'a':
+ /* PC-relative address -- the bottom two
+ bits of the address are dropped before
+ the calculation. */
+ info->print_address_func
+ (((pc + 4) & ~3) + (reg << 2), info);
+ break;
+
+ case 'x':
+ func (stream, "0x%04x", reg);
+ break;
+
+ case 'I':
+ reg = ((reg ^ (1 << bitend)) - (1 << bitend));
+ func (stream, "%d", reg);
+ break;
+
+ case 'B':
+ reg = ((reg ^ (1 << bitend)) - (1 << bitend));
+ (*info->print_address_func)
+ (reg * 2 + pc + 4, info);
+ break;
+
+ default:
+ abort();
+ }
+ }
+ break;
+
+ case '\'':
+ c++;
+ if ((given & (1 << bitstart)) != 0)
+ func (stream, "%c", *c);
+ break;
+
+ case '?':
+ ++c;
+ if ((given & (1 << bitstart)) != 0)
+ func (stream, "%c", *c++);
+ else
+ func (stream, "%c", *++c);
+ break;
+
+ default:
+ abort();
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ else
+ func (stream, "%c", *c);
+ }
+ }
+ return 2;
+ }
+ }
+
+ /* no match */
+ abort ();
+}
+
+/* NOTE: There are no checks in these routines that the relevant number of data bytes exist */
+
+int
+print_insn_big_arm (pc, info)
+ bfd_vma pc;
+ struct disassemble_info *info;
+{
+ unsigned char b[4];
+ long given;
+ int status;
+ coff_symbol_type *cs;
+ elf_symbol_type *es;
+ int is_thumb;
+
+ is_thumb = false;
+ if (info->symbols != NULL)
+ {
+ if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
+ {
+ cs = coffsymbol (*info->symbols);
+ is_thumb = (cs->native->u.syment.n_sclass == C_THUMBEXT
+ || cs->native->u.syment.n_sclass == C_THUMBSTAT
+ || cs->native->u.syment.n_sclass == C_THUMBLABEL
+ || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
+ || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
+
+ }
+ else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
+ {
+ es = *(elf_symbol_type **)(info->symbols);
+ is_thumb = ELF_ST_TYPE (es->internal_elf_sym.st_info) ==
+ STT_ARM_TFUNC;
+ }
+ }
+
+ info->bytes_per_chunk = 4;
+ info->display_endian = BFD_ENDIAN_BIG;
+
+ /* Always fetch word aligned values. */
+
+ status = (*info->read_memory_func) (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+
+ if (is_thumb)
+ {
+ if (pc & 0x2)
+ {
+ given = (b[2] << 8) | b[3];
+
+ status = info->read_memory_func ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
+ if (status != 0)
+ {
+ info->memory_error_func (status, pc + 4, info);
+ return -1;
+ }
+
+ given |= (b[0] << 24) | (b[1] << 16);
+ }
+ else
+ {
+ given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
+ }
+ }
+ else
+ {
+ given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
+ }
+
+ if (is_thumb)
+ {
+ status = print_insn_thumb (pc, info, given);
+ }
+ else
+ {
+ status = print_insn_arm (pc, info, given);
+ }
+
+ return status;
+}
+
+int
+print_insn_little_arm (pc, info)
+ bfd_vma pc;
+ struct disassemble_info * info;
+{
+ unsigned char b[4];
+ long given;
+ int status;
+ coff_symbol_type *cs;
+ elf_symbol_type *es;
+ int is_thumb;
+
+ is_thumb = false;
+ if (info->symbols != NULL)
+ {
+ if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
+ {
+ cs = coffsymbol (*info->symbols);
+ is_thumb = (cs->native->u.syment.n_sclass == C_THUMBEXT
+ || cs->native->u.syment.n_sclass == C_THUMBSTAT
+ || cs->native->u.syment.n_sclass == C_THUMBLABEL
+ || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
+ || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
+
+ }
+ else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
+ {
+ es = *(elf_symbol_type **)(info->symbols);
+ is_thumb = ELF_ST_TYPE (es->internal_elf_sym.st_info) ==
+ STT_ARM_TFUNC;
+ }
+ }
+
+ info->bytes_per_chunk = 4;
+ info->display_endian = BFD_ENDIAN_LITTLE;
+
+ status = (*info->read_memory_func) (pc, (bfd_byte *) &b[0], 4, info);
+ if (status != 0 && is_thumb)
+ {
+ info->bytes_per_chunk = 2;
+
+ status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
+ b[3] = b[2] = 0;
+ }
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+
+ given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
+
+ if (is_thumb)
+ {
+ status = print_insn_thumb (pc, info, given);
+ }
+ else
+ {
+ status = print_insn_arm (pc, info, given);
+ }
+
+ return status;
+}
diff --git a/opcodes/arm-opc.h b/opcodes/arm-opc.h
new file mode 100644
index 00000000000..f49298fb0cd
--- /dev/null
+++ b/opcodes/arm-opc.h
@@ -0,0 +1,281 @@
+/* Opcode table for the ARM.
+
+ Copyright 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+struct arm_opcode {
+ unsigned long value, mask; /* recognise instruction if (op&mask)==value */
+ char *assembler; /* how to disassemble this instruction */
+};
+
+struct thumb_opcode
+{
+ unsigned short value, mask; /* recognise instruction if (op&mask)==value */
+ char * assembler; /* how to disassemble this instruction */
+};
+
+/* format of the assembler string :
+
+ %% %
+ %<bitfield>d print the bitfield in decimal
+ %<bitfield>x print the bitfield in hex
+ %<bitfield>r print as an ARM register
+ %<bitfield>f print a floating point constant if >7 else a
+ floating point register
+ %c print condition code (always bits 28-31)
+ %P print floating point precision in arithmetic insn
+ %Q print floating point precision in ldf/stf insn
+ %R print floating point rounding mode
+ %<bitnum>'c print specified char iff bit is one
+ %<bitnum>`c print specified char iff bit is zero
+ %<bitnum>?ab print a if bit is one else print b
+ %p print 'p' iff bits 12-15 are 15
+ %t print 't' iff bit 21 set and bit 24 clear
+ %h print 'h' iff bit 5 set, else print 'b'
+ %o print operand2 (immediate or register + shift)
+ %a print address for ldr/str instruction
+ %s print address for ldr/str halfword/signextend instruction
+ %b print branch destination
+ %A print address for ldc/stc/ldf/stf instruction
+ %m print register mask for ldm/stm instruction
+ %C print the PSR sub type.
+ %F print the COUNT field of a LFM/SFM instruction.
+Thumb specific format options:
+ %D print Thumb register (bits 0..2 as high number if bit 7 set)
+ %S print Thumb register (bits 3..5 as high number if bit 6 set)
+ %<bitfield>I print bitfield as a signed decimal
+ (top bit of range being the sign bit)
+ %M print Thumb register mask
+ %N print Thumb register mask (with LR)
+ %O print Thumb register mask (with PC)
+ %T print Thumb condition code (always bits 8-11)
+ %<bitfield>B print Thumb branch destination (signed displacement)
+ %<bitfield>W print (bitfield * 4) as a decimal
+ %<bitfield>H print (bitfield * 2) as a decimal
+ %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
+*/
+
+/* Note: There is a partial ordering in this table - it must be searched from
+ the top to obtain a correct match. */
+
+static struct arm_opcode arm_opcodes[] = {
+ /* ARM instructions */
+ {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
+ {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
+ {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
+ {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
+ {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
+ {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
+ {0x00000090, 0x0e100090, "str%c%6's%h\t%12-15r, %s"},
+ {0x00100090, 0x0e100090, "ldr%c%6's%h\t%12-15r, %s"},
+ {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
+ {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
+ {0x0120f000, 0x0db6f000, "msr%c\t%22?scpsr%C, %o"},
+ {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?scpsr"},
+ {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
+ {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
+ {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
+ {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
+ {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
+ {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
+ {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
+ {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
+ {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
+ {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
+ {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
+ {0x06000010, 0x0e000010, "undefined"},
+ {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
+ {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
+ {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
+ {0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
+ {0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
+
+ /* Floating point coprocessor instructions */
+ {0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
+ {0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
+ {0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
+ {0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
+ {0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
+ {0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
+ {0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
+ {0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
+ {0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
+ {0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
+ {0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
+ {0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
+ {0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
+ {0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
+ {0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
+ {0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
+ {0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
+ {0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
+ {0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
+ {0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
+ {0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
+ {0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
+ {0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
+ {0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
+ {0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
+ {0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
+ {0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
+ {0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
+ {0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
+ {0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
+ {0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
+
+ /* Generic coprocessor instructions */
+ {0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
+ {0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
+ {0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
+ /* the rest */
+ {0x00000000, 0x00000000, "undefined instruction %0-31x"},
+ {0x00000000, 0x00000000, 0}
+};
+
+#define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */
+
+static struct thumb_opcode thumb_opcodes[] =
+{
+ /* Thumb instructions */
+ {0x46C0, 0xFFFF, "nop\t\t\t(mov r8,r8)"}, /* format 5 instructions do not update the PSR */
+ {0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
+ /* format 4 */
+ {0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
+ {0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
+ {0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
+ {0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
+ {0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
+ {0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
+ {0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
+ {0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
+ {0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
+ {0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
+ {0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
+ {0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
+ {0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
+ {0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
+ {0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
+ {0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
+ /* format 13 */
+ {0xB000, 0xFF80, "add\tsp, #%0-6W"},
+ {0xB080, 0xFF80, "sub\tsp, #%0-6W"},
+ /* format 5 */
+ {0x4700, 0xFF80, "bx\t%S"},
+ {0x4400, 0xFF00, "add\t%D, %S"},
+ {0x4500, 0xFF00, "cmp\t%D, %S"},
+ {0x4600, 0xFF00, "mov\t%D, %S"},
+ /* format 14 */
+ {0xB400, 0xFE00, "push\t%N"},
+ {0xBC00, 0xFE00, "pop\t%O"},
+ /* format 2 */
+ {0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
+ {0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
+ {0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
+ {0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
+ /* format 8 */
+ {0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
+ {0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
+ {0x5600, 0xF600, "lds%11?hb\t%0-2r, [%3-5r, %6-8r]"},
+ /* format 7 */
+ {0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
+ {0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
+ /* format 1 */
+ {0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
+ {0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
+ {0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
+ /* format 3 */
+ {0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
+ {0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
+ {0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
+ {0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
+ /* format 6 */
+ {0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
+ /* format 9 */
+ {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
+ {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
+ {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
+ {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
+ /* format 10 */
+ {0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
+ {0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
+ /* format 11 */
+ {0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
+ {0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
+ /* format 12 */
+ {0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
+ {0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
+ /* format 15 */
+ {0xC000, 0xF800, "stmia\t%8-10r!,%M"},
+ {0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
+ /* format 18 */
+ {0xE000, 0xF800, "b\t%0-10B"},
+ {0xE800, 0xF800, "undefined"},
+ /* format 19 */
+ {0xF000, 0xF800, ""}, /* special processing required in disassembler */
+ {0xF800, 0xF800, "second half of BL instruction %0-15x"},
+ /* format 16 */
+ {0xD000, 0xFF00, "beq\t%0-7B"},
+ {0xD100, 0xFF00, "bne\t%0-7B"},
+ {0xD200, 0xFF00, "bcs\t%0-7B"},
+ {0xD300, 0xFF00, "bcc\t%0-7B"},
+ {0xD400, 0xFF00, "bmi\t%0-7B"},
+ {0xD500, 0xFF00, "bpl\t%0-7B"},
+ {0xD600, 0xFF00, "bvs\t%0-7B"},
+ {0xD700, 0xFF00, "bvc\t%0-7B"},
+ {0xD800, 0xFF00, "bhi\t%0-7B"},
+ {0xD900, 0xFF00, "bls\t%0-7B"},
+ {0xDA00, 0xFF00, "bge\t%0-7B"},
+ {0xDB00, 0xFF00, "blt\t%0-7B"},
+ {0xDC00, 0xFF00, "bgt\t%0-7B"},
+ {0xDD00, 0xFF00, "ble\t%0-7B"},
+ /* format 17 */
+ {0xDE00, 0xFF00, "undefined"},
+ {0xDF00, 0xFF00, "swi\t%0-7d"},
+ /* format 9 */
+ {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
+ {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
+ {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
+ {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
+ /* the rest */
+ {0x0000, 0x0000, "undefined instruction %0-15x"},
+ {0x0000, 0x0000, 0}
+};
+
+#define BDISP23(x) ((((((x) & 0x07ff) << 11) | (((x) & 0x07ff0000) >> 16)) \
+ ^ 0x200000) - 0x200000) /* 23bit */
+
diff --git a/opcodes/cgen-asm.c b/opcodes/cgen-asm.c
new file mode 100644
index 00000000000..4ed69363a9d
--- /dev/null
+++ b/opcodes/cgen-asm.c
@@ -0,0 +1,359 @@
+/* CGEN generic assembler support code.
+
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+ 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, 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.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include <stdio.h>
+#include <ctype.h>
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "opcode/cgen.h"
+#include "opintl.h"
+
+/* Set the cgen_parse_operand_fn callback. */
+
+void
+cgen_set_parse_operand_fn (cd, fn)
+ CGEN_CPU_DESC cd;
+ cgen_parse_operand_fn fn;
+{
+ cd->parse_operand_fn = fn;
+}
+
+/* Called whenever starting to parse an insn. */
+
+void
+cgen_init_parse_operand (cd)
+ CGEN_CPU_DESC cd;
+{
+ /* This tells the callback to re-initialize. */
+ (void) (* cd->parse_operand_fn)
+ (cd, CGEN_PARSE_OPERAND_INIT, NULL, 0, 0, NULL, NULL);
+}
+
+/* Subroutine of build_asm_hash_table to add INSNS to the hash table.
+
+ COUNT is the number of elements in INSNS.
+ ENTSIZE is sizeof (CGEN_IBASE) for the target.
+ ??? No longer used but leave in for now.
+ HTABLE points to the hash table.
+ HENTBUF is a pointer to sufficiently large buffer of hash entries.
+ The result is a pointer to the next entry to use.
+
+ The table is scanned backwards as additions are made to the front of the
+ list and we want earlier ones to be prefered. */
+
+static CGEN_INSN_LIST *
+hash_insn_array (cd, insns, count, entsize, htable, hentbuf)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insns;
+ int count;
+ int entsize;
+ CGEN_INSN_LIST **htable;
+ CGEN_INSN_LIST *hentbuf;
+{
+ int i;
+
+ for (i = count - 1; i >= 0; --i, ++hentbuf)
+ {
+ unsigned int hash;
+ const CGEN_INSN *insn = &insns[i];
+
+ if (! (* cd->asm_hash_p) (insn))
+ continue;
+ hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (insn));
+ hentbuf->next = htable[hash];
+ hentbuf->insn = insn;
+ htable[hash] = hentbuf;
+ }
+
+ return hentbuf;
+}
+
+/* Subroutine of build_asm_hash_table to add INSNS to the hash table.
+ This function is identical to hash_insn_array except the insns are
+ in a list. */
+
+static CGEN_INSN_LIST *
+hash_insn_list (cd, insns, htable, hentbuf)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN_LIST *insns;
+ CGEN_INSN_LIST **htable;
+ CGEN_INSN_LIST *hentbuf;
+{
+ const CGEN_INSN_LIST *ilist;
+
+ for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
+ {
+ unsigned int hash;
+
+ if (! (* cd->asm_hash_p) (ilist->insn))
+ continue;
+ hash = (* cd->asm_hash) (CGEN_INSN_MNEMONIC (ilist->insn));
+ hentbuf->next = htable[hash];
+ hentbuf->insn = ilist->insn;
+ htable[hash] = hentbuf;
+ }
+
+ return hentbuf;
+}
+
+/* Build the assembler instruction hash table. */
+
+static void
+build_asm_hash_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
+ CGEN_INSN_TABLE *insn_table = &cd->insn_table;
+ CGEN_INSN_TABLE *macro_insn_table = &cd->macro_insn_table;
+ unsigned int hash_size = cd->asm_hash_size;
+ CGEN_INSN_LIST *hash_entry_buf;
+ CGEN_INSN_LIST **asm_hash_table;
+ CGEN_INSN_LIST *asm_hash_table_entries;
+
+ /* The space allocated for the hash table consists of two parts:
+ the hash table and the hash lists. */
+
+ asm_hash_table = (CGEN_INSN_LIST **)
+ xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
+ memset (asm_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
+ asm_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
+ xmalloc (count * sizeof (CGEN_INSN_LIST));
+
+ /* Add compiled in insns.
+ Don't include the first one as it is a reserved entry. */
+ /* ??? It was the end of all hash chains, and also the special
+ "invalid insn" marker. May be able to do it differently now. */
+
+ hash_entry_buf = hash_insn_array (cd,
+ insn_table->init_entries + 1,
+ insn_table->num_init_entries - 1,
+ insn_table->entry_size,
+ asm_hash_table, hash_entry_buf);
+
+ /* Add compiled in macro-insns. */
+
+ hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
+ macro_insn_table->num_init_entries,
+ macro_insn_table->entry_size,
+ asm_hash_table, hash_entry_buf);
+
+ /* Add runtime added insns.
+ Later added insns will be prefered over earlier ones. */
+
+ hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
+ asm_hash_table, hash_entry_buf);
+
+ /* Add runtime added macro-insns. */
+
+ hash_insn_list (cd, macro_insn_table->new_entries,
+ asm_hash_table, hash_entry_buf);
+
+ cd->asm_hash_table = asm_hash_table;
+ cd->asm_hash_table_entries = asm_hash_table_entries;
+}
+
+/* Return the first entry in the hash list for INSN. */
+
+CGEN_INSN_LIST *
+cgen_asm_lookup_insn (cd, insn)
+ CGEN_CPU_DESC cd;
+ const char *insn;
+{
+ unsigned int hash;
+
+ if (cd->asm_hash_table == NULL)
+ build_asm_hash_table (cd);
+
+ hash = (* cd->asm_hash) (insn);
+ return cd->asm_hash_table[hash];
+}
+
+/* Keyword parser.
+ The result is NULL upon success or an error message.
+ If successful, *STRP is updated to point passed the keyword.
+
+ ??? At present we have a static notion of how to pick out a keyword.
+ Later we can allow a target to customize this if necessary [say by
+ recording something in the keyword table]. */
+
+const char *
+cgen_parse_keyword (cd, strp, keyword_table, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ CGEN_KEYWORD *keyword_table;
+ long *valuep;
+{
+ const CGEN_KEYWORD_ENTRY *ke;
+ char buf[256];
+ const char *p,*start;
+
+ p = start = *strp;
+
+ /* Allow any first character.
+ Note that this allows recognizing ",a" for the annul flag in sparc
+ even though "," is subsequently not a valid keyword char. */
+ if (*p)
+ ++p;
+
+ /* Now allow letters, digits, and _. */
+ while (((p - start) < (int) sizeof (buf))
+ && (isalnum ((unsigned char) *p) || *p == '_'))
+ ++p;
+
+ if (p - start >= (int) sizeof (buf))
+ return _("unrecognized keyword/register name");
+
+ memcpy (buf, start, p - start);
+ buf[p - start] = 0;
+
+ ke = cgen_keyword_lookup_name (keyword_table, buf);
+
+ if (ke != NULL)
+ {
+ *valuep = ke->value;
+ /* Don't advance pointer if we recognized the null keyword. */
+ if (ke->name[0] != 0)
+ *strp = p;
+ return NULL;
+ }
+
+ return "unrecognized keyword/register name";
+}
+
+/* Parse a small signed integer parser.
+ ??? VALUEP is not a bfd_vma * on purpose, though this is confusing.
+ Note that if the caller expects a bfd_vma result, it should call
+ cgen_parse_address. */
+
+const char *
+cgen_parse_signed_integer (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ long *valuep;
+{
+ bfd_vma value;
+ enum cgen_parse_operand_result result;
+ const char *errmsg;
+
+ errmsg = (* cd->parse_operand_fn)
+ (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
+ &result, &value);
+ /* FIXME: Examine `result'. */
+ if (!errmsg)
+ *valuep = value;
+ return errmsg;
+}
+
+/* Parse a small unsigned integer parser.
+ ??? VALUEP is not a bfd_vma * on purpose, though this is confusing.
+ Note that if the caller expects a bfd_vma result, it should call
+ cgen_parse_address. */
+
+const char *
+cgen_parse_unsigned_integer (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ bfd_vma value;
+ enum cgen_parse_operand_result result;
+ const char *errmsg;
+
+ errmsg = (* cd->parse_operand_fn)
+ (cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE,
+ &result, &value);
+ /* FIXME: Examine `result'. */
+ if (!errmsg)
+ *valuep = value;
+ return errmsg;
+}
+
+/* Address parser. */
+
+const char *
+cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ int opinfo;
+ enum cgen_parse_operand_result *resultp;
+ bfd_vma *valuep;
+{
+ bfd_vma value;
+ enum cgen_parse_operand_result result_type;
+ const char *errmsg;
+
+ errmsg = (* cd->parse_operand_fn)
+ (cd, CGEN_PARSE_OPERAND_ADDRESS, strp, opindex, opinfo,
+ &result_type, &value);
+ /* FIXME: Examine `result'. */
+ if (!errmsg)
+ {
+ if (resultp != NULL)
+ *resultp = result_type;
+ *valuep = value;
+ }
+ return errmsg;
+}
+
+/* Signed integer validation routine. */
+
+const char *
+cgen_validate_signed_integer (value, min, max)
+ long value, min, max;
+{
+ if (value < min || value > max)
+ {
+ static char buf[100];
+
+ /* xgettext:c-format */
+ sprintf (buf, _("operand out of range (%ld not between %ld and %ld)"),
+ value, min, max);
+ return buf;
+ }
+
+ return NULL;
+}
+
+/* Unsigned integer validation routine.
+ Supplying `min' here may seem unnecessary, but we also want to handle
+ cases where min != 0 (and max > LONG_MAX). */
+
+const char *
+cgen_validate_unsigned_integer (value, min, max)
+ unsigned long value, min, max;
+{
+ if (value < min || value > max)
+ {
+ static char buf[100];
+
+ /* xgettext:c-format */
+ sprintf (buf, _("operand out of range (%lu not between %lu and %lu)"),
+ value, min, max);
+ return buf;
+ }
+
+ return NULL;
+}
diff --git a/opcodes/cgen-dis.c b/opcodes/cgen-dis.c
new file mode 100644
index 00000000000..78b1cd90ed9
--- /dev/null
+++ b/opcodes/cgen-dis.c
@@ -0,0 +1,226 @@
+/* CGEN generic disassembler support code.
+
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+ 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, 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.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include <stdio.h>
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "opcode/cgen.h"
+
+/* Subroutine of build_dis_hash_table to add INSNS to the hash table.
+
+ COUNT is the number of elements in INSNS.
+ ENTSIZE is sizeof (CGEN_IBASE) for the target.
+ ??? No longer used but leave in for now.
+ HTABLE points to the hash table.
+ HENTBUF is a pointer to sufficiently large buffer of hash entries.
+ The result is a pointer to the next entry to use.
+
+ The table is scanned backwards as additions are made to the front of the
+ list and we want earlier ones to be prefered. */
+
+static CGEN_INSN_LIST *
+hash_insn_array (cd, insns, count, entsize, htable, hentbuf)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN * insns;
+ int count;
+ int entsize;
+ CGEN_INSN_LIST ** htable;
+ CGEN_INSN_LIST * hentbuf;
+{
+ int big_p = CGEN_CPU_ENDIAN (cd) == CGEN_ENDIAN_BIG;
+ int i;
+
+ for (i = count - 1; i >= 0; --i, ++hentbuf)
+ {
+ unsigned int hash;
+ char buf [4];
+ unsigned long value;
+ const CGEN_INSN *insn = &insns[i];
+
+ if (! (* cd->dis_hash_p) (insn))
+ continue;
+
+ /* We don't know whether the target uses the buffer or the base insn
+ to hash on, so set both up. */
+
+ value = CGEN_INSN_BASE_VALUE (insn);
+ switch (CGEN_INSN_MASK_BITSIZE (insn))
+ {
+ case 8:
+ buf[0] = value;
+ break;
+ case 16:
+ if (big_p)
+ bfd_putb16 ((bfd_vma) value, buf);
+ else
+ bfd_putl16 ((bfd_vma) value, buf);
+ break;
+ case 32:
+ if (big_p)
+ bfd_putb32 ((bfd_vma) value, buf);
+ else
+ bfd_putl32 ((bfd_vma) value, buf);
+ break;
+ default:
+ abort ();
+ }
+
+ hash = (* cd->dis_hash) (buf, value);
+ hentbuf->next = htable[hash];
+ hentbuf->insn = insn;
+ htable[hash] = hentbuf;
+ }
+
+ return hentbuf;
+}
+
+/* Subroutine of build_dis_hash_table to add INSNS to the hash table.
+ This function is identical to hash_insn_array except the insns are
+ in a list. */
+
+static CGEN_INSN_LIST *
+hash_insn_list (cd, insns, htable, hentbuf)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN_LIST *insns;
+ CGEN_INSN_LIST **htable;
+ CGEN_INSN_LIST *hentbuf;
+{
+ int big_p = CGEN_CPU_ENDIAN (cd) == CGEN_ENDIAN_BIG;
+ const CGEN_INSN_LIST *ilist;
+
+ for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
+ {
+ unsigned int hash;
+ char buf[4];
+ unsigned long value;
+
+ if (! (* cd->dis_hash_p) (ilist->insn))
+ continue;
+
+ /* We don't know whether the target uses the buffer or the base insn
+ to hash on, so set both up. */
+
+ value = CGEN_INSN_BASE_VALUE (ilist->insn);
+ switch (CGEN_INSN_MASK_BITSIZE (ilist->insn))
+ {
+ case 8:
+ buf[0] = value;
+ break;
+ case 16:
+ if (big_p)
+ bfd_putb16 ((bfd_vma) value, buf);
+ else
+ bfd_putl16 ((bfd_vma) value, buf);
+ break;
+ case 32:
+ if (big_p)
+ bfd_putb32 ((bfd_vma) value, buf);
+ else
+ bfd_putl32 ((bfd_vma) value, buf);
+ break;
+ default:
+ abort ();
+ }
+
+ hash = (* cd->dis_hash) (buf, value);
+ hentbuf->next = htable [hash];
+ hentbuf->insn = ilist->insn;
+ htable [hash] = hentbuf;
+ }
+
+ return hentbuf;
+}
+
+/* Build the disassembler instruction hash table. */
+
+static void
+build_dis_hash_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ int count = cgen_insn_count (cd) + cgen_macro_insn_count (cd);
+ CGEN_INSN_TABLE *insn_table = & cd->insn_table;
+ CGEN_INSN_TABLE *macro_insn_table = & cd->macro_insn_table;
+ unsigned int hash_size = cd->dis_hash_size;
+ CGEN_INSN_LIST *hash_entry_buf;
+ CGEN_INSN_LIST **dis_hash_table;
+ CGEN_INSN_LIST *dis_hash_table_entries;
+
+ /* The space allocated for the hash table consists of two parts:
+ the hash table and the hash lists. */
+
+ dis_hash_table = (CGEN_INSN_LIST **)
+ xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
+ memset (dis_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
+ dis_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
+ xmalloc (count * sizeof (CGEN_INSN_LIST));
+
+ /* Add compiled in insns.
+ Don't include the first one as it is a reserved entry. */
+ /* ??? It was the end of all hash chains, and also the special
+ "invalid insn" marker. May be able to do it differently now. */
+
+ hash_entry_buf = hash_insn_array (cd,
+ insn_table->init_entries + 1,
+ insn_table->num_init_entries - 1,
+ insn_table->entry_size,
+ dis_hash_table, hash_entry_buf);
+
+ /* Add compiled in macro-insns. */
+
+ hash_entry_buf = hash_insn_array (cd, macro_insn_table->init_entries,
+ macro_insn_table->num_init_entries,
+ macro_insn_table->entry_size,
+ dis_hash_table, hash_entry_buf);
+
+ /* Add runtime added insns.
+ Later added insns will be prefered over earlier ones. */
+
+ hash_entry_buf = hash_insn_list (cd, insn_table->new_entries,
+ dis_hash_table, hash_entry_buf);
+
+ /* Add runtime added macro-insns. */
+
+ hash_insn_list (cd, macro_insn_table->new_entries,
+ dis_hash_table, hash_entry_buf);
+
+ cd->dis_hash_table = dis_hash_table;
+ cd->dis_hash_table_entries = dis_hash_table_entries;
+}
+
+/* Return the first entry in the hash list for INSN. */
+
+CGEN_INSN_LIST *
+cgen_dis_lookup_insn (cd, buf, value)
+ CGEN_CPU_DESC cd;
+ const char * buf;
+ CGEN_INSN_INT value;
+{
+ unsigned int hash;
+
+ if (cd->dis_hash_table == NULL)
+ build_dis_hash_table (cd);
+
+ hash = (* cd->dis_hash) (buf, value);
+
+ return cd->dis_hash_table[hash];
+}
diff --git a/opcodes/cgen-opc.c b/opcodes/cgen-opc.c
new file mode 100644
index 00000000000..56840a6a6f9
--- /dev/null
+++ b/opcodes/cgen-opc.c
@@ -0,0 +1,597 @@
+/* CGEN generic opcode support.
+
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+ 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, 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.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "opcode/cgen.h"
+
+static unsigned int hash_keyword_name
+ PARAMS ((const CGEN_KEYWORD *, const char *, int));
+static unsigned int hash_keyword_value
+ PARAMS ((const CGEN_KEYWORD *, unsigned int));
+static void build_keyword_hash_tables
+ PARAMS ((CGEN_KEYWORD *));
+
+/* Return number of hash table entries to use for N elements. */
+#define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
+
+/* Look up *NAMEP in the keyword table KT.
+ The result is the keyword entry or NULL if not found. */
+
+const CGEN_KEYWORD_ENTRY *
+cgen_keyword_lookup_name (kt, name)
+ CGEN_KEYWORD *kt;
+ const char *name;
+{
+ const CGEN_KEYWORD_ENTRY *ke;
+ const char *p,*n;
+
+ if (kt->name_hash_table == NULL)
+ build_keyword_hash_tables (kt);
+
+ ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];
+
+ /* We do case insensitive comparisons.
+ If that ever becomes a problem, add an attribute that denotes
+ "do case sensitive comparisons". */
+
+ while (ke != NULL)
+ {
+ n = name;
+ p = ke->name;
+
+ while (*p
+ && (*p == *n
+ || (isalpha ((unsigned char) *p)
+ && (tolower ((unsigned char) *p)
+ == tolower ((unsigned char) *n)))))
+ ++n, ++p;
+
+ if (!*p && !*n)
+ return ke;
+
+ ke = ke->next_name;
+ }
+
+ if (kt->null_entry)
+ return kt->null_entry;
+ return NULL;
+}
+
+/* Look up VALUE in the keyword table KT.
+ The result is the keyword entry or NULL if not found. */
+
+const CGEN_KEYWORD_ENTRY *
+cgen_keyword_lookup_value (kt, value)
+ CGEN_KEYWORD *kt;
+ int value;
+{
+ const CGEN_KEYWORD_ENTRY *ke;
+
+ if (kt->name_hash_table == NULL)
+ build_keyword_hash_tables (kt);
+
+ ke = kt->value_hash_table[hash_keyword_value (kt, value)];
+
+ while (ke != NULL)
+ {
+ if (value == ke->value)
+ return ke;
+ ke = ke->next_value;
+ }
+
+ return NULL;
+}
+
+/* Add an entry to a keyword table. */
+
+void
+cgen_keyword_add (kt, ke)
+ CGEN_KEYWORD *kt;
+ CGEN_KEYWORD_ENTRY *ke;
+{
+ unsigned int hash;
+
+ if (kt->name_hash_table == NULL)
+ build_keyword_hash_tables (kt);
+
+ hash = hash_keyword_name (kt, ke->name, 0);
+ ke->next_name = kt->name_hash_table[hash];
+ kt->name_hash_table[hash] = ke;
+
+ hash = hash_keyword_value (kt, ke->value);
+ ke->next_value = kt->value_hash_table[hash];
+ kt->value_hash_table[hash] = ke;
+
+ if (ke->name[0] == 0)
+ kt->null_entry = ke;
+}
+
+/* FIXME: Need function to return count of keywords. */
+
+/* Initialize a keyword table search.
+ SPEC is a specification of what to search for.
+ A value of NULL means to find every keyword.
+ Currently NULL is the only acceptable value [further specification
+ deferred].
+ The result is an opaque data item used to record the search status.
+ It is passed to each call to cgen_keyword_search_next. */
+
+CGEN_KEYWORD_SEARCH
+cgen_keyword_search_init (kt, spec)
+ CGEN_KEYWORD *kt;
+ const char *spec;
+{
+ CGEN_KEYWORD_SEARCH search;
+
+ /* FIXME: Need to specify format of PARAMS. */
+ if (spec != NULL)
+ abort ();
+
+ if (kt->name_hash_table == NULL)
+ build_keyword_hash_tables (kt);
+
+ search.table = kt;
+ search.spec = spec;
+ search.current_hash = 0;
+ search.current_entry = NULL;
+ return search;
+}
+
+/* Return the next keyword specified by SEARCH.
+ The result is the next entry or NULL if there are no more. */
+
+const CGEN_KEYWORD_ENTRY *
+cgen_keyword_search_next (search)
+ CGEN_KEYWORD_SEARCH *search;
+{
+ /* Has search finished? */
+ if (search->current_hash == search->table->hash_table_size)
+ return NULL;
+
+ /* Search in progress? */
+ if (search->current_entry != NULL
+ /* Anything left on this hash chain? */
+ && search->current_entry->next_name != NULL)
+ {
+ search->current_entry = search->current_entry->next_name;
+ return search->current_entry;
+ }
+
+ /* Move to next hash chain [unless we haven't started yet]. */
+ if (search->current_entry != NULL)
+ ++search->current_hash;
+
+ while (search->current_hash < search->table->hash_table_size)
+ {
+ search->current_entry = search->table->name_hash_table[search->current_hash];
+ if (search->current_entry != NULL)
+ return search->current_entry;
+ ++search->current_hash;
+ }
+
+ return NULL;
+}
+
+/* Return first entry in hash chain for NAME.
+ If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
+
+static unsigned int
+hash_keyword_name (kt, name, case_sensitive_p)
+ const CGEN_KEYWORD *kt;
+ const char *name;
+ int case_sensitive_p;
+{
+ unsigned int hash;
+
+ if (case_sensitive_p)
+ for (hash = 0; *name; ++name)
+ hash = (hash * 97) + (unsigned char) *name;
+ else
+ for (hash = 0; *name; ++name)
+ hash = (hash * 97) + (unsigned char) tolower (*name);
+ return hash % kt->hash_table_size;
+}
+
+/* Return first entry in hash chain for VALUE. */
+
+static unsigned int
+hash_keyword_value (kt, value)
+ const CGEN_KEYWORD *kt;
+ unsigned int value;
+{
+ return value % kt->hash_table_size;
+}
+
+/* Build a keyword table's hash tables.
+ We probably needn't build the value hash table for the assembler when
+ we're using the disassembler, but we keep things simple. */
+
+static void
+build_keyword_hash_tables (kt)
+ CGEN_KEYWORD *kt;
+{
+ int i;
+ /* Use the number of compiled in entries as an estimate for the
+ typical sized table [not too many added at runtime]. */
+ unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);
+
+ kt->hash_table_size = size;
+ kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
+ xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
+ memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
+ kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
+ xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
+ memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
+
+ /* The table is scanned backwards as we want keywords appearing earlier to
+ be prefered over later ones. */
+ for (i = kt->num_init_entries - 1; i >= 0; --i)
+ cgen_keyword_add (kt, &kt->init_entries[i]);
+}
+
+/* Hardware support. */
+
+/* Lookup a hardware element by its name.
+ Returns NULL if NAME is not supported by the currently selected
+ mach/isa. */
+
+const CGEN_HW_ENTRY *
+cgen_hw_lookup_by_name (cd, name)
+ CGEN_CPU_DESC cd;
+ const char *name;
+{
+ int i;
+ const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
+
+ for (i = 0; i < cd->hw_table.num_entries; ++i)
+ if (hw[i] && strcmp (name, hw[i]->name) == 0)
+ return hw[i];
+
+ return NULL;
+}
+
+/* Lookup a hardware element by its number.
+ Hardware elements are enumerated, however it may be possible to add some
+ at runtime, thus HWNUM is not an enum type but rather an int.
+ Returns NULL if HWNUM is not supported by the currently selected mach. */
+
+const CGEN_HW_ENTRY *
+cgen_hw_lookup_by_num (cd, hwnum)
+ CGEN_CPU_DESC cd;
+ int hwnum;
+{
+ int i;
+ const CGEN_HW_ENTRY **hw = cd->hw_table.entries;
+
+ /* ??? This can be speeded up. */
+ for (i = 0; i < cd->hw_table.num_entries; ++i)
+ if (hw[i] && hwnum == hw[i]->type)
+ return hw[i];
+
+ return NULL;
+}
+
+/* Operand support. */
+
+/* Lookup an operand by its name.
+ Returns NULL if NAME is not supported by the currently selected
+ mach/isa. */
+
+const CGEN_OPERAND *
+cgen_operand_lookup_by_name (cd, name)
+ CGEN_CPU_DESC cd;
+ const char *name;
+{
+ int i;
+ const CGEN_OPERAND **op = cd->operand_table.entries;
+
+ for (i = 0; i < cd->operand_table.num_entries; ++i)
+ if (op[i] && strcmp (name, op[i]->name) == 0)
+ return op[i];
+
+ return NULL;
+}
+
+/* Lookup an operand by its number.
+ Operands are enumerated, however it may be possible to add some
+ at runtime, thus OPNUM is not an enum type but rather an int.
+ Returns NULL if OPNUM is not supported by the currently selected
+ mach/isa. */
+
+const CGEN_OPERAND *
+cgen_operand_lookup_by_num (cd, opnum)
+ CGEN_CPU_DESC cd;
+ int opnum;
+{
+ return cd->operand_table.entries[opnum];
+}
+
+/* Instruction support. */
+
+/* Return number of instructions. This includes any added at runtime. */
+
+int
+cgen_insn_count (cd)
+ CGEN_CPU_DESC cd;
+{
+ int count = cd->insn_table.num_init_entries;
+ CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;
+
+ for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
+ ++count;
+
+ return count;
+}
+
+/* Return number of macro-instructions.
+ This includes any added at runtime. */
+
+int
+cgen_macro_insn_count (cd)
+ CGEN_CPU_DESC cd;
+{
+ int count = cd->macro_insn_table.num_init_entries;
+ CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;
+
+ for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
+ ++count;
+
+ return count;
+}
+
+/* Cover function to read and properly byteswap an insn value. */
+
+CGEN_INSN_INT
+cgen_get_insn_value (cd, buf, length)
+ CGEN_CPU_DESC cd;
+ unsigned char *buf;
+ int length;
+{
+ CGEN_INSN_INT value;
+
+ switch (length)
+ {
+ case 8:
+ value = *buf;
+ break;
+ case 16:
+ if (cd->insn_endian == CGEN_ENDIAN_BIG)
+ value = bfd_getb16 (buf);
+ else
+ value = bfd_getl16 (buf);
+ break;
+ case 32:
+ if (cd->insn_endian == CGEN_ENDIAN_BIG)
+ value = bfd_getb32 (buf);
+ else
+ value = bfd_getl32 (buf);
+ break;
+ default:
+ abort ();
+ }
+
+ return value;
+}
+
+/* Cover function to store an insn value properly byteswapped. */
+
+void
+cgen_put_insn_value (cd, buf, length, value)
+ CGEN_CPU_DESC cd;
+ unsigned char *buf;
+ int length;
+ CGEN_INSN_INT value;
+{
+ switch (length)
+ {
+ case 8:
+ buf[0] = value;
+ break;
+ case 16:
+ if (cd->insn_endian == CGEN_ENDIAN_BIG)
+ bfd_putb16 (value, buf);
+ else
+ bfd_putl16 (value, buf);
+ break;
+ case 32:
+ if (cd->insn_endian == CGEN_ENDIAN_BIG)
+ bfd_putb32 (value, buf);
+ else
+ bfd_putl32 (value, buf);
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Look up instruction INSN_*_VALUE and extract its fields.
+ INSN_INT_VALUE is used if CGEN_INT_INSN_P.
+ Otherwise INSN_BYTES_VALUE is used.
+ INSN, if non-null, is the insn table entry.
+ Otherwise INSN_*_VALUE is examined to compute it.
+ LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
+ 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
+ If INSN != NULL, LENGTH must be valid.
+ ALIAS_P is non-zero if alias insns are to be included in the search.
+
+ The result is a pointer to the insn table entry, or NULL if the instruction
+ wasn't recognized. */
+
+/* ??? Will need to be revisited for VLIW architectures. */
+
+const CGEN_INSN *
+cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, length, fields,
+ alias_p)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ CGEN_INSN_INT insn_int_value;
+ /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
+ unsigned char *insn_bytes_value;
+ int length;
+ CGEN_FIELDS *fields;
+ int alias_p;
+{
+ unsigned char *buf;
+ CGEN_INSN_INT base_insn;
+ CGEN_EXTRACT_INFO ex_info;
+ CGEN_EXTRACT_INFO *info;
+
+ if (cd->int_insn_p)
+ {
+ info = NULL;
+ buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
+ cgen_put_insn_value (cd, buf, length, insn_int_value);
+ base_insn = insn_int_value;
+ }
+ else
+ {
+ info = &ex_info;
+ ex_info.dis_info = NULL;
+ ex_info.insn_bytes = insn_bytes_value;
+ ex_info.valid = -1;
+ buf = insn_bytes_value;
+ base_insn = cgen_get_insn_value (cd, buf, length);
+ }
+
+ if (!insn)
+ {
+ const CGEN_INSN_LIST *insn_list;
+
+ /* The instructions are stored in hash lists.
+ Pick the first one and keep trying until we find the right one. */
+
+ insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
+ while (insn_list != NULL)
+ {
+ insn = insn_list->insn;
+
+ if (alias_p
+ /* FIXME: Ensure ALIAS attribute always has same index. */
+ || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
+ {
+ /* Basic bit mask must be correct. */
+ /* ??? May wish to allow target to defer this check until the
+ extract handler. */
+ if ((base_insn & CGEN_INSN_BASE_MASK (insn))
+ == CGEN_INSN_BASE_VALUE (insn))
+ {
+ /* ??? 0 is passed for `pc' */
+ int elength = CGEN_EXTRACT_FN (cd, insn)
+ (cd, insn, info, base_insn, fields, (bfd_vma) 0);
+ if (elength > 0)
+ {
+ /* sanity check */
+ if (length != 0 && length != elength)
+ abort ();
+ return insn;
+ }
+ }
+ }
+
+ insn_list = insn_list->next;
+ }
+ }
+ else
+ {
+ /* Sanity check: can't pass an alias insn if ! alias_p. */
+ if (! alias_p
+ && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
+ abort ();
+ /* Sanity check: length must be correct. */
+ if (length != CGEN_INSN_BITSIZE (insn))
+ abort ();
+
+ /* ??? 0 is passed for `pc' */
+ length = CGEN_EXTRACT_FN (cd, insn)
+ (cd, insn, info, base_insn, fields, (bfd_vma) 0);
+ /* Sanity check: must succeed.
+ Could relax this later if it ever proves useful. */
+ if (length == 0)
+ abort ();
+ return insn;
+ }
+
+ return NULL;
+}
+
+/* Fill in the operand instances used by INSN whose operands are FIELDS.
+ INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
+ in. */
+
+void
+cgen_get_insn_operands (cd, insn, fields, indices)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ const CGEN_FIELDS *fields;
+ int *indices;
+{
+ const CGEN_OPINST *opinst;
+ int i;
+
+ if (insn->opinst == NULL)
+ abort ();
+ for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
+ {
+ enum cgen_operand_type op_type = opinst->op_type;
+ if (op_type == CGEN_OPERAND_NIL)
+ indices[i] = opinst->index;
+ else
+ indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
+ }
+}
+
+/* Cover function to cgen_get_insn_operands when either INSN or FIELDS
+ isn't known.
+ The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
+ cgen_lookup_insn unchanged.
+ INSN_INT_VALUE is used if CGEN_INT_INSN_P.
+ Otherwise INSN_BYTES_VALUE is used.
+
+ The result is the insn table entry or NULL if the instruction wasn't
+ recognized. */
+
+const CGEN_INSN *
+cgen_lookup_get_insn_operands (cd, insn, insn_int_value, insn_bytes_value,
+ length, indices, fields)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ CGEN_INSN_INT insn_int_value;
+ /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
+ unsigned char *insn_bytes_value;
+ int length;
+ int *indices;
+ CGEN_FIELDS *fields;
+{
+ /* Pass non-zero for ALIAS_P only if INSN != NULL.
+ If INSN == NULL, we want a real insn. */
+ insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
+ length, fields, insn != NULL);
+ if (! insn)
+ return NULL;
+
+ cgen_get_insn_operands (cd, insn, fields, indices);
+ return insn;
+}
diff --git a/opcodes/config.in b/opcodes/config.in
new file mode 100644
index 00000000000..c60a32101ae
--- /dev/null
+++ b/opcodes/config.in
@@ -0,0 +1,135 @@
+/* config.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you have the __argz_count function. */
+#undef HAVE___ARGZ_COUNT
+
+/* Define if you have the __argz_next function. */
+#undef HAVE___ARGZ_NEXT
+
+/* Define if you have the __argz_stringify function. */
+#undef HAVE___ARGZ_STRINGIFY
+
+/* Define if you have the dcgettext function. */
+#undef HAVE_DCGETTEXT
+
+/* Define if you have the getcwd function. */
+#undef HAVE_GETCWD
+
+/* Define if you have the getpagesize function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the munmap function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the setenv function. */
+#undef HAVE_SETENV
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the stpcpy function. */
+#undef HAVE_STPCPY
+
+/* Define if you have the strcasecmp function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <nl_types.h> header file. */
+#undef HAVE_NL_TYPES_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the <values.h> header file. */
+#undef HAVE_VALUES_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if you have the stpcpy function */
+#undef HAVE_STPCPY
+
+/* Define if your locale.h file contains LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if NLS is requested */
+#undef ENABLE_NLS
+
+/* Define as 1 if you have gettext and don't want to use GNU gettext. */
+#undef HAVE_GETTEXT
+
diff --git a/opcodes/configure b/opcodes/configure
new file mode 100755
index 00000000000..71cff129f61
--- /dev/null
+++ b/opcodes/configure
@@ -0,0 +1,4754 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=no]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock force libtool not to do file locking"
+ac_help="$ac_help
+ --enable-targets alternative target configurations"
+ac_help="$ac_help
+ --enable-commonbfdlib build shared BFD/opcodes/libiberty library"
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+ --disable-nls do not use Native Language Support"
+ac_help="$ac_help
+ --with-included-gettext use the GNU gettext library included here"
+ac_help="$ac_help
+ --enable-cgen-maint[=dir] build cgen generated files"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=z8k-dis.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:596: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:617: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:635: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:660: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:690: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:741: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:773: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 784 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:815: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:820: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:829: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:848: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:880: checking for POSIXized ISC" >&5
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
+fi
+
+
+# We currently only use the version number for the name of any shared
+# library. For user convenience, we always use the same version
+# number that BFD is using.
+BFD_VERSION=`grep INIT_AUTOMAKE ${srcdir}/../bfd/configure.in | sed -n -e 's/[ ]//g' -e 's/^.*,\(.*\)).*$/\1/p'`
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:918: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:971: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1028: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=opcodes
+
+VERSION=${BFD_VERSION}
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:1074: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:1087: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:1100: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:1113: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:1126: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1149: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1181: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1213: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=no
+fi
+
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1319: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1358: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1382: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1385: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1421: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1437: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:1475: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* \($ac_symcode\) *\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if { (eval echo configure:1538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if { (eval echo configure:1542: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftestm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftestm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:1594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+echo "$ac_t""$ac_result" 1>&6
+
+echo $ac_n "checking for _ prefix in compiled symbols""... $ac_c" 1>&6
+echo "configure:1640: checking for _ prefix in compiled symbols" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_symbol_underscore'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if { (eval echo configure:1649: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { (eval echo configure:1652: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -rf conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_sys_symbol_underscore" 1>&6
+USE_SYMBOL_UNDERSCORE=${ac_cv_sys_symbol_underscore=no}
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1678: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$lt_dlopen" = yes && libtool_flags="$libtool_flags --enable-dlopen"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1714 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1736: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1741 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+*-*-cygwin*)
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1771: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_DLLTOOL"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1803: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_DLLTOOL="dlltool"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false"
+fi
+fi
+DLLTOOL="$ac_cv_prog_DLLTOOL"
+if test -n "$DLLTOOL"; then
+ echo "$ac_t""$DLLTOOL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ DLLTOOL="false"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1838: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_AS"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1870: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AS="as"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+ echo "$ac_t""$AS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ AS="false"
+fi
+fi
+
+
+ ;;
+
+esac
+
+# enable the --disable-libtool-lock switch
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ need_locks=$enableval
+else
+ need_locks=yes
+fi
+
+
+if test x"$need_locks" = xno; then
+ libtool_flags="$libtool_flags --disable-lock"
+fi
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+DLLTOOL="$DLLTOOL" AS="$AS" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+ case "${enableval}" in
+ yes | "") { echo "configure: error: enable-targets option must specify target names or 'all'" 1>&2; exit 1; }
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi
+# Check whether --enable-commonbfdlib or --disable-commonbfdlib was given.
+if test "${enable_commonbfdlib+set}" = set; then
+ enableval="$enable_commonbfdlib"
+ case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) { echo "configure: error: bad value ${enableval} for opcodes commonbfdlib option" 1>&2; exit 1; } ;;
+esac
+fi
+
+
+
+
+
+if test -z "$target" ; then
+ { echo "configure: error: Unrecognized target system type; please check config.sub." 1>&2; exit 1; }
+fi
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:2049: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:2072: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2077 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:2088: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:2105: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2110 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:2117: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:2136: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:2146: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+# host-specific stuff:
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2172: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2202: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2253: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2285: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2296 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2327: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2332: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2360: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+ALL_LINGUAS=
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2394: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2409 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2415: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2426 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2432: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2443 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2449: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2474: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2479 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2487: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2504 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2522 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2543 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2578: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2583 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2632: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2653: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 2660 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2667: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2693: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2698 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2726: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2731 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:2761: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2766 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:2773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:2794: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2799 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:2827: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_cv_func_alloca_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.${ac_objext}
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2859: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2864 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2889: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2894 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2944: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2952 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_stack_direction=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2996: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3001 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3006: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3035: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3040 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:3088: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3096 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the filesystem buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propogated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h. */
+# ifndef HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize();
+
+ /*
+ * First, make a file with some known garbage in it.
+ */
+ data = malloc(pagesize);
+ if (!data)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand();
+ umask(0);
+ fd = creat("conftestmmap", 0600);
+ if (fd < 0)
+ exit(1);
+ if (write(fd, data, pagesize) != pagesize)
+ exit(1);
+ close(fd);
+
+ /*
+ * Next, try to mmap the file at a fixed address which
+ * already has something else allocated at it. If we can,
+ * also make sure that we see the same garbage.
+ */
+ fd = open("conftestmmap", O_RDWR);
+ if (fd < 0)
+ exit(1);
+ data2 = malloc(2 * pagesize);
+ if (!data2)
+ exit(1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit(1);
+
+ /*
+ * Finally, make sure that changes to the mapped area
+ * do not percolate back to the file as seen by read().
+ * (This is a bug on some variants of i386 svr4.0.)
+ */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = malloc(pagesize);
+ if (!data3)
+ exit(1);
+ if (read(fd, data3, pagesize) != pagesize)
+ exit(1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit(1);
+ close(fd);
+ unlink("conftestmmap");
+ exit(0);
+}
+
+EOF
+if { (eval echo configure:3236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h values.h sys/param.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3264: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3269 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3274: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \
+__argz_count __argz_stringify __argz_next
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3304: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3309 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ for ac_func in stpcpy
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3361: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3366 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3389: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STPCPY 1
+EOF
+
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
+echo "configure:3423: checking for LC_MESSAGES" >&5
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3428 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:3435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_LC_MESSAGES 1
+EOF
+
+ fi
+ fi
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:3456: checking whether NLS is requested" >&5
+ # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+ enableval="$enable_nls"
+ USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ echo "$ac_t""$USE_NLS" 1>&6
+
+
+ USE_INCLUDED_LIBINTL=no
+
+ if test "$USE_NLS" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:3476: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+ withval="$with_included_gettext"
+ nls_cv_force_use_gnu_gettext=$withval
+else
+ nls_cv_force_use_gnu_gettext=no
+fi
+
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:3495: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3500 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3505: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:3522: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3527 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:3550: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3558 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:3569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:3585: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3590 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:3597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3625: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ if test "$MSGFMT" != "no"; then
+ for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3659: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3664 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3687: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3714: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3750: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ cat > conftest.$ac_ext <<EOF
+#line 3782 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:3790: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+rm -f conftest*
+ INSTOBJEXT=.mo
+ fi
+ fi
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "$CATOBJEXT" = "NONE"; then
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ INTLOBJS="\$(GETTOBJS)"
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3822: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+ echo "$ac_t""$MSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3856: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GMSGFMT" in
+ /*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+ echo "$ac_t""$GMSGFMT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3892: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+ echo "$ac_t""$XGETTEXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/../intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=libintl.h
+ nls_cv_header_libgt=libgettext.h
+ fi
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:3982: checking for catalogs to be installed" >&5
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ echo "$ac_t""$LINGUAS" 1>&6
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+
+
+ if test -f $srcdir/po2tbl.sed.in; then
+ if test "$CATOBJEXT" = ".cat"; then
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
+echo "configure:4010: checking for linux/version.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4015 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ msgformat=linux
+else
+ echo "$ac_t""no" 1>&6
+msgformat=xopen
+fi
+
+
+ sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed
+ fi
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/po2tbl.sed.in > po2tbl.sed
+ fi
+
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+
+
+
+ MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs"
+
+
+ l=
+
+
+ if test -d $srcdir/po; then
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ fi
+
+
+. ${srcdir}/../bfd/configure.host
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:4097: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+for ac_hdr in string.h strings.h stdlib.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:4154: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4159 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+using_cgen=no
+
+# Horrible hacks to build DLLs on Windows.
+WIN32LDFLAGS=
+WIN32LIBADD=
+case "${host}" in
+*-*-cygwin*)
+ if test "$enable_shared" = "yes"; then
+ WIN32LDFLAGS="-no-undefined"
+ WIN32LIBADD="-L`pwd`/../bfd -lbfd -L`pwd`/../libiberty -liberty -L`pwd`/../intl -lintl -lcygwin"
+ fi
+ ;;
+esac
+
+
+
+# target-specific stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets" ; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+ else
+ # Allow targets that config.sub doesn't recognize, like "all".
+ canon_targets="$canon_targets $targ"
+ fi
+ done
+fi
+
+all_targets=false
+selarchs=
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall" ; then
+ all_targets=true
+ else
+ . $srcdir/../bfd/config.bfd
+ selarchs="$selarchs $targ_archs"
+ fi
+done
+
+# Utility var, documents generic cgen support files.
+
+cgen_files="cgen-opc.lo cgen-asm.lo cgen-dis.lo"
+
+# We don't do any links based on the target system, just makefile config.
+
+if test x${all_targets} = xfalse ; then
+
+ # Target architecture .o files.
+ ta=
+
+ for arch in $selarchs
+ do
+ ad=`echo $arch | sed -e s/bfd_//g -e s/_arch//g`
+ archdefs="$archdefs -DARCH_$ad"
+ case "$arch" in
+ bfd_a29k_arch) ta="$ta a29k-dis.lo" ;;
+ bfd_alliant_arch) ;;
+ bfd_alpha_arch) ta="$ta alpha-dis.lo alpha-opc.lo" ;;
+ bfd_arc_arch) ta="$ta arc-dis.lo arc-opc.lo" ;;
+ bfd_arm_arch) ta="$ta arm-dis.lo" ;;
+ bfd_convex_arch) ;;
+ bfd_d10v_arch) ta="$ta d10v-dis.lo d10v-opc.lo" ;;
+ bfd_d30v_arch) ta="$ta d30v-dis.lo d30v-opc.lo" ;;
+ bfd_fr30_arch) ta="$ta fr30-asm.lo fr30-desc.lo fr30-dis.lo fr30-ibld.lo fr30-opc.lo" using_cgen=yes ;;
+ bfd_h8300_arch) ta="$ta h8300-dis.lo" ;;
+ bfd_h8500_arch) ta="$ta h8500-dis.lo" ;;
+ bfd_hppa_arch) ta="$ta hppa-dis.lo" ;;
+ bfd_i386_arch) ta="$ta i386-dis.lo" ;;
+ bfd_i860_arch) ;;
+ bfd_i960_arch) ta="$ta i960-dis.lo" ;;
+ bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
+ bfd_m68k_arch) ta="$ta m68k-dis.lo m68k-opc.lo" ;;
+ bfd_m88k_arch) ta="$ta m88k-dis.lo" ;;
+ bfd_mcore_arch) ta="$ta mcore-dis.lo" ;;
+ bfd_mips_arch) ta="$ta mips-dis.lo mips-opc.lo mips16-opc.lo" ;;
+ bfd_mn10200_arch) ta="$ta m10200-dis.lo m10200-opc.lo" ;;
+ bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
+ bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
+ bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
+ bfd_pyramid_arch) ;;
+ bfd_romp_arch) ;;
+ bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
+ bfd_sh_arch) ta="$ta sh-dis.lo" ;;
+ bfd_sparc_arch) ta="$ta sparc-dis.lo sparc-opc.lo" ;;
+ bfd_tahoe_arch) ;;
+ bfd_tic30_arch) ta="$ta tic30-dis.lo" ;;
+ bfd_tic80_arch) ta="$ta tic80-dis.lo tic80-opc.lo" ;;
+ bfd_v850_arch) ta="$ta v850-opc.lo v850-dis.lo" ;;
+ bfd_v850e_arch) ta="$ta v850-opc.lo v850-dis.lo" ;;
+ bfd_v850ea_arch) ta="$ta v850-opc.lo v850-dis.lo" ;;
+ bfd_vax_arch) ta="$ta vax-dis.lo" ;;
+ bfd_w65_arch) ta="$ta w65-dis.lo" ;;
+ bfd_we32k_arch) ;;
+ bfd_z8k_arch) ta="$ta z8k-dis.lo" ;;
+
+ "") ;;
+ *) { echo "configure: error: *** unknown target architecture $arch" 1>&2; exit 1; } ;;
+ esac
+ done
+
+ if test $using_cgen = yes ; then
+ ta="$ta $cgen_files"
+ fi
+
+ # Weed out duplicate .o files.
+ f=""
+ for i in $ta ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+ done
+ ta="$f"
+
+ # And duplicate -D flags.
+ f=""
+ for i in $archdefs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+ done
+ archdefs="$f"
+
+ BFD_MACHINES="$ta"
+
+else # all_targets is true
+ archdefs=-DARCH_all
+ BFD_MACHINES='$(ALL_MACHINES)'
+fi
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile po/Makefile.in:po/Make-in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@USE_SYMBOL_UNDERSCORE@%$USE_SYMBOL_UNDERSCORE%g
+s%@LN_S@%$LN_S%g
+s%@DLLTOOL@%$DLLTOOL%g
+s%@AS@%$AS%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g
+s%@GT_NO@%$GT_NO%g
+s%@GT_YES@%$GT_YES%g
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
+s%@l@%$l%g
+s%@HDEFINES@%$HDEFINES%g
+s%@CGEN_MAINT_TRUE@%$CGEN_MAINT_TRUE%g
+s%@CGEN_MAINT_FALSE@%$CGEN_MAINT_FALSE%g
+s%@cgendir@%$cgendir%g
+s%@cgen@%$cgen%g
+s%@WIN32LDFLAGS@%$WIN32LDFLAGS%g
+s%@WIN32LIBADD@%$WIN32LIBADD%g
+s%@archdefs@%$archdefs%g
+s%@BFD_MACHINES@%$BFD_MACHINES%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile po/Makefile.in:po/Make-in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/opcodes/configure.bat b/opcodes/configure.bat
new file mode 100644
index 00000000000..5f2c6d11c23
--- /dev/null
+++ b/opcodes/configure.bat
@@ -0,0 +1,24 @@
+@echo off
+echo Configuring opcodes for go32
+rem This batch file assumes a unix-type "sed" program
+
+echo # Makefile generated by "configure.bat"> Makefile
+
+if exist config.sed del config.sed
+
+echo "/\.o[ ]*:/ s/config.status// ">> config.sed
+echo "s/CC = cc/CC = gcc/ ">> config.sed
+echo "s/@BFD_MACHINES@/i386-dis.o/ ">> config.sed
+echo "s/@archdefs@/-DARCH_i386/ ">> config.sed
+echo "s/@frags@// ">> config.sed
+echo "s/@srcdir@// ">> config.sed
+echo "s!@prefix@!/usr/local! ">> config.sed
+echo "s!@exec_prefix@!/usr/local! ">> config.sed
+echo "s/@RANLIB@/ranlib/ ">> config.sed
+
+echo "s/^[ ]*rm/ -rm/ ">> config.sed
+
+sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
+sed -f config2.sed Makefile.in >> Makefile
+del config.sed
+del config2.sed
diff --git a/opcodes/configure.in b/opcodes/configure.in
new file mode 100644
index 00000000000..c2785804b22
--- /dev/null
+++ b/opcodes/configure.in
@@ -0,0 +1,211 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+
+AC_PREREQ(2.13)
+AC_INIT(z8k-dis.c)
+
+AC_CANONICAL_SYSTEM
+AC_ISC_POSIX
+
+# We currently only use the version number for the name of any shared
+# library. For user convenience, we always use the same version
+# number that BFD is using.
+changequote(,)dnl
+BFD_VERSION=`grep INIT_AUTOMAKE ${srcdir}/../bfd/configure.in | sed -n -e 's/[ ]//g' -e 's/^.*,\(.*\)).*$/\1/p'`
+changequote([,])dnl
+
+AM_INIT_AUTOMAKE(opcodes, ${BFD_VERSION})
+
+dnl These must be called before AM_PROG_LIBTOOL, because it may want
+dnl to call AC_CHECK_PROG.
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+dnl Default to a non shared library. This may be overridden by the
+dnl configure option --enable-shared.
+AM_DISABLE_SHARED
+
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(targets,
+[ --enable-targets alternative target configurations],
+[case "${enableval}" in
+ yes | "") AC_ERROR(enable-targets option must specify target names or 'all')
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac])dnl
+AC_ARG_ENABLE(commonbfdlib,
+[ --enable-commonbfdlib build shared BFD/opcodes/libiberty library],
+[case "${enableval}" in
+ yes) commonbfdlib=true ;;
+ no) commonbfdlib=false ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for opcodes commonbfdlib option]) ;;
+esac])dnl
+
+AM_CONFIG_HEADER(config.h:config.in)
+
+if test -z "$target" ; then
+ AC_MSG_ERROR(Unrecognized target system type; please check config.sub.)
+fi
+AC_ARG_PROGRAM
+
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+# host-specific stuff:
+
+AC_PROG_CC
+
+ALL_LINGUAS=
+CY_GNU_GETTEXT
+
+. ${srcdir}/../bfd/configure.host
+
+AC_SUBST(HDEFINES)
+AC_PROG_INSTALL
+
+AC_CHECK_HEADERS(string.h strings.h stdlib.h)
+
+
+using_cgen=no
+
+# Horrible hacks to build DLLs on Windows.
+WIN32LDFLAGS=
+WIN32LIBADD=
+case "${host}" in
+*-*-cygwin*)
+ if test "$enable_shared" = "yes"; then
+ WIN32LDFLAGS="-no-undefined"
+ WIN32LIBADD="-L`pwd`/../bfd -lbfd -L`pwd`/../libiberty -liberty -L`pwd`/../intl -lintl -lcygwin"
+ fi
+ ;;
+esac
+AC_SUBST(WIN32LDFLAGS)
+AC_SUBST(WIN32LIBADD)
+
+# target-specific stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets" ; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $targ 2>/dev/null`
+ if test -n "$result" ; then
+ canon_targets="$canon_targets $result"
+ else
+ # Allow targets that config.sub doesn't recognize, like "all".
+ canon_targets="$canon_targets $targ"
+ fi
+ done
+fi
+
+all_targets=false
+selarchs=
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall" ; then
+ all_targets=true
+ else
+ . $srcdir/../bfd/config.bfd
+ selarchs="$selarchs $targ_archs"
+ fi
+done
+
+# Utility var, documents generic cgen support files.
+
+cgen_files="cgen-opc.lo cgen-asm.lo cgen-dis.lo"
+
+# We don't do any links based on the target system, just makefile config.
+
+if test x${all_targets} = xfalse ; then
+
+ # Target architecture .o files.
+ ta=
+
+ for arch in $selarchs
+ do
+ ad=`echo $arch | sed -e s/bfd_//g -e s/_arch//g`
+ archdefs="$archdefs -DARCH_$ad"
+ case "$arch" in
+ bfd_a29k_arch) ta="$ta a29k-dis.lo" ;;
+ bfd_alliant_arch) ;;
+ bfd_alpha_arch) ta="$ta alpha-dis.lo alpha-opc.lo" ;;
+ bfd_arc_arch) ta="$ta arc-dis.lo arc-opc.lo" ;;
+ bfd_arm_arch) ta="$ta arm-dis.lo" ;;
+ bfd_convex_arch) ;;
+ bfd_d10v_arch) ta="$ta d10v-dis.lo d10v-opc.lo" ;;
+ bfd_d30v_arch) ta="$ta d30v-dis.lo d30v-opc.lo" ;;
+ bfd_fr30_arch) ta="$ta fr30-asm.lo fr30-desc.lo fr30-dis.lo fr30-ibld.lo fr30-opc.lo" using_cgen=yes ;;
+ bfd_h8300_arch) ta="$ta h8300-dis.lo" ;;
+ bfd_h8500_arch) ta="$ta h8500-dis.lo" ;;
+ bfd_hppa_arch) ta="$ta hppa-dis.lo" ;;
+ bfd_i386_arch) ta="$ta i386-dis.lo" ;;
+ bfd_i860_arch) ;;
+ bfd_i960_arch) ta="$ta i960-dis.lo" ;;
+ bfd_m32r_arch) ta="$ta m32r-asm.lo m32r-desc.lo m32r-dis.lo m32r-ibld.lo m32r-opc.lo m32r-opinst.lo" using_cgen=yes ;;
+ bfd_m68k_arch) ta="$ta m68k-dis.lo m68k-opc.lo" ;;
+ bfd_m88k_arch) ta="$ta m88k-dis.lo" ;;
+ bfd_mcore_arch) ta="$ta mcore-dis.lo" ;;
+ bfd_mips_arch) ta="$ta mips-dis.lo mips-opc.lo mips16-opc.lo" ;;
+ bfd_mn10200_arch) ta="$ta m10200-dis.lo m10200-opc.lo" ;;
+ bfd_mn10300_arch) ta="$ta m10300-dis.lo m10300-opc.lo" ;;
+ bfd_ns32k_arch) ta="$ta ns32k-dis.lo" ;;
+ bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
+ bfd_pyramid_arch) ;;
+ bfd_romp_arch) ;;
+ bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
+ bfd_sh_arch) ta="$ta sh-dis.lo" ;;
+ bfd_sparc_arch) ta="$ta sparc-dis.lo sparc-opc.lo" ;;
+ bfd_tahoe_arch) ;;
+ bfd_tic30_arch) ta="$ta tic30-dis.lo" ;;
+ bfd_tic80_arch) ta="$ta tic80-dis.lo tic80-opc.lo" ;;
+ bfd_v850_arch) ta="$ta v850-opc.lo v850-dis.lo" ;;
+ bfd_v850e_arch) ta="$ta v850-opc.lo v850-dis.lo" ;;
+ bfd_v850ea_arch) ta="$ta v850-opc.lo v850-dis.lo" ;;
+ bfd_vax_arch) ta="$ta vax-dis.lo" ;;
+ bfd_w65_arch) ta="$ta w65-dis.lo" ;;
+ bfd_we32k_arch) ;;
+ bfd_z8k_arch) ta="$ta z8k-dis.lo" ;;
+
+ "") ;;
+ *) AC_MSG_ERROR(*** unknown target architecture $arch) ;;
+ esac
+ done
+
+ if test $using_cgen = yes ; then
+ ta="$ta $cgen_files"
+ fi
+
+ # Weed out duplicate .o files.
+ f=""
+ for i in $ta ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+ done
+ ta="$f"
+
+ # And duplicate -D flags.
+ f=""
+ for i in $archdefs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+ done
+ archdefs="$f"
+
+ BFD_MACHINES="$ta"
+
+else # all_targets is true
+ archdefs=-DARCH_all
+ BFD_MACHINES='$(ALL_MACHINES)'
+fi
+
+AC_SUBST(archdefs)
+AC_SUBST(BFD_MACHINES)
+
+AC_OUTPUT(Makefile po/Makefile.in:po/Make-in,
+[sed -e '/POTFILES =/r po/POTFILES' po/Makefile.in > po/Makefile])
diff --git a/opcodes/d10v-dis.c b/opcodes/d10v-dis.c
new file mode 100644
index 00000000000..fb1a7d30dd2
--- /dev/null
+++ b/opcodes/d10v-dis.c
@@ -0,0 +1,301 @@
+/* Disassemble D10V instructions.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <stdio.h>
+
+#include "ansidecl.h"
+#include "opcode/d10v.h"
+#include "dis-asm.h"
+
+/* the PC wraps at 18 bits, except for the segment number */
+/* so use this mask to keep the parts we want */
+#define PC_MASK 0x0303FFFF
+
+static void dis_2_short PARAMS ((unsigned long insn, bfd_vma memaddr,
+ struct disassemble_info *info, int order));
+static void dis_long PARAMS ((unsigned long insn, bfd_vma memaddr,
+ struct disassemble_info *info));
+
+int
+print_insn_d10v (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int status;
+ bfd_byte buffer[4];
+ unsigned long insn;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb32 (buffer);
+
+ status = insn & FM11;
+ switch (status) {
+ case 0:
+ dis_2_short (insn, memaddr, info, 2);
+ break;
+ case FM01:
+ dis_2_short (insn, memaddr, info, 0);
+ break;
+ case FM10:
+ dis_2_short (insn, memaddr, info, 1);
+ break;
+ case FM11:
+ dis_long (insn, memaddr, info);
+ break;
+ }
+ return 4;
+}
+
+static void
+print_operand (oper, insn, op, memaddr, info)
+ struct d10v_operand *oper;
+ unsigned long insn;
+ struct d10v_opcode *op;
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int num, shift;
+
+ if (oper->flags == OPERAND_ATMINUS)
+ {
+ (*info->fprintf_func) (info->stream, "@-");
+ return;
+ }
+ if (oper->flags == OPERAND_MINUS)
+ {
+ (*info->fprintf_func) (info->stream, "-");
+ return;
+ }
+ if (oper->flags == OPERAND_PLUS)
+ {
+ (*info->fprintf_func) (info->stream, "+");
+ return;
+ }
+ if (oper->flags == OPERAND_ATSIGN)
+ {
+ (*info->fprintf_func) (info->stream, "@");
+ return;
+ }
+ if (oper->flags == OPERAND_ATPAR)
+ {
+ (*info->fprintf_func) (info->stream, "@(");
+ return;
+ }
+
+ shift = oper->shift;
+
+ /* the LONG_L format shifts registers over by 15 */
+ if (op->format == LONG_L && (oper->flags & OPERAND_REG))
+ shift += 15;
+
+ num = (insn >> shift) & (0x7FFFFFFF >> (31 - oper->bits));
+
+ if (oper->flags & OPERAND_REG)
+ {
+ int i;
+ int match=0;
+ num += (oper->flags
+ & (OPERAND_GPR|OPERAND_FFLAG|OPERAND_CFLAG|OPERAND_CONTROL));
+ if (oper->flags & (OPERAND_ACC0|OPERAND_ACC1))
+ num += num ? OPERAND_ACC1 : OPERAND_ACC0;
+ for (i = 0; i < d10v_reg_name_cnt(); i++)
+ {
+ if (num == d10v_predefined_registers[i].value)
+ {
+ if (d10v_predefined_registers[i].pname)
+ (*info->fprintf_func) (info->stream, "%s",d10v_predefined_registers[i].pname);
+ else
+ (*info->fprintf_func) (info->stream, "%s",d10v_predefined_registers[i].name);
+ match=1;
+ break;
+ }
+ }
+ if (match == 0)
+ {
+ /* this would only get executed if a register was not in the
+ register table */
+ if (oper->flags & (OPERAND_ACC0|OPERAND_ACC1))
+ (*info->fprintf_func) (info->stream, "a");
+ else if (oper->flags & OPERAND_CONTROL)
+ (*info->fprintf_func) (info->stream, "cr");
+ else if(oper->flags & OPERAND_REG)
+ (*info->fprintf_func) (info->stream, "r");
+ (*info->fprintf_func) (info->stream, "%d",num);
+ }
+ }
+ else
+ {
+ /* addresses are right-shifted by 2 */
+ if (oper->flags & OPERAND_ADDR)
+ {
+ long max;
+ int neg=0;
+ max = (1 << (oper->bits - 1));
+ if (num & max)
+ {
+ num = -num & ((1 << oper->bits)-1);
+ neg = 1;
+ }
+ num = num<<2;
+ if (info->flags & INSN_HAS_RELOC)
+ (*info->print_address_func) (num & PC_MASK, info);
+ else
+ {
+ if (neg)
+ (*info->print_address_func) ((memaddr - num) & PC_MASK, info);
+ else
+ (*info->print_address_func) ((memaddr + num) & PC_MASK, info);
+ }
+ }
+ else
+ {
+ if (oper->flags & OPERAND_SIGNED)
+ {
+ int max = (1 << (oper->bits - 1));
+ if (num & max)
+ {
+ num = -num & ((1 << oper->bits)-1);
+ (*info->fprintf_func) (info->stream, "-");
+ }
+ }
+ (*info->fprintf_func) (info->stream, "0x%x",num);
+ }
+ }
+}
+
+
+static void
+dis_long (insn, memaddr, info)
+ unsigned long insn;
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int i;
+ char buf[32];
+ struct d10v_opcode *op = (struct d10v_opcode *)d10v_opcodes;
+ struct d10v_operand *oper;
+ int need_paren = 0;
+ int match = 0;
+
+ while (op->name)
+ {
+ if ((op->format & LONG_OPCODE) && ((op->mask & insn) == op->opcode))
+ {
+ match = 1;
+ (*info->fprintf_func) (info->stream, "%s\t", op->name);
+ for ( i=0; op->operands[i]; i++)
+ {
+ oper = (struct d10v_operand *)&d10v_operands[op->operands[i]];
+ if (oper->flags == OPERAND_ATPAR)
+ need_paren = 1;
+ print_operand (oper, insn, op, memaddr, info);
+ if (op->operands[i+1] && oper->bits &&
+ d10v_operands[op->operands[i+1]].flags != OPERAND_PLUS &&
+ d10v_operands[op->operands[i+1]].flags != OPERAND_MINUS)
+ (*info->fprintf_func) (info->stream, ", ");
+ }
+ break;
+ }
+ op++;
+ }
+
+ if (!match)
+ (*info->fprintf_func) (info->stream, ".long\t0x%08x",insn);
+
+ if (need_paren)
+ (*info->fprintf_func) (info->stream, ")");
+}
+
+static void
+dis_2_short (insn, memaddr, info, order)
+ unsigned long insn;
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+ int order;
+{
+ int i,j;
+ char astr[2][32];
+ unsigned int ins[2];
+ struct d10v_opcode *op;
+ char buf[32];
+ int match, num_match=0;
+ struct d10v_operand *oper;
+ int need_paren = 0;
+
+ ins[0] = (insn & 0x3FFFFFFF) >> 15;
+ ins[1] = insn & 0x00007FFF;
+
+ for(j=0;j<2;j++)
+ {
+ op = (struct d10v_opcode *)d10v_opcodes;
+ match=0;
+ while (op->name)
+ {
+ if ((op->format & SHORT_OPCODE) && ((op->mask & ins[j]) == op->opcode))
+ {
+ (*info->fprintf_func) (info->stream, "%s\t",op->name);
+ for (i=0; op->operands[i]; i++)
+ {
+ oper = (struct d10v_operand *)&d10v_operands[op->operands[i]];
+ if (oper->flags == OPERAND_ATPAR)
+ need_paren = 1;
+ print_operand (oper, ins[j], op, memaddr, info);
+ if (op->operands[i+1] && oper->bits &&
+ d10v_operands[op->operands[i+1]].flags != OPERAND_PLUS &&
+ d10v_operands[op->operands[i+1]].flags != OPERAND_MINUS)
+ (*info->fprintf_func) (info->stream, ", ");
+ }
+ match = 1;
+ num_match++;
+ break;
+ }
+ op++;
+ }
+ if (!match)
+ (*info->fprintf_func) (info->stream, "unknown");
+
+ switch (order)
+ {
+ case 0:
+ (*info->fprintf_func) (info->stream, "\t->\t");
+ order = -1;
+ break;
+ case 1:
+ (*info->fprintf_func) (info->stream, "\t<-\t");
+ order = -1;
+ break;
+ case 2:
+ (*info->fprintf_func) (info->stream, "\t||\t");
+ order = -1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (num_match == 0)
+ (*info->fprintf_func) (info->stream, ".long\t0x%08x",insn);
+
+ if (need_paren)
+ (*info->fprintf_func) (info->stream, ")");
+}
diff --git a/opcodes/d10v-opc.c b/opcodes/d10v-opc.c
new file mode 100644
index 00000000000..a8a02d03871
--- /dev/null
+++ b/opcodes/d10v-opc.c
@@ -0,0 +1,334 @@
+/* d10v-opc.c -- D10V opcode list
+ Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Martin Hunt, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/d10v.h"
+
+
+/* The table is sorted. Suitable for searching by a binary search. */
+const struct pd_reg d10v_predefined_registers[] =
+{
+ { "a0", NULL, OPERAND_ACC0+0 },
+ { "a1", NULL, OPERAND_ACC1+1 },
+ { "bpc", NULL, OPERAND_CONTROL+3 },
+ { "bpsw", NULL, OPERAND_CONTROL+1 },
+ { "c", NULL, OPERAND_CFLAG+3 },
+ { "cr0", "psw", OPERAND_CONTROL },
+ { "cr1", "bpsw", OPERAND_CONTROL+1 },
+ { "cr10", "mod_s", OPERAND_CONTROL+10 },
+ { "cr11", "mod_e", OPERAND_CONTROL+11 },
+ { "cr12", NULL, OPERAND_CONTROL+12 },
+ { "cr13", NULL, OPERAND_CONTROL+13 },
+ { "cr14", "iba", OPERAND_CONTROL+14 },
+ { "cr15", NULL, OPERAND_CONTROL+15 },
+ { "cr2", "pc", OPERAND_CONTROL+2 },
+ { "cr3", "bpc", OPERAND_CONTROL+3 },
+ { "cr4", "dpsw", OPERAND_CONTROL+4 },
+ { "cr5", "dpc", OPERAND_CONTROL+5 },
+ { "cr6", NULL, OPERAND_CONTROL+6 },
+ { "cr7", "rpt_c", OPERAND_CONTROL+7 },
+ { "cr8", "rpt_s", OPERAND_CONTROL+8 },
+ { "cr9", "rpt_e", OPERAND_CONTROL+9 },
+ { "dpc", NULL, OPERAND_CONTROL+5 },
+ { "dpsw", NULL, OPERAND_CONTROL+4 },
+ { "f0", NULL, OPERAND_FFLAG+0 },
+ { "f1", NULL, OPERAND_FFLAG+1 },
+ { "iba", NULL, OPERAND_CONTROL+14 },
+ { "link", "r13", OPERAND_GPR+13 },
+ { "mod_e", NULL, OPERAND_CONTROL+11 },
+ { "mod_s", NULL, OPERAND_CONTROL+10 },
+ { "pc", NULL, OPERAND_CONTROL+2 },
+ { "psw", NULL, OPERAND_CONTROL+0 },
+ { "r0", NULL, OPERAND_GPR+0 },
+ { "r0-r1", NULL, OPERAND_GPR+0},
+ { "r1", NULL, OPERAND_GPR+1 },
+ { "r1", NULL, OPERAND_GPR+1 },
+ { "r10", NULL, OPERAND_GPR+10 },
+ { "r10-r11", NULL, OPERAND_GPR+10 },
+ { "r11", NULL, OPERAND_GPR+11 },
+ { "r12", NULL, OPERAND_GPR+12 },
+ { "r12-r13", NULL, OPERAND_GPR+12 },
+ { "r13", NULL, OPERAND_GPR+13 },
+ { "r14", NULL, OPERAND_GPR+14 },
+ { "r14-r15", NULL, OPERAND_GPR+14 },
+ { "r15", "sp", OPERAND_GPR+15 },
+ { "r2", NULL, OPERAND_GPR+2 },
+ { "r2-r3", NULL, OPERAND_GPR+2 },
+ { "r3", NULL, OPERAND_GPR+3 },
+ { "r4", NULL, OPERAND_GPR+4 },
+ { "r4-r5", NULL, OPERAND_GPR+4 },
+ { "r5", NULL, OPERAND_GPR+5 },
+ { "r6", NULL, OPERAND_GPR+6 },
+ { "r6-r7", NULL, OPERAND_GPR+6 },
+ { "r7", NULL, OPERAND_GPR+7 },
+ { "r8", NULL, OPERAND_GPR+8 },
+ { "r8-r9", NULL, OPERAND_GPR+8 },
+ { "r9", NULL, OPERAND_GPR+9 },
+ { "rpt_c", NULL, OPERAND_CONTROL+7 },
+ { "rpt_e", NULL, OPERAND_CONTROL+9 },
+ { "rpt_s", NULL, OPERAND_CONTROL+8 },
+ { "sp", NULL, OPERAND_GPR+15 },
+};
+
+int
+d10v_reg_name_cnt()
+{
+ return (sizeof(d10v_predefined_registers) / sizeof(struct pd_reg));
+}
+
+const struct d10v_operand d10v_operands[] =
+{
+#define UNUSED (0)
+ { 0, 0, 0 },
+#define RSRC (UNUSED + 1)
+ { 4, 1, OPERAND_GPR|OPERAND_REG },
+#define RDST (RSRC + 1)
+ { 4, 5, OPERAND_DEST|OPERAND_GPR|OPERAND_REG },
+#define ASRC (RDST + 1)
+ { 1, 4, OPERAND_ACC0|OPERAND_ACC1|OPERAND_REG },
+#define ASRC0ONLY (ASRC + 1)
+ { 1, 4, OPERAND_ACC0|OPERAND_REG },
+#define ADST (ASRC0ONLY + 1)
+ { 1, 8, OPERAND_DEST|OPERAND_ACC0|OPERAND_ACC1|OPERAND_REG },
+#define RSRCE (ADST + 1)
+ { 4, 1, OPERAND_EVEN|OPERAND_GPR|OPERAND_REG },
+#define RDSTE (RSRCE + 1)
+ { 4, 5, OPERAND_EVEN|OPERAND_DEST|OPERAND_GPR|OPERAND_REG },
+#define NUM16 (RDSTE + 1)
+ { 16, 0, OPERAND_NUM|OPERAND_SIGNED },
+#define NUM3 (NUM16 + 1) /* rac, rachi */
+ { 3, 1, OPERAND_NUM|OPERAND_SIGNED },
+#define NUM4 (NUM3 + 1)
+ { 4, 1, OPERAND_NUM|OPERAND_SIGNED },
+#define UNUM4 (NUM4 + 1)
+ { 4, 1, OPERAND_NUM },
+#define UNUM4S (UNUM4 + 1) /* addi, slli, srai, srli, subi */
+ { 4, 1, OPERAND_NUM|OPERAND_SHIFT },
+#define UNUM8 (UNUM4S + 1) /* repi */
+ { 8, 16, OPERAND_NUM },
+#define UNUM16 (UNUM8 + 1) /* cmpui */
+ { 16, 0, OPERAND_NUM },
+#define ANUM16 (UNUM16 + 1)
+ { 16, 0, OPERAND_ADDR|OPERAND_SIGNED },
+#define ANUM8 (ANUM16 + 1)
+ { 8, 0, OPERAND_ADDR|OPERAND_SIGNED },
+#define ASRC2 (ANUM8 + 1)
+ { 1, 8, OPERAND_ACC0|OPERAND_ACC1|OPERAND_REG },
+#define RSRC2 (ASRC2 + 1)
+ { 4, 5, OPERAND_GPR|OPERAND_REG },
+#define RSRC2E (RSRC2 + 1)
+ { 4, 5, OPERAND_GPR|OPERAND_REG|OPERAND_EVEN },
+#define ASRC0 (RSRC2E + 1)
+ { 1, 0, OPERAND_ACC0|OPERAND_ACC1|OPERAND_REG },
+#define ADST0 (ASRC0 + 1)
+ { 1, 0, OPERAND_ACC0|OPERAND_ACC1|OPERAND_REG|OPERAND_DEST },
+#define FFSRC (ADST0 + 1)
+ { 2, 1, OPERAND_REG | OPERAND_FFLAG },
+#define CFSRC (FFSRC + 1)
+ { 2, 1, OPERAND_REG | OPERAND_CFLAG },
+#define FDST (CFSRC + 1)
+ { 1, 5, OPERAND_REG | OPERAND_FFLAG | OPERAND_DEST},
+#define ATSIGN (FDST + 1)
+ { 0, 0, OPERAND_ATSIGN},
+#define ATPAR (ATSIGN + 1) /* "@(" */
+ { 0, 0, OPERAND_ATPAR},
+#define PLUS (ATPAR + 1) /* postincrement */
+ { 0, 0, OPERAND_PLUS},
+#define MINUS (PLUS + 1) /* postdecrement */
+ { 0, 0, OPERAND_MINUS},
+#define ATMINUS (MINUS + 1) /* predecrement */
+ { 0, 0, OPERAND_ATMINUS},
+#define CSRC (ATMINUS + 1) /* control register */
+ { 4, 1, OPERAND_REG|OPERAND_CONTROL},
+#define CDST (CSRC + 1) /* control register */
+ { 4, 5, OPERAND_REG|OPERAND_CONTROL|OPERAND_DEST},
+};
+
+const struct d10v_opcode d10v_opcodes[] = {
+ { "abs", SHORT_2, 1, EITHER, PAR|WF0, 0x4607, 0x7e1f, { RDST } },
+ { "abs", SHORT_2, 1, IU, PAR|WF0, 0x5607, 0x7eff, { ADST } },
+ { "add", SHORT_2, 1, EITHER, PAR|WCAR, 0x0200, 0x7e01, { RDST, RSRC } },
+ { "add", SHORT_2, 1, IU, PAR, 0x1201, 0x7ee3, { ADST, RSRCE } },
+ { "add", SHORT_2, 1, IU, PAR, 0x1203, 0x7eef, { ADST, ASRC } },
+ { "add2w", SHORT_2, 2, IU, PAR|WCAR, 0x1200, 0x7e23, { RDSTE, RSRCE } },
+ { "add3", LONG_L, 1, MU, SEQ|WCAR, 0x1000000, 0x3f000000, { RDST, RSRC, NUM16 } },
+ { "addac3", LONG_R, 1, IU, SEQ, 0x17000200, 0x3ffffe22, { RDSTE, RSRCE, ASRC0 } },
+ { "addac3", LONG_R, 1, IU, SEQ, 0x17000202, 0x3ffffe2e, { RDSTE, ASRC, ASRC0 } },
+ { "addac3s", LONG_R, 1, IU, SEQ, 0x17001200, 0x3ffffe22, { RDSTE, RSRCE, ASRC0 } },
+ { "addac3s", LONG_R, 1, IU, SEQ, 0x17001202, 0x3ffffe2e, { RDSTE, ASRC, ASRC0 } },
+ { "addi", SHORT_2, 1, EITHER, PAR|WCAR, 0x201, 0x7e01, { RDST, UNUM4S } },
+ { "and", SHORT_2, 1, EITHER, PAR, 0xc00, 0x7e01, { RDST, RSRC } },
+ { "and3", LONG_L, 1, MU, SEQ, 0x6000000, 0x3f000000, { RDST, RSRC, NUM16 } },
+ { "bclri", SHORT_2, 1, IU, PAR, 0xc01, 0x7e01, { RDST, UNUM4 } },
+ { "bl", OPCODE_FAKE, 0, 0, 0, 0, 0, { 0, 8, 16, 0 } },
+ { "bl.s", SHORT_B, 3, MU, BRANCH_LINK|PAR, 0x4900, 0x7f00, { ANUM8 } },
+ { "bl.l", LONG_B, 3, MU, BRANCH_LINK|SEQ, 0x24800000, 0x3fff0000, { ANUM16 } },
+ { "bnoti", SHORT_2, 1, IU, PAR, 0xa01, 0x7e01, { RDST, UNUM4 } },
+ { "bra", OPCODE_FAKE, 0, 0, 0, 0, 0, { 0, 8, 16, 0 } },
+ { "bra.s", SHORT_B, 3, MU, BRANCH|PAR, 0x4800, 0x7f00, { ANUM8 } },
+ { "bra.l", LONG_B, 3, MU, BRANCH|SEQ, 0x24000000, 0x3fff0000, { ANUM16 } },
+ { "brf0f", OPCODE_FAKE, 0, 0, 0, 0, 0, { 0, 8, 16, 0 } },
+ { "brf0f.s", SHORT_B, 3, MU, BRANCH|PAR|RF0, 0x4a00, 0x7f00, { ANUM8 } },
+ { "brf0f.l", LONG_B, 3, MU, SEQ, 0x25000000, 0x3fff0000, { ANUM16 } },
+ { "brf0t", OPCODE_FAKE, 0, 0, 0, 0, 0, { 0, 8, 16, 0 } },
+ { "brf0t.s", SHORT_B, 3, MU, BRANCH|PAR|RF0, 0x4b00, 0x7f00, { ANUM8 } },
+ { "brf0t.l", LONG_B, 3, MU, SEQ, 0x25800000, 0x3fff0000, { ANUM16 } },
+ { "bseti", SHORT_2, 1, IU, PAR, 0x801, 0x7e01, { RDST, UNUM4 } },
+ { "btsti", SHORT_2, 1, IU, PAR|WF0, 0xe01, 0x7e01, { RDST, UNUM4 } },
+ { "clrac", SHORT_2, 1, IU, PAR, 0x5601, 0x7eff, { ADST } },
+ { "cmp", SHORT_2, 1, EITHER, PAR|WF0, 0x600, 0x7e01, { RSRC2, RSRC } },
+ { "cmp", SHORT_2, 1, IU, PAR|WF0, 0x1603, 0x7eef, { ASRC2, ASRC } },
+ { "cmpeq", SHORT_2, 1, EITHER, PAR|WF0, 0x400, 0x7e01, { RSRC2, RSRC } },
+ { "cmpeq", SHORT_2, 1, IU, PAR|WF0, 0x1403, 0x7eef, { ASRC2, ASRC } },
+ { "cmpeqi", OPCODE_FAKE, 0, 0, 0, 0, 0, { 1, 4, 16, 0 } },
+ { "cmpeqi.s", SHORT_2, 1, EITHER, PAR|WF0, 0x401, 0x7e01, { RSRC2, NUM4 } },
+ { "cmpeqi.l", LONG_L, 1, MU, SEQ, 0x2000000, 0x3f0f0000, { RSRC2, NUM16 } },
+ { "cmpi", OPCODE_FAKE, 0, 0, 0, 0, 0, { 1, 4, 16, 0 } },
+ { "cmpi.s", SHORT_2, 1, EITHER, PAR|WF0, 0x601, 0x7e01, { RSRC2, NUM4 } },
+ { "cmpi.l", LONG_L, 1, MU, SEQ, 0x3000000, 0x3f0f0000, { RSRC2, NUM16 } },
+ { "cmpu", SHORT_2, 1, EITHER, PAR|WF0, 0x4600, 0x7e01, { RSRC2, RSRC } },
+ { "cmpui", LONG_L, 1, MU, SEQ, 0x23000000, 0x3f0f0000, { RSRC2, UNUM16 } },
+ { "cpfg", SHORT_2, 1, MU, PAR, 0x4e09, 0x7fd9, { FDST, FFSRC } },
+ { "cpfg", SHORT_2, 1, MU, PAR, 0x4e09, 0x7fd9, { FDST, CFSRC } },
+ { "dbt", SHORT_2, 5, MU, PAR, 0x5f20, 0x7fff, { 0 } },
+ { "divs", LONG_L, 1, BOTH, SEQ, 0x14002800, 0x3f10fe21, { RDSTE, RSRC } },
+ { "exef0f", SHORT_2, 1, EITHER, PARONLY, 0x4e04, 0x7fff, { 0 } },
+ { "exef0t", SHORT_2, 1, EITHER, PARONLY, 0x4e24, 0x7fff, { 0 } },
+ { "exef1f", SHORT_2, 1, EITHER, PARONLY, 0x4e40, 0x7fff, { 0 } },
+ { "exef1t", SHORT_2, 1, EITHER, PARONLY, 0x4e42, 0x7fff, { 0 } },
+ { "exefaf", SHORT_2, 1, EITHER, PARONLY, 0x4e00, 0x7fff, { 0 } },
+ { "exefat", SHORT_2, 1, EITHER, PARONLY, 0x4e02, 0x7fff, { 0 } },
+ { "exetaf", SHORT_2, 1, EITHER, PARONLY, 0x4e20, 0x7fff, { 0 } },
+ { "exetat", SHORT_2, 1, EITHER, PARONLY, 0x4e22, 0x7fff, { 0 } },
+ { "exp", LONG_R, 1, IU, SEQ, 0x15002a00, 0x3ffffe03, { RDST, RSRCE } },
+ { "exp", LONG_R, 1, IU, SEQ, 0x15002a02, 0x3ffffe0f, { RDST, ASRC } },
+ { "jl", SHORT_2, 3, MU, BRANCH_LINK|PAR, 0x4d00, 0x7fe1, { RSRC } },
+ { "jmp", SHORT_2, 3, MU, BRANCH|PAR, 0x4c00, 0x7fe1, { RSRC } },
+ { "ld", LONG_L, 1, MU, SEQ, 0x30000000, 0x3f000000, { RDST, ATPAR, NUM16, RSRC } },
+ { "ld", SHORT_2, 1, MU, PAR|RMEM, 0x6401, 0x7e01, { RDST, ATSIGN, RSRC, MINUS } },
+ { "ld", SHORT_2, 1, MU, PAR|RMEM, 0x6001, 0x7e01, { RDST, ATSIGN, RSRC, PLUS } },
+ { "ld", SHORT_2, 1, MU, PAR|RMEM, 0x6000, 0x7e01, { RDST, ATSIGN, RSRC } },
+ { "ld2w", LONG_L, 1, MU, SEQ, 0x31000000, 0x3f100000, { RDSTE, ATPAR, NUM16, RSRC } },
+ { "ld2w", SHORT_2, 1, MU, PAR|RMEM, 0x6601, 0x7e21, { RDSTE, ATSIGN, RSRC, MINUS } },
+ { "ld2w", SHORT_2, 1, MU, PAR|RMEM, 0x6201, 0x7e21, { RDSTE, ATSIGN, RSRC, PLUS } },
+ { "ld2w", SHORT_2, 1, MU, PAR|RMEM, 0x6200, 0x7e21, { RDSTE, ATSIGN, RSRC } },
+ { "ldb", LONG_L, 1, MU, SEQ, 0x38000000, 0x3f000000, { RDST, ATPAR, NUM16, RSRC } },
+ { "ldb", SHORT_2, 1, MU, PAR|RMEM, 0x7000, 0x7e01, { RDST, ATSIGN, RSRC } },
+ { "ldi", OPCODE_FAKE, 0, 0, 0, 0, 0, { 1, 4, 16, 0 } },
+ { "ldi.s", SHORT_2, 1, EITHER, PAR|RMEM, 0x4001, 0x7e01 , { RDST, NUM4 } },
+ { "ldi.l", LONG_L, 1, MU, SEQ, 0x20000000, 0x3f0f0000, { RDST, NUM16 } },
+ { "ldub", LONG_L, 1, MU, SEQ, 0x39000000, 0x3f000000, { RDST, ATPAR, NUM16, RSRC } },
+ { "ldub", SHORT_2, 1, MU, PAR|RMEM, 0x7200, 0x7e01, { RDST, ATSIGN, RSRC } },
+ { "mac", SHORT_2, 1, IU, PAR, 0x2a00, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "macsu", SHORT_2, 1, IU, PAR, 0x1a00, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "macu", SHORT_2, 1, IU, PAR, 0x3a00, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "max", SHORT_2, 1, IU, PAR|WF0, 0x2600, 0x7e01, { RDST, RSRC } },
+ { "max", SHORT_2, 1, IU, PAR|WF0, 0x3600, 0x7ee3, { ADST, RSRCE } },
+ { "max", SHORT_2, 1, IU, PAR|WF0, 0x3602, 0x7eef, { ADST, ASRC } },
+ { "min", SHORT_2, 1, IU, PAR|WF0, 0x2601, 0x7e01 , { RDST, RSRC } },
+ { "min", SHORT_2, 1, IU, PAR|WF0, 0x3601, 0x7ee3 , { ADST, RSRCE } },
+ { "min", SHORT_2, 1, IU, PAR|WF0, 0x3603, 0x7eef, { ADST, ASRC } },
+ { "msb", SHORT_2, 1, IU, PAR, 0x2800, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "msbsu", SHORT_2, 1, IU, PAR, 0x1800, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "msbu", SHORT_2, 1, IU, PAR, 0x3800, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "mul", SHORT_2, 1, IU, PAR, 0x2e00, 0x7e01 , { RDST, RSRC } },
+ { "mulx", SHORT_2, 1, IU, PAR, 0x2c00, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "mulxsu", SHORT_2, 1, IU, PAR, 0x1c00, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "mulxu", SHORT_2, 1, IU, PAR, 0x3c00, 0x7e00, { ADST0, RSRC2, RSRC } },
+ { "mv", SHORT_2, 1, EITHER, PAR, 0x4000, 0x7e01, { RDST, RSRC } },
+ { "mv2w", SHORT_2, 1, IU, PAR, 0x5000, 0x7e23, { RDSTE, RSRCE } },
+ { "mv2wfac", SHORT_2, 1, IU, PAR, 0x3e00, 0x7e2f, { RDSTE, ASRC } },
+ { "mv2wtac", SHORT_2, 1, IU, PAR, 0x3e01, 0x7ee3, { RSRCE, ADST } },
+ { "mvac", SHORT_2, 1, IU, PAR, 0x3e03, 0x7eef, { ADST, ASRC } },
+ { "mvb", SHORT_2, 1, IU, PAR, 0x5400, 0x7e01, { RDST, RSRC } },
+ { "mvf0f", SHORT_2, 1, EITHER, PAR|RF0, 0x4400, 0x7e01, { RDST, RSRC } },
+ { "mvf0t", SHORT_2, 1, EITHER, PAR|RF0, 0x4401, 0x7e01, { RDST, RSRC } },
+ { "mvfacg", SHORT_2, 1, IU, PAR, 0x1e04, 0x7e0f, { RDST, ASRC } },
+ { "mvfachi", SHORT_2, 1, IU, PAR, 0x1e00, 0x7e0f, { RDST, ASRC } },
+ { "mvfaclo", SHORT_2, 1, IU, PAR, 0x1e02, 0x7e0f, { RDST, ASRC } },
+ { "mvfc", SHORT_2, 1, MU, PAR, 0x5200, 0x7e01, { RDST, CSRC } },
+ { "mvtacg", SHORT_2, 1, IU, PAR, 0x1e41, 0x7ee1, { RSRC, ADST } },
+ { "mvtachi", SHORT_2, 1, IU, PAR, 0x1e01, 0x7ee1, { RSRC, ADST } },
+ { "mvtaclo", SHORT_2, 1, IU, PAR, 0x1e21, 0x7ee1, { RSRC, ADST } },
+ { "mvtc", SHORT_2, 1, MU, PAR, 0x5600, 0x7e01, { RSRC, CDST } },
+ { "mvub", SHORT_2, 1, IU, PAR, 0x5401, 0x7e01, { RDST, RSRC } },
+ { "neg", SHORT_2, 1, EITHER, PAR, 0x4605, 0x7e1f, { RDST } },
+ { "neg", SHORT_2, 1, IU, PAR, 0x5605, 0x7eff, { ADST } },
+ { "nop", SHORT_2, 1, EITHER, PAR, 0x5e00, 0x7fff, { 0 } },
+ { "not", SHORT_2, 1, EITHER, PAR, 0x4603, 0x7e1f, { RDST } },
+ { "or", SHORT_2, 1, EITHER, PAR, 0x800, 0x7e01, { RDST, RSRC } },
+ { "or3", LONG_L, 1, MU, SEQ, 0x4000000, 0x3f000000, { RDST, RSRC, NUM16 } },
+ { "rac", SHORT_2, 1, IU, PAR|WF0, 0x5201, 0x7e21, { RDSTE, ASRC0ONLY, NUM3 } },
+ { "rachi", SHORT_2, 1, IU, PAR|WF0, 0x4201, 0x7e01, { RDST, ASRC, NUM3 } },
+ { "rep", LONG_L, 2, MU, SEQ, 0x27000000, 0x3ff00000, { RSRC, ANUM16 } },
+ { "repi", LONG_L, 2, MU, SEQ, 0x2f000000, 0x3f000000, { UNUM8, ANUM16 } },
+ { "rtd", SHORT_2, 3, MU, PAR, 0x5f60, 0x7fff, { 0 } },
+ { "rte", SHORT_2, 3, MU, PAR, 0x5f40, 0x7fff, { 0 } },
+ { "sadd", SHORT_2, 1, IU, PAR, 0x1223, 0x7eef, { ADST, ASRC } },
+ { "setf0f", SHORT_2, 1, MU, PAR|RF0, 0x4611, 0x7e1f, { RDST } },
+ { "setf0t", SHORT_2, 1, MU, PAR|RF0, 0x4613, 0x7e1f, { RDST } },
+ { "sleep", SHORT_2, 1, MU, PAR, 0x5fc0, 0x7fff, { 0 } },
+ { "sll", SHORT_2, 1, IU, PAR, 0x2200, 0x7e01, { RDST, RSRC } },
+ { "sll", SHORT_2, 1, IU, PAR, 0x3200, 0x7ee1, { ADST, RSRC } },
+ { "slli", SHORT_2, 1, IU, PAR, 0x2201, 0x7e01, { RDST, UNUM4 } },
+ { "slli", SHORT_2, 1, IU, PAR, 0x3201, 0x7ee1, { ADST, UNUM4S } },
+ { "slx", SHORT_2, 1, IU, PAR|RF0, 0x460b, 0x7e1f, { RDST } },
+ { "sra", SHORT_2, 1, IU, PAR, 0x2400, 0x7e01, { RDST, RSRC } },
+ { "sra", SHORT_2, 1, IU, PAR, 0x3400, 0x7ee1, { ADST, RSRC } },
+ { "srai", SHORT_2, 1, IU, PAR, 0x2401, 0x7e01, { RDST, UNUM4 } },
+ { "srai", SHORT_2, 1, IU, PAR, 0x3401, 0x7ee1, { ADST, UNUM4S } },
+ { "srl", SHORT_2, 1, IU, PAR, 0x2000, 0x7e01, { RDST, RSRC } },
+ { "srl", SHORT_2, 1, IU, PAR, 0x3000, 0x7ee1, { ADST, RSRC } },
+ { "srli", SHORT_2, 1, IU, PAR, 0x2001, 0x7e01, { RDST, UNUM4 } },
+ { "srli", SHORT_2, 1, IU, PAR, 0x3001, 0x7ee1, { ADST, UNUM4S } },
+ { "srx", SHORT_2, 1, IU, PAR|RF0, 0x4609, 0x7e1f, { RDST } },
+ { "st", LONG_L, 1, MU, SEQ, 0x34000000, 0x3f000000, { RSRC2, ATPAR, NUM16, RSRC } },
+ { "st", SHORT_2, 1, MU, PAR|WMEM, 0x6800, 0x7e01, { RSRC2, ATSIGN, RSRC } },
+ { "st", SHORT_2, 1, MU, PAR|WMEM, 0x6c1f, 0x7e1f, { RSRC2, ATMINUS, RSRC } },
+ { "st", SHORT_2, 1, MU, PAR|WMEM, 0x6801, 0x7e01, { RSRC2, ATSIGN, RSRC, PLUS } },
+ { "st", SHORT_2, 1, MU, PAR|WMEM, 0x6c01, 0x7e01, { RSRC2, ATSIGN, RSRC, MINUS } },
+ { "st2w", LONG_L, 1, MU, SEQ, 0x35000000, 0x3f100000, { RSRC2E, ATPAR, NUM16, RSRC } },
+ { "st2w", SHORT_2, 1, MU, PAR|WMEM, 0x6a00, 0x7e21, { RSRC2E, ATSIGN, RSRC } },
+ { "st2w", SHORT_2, 1, MU, PAR|WMEM, 0x6e1f, 0x7e3f, { RSRC2E, ATMINUS, RSRC } },
+ { "st2w", SHORT_2, 1, MU, PAR|WMEM, 0x6a01, 0x7e21, { RSRC2E, ATSIGN, RSRC, PLUS } },
+ { "st2w", SHORT_2, 1, MU, PAR|WMEM, 0x6e01, 0x7e21, { RSRC2E, ATSIGN, RSRC, MINUS } },
+ { "stb", LONG_L, 1, MU, SEQ, 0x3c000000, 0x3f000000, { RSRC2, ATPAR, NUM16, RSRC } },
+ { "stb", SHORT_2, 1, MU, PAR|WMEM, 0x7800, 0x7e01, { RSRC2, ATSIGN, RSRC } },
+ { "stop", SHORT_2, 1, MU, PAR, 0x5fe0, 0x7fff, { 0 } },
+ { "sub", SHORT_2, 1, EITHER, PAR|WCAR, 0x0, 0x7e01, { RDST, RSRC } },
+ { "sub", SHORT_2, 1, IU, PAR, 0x1001, 0x7ee3, { ADST, RSRC } },
+ { "sub", SHORT_2, 1, IU, PAR, 0x1003, 0x7eef, { ADST, ASRC } },
+ { "sub2w", SHORT_2, 1, IU, PAR|WCAR, 0x1000, 0x7e23, { RDSTE, RSRCE } },
+ { "subac3", LONG_R, 1, IU, SEQ, 0x17000000, 0x3ffffe22, { RDSTE, RSRCE, ASRC0 } },
+ { "subac3", LONG_R, 1, IU, SEQ, 0x17000002, 0x3ffffe2e, { RDSTE, ASRC, ASRC0 } },
+ { "subac3s", LONG_R, 1, IU, SEQ, 0x17001000, 0x3ffffe22, { RDSTE, RSRCE, ASRC0 } },
+ { "subac3s", LONG_R, 1, IU, SEQ, 0x17001002, 0x3ffffe2e, { RDSTE, ASRC, ASRC0 } },
+ { "subi", SHORT_2, 1, EITHER, PAR, 0x1, 0x7e01, { RDST, UNUM4S } },
+ { "trap", SHORT_2, 5, MU, BRANCH_LINK|PAR, 0x5f00, 0x7fe1, { UNUM4 } },
+ { "tst0i", LONG_L, 1, MU, SEQ, 0x7000000, 0x3f0f0000, { RSRC2, NUM16 } },
+ { "tst1i", LONG_L, 1, MU, SEQ, 0xf000000, 0x3f0f0000, { RSRC2, NUM16 } },
+ { "wait", SHORT_2, 1, MU, PAR, 0x5f80, 0x7fff, { 0 } },
+ { "xor", SHORT_2, 1, EITHER, PAR, 0xa00, 0x7e01, { RDST, RSRC } },
+ { "xor3", LONG_L, 1, MU, SEQ, 0x5000000, 0x3f000000, { RDST, RSRC, NUM16 } },
+ { 0, 0, 0, 0, 0, 0, 0, { 0 } },
+};
+
+
diff --git a/opcodes/d30v-dis.c b/opcodes/d30v-dis.c
new file mode 100644
index 00000000000..9358b753235
--- /dev/null
+++ b/opcodes/d30v-dis.c
@@ -0,0 +1,399 @@
+/* Disassemble D30V instructions.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "opcode/d30v.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+#define PC_MASK 0xFFFFFFFF
+
+static int lookup_opcode PARAMS (( struct d30v_insn *insn, long num, int is_long ));
+static void print_insn PARAMS (( struct disassemble_info *info, bfd_vma memaddr, long long num,
+ struct d30v_insn *insn, int is_long, int show_ext ));
+static int extract_value PARAMS (( long long num, struct d30v_operand *oper, int is_long ));
+
+int
+print_insn_d30v (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int status, result;
+ bfd_byte buffer[12];
+ unsigned long in1,in2;
+ struct d30v_insn insn;
+ long long num;
+
+ insn.form = (struct d30v_format *)NULL;
+
+ info->bytes_per_line = 8;
+ info->bytes_per_chunk = 4;
+ info->display_endian = BFD_ENDIAN_BIG;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ in1 = bfd_getb32 (buffer);
+
+ status = (*info->read_memory_func) (memaddr+4, buffer, 4, info);
+ if (status != 0)
+ {
+ info->bytes_per_line = 8;
+ if (!(result = lookup_opcode(&insn, in1, 0)))
+ (*info->fprintf_func) (info->stream, ".long\t0x%x",in1);
+ else
+ print_insn(info, memaddr, (long long) in1, &insn, 0, result);
+ return 4;
+ }
+ in2 = bfd_getb32 (buffer);
+
+ if (in1 & in2 & FM01)
+ {
+ /* LONG instruction */
+ if (!(result = lookup_opcode(&insn, in1, 1)))
+ {
+ (*info->fprintf_func) (info->stream, ".long\t0x%x,0x%x",in1,in2);
+ return 8;
+ }
+ num = (long long)in1 << 32 | in2;
+ print_insn(info, memaddr, num, &insn, 1, result);
+ }
+ else
+ {
+ num = in1;
+ if (!(result = lookup_opcode(&insn, in1, 0)))
+ (*info->fprintf_func) (info->stream, ".long\t0x%x",in1);
+ else
+ print_insn(info, memaddr, num, &insn, 0, result);
+
+ switch ( ((in1>>31)<<1) | (in2>>31) )
+ {
+ case 0:
+ (*info->fprintf_func) (info->stream, "\t||\t");
+ break;
+ case 1:
+ (*info->fprintf_func) (info->stream, "\t->\t");
+ break;
+ case 2:
+ (*info->fprintf_func) (info->stream, "\t<-\t");
+ default:
+ break;
+ }
+
+ insn.form = (struct d30v_format *)NULL;
+ num = in2;
+ if (!(result = lookup_opcode(&insn, in2, 0)))
+ (*info->fprintf_func) (info->stream, ".long\t0x%x",in2);
+ else
+ print_insn(info, memaddr, num, &insn, 0, result);
+
+ }
+ return 8;
+}
+
+
+/* returns 0 if lookup fails */
+/* 1 if found and only one form */
+/* 2 if found and there are short and long forms */
+static int
+lookup_opcode (insn, num, is_long)
+ struct d30v_insn *insn;
+ long num;
+ int is_long;
+{
+ int i=0, index;
+ struct d30v_format *f;
+ struct d30v_opcode *op = (struct d30v_opcode *)d30v_opcode_table;
+ int op1 = (num >> 25) & 0x7;
+ int op2 = (num >> 20) & 0x1f;
+ int mod = (num >> 18) & 0x3;
+
+ /* find the opcode */
+ do {
+ if ((op->op1 == op1) && (op->op2 == op2))
+ break;
+ op++;
+ } while (op->name);
+
+ if (!op || !op->name)
+ return 0;
+
+ while (op->op1 == op1 && op->op2 == op2)
+ {
+ /* scan through all the formats for the opcode */
+ index = op->format[i++];
+ do
+ {
+ f = (struct d30v_format *)&d30v_format_table[index];
+ while (f->form == index)
+ {
+ if ((!is_long || f->form >= LONG) && (f->modifier == mod))
+ {
+ insn->form = f;
+ break;
+ }
+ f++;
+ }
+ if (insn->form)
+ break;
+ } while ((index = op->format[i++]) != 0);
+ if (insn->form)
+ break;
+ op++;
+ i=0;
+ }
+ if (insn->form == NULL)
+ return 0;
+
+ insn->op = op;
+ insn->ecc = (num >> 28) & 0x7;
+ if (op->format[1])
+ return 2;
+ else
+ return 1;
+}
+
+
+static void
+print_insn ( info, memaddr, num, insn, is_long, show_ext )
+ struct disassemble_info *info;
+ bfd_vma memaddr;
+ long long num;
+ struct d30v_insn *insn;
+ int is_long;
+ int show_ext;
+{
+ int val, opnum, need_comma=0;
+ struct d30v_operand *oper;
+ int i, match, opind=0, need_paren=0, found_control=0;
+
+ (*info->fprintf_func) (info->stream, "%s",insn->op->name);
+
+ /* check for CMP or CMPU */
+ if (d30v_operand_table[insn->form->operands[0]].flags & OPERAND_NAME)
+ {
+ opind++;
+ val = extract_value(num,(struct d30v_operand *)&d30v_operand_table[insn->form->operands[0]],is_long);
+ (*info->fprintf_func) (info->stream, "%s",d30v_cc_names[val]);
+ }
+
+ /* add in ".s" or ".l" */
+ if (show_ext == 2)
+ {
+ if (is_long)
+ (*info->fprintf_func) (info->stream, ".l");
+ else
+ (*info->fprintf_func) (info->stream, ".s");
+ }
+
+ if (insn->ecc)
+ (*info->fprintf_func) (info->stream, "/%s",d30v_ecc_names[insn->ecc]);
+
+ (*info->fprintf_func) (info->stream, "\t");
+
+ while ((opnum = insn->form->operands[opind++]) != 0)
+ {
+ int bits;
+ oper = (struct d30v_operand *)&d30v_operand_table[opnum];
+ bits = oper->bits;
+ if (oper->flags & OPERAND_SHIFT)
+ bits += 3;
+
+ if (need_comma && oper->flags != OPERAND_PLUS && oper->flags != OPERAND_MINUS)
+ {
+ need_comma=0;
+ (*info->fprintf_func) (info->stream, ", ");
+ }
+
+ if (oper->flags == OPERAND_ATMINUS)
+ {
+ (*info->fprintf_func) (info->stream, "@-");
+ continue;
+ }
+ if (oper->flags == OPERAND_MINUS)
+ {
+ (*info->fprintf_func) (info->stream, "-");
+ continue;
+ }
+ if (oper->flags == OPERAND_PLUS)
+ {
+ (*info->fprintf_func) (info->stream, "+");
+ continue;
+ }
+ if (oper->flags == OPERAND_ATSIGN)
+ {
+ (*info->fprintf_func) (info->stream, "@");
+ continue;
+ }
+ if (oper->flags == OPERAND_ATPAR)
+ {
+ (*info->fprintf_func) (info->stream, "@(");
+ need_paren = 1;
+ continue;
+ }
+
+ if (oper->flags == OPERAND_SPECIAL)
+ continue;
+
+ val = extract_value(num, oper, is_long);
+
+ if (oper->flags & OPERAND_REG)
+ {
+ match = 0;
+ if (oper->flags & OPERAND_CONTROL)
+ {
+ struct d30v_operand *oper3 =
+ (struct d30v_operand *)&d30v_operand_table[insn->form->operands[2]];
+ int id = extract_value (num, oper3, is_long );
+ found_control = 1;
+ switch ( id )
+ {
+ case 0:
+ val |= OPERAND_CONTROL;
+ break;
+ case 1:
+ case 2:
+ val = OPERAND_CONTROL + MAX_CONTROL_REG + id;
+ break;
+ case 3:
+ val |= OPERAND_FLAG;
+ break;
+ default:
+ fprintf(stderr,"illegal id (%d)\n",id);
+ }
+ }
+ else if (oper->flags & OPERAND_ACC)
+ val |= OPERAND_ACC;
+ else if (oper->flags & OPERAND_FLAG)
+ val |= OPERAND_FLAG;
+ for (i=0;i<reg_name_cnt();i++)
+ {
+ if (val == pre_defined_registers[i].value)
+ {
+ if (pre_defined_registers[i].pname)
+ (*info->fprintf_func)
+ (info->stream, "%s",pre_defined_registers[i].pname);
+ else
+ (*info->fprintf_func)
+ (info->stream, "%s",pre_defined_registers[i].name);
+ match=1;
+ break;
+ }
+ }
+ if (match==0)
+ {
+ /* this would only get executed if a register was not in the
+ register table */
+ (*info->fprintf_func)
+ (info->stream, _("<unknown register %d>"), val & 0x3F);
+ }
+ }
+ else if (insn->op->reloc_flag == RELOC_PCREL ||
+ (opind == 1 && (insn->form->form == SHORT_D2 || insn->form->form == LONG_D)))
+ {
+ long max;
+ int neg=0;
+ max = (1 << (bits - 1));
+ if (val & max)
+ {
+ if (bits == 32)
+ val = -val;
+ else
+ val = -val & ((1 << bits)-1);
+ neg = 1;
+ }
+ if (opind == 1 && (insn->form->form == SHORT_D2 || insn->form->form == LONG_D))
+ {
+ (*info->fprintf_func) (info->stream, "%x",val);
+ }
+ else {
+ if (neg)
+ {
+ (*info->fprintf_func) (info->stream, "-%x\t(",val);
+ (*info->print_address_func) ((memaddr - val) & PC_MASK, info);
+ (*info->fprintf_func) (info->stream, ")");
+ }
+ else
+ {
+ (*info->fprintf_func) (info->stream, "%x\t(",val);
+ (*info->print_address_func) ((memaddr + val) & PC_MASK, info);
+ (*info->fprintf_func) (info->stream, ")");
+ }
+ }
+ }
+ else if (insn->op->reloc_flag == RELOC_ABS)
+ {
+ (*info->print_address_func) (val, info);
+ }
+ else
+ {
+ if (oper->flags & OPERAND_SIGNED)
+ {
+ int max = (1 << (bits - 1));
+ if (val & max)
+ {
+ val = -val;
+ if (bits < 32)
+ val &= ((1 << bits) - 1);
+ (*info->fprintf_func) (info->stream, "-");
+ }
+ }
+ (*info->fprintf_func) (info->stream, "0x%x",val);
+ }
+ /* if there is another operand, then write a comma and space */
+ if (insn->form->operands[opind] && !(found_control && opind == 2))
+ need_comma = 1;
+ }
+ if (need_paren)
+ (*info->fprintf_func) (info->stream, ")");
+}
+
+
+
+static int
+extract_value (num, oper, is_long)
+ long long num;
+ struct d30v_operand *oper;
+ int is_long;
+{
+ int val;
+ int shift = 12 - oper->position;
+ int mask = (0xFFFFFFFF >> (32 - oper->bits));
+
+ if (is_long)
+ {
+ if (oper->bits == 32)
+ {
+ /* piece together 32-bit constant */
+ val = ((num & 0x3FFFF)
+ | ((num & 0xFF00000) >> 2)
+ | ((num & 0x3F00000000LL) >> 6));
+ }
+ else
+ val = (num >> (32 + shift)) & mask;
+ }
+ else
+ val = (num >> shift) & mask;
+
+ if (oper->flags & OPERAND_SHIFT)
+ val <<= 3;
+
+ return val;
+}
diff --git a/opcodes/d30v-opc.c b/opcodes/d30v-opc.c
new file mode 100644
index 00000000000..2265e7cf81f
--- /dev/null
+++ b/opcodes/d30v-opc.c
@@ -0,0 +1,500 @@
+/* d30v-opc.c -- D30V opcode list
+ Copyright 1997, 1998 Free Software Foundation, Inc.
+ Written by Martin Hunt, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/d30v.h"
+
+
+/* This table is sorted. */
+/* If you add anything, it MUST be in alphabetical order */
+/* The first field is the name the assembler uses when looking */
+/* up orcodes. The second field is the name the disassembler will use. */
+/* This allows the assembler to assemble references to r63 (for example) */
+/* or "sp". The disassembler will always use the preferred form (sp) */
+const struct pd_reg pre_defined_registers[] =
+{
+ { "a0", NULL, OPERAND_ACC+0 },
+ { "a1", NULL, OPERAND_ACC+1 },
+ { "bpc", NULL, OPERAND_CONTROL+3 },
+ { "bpsw", NULL, OPERAND_CONTROL+1 },
+ { "c", "c", OPERAND_FLAG+7 },
+ { "cr0", "psw", OPERAND_CONTROL },
+ { "cr1", "bpsw", OPERAND_CONTROL+1 },
+ { "cr10", "mod_s", OPERAND_CONTROL+10 },
+ { "cr11", "mod_e", OPERAND_CONTROL+11 },
+ { "cr12", NULL, OPERAND_CONTROL+12 },
+ { "cr13", NULL, OPERAND_CONTROL+13 },
+ { "cr14", "iba", OPERAND_CONTROL+14 },
+ { "cr15", "eit_vb", OPERAND_CONTROL+15 },
+ { "cr16", "int_s", OPERAND_CONTROL+16 },
+ { "cr17", "int_m", OPERAND_CONTROL+17 },
+ { "cr18", NULL, OPERAND_CONTROL+18 },
+ { "cr19", NULL, OPERAND_CONTROL+19 },
+ { "cr2", "pc", OPERAND_CONTROL+2 },
+ { "cr20", NULL, OPERAND_CONTROL+20 },
+ { "cr21", NULL, OPERAND_CONTROL+21 },
+ { "cr22", NULL, OPERAND_CONTROL+22 },
+ { "cr23", NULL, OPERAND_CONTROL+23 },
+ { "cr24", NULL, OPERAND_CONTROL+24 },
+ { "cr25", NULL, OPERAND_CONTROL+25 },
+ { "cr26", NULL, OPERAND_CONTROL+26 },
+ { "cr27", NULL, OPERAND_CONTROL+27 },
+ { "cr28", NULL, OPERAND_CONTROL+28 },
+ { "cr29", NULL, OPERAND_CONTROL+29 },
+ { "cr3", "bpc", OPERAND_CONTROL+3 },
+ { "cr30", NULL, OPERAND_CONTROL+30 },
+ { "cr31", NULL, OPERAND_CONTROL+31 },
+ { "cr32", NULL, OPERAND_CONTROL+32 },
+ { "cr33", NULL, OPERAND_CONTROL+33 },
+ { "cr34", NULL, OPERAND_CONTROL+34 },
+ { "cr35", NULL, OPERAND_CONTROL+35 },
+ { "cr36", NULL, OPERAND_CONTROL+36 },
+ { "cr37", NULL, OPERAND_CONTROL+37 },
+ { "cr38", NULL, OPERAND_CONTROL+38 },
+ { "cr39", NULL, OPERAND_CONTROL+39 },
+ { "cr4", "dpsw", OPERAND_CONTROL+4 },
+ { "cr40", NULL, OPERAND_CONTROL+40 },
+ { "cr41", NULL, OPERAND_CONTROL+41 },
+ { "cr42", NULL, OPERAND_CONTROL+42 },
+ { "cr43", NULL, OPERAND_CONTROL+43 },
+ { "cr44", NULL, OPERAND_CONTROL+44 },
+ { "cr45", NULL, OPERAND_CONTROL+45 },
+ { "cr46", NULL, OPERAND_CONTROL+46 },
+ { "cr47", NULL, OPERAND_CONTROL+47 },
+ { "cr48", NULL, OPERAND_CONTROL+48 },
+ { "cr49", NULL, OPERAND_CONTROL+49 },
+ { "cr5","dpc", OPERAND_CONTROL+5 },
+ { "cr50", NULL, OPERAND_CONTROL+50 },
+ { "cr51", NULL, OPERAND_CONTROL+51 },
+ { "cr52", NULL, OPERAND_CONTROL+52 },
+ { "cr53", NULL, OPERAND_CONTROL+53 },
+ { "cr54", NULL, OPERAND_CONTROL+54 },
+ { "cr55", NULL, OPERAND_CONTROL+55 },
+ { "cr56", NULL, OPERAND_CONTROL+56 },
+ { "cr57", NULL, OPERAND_CONTROL+57 },
+ { "cr58", NULL, OPERAND_CONTROL+58 },
+ { "cr59", NULL, OPERAND_CONTROL+59 },
+ { "cr6", NULL, OPERAND_CONTROL+6 },
+ { "cr60", NULL, OPERAND_CONTROL+60 },
+ { "cr61", NULL, OPERAND_CONTROL+61 },
+ { "cr62", NULL, OPERAND_CONTROL+62 },
+ { "cr63", NULL, OPERAND_CONTROL+63 },
+ { "cr7", "rpt_c", OPERAND_CONTROL+7 },
+ { "cr8", "rpt_s", OPERAND_CONTROL+8 },
+ { "cr9", "rpt_e", OPERAND_CONTROL+9 },
+ { "dpc", NULL, OPERAND_CONTROL+5 },
+ { "dpsw", NULL, OPERAND_CONTROL+4 },
+ { "eit_vb", NULL, OPERAND_CONTROL+15 },
+ { "f0", NULL, OPERAND_FLAG+0 },
+ { "f1", NULL, OPERAND_FLAG+1 },
+ { "f2", NULL, OPERAND_FLAG+2 },
+ { "f3", NULL, OPERAND_FLAG+3 },
+ { "f4", "s", OPERAND_FLAG+4 },
+ { "f5", "v", OPERAND_FLAG+5 },
+ { "f6", "va", OPERAND_FLAG+6 },
+ { "f7", "c", OPERAND_FLAG+7 },
+ { "iba", NULL, OPERAND_CONTROL+14 },
+ { "int_m", NULL, OPERAND_CONTROL+17 },
+ { "int_s", NULL, OPERAND_CONTROL+16 },
+ { "link", "r62", 62 },
+ { "mod_e", NULL, OPERAND_CONTROL+11 },
+ { "mod_s", NULL, OPERAND_CONTROL+10 },
+ { "pc", NULL, OPERAND_CONTROL+2 },
+ { "psw", NULL, OPERAND_CONTROL },
+ { "pswh", NULL, OPERAND_CONTROL+MAX_CONTROL_REG+2 },
+ { "pswl", NULL, OPERAND_CONTROL+MAX_CONTROL_REG+1 },
+ { "r0", NULL, 0 },
+ { "r1", NULL, 1 },
+ { "r10", NULL, 10 },
+ { "r11", NULL, 11 },
+ { "r12", NULL, 12 },
+ { "r13", NULL, 13 },
+ { "r14", NULL, 14 },
+ { "r15", NULL, 15 },
+ { "r16", NULL, 16 },
+ { "r17", NULL, 17 },
+ { "r18", NULL, 18 },
+ { "r19", NULL, 19 },
+ { "r2", NULL, 2 },
+ { "r20", NULL, 20 },
+ { "r21", NULL, 21 },
+ { "r22", NULL, 22 },
+ { "r23", NULL, 23 },
+ { "r24", NULL, 24 },
+ { "r25", NULL, 25 },
+ { "r26", NULL, 26 },
+ { "r27", NULL, 27 },
+ { "r28", NULL, 28 },
+ { "r29", NULL, 29 },
+ { "r3", NULL, 3 },
+ { "r30", NULL, 30 },
+ { "r31", NULL, 31 },
+ { "r32", NULL, 32 },
+ { "r33", NULL, 33 },
+ { "r34", NULL, 34 },
+ { "r35", NULL, 35 },
+ { "r36", NULL, 36 },
+ { "r37", NULL, 37 },
+ { "r38", NULL, 38 },
+ { "r39", NULL, 39 },
+ { "r4", NULL, 4 },
+ { "r40", NULL, 40 },
+ { "r41", NULL, 41 },
+ { "r42", NULL, 42 },
+ { "r43", NULL, 43 },
+ { "r44", NULL, 44 },
+ { "r45", NULL, 45 },
+ { "r46", NULL, 46 },
+ { "r47", NULL, 47 },
+ { "r48", NULL, 48 },
+ { "r49", NULL, 49 },
+ { "r5", NULL, 5 },
+ { "r50", NULL, 50 },
+ { "r51", NULL, 51 },
+ { "r52", NULL, 52 },
+ { "r53", NULL, 53 },
+ { "r54", NULL, 54 },
+ { "r55", NULL, 55 },
+ { "r56", NULL, 56 },
+ { "r57", NULL, 57 },
+ { "r58", NULL, 58 },
+ { "r59", NULL, 59 },
+ { "r6", NULL, 6 },
+ { "r60", NULL, 60 },
+ { "r61", NULL, 61 },
+ { "r62", "link", 62 },
+ { "r63", "sp", 63 },
+ { "r7", NULL, 7 },
+ { "r8", NULL, 8 },
+ { "r9", NULL, 9 },
+ { "rpt_c", NULL, OPERAND_CONTROL+7 },
+ { "rpt_e", NULL, OPERAND_CONTROL+9 },
+ { "rpt_s", NULL, OPERAND_CONTROL+8 },
+ { "s", NULL, OPERAND_FLAG+4 },
+ { "sp", NULL, 63 },
+ { "v", NULL, OPERAND_FLAG+5 },
+ { "va", NULL, OPERAND_FLAG+6 },
+};
+
+int
+reg_name_cnt()
+{
+ return (sizeof(pre_defined_registers) / sizeof(struct pd_reg));
+}
+
+/* OPCODE TABLE */
+/* The format of this table is defined in opcode/d30v.h */
+const struct d30v_opcode d30v_opcode_table[] = {
+ { "abs", IALU1, 0x8, { SHORT_U }, EITHER, 0, 0, 0 },
+ { "add", IALU1, 0x0, { SHORT_A, LONG}, EITHER, 0, FLAG_CVVA, 0 },
+ { "add2h", IALU1, 0x1, { SHORT_A, LONG}, EITHER, 0, 0, 0 },
+ { "addc", IALU1, 0x4, { SHORT_A, LONG }, EITHER, FLAG_C, FLAG_CVVA, 0 },
+ { "addhlll", IALU1, 0x10, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhllh", IALU1, 0x11, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhlhl", IALU1, 0x12, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhlhh", IALU1, 0x13, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhhll", IALU1, 0x14, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhhlh", IALU1, 0x15, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhhhl", IALU1, 0x16, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "addhhhh", IALU1, 0x17, { SHORT_A, LONG }, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "adds", IALU1, 0x6, { SHORT_A, LONG }, EITHER, 0, FLAG_CVVA, 0 },
+ { "adds2h", IALU1, 0x7, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "and", LOGIC, 0x18, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "andfg", LOGIC, 0x8, { SHORT_F }, EITHER, 0, 0, 0 },
+ { "avg", IALU1, 0xa, { SHORT_A, LONG}, EITHER, 0, 0, 0 },
+ { "avg2h", IALU1, 0xb, { SHORT_A, LONG}, EITHER, 0, 0, 0 },
+ { "bclr", LOGIC, 0x3, { SHORT_A }, EITHER_BUT_PREFER_MU, 0, 0, 0 },
+ { "bnot", LOGIC, 0x1, { SHORT_A }, EITHER_BUT_PREFER_MU, 0, 0, 0 },
+ { "bra", BRA, 0, { SHORT_B1, SHORT_B2, LONG_U }, MU, FLAG_JMP, 0, RELOC_PCREL },
+ { "bratnz", BRA, 0x4, { SHORT_B3b, LONG_2b }, MU, FLAG_JMP, 0, RELOC_PCREL },
+ { "bratzr", BRA, 0x4, { SHORT_B3, LONG_2 }, MU, FLAG_JMP, 0, RELOC_PCREL },
+ { "bset", LOGIC, 0x2, { SHORT_A }, EITHER_BUT_PREFER_MU, 0, 0, 0 },
+ { "bsr", BRA, 0x2, { SHORT_B1, SHORT_B2, LONG_U }, MU, FLAG_JSR, 0, RELOC_PCREL },
+ { "bsrtnz", BRA, 0x6, { SHORT_B3b, LONG_2b }, MU, FLAG_JSR, 0, RELOC_PCREL },
+ { "bsrtzr", BRA, 0x6, { SHORT_B3, LONG_2 }, MU, FLAG_JSR, 0, RELOC_PCREL },
+ { "btst", LOGIC, 0, { SHORT_AF }, EITHER_BUT_PREFER_MU, 0, 0, 0 },
+ { "cmp", LOGIC, 0xC, { SHORT_CMP, LONG_CMP }, EITHER, 0, 0, 0 },
+ { "cmpu", LOGIC, 0xD, { SHORT_CMPU, LONG_CMP }, EITHER, 0, 0, 0 },
+ { "dbra", BRA, 0x10, { SHORT_B3, LONG_2 }, MU, FLAG_JMP | FLAG_DELAY, FLAG_RP, RELOC_PCREL },
+ { "dbrai", BRA, 0x14, { SHORT_D2, LONG_D }, MU, FLAG_JMP | FLAG_DELAY, FLAG_RP, RELOC_PCREL },
+ { "dbsr", BRA, 0x12, { SHORT_B3, LONG_2 }, MU, FLAG_JSR | FLAG_DELAY, FLAG_RP, RELOC_PCREL },
+ { "dbsri", BRA, 0x16, { SHORT_D2, LONG_D }, MU, FLAG_JSR | FLAG_DELAY, FLAG_RP, RELOC_PCREL },
+ { "dbt", BRA, 0xb, { SHORT_NONE }, MU, FLAG_JSR, FLAG_LKR, 0 },
+ { "djmp", BRA, 0x11, { SHORT_B3, LONG_2 }, MU, FLAG_JMP | FLAG_DELAY, FLAG_RP, RELOC_ABS },
+ { "djmpi", BRA, 0x15, { SHORT_D2, LONG_D }, MU, FLAG_JMP | FLAG_DELAY, FLAG_RP, RELOC_ABS },
+ { "djsr", BRA, 0x13, { SHORT_B3, LONG_2 }, MU, FLAG_JSR | FLAG_DELAY, FLAG_RP, RELOC_ABS },
+ { "djsri", BRA, 0x17, { SHORT_D2, LONG_D }, MU, FLAG_JSR | FLAG_DELAY, FLAG_RP, RELOC_ABS },
+ { "jmp", BRA, 0x1, { SHORT_B1, SHORT_B2, LONG_U }, MU, FLAG_JMP, 0, RELOC_ABS },
+ { "jmptnz", BRA, 0x5, { SHORT_B3b, LONG_2b }, MU, FLAG_JMP, 0, RELOC_ABS },
+ { "jmptzr", BRA, 0x5, { SHORT_B3, LONG_2 }, MU, FLAG_JMP, 0, RELOC_ABS },
+ { "joinll", IALU1, 0xC, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "joinlh", IALU1, 0xD, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "joinhl", IALU1, 0xE, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "joinhh", IALU1, 0xF, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "jsr", BRA, 0x3, { SHORT_B1, SHORT_B2, LONG_U }, MU, FLAG_JSR, 0, RELOC_ABS },
+ { "jsrtnz", BRA, 0x7, { SHORT_B3b, LONG_2b }, MU, FLAG_JSR, 0, RELOC_ABS },
+ { "jsrtzr", BRA, 0x7, { SHORT_B3, LONG_2 }, MU, FLAG_JSR, 0, RELOC_ABS },
+ { "ld2h", IMEM, 0x3, { SHORT_M2, LONG_M2 }, MU, FLAG_MEM, 0, 0 },
+ { "ld2w", IMEM, 0x6, { SHORT_M2, LONG_M2 }, MU, FLAG_MEM | FLAG_2WORD, 0, 0 },
+ { "ld4bh", IMEM, 0x5, { SHORT_M2, LONG_M2 }, MU, FLAG_MEM | FLAG_2WORD, 0, 0 },
+ { "ld4bhu", IMEM, 0xd, { SHORT_M2, LONG_M2 }, MU, FLAG_MEM, 0, 0 },
+ { "ldb", IMEM, 0, { SHORT_M, LONG_M }, MU, FLAG_MEM, 0, 0 },
+ { "ldbu", IMEM, 0x9, { SHORT_M, LONG_M }, MU, FLAG_MEM, 0, 0 },
+ { "ldh", IMEM, 0x2, { SHORT_M, LONG_M }, MU, FLAG_MEM, 0, 0 },
+ { "ldhh", IMEM, 0x1, { SHORT_M, LONG_M }, MU, FLAG_MEM, 0, 0 },
+ { "ldhu", IMEM, 0xa, { SHORT_M, LONG_M }, MU, FLAG_MEM, 0, 0 },
+ { "ldw", IMEM, 0x4, { SHORT_M, LONG_M }, MU, FLAG_MEM, 0, 0 },
+ { "mac0", IALU2, 0x14, { SHORT_A }, IU, FLAG_MUL32, 0, 0 },
+ { "mac1", IALU2, 0x14, { SHORT_A1 }, IU, FLAG_MUL32, 0, 0 },
+ { "macs0", IALU2, 0x15, { SHORT_A }, IU, FLAG_MUL32, 0, 0 },
+ { "macs1", IALU2, 0x15, { SHORT_A1 }, IU, FLAG_MUL32, 0, 0 },
+ { "moddec", IMEM, 0x7, { SHORT_MODDEC }, MU, 0, 0, 0 },
+ { "modinc", IMEM, 0x7, { SHORT_MODINC }, MU, 0, 0, 0 },
+ { "msub0", IALU2, 0x16, { SHORT_A }, IU, FLAG_MUL32, 0, 0 },
+ { "msub1", IALU2, 0x16, { SHORT_A1 }, IU, FLAG_MUL32, 0, 0 },
+ { "msubs0", IALU2, 0x17, { SHORT_A }, IU, FLAG_MUL32, 0, 0 },
+ { "msubs1", IALU2, 0x17, { SHORT_A1 }, IU, FLAG_MUL32, 0, 0 },
+ { "mul", IALU2, 0x10, { SHORT_A }, IU, FLAG_MUL32, 0, 0 },
+ { "mul2h", IALU2, 0, { SHORT_A }, IU, FLAG_MUL16, 0, 0 },
+ { "mulhxll", IALU2, 0x4, { SHORT_A }, IU, FLAG_MUL16, 0, 0 },
+ { "mulhxlh", IALU2, 0x5, { SHORT_A }, IU, FLAG_MUL16, 0, 0 },
+ { "mulhxhl", IALU2, 0x6, { SHORT_A }, IU, FLAG_MUL16, 0, 0 },
+ { "mulhxhh", IALU2, 0x7, { SHORT_A }, IU, FLAG_MUL16, 0, 0 },
+ { "mulx", IALU2, 0x18, { SHORT_AA }, IU, FLAG_MUL32, 0, 0 },
+ { "mulx2h", IALU2, 0x1, { SHORT_A2 }, IU, FLAG_MUL16, 0, 0 },
+ { "mulxs", IALU2, 0x19, { SHORT_AA }, IU, FLAG_MUL32, 0, 0 },
+ { "mvfacc", IALU2, 0x1f, { SHORT_RA }, IU, 0, 0, 0 },
+ { "mvfsys", BRA, 0x1e, { SHORT_C1 }, MU, FLAG_ALL, FLAG_ALL, 0 },
+ { "mvtacc", IALU2, 0xf, { SHORT_AA }, IU, 0, 0, 0 },
+ { "mvtsys", BRA, 0xe, { SHORT_C2 }, MU, FLAG_ALL, FLAG_ALL, 0 },
+ { "nop", BRA, 0xF, { SHORT_NONE }, EITHER, 0, 0, 0 },
+ { "not", LOGIC, 0x19, { SHORT_U }, EITHER, 0, 0, 0 },
+ { "notfg", LOGIC, 0x9, { SHORT_UF }, EITHER, 0, 0, 0 },
+ { "or", LOGIC, 0x1a, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "orfg", LOGIC, 0xa, { SHORT_F }, EITHER, 0, 0, 0 },
+ { "reit", BRA, 0x8, { SHORT_NONE }, MU, FLAG_SM | FLAG_JMP, FLAG_SM | FLAG_LKR, 0 },
+ { "repeat", BRA, 0x18, { SHORT_D1, LONG_2 }, MU, FLAG_RP, FLAG_RP, RELOC_PCREL },
+ { "repeati", BRA, 0x1a, { SHORT_D2B, LONG_Db }, MU, FLAG_RP, FLAG_RP, RELOC_PCREL },
+ { "rot", LOGIC, 0x14, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "rot2h", LOGIC, 0x15, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "rtd", BRA, 0xa, { SHORT_NONE }, MU, FLAG_JMP, FLAG_LKR, 0 },
+ { "sat", IALU2, 0x8, { SHORT_A5 }, IU, 0, 0, 0 },
+ { "sat2h", IALU2, 0x9, { SHORT_A5 }, IU, 0, 0, 0 },
+ { "sathl", IALU2, 0x1c, { SHORT_A5 }, IU, FLAG_ADDSUBppp, 0, 0 },
+ { "sathh", IALU2, 0x1d, { SHORT_A5 }, IU, FLAG_ADDSUBppp, 0, 0 },
+ { "satz", IALU2, 0xa, { SHORT_A5 }, IU, 0, 0, 0 },
+ { "satz2h", IALU2, 0xb, { SHORT_A5 }, IU, 0, 0, 0 },
+ { "sra", LOGIC, 0x10, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "sra2h", LOGIC, 0x11, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "srahh", LOGIC, 0x5, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "srahl", LOGIC, 0x4, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "src", LOGIC, 0x16, { SHORT_A }, EITHER, FLAG_ADDSUBppp, 0, 0 },
+ { "srl", LOGIC, 0x12, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "srl2h", LOGIC, 0x13, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "srlhh", LOGIC, 0x7, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "srlhl", LOGIC, 0x6, { SHORT_A }, EITHER, 0, 0, 0 },
+ { "st2h", IMEM, 0x13, { SHORT_M2, LONG_M2 }, MU, 0, FLAG_MEM, 0 },
+ { "st2w", IMEM, 0x16, { SHORT_M2, LONG_M2 }, MU, 0, FLAG_MEM | FLAG_2WORD, 0 },
+ { "st4hb", IMEM, 0x15, { SHORT_M2, LONG_M2 }, MU, 0, FLAG_MEM | FLAG_2WORD, 0 },
+ { "stb", IMEM, 0x10, { SHORT_M, LONG_M }, MU, 0, FLAG_MEM, 0 },
+ { "sth", IMEM, 0x12, { SHORT_M, LONG_M }, MU, 0, FLAG_MEM, 0 },
+ { "sthh", IMEM, 0x11, { SHORT_M, LONG_M }, MU, 0, FLAG_MEM, 0 },
+ { "stw", IMEM, 0x14, { SHORT_M, LONG_M }, MU, 0, FLAG_MEM, 0 },
+ { "sub", IALU1, 0x2, { SHORT_A, LONG}, EITHER, 0, FLAG_CVVA, 0 },
+ { "sub2h", IALU1, 0x3, { SHORT_A, LONG}, EITHER, 0, 0, 0 },
+ { "subb", IALU1, 0x5, { SHORT_A, LONG}, EITHER, FLAG_C, FLAG_CVVA, 0 },
+ { "subhlll", IALU1, 0x18, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhllh", IALU1, 0x19, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhlhl", IALU1, 0x1a, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhlhh", IALU1, 0x1b, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhhll", IALU1, 0x1c, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhhlh", IALU1, 0x1d, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhhhl", IALU1, 0x1e, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "subhhhh", IALU1, 0x1f, { SHORT_A, LONG}, EITHER, FLAG_ADDSUBppp, FLAG_CVVA, 0 },
+ { "trap", BRA, 0x9, { SHORT_B1, SHORT_T}, MU, FLAG_JSR, FLAG_SM | FLAG_LKR, 0 },
+ { "xor", LOGIC, 0x1b, { SHORT_A, LONG }, EITHER, 0, 0, 0 },
+ { "xorfg", LOGIC, 0xb, { SHORT_F }, EITHER, 0, 0, 0 },
+ { NULL, 0, 0, { 0 }, 0, 0, 0, 0 },
+};
+
+
+/* now define the operand types */
+/* format is length, bits, position, flags */
+const struct d30v_operand d30v_operand_table[] =
+{
+#define UNUSED (0)
+ { 0, 0, 0, 0 },
+#define Ra (UNUSED + 1)
+ { 6, 6, 0, OPERAND_REG|OPERAND_DEST },
+#define Ra2 (Ra + 1)
+ { 6, 6, 0, OPERAND_REG|OPERAND_DEST|OPERAND_2REG },
+#define Ra3 (Ra2 + 1)
+ { 6, 6, 0, OPERAND_REG },
+#define Rb (Ra3 + 1)
+ { 6, 6, 6, OPERAND_REG },
+#define Rc (Rb + 1)
+ { 6, 6, 12, OPERAND_REG },
+#define Aa (Rc + 1)
+ { 6, 1, 0, OPERAND_ACC|OPERAND_REG|OPERAND_DEST },
+#define Ab (Aa + 1)
+ { 6, 1, 6, OPERAND_ACC|OPERAND_REG },
+#define IMM5 (Ab + 1)
+ { 6, 5, 12, OPERAND_NUM },
+#define IMM5U (IMM5 + 1)
+ { 6, 5, 12, OPERAND_NUM|OPERAND_SIGNED },
+#define IMM5S3 (IMM5U + 1)
+ { 6, 5, 12, OPERAND_NUM|OPERAND_SIGNED },
+#define IMM6 (IMM5S3 + 1)
+ { 6, 6, 12, OPERAND_NUM|OPERAND_SIGNED },
+#define IMM6U (IMM6 + 1)
+ { 6, 6, 0, OPERAND_NUM },
+#define IMM6U2 (IMM6U + 1)
+ { 6, 6, 12, OPERAND_NUM },
+#define IMM6S3 (IMM6U2 + 1)
+ { 6, 6, 0, OPERAND_NUM|OPERAND_SHIFT },
+#define IMM12S3 (IMM6S3 + 1)
+ { 12, 12, 12, OPERAND_NUM|OPERAND_SIGNED|OPERAND_SHIFT },
+#define IMM12S3U (IMM12S3 + 1)
+ { 12, 12, 12, OPERAND_NUM|OPERAND_SHIFT },
+#define IMM18S3 (IMM12S3U + 1)
+ { 18, 18, 12, OPERAND_NUM|OPERAND_SIGNED|OPERAND_SHIFT },
+#define IMM32 (IMM18S3 + 1)
+ { 32, 32, 0, OPERAND_NUM },
+#define Fa (IMM32 + 1)
+ { 6, 3, 0, OPERAND_REG | OPERAND_FLAG | OPERAND_DEST },
+#define Fb (Fa + 1)
+ { 6, 3, 6, OPERAND_REG | OPERAND_FLAG },
+#define Fc (Fb + 1)
+ { 6, 3, 12, OPERAND_REG | OPERAND_FLAG },
+#define ATSIGN (Fc + 1)
+ { 0, 0, 0, OPERAND_ATSIGN},
+#define ATPAR (ATSIGN + 1) /* "@(" */
+ { 0, 0, 0, OPERAND_ATPAR},
+#define PLUS (ATPAR + 1) /* postincrement */
+ { 0, 0, 0, OPERAND_PLUS},
+#define MINUS (PLUS + 1) /* postdecrement */
+ { 0, 0, 0, OPERAND_MINUS},
+#define ATMINUS (MINUS + 1) /* predecrement */
+ { 0, 0, 0, OPERAND_ATMINUS},
+#define Ca (ATMINUS + 1) /* control register */
+ { 6, 6, 0, OPERAND_REG|OPERAND_CONTROL|OPERAND_DEST},
+#define Cb (Ca + 1) /* control register */
+ { 6, 6, 6, OPERAND_REG|OPERAND_CONTROL},
+#define CC (Cb + 1) /* condition code (CMPcc and CMPUcc) */
+ { 3, 3, -3, OPERAND_NAME},
+#define Fa2 (CC + 1) /* flag register (CMPcc and CMPUcc) */
+ { 3, 3, 0, OPERAND_REG|OPERAND_FLAG|OPERAND_DEST},
+#define Fake (Fa2 + 1) /* place holder for "id" field in mvfsys and mvtsys */
+ { 6, 2, 12, OPERAND_SPECIAL},
+};
+
+/* now we need to define the instruction formats */
+const struct d30v_format d30v_format_table[] =
+{
+ { 0, 0, { 0 } },
+ { SHORT_M, 0, { Ra, ATPAR, Rb, Rc } }, /* Ra,@(Rb,Rc) */
+ { SHORT_M, 1, { Ra, ATPAR, Rb, PLUS, Rc } }, /* Ra,@(Rb+,Rc) */
+ { SHORT_M, 2, { Ra, ATPAR, Rb, IMM6 } }, /* Ra,@(Rb,imm6) */
+ { SHORT_M, 3, { Ra, ATPAR, Rb, MINUS, Rc } }, /* Ra,@(Rb-,Rc) */
+ { SHORT_M2, 0, { Ra2, ATPAR, Rb, Rc } }, /* Ra,@(Rb,Rc) */
+ { SHORT_M2, 1, { Ra2, ATPAR, Rb, PLUS, Rc } }, /* Ra,@(Rb+,Rc) */
+ { SHORT_M2, 2, { Ra2, ATPAR, Rb, IMM6 } }, /* Ra,@(Rb,imm6) */
+ { SHORT_M2, 3, { Ra2, ATPAR, Rb, MINUS, Rc } }, /* Ra,@(Rb-,Rc) */
+ { SHORT_A, 0, { Ra, Rb, Rc } }, /* Ra,Rb,Rc */
+ { SHORT_A, 2, { Ra, Rb, IMM6 } }, /* Ra,Rb,imm6 */
+ { SHORT_B1, 0, { Rc } }, /* Rc */
+ { SHORT_B2, 2, { IMM18S3 } }, /* imm18 */
+ { SHORT_B3, 0, { Ra3, Rc } }, /* Ra,Rc */
+ { SHORT_B3, 2, { Ra3, IMM12S3 } }, /* Ra,imm12 */
+ { SHORT_B3b, 1, { Ra3, Rc } }, /* Ra,Rc */
+ { SHORT_B3b, 3, { Ra3, IMM12S3 } }, /* Ra,imm12 */
+ { SHORT_D1, 0, { Ra, Rc } }, /* Ra,Rc */
+ { SHORT_D1, 2, { Ra, IMM12S3 } }, /* Ra,imm12s3 */
+ { SHORT_D2, 0, { IMM6S3, Rc } }, /* imm6s3,Rc */
+ { SHORT_D2, 2, { IMM6S3, IMM12S3 } }, /* imm6s3,imm12s3 */
+ { SHORT_D2B, 0, { IMM6U, Rc } }, /* imm6u,Rc */
+ { SHORT_D2B, 2, { IMM6U, IMM12S3U } }, /* imm6u,imm12s3u */
+ { SHORT_U, 0, { Ra, Rb } }, /* Ra,Rb */
+ { SHORT_U, 2, { Ra, IMM12S3 } }, /* Ra,imm12 (repeat) */
+ { SHORT_F, 0, { Fa, Fb, Fc } }, /* Fa,Fb,Fc (orfg, xorfg) */
+ { SHORT_F, 2, { Fa, Fb, IMM6 } }, /* Fa,Fb,imm6 */
+ { SHORT_AF, 0, { Fa, Rb, Rc } }, /* Fa,Rb,Rc */
+ { SHORT_AF, 2, { Fa, Rb, IMM6 } }, /* Fa,Rb,imm6 */
+ { SHORT_T, 2, { IMM5 } }, /* imm5s3 (trap) */
+ { SHORT_A5, 0, { Ra, Rb, Rc } }, /* Ra,Rb,Rc */
+ { SHORT_A5, 2, { Ra, Rb, IMM5 } }, /* Ra,Rb,imm5 (sat*) */
+ { SHORT_CMP, 0, { CC, Fa2, Rb, Rc} }, /* CC Fa2,Rb,Rc */
+ { SHORT_CMP, 2, { CC, Fa2, Rb, IMM6} }, /* CC Fa2,Rb,imm6 */
+ { SHORT_CMPU, 0, { CC, Fa2, Rb, Rc} }, /* CC Fa2,Rb,Rc */
+ { SHORT_CMPU, 2, { CC, Fa2, Rb, IMM6U2} }, /* CC Fa2,Rb,imm6 */
+ { SHORT_A1, 1, { Ra, Rb, Rc } }, /* Ra,Rb,Rc for MAC where a=1 */
+ { SHORT_A1, 3, { Ra, Rb, IMM6 } }, /* Ra,Rb,imm6 for MAC where a=1 */
+ { SHORT_AA, 0, { Aa, Rb, Rc } }, /* Aa,Rb,Rc */
+ { SHORT_AA, 2, { Aa, Rb, IMM6 } }, /* Aa,Rb,imm6 */
+ { SHORT_RA, 0, { Ra, Ab, Rc } }, /* Ra,Ab,Rc */
+ { SHORT_RA, 2, { Ra, Ab, IMM6U2 } }, /* Ra,Ab,imm6u */
+ { SHORT_MODINC, 1, { Rb, IMM5 } }, /* Rb,imm5 (modinc) */
+ { SHORT_MODDEC, 3, { Rb, IMM5 } }, /* Rb,imm5 (moddec) */
+ { SHORT_C1, 0, { Ra, Cb, Fake } }, /* Ra,Cb (mvfsys) */
+ { SHORT_C2, 0, { Ca, Rb, Fake } }, /* Ca,Rb (mvtsys) */
+ { SHORT_UF, 0, { Fa, Fb } }, /* Fa,Fb (notfg) */
+ { SHORT_A2, 0, { Ra2, Rb, Rc } }, /* Ra2,Rb,Rc */
+ { SHORT_A2, 2, { Ra2, Rb, IMM6 } }, /* Ra2,Rb,imm6 */
+ { SHORT_A5S, 0, { Ra, Rb, Rc } }, /* Ra,Rb,Rc */
+ { SHORT_A5S, 2, { Ra, Rb, IMM5U } }, /* Ra,Rb,imm5u (shifts) */
+ { SHORT_NONE, 0, { 0 } }, /* no operands (nop, reit) */
+ { LONG, 2, { Ra, Rb, IMM32 } }, /* Ra,Rb,imm32 */
+ { LONG_U, 2, { IMM32 } }, /* imm32 */
+ { LONG_AF, 2, { Fa, Rb, IMM32 } }, /* Fa,Rb,imm32 */
+ { LONG_CMP, 2, { CC, Fa2, Rb, IMM32} }, /* CC Fa2,Rb,imm32 */
+ { LONG_M, 2, { Ra, ATPAR, Rb, IMM32 } }, /* Ra,@(Rb,imm32) */
+ { LONG_M2, 2, { Ra2, ATPAR, Rb, IMM32 } }, /* Ra,@(Rb,imm32) */
+ { LONG_2, 2, { Ra3, IMM32 } }, /* Ra,imm32 */
+ { LONG_2b, 3, { Ra3, IMM32 } }, /* Ra,imm32 */
+ { LONG_D, 2, { IMM6S3, IMM32 } }, /* imm6s3,imm32 */
+ { LONG_Db, 2, { IMM6U, IMM32 } }, /* imm6,imm32 */
+ { 0, 0, { 0 } },
+};
+
+const char *d30v_ecc_names[] =
+{
+ "al",
+ "tx",
+ "fx",
+ "xt",
+ "xf",
+ "tt",
+ "tf",
+ "res"
+};
+
+const char *d30v_cc_names[] =
+{
+ "eq",
+ "ne",
+ "gt",
+ "ge",
+ "lt",
+ "le",
+ "ps",
+ "ng",
+ NULL
+};
diff --git a/opcodes/dep-in.sed b/opcodes/dep-in.sed
new file mode 100644
index 00000000000..c30dee56391
--- /dev/null
+++ b/opcodes/dep-in.sed
@@ -0,0 +1,20 @@
+:loop
+/\\$/N
+s/\\\n */ /g
+t loop
+
+s!\.o:!.lo:!
+s! @BFD_H@! $(BFD_H)!g
+s!@INCDIR@!$(INCDIR)!g
+s!@BFDDIR@!$(BFDDIR)!g
+s!@SRCDIR@/!!g
+
+s/\\\n */ /g
+
+s/ *$//
+s/ */ /g
+s/ *:/:/g
+/:$/d
+
+s/\(.\{50\}[^ ]*\) /\1 \\\
+ /g
diff --git a/opcodes/dis-buf.c b/opcodes/dis-buf.c
new file mode 100644
index 00000000000..d76be2ec872
--- /dev/null
+++ b/opcodes/dis-buf.c
@@ -0,0 +1,104 @@
+/* Disassemble from a buffer, for GNU.
+ Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "dis-asm.h"
+#include <errno.h>
+#include "opintl.h"
+
+/* Get LENGTH bytes from info's buffer, at target address memaddr.
+ Transfer them to myaddr. */
+int
+buffer_read_memory (memaddr, myaddr, length, info)
+ bfd_vma memaddr;
+ bfd_byte *myaddr;
+ int length;
+ struct disassemble_info *info;
+{
+ if (memaddr < info->buffer_vma
+ || memaddr + length > info->buffer_vma + info->buffer_length)
+ /* Out of bounds. Use EIO because GDB uses it. */
+ return EIO;
+ memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
+ return 0;
+}
+
+/* Print an error message. We can assume that this is in response to
+ an error return from buffer_read_memory. */
+void
+perror_memory (status, memaddr, info)
+ int status;
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ if (status != EIO)
+ /* Can't happen. */
+ info->fprintf_func (info->stream, _("Unknown error %d\n"), status);
+ else
+ /* Actually, address between memaddr and memaddr + len was
+ out of bounds. */
+ info->fprintf_func (info->stream,
+ _("Address 0x%x is out of bounds.\n"), memaddr);
+}
+
+/* This could be in a separate file, to save miniscule amounts of space
+ in statically linked executables. */
+
+/* Just print the address is hex. This is included for completeness even
+ though both GDB and objdump provide their own (to print symbolic
+ addresses). */
+
+void
+generic_print_address (addr, info)
+ bfd_vma addr;
+ struct disassemble_info *info;
+{
+ (*info->fprintf_func) (info->stream, "0x%x", addr);
+}
+
+/* Just concatenate the address as hex. This is included for
+ completeness even though both GDB and objdump provide their own (to
+ print symbolic addresses). */
+
+void
+generic_strcat_address (addr, buf, len)
+ bfd_vma addr;
+ char *buf;
+ int len;
+{
+ if (buf != (char *)NULL && len > 0)
+ {
+ char tmpBuf[30];
+
+ sprintf_vma (tmpBuf, addr);
+ if ((strlen (buf) + strlen (tmpBuf)) <= len)
+ strcat (buf, tmpBuf);
+ else
+ strncat (buf, tmpBuf, (len - strlen(buf)));
+ }
+ return;
+}
+
+/* Just return the given address. */
+
+int
+generic_symbol_at_address (addr, info)
+ bfd_vma addr;
+ struct disassemble_info * info;
+{
+ return 1;
+}
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
new file mode 100644
index 00000000000..4898b42458d
--- /dev/null
+++ b/opcodes/disassemble.c
@@ -0,0 +1,248 @@
+/* Select disassembly routine for specified architecture.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "dis-asm.h"
+
+#ifdef ARCH_all
+#define ARCH_a29k
+#define ARCH_alpha
+#define ARCH_arc
+#define ARCH_arm
+#define ARCH_d10v
+#define ARCH_d30v
+#define ARCH_h8300
+#define ARCH_h8500
+#define ARCH_hppa
+#define ARCH_i386
+#define ARCH_i960
+#define ARCH_fr30
+#define ARCH_m32r
+#define ARCH_m68k
+#define ARCH_m88k
+#define ARCH_mcore
+#define ARCH_mips
+#define ARCH_mn10200
+#define ARCH_mn10300
+#define ARCH_ns32k
+#define ARCH_powerpc
+#define ARCH_rs6000
+#define ARCH_sh
+#define ARCH_sparc
+#define ARCH_tic30
+#define ARCH_tic80
+#define ARCH_v850
+#define ARCH_vax
+#define ARCH_w65
+#define ARCH_z8k
+#endif
+
+
+disassembler_ftype
+disassembler (abfd)
+ bfd *abfd;
+{
+ enum bfd_architecture a = bfd_get_arch (abfd);
+ disassembler_ftype disassemble;
+
+ switch (a)
+ {
+ /* If you add a case to this table, also add it to the
+ ARCH_all definition right above this function. */
+#ifdef ARCH_a29k
+ case bfd_arch_a29k:
+ /* As far as I know we only handle big-endian 29k objects. */
+ disassemble = print_insn_big_a29k;
+ break;
+#endif
+#ifdef ARCH_alpha
+ case bfd_arch_alpha:
+ disassemble = print_insn_alpha;
+ break;
+#endif
+#ifdef ARCH_arc
+ case bfd_arch_arc:
+ {
+ disassemble = arc_get_disassembler (bfd_get_mach (abfd),
+ bfd_big_endian (abfd));
+ break;
+ }
+#endif
+#ifdef ARCH_arm
+ case bfd_arch_arm:
+ if (bfd_big_endian (abfd))
+ disassemble = print_insn_big_arm;
+ else
+ disassemble = print_insn_little_arm;
+ break;
+#endif
+#ifdef ARCH_d10v
+ case bfd_arch_d10v:
+ disassemble = print_insn_d10v;
+ break;
+#endif
+#ifdef ARCH_d30v
+ case bfd_arch_d30v:
+ disassemble = print_insn_d30v;
+ break;
+#endif
+#ifdef ARCH_h8300
+ case bfd_arch_h8300:
+ if (bfd_get_mach(abfd) == bfd_mach_h8300h)
+ disassemble = print_insn_h8300h;
+ else if (bfd_get_mach(abfd) == bfd_mach_h8300s)
+ disassemble = print_insn_h8300s;
+ else
+ disassemble = print_insn_h8300;
+ break;
+#endif
+#ifdef ARCH_h8500
+ case bfd_arch_h8500:
+ disassemble = print_insn_h8500;
+ break;
+#endif
+#ifdef ARCH_hppa
+ case bfd_arch_hppa:
+ disassemble = print_insn_hppa;
+ break;
+#endif
+#ifdef ARCH_i386
+ case bfd_arch_i386:
+ if (bfd_get_mach (abfd) == bfd_mach_i386_i386_intel_syntax)
+ disassemble = print_insn_i386_intel;
+ else
+ disassemble = print_insn_i386_att;
+ break;
+#endif
+#ifdef ARCH_i960
+ case bfd_arch_i960:
+ disassemble = print_insn_i960;
+ break;
+#endif
+#ifdef ARCH_fr30
+ case bfd_arch_fr30:
+ disassemble = print_insn_fr30;
+ break;
+#endif
+#ifdef ARCH_m32r
+ case bfd_arch_m32r:
+ disassemble = print_insn_m32r;
+ break;
+#endif
+#ifdef ARCH_m68k
+ case bfd_arch_m68k:
+ disassemble = print_insn_m68k;
+ break;
+#endif
+#ifdef ARCH_m88k
+ case bfd_arch_m88k:
+ disassemble = print_insn_m88k;
+ break;
+#endif
+#ifdef ARCH_ns32k
+ case bfd_arch_ns32k:
+ disassemble = print_insn_ns32k;
+ break;
+#endif
+#ifdef ARCH_mcore
+ case bfd_arch_mcore:
+ disassemble = print_insn_mcore;
+ break;
+#endif
+#ifdef ARCH_mips
+ case bfd_arch_mips:
+ if (bfd_big_endian (abfd))
+ disassemble = print_insn_big_mips;
+ else
+ disassemble = print_insn_little_mips;
+ break;
+#endif
+#ifdef ARCH_mn10200
+ case bfd_arch_mn10200:
+ disassemble = print_insn_mn10200;
+ break;
+#endif
+#ifdef ARCH_mn10300
+ case bfd_arch_mn10300:
+ disassemble = print_insn_mn10300;
+ break;
+#endif
+#ifdef ARCH_powerpc
+ case bfd_arch_powerpc:
+ if (bfd_big_endian (abfd))
+ disassemble = print_insn_big_powerpc;
+ else
+ disassemble = print_insn_little_powerpc;
+ break;
+#endif
+#ifdef ARCH_rs6000
+ case bfd_arch_rs6000:
+ disassemble = print_insn_rs6000;
+ break;
+#endif
+#ifdef ARCH_sh
+ case bfd_arch_sh:
+ if (bfd_big_endian (abfd))
+ disassemble = print_insn_sh;
+ else
+ disassemble = print_insn_shl;
+ break;
+#endif
+#ifdef ARCH_sparc
+ case bfd_arch_sparc:
+ disassemble = print_insn_sparc;
+ break;
+#endif
+#ifdef ARCH_tic30
+ case bfd_arch_tic30:
+ disassemble = print_insn_tic30;
+ break;
+#endif
+#ifdef ARCH_tic80
+ case bfd_arch_tic80:
+ disassemble = print_insn_tic80;
+ break;
+#endif
+#ifdef ARCH_v850
+ case bfd_arch_v850:
+ disassemble = print_insn_v850;
+ break;
+#endif
+#ifdef ARCH_w65
+ case bfd_arch_w65:
+ disassemble = print_insn_w65;
+ break;
+#endif
+#ifdef ARCH_z8k
+ case bfd_arch_z8k:
+ if (bfd_get_mach(abfd) == bfd_mach_z8001)
+ disassemble = print_insn_z8001;
+ else
+ disassemble = print_insn_z8002;
+ break;
+#endif
+#ifdef ARCH_vax
+ case bfd_arch_vax:
+ disassemble = print_insn_vax;
+ break;
+#endif
+ default:
+ return 0;
+ }
+ return disassemble;
+}
+
diff --git a/opcodes/fr30-asm.c b/opcodes/fr30-asm.c
new file mode 100644
index 00000000000..5f5ccdc0b80
--- /dev/null
+++ b/opcodes/fr30-asm.c
@@ -0,0 +1,560 @@
+/* Assembler interface for targets using CGEN. -*- C -*-
+ CGEN: Cpu tools GENerator
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+- the resultant file is machine generated, cgen-asm.in isn't
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ??? Eventually more and more of this stuff can go to cpu-independent files.
+ Keep that in mind. */
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "fr30-desc.h"
+#include "fr30-opc.h"
+#include "opintl.h"
+
+#undef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#undef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+static const char * parse_insn_normal
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
+
+/* -- assembler routines inserted here */
+
+/* -- asm.c */
+/* Handle register lists for LDMx and STMx */
+
+static int
+parse_register_number (strp)
+ const char **strp;
+{
+ int regno;
+ if (**strp < '0' || **strp > '9')
+ return -1; /* error */
+ regno = **strp - '0';
+ ++*strp;
+
+ if (**strp >= '0' && **strp <= '9')
+ {
+ regno = regno * 10 + (**strp - '0');
+ ++*strp;
+ }
+
+ return regno;
+}
+
+static const char *
+parse_register_list (cd, strp, opindex, valuep, high_low, load_store)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+ int high_low; /* 0 == high, 1 == low */
+ int load_store; /* 0 == load, 1 == store */
+{
+ int regno;
+ *valuep = 0;
+ while (**strp && **strp != ')')
+ {
+ if (**strp != 'R' && **strp != 'r')
+ break;
+ ++*strp;
+
+ regno = parse_register_number (strp);
+ if (regno == -1)
+ return "Register number is not valid";
+ if (regno > 7 && !high_low)
+ return "Register must be between r0 and r7";
+ if (regno < 8 && high_low)
+ return "Register must be between r8 and r15";
+
+ if (high_low)
+ regno -= 8;
+
+ if (load_store) /* mask is reversed for store */
+ *valuep |= 0x80 >> regno;
+ else
+ *valuep |= 1 << regno;
+
+ if (**strp == ',')
+ {
+ if (*(*strp + 1) == ')')
+ break;
+ ++*strp;
+ }
+ }
+
+ if (!*strp || **strp != ')')
+ return "Register list is not valid";
+
+ return NULL;
+}
+
+static const char *
+parse_low_register_list_ld (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 0/*load*/);
+}
+
+static const char *
+parse_hi_register_list_ld (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 0/*load*/);
+}
+
+static const char *
+parse_low_register_list_st (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 1/*store*/);
+}
+
+static const char *
+parse_hi_register_list_st (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 1/*store*/);
+}
+
+/* -- */
+
+/* Main entry point for operand parsing.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `parse_insn_normal', but keeping it
+ separate makes clear the interface between `parse_insn_normal' and each of
+ the handlers.
+*/
+
+const char *
+fr30_cgen_parse_operand (cd, opindex, strp, fields)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ const char ** strp;
+ CGEN_FIELDS * fields;
+{
+ const char * errmsg;
+
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_cr_names, & fields->f_CRi);
+ break;
+ case FR30_OPERAND_CRJ :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_cr_names, & fields->f_CRj);
+ break;
+ case FR30_OPERAND_R13 :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r13, & fields->f_nil);
+ break;
+ case FR30_OPERAND_R14 :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r14, & fields->f_nil);
+ break;
+ case FR30_OPERAND_R15 :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r15, & fields->f_nil);
+ break;
+ case FR30_OPERAND_RI :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Ri);
+ break;
+ case FR30_OPERAND_RIC :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Ric);
+ break;
+ case FR30_OPERAND_RJ :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Rj);
+ break;
+ case FR30_OPERAND_RJC :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Rjc);
+ break;
+ case FR30_OPERAND_RS1 :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_dr_names, & fields->f_Rs1);
+ break;
+ case FR30_OPERAND_RS2 :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_dr_names, & fields->f_Rs2);
+ break;
+ case FR30_OPERAND_CC :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_CC, &fields->f_cc);
+ break;
+ case FR30_OPERAND_CCC :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_CCC, &fields->f_ccc);
+ break;
+ case FR30_OPERAND_DIR10 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR10, &fields->f_dir10);
+ break;
+ case FR30_OPERAND_DIR8 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR8, &fields->f_dir8);
+ break;
+ case FR30_OPERAND_DIR9 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR9, &fields->f_dir9);
+ break;
+ case FR30_OPERAND_DISP10 :
+ errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP10, &fields->f_disp10);
+ break;
+ case FR30_OPERAND_DISP8 :
+ errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP8, &fields->f_disp8);
+ break;
+ case FR30_OPERAND_DISP9 :
+ errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP9, &fields->f_disp9);
+ break;
+ case FR30_OPERAND_I20 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I20, &fields->f_i20);
+ break;
+ case FR30_OPERAND_I32 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I32, &fields->f_i32);
+ break;
+ case FR30_OPERAND_I8 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I8, &fields->f_i8);
+ break;
+ case FR30_OPERAND_LABEL12 :
+ {
+ bfd_vma value;
+ errmsg = cgen_parse_address (cd, strp, FR30_OPERAND_LABEL12, 0, NULL, & value);
+ fields->f_rel12 = value;
+ }
+ break;
+ case FR30_OPERAND_LABEL9 :
+ {
+ bfd_vma value;
+ errmsg = cgen_parse_address (cd, strp, FR30_OPERAND_LABEL9, 0, NULL, & value);
+ fields->f_rel9 = value;
+ }
+ break;
+ case FR30_OPERAND_M4 :
+ errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_M4, &fields->f_m4);
+ break;
+ case FR30_OPERAND_PS :
+ errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_ps, & fields->f_nil);
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ errmsg = parse_hi_register_list_ld (cd, strp, FR30_OPERAND_REGLIST_HI_LD, &fields->f_reglist_hi_ld);
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ errmsg = parse_hi_register_list_st (cd, strp, FR30_OPERAND_REGLIST_HI_ST, &fields->f_reglist_hi_st);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ errmsg = parse_low_register_list_ld (cd, strp, FR30_OPERAND_REGLIST_LOW_LD, &fields->f_reglist_low_ld);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ errmsg = parse_low_register_list_st (cd, strp, FR30_OPERAND_REGLIST_LOW_ST, &fields->f_reglist_low_st);
+ break;
+ case FR30_OPERAND_S10 :
+ errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_S10, &fields->f_s10);
+ break;
+ case FR30_OPERAND_U10 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U10, &fields->f_u10);
+ break;
+ case FR30_OPERAND_U4 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U4, &fields->f_u4);
+ break;
+ case FR30_OPERAND_U4C :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U4C, &fields->f_u4c);
+ break;
+ case FR30_OPERAND_U8 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U8, &fields->f_u8);
+ break;
+ case FR30_OPERAND_UDISP6 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_UDISP6, &fields->f_udisp6);
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
+ abort ();
+ }
+
+ return errmsg;
+}
+
+cgen_parse_fn * const fr30_cgen_parse_handlers[] =
+{
+ parse_insn_normal,
+};
+
+void
+fr30_cgen_init_asm (cd)
+ CGEN_CPU_DESC cd;
+{
+ fr30_cgen_init_opcode_table (cd);
+ fr30_cgen_init_ibld_table (cd);
+ cd->parse_handlers = & fr30_cgen_parse_handlers[0];
+ cd->parse_operand = fr30_cgen_parse_operand;
+}
+
+
+/* Default insn parser.
+
+ The syntax string is scanned and operands are parsed and stored in FIELDS.
+ Relocs are queued as we go via other callbacks.
+
+ ??? Note that this is currently an all-or-nothing parser. If we fail to
+ parse the instruction, we return 0 and the caller will start over from
+ the beginning. Backtracking will be necessary in parsing subexpressions,
+ but that can be handled there. Not handling backtracking here may get
+ expensive in the case of the m68k. Deal with later.
+
+ Returns NULL for success, an error message for failure.
+*/
+
+static const char *
+parse_insn_normal (cd, insn, strp, fields)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ const char **strp;
+ CGEN_FIELDS *fields;
+{
+ /* ??? Runtime added insns not handled yet. */
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ const char *str = *strp;
+ const char *errmsg;
+ const char *p;
+ const unsigned char * syn;
+#ifdef CGEN_MNEMONIC_OPERANDS
+ /* FIXME: wip */
+ int past_opcode_p;
+#endif
+
+ /* For now we assume the mnemonic is first (there are no leading operands).
+ We can parse it without needing to set up operand parsing.
+ GAS's input scrubber will ensure mnemonics are lowercase, but we may
+ not be called from GAS. */
+ p = CGEN_INSN_MNEMONIC (insn);
+ while (*p && tolower (*p) == tolower (*str))
+ ++p, ++str;
+
+ if (* p || (* str && !isspace (* str)))
+ return _("unrecognized instruction");
+
+ CGEN_INIT_PARSE (cd);
+ cgen_init_parse_operand (cd);
+#ifdef CGEN_MNEMONIC_OPERANDS
+ past_opcode_p = 0;
+#endif
+
+ /* We don't check for (*str != '\0') here because we want to parse
+ any trailing fake arguments in the syntax string. */
+ syn = CGEN_SYNTAX_STRING (syntax);
+
+ /* Mnemonics come first for now, ensure valid string. */
+ if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
+ abort ();
+
+ ++syn;
+
+ while (* syn != 0)
+ {
+ /* Non operand chars must match exactly. */
+ if (CGEN_SYNTAX_CHAR_P (* syn))
+ {
+ if (*str == CGEN_SYNTAX_CHAR (* syn))
+ {
+#ifdef CGEN_MNEMONIC_OPERANDS
+ if (* syn == ' ')
+ past_opcode_p = 1;
+#endif
+ ++ syn;
+ ++ str;
+ }
+ else
+ {
+ /* Syntax char didn't match. Can't be this insn. */
+ /* FIXME: would like to return something like
+ "expected char `c'" */
+ return _("syntax error");
+ }
+ continue;
+ }
+
+ /* We have an operand of some sort. */
+ errmsg = fr30_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
+ &str, fields);
+ if (errmsg)
+ return errmsg;
+
+ /* Done with this operand, continue with next one. */
+ ++ syn;
+ }
+
+ /* If we're at the end of the syntax string, we're done. */
+ if (* syn == '\0')
+ {
+ /* FIXME: For the moment we assume a valid `str' can only contain
+ blanks now. IE: We needn't try again with a longer version of
+ the insn and it is assumed that longer versions of insns appear
+ before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
+ while (isspace (* str))
+ ++ str;
+
+ if (* str != '\0')
+ return _("junk at end of line"); /* FIXME: would like to include `str' */
+
+ return NULL;
+ }
+
+ /* We couldn't parse it. */
+ return _("unrecognized instruction");
+}
+
+/* Main entry point.
+ This routine is called for each instruction to be assembled.
+ STR points to the insn to be assembled.
+ We assume all necessary tables have been initialized.
+ The assembled instruction, less any fixups, is stored in BUF.
+ Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
+ still needs to be converted to target byte order, otherwise BUF is an array
+ of bytes in target byte order.
+ The result is a pointer to the insn's entry in the opcode table,
+ or NULL if an error occured (an error message will have already been
+ printed).
+
+ Note that when processing (non-alias) macro-insns,
+ this function recurses.
+
+ ??? It's possible to make this cpu-independent.
+ One would have to deal with a few minor things.
+ At this point in time doing so would be more of a curiosity than useful
+ [for example this file isn't _that_ big], but keeping the possibility in
+ mind helps keep the design clean. */
+
+const CGEN_INSN *
+fr30_cgen_assemble_insn (cd, str, fields, buf, errmsg)
+ CGEN_CPU_DESC cd;
+ const char *str;
+ CGEN_FIELDS *fields;
+ CGEN_INSN_BYTES_PTR buf;
+ char **errmsg;
+{
+ const char *start;
+ CGEN_INSN_LIST *ilist;
+
+ /* Skip leading white space. */
+ while (isspace (* str))
+ ++ str;
+
+ /* The instructions are stored in hashed lists.
+ Get the first in the list. */
+ ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
+
+ /* Keep looking until we find a match. */
+
+ start = str;
+ for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
+ {
+ const CGEN_INSN *insn = ilist->insn;
+
+#if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
+ /* Is this insn supported by the selected cpu? */
+ if (! fr30_cgen_insn_supported (cd, insn))
+ continue;
+#endif
+
+ /* If the RELAX attribute is set, this is an insn that shouldn't be
+ chosen immediately. Instead, it is used during assembler/linker
+ relaxation if possible. */
+ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
+ continue;
+
+ str = start;
+
+ /* Allow parse/insert handlers to obtain length of insn. */
+ CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
+
+ if (! CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields))
+ {
+ /* ??? 0 is passed for `pc' */
+ if (CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, (bfd_vma) 0)
+ != NULL)
+ continue;
+ /* It is up to the caller to actually output the insn and any
+ queued relocs. */
+ return insn;
+ }
+
+ /* Try the next entry. */
+ }
+
+ /* FIXME: We can return a better error message than this.
+ Need to track why it failed and pick the right one. */
+ {
+ static char errbuf[100];
+ if (strlen (start) > 50)
+ /* xgettext:c-format */
+ sprintf (errbuf, _("bad instruction `%.50s...'"), start);
+ else
+ /* xgettext:c-format */
+ sprintf (errbuf, _("bad instruction `%.50s'"), start);
+
+ *errmsg = errbuf;
+ return NULL;
+ }
+}
+
+#if 0 /* This calls back to GAS which we can't do without care. */
+
+/* Record each member of OPVALS in the assembler's symbol table.
+ This lets GAS parse registers for us.
+ ??? Interesting idea but not currently used. */
+
+/* Record each member of OPVALS in the assembler's symbol table.
+ FIXME: Not currently used. */
+
+void
+fr30_cgen_asm_hash_keywords (cd, opvals)
+ CGEN_CPU_DESC cd;
+ CGEN_KEYWORD *opvals;
+{
+ CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
+ const CGEN_KEYWORD_ENTRY * ke;
+
+ while ((ke = cgen_keyword_search_next (& search)) != NULL)
+ {
+#if 0 /* Unnecessary, should be done in the search routine. */
+ if (! fr30_cgen_opval_supported (ke))
+ continue;
+#endif
+ cgen_asm_record_register (cd, ke->name, ke->value);
+ }
+}
+
+#endif /* 0 */
diff --git a/opcodes/fr30-desc.c b/opcodes/fr30-desc.c
new file mode 100644
index 00000000000..810f04b9dcc
--- /dev/null
+++ b/opcodes/fr30-desc.c
@@ -0,0 +1,1643 @@
+/* CPU data for fr30.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "fr30-desc.h"
+#include "fr30-opc.h"
+#include "opintl.h"
+
+/* Attributes. */
+
+static const CGEN_ATTR_ENTRY bool_attr[] =
+{
+ { "#f", 0 },
+ { "#t", 1 },
+ { 0, 0 }
+};
+
+static const CGEN_ATTR_ENTRY MACH_attr[] =
+{
+ { "base", MACH_BASE },
+ { "fr30", MACH_FR30 },
+ { "max", MACH_MAX },
+ { 0, 0 }
+};
+
+static const CGEN_ATTR_ENTRY ISA_attr[] =
+{
+ { "fr30", ISA_FR30 },
+ { "max", ISA_MAX },
+ { 0, 0 }
+};
+
+const CGEN_ATTR_TABLE fr30_cgen_ifield_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "RESERVED", &bool_attr[0], &bool_attr[0] },
+ { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
+ { "SIGNED", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+const CGEN_ATTR_TABLE fr30_cgen_hardware_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "PC", &bool_attr[0], &bool_attr[0] },
+ { "PROFILE", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
+ { "SIGNED", &bool_attr[0], &bool_attr[0] },
+ { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
+ { "RELAX", &bool_attr[0], &bool_attr[0] },
+ { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
+ { "HASH-PREFIX", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "ALIAS", &bool_attr[0], &bool_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
+ { "COND-CTI", &bool_attr[0], &bool_attr[0] },
+ { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
+ { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
+ { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
+ { "RELAX", &bool_attr[0], &bool_attr[0] },
+ { "NO-DIS", &bool_attr[0], &bool_attr[0] },
+ { "PBB", &bool_attr[0], &bool_attr[0] },
+ { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+/* Instruction set variants. */
+
+static const CGEN_ISA fr30_cgen_isa_table[] = {
+ { "fr30", 16, 16, 16, 48, },
+ { 0 }
+};
+
+/* Machine variants. */
+
+static const CGEN_MACH fr30_cgen_mach_table[] = {
+ { "fr30", "fr30", MACH_FR30 },
+ { 0 }
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_gr_names_entries[] =
+{
+ { "r0", 0 },
+ { "r1", 1 },
+ { "r2", 2 },
+ { "r3", 3 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 },
+ { "ac", 13 },
+ { "fp", 14 },
+ { "sp", 15 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_gr_names =
+{
+ & fr30_cgen_opval_gr_names_entries[0],
+ 19
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_cr_names_entries[] =
+{
+ { "cr0", 0 },
+ { "cr1", 1 },
+ { "cr2", 2 },
+ { "cr3", 3 },
+ { "cr4", 4 },
+ { "cr5", 5 },
+ { "cr6", 6 },
+ { "cr7", 7 },
+ { "cr8", 8 },
+ { "cr9", 9 },
+ { "cr10", 10 },
+ { "cr11", 11 },
+ { "cr12", 12 },
+ { "cr13", 13 },
+ { "cr14", 14 },
+ { "cr15", 15 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_cr_names =
+{
+ & fr30_cgen_opval_cr_names_entries[0],
+ 16
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_dr_names_entries[] =
+{
+ { "tbr", 0 },
+ { "rp", 1 },
+ { "ssp", 2 },
+ { "usp", 3 },
+ { "mdh", 4 },
+ { "mdl", 5 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_dr_names =
+{
+ & fr30_cgen_opval_dr_names_entries[0],
+ 6
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_ps_entries[] =
+{
+ { "ps", 0 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_h_ps =
+{
+ & fr30_cgen_opval_h_ps_entries[0],
+ 1
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_r13_entries[] =
+{
+ { "r13", 0 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_h_r13 =
+{
+ & fr30_cgen_opval_h_r13_entries[0],
+ 1
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_r14_entries[] =
+{
+ { "r14", 0 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_h_r14 =
+{
+ & fr30_cgen_opval_h_r14_entries[0],
+ 1
+};
+
+static CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_r15_entries[] =
+{
+ { "r15", 0 }
+};
+
+CGEN_KEYWORD fr30_cgen_opval_h_r15 =
+{
+ & fr30_cgen_opval_h_r15_entries[0],
+ 1
+};
+
+
+
+/* The hardware table. */
+
+#define A(a) (1 << CONCAT2 (CGEN_HW_,a))
+
+const CGEN_HW_ENTRY fr30_cgen_hw_table[] =
+{
+ { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
+ { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_gr_names, { 0|A(CACHE_ADDR)|A(PROFILE), { (1<<MACH_BASE) } } },
+ { "h-cr", HW_H_CR, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_cr_names, { 0, { (1<<MACH_BASE) } } },
+ { "h-dr", HW_H_DR, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_dr_names, { 0, { (1<<MACH_BASE) } } },
+ { "h-ps", HW_H_PS, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_ps, { 0, { (1<<MACH_BASE) } } },
+ { "h-r13", HW_H_R13, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_r13, { 0, { (1<<MACH_BASE) } } },
+ { "h-r14", HW_H_R14, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_r14, { 0, { (1<<MACH_BASE) } } },
+ { "h-r15", HW_H_R15, CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_r15, { 0, { (1<<MACH_BASE) } } },
+ { "h-nbit", HW_H_NBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-zbit", HW_H_ZBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-vbit", HW_H_VBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-ibit", HW_H_IBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-sbit", HW_H_SBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-tbit", HW_H_TBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-d0bit", HW_H_D0BIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-d1bit", HW_H_D1BIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-ccr", HW_H_CCR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-scr", HW_H_SCR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-ilm", HW_H_ILM, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { 0 }
+};
+
+#undef A
+
+/* The instruction field table. */
+
+#define A(a) (1 << CONCAT2 (CGEN_IFLD_,a))
+
+const CGEN_IFLD fr30_cgen_ifld_table[] =
+{
+ { FR30_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_OP1, "f-op1", 0, 16, 0, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_OP2, "f-op2", 0, 16, 4, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_OP3, "f-op3", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_OP4, "f-op4", 0, 16, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_OP5, "f-op5", 0, 16, 4, 1, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_CC, "f-cc", 0, 16, 4, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_CCC, "f-ccc", 16, 16, 0, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_RJ, "f-Rj", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_RI, "f-Ri", 0, 16, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_RS1, "f-Rs1", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_RS2, "f-Rs2", 0, 16, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_RJC, "f-Rjc", 16, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_RIC, "f-Ric", 16, 16, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_CRJ, "f-CRj", 16, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_CRI, "f-CRi", 16, 16, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_U4, "f-u4", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_U4C, "f-u4c", 0, 16, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_I4, "f-i4", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_M4, "f-m4", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_U8, "f-u8", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_I8, "f-i8", 0, 16, 4, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_I20_4, "f-i20-4", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_I20_16, "f-i20-16", 16, 16, 0, 16, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_I32, "f-i32", 16, 32, 0, 32, { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
+ { FR30_F_UDISP6, "f-udisp6", 0, 16, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_DISP8, "f-disp8", 0, 16, 4, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_DISP9, "f-disp9", 0, 16, 4, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_DISP10, "f-disp10", 0, 16, 4, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_S10, "f-s10", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_U10, "f-u10", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_REL9, "f-rel9", 0, 16, 8, 8, { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+ { FR30_F_DIR8, "f-dir8", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_DIR9, "f-dir9", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_DIR10, "f-dir10", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_REL12, "f-rel12", 0, 16, 5, 11, { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+ { FR30_F_REGLIST_HI_ST, "f-reglist_hi_st", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_REGLIST_LOW_ST, "f-reglist_low_st", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_REGLIST_HI_LD, "f-reglist_hi_ld", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { FR30_F_REGLIST_LOW_LD, "f-reglist_low_ld", 0, 16, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { 0 }
+};
+
+#undef A
+
+/* The operand table. */
+
+#define A(a) (1 << CONCAT2 (CGEN_OPERAND_,a))
+#define OPERAND(op) CONCAT2 (FR30_OPERAND_,op)
+
+const CGEN_OPERAND fr30_cgen_operand_table[] =
+{
+/* pc: program counter */
+ { "pc", FR30_OPERAND_PC, HW_H_PC, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* Ri: destination register */
+ { "Ri", FR30_OPERAND_RI, HW_H_GR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* Rj: source register */
+ { "Rj", FR30_OPERAND_RJ, HW_H_GR, 8, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* Ric: target register coproc insn */
+ { "Ric", FR30_OPERAND_RIC, HW_H_GR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* Rjc: source register coproc insn */
+ { "Rjc", FR30_OPERAND_RJC, HW_H_GR, 8, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* CRi: coprocessor register */
+ { "CRi", FR30_OPERAND_CRI, HW_H_CR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* CRj: coprocessor register */
+ { "CRj", FR30_OPERAND_CRJ, HW_H_CR, 8, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* Rs1: dedicated register */
+ { "Rs1", FR30_OPERAND_RS1, HW_H_DR, 8, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* Rs2: dedicated register */
+ { "Rs2", FR30_OPERAND_RS2, HW_H_DR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* R13: General Register 13 */
+ { "R13", FR30_OPERAND_R13, HW_H_R13, 0, 0,
+ { 0, { (1<<MACH_BASE) } } },
+/* R14: General Register 14 */
+ { "R14", FR30_OPERAND_R14, HW_H_R14, 0, 0,
+ { 0, { (1<<MACH_BASE) } } },
+/* R15: General Register 15 */
+ { "R15", FR30_OPERAND_R15, HW_H_R15, 0, 0,
+ { 0, { (1<<MACH_BASE) } } },
+/* ps: Program Status register */
+ { "ps", FR30_OPERAND_PS, HW_H_PS, 0, 0,
+ { 0, { (1<<MACH_BASE) } } },
+/* u4: 4 bit unsigned immediate */
+ { "u4", FR30_OPERAND_U4, HW_H_UINT, 8, 4,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* u4c: 4 bit unsigned immediate */
+ { "u4c", FR30_OPERAND_U4C, HW_H_UINT, 12, 4,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* u8: 8 bit unsigned immediate */
+ { "u8", FR30_OPERAND_U8, HW_H_UINT, 8, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* i8: 8 bit unsigned immediate */
+ { "i8", FR30_OPERAND_I8, HW_H_UINT, 4, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* udisp6: 6 bit unsigned immediate */
+ { "udisp6", FR30_OPERAND_UDISP6, HW_H_UINT, 8, 4,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* disp8: 8 bit signed immediate */
+ { "disp8", FR30_OPERAND_DISP8, HW_H_SINT, 4, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* disp9: 9 bit signed immediate */
+ { "disp9", FR30_OPERAND_DISP9, HW_H_SINT, 4, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* disp10: 10 bit signed immediate */
+ { "disp10", FR30_OPERAND_DISP10, HW_H_SINT, 4, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* s10: 10 bit signed immediate */
+ { "s10", FR30_OPERAND_S10, HW_H_SINT, 8, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* u10: 10 bit unsigned immediate */
+ { "u10", FR30_OPERAND_U10, HW_H_UINT, 8, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* i32: 32 bit immediate */
+ { "i32", FR30_OPERAND_I32, HW_H_UINT, 0, 32,
+ { 0|A(HASH_PREFIX)|A(SIGN_OPT), { (1<<MACH_BASE) } } },
+/* m4: 4 bit negative immediate */
+ { "m4", FR30_OPERAND_M4, HW_H_SINT, 8, 4,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* i20: 20 bit immediate */
+ { "i20", FR30_OPERAND_I20, HW_H_UINT, 0, 20,
+ { 0|A(HASH_PREFIX)|A(VIRTUAL), { (1<<MACH_BASE) } } },
+/* dir8: 8 bit direct address */
+ { "dir8", FR30_OPERAND_DIR8, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* dir9: 9 bit direct address */
+ { "dir9", FR30_OPERAND_DIR9, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* dir10: 10 bit direct address */
+ { "dir10", FR30_OPERAND_DIR10, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* label9: 9 bit pc relative address */
+ { "label9", FR30_OPERAND_LABEL9, HW_H_IADDR, 8, 8,
+ { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+/* label12: 12 bit pc relative address */
+ { "label12", FR30_OPERAND_LABEL12, HW_H_IADDR, 5, 11,
+ { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+/* reglist_low_ld: 8 bit low register mask for ldm */
+ { "reglist_low_ld", FR30_OPERAND_REGLIST_LOW_LD, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* reglist_hi_ld: 8 bit high register mask for ldm */
+ { "reglist_hi_ld", FR30_OPERAND_REGLIST_HI_LD, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* reglist_low_st: 8 bit low register mask for stm */
+ { "reglist_low_st", FR30_OPERAND_REGLIST_LOW_ST, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* reglist_hi_st: 8 bit high register mask for stm */
+ { "reglist_hi_st", FR30_OPERAND_REGLIST_HI_ST, HW_H_UINT, 8, 8,
+ { 0, { (1<<MACH_BASE) } } },
+/* cc: condition codes */
+ { "cc", FR30_OPERAND_CC, HW_H_UINT, 4, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* ccc: coprocessor calc */
+ { "ccc", FR30_OPERAND_CCC, HW_H_UINT, 0, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* nbit: negative bit */
+ { "nbit", FR30_OPERAND_NBIT, HW_H_NBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* vbit: overflow bit */
+ { "vbit", FR30_OPERAND_VBIT, HW_H_VBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* zbit: zero bit */
+ { "zbit", FR30_OPERAND_ZBIT, HW_H_ZBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* cbit: carry bit */
+ { "cbit", FR30_OPERAND_CBIT, HW_H_CBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* ibit: interrupt bit */
+ { "ibit", FR30_OPERAND_IBIT, HW_H_IBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* sbit: stack bit */
+ { "sbit", FR30_OPERAND_SBIT, HW_H_SBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* tbit: trace trap bit */
+ { "tbit", FR30_OPERAND_TBIT, HW_H_TBIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* d0bit: division 0 bit */
+ { "d0bit", FR30_OPERAND_D0BIT, HW_H_D0BIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* d1bit: division 1 bit */
+ { "d1bit", FR30_OPERAND_D1BIT, HW_H_D1BIT, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* ccr: condition code bits */
+ { "ccr", FR30_OPERAND_CCR, HW_H_CCR, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* scr: system condition bits */
+ { "scr", FR30_OPERAND_SCR, HW_H_SCR, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* ilm: interrupt level mask */
+ { "ilm", FR30_OPERAND_ILM, HW_H_ILM, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+ { 0 }
+};
+
+#undef A
+
+#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
+#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
+
+/* The instruction table. */
+
+static const CGEN_IBASE fr30_cgen_insn_table[MAX_INSNS] =
+{
+ /* Special null first entry.
+ A `num' value of zero is thus invalid.
+ Also, the special `invalid' insn resides here. */
+ { 0, 0, 0 },
+/* add $Rj,$Ri */
+ {
+ FR30_INSN_ADD, "add", "add", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* add $u4,$Ri */
+ {
+ FR30_INSN_ADDI, "addi", "add", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* add2 $m4,$Ri */
+ {
+ FR30_INSN_ADD2, "add2", "add2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addc $Rj,$Ri */
+ {
+ FR30_INSN_ADDC, "addc", "addc", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addn $Rj,$Ri */
+ {
+ FR30_INSN_ADDN, "addn", "addn", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addn $u4,$Ri */
+ {
+ FR30_INSN_ADDNI, "addni", "addn", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addn2 $m4,$Ri */
+ {
+ FR30_INSN_ADDN2, "addn2", "addn2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sub $Rj,$Ri */
+ {
+ FR30_INSN_SUB, "sub", "sub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* subc $Rj,$Ri */
+ {
+ FR30_INSN_SUBC, "subc", "subc", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* subn $Rj,$Ri */
+ {
+ FR30_INSN_SUBN, "subn", "subn", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* cmp $Rj,$Ri */
+ {
+ FR30_INSN_CMP, "cmp", "cmp", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* cmp $u4,$Ri */
+ {
+ FR30_INSN_CMPI, "cmpi", "cmp", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* cmp2 $m4,$Ri */
+ {
+ FR30_INSN_CMP2, "cmp2", "cmp2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* and $Rj,$Ri */
+ {
+ FR30_INSN_AND, "and", "and", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* or $Rj,$Ri */
+ {
+ FR30_INSN_OR, "or", "or", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* eor $Rj,$Ri */
+ {
+ FR30_INSN_EOR, "eor", "eor", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* and $Rj,@$Ri */
+ {
+ FR30_INSN_ANDM, "andm", "and", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* andh $Rj,@$Ri */
+ {
+ FR30_INSN_ANDH, "andh", "andh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* andb $Rj,@$Ri */
+ {
+ FR30_INSN_ANDB, "andb", "andb", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* or $Rj,@$Ri */
+ {
+ FR30_INSN_ORM, "orm", "or", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* orh $Rj,@$Ri */
+ {
+ FR30_INSN_ORH, "orh", "orh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* orb $Rj,@$Ri */
+ {
+ FR30_INSN_ORB, "orb", "orb", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* eor $Rj,@$Ri */
+ {
+ FR30_INSN_EORM, "eorm", "eor", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* eorh $Rj,@$Ri */
+ {
+ FR30_INSN_EORH, "eorh", "eorh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* eorb $Rj,@$Ri */
+ {
+ FR30_INSN_EORB, "eorb", "eorb", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bandl $u4,@$Ri */
+ {
+ FR30_INSN_BANDL, "bandl", "bandl", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* borl $u4,@$Ri */
+ {
+ FR30_INSN_BORL, "borl", "borl", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* beorl $u4,@$Ri */
+ {
+ FR30_INSN_BEORL, "beorl", "beorl", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bandh $u4,@$Ri */
+ {
+ FR30_INSN_BANDH, "bandh", "bandh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* borh $u4,@$Ri */
+ {
+ FR30_INSN_BORH, "borh", "borh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* beorh $u4,@$Ri */
+ {
+ FR30_INSN_BEORH, "beorh", "beorh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* btstl $u4,@$Ri */
+ {
+ FR30_INSN_BTSTL, "btstl", "btstl", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* btsth $u4,@$Ri */
+ {
+ FR30_INSN_BTSTH, "btsth", "btsth", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* mul $Rj,$Ri */
+ {
+ FR30_INSN_MUL, "mul", "mul", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* mulu $Rj,$Ri */
+ {
+ FR30_INSN_MULU, "mulu", "mulu", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* mulh $Rj,$Ri */
+ {
+ FR30_INSN_MULH, "mulh", "mulh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* muluh $Rj,$Ri */
+ {
+ FR30_INSN_MULUH, "muluh", "muluh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* div0s $Ri */
+ {
+ FR30_INSN_DIV0S, "div0s", "div0s", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* div0u $Ri */
+ {
+ FR30_INSN_DIV0U, "div0u", "div0u", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* div1 $Ri */
+ {
+ FR30_INSN_DIV1, "div1", "div1", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* div2 $Ri */
+ {
+ FR30_INSN_DIV2, "div2", "div2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* div3 */
+ {
+ FR30_INSN_DIV3, "div3", "div3", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* div4s */
+ {
+ FR30_INSN_DIV4S, "div4s", "div4s", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lsl $Rj,$Ri */
+ {
+ FR30_INSN_LSL, "lsl", "lsl", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lsl $u4,$Ri */
+ {
+ FR30_INSN_LSLI, "lsli", "lsl", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lsl2 $u4,$Ri */
+ {
+ FR30_INSN_LSL2, "lsl2", "lsl2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lsr $Rj,$Ri */
+ {
+ FR30_INSN_LSR, "lsr", "lsr", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lsr $u4,$Ri */
+ {
+ FR30_INSN_LSRI, "lsri", "lsr", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lsr2 $u4,$Ri */
+ {
+ FR30_INSN_LSR2, "lsr2", "lsr2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* asr $Rj,$Ri */
+ {
+ FR30_INSN_ASR, "asr", "asr", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* asr $u4,$Ri */
+ {
+ FR30_INSN_ASRI, "asri", "asr", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* asr2 $u4,$Ri */
+ {
+ FR30_INSN_ASR2, "asr2", "asr2", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldi:8 $i8,$Ri */
+ {
+ FR30_INSN_LDI8, "ldi8", "ldi:8", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldi:20 $i20,$Ri */
+ {
+ FR30_INSN_LDI20, "ldi20", "ldi:20", 32,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* ldi:32 $i32,$Ri */
+ {
+ FR30_INSN_LDI32, "ldi32", "ldi:32", 48,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* ld @$Rj,$Ri */
+ {
+ FR30_INSN_LD, "ld", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lduh @$Rj,$Ri */
+ {
+ FR30_INSN_LDUH, "lduh", "lduh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldub @$Rj,$Ri */
+ {
+ FR30_INSN_LDUB, "ldub", "ldub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld @($R13,$Rj),$Ri */
+ {
+ FR30_INSN_LDR13, "ldr13", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lduh @($R13,$Rj),$Ri */
+ {
+ FR30_INSN_LDR13UH, "ldr13uh", "lduh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldub @($R13,$Rj),$Ri */
+ {
+ FR30_INSN_LDR13UB, "ldr13ub", "ldub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld @($R14,$disp10),$Ri */
+ {
+ FR30_INSN_LDR14, "ldr14", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lduh @($R14,$disp9),$Ri */
+ {
+ FR30_INSN_LDR14UH, "ldr14uh", "lduh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldub @($R14,$disp8),$Ri */
+ {
+ FR30_INSN_LDR14UB, "ldr14ub", "ldub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld @($R15,$udisp6),$Ri */
+ {
+ FR30_INSN_LDR15, "ldr15", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld @$R15+,$Ri */
+ {
+ FR30_INSN_LDR15GR, "ldr15gr", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld @$R15+,$Rs2 */
+ {
+ FR30_INSN_LDR15DR, "ldr15dr", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld @$R15+,$ps */
+ {
+ FR30_INSN_LDR15PS, "ldr15ps", "ld", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* st $Ri,@$Rj */
+ {
+ FR30_INSN_ST, "st", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sth $Ri,@$Rj */
+ {
+ FR30_INSN_STH, "sth", "sth", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stb $Ri,@$Rj */
+ {
+ FR30_INSN_STB, "stb", "stb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $Ri,@($R13,$Rj) */
+ {
+ FR30_INSN_STR13, "str13", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sth $Ri,@($R13,$Rj) */
+ {
+ FR30_INSN_STR13H, "str13h", "sth", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stb $Ri,@($R13,$Rj) */
+ {
+ FR30_INSN_STR13B, "str13b", "stb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $Ri,@($R14,$disp10) */
+ {
+ FR30_INSN_STR14, "str14", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sth $Ri,@($R14,$disp9) */
+ {
+ FR30_INSN_STR14H, "str14h", "sth", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stb $Ri,@($R14,$disp8) */
+ {
+ FR30_INSN_STR14B, "str14b", "stb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $Ri,@($R15,$udisp6) */
+ {
+ FR30_INSN_STR15, "str15", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $Ri,@-$R15 */
+ {
+ FR30_INSN_STR15GR, "str15gr", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $Rs2,@-$R15 */
+ {
+ FR30_INSN_STR15DR, "str15dr", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $ps,@-$R15 */
+ {
+ FR30_INSN_STR15PS, "str15ps", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mov $Rj,$Ri */
+ {
+ FR30_INSN_MOV, "mov", "mov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mov $Rs1,$Ri */
+ {
+ FR30_INSN_MOVDR, "movdr", "mov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mov $ps,$Ri */
+ {
+ FR30_INSN_MOVPS, "movps", "mov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mov $Ri,$Rs1 */
+ {
+ FR30_INSN_MOV2DR, "mov2dr", "mov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mov $Ri,$ps */
+ {
+ FR30_INSN_MOV2PS, "mov2ps", "mov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* jmp @$Ri */
+ {
+ FR30_INSN_JMP, "jmp", "jmp", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* jmp:d @$Ri */
+ {
+ FR30_INSN_JMPD, "jmpd", "jmp:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* call @$Ri */
+ {
+ FR30_INSN_CALLR, "callr", "call", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* call:d @$Ri */
+ {
+ FR30_INSN_CALLRD, "callrd", "call:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* call $label12 */
+ {
+ FR30_INSN_CALL, "call", "call", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* call:d $label12 */
+ {
+ FR30_INSN_CALLD, "calld", "call:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* ret */
+ {
+ FR30_INSN_RET, "ret", "ret", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* ret:d */
+ {
+ FR30_INSN_RET_D, "ret:d", "ret:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* int $u8 */
+ {
+ FR30_INSN_INT, "int", "int", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* inte */
+ {
+ FR30_INSN_INTE, "inte", "inte", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* reti */
+ {
+ FR30_INSN_RETI, "reti", "reti", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bra:d $label9 */
+ {
+ FR30_INSN_BRAD, "brad", "bra:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bra $label9 */
+ {
+ FR30_INSN_BRA, "bra", "bra", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bno:d $label9 */
+ {
+ FR30_INSN_BNOD, "bnod", "bno:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bno $label9 */
+ {
+ FR30_INSN_BNO, "bno", "bno", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* beq:d $label9 */
+ {
+ FR30_INSN_BEQD, "beqd", "beq:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* beq $label9 */
+ {
+ FR30_INSN_BEQ, "beq", "beq", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bne:d $label9 */
+ {
+ FR30_INSN_BNED, "bned", "bne:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bne $label9 */
+ {
+ FR30_INSN_BNE, "bne", "bne", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bc:d $label9 */
+ {
+ FR30_INSN_BCD, "bcd", "bc:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bc $label9 */
+ {
+ FR30_INSN_BC, "bc", "bc", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bnc:d $label9 */
+ {
+ FR30_INSN_BNCD, "bncd", "bnc:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bnc $label9 */
+ {
+ FR30_INSN_BNC, "bnc", "bnc", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bn:d $label9 */
+ {
+ FR30_INSN_BND, "bnd", "bn:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bn $label9 */
+ {
+ FR30_INSN_BN, "bn", "bn", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bp:d $label9 */
+ {
+ FR30_INSN_BPD, "bpd", "bp:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bp $label9 */
+ {
+ FR30_INSN_BP, "bp", "bp", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bv:d $label9 */
+ {
+ FR30_INSN_BVD, "bvd", "bv:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bv $label9 */
+ {
+ FR30_INSN_BV, "bv", "bv", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bnv:d $label9 */
+ {
+ FR30_INSN_BNVD, "bnvd", "bnv:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bnv $label9 */
+ {
+ FR30_INSN_BNV, "bnv", "bnv", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* blt:d $label9 */
+ {
+ FR30_INSN_BLTD, "bltd", "blt:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* blt $label9 */
+ {
+ FR30_INSN_BLT, "blt", "blt", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bge:d $label9 */
+ {
+ FR30_INSN_BGED, "bged", "bge:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bge $label9 */
+ {
+ FR30_INSN_BGE, "bge", "bge", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* ble:d $label9 */
+ {
+ FR30_INSN_BLED, "bled", "ble:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* ble $label9 */
+ {
+ FR30_INSN_BLE, "ble", "ble", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bgt:d $label9 */
+ {
+ FR30_INSN_BGTD, "bgtd", "bgt:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bgt $label9 */
+ {
+ FR30_INSN_BGT, "bgt", "bgt", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bls:d $label9 */
+ {
+ FR30_INSN_BLSD, "blsd", "bls:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bls $label9 */
+ {
+ FR30_INSN_BLS, "bls", "bls", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bhi:d $label9 */
+ {
+ FR30_INSN_BHID, "bhid", "bhi:d", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* bhi $label9 */
+ {
+ FR30_INSN_BHI, "bhi", "bhi", 16,
+ { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* dmov $R13,@$dir10 */
+ {
+ FR30_INSN_DMOVR13, "dmovr13", "dmov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* dmovh $R13,@$dir9 */
+ {
+ FR30_INSN_DMOVR13H, "dmovr13h", "dmovh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* dmovb $R13,@$dir8 */
+ {
+ FR30_INSN_DMOVR13B, "dmovr13b", "dmovb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* dmov @$R13+,@$dir10 */
+ {
+ FR30_INSN_DMOVR13PI, "dmovr13pi", "dmov", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmovh @$R13+,@$dir9 */
+ {
+ FR30_INSN_DMOVR13PIH, "dmovr13pih", "dmovh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmovb @$R13+,@$dir8 */
+ {
+ FR30_INSN_DMOVR13PIB, "dmovr13pib", "dmovb", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmov @$R15+,@$dir10 */
+ {
+ FR30_INSN_DMOVR15PI, "dmovr15pi", "dmov", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmov @$dir10,$R13 */
+ {
+ FR30_INSN_DMOV2R13, "dmov2r13", "dmov", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* dmovh @$dir9,$R13 */
+ {
+ FR30_INSN_DMOV2R13H, "dmov2r13h", "dmovh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* dmovb @$dir8,$R13 */
+ {
+ FR30_INSN_DMOV2R13B, "dmov2r13b", "dmovb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* dmov @$dir10,@$R13+ */
+ {
+ FR30_INSN_DMOV2R13PI, "dmov2r13pi", "dmov", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmovh @$dir9,@$R13+ */
+ {
+ FR30_INSN_DMOV2R13PIH, "dmov2r13pih", "dmovh", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmovb @$dir8,@$R13+ */
+ {
+ FR30_INSN_DMOV2R13PIB, "dmov2r13pib", "dmovb", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* dmov @$dir10,@-$R15 */
+ {
+ FR30_INSN_DMOV2R15PD, "dmov2r15pd", "dmov", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* ldres @$Ri+,$u4 */
+ {
+ FR30_INSN_LDRES, "ldres", "ldres", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stres $u4,@$Ri+ */
+ {
+ FR30_INSN_STRES, "stres", "stres", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* copop $u4c,$ccc,$CRj,$CRi */
+ {
+ FR30_INSN_COPOP, "copop", "copop", 32,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* copld $u4c,$ccc,$Rjc,$CRi */
+ {
+ FR30_INSN_COPLD, "copld", "copld", 32,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* copst $u4c,$ccc,$CRj,$Ric */
+ {
+ FR30_INSN_COPST, "copst", "copst", 32,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* copsv $u4c,$ccc,$CRj,$Ric */
+ {
+ FR30_INSN_COPSV, "copsv", "copsv", 32,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* nop */
+ {
+ FR30_INSN_NOP, "nop", "nop", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* andccr $u8 */
+ {
+ FR30_INSN_ANDCCR, "andccr", "andccr", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* orccr $u8 */
+ {
+ FR30_INSN_ORCCR, "orccr", "orccr", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stilm $u8 */
+ {
+ FR30_INSN_STILM, "stilm", "stilm", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addsp $s10 */
+ {
+ FR30_INSN_ADDSP, "addsp", "addsp", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* extsb $Ri */
+ {
+ FR30_INSN_EXTSB, "extsb", "extsb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* extub $Ri */
+ {
+ FR30_INSN_EXTUB, "extub", "extub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* extsh $Ri */
+ {
+ FR30_INSN_EXTSH, "extsh", "extsh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* extuh $Ri */
+ {
+ FR30_INSN_EXTUH, "extuh", "extuh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldm0 ($reglist_low_ld) */
+ {
+ FR30_INSN_LDM0, "ldm0", "ldm0", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* ldm1 ($reglist_hi_ld) */
+ {
+ FR30_INSN_LDM1, "ldm1", "ldm1", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* stm0 ($reglist_low_st) */
+ {
+ FR30_INSN_STM0, "stm0", "stm0", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* stm1 ($reglist_hi_st) */
+ {
+ FR30_INSN_STM1, "stm1", "stm1", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* enter $u10 */
+ {
+ FR30_INSN_ENTER, "enter", "enter", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+/* leave */
+ {
+ FR30_INSN_LEAVE, "leave", "leave", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* xchb @$Rj,$Ri */
+ {
+ FR30_INSN_XCHB, "xchb", "xchb", 16,
+ { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
+ },
+};
+
+#undef A
+#undef MNEM
+#undef OP
+
+/* Initialize anything needed to be done once, before any cpu_open call. */
+
+static void
+init_tables ()
+{
+}
+
+/* Subroutine of fr30_cgen_cpu_open to look up a mach via its bfd name. */
+
+static const CGEN_MACH *
+lookup_mach_via_bfd_name (table, name)
+ const CGEN_MACH *table;
+ const char *name;
+{
+ while (table->name)
+ {
+ if (strcmp (name, table->bfd_name) == 0)
+ return table;
+ ++table;
+ }
+ abort ();
+}
+
+/* Subroutine of fr30_cgen_cpu_open to build the hardware table. */
+
+static void
+build_hw_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i;
+ int machs = cd->machs;
+ const CGEN_HW_ENTRY *init = & fr30_cgen_hw_table[0];
+ /* MAX_HW is only an upper bound on the number of selected entries.
+ However each entry is indexed by it's enum so there can be holes in
+ the table. */
+ const CGEN_HW_ENTRY **selected =
+ (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
+
+ cd->hw_table.init_entries = init;
+ cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
+ memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
+ /* ??? For now we just use machs to determine which ones we want. */
+ for (i = 0; init[i].name != NULL; ++i)
+ if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
+ & machs)
+ selected[init[i].type] = &init[i];
+ cd->hw_table.entries = selected;
+ cd->hw_table.num_entries = MAX_HW;
+}
+
+/* Subroutine of fr30_cgen_cpu_open to build the hardware table. */
+
+static void
+build_ifield_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ cd->ifld_table = & fr30_cgen_ifld_table[0];
+}
+
+/* Subroutine of fr30_cgen_cpu_open to build the hardware table. */
+
+static void
+build_operand_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i;
+ int machs = cd->machs;
+ const CGEN_OPERAND *init = & fr30_cgen_operand_table[0];
+ /* MAX_OPERANDS is only an upper bound on the number of selected entries.
+ However each entry is indexed by it's enum so there can be holes in
+ the table. */
+ const CGEN_OPERAND **selected =
+ (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
+
+ cd->operand_table.init_entries = init;
+ cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
+ memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
+ /* ??? For now we just use mach to determine which ones we want. */
+ for (i = 0; init[i].name != NULL; ++i)
+ if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
+ & machs)
+ selected[init[i].type] = &init[i];
+ cd->operand_table.entries = selected;
+ cd->operand_table.num_entries = MAX_OPERANDS;
+}
+
+/* Subroutine of fr30_cgen_cpu_open to build the hardware table.
+ ??? This could leave out insns not supported by the specified mach/isa,
+ but that would cause errors like "foo only supported by bar" to become
+ "unknown insn", so for now we include all insns and require the app to
+ do the checking later.
+ ??? On the other hand, parsing of such insns may require their hardware or
+ operand elements to be in the table [which they mightn't be]. */
+
+static void
+build_insn_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i;
+ const CGEN_IBASE *ib = & fr30_cgen_insn_table[0];
+ CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
+
+ memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
+ for (i = 0; i < MAX_INSNS; ++i)
+ insns[i].base = &ib[i];
+ cd->insn_table.init_entries = insns;
+ cd->insn_table.entry_size = sizeof (CGEN_IBASE);
+ cd->insn_table.num_init_entries = MAX_INSNS;
+}
+
+/* Subroutine of fr30_cgen_cpu_open to rebuild the tables. */
+
+static void
+fr30_cgen_rebuild_tables (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i,n_isas,n_machs;
+ unsigned int isas = cd->isas;
+ unsigned int machs = cd->machs;
+
+ cd->int_insn_p = CGEN_INT_INSN_P;
+
+ /* Data derived from the isa spec. */
+#define UNSET (CGEN_SIZE_UNKNOWN + 1)
+ cd->default_insn_bitsize = UNSET;
+ cd->base_insn_bitsize = UNSET;
+ cd->min_insn_bitsize = 65535; /* some ridiculously big number */
+ cd->max_insn_bitsize = 0;
+ for (i = 0; i < MAX_ISAS; ++i)
+ if (((1 << i) & isas) != 0)
+ {
+ const CGEN_ISA *isa = & fr30_cgen_isa_table[i];
+
+ /* Default insn sizes of all selected isas must be equal or we set
+ the result to 0, meaning "unknown". */
+ if (cd->default_insn_bitsize == UNSET)
+ cd->default_insn_bitsize = isa->default_insn_bitsize;
+ else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
+ ; /* this is ok */
+ else
+ cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
+
+ /* Base insn sizes of all selected isas must be equal or we set
+ the result to 0, meaning "unknown". */
+ if (cd->base_insn_bitsize == UNSET)
+ cd->base_insn_bitsize = isa->base_insn_bitsize;
+ else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
+ ; /* this is ok */
+ else
+ cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
+
+ /* Set min,max insn sizes. */
+ if (isa->min_insn_bitsize < cd->min_insn_bitsize)
+ cd->min_insn_bitsize = isa->min_insn_bitsize;
+ if (isa->max_insn_bitsize > cd->max_insn_bitsize)
+ cd->max_insn_bitsize = isa->max_insn_bitsize;
+
+ ++n_isas;
+ }
+
+ /* Data derived from the mach spec. */
+ for (i = 0; i < MAX_MACHS; ++i)
+ if (((1 << i) & machs) != 0)
+ {
+ const CGEN_MACH *mach = & fr30_cgen_mach_table[i];
+
+ ++n_machs;
+ }
+
+ /* Determine which hw elements are used by MACH. */
+ build_hw_table (cd);
+
+ /* Build the ifield table. */
+ build_ifield_table (cd);
+
+ /* Determine which operands are used by MACH/ISA. */
+ build_operand_table (cd);
+
+ /* Build the instruction table. */
+ build_insn_table (cd);
+}
+
+/* Initialize a cpu table and return a descriptor.
+ It's much like opening a file, and must be the first function called.
+ The arguments are a set of (type/value) pairs, terminated with
+ CGEN_CPU_OPEN_END.
+
+ Currently supported values:
+ CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
+ CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
+ CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
+ CGEN_CPU_OPEN_ENDIAN: specify endian choice
+ CGEN_CPU_OPEN_END: terminates arguments
+
+ ??? Simultaneous multiple isas might not make sense, but it's not (yet)
+ precluded.
+
+ ??? We only support ISO C stdargs here, not K&R.
+ Laziness, plus experiment to see if anything requires K&R - eventually
+ K&R will no longer be supported - e.g. GDB is currently trying this. */
+
+CGEN_CPU_DESC
+fr30_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
+{
+ CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
+ static int init_p;
+ unsigned int isas = 0; /* 0 = "unspecified" */
+ unsigned int machs = 0; /* 0 = "unspecified" */
+ enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
+ va_list ap;
+
+ if (! init_p)
+ {
+ init_tables ();
+ init_p = 1;
+ }
+
+ memset (cd, 0, sizeof (*cd));
+
+ va_start (ap, arg_type);
+ while (arg_type != CGEN_CPU_OPEN_END)
+ {
+ switch (arg_type)
+ {
+ case CGEN_CPU_OPEN_ISAS :
+ isas = va_arg (ap, unsigned int);
+ break;
+ case CGEN_CPU_OPEN_MACHS :
+ machs = va_arg (ap, unsigned int);
+ break;
+ case CGEN_CPU_OPEN_BFDMACH :
+ {
+ const char *name = va_arg (ap, const char *);
+ const CGEN_MACH *mach =
+ lookup_mach_via_bfd_name (fr30_cgen_mach_table, name);
+
+ machs |= mach->num << 1;
+ break;
+ }
+ case CGEN_CPU_OPEN_ENDIAN :
+ endian = va_arg (ap, enum cgen_endian);
+ break;
+ default :
+ fprintf (stderr, "fr30_cgen_cpu_open: unsupported argument `%d'\n",
+ arg_type);
+ abort (); /* ??? return NULL? */
+ }
+ arg_type = va_arg (ap, enum cgen_cpu_open_arg);
+ }
+ va_end (ap);
+
+ /* mach unspecified means "all" */
+ if (machs == 0)
+ machs = (1 << MAX_MACHS) - 1;
+ /* base mach is always selected */
+ machs |= 1;
+ /* isa unspecified means "all" */
+ if (isas == 0)
+ isas = (1 << MAX_ISAS) - 1;
+ if (endian == CGEN_ENDIAN_UNKNOWN)
+ {
+ /* ??? If target has only one, could have a default. */
+ fprintf (stderr, "fr30_cgen_cpu_open: no endianness specified\n");
+ abort ();
+ }
+
+ cd->isas = isas;
+ cd->machs = machs;
+ cd->endian = endian;
+ /* FIXME: for the sparc case we can determine insn-endianness statically.
+ The worry here is where both data and insn endian can be independently
+ chosen, in which case this function will need another argument.
+ Actually, will want to allow for more arguments in the future anyway. */
+ cd->insn_endian = endian;
+
+ /* Table (re)builder. */
+ cd->rebuild_tables = fr30_cgen_rebuild_tables;
+ fr30_cgen_rebuild_tables (cd);
+
+ return (CGEN_CPU_DESC) cd;
+}
+
+/* Cover fn to fr30_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
+ MACH_NAME is the bfd name of the mach. */
+
+CGEN_CPU_DESC
+fr30_cgen_cpu_open_1 (mach_name, endian)
+ const char *mach_name;
+ enum cgen_endian endian;
+{
+ return fr30_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
+ CGEN_CPU_OPEN_ENDIAN, endian,
+ CGEN_CPU_OPEN_END);
+}
+
+/* Close a cpu table.
+ ??? This can live in a machine independent file, but there's currently
+ no place to put this file (there's no libcgen). libopcodes is the wrong
+ place as some simulator ports use this but they don't use libopcodes. */
+
+void
+fr30_cgen_cpu_close (cd)
+ CGEN_CPU_DESC cd;
+{
+ if (cd->insn_table.init_entries)
+ free ((CGEN_INSN *) cd->insn_table.init_entries);
+ if (cd->hw_table.entries)
+ free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
+ free (cd);
+}
+
diff --git a/opcodes/fr30-desc.h b/opcodes/fr30-desc.h
new file mode 100644
index 00000000000..0289156bca3
--- /dev/null
+++ b/opcodes/fr30-desc.h
@@ -0,0 +1,266 @@
+/* CPU data header for fr30.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef FR30_CPU_H
+#define FR30_CPU_H
+
+#define CGEN_ARCH fr30
+
+/* Given symbol S, return fr30_cgen_<S>. */
+#define CGEN_SYM(s) CONCAT3 (fr30,_cgen_,s)
+
+/* Selected cpu families. */
+#define HAVE_CPU_FR30BF
+
+#define CGEN_INSN_LSB0_P 0
+
+/* Maximum size of any insn (in bytes). */
+#define CGEN_MAX_INSN_SIZE 6
+
+#define CGEN_INT_INSN_P 0
+
+/* FIXME: Need to compute CGEN_MAX_SYNTAX_BYTES. */
+
+/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands.
+ e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands
+ we can't hash on everything up to the space. */
+#define CGEN_MNEMONIC_OPERANDS
+/* Maximum number of operands any insn or macro-insn has. */
+#define CGEN_MAX_INSN_OPERANDS 16
+
+/* Maximum number of fields in an instruction. */
+#define CGEN_MAX_IFMT_OPERANDS 7
+
+/* Enums. */
+
+/* Enum declaration for insn op1 enums. */
+typedef enum insn_op1 {
+ OP1_0, OP1_1, OP1_2, OP1_3
+ , OP1_4, OP1_5, OP1_6, OP1_7
+ , OP1_8, OP1_9, OP1_A, OP1_B
+ , OP1_C, OP1_D, OP1_E, OP1_F
+} INSN_OP1;
+
+/* Enum declaration for insn op2 enums. */
+typedef enum insn_op2 {
+ OP2_0, OP2_1, OP2_2, OP2_3
+ , OP2_4, OP2_5, OP2_6, OP2_7
+ , OP2_8, OP2_9, OP2_A, OP2_B
+ , OP2_C, OP2_D, OP2_E, OP2_F
+} INSN_OP2;
+
+/* Enum declaration for insn op3 enums. */
+typedef enum insn_op3 {
+ OP3_0, OP3_1, OP3_2, OP3_3
+ , OP3_4, OP3_5, OP3_6, OP3_7
+ , OP3_8, OP3_9, OP3_A, OP3_B
+ , OP3_C, OP3_D, OP3_E, OP3_F
+} INSN_OP3;
+
+/* Enum declaration for insn op4 enums. */
+typedef enum insn_op4 {
+ OP4_0
+} INSN_OP4;
+
+/* Enum declaration for insn op5 enums. */
+typedef enum insn_op5 {
+ OP5_0, OP5_1
+} INSN_OP5;
+
+/* Enum declaration for insn cc enums. */
+typedef enum insn_cc {
+ CC_RA, CC_NO, CC_EQ, CC_NE
+ , CC_C, CC_NC, CC_N, CC_P
+ , CC_V, CC_NV, CC_LT, CC_GE
+ , CC_LE, CC_GT, CC_LS, CC_HI
+} INSN_CC;
+
+/* Enum declaration for . */
+typedef enum gr_names {
+ H_GR_R0 = 0, H_GR_R1 = 1, H_GR_R2 = 2, H_GR_R3 = 3
+ , H_GR_R4 = 4, H_GR_R5 = 5, H_GR_R6 = 6, H_GR_R7 = 7
+ , H_GR_R8 = 8, H_GR_R9 = 9, H_GR_R10 = 10, H_GR_R11 = 11
+ , H_GR_R12 = 12, H_GR_R13 = 13, H_GR_R14 = 14, H_GR_R15 = 15
+ , H_GR_AC = 13, H_GR_FP = 14, H_GR_SP = 15
+} GR_NAMES;
+
+/* Enum declaration for . */
+typedef enum cr_names {
+ H_CR_CR0, H_CR_CR1, H_CR_CR2, H_CR_CR3
+ , H_CR_CR4, H_CR_CR5, H_CR_CR6, H_CR_CR7
+ , H_CR_CR8, H_CR_CR9, H_CR_CR10, H_CR_CR11
+ , H_CR_CR12, H_CR_CR13, H_CR_CR14, H_CR_CR15
+} CR_NAMES;
+
+/* Enum declaration for . */
+typedef enum dr_names {
+ H_DR_TBR, H_DR_RP, H_DR_SSP, H_DR_USP
+ , H_DR_MDH, H_DR_MDL
+} DR_NAMES;
+
+/* Attributes. */
+
+/* Enum declaration for machine type selection. */
+typedef enum mach_attr {
+ MACH_BASE, MACH_FR30, MACH_MAX
+} MACH_ATTR;
+
+/* Enum declaration for instruction set selection. */
+typedef enum isa_attr {
+ ISA_FR30, ISA_MAX
+} ISA_ATTR;
+
+/* Number of architecture variants. */
+#define MAX_ISAS 1
+#define MAX_MACHS ((int) MACH_MAX)
+
+/* Ifield support. */
+
+extern const struct cgen_ifld fr30_cgen_ifld_table[];
+
+/* Ifield attribute indices. */
+
+/* Enum declaration for cgen_ifld attrs. */
+typedef enum cgen_ifld_attr {
+ CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED
+ , CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31
+ , CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS
+} CGEN_IFLD_ATTR;
+
+/* Number of non-boolean elements in cgen_ifld_attr. */
+#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1)
+
+/* Enum declaration for fr30 ifield types. */
+typedef enum ifield_type {
+ FR30_F_NIL, FR30_F_OP1, FR30_F_OP2, FR30_F_OP3
+ , FR30_F_OP4, FR30_F_OP5, FR30_F_CC, FR30_F_CCC
+ , FR30_F_RJ, FR30_F_RI, FR30_F_RS1, FR30_F_RS2
+ , FR30_F_RJC, FR30_F_RIC, FR30_F_CRJ, FR30_F_CRI
+ , FR30_F_U4, FR30_F_U4C, FR30_F_I4, FR30_F_M4
+ , FR30_F_U8, FR30_F_I8, FR30_F_I20_4, FR30_F_I20_16
+ , FR30_F_I20, FR30_F_I32, FR30_F_UDISP6, FR30_F_DISP8
+ , FR30_F_DISP9, FR30_F_DISP10, FR30_F_S10, FR30_F_U10
+ , FR30_F_REL9, FR30_F_DIR8, FR30_F_DIR9, FR30_F_DIR10
+ , FR30_F_REL12, FR30_F_REGLIST_HI_ST, FR30_F_REGLIST_LOW_ST, FR30_F_REGLIST_HI_LD
+ , FR30_F_REGLIST_LOW_LD, FR30_F_MAX
+} IFIELD_TYPE;
+
+#define MAX_IFLD ((int) FR30_F_MAX)
+
+/* Hardware attribute indices. */
+
+/* Enum declaration for cgen_hw attrs. */
+typedef enum cgen_hw_attr {
+ CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
+ , CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS
+} CGEN_HW_ATTR;
+
+/* Number of non-boolean elements in cgen_hw_attr. */
+#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1)
+
+/* Enum declaration for fr30 hardware types. */
+typedef enum cgen_hw_type {
+ HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR
+ , HW_H_IADDR, HW_H_PC, HW_H_GR, HW_H_CR
+ , HW_H_DR, HW_H_PS, HW_H_R13, HW_H_R14
+ , HW_H_R15, HW_H_NBIT, HW_H_ZBIT, HW_H_VBIT
+ , HW_H_CBIT, HW_H_IBIT, HW_H_SBIT, HW_H_TBIT
+ , HW_H_D0BIT, HW_H_D1BIT, HW_H_CCR, HW_H_SCR
+ , HW_H_ILM, HW_MAX
+} CGEN_HW_TYPE;
+
+#define MAX_HW ((int) HW_MAX)
+
+/* Operand attribute indices. */
+
+/* Enum declaration for cgen_operand attrs. */
+typedef enum cgen_operand_attr {
+ CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT
+ , CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY
+ , CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH
+ , CGEN_OPERAND_END_NBOOLS
+} CGEN_OPERAND_ATTR;
+
+/* Number of non-boolean elements in cgen_operand_attr. */
+#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1)
+
+/* Enum declaration for fr30 operand types. */
+typedef enum cgen_operand_type {
+ FR30_OPERAND_PC, FR30_OPERAND_RI, FR30_OPERAND_RJ, FR30_OPERAND_RIC
+ , FR30_OPERAND_RJC, FR30_OPERAND_CRI, FR30_OPERAND_CRJ, FR30_OPERAND_RS1
+ , FR30_OPERAND_RS2, FR30_OPERAND_R13, FR30_OPERAND_R14, FR30_OPERAND_R15
+ , FR30_OPERAND_PS, FR30_OPERAND_U4, FR30_OPERAND_U4C, FR30_OPERAND_U8
+ , FR30_OPERAND_I8, FR30_OPERAND_UDISP6, FR30_OPERAND_DISP8, FR30_OPERAND_DISP9
+ , FR30_OPERAND_DISP10, FR30_OPERAND_S10, FR30_OPERAND_U10, FR30_OPERAND_I32
+ , FR30_OPERAND_M4, FR30_OPERAND_I20, FR30_OPERAND_DIR8, FR30_OPERAND_DIR9
+ , FR30_OPERAND_DIR10, FR30_OPERAND_LABEL9, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW_LD
+ , FR30_OPERAND_REGLIST_HI_LD, FR30_OPERAND_REGLIST_LOW_ST, FR30_OPERAND_REGLIST_HI_ST, FR30_OPERAND_CC
+ , FR30_OPERAND_CCC, FR30_OPERAND_NBIT, FR30_OPERAND_VBIT, FR30_OPERAND_ZBIT
+ , FR30_OPERAND_CBIT, FR30_OPERAND_IBIT, FR30_OPERAND_SBIT, FR30_OPERAND_TBIT
+ , FR30_OPERAND_D0BIT, FR30_OPERAND_D1BIT, FR30_OPERAND_CCR, FR30_OPERAND_SCR
+ , FR30_OPERAND_ILM, FR30_OPERAND_MAX
+} CGEN_OPERAND_TYPE;
+
+/* Number of operands types. */
+#define MAX_OPERANDS ((int) FR30_OPERAND_MAX)
+
+/* Maximum number of operands referenced by any insn. */
+#define MAX_OPERAND_INSTANCES 8
+
+/* Insn attribute indices. */
+
+/* Enum declaration for cgen_insn attrs. */
+typedef enum cgen_insn_attr {
+ CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
+ , CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX
+ , CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_NOT_IN_DELAY_SLOT, CGEN_INSN_END_BOOLS
+ , CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_END_NBOOLS
+} CGEN_INSN_ATTR;
+
+/* Number of non-boolean elements in cgen_insn_attr. */
+#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1)
+
+/* cgen.h uses things we just defined. */
+#include "opcode/cgen.h"
+
+/* Attributes. */
+extern const CGEN_ATTR_TABLE fr30_cgen_hardware_attr_table[];
+extern const CGEN_ATTR_TABLE fr30_cgen_ifield_attr_table[];
+extern const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[];
+extern const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[];
+
+/* Hardware decls. */
+
+extern CGEN_KEYWORD fr30_cgen_opval_gr_names;
+extern CGEN_KEYWORD fr30_cgen_opval_cr_names;
+extern CGEN_KEYWORD fr30_cgen_opval_dr_names;
+extern CGEN_KEYWORD fr30_cgen_opval_h_ps;
+extern CGEN_KEYWORD fr30_cgen_opval_h_r13;
+extern CGEN_KEYWORD fr30_cgen_opval_h_r14;
+extern CGEN_KEYWORD fr30_cgen_opval_h_r15;
+
+
+
+
+#endif /* FR30_CPU_H */
diff --git a/opcodes/fr30-dis.c b/opcodes/fr30-dis.c
new file mode 100644
index 00000000000..0d7c18c766d
--- /dev/null
+++ b/opcodes/fr30-dis.c
@@ -0,0 +1,630 @@
+/* Disassembler interface for targets using CGEN. -*- C -*-
+ CGEN: Cpu tools GENerator
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+- the resultant file is machine generated, cgen-dis.in isn't
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ??? Eventually more and more of this stuff can go to cpu-independent files.
+ Keep that in mind. */
+
+#include "sysdep.h"
+#include <stdio.h>
+#include "ansidecl.h"
+#include "dis-asm.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "fr30-desc.h"
+#include "fr30-opc.h"
+#include "opintl.h"
+
+/* Default text to print if an instruction isn't recognized. */
+#define UNKNOWN_INSN_MSG _("*unknown*")
+
+static void print_normal
+ PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned int, bfd_vma, int));
+static void print_address
+ PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
+static void print_keyword
+ PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
+static void print_insn_normal
+ PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
+ bfd_vma, int));
+static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma,
+ disassemble_info *, char *, int));
+static int default_print_insn
+ PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
+
+/* -- disassembler routines inserted here */
+
+/* -- dis.c */
+
+static void
+print_register_list (dis_info, value, offset, load_store)
+ PTR dis_info;
+ long value;
+ long offset;
+ int load_store; /* 0 == load, 1 == store */
+{
+ disassemble_info *info = dis_info;
+ int mask;
+ int index = 0;
+ char* comma = "";
+
+ if (load_store)
+ mask = 0x80;
+ else
+ mask = 1;
+
+ if (value & mask)
+ {
+ (*info->fprintf_func) (info->stream, "r%i", index + offset);
+ comma = ",";
+ }
+
+ for (index = 1; index <= 7; ++index)
+ {
+ if (load_store)
+ mask >>= 1;
+ else
+ mask <<= 1;
+
+ if (value & mask)
+ {
+ (*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset);
+ comma = ",";
+ }
+ }
+}
+
+static void
+print_hi_register_list_ld (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 8, 0/*load*/);
+}
+
+static void
+print_low_register_list_ld (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 0, 0/*load*/);
+}
+
+static void
+print_hi_register_list_st (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 8, 1/*store*/);
+}
+
+static void
+print_low_register_list_st (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ print_register_list (dis_info, value, 0, 1/*store*/);
+}
+
+static void
+print_m4 (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+ (*info->fprintf_func) (info->stream, "%ld", value);
+}
+/* -- */
+
+/* Main entry point for printing operands.
+ XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
+ of dis-asm.h on cgen.h.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `print_insn_normal', but keeping it
+ separate makes clear the interface between `print_insn_normal' and each of
+ the handlers.
+*/
+
+void
+fr30_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ PTR xinfo;
+ CGEN_FIELDS *fields;
+ void const *attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) xinfo;
+
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRi, 0);
+ break;
+ case FR30_OPERAND_CRJ :
+ print_keyword (cd, info, & fr30_cgen_opval_cr_names, fields->f_CRj, 0);
+ break;
+ case FR30_OPERAND_R13 :
+ print_keyword (cd, info, & fr30_cgen_opval_h_r13, fields->f_nil, 0);
+ break;
+ case FR30_OPERAND_R14 :
+ print_keyword (cd, info, & fr30_cgen_opval_h_r14, fields->f_nil, 0);
+ break;
+ case FR30_OPERAND_R15 :
+ print_keyword (cd, info, & fr30_cgen_opval_h_r15, fields->f_nil, 0);
+ break;
+ case FR30_OPERAND_RI :
+ print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ri, 0);
+ break;
+ case FR30_OPERAND_RIC :
+ print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Ric, 0);
+ break;
+ case FR30_OPERAND_RJ :
+ print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rj, 0);
+ break;
+ case FR30_OPERAND_RJC :
+ print_keyword (cd, info, & fr30_cgen_opval_gr_names, fields->f_Rjc, 0);
+ break;
+ case FR30_OPERAND_RS1 :
+ print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs1, 0);
+ break;
+ case FR30_OPERAND_RS2 :
+ print_keyword (cd, info, & fr30_cgen_opval_dr_names, fields->f_Rs2, 0);
+ break;
+ case FR30_OPERAND_CC :
+ print_normal (cd, info, fields->f_cc, 0, pc, length);
+ break;
+ case FR30_OPERAND_CCC :
+ print_normal (cd, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_DIR10 :
+ print_normal (cd, info, fields->f_dir10, 0, pc, length);
+ break;
+ case FR30_OPERAND_DIR8 :
+ print_normal (cd, info, fields->f_dir8, 0, pc, length);
+ break;
+ case FR30_OPERAND_DIR9 :
+ print_normal (cd, info, fields->f_dir9, 0, pc, length);
+ break;
+ case FR30_OPERAND_DISP10 :
+ print_normal (cd, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_DISP8 :
+ print_normal (cd, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_DISP9 :
+ print_normal (cd, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_I20 :
+ print_normal (cd, info, fields->f_i20, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
+ break;
+ case FR30_OPERAND_I32 :
+ print_normal (cd, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
+ break;
+ case FR30_OPERAND_I8 :
+ print_normal (cd, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_LABEL12 :
+ print_address (cd, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
+ break;
+ case FR30_OPERAND_LABEL9 :
+ print_address (cd, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
+ break;
+ case FR30_OPERAND_M4 :
+ print_m4 (cd, info, fields->f_m4, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_PS :
+ print_keyword (cd, info, & fr30_cgen_opval_h_ps, fields->f_nil, 0);
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ print_hi_register_list_ld (cd, info, fields->f_reglist_hi_ld, 0, pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ print_hi_register_list_st (cd, info, fields->f_reglist_hi_st, 0, pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ print_low_register_list_ld (cd, info, fields->f_reglist_low_ld, 0, pc, length);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ print_low_register_list_st (cd, info, fields->f_reglist_low_st, 0, pc, length);
+ break;
+ case FR30_OPERAND_S10 :
+ print_normal (cd, info, fields->f_s10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_U10 :
+ print_normal (cd, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_U4 :
+ print_normal (cd, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_U4C :
+ print_normal (cd, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_U8 :
+ print_normal (cd, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case FR30_OPERAND_UDISP6 :
+ print_normal (cd, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
+ opindex);
+ abort ();
+ }
+}
+
+cgen_print_fn * const fr30_cgen_print_handlers[] =
+{
+ print_insn_normal,
+};
+
+
+void
+fr30_cgen_init_dis (cd)
+ CGEN_CPU_DESC cd;
+{
+ fr30_cgen_init_opcode_table (cd);
+ fr30_cgen_init_ibld_table (cd);
+ cd->print_handlers = & fr30_cgen_print_handlers[0];
+ cd->print_operand = fr30_cgen_print_operand;
+}
+
+
+/* Default print handler. */
+
+static void
+print_normal (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+
+#ifdef CGEN_PRINT_NORMAL
+ CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
+#endif
+
+ /* Print the operand as directed by the attributes. */
+ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
+ ; /* nothing to do */
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
+ (*info->fprintf_func) (info->stream, "%ld", value);
+ else
+ (*info->fprintf_func) (info->stream, "0x%lx", value);
+}
+
+/* Default address handler. */
+
+static void
+print_address (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ bfd_vma value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+
+#ifdef CGEN_PRINT_ADDRESS
+ CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
+#endif
+
+ /* Print the operand as directed by the attributes. */
+ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
+ ; /* nothing to do */
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
+ (*info->print_address_func) (value, info);
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
+ (*info->print_address_func) (value, info);
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
+ (*info->fprintf_func) (info->stream, "%ld", (long) value);
+ else
+ (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
+}
+
+/* Keyword print handler. */
+
+static void
+print_keyword (cd, dis_info, keyword_table, value, attrs)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ CGEN_KEYWORD *keyword_table;
+ long value;
+ unsigned int attrs;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+ const CGEN_KEYWORD_ENTRY *ke;
+
+ ke = cgen_keyword_lookup_value (keyword_table, value);
+ if (ke != NULL)
+ (*info->fprintf_func) (info->stream, "%s", ke->name);
+ else
+ (*info->fprintf_func) (info->stream, "???");
+}
+
+/* Default insn printer.
+
+ DIS_INFO is defined as `PTR' so the disassembler needn't know anything
+ about disassemble_info. */
+
+static void
+print_insn_normal (cd, dis_info, insn, fields, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ const CGEN_INSN *insn;
+ CGEN_FIELDS *fields;
+ bfd_vma pc;
+ int length;
+{
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ disassemble_info *info = (disassemble_info *) dis_info;
+ const unsigned char *syn;
+
+ CGEN_INIT_PRINT (cd);
+
+ for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
+ {
+ if (CGEN_SYNTAX_MNEMONIC_P (*syn))
+ {
+ (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
+ continue;
+ }
+ if (CGEN_SYNTAX_CHAR_P (*syn))
+ {
+ (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
+ continue;
+ }
+
+ /* We have an operand. */
+ fr30_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
+ fields, CGEN_INSN_ATTRS (insn), pc, length);
+ }
+}
+
+/* Utility to print an insn.
+ BUF is the base part of the insn, target byte order, BUFLEN bytes long.
+ The result is the size of the insn in bytes or zero for an unknown insn
+ or -1 if an error occurs fetching data (memory_error_func will have
+ been called). */
+
+static int
+print_insn (cd, pc, info, buf, buflen)
+ CGEN_CPU_DESC cd;
+ bfd_vma pc;
+ disassemble_info *info;
+ char *buf;
+ int buflen;
+{
+ unsigned long insn_value;
+ const CGEN_INSN_LIST *insn_list;
+ CGEN_EXTRACT_INFO ex_info;
+
+ ex_info.dis_info = info;
+ ex_info.valid = (1 << (cd->base_insn_bitsize / 8)) - 1;
+ ex_info.insn_bytes = buf;
+
+ switch (buflen)
+ {
+ case 1:
+ insn_value = buf[0];
+ break;
+ case 2:
+ insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
+ break;
+ case 4:
+ insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
+ break;
+ default:
+ abort ();
+ }
+
+ /* The instructions are stored in hash lists.
+ Pick the first one and keep trying until we find the right one. */
+
+ insn_list = CGEN_DIS_LOOKUP_INSN (cd, buf, insn_value);
+ while (insn_list != NULL)
+ {
+ const CGEN_INSN *insn = insn_list->insn;
+ CGEN_FIELDS fields;
+ int length;
+
+#if 0 /* not needed as insn shouldn't be in hash lists if not supported */
+ /* Supported by this cpu? */
+ if (! fr30_cgen_insn_supported (cd, insn))
+ continue;
+#endif
+
+ /* Basic bit mask must be correct. */
+ /* ??? May wish to allow target to defer this check until the extract
+ handler. */
+ if ((insn_value & CGEN_INSN_BASE_MASK (insn))
+ == CGEN_INSN_BASE_VALUE (insn))
+ {
+ /* Printing is handled in two passes. The first pass parses the
+ machine insn and extracts the fields. The second pass prints
+ them. */
+
+ length = CGEN_EXTRACT_FN (cd, insn)
+ (cd, insn, &ex_info, insn_value, &fields, pc);
+ /* length < 0 -> error */
+ if (length < 0)
+ return length;
+ if (length > 0)
+ {
+ CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
+ /* length is in bits, result is in bytes */
+ return length / 8;
+ }
+ }
+
+ insn_list = CGEN_DIS_NEXT_INSN (insn_list);
+ }
+
+ return 0;
+}
+
+/* Default value for CGEN_PRINT_INSN.
+ The result is the size of the insn in bytes or zero for an unknown insn
+ or -1 if an error occured fetching bytes. */
+
+#ifndef CGEN_PRINT_INSN
+#define CGEN_PRINT_INSN default_print_insn
+#endif
+
+static int
+default_print_insn (cd, pc, info)
+ CGEN_CPU_DESC cd;
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ char buf[CGEN_MAX_INSN_SIZE];
+ int status;
+
+ /* Read the base part of the insn. */
+
+ status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+
+ return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
+}
+
+/* Main entry point.
+ Print one instruction from PC on INFO->STREAM.
+ Return the size of the instruction (in bytes). */
+
+int
+print_insn_fr30 (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ static CGEN_CPU_DESC cd = 0;
+ static prev_isa,prev_mach,prev_endian;
+ int length;
+ int isa,mach;
+ int endian = (info->endian == BFD_ENDIAN_BIG
+ ? CGEN_ENDIAN_BIG
+ : CGEN_ENDIAN_LITTLE);
+ enum bfd_architecture arch;
+
+ /* ??? gdb will set mach but leave the architecture as "unknown" */
+#ifndef CGEN_BFD_ARCH
+#define CGEN_BFD_ARCH bfd_arch_fr30
+#endif
+ arch = info->arch;
+ if (arch == bfd_arch_unknown)
+ arch = CGEN_BFD_ARCH;
+
+ /* There's no standard way to compute the isa number (e.g. for arm thumb)
+ so we leave it to the target. */
+#ifdef CGEN_COMPUTE_ISA
+ isa = CGEN_COMPUTE_ISA (info);
+#else
+ isa = 0;
+#endif
+
+ mach = info->mach;
+
+ /* If we've switched cpu's, close the current table and open a new one. */
+ if (cd
+ && (isa != prev_isa
+ || mach != prev_mach
+ || endian != prev_endian))
+ {
+ fr30_cgen_cpu_close (cd);
+ cd = 0;
+ }
+
+ /* If we haven't initialized yet, initialize the opcode table. */
+ if (! cd)
+ {
+ const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
+ const char *mach_name;
+
+ if (!arch_type)
+ abort ();
+ mach_name = arch_type->printable_name;
+
+ prev_isa = isa;
+ prev_mach = mach;
+ prev_endian = endian;
+ cd = fr30_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
+ CGEN_CPU_OPEN_BFDMACH, mach_name,
+ CGEN_CPU_OPEN_ENDIAN, prev_endian,
+ CGEN_CPU_OPEN_END);
+ if (!cd)
+ abort ();
+ fr30_cgen_init_dis (cd);
+ }
+
+ /* We try to have as much common code as possible.
+ But at this point some targets need to take over. */
+ /* ??? Some targets may need a hook elsewhere. Try to avoid this,
+ but if not possible try to move this hook elsewhere rather than
+ have two hooks. */
+ length = CGEN_PRINT_INSN (cd, pc, info);
+ if (length > 0)
+ return length;
+ if (length < 0)
+ return -1;
+
+ (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
+ return cd->default_insn_bitsize / 8;
+}
diff --git a/opcodes/fr30-ibld.c b/opcodes/fr30-ibld.c
new file mode 100644
index 00000000000..386613d41c7
--- /dev/null
+++ b/opcodes/fr30-ibld.c
@@ -0,0 +1,1506 @@
+/* Instruction building/extraction support for fr30. -*- C -*-
+
+THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
+- the resultant file is machine generated, cgen-ibld.in isn't
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ??? Eventually more and more of this stuff can go to cpu-independent files.
+ Keep that in mind. */
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include "ansidecl.h"
+#include "dis-asm.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "fr30-desc.h"
+#include "fr30-opc.h"
+#include "opintl.h"
+
+#undef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#undef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+/* Used by the ifield rtx function. */
+#define FLD(f) (fields->f)
+
+static const char * insert_normal
+ PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
+static const char * insert_insn_normal
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
+ CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
+
+static int extract_normal
+ PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
+ unsigned int, unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int, bfd_vma, long *));
+static int extract_insn_normal
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
+ CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
+
+/* Operand insertion. */
+
+#if ! CGEN_INT_INSN_P
+
+/* Subroutine of insert_normal. */
+
+static CGEN_INLINE void
+insert_1 (cd, value, start, length, word_length, bufp)
+ CGEN_CPU_DESC cd;
+ unsigned long value;
+ int start,length,word_length;
+ unsigned char *bufp;
+{
+ unsigned long x,mask;
+ int shift;
+ int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
+
+ switch (word_length)
+ {
+ case 8:
+ x = *bufp;
+ break;
+ case 16:
+ if (big_p)
+ x = bfd_getb16 (bufp);
+ else
+ x = bfd_getl16 (bufp);
+ break;
+ case 24:
+ /* ??? This may need reworking as these cases don't necessarily
+ want the first byte and the last two bytes handled like this. */
+ if (big_p)
+ x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
+ else
+ x = bfd_getl16 (bufp) | (bufp[2] << 16);
+ break;
+ case 32:
+ if (big_p)
+ x = bfd_getb32 (bufp);
+ else
+ x = bfd_getl32 (bufp);
+ break;
+ default :
+ abort ();
+ }
+
+ /* Written this way to avoid undefined behaviour. */
+ mask = (((1L << (length - 1)) - 1) << 1) | 1;
+ if (CGEN_INSN_LSB0_P)
+ shift = (start + 1) - length;
+ else
+ shift = (word_length - (start + length));
+ x = (x & ~(mask << shift)) | ((value & mask) << shift);
+
+ switch (word_length)
+ {
+ case 8:
+ *bufp = x;
+ break;
+ case 16:
+ if (big_p)
+ bfd_putb16 (x, bufp);
+ else
+ bfd_putl16 (x, bufp);
+ break;
+ case 24:
+ /* ??? This may need reworking as these cases don't necessarily
+ want the first byte and the last two bytes handled like this. */
+ if (big_p)
+ {
+ bufp[0] = x >> 16;
+ bfd_putb16 (x, bufp + 1);
+ }
+ else
+ {
+ bfd_putl16 (x, bufp);
+ bufp[2] = x >> 16;
+ }
+ break;
+ case 32:
+ if (big_p)
+ bfd_putb32 (x, bufp);
+ else
+ bfd_putl32 (x, bufp);
+ break;
+ default :
+ abort ();
+ }
+}
+
+#endif /* ! CGEN_INT_INSN_P */
+
+/* Default insertion routine.
+
+ ATTRS is a mask of the boolean attributes.
+ WORD_OFFSET is the offset in bits from the start of the insn of the value.
+ WORD_LENGTH is the length of the word in bits in which the value resides.
+ START is the starting bit number in the word, architecture origin.
+ LENGTH is the length of VALUE in bits.
+ TOTAL_LENGTH is the total length of the insn in bits.
+
+ The result is an error message or NULL if success. */
+
+/* ??? This duplicates functionality with bfd's howto table and
+ bfd_install_relocation. */
+/* ??? This doesn't handle bfd_vma's. Create another function when
+ necessary. */
+
+static const char *
+insert_normal (cd, value, attrs, word_offset, start, length, word_length,
+ total_length, buffer)
+ CGEN_CPU_DESC cd;
+ long value;
+ unsigned int attrs;
+ unsigned int word_offset, start, length, word_length, total_length;
+ CGEN_INSN_BYTES_PTR buffer;
+{
+ static char errbuf[100];
+ /* Written this way to avoid undefined behaviour. */
+ unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
+
+ /* If LENGTH is zero, this operand doesn't contribute to the value. */
+ if (length == 0)
+ return NULL;
+
+ if (CGEN_INT_INSN_P
+ && word_offset != 0)
+ abort ();
+
+ if (word_length > 32)
+ abort ();
+
+ /* For architectures with insns smaller than the base-insn-bitsize,
+ word_length may be too big. */
+ if (cd->min_insn_bitsize < cd->base_insn_bitsize)
+ {
+ if (word_offset == 0
+ && word_length > total_length)
+ word_length = total_length;
+ }
+
+ /* Ensure VALUE will fit. */
+ if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
+ {
+ unsigned long maxval = mask;
+ if ((unsigned long) value > maxval)
+ {
+ /* xgettext:c-format */
+ sprintf (errbuf,
+ _("operand out of range (%lu not between 0 and %lu)"),
+ value, maxval);
+ return errbuf;
+ }
+ }
+ else
+ {
+ long minval = - (1L << (length - 1));
+ long maxval = (1L << (length - 1)) - 1;
+ if (value < minval || value > maxval)
+ {
+ sprintf
+ /* xgettext:c-format */
+ (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
+ value, minval, maxval);
+ return errbuf;
+ }
+ }
+
+#if CGEN_INT_INSN_P
+
+ {
+ int shift;
+
+ if (CGEN_INSN_LSB0_P)
+ shift = (start + 1) - length;
+ else
+ shift = word_length - (start + length);
+ *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
+ }
+
+#else /* ! CGEN_INT_INSN_P */
+
+ {
+ unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
+
+ insert_1 (cd, value, start, length, word_length, bufp);
+ }
+
+#endif /* ! CGEN_INT_INSN_P */
+
+ return NULL;
+}
+
+/* Default insn builder (insert handler).
+ The instruction is recorded in CGEN_INT_INSN_P byte order
+ (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
+ recorded in host byte order, otherwise BUFFER is an array of bytes and the
+ value is recorded in target byte order).
+ The result is an error message or NULL if success. */
+
+static const char *
+insert_insn_normal (cd, insn, fields, buffer, pc)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN * insn;
+ CGEN_FIELDS * fields;
+ CGEN_INSN_BYTES_PTR buffer;
+ bfd_vma pc;
+{
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ unsigned long value;
+ const unsigned char * syn;
+
+ CGEN_INIT_INSERT (cd);
+ value = CGEN_INSN_BASE_VALUE (insn);
+
+ /* If we're recording insns as numbers (rather than a string of bytes),
+ target byte order handling is deferred until later. */
+
+#if CGEN_INT_INSN_P
+
+ *buffer = value;
+
+#else
+
+ cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
+ CGEN_FIELDS_BITSIZE (fields)),
+ value);
+
+#endif /* ! CGEN_INT_INSN_P */
+
+ /* ??? It would be better to scan the format's fields.
+ Still need to be able to insert a value based on the operand though;
+ e.g. storing a branch displacement that got resolved later.
+ Needs more thought first. */
+
+ for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
+ {
+ const char *errmsg;
+
+ if (CGEN_SYNTAX_CHAR_P (* syn))
+ continue;
+
+ errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
+ fields, buffer, pc);
+ if (errmsg)
+ return errmsg;
+ }
+
+ return NULL;
+}
+
+/* Operand extraction. */
+
+#if ! CGEN_INT_INSN_P
+
+/* Subroutine of extract_normal.
+ Ensure sufficient bytes are cached in EX_INFO.
+ OFFSET is the offset in bytes from the start of the insn of the value.
+ BYTES is the length of the needed value.
+ Returns 1 for success, 0 for failure. */
+
+static CGEN_INLINE int
+fill_cache (cd, ex_info, offset, bytes, pc)
+ CGEN_CPU_DESC cd;
+ CGEN_EXTRACT_INFO *ex_info;
+ int offset, bytes;
+ bfd_vma pc;
+{
+ /* It's doubtful that the middle part has already been fetched so
+ we don't optimize that case. kiss. */
+ int mask;
+ disassemble_info *info = (disassemble_info *) ex_info->dis_info;
+
+ /* First do a quick check. */
+ mask = (1 << bytes) - 1;
+ if (((ex_info->valid >> offset) & mask) == mask)
+ return 1;
+
+ /* Search for the first byte we need to read. */
+ for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
+ if (! (mask & ex_info->valid))
+ break;
+
+ if (bytes)
+ {
+ int status;
+
+ pc += offset;
+ status = (*info->read_memory_func)
+ (pc, ex_info->insn_bytes + offset, bytes, info);
+
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return 0;
+ }
+
+ ex_info->valid |= ((1 << bytes) - 1) << offset;
+ }
+
+ return 1;
+}
+
+/* Subroutine of extract_normal. */
+
+static CGEN_INLINE long
+extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
+ CGEN_CPU_DESC cd;
+ CGEN_EXTRACT_INFO *ex_info;
+ int start,length,word_length;
+ unsigned char *bufp;
+ bfd_vma pc;
+{
+ unsigned long x,mask;
+ int shift;
+ int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
+
+ switch (word_length)
+ {
+ case 8:
+ x = *bufp;
+ break;
+ case 16:
+ if (big_p)
+ x = bfd_getb16 (bufp);
+ else
+ x = bfd_getl16 (bufp);
+ break;
+ case 24:
+ /* ??? This may need reworking as these cases don't necessarily
+ want the first byte and the last two bytes handled like this. */
+ if (big_p)
+ x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
+ else
+ x = bfd_getl16 (bufp) | (bufp[2] << 16);
+ break;
+ case 32:
+ if (big_p)
+ x = bfd_getb32 (bufp);
+ else
+ x = bfd_getl32 (bufp);
+ break;
+ default :
+ abort ();
+ }
+
+ /* Written this way to avoid undefined behaviour. */
+ mask = (((1L << (length - 1)) - 1) << 1) | 1;
+ if (CGEN_INSN_LSB0_P)
+ shift = (start + 1) - length;
+ else
+ shift = (word_length - (start + length));
+ return (x >> shift) & mask;
+}
+
+#endif /* ! CGEN_INT_INSN_P */
+
+/* Default extraction routine.
+
+ INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
+ or sometimes less for cases like the m32r where the base insn size is 32
+ but some insns are 16 bits.
+ ATTRS is a mask of the boolean attributes. We only need `SIGNED',
+ but for generality we take a bitmask of all of them.
+ WORD_OFFSET is the offset in bits from the start of the insn of the value.
+ WORD_LENGTH is the length of the word in bits in which the value resides.
+ START is the starting bit number in the word, architecture origin.
+ LENGTH is the length of VALUE in bits.
+ TOTAL_LENGTH is the total length of the insn in bits.
+
+ Returns 1 for success, 0 for failure. */
+
+/* ??? The return code isn't properly used. wip. */
+
+/* ??? This doesn't handle bfd_vma's. Create another function when
+ necessary. */
+
+static int
+extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
+ word_length, total_length, pc, valuep)
+ CGEN_CPU_DESC cd;
+ CGEN_EXTRACT_INFO *ex_info;
+ CGEN_INSN_INT insn_value;
+ unsigned int attrs;
+ unsigned int word_offset, start, length, word_length, total_length;
+ bfd_vma pc;
+ long *valuep;
+{
+ CGEN_INSN_INT value;
+
+ /* If LENGTH is zero, this operand doesn't contribute to the value
+ so give it a standard value of zero. */
+ if (length == 0)
+ {
+ *valuep = 0;
+ return 1;
+ }
+
+ if (CGEN_INT_INSN_P
+ && word_offset != 0)
+ abort ();
+
+ if (word_length > 32)
+ abort ();
+
+ /* For architectures with insns smaller than the insn-base-bitsize,
+ word_length may be too big. */
+ if (cd->min_insn_bitsize < cd->base_insn_bitsize)
+ {
+ if (word_offset == 0
+ && word_length > total_length)
+ word_length = total_length;
+ }
+
+ /* Does the value reside in INSN_VALUE? */
+
+ if (word_offset == 0)
+ {
+ /* Written this way to avoid undefined behaviour. */
+ CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
+
+ if (CGEN_INSN_LSB0_P)
+ value = insn_value >> ((start + 1) - length);
+ else
+ value = insn_value >> (word_length - (start + length));
+ value &= mask;
+ /* sign extend? */
+ if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
+ && (value & (1L << (length - 1))))
+ value |= ~mask;
+ }
+
+#if ! CGEN_INT_INSN_P
+
+ else
+ {
+ unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
+
+ if (word_length > 32)
+ abort ();
+
+ if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
+ return 0;
+
+ value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
+ }
+
+#endif /* ! CGEN_INT_INSN_P */
+
+ *valuep = value;
+
+ return 1;
+}
+
+/* Default insn extractor.
+
+ INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
+ The extracted fields are stored in FIELDS.
+ EX_INFO is used to handle reading variable length insns.
+ Return the length of the insn in bits, or 0 if no match,
+ or -1 if an error occurs fetching data (memory_error_func will have
+ been called). */
+
+static int
+extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ CGEN_EXTRACT_INFO *ex_info;
+ CGEN_INSN_INT insn_value;
+ CGEN_FIELDS *fields;
+ bfd_vma pc;
+{
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ const unsigned char *syn;
+
+ CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
+
+ CGEN_INIT_EXTRACT (cd);
+
+ for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
+ {
+ int length;
+
+ if (CGEN_SYNTAX_CHAR_P (*syn))
+ continue;
+
+ length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
+ ex_info, insn_value, fields, pc);
+ if (length <= 0)
+ return length;
+ }
+
+ /* We recognized and successfully extracted this insn. */
+ return CGEN_INSN_BITSIZE (insn);
+}
+
+/* machine generated code added here */
+
+/* Main entry point for operand insertion.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `parse_insn_normal', but keeping it
+ separate makes clear the interface between `parse_insn_normal' and each of
+ the handlers. It's also needed by GAS to insert operands that couldn't be
+ resolved during parsing.
+*/
+
+const char *
+fr30_cgen_insert_operand (cd, opindex, fields, buffer, pc)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_FIELDS * fields;
+ CGEN_INSN_BYTES_PTR buffer;
+ bfd_vma pc;
+{
+ const char * errmsg;
+ unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
+
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_CRJ :
+ errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_R13 :
+ errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
+ break;
+ case FR30_OPERAND_R14 :
+ errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
+ break;
+ case FR30_OPERAND_R15 :
+ errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
+ break;
+ case FR30_OPERAND_RI :
+ errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_RIC :
+ errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_RJ :
+ errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_RJC :
+ errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_RS1 :
+ errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_RS2 :
+ errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_CC :
+ errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_CCC :
+ errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_DIR10 :
+ {
+ long value = fields->f_dir10;
+ value = ((unsigned int) (value) >> (2));
+ errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_DIR8 :
+ errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_DIR9 :
+ {
+ long value = fields->f_dir9;
+ value = ((unsigned int) (value) >> (1));
+ errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_DISP10 :
+ {
+ long value = fields->f_disp10;
+ value = ((int) (value) >> (2));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_DISP8 :
+ errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_DISP9 :
+ {
+ long value = fields->f_disp9;
+ value = ((int) (value) >> (1));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_I20 :
+ {
+{
+ FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
+ FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
+}
+ errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
+ if (errmsg)
+ break;
+ errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
+ if (errmsg)
+ break;
+ }
+ break;
+ case FR30_OPERAND_I32 :
+ errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
+ break;
+ case FR30_OPERAND_I8 :
+ errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_LABEL12 :
+ {
+ long value = fields->f_rel12;
+ value = ((int) (((value) - (((pc) + (2))))) >> (1));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_LABEL9 :
+ {
+ long value = fields->f_rel9;
+ value = ((int) (((value) - (((pc) + (2))))) >> (1));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_M4 :
+ {
+ long value = fields->f_m4;
+ value = ((value) & (15));
+ errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_PS :
+ errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_S10 :
+ {
+ long value = fields->f_s10;
+ value = ((int) (value) >> (2));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_U10 :
+ {
+ long value = fields->f_u10;
+ value = ((unsigned int) (value) >> (2));
+ errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
+ }
+ break;
+ case FR30_OPERAND_U4 :
+ errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_U4C :
+ errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_U8 :
+ errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
+ break;
+ case FR30_OPERAND_UDISP6 :
+ {
+ long value = fields->f_udisp6;
+ value = ((unsigned int) (value) >> (2));
+ errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
+ }
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
+ opindex);
+ abort ();
+ }
+
+ return errmsg;
+}
+
+/* Main entry point for operand extraction.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `print_insn_normal', but keeping it
+ separate makes clear the interface between `print_insn_normal' and each of
+ the handlers.
+*/
+
+int
+fr30_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_EXTRACT_INFO *ex_info;
+ CGEN_INSN_INT insn_value;
+ CGEN_FIELDS * fields;
+ bfd_vma pc;
+{
+ int length;
+ unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
+
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
+ break;
+ case FR30_OPERAND_CRJ :
+ length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
+ break;
+ case FR30_OPERAND_R13 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
+ break;
+ case FR30_OPERAND_R14 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
+ break;
+ case FR30_OPERAND_R15 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
+ break;
+ case FR30_OPERAND_RI :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
+ break;
+ case FR30_OPERAND_RIC :
+ length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
+ break;
+ case FR30_OPERAND_RJ :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
+ break;
+ case FR30_OPERAND_RJC :
+ length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
+ break;
+ case FR30_OPERAND_RS1 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
+ break;
+ case FR30_OPERAND_RS2 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
+ break;
+ case FR30_OPERAND_CC :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
+ break;
+ case FR30_OPERAND_CCC :
+ length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
+ break;
+ case FR30_OPERAND_DIR10 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
+ value = ((value) << (2));
+ fields->f_dir10 = value;
+ }
+ break;
+ case FR30_OPERAND_DIR8 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
+ break;
+ case FR30_OPERAND_DIR9 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
+ value = ((value) << (1));
+ fields->f_dir9 = value;
+ }
+ break;
+ case FR30_OPERAND_DISP10 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
+ value = ((value) << (2));
+ fields->f_disp10 = value;
+ }
+ break;
+ case FR30_OPERAND_DISP8 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
+ break;
+ case FR30_OPERAND_DISP9 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
+ value = ((value) << (1));
+ fields->f_disp9 = value;
+ }
+ break;
+ case FR30_OPERAND_I20 :
+ {
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
+ length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
+{
+ FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
+}
+ }
+ break;
+ case FR30_OPERAND_I32 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
+ break;
+ case FR30_OPERAND_I8 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
+ break;
+ case FR30_OPERAND_LABEL12 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
+ value = ((((value) << (1))) + (((pc) + (2))));
+ fields->f_rel12 = value;
+ }
+ break;
+ case FR30_OPERAND_LABEL9 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
+ value = ((((value) << (1))) + (((pc) + (2))));
+ fields->f_rel9 = value;
+ }
+ break;
+ case FR30_OPERAND_M4 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
+ value = ((value) | (((-1) << (4))));
+ fields->f_m4 = value;
+ }
+ break;
+ case FR30_OPERAND_PS :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
+ break;
+ case FR30_OPERAND_S10 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
+ value = ((value) << (2));
+ fields->f_s10 = value;
+ }
+ break;
+ case FR30_OPERAND_U10 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
+ value = ((value) << (2));
+ fields->f_u10 = value;
+ }
+ break;
+ case FR30_OPERAND_U4 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
+ break;
+ case FR30_OPERAND_U4C :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
+ break;
+ case FR30_OPERAND_U8 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
+ break;
+ case FR30_OPERAND_UDISP6 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
+ value = ((value) << (2));
+ fields->f_udisp6 = value;
+ }
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
+ opindex);
+ abort ();
+ }
+
+ return length;
+}
+
+cgen_insert_fn * const fr30_cgen_insert_handlers[] =
+{
+ insert_insn_normal,
+};
+
+cgen_extract_fn * const fr30_cgen_extract_handlers[] =
+{
+ extract_insn_normal,
+};
+
+/* Getting values from cgen_fields is handled by a collection of functions.
+ They are distinguished by the type of the VALUE argument they return.
+ TODO: floating point, inlining support, remove cases where result type
+ not appropriate. */
+
+int
+fr30_cgen_get_int_operand (cd, opindex, fields)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ const CGEN_FIELDS * fields;
+{
+ int value;
+
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ value = fields->f_CRi;
+ break;
+ case FR30_OPERAND_CRJ :
+ value = fields->f_CRj;
+ break;
+ case FR30_OPERAND_R13 :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_R14 :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_R15 :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_RI :
+ value = fields->f_Ri;
+ break;
+ case FR30_OPERAND_RIC :
+ value = fields->f_Ric;
+ break;
+ case FR30_OPERAND_RJ :
+ value = fields->f_Rj;
+ break;
+ case FR30_OPERAND_RJC :
+ value = fields->f_Rjc;
+ break;
+ case FR30_OPERAND_RS1 :
+ value = fields->f_Rs1;
+ break;
+ case FR30_OPERAND_RS2 :
+ value = fields->f_Rs2;
+ break;
+ case FR30_OPERAND_CC :
+ value = fields->f_cc;
+ break;
+ case FR30_OPERAND_CCC :
+ value = fields->f_ccc;
+ break;
+ case FR30_OPERAND_DIR10 :
+ value = fields->f_dir10;
+ break;
+ case FR30_OPERAND_DIR8 :
+ value = fields->f_dir8;
+ break;
+ case FR30_OPERAND_DIR9 :
+ value = fields->f_dir9;
+ break;
+ case FR30_OPERAND_DISP10 :
+ value = fields->f_disp10;
+ break;
+ case FR30_OPERAND_DISP8 :
+ value = fields->f_disp8;
+ break;
+ case FR30_OPERAND_DISP9 :
+ value = fields->f_disp9;
+ break;
+ case FR30_OPERAND_I20 :
+ value = fields->f_i20;
+ break;
+ case FR30_OPERAND_I32 :
+ value = fields->f_i32;
+ break;
+ case FR30_OPERAND_I8 :
+ value = fields->f_i8;
+ break;
+ case FR30_OPERAND_LABEL12 :
+ value = fields->f_rel12;
+ break;
+ case FR30_OPERAND_LABEL9 :
+ value = fields->f_rel9;
+ break;
+ case FR30_OPERAND_M4 :
+ value = fields->f_m4;
+ break;
+ case FR30_OPERAND_PS :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ value = fields->f_reglist_hi_ld;
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ value = fields->f_reglist_hi_st;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ value = fields->f_reglist_low_ld;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ value = fields->f_reglist_low_st;
+ break;
+ case FR30_OPERAND_S10 :
+ value = fields->f_s10;
+ break;
+ case FR30_OPERAND_U10 :
+ value = fields->f_u10;
+ break;
+ case FR30_OPERAND_U4 :
+ value = fields->f_u4;
+ break;
+ case FR30_OPERAND_U4C :
+ value = fields->f_u4c;
+ break;
+ case FR30_OPERAND_U8 :
+ value = fields->f_u8;
+ break;
+ case FR30_OPERAND_UDISP6 :
+ value = fields->f_udisp6;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
+ opindex);
+ abort ();
+ }
+
+ return value;
+}
+
+bfd_vma
+fr30_cgen_get_vma_operand (cd, opindex, fields)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ const CGEN_FIELDS * fields;
+{
+ bfd_vma value;
+
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ value = fields->f_CRi;
+ break;
+ case FR30_OPERAND_CRJ :
+ value = fields->f_CRj;
+ break;
+ case FR30_OPERAND_R13 :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_R14 :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_R15 :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_RI :
+ value = fields->f_Ri;
+ break;
+ case FR30_OPERAND_RIC :
+ value = fields->f_Ric;
+ break;
+ case FR30_OPERAND_RJ :
+ value = fields->f_Rj;
+ break;
+ case FR30_OPERAND_RJC :
+ value = fields->f_Rjc;
+ break;
+ case FR30_OPERAND_RS1 :
+ value = fields->f_Rs1;
+ break;
+ case FR30_OPERAND_RS2 :
+ value = fields->f_Rs2;
+ break;
+ case FR30_OPERAND_CC :
+ value = fields->f_cc;
+ break;
+ case FR30_OPERAND_CCC :
+ value = fields->f_ccc;
+ break;
+ case FR30_OPERAND_DIR10 :
+ value = fields->f_dir10;
+ break;
+ case FR30_OPERAND_DIR8 :
+ value = fields->f_dir8;
+ break;
+ case FR30_OPERAND_DIR9 :
+ value = fields->f_dir9;
+ break;
+ case FR30_OPERAND_DISP10 :
+ value = fields->f_disp10;
+ break;
+ case FR30_OPERAND_DISP8 :
+ value = fields->f_disp8;
+ break;
+ case FR30_OPERAND_DISP9 :
+ value = fields->f_disp9;
+ break;
+ case FR30_OPERAND_I20 :
+ value = fields->f_i20;
+ break;
+ case FR30_OPERAND_I32 :
+ value = fields->f_i32;
+ break;
+ case FR30_OPERAND_I8 :
+ value = fields->f_i8;
+ break;
+ case FR30_OPERAND_LABEL12 :
+ value = fields->f_rel12;
+ break;
+ case FR30_OPERAND_LABEL9 :
+ value = fields->f_rel9;
+ break;
+ case FR30_OPERAND_M4 :
+ value = fields->f_m4;
+ break;
+ case FR30_OPERAND_PS :
+ value = fields->f_nil;
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ value = fields->f_reglist_hi_ld;
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ value = fields->f_reglist_hi_st;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ value = fields->f_reglist_low_ld;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ value = fields->f_reglist_low_st;
+ break;
+ case FR30_OPERAND_S10 :
+ value = fields->f_s10;
+ break;
+ case FR30_OPERAND_U10 :
+ value = fields->f_u10;
+ break;
+ case FR30_OPERAND_U4 :
+ value = fields->f_u4;
+ break;
+ case FR30_OPERAND_U4C :
+ value = fields->f_u4c;
+ break;
+ case FR30_OPERAND_U8 :
+ value = fields->f_u8;
+ break;
+ case FR30_OPERAND_UDISP6 :
+ value = fields->f_udisp6;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
+ opindex);
+ abort ();
+ }
+
+ return value;
+}
+
+/* Stuffing values in cgen_fields is handled by a collection of functions.
+ They are distinguished by the type of the VALUE argument they accept.
+ TODO: floating point, inlining support, remove cases where argument type
+ not appropriate. */
+
+void
+fr30_cgen_set_int_operand (cd, opindex, fields, value)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_FIELDS * fields;
+ int value;
+{
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ fields->f_CRi = value;
+ break;
+ case FR30_OPERAND_CRJ :
+ fields->f_CRj = value;
+ break;
+ case FR30_OPERAND_R13 :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_R14 :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_R15 :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_RI :
+ fields->f_Ri = value;
+ break;
+ case FR30_OPERAND_RIC :
+ fields->f_Ric = value;
+ break;
+ case FR30_OPERAND_RJ :
+ fields->f_Rj = value;
+ break;
+ case FR30_OPERAND_RJC :
+ fields->f_Rjc = value;
+ break;
+ case FR30_OPERAND_RS1 :
+ fields->f_Rs1 = value;
+ break;
+ case FR30_OPERAND_RS2 :
+ fields->f_Rs2 = value;
+ break;
+ case FR30_OPERAND_CC :
+ fields->f_cc = value;
+ break;
+ case FR30_OPERAND_CCC :
+ fields->f_ccc = value;
+ break;
+ case FR30_OPERAND_DIR10 :
+ fields->f_dir10 = value;
+ break;
+ case FR30_OPERAND_DIR8 :
+ fields->f_dir8 = value;
+ break;
+ case FR30_OPERAND_DIR9 :
+ fields->f_dir9 = value;
+ break;
+ case FR30_OPERAND_DISP10 :
+ fields->f_disp10 = value;
+ break;
+ case FR30_OPERAND_DISP8 :
+ fields->f_disp8 = value;
+ break;
+ case FR30_OPERAND_DISP9 :
+ fields->f_disp9 = value;
+ break;
+ case FR30_OPERAND_I20 :
+ fields->f_i20 = value;
+ break;
+ case FR30_OPERAND_I32 :
+ fields->f_i32 = value;
+ break;
+ case FR30_OPERAND_I8 :
+ fields->f_i8 = value;
+ break;
+ case FR30_OPERAND_LABEL12 :
+ fields->f_rel12 = value;
+ break;
+ case FR30_OPERAND_LABEL9 :
+ fields->f_rel9 = value;
+ break;
+ case FR30_OPERAND_M4 :
+ fields->f_m4 = value;
+ break;
+ case FR30_OPERAND_PS :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ fields->f_reglist_hi_ld = value;
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ fields->f_reglist_hi_st = value;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ fields->f_reglist_low_ld = value;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ fields->f_reglist_low_st = value;
+ break;
+ case FR30_OPERAND_S10 :
+ fields->f_s10 = value;
+ break;
+ case FR30_OPERAND_U10 :
+ fields->f_u10 = value;
+ break;
+ case FR30_OPERAND_U4 :
+ fields->f_u4 = value;
+ break;
+ case FR30_OPERAND_U4C :
+ fields->f_u4c = value;
+ break;
+ case FR30_OPERAND_U8 :
+ fields->f_u8 = value;
+ break;
+ case FR30_OPERAND_UDISP6 :
+ fields->f_udisp6 = value;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
+ opindex);
+ abort ();
+ }
+}
+
+void
+fr30_cgen_set_vma_operand (cd, opindex, fields, value)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_FIELDS * fields;
+ bfd_vma value;
+{
+ switch (opindex)
+ {
+ case FR30_OPERAND_CRI :
+ fields->f_CRi = value;
+ break;
+ case FR30_OPERAND_CRJ :
+ fields->f_CRj = value;
+ break;
+ case FR30_OPERAND_R13 :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_R14 :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_R15 :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_RI :
+ fields->f_Ri = value;
+ break;
+ case FR30_OPERAND_RIC :
+ fields->f_Ric = value;
+ break;
+ case FR30_OPERAND_RJ :
+ fields->f_Rj = value;
+ break;
+ case FR30_OPERAND_RJC :
+ fields->f_Rjc = value;
+ break;
+ case FR30_OPERAND_RS1 :
+ fields->f_Rs1 = value;
+ break;
+ case FR30_OPERAND_RS2 :
+ fields->f_Rs2 = value;
+ break;
+ case FR30_OPERAND_CC :
+ fields->f_cc = value;
+ break;
+ case FR30_OPERAND_CCC :
+ fields->f_ccc = value;
+ break;
+ case FR30_OPERAND_DIR10 :
+ fields->f_dir10 = value;
+ break;
+ case FR30_OPERAND_DIR8 :
+ fields->f_dir8 = value;
+ break;
+ case FR30_OPERAND_DIR9 :
+ fields->f_dir9 = value;
+ break;
+ case FR30_OPERAND_DISP10 :
+ fields->f_disp10 = value;
+ break;
+ case FR30_OPERAND_DISP8 :
+ fields->f_disp8 = value;
+ break;
+ case FR30_OPERAND_DISP9 :
+ fields->f_disp9 = value;
+ break;
+ case FR30_OPERAND_I20 :
+ fields->f_i20 = value;
+ break;
+ case FR30_OPERAND_I32 :
+ fields->f_i32 = value;
+ break;
+ case FR30_OPERAND_I8 :
+ fields->f_i8 = value;
+ break;
+ case FR30_OPERAND_LABEL12 :
+ fields->f_rel12 = value;
+ break;
+ case FR30_OPERAND_LABEL9 :
+ fields->f_rel9 = value;
+ break;
+ case FR30_OPERAND_M4 :
+ fields->f_m4 = value;
+ break;
+ case FR30_OPERAND_PS :
+ fields->f_nil = value;
+ break;
+ case FR30_OPERAND_REGLIST_HI_LD :
+ fields->f_reglist_hi_ld = value;
+ break;
+ case FR30_OPERAND_REGLIST_HI_ST :
+ fields->f_reglist_hi_st = value;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_LD :
+ fields->f_reglist_low_ld = value;
+ break;
+ case FR30_OPERAND_REGLIST_LOW_ST :
+ fields->f_reglist_low_st = value;
+ break;
+ case FR30_OPERAND_S10 :
+ fields->f_s10 = value;
+ break;
+ case FR30_OPERAND_U10 :
+ fields->f_u10 = value;
+ break;
+ case FR30_OPERAND_U4 :
+ fields->f_u4 = value;
+ break;
+ case FR30_OPERAND_U4C :
+ fields->f_u4c = value;
+ break;
+ case FR30_OPERAND_U8 :
+ fields->f_u8 = value;
+ break;
+ case FR30_OPERAND_UDISP6 :
+ fields->f_udisp6 = value;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
+ opindex);
+ abort ();
+ }
+}
+
+/* Function to call before using the instruction builder tables. */
+
+void
+fr30_cgen_init_ibld_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ cd->insert_handlers = & fr30_cgen_insert_handlers[0];
+ cd->extract_handlers = & fr30_cgen_extract_handlers[0];
+
+ cd->insert_operand = fr30_cgen_insert_operand;
+ cd->extract_operand = fr30_cgen_extract_operand;
+
+ cd->get_int_operand = fr30_cgen_get_int_operand;
+ cd->set_int_operand = fr30_cgen_set_int_operand;
+ cd->get_vma_operand = fr30_cgen_get_vma_operand;
+ cd->set_vma_operand = fr30_cgen_set_vma_operand;
+}
diff --git a/opcodes/fr30-opc.c b/opcodes/fr30-opc.c
new file mode 100644
index 00000000000..302100dfc64
--- /dev/null
+++ b/opcodes/fr30-opc.c
@@ -0,0 +1,1368 @@
+/* Instruction opcode table for fr30.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "sysdep.h"
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "fr30-desc.h"
+#include "fr30-opc.h"
+
+/* The hash functions are recorded here to help keep assembler code out of
+ the disassembler and vice versa. */
+
+static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
+static unsigned int asm_hash_insn PARAMS ((const char *));
+static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
+static unsigned int dis_hash_insn PARAMS ((const char *, CGEN_INSN_INT));
+
+/* Instruction formats. */
+
+#define F(f) & fr30_cgen_ifld_table[CONCAT2 (FR30_,f)]
+
+static const CGEN_IFMT ifmt_empty = {
+ 0, 0, 0x0, { 0 }
+};
+
+static const CGEN_IFMT ifmt_add = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_RJ), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_addi = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_U4), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_add2 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_M4), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_div0s = {
+ 16, 16, 0xfff0, { F (F_OP1), F (F_OP2), F (F_OP3), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_div3 = {
+ 16, 16, 0xffff, { F (F_OP1), F (F_OP2), F (F_OP3), F (F_OP4), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi8 = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_I8), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi20 = {
+ 16, 32, 0xff00, { F (F_OP1), F (F_I20), F (F_OP2), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi32 = {
+ 16, 48, 0xfff0, { F (F_OP1), F (F_I32), F (F_OP2), F (F_OP3), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldr14 = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_DISP10), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldr14uh = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_DISP9), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldr14ub = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_DISP8), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldr15 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_UDISP6), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldr15dr = {
+ 16, 16, 0xfff0, { F (F_OP1), F (F_OP2), F (F_OP3), F (F_RS2), 0 }
+};
+
+static const CGEN_IFMT ifmt_movdr = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_RS1), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_call = {
+ 16, 16, 0xf800, { F (F_OP1), F (F_OP5), F (F_REL12), 0 }
+};
+
+static const CGEN_IFMT ifmt_int = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_U8), 0 }
+};
+
+static const CGEN_IFMT ifmt_brad = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_CC), F (F_REL9), 0 }
+};
+
+static const CGEN_IFMT ifmt_dmovr13 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_DIR10), 0 }
+};
+
+static const CGEN_IFMT ifmt_dmovr13h = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_DIR9), 0 }
+};
+
+static const CGEN_IFMT ifmt_dmovr13b = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_DIR8), 0 }
+};
+
+static const CGEN_IFMT ifmt_copop = {
+ 16, 32, 0xfff0, { F (F_OP1), F (F_CCC), F (F_OP2), F (F_OP3), F (F_CRJ), F (F_U4C), F (F_CRI), 0 }
+};
+
+static const CGEN_IFMT ifmt_copld = {
+ 16, 32, 0xfff0, { F (F_OP1), F (F_CCC), F (F_OP2), F (F_OP3), F (F_RJC), F (F_U4C), F (F_CRI), 0 }
+};
+
+static const CGEN_IFMT ifmt_copst = {
+ 16, 32, 0xfff0, { F (F_OP1), F (F_CCC), F (F_OP2), F (F_OP3), F (F_CRJ), F (F_U4C), F (F_RIC), 0 }
+};
+
+static const CGEN_IFMT ifmt_addsp = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_S10), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldm0 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_REGLIST_LOW_LD), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldm1 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_REGLIST_HI_LD), 0 }
+};
+
+static const CGEN_IFMT ifmt_stm0 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_REGLIST_LOW_ST), 0 }
+};
+
+static const CGEN_IFMT ifmt_stm1 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_REGLIST_HI_ST), 0 }
+};
+
+static const CGEN_IFMT ifmt_enter = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_OP2), F (F_U10), 0 }
+};
+
+#undef F
+
+#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
+#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
+#define OPERAND(op) CONCAT2 (FR30_OPERAND_,op)
+#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
+
+/* The instruction table. */
+
+static const CGEN_OPCODE fr30_cgen_insn_opcode_table[MAX_INSNS] =
+{
+ /* Special null first entry.
+ A `num' value of zero is thus invalid.
+ Also, the special `invalid' insn resides here. */
+ { { 0 } },
+/* add $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xa600 }
+ },
+/* add $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xa400 }
+ },
+/* add2 $m4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (M4), ',', OP (RI), 0 } },
+ & ifmt_add2, { 0xa500 }
+ },
+/* addc $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xa700 }
+ },
+/* addn $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xa200 }
+ },
+/* addn $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xa000 }
+ },
+/* addn2 $m4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (M4), ',', OP (RI), 0 } },
+ & ifmt_add2, { 0xa100 }
+ },
+/* sub $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xac00 }
+ },
+/* subc $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xad00 }
+ },
+/* subn $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xae00 }
+ },
+/* cmp $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xaa00 }
+ },
+/* cmp $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xa800 }
+ },
+/* cmp2 $m4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (M4), ',', OP (RI), 0 } },
+ & ifmt_add2, { 0xa900 }
+ },
+/* and $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x8200 }
+ },
+/* or $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x9200 }
+ },
+/* eor $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x9a00 }
+ },
+/* and $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x8400 }
+ },
+/* andh $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x8500 }
+ },
+/* andb $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x8600 }
+ },
+/* or $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x9400 }
+ },
+/* orh $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x9500 }
+ },
+/* orb $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x9600 }
+ },
+/* eor $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x9c00 }
+ },
+/* eorh $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x9d00 }
+ },
+/* eorb $Rj,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', '@', OP (RI), 0 } },
+ & ifmt_add, { 0x9e00 }
+ },
+/* bandl $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x8000 }
+ },
+/* borl $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x9000 }
+ },
+/* beorl $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x9800 }
+ },
+/* bandh $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x8100 }
+ },
+/* borh $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x9100 }
+ },
+/* beorh $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x9900 }
+ },
+/* btstl $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x8800 }
+ },
+/* btsth $u4,@$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), 0 } },
+ & ifmt_addi, { 0x8900 }
+ },
+/* mul $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xaf00 }
+ },
+/* mulu $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xab00 }
+ },
+/* mulh $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xbf00 }
+ },
+/* muluh $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xbb00 }
+ },
+/* div0s $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9740 }
+ },
+/* div0u $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9750 }
+ },
+/* div1 $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9760 }
+ },
+/* div2 $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9770 }
+ },
+/* div3 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9f60 }
+ },
+/* div4s */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9f70 }
+ },
+/* lsl $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xb600 }
+ },
+/* lsl $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xb400 }
+ },
+/* lsl2 $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xb500 }
+ },
+/* lsr $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xb200 }
+ },
+/* lsr $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xb000 }
+ },
+/* lsr2 $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xb100 }
+ },
+/* asr $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0xba00 }
+ },
+/* asr $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xb800 }
+ },
+/* asr2 $u4,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', OP (RI), 0 } },
+ & ifmt_addi, { 0xb900 }
+ },
+/* ldi:8 $i8,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (I8), ',', OP (RI), 0 } },
+ & ifmt_ldi8, { 0xc000 }
+ },
+/* ldi:20 $i20,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (I20), ',', OP (RI), 0 } },
+ & ifmt_ldi20, { 0x9b00 }
+ },
+/* ldi:32 $i32,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (I32), ',', OP (RI), 0 } },
+ & ifmt_ldi32, { 0x9f80 }
+ },
+/* ld @$Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x400 }
+ },
+/* lduh @$Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x500 }
+ },
+/* ldub @$Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x600 }
+ },
+/* ld @($R13,$Rj),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R13), ',', OP (RJ), ')', ',', OP (RI), 0 } },
+ & ifmt_add, { 0x0 }
+ },
+/* lduh @($R13,$Rj),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R13), ',', OP (RJ), ')', ',', OP (RI), 0 } },
+ & ifmt_add, { 0x100 }
+ },
+/* ldub @($R13,$Rj),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R13), ',', OP (RJ), ')', ',', OP (RI), 0 } },
+ & ifmt_add, { 0x200 }
+ },
+/* ld @($R14,$disp10),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R14), ',', OP (DISP10), ')', ',', OP (RI), 0 } },
+ & ifmt_ldr14, { 0x2000 }
+ },
+/* lduh @($R14,$disp9),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R14), ',', OP (DISP9), ')', ',', OP (RI), 0 } },
+ & ifmt_ldr14uh, { 0x4000 }
+ },
+/* ldub @($R14,$disp8),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R14), ',', OP (DISP8), ')', ',', OP (RI), 0 } },
+ & ifmt_ldr14ub, { 0x6000 }
+ },
+/* ld @($R15,$udisp6),$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', '(', OP (R15), ',', OP (UDISP6), ')', ',', OP (RI), 0 } },
+ & ifmt_ldr15, { 0x300 }
+ },
+/* ld @$R15+,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R15), '+', ',', OP (RI), 0 } },
+ & ifmt_div0s, { 0x700 }
+ },
+/* ld @$R15+,$Rs2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R15), '+', ',', OP (RS2), 0 } },
+ & ifmt_ldr15dr, { 0x780 }
+ },
+/* ld @$R15+,$ps */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R15), '+', ',', OP (PS), 0 } },
+ & ifmt_div3, { 0x790 }
+ },
+/* st $Ri,@$Rj */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', OP (RJ), 0 } },
+ & ifmt_add, { 0x1400 }
+ },
+/* sth $Ri,@$Rj */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', OP (RJ), 0 } },
+ & ifmt_add, { 0x1500 }
+ },
+/* stb $Ri,@$Rj */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', OP (RJ), 0 } },
+ & ifmt_add, { 0x1600 }
+ },
+/* st $Ri,@($R13,$Rj) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R13), ',', OP (RJ), ')', 0 } },
+ & ifmt_add, { 0x1000 }
+ },
+/* sth $Ri,@($R13,$Rj) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R13), ',', OP (RJ), ')', 0 } },
+ & ifmt_add, { 0x1100 }
+ },
+/* stb $Ri,@($R13,$Rj) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R13), ',', OP (RJ), ')', 0 } },
+ & ifmt_add, { 0x1200 }
+ },
+/* st $Ri,@($R14,$disp10) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R14), ',', OP (DISP10), ')', 0 } },
+ & ifmt_ldr14, { 0x3000 }
+ },
+/* sth $Ri,@($R14,$disp9) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R14), ',', OP (DISP9), ')', 0 } },
+ & ifmt_ldr14uh, { 0x5000 }
+ },
+/* stb $Ri,@($R14,$disp8) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R14), ',', OP (DISP8), ')', 0 } },
+ & ifmt_ldr14ub, { 0x7000 }
+ },
+/* st $Ri,@($R15,$udisp6) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '(', OP (R15), ',', OP (UDISP6), ')', 0 } },
+ & ifmt_ldr15, { 0x1300 }
+ },
+/* st $Ri,@-$R15 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', '@', '-', OP (R15), 0 } },
+ & ifmt_div0s, { 0x1700 }
+ },
+/* st $Rs2,@-$R15 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RS2), ',', '@', '-', OP (R15), 0 } },
+ & ifmt_ldr15dr, { 0x1780 }
+ },
+/* st $ps,@-$R15 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (PS), ',', '@', '-', OP (R15), 0 } },
+ & ifmt_div3, { 0x1790 }
+ },
+/* mov $Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x8b00 }
+ },
+/* mov $Rs1,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RS1), ',', OP (RI), 0 } },
+ & ifmt_movdr, { 0xb700 }
+ },
+/* mov $ps,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (PS), ',', OP (RI), 0 } },
+ & ifmt_div0s, { 0x1710 }
+ },
+/* mov $Ri,$Rs1 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', OP (RS1), 0 } },
+ & ifmt_movdr, { 0xb300 }
+ },
+/* mov $Ri,$ps */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), ',', OP (PS), 0 } },
+ & ifmt_div0s, { 0x710 }
+ },
+/* jmp @$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9700 }
+ },
+/* jmp:d @$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9f00 }
+ },
+/* call @$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9710 }
+ },
+/* call:d @$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9f10 }
+ },
+/* call $label12 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL12), 0 } },
+ & ifmt_call, { 0xd000 }
+ },
+/* call:d $label12 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL12), 0 } },
+ & ifmt_call, { 0xd800 }
+ },
+/* ret */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9720 }
+ },
+/* ret:d */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9f20 }
+ },
+/* int $u8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U8), 0 } },
+ & ifmt_int, { 0x1f00 }
+ },
+/* inte */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9f30 }
+ },
+/* reti */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9730 }
+ },
+/* bra:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf000 }
+ },
+/* bra $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe000 }
+ },
+/* bno:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf100 }
+ },
+/* bno $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe100 }
+ },
+/* beq:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf200 }
+ },
+/* beq $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe200 }
+ },
+/* bne:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf300 }
+ },
+/* bne $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe300 }
+ },
+/* bc:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf400 }
+ },
+/* bc $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe400 }
+ },
+/* bnc:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf500 }
+ },
+/* bnc $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe500 }
+ },
+/* bn:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf600 }
+ },
+/* bn $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe600 }
+ },
+/* bp:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf700 }
+ },
+/* bp $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe700 }
+ },
+/* bv:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf800 }
+ },
+/* bv $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe800 }
+ },
+/* bnv:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xf900 }
+ },
+/* bnv $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xe900 }
+ },
+/* blt:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xfa00 }
+ },
+/* blt $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xea00 }
+ },
+/* bge:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xfb00 }
+ },
+/* bge $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xeb00 }
+ },
+/* ble:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xfc00 }
+ },
+/* ble $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xec00 }
+ },
+/* bgt:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xfd00 }
+ },
+/* bgt $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xed00 }
+ },
+/* bls:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xfe00 }
+ },
+/* bls $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xee00 }
+ },
+/* bhi:d $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xff00 }
+ },
+/* bhi $label9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (LABEL9), 0 } },
+ & ifmt_brad, { 0xef00 }
+ },
+/* dmov $R13,@$dir10 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (R13), ',', '@', OP (DIR10), 0 } },
+ & ifmt_dmovr13, { 0x1800 }
+ },
+/* dmovh $R13,@$dir9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (R13), ',', '@', OP (DIR9), 0 } },
+ & ifmt_dmovr13h, { 0x1900 }
+ },
+/* dmovb $R13,@$dir8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (R13), ',', '@', OP (DIR8), 0 } },
+ & ifmt_dmovr13b, { 0x1a00 }
+ },
+/* dmov @$R13+,@$dir10 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R13), '+', ',', '@', OP (DIR10), 0 } },
+ & ifmt_dmovr13, { 0x1c00 }
+ },
+/* dmovh @$R13+,@$dir9 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R13), '+', ',', '@', OP (DIR9), 0 } },
+ & ifmt_dmovr13h, { 0x1d00 }
+ },
+/* dmovb @$R13+,@$dir8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R13), '+', ',', '@', OP (DIR8), 0 } },
+ & ifmt_dmovr13b, { 0x1e00 }
+ },
+/* dmov @$R15+,@$dir10 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (R15), '+', ',', '@', OP (DIR10), 0 } },
+ & ifmt_dmovr13, { 0x1b00 }
+ },
+/* dmov @$dir10,$R13 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR10), ',', OP (R13), 0 } },
+ & ifmt_dmovr13, { 0x800 }
+ },
+/* dmovh @$dir9,$R13 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR9), ',', OP (R13), 0 } },
+ & ifmt_dmovr13h, { 0x900 }
+ },
+/* dmovb @$dir8,$R13 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR8), ',', OP (R13), 0 } },
+ & ifmt_dmovr13b, { 0xa00 }
+ },
+/* dmov @$dir10,@$R13+ */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR10), ',', '@', OP (R13), '+', 0 } },
+ & ifmt_dmovr13, { 0xc00 }
+ },
+/* dmovh @$dir9,@$R13+ */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR9), ',', '@', OP (R13), '+', 0 } },
+ & ifmt_dmovr13h, { 0xd00 }
+ },
+/* dmovb @$dir8,@$R13+ */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR8), ',', '@', OP (R13), '+', 0 } },
+ & ifmt_dmovr13b, { 0xe00 }
+ },
+/* dmov @$dir10,@-$R15 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (DIR10), ',', '@', '-', OP (R15), 0 } },
+ & ifmt_dmovr13, { 0xb00 }
+ },
+/* ldres @$Ri+,$u4 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RI), '+', ',', OP (U4), 0 } },
+ & ifmt_addi, { 0xbc00 }
+ },
+/* stres $u4,@$Ri+ */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4), ',', '@', OP (RI), '+', 0 } },
+ & ifmt_addi, { 0xbd00 }
+ },
+/* copop $u4c,$ccc,$CRj,$CRi */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4C), ',', OP (CCC), ',', OP (CRJ), ',', OP (CRI), 0 } },
+ & ifmt_copop, { 0x9fc0 }
+ },
+/* copld $u4c,$ccc,$Rjc,$CRi */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4C), ',', OP (CCC), ',', OP (RJC), ',', OP (CRI), 0 } },
+ & ifmt_copld, { 0x9fd0 }
+ },
+/* copst $u4c,$ccc,$CRj,$Ric */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4C), ',', OP (CCC), ',', OP (CRJ), ',', OP (RIC), 0 } },
+ & ifmt_copst, { 0x9fe0 }
+ },
+/* copsv $u4c,$ccc,$CRj,$Ric */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U4C), ',', OP (CCC), ',', OP (CRJ), ',', OP (RIC), 0 } },
+ & ifmt_copst, { 0x9ff0 }
+ },
+/* nop */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9fa0 }
+ },
+/* andccr $u8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U8), 0 } },
+ & ifmt_int, { 0x8300 }
+ },
+/* orccr $u8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U8), 0 } },
+ & ifmt_int, { 0x9300 }
+ },
+/* stilm $u8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U8), 0 } },
+ & ifmt_int, { 0x8700 }
+ },
+/* addsp $s10 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (S10), 0 } },
+ & ifmt_addsp, { 0xa300 }
+ },
+/* extsb $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9780 }
+ },
+/* extub $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x9790 }
+ },
+/* extsh $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x97a0 }
+ },
+/* extuh $Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (RI), 0 } },
+ & ifmt_div0s, { 0x97b0 }
+ },
+/* ldm0 ($reglist_low_ld) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '(', OP (REGLIST_LOW_LD), ')', 0 } },
+ & ifmt_ldm0, { 0x8c00 }
+ },
+/* ldm1 ($reglist_hi_ld) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '(', OP (REGLIST_HI_LD), ')', 0 } },
+ & ifmt_ldm1, { 0x8d00 }
+ },
+/* stm0 ($reglist_low_st) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '(', OP (REGLIST_LOW_ST), ')', 0 } },
+ & ifmt_stm0, { 0x8e00 }
+ },
+/* stm1 ($reglist_hi_st) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '(', OP (REGLIST_HI_ST), ')', 0 } },
+ & ifmt_stm1, { 0x8f00 }
+ },
+/* enter $u10 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (U10), 0 } },
+ & ifmt_enter, { 0xf00 }
+ },
+/* leave */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_div3, { 0x9f90 }
+ },
+/* xchb @$Rj,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', '@', OP (RJ), ',', OP (RI), 0 } },
+ & ifmt_add, { 0x8a00 }
+ },
+};
+
+#undef A
+#undef MNEM
+#undef OPERAND
+#undef OP
+
+/* Formats for ALIAS macro-insns. */
+
+#define F(f) & fr30_cgen_ifld_table[CONCAT2 (FR30_,f)]
+
+static const CGEN_IFMT ifmt_ldi8m = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_I8), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi20m = {
+ 16, 32, 0xff00, { F (F_OP1), F (F_I20), F (F_OP2), F (F_RI), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi32m = {
+ 16, 48, 0xfff0, { F (F_OP1), F (F_I32), F (F_OP2), F (F_OP3), F (F_RI), 0 }
+};
+
+#undef F
+
+/* Each non-simple macro entry points to an array of expansion possibilities. */
+
+#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
+#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
+#define OPERAND(op) CONCAT2 (FR30_OPERAND_,op)
+#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
+
+/* The macro instruction table. */
+
+static const CGEN_IBASE fr30_cgen_macro_insn_table[] =
+{
+/* ldi8 $i8,$Ri */
+ {
+ -1, "ldi8m", "ldi8", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldi20 $i20,$Ri */
+ {
+ -1, "ldi20m", "ldi20", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldi32 $i32,$Ri */
+ {
+ -1, "ldi32m", "ldi32", 48,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+};
+
+/* The macro instruction opcode table. */
+
+static const CGEN_OPCODE fr30_cgen_macro_insn_opcode_table[] =
+{
+/* ldi8 $i8,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (I8), ',', OP (RI), 0 } },
+ & ifmt_ldi8m, { 0xc000 }
+ },
+/* ldi20 $i20,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (I20), ',', OP (RI), 0 } },
+ & ifmt_ldi20m, { 0x9b00 }
+ },
+/* ldi32 $i32,$Ri */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (I32), ',', OP (RI), 0 } },
+ & ifmt_ldi32m, { 0x9f80 }
+ },
+};
+
+#undef A
+#undef MNEM
+#undef OPERAND
+#undef OP
+
+#ifndef CGEN_ASM_HASH_P
+#define CGEN_ASM_HASH_P(insn) 1
+#endif
+
+#ifndef CGEN_DIS_HASH_P
+#define CGEN_DIS_HASH_P(insn) 1
+#endif
+
+/* Return non-zero if INSN is to be added to the hash table.
+ Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */
+
+static int
+asm_hash_insn_p (insn)
+ const CGEN_INSN *insn;
+{
+ return CGEN_ASM_HASH_P (insn);
+}
+
+static int
+dis_hash_insn_p (insn)
+ const CGEN_INSN *insn;
+{
+ /* If building the hash table and the NO-DIS attribute is present,
+ ignore. */
+ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS))
+ return 0;
+ return CGEN_DIS_HASH_P (insn);
+}
+
+#ifndef CGEN_ASM_HASH
+#define CGEN_ASM_HASH_SIZE 127
+#ifdef CGEN_MNEMONIC_OPERANDS
+#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE)
+#else
+#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/
+#endif
+#endif
+
+/* It doesn't make much sense to provide a default here,
+ but while this is under development we do.
+ BUFFER is a pointer to the bytes of the insn, target order.
+ VALUE is the first base_insn_bitsize bits as an int in host order. */
+
+#ifndef CGEN_DIS_HASH
+#define CGEN_DIS_HASH_SIZE 256
+#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf))
+#endif
+
+/* The result is the hash value of the insn.
+ Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */
+
+static unsigned int
+asm_hash_insn (mnem)
+ const char * mnem;
+{
+ return CGEN_ASM_HASH (mnem);
+}
+
+/* BUF is a pointer to the bytes of the insn, target order.
+ VALUE is the first base_insn_bitsize bits as an int in host order. */
+
+static unsigned int
+dis_hash_insn (buf, value)
+ const char * buf;
+ CGEN_INSN_INT value;
+{
+ return CGEN_DIS_HASH (buf, value);
+}
+
+/* Set the recorded length of the insn in the CGEN_FIELDS struct. */
+
+static void
+set_fields_bitsize (fields, size)
+ CGEN_FIELDS *fields;
+ int size;
+{
+ CGEN_FIELDS_BITSIZE (fields) = size;
+}
+
+/* Function to call before using the operand instance table.
+ This plugs the opcode entries and macro instructions into the cpu table. */
+
+void
+fr30_cgen_init_opcode_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ int i;
+ int num_macros = (sizeof (fr30_cgen_macro_insn_table) /
+ sizeof (fr30_cgen_macro_insn_table[0]));
+ const CGEN_IBASE *ib = & fr30_cgen_macro_insn_table[0];
+ const CGEN_OPCODE *oc = & fr30_cgen_macro_insn_opcode_table[0];
+ CGEN_INSN *insns = (CGEN_INSN *) xmalloc (num_macros * sizeof (CGEN_INSN));
+ memset (insns, 0, num_macros * sizeof (CGEN_INSN));
+ for (i = 0; i < num_macros; ++i)
+ {
+ insns[i].base = &ib[i];
+ insns[i].opcode = &oc[i];
+ }
+ cd->macro_insn_table.init_entries = insns;
+ cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
+ cd->macro_insn_table.num_init_entries = num_macros;
+
+ oc = & fr30_cgen_insn_opcode_table[0];
+ insns = (CGEN_INSN *) cd->insn_table.init_entries;
+ for (i = 0; i < MAX_INSNS; ++i)
+ insns[i].opcode = &oc[i];
+
+ cd->sizeof_fields = sizeof (CGEN_FIELDS);
+ cd->set_fields_bitsize = set_fields_bitsize;
+
+ cd->asm_hash_p = asm_hash_insn_p;
+ cd->asm_hash = asm_hash_insn;
+ cd->asm_hash_size = CGEN_ASM_HASH_SIZE;
+
+ cd->dis_hash_p = dis_hash_insn_p;
+ cd->dis_hash = dis_hash_insn;
+ cd->dis_hash_size = CGEN_DIS_HASH_SIZE;
+}
diff --git a/opcodes/fr30-opc.h b/opcodes/fr30-opc.h
new file mode 100644
index 00000000000..d387ed55e99
--- /dev/null
+++ b/opcodes/fr30-opc.h
@@ -0,0 +1,150 @@
+/* Instruction opcode header for fr30.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef FR30_OPC_H
+#define FR30_OPC_H
+
+/* -- opc.h */
+
+/* ??? This can be improved upon. */
+#undef CGEN_DIS_HASH_SIZE
+#define CGEN_DIS_HASH_SIZE 16
+#undef CGEN_DIS_HASH
+#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)
+
+/* -- */
+/* Enum declaration for fr30 instruction types. */
+typedef enum cgen_insn_type {
+ FR30_INSN_INVALID, FR30_INSN_ADD, FR30_INSN_ADDI, FR30_INSN_ADD2
+ , FR30_INSN_ADDC, FR30_INSN_ADDN, FR30_INSN_ADDNI, FR30_INSN_ADDN2
+ , FR30_INSN_SUB, FR30_INSN_SUBC, FR30_INSN_SUBN, FR30_INSN_CMP
+ , FR30_INSN_CMPI, FR30_INSN_CMP2, FR30_INSN_AND, FR30_INSN_OR
+ , FR30_INSN_EOR, FR30_INSN_ANDM, FR30_INSN_ANDH, FR30_INSN_ANDB
+ , FR30_INSN_ORM, FR30_INSN_ORH, FR30_INSN_ORB, FR30_INSN_EORM
+ , FR30_INSN_EORH, FR30_INSN_EORB, FR30_INSN_BANDL, FR30_INSN_BORL
+ , FR30_INSN_BEORL, FR30_INSN_BANDH, FR30_INSN_BORH, FR30_INSN_BEORH
+ , FR30_INSN_BTSTL, FR30_INSN_BTSTH, FR30_INSN_MUL, FR30_INSN_MULU
+ , FR30_INSN_MULH, FR30_INSN_MULUH, FR30_INSN_DIV0S, FR30_INSN_DIV0U
+ , FR30_INSN_DIV1, FR30_INSN_DIV2, FR30_INSN_DIV3, FR30_INSN_DIV4S
+ , FR30_INSN_LSL, FR30_INSN_LSLI, FR30_INSN_LSL2, FR30_INSN_LSR
+ , FR30_INSN_LSRI, FR30_INSN_LSR2, FR30_INSN_ASR, FR30_INSN_ASRI
+ , FR30_INSN_ASR2, FR30_INSN_LDI8, FR30_INSN_LDI20, FR30_INSN_LDI32
+ , FR30_INSN_LD, FR30_INSN_LDUH, FR30_INSN_LDUB, FR30_INSN_LDR13
+ , FR30_INSN_LDR13UH, FR30_INSN_LDR13UB, FR30_INSN_LDR14, FR30_INSN_LDR14UH
+ , FR30_INSN_LDR14UB, FR30_INSN_LDR15, FR30_INSN_LDR15GR, FR30_INSN_LDR15DR
+ , FR30_INSN_LDR15PS, FR30_INSN_ST, FR30_INSN_STH, FR30_INSN_STB
+ , FR30_INSN_STR13, FR30_INSN_STR13H, FR30_INSN_STR13B, FR30_INSN_STR14
+ , FR30_INSN_STR14H, FR30_INSN_STR14B, FR30_INSN_STR15, FR30_INSN_STR15GR
+ , FR30_INSN_STR15DR, FR30_INSN_STR15PS, FR30_INSN_MOV, FR30_INSN_MOVDR
+ , FR30_INSN_MOVPS, FR30_INSN_MOV2DR, FR30_INSN_MOV2PS, FR30_INSN_JMP
+ , FR30_INSN_JMPD, FR30_INSN_CALLR, FR30_INSN_CALLRD, FR30_INSN_CALL
+ , FR30_INSN_CALLD, FR30_INSN_RET, FR30_INSN_RET_D, FR30_INSN_INT
+ , FR30_INSN_INTE, FR30_INSN_RETI, FR30_INSN_BRAD, FR30_INSN_BRA
+ , FR30_INSN_BNOD, FR30_INSN_BNO, FR30_INSN_BEQD, FR30_INSN_BEQ
+ , FR30_INSN_BNED, FR30_INSN_BNE, FR30_INSN_BCD, FR30_INSN_BC
+ , FR30_INSN_BNCD, FR30_INSN_BNC, FR30_INSN_BND, FR30_INSN_BN
+ , FR30_INSN_BPD, FR30_INSN_BP, FR30_INSN_BVD, FR30_INSN_BV
+ , FR30_INSN_BNVD, FR30_INSN_BNV, FR30_INSN_BLTD, FR30_INSN_BLT
+ , FR30_INSN_BGED, FR30_INSN_BGE, FR30_INSN_BLED, FR30_INSN_BLE
+ , FR30_INSN_BGTD, FR30_INSN_BGT, FR30_INSN_BLSD, FR30_INSN_BLS
+ , FR30_INSN_BHID, FR30_INSN_BHI, FR30_INSN_DMOVR13, FR30_INSN_DMOVR13H
+ , FR30_INSN_DMOVR13B, FR30_INSN_DMOVR13PI, FR30_INSN_DMOVR13PIH, FR30_INSN_DMOVR13PIB
+ , FR30_INSN_DMOVR15PI, FR30_INSN_DMOV2R13, FR30_INSN_DMOV2R13H, FR30_INSN_DMOV2R13B
+ , FR30_INSN_DMOV2R13PI, FR30_INSN_DMOV2R13PIH, FR30_INSN_DMOV2R13PIB, FR30_INSN_DMOV2R15PD
+ , FR30_INSN_LDRES, FR30_INSN_STRES, FR30_INSN_COPOP, FR30_INSN_COPLD
+ , FR30_INSN_COPST, FR30_INSN_COPSV, FR30_INSN_NOP, FR30_INSN_ANDCCR
+ , FR30_INSN_ORCCR, FR30_INSN_STILM, FR30_INSN_ADDSP, FR30_INSN_EXTSB
+ , FR30_INSN_EXTUB, FR30_INSN_EXTSH, FR30_INSN_EXTUH, FR30_INSN_LDM0
+ , FR30_INSN_LDM1, FR30_INSN_STM0, FR30_INSN_STM1, FR30_INSN_ENTER
+ , FR30_INSN_LEAVE, FR30_INSN_XCHB, FR30_INSN_MAX
+} CGEN_INSN_TYPE;
+
+/* Index of `invalid' insn place holder. */
+#define CGEN_INSN_INVALID FR30_INSN_INVALID
+
+/* Total number of insns in table. */
+#define MAX_INSNS ((int) FR30_INSN_MAX)
+
+/* This struct records data prior to insertion or after extraction. */
+struct cgen_fields
+{
+ int length;
+ long f_nil;
+ long f_op1;
+ long f_op2;
+ long f_op3;
+ long f_op4;
+ long f_op5;
+ long f_cc;
+ long f_ccc;
+ long f_Rj;
+ long f_Ri;
+ long f_Rs1;
+ long f_Rs2;
+ long f_Rjc;
+ long f_Ric;
+ long f_CRj;
+ long f_CRi;
+ long f_u4;
+ long f_u4c;
+ long f_i4;
+ long f_m4;
+ long f_u8;
+ long f_i8;
+ long f_i20_4;
+ long f_i20_16;
+ long f_i20;
+ long f_i32;
+ long f_udisp6;
+ long f_disp8;
+ long f_disp9;
+ long f_disp10;
+ long f_s10;
+ long f_u10;
+ long f_rel9;
+ long f_dir8;
+ long f_dir9;
+ long f_dir10;
+ long f_rel12;
+ long f_reglist_hi_st;
+ long f_reglist_low_st;
+ long f_reglist_hi_ld;
+ long f_reglist_low_ld;
+};
+
+#define CGEN_INIT_PARSE(od) \
+{\
+}
+#define CGEN_INIT_INSERT(od) \
+{\
+}
+#define CGEN_INIT_EXTRACT(od) \
+{\
+}
+#define CGEN_INIT_PRINT(od) \
+{\
+}
+
+
+#endif /* FR30_OPC_H */
diff --git a/opcodes/h8300-dis.c b/opcodes/h8300-dis.c
new file mode 100644
index 00000000000..57753a98d54
--- /dev/null
+++ b/opcodes/h8300-dis.c
@@ -0,0 +1,457 @@
+/* Disassemble h8300 instructions.
+ Copyright (C) 1993, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define DEFINE_TABLE
+
+#define h8_opcodes h8ops
+#include "opcode/h8300.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+
+/* Run through the opcodes and sort them into order to make them easy
+ to disassemble
+ */
+static void
+bfd_h8_disassemble_init ()
+{
+ unsigned int i;
+
+
+ struct h8_opcode *p;
+
+ for (p = h8_opcodes; p->name; p++)
+ {
+ int n1 = 0;
+ int n2 = 0;
+
+ if ((int) p->data.nib[0] < 16)
+ {
+ n1 = (int) p->data.nib[0];
+ }
+ else
+ n1 = 0;
+ if ((int) p->data.nib[1] < 16)
+ {
+ n2 = (int) p->data.nib[1];
+ }
+ else
+ n2 = 0;
+
+ /* Just make sure there are an even number of nibbles in it, and
+ that the count is the same s the length */
+ for (i = 0; p->data.nib[i] != E; i++)
+ /*EMPTY*/ ;
+ if (i & 1)
+ abort ();
+ p->length = i / 2;
+ }
+
+}
+
+
+unsigned int
+bfd_h8_disassemble (addr, info, mode)
+ bfd_vma addr;
+ disassemble_info *info;
+ int mode;
+{
+ /* Find the first entry in the table for this opcode */
+ static CONST char *regnames[] =
+ {
+ "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
+ "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"};
+
+ static CONST char *wregnames[] =
+ {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
+ };
+
+ static CONST char *lregnames[] =
+ {
+ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
+ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
+ }
+ ;
+
+ int rs = 0;
+ int rd = 0;
+ int rdisp = 0;
+ int abs = 0;
+ int bit = 0;
+ int plen = 0;
+ static boolean init = 0;
+ struct h8_opcode *q = h8_opcodes;
+ char CONST **pregnames = mode != 0 ? lregnames : wregnames;
+ int status;
+ int l;
+
+ unsigned char data[20];
+ void *stream = info->stream;
+ fprintf_ftype fprintf = info->fprintf_func;
+
+ if (!init)
+ {
+ bfd_h8_disassemble_init ();
+ init = 1;
+ }
+
+ status = info->read_memory_func(addr, data, 2, info);
+ if (status != 0)
+ {
+ info->memory_error_func(status, addr, info);
+ return -1;
+ }
+ for (l = 2; status == 0 && l < 10; l+=2)
+ {
+ status = info->read_memory_func(addr+l, data+l, 2, info);
+ }
+
+
+
+ /* Find the exact opcode/arg combo */
+ while (q->name)
+ {
+ op_type *nib;
+ unsigned int len = 0;
+
+ nib = q->data.nib;
+
+ while (1)
+ {
+ op_type looking_for = *nib;
+ int thisnib = data[len >> 1];
+
+ thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
+
+ if (looking_for < 16 && looking_for >=0)
+ {
+
+ if (looking_for != thisnib)
+ goto fail;
+ }
+
+ else
+ {
+
+ if ((int) looking_for & (int) B31)
+ {
+ if (! (((int) thisnib & 0x8) != 0))
+ goto fail;
+ looking_for = (op_type) ((int) looking_for & ~(int) B31);
+ }
+ if ((int) looking_for & (int) B30)
+ {
+ if (!(((int) thisnib & 0x8) == 0))
+ goto fail;
+ looking_for = (op_type) ((int) looking_for & ~(int) B30);
+ }
+
+ if (looking_for & DBIT)
+ {
+ if ((looking_for & 5) != (thisnib &5)) goto fail;
+ abs = (thisnib & 0x8) ? 2 : 1;
+ }
+
+ else if (looking_for & (REG | IND|INC|DEC))
+ {
+ if (looking_for & SRC)
+ {
+ rs = thisnib;
+ }
+ else
+ {
+ rd = thisnib;
+ }
+ }
+ else if (looking_for & L_16)
+ {
+ abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
+ plen = 16;
+
+ }
+ else if(looking_for & ABSJMP)
+ {
+ abs =
+ (data[1] << 16)
+ | (data[2] << 8)
+ | (data[3]);
+ }
+ else if(looking_for & MEMIND)
+ {
+ abs = data[1];
+ }
+ else if (looking_for & L_32)
+ {
+ int i = len >> 1;
+ abs = (data[i] << 24)
+ | (data[i + 1] << 16)
+ | (data[i + 2] << 8)
+ | (data[i+ 3]);
+
+ plen =32;
+
+ }
+ else if (looking_for & L_24)
+ {
+ int i = len >> 1;
+ abs = (data[i] << 16) | (data[i + 1] << 8)| (data[i+2]);
+ plen =24;
+ }
+ else if (looking_for & IGNORE)
+ {
+
+ }
+ else if (looking_for & DISPREG)
+ {
+ rdisp = thisnib;
+ }
+ else if (looking_for & KBIT)
+ {
+ switch (thisnib)
+ {
+ case 9:
+ abs = 4;
+ break;
+ case 8:
+ abs = 2;
+ break;
+ case 0:
+ abs = 1;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ else if (looking_for & L_8)
+ {
+ plen = 8;
+ abs = data[len >> 1];
+ }
+ else if (looking_for & L_3)
+ {
+ bit = thisnib & 0x7;
+ }
+ else if (looking_for & L_2)
+ {
+ plen = 2;
+ abs = thisnib & 0x3;
+ }
+ else if (looking_for & MACREG)
+ {
+ abs = (thisnib == 3);
+ }
+ else if (looking_for == E)
+ {
+
+ {
+ int i;
+
+ for (i = 0; i < q->length; i++)
+ {
+ fprintf (stream, "%02x ", data[i]);
+ }
+ for (; i < 6; i++)
+ {
+ fprintf (stream, " ");
+ }
+ }
+ fprintf (stream, "%s\t", q->name);
+
+ /* Gross. Disgusting. */
+ if (strcmp (q->name, "ldm.l") == 0)
+ {
+ int count, high;
+
+ count = (data[1] >> 4) & 0x3;
+ high = data[3] & 0x7;
+
+ fprintf (stream, "@sp+,er%d-er%d", high - count, high);
+ return q->length;
+ }
+
+ if (strcmp (q->name, "stm.l") == 0)
+ {
+ int count, low;
+
+ count = (data[1] >> 4) & 0x3;
+ low = data[3] & 0x7;
+
+ fprintf (stream, "er%d-er%d,@-sp", low, low + count);
+ return q->length;
+ }
+
+ /* Fill in the args */
+ {
+ op_type *args = q->args.nib;
+ int hadone = 0;
+
+
+ while (*args != E)
+ {
+ int x = *args;
+ if (hadone)
+ fprintf (stream, ",");
+
+
+ if (x & L_3)
+ {
+ fprintf (stream, "#0x%x", (unsigned) bit);
+ }
+ else if (x & (IMM|KBIT|DBIT))
+ {
+ /* Bletch. For shal #2,er0 and friends. */
+ if (*(args+1) & SRC_IN_DST)
+ abs = 2;
+
+ fprintf (stream, "#0x%x", (unsigned) abs);
+ }
+ else if (x & REG)
+ {
+ int rn = (x & DST) ? rd : rs;
+ switch (x & SIZE)
+ {
+ case L_8:
+ fprintf (stream, "%s", regnames[rn]);
+ break;
+ case L_16:
+ fprintf (stream, "%s", wregnames[rn]);
+ break;
+ case L_P:
+ case L_32:
+ fprintf (stream, "%s", lregnames[rn]);
+ break;
+
+ }
+ }
+ else if (x & MACREG)
+ {
+ fprintf (stream, "mac%c", abs ? 'l' : 'h');
+ }
+ else if (x & INC)
+ {
+ fprintf (stream, "@%s+", pregnames[rs]);
+ }
+ else if (x & DEC)
+ {
+ fprintf (stream, "@-%s", pregnames[rd]);
+ }
+
+ else if (x & IND)
+ {
+ int rn = (x & DST) ? rd : rs;
+ fprintf (stream, "@%s", pregnames[rn]);
+ }
+
+ else if (x & ABS8MEM)
+ {
+ fprintf (stream, "@0x%x:8", (unsigned) abs);
+ }
+
+ else if (x & (ABS|ABSJMP))
+ {
+ fprintf (stream, "@0x%x:%d", (unsigned) abs, plen);
+ }
+
+ else if (x & MEMIND)
+ {
+ fprintf (stream, "@@%d (%x)", abs, abs);
+ }
+
+ else if (x & PCREL)
+ {
+ if (x & L_16)
+ {
+ abs +=2;
+ fprintf (stream, ".%s%d (%x)", (short) abs > 0 ? "+" : "", (short) abs,
+ addr + (short) abs + 2);
+ }
+ else {
+ fprintf (stream, ".%s%d (%x)", (char) abs > 0 ? "+" : "", (char) abs,
+ addr + (char) abs + 2);
+ }
+ }
+ else if (x & DISP)
+ {
+ fprintf (stream, "@(0x%x:%d,%s)", abs,plen, pregnames[rdisp]);
+ }
+
+ else if (x & CCR)
+ {
+ fprintf (stream, "ccr");
+ }
+ else if (x & EXR)
+ {
+ fprintf (stream, "exr");
+ }
+ else
+ /* xgettext:c-format */
+ fprintf (stream, _("Hmmmm %x"), x);
+ hadone = 1;
+ args++;
+ }
+ }
+ return q->length;
+ }
+
+
+ else
+ {
+ /* xgettext:c-format */
+ fprintf (stream, _("Don't understand %x \n"), looking_for);
+ }
+ }
+
+ len++;
+ nib++;
+ }
+
+ fail:
+ q++;
+ }
+
+ /* Fell of the end */
+ fprintf (stream, "%02x %02x .word\tH'%x,H'%x",
+ data[0], data[1],
+ data[0], data[1]);
+ return 2;
+}
+
+int
+print_insn_h8300 (addr, info)
+bfd_vma addr;
+disassemble_info *info;
+{
+ return bfd_h8_disassemble (addr, info , 0);
+}
+
+int
+print_insn_h8300h (addr, info)
+bfd_vma addr;
+disassemble_info *info;
+{
+ return bfd_h8_disassemble (addr, info , 1);
+}
+
+int
+print_insn_h8300s (addr, info)
+bfd_vma addr;
+disassemble_info *info;
+{
+ return bfd_h8_disassemble (addr, info , 2);
+}
diff --git a/opcodes/h8500-dis.c b/opcodes/h8500-dis.c
new file mode 100644
index 00000000000..16858c98fa6
--- /dev/null
+++ b/opcodes/h8500-dis.c
@@ -0,0 +1,347 @@
+/* Disassemble h8500 instructions.
+ Copyright (C) 1993, 94, 95, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+
+#define DISASSEMBLER_TABLE
+#define DEFINE_TABLE
+
+#include "h8500-opc.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+/* Maximum length of an instruction. */
+#define MAXLEN 8
+
+#include <setjmp.h>
+
+struct private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+ struct disassemble_info *info;
+ bfd_byte *addr;
+{
+ int status;
+ struct private *priv = (struct private *) info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ longjmp (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+static char *crname[] =
+{"sr", "ccr", "*", "br", "ep", "dp", "*", "tp"};
+
+int
+print_insn_h8500 (addr, info)
+ bfd_vma addr;
+ disassemble_info *info;
+{
+ h8500_opcode_info *opcode;
+ void *stream = info->stream;
+ fprintf_ftype func = info->fprintf_func;
+
+ struct private priv;
+ bfd_byte *buffer = priv.the_buffer;
+
+ info->private_data = (PTR) & priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = addr;
+ if (setjmp (priv.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+if (0) {
+ static int one;
+ if (!one )
+ {
+ one = 1;
+ for (opcode = h8500_table; opcode->name; opcode++)
+ {
+ if ((opcode->bytes[0].contents & 0x8) == 0)
+ printf("%s\n", opcode->name);
+ }
+ }
+ }
+
+
+ /* Run down the table to find the one which matches */
+ for (opcode = h8500_table; opcode->name; opcode++)
+ {
+ int byte;
+ int rn = 0;
+ int rd = 0;
+ int rs = 0;
+ int disp = 0;
+ int abs = 0;
+ int imm = 0;
+ int pcrel = 0;
+ int qim = 0;
+ int i;
+ int cr = 0;
+ for (byte = 0; byte < opcode->length; byte++)
+ {
+ FETCH_DATA (info, buffer + byte + 1);
+ if ((buffer[byte] & opcode->bytes[byte].mask)
+ != (opcode->bytes[byte].contents))
+ {
+ goto next;
+ }
+ else
+ {
+ /* extract any info parts */
+ switch (opcode->bytes[byte].insert)
+ {
+ case 0:
+ case FP:
+ break;
+ default:
+ /* xgettext:c-format */
+ func (stream, _("can't cope with insert %d\n"),
+ opcode->bytes[byte].insert);
+ break;
+ case RN:
+ rn = buffer[byte] & 0x7;
+ break;
+ case RS:
+ rs = buffer[byte] & 0x7;
+ break;
+ case CRB:
+ cr = buffer[byte] & 0x7;
+ if (cr == 0)
+ goto next;
+ break;
+ case CRW:
+ cr = buffer[byte] & 0x7;
+ if (cr != 0)
+ goto next;
+ break;
+ case DISP16:
+ FETCH_DATA (info, buffer + byte + 2);
+ disp = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case FPIND_D8:
+ case DISP8:
+ disp = ((char) (buffer[byte]));
+ break;
+ case RD:
+ case RDIND:
+ rd = buffer[byte] & 0x7;
+ break;
+ case ABS24:
+ FETCH_DATA (info, buffer + byte + 3);
+ abs =
+ (buffer[byte] << 16)
+ | (buffer[byte + 1] << 8)
+ | (buffer[byte + 2]);
+ break;
+ case ABS16:
+ FETCH_DATA (info, buffer + byte + 2);
+ abs = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case ABS8:
+ abs = (buffer[byte]);
+ break;
+ case IMM16:
+ FETCH_DATA (info, buffer + byte + 2);
+ imm = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case IMM4:
+ imm = (buffer[byte]) & 0xf;
+ break;
+ case IMM8:
+ case RLIST:
+ imm = (buffer[byte]);
+ break;
+ case PCREL16:
+ FETCH_DATA (info, buffer + byte + 2);
+ pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
+ break;
+ case PCREL8:
+ pcrel = (buffer[byte]);
+ break;
+ case QIM:
+ switch (buffer[byte] & 0x7)
+ {
+ case 0:
+ qim = 1;
+ break;
+ case 1:
+ qim = 2;
+ break;
+ case 4:
+ qim = -1;
+ break;
+ case 5:
+ qim = -2;
+ break;
+ }
+ break;
+
+ }
+ }
+ }
+ /* We get here when all the masks have passed so we can output the
+ operands*/
+ FETCH_DATA (info, buffer + opcode->length);
+ for (i = 0; i < opcode->length; i++)
+ {
+ (func) (stream, "%02x ", buffer[i]);
+ }
+ for (; i < 6; i++)
+ {
+ (func) (stream, " ");
+ }
+ (func) (stream, "%s\t", opcode->name);
+ for (i = 0; i < opcode->nargs; i++)
+ {
+ if (i)
+ (func) (stream, ",");
+ switch (opcode->arg_type[i])
+ {
+ case FP:
+ func (stream, "fp");
+ break;
+ case RNIND_D16:
+ func (stream, "@(0x%x:16,r%d)", disp, rn);
+ break;
+ case RNIND_D8:
+ func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
+ break;
+ case RDIND_D16:
+ func (stream, "@(0x%x:16,r%d)", disp, rd);
+ break;
+ case RDIND_D8:
+ func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
+ break;
+ case FPIND_D8:
+ func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);
+ break;
+ case CRB:
+ case CRW:
+ func (stream, "%s", crname[cr]);
+ break;
+ case RN:
+ func (stream, "r%d", rn);
+ break;
+ case RD:
+ func (stream, "r%d", rd);
+ break;
+ case RS:
+ func (stream, "r%d", rs);
+ break;
+ case RNDEC:
+ func (stream, "@-r%d", rn);
+ break;
+ case RNINC:
+ func (stream, "@r%d+", rn);
+ break;
+ case RNIND:
+ func (stream, "@r%d", rn);
+ break;
+ case RDIND:
+ func (stream, "@r%d", rd);
+ break;
+ case SPINC:
+ func (stream, "@sp+");
+ break;
+ case SPDEC:
+ func (stream, "@-sp");
+ break;
+ case ABS24:
+ func (stream, "@0x%0x:24", abs);
+ break;
+ case ABS16:
+ func (stream, "@0x%0x:16", abs & 0xffff);
+ break;
+ case ABS8:
+ func (stream, "@0x%0x:8", abs & 0xff);
+ break;
+ case IMM16:
+ func (stream, "#0x%0x:16", imm & 0xffff);
+ break;
+ case RLIST:
+ {
+ int i;
+ int nc = 0;
+ func (stream, "(");
+ for (i = 0; i < 8; i++)
+ {
+ if (imm & (1 << i))
+ {
+ func (stream, "r%d", i);
+ if (nc)
+ func (stream, ",");
+ nc = 1;
+ }
+ }
+ func (stream, ")");
+ }
+ break;
+ case IMM8:
+ func (stream, "#0x%0x:8", imm & 0xff);
+ break;
+ case PCREL16:
+ func (stream, "0x%0x:16", (pcrel + addr + opcode->length) & 0xffff);
+ break;
+ case PCREL8:
+ func (stream, "#0x%0x:8",
+ ((char) pcrel + addr + opcode->length) & 0xffff);
+ break;
+ case QIM:
+ func (stream, "#%d:q", qim);
+ break;
+ case IMM4:
+ func (stream, "#%d:4", imm);
+ break;
+ }
+ }
+ return opcode->length;
+ next:;
+ }
+
+ /* Couldn't understand anything */
+ /* xgettext:c-format */
+ func (stream, _("%02x\t\t*unknown*"), buffer[0]);
+ return 1;
+
+}
diff --git a/opcodes/h8500-opc.h b/opcodes/h8500-opc.h
new file mode 100644
index 00000000000..d4949af34d0
--- /dev/null
+++ b/opcodes/h8500-opc.h
@@ -0,0 +1,3836 @@
+typedef enum
+{
+ GR0,GR1,GR2,GR3,GR4,GR5,GR6,GR7,
+ GPR0, GPR1, GPR2, GPR3, GPR4, GPR5, GPR6, GPR7,
+ GCCR, GPC,
+ GSEGC, GSEGD, GSEGE, GSEGT,GLAST
+} gdbreg_type;
+#define O_XORC 1
+#define O_XOR 2
+#define O_XCH 3
+#define O_UNLK 4
+#define O_TST 5
+#define O_TRAPA 6
+#define O_TRAP_VS 7
+#define O_TAS 8
+#define O_SWAP 9
+#define O_SUBX 10
+#define O_SUBS 11
+#define O_SUB 12
+#define O_STM 13
+#define O_STC 14
+#define O_SLEEP 15
+#define O_SHLR 16
+#define O_SHLL 17
+#define O_SHAR 18
+#define O_SHAL 19
+#define O_SCB_NE 20
+#define O_SCB_F 21
+#define O_SCB_EQ 22
+#define O_RTS 23
+#define O_RTD 24
+#define O_ROTXR 25
+#define O_ROTXL 26
+#define O_ROTR 27
+#define O_ROTL 28
+#define O_PRTS 29
+#define O_PRTD 30
+#define O_PJSR 31
+#define O_PJMP 32
+#define O_ORC 33
+#define O_OR 34
+#define O_NOT 35
+#define O_NOP 36
+#define O_NEG 37
+#define O_MULXU 38
+#define O_MOVTPE 39
+#define O_MOVFPE 40
+#define O_MOV 41
+#define O_LINK 42
+#define O_LDM 43
+#define O_LDC 44
+#define O_JSR 45
+#define O_JMP 46
+#define O_EXTU 47
+#define O_EXTS 48
+#define O_DSUB 49
+#define O_DIVXU 50
+#define O_DADD 51
+#define O_CMP 52
+#define O_CLR 53
+#define O_BVS 54
+#define O_BVC 55
+#define O_BTST 56
+#define O_BT 57
+#define O_BSR 58
+#define O_BSET 59
+#define O_BRN 60
+#define O_BRA 61
+#define O_BPT 62
+#define O_BPL 63
+#define O_BNOT 64
+#define O_BNE 65
+#define O_BMI 66
+#define O_BLT 67
+#define O_BLS 68
+#define O_BLO 69
+#define O_BLE 70
+#define O_BHS 71
+#define O_BHI 72
+#define O_BGT 73
+#define O_BGE 74
+#define O_BF 75
+#define O_BEQ 76
+#define O_BCS 77
+#define O_BCLR 78
+#define O_BCC 79
+#define O_ANDC 80
+#define O_AND 81
+#define O_ADDX 82
+#define O_ADDS 83
+#define O_ADD 84
+#define O_BYTE 128
+#define O_WORD 0x000
+#define O_UNSZ 0x000
+#define FPIND_D8 10
+#define RDIND_D16 11
+#define RDIND_D8 12
+#define SPDEC 13
+#define RDIND 14
+#define RN 15
+#define RNIND_D8 16
+#define RNIND_D16 17
+#define RNDEC 18
+#define RNINC 19
+#define RNIND 20
+#define SPINC 21
+#define ABS16 22
+#define ABS24 23
+#define PCREL16 24
+#define PCREL8 25
+#define ABS8 26
+#define CRB 27
+#define CR 28
+#define CRW 29
+#define DISP16 30
+#define DISP8 31
+#define FP 32
+#define IMM16 33
+#define IMM4 34
+#define IMM8 35
+#define RLIST 36
+#define QIM 37
+#define RD 38
+#define RS 39
+#define SP 40
+typedef enum { AC_BAD, AC_EI, AC_RI, AC_D, AC_,AC_ERR, AC_X,AC_B, AC_EE,AC_RR,AC_IE,
+ AC_RE,AC_E, AC_I, AC_ER,AC_IRR, AC_IR, AC_RER, AC_ERE,AC_EIE } addr_class_type;
+typedef struct {
+ short int idx;
+ char flags,src1,src2,dst;
+ unsigned char flavor;
+ char *name;
+ int nargs;
+ int arg_type[2];
+ int length;
+ struct { unsigned char contents;unsigned char mask; char insert; } bytes[6];
+} h8500_opcode_info;
+h8500_opcode_info h8500_table[]
+#ifdef ASSEMBLER_TABLE
+#ifdef DEFINE_TABLE
+={
+/*
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },
+ {0x00,0x00,ABS16 },
+ {0x00,0x00, },
+ {0x07,0xff, },
+ {0x00,0x00,IMM16 },{0x00,0x00, }}},*/
+
+{1,'s','E','C','C',O_XORC|O_WORD,"xorc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x68,0xf8,CRW }}},
+{2,'s','E','C','C',O_XORC|O_BYTE,"xorc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x68,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{5,'m','E','D','D',O_XOR|O_UNSZ,"xor",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{6,'-','X','!','!',O_XCH|O_WORD,"xch.w",2,{RS,RD},2, {{0xa8,0xf8,RS },{0x90,0xf8,RD }}},
+{7,'-','X','!','!',O_XCH|O_UNSZ,"xch",2,{RS,RD},2, {{0xa8,0xf8,RS },{0x90,0xf8,RD }}},
+{8,'-','B','!','!',O_UNLK|O_UNSZ,"unlk",1,{FP,0},1, {{0x0f,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{RN,0},2, {{0xa8,0xf8,RN },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x16,0xff, }}},
+{11,'a','E','!','!',O_TST|O_UNSZ,"tst",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x16,0xff, }}},
+{12,'-','I','!','!',O_TRAPA|O_UNSZ,"trapa",1,{IMM4,0},2, {{0x08,0xff, },{0x10,0xf0,IMM4 }}},
+{13,'-','B','!','!',O_TRAP_VS|O_UNSZ,"trap/vs",0,{0,0},1, {{0x09,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x17,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{RN,0},2, {{0xa0,0xf8,RN },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x17,0xff, }}},
+{15,'s','E','!','E',O_TAS|O_UNSZ,"tas",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x17,0xff, }}},
+{16,'m','D','!','D',O_SWAP|O_BYTE,"swap.b",1,{RD,0},2, {{0xa0,0xf8,RD },{0x10,0xff, }}},
+{17,'m','D','!','D',O_SWAP|O_UNSZ,"swap",1,{RD,0},2, {{0xa0,0xf8,RD },{0x10,0xff, }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{20,'a','E','D','D',O_SUBX|O_UNSZ,"subx",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{23,'-','E','D','D',O_SUBS|O_UNSZ,"subs",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{26,'a','E','D','D',O_SUB|O_UNSZ,"sub",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{27,'-','I','!','E',O_STM|O_UNSZ,"stm",2,{RLIST,SPDEC},2, {{0x12,0xff, },{0x00,0x00,RLIST }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,RN},2, {{0xa8,0xf8,RN },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,RNDEC},2, {{0xb8,0xf8,RN },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,RNINC},2, {{0xc8,0xf8,RN },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,RNIND},2, {{0xd8,0xf8,RN },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x98,0xf8,CRW }}},
+{28,'s','C','!','E',O_STC|O_WORD,"stc.w",2,{CRW,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x98,0xf8,CRW }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RN},2, {{0xa0,0xf8,RN },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNDEC},2, {{0xb0,0xf8,RN },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNINC},2, {{0xc0,0xf8,RN },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNIND},2, {{0xd0,0xf8,RN },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x98,0xf8,CRB }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,RN},2, {{0xa8,0xf8,RN },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,RN},2, {{0xa0,0xf8,RN },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,RNDEC},2, {{0xb0,0xf8,RN },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,RNIND},2, {{0xd8,0xf8,RN },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,RNINC},2, {{0xc8,0xf8,RN },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,RNDEC},2, {{0xb8,0xf8,RN },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,RNIND},2, {{0xd0,0xf8,RN },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,RNINC},2, {{0xc0,0xf8,RN },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRW,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x98,0xf8,CRW }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x98,0xf8,CRB }}},
+{30,'s','C','!','E',O_STC|O_UNSZ,"stc",2,{CRB,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x98,0xf8,CRB }}},
+{31,'-','!','!','!',O_SLEEP|O_UNSZ,"sleep",0,{0,0},1, {{0x1a,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1b,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1b,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1b,0xff, }}},
+{34,'h','E','!','E',O_SHLR|O_UNSZ,"shlr",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1b,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1a,0xff, }}},
+{37,'h','E','!','E',O_SHLL|O_UNSZ,"shll",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1a,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{RN,0},2, {{0xa8,0xf8,RN },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x19,0xff, }}},
+{40,'h','E','!','E',O_SHAR|O_UNSZ,"shar",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x19,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{RN,0},2, {{0xa8,0xf8,RN },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x18,0xff, }}},
+{43,'h','E','!','E',O_SHAL|O_UNSZ,"shal",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x18,0xff, }}},
+{44,'-','B','S','S',O_SCB_NE|O_UNSZ,"scb/ne",2,{RS,PCREL8},3, {{0x06,0xff, },{0xb8,0xf8,RS },{0x00,0x00,PCREL8 }}},
+{45,'-','B','S','S',O_SCB_F|O_UNSZ,"scb/f",2,{RS,PCREL8},3, {{0x01,0xff, },{0xb8,0xf8,RS },{0x00,0x00,PCREL8 }}},
+{46,'-','B','S','S',O_SCB_EQ|O_UNSZ,"scb/eq",2,{RS,PCREL8},3, {{0x07,0xff, },{0xb8,0xf8,RS },{0x00,0x00,PCREL8 }}},
+{47,'-','B','!','!',O_RTS|O_UNSZ,"rts",0,{0,0},1, {{0x19,0xff, }}},
+{48,'-','B','!','!',O_RTD|O_UNSZ,"rtd",1,{IMM8,0},2, {{0x14,0xff, },{0x00,0x00,IMM8 }}},
+{48,'-','B','!','!',O_RTD|O_UNSZ,"rtd",1,{IMM16,0},3, {{0x14,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1f,0xff, }}},
+{51,'h','E','!','E',O_ROTXR|O_UNSZ,"rotxr",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1f,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1e,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1e,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1e,0xff, }}},
+{54,'h','E','!','E',O_ROTXL|O_UNSZ,"rotxl",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1e,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1d,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1d,0xff, }}},
+{57,'h','E','!','E',O_ROTR|O_UNSZ,"rotr",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1d,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1c,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1c,0xff, }}},
+{60,'h','E','!','E',O_ROTL|O_UNSZ,"rotl",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1c,0xff, }}},
+{61,'-','B','!','!',O_PRTS|O_UNSZ,"prts",0,{0,0},2, {{0x11,0xff, },{0x19,0xff, }}},
+{62,'-','B','!','!',O_PRTD|O_UNSZ,"prtd",1,{IMM8,0},3, {{0x11,0xff, },{0x14,0xff, },{0x00,0x00,IMM8 }}},
+{62,'-','B','!','!',O_PRTD|O_UNSZ,"prtd",1,{IMM16,0},4, {{0x11,0xff, },{0x1c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{63,'-','J','!','!',O_PJSR|O_UNSZ,"pjsr",1,{RDIND,0},2, {{0x11,0xff, },{0xc8,0xf8,RDIND }}},
+{63,'-','J','!','!',O_PJSR|O_UNSZ,"pjsr",1,{ABS24,0},4, {{0x03,0xff, },{0x00,0x00,ABS24 },{0x00,0x00, },{0x00,0x00, }}},
+{64,'-','J','!','!',O_PJMP|O_UNSZ,"pjmp",1,{RDIND,0},2, {{0x11,0xff, },{0xc0,0xf8,RDIND }}},
+{64,'-','J','!','!',O_PJMP|O_UNSZ,"pjmp",1,{ABS24,0},4, {{0x13,0xff, },{0x00,0x00,ABS24 },{0x00,0x00, },{0x00,0x00, }}},
+{65,'s','I','C','C',O_ORC|O_WORD,"orc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x48,0xf8,CRW }}},
+{66,'s','I','C','C',O_ORC|O_BYTE,"orc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x48,0xf8,CRB }}},
+{67,'s','I','C','C',O_ORC|O_UNSZ,"orc",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x48,0xf8,CRB }}},
+{67,'s','I','C','C',O_ORC|O_UNSZ,"orc",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x48,0xf8,CRW }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{70,'m','E','D','D',O_OR|O_UNSZ,"or",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x15,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x15,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{RN,0},2, {{0xa8,0xf8,RN },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x15,0xff, }}},
+{73,'m','E','!','E',O_NOT|O_UNSZ,"not",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x15,0xff, }}},
+{74,'-','!','!','!',O_NOP|O_UNSZ,"nop",0,{0,0},1, {{0x00,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x14,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x14,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{RN,0},2, {{0xa8,0xf8,RN },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x14,0xff, }}},
+{77,'a','E','!','E',O_NEG|O_UNSZ,"neg",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x14,0xff, }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{80,'p','E','D','D',O_MULXU|O_UNSZ,"mulxu",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RN},3, {{0xa0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNDEC},3, {{0xb0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNINC},3, {{0xc0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNIND},3, {{0xd0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,RN},3, {{0xa0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,RNDEC},3, {{0xb0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,RNIND},3, {{0xd0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,RNINC},3, {{0xc0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x00,0xff, },{0x90,0xf8,RS }}},
+{82,'-','S','!','E',O_MOVTPE|O_UNSZ,"movtpe",2,{RS,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x00,0xff, },{0x90,0xf8,RS }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RN,RD},3, {{0xa0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNINC,RD},3, {{0xc0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNIND,RD},3, {{0xd0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNDEC,RD},3, {{0xb0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{IMM8,RD},4, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{ABS8,RD},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNIND_D8,RD},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{ABS16,RD},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNIND_D16,RD},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{RN,RD},3, {{0xa0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{RNINC,RD},3, {{0xc0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{RNIND,RD},3, {{0xd0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{RNDEC,RD},3, {{0xb0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{IMM8,RD},4, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{ABS8,RD},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{RNIND_D8,RD},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{ABS16,RD},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x00,0xff, },{0x80,0xf8,RD }}},
+{84,'-','E','!','D',O_MOVFPE|O_UNSZ,"movfpe",2,{RNIND_D16,RD},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x00,0xff, },{0x80,0xf8,RD }}},
+{85,'m','S','!','E',O_MOV|O_WORD,"mov:s.w",2,{RS,ABS8},2, {{0x78,0xf8,RS },{0x00,0x00,ABS8 }}},
+{86,'m','S','!','E',O_MOV|O_BYTE,"mov:s.b",2,{RS,ABS8},2, {{0x70,0xf8,RS },{0x00,0x00,ABS8 }}},
+{87,'m','S','!','E',O_MOV|O_UNSZ,"mov:s",2,{RS,ABS8},2, {{0x78,0xf8,RS },{0x00,0x00,ABS8 }}},
+{88,'m','E','!','D',O_MOV|O_WORD,"mov:l.w",2,{ABS8,RD},2, {{0x68,0xf8,RD },{0x00,0x00,ABS8 }}},
+{89,'m','E','!','D',O_MOV|O_BYTE,"mov:l.b",2,{ABS8,RD},2, {{0x60,0xf8,RD },{0x00,0x00,ABS8 }}},
+{90,'m','E','!','D',O_MOV|O_UNSZ,"mov:l",2,{ABS8,RD},2, {{0x68,0xf8,RD },{0x00,0x00,ABS8 }}},
+{91,'m','I','!','D',O_MOV|O_WORD,"mov:i.w",2,{IMM16,RD},3, {{0x58,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{92,'m','I','!','D',O_MOV|O_UNSZ,"mov:i", 2,{IMM16,RD},3, {{0x58,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x90,0xf8,RS }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x90,0xf8,RS }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x90,0xf8,RS }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x80,0xf8,RD }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x80,0xf8,RD }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNIND_D8},5,{{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNIND_D16},6,{{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x90,0xf8,RS }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x90,0xf8,RS }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x90,0xf8,RS }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x80,0xf8,RD }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNIND},3, {{0xd0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNINC},3, {{0xc0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNDEC},3, {{0xb0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x90,0xf8,RS }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x80,0xf8,RD }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x90,0xf8,RS }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x80,0xf8,RD }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x90,0xf8,RS }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x80,0xf8,RD }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x80,0xf8,RD }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,RNIND},3, {{0xd8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,RNDEC},3, {{0xb8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,RNINC},3, {{0xc8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,RNIND_D8},4, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,ABS8},4, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{95,'m','S','!','E',O_MOV|O_UNSZ,"mov:g",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{95,'m','E','!','D',O_MOV|O_UNSZ,"mov:g",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,ABS16},5, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM8,RNIND_D16},5, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{95,'m','I','!','E',O_MOV|O_UNSZ,"mov:g",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{96,'m','S','!','E',O_MOV|O_WORD,"mov:f.w",2,{RS,FPIND_D8},2, {{0x98,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{96,'m','E','!','D',O_MOV|O_WORD,"mov:f.w",2,{FPIND_D8,RD},2, {{0x88,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{97,'m','S','!','E',O_MOV|O_BYTE,"mov:f.b",2,{RS,FPIND_D8},2, {{0x90,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{97,'m','E','!','D',O_MOV|O_BYTE,"mov:f.b",2,{FPIND_D8,RD},2, {{0x80,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{98,'m','S','!','E',O_MOV|O_UNSZ,"mov:f",2,{RS,FPIND_D8},2, {{0x98,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{98,'m','E','!','D',O_MOV|O_UNSZ,"mov:f",2,{FPIND_D8,RD},2, {{0x88,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{99,'m','I','!','D',O_MOV|O_BYTE,"mov:e.b",2,{IMM8,RD},2, {{0x50,0xf8,RD },{0x00,0x00,IMM8 }}},
+{100,'m','I','!','D',O_MOV|O_UNSZ,"mov:e",2,{IMM8,RD},2, {{0x50,0xf8,RD },{0x00,0x00,IMM8 }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,FPIND_D8},2, {{0x98,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,ABS8},2, {{0x78,0xf8,RS },{0x00,0x00,ABS8 }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{ABS8,RD},2, {{0x68,0xf8,RD },{0x00,0x00,ABS8 }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x90,0xf8,RS }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x90,0xf8,RS }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x90,0xf8,RS }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x80,0xf8,RD }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{FPIND_D8,RD},2, {{0x88,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x80,0xf8,RD }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x80,0xf8,RD }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x80,0xf8,RD }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{101,'m','I','!','D',O_MOV|O_WORD,"mov.w",2,{IMM16,RD},3, {{0x58,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{101,'m','S','!','E',O_MOV|O_WORD,"mov.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{101,'m','E','!','D',O_MOV|O_WORD,"mov.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{101,'m','I','!','E',O_MOV|O_WORD,"mov.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{FPIND_D8,RD},2, {{0x80,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,ABS8},2, {{0x70,0xf8,RS },{0x00,0x00,ABS8 }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x80,0xf8,RD }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x90,0xf8,RS }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x90,0xf8,RS }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x90,0xf8,RS }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x80,0xf8,RD }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,FPIND_D8},2, {{0x90,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x80,0xf8,RD }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x80,0xf8,RD }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{ABS8,RD},2, {{0x60,0xf8,RD },{0x00,0x00,ABS8 }}},
+{102,'m','I','!','D',O_MOV|O_BYTE,"mov.b",2,{IMM8,RD},2, {{0x50,0xf8,RD },{0x00,0x00,IMM8 }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x80,0xf8,RD }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,RNIND},3, {{0xd0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,RNINC},3, {{0xc0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,RNDEC},3, {{0xb0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{102,'m','S','!','E',O_MOV|O_BYTE,"mov.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{102,'m','E','!','D',O_MOV|O_BYTE,"mov.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{102,'m','I','!','E',O_MOV|O_BYTE,"mov.b",2,{IMM8,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{ABS8,RD},2, {{0x68,0xf8,RD },{0x00,0x00,ABS8 }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,ABS8},2, {{0x78,0xf8,RS },{0x00,0x00,ABS8 }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x80,0xf8,RD }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x90,0xf8,RS }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x90,0xf8,RS }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x90,0xf8,RS }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x80,0xf8,RD }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,FPIND_D8},2, {{0x98,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x80,0xf8,RD }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{FPIND_D8,RD},2, {{0x88,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+/*{103,'m','I','!','D',O_MOV|O_UNSZ,"mov",2,{IMM8,RD},2, {{0x58,0xf8,RD },{0x00,0x00,IMM8 }}},*/
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x80,0xf8,RD }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,RNIND},3, {{0xd8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,RNINC},3, {{0xc8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,RNDEC},3, {{0xb8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{103,'m','I','!','D',O_MOV|O_UNSZ,"mov",2,{IMM16,RD},3, {{0x58,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,ABS8},4, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','S','!','E',O_MOV|O_UNSZ,"mov",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,RNIND_D8},4, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{103,'m','E','!','D',O_MOV|O_UNSZ,"mov",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,ABS16},5, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM8,RNIND_D16},5, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{103,'m','I','!','E',O_MOV|O_UNSZ,"mov",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{104,'-','S','I','!',O_LINK|O_UNSZ,"link",2,{FP,IMM8},2, {{0x17,0xff, },{0x00,0x00,IMM8 }}},
+{104,'-','S','I','!',O_LINK|O_UNSZ,"link",2,{FP,IMM16},3, {{0x1f,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{105,'-','E','!','C',O_LDM|O_UNSZ,"ldm",2,{SPINC,RLIST},2, {{0x02,0xff, },{0x00,0x00,RLIST }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{RN,CRW},2, {{0xa8,0xf8,RN },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{RNIND,CRW},2, {{0xd8,0xf8,RN },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{RNINC,CRW},2, {{0xc8,0xf8,RN },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{RNDEC,CRW},2, {{0xb8,0xf8,RN },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{ABS8,CRW},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{RNIND_D8,CRW},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{ABS16,CRW},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{RNIND_D16,CRW},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RN,CRB},2, {{0xa0,0xf8,RN },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNDEC,CRB},2, {{0xb0,0xf8,RN },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNINC,CRB},2, {{0xc0,0xf8,RN },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNIND,CRB},2, {{0xd0,0xf8,RN },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{ABS8,CRB},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNIND_D8,CRB},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{ABS16,CRB},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNIND_D16,CRB},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RN,CRW},2, {{0xa8,0xf8,RN },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RN,CRB},2, {{0xa0,0xf8,RN },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNINC,CRW},2, {{0xc8,0xf8,RN },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNIND,CRB},2, {{0xd0,0xf8,RN },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNDEC,CRW},2, {{0xb8,0xf8,RN },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNIND,CRW},2, {{0xd8,0xf8,RN },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNDEC,CRB},2, {{0xb0,0xf8,RN },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNINC,CRB},2, {{0xc0,0xf8,RN },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{ABS8,CRW},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{ABS8,CRB},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNIND_D8,CRW},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNIND_D8,CRB},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{ABS16,CRB},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x88,0xf8,CRB }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{ABS16,CRW},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNIND_D16,CRW},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{108,'s','E','!','C',O_LDC|O_UNSZ,"ldc",2,{RNIND_D16,CRB},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x88,0xf8,CRB }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{RDIND,0},2, {{0x11,0xff, },{0xd8,0xf8,RD }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{ABS16,0},3, {{0x18,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{RDIND_D8,0},3, {{0x11,0xff, },{0xe8,0xf8,RDIND_D8 },{0x00,0x00, }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{RDIND_D16,0},4, {{0x11,0xff, },{0xf8,0xf8,RDIND_D16 },{0x00,0x00, },{0x00,0x00, }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{RDIND,0},2, {{0x11,0xff, },{0xd0,0xf8,RD }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{ABS16,0},3, {{0x10,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{RDIND_D8,0},3, {{0x11,0xff, },{0xe0,0xf8,RDIND_D8 },{0x00,0x00, }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{RDIND_D16,0},4, {{0x11,0xff, },{0xf0,0xf8,RDIND_D16 },{0x00,0x00, },{0x00,0x00, }}},
+{111,'s','D','!','D',O_EXTU|O_BYTE,"extu.b",1,{RD,0},2, {{0xa0,0xf8,RD },{0x12,0xff, }}},
+{112,'s','D','!','D',O_EXTU|O_UNSZ,"extu",1,{RD,0},2, {{0xa0,0xf8,RD },{0x12,0xff, }}},
+{113,'s','D','!','D',O_EXTS|O_BYTE,"exts.b",1,{RD,0},2, {{0xa0,0xf8,RD },{0x11,0xff, }}},
+{114,'s','D','!','D',O_EXTS|O_UNSZ,"exts",1,{RD,0},2, {{0xa0,0xf8,RD },{0x11,0xff, }}},
+{115,'s','D','!','!',O_DSUB|O_UNSZ,"dsub",2,{RS,RD},3, {{0xa0,0xf8,RS },{0x00,0xff, },{0xb0,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{118,'s','E','D','D',O_DIVXU|O_UNSZ,"divxu",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{119,'s','D','!','!',O_DADD|O_UNSZ,"dadd",2,{RS,RD},3, {{0xa0,0xf8,RS },{0x00,0xff, },{0xa0,0xf8,RD }}},
+{120,'a','D','I','!',O_CMP|O_WORD,"cmp:i.w",2,{IMM16,RD},3, {{0x48,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{121,'a','D','I','!',O_CMP|O_UNSZ,"cmp:i",2,{IMM16,RD},3, {{0x48,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RN},4, {{0xa8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNIND_D8},5,{{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RN},3, {{0xa0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNIND},3, {{0xd0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNINC},3, {{0xc0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNDEC},3, {{0xb0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RN},4, {{0xa8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{124,'a','D','E','!',O_CMP|O_UNSZ,"cmp:g",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,RNIND_D16},6,{{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{124,'a','E','I','!',O_CMP|O_UNSZ,"cmp:g",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{125,'a','D','I','!',O_CMP|O_BYTE,"cmp:e.b",2,{IMM8,RD},2, {{0x40,0xf8,RD },{0x00,0x00,IMM8 }}},
+{126,'a','D','I','!',O_CMP|O_UNSZ,"cmp:e",2,{IMM8,RD},2, {{0x48,0xf8,RD },{0x00,0x00,IMM8 }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x70,0xf8,RD }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x70,0xf8,RD }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x70,0xf8,RD }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x70,0xf8,RD }}},
+{127,'a','D','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RD},3, {{0x48,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{127,'a','D','E','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RN},4, {{0xa8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,RNIND_D16},6,{{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{127,'a','E','I','!',O_CMP|O_WORD,"cmp.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x70,0xf8,RD }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x70,0xf8,RD }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x70,0xf8,RD }}},
+{128,'a','D','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RD},2, {{0x40,0xf8,RD },{0x00,0x00,IMM8 }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x70,0xf8,RD }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RN},3, {{0xa0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RNIND},3, {{0xd0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RNINC},3, {{0xc0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RNDEC},3, {{0xb0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x70,0xf8,RD }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','D','E','!',O_CMP|O_BYTE,"cmp.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{128,'a','E','I','!',O_CMP|O_BYTE,"cmp.b",2,{IMM8,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x70,0xf8,RD }}},
+{129,'a','D','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM8,RD},2, {{0x48,0xf8,RD },{0x00,0x00,IMM8 }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x70,0xf8,RD }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x70,0xf8,RD }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x70,0xf8,RD }}},
+{129,'a','D','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RD},3, {{0x48,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RN},4, {{0xa8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{129,'a','D','E','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{129,'a','E','I','!',O_CMP|O_UNSZ,"cmp",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{RN,0},2, {{0xa8,0xf8,RN },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x13,0xff, }}},
+{132,'c','!','!','E',O_CLR|O_UNSZ,"clr",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x13,0xff, }}},
+{133,'-','B','!','!',O_BVS|O_WORD,"bvs.w",1,{PCREL16,0},3, {{0x39,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{134,'-','B','!','!',O_BVS|O_BYTE,"bvs.b",1,{PCREL8,0},2, {{0x29,0xff, },{0x00,0x00,PCREL8 }}},
+{135,'-','B','!','!',O_BVS|O_UNSZ,"bvs",1,{PCREL8,0},2, {{0x29,0xff, },{0x00,0x00,PCREL8 }}},
+{135,'-','B','!','!',O_BVS|O_UNSZ,"bvs",1,{PCREL16,0},3, {{0x39,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{136,'-','B','!','!',O_BVC|O_WORD,"bvc.w",1,{PCREL16,0},3, {{0x38,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{137,'-','B','!','!',O_BVC|O_BYTE,"bvc.b",1,{PCREL8,0},2, {{0x28,0xff, },{0x00,0x00,PCREL8 }}},
+{138,'-','B','!','!',O_BVC|O_UNSZ,"bvc",1,{PCREL8,0},2, {{0x28,0xff, },{0x00,0x00,PCREL8 }}},
+{138,'-','B','!','!',O_BVC|O_UNSZ,"bvc",1,{PCREL16,0},3, {{0x38,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x78,0xf8,RS }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x78,0xf8,RS }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x78,0xf8,RS }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x78,0xf8,RS }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x78,0xf8,RS }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x78,0xf8,RS }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x78,0xf8,RS }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x78,0xf8,RS }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{141,'b','E','S','E',O_BTST|O_UNSZ,"btst",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{141,'b','E','I','E',O_BTST|O_UNSZ,"btst",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{142,'-','B','!','!',O_BT|O_WORD,"bt.w",1,{PCREL16,0},3, {{0x30,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{143,'-','B','!','!',O_BT|O_BYTE,"bt.b",1,{PCREL8,0},2, {{0x20,0xff, },{0x00,0x00,PCREL8 }}},
+{144,'-','B','!','!',O_BT|O_UNSZ,"bt",1,{PCREL8,0},2, {{0x20,0xff, },{0x00,0x00,PCREL8 }}},
+{144,'-','B','!','!',O_BT|O_UNSZ,"bt",1,{PCREL16,0},3, {{0x30,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{145,'-','B','!','!',O_BSR|O_WORD,"bsr.w",1,{PCREL16,0},3, {{0x1e,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{146,'-','B','!','!',O_BSR|O_BYTE,"bsr.b",1,{PCREL8,0},2, {{0x0e,0xff, },{0x00,0x00,PCREL8 }}},
+{147,'-','B','!','!',O_BSR|O_UNSZ,"bsr",1,{PCREL8,0},2, {{0x0e,0xff, },{0x00,0x00,PCREL8 }}},
+{147,'-','B','!','!',O_BSR|O_UNSZ,"bsr",1,{PCREL16,0},3, {{0x1e,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x48,0xf8,RS }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x48,0xf8,RS }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x48,0xf8,RS }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x48,0xf8,RS }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x48,0xf8,RS }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x48,0xf8,RS }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x48,0xf8,RS }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x48,0xf8,RS }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x48,0xf8,RS }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x48,0xf8,RS }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{150,'b','E','S','E',O_BSET|O_UNSZ,"bset",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{150,'b','E','I','E',O_BSET|O_UNSZ,"bset",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{151,'-','B','!','!',O_BRN|O_WORD,"brn.w",1,{PCREL16,0},3, {{0x31,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{152,'-','B','!','!',O_BRN|O_BYTE,"brn.b",1,{PCREL8,0},2, {{0x21,0xff, },{0x00,0x00,PCREL8 }}},
+{153,'-','B','!','!',O_BRN|O_UNSZ,"brn",1,{PCREL8,0},2, {{0x21,0xff, },{0x00,0x00,PCREL8 }}},
+{153,'-','B','!','!',O_BRN|O_UNSZ,"brn",1,{PCREL16,0},3, {{0x31,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{154,'-','B','!','!',O_BRA|O_WORD,"bra.w",1,{PCREL16,0},3, {{0x30,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{155,'-','B','!','!',O_BRA|O_BYTE,"bra.b",1,{PCREL8,0},2, {{0x20,0xff, },{0x00,0x00,PCREL8 }}},
+{156,'-','B','!','!',O_BRA|O_UNSZ,"bra",1,{PCREL8,0},2, {{0x20,0xff, },{0x00,0x00,PCREL8 }}},
+{156,'-','B','!','!',O_BRA|O_UNSZ,"bra",1,{PCREL16,0},3, {{0x30,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{157,'-','!','!','!',O_BPT|O_UNSZ,"bpt",0,{0,0},1, {{0x0b,0xff, }}},
+{158,'-','B','!','!',O_BPL|O_WORD,"bpl.w",1,{PCREL16,0},3, {{0x3a,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{159,'-','B','!','!',O_BPL|O_BYTE,"bpl.b",1,{PCREL8,0},2, {{0x2a,0xff, },{0x00,0x00,PCREL8 }}},
+{160,'-','B','!','!',O_BPL|O_UNSZ,"bpl",1,{PCREL8,0},2, {{0x2a,0xff, },{0x00,0x00,PCREL8 }}},
+{160,'-','B','!','!',O_BPL|O_UNSZ,"bpl",1,{PCREL16,0},3, {{0x3a,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x68,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x68,0xf8,RS }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x68,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x68,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x68,0xf8,RS }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x68,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x68,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x68,0xf8,RS }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x68,0xf8,RS }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x68,0xf8,RS }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x68,0xf8,RS }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x68,0xf8,RS }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x68,0xf8,RS }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{163,'b','E','S','E',O_BNOT|O_UNSZ,"bnot",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{163,'b','E','I','E',O_BNOT|O_UNSZ,"bnot",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{164,'-','B','!','!',O_BNE|O_WORD,"bne.w",1,{PCREL16,0},3, {{0x36,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{165,'-','B','!','!',O_BNE|O_BYTE,"bne.b",1,{PCREL8,0},2, {{0x26,0xff, },{0x00,0x00,PCREL8 }}},
+{166,'-','B','!','!',O_BNE|O_UNSZ,"bne",1,{PCREL8,0},2, {{0x26,0xff, },{0x00,0x00,PCREL8 }}},
+{166,'-','B','!','!',O_BNE|O_UNSZ,"bne",1,{PCREL16,0},3, {{0x36,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{167,'-','B','!','!',O_BMI|O_WORD,"bmi.w",1,{PCREL16,0},3, {{0x3b,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{168,'-','B','!','!',O_BMI|O_BYTE,"bmi.b",1,{PCREL8,0},2, {{0x2b,0xff, },{0x00,0x00,PCREL8 }}},
+{169,'-','B','!','!',O_BMI|O_UNSZ,"bmi",1,{PCREL8,0},2, {{0x2b,0xff, },{0x00,0x00,PCREL8 }}},
+{169,'-','B','!','!',O_BMI|O_UNSZ,"bmi",1,{PCREL16,0},3, {{0x3b,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{170,'-','B','!','!',O_BLT|O_WORD,"blt.w",1,{PCREL16,0},3, {{0x3d,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{171,'-','B','!','!',O_BLT|O_BYTE,"blt.b",1,{PCREL8,0},2, {{0x2d,0xff, },{0x00,0x00,PCREL8 }}},
+{172,'-','B','!','!',O_BLT|O_UNSZ,"blt",1,{PCREL8,0},2, {{0x2d,0xff, },{0x00,0x00,PCREL8 }}},
+{172,'-','B','!','!',O_BLT|O_UNSZ,"blt",1,{PCREL16,0},3, {{0x3d,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{173,'-','B','!','!',O_BLS|O_WORD,"bls.w",1,{PCREL16,0},3, {{0x33,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{174,'-','B','!','!',O_BLS|O_BYTE,"bls.b",1,{PCREL8,0},2, {{0x23,0xff, },{0x00,0x00,PCREL8 }}},
+{175,'-','B','!','!',O_BLS|O_UNSZ,"bls",1,{PCREL8,0},2, {{0x23,0xff, },{0x00,0x00,PCREL8 }}},
+{175,'-','B','!','!',O_BLS|O_UNSZ,"bls",1,{PCREL16,0},3, {{0x33,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{176,'-','B','!','!',O_BLO|O_WORD,"blo.w",1,{PCREL16,0},3, {{0x35,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{177,'-','B','!','!',O_BLO|O_BYTE,"blo.b",1,{PCREL8,0},2, {{0x25,0xff, },{0x00,0x00,PCREL8 }}},
+{178,'-','B','!','!',O_BLO|O_UNSZ,"blo",1,{PCREL8,0},2, {{0x25,0xff, },{0x00,0x00,PCREL8 }}},
+{178,'-','B','!','!',O_BLO|O_UNSZ,"blo",1,{PCREL16,0},3, {{0x35,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{179,'-','B','!','!',O_BLE|O_WORD,"ble.w",1,{PCREL16,0},3, {{0x3f,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{180,'-','B','!','!',O_BLE|O_BYTE,"ble.b",1,{PCREL8,0},2, {{0x2f,0xff, },{0x00,0x00,PCREL8 }}},
+{181,'-','B','!','!',O_BLE|O_UNSZ,"ble",1,{PCREL8,0},2, {{0x2f,0xff, },{0x00,0x00,PCREL8 }}},
+{181,'-','B','!','!',O_BLE|O_UNSZ,"ble",1,{PCREL16,0},3, {{0x3f,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{182,'-','B','!','!',O_BHS|O_WORD,"bhs.w",1,{PCREL16,0},3, {{0x34,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{183,'-','B','!','!',O_BHS|O_BYTE,"bhs.b",1,{PCREL8,0},2, {{0x24,0xff, },{0x00,0x00,PCREL8 }}},
+{184,'-','B','!','!',O_BHS|O_UNSZ,"bhs",1,{PCREL8,0},2, {{0x24,0xff, },{0x00,0x00,PCREL8 }}},
+{184,'-','B','!','!',O_BHS|O_UNSZ,"bhs",1,{PCREL16,0},3, {{0x34,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{185,'-','B','!','!',O_BHI|O_WORD,"bhi.w",1,{PCREL16,0},3, {{0x32,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{186,'-','B','!','!',O_BHI|O_BYTE,"bhi.b",1,{PCREL8,0},2, {{0x22,0xff, },{0x00,0x00,PCREL8 }}},
+{187,'-','B','!','!',O_BHI|O_UNSZ,"bhi",1,{PCREL8,0},2, {{0x22,0xff, },{0x00,0x00,PCREL8 }}},
+{187,'-','B','!','!',O_BHI|O_UNSZ,"bhi",1,{PCREL16,0},3, {{0x32,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{188,'-','B','!','!',O_BGT|O_WORD,"bgt.w",1,{PCREL16,0},3, {{0x3e,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{189,'-','B','!','!',O_BGT|O_BYTE,"bgt.b",1,{PCREL8,0},2, {{0x2e,0xff, },{0x00,0x00,PCREL8 }}},
+{190,'-','B','!','!',O_BGT|O_UNSZ,"bgt",1,{PCREL8,0},2, {{0x2e,0xff, },{0x00,0x00,PCREL8 }}},
+{190,'-','B','!','!',O_BGT|O_UNSZ,"bgt",1,{PCREL16,0},3, {{0x3e,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{191,'-','B','!','!',O_BGE|O_WORD,"bge.w",1,{PCREL16,0},3, {{0x3c,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{192,'-','B','!','!',O_BGE|O_BYTE,"bge.b",1,{PCREL8,0},2, {{0x2c,0xff, },{0x00,0x00,PCREL8 }}},
+{193,'-','B','!','!',O_BGE|O_UNSZ,"bge",1,{PCREL8,0},2, {{0x2c,0xff, },{0x00,0x00,PCREL8 }}},
+{193,'-','B','!','!',O_BGE|O_UNSZ,"bge",1,{PCREL16,0},3, {{0x3c,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{194,'-','B','!','!',O_BF|O_WORD,"bf.w",1,{PCREL16,0},3, {{0x31,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{195,'-','B','!','!',O_BF|O_BYTE,"bf.b",1,{PCREL8,0},2, {{0x21,0xff, },{0x00,0x00,PCREL8 }}},
+{196,'-','B','!','!',O_BF|O_UNSZ,"bf",1,{PCREL8,0},2, {{0x21,0xff, },{0x00,0x00,PCREL8 }}},
+{196,'-','B','!','!',O_BF|O_UNSZ,"bf",1,{PCREL16,0},3, {{0x31,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{197,'-','B','!','!',O_BEQ|O_WORD,"beq.w",1,{PCREL16,0},3, {{0x37,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{198,'-','B','!','!',O_BEQ|O_BYTE,"beq.b",1,{PCREL8,0},2, {{0x27,0xff, },{0x00,0x00,PCREL8 }}},
+{199,'-','B','!','!',O_BEQ|O_UNSZ,"beq",1,{PCREL8,0},2, {{0x27,0xff, },{0x00,0x00,PCREL8 }}},
+{199,'-','B','!','!',O_BEQ|O_UNSZ,"beq",1,{PCREL16,0},3, {{0x37,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{200,'-','B','!','!',O_BCS|O_WORD,"bcs.w",1,{PCREL16,0},3, {{0x35,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{201,'-','B','!','!',O_BCS|O_BYTE,"bcs.b",1,{PCREL8,0},2, {{0x25,0xff, },{0x00,0x00,PCREL8 }}},
+{202,'-','B','!','!',O_BCS|O_UNSZ,"bcs",1,{PCREL8,0},2, {{0x25,0xff, },{0x00,0x00,PCREL8 }}},
+{202,'-','B','!','!',O_BCS|O_UNSZ,"bcs",1,{PCREL16,0},3, {{0x35,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x58,0xf8,RS }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x58,0xf8,RS }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x58,0xf8,RS }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x58,0xf8,RS }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x58,0xf8,RS }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x58,0xf8,RS }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x58,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x58,0xf8,RS }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x58,0xf8,RS }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x58,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x58,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x58,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x58,0xf8,RS }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x58,0xf8,RS }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x58,0xf8,RS }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x58,0xf8,RS }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x58,0xf8,RS }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x58,0xf8,RS }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{205,'b','E','S','E',O_BCLR|O_UNSZ,"bclr",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{205,'b','E','I','E',O_BCLR|O_UNSZ,"bclr",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{206,'-','B','!','!',O_BCC|O_WORD,"bcc.w",1,{PCREL16,0},3, {{0x34,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{207,'-','B','!','!',O_BCC|O_BYTE,"bcc.b",1,{PCREL8,0},2, {{0x24,0xff, },{0x00,0x00,PCREL8 }}},
+{208,'-','B','!','!',O_BCC|O_UNSZ,"bcc",1,{PCREL8,0},2, {{0x24,0xff, },{0x00,0x00,PCREL8 }}},
+{208,'-','B','!','!',O_BCC|O_UNSZ,"bcc",1,{PCREL16,0},3, {{0x34,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{209,'s','I','S','S',O_ANDC|O_WORD,"andc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x58,0xf8,CRW }}},
+{210,'s','I','S','S',O_ANDC|O_BYTE,"andc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x58,0xf8,CRB }}},
+{211,'s','I','S','S',O_ANDC|O_UNSZ,"andc",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x58,0xf8,CRB }}},
+{211,'s','I','S','S',O_ANDC|O_UNSZ,"andc",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x58,0xf8,CRW }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{214,'m','E','D','D',O_AND|O_UNSZ,"and",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{217,'a','E','D','D',O_ADDX|O_UNSZ,"addx",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{220,'-','E','D','D',O_ADDS|O_UNSZ,"adds",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RN},2, {{0xa8,0xf8,RN },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNINC},2, {{0xc8,0xf8,RN },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNDEC},2, {{0xb8,0xf8,RN },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNIND},2, {{0xd8,0xf8,RN },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RN},2, {{0xa0,0xf8,RN },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNINC},2, {{0xc0,0xf8,RN },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNDEC},2, {{0xb0,0xf8,RN },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNIND},2, {{0xd0,0xf8,RN },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,RN},2, {{0xa8,0xf8,RN },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,RNDEC},2, {{0xb8,0xf8,RN },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,RNINC},2, {{0xc8,0xf8,RN },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,RNIND},2, {{0xd8,0xf8,RN },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{223,'a','I','E','E',O_ADD|O_UNSZ,"add:q",2,{QIM,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{226,'a','E','D','D',O_ADD|O_UNSZ,"add:g",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x20,0xf8,RD }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,RN},2, {{0xa8,0xf8,RN },{0x08,0xf8,QIM }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,RNIND},2, {{0xd8,0xf8,RN },{0x08,0xf8,QIM }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x20,0xf8,RD }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,RNDEC},2, {{0xb8,0xf8,RN },{0x08,0xf8,QIM }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,RNINC},2, {{0xc8,0xf8,RN },{0x08,0xf8,QIM }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x20,0xf8,RD }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x20,0xf8,RD }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{227,'a','I','E','E',O_ADD|O_WORD,"add.w",2,{QIM,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{227,'a','E','D','D',O_ADD|O_WORD,"add.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x20,0xf8,RD }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,RN},2, {{0xa0,0xf8,RN },{0x08,0xf8,QIM }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,RNINC},2, {{0xc0,0xf8,RN },{0x08,0xf8,QIM }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x20,0xf8,RD }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,RNIND},2, {{0xd0,0xf8,RN },{0x08,0xf8,QIM }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x20,0xf8,RD }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,RNDEC},2, {{0xb0,0xf8,RN },{0x08,0xf8,QIM }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x20,0xf8,RD }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x20,0xf8,RD }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{228,'a','I','E','E',O_ADD|O_BYTE,"add.b",2,{QIM,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{228,'a','E','D','D',O_ADD|O_BYTE,"add.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x20,0xf8,RD }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,RN},2, {{0xa8,0xf8,RN },{0x08,0xf8,QIM }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,RNDEC},2, {{0xb8,0xf8,RN },{0x08,0xf8,QIM }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x20,0xf8,RD }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,RNIND},2, {{0xd8,0xf8,RN },{0x08,0xf8,QIM }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,RNINC},2, {{0xc8,0xf8,RN },{0x08,0xf8,QIM }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x20,0xf8,RD }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x20,0xf8,RD }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{229,'a','I','E','E',O_ADD|O_UNSZ,"add",2,{QIM,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{229,'a','E','D','D',O_ADD|O_UNSZ,"add",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+0,0,0}
+#endif
+;
+#endif
+#ifdef DISASSEMBLER_TABLE
+#ifdef DEFINE_TABLE
+={
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RN},2, {{0xa0,0xf8,RN },{0x98,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNDEC},2, {{0xb0,0xf8,RN },{0x98,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNINC},2, {{0xc0,0xf8,RN },{0x98,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x60,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNIND},2, {{0xd0,0xf8,RN },{0x98,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x60,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x30,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x98,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x60,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x98,0xf8,CRB }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x30,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x16,0xff, }}},
+{6,'-','X','!','!',O_XCH|O_WORD,"xch.w",2,{RS,RD},2, {{0xa8,0xf8,RS },{0x90,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x16,0xff, }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x30,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x16,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x30,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x16,0xff, }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x30,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x16,0xff, }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x16,0xff, }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x30,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x16,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x30,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x16,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x30,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x16,0xff, }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x16,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{16,'m','D','!','D',O_SWAP|O_WORD,"swap.b",1,{RD,0},2, {{0xa0,0xf8,RD },{0x10,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x17,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x30,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xb0,0xf8,RD }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x17,0xff, }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xb0,0xf8,RD }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x17,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x30,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x38,0xf8,RD }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x17,0xff, }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xb0,0xf8,RD }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x17,0xff, }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x17,0xff, }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x38,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xb0,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x38,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xb0,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x38,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x38,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xb0,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x38,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xb0,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xb0,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x38,0xf8,RD }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x38,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xb0,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x16,0xff, }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x30,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x38,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x60,0xf8,RD }}},
+{2,'s','E','C','C',O_XORC|O_BYTE,"xorc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x68,0xf8,CRB }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xb0,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x16,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x17,0xff, }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x30,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x38,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x98,0xf8,CRB }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xb0,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x16,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x17,0xff, }}},
+{12,'-','I','!','!',O_TRAPA|O_UNSZ,"trapa",1,{IMM4,0},2, {{0x08,0xff, },{0x10,0xf0,IMM4 }}},
+{13,'-','B','!','!',O_TRAP_VS|O_UNSZ,"trap/vs",0,{0,0},1, {{0x09,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{1,'s','E','C','C',O_XORC|O_WORD,"xorc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x68,0xf8,CRW }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x16,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x30,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x38,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x60,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xb0,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x16,0xff, }}},
+{8,'-','B','!','!',O_UNLK|O_UNSZ,"unlk",1,{FP,0},1, {{0x0f,0xff, }}},
+{25,'a','E','D','D',O_SUB|O_BYTE,"sub.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{22,'-','E','D','D',O_SUBS|O_BYTE,"subs.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{4,'m','E','D','D',O_XOR|O_BYTE,"xor.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{29,'s','C','!','E',O_STC|O_BYTE,"stc.b",2,{CRB,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x98,0xf8,CRB }}},
+{27,'-','I','!','E',O_STM|O_UNSZ,"stm",2,{RLIST,SPDEC},2, {{0x12,0xff, },{0x00,0x00,RLIST }}},
+{19,'a','E','D','D',O_SUBX|O_BYTE,"subx.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{10,'a','E','!','!',O_TST|O_BYTE,"tst.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x16,0xff, }}},
+{14,'s','E','!','E',O_TAS|O_BYTE,"tas.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x17,0xff, }}},
+{24,'a','E','D','D',O_SUB|O_WORD,"sub.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x30,0xf8,RD }}},
+{21,'-','E','D','D',O_SUBS|O_WORD,"subs.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x38,0xf8,RD }}},
+{3,'m','E','D','D',O_XOR|O_WORD,"xor.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x60,0xf8,RD }}},
+{18,'a','E','D','D',O_SUBX|O_WORD,"subx.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb0,0xf8,RD }}},
+{9,'a','E','!','!',O_TST|O_WORD,"tst.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x16,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1b,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1b,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1b,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1b,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x19,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1b,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x19,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1b,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1b,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1b,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1b,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1b,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1a,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1a,0xff, }}},
+{36,'h','E','!','E',O_SHLL|O_BYTE,"shll.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1a,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1b,0xff, }}},
+{35,'h','E','!','E',O_SHLL|O_WORD,"shll.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1a,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1b,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1b,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x19,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1b,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x19,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x19,0xff, }}},
+{33,'h','E','!','E',O_SHLR|O_BYTE,"shlr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1b,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1b,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1b,0xff, }}},
+{39,'h','E','!','E',O_SHAR|O_BYTE,"shar.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x19,0xff, }}},
+{31,'-','!','!','!',O_SLEEP|O_UNSZ,"sleep",0,{0,0},1, {{0x1a,0xff, }}},
+{38,'h','E','!','E',O_SHAR|O_WORD,"shar.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x19,0xff, }}},
+{32,'h','E','!','E',O_SHLR|O_WORD,"shlr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1b,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x18,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1e,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x18,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x18,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x18,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1e,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x18,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1e,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x18,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1e,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x18,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1e,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x18,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1f,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1e,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1f,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1e,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1f,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1e,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1f,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1e,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1f,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1e,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1f,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1e,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1f,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1e,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1f,0xff, }}},
+{45,'-','B','S','S',O_SCB_F|O_UNSZ,"scb/f",2,{RS,PCREL8},3, {{0x01,0xff, },{0xb8,0xf8,RS },{0x00,0x00,PCREL8 }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1e,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1f,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1f,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1f,0xff, }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x18,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1e,0xff, }}},
+{44,'-','B','S','S',O_SCB_NE|O_UNSZ,"scb/ne",2,{RS,PCREL8},3, {{0x06,0xff, },{0xb8,0xf8,RS },{0x00,0x00,PCREL8 }}},
+{46,'-','B','S','S',O_SCB_EQ|O_UNSZ,"scb/eq",2,{RS,PCREL8},3, {{0x07,0xff, },{0xb8,0xf8,RS },{0x00,0x00,PCREL8 }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x18,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1e,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x18,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1e,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1f,0xff, }}},
+{48,'-','B','!','!',O_RTD|O_UNSZ,"rtd",1,{IMM16,0},3, {{0x14,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{48,'-','B','!','!',O_RTD|O_UNSZ,"rtd",1,{IMM8,0},2, {{0x14,0xff, },{0x00,0x00,IMM8 }}},
+{42,'h','E','!','E',O_SHAL|O_BYTE,"shal.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x18,0xff, }}},
+{53,'h','E','!','E',O_ROTXL|O_BYTE,"rotxl.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1e,0xff, }}},
+{50,'h','E','!','E',O_ROTXR|O_BYTE,"rotxr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1f,0xff, }}},
+{47,'-','B','!','!',O_RTS|O_UNSZ,"rts",0,{0,0},1, {{0x19,0xff, }}},
+{41,'h','E','!','E',O_SHAL|O_WORD,"shal.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x18,0xff, }}},
+{52,'h','E','!','E',O_ROTXL|O_WORD,"rotxl.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1e,0xff, }}},
+{49,'h','E','!','E',O_ROTXR|O_WORD,"rotxr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1f,0xff, }}},
+{99,'m','I','!','D',O_MOV|O_BYTE,"mov:e.b",2,{IMM8,RD},2, {{0x50,0xf8,RD },{0x00,0x00,IMM8 }}},
+{97,'m','E','!','D',O_MOV|O_BYTE,"mov:f.b",2,{FPIND_D8,RD},2, {{0x80,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{96,'m','E','!','D',O_MOV|O_WORD,"mov:f.w",2,{FPIND_D8,RD},2, {{0x88,0xf8,RD },{0x00,0x00,FPIND_D8 }}},
+{97,'m','S','!','E',O_MOV|O_BYTE,"mov:f.b",2,{RS,FPIND_D8},2, {{0x90,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{96,'m','S','!','E',O_MOV|O_WORD,"mov:f.w",2,{RS,FPIND_D8},2, {{0x98,0xf8,RS },{0x00,0x00,FPIND_D8 }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x80,0xf8,RD }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1d,0xff, }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x90,0xf8,RS }}},
+{91,'m','I','!','D',O_MOV|O_WORD,"mov:i.w",2,{IMM16,RD},3, {{0x58,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{89,'m','E','!','D',O_MOV|O_BYTE,"mov:l.b",2,{ABS8,RD},2, {{0x60,0xf8,RD },{0x00,0x00,ABS8 }}},
+{88,'m','E','!','D',O_MOV|O_WORD,"mov:l.w",2,{ABS8,RD},2, {{0x68,0xf8,RD },{0x00,0x00,ABS8 }}},
+{86,'m','S','!','E',O_MOV|O_BYTE,"mov:s.b",2,{RS,ABS8},2, {{0x70,0xf8,RS },{0x00,0x00,ABS8 }}},
+{85,'m','S','!','E',O_MOV|O_WORD,"mov:s.w",2,{RS,ABS8},2, {{0x78,0xf8,RS },{0x00,0x00,ABS8 }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RN,RD},3, {{0xa0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1d,0xff, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNDEC,RD},3, {{0xb0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xa8,0xf8,RD }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RN},3, {{0xa0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x1c,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x40,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xa8,0xf8,RD }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x15,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x1c,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x40,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xa8,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x15,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x40,0xf8,RD }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNDEC},3, {{0xb0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1c,0xff, }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x14,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x40,0xf8,RD }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1c,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x15,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x40,0xf8,RD }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x15,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1d,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x15,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x40,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x15,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1d,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x40,0xf8,RD }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x15,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1c,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x40,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x15,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1d,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x40,0xf8,RD }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x15,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1c,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x40,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x15,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1d,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x15,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1c,0xff, }}},
+{63,'-','J','!','!',O_PJSR|O_UNSZ,"pjsr",1,{ABS24,0},4, {{0x03,0xff, },{0x00,0x00,ABS24 },{0x00,0x00, },{0x00,0x00, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x40,0xf8,RD }}},
+{66,'s','I','C','C',O_ORC|O_BYTE,"orc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x48,0xf8,CRB }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x14,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1c,0xff, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x40,0xf8,RD }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x15,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1c,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x15,0xff, }}},
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x14,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x15,0xff, }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{74,'-','!','!','!',O_NOP|O_UNSZ,"nop",0,{0,0},1, {{0x00,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1c,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{65,'s','I','C','C',O_ORC|O_WORD,"orc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x48,0xf8,CRW }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x15,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1c,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x40,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x14,0xff, }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x15,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1d,0xff, }}},
+{64,'-','J','!','!',O_PJMP|O_UNSZ,"pjmp",1,{RDIND,0},2, {{0x11,0xff, },{0xc0,0xf8,RDIND }}},
+{63,'-','J','!','!',O_PJSR|O_UNSZ,"pjsr",1,{RDIND,0},2, {{0x11,0xff, },{0xc8,0xf8,RDIND }}},
+{62,'-','B','!','!',O_PRTD|O_UNSZ,"prtd",1,{IMM8,0},3, {{0x11,0xff, },{0x14,0xff, },{0x00,0x00,IMM8 }}},
+{61,'-','B','!','!',O_PRTS|O_UNSZ,"prts",0,{0,0},2, {{0x11,0xff, },{0x19,0xff, }}},
+{62,'-','B','!','!',O_PRTD|O_UNSZ,"prtd",1,{IMM16,0},4, {{0x11,0xff, },{0x1c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{64,'-','J','!','!',O_PJMP|O_UNSZ,"pjmp",1,{ABS24,0},4, {{0x13,0xff, },{0x00,0x00,ABS24 },{0x00,0x00, },{0x00,0x00, }}},
+{69,'m','E','D','D',O_OR|O_BYTE,"or.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xa8,0xf8,RD }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x1c,0xff, }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xa8,0xf8,RD }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x1c,0xff, }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xa8,0xf8,RD }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xa8,0xf8,RD }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x1c,0xff, }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{79,'p','E','D','D',O_MULXU|O_BYTE,"mulxu.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNINC},3, {{0xc0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x1c,0xff, }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNIND},3, {{0xd0,0xf8,RN },{0x00,0xff, },{0x90,0xf8,RS }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x1c,0xff, }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x00,0xff, },{0x90,0xf8,RS }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x00,0xff, },{0x90,0xf8,RS }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x00,0xff, },{0x90,0xf8,RS }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNIND,RD},3, {{0xd0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNINC,RD},3, {{0xc0,0xf8,RN },{0x00,0xff, },{0x80,0xf8,RD }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1d,0xff, }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNIND_D8,RD},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{RNIND_D16,RD},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{IMM8,RD},4, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{ABS8,RD},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x00,0xff, },{0x80,0xf8,RD }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x1d,0xff, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x80,0xf8,RD }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x80,0xf8,RD }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x1d,0xff, }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x90,0xf8,RS }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x90,0xf8,RS }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x90,0xf8,RS }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x1d,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x1d,0xff, }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNDEC},3, {{0xb0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,RNDEC},4, {{0xb8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x90,0xf8,RS }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNINC},3, {{0xc0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,RNINC},4, {{0xc8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x90,0xf8,RS }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RNIND},3, {{0xd0,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,RNIND},4, {{0xd8,0xf8,RN },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x90,0xf8,RS }}},
+
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x1d,0xff, }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x80,0xf8,RD }}},
+{94,'m','E','!','D',O_MOV|O_BYTE,"mov:g.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{94,'m','S','!','E',O_MOV|O_BYTE,"mov:g.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x90,0xf8,RS }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x1d,0xff, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x80,0xf8,RD }}},
+{83,'-','E','!','D',O_MOVFPE|O_BYTE,"movfpe.b",2,{ABS16,RD},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x00,0xff, },{0x80,0xf8,RD }}},
+{81,'-','S','!','E',O_MOVTPE|O_BYTE,"movtpe.b",2,{RS,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x00,0xff, },{0x90,0xf8,RS }}},
+{94,'m','I','!','E',O_MOV|O_BYTE,"mov:g.b",2,{IMM8,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x07,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+
+{93,'m','I','!','E',O_MOV|O_WORD,"mov:g.w",2,{IMM8,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x06,0xff, },{0x00,0x00,IMM8 },{0x00,0x00, }}},
+
+{76,'a','E','!','E',O_NEG|O_BYTE,"neg.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x14,0xff, }}},
+{56,'h','E','!','E',O_ROTR|O_BYTE,"rotr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1d,0xff, }}},
+{93,'m','E','!','D',O_MOV|O_WORD,"mov:g.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x80,0xf8,RD }}},
+{93,'m','S','!','E',O_MOV|O_WORD,"mov:g.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x90,0xf8,RS }}},
+{78,'p','E','D','D',O_MULXU|O_WORD,"mulxu.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa8,0xf8,RD }}},
+{75,'a','E','!','E',O_NEG|O_WORD,"neg.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x14,0xff, }}},
+{55,'h','E','!','E',O_ROTR|O_WORD,"rotr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1d,0xff, }}},
+{72,'m','E','!','E',O_NOT|O_BYTE,"not.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x15,0xff, }}},
+{68,'m','E','D','D',O_OR|O_WORD,"or.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x40,0xf8,RD }}},
+{71,'m','E','!','E',O_NOT|O_WORD,"not.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x15,0xff, }}},
+{58,'h','E','!','E',O_ROTL|O_WORD,"rotl.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1c,0xff, }}},
+{59,'h','E','!','E',O_ROTL|O_BYTE,"rotl.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x1c,0xff, }}},
+{125,'a','D','I','!',O_CMP|O_BYTE,"cmp:e.b",2,{IMM8,RD},2, {{0x40,0xf8,RD },{0x00,0x00,IMM8 }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RN},3, {{0xa0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x70,0xf8,RD }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RN},4, {{0xa8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RN,CRB},2, {{0xa0,0xf8,RN },{0x88,0xf8,CRB }}},
+{120,'a','D','I','!',O_CMP|O_WORD,"cmp:i.w",2,{IMM16,RD},3, {{0x48,0xf8,RD },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xb8,0xf8,RD }}},
+{119,'s','D','!','!',O_DADD|O_UNSZ,"dadd",2,{RS,RD},3, {{0xa0,0xf8,RS },{0x00,0xff, },{0xa0,0xf8,RD }}},
+{115,'s','D','!','!',O_DSUB|O_UNSZ,"dsub",2,{RS,RD},3, {{0xa0,0xf8,RS },{0x00,0xff, },{0xb0,0xf8,RD }}},
+{113,'s','D','!','D',O_EXTS|O_BYTE,"exts.b",1,{RD,0},2, {{0xa0,0xf8,RD },{0x11,0xff, }}},
+{111,'s','D','!','D',O_EXTU|O_BYTE,"extu.b",1,{RD,0},2, {{0xa0,0xf8,RD },{0x12,0xff, }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xb8,0xf8,RD }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNIND_D8,CRB},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x88,0xf8,CRB }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNIND_D16,CRB},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x88,0xf8,CRB }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{ABS16,0},3, {{0x10,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{RDIND,0},2, {{0x11,0xff, },{0xd0,0xf8,RD }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{RDIND,0},2, {{0x11,0xff, },{0xd8,0xf8,RD }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{RDIND_D8,0},3, {{0x11,0xff, },{0xe0,0xf8,RDIND_D8 },{0x00,0x00, }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{RDIND_D8,0},3, {{0x11,0xff, },{0xe8,0xf8,RDIND_D8 },{0x00,0x00, }}},
+{110,'-','B','!','!',O_JMP|O_UNSZ,"jmp",1,{RDIND_D16,0},4, {{0x11,0xff, },{0xf0,0xf8,RDIND_D16 },{0x00,0x00, },{0x00,0x00, }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{RDIND_D16,0},4, {{0x11,0xff, },{0xf8,0xf8,RDIND_D16 },{0x00,0x00, },{0x00,0x00, }}},
+{109,'-','B','!','!',O_JSR|O_UNSZ,"jsr",1,{ABS16,0},3, {{0x18,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{ABS16,CRB},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x88,0xf8,CRB }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xb8,0xf8,RD }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNINC,CRB},2, {{0xc0,0xf8,RN },{0x88,0xf8,CRB }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xb8,0xf8,RD }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNIND,CRB},2, {{0xd0,0xf8,RN },{0x88,0xf8,CRB }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x88,0xf8,CRB }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{117,'s','E','D','D',O_DIVXU|O_BYTE,"divxu.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xb8,0xf8,RD }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{ABS8,CRB},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x88,0xf8,CRB }}},
+{116,'s','E','D','D',O_DIVXU|O_WORD,"divxu.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xb8,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x70,0xf8,RD }}},
+{107,'s','E','!','C',O_LDC|O_BYTE,"ldc.b",2,{RNDEC,CRB},2, {{0xb0,0xf8,RN },{0x88,0xf8,CRB }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNDEC},3, {{0xb0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNDEC},4, {{0xb8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNINC},3, {{0xc0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNINC},4, {{0xc8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNIND},3, {{0xd0,0xf8,RN },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNIND},4, {{0xd8,0xf8,RN },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNIND_D8},4, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNIND_D8},5, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RNIND_D16},5, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RNIND_D16},6, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{105,'-','E','!','C',O_LDM|O_UNSZ,"ldm",2,{SPINC,RLIST},2, {{0x02,0xff, },{0x00,0x00,RLIST }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,ABS8},4, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,ABS8},5, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{106,'s','E','!','C',O_LDC|O_WORD,"ldc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x88,0xf8,CRW }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x70,0xf8,RD }}},
+{123,'a','D','E','!',O_CMP|O_BYTE,"cmp:g.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{123,'a','E','I','!',O_CMP|O_BYTE,"cmp:g.b",2,{IMM8,ABS16},5, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x04,0xff, },{0x00,0x00,IMM8 }}},
+{122,'a','E','I','!',O_CMP|O_WORD,"cmp:g.w",2,{IMM16,ABS16},6, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x05,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{122,'a','D','E','!',O_CMP|O_WORD,"cmp:g.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x70,0xf8,RD }}},
+{104,'-','S','I','!',O_LINK|O_UNSZ,"link",2,{FP,IMM16},3, {{0x1f,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, }}},
+{104,'-','S','I','!',O_LINK|O_UNSZ,"link",2,{FP,IMM8},2, {{0x17,0xff, },{0x00,0x00,IMM8 }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x48,0xf8,RS }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x78,0xf8,RS }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RN,0},2, {{0xa0,0xf8,RN },{0x13,0xff, }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNDEC,0},2, {{0xb0,0xf8,RN },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNINC,0},2, {{0xc0,0xf8,RN },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNIND,0},2, {{0xd0,0xf8,RN },{0x13,0xff, }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x78,0xf8,RS }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNIND_D8,0},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x13,0xff, }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{RNIND_D16,0},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x13,0xff, }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNIND_D16,0},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{IMM8,0},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x13,0xff, }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{ABS8,0},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x13,0xff, }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x78,0xf8,RS }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x78,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNDEC,0},2, {{0xb8,0xf8,RN },{0x13,0xff, }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x78,0xf8,RS }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x78,0xf8,RS }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x78,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNIND_D8,0},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x13,0xff, }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{IMM16,0},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x13,0xff, }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x78,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{ABS8,0},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x13,0xff, }}},
+{140,'b','E','I','E',O_BTST|O_BYTE,"btst.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{140,'b','E','S','E',O_BTST|O_BYTE,"btst.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{131,'c','!','!','E',O_CLR|O_BYTE,"clr.b",1,{ABS16,0},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x13,0xff, }}},
+{139,'b','E','I','E',O_BTST|O_WORD,"btst.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xf0,0xf0,IMM4 }}},
+{139,'b','E','S','E',O_BTST|O_WORD,"btst.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x78,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{ABS16,0},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x13,0xff, }}},
+{137,'-','B','!','!',O_BVC|O_BYTE,"bvc.b",1,{PCREL8,0},2, {{0x28,0xff, },{0x00,0x00,PCREL8 }}},
+{134,'-','B','!','!',O_BVS|O_BYTE,"bvs.b",1,{PCREL8,0},2, {{0x29,0xff, },{0x00,0x00,PCREL8 }}},
+{136,'-','B','!','!',O_BVC|O_WORD,"bvc.w",1,{PCREL16,0},3, {{0x38,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{133,'-','B','!','!',O_BVS|O_WORD,"bvs.w",1,{PCREL16,0},3, {{0x39,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x48,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RN,0},2, {{0xa8,0xf8,RN },{0x13,0xff, }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x48,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNINC,0},2, {{0xc8,0xf8,RN },{0x13,0xff, }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x48,0xf8,RS }}},
+{130,'c','!','!','E',O_CLR|O_WORD,"clr.w",1,{RNIND,0},2, {{0xd8,0xf8,RN },{0x13,0xff, }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x48,0xf8,RS }}},
+{146,'-','B','!','!',O_BSR|O_BYTE,"bsr.b",1,{PCREL8,0},2, {{0x0e,0xff, },{0x00,0x00,PCREL8 }}},
+{149,'b','E','I','E',O_BSET|O_BYTE,"bset.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{149,'b','E','S','E',O_BSET|O_BYTE,"bset.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{148,'b','E','I','E',O_BSET|O_WORD,"bset.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xc0,0xf0,IMM4 }}},
+{148,'b','E','S','E',O_BSET|O_WORD,"bset.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x48,0xf8,RS }}},
+{145,'-','B','!','!',O_BSR|O_WORD,"bsr.w",1,{PCREL16,0},3, {{0x1e,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RN},2, {{0xa0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RN},2, {{0xa0,0xf8,RN },{0x08,0xf8,QIM }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x28,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x20,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0x50,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x58,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RN},2, {{0xa0,0xf8,RN },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RN,RD},2, {{0xa0,0xf8,RN },{0xa0,0xf8,RD }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RN},2, {{0xa8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RN},2, {{0xa8,0xf8,RN },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x58,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RN},2, {{0xa8,0xf8,RN },{0x68,0xf8,RS }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RN,RD},2, {{0xa8,0xf8,RN },{0xa0,0xf8,RD }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNDEC},2, {{0xb0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNDEC},2, {{0xb0,0xf8,RN },{0x08,0xf8,QIM }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x20,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0x50,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x58,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNDEC},2, {{0xb0,0xf8,RN },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNDEC,RD},2, {{0xb0,0xf8,RN },{0xa0,0xf8,RD }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNDEC},2, {{0xb8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNDEC},2, {{0xb8,0xf8,RN },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x58,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNDEC},2, {{0xb8,0xf8,RN },{0x68,0xf8,RS }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNDEC,RD},2, {{0xb8,0xf8,RN },{0xa0,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x20,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x50,0xf8,RD }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNINC},2, {{0xc0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0x28,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x58,0xf8,RS }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNINC},2, {{0xc0,0xf8,RN },{0x08,0xf8,QIM }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNINC},2, {{0xc0,0xf8,RN },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNINC,RD},2, {{0xc0,0xf8,RN },{0xa0,0xf8,RD }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNINC},2, {{0xc8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0xa0,0xf8,RD }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x68,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNIND},2, {{0xd0,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x28,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNINC},2, {{0xc8,0xf8,RN },{0x58,0xf8,RS }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNINC,RD},2, {{0xc8,0xf8,RN },{0x50,0xf8,RD }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNINC},2, {{0xc8,0xf8,RN },{0x08,0xf8,QIM }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNIND},2, {{0xd0,0xf8,RN },{0x08,0xf8,QIM }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x20,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0x50,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x58,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNIND},2, {{0xd0,0xf8,RN },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNIND,RD},2, {{0xd0,0xf8,RN },{0xa0,0xf8,RD }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xd0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNIND},2, {{0xd8,0xf8,RN },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNIND},2, {{0xd8,0xf8,RN },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x58,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNIND},2, {{0xd8,0xf8,RN },{0x68,0xf8,RS }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNIND,RD},2, {{0xd8,0xf8,RN },{0xa0,0xf8,RD }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xd0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xe0,0xf0,IMM4 }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x50,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x58,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNIND_D8},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNIND_D8,RD},3, {{0xe0,0xf8,RN },{0x00,0x00,DISP8 },{0xa0,0xf8,RD }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xd0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x58,0xf8,RS }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNIND_D8},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNIND_D8,RD},3, {{0xe8,0xf8,RN },{0x00,0x00,DISP8 },{0xa0,0xf8,RD }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{RNIND_D16,RD},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,RNIND_D16},4, {{0xf0,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,RNIND_D16},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{RNIND_D16,RD},4, {{0xf8,0xf8,RN },{0x00,0x00,DISP16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x20,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x50,0xf8,RD }}},
+{210,'s','I','S','S',O_ANDC|O_BYTE,"andc.b",2,{IMM8,CRB},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0x58,0xf8,CRB }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{IMM8,RD},3, {{0x04,0xff, },{0x00,0x00,IMM8 },{0xa0,0xf8,RD }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xd0,0xf0,IMM4 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xe0,0xf0,IMM4 }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x50,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x58,0xf8,RS }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,ABS8},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0x68,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{ABS8,RD},3, {{0x05,0xff, },{0x00,0x00,ABS8 },{0xa0,0xf8,RD }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{209,'s','I','S','S',O_ANDC|O_WORD,"andc.w",2,{IMM16,CRW},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0x58,0xf8,CRW }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{IMM16,RD},4, {{0x0c,0xff, },{0x00,0x00,IMM16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x20,0xf8,RD }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x28,0xf8,RD }}},
+{157,'-','!','!','!',O_BPT|O_UNSZ,"bpt",0,{0,0},1, {{0x0b,0xff, }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xd0,0xf0,IMM4 }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x58,0xf8,RS }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,ABS8},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0x68,0xf8,RS }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{ABS8,RD},3, {{0x0d,0xff, },{0x00,0x00,ABS8 },{0xa0,0xf8,RD }}},
+{204,'b','E','I','E',O_BCLR|O_BYTE,"bclr.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{225,'a','E','D','D',O_ADD|O_BYTE,"add:g.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{219,'-','E','D','D',O_ADDS|O_BYTE,"adds.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{213,'m','E','D','D',O_AND|O_BYTE,"and.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{204,'b','E','S','E',O_BCLR|O_BYTE,"bclr.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{216,'a','E','D','D',O_ADDX|O_BYTE,"addx.b",2,{ABS16,RD},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{203,'b','E','I','E',O_BCLR|O_WORD,"bclr.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xd0,0xf0,IMM4 }}},
+{218,'-','E','D','D',O_ADDS|O_WORD,"adds.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x28,0xf8,RD }}},
+{212,'m','E','D','D',O_AND|O_WORD,"and.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x50,0xf8,RD }}},
+{203,'b','E','S','E',O_BCLR|O_WORD,"bclr.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x58,0xf8,RS }}},
+{215,'a','E','D','D',O_ADDX|O_WORD,"addx.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xa0,0xf8,RD }}},
+{155,'-','B','!','!',O_BRA|O_BYTE,"bra.b",1,{PCREL8,0},2, {{0x20,0xff, },{0x00,0x00,PCREL8 }}},
+{162,'b','E','I','E',O_BNOT|O_BYTE,"bnot.b",2,{IMM4,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{222,'a','I','E','E',O_ADD|O_BYTE,"add:q.b",2,{QIM,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{162,'b','E','S','E',O_BNOT|O_BYTE,"bnot.b",2,{RS,ABS16},4, {{0x15,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{161,'b','E','I','E',O_BNOT|O_WORD,"bnot.w",2,{IMM4,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0xe0,0xf0,IMM4 }}},
+{221,'a','I','E','E',O_ADD|O_WORD,"add:q.w",2,{QIM,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x08,0xf8,QIM }}},
+{224,'a','E','D','D',O_ADD|O_WORD,"add:g.w",2,{ABS16,RD},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x20,0xf8,RD }}},
+{161,'b','E','S','E',O_BNOT|O_WORD,"bnot.w",2,{RS,ABS16},4, {{0x1d,0xff, },{0x00,0x00,ABS16 },{0x00,0x00, },{0x68,0xf8,RS }}},
+{152,'-','B','!','!',O_BRN|O_BYTE,"brn.b",1,{PCREL8,0},2, {{0x21,0xff, },{0x00,0x00,PCREL8 }}},
+{186,'-','B','!','!',O_BHI|O_BYTE,"bhi.b",1,{PCREL8,0},2, {{0x22,0xff, },{0x00,0x00,PCREL8 }}},
+{174,'-','B','!','!',O_BLS|O_BYTE,"bls.b",1,{PCREL8,0},2, {{0x23,0xff, },{0x00,0x00,PCREL8 }}},
+{207,'-','B','!','!',O_BCC|O_BYTE,"bcc.b",1,{PCREL8,0},2, {{0x24,0xff, },{0x00,0x00,PCREL8 }}},
+{201,'-','B','!','!',O_BCS|O_BYTE,"bcs.b",1,{PCREL8,0},2, {{0x25,0xff, },{0x00,0x00,PCREL8 }}},
+{165,'-','B','!','!',O_BNE|O_BYTE,"bne.b",1,{PCREL8,0},2, {{0x26,0xff, },{0x00,0x00,PCREL8 }}},
+{198,'-','B','!','!',O_BEQ|O_BYTE,"beq.b",1,{PCREL8,0},2, {{0x27,0xff, },{0x00,0x00,PCREL8 }}},
+{159,'-','B','!','!',O_BPL|O_BYTE,"bpl.b",1,{PCREL8,0},2, {{0x2a,0xff, },{0x00,0x00,PCREL8 }}},
+{168,'-','B','!','!',O_BMI|O_BYTE,"bmi.b",1,{PCREL8,0},2, {{0x2b,0xff, },{0x00,0x00,PCREL8 }}},
+{192,'-','B','!','!',O_BGE|O_BYTE,"bge.b",1,{PCREL8,0},2, {{0x2c,0xff, },{0x00,0x00,PCREL8 }}},
+{171,'-','B','!','!',O_BLT|O_BYTE,"blt.b",1,{PCREL8,0},2, {{0x2d,0xff, },{0x00,0x00,PCREL8 }}},
+{189,'-','B','!','!',O_BGT|O_BYTE,"bgt.b",1,{PCREL8,0},2, {{0x2e,0xff, },{0x00,0x00,PCREL8 }}},
+{180,'-','B','!','!',O_BLE|O_BYTE,"ble.b",1,{PCREL8,0},2, {{0x2f,0xff, },{0x00,0x00,PCREL8 }}},
+{154,'-','B','!','!',O_BRA|O_WORD,"bra.w",1,{PCREL16,0},3, {{0x30,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{151,'-','B','!','!',O_BRN|O_WORD,"brn.w",1,{PCREL16,0},3, {{0x31,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{185,'-','B','!','!',O_BHI|O_WORD,"bhi.w",1,{PCREL16,0},3, {{0x32,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{173,'-','B','!','!',O_BLS|O_WORD,"bls.w",1,{PCREL16,0},3, {{0x33,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{206,'-','B','!','!',O_BCC|O_WORD,"bcc.w",1,{PCREL16,0},3, {{0x34,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{200,'-','B','!','!',O_BCS|O_WORD,"bcs.w",1,{PCREL16,0},3, {{0x35,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{164,'-','B','!','!',O_BNE|O_WORD,"bne.w",1,{PCREL16,0},3, {{0x36,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{197,'-','B','!','!',O_BEQ|O_WORD,"beq.w",1,{PCREL16,0},3, {{0x37,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{158,'-','B','!','!',O_BPL|O_WORD,"bpl.w",1,{PCREL16,0},3, {{0x3a,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{167,'-','B','!','!',O_BMI|O_WORD,"bmi.w",1,{PCREL16,0},3, {{0x3b,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{191,'-','B','!','!',O_BGE|O_WORD,"bge.w",1,{PCREL16,0},3, {{0x3c,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{170,'-','B','!','!',O_BLT|O_WORD,"blt.w",1,{PCREL16,0},3, {{0x3d,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{188,'-','B','!','!',O_BGT|O_WORD,"bgt.w",1,{PCREL16,0},3, {{0x3e,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+{179,'-','B','!','!',O_BLE|O_WORD,"ble.w",1,{PCREL16,0},3, {{0x3f,0xff, },{0x00,0x00,PCREL16 },{0x00,0x00, }}},
+/*
+RN,RD 'm','E','D','D'
+CRB,RN 's','C','!','E'
+RN,RD 'm','E','D','D'
+RNDEC,RD 'm','E','D','D'
+CRB,RNDEC 's','C','!','E'
+RNDEC,RD 'm','E','D','D'
+RNINC,RD 'm','E','D','D'
+CRB,RNINC 's','C','!','E'
+RNINC,RD 'm','E','D','D'
+RNIND,RD 'm','E','D','D'
+CRB,RNIND 's','C','!','E'
+RNIND,RD 'm','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+RNIND_D8,RD 'm','E','D','D'
+CRB,RNIND_D8 's','C','!','E'
+RNIND_D8,RD 'm','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+CRB,RNIND_D16 's','C','!','E'
+RNIND_D16,RD 'm','E','D','D'
+RN,RD 'm','E','D','D'
+RNDEC,RD 'm','E','D','D'
+RNIND,RD 'm','E','D','D'
+RNINC,RD 'm','E','D','D'
+RNIND_D8,RD 'm','E','D','D'
+ABS8,RD 'm','E','D','D'
+IMM16,RD 'm','E','D','D'
+ABS16,RD 'm','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+RN,RD 'a','E','D','D'
+RS,RD '-','X','!','!'
+RN,0 'a','E','!','!'
+RS,RD '-','X','!','!'
+RN,0 'a','E','!','!'
+RNDEC,RD 'a','E','D','D'
+RNDEC,0 'a','E','!','!'
+RNDEC,RD 'a','E','D','D'
+RNDEC,0 'a','E','!','!'
+RNINC,RD 'a','E','D','D'
+RNINC,0 'a','E','!','!'
+RNINC,0 'a','E','!','!'
+RNIND,RD 'a','E','D','D'
+RNIND,0 'a','E','!','!'
+RNIND,RD 'a','E','D','D'
+RNIND,0 'a','E','!','!'
+RNIND_D8,0 'a','E','!','!'
+RNIND_D8,RD 'a','E','D','D'
+RNIND_D8,0 'a','E','!','!'
+RNIND_D16,0 'a','E','!','!'
+RNIND_D16,RD 'a','E','D','D'
+RN,0 'a','E','!','!'
+RNIND,0 'a','E','!','!'
+RNDEC,0 'a','E','!','!'
+RNINC,0 'a','E','!','!'
+ABS8,0 'a','E','!','!'
+RNIND_D8,0 'a','E','!','!'
+RD,0 'm','D','!','D'
+ABS16,0 'a','E','!','!'
+RNIND_D16,0 'a','E','!','!'
+RN,0 's','E','!','E'
+RN,RD 'a','E','D','D'
+RN,RD 'a','E','D','D'
+RNDEC,0 's','E','!','E'
+RNDEC,RD 'a','E','D','D'
+RNINC,0 's','E','!','E'
+RNINC,RD 'a','E','D','D'
+RNIND,RD '-','E','D','D'
+RNIND,0 's','E','!','E'
+RNIND,RD 'a','E','D','D'
+RNIND_D8,0 's','E','!','E'
+RN,0 's','E','!','E'
+RNIND,0 's','E','!','E'
+RNINC,0 's','E','!','E'
+RNDEC,0 's','E','!','E'
+IMM8,0 's','E','!','E'
+ABS8,0 's','E','!','E'
+RNIND_D8,0 's','E','!','E'
+ABS16,0 's','E','!','E'
+RNIND_D16,0 's','E','!','E'
+RNIND_D8,RD '-','E','D','D'
+RD,0 'm','D','!','D'
+RNIND_D16,RD '-','E','D','D'
+RNIND_D16,0 's','E','!','E'
+IMM16,0 'a','E','!','!'
+RN,RD '-','E','D','D'
+RN,RD 'a','E','D','D'
+RN,RD '-','E','D','D'
+RNDEC,RD '-','E','D','D'
+RNDEC,RD 'a','E','D','D'
+RNDEC,RD '-','E','D','D'
+RNINC,RD '-','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNINC,RD '-','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNIND,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+RNIND_D8,RD '-','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RNIND_D16,RD '-','E','D','D'
+RN,RD 'a','E','D','D'
+RNDEC,RD 'a','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNIND,RD 'a','E','D','D'
+ABS8,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+IMM16,RD 'a','E','D','D'
+ABS16,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RNIND,RD '-','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RNIND_D16,0 'a','E','!','!'
+IMM8,RD 'a','E','D','D'
+IMM8,RD '-','E','D','D'
+IMM8,RD 'm','E','D','D'
+IMM8,CRB 's','E','C','C'
+IMM8,RD 'a','E','D','D'
+IMM8,0 'a','E','!','!'
+IMM8,0 's','E','!','E'
+ABS8,RD 'a','E','D','D'
+ABS8,RD '-','E','D','D'
+ABS8,RD 'm','E','D','D'
+CRB,ABS8 's','C','!','E'
+ABS8,RD 'a','E','D','D'
+ABS8,0 'a','E','!','!'
+ABS8,0 's','E','!','E'
+RN,RD '-','E','D','D'
+RNDEC,RD '-','E','D','D'
+RNIND,RD '-','E','D','D'
+RNINC,RD '-','E','D','D'
+ABS8,RD '-','E','D','D'
+RNIND_D8,RD '-','E','D','D'
+ABS16,RD '-','E','D','D'
+IMM16,RD '-','E','D','D'
+RNIND_D16,RD '-','E','D','D'
+IMM4,0 '-','I','!','!'
+0,0 '-','B','!','!'
+IMM16,RD 'a','E','D','D'
+IMM16,RD '-','E','D','D'
+IMM16,RD 'm','E','D','D'
+IMM16,CRW 's','E','C','C'
+IMM16,RD 'a','E','D','D'
+IMM16,0 'a','E','!','!'
+ABS8,RD 'a','E','D','D'
+ABS8,RD '-','E','D','D'
+ABS8,RD 'm','E','D','D'
+ABS8,RD 'a','E','D','D'
+ABS8,0 'a','E','!','!'
+FP,0 '-','B','!','!'
+ABS16,RD 'a','E','D','D'
+ABS16,RD '-','E','D','D'
+ABS16,RD 'm','E','D','D'
+CRB,ABS16 's','C','!','E'
+RN,RD 'a','E','D','D'
+RNIND,RD 'a','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNDEC,RD 'a','E','D','D'
+ABS8,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+IMM16,RD 'a','E','D','D'
+ABS16,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RLIST,SPDEC '-','I','!','E'
+CRW,RN 's','C','!','E'
+CRW,RNDEC 's','C','!','E'
+CRW,RNINC 's','C','!','E'
+CRW,RNIND 's','C','!','E'
+CRW,ABS8 's','C','!','E'
+CRW,RNIND_D8 's','C','!','E'
+CRW,ABS16 's','C','!','E'
+CRW,RNIND_D16 's','C','!','E'
+ABS16,RD 'a','E','D','D'
+ABS16,0 'a','E','!','!'
+ABS16,0 's','E','!','E'
+ABS16,RD 'a','E','D','D'
+ABS16,RD '-','E','D','D'
+ABS16,RD 'm','E','D','D'
+ABS16,RD 'a','E','D','D'
+ABS16,0 'a','E','!','!'
+CRW,RN 's','C','!','E'
+RNIND,0 'h','E','!','E'
+CRB,RNDEC 's','C','!','E'
+CRW,RNIND 's','C','!','E'
+CRW,RNINC 's','C','!','E'
+CRW,RNDEC 's','C','!','E'
+CRB,RNIND 's','C','!','E'
+CRB,RNINC 's','C','!','E'
+CRW,RNIND_D8 's','C','!','E'
+CRB,ABS8 's','C','!','E'
+CRB,RNIND_D8 's','C','!','E'
+CRW,ABS8 's','C','!','E'
+CRW,RNIND_D16 's','C','!','E'
+RNIND,0 'h','E','!','E'
+CRB,ABS16 's','C','!','E'
+CRB,RNIND_D16 's','C','!','E'
+RN,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+CRW,ABS16 's','C','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+CRB,RN 's','C','!','E'
+RN,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+IMM8,0 'h','E','!','E'
+IMM8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+IMM8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+0,0 '-','!','!','!'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+IMM8,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RS,PCREL8 '-','B','S','S'
+IMM8,0 'h','E','!','E'
+IMM8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RS,PCREL8 '-','B','S','S'
+RS,PCREL8 '-','B','S','S'
+IMM16,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+IMM16,0 '-','B','!','!'
+IMM8,0 '-','B','!','!'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+0,0 '-','B','!','!'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+IMM8,RD 'm','I','!','D'
+ABS16,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+FPIND_D8,RD 'm','E','!','D'
+FPIND_D8,RD 'm','E','!','D'
+RS,FPIND_D8 'm','S','!','E'
+RS,FPIND_D8 'm','S','!','E'
+RN,RD 'm','E','!','D'
+RN,0 'h','E','!','E'
+RS,RNDEC 'm','S','!','E'
+RNIND_D8,0 'h','E','!','E'
+IMM16,RD 'm','I','!','D'
+ABS8,RD 'm','E','!','D'
+ABS8,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+RS,ABS8 'm','S','!','E'
+RN,RD '-','E','!','D'
+RN,0 'h','E','!','E'
+RN,RD 'm','E','!','D'
+RNDEC,RD 'm','E','!','D'
+RNDEC,RD '-','E','!','D'
+RN,0 'h','E','!','E'
+RNDEC,RD 'p','E','D','D'
+RNIND,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RS,RN '-','S','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RN,RD 'm','E','D','D'
+RN,RD 'p','E','D','D'
+RN,0 'a','E','!','E'
+RN,0 'm','E','!','E'
+RN,0 'h','E','!','E'
+RN,RD 'm','E','D','D'
+RN,RD 'p','E','D','D'
+RN,0 'a','E','!','E'
+RN,0 'm','E','!','E'
+RNDEC,RD 'm','E','D','D'
+RS,RNDEC '-','S','!','E'
+RNDEC,0 'h','E','!','E'
+RNDEC,0 'a','E','!','E'
+RNINC,RD 'm','E','D','D'
+RNINC,0 'h','E','!','E'
+RN,0 'h','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNIND,0 'h','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS16,0 'h','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+RNDEC,0 'a','E','!','E'
+RNDEC,0 'm','E','!','E'
+RNDEC,RD 'm','E','D','D'
+RNDEC,0 'm','E','!','E'
+RNDEC,0 'h','E','!','E'
+RNINC,0 'a','E','!','E'
+RNINC,0 'm','E','!','E'
+RNINC,RD 'm','E','D','D'
+RNINC,0 'a','E','!','E'
+IMM8,CRB 's','I','C','C'
+IMM16,CRW 's','I','C','C'
+RNINC,0 'm','E','!','E'
+RNINC,0 'h','E','!','E'
+RNIND,RD 'm','E','D','D'
+RNIND,0 'a','E','!','E'
+RNIND,0 'm','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND,RD 'm','E','D','D'
+RNIND,0 'a','E','!','E'
+RNIND,0 'm','E','!','E'
+RNIND,0 'h','E','!','E'
+RNIND_D8,RD 'm','E','D','D'
+RNIND_D8,0 'a','E','!','E'
+RNIND_D8,0 'm','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D8,RD 'm','E','D','D'
+RNIND_D8,0 'a','E','!','E'
+RNIND_D8,0 'm','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D16,RD 'm','E','D','D'
+RNIND,RD 'm','E','D','D'
+RNDEC,RD 'm','E','D','D'
+RNINC,RD 'm','E','D','D'
+ABS8,RD 'm','E','D','D'
+RNIND_D8,RD 'm','E','D','D'
+ABS16,RD 'm','E','D','D'
+IMM16,RD 'm','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+RNIND_D16,0 'a','E','!','E'
+RNIND_D16,0 'm','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+ABS24,0 '-','J','!','!'
+IMM8,RD 'm','E','D','D'
+IMM8,CRB 's','I','C','C'
+IMM8,0 'a','E','!','E'
+IMM8,0 'h','E','!','E'
+ABS8,RD 'm','E','D','D'
+RN,RD 'm','E','D','D'
+RNIND_D16,RD 'm','E','!','D'
+RNIND_D16,0 'a','E','!','E'
+RNIND_D16,0 'm','E','!','E'
+RNIND_D16,0 'h','E','!','E'
+IMM8,0 'm','E','!','E'
+ABS8,0 'a','E','!','E'
+ABS8,0 'm','E','!','E'
+RN,0 'm','E','!','E'
+RNIND,0 'm','E','!','E'
+RNDEC,0 'm','E','!','E'
+RNINC,0 'm','E','!','E'
+ABS8,0 'm','E','!','E'
+RNIND_D8,0 'm','E','!','E'
+ABS16,0 'm','E','!','E'
+IMM16,0 'm','E','!','E'
+RNIND_D16,0 'm','E','!','E'
+IMM8,RNIND_D16 'm','I','!','E'
+0,0 '-','!','!','!'
+ABS8,0 'h','E','!','E'
+IMM16,RD 'm','E','D','D'
+IMM16,CRW 's','I','C','C'
+IMM16,0 'a','E','!','E'
+IMM16,0 'm','E','!','E'
+IMM16,0 'h','E','!','E'
+ABS8,RD 'm','E','D','D'
+ABS8,0 'a','E','!','E'
+ABS8,0 'm','E','!','E'
+ABS8,0 'h','E','!','E'
+RDIND,0 '-','J','!','!'
+RDIND,0 '-','J','!','!'
+IMM8,0 '-','B','!','!'
+0,0 '-','B','!','!'
+IMM16,0 '-','B','!','!'
+ABS24,0 '-','J','!','!'
+ABS16,RD 'm','E','D','D'
+RN,0 'a','E','!','E'
+RNDEC,0 'a','E','!','E'
+RNINC,0 'a','E','!','E'
+RNIND,0 'a','E','!','E'
+ABS8,0 'a','E','!','E'
+RNIND_D8,0 'a','E','!','E'
+ABS16,0 'a','E','!','E'
+IMM16,0 'a','E','!','E'
+RNIND_D16,0 'a','E','!','E'
+RNDEC,RD 'p','E','D','D'
+RNDEC,0 'h','E','!','E'
+RNINC,RD 'p','E','D','D'
+RNINC,RD 'p','E','D','D'
+RNIND,RD 'p','E','D','D'
+RNIND,RD 'p','E','D','D'
+RNIND_D8,RD 'p','E','D','D'
+RNIND_D8,RD 'p','E','D','D'
+RNIND_D8,0 'h','E','!','E'
+RNIND_D16,RD 'p','E','D','D'
+RNIND_D16,RD 'p','E','D','D'
+IMM8,RD 'p','E','D','D'
+ABS8,RD 'p','E','D','D'
+IMM16,RD 'p','E','D','D'
+ABS8,RD 'p','E','D','D'
+ABS8,0 'h','E','!','E'
+RS,ABS16 'm','S','!','E'
+ABS16,RD 'p','E','D','D'
+RN,RD 'p','E','D','D'
+RNIND,RD 'p','E','D','D'
+RNDEC,RD 'p','E','D','D'
+RNINC,RD 'p','E','D','D'
+RNIND_D8,RD 'p','E','D','D'
+ABS8,RD 'p','E','D','D'
+IMM16,RD 'p','E','D','D'
+ABS16,RD 'p','E','D','D'
+RNIND_D16,RD 'p','E','D','D'
+RS,RNINC '-','S','!','E'
+RNINC,0 'h','E','!','E'
+RS,RNIND '-','S','!','E'
+RNIND,0 'h','E','!','E'
+RS,RNIND_D8 '-','S','!','E'
+RS,RNIND_D16 'm','S','!','E'
+RS,RNIND_D16 '-','S','!','E'
+RS,ABS8 '-','S','!','E'
+RS,RN '-','S','!','E'
+RS,RNDEC '-','S','!','E'
+RS,RNIND '-','S','!','E'
+RS,RNINC '-','S','!','E'
+RS,ABS8 '-','S','!','E'
+RNIND,RD '-','E','!','D'
+RS,ABS16 '-','S','!','E'
+RS,RNIND_D16 '-','S','!','E'
+RNINC,RD '-','E','!','D'
+RNIND_D16,0 'h','E','!','E'
+ABS16,RD 'm','E','!','D'
+RS,RNIND_D8 '-','S','!','E'
+RNIND_D8,RD '-','E','!','D'
+IMM8,RNIND_D8 'm','I','!','E'
+RNIND_D16,RD '-','E','!','D'
+IMM8,RD '-','E','!','D'
+ABS8,RD '-','E','!','D'
+RN,RD '-','E','!','D'
+RNINC,0 'h','E','!','E'
+RNIND,RD '-','E','!','D'
+RNDEC,RD '-','E','!','D'
+IMM8,RD '-','E','!','D'
+ABS8,RD '-','E','!','D'
+RNIND_D8,RD '-','E','!','D'
+ABS16,RD '-','E','!','D'
+RNIND_D16,RD '-','E','!','D'
+RNIND,0 'h','E','!','E'
+RNIND_D8,0 'h','E','!','E'
+RS,ABS8 'm','S','!','E'
+RNDEC,RD 'm','E','!','D'
+RNINC,RD 'm','E','!','D'
+ABS8,RD 'm','E','!','D'
+RNDEC,0 'h','E','!','E'
+IMM16,RD 'm','I','!','D'
+RS,RNDEC 'm','S','!','E'
+RS,RNINC 'm','S','!','E'
+RNIND,RD 'm','E','!','D'
+RS,RNIND 'm','S','!','E'
+RNIND_D8,RD 'm','E','!','D'
+RS,RNIND_D8 'm','S','!','E'
+IMM8,0 'h','E','!','E'
+ABS8,0 'h','E','!','E'
+RS,ABS8 'm','S','!','E'
+RNINC,RD '-','E','!','D'
+IMM8,RNDEC 'm','I','!','E'
+IMM16,RNDEC 'm','I','!','E'
+RNINC,RD 'm','E','!','D'
+RS,RNINC 'm','S','!','E'
+IMM8,RNINC 'm','I','!','E'
+IMM16,RNINC 'm','I','!','E'
+RNIND,RD 'm','E','!','D'
+RS,RNIND 'm','S','!','E'
+IMM8,RNIND 'm','I','!','E'
+IMM16,RNIND 'm','I','!','E'
+RNIND_D8,RD 'm','E','!','D'
+RS,RNIND_D8 'm','S','!','E'
+IMM16,RNIND_D8 'm','I','!','E'
+IMM16,RNIND_D16 'm','I','!','E'
+RNIND_D16,RD 'm','E','!','D'
+RS,RNIND_D16 'm','S','!','E'
+RNIND_D16,0 'h','E','!','E'
+IMM8,RD 'm','E','!','D'
+ABS8,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+IMM8,ABS8 'm','I','!','E'
+IMM16,ABS8 'm','I','!','E'
+IMM16,RD 'm','E','!','D'
+IMM16,0 'h','E','!','E'
+ABS8,RD 'm','E','!','D'
+ABS16,RD '-','E','!','D'
+RS,ABS16 '-','S','!','E'
+IMM8,ABS16 'm','I','!','E'
+IMM16,ABS16 'm','I','!','E'
+ABS16,0 'a','E','!','E'
+ABS16,0 'h','E','!','E'
+ABS16,RD 'm','E','!','D'
+RS,ABS16 'm','S','!','E'
+ABS16,RD 'p','E','D','D'
+ABS16,0 'a','E','!','E'
+ABS16,0 'h','E','!','E'
+RS,RNINC 'm','S','!','E'
+RN,RD 'm','E','!','D'
+RS,RNIND 'm','S','!','E'
+RNIND,RD 'm','E','!','D'
+RS,RNDEC 'm','S','!','E'
+RNINC,RD 'm','E','!','D'
+RNDEC,RD 'm','E','!','D'
+RS,RNIND_D8 'm','S','!','E'
+RS,ABS8 'm','S','!','E'
+RNIND_D8,RD 'm','E','!','D'
+IMM8,RNIND 'm','I','!','E'
+ABS8,RD 'm','E','!','D'
+IMM8,RNDEC 'm','I','!','E'
+IMM8,RNINC 'm','I','!','E'
+IMM8,RNIND_D8 'm','I','!','E'
+IMM8,ABS8 'm','I','!','E'
+RS,RNIND_D16 'm','S','!','E'
+IMM16,RD 'm','E','!','D'
+IMM16,RNIND 'm','I','!','E'
+IMM16,RNINC 'm','I','!','E'
+IMM16,RNDEC 'm','I','!','E'
+RS,ABS16 'm','S','!','E'
+RNIND_D16,RD 'm','E','!','D'
+ABS16,RD 'm','E','!','D'
+IMM16,RNIND_D8 'm','I','!','E'
+IMM8,ABS16 'm','I','!','E'
+IMM16,ABS8 'm','I','!','E'
+IMM8,RNIND_D16 'm','I','!','E'
+IMM16,ABS16 'm','I','!','E'
+IMM16,RNIND_D16 'm','I','!','E'
+ABS16,0 'm','E','!','E'
+ABS16,RD 'm','E','D','D'
+ABS16,0 'm','E','!','E'
+ABS16,0 'h','E','!','E'
+RS,FPIND_D8 'm','S','!','E'
+FPIND_D8,RD 'm','E','!','D'
+ABS16,0 'h','E','!','E'
+IMM8,RD 'm','I','!','D'
+RS,FPIND_D8 'm','S','!','E'
+RS,ABS8 'm','S','!','E'
+ABS8,RD 'm','E','!','D'
+RS,RNIND 'm','S','!','E'
+RS,RNINC 'm','S','!','E'
+RS,RNDEC 'm','S','!','E'
+RNIND,RD 'm','E','!','D'
+FPIND_D8,RD 'm','E','!','D'
+RNINC,RD 'm','E','!','D'
+RN,RD 'm','E','!','D'
+RNDEC,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+RNIND_D8,RD 'm','E','!','D'
+RS,RNIND_D8 'm','S','!','E'
+IMM16,RD 'm','I','!','D'
+ABS8,RD 'm','E','!','D'
+IMM16,RNINC 'm','I','!','E'
+IMM16,RNDEC 'm','I','!','E'
+IMM16,RNIND 'm','I','!','E'
+RS,RNIND_D16 'm','S','!','E'
+RS,ABS16 'm','S','!','E'
+ABS16,RD 'm','E','!','D'
+IMM16,RD 'm','E','!','D'
+RNIND_D16,RD 'm','E','!','D'
+IMM16,RNIND_D8 'm','I','!','E'
+IMM16,ABS8 'm','I','!','E'
+IMM16,RNIND_D16 'm','I','!','E'
+IMM16,ABS16 'm','I','!','E'
+FPIND_D8,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+RNINC,RD 'm','E','!','D'
+RS,RNIND 'm','S','!','E'
+RS,RNINC 'm','S','!','E'
+RS,RNDEC 'm','S','!','E'
+RNDEC,RD 'm','E','!','D'
+RS,FPIND_D8 'm','S','!','E'
+RNIND,RD 'm','E','!','D'
+RN,RD 'm','E','!','D'
+ABS8,RD 'm','E','!','D'
+IMM8,RD 'm','I','!','D'
+IMM8,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+IMM8,RNIND 'm','I','!','E'
+IMM8,RNINC 'm','I','!','E'
+IMM8,RNDEC 'm','I','!','E'
+RNIND_D8,RD 'm','E','!','D'
+ABS8,RD 'm','E','!','D'
+RS,RNIND_D8 'm','S','!','E'
+IMM8,RNIND_D8 'm','I','!','E'
+ABS16,RD 'm','E','!','D'
+IMM8,ABS8 'm','I','!','E'
+RS,ABS16 'm','S','!','E'
+RS,RNIND_D16 'm','S','!','E'
+RNIND_D16,RD 'm','E','!','D'
+IMM8,ABS16 'm','I','!','E'
+IMM8,RNIND_D16 'm','I','!','E'
+ABS8,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+RNIND,RD 'm','E','!','D'
+RS,RNIND 'm','S','!','E'
+RS,RNINC 'm','S','!','E'
+RS,RNDEC 'm','S','!','E'
+RN,RD 'm','E','!','D'
+RS,FPIND_D8 'm','S','!','E'
+RNINC,RD 'm','E','!','D'
+FPIND_D8,RD 'm','E','!','D'
+IMM8,RD 'm','I','!','D'
+RNDEC,RD 'm','E','!','D'
+RS,RNIND_D8 'm','S','!','E'
+IMM8,RNIND 'm','I','!','E'
+IMM8,RNINC 'm','I','!','E'
+IMM8,RNDEC 'm','I','!','E'
+RNIND_D8,RD 'm','E','!','D'
+RS,ABS8 'm','S','!','E'
+ABS8,RD 'm','E','!','D'
+IMM16,RD 'm','I','!','D'
+IMM8,ABS8 'm','I','!','E'
+RS,RNIND_D16 'm','S','!','E'
+IMM16,RNIND 'm','I','!','E'
+IMM16,RNINC 'm','I','!','E'
+IMM16,RNDEC 'm','I','!','E'
+RS,ABS16 'm','S','!','E'
+IMM16,RD 'm','E','!','D'
+IMM8,RNIND_D8 'm','I','!','E'
+RNIND_D16,RD 'm','E','!','D'
+ABS16,RD 'm','E','!','D'
+IMM16,RNIND_D8 'm','I','!','E'
+IMM8,ABS16 'm','I','!','E'
+IMM16,ABS8 'm','I','!','E'
+IMM8,RNIND_D16 'm','I','!','E'
+IMM16,ABS16 'm','I','!','E'
+IMM16,RNIND_D16 'm','I','!','E'
+IMM8,RD 'a','D','I','!'
+RN,RD 'a','D','E','!'
+IMM8,RN 'a','E','I','!'
+RN,CRW 's','E','!','C'
+RNIND,CRW 's','E','!','C'
+RNINC,CRW 's','E','!','C'
+RNDEC,CRW 's','E','!','C'
+RN,RD 'a','D','E','!'
+RNIND_D8,CRW 's','E','!','C'
+IMM16,RN 'a','E','I','!'
+ABS16,CRW 's','E','!','C'
+RNIND_D16,CRW 's','E','!','C'
+RN,CRB 's','E','!','C'
+ABS8,CRW 's','E','!','C'
+IMM16,RD 'a','D','I','!'
+RN,RD 's','E','D','D'
+RS,RD 's','D','!','!'
+RS,RD 's','D','!','!'
+RD,0 's','D','!','D'
+RD,0 's','D','!','D'
+RN,RD 's','E','D','D'
+RNIND_D8,CRB 's','E','!','C'
+RN,CRB 's','E','!','C'
+RNINC,CRW 's','E','!','C'
+RNIND,CRB 's','E','!','C'
+RNDEC,CRW 's','E','!','C'
+RNIND,CRW 's','E','!','C'
+RNDEC,CRB 's','E','!','C'
+RNINC,CRB 's','E','!','C'
+ABS8,CRW 's','E','!','C'
+ABS8,CRB 's','E','!','C'
+IMM8,CRB 's','E','!','C'
+RNIND_D8,CRW 's','E','!','C'
+RNIND_D8,CRB 's','E','!','C'
+ABS16,CRB 's','E','!','C'
+ABS16,CRW 's','E','!','C'
+IMM16,CRW 's','E','!','C'
+RNIND_D16,CRW 's','E','!','C'
+RNIND_D16,CRB 's','E','!','C'
+RNIND_D16,CRB 's','E','!','C'
+ABS16,0 '-','B','!','!'
+RDIND,0 '-','B','!','!'
+RDIND,0 '-','B','!','!'
+RDIND_D8,0 '-','B','!','!'
+RDIND_D8,0 '-','B','!','!'
+RDIND_D16,0 '-','B','!','!'
+RDIND_D16,0 '-','B','!','!'
+ABS16,0 '-','B','!','!'
+RD,0 's','D','!','D'
+ABS16,CRB 's','E','!','C'
+RD,0 's','D','!','D'
+RN,CRW 's','E','!','C'
+RNDEC,RD 's','E','D','D'
+RNDEC,RD 's','E','D','D'
+RNINC,CRB 's','E','!','C'
+RNINC,RD 's','E','D','D'
+RNINC,RD 's','E','D','D'
+RNIND,CRB 's','E','!','C'
+RNIND,RD 's','E','D','D'
+RNIND,RD 's','E','D','D'
+RNIND_D8,RD 's','E','D','D'
+RNIND_D8,RD 's','E','D','D'
+RNIND_D16,RD 's','E','D','D'
+RNIND_D16,RD 's','E','D','D'
+IMM8,CRB 's','E','!','C'
+IMM8,RD 's','E','D','D'
+ABS8,RD 's','E','D','D'
+IMM16,RD 's','E','D','D'
+ABS16,RD 's','E','D','D'
+ABS16,RD 's','E','D','D'
+RN,RD 's','E','D','D'
+RNINC,RD 's','E','D','D'
+RNDEC,RD 's','E','D','D'
+RNIND,RD 's','E','D','D'
+ABS8,RD 's','E','D','D'
+RNIND_D8,RD 's','E','D','D'
+IMM16,RD 's','E','D','D'
+ABS16,RD 's','E','D','D'
+RNIND_D16,RD 's','E','D','D'
+ABS8,CRB 's','E','!','C'
+ABS8,RD 's','E','D','D'
+IMM16,RD 'a','D','I','!'
+RNDEC,RD 'a','D','E','!'
+RNDEC,CRB 's','E','!','C'
+IMM8,RNDEC 'a','E','I','!'
+IMM16,RNDEC 'a','E','I','!'
+RNDEC,RD 'a','D','E','!'
+RNINC,RD 'a','D','E','!'
+IMM8,RNINC 'a','E','I','!'
+IMM16,RNINC 'a','E','I','!'
+RNINC,RD 'a','D','E','!'
+RNIND,RD 'a','D','E','!'
+IMM8,RNIND 'a','E','I','!'
+IMM16,RNIND 'a','E','I','!'
+RNIND,RD 'a','D','E','!'
+RNIND_D8,RD 'a','D','E','!'
+IMM8,RNIND_D8 'a','E','I','!'
+IMM16,RNIND_D8 'a','E','I','!'
+RNIND_D8,RD 'a','D','E','!'
+RNIND_D16,RD 'a','D','E','!'
+IMM8,RNIND_D16 'a','E','I','!'
+IMM16,RNIND_D16 'a','E','I','!'
+RNIND_D16,RD 'a','D','E','!'
+SPINC,RLIST '-','E','!','C'
+IMM8,RD 'a','D','E','!'
+ABS8,RD 'a','D','E','!'
+IMM8,ABS8 'a','E','I','!'
+IMM16,ABS8 'a','E','I','!'
+IMM16,RD 'a','D','E','!'
+IMM16,CRW 's','E','!','C'
+ABS8,RD 'a','D','E','!'
+ABS16,RD 'a','D','E','!'
+IMM8,ABS16 'a','E','I','!'
+IMM16,ABS16 'a','E','I','!'
+ABS16,RD 'a','D','E','!'
+FP,IMM16 '-','S','I','!'
+RN,RD 'a','D','E','!'
+RNIND,RD 'a','D','E','!'
+RNINC,RD 'a','D','E','!'
+RNDEC,RD 'a','D','E','!'
+RNIND_D8,RD 'a','D','E','!'
+ABS8,RD 'a','D','E','!'
+IMM16,RNINC 'a','E','I','!'
+IMM16,RNIND 'a','E','I','!'
+IMM16,RN 'a','E','I','!'
+IMM16,RNDEC 'a','E','I','!'
+IMM16,RD 'a','D','E','!'
+ABS16,RD 'a','D','E','!'
+RNIND_D16,RD 'a','D','E','!'
+IMM16,RNIND_D8 'a','E','I','!'
+IMM16,ABS8 'a','E','I','!'
+IMM16,RNIND_D16 'a','E','I','!'
+IMM16,ABS16 'a','E','I','!'
+FP,IMM8 '-','S','I','!'
+IMM8,RD 'a','D','I','!'
+RN,RD 'a','D','E','!'
+RNDEC,RD 'a','D','E','!'
+RNINC,RD 'a','D','E','!'
+RNIND,RD 'a','D','E','!'
+IMM16,RD 'a','D','I','!'
+RNIND_D8,RD 'a','D','E','!'
+ABS8,RD 'a','D','E','!'
+IMM16,RNINC 'a','E','I','!'
+IMM16,RNDEC 'a','E','I','!'
+IMM16,RNIND 'a','E','I','!'
+RNIND_D16,RD 'a','D','E','!'
+ABS16,RD 'a','D','E','!'
+IMM16,RD 'a','D','E','!'
+IMM16,RN 'a','E','I','!'
+IMM16,RNIND_D8 'a','E','I','!'
+IMM16,ABS8 'a','E','I','!'
+IMM16,RNIND_D16 'a','E','I','!'
+IMM16,ABS16 'a','E','I','!'
+RN,RD 'a','D','E','!'
+RNDEC,RD 'a','D','E','!'
+RNINC,RD 'a','D','E','!'
+IMM8,RD 'a','D','I','!'
+RNIND,RD 'a','D','E','!'
+IMM8,RN 'a','E','I','!'
+IMM8,RNIND 'a','E','I','!'
+IMM8,RNINC 'a','E','I','!'
+IMM8,RNDEC 'a','E','I','!'
+ABS8,RD 'a','D','E','!'
+RNIND_D8,RD 'a','D','E','!'
+IMM8,RD 'a','D','E','!'
+IMM8,ABS8 'a','E','I','!'
+ABS16,RD 'a','D','E','!'
+IMM8,RNIND_D8 'a','E','I','!'
+RNIND_D16,RD 'a','D','E','!'
+IMM8,ABS16 'a','E','I','!'
+IMM8,RNIND_D16 'a','E','I','!'
+RN,RD 'a','D','E','!'
+IMM8,RD 'a','D','I','!'
+RNINC,RD 'a','D','E','!'
+RNIND,RD 'a','D','E','!'
+RNDEC,RD 'a','D','E','!'
+IMM16,RD 'a','D','I','!'
+RNIND_D8,RD 'a','D','E','!'
+ABS8,RD 'a','D','E','!'
+IMM16,RN 'a','E','I','!'
+IMM16,RNDEC 'a','E','I','!'
+IMM16,RNIND 'a','E','I','!'
+RNIND_D16,RD 'a','D','E','!'
+IMM16,RNINC 'a','E','I','!'
+ABS16,RD 'a','D','E','!'
+IMM16,RD 'a','D','E','!'
+IMM16,ABS8 'a','E','I','!'
+IMM16,RNIND_D8 'a','E','I','!'
+IMM16,ABS16 'a','E','I','!'
+IMM16,RNIND_D16 'a','E','I','!'
+IMM4,RN 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+RS,RN 'b','E','S','E'
+RS,RN 'b','E','S','E'
+RN,0 'c','!','!','E'
+IMM4,RN 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+RNDEC,0 'c','!','!','E'
+RNINC,0 'c','!','!','E'
+RNIND,0 'c','!','!','E'
+RS,RNIND 'b','E','S','E'
+RNIND_D8,0 'c','!','!','E'
+IMM4,RNIND_D16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+RNIND_D16,0 'c','!','!','E'
+RNIND_D16,0 'c','!','!','E'
+IMM8,0 'c','!','!','E'
+ABS8,0 'c','!','!','E'
+RN,0 'c','!','!','E'
+RNIND,0 'c','!','!','E'
+RNINC,0 'c','!','!','E'
+RNDEC,0 'c','!','!','E'
+ABS8,0 'c','!','!','E'
+RNIND_D8,0 'c','!','!','E'
+IMM16,0 'c','!','!','E'
+ABS16,0 'c','!','!','E'
+RNIND_D16,0 'c','!','!','E'
+IMM4,ABS8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RS,RN 'b','E','S','E'
+IMM4,RNDEC 'b','E','I','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RS,RNDEC 'b','E','S','E'
+IMM4,RNDEC 'b','E','I','E'
+RS,RNDEC 'b','E','S','E'
+RNDEC,0 'c','!','!','E'
+IMM4,RNINC 'b','E','I','E'
+RS,RNINC 'b','E','S','E'
+IMM4,RNINC 'b','E','I','E'
+RS,RNINC 'b','E','S','E'
+IMM4,RNIND 'b','E','I','E'
+RS,RNIND 'b','E','S','E'
+IMM4,RNIND 'b','E','I','E'
+IMM4,RNIND_D8 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,RNIND_D8 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+RNIND_D8,0 'c','!','!','E'
+IMM4,RNIND_D16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+IMM16,0 'c','!','!','E'
+IMM4,ABS8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+ABS8,0 'c','!','!','E'
+IMM4,ABS16 'b','E','I','E'
+RS,ABS16 'b','E','S','E'
+ABS16,0 'c','!','!','E'
+IMM4,ABS16 'b','E','I','E'
+RS,ABS16 'b','E','S','E'
+ABS16,0 'c','!','!','E'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RS,RN 'b','E','S','E'
+IMM4,RNDEC 'b','E','I','E'
+IMM4,RNIND 'b','E','I','E'
+RS,RNIND 'b','E','S','E'
+RS,RNINC 'b','E','S','E'
+RS,RNDEC 'b','E','S','E'
+IMM4,RN 'b','E','I','E'
+IMM4,RNINC 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,ABS8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+IMM4,RNIND_D8 'b','E','I','E'
+IMM4,ABS16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+RS,ABS16 'b','E','S','E'
+IMM4,RNDEC 'b','E','I','E'
+PCREL16,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+IMM4,RNIND_D16 'b','E','I','E'
+RS,RNDEC 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RS,RN 'b','E','S','E'
+RN,0 'c','!','!','E'
+IMM4,RNDEC 'b','E','I','E'
+RS,RNDEC 'b','E','S','E'
+IMM4,RNINC 'b','E','I','E'
+RS,RNINC 'b','E','S','E'
+IMM4,RNINC 'b','E','I','E'
+RS,RNINC 'b','E','S','E'
+RNINC,0 'c','!','!','E'
+IMM4,RNIND 'b','E','I','E'
+RS,RNIND 'b','E','S','E'
+IMM4,RNIND 'b','E','I','E'
+RS,RNIND 'b','E','S','E'
+RNIND,0 'c','!','!','E'
+IMM4,RNIND_D8 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,RNIND_D8 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+IMM4,ABS8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+IMM4,ABS8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+IMM4,ABS16 'b','E','I','E'
+RS,ABS16 'b','E','S','E'
+IMM4,ABS16 'b','E','I','E'
+RS,ABS16 'b','E','S','E'
+PCREL16,0 '-','B','!','!'
+RS,RN 'b','E','S','E'
+IMM4,RN 'b','E','I','E'
+IMM4,RNIND 'b','E','I','E'
+RS,RNIND 'b','E','S','E'
+RS,RNINC 'b','E','S','E'
+RS,RNDEC 'b','E','S','E'
+IMM4,RNINC 'b','E','I','E'
+IMM4,RNDEC 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,RNIND_D8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+IMM4,ABS8 'b','E','I','E'
+IMM4,ABS16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+RS,ABS16 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+QIM,RN 'a','I','E','E'
+RN,RD '-','E','D','D'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RN,RD 'a','E','D','D'
+RN,RD 'm','E','D','D'
+RS,RN 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RS,RN 'b','E','S','E'
+RN,RD 'a','E','D','D'
+IMM4,RN 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+QIM,RN 'a','I','E','E'
+RN,RD 'a','E','D','D'
+RN,RD '-','E','D','D'
+RN,RD 'm','E','D','D'
+RS,RN 'b','E','S','E'
+RS,RN 'b','E','S','E'
+RN,RD 'a','E','D','D'
+IMM4,RNDEC 'b','E','I','E'
+IMM4,RNDEC 'b','E','I','E'
+QIM,RNDEC 'a','I','E','E'
+RNDEC,RD 'a','E','D','D'
+RNDEC,RD '-','E','D','D'
+RNDEC,RD 'm','E','D','D'
+RS,RNDEC 'b','E','S','E'
+RS,RNDEC 'b','E','S','E'
+RNDEC,RD 'a','E','D','D'
+IMM4,RNDEC 'b','E','I','E'
+IMM4,RNDEC 'b','E','I','E'
+QIM,RNDEC 'a','I','E','E'
+RNDEC,RD 'a','E','D','D'
+RNDEC,RD '-','E','D','D'
+RNDEC,RD 'm','E','D','D'
+RS,RNDEC 'b','E','S','E'
+RS,RNDEC 'b','E','S','E'
+RNDEC,RD 'a','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNINC,RD 'm','E','D','D'
+IMM4,RNINC 'b','E','I','E'
+RS,RN 'b','E','S','E'
+RS,RNIND 'b','E','S','E'
+IMM4,RNIND 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+RS,RNINC 'b','E','S','E'
+RS,RNDEC 'b','E','S','E'
+IMM4,RNDEC 'b','E','I','E'
+IMM4,RNINC 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+IMM4,ABS8 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,RNIND_D8 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+IMM4,ABS16 'b','E','I','E'
+RS,ABS16 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+IMM4,RNINC 'b','E','I','E'
+IMM4,RNINC 'b','E','I','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RNINC,RD '-','E','D','D'
+RS,RNINC 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+QIM,RNINC 'a','I','E','E'
+RS,RNINC 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RNINC,RD 'a','E','D','D'
+IMM4,RNINC 'b','E','I','E'
+RNINC,RD 'a','E','D','D'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RS,RNINC 'b','E','S','E'
+IMM4,RNIND 'b','E','I','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+IMM4,RNIND 'b','E','I','E'
+PCREL8,0 '-','B','!','!'
+RNINC,RD 'a','E','D','D'
+PCREL16,0 '-','B','!','!'
+RNINC,RD '-','E','D','D'
+RS,RNINC 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RNINC,RD 'm','E','D','D'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+QIM,RNINC 'a','I','E','E'
+QIM,RNIND 'a','I','E','E'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RNIND,RD 'a','E','D','D'
+RNIND,RD '-','E','D','D'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RNIND,RD 'm','E','D','D'
+RS,RNIND 'b','E','S','E'
+RS,RNIND 'b','E','S','E'
+RNIND,RD 'a','E','D','D'
+IMM4,RNIND 'b','E','I','E'
+IMM4,RNIND 'b','E','I','E'
+QIM,RNIND 'a','I','E','E'
+RNIND,RD 'a','E','D','D'
+RNIND,RD '-','E','D','D'
+RNIND,RD 'm','E','D','D'
+RS,RNIND 'b','E','S','E'
+RS,RNIND 'b','E','S','E'
+RNIND,RD 'a','E','D','D'
+IMM4,RNIND_D8 'b','E','I','E'
+IMM4,RNIND_D8 'b','E','I','E'
+QIM,RNIND_D8 'a','I','E','E'
+RNIND_D8,RD 'a','E','D','D'
+RNIND_D8,RD '-','E','D','D'
+RNIND_D8,RD 'm','E','D','D'
+RS,RNIND_D8 'b','E','S','E'
+RS,RNIND_D8 'b','E','S','E'
+RNIND_D8,RD 'a','E','D','D'
+IMM4,RNIND_D8 'b','E','I','E'
+IMM4,RNIND_D8 'b','E','I','E'
+QIM,RNIND_D8 'a','I','E','E'
+RNIND_D8,RD 'a','E','D','D'
+RNIND_D8,RD '-','E','D','D'
+RNIND_D8,RD 'm','E','D','D'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+QIM,RNIND_D16 'a','I','E','E'
+RS,RNIND_D16 'b','E','S','E'
+RS,RN 'b','E','S','E'
+IMM4,RNDEC 'b','E','I','E'
+IMM4,RNINC 'b','E','I','E'
+RS,RNIND 'b','E','S','E'
+RS,RNINC 'b','E','S','E'
+RS,RNDEC 'b','E','S','E'
+IMM4,RNIND 'b','E','I','E'
+IMM4,RN 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+IMM4,ABS8 'b','E','I','E'
+RS,ABS8 'b','E','S','E'
+IMM4,RNIND_D8 'b','E','I','E'
+IMM4,ABS16 'b','E','I','E'
+RS,RNIND_D16 'b','E','S','E'
+RS,ABS16 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+RS,RNIND_D8 'b','E','S','E'
+RNIND_D16,RD 'a','E','D','D'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RNIND_D16,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+IMM8,CRB 's','I','S','S'
+IMM16,CRW 's','I','S','S'
+RNIND_D8,RD 'a','E','D','D'
+IMM4,RNIND_D16 'b','E','I','E'
+RNIND_D16,RD '-','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+RS,RNIND_D16 'b','E','S','E'
+IMM4,RNIND_D16 'b','E','I','E'
+IMM4,RNIND_D16 'b','E','I','E'
+QIM,RNIND_D16 'a','I','E','E'
+RNIND_D16,RD '-','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+RS,RNIND_D16 'b','E','S','E'
+RS,RNIND_D16 'b','E','S','E'
+RNIND_D16,RD 'a','E','D','D'
+IMM8,RD 'a','E','D','D'
+IMM8,RD '-','E','D','D'
+IMM8,RD 'm','E','D','D'
+IMM8,CRB 's','I','S','S'
+IMM8,RD 'a','E','D','D'
+RN,RD 'm','E','D','D'
+RNDEC,RD 'm','E','D','D'
+RNINC,RD 'm','E','D','D'
+RNIND,RD 'm','E','D','D'
+ABS8,RD 'm','E','D','D'
+RNIND_D8,RD 'm','E','D','D'
+IMM16,RD 'm','E','D','D'
+ABS16,RD 'm','E','D','D'
+RNIND_D16,RD 'm','E','D','D'
+IMM4,ABS8 'b','E','I','E'
+IMM4,ABS8 'b','E','I','E'
+QIM,ABS8 'a','I','E','E'
+ABS8,RD 'a','E','D','D'
+ABS8,RD '-','E','D','D'
+ABS8,RD 'm','E','D','D'
+RS,ABS8 'b','E','S','E'
+RS,ABS8 'b','E','S','E'
+ABS8,RD 'a','E','D','D'
+IMM16,RD 'a','E','D','D'
+IMM16,RD '-','E','D','D'
+IMM16,RD 'm','E','D','D'
+IMM16,CRW 's','I','S','S'
+IMM16,RD 'a','E','D','D'
+IMM4,ABS8 'b','E','I','E'
+QIM,ABS8 'a','I','E','E'
+ABS8,RD 'a','E','D','D'
+ABS8,RD '-','E','D','D'
+RN,RD 'a','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNIND,RD 'a','E','D','D'
+RNDEC,RD 'a','E','D','D'
+ABS8,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+ABS16,RD 'a','E','D','D'
+IMM16,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+0,0 '-','!','!','!'
+IMM4,ABS8 'b','E','I','E'
+ABS8,RD 'm','E','D','D'
+RS,ABS8 'b','E','S','E'
+RS,ABS8 'b','E','S','E'
+ABS8,RD 'a','E','D','D'
+IMM4,ABS16 'b','E','I','E'
+ABS16,RD 'a','E','D','D'
+ABS16,RD '-','E','D','D'
+ABS16,RD 'm','E','D','D'
+RS,ABS16 'b','E','S','E'
+ABS16,RD 'a','E','D','D'
+IMM4,ABS16 'b','E','I','E'
+ABS16,RD '-','E','D','D'
+ABS16,RD 'm','E','D','D'
+RS,ABS16 'b','E','S','E'
+ABS16,RD 'a','E','D','D'
+PCREL8,0 '-','B','!','!'
+RN,RD '-','E','D','D'
+RNIND,RD '-','E','D','D'
+RNINC,RD '-','E','D','D'
+RNDEC,RD '-','E','D','D'
+ABS8,RD '-','E','D','D'
+RNIND_D8,RD '-','E','D','D'
+ABS16,RD '-','E','D','D'
+IMM16,RD '-','E','D','D'
+RNIND_D16,RD '-','E','D','D'
+IMM4,ABS16 'b','E','I','E'
+QIM,ABS16 'a','I','E','E'
+RS,ABS16 'b','E','S','E'
+IMM4,ABS16 'b','E','I','E'
+QIM,ABS16 'a','I','E','E'
+ABS16,RD 'a','E','D','D'
+RS,ABS16 'b','E','S','E'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+QIM,RN 'a','I','E','E'
+QIM,RNDEC 'a','I','E','E'
+QIM,RNINC 'a','I','E','E'
+QIM,RNIND 'a','I','E','E'
+QIM,ABS8 'a','I','E','E'
+QIM,RNIND_D8 'a','I','E','E'
+QIM,ABS16 'a','I','E','E'
+QIM,RNIND_D16 'a','I','E','E'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL8,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+PCREL16,0 '-','B','!','!'
+RN,RD 'a','E','D','D'
+RNDEC,RD 'a','E','D','D'
+RNINC,RD 'a','E','D','D'
+RNIND,RD 'a','E','D','D'
+ABS8,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+ABS16,RD 'a','E','D','D'
+IMM16,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RN,RD 'a','E','D','D'
+QIM,RN 'a','I','E','E'
+QIM,RNIND 'a','I','E','E'
+RNDEC,RD 'a','E','D','D'
+QIM,RNDEC 'a','I','E','E'
+QIM,RNINC 'a','I','E','E'
+RNIND,RD 'a','E','D','D'
+RNINC,RD 'a','E','D','D'
+QIM,ABS8 'a','I','E','E'
+QIM,RNIND_D8 'a','I','E','E'
+ABS8,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+ABS16,RD 'a','E','D','D'
+QIM,RNIND_D16 'a','I','E','E'
+IMM16,RD 'a','E','D','D'
+QIM,ABS16 'a','I','E','E'
+RNIND_D16,RD 'a','E','D','D'
+RN,RD 'a','E','D','D'
+QIM,RN 'a','I','E','E'
+QIM,RNINC 'a','I','E','E'
+RNDEC,RD 'a','E','D','D'
+QIM,RNIND 'a','I','E','E'
+RNINC,RD 'a','E','D','D'
+QIM,RNDEC 'a','I','E','E'
+RNIND,RD 'a','E','D','D'
+QIM,RNIND_D8 'a','I','E','E'
+IMM8,RD 'a','E','D','D'
+QIM,ABS8 'a','I','E','E'
+ABS8,RD 'a','E','D','D'
+RNIND_D8,RD 'a','E','D','D'
+QIM,RNIND_D16 'a','I','E','E'
+QIM,ABS16 'a','I','E','E'
+ABS16,RD 'a','E','D','D'
+RNIND_D16,RD 'a','E','D','D'
+RN,RD 'a','E','D','D'
+QIM,RN 'a','I','E','E'
+QIM,RNDEC 'a','I','E','E'
+RNDEC,RD 'a','E','D','D'
+QIM,RNIND 'a','I','E','E'
+QIM,RNINC 'a','I','E','E'
+RNINC,RD 'a','E','D','D'
+RNIND,RD 'a','E','D','D'
+QIM,ABS8 'a','I','E','E'
+QIM,RNIND_D8 'a','I','E','E'
+RNIND_D8,RD 'a','E','D','D'
+ABS8,RD 'a','E','D','D'
+ABS16,RD 'a','E','D','D'
+QIM,RNIND_D16 'a','I','E','E'
+IMM16,RD 'a','E','D','D'
+QIM,ABS16 'a','I','E','E'
+RNIND_D16,RD 'a','E','D','D'
+*/
+{0,0,0}}
+#endif
+;
+#endif
diff --git a/opcodes/hppa-dis.c b/opcodes/hppa-dis.c
new file mode 100644
index 00000000000..dc45d5ee4ba
--- /dev/null
+++ b/opcodes/hppa-dis.c
@@ -0,0 +1,631 @@
+/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
+ Copyright 1989, 1990, 1992, 1993 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ University of Utah (pa-gdb-bugs@cs.utah.edu).
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ansidecl.h>
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "libhppa.h"
+#include "opcode/hppa.h"
+
+/* Integer register names, indexed by the numbers which appear in the
+ opcodes. */
+static const char *const reg_names[] =
+ {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
+ "sp", "r31"};
+
+/* Floating point register names, indexed by the numbers which appear in the
+ opcodes. */
+static const char *const fp_reg_names[] =
+ {"fpsr", "fpe2", "fpe4", "fpe6",
+ "fr4", "fr5", "fr6", "fr7", "fr8",
+ "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
+ "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
+ "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"};
+
+typedef unsigned int CORE_ADDR;
+
+/* Get at various relevent fields of an instruction word. */
+
+#define MASK_5 0x1f
+#define MASK_11 0x7ff
+#define MASK_14 0x3fff
+#define MASK_21 0x1fffff
+
+/* This macro gets bit fields using HP's numbering (MSB = 0) */
+
+#define GET_FIELD(X, FROM, TO) \
+ ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
+
+/* Some of these have been converted to 2-d arrays because they
+ consume less storage this way. If the maintenance becomes a
+ problem, convert them back to const 1-d pointer arrays. */
+static const char control_reg[][6] = {
+ "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+ "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
+ "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
+ "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
+ "tr4", "tr5", "tr6", "tr7"
+};
+
+static const char compare_cond_names[][5] = {
+ "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv",
+ ",od", ",tr", ",<>", ",>=", ",>", ",>>=",
+ ",>>", ",nsv", ",ev"
+};
+static const char add_cond_names[][5] = {
+ "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv",
+ ",od", ",tr", ",<>", ",>=", ",>", ",uv",
+ ",vnz", ",nsv", ",ev"
+};
+static const char *const logical_cond_names[] = {
+ "", ",=", ",<", ",<=", 0, 0, 0, ",od",
+ ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
+static const char *const unit_cond_names[] = {
+ "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
+ ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
+};
+static const char shift_cond_names[][4] = {
+ "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
+};
+static const char index_compl_names[][4] = {"", ",m", ",s", ",sm"};
+static const char short_ldst_compl_names[][4] = {"", ",ma", "", ",mb"};
+static const char *const short_bytes_compl_names[] = {
+ "", ",b,m", ",e", ",e,m"
+};
+static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
+static const char float_comp_names[][8] =
+{
+ ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
+ ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
+ ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
+ ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
+};
+
+/* For a bunch of different instructions form an index into a
+ completer name table. */
+#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
+ GET_FIELD (insn, 18, 18) << 1)
+
+#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
+ (GET_FIELD ((insn), 19, 19) ? 8 : 0))
+
+/* Utility function to print registers. Put these first, so gcc's function
+ inlining can do its stuff. */
+
+#define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
+
+static void
+fput_reg (reg, info)
+ unsigned reg;
+ disassemble_info *info;
+{
+ (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
+}
+
+static void
+fput_fp_reg (reg, info)
+ unsigned reg;
+ disassemble_info *info;
+{
+ (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
+}
+
+static void
+fput_fp_reg_r (reg, info)
+ unsigned reg;
+ disassemble_info *info;
+{
+ /* Special case floating point exception registers. */
+ if (reg < 4)
+ (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
+ else
+ (*info->fprintf_func) (info->stream, "%sR", reg ? fp_reg_names[reg]
+ : "fr0");
+}
+
+static void
+fput_creg (reg, info)
+ unsigned reg;
+ disassemble_info *info;
+{
+ (*info->fprintf_func) (info->stream, control_reg[reg]);
+}
+
+/* print constants with sign */
+
+static void
+fput_const (num, info)
+ unsigned num;
+ disassemble_info *info;
+{
+ if ((int)num < 0)
+ (*info->fprintf_func) (info->stream, "-%x", -(int)num);
+ else
+ (*info->fprintf_func) (info->stream, "%x", num);
+}
+
+/* Routines to extract various sized constants out of hppa
+ instructions. */
+
+/* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
+static int
+extract_3 (word)
+ unsigned word;
+{
+ return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
+}
+
+static int
+extract_5_load (word)
+ unsigned word;
+{
+ return low_sign_extend (word >> 16 & MASK_5, 5);
+}
+
+/* extract the immediate field from a st{bhw}s instruction */
+static int
+extract_5_store (word)
+ unsigned word;
+{
+ return low_sign_extend (word & MASK_5, 5);
+}
+
+/* extract the immediate field from a break instruction */
+static unsigned
+extract_5r_store (word)
+ unsigned word;
+{
+ return (word & MASK_5);
+}
+
+/* extract the immediate field from a {sr}sm instruction */
+static unsigned
+extract_5R_store (word)
+ unsigned word;
+{
+ return (word >> 16 & MASK_5);
+}
+
+/* extract the immediate field from a bb instruction */
+static unsigned
+extract_5Q_store (word)
+ unsigned word;
+{
+ return (word >> 21 & MASK_5);
+}
+
+/* extract an 11 bit immediate field */
+static int
+extract_11 (word)
+ unsigned word;
+{
+ return low_sign_extend (word & MASK_11, 11);
+}
+
+/* extract a 14 bit immediate field */
+static int
+extract_14 (word)
+ unsigned word;
+{
+ return low_sign_extend (word & MASK_14, 14);
+}
+
+/* extract a 21 bit constant */
+
+static int
+extract_21 (word)
+ unsigned word;
+{
+ int val;
+
+ word &= MASK_21;
+ word <<= 11;
+ val = GET_FIELD (word, 20, 20);
+ val <<= 11;
+ val |= GET_FIELD (word, 9, 19);
+ val <<= 2;
+ val |= GET_FIELD (word, 5, 6);
+ val <<= 5;
+ val |= GET_FIELD (word, 0, 4);
+ val <<= 2;
+ val |= GET_FIELD (word, 7, 8);
+ return sign_extend (val, 21) << 11;
+}
+
+/* extract a 12 bit constant from branch instructions */
+
+static int
+extract_12 (word)
+ unsigned word;
+{
+ return sign_extend (GET_FIELD (word, 19, 28) |
+ GET_FIELD (word, 29, 29) << 10 |
+ (word & 0x1) << 11, 12) << 2;
+}
+
+/* extract a 17 bit constant from branch instructions, returning the
+ 19 bit signed value. */
+
+static int
+extract_17 (word)
+ unsigned word;
+{
+ return sign_extend (GET_FIELD (word, 19, 28) |
+ GET_FIELD (word, 29, 29) << 10 |
+ GET_FIELD (word, 11, 15) << 11 |
+ (word & 0x1) << 16, 17) << 2;
+}
+
+/* Print one instruction. */
+int
+print_insn_hppa (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info *info;
+{
+ bfd_byte buffer[4];
+ unsigned int insn, i;
+
+ {
+ int status =
+ (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ }
+
+ insn = bfd_getb32 (buffer);
+
+ for (i = 0; i < NUMOPCODES; ++i)
+ {
+ const struct pa_opcode *opcode = &pa_opcodes[i];
+ if ((insn & opcode->mask) == opcode->match)
+ {
+ register const char *s;
+
+ (*info->fprintf_func) (info->stream, "%s", opcode->name);
+
+ if (!strchr ("cfCY<?!@-+&U>~nHNZFIMadu|", opcode->args[0]))
+ (*info->fprintf_func) (info->stream, " ");
+ for (s = opcode->args; *s != '\0'; ++s)
+ {
+ switch (*s)
+ {
+ case 'x':
+ fput_reg (GET_FIELD (insn, 11, 15), info);
+ break;
+ case 'X':
+ if (GET_FIELD (insn, 25, 25))
+ fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
+ else
+ fput_fp_reg (GET_FIELD (insn, 11, 15), info);
+ break;
+ case 'b':
+ fput_reg (GET_FIELD (insn, 6, 10), info);
+ break;
+ case '^':
+ fput_creg (GET_FIELD (insn, 6, 10), info);
+ break;
+ case 'E':
+ if (GET_FIELD (insn, 25, 25))
+ fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
+ else
+ fput_fp_reg (GET_FIELD (insn, 6, 10), info);
+ break;
+ case 't':
+ fput_reg (GET_FIELD (insn, 27, 31), info);
+ break;
+ case 'v':
+ if (GET_FIELD (insn, 25, 25))
+ fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
+ else
+ fput_fp_reg (GET_FIELD (insn, 27, 31), info);
+ break;
+ case 'y':
+ fput_fp_reg (GET_FIELD (insn, 27, 31), info);
+ break;
+ case '4':
+ {
+ int reg = GET_FIELD (insn, 6, 10);
+
+ reg |= (GET_FIELD (insn, 26, 26) << 4);
+ fput_fp_reg (reg, info);
+ break;
+ }
+ case '6':
+ {
+ int reg = GET_FIELD (insn, 11, 15);
+
+ reg |= (GET_FIELD (insn, 26, 26) << 4);
+ fput_fp_reg (reg, info);
+ break;
+ }
+ case '7':
+ {
+ int reg = GET_FIELD (insn, 27, 31);
+
+ reg |= (GET_FIELD (insn, 26, 26) << 4);
+ fput_fp_reg (reg, info);
+ break;
+ }
+ case '8':
+ {
+ int reg = GET_FIELD (insn, 16, 20);
+
+ reg |= (GET_FIELD (insn, 26, 26) << 4);
+ fput_fp_reg (reg, info);
+ break;
+ }
+ case '9':
+ {
+ int reg = GET_FIELD (insn, 21, 25);
+
+ reg |= (GET_FIELD (insn, 26, 26) << 4);
+ fput_fp_reg (reg, info);
+ break;
+ }
+ case '5':
+ fput_const (extract_5_load (insn), info);
+ break;
+ case 's':
+ (*info->fprintf_func) (info->stream,
+ "sr%d", GET_FIELD (insn, 16, 17));
+ break;
+ case 'S':
+ (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn));
+ break;
+ case 'c':
+ (*info->fprintf_func) (info->stream, "%s ",
+ index_compl_names[GET_COMPL (insn)]);
+ break;
+ case 'C':
+ (*info->fprintf_func) (info->stream, "%s ",
+ short_ldst_compl_names[GET_COMPL (insn)]);
+ break;
+ case 'Y':
+ (*info->fprintf_func) (info->stream, "%s ",
+ short_bytes_compl_names[GET_COMPL (insn)]);
+ break;
+ /* these four conditions are for the set of instructions
+ which distinguish true/false conditions by opcode rather
+ than by the 'f' bit (sigh): comb, comib, addb, addib */
+ case '<':
+ fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
+ info);
+ break;
+ case '?':
+ fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
+ + GET_FIELD (insn, 4, 4) * 8], info);
+ break;
+ case '@':
+ fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
+ + GET_FIELD (insn, 4, 4) * 8], info);
+ break;
+ case 'a':
+ (*info->fprintf_func) (info->stream, "%s ",
+ compare_cond_names[GET_COND (insn)]);
+ break;
+ case 'd':
+ (*info->fprintf_func) (info->stream, "%s ",
+ add_cond_names[GET_COND (insn)]);
+ break;
+ case '!':
+ (*info->fprintf_func) (info->stream, "%s",
+ add_cond_names[GET_FIELD (insn, 16, 18)]);
+ break;
+
+ case '&':
+ (*info->fprintf_func) (info->stream, "%s ",
+ logical_cond_names[GET_COND (insn)]);
+ break;
+ case 'U':
+ (*info->fprintf_func) (info->stream, "%s ",
+ unit_cond_names[GET_COND (insn)]);
+ break;
+ case '|':
+ case '>':
+ case '~':
+ (*info->fprintf_func)
+ (info->stream, "%s",
+ shift_cond_names[GET_FIELD (insn, 16, 18)]);
+
+ /* If the next character in args is 'n', it will handle
+ putting out the space. */
+ if (s[1] != 'n')
+ (*info->fprintf_func) (info->stream, " ");
+ break;
+ case 'V':
+ fput_const (extract_5_store (insn), info);
+ break;
+ case 'r':
+ fput_const (extract_5r_store (insn), info);
+ break;
+ case 'R':
+ fput_const (extract_5R_store (insn), info);
+ break;
+ case 'Q':
+ fput_const (extract_5Q_store (insn), info);
+ break;
+ case 'i':
+ fput_const (extract_11 (insn), info);
+ break;
+ case 'j':
+ fput_const (extract_14 (insn), info);
+ break;
+ case 'k':
+ fput_const (extract_21 (insn), info);
+ break;
+ case 'n':
+ if (insn & 0x2)
+ (*info->fprintf_func) (info->stream, ",n ");
+ else
+ (*info->fprintf_func) (info->stream, " ");
+ break;
+ case 'N':
+ if ((insn & 0x20) && s[1])
+ (*info->fprintf_func) (info->stream, ",n ");
+ else if (insn & 0x20)
+ (*info->fprintf_func) (info->stream, ",n");
+ else if (s[1])
+ (*info->fprintf_func) (info->stream, " ");
+ break;
+ case 'w':
+ (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
+ info);
+ break;
+ case 'W':
+ /* 17 bit PC-relative branch. */
+ (*info->print_address_func) ((memaddr + 8
+ + extract_17 (insn)),
+ info);
+ break;
+ case 'z':
+ /* 17 bit displacement. This is an offset from a register
+ so it gets disasssembled as just a number, not any sort
+ of address. */
+ fput_const (extract_17 (insn), info);
+ break;
+ case 'p':
+ (*info->fprintf_func) (info->stream, "%d",
+ 31 - GET_FIELD (insn, 22, 26));
+ break;
+ case 'P':
+ (*info->fprintf_func) (info->stream, "%d",
+ GET_FIELD (insn, 22, 26));
+ break;
+ case 'T':
+ (*info->fprintf_func) (info->stream, "%d",
+ 32 - GET_FIELD (insn, 27, 31));
+ break;
+ case 'A':
+ fput_const (GET_FIELD (insn, 6, 18), info);
+ break;
+ case 'Z':
+ if (GET_FIELD (insn, 26, 26))
+ (*info->fprintf_func) (info->stream, ",m ");
+ else
+ (*info->fprintf_func) (info->stream, " ");
+ break;
+ case 'D':
+ fput_const (GET_FIELD (insn, 6, 31), info);
+ break;
+ case 'f':
+ (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
+ break;
+ case 'O':
+ fput_const ((GET_FIELD (insn, 6,20) << 5 |
+ GET_FIELD (insn, 27, 31)), info);
+ break;
+ case 'o':
+ fput_const (GET_FIELD (insn, 6, 20), info);
+ break;
+ case '3':
+ {
+ int reg = GET_FIELD (insn, 21, 22);
+ reg |= GET_FIELD (insn, 16, 18) << 2;
+ if (GET_FIELD (insn, 23, 23) != 0)
+ fput_fp_reg_r (reg, info);
+ else
+ fput_fp_reg (reg, info);
+ break;
+ }
+
+ case '2':
+ fput_const ((GET_FIELD (insn, 6, 22) << 5 |
+ GET_FIELD (insn, 27, 31)), info);
+ break;
+ case '1':
+ fput_const ((GET_FIELD (insn, 11, 20) << 5 |
+ GET_FIELD (insn, 27, 31)), info);
+ break;
+ case '0':
+ fput_const ((GET_FIELD (insn, 16, 20) << 5 |
+ GET_FIELD (insn, 27, 31)), info);
+ break;
+ case 'u':
+ (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
+ break;
+ case 'F':
+ /* if no destination completer and not before a completer
+ for fcmp, need a space here */
+ if (GET_FIELD (insn, 21, 22) == 1 || s[1] == 'M')
+ fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
+ info);
+ else
+ (*info->fprintf_func) (info->stream, "%s ",
+ float_format_names[GET_FIELD
+ (insn, 19, 20)]);
+ break;
+ case 'G':
+ (*info->fprintf_func) (info->stream, "%s ",
+ float_format_names[GET_FIELD (insn,
+ 17, 18)]);
+ break;
+ case 'H':
+ if (GET_FIELD (insn, 26, 26) == 1)
+ (*info->fprintf_func) (info->stream, "%s ",
+ float_format_names[0]);
+ else
+ (*info->fprintf_func) (info->stream, "%s ",
+ float_format_names[1]);
+ break;
+ case 'I':
+ /* if no destination completer and not before a completer
+ for fcmp, need a space here */
+ if (GET_FIELD (insn, 21, 22) == 1 || s[1] == 'M')
+ fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
+ info);
+ else
+ (*info->fprintf_func) (info->stream, "%s ",
+ float_format_names[GET_FIELD
+ (insn, 20, 20)]);
+ break;
+ case 'J':
+ if (GET_FIELD (insn, 24, 24))
+ fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
+ else
+ fput_fp_reg (GET_FIELD (insn, 6, 10), info);
+
+ break;
+ case 'K':
+ if (GET_FIELD (insn, 19, 19))
+ fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
+ else
+ fput_fp_reg (GET_FIELD (insn, 11, 15), info);
+ break;
+ case 'M':
+ (*info->fprintf_func) (info->stream, "%s ",
+ float_comp_names[GET_FIELD
+ (insn, 27, 31)]);
+ break;
+ default:
+ (*info->fprintf_func) (info->stream, "%c", *s);
+ break;
+ }
+ }
+ return sizeof(insn);
+ }
+ }
+ (*info->fprintf_func) (info->stream, "#%8x", insn);
+ return sizeof(insn);
+}
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
new file mode 100644
index 00000000000..19144cb9fc5
--- /dev/null
+++ b/opcodes/i386-dis.c
@@ -0,0 +1,3268 @@
+/* Print i386 instructions for GDB, the GNU debugger.
+ Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ * modified by John Hassey (hassey@dg-rtp.dg.com)
+ */
+
+/*
+ * The main tables describing the instructions is essentially a copy
+ * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+ * Programmers Manual. Usually, there is a capital letter, followed
+ * by a small letter. The capital letter tell the addressing mode,
+ * and the small letter tells about the operand size. Refer to
+ * the Intel manual for details.
+ */
+
+#include "dis-asm.h"
+#include "sysdep.h"
+#include "opintl.h"
+
+#define MAXLEN 20
+
+#include <setjmp.h>
+
+#ifndef UNIXWARE_COMPAT
+/* Set non-zero for broken, compatible instructions. Set to zero for
+ non-broken opcodes. */
+#define UNIXWARE_COMPAT 1
+#endif
+
+
+static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
+
+struct dis_private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+ struct disassemble_info *info;
+ bfd_byte *addr;
+{
+ int status;
+ struct dis_private *priv = (struct dis_private *)info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ longjmp (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+#define Eb OP_E, b_mode
+#define indirEb OP_indirE, b_mode
+#define Gb OP_G, b_mode
+#define Ev OP_E, v_mode
+#define indirEv OP_indirE, v_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_E, 0
+#define Mp OP_E, 0 /* ? */
+#define Gv OP_G, v_mode
+#define Gw OP_G, w_mode
+#define Rw OP_rm, w_mode
+#define Rd OP_rm, d_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode /* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iw OP_I, w_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#if 0
+#define ONE OP_ONE, 0
+#endif
+#define Cd OP_C, d_mode
+#define Dd OP_D, d_mode
+#define Td OP_T, d_mode
+
+#define eAX OP_REG, eAX_reg
+#define eBX OP_REG, eBX_reg
+#define eCX OP_REG, eCX_reg
+#define eDX OP_REG, eDX_reg
+#define eSP OP_REG, eSP_reg
+#define eBP OP_REG, eBP_reg
+#define eSI OP_REG, eSI_reg
+#define eDI OP_REG, eDI_reg
+#define AL OP_REG, al_reg
+#define CL OP_REG, cl_reg
+#define DL OP_REG, dl_reg
+#define BL OP_REG, bl_reg
+#define AH OP_REG, ah_reg
+#define CH OP_REG, ch_reg
+#define DH OP_REG, dh_reg
+#define BH OP_REG, bh_reg
+#define AX OP_REG, ax_reg
+#define DX OP_REG, dx_reg
+#define indirDX OP_REG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, lptr
+#define Av OP_DIR, v_mode
+#define Ob OP_OFF, b_mode
+#define Ov OP_OFF, v_mode
+#define Xb OP_DSreg, eSI_reg
+#define Xv OP_DSreg, eSI_reg
+#define Yb OP_ESreg, eDI_reg
+#define Yv OP_ESreg, eDI_reg
+#define DSBX OP_DSreg, eBX_reg
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+#define MX OP_MMX, 0
+#define EM OP_EM, v_mode
+#define MS OP_MS, b_mode
+#define OPSUF OP_3DNowSuffix, 0
+
+/* bits in sizeflag */
+#if 0 /* leave undefined until someone adds the extra flag to objdump */
+#define SUFFIX_ALWAYS 4
+#endif
+#define AFLAG 2
+#define DFLAG 1
+
+typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag ));
+
+static void OP_E PARAMS ((int, int));
+static void OP_G PARAMS ((int, int));
+static void OP_I PARAMS ((int, int));
+static void OP_indirE PARAMS ((int, int));
+static void OP_sI PARAMS ((int, int));
+static void OP_REG PARAMS ((int, int));
+static void OP_J PARAMS ((int, int));
+static void OP_DIR PARAMS ((int, int));
+static void OP_OFF PARAMS ((int, int));
+static void OP_ESreg PARAMS ((int, int));
+static void OP_DSreg PARAMS ((int, int));
+static void OP_SEG PARAMS ((int, int));
+static void OP_C PARAMS ((int, int));
+static void OP_D PARAMS ((int, int));
+static void OP_T PARAMS ((int, int));
+static void OP_rm PARAMS ((int, int));
+static void OP_ST PARAMS ((int, int));
+static void OP_STi PARAMS ((int, int));
+#if 0
+static void OP_ONE PARAMS ((int, int));
+#endif
+static void OP_MMX PARAMS ((int, int));
+static void OP_EM PARAMS ((int, int));
+static void OP_MS PARAMS ((int, int));
+static void OP_3DNowSuffix PARAMS ((int, int));
+
+static void append_seg PARAMS ((void));
+static void set_op PARAMS ((unsigned int op));
+static void putop PARAMS ((char *template, int sizeflag));
+static void dofloat PARAMS ((int sizeflag));
+static int get16 PARAMS ((void));
+static int get32 PARAMS ((void));
+static void ckprefix PARAMS ((void));
+static void ptr_reg PARAMS ((int, int));
+
+#define b_mode 1
+#define v_mode 2
+#define w_mode 3
+#define d_mode 4
+#define x_mode 5
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+#define eAX_reg 107
+#define eCX_reg 108
+#define eDX_reg 109
+#define eBX_reg 110
+#define eSP_reg 111
+#define eBP_reg 112
+#define eSI_reg 113
+#define eDI_reg 114
+
+#define lptr 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define indir_dx_reg 150
+
+#define GRP1b NULL, NULL, 0
+#define GRP1S NULL, NULL, 1
+#define GRP1Ss NULL, NULL, 2
+#define GRP2b NULL, NULL, 3
+#define GRP2S NULL, NULL, 4
+#define GRP2b_one NULL, NULL, 5
+#define GRP2S_one NULL, NULL, 6
+#define GRP2b_cl NULL, NULL, 7
+#define GRP2S_cl NULL, NULL, 8
+#define GRP3b NULL, NULL, 9
+#define GRP3S NULL, NULL, 10
+#define GRP4 NULL, NULL, 11
+#define GRP5 NULL, NULL, 12
+#define GRP6 NULL, NULL, 13
+#define GRP7 NULL, NULL, 14
+#define GRP8 NULL, NULL, 15
+#define GRP9 NULL, NULL, 16
+#define GRP10 NULL, NULL, 17
+#define GRP11 NULL, NULL, 18
+#define GRP12 NULL, NULL, 19
+#define GRP13 NULL, NULL, 20
+#define GRP14 NULL, NULL, 21
+
+#define FLOATCODE 50
+#define FLOAT NULL, NULL, FLOATCODE
+
+struct dis386 {
+ char *name;
+ op_rtn op1;
+ int bytemode1;
+ op_rtn op2;
+ int bytemode2;
+ op_rtn op3;
+ int bytemode3;
+};
+
+/* Upper case letters in the instruction names here are macros.
+ 'A' => print 'b' if no register operands or suffix_always is true
+ 'B' => print 'b' if suffix_always is true
+ 'E' => print 'e' if 32-bit form of jcxz
+ 'L' => print 'l' if suffix_always is true
+ 'N' => print 'n' if instruction has no wait "prefix"
+ 'P' => print 'w' or 'l' if instruction has an operand size prefix,
+ or suffix_always is true
+ 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
+ 'R' => print 'w' or 'l'
+ 'S' => print 'w' or 'l' if suffix_always is true
+ 'W' => print 'b' or 'w'
+*/
+
+static struct dis386 dis386_att[] = {
+ /* 00 */
+ { "addB", Eb, Gb },
+ { "addS", Ev, Gv },
+ { "addB", Gb, Eb },
+ { "addS", Gv, Ev },
+ { "addB", AL, Ib },
+ { "addS", eAX, Iv },
+ { "pushP", es },
+ { "popP", es },
+ /* 08 */
+ { "orB", Eb, Gb },
+ { "orS", Ev, Gv },
+ { "orB", Gb, Eb },
+ { "orS", Gv, Ev },
+ { "orB", AL, Ib },
+ { "orS", eAX, Iv },
+ { "pushP", cs },
+ { "(bad)" }, /* 0x0f extended opcode escape */
+ /* 10 */
+ { "adcB", Eb, Gb },
+ { "adcS", Ev, Gv },
+ { "adcB", Gb, Eb },
+ { "adcS", Gv, Ev },
+ { "adcB", AL, Ib },
+ { "adcS", eAX, Iv },
+ { "pushP", ss },
+ { "popP", ss },
+ /* 18 */
+ { "sbbB", Eb, Gb },
+ { "sbbS", Ev, Gv },
+ { "sbbB", Gb, Eb },
+ { "sbbS", Gv, Ev },
+ { "sbbB", AL, Ib },
+ { "sbbS", eAX, Iv },
+ { "pushP", ds },
+ { "popP", ds },
+ /* 20 */
+ { "andB", Eb, Gb },
+ { "andS", Ev, Gv },
+ { "andB", Gb, Eb },
+ { "andS", Gv, Ev },
+ { "andB", AL, Ib },
+ { "andS", eAX, Iv },
+ { "(bad)" }, /* SEG ES prefix */
+ { "daa" },
+ /* 28 */
+ { "subB", Eb, Gb },
+ { "subS", Ev, Gv },
+ { "subB", Gb, Eb },
+ { "subS", Gv, Ev },
+ { "subB", AL, Ib },
+ { "subS", eAX, Iv },
+ { "(bad)" }, /* SEG CS prefix */
+ { "das" },
+ /* 30 */
+ { "xorB", Eb, Gb },
+ { "xorS", Ev, Gv },
+ { "xorB", Gb, Eb },
+ { "xorS", Gv, Ev },
+ { "xorB", AL, Ib },
+ { "xorS", eAX, Iv },
+ { "(bad)" }, /* SEG SS prefix */
+ { "aaa" },
+ /* 38 */
+ { "cmpB", Eb, Gb },
+ { "cmpS", Ev, Gv },
+ { "cmpB", Gb, Eb },
+ { "cmpS", Gv, Ev },
+ { "cmpB", AL, Ib },
+ { "cmpS", eAX, Iv },
+ { "(bad)" }, /* SEG DS prefix */
+ { "aas" },
+ /* 40 */
+ { "incS", eAX },
+ { "incS", eCX },
+ { "incS", eDX },
+ { "incS", eBX },
+ { "incS", eSP },
+ { "incS", eBP },
+ { "incS", eSI },
+ { "incS", eDI },
+ /* 48 */
+ { "decS", eAX },
+ { "decS", eCX },
+ { "decS", eDX },
+ { "decS", eBX },
+ { "decS", eSP },
+ { "decS", eBP },
+ { "decS", eSI },
+ { "decS", eDI },
+ /* 50 */
+ { "pushS", eAX },
+ { "pushS", eCX },
+ { "pushS", eDX },
+ { "pushS", eBX },
+ { "pushS", eSP },
+ { "pushS", eBP },
+ { "pushS", eSI },
+ { "pushS", eDI },
+ /* 58 */
+ { "popS", eAX },
+ { "popS", eCX },
+ { "popS", eDX },
+ { "popS", eBX },
+ { "popS", eSP },
+ { "popS", eBP },
+ { "popS", eSI },
+ { "popS", eDI },
+ /* 60 */
+ { "pushaP" },
+ { "popaP" },
+ { "boundS", Gv, Ma },
+ { "arpl", Ew, Gw },
+ { "(bad)" }, /* seg fs */
+ { "(bad)" }, /* seg gs */
+ { "(bad)" }, /* op size prefix */
+ { "(bad)" }, /* adr size prefix */
+ /* 68 */
+ { "pushP", Iv }, /* 386 book wrong */
+ { "imulS", Gv, Ev, Iv },
+ { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
+ { "imulS", Gv, Ev, sIb },
+ { "insb", Yb, indirDX },
+ { "insR", Yv, indirDX },
+ { "outsb", indirDX, Xb },
+ { "outsR", indirDX, Xv },
+ /* 70 */
+ { "jo", Jb },
+ { "jno", Jb },
+ { "jb", Jb },
+ { "jae", Jb },
+ { "je", Jb },
+ { "jne", Jb },
+ { "jbe", Jb },
+ { "ja", Jb },
+ /* 78 */
+ { "js", Jb },
+ { "jns", Jb },
+ { "jp", Jb },
+ { "jnp", Jb },
+ { "jl", Jb },
+ { "jge", Jb },
+ { "jle", Jb },
+ { "jg", Jb },
+ /* 80 */
+ { GRP1b },
+ { GRP1S },
+ { "(bad)" },
+ { GRP1Ss },
+ { "testB", Eb, Gb },
+ { "testS", Ev, Gv },
+ { "xchgB", Eb, Gb },
+ { "xchgS", Ev, Gv },
+ /* 88 */
+ { "movB", Eb, Gb },
+ { "movS", Ev, Gv },
+ { "movB", Gb, Eb },
+ { "movS", Gv, Ev },
+ { "movQ", Ev, Sw },
+ { "leaS", Gv, M },
+ { "movQ", Sw, Ev },
+ { "popQ", Ev },
+ /* 90 */
+ { "nop" },
+ { "xchgS", eCX, eAX },
+ { "xchgS", eDX, eAX },
+ { "xchgS", eBX, eAX },
+ { "xchgS", eSP, eAX },
+ { "xchgS", eBP, eAX },
+ { "xchgS", eSI, eAX },
+ { "xchgS", eDI, eAX },
+ /* 98 */
+ { "cWtR" },
+ { "cRtd" },
+ { "lcallP", Ap },
+ { "(bad)" }, /* fwait */
+ { "pushfP" },
+ { "popfP" },
+ { "sahf" },
+ { "lahf" },
+ /* a0 */
+ { "movB", AL, Ob },
+ { "movS", eAX, Ov },
+ { "movB", Ob, AL },
+ { "movS", Ov, eAX },
+ { "movsb", Yb, Xb },
+ { "movsR", Yv, Xv },
+ { "cmpsb", Xb, Yb },
+ { "cmpsR", Xv, Yv },
+ /* a8 */
+ { "testB", AL, Ib },
+ { "testS", eAX, Iv },
+ { "stosB", Yb, AL },
+ { "stosS", Yv, eAX },
+ { "lodsB", AL, Xb },
+ { "lodsS", eAX, Xv },
+ { "scasB", AL, Yb },
+ { "scasS", eAX, Yv },
+ /* b0 */
+ { "movB", AL, Ib },
+ { "movB", CL, Ib },
+ { "movB", DL, Ib },
+ { "movB", BL, Ib },
+ { "movB", AH, Ib },
+ { "movB", CH, Ib },
+ { "movB", DH, Ib },
+ { "movB", BH, Ib },
+ /* b8 */
+ { "movS", eAX, Iv },
+ { "movS", eCX, Iv },
+ { "movS", eDX, Iv },
+ { "movS", eBX, Iv },
+ { "movS", eSP, Iv },
+ { "movS", eBP, Iv },
+ { "movS", eSI, Iv },
+ { "movS", eDI, Iv },
+ /* c0 */
+ { GRP2b },
+ { GRP2S },
+ { "retP", Iw },
+ { "retP" },
+ { "lesS", Gv, Mp },
+ { "ldsS", Gv, Mp },
+ { "movA", Eb, Ib },
+ { "movQ", Ev, Iv },
+ /* c8 */
+ { "enterP", Iw, Ib },
+ { "leaveP" },
+ { "lretP", Iw },
+ { "lretP" },
+ { "int3" },
+ { "int", Ib },
+ { "into" },
+ { "iretP" },
+ /* d0 */
+ { GRP2b_one },
+ { GRP2S_one },
+ { GRP2b_cl },
+ { GRP2S_cl },
+ { "aam", sIb },
+ { "aad", sIb },
+ { "(bad)" },
+ { "xlat", DSBX },
+ /* d8 */
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ /* e0 */
+ { "loopne", Jb },
+ { "loope", Jb },
+ { "loop", Jb },
+ { "jEcxz", Jb },
+ { "inB", AL, Ib },
+ { "inS", eAX, Ib },
+ { "outB", Ib, AL },
+ { "outS", Ib, eAX },
+ /* e8 */
+ { "callP", Av },
+ { "jmpP", Jv },
+ { "ljmpP", Ap },
+ { "jmp", Jb },
+ { "inB", AL, indirDX },
+ { "inS", eAX, indirDX },
+ { "outB", indirDX, AL },
+ { "outS", indirDX, eAX },
+ /* f0 */
+ { "(bad)" }, /* lock prefix */
+ { "(bad)" },
+ { "(bad)" }, /* repne */
+ { "(bad)" }, /* repz */
+ { "hlt" },
+ { "cmc" },
+ { GRP3b },
+ { GRP3S },
+ /* f8 */
+ { "clc" },
+ { "stc" },
+ { "cli" },
+ { "sti" },
+ { "cld" },
+ { "std" },
+ { GRP4 },
+ { GRP5 },
+};
+
+static struct dis386 dis386_intel[] = {
+ /* 00 */
+ { "addB", Eb, Gb },
+ { "addS", Ev, Gv },
+ { "addB", Gb, Eb },
+ { "addS", Gv, Ev },
+ { "addB", AL, Ib },
+ { "addS", eAX, Iv },
+ { "pushP", es },
+ { "popP", es },
+ /* 08 */
+ { "orB", Eb, Gb },
+ { "orS", Ev, Gv },
+ { "orB", Gb, Eb },
+ { "orS", Gv, Ev },
+ { "orB", AL, Ib },
+ { "orS", eAX, Iv },
+ { "pushP", cs },
+ { "(bad)" }, /* 0x0f extended opcode escape */
+ /* 10 */
+ { "adcB", Eb, Gb },
+ { "adcS", Ev, Gv },
+ { "adcB", Gb, Eb },
+ { "adcS", Gv, Ev },
+ { "adcB", AL, Ib },
+ { "adcS", eAX, Iv },
+ { "pushP", ss },
+ { "popP", ss },
+ /* 18 */
+ { "sbbB", Eb, Gb },
+ { "sbbS", Ev, Gv },
+ { "sbbB", Gb, Eb },
+ { "sbbS", Gv, Ev },
+ { "sbbB", AL, Ib },
+ { "sbbS", eAX, Iv },
+ { "pushP", ds },
+ { "popP", ds },
+ /* 20 */
+ { "andB", Eb, Gb },
+ { "andS", Ev, Gv },
+ { "andB", Gb, Eb },
+ { "andS", Gv, Ev },
+ { "andB", AL, Ib },
+ { "andS", eAX, Iv },
+ { "(bad)" }, /* SEG ES prefix */
+ { "daa" },
+ /* 28 */
+ { "subB", Eb, Gb },
+ { "subS", Ev, Gv },
+ { "subB", Gb, Eb },
+ { "subS", Gv, Ev },
+ { "subB", AL, Ib },
+ { "subS", eAX, Iv },
+ { "(bad)" }, /* SEG CS prefix */
+ { "das" },
+ /* 30 */
+ { "xorB", Eb, Gb },
+ { "xorS", Ev, Gv },
+ { "xorB", Gb, Eb },
+ { "xorS", Gv, Ev },
+ { "xorB", AL, Ib },
+ { "xorS", eAX, Iv },
+ { "(bad)" }, /* SEG SS prefix */
+ { "aaa" },
+ /* 38 */
+ { "cmpB", Eb, Gb },
+ { "cmpS", Ev, Gv },
+ { "cmpB", Gb, Eb },
+ { "cmpS", Gv, Ev },
+ { "cmpB", AL, Ib },
+ { "cmpS", eAX, Iv },
+ { "(bad)" }, /* SEG DS prefix */
+ { "aas" },
+ /* 40 */
+ { "incS", eAX },
+ { "incS", eCX },
+ { "incS", eDX },
+ { "incS", eBX },
+ { "incS", eSP },
+ { "incS", eBP },
+ { "incS", eSI },
+ { "incS", eDI },
+ /* 48 */
+ { "decS", eAX },
+ { "decS", eCX },
+ { "decS", eDX },
+ { "decS", eBX },
+ { "decS", eSP },
+ { "decS", eBP },
+ { "decS", eSI },
+ { "decS", eDI },
+ /* 50 */
+ { "pushS", eAX },
+ { "pushS", eCX },
+ { "pushS", eDX },
+ { "pushS", eBX },
+ { "pushS", eSP },
+ { "pushS", eBP },
+ { "pushS", eSI },
+ { "pushS", eDI },
+ /* 58 */
+ { "popS", eAX },
+ { "popS", eCX },
+ { "popS", eDX },
+ { "popS", eBX },
+ { "popS", eSP },
+ { "popS", eBP },
+ { "popS", eSI },
+ { "popS", eDI },
+ /* 60 */
+ { "pushaP" },
+ { "popaP" },
+ { "boundS", Gv, Ma },
+ { "arpl", Ew, Gw },
+ { "(bad)" }, /* seg fs */
+ { "(bad)" }, /* seg gs */
+ { "(bad)" }, /* op size prefix */
+ { "(bad)" }, /* adr size prefix */
+ /* 68 */
+ { "pushP", Iv }, /* 386 book wrong */
+ { "imulS", Gv, Ev, Iv },
+ { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
+ { "imulS", Gv, Ev, sIb },
+ { "insb", Yb, indirDX },
+ { "insR", Yv, indirDX },
+ { "outsb", indirDX, Xb },
+ { "outsR", indirDX, Xv },
+ /* 70 */
+ { "jo", Jb },
+ { "jno", Jb },
+ { "jb", Jb },
+ { "jae", Jb },
+ { "je", Jb },
+ { "jne", Jb },
+ { "jbe", Jb },
+ { "ja", Jb },
+ /* 78 */
+ { "js", Jb },
+ { "jns", Jb },
+ { "jp", Jb },
+ { "jnp", Jb },
+ { "jl", Jb },
+ { "jge", Jb },
+ { "jle", Jb },
+ { "jg", Jb },
+ /* 80 */
+ { GRP1b },
+ { GRP1S },
+ { "(bad)" },
+ { GRP1Ss },
+ { "testB", Eb, Gb },
+ { "testS", Ev, Gv },
+ { "xchgB", Eb, Gb },
+ { "xchgS", Ev, Gv },
+ /* 88 */
+ { "movB", Eb, Gb },
+ { "movS", Ev, Gv },
+ { "movB", Gb, Eb },
+ { "movS", Gv, Ev },
+ { "movQ", Ev, Sw },
+ { "leaS", Gv, M },
+ { "movQ", Sw, Ev },
+ { "popQ", Ev },
+ /* 90 */
+ { "nop" },
+ { "xchgS", eCX, eAX },
+ { "xchgS", eDX, eAX },
+ { "xchgS", eBX, eAX },
+ { "xchgS", eSP, eAX },
+ { "xchgS", eBP, eAX },
+ { "xchgS", eSI, eAX },
+ { "xchgS", eDI, eAX },
+ /* 98 */
+ { "cWtR" },
+ { "cRtd" },
+ { "lcallP", Ap },
+ { "(bad)" }, /* fwait */
+ { "pushfP" },
+ { "popfP" },
+ { "sahf" },
+ { "lahf" },
+ /* a0 */
+ { "movB", AL, Ob },
+ { "movS", eAX, Ov },
+ { "movB", Ob, AL },
+ { "movS", Ov, eAX },
+ { "movsb", Yb, Xb },
+ { "movsR", Yv, Xv },
+ { "cmpsb", Xb, Yb },
+ { "cmpsR", Xv, Yv },
+ /* a8 */
+ { "testB", AL, Ib },
+ { "testS", eAX, Iv },
+ { "stosB", Yb, AL },
+ { "stosS", Yv, eAX },
+ { "lodsB", AL, Xb },
+ { "lodsS", eAX, Xv },
+ { "scasB", AL, Yb },
+ { "scasS", eAX, Yv },
+ /* b0 */
+ { "movB", AL, Ib },
+ { "movB", CL, Ib },
+ { "movB", DL, Ib },
+ { "movB", BL, Ib },
+ { "movB", AH, Ib },
+ { "movB", CH, Ib },
+ { "movB", DH, Ib },
+ { "movB", BH, Ib },
+ /* b8 */
+ { "movS", eAX, Iv },
+ { "movS", eCX, Iv },
+ { "movS", eDX, Iv },
+ { "movS", eBX, Iv },
+ { "movS", eSP, Iv },
+ { "movS", eBP, Iv },
+ { "movS", eSI, Iv },
+ { "movS", eDI, Iv },
+ /* c0 */
+ { GRP2b },
+ { GRP2S },
+ { "retP", Iw },
+ { "retP" },
+ { "lesS", Gv, Mp },
+ { "ldsS", Gv, Mp },
+ { "movA", Eb, Ib },
+ { "movQ", Ev, Iv },
+ /* c8 */
+ { "enterP", Iw, Ib },
+ { "leaveP" },
+ { "lretP", Iw },
+ { "lretP" },
+ { "int3" },
+ { "int", Ib },
+ { "into" },
+ { "iretP" },
+ /* d0 */
+ { GRP2b_one },
+ { GRP2S_one },
+ { GRP2b_cl },
+ { GRP2S_cl },
+ { "aam", sIb },
+ { "aad", sIb },
+ { "(bad)" },
+ { "xlat", DSBX },
+ /* d8 */
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ /* e0 */
+ { "loopne", Jb },
+ { "loope", Jb },
+ { "loop", Jb },
+ { "jEcxz", Jb },
+ { "inB", AL, Ib },
+ { "inS", eAX, Ib },
+ { "outB", Ib, AL },
+ { "outS", Ib, eAX },
+ /* e8 */
+ { "callP", Av },
+ { "jmpP", Jv },
+ { "ljmpP", Ap },
+ { "jmp", Jb },
+ { "inB", AL, indirDX },
+ { "inS", eAX, indirDX },
+ { "outB", indirDX, AL },
+ { "outS", indirDX, eAX },
+ /* f0 */
+ { "(bad)" }, /* lock prefix */
+ { "(bad)" },
+ { "(bad)" }, /* repne */
+ { "(bad)" }, /* repz */
+ { "hlt" },
+ { "cmc" },
+ { GRP3b },
+ { GRP3S },
+ /* f8 */
+ { "clc" },
+ { "stc" },
+ { "cli" },
+ { "sti" },
+ { "cld" },
+ { "std" },
+ { GRP4 },
+ { GRP5 },
+};
+
+static struct dis386 dis386_twobyte_att[] = {
+ /* 00 */
+ { GRP6 },
+ { GRP7 },
+ { "larS", Gv, Ew },
+ { "lslS", Gv, Ew },
+ { "(bad)" },
+ { "(bad)" },
+ { "clts" },
+ { "(bad)" },
+ /* 08 */
+ { "invd" },
+ { "wbinvd" },
+ { "(bad)" },
+ { "ud2a" },
+ { "(bad)" },
+ { GRP14 },
+ { "femms" },
+ { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
+ /* 10 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 18 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 20 */
+ /* these are all backward in appendix A of the intel book */
+ { "movL", Rd, Cd },
+ { "movL", Rd, Dd },
+ { "movL", Cd, Rd },
+ { "movL", Dd, Rd },
+ { "movL", Rd, Td },
+ { "(bad)" },
+ { "movL", Td, Rd },
+ { "(bad)" },
+ /* 28 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 30 */
+ { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
+ { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
+ /* 38 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 40 */
+ { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
+ { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
+ /* 48 */
+ { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
+ { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
+ /* 50 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 58 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 60 */
+ { "punpcklbw", MX, EM },
+ { "punpcklwd", MX, EM },
+ { "punpckldq", MX, EM },
+ { "packsswb", MX, EM },
+ { "pcmpgtb", MX, EM },
+ { "pcmpgtw", MX, EM },
+ { "pcmpgtd", MX, EM },
+ { "packuswb", MX, EM },
+ /* 68 */
+ { "punpckhbw", MX, EM },
+ { "punpckhwd", MX, EM },
+ { "punpckhdq", MX, EM },
+ { "packssdw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ { "movd", MX, Ev },
+ { "movq", MX, EM },
+ /* 70 */
+ { "(bad)" },
+ { GRP10 },
+ { GRP11 },
+ { GRP12 },
+ { "pcmpeqb", MX, EM },
+ { "pcmpeqw", MX, EM },
+ { "pcmpeqd", MX, EM },
+ { "emms" },
+ /* 78 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" },
+ { "movd", Ev, MX },
+ { "movq", EM, MX },
+ /* 80 */
+ { "jo", Jv },
+ { "jno", Jv },
+ { "jb", Jv },
+ { "jae", Jv },
+ { "je", Jv },
+ { "jne", Jv },
+ { "jbe", Jv },
+ { "ja", Jv },
+ /* 88 */
+ { "js", Jv },
+ { "jns", Jv },
+ { "jp", Jv },
+ { "jnp", Jv },
+ { "jl", Jv },
+ { "jge", Jv },
+ { "jle", Jv },
+ { "jg", Jv },
+ /* 90 */
+ { "seto", Eb },
+ { "setno", Eb },
+ { "setb", Eb },
+ { "setae", Eb },
+ { "sete", Eb },
+ { "setne", Eb },
+ { "setbe", Eb },
+ { "seta", Eb },
+ /* 98 */
+ { "sets", Eb },
+ { "setns", Eb },
+ { "setp", Eb },
+ { "setnp", Eb },
+ { "setl", Eb },
+ { "setge", Eb },
+ { "setle", Eb },
+ { "setg", Eb },
+ /* a0 */
+ { "pushP", fs },
+ { "popP", fs },
+ { "cpuid" },
+ { "btS", Ev, Gv },
+ { "shldS", Ev, Gv, Ib },
+ { "shldS", Ev, Gv, CL },
+ { "(bad)" },
+ { "(bad)" },
+ /* a8 */
+ { "pushP", gs },
+ { "popP", gs },
+ { "rsm" },
+ { "btsS", Ev, Gv },
+ { "shrdS", Ev, Gv, Ib },
+ { "shrdS", Ev, Gv, CL },
+ { GRP13 },
+ { "imulS", Gv, Ev },
+ /* b0 */
+ { "cmpxchgB", Eb, Gb },
+ { "cmpxchgS", Ev, Gv },
+ { "lssS", Gv, Mp }, /* 386 lists only Mp */
+ { "btrS", Ev, Gv },
+ { "lfsS", Gv, Mp }, /* 386 lists only Mp */
+ { "lgsS", Gv, Mp }, /* 386 lists only Mp */
+ { "movzbR", Gv, Eb },
+ { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
+ /* b8 */
+ { "(bad)" },
+ { "ud2b" },
+ { GRP8 },
+ { "btcS", Ev, Gv },
+ { "bsfS", Gv, Ev },
+ { "bsrS", Gv, Ev },
+ { "movsbR", Gv, Eb },
+ { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
+ /* c0 */
+ { "xaddB", Eb, Gb },
+ { "xaddS", Ev, Gv },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { GRP9 },
+ /* c8 */
+ { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
+ { "bswap", eCX },
+ { "bswap", eDX },
+ { "bswap", eBX },
+ { "bswap", eSP },
+ { "bswap", eBP },
+ { "bswap", eSI },
+ { "bswap", eDI },
+ /* d0 */
+ { "(bad)" },
+ { "psrlw", MX, EM },
+ { "psrld", MX, EM },
+ { "psrlq", MX, EM },
+ { "(bad)" },
+ { "pmullw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ /* d8 */
+ { "psubusb", MX, EM },
+ { "psubusw", MX, EM },
+ { "(bad)" },
+ { "pand", MX, EM },
+ { "paddusb", MX, EM },
+ { "paddusw", MX, EM },
+ { "(bad)" },
+ { "pandn", MX, EM },
+ /* e0 */
+ { "(bad)" },
+ { "psraw", MX, EM },
+ { "psrad", MX, EM },
+ { "(bad)" },
+ { "(bad)" },
+ { "pmulhw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ /* e8 */
+ { "psubsb", MX, EM },
+ { "psubsw", MX, EM },
+ { "(bad)" },
+ { "por", MX, EM },
+ { "paddsb", MX, EM },
+ { "paddsw", MX, EM },
+ { "(bad)" },
+ { "pxor", MX, EM },
+ /* f0 */
+ { "(bad)" },
+ { "psllw", MX, EM },
+ { "pslld", MX, EM },
+ { "psllq", MX, EM },
+ { "(bad)" },
+ { "pmaddwd", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ /* f8 */
+ { "psubb", MX, EM },
+ { "psubw", MX, EM },
+ { "psubd", MX, EM },
+ { "(bad)" },
+ { "paddb", MX, EM },
+ { "paddw", MX, EM },
+ { "paddd", MX, EM },
+ { "(bad)" }
+};
+
+static struct dis386 dis386_twobyte_intel[] = {
+ /* 00 */
+ { GRP6 },
+ { GRP7 },
+ { "larS", Gv, Ew },
+ { "lslS", Gv, Ew },
+ { "(bad)" },
+ { "(bad)" },
+ { "clts" },
+ { "(bad)" },
+ /* 08 */
+ { "invd" },
+ { "wbinvd" },
+ { "(bad)" },
+ { "ud2a" },
+ { "(bad)" },
+ { GRP14 },
+ { "femms" },
+ { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
+ /* 10 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 18 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 20 */
+ /* these are all backward in appendix A of the intel book */
+ { "movL", Rd, Cd },
+ { "movL", Rd, Dd },
+ { "movL", Cd, Rd },
+ { "movL", Dd, Rd },
+ { "movL", Rd, Td },
+ { "(bad)" },
+ { "movL", Td, Rd },
+ { "(bad)" },
+ /* 28 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 30 */
+ { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
+ { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
+ /* 38 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 40 */
+ { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
+ { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
+ /* 48 */
+ { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
+ { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
+ /* 50 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 58 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 60 */
+ { "punpcklbw", MX, EM },
+ { "punpcklwd", MX, EM },
+ { "punpckldq", MX, EM },
+ { "packsswb", MX, EM },
+ { "pcmpgtb", MX, EM },
+ { "pcmpgtw", MX, EM },
+ { "pcmpgtd", MX, EM },
+ { "packuswb", MX, EM },
+ /* 68 */
+ { "punpckhbw", MX, EM },
+ { "punpckhwd", MX, EM },
+ { "punpckhdq", MX, EM },
+ { "packssdw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ { "movd", MX, Ev },
+ { "movq", MX, EM },
+ /* 70 */
+ { "(bad)" },
+ { GRP10 },
+ { GRP11 },
+ { GRP12 },
+ { "pcmpeqb", MX, EM },
+ { "pcmpeqw", MX, EM },
+ { "pcmpeqd", MX, EM },
+ { "emms" },
+ /* 78 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" },
+ { "movd", Ev, MX },
+ { "movq", EM, MX },
+ /* 80 */
+ { "jo", Jv },
+ { "jno", Jv },
+ { "jb", Jv },
+ { "jae", Jv },
+ { "je", Jv },
+ { "jne", Jv },
+ { "jbe", Jv },
+ { "ja", Jv },
+ /* 88 */
+ { "js", Jv },
+ { "jns", Jv },
+ { "jp", Jv },
+ { "jnp", Jv },
+ { "jl", Jv },
+ { "jge", Jv },
+ { "jle", Jv },
+ { "jg", Jv },
+ /* 90 */
+ { "seto", Eb },
+ { "setno", Eb },
+ { "setb", Eb },
+ { "setae", Eb },
+ { "sete", Eb },
+ { "setne", Eb },
+ { "setbe", Eb },
+ { "seta", Eb },
+ /* 98 */
+ { "sets", Eb },
+ { "setns", Eb },
+ { "setp", Eb },
+ { "setnp", Eb },
+ { "setl", Eb },
+ { "setge", Eb },
+ { "setle", Eb },
+ { "setg", Eb },
+ /* a0 */
+ { "pushP", fs },
+ { "popP", fs },
+ { "cpuid" },
+ { "btS", Ev, Gv },
+ { "shldS", Ev, Gv, Ib },
+ { "shldS", Ev, Gv, CL },
+ { "(bad)" },
+ { "(bad)" },
+ /* a8 */
+ { "pushP", gs },
+ { "popP", gs },
+ { "rsm" },
+ { "btsS", Ev, Gv },
+ { "shrdS", Ev, Gv, Ib },
+ { "shrdS", Ev, Gv, CL },
+ { GRP13 },
+ { "imulS", Gv, Ev },
+ /* b0 */
+ { "cmpxchgB", Eb, Gb },
+ { "cmpxchgS", Ev, Gv },
+ { "lssS", Gv, Mp }, /* 386 lists only Mp */
+ { "btrS", Ev, Gv },
+ { "lfsS", Gv, Mp }, /* 386 lists only Mp */
+ { "lgsS", Gv, Mp }, /* 386 lists only Mp */
+ { "movzx", Gv, Eb },
+ { "movzx", Gv, Ew },
+ /* b8 */
+ { "(bad)" },
+ { "ud2b" },
+ { GRP8 },
+ { "btcS", Ev, Gv },
+ { "bsfS", Gv, Ev },
+ { "bsrS", Gv, Ev },
+ { "movsx", Gv, Eb },
+ { "movsx", Gv, Ew },
+ /* c0 */
+ { "xaddB", Eb, Gb },
+ { "xaddS", Ev, Gv },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { GRP9 },
+ /* c8 */
+ { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
+ { "bswap", eCX },
+ { "bswap", eDX },
+ { "bswap", eBX },
+ { "bswap", eSP },
+ { "bswap", eBP },
+ { "bswap", eSI },
+ { "bswap", eDI },
+ /* d0 */
+ { "(bad)" },
+ { "psrlw", MX, EM },
+ { "psrld", MX, EM },
+ { "psrlq", MX, EM },
+ { "(bad)" },
+ { "pmullw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ /* d8 */
+ { "psubusb", MX, EM },
+ { "psubusw", MX, EM },
+ { "(bad)" },
+ { "pand", MX, EM },
+ { "paddusb", MX, EM },
+ { "paddusw", MX, EM },
+ { "(bad)" },
+ { "pandn", MX, EM },
+ /* e0 */
+ { "(bad)" },
+ { "psraw", MX, EM },
+ { "psrad", MX, EM },
+ { "(bad)" },
+ { "(bad)" },
+ { "pmulhw", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ /* e8 */
+ { "psubsb", MX, EM },
+ { "psubsw", MX, EM },
+ { "(bad)" },
+ { "por", MX, EM },
+ { "paddsb", MX, EM },
+ { "paddsw", MX, EM },
+ { "(bad)" },
+ { "pxor", MX, EM },
+ /* f0 */
+ { "(bad)" },
+ { "psllw", MX, EM },
+ { "pslld", MX, EM },
+ { "psllq", MX, EM },
+ { "(bad)" },
+ { "pmaddwd", MX, EM },
+ { "(bad)" }, { "(bad)" },
+ /* f8 */
+ { "psubb", MX, EM },
+ { "psubw", MX, EM },
+ { "psubd", MX, EM },
+ { "(bad)" },
+ { "paddb", MX, EM },
+ { "paddw", MX, EM },
+ { "paddd", MX, EM },
+ { "(bad)" }
+};
+
+static const unsigned char onebyte_has_modrm[256] = {
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
+};
+
+static const unsigned char twobyte_has_modrm[256] = {
+ /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
+ /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
+ /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
+ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
+ /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
+ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
+ /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
+ /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
+ /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
+ /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *insn_codep;
+static unsigned char *codep;
+static disassemble_info *the_info;
+static int mod;
+static int rm;
+static int reg;
+static void oappend PARAMS ((char *s));
+
+static char *names32[]={
+ "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
+};
+static char *names16[] = {
+ "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
+};
+static char *names8[] = {
+ "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
+};
+static char *names_seg[] = {
+ "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+};
+static char *index16[] = {
+ "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
+};
+
+static struct dis386 grps[][8] = {
+ /* GRP1b */
+ {
+ { "addA", Eb, Ib },
+ { "orA", Eb, Ib },
+ { "adcA", Eb, Ib },
+ { "sbbA", Eb, Ib },
+ { "andA", Eb, Ib },
+ { "subA", Eb, Ib },
+ { "xorA", Eb, Ib },
+ { "cmpA", Eb, Ib }
+ },
+ /* GRP1S */
+ {
+ { "addQ", Ev, Iv },
+ { "orQ", Ev, Iv },
+ { "adcQ", Ev, Iv },
+ { "sbbQ", Ev, Iv },
+ { "andQ", Ev, Iv },
+ { "subQ", Ev, Iv },
+ { "xorQ", Ev, Iv },
+ { "cmpQ", Ev, Iv }
+ },
+ /* GRP1Ss */
+ {
+ { "addQ", Ev, sIb },
+ { "orQ", Ev, sIb },
+ { "adcQ", Ev, sIb },
+ { "sbbQ", Ev, sIb },
+ { "andQ", Ev, sIb },
+ { "subQ", Ev, sIb },
+ { "xorQ", Ev, sIb },
+ { "cmpQ", Ev, sIb }
+ },
+ /* GRP2b */
+ {
+ { "rolA", Eb, Ib },
+ { "rorA", Eb, Ib },
+ { "rclA", Eb, Ib },
+ { "rcrA", Eb, Ib },
+ { "shlA", Eb, Ib },
+ { "shrA", Eb, Ib },
+ { "(bad)" },
+ { "sarA", Eb, Ib },
+ },
+ /* GRP2S */
+ {
+ { "rolQ", Ev, Ib },
+ { "rorQ", Ev, Ib },
+ { "rclQ", Ev, Ib },
+ { "rcrQ", Ev, Ib },
+ { "shlQ", Ev, Ib },
+ { "shrQ", Ev, Ib },
+ { "(bad)" },
+ { "sarQ", Ev, Ib },
+ },
+ /* GRP2b_one */
+ {
+ { "rolA", Eb },
+ { "rorA", Eb },
+ { "rclA", Eb },
+ { "rcrA", Eb },
+ { "shlA", Eb },
+ { "shrA", Eb },
+ { "(bad)" },
+ { "sarA", Eb },
+ },
+ /* GRP2S_one */
+ {
+ { "rolQ", Ev },
+ { "rorQ", Ev },
+ { "rclQ", Ev },
+ { "rcrQ", Ev },
+ { "shlQ", Ev },
+ { "shrQ", Ev },
+ { "(bad)" },
+ { "sarQ", Ev },
+ },
+ /* GRP2b_cl */
+ {
+ { "rolA", Eb, CL },
+ { "rorA", Eb, CL },
+ { "rclA", Eb, CL },
+ { "rcrA", Eb, CL },
+ { "shlA", Eb, CL },
+ { "shrA", Eb, CL },
+ { "(bad)" },
+ { "sarA", Eb, CL },
+ },
+ /* GRP2S_cl */
+ {
+ { "rolQ", Ev, CL },
+ { "rorQ", Ev, CL },
+ { "rclQ", Ev, CL },
+ { "rcrQ", Ev, CL },
+ { "shlQ", Ev, CL },
+ { "shrQ", Ev, CL },
+ { "(bad)" },
+ { "sarQ", Ev, CL }
+ },
+ /* GRP3b */
+ {
+ { "testA", Eb, Ib },
+ { "(bad)", Eb },
+ { "notA", Eb },
+ { "negA", Eb },
+ { "mulB", AL, Eb },
+ { "imulB", AL, Eb },
+ { "divB", AL, Eb },
+ { "idivB", AL, Eb }
+ },
+ /* GRP3S */
+ {
+ { "testQ", Ev, Iv },
+ { "(bad)" },
+ { "notQ", Ev },
+ { "negQ", Ev },
+ { "mulS", eAX, Ev },
+ { "imulS", eAX, Ev },
+ { "divS", eAX, Ev },
+ { "idivS", eAX, Ev },
+ },
+ /* GRP4 */
+ {
+ { "incA", Eb },
+ { "decA", Eb },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* GRP5 */
+ {
+ { "incQ", Ev },
+ { "decQ", Ev },
+ { "callP", indirEv },
+ { "callP", indirEv },
+ { "jmpP", indirEv },
+ { "ljmpP", indirEv },
+ { "pushQ", Ev },
+ { "(bad)" },
+ },
+ /* GRP6 */
+ {
+ { "sldt", Ew },
+ { "str", Ew },
+ { "lldt", Ew },
+ { "ltr", Ew },
+ { "verr", Ew },
+ { "verw", Ew },
+ { "(bad)" },
+ { "(bad)" }
+ },
+ /* GRP7 */
+ {
+ { "sgdt", Ew },
+ { "sidt", Ew },
+ { "lgdt", Ew },
+ { "lidt", Ew },
+ { "smsw", Ew },
+ { "(bad)" },
+ { "lmsw", Ew },
+ { "invlpg", Ew },
+ },
+ /* GRP8 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "btQ", Ev, Ib },
+ { "btsQ", Ev, Ib },
+ { "btrQ", Ev, Ib },
+ { "btcQ", Ev, Ib },
+ },
+ /* GRP9 */
+ {
+ { "(bad)" },
+ { "cmpxchg8b", Ev },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* GRP10 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "psrlw", MS, Ib },
+ { "(bad)" },
+ { "psraw", MS, Ib },
+ { "(bad)" },
+ { "psllw", MS, Ib },
+ { "(bad)" },
+ },
+ /* GRP11 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "psrld", MS, Ib },
+ { "(bad)" },
+ { "psrad", MS, Ib },
+ { "(bad)" },
+ { "pslld", MS, Ib },
+ { "(bad)" },
+ },
+ /* GRP12 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "psrlq", MS, Ib },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "psllq", MS, Ib },
+ { "(bad)" },
+ },
+ /* GRP13 */
+ {
+ { "fxsave", Ev },
+ { "fxrstor", Ev },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* GRP14 */
+ {
+ { "prefetch", Eb },
+ { "prefetchw", Eb },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ }
+
+};
+
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADDR 0x400
+#define PREFIX_FWAIT 0x800
+
+static int prefixes;
+
+static void
+ckprefix ()
+{
+ prefixes = 0;
+ while (1)
+ {
+ FETCH_DATA (the_info, codep + 1);
+ switch (*codep)
+ {
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ break;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ break;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ break;
+ case 0x2e:
+ prefixes |= PREFIX_CS;
+ break;
+ case 0x36:
+ prefixes |= PREFIX_SS;
+ break;
+ case 0x3e:
+ prefixes |= PREFIX_DS;
+ break;
+ case 0x26:
+ prefixes |= PREFIX_ES;
+ break;
+ case 0x64:
+ prefixes |= PREFIX_FS;
+ break;
+ case 0x65:
+ prefixes |= PREFIX_GS;
+ break;
+ case 0x66:
+ prefixes |= PREFIX_DATA;
+ break;
+ case 0x67:
+ prefixes |= PREFIX_ADDR;
+ break;
+ case 0x9b:
+ /* fwait is really an instruction. If there are prefixes
+ before the fwait, they belong to the fwait, *not* to the
+ following instruction. */
+ if (prefixes)
+ {
+ prefixes |= PREFIX_FWAIT;
+ codep++;
+ return;
+ }
+ prefixes = PREFIX_FWAIT;
+ break;
+ default:
+ return;
+ }
+ codep++;
+ }
+}
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_ad, op_index[3];
+static unsigned int op_address[3];
+static unsigned int start_pc;
+
+
+/*
+ * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ * (see topic "Redundant prefixes" in the "Differences from 8086"
+ * section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ * be used to print the target address if this is a relative jump or call
+ * The function returns the length of this instruction in bytes.
+ */
+
+static int print_insn_x86
+ PARAMS ((bfd_vma pc, disassemble_info *info, int sizeflag));
+static int print_insn_i386
+ PARAMS ((bfd_vma pc, disassemble_info *info));
+
+static char intel_syntax;
+static char open_char;
+static char close_char;
+static char separator_char;
+static char scale_char;
+
+int
+print_insn_i386_att (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ intel_syntax = 0;
+ open_char = '(';
+ close_char = ')';
+ separator_char = ',';
+ scale_char = ',';
+
+ return print_insn_i386 (pc, info);
+}
+
+int
+print_insn_i386_intel (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ intel_syntax = 1;
+ open_char = '[';
+ close_char = ']';
+ separator_char = '+';
+ scale_char = '*';
+
+ return print_insn_i386 (pc, info);
+}
+
+static int
+print_insn_i386 (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ int flags;
+ if (info->mach == bfd_mach_i386_i386
+ || info->mach == bfd_mach_i386_i386_intel_syntax)
+ flags = AFLAG|DFLAG;
+ else if (info->mach == bfd_mach_i386_i8086)
+ flags = 0;
+ else
+ abort ();
+ return print_insn_x86 (pc, info, flags);
+}
+
+static int
+print_insn_x86 (pc, info, sizeflag)
+ bfd_vma pc;
+ disassemble_info *info;
+ int sizeflag;
+{
+ struct dis386 *dp;
+ int i;
+ int two_source_ops;
+ char *first, *second, *third;
+ int needcomma;
+ unsigned char need_modrm;
+
+ struct dis_private priv;
+ bfd_byte *inbuf = priv.the_buffer;
+
+ /* The output looks better if we put 5 bytes on a line, since that
+ puts long word instructions on a single line. */
+ info->bytes_per_line = 5;
+
+ info->private_data = (PTR) &priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = pc;
+ if (setjmp (priv.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+ obuf[0] = 0;
+ op1out[0] = 0;
+ op2out[0] = 0;
+ op3out[0] = 0;
+
+ op_index[0] = op_index[1] = op_index[2] = -1;
+
+ the_info = info;
+ start_pc = pc;
+ start_codep = inbuf;
+ codep = inbuf;
+
+ ckprefix ();
+
+ insn_codep = codep;
+
+ FETCH_DATA (info, codep + 1);
+ two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
+
+ obufp = obuf;
+
+ if ((prefixes & PREFIX_FWAIT)
+ && ((*codep < 0xd8) || (*codep > 0xdf)))
+ {
+ /* fwait not followed by floating point instruction. */
+ (*info->fprintf_func) (info->stream, "fwait");
+ /* There may be other prefixes. Skip any before the fwait. */
+ return codep - inbuf;
+ }
+
+ if (prefixes & PREFIX_REPZ)
+ oappend ("repz ");
+ if (prefixes & PREFIX_REPNZ)
+ oappend ("repnz ");
+ if (prefixes & PREFIX_LOCK)
+ oappend ("lock ");
+
+ if (prefixes & PREFIX_DATA)
+ sizeflag ^= DFLAG;
+
+ if (prefixes & PREFIX_ADDR)
+ {
+ sizeflag ^= AFLAG;
+ if (sizeflag & AFLAG)
+ oappend ("addr32 ");
+ else
+ oappend ("addr16 ");
+ }
+
+ if (*codep == 0x0f)
+ {
+ FETCH_DATA (info, codep + 2);
+ if (intel_syntax)
+ dp = &dis386_twobyte_intel[*++codep];
+ else
+ dp = &dis386_twobyte_att[*++codep];
+ need_modrm = twobyte_has_modrm[*codep];
+ }
+ else
+ {
+ if (intel_syntax)
+ dp = &dis386_intel[*codep];
+ else
+ dp = &dis386_att[*codep];
+ need_modrm = onebyte_has_modrm[*codep];
+ }
+ codep++;
+
+ if (need_modrm)
+ {
+ FETCH_DATA (info, codep + 1);
+ mod = (*codep >> 6) & 3;
+ reg = (*codep >> 3) & 7;
+ rm = *codep & 7;
+ }
+
+ if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+ {
+ dofloat (sizeflag);
+ }
+ else
+ {
+ if (dp->name == NULL)
+ dp = &grps[dp->bytemode1][reg];
+
+ putop (dp->name, sizeflag);
+
+ obufp = op1out;
+ op_ad = 2;
+ if (dp->op1)
+ (*dp->op1)(dp->bytemode1, sizeflag);
+
+ obufp = op2out;
+ op_ad = 1;
+ if (dp->op2)
+ (*dp->op2)(dp->bytemode2, sizeflag);
+
+ obufp = op3out;
+ op_ad = 0;
+ if (dp->op3)
+ (*dp->op3)(dp->bytemode3, sizeflag);
+ }
+
+ obufp = obuf + strlen (obuf);
+ for (i = strlen (obuf); i < 6; i++)
+ oappend (" ");
+ oappend (" ");
+ (*info->fprintf_func) (info->stream, "%s", obuf);
+
+ /* The enter and bound instructions are printed with operands in the same
+ order as the intel book; everything else is printed in reverse order. */
+ if (intel_syntax || two_source_ops)
+ {
+ first = op1out;
+ second = op2out;
+ third = op3out;
+ op_ad = op_index[0];
+ op_index[0] = op_index[2];
+ op_index[2] = op_ad;
+ }
+ else
+ {
+ first = op3out;
+ second = op2out;
+ third = op1out;
+ }
+ needcomma = 0;
+ if (*first)
+ {
+ if (op_index[0] != -1)
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", first);
+ needcomma = 1;
+ }
+ if (*second)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[1] != -1)
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", second);
+ needcomma = 1;
+ }
+ if (*third)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[2] != -1)
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", third);
+ }
+ return codep - inbuf;
+}
+
+static char *float_mem_att[] = {
+ /* d8 */
+ "fadds",
+ "fmuls",
+ "fcoms",
+ "fcomps",
+ "fsubs",
+ "fsubrs",
+ "fdivs",
+ "fdivrs",
+ /* d9 */
+ "flds",
+ "(bad)",
+ "fsts",
+ "fstps",
+ "fldenv",
+ "fldcw",
+ "fNstenv",
+ "fNstcw",
+ /* da */
+ "fiaddl",
+ "fimull",
+ "ficoml",
+ "ficompl",
+ "fisubl",
+ "fisubrl",
+ "fidivl",
+ "fidivrl",
+ /* db */
+ "fildl",
+ "(bad)",
+ "fistl",
+ "fistpl",
+ "(bad)",
+ "fldt",
+ "(bad)",
+ "fstpt",
+ /* dc */
+ "faddl",
+ "fmull",
+ "fcoml",
+ "fcompl",
+ "fsubl",
+ "fsubrl",
+ "fdivl",
+ "fdivrl",
+ /* dd */
+ "fldl",
+ "(bad)",
+ "fstl",
+ "fstpl",
+ "frstor",
+ "(bad)",
+ "fNsave",
+ "fNstsw",
+ /* de */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* df */
+ "fild",
+ "(bad)",
+ "fist",
+ "fistp",
+ "fbld",
+ "fildll",
+ "fbstp",
+ "fistpll",
+};
+
+static char *float_mem_intel[] = {
+ /* d8 */
+ "fadd",
+ "fmul",
+ "fcom",
+ "fcomp",
+ "fsub",
+ "fsubr",
+ "fdiv",
+ "fdivr",
+ /* d9 */
+ "fld",
+ "(bad)",
+ "fst",
+ "fstp",
+ "fldenv",
+ "fldcw",
+ "fNstenv",
+ "fNstcw",
+ /* da */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* db */
+ "fild",
+ "(bad)",
+ "fist",
+ "fistp",
+ "(bad)",
+ "fld",
+ "(bad)",
+ "fstp",
+ /* dc */
+ "fadd",
+ "fmul",
+ "fcom",
+ "fcomp",
+ "fsub",
+ "fsubr",
+ "fdiv",
+ "fdivr",
+ /* dd */
+ "fld",
+ "(bad)",
+ "fst",
+ "fstp",
+ "frstor",
+ "(bad)",
+ "fNsave",
+ "fNstsw",
+ /* de */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* df */
+ "fild",
+ "(bad)",
+ "fist",
+ "fistp",
+ "fbld",
+ "fild",
+ "fbstp",
+ "fistpll",
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+
+#define FGRPd9_2 NULL, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1
+#define FGRPd9_5 NULL, NULL, 2
+#define FGRPd9_6 NULL, NULL, 3
+#define FGRPd9_7 NULL, NULL, 4
+#define FGRPda_5 NULL, NULL, 5
+#define FGRPdb_4 NULL, NULL, 6
+#define FGRPde_3 NULL, NULL, 7
+#define FGRPdf_4 NULL, NULL, 8
+
+static struct dis386 float_reg[][8] = {
+ /* d8 */
+ {
+ { "fadd", ST, STi },
+ { "fmul", ST, STi },
+ { "fcom", STi },
+ { "fcomp", STi },
+ { "fsub", ST, STi },
+ { "fsubr", ST, STi },
+ { "fdiv", ST, STi },
+ { "fdivr", ST, STi },
+ },
+ /* d9 */
+ {
+ { "fld", STi },
+ { "fxch", STi },
+ { FGRPd9_2 },
+ { "(bad)" },
+ { FGRPd9_4 },
+ { FGRPd9_5 },
+ { FGRPd9_6 },
+ { FGRPd9_7 },
+ },
+ /* da */
+ {
+ { "fcmovb", ST, STi },
+ { "fcmove", ST, STi },
+ { "fcmovbe",ST, STi },
+ { "fcmovu", ST, STi },
+ { "(bad)" },
+ { FGRPda_5 },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* db */
+ {
+ { "fcmovnb",ST, STi },
+ { "fcmovne",ST, STi },
+ { "fcmovnbe",ST, STi },
+ { "fcmovnu",ST, STi },
+ { FGRPdb_4 },
+ { "fucomi", ST, STi },
+ { "fcomi", ST, STi },
+ { "(bad)" },
+ },
+ /* dc */
+ {
+ { "fadd", STi, ST },
+ { "fmul", STi, ST },
+ { "(bad)" },
+ { "(bad)" },
+#if UNIXWARE_COMPAT
+ { "fsub", STi, ST },
+ { "fsubr", STi, ST },
+ { "fdiv", STi, ST },
+ { "fdivr", STi, ST },
+#else
+ { "fsubr", STi, ST },
+ { "fsub", STi, ST },
+ { "fdivr", STi, ST },
+ { "fdiv", STi, ST },
+#endif
+ },
+ /* dd */
+ {
+ { "ffree", STi },
+ { "(bad)" },
+ { "fst", STi },
+ { "fstp", STi },
+ { "fucom", STi },
+ { "fucomp", STi },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* de */
+ {
+ { "faddp", STi, ST },
+ { "fmulp", STi, ST },
+ { "(bad)" },
+ { FGRPde_3 },
+#if UNIXWARE_COMPAT
+ { "fsubp", STi, ST },
+ { "fsubrp", STi, ST },
+ { "fdivp", STi, ST },
+ { "fdivrp", STi, ST },
+#else
+ { "fsubrp", STi, ST },
+ { "fsubp", STi, ST },
+ { "fdivrp", STi, ST },
+ { "fdivp", STi, ST },
+#endif
+ },
+ /* df */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { FGRPdf_4 },
+ { "fucomip",ST, STi },
+ { "fcomip", ST, STi },
+ { "(bad)" },
+ },
+};
+
+
+static char *fgrps[][8] = {
+ /* d9_2 0 */
+ {
+ "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* d9_4 1 */
+ {
+ "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+ },
+
+ /* d9_5 2 */
+ {
+ "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+ },
+
+ /* d9_6 3 */
+ {
+ "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+ },
+
+ /* d9_7 4 */
+ {
+ "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+ },
+
+ /* da_5 5 */
+ {
+ "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* db_4 6 */
+ {
+ "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+ "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+ },
+
+ /* de_3 7 */
+ {
+ "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* df_4 8 */
+ {
+ "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+};
+
+static void
+dofloat (sizeflag)
+ int sizeflag;
+{
+ struct dis386 *dp;
+ unsigned char floatop;
+
+ floatop = codep[-1];
+
+ if (mod != 3)
+ {
+ if (intel_syntax)
+ putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
+ else
+ putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
+ obufp = op1out;
+ if (floatop == 0xdb)
+ OP_E (x_mode, sizeflag);
+ else if (floatop == 0xdd)
+ OP_E (d_mode, sizeflag);
+ else
+ OP_E (v_mode, sizeflag);
+ return;
+ }
+ codep++;
+
+ dp = &float_reg[floatop - 0xd8][reg];
+ if (dp->name == NULL)
+ {
+ putop (fgrps[dp->bytemode1][rm], sizeflag);
+
+ /* instruction fnstsw is only one with strange arg */
+ if (floatop == 0xdf && codep[-1] == 0xe0)
+ strcpy (op1out, names16[0]);
+ }
+ else
+ {
+ putop (dp->name, sizeflag);
+
+ obufp = op1out;
+ if (dp->op1)
+ (*dp->op1)(dp->bytemode1, sizeflag);
+ obufp = op2out;
+ if (dp->op2)
+ (*dp->op2)(dp->bytemode2, sizeflag);
+ }
+}
+
+/* ARGSUSED */
+static void
+OP_ST (ignore, sizeflag)
+ int ignore;
+ int sizeflag;
+{
+ oappend ("%st");
+}
+
+/* ARGSUSED */
+static void
+OP_STi (ignore, sizeflag)
+ int ignore;
+ int sizeflag;
+{
+ sprintf (scratchbuf, "%%st(%d)", rm);
+ oappend (scratchbuf);
+}
+
+
+/* capital letters in template are macros */
+static void
+putop (template, sizeflag)
+ char *template;
+ int sizeflag;
+{
+ char *p;
+
+ for (p = template; *p; p++)
+ {
+ switch (*p)
+ {
+ default:
+ *obufp++ = *p;
+ break;
+ case 'A':
+ if (intel_syntax)
+ break;
+ if (mod != 3
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ *obufp++ = 'b';
+ break;
+ case 'B':
+ if (intel_syntax)
+ break;
+#ifdef SUFFIX_ALWAYS
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'b';
+#endif
+ break;
+ case 'E': /* For jcxz/jecxz */
+ if (sizeflag & AFLAG)
+ *obufp++ = 'e';
+ break;
+ case 'L':
+ if (intel_syntax)
+ break;
+#ifdef SUFFIX_ALWAYS
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'l';
+#endif
+ break;
+ case 'N':
+ if ((prefixes & PREFIX_FWAIT) == 0)
+ *obufp++ = 'n';
+ break;
+ case 'P':
+ if (intel_syntax)
+ break;
+ if ((prefixes & PREFIX_DATA)
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ }
+ break;
+ case 'Q':
+ if (intel_syntax)
+ break;
+ if (mod != 3
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ }
+ break;
+ case 'R':
+ if (intel_syntax)
+ break;
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ break;
+ case 'S':
+ if (intel_syntax)
+ break;
+#ifdef SUFFIX_ALWAYS
+ if (sizeflag & SUFFIX_ALWAYS)
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ }
+#endif
+ break;
+ case 'W':
+ if (intel_syntax)
+ break;
+ /* operand size flag for cwtl, cbtw */
+ if (sizeflag & DFLAG)
+ *obufp++ = 'w';
+ else
+ *obufp++ = 'b';
+ break;
+ }
+ }
+ *obufp = 0;
+}
+
+static void
+oappend (s)
+ char *s;
+{
+ strcpy (obufp, s);
+ obufp += strlen (s);
+}
+
+static void
+append_seg ()
+{
+ if (prefixes & PREFIX_CS)
+ oappend ("%cs:");
+ if (prefixes & PREFIX_DS)
+ oappend ("%ds:");
+ if (prefixes & PREFIX_SS)
+ oappend ("%ss:");
+ if (prefixes & PREFIX_ES)
+ oappend ("%es:");
+ if (prefixes & PREFIX_FS)
+ oappend ("%fs:");
+ if (prefixes & PREFIX_GS)
+ oappend ("%gs:");
+}
+
+static void
+OP_indirE (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ if (!intel_syntax)
+ oappend ("*");
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_E (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ int disp;
+
+ /* skip mod/rm byte */
+ codep++;
+
+ if (mod == 3)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend (names8[rm]);
+ break;
+ case w_mode:
+ oappend (names16[rm]);
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ oappend (names32[rm]);
+ else
+ oappend (names16[rm]);
+ break;
+ default:
+ oappend ("<bad dis table>");
+ break;
+ }
+ return;
+ }
+
+ disp = 0;
+ append_seg ();
+
+ if (sizeflag & AFLAG) /* 32 bit address mode */
+ {
+ int havesib;
+ int havebase;
+ int base;
+ int index = 0;
+ int scale = 0;
+
+ havesib = 0;
+ havebase = 1;
+ base = rm;
+
+ if (base == 4)
+ {
+ havesib = 1;
+ FETCH_DATA (the_info, codep + 1);
+ scale = (*codep >> 6) & 3;
+ index = (*codep >> 3) & 7;
+ base = *codep & 7;
+ codep++;
+ }
+
+ switch (mod)
+ {
+ case 0:
+ if (base == 5)
+ {
+ havebase = 0;
+ disp = get32 ();
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case 2:
+ disp = get32 ();
+ break;
+ }
+
+ if (!intel_syntax)
+ if (mod != 0 || base == 5)
+ {
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ }
+
+ if (havebase || (havesib && (index != 4 || scale != 0)))
+ {
+ if (intel_syntax)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend("BYTE PTR ");
+ break;
+ case w_mode:
+ oappend("WORD PTR ");
+ break;
+ case v_mode:
+ oappend("DWORD PTR ");
+ break;
+ case d_mode:
+ oappend("QWORD PTR ");
+ break;
+ case x_mode:
+ oappend("XWORD PTR ");
+ break;
+ default:
+ break;
+ }
+ }
+ *obufp++ = open_char;
+ *obufp = '\0';
+ if (havebase)
+ oappend (names32[base]);
+ if (havesib)
+ {
+ if (index != 4)
+ {
+ if (intel_syntax)
+ {
+ if (havebase)
+ {
+ *obufp++ = separator_char;
+ *obufp = '\0';
+ }
+ sprintf (scratchbuf, "%s", names32[index]);
+ }
+ else
+ sprintf (scratchbuf, ",%s", names32[index]);
+ oappend (scratchbuf);
+ }
+ if (!intel_syntax
+ || (intel_syntax
+ && bytemode != b_mode
+ && bytemode != w_mode
+ && bytemode != v_mode))
+ {
+ *obufp++ = scale_char;
+ *obufp = '\0';
+ sprintf (scratchbuf, "%d", 1 << scale);
+ oappend (scratchbuf);
+ }
+ }
+ if (intel_syntax)
+ if (mod != 0 || base == 5)
+ {
+ /* Don't print zero displacements */
+ if (disp > 0)
+ {
+ sprintf (scratchbuf, "+%d", disp);
+ oappend (scratchbuf);
+ }
+ else if (disp < 0)
+ {
+ sprintf (scratchbuf, "%d", disp);
+ oappend (scratchbuf);
+ }
+ }
+
+ *obufp++ = close_char;
+ *obufp = '\0';
+ }
+ else if (intel_syntax)
+ {
+ if (mod != 0 || base == 5)
+ {
+ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+ ;
+ else
+ {
+ oappend (names_seg[3]);
+ oappend (":");
+ }
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ }
+ }
+ }
+ else
+ { /* 16 bit address mode */
+ switch (mod)
+ {
+ case 0:
+ if (rm == 6)
+ {
+ disp = get16 ();
+ if ((disp & 0x8000) != 0)
+ disp -= 0x10000;
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case 2:
+ disp = get16 ();
+ if ((disp & 0x8000) != 0)
+ disp -= 0x10000;
+ break;
+ }
+
+ if (!intel_syntax)
+ if (mod != 0 || rm == 6)
+ {
+ sprintf (scratchbuf, "%d", disp);
+ oappend (scratchbuf);
+ }
+
+ if (mod != 0 || rm != 6)
+ {
+ *obufp++ = open_char;
+ *obufp = '\0';
+ oappend (index16[rm]);
+ *obufp++ = close_char;
+ *obufp = '\0';
+ }
+ }
+}
+
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+
+static void
+OP_G (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend (names8[reg]);
+ break;
+ case w_mode:
+ oappend (names16[reg]);
+ break;
+ case d_mode:
+ oappend (names32[reg]);
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ oappend (names32[reg]);
+ else
+ oappend (names16[reg]);
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+}
+
+static int
+get32 ()
+{
+ int x = 0;
+
+ FETCH_DATA (the_info, codep + 4);
+ x = *codep++ & 0xff;
+ x |= (*codep++ & 0xff) << 8;
+ x |= (*codep++ & 0xff) << 16;
+ x |= (*codep++ & 0xff) << 24;
+ return x;
+}
+
+static int
+get16 ()
+{
+ int x = 0;
+
+ FETCH_DATA (the_info, codep + 2);
+ x = *codep++ & 0xff;
+ x |= (*codep++ & 0xff) << 8;
+ return x;
+}
+
+static void
+set_op (op)
+ unsigned int op;
+{
+ op_index[op_ad] = op_ad;
+ op_address[op_ad] = op;
+}
+
+static void
+OP_REG (code, sizeflag)
+ int code;
+ int sizeflag;
+{
+ char *s;
+
+ switch (code)
+ {
+ case indir_dx_reg:
+ s = "(%dx)";
+ break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ s = names8[code - al_reg];
+ break;
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ if (sizeflag & DFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ break;
+ default:
+ s = INTERNAL_DISASSEMBLER_ERROR;
+ break;
+ }
+ oappend (s);
+}
+
+static void
+OP_I (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ int op;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++ & 0xff;
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ op = get32 ();
+ else
+ op = get16 ();
+ break;
+ case w_mode:
+ op = get16 ();
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ if (intel_syntax)
+ sprintf (scratchbuf, "0x%x", op);
+ else
+ sprintf (scratchbuf, "$0x%x", op);
+ oappend (scratchbuf);
+ scratchbuf[0] = '\0';
+}
+
+static void
+OP_sI (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ int op;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ if ((op & 0x80) != 0)
+ op -= 0x100;
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ op = get32 ();
+ else
+ {
+ op = get16();
+ if ((op & 0x8000) != 0)
+ op -= 0x10000;
+ }
+ break;
+ case w_mode:
+ op = get16 ();
+ if ((op & 0x8000) != 0)
+ op -= 0x10000;
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+ if (intel_syntax)
+ sprintf (scratchbuf, "%d", op);
+ else
+ sprintf (scratchbuf, "$0x%x", op);
+ oappend (scratchbuf);
+}
+
+static void
+OP_J (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ int disp;
+ int mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ disp = get32 ();
+ else
+ {
+ disp = get16 ();
+ /* for some reason, a data16 prefix on a jump instruction
+ means that the pc is masked to 16 bits after the
+ displacement is added! */
+ mask = 0xffff;
+ }
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+ disp = (start_pc + codep - start_codep + disp) & mask;
+ set_op (disp);
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+static void
+OP_SEG (dummy, sizeflag)
+ int dummy;
+ int sizeflag;
+{
+ static char *sreg[] = {
+ "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+ };
+
+ oappend (sreg[reg]);
+}
+
+static void
+OP_DIR (size, sizeflag)
+ int size;
+ int sizeflag;
+{
+ int seg, offset;
+
+ switch (size)
+ {
+ case lptr:
+ if (sizeflag & DFLAG)
+ {
+ offset = get32 ();
+ seg = get16 ();
+ }
+ else
+ {
+ offset = get16 ();
+ seg = get16 ();
+ }
+ sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+ oappend (scratchbuf);
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ offset = get32 ();
+ else
+ {
+ offset = get16 ();
+ if ((offset & 0x8000) != 0)
+ offset -= 0x10000;
+ }
+
+ offset = start_pc + codep - start_codep + offset;
+ set_op (offset);
+ sprintf (scratchbuf, "0x%x", offset);
+ oappend (scratchbuf);
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+}
+
+/* ARGSUSED */
+static void
+OP_OFF (ignore, sizeflag)
+ int ignore;
+ int sizeflag;
+{
+ int off;
+
+ append_seg ();
+
+ if (sizeflag & AFLAG)
+ off = get32 ();
+ else
+ off = get16 ();
+
+ if (intel_syntax)
+ {
+ if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ {
+ oappend (names_seg[3]);
+ oappend (":");
+ }
+ }
+ sprintf (scratchbuf, "0x%x", off);
+ oappend (scratchbuf);
+}
+
+static void
+ptr_reg (code, sizeflag)
+ int code;
+ int sizeflag;
+{
+ char *s;
+ oappend ("(");
+ if (sizeflag & AFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ oappend (s);
+ oappend (")");
+}
+
+static void
+OP_ESreg (code, sizeflag)
+ int code;
+ int sizeflag;
+{
+ oappend ("%es:");
+ ptr_reg (code, sizeflag);
+}
+
+static void
+OP_DSreg (code, sizeflag)
+ int code;
+ int sizeflag;
+{
+ if ((prefixes
+ & (PREFIX_CS
+ | PREFIX_DS
+ | PREFIX_SS
+ | PREFIX_ES
+ | PREFIX_FS
+ | PREFIX_GS)) == 0)
+ prefixes |= PREFIX_DS;
+ append_seg();
+ ptr_reg (code, sizeflag);
+}
+
+#if 0
+/* Not used. */
+
+/* ARGSUSED */
+static void
+OP_ONE (dummy, sizeflag)
+ int dummy;
+ int sizeflag;
+{
+ oappend ("1");
+}
+
+#endif
+
+/* ARGSUSED */
+static void
+OP_C (dummy, sizeflag)
+ int dummy;
+ int sizeflag;
+{
+ codep++; /* skip mod/rm */
+ sprintf (scratchbuf, "%%cr%d", reg);
+ oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+static void
+OP_D (dummy, sizeflag)
+ int dummy;
+ int sizeflag;
+{
+ codep++; /* skip mod/rm */
+ sprintf (scratchbuf, "%%db%d", reg);
+ oappend (scratchbuf);
+}
+
+/* ARGSUSED */
+static void
+OP_T (dummy, sizeflag)
+ int dummy;
+ int sizeflag;
+{
+ codep++; /* skip mod/rm */
+ sprintf (scratchbuf, "%%tr%d", reg);
+ oappend (scratchbuf);
+}
+
+static void
+OP_rm (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ switch (bytemode)
+ {
+ case d_mode:
+ oappend (names32[rm]);
+ break;
+ case w_mode:
+ oappend (names16[rm]);
+ break;
+ }
+}
+
+static void
+OP_MMX (ignore, sizeflag)
+ int ignore;
+ int sizeflag;
+{
+ sprintf (scratchbuf, "%%mm%d", reg);
+ oappend (scratchbuf);
+}
+
+static void
+OP_EM (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ if (mod != 3)
+ {
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+
+ codep++;
+ sprintf (scratchbuf, "%%mm%d", rm);
+ oappend (scratchbuf);
+}
+
+static void
+OP_MS (ignore, sizeflag)
+ int ignore;
+ int sizeflag;
+{
+ ++codep;
+ sprintf (scratchbuf, "%%mm%d", rm);
+ oappend (scratchbuf);
+}
+
+static const char *Suffix3DNow[] = {
+/* 00 */ NULL, NULL, NULL, NULL,
+/* 04 */ NULL, NULL, NULL, NULL,
+/* 08 */ NULL, NULL, NULL, NULL,
+/* 0C */ NULL, "pi2fd", NULL, NULL,
+/* 10 */ NULL, NULL, NULL, NULL,
+/* 14 */ NULL, NULL, NULL, NULL,
+/* 18 */ NULL, NULL, NULL, NULL,
+/* 1C */ NULL, "pf2id", NULL, NULL,
+/* 20 */ NULL, NULL, NULL, NULL,
+/* 24 */ NULL, NULL, NULL, NULL,
+/* 28 */ NULL, NULL, NULL, NULL,
+/* 2C */ NULL, NULL, NULL, NULL,
+/* 30 */ NULL, NULL, NULL, NULL,
+/* 34 */ NULL, NULL, NULL, NULL,
+/* 38 */ NULL, NULL, NULL, NULL,
+/* 3C */ NULL, NULL, NULL, NULL,
+/* 40 */ NULL, NULL, NULL, NULL,
+/* 44 */ NULL, NULL, NULL, NULL,
+/* 48 */ NULL, NULL, NULL, NULL,
+/* 4C */ NULL, NULL, NULL, NULL,
+/* 50 */ NULL, NULL, NULL, NULL,
+/* 54 */ NULL, NULL, NULL, NULL,
+/* 58 */ NULL, NULL, NULL, NULL,
+/* 5C */ NULL, NULL, NULL, NULL,
+/* 60 */ NULL, NULL, NULL, NULL,
+/* 64 */ NULL, NULL, NULL, NULL,
+/* 68 */ NULL, NULL, NULL, NULL,
+/* 6C */ NULL, NULL, NULL, NULL,
+/* 70 */ NULL, NULL, NULL, NULL,
+/* 74 */ NULL, NULL, NULL, NULL,
+/* 78 */ NULL, NULL, NULL, NULL,
+/* 7C */ NULL, NULL, NULL, NULL,
+/* 80 */ NULL, NULL, NULL, NULL,
+/* 84 */ NULL, NULL, NULL, NULL,
+/* 88 */ NULL, NULL, NULL, NULL,
+/* 8C */ NULL, NULL, NULL, NULL,
+/* 90 */ "pfcmpge", NULL, NULL, NULL,
+/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
+/* 98 */ NULL, NULL, "pfsub", NULL,
+/* 9C */ NULL, NULL, "pfadd", NULL,
+/* A0 */ "pfcmpgt", NULL, NULL, NULL,
+/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
+/* A8 */ NULL, NULL, "pfsubr", NULL,
+/* AC */ NULL, NULL, "pfacc", NULL,
+/* B0 */ "pfcmpeq", NULL, NULL, NULL,
+/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
+/* B8 */ NULL, NULL, NULL, NULL,
+/* BC */ NULL, NULL, NULL, "pavgusb",
+/* C0 */ NULL, NULL, NULL, NULL,
+/* C4 */ NULL, NULL, NULL, NULL,
+/* C8 */ NULL, NULL, NULL, NULL,
+/* CC */ NULL, NULL, NULL, NULL,
+/* D0 */ NULL, NULL, NULL, NULL,
+/* D4 */ NULL, NULL, NULL, NULL,
+/* D8 */ NULL, NULL, NULL, NULL,
+/* DC */ NULL, NULL, NULL, NULL,
+/* E0 */ NULL, NULL, NULL, NULL,
+/* E4 */ NULL, NULL, NULL, NULL,
+/* E8 */ NULL, NULL, NULL, NULL,
+/* EC */ NULL, NULL, NULL, NULL,
+/* F0 */ NULL, NULL, NULL, NULL,
+/* F4 */ NULL, NULL, NULL, NULL,
+/* F8 */ NULL, NULL, NULL, NULL,
+/* FC */ NULL, NULL, NULL, NULL,
+};
+
+static void
+OP_3DNowSuffix (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ const char *mnemonic;
+
+ FETCH_DATA (the_info, codep + 1);
+ /* AMD 3DNow! instructions are specified by an opcode suffix in the
+ place where an 8-bit immediate would normally go. ie. the last
+ byte of the instruction. */
+ mnemonic = Suffix3DNow[*codep++];
+ if (mnemonic)
+ strcat (obuf, mnemonic);
+ else
+ {
+ /* Since a variable sized modrm/sib chunk is between the start
+ of the opcode (0x0f0f) and the opcode suffix, we need to do
+ all the modrm processing first, and don't know until now that
+ we have a bad opcode. This necessitates some cleaning up. */
+ op1out[0] = 0;
+ op2out[0] = 0;
+ codep = insn_codep + 1;
+ strcat (obuf, "(bad)");
+ }
+}
diff --git a/opcodes/i960-dis.c b/opcodes/i960-dis.c
new file mode 100644
index 00000000000..c0bd84837aa
--- /dev/null
+++ b/opcodes/i960-dis.c
@@ -0,0 +1,914 @@
+/* Disassemble i80960 instructions.
+ Copyright (C) 1990, 91, 93, 94, 95, 96, 1998 Free Software Foundation, Inc.
+
+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, 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; see the file COPYING. If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "dis-asm.h"
+
+static const char *const reg_names[] = {
+/* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
+/* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+/* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+/* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
+/* 32 */ "pc", "ac", "ip", "tc", "fp0", "fp1", "fp2", "fp3"
+};
+
+
+static FILE *stream; /* Output goes here */
+static struct disassemble_info *info;
+static void print_addr();
+static void ctrl();
+static void cobr();
+static void reg();
+static int mem();
+static void ea();
+static void dstop();
+static void regop();
+static void invalid();
+static int pinsn();
+static void put_abs();
+
+
+/* Print the i960 instruction at address 'memaddr' in debugged memory,
+ on INFO->STREAM. Returns length of the instruction, in bytes. */
+
+int
+print_insn_i960 (memaddr, info_arg)
+ bfd_vma memaddr;
+ struct disassemble_info *info_arg;
+{
+ unsigned int word1, word2 = 0xdeadbeef;
+ bfd_byte buffer[8];
+ int status;
+
+ info = info_arg;
+ stream = info->stream;
+
+ /* Read word1. Only read word2 if the instruction
+ needs it, to prevent reading past the end of a section. */
+
+ status = (*info->read_memory_func) (memaddr, (bfd_byte *) buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ word1 = bfd_getl32 (buffer);
+
+ /* Divide instruction set into classes based on high 4 bits of opcode. */
+ switch ( (word1 >> 28) & 0xf )
+ {
+ default:
+ break;
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ /* Read word2. */
+ status = (*info->read_memory_func)
+ (memaddr + 4, (bfd_byte *) (buffer + 4), 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ word2 = bfd_getl32 (buffer + 4);
+ break;
+ }
+
+ return pinsn( memaddr, word1, word2 );
+}
+
+#define IN_GDB
+
+/*****************************************************************************
+ * All code below this point should be identical with that of
+ * the disassembler in gdmp960.
+
+ A noble sentiment, but at least in cosmetic ways (info->fprintf_func), it
+ just ain't so. -kingdon, 31 Mar 93
+ *****************************************************************************/
+
+struct tabent {
+ char *name;
+ short numops;
+};
+
+struct sparse_tabent {
+ int opcode;
+ char *name;
+ short numops;
+};
+
+static int
+pinsn( memaddr, word1, word2 )
+ bfd_vma memaddr;
+ unsigned long word1, word2;
+{
+ int instr_len;
+
+ instr_len = 4;
+ put_abs( word1, word2 );
+
+ /* Divide instruction set into classes based on high 4 bits of opcode*/
+ switch ( (word1 >> 28) & 0xf ){
+ case 0x0:
+ case 0x1:
+ ctrl( memaddr, word1, word2 );
+ break;
+ case 0x2:
+ case 0x3:
+ cobr( memaddr, word1, word2 );
+ break;
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ reg( word1 );
+ break;
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ instr_len = mem( memaddr, word1, word2, 0 );
+ break;
+ default:
+ /* invalid instruction, print as data word */
+ invalid( word1 );
+ break;
+ }
+ return instr_len;
+}
+
+/****************************************/
+/* CTRL format */
+/****************************************/
+static void
+ctrl( memaddr, word1, word2 )
+ bfd_vma memaddr;
+ unsigned long word1, word2;
+{
+ int i;
+ static const struct tabent ctrl_tab[] = {
+ { NULL, 0, }, /* 0x00 */
+ { NULL, 0, }, /* 0x01 */
+ { NULL, 0, }, /* 0x02 */
+ { NULL, 0, }, /* 0x03 */
+ { NULL, 0, }, /* 0x04 */
+ { NULL, 0, }, /* 0x05 */
+ { NULL, 0, }, /* 0x06 */
+ { NULL, 0, }, /* 0x07 */
+ { "b", 1, }, /* 0x08 */
+ { "call", 1, }, /* 0x09 */
+ { "ret", 0, }, /* 0x0a */
+ { "bal", 1, }, /* 0x0b */
+ { NULL, 0, }, /* 0x0c */
+ { NULL, 0, }, /* 0x0d */
+ { NULL, 0, }, /* 0x0e */
+ { NULL, 0, }, /* 0x0f */
+ { "bno", 1, }, /* 0x10 */
+ { "bg", 1, }, /* 0x11 */
+ { "be", 1, }, /* 0x12 */
+ { "bge", 1, }, /* 0x13 */
+ { "bl", 1, }, /* 0x14 */
+ { "bne", 1, }, /* 0x15 */
+ { "ble", 1, }, /* 0x16 */
+ { "bo", 1, }, /* 0x17 */
+ { "faultno", 0, }, /* 0x18 */
+ { "faultg", 0, }, /* 0x19 */
+ { "faulte", 0, }, /* 0x1a */
+ { "faultge", 0, }, /* 0x1b */
+ { "faultl", 0, }, /* 0x1c */
+ { "faultne", 0, }, /* 0x1d */
+ { "faultle", 0, }, /* 0x1e */
+ { "faulto", 0, }, /* 0x1f */
+ };
+
+ i = (word1 >> 24) & 0xff;
+ if ( (ctrl_tab[i].name == NULL) || ((word1 & 1) != 0) ){
+ invalid( word1 );
+ return;
+ }
+
+ (*info->fprintf_func) ( stream, ctrl_tab[i].name );
+ if ( word1 & 2 ){ /* Predicts branch not taken */
+ (*info->fprintf_func) ( stream, ".f" );
+ }
+
+ if ( ctrl_tab[i].numops == 1 ){
+ /* EXTRACT DISPLACEMENT AND CONVERT TO ADDRESS */
+ word1 &= 0x00ffffff;
+ if ( word1 & 0x00800000 ){ /* Sign bit is set */
+ word1 |= (-1 & ~0xffffff); /* Sign extend */
+ }
+ (*info->fprintf_func)( stream, "\t" );
+ print_addr( word1 + memaddr );
+ }
+}
+
+/****************************************/
+/* COBR format */
+/****************************************/
+static void
+cobr( memaddr, word1, word2 )
+ bfd_vma memaddr;
+ unsigned long word1, word2;
+{
+ int src1;
+ int src2;
+ int i;
+
+ static const struct tabent cobr_tab[] = {
+ { "testno", 1, }, /* 0x20 */
+ { "testg", 1, }, /* 0x21 */
+ { "teste", 1, }, /* 0x22 */
+ { "testge", 1, }, /* 0x23 */
+ { "testl", 1, }, /* 0x24 */
+ { "testne", 1, }, /* 0x25 */
+ { "testle", 1, }, /* 0x26 */
+ { "testo", 1, }, /* 0x27 */
+ { NULL, 0, }, /* 0x28 */
+ { NULL, 0, }, /* 0x29 */
+ { NULL, 0, }, /* 0x2a */
+ { NULL, 0, }, /* 0x2b */
+ { NULL, 0, }, /* 0x2c */
+ { NULL, 0, }, /* 0x2d */
+ { NULL, 0, }, /* 0x2e */
+ { NULL, 0, }, /* 0x2f */
+ { "bbc", 3, }, /* 0x30 */
+ { "cmpobg", 3, }, /* 0x31 */
+ { "cmpobe", 3, }, /* 0x32 */
+ { "cmpobge", 3, }, /* 0x33 */
+ { "cmpobl", 3, }, /* 0x34 */
+ { "cmpobne", 3, }, /* 0x35 */
+ { "cmpoble", 3, }, /* 0x36 */
+ { "bbs", 3, }, /* 0x37 */
+ { "cmpibno", 3, }, /* 0x38 */
+ { "cmpibg", 3, }, /* 0x39 */
+ { "cmpibe", 3, }, /* 0x3a */
+ { "cmpibge", 3, }, /* 0x3b */
+ { "cmpibl", 3, }, /* 0x3c */
+ { "cmpibne", 3, }, /* 0x3d */
+ { "cmpible", 3, }, /* 0x3e */
+ { "cmpibo", 3, }, /* 0x3f */
+ };
+
+ i = ((word1 >> 24) & 0xff) - 0x20;
+ if ( cobr_tab[i].name == NULL ){
+ invalid( word1 );
+ return;
+ }
+
+ (*info->fprintf_func) ( stream, cobr_tab[i].name );
+ if ( word1 & 2 ){ /* Predicts branch not taken */
+ (*info->fprintf_func) ( stream, ".f" );
+ }
+ (*info->fprintf_func)( stream, "\t" );
+
+ src1 = (word1 >> 19) & 0x1f;
+ src2 = (word1 >> 14) & 0x1f;
+
+ if ( word1 & 0x02000 ){ /* M1 is 1 */
+ (*info->fprintf_func)( stream, "%d", src1 );
+ } else { /* M1 is 0 */
+ (*info->fprintf_func)( stream, reg_names[src1] );
+ }
+
+ if ( cobr_tab[i].numops > 1 ){
+ if ( word1 & 1 ){ /* S2 is 1 */
+ (*info->fprintf_func)( stream, ",sf%d,", src2 );
+ } else { /* S1 is 0 */
+ (*info->fprintf_func)( stream, ",%s,", reg_names[src2] );
+ }
+
+ /* Extract displacement and convert to address
+ */
+ word1 &= 0x00001ffc;
+ if ( word1 & 0x00001000 ){ /* Negative displacement */
+ word1 |= (-1 & ~0x1fff); /* Sign extend */
+ }
+ print_addr( memaddr + word1 );
+ }
+}
+
+/****************************************/
+/* MEM format */
+/****************************************/
+static int /* returns instruction length: 4 or 8 */
+mem( memaddr, word1, word2, noprint )
+ bfd_vma memaddr;
+ unsigned long word1, word2;
+ int noprint; /* If TRUE, return instruction length, but
+ * don't output any text.
+ */
+{
+ int i, j;
+ int len;
+ int mode;
+ int offset;
+ const char *reg1, *reg2, *reg3;
+
+ /* This lookup table is too sparse to make it worth typing in, but not
+ so large as to make a sparse array necessary. We create the table
+ at runtime. */
+
+ /*
+ * NOTE: In this table, the meaning of 'numops' is:
+ * 1: single operand
+ * 2: 2 operands, load instruction
+ * -2: 2 operands, store instruction
+ */
+ static struct tabent *mem_tab;
+/* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table. */
+#define MEM_MIN 0x80
+#define MEM_MAX 0xcf
+#define MEM_SIZ ( * sizeof(struct tabent))
+
+ static const struct sparse_tabent mem_init[] = {
+ { 0x80, "ldob", 2 },
+ { 0x82, "stob", -2 },
+ { 0x84, "bx", 1 },
+ { 0x85, "balx", 2 },
+ { 0x86, "callx", 1 },
+ { 0x88, "ldos", 2 },
+ { 0x8a, "stos", -2 },
+ { 0x8c, "lda", 2 },
+ { 0x90, "ld", 2 },
+ { 0x92, "st", -2 },
+ { 0x98, "ldl", 2 },
+ { 0x9a, "stl", -2 },
+ { 0xa0, "ldt", 2 },
+ { 0xa2, "stt", -2 },
+ { 0xac, "dcinva", 1 },
+ { 0xb0, "ldq", 2 },
+ { 0xb2, "stq", -2 },
+ { 0xc0, "ldib", 2 },
+ { 0xc2, "stib", -2 },
+ { 0xc8, "ldis", 2 },
+ { 0xca, "stis", -2 },
+ { 0, NULL, 0 }
+ };
+ static struct tabent mem_tab_buf[MEM_MAX - MEM_MIN + 1];
+
+ if ( mem_tab == NULL ){
+ mem_tab = mem_tab_buf;
+ for ( i = 0; mem_init[i].opcode != 0; i++ ){
+ j = mem_init[i].opcode - MEM_MIN;
+ mem_tab[j].name = mem_init[i].name;
+ mem_tab[j].numops = mem_init[i].numops;
+ }
+ }
+
+ i = ((word1 >> 24) & 0xff) - MEM_MIN;
+ mode = (word1 >> 10) & 0xf;
+
+ if ( (mem_tab[i].name != NULL) /* Valid instruction */
+ && ((mode == 5) || (mode >=12)) ){ /* With 32-bit displacement */
+ len = 8;
+ } else {
+ len = 4;
+ }
+
+ if ( noprint ){
+ return len;
+ }
+
+ if ( (mem_tab[i].name == NULL) || (mode == 6) ){
+ invalid( word1 );
+ return len;
+ }
+
+ (*info->fprintf_func)( stream, "%s\t", mem_tab[i].name );
+
+ reg1 = reg_names[ (word1 >> 19) & 0x1f ]; /* MEMB only */
+ reg2 = reg_names[ (word1 >> 14) & 0x1f ];
+ reg3 = reg_names[ word1 & 0x1f ]; /* MEMB only */
+ offset = word1 & 0xfff; /* MEMA only */
+
+ switch ( mem_tab[i].numops ){
+
+ case 2: /* LOAD INSTRUCTION */
+ if ( mode & 4 ){ /* MEMB FORMAT */
+ ea( memaddr, mode, reg2, reg3, word1, word2 );
+ (*info->fprintf_func)( stream, ",%s", reg1 );
+ } else { /* MEMA FORMAT */
+ (*info->fprintf_func)( stream, "0x%x", (unsigned) offset );
+ if (mode & 8) {
+ (*info->fprintf_func)( stream, "(%s)", reg2 );
+ }
+ (*info->fprintf_func)( stream, ",%s", reg1 );
+ }
+ break;
+
+ case -2: /* STORE INSTRUCTION */
+ if ( mode & 4 ){ /* MEMB FORMAT */
+ (*info->fprintf_func)( stream, "%s,", reg1 );
+ ea( memaddr, mode, reg2, reg3, word1, word2 );
+ } else { /* MEMA FORMAT */
+ (*info->fprintf_func)( stream, "%s,0x%x", reg1, (unsigned) offset );
+ if (mode & 8) {
+ (*info->fprintf_func)( stream, "(%s)", reg2 );
+ }
+ }
+ break;
+
+ case 1: /* BX/CALLX INSTRUCTION */
+ if ( mode & 4 ){ /* MEMB FORMAT */
+ ea( memaddr, mode, reg2, reg3, word1, word2 );
+ } else { /* MEMA FORMAT */
+ (*info->fprintf_func)( stream, "0x%x", (unsigned) offset );
+ if (mode & 8) {
+ (*info->fprintf_func)( stream, "(%s)", reg2 );
+ }
+ }
+ break;
+ }
+
+ return len;
+}
+
+/****************************************/
+/* REG format */
+/****************************************/
+static void
+reg( word1 )
+ unsigned long word1;
+{
+ int i, j;
+ int opcode;
+ int fp;
+ int m1, m2, m3;
+ int s1, s2;
+ int src, src2, dst;
+ char *mnemp;
+
+ /* This lookup table is too sparse to make it worth typing in, but not
+ so large as to make a sparse array necessary. We create the table
+ at runtime. */
+
+ /*
+ * NOTE: In this table, the meaning of 'numops' is:
+ * 1: single operand, which is NOT a destination.
+ * -1: single operand, which IS a destination.
+ * 2: 2 operands, the 2nd of which is NOT a destination.
+ * -2: 2 operands, the 2nd of which IS a destination.
+ * 3: 3 operands
+ *
+ * If an opcode mnemonic begins with "F", it is a floating-point
+ * opcode (the "F" is not printed).
+ */
+
+ static struct tabent *reg_tab;
+ static const struct sparse_tabent reg_init[] = {
+#define REG_MIN 0x580
+ { 0x580, "notbit", 3 },
+ { 0x581, "and", 3 },
+ { 0x582, "andnot", 3 },
+ { 0x583, "setbit", 3 },
+ { 0x584, "notand", 3 },
+ { 0x586, "xor", 3 },
+ { 0x587, "or", 3 },
+ { 0x588, "nor", 3 },
+ { 0x589, "xnor", 3 },
+ { 0x58a, "not", -2 },
+ { 0x58b, "ornot", 3 },
+ { 0x58c, "clrbit", 3 },
+ { 0x58d, "notor", 3 },
+ { 0x58e, "nand", 3 },
+ { 0x58f, "alterbit", 3 },
+ { 0x590, "addo", 3 },
+ { 0x591, "addi", 3 },
+ { 0x592, "subo", 3 },
+ { 0x593, "subi", 3 },
+ { 0x594, "cmpob", 2 },
+ { 0x595, "cmpib", 2 },
+ { 0x596, "cmpos", 2 },
+ { 0x597, "cmpis", 2 },
+ { 0x598, "shro", 3 },
+ { 0x59a, "shrdi", 3 },
+ { 0x59b, "shri", 3 },
+ { 0x59c, "shlo", 3 },
+ { 0x59d, "rotate", 3 },
+ { 0x59e, "shli", 3 },
+ { 0x5a0, "cmpo", 2 },
+ { 0x5a1, "cmpi", 2 },
+ { 0x5a2, "concmpo", 2 },
+ { 0x5a3, "concmpi", 2 },
+ { 0x5a4, "cmpinco", 3 },
+ { 0x5a5, "cmpinci", 3 },
+ { 0x5a6, "cmpdeco", 3 },
+ { 0x5a7, "cmpdeci", 3 },
+ { 0x5ac, "scanbyte", 2 },
+ { 0x5ad, "bswap", -2 },
+ { 0x5ae, "chkbit", 2 },
+ { 0x5b0, "addc", 3 },
+ { 0x5b2, "subc", 3 },
+ { 0x5b4, "intdis", 0 },
+ { 0x5b5, "inten", 0 },
+ { 0x5cc, "mov", -2 },
+ { 0x5d8, "eshro", 3 },
+ { 0x5dc, "movl", -2 },
+ { 0x5ec, "movt", -2 },
+ { 0x5fc, "movq", -2 },
+ { 0x600, "synmov", 2 },
+ { 0x601, "synmovl", 2 },
+ { 0x602, "synmovq", 2 },
+ { 0x603, "cmpstr", 3 },
+ { 0x604, "movqstr", 3 },
+ { 0x605, "movstr", 3 },
+ { 0x610, "atmod", 3 },
+ { 0x612, "atadd", 3 },
+ { 0x613, "inspacc", -2 },
+ { 0x614, "ldphy", -2 },
+ { 0x615, "synld", -2 },
+ { 0x617, "fill", 3 },
+ { 0x630, "sdma", 3 },
+ { 0x631, "udma", 0 },
+ { 0x640, "spanbit", -2 },
+ { 0x641, "scanbit", -2 },
+ { 0x642, "daddc", 3 },
+ { 0x643, "dsubc", 3 },
+ { 0x644, "dmovt", -2 },
+ { 0x645, "modac", 3 },
+ { 0x646, "condrec", -2 },
+ { 0x650, "modify", 3 },
+ { 0x651, "extract", 3 },
+ { 0x654, "modtc", 3 },
+ { 0x655, "modpc", 3 },
+ { 0x656, "receive", -2 },
+ { 0x658, "intctl", -2 },
+ { 0x659, "sysctl", 3 },
+ { 0x65b, "icctl", 3 },
+ { 0x65c, "dcctl", 3 },
+ { 0x65d, "halt", 0 },
+ { 0x660, "calls", 1 },
+ { 0x662, "send", 3 },
+ { 0x663, "sendserv", 1 },
+ { 0x664, "resumprcs", 1 },
+ { 0x665, "schedprcs", 1 },
+ { 0x666, "saveprcs", 0 },
+ { 0x668, "condwait", 1 },
+ { 0x669, "wait", 1 },
+ { 0x66a, "signal", 1 },
+ { 0x66b, "mark", 0 },
+ { 0x66c, "fmark", 0 },
+ { 0x66d, "flushreg", 0 },
+ { 0x66f, "syncf", 0 },
+ { 0x670, "emul", 3 },
+ { 0x671, "ediv", 3 },
+ { 0x673, "ldtime", -1 },
+ { 0x674, "Fcvtir", -2 },
+ { 0x675, "Fcvtilr", -2 },
+ { 0x676, "Fscalerl", 3 },
+ { 0x677, "Fscaler", 3 },
+ { 0x680, "Fatanr", 3 },
+ { 0x681, "Flogepr", 3 },
+ { 0x682, "Flogr", 3 },
+ { 0x683, "Fremr", 3 },
+ { 0x684, "Fcmpor", 2 },
+ { 0x685, "Fcmpr", 2 },
+ { 0x688, "Fsqrtr", -2 },
+ { 0x689, "Fexpr", -2 },
+ { 0x68a, "Flogbnr", -2 },
+ { 0x68b, "Froundr", -2 },
+ { 0x68c, "Fsinr", -2 },
+ { 0x68d, "Fcosr", -2 },
+ { 0x68e, "Ftanr", -2 },
+ { 0x68f, "Fclassr", 1 },
+ { 0x690, "Fatanrl", 3 },
+ { 0x691, "Flogeprl", 3 },
+ { 0x692, "Flogrl", 3 },
+ { 0x693, "Fremrl", 3 },
+ { 0x694, "Fcmporl", 2 },
+ { 0x695, "Fcmprl", 2 },
+ { 0x698, "Fsqrtrl", -2 },
+ { 0x699, "Fexprl", -2 },
+ { 0x69a, "Flogbnrl", -2 },
+ { 0x69b, "Froundrl", -2 },
+ { 0x69c, "Fsinrl", -2 },
+ { 0x69d, "Fcosrl", -2 },
+ { 0x69e, "Ftanrl", -2 },
+ { 0x69f, "Fclassrl", 1 },
+ { 0x6c0, "Fcvtri", -2 },
+ { 0x6c1, "Fcvtril", -2 },
+ { 0x6c2, "Fcvtzri", -2 },
+ { 0x6c3, "Fcvtzril", -2 },
+ { 0x6c9, "Fmovr", -2 },
+ { 0x6d9, "Fmovrl", -2 },
+ { 0x6e1, "Fmovre", -2 },
+ { 0x6e2, "Fcpysre", 3 },
+ { 0x6e3, "Fcpyrsre", 3 },
+ { 0x701, "mulo", 3 },
+ { 0x708, "remo", 3 },
+ { 0x70b, "divo", 3 },
+ { 0x741, "muli", 3 },
+ { 0x748, "remi", 3 },
+ { 0x749, "modi", 3 },
+ { 0x74b, "divi", 3 },
+ { 0x780, "addono", 3 },
+ { 0x781, "addino", 3 },
+ { 0x782, "subono", 3 },
+ { 0x783, "subino", 3 },
+ { 0x784, "selno", 3 },
+ { 0x78b, "Fdivr", 3 },
+ { 0x78c, "Fmulr", 3 },
+ { 0x78d, "Fsubr", 3 },
+ { 0x78f, "Faddr", 3 },
+ { 0x790, "addog", 3 },
+ { 0x791, "addig", 3 },
+ { 0x792, "subog", 3 },
+ { 0x793, "subig", 3 },
+ { 0x794, "selg", 3 },
+ { 0x79b, "Fdivrl", 3 },
+ { 0x79c, "Fmulrl", 3 },
+ { 0x79d, "Fsubrl", 3 },
+ { 0x79f, "Faddrl", 3 },
+ { 0x7a0, "addoe", 3 },
+ { 0x7a1, "addie", 3 },
+ { 0x7a2, "suboe", 3 },
+ { 0x7a3, "subie", 3 },
+ { 0x7a4, "sele", 3 },
+ { 0x7b0, "addoge", 3 },
+ { 0x7b1, "addige", 3 },
+ { 0x7b2, "suboge", 3 },
+ { 0x7b3, "subige", 3 },
+ { 0x7b4, "selge", 3 },
+ { 0x7c0, "addol", 3 },
+ { 0x7c1, "addil", 3 },
+ { 0x7c2, "subol", 3 },
+ { 0x7c3, "subil", 3 },
+ { 0x7c4, "sell", 3 },
+ { 0x7d0, "addone", 3 },
+ { 0x7d1, "addine", 3 },
+ { 0x7d2, "subone", 3 },
+ { 0x7d3, "subine", 3 },
+ { 0x7d4, "selne", 3 },
+ { 0x7e0, "addole", 3 },
+ { 0x7e1, "addile", 3 },
+ { 0x7e2, "subole", 3 },
+ { 0x7e3, "subile", 3 },
+ { 0x7e4, "selle", 3 },
+ { 0x7f0, "addoo", 3 },
+ { 0x7f1, "addio", 3 },
+ { 0x7f2, "suboo", 3 },
+ { 0x7f3, "subio", 3 },
+ { 0x7f4, "selo", 3 },
+#define REG_MAX 0x7f4
+ { 0, NULL, 0 }
+ };
+ static struct tabent reg_tab_buf[REG_MAX - REG_MIN + 1];
+
+ if ( reg_tab == NULL ){
+ reg_tab = reg_tab_buf;
+ for ( i = 0; reg_init[i].opcode != 0; i++ ){
+ j = reg_init[i].opcode - REG_MIN;
+ reg_tab[j].name = reg_init[i].name;
+ reg_tab[j].numops = reg_init[i].numops;
+ }
+ }
+
+ opcode = ((word1 >> 20) & 0xff0) | ((word1 >> 7) & 0xf);
+ i = opcode - REG_MIN;
+
+ if ( (opcode<REG_MIN) || (opcode>REG_MAX) || (reg_tab[i].name==NULL) ){
+ invalid( word1 );
+ return;
+ }
+
+ mnemp = reg_tab[i].name;
+ if ( *mnemp == 'F' ){
+ fp = 1;
+ mnemp++;
+ } else {
+ fp = 0;
+ }
+
+ (*info->fprintf_func)( stream, mnemp );
+
+ s1 = (word1 >> 5) & 1;
+ s2 = (word1 >> 6) & 1;
+ m1 = (word1 >> 11) & 1;
+ m2 = (word1 >> 12) & 1;
+ m3 = (word1 >> 13) & 1;
+ src = word1 & 0x1f;
+ src2 = (word1 >> 14) & 0x1f;
+ dst = (word1 >> 19) & 0x1f;
+
+ if ( reg_tab[i].numops != 0 ){
+ (*info->fprintf_func)( stream, "\t" );
+
+ switch ( reg_tab[i].numops ){
+ case 1:
+ regop( m1, s1, src, fp );
+ break;
+ case -1:
+ dstop( m3, dst, fp );
+ break;
+ case 2:
+ regop( m1, s1, src, fp );
+ (*info->fprintf_func)( stream, "," );
+ regop( m2, s2, src2, fp );
+ break;
+ case -2:
+ regop( m1, s1, src, fp );
+ (*info->fprintf_func)( stream, "," );
+ dstop( m3, dst, fp );
+ break;
+ case 3:
+ regop( m1, s1, src, fp );
+ (*info->fprintf_func)( stream, "," );
+ regop( m2, s2, src2, fp );
+ (*info->fprintf_func)( stream, "," );
+ dstop( m3, dst, fp );
+ break;
+ }
+ }
+}
+
+
+/*
+ * Print out effective address for memb instructions.
+ */
+static void
+ea( memaddr, mode, reg2, reg3, word1, word2 )
+ bfd_vma memaddr;
+ int mode;
+ char *reg2, *reg3;
+ int word1;
+ unsigned int word2;
+{
+ int scale;
+ static const int scale_tab[] = { 1, 2, 4, 8, 16 };
+
+ scale = (word1 >> 7) & 0x07;
+ if ( (scale > 4) || (((word1 >> 5) & 0x03) != 0) ){
+ invalid( word1 );
+ return;
+ }
+ scale = scale_tab[scale];
+
+ switch (mode) {
+ case 4: /* (reg) */
+ (*info->fprintf_func)( stream, "(%s)", reg2 );
+ break;
+ case 5: /* displ+8(ip) */
+ print_addr( word2+8+memaddr );
+ break;
+ case 7: /* (reg)[index*scale] */
+ if (scale == 1) {
+ (*info->fprintf_func)( stream, "(%s)[%s]", reg2, reg3 );
+ } else {
+ (*info->fprintf_func)( stream, "(%s)[%s*%d]",reg2,reg3,scale);
+ }
+ break;
+ case 12: /* displacement */
+ print_addr( (bfd_vma)word2 );
+ break;
+ case 13: /* displ(reg) */
+ print_addr( (bfd_vma)word2 );
+ (*info->fprintf_func)( stream, "(%s)", reg2 );
+ break;
+ case 14: /* displ[index*scale] */
+ print_addr( (bfd_vma)word2 );
+ if (scale == 1) {
+ (*info->fprintf_func)( stream, "[%s]", reg3 );
+ } else {
+ (*info->fprintf_func)( stream, "[%s*%d]", reg3, scale );
+ }
+ break;
+ case 15: /* displ(reg)[index*scale] */
+ print_addr( (bfd_vma)word2 );
+ if (scale == 1) {
+ (*info->fprintf_func)( stream, "(%s)[%s]", reg2, reg3 );
+ } else {
+ (*info->fprintf_func)( stream, "(%s)[%s*%d]",reg2,reg3,scale );
+ }
+ break;
+ default:
+ invalid( word1 );
+ return;
+ }
+}
+
+
+/************************************************/
+/* Register Instruction Operand */
+/************************************************/
+static void
+regop( mode, spec, reg, fp )
+ int mode, spec, reg, fp;
+{
+ if ( fp ){ /* FLOATING POINT INSTRUCTION */
+ if ( mode == 1 ){ /* FP operand */
+ switch ( reg ){
+ case 0: (*info->fprintf_func)( stream, "fp0" );
+ break;
+ case 1: (*info->fprintf_func)( stream, "fp1" );
+ break;
+ case 2: (*info->fprintf_func)( stream, "fp2" );
+ break;
+ case 3: (*info->fprintf_func)( stream, "fp3" );
+ break;
+ case 16: (*info->fprintf_func)( stream, "0f0.0" );
+ break;
+ case 22: (*info->fprintf_func)( stream, "0f1.0" );
+ break;
+ default: (*info->fprintf_func)( stream, "?" );
+ break;
+ }
+ } else { /* Non-FP register */
+ (*info->fprintf_func)( stream, reg_names[reg] );
+ }
+ } else { /* NOT FLOATING POINT */
+ if ( mode == 1 ){ /* Literal */
+ (*info->fprintf_func)( stream, "%d", reg );
+ } else { /* Register */
+ if ( spec == 0 ){
+ (*info->fprintf_func)( stream, reg_names[reg] );
+ } else {
+ (*info->fprintf_func)( stream, "sf%d", reg );
+ }
+ }
+ }
+}
+
+/************************************************/
+/* Register Instruction Destination Operand */
+/************************************************/
+static void
+dstop( mode, reg, fp )
+ int mode, reg, fp;
+{
+ /* 'dst' operand can't be a literal. On non-FP instructions, register
+ * mode is assumed and "m3" acts as if were "s3"; on FP-instructions,
+ * sf registers are not allowed so m3 acts normally.
+ */
+ if ( fp ){
+ regop( mode, 0, reg, fp );
+ } else {
+ regop( 0, mode, reg, fp );
+ }
+}
+
+
+static void
+invalid( word1 )
+ int word1;
+{
+ (*info->fprintf_func)( stream, ".word\t0x%08x", (unsigned) word1 );
+}
+
+static void
+print_addr(a)
+bfd_vma a;
+{
+ (*info->print_address_func) (a, info);
+}
+
+static void
+put_abs( word1, word2 )
+ unsigned long word1, word2;
+{
+#ifdef IN_GDB
+ return;
+#else
+ int len;
+
+ switch ( (word1 >> 28) & 0xf ){
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ /* MEM format instruction */
+ len = mem( 0, word1, word2, 1 );
+ break;
+ default:
+ len = 4;
+ break;
+ }
+
+ if ( len == 8 ){
+ (*info->fprintf_func)( stream, "%08x %08x\t", word1, word2 );
+ } else {
+ (*info->fprintf_func)( stream, "%08x \t", word1 );
+ }
+;
+
+#endif
+}
diff --git a/opcodes/m10200-dis.c b/opcodes/m10200-dis.c
new file mode 100644
index 00000000000..022c7e3410b
--- /dev/null
+++ b/opcodes/m10200-dis.c
@@ -0,0 +1,341 @@
+/* Disassemble MN10200 instructions.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <stdio.h>
+
+#include "ansidecl.h"
+#include "opcode/mn10200.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
+ unsigned long insn, unsigned long,
+ unsigned int));
+
+int
+print_insn_mn10200 (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int status;
+ bfd_byte buffer[4];
+ unsigned long insn;
+ unsigned long extension = 0;
+ unsigned int consume;
+
+ /* First figure out how big the opcode is. */
+ status = (*info->read_memory_func) (memaddr, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ insn = *(unsigned char *) buffer;
+
+ /* These are one byte insns. */
+ if ((insn & 0xf0) == 0x00
+ || (insn & 0xf0) == 0x10
+ || (insn & 0xf0) == 0x20
+ || (insn & 0xf0) == 0x30
+ || ((insn & 0xf0) == 0x80
+ && (insn & 0x0c) >> 2 != (insn & 0x03))
+ || (insn & 0xf0) == 0x90
+ || (insn & 0xf0) == 0xa0
+ || (insn & 0xf0) == 0xb0
+ || (insn & 0xff) == 0xeb
+ || (insn & 0xff) == 0xf6
+ || (insn & 0xff) == 0xfe
+ || (insn & 0xff) == 0xff)
+ {
+ extension = 0;
+ consume = 1;
+ }
+
+ /* These are two byte insns. */
+ else if ((insn & 0xf0) == 0x40
+ || (insn & 0xf0) == 0x50
+ || (insn & 0xf0) == 0x60
+ || (insn & 0xf0) == 0x70
+ || (insn & 0xf0) == 0x80
+ || (insn & 0xfc) == 0xd0
+ || (insn & 0xfc) == 0xd4
+ || (insn & 0xfc) == 0xd8
+ || (insn & 0xfc) == 0xe0
+ || (insn & 0xfc) == 0xe4
+ || (insn & 0xff) == 0xe8
+ || (insn & 0xff) == 0xe9
+ || (insn & 0xff) == 0xea
+ || (insn & 0xff) == 0xf0
+ || (insn & 0xff) == 0xf1
+ || (insn & 0xff) == 0xf2
+ || (insn & 0xff) == 0xf3)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb16 (buffer);
+ consume = 2;
+ }
+
+ /* These are three byte insns with a 16bit operand in little
+ endian form. */
+ else if ((insn & 0xf0) == 0xc0
+ || (insn & 0xfc) == 0xdc
+ || (insn & 0xfc) == 0xec
+ || (insn & 0xff) == 0xf8
+ || (insn & 0xff) == 0xf9
+ || (insn & 0xff) == 0xfa
+ || (insn & 0xff) == 0xfb
+ || (insn & 0xff) == 0xfc
+ || (insn & 0xff) == 0xfd)
+ {
+ status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn <<= 16;
+ insn |= bfd_getl16 (buffer);
+ extension = 0;
+ consume = 3;
+ }
+ /* These are three byte insns too, but we don't have to mess with
+ endianness stuff. */
+ else if ((insn & 0xff) == 0xf5)
+ {
+ status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn <<= 16;
+ insn |= bfd_getb16 (buffer);
+ extension = 0;
+ consume = 3;
+ }
+
+ /* These are four byte insns. */
+ else if ((insn & 0xff) == 0xf7)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb16 (buffer);
+ insn <<= 16;
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn |= bfd_getl16 (buffer);
+ extension = 0;
+ consume = 4;
+ }
+
+ /* These are five byte insns. */
+ else if ((insn & 0xff) == 0xf4)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb16 (buffer);
+ insn <<= 16;
+
+ status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn |= (*(unsigned char *)buffer << 8) & 0xff00;
+
+ status = (*info->read_memory_func) (memaddr + 3, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn |= (*(unsigned char *)buffer) & 0xff;
+
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ extension = (*(unsigned char *)buffer) & 0xff;
+ consume = 5;
+ }
+ else
+ {
+ (*info->fprintf_func) (info->stream, _("unknown\t0x%02x"), insn);
+ return 1;
+ }
+
+ disassemble (memaddr, info, insn, extension, consume);
+
+ return consume;
+}
+
+static void
+disassemble (memaddr, info, insn, extension, size)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+ unsigned long insn;
+ unsigned long extension;
+ unsigned int size;
+{
+ struct mn10200_opcode *op = (struct mn10200_opcode *)mn10200_opcodes;
+ const struct mn10200_operand *operand;
+ int match = 0;
+
+ /* Find the opcode. */
+ while (op->name)
+ {
+ int mysize, extra_shift;
+
+ if (op->format == FMT_1)
+ mysize = 1;
+ else if (op->format == FMT_2
+ || op->format == FMT_4)
+ mysize = 2;
+ else if (op->format == FMT_3
+ || op->format == FMT_5)
+ mysize = 3;
+ else if (op->format == FMT_6)
+ mysize = 4;
+ else if (op->format == FMT_7)
+ mysize = 5;
+ else
+ abort ();
+
+ if (op->format == FMT_2 || op->format == FMT_5)
+ extra_shift = 8;
+ else if (op->format == FMT_3
+ || op->format == FMT_6
+ || op->format == FMT_7)
+ extra_shift = 16;
+ else
+ extra_shift = 0;
+
+ if ((op->mask & insn) == op->opcode
+ && size == (unsigned int) mysize)
+ {
+ const unsigned char *opindex_ptr;
+ unsigned int nocomma;
+ int paren = 0;
+
+ match = 1;
+ (*info->fprintf_func) (info->stream, "%s\t", op->name);
+
+ /* Now print the operands. */
+ for (opindex_ptr = op->operands, nocomma = 1;
+ *opindex_ptr != 0;
+ opindex_ptr++)
+ {
+ unsigned long value;
+
+ operand = &mn10200_operands[*opindex_ptr];
+
+ if ((operand->flags & MN10200_OPERAND_EXTENDED) != 0)
+ {
+ value = (insn & 0xffff) << 8;
+ value |= extension;
+ }
+ else
+ {
+ value = ((insn >> (operand->shift))
+ & ((1L << operand->bits) - 1L));
+ }
+
+ if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
+ value = ((long)(value << (32 - operand->bits))
+ >> (32 - operand->bits));
+
+ if (!nocomma
+ && (!paren
+ || ((operand->flags & MN10200_OPERAND_PAREN) == 0)))
+ (*info->fprintf_func) (info->stream, ",");
+
+ nocomma = 0;
+
+ if ((operand->flags & MN10200_OPERAND_DREG) != 0)
+ {
+ value = ((insn >> (operand->shift + extra_shift))
+ & ((1 << operand->bits) - 1));
+ (*info->fprintf_func) (info->stream, "d%d", value);
+ }
+
+ else if ((operand->flags & MN10200_OPERAND_AREG) != 0)
+ {
+ value = ((insn >> (operand->shift + extra_shift))
+ & ((1 << operand->bits) - 1));
+ (*info->fprintf_func) (info->stream, "a%d", value);
+ }
+
+ else if ((operand->flags & MN10200_OPERAND_PSW) != 0)
+ (*info->fprintf_func) (info->stream, "psw");
+
+ else if ((operand->flags & MN10200_OPERAND_MDR) != 0)
+ (*info->fprintf_func) (info->stream, "mdr");
+
+ else if ((operand->flags & MN10200_OPERAND_PAREN) != 0)
+ {
+ if (paren)
+ (*info->fprintf_func) (info->stream, ")");
+ else
+ {
+ (*info->fprintf_func) (info->stream, "(");
+ nocomma = 1;
+ }
+ paren = !paren;
+ }
+
+ else if ((operand->flags & MN10200_OPERAND_PCREL) != 0)
+ (*info->print_address_func) ((value + memaddr + mysize) & 0xffffff, info);
+
+ else if ((operand->flags & MN10200_OPERAND_MEMADDR) != 0)
+ (*info->print_address_func) (value, info);
+
+ else
+ (*info->fprintf_func) (info->stream, "%ld", value);
+ }
+ /* All done. */
+ break;
+ }
+ op++;
+ }
+
+ if (!match)
+ {
+ (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
+ }
+}
diff --git a/opcodes/m10200-opc.c b/opcodes/m10200-opc.c
new file mode 100644
index 00000000000..2f70b9081ae
--- /dev/null
+++ b/opcodes/m10200-opc.c
@@ -0,0 +1,360 @@
+/* Assemble Matsushita MN10200 instructions.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "opcode/mn10200.h"
+
+
+const struct mn10200_operand mn10200_operands[] = {
+#define UNUSED 0
+ {0, 0, 0},
+
+/* dn register in the first register operand position. */
+#define DN0 (UNUSED+1)
+ {2, 0, MN10200_OPERAND_DREG},
+
+/* dn register in the second register operand position. */
+#define DN1 (DN0+1)
+ {2, 2, MN10200_OPERAND_DREG},
+
+/* dm register in the first register operand position. */
+#define DM0 (DN1+1)
+ {2, 0, MN10200_OPERAND_DREG},
+
+/* dm register in the second register operand position. */
+#define DM1 (DM0+1)
+ {2, 2, MN10200_OPERAND_DREG},
+
+/* an register in the first register operand position. */
+#define AN0 (DM1+1)
+ {2, 0, MN10200_OPERAND_AREG},
+
+/* an register in the second register operand position. */
+#define AN1 (AN0+1)
+ {2, 2, MN10200_OPERAND_AREG},
+
+/* am register in the first register operand position. */
+#define AM0 (AN1+1)
+ {2, 0, MN10200_OPERAND_AREG},
+
+/* am register in the second register operand position. */
+#define AM1 (AM0+1)
+ {2, 2, MN10200_OPERAND_AREG},
+
+/* 8 bit unsigned immediate which may promote to a 16bit
+ unsigned immediate. */
+#define IMM8 (AM1+1)
+ {8, 0, MN10200_OPERAND_PROMOTE},
+
+/* 16 bit unsigned immediate which may promote to a 32bit
+ unsigned immediate. */
+#define IMM16 (IMM8+1)
+ {16, 0, MN10200_OPERAND_PROMOTE},
+
+/* 16 bit pc-relative immediate which may promote to a 16bit
+ pc-relative immediate. */
+#define IMM16_PCREL (IMM16+1)
+ {16, 0, MN10200_OPERAND_PCREL | MN10200_OPERAND_RELAX | MN10200_OPERAND_SIGNED},
+
+/* 16bit unsigned dispacement in a memory operation which
+ may promote to a 32bit displacement. */
+#define IMM16_MEM (IMM16_PCREL+1)
+ {16, 0, MN10200_OPERAND_PROMOTE | MN10200_OPERAND_MEMADDR},
+
+/* 24 immediate, low 16 bits in the main instruction
+ word, 8 in the extension word. */
+
+#define IMM24 (IMM16_MEM+1)
+ {24, 0, MN10200_OPERAND_EXTENDED},
+
+/* 32bit pc-relative offset. */
+#define IMM24_PCREL (IMM24+1)
+ {24, 0, MN10200_OPERAND_EXTENDED | MN10200_OPERAND_PCREL | MN10200_OPERAND_SIGNED},
+
+/* 32bit memory offset. */
+#define IMM24_MEM (IMM24_PCREL+1)
+ {24, 0, MN10200_OPERAND_EXTENDED | MN10200_OPERAND_MEMADDR},
+
+/* Processor status word. */
+#define PSW (IMM24_MEM+1)
+ {0, 0, MN10200_OPERAND_PSW},
+
+/* MDR register. */
+#define MDR (PSW+1)
+ {0, 0, MN10200_OPERAND_MDR},
+
+/* Index register. */
+#define DI (MDR+1)
+ {2, 4, MN10200_OPERAND_DREG},
+
+/* 8 bit signed displacement, may promote to 16bit signed dispacement. */
+#define SD8 (DI+1)
+ {8, 0, MN10200_OPERAND_SIGNED | MN10200_OPERAND_PROMOTE},
+
+/* 16 bit signed displacement, may promote to 32bit dispacement. */
+#define SD16 (SD8+1)
+ {16, 0, MN10200_OPERAND_SIGNED | MN10200_OPERAND_PROMOTE},
+
+/* 8 bit pc-relative displacement. */
+#define SD8N_PCREL (SD16+1)
+ {8, 0, MN10200_OPERAND_SIGNED | MN10200_OPERAND_PCREL | MN10200_OPERAND_RELAX},
+
+/* 8 bit signed immediate which may promote to 16bit signed immediate. */
+#define SIMM8 (SD8N_PCREL+1)
+ {8, 0, MN10200_OPERAND_SIGNED | MN10200_OPERAND_PROMOTE},
+
+/* 16 bit signed immediate which may promote to 32bit immediate. */
+#define SIMM16 (SIMM8+1)
+ {16, 0, MN10200_OPERAND_SIGNED | MN10200_OPERAND_PROMOTE},
+
+/* 16 bit signed immediate which may not promote. */
+#define SIMM16N (SIMM16+1)
+ {16, 0, MN10200_OPERAND_SIGNED | MN10200_OPERAND_NOCHECK},
+
+/* Either an open paren or close paren. */
+#define PAREN (SIMM16N+1)
+ {0, 0, MN10200_OPERAND_PAREN},
+
+/* dn register that appears in the first and second register positions. */
+#define DN01 (PAREN+1)
+ {2, 0, MN10200_OPERAND_DREG | MN10200_OPERAND_REPEATED},
+
+/* an register that appears in the first and second register positions. */
+#define AN01 (DN01+1)
+ {2, 0, MN10200_OPERAND_AREG | MN10200_OPERAND_REPEATED},
+} ;
+
+#define MEM(ADDR) PAREN, ADDR, PAREN
+#define MEM2(ADDR1,ADDR2) PAREN, ADDR1, ADDR2, PAREN
+
+/* The opcode table.
+
+ The format of the opcode table is:
+
+ NAME OPCODE MASK { OPERANDS }
+
+ NAME is the name of the instruction.
+ OPCODE is the instruction opcode.
+ MASK is the opcode mask; this is used to tell the disassembler
+ which bits in the actual opcode must match OPCODE.
+ OPERANDS is the list of operands.
+
+ The disassembler reads the table in order and prints the first
+ instruction which matches, so this table is sorted to put more
+ specific instructions before more general instructions. It is also
+ sorted by major opcode. */
+
+const struct mn10200_opcode mn10200_opcodes[] = {
+{ "mov", 0x8000, 0xf000, FMT_2, {SIMM8, DN01}},
+{ "mov", 0x80, 0xf0, FMT_1, {DN1, DM0}},
+{ "mov", 0xf230, 0xfff0, FMT_4, {DM1, AN0}},
+{ "mov", 0xf2f0, 0xfff0, FMT_4, {AN1, DM0}},
+{ "mov", 0xf270, 0xfff0, FMT_4, {AN1, AM0}},
+{ "mov", 0xf3f0, 0xfffc, FMT_4, {PSW, DN0}},
+{ "mov", 0xf3d0, 0xfff3, FMT_4, {DN1, PSW}},
+{ "mov", 0xf3e0, 0xfffc, FMT_4, {MDR, DN0}},
+{ "mov", 0xf3c0, 0xfff3, FMT_4, {DN1, MDR}},
+{ "mov", 0x20, 0xf0, FMT_1, {MEM(AN1), DM0}},
+{ "mov", 0x6000, 0xf000, FMT_2, {MEM2(SD8, AN1), DM0}},
+{ "mov", 0xf7c00000, 0xfff00000, FMT_6, {MEM2(SD16, AN1), DM0}},
+{ "mov", 0xf4800000, 0xfff00000, FMT_7, {MEM2(IMM24,AN1), DM0}},
+{ "mov", 0xf140, 0xffc0, FMT_4, {MEM2(DI, AN1), DM0}},
+{ "mov", 0xc80000, 0xfc0000, FMT_3, {MEM(IMM16_MEM), DN0}},
+{ "mov", 0xf4c00000, 0xfffc0000, FMT_7, {MEM(IMM24_MEM), DN0}},
+{ "mov", 0x7000, 0xf000, FMT_2, {MEM2(SD8,AN1), AM0}},
+{ "mov", 0x7000, 0xf000, FMT_2, {MEM(AN1), AM0}},
+{ "mov", 0xf7b00000, 0xfff00000, FMT_6, {MEM2(SD16, AN1), AM0}},
+{ "mov", 0xf4f00000, 0xfff00000, FMT_7, {MEM2(IMM24,AN1), AM0}},
+{ "mov", 0xf100, 0xffc0, FMT_4, {MEM2(DI, AN1), AM0}},
+{ "mov", 0xf7300000, 0xfffc0000, FMT_6, {MEM(IMM16_MEM), AN0}},
+{ "mov", 0xf4d00000, 0xfffc0000, FMT_7, {MEM(IMM24_MEM), AN0}},
+{ "mov", 0x00, 0xf0, FMT_1, {DM0, MEM(AN1)}},
+{ "mov", 0x4000, 0xf000, FMT_2, {DM0, MEM2(SD8, AN1)}},
+{ "mov", 0xf7800000, 0xfff00000, FMT_6, {DM0, MEM2(SD16, AN1)}},
+{ "mov", 0xf4000000, 0xfff00000, FMT_7, {DM0, MEM2(IMM24, AN1)}},
+{ "mov", 0xf1c0, 0xffc0, FMT_4, {DM0, MEM2(DI, AN1)}},
+{ "mov", 0xc00000, 0xfc0000, FMT_3, {DN0, MEM(IMM16_MEM)}},
+{ "mov", 0xf4400000, 0xfffc0000, FMT_7, {DN0, MEM(IMM24_MEM)}},
+{ "mov", 0x5000, 0xf000, FMT_2, {AM0, MEM2(SD8, AN1)}},
+{ "mov", 0x5000, 0xf000, FMT_2, {AM0, MEM(AN1)}},
+{ "mov", 0xf7a00000, 0xfff00000, FMT_6, {AM0, MEM2(SD16, AN1)}},
+{ "mov", 0xf4100000, 0xfff00000, FMT_7, {AM0, MEM2(IMM24,AN1)}},
+{ "mov", 0xf180, 0xffc0, FMT_4, {AM0, MEM2(DI, AN1)}},
+{ "mov", 0xf7200000, 0xfffc0000, FMT_6, {AN0, MEM(IMM16_MEM)}},
+{ "mov", 0xf4500000, 0xfffc0000, FMT_7, {AN0, MEM(IMM24_MEM)}},
+{ "mov", 0xf80000, 0xfc0000, FMT_3, {SIMM16, DN0}},
+{ "mov", 0xf4700000, 0xfffc0000, FMT_7, {IMM24, DN0}},
+{ "mov", 0xdc0000, 0xfc0000, FMT_3, {IMM16, AN0}},
+{ "mov", 0xf4740000, 0xfffc0000, FMT_7, {IMM24, AN0}},
+
+{ "movx", 0xf57000, 0xfff000, FMT_5, {MEM2(SD8, AN1), DM0}},
+{ "movx", 0xf7700000, 0xfff00000, FMT_6, {MEM2(SD16, AN1), DM0}},
+{ "movx", 0xf4b00000, 0xfff00000, FMT_7, {MEM2(IMM24,AN1), DM0}},
+{ "movx", 0xf55000, 0xfff000, FMT_5, {DM0, MEM2(SD8, AN1)}},
+{ "movx", 0xf7600000, 0xfff00000, FMT_6, {DM0, MEM2(SD16, AN1)}},
+{ "movx", 0xf4300000, 0xfff00000, FMT_7, {DM0, MEM2(IMM24, AN1)}},
+
+{ "movb", 0xf52000, 0xfff000, FMT_5, {MEM2(SD8, AN1), DM0}},
+{ "movb", 0xf7d00000, 0xfff00000, FMT_6, {MEM2(SD16, AN1), DM0}},
+{ "movb", 0xf4a00000, 0xfff00000, FMT_7, {MEM2(IMM24,AN1), DM0}},
+{ "movb", 0xf040, 0xffc0, FMT_4, {MEM2(DI, AN1), DM0}},
+{ "movb", 0xf4c40000, 0xfffc0000, FMT_7, {MEM(IMM24_MEM), DN0}},
+{ "movb", 0x10, 0xf0, FMT_1, {DM0, MEM(AN1)}},
+{ "movb", 0xf51000, 0xfff000, FMT_5, {DM0, MEM2(SD8, AN1)}},
+{ "movb", 0xf7900000, 0xfff00000, FMT_6, {DM0, MEM2(SD16, AN1)}},
+{ "movb", 0xf4200000, 0xfff00000, FMT_7, {DM0, MEM2(IMM24, AN1)}},
+{ "movb", 0xf0c0, 0xffc0, FMT_4, {DM0, MEM2(DI, AN1)}},
+{ "movb", 0xc40000, 0xfc0000, FMT_3, {DN0, MEM(IMM16_MEM)}},
+{ "movb", 0xf4440000, 0xfffc0000, FMT_7, {DN0, MEM(IMM24_MEM)}},
+
+{ "movbu", 0x30, 0xf0, FMT_1, {MEM(AN1), DM0}},
+{ "movbu", 0xf53000, 0xfff000, FMT_5, {MEM2(SD8, AN1), DM0}},
+{ "movbu", 0xf7500000, 0xfff00000, FMT_6, {MEM2(SD16, AN1), DM0}},
+{ "movbu", 0xf4900000, 0xfff00000, FMT_7, {MEM2(IMM24,AN1), DM0}},
+{ "movbu", 0xf080, 0xffc0, FMT_4, {MEM2(DI, AN1), DM0}},
+{ "movbu", 0xcc0000, 0xfc0000, FMT_3, {MEM(IMM16_MEM), DN0}},
+{ "movbu", 0xf4c80000, 0xfffc0000, FMT_7, {MEM(IMM24_MEM), DN0}},
+
+{ "ext", 0xf3c1, 0xfff3, FMT_4, {DN1}},
+{ "extx", 0xb0, 0xfc, FMT_1, {DN0}},
+{ "extxu", 0xb4, 0xfc, FMT_1, {DN0}},
+{ "extxb", 0xb8, 0xfc, FMT_1, {DN0}},
+{ "extxbu", 0xbc, 0xfc, FMT_1, {DN0}},
+
+{ "add", 0x90, 0xf0, FMT_1, {DN1, DM0}},
+{ "add", 0xf200, 0xfff0, FMT_4, {DM1, AN0}},
+{ "add", 0xf2c0, 0xfff0, FMT_4, {AN1, DM0}},
+{ "add", 0xf240, 0xfff0, FMT_4, {AN1, AM0}},
+{ "add", 0xd400, 0xfc00, FMT_2, {SIMM8, DN0}},
+{ "add", 0xf7180000, 0xfffc0000, FMT_6, {SIMM16, DN0}},
+{ "add", 0xf4600000, 0xfffc0000, FMT_7, {IMM24, DN0}},
+{ "add", 0xd000, 0xfc00, FMT_2, {SIMM8, AN0}},
+{ "add", 0xf7080000, 0xfffc0000, FMT_6, {SIMM16, AN0}},
+{ "add", 0xf4640000, 0xfffc0000, FMT_7, {IMM24, AN0}},
+{ "addc", 0xf280, 0xfff0, FMT_4, {DN1, DM0}},
+{ "addnf", 0xf50c00, 0xfffc00, FMT_5, {SIMM8, AN0}},
+
+{ "sub", 0xa0, 0xf0, FMT_1, {DN1, DM0}},
+{ "sub", 0xf210, 0xfff0, FMT_4, {DN1, AN0}},
+{ "sub", 0xf2d0, 0xfff0, FMT_4, {AN1, DM0}},
+{ "sub", 0xf250, 0xfff0, FMT_4, {AN1, AM0}},
+{ "sub", 0xf71c0000, 0xfffc0000, FMT_6, {IMM16, DN0}},
+{ "sub", 0xf4680000, 0xfffc0000, FMT_7, {IMM24, DN0}},
+{ "sub", 0xf70c0000, 0xfffc0000, FMT_6, {IMM16, AN0}},
+{ "sub", 0xf46c0000, 0xfffc0000, FMT_7, {IMM24, AN0}},
+{ "subc", 0xf290, 0xfff0, FMT_4, {DN1, DM0}},
+
+{ "mul", 0xf340, 0xfff0, FMT_4, {DN1, DM0}},
+{ "mulu", 0xf350, 0xfff0, FMT_4, {DN1, DM0}},
+
+{ "divu", 0xf360, 0xfff0, FMT_4, {DN1, DM0}},
+
+{ "cmp", 0xf390, 0xfff0, FMT_4, {DN1, DM0}},
+{ "cmp", 0xf220, 0xfff0, FMT_4, {DM1, AN0}},
+{ "cmp", 0xf2e0, 0xfff0, FMT_4, {AN1, DM0}},
+{ "cmp", 0xf260, 0xfff0, FMT_4, {AN1, AM0}},
+{ "cmp", 0xd800, 0xfc00, FMT_2, {SIMM8, DN0}},
+{ "cmp", 0xf7480000, 0xfffc0000, FMT_6, {SIMM16, DN0}},
+{ "cmp", 0xf4780000, 0xfffc0000, FMT_7, {IMM24, DN0}},
+{ "cmp", 0xec0000, 0xfc0000, FMT_3, {IMM16, AN0}},
+{ "cmp", 0xf47c0000, 0xfffc0000, FMT_7, {IMM24, AN0}},
+
+{ "and", 0xf300, 0xfff0, FMT_4, {DN1, DM0}},
+{ "and", 0xf50000, 0xfffc00, FMT_5, {IMM8, DN0}},
+{ "and", 0xf7000000, 0xfffc0000, FMT_6, {SIMM16N, DN0}},
+{ "and", 0xf7100000, 0xffff0000, FMT_6, {SIMM16N, PSW}},
+{ "or", 0xf310, 0xfff0, FMT_4, {DN1, DM0}},
+{ "or", 0xf50800, 0xfffc00, FMT_5, {IMM8, DN0}},
+{ "or", 0xf7400000, 0xfffc0000, FMT_6, {SIMM16N, DN0}},
+{ "or", 0xf7140000, 0xffff0000, FMT_6, {SIMM16N, PSW}},
+{ "xor", 0xf320, 0xfff0, FMT_4, {DN1, DM0}},
+{ "xor", 0xf74c0000, 0xfffc0000, FMT_6, {SIMM16N, DN0}},
+{ "not", 0xf3e4, 0xfffc, FMT_4, {DN0}},
+
+{ "asr", 0xf338, 0xfffc, FMT_4, {DN0}},
+{ "lsr", 0xf33c, 0xfffc, FMT_4, {DN0}},
+{ "ror", 0xf334, 0xfffc, FMT_4, {DN0}},
+{ "rol", 0xf330, 0xfffc, FMT_4, {DN0}},
+
+{ "btst", 0xf50400, 0xfffc00, FMT_5, {IMM8, DN0}},
+{ "btst", 0xf7040000, 0xfffc0000, FMT_6, {SIMM16N, DN0}},
+{ "bset", 0xf020, 0xfff0, FMT_4, {DM0, MEM(AN1)}},
+{ "bclr", 0xf030, 0xfff0, FMT_4, {DM0, MEM(AN1)}},
+
+{ "beq", 0xe800, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bne", 0xe900, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "blt", 0xe000, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "ble", 0xe300, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bge", 0xe200, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bgt", 0xe100, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bcs", 0xe400, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bls", 0xe700, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bcc", 0xe600, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bhi", 0xe500, 0xff00, FMT_2, {SD8N_PCREL}},
+{ "bvc", 0xf5fc00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bvs", 0xf5fd00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bnc", 0xf5fe00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bns", 0xf5ff00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bra", 0xea00, 0xff00, FMT_2, {SD8N_PCREL}},
+
+{ "beqx", 0xf5e800, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bnex", 0xf5e900, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bltx", 0xf5e000, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "blex", 0xf5e300, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bgex", 0xf5e200, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bgtx", 0xf5e100, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bcsx", 0xf5e400, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "blsx", 0xf5e700, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bccx", 0xf5e600, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bhix", 0xf5e500, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bvcx", 0xf5ec00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bvsx", 0xf5ed00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bncx", 0xf5ee00, 0xffff00, FMT_5, {SD8N_PCREL}},
+{ "bnsx", 0xf5ef00, 0xffff00, FMT_5, {SD8N_PCREL}},
+
+{ "jmp", 0xfc0000, 0xff0000, FMT_3, {IMM16_PCREL}},
+{ "jmp", 0xf4e00000, 0xffff0000, FMT_7, {IMM24_PCREL}},
+{ "jmp", 0xf000, 0xfff3, FMT_4, {PAREN,AN1,PAREN}},
+{ "jsr", 0xfd0000, 0xff0000, FMT_3, {IMM16_PCREL}},
+{ "jsr", 0xf4e10000, 0xffff0000, FMT_7, {IMM24_PCREL}},
+{ "jsr", 0xf001, 0xfff3, FMT_4, {PAREN,AN1,PAREN}},
+
+{ "nop", 0xf6, 0xff, FMT_1, {UNUSED}},
+
+{ "rts", 0xfe, 0xff, FMT_1, {UNUSED}},
+{ "rti", 0xeb, 0xff, FMT_1, {UNUSED}},
+
+/* Extension. We need some instruction to trigger "emulated syscalls"
+ for our simulator. */
+{ "syscall", 0xf010, 0xffff, FMT_4, {UNUSED}},
+
+/* Extension. When talking to the simulator, gdb requires some instruction
+ that will trigger a "breakpoint" (really just an instruction that isn't
+ otherwise used by the tools. This instruction must be the same size
+ as the smallest instruction on the target machine. In the case of the
+ mn10x00 the "break" instruction must be one byte. 0xff is available on
+ both mn10x00 architectures. */
+{ "break", 0xff, 0xff, FMT_1, {UNUSED}},
+
+{ 0, 0, 0, 0, {0}},
+
+} ;
+
+const int mn10200_num_opcodes =
+ sizeof (mn10200_opcodes) / sizeof (mn10200_opcodes[0]);
+
+
diff --git a/opcodes/m10300-dis.c b/opcodes/m10300-dis.c
new file mode 100644
index 00000000000..415bffce37d
--- /dev/null
+++ b/opcodes/m10300-dis.c
@@ -0,0 +1,548 @@
+/* Disassemble MN10300 instructions.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <stdio.h>
+
+#include "ansidecl.h"
+#include "opcode/mn10300.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
+ unsigned long insn, unsigned int));
+
+int
+print_insn_mn10300 (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int status;
+ bfd_byte buffer[4];
+ unsigned long insn;
+ unsigned int consume;
+
+ /* First figure out how big the opcode is. */
+ status = (*info->read_memory_func) (memaddr, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = *(unsigned char *) buffer;
+
+ /* These are one byte insns. */
+ if ((insn & 0xf3) == 0x00
+ || (insn & 0xf0) == 0x10
+ || (insn & 0xfc) == 0x3c
+ || (insn & 0xf3) == 0x41
+ || (insn & 0xf3) == 0x40
+ || (insn & 0xfc) == 0x50
+ || (insn & 0xfc) == 0x54
+ || (insn & 0xf0) == 0x60
+ || (insn & 0xf0) == 0x70
+ || ((insn & 0xf0) == 0x80
+ && (insn & 0x0c) >> 2 != (insn & 0x03))
+ || ((insn & 0xf0) == 0x90
+ && (insn & 0x0c) >> 2 != (insn & 0x03))
+ || ((insn & 0xf0) == 0xa0
+ && (insn & 0x0c) >> 2 != (insn & 0x03))
+ || ((insn & 0xf0) == 0xb0
+ && (insn & 0x0c) >> 2 != (insn & 0x03))
+ || (insn & 0xff) == 0xcb
+ || (insn & 0xfc) == 0xd0
+ || (insn & 0xfc) == 0xd4
+ || (insn & 0xfc) == 0xd8
+ || (insn & 0xf0) == 0xe0
+ || (insn & 0xff) == 0xff)
+ {
+ consume = 1;
+ }
+
+ /* These are two byte insns. */
+ else if ((insn & 0xf0) == 0x80
+ || (insn & 0xf0) == 0x90
+ || (insn & 0xf0) == 0xa0
+ || (insn & 0xf0) == 0xb0
+ || (insn & 0xfc) == 0x20
+ || (insn & 0xfc) == 0x28
+ || (insn & 0xf3) == 0x43
+ || (insn & 0xf3) == 0x42
+ || (insn & 0xfc) == 0x58
+ || (insn & 0xfc) == 0x5c
+ || ((insn & 0xf0) == 0xc0
+ && (insn & 0xff) != 0xcb
+ && (insn & 0xff) != 0xcc
+ && (insn & 0xff) != 0xcd)
+ || (insn & 0xff) == 0xf0
+ || (insn & 0xff) == 0xf1
+ || (insn & 0xff) == 0xf2
+ || (insn & 0xff) == 0xf3
+ || (insn & 0xff) == 0xf4
+ || (insn & 0xff) == 0xf5
+ || (insn & 0xff) == 0xf6)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb16 (buffer);
+ consume = 2;
+ }
+
+ /* These are three byte insns. */
+ else if ((insn & 0xff) == 0xf8
+ || (insn & 0xff) == 0xcc
+ || (insn & 0xff) == 0xf9
+ || (insn & 0xf3) == 0x01
+ || (insn & 0xf3) == 0x02
+ || (insn & 0xf3) == 0x03
+ || (insn & 0xfc) == 0x24
+ || (insn & 0xfc) == 0x2c
+ || (insn & 0xfc) == 0x30
+ || (insn & 0xfc) == 0x34
+ || (insn & 0xfc) == 0x38
+ || (insn & 0xff) == 0xde
+ || (insn & 0xff) == 0xdf
+ || (insn & 0xff) == 0xcc)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb16 (buffer);
+ insn <<= 8;
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn |= *(unsigned char *)buffer;
+ consume = 3;
+ }
+
+ /* These are four byte insns. */
+ else if ((insn & 0xff) == 0xfa
+ || (insn & 0xff) == 0xfb)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb32 (buffer);
+ consume = 4;
+ }
+
+ /* These are five byte insns. */
+ else if ((insn & 0xff) == 0xcd
+ || (insn & 0xff) == 0xdc)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ insn = bfd_getb32 (buffer);
+ consume = 5;
+ }
+
+ /* These are six byte insns. */
+ else if ((insn & 0xff) == 0xfd
+ || (insn & 0xff) == 0xfc)
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ insn = bfd_getb32 (buffer);
+ consume = 6;
+ }
+
+ /* Else its a seven byte insns (in theory). */
+ else
+ {
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ insn = bfd_getb32 (buffer);
+ consume = 7;
+ }
+
+ disassemble (memaddr, info, insn, consume);
+
+ return consume;
+}
+
+static void
+disassemble (memaddr, info, insn, size)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+ unsigned long insn;
+ unsigned int size;
+{
+ struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
+ const struct mn10300_operand *operand;
+ bfd_byte buffer[4];
+ unsigned long extension = 0;
+ int status, match = 0;
+
+ /* Find the opcode. */
+ while (op->name)
+ {
+ int mysize, extra_shift;
+
+ if (op->format == FMT_S0)
+ mysize = 1;
+ else if (op->format == FMT_S1
+ || op->format == FMT_D0)
+ mysize = 2;
+ else if (op->format == FMT_S2
+ || op->format == FMT_D1)
+ mysize = 3;
+ else if (op->format == FMT_S4)
+ mysize = 5;
+ else if (op->format == FMT_D2)
+ mysize = 4;
+ else if (op->format == FMT_D4)
+ mysize = 6;
+ else
+ mysize = 7;
+
+ if ((op->mask & insn) == op->opcode
+ && size == (unsigned int) mysize
+ && (op->machine == 0
+ || op->machine == info->mach))
+ {
+ const unsigned char *opindex_ptr;
+ unsigned int nocomma;
+ int paren = 0;
+
+ if (op->format == FMT_D1 || op->format == FMT_S1)
+ extra_shift = 8;
+ else if (op->format == FMT_D2 || op->format == FMT_D4
+ || op->format == FMT_S2 || op->format == FMT_S4
+ || op->format == FMT_S6 || op->format == FMT_D5)
+ extra_shift = 16;
+ else
+ extra_shift = 0;
+
+ if (size == 1 || size == 2)
+ {
+ extension = 0;
+ }
+ else if (size == 3
+ && (op->format == FMT_D1
+ || op->opcode == 0xdf0000
+ || op->opcode == 0xde0000))
+ {
+ extension = 0;
+ }
+ else if (size == 3)
+ {
+ insn &= 0xff0000;
+ status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+
+ insn |= bfd_getl16 (buffer);
+ extension = 0;
+ }
+ else if (size == 4
+ && (op->opcode == 0xfaf80000
+ || op->opcode == 0xfaf00000
+ || op->opcode == 0xfaf40000))
+ {
+ extension = 0;
+ }
+ else if (size == 4)
+ {
+ insn &= 0xffff0000;
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+
+ insn |= bfd_getl16 (buffer);
+ extension = 0;
+ }
+ else if (size == 5 && op->opcode == 0xdc000000)
+ {
+ unsigned long temp = 0;
+ status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ temp |= bfd_getl32 (buffer);
+
+ insn &= 0xff000000;
+ insn |= (temp & 0xffffff00) >> 8;
+ extension = temp & 0xff;
+ }
+ else if (size == 5)
+ {
+ unsigned long temp = 0;
+ status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ temp |= bfd_getl16 (buffer);
+
+ insn &= 0xff0000ff;
+ insn |= temp << 8;
+
+ status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ extension = *(unsigned char *)buffer;
+ }
+ else if (size == 6)
+ {
+ unsigned long temp = 0;
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ temp |= bfd_getl32 (buffer);
+
+ insn &= 0xffff0000;
+ insn |= (temp >> 16) & 0xffff;
+ extension = temp & 0xffff;
+ }
+ else if (size == 7 && op->opcode == 0xdd000000)
+ {
+ unsigned long temp = 0;
+ status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ temp |= bfd_getl32 (buffer);
+
+ insn &= 0xff000000;
+ insn |= (temp >> 8) & 0xffffff;
+ extension = (temp & 0xff) << 16;
+
+ status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ extension |= bfd_getb16 (buffer);
+ }
+ else if (size == 7)
+ {
+ unsigned long temp = 0;
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ temp |= bfd_getl32 (buffer);
+
+ insn &= 0xffff0000;
+ insn |= (temp >> 16) & 0xffff;
+ extension = (temp & 0xffff) << 8;
+
+ status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ extension |= *(unsigned char *)buffer;
+ }
+
+ match = 1;
+ (*info->fprintf_func) (info->stream, "%s\t", op->name);
+
+ /* Now print the operands. */
+ for (opindex_ptr = op->operands, nocomma = 1;
+ *opindex_ptr != 0;
+ opindex_ptr++)
+ {
+ unsigned long value;
+
+ operand = &mn10300_operands[*opindex_ptr];
+
+
+ if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
+ {
+ unsigned long temp;
+ value = insn & ((1 << operand->bits) - 1);
+ value <<= (32 - operand->bits);
+ temp = extension >> operand->shift;
+ temp &= ((1 << (32 - operand->bits)) - 1);
+ value |= temp;
+ }
+ else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
+ {
+ value = ((extension >> (operand->shift))
+ & ((1 << operand->bits) - 1));
+ }
+ else
+ {
+ value = ((insn >> (operand->shift))
+ & ((1 << operand->bits) - 1));
+ }
+
+ if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
+ )
+ value = ((long)(value << (32 - operand->bits))
+ >> (32 - operand->bits));
+
+ if (!nocomma
+ && (!paren
+ || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
+ (*info->fprintf_func) (info->stream, ",");
+
+ nocomma = 0;
+
+ if ((operand->flags & MN10300_OPERAND_DREG) != 0)
+ {
+ value = ((insn >> (operand->shift + extra_shift))
+ & ((1 << operand->bits) - 1));
+ (*info->fprintf_func) (info->stream, "d%d", value);
+ }
+
+ else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
+ {
+ value = ((insn >> (operand->shift + extra_shift))
+ & ((1 << operand->bits) - 1));
+ (*info->fprintf_func) (info->stream, "a%d", value);
+ }
+
+ else if ((operand->flags & MN10300_OPERAND_SP) != 0)
+ (*info->fprintf_func) (info->stream, "sp");
+
+ else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
+ (*info->fprintf_func) (info->stream, "psw");
+
+ else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
+ (*info->fprintf_func) (info->stream, "mdr");
+
+
+ else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
+ {
+ if (paren)
+ (*info->fprintf_func) (info->stream, ")");
+ else
+ {
+ (*info->fprintf_func) (info->stream, "(");
+ nocomma = 1;
+ }
+ paren = !paren;
+ }
+
+ else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
+ (*info->print_address_func) ((long) value + memaddr, info);
+
+ else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
+ (*info->print_address_func) (value, info);
+
+ else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
+ {
+ int comma = 0;
+
+ (*info->fprintf_func) (info->stream, "[");
+ if (value & 0x80)
+ {
+ (*info->fprintf_func) (info->stream, "d2");
+ comma = 1;
+ }
+
+ if (value & 0x40)
+ {
+ if (comma)
+ (*info->fprintf_func) (info->stream, ",");
+ (*info->fprintf_func) (info->stream, "d3");
+ comma = 1;
+ }
+
+ if (value & 0x20)
+ {
+ if (comma)
+ (*info->fprintf_func) (info->stream, ",");
+ (*info->fprintf_func) (info->stream, "a2");
+ comma = 1;
+ }
+
+ if (value & 0x10)
+ {
+ if (comma)
+ (*info->fprintf_func) (info->stream, ",");
+ (*info->fprintf_func) (info->stream, "a3");
+ comma = 1;
+ }
+
+ if (value & 0x08)
+ {
+ if (comma)
+ (*info->fprintf_func) (info->stream, ",");
+ (*info->fprintf_func) (info->stream, "other");
+ comma = 1;
+ }
+
+ (*info->fprintf_func) (info->stream, "]");
+ }
+
+ else
+ (*info->fprintf_func) (info->stream, "%d", value);
+ }
+ /* All done. */
+ break;
+ }
+ op++;
+ }
+
+ if (!match)
+ {
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream, _("unknown\t0x%04x"), insn);
+ }
+}
diff --git a/opcodes/m10300-opc.c b/opcodes/m10300-opc.c
new file mode 100644
index 00000000000..8d0c0f3f8a1
--- /dev/null
+++ b/opcodes/m10300-opc.c
@@ -0,0 +1,683 @@
+/* Assemble Matsushita MN10300 instructions.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This file is formatted at > 80 columns. Attempting to read it on a
+ screeen with less than 80 columns will be difficult. */
+#include "ansidecl.h"
+#include "opcode/mn10300.h"
+
+
+const struct mn10300_operand mn10300_operands[] = {
+#define UNUSED 0
+ {0, 0, 0},
+
+/* dn register in the first register operand position. */
+#define DN0 (UNUSED+1)
+ {2, 0, MN10300_OPERAND_DREG},
+
+/* dn register in the second register operand position. */
+#define DN1 (DN0+1)
+ {2, 2, MN10300_OPERAND_DREG},
+
+/* dn register in the third register operand position. */
+#define DN2 (DN1+1)
+ {2, 4, MN10300_OPERAND_DREG},
+
+/* dm register in the first register operand position. */
+#define DM0 (DN2+1)
+ {2, 0, MN10300_OPERAND_DREG},
+
+/* dm register in the second register operand position. */
+#define DM1 (DM0+1)
+ {2, 2, MN10300_OPERAND_DREG},
+
+/* dm register in the third register operand position. */
+#define DM2 (DM1+1)
+ {2, 4, MN10300_OPERAND_DREG},
+
+/* an register in the first register operand position. */
+#define AN0 (DM2+1)
+ {2, 0, MN10300_OPERAND_AREG},
+
+/* an register in the second register operand position. */
+#define AN1 (AN0+1)
+ {2, 2, MN10300_OPERAND_AREG},
+
+/* an register in the third register operand position. */
+#define AN2 (AN1+1)
+ {2, 4, MN10300_OPERAND_AREG},
+
+/* am register in the first register operand position. */
+#define AM0 (AN2+1)
+ {2, 0, MN10300_OPERAND_AREG},
+
+/* am register in the second register operand position. */
+#define AM1 (AM0+1)
+ {2, 2, MN10300_OPERAND_AREG},
+
+/* am register in the third register operand position. */
+#define AM2 (AM1+1)
+ {2, 4, MN10300_OPERAND_AREG},
+
+/* 8 bit unsigned immediate which may promote to a 16bit
+ unsigned immediate. */
+#define IMM8 (AM2+1)
+ {8, 0, MN10300_OPERAND_PROMOTE},
+
+/* 16 bit unsigned immediate which may promote to a 32bit
+ unsigned immediate. */
+#define IMM16 (IMM8+1)
+ {16, 0, MN10300_OPERAND_PROMOTE},
+
+/* 16 bit pc-relative immediate which may promote to a 16bit
+ pc-relative immediate. */
+#define IMM16_PCREL (IMM16+1)
+ {16, 0, MN10300_OPERAND_PCREL | MN10300_OPERAND_RELAX | MN10300_OPERAND_SIGNED},
+
+/* 16bit unsigned dispacement in a memory operation which
+ may promote to a 32bit displacement. */
+#define IMM16_MEM (IMM16_PCREL+1)
+ {16, 0, MN10300_OPERAND_PROMOTE | MN10300_OPERAND_MEMADDR},
+
+/* 32bit immediate, high 16 bits in the main instruction
+ word, 16bits in the extension word.
+
+ The "bits" field indicates how many bits are in the
+ main instruction word for MN10300_OPERAND_SPLIT! */
+#define IMM32 (IMM16_MEM+1)
+ {16, 0, MN10300_OPERAND_SPLIT},
+
+/* 32bit pc-relative offset. */
+#define IMM32_PCREL (IMM32+1)
+ {16, 0, MN10300_OPERAND_SPLIT | MN10300_OPERAND_PCREL},
+
+/* 32bit memory offset. */
+#define IMM32_MEM (IMM32_PCREL+1)
+ {16, 0, MN10300_OPERAND_SPLIT | MN10300_OPERAND_MEMADDR},
+
+/* 32bit immediate, high 16 bits in the main instruction
+ word, 16bits in the extension word, low 16bits are left
+ shifted 8 places.
+
+ The "bits" field indicates how many bits are in the
+ main instruction word for MN10300_OPERAND_SPLIT! */
+#define IMM32_LOWSHIFT8 (IMM32_MEM+1)
+ {16, 8, MN10300_OPERAND_SPLIT | MN10300_OPERAND_MEMADDR},
+
+/* 32bit immediate, high 24 bits in the main instruction
+ word, 8 in the extension word.
+
+ The "bits" field indicates how many bits are in the
+ main instruction word for MN10300_OPERAND_SPLIT! */
+#define IMM32_HIGH24 (IMM32_LOWSHIFT8+1)
+ {24, 0, MN10300_OPERAND_SPLIT | MN10300_OPERAND_PCREL},
+
+/* 32bit immediate, high 24 bits in the main instruction
+ word, 8 in the extension word, low 8 bits are left
+ shifted 16 places.
+
+ The "bits" field indicates how many bits are in the
+ main instruction word for MN10300_OPERAND_SPLIT! */
+#define IMM32_HIGH24_LOWSHIFT16 (IMM32_HIGH24+1)
+ {24, 16, MN10300_OPERAND_SPLIT | MN10300_OPERAND_PCREL},
+
+/* Stack pointer. */
+#define SP (IMM32_HIGH24_LOWSHIFT16+1)
+ {8, 0, MN10300_OPERAND_SP},
+
+/* Processor status word. */
+#define PSW (SP+1)
+ {0, 0, MN10300_OPERAND_PSW},
+
+/* MDR register. */
+#define MDR (PSW+1)
+ {0, 0, MN10300_OPERAND_MDR},
+
+/* Index register. */
+#define DI (MDR+1)
+ {2, 2, MN10300_OPERAND_DREG},
+
+/* 8 bit signed displacement, may promote to 16bit signed dispacement. */
+#define SD8 (DI+1)
+ {8, 0, MN10300_OPERAND_SIGNED | MN10300_OPERAND_PROMOTE},
+
+/* 16 bit signed displacement, may promote to 32bit dispacement. */
+#define SD16 (SD8+1)
+ {16, 0, MN10300_OPERAND_SIGNED | MN10300_OPERAND_PROMOTE},
+
+/* 8 bit signed displacement that can not promote. */
+#define SD8N (SD16+1)
+ {8, 0, MN10300_OPERAND_SIGNED},
+
+/* 8 bit pc-relative displacement. */
+#define SD8N_PCREL (SD8N+1)
+ {8, 0, MN10300_OPERAND_SIGNED | MN10300_OPERAND_PCREL | MN10300_OPERAND_RELAX},
+
+/* 8 bit signed displacement shifted left 8 bits in the instruction. */
+#define SD8N_SHIFT8 (SD8N_PCREL+1)
+ {8, 8, MN10300_OPERAND_SIGNED},
+
+/* 8 bit signed immediate which may promote to 16bit signed immediate. */
+#define SIMM8 (SD8N_SHIFT8+1)
+ {8, 0, MN10300_OPERAND_SIGNED | MN10300_OPERAND_PROMOTE},
+
+/* 16 bit signed immediate which may promote to 32bit immediate. */
+#define SIMM16 (SIMM8+1)
+ {16, 0, MN10300_OPERAND_SIGNED | MN10300_OPERAND_PROMOTE},
+
+/* Either an open paren or close paren. */
+#define PAREN (SIMM16+1)
+ {0, 0, MN10300_OPERAND_PAREN},
+
+/* dn register that appears in the first and second register positions. */
+#define DN01 (PAREN+1)
+ {2, 0, MN10300_OPERAND_DREG | MN10300_OPERAND_REPEATED},
+
+/* an register that appears in the first and second register positions. */
+#define AN01 (DN01+1)
+ {2, 0, MN10300_OPERAND_AREG | MN10300_OPERAND_REPEATED},
+
+/* 16bit pc-relative displacement which may promote to 32bit pc-relative
+ displacement. */
+#define D16_SHIFT (AN01+1)
+ {16, 8, MN10300_OPERAND_PCREL | MN10300_OPERAND_RELAX | MN10300_OPERAND_SIGNED},
+
+/* 8 bit immediate found in the extension word. */
+#define IMM8E (D16_SHIFT+1)
+ {8, 0, MN10300_OPERAND_EXTENDED},
+
+/* Register list found in the extension word shifted 8 bits left. */
+#define REGSE_SHIFT8 (IMM8E+1)
+ {8, 8, MN10300_OPERAND_EXTENDED | MN10300_OPERAND_REG_LIST},
+
+/* Register list shifted 8 bits left. */
+#define REGS_SHIFT8 (REGSE_SHIFT8 + 1)
+ {8, 8, MN10300_OPERAND_REG_LIST},
+
+/* Reigster list. */
+#define REGS (REGS_SHIFT8+1)
+ {8, 0, MN10300_OPERAND_REG_LIST},
+
+
+} ;
+
+#define MEM(ADDR) PAREN, ADDR, PAREN
+#define MEMINC(ADDR) PAREN, ADDR, PLUS, PAREN
+#define MEMINC2(ADDR,INC) PAREN, ADDR, PLUS, INC, PAREN
+#define MEM2(ADDR1,ADDR2) PAREN, ADDR1, ADDR2, PAREN
+
+/* The opcode table.
+
+ The format of the opcode table is:
+
+ NAME OPCODE MASK MATCH_MASK, FORMAT, PROCESSOR { OPERANDS }
+
+ NAME is the name of the instruction.
+ OPCODE is the instruction opcode.
+ MASK is the opcode mask; this is used to tell the disassembler
+ which bits in the actual opcode must match OPCODE.
+ OPERANDS is the list of operands.
+
+ The disassembler reads the table in order and prints the first
+ instruction which matches, so this table is sorted to put more
+ specific instructions before more general instructions. It is also
+ sorted by major opcode. */
+
+const struct mn10300_opcode mn10300_opcodes[] = {
+{ "mov", 0x8000, 0xf000, 0, FMT_S1, 0, {SIMM8, DN01}},
+{ "mov", 0x80, 0xf0, 0x3, FMT_S0, 0, {DM1, DN0}},
+{ "mov", 0xf1e0, 0xfff0, 0, FMT_D0, 0, {DM1, AN0}},
+{ "mov", 0xf1d0, 0xfff0, 0, FMT_D0, 0, {AM1, DN0}},
+{ "mov", 0x9000, 0xf000, 0, FMT_S1, 0, {IMM8, AN01}},
+{ "mov", 0x90, 0xf0, 0x3, FMT_S0, 0, {AM1, AN0}},
+{ "mov", 0x3c, 0xfc, 0, FMT_S0, 0, {SP, AN0}},
+{ "mov", 0xf2f0, 0xfff3, 0, FMT_D0, 0, {AM1, SP}},
+{ "mov", 0xf2e4, 0xfffc, 0, FMT_D0, 0, {PSW, DN0}},
+{ "mov", 0xf2f3, 0xfff3, 0, FMT_D0, 0, {DM1, PSW}},
+{ "mov", 0xf2e0, 0xfffc, 0, FMT_D0, 0, {MDR, DN0}},
+{ "mov", 0xf2f2, 0xfff3, 0, FMT_D0, 0, {DM1, MDR}},
+{ "mov", 0x70, 0xf0, 0, FMT_S0, 0, {MEM(AM0), DN1}},
+{ "mov", 0x5800, 0xfcff, 0, FMT_S1, 0, {MEM(SP), DN0}},
+{ "mov", 0x300000, 0xfc0000, 0, FMT_S2, 0, {MEM(IMM16_MEM), DN0}},
+{ "mov", 0xf000, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), AN1}},
+{ "mov", 0x5c00, 0xfcff, 0, FMT_S1, 0, {MEM(SP), AN0}},
+{ "mov", 0xfaa00000, 0xfffc0000, 0, FMT_D2, 0, {MEM(IMM16_MEM), AN0}},
+{ "mov", 0x60, 0xf0, 0, FMT_S0, 0, {DM1, MEM(AN0)}},
+{ "mov", 0x4200, 0xf3ff, 0, FMT_S1, 0, {DM1, MEM(SP)}},
+{ "mov", 0x010000, 0xf30000, 0, FMT_S2, 0, {DM1, MEM(IMM16_MEM)}},
+{ "mov", 0xf010, 0xfff0, 0, FMT_D0, 0, {AM1, MEM(AN0)}},
+{ "mov", 0x4300, 0xf3ff, 0, FMT_S1, 0, {AM1, MEM(SP)}},
+{ "mov", 0xfa800000, 0xfff30000, 0, FMT_D2, 0, {AM1, MEM(IMM16_MEM)}},
+{ "mov", 0x5c00, 0xfc00, 0, FMT_S1, 0, {MEM2(IMM8, SP), AN0}},
+{ "mov", 0xf80000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8, AM0), DN1}},
+{ "mov", 0xfa000000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), DN1}},
+{ "mov", 0x5800, 0xfc00, 0, FMT_S1, 0, {MEM2(IMM8, SP), DN0}},
+{ "mov", 0xfab40000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}},
+{ "mov", 0xf300, 0xffc0, 0, FMT_D0, 0, {MEM2(DI, AM0), DN2}},
+{ "mov", 0xf82000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8,AM0), AN1}},
+{ "mov", 0xfa200000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), AN1}},
+{ "mov", 0xfab00000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), AN0}},
+{ "mov", 0xf380, 0xffc0, 0, FMT_D0, 0, {MEM2(DI, AM0), AN2}},
+{ "mov", 0x4300, 0xf300, 0, FMT_S1, 0, {AM1, MEM2(IMM8, SP)}},
+{ "mov", 0xf81000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}},
+{ "mov", 0xfa100000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}},
+{ "mov", 0x4200, 0xf300, 0, FMT_S1, 0, {DM1, MEM2(IMM8, SP)}},
+{ "mov", 0xfa910000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}},
+{ "mov", 0xf340, 0xffc0, 0, FMT_D0, 0, {DM2, MEM2(DI, AN0)}},
+{ "mov", 0xf83000, 0xfff000, 0, FMT_D1, 0, {AM1, MEM2(SD8, AN0)}},
+{ "mov", 0xfa300000, 0xfff00000, 0, FMT_D2, 0, {AM1, MEM2(SD16, AN0)}},
+{ "mov", 0xfa900000, 0xfff30000, 0, FMT_D2, 0, {AM1, MEM2(IMM16, SP)}},
+{ "mov", 0xf3c0, 0xffc0, 0, FMT_D0, 0, {AM2, MEM2(DI, AN0)}},
+
+/* These must come after most of the other move instructions to avoid matching
+ a symbolic name with IMMxx operands. Ugh. */
+{ "mov", 0x2c0000, 0xfc0000, 0, FMT_S2, 0, {SIMM16, DN0}},
+{ "mov", 0xfccc0000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "mov", 0x240000, 0xfc0000, 0, FMT_S2, 0, {IMM16, AN0}},
+{ "mov", 0xfcdc0000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, AN0}},
+{ "mov", 0xfca40000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}},
+{ "mov", 0xfca00000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), AN0}},
+{ "mov", 0xfc810000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}},
+{ "mov", 0xfc800000, 0xfff30000, 0, FMT_D4, 0, {AM1, MEM(IMM32_MEM)}},
+{ "mov", 0xfc000000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}},
+{ "mov", 0xfcb40000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}},
+{ "mov", 0xfc200000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), AN1}},
+{ "mov", 0xfcb00000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), AN0}},
+{ "mov", 0xfc100000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}},
+{ "mov", 0xfc910000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}},
+{ "mov", 0xfc300000, 0xfff00000, 0, FMT_D4, 0, {AM1, MEM2(IMM32,AN0)}},
+{ "mov", 0xfc900000, 0xfff30000, 0, FMT_D4, 0, {AM1, MEM2(IMM32, SP)}},
+/* These non-promoting variants need to come after all the other memory
+ moves. */
+{ "mov", 0xf8f000, 0xfffc00, 0, FMT_D1, AM30, {MEM2(SD8N, AM0), SP}},
+{ "mov", 0xf8f400, 0xfffc00, 0, FMT_D1, AM30, {SP, MEM2(SD8N, AN0)}},
+
+
+
+{ "movbu", 0xf040, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), DN1}},
+{ "movbu", 0xf84000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8, AM0), DN1}},
+{ "movbu", 0xfa400000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), DN1}},
+{ "movbu", 0xf8b800, 0xfffcff, 0, FMT_D1, 0, {MEM(SP), DN0}},
+{ "movbu", 0xf8b800, 0xfffc00, 0, FMT_D1, 0, {MEM2(IMM8, SP), DN0}},
+{ "movbu", 0xfab80000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}},
+{ "movbu", 0xf400, 0xffc0, 0, FMT_D0, 0, {MEM2(DI, AM0), DN2}},
+{ "movbu", 0x340000, 0xfc0000, 0, FMT_S2, 0, {MEM(IMM16_MEM), DN0}},
+{ "movbu", 0xf050, 0xfff0, 0, FMT_D0, 0, {DM1, MEM(AN0)}},
+{ "movbu", 0xf85000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}},
+{ "movbu", 0xfa500000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}},
+{ "movbu", 0xf89200, 0xfff3ff, 0, FMT_D1, 0, {DM1, MEM(SP)}},
+{ "movbu", 0xf89200, 0xfff300, 0, FMT_D1, 0, {DM1, MEM2(IMM8, SP)}},
+{ "movbu", 0xfa920000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}},
+{ "movbu", 0xf440, 0xffc0, 0, FMT_D0, 0, {DM2, MEM2(DI, AN0)}},
+{ "movbu", 0x020000, 0xf30000, 0, FMT_S2, 0, {DM1, MEM(IMM16_MEM)}},
+{ "movbu", 0xfc400000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}},
+{ "movbu", 0xfcb80000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}},
+{ "movbu", 0xfca80000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}},
+{ "movbu", 0xfc500000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}},
+{ "movbu", 0xfc920000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}},
+{ "movbu", 0xfc820000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}},
+
+{ "movhu", 0xf060, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), DN1}},
+{ "movhu", 0xf86000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8, AM0), DN1}},
+{ "movhu", 0xfa600000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), DN1}},
+{ "movhu", 0xf8bc00, 0xfffcff, 0, FMT_D1, 0, {MEM(SP), DN0}},
+{ "movhu", 0xf8bc00, 0xfffc00, 0, FMT_D1, 0, {MEM2(IMM8, SP), DN0}},
+{ "movhu", 0xfabc0000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}},
+{ "movhu", 0xf480, 0xffc0, 0, FMT_D0, 0, {MEM2(DI, AM0), DN2}},
+{ "movhu", 0x380000, 0xfc0000, 0, FMT_S2, 0, {MEM(IMM16_MEM), DN0}},
+{ "movhu", 0xf070, 0xfff0, 0, FMT_D0, 0, {DM1, MEM(AN0)}},
+{ "movhu", 0xf87000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}},
+{ "movhu", 0xfa700000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}},
+{ "movhu", 0xf89300, 0xfff3ff, 0, FMT_D1, 0, {DM1, MEM(SP)}},
+{ "movhu", 0xf89300, 0xfff300, 0, FMT_D1, 0, {DM1, MEM2(IMM8, SP)}},
+{ "movhu", 0xfa930000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}},
+{ "movhu", 0xf4c0, 0xffc0, 0, FMT_D0, 0, {DM2, MEM2(DI, AN0)}},
+{ "movhu", 0x030000, 0xf30000, 0, FMT_S2, 0, {DM1, MEM(IMM16_MEM)}},
+{ "movhu", 0xfc600000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}},
+{ "movhu", 0xfcbc0000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}},
+{ "movhu", 0xfcac0000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}},
+{ "movhu", 0xfc700000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}},
+{ "movhu", 0xfc930000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}},
+{ "movhu", 0xfc830000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}},
+
+{ "ext", 0xf2d0, 0xfffc, 0, FMT_D0, 0, {DN0}},
+
+{ "extb", 0x10, 0xfc, 0, FMT_S0, 0, {DN0}},
+
+{ "extbu", 0x14, 0xfc, 0, FMT_S0, 0, {DN0}},
+
+{ "exth", 0x18, 0xfc, 0, FMT_S0, 0, {DN0}},
+
+{ "exthu", 0x1c, 0xfc, 0, FMT_S0, 0, {DN0}},
+
+{ "movm", 0xce00, 0xff00, 0, FMT_S1, 0, {MEM(SP), REGS}},
+{ "movm", 0xcf00, 0xff00, 0, FMT_S1, 0, {REGS, MEM(SP)}},
+
+{ "clr", 0x00, 0xf3, 0, FMT_S0, 0, {DN1}},
+
+{ "add", 0xe0, 0xf0, 0, FMT_S0, 0, {DM1, DN0}},
+{ "add", 0xf160, 0xfff0, 0, FMT_D0, 0, {DM1, AN0}},
+{ "add", 0xf150, 0xfff0, 0, FMT_D0, 0, {AM1, DN0}},
+{ "add", 0xf170, 0xfff0, 0, FMT_D0, 0, {AM1, AN0}},
+{ "add", 0x2800, 0xfc00, 0, FMT_S1, 0, {SIMM8, DN0}},
+{ "add", 0xfac00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "add", 0x2000, 0xfc00, 0, FMT_S1, 0, {SIMM8, AN0}},
+{ "add", 0xfad00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, AN0}},
+{ "add", 0xf8fe00, 0xffff00, 0, FMT_D1, 0, {SIMM8, SP}},
+{ "add", 0xfafe0000, 0xffff0000, 0, FMT_D2, 0, {SIMM16, SP}},
+{ "add", 0xfcc00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "add", 0xfcd00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, AN0}},
+{ "add", 0xfcfe0000, 0xffff0000, 0, FMT_D4, 0, {IMM32, SP}},
+
+{ "addc", 0xf140, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+
+{ "sub", 0xf100, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "sub", 0xf120, 0xfff0, 0, FMT_D0, 0, {DM1, AN0}},
+{ "sub", 0xf110, 0xfff0, 0, FMT_D0, 0, {AM1, DN0}},
+{ "sub", 0xf130, 0xfff0, 0, FMT_D0, 0, {AM1, AN0}},
+{ "sub", 0xfcc40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "sub", 0xfcd40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, AN0}},
+
+{ "subc", 0xf180, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+
+{ "mul", 0xf240, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+
+{ "mulu", 0xf250, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+
+{ "div", 0xf260, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+
+{ "divu", 0xf270, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+
+{ "inc", 0x40, 0xf3, 0, FMT_S0, 0, {DN1}},
+{ "inc", 0x41, 0xf3, 0, FMT_S0, 0, {AN1}},
+
+{ "inc4", 0x50, 0xfc, 0, FMT_S0, 0, {AN0}},
+
+{ "cmp", 0xa000, 0xf000, 0, FMT_S1, 0, {SIMM8, DN01}},
+{ "cmp", 0xa0, 0xf0, 0x3, FMT_S0, 0, {DM1, DN0}},
+{ "cmp", 0xf1a0, 0xfff0, 0, FMT_D0, 0, {DM1, AN0}},
+{ "cmp", 0xf190, 0xfff0, 0, FMT_D0, 0, {AM1, DN0}},
+{ "cmp", 0xb000, 0xf000, 0, FMT_S1, 0, {IMM8, AN01}},
+{ "cmp", 0xb0, 0xf0, 0x3, FMT_S0, 0, {AM1, AN0}},
+{ "cmp", 0xfac80000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "cmp", 0xfad80000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, AN0}},
+{ "cmp", 0xfcc80000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "cmp", 0xfcd80000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, AN0}},
+
+{ "and", 0xf200, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "and", 0xf8e000, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "and", 0xfae00000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "and", 0xfafc0000, 0xffff0000, 0, FMT_D2, 0, {IMM16, PSW}},
+{ "and", 0xfce00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+
+{ "or", 0xf210, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "or", 0xf8e400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "or", 0xfae40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "or", 0xfafd0000, 0xffff0000, 0, FMT_D2, 0, {IMM16, PSW}},
+{ "or", 0xfce40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+
+{ "xor", 0xf220, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "xor", 0xfae80000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "xor", 0xfce80000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+
+{ "not", 0xf230, 0xfffc, 0, FMT_D0, 0, {DN0}},
+
+{ "btst", 0xf8ec00, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "btst", 0xfaec0000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "btst", 0xfcec0000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "btst", 0xfe020000, 0xffff0000, 0, FMT_D5, 0, {IMM8E, MEM(IMM32_LOWSHIFT8)}},
+{ "btst", 0xfaf80000, 0xfffc0000, 0, FMT_D2, 0, {IMM8, MEM2(SD8N_SHIFT8, AN0)}},
+
+{ "bset", 0xf080, 0xfff0, 0, FMT_D0, 0, {DM1, MEM(AN0)}},
+{ "bset", 0xfe000000, 0xffff0000, 0, FMT_D5, 0, {IMM8E, MEM(IMM32_LOWSHIFT8)}},
+{ "bset", 0xfaf00000, 0xfffc0000, 0, FMT_D2, 0, {IMM8, MEM2(SD8N_SHIFT8, AN0)}},
+
+{ "bclr", 0xf090, 0xfff0, 0, FMT_D0, 0, {DM1, MEM(AN0)}},
+{ "bclr", 0xfe010000, 0xffff0000, 0, FMT_D5, 0, {IMM8E, MEM(IMM32_LOWSHIFT8)}},
+{ "bclr", 0xfaf40000, 0xfffc0000, 0, FMT_D2, 0, {IMM8, MEM2(SD8N_SHIFT8,AN0)}},
+
+{ "asr", 0xf2b0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "asr", 0xf8c800, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "asr", 0xf8c801, 0xfffcff, 0, FMT_D1, 0, {DN0}},
+
+{ "lsr", 0xf2a0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "lsr", 0xf8c400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "lsr", 0xf8c401, 0xfffcff, 0, FMT_D1, 0, {DN0}},
+
+{ "asl", 0xf290, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "asl", 0xf8c000, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "asl", 0xf8c001, 0xfffcff, 0, FMT_D1, 0, {DN0}},
+
+{ "asl2", 0x54, 0xfc, 0, FMT_S0, 0, {DN0}},
+
+{ "ror", 0xf284, 0xfffc, 0, FMT_D0, 0, {DN0}},
+
+{ "rol", 0xf280, 0xfffc, 0, FMT_D0, 0, {DN0}},
+
+{ "beq", 0xc800, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bne", 0xc900, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bgt", 0xc100, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bge", 0xc200, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "ble", 0xc300, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "blt", 0xc000, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bhi", 0xc500, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bcc", 0xc600, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bls", 0xc700, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bcs", 0xc400, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+{ "bvc", 0xf8e800, 0xffff00, 0, FMT_D1, 0, {SD8N_PCREL}},
+{ "bvs", 0xf8e900, 0xffff00, 0, FMT_D1, 0, {SD8N_PCREL}},
+{ "bnc", 0xf8ea00, 0xffff00, 0, FMT_D1, 0, {SD8N_PCREL}},
+{ "bns", 0xf8eb00, 0xffff00, 0, FMT_D1, 0, {SD8N_PCREL}},
+{ "bra", 0xca00, 0xff00, 0, FMT_S1, 0, {SD8N_PCREL}},
+
+{ "leq", 0xd8, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lne", 0xd9, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lgt", 0xd1, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lge", 0xd2, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lle", 0xd3, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "llt", 0xd0, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lhi", 0xd5, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lcc", 0xd6, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lls", 0xd7, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lcs", 0xd4, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "lra", 0xda, 0xff, 0, FMT_S0, 0, {UNUSED}},
+{ "setlb", 0xdb, 0xff, 0, FMT_S0, 0, {UNUSED}},
+
+{ "jmp", 0xf0f4, 0xfffc, 0, FMT_D0, 0, {PAREN,AN0,PAREN}},
+{ "jmp", 0xcc0000, 0xff0000, 0, FMT_S2, 0, {IMM16_PCREL}},
+{ "jmp", 0xdc000000, 0xff000000, 0, FMT_S4, 0, {IMM32_HIGH24}},
+{ "call", 0xcd000000, 0xff000000, 0, FMT_S4, 0, {D16_SHIFT,REGS,IMM8E}},
+{ "call", 0xdd000000, 0xff000000, 0, FMT_S6, 0, {IMM32_HIGH24_LOWSHIFT16, REGSE_SHIFT8,IMM8E}},
+{ "calls", 0xf0f0, 0xfffc, 0, FMT_D0, 0, {PAREN,AN0,PAREN}},
+{ "calls", 0xfaff0000, 0xffff0000, 0, FMT_D2, 0, {IMM16_PCREL}},
+{ "calls", 0xfcff0000, 0xffff0000, 0, FMT_D4, 0, {IMM32_PCREL}},
+
+{ "ret", 0xdf0000, 0xff0000, 0, FMT_S2, 0, {REGS_SHIFT8, IMM8}},
+{ "retf", 0xde0000, 0xff0000, 0, FMT_S2, 0, {REGS_SHIFT8, IMM8}},
+{ "rets", 0xf0fc, 0xffff, 0, FMT_D0, 0, {UNUSED}},
+{ "rti", 0xf0fd, 0xffff, 0, FMT_D0, 0, {UNUSED}},
+{ "trap", 0xf0fe, 0xffff, 0, FMT_D0, 0, {UNUSED}},
+{ "rtm", 0xf0ff, 0xffff, 0, FMT_D0, 0, {UNUSED}},
+{ "nop", 0xcb, 0xff, 0, FMT_S0, 0, {UNUSED}},
+
+/* UDF instructions. */
+{ "udf00", 0xf600, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf00", 0xf90000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf00", 0xfb000000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf00", 0xfd000000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf01", 0xf610, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf01", 0xf91000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf01", 0xfb100000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf01", 0xfd100000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf02", 0xf620, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf02", 0xf92000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf02", 0xfb200000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf02", 0xfd200000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf03", 0xf630, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf03", 0xf93000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf03", 0xfb300000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf03", 0xfd300000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf04", 0xf640, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf04", 0xf94000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf04", 0xfb400000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf04", 0xfd400000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf05", 0xf650, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf05", 0xf95000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf05", 0xfb500000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf05", 0xfd500000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf06", 0xf660, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf06", 0xf96000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf06", 0xfb600000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf06", 0xfd600000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf07", 0xf670, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf07", 0xf97000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf07", 0xfb700000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf07", 0xfd700000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf08", 0xf680, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf08", 0xf98000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf08", 0xfb800000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf08", 0xfd800000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf09", 0xf690, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf09", 0xf99000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf09", 0xfb900000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf09", 0xfd900000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf10", 0xf6a0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf10", 0xf9a000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf10", 0xfba00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf10", 0xfda00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf11", 0xf6b0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf11", 0xf9b000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf11", 0xfbb00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf11", 0xfdb00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf12", 0xf6c0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf12", 0xf9c000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf12", 0xfbc00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf12", 0xfdc00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf13", 0xf6d0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf13", 0xf9d000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf13", 0xfbd00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf13", 0xfdd00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf14", 0xf6e0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf14", 0xf9e000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf14", 0xfbe00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf14", 0xfde00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf15", 0xf6f0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf15", 0xf9f000, 0xfffc00, 0, FMT_D1, 0, {SIMM8, DN0}},
+{ "udf15", 0xfbf00000, 0xfffc0000, 0, FMT_D2, 0, {SIMM16, DN0}},
+{ "udf15", 0xfdf00000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udf20", 0xf500, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf21", 0xf510, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf22", 0xf520, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf23", 0xf530, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf24", 0xf540, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf25", 0xf550, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf26", 0xf560, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf27", 0xf570, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf28", 0xf580, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf29", 0xf590, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf30", 0xf5a0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf31", 0xf5b0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf32", 0xf5c0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf33", 0xf5d0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf34", 0xf5e0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udf35", 0xf5f0, 0xfff0, 0, FMT_D0, 0, {DM1, DN0}},
+{ "udfu00", 0xf90400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu00", 0xfb040000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu00", 0xfd040000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu01", 0xf91400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu01", 0xfb140000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu01", 0xfd140000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu02", 0xf92400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu02", 0xfb240000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu02", 0xfd240000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu03", 0xf93400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu03", 0xfb340000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu03", 0xfd340000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu04", 0xf94400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu04", 0xfb440000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu04", 0xfd440000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu05", 0xf95400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu05", 0xfb540000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu05", 0xfd540000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu06", 0xf96400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu06", 0xfb640000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu06", 0xfd640000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu07", 0xf97400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu07", 0xfb740000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu07", 0xfd740000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu08", 0xf98400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu08", 0xfb840000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu08", 0xfd840000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu09", 0xf99400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu09", 0xfb940000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu09", 0xfd940000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu10", 0xf9a400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu10", 0xfba40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu10", 0xfda40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu11", 0xf9b400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu11", 0xfbb40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu11", 0xfdb40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu12", 0xf9c400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu12", 0xfbc40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu12", 0xfdc40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu13", 0xf9d400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu13", 0xfbd40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu13", 0xfdd40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu14", 0xf9e400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu14", 0xfbe40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu14", 0xfde40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+{ "udfu15", 0xf9f400, 0xfffc00, 0, FMT_D1, 0, {IMM8, DN0}},
+{ "udfu15", 0xfbf40000, 0xfffc0000, 0, FMT_D2, 0, {IMM16, DN0}},
+{ "udfu15", 0xfdf40000, 0xfffc0000, 0, FMT_D4, 0, {IMM32, DN0}},
+
+{ "putx", 0xf500, 0xfff0, 0, FMT_D0, AM30, {DN01}},
+{ "getx", 0xf6f0, 0xfff0, 0, FMT_D0, AM30, {DN01}},
+{ "mulq", 0xf600, 0xfff0, 0, FMT_D0, AM30, {DM1, DN0}},
+{ "mulq", 0xf90000, 0xfffc00, 0, FMT_D1, AM30, {SIMM8, DN0}},
+{ "mulq", 0xfb000000, 0xfffc0000, 0, FMT_D2, AM30, {SIMM16, DN0}},
+{ "mulq", 0xfd000000, 0xfffc0000, 0, FMT_D4, AM30, {IMM32, DN0}},
+{ "mulqu", 0xf610, 0xfff0, 0, FMT_D0, AM30, {DM1, DN0}},
+{ "mulqu", 0xf91400, 0xfffc00, 0, FMT_D1, AM30, {SIMM8, DN0}},
+{ "mulqu", 0xfb140000, 0xfffc0000, 0, FMT_D2, AM30, {SIMM16, DN0}},
+{ "mulqu", 0xfd140000, 0xfffc0000, 0, FMT_D4, AM30, {IMM32, DN0}},
+{ "sat16", 0xf640, 0xfff0, 0, FMT_D0, AM30, {DM1, DN0}},
+
+{ "sat24", 0xf650, 0xfff0, 0, FMT_D0, AM30, {DM1, DN0}},
+
+{ "bsch", 0xf670, 0xfff0, 0, FMT_D0, AM30, {DM1, DN0}},
+
+/* Extension. We need some instruction to trigger "emulated syscalls"
+ for our simulator. */
+{ "syscall", 0xf0c0, 0xffff, 0, FMT_D0, 0, {UNUSED}},
+
+/* Extension. When talking to the simulator, gdb requires some instruction
+ that will trigger a "breakpoint" (really just an instruction that isn't
+ otherwise used by the tools. This instruction must be the same size
+ as the smallest instruction on the target machine. In the case of the
+ mn10x00 the "break" instruction must be one byte. 0xff is available on
+ both mn10x00 architectures. */
+{ "break", 0xff, 0xff, 0, FMT_S0, 0, {UNUSED}},
+
+
+{ 0, 0, 0, 0, 0, 0, {0}},
+
+} ;
+
+const int mn10300_num_opcodes =
+ sizeof (mn10300_opcodes) / sizeof (mn10300_opcodes[0]);
+
+
diff --git a/opcodes/m32r-asm.c b/opcodes/m32r-asm.c
new file mode 100644
index 00000000000..378cd73e9c4
--- /dev/null
+++ b/opcodes/m32r-asm.c
@@ -0,0 +1,556 @@
+/* Assembler interface for targets using CGEN. -*- C -*-
+ CGEN: Cpu tools GENerator
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+- the resultant file is machine generated, cgen-asm.in isn't
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ??? Eventually more and more of this stuff can go to cpu-independent files.
+ Keep that in mind. */
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "m32r-desc.h"
+#include "m32r-opc.h"
+#include "opintl.h"
+
+#undef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#undef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+static const char * parse_insn_normal
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
+
+/* -- assembler routines inserted here */
+
+/* -- asm.c */
+
+/* Handle '#' prefixes (i.e. skip over them). */
+
+static const char *
+parse_hash (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ if (**strp == '#')
+ ++*strp;
+ return NULL;
+}
+
+/* Handle shigh(), high(). */
+
+static const char *
+parse_hi16 (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ if (**strp == '#')
+ ++*strp;
+
+ if (strncasecmp (*strp, "high(", 5) == 0)
+ {
+ *strp += 5;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value >>= 16;
+ *valuep = value;
+ return errmsg;
+ }
+ else if (strncasecmp (*strp, "shigh(", 6) == 0)
+ {
+ *strp += 6;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value = (value >> 16) + (value & 0x8000 ? 1 : 0);
+ *valuep = value;
+ return errmsg;
+ }
+
+ return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+}
+
+/* Handle low() in a signed context. Also handle sda().
+ The signedness of the value doesn't matter to low(), but this also
+ handles the case where low() isn't present. */
+
+static const char *
+parse_slo16 (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ long *valuep;
+{
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ if (**strp == '#')
+ ++*strp;
+
+ if (strncasecmp (*strp, "low(", 4) == 0)
+ {
+ *strp += 4;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ if (strncasecmp (*strp, "sda(", 4) == 0)
+ {
+ *strp += 4;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16,
+ NULL, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return cgen_parse_signed_integer (cd, strp, opindex, valuep);
+}
+
+/* Handle low() in an unsigned context.
+ The signedness of the value doesn't matter to low(), but this also
+ handles the case where low() isn't present. */
+
+static const char *
+parse_ulo16 (cd, strp, opindex, valuep)
+ CGEN_CPU_DESC cd;
+ const char **strp;
+ int opindex;
+ unsigned long *valuep;
+{
+ const char *errmsg;
+ enum cgen_parse_operand_result result_type;
+ bfd_vma value;
+
+ if (**strp == '#')
+ ++*strp;
+
+ if (strncasecmp (*strp, "low(", 4) == 0)
+ {
+ *strp += 4;
+ errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
+ &result_type, &value);
+ if (**strp != ')')
+ return "missing `)'";
+ ++*strp;
+ if (errmsg == NULL
+ && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
+ value &= 0xffff;
+ *valuep = value;
+ return errmsg;
+ }
+
+ return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
+}
+
+/* -- */
+
+/* Main entry point for operand parsing.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `parse_insn_normal', but keeping it
+ separate makes clear the interface between `parse_insn_normal' and each of
+ the handlers.
+*/
+
+const char *
+m32r_cgen_parse_operand (cd, opindex, strp, fields)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ const char ** strp;
+ CGEN_FIELDS * fields;
+{
+ const char * errmsg;
+
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r1);
+ break;
+ case M32R_OPERAND_DISP16 :
+ {
+ bfd_vma value;
+ errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP16, 0, NULL, & value);
+ fields->f_disp16 = value;
+ }
+ break;
+ case M32R_OPERAND_DISP24 :
+ {
+ bfd_vma value;
+ errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP24, 0, NULL, & value);
+ fields->f_disp24 = value;
+ }
+ break;
+ case M32R_OPERAND_DISP8 :
+ {
+ bfd_vma value;
+ errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP8, 0, NULL, & value);
+ fields->f_disp8 = value;
+ }
+ break;
+ case M32R_OPERAND_DR :
+ errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1);
+ break;
+ case M32R_OPERAND_HASH :
+ errmsg = parse_hash (cd, strp, M32R_OPERAND_HASH, &fields->f_nil);
+ break;
+ case M32R_OPERAND_HI16 :
+ errmsg = parse_hi16 (cd, strp, M32R_OPERAND_HI16, &fields->f_hi16);
+ break;
+ case M32R_OPERAND_SCR :
+ errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r2);
+ break;
+ case M32R_OPERAND_SIMM16 :
+ errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
+ break;
+ case M32R_OPERAND_SIMM8 :
+ errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
+ break;
+ case M32R_OPERAND_SLO16 :
+ errmsg = parse_slo16 (cd, strp, M32R_OPERAND_SLO16, &fields->f_simm16);
+ break;
+ case M32R_OPERAND_SR :
+ errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2);
+ break;
+ case M32R_OPERAND_SRC1 :
+ errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1);
+ break;
+ case M32R_OPERAND_SRC2 :
+ errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2);
+ break;
+ case M32R_OPERAND_UIMM16 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
+ break;
+ case M32R_OPERAND_UIMM24 :
+ {
+ bfd_vma value;
+ errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_UIMM24, 0, NULL, & value);
+ fields->f_uimm24 = value;
+ }
+ break;
+ case M32R_OPERAND_UIMM4 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
+ break;
+ case M32R_OPERAND_UIMM5 :
+ errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
+ break;
+ case M32R_OPERAND_ULO16 :
+ errmsg = parse_ulo16 (cd, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
+ abort ();
+ }
+
+ return errmsg;
+}
+
+cgen_parse_fn * const m32r_cgen_parse_handlers[] =
+{
+ parse_insn_normal,
+};
+
+void
+m32r_cgen_init_asm (cd)
+ CGEN_CPU_DESC cd;
+{
+ m32r_cgen_init_opcode_table (cd);
+ m32r_cgen_init_ibld_table (cd);
+ cd->parse_handlers = & m32r_cgen_parse_handlers[0];
+ cd->parse_operand = m32r_cgen_parse_operand;
+}
+
+
+/* Default insn parser.
+
+ The syntax string is scanned and operands are parsed and stored in FIELDS.
+ Relocs are queued as we go via other callbacks.
+
+ ??? Note that this is currently an all-or-nothing parser. If we fail to
+ parse the instruction, we return 0 and the caller will start over from
+ the beginning. Backtracking will be necessary in parsing subexpressions,
+ but that can be handled there. Not handling backtracking here may get
+ expensive in the case of the m68k. Deal with later.
+
+ Returns NULL for success, an error message for failure.
+*/
+
+static const char *
+parse_insn_normal (cd, insn, strp, fields)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ const char **strp;
+ CGEN_FIELDS *fields;
+{
+ /* ??? Runtime added insns not handled yet. */
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ const char *str = *strp;
+ const char *errmsg;
+ const char *p;
+ const unsigned char * syn;
+#ifdef CGEN_MNEMONIC_OPERANDS
+ /* FIXME: wip */
+ int past_opcode_p;
+#endif
+
+ /* For now we assume the mnemonic is first (there are no leading operands).
+ We can parse it without needing to set up operand parsing.
+ GAS's input scrubber will ensure mnemonics are lowercase, but we may
+ not be called from GAS. */
+ p = CGEN_INSN_MNEMONIC (insn);
+ while (*p && tolower (*p) == tolower (*str))
+ ++p, ++str;
+
+ if (* p || (* str && !isspace (* str)))
+ return _("unrecognized instruction");
+
+ CGEN_INIT_PARSE (cd);
+ cgen_init_parse_operand (cd);
+#ifdef CGEN_MNEMONIC_OPERANDS
+ past_opcode_p = 0;
+#endif
+
+ /* We don't check for (*str != '\0') here because we want to parse
+ any trailing fake arguments in the syntax string. */
+ syn = CGEN_SYNTAX_STRING (syntax);
+
+ /* Mnemonics come first for now, ensure valid string. */
+ if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
+ abort ();
+
+ ++syn;
+
+ while (* syn != 0)
+ {
+ /* Non operand chars must match exactly. */
+ if (CGEN_SYNTAX_CHAR_P (* syn))
+ {
+ if (*str == CGEN_SYNTAX_CHAR (* syn))
+ {
+#ifdef CGEN_MNEMONIC_OPERANDS
+ if (* syn == ' ')
+ past_opcode_p = 1;
+#endif
+ ++ syn;
+ ++ str;
+ }
+ else
+ {
+ /* Syntax char didn't match. Can't be this insn. */
+ /* FIXME: would like to return something like
+ "expected char `c'" */
+ return _("syntax error");
+ }
+ continue;
+ }
+
+ /* We have an operand of some sort. */
+ errmsg = m32r_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
+ &str, fields);
+ if (errmsg)
+ return errmsg;
+
+ /* Done with this operand, continue with next one. */
+ ++ syn;
+ }
+
+ /* If we're at the end of the syntax string, we're done. */
+ if (* syn == '\0')
+ {
+ /* FIXME: For the moment we assume a valid `str' can only contain
+ blanks now. IE: We needn't try again with a longer version of
+ the insn and it is assumed that longer versions of insns appear
+ before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
+ while (isspace (* str))
+ ++ str;
+
+ if (* str != '\0')
+ return _("junk at end of line"); /* FIXME: would like to include `str' */
+
+ return NULL;
+ }
+
+ /* We couldn't parse it. */
+ return _("unrecognized instruction");
+}
+
+/* Main entry point.
+ This routine is called for each instruction to be assembled.
+ STR points to the insn to be assembled.
+ We assume all necessary tables have been initialized.
+ The assembled instruction, less any fixups, is stored in BUF.
+ Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
+ still needs to be converted to target byte order, otherwise BUF is an array
+ of bytes in target byte order.
+ The result is a pointer to the insn's entry in the opcode table,
+ or NULL if an error occured (an error message will have already been
+ printed).
+
+ Note that when processing (non-alias) macro-insns,
+ this function recurses.
+
+ ??? It's possible to make this cpu-independent.
+ One would have to deal with a few minor things.
+ At this point in time doing so would be more of a curiosity than useful
+ [for example this file isn't _that_ big], but keeping the possibility in
+ mind helps keep the design clean. */
+
+const CGEN_INSN *
+m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
+ CGEN_CPU_DESC cd;
+ const char *str;
+ CGEN_FIELDS *fields;
+ CGEN_INSN_BYTES_PTR buf;
+ char **errmsg;
+{
+ const char *start;
+ CGEN_INSN_LIST *ilist;
+
+ /* Skip leading white space. */
+ while (isspace (* str))
+ ++ str;
+
+ /* The instructions are stored in hashed lists.
+ Get the first in the list. */
+ ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
+
+ /* Keep looking until we find a match. */
+
+ start = str;
+ for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
+ {
+ const CGEN_INSN *insn = ilist->insn;
+
+#if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
+ /* Is this insn supported by the selected cpu? */
+ if (! m32r_cgen_insn_supported (cd, insn))
+ continue;
+#endif
+
+ /* If the RELAX attribute is set, this is an insn that shouldn't be
+ chosen immediately. Instead, it is used during assembler/linker
+ relaxation if possible. */
+ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
+ continue;
+
+ str = start;
+
+ /* Allow parse/insert handlers to obtain length of insn. */
+ CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
+
+ if (! CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields))
+ {
+ /* ??? 0 is passed for `pc' */
+ if (CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, (bfd_vma) 0)
+ != NULL)
+ continue;
+ /* It is up to the caller to actually output the insn and any
+ queued relocs. */
+ return insn;
+ }
+
+ /* Try the next entry. */
+ }
+
+ /* FIXME: We can return a better error message than this.
+ Need to track why it failed and pick the right one. */
+ {
+ static char errbuf[100];
+ if (strlen (start) > 50)
+ /* xgettext:c-format */
+ sprintf (errbuf, _("bad instruction `%.50s...'"), start);
+ else
+ /* xgettext:c-format */
+ sprintf (errbuf, _("bad instruction `%.50s'"), start);
+
+ *errmsg = errbuf;
+ return NULL;
+ }
+}
+
+#if 0 /* This calls back to GAS which we can't do without care. */
+
+/* Record each member of OPVALS in the assembler's symbol table.
+ This lets GAS parse registers for us.
+ ??? Interesting idea but not currently used. */
+
+/* Record each member of OPVALS in the assembler's symbol table.
+ FIXME: Not currently used. */
+
+void
+m32r_cgen_asm_hash_keywords (cd, opvals)
+ CGEN_CPU_DESC cd;
+ CGEN_KEYWORD *opvals;
+{
+ CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
+ const CGEN_KEYWORD_ENTRY * ke;
+
+ while ((ke = cgen_keyword_search_next (& search)) != NULL)
+ {
+#if 0 /* Unnecessary, should be done in the search routine. */
+ if (! m32r_cgen_opval_supported (ke))
+ continue;
+#endif
+ cgen_asm_record_register (cd, ke->name, ke->value);
+ }
+}
+
+#endif /* 0 */
diff --git a/opcodes/m32r-desc.c b/opcodes/m32r-desc.c
new file mode 100644
index 00000000000..9cb5462502e
--- /dev/null
+++ b/opcodes/m32r-desc.c
@@ -0,0 +1,1150 @@
+/* CPU data for m32r.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "m32r-desc.h"
+#include "m32r-opc.h"
+#include "opintl.h"
+
+/* Attributes. */
+
+static const CGEN_ATTR_ENTRY bool_attr[] =
+{
+ { "#f", 0 },
+ { "#t", 1 },
+ { 0, 0 }
+};
+
+static const CGEN_ATTR_ENTRY MACH_attr[] =
+{
+ { "base", MACH_BASE },
+ { "m32r", MACH_M32R },
+ { "max", MACH_MAX },
+ { 0, 0 }
+};
+
+static const CGEN_ATTR_ENTRY ISA_attr[] =
+{
+ { "m32r", ISA_M32R },
+ { "max", ISA_MAX },
+ { 0, 0 }
+};
+
+const CGEN_ATTR_TABLE m32r_cgen_ifield_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "RESERVED", &bool_attr[0], &bool_attr[0] },
+ { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
+ { "SIGNED", &bool_attr[0], &bool_attr[0] },
+ { "RELOC", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+const CGEN_ATTR_TABLE m32r_cgen_hardware_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "PC", &bool_attr[0], &bool_attr[0] },
+ { "PROFILE", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+const CGEN_ATTR_TABLE m32r_cgen_operand_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
+ { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
+ { "SIGNED", &bool_attr[0], &bool_attr[0] },
+ { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
+ { "RELAX", &bool_attr[0], &bool_attr[0] },
+ { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
+ { "RELOC", &bool_attr[0], &bool_attr[0] },
+ { "HASH-PREFIX", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+const CGEN_ATTR_TABLE m32r_cgen_insn_attr_table[] =
+{
+ { "MACH", & MACH_attr[0] },
+ { "ALIAS", &bool_attr[0], &bool_attr[0] },
+ { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
+ { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
+ { "COND-CTI", &bool_attr[0], &bool_attr[0] },
+ { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
+ { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
+ { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
+ { "RELAX", &bool_attr[0], &bool_attr[0] },
+ { "NO-DIS", &bool_attr[0], &bool_attr[0] },
+ { "PBB", &bool_attr[0], &bool_attr[0] },
+ { "FILL-SLOT", &bool_attr[0], &bool_attr[0] },
+ { 0, 0, 0 }
+};
+
+/* Instruction set variants. */
+
+static const CGEN_ISA m32r_cgen_isa_table[] = {
+ { "m32r", 32, 32, 16, 32, },
+ { 0 }
+};
+
+/* Machine variants. */
+
+static const CGEN_MACH m32r_cgen_mach_table[] = {
+ { "m32r", "m32r", MACH_M32R },
+ { 0 }
+};
+
+static CGEN_KEYWORD_ENTRY m32r_cgen_opval_gr_names_entries[] =
+{
+ { "fp", 13 },
+ { "lr", 14 },
+ { "sp", 15 },
+ { "r0", 0 },
+ { "r1", 1 },
+ { "r2", 2 },
+ { "r3", 3 },
+ { "r4", 4 },
+ { "r5", 5 },
+ { "r6", 6 },
+ { "r7", 7 },
+ { "r8", 8 },
+ { "r9", 9 },
+ { "r10", 10 },
+ { "r11", 11 },
+ { "r12", 12 },
+ { "r13", 13 },
+ { "r14", 14 },
+ { "r15", 15 }
+};
+
+CGEN_KEYWORD m32r_cgen_opval_gr_names =
+{
+ & m32r_cgen_opval_gr_names_entries[0],
+ 19
+};
+
+static CGEN_KEYWORD_ENTRY m32r_cgen_opval_cr_names_entries[] =
+{
+ { "psw", 0 },
+ { "cbr", 1 },
+ { "spi", 2 },
+ { "spu", 3 },
+ { "bpc", 6 },
+ { "bbpsw", 8 },
+ { "bbpc", 14 },
+ { "cr0", 0 },
+ { "cr1", 1 },
+ { "cr2", 2 },
+ { "cr3", 3 },
+ { "cr4", 4 },
+ { "cr5", 5 },
+ { "cr6", 6 },
+ { "cr7", 7 },
+ { "cr8", 8 },
+ { "cr9", 9 },
+ { "cr10", 10 },
+ { "cr11", 11 },
+ { "cr12", 12 },
+ { "cr13", 13 },
+ { "cr14", 14 },
+ { "cr15", 15 }
+};
+
+CGEN_KEYWORD m32r_cgen_opval_cr_names =
+{
+ & m32r_cgen_opval_cr_names_entries[0],
+ 23
+};
+
+
+
+/* The hardware table. */
+
+#define A(a) (1 << CONCAT2 (CGEN_HW_,a))
+
+const CGEN_HW_ENTRY m32r_cgen_hw_table[] =
+{
+ { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
+ { "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-slo16", HW_H_SLO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-ulo16", HW_H_ULO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & m32r_cgen_opval_gr_names, { 0|A(CACHE_ADDR)|A(PROFILE), { (1<<MACH_BASE) } } },
+ { "h-cr", HW_H_CR, CGEN_ASM_KEYWORD, (PTR) & m32r_cgen_opval_cr_names, { 0, { (1<<MACH_BASE) } } },
+ { "h-accum", HW_H_ACCUM, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-cond", HW_H_COND, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-psw", HW_H_PSW, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-bpsw", HW_H_BPSW, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-bbpsw", HW_H_BBPSW, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { "h-lock", HW_H_LOCK, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
+ { 0 }
+};
+
+#undef A
+
+/* The instruction field table. */
+
+#define A(a) (1 << CONCAT2 (CGEN_IFLD_,a))
+
+const CGEN_IFLD m32r_cgen_ifld_table[] =
+{
+ { M32R_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_OP1, "f-op1", 0, 32, 0, 4, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_OP2, "f-op2", 0, 32, 8, 4, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_COND, "f-cond", 0, 32, 4, 4, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_R1, "f-r1", 0, 32, 4, 4, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_R2, "f-r2", 0, 32, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_SIMM8, "f-simm8", 0, 32, 8, 8, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_SIMM16, "f-simm16", 0, 32, 16, 16, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_SHIFT_OP2, "f-shift-op2", 0, 32, 8, 3, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_UIMM4, "f-uimm4", 0, 32, 12, 4, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_UIMM5, "f-uimm5", 0, 32, 11, 5, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_UIMM16, "f-uimm16", 0, 32, 16, 16, { 0, { (1<<MACH_BASE) } } },
+ { M32R_F_UIMM24, "f-uimm24", 0, 32, 8, 24, { 0|A(RELOC)|A(ABS_ADDR), { (1<<MACH_BASE) } } },
+ { M32R_F_HI16, "f-hi16", 0, 32, 16, 16, { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
+ { M32R_F_DISP8, "f-disp8", 0, 32, 8, 8, { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+ { M32R_F_DISP16, "f-disp16", 0, 32, 16, 16, { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+ { M32R_F_DISP24, "f-disp24", 0, 32, 8, 24, { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+ { 0 }
+};
+
+#undef A
+
+/* The operand table. */
+
+#define A(a) (1 << CONCAT2 (CGEN_OPERAND_,a))
+#define OPERAND(op) CONCAT2 (M32R_OPERAND_,op)
+
+const CGEN_OPERAND m32r_cgen_operand_table[] =
+{
+/* pc: program counter */
+ { "pc", M32R_OPERAND_PC, HW_H_PC, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* sr: source register */
+ { "sr", M32R_OPERAND_SR, HW_H_GR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* dr: destination register */
+ { "dr", M32R_OPERAND_DR, HW_H_GR, 4, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* src1: source register 1 */
+ { "src1", M32R_OPERAND_SRC1, HW_H_GR, 4, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* src2: source register 2 */
+ { "src2", M32R_OPERAND_SRC2, HW_H_GR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* scr: source control register */
+ { "scr", M32R_OPERAND_SCR, HW_H_CR, 12, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* dcr: destination control register */
+ { "dcr", M32R_OPERAND_DCR, HW_H_CR, 4, 4,
+ { 0, { (1<<MACH_BASE) } } },
+/* simm8: 8 bit signed immediate */
+ { "simm8", M32R_OPERAND_SIMM8, HW_H_SINT, 8, 8,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* simm16: 16 bit signed immediate */
+ { "simm16", M32R_OPERAND_SIMM16, HW_H_SINT, 16, 16,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* uimm4: 4 bit trap number */
+ { "uimm4", M32R_OPERAND_UIMM4, HW_H_UINT, 12, 4,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* uimm5: 5 bit shift count */
+ { "uimm5", M32R_OPERAND_UIMM5, HW_H_UINT, 11, 5,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* uimm16: 16 bit unsigned immediate */
+ { "uimm16", M32R_OPERAND_UIMM16, HW_H_UINT, 16, 16,
+ { 0|A(HASH_PREFIX), { (1<<MACH_BASE) } } },
+/* hash: # prefix */
+ { "hash", M32R_OPERAND_HASH, HW_H_SINT, 0, 0,
+ { 0, { (1<<MACH_BASE) } } },
+/* hi16: high 16 bit immediate, sign optional */
+ { "hi16", M32R_OPERAND_HI16, HW_H_HI16, 16, 16,
+ { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
+/* slo16: 16 bit signed immediate, for low() */
+ { "slo16", M32R_OPERAND_SLO16, HW_H_SLO16, 16, 16,
+ { 0, { (1<<MACH_BASE) } } },
+/* ulo16: 16 bit unsigned immediate, for low() */
+ { "ulo16", M32R_OPERAND_ULO16, HW_H_ULO16, 16, 16,
+ { 0, { (1<<MACH_BASE) } } },
+/* uimm24: 24 bit address */
+ { "uimm24", M32R_OPERAND_UIMM24, HW_H_ADDR, 8, 24,
+ { 0|A(HASH_PREFIX)|A(RELOC)|A(ABS_ADDR), { (1<<MACH_BASE) } } },
+/* disp8: 8 bit displacement */
+ { "disp8", M32R_OPERAND_DISP8, HW_H_IADDR, 8, 8,
+ { 0|A(RELAX)|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+/* disp16: 16 bit displacement */
+ { "disp16", M32R_OPERAND_DISP16, HW_H_IADDR, 16, 16,
+ { 0|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+/* disp24: 24 bit displacement */
+ { "disp24", M32R_OPERAND_DISP24, HW_H_IADDR, 8, 24,
+ { 0|A(RELAX)|A(RELOC)|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
+/* condbit: condition bit */
+ { "condbit", M32R_OPERAND_CONDBIT, HW_H_COND, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+/* accum: accumulator */
+ { "accum", M32R_OPERAND_ACCUM, HW_H_ACCUM, 0, 0,
+ { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
+ { 0 }
+};
+
+#undef A
+
+#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
+#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
+
+/* The instruction table. */
+
+static const CGEN_IBASE m32r_cgen_insn_table[MAX_INSNS] =
+{
+ /* Special null first entry.
+ A `num' value of zero is thus invalid.
+ Also, the special `invalid' insn resides here. */
+ { 0, 0, 0 },
+/* add $dr,$sr */
+ {
+ M32R_INSN_ADD, "add", "add", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* add3 $dr,$sr,$hash$slo16 */
+ {
+ M32R_INSN_ADD3, "add3", "add3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* and $dr,$sr */
+ {
+ M32R_INSN_AND, "and", "and", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* and3 $dr,$sr,$uimm16 */
+ {
+ M32R_INSN_AND3, "and3", "and3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* or $dr,$sr */
+ {
+ M32R_INSN_OR, "or", "or", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* or3 $dr,$sr,$hash$ulo16 */
+ {
+ M32R_INSN_OR3, "or3", "or3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* xor $dr,$sr */
+ {
+ M32R_INSN_XOR, "xor", "xor", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* xor3 $dr,$sr,$uimm16 */
+ {
+ M32R_INSN_XOR3, "xor3", "xor3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addi $dr,$simm8 */
+ {
+ M32R_INSN_ADDI, "addi", "addi", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addv $dr,$sr */
+ {
+ M32R_INSN_ADDV, "addv", "addv", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addv3 $dr,$sr,$simm16 */
+ {
+ M32R_INSN_ADDV3, "addv3", "addv3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* addx $dr,$sr */
+ {
+ M32R_INSN_ADDX, "addx", "addx", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* bc.s $disp8 */
+ {
+ M32R_INSN_BC8, "bc8", "bc.s", 16,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bc.l $disp24 */
+ {
+ M32R_INSN_BC24, "bc24", "bc.l", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* beq $src1,$src2,$disp16 */
+ {
+ M32R_INSN_BEQ, "beq", "beq", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* beqz $src2,$disp16 */
+ {
+ M32R_INSN_BEQZ, "beqz", "beqz", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bgez $src2,$disp16 */
+ {
+ M32R_INSN_BGEZ, "bgez", "bgez", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bgtz $src2,$disp16 */
+ {
+ M32R_INSN_BGTZ, "bgtz", "bgtz", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* blez $src2,$disp16 */
+ {
+ M32R_INSN_BLEZ, "blez", "blez", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bltz $src2,$disp16 */
+ {
+ M32R_INSN_BLTZ, "bltz", "bltz", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bnez $src2,$disp16 */
+ {
+ M32R_INSN_BNEZ, "bnez", "bnez", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bl.s $disp8 */
+ {
+ M32R_INSN_BL8, "bl8", "bl.s", 16,
+ { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bl.l $disp24 */
+ {
+ M32R_INSN_BL24, "bl24", "bl.l", 32,
+ { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bnc.s $disp8 */
+ {
+ M32R_INSN_BNC8, "bnc8", "bnc.s", 16,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bnc.l $disp24 */
+ {
+ M32R_INSN_BNC24, "bnc24", "bnc.l", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bne $src1,$src2,$disp16 */
+ {
+ M32R_INSN_BNE, "bne", "bne", 32,
+ { 0|A(COND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bra.s $disp8 */
+ {
+ M32R_INSN_BRA8, "bra8", "bra.s", 16,
+ { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* bra.l $disp24 */
+ {
+ M32R_INSN_BRA24, "bra24", "bra.l", 32,
+ { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* cmp $src1,$src2 */
+ {
+ M32R_INSN_CMP, "cmp", "cmp", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* cmpi $src2,$simm16 */
+ {
+ M32R_INSN_CMPI, "cmpi", "cmpi", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* cmpu $src1,$src2 */
+ {
+ M32R_INSN_CMPU, "cmpu", "cmpu", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* cmpui $src2,$simm16 */
+ {
+ M32R_INSN_CMPUI, "cmpui", "cmpui", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* div $dr,$sr */
+ {
+ M32R_INSN_DIV, "div", "div", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* divu $dr,$sr */
+ {
+ M32R_INSN_DIVU, "divu", "divu", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* rem $dr,$sr */
+ {
+ M32R_INSN_REM, "rem", "rem", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* remu $dr,$sr */
+ {
+ M32R_INSN_REMU, "remu", "remu", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* jl $sr */
+ {
+ M32R_INSN_JL, "jl", "jl", 16,
+ { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* jmp $sr */
+ {
+ M32R_INSN_JMP, "jmp", "jmp", 16,
+ { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* ld $dr,@$sr */
+ {
+ M32R_INSN_LD, "ld", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld $dr,@($slo16,$sr) */
+ {
+ M32R_INSN_LD_D, "ld-d", "ld", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldb $dr,@$sr */
+ {
+ M32R_INSN_LDB, "ldb", "ldb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldb $dr,@($slo16,$sr) */
+ {
+ M32R_INSN_LDB_D, "ldb-d", "ldb", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldh $dr,@$sr */
+ {
+ M32R_INSN_LDH, "ldh", "ldh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldh $dr,@($slo16,$sr) */
+ {
+ M32R_INSN_LDH_D, "ldh-d", "ldh", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldub $dr,@$sr */
+ {
+ M32R_INSN_LDUB, "ldub", "ldub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldub $dr,@($slo16,$sr) */
+ {
+ M32R_INSN_LDUB_D, "ldub-d", "ldub", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lduh $dr,@$sr */
+ {
+ M32R_INSN_LDUH, "lduh", "lduh", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lduh $dr,@($slo16,$sr) */
+ {
+ M32R_INSN_LDUH_D, "lduh-d", "lduh", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld $dr,@$sr+ */
+ {
+ M32R_INSN_LD_PLUS, "ld-plus", "ld", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ld24 $dr,$uimm24 */
+ {
+ M32R_INSN_LD24, "ld24", "ld24", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldi8 $dr,$simm8 */
+ {
+ M32R_INSN_LDI8, "ldi8", "ldi8", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* ldi16 $dr,$hash$slo16 */
+ {
+ M32R_INSN_LDI16, "ldi16", "ldi16", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* lock $dr,@$sr */
+ {
+ M32R_INSN_LOCK, "lock", "lock", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* machi $src1,$src2 */
+ {
+ M32R_INSN_MACHI, "machi", "machi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* maclo $src1,$src2 */
+ {
+ M32R_INSN_MACLO, "maclo", "maclo", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* macwhi $src1,$src2 */
+ {
+ M32R_INSN_MACWHI, "macwhi", "macwhi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* macwlo $src1,$src2 */
+ {
+ M32R_INSN_MACWLO, "macwlo", "macwlo", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mul $dr,$sr */
+ {
+ M32R_INSN_MUL, "mul", "mul", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mulhi $src1,$src2 */
+ {
+ M32R_INSN_MULHI, "mulhi", "mulhi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mullo $src1,$src2 */
+ {
+ M32R_INSN_MULLO, "mullo", "mullo", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mulwhi $src1,$src2 */
+ {
+ M32R_INSN_MULWHI, "mulwhi", "mulwhi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mulwlo $src1,$src2 */
+ {
+ M32R_INSN_MULWLO, "mulwlo", "mulwlo", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mv $dr,$sr */
+ {
+ M32R_INSN_MV, "mv", "mv", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mvfachi $dr */
+ {
+ M32R_INSN_MVFACHI, "mvfachi", "mvfachi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mvfaclo $dr */
+ {
+ M32R_INSN_MVFACLO, "mvfaclo", "mvfaclo", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mvfacmi $dr */
+ {
+ M32R_INSN_MVFACMI, "mvfacmi", "mvfacmi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mvfc $dr,$scr */
+ {
+ M32R_INSN_MVFC, "mvfc", "mvfc", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* mvtachi $src1 */
+ {
+ M32R_INSN_MVTACHI, "mvtachi", "mvtachi", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mvtaclo $src1 */
+ {
+ M32R_INSN_MVTACLO, "mvtaclo", "mvtaclo", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* mvtc $sr,$dcr */
+ {
+ M32R_INSN_MVTC, "mvtc", "mvtc", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* neg $dr,$sr */
+ {
+ M32R_INSN_NEG, "neg", "neg", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* nop */
+ {
+ M32R_INSN_NOP, "nop", "nop", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* not $dr,$sr */
+ {
+ M32R_INSN_NOT, "not", "not", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* rac */
+ {
+ M32R_INSN_RAC, "rac", "rac", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* rach */
+ {
+ M32R_INSN_RACH, "rach", "rach", 16,
+ { 0, { (1<<MACH_M32R) } }
+ },
+/* rte */
+ {
+ M32R_INSN_RTE, "rte", "rte", 16,
+ { 0|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* seth $dr,$hash$hi16 */
+ {
+ M32R_INSN_SETH, "seth", "seth", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sll $dr,$sr */
+ {
+ M32R_INSN_SLL, "sll", "sll", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sll3 $dr,$sr,$simm16 */
+ {
+ M32R_INSN_SLL3, "sll3", "sll3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* slli $dr,$uimm5 */
+ {
+ M32R_INSN_SLLI, "slli", "slli", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sra $dr,$sr */
+ {
+ M32R_INSN_SRA, "sra", "sra", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sra3 $dr,$sr,$simm16 */
+ {
+ M32R_INSN_SRA3, "sra3", "sra3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* srai $dr,$uimm5 */
+ {
+ M32R_INSN_SRAI, "srai", "srai", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* srl $dr,$sr */
+ {
+ M32R_INSN_SRL, "srl", "srl", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* srl3 $dr,$sr,$simm16 */
+ {
+ M32R_INSN_SRL3, "srl3", "srl3", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* srli $dr,$uimm5 */
+ {
+ M32R_INSN_SRLI, "srli", "srli", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $src1,@$src2 */
+ {
+ M32R_INSN_ST, "st", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $src1,@($slo16,$src2) */
+ {
+ M32R_INSN_ST_D, "st-d", "st", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stb $src1,@$src2 */
+ {
+ M32R_INSN_STB, "stb", "stb", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* stb $src1,@($slo16,$src2) */
+ {
+ M32R_INSN_STB_D, "stb-d", "stb", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sth $src1,@$src2 */
+ {
+ M32R_INSN_STH, "sth", "sth", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sth $src1,@($slo16,$src2) */
+ {
+ M32R_INSN_STH_D, "sth-d", "sth", 32,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $src1,@+$src2 */
+ {
+ M32R_INSN_ST_PLUS, "st-plus", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* st $src1,@-$src2 */
+ {
+ M32R_INSN_ST_MINUS, "st-minus", "st", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* sub $dr,$sr */
+ {
+ M32R_INSN_SUB, "sub", "sub", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* subv $dr,$sr */
+ {
+ M32R_INSN_SUBV, "subv", "subv", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* subx $dr,$sr */
+ {
+ M32R_INSN_SUBX, "subx", "subx", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+/* trap $uimm4 */
+ {
+ M32R_INSN_TRAP, "trap", "trap", 16,
+ { 0|A(FILL_SLOT)|A(UNCOND_CTI), { (1<<MACH_BASE) } }
+ },
+/* unlock $src1,@$src2 */
+ {
+ M32R_INSN_UNLOCK, "unlock", "unlock", 16,
+ { 0, { (1<<MACH_BASE) } }
+ },
+};
+
+#undef A
+#undef MNEM
+#undef OP
+
+/* Initialize anything needed to be done once, before any cpu_open call. */
+
+static void
+init_tables ()
+{
+}
+
+/* Subroutine of m32r_cgen_cpu_open to look up a mach via its bfd name. */
+
+static const CGEN_MACH *
+lookup_mach_via_bfd_name (table, name)
+ const CGEN_MACH *table;
+ const char *name;
+{
+ while (table->name)
+ {
+ if (strcmp (name, table->bfd_name) == 0)
+ return table;
+ ++table;
+ }
+ abort ();
+}
+
+/* Subroutine of m32r_cgen_cpu_open to build the hardware table. */
+
+static void
+build_hw_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i;
+ int machs = cd->machs;
+ const CGEN_HW_ENTRY *init = & m32r_cgen_hw_table[0];
+ /* MAX_HW is only an upper bound on the number of selected entries.
+ However each entry is indexed by it's enum so there can be holes in
+ the table. */
+ const CGEN_HW_ENTRY **selected =
+ (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
+
+ cd->hw_table.init_entries = init;
+ cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
+ memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
+ /* ??? For now we just use machs to determine which ones we want. */
+ for (i = 0; init[i].name != NULL; ++i)
+ if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
+ & machs)
+ selected[init[i].type] = &init[i];
+ cd->hw_table.entries = selected;
+ cd->hw_table.num_entries = MAX_HW;
+}
+
+/* Subroutine of m32r_cgen_cpu_open to build the hardware table. */
+
+static void
+build_ifield_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ cd->ifld_table = & m32r_cgen_ifld_table[0];
+}
+
+/* Subroutine of m32r_cgen_cpu_open to build the hardware table. */
+
+static void
+build_operand_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i;
+ int machs = cd->machs;
+ const CGEN_OPERAND *init = & m32r_cgen_operand_table[0];
+ /* MAX_OPERANDS is only an upper bound on the number of selected entries.
+ However each entry is indexed by it's enum so there can be holes in
+ the table. */
+ const CGEN_OPERAND **selected =
+ (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
+
+ cd->operand_table.init_entries = init;
+ cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
+ memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
+ /* ??? For now we just use mach to determine which ones we want. */
+ for (i = 0; init[i].name != NULL; ++i)
+ if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
+ & machs)
+ selected[init[i].type] = &init[i];
+ cd->operand_table.entries = selected;
+ cd->operand_table.num_entries = MAX_OPERANDS;
+}
+
+/* Subroutine of m32r_cgen_cpu_open to build the hardware table.
+ ??? This could leave out insns not supported by the specified mach/isa,
+ but that would cause errors like "foo only supported by bar" to become
+ "unknown insn", so for now we include all insns and require the app to
+ do the checking later.
+ ??? On the other hand, parsing of such insns may require their hardware or
+ operand elements to be in the table [which they mightn't be]. */
+
+static void
+build_insn_table (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i;
+ const CGEN_IBASE *ib = & m32r_cgen_insn_table[0];
+ CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
+
+ memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
+ for (i = 0; i < MAX_INSNS; ++i)
+ insns[i].base = &ib[i];
+ cd->insn_table.init_entries = insns;
+ cd->insn_table.entry_size = sizeof (CGEN_IBASE);
+ cd->insn_table.num_init_entries = MAX_INSNS;
+}
+
+/* Subroutine of m32r_cgen_cpu_open to rebuild the tables. */
+
+static void
+m32r_cgen_rebuild_tables (cd)
+ CGEN_CPU_TABLE *cd;
+{
+ int i,n_isas,n_machs;
+ unsigned int isas = cd->isas;
+ unsigned int machs = cd->machs;
+
+ cd->int_insn_p = CGEN_INT_INSN_P;
+
+ /* Data derived from the isa spec. */
+#define UNSET (CGEN_SIZE_UNKNOWN + 1)
+ cd->default_insn_bitsize = UNSET;
+ cd->base_insn_bitsize = UNSET;
+ cd->min_insn_bitsize = 65535; /* some ridiculously big number */
+ cd->max_insn_bitsize = 0;
+ for (i = 0; i < MAX_ISAS; ++i)
+ if (((1 << i) & isas) != 0)
+ {
+ const CGEN_ISA *isa = & m32r_cgen_isa_table[i];
+
+ /* Default insn sizes of all selected isas must be equal or we set
+ the result to 0, meaning "unknown". */
+ if (cd->default_insn_bitsize == UNSET)
+ cd->default_insn_bitsize = isa->default_insn_bitsize;
+ else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
+ ; /* this is ok */
+ else
+ cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
+
+ /* Base insn sizes of all selected isas must be equal or we set
+ the result to 0, meaning "unknown". */
+ if (cd->base_insn_bitsize == UNSET)
+ cd->base_insn_bitsize = isa->base_insn_bitsize;
+ else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
+ ; /* this is ok */
+ else
+ cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
+
+ /* Set min,max insn sizes. */
+ if (isa->min_insn_bitsize < cd->min_insn_bitsize)
+ cd->min_insn_bitsize = isa->min_insn_bitsize;
+ if (isa->max_insn_bitsize > cd->max_insn_bitsize)
+ cd->max_insn_bitsize = isa->max_insn_bitsize;
+
+ ++n_isas;
+ }
+
+ /* Data derived from the mach spec. */
+ for (i = 0; i < MAX_MACHS; ++i)
+ if (((1 << i) & machs) != 0)
+ {
+ const CGEN_MACH *mach = & m32r_cgen_mach_table[i];
+
+ ++n_machs;
+ }
+
+ /* Determine which hw elements are used by MACH. */
+ build_hw_table (cd);
+
+ /* Build the ifield table. */
+ build_ifield_table (cd);
+
+ /* Determine which operands are used by MACH/ISA. */
+ build_operand_table (cd);
+
+ /* Build the instruction table. */
+ build_insn_table (cd);
+}
+
+/* Initialize a cpu table and return a descriptor.
+ It's much like opening a file, and must be the first function called.
+ The arguments are a set of (type/value) pairs, terminated with
+ CGEN_CPU_OPEN_END.
+
+ Currently supported values:
+ CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
+ CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
+ CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
+ CGEN_CPU_OPEN_ENDIAN: specify endian choice
+ CGEN_CPU_OPEN_END: terminates arguments
+
+ ??? Simultaneous multiple isas might not make sense, but it's not (yet)
+ precluded.
+
+ ??? We only support ISO C stdargs here, not K&R.
+ Laziness, plus experiment to see if anything requires K&R - eventually
+ K&R will no longer be supported - e.g. GDB is currently trying this. */
+
+CGEN_CPU_DESC
+m32r_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
+{
+ CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
+ static int init_p;
+ unsigned int isas = 0; /* 0 = "unspecified" */
+ unsigned int machs = 0; /* 0 = "unspecified" */
+ enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
+ va_list ap;
+
+ if (! init_p)
+ {
+ init_tables ();
+ init_p = 1;
+ }
+
+ memset (cd, 0, sizeof (*cd));
+
+ va_start (ap, arg_type);
+ while (arg_type != CGEN_CPU_OPEN_END)
+ {
+ switch (arg_type)
+ {
+ case CGEN_CPU_OPEN_ISAS :
+ isas = va_arg (ap, unsigned int);
+ break;
+ case CGEN_CPU_OPEN_MACHS :
+ machs = va_arg (ap, unsigned int);
+ break;
+ case CGEN_CPU_OPEN_BFDMACH :
+ {
+ const char *name = va_arg (ap, const char *);
+ const CGEN_MACH *mach =
+ lookup_mach_via_bfd_name (m32r_cgen_mach_table, name);
+
+ machs |= mach->num << 1;
+ break;
+ }
+ case CGEN_CPU_OPEN_ENDIAN :
+ endian = va_arg (ap, enum cgen_endian);
+ break;
+ default :
+ fprintf (stderr, "m32r_cgen_cpu_open: unsupported argument `%d'\n",
+ arg_type);
+ abort (); /* ??? return NULL? */
+ }
+ arg_type = va_arg (ap, enum cgen_cpu_open_arg);
+ }
+ va_end (ap);
+
+ /* mach unspecified means "all" */
+ if (machs == 0)
+ machs = (1 << MAX_MACHS) - 1;
+ /* base mach is always selected */
+ machs |= 1;
+ /* isa unspecified means "all" */
+ if (isas == 0)
+ isas = (1 << MAX_ISAS) - 1;
+ if (endian == CGEN_ENDIAN_UNKNOWN)
+ {
+ /* ??? If target has only one, could have a default. */
+ fprintf (stderr, "m32r_cgen_cpu_open: no endianness specified\n");
+ abort ();
+ }
+
+ cd->isas = isas;
+ cd->machs = machs;
+ cd->endian = endian;
+ /* FIXME: for the sparc case we can determine insn-endianness statically.
+ The worry here is where both data and insn endian can be independently
+ chosen, in which case this function will need another argument.
+ Actually, will want to allow for more arguments in the future anyway. */
+ cd->insn_endian = endian;
+
+ /* Table (re)builder. */
+ cd->rebuild_tables = m32r_cgen_rebuild_tables;
+ m32r_cgen_rebuild_tables (cd);
+
+ return (CGEN_CPU_DESC) cd;
+}
+
+/* Cover fn to m32r_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
+ MACH_NAME is the bfd name of the mach. */
+
+CGEN_CPU_DESC
+m32r_cgen_cpu_open_1 (mach_name, endian)
+ const char *mach_name;
+ enum cgen_endian endian;
+{
+ return m32r_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
+ CGEN_CPU_OPEN_ENDIAN, endian,
+ CGEN_CPU_OPEN_END);
+}
+
+/* Close a cpu table.
+ ??? This can live in a machine independent file, but there's currently
+ no place to put this file (there's no libcgen). libopcodes is the wrong
+ place as some simulator ports use this but they don't use libopcodes. */
+
+void
+m32r_cgen_cpu_close (cd)
+ CGEN_CPU_DESC cd;
+{
+ if (cd->insn_table.init_entries)
+ free ((CGEN_INSN *) cd->insn_table.init_entries);
+ if (cd->hw_table.entries)
+ free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
+ free (cd);
+}
+
diff --git a/opcodes/m32r-desc.h b/opcodes/m32r-desc.h
new file mode 100644
index 00000000000..6a3636cd55c
--- /dev/null
+++ b/opcodes/m32r-desc.h
@@ -0,0 +1,219 @@
+/* CPU data header for m32r.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef M32R_CPU_H
+#define M32R_CPU_H
+
+#define CGEN_ARCH m32r
+
+/* Given symbol S, return m32r_cgen_<S>. */
+#define CGEN_SYM(s) CONCAT3 (m32r,_cgen_,s)
+
+/* Selected cpu families. */
+#define HAVE_CPU_M32RBF
+
+#define CGEN_INSN_LSB0_P 0
+
+/* Maximum size of any insn (in bytes). */
+#define CGEN_MAX_INSN_SIZE 4
+
+#define CGEN_INT_INSN_P 1
+
+/* FIXME: Need to compute CGEN_MAX_SYNTAX_BYTES. */
+
+/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands.
+ e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands
+ we can't hash on everything up to the space. */
+#define CGEN_MNEMONIC_OPERANDS
+/* Maximum number of operands any insn or macro-insn has. */
+#define CGEN_MAX_INSN_OPERANDS 16
+
+/* Maximum number of fields in an instruction. */
+#define CGEN_MAX_IFMT_OPERANDS 7
+
+/* Enums. */
+
+/* Enum declaration for insn format enums. */
+typedef enum insn_op1 {
+ OP1_0, OP1_1, OP1_2, OP1_3
+ , OP1_4, OP1_5, OP1_6, OP1_7
+ , OP1_8, OP1_9, OP1_10, OP1_11
+ , OP1_12, OP1_13, OP1_14, OP1_15
+} INSN_OP1;
+
+/* Enum declaration for op2 enums. */
+typedef enum insn_op2 {
+ OP2_0, OP2_1, OP2_2, OP2_3
+ , OP2_4, OP2_5, OP2_6, OP2_7
+ , OP2_8, OP2_9, OP2_10, OP2_11
+ , OP2_12, OP2_13, OP2_14, OP2_15
+} INSN_OP2;
+
+/* Enum declaration for . */
+typedef enum gr_names {
+ H_GR_FP = 13, H_GR_LR = 14, H_GR_SP = 15, H_GR_R0 = 0
+ , H_GR_R1 = 1, H_GR_R2 = 2, H_GR_R3 = 3, H_GR_R4 = 4
+ , H_GR_R5 = 5, H_GR_R6 = 6, H_GR_R7 = 7, H_GR_R8 = 8
+ , H_GR_R9 = 9, H_GR_R10 = 10, H_GR_R11 = 11, H_GR_R12 = 12
+ , H_GR_R13 = 13, H_GR_R14 = 14, H_GR_R15 = 15
+} GR_NAMES;
+
+/* Enum declaration for . */
+typedef enum cr_names {
+ H_CR_PSW = 0, H_CR_CBR = 1, H_CR_SPI = 2, H_CR_SPU = 3
+ , H_CR_BPC = 6, H_CR_BBPSW = 8, H_CR_BBPC = 14, H_CR_CR0 = 0
+ , H_CR_CR1 = 1, H_CR_CR2 = 2, H_CR_CR3 = 3, H_CR_CR4 = 4
+ , H_CR_CR5 = 5, H_CR_CR6 = 6, H_CR_CR7 = 7, H_CR_CR8 = 8
+ , H_CR_CR9 = 9, H_CR_CR10 = 10, H_CR_CR11 = 11, H_CR_CR12 = 12
+ , H_CR_CR13 = 13, H_CR_CR14 = 14, H_CR_CR15 = 15
+} CR_NAMES;
+
+/* Attributes. */
+
+/* Enum declaration for machine type selection. */
+typedef enum mach_attr {
+ MACH_BASE, MACH_M32R
+ , MACH_MAX
+} MACH_ATTR;
+
+/* Enum declaration for instruction set selection. */
+typedef enum isa_attr {
+ ISA_M32R, ISA_MAX
+} ISA_ATTR;
+
+/* Number of architecture variants. */
+#define MAX_ISAS 1
+#define MAX_MACHS ((int) MACH_MAX)
+
+/* Ifield support. */
+
+extern const struct cgen_ifld m32r_cgen_ifld_table[];
+
+/* Ifield attribute indices. */
+
+/* Enum declaration for cgen_ifld attrs. */
+typedef enum cgen_ifld_attr {
+ CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED
+ , CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_RELOC, CGEN_IFLD_END_BOOLS
+ , CGEN_IFLD_START_NBOOLS = 31, CGEN_IFLD_MACH, CGEN_IFLD_END_NBOOLS
+} CGEN_IFLD_ATTR;
+
+/* Number of non-boolean elements in cgen_ifld_attr. */
+#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1)
+
+/* Enum declaration for m32r ifield types. */
+typedef enum ifield_type {
+ M32R_F_NIL, M32R_F_OP1, M32R_F_OP2, M32R_F_COND
+ , M32R_F_R1, M32R_F_R2, M32R_F_SIMM8, M32R_F_SIMM16
+ , M32R_F_SHIFT_OP2, M32R_F_UIMM4, M32R_F_UIMM5, M32R_F_UIMM16
+ , M32R_F_UIMM24, M32R_F_HI16, M32R_F_DISP8, M32R_F_DISP16
+ , M32R_F_DISP24
+ , M32R_F_MAX
+} IFIELD_TYPE;
+
+#define MAX_IFLD ((int) M32R_F_MAX)
+
+/* Hardware attribute indices. */
+
+/* Enum declaration for cgen_hw attrs. */
+typedef enum cgen_hw_attr {
+ CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
+ , CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH, CGEN_HW_END_NBOOLS
+} CGEN_HW_ATTR;
+
+/* Number of non-boolean elements in cgen_hw_attr. */
+#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1)
+
+/* Enum declaration for m32r hardware types. */
+typedef enum cgen_hw_type {
+ HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR
+ , HW_H_IADDR, HW_H_PC, HW_H_HI16, HW_H_SLO16
+ , HW_H_ULO16, HW_H_GR, HW_H_CR, HW_H_ACCUM
+ , HW_H_COND, HW_H_PSW, HW_H_BPSW, HW_H_BBPSW
+ , HW_H_LOCK, HW_MAX
+} CGEN_HW_TYPE;
+
+#define MAX_HW ((int) HW_MAX)
+
+/* Operand attribute indices. */
+
+/* Enum declaration for cgen_operand attrs. */
+typedef enum cgen_operand_attr {
+ CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT
+ , CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY
+ , CGEN_OPERAND_RELOC, CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31
+ , CGEN_OPERAND_MACH, CGEN_OPERAND_END_NBOOLS
+} CGEN_OPERAND_ATTR;
+
+/* Number of non-boolean elements in cgen_operand_attr. */
+#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1)
+
+/* Enum declaration for m32r operand types. */
+typedef enum cgen_operand_type {
+ M32R_OPERAND_PC, M32R_OPERAND_SR, M32R_OPERAND_DR, M32R_OPERAND_SRC1
+ , M32R_OPERAND_SRC2, M32R_OPERAND_SCR, M32R_OPERAND_DCR, M32R_OPERAND_SIMM8
+ , M32R_OPERAND_SIMM16, M32R_OPERAND_UIMM4, M32R_OPERAND_UIMM5, M32R_OPERAND_UIMM16
+ , M32R_OPERAND_HASH, M32R_OPERAND_HI16, M32R_OPERAND_SLO16, M32R_OPERAND_ULO16
+ , M32R_OPERAND_UIMM24, M32R_OPERAND_DISP8, M32R_OPERAND_DISP16, M32R_OPERAND_DISP24
+ , M32R_OPERAND_CONDBIT, M32R_OPERAND_ACCUM, M32R_OPERAND_MAX
+} CGEN_OPERAND_TYPE;
+
+/* Number of operands types. */
+#define MAX_OPERANDS ((int) M32R_OPERAND_MAX)
+
+/* Maximum number of operands referenced by any insn. */
+#define MAX_OPERAND_INSTANCES 11
+
+/* Insn attribute indices. */
+
+/* Enum declaration for cgen_insn attrs. */
+typedef enum cgen_insn_attr {
+ CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
+ , CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX
+ , CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_FILL_SLOT, CGEN_INSN_SPECIAL
+ , CGEN_INSN_END_BOOLS, CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_PIPE
+ , CGEN_INSN_END_NBOOLS
+} CGEN_INSN_ATTR;
+
+/* Number of non-boolean elements in cgen_insn_attr. */
+#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1)
+
+/* cgen.h uses things we just defined. */
+#include "opcode/cgen.h"
+
+/* Attributes. */
+extern const CGEN_ATTR_TABLE m32r_cgen_hardware_attr_table[];
+extern const CGEN_ATTR_TABLE m32r_cgen_ifield_attr_table[];
+extern const CGEN_ATTR_TABLE m32r_cgen_operand_attr_table[];
+extern const CGEN_ATTR_TABLE m32r_cgen_insn_attr_table[];
+
+/* Hardware decls. */
+
+extern CGEN_KEYWORD m32r_cgen_opval_gr_names;
+extern CGEN_KEYWORD m32r_cgen_opval_cr_names;
+
+
+
+
+#endif /* M32R_CPU_H */
diff --git a/opcodes/m32r-dis.c b/opcodes/m32r-dis.c
new file mode 100644
index 00000000000..48c591a6941
--- /dev/null
+++ b/opcodes/m32r-dis.c
@@ -0,0 +1,557 @@
+/* Disassembler interface for targets using CGEN. -*- C -*-
+ CGEN: Cpu tools GENerator
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+- the resultant file is machine generated, cgen-dis.in isn't
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ??? Eventually more and more of this stuff can go to cpu-independent files.
+ Keep that in mind. */
+
+#include "sysdep.h"
+#include <stdio.h>
+#include "ansidecl.h"
+#include "dis-asm.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "m32r-desc.h"
+#include "m32r-opc.h"
+#include "opintl.h"
+
+/* Default text to print if an instruction isn't recognized. */
+#define UNKNOWN_INSN_MSG _("*unknown*")
+
+static void print_normal
+ PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned int, bfd_vma, int));
+static void print_address
+ PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
+static void print_keyword
+ PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
+static void print_insn_normal
+ PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
+ bfd_vma, int));
+static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma,
+ disassemble_info *, char *, int));
+static int default_print_insn
+ PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));
+
+/* -- disassembler routines inserted here */
+
+/* -- dis.c */
+
+/* Immediate values are prefixed with '#'. */
+
+#define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length) \
+do { \
+ if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_HASH_PREFIX)) \
+ (*info->fprintf_func) (info->stream, "#"); \
+} while (0)
+
+/* Handle '#' prefixes as operands. */
+
+static void
+print_hash (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+ (*info->fprintf_func) (info->stream, "#");
+}
+
+#undef CGEN_PRINT_INSN
+#define CGEN_PRINT_INSN my_print_insn
+
+static int
+my_print_insn (cd, pc, info)
+ CGEN_CPU_DESC cd;
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ char buffer[CGEN_MAX_INSN_SIZE];
+ char *buf = buffer;
+ int status;
+ int buflen = (pc & 3) == 0 ? 4 : 2;
+
+ /* Read the base part of the insn. */
+
+ status = (*info->read_memory_func) (pc, buf, buflen, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+
+ /* 32 bit insn? */
+ if ((pc & 3) == 0 && (buf[0] & 0x80) != 0)
+ return print_insn (cd, pc, info, buf, buflen);
+
+ /* Print the first insn. */
+ if ((pc & 3) == 0)
+ {
+ if (print_insn (cd, pc, info, buf, 2) == 0)
+ (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
+ buf += 2;
+ }
+
+ if (buf[0] & 0x80)
+ {
+ /* Parallel. */
+ (*info->fprintf_func) (info->stream, " || ");
+ buf[0] &= 0x7f;
+ }
+ else
+ (*info->fprintf_func) (info->stream, " -> ");
+
+ /* The "& 3" is to pass a consistent address.
+ Parallel insns arguably both begin on the word boundary.
+ Also, branch insns are calculated relative to the word boundary. */
+ if (print_insn (cd, pc & ~ (bfd_vma) 3, info, buf, 2) == 0)
+ (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
+
+ return (pc & 3) ? 2 : 4;
+}
+
+/* -- */
+
+/* Main entry point for printing operands.
+ XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
+ of dis-asm.h on cgen.h.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `print_insn_normal', but keeping it
+ separate makes clear the interface between `print_insn_normal' and each of
+ the handlers.
+*/
+
+void
+m32r_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ PTR xinfo;
+ CGEN_FIELDS *fields;
+ void const *attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) xinfo;
+
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ print_keyword (cd, info, & m32r_cgen_opval_cr_names, fields->f_r1, 0);
+ break;
+ case M32R_OPERAND_DISP16 :
+ print_address (cd, info, fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
+ break;
+ case M32R_OPERAND_DISP24 :
+ print_address (cd, info, fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
+ break;
+ case M32R_OPERAND_DISP8 :
+ print_address (cd, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
+ break;
+ case M32R_OPERAND_DR :
+ print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r1, 0);
+ break;
+ case M32R_OPERAND_HASH :
+ print_hash (cd, info, fields->f_nil, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ break;
+ case M32R_OPERAND_HI16 :
+ print_normal (cd, info, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT), pc, length);
+ break;
+ case M32R_OPERAND_SCR :
+ print_keyword (cd, info, & m32r_cgen_opval_cr_names, fields->f_r2, 0);
+ break;
+ case M32R_OPERAND_SIMM16 :
+ print_normal (cd, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case M32R_OPERAND_SIMM8 :
+ print_normal (cd, info, fields->f_simm8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case M32R_OPERAND_SLO16 :
+ print_normal (cd, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
+ break;
+ case M32R_OPERAND_SR :
+ print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r2, 0);
+ break;
+ case M32R_OPERAND_SRC1 :
+ print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r1, 0);
+ break;
+ case M32R_OPERAND_SRC2 :
+ print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r2, 0);
+ break;
+ case M32R_OPERAND_UIMM16 :
+ print_normal (cd, info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case M32R_OPERAND_UIMM24 :
+ print_address (cd, info, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR), pc, length);
+ break;
+ case M32R_OPERAND_UIMM4 :
+ print_normal (cd, info, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case M32R_OPERAND_UIMM5 :
+ print_normal (cd, info, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
+ break;
+ case M32R_OPERAND_ULO16 :
+ print_normal (cd, info, fields->f_uimm16, 0, pc, length);
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
+ opindex);
+ abort ();
+ }
+}
+
+cgen_print_fn * const m32r_cgen_print_handlers[] =
+{
+ print_insn_normal,
+};
+
+
+void
+m32r_cgen_init_dis (cd)
+ CGEN_CPU_DESC cd;
+{
+ m32r_cgen_init_opcode_table (cd);
+ m32r_cgen_init_ibld_table (cd);
+ cd->print_handlers = & m32r_cgen_print_handlers[0];
+ cd->print_operand = m32r_cgen_print_operand;
+}
+
+
+/* Default print handler. */
+
+static void
+print_normal (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ long value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+
+#ifdef CGEN_PRINT_NORMAL
+ CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
+#endif
+
+ /* Print the operand as directed by the attributes. */
+ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
+ ; /* nothing to do */
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
+ (*info->fprintf_func) (info->stream, "%ld", value);
+ else
+ (*info->fprintf_func) (info->stream, "0x%lx", value);
+}
+
+/* Default address handler. */
+
+static void
+print_address (cd, dis_info, value, attrs, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ bfd_vma value;
+ unsigned int attrs;
+ bfd_vma pc;
+ int length;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+
+#ifdef CGEN_PRINT_ADDRESS
+ CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
+#endif
+
+ /* Print the operand as directed by the attributes. */
+ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
+ ; /* nothing to do */
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
+ (*info->print_address_func) (value, info);
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
+ (*info->print_address_func) (value, info);
+ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
+ (*info->fprintf_func) (info->stream, "%ld", (long) value);
+ else
+ (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
+}
+
+/* Keyword print handler. */
+
+static void
+print_keyword (cd, dis_info, keyword_table, value, attrs)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ CGEN_KEYWORD *keyword_table;
+ long value;
+ unsigned int attrs;
+{
+ disassemble_info *info = (disassemble_info *) dis_info;
+ const CGEN_KEYWORD_ENTRY *ke;
+
+ ke = cgen_keyword_lookup_value (keyword_table, value);
+ if (ke != NULL)
+ (*info->fprintf_func) (info->stream, "%s", ke->name);
+ else
+ (*info->fprintf_func) (info->stream, "???");
+}
+
+/* Default insn printer.
+
+ DIS_INFO is defined as `PTR' so the disassembler needn't know anything
+ about disassemble_info. */
+
+static void
+print_insn_normal (cd, dis_info, insn, fields, pc, length)
+ CGEN_CPU_DESC cd;
+ PTR dis_info;
+ const CGEN_INSN *insn;
+ CGEN_FIELDS *fields;
+ bfd_vma pc;
+ int length;
+{
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ disassemble_info *info = (disassemble_info *) dis_info;
+ const unsigned char *syn;
+
+ CGEN_INIT_PRINT (cd);
+
+ for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
+ {
+ if (CGEN_SYNTAX_MNEMONIC_P (*syn))
+ {
+ (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
+ continue;
+ }
+ if (CGEN_SYNTAX_CHAR_P (*syn))
+ {
+ (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
+ continue;
+ }
+
+ /* We have an operand. */
+ m32r_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
+ fields, CGEN_INSN_ATTRS (insn), pc, length);
+ }
+}
+
+/* Utility to print an insn.
+ BUF is the base part of the insn, target byte order, BUFLEN bytes long.
+ The result is the size of the insn in bytes or zero for an unknown insn
+ or -1 if an error occurs fetching data (memory_error_func will have
+ been called). */
+
+static int
+print_insn (cd, pc, info, buf, buflen)
+ CGEN_CPU_DESC cd;
+ bfd_vma pc;
+ disassemble_info *info;
+ char *buf;
+ int buflen;
+{
+ unsigned long insn_value;
+ const CGEN_INSN_LIST *insn_list;
+ CGEN_EXTRACT_INFO ex_info;
+
+ ex_info.dis_info = info;
+ ex_info.valid = (1 << (cd->base_insn_bitsize / 8)) - 1;
+ ex_info.insn_bytes = buf;
+
+ switch (buflen)
+ {
+ case 1:
+ insn_value = buf[0];
+ break;
+ case 2:
+ insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
+ break;
+ case 4:
+ insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
+ break;
+ default:
+ abort ();
+ }
+
+ /* The instructions are stored in hash lists.
+ Pick the first one and keep trying until we find the right one. */
+
+ insn_list = CGEN_DIS_LOOKUP_INSN (cd, buf, insn_value);
+ while (insn_list != NULL)
+ {
+ const CGEN_INSN *insn = insn_list->insn;
+ CGEN_FIELDS fields;
+ int length;
+
+#if 0 /* not needed as insn shouldn't be in hash lists if not supported */
+ /* Supported by this cpu? */
+ if (! m32r_cgen_insn_supported (cd, insn))
+ continue;
+#endif
+
+ /* Basic bit mask must be correct. */
+ /* ??? May wish to allow target to defer this check until the extract
+ handler. */
+ if ((insn_value & CGEN_INSN_BASE_MASK (insn))
+ == CGEN_INSN_BASE_VALUE (insn))
+ {
+ /* Printing is handled in two passes. The first pass parses the
+ machine insn and extracts the fields. The second pass prints
+ them. */
+
+ length = CGEN_EXTRACT_FN (cd, insn)
+ (cd, insn, &ex_info, insn_value, &fields, pc);
+ /* length < 0 -> error */
+ if (length < 0)
+ return length;
+ if (length > 0)
+ {
+ CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
+ /* length is in bits, result is in bytes */
+ return length / 8;
+ }
+ }
+
+ insn_list = CGEN_DIS_NEXT_INSN (insn_list);
+ }
+
+ return 0;
+}
+
+/* Default value for CGEN_PRINT_INSN.
+ The result is the size of the insn in bytes or zero for an unknown insn
+ or -1 if an error occured fetching bytes. */
+
+#ifndef CGEN_PRINT_INSN
+#define CGEN_PRINT_INSN default_print_insn
+#endif
+
+static int
+default_print_insn (cd, pc, info)
+ CGEN_CPU_DESC cd;
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ char buf[CGEN_MAX_INSN_SIZE];
+ int status;
+
+ /* Read the base part of the insn. */
+
+ status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return -1;
+ }
+
+ return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8);
+}
+
+/* Main entry point.
+ Print one instruction from PC on INFO->STREAM.
+ Return the size of the instruction (in bytes). */
+
+int
+print_insn_m32r (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ static CGEN_CPU_DESC cd = 0;
+ static prev_isa,prev_mach,prev_endian;
+ int length;
+ int isa,mach;
+ int endian = (info->endian == BFD_ENDIAN_BIG
+ ? CGEN_ENDIAN_BIG
+ : CGEN_ENDIAN_LITTLE);
+ enum bfd_architecture arch;
+
+ /* ??? gdb will set mach but leave the architecture as "unknown" */
+#ifndef CGEN_BFD_ARCH
+#define CGEN_BFD_ARCH bfd_arch_m32r
+#endif
+ arch = info->arch;
+ if (arch == bfd_arch_unknown)
+ arch = CGEN_BFD_ARCH;
+
+ /* There's no standard way to compute the isa number (e.g. for arm thumb)
+ so we leave it to the target. */
+#ifdef CGEN_COMPUTE_ISA
+ isa = CGEN_COMPUTE_ISA (info);
+#else
+ isa = 0;
+#endif
+
+ mach = info->mach;
+
+ /* If we've switched cpu's, close the current table and open a new one. */
+ if (cd
+ && (isa != prev_isa
+ || mach != prev_mach
+ || endian != prev_endian))
+ {
+ m32r_cgen_cpu_close (cd);
+ cd = 0;
+ }
+
+ /* If we haven't initialized yet, initialize the opcode table. */
+ if (! cd)
+ {
+ const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
+ const char *mach_name;
+
+ if (!arch_type)
+ abort ();
+ mach_name = arch_type->printable_name;
+
+ prev_isa = isa;
+ prev_mach = mach;
+ prev_endian = endian;
+ cd = m32r_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
+ CGEN_CPU_OPEN_BFDMACH, mach_name,
+ CGEN_CPU_OPEN_ENDIAN, prev_endian,
+ CGEN_CPU_OPEN_END);
+ if (!cd)
+ abort ();
+ m32r_cgen_init_dis (cd);
+ }
+
+ /* We try to have as much common code as possible.
+ But at this point some targets need to take over. */
+ /* ??? Some targets may need a hook elsewhere. Try to avoid this,
+ but if not possible try to move this hook elsewhere rather than
+ have two hooks. */
+ length = CGEN_PRINT_INSN (cd, pc, info);
+ if (length > 0)
+ return length;
+ if (length < 0)
+ return -1;
+
+ (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
+ return cd->default_insn_bitsize / 8;
+}
diff --git a/opcodes/m32r-ibld.c b/opcodes/m32r-ibld.c
new file mode 100644
index 00000000000..fa15d7e4514
--- /dev/null
+++ b/opcodes/m32r-ibld.c
@@ -0,0 +1,1120 @@
+/* Instruction building/extraction support for m32r. -*- C -*-
+
+THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
+- the resultant file is machine generated, cgen-ibld.in isn't
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* ??? Eventually more and more of this stuff can go to cpu-independent files.
+ Keep that in mind. */
+
+#include "sysdep.h"
+#include <ctype.h>
+#include <stdio.h>
+#include "ansidecl.h"
+#include "dis-asm.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "m32r-desc.h"
+#include "m32r-opc.h"
+#include "opintl.h"
+
+#undef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#undef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+/* Used by the ifield rtx function. */
+#define FLD(f) (fields->f)
+
+static const char * insert_normal
+ PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
+static const char * insert_insn_normal
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
+ CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
+
+static int extract_normal
+ PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
+ unsigned int, unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int, bfd_vma, long *));
+static int extract_insn_normal
+ PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
+ CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
+
+/* Operand insertion. */
+
+#if ! CGEN_INT_INSN_P
+
+/* Subroutine of insert_normal. */
+
+static CGEN_INLINE void
+insert_1 (cd, value, start, length, word_length, bufp)
+ CGEN_CPU_DESC cd;
+ unsigned long value;
+ int start,length,word_length;
+ unsigned char *bufp;
+{
+ unsigned long x,mask;
+ int shift;
+ int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
+
+ switch (word_length)
+ {
+ case 8:
+ x = *bufp;
+ break;
+ case 16:
+ if (big_p)
+ x = bfd_getb16 (bufp);
+ else
+ x = bfd_getl16 (bufp);
+ break;
+ case 24:
+ /* ??? This may need reworking as these cases don't necessarily
+ want the first byte and the last two bytes handled like this. */
+ if (big_p)
+ x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
+ else
+ x = bfd_getl16 (bufp) | (bufp[2] << 16);
+ break;
+ case 32:
+ if (big_p)
+ x = bfd_getb32 (bufp);
+ else
+ x = bfd_getl32 (bufp);
+ break;
+ default :
+ abort ();
+ }
+
+ /* Written this way to avoid undefined behaviour. */
+ mask = (((1L << (length - 1)) - 1) << 1) | 1;
+ if (CGEN_INSN_LSB0_P)
+ shift = (start + 1) - length;
+ else
+ shift = (word_length - (start + length));
+ x = (x & ~(mask << shift)) | ((value & mask) << shift);
+
+ switch (word_length)
+ {
+ case 8:
+ *bufp = x;
+ break;
+ case 16:
+ if (big_p)
+ bfd_putb16 (x, bufp);
+ else
+ bfd_putl16 (x, bufp);
+ break;
+ case 24:
+ /* ??? This may need reworking as these cases don't necessarily
+ want the first byte and the last two bytes handled like this. */
+ if (big_p)
+ {
+ bufp[0] = x >> 16;
+ bfd_putb16 (x, bufp + 1);
+ }
+ else
+ {
+ bfd_putl16 (x, bufp);
+ bufp[2] = x >> 16;
+ }
+ break;
+ case 32:
+ if (big_p)
+ bfd_putb32 (x, bufp);
+ else
+ bfd_putl32 (x, bufp);
+ break;
+ default :
+ abort ();
+ }
+}
+
+#endif /* ! CGEN_INT_INSN_P */
+
+/* Default insertion routine.
+
+ ATTRS is a mask of the boolean attributes.
+ WORD_OFFSET is the offset in bits from the start of the insn of the value.
+ WORD_LENGTH is the length of the word in bits in which the value resides.
+ START is the starting bit number in the word, architecture origin.
+ LENGTH is the length of VALUE in bits.
+ TOTAL_LENGTH is the total length of the insn in bits.
+
+ The result is an error message or NULL if success. */
+
+/* ??? This duplicates functionality with bfd's howto table and
+ bfd_install_relocation. */
+/* ??? This doesn't handle bfd_vma's. Create another function when
+ necessary. */
+
+static const char *
+insert_normal (cd, value, attrs, word_offset, start, length, word_length,
+ total_length, buffer)
+ CGEN_CPU_DESC cd;
+ long value;
+ unsigned int attrs;
+ unsigned int word_offset, start, length, word_length, total_length;
+ CGEN_INSN_BYTES_PTR buffer;
+{
+ static char errbuf[100];
+ /* Written this way to avoid undefined behaviour. */
+ unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
+
+ /* If LENGTH is zero, this operand doesn't contribute to the value. */
+ if (length == 0)
+ return NULL;
+
+ if (CGEN_INT_INSN_P
+ && word_offset != 0)
+ abort ();
+
+ if (word_length > 32)
+ abort ();
+
+ /* For architectures with insns smaller than the base-insn-bitsize,
+ word_length may be too big. */
+ if (cd->min_insn_bitsize < cd->base_insn_bitsize)
+ {
+ if (word_offset == 0
+ && word_length > total_length)
+ word_length = total_length;
+ }
+
+ /* Ensure VALUE will fit. */
+ if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
+ {
+ unsigned long maxval = mask;
+ if ((unsigned long) value > maxval)
+ {
+ /* xgettext:c-format */
+ sprintf (errbuf,
+ _("operand out of range (%lu not between 0 and %lu)"),
+ value, maxval);
+ return errbuf;
+ }
+ }
+ else
+ {
+ long minval = - (1L << (length - 1));
+ long maxval = (1L << (length - 1)) - 1;
+ if (value < minval || value > maxval)
+ {
+ sprintf
+ /* xgettext:c-format */
+ (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
+ value, minval, maxval);
+ return errbuf;
+ }
+ }
+
+#if CGEN_INT_INSN_P
+
+ {
+ int shift;
+
+ if (CGEN_INSN_LSB0_P)
+ shift = (start + 1) - length;
+ else
+ shift = word_length - (start + length);
+ *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
+ }
+
+#else /* ! CGEN_INT_INSN_P */
+
+ {
+ unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
+
+ insert_1 (cd, value, start, length, word_length, bufp);
+ }
+
+#endif /* ! CGEN_INT_INSN_P */
+
+ return NULL;
+}
+
+/* Default insn builder (insert handler).
+ The instruction is recorded in CGEN_INT_INSN_P byte order
+ (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
+ recorded in host byte order, otherwise BUFFER is an array of bytes and the
+ value is recorded in target byte order).
+ The result is an error message or NULL if success. */
+
+static const char *
+insert_insn_normal (cd, insn, fields, buffer, pc)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN * insn;
+ CGEN_FIELDS * fields;
+ CGEN_INSN_BYTES_PTR buffer;
+ bfd_vma pc;
+{
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ unsigned long value;
+ const unsigned char * syn;
+
+ CGEN_INIT_INSERT (cd);
+ value = CGEN_INSN_BASE_VALUE (insn);
+
+ /* If we're recording insns as numbers (rather than a string of bytes),
+ target byte order handling is deferred until later. */
+
+#if CGEN_INT_INSN_P
+
+ *buffer = value;
+
+#else
+
+ cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
+ CGEN_FIELDS_BITSIZE (fields)),
+ value);
+
+#endif /* ! CGEN_INT_INSN_P */
+
+ /* ??? It would be better to scan the format's fields.
+ Still need to be able to insert a value based on the operand though;
+ e.g. storing a branch displacement that got resolved later.
+ Needs more thought first. */
+
+ for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
+ {
+ const char *errmsg;
+
+ if (CGEN_SYNTAX_CHAR_P (* syn))
+ continue;
+
+ errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
+ fields, buffer, pc);
+ if (errmsg)
+ return errmsg;
+ }
+
+ return NULL;
+}
+
+/* Operand extraction. */
+
+#if ! CGEN_INT_INSN_P
+
+/* Subroutine of extract_normal.
+ Ensure sufficient bytes are cached in EX_INFO.
+ OFFSET is the offset in bytes from the start of the insn of the value.
+ BYTES is the length of the needed value.
+ Returns 1 for success, 0 for failure. */
+
+static CGEN_INLINE int
+fill_cache (cd, ex_info, offset, bytes, pc)
+ CGEN_CPU_DESC cd;
+ CGEN_EXTRACT_INFO *ex_info;
+ int offset, bytes;
+ bfd_vma pc;
+{
+ /* It's doubtful that the middle part has already been fetched so
+ we don't optimize that case. kiss. */
+ int mask;
+ disassemble_info *info = (disassemble_info *) ex_info->dis_info;
+
+ /* First do a quick check. */
+ mask = (1 << bytes) - 1;
+ if (((ex_info->valid >> offset) & mask) == mask)
+ return 1;
+
+ /* Search for the first byte we need to read. */
+ for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
+ if (! (mask & ex_info->valid))
+ break;
+
+ if (bytes)
+ {
+ int status;
+
+ pc += offset;
+ status = (*info->read_memory_func)
+ (pc, ex_info->insn_bytes + offset, bytes, info);
+
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, pc, info);
+ return 0;
+ }
+
+ ex_info->valid |= ((1 << bytes) - 1) << offset;
+ }
+
+ return 1;
+}
+
+/* Subroutine of extract_normal. */
+
+static CGEN_INLINE long
+extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
+ CGEN_CPU_DESC cd;
+ CGEN_EXTRACT_INFO *ex_info;
+ int start,length,word_length;
+ unsigned char *bufp;
+ bfd_vma pc;
+{
+ unsigned long x,mask;
+ int shift;
+ int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
+
+ switch (word_length)
+ {
+ case 8:
+ x = *bufp;
+ break;
+ case 16:
+ if (big_p)
+ x = bfd_getb16 (bufp);
+ else
+ x = bfd_getl16 (bufp);
+ break;
+ case 24:
+ /* ??? This may need reworking as these cases don't necessarily
+ want the first byte and the last two bytes handled like this. */
+ if (big_p)
+ x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
+ else
+ x = bfd_getl16 (bufp) | (bufp[2] << 16);
+ break;
+ case 32:
+ if (big_p)
+ x = bfd_getb32 (bufp);
+ else
+ x = bfd_getl32 (bufp);
+ break;
+ default :
+ abort ();
+ }
+
+ /* Written this way to avoid undefined behaviour. */
+ mask = (((1L << (length - 1)) - 1) << 1) | 1;
+ if (CGEN_INSN_LSB0_P)
+ shift = (start + 1) - length;
+ else
+ shift = (word_length - (start + length));
+ return (x >> shift) & mask;
+}
+
+#endif /* ! CGEN_INT_INSN_P */
+
+/* Default extraction routine.
+
+ INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
+ or sometimes less for cases like the m32r where the base insn size is 32
+ but some insns are 16 bits.
+ ATTRS is a mask of the boolean attributes. We only need `SIGNED',
+ but for generality we take a bitmask of all of them.
+ WORD_OFFSET is the offset in bits from the start of the insn of the value.
+ WORD_LENGTH is the length of the word in bits in which the value resides.
+ START is the starting bit number in the word, architecture origin.
+ LENGTH is the length of VALUE in bits.
+ TOTAL_LENGTH is the total length of the insn in bits.
+
+ Returns 1 for success, 0 for failure. */
+
+/* ??? The return code isn't properly used. wip. */
+
+/* ??? This doesn't handle bfd_vma's. Create another function when
+ necessary. */
+
+static int
+extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
+ word_length, total_length, pc, valuep)
+ CGEN_CPU_DESC cd;
+ CGEN_EXTRACT_INFO *ex_info;
+ CGEN_INSN_INT insn_value;
+ unsigned int attrs;
+ unsigned int word_offset, start, length, word_length, total_length;
+ bfd_vma pc;
+ long *valuep;
+{
+ CGEN_INSN_INT value;
+
+ /* If LENGTH is zero, this operand doesn't contribute to the value
+ so give it a standard value of zero. */
+ if (length == 0)
+ {
+ *valuep = 0;
+ return 1;
+ }
+
+ if (CGEN_INT_INSN_P
+ && word_offset != 0)
+ abort ();
+
+ if (word_length > 32)
+ abort ();
+
+ /* For architectures with insns smaller than the insn-base-bitsize,
+ word_length may be too big. */
+ if (cd->min_insn_bitsize < cd->base_insn_bitsize)
+ {
+ if (word_offset == 0
+ && word_length > total_length)
+ word_length = total_length;
+ }
+
+ /* Does the value reside in INSN_VALUE? */
+
+ if (word_offset == 0)
+ {
+ /* Written this way to avoid undefined behaviour. */
+ CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
+
+ if (CGEN_INSN_LSB0_P)
+ value = insn_value >> ((start + 1) - length);
+ else
+ value = insn_value >> (word_length - (start + length));
+ value &= mask;
+ /* sign extend? */
+ if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
+ && (value & (1L << (length - 1))))
+ value |= ~mask;
+ }
+
+#if ! CGEN_INT_INSN_P
+
+ else
+ {
+ unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
+
+ if (word_length > 32)
+ abort ();
+
+ if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
+ return 0;
+
+ value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
+ }
+
+#endif /* ! CGEN_INT_INSN_P */
+
+ *valuep = value;
+
+ return 1;
+}
+
+/* Default insn extractor.
+
+ INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
+ The extracted fields are stored in FIELDS.
+ EX_INFO is used to handle reading variable length insns.
+ Return the length of the insn in bits, or 0 if no match,
+ or -1 if an error occurs fetching data (memory_error_func will have
+ been called). */
+
+static int
+extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
+ CGEN_CPU_DESC cd;
+ const CGEN_INSN *insn;
+ CGEN_EXTRACT_INFO *ex_info;
+ CGEN_INSN_INT insn_value;
+ CGEN_FIELDS *fields;
+ bfd_vma pc;
+{
+ const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
+ const unsigned char *syn;
+
+ CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
+
+ CGEN_INIT_EXTRACT (cd);
+
+ for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
+ {
+ int length;
+
+ if (CGEN_SYNTAX_CHAR_P (*syn))
+ continue;
+
+ length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
+ ex_info, insn_value, fields, pc);
+ if (length <= 0)
+ return length;
+ }
+
+ /* We recognized and successfully extracted this insn. */
+ return CGEN_INSN_BITSIZE (insn);
+}
+
+/* machine generated code added here */
+
+/* Main entry point for operand insertion.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `parse_insn_normal', but keeping it
+ separate makes clear the interface between `parse_insn_normal' and each of
+ the handlers. It's also needed by GAS to insert operands that couldn't be
+ resolved during parsing.
+*/
+
+const char *
+m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_FIELDS * fields;
+ CGEN_INSN_BYTES_PTR buffer;
+ bfd_vma pc;
+{
+ const char * errmsg;
+ unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
+
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_DISP16 :
+ {
+ long value = fields->f_disp16;
+ value = ((int) (((value) - (pc))) >> (2));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, buffer);
+ }
+ break;
+ case M32R_OPERAND_DISP24 :
+ {
+ long value = fields->f_disp24;
+ value = ((int) (((value) - (pc))) >> (2));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, buffer);
+ }
+ break;
+ case M32R_OPERAND_DISP8 :
+ {
+ long value = fields->f_disp8;
+ value = ((int) (((value) - (((pc) & (-4))))) >> (2));
+ errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
+ }
+ break;
+ case M32R_OPERAND_DR :
+ errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_HASH :
+ errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
+ break;
+ case M32R_OPERAND_HI16 :
+ errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SCR :
+ errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SIMM16 :
+ errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SIMM8 :
+ errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SLO16 :
+ errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SR :
+ errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SRC1 :
+ errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_SRC2 :
+ errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_UIMM16 :
+ errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_UIMM24 :
+ errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_UIMM4 :
+ errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_UIMM5 :
+ errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
+ break;
+ case M32R_OPERAND_ULO16 :
+ errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
+ opindex);
+ abort ();
+ }
+
+ return errmsg;
+}
+
+/* Main entry point for operand extraction.
+
+ This function is basically just a big switch statement. Earlier versions
+ used tables to look up the function to use, but
+ - if the table contains both assembler and disassembler functions then
+ the disassembler contains much of the assembler and vice-versa,
+ - there's a lot of inlining possibilities as things grow,
+ - using a switch statement avoids the function call overhead.
+
+ This function could be moved into `print_insn_normal', but keeping it
+ separate makes clear the interface between `print_insn_normal' and each of
+ the handlers.
+*/
+
+int
+m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_EXTRACT_INFO *ex_info;
+ CGEN_INSN_INT insn_value;
+ CGEN_FIELDS * fields;
+ bfd_vma pc;
+{
+ int length;
+ unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
+
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
+ break;
+ case M32R_OPERAND_DISP16 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, pc, & value);
+ value = ((((value) << (2))) + (pc));
+ fields->f_disp16 = value;
+ }
+ break;
+ case M32R_OPERAND_DISP24 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, pc, & value);
+ value = ((((value) << (2))) + (pc));
+ fields->f_disp24 = value;
+ }
+ break;
+ case M32R_OPERAND_DISP8 :
+ {
+ long value;
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
+ value = ((((value) << (2))) + (((pc) & (-4))));
+ fields->f_disp8 = value;
+ }
+ break;
+ case M32R_OPERAND_DR :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
+ break;
+ case M32R_OPERAND_HASH :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
+ break;
+ case M32R_OPERAND_HI16 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
+ break;
+ case M32R_OPERAND_SCR :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
+ break;
+ case M32R_OPERAND_SIMM16 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
+ break;
+ case M32R_OPERAND_SIMM8 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
+ break;
+ case M32R_OPERAND_SLO16 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
+ break;
+ case M32R_OPERAND_SR :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
+ break;
+ case M32R_OPERAND_SRC1 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
+ break;
+ case M32R_OPERAND_SRC2 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
+ break;
+ case M32R_OPERAND_UIMM16 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
+ break;
+ case M32R_OPERAND_UIMM24 :
+ length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, pc, & fields->f_uimm24);
+ break;
+ case M32R_OPERAND_UIMM4 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
+ break;
+ case M32R_OPERAND_UIMM5 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
+ break;
+ case M32R_OPERAND_ULO16 :
+ length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
+ opindex);
+ abort ();
+ }
+
+ return length;
+}
+
+cgen_insert_fn * const m32r_cgen_insert_handlers[] =
+{
+ insert_insn_normal,
+};
+
+cgen_extract_fn * const m32r_cgen_extract_handlers[] =
+{
+ extract_insn_normal,
+};
+
+/* Getting values from cgen_fields is handled by a collection of functions.
+ They are distinguished by the type of the VALUE argument they return.
+ TODO: floating point, inlining support, remove cases where result type
+ not appropriate. */
+
+int
+m32r_cgen_get_int_operand (cd, opindex, fields)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ const CGEN_FIELDS * fields;
+{
+ int value;
+
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ value = fields->f_r1;
+ break;
+ case M32R_OPERAND_DISP16 :
+ value = fields->f_disp16;
+ break;
+ case M32R_OPERAND_DISP24 :
+ value = fields->f_disp24;
+ break;
+ case M32R_OPERAND_DISP8 :
+ value = fields->f_disp8;
+ break;
+ case M32R_OPERAND_DR :
+ value = fields->f_r1;
+ break;
+ case M32R_OPERAND_HASH :
+ value = fields->f_nil;
+ break;
+ case M32R_OPERAND_HI16 :
+ value = fields->f_hi16;
+ break;
+ case M32R_OPERAND_SCR :
+ value = fields->f_r2;
+ break;
+ case M32R_OPERAND_SIMM16 :
+ value = fields->f_simm16;
+ break;
+ case M32R_OPERAND_SIMM8 :
+ value = fields->f_simm8;
+ break;
+ case M32R_OPERAND_SLO16 :
+ value = fields->f_simm16;
+ break;
+ case M32R_OPERAND_SR :
+ value = fields->f_r2;
+ break;
+ case M32R_OPERAND_SRC1 :
+ value = fields->f_r1;
+ break;
+ case M32R_OPERAND_SRC2 :
+ value = fields->f_r2;
+ break;
+ case M32R_OPERAND_UIMM16 :
+ value = fields->f_uimm16;
+ break;
+ case M32R_OPERAND_UIMM24 :
+ value = fields->f_uimm24;
+ break;
+ case M32R_OPERAND_UIMM4 :
+ value = fields->f_uimm4;
+ break;
+ case M32R_OPERAND_UIMM5 :
+ value = fields->f_uimm5;
+ break;
+ case M32R_OPERAND_ULO16 :
+ value = fields->f_uimm16;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
+ opindex);
+ abort ();
+ }
+
+ return value;
+}
+
+bfd_vma
+m32r_cgen_get_vma_operand (cd, opindex, fields)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ const CGEN_FIELDS * fields;
+{
+ bfd_vma value;
+
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ value = fields->f_r1;
+ break;
+ case M32R_OPERAND_DISP16 :
+ value = fields->f_disp16;
+ break;
+ case M32R_OPERAND_DISP24 :
+ value = fields->f_disp24;
+ break;
+ case M32R_OPERAND_DISP8 :
+ value = fields->f_disp8;
+ break;
+ case M32R_OPERAND_DR :
+ value = fields->f_r1;
+ break;
+ case M32R_OPERAND_HASH :
+ value = fields->f_nil;
+ break;
+ case M32R_OPERAND_HI16 :
+ value = fields->f_hi16;
+ break;
+ case M32R_OPERAND_SCR :
+ value = fields->f_r2;
+ break;
+ case M32R_OPERAND_SIMM16 :
+ value = fields->f_simm16;
+ break;
+ case M32R_OPERAND_SIMM8 :
+ value = fields->f_simm8;
+ break;
+ case M32R_OPERAND_SLO16 :
+ value = fields->f_simm16;
+ break;
+ case M32R_OPERAND_SR :
+ value = fields->f_r2;
+ break;
+ case M32R_OPERAND_SRC1 :
+ value = fields->f_r1;
+ break;
+ case M32R_OPERAND_SRC2 :
+ value = fields->f_r2;
+ break;
+ case M32R_OPERAND_UIMM16 :
+ value = fields->f_uimm16;
+ break;
+ case M32R_OPERAND_UIMM24 :
+ value = fields->f_uimm24;
+ break;
+ case M32R_OPERAND_UIMM4 :
+ value = fields->f_uimm4;
+ break;
+ case M32R_OPERAND_UIMM5 :
+ value = fields->f_uimm5;
+ break;
+ case M32R_OPERAND_ULO16 :
+ value = fields->f_uimm16;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
+ opindex);
+ abort ();
+ }
+
+ return value;
+}
+
+/* Stuffing values in cgen_fields is handled by a collection of functions.
+ They are distinguished by the type of the VALUE argument they accept.
+ TODO: floating point, inlining support, remove cases where argument type
+ not appropriate. */
+
+void
+m32r_cgen_set_int_operand (cd, opindex, fields, value)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_FIELDS * fields;
+ int value;
+{
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ fields->f_r1 = value;
+ break;
+ case M32R_OPERAND_DISP16 :
+ fields->f_disp16 = value;
+ break;
+ case M32R_OPERAND_DISP24 :
+ fields->f_disp24 = value;
+ break;
+ case M32R_OPERAND_DISP8 :
+ fields->f_disp8 = value;
+ break;
+ case M32R_OPERAND_DR :
+ fields->f_r1 = value;
+ break;
+ case M32R_OPERAND_HASH :
+ fields->f_nil = value;
+ break;
+ case M32R_OPERAND_HI16 :
+ fields->f_hi16 = value;
+ break;
+ case M32R_OPERAND_SCR :
+ fields->f_r2 = value;
+ break;
+ case M32R_OPERAND_SIMM16 :
+ fields->f_simm16 = value;
+ break;
+ case M32R_OPERAND_SIMM8 :
+ fields->f_simm8 = value;
+ break;
+ case M32R_OPERAND_SLO16 :
+ fields->f_simm16 = value;
+ break;
+ case M32R_OPERAND_SR :
+ fields->f_r2 = value;
+ break;
+ case M32R_OPERAND_SRC1 :
+ fields->f_r1 = value;
+ break;
+ case M32R_OPERAND_SRC2 :
+ fields->f_r2 = value;
+ break;
+ case M32R_OPERAND_UIMM16 :
+ fields->f_uimm16 = value;
+ break;
+ case M32R_OPERAND_UIMM24 :
+ fields->f_uimm24 = value;
+ break;
+ case M32R_OPERAND_UIMM4 :
+ fields->f_uimm4 = value;
+ break;
+ case M32R_OPERAND_UIMM5 :
+ fields->f_uimm5 = value;
+ break;
+ case M32R_OPERAND_ULO16 :
+ fields->f_uimm16 = value;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
+ opindex);
+ abort ();
+ }
+}
+
+void
+m32r_cgen_set_vma_operand (cd, opindex, fields, value)
+ CGEN_CPU_DESC cd;
+ int opindex;
+ CGEN_FIELDS * fields;
+ bfd_vma value;
+{
+ switch (opindex)
+ {
+ case M32R_OPERAND_DCR :
+ fields->f_r1 = value;
+ break;
+ case M32R_OPERAND_DISP16 :
+ fields->f_disp16 = value;
+ break;
+ case M32R_OPERAND_DISP24 :
+ fields->f_disp24 = value;
+ break;
+ case M32R_OPERAND_DISP8 :
+ fields->f_disp8 = value;
+ break;
+ case M32R_OPERAND_DR :
+ fields->f_r1 = value;
+ break;
+ case M32R_OPERAND_HASH :
+ fields->f_nil = value;
+ break;
+ case M32R_OPERAND_HI16 :
+ fields->f_hi16 = value;
+ break;
+ case M32R_OPERAND_SCR :
+ fields->f_r2 = value;
+ break;
+ case M32R_OPERAND_SIMM16 :
+ fields->f_simm16 = value;
+ break;
+ case M32R_OPERAND_SIMM8 :
+ fields->f_simm8 = value;
+ break;
+ case M32R_OPERAND_SLO16 :
+ fields->f_simm16 = value;
+ break;
+ case M32R_OPERAND_SR :
+ fields->f_r2 = value;
+ break;
+ case M32R_OPERAND_SRC1 :
+ fields->f_r1 = value;
+ break;
+ case M32R_OPERAND_SRC2 :
+ fields->f_r2 = value;
+ break;
+ case M32R_OPERAND_UIMM16 :
+ fields->f_uimm16 = value;
+ break;
+ case M32R_OPERAND_UIMM24 :
+ fields->f_uimm24 = value;
+ break;
+ case M32R_OPERAND_UIMM4 :
+ fields->f_uimm4 = value;
+ break;
+ case M32R_OPERAND_UIMM5 :
+ fields->f_uimm5 = value;
+ break;
+ case M32R_OPERAND_ULO16 :
+ fields->f_uimm16 = value;
+ break;
+
+ default :
+ /* xgettext:c-format */
+ fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
+ opindex);
+ abort ();
+ }
+}
+
+/* Function to call before using the instruction builder tables. */
+
+void
+m32r_cgen_init_ibld_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ cd->insert_handlers = & m32r_cgen_insert_handlers[0];
+ cd->extract_handlers = & m32r_cgen_extract_handlers[0];
+
+ cd->insert_operand = m32r_cgen_insert_operand;
+ cd->extract_operand = m32r_cgen_extract_operand;
+
+ cd->get_int_operand = m32r_cgen_get_int_operand;
+ cd->set_int_operand = m32r_cgen_set_int_operand;
+ cd->get_vma_operand = m32r_cgen_get_vma_operand;
+ cd->set_vma_operand = m32r_cgen_set_vma_operand;
+}
diff --git a/opcodes/m32r-opc.c b/opcodes/m32r-opc.c
new file mode 100644
index 00000000000..43edf9ae1f7
--- /dev/null
+++ b/opcodes/m32r-opc.c
@@ -0,0 +1,1331 @@
+/* Instruction opcode table for m32r.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "sysdep.h"
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "m32r-desc.h"
+#include "m32r-opc.h"
+
+/* The hash functions are recorded here to help keep assembler code out of
+ the disassembler and vice versa. */
+
+static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
+static unsigned int asm_hash_insn PARAMS ((const char *));
+static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
+static unsigned int dis_hash_insn PARAMS ((const char *, CGEN_INSN_INT));
+
+/* Instruction formats. */
+
+#define F(f) & m32r_cgen_ifld_table[CONCAT2 (M32R_,f)]
+
+static const CGEN_IFMT ifmt_empty = {
+ 0, 0, 0x0, { 0 }
+};
+
+static const CGEN_IFMT ifmt_add = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_add3 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_and3 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_UIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_or3 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_UIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_addi = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_R1), F (F_SIMM8), 0 }
+};
+
+static const CGEN_IFMT ifmt_addv3 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_bc8 = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_R1), F (F_DISP8), 0 }
+};
+
+static const CGEN_IFMT ifmt_bc24 = {
+ 32, 32, 0xff000000, { F (F_OP1), F (F_R1), F (F_DISP24), 0 }
+};
+
+static const CGEN_IFMT ifmt_beq = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_DISP16), 0 }
+};
+
+static const CGEN_IFMT ifmt_beqz = {
+ 32, 32, 0xfff00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_DISP16), 0 }
+};
+
+static const CGEN_IFMT ifmt_cmp = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_cmpi = {
+ 32, 32, 0xfff00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_div = {
+ 32, 32, 0xf0f0ffff, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_jl = {
+ 16, 16, 0xfff0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_ld24 = {
+ 32, 32, 0xf0000000, { F (F_OP1), F (F_R1), F (F_UIMM24), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi16 = {
+ 32, 32, 0xf0ff0000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_mvfachi = {
+ 16, 16, 0xf0ff, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_mvfc = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_mvtachi = {
+ 16, 16, 0xf0ff, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_mvtc = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_nop = {
+ 16, 16, 0xffff, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_seth = {
+ 32, 32, 0xf0ff0000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_HI16), 0 }
+};
+
+static const CGEN_IFMT ifmt_slli = {
+ 16, 16, 0xf0e0, { F (F_OP1), F (F_R1), F (F_SHIFT_OP2), F (F_UIMM5), 0 }
+};
+
+static const CGEN_IFMT ifmt_st_d = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_trap = {
+ 16, 16, 0xfff0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_UIMM4), 0 }
+};
+
+#undef F
+
+#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
+#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
+#define OPERAND(op) CONCAT2 (M32R_OPERAND_,op)
+#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
+
+/* The instruction table. */
+
+static const CGEN_OPCODE m32r_cgen_insn_opcode_table[MAX_INSNS] =
+{
+ /* Special null first entry.
+ A `num' value of zero is thus invalid.
+ Also, the special `invalid' insn resides here. */
+ { { 0 } },
+/* add $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0xa0 }
+ },
+/* add3 $dr,$sr,$hash$slo16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (HASH), OP (SLO16), 0 } },
+ & ifmt_add3, { 0x80a00000 }
+ },
+/* and $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0xc0 }
+ },
+/* and3 $dr,$sr,$uimm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (UIMM16), 0 } },
+ & ifmt_and3, { 0x80c00000 }
+ },
+/* or $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0xe0 }
+ },
+/* or3 $dr,$sr,$hash$ulo16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (HASH), OP (ULO16), 0 } },
+ & ifmt_or3, { 0x80e00000 }
+ },
+/* xor $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0xd0 }
+ },
+/* xor3 $dr,$sr,$uimm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (UIMM16), 0 } },
+ & ifmt_and3, { 0x80d00000 }
+ },
+/* addi $dr,$simm8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SIMM8), 0 } },
+ & ifmt_addi, { 0x4000 }
+ },
+/* addv $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x80 }
+ },
+/* addv3 $dr,$sr,$simm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (SIMM16), 0 } },
+ & ifmt_addv3, { 0x80800000 }
+ },
+/* addx $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x90 }
+ },
+/* bc.s $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bc8, { 0x7c00 }
+ },
+/* bc.l $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bc24, { 0xfc000000 }
+ },
+/* beq $src1,$src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beq, { 0xb0000000 }
+ },
+/* beqz $src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beqz, { 0xb0800000 }
+ },
+/* bgez $src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beqz, { 0xb0b00000 }
+ },
+/* bgtz $src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beqz, { 0xb0d00000 }
+ },
+/* blez $src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beqz, { 0xb0c00000 }
+ },
+/* bltz $src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beqz, { 0xb0a00000 }
+ },
+/* bnez $src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beqz, { 0xb0900000 }
+ },
+/* bl.s $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bc8, { 0x7e00 }
+ },
+/* bl.l $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bc24, { 0xfe000000 }
+ },
+/* bnc.s $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bc8, { 0x7d00 }
+ },
+/* bnc.l $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bc24, { 0xfd000000 }
+ },
+/* bne $src1,$src2,$disp16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), ',', OP (DISP16), 0 } },
+ & ifmt_beq, { 0xb0100000 }
+ },
+/* bra.s $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bc8, { 0x7f00 }
+ },
+/* bra.l $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bc24, { 0xff000000 }
+ },
+/* cmp $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x40 }
+ },
+/* cmpi $src2,$simm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (SIMM16), 0 } },
+ & ifmt_cmpi, { 0x80400000 }
+ },
+/* cmpu $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x50 }
+ },
+/* cmpui $src2,$simm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC2), ',', OP (SIMM16), 0 } },
+ & ifmt_cmpi, { 0x80500000 }
+ },
+/* div $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_div, { 0x90000000 }
+ },
+/* divu $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_div, { 0x90100000 }
+ },
+/* rem $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_div, { 0x90200000 }
+ },
+/* remu $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_div, { 0x90300000 }
+ },
+/* jl $sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SR), 0 } },
+ & ifmt_jl, { 0x1ec0 }
+ },
+/* jmp $sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SR), 0 } },
+ & ifmt_jl, { 0x1fc0 }
+ },
+/* ld $dr,@$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), 0 } },
+ & ifmt_add, { 0x20c0 }
+ },
+/* ld $dr,@($slo16,$sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SLO16), ',', OP (SR), ')', 0 } },
+ & ifmt_add3, { 0xa0c00000 }
+ },
+/* ldb $dr,@$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), 0 } },
+ & ifmt_add, { 0x2080 }
+ },
+/* ldb $dr,@($slo16,$sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SLO16), ',', OP (SR), ')', 0 } },
+ & ifmt_add3, { 0xa0800000 }
+ },
+/* ldh $dr,@$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), 0 } },
+ & ifmt_add, { 0x20a0 }
+ },
+/* ldh $dr,@($slo16,$sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SLO16), ',', OP (SR), ')', 0 } },
+ & ifmt_add3, { 0xa0a00000 }
+ },
+/* ldub $dr,@$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), 0 } },
+ & ifmt_add, { 0x2090 }
+ },
+/* ldub $dr,@($slo16,$sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SLO16), ',', OP (SR), ')', 0 } },
+ & ifmt_add3, { 0xa0900000 }
+ },
+/* lduh $dr,@$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), 0 } },
+ & ifmt_add, { 0x20b0 }
+ },
+/* lduh $dr,@($slo16,$sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SLO16), ',', OP (SR), ')', 0 } },
+ & ifmt_add3, { 0xa0b00000 }
+ },
+/* ld $dr,@$sr+ */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), '+', 0 } },
+ & ifmt_add, { 0x20e0 }
+ },
+/* ld24 $dr,$uimm24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (UIMM24), 0 } },
+ & ifmt_ld24, { 0xe0000000 }
+ },
+/* ldi8 $dr,$simm8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SIMM8), 0 } },
+ & ifmt_addi, { 0x6000 }
+ },
+/* ldi16 $dr,$hash$slo16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (HASH), OP (SLO16), 0 } },
+ & ifmt_ldi16, { 0x90f00000 }
+ },
+/* lock $dr,@$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', OP (SR), 0 } },
+ & ifmt_add, { 0x20d0 }
+ },
+/* machi $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3040 }
+ },
+/* maclo $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3050 }
+ },
+/* macwhi $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3060 }
+ },
+/* macwlo $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3070 }
+ },
+/* mul $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x1060 }
+ },
+/* mulhi $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3000 }
+ },
+/* mullo $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3010 }
+ },
+/* mulwhi $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3020 }
+ },
+/* mulwlo $src1,$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x3030 }
+ },
+/* mv $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x1080 }
+ },
+/* mvfachi $dr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), 0 } },
+ & ifmt_mvfachi, { 0x50f0 }
+ },
+/* mvfaclo $dr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), 0 } },
+ & ifmt_mvfachi, { 0x50f1 }
+ },
+/* mvfacmi $dr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), 0 } },
+ & ifmt_mvfachi, { 0x50f2 }
+ },
+/* mvfc $dr,$scr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SCR), 0 } },
+ & ifmt_mvfc, { 0x1090 }
+ },
+/* mvtachi $src1 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), 0 } },
+ & ifmt_mvtachi, { 0x5070 }
+ },
+/* mvtaclo $src1 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), 0 } },
+ & ifmt_mvtachi, { 0x5071 }
+ },
+/* mvtc $sr,$dcr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SR), ',', OP (DCR), 0 } },
+ & ifmt_mvtc, { 0x10a0 }
+ },
+/* neg $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x30 }
+ },
+/* nop */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_nop, { 0x7000 }
+ },
+/* not $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0xb0 }
+ },
+/* rac */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_nop, { 0x5090 }
+ },
+/* rach */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_nop, { 0x5080 }
+ },
+/* rte */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, 0 } },
+ & ifmt_nop, { 0x10d6 }
+ },
+/* seth $dr,$hash$hi16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (HASH), OP (HI16), 0 } },
+ & ifmt_seth, { 0xd0c00000 }
+ },
+/* sll $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x1040 }
+ },
+/* sll3 $dr,$sr,$simm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (SIMM16), 0 } },
+ & ifmt_addv3, { 0x90c00000 }
+ },
+/* slli $dr,$uimm5 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (UIMM5), 0 } },
+ & ifmt_slli, { 0x5040 }
+ },
+/* sra $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x1020 }
+ },
+/* sra3 $dr,$sr,$simm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (SIMM16), 0 } },
+ & ifmt_addv3, { 0x90a00000 }
+ },
+/* srai $dr,$uimm5 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (UIMM5), 0 } },
+ & ifmt_slli, { 0x5020 }
+ },
+/* srl $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x1000 }
+ },
+/* srl3 $dr,$sr,$simm16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), ',', OP (SIMM16), 0 } },
+ & ifmt_addv3, { 0x90800000 }
+ },
+/* srli $dr,$uimm5 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (UIMM5), 0 } },
+ & ifmt_slli, { 0x5000 }
+ },
+/* st $src1,@$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x2040 }
+ },
+/* st $src1,@($slo16,$src2) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SLO16), ',', OP (SRC2), ')', 0 } },
+ & ifmt_st_d, { 0xa0400000 }
+ },
+/* stb $src1,@$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x2000 }
+ },
+/* stb $src1,@($slo16,$src2) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SLO16), ',', OP (SRC2), ')', 0 } },
+ & ifmt_st_d, { 0xa0000000 }
+ },
+/* sth $src1,@$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x2020 }
+ },
+/* sth $src1,@($slo16,$src2) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SLO16), ',', OP (SRC2), ')', 0 } },
+ & ifmt_st_d, { 0xa0200000 }
+ },
+/* st $src1,@+$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '+', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x2060 }
+ },
+/* st $src1,@-$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '-', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x2070 }
+ },
+/* sub $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x20 }
+ },
+/* subv $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x0 }
+ },
+/* subx $dr,$sr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SR), 0 } },
+ & ifmt_add, { 0x10 }
+ },
+/* trap $uimm4 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (UIMM4), 0 } },
+ & ifmt_trap, { 0x10f0 }
+ },
+/* unlock $src1,@$src2 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', OP (SRC2), 0 } },
+ & ifmt_cmp, { 0x2050 }
+ },
+};
+
+#undef A
+#undef MNEM
+#undef OPERAND
+#undef OP
+
+/* Formats for ALIAS macro-insns. */
+
+#define F(f) & m32r_cgen_ifld_table[CONCAT2 (M32R_,f)]
+
+static const CGEN_IFMT ifmt_bc8r = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_R1), F (F_DISP8), 0 }
+};
+
+static const CGEN_IFMT ifmt_bc24r = {
+ 32, 32, 0xff000000, { F (F_OP1), F (F_R1), F (F_DISP24), 0 }
+};
+
+static const CGEN_IFMT ifmt_bl8r = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_R1), F (F_DISP8), 0 }
+};
+
+static const CGEN_IFMT ifmt_bl24r = {
+ 32, 32, 0xff000000, { F (F_OP1), F (F_R1), F (F_DISP24), 0 }
+};
+
+static const CGEN_IFMT ifmt_bnc8r = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_R1), F (F_DISP8), 0 }
+};
+
+static const CGEN_IFMT ifmt_bnc24r = {
+ 32, 32, 0xff000000, { F (F_OP1), F (F_R1), F (F_DISP24), 0 }
+};
+
+static const CGEN_IFMT ifmt_bra8r = {
+ 16, 16, 0xff00, { F (F_OP1), F (F_R1), F (F_DISP8), 0 }
+};
+
+static const CGEN_IFMT ifmt_bra24r = {
+ 32, 32, 0xff000000, { F (F_OP1), F (F_R1), F (F_DISP24), 0 }
+};
+
+static const CGEN_IFMT ifmt_ld_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_ld_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldb_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldb_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldh_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldh_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldub_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldub_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_lduh_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_lduh_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_pop = {
+ 16, 16, 0xf0ff, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi8a = {
+ 16, 16, 0xf000, { F (F_OP1), F (F_R1), F (F_SIMM8), 0 }
+};
+
+static const CGEN_IFMT ifmt_ldi16a = {
+ 32, 32, 0xf0ff0000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_st_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_st_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_stb_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_stb_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_sth_2 = {
+ 16, 16, 0xf0f0, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+static const CGEN_IFMT ifmt_sth_d2 = {
+ 32, 32, 0xf0f00000, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), F (F_SIMM16), 0 }
+};
+
+static const CGEN_IFMT ifmt_push = {
+ 16, 16, 0xf0ff, { F (F_OP1), F (F_R1), F (F_OP2), F (F_R2), 0 }
+};
+
+#undef F
+
+/* Each non-simple macro entry points to an array of expansion possibilities. */
+
+#define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
+#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
+#define OPERAND(op) CONCAT2 (M32R_OPERAND_,op)
+#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
+
+/* The macro instruction table. */
+
+static const CGEN_IBASE m32r_cgen_macro_insn_table[] =
+{
+/* bc $disp8 */
+ {
+ -1, "bc8r", "bc", 16,
+ { 0|A(RELAXABLE)|A(COND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bc $disp24 */
+ {
+ -1, "bc24r", "bc", 32,
+ { 0|A(RELAX)|A(COND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bl $disp8 */
+ {
+ -1, "bl8r", "bl", 16,
+ { 0|A(RELAXABLE)|A(FILL_SLOT)|A(UNCOND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bl $disp24 */
+ {
+ -1, "bl24r", "bl", 32,
+ { 0|A(RELAX)|A(UNCOND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bnc $disp8 */
+ {
+ -1, "bnc8r", "bnc", 16,
+ { 0|A(RELAXABLE)|A(COND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bnc $disp24 */
+ {
+ -1, "bnc24r", "bnc", 32,
+ { 0|A(RELAX)|A(COND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bra $disp8 */
+ {
+ -1, "bra8r", "bra", 16,
+ { 0|A(RELAXABLE)|A(FILL_SLOT)|A(UNCOND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* bra $disp24 */
+ {
+ -1, "bra24r", "bra", 32,
+ { 0|A(RELAX)|A(UNCOND_CTI)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ld $dr,@($sr) */
+ {
+ -1, "ld-2", "ld", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ld $dr,@($sr,$slo16) */
+ {
+ -1, "ld-d2", "ld", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldb $dr,@($sr) */
+ {
+ -1, "ldb-2", "ldb", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldb $dr,@($sr,$slo16) */
+ {
+ -1, "ldb-d2", "ldb", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldh $dr,@($sr) */
+ {
+ -1, "ldh-2", "ldh", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldh $dr,@($sr,$slo16) */
+ {
+ -1, "ldh-d2", "ldh", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldub $dr,@($sr) */
+ {
+ -1, "ldub-2", "ldub", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldub $dr,@($sr,$slo16) */
+ {
+ -1, "ldub-d2", "ldub", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* lduh $dr,@($sr) */
+ {
+ -1, "lduh-2", "lduh", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* lduh $dr,@($sr,$slo16) */
+ {
+ -1, "lduh-d2", "lduh", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* pop $dr */
+ {
+ -1, "pop", "pop", 16,
+ { 0|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldi $dr,$simm8 */
+ {
+ -1, "ldi8a", "ldi", 16,
+ { 0|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* ldi $dr,$hash$slo16 */
+ {
+ -1, "ldi16a", "ldi", 32,
+ { 0|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* st $src1,@($src2) */
+ {
+ -1, "st-2", "st", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* st $src1,@($src2,$slo16) */
+ {
+ -1, "st-d2", "st", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* stb $src1,@($src2) */
+ {
+ -1, "stb-2", "stb", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* stb $src1,@($src2,$slo16) */
+ {
+ -1, "stb-d2", "stb", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* sth $src1,@($src2) */
+ {
+ -1, "sth-2", "sth", 16,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* sth $src1,@($src2,$slo16) */
+ {
+ -1, "sth-d2", "sth", 32,
+ { 0|A(NO_DIS)|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+/* push $src1 */
+ {
+ -1, "push", "push", 16,
+ { 0|A(ALIAS), { (1<<MACH_BASE) } }
+ },
+};
+
+/* The macro instruction opcode table. */
+
+static const CGEN_OPCODE m32r_cgen_macro_insn_opcode_table[] =
+{
+/* bc $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bc8r, { 0x7c00 }
+ },
+/* bc $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bc24r, { 0xfc000000 }
+ },
+/* bl $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bl8r, { 0x7e00 }
+ },
+/* bl $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bl24r, { 0xfe000000 }
+ },
+/* bnc $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bnc8r, { 0x7d00 }
+ },
+/* bnc $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bnc24r, { 0xfd000000 }
+ },
+/* bra $disp8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP8), 0 } },
+ & ifmt_bra8r, { 0x7f00 }
+ },
+/* bra $disp24 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DISP24), 0 } },
+ & ifmt_bra24r, { 0xff000000 }
+ },
+/* ld $dr,@($sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ')', 0 } },
+ & ifmt_ld_2, { 0x20c0 }
+ },
+/* ld $dr,@($sr,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ',', OP (SLO16), ')', 0 } },
+ & ifmt_ld_d2, { 0xa0c00000 }
+ },
+/* ldb $dr,@($sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ')', 0 } },
+ & ifmt_ldb_2, { 0x2080 }
+ },
+/* ldb $dr,@($sr,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ',', OP (SLO16), ')', 0 } },
+ & ifmt_ldb_d2, { 0xa0800000 }
+ },
+/* ldh $dr,@($sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ')', 0 } },
+ & ifmt_ldh_2, { 0x20a0 }
+ },
+/* ldh $dr,@($sr,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ',', OP (SLO16), ')', 0 } },
+ & ifmt_ldh_d2, { 0xa0a00000 }
+ },
+/* ldub $dr,@($sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ')', 0 } },
+ & ifmt_ldub_2, { 0x2090 }
+ },
+/* ldub $dr,@($sr,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ',', OP (SLO16), ')', 0 } },
+ & ifmt_ldub_d2, { 0xa0900000 }
+ },
+/* lduh $dr,@($sr) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ')', 0 } },
+ & ifmt_lduh_2, { 0x20b0 }
+ },
+/* lduh $dr,@($sr,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', '@', '(', OP (SR), ',', OP (SLO16), ')', 0 } },
+ & ifmt_lduh_d2, { 0xa0b00000 }
+ },
+/* pop $dr */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), 0 } },
+ & ifmt_pop, { 0x20ef }
+ },
+/* ldi $dr,$simm8 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (SIMM8), 0 } },
+ & ifmt_ldi8a, { 0x6000 }
+ },
+/* ldi $dr,$hash$slo16 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (DR), ',', OP (HASH), OP (SLO16), 0 } },
+ & ifmt_ldi16a, { 0x90f00000 }
+ },
+/* st $src1,@($src2) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SRC2), ')', 0 } },
+ & ifmt_st_2, { 0x2040 }
+ },
+/* st $src1,@($src2,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SRC2), ',', OP (SLO16), ')', 0 } },
+ & ifmt_st_d2, { 0xa0400000 }
+ },
+/* stb $src1,@($src2) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SRC2), ')', 0 } },
+ & ifmt_stb_2, { 0x2000 }
+ },
+/* stb $src1,@($src2,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SRC2), ',', OP (SLO16), ')', 0 } },
+ & ifmt_stb_d2, { 0xa0000000 }
+ },
+/* sth $src1,@($src2) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SRC2), ')', 0 } },
+ & ifmt_sth_2, { 0x2020 }
+ },
+/* sth $src1,@($src2,$slo16) */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), ',', '@', '(', OP (SRC2), ',', OP (SLO16), ')', 0 } },
+ & ifmt_sth_d2, { 0xa0200000 }
+ },
+/* push $src1 */
+ {
+ { 0, 0, 0, 0 },
+ { { MNEM, ' ', OP (SRC1), 0 } },
+ & ifmt_push, { 0x207f }
+ },
+};
+
+#undef A
+#undef MNEM
+#undef OPERAND
+#undef OP
+
+#ifndef CGEN_ASM_HASH_P
+#define CGEN_ASM_HASH_P(insn) 1
+#endif
+
+#ifndef CGEN_DIS_HASH_P
+#define CGEN_DIS_HASH_P(insn) 1
+#endif
+
+/* Return non-zero if INSN is to be added to the hash table.
+ Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */
+
+static int
+asm_hash_insn_p (insn)
+ const CGEN_INSN *insn;
+{
+ return CGEN_ASM_HASH_P (insn);
+}
+
+static int
+dis_hash_insn_p (insn)
+ const CGEN_INSN *insn;
+{
+ /* If building the hash table and the NO-DIS attribute is present,
+ ignore. */
+ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS))
+ return 0;
+ return CGEN_DIS_HASH_P (insn);
+}
+
+#ifndef CGEN_ASM_HASH
+#define CGEN_ASM_HASH_SIZE 127
+#ifdef CGEN_MNEMONIC_OPERANDS
+#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE)
+#else
+#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/
+#endif
+#endif
+
+/* It doesn't make much sense to provide a default here,
+ but while this is under development we do.
+ BUFFER is a pointer to the bytes of the insn, target order.
+ VALUE is the first base_insn_bitsize bits as an int in host order. */
+
+#ifndef CGEN_DIS_HASH
+#define CGEN_DIS_HASH_SIZE 256
+#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf))
+#endif
+
+/* The result is the hash value of the insn.
+ Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */
+
+static unsigned int
+asm_hash_insn (mnem)
+ const char * mnem;
+{
+ return CGEN_ASM_HASH (mnem);
+}
+
+/* BUF is a pointer to the bytes of the insn, target order.
+ VALUE is the first base_insn_bitsize bits as an int in host order. */
+
+static unsigned int
+dis_hash_insn (buf, value)
+ const char * buf;
+ CGEN_INSN_INT value;
+{
+ return CGEN_DIS_HASH (buf, value);
+}
+
+/* Set the recorded length of the insn in the CGEN_FIELDS struct. */
+
+static void
+set_fields_bitsize (fields, size)
+ CGEN_FIELDS *fields;
+ int size;
+{
+ CGEN_FIELDS_BITSIZE (fields) = size;
+}
+
+/* Function to call before using the operand instance table.
+ This plugs the opcode entries and macro instructions into the cpu table. */
+
+void
+m32r_cgen_init_opcode_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ int i;
+ int num_macros = (sizeof (m32r_cgen_macro_insn_table) /
+ sizeof (m32r_cgen_macro_insn_table[0]));
+ const CGEN_IBASE *ib = & m32r_cgen_macro_insn_table[0];
+ const CGEN_OPCODE *oc = & m32r_cgen_macro_insn_opcode_table[0];
+ CGEN_INSN *insns = (CGEN_INSN *) xmalloc (num_macros * sizeof (CGEN_INSN));
+ memset (insns, 0, num_macros * sizeof (CGEN_INSN));
+ for (i = 0; i < num_macros; ++i)
+ {
+ insns[i].base = &ib[i];
+ insns[i].opcode = &oc[i];
+ }
+ cd->macro_insn_table.init_entries = insns;
+ cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE);
+ cd->macro_insn_table.num_init_entries = num_macros;
+
+ oc = & m32r_cgen_insn_opcode_table[0];
+ insns = (CGEN_INSN *) cd->insn_table.init_entries;
+ for (i = 0; i < MAX_INSNS; ++i)
+ insns[i].opcode = &oc[i];
+
+ cd->sizeof_fields = sizeof (CGEN_FIELDS);
+ cd->set_fields_bitsize = set_fields_bitsize;
+
+ cd->asm_hash_p = asm_hash_insn_p;
+ cd->asm_hash = asm_hash_insn;
+ cd->asm_hash_size = CGEN_ASM_HASH_SIZE;
+
+ cd->dis_hash_p = dis_hash_insn_p;
+ cd->dis_hash = dis_hash_insn;
+ cd->dis_hash_size = CGEN_DIS_HASH_SIZE;
+}
diff --git a/opcodes/m32r-opc.h b/opcodes/m32r-opc.h
new file mode 100644
index 00000000000..6c57daa8f9c
--- /dev/null
+++ b/opcodes/m32r-opc.h
@@ -0,0 +1,126 @@
+/* Instruction opcode header for m32r.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef M32R_OPC_H
+#define M32R_OPC_H
+
+/* -- opc.h */
+
+#undef CGEN_DIS_HASH_SIZE
+#define CGEN_DIS_HASH_SIZE 256
+#undef CGEN_DIS_HASH
+#define X(b) (((unsigned char *) (b))[0] & 0xf0)
+#define CGEN_DIS_HASH(buffer, value) \
+(X (buffer) | \
+ (X (buffer) == 0x40 || X (buffer) == 0xe0 || X (buffer) == 0x60 || X (buffer) == 0x50 ? 0 \
+ : X (buffer) == 0x70 || X (buffer) == 0xf0 ? (((unsigned char *) (buffer))[0] & 0xf) \
+ : X (buffer) == 0x30 ? ((((unsigned char *) (buffer))[1] & 0x70) >> 4) \
+ : ((((unsigned char *) (buffer))[1] & 0xf0) >> 4)))
+
+/* -- */
+/* Enum declaration for m32r instruction types. */
+typedef enum cgen_insn_type {
+ M32R_INSN_INVALID, M32R_INSN_ADD, M32R_INSN_ADD3, M32R_INSN_AND
+ , M32R_INSN_AND3, M32R_INSN_OR, M32R_INSN_OR3, M32R_INSN_XOR
+ , M32R_INSN_XOR3, M32R_INSN_ADDI, M32R_INSN_ADDV, M32R_INSN_ADDV3
+ , M32R_INSN_ADDX, M32R_INSN_BC8, M32R_INSN_BC24, M32R_INSN_BEQ
+ , M32R_INSN_BEQZ, M32R_INSN_BGEZ, M32R_INSN_BGTZ, M32R_INSN_BLEZ
+ , M32R_INSN_BLTZ, M32R_INSN_BNEZ, M32R_INSN_BL8, M32R_INSN_BL24
+ , M32R_INSN_BNC8, M32R_INSN_BNC24, M32R_INSN_BNE, M32R_INSN_BRA8
+ , M32R_INSN_BRA24
+ , M32R_INSN_CMP, M32R_INSN_CMPI, M32R_INSN_CMPU, M32R_INSN_CMPUI
+ , M32R_INSN_DIV, M32R_INSN_DIVU, M32R_INSN_REM, M32R_INSN_REMU
+ , M32R_INSN_JL, M32R_INSN_JMP, M32R_INSN_LD, M32R_INSN_LD_D
+ , M32R_INSN_LDB, M32R_INSN_LDB_D, M32R_INSN_LDH, M32R_INSN_LDH_D
+ , M32R_INSN_LDUB, M32R_INSN_LDUB_D, M32R_INSN_LDUH, M32R_INSN_LDUH_D
+ , M32R_INSN_LD_PLUS, M32R_INSN_LD24, M32R_INSN_LDI8, M32R_INSN_LDI16
+ , M32R_INSN_LOCK, M32R_INSN_MACHI
+ , M32R_INSN_MACLO
+ , M32R_INSN_MACWHI
+ , M32R_INSN_MACWLO
+ , M32R_INSN_MUL, M32R_INSN_MULHI
+ , M32R_INSN_MULLO
+ , M32R_INSN_MULWHI
+ , M32R_INSN_MULWLO
+ , M32R_INSN_MV, M32R_INSN_MVFACHI
+ , M32R_INSN_MVFACLO
+ , M32R_INSN_MVFACMI
+ , M32R_INSN_MVFC, M32R_INSN_MVTACHI
+ , M32R_INSN_MVTACLO
+ , M32R_INSN_MVTC, M32R_INSN_NEG, M32R_INSN_NOP, M32R_INSN_NOT
+ , M32R_INSN_RAC
+ , M32R_INSN_RACH
+ , M32R_INSN_RTE, M32R_INSN_SETH, M32R_INSN_SLL, M32R_INSN_SLL3
+ , M32R_INSN_SLLI, M32R_INSN_SRA, M32R_INSN_SRA3, M32R_INSN_SRAI
+ , M32R_INSN_SRL, M32R_INSN_SRL3, M32R_INSN_SRLI, M32R_INSN_ST
+ , M32R_INSN_ST_D, M32R_INSN_STB, M32R_INSN_STB_D, M32R_INSN_STH
+ , M32R_INSN_STH_D, M32R_INSN_ST_PLUS, M32R_INSN_ST_MINUS, M32R_INSN_SUB
+ , M32R_INSN_SUBV, M32R_INSN_SUBX, M32R_INSN_TRAP, M32R_INSN_UNLOCK
+ , M32R_INSN_MAX
+} CGEN_INSN_TYPE;
+
+/* Index of `invalid' insn place holder. */
+#define CGEN_INSN_INVALID M32R_INSN_INVALID
+
+/* Total number of insns in table. */
+#define MAX_INSNS ((int) M32R_INSN_MAX)
+
+/* This struct records data prior to insertion or after extraction. */
+struct cgen_fields
+{
+ int length;
+ long f_nil;
+ long f_op1;
+ long f_op2;
+ long f_cond;
+ long f_r1;
+ long f_r2;
+ long f_simm8;
+ long f_simm16;
+ long f_shift_op2;
+ long f_uimm4;
+ long f_uimm5;
+ long f_uimm16;
+ long f_uimm24;
+ long f_hi16;
+ long f_disp8;
+ long f_disp16;
+ long f_disp24;
+};
+
+#define CGEN_INIT_PARSE(od) \
+{\
+}
+#define CGEN_INIT_INSERT(od) \
+{\
+}
+#define CGEN_INIT_EXTRACT(od) \
+{\
+}
+#define CGEN_INIT_PRINT(od) \
+{\
+}
+
+
+#endif /* M32R_OPC_H */
diff --git a/opcodes/m32r-opinst.c b/opcodes/m32r-opinst.c
new file mode 100644
index 00000000000..7f3a49f8b97
--- /dev/null
+++ b/opcodes/m32r-opinst.c
@@ -0,0 +1,562 @@
+/* Semantic operand instances for m32r.
+
+THIS FILE IS MACHINE GENERATED WITH CGEN.
+
+Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of the GNU Binutils and/or GDB, the GNU debugger.
+
+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, 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.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "sysdep.h"
+#include "ansidecl.h"
+#include "bfd.h"
+#include "symcat.h"
+#include "m32r-desc.h"
+#include "m32r-opc.h"
+
+/* Operand references. */
+
+#define INPUT CGEN_OPINST_INPUT
+#define OUTPUT CGEN_OPINST_OUTPUT
+#define END CGEN_OPINST_END
+#define COND_REF CGEN_OPINST_COND_REF
+#define OP_ENT(op) CONCAT2 (M32R_OPERAND_,op)
+
+static const CGEN_OPINST fmt_empty_ops[] = {
+ { END }
+};
+
+static const CGEN_OPINST fmt_add_ops[] = {
+ { INPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_add3_ops[] = {
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_and3_ops[] = {
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { INPUT, "uimm16", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (UIMM16), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_or3_ops[] = {
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { INPUT, "ulo16", HW_H_ULO16, CGEN_MODE_UINT, OP_ENT (ULO16), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_addi_ops[] = {
+ { INPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { INPUT, "simm8", HW_H_SINT, CGEN_MODE_INT, OP_ENT (SIMM8), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_addv_ops[] = {
+ { INPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_addv3_ops[] = {
+ { INPUT, "simm16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_addx_ops[] = {
+ { INPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { INPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_bc8_ops[] = {
+ { INPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { INPUT, "disp8", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP8), 0, COND_REF },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
+ { END }
+};
+
+static const CGEN_OPINST fmt_bc24_ops[] = {
+ { INPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { INPUT, "disp24", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP24), 0, COND_REF },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
+ { END }
+};
+
+static const CGEN_OPINST fmt_beq_ops[] = {
+ { INPUT, "disp16", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP16), 0, COND_REF },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
+ { END }
+};
+
+static const CGEN_OPINST fmt_beqz_ops[] = {
+ { INPUT, "disp16", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP16), 0, COND_REF },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, COND_REF },
+ { END }
+};
+
+static const CGEN_OPINST fmt_bl8_ops[] = {
+ { INPUT, "disp8", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP8), 0, 0 },
+ { INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_bl24_ops[] = {
+ { INPUT, "disp24", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP24), 0, 0 },
+ { INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_bra8_ops[] = {
+ { INPUT, "disp8", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP8), 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_bra24_ops[] = {
+ { INPUT, "disp24", HW_H_IADDR, CGEN_MODE_USI, OP_ENT (DISP24), 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_cmp_ops[] = {
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_cmpi_ops[] = {
+ { INPUT, "simm16", HW_H_SINT, CGEN_MODE_INT, OP_ENT (SIMM16), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "condbit", HW_H_COND, CGEN_MODE_BI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_div_ops[] = {
+ { INPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, COND_REF },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, COND_REF },
+ { END }
+};
+
+static const CGEN_OPINST fmt_jl_ops[] = {
+ { INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "h_gr_14", HW_H_GR, CGEN_MODE_SI, 0, 14, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_jmp_ops[] = {
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ld_ops[] = {
+ { INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ld_d_ops[] = {
+ { INPUT, "h_memory_add__VM_sr_slo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ldb_ops[] = {
+ { INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ldb_d_ops[] = {
+ { INPUT, "h_memory_add__VM_sr_slo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ldh_ops[] = {
+ { INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ldh_d_ops[] = {
+ { INPUT, "h_memory_add__VM_sr_slo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ld_plus_ops[] = {
+ { INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { OUTPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ld24_ops[] = {
+ { INPUT, "uimm24", HW_H_ADDR, CGEN_MODE_USI, OP_ENT (UIMM24), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ldi8_ops[] = {
+ { INPUT, "simm8", HW_H_SINT, CGEN_MODE_INT, OP_ENT (SIMM8), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_ldi16_ops[] = {
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_lock_ops[] = {
+ { INPUT, "h_memory_sr", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_USI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { OUTPUT, "h_lock", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_machi_ops[] = {
+ { INPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_mulhi_ops[] = {
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_mv_ops[] = {
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_mvfachi_ops[] = {
+ { INPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_mvfc_ops[] = {
+ { INPUT, "scr", HW_H_CR, CGEN_MODE_USI, OP_ENT (SCR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_mvtachi_ops[] = {
+ { INPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { OUTPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_mvtc_ops[] = {
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dcr", HW_H_CR, CGEN_MODE_USI, OP_ENT (DCR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_nop_ops[] = {
+ { END }
+};
+
+static const CGEN_OPINST fmt_rac_ops[] = {
+ { INPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { OUTPUT, "accum", HW_H_ACCUM, CGEN_MODE_DI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_rte_ops[] = {
+ { INPUT, "h_bbpsw", HW_H_BBPSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { INPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { INPUT, "h_cr_14", HW_H_CR, CGEN_MODE_USI, 0, 14, 0 },
+ { INPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
+ { OUTPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { OUTPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
+ { OUTPUT, "h_psw", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_seth_ops[] = {
+ { INPUT, "hi16", HW_H_HI16, CGEN_MODE_SI, OP_ENT (HI16), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_sll3_ops[] = {
+ { INPUT, "simm16", HW_H_SINT, CGEN_MODE_SI, OP_ENT (SIMM16), 0, 0 },
+ { INPUT, "sr", HW_H_GR, CGEN_MODE_SI, OP_ENT (SR), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_slli_ops[] = {
+ { INPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { INPUT, "uimm5", HW_H_UINT, CGEN_MODE_INT, OP_ENT (UIMM5), 0, 0 },
+ { OUTPUT, "dr", HW_H_GR, CGEN_MODE_SI, OP_ENT (DR), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_st_ops[] = {
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_st_d_ops[] = {
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_add__VM_src2_slo16", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_stb_ops[] = {
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_QI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_stb_d_ops[] = {
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_QI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_add__VM_src2_slo16", HW_H_MEMORY, CGEN_MODE_QI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_sth_ops[] = {
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_HI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_sth_d_ops[] = {
+ { INPUT, "slo16", HW_H_SLO16, CGEN_MODE_INT, OP_ENT (SLO16), 0, 0 },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_HI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_add__VM_src2_slo16", HW_H_MEMORY, CGEN_MODE_HI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_st_plus_ops[] = {
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, 0 },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { OUTPUT, "h_memory_new_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, 0 },
+ { OUTPUT, "src2", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC2), 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_trap_ops[] = {
+ { INPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { INPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
+ { INPUT, "h_psw", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { INPUT, "pc", HW_H_PC, CGEN_MODE_USI, 0, 0, 0 },
+ { INPUT, "uimm4", HW_H_UINT, CGEN_MODE_UINT, OP_ENT (UIMM4), 0, 0 },
+ { OUTPUT, "h_bbpsw", HW_H_BBPSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { OUTPUT, "h_bpsw", HW_H_BPSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { OUTPUT, "h_cr_14", HW_H_CR, CGEN_MODE_USI, 0, 14, 0 },
+ { OUTPUT, "h_cr_6", HW_H_CR, CGEN_MODE_USI, 0, 6, 0 },
+ { OUTPUT, "h_psw", HW_H_PSW, CGEN_MODE_UQI, 0, 0, 0 },
+ { OUTPUT, "pc", HW_H_PC, CGEN_MODE_SI, 0, 0, 0 },
+ { END }
+};
+
+static const CGEN_OPINST fmt_unlock_ops[] = {
+ { INPUT, "h_lock", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
+ { INPUT, "src1", HW_H_GR, CGEN_MODE_SI, OP_ENT (SRC1), 0, COND_REF },
+ { INPUT, "src2", HW_H_GR, CGEN_MODE_USI, OP_ENT (SRC2), 0, COND_REF },
+ { OUTPUT, "h_lock", HW_H_LOCK, CGEN_MODE_BI, 0, 0, 0 },
+ { OUTPUT, "h_memory_src2", HW_H_MEMORY, CGEN_MODE_SI, 0, 0, COND_REF },
+ { END }
+};
+
+#undef INPUT
+#undef OUTPUT
+#undef END
+#undef COND_REF
+#undef OP_ENT
+
+/* Operand instance lookup table. */
+
+static const CGEN_OPINST *m32r_cgen_opinst_table[MAX_INSNS] = {
+ 0,
+ & fmt_add_ops[0],
+ & fmt_add3_ops[0],
+ & fmt_add_ops[0],
+ & fmt_and3_ops[0],
+ & fmt_add_ops[0],
+ & fmt_or3_ops[0],
+ & fmt_add_ops[0],
+ & fmt_and3_ops[0],
+ & fmt_addi_ops[0],
+ & fmt_addv_ops[0],
+ & fmt_addv3_ops[0],
+ & fmt_addx_ops[0],
+ & fmt_bc8_ops[0],
+ & fmt_bc24_ops[0],
+ & fmt_beq_ops[0],
+ & fmt_beqz_ops[0],
+ & fmt_beqz_ops[0],
+ & fmt_beqz_ops[0],
+ & fmt_beqz_ops[0],
+ & fmt_beqz_ops[0],
+ & fmt_beqz_ops[0],
+ & fmt_bl8_ops[0],
+ & fmt_bl24_ops[0],
+ & fmt_bc8_ops[0],
+ & fmt_bc24_ops[0],
+ & fmt_beq_ops[0],
+ & fmt_bra8_ops[0],
+ & fmt_bra24_ops[0],
+ & fmt_cmp_ops[0],
+ & fmt_cmpi_ops[0],
+ & fmt_cmp_ops[0],
+ & fmt_cmpi_ops[0],
+ & fmt_div_ops[0],
+ & fmt_div_ops[0],
+ & fmt_div_ops[0],
+ & fmt_div_ops[0],
+ & fmt_jl_ops[0],
+ & fmt_jmp_ops[0],
+ & fmt_ld_ops[0],
+ & fmt_ld_d_ops[0],
+ & fmt_ldb_ops[0],
+ & fmt_ldb_d_ops[0],
+ & fmt_ldh_ops[0],
+ & fmt_ldh_d_ops[0],
+ & fmt_ldb_ops[0],
+ & fmt_ldb_d_ops[0],
+ & fmt_ldh_ops[0],
+ & fmt_ldh_d_ops[0],
+ & fmt_ld_plus_ops[0],
+ & fmt_ld24_ops[0],
+ & fmt_ldi8_ops[0],
+ & fmt_ldi16_ops[0],
+ & fmt_lock_ops[0],
+ & fmt_machi_ops[0],
+ & fmt_machi_ops[0],
+ & fmt_machi_ops[0],
+ & fmt_machi_ops[0],
+ & fmt_add_ops[0],
+ & fmt_mulhi_ops[0],
+ & fmt_mulhi_ops[0],
+ & fmt_mulhi_ops[0],
+ & fmt_mulhi_ops[0],
+ & fmt_mv_ops[0],
+ & fmt_mvfachi_ops[0],
+ & fmt_mvfachi_ops[0],
+ & fmt_mvfachi_ops[0],
+ & fmt_mvfc_ops[0],
+ & fmt_mvtachi_ops[0],
+ & fmt_mvtachi_ops[0],
+ & fmt_mvtc_ops[0],
+ & fmt_mv_ops[0],
+ & fmt_nop_ops[0],
+ & fmt_mv_ops[0],
+ & fmt_rac_ops[0],
+ & fmt_rac_ops[0],
+ & fmt_rte_ops[0],
+ & fmt_seth_ops[0],
+ & fmt_add_ops[0],
+ & fmt_sll3_ops[0],
+ & fmt_slli_ops[0],
+ & fmt_add_ops[0],
+ & fmt_sll3_ops[0],
+ & fmt_slli_ops[0],
+ & fmt_add_ops[0],
+ & fmt_sll3_ops[0],
+ & fmt_slli_ops[0],
+ & fmt_st_ops[0],
+ & fmt_st_d_ops[0],
+ & fmt_stb_ops[0],
+ & fmt_stb_d_ops[0],
+ & fmt_sth_ops[0],
+ & fmt_sth_d_ops[0],
+ & fmt_st_plus_ops[0],
+ & fmt_st_plus_ops[0],
+ & fmt_add_ops[0],
+ & fmt_addv_ops[0],
+ & fmt_addx_ops[0],
+ & fmt_trap_ops[0],
+ & fmt_unlock_ops[0],
+};
+
+/* Function to call before using the operand instance table. */
+
+void
+m32r_cgen_init_opinst_table (cd)
+ CGEN_CPU_DESC cd;
+{
+ int i;
+ const CGEN_OPINST **oi = & m32r_cgen_opinst_table[0];
+ CGEN_INSN *insns = (CGEN_INSN *) cd->insn_table.init_entries;
+ for (i = 0; i < MAX_INSNS; ++i)
+ insns[i].opinst = oi[i];
+}
diff --git a/opcodes/m68k-dis.c b/opcodes/m68k-dis.c
new file mode 100644
index 00000000000..a316c211a82
--- /dev/null
+++ b/opcodes/m68k-dis.c
@@ -0,0 +1,1243 @@
+/* Print Motorola 68k instructions.
+ Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "dis-asm.h"
+#include "floatformat.h"
+#include <libiberty.h>
+#include "opintl.h"
+
+#include "opcode/m68k.h"
+
+/* Local function prototypes */
+
+static int
+fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
+
+static void
+dummy_print_address PARAMS ((bfd_vma, struct disassemble_info *));
+
+static int
+fetch_arg PARAMS ((unsigned char *, int, int, disassemble_info *));
+
+static void
+print_base PARAMS ((int, bfd_vma, disassemble_info*));
+
+static unsigned char *
+print_indexed PARAMS ((int, unsigned char *, bfd_vma, disassemble_info *));
+
+static int
+print_insn_arg PARAMS ((const char *, unsigned char *, unsigned char *,
+ bfd_vma, disassemble_info *));
+
+CONST char * CONST fpcr_names[] = {
+ "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
+ "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"};
+
+static char *const reg_names[] = {
+ "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
+ "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
+ "%ps", "%pc"};
+
+/* Sign-extend an (unsigned char). */
+#if __STDC__ == 1
+#define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
+#else
+#define COERCE_SIGNED_CHAR(ch) ((int)(((ch) ^ 0x80) & 0xFF) - 128)
+#endif
+
+/* Get a 1 byte signed integer. */
+#define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
+
+/* Get a 2 byte signed integer. */
+#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
+#define NEXTWORD(p) \
+ (p += 2, FETCH_DATA (info, p), \
+ COERCE16 ((p[-2] << 8) + p[-1]))
+
+/* Get a 4 byte signed integer. */
+#define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
+#define NEXTLONG(p) \
+ (p += 4, FETCH_DATA (info, p), \
+ (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
+
+/* Get a 4 byte unsigned integer. */
+#define NEXTULONG(p) \
+ (p += 4, FETCH_DATA (info, p), \
+ (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
+
+/* Get a single precision float. */
+#define NEXTSINGLE(val, p) \
+ (p += 4, FETCH_DATA (info, p), \
+ floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
+
+/* Get a double precision float. */
+#define NEXTDOUBLE(val, p) \
+ (p += 8, FETCH_DATA (info, p), \
+ floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
+
+/* Get an extended precision float. */
+#define NEXTEXTEND(val, p) \
+ (p += 12, FETCH_DATA (info, p), \
+ floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
+
+/* Need a function to convert from packed to double
+ precision. Actually, it's easier to print a
+ packed number than a double anyway, so maybe
+ there should be a special case to handle this... */
+#define NEXTPACKED(p) \
+ (p += 12, FETCH_DATA (info, p), 0.0)
+
+
+/* Maximum length of an instruction. */
+#define MAXLEN 22
+
+#include <setjmp.h>
+
+struct private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+ struct disassemble_info *info;
+ bfd_byte *addr;
+{
+ int status;
+ struct private *priv = (struct private *)info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ longjmp (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+/* This function is used to print to the bit-bucket. */
+static int
+#ifdef __STDC__
+dummy_printer (FILE * file, const char * format, ...)
+#else
+dummy_printer (file) FILE *file;
+#endif
+ { return 0; }
+
+static void
+dummy_print_address (vma, info)
+ bfd_vma vma;
+ struct disassemble_info *info;
+{
+}
+
+/* Print the m68k instruction at address MEMADDR in debugged memory,
+ on INFO->STREAM. Returns length of the instruction, in bytes. */
+
+int
+print_insn_m68k (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info *info;
+{
+ register int i;
+ register unsigned char *p;
+ unsigned char *save_p;
+ register const char *d;
+ register unsigned long bestmask;
+ const struct m68k_opcode *best = 0;
+ unsigned int arch_mask;
+ struct private priv;
+ bfd_byte *buffer = priv.the_buffer;
+ fprintf_ftype save_printer = info->fprintf_func;
+ void (*save_print_address) PARAMS((bfd_vma, struct disassemble_info*))
+ = info->print_address_func;
+ int major_opcode;
+ static int numopcodes[16];
+ static const struct m68k_opcode **opcodes[16];
+
+ if (!opcodes[0])
+ {
+ /* Speed up the matching by sorting the opcode table on the upper
+ four bits of the opcode. */
+ const struct m68k_opcode **opc_pointer[16];
+
+ /* First count how many opcodes are in each of the sixteen buckets. */
+ for (i = 0; i < m68k_numopcodes; i++)
+ numopcodes[(m68k_opcodes[i].opcode >> 28) & 15]++;
+
+ /* Then create a sorted table of pointers that point into the
+ unsorted table. */
+ opc_pointer[0] = ((const struct m68k_opcode **)
+ xmalloc (sizeof (struct m68k_opcode *)
+ * m68k_numopcodes));
+ opcodes[0] = opc_pointer[0];
+ for (i = 1; i < 16; i++)
+ {
+ opc_pointer[i] = opc_pointer[i - 1] + numopcodes[i - 1];
+ opcodes[i] = opc_pointer[i];
+ }
+
+ for (i = 0; i < m68k_numopcodes; i++)
+ *opc_pointer[(m68k_opcodes[i].opcode >> 28) & 15]++ = &m68k_opcodes[i];
+
+ }
+
+ info->private_data = (PTR) &priv;
+ /* Tell objdump to use two bytes per chunk and six bytes per line for
+ displaying raw data. */
+ info->bytes_per_chunk = 2;
+ info->bytes_per_line = 6;
+ info->display_endian = BFD_ENDIAN_BIG;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = memaddr;
+ if (setjmp (priv.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+ switch (info->mach)
+ {
+ default:
+ case 0:
+ arch_mask = (unsigned int) -1;
+ break;
+ case bfd_mach_m68000:
+ arch_mask = m68000;
+ break;
+ case bfd_mach_m68008:
+ arch_mask = m68008;
+ break;
+ case bfd_mach_m68010:
+ arch_mask = m68010;
+ break;
+ case bfd_mach_m68020:
+ arch_mask = m68020;
+ break;
+ case bfd_mach_m68030:
+ arch_mask = m68030;
+ break;
+ case bfd_mach_m68040:
+ arch_mask = m68040;
+ break;
+ case bfd_mach_m68060:
+ arch_mask = m68060;
+ break;
+ }
+
+ arch_mask |= m68881 | m68851;
+
+ bestmask = 0;
+ FETCH_DATA (info, buffer + 2);
+ major_opcode = (buffer[0] >> 4) & 15;
+ for (i = 0; i < numopcodes[major_opcode]; i++)
+ {
+ const struct m68k_opcode *opc = opcodes[major_opcode][i];
+ unsigned long opcode = opc->opcode;
+ unsigned long match = opc->match;
+
+ if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
+ && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
+ /* Only fetch the next two bytes if we need to. */
+ && (((0xffff & match) == 0)
+ ||
+ (FETCH_DATA (info, buffer + 4)
+ && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
+ && ((0xff & buffer[3] & match) == (0xff & opcode)))
+ )
+ && (opc->arch & arch_mask) != 0)
+ {
+ /* Don't use for printout the variants of divul and divsl
+ that have the same register number in two places.
+ The more general variants will match instead. */
+ for (d = opc->args; *d; d += 2)
+ if (d[1] == 'D')
+ break;
+
+ /* Don't use for printout the variants of most floating
+ point coprocessor instructions which use the same
+ register number in two places, as above. */
+ if (*d == '\0')
+ for (d = opc->args; *d; d += 2)
+ if (d[1] == 't')
+ break;
+
+ /* Don't match fmovel with more than one register; wait for
+ fmoveml. */
+ if (*d == '\0')
+ {
+ for (d = opc->args; *d; d += 2)
+ {
+ if (d[0] == 's' && d[1] == '8')
+ {
+ int val;
+
+ val = fetch_arg (buffer, d[1], 3, info);
+ if ((val & (val - 1)) != 0)
+ break;
+ }
+ }
+ }
+
+ if (*d == '\0' && match > bestmask)
+ {
+ best = opc;
+ bestmask = match;
+ }
+ }
+ }
+
+ if (best == 0)
+ goto invalid;
+
+ /* Point at first word of argument data,
+ and at descriptor for first argument. */
+ p = buffer + 2;
+
+ /* Figure out how long the fixed-size portion of the instruction is.
+ The only place this is stored in the opcode table is
+ in the arguments--look for arguments which specify fields in the 2nd
+ or 3rd words of the instruction. */
+ for (d = best->args; *d; d += 2)
+ {
+ /* I don't think it is necessary to be checking d[0] here; I suspect
+ all this could be moved to the case statement below. */
+ if (d[0] == '#')
+ {
+ if (d[1] == 'l' && p - buffer < 6)
+ p = buffer + 6;
+ else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
+ p = buffer + 4;
+ }
+ if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
+ p = buffer + 4;
+ switch (d[1])
+ {
+ case '1':
+ case '2':
+ case '3':
+ case '7':
+ case '8':
+ case '9':
+ case 'i':
+ if (p - buffer < 4)
+ p = buffer + 4;
+ break;
+ case '4':
+ case '5':
+ case '6':
+ if (p - buffer < 6)
+ p = buffer + 6;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* pflusha is an exceptions. It takes no arguments but is two words
+ long. Recognize it by looking at the lower 16 bits of the mask. */
+ if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
+ p = buffer + 4;
+
+ /* lpstop is another exception. It takes a one word argument but is
+ three words long. */
+ if (p - buffer < 6
+ && (best->match & 0xffff) == 0xffff
+ && best->args[0] == '#'
+ && best->args[1] == 'w')
+ {
+ /* Copy the one word argument into the usual location for a one
+ word argument, to simplify printing it. We can get away with
+ this because we know exactly what the second word is, and we
+ aren't going to print anything based on it. */
+ p = buffer + 6;
+ FETCH_DATA (info, p);
+ buffer[2] = buffer[4];
+ buffer[3] = buffer[5];
+ }
+
+ FETCH_DATA (info, p);
+
+ d = best->args;
+
+ /* We can the operands twice. The first time we don't print anything,
+ but look for errors. */
+
+ save_p = p;
+ info->print_address_func = dummy_print_address;
+ info->fprintf_func = (fprintf_ftype)dummy_printer;
+ for ( ; *d; d += 2)
+ {
+ int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
+ if (eaten >= 0)
+ p += eaten;
+ else if (eaten == -1)
+ goto invalid;
+ else
+ {
+ (*info->fprintf_func)(info->stream,
+ /* xgettext:c-format */
+ _("<internal error in opcode table: %s %s>\n"),
+ best->name,
+ best->args);
+ goto invalid;
+ }
+
+ }
+ p = save_p;
+ info->fprintf_func = save_printer;
+ info->print_address_func = save_print_address;
+
+ d = best->args;
+
+ (*info->fprintf_func) (info->stream, "%s", best->name);
+
+ if (*d)
+ (*info->fprintf_func) (info->stream, " ");
+
+ while (*d)
+ {
+ p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
+ d += 2;
+ if (*d && *(d - 2) != 'I' && *d != 'k')
+ (*info->fprintf_func) (info->stream, ",");
+ }
+ return p - buffer;
+
+ invalid:
+ /* Handle undefined instructions. */
+ info->fprintf_func = save_printer;
+ info->print_address_func = save_print_address;
+ (*info->fprintf_func) (info->stream, "0%o",
+ (buffer[0] << 8) + buffer[1]);
+ return 2;
+}
+
+/* Returns number of bytes "eaten" by the operand, or
+ return -1 if an invalid operand was found, or -2 if
+ an opcode tabe error was found. */
+
+static int
+print_insn_arg (d, buffer, p0, addr, info)
+ const char *d;
+ unsigned char *buffer;
+ unsigned char *p0;
+ bfd_vma addr; /* PC for this arg to be relative to */
+ disassemble_info *info;
+{
+ register int val = 0;
+ register int place = d[1];
+ register unsigned char *p = p0;
+ int regno;
+ register CONST char *regname;
+ register unsigned char *p1;
+ double flval;
+ int flt_p;
+ bfd_signed_vma disp;
+ unsigned int uval;
+
+ switch (*d)
+ {
+ case 'c': /* cache identifier */
+ {
+ static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
+ val = fetch_arg (buffer, place, 2, info);
+ (*info->fprintf_func) (info->stream, cacheFieldName[val]);
+ break;
+ }
+
+ case 'a': /* address register indirect only. Cf. case '+'. */
+ {
+ (*info->fprintf_func)
+ (info->stream,
+ "%s@",
+ reg_names [fetch_arg (buffer, place, 3, info) + 8]);
+ break;
+ }
+
+ case '_': /* 32-bit absolute address for move16. */
+ {
+ uval = NEXTULONG (p);
+ (*info->print_address_func) (uval, info);
+ break;
+ }
+
+ case 'C':
+ (*info->fprintf_func) (info->stream, "%%ccr");
+ break;
+
+ case 'S':
+ (*info->fprintf_func) (info->stream, "%%sr");
+ break;
+
+ case 'U':
+ (*info->fprintf_func) (info->stream, "%%usp");
+ break;
+
+ case 'J':
+ {
+ static const struct { char *name; int value; } names[]
+ = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
+ {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
+ {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
+ {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
+ {"%msp", 0x803}, {"%isp", 0x804},
+
+ /* Should we be calling this psr like we do in case 'Y'? */
+ {"%mmusr",0x805},
+
+ {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
+
+ val = fetch_arg (buffer, place, 12, info);
+ for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
+ if (names[regno].value == val)
+ {
+ (*info->fprintf_func) (info->stream, "%s", names[regno].name);
+ break;
+ }
+ if (regno < 0)
+ (*info->fprintf_func) (info->stream, "%d", val);
+ }
+ break;
+
+ case 'Q':
+ val = fetch_arg (buffer, place, 3, info);
+ /* 0 means 8, except for the bkpt instruction... */
+ if (val == 0 && d[1] != 's')
+ val = 8;
+ (*info->fprintf_func) (info->stream, "#%d", val);
+ break;
+
+ case 'M':
+ val = fetch_arg (buffer, place, 8, info);
+ if (val & 0x80)
+ val = val - 0x100;
+ (*info->fprintf_func) (info->stream, "#%d", val);
+ break;
+
+ case 'T':
+ val = fetch_arg (buffer, place, 4, info);
+ (*info->fprintf_func) (info->stream, "#%d", val);
+ break;
+
+ case 'D':
+ (*info->fprintf_func) (info->stream, "%s",
+ reg_names[fetch_arg (buffer, place, 3, info)]);
+ break;
+
+ case 'A':
+ (*info->fprintf_func)
+ (info->stream, "%s",
+ reg_names[fetch_arg (buffer, place, 3, info) + 010]);
+ break;
+
+ case 'R':
+ (*info->fprintf_func)
+ (info->stream, "%s",
+ reg_names[fetch_arg (buffer, place, 4, info)]);
+ break;
+
+ case 'r':
+ regno = fetch_arg (buffer, place, 4, info);
+ if (regno > 7)
+ (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
+ else
+ (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
+ break;
+
+ case 'F':
+ (*info->fprintf_func)
+ (info->stream, "%%fp%d",
+ fetch_arg (buffer, place, 3, info));
+ break;
+
+ case 'O':
+ val = fetch_arg (buffer, place, 6, info);
+ if (val & 0x20)
+ (*info->fprintf_func) (info->stream, "%s", reg_names [val & 7]);
+ else
+ (*info->fprintf_func) (info->stream, "%d", val);
+ break;
+
+ case '+':
+ (*info->fprintf_func)
+ (info->stream, "%s@+",
+ reg_names[fetch_arg (buffer, place, 3, info) + 8]);
+ break;
+
+ case '-':
+ (*info->fprintf_func)
+ (info->stream, "%s@-",
+ reg_names[fetch_arg (buffer, place, 3, info) + 8]);
+ break;
+
+ case 'k':
+ if (place == 'k')
+ (*info->fprintf_func)
+ (info->stream, "{%s}",
+ reg_names[fetch_arg (buffer, place, 3, info)]);
+ else if (place == 'C')
+ {
+ val = fetch_arg (buffer, place, 7, info);
+ if ( val > 63 ) /* This is a signed constant. */
+ val -= 128;
+ (*info->fprintf_func) (info->stream, "{#%d}", val);
+ }
+ else
+ return -2;
+ break;
+
+ case '#':
+ case '^':
+ p1 = buffer + (*d == '#' ? 2 : 4);
+ if (place == 's')
+ val = fetch_arg (buffer, place, 4, info);
+ else if (place == 'C')
+ val = fetch_arg (buffer, place, 7, info);
+ else if (place == '8')
+ val = fetch_arg (buffer, place, 3, info);
+ else if (place == '3')
+ val = fetch_arg (buffer, place, 8, info);
+ else if (place == 'b')
+ val = NEXTBYTE (p1);
+ else if (place == 'w' || place == 'W')
+ val = NEXTWORD (p1);
+ else if (place == 'l')
+ val = NEXTLONG (p1);
+ else
+ return -2;
+ (*info->fprintf_func) (info->stream, "#%d", val);
+ break;
+
+ case 'B':
+ if (place == 'b')
+ disp = NEXTBYTE (p);
+ else if (place == 'B')
+ disp = COERCE_SIGNED_CHAR(buffer[1]);
+ else if (place == 'w' || place == 'W')
+ disp = NEXTWORD (p);
+ else if (place == 'l' || place == 'L' || place == 'C')
+ disp = NEXTLONG (p);
+ else if (place == 'g')
+ {
+ disp = NEXTBYTE (buffer);
+ if (disp == 0)
+ disp = NEXTWORD (p);
+ else if (disp == -1)
+ disp = NEXTLONG (p);
+ }
+ else if (place == 'c')
+ {
+ if (buffer[1] & 0x40) /* If bit six is one, long offset */
+ disp = NEXTLONG (p);
+ else
+ disp = NEXTWORD (p);
+ }
+ else
+ return -2;
+
+ (*info->print_address_func) (addr + disp, info);
+ break;
+
+ case 'd':
+ val = NEXTWORD (p);
+ (*info->fprintf_func)
+ (info->stream, "%s@(%d)",
+ reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
+ break;
+
+ case 's':
+ (*info->fprintf_func) (info->stream, "%s",
+ fpcr_names[fetch_arg (buffer, place, 3, info)]);
+ break;
+
+ case 'I':
+ /* Get coprocessor ID... */
+ val = fetch_arg (buffer, 'd', 3, info);
+
+ if (val != 1) /* Unusual coprocessor ID? */
+ (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
+ break;
+
+ case '*':
+ case '~':
+ case '%':
+ case ';':
+ case '@':
+ case '!':
+ case '$':
+ case '?':
+ case '/':
+ case '&':
+ case '|':
+ case '<':
+ case '>':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'v':
+
+ if (place == 'd')
+ {
+ val = fetch_arg (buffer, 'x', 6, info);
+ val = ((val & 7) << 3) + ((val >> 3) & 7);
+ }
+ else
+ val = fetch_arg (buffer, 's', 6, info);
+
+ /* Get register number assuming address register. */
+ regno = (val & 7) + 8;
+ regname = reg_names[regno];
+ switch (val >> 3)
+ {
+ case 0:
+ (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
+ break;
+
+ case 1:
+ (*info->fprintf_func) (info->stream, "%s", regname);
+ break;
+
+ case 2:
+ (*info->fprintf_func) (info->stream, "%s@", regname);
+ break;
+
+ case 3:
+ (*info->fprintf_func) (info->stream, "%s@+", regname);
+ break;
+
+ case 4:
+ (*info->fprintf_func) (info->stream, "%s@-", regname);
+ break;
+
+ case 5:
+ val = NEXTWORD (p);
+ (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
+ break;
+
+ case 6:
+ p = print_indexed (regno, p, addr, info);
+ break;
+
+ case 7:
+ switch (val & 7)
+ {
+ case 0:
+ val = NEXTWORD (p);
+ (*info->print_address_func) (val, info);
+ break;
+
+ case 1:
+ uval = NEXTULONG (p);
+ (*info->print_address_func) (uval, info);
+ break;
+
+ case 2:
+ val = NEXTWORD (p);
+ (*info->fprintf_func) (info->stream, "%%pc@(");
+ (*info->print_address_func) (addr + val, info);
+ (*info->fprintf_func) (info->stream, ")");
+ break;
+
+ case 3:
+ p = print_indexed (-1, p, addr, info);
+ break;
+
+ case 4:
+ flt_p = 1; /* Assume it's a float... */
+ switch( place )
+ {
+ case 'b':
+ val = NEXTBYTE (p);
+ flt_p = 0;
+ break;
+
+ case 'w':
+ val = NEXTWORD (p);
+ flt_p = 0;
+ break;
+
+ case 'l':
+ val = NEXTLONG (p);
+ flt_p = 0;
+ break;
+
+ case 'f':
+ NEXTSINGLE(flval, p);
+ break;
+
+ case 'F':
+ NEXTDOUBLE(flval, p);
+ break;
+
+ case 'x':
+ NEXTEXTEND(flval, p);
+ break;
+
+ case 'p':
+ flval = NEXTPACKED(p);
+ break;
+
+ default:
+ return -1;
+ }
+ if ( flt_p ) /* Print a float? */
+ (*info->fprintf_func) (info->stream, "#%g", flval);
+ else
+ (*info->fprintf_func) (info->stream, "#%d", val);
+ break;
+
+ default:
+ return -1;
+ }
+ }
+ break;
+
+ case 'L':
+ case 'l':
+ if (place == 'w')
+ {
+ char doneany;
+ p1 = buffer + 2;
+ val = NEXTWORD (p1);
+ /* Move the pointer ahead if this point is farther ahead
+ than the last. */
+ p = p1 > p ? p1 : p;
+ if (val == 0)
+ {
+ (*info->fprintf_func) (info->stream, "#0");
+ break;
+ }
+ if (*d == 'l')
+ {
+ register int newval = 0;
+ for (regno = 0; regno < 16; ++regno)
+ if (val & (0x8000 >> regno))
+ newval |= 1 << regno;
+ val = newval;
+ }
+ val &= 0xffff;
+ doneany = 0;
+ for (regno = 0; regno < 16; ++regno)
+ if (val & (1 << regno))
+ {
+ int first_regno;
+ if (doneany)
+ (*info->fprintf_func) (info->stream, "/");
+ doneany = 1;
+ (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
+ first_regno = regno;
+ while (val & (1 << (regno + 1)))
+ ++regno;
+ if (regno > first_regno)
+ (*info->fprintf_func) (info->stream, "-%s",
+ reg_names[regno]);
+ }
+ }
+ else if (place == '3')
+ {
+ /* `fmovem' insn. */
+ char doneany;
+ val = fetch_arg (buffer, place, 8, info);
+ if (val == 0)
+ {
+ (*info->fprintf_func) (info->stream, "#0");
+ break;
+ }
+ if (*d == 'l')
+ {
+ register int newval = 0;
+ for (regno = 0; regno < 8; ++regno)
+ if (val & (0x80 >> regno))
+ newval |= 1 << regno;
+ val = newval;
+ }
+ val &= 0xff;
+ doneany = 0;
+ for (regno = 0; regno < 8; ++regno)
+ if (val & (1 << regno))
+ {
+ int first_regno;
+ if (doneany)
+ (*info->fprintf_func) (info->stream, "/");
+ doneany = 1;
+ (*info->fprintf_func) (info->stream, "%%fp%d", regno);
+ first_regno = regno;
+ while (val & (1 << (regno + 1)))
+ ++regno;
+ if (regno > first_regno)
+ (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
+ }
+ }
+ else if (place == '8')
+ {
+ /* fmoveml for FP status registers */
+ (*info->fprintf_func) (info->stream, "%s",
+ fpcr_names[fetch_arg (buffer, place, 3,
+ info)]);
+ }
+ else
+ return -2;
+ break;
+
+ case 'X':
+ place = '8';
+ case 'Y':
+ case 'Z':
+ case 'W':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ {
+ int val = fetch_arg (buffer, place, 5, info);
+ char *name = 0;
+ switch (val)
+ {
+ case 2: name = "%tt0"; break;
+ case 3: name = "%tt1"; break;
+ case 0x10: name = "%tc"; break;
+ case 0x11: name = "%drp"; break;
+ case 0x12: name = "%srp"; break;
+ case 0x13: name = "%crp"; break;
+ case 0x14: name = "%cal"; break;
+ case 0x15: name = "%val"; break;
+ case 0x16: name = "%scc"; break;
+ case 0x17: name = "%ac"; break;
+ case 0x18: name = "%psr"; break;
+ case 0x19: name = "%pcsr"; break;
+ case 0x1c:
+ case 0x1d:
+ {
+ int break_reg = ((buffer[3] >> 2) & 7);
+ (*info->fprintf_func)
+ (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
+ break_reg);
+ }
+ break;
+ default:
+ (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
+ }
+ if (name)
+ (*info->fprintf_func) (info->stream, "%s", name);
+ }
+ break;
+
+ case 'f':
+ {
+ int fc = fetch_arg (buffer, place, 5, info);
+ if (fc == 1)
+ (*info->fprintf_func) (info->stream, "%%dfc");
+ else if (fc == 0)
+ (*info->fprintf_func) (info->stream, "%%sfc");
+ else
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
+ }
+ break;
+
+ case 'V':
+ (*info->fprintf_func) (info->stream, "%%val");
+ break;
+
+ case 't':
+ {
+ int level = fetch_arg (buffer, place, 3, info);
+ (*info->fprintf_func) (info->stream, "%d", level);
+ }
+ break;
+
+ default:
+ return -2;
+ }
+
+ return p - p0;
+}
+
+/* Fetch BITS bits from a position in the instruction specified by CODE.
+ CODE is a "place to put an argument", or 'x' for a destination
+ that is a general address (mode and register).
+ BUFFER contains the instruction. */
+
+static int
+fetch_arg (buffer, code, bits, info)
+ unsigned char *buffer;
+ int code;
+ int bits;
+ disassemble_info *info;
+{
+ register int val = 0;
+ switch (code)
+ {
+ case 's':
+ val = buffer[1];
+ break;
+
+ case 'd': /* Destination, for register or quick. */
+ val = (buffer[0] << 8) + buffer[1];
+ val >>= 9;
+ break;
+
+ case 'x': /* Destination, for general arg */
+ val = (buffer[0] << 8) + buffer[1];
+ val >>= 6;
+ break;
+
+ case 'k':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[3] >> 4);
+ break;
+
+ case 'C':
+ FETCH_DATA (info, buffer + 3);
+ val = buffer[3];
+ break;
+
+ case '1':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[2] << 8) + buffer[3];
+ val >>= 12;
+ break;
+
+ case '2':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[2] << 8) + buffer[3];
+ val >>= 6;
+ break;
+
+ case '3':
+ case 'j':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[2] << 8) + buffer[3];
+ break;
+
+ case '4':
+ FETCH_DATA (info, buffer + 5);
+ val = (buffer[4] << 8) + buffer[5];
+ val >>= 12;
+ break;
+
+ case '5':
+ FETCH_DATA (info, buffer + 5);
+ val = (buffer[4] << 8) + buffer[5];
+ val >>= 6;
+ break;
+
+ case '6':
+ FETCH_DATA (info, buffer + 5);
+ val = (buffer[4] << 8) + buffer[5];
+ break;
+
+ case '7':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[2] << 8) + buffer[3];
+ val >>= 7;
+ break;
+
+ case '8':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[2] << 8) + buffer[3];
+ val >>= 10;
+ break;
+
+ case '9':
+ FETCH_DATA (info, buffer + 3);
+ val = (buffer[2] << 8) + buffer[3];
+ val >>= 5;
+ break;
+
+ case 'e':
+ val = (buffer[1] >> 6);
+ break;
+
+ default:
+ abort ();
+ }
+
+ switch (bits)
+ {
+ case 2:
+ return val & 3;
+ case 3:
+ return val & 7;
+ case 4:
+ return val & 017;
+ case 5:
+ return val & 037;
+ case 6:
+ return val & 077;
+ case 7:
+ return val & 0177;
+ case 8:
+ return val & 0377;
+ case 12:
+ return val & 07777;
+ default:
+ abort ();
+ }
+}
+
+/* Print an indexed argument. The base register is BASEREG (-1 for pc).
+ P points to extension word, in buffer.
+ ADDR is the nominal core address of that extension word. */
+
+static unsigned char *
+print_indexed (basereg, p, addr, info)
+ int basereg;
+ unsigned char *p;
+ bfd_vma addr;
+ disassemble_info *info;
+{
+ register int word;
+ static char *const scales[] = {"", ":2", ":4", ":8"};
+ bfd_vma base_disp;
+ bfd_vma outer_disp;
+ char buf[40];
+ char vmabuf[50];
+
+ word = NEXTWORD (p);
+
+ /* Generate the text for the index register.
+ Where this will be output is not yet determined. */
+ sprintf (buf, "%s:%c%s",
+ reg_names[(word >> 12) & 0xf],
+ (word & 0x800) ? 'l' : 'w',
+ scales[(word >> 9) & 3]);
+
+ /* Handle the 68000 style of indexing. */
+
+ if ((word & 0x100) == 0)
+ {
+ base_disp = word & 0xff;
+ if ((base_disp & 0x80) != 0)
+ base_disp -= 0x100;
+ if (basereg == -1)
+ base_disp += addr;
+ print_base (basereg, base_disp, info);
+ (*info->fprintf_func) (info->stream, ",%s)", buf);
+ return p;
+ }
+
+ /* Handle the generalized kind. */
+ /* First, compute the displacement to add to the base register. */
+
+ if (word & 0200)
+ {
+ if (basereg == -1)
+ basereg = -3;
+ else
+ basereg = -2;
+ }
+ if (word & 0100)
+ buf[0] = '\0';
+ base_disp = 0;
+ switch ((word >> 4) & 3)
+ {
+ case 2:
+ base_disp = NEXTWORD (p);
+ break;
+ case 3:
+ base_disp = NEXTLONG (p);
+ }
+ if (basereg == -1)
+ base_disp += addr;
+
+ /* Handle single-level case (not indirect) */
+
+ if ((word & 7) == 0)
+ {
+ print_base (basereg, base_disp, info);
+ if (buf[0] != '\0')
+ (*info->fprintf_func) (info->stream, ",%s", buf);
+ (*info->fprintf_func) (info->stream, ")");
+ return p;
+ }
+
+ /* Two level. Compute displacement to add after indirection. */
+
+ outer_disp = 0;
+ switch (word & 3)
+ {
+ case 2:
+ outer_disp = NEXTWORD (p);
+ break;
+ case 3:
+ outer_disp = NEXTLONG (p);
+ }
+
+ print_base (basereg, base_disp, info);
+ if ((word & 4) == 0 && buf[0] != '\0')
+ {
+ (*info->fprintf_func) (info->stream, ",%s", buf);
+ buf[0] = '\0';
+ }
+ sprintf_vma (vmabuf, outer_disp);
+ (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
+ if (buf[0] != '\0')
+ (*info->fprintf_func) (info->stream, ",%s", buf);
+ (*info->fprintf_func) (info->stream, ")");
+
+ return p;
+}
+
+/* Print a base register REGNO and displacement DISP, on INFO->STREAM.
+ REGNO = -1 for pc, -2 for none (suppressed). */
+
+static void
+print_base (regno, disp, info)
+ int regno;
+ bfd_vma disp;
+ disassemble_info *info;
+{
+ if (regno == -1)
+ {
+ (*info->fprintf_func) (info->stream, "%%pc@(");
+ (*info->print_address_func) (disp, info);
+ }
+ else
+ {
+ char buf[50];
+
+ if (regno == -2)
+ (*info->fprintf_func) (info->stream, "@(");
+ else if (regno == -3)
+ (*info->fprintf_func) (info->stream, "%%zpc@(");
+ else
+ (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
+
+ sprintf_vma (buf, disp);
+ (*info->fprintf_func) (info->stream, "%s", buf);
+ }
+}
diff --git a/opcodes/m68k-opc.c b/opcodes/m68k-opc.c
new file mode 100644
index 00000000000..15e1b8dd626
--- /dev/null
+++ b/opcodes/m68k-opc.c
@@ -0,0 +1,2090 @@
+/* Opcode table for m680[012346]0/m6888[12]/m68851/mcf5200.
+ Copyright 1989, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation.
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "opcode/m68k.h"
+
+#define one(x) ((unsigned int) (x) << 16)
+#define two(x, y) (((unsigned int) (x) << 16) + (y))
+
+/* The assembler requires that all instances of the same mnemonic must
+ be consecutive. If they aren't, the assembler will bomb at
+ runtime. */
+
+const struct m68k_opcode m68k_opcodes[] =
+{
+{"abcd", one(0140400), one(0170770), "DsDd", m68000up },
+{"abcd", one(0140410), one(0170770), "-s-d", m68000up },
+
+{"addaw", one(0150300), one(0170700), "*wAd", m68000up },
+{"addal", one(0150700), one(0170700), "*lAd", m68000up | mcf5200 },
+
+{"addib", one(0003000), one(0177700), "#b$s", m68000up },
+{"addiw", one(0003100), one(0177700), "#w$s", m68000up },
+{"addil", one(0003200), one(0177700), "#l$s", m68000up },
+{"addil", one(0003200), one(0177700), "#lDs", mcf5200 },
+
+{"addqb", one(0050000), one(0170700), "Qd$b", m68000up },
+{"addqw", one(0050100), one(0170700), "Qd%w", m68000up },
+{"addql", one(0050200), one(0170700), "Qd%l", m68000up | mcf5200 },
+
+/* The add opcode can generate the adda, addi, and addq instructions. */
+{"addb", one(0050000), one(0170700), "Qd$b", m68000up },
+{"addb", one(0003000), one(0177700), "#b$s", m68000up },
+{"addb", one(0150000), one(0170700), ";bDd", m68000up },
+{"addb", one(0150400), one(0170700), "Dd~b", m68000up },
+{"addw", one(0050100), one(0170700), "Qd%w", m68000up },
+{"addw", one(0150300), one(0170700), "*wAd", m68000up },
+{"addw", one(0003100), one(0177700), "#w$s", m68000up },
+{"addw", one(0150100), one(0170700), "*wDd", m68000up },
+{"addw", one(0150500), one(0170700), "Dd~w", m68000up },
+{"addl", one(0050200), one(0170700), "Qd%l", m68000up | mcf5200 },
+{"addl", one(0003200), one(0177700), "#l$s", m68000up },
+{"addl", one(0003200), one(0177700), "#lDs", mcf5200 },
+{"addl", one(0150700), one(0170700), "*lAd", m68000up | mcf5200 },
+{"addl", one(0150200), one(0170700), "*lDd", m68000up | mcf5200 },
+{"addl", one(0150600), one(0170700), "Dd~l", m68000up | mcf5200 },
+
+{"addxb", one(0150400), one(0170770), "DsDd", m68000up },
+{"addxb", one(0150410), one(0170770), "-s-d", m68000up },
+{"addxw", one(0150500), one(0170770), "DsDd", m68000up },
+{"addxw", one(0150510), one(0170770), "-s-d", m68000up },
+{"addxl", one(0150600), one(0170770), "DsDd", m68000up | mcf5200 },
+{"addxl", one(0150610), one(0170770), "-s-d", m68000up },
+
+{"andib", one(0001000), one(0177700), "#b$s", m68000up },
+{"andib", one(0001074), one(0177777), "#bCs", m68000up },
+{"andiw", one(0001100), one(0177700), "#w$s", m68000up },
+{"andiw", one(0001174), one(0177777), "#wSs", m68000up },
+{"andil", one(0001200), one(0177700), "#l$s", m68000up },
+{"andil", one(0001200), one(0177700), "#lDs", mcf5200 },
+{"andi", one(0001100), one(0177700), "#w$s", m68000up },
+{"andi", one(0001074), one(0177777), "#bCs", m68000up },
+{"andi", one(0001174), one(0177777), "#wSs", m68000up },
+
+/* The and opcode can generate the andi instruction. */
+{"andb", one(0001000), one(0177700), "#b$s", m68000up },
+{"andb", one(0001074), one(0177777), "#bCs", m68000up },
+{"andb", one(0140000), one(0170700), ";bDd", m68000up },
+{"andb", one(0140400), one(0170700), "Dd~b", m68000up },
+{"andw", one(0001100), one(0177700), "#w$s", m68000up },
+{"andw", one(0001174), one(0177777), "#wSs", m68000up },
+{"andw", one(0140100), one(0170700), ";wDd", m68000up },
+{"andw", one(0140500), one(0170700), "Dd~w", m68000up },
+{"andl", one(0001200), one(0177700), "#l$s", m68000up },
+{"andl", one(0001200), one(0177700), "#lDs", mcf5200 },
+{"andl", one(0140200), one(0170700), ";lDd", m68000up | mcf5200 },
+{"andl", one(0140600), one(0170700), "Dd~l", m68000up | mcf5200 },
+{"and", one(0001100), one(0177700), "#w$w", m68000up },
+{"and", one(0001074), one(0177777), "#bCs", m68000up },
+{"and", one(0001174), one(0177777), "#wSs", m68000up },
+{"and", one(0140100), one(0170700), ";wDd", m68000up },
+{"and", one(0140500), one(0170700), "Dd~w", m68000up },
+
+{"aslb", one(0160400), one(0170770), "QdDs", m68000up },
+{"aslb", one(0160440), one(0170770), "DdDs", m68000up },
+{"aslw", one(0160500), one(0170770), "QdDs", m68000up },
+{"aslw", one(0160540), one(0170770), "DdDs", m68000up },
+{"aslw", one(0160700), one(0177700), "~s", m68000up },
+{"asll", one(0160600), one(0170770), "QdDs", m68000up | mcf5200 },
+{"asll", one(0160640), one(0170770), "DdDs", m68000up | mcf5200 },
+
+{"asrb", one(0160000), one(0170770), "QdDs", m68000up },
+{"asrb", one(0160040), one(0170770), "DdDs", m68000up },
+{"asrw", one(0160100), one(0170770), "QdDs", m68000up },
+{"asrw", one(0160140), one(0170770), "DdDs", m68000up },
+{"asrw", one(0160300), one(0177700), "~s", m68000up },
+{"asrl", one(0160200), one(0170770), "QdDs", m68000up | mcf5200 },
+{"asrl", one(0160240), one(0170770), "DdDs", m68000up | mcf5200 },
+
+{"bhiw", one(0061000), one(0177777), "BW", m68000up | mcf5200 },
+{"blsw", one(0061400), one(0177777), "BW", m68000up | mcf5200 },
+{"bccw", one(0062000), one(0177777), "BW", m68000up | mcf5200 },
+{"bcsw", one(0062400), one(0177777), "BW", m68000up | mcf5200 },
+{"bnew", one(0063000), one(0177777), "BW", m68000up | mcf5200 },
+{"beqw", one(0063400), one(0177777), "BW", m68000up | mcf5200 },
+{"bvcw", one(0064000), one(0177777), "BW", m68000up | mcf5200 },
+{"bvsw", one(0064400), one(0177777), "BW", m68000up | mcf5200 },
+{"bplw", one(0065000), one(0177777), "BW", m68000up | mcf5200 },
+{"bmiw", one(0065400), one(0177777), "BW", m68000up | mcf5200 },
+{"bgew", one(0066000), one(0177777), "BW", m68000up | mcf5200 },
+{"bltw", one(0066400), one(0177777), "BW", m68000up | mcf5200 },
+{"bgtw", one(0067000), one(0177777), "BW", m68000up | mcf5200 },
+{"blew", one(0067400), one(0177777), "BW", m68000up | mcf5200 },
+
+{"bhil", one(0061377), one(0177777), "BL", m68020up | cpu32 },
+{"blsl", one(0061777), one(0177777), "BL", m68020up | cpu32 },
+{"bccl", one(0062377), one(0177777), "BL", m68020up | cpu32 },
+{"bcsl", one(0062777), one(0177777), "BL", m68020up | cpu32 },
+{"bnel", one(0063377), one(0177777), "BL", m68020up | cpu32 },
+{"beql", one(0063777), one(0177777), "BL", m68020up | cpu32 },
+{"bvcl", one(0064377), one(0177777), "BL", m68020up | cpu32 },
+{"bvsl", one(0064777), one(0177777), "BL", m68020up | cpu32 },
+{"bpll", one(0065377), one(0177777), "BL", m68020up | cpu32 },
+{"bmil", one(0065777), one(0177777), "BL", m68020up | cpu32 },
+{"bgel", one(0066377), one(0177777), "BL", m68020up | cpu32 },
+{"bltl", one(0066777), one(0177777), "BL", m68020up | cpu32 },
+{"bgtl", one(0067377), one(0177777), "BL", m68020up | cpu32 },
+{"blel", one(0067777), one(0177777), "BL", m68020up | cpu32 },
+
+{"bhis", one(0061000), one(0177400), "BB", m68000up | mcf5200 },
+{"blss", one(0061400), one(0177400), "BB", m68000up | mcf5200 },
+{"bccs", one(0062000), one(0177400), "BB", m68000up | mcf5200 },
+{"bcss", one(0062400), one(0177400), "BB", m68000up | mcf5200 },
+{"bnes", one(0063000), one(0177400), "BB", m68000up | mcf5200 },
+{"beqs", one(0063400), one(0177400), "BB", m68000up | mcf5200 },
+{"bvcs", one(0064000), one(0177400), "BB", m68000up | mcf5200 },
+{"bvss", one(0064400), one(0177400), "BB", m68000up | mcf5200 },
+{"bpls", one(0065000), one(0177400), "BB", m68000up | mcf5200 },
+{"bmis", one(0065400), one(0177400), "BB", m68000up | mcf5200 },
+{"bges", one(0066000), one(0177400), "BB", m68000up | mcf5200 },
+{"blts", one(0066400), one(0177400), "BB", m68000up | mcf5200 },
+{"bgts", one(0067000), one(0177400), "BB", m68000up | mcf5200 },
+{"bles", one(0067400), one(0177400), "BB", m68000up | mcf5200 },
+
+{"jhi", one(0061000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jls", one(0061400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jcc", one(0062000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jcs", one(0062400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jne", one(0063000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jeq", one(0063400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jvc", one(0064000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jvs", one(0064400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jpl", one(0065000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jmi", one(0065400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jge", one(0066000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jlt", one(0066400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jgt", one(0067000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jle", one(0067400), one(0177400), "Bg", m68000up | mcf5200 },
+
+{"bchg", one(0000500), one(0170700), "Dd$s", m68000up | mcf5200 },
+{"bchg", one(0004100), one(0177700), "#b$s", m68000up },
+{"bchg", one(0004100), one(0177700), "#bqs", mcf5200 },
+
+{"bclr", one(0000600), one(0170700), "Dd$s", m68000up },
+{"bclr", one(0000600), one(0170700), "Ddvs", mcf5200 },
+{"bclr", one(0004200), one(0177700), "#b$s", m68000up },
+{"bclr", one(0004200), one(0177700), "#bqs", mcf5200 },
+
+{"bfchg", two(0165300, 0), two(0177700, 0170000), "?sO2O3", m68020up },
+{"bfclr", two(0166300, 0), two(0177700, 0170000), "?sO2O3", m68020up },
+{"bfexts", two(0165700, 0), two(0177700, 0100000), "/sO2O3D1", m68020up },
+{"bfextu", two(0164700, 0), two(0177700, 0100000), "/sO2O3D1", m68020up },
+{"bfffo", two(0166700, 0), two(0177700, 0100000), "/sO2O3D1", m68020up },
+{"bfins", two(0167700, 0), two(0177700, 0100000), "D1?sO2O3", m68020up },
+{"bfset", two(0167300, 0), two(0177700, 0170000), "?sO2O3", m68020up },
+{"bftst", two(0164300, 0), two(0177700, 0170000), "/sO2O3", m68020up },
+
+{"bgnd", one(0045372), one(0177777), "", cpu32 },
+
+{"bkpt", one(0044110), one(0177770), "ts", m68010up },
+
+{"braw", one(0060000), one(0177777), "BW", m68000up | mcf5200 },
+{"bral", one(0060377), one(0177777), "BL", m68020up | cpu32 },
+{"bras", one(0060000), one(0177400), "BB", m68000up | mcf5200 },
+
+{"bset", one(0000700), one(0170700), "Dd$s", m68000up },
+{"bset", one(0000700), one(0170700), "Ddvs", mcf5200 },
+{"bset", one(0004300), one(0177700), "#b$s", m68000up },
+{"bset", one(0004300), one(0177700), "#bqs", mcf5200 },
+
+{"bsrw", one(0060400), one(0177777), "BW", m68000up | mcf5200 },
+{"bsrl", one(0060777), one(0177777), "BL", m68020up | cpu32 },
+{"bsrs", one(0060400), one(0177400), "BB", m68000up | mcf5200 },
+
+{"btst", one(0000400), one(0170700), "Dd;b", m68000up | mcf5200 },
+{"btst", one(0004000), one(0177700), "#b@s", m68000up },
+{"btst", one(0004000), one(0177700), "#bqs", mcf5200 },
+
+{"callm", one(0003300), one(0177700), "#b!s", m68020 },
+
+{"cas2w", two(0006374,0), two(0177777,0007070), "D3D6D2D5r1r4", m68020up },
+{"cas2w", two(0006374,0), two(0177777,0007070), "D3D6D2D5R1R4", m68020up },
+{"cas2l", two(0007374,0), two(0177777,0007070), "D3D6D2D5r1r4", m68020up },
+{"cas2l", two(0007374,0), two(0177777,0007070), "D3D6D2D5R1R4", m68020up },
+
+{"casb", two(0005300, 0), two(0177700, 0177070), "D3D2~s", m68020up },
+{"casw", two(0006300, 0), two(0177700, 0177070), "D3D2~s", m68020up },
+{"casl", two(0007300, 0), two(0177700, 0177070), "D3D2~s", m68020up },
+
+{"chk2b", two(0000300,0004000), two(0177700,07777), "!sR1", m68020up | cpu32 },
+{"chk2w", two(0001300,0004000), two(0177700,07777), "!sR1", m68020up | cpu32 },
+{"chk2l", two(0002300,0004000), two(0177700,07777), "!sR1", m68020up | cpu32 },
+
+{"chkl", one(0040400), one(0170700), ";lDd", m68000up },
+{"chkw", one(0040600), one(0170700), ";wDd", m68000up },
+
+#define SCOPE_LINE (0x1 << 3)
+#define SCOPE_PAGE (0x2 << 3)
+#define SCOPE_ALL (0x3 << 3)
+
+{"cinva", one(0xf400|SCOPE_ALL), one(0xff38), "ce", m68040up },
+{"cinvl", one(0xf400|SCOPE_LINE), one(0xff38), "ceas", m68040up },
+{"cinvp", one(0xf400|SCOPE_PAGE), one(0xff38), "ceas", m68040up },
+
+{"cpusha", one(0xf420|SCOPE_ALL), one(0xff38), "ce", m68040up },
+{"cpushl", one(0xf420|SCOPE_LINE), one(0xff38), "ceas", m68040up },
+{"cpushl", one(0x04e8), one(0xfff8), "as", mcf5200 },
+{"cpushp", one(0xf420|SCOPE_PAGE), one(0xff38), "ceas", m68040up },
+
+#undef SCOPE_LINE
+#undef SCOPE_PAGE
+#undef SCOPE_ALL
+
+{"clrb", one(0041000), one(0177700), "$s", m68000up | mcf5200 },
+{"clrw", one(0041100), one(0177700), "$s", m68000up | mcf5200 },
+{"clrl", one(0041200), one(0177700), "$s", m68000up | mcf5200 },
+
+{"cmp2b", two(0000300,0), two(0177700,07777), "!sR1", m68020up | cpu32 },
+{"cmp2w", two(0001300,0), two(0177700,07777), "!sR1", m68020up | cpu32 },
+{"cmp2l", two(0002300,0), two(0177700,07777), "!sR1", m68020up | cpu32 },
+
+{"cmpaw", one(0130300), one(0170700), "*wAd", m68000up },
+{"cmpal", one(0130700), one(0170700), "*lAd", m68000up | mcf5200 },
+
+{"cmpib", one(0006000), one(0177700), "#b@s", m68000up },
+{"cmpiw", one(0006100), one(0177700), "#w@s", m68000up },
+{"cmpil", one(0006200), one(0177700), "#l@s", m68000up },
+{"cmpil", one(0006200), one(0177700), "#lDs", mcf5200 },
+
+{"cmpmb", one(0130410), one(0170770), "+s+d", m68000up },
+{"cmpmw", one(0130510), one(0170770), "+s+d", m68000up },
+{"cmpml", one(0130610), one(0170770), "+s+d", m68000up },
+
+/* The cmp opcode can generate the cmpa, cmpm, and cmpi instructions. */
+{"cmpb", one(0006000), one(0177700), "#b@s", m68000up },
+{"cmpb", one(0130410), one(0170770), "+s+d", m68000up },
+{"cmpb", one(0130000), one(0170700), ";bDd", m68000up },
+{"cmpw", one(0130300), one(0170700), "*wAd", m68000up },
+{"cmpw", one(0006100), one(0177700), "#w@s", m68000up },
+{"cmpw", one(0130510), one(0170770), "+s+d", m68000up },
+{"cmpw", one(0130100), one(0170700), "*wDd", m68000up },
+{"cmpl", one(0130700), one(0170700), "*lAd", m68000up | mcf5200 },
+{"cmpl", one(0006200), one(0177700), "#l@s", m68000up },
+{"cmpl", one(0006200), one(0177700), "#lDs", mcf5200 },
+{"cmpl", one(0130610), one(0170770), "+s+d", m68000up },
+{"cmpl", one(0130200), one(0170700), "*lDd", m68000up | mcf5200 },
+
+{"dbcc", one(0052310), one(0177770), "DsBw", m68000up },
+{"dbcs", one(0052710), one(0177770), "DsBw", m68000up },
+{"dbeq", one(0053710), one(0177770), "DsBw", m68000up },
+{"dbf", one(0050710), one(0177770), "DsBw", m68000up },
+{"dbge", one(0056310), one(0177770), "DsBw", m68000up },
+{"dbgt", one(0057310), one(0177770), "DsBw", m68000up },
+{"dbhi", one(0051310), one(0177770), "DsBw", m68000up },
+{"dble", one(0057710), one(0177770), "DsBw", m68000up },
+{"dbls", one(0051710), one(0177770), "DsBw", m68000up },
+{"dblt", one(0056710), one(0177770), "DsBw", m68000up },
+{"dbmi", one(0055710), one(0177770), "DsBw", m68000up },
+{"dbne", one(0053310), one(0177770), "DsBw", m68000up },
+{"dbpl", one(0055310), one(0177770), "DsBw", m68000up },
+{"dbt", one(0050310), one(0177770), "DsBw", m68000up },
+{"dbvc", one(0054310), one(0177770), "DsBw", m68000up },
+{"dbvs", one(0054710), one(0177770), "DsBw", m68000up },
+
+{"divsw", one(0100700), one(0170700), ";wDd", m68000up },
+
+{"divsl", two(0046100,0006000),two(0177700,0107770),";lD3D1", m68020up|cpu32 },
+{"divsl", two(0046100,0004000),two(0177700,0107770),";lDD", m68020up|cpu32 },
+
+{"divsll", two(0046100,0004000),two(0177700,0107770),";lD3D1",m68020up|cpu32 },
+{"divsll", two(0046100,0004000),two(0177700,0107770),";lDD", m68020up|cpu32 },
+
+{"divuw", one(0100300), one(0170700), ";wDd", m68000up },
+
+{"divul", two(0046100,0002000),two(0177700,0107770),";lD3D1", m68020up|cpu32 },
+{"divul", two(0046100,0000000),two(0177700,0107770),";lDD", m68020up|cpu32 },
+
+{"divull", two(0046100,0000000),two(0177700,0107770),";lD3D1",m68020up|cpu32 },
+{"divull", two(0046100,0000000),two(0177700,0107770),";lDD", m68020up|cpu32 },
+
+{"eorib", one(0005000), one(0177700), "#b$s", m68000up },
+{"eorib", one(0005074), one(0177777), "#bCs", m68000up },
+{"eoriw", one(0005100), one(0177700), "#w$s", m68000up },
+{"eoriw", one(0005174), one(0177777), "#wSs", m68000up },
+{"eoril", one(0005200), one(0177700), "#l$s", m68000up },
+{"eoril", one(0005200), one(0177700), "#lDs", mcf5200 },
+{"eori", one(0005074), one(0177777), "#bCs", m68000up },
+{"eori", one(0005174), one(0177777), "#wSs", m68000up },
+{"eori", one(0005100), one(0177700), "#w$s", m68000up },
+
+/* The eor opcode can generate the eori instruction. */
+{"eorb", one(0005000), one(0177700), "#b$s", m68000up },
+{"eorb", one(0005074), one(0177777), "#bCs", m68000up },
+{"eorb", one(0130400), one(0170700), "Dd$s", m68000up },
+{"eorw", one(0005100), one(0177700), "#w$s", m68000up },
+{"eorw", one(0005174), one(0177777), "#wSs", m68000up },
+{"eorw", one(0130500), one(0170700), "Dd$s", m68000up },
+{"eorl", one(0005200), one(0177700), "#l$s", m68000up },
+{"eorl", one(0005200), one(0177700), "#lDs", mcf5200 },
+{"eorl", one(0130600), one(0170700), "Dd$s", m68000up | mcf5200 },
+{"eor", one(0005074), one(0177777), "#bCs", m68000up },
+{"eor", one(0005174), one(0177777), "#wSs", m68000up },
+{"eor", one(0005100), one(0177700), "#w$s", m68000up },
+{"eor", one(0130500), one(0170700), "Dd$s", m68000up },
+
+{"exg", one(0140500), one(0170770), "DdDs", m68000up },
+{"exg", one(0140510), one(0170770), "AdAs", m68000up },
+{"exg", one(0140610), one(0170770), "DdAs", m68000up },
+{"exg", one(0140610), one(0170770), "AsDd", m68000up },
+
+{"extw", one(0044200), one(0177770), "Ds", m68000up|mcf5200 },
+{"extl", one(0044300), one(0177770), "Ds", m68000up|mcf5200 },
+{"extbl", one(0044700), one(0177770), "Ds", m68020up|cpu32|mcf5200 },
+
+/* float stuff starts here */
+
+{"fabsb", two(0xF000, 0x5818), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fabsd", two(0xF000, 0x5418), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fabsl", two(0xF000, 0x4018), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fabsp", two(0xF000, 0x4C18), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fabss", two(0xF000, 0x4418), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fabsw", two(0xF000, 0x5018), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fabsx", two(0xF000, 0x0018), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fabsx", two(0xF000, 0x4818), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fabsx", two(0xF000, 0x0018), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fsabsb", two(0xF000, 0x5858), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fsabsd", two(0xF000, 0x5458), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fsabsl", two(0xF000, 0x4058), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fsabsp", two(0xF000, 0x4C58), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fsabss", two(0xF000, 0x4458), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fsabsw", two(0xF000, 0x5058), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fsabsx", two(0xF000, 0x0058), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fsabsx", two(0xF000, 0x4858), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fsabsx", two(0xF000, 0x0058), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"fdabsb", two(0xF000, 0x585c), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up},
+{"fdabsd", two(0xF000, 0x545c), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up},
+{"fdabsl", two(0xF000, 0x405c), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up},
+{"fdabsp", two(0xF000, 0x4C5c), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up},
+{"fdabss", two(0xF000, 0x445c), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up},
+{"fdabsw", two(0xF000, 0x505c), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up},
+{"fdabsx", two(0xF000, 0x005c), two(0xF1C0, 0xE07F), "IiF8F7", m68040up},
+{"fdabsx", two(0xF000, 0x485c), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up},
+{"fdabsx", two(0xF000, 0x005c), two(0xF1C0, 0xE07F), "IiFt", m68040up},
+
+{"facosb", two(0xF000, 0x581C), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"facosd", two(0xF000, 0x541C), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"facosl", two(0xF000, 0x401C), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"facosp", two(0xF000, 0x4C1C), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"facoss", two(0xF000, 0x441C), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"facosw", two(0xF000, 0x501C), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"facosx", two(0xF000, 0x001C), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"facosx", two(0xF000, 0x481C), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"facosx", two(0xF000, 0x001C), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"faddb", two(0xF000, 0x5822), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"faddd", two(0xF000, 0x5422), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"faddl", two(0xF000, 0x4022), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"faddp", two(0xF000, 0x4C22), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fadds", two(0xF000, 0x4422), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"faddw", two(0xF000, 0x5022), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"faddx", two(0xF000, 0x0022), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"faddx", two(0xF000, 0x4822), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+{"fsaddb", two(0xF000, 0x5862), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fsaddd", two(0xF000, 0x5462), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fsaddl", two(0xF000, 0x4062), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fsaddp", two(0xF000, 0x4C62), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fsadds", two(0xF000, 0x4462), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fsaddw", two(0xF000, 0x5062), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fsaddx", two(0xF000, 0x0062), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fsaddx", two(0xF000, 0x4862), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+
+{"fdaddb", two(0xF000, 0x5866), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fdaddd", two(0xF000, 0x5466), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fdaddl", two(0xF000, 0x4066), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fdaddp", two(0xF000, 0x4C66), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fdadds", two(0xF000, 0x4466), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fdaddw", two(0xF000, 0x5066), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fdaddx", two(0xF000, 0x0066), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fdaddx", two(0xF000, 0x4866), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+
+{"fasinb", two(0xF000, 0x580C), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fasind", two(0xF000, 0x540C), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fasinl", two(0xF000, 0x400C), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fasinp", two(0xF000, 0x4C0C), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fasins", two(0xF000, 0x440C), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fasinw", two(0xF000, 0x500C), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fasinx", two(0xF000, 0x000C), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fasinx", two(0xF000, 0x480C), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fasinx", two(0xF000, 0x000C), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fatanb", two(0xF000, 0x580A), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fatand", two(0xF000, 0x540A), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fatanl", two(0xF000, 0x400A), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fatanp", two(0xF000, 0x4C0A), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fatans", two(0xF000, 0x440A), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fatanw", two(0xF000, 0x500A), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fatanx", two(0xF000, 0x000A), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fatanx", two(0xF000, 0x480A), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fatanx", two(0xF000, 0x000A), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fatanhb", two(0xF000, 0x580D), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fatanhd", two(0xF000, 0x540D), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fatanhl", two(0xF000, 0x400D), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fatanhp", two(0xF000, 0x4C0D), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fatanhs", two(0xF000, 0x440D), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fatanhw", two(0xF000, 0x500D), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fatanhx", two(0xF000, 0x000D), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fatanhx", two(0xF000, 0x480D), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fatanhx", two(0xF000, 0x000D), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fbeq", one(0xF081), one(0xF1FF), "IdBW", mfloat },
+{"fbf", one(0xF080), one(0xF1FF), "IdBW", mfloat },
+{"fbge", one(0xF093), one(0xF1FF), "IdBW", mfloat },
+{"fbgl", one(0xF096), one(0xF1FF), "IdBW", mfloat },
+{"fbgle", one(0xF097), one(0xF1FF), "IdBW", mfloat },
+{"fbgt", one(0xF092), one(0xF1FF), "IdBW", mfloat },
+{"fble", one(0xF095), one(0xF1FF), "IdBW", mfloat },
+{"fblt", one(0xF094), one(0xF1FF), "IdBW", mfloat },
+{"fbne", one(0xF08E), one(0xF1FF), "IdBW", mfloat },
+{"fbnge", one(0xF09C), one(0xF1FF), "IdBW", mfloat },
+{"fbngl", one(0xF099), one(0xF1FF), "IdBW", mfloat },
+{"fbngle", one(0xF098), one(0xF1FF), "IdBW", mfloat },
+{"fbngt", one(0xF09D), one(0xF1FF), "IdBW", mfloat },
+{"fbnle", one(0xF09A), one(0xF1FF), "IdBW", mfloat },
+{"fbnlt", one(0xF09B), one(0xF1FF), "IdBW", mfloat },
+{"fboge", one(0xF083), one(0xF1FF), "IdBW", mfloat },
+{"fbogl", one(0xF086), one(0xF1FF), "IdBW", mfloat },
+{"fbogt", one(0xF082), one(0xF1FF), "IdBW", mfloat },
+{"fbole", one(0xF085), one(0xF1FF), "IdBW", mfloat },
+{"fbolt", one(0xF084), one(0xF1FF), "IdBW", mfloat },
+{"fbor", one(0xF087), one(0xF1FF), "IdBW", mfloat },
+{"fbseq", one(0xF091), one(0xF1FF), "IdBW", mfloat },
+{"fbsf", one(0xF090), one(0xF1FF), "IdBW", mfloat },
+{"fbsne", one(0xF09E), one(0xF1FF), "IdBW", mfloat },
+{"fbst", one(0xF09F), one(0xF1FF), "IdBW", mfloat },
+{"fbt", one(0xF08F), one(0xF1FF), "IdBW", mfloat },
+{"fbueq", one(0xF089), one(0xF1FF), "IdBW", mfloat },
+{"fbuge", one(0xF08B), one(0xF1FF), "IdBW", mfloat },
+{"fbugt", one(0xF08A), one(0xF1FF), "IdBW", mfloat },
+{"fbule", one(0xF08D), one(0xF1FF), "IdBW", mfloat },
+{"fbult", one(0xF08C), one(0xF1FF), "IdBW", mfloat },
+{"fbun", one(0xF088), one(0xF1FF), "IdBW", mfloat },
+
+{"fbeql", one(0xF0C1), one(0xF1FF), "IdBC", mfloat },
+{"fbfl", one(0xF0C0), one(0xF1FF), "IdBC", mfloat },
+{"fbgel", one(0xF0D3), one(0xF1FF), "IdBC", mfloat },
+{"fbgll", one(0xF0D6), one(0xF1FF), "IdBC", mfloat },
+{"fbglel", one(0xF0D7), one(0xF1FF), "IdBC", mfloat },
+{"fbgtl", one(0xF0D2), one(0xF1FF), "IdBC", mfloat },
+{"fblel", one(0xF0D5), one(0xF1FF), "IdBC", mfloat },
+{"fbltl", one(0xF0D4), one(0xF1FF), "IdBC", mfloat },
+{"fbnel", one(0xF0CE), one(0xF1FF), "IdBC", mfloat },
+{"fbngel", one(0xF0DC), one(0xF1FF), "IdBC", mfloat },
+{"fbngll", one(0xF0D9), one(0xF1FF), "IdBC", mfloat },
+{"fbnglel", one(0xF0D8), one(0xF1FF), "IdBC", mfloat },
+{"fbngtl", one(0xF0DD), one(0xF1FF), "IdBC", mfloat },
+{"fbnlel", one(0xF0DA), one(0xF1FF), "IdBC", mfloat },
+{"fbnltl", one(0xF0DB), one(0xF1FF), "IdBC", mfloat },
+{"fbogel", one(0xF0C3), one(0xF1FF), "IdBC", mfloat },
+{"fbogll", one(0xF0C6), one(0xF1FF), "IdBC", mfloat },
+{"fbogtl", one(0xF0C2), one(0xF1FF), "IdBC", mfloat },
+{"fbolel", one(0xF0C5), one(0xF1FF), "IdBC", mfloat },
+{"fboltl", one(0xF0C4), one(0xF1FF), "IdBC", mfloat },
+{"fborl", one(0xF0C7), one(0xF1FF), "IdBC", mfloat },
+{"fbseql", one(0xF0D1), one(0xF1FF), "IdBC", mfloat },
+{"fbsfl", one(0xF0D0), one(0xF1FF), "IdBC", mfloat },
+{"fbsnel", one(0xF0DE), one(0xF1FF), "IdBC", mfloat },
+{"fbstl", one(0xF0DF), one(0xF1FF), "IdBC", mfloat },
+{"fbtl", one(0xF0CF), one(0xF1FF), "IdBC", mfloat },
+{"fbueql", one(0xF0C9), one(0xF1FF), "IdBC", mfloat },
+{"fbugel", one(0xF0CB), one(0xF1FF), "IdBC", mfloat },
+{"fbugtl", one(0xF0CA), one(0xF1FF), "IdBC", mfloat },
+{"fbulel", one(0xF0CD), one(0xF1FF), "IdBC", mfloat },
+{"fbultl", one(0xF0CC), one(0xF1FF), "IdBC", mfloat },
+{"fbunl", one(0xF0C8), one(0xF1FF), "IdBC", mfloat },
+
+{"fjeq", one(0xF081), one(0xF1BF), "IdBc", mfloat },
+{"fjf", one(0xF080), one(0xF1BF), "IdBc", mfloat },
+{"fjge", one(0xF093), one(0xF1BF), "IdBc", mfloat },
+{"fjgl", one(0xF096), one(0xF1BF), "IdBc", mfloat },
+{"fjgle", one(0xF097), one(0xF1BF), "IdBc", mfloat },
+{"fjgt", one(0xF092), one(0xF1BF), "IdBc", mfloat },
+{"fjle", one(0xF095), one(0xF1BF), "IdBc", mfloat },
+{"fjlt", one(0xF094), one(0xF1BF), "IdBc", mfloat },
+{"fjne", one(0xF08E), one(0xF1BF), "IdBc", mfloat },
+{"fjnge", one(0xF09C), one(0xF1BF), "IdBc", mfloat },
+{"fjngl", one(0xF099), one(0xF1BF), "IdBc", mfloat },
+{"fjngle", one(0xF098), one(0xF1BF), "IdBc", mfloat },
+{"fjngt", one(0xF09D), one(0xF1BF), "IdBc", mfloat },
+{"fjnle", one(0xF09A), one(0xF1BF), "IdBc", mfloat },
+{"fjnlt", one(0xF09B), one(0xF1BF), "IdBc", mfloat },
+{"fjoge", one(0xF083), one(0xF1BF), "IdBc", mfloat },
+{"fjogl", one(0xF086), one(0xF1BF), "IdBc", mfloat },
+{"fjogt", one(0xF082), one(0xF1BF), "IdBc", mfloat },
+{"fjole", one(0xF085), one(0xF1BF), "IdBc", mfloat },
+{"fjolt", one(0xF084), one(0xF1BF), "IdBc", mfloat },
+{"fjor", one(0xF087), one(0xF1BF), "IdBc", mfloat },
+{"fjseq", one(0xF091), one(0xF1BF), "IdBc", mfloat },
+{"fjsf", one(0xF090), one(0xF1BF), "IdBc", mfloat },
+{"fjsne", one(0xF09E), one(0xF1BF), "IdBc", mfloat },
+{"fjst", one(0xF09F), one(0xF1BF), "IdBc", mfloat },
+{"fjt", one(0xF08F), one(0xF1BF), "IdBc", mfloat },
+{"fjueq", one(0xF089), one(0xF1BF), "IdBc", mfloat },
+{"fjuge", one(0xF08B), one(0xF1BF), "IdBc", mfloat },
+{"fjugt", one(0xF08A), one(0xF1BF), "IdBc", mfloat },
+{"fjule", one(0xF08D), one(0xF1BF), "IdBc", mfloat },
+{"fjult", one(0xF08C), one(0xF1BF), "IdBc", mfloat },
+{"fjun", one(0xF088), one(0xF1BF), "IdBc", mfloat },
+
+{"fcmpb", two(0xF000, 0x5838), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fcmpd", two(0xF000, 0x5438), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fcmpl", two(0xF000, 0x4038), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fcmpp", two(0xF000, 0x4C38), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fcmps", two(0xF000, 0x4438), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fcmpw", two(0xF000, 0x5038), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fcmpx", two(0xF000, 0x0038), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fcmpx", two(0xF000, 0x4838), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+{"fcosb", two(0xF000, 0x581D), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fcosd", two(0xF000, 0x541D), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fcosl", two(0xF000, 0x401D), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fcosp", two(0xF000, 0x4C1D), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fcoss", two(0xF000, 0x441D), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fcosw", two(0xF000, 0x501D), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fcosx", two(0xF000, 0x001D), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fcosx", two(0xF000, 0x481D), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fcosx", two(0xF000, 0x001D), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fcoshb", two(0xF000, 0x5819), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fcoshd", two(0xF000, 0x5419), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fcoshl", two(0xF000, 0x4019), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fcoshp", two(0xF000, 0x4C19), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fcoshs", two(0xF000, 0x4419), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fcoshw", two(0xF000, 0x5019), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fcoshx", two(0xF000, 0x0019), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fcoshx", two(0xF000, 0x4819), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fcoshx", two(0xF000, 0x0019), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fdbeq", two(0xF048, 0x0001), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbf", two(0xF048, 0x0000), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbge", two(0xF048, 0x0013), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbgl", two(0xF048, 0x0016), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbgle", two(0xF048, 0x0017), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbgt", two(0xF048, 0x0012), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdble", two(0xF048, 0x0015), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdblt", two(0xF048, 0x0014), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbne", two(0xF048, 0x000E), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbnge", two(0xF048, 0x001C), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbngl", two(0xF048, 0x0019), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbngle", two(0xF048, 0x0018), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbngt", two(0xF048, 0x001D), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbnle", two(0xF048, 0x001A), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbnlt", two(0xF048, 0x001B), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdboge", two(0xF048, 0x0003), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbogl", two(0xF048, 0x0006), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbogt", two(0xF048, 0x0002), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbole", two(0xF048, 0x0005), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbolt", two(0xF048, 0x0004), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbor", two(0xF048, 0x0007), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbseq", two(0xF048, 0x0011), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbsf", two(0xF048, 0x0010), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbsne", two(0xF048, 0x001E), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbst", two(0xF048, 0x001F), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbt", two(0xF048, 0x000F), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbueq", two(0xF048, 0x0009), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbuge", two(0xF048, 0x000B), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbugt", two(0xF048, 0x000A), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbule", two(0xF048, 0x000D), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbult", two(0xF048, 0x000C), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+{"fdbun", two(0xF048, 0x0008), two(0xF1F8, 0xFFFF), "IiDsBw", mfloat },
+
+{"fdivb", two(0xF000, 0x5820), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fdivd", two(0xF000, 0x5420), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fdivl", two(0xF000, 0x4020), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fdivp", two(0xF000, 0x4C20), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fdivs", two(0xF000, 0x4420), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fdivw", two(0xF000, 0x5020), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fdivx", two(0xF000, 0x0020), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fdivx", two(0xF000, 0x4820), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+{"fsdivb", two(0xF000, 0x5860), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fsdivd", two(0xF000, 0x5460), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fsdivl", two(0xF000, 0x4060), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fsdivp", two(0xF000, 0x4C60), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fsdivs", two(0xF000, 0x4460), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fsdivw", two(0xF000, 0x5060), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fsdivx", two(0xF000, 0x0060), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fsdivx", two(0xF000, 0x4860), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+
+{"fddivb", two(0xF000, 0x5864), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fddivd", two(0xF000, 0x5464), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fddivl", two(0xF000, 0x4064), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fddivp", two(0xF000, 0x4C64), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fddivs", two(0xF000, 0x4464), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fddivw", two(0xF000, 0x5064), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fddivx", two(0xF000, 0x0064), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fddivx", two(0xF000, 0x4864), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+
+{"fetoxb", two(0xF000, 0x5810), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fetoxd", two(0xF000, 0x5410), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fetoxl", two(0xF000, 0x4010), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fetoxp", two(0xF000, 0x4C10), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fetoxs", two(0xF000, 0x4410), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fetoxw", two(0xF000, 0x5010), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fetoxx", two(0xF000, 0x0010), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fetoxx", two(0xF000, 0x4810), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fetoxx", two(0xF000, 0x0010), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fetoxm1b", two(0xF000, 0x5808), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fetoxm1d", two(0xF000, 0x5408), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fetoxm1l", two(0xF000, 0x4008), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fetoxm1p", two(0xF000, 0x4C08), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fetoxm1s", two(0xF000, 0x4408), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fetoxm1w", two(0xF000, 0x5008), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fetoxm1x", two(0xF000, 0x0008), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fetoxm1x", two(0xF000, 0x4808), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fetoxm1x", two(0xF000, 0x0008), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fgetexpb", two(0xF000, 0x581E), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fgetexpd", two(0xF000, 0x541E), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fgetexpl", two(0xF000, 0x401E), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fgetexpp", two(0xF000, 0x4C1E), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fgetexps", two(0xF000, 0x441E), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fgetexpw", two(0xF000, 0x501E), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fgetexpx", two(0xF000, 0x001E), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fgetexpx", two(0xF000, 0x481E), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fgetexpx", two(0xF000, 0x001E), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fgetmanb", two(0xF000, 0x581F), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fgetmand", two(0xF000, 0x541F), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fgetmanl", two(0xF000, 0x401F), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fgetmanp", two(0xF000, 0x4C1F), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fgetmans", two(0xF000, 0x441F), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fgetmanw", two(0xF000, 0x501F), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fgetmanx", two(0xF000, 0x001F), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fgetmanx", two(0xF000, 0x481F), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fgetmanx", two(0xF000, 0x001F), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fintb", two(0xF000, 0x5801), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fintd", two(0xF000, 0x5401), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fintl", two(0xF000, 0x4001), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fintp", two(0xF000, 0x4C01), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fints", two(0xF000, 0x4401), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fintw", two(0xF000, 0x5001), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fintx", two(0xF000, 0x0001), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fintx", two(0xF000, 0x4801), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fintx", two(0xF000, 0x0001), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fintrzb", two(0xF000, 0x5803), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fintrzd", two(0xF000, 0x5403), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fintrzl", two(0xF000, 0x4003), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fintrzp", two(0xF000, 0x4C03), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fintrzs", two(0xF000, 0x4403), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fintrzw", two(0xF000, 0x5003), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fintrzx", two(0xF000, 0x0003), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fintrzx", two(0xF000, 0x4803), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fintrzx", two(0xF000, 0x0003), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"flog10b", two(0xF000, 0x5815), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"flog10d", two(0xF000, 0x5415), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"flog10l", two(0xF000, 0x4015), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"flog10p", two(0xF000, 0x4C15), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"flog10s", two(0xF000, 0x4415), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"flog10w", two(0xF000, 0x5015), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"flog10x", two(0xF000, 0x0015), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"flog10x", two(0xF000, 0x4815), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"flog10x", two(0xF000, 0x0015), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"flog2b", two(0xF000, 0x5816), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"flog2d", two(0xF000, 0x5416), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"flog2l", two(0xF000, 0x4016), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"flog2p", two(0xF000, 0x4C16), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"flog2s", two(0xF000, 0x4416), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"flog2w", two(0xF000, 0x5016), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"flog2x", two(0xF000, 0x0016), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"flog2x", two(0xF000, 0x4816), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"flog2x", two(0xF000, 0x0016), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"flognb", two(0xF000, 0x5814), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"flognd", two(0xF000, 0x5414), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"flognl", two(0xF000, 0x4014), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"flognp", two(0xF000, 0x4C14), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"flogns", two(0xF000, 0x4414), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"flognw", two(0xF000, 0x5014), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"flognx", two(0xF000, 0x0014), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"flognx", two(0xF000, 0x4814), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"flognx", two(0xF000, 0x0014), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"flognp1b", two(0xF000, 0x5806), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"flognp1d", two(0xF000, 0x5406), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"flognp1l", two(0xF000, 0x4006), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"flognp1p", two(0xF000, 0x4C06), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"flognp1s", two(0xF000, 0x4406), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"flognp1w", two(0xF000, 0x5006), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"flognp1x", two(0xF000, 0x0006), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"flognp1x", two(0xF000, 0x4806), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"flognp1x", two(0xF000, 0x0006), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fmodb", two(0xF000, 0x5821), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fmodd", two(0xF000, 0x5421), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fmodl", two(0xF000, 0x4021), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fmodp", two(0xF000, 0x4C21), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fmods", two(0xF000, 0x4421), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fmodw", two(0xF000, 0x5021), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fmodx", two(0xF000, 0x0021), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fmodx", two(0xF000, 0x4821), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+{"fmoveb", two(0xF000, 0x5800), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fmoveb", two(0xF000, 0x7800), two(0xF1C0, 0xFC7F), "IiF7$b", mfloat },
+{"fmoved", two(0xF000, 0x5400), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fmoved", two(0xF000, 0x7400), two(0xF1C0, 0xFC7F), "IiF7~F", mfloat },
+{"fmovel", two(0xF000, 0x4000), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fmovel", two(0xF000, 0x6000), two(0xF1C0, 0xFC7F), "IiF7$l", mfloat },
+/* FIXME: the next two variants should not permit moving an address
+ register to anything but the floating point instruction register. */
+{"fmovel", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8%s", mfloat },
+{"fmovel", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*ls8", mfloat },
+{"fmovep", two(0xF000, 0x4C00), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fmovep", two(0xF000, 0x6C00), two(0xF1C0, 0xFC00), "IiF7~pkC", mfloat },
+{"fmovep", two(0xF000, 0x7C00), two(0xF1C0, 0xFC0F), "IiF7~pDk", mfloat },
+{"fmoves", two(0xF000, 0x4400), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fmoves", two(0xF000, 0x6400), two(0xF1C0, 0xFC7F), "IiF7$f", mfloat },
+{"fmovew", two(0xF000, 0x5000), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fmovew", two(0xF000, 0x7000), two(0xF1C0, 0xFC7F), "IiF7$w", mfloat },
+{"fmovex", two(0xF000, 0x0000), two(0xF1FF, 0xE07F), "IiF8F7", mfloat },
+{"fmovex", two(0xF000, 0x4800), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fmovex", two(0xF000, 0x6800), two(0xF1C0, 0xFC7F), "IiF7~x", mfloat },
+
+{"fsmoveb", two(0xF000, 0x5840), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fsmoved", two(0xF000, 0x5440), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fsmovel", two(0xF000, 0x4040), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fsmoves", two(0xF000, 0x4440), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fsmovew", two(0xF000, 0x5040), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fsmovex", two(0xF000, 0x0040), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fsmovex", two(0xF000, 0x4840), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fsmovep", two(0xF000, 0x4C40), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+
+{"fdmoveb", two(0xF000, 0x5844), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fdmoved", two(0xF000, 0x5444), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fdmovel", two(0xF000, 0x4044), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fdmoves", two(0xF000, 0x4444), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fdmovew", two(0xF000, 0x5044), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fdmovex", two(0xF000, 0x0044), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fdmovex", two(0xF000, 0x4844), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fdmovep", two(0xF000, 0x4C44), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+
+{"fmovecrx", two(0xF000, 0x5C00), two(0xF1FF, 0xFC00), "Ii#CF7", mfloat },
+
+{"fmovemx", two(0xF000, 0xF800), two(0xF1C0, 0xFF8F), "IiDk&s", mfloat },
+{"fmovemx", two(0xF020, 0xE800), two(0xF1F8, 0xFF8F), "IiDk-s", mfloat },
+{"fmovemx", two(0xF000, 0xD800), two(0xF1C0, 0xFF8F), "Ii&sDk", mfloat },
+{"fmovemx", two(0xF018, 0xD800), two(0xF1F8, 0xFF8F), "Ii+sDk", mfloat },
+{"fmovemx", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Idl3&s", mfloat },
+{"fmovemx", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Id#3&s", mfloat },
+{"fmovemx", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&sl3", mfloat },
+{"fmovemx", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&s#3", mfloat },
+{"fmovemx", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "IdL3-s", mfloat },
+{"fmovemx", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "Id#3-s", mfloat },
+{"fmovemx", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+sl3", mfloat },
+{"fmovemx", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+s#3", mfloat },
+
+{"fmoveml", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8%s", mfloat },
+{"fmoveml", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "IiL8~s", mfloat },
+/* FIXME: In the next instruction, we should only permit %dn if the
+ target is a single register. We should only permit %an if the
+ target is a single %fpiar. */
+{"fmoveml", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*lL8", mfloat },
+
+{"fmovem", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "IdL3-s", mfloat },
+{"fmovem", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Idl3&s", mfloat },
+{"fmovem", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+sl3", mfloat },
+{"fmovem", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&sl3", mfloat },
+{"fmovem", two(0xF020, 0xE000), two(0xF1F8, 0xFF00), "Id#3-s", mfloat },
+{"fmovem", two(0xF020, 0xE800), two(0xF1F8, 0xFF8F), "IiDk-s", mfloat },
+{"fmovem", two(0xF000, 0xF000), two(0xF1C0, 0xFF00), "Id#3&s", mfloat },
+{"fmovem", two(0xF000, 0xF800), two(0xF1C0, 0xFF8F), "IiDk&s", mfloat },
+{"fmovem", two(0xF018, 0xD000), two(0xF1F8, 0xFF00), "Id+s#3", mfloat },
+{"fmovem", two(0xF018, 0xD800), two(0xF1F8, 0xFF8F), "Ii+sDk", mfloat },
+{"fmovem", two(0xF000, 0xD000), two(0xF1C0, 0xFF00), "Id&s#3", mfloat },
+{"fmovem", two(0xF000, 0xD800), two(0xF1C0, 0xFF8F), "Ii&sDk", mfloat },
+{"fmovem", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8%s", mfloat },
+{"fmovem", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*ss8", mfloat },
+{"fmovem", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "IiL8~s", mfloat },
+{"fmovem", two(0xF000, 0x8000), two(0xF2C0, 0xE3FF), "Ii*sL8", mfloat },
+
+{"fmulb", two(0xF000, 0x5823), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fmuld", two(0xF000, 0x5423), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fmull", two(0xF000, 0x4023), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fmulp", two(0xF000, 0x4C23), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fmuls", two(0xF000, 0x4423), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fmulw", two(0xF000, 0x5023), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fmulx", two(0xF000, 0x0023), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fmulx", two(0xF000, 0x4823), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+{"fsmulb", two(0xF000, 0x5863), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fsmuld", two(0xF000, 0x5463), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fsmull", two(0xF000, 0x4063), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fsmulp", two(0xF000, 0x4C63), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fsmuls", two(0xF000, 0x4463), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fsmulw", two(0xF000, 0x5063), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fsmulx", two(0xF000, 0x0063), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fsmulx", two(0xF000, 0x4863), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+
+{"fdmulb", two(0xF000, 0x5867), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fdmuld", two(0xF000, 0x5467), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fdmull", two(0xF000, 0x4067), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fdmulp", two(0xF000, 0x4C67), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fdmuls", two(0xF000, 0x4467), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fdmulw", two(0xF000, 0x5067), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fdmulx", two(0xF000, 0x0067), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fdmulx", two(0xF000, 0x4867), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+
+{"fnegb", two(0xF000, 0x581A), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fnegd", two(0xF000, 0x541A), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fnegl", two(0xF000, 0x401A), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fnegp", two(0xF000, 0x4C1A), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fnegs", two(0xF000, 0x441A), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fnegw", two(0xF000, 0x501A), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fnegx", two(0xF000, 0x001A), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fnegx", two(0xF000, 0x481A), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fnegx", two(0xF000, 0x001A), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fsnegb", two(0xF000, 0x585A), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fsnegd", two(0xF000, 0x545A), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fsnegl", two(0xF000, 0x405A), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fsnegp", two(0xF000, 0x4C5A), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fsnegs", two(0xF000, 0x445A), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fsnegw", two(0xF000, 0x505A), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fsnegx", two(0xF000, 0x005A), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fsnegx", two(0xF000, 0x485A), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fsnegx", two(0xF000, 0x005A), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"fdnegb", two(0xF000, 0x585E), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fdnegd", two(0xF000, 0x545E), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fdnegl", two(0xF000, 0x405E), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fdnegp", two(0xF000, 0x4C5E), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fdnegs", two(0xF000, 0x445E), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fdnegw", two(0xF000, 0x505E), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fdnegx", two(0xF000, 0x005E), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fdnegx", two(0xF000, 0x485E), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fdnegx", two(0xF000, 0x005E), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"fnop", two(0xF280, 0x0000), two(0xFFFF, 0xFFFF), "Ii", mfloat },
+
+{"fremb", two(0xF000, 0x5825), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fremd", two(0xF000, 0x5425), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"freml", two(0xF000, 0x4025), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fremp", two(0xF000, 0x4C25), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"frems", two(0xF000, 0x4425), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fremw", two(0xF000, 0x5025), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fremx", two(0xF000, 0x0025), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fremx", two(0xF000, 0x4825), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+{"frestore", one(0xF140), one(0xF1C0), "Id<s", mfloat },
+
+{"fsave", one(0xF100), one(0xF1C0), "Id>s", mfloat },
+
+{"fscaleb", two(0xF000, 0x5826), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fscaled", two(0xF000, 0x5426), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fscalel", two(0xF000, 0x4026), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fscalep", two(0xF000, 0x4C26), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fscales", two(0xF000, 0x4426), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fscalew", two(0xF000, 0x5026), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fscalex", two(0xF000, 0x0026), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fscalex", two(0xF000, 0x4826), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+
+/* $ is necessary to prevent the assembler from using PC-relative.
+ If @ were used, "label: fseq label" could produce "ftrapeq",
+ because "label" became "pc@label". */
+{"fseq", two(0xF040, 0x0001), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsf", two(0xF040, 0x0000), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsge", two(0xF040, 0x0013), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsgl", two(0xF040, 0x0016), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsgle", two(0xF040, 0x0017), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsgt", two(0xF040, 0x0012), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsle", two(0xF040, 0x0015), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fslt", two(0xF040, 0x0014), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsne", two(0xF040, 0x000E), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsnge", two(0xF040, 0x001C), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsngl", two(0xF040, 0x0019), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsngle", two(0xF040, 0x0018), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsngt", two(0xF040, 0x001D), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsnle", two(0xF040, 0x001A), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsnlt", two(0xF040, 0x001B), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsoge", two(0xF040, 0x0003), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsogl", two(0xF040, 0x0006), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsogt", two(0xF040, 0x0002), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsole", two(0xF040, 0x0005), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsolt", two(0xF040, 0x0004), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsor", two(0xF040, 0x0007), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsseq", two(0xF040, 0x0011), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fssf", two(0xF040, 0x0010), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fssne", two(0xF040, 0x001E), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsst", two(0xF040, 0x001F), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fst", two(0xF040, 0x000F), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsueq", two(0xF040, 0x0009), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsuge", two(0xF040, 0x000B), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsugt", two(0xF040, 0x000A), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsule", two(0xF040, 0x000D), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsult", two(0xF040, 0x000C), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+{"fsun", two(0xF040, 0x0008), two(0xF1C0, 0xFFFF), "Ii$s", mfloat },
+
+{"fsgldivb", two(0xF000, 0x5824), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fsgldivd", two(0xF000, 0x5424), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fsgldivl", two(0xF000, 0x4024), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fsgldivp", two(0xF000, 0x4C24), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fsgldivs", two(0xF000, 0x4424), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fsgldivw", two(0xF000, 0x5024), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fsgldivx", two(0xF000, 0x0024), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fsgldivx", two(0xF000, 0x4824), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fsgldivx", two(0xF000, 0x0024), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fsglmulb", two(0xF000, 0x5827), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fsglmuld", two(0xF000, 0x5427), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fsglmull", two(0xF000, 0x4027), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fsglmulp", two(0xF000, 0x4C27), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fsglmuls", two(0xF000, 0x4427), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fsglmulw", two(0xF000, 0x5027), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fsglmulx", two(0xF000, 0x0027), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fsglmulx", two(0xF000, 0x4827), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fsglmulx", two(0xF000, 0x0027), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fsinb", two(0xF000, 0x580E), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fsind", two(0xF000, 0x540E), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fsinl", two(0xF000, 0x400E), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fsinp", two(0xF000, 0x4C0E), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fsins", two(0xF000, 0x440E), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fsinw", two(0xF000, 0x500E), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fsinx", two(0xF000, 0x000E), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fsinx", two(0xF000, 0x480E), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fsinx", two(0xF000, 0x000E), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fsincosb", two(0xF000, 0x5830), two(0xF1C0, 0xFC78), "Ii;bF3F7", mfloat },
+{"fsincosd", two(0xF000, 0x5430), two(0xF1C0, 0xFC78), "Ii;FF3F7", mfloat },
+{"fsincosl", two(0xF000, 0x4030), two(0xF1C0, 0xFC78), "Ii;lF3F7", mfloat },
+{"fsincosp", two(0xF000, 0x4C30), two(0xF1C0, 0xFC78), "Ii;pF3F7", mfloat },
+{"fsincoss", two(0xF000, 0x4430), two(0xF1C0, 0xFC78), "Ii;fF3F7", mfloat },
+{"fsincosw", two(0xF000, 0x5030), two(0xF1C0, 0xFC78), "Ii;wF3F7", mfloat },
+{"fsincosx", two(0xF000, 0x0030), two(0xF1C0, 0xE078), "IiF8F3F7", mfloat },
+{"fsincosx", two(0xF000, 0x4830), two(0xF1C0, 0xFC78), "Ii;xF3F7", mfloat },
+
+{"fsinhb", two(0xF000, 0x5802), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fsinhd", two(0xF000, 0x5402), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fsinhl", two(0xF000, 0x4002), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fsinhp", two(0xF000, 0x4C02), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fsinhs", two(0xF000, 0x4402), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fsinhw", two(0xF000, 0x5002), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fsinhx", two(0xF000, 0x0002), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fsinhx", two(0xF000, 0x4802), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fsinhx", two(0xF000, 0x0002), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fsqrtb", two(0xF000, 0x5804), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fsqrtd", two(0xF000, 0x5404), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fsqrtl", two(0xF000, 0x4004), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fsqrtp", two(0xF000, 0x4C04), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fsqrts", two(0xF000, 0x4404), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fsqrtw", two(0xF000, 0x5004), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fsqrtx", two(0xF000, 0x0004), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fsqrtx", two(0xF000, 0x4804), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fsqrtx", two(0xF000, 0x0004), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fssqrtb", two(0xF000, 0x5841), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fssqrtd", two(0xF000, 0x5441), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fssqrtl", two(0xF000, 0x4041), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fssqrtp", two(0xF000, 0x4C41), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fssqrts", two(0xF000, 0x4441), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fssqrtw", two(0xF000, 0x5041), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fssqrtx", two(0xF000, 0x0041), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fssqrtx", two(0xF000, 0x4841), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fssqrtx", two(0xF000, 0x0041), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"fdsqrtb", two(0xF000, 0x5845), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fdsqrtd", two(0xF000, 0x5445), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fdsqrtl", two(0xF000, 0x4045), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fdsqrtp", two(0xF000, 0x4C45), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fdsqrts", two(0xF000, 0x4445), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fdsqrtw", two(0xF000, 0x5045), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fdsqrtx", two(0xF000, 0x0045), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fdsqrtx", two(0xF000, 0x4845), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fdsqrtx", two(0xF000, 0x0045), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"fsubb", two(0xF000, 0x5828), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"fsubd", two(0xF000, 0x5428), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"fsubl", two(0xF000, 0x4028), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"fsubp", two(0xF000, 0x4C28), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"fsubs", two(0xF000, 0x4428), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"fsubw", two(0xF000, 0x5028), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"fsubx", two(0xF000, 0x0028), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"fsubx", two(0xF000, 0x4828), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"fsubx", two(0xF000, 0x0028), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"fssubb", two(0xF000, 0x5868), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fssubd", two(0xF000, 0x5468), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fssubl", two(0xF000, 0x4068), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fssubp", two(0xF000, 0x4C68), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fssubs", two(0xF000, 0x4468), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fssubw", two(0xF000, 0x5068), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fssubx", two(0xF000, 0x0068), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fssubx", two(0xF000, 0x4868), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fssubx", two(0xF000, 0x0068), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"fdsubb", two(0xF000, 0x586c), two(0xF1C0, 0xFC7F), "Ii;bF7", m68040up },
+{"fdsubd", two(0xF000, 0x546c), two(0xF1C0, 0xFC7F), "Ii;FF7", m68040up },
+{"fdsubl", two(0xF000, 0x406c), two(0xF1C0, 0xFC7F), "Ii;lF7", m68040up },
+{"fdsubp", two(0xF000, 0x4C6c), two(0xF1C0, 0xFC7F), "Ii;pF7", m68040up },
+{"fdsubs", two(0xF000, 0x446c), two(0xF1C0, 0xFC7F), "Ii;fF7", m68040up },
+{"fdsubw", two(0xF000, 0x506c), two(0xF1C0, 0xFC7F), "Ii;wF7", m68040up },
+{"fdsubx", two(0xF000, 0x006c), two(0xF1C0, 0xE07F), "IiF8F7", m68040up },
+{"fdsubx", two(0xF000, 0x486c), two(0xF1C0, 0xFC7F), "Ii;xF7", m68040up },
+{"fdsubx", two(0xF000, 0x006c), two(0xF1C0, 0xE07F), "IiFt", m68040up },
+
+{"ftanb", two(0xF000, 0x580F), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"ftand", two(0xF000, 0x540F), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"ftanl", two(0xF000, 0x400F), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"ftanp", two(0xF000, 0x4C0F), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"ftans", two(0xF000, 0x440F), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"ftanw", two(0xF000, 0x500F), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"ftanx", two(0xF000, 0x000F), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"ftanx", two(0xF000, 0x480F), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"ftanx", two(0xF000, 0x000F), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"ftanhb", two(0xF000, 0x5809), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"ftanhd", two(0xF000, 0x5409), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"ftanhl", two(0xF000, 0x4009), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"ftanhp", two(0xF000, 0x4C09), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"ftanhs", two(0xF000, 0x4409), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"ftanhw", two(0xF000, 0x5009), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"ftanhx", two(0xF000, 0x0009), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"ftanhx", two(0xF000, 0x4809), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"ftanhx", two(0xF000, 0x0009), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"ftentoxb", two(0xF000, 0x5812), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"ftentoxd", two(0xF000, 0x5412), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"ftentoxl", two(0xF000, 0x4012), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"ftentoxp", two(0xF000, 0x4C12), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"ftentoxs", two(0xF000, 0x4412), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"ftentoxw", two(0xF000, 0x5012), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"ftentoxx", two(0xF000, 0x0012), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"ftentoxx", two(0xF000, 0x4812), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"ftentoxx", two(0xF000, 0x0012), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"ftrapeq", two(0xF07C, 0x0001), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapf", two(0xF07C, 0x0000), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapge", two(0xF07C, 0x0013), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapgl", two(0xF07C, 0x0016), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapgle", two(0xF07C, 0x0017), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapgt", two(0xF07C, 0x0012), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftraple", two(0xF07C, 0x0015), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftraplt", two(0xF07C, 0x0014), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapne", two(0xF07C, 0x000E), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapnge", two(0xF07C, 0x001C), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapngl", two(0xF07C, 0x0019), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapngle", two(0xF07C, 0x0018), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapngt", two(0xF07C, 0x001D), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapnle", two(0xF07C, 0x001A), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapnlt", two(0xF07C, 0x001B), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapoge", two(0xF07C, 0x0003), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapogl", two(0xF07C, 0x0006), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapogt", two(0xF07C, 0x0002), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapole", two(0xF07C, 0x0005), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapolt", two(0xF07C, 0x0004), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapor", two(0xF07C, 0x0007), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapseq", two(0xF07C, 0x0011), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapsf", two(0xF07C, 0x0010), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapsne", two(0xF07C, 0x001E), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapst", two(0xF07C, 0x001F), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapt", two(0xF07C, 0x000F), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapueq", two(0xF07C, 0x0009), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapuge", two(0xF07C, 0x000B), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapugt", two(0xF07C, 0x000A), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapule", two(0xF07C, 0x000D), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapult", two(0xF07C, 0x000C), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+{"ftrapun", two(0xF07C, 0x0008), two(0xF1FF, 0xFFFF), "Ii", mfloat },
+
+{"ftrapeqw", two(0xF07A, 0x0001), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapfw", two(0xF07A, 0x0000), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapgew", two(0xF07A, 0x0013), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapglw", two(0xF07A, 0x0016), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapglew", two(0xF07A, 0x0017), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapgtw", two(0xF07A, 0x0012), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftraplew", two(0xF07A, 0x0015), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapltw", two(0xF07A, 0x0014), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapnew", two(0xF07A, 0x000E), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapngew", two(0xF07A, 0x001C), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapnglw", two(0xF07A, 0x0019), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapnglew", two(0xF07A, 0x0018), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapngtw", two(0xF07A, 0x001D), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapnlew", two(0xF07A, 0x001A), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapnltw", two(0xF07A, 0x001B), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapogew", two(0xF07A, 0x0003), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapoglw", two(0xF07A, 0x0006), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapogtw", two(0xF07A, 0x0002), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapolew", two(0xF07A, 0x0005), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapoltw", two(0xF07A, 0x0004), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftraporw", two(0xF07A, 0x0007), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapseqw", two(0xF07A, 0x0011), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapsfw", two(0xF07A, 0x0010), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapsnew", two(0xF07A, 0x001E), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapstw", two(0xF07A, 0x001F), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftraptw", two(0xF07A, 0x000F), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapueqw", two(0xF07A, 0x0009), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapugew", two(0xF07A, 0x000B), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapugtw", two(0xF07A, 0x000A), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapulew", two(0xF07A, 0x000D), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapultw", two(0xF07A, 0x000C), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+{"ftrapunw", two(0xF07A, 0x0008), two(0xF1FF, 0xFFFF), "Ii^w", mfloat },
+
+{"ftrapeql", two(0xF07B, 0x0001), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapfl", two(0xF07B, 0x0000), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapgel", two(0xF07B, 0x0013), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapgll", two(0xF07B, 0x0016), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapglel", two(0xF07B, 0x0017), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapgtl", two(0xF07B, 0x0012), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftraplel", two(0xF07B, 0x0015), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapltl", two(0xF07B, 0x0014), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapnel", two(0xF07B, 0x000E), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapngel", two(0xF07B, 0x001C), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapngll", two(0xF07B, 0x0019), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapnglel", two(0xF07B, 0x0018), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapngtl", two(0xF07B, 0x001D), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapnlel", two(0xF07B, 0x001A), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapnltl", two(0xF07B, 0x001B), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapogel", two(0xF07B, 0x0003), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapogll", two(0xF07B, 0x0006), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapogtl", two(0xF07B, 0x0002), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapolel", two(0xF07B, 0x0005), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapoltl", two(0xF07B, 0x0004), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftraporl", two(0xF07B, 0x0007), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapseql", two(0xF07B, 0x0011), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapsfl", two(0xF07B, 0x0010), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapsnel", two(0xF07B, 0x001E), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapstl", two(0xF07B, 0x001F), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftraptl", two(0xF07B, 0x000F), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapueql", two(0xF07B, 0x0009), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapugel", two(0xF07B, 0x000B), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapugtl", two(0xF07B, 0x000A), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapulel", two(0xF07B, 0x000D), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapultl", two(0xF07B, 0x000C), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+{"ftrapunl", two(0xF07B, 0x0008), two(0xF1FF, 0xFFFF), "Ii^l", mfloat },
+
+{"ftstb", two(0xF000, 0x583A), two(0xF1C0, 0xFC7F), "Ii;b", mfloat },
+{"ftstd", two(0xF000, 0x543A), two(0xF1C0, 0xFC7F), "Ii;F", mfloat },
+{"ftstl", two(0xF000, 0x403A), two(0xF1C0, 0xFC7F), "Ii;l", mfloat },
+{"ftstp", two(0xF000, 0x4C3A), two(0xF1C0, 0xFC7F), "Ii;p", mfloat },
+{"ftsts", two(0xF000, 0x443A), two(0xF1C0, 0xFC7F), "Ii;f", mfloat },
+{"ftstw", two(0xF000, 0x503A), two(0xF1C0, 0xFC7F), "Ii;w", mfloat },
+{"ftstx", two(0xF000, 0x003A), two(0xF1C0, 0xE07F), "IiF8", mfloat },
+{"ftstx", two(0xF000, 0x483A), two(0xF1C0, 0xFC7F), "Ii;x", mfloat },
+
+{"ftwotoxb", two(0xF000, 0x5811), two(0xF1C0, 0xFC7F), "Ii;bF7", mfloat },
+{"ftwotoxd", two(0xF000, 0x5411), two(0xF1C0, 0xFC7F), "Ii;FF7", mfloat },
+{"ftwotoxl", two(0xF000, 0x4011), two(0xF1C0, 0xFC7F), "Ii;lF7", mfloat },
+{"ftwotoxp", two(0xF000, 0x4C11), two(0xF1C0, 0xFC7F), "Ii;pF7", mfloat },
+{"ftwotoxs", two(0xF000, 0x4411), two(0xF1C0, 0xFC7F), "Ii;fF7", mfloat },
+{"ftwotoxw", two(0xF000, 0x5011), two(0xF1C0, 0xFC7F), "Ii;wF7", mfloat },
+{"ftwotoxx", two(0xF000, 0x0011), two(0xF1C0, 0xE07F), "IiF8F7", mfloat },
+{"ftwotoxx", two(0xF000, 0x4811), two(0xF1C0, 0xFC7F), "Ii;xF7", mfloat },
+{"ftwotoxx", two(0xF000, 0x0011), two(0xF1C0, 0xE07F), "IiFt", mfloat },
+
+{"halt", one(0045310), one(0177777), "", m68060 | mcf5200 },
+
+{"illegal", one(0045374), one(0177777), "", m68000up },
+
+{"jmp", one(0047300), one(0177700), "!s", m68000up | mcf5200 },
+
+{"jra", one(0060000), one(0177400), "Bg", m68000up | mcf5200 },
+{"jra", one(0047300), one(0177700), "!s", m68000up | mcf5200 },
+
+{"jsr", one(0047200), one(0177700), "!s", m68000up | mcf5200 },
+
+{"jbsr", one(0060400), one(0177400), "Bg", m68000up | mcf5200 },
+{"jbsr", one(0047200), one(0177700), "!s", m68000up | mcf5200 },
+
+{"lea", one(0040700), one(0170700), "!sAd", m68000up | mcf5200 },
+
+{"lpstop", two(0174000,0000700),two(0177777,0177777),"#w", cpu32|m68060 },
+
+{"linkw", one(0047120), one(0177770), "As#w", m68000up | mcf5200 },
+{"linkl", one(0044010), one(0177770), "As#l", m68020up | cpu32 },
+{"link", one(0047120), one(0177770), "As#W", m68000up | mcf5200 },
+{"link", one(0044010), one(0177770), "As#l", m68020up | cpu32 },
+
+{"lslb", one(0160410), one(0170770), "QdDs", m68000up },
+{"lslb", one(0160450), one(0170770), "DdDs", m68000up },
+{"lslw", one(0160510), one(0170770), "QdDs", m68000up },
+{"lslw", one(0160550), one(0170770), "DdDs", m68000up },
+{"lslw", one(0161700), one(0177700), "~s", m68000up },
+{"lsll", one(0160610), one(0170770), "QdDs", m68000up | mcf5200 },
+{"lsll", one(0160650), one(0170770), "DdDs", m68000up | mcf5200 },
+
+{"lsrb", one(0160010), one(0170770), "QdDs", m68000up },
+{"lsrb", one(0160050), one(0170770), "DdDs", m68000up },
+{"lsrw", one(0160110), one(0170770), "QdDs", m68000up },
+{"lsrw", one(0160150), one(0170770), "DdDs", m68000up },
+{"lsrw", one(0161300), one(0177700), "~s", m68000up },
+{"lsrl", one(0160210), one(0170770), "QdDs", m68000up | mcf5200 },
+{"lsrl", one(0160250), one(0170770), "DdDs", m68000up | mcf5200 },
+
+/* NOTE: The mcf5200 family programmer's reference manual does not
+ indicate the byte form of the movea instruction is invalid (as it
+ is on 68000 family cpus). However, experiments on the 5202 yeild
+ unexpected results. The value is copied, but it is not sign extended
+ (as is done with movea.w) and the top three bytes in the address
+ register are not disturbed. I don't know if this is the intended
+ behavior --- it could be a hole in instruction decoding (Motorola
+ decided not to trap all invalid instructions for performance reasons)
+ --- but I suspect that it is not.
+
+ I reported this to Motorola ISD Technical Communications Support,
+ which replied that other coldfire assemblers reject movea.b. For
+ this reason I've decided to not allow moveab.
+
+ jtc@cygnus.com - 97/01/24
+ */
+
+{"moveal", one(0020100), one(0170700), "*lAd", m68000up | mcf5200 },
+{"moveaw", one(0030100), one(0170700), "*wAd", m68000up | mcf5200 },
+
+{"movec", one(0047173), one(0177777), "R1Jj", m68010up | mcf5200 },
+{"movec", one(0047173), one(0177777), "R1#j", m68010up | mcf5200 },
+{"movec", one(0047172), one(0177777), "JjR1", m68010up },
+{"movec", one(0047172), one(0177777), "#jR1", m68010up },
+
+{"movemw", one(0044200), one(0177700), "Lw&s", m68000up },
+{"movemw", one(0044240), one(0177770), "lw-s", m68000up },
+{"movemw", one(0044200), one(0177700), "#w>s", m68000up },
+{"movemw", one(0046200), one(0177700), "<sLw", m68000up },
+{"movemw", one(0046200), one(0177700), "<s#w", m68000up },
+{"moveml", one(0044300), one(0177700), "Lw&s", m68000up },
+{"moveml", one(0044340), one(0177770), "lw-s", m68000up },
+{"moveml", one(0044300), one(0177700), "#w>s", m68000up },
+{"moveml", one(0046300), one(0177700), "<sLw", m68000up },
+{"moveml", one(0046300), one(0177700), "<s#w", m68000up },
+/* FIXME: need specifier for mode 2 and 5 to simplify below insn patterns */
+{"moveml", one(0044320), one(0177770), "Lwas", mcf5200 },
+{"moveml", one(0044320), one(0177770), "#was", mcf5200 },
+{"moveml", one(0044350), one(0177770), "Lwds", mcf5200 },
+{"moveml", one(0044350), one(0177770), "#wds", mcf5200 },
+{"moveml", one(0046320), one(0177770), "asLw", mcf5200 },
+{"moveml", one(0046320), one(0177770), "as#w", mcf5200 },
+{"moveml", one(0046350), one(0177770), "dsLw", mcf5200 },
+{"moveml", one(0046350), one(0177770), "ds#w", mcf5200 },
+
+{"movepw", one(0000410), one(0170770), "dsDd", m68000up },
+{"movepw", one(0000610), one(0170770), "Ddds", m68000up },
+{"movepl", one(0000510), one(0170770), "dsDd", m68000up },
+{"movepl", one(0000710), one(0170770), "Ddds", m68000up },
+
+{"moveq", one(0070000), one(0170400), "MsDd", m68000up | mcf5200 },
+{"moveq", one(0070000), one(0170400), "#BDd", m68000up | mcf5200 },
+
+/* The move opcode can generate the movea and moveq instructions. */
+{"moveb", one(0010000), one(0170000), ";b$d", m68000up },
+{"moveb", one(0010000), one(0170000), "ms%d", mcf5200 },
+{"moveb", one(0010000), one(0170000), "nspd", mcf5200 },
+{"moveb", one(0010000), one(0170000), "obmd", mcf5200 },
+
+{"movew", one(0030000), one(0170000), "*w%d", m68000up },
+{"movew", one(0030000), one(0170000), "ms%d", mcf5200 },
+{"movew", one(0030000), one(0170000), "nspd", mcf5200 },
+{"movew", one(0030000), one(0170000), "owmd", mcf5200 },
+{"movew", one(0040300), one(0177700), "Ss$s", m68000up },
+{"movew", one(0040300), one(0177770), "SsDs", mcf5200 },
+{"movew", one(0041300), one(0177700), "Cs$s", m68010up },
+{"movew", one(0041300), one(0177770), "CsDs", mcf5200 },
+{"movew", one(0042300), one(0177700), ";wCd", m68000up },
+{"movew", one(0042300), one(0177700), "DsCd", mcf5200 },
+{"movew", one(0042374), one(0177777), "#wCd", mcf5200 },
+{"movew", one(0043300), one(0177700), ";wSd", m68000up },
+{"movew", one(0043300), one(0177700), "DsSd", mcf5200 },
+{"movew", one(0043374), one(0177777), "#wSd", mcf5200 },
+
+{"movel", one(0070000), one(0170400), "MsDd", m68000up | mcf5200 },
+{"movel", one(0020000), one(0170000), "*l%d", m68000up },
+{"movel", one(0020000), one(0170000), "ms%d", mcf5200 },
+{"movel", one(0020000), one(0170000), "nspd", mcf5200 },
+{"movel", one(0020000), one(0170000), "olmd", mcf5200 },
+{"movel", one(0047140), one(0177770), "AsUd", m68000up },
+{"movel", one(0047150), one(0177770), "UdAs", m68000up },
+
+{"move", one(0030000), one(0170000), "*w%d", m68000up },
+{"move", one(0030000), one(0170000), "ms%d", mcf5200 },
+{"move", one(0030000), one(0170000), "nspd", mcf5200 },
+{"move", one(0030000), one(0170000), "owmd", mcf5200 },
+{"move", one(0040300), one(0177700), "Ss$s", m68000up },
+{"move", one(0040300), one(0177770), "SsDs", mcf5200 },
+{"move", one(0041300), one(0177700), "Cs$s", m68010up },
+{"move", one(0041300), one(0177770), "CsDs", mcf5200 },
+{"move", one(0042300), one(0177700), ";wCd", m68000up },
+{"move", one(0042300), one(0177700), "DsCd", mcf5200 },
+{"move", one(0042374), one(0177777), "#wCd", mcf5200 },
+{"move", one(0043300), one(0177700), ";wSd", m68000up },
+{"move", one(0043300), one(0177700), "DsSd", mcf5200 },
+{"move", one(0043374), one(0177777), "#wSd", mcf5200 },
+
+{"move", one(0047140), one(0177770), "AsUd", m68000up },
+{"move", one(0047150), one(0177770), "UdAs", m68000up },
+
+{"movesb", two(0007000, 0), two(0177700, 07777), "~sR1", m68010up },
+{"movesb", two(0007000, 04000), two(0177700, 07777), "R1~s", m68010up },
+{"movesw", two(0007100, 0), two(0177700, 07777), "~sR1", m68010up },
+{"movesw", two(0007100, 04000), two(0177700, 07777), "R1~s", m68010up },
+{"movesl", two(0007200, 0), two(0177700, 07777), "~sR1", m68010up },
+{"movesl", two(0007200, 04000), two(0177700, 07777), "R1~s", m68010up },
+
+{"move16", two(0xf620, 0x8000), two(0xfff8, 0x8fff), "+s+1", m68040up },
+{"move16", one(0xf600), one(0xfff8), "+s_L", m68040up },
+{"move16", one(0xf608), one(0xfff8), "_L+s", m68040up },
+{"move16", one(0xf610), one(0xfff8), "as_L", m68040up },
+{"move16", one(0xf618), one(0xfff8), "_Las", m68040up },
+
+{"mulsw", one(0140700), one(0170700), ";wDd", m68000up|mcf5200 },
+{"mulsl", two(0046000,004000), two(0177700,0107770), ";lD1", m68020up|cpu32 },
+{"mulsl", two(0046000,004000), two(0177700,0107770), "qsD1", mcf5200 },
+{"mulsl", two(0046000,006000), two(0177700,0107770), ";lD3D1",m68020up|cpu32 },
+
+{"muluw", one(0140300), one(0170700), ";wDd", m68000up|mcf5200 },
+{"mulul", two(0046000,000000), two(0177700,0107770), ";lD1", m68020up|cpu32 },
+{"mulul", two(0046000,000000), two(0177700,0107770), "qsD1", mcf5200 },
+{"mulul", two(0046000,002000), two(0177700,0107770), ";lD3D1",m68020up|cpu32 },
+
+{"nbcd", one(0044000), one(0177700), "$s", m68000up },
+
+{"negb", one(0042000), one(0177700), "$s", m68000up },
+{"negw", one(0042100), one(0177700), "$s", m68000up },
+{"negl", one(0042200), one(0177700), "$s", m68000up },
+{"negl", one(0042200), one(0177700), "Ds", mcf5200},
+
+{"negxb", one(0040000), one(0177700), "$s", m68000up },
+{"negxw", one(0040100), one(0177700), "$s", m68000up },
+{"negxl", one(0040200), one(0177700), "$s", m68000up },
+{"negxl", one(0040200), one(0177700), "Ds", mcf5200},
+
+{"nop", one(0047161), one(0177777), "", m68000up | mcf5200},
+
+{"notb", one(0043000), one(0177700), "$s", m68000up },
+{"notw", one(0043100), one(0177700), "$s", m68000up },
+{"notl", one(0043200), one(0177700), "$s", m68000up },
+{"notl", one(0043200), one(0177700), "Ds", mcf5200},
+
+{"orib", one(0000000), one(0177700), "#b$s", m68000up },
+{"orib", one(0000074), one(0177777), "#bCs", m68000up },
+{"oriw", one(0000100), one(0177700), "#w$s", m68000up },
+{"oriw", one(0000174), one(0177777), "#wSs", m68000up },
+{"oril", one(0000200), one(0177700), "#l$s", m68000up },
+{"oril", one(0000200), one(0177700), "#lDs", mcf5200 },
+{"ori", one(0000074), one(0177777), "#bCs", m68000up },
+{"ori", one(0000100), one(0177700), "#w$s", m68000up },
+{"ori", one(0000174), one(0177777), "#wSs", m68000up },
+
+/* The or opcode can generate the ori instruction. */
+{"orb", one(0000000), one(0177700), "#b$s", m68000up },
+{"orb", one(0000074), one(0177777), "#bCs", m68000up },
+{"orb", one(0100000), one(0170700), ";bDd", m68000up },
+{"orb", one(0100400), one(0170700), "Dd~s", m68000up },
+{"orw", one(0000100), one(0177700), "#w$s", m68000up },
+{"orw", one(0000174), one(0177777), "#wSs", m68000up },
+{"orw", one(0100100), one(0170700), ";wDd", m68000up },
+{"orw", one(0100500), one(0170700), "Dd~s", m68000up },
+{"orl", one(0000200), one(0177700), "#l$s", m68000up },
+{"orl", one(0000200), one(0177700), "#lDs", mcf5200 },
+{"orl", one(0100200), one(0170700), ";lDd", m68000up | mcf5200 },
+{"orl", one(0100600), one(0170700), "Dd~s", m68000up | mcf5200 },
+{"or", one(0000074), one(0177777), "#bCs", m68000up },
+{"or", one(0000100), one(0177700), "#w$s", m68000up },
+{"or", one(0000174), one(0177777), "#wSs", m68000up },
+{"or", one(0100100), one(0170700), ";wDd", m68000up },
+{"or", one(0100500), one(0170700), "Dd~s", m68000up },
+
+{"pack", one(0100500), one(0170770), "DsDd#w", m68020up },
+{"pack", one(0100510), one(0170770), "-s-d#w", m68020up },
+
+{"pbac", one(0xf087), one(0xffbf), "Bc", m68851 },
+{"pbacw", one(0xf087), one(0xffff), "BW", m68851 },
+{"pbas", one(0xf086), one(0xffbf), "Bc", m68851 },
+{"pbasw", one(0xf086), one(0xffff), "BW", m68851 },
+{"pbbc", one(0xf081), one(0xffbf), "Bc", m68851 },
+{"pbbcw", one(0xf081), one(0xffff), "BW", m68851 },
+{"pbbs", one(0xf080), one(0xffbf), "Bc", m68851 },
+{"pbbsw", one(0xf080), one(0xffff), "BW", m68851 },
+{"pbcc", one(0xf08f), one(0xffbf), "Bc", m68851 },
+{"pbccw", one(0xf08f), one(0xffff), "BW", m68851 },
+{"pbcs", one(0xf08e), one(0xffbf), "Bc", m68851 },
+{"pbcsw", one(0xf08e), one(0xffff), "BW", m68851 },
+{"pbgc", one(0xf08d), one(0xffbf), "Bc", m68851 },
+{"pbgcw", one(0xf08d), one(0xffff), "BW", m68851 },
+{"pbgs", one(0xf08c), one(0xffbf), "Bc", m68851 },
+{"pbgsw", one(0xf08c), one(0xffff), "BW", m68851 },
+{"pbic", one(0xf08b), one(0xffbf), "Bc", m68851 },
+{"pbicw", one(0xf08b), one(0xffff), "BW", m68851 },
+{"pbis", one(0xf08a), one(0xffbf), "Bc", m68851 },
+{"pbisw", one(0xf08a), one(0xffff), "BW", m68851 },
+{"pblc", one(0xf083), one(0xffbf), "Bc", m68851 },
+{"pblcw", one(0xf083), one(0xffff), "BW", m68851 },
+{"pbls", one(0xf082), one(0xffbf), "Bc", m68851 },
+{"pblsw", one(0xf082), one(0xffff), "BW", m68851 },
+{"pbsc", one(0xf085), one(0xffbf), "Bc", m68851 },
+{"pbscw", one(0xf085), one(0xffff), "BW", m68851 },
+{"pbss", one(0xf084), one(0xffbf), "Bc", m68851 },
+{"pbssw", one(0xf084), one(0xffff), "BW", m68851 },
+{"pbwc", one(0xf089), one(0xffbf), "Bc", m68851 },
+{"pbwcw", one(0xf089), one(0xffff), "BW", m68851 },
+{"pbws", one(0xf088), one(0xffbf), "Bc", m68851 },
+{"pbwsw", one(0xf088), one(0xffff), "BW", m68851 },
+
+{"pdbac", two(0xf048, 0x0007), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbas", two(0xf048, 0x0006), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbbc", two(0xf048, 0x0001), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbbs", two(0xf048, 0x0000), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbcc", two(0xf048, 0x000f), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbcs", two(0xf048, 0x000e), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbgc", two(0xf048, 0x000d), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbgs", two(0xf048, 0x000c), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbic", two(0xf048, 0x000b), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbis", two(0xf048, 0x000a), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdblc", two(0xf048, 0x0003), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbls", two(0xf048, 0x0002), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbsc", two(0xf048, 0x0005), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbss", two(0xf048, 0x0004), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbwc", two(0xf048, 0x0009), two(0xfff8, 0xffff), "DsBw", m68851 },
+{"pdbws", two(0xf048, 0x0008), two(0xfff8, 0xffff), "DsBw", m68851 },
+
+{"pea", one(0044100), one(0177700), "!s", m68000up|mcf5200 },
+
+{"pflusha", one(0xf518), one(0xfff8), "", m68040up },
+{"pflusha", two(0xf000,0x2400), two(0xffff,0xffff), "", m68030 | m68851 },
+
+{"pflush", two(0xf000,0x3010), two(0xffc0,0xfe10), "T3T9", m68030|m68851 },
+{"pflush", two(0xf000,0x3810), two(0xffc0,0xfe10), "T3T9&s", m68030|m68851 },
+{"pflush", two(0xf000,0x3008), two(0xffc0,0xfe18), "D3T9", m68030|m68851 },
+{"pflush", two(0xf000,0x3808), two(0xffc0,0xfe18), "D3T9&s", m68030|m68851 },
+{"pflush", two(0xf000,0x3000), two(0xffc0,0xfe1e), "f3T9", m68030|m68851 },
+{"pflush", two(0xf000,0x3800), two(0xffc0,0xfe1e), "f3T9&s", m68030|m68851 },
+{"pflush", one(0xf508), one(0xfff8), "as", m68040up },
+{"pflush", one(0xf508), one(0xfff8), "As", m68040up },
+
+{"pflushan", one(0xf510), one(0xfff8), "", m68040up },
+{"pflushn", one(0xf500), one(0xfff8), "as", m68040up },
+{"pflushn", one(0xf500), one(0xfff8), "As", m68040up },
+
+{"pflushr", two(0xf000, 0xa000), two(0xffc0, 0xffff), "|s", m68851 },
+
+{"pflushs", two(0xf000, 0x3410), two(0xfff8, 0xfe10), "T3T9", m68851 },
+{"pflushs", two(0xf000, 0x3c10), two(0xfff8, 0xfe10), "T3T9&s", m68851 },
+{"pflushs", two(0xf000, 0x3408), two(0xfff8, 0xfe18), "D3T9", m68851 },
+{"pflushs", two(0xf000, 0x3c08), two(0xfff8, 0xfe18), "D3T9&s", m68851 },
+{"pflushs", two(0xf000, 0x3400), two(0xfff8, 0xfe1e), "f3T9", m68851 },
+{"pflushs", two(0xf000, 0x3c00), two(0xfff8, 0xfe1e), "f3T9&s", m68851 },
+
+{"ploadr", two(0xf000,0x2210), two(0xffc0,0xfff0), "T3&s", m68030|m68851 },
+{"ploadr", two(0xf000,0x2208), two(0xffc0,0xfff8), "D3&s", m68030|m68851 },
+{"ploadr", two(0xf000,0x2200), two(0xffc0,0xfffe), "f3&s", m68030|m68851 },
+{"ploadw", two(0xf000,0x2010), two(0xffc0,0xfff0), "T3&s", m68030|m68851 },
+{"ploadw", two(0xf000,0x2008), two(0xffc0,0xfff8), "D3&s", m68030|m68851 },
+{"ploadw", two(0xf000,0x2000), two(0xffc0,0xfffe), "f3&s", m68030|m68851 },
+
+{"plpar", one(0xf5c8), one(0xfff8), "as", m68060 },
+{"plpaw", one(0xf588), one(0xfff8), "as", m68060 },
+
+{"pmove", two(0xf000,0x4000), two(0xffc0,0xffff), "*l08", m68030|m68851 },
+{"pmove", two(0xf000,0x5c00), two(0xffc0,0xffff), "*w18", m68851 },
+{"pmove", two(0xf000,0x4000), two(0xffc0,0xe3ff), "*b28", m68851 },
+{"pmove", two(0xf000,0x4200), two(0xffc0,0xffff), "08%s", m68030|m68851 },
+{"pmove", two(0xf000,0x5e00), two(0xffc0,0xffff), "18%s", m68851 },
+{"pmove", two(0xf000,0x4200), two(0xffc0,0xe3ff), "28%s", m68851 },
+{"pmove", two(0xf000,0x4000), two(0xffc0,0xe3ff), "|sW8", m68030|m68851 },
+{"pmove", two(0xf000,0x4200), two(0xffc0,0xe3ff), "W8~s", m68030|m68851 },
+{"pmove", two(0xf000,0x6200), two(0xffc0,0xe3e3), "*wX3", m68851 },
+{"pmove", two(0xf000,0x6000), two(0xffc0,0xe3e3), "X3%s", m68851 },
+{"pmove", two(0xf000,0x6000), two(0xffc0,0xffff), "*wY8", m68030|m68851 },
+{"pmove", two(0xf000,0x6200), two(0xffc0,0xffff), "Y8%s", m68030|m68851 },
+{"pmove", two(0xf000,0x6600), two(0xffc0,0xffff), "Z8%s", m68851 },
+{"pmove", two(0xf000,0x0800), two(0xffc0,0xfbff), "*l38", m68030 },
+{"pmove", two(0xf000,0x0a00), two(0xffc0,0xfbff), "38%s", m68030 },
+
+{"pmovefd", two(0xf000, 0x4100), two(0xffc0, 0xe3ff), "*l08", m68030 },
+{"pmovefd", two(0xf000, 0x4100), two(0xffc0, 0xe3ff), "|sW8", m68030 },
+{"pmovefd", two(0xf000, 0x0900), two(0xffc0, 0xfbff), "*l38", m68030 },
+
+{"prestore", one(0xf140), one(0xffc0), "<s", m68851 },
+
+{"psave", one(0xf100), one(0xffc0), ">s", m68851 },
+
+{"psac", two(0xf040, 0x0007), two(0xffc0, 0xffff), "$s", m68851 },
+{"psas", two(0xf040, 0x0006), two(0xffc0, 0xffff), "$s", m68851 },
+{"psbc", two(0xf040, 0x0001), two(0xffc0, 0xffff), "$s", m68851 },
+{"psbs", two(0xf040, 0x0000), two(0xffc0, 0xffff), "$s", m68851 },
+{"pscc", two(0xf040, 0x000f), two(0xffc0, 0xffff), "$s", m68851 },
+{"pscs", two(0xf040, 0x000e), two(0xffc0, 0xffff), "$s", m68851 },
+{"psgc", two(0xf040, 0x000d), two(0xffc0, 0xffff), "$s", m68851 },
+{"psgs", two(0xf040, 0x000c), two(0xffc0, 0xffff), "$s", m68851 },
+{"psic", two(0xf040, 0x000b), two(0xffc0, 0xffff), "$s", m68851 },
+{"psis", two(0xf040, 0x000a), two(0xffc0, 0xffff), "$s", m68851 },
+{"pslc", two(0xf040, 0x0003), two(0xffc0, 0xffff), "$s", m68851 },
+{"psls", two(0xf040, 0x0002), two(0xffc0, 0xffff), "$s", m68851 },
+{"pssc", two(0xf040, 0x0005), two(0xffc0, 0xffff), "$s", m68851 },
+{"psss", two(0xf040, 0x0004), two(0xffc0, 0xffff), "$s", m68851 },
+{"pswc", two(0xf040, 0x0009), two(0xffc0, 0xffff), "$s", m68851 },
+{"psws", two(0xf040, 0x0008), two(0xffc0, 0xffff), "$s", m68851 },
+
+{"ptestr", two(0xf000,0x8210), two(0xffc0, 0xe3f0), "T3&st8", m68030|m68851 },
+{"ptestr", two(0xf000,0x8310), two(0xffc0,0xe310), "T3&st8A9", m68030|m68851 },
+{"ptestr", two(0xf000,0x8208), two(0xffc0,0xe3f8), "D3&st8", m68030|m68851 },
+{"ptestr", two(0xf000,0x8308), two(0xffc0,0xe318), "D3&st8A9", m68030|m68851 },
+{"ptestr", two(0xf000,0x8200), two(0xffc0,0xe3fe), "f3&st8", m68030|m68851 },
+{"ptestr", two(0xf000,0x8300), two(0xffc0,0xe31e), "f3&st8A9", m68030|m68851 },
+{"ptestr", one(0xf568), one(0xfff8), "as", m68040 },
+
+{"ptestw", two(0xf000,0x8010), two(0xffc0,0xe3f0), "T3&st8", m68030|m68851 },
+{"ptestw", two(0xf000,0x8110), two(0xffc0,0xe310), "T3&st8A9", m68030|m68851 },
+{"ptestw", two(0xf000,0x8008), two(0xffc0,0xe3f8), "D3&st8", m68030|m68851 },
+{"ptestw", two(0xf000,0x8108), two(0xffc0,0xe318), "D3&st8A9", m68030|m68851 },
+{"ptestw", two(0xf000,0x8000), two(0xffc0,0xe3fe), "f3&st8", m68030|m68851 },
+{"ptestw", two(0xf000,0x8100), two(0xffc0,0xe31e), "f3&st8A9", m68030|m68851 },
+{"ptestw", one(0xf548), one(0xfff8), "as", m68040 },
+
+{"ptrapacw", two(0xf07a, 0x0007), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapacl", two(0xf07b, 0x0007), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapac", two(0xf07c, 0x0007), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapasw", two(0xf07a, 0x0006), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapasl", two(0xf07b, 0x0006), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapas", two(0xf07c, 0x0006), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapbcw", two(0xf07a, 0x0001), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapbcl", two(0xf07b, 0x0001), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapbc", two(0xf07c, 0x0001), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapbsw", two(0xf07a, 0x0000), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapbsl", two(0xf07b, 0x0000), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapbs", two(0xf07c, 0x0000), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapccw", two(0xf07a, 0x000f), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapccl", two(0xf07b, 0x000f), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapcc", two(0xf07c, 0x000f), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapcsw", two(0xf07a, 0x000e), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapcsl", two(0xf07b, 0x000e), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapcs", two(0xf07c, 0x000e), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapgcw", two(0xf07a, 0x000d), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapgcl", two(0xf07b, 0x000d), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapgc", two(0xf07c, 0x000d), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapgsw", two(0xf07a, 0x000c), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapgsl", two(0xf07b, 0x000c), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapgs", two(0xf07c, 0x000c), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapicw", two(0xf07a, 0x000b), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapicl", two(0xf07b, 0x000b), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapic", two(0xf07c, 0x000b), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapisw", two(0xf07a, 0x000a), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapisl", two(0xf07b, 0x000a), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapis", two(0xf07c, 0x000a), two(0xffff, 0xffff), "", m68851 },
+
+{"ptraplcw", two(0xf07a, 0x0003), two(0xffff, 0xffff), "#w", m68851 },
+{"ptraplcl", two(0xf07b, 0x0003), two(0xffff, 0xffff), "#l", m68851 },
+{"ptraplc", two(0xf07c, 0x0003), two(0xffff, 0xffff), "", m68851 },
+
+{"ptraplsw", two(0xf07a, 0x0002), two(0xffff, 0xffff), "#w", m68851 },
+{"ptraplsl", two(0xf07b, 0x0002), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapls", two(0xf07c, 0x0002), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapscw", two(0xf07a, 0x0005), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapscl", two(0xf07b, 0x0005), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapsc", two(0xf07c, 0x0005), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapssw", two(0xf07a, 0x0004), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapssl", two(0xf07b, 0x0004), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapss", two(0xf07c, 0x0004), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapwcw", two(0xf07a, 0x0009), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapwcl", two(0xf07b, 0x0009), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapwc", two(0xf07c, 0x0009), two(0xffff, 0xffff), "", m68851 },
+
+{"ptrapwsw", two(0xf07a, 0x0008), two(0xffff, 0xffff), "#w", m68851 },
+{"ptrapwsl", two(0xf07b, 0x0008), two(0xffff, 0xffff), "#l", m68851 },
+{"ptrapws", two(0xf07c, 0x0008), two(0xffff, 0xffff), "", m68851 },
+
+{"pulse", one(0045314), one(0177777), "", m68060 | mcf5200 },
+
+{"pvalid", two(0xf000, 0x2800), two(0xffc0, 0xffff), "Vs&s", m68851 },
+{"pvalid", two(0xf000, 0x2c00), two(0xffc0, 0xfff8), "A3&s", m68851 },
+
+
+{"reset", one(0047160), one(0177777), "", m68000up },
+
+{"rolb", one(0160430), one(0170770), "QdDs", m68000up },
+{"rolb", one(0160470), one(0170770), "DdDs", m68000up },
+{"rolw", one(0160530), one(0170770), "QdDs", m68000up },
+{"rolw", one(0160570), one(0170770), "DdDs", m68000up },
+{"rolw", one(0163700), one(0177700), "~s", m68000up },
+{"roll", one(0160630), one(0170770), "QdDs", m68000up },
+{"roll", one(0160670), one(0170770), "DdDs", m68000up },
+
+{"rorb", one(0160030), one(0170770), "QdDs", m68000up },
+{"rorb", one(0160070), one(0170770), "DdDs", m68000up },
+{"rorw", one(0160130), one(0170770), "QdDs", m68000up },
+{"rorw", one(0160170), one(0170770), "DdDs", m68000up },
+{"rorw", one(0163300), one(0177700), "~s", m68000up },
+{"rorl", one(0160230), one(0170770), "QdDs", m68000up },
+{"rorl", one(0160270), one(0170770), "DdDs", m68000up },
+
+{"roxlb", one(0160420), one(0170770), "QdDs", m68000up },
+{"roxlb", one(0160460), one(0170770), "DdDs", m68000up },
+{"roxlw", one(0160520), one(0170770), "QdDs", m68000up },
+{"roxlw", one(0160560), one(0170770), "DdDs", m68000up },
+{"roxlw", one(0162700), one(0177700), "~s", m68000up },
+{"roxll", one(0160620), one(0170770), "QdDs", m68000up },
+{"roxll", one(0160660), one(0170770), "DdDs", m68000up },
+
+{"roxrb", one(0160020), one(0170770), "QdDs", m68000up },
+{"roxrb", one(0160060), one(0170770), "DdDs", m68000up },
+{"roxrw", one(0160120), one(0170770), "QdDs", m68000up },
+{"roxrw", one(0160160), one(0170770), "DdDs", m68000up },
+{"roxrw", one(0162300), one(0177700), "~s", m68000up },
+{"roxrl", one(0160220), one(0170770), "QdDs", m68000up },
+{"roxrl", one(0160260), one(0170770), "DdDs", m68000up },
+
+{"rtd", one(0047164), one(0177777), "#w", m68010up },
+
+{"rte", one(0047163), one(0177777), "", m68000up|mcf5200 },
+
+{"rtm", one(0003300), one(0177760), "Rs", m68020 },
+
+{"rtr", one(0047167), one(0177777), "", m68000up },
+
+{"rts", one(0047165), one(0177777), "", m68000up|mcf5200 },
+
+{"sbcd", one(0100400), one(0170770), "DsDd", m68000up },
+{"sbcd", one(0100410), one(0170770), "-s-d", m68000up },
+
+
+{"scc", one(0052300), one(0177700), "$s", m68000up },
+{"scc", one(0052300), one(0177700), "Ds", mcf5200 },
+{"scs", one(0052700), one(0177700), "$s", m68000up },
+{"scs", one(0052700), one(0177700), "Ds", mcf5200 },
+{"seq", one(0053700), one(0177700), "$s", m68000up },
+{"seq", one(0053700), one(0177700), "Ds", mcf5200 },
+{"sf", one(0050700), one(0177700), "$s", m68000up },
+{"sf", one(0050700), one(0177700), "Ds", mcf5200 },
+{"sge", one(0056300), one(0177700), "$s", m68000up },
+{"sge", one(0056300), one(0177700), "Ds", mcf5200 },
+{"sgt", one(0057300), one(0177700), "$s", m68000up },
+{"sgt", one(0057300), one(0177700), "Ds", mcf5200 },
+{"shi", one(0051300), one(0177700), "$s", m68000up },
+{"shi", one(0051300), one(0177700), "Ds", mcf5200 },
+{"sle", one(0057700), one(0177700), "$s", m68000up },
+{"sle", one(0057700), one(0177700), "Ds", mcf5200 },
+{"sls", one(0051700), one(0177700), "$s", m68000up },
+{"sls", one(0051700), one(0177700), "Ds", mcf5200 },
+{"slt", one(0056700), one(0177700), "$s", m68000up },
+{"slt", one(0056700), one(0177700), "Ds", mcf5200 },
+{"smi", one(0055700), one(0177700), "$s", m68000up },
+{"smi", one(0055700), one(0177700), "Ds", mcf5200 },
+{"sne", one(0053300), one(0177700), "$s", m68000up },
+{"sne", one(0053300), one(0177700), "Ds", mcf5200 },
+{"spl", one(0055300), one(0177700), "$s", m68000up },
+{"spl", one(0055300), one(0177700), "Ds", mcf5200 },
+{"st", one(0050300), one(0177700), "$s", m68000up },
+{"st", one(0050300), one(0177700), "Ds", mcf5200 },
+{"svc", one(0054300), one(0177700), "$s", m68000up },
+{"svc", one(0054300), one(0177700), "Ds", mcf5200 },
+{"svs", one(0054700), one(0177700), "$s", m68000up },
+{"svs", one(0054700), one(0177700), "Ds", mcf5200 },
+
+{"stop", one(0047162), one(0177777), "#w", m68000up | mcf5200 },
+
+{"subal", one(0110700), one(0170700), "*lAd", m68000up | mcf5200 },
+{"subaw", one(0110300), one(0170700), "*wAd", m68000up },
+
+{"subib", one(0002000), one(0177700), "#b$s", m68000up },
+{"subiw", one(0002100), one(0177700), "#w$s", m68000up },
+{"subil", one(0002200), one(0177700), "#l$s", m68000up },
+{"subil", one(0002200), one(0177700), "#lDs", mcf5200 },
+
+{"subqb", one(0050400), one(0170700), "Qd%s", m68000up },
+{"subqw", one(0050500), one(0170700), "Qd%s", m68000up },
+{"subql", one(0050600), one(0170700), "Qd%s", m68000up | mcf5200 },
+
+/* The sub opcode can generate the suba, subi, and subq instructions. */
+{"subb", one(0050400), one(0170700), "Qd%s", m68000up },
+{"subb", one(0002000), one(0177700), "#b$s", m68000up },
+{"subb", one(0110000), one(0170700), ";bDd", m68000up },
+{"subb", one(0110400), one(0170700), "Dd~s", m68000up },
+{"subw", one(0050500), one(0170700), "Qd%s", m68000up },
+{"subw", one(0002100), one(0177700), "#w$s", m68000up },
+{"subw", one(0110300), one(0170700), "*wAd", m68000up },
+{"subw", one(0110100), one(0170700), "*wDd", m68000up },
+{"subw", one(0110500), one(0170700), "Dd~s", m68000up },
+{"subl", one(0050600), one(0170700), "Qd%s", m68000up | mcf5200 },
+{"subl", one(0002200), one(0177700), "#l$s", m68000up },
+{"subl", one(0002200), one(0177700), "#lDs", mcf5200 },
+{"subl", one(0110700), one(0170700), "*lAd", m68000up | mcf5200 },
+{"subl", one(0110200), one(0170700), "*lDd", m68000up | mcf5200 },
+{"subl", one(0110600), one(0170700), "Dd~s", m68000up | mcf5200 },
+
+{"subxb", one(0110400), one(0170770), "DsDd", m68000up },
+{"subxb", one(0110410), one(0170770), "-s-d", m68000up },
+{"subxw", one(0110500), one(0170770), "DsDd", m68000up },
+{"subxw", one(0110510), one(0170770), "-s-d", m68000up },
+{"subxl", one(0110600), one(0170770), "DsDd", m68000up | mcf5200 },
+{"subxl", one(0110610), one(0170770), "-s-d", m68000up },
+
+{"swap", one(0044100), one(0177770), "Ds", m68000up | mcf5200 },
+
+/* swbeg and swbegl are magic constants used on sysV68. The compiler
+ generates them before a switch table. They tell the debugger and
+ disassembler that a switch table follows. The parameter is the
+ number of elements in the table. swbeg means that the entries in
+ the table are word (2 byte) sized, and swbegl means that the
+ entries in the table are longword (4 byte) sized. */
+{"swbeg", one(0045374), one(0177777), "#w", m68000up | mcf5200 },
+{"swbegl", one(0045375), one(0177777), "#l", m68000up | mcf5200 },
+
+{"tas", one(0045300), one(0177700), "$s", m68000up },
+
+#define TBL1(name,signed,round,size) \
+ {name, two(0174000, (signed<<11)|(!round<<10)|(size<<6)|0000400), \
+ two(0177700,0107777), "!sD1", cpu32 }, \
+ {name, two(0174000, (signed<<11)|(!round<<10)|(size<<6)), \
+ two(0177770,0107770), "DsD3D1", cpu32 }
+#define TBL(name1, name2, name3, s, r) \
+ TBL1(name1, s, r, 0), TBL1(name2, s, r, 1), TBL1(name3, s, r, 2)
+TBL("tblsb", "tblsw", "tblsl", 1, 1),
+TBL("tblsnb", "tblsnw", "tblsnl", 1, 0),
+TBL("tblub", "tbluw", "tblul", 0, 1),
+TBL("tblunb", "tblunw", "tblunl", 0, 0),
+
+{"trap", one(0047100), one(0177760), "Ts", m68000up | mcf5200 },
+
+{"trapcc", one(0052374), one(0177777), "", m68020up | cpu32 },
+{"trapcs", one(0052774), one(0177777), "", m68020up | cpu32 },
+{"trapeq", one(0053774), one(0177777), "", m68020up | cpu32 },
+{"trapf", one(0050774), one(0177777), "", m68020up | cpu32 | mcf5200 },
+{"trapge", one(0056374), one(0177777), "", m68020up | cpu32 },
+{"trapgt", one(0057374), one(0177777), "", m68020up | cpu32 },
+{"traphi", one(0051374), one(0177777), "", m68020up | cpu32 },
+{"traple", one(0057774), one(0177777), "", m68020up | cpu32 },
+{"trapls", one(0051774), one(0177777), "", m68020up | cpu32 },
+{"traplt", one(0056774), one(0177777), "", m68020up | cpu32 },
+{"trapmi", one(0055774), one(0177777), "", m68020up | cpu32 },
+{"trapne", one(0053374), one(0177777), "", m68020up | cpu32 },
+{"trappl", one(0055374), one(0177777), "", m68020up | cpu32 },
+{"trapt", one(0050374), one(0177777), "", m68020up | cpu32 },
+{"trapvc", one(0054374), one(0177777), "", m68020up | cpu32 },
+{"trapvs", one(0054774), one(0177777), "", m68020up | cpu32 },
+
+{"trapccw", one(0052372), one(0177777), "#w", m68020up|cpu32 },
+{"trapcsw", one(0052772), one(0177777), "#w", m68020up|cpu32 },
+{"trapeqw", one(0053772), one(0177777), "#w", m68020up|cpu32 },
+{"trapfw", one(0050772), one(0177777), "#w", m68020up|cpu32|mcf5200},
+{"trapgew", one(0056372), one(0177777), "#w", m68020up|cpu32 },
+{"trapgtw", one(0057372), one(0177777), "#w", m68020up|cpu32 },
+{"traphiw", one(0051372), one(0177777), "#w", m68020up|cpu32 },
+{"traplew", one(0057772), one(0177777), "#w", m68020up|cpu32 },
+{"traplsw", one(0051772), one(0177777), "#w", m68020up|cpu32 },
+{"trapltw", one(0056772), one(0177777), "#w", m68020up|cpu32 },
+{"trapmiw", one(0055772), one(0177777), "#w", m68020up|cpu32 },
+{"trapnew", one(0053372), one(0177777), "#w", m68020up|cpu32 },
+{"trapplw", one(0055372), one(0177777), "#w", m68020up|cpu32 },
+{"traptw", one(0050372), one(0177777), "#w", m68020up|cpu32 },
+{"trapvcw", one(0054372), one(0177777), "#w", m68020up|cpu32 },
+{"trapvsw", one(0054772), one(0177777), "#w", m68020up|cpu32 },
+
+{"trapccl", one(0052373), one(0177777), "#l", m68020up|cpu32 },
+{"trapcsl", one(0052773), one(0177777), "#l", m68020up|cpu32 },
+{"trapeql", one(0053773), one(0177777), "#l", m68020up|cpu32 },
+{"trapfl", one(0050773), one(0177777), "#l", m68020up|cpu32|mcf5200},
+{"trapgel", one(0056373), one(0177777), "#l", m68020up|cpu32 },
+{"trapgtl", one(0057373), one(0177777), "#l", m68020up|cpu32 },
+{"traphil", one(0051373), one(0177777), "#l", m68020up|cpu32 },
+{"traplel", one(0057773), one(0177777), "#l", m68020up|cpu32 },
+{"traplsl", one(0051773), one(0177777), "#l", m68020up|cpu32 },
+{"trapltl", one(0056773), one(0177777), "#l", m68020up|cpu32 },
+{"trapmil", one(0055773), one(0177777), "#l", m68020up|cpu32 },
+{"trapnel", one(0053373), one(0177777), "#l", m68020up|cpu32 },
+{"trappll", one(0055373), one(0177777), "#l", m68020up|cpu32 },
+{"traptl", one(0050373), one(0177777), "#l", m68020up|cpu32 },
+{"trapvcl", one(0054373), one(0177777), "#l", m68020up|cpu32 },
+{"trapvsl", one(0054773), one(0177777), "#l", m68020up|cpu32 },
+
+{"trapv", one(0047166), one(0177777), "", m68000up },
+
+{"tstb", one(0045000), one(0177700), ";b", m68020up|cpu32|mcf5200 },
+{"tstb", one(0045000), one(0177700), "$b", m68000up },
+{"tstw", one(0045100), one(0177700), "*w", m68020up|cpu32|mcf5200 },
+{"tstw", one(0045100), one(0177700), "$w", m68000up },
+{"tstl", one(0045200), one(0177700), "*l", m68020up|cpu32|mcf5200 },
+{"tstl", one(0045200), one(0177700), "$l", m68000up },
+
+{"unlk", one(0047130), one(0177770), "As", m68000up | mcf5200 },
+
+{"unpk", one(0100600), one(0170770), "DsDd#w", m68020up },
+{"unpk", one(0100610), one(0170770), "-s-d#w", m68020up },
+
+{"wddatab", one(0172000), one(0177700), "~s", mcf5200 },
+{"wddataw", one(0172100), one(0177700), "~s", mcf5200 },
+{"wddatal", one(0172200), one(0177700), "~s", mcf5200 },
+
+};
+
+const int m68k_numopcodes = sizeof m68k_opcodes / sizeof m68k_opcodes[0];
+
+/* These aliases used to be in the above table, each one duplicating
+ all of the entries for its primary exactly. This table was
+ constructed by mechanical processing of the opcode table, with a
+ small number of tweaks done by hand. There are probably a lot more
+ aliases above that could be moved down here, except for very minor
+ differences. */
+
+const struct m68k_opcode_alias m68k_opcode_aliases[] =
+{
+ { "add", "addw", },
+ { "adda", "addaw", },
+ { "addi", "addiw", },
+ { "addq", "addqw", },
+ { "addx", "addxw", },
+ { "asl", "aslw", },
+ { "asr", "asrw", },
+ { "bhi", "bhiw", },
+ { "bls", "blsw", },
+ { "bcc", "bccw", },
+ { "bcs", "bcsw", },
+ { "bne", "bnew", },
+ { "beq", "beqw", },
+ { "bvc", "bvcw", },
+ { "bvs", "bvsw", },
+ { "bpl", "bplw", },
+ { "bmi", "bmiw", },
+ { "bge", "bgew", },
+ { "blt", "bltw", },
+ { "bgt", "bgtw", },
+ { "ble", "blew", },
+ { "bra", "braw", },
+ { "bsr", "bsrw", },
+ { "bhib", "bhis", },
+ { "blsb", "blss", },
+ { "bccb", "bccs", },
+ { "bcsb", "bcss", },
+ { "bneb", "bnes", },
+ { "beqb", "beqs", },
+ { "bvcb", "bvcs", },
+ { "bvsb", "bvss", },
+ { "bplb", "bpls", },
+ { "bmib", "bmis", },
+ { "bgeb", "bges", },
+ { "bltb", "blts", },
+ { "bgtb", "bgts", },
+ { "bleb", "bles", },
+ { "brab", "bras", },
+ { "bsrb", "bsrs", },
+ { "bhs", "bccw" },
+ { "bhss", "bccs" },
+ { "bhsb", "bccs" },
+ { "bhsw", "bccw" },
+ { "bhsl", "bccl" },
+ { "blo", "bcsw" },
+ { "blos", "bcss" },
+ { "blob", "bcss" },
+ { "blow", "bcsw" },
+ { "blol", "bcsl" },
+ { "br", "braw", },
+ { "brs", "bras", },
+ { "brb", "bras", },
+ { "brw", "braw", },
+ { "brl", "bral", },
+ { "jfnlt", "bcc", }, /* apparently a sun alias */
+ { "jfngt", "ble", }, /* apparently a sun alias */
+ { "jfeq", "beqs", }, /* apparently a sun alias */
+ { "bchgb", "bchg", },
+ { "bchgl", "bchg", },
+ { "bclrb", "bclr", },
+ { "bclrl", "bclr", },
+ { "bsetb", "bset", },
+ { "bsetl", "bset", },
+ { "btstb", "btst", },
+ { "btstl", "btst", },
+ { "cas2", "cas2w", },
+ { "cas", "casw", },
+ { "chk2", "chk2w", },
+ { "chk", "chkw", },
+ { "clr", "clrw", },
+ { "cmp2", "cmp2w", },
+ { "cmpa", "cmpaw", },
+ { "cmpi", "cmpiw", },
+ { "cmpm", "cmpmw", },
+ { "cmp", "cmpw", },
+ { "dbccw", "dbcc", },
+ { "dbcsw", "dbcs", },
+ { "dbeqw", "dbeq", },
+ { "dbfw", "dbf", },
+ { "dbgew", "dbge", },
+ { "dbgtw", "dbgt", },
+ { "dbhiw", "dbhi", },
+ { "dblew", "dble", },
+ { "dblsw", "dbls", },
+ { "dbltw", "dblt", },
+ { "dbmiw", "dbmi", },
+ { "dbnew", "dbne", },
+ { "dbplw", "dbpl", },
+ { "dbtw", "dbt", },
+ { "dbvcw", "dbvc", },
+ { "dbvsw", "dbvs", },
+ { "dbhs", "dbcc", },
+ { "dbhsw", "dbcc", },
+ { "dbra", "dbf", },
+ { "dbraw", "dbf", },
+ { "tdivsl", "divsl", },
+ { "divs", "divsw", },
+ { "divu", "divuw", },
+ { "ext", "extw", },
+ { "extbw", "extw", },
+ { "extwl", "extl", },
+ { "fbneq", "fbne", },
+ { "fbsneq", "fbsne", },
+ { "fdbneq", "fdbne", },
+ { "fdbsneq", "fdbsne", },
+ { "fmovecr", "fmovecrx", },
+ { "fmovm", "fmovem", },
+ { "fsneq", "fsne", },
+ { "fssneq", "fssne", },
+ { "ftrapneq", "ftrapne", },
+ { "ftrapsneq", "ftrapsne", },
+ { "fjneq", "fjne", },
+ { "fjsneq", "fjsne", },
+ { "jmpl", "jmp", },
+ { "jmps", "jmp", },
+ { "jsrl", "jsr", },
+ { "jsrs", "jsr", },
+ { "leal", "lea", },
+ { "lsl", "lslw", },
+ { "lsr", "lsrw", },
+ { "movea", "moveaw", },
+ { "movem", "movemw", },
+ { "movml", "moveml", },
+ { "movmw", "movemw", },
+ { "movm", "movemw", },
+ { "movep", "movepw", },
+ { "movpw", "movepw", },
+ { "moves", "movesw" },
+ { "muls", "mulsw", },
+ { "mulu", "muluw", },
+ { "nbcdb", "nbcd" },
+ { "neg", "negw", },
+ { "negx", "negxw", },
+ { "not", "notw", },
+ { "peal", "pea", },
+ { "rol", "rolw", },
+ { "ror", "rorw", },
+ { "roxl", "roxlw", },
+ { "roxr", "roxrw", },
+ { "sbcdb", "sbcd", },
+ { "sccb", "scc", },
+ { "scsb", "scs", },
+ { "seqb", "seq", },
+ { "sfb", "sf", },
+ { "sgeb", "sge", },
+ { "sgtb", "sgt", },
+ { "shib", "shi", },
+ { "sleb", "sle", },
+ { "slsb", "sls", },
+ { "sltb", "slt", },
+ { "smib", "smi", },
+ { "sneb", "sne", },
+ { "splb", "spl", },
+ { "stb", "st", },
+ { "svcb", "svc", },
+ { "svsb", "svs", },
+ { "sfge", "sge", },
+ { "sfgt", "sgt", },
+ { "sfle", "sle", },
+ { "sflt", "slt", },
+ { "sfneq", "sne", },
+ { "suba", "subaw", },
+ { "subi", "subiw", },
+ { "subq", "subqw", },
+ { "sub", "subw", },
+ { "subx", "subxw", },
+ { "swapw", "swap", },
+ { "tasb", "tas", },
+ { "tpcc", "trapcc", },
+ { "tcc", "trapcc", },
+ { "tst", "tstw", },
+ { "jbra", "jra", },
+ { "jbhi", "jhi", },
+ { "jbls", "jls", },
+ { "jbcc", "jcc", },
+ { "jbcs", "jcs", },
+ { "jbne", "jne", },
+ { "jbeq", "jeq", },
+ { "jbvc", "jvc", },
+ { "jbvs", "jvs", },
+ { "jbpl", "jpl", },
+ { "jbmi", "jmi", },
+ { "jbge", "jge", },
+ { "jblt", "jlt", },
+ { "jbgt", "jgt", },
+ { "jble", "jle", },
+ { "movql", "moveq", },
+ { "moveql", "moveq", },
+ { "movl", "movel", },
+ { "movq", "moveq", },
+ { "moval", "moveal", },
+ { "movaw", "moveaw", },
+ { "movb", "moveb", },
+ { "movc", "movec", },
+ { "movecl", "movec", },
+ { "movpl", "movepl", },
+ { "movw", "movew", },
+ { "movsb", "movesb", },
+ { "movsl", "movesl", },
+ { "movsw", "movesw", },
+
+ { "tdivul", "divul", }, /* for m68k-svr4 */
+ { "fmovb", "fmoveb", },
+ { "fsmovb", "fsmoveb", },
+ { "fdmovb", "fdmoveb", },
+ { "fmovd", "fmoved", },
+ { "fsmovd", "fsmoved", },
+ { "fmovl", "fmovel", },
+ { "fsmovl", "fsmovel", },
+ { "fdmovl", "fdmovel", },
+ { "fmovp", "fmovep", },
+ { "fsmovp", "fsmovep", },
+ { "fdmovp", "fdmovep", },
+ { "fmovs", "fmoves", },
+ { "fsmovs", "fsmoves", },
+ { "fdmovs", "fdmoves", },
+ { "fmovw", "fmovew", },
+ { "fsmovw", "fsmovew", },
+ { "fdmovw", "fdmovew", },
+ { "fmovx", "fmovex", },
+ { "fsmovx", "fsmovex", },
+ { "fdmovx", "fdmovex", },
+ { "fmovcr", "fmovecr", },
+ { "fmovcrx", "fmovecrx", },
+ { "ftestb", "ftstb", },
+ { "ftestd", "ftstd", },
+ { "ftestl", "ftstl", },
+ { "ftestp", "ftstp", },
+ { "ftests", "ftsts", },
+ { "ftestw", "ftstw", },
+ { "ftestx", "ftstx", },
+};
+
+const int m68k_numaliases =
+ sizeof m68k_opcode_aliases / sizeof m68k_opcode_aliases[0];
diff --git a/opcodes/m88k-dis.c b/opcodes/m88k-dis.c
new file mode 100644
index 00000000000..8af6b87929b
--- /dev/null
+++ b/opcodes/m88k-dis.c
@@ -0,0 +1,330 @@
+/* Print instructions for the Motorola 88000, for GDB and GNU Binutils.
+ Copyright (c) 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1998
+ Free Software Foundation, Inc.
+ Contributed by Data General Corporation, November 1989.
+ Partially derived from an earlier printcmd.c.
+
+This file is part of GDB and the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "dis-asm.h"
+#include "opcode/m88k.h"
+#include "opintl.h"
+
+INSTAB *hashtable[HASHVAL] = {0};
+
+static int
+m88kdis PARAMS ((bfd_vma, unsigned long, struct disassemble_info *));
+
+static void
+printop PARAMS ((struct disassemble_info *, OPSPEC *,
+ unsigned long, bfd_vma, int));
+
+static void
+init_disasm PARAMS ((void));
+
+static void
+install PARAMS ((INSTAB *instptr));
+
+/*
+* Disassemble an M88000 Instruction
+*
+*
+* This module decodes the instruction at memaddr.
+*
+* Revision History
+*
+* Revision 1.0 11/08/85 Creation date by Motorola
+* 05/11/89 R. Trawick adapted to GDB interface.
+* 07/12/93 Ian Lance Taylor updated to
+* binutils interface.
+*/
+
+int
+print_insn_m88k (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ bfd_byte buffer[4];
+ int status;
+
+ /* Instruction addresses may have low two bits set. Clear them. */
+ memaddr &=~ (bfd_vma) 3;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ return m88kdis (memaddr, bfd_getb32 (buffer), info);
+}
+
+/*
+ * disassemble the instruction in 'instruction'.
+ * 'pc' should be the address of this instruction, it will
+ * be used to print the target address if this is a relative jump or call
+ * the disassembled instruction is written to 'info'.
+ * The function returns the length of this instruction in bytes.
+ */
+
+static int
+m88kdis (pc, instruction, info)
+ bfd_vma pc;
+ unsigned long instruction;
+ struct disassemble_info *info;
+{
+ static int ihashtab_initialized = 0;
+ unsigned int opcode;
+ INSTAB *entry_ptr;
+ int opmask;
+ unsigned int class;
+
+ if (! ihashtab_initialized)
+ init_disasm ();
+
+ /* create the appropriate mask to isolate the opcode */
+ opmask = DEFMASK;
+ class = instruction & DEFMASK;
+ if ((class >= SFU0) && (class <= SFU7))
+ {
+ if (instruction < SFU1)
+ opmask = CTRLMASK;
+ else
+ opmask = SFUMASK;
+ }
+ else if (class == RRR)
+ opmask = RRRMASK;
+ else if (class == RRI10)
+ opmask = RRI10MASK;
+
+ /* isolate the opcode */
+ opcode = instruction & opmask;
+
+ /* search the hash table with the isolated opcode */
+ for (entry_ptr = hashtable[opcode % HASHVAL];
+ (entry_ptr != NULL) && (entry_ptr->opcode != opcode);
+ entry_ptr = entry_ptr->next)
+ ;
+
+ if (entry_ptr == NULL)
+ (*info->fprintf_func) (info->stream, "word\t%08x", instruction);
+ else
+ {
+ (*info->fprintf_func) (info->stream, "%s", entry_ptr->mnemonic);
+ printop (info, &(entry_ptr->op1), instruction, pc, 1);
+ printop (info, &(entry_ptr->op2), instruction, pc, 0);
+ printop (info, &(entry_ptr->op3), instruction, pc, 0);
+ }
+
+ return 4;
+}
+
+/*
+* Decode an Operand of an Instruction
+*
+* Functional Description
+*
+* This module formats and writes an operand of an instruction to info
+* based on the operand specification. When the first flag is set this
+* is the first operand of an instruction. Undefined operand types
+* cause a <dis error> message.
+*
+* Parameters
+* disassemble_info where the operand may be printed
+* OPSPEC *opptr Pointer to an operand specification
+* UINT inst Instruction from which operand is extracted
+* UINT pc PC of instruction; used for pc-relative disp.
+* int first Flag which if nonzero indicates the first
+* operand of an instruction
+*
+* Output
+*
+* The operand specified is extracted from the instruction and is
+* written to buf in the format specified. The operand is preceded
+* by a comma if it is not the first operand of an instruction and it
+* is not a register indirect form. Registers are preceded by 'r' and
+* hex values by '0x'.
+*
+* Revision History
+*
+* Revision 1.0 11/08/85 Creation date
+*/
+
+static void
+printop (info, opptr, inst, pc, first)
+ struct disassemble_info *info;
+ OPSPEC *opptr;
+ unsigned long inst;
+ bfd_vma pc;
+ int first;
+{
+ int extracted_field;
+ char *cond_mask_sym;
+
+ if (opptr->width == 0)
+ return;
+
+ if (! first)
+ {
+ switch (opptr->type)
+ {
+ case REGSC:
+ case CONT:
+ break;
+ default:
+ (*info->fprintf_func) (info->stream, ",");
+ break;
+ }
+ }
+
+ switch (opptr->type)
+ {
+ case CRREG:
+ (*info->fprintf_func) (info->stream, "cr%d",
+ UEXT (inst, opptr->offset, opptr->width));
+ break;
+
+ case FCRREG:
+ (*info->fprintf_func) (info->stream, "fcr%d",
+ UEXT (inst, opptr->offset, opptr->width));
+ break;
+
+ case REGSC:
+ (*info->fprintf_func) (info->stream, "[r%d]",
+ UEXT (inst, opptr->offset, opptr->width));
+ break;
+
+ case REG:
+ (*info->fprintf_func) (info->stream, "r%d",
+ UEXT (inst, opptr->offset, opptr->width));
+ break;
+
+ case XREG:
+ (*info->fprintf_func) (info->stream, "x%d",
+ UEXT (inst, opptr->offset, opptr->width));
+ break;
+
+ case HEX:
+ extracted_field = UEXT (inst, opptr->offset, opptr->width);
+ if (extracted_field == 0)
+ (*info->fprintf_func) (info->stream, "0");
+ else
+ (*info->fprintf_func) (info->stream, "0x%02x", extracted_field);
+ break;
+
+ case DEC:
+ extracted_field = UEXT (inst, opptr->offset, opptr->width);
+ (*info->fprintf_func) (info->stream, "%d", extracted_field);
+ break;
+
+ case CONDMASK:
+ extracted_field = UEXT (inst, opptr->offset, opptr->width);
+ switch (extracted_field & 0x0f)
+ {
+ case 0x1: cond_mask_sym = "gt0"; break;
+ case 0x2: cond_mask_sym = "eq0"; break;
+ case 0x3: cond_mask_sym = "ge0"; break;
+ case 0xc: cond_mask_sym = "lt0"; break;
+ case 0xd: cond_mask_sym = "ne0"; break;
+ case 0xe: cond_mask_sym = "le0"; break;
+ default: cond_mask_sym = NULL; break;
+ }
+ if (cond_mask_sym != NULL)
+ (*info->fprintf_func) (info->stream, "%s", cond_mask_sym);
+ else
+ (*info->fprintf_func) (info->stream, "%x", extracted_field);
+ break;
+
+ case PCREL:
+ (*info->print_address_func)
+ (pc + (4 * (SEXT (inst, opptr->offset, opptr->width))),
+ info);
+ break;
+
+ case CONT:
+ (*info->fprintf_func) (info->stream, "%d,r%d",
+ UEXT (inst, opptr->offset, 5),
+ UEXT (inst, (opptr->offset) + 5, 5));
+ break;
+
+ case BF:
+ (*info->fprintf_func) (info->stream, "%d<%d>",
+ UEXT (inst, (opptr->offset) + 5, 5),
+ UEXT (inst, opptr->offset, 5));
+ break;
+
+ default:
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream, _("# <dis error: %08x>"), inst);
+ }
+}
+
+/*
+* Initialize the Disassembler Instruction Table
+*
+* Initialize the hash table and instruction table for the disassembler.
+* This should be called once before the first call to disasm().
+*
+* Parameters
+*
+* Output
+*
+* If the debug option is selected, certain statistics about the hashing
+* distribution are written to stdout.
+*
+* Revision History
+*
+* Revision 1.0 11/08/85 Creation date
+*/
+
+static void
+init_disasm ()
+{
+ int i, size;
+
+ for (i = 0; i < HASHVAL; i++)
+ hashtable[i] = NULL;
+
+ size = sizeof (instructions) / sizeof (INSTAB);
+ for (i = 0; i < size; i++)
+ install (&instructions[i]);
+}
+
+/*
+* Insert an instruction into the disassembler table by hashing the
+* opcode and inserting it into the linked list for that hash value.
+*
+* Parameters
+*
+* INSTAB *instptr Pointer to the entry in the instruction table
+* to be installed
+*
+* Revision 1.0 11/08/85 Creation date
+* 05/11/89 R. TRAWICK ADAPTED FROM MOTOROLA
+*/
+
+static void
+install (instptr)
+ INSTAB *instptr;
+{
+ unsigned int i;
+
+ i = (instptr->opcode) % HASHVAL;
+ instptr->next = hashtable[i];
+ hashtable[i] = instptr;
+}
diff --git a/opcodes/makefile.vms b/opcodes/makefile.vms
new file mode 100644
index 00000000000..fc8704831e0
--- /dev/null
+++ b/opcodes/makefile.vms
@@ -0,0 +1,42 @@
+#
+# Makefile for libopcodes under openVMS VAX and Alpha
+#
+# For use with gnu-make for vms
+#
+# Created by Klaus K"ampf, kkaempf@progis.de
+#
+#
+ifeq ($(ARCH),alpha)
+OBJS=alpha-dis.obj,alpha-opc.obj,dis-buf.obj,disassemble.obj
+FORMAT=OBJ_EVAX
+ARCHDEF="ARCH_alpha"
+else
+OBJS=vax-dis.obj,dis-buf.obj,disassemble.obj
+FORMAT=OBJ_VAX
+ARCHDEF="ARCH_vax"
+endif
+
+ifeq ($(CC),gcc)
+DEFS=/define=($(FORMAT))
+CFLAGS=/include=([],[-.include],[-.bfd])$(DEFS)
+else
+DEFS=/define=($(FORMAT),"const=")
+CFLAGS=/noopt/debug/include=([],[-.include],[-.bfd])$(DEFS)\
+/warnings=disable=(missingreturn,implicitfunc,longextern)
+endif
+
+libopcodes.olb: sysdep.h $(OBJS)
+ purge
+ lib/create libopcodes *.obj
+
+disassemble.obj: disassemble.c
+ $(CC)$(CFLAGS)/define=($(ARCHDEF)) $<
+
+sysdep.h: [-.bfd.hosts]$(ARCH)vms.h
+ $(CP) $< $@
+
+clean:
+ $$ purge
+ $(RM) *.obj;
+ $(RM) sysdep.h;
+ $(RM) libopcodes.olb;
diff --git a/opcodes/mcore-dis.c b/opcodes/mcore-dis.c
new file mode 100644
index 00000000000..42c1793b6d7
--- /dev/null
+++ b/opcodes/mcore-dis.c
@@ -0,0 +1,250 @@
+/* Disassemble Motorolla M*Core instructions.
+ Copyright (C) 1993, 1999 Free Software Foundation, Inc.
+
+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. */
+
+#include <stdio.h>
+#define STATIC_TABLE
+#define DEFINE_TABLE
+
+#include "mcore-opc.h"
+#include "dis-asm.h"
+
+/* Mask for each mcore_opclass: */
+static const unsigned short imsk[] =
+{
+ /* O0 */ 0xFFFF,
+ /* OT */ 0xFFFC,
+ /* O1 */ 0xFFF0,
+ /* OC */ 0xFFE0,
+ /* O2 */ 0xFF00,
+ /* X1 */ 0xFFF0,
+ /* OI */ 0xFE00,
+ /* OB */ 0xFE00,
+
+ /* OMa */ 0xFFF0,
+ /* SI */ 0xFE00,
+ /* I7 */ 0xF800,
+ /* LS */ 0xF000,
+ /* BR */ 0xF800,
+ /* BL */ 0xFF00,
+ /* LR */ 0xF000,
+ /* LJ */ 0xFF00,
+
+ /* RM */ 0xFFF0,
+ /* RQ */ 0xFFF0,
+ /* JSR */ 0xFFF0,
+ /* JMP */ 0xFFF0,
+ /* OBRa*/ 0xFFF0,
+ /* OBRb*/ 0xFF80,
+ /* OBRc*/ 0xFF00,
+ /* OBR2*/ 0xFE00,
+
+ /* O1R1*/ 0xFFF0,
+ /* OMb */ 0xFF80,
+ /* OMc */ 0xFF00,
+ /* SIa */ 0xFE00,
+
+
+ /* JC */ 0, /* JC,JU,JL don't appear in object */
+ /* JU */ 0,
+ /* JL */ 0,
+ /* RSI */ 0,
+ /* DO21*/ 0,
+ /* OB2 */ 0 /* OB2 won't appear in object. */
+};
+
+static const char * grname[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+
+static const char X[] = "??";
+
+static const char * crname[] =
+{
+ "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
+ "ss2", "ss3", "ss4", "gcr", "gsr", X, X, X,
+ X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X
+};
+
+static const unsigned isiz[] = { 2, 0, 1, 0 };
+
+int
+print_insn_mcore (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info * info;
+{
+ unsigned char ibytes[4];
+ fprintf_ftype fprintf = info->fprintf_func;
+ void * stream = info->stream;
+ unsigned short inst;
+ mcore_opcode_info * op;
+ int status;
+
+ status = info->read_memory_func (memaddr, ibytes, 2, info);
+
+ if (status != 0)
+ {
+ info->memory_error_func (status, memaddr, info);
+ return -1;
+ }
+
+ inst = (ibytes[0] << 8) | ibytes[1];
+
+ /* Just a linear search of the table. */
+ for (op = mcore_table; op->name != 0; op ++)
+ {
+ if (op->inst == (inst & imsk[op->opclass]))
+ break;
+ }
+
+ if (op->name == 0)
+ fprintf (stream, ".word 0x%04x", inst);
+ else
+ {
+ const char * name = grname[inst & 0x0F];
+
+ fprintf (stream, "%s", op->name);
+
+ switch (op->opclass)
+ {
+ case O0: break;
+ case OT: fprintf (stream, "\t%d", inst & 0x3); break;
+ case O1:
+ case JMP:
+ case JSR: fprintf (stream, "\t%s", name); break;
+ case OC: fprintf (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]); break;
+ case O1R1: fprintf (stream, "\t%s, r1", name); break;
+ case O2: fprintf (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]); break;
+ case X1: fprintf (stream, "\tr1, %s", name); break;
+ case OI: fprintf (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1); break;
+ case RM: fprintf (stream, "\t%s-r15, (r0)", name); break;
+ case RQ: fprintf (stream, "\tr4-r7, (%s)", name); break;
+ case OB:
+ case OBRa:
+ case OBRb:
+ case OBRc:
+ case SI:
+ case SIa:
+ case OMa:
+ case OMb:
+ case OMc: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x1F); break;
+ case I7: fprintf (stream, "\t%s, %d", name, (inst >> 4) & 0x7F); break;
+ case LS: fprintf (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
+ name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
+ break;
+
+ case BR:
+ {
+ long val = inst & 0x3FF;
+
+ if (inst & 0x400)
+ val |= 0xFFFFFC00;
+
+ fprintf (stream, "\t0x%x", memaddr + 2 + (val<<1));
+
+ if (strcmp (op->name, "bsr") == 0)
+ {
+ /* for bsr, we'll try to get a symbol for the target */
+ val = memaddr + 2 + (val << 1);
+
+ if (info->print_address_func && val != 0)
+ {
+ fprintf (stream, "\t// ");
+ info->print_address_func (val, info);
+ }
+ }
+ }
+ break;
+
+ case BL:
+ {
+ long val;
+ val = (inst & 0x000F);
+ fprintf (stream, "\t%s, 0x%x",
+ grname[(inst >> 4) & 0xF], memaddr - (val << 1));
+ }
+ break;
+
+ case LR:
+ {
+ unsigned long val;
+
+ val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
+
+ status = info->read_memory_func (val, ibytes, 4, info);
+ if (status != 0)
+ {
+ info->memory_error_func (status, memaddr, info);
+ return -1;
+ }
+
+ val = (ibytes[0] << 24) | (ibytes[1] << 16)
+ | (ibytes[2] << 8) | (ibytes[3]);
+
+ /* Removed [] around literal value to match ABI syntax 12/95. */
+ fprintf (stream, "\t%s, 0x%X", grname[(inst >> 8) & 0xF], val);
+
+ if (val == 0)
+ fprintf (stream, "\t// from address pool at 0x%x",
+ (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
+ }
+ break;
+
+ case LJ:
+ {
+ unsigned long val;
+
+ val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
+
+ status = info->read_memory_func (val, ibytes, 4, info);
+ if (status != 0)
+ {
+ info->memory_error_func (status, memaddr, info);
+ return -1;
+ }
+
+ val = (ibytes[0] << 24) | (ibytes[1] << 16)
+ | (ibytes[2] << 8) | (ibytes[3]);
+
+ /* Removed [] around literal value to match ABI syntax 12/95. */
+ fprintf (stream, "\t0x%X", val);
+ /* For jmpi/jsri, we'll try to get a symbol for the target. */
+ if (info->print_address_func && val != 0)
+ {
+ fprintf (stream, "\t// ");
+ info->print_address_func (val, info);
+ }
+ else
+ {
+ fprintf (stream, "\t// from address pool at 0x%x",
+ (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
+ }
+ }
+ break;
+
+ default:
+ /* if the disassembler lags the instruction set */
+ fprintf (stream, "\tundecoded operands, inst is 0x%04x", inst);
+ break;
+ }
+ }
+
+ /* Say how many bytes we consumed? */
+ return 2;
+}
diff --git a/opcodes/mcore-opc.h b/opcodes/mcore-opc.h
new file mode 100644
index 00000000000..606ba846efd
--- /dev/null
+++ b/opcodes/mcore-opc.h
@@ -0,0 +1,202 @@
+/* Assembler instructions for Motorolla's Mcore processor
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+
+typedef enum
+{
+ O0, OT, O1, OC, O2, X1, OI, OB,
+ OMa, SI, I7, LS, BR, BL, LR, LJ,
+ RM, RQ, JSR, JMP, OBRa, OBRb, OBRc, OBR2,
+ O1R1, OMb, OMc, SIa,
+ JC, JU, JL, RSI, DO21, OB2
+}
+mcore_opclass;
+
+typedef struct inst
+{
+ char * name;
+ mcore_opclass opclass;
+ unsigned char transfer;
+ unsigned short inst;
+}
+mcore_opcode_info;
+
+#ifdef DEFINE_TABLE
+mcore_opcode_info mcore_table[] =
+{
+ { "bkpt", O0, 0, 0x0000 },
+ { "sync", O0, 0, 0x0001 },
+ { "rte", O0, 1, 0x0002 },
+ { "rfe", O0, 1, 0x0002 },
+ { "rfi", O0, 1, 0x0003 },
+ { "stop", O0, 0, 0x0004 },
+ { "wait", O0, 0, 0x0005 },
+ { "doze", O0, 0, 0x0006 },
+ { "trap", OT, 0, 0x0008 },
+/* SPACE: 0x000C - 0x000F */
+/* SPACE: 0x0010 - 0x001F */
+ { "mvc", O1, 0, 0x0020 },
+ { "mvcv", O1, 0, 0x0030 },
+ { "ldq", RQ, 0, 0x0040 },
+ { "stq", RQ, 0, 0x0050 },
+ { "ldm", RM, 0, 0x0060 },
+ { "stm", RM, 0, 0x0070 },
+ { "dect", O1, 0, 0x0080 },
+ { "decf", O1, 0, 0x0090 },
+ { "inct", O1, 0, 0x00A0 },
+ { "incf", O1, 0, 0x00B0 },
+ { "jmp", JMP, 2, 0x00C0 },
+#define MCORE_INST_JMP 0x00C0
+ { "jsr", JSR, 0, 0x00D0 },
+#define MCORE_INST_JSR 0x00E0
+ { "ff1", O1, 0, 0x00E0 },
+ { "brev", O1, 0, 0x00F0 },
+ { "xtrb3", X1, 0, 0x0100 },
+ { "xtrb2", X1, 0, 0x0110 },
+ { "xtrb1", X1, 0, 0x0120 },
+ { "xtrb0", X1, 0, 0x0130 },
+ { "zextb", O1, 0, 0x0140 },
+ { "sextb", O1, 0, 0x0150 },
+ { "zexth", O1, 0, 0x0160 },
+ { "sexth", O1, 0, 0x0170 },
+ { "declt", O1, 0, 0x0180 },
+ { "tstnbz", O1, 0, 0x0190 },
+ { "decgt", O1, 0, 0x01A0 },
+ { "decne", O1, 0, 0x01B0 },
+ { "clrt", O1, 0, 0x01C0 },
+ { "clrf", O1, 0, 0x01D0 },
+ { "abs", O1, 0, 0x01E0 },
+ { "not", O1, 0, 0x01F0 },
+ { "movt", O2, 0, 0x0200 },
+ { "mult", O2, 0, 0x0300 },
+ { "loopt", BL, 0, 0x0400 },
+ { "subu", O2, 0, 0x0500 },
+ { "sub", O2, 0, 0x0500 }, /* Official alias. */
+ { "addc", O2, 0, 0x0600 },
+ { "subc", O2, 0, 0x0700 },
+/* SPACE: 0x0800-0x08ff for a diadic operation */
+/* SPACE: 0x0900-0x09ff for a diadic operation */
+ { "movf", O2, 0, 0x0A00 },
+ { "lsr", O2, 0, 0x0B00 },
+ { "cmphs", O2, 0, 0x0C00 },
+ { "cmplt", O2, 0, 0x0D00 },
+ { "tst", O2, 0, 0x0E00 },
+ { "cmpne", O2, 0, 0x0F00 },
+ { "mfcr", OC, 0, 0x1000 },
+ { "mov", O2, 0, 0x1200 },
+ { "bgenr", O2, 0, 0x1300 },
+ { "rsub", O2, 0, 0x1400 },
+ { "ixw", O2, 0, 0x1500 },
+ { "and", O2, 0, 0x1600 },
+ { "xor", O2, 0, 0x1700 },
+ { "mtcr", OC, 0, 0x1800 },
+ { "asr", O2, 0, 0x1A00 },
+ { "lsl", O2, 0, 0x1B00 },
+ { "addu", O2, 0, 0x1C00 },
+ { "ixh", O2, 0, 0x1D00 },
+ { "or", O2, 0, 0x1E00 },
+ { "andn", O2, 0, 0x1F00 },
+ { "addi", OI, 0, 0x2000 },
+#define MCORE_INST_ADDI 0x2000
+ { "cmplti", OI, 0, 0x2200 },
+ { "subi", OI, 0, 0x2400 },
+/* SPACE: 0x2600-0x27ff open for a register+immediate operation */
+ { "rsubi", OB, 0, 0x2800 },
+ { "cmpnei", OB, 0, 0x2A00 },
+ { "bmaski", OMa, 0, 0x2C00 },
+ { "divu", O1R1, 0, 0x2C10 },
+/* SPACE: 0x2c20 - 0x2c7f */
+ { "bmaski", OMb, 0, 0x2C80 },
+ { "bmaski", OMc, 0, 0x2D00 },
+ { "andi", OB, 0, 0x2E00 },
+ { "bclri", OB, 0, 0x3000 },
+/* SPACE: 0x3200 - 0x320f */
+ { "divs", O1R1, 0, 0x3210 },
+/* SPACE: 0x3220 - 0x326f */
+ { "bgeni", OBRa, 0, 0x3270 },
+ { "bgeni", OBRb, 0, 0x3280 },
+ { "bgeni", OBRc, 0, 0x3300 },
+ { "bseti", OB, 0, 0x3400 },
+ { "btsti", OB, 0, 0x3600 },
+ { "xsr", O1, 0, 0x3800 },
+ { "rotli", SIa, 0, 0x3800 },
+ { "asrc", O1, 0, 0x3A00 },
+ { "asri", SIa, 0, 0x3A00 },
+ { "lslc", O1, 0, 0x3C00 },
+ { "lsli", SIa, 0, 0x3C00 },
+ { "lsrc", O1, 0, 0x3E00 },
+ { "lsri", SIa, 0, 0x3E00 },
+/* SPACE: 0x4000 - 0x5fff */
+ { "movi", I7, 0, 0x6000 },
+#define MCORE_INST_BMASKI_ALT 0x6000
+#define MCORE_INST_BGENI_ALT 0x6000
+/* SPACE: 0x6900 - 0x6FFF */
+ { "jmpi", LJ, 1, 0x7000 },
+ { "jsri", LJ, 0, 0x7F00 },
+#define MCORE_INST_JMPI 0x7000
+ { "lrw", LR, 0, 0x7000 },
+#define MCORE_INST_JSRI 0x7F00
+ { "ld", LS, 0, 0x8000 },
+ { "ldw", LS, 0, 0x8000 },
+ { "ld.w", LS, 0, 0x8000 },
+ { "st", LS, 0, 0x9000 },
+ { "stw", LS, 0, 0x9000 },
+ { "st.w", LS, 0, 0x9000 },
+ { "ldb", LS, 0, 0xA000 },
+ { "ld.b", LS, 0, 0xA000 },
+ { "stb", LS, 0, 0xB000 },
+ { "st.b", LS, 0, 0xB000 },
+ { "ldh", LS, 0, 0xC000 },
+ { "ld.h", LS, 0, 0xC000 },
+ { "sth", LS, 0, 0xD000 },
+ { "st.h", LS, 0, 0xD000 },
+ { "bt", BR, 0, 0xE000 },
+ { "bf", BR, 0, 0xE800 },
+ { "br", BR, 1, 0xF000 },
+#define MCORE_INST_BR 0xF000
+ { "bsr", BR, 0, 0xF800 },
+#define MCORE_INST_BSR 0xF800
+
+/* The following are relaxable branches */
+ { "jbt", JC, 0, 0xE000 },
+ { "jbf", JC, 0, 0xE800 },
+ { "jbr", JU, 1, 0xF000 },
+ { "jbsr", JL, 0, 0xF800 },
+
+/* The following are aliases for other instructions */
+ { "rts", O0, 2, 0x00CF }, /* jmp r15 */
+ { "rolc", DO21, 0, 0x0600 }, /* addc rd,rd */
+ { "rotlc", DO21, 0, 0x0600 }, /* addc rd,rd */
+ { "setc", O0, 0, 0x0C00 }, /* cmphs r0,r0 */
+ { "clrc", O0, 0, 0x0F00 }, /* cmpne r0,r0 */
+ { "tstle", O1, 0, 0x2200 }, /* cmplti rd,1 */
+ { "cmplei", OB, 0, 0x2200 }, /* cmplei rd,X -> cmplti rd,X+1 */
+ { "neg", O1, 0, 0x2800 }, /* rsubi rd,0 */
+ { "tstne", O1, 0, 0x2A00 }, /* cmpnei rd,0 */
+ { "tstlt", O1, 0, 0x37F0 }, /* btsti rx,31 */
+ { "mclri", OB2, 0, 0x3000 }, /* bclri rx,log2(imm) */
+ { "mgeni", OBR2, 0, 0x3200 }, /* bgeni rx,log2(imm) */
+ { "mseti", OB2, 0, 0x3400 }, /* bseti rx,log2(imm) */
+ { "mtsti", OB2, 0, 0x3600 }, /* btsti rx,log2(imm) */
+ { "rori", RSI, 0, 0x3800 },
+ { "rotri", RSI, 0, 0x3800 },
+ { "nop", O0, 0, 0x1200 }, /* mov r0, r0 */
+ { 0, 0, 0, 0 }
+};
+#endif
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
new file mode 100644
index 00000000000..1e3577cec32
--- /dev/null
+++ b/opcodes/mips-dis.c
@@ -0,0 +1,1068 @@
+/* Print mips instructions for GDB, the GNU debugger, or for objdump.
+ Copyright (c) 1989, 91-97, 1998 Free Software Foundation, Inc.
+ Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
+
+This file is part of GDB, GAS, and the 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ansidecl.h>
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "opcode/mips.h"
+#include "opintl.h"
+
+/* FIXME: These are needed to figure out if the code is mips16 or
+ not. The low bit of the address is often a good indicator. No
+ symbol table is available when this code runs out in an embedded
+ system as when it is used for disassembler support in a monitor. */
+
+#if !defined(EMBEDDED_ENV)
+#define SYMTAB_AVAILABLE 1
+#include "elf-bfd.h"
+#include "elf/mips.h"
+#endif
+
+static int print_insn_mips16 PARAMS ((bfd_vma, struct disassemble_info *));
+static void print_mips16_insn_arg
+ PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
+ struct disassemble_info *));
+
+/* Mips instructions are never longer than this many bytes. */
+#define MAXLEN 4
+
+static void print_insn_arg PARAMS ((const char *, unsigned long, bfd_vma,
+ struct disassemble_info *));
+static int _print_insn_mips PARAMS ((bfd_vma, unsigned long int,
+ struct disassemble_info *));
+
+
+/* FIXME: This should be shared with gdb somehow. */
+#define REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "sr", "lo", "hi", "bad", "cause","pc", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",\
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",\
+ "fsr", "fir", "fp", "inx", "rand", "tlblo","ctxt", "tlbhi",\
+ "epc", "prid"\
+ }
+
+static CONST char * CONST reg_names[] = REGISTER_NAMES;
+
+/* The mips16 register names. */
+static const char * const mips16_reg_names[] =
+{
+ "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
+};
+
+/* subroutine */
+static void
+print_insn_arg (d, l, pc, info)
+ const char *d;
+ register unsigned long int l;
+ bfd_vma pc;
+ struct disassemble_info *info;
+{
+ int delta;
+
+ switch (*d)
+ {
+ case ',':
+ case '(':
+ case ')':
+ (*info->fprintf_func) (info->stream, "%c", *d);
+ break;
+
+ case 's':
+ case 'b':
+ case 'r':
+ case 'v':
+ (*info->fprintf_func) (info->stream, "$%s",
+ reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
+ break;
+
+ case 't':
+ case 'w':
+ (*info->fprintf_func) (info->stream, "$%s",
+ reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+ break;
+
+ case 'i':
+ case 'u':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
+ break;
+
+ case 'j': /* same as i, but sign-extended */
+ case 'o':
+ delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
+ if (delta & 0x8000)
+ delta |= ~0xffff;
+ (*info->fprintf_func) (info->stream, "%d",
+ delta);
+ break;
+
+ case 'h':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (unsigned int) ((l >> OP_SH_PREFX)
+ & OP_MASK_PREFX));
+ break;
+
+ case 'k':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (unsigned int) ((l >> OP_SH_CACHE)
+ & OP_MASK_CACHE));
+ break;
+
+ case 'a':
+ (*info->print_address_func)
+ (((pc & 0xF0000000) | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
+ info);
+ break;
+
+ case 'p':
+ /* sign extend the displacement */
+ delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
+ if (delta & 0x8000)
+ delta |= ~0xffff;
+ (*info->print_address_func)
+ ((delta << 2) + pc + 4,
+ info);
+ break;
+
+ case 'd':
+ (*info->fprintf_func) (info->stream, "$%s",
+ reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
+ break;
+
+ case 'z':
+ (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
+ break;
+
+ case '<':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
+ break;
+
+ case 'c':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_CODE) & OP_MASK_CODE);
+ break;
+
+
+ case 'q':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_CODE2) & OP_MASK_CODE2);
+ break;
+
+ case 'C':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_COPZ) & OP_MASK_COPZ);
+ break;
+
+ case 'B':
+ (*info->fprintf_func) (info->stream, "0x%x",
+ (l >> OP_SH_SYSCALL) & OP_MASK_SYSCALL);
+ break;
+
+ case 'S':
+ case 'V':
+ (*info->fprintf_func) (info->stream, "$f%d",
+ (l >> OP_SH_FS) & OP_MASK_FS);
+ break;
+
+
+ case 'T':
+ case 'W':
+ (*info->fprintf_func) (info->stream, "$f%d",
+ (l >> OP_SH_FT) & OP_MASK_FT);
+ break;
+
+ case 'D':
+ (*info->fprintf_func) (info->stream, "$f%d",
+ (l >> OP_SH_FD) & OP_MASK_FD);
+ break;
+
+ case 'R':
+ (*info->fprintf_func) (info->stream, "$f%d",
+ (l >> OP_SH_FR) & OP_MASK_FR);
+ break;
+
+ case 'E':
+ (*info->fprintf_func) (info->stream, "$%d",
+ (l >> OP_SH_RT) & OP_MASK_RT);
+ break;
+
+ case 'G':
+ (*info->fprintf_func) (info->stream, "$%d",
+ (l >> OP_SH_RD) & OP_MASK_RD);
+ break;
+
+ case 'N':
+ (*info->fprintf_func) (info->stream, "$fcc%d",
+ (l >> OP_SH_BCC) & OP_MASK_BCC);
+ break;
+
+ case 'M':
+ (*info->fprintf_func) (info->stream, "$fcc%d",
+ (l >> OP_SH_CCC) & OP_MASK_CCC);
+ break;
+
+ case 'P':
+ (*info->fprintf_func) (info->stream, "%d",
+ (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
+ break;
+
+
+ default:
+ /* xgettext:c-format */
+ (*info->fprintf_func) (info->stream,
+ _("# internal error, undefined modifier(%c)"),
+ *d);
+ break;
+ }
+}
+
+#if SYMTAB_AVAILABLE
+
+/* Figure out the MIPS ISA and CPU based on the machine number.
+ FIXME: What does this have to do with SYMTAB_AVAILABLE? */
+
+static void
+set_mips_isa_type (mach, isa, cputype)
+ int mach;
+ int *isa;
+ int *cputype;
+{
+ int target_processor = 0;
+ int mips_isa = 0;
+
+ switch (mach)
+ {
+ case bfd_mach_mips3000:
+ target_processor = 3000;
+ mips_isa = 1;
+ break;
+ case bfd_mach_mips3900:
+ target_processor = 3900;
+ mips_isa = 1;
+ break;
+ case bfd_mach_mips4000:
+ target_processor = 4000;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips4010:
+ target_processor = 4010;
+ mips_isa = 2;
+ break;
+ case bfd_mach_mips4100:
+ target_processor = 4100;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips4111:
+ target_processor = 4100;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips4300:
+ target_processor = 4300;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips4400:
+ target_processor = 4400;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips4600:
+ target_processor = 4600;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips4650:
+ target_processor = 4650;
+ mips_isa = 3;
+ break;
+ case bfd_mach_mips5000:
+ target_processor = 5000;
+ mips_isa = 4;
+ break;
+ case bfd_mach_mips6000:
+ target_processor = 6000;
+ mips_isa = 2;
+ break;
+ case bfd_mach_mips8000:
+ target_processor = 8000;
+ mips_isa = 4;
+ break;
+ case bfd_mach_mips10000:
+ target_processor = 10000;
+ mips_isa = 4;
+ break;
+ case bfd_mach_mips16:
+ target_processor = 16;
+ mips_isa = 3;
+ break;
+ default:
+ target_processor = 3000;
+ mips_isa = 3;
+ break;
+
+ }
+
+ *isa = mips_isa;
+ *cputype = target_processor;
+}
+
+#endif /* SYMTAB_AVAILABLE */
+
+/* Print the mips instruction at address MEMADDR in debugged memory,
+ on using INFO. Returns length of the instruction, in bytes, which is
+ always 4. BIGENDIAN must be 1 if this is big-endian code, 0 if
+ this is little-endian code. */
+
+static int
+_print_insn_mips (memaddr, word, info)
+ bfd_vma memaddr;
+ unsigned long int word;
+ struct disassemble_info *info;
+{
+ register const struct mips_opcode *op;
+ int target_processor, mips_isa;
+ static boolean init = 0;
+ static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
+
+ /* Build a hash table to shorten the search time. */
+ if (! init)
+ {
+ unsigned int i;
+
+ for (i = 0; i <= OP_MASK_OP; i++)
+ {
+ for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
+ {
+ if (op->pinfo == INSN_MACRO)
+ continue;
+ if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
+ {
+ mips_hash[i] = op;
+ break;
+ }
+ }
+ }
+
+ init = 1;
+ }
+
+#if ! SYMTAB_AVAILABLE
+ /* This is running out on a target machine, not in a host tool.
+ FIXME: Where does mips_target_info come from? */
+ target_processor = mips_target_info.processor;
+ mips_isa = mips_target_info.isa;
+#else
+ set_mips_isa_type (info->mach, &mips_isa, &target_processor);
+#endif
+
+ info->bytes_per_chunk = 4;
+ info->display_endian = info->endian;
+
+ op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
+ if (op != NULL)
+ {
+ for (; op < &mips_opcodes[NUMOPCODES]; op++)
+ {
+ if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
+ {
+ register const char *d;
+ int insn_isa;
+
+ if ((op->membership & INSN_ISA) == INSN_ISA1)
+ insn_isa = 1;
+ else if ((op->membership & INSN_ISA) == INSN_ISA2)
+ insn_isa = 2;
+ else if ((op->membership & INSN_ISA) == INSN_ISA3)
+ insn_isa = 3;
+ else if ((op->membership & INSN_ISA) == INSN_ISA4)
+ insn_isa = 4;
+ else
+ insn_isa = 15;
+
+ if (insn_isa > mips_isa
+ && (target_processor == 4650
+ && op->membership & INSN_4650) == 0
+ && (target_processor == 4010
+ && op->membership & INSN_4010) == 0
+ && (target_processor == 4100
+ && op->membership & INSN_4100) == 0
+ && (target_processor == 3900
+ && op->membership & INSN_3900) == 0)
+ continue;
+
+ (*info->fprintf_func) (info->stream, "%s", op->name);
+
+ d = op->args;
+ if (d != NULL && *d != '\0')
+ {
+ (*info->fprintf_func) (info->stream, "\t");
+ for (; *d != '\0'; d++)
+ print_insn_arg (d, word, memaddr, info);
+ }
+
+ return 4;
+ }
+ }
+ }
+
+ /* Handle undefined instructions. */
+ (*info->fprintf_func) (info->stream, "0x%x", word);
+ return 4;
+}
+
+
+/* In an environment where we do not know the symbol type of the
+ instruction we are forced to assume that the low order bit of the
+ instructions' address may mark it as a mips16 instruction. If we
+ are single stepping, or the pc is within the disassembled function,
+ this works. Otherwise, we need a clue. Sometimes. */
+
+int
+print_insn_big_mips (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ bfd_byte buffer[4];
+ int status;
+
+#if 1
+ /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
+ /* Only a few tools will work this way. */
+ if (memaddr & 0x01)
+ return print_insn_mips16 (memaddr, info);
+#endif
+
+#if SYMTAB_AVAILABLE
+ if (info->mach == 16
+ || (info->flavour == bfd_target_elf_flavour
+ && info->symbols != NULL
+ && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
+ == STO_MIPS16)))
+ return print_insn_mips16 (memaddr, info);
+#endif
+
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status == 0)
+ return _print_insn_mips (memaddr, (unsigned long) bfd_getb32 (buffer),
+ info);
+ else
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+}
+
+int
+print_insn_little_mips (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ bfd_byte buffer[4];
+ int status;
+
+
+#if 1
+ if (memaddr & 0x01)
+ return print_insn_mips16 (memaddr, info);
+#endif
+
+#if SYMTAB_AVAILABLE
+ if (info->mach == 16
+ || (info->flavour == bfd_target_elf_flavour
+ && info->symbols != NULL
+ && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
+ == STO_MIPS16)))
+ return print_insn_mips16 (memaddr, info);
+#endif
+
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status == 0)
+ return _print_insn_mips (memaddr, (unsigned long) bfd_getl32 (buffer),
+ info);
+ else
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+}
+
+/* Disassemble mips16 instructions. */
+
+static int
+print_insn_mips16 (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int status;
+ bfd_byte buffer[2];
+ int length;
+ int insn;
+ boolean use_extend;
+ int extend = 0;
+ const struct mips_opcode *op, *opend;
+
+ info->bytes_per_chunk = 2;
+ info->display_endian = info->endian;
+
+ info->insn_info_valid = 1;
+ info->branch_delay_insns = 0;
+ info->data_size = 0;
+ info->insn_type = dis_nonbranch;
+ info->target = 0;
+ info->target2 = 0;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ length = 2;
+
+ if (info->endian == BFD_ENDIAN_BIG)
+ insn = bfd_getb16 (buffer);
+ else
+ insn = bfd_getl16 (buffer);
+
+ /* Handle the extend opcode specially. */
+ use_extend = false;
+ if ((insn & 0xf800) == 0xf000)
+ {
+ use_extend = true;
+ extend = insn & 0x7ff;
+
+ memaddr += 2;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->fprintf_func) (info->stream, "extend 0x%x",
+ (unsigned int) extend);
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ if (info->endian == BFD_ENDIAN_BIG)
+ insn = bfd_getb16 (buffer);
+ else
+ insn = bfd_getl16 (buffer);
+
+ /* Check for an extend opcode followed by an extend opcode. */
+ if ((insn & 0xf800) == 0xf000)
+ {
+ (*info->fprintf_func) (info->stream, "extend 0x%x",
+ (unsigned int) extend);
+ info->insn_type = dis_noninsn;
+ return length;
+ }
+
+ length += 2;
+ }
+
+ /* FIXME: Should probably use a hash table on the major opcode here. */
+
+ opend = mips16_opcodes + bfd_mips16_num_opcodes;
+ for (op = mips16_opcodes; op < opend; op++)
+ {
+ if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
+ {
+ const char *s;
+
+ if (strchr (op->args, 'a') != NULL)
+ {
+ if (use_extend)
+ {
+ (*info->fprintf_func) (info->stream, "extend 0x%x",
+ (unsigned int) extend);
+ info->insn_type = dis_noninsn;
+ return length - 2;
+ }
+
+ use_extend = false;
+
+ memaddr += 2;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 2,
+ info);
+ if (status == 0)
+ {
+ use_extend = true;
+ if (info->endian == BFD_ENDIAN_BIG)
+ extend = bfd_getb16 (buffer);
+ else
+ extend = bfd_getl16 (buffer);
+ length += 2;
+ }
+ }
+
+ (*info->fprintf_func) (info->stream, "%s", op->name);
+ if (op->args[0] != '\0')
+ (*info->fprintf_func) (info->stream, "\t");
+
+ for (s = op->args; *s != '\0'; s++)
+ {
+ if (*s == ','
+ && s[1] == 'w'
+ && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
+ == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
+ {
+ /* Skip the register and the comma. */
+ ++s;
+ continue;
+ }
+ if (*s == ','
+ && s[1] == 'v'
+ && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
+ == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
+ {
+ /* Skip the register and the comma. */
+ ++s;
+ continue;
+ }
+ print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
+ info);
+ }
+
+ if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+ {
+ info->branch_delay_insns = 1;
+ if (info->insn_type != dis_jsr)
+ info->insn_type = dis_branch;
+ }
+
+ return length;
+ }
+ }
+
+ if (use_extend)
+ (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
+ (*info->fprintf_func) (info->stream, "0x%x", insn);
+ info->insn_type = dis_noninsn;
+
+ return length;
+}
+
+/* Disassemble an operand for a mips16 instruction. */
+
+static void
+print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
+ int type;
+ const struct mips_opcode *op;
+ int l;
+ boolean use_extend;
+ int extend;
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ switch (type)
+ {
+ case ',':
+ case '(':
+ case ')':
+ (*info->fprintf_func) (info->stream, "%c", type);
+ break;
+
+ case 'y':
+ case 'w':
+ (*info->fprintf_func) (info->stream, "$%s",
+ mips16_reg_names[((l >> MIPS16OP_SH_RY)
+ & MIPS16OP_MASK_RY)]);
+ break;
+
+ case 'x':
+ case 'v':
+ (*info->fprintf_func) (info->stream, "$%s",
+ mips16_reg_names[((l >> MIPS16OP_SH_RX)
+ & MIPS16OP_MASK_RX)]);
+ break;
+
+ case 'z':
+ (*info->fprintf_func) (info->stream, "$%s",
+ mips16_reg_names[((l >> MIPS16OP_SH_RZ)
+ & MIPS16OP_MASK_RZ)]);
+ break;
+
+ case 'Z':
+ (*info->fprintf_func) (info->stream, "$%s",
+ mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
+ & MIPS16OP_MASK_MOVE32Z)]);
+ break;
+
+ case '0':
+ (*info->fprintf_func) (info->stream, "$%s", reg_names[0]);
+ break;
+
+ case 'S':
+ (*info->fprintf_func) (info->stream, "$%s", reg_names[29]);
+ break;
+
+ case 'P':
+ (*info->fprintf_func) (info->stream, "$pc");
+ break;
+
+ case 'R':
+ (*info->fprintf_func) (info->stream, "$%s", reg_names[31]);
+ break;
+
+ case 'X':
+ (*info->fprintf_func) (info->stream, "$%s",
+ reg_names[((l >> MIPS16OP_SH_REGR32)
+ & MIPS16OP_MASK_REGR32)]);
+ break;
+
+ case 'Y':
+ (*info->fprintf_func) (info->stream, "$%s",
+ reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
+ break;
+
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '4':
+ case '5':
+ case 'H':
+ case 'W':
+ case 'D':
+ case 'j':
+ case '6':
+ case '8':
+ case 'V':
+ case 'C':
+ case 'U':
+ case 'k':
+ case 'K':
+ case 'p':
+ case 'q':
+ case 'A':
+ case 'B':
+ case 'E':
+ {
+ int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
+
+ shift = 0;
+ signedp = 0;
+ extbits = 16;
+ pcrel = 0;
+ extu = 0;
+ branch = 0;
+ switch (type)
+ {
+ case '<':
+ nbits = 3;
+ immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
+ extbits = 5;
+ extu = 1;
+ break;
+ case '>':
+ nbits = 3;
+ immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
+ extbits = 5;
+ extu = 1;
+ break;
+ case '[':
+ nbits = 3;
+ immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
+ extbits = 6;
+ extu = 1;
+ break;
+ case ']':
+ nbits = 3;
+ immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
+ extbits = 6;
+ extu = 1;
+ break;
+ case '4':
+ nbits = 4;
+ immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
+ signedp = 1;
+ extbits = 15;
+ break;
+ case '5':
+ nbits = 5;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ info->insn_type = dis_dref;
+ info->data_size = 1;
+ break;
+ case 'H':
+ nbits = 5;
+ shift = 1;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ info->insn_type = dis_dref;
+ info->data_size = 2;
+ break;
+ case 'W':
+ nbits = 5;
+ shift = 2;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
+ && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
+ {
+ info->insn_type = dis_dref;
+ info->data_size = 4;
+ }
+ break;
+ case 'D':
+ nbits = 5;
+ shift = 3;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ info->insn_type = dis_dref;
+ info->data_size = 8;
+ break;
+ case 'j':
+ nbits = 5;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ signedp = 1;
+ break;
+ case '6':
+ nbits = 6;
+ immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
+ break;
+ case '8':
+ nbits = 8;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ break;
+ case 'V':
+ nbits = 8;
+ shift = 2;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ /* FIXME: This might be lw, or it might be addiu to $sp or
+ $pc. We assume it's load. */
+ info->insn_type = dis_dref;
+ info->data_size = 4;
+ break;
+ case 'C':
+ nbits = 8;
+ shift = 3;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ info->insn_type = dis_dref;
+ info->data_size = 8;
+ break;
+ case 'U':
+ nbits = 8;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ extu = 1;
+ break;
+ case 'k':
+ nbits = 8;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ signedp = 1;
+ break;
+ case 'K':
+ nbits = 8;
+ shift = 3;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ signedp = 1;
+ break;
+ case 'p':
+ nbits = 8;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ signedp = 1;
+ pcrel = 1;
+ branch = 1;
+ info->insn_type = dis_condbranch;
+ break;
+ case 'q':
+ nbits = 11;
+ immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
+ signedp = 1;
+ pcrel = 1;
+ branch = 1;
+ info->insn_type = dis_branch;
+ break;
+ case 'A':
+ nbits = 8;
+ shift = 2;
+ immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
+ pcrel = 1;
+ /* FIXME: This can be lw or la. We assume it is lw. */
+ info->insn_type = dis_dref;
+ info->data_size = 4;
+ break;
+ case 'B':
+ nbits = 5;
+ shift = 3;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ pcrel = 1;
+ info->insn_type = dis_dref;
+ info->data_size = 8;
+ break;
+ case 'E':
+ nbits = 5;
+ shift = 2;
+ immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
+ pcrel = 1;
+ break;
+ default:
+ abort ();
+ }
+
+ if (! use_extend)
+ {
+ if (signedp && immed >= (1 << (nbits - 1)))
+ immed -= 1 << nbits;
+ immed <<= shift;
+ if ((type == '<' || type == '>' || type == '[' || type == ']')
+ && immed == 0)
+ immed = 8;
+ }
+ else
+ {
+ if (extbits == 16)
+ immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
+ else if (extbits == 15)
+ immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
+ else
+ immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
+ immed &= (1 << extbits) - 1;
+ if (! extu && immed >= (1 << (extbits - 1)))
+ immed -= 1 << extbits;
+ }
+
+ if (! pcrel)
+ (*info->fprintf_func) (info->stream, "%d", immed);
+ else
+ {
+ bfd_vma baseaddr;
+ bfd_vma val;
+
+ if (branch)
+ {
+ immed *= 2;
+ baseaddr = memaddr + 2;
+ }
+ else if (use_extend)
+ baseaddr = memaddr - 2;
+ else
+ {
+ int status;
+ bfd_byte buffer[2];
+
+ baseaddr = memaddr;
+
+ /* If this instruction is in the delay slot of a jr
+ instruction, the base address is the address of the
+ jr instruction. If it is in the delay slot of jalr
+ instruction, the base address is the address of the
+ jalr instruction. This test is unreliable: we have
+ no way of knowing whether the previous word is
+ instruction or data. */
+ status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
+ info);
+ if (status == 0
+ && (((info->endian == BFD_ENDIAN_BIG
+ ? bfd_getb16 (buffer)
+ : bfd_getl16 (buffer))
+ & 0xf800) == 0x1800))
+ baseaddr = memaddr - 4;
+ else
+ {
+ status = (*info->read_memory_func) (memaddr - 2, buffer,
+ 2, info);
+ if (status == 0
+ && (((info->endian == BFD_ENDIAN_BIG
+ ? bfd_getb16 (buffer)
+ : bfd_getl16 (buffer))
+ & 0xf81f) == 0xe800))
+ baseaddr = memaddr - 2;
+ }
+ }
+ val = (baseaddr & ~ ((1 << shift) - 1)) + immed;
+ (*info->print_address_func) (val, info);
+ info->target = val;
+ }
+ }
+ break;
+
+ case 'a':
+ if (! use_extend)
+ extend = 0;
+ l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
+ (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
+ info->insn_type = dis_jsr;
+ info->target = (memaddr & 0xf0000000) | l;
+ info->branch_delay_insns = 1;
+ break;
+
+ case 'l':
+ case 'L':
+ {
+ int need_comma, amask, smask;
+
+ need_comma = 0;
+
+ l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
+
+ amask = (l >> 3) & 7;
+
+ if (amask > 0 && amask < 5)
+ {
+ (*info->fprintf_func) (info->stream, "$%s", reg_names[4]);
+ if (amask > 1)
+ (*info->fprintf_func) (info->stream, "-$%s",
+ reg_names[amask + 3]);
+ need_comma = 1;
+ }
+
+ smask = (l >> 1) & 3;
+ if (smask == 3)
+ {
+ (*info->fprintf_func) (info->stream, "%s??",
+ need_comma ? "," : "");
+ need_comma = 1;
+ }
+ else if (smask > 0)
+ {
+ (*info->fprintf_func) (info->stream, "%s$%s",
+ need_comma ? "," : "",
+ reg_names[16]);
+ if (smask > 1)
+ (*info->fprintf_func) (info->stream, "-$%s",
+ reg_names[smask + 15]);
+ need_comma = 1;
+ }
+
+ if (l & 1)
+ {
+ (*info->fprintf_func) (info->stream, "%s$%s",
+ need_comma ? "," : "",
+ reg_names[31]);
+ need_comma = 1;
+ }
+
+ if (amask == 5 || amask == 6)
+ {
+ (*info->fprintf_func) (info->stream, "%s$f0",
+ need_comma ? "," : "");
+ if (amask == 6)
+ (*info->fprintf_func) (info->stream, "-$f1");
+ }
+ }
+ break;
+
+ default:
+ abort ();
+ }
+}
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
new file mode 100644
index 00000000000..b8646193863
--- /dev/null
+++ b/opcodes/mips-opc.c
@@ -0,0 +1,772 @@
+/* mips.h. Mips opcode list for GDB, the GNU debugger.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Ralph Campbell and OSF
+ Commented and modified by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/mips.h"
+
+/* Short hand so the lines aren't too long. */
+
+#define LDD INSN_LOAD_MEMORY_DELAY
+#define LCD INSN_LOAD_COPROC_DELAY
+#define UBD INSN_UNCOND_BRANCH_DELAY
+#define CBD INSN_COND_BRANCH_DELAY
+#define COD INSN_COPROC_MOVE_DELAY
+#define CLD INSN_COPROC_MEMORY_DELAY
+#define CBL INSN_COND_BRANCH_LIKELY
+#define TRAP INSN_TRAP
+#define SM INSN_STORE_MEMORY
+
+#define WR_d INSN_WRITE_GPR_D
+#define WR_t INSN_WRITE_GPR_T
+#define WR_31 INSN_WRITE_GPR_31
+#define WR_D INSN_WRITE_FPR_D
+#define WR_T INSN_WRITE_FPR_T
+#define WR_S INSN_WRITE_FPR_S
+#define RD_s INSN_READ_GPR_S
+#define RD_b INSN_READ_GPR_S
+#define RD_t INSN_READ_GPR_T
+#define RD_S INSN_READ_FPR_S
+#define RD_T INSN_READ_FPR_T
+#define RD_R INSN_READ_FPR_R
+#define WR_CC INSN_WRITE_COND_CODE
+#define RD_CC INSN_READ_COND_CODE
+#define RD_C0 INSN_COP
+#define RD_C1 INSN_COP
+#define RD_C2 INSN_COP
+#define RD_C3 INSN_COP
+#define WR_C0 INSN_COP
+#define WR_C1 INSN_COP
+#define WR_C2 INSN_COP
+#define WR_C3 INSN_COP
+
+#define WR_HI INSN_WRITE_HI
+#define RD_HI INSN_READ_HI
+#define MOD_HI WR_HI|RD_HI
+
+#define WR_LO INSN_WRITE_LO
+#define RD_LO INSN_READ_LO
+#define MOD_LO WR_LO|RD_LO
+
+#define WR_HILO WR_HI|WR_LO
+#define RD_HILO RD_HI|RD_LO
+#define MOD_HILO WR_HILO|RD_HILO
+
+#define IS_M INSN_MULT
+
+#define I1 INSN_ISA1
+#define I2 INSN_ISA2
+#define I3 INSN_ISA3
+#define I4 INSN_ISA4
+#define P3 INSN_4650
+#define L1 INSN_4010
+#define V1 INSN_4100
+#define T3 INSN_3900
+
+#define G1 (T3 \
+ )
+
+#define G2 (T3 \
+ )
+
+#define G3 (I4 \
+ )
+
+/* The order of overloaded instructions matters. Label arguments and
+ register arguments look the same. Instructions that can have either
+ for arguments must apear in the correct order in this table for the
+ assembler to pick the right one. In other words, entries with
+ immediate operands must apear after the same instruction with
+ registers.
+
+ Many instructions are short hand for other instructions (i.e., The
+ jal <register> instruction is short for jalr <register>). */
+
+const struct mips_opcode mips_builtin_opcodes[] = {
+/* These instructions appear first so that the disassembler will find
+ them first. The assemblers uses a hash table based on the
+ instruction name anyhow. */
+/* name, args, mask, match, pinfo */
+{"nop", "", 0x00000000, 0xffffffff, 0, I1 },
+{"li", "t,j", 0x24000000, 0xffe00000, WR_t, I1 }, /* addiu */
+{"li", "t,i", 0x34000000, 0xffe00000, WR_t, I1 }, /* ori */
+{"li", "t,I", 0, (int) M_LI, INSN_MACRO, I1 },
+{"move", "d,s", 0x0000002d, 0xfc1f07ff, WR_d|RD_s, I3 },/* daddu */
+{"move", "d,s", 0x00000021, 0xfc1f07ff, WR_d|RD_s, I1 },/* addu */
+{"move", "d,s", 0x00000025, 0xfc1f07ff, WR_d|RD_s, I1 },/* or */
+{"b", "p", 0x10000000, 0xffff0000, UBD, I1 },/* beq 0,0 */
+{"b", "p", 0x04010000, 0xffff0000, UBD, I1 },/* bgez 0 */
+{"bal", "p", 0x04110000, 0xffff0000, UBD|WR_31, I1 },/* bgezal 0*/
+
+{"abs", "d,v", 0, (int) M_ABS, INSN_MACRO, I1 },
+{"abs.s", "D,V", 0x46000005, 0xffff003f, WR_D|RD_S|FP_S, I1 },
+{"abs.d", "D,V", 0x46200005, 0xffff003f, WR_D|RD_S|FP_D, I1 },
+{"add", "d,v,t", 0x00000020, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"add", "t,r,I", 0, (int) M_ADD_I, INSN_MACRO, I1 },
+{"add.s", "D,V,T", 0x46000000, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, I1},
+{"add.d", "D,V,T", 0x46200000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I1},
+{"addi", "t,r,j", 0x20000000, 0xfc000000, WR_t|RD_s, I1 },
+{"addiu", "t,r,j", 0x24000000, 0xfc000000, WR_t|RD_s, I1 },
+{"addu", "d,v,t", 0x00000021, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"addu", "t,r,I", 0, (int) M_ADDU_I, INSN_MACRO, I1 },
+{"and", "d,v,t", 0x00000024, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"and", "t,r,I", 0, (int) M_AND_I, INSN_MACRO, I1 },
+{"andi", "t,r,i", 0x30000000, 0xfc000000, WR_t|RD_s, I1 },
+/* b is at the top of the table. */
+/* bal is at the top of the table. */
+{"bc0f", "p", 0x41000000, 0xffff0000, CBD|RD_CC, I1 },
+{"bc0fl", "p", 0x41020000, 0xffff0000, CBL|RD_CC, I2|T3 },
+{"bc1f", "p", 0x45000000, 0xffff0000, CBD|RD_CC|FP_S, I1 },
+{"bc1f", "N,p", 0x45000000, 0xffe30000, CBD|RD_CC|FP_S, I4 },
+{"bc1fl", "p", 0x45020000, 0xffff0000, CBL|RD_CC|FP_S, I2|T3 },
+{"bc1fl", "N,p", 0x45020000, 0xffe30000, CBL|RD_CC|FP_S, I4 },
+{"bc2f", "p", 0x49000000, 0xffff0000, CBD|RD_CC, I1 },
+{"bc2fl", "p", 0x49020000, 0xffff0000, CBL|RD_CC, I2|T3 },
+{"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, I1 },
+{"bc3fl", "p", 0x4d020000, 0xffff0000, CBL|RD_CC, I2|T3 },
+{"bc0t", "p", 0x41010000, 0xffff0000, CBD|RD_CC, I1 },
+{"bc0tl", "p", 0x41030000, 0xffff0000, CBL|RD_CC, I2|T3 },
+{"bc1t", "p", 0x45010000, 0xffff0000, CBD|RD_CC|FP_S, I1 },
+{"bc1t", "N,p", 0x45010000, 0xffe30000, CBD|RD_CC|FP_S, I4 },
+{"bc1tl", "p", 0x45030000, 0xffff0000, CBL|RD_CC|FP_S, I2|T3 },
+{"bc1tl", "N,p", 0x45030000, 0xffe30000, CBL|RD_CC|FP_S, I4 },
+{"bc2t", "p", 0x49010000, 0xffff0000, CBD|RD_CC, I1 },
+{"bc2tl", "p", 0x49030000, 0xffff0000, CBL|RD_CC, I2|T3 },
+{"bc3t", "p", 0x4d010000, 0xffff0000, CBD|RD_CC, I1 },
+{"bc3tl", "p", 0x4d030000, 0xffff0000, CBL|RD_CC, I2|T3 },
+{"beqz", "s,p", 0x10000000, 0xfc1f0000, CBD|RD_s, I1 },
+{"beqzl", "s,p", 0x50000000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"beq", "s,t,p", 0x10000000, 0xfc000000, CBD|RD_s|RD_t, I1 },
+{"beq", "s,I,p", 0, (int) M_BEQ_I, INSN_MACRO, I1 },
+{"beql", "s,t,p", 0x50000000, 0xfc000000, CBL|RD_s|RD_t, I2|T3 },
+{"beql", "s,I,p", 0, (int) M_BEQL_I, INSN_MACRO, I2 },
+{"bge", "s,t,p", 0, (int) M_BGE, INSN_MACRO, I1 },
+{"bge", "s,I,p", 0, (int) M_BGE_I, INSN_MACRO, I1 },
+{"bgel", "s,t,p", 0, (int) M_BGEL, INSN_MACRO, I2 },
+{"bgel", "s,I,p", 0, (int) M_BGEL_I, INSN_MACRO, I2 },
+{"bgeu", "s,t,p", 0, (int) M_BGEU, INSN_MACRO, I1 },
+{"bgeu", "s,I,p", 0, (int) M_BGEU_I, INSN_MACRO, I1 },
+{"bgeul", "s,t,p", 0, (int) M_BGEUL, INSN_MACRO, I2 },
+{"bgeul", "s,I,p", 0, (int) M_BGEUL_I, INSN_MACRO, I2 },
+{"bgez", "s,p", 0x04010000, 0xfc1f0000, CBD|RD_s, I1 },
+{"bgezl", "s,p", 0x04030000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"bgezal", "s,p", 0x04110000, 0xfc1f0000, CBD|RD_s|WR_31, I1 },
+{"bgezall", "s,p", 0x04130000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"bgt", "s,t,p", 0, (int) M_BGT, INSN_MACRO, I1 },
+{"bgt", "s,I,p", 0, (int) M_BGT_I, INSN_MACRO, I1 },
+{"bgtl", "s,t,p", 0, (int) M_BGTL, INSN_MACRO, I2 },
+{"bgtl", "s,I,p", 0, (int) M_BGTL_I, INSN_MACRO, I2 },
+{"bgtu", "s,t,p", 0, (int) M_BGTU, INSN_MACRO, I1 },
+{"bgtu", "s,I,p", 0, (int) M_BGTU_I, INSN_MACRO, I1 },
+{"bgtul", "s,t,p", 0, (int) M_BGTUL, INSN_MACRO, I2 },
+{"bgtul", "s,I,p", 0, (int) M_BGTUL_I, INSN_MACRO, I2 },
+{"bgtz", "s,p", 0x1c000000, 0xfc1f0000, CBD|RD_s, I1 },
+{"bgtzl", "s,p", 0x5c000000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"ble", "s,t,p", 0, (int) M_BLE, INSN_MACRO, I1 },
+{"ble", "s,I,p", 0, (int) M_BLE_I, INSN_MACRO, I1 },
+{"blel", "s,t,p", 0, (int) M_BLEL, INSN_MACRO, I2 },
+{"blel", "s,I,p", 0, (int) M_BLEL_I, INSN_MACRO, I2 },
+{"bleu", "s,t,p", 0, (int) M_BLEU, INSN_MACRO, I1 },
+{"bleu", "s,I,p", 0, (int) M_BLEU_I, INSN_MACRO, I1 },
+{"bleul", "s,t,p", 0, (int) M_BLEUL, INSN_MACRO, I2 },
+{"bleul", "s,I,p", 0, (int) M_BLEUL_I, INSN_MACRO, I2 },
+{"blez", "s,p", 0x18000000, 0xfc1f0000, CBD|RD_s, I1 },
+{"blezl", "s,p", 0x58000000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"blt", "s,t,p", 0, (int) M_BLT, INSN_MACRO, I1 },
+{"blt", "s,I,p", 0, (int) M_BLT_I, INSN_MACRO, I1 },
+{"bltl", "s,t,p", 0, (int) M_BLTL, INSN_MACRO, I2 },
+{"bltl", "s,I,p", 0, (int) M_BLTL_I, INSN_MACRO, I2 },
+{"bltu", "s,t,p", 0, (int) M_BLTU, INSN_MACRO, I1 },
+{"bltu", "s,I,p", 0, (int) M_BLTU_I, INSN_MACRO, I1 },
+{"bltul", "s,t,p", 0, (int) M_BLTUL, INSN_MACRO, I2 },
+{"bltul", "s,I,p", 0, (int) M_BLTUL_I, INSN_MACRO, I2 },
+{"bltz", "s,p", 0x04000000, 0xfc1f0000, CBD|RD_s, I1 },
+{"bltzl", "s,p", 0x04020000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"bltzal", "s,p", 0x04100000, 0xfc1f0000, CBD|RD_s|WR_31, I1 },
+{"bltzall", "s,p", 0x04120000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"bnez", "s,p", 0x14000000, 0xfc1f0000, CBD|RD_s, I1 },
+{"bnezl", "s,p", 0x54000000, 0xfc1f0000, CBL|RD_s, I2|T3 },
+{"bne", "s,t,p", 0x14000000, 0xfc000000, CBD|RD_s|RD_t, I1 },
+{"bne", "s,I,p", 0, (int) M_BNE_I, INSN_MACRO, I1 },
+{"bnel", "s,t,p", 0x54000000, 0xfc000000, CBL|RD_s|RD_t, I2|T3 },
+{"bnel", "s,I,p", 0, (int) M_BNEL_I, INSN_MACRO, I2 },
+{"break", "", 0x0000000d, 0xffffffff, TRAP, I1 },
+{"break", "c", 0x0000000d, 0xfc00ffff, TRAP, I1 },
+{"break", "c,q", 0x0000000d, 0xfc00003f, TRAP, I1 },
+{"c.f.d", "S,T", 0x46200030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.f.d", "M,S,T", 0x46200030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.f.s", "S,T", 0x46000030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.f.s", "M,S,T", 0x46000030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.un.d", "S,T", 0x46200031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.un.d", "M,S,T", 0x46200031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.un.s", "S,T", 0x46000031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.un.s", "M,S,T", 0x46000031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.eq.d", "S,T", 0x46200032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.eq.d", "M,S,T", 0x46200032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.eq.s", "S,T", 0x46000032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.eq.s", "M,S,T", 0x46000032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ueq.d", "S,T", 0x46200033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ueq.d", "M,S,T", 0x46200033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ueq.s", "S,T", 0x46000033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ueq.s", "M,S,T", 0x46000033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.olt.d", "S,T", 0x46200034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.olt.d", "M,S,T", 0x46200034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.olt.s", "S,T", 0x46000034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.olt.s", "M,S,T", 0x46000034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ult.d", "S,T", 0x46200035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ult.d", "M,S,T", 0x46200035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ult.s", "S,T", 0x46000035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ult.s", "M,S,T", 0x46000035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ole.d", "S,T", 0x46200036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ole.d", "M,S,T", 0x46200036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ole.s", "S,T", 0x46000036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ole.s", "M,S,T", 0x46000036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ule.d", "S,T", 0x46200037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ule.d", "M,S,T", 0x46200037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ule.s", "S,T", 0x46000037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ule.s", "M,S,T", 0x46000037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.sf.d", "S,T", 0x46200038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.sf.d", "M,S,T", 0x46200038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.sf.s", "S,T", 0x46000038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.sf.s", "M,S,T", 0x46000038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ngle.d","S,T", 0x46200039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ngle.d","M,S,T", 0x46200039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ngle.s","S,T", 0x46000039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ngle.s","M,S,T", 0x46000039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.seq.d", "S,T", 0x4620003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.seq.d", "M,S,T", 0x4620003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.seq.s", "S,T", 0x4600003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.seq.s", "M,S,T", 0x4600003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ngl.d", "S,T", 0x4620003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ngl.d", "M,S,T", 0x4620003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ngl.s", "S,T", 0x4600003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ngl.s", "M,S,T", 0x4600003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.lt.d", "S,T", 0x4620003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.lt.d", "M,S,T", 0x4620003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.lt.s", "S,T", 0x4600003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.lt.s", "M,S,T", 0x4600003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.nge.d", "S,T", 0x4620003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.nge.d", "M,S,T", 0x4620003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.nge.s", "S,T", 0x4600003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.nge.s", "M,S,T", 0x4600003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.le.d", "S,T", 0x4620003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.le.d", "M,S,T", 0x4620003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.le.s", "S,T", 0x4600003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.le.s", "M,S,T", 0x4600003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"c.ngt.d", "S,T", 0x4620003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, I1 },
+{"c.ngt.d", "M,S,T", 0x4620003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, I4 },
+{"c.ngt.s", "S,T", 0x4600003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, I1 },
+{"c.ngt.s", "M,S,T", 0x4600003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, I4 },
+{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, I3|T3 },
+{"ceil.l.d", "D,S", 0x4620000a, 0xffff003f, WR_D|RD_S|FP_D, I3 },
+{"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S, I3 },
+{"ceil.w.d", "D,S", 0x4620000e, 0xffff003f, WR_D|RD_S|FP_D, I2 },
+{"ceil.w.s", "D,S", 0x4600000e, 0xffff003f, WR_D|RD_S|FP_S, I2 },
+{"cfc0", "t,G", 0x40400000, 0xffe007ff, LCD|WR_t|RD_C0, I1 },
+{"cfc1", "t,G", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, I1 },
+{"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, I1 },
+{"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, I1 },
+{"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, I1 },
+{"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, I1 },
+{"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, I1 },
+{"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, I1 },
+{"ctc2", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, I1 },
+{"ctc3", "t,G", 0x4cc00000, 0xffe007ff, COD|RD_t|WR_CC, I1 },
+{"cvt.d.l", "D,S", 0x46a00021, 0xffff003f, WR_D|RD_S|FP_D, I3 },
+{"cvt.d.s", "D,S", 0x46000021, 0xffff003f, WR_D|RD_S|FP_D|FP_S, I1 },
+{"cvt.d.w", "D,S", 0x46800021, 0xffff003f, WR_D|RD_S|FP_D, I1 },
+{"cvt.l.d", "D,S", 0x46200025, 0xffff003f, WR_D|RD_S|FP_D, I3 },
+{"cvt.l.s", "D,S", 0x46000025, 0xffff003f, WR_D|RD_S|FP_S, I3 },
+{"cvt.s.l", "D,S", 0x46a00020, 0xffff003f, WR_D|RD_S|FP_S, I3 },
+{"cvt.s.d", "D,S", 0x46200020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, I1 },
+{"cvt.s.w", "D,S", 0x46800020, 0xffff003f, WR_D|RD_S|FP_S, I1 },
+{"cvt.w.d", "D,S", 0x46200024, 0xffff003f, WR_D|RD_S|FP_D, I1 },
+{"cvt.w.s", "D,S", 0x46000024, 0xffff003f, WR_D|RD_S|FP_S, I1 },
+{"dabs", "d,v", 0, (int) M_DABS, INSN_MACRO, I3 },
+{"dadd", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, I3 },
+{"dadd", "t,r,I", 0, (int) M_DADD_I, INSN_MACRO, I3 },
+{"daddi", "t,r,j", 0x60000000, 0xfc000000, WR_t|RD_s, I3 },
+{"daddiu", "t,r,j", 0x64000000, 0xfc000000, WR_t|RD_s, I3 },
+{"daddu", "d,v,t", 0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t, I3 },
+{"daddu", "t,r,I", 0, (int) M_DADDU_I, INSN_MACRO, I3 },
+/* dctr and dctw are used on the r5000. */
+{"dctr", "o(b)", 0xbc050000, 0xfc1f0000, RD_b, I3 },
+{"dctw", "o(b)", 0xbc090000, 0xfc1f0000, RD_b, I3 },
+{"deret", "", 0x4200001f, 0xffffffff, 0, G2 },
+/* For ddiv, see the comments about div. */
+{"ddiv", "z,s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3 },
+{"ddiv", "d,v,t", 0, (int) M_DDIV_3, INSN_MACRO, I3 },
+{"ddiv", "d,v,I", 0, (int) M_DDIV_3I, INSN_MACRO, I3 },
+/* For ddivu, see the comments about div. */
+{"ddivu", "z,s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3 },
+{"ddivu", "d,v,t", 0, (int) M_DDIVU_3, INSN_MACRO, I3 },
+{"ddivu", "d,v,I", 0, (int) M_DDIVU_3I, INSN_MACRO, I3 },
+/* The MIPS assembler treats the div opcode with two operands as
+ though the first operand appeared twice (the first operand is both
+ a source and a destination). To get the div machine instruction,
+ you must use an explicit destination of $0. */
+{"div", "z,s,t", 0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I1 },
+{"div", "z,t", 0x0000001a, 0xffe0ffff, RD_s|RD_t|WR_HI|WR_LO, I1 },
+{"div", "d,v,t", 0, (int) M_DIV_3, INSN_MACRO, I1 },
+{"div", "d,v,I", 0, (int) M_DIV_3I, INSN_MACRO, I1 },
+{"div.d", "D,V,T", 0x46200003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I1 },
+{"div.s", "D,V,T", 0x46000003, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, I1 },
+/* For divu, see the comments about div. */
+{"divu", "z,s,t", 0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I1 },
+{"divu", "z,t", 0x0000001b, 0xffe0ffff, RD_s|RD_t|WR_HI|WR_LO, I1 },
+{"divu", "d,v,t", 0, (int) M_DIVU_3, INSN_MACRO, I1 },
+{"divu", "d,v,I", 0, (int) M_DIVU_3I, INSN_MACRO, I1 },
+{"dla", "t,A(b)", 0, (int) M_DLA_AB, INSN_MACRO, I3 },
+{"dli", "t,j", 0x24000000, 0xffe00000, WR_t, I3 }, /* addiu */
+{"dli", "t,i", 0x34000000, 0xffe00000, WR_t, I3 }, /* ori */
+{"dli", "t,I", 0, (int) M_DLI, INSN_MACRO, I3 },
+
+{"dmadd16", "s,t", 0x00000029, 0xfc00ffff, RD_s|RD_t|WR_LO|RD_LO, V1 },
+{"dmfc0", "t,G", 0x40200000, 0xffe007ff, LCD|WR_t|RD_C0, I3 },
+{"dmtc0", "t,G", 0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, I3 },
+{"dmfc1", "t,S", 0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, I3 },
+{"dmtc1", "t,S", 0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_S, I3 },
+{"dmfc2", "t,S", 0x48200000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, I3 },
+{"dmtc2", "t,S", 0x48a00000, 0xffe007ff, COD|RD_t|WR_S|FP_S, I3 },
+{"dmul", "d,v,t", 0, (int) M_DMUL, INSN_MACRO, I3 },
+{"dmul", "d,v,I", 0, (int) M_DMUL_I, INSN_MACRO, I3 },
+{"dmulo", "d,v,t", 0, (int) M_DMULO, INSN_MACRO, I3 },
+{"dmulo", "d,v,I", 0, (int) M_DMULO_I, INSN_MACRO, I3 },
+{"dmulou", "d,v,t", 0, (int) M_DMULOU, INSN_MACRO, I3 },
+{"dmulou", "d,v,I", 0, (int) M_DMULOU_I, INSN_MACRO, I3 },
+{"dmult", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3},
+{"dmultu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3},
+{"dneg", "d,w", 0x0000002e, 0xffe007ff, WR_d|RD_t, I3 }, /* dsub 0 */
+{"dnegu", "d,w", 0x0000002f, 0xffe007ff, WR_d|RD_t, I3 }, /* dsubu 0*/
+{"drem", "z,s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3 },
+{"drem", "d,v,t", 3, (int) M_DREM_3, INSN_MACRO, I3 },
+{"drem", "d,v,I", 3, (int) M_DREM_3I, INSN_MACRO, I3 },
+{"dremu", "z,s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I3 },
+{"dremu", "d,v,t", 3, (int) M_DREMU_3, INSN_MACRO, I3 },
+{"dremu", "d,v,I", 3, (int) M_DREMU_3I, INSN_MACRO, I3 },
+{"dsllv", "d,t,s", 0x00000014, 0xfc0007ff, WR_d|RD_t|RD_s, I3 },
+{"dsll32", "d,w,<", 0x0000003c, 0xffe0003f, WR_d|RD_t, I3 },
+{"dsll", "d,w,s", 0x00000014, 0xfc0007ff, WR_d|RD_t|RD_s, I3 }, /* dsllv */
+{"dsll", "d,w,>", 0x0000003c, 0xffe0003f, WR_d|RD_t, I3 }, /* dsll32 */
+{"dsll", "d,w,<", 0x00000038, 0xffe0003f, WR_d|RD_t, I3 },
+{"dsrav", "d,t,s", 0x00000017, 0xfc0007ff, WR_d|RD_t|RD_s, I3 },
+{"dsra32", "d,w,<", 0x0000003f, 0xffe0003f, WR_d|RD_t, I3 },
+{"dsra", "d,w,s", 0x00000017, 0xfc0007ff, WR_d|RD_t|RD_s, I3 }, /* dsrav */
+{"dsra", "d,w,>", 0x0000003f, 0xffe0003f, WR_d|RD_t, I3 }, /* dsra32 */
+{"dsra", "d,w,<", 0x0000003b, 0xffe0003f, WR_d|RD_t, I3 },
+{"dsrlv", "d,t,s", 0x00000016, 0xfc0007ff, WR_d|RD_t|RD_s, I3 },
+{"dsrl32", "d,w,<", 0x0000003e, 0xffe0003f, WR_d|RD_t, I3 },
+{"dsrl", "d,w,s", 0x00000016, 0xfc0007ff, WR_d|RD_t|RD_s, I3 }, /* dsrlv */
+{"dsrl", "d,w,>", 0x0000003e, 0xffe0003f, WR_d|RD_t, I3 }, /* dsrl32 */
+{"dsrl", "d,w,<", 0x0000003a, 0xffe0003f, WR_d|RD_t, I3 },
+{"dsub", "d,v,t", 0x0000002e, 0xfc0007ff, WR_d|RD_s|RD_t, I3 },
+{"dsub", "d,v,I", 0, (int) M_DSUB_I, INSN_MACRO, I3 },
+{"dsubu", "d,v,t", 0x0000002f, 0xfc0007ff, WR_d|RD_s|RD_t, I3 },
+{"dsubu", "d,v,I", 0, (int) M_DSUBU_I, INSN_MACRO, I3 },
+{"eret", "", 0x42000018, 0xffffffff, 0, I3 },
+{"floor.l.d", "D,S", 0x4620000b, 0xffff003f, WR_D|RD_S|FP_D, I3 },
+{"floor.l.s", "D,S", 0x4600000b, 0xffff003f, WR_D|RD_S|FP_S, I3 },
+{"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_D, I2 },
+{"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, I2 },
+{"flushi", "", 0xbc010000, 0xffffffff, 0, L1 },
+{"flushd", "", 0xbc020000, 0xffffffff, 0, L1 },
+{"flushid", "", 0xbc030000, 0xffffffff, 0, L1 },
+{"hibernate","", 0x42000023, 0xffffffff, 0, V1 },
+{"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, I1 },
+{"j", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, I1 }, /* jr */
+/* SVR4 PIC code requires special handling for j, so it must be a
+ macro. */
+{"j", "a", 0, (int) M_J_A, INSN_MACRO, I1 },
+/* This form of j is used by the disassembler and internally by the
+ assembler, but will never match user input (because the line above
+ will match first). */
+{"j", "a", 0x08000000, 0xfc000000, UBD, I1 },
+{"jalr", "s", 0x0000f809, 0xfc1fffff, UBD|RD_s|WR_d, I1 },
+{"jalr", "d,s", 0x00000009, 0xfc1f07ff, UBD|RD_s|WR_d, I1 },
+/* SVR4 PIC code requires special handling for jal, so it must be a
+ macro. */
+{"jal", "d,s", 0, (int) M_JAL_2, INSN_MACRO, I1 },
+{"jal", "s", 0, (int) M_JAL_1, INSN_MACRO, I1 },
+{"jal", "a", 0, (int) M_JAL_A, INSN_MACRO, I1 },
+/* This form of jal is used by the disassembler and internally by the
+ assembler, but will never match user input (because the line above
+ will match first). */
+{"jal", "a", 0x0c000000, 0xfc000000, UBD|WR_31, I1 },
+ /* jalx really should only be avaliable if mips16 is available,
+ but for now make it I1. */
+{"jalx", "a", 0x74000000, 0xfc000000, UBD|WR_31, I1 },
+{"la", "t,A(b)", 0, (int) M_LA_AB, INSN_MACRO, I1 },
+{"lb", "t,o(b)", 0x80000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lb", "t,A(b)", 0, (int) M_LB_AB, INSN_MACRO, I1 },
+{"lbu", "t,o(b)", 0x90000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lbu", "t,A(b)", 0, (int) M_LBU_AB, INSN_MACRO, I1 },
+{"ld", "t,o(b)", 0xdc000000, 0xfc000000, WR_t|RD_b, I3 },
+{"ld", "t,o(b)", 0, (int) M_LD_OB, INSN_MACRO, I1 },
+{"ld", "t,A(b)", 0, (int) M_LD_AB, INSN_MACRO, I1 },
+{"ldc1", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, I2 },
+{"ldc1", "E,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, I2 },
+{"ldc1", "T,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, I2 },
+{"ldc1", "E,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, I2 },
+{"l.d", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, I2 }, /* ldc1 */
+{"l.d", "T,o(b)", 0, (int) M_L_DOB, INSN_MACRO, I1 },
+{"l.d", "T,A(b)", 0, (int) M_L_DAB, INSN_MACRO, I1 },
+{"ldc2", "E,o(b)", 0xd8000000, 0xfc000000, CLD|RD_b|WR_CC, I2 },
+{"ldc2", "E,A(b)", 0, (int) M_LDC2_AB, INSN_MACRO, I2 },
+{"ldc3", "E,o(b)", 0xdc000000, 0xfc000000, CLD|RD_b|WR_CC, I2 },
+{"ldc3", "E,A(b)", 0, (int) M_LDC3_AB, INSN_MACRO, I2 },
+{"ldl", "t,o(b)", 0x68000000, 0xfc000000, LDD|WR_t|RD_b, I3 },
+{"ldl", "t,A(b)", 0, (int) M_LDL_AB, INSN_MACRO, I3 },
+{"ldr", "t,o(b)", 0x6c000000, 0xfc000000, LDD|WR_t|RD_b, I3 },
+{"ldr", "t,A(b)", 0, (int) M_LDR_AB, INSN_MACRO, I3 },
+{"ldxc1", "D,t(b)", 0x4c000001, 0xfc00f83f, LDD|WR_D|RD_t|RD_b, I4 },
+{"lh", "t,o(b)", 0x84000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lh", "t,A(b)", 0, (int) M_LH_AB, INSN_MACRO, I1 },
+{"lhu", "t,o(b)", 0x94000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lhu", "t,A(b)", 0, (int) M_LHU_AB, INSN_MACRO, I1 },
+/* li is at the start of the table. */
+{"li.d", "t,F", 0, (int) M_LI_D, INSN_MACRO, I1 },
+{"li.d", "T,L", 0, (int) M_LI_DD, INSN_MACRO, I1 },
+{"li.s", "t,f", 0, (int) M_LI_S, INSN_MACRO, I1 },
+{"li.s", "T,l", 0, (int) M_LI_SS, INSN_MACRO, I1 },
+{"ll", "t,o(b)", 0xc0000000, 0xfc000000, LDD|RD_b|WR_t, I2 },
+{"ll", "t,A(b)", 0, (int) M_LL_AB, INSN_MACRO, I2 },
+{"lld", "t,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, I3 },
+{"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, I3 },
+{"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, I1 },
+{"lw", "t,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lw", "t,A(b)", 0, (int) M_LW_AB, INSN_MACRO, I1 },
+{"lwc0", "E,o(b)", 0xc0000000, 0xfc000000, CLD|RD_b|WR_CC, I1 },
+{"lwc0", "E,A(b)", 0, (int) M_LWC0_AB, INSN_MACRO, I1 },
+{"lwc1", "T,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, I1 },
+{"lwc1", "E,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, I1 },
+{"lwc1", "T,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, I1 },
+{"lwc1", "E,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, I1 },
+{"l.s", "T,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, I1 }, /* lwc1 */
+{"l.s", "T,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, I1 },
+{"lwc2", "E,o(b)", 0xc8000000, 0xfc000000, CLD|RD_b|WR_CC, I1 },
+{"lwc2", "E,A(b)", 0, (int) M_LWC2_AB, INSN_MACRO, I1 },
+{"lwc3", "E,o(b)", 0xcc000000, 0xfc000000, CLD|RD_b|WR_CC, I1 },
+{"lwc3", "E,A(b)", 0, (int) M_LWC3_AB, INSN_MACRO, I1 },
+{"lwl", "t,o(b)", 0x88000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lwl", "t,A(b)", 0, (int) M_LWL_AB, INSN_MACRO, I1 },
+{"lcache", "t,o(b)", 0x88000000, 0xfc000000, LDD|RD_b|WR_t, I2 }, /* same */
+{"lcache", "t,A(b)", 0, (int) M_LWL_AB, INSN_MACRO, I2 }, /* as lwl */
+{"lwr", "t,o(b)", 0x98000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
+{"lwr", "t,A(b)", 0, (int) M_LWR_AB, INSN_MACRO, I1 },
+{"flush", "t,o(b)", 0x98000000, 0xfc000000, LDD|RD_b|WR_t, I2 }, /* same */
+{"flush", "t,A(b)", 0, (int) M_LWR_AB, INSN_MACRO, I2 }, /* as lwr */
+{"lwu", "t,o(b)", 0x9c000000, 0xfc000000, LDD|RD_b|WR_t, I3 },
+{"lwu", "t,A(b)", 0, (int) M_LWU_AB, INSN_MACRO, I3 },
+{"lwxc1", "D,t(b)", 0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b, I4 },
+
+
+{"mad", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P3 },
+{"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, P3 },
+{"madd.d", "D,R,S,T", 0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4 },
+{"madd.s", "D,R,S,T", 0x4c000020, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4 },
+{"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, L1 },
+{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|IS_M, G1 },
+{"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HI|WR_LO|WR_d|IS_M, G1 },
+{"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, L1 },
+{"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|IS_M, G1},
+{"maddu", "d,s,t", 0x70000001, 0xfc0007ff, RD_s|RD_t|WR_HI|WR_LO|WR_d|IS_M, G1},
+{"madd16", "s,t", 0x00000028, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|RD_HI|RD_LO, V1 },
+{"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, I1 },
+{"mfc1", "t,S", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, I1 },
+{"mfc1", "t,G", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, I1 },
+{"mfc2", "t,G", 0x48000000, 0xffe007ff, LCD|WR_t|RD_C2, I1 },
+{"mfc3", "t,G", 0x4c000000, 0xffe007ff, LCD|WR_t|RD_C3, I1 },
+{"mfhi", "d", 0x00000010, 0xffff07ff, WR_d|RD_HI, I1 },
+{"mflo", "d", 0x00000012, 0xffff07ff, WR_d|RD_LO, I1 },
+{"mov.d", "D,S", 0x46200006, 0xffff003f, WR_D|RD_S|FP_D, I1 },
+{"mov.s", "D,S", 0x46000006, 0xffff003f, WR_D|RD_S|FP_S, I1 },
+{"movf", "d,s,N", 0x00000001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_D|FP_S, I4 },
+{"movf.d", "D,S,N", 0x46200011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, I4 },
+{"movf.s", "D,S,N", 0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, I4 },
+{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, I4 },
+{"ffc", "d,v", 0x0000000b, 0xfc1f07ff, WR_d|RD_s,L1 },
+{"movn.d", "D,S,t", 0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, I4 },
+{"movn.s", "D,S,t", 0x46000013, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, I4 },
+{"movt", "d,s,N", 0x00010001, 0xfc0307ff, WR_d|RD_s|RD_CC, I4 },
+{"movt.d", "D,S,N", 0x46210011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, I4 },
+{"movt.s", "D,S,N", 0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, I4 },
+{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, I4 },
+{"ffs", "d,v", 0x0000000a, 0xfc1f07ff, WR_d|RD_s,L1 },
+{"movz.d", "D,S,t", 0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, I4 },
+{"movz.s", "D,S,t", 0x46000012, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, I4 },
+/* move is at the top of the table. */
+{"msub.d", "D,R,S,T", 0x4c000029, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4 },
+{"msub.s", "D,R,S,T", 0x4c000028, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4 },
+{"msub", "s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO,L1 },
+{"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO,L1 },
+{"mtc0", "t,G", 0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, I1 },
+{"mtc1", "t,S", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, I1 },
+{"mtc1", "t,G", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, I1 },
+{"mtc2", "t,G", 0x48800000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, I1 },
+{"mtc3", "t,G", 0x4c800000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, I1 },
+{"mthi", "s", 0x00000011, 0xfc1fffff, RD_s|WR_HI, I1 },
+{"mtlo", "s", 0x00000013, 0xfc1fffff, RD_s|WR_LO, I1 },
+{"mul.d", "D,V,T", 0x46200002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I1 },
+{"mul.s", "D,V,T", 0x46000002, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, I1 },
+{"mul", "d,v,t", 0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HI|WR_LO,P3},
+{"mul", "d,v,t", 0, (int) M_MUL, INSN_MACRO, I1 },
+{"mul", "d,v,I", 0, (int) M_MUL_I, INSN_MACRO, I1 },
+{"mulo", "d,v,t", 0, (int) M_MULO, INSN_MACRO, I1 },
+{"mulo", "d,v,I", 0, (int) M_MULO_I, INSN_MACRO, I1 },
+{"mulou", "d,v,t", 0, (int) M_MULOU, INSN_MACRO, I1 },
+{"mulou", "d,v,I", 0, (int) M_MULOU_I, INSN_MACRO, I1 },
+{"mult", "s,t", 0x00000018, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|IS_M, I1},
+{"mult", "d,s,t", 0x00000018, 0xfc0007ff, RD_s|RD_t|WR_HI|WR_LO|WR_d|IS_M, G1},
+{"multu", "s,t", 0x00000019, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO|IS_M, I1},
+{"multu", "d,s,t", 0x00000019, 0xfc0007ff, RD_s|RD_t|WR_HI|WR_LO|WR_d|IS_M, G1},
+{"neg", "d,w", 0x00000022, 0xffe007ff, WR_d|RD_t, I1 }, /* sub 0 */
+{"negu", "d,w", 0x00000023, 0xffe007ff, WR_d|RD_t, I1 }, /* subu 0 */
+{"neg.d", "D,V", 0x46200007, 0xffff003f, WR_D|RD_S|FP_D, I1 },
+{"neg.s", "D,V", 0x46000007, 0xffff003f, WR_D|RD_S|FP_S, I1 },
+{"nmadd.d", "D,R,S,T", 0x4c000031, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4 },
+{"nmadd.s", "D,R,S,T", 0x4c000030, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4 },
+{"nmsub.d", "D,R,S,T", 0x4c000039, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, I4 },
+{"nmsub.s", "D,R,S,T", 0x4c000038, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, I4 },
+/* nop is at the start of the table. */
+{"nor", "d,v,t", 0x00000027, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"nor", "t,r,I", 0, (int) M_NOR_I, INSN_MACRO, I1 },
+{"not", "d,v", 0x00000027, 0xfc1f07ff, WR_d|RD_s|RD_t, I1 },/*nor d,s,0*/
+{"or", "d,v,t", 0x00000025, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"or", "t,r,I", 0, (int) M_OR_I, INSN_MACRO, I1 },
+{"ori", "t,r,i", 0x34000000, 0xfc000000, WR_t|RD_s, I1 },
+
+
+{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, G3 },
+{"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, I4 },
+
+
+{"recip.d", "D,S", 0x46200015, 0xffff003f, WR_D|RD_S|FP_D, I4 },
+{"recip.s", "D,S", 0x46000015, 0xffff003f, WR_D|RD_S|FP_S, I4 },
+{"rem", "z,s,t", 0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I1 },
+{"rem", "d,v,t", 0, (int) M_REM_3, INSN_MACRO, I1 },
+{"rem", "d,v,I", 0, (int) M_REM_3I, INSN_MACRO, I1 },
+{"remu", "z,s,t", 0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HI|WR_LO, I1 },
+{"remu", "d,v,t", 0, (int) M_REMU_3, INSN_MACRO, I1 },
+{"remu", "d,v,I", 0, (int) M_REMU_3I, INSN_MACRO, I1 },
+{"rfe", "", 0x42000010, 0xffffffff, 0, I1|T3 },
+{"rol", "d,v,t", 0, (int) M_ROL, INSN_MACRO, I1 },
+{"rol", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, I1 },
+{"ror", "d,v,t", 0, (int) M_ROR, INSN_MACRO, I1 },
+{"ror", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, I1 },
+{"round.l.d", "D,S", 0x46200008, 0xffff003f, WR_D|RD_S|FP_D, I3 },
+{"round.l.s", "D,S", 0x46000008, 0xffff003f, WR_D|RD_S|FP_S, I3 },
+{"round.w.d", "D,S", 0x4620000c, 0xffff003f, WR_D|RD_S|FP_D, I2 },
+{"round.w.s", "D,S", 0x4600000c, 0xffff003f, WR_D|RD_S|FP_S, I2 },
+{"rsqrt.d", "D,S", 0x46200016, 0xffff003f, WR_D|RD_S|FP_D, I4 },
+{"rsqrt.s", "D,S", 0x46000016, 0xffff003f, WR_D|RD_S|FP_S, I4 },
+{"sb", "t,o(b)", 0xa0000000, 0xfc000000, SM|RD_t|RD_b, I1 },
+{"sb", "t,A(b)", 0, (int) M_SB_AB, INSN_MACRO, I1 },
+{"sc", "t,o(b)", 0xe0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, I2 },
+{"sc", "t,A(b)", 0, (int) M_SC_AB, INSN_MACRO, I2 },
+{"scd", "t,o(b)", 0xf0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, I3 },
+{"scd", "t,A(b)", 0, (int) M_SCD_AB, INSN_MACRO, I3 },
+{"sd", "t,o(b)", 0xfc000000, 0xfc000000, SM|RD_t|RD_b, I3 },
+{"sd", "t,o(b)", 0, (int) M_SD_OB, INSN_MACRO, I1 },
+{"sd", "t,A(b)", 0, (int) M_SD_AB, INSN_MACRO, I1 },
+{"sdbbp", "", 0x0000000e, 0xffffffff, TRAP, G2 },
+{"sdbbp", "c", 0x0000000e, 0xfc00ffff, TRAP, G2 },
+{"sdbbp", "c,q", 0x0000000e, 0xfc00003f, TRAP, G2 },
+{"sdc1", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, I2 },
+{"sdc1", "E,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, I2 },
+{"sdc1", "T,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, I2 },
+{"sdc1", "E,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, I2 },
+{"sdc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, I2 },
+{"sdc2", "E,A(b)", 0, (int) M_SDC2_AB, INSN_MACRO, I2 },
+{"sdc3", "E,o(b)", 0xfc000000, 0xfc000000, SM|RD_C3|RD_b, I2 },
+{"sdc3", "E,A(b)", 0, (int) M_SDC3_AB, INSN_MACRO, I2 },
+{"s.d", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, I2 },
+{"s.d", "T,o(b)", 0, (int) M_S_DOB, INSN_MACRO, I1 },
+{"s.d", "T,A(b)", 0, (int) M_S_DAB, INSN_MACRO, I1 },
+{"sdl", "t,o(b)", 0xb0000000, 0xfc000000, SM|RD_t|RD_b, I3 },
+{"sdl", "t,A(b)", 0, (int) M_SDL_AB, INSN_MACRO, I3 },
+{"sdr", "t,o(b)", 0xb4000000, 0xfc000000, SM|RD_t|RD_b, I3 },
+{"sdr", "t,A(b)", 0, (int) M_SDR_AB, INSN_MACRO, I3 },
+{"sdxc1", "S,t(b)", 0x4c000009, 0xfc0007ff, SM|RD_S|RD_t|RD_b, I4 },
+{"selsl", "d,v,t", 0x00000005, 0xfc0007ff, WR_d|RD_s|RD_t,L1 },
+{"selsr", "d,v,t", 0x00000001, 0xfc0007ff, WR_d|RD_s|RD_t,L1 },
+{"seq", "d,v,t", 0, (int) M_SEQ, INSN_MACRO, I1 },
+{"seq", "d,v,I", 0, (int) M_SEQ_I, INSN_MACRO, I1 },
+{"sge", "d,v,t", 0, (int) M_SGE, INSN_MACRO, I1 },
+{"sge", "d,v,I", 0, (int) M_SGE_I, INSN_MACRO, I1 },
+{"sgeu", "d,v,t", 0, (int) M_SGEU, INSN_MACRO, I1 },
+{"sgeu", "d,v,I", 0, (int) M_SGEU_I, INSN_MACRO, I1 },
+{"sgt", "d,v,t", 0, (int) M_SGT, INSN_MACRO, I1 },
+{"sgt", "d,v,I", 0, (int) M_SGT_I, INSN_MACRO, I1 },
+{"sgtu", "d,v,t", 0, (int) M_SGTU, INSN_MACRO, I1 },
+{"sgtu", "d,v,I", 0, (int) M_SGTU_I, INSN_MACRO, I1 },
+{"sh", "t,o(b)", 0xa4000000, 0xfc000000, SM|RD_t|RD_b, I1 },
+{"sh", "t,A(b)", 0, (int) M_SH_AB, INSN_MACRO, I1 },
+{"sle", "d,v,t", 0, (int) M_SLE, INSN_MACRO, I1 },
+{"sle", "d,v,I", 0, (int) M_SLE_I, INSN_MACRO, I1 },
+{"sleu", "d,v,t", 0, (int) M_SLEU, INSN_MACRO, I1 },
+{"sleu", "d,v,I", 0, (int) M_SLEU_I, INSN_MACRO, I1 },
+{"sllv", "d,t,s", 0x00000004, 0xfc0007ff, WR_d|RD_t|RD_s, I1 },
+{"sll", "d,w,s", 0x00000004, 0xfc0007ff, WR_d|RD_t|RD_s, I1 }, /* sllv */
+{"sll", "d,w,<", 0x00000000, 0xffe0003f, WR_d|RD_t, I1 },
+{"slt", "d,v,t", 0x0000002a, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"slt", "d,v,I", 0, (int) M_SLT_I, INSN_MACRO, I1 },
+{"slti", "t,r,j", 0x28000000, 0xfc000000, WR_t|RD_s, I1 },
+{"sltiu", "t,r,j", 0x2c000000, 0xfc000000, WR_t|RD_s, I1 },
+{"sltu", "d,v,t", 0x0000002b, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"sltu", "d,v,I", 0, (int) M_SLTU_I, INSN_MACRO, I1 },
+{"sne", "d,v,t", 0, (int) M_SNE, INSN_MACRO, I1 },
+{"sne", "d,v,I", 0, (int) M_SNE_I, INSN_MACRO, I1 },
+{"sqrt.d", "D,S", 0x46200004, 0xffff003f, WR_D|RD_S|FP_D, I2 },
+{"sqrt.s", "D,S", 0x46000004, 0xffff003f, WR_D|RD_S|FP_S, I2 },
+{"srav", "d,t,s", 0x00000007, 0xfc0007ff, WR_d|RD_t|RD_s, I1 },
+{"sra", "d,w,s", 0x00000007, 0xfc0007ff, WR_d|RD_t|RD_s, I1 }, /* srav */
+{"sra", "d,w,<", 0x00000003, 0xffe0003f, WR_d|RD_t, I1 },
+{"srlv", "d,t,s", 0x00000006, 0xfc0007ff, WR_d|RD_t|RD_s, I1 },
+{"srl", "d,w,s", 0x00000006, 0xfc0007ff, WR_d|RD_t|RD_s, I1 }, /* srlv */
+{"srl", "d,w,<", 0x00000002, 0xffe0003f, WR_d|RD_t, I1 },
+{"standby", "", 0x42000021, 0xffffffff, 0, V1 },
+{"sub", "d,v,t", 0x00000022, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"sub", "d,v,I", 0, (int) M_SUB_I, INSN_MACRO, I1 },
+{"sub.d", "D,V,T", 0x46200001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, I1 },
+{"sub.s", "D,V,T", 0x46000001, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, I1 },
+{"subu", "d,v,t", 0x00000023, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"subu", "d,v,I", 0, (int) M_SUBU_I, INSN_MACRO, I1 },
+{"suspend", "", 0x42000022, 0xffffffff, 0, V1 },
+{"sw", "t,o(b)", 0xac000000, 0xfc000000, SM|RD_t|RD_b, I1 },
+{"sw", "t,A(b)", 0, (int) M_SW_AB, INSN_MACRO, I1 },
+{"swc0", "E,o(b)", 0xe0000000, 0xfc000000, SM|RD_C0|RD_b, I1 },
+{"swc0", "E,A(b)", 0, (int) M_SWC0_AB, INSN_MACRO, I1 },
+{"swc1", "T,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, I1 },
+{"swc1", "E,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, I1 },
+{"swc1", "T,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, I1 },
+{"swc1", "E,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, I1 },
+{"s.s", "T,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, I1 }, /* swc1 */
+{"s.s", "T,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, I1 },
+{"swc2", "E,o(b)", 0xe8000000, 0xfc000000, SM|RD_C2|RD_b, I1 },
+{"swc2", "E,A(b)", 0, (int) M_SWC2_AB, INSN_MACRO, I1 },
+{"swc3", "E,o(b)", 0xec000000, 0xfc000000, SM|RD_C3|RD_b, I1 },
+{"swc3", "E,A(b)", 0, (int) M_SWC3_AB, INSN_MACRO, I1 },
+{"swl", "t,o(b)", 0xa8000000, 0xfc000000, SM|RD_t|RD_b, I1 },
+{"swl", "t,A(b)", 0, (int) M_SWL_AB, INSN_MACRO, I1 },
+{"scache", "t,o(b)", 0xa8000000, 0xfc000000, RD_t|RD_b, I2 }, /* same */
+{"scache", "t,A(b)", 0, (int) M_SWL_AB, INSN_MACRO, I2 }, /* as swl */
+{"swr", "t,o(b)", 0xb8000000, 0xfc000000, SM|RD_t|RD_b, I1 },
+{"swr", "t,A(b)", 0, (int) M_SWR_AB, INSN_MACRO, I1 },
+{"invalidate", "t,o(b)",0xb8000000, 0xfc000000, RD_t|RD_b, I2 }, /* same */
+{"invalidate", "t,A(b)",0, (int) M_SWR_AB, INSN_MACRO, I2 }, /* as swr */
+{"swxc1", "S,t(b)", 0x4c000008, 0xfc0007ff, SM|RD_S|RD_t|RD_b, I4 },
+{"sync", "", 0x0000000f, 0xffffffff, INSN_SYNC, I2|G1 },
+{"sync.p", "", 0x0000040f, 0xffffffff, INSN_SYNC, I2 },
+{"sync.l", "", 0x0000000f, 0xffffffff, INSN_SYNC, I2 },
+{"syscall", "", 0x0000000c, 0xffffffff, TRAP, I1 },
+{"syscall", "B", 0x0000000c, 0xfc00003f, TRAP, I1 },
+{"teqi", "s,j", 0x040c0000, 0xfc1f0000, RD_s|TRAP, I2 },
+{"teq", "s,t", 0x00000034, 0xfc00ffff, RD_s|RD_t|TRAP, I2 },
+{"teq", "s,t,q", 0x00000034, 0xfc00003f, RD_s|RD_t|TRAP, I2 },
+{"teq", "s,j", 0x040c0000, 0xfc1f0000, RD_s|TRAP, I2 }, /* teqi */
+{"teq", "s,I", 0, (int) M_TEQ_I, INSN_MACRO, I2 },
+{"tgei", "s,j", 0x04080000, 0xfc1f0000, RD_s|TRAP, I2 },
+{"tge", "s,t", 0x00000030, 0xfc00ffff, RD_s|RD_t|TRAP, I2 },
+{"tge", "s,t,q", 0x00000030, 0xfc00003f, RD_s|RD_t|TRAP, I2 },
+{"tge", "s,j", 0x04080000, 0xfc1f0000, RD_s|TRAP, I2 }, /* tgei */
+{"tge", "s,I", 0, (int) M_TGE_I, INSN_MACRO, I2 },
+{"tgeiu", "s,j", 0x04090000, 0xfc1f0000, RD_s|TRAP, I2 },
+{"tgeu", "s,t", 0x00000031, 0xfc00ffff, RD_s|RD_t|TRAP, I2 },
+{"tgeu", "s,t,q", 0x00000031, 0xfc00003f, RD_s|RD_t|TRAP, I2 },
+{"tgeu", "s,j", 0x04090000, 0xfc1f0000, RD_s|TRAP, I2 }, /* tgeiu */
+{"tgeu", "s,I", 0, (int) M_TGEU_I, INSN_MACRO, I2 },
+{"tlbp", "", 0x42000008, 0xffffffff, INSN_TLB, I1 },
+{"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, I1 },
+{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, I1 },
+{"tlbwr", "", 0x42000006, 0xffffffff, INSN_TLB, I1 },
+{"tlti", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, I2 },
+{"tlt", "s,t", 0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP, I2 },
+{"tlt", "s,t,q", 0x00000032, 0xfc00003f, RD_s|RD_t|TRAP, I2 },
+{"tlt", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, I2 }, /* tlti */
+{"tlt", "s,I", 0, (int) M_TLT_I, INSN_MACRO, I2 },
+{"tltiu", "s,j", 0x040b0000, 0xfc1f0000, RD_s|TRAP, I2 },
+{"tltu", "s,t", 0x00000033, 0xfc00ffff, RD_s|RD_t|TRAP, I2 },
+{"tltu", "s,t,q", 0x00000033, 0xfc00003f, RD_s|RD_t|TRAP, I2 },
+{"tltu", "s,j", 0x040b0000, 0xfc1f0000, RD_s|TRAP, I2 }, /* tltiu */
+{"tltu", "s,I", 0, (int) M_TLTU_I, INSN_MACRO, I2 },
+{"tnei", "s,j", 0x040e0000, 0xfc1f0000, RD_s|TRAP, I2 },
+{"tne", "s,t", 0x00000036, 0xfc00ffff, RD_s|RD_t|TRAP, I2 },
+{"tne", "s,t,q", 0x00000036, 0xfc00003f, RD_s|RD_t|TRAP, I2 },
+{"tne", "s,j", 0x040e0000, 0xfc1f0000, RD_s|TRAP, I2 }, /* tnei */
+{"tne", "s,I", 0, (int) M_TNE_I, INSN_MACRO, I2 },
+{"trunc.l.d", "D,S", 0x46200009, 0xffff003f, WR_D|RD_S|FP_D, I3 },
+{"trunc.l.s", "D,S", 0x46000009, 0xffff003f, WR_D|RD_S|FP_S, I3 },
+{"trunc.w.d", "D,S", 0x4620000d, 0xffff003f, WR_D|RD_S|FP_D, I2 },
+{"trunc.w.d", "D,S,x", 0x4620000d, 0xffff003f, WR_D|RD_S|FP_D, I2 },
+{"trunc.w.d", "D,S,t", 0, (int) M_TRUNCWD, INSN_MACRO, I1 },
+{"trunc.w.s", "D,S", 0x4600000d, 0xffff003f, WR_D|RD_S|FP_S, I2 },
+{"trunc.w.s", "D,S,x", 0x4600000d, 0xffff003f, WR_D|RD_S|FP_S, I2 },
+{"trunc.w.s", "D,S,t", 0, (int) M_TRUNCWS, INSN_MACRO, I1 },
+{"uld", "t,o(b)", 0, (int) M_ULD, INSN_MACRO, I3 },
+{"uld", "t,A(b)", 0, (int) M_ULD_A, INSN_MACRO, I3 },
+{"ulh", "t,o(b)", 0, (int) M_ULH, INSN_MACRO, I1 },
+{"ulh", "t,A(b)", 0, (int) M_ULH_A, INSN_MACRO, I1 },
+{"ulhu", "t,o(b)", 0, (int) M_ULHU, INSN_MACRO, I1 },
+{"ulhu", "t,A(b)", 0, (int) M_ULHU_A, INSN_MACRO, I1 },
+{"ulw", "t,o(b)", 0, (int) M_ULW, INSN_MACRO, I1 },
+{"ulw", "t,A(b)", 0, (int) M_ULW_A, INSN_MACRO, I1 },
+{"usd", "t,o(b)", 0, (int) M_USD, INSN_MACRO, I3 },
+{"usd", "t,A(b)", 0, (int) M_USD_A, INSN_MACRO, I3 },
+{"ush", "t,o(b)", 0, (int) M_USH, INSN_MACRO, I1 },
+{"ush", "t,A(b)", 0, (int) M_USH_A, INSN_MACRO, I1 },
+{"usw", "t,o(b)", 0, (int) M_USW, INSN_MACRO, I1 },
+{"usw", "t,A(b)", 0, (int) M_USW_A, INSN_MACRO, I1 },
+{"xor", "d,v,t", 0x00000026, 0xfc0007ff, WR_d|RD_s|RD_t, I1 },
+{"xor", "t,r,I", 0, (int) M_XOR_I, INSN_MACRO, I1 },
+{"xori", "t,r,i", 0x38000000, 0xfc000000, WR_t|RD_s, I1 },
+{"wait", "", 0x42000020, 0xffffffff, TRAP, I3 },
+{"waiti", "", 0x42000020, 0xffffffff, TRAP, L1 },
+{"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, L1 },
+/* No hazard protection on coprocessor instructions--they shouldn't
+ change the state of the processor and if they do it's up to the
+ user to put in nops as necessary. These are at the end so that the
+ disasembler recognizes more specific versions first. */
+{"c0", "C", 0x42000000, 0xfe000000, 0, I1 },
+{"c1", "C", 0x46000000, 0xfe000000, 0, I1 },
+{"c2", "C", 0x4a000000, 0xfe000000, 0, I1 },
+{"c3", "C", 0x4e000000, 0xfe000000, 0, I1 },
+{"cop0", "C", 0, (int) M_COP0, INSN_MACRO, I1 },
+{"cop1", "C", 0, (int) M_COP1, INSN_MACRO, I1 },
+{"cop2", "C", 0, (int) M_COP2, INSN_MACRO, I1 },
+{"cop3", "C", 0, (int) M_COP3, INSN_MACRO, I1 },
+
+ /* Conflicts with the 4650's "mul" instruction. Nobody's using the
+ 4010 any more, so move this insn out of the way. If the object
+ format gave us more info, we could do this right. */
+{"addciu", "t,r,j", 0x70000000, 0xfc000000, WR_t|RD_s,L1 },
+};
+
+#define MIPS_NUM_OPCODES \
+ ((sizeof mips_builtin_opcodes) / (sizeof (mips_builtin_opcodes[0])))
+const int bfd_mips_num_builtin_opcodes = MIPS_NUM_OPCODES;
+
+/* const removed from the following to allow for dynamic extensions to the
+ * built-in instruction set. */
+struct mips_opcode *mips_opcodes =
+ (struct mips_opcode *) mips_builtin_opcodes;
+int bfd_mips_num_opcodes = MIPS_NUM_OPCODES;
+#undef MIPS_NUM_OPCODES
+
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
new file mode 100644
index 00000000000..dad2dbb2e5a
--- /dev/null
+++ b/opcodes/mips16-opc.c
@@ -0,0 +1,226 @@
+/* mips16-opc.c. Mips16 opcode table.
+ Copyright 1996, 1997 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/mips.h"
+
+/* This is the opcodes table for the mips16 processor. The format of
+ this table is intentionally identical to the one in mips-opc.c.
+ However, the special letters that appear in the argument string are
+ different, and the table uses some different flags. */
+
+/* Use some short hand macros to keep down the length of the lines in
+ the opcodes table. */
+
+#define UBD INSN_UNCOND_BRANCH_DELAY
+#define BR MIPS16_INSN_BRANCH
+
+#define WR_x MIPS16_INSN_WRITE_X
+#define WR_y MIPS16_INSN_WRITE_Y
+#define WR_z MIPS16_INSN_WRITE_Z
+#define WR_T MIPS16_INSN_WRITE_T
+#define WR_SP MIPS16_INSN_WRITE_SP
+#define WR_31 MIPS16_INSN_WRITE_31
+#define WR_Y MIPS16_INSN_WRITE_GPR_Y
+
+#define RD_x MIPS16_INSN_READ_X
+#define RD_y MIPS16_INSN_READ_Y
+#define RD_Z MIPS16_INSN_READ_Z
+#define RD_T MIPS16_INSN_READ_T
+#define RD_SP MIPS16_INSN_READ_SP
+#define RD_31 MIPS16_INSN_READ_31
+#define RD_PC MIPS16_INSN_READ_PC
+#define RD_X MIPS16_INSN_READ_GPR_X
+
+#define WR_HI INSN_WRITE_HI
+#define WR_LO INSN_WRITE_LO
+#define RD_HI INSN_READ_HI
+#define RD_LO INSN_READ_LO
+
+#define TRAP INSN_TRAP
+
+#define I3 INSN_ISA3
+
+#define T3 INSN_3900
+
+const struct mips_opcode mips16_opcodes[] = {
+{"nop", "", 0x6500, 0xffff, RD_Z }, /* move $0,$Z */
+{"la", "x,A", 0x0800, 0xf800, WR_x|RD_PC },
+{"abs", "x,w", 0, (int) M_ABS, INSN_MACRO },
+{"addiu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x },
+{"addiu", "x,k", 0x4800, 0xf800, WR_x|RD_x },
+{"addiu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP },
+{"addiu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP },
+{"addiu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC },
+{"addiu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP },
+{"addu", "z,v,y", 0xe001, 0xf803, WR_z|RD_x|RD_y },
+{"addu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x },
+{"addu", "x,k", 0x4800, 0xf800, WR_x|RD_x },
+{"addu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP },
+{"addu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP },
+{"addu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC },
+{"addu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP },
+{"and", "x,y", 0xe80c, 0xf81f, WR_x|RD_x|RD_y },
+{"b", "q", 0x1000, 0xf800, BR},
+{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO },
+{"beq", "x,U,p", 0, (int) M_BEQ_I, INSN_MACRO },
+{"beqz", "x,p", 0x2000, 0xf800, BR|RD_x },
+{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO },
+{"bge", "x,8,p", 0, (int) M_BGE_I, INSN_MACRO },
+{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO },
+{"bgeu", "x,8,p", 0, (int) M_BGEU_I, INSN_MACRO },
+{"bgt", "x,y,p", 0, (int) M_BGT, INSN_MACRO },
+{"bgt", "x,8,p", 0, (int) M_BGT_I, INSN_MACRO },
+{"bgtu", "x,y,p", 0, (int) M_BGTU, INSN_MACRO },
+{"bgtu", "x,8,p", 0, (int) M_BGTU_I, INSN_MACRO },
+{"ble", "x,y,p", 0, (int) M_BLE, INSN_MACRO },
+{"ble", "x,8,p", 0, (int) M_BLE_I, INSN_MACRO },
+{"bleu", "x,y,p", 0, (int) M_BLEU, INSN_MACRO },
+{"bleu", "x,8,p", 0, (int) M_BLEU_I, INSN_MACRO },
+{"blt", "x,y,p", 0, (int) M_BLT, INSN_MACRO },
+{"blt", "x,8,p", 0, (int) M_BLT_I, INSN_MACRO },
+{"bltu", "x,y,p", 0, (int) M_BLTU, INSN_MACRO },
+{"bltu", "x,8,p", 0, (int) M_BLTU_I, INSN_MACRO },
+{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO },
+{"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO },
+{"bnez", "x,p", 0x2800, 0xf800, BR|RD_x },
+{"break", "6", 0xe805, 0xf81f, TRAP },
+{"bteqz", "p", 0x6000, 0xff00, BR|RD_T },
+{"btnez", "p", 0x6100, 0xff00, BR|RD_T },
+{"cmpi", "x,U", 0x7000, 0xf800, WR_T|RD_x },
+{"cmp", "x,y", 0xe80a, 0xf81f, WR_T|RD_x|RD_y },
+{"cmp", "x,U", 0x7000, 0xf800, WR_T|RD_x },
+{"dla", "y,E", 0xfe00, 0xff00, WR_y|RD_PC, I3 },
+{"daddiu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, I3 },
+{"daddiu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, I3 },
+{"daddiu", "S,K", 0xfb00, 0xff00, WR_SP|RD_SP, I3 },
+{"daddiu", "S,S,K", 0xfb00, 0xff00, WR_SP|RD_SP, I3 },
+{"daddiu", "y,P,W", 0xfe00, 0xff00, WR_y|RD_PC, I3 },
+{"daddiu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, I3 },
+{"daddu", "z,v,y", 0xe000, 0xf803, WR_z|RD_x|RD_y, I3 },
+{"daddu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, I3 },
+{"daddu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, I3 },
+{"daddu", "S,K", 0xfb00, 0xff00, WR_SP|RD_SP, I3 },
+{"daddu", "S,S,K", 0xfb00, 0xff00, WR_SP|RD_SP, I3 },
+{"daddu", "y,P,W", 0xfe00, 0xff00, WR_y|RD_PC, I3 },
+{"daddu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, I3 },
+{"ddiv", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, I3 },
+{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO },
+{"ddivu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, I3 },
+{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO },
+{"div", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO },
+{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO },
+{"divu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO },
+{"divu", "z,v,y", 0, (int) M_DIVU_3, INSN_MACRO },
+{"dmul", "z,v,y", 0, (int) M_DMUL, INSN_MACRO, I3 },
+{"dmult", "x,y", 0xe81c, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, I3 },
+{"dmultu", "x,y", 0xe81d, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, I3 },
+{"drem", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, I3 },
+{"drem", "z,v,y", 0, (int) M_DREM_3, INSN_MACRO },
+{"dremu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, I3 },
+{"dremu", "z,v,y", 0, (int) M_DREMU_3, INSN_MACRO },
+{"dsllv", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, I3 },
+{"dsll", "x,w,[", 0x3001, 0xf803, WR_x|RD_y, I3 },
+{"dsll", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, I3 },
+{"dsrav", "y,x", 0xe817, 0xf81f, WR_y|RD_y|RD_x, I3 },
+{"dsra", "y,]", 0xe813, 0xf81f, WR_y|RD_y, I3 },
+{"dsra", "y,x", 0xe817, 0xf81f, WR_y|RD_y|RD_x, I3 },
+{"dsrlv", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, I3 },
+{"dsrl", "y,]", 0xe808, 0xf81f, WR_y|RD_y, I3 },
+{"dsrl", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, I3 },
+{"dsubu", "z,v,y", 0xe002, 0xf803, WR_z|RD_x|RD_y, I3 },
+{"dsubu", "y,x,4", 0, (int) M_DSUBU_I, INSN_MACRO },
+{"dsubu", "y,j", 0, (int) M_DSUBU_I_2, INSN_MACRO },
+{"exit", "L", 0xed09, 0xff1f, TRAP },
+{"exit", "L", 0xee09, 0xff1f, TRAP },
+{"exit", "L", 0xef09, 0xff1f, TRAP },
+{"entry", "l", 0xe809, 0xf81f, TRAP },
+{"extend", "e", 0xf000, 0xf800, 0 },
+{"jalr", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x },
+{"jalr", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x },
+{"jal", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x },
+{"jal", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x },
+{"jal", "a", 0x1800, 0xfc00, UBD|WR_31 },
+{"jalx", "a", 0x1c00, 0xfc00, UBD|WR_31 },
+{"jr", "x", 0xe800, 0xf8ff, UBD|RD_x },
+{"jr", "R", 0xe820, 0xffff, UBD|RD_31 },
+{"j", "x", 0xe800, 0xf8ff, UBD|RD_x },
+{"j", "R", 0xe820, 0xffff, UBD|RD_31 },
+{"lb", "y,5(x)", 0x8000, 0xf800, WR_y|RD_x },
+{"lbu", "y,5(x)", 0xa000, 0xf800, WR_y|RD_x },
+{"ld", "y,D(x)", 0x3800, 0xf800, WR_y|RD_x, I3 },
+{"ld", "y,B", 0xfc00, 0xff00, WR_y|RD_PC, I3 },
+{"ld", "y,D(P)", 0xfc00, 0xff00, WR_y|RD_PC, I3 },
+{"ld", "y,D(S)", 0xf800, 0xff00, WR_y|RD_SP, I3 },
+{"lh", "y,H(x)", 0x8800, 0xf800, WR_y|RD_x },
+{"lhu", "y,H(x)", 0xa800, 0xf800, WR_y|RD_x },
+{"li", "x,U", 0x6800, 0xf800, WR_x },
+{"lw", "y,W(x)", 0x9800, 0xf800, WR_y|RD_x },
+{"lw", "x,A", 0xb000, 0xf800, WR_x|RD_PC },
+{"lw", "x,V(P)", 0xb000, 0xf800, WR_x|RD_PC },
+{"lw", "x,V(S)", 0x9000, 0xf800, WR_x|RD_SP },
+{"lwu", "y,W(x)", 0xb800, 0xf800, WR_y|RD_x, I3 },
+{"mfhi", "x", 0xe810, 0xf8ff, WR_x|RD_HI },
+{"mflo", "x", 0xe812, 0xf8ff, WR_x|RD_LO },
+{"move", "y,X", 0x6700, 0xff00, WR_y|RD_X },
+{"move", "Y,Z", 0x6500, 0xff00, WR_Y|RD_Z },
+{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO },
+{"mult", "x,y", 0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO },
+{"multu", "x,y", 0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO },
+{"neg", "x,w", 0xe80b, 0xf81f, WR_x|RD_y },
+{"not", "x,w", 0xe80f, 0xf81f, WR_x|RD_y },
+{"or", "x,y", 0xe80d, 0xf81f, WR_x|RD_x|RD_y },
+{"rem", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO },
+{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO },
+{"remu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO },
+{"remu", "z,v,y", 0, (int) M_REMU_3, INSN_MACRO },
+{"sb", "y,5(x)", 0xc000, 0xf800, RD_y|RD_x },
+{"sd", "y,D(x)", 0x7800, 0xf800, RD_y|RD_x, I3 },
+{"sd", "y,D(S)", 0xf900, 0xff00, RD_y|RD_PC, I3 },
+{"sd", "R,C(S)", 0xfa00, 0xff00, RD_31|RD_PC },
+{"sh", "y,H(x)", 0xc800, 0xf800, RD_y|RD_x },
+{"sllv", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x },
+{"sll", "x,w,<", 0x3000, 0xf803, WR_x|RD_y },
+{"sll", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x },
+{"slti", "x,8", 0x5000, 0xf800, WR_T|RD_x },
+{"slt", "x,y", 0xe802, 0xf81f, WR_T|RD_x|RD_y },
+{"slt", "x,8", 0x5000, 0xf800, WR_T|RD_x },
+{"sltiu", "x,8", 0x5800, 0xf800, WR_T|RD_x },
+{"sltu", "x,y", 0xe803, 0xf81f, WR_T|RD_x|RD_y },
+{"sltu", "x,8", 0x5800, 0xf800, WR_T|RD_x },
+{"srav", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x },
+{"sra", "x,w,<", 0x3003, 0xf803, WR_x|RD_y },
+{"sra", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x },
+{"srlv", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x },
+{"srl", "x,w,<", 0x3002, 0xf803, WR_x|RD_y },
+{"srl", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x },
+{"subu", "z,v,y", 0xe003, 0xf803, WR_z|RD_x|RD_y },
+{"subu", "y,x,4", 0, (int) M_SUBU_I, INSN_MACRO },
+{"subu", "x,k", 0, (int) M_SUBU_I_2, INSN_MACRO },
+{"sw", "y,W(x)", 0xd800, 0xf800, RD_y|RD_x },
+{"sw", "x,V(S)", 0xd000, 0xf800, RD_x|RD_SP },
+{"sw", "R,V(S)", 0x6200, 0xff00, RD_31|RD_SP },
+{"xor", "x,y", 0xe80e, 0xf81f, WR_x|RD_x|RD_y },
+};
+
+const int bfd_mips16_num_opcodes =
+ ((sizeof mips16_opcodes) / (sizeof (mips16_opcodes[0])));
diff --git a/opcodes/mpw-config.in b/opcodes/mpw-config.in
new file mode 100644
index 00000000000..ff9be9d72f4
--- /dev/null
+++ b/opcodes/mpw-config.in
@@ -0,0 +1,27 @@
+# Configuration fragment for opcodes.
+
+Set target_arch `echo {target_canonical} | sed -e 's/-.*-.*//'`
+
+Set archname ARCH_{target_arch}
+
+If "{target_arch}" =~ /m68k/
+ Set BFD_MACHINES '"{o}"m68k-dis.c.o "{o}"m68k-opc.c.o'
+Else If "{target_arch}" =~ /powerpc/
+ Set BFD_MACHINES '"{o}"ppc-dis.c.o "{o}"ppc-opc.c.o'
+Else If "{target_arch}" =~ /i386/
+ Set BFD_MACHINES '"{o}"i386-dis.c.o'
+Else If "{target_arch}" =~ /mips/
+ Set BFD_MACHINES '"{o}"mips-dis.c.o "{o}"mips-opc.c.o'
+Else If "{target_arch}" =~ /sh/
+ Set BFD_MACHINES '"{o}"sh-dis.c.o'
+End If
+
+Echo '# Start from mpw-config.in' > "{o}"mk.tmp
+Echo "BFD_MACHINES = " {BFD_MACHINES} >> "{o}"mk.tmp
+Echo "ARCHDEFS = -d" {archname} >> "{o}"mk.tmp
+Echo '# End from mpw-config.in' >> "{o}"mk.tmp
+
+Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new
+Echo '#include "mpw.h"' >> "{o}"config.new
+
+MoveIfChange "{o}"config.new "{o}"config.h
diff --git a/opcodes/mpw-make.sed b/opcodes/mpw-make.sed
new file mode 100644
index 00000000000..ee604862de6
--- /dev/null
+++ b/opcodes/mpw-make.sed
@@ -0,0 +1,25 @@
+# Sed commands to finish translating the opcodes Makefile.in into MPW syntax.
+
+# Empty HDEFINES.
+/HDEFINES/s/@HDEFINES@//
+
+# Fix pathnames to include directories.
+/^INCDIR = /s/^INCDIR = .*$/INCDIR = "{topsrcdir}"include/
+/^CSEARCH = /s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/
+
+/BFD_MACHINES/s/@BFD_MACHINES@/{BFD_MACHINES}/
+/archdefs/s/@archdefs@/{ARCHDEFS}/
+
+# No PIC foolery in this environment.
+/@ALLLIBS@/s/@ALLLIBS@/{TARGETLIB}/
+/@PICLIST@/s/@PICLIST@//
+/@PICFLAG@/s/@PICFLAG@//
+/^{OFILES} \\Option-f stamp-picdir/,/^$/d
+
+# Remove the pic trickery from the default build rule.
+/^\.c\.o \\Option-f /,/End If/c\
+.c.o \\Option-f .c
+
+# Remove pic trickery from other rules - aimed at the rule
+# for disassemble.o in particular.
+/-n "{PICFLAG}"/,/End If/d
diff --git a/opcodes/ns32k-dis.c b/opcodes/ns32k-dis.c
new file mode 100644
index 00000000000..050266be849
--- /dev/null
+++ b/opcodes/ns32k-dis.c
@@ -0,0 +1,894 @@
+/* Print National Semiconductor 32000 instructions.
+ Copyright (c) 1986, 88, 91, 92, 94, 95, 1998 Free Software Foundation, Inc.
+
+This file is part of opcodes library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "dis-asm.h"
+#if !defined(const) && !defined(__STDC__)
+#define const
+#endif
+#include "opcode/ns32k.h"
+#include "opintl.h"
+
+static disassemble_info *dis_info;
+
+/*
+ * Hacks to get it to compile <= READ THESE AS FIXES NEEDED
+ */
+#define INVALID_FLOAT(val, size) invalid_float((char *)val, size)
+
+static int print_insn_arg
+ PARAMS ((int, int, int *, char *, bfd_vma, char *, int));
+static int get_displacement PARAMS ((char *, int *));
+static int invalid_float PARAMS ((char *, int));
+
+static long read_memory_integer(addr, nr)
+ unsigned char *addr;
+ int nr;
+{
+ long val;
+ int i;
+ for (val = 0, i = nr - 1; i >= 0; i--) {
+ val = (val << 8);
+ val |= (0xff & *(addr + i));
+ }
+ return val;
+}
+
+/* 32000 instructions are never longer than this. */
+#define MAXLEN 62
+
+
+#include <setjmp.h>
+
+struct private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+};
+
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+ struct disassemble_info *info;
+ bfd_byte *addr;
+{
+ int status;
+ struct private *priv = (struct private *)info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ longjmp (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+/* Number of elements in the opcode table. */
+#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
+
+#define NEXT_IS_ADDR '|'
+
+
+struct ns32k_option {
+ char *pattern; /* the option itself */
+ unsigned long value; /* binary value of the option */
+ unsigned long match; /* these bits must match */
+};
+
+
+static const struct ns32k_option opt_u[]= /* restore, exit */
+{
+ { "r0", 0x80, 0x80 },
+ { "r1", 0x40, 0x40 },
+ { "r2", 0x20, 0x20 },
+ { "r3", 0x10, 0x10 },
+ { "r4", 0x08, 0x08 },
+ { "r5", 0x04, 0x04 },
+ { "r6", 0x02, 0x02 },
+ { "r7", 0x01, 0x01 },
+ { 0 , 0x00, 0x00 }
+};
+
+static const struct ns32k_option opt_U[]= /* save, enter */
+{
+ { "r0", 0x01, 0x01 },
+ { "r1", 0x02, 0x02 },
+ { "r2", 0x04, 0x04 },
+ { "r3", 0x08, 0x08 },
+ { "r4", 0x10, 0x10 },
+ { "r5", 0x20, 0x20 },
+ { "r6", 0x40, 0x40 },
+ { "r7", 0x80, 0x80 },
+ { 0 , 0x00, 0x00 }
+};
+
+static const struct ns32k_option opt_O[]= /* setcfg */
+{
+ { "c", 0x8, 0x8 },
+ { "m", 0x4, 0x4 },
+ { "f", 0x2, 0x2 },
+ { "i", 0x1, 0x1 },
+ { 0 , 0x0, 0x0 }
+};
+
+static const struct ns32k_option opt_C[]= /* cinv */
+{
+ { "a", 0x4, 0x4 },
+ { "i", 0x2, 0x2 },
+ { "d", 0x1, 0x1 },
+ { 0 , 0x0, 0x0 }
+};
+
+static const struct ns32k_option opt_S[]= /* string inst */
+{
+ { "b", 0x1, 0x1 },
+ { "u", 0x6, 0x6 },
+ { "w", 0x2, 0x2 },
+ { 0 , 0x0, 0x0 }
+};
+
+static const struct ns32k_option list_P532[]= /* lpr spr */
+{
+ { "us", 0x0, 0xf },
+ { "dcr", 0x1, 0xf },
+ { "bpc", 0x2, 0xf },
+ { "dsr", 0x3, 0xf },
+ { "car", 0x4, 0xf },
+ { "fp", 0x8, 0xf },
+ { "sp", 0x9, 0xf },
+ { "sb", 0xa, 0xf },
+ { "usp", 0xb, 0xf },
+ { "cfg", 0xc, 0xf },
+ { "psr", 0xd, 0xf },
+ { "intbase", 0xe, 0xf },
+ { "mod", 0xf, 0xf },
+ { 0 , 0x00, 0xf }
+};
+
+static const struct ns32k_option list_M532[]= /* lmr smr */
+{
+ { "mcr", 0x9, 0xf },
+ { "msr", 0xa, 0xf },
+ { "tear", 0xb, 0xf },
+ { "ptb0", 0xc, 0xf },
+ { "ptb1", 0xd, 0xf },
+ { "ivar0", 0xe, 0xf },
+ { "ivar1", 0xf, 0xf },
+ { 0 , 0x0, 0xf }
+};
+
+static const struct ns32k_option list_P032[]= /* lpr spr */
+{
+ { "upsr", 0x0, 0xf },
+ { "fp", 0x8, 0xf },
+ { "sp", 0x9, 0xf },
+ { "sb", 0xa, 0xf },
+ { "psr", 0xb, 0xf },
+ { "intbase", 0xe, 0xf },
+ { "mod", 0xf, 0xf },
+ { 0 , 0x0, 0xf }
+};
+
+static const struct ns32k_option list_M032[]= /* lmr smr */
+{
+ { "bpr0", 0x0, 0xf },
+ { "bpr1", 0x1, 0xf },
+ { "pf0", 0x4, 0xf },
+ { "pf1", 0x5, 0xf },
+ { "sc", 0x8, 0xf },
+ { "msr", 0xa, 0xf },
+ { "bcnt", 0xb, 0xf },
+ { "ptb0", 0xc, 0xf },
+ { "ptb1", 0xd, 0xf },
+ { "eia", 0xf, 0xf },
+ { 0 , 0x0, 0xf }
+};
+
+
+/*
+ * figure out which options are present
+ */
+static void
+optlist(options, optionP, result)
+ int options;
+ const struct ns32k_option *optionP;
+ char *result;
+{
+ if (options == 0) {
+ sprintf(result, "[]");
+ return;
+ }
+ sprintf(result, "[");
+
+ for (; (options != 0) && optionP->pattern; optionP++) {
+ if ((options & optionP->match) == optionP->value) {
+ /* we found a match, update result and options */
+ strcat(result, optionP->pattern);
+ options &= ~optionP->value;
+ if (options != 0) /* more options to come */
+ strcat(result, ",");
+ }
+ }
+ if (options != 0)
+ strcat(result, "undefined");
+
+ strcat(result, "]");
+}
+
+static void
+list_search (reg_value, optionP, result)
+ int reg_value;
+ const struct ns32k_option *optionP;
+ char *result;
+{
+ for (; optionP->pattern; optionP++) {
+ if ((reg_value & optionP->match) == optionP->value) {
+ sprintf(result, "%s", optionP->pattern);
+ return;
+ }
+ }
+ sprintf(result, "undefined");
+}
+
+/*
+ * extract "count" bits starting "offset" bits
+ * into buffer
+ */
+
+static int
+bit_extract (buffer, offset, count)
+ bfd_byte *buffer;
+ int offset;
+ int count;
+{
+ int result;
+ int bit;
+
+ buffer += offset >> 3;
+ offset &= 7;
+ bit = 1;
+ result = 0;
+ while (count--)
+ {
+ FETCH_DATA(dis_info, buffer + 1);
+ if ((*buffer & (1 << offset)))
+ result |= bit;
+ if (++offset == 8)
+ {
+ offset = 0;
+ buffer++;
+ }
+ bit <<= 1;
+ }
+ return result;
+}
+
+/* Like bit extract but the buffer is valid and doen't need to be
+ * fetched
+ */
+static int
+bit_extract_simple (buffer, offset, count)
+ bfd_byte *buffer;
+ int offset;
+ int count;
+{
+ int result;
+ int mask;
+ int bit;
+
+ buffer += offset >> 3;
+ offset &= 7;
+ bit = 1;
+ result = 0;
+ while (count--)
+ {
+ if ((*buffer & (1 << offset)))
+ result |= bit;
+ if (++offset == 8)
+ {
+ offset = 0;
+ buffer++;
+ }
+ bit <<= 1;
+ }
+ return result;
+}
+
+static void
+bit_copy (buffer, offset, count, to)
+ char *buffer;
+ int offset;
+ int count;
+ char *to;
+{
+ for(; count > 8; count -= 8, to++, offset += 8)
+ *to = bit_extract (buffer, offset, 8);
+ *to = bit_extract (buffer, offset, count);
+}
+
+
+static int
+sign_extend (value, bits)
+ int value, bits;
+{
+ value = value & ((1 << bits) - 1);
+ return (value & (1 << (bits-1))
+ ? value | (~((1 << bits) - 1))
+ : value);
+}
+
+static void
+flip_bytes (ptr, count)
+ char *ptr;
+ int count;
+{
+ char tmp;
+
+ while (count > 0)
+ {
+ tmp = ptr[0];
+ ptr[0] = ptr[count-1];
+ ptr[count-1] = tmp;
+ ptr++;
+ count -= 2;
+ }
+}
+
+/* Given a character C, does it represent a general addressing mode? */
+#define Is_gen(c) \
+ ((c) == 'F' || (c) == 'L' || (c) == 'B' \
+ || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
+
+/* Adressing modes. */
+#define Adrmod_index_byte 0x1c
+#define Adrmod_index_word 0x1d
+#define Adrmod_index_doubleword 0x1e
+#define Adrmod_index_quadword 0x1f
+
+/* Is MODE an indexed addressing mode? */
+#define Adrmod_is_index(mode) \
+ (mode == Adrmod_index_byte \
+ || mode == Adrmod_index_word \
+ || mode == Adrmod_index_doubleword \
+ || mode == Adrmod_index_quadword)
+
+
+/* Print the 32000 instruction at address MEMADDR in debugged memory,
+ on STREAM. Returns length of the instruction, in bytes. */
+
+int
+print_insn_ns32k (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info *info;
+{
+ register unsigned int i;
+ register char *d;
+ unsigned short first_word;
+ int ioffset; /* bits into instruction */
+ int aoffset; /* bits into arguments */
+ char arg_bufs[MAX_ARGS+1][ARG_LEN];
+ int argnum;
+ int maxarg;
+ struct private priv;
+ bfd_byte *buffer = priv.the_buffer;
+ dis_info = info;
+
+ info->private_data = (PTR) &priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = memaddr;
+ if (setjmp (priv.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+ /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
+ * us over the end of accessible data unnecessarilly
+ */
+ FETCH_DATA(info, buffer + 1);
+ for (i = 0; i < NOPCODES; i++)
+ if (ns32k_opcodes[i].opcode_id_size <= 8
+ && ((buffer[0]
+ & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
+ == ns32k_opcodes[i].opcode_seed))
+ break;
+ if (i == NOPCODES) {
+ /* Maybe it is 9 to 16 bits big */
+ FETCH_DATA(info, buffer + 2);
+ first_word = read_memory_integer(buffer, 2);
+
+ for (i = 0; i < NOPCODES; i++)
+ if ((first_word
+ & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
+ == ns32k_opcodes[i].opcode_seed)
+ break;
+
+ /* Handle undefined instructions. */
+ if (i == NOPCODES)
+ {
+ (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
+ return 1;
+ }
+ }
+
+ (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
+
+ ioffset = ns32k_opcodes[i].opcode_size;
+ aoffset = ns32k_opcodes[i].opcode_size;
+ d = ns32k_opcodes[i].operands;
+
+ if (*d)
+ {
+ /* Offset in bits of the first thing beyond each index byte.
+ Element 0 is for operand A and element 1 is for operand B.
+ The rest are irrelevant, but we put them here so we don't
+ index outside the array. */
+ int index_offset[MAX_ARGS];
+
+ /* 0 for operand A, 1 for operand B, greater for other args. */
+ int whicharg = 0;
+
+ (*dis_info->fprintf_func)(dis_info->stream, "\t");
+
+ maxarg = 0;
+
+ /* First we have to find and keep track of the index bytes,
+ if we are using scaled indexed addressing mode, since the index
+ bytes occur right after the basic instruction, not as part
+ of the addressing extension. */
+ if (Is_gen(d[1]))
+ {
+ int addr_mode = bit_extract (buffer, ioffset - 5, 5);
+
+ if (Adrmod_is_index (addr_mode))
+ {
+ aoffset += 8;
+ index_offset[0] = aoffset;
+ }
+ }
+ if (d[2] && Is_gen(d[3]))
+ {
+ int addr_mode = bit_extract (buffer, ioffset - 10, 5);
+
+ if (Adrmod_is_index (addr_mode))
+ {
+ aoffset += 8;
+ index_offset[1] = aoffset;
+ }
+ }
+
+ while (*d)
+ {
+ argnum = *d - '1';
+ d++;
+ if (argnum > maxarg && argnum < MAX_ARGS)
+ maxarg = argnum;
+ ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
+ memaddr, arg_bufs[argnum],
+ index_offset[whicharg]);
+ d++;
+ whicharg++;
+ }
+ for (argnum = 0; argnum <= maxarg; argnum++)
+ {
+ bfd_vma addr;
+ char *ch;
+ for (ch = arg_bufs[argnum]; *ch;)
+ {
+ if (*ch == NEXT_IS_ADDR)
+ {
+ ++ch;
+ addr = bfd_scan_vma (ch, NULL, 16);
+ (*dis_info->print_address_func) (addr, dis_info);
+ while (*ch && *ch != NEXT_IS_ADDR)
+ ++ch;
+ if (*ch)
+ ++ch;
+ }
+ else
+ (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
+ }
+ if (argnum < maxarg)
+ (*dis_info->fprintf_func)(dis_info->stream, ", ");
+ }
+ }
+ return aoffset / 8;
+}
+
+/* Print an instruction operand of category given by d. IOFFSET is
+ the bit position below which small (<1 byte) parts of the operand can
+ be found (usually in the basic instruction, but for indexed
+ addressing it can be in the index byte). AOFFSETP is a pointer to the
+ bit position of the addressing extension. BUFFER contains the
+ instruction. ADDR is where BUFFER was read from. Put the disassembled
+ version of the operand in RESULT. INDEX_OFFSET is the bit position
+ of the index byte (it contains garbage if this operand is not a
+ general operand using scaled indexed addressing mode). */
+
+static int
+print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
+ int d;
+ int ioffset, *aoffsetp;
+ char *buffer;
+ bfd_vma addr;
+ char *result;
+ int index_offset;
+{
+ int addr_mode;
+ float Fvalue;
+ double Lvalue;
+ int Ivalue;
+ int disp1, disp2;
+ int index;
+ int size;
+
+ switch (d)
+ {
+ case 'f':
+ /* a "gen" operand but 5 bits from the end of instruction */
+ ioffset -= 5;
+ case 'Z':
+ case 'F':
+ case 'L':
+ case 'I':
+ case 'B':
+ case 'W':
+ case 'D':
+ case 'A':
+ addr_mode = bit_extract (buffer, ioffset-5, 5);
+ ioffset -= 5;
+ switch (addr_mode)
+ {
+ case 0x0: case 0x1: case 0x2: case 0x3:
+ case 0x4: case 0x5: case 0x6: case 0x7:
+ /* register mode R0 -- R7 */
+ switch (d)
+ {
+ case 'F':
+ case 'L':
+ case 'Z':
+ sprintf (result, "f%d", addr_mode);
+ break;
+ default:
+ sprintf (result, "r%d", addr_mode);
+ }
+ break;
+ case 0x8: case 0x9: case 0xa: case 0xb:
+ case 0xc: case 0xd: case 0xe: case 0xf:
+ /* Register relative disp(R0 -- R7) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
+ break;
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ /* Memory relative disp2(disp1(FP, SP, SB)) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ disp2 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "%d(%d(%s))", disp2, disp1,
+ addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
+ break;
+ case 0x13:
+ /* reserved */
+ sprintf (result, "reserved");
+ break;
+ case 0x14:
+ /* Immediate */
+ switch (d)
+ {
+ case 'I': case 'Z': case 'A':
+ /* I and Z are output operands and can`t be immediate
+ * A is an address and we can`t have the address of
+ * an immediate either. We don't know how much to increase
+ * aoffsetp by since whatever generated this is broken
+ * anyway!
+ */
+ sprintf (result, _("$<undefined>"));
+ break;
+ case 'B':
+ Ivalue = bit_extract (buffer, *aoffsetp, 8);
+ Ivalue = sign_extend (Ivalue, 8);
+ *aoffsetp += 8;
+ sprintf (result, "$%d", Ivalue);
+ break;
+ case 'W':
+ Ivalue = bit_extract (buffer, *aoffsetp, 16);
+ flip_bytes (&Ivalue, 2);
+ *aoffsetp += 16;
+ Ivalue = sign_extend (Ivalue, 16);
+ sprintf (result, "$%d", Ivalue);
+ break;
+ case 'D':
+ Ivalue = bit_extract (buffer, *aoffsetp, 32);
+ flip_bytes (&Ivalue, 4);
+ *aoffsetp += 32;
+ sprintf (result, "$%d", Ivalue);
+ break;
+ case 'F':
+ bit_copy (buffer, *aoffsetp, 32, (char *) &Fvalue);
+ flip_bytes (&Fvalue, 4);
+ *aoffsetp += 32;
+ if (INVALID_FLOAT (&Fvalue, 4))
+ sprintf (result, "<<invalid float 0x%.8x>>", *(int *) &Fvalue);
+ else /* assume host has ieee float */
+ sprintf (result, "$%g", Fvalue);
+ break;
+ case 'L':
+ bit_copy (buffer, *aoffsetp, 64, (char *) &Lvalue);
+ flip_bytes (&Lvalue, 8);
+ *aoffsetp += 64;
+ if (INVALID_FLOAT (&Lvalue, 8))
+ sprintf (result, "<<invalid long 0x%.8x%.8x>>",
+ *(((int *) &Lvalue) + 1), *(int *) &Lvalue);
+ else /* assume host has ieee float */
+ sprintf (result, "$%g", Lvalue);
+ break;
+ }
+ break;
+ case 0x15:
+ /* Absolute @disp */
+ disp1 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "@|%d|", disp1);
+ break;
+ case 0x16:
+ /* External EXT(disp1) + disp2 (Mod table stuff) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ disp2 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "EXT(%d) + %d", disp1, disp2);
+ break;
+ case 0x17:
+ /* Top of stack tos */
+ sprintf (result, "tos");
+ break;
+ case 0x18:
+ /* Memory space disp(FP) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "%d(fp)", disp1);
+ break;
+ case 0x19:
+ /* Memory space disp(SP) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "%d(sp)", disp1);
+ break;
+ case 0x1a:
+ /* Memory space disp(SB) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ sprintf (result, "%d(sb)", disp1);
+ break;
+ case 0x1b:
+ /* Memory space disp(PC) */
+ disp1 = get_displacement (buffer, aoffsetp);
+ *result++ = NEXT_IS_ADDR;
+ sprintf_vma (result, addr + disp1);
+ result += strlen (result);
+ *result++ = NEXT_IS_ADDR;
+ *result = '\0';
+ break;
+ case 0x1c:
+ case 0x1d:
+ case 0x1e:
+ case 0x1f:
+ /* Scaled index basemode[R0 -- R7:B,W,D,Q] */
+ index = bit_extract (buffer, index_offset - 8, 3);
+ print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
+ result, 0);
+ {
+ static const char *ind = "bwdq";
+ char *off;
+
+ off = result + strlen (result);
+ sprintf (off, "[r%d:%c]", index,
+ ind[addr_mode & 3]);
+ }
+ break;
+ }
+ break;
+ case 'H':
+ case 'q':
+ Ivalue = bit_extract (buffer, ioffset-4, 4);
+ Ivalue = sign_extend (Ivalue, 4);
+ sprintf (result, "%d", Ivalue);
+ ioffset -= 4;
+ break;
+ case 'r':
+ Ivalue = bit_extract (buffer, ioffset-3, 3);
+ sprintf (result, "r%d", Ivalue&7);
+ ioffset -= 3;
+ break;
+ case 'd':
+ sprintf (result, "%d", get_displacement (buffer, aoffsetp));
+ break;
+ case 'b':
+ Ivalue = get_displacement (buffer, aoffsetp);
+ /*
+ * Warning!! HACK ALERT!
+ * Operand type 'b' is only used by the cmp{b,w,d} and
+ * movm{b,w,d} instructions; we need to know whether
+ * it's a `b' or `w' or `d' instruction; and for both
+ * cmpm and movm it's stored at the same place so we
+ * just grab two bits of the opcode and look at it...
+ *
+ */
+ size = bit_extract(buffer, ioffset-6, 2);
+ if (size == 0) /* 00 => b */
+ size = 1;
+ else if (size == 1) /* 01 => w */
+ size = 2;
+ else
+ size = 4; /* 11 => d */
+
+ sprintf (result, "%d", (Ivalue / size) + 1);
+ break;
+ case 'p':
+ *result++ = NEXT_IS_ADDR;
+ sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
+ result += strlen (result);
+ *result++ = NEXT_IS_ADDR;
+ *result = '\0';
+ break;
+ case 'i':
+ Ivalue = bit_extract (buffer, *aoffsetp, 8);
+ *aoffsetp += 8;
+ sprintf (result, "0x%x", Ivalue);
+ break;
+ case 'u':
+ Ivalue = bit_extract (buffer, *aoffsetp, 8);
+ optlist(Ivalue, opt_u, result);
+ *aoffsetp += 8;
+ break;
+ case 'U':
+ Ivalue = bit_extract(buffer, *aoffsetp, 8);
+ optlist(Ivalue, opt_U, result);
+ *aoffsetp += 8;
+ break;
+ case 'O':
+ Ivalue = bit_extract(buffer, ioffset-9, 9);
+ optlist(Ivalue, opt_O, result);
+ ioffset -= 9;
+ break;
+ case 'C':
+ Ivalue = bit_extract(buffer, ioffset-4, 4);
+ optlist(Ivalue, opt_C, result);
+ ioffset -= 4;
+ break;
+ case 'S':
+ Ivalue = bit_extract(buffer, ioffset - 8, 8);
+ optlist(Ivalue, opt_S, result);
+ ioffset -= 8;
+ break;
+ case 'M':
+ Ivalue = bit_extract(buffer, ioffset-4, 4);
+ list_search(Ivalue, 0 ? list_M032 : list_M532, result);
+ ioffset -= 4;
+ break;
+ case 'P':
+ Ivalue = bit_extract(buffer, ioffset-4, 4);
+ list_search(Ivalue, 0 ? list_P032 : list_P532, result);
+ ioffset -= 4;
+ break;
+ case 'g':
+ Ivalue = bit_extract(buffer, *aoffsetp, 3);
+ sprintf(result, "%d", Ivalue);
+ *aoffsetp += 3;
+ break;
+ case 'G':
+ Ivalue = bit_extract(buffer, *aoffsetp, 5);
+ sprintf(result, "%d", Ivalue + 1);
+ *aoffsetp += 5;
+ break;
+ }
+ return ioffset;
+}
+
+static int
+get_displacement (buffer, aoffsetp)
+ char *buffer;
+ int *aoffsetp;
+{
+ int Ivalue;
+ short Ivalue2;
+
+ Ivalue = bit_extract (buffer, *aoffsetp, 8);
+ switch (Ivalue & 0xc0)
+ {
+ case 0x00:
+ case 0x40:
+ Ivalue = sign_extend (Ivalue, 7);
+ *aoffsetp += 8;
+ break;
+ case 0x80:
+ Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
+ flip_bytes (&Ivalue2, 2);
+ Ivalue = sign_extend (Ivalue2, 14);
+ *aoffsetp += 16;
+ break;
+ case 0xc0:
+ Ivalue = bit_extract (buffer, *aoffsetp, 32);
+ flip_bytes (&Ivalue, 4);
+ Ivalue = sign_extend (Ivalue, 30);
+ *aoffsetp += 32;
+ break;
+ }
+ return Ivalue;
+}
+
+
+#if 1 /* a version that should work on ns32k f's&d's on any machine */
+static int
+invalid_float (p, len)
+ register char *p;
+ register int len;
+{
+ register int val;
+
+ if ( len == 4 )
+ val = (bit_extract_simple(p, 23, 8)/*exponent*/ == 0xff
+ || (bit_extract_simple(p, 23, 8)/*exponent*/ == 0 &&
+ bit_extract_simple(p, 0, 23)/*mantisa*/ != 0));
+ else if ( len == 8 )
+ val = (bit_extract_simple(p, 52, 11)/*exponent*/ == 0x7ff
+ || (bit_extract_simple(p, 52, 11)/*exponent*/ == 0
+ && (bit_extract_simple(p, 0, 32)/*low mantisa*/ != 0
+ || bit_extract_simple(p, 32, 20)/*high mantisa*/ != 0)));
+ else
+ val = 1;
+ return (val);
+}
+#else
+
+/* assumes the bytes have been swapped to local order */
+typedef union { double d;
+ float f;
+ struct { unsigned m:23, e:8, :1;} sf;
+ struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
+ } float_type_u;
+
+static int
+invalid_float (p, len)
+ register float_type_u *p;
+ register int len;
+{
+ register int val;
+ if ( len == sizeof (float) )
+ val = (p->sf.e == 0xff
+ || (p->sf.e == 0 && p->sf.m != 0));
+ else if ( len == sizeof (double) )
+ val = (p->sd.e == 0x7ff
+ || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
+ else
+ val = 1;
+ return (val);
+}
+#endif
diff --git a/opcodes/opintl.h b/opcodes/opintl.h
new file mode 100644
index 00000000000..a5901604081
--- /dev/null
+++ b/opcodes/opintl.h
@@ -0,0 +1,30 @@
+/* opintl.h - opcodes specific header for gettext code.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+ Written by Tom Tromey <tromey@cygnus.com>
+
+ This file is part of the opcodes library used by GAS and the GNU binutils.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) dgettext (PACKAGE, String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+/* Stubs that do something close enough. */
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
diff --git a/opcodes/po/Make-in b/opcodes/po/Make-in
new file mode 100644
index 00000000000..0552db1feef
--- /dev/null
+++ b/opcodes/po/Make-in
@@ -0,0 +1,251 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS) @MAINT@ $(PACKAGE).pot
+all-no:
+
+$(srcdir)/$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ rm -f $(srcdir)/$(PACKAGE).pot
+ mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot
+
+$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
+$(srcdir)/stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-info:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/POTFILES.in
+
+Makefile: Make-in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/Makefile.in:$(subdir)/Make-in \
+ CONFIG_HEADERS= $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/opcodes/po/POTFILES.in b/opcodes/po/POTFILES.in
new file mode 100644
index 00000000000..f072ccaeb9e
--- /dev/null
+++ b/opcodes/po/POTFILES.in
@@ -0,0 +1,69 @@
+a29k-dis.c
+alpha-dis.c
+alpha-opc.c
+arc-dis.c
+arc-opc.c
+arm-dis.c
+arm-opc.h
+cgen-asm.c
+cgen-dis.c
+cgen-opc.c
+d10v-dis.c
+d10v-opc.c
+d30v-dis.c
+d30v-opc.c
+dis-buf.c
+disassemble.c
+fr30-asm.c
+fr30-desc.c
+fr30-desc.h
+fr30-dis.c
+fr30-ibld.c
+fr30-opc.c
+fr30-opc.h
+h8300-dis.c
+h8500-dis.c
+h8500-opc.h
+hppa-dis.c
+i386-dis.c
+i960-dis.c
+m10200-dis.c
+m10200-opc.c
+m10300-dis.c
+m10300-opc.c
+m32r-asm.c
+m32r-desc.c
+m32r-desc.h
+m32r-dis.c
+m32r-ibld.c
+m32r-opc.c
+m32r-opc.h
+m32r-opinst.c
+m68k-dis.c
+m68k-opc.c
+m88k-dis.c
+mcore-dis.c
+mcore-opc.h
+mips-dis.c
+mips-opc.c
+mips16-opc.c
+ns32k-dis.c
+opintl.h
+ppc-dis.c
+ppc-opc.c
+sh-dis.c
+sh-opc.h
+sparc-dis.c
+sparc-opc.c
+sysdep.h
+tic30-dis.c
+tic80-dis.c
+tic80-opc.c
+v850-dis.c
+v850-opc.c
+vax-dis.c
+w65-dis.c
+w65-opc.h
+z8k-dis.c
+z8k-opc.h
+z8kgen.c
diff --git a/opcodes/po/opcodes.pot b/opcodes/po/opcodes.pot
new file mode 100644
index 00000000000..f7e3f0f47f9
--- /dev/null
+++ b/opcodes/po/opcodes.pot
@@ -0,0 +1,242 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1999-04-18 19:01-0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: alpha-opc.c:335
+msgid "branch operand unaligned"
+msgstr ""
+
+#: alpha-opc.c:358 alpha-opc.c:380
+msgid "jump hint unaligned"
+msgstr ""
+
+#: arm-dis.c:388
+msgid "<illegal precision>"
+msgstr ""
+
+#: cgen-asm.c:224
+msgid "unrecognized keyword/register name"
+msgstr ""
+
+#: cgen-asm.c:332 fr30-ibld.c:223 m32r-ibld.c:223
+#, c-format
+msgid "operand out of range (%ld not between %ld and %ld)"
+msgstr ""
+
+#: cgen-asm.c:353
+#, c-format
+msgid "operand out of range (%lu not between %lu and %lu)"
+msgstr ""
+
+#: d30v-dis.c:305
+#, c-format
+msgid "<unknown register %d>"
+msgstr ""
+
+#. Can't happen.
+#: dis-buf.c:50
+#, c-format
+msgid "Unknown error %d\n"
+msgstr ""
+
+#: dis-buf.c:55
+#, c-format
+msgid "Address 0x%x is out of bounds.\n"
+msgstr ""
+
+#: fr30-asm.c:303 m32r-asm.c:319
+#, c-format
+msgid "Unrecognized field %d while parsing.\n"
+msgstr ""
+
+#. We couldn't parse it.
+#: fr30-asm.c:367 fr30-asm.c:436 m32r-asm.c:383 m32r-asm.c:452
+msgid "unrecognized instruction"
+msgstr ""
+
+#. Syntax char didn't match. Can't be this insn.
+#. FIXME: would like to return something like
+#. "expected char `c'"
+#: fr30-asm.c:404 m32r-asm.c:420
+msgid "syntax error"
+msgstr ""
+
+#: fr30-asm.c:430 m32r-asm.c:446
+msgid "junk at end of line"
+msgstr ""
+
+#: fr30-asm.c:523 m32r-asm.c:539
+#, c-format
+msgid "bad instruction `%.50s...'"
+msgstr ""
+
+#: fr30-asm.c:526 m32r-asm.c:542
+#, c-format
+msgid "bad instruction `%.50s'"
+msgstr ""
+
+#: fr30-dis.c:300 m32r-dis.c:247
+#, c-format
+msgid "Unrecognized field %d while printing insn.\n"
+msgstr ""
+
+#: fr30-ibld.c:210 m32r-ibld.c:210
+#, c-format
+msgid "operand out of range (%lu not between 0 and %lu)"
+msgstr ""
+
+#: fr30-ibld.c:749 m32r-ibld.c:683
+#, c-format
+msgid "Unrecognized field %d while building insn.\n"
+msgstr ""
+
+#: fr30-ibld.c:952 m32r-ibld.c:819
+#, c-format
+msgid "Unrecognized field %d while decoding insn.\n"
+msgstr ""
+
+#: fr30-ibld.c:1096 m32r-ibld.c:932
+#, c-format
+msgid "Unrecognized field %d while getting int operand.\n"
+msgstr ""
+
+#: fr30-ibld.c:1225 m32r-ibld.c:1030
+#, c-format
+msgid "Unrecognized field %d while getting vma operand.\n"
+msgstr ""
+
+#: fr30-ibld.c:1358 m32r-ibld.c:1132
+#, c-format
+msgid "Unrecognized field %d while setting int operand.\n"
+msgstr ""
+
+#: fr30-ibld.c:1484 m32r-ibld.c:1227
+#, c-format
+msgid "Unrecognized field %d while setting vma operand.\n"
+msgstr ""
+
+#: h8300-dis.c:404
+#, c-format
+msgid "Hmmmm %x"
+msgstr ""
+
+#: h8300-dis.c:416
+#, c-format
+msgid "Don't understand %x \n"
+msgstr ""
+
+#: h8500-dis.c:139
+#, c-format
+msgid "can't cope with insert %d\n"
+msgstr ""
+
+#. Couldn't understand anything
+#: h8500-dis.c:344
+#, c-format
+msgid "%02x\t\t*unknown*"
+msgstr ""
+
+#: m10200-dis.c:199
+#, c-format
+msgid "unknown\t0x%02x"
+msgstr ""
+
+#: m10200-dis.c:339
+#, c-format
+msgid "unknown\t0x%04lx"
+msgstr ""
+
+#: m10300-dis.c:706
+#, c-format
+msgid "unknown\t0x%04x"
+msgstr ""
+
+#: m68k-dis.c:410
+#, c-format
+msgid "<internal error in opcode table: %s %s>\n"
+msgstr ""
+
+#: m68k-dis.c:967
+#, c-format
+msgid "<function code %d>"
+msgstr ""
+
+#: m88k-dis.c:273
+#, c-format
+msgid "# <dis error: %08x>"
+msgstr ""
+
+#: mips-dis.c:373
+#, c-format
+msgid "# internal error, undefined modifier(%c)"
+msgstr ""
+
+#. I and Z are output operands and can`t be immediate
+#. * A is an address and we can`t have the address of
+#. * an immediate either. We don't know how much to increase
+#. * aoffsetp by since whatever generated this is broken
+#. * anyway!
+#.
+#: ns32k-dis.c:618
+msgid "$<undefined>"
+msgstr ""
+
+#: ppc-opc.c:586 ppc-opc.c:617
+msgid "invalid conditional option"
+msgstr ""
+
+#: ppc-opc.c:619
+msgid "attempt to set y bit when using + or - modifier"
+msgstr ""
+
+#: ppc-opc.c:674
+msgid "ignoring least significant bits in branch offset"
+msgstr ""
+
+#: ppc-opc.c:709 ppc-opc.c:746
+msgid "illegal bitmask"
+msgstr ""
+
+#: ppc-opc.c:815
+msgid "value out of range"
+msgstr ""
+
+#: ppc-opc.c:889
+msgid "index register in load range"
+msgstr ""
+
+#: ppc-opc.c:904
+msgid "invalid register operand when updating"
+msgstr ""
+
+#. Mark as non-valid instruction
+#: sparc-dis.c:739
+msgid "unknown"
+msgstr ""
+
+#: sparc-dis.c:811
+#, c-format
+msgid "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"
+msgstr ""
+
+#: sparc-dis.c:822
+#, c-format
+msgid "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"
+msgstr ""
+
+#: sparc-dis.c:871
+#, c-format
+msgid "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"
+msgstr ""
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
new file mode 100644
index 00000000000..70716ea2471
--- /dev/null
+++ b/opcodes/ppc-dis.c
@@ -0,0 +1,238 @@
+/* ppc-dis.c -- Disassemble PowerPC instructions
+ Copyright 1994 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "opcode/ppc.h"
+
+/* This file provides several disassembler functions, all of which use
+ the disassembler interface defined in dis-asm.h. Several functions
+ are provided because this file handles disassembly for the PowerPC
+ in both big and little endian mode and also for the POWER (RS/6000)
+ chip. */
+
+static int print_insn_powerpc PARAMS ((bfd_vma, struct disassemble_info *,
+ int bigendian, int dialect));
+
+/* Print a big endian PowerPC instruction. For convenience, also
+ disassemble instructions supported by the Motorola PowerPC 601. */
+
+int
+print_insn_big_powerpc (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ return print_insn_powerpc (memaddr, info, 1,
+ PPC_OPCODE_PPC | PPC_OPCODE_601);
+}
+
+/* Print a little endian PowerPC instruction. For convenience, also
+ disassemble instructions supported by the Motorola PowerPC 601. */
+
+int
+print_insn_little_powerpc (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ return print_insn_powerpc (memaddr, info, 0,
+ PPC_OPCODE_PPC | PPC_OPCODE_601);
+}
+
+/* Print a POWER (RS/6000) instruction. */
+
+int
+print_insn_rs6000 (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
+}
+
+/* Print a PowerPC or POWER instruction. */
+
+static int
+print_insn_powerpc (memaddr, info, bigendian, dialect)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+ int bigendian;
+ int dialect;
+{
+ bfd_byte buffer[4];
+ int status;
+ unsigned long insn;
+ const struct powerpc_opcode *opcode;
+ const struct powerpc_opcode *opcode_end;
+ unsigned long op;
+
+ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+
+ if (bigendian)
+ insn = bfd_getb32 (buffer);
+ else
+ insn = bfd_getl32 (buffer);
+
+ /* Get the major opcode of the instruction. */
+ op = PPC_OP (insn);
+
+ /* Find the first match in the opcode table. We could speed this up
+ a bit by doing a binary search on the major opcode. */
+ opcode_end = powerpc_opcodes + powerpc_num_opcodes;
+ for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
+ {
+ unsigned long table_op;
+ const unsigned char *opindex;
+ const struct powerpc_operand *operand;
+ int invalid;
+ int need_comma;
+ int need_paren;
+
+ table_op = PPC_OP (opcode->opcode);
+ if (op < table_op)
+ break;
+ if (op > table_op)
+ continue;
+
+ if ((insn & opcode->mask) != opcode->opcode
+ || (opcode->flags & dialect) == 0)
+ continue;
+
+ /* Make two passes over the operands. First see if any of them
+ have extraction functions, and, if they do, make sure the
+ instruction is valid. */
+ invalid = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ operand = powerpc_operands + *opindex;
+ if (operand->extract)
+ (*operand->extract) (insn, &invalid);
+ }
+ if (invalid)
+ continue;
+
+ /* The instruction is valid. */
+ (*info->fprintf_func) (info->stream, "%s", opcode->name);
+ if (opcode->operands[0] != 0)
+ (*info->fprintf_func) (info->stream, "\t");
+
+ /* Now extract and print the operands. */
+ need_comma = 0;
+ need_paren = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ long value;
+
+ operand = powerpc_operands + *opindex;
+
+ /* Operands that are marked FAKE are simply ignored. We
+ already made sure that the extract function considered
+ the instruction to be valid. */
+ if ((operand->flags & PPC_OPERAND_FAKE) != 0)
+ continue;
+
+ /* Extract the value from the instruction. */
+ if (operand->extract)
+ value = (*operand->extract) (insn, (int *) NULL);
+ else
+ {
+ value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+ if ((operand->flags & PPC_OPERAND_SIGNED) != 0
+ && (value & (1 << (operand->bits - 1))) != 0)
+ value -= 1 << operand->bits;
+ }
+
+ /* If the operand is optional, and the value is zero, don't
+ print anything. */
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+ && (operand->flags & PPC_OPERAND_NEXT) == 0
+ && value == 0)
+ continue;
+
+ if (need_comma)
+ {
+ (*info->fprintf_func) (info->stream, ",");
+ need_comma = 0;
+ }
+
+ /* Print the operand as directed by the flags. */
+ if ((operand->flags & PPC_OPERAND_GPR) != 0)
+ (*info->fprintf_func) (info->stream, "r%ld", value);
+ else if ((operand->flags & PPC_OPERAND_FPR) != 0)
+ (*info->fprintf_func) (info->stream, "f%ld", value);
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+ (*info->print_address_func) (memaddr + value, info);
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+ (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
+ else if ((operand->flags & PPC_OPERAND_CR) == 0
+ || (dialect & PPC_OPCODE_PPC) == 0)
+ (*info->fprintf_func) (info->stream, "%ld", value);
+ else
+ {
+ if (operand->bits == 3)
+ (*info->fprintf_func) (info->stream, "cr%d", value);
+ else
+ {
+ static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
+ int cr;
+ int cc;
+
+ cr = value >> 2;
+ if (cr != 0)
+ (*info->fprintf_func) (info->stream, "4*cr%d", cr);
+ cc = value & 3;
+ if (cc != 0)
+ {
+ if (cr != 0)
+ (*info->fprintf_func) (info->stream, "+");
+ (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
+ }
+ }
+ }
+
+ if (need_paren)
+ {
+ (*info->fprintf_func) (info->stream, ")");
+ need_paren = 0;
+ }
+
+ if ((operand->flags & PPC_OPERAND_PARENS) == 0)
+ need_comma = 1;
+ else
+ {
+ (*info->fprintf_func) (info->stream, "(");
+ need_paren = 1;
+ }
+ }
+
+ /* We have found and printed an instruction; return. */
+ return 4;
+ }
+
+ /* We could not find a match. */
+ (*info->fprintf_func) (info->stream, ".long 0x%lx", insn);
+
+ return 4;
+}
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
new file mode 100644
index 00000000000..59218805da8
--- /dev/null
+++ b/opcodes/ppc-opc.c
@@ -0,0 +1,3124 @@
+/* ppc-opc.c -- PowerPC opcode list
+ Copyright (c) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+2, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/ppc.h"
+#include "opintl.h"
+
+/* This file holds the PowerPC opcode table. The opcode table
+ includes almost all of the extended instruction mnemonics. This
+ permits the disassembler to use them, and simplifies the assembler
+ logic, at the cost of increasing the table size. The table is
+ strictly constant data, so the compiler should be able to put it in
+ the .text section.
+
+ This file also holds the operand table. All knowledge about
+ inserting operands into instructions and vice-versa is kept in this
+ file. */
+
+/* Local insertion and extraction functions. */
+
+static unsigned long insert_bat PARAMS ((unsigned long, long, const char **));
+static long extract_bat PARAMS ((unsigned long, int *));
+static unsigned long insert_bba PARAMS ((unsigned long, long, const char **));
+static long extract_bba PARAMS ((unsigned long, int *));
+static unsigned long insert_bd PARAMS ((unsigned long, long, const char **));
+static long extract_bd PARAMS ((unsigned long, int *));
+static unsigned long insert_bdm PARAMS ((unsigned long, long, const char **));
+static long extract_bdm PARAMS ((unsigned long, int *));
+static unsigned long insert_bdp PARAMS ((unsigned long, long, const char **));
+static long extract_bdp PARAMS ((unsigned long, int *));
+static int valid_bo PARAMS ((long));
+static unsigned long insert_bo PARAMS ((unsigned long, long, const char **));
+static long extract_bo PARAMS ((unsigned long, int *));
+static unsigned long insert_boe PARAMS ((unsigned long, long, const char **));
+static long extract_boe PARAMS ((unsigned long, int *));
+static unsigned long insert_ds PARAMS ((unsigned long, long, const char **));
+static long extract_ds PARAMS ((unsigned long, int *));
+static unsigned long insert_li PARAMS ((unsigned long, long, const char **));
+static long extract_li PARAMS ((unsigned long, int *));
+static unsigned long insert_mbe PARAMS ((unsigned long, long, const char **));
+static long extract_mbe PARAMS ((unsigned long, int *));
+static unsigned long insert_mb6 PARAMS ((unsigned long, long, const char **));
+static long extract_mb6 PARAMS ((unsigned long, int *));
+static unsigned long insert_nb PARAMS ((unsigned long, long, const char **));
+static long extract_nb PARAMS ((unsigned long, int *));
+static unsigned long insert_nsi PARAMS ((unsigned long, long, const char **));
+static long extract_nsi PARAMS ((unsigned long, int *));
+static unsigned long insert_ral PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ram PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ras PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_rbs PARAMS ((unsigned long, long, const char **));
+static long extract_rbs PARAMS ((unsigned long, int *));
+static unsigned long insert_sh6 PARAMS ((unsigned long, long, const char **));
+static long extract_sh6 PARAMS ((unsigned long, int *));
+static unsigned long insert_spr PARAMS ((unsigned long, long, const char **));
+static long extract_spr PARAMS ((unsigned long, int *));
+static unsigned long insert_tbr PARAMS ((unsigned long, long, const char **));
+static long extract_tbr PARAMS ((unsigned long, int *));
+
+/* The operands table.
+
+ The fields are bits, shift, insert, extract, flags.
+
+ We used to put parens around the various additions, like the one
+ for BA just below. However, that caused trouble with feeble
+ compilers with a limit on depth of a parenthesized expression, like
+ (reportedly) the compiler in Microsoft Developer Studio 5. So we
+ omit the parens, since the macros are never used in a context where
+ the addition will be ambiguous. */
+
+const struct powerpc_operand powerpc_operands[] =
+{
+ /* The zero index is used to indicate the end of the list of
+ operands. */
+#define UNUSED 0
+ { 0, 0, 0, 0, 0 },
+
+ /* The BA field in an XL form instruction. */
+#define BA UNUSED + 1
+#define BA_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_CR },
+
+ /* The BA field in an XL form instruction when it must be the same
+ as the BT field in the same instruction. */
+#define BAT BA + 1
+ { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
+
+ /* The BB field in an XL form instruction. */
+#define BB BAT + 1
+#define BB_MASK (0x1f << 11)
+ { 5, 11, 0, 0, PPC_OPERAND_CR },
+
+ /* The BB field in an XL form instruction when it must be the same
+ as the BA field in the same instruction. */
+#define BBA BB + 1
+ { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
+
+ /* The BD field in a B form instruction. The lower two bits are
+ forced to zero. */
+#define BD BBA + 1
+ { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when absolute addressing is
+ used. */
+#define BDA BD + 1
+ { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the - modifier is used.
+ This sets the y bit of the BO field appropriately. */
+#define BDM BDA + 1
+ { 16, 0, insert_bdm, extract_bdm,
+ PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the - modifier is used
+ and absolute address is used. */
+#define BDMA BDM + 1
+ { 16, 0, insert_bdm, extract_bdm,
+ PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the + modifier is used.
+ This sets the y bit of the BO field appropriately. */
+#define BDP BDMA + 1
+ { 16, 0, insert_bdp, extract_bdp,
+ PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the + modifier is used
+ and absolute addressing is used. */
+#define BDPA BDP + 1
+ { 16, 0, insert_bdp, extract_bdp,
+ PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The BF field in an X or XL form instruction. */
+#define BF BDPA + 1
+ { 3, 23, 0, 0, PPC_OPERAND_CR },
+
+ /* An optional BF field. This is used for comparison instructions,
+ in which an omitted BF field is taken as zero. */
+#define OBF BF + 1
+ { 3, 23, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+ /* The BFA field in an X or XL form instruction. */
+#define BFA OBF + 1
+ { 3, 18, 0, 0, PPC_OPERAND_CR },
+
+ /* The BI field in a B form or XL form instruction. */
+#define BI BFA + 1
+#define BI_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_CR },
+
+ /* The BO field in a B form instruction. Certain values are
+ illegal. */
+#define BO BI + 1
+#define BO_MASK (0x1f << 21)
+ { 5, 21, insert_bo, extract_bo, 0 },
+
+ /* The BO field in a B form instruction when the + or - modifier is
+ used. This is like the BO field, but it must be even. */
+#define BOE BO + 1
+ { 5, 21, insert_boe, extract_boe, 0 },
+
+ /* The BT field in an X or XL form instruction. */
+#define BT BOE + 1
+ { 5, 21, 0, 0, PPC_OPERAND_CR },
+
+ /* The condition register number portion of the BI field in a B form
+ or XL form instruction. This is used for the extended
+ conditional branch mnemonics, which set the lower two bits of the
+ BI field. This field is optional. */
+#define CR BT + 1
+ { 3, 18, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+ /* The D field in a D form instruction. This is a displacement off
+ a register, and implies that the next operand is a register in
+ parentheses. */
+#define D CR + 1
+ { 16, 0, 0, 0, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+ /* The DS field in a DS form instruction. This is like D, but the
+ lower two bits are forced to zero. */
+#define DS D + 1
+ { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+ /* The E field in a wrteei instruction. */
+#define E DS + 1
+ { 1, 15, 0, 0, 0 },
+
+ /* The FL1 field in a POWER SC form instruction. */
+#define FL1 E + 1
+ { 4, 12, 0, 0, 0 },
+
+ /* The FL2 field in a POWER SC form instruction. */
+#define FL2 FL1 + 1
+ { 3, 2, 0, 0, 0 },
+
+ /* The FLM field in an XFL form instruction. */
+#define FLM FL2 + 1
+ { 8, 17, 0, 0, 0 },
+
+ /* The FRA field in an X or A form instruction. */
+#define FRA FLM + 1
+#define FRA_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FRB field in an X or A form instruction. */
+#define FRB FRA + 1
+#define FRB_MASK (0x1f << 11)
+ { 5, 11, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FRC field in an A form instruction. */
+#define FRC FRB + 1
+#define FRC_MASK (0x1f << 6)
+ { 5, 6, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FRS field in an X form instruction or the FRT field in a D, X
+ or A form instruction. */
+#define FRS FRC + 1
+#define FRT FRS
+ { 5, 21, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FXM field in an XFX instruction. */
+#define FXM FRS + 1
+#define FXM_MASK (0xff << 12)
+ { 8, 12, 0, 0, 0 },
+
+ /* The L field in a D or X form instruction. */
+#define L FXM + 1
+ { 1, 21, 0, 0, PPC_OPERAND_OPTIONAL },
+
+ /* The LEV field in a POWER SC form instruction. */
+#define LEV L + 1
+ { 7, 5, 0, 0, 0 },
+
+ /* The LI field in an I form instruction. The lower two bits are
+ forced to zero. */
+#define LI LEV + 1
+ { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The LI field in an I form instruction when used as an absolute
+ address. */
+#define LIA LI + 1
+ { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The MB field in an M form instruction. */
+#define MB LIA + 1
+#define MB_MASK (0x1f << 6)
+ { 5, 6, 0, 0, 0 },
+
+ /* The ME field in an M form instruction. */
+#define ME MB + 1
+#define ME_MASK (0x1f << 1)
+ { 5, 1, 0, 0, 0 },
+
+ /* The MB and ME fields in an M form instruction expressed a single
+ operand which is a bitmask indicating which bits to select. This
+ is a two operand form using PPC_OPERAND_NEXT. See the
+ description in opcode/ppc.h for what this means. */
+#define MBE ME + 1
+ { 5, 6, 0, 0, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
+ { 32, 0, insert_mbe, extract_mbe, 0 },
+
+ /* The MB or ME field in an MD or MDS form instruction. The high
+ bit is wrapped to the low end. */
+#define MB6 MBE + 2
+#define ME6 MB6
+#define MB6_MASK (0x3f << 5)
+ { 6, 5, insert_mb6, extract_mb6, 0 },
+
+ /* The NB field in an X form instruction. The value 32 is stored as
+ 0. */
+#define NB MB6 + 1
+ { 6, 11, insert_nb, extract_nb, 0 },
+
+ /* The NSI field in a D form instruction. This is the same as the
+ SI field, only negated. */
+#define NSI NB + 1
+ { 16, 0, insert_nsi, extract_nsi,
+ PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
+
+ /* The RA field in an D, DS, X, XO, M, or MDS form instruction. */
+#define RA NSI + 1
+#define RA_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_GPR },
+
+ /* The RA field in a D or X form instruction which is an updating
+ load, which means that the RA field may not be zero and may not
+ equal the RT field. */
+#define RAL RA + 1
+ { 5, 16, insert_ral, 0, PPC_OPERAND_GPR },
+
+ /* The RA field in an lmw instruction, which has special value
+ restrictions. */
+#define RAM RAL + 1
+ { 5, 16, insert_ram, 0, PPC_OPERAND_GPR },
+
+ /* The RA field in a D or X form instruction which is an updating
+ store or an updating floating point load, which means that the RA
+ field may not be zero. */
+#define RAS RAM + 1
+ { 5, 16, insert_ras, 0, PPC_OPERAND_GPR },
+
+ /* The RB field in an X, XO, M, or MDS form instruction. */
+#define RB RAS + 1
+#define RB_MASK (0x1f << 11)
+ { 5, 11, 0, 0, PPC_OPERAND_GPR },
+
+ /* The RB field in an X form instruction when it must be the same as
+ the RS field in the instruction. This is used for extended
+ mnemonics like mr. */
+#define RBS RB + 1
+ { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
+
+ /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
+ instruction or the RT field in a D, DS, X, XFX or XO form
+ instruction. */
+#define RS RBS + 1
+#define RT RS
+#define RT_MASK (0x1f << 21)
+ { 5, 21, 0, 0, PPC_OPERAND_GPR },
+
+ /* The SH field in an X or M form instruction. */
+#define SH RS + 1
+#define SH_MASK (0x1f << 11)
+ { 5, 11, 0, 0, 0 },
+
+ /* The SH field in an MD form instruction. This is split. */
+#define SH6 SH + 1
+#define SH6_MASK ((0x1f << 11) | (1 << 1))
+ { 6, 1, insert_sh6, extract_sh6, 0 },
+
+ /* The SI field in a D form instruction. */
+#define SI SH6 + 1
+ { 16, 0, 0, 0, PPC_OPERAND_SIGNED },
+
+ /* The SI field in a D form instruction when we accept a wide range
+ of positive values. */
+#define SISIGNOPT SI + 1
+ { 16, 0, 0, 0, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
+
+ /* The SPR field in an XFX form instruction. This is flipped--the
+ lower 5 bits are stored in the upper 5 and vice- versa. */
+#define SPR SISIGNOPT + 1
+#define SPR_MASK (0x3ff << 11)
+ { 10, 11, insert_spr, extract_spr, 0 },
+
+ /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */
+#define SPRBAT SPR + 1
+#define SPRBAT_MASK (0x3 << 17)
+ { 2, 17, 0, 0, 0 },
+
+ /* The SPRG register number in an XFX form m[ft]sprg instruction. */
+#define SPRG SPRBAT + 1
+#define SPRG_MASK (0x3 << 16)
+ { 2, 16, 0, 0, 0 },
+
+ /* The SR field in an X form instruction. */
+#define SR SPRG + 1
+ { 4, 16, 0, 0, 0 },
+
+ /* The SV field in a POWER SC form instruction. */
+#define SV SR + 1
+ { 14, 2, 0, 0, 0 },
+
+ /* The TBR field in an XFX form instruction. This is like the SPR
+ field, but it is optional. */
+#define TBR SV + 1
+ { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
+
+ /* The TO field in a D or X form instruction. */
+#define TO TBR + 1
+#define TO_MASK (0x1f << 21)
+ { 5, 21, 0, 0, 0 },
+
+ /* The U field in an X form instruction. */
+#define U TO + 1
+ { 4, 12, 0, 0, 0 },
+
+ /* The UI field in a D form instruction. */
+#define UI U + 1
+ { 16, 0, 0, 0, 0 },
+};
+
+/* The functions used to insert and extract complicated operands. */
+
+/* The BA field in an XL form instruction when it must be the same as
+ the BT field in the same instruction. This operand is marked FAKE.
+ The insertion function just copies the BT field into the BA field,
+ and the extraction function just checks that the fields are the
+ same. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bat (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 21) & 0x1f) << 16);
+}
+
+static long
+extract_bat (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+/* The BB field in an XL form instruction when it must be the same as
+ the BA field in the same instruction. This operand is marked FAKE.
+ The insertion function just copies the BA field into the BB field,
+ and the extraction function just checks that the fields are the
+ same. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bba (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 16) & 0x1f) << 11);
+}
+
+static long
+extract_bba (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+/* The BD field in a B form instruction. The lower two bits are
+ forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bd (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_bd (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the - modifier is used.
+ This modifier means that the branch is not expected to be taken.
+ We must set the y bit of the BO field to 1 if the offset is
+ negative. When extracting, we require that the y bit be 1 and that
+ the offset be positive, since if the y bit is 0 we just want to
+ print the normal form of the instruction. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdm (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if ((value & 0x8000) != 0)
+ insn |= 1 << 21;
+ return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdm (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn & (1 << 21)) == 0
+ || (insn & (1 << 15)) == 0))
+ *invalid = 1;
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the + modifier is used.
+ This is like BDM, above, except that the branch is expected to be
+ taken. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdp (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if ((value & 0x8000) == 0)
+ insn |= 1 << 21;
+ return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdp (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn & (1 << 21)) == 0
+ || (insn & (1 << 15)) != 0))
+ *invalid = 1;
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* Check for legal values of a BO field. */
+
+static int
+valid_bo (value)
+ long value;
+{
+ /* Certain encodings have bits that are required to be zero. These
+ are (z must be zero, y may be anything):
+ 001zy
+ 011zy
+ 1z00y
+ 1z01y
+ 1z1zz
+ */
+ switch (value & 0x14)
+ {
+ default:
+ case 0:
+ return 1;
+ case 0x4:
+ return (value & 0x2) == 0;
+ case 0x10:
+ return (value & 0x8) == 0;
+ case 0x14:
+ return value == 0x14;
+ }
+}
+
+/* The BO field in a B form instruction. Warn about attempts to set
+ the field to an illegal value. */
+
+static unsigned long
+insert_bo (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **) NULL
+ && ! valid_bo (value))
+ *errmsg = _("invalid conditional option");
+ return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_bo (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long value;
+
+ value = (insn >> 21) & 0x1f;
+ if (invalid != (int *) NULL
+ && ! valid_bo (value))
+ *invalid = 1;
+ return value;
+}
+
+/* The BO field in a B form instruction when the + or - modifier is
+ used. This is like the BO field, but it must be even. When
+ extracting it, we force it to be even. */
+
+static unsigned long
+insert_boe (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **) NULL)
+ {
+ if (! valid_bo (value))
+ *errmsg = _("invalid conditional option");
+ else if ((value & 1) != 0)
+ *errmsg = _("attempt to set y bit when using + or - modifier");
+ }
+ return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_boe (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long value;
+
+ value = (insn >> 21) & 0x1f;
+ if (invalid != (int *) NULL
+ && ! valid_bo (value))
+ *invalid = 1;
+ return value & 0x1e;
+}
+
+/* The DS field in a DS form instruction. This is like D, but the
+ lower two bits are forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_ds (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_ds (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* The LI field in an I form instruction. The lower two bits are
+ forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_li (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if ((value & 3) != 0 && errmsg != (const char **) NULL)
+ *errmsg = _("ignoring least significant bits in branch offset");
+ return insn | (value & 0x3fffffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_li (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if ((insn & 0x2000000) != 0)
+ return (insn & 0x3fffffc) - 0x4000000;
+ else
+ return insn & 0x3fffffc;
+}
+
+/* The MB and ME fields in an M form instruction expressed as a single
+ operand which is itself a bitmask. The extraction function always
+ marks it as invalid, since we never want to recognize an
+ instruction which uses a field of this type. */
+
+static unsigned long
+insert_mbe (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ unsigned long uval, mask;
+ int mb, me, mx, count, last;
+
+ uval = value;
+
+ if (uval == 0)
+ {
+ if (errmsg != (const char **) NULL)
+ *errmsg = _("illegal bitmask");
+ return insn;
+ }
+
+ mb = 0;
+ me = 32;
+ if ((uval & 1) != 0)
+ last = 1;
+ else
+ last = 0;
+ count = 0;
+
+ /* mb: location of last 0->1 transition */
+ /* me: location of last 1->0 transition */
+ /* count: # transitions */
+
+ for (mx = 0, mask = 1 << 31; mx < 32; ++mx, mask >>= 1)
+ {
+ if ((uval & mask) && !last)
+ {
+ ++count;
+ mb = mx;
+ last = 1;
+ }
+ else if (!(uval & mask) && last)
+ {
+ ++count;
+ me = mx;
+ last = 0;
+ }
+ }
+ if (me == 0)
+ me = 32;
+
+ if (count != 2 && (count != 0 || ! last))
+ {
+ if (errmsg != (const char **) NULL)
+ *errmsg = _("illegal bitmask");
+ }
+
+ return insn | (mb << 6) | ((me - 1) << 1);
+}
+
+static long
+extract_mbe (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long ret;
+ int mb, me;
+ int i;
+
+ if (invalid != (int *) NULL)
+ *invalid = 1;
+
+ mb = (insn >> 6) & 0x1f;
+ me = (insn >> 1) & 0x1f;
+ if (mb < me + 1)
+ {
+ ret = 0;
+ for (i = mb; i <= me; i++)
+ ret |= (long) 1 << (31 - i);
+ }
+ else if (mb == me + 1)
+ ret = ~0;
+ else /* (mb > me + 1) */
+ {
+ ret = ~ (long) 0;
+ for (i = me + 1; i < mb; i++)
+ ret &= ~ ((long) 1 << (31 - i));
+ }
+ return ret;
+}
+
+/* The MB or ME field in an MD or MDS form instruction. The high bit
+ is wrapped to the low end. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_mb6 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((value & 0x1f) << 6) | (value & 0x20);
+}
+
+/*ARGSUSED*/
+static long
+extract_mb6 (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ return ((insn >> 6) & 0x1f) | (insn & 0x20);
+}
+
+/* The NB field in an X form instruction. The value 32 is stored as
+ 0. */
+
+static unsigned long
+insert_nb (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value < 0 || value > 32)
+ *errmsg = _("value out of range");
+ if (value == 32)
+ value = 0;
+ return insn | ((value & 0x1f) << 11);
+}
+
+/*ARGSUSED*/
+static long
+extract_nb (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long ret;
+
+ ret = (insn >> 11) & 0x1f;
+ if (ret == 0)
+ ret = 32;
+ return ret;
+}
+
+/* The NSI field in a D form instruction. This is the same as the SI
+ field, only negated. The extraction function always marks it as
+ invalid, since we never want to recognize an instruction which uses
+ a field of this type. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_nsi (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((- value) & 0xffff);
+}
+
+static long
+extract_nsi (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL)
+ *invalid = 1;
+ if ((insn & 0x8000) != 0)
+ return - ((long)(insn & 0xffff) - 0x10000);
+ else
+ return - (long)(insn & 0xffff);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+ load, which means that the RA field may not be zero and may not
+ equal the RT field. */
+
+static unsigned long
+insert_ral (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value == 0
+ || (unsigned long) value == ((insn >> 21) & 0x1f))
+ *errmsg = "invalid register operand when updating";
+ return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in an lmw instruction, which has special value
+ restrictions. */
+
+static unsigned long
+insert_ram (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if ((unsigned long) value >= ((insn >> 21) & 0x1f))
+ *errmsg = _("index register in load range");
+ return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+ store or an updating floating point load, which means that the RA
+ field may not be zero. */
+
+static unsigned long
+insert_ras (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value == 0)
+ *errmsg = _("invalid register operand when updating");
+ return insn | ((value & 0x1f) << 16);
+}
+
+/* The RB field in an X form instruction when it must be the same as
+ the RS field in the instruction. This is used for extended
+ mnemonics like mr. This operand is marked FAKE. The insertion
+ function just copies the BT field into the BA field, and the
+ extraction function just checks that the fields are the same. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_rbs (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 21) & 0x1f) << 11);
+}
+
+static long
+extract_rbs (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+/* The SH field in an MD form instruction. This is split. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_sh6 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
+}
+
+/*ARGSUSED*/
+static long
+extract_sh6 (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
+}
+
+/* The SPR field in an XFX form instruction. This is flipped--the
+ lower 5 bits are stored in the upper 5 and vice- versa. */
+
+static unsigned long
+insert_spr (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_spr (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+}
+
+/* The TBR field in an XFX instruction. This is just like SPR, but it
+ is optional. When TBR is omitted, it must be inserted as 268 (the
+ magic number of the TB register). These functions treat 0
+ (indicating an omitted optional operand) as 268. This means that
+ ``mftb 4,0'' is not handled correctly. This does not matter very
+ much, since the architecture manual does not define mftb as
+ accepting any values other than 268 or 269. */
+
+#define TB (268)
+
+static unsigned long
+insert_tbr (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value == 0)
+ value = TB;
+ return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_tbr (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long ret;
+
+ ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+ if (ret == TB)
+ ret = 0;
+ return ret;
+}
+
+/* Macros used to form opcodes. */
+
+/* The main opcode. */
+#define OP(x) ((((unsigned long)(x)) & 0x3f) << 26)
+#define OP_MASK OP (0x3f)
+
+/* The main opcode combined with a trap code in the TO field of a D
+ form instruction. Used for extended mnemonics for the trap
+ instructions. */
+#define OPTO(x,to) (OP (x) | ((((unsigned long)(to)) & 0x1f) << 21))
+#define OPTO_MASK (OP_MASK | TO_MASK)
+
+/* The main opcode combined with a comparison size bit in the L field
+ of a D form or X form instruction. Used for extended mnemonics for
+ the comparison instructions. */
+#define OPL(x,l) (OP (x) | ((((unsigned long)(l)) & 1) << 21))
+#define OPL_MASK OPL (0x3f,1)
+
+/* An A form instruction. */
+#define A(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1f) << 1) | (((unsigned long)(rc)) & 1))
+#define A_MASK A (0x3f, 0x1f, 1)
+
+/* An A_MASK with the FRB field fixed. */
+#define AFRB_MASK (A_MASK | FRB_MASK)
+
+/* An A_MASK with the FRC field fixed. */
+#define AFRC_MASK (A_MASK | FRC_MASK)
+
+/* An A_MASK with the FRA and FRC fields fixed. */
+#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
+
+/* A B form instruction. */
+#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1))
+#define B_MASK B (0x3f, 1, 1)
+
+/* A B form instruction setting the BO field. */
+#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
+#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
+
+/* A BBO_MASK with the y bit of the BO field removed. This permits
+ matching a conditional branch regardless of the setting of the y
+ bit. */
+#define Y_MASK (((unsigned long)1) << 21)
+#define BBOY_MASK (BBO_MASK &~ Y_MASK)
+
+/* A B form instruction setting the BO field and the condition bits of
+ the BI field. */
+#define BBOCB(op, bo, cb, aa, lk) \
+ (BBO ((op), (bo), (aa), (lk)) | ((((unsigned long)(cb)) & 0x3) << 16))
+#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
+
+/* A BBOCB_MASK with the y bit of the BO field removed. */
+#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
+
+/* A BBOYCB_MASK in which the BI field is fixed. */
+#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
+
+/* The main opcode mask with the RA field clear. */
+#define DRA_MASK (OP_MASK | RA_MASK)
+
+/* A DS form instruction. */
+#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
+#define DS_MASK DSO (0x3f, 3)
+
+/* An M form instruction. */
+#define M(op, rc) (OP (op) | ((rc) & 1))
+#define M_MASK M (0x3f, 1)
+
+/* An M form instruction with the ME field specified. */
+#define MME(op, me, rc) (M ((op), (rc)) | ((((unsigned long)(me)) & 0x1f) << 1))
+
+/* An M_MASK with the MB and ME fields fixed. */
+#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
+
+/* An M_MASK with the SH and ME fields fixed. */
+#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
+
+/* An MD form instruction. */
+#define MD(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x7) << 2) | ((rc) & 1))
+#define MD_MASK MD (0x3f, 0x7, 1)
+
+/* An MD_MASK with the MB field fixed. */
+#define MDMB_MASK (MD_MASK | MB6_MASK)
+
+/* An MD_MASK with the SH field fixed. */
+#define MDSH_MASK (MD_MASK | SH6_MASK)
+
+/* An MDS form instruction. */
+#define MDS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0xf) << 1) | ((rc) & 1))
+#define MDS_MASK MDS (0x3f, 0xf, 1)
+
+/* An MDS_MASK with the MB field fixed. */
+#define MDSMB_MASK (MDS_MASK | MB6_MASK)
+
+/* An SC form instruction. */
+#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1))
+#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1)
+
+/* An X form instruction. */
+#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
+
+/* An X form instruction with the RC bit specified. */
+#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
+
+/* The mask for an X form instruction. */
+#define X_MASK XRC (0x3f, 0x3ff, 1)
+
+/* An X_MASK with the RA field fixed. */
+#define XRA_MASK (X_MASK | RA_MASK)
+
+/* An X_MASK with the RB field fixed. */
+#define XRB_MASK (X_MASK | RB_MASK)
+
+/* An X_MASK with the RT field fixed. */
+#define XRT_MASK (X_MASK | RT_MASK)
+
+/* An X_MASK with the RA and RB fields fixed. */
+#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
+
+/* An X_MASK with the RT and RA fields fixed. */
+#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
+
+/* An X form comparison instruction. */
+#define XCMPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21))
+
+/* The mask for an X form comparison instruction. */
+#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22))
+
+/* The mask for an X form comparison instruction with the L field
+ fixed. */
+#define XCMPL_MASK (XCMP_MASK | (((unsigned long)1) << 21))
+
+/* An X form trap instruction with the TO field specified. */
+#define XTO(op, xop, to) (X ((op), (xop)) | ((((unsigned long)(to)) & 0x1f) << 21))
+#define XTO_MASK (X_MASK | TO_MASK)
+
+/* An XFL form instruction. */
+#define XFL(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1) | (((unsigned long)(rc)) & 1))
+#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (((unsigned long)1) << 25) | (((unsigned long)1) << 16))
+
+/* An XL form instruction with the LK field set to 0. */
+#define XL(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
+
+/* An XL form instruction which uses the LK field. */
+#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
+
+/* The mask for an XL form instruction. */
+#define XL_MASK XLLK (0x3f, 0x3ff, 1)
+
+/* An XL form instruction which explicitly sets the BO field. */
+#define XLO(op, bo, xop, lk) \
+ (XLLK ((op), (xop), (lk)) | ((((unsigned long)(bo)) & 0x1f) << 21))
+#define XLO_MASK (XL_MASK | BO_MASK)
+
+/* An XL form instruction which explicitly sets the y bit of the BO
+ field. */
+#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | ((((unsigned long)(y)) & 1) << 21))
+#define XLYLK_MASK (XL_MASK | Y_MASK)
+
+/* An XL form instruction which sets the BO field and the condition
+ bits of the BI field. */
+#define XLOCB(op, bo, cb, xop, lk) \
+ (XLO ((op), (bo), (xop), (lk)) | ((((unsigned long)(cb)) & 3) << 16))
+#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
+
+/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */
+#define XLBB_MASK (XL_MASK | BB_MASK)
+#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
+#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
+
+/* An XL_MASK with the BO and BB fields fixed. */
+#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
+
+/* An XL_MASK with the BO, BI and BB fields fixed. */
+#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
+
+/* An XO form instruction. */
+#define XO(op, xop, oe, rc) \
+ (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1) | ((((unsigned long)(oe)) & 1) << 10) | (((unsigned long)(rc)) & 1))
+#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
+
+/* An XO_MASK with the RB field fixed. */
+#define XORB_MASK (XO_MASK | RB_MASK)
+
+/* An XS form instruction. */
+#define XS(op, xop, rc) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 2) | (((unsigned long)(rc)) & 1))
+#define XS_MASK XS (0x3f, 0x1ff, 1)
+
+/* A mask for the FXM version of an XFX form instruction. */
+#define XFXFXM_MASK (X_MASK | (((unsigned long)1) << 20) | (((unsigned long)1) << 11))
+
+/* An XFX form instruction with the FXM field filled in. */
+#define XFXM(op, xop, fxm) \
+ (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12))
+
+/* An XFX form instruction with the SPR field filled in. */
+#define XSPR(op, xop, spr) \
+ (X ((op), (xop)) | ((((unsigned long)(spr)) & 0x1f) << 16) | ((((unsigned long)(spr)) & 0x3e0) << 6))
+#define XSPR_MASK (X_MASK | SPR_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+ SPRBAT field. */
+#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+ SPRG field. */
+#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
+
+/* An X form instruction with everything filled in except the E field. */
+#define XE_MASK (0xffff7fff)
+
+/* The BO encodings used in extended conditional branch mnemonics. */
+#define BODNZF (0x0)
+#define BODNZFP (0x1)
+#define BODZF (0x2)
+#define BODZFP (0x3)
+#define BOF (0x4)
+#define BOFP (0x5)
+#define BODNZT (0x8)
+#define BODNZTP (0x9)
+#define BODZT (0xa)
+#define BODZTP (0xb)
+#define BOT (0xc)
+#define BOTP (0xd)
+#define BODNZ (0x10)
+#define BODNZP (0x11)
+#define BODZ (0x12)
+#define BODZP (0x13)
+#define BOU (0x14)
+
+/* The BI condition bit encodings used in extended conditional branch
+ mnemonics. */
+#define CBLT (0)
+#define CBGT (1)
+#define CBEQ (2)
+#define CBSO (3)
+
+/* The TO encodings used in extended trap mnemonics. */
+#define TOLGT (0x1)
+#define TOLLT (0x2)
+#define TOEQ (0x4)
+#define TOLGE (0x5)
+#define TOLNL (0x5)
+#define TOLLE (0x6)
+#define TOLNG (0x6)
+#define TOGT (0x8)
+#define TOGE (0xc)
+#define TONL (0xc)
+#define TOLT (0x10)
+#define TOLE (0x14)
+#define TONG (0x14)
+#define TONE (0x18)
+#define TOU (0x1f)
+
+/* Smaller names for the flags so each entry in the opcodes table will
+ fit on a single line. */
+#undef PPC
+#define PPC PPC_OPCODE_PPC | PPC_OPCODE_ANY
+#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
+#define PPC32 PPC_OPCODE_PPC | PPC_OPCODE_32 | PPC_OPCODE_ANY
+#define PPC64 PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_ANY
+#define PPCONLY PPC_OPCODE_PPC
+#define PPC403 PPC
+#define PPC750 PPC
+#define PPC860 PPC
+#define POWER PPC_OPCODE_POWER | PPC_OPCODE_ANY
+#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY
+#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY
+#define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_ANY | PPC_OPCODE_32
+#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
+#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY | PPC_OPCODE_32
+#define M601 PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_ANY
+#define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
+#define MFDEC1 PPC_OPCODE_POWER
+#define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601
+
+/* The opcode table.
+
+ The format of the opcode table is:
+
+ NAME OPCODE MASK FLAGS { OPERANDS }
+
+ NAME is the name of the instruction.
+ OPCODE is the instruction opcode.
+ MASK is the opcode mask; this is used to tell the disassembler
+ which bits in the actual opcode must match OPCODE.
+ FLAGS are flags indicated what processors support the instruction.
+ OPERANDS is the list of operands.
+
+ The disassembler reads the table in order and prints the first
+ instruction which matches, so this table is sorted to put more
+ specific instructions before more general instructions. It is also
+ sorted by major opcode. */
+
+const struct powerpc_opcode powerpc_opcodes[] = {
+{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlgei", OPTO(2,TOLGE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlnli", OPTO(2,TOLNL), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdllei", OPTO(2,TOLLE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlngi", OPTO(2,TOLNG), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdgti", OPTO(2,TOGT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdgei", OPTO(2,TOGE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdnli", OPTO(2,TONL), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlti", OPTO(2,TOLT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlei", OPTO(2,TOLE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdngi", OPTO(2,TONG), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdnei", OPTO(2,TONE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdi", OP(2), OP_MASK, PPC64, { TO, RA, SI } },
+
+{ "twlgti", OPTO(3,TOLGT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlgti", OPTO(3,TOLGT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twllti", OPTO(3,TOLLT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tllti", OPTO(3,TOLLT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "tweqi", OPTO(3,TOEQ), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "teqi", OPTO(3,TOEQ), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlgei", OPTO(3,TOLGE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlgei", OPTO(3,TOLGE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlnli", OPTO(3,TOLNL), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlnli", OPTO(3,TOLNL), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twllei", OPTO(3,TOLLE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tllei", OPTO(3,TOLLE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlngi", OPTO(3,TOLNG), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlngi", OPTO(3,TOLNG), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twgti", OPTO(3,TOGT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tgti", OPTO(3,TOGT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twgei", OPTO(3,TOGE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tgei", OPTO(3,TOGE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twnli", OPTO(3,TONL), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tnli", OPTO(3,TONL), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlti", OPTO(3,TOLT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlti", OPTO(3,TOLT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlei", OPTO(3,TOLE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlei", OPTO(3,TOLE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twngi", OPTO(3,TONG), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tngi", OPTO(3,TONG), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twnei", OPTO(3,TONE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tnei", OPTO(3,TONE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twi", OP(3), OP_MASK, PPCCOM, { TO, RA, SI } },
+{ "ti", OP(3), OP_MASK, PWRCOM, { TO, RA, SI } },
+
+{ "mulli", OP(7), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "muli", OP(7), OP_MASK, PWRCOM, { RT, RA, SI } },
+
+{ "subfic", OP(8), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "sfi", OP(8), OP_MASK, PWRCOM, { RT, RA, SI } },
+
+{ "dozi", OP(9), OP_MASK, M601, { RT, RA, SI } },
+
+{ "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI } },
+{ "cmpldi", OPL(10,1), OPL_MASK, PPC64, { OBF, RA, UI } },
+{ "cmpli", OP(10), OP_MASK, PPCONLY, { BF, L, RA, UI } },
+{ "cmpli", OP(10), OP_MASK, PWRCOM, { BF, RA, UI } },
+
+{ "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI } },
+{ "cmpdi", OPL(11,1), OPL_MASK, PPC64, { OBF, RA, SI } },
+{ "cmpi", OP(11), OP_MASK, PPCONLY, { BF, L, RA, SI } },
+{ "cmpi", OP(11), OP_MASK, PWRCOM, { BF, RA, SI } },
+
+{ "addic", OP(12), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "ai", OP(12), OP_MASK, PWRCOM, { RT, RA, SI } },
+{ "subic", OP(12), OP_MASK, PPCCOM, { RT, RA, NSI } },
+
+{ "addic.", OP(13), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "ai.", OP(13), OP_MASK, PWRCOM, { RT, RA, SI } },
+{ "subic.", OP(13), OP_MASK, PPCCOM, { RT, RA, NSI } },
+
+{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } },
+{ "lil", OP(14), DRA_MASK, PWRCOM, { RT, SI } },
+{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA } },
+{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA, NSI } },
+{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA } },
+
+{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SISIGNOPT } },
+{ "liu", OP(15), DRA_MASK, PWRCOM, { RT, SISIGNOPT } },
+{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA,SISIGNOPT } },
+{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA,SISIGNOPT } },
+{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA, NSI } },
+
+{ "bdnz-", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDM } },
+{ "bdnz+", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDP } },
+{ "bdnz", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPCCOM, { BD } },
+{ "bdn", BBO(16,BODNZ,0,0), BBOYBI_MASK, PWRCOM, { BD } },
+{ "bdnzl-", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDM } },
+{ "bdnzl+", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDP } },
+{ "bdnzl", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPCCOM, { BD } },
+{ "bdnl", BBO(16,BODNZ,0,1), BBOYBI_MASK, PWRCOM, { BD } },
+{ "bdnza-", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdnza+", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdnza", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPCCOM, { BDA } },
+{ "bdna", BBO(16,BODNZ,1,0), BBOYBI_MASK, PWRCOM, { BDA } },
+{ "bdnzla-", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdnzla+", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdnzla", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPCCOM, { BDA } },
+{ "bdnla", BBO(16,BODNZ,1,1), BBOYBI_MASK, PWRCOM, { BDA } },
+{ "bdz-", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDM } },
+{ "bdz+", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDP } },
+{ "bdz", BBO(16,BODZ,0,0), BBOYBI_MASK, COM, { BD } },
+{ "bdzl-", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDM } },
+{ "bdzl+", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDP } },
+{ "bdzl", BBO(16,BODZ,0,1), BBOYBI_MASK, COM, { BD } },
+{ "bdza-", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdza+", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdza", BBO(16,BODZ,1,0), BBOYBI_MASK, COM, { BDA } },
+{ "bdzla-", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdzla+", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdzla", BBO(16,BODZ,1,1), BBOYBI_MASK, COM, { BDA } },
+{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "blt+", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "blt", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bltl-", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bltl+", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bltl", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "blta-", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "blta+", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "blta", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bltla-", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bltla+", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bltla", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bgt-", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bgt+", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bgt", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgtl-", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bgtl+", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bgtl", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgta-", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgta+", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgta", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bgtla-", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgtla+", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgtla", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "beq-", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "beq+", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "beq", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "beql-", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "beql+", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "beql", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "beqa-", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "beqa+", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "beqa", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "beqla-", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "beqla+", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "beqla", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bso-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bso+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bso", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bsol-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bsol+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bsol", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bsoa-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bsoa+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bsoa", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bsola-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bsola+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bsola", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bun-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bun+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bun", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "bunl-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bunl+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bunl", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "buna-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "buna+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "buna", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bunla-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bunla+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bunla", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bge-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bge+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bge", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgel-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bgel+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bgel", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgea-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgea+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgea", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bgela-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgela+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgela", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnl-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnl+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnl", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnll-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnll+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnll", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnla-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnla+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnla", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnlla-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnlla+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnlla", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "ble-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "ble+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "ble", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "blel-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "blel+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "blel", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "blea-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "blea+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "blea", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "blela-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "blela+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "blela", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bng-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bng+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bng", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bngl-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bngl+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bngl", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnga-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnga+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnga", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bngla-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bngla+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bngla", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bne-", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bne+", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bne", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnel-", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnel+", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnel", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnea-", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnea+", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnea", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnela-", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnela+", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnela", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bns-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bns+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bns", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnsl-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnsl+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnsl", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnsa-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnsa+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnsa", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnsla-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnsla+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnsla", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnu-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnu+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnu", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "bnul-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnul+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnul", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "bnua-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnua+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnua", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bnula-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnula+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnula", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bdnzt-", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnzt+", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnzt", BBO(16,BODNZT,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnztl", BBO(16,BODNZT,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnzta", BBO(16,BODNZT,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdnzf-", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnzf+", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnzf", BBO(16,BODNZF,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnzfl", BBO(16,BODNZF,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnzfa", BBO(16,BODNZF,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bt-", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bt+", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bt", BBO(16,BOT,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbt", BBO(16,BOT,0,0), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "btl-", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "btl+", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "btl", BBO(16,BOT,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbtl", BBO(16,BOT,0,1), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "bta-", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bta+", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bta", BBO(16,BOT,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbta", BBO(16,BOT,1,0), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "btla-", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "btla+", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "btla", BBO(16,BOT,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbtla", BBO(16,BOT,1,1), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "bf-", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bf+", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bf", BBO(16,BOF,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbf", BBO(16,BOF,0,0), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "bfl-", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bfl+", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bfl", BBO(16,BOF,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbfl", BBO(16,BOF,0,1), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "bfa-", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bfa+", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bfa", BBO(16,BOF,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbfa", BBO(16,BOF,1,0), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "bfla-", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bfla+", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bfla", BBO(16,BOF,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbfla", BBO(16,BOF,1,1), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "bdzt-", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdzt+", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdzt", BBO(16,BODZT,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdztl-", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdztl+", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdztl", BBO(16,BODZT,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdzta-", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdzta+", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdzta", BBO(16,BODZT,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdztla", BBO(16,BODZT,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdzf-", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdzf+", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdzf", BBO(16,BODZF,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdzfl-", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdzfl+", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdzfl", BBO(16,BODZF,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdzfa-", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdzfa+", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdzfa", BBO(16,BODZF,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdzfla", BBO(16,BODZF,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bc-", B(16,0,0), B_MASK, PPC, { BOE, BI, BDM } },
+{ "bc+", B(16,0,0), B_MASK, PPC, { BOE, BI, BDP } },
+{ "bc", B(16,0,0), B_MASK, COM, { BO, BI, BD } },
+{ "bcl-", B(16,0,1), B_MASK, PPC, { BOE, BI, BDM } },
+{ "bcl+", B(16,0,1), B_MASK, PPC, { BOE, BI, BDP } },
+{ "bcl", B(16,0,1), B_MASK, COM, { BO, BI, BD } },
+{ "bca-", B(16,1,0), B_MASK, PPC, { BOE, BI, BDMA } },
+{ "bca+", B(16,1,0), B_MASK, PPC, { BOE, BI, BDPA } },
+{ "bca", B(16,1,0), B_MASK, COM, { BO, BI, BDA } },
+{ "bcla-", B(16,1,1), B_MASK, PPC, { BOE, BI, BDMA } },
+{ "bcla+", B(16,1,1), B_MASK, PPC, { BOE, BI, BDPA } },
+{ "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA } },
+
+{ "sc", SC(17,1,0), 0xffffffff, PPC, { 0 } },
+{ "svc", SC(17,0,0), SC_MASK, POWER, { LEV, FL1, FL2 } },
+{ "svcl", SC(17,0,1), SC_MASK, POWER, { LEV, FL1, FL2 } },
+{ "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV } },
+{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV } },
+
+{ "b", B(18,0,0), B_MASK, COM, { LI } },
+{ "bl", B(18,0,1), B_MASK, COM, { LI } },
+{ "ba", B(18,1,0), B_MASK, COM, { LIA } },
+{ "bla", B(18,1,1), B_MASK, COM, { LIA } },
+
+{ "mcrf", XL(19,0), XLBB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } },
+
+{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "br", XLO(19,BOU,16,0), XLBOBIBB_MASK, PWRCOM, { 0 } },
+{ "blrl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "brl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PWRCOM, { 0 } },
+{ "bdnzlr", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlr", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdzlr-", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlr+", XLO(19,BODZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlrl", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bltlr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltlr-", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlr+", XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bltlrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bgtlr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtlr-", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlr+", XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bgtlrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "beqlr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqlr-", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlr+", XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "beqlrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bsolr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsolr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsor", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bsolrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsorl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bunlr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunlr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgelr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bger", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bgelrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgerl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnllr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnllr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnllrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "blelr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blelr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bler", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "blelrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blerl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnglr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnglr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnglrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnelr", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnelr-", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelr+", XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bner", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnelrl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnerl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnslr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnslr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnslrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnulr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnulr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btlr", XLO(19,BOT,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btlr-", XLO(19,BOT,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "btlr+", XLO(19,BOTP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bbtr", XLO(19,BOT,16,0), XLBOBB_MASK, PWRCOM, { BI } },
+{ "btlrl", XLO(19,BOT,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btlrl-", XLO(19,BOT,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "btlrl+", XLO(19,BOTP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bbtrl", XLO(19,BOT,16,1), XLBOBB_MASK, PWRCOM, { BI } },
+{ "bflr", XLO(19,BOF,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bflr-", XLO(19,BOF,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bflr+", XLO(19,BOFP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bbfr", XLO(19,BOF,16,0), XLBOBB_MASK, PWRCOM, { BI } },
+{ "bflrl", XLO(19,BOF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bflrl-", XLO(19,BOF,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bflrl+", XLO(19,BOFP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bbfrl", XLO(19,BOF,16,1), XLBOBB_MASK, PWRCOM, { BI } },
+{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlr", XLO(19,BODZT,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflr", XLO(19,BODZF,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bclr", XLLK(19,16,0), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bclrl", XLLK(19,16,1), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcr", XLLK(19,16,0), XLBB_MASK, PWRCOM, { BO, BI } },
+{ "bcrl", XLLK(19,16,1), XLBB_MASK, PWRCOM, { BO, BI } },
+
+{ "crnot", XL(19,33), XL_MASK, PPCCOM, { BT, BA, BBA } },
+{ "crnor", XL(19,33), XL_MASK, COM, { BT, BA, BB } },
+
+{ "rfi", XL(19,50), 0xffffffff, COM, { 0 } },
+{ "rfci", XL(19,51), 0xffffffff, PPC, { 0 } },
+
+{ "rfsvc", XL(19,82), 0xffffffff, POWER, { 0 } },
+
+{ "crandc", XL(19,129), XL_MASK, COM, { BT, BA, BB } },
+
+{ "isync", XL(19,150), 0xffffffff, PPCCOM, { 0 } },
+{ "ics", XL(19,150), 0xffffffff, PWRCOM, { 0 } },
+
+{ "crclr", XL(19,193), XL_MASK, PPCCOM, { BT, BAT, BBA } },
+{ "crxor", XL(19,193), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crnand", XL(19,225), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crand", XL(19,257), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crset", XL(19,289), XL_MASK, PPCCOM, { BT, BAT, BBA } },
+{ "creqv", XL(19,289), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crorc", XL(19,417), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crmove", XL(19,449), XL_MASK, PPCCOM, { BT, BA, BBA } },
+{ "cror", XL(19,449), XL_MASK, COM, { BT, BA, BB } },
+
+{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } },
+{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } },
+{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btctr", XLO(19,BOT,528,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btctr-", XLO(19,BOT,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "btctr+", XLO(19,BOTP,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "btctrl", XLO(19,BOT,528,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "bfctr", XLO(19,BOF,528,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bfctr-", XLO(19,BOF,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "bfctr+", XLO(19,BOFP,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "bfctrl", XLO(19,BOF,528,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "bcctr", XLLK(19,528,0), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcctrl", XLLK(19,528,1), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcc", XLLK(19,528,0), XLBB_MASK, PWRCOM, { BO, BI } },
+{ "bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, { BO, BI } },
+
+{ "rlwimi", M(20,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlimi", M(20,0), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+
+{ "rlwimi.", M(20,1), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlimi.", M(20,1), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+
+{ "rotlwi", MME(21,31,0), MMBME_MASK, PPCCOM, { RA, RS, SH } },
+{ "clrlwi", MME(21,31,0), MSHME_MASK, PPCCOM, { RA, RS, MB } },
+{ "rlwinm", M(21,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlinm", M(21,0), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+{ "rotlwi.", MME(21,31,1), MMBME_MASK, PPCCOM, { RA,RS,SH } },
+{ "clrlwi.", MME(21,31,1), MSHME_MASK, PPCCOM, { RA, RS, MB } },
+{ "rlwinm.", M(21,1), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlinm.", M(21,1), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+
+{ "rlmi", M(22,0), M_MASK, M601, { RA,RS,RB,MBE,ME } },
+{ "rlmi.", M(22,1), M_MASK, M601, { RA,RS,RB,MBE,ME } },
+
+{ "rotlw", MME(23,31,0), MMBME_MASK, PPCCOM, { RA, RS, RB } },
+{ "rlwnm", M(23,0), M_MASK, PPCCOM, { RA,RS,RB,MBE,ME } },
+{ "rlnm", M(23,0), M_MASK, PWRCOM, { RA,RS,RB,MBE,ME } },
+{ "rotlw.", MME(23,31,1), MMBME_MASK, PPCCOM, { RA, RS, RB } },
+{ "rlwnm.", M(23,1), M_MASK, PPCCOM, { RA,RS,RB,MBE,ME } },
+{ "rlnm.", M(23,1), M_MASK, PWRCOM, { RA,RS,RB,MBE,ME } },
+
+{ "nop", OP(24), 0xffffffff, PPCCOM, { 0 } },
+{ "ori", OP(24), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "oril", OP(24), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "oris", OP(25), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "oriu", OP(25), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "xori", OP(26), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "xoril", OP(26), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "xoris", OP(27), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "xoriu", OP(27), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "andi.", OP(28), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "andil.", OP(28), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "andis.", OP(29), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "andiu.", OP(29), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "rotldi", MD(30,0,0), MDMB_MASK, PPC64, { RA, RS, SH6 } },
+{ "clrldi", MD(30,0,0), MDSH_MASK, PPC64, { RA, RS, MB6 } },
+{ "rldicl", MD(30,0,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+{ "rotldi.", MD(30,0,1), MDMB_MASK, PPC64, { RA, RS, SH6 } },
+{ "clrldi.", MD(30,0,1), MDSH_MASK, PPC64, { RA, RS, MB6 } },
+{ "rldicl.", MD(30,0,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+
+{ "rldicr", MD(30,1,0), MD_MASK, PPC64, { RA, RS, SH6, ME6 } },
+{ "rldicr.", MD(30,1,1), MD_MASK, PPC64, { RA, RS, SH6, ME6 } },
+
+{ "rldic", MD(30,2,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+{ "rldic.", MD(30,2,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+
+{ "rldimi", MD(30,3,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+{ "rldimi.", MD(30,3,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+
+{ "rotld", MDS(30,8,0), MDSMB_MASK, PPC64, { RA, RS, RB } },
+{ "rldcl", MDS(30,8,0), MDS_MASK, PPC64, { RA, RS, RB, MB6 } },
+{ "rotld.", MDS(30,8,1), MDSMB_MASK, PPC64, { RA, RS, RB } },
+{ "rldcl.", MDS(30,8,1), MDS_MASK, PPC64, { RA, RS, RB, MB6 } },
+
+{ "rldcr", MDS(30,9,0), MDS_MASK, PPC64, { RA, RS, RB, ME6 } },
+{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC64, { RA, RS, RB, ME6 } },
+
+{ "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
+{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } },
+{ "cmp", X(31,0), XCMP_MASK, PPCONLY, { BF, L, RA, RB } },
+{ "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
+
+{ "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlgt", XTO(31,4,TOLGT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twllt", XTO(31,4,TOLLT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tllt", XTO(31,4,TOLLT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "tweq", XTO(31,4,TOEQ), XTO_MASK, PPCCOM, { RA, RB } },
+{ "teq", XTO(31,4,TOEQ), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlge", XTO(31,4,TOLGE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlge", XTO(31,4,TOLGE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlnl", XTO(31,4,TOLNL), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlnl", XTO(31,4,TOLNL), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlle", XTO(31,4,TOLLE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlle", XTO(31,4,TOLLE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlng", XTO(31,4,TOLNG), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlng", XTO(31,4,TOLNG), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twgt", XTO(31,4,TOGT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tgt", XTO(31,4,TOGT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twge", XTO(31,4,TOGE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tge", XTO(31,4,TOGE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twnl", XTO(31,4,TONL), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tnl", XTO(31,4,TONL), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlt", XTO(31,4,TOLT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlt", XTO(31,4,TOLT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twle", XTO(31,4,TOLE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tle", XTO(31,4,TOLE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twng", XTO(31,4,TONG), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tng", XTO(31,4,TONG), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twne", XTO(31,4,TONE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tne", XTO(31,4,TONE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "trap", XTO(31,4,TOU), 0xffffffff, PPCCOM, { 0 } },
+{ "tw", X(31,4), X_MASK, PPCCOM, { TO, RA, RB } },
+{ "t", X(31,4), X_MASK, PWRCOM, { TO, RA, RB } },
+
+{ "subfc", XO(31,8,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sf", XO(31,8,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subc", XO(31,8,0,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfc.", XO(31,8,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sf.", XO(31,8,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subc.", XO(31,8,0,1), XO_MASK, PPCCOM, { RT, RB, RA } },
+{ "subfco", XO(31,8,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfo", XO(31,8,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subco", XO(31,8,1,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfco.", XO(31,8,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfo.", XO(31,8,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RB, RA } },
+
+{ "mulhdu", XO(31,9,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulhdu.", XO(31,9,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "addc", XO(31,10,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "a", XO(31,10,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addc.", XO(31,10,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "a.", XO(31,10,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addco", XO(31,10,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ao", XO(31,10,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addco.", XO(31,10,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ao.", XO(31,10,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "mulhwu", XO(31,11,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "mulhwu.", XO(31,11,0,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "mfcr", X(31,19), XRARB_MASK, COM, { RT } },
+
+{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } },
+
+{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA, RB } },
+
+{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA, RB } },
+{ "lx", X(31,23), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sl", XRC(31,24,0), X_MASK, PWRCOM, { RA, RS, RB } },
+{ "slw.", XRC(31,24,1), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sl.", XRC(31,24,1), X_MASK, PWRCOM, { RA, RS, RB } },
+
+{ "cntlzw", XRC(31,26,0), XRB_MASK, PPCCOM, { RA, RS } },
+{ "cntlz", XRC(31,26,0), XRB_MASK, PWRCOM, { RA, RS } },
+{ "cntlzw.", XRC(31,26,1), XRB_MASK, PPCCOM, { RA, RS } },
+{ "cntlz.", XRC(31,26,1), XRB_MASK, PWRCOM, { RA, RS } },
+
+{ "sld", XRC(31,27,0), X_MASK, PPC64, { RA, RS, RB } },
+{ "sld.", XRC(31,27,1), X_MASK, PPC64, { RA, RS, RB } },
+
+{ "and", XRC(31,28,0), X_MASK, COM, { RA, RS, RB } },
+{ "and.", XRC(31,28,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "maskg", XRC(31,29,0), X_MASK, M601, { RA, RS, RB } },
+{ "maskg.", XRC(31,29,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
+{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB } },
+{ "cmpl", X(31,32), XCMP_MASK, PPCONLY, { BF, L, RA, RB } },
+{ "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
+
+{ "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subf.", XO(31,40,0,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "sub.", XO(31,40,0,1), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfo", XO(31,40,1,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "subo", XO(31,40,1,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "subo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RB, RA } },
+
+{ "ldux", X(31,53), X_MASK, PPC64, { RT, RAL, RB } },
+
+{ "dcbst", X(31,54), XRT_MASK, PPC, { RA, RB } },
+
+{ "lwzux", X(31,55), X_MASK, PPCCOM, { RT, RAL, RB } },
+{ "lux", X(31,55), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "cntlzd", XRC(31,58,0), XRB_MASK, PPC64, { RA, RS } },
+{ "cntlzd.", XRC(31,58,1), XRB_MASK, PPC64, { RA, RS } },
+
+{ "andc", XRC(31,60,0), X_MASK, COM, { RA, RS, RB } },
+{ "andc.", XRC(31,60,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "tdlgt", XTO(31,68,TOLGT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdllt", XTO(31,68,TOLLT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdeq", XTO(31,68,TOEQ), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlge", XTO(31,68,TOLGE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlnl", XTO(31,68,TOLNL), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlle", XTO(31,68,TOLLE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlng", XTO(31,68,TOLNG), XTO_MASK, PPC64, { RA, RB } },
+{ "tdgt", XTO(31,68,TOGT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdge", XTO(31,68,TOGE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdnl", XTO(31,68,TONL), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlt", XTO(31,68,TOLT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdle", XTO(31,68,TOLE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdng", XTO(31,68,TONG), XTO_MASK, PPC64, { RA, RB } },
+{ "tdne", XTO(31,68,TONE), XTO_MASK, PPC64, { RA, RB } },
+{ "td", X(31,68), X_MASK, PPC64, { TO, RA, RB } },
+
+{ "mulhd", XO(31,73,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulhd.", XO(31,73,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "mulhw", XO(31,75,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "mulhw.", XO(31,75,0,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "mfmsr", X(31,83), XRARB_MASK, COM, { RT } },
+
+{ "ldarx", X(31,84), X_MASK, PPC64, { RT, RA, RB } },
+
+{ "dcbf", X(31,86), XRT_MASK, PPC, { RA, RB } },
+
+{ "lbzx", X(31,87), X_MASK, COM, { RT, RA, RB } },
+
+{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } },
+{ "neg.", XO(31,104,0,1), XORB_MASK, COM, { RT, RA } },
+{ "nego", XO(31,104,1,0), XORB_MASK, COM, { RT, RA } },
+{ "nego.", XO(31,104,1,1), XORB_MASK, COM, { RT, RA } },
+
+{ "mul", XO(31,107,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "mul.", XO(31,107,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "mulo", XO(31,107,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "mulo.", XO(31,107,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "clf", X(31,118), XRB_MASK, POWER, { RT, RA } },
+
+{ "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB } },
+
+{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } },
+{ "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB } },
+{ "not.", XRC(31,124,1), X_MASK, COM, { RA, RS, RBS } },
+{ "nor.", XRC(31,124,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "wrtee", X(31,131), XRARB_MASK, PPC403, { RS } },
+
+{ "subfe", XO(31,136,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfe", XO(31,136,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subfe.", XO(31,136,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfe.", XO(31,136,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subfeo", XO(31,136,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfeo", XO(31,136,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subfeo.", XO(31,136,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfeo.", XO(31,136,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "adde", XO(31,138,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ae", XO(31,138,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "adde.", XO(31,138,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ae.", XO(31,138,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addeo", XO(31,138,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "aeo", XO(31,138,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addeo.", XO(31,138,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "aeo.", XO(31,138,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "mtcr", XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, COM, { RS }},
+{ "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } },
+
+{ "mtmsr", X(31,146), XRARB_MASK, COM, { RS } },
+
+{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA, RB } },
+
+{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA, RB } },
+
+{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA, RB } },
+{ "stx", X(31,151), X_MASK, PWRCOM, { RS, RA, RB } },
+
+{ "slq", XRC(31,152,0), X_MASK, M601, { RA, RS, RB } },
+{ "slq.", XRC(31,152,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sle", XRC(31,153,0), X_MASK, M601, { RA, RS, RB } },
+{ "sle.", XRC(31,153,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "wrteei", X(31,163), XE_MASK, PPC403, { E } },
+
+{ "stdux", X(31,181), X_MASK, PPC64, { RS, RAS, RB } },
+
+{ "stwux", X(31,183), X_MASK, PPCCOM, { RS, RAS, RB } },
+{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA, RB } },
+
+{ "sliq", XRC(31,184,0), X_MASK, M601, { RA, RS, SH } },
+{ "sliq.", XRC(31,184,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "subfze", XO(31,200,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfze", XO(31,200,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfze.", XO(31,200,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfze.", XO(31,200,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfzeo", XO(31,200,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfzeo.", XO(31,200,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "addze", XO(31,202,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "aze", XO(31,202,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addze.", XO(31,202,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "aze.", XO(31,202,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addzeo", XO(31,202,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "azeo", XO(31,202,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "azeo.", XO(31,202,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "mtsr", X(31,210), XRB_MASK|(1<<20), COM32, { SR, RS } },
+
+{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA, RB } },
+
+{ "stbx", X(31,215), X_MASK, COM, { RS, RA, RB } },
+
+{ "sllq", XRC(31,216,0), X_MASK, M601, { RA, RS, RB } },
+{ "sllq.", XRC(31,216,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sleq", XRC(31,217,0), X_MASK, M601, { RA, RS, RB } },
+{ "sleq.", XRC(31,217,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "subfme", XO(31,232,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfme", XO(31,232,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfme.", XO(31,232,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfme.", XO(31,232,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfmeo", XO(31,232,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfmeo.", XO(31,232,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "mulld", XO(31,233,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulld.", XO(31,233,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulldo", XO(31,233,1,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulldo.", XO(31,233,1,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "addme", XO(31,234,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ame", XO(31,234,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addme.", XO(31,234,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ame.", XO(31,234,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addmeo", XO(31,234,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ameo", XO(31,234,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ameo.", XO(31,234,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "mullw", XO(31,235,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "muls", XO(31,235,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "mullw.", XO(31,235,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "muls.", XO(31,235,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "mullwo", XO(31,235,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "mulso", XO(31,235,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "mullwo.", XO(31,235,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "mulso.", XO(31,235,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "mtsrin", X(31,242), XRA_MASK, PPC32, { RS, RB } },
+{ "mtsri", X(31,242), XRA_MASK, POWER32, { RS, RB } },
+
+{ "dcbtst", X(31,246), XRT_MASK, PPC, { RA, RB } },
+
+{ "stbux", X(31,247), X_MASK, COM, { RS, RAS, RB } },
+
+{ "slliq", XRC(31,248,0), X_MASK, M601, { RA, RS, SH } },
+{ "slliq.", XRC(31,248,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "doz", XO(31,264,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "doz.", XO(31,264,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "dozo", XO(31,264,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "dozo.", XO(31,264,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "add", XO(31,266,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "cax", XO(31,266,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "add.", XO(31,266,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "cax.", XO(31,266,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addo", XO(31,266,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "caxo", XO(31,266,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } },
+{ "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB } },
+
+{ "dcbt", X(31,278), XRT_MASK, PPC, { RA, RB } },
+
+{ "lhzx", X(31,279), X_MASK, COM, { RT, RA, RB } },
+
+{ "icbt", X(31,262), XRT_MASK, PPC, { RA, RB } },
+
+{ "eqv", XRC(31,284,0), X_MASK, COM, { RA, RS, RB } },
+{ "eqv.", XRC(31,284,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "tlbie", X(31,306), XRTRA_MASK, PPC, { RB } },
+{ "tlbi", X(31,306), XRT_MASK, POWER, { RA, RB } },
+
+{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB } },
+
+{ "lhzux", X(31,311), X_MASK, COM, { RT, RAL, RB } },
+
+{ "xor", XRC(31,316,0), X_MASK, COM, { RA, RS, RB } },
+{ "xor.", XRC(31,316,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "mfexisr", XSPR(31,323,64), XSPR_MASK, PPC403, { RT } },
+{ "mfexier", XSPR(31,323,66), XSPR_MASK, PPC403, { RT } },
+{ "mfbr0", XSPR(31,323,128), XSPR_MASK, PPC403, { RT } },
+{ "mfbr1", XSPR(31,323,129), XSPR_MASK, PPC403, { RT } },
+{ "mfbr2", XSPR(31,323,130), XSPR_MASK, PPC403, { RT } },
+{ "mfbr3", XSPR(31,323,131), XSPR_MASK, PPC403, { RT } },
+{ "mfbr4", XSPR(31,323,132), XSPR_MASK, PPC403, { RT } },
+{ "mfbr5", XSPR(31,323,133), XSPR_MASK, PPC403, { RT } },
+{ "mfbr6", XSPR(31,323,134), XSPR_MASK, PPC403, { RT } },
+{ "mfbr7", XSPR(31,323,135), XSPR_MASK, PPC403, { RT } },
+{ "mfbear", XSPR(31,323,144), XSPR_MASK, PPC403, { RT } },
+{ "mfbesr", XSPR(31,323,145), XSPR_MASK, PPC403, { RT } },
+{ "mfiocr", XSPR(31,323,160), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacr0", XSPR(31,323,192), XSPR_MASK, PPC403, { RT } },
+{ "mfdmact0", XSPR(31,323,193), XSPR_MASK, PPC403, { RT } },
+{ "mfdmada0", XSPR(31,323,194), XSPR_MASK, PPC403, { RT } },
+{ "mfdmasa0", XSPR(31,323,195), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacc0", XSPR(31,323,196), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacr1", XSPR(31,323,200), XSPR_MASK, PPC403, { RT } },
+{ "mfdmact1", XSPR(31,323,201), XSPR_MASK, PPC403, { RT } },
+{ "mfdmada1", XSPR(31,323,202), XSPR_MASK, PPC403, { RT } },
+{ "mfdmasa1", XSPR(31,323,203), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacc1", XSPR(31,323,204), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacr2", XSPR(31,323,208), XSPR_MASK, PPC403, { RT } },
+{ "mfdmact2", XSPR(31,323,209), XSPR_MASK, PPC403, { RT } },
+{ "mfdmada2", XSPR(31,323,210), XSPR_MASK, PPC403, { RT } },
+{ "mfdmasa2", XSPR(31,323,211), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacc2", XSPR(31,323,212), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacr3", XSPR(31,323,216), XSPR_MASK, PPC403, { RT } },
+{ "mfdmact3", XSPR(31,323,217), XSPR_MASK, PPC403, { RT } },
+{ "mfdmada3", XSPR(31,323,218), XSPR_MASK, PPC403, { RT } },
+{ "mfdmasa3", XSPR(31,323,219), XSPR_MASK, PPC403, { RT } },
+{ "mfdmacc3", XSPR(31,323,220), XSPR_MASK, PPC403, { RT } },
+{ "mfdmasr", XSPR(31,323,224), XSPR_MASK, PPC403, { RT } },
+{ "mfdcr", X(31,323), X_MASK, PPC, { RT, SPR } },
+
+{ "div", XO(31,331,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "div.", XO(31,331,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "divo", XO(31,331,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "divo.", XO(31,331,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "mfmq", XSPR(31,339,0), XSPR_MASK, M601, { RT } },
+{ "mfxer", XSPR(31,339,1), XSPR_MASK, COM, { RT } },
+{ "mfrtcu", XSPR(31,339,4), XSPR_MASK, COM, { RT } },
+{ "mfrtcl", XSPR(31,339,5), XSPR_MASK, COM, { RT } },
+{ "mfdec", XSPR(31,339,6), XSPR_MASK, MFDEC1, { RT } },
+{ "mflr", XSPR(31,339,8), XSPR_MASK, COM, { RT } },
+{ "mfctr", XSPR(31,339,9), XSPR_MASK, COM, { RT } },
+{ "mftid", XSPR(31,339,17), XSPR_MASK, POWER, { RT } },
+{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, COM, { RT } },
+{ "mfdar", XSPR(31,339,19), XSPR_MASK, COM, { RT } },
+{ "mfdec", XSPR(31,339,22), XSPR_MASK, MFDEC2, { RT } },
+{ "mfsdr0", XSPR(31,339,24), XSPR_MASK, POWER, { RT } },
+{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, COM, { RT } },
+{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, COM, { RT } },
+{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, COM, { RT } },
+{ "mfcmpa", XSPR(31,339,144), XSPR_MASK, PPC860, { RT } },
+{ "mfcmpb", XSPR(31,339,145), XSPR_MASK, PPC860, { RT } },
+{ "mfcmpc", XSPR(31,339,146), XSPR_MASK, PPC860, { RT } },
+{ "mfcmpd", XSPR(31,339,147), XSPR_MASK, PPC860, { RT } },
+{ "mficr", XSPR(31,339,148), XSPR_MASK, PPC860, { RT } },
+{ "mfder", XSPR(31,339,149), XSPR_MASK, PPC860, { RT } },
+{ "mfcounta", XSPR(31,339,150), XSPR_MASK, PPC860, { RT } },
+{ "mfcountb", XSPR(31,339,151), XSPR_MASK, PPC860, { RT } },
+{ "mfcmpe", XSPR(31,339,152), XSPR_MASK, PPC860, { RT } },
+{ "mfcmpf", XSPR(31,339,153), XSPR_MASK, PPC860, { RT } },
+{ "mfcmpg", XSPR(31,339,154), XSPR_MASK, PPC860, { RT } },
+{ "mfcmph", XSPR(31,339,155), XSPR_MASK, PPC860, { RT } },
+{ "mflctrl1", XSPR(31,339,156), XSPR_MASK, PPC860, { RT } },
+{ "mflctrl2", XSPR(31,339,157), XSPR_MASK, PPC860, { RT } },
+{ "mfictrl", XSPR(31,339,158), XSPR_MASK, PPC860, { RT } },
+{ "mfbar", XSPR(31,339,159), XSPR_MASK, PPC860, { RT } },
+{ "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } },
+{ "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } },
+{ "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT } },
+{ "mfsprg2", XSPR(31,339,274), XSPR_MASK, PPC, { RT } },
+{ "mfsprg3", XSPR(31,339,275), XSPR_MASK, PPC, { RT } },
+{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT } },
+{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } },
+{ "mfpvr", XSPR(31,339,287), XSPR_MASK, PPC, { RT } },
+{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfic_cst", XSPR(31,339,560), XSPR_MASK, PPC860, { RT } },
+{ "mfic_adr", XSPR(31,339,561), XSPR_MASK, PPC860, { RT } },
+{ "mfic_dat", XSPR(31,339,562), XSPR_MASK, PPC860, { RT } },
+{ "mfdc_cst", XSPR(31,339,568), XSPR_MASK, PPC860, { RT } },
+{ "mfdc_adr", XSPR(31,339,569), XSPR_MASK, PPC860, { RT } },
+{ "mfdc_dat", XSPR(31,339,570), XSPR_MASK, PPC860, { RT } },
+{ "mfdpdr", XSPR(31,339,630), XSPR_MASK, PPC860, { RT } },
+{ "mfdpir", XSPR(31,339,631), XSPR_MASK, PPC860, { RT } },
+{ "mfimmr", XSPR(31,339,638), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_ctr", XSPR(31,339,784), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_ap", XSPR(31,339,786), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_epn", XSPR(31,339,787), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_twc", XSPR(31,339,789), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_rpn", XSPR(31,339,790), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_ctr", XSPR(31,339,792), XSPR_MASK, PPC860, { RT } },
+{ "mfm_casid",XSPR(31,339,793), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_ap", XSPR(31,339,794), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_epn", XSPR(31,339,795), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_twb", XSPR(31,339,796), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_twc", XSPR(31,339,797), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_rpn", XSPR(31,339,798), XSPR_MASK, PPC860, { RT } },
+{ "mfm_tw", XSPR(31,339,799), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_dbcam",XSPR(31,339,816), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_dbram0",XSPR(31,339,817), XSPR_MASK, PPC860, { RT } },
+{ "mfmi_dbram1",XSPR(31,339,818), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_dbcam", XSPR(31,339,824), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_dbram0",XSPR(31,339,825), XSPR_MASK, PPC860, { RT } },
+{ "mfmd_dbram1",XSPR(31,339,826), XSPR_MASK, PPC860, { RT } },
+{ "mfzpr", XSPR(31,339,944), XSPR_MASK, PPC403, { RT } },
+{ "mfpid", XSPR(31,339,945), XSPR_MASK, PPC403, { RT } },
+{ "mficdbdr",XSPR(31,339,979), XSPR_MASK, PPC403, { RT } },
+{ "mfummcr0", XSPR(31,339,936), XSPR_MASK, PPC750, { RT } },
+{ "mfupmc1", XSPR(31,339,937), XSPR_MASK, PPC750, { RT } },
+{ "mfupmc2", XSPR(31,339,938), XSPR_MASK, PPC750, { RT } },
+{ "mfusia", XSPR(31,339,939), XSPR_MASK, PPC750, { RT } },
+{ "mfummcr1", XSPR(31,339,940), XSPR_MASK, PPC750, { RT } },
+{ "mfupmc3", XSPR(31,339,941), XSPR_MASK, PPC750, { RT } },
+{ "mfupmc4", XSPR(31,339,942), XSPR_MASK, PPC750, { RT } },
+{ "mfmmcr0", XSPR(31,339,952), XSPR_MASK, PPC750, { RT } },
+{ "mfpmc1", XSPR(31,339,953), XSPR_MASK, PPC750, { RT } },
+{ "mfpmc2", XSPR(31,339,954), XSPR_MASK, PPC750, { RT } },
+{ "mfsia", XSPR(31,339,955), XSPR_MASK, PPC750, { RT } },
+{ "mfmmcr1", XSPR(31,339,956), XSPR_MASK, PPC750, { RT } },
+{ "mfpmc3", XSPR(31,339,957), XSPR_MASK, PPC750, { RT } },
+{ "mfpmc4", XSPR(31,339,958), XSPR_MASK, PPC750, { RT } },
+{ "mfesr", XSPR(31,339,980), XSPR_MASK, PPC403, { RT } },
+{ "mfdear", XSPR(31,339,981), XSPR_MASK, PPC403, { RT } },
+{ "mfevpr", XSPR(31,339,982), XSPR_MASK, PPC403, { RT } },
+{ "mfcdbcr", XSPR(31,339,983), XSPR_MASK, PPC403, { RT } },
+{ "mftsr", XSPR(31,339,984), XSPR_MASK, PPC403, { RT } },
+{ "mftcr", XSPR(31,339,986), XSPR_MASK, PPC403, { RT } },
+{ "mfpit", XSPR(31,339,987), XSPR_MASK, PPC403, { RT } },
+{ "mftbhi", XSPR(31,339,988), XSPR_MASK, PPC403, { RT } },
+{ "mftblo", XSPR(31,339,989), XSPR_MASK, PPC403, { RT } },
+{ "mfsrr2", XSPR(31,339,990), XSPR_MASK, PPC403, { RT } },
+{ "mfsrr3", XSPR(31,339,991), XSPR_MASK, PPC403, { RT } },
+{ "mfdbsr", XSPR(31,339,1008), XSPR_MASK, PPC403, { RT } },
+{ "mfiac1", XSPR(31,339,1012), XSPR_MASK, PPC403, { RT } },
+{ "mfiac2", XSPR(31,339,1013), XSPR_MASK, PPC403, { RT } },
+{ "mfdac1", XSPR(31,339,1014), XSPR_MASK, PPC403, { RT } },
+{ "mfdac2", XSPR(31,339,1015), XSPR_MASK, PPC403, { RT } },
+{ "mfdccr", XSPR(31,339,1018), XSPR_MASK, PPC403, { RT } },
+{ "mficcr", XSPR(31,339,1019), XSPR_MASK, PPC403, { RT } },
+{ "mfpbl1", XSPR(31,339,1020), XSPR_MASK, PPC403, { RT } },
+{ "mfpbu1", XSPR(31,339,1021), XSPR_MASK, PPC403, { RT } },
+{ "mfpbl2", XSPR(31,339,1022), XSPR_MASK, PPC403, { RT } },
+{ "mfpbu2", XSPR(31,339,1023), XSPR_MASK, PPC403, { RT } },
+{ "mfl2cr", XSPR(31,339,1017), XSPR_MASK, PPC750, { RT } },
+{ "mfictc", XSPR(31,339,1019), XSPR_MASK, PPC750, { RT } },
+{ "mfthrm1", XSPR(31,339,1020), XSPR_MASK, PPC750, { RT } },
+{ "mfthrm2", XSPR(31,339,1021), XSPR_MASK, PPC750, { RT } },
+{ "mfthrm3", XSPR(31,339,1022), XSPR_MASK, PPC750, { RT } },
+{ "mfspr", X(31,339), X_MASK, COM, { RT, SPR } },
+
+{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA, RB } },
+
+{ "lhax", X(31,343), X_MASK, COM, { RT, RA, RB } },
+
+{ "dccci", X(31,454), XRT_MASK, PPC, { RA, RB } },
+
+{ "abs", XO(31,360,0,0), XORB_MASK, M601, { RT, RA } },
+{ "abs.", XO(31,360,0,1), XORB_MASK, M601, { RT, RA } },
+{ "abso", XO(31,360,1,0), XORB_MASK, M601, { RT, RA } },
+{ "abso.", XO(31,360,1,1), XORB_MASK, M601, { RT, RA } },
+
+{ "divs", XO(31,363,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "divs.", XO(31,363,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "divso", XO(31,363,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "divso.", XO(31,363,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "tlbia", X(31,370), 0xffffffff, PPC, { 0 } },
+
+{ "mftbu", XSPR(31,371,269), XSPR_MASK, PPC, { RT } },
+{ "mftb", X(31,371), X_MASK, PPC, { RT, TBR } },
+
+{ "lwaux", X(31,373), X_MASK, PPC64, { RT, RAL, RB } },
+
+{ "lhaux", X(31,375), X_MASK, COM, { RT, RAL, RB } },
+
+{ "sthx", X(31,407), X_MASK, COM, { RS, RA, RB } },
+
+{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB } },
+
+{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB } },
+
+{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB } },
+
+{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB } },
+
+{ "orc", XRC(31,412,0), X_MASK, COM, { RA, RS, RB } },
+{ "orc.", XRC(31,412,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "sradi", XS(31,413,0), XS_MASK, PPC64, { RA, RS, SH6 } },
+{ "sradi.", XS(31,413,1), XS_MASK, PPC64, { RA, RS, SH6 } },
+
+{ "slbie", X(31,434), XRTRA_MASK, PPC64, { RB } },
+
+{ "ecowx", X(31,438), X_MASK, PPC, { RT, RA, RB } },
+
+{ "sthux", X(31,439), X_MASK, COM, { RS, RAS, RB } },
+
+{ "mr", XRC(31,444,0), X_MASK, COM, { RA, RS, RBS } },
+{ "or", XRC(31,444,0), X_MASK, COM, { RA, RS, RB } },
+{ "mr.", XRC(31,444,1), X_MASK, COM, { RA, RS, RBS } },
+{ "or.", XRC(31,444,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "mtexisr", XSPR(31,451,64), XSPR_MASK, PPC403, { RT } },
+{ "mtexier", XSPR(31,451,66), XSPR_MASK, PPC403, { RT } },
+{ "mtbr0", XSPR(31,451,128), XSPR_MASK, PPC403, { RT } },
+{ "mtbr1", XSPR(31,451,129), XSPR_MASK, PPC403, { RT } },
+{ "mtbr2", XSPR(31,451,130), XSPR_MASK, PPC403, { RT } },
+{ "mtbr3", XSPR(31,451,131), XSPR_MASK, PPC403, { RT } },
+{ "mtbr4", XSPR(31,451,132), XSPR_MASK, PPC403, { RT } },
+{ "mtbr5", XSPR(31,451,133), XSPR_MASK, PPC403, { RT } },
+{ "mtbr6", XSPR(31,451,134), XSPR_MASK, PPC403, { RT } },
+{ "mtbr7", XSPR(31,451,135), XSPR_MASK, PPC403, { RT } },
+{ "mtbear", XSPR(31,451,144), XSPR_MASK, PPC403, { RT } },
+{ "mtbesr", XSPR(31,451,145), XSPR_MASK, PPC403, { RT } },
+{ "mtiocr", XSPR(31,451,160), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacr0", XSPR(31,451,192), XSPR_MASK, PPC403, { RT } },
+{ "mtdmact0", XSPR(31,451,193), XSPR_MASK, PPC403, { RT } },
+{ "mtdmada0", XSPR(31,451,194), XSPR_MASK, PPC403, { RT } },
+{ "mtdmasa0", XSPR(31,451,195), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacc0", XSPR(31,451,196), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacr1", XSPR(31,451,200), XSPR_MASK, PPC403, { RT } },
+{ "mtdmact1", XSPR(31,451,201), XSPR_MASK, PPC403, { RT } },
+{ "mtdmada1", XSPR(31,451,202), XSPR_MASK, PPC403, { RT } },
+{ "mtdmasa1", XSPR(31,451,203), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacc1", XSPR(31,451,204), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacr2", XSPR(31,451,208), XSPR_MASK, PPC403, { RT } },
+{ "mtdmact2", XSPR(31,451,209), XSPR_MASK, PPC403, { RT } },
+{ "mtdmada2", XSPR(31,451,210), XSPR_MASK, PPC403, { RT } },
+{ "mtdmasa2", XSPR(31,451,211), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacc2", XSPR(31,451,212), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacr3", XSPR(31,451,216), XSPR_MASK, PPC403, { RT } },
+{ "mtdmact3", XSPR(31,451,217), XSPR_MASK, PPC403, { RT } },
+{ "mtdmada3", XSPR(31,451,218), XSPR_MASK, PPC403, { RT } },
+{ "mtdmasa3", XSPR(31,451,219), XSPR_MASK, PPC403, { RT } },
+{ "mtdmacc3", XSPR(31,451,220), XSPR_MASK, PPC403, { RT } },
+{ "mtdmasr", XSPR(31,451,224), XSPR_MASK, PPC403, { RT } },
+{ "mtummcr0", XSPR(31,451,936), XSPR_MASK, PPC750, { RT } },
+{ "mtupmc1", XSPR(31,451,937), XSPR_MASK, PPC750, { RT } },
+{ "mtupmc2", XSPR(31,451,938), XSPR_MASK, PPC750, { RT } },
+{ "mtusia", XSPR(31,451,939), XSPR_MASK, PPC750, { RT } },
+{ "mtummcr1", XSPR(31,451,940), XSPR_MASK, PPC750, { RT } },
+{ "mtupmc3", XSPR(31,451,941), XSPR_MASK, PPC750, { RT } },
+{ "mtupmc4", XSPR(31,451,942), XSPR_MASK, PPC750, { RT } },
+{ "mtmmcr0", XSPR(31,451,952), XSPR_MASK, PPC750, { RT } },
+{ "mtpmc1", XSPR(31,451,953), XSPR_MASK, PPC750, { RT } },
+{ "mtpmc2", XSPR(31,451,954), XSPR_MASK, PPC750, { RT } },
+{ "mtsia", XSPR(31,451,955), XSPR_MASK, PPC750, { RT } },
+{ "mtmmcr1", XSPR(31,451,956), XSPR_MASK, PPC750, { RT } },
+{ "mtpmc3", XSPR(31,451,957), XSPR_MASK, PPC750, { RT } },
+{ "mtpmc4", XSPR(31,451,958), XSPR_MASK, PPC750, { RT } },
+{ "mtl2cr", XSPR(31,451,1017), XSPR_MASK, PPC750, { RT } },
+{ "mtictc", XSPR(31,451,1019), XSPR_MASK, PPC750, { RT } },
+{ "mtthrm1", XSPR(31,451,1020), XSPR_MASK, PPC750, { RT } },
+{ "mtthrm2", XSPR(31,451,1021), XSPR_MASK, PPC750, { RT } },
+{ "mtthrm3", XSPR(31,451,1022), XSPR_MASK, PPC750, { RT } },
+{ "mtdcr", X(31,451), X_MASK, PPC, { SPR, RS } },
+
+{ "divdu", XO(31,457,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divdu.", XO(31,457,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divduo", XO(31,457,1,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divduo.", XO(31,457,1,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwu.", XO(31,459,0,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwuo", XO(31,459,1,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwuo.", XO(31,459,1,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "mtmq", XSPR(31,467,0), XSPR_MASK, M601, { RS } },
+{ "mtxer", XSPR(31,467,1), XSPR_MASK, COM, { RS } },
+{ "mtlr", XSPR(31,467,8), XSPR_MASK, COM, { RS } },
+{ "mtctr", XSPR(31,467,9), XSPR_MASK, COM, { RS } },
+{ "mttid", XSPR(31,467,17), XSPR_MASK, POWER, { RS } },
+{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, COM, { RS } },
+{ "mtdar", XSPR(31,467,19), XSPR_MASK, COM, { RS } },
+{ "mtrtcu", XSPR(31,467,20), XSPR_MASK, COM, { RS } },
+{ "mtrtcl", XSPR(31,467,21), XSPR_MASK, COM, { RS } },
+{ "mtdec", XSPR(31,467,22), XSPR_MASK, COM, { RS } },
+{ "mtsdr0", XSPR(31,467,24), XSPR_MASK, POWER, { RS } },
+{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, COM, { RS } },
+{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, COM, { RS } },
+{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, COM, { RS } },
+{ "mtcmpa", XSPR(31,467,144), XSPR_MASK, PPC860, { RT } },
+{ "mtcmpb", XSPR(31,467,145), XSPR_MASK, PPC860, { RT } },
+{ "mtcmpc", XSPR(31,467,146), XSPR_MASK, PPC860, { RT } },
+{ "mtcmpd", XSPR(31,467,147), XSPR_MASK, PPC860, { RT } },
+{ "mticr", XSPR(31,467,148), XSPR_MASK, PPC860, { RT } },
+{ "mtder", XSPR(31,467,149), XSPR_MASK, PPC860, { RT } },
+{ "mtcounta", XSPR(31,467,150), XSPR_MASK, PPC860, { RT } },
+{ "mtcountb", XSPR(31,467,151), XSPR_MASK, PPC860, { RT } },
+{ "mtcmpe", XSPR(31,467,152), XSPR_MASK, PPC860, { RT } },
+{ "mtcmpf", XSPR(31,467,153), XSPR_MASK, PPC860, { RT } },
+{ "mtcmpg", XSPR(31,467,154), XSPR_MASK, PPC860, { RT } },
+{ "mtcmph", XSPR(31,467,155), XSPR_MASK, PPC860, { RT } },
+{ "mtlctrl1", XSPR(31,467,156), XSPR_MASK, PPC860, { RT } },
+{ "mtlctrl2", XSPR(31,467,157), XSPR_MASK, PPC860, { RT } },
+{ "mtictrl", XSPR(31,467,158), XSPR_MASK, PPC860, { RT } },
+{ "mtbar", XSPR(31,467,159), XSPR_MASK, PPC860, { RT } },
+{ "mtsprg", XSPR(31,467,272), XSPRG_MASK, PPC, { SPRG, RS } },
+{ "mtsprg0", XSPR(31,467,272), XSPR_MASK, PPC, { RT } },
+{ "mtsprg1", XSPR(31,467,273), XSPR_MASK, PPC, { RT } },
+{ "mtsprg2", XSPR(31,467,274), XSPR_MASK, PPC, { RT } },
+{ "mtsprg3", XSPR(31,467,275), XSPR_MASK, PPC, { RT } },
+{ "mtasr", XSPR(31,467,280), XSPR_MASK, PPC64, { RS } },
+{ "mtear", XSPR(31,467,282), XSPR_MASK, PPC, { RS } },
+{ "mttbl", XSPR(31,467,284), XSPR_MASK, PPC, { RS } },
+{ "mttbu", XSPR(31,467,285), XSPR_MASK, PPC, { RS } },
+{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtzpr", XSPR(31,467,944), XSPR_MASK, PPC403, { RT } },
+{ "mtpid", XSPR(31,467,945), XSPR_MASK, PPC403, { RT } },
+{ "mticdbdr",XSPR(31,467,979), XSPR_MASK, PPC403, { RT } },
+{ "mtesr", XSPR(31,467,980), XSPR_MASK, PPC403, { RT } },
+{ "mtevpr", XSPR(31,467,982), XSPR_MASK, PPC403, { RT } },
+{ "mtcdbcr", XSPR(31,467,983), XSPR_MASK, PPC403, { RT } },
+{ "mttsr", XSPR(31,467,984), XSPR_MASK, PPC403, { RT } },
+{ "mttcr", XSPR(31,467,986), XSPR_MASK, PPC403, { RT } },
+{ "mtpit", XSPR(31,467,987), XSPR_MASK, PPC403, { RT } },
+{ "mttbhi", XSPR(31,467,988), XSPR_MASK, PPC403, { RT } },
+{ "mttblo", XSPR(31,467,989), XSPR_MASK, PPC403, { RT } },
+{ "mtsrr2", XSPR(31,467,990), XSPR_MASK, PPC403, { RT } },
+{ "mtsrr3", XSPR(31,467,991), XSPR_MASK, PPC403, { RT } },
+{ "mtdbsr", XSPR(31,467,1008), XSPR_MASK, PPC403, { RT } },
+{ "mtiac1", XSPR(31,467,1012), XSPR_MASK, PPC403, { RT } },
+{ "mtiac2", XSPR(31,467,1013), XSPR_MASK, PPC403, { RT } },
+{ "mtdac1", XSPR(31,467,1014), XSPR_MASK, PPC403, { RT } },
+{ "mtdac2", XSPR(31,467,1015), XSPR_MASK, PPC403, { RT } },
+{ "mtdccr", XSPR(31,467,1018), XSPR_MASK, PPC403, { RT } },
+{ "mticcr", XSPR(31,467,1019), XSPR_MASK, PPC403, { RT } },
+{ "mtpbl1", XSPR(31,467,1020), XSPR_MASK, PPC403, { RT } },
+{ "mtpbu1", XSPR(31,467,1021), XSPR_MASK, PPC403, { RT } },
+{ "mtpbl2", XSPR(31,467,1022), XSPR_MASK, PPC403, { RT } },
+{ "mtpbu2", XSPR(31,467,1023), XSPR_MASK, PPC403, { RT } },
+{ "mtspr", X(31,467), X_MASK, COM, { SPR, RS } },
+
+{ "dcbi", X(31,470), XRT_MASK, PPC, { RA, RB } },
+
+{ "nand", XRC(31,476,0), X_MASK, COM, { RA, RS, RB } },
+{ "nand.", XRC(31,476,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "dcread", X(31,486), XRT_MASK, PPC403, { RA, RB } },
+
+{ "nabs", XO(31,488,0,0), XORB_MASK, M601, { RT, RA } },
+{ "nabs.", XO(31,488,0,1), XORB_MASK, M601, { RT, RA } },
+{ "nabso", XO(31,488,1,0), XORB_MASK, M601, { RT, RA } },
+{ "nabso.", XO(31,488,1,1), XORB_MASK, M601, { RT, RA } },
+
+{ "divd", XO(31,489,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divd.", XO(31,489,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divdo", XO(31,489,1,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divdo.", XO(31,489,1,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divw.", XO(31,491,0,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwo", XO(31,491,1,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwo.", XO(31,491,1,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "slbia", X(31,498), 0xffffffff, PPC64, { 0 } },
+
+{ "cli", X(31,502), XRB_MASK, POWER, { RT, RA } },
+
+{ "mcrxr", X(31,512), XRARB_MASK|(3<<21), COM, { BF } },
+
+{ "clcs", X(31,531), XRB_MASK, M601, { RT, RA } },
+
+{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA, RB } },
+{ "lsx", X(31,533), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA, RB } },
+{ "lbrx", X(31,534), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA, RB } },
+
+{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sr", XRC(31,536,0), X_MASK, PWRCOM, { RA, RS, RB } },
+{ "srw.", XRC(31,536,1), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sr.", XRC(31,536,1), X_MASK, PWRCOM, { RA, RS, RB } },
+
+{ "rrib", XRC(31,537,0), X_MASK, M601, { RA, RS, RB } },
+{ "rrib.", XRC(31,537,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "srd", XRC(31,539,0), X_MASK, PPC64, { RA, RS, RB } },
+{ "srd.", XRC(31,539,1), X_MASK, PPC64, { RA, RS, RB } },
+
+{ "maskir", XRC(31,541,0), X_MASK, M601, { RA, RS, RB } },
+{ "maskir.", XRC(31,541,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } },
+
+{ "lfsux", X(31,567), X_MASK, COM, { FRT, RAS, RB } },
+
+{ "mfsr", X(31,595), XRB_MASK|(1<<20), COM32, { RT, SR } },
+
+{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA, NB } },
+{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA, NB } },
+
+{ "sync", X(31,598), 0xffffffff, PPCCOM, { 0 } },
+{ "dcs", X(31,598), 0xffffffff, PWRCOM, { 0 } },
+
+{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA, RB } },
+
+{ "mfsri", X(31,627), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "dclst", X(31,630), XRB_MASK, PWRCOM, { RS, RA } },
+
+{ "lfdux", X(31,631), X_MASK, COM, { FRT, RAS, RB } },
+
+{ "mfsrin", X(31,659), XRA_MASK, PPC32, { RT, RB } },
+
+{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA, RB } },
+{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA, RB } },
+
+{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA, RB } },
+{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA, RB } },
+
+{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA, RB } },
+
+{ "srq", XRC(31,664,0), X_MASK, M601, { RA, RS, RB } },
+{ "srq.", XRC(31,664,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sre", XRC(31,665,0), X_MASK, M601, { RA, RS, RB } },
+{ "sre.", XRC(31,665,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "stfsux", X(31,695), X_MASK, COM, { FRS, RAS, RB } },
+
+{ "sriq", XRC(31,696,0), X_MASK, M601, { RA, RS, SH } },
+{ "sriq.", XRC(31,696,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA, NB } },
+{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA, NB } },
+
+{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA, RB } },
+
+{ "srlq", XRC(31,728,0), X_MASK, M601, { RA, RS, RB } },
+{ "srlq.", XRC(31,728,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sreq", XRC(31,729,0), X_MASK, M601, { RA, RS, RB } },
+{ "sreq.", XRC(31,729,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "stfdux", X(31,759), X_MASK, COM, { FRS, RAS, RB } },
+
+{ "srliq", XRC(31,760,0), X_MASK, M601, { RA, RS, SH } },
+{ "srliq.", XRC(31,760,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA, RB } },
+
+{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sra", XRC(31,792,0), X_MASK, PWRCOM, { RA, RS, RB } },
+{ "sraw.", XRC(31,792,1), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sra.", XRC(31,792,1), X_MASK, PWRCOM, { RA, RS, RB } },
+
+{ "srad", XRC(31,794,0), X_MASK, PPC64, { RA, RS, RB } },
+{ "srad.", XRC(31,794,1), X_MASK, PPC64, { RA, RS, RB } },
+
+{ "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "srawi", XRC(31,824,0), X_MASK, PPCCOM, { RA, RS, SH } },
+{ "srai", XRC(31,824,0), X_MASK, PWRCOM, { RA, RS, SH } },
+{ "srawi.", XRC(31,824,1), X_MASK, PPCCOM, { RA, RS, SH } },
+{ "srai.", XRC(31,824,1), X_MASK, PWRCOM, { RA, RS, SH } },
+
+{ "eieio", X(31,854), 0xffffffff, PPC, { 0 } },
+
+{ "tlbsx", XRC(31,914,0), X_MASK, PPC403, { RT, RA, RB } },
+{ "tlbsx.", XRC(31,914,1), X_MASK, PPC403, { RT, RA, RB } },
+
+{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA, RB } },
+
+{ "sraq", XRC(31,920,0), X_MASK, M601, { RA, RS, RB } },
+{ "sraq.", XRC(31,920,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "srea", XRC(31,921,0), X_MASK, M601, { RA, RS, RB } },
+{ "srea.", XRC(31,921,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "extsh", XRC(31,922,0), XRB_MASK, PPCCOM, { RA, RS } },
+{ "exts", XRC(31,922,0), XRB_MASK, PWRCOM, { RA, RS } },
+{ "extsh.", XRC(31,922,1), XRB_MASK, PPCCOM, { RA, RS } },
+{ "exts.", XRC(31,922,1), XRB_MASK, PWRCOM, { RA, RS } },
+
+{ "tlbre", X(31,946), X_MASK, PPC403, { RT, RA, SH } },
+
+{ "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH } },
+{ "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS} },
+{ "extsb.", XRC(31,954,1), XRB_MASK, PPC, { RA, RS} },
+
+{ "iccci", X(31,966), XRT_MASK, PPC, { RA, RB } },
+
+{ "tlbld", X(31,978), XRTRA_MASK, PPC, { RB } },
+{ "tlbwe", X(31,978), X_MASK, PPC403, { RS, RA, SH } },
+
+{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } },
+
+{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA, RB } },
+
+{ "extsw", XRC(31,986,0), XRB_MASK, PPC, { RA, RS } },
+{ "extsw.", XRC(31,986,1), XRB_MASK, PPC, { RA, RS } },
+
+{ "icread", X(31,998), XRT_MASK, PPC403, { RA, RB } },
+
+{ "tlbli", X(31,1010), XRTRA_MASK, PPC, { RB } },
+
+{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
+{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
+
+{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA } },
+{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA } },
+
+{ "lwzu", OP(33), OP_MASK, PPCCOM, { RT, D, RAL } },
+{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA } },
+
+{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA } },
+
+{ "lbzu", OP(35), OP_MASK, COM, { RT, D, RAL } },
+
+{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA } },
+{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA } },
+
+{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } },
+{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA } },
+
+{ "stb", OP(38), OP_MASK, COM, { RS, D, RA } },
+
+{ "stbu", OP(39), OP_MASK, COM, { RS, D, RAS } },
+
+{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA } },
+
+{ "lhzu", OP(41), OP_MASK, COM, { RT, D, RAL } },
+
+{ "lha", OP(42), OP_MASK, COM, { RT, D, RA } },
+
+{ "lhau", OP(43), OP_MASK, COM, { RT, D, RAL } },
+
+{ "sth", OP(44), OP_MASK, COM, { RS, D, RA } },
+
+{ "sthu", OP(45), OP_MASK, COM, { RS, D, RAS } },
+
+{ "lmw", OP(46), OP_MASK, PPCCOM, { RT, D, RAM } },
+{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA } },
+
+{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA } },
+{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA } },
+
+{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA } },
+
+{ "lfsu", OP(49), OP_MASK, COM, { FRT, D, RAS } },
+
+{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA } },
+
+{ "lfdu", OP(51), OP_MASK, COM, { FRT, D, RAS } },
+
+{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA } },
+
+{ "stfsu", OP(53), OP_MASK, COM, { FRS, D, RAS } },
+
+{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA } },
+
+{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } },
+
+{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } },
+
+{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } },
+
+{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA } },
+
+{ "ldu", DSO(58,1), DS_MASK, PPC64, { RT, DS, RAL } },
+
+{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA } },
+
+{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+
+{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+{ "fsubs.", A(59,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+
+{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+{ "fadds.", A(59,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+
+{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fres", A(59,24,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "fres.", A(59,24,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
+{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
+
+{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fmadds", A(59,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fmadds.", A(59,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fnmsubs", A(59,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fnmsubs.",A(59,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } },
+
+{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } },
+
+{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA } },
+
+{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } },
+
+{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
+
+{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } },
+{ "frsp.", XRC(63,12,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "fctiw", XRC(63,14,0), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcir", XRC(63,14,0), XRA_MASK, POWER2, { FRT, FRB } },
+{ "fctiw.", XRC(63,14,1), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcir.", XRC(63,14,1), XRA_MASK, POWER2, { FRT, FRB } },
+
+{ "fctiwz", XRC(63,15,0), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcirz", XRC(63,15,0), XRA_MASK, POWER2, { FRT, FRB } },
+{ "fctiwz.", XRC(63,15,1), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcirz.", XRC(63,15,1), XRA_MASK, POWER2, { FRT, FRB } },
+
+{ "fdiv", A(63,18,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fd", A(63,18,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+{ "fdiv.", A(63,18,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fd.", A(63,18,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+
+{ "fsub", A(63,20,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fs", A(63,20,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+{ "fsub.", A(63,20,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fs.", A(63,20,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+
+{ "fadd", A(63,21,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fa", A(63,21,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+{ "fadd.", A(63,21,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fa.", A(63,21,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+
+{ "fsqrt", A(63,22,0), AFRAFRC_MASK, PPCPWR2, { FRT, FRB } },
+{ "fsqrt.", A(63,22,1), AFRAFRC_MASK, PPCPWR2, { FRT, FRB } },
+
+{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fmul", A(63,25,0), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } },
+{ "fm", A(63,25,0), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } },
+{ "fmul.", A(63,25,1), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } },
+{ "fm.", A(63,25,1), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } },
+
+{ "frsqrte", A(63,26,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "frsqrte.",A(63,26,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fmsub", A(63,28,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fms", A(63,28,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fmsub.", A(63,28,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fms.", A(63,28,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fmadd", A(63,29,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fma", A(63,29,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fmadd.", A(63,29,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fma.", A(63,29,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fnmsub", A(63,30,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnms", A(63,30,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fnmsub.", A(63,30,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnms.", A(63,30,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fnmadd", A(63,31,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnma", A(63,31,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fnmadd.", A(63,31,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnma.", A(63,31,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fcmpo", X(63,32), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
+
+{ "mtfsb1", XRC(63,38,0), XRARB_MASK, COM, { BT } },
+{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, COM, { BT } },
+
+{ "fneg", XRC(63,40,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fneg.", XRC(63,40,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } },
+
+{ "mtfsb0", XRC(63,70,0), XRARB_MASK, COM, { BT } },
+{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, COM, { BT } },
+
+{ "fmr", XRC(63,72,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fmr.", XRC(63,72,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+
+{ "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "fabs", XRC(63,264,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fabs.", XRC(63,264,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } },
+{ "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } },
+
+{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB } },
+{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB } },
+
+{ "fctid", XRC(63,814,0), XRA_MASK, PPC64, { FRT, FRB } },
+{ "fctid.", XRC(63,814,1), XRA_MASK, PPC64, { FRT, FRB } },
+
+{ "fctidz", XRC(63,815,0), XRA_MASK, PPC64, { FRT, FRB } },
+{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC64, { FRT, FRB } },
+
+{ "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB } },
+{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB } },
+
+};
+
+const int powerpc_num_opcodes =
+ sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+
+/* The macro table. This is only used by the assembler. */
+
+/* The expressions of the form (-x ! 31) & (x | 31) have the value 0
+ when x=0; 32-x when x is between 1 and 31; are negative if x is
+ negative; and are 32 or more otherwise. This is what you want
+ when, for instance, you are emulating a right shift by a
+ rotate-left-and-mask, because the underlying instructions support
+ shifts of size 0 but not shifts of size 32. By comparison, when
+ extracting x bits from some word you want to use just 32-x, because
+ the underlying instructions don't support extracting 0 bits but do
+ support extracting the whole word (32 bits in this case). */
+
+const struct powerpc_macro powerpc_macros[] = {
+{ "extldi", 4, PPC64, "rldicr %0,%1,%3,(%2)-1" },
+{ "extldi.", 4, PPC64, "rldicr. %0,%1,%3,(%2)-1" },
+{ "extrdi", 4, PPC64, "rldicl %0,%1,(%2)+(%3),64-(%2)" },
+{ "extrdi.", 4, PPC64, "rldicl. %0,%1,(%2)+(%3),64-(%2)" },
+{ "insrdi", 4, PPC64, "rldimi %0,%1,64-((%2)+(%3)),%3" },
+{ "insrdi.", 4, PPC64, "rldimi. %0,%1,64-((%2)+(%3)),%3" },
+{ "rotrdi", 3, PPC64, "rldicl %0,%1,(-(%2)!63)&((%2)|63),0" },
+{ "rotrdi.", 3, PPC64, "rldicl. %0,%1,(-(%2)!63)&((%2)|63),0" },
+{ "sldi", 3, PPC64, "rldicr %0,%1,%2,63-(%2)" },
+{ "sldi.", 3, PPC64, "rldicr. %0,%1,%2,63-(%2)" },
+{ "srdi", 3, PPC64, "rldicl %0,%1,(-(%2)!63)&((%2)|63),%2" },
+{ "srdi.", 3, PPC64, "rldicl. %0,%1,(-(%2)!63)&((%2)|63),%2" },
+{ "clrrdi", 3, PPC64, "rldicr %0,%1,0,63-(%2)" },
+{ "clrrdi.", 3, PPC64, "rldicr. %0,%1,0,63-(%2)" },
+{ "clrlsldi",4, PPC64, "rldic %0,%1,%3,(%2)-(%3)" },
+{ "clrlsldi.",4, PPC64, "rldic. %0,%1,%3,(%2)-(%3)" },
+
+{ "extlwi", 4, PPCCOM, "rlwinm %0,%1,%3,0,(%2)-1" },
+{ "extlwi.", 4, PPCCOM, "rlwinm. %0,%1,%3,0,(%2)-1" },
+{ "extrwi", 4, PPCCOM, "rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
+{ "extrwi.", 4, PPCCOM, "rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
+{ "inslwi", 4, PPCCOM, "rlwimi %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1" },
+{ "inslwi.", 4, PPCCOM, "rlwimi. %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1"},
+{ "insrwi", 4, PPCCOM, "rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
+{ "insrwi.", 4, PPCCOM, "rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
+{ "rotrwi", 3, PPCCOM, "rlwinm %0,%1,(-(%2)!31)&((%2)|31),0,31" },
+{ "rotrwi.", 3, PPCCOM, "rlwinm. %0,%1,(-(%2)!31)&((%2)|31),0,31" },
+{ "slwi", 3, PPCCOM, "rlwinm %0,%1,%2,0,31-(%2)" },
+{ "sli", 3, PWRCOM, "rlinm %0,%1,%2,0,31-(%2)" },
+{ "slwi.", 3, PPCCOM, "rlwinm. %0,%1,%2,0,31-(%2)" },
+{ "sli.", 3, PWRCOM, "rlinm. %0,%1,%2,0,31-(%2)" },
+{ "srwi", 3, PPCCOM, "rlwinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+{ "sri", 3, PWRCOM, "rlinm %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+{ "srwi.", 3, PPCCOM, "rlwinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+{ "sri.", 3, PWRCOM, "rlinm. %0,%1,(-(%2)!31)&((%2)|31),%2,31" },
+{ "clrrwi", 3, PPCCOM, "rlwinm %0,%1,0,0,31-(%2)" },
+{ "clrrwi.", 3, PPCCOM, "rlwinm. %0,%1,0,0,31-(%2)" },
+{ "clrlslwi",4, PPCCOM, "rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
+{ "clrlslwi.",4, PPCCOM, "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
+
+};
+
+const int powerpc_num_macros =
+ sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
diff --git a/opcodes/sh-dis.c b/opcodes/sh-dis.c
new file mode 100644
index 00000000000..2ebfdb6d368
--- /dev/null
+++ b/opcodes/sh-dis.c
@@ -0,0 +1,387 @@
+/* Disassemble SH instructions.
+ Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#define STATIC_TABLE
+#define DEFINE_TABLE
+
+#include "sh-opc.h"
+#include "dis-asm.h"
+
+#define LITTLE_BIT 2
+
+static int
+print_insn_shx (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ fprintf_ftype fprintf_fn = info->fprintf_func;
+ void *stream = info->stream;
+ unsigned char insn[2];
+ unsigned char nibs[4];
+ int status;
+ bfd_vma relmask = ~ (bfd_vma) 0;
+ sh_opcode_info *op;
+
+ status = info->read_memory_func (memaddr, insn, 2, info);
+
+ if (status != 0)
+ {
+ info->memory_error_func (status, memaddr, info);
+ return -1;
+ }
+
+ if (info->flags & LITTLE_BIT)
+ {
+ nibs[0] = (insn[1] >> 4) & 0xf;
+ nibs[1] = insn[1] & 0xf;
+
+ nibs[2] = (insn[0] >> 4) & 0xf;
+ nibs[3] = insn[0] & 0xf;
+ }
+ else
+ {
+ nibs[0] = (insn[0] >> 4) & 0xf;
+ nibs[1] = insn[0] & 0xf;
+
+ nibs[2] = (insn[1] >> 4) & 0xf;
+ nibs[3] = insn[1] & 0xf;
+ }
+
+ for (op = sh_table; op->name; op++)
+ {
+ int n;
+ int imm = 0;
+ int rn = 0;
+ int rm = 0;
+ int rb = 0;
+ int disp_pc;
+ bfd_vma disp_pc_addr = 0;
+
+ for (n = 0; n < 4; n++)
+ {
+ int i = op->nibbles[n];
+
+ if (i < 16)
+ {
+ if (nibs[n] == i)
+ continue;
+ goto fail;
+ }
+ switch (i)
+ {
+ case BRANCH_8:
+ imm = (nibs[2] << 4) | (nibs[3]);
+ if (imm & 0x80)
+ imm |= ~0xff;
+ imm = ((char)imm) * 2 + 4 ;
+ goto ok;
+ case BRANCH_12:
+ imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
+ if (imm & 0x800)
+ imm |= ~0xfff;
+ imm = imm * 2 + 4;
+ goto ok;
+ case IMM_4:
+ imm = nibs[3];
+ goto ok;
+ case IMM_4BY2:
+ imm = nibs[3] <<1;
+ goto ok;
+ case IMM_4BY4:
+ imm = nibs[3] <<2;
+ goto ok;
+ case IMM_8:
+ imm = (nibs[2] << 4) | nibs[3];
+ goto ok;
+ case PCRELIMM_8BY2:
+ imm = ((nibs[2] << 4) | nibs[3]) <<1;
+ relmask = ~ (bfd_vma) 1;
+ goto ok;
+ case PCRELIMM_8BY4:
+ imm = ((nibs[2] << 4) | nibs[3]) <<2;
+ relmask = ~ (bfd_vma) 3;
+ goto ok;
+ case IMM_8BY2:
+ imm = ((nibs[2] << 4) | nibs[3]) <<1;
+ goto ok;
+ case IMM_8BY4:
+ imm = ((nibs[2] << 4) | nibs[3]) <<2;
+ goto ok;
+ case DISP_8:
+ imm = (nibs[2] << 4) | (nibs[3]);
+ goto ok;
+ case DISP_4:
+ imm = nibs[3];
+ goto ok;
+ case REG_N:
+ rn = nibs[n];
+ break;
+ case REG_M:
+ rm = nibs[n];
+ break;
+ case REG_NM:
+ rn = (nibs[n] & 0xc) >> 2;
+ rm = (nibs[n] & 0x3);
+ break;
+ case REG_B:
+ rb = nibs[n] & 0x07;
+ break;
+ default:
+ abort();
+ }
+ }
+
+ ok:
+ fprintf_fn (stream,"%s\t", op->name);
+ disp_pc = 0;
+ for (n = 0; n < 3 && op->arg[n] != A_END; n++)
+ {
+ if (n && op->arg[1] != A_END)
+ fprintf_fn (stream, ",");
+ switch (op->arg[n])
+ {
+ case A_IMM:
+ fprintf_fn (stream, "#%d", (char)(imm));
+ break;
+ case A_R0:
+ fprintf_fn (stream, "r0");
+ break;
+ case A_REG_N:
+ fprintf_fn (stream, "r%d", rn);
+ break;
+ case A_INC_N:
+ fprintf_fn (stream, "@r%d+", rn);
+ break;
+ case A_DEC_N:
+ fprintf_fn (stream, "@-r%d", rn);
+ break;
+ case A_IND_N:
+ fprintf_fn (stream, "@r%d", rn);
+ break;
+ case A_DISP_REG_N:
+ fprintf_fn (stream, "@(%d,r%d)", imm, rn);
+ break;
+ case A_REG_M:
+ fprintf_fn (stream, "r%d", rm);
+ break;
+ case A_INC_M:
+ fprintf_fn (stream, "@r%d+", rm);
+ break;
+ case A_DEC_M:
+ fprintf_fn (stream, "@-r%d", rm);
+ break;
+ case A_IND_M:
+ fprintf_fn (stream, "@r%d", rm);
+ break;
+ case A_DISP_REG_M:
+ fprintf_fn (stream, "@(%d,r%d)", imm, rm);
+ break;
+ case A_REG_B:
+ fprintf_fn (stream, "r%d_bank", rb);
+ break;
+ case A_DISP_PC:
+ disp_pc = 1;
+ disp_pc_addr = imm + 4 + (memaddr & relmask);
+ (*info->print_address_func) (disp_pc_addr, info);
+ break;
+ case A_IND_R0_REG_N:
+ fprintf_fn (stream, "@(r0,r%d)", rn);
+ break;
+ case A_IND_R0_REG_M:
+ fprintf_fn (stream, "@(r0,r%d)", rm);
+ break;
+ case A_DISP_GBR:
+ fprintf_fn (stream, "@(%d,gbr)",imm);
+ break;
+ case A_R0_GBR:
+ fprintf_fn (stream, "@(r0,gbr)");
+ break;
+ case A_BDISP12:
+ case A_BDISP8:
+ (*info->print_address_func) (imm + memaddr, info);
+ break;
+ case A_SR:
+ fprintf_fn (stream, "sr");
+ break;
+ case A_GBR:
+ fprintf_fn (stream, "gbr");
+ break;
+ case A_VBR:
+ fprintf_fn (stream, "vbr");
+ break;
+ case A_SSR:
+ fprintf_fn (stream, "ssr");
+ break;
+ case A_SPC:
+ fprintf_fn (stream, "spc");
+ break;
+ case A_MACH:
+ fprintf_fn (stream, "mach");
+ break;
+ case A_MACL:
+ fprintf_fn (stream ,"macl");
+ break;
+ case A_PR:
+ fprintf_fn (stream, "pr");
+ break;
+ case A_SGR:
+ fprintf_fn (stream, "sgr");
+ break;
+ case A_DBR:
+ fprintf_fn (stream, "dbr");
+ break;
+ case FD_REG_N:
+ if (0)
+ goto d_reg_n;
+ case F_REG_N:
+ fprintf_fn (stream, "fr%d", rn);
+ break;
+ case F_REG_M:
+ fprintf_fn (stream, "fr%d", rm);
+ break;
+ case DX_REG_N:
+ if (rn & 1)
+ {
+ fprintf_fn (stream, "xd%d", rn & ~1);
+ break;
+ }
+ d_reg_n:
+ case D_REG_N:
+ fprintf_fn (stream, "dr%d", rn);
+ break;
+ case DX_REG_M:
+ if (rm & 1)
+ {
+ fprintf_fn (stream, "xd%d", rm & ~1);
+ break;
+ }
+ case D_REG_M:
+ fprintf_fn (stream, "dr%d", rm);
+ break;
+ case FPSCR_M:
+ case FPSCR_N:
+ fprintf_fn (stream, "fpscr");
+ break;
+ case FPUL_M:
+ case FPUL_N:
+ fprintf_fn (stream, "fpul");
+ break;
+ case F_FR0:
+ fprintf_fn (stream, "fr0");
+ break;
+ case V_REG_N:
+ fprintf_fn (stream, "fv%d", rn*4);
+ break;
+ case V_REG_M:
+ fprintf_fn (stream, "fv%d", rm*4);
+ break;
+ case XMTRX_M4:
+ fprintf_fn (stream, "xmtrx");
+ break;
+ default:
+ abort();
+ }
+ }
+
+#if 0
+ /* This code prints instructions in delay slots on the same line
+ as the instruction which needs the delay slots. This can be
+ confusing, since other disassembler don't work this way, and
+ it means that the instructions are not all in a line. So I
+ disabled it. Ian. */
+ if (!(info->flags & 1)
+ && (op->name[0] == 'j'
+ || (op->name[0] == 'b'
+ && (op->name[1] == 'r'
+ || op->name[1] == 's'))
+ || (op->name[0] == 'r' && op->name[1] == 't')
+ || (op->name[0] == 'b' && op->name[2] == '.')))
+ {
+ info->flags |= 1;
+ fprintf_fn (stream, "\t(slot ");
+ print_insn_shx (memaddr + 2, info);
+ info->flags &= ~1;
+ fprintf_fn (stream, ")");
+ return 4;
+ }
+#endif
+
+ if (disp_pc && strcmp (op->name, "mova") != 0)
+ {
+ int size;
+ bfd_byte bytes[4];
+
+ if (relmask == ~ (bfd_vma) 1)
+ size = 2;
+ else
+ size = 4;
+ status = info->read_memory_func (disp_pc_addr, bytes, size, info);
+ if (status == 0)
+ {
+ unsigned int val;
+
+ if (size == 2)
+ {
+ if ((info->flags & LITTLE_BIT) != 0)
+ val = bfd_getl16 (bytes);
+ else
+ val = bfd_getb16 (bytes);
+ }
+ else
+ {
+ if ((info->flags & LITTLE_BIT) != 0)
+ val = bfd_getl32 (bytes);
+ else
+ val = bfd_getb32 (bytes);
+ }
+ fprintf_fn (stream, "\t! 0x%x", val);
+ }
+ }
+
+ return 2;
+ fail:
+ ;
+
+ }
+ fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
+ return 2;
+}
+
+int
+print_insn_shl (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int r;
+
+ info->flags = LITTLE_BIT;
+ r = print_insn_shx (memaddr, info);
+ return r;
+}
+
+int
+print_insn_sh (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ int r;
+
+ info->flags = 0;
+ r = print_insn_shx (memaddr, info);
+ return r;
+}
diff --git a/opcodes/sh-opc.h b/opcodes/sh-opc.h
new file mode 100644
index 00000000000..dc1aae5cbb1
--- /dev/null
+++ b/opcodes/sh-opc.h
@@ -0,0 +1,573 @@
+/* Definitions for SH opcodes.
+ Copyright (C) 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+typedef enum {
+ HEX_0,
+ HEX_1,
+ HEX_2,
+ HEX_3,
+ HEX_4,
+ HEX_5,
+ HEX_6,
+ HEX_7,
+ HEX_8,
+ HEX_9,
+ HEX_A,
+ HEX_B,
+ HEX_C,
+ HEX_D,
+ HEX_E,
+ HEX_F,
+ REG_N,
+ REG_M,
+ REG_NM,
+ REG_B,
+ BRANCH_12,
+ BRANCH_8,
+ DISP_8,
+ DISP_4,
+ IMM_4,
+ IMM_4BY2,
+ IMM_4BY4,
+ PCRELIMM_8BY2,
+ PCRELIMM_8BY4,
+ IMM_8,
+ IMM_8BY2,
+ IMM_8BY4
+} sh_nibble_type;
+
+typedef enum {
+ A_END,
+ A_BDISP12,
+ A_BDISP8,
+ A_DEC_M,
+ A_DEC_N,
+ A_DISP_GBR,
+ A_DISP_PC,
+ A_DISP_REG_M,
+ A_DISP_REG_N,
+ A_GBR,
+ A_IMM,
+ A_INC_M,
+ A_INC_N,
+ A_IND_M,
+ A_IND_N,
+ A_IND_R0_REG_M,
+ A_IND_R0_REG_N,
+ A_MACH,
+ A_MACL,
+ A_PR,
+ A_R0,
+ A_R0_GBR,
+ A_REG_M,
+ A_REG_N,
+ A_REG_B,
+ A_SR,
+ A_VBR,
+ A_SSR,
+ A_SPC,
+ A_SGR,
+ A_DBR,
+ F_REG_N,
+ F_REG_M,
+ D_REG_N,
+ D_REG_M,
+ X_REG_N, /* Only used for argument parsing */
+ X_REG_M, /* Only used for argument parsing */
+ DX_REG_N,
+ DX_REG_M,
+ V_REG_N,
+ V_REG_M,
+ FD_REG_N,
+ XMTRX_M4,
+ F_FR0,
+ FPUL_N,
+ FPUL_M,
+ FPSCR_N,
+ FPSCR_M
+} sh_arg_type;
+
+typedef struct {
+ char *name;
+ sh_arg_type arg[4];
+ sh_nibble_type nibbles[4];
+} sh_opcode_info;
+
+#ifdef DEFINE_TABLE
+
+sh_opcode_info sh_table[] = {
+
+/* 0111nnnni8*1.... add #<imm>,<REG_N> */{"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}},
+
+/* 0011nnnnmmmm1100 add <REG_M>,<REG_N> */{"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}},
+
+/* 0011nnnnmmmm1110 addc <REG_M>,<REG_N>*/{"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}},
+
+/* 0011nnnnmmmm1111 addv <REG_M>,<REG_N>*/{"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}},
+
+/* 11001001i8*1.... and #<imm>,R0 */{"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}},
+
+/* 0010nnnnmmmm1001 and <REG_M>,<REG_N> */{"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}},
+
+/* 11001101i8*1.... and.b #<imm>,@(R0,GBR)*/{"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}},
+
+/* 1010i12......... bra <bdisp12> */{"bra",{A_BDISP12},{HEX_A,BRANCH_12}},
+
+/* 1011i12......... bsr <bdisp12> */{"bsr",{A_BDISP12},{HEX_B,BRANCH_12}},
+
+/* 10001001i8p1.... bt <bdisp8> */{"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}},
+
+/* 10001011i8p1.... bf <bdisp8> */{"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}},
+
+/* 10001101i8p1.... bt.s <bdisp8> */{"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
+
+/* 10001101i8p1.... bt/s <bdisp8> */{"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
+
+/* 10001111i8p1.... bf.s <bdisp8> */{"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
+
+/* 10001111i8p1.... bf/s <bdisp8> */{"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
+
+/* 0000000000101000 clrmac */{"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}},
+
+/* 0000000001001000 clrs */{"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}},
+
+/* 0000000000001000 clrt */{"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}},
+
+/* 10001000i8*1.... cmp/eq #<imm>,R0 */{"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}},
+
+/* 0011nnnnmmmm0000 cmp/eq <REG_M>,<REG_N>*/{"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}},
+
+/* 0011nnnnmmmm0011 cmp/ge <REG_M>,<REG_N>*/{"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}},
+
+/* 0011nnnnmmmm0111 cmp/gt <REG_M>,<REG_N>*/{"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}},
+
+/* 0011nnnnmmmm0110 cmp/hi <REG_M>,<REG_N>*/{"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}},
+
+/* 0011nnnnmmmm0010 cmp/hs <REG_M>,<REG_N>*/{"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}},
+
+/* 0100nnnn00010101 cmp/pl <REG_N> */{"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}},
+
+/* 0100nnnn00010001 cmp/pz <REG_N> */{"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}},
+
+/* 0010nnnnmmmm1100 cmp/str <REG_M>,<REG_N>*/{"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}},
+
+/* 0010nnnnmmmm0111 div0s <REG_M>,<REG_N>*/{"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}},
+
+/* 0000000000011001 div0u */{"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}},
+
+/* 0011nnnnmmmm0100 div1 <REG_M>,<REG_N>*/{"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}},
+
+/* 0110nnnnmmmm1110 exts.b <REG_M>,<REG_N>*/{"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}},
+
+/* 0110nnnnmmmm1111 exts.w <REG_M>,<REG_N>*/{"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}},
+
+/* 0110nnnnmmmm1100 extu.b <REG_M>,<REG_N>*/{"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}},
+
+/* 0110nnnnmmmm1101 extu.w <REG_M>,<REG_N>*/{"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}},
+
+/* 0100nnnn00101011 jmp @<REG_N> */{"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}},
+
+/* 0100nnnn00001011 jsr @<REG_N> */{"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}},
+
+/* 0100nnnn00001110 ldc <REG_N>,SR */{"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}},
+
+/* 0100nnnn00011110 ldc <REG_N>,GBR */{"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}},
+
+/* 0100nnnn00101110 ldc <REG_N>,VBR */{"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}},
+
+/* 0100nnnn00111110 ldc <REG_N>,SSR */{"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}},
+
+/* 0100nnnn01001110 ldc <REG_N>,SPC */{"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}},
+
+/* 0100nnnn01111110 ldc <REG_N>,DBR */{"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_E}},
+
+/* 0100nnnn1xxx1110 ldc <REG_N>,Rn_BANK */{"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}},
+
+/* 0100nnnn00000111 ldc.l @<REG_N>+,SR */{"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}},
+
+/* 0100nnnn00010111 ldc.l @<REG_N>+,GBR */{"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}},
+
+/* 0100nnnn00100111 ldc.l @<REG_N>+,VBR */{"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}},
+
+/* 0100nnnn00110111 ldc.l @<REG_N>+,SSR */{"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}},
+
+/* 0100nnnn01000111 ldc.l @<REG_N>+,SPC */{"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}},
+
+/* 0100nnnn01110111 ldc.l @<REG_N>+,DBR */{"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_7}},
+
+/* 0100nnnn1xxx0111 ldc.l <REG_N>,Rn_BANK */{"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}},
+
+/* 0100nnnn00001010 lds <REG_N>,MACH */{"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}},
+
+/* 0100nnnn00011010 lds <REG_N>,MACL */{"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}},
+
+/* 0100nnnn00101010 lds <REG_N>,PR */{"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}},
+
+/* 0100nnnn01011010 lds <REG_N>,FPUL */{"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}},
+
+/* 0100nnnn01101010 lds <REG_M>,FPSCR */{"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}},
+
+/* 0100nnnn00000110 lds.l @<REG_N>+,MACH*/{"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}},
+
+/* 0100nnnn00010110 lds.l @<REG_N>+,MACL*/{"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}},
+
+/* 0100nnnn00100110 lds.l @<REG_N>+,PR */{"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}},
+
+/* 0100nnnn01010110 lds.l @<REG_M>+,FPUL*/{"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}},
+
+/* 0100nnnn01100110 lds.l @<REG_M>+,FPSCR*/{"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}},
+
+/* 0000000000111000 ldtlb */{"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}},
+
+/* 0100nnnnmmmm1111 mac.w @<REG_M>+,@<REG_N>+*/{"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}},
+
+/* 1110nnnni8*1.... mov #<imm>,<REG_N> */{"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}},
+
+/* 0110nnnnmmmm0011 mov <REG_M>,<REG_N> */{"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}},
+
+/* 0000nnnnmmmm0100 mov.b <REG_M>,@(R0,<REG_N>)*/{"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}},
+
+/* 0010nnnnmmmm0100 mov.b <REG_M>,@-<REG_N>*/{"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}},
+
+/* 0010nnnnmmmm0000 mov.b <REG_M>,@<REG_N>*/{"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}},
+
+/* 10000100mmmmi4*1 mov.b @(<disp>,<REG_M>),R0*/{"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}},
+
+/* 11000100i8*1.... mov.b @(<disp>,GBR),R0*/{"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}},
+
+/* 0000nnnnmmmm1100 mov.b @(R0,<REG_M>),<REG_N>*/{"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}},
+
+/* 0110nnnnmmmm0100 mov.b @<REG_M>+,<REG_N>*/{"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}},
+
+/* 0110nnnnmmmm0000 mov.b @<REG_M>,<REG_N>*/{"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}},
+
+/* 10000000mmmmi4*1 mov.b R0,@(<disp>,<REG_M>)*/{"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}},
+
+/* 11000000i8*1.... mov.b R0,@(<disp>,GBR)*/{"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}},
+
+/* 0001nnnnmmmmi4*4 mov.l <REG_M>,@(<disp>,<REG_N>)*/{"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}},
+
+/* 0000nnnnmmmm0110 mov.l <REG_M>,@(R0,<REG_N>)*/{"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}},
+
+/* 0010nnnnmmmm0110 mov.l <REG_M>,@-<REG_N>*/{"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}},
+
+/* 0010nnnnmmmm0010 mov.l <REG_M>,@<REG_N>*/{"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}},
+
+/* 0101nnnnmmmmi4*4 mov.l @(<disp>,<REG_M>),<REG_N>*/{"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}},
+
+/* 11000110i8*4.... mov.l @(<disp>,GBR),R0*/{"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}},
+
+/* 1101nnnni8p4.... mov.l @(<disp>,PC),<REG_N>*/{"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}},
+
+/* 0000nnnnmmmm1110 mov.l @(R0,<REG_M>),<REG_N>*/{"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}},
+
+/* 0110nnnnmmmm0110 mov.l @<REG_M>+,<REG_N>*/{"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}},
+
+/* 0110nnnnmmmm0010 mov.l @<REG_M>,<REG_N>*/{"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}},
+
+/* 11000010i8*4.... mov.l R0,@(<disp>,GBR)*/{"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}},
+
+/* 0000nnnnmmmm0101 mov.w <REG_M>,@(R0,<REG_N>)*/{"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}},
+
+/* 0010nnnnmmmm0101 mov.w <REG_M>,@-<REG_N>*/{"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}},
+
+/* 0010nnnnmmmm0001 mov.w <REG_M>,@<REG_N>*/{"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}},
+
+/* 10000101mmmmi4*2 mov.w @(<disp>,<REG_M>),R0*/{"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}},
+
+/* 11000101i8*2.... mov.w @(<disp>,GBR),R0*/{"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}},
+
+/* 1001nnnni8p2.... mov.w @(<disp>,PC),<REG_N>*/{"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}},
+
+/* 0000nnnnmmmm1101 mov.w @(R0,<REG_M>),<REG_N>*/{"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}},
+
+/* 0110nnnnmmmm0101 mov.w @<REG_M>+,<REG_N>*/{"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}},
+
+/* 0110nnnnmmmm0001 mov.w @<REG_M>,<REG_N>*/{"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}},
+
+/* 10000001mmmmi4*2 mov.w R0,@(<disp>,<REG_M>)*/{"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}},
+
+/* 11000001i8*2.... mov.w R0,@(<disp>,GBR)*/{"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}},
+
+/* 11000111i8p4.... mova @(<disp>,PC),R0*/{"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}},
+/* 0000nnnn11000011 movca.l R0,@<REG_N> */{"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}},
+
+
+/* 0000nnnn00101001 movt <REG_N> */{"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}},
+
+/* 0010nnnnmmmm1111 muls <REG_M>,<REG_N>*/{"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
+
+/* 0000nnnnmmmm0111 mul.l <REG_M>,<REG_N>*/{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
+
+/* 0010nnnnmmmm1110 mulu <REG_M>,<REG_N>*/{"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
+
+/* 0110nnnnmmmm1011 neg <REG_M>,<REG_N> */{"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}},
+
+/* 0110nnnnmmmm1010 negc <REG_M>,<REG_N>*/{"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}},
+
+/* 0000000000001001 nop */{"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}},
+
+/* 0110nnnnmmmm0111 not <REG_M>,<REG_N> */{"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}},
+/* 0000nnnn10010011 ocbi @<REG_N> */{"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}},
+
+/* 0000nnnn10100011 ocbp @<REG_N> */{"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}},
+
+/* 0000nnnn10110011 ocbwb @<REG_N> */{"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}},
+
+
+/* 11001011i8*1.... or #<imm>,R0 */{"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}},
+
+/* 0010nnnnmmmm1011 or <REG_M>,<REG_N> */{"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}},
+
+/* 11001111i8*1.... or.b #<imm>,@(R0,GBR)*/{"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}},
+
+/* 0000nnnn10000011 pref @<REG_N> */{"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}},
+
+/* 0100nnnn00100100 rotcl <REG_N> */{"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}},
+
+/* 0100nnnn00100101 rotcr <REG_N> */{"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}},
+
+/* 0100nnnn00000100 rotl <REG_N> */{"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}},
+
+/* 0100nnnn00000101 rotr <REG_N> */{"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}},
+
+/* 0000000000101011 rte */{"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}},
+
+/* 0000000000001011 rts */{"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}},
+
+/* 0000000001011000 sets */{"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}},
+/* 0000000000011000 sett */{"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}},
+
+/* 0100nnnnmmmm1100 shad <REG_M>,<REG_N>*/{"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}},
+
+/* 0100nnnnmmmm1101 shld <REG_M>,<REG_N>*/{"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}},
+
+/* 0100nnnn00100000 shal <REG_N> */{"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}},
+
+/* 0100nnnn00100001 shar <REG_N> */{"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}},
+
+/* 0100nnnn00000000 shll <REG_N> */{"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}},
+
+/* 0100nnnn00101000 shll16 <REG_N> */{"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}},
+
+/* 0100nnnn00001000 shll2 <REG_N> */{"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}},
+
+/* 0100nnnn00011000 shll8 <REG_N> */{"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}},
+
+/* 0100nnnn00000001 shlr <REG_N> */{"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}},
+
+/* 0100nnnn00101001 shlr16 <REG_N> */{"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}},
+
+/* 0100nnnn00001001 shlr2 <REG_N> */{"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}},
+
+/* 0100nnnn00011001 shlr8 <REG_N> */{"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}},
+
+/* 0000000000011011 sleep */{"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}},
+
+/* 0000nnnn00000010 stc SR,<REG_N> */{"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}},
+
+/* 0000nnnn00010010 stc GBR,<REG_N> */{"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}},
+
+/* 0000nnnn00100010 stc VBR,<REG_N> */{"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}},
+
+/* 0000nnnn00110010 stc SSR,<REG_N> */{"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}},
+
+/* 0000nnnn01000010 stc SPC,<REG_N> */{"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}},
+
+/* 0000nnnn01100010 stc SGR,<REG_N> */{"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}},
+
+/* 0000nnnn01110010 stc DBR,<REG_N> */{"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}},
+
+/* 0000nnnn1xxx0012 stc Rn_BANK,<REG_N> */{"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}},
+
+/* 0100nnnn00000011 stc.l SR,@-<REG_N> */{"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}},
+
+/* 0100nnnn00010011 stc.l GBR,@-<REG_N> */{"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}},
+
+/* 0100nnnn00100011 stc.l VBR,@-<REG_N> */{"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}},
+
+/* 0100nnnn00110011 stc.l SSR,@-<REG_N> */{"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}},
+
+/* 0100nnnn01000011 stc.l SPC,@-<REG_N> */{"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}},
+
+/* 0100nnnn01100011 stc.l SGR,@-<REG_N> */{"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}},
+
+/* 0100nnnn01110011 stc.l DBR,@-<REG_N> */{"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}},
+
+/* 0100nnnn1xxx0012 stc.l Rn_BANK,@-<REG_N> */{"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}},
+
+/* 0000nnnn00001010 sts MACH,<REG_N> */{"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}},
+
+/* 0000nnnn00011010 sts MACL,<REG_N> */{"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}},
+
+/* 0000nnnn00101010 sts PR,<REG_N> */{"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}},
+
+/* 0000nnnn01011010 sts FPUL,<REG_N> */{"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}},
+
+/* 0000nnnn01101010 sts FPSCR,<REG_N> */{"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}},
+
+/* 0100nnnn00000010 sts.l MACH,@-<REG_N>*/{"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}},
+
+/* 0100nnnn00010010 sts.l MACL,@-<REG_N>*/{"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}},
+
+/* 0100nnnn00100010 sts.l PR,@-<REG_N> */{"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}},
+
+/* 0100nnnn01010010 sts.l FPUL,@-<REG_N>*/{"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}},
+
+/* 0100nnnn01100010 sts.l FPSCR,@-<REG_N>*/{"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}},
+
+/* 0011nnnnmmmm1000 sub <REG_M>,<REG_N> */{"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}},
+
+/* 0011nnnnmmmm1010 subc <REG_M>,<REG_N>*/{"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}},
+
+/* 0011nnnnmmmm1011 subv <REG_M>,<REG_N>*/{"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}},
+
+/* 0110nnnnmmmm1000 swap.b <REG_M>,<REG_N>*/{"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}},
+
+/* 0110nnnnmmmm1001 swap.w <REG_M>,<REG_N>*/{"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}},
+
+/* 0100nnnn00011011 tas.b @<REG_N> */{"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}},
+
+/* 11000011i8*1.... trapa #<imm> */{"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}},
+
+/* 11001000i8*1.... tst #<imm>,R0 */{"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}},
+
+/* 0010nnnnmmmm1000 tst <REG_M>,<REG_N> */{"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}},
+
+/* 11001100i8*1.... tst.b #<imm>,@(R0,GBR)*/{"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}},
+
+/* 11001010i8*1.... xor #<imm>,R0 */{"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}},
+
+/* 0010nnnnmmmm1010 xor <REG_M>,<REG_N> */{"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}},
+
+/* 11001110i8*1.... xor.b #<imm>,@(R0,GBR)*/{"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}},
+
+/* 0010nnnnmmmm1101 xtrct <REG_M>,<REG_N>*/{"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}},
+
+/* 0000nnnnmmmm0111 mul.l <REG_M>,<REG_N>*/{"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
+
+/* 0100nnnn00010000 dt <REG_N> */{"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}},
+
+/* 0011nnnnmmmm1101 dmuls.l <REG_M>,<REG_N>*/{"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}},
+
+/* 0011nnnnmmmm0101 dmulu.l <REG_M>,<REG_N>*/{"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}},
+
+/* 0000nnnnmmmm1111 mac.l @<REG_M>+,@<REG_N>+*/{"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}},
+
+/* 0000nnnn00100011 braf <REG_N> */{"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}},
+
+/* 0000nnnn00000011 bsrf <REG_N> */{"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}},
+
+/* 1111nnnn01011101 fabs <F_REG_N> */{"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}},
+
+/* 1111nnnnmmmm0000 fadd <F_REG_M>,<F_REG_N>*/{"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
+/* 1111nnn0mmm00000 fadd <D_REG_M>,<D_REG_N>*/{"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
+
+/* 1111nnnnmmmm0100 fcmp/eq <F_REG_M>,<F_REG_N>*/{"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
+/* 1111nnn0mmm00100 fcmp/eq <D_REG_M>,<D_REG_N>*/{"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
+
+/* 1111nnnnmmmm0101 fcmp/gt <F_REG_M>,<F_REG_N>*/{"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
+/* 1111nnn0mmm00101 fcmp/gt <D_REG_M>,<D_REG_N>*/{"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
+
+/* 1111nnn010111101 fcnvds <D_REG_N>,FPUL*/{"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}},
+
+/* 1111nnn010101101 fcnvsd FPUL,<D_REG_N>*/{"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}},
+
+/* 1111nnnnmmmm0011 fdiv <F_REG_M>,<F_REG_N>*/{"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
+/* 1111nnn0mmm00011 fdiv <D_REG_M>,<D_REG_N>*/{"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
+
+/* 1111nnmm11101101 fipr <V_REG_M>,<V_REG_N>*/{"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}},
+
+/* 1111nnnn10001101 fldi0 <F_REG_N> */{"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}},
+
+/* 1111nnnn10011101 fldi1 <F_REG_N> */{"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}},
+
+/* 1111nnnn00011101 flds <F_REG_N>,FPUL*/{"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}},
+
+/* 1111nnnn00101101 float FPUL,<FD_REG_N>*/{"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}},
+
+/* 1111nnnnmmmm1110 fmac FR0,<F_REG_M>,<F_REG_N>*/{"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}},
+
+/* 1111nnnnmmmm1100 fmov <F_REG_M>,<F_REG_N>*/{"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
+/* 1111nnnnmmmm1100 fmov <DX_REG_M>,<DX_REG_N>*/{"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
+
+/* 1111nnnnmmmm1000 fmov @<REG_M>,<F_REG_N>*/{"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+/* 1111nnnnmmmm1000 fmov @<REG_M>,<DX_REG_N>*/{"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+
+/* 1111nnnnmmmm1010 fmov <F_REG_M>,@<REG_N>*/{"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+/* 1111nnnnmmmm1010 fmov <DX_REG_M>,@<REG_N>*/{"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+
+/* 1111nnnnmmmm1001 fmov @<REG_M>+,<F_REG_N>*/{"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+/* 1111nnnnmmmm1001 fmov @<REG_M>+,<DX_REG_N>*/{"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+
+/* 1111nnnnmmmm1011 fmov <F_REG_M>,@-<REG_N>*/{"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+/* 1111nnnnmmmm1011 fmov <DX_REG_M>,@-<REG_N>*/{"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+
+/* 1111nnnnmmmm0110 fmov @(R0,<REG_M>),<F_REG_N>*/{"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+/* 1111nnnnmmmm0110 fmov @(R0,<REG_M>),<DX_REG_N>*/{"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+
+/* 1111nnnnmmmm0111 fmov <F_REG_M>,@(R0,<REG_N>)*/{"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+/* 1111nnnnmmmm0111 fmov <DX_REG_M>,@(R0,<REG_N>)*/{"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+
+/* 1111nnnnmmmm1000 fmov.d @<REG_M>,<DX_REG_N>*/{"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+
+/* 1111nnnnmmmm1010 fmov.d <DX_REG_M>,@<REG_N>*/{"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+
+/* 1111nnnnmmmm1001 fmov.d @<REG_M>+,<DX_REG_N>*/{"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+
+/* 1111nnnnmmmm1011 fmov.d <DX_REG_M>,@-<REG_N>*/{"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+
+/* 1111nnnnmmmm0110 fmov.d @(R0,<REG_M>),<DX_REG_N>*/{"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+
+/* 1111nnnnmmmm0111 fmov.d <DX_REG_M>,@(R0,<REG_N>)*/{"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+
+/* 1111nnnnmmmm1000 fmov.s @<REG_M>,<F_REG_N>*/{"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
+
+/* 1111nnnnmmmm1010 fmov.s <F_REG_M>,@<REG_N>*/{"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
+
+/* 1111nnnnmmmm1001 fmov.s @<REG_M>+,<F_REG_N>*/{"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
+
+/* 1111nnnnmmmm1011 fmov.s <F_REG_M>,@-<REG_N>*/{"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
+
+/* 1111nnnnmmmm0110 fmov.s @(R0,<REG_M>),<F_REG_N>*/{"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
+
+/* 1111nnnnmmmm0111 fmov.s <F_REG_M>,@(R0,<REG_N>)*/{"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
+
+/* 1111nnnnmmmm0010 fmul <F_REG_M>,<F_REG_N>*/{"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
+/* 1111nnn0mmm00010 fmul <D_REG_M>,<D_REG_N>*/{"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
+
+/* 1111nnnn01001101 fneg <FD_REG_N> */{"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}},
+
+/* 1111101111111101 frchg */{"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}},
+
+/* 1111001111111101 fschg */{"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}},
+
+/* 1111nnnn01101101 fsqrt <FD_REG_N> */{"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}},
+
+/* 1111nnnn00001101 fsts FPUL,<F_REG_N>*/{"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}},
+
+/* 1111nnnnmmmm0001 fsub <F_REG_M>,<F_REG_N>*/{"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
+/* 1111nnn0mmm00001 fsub <D_REG_M>,<D_REG_N>*/{"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
+
+/* 1111nnnn00111101 ftrc <FD_REG_N>,FPUL*/{"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}},
+
+/* 1111nn0111111101 ftrv XMTRX_M4,<V_REG_n>*/{"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}},
+
+{ 0 }
+};
+
+#endif
diff --git a/opcodes/sparc-dis.c b/opcodes/sparc-dis.c
new file mode 100644
index 00000000000..0975b280e28
--- /dev/null
+++ b/opcodes/sparc-dis.c
@@ -0,0 +1,969 @@
+/* Print SPARC instructions.
+ Copyright (C) 1989, 91-97, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+
+#include "ansidecl.h"
+#include "sysdep.h"
+#include "opcode/sparc.h"
+#include "dis-asm.h"
+#include "libiberty.h"
+#include "opintl.h"
+
+/* Bitmask of v9 architectures. */
+#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
+ | (1 << SPARC_OPCODE_ARCH_V9A))
+/* 1 if INSN is for v9 only. */
+#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
+/* 1 if INSN is for v9. */
+#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
+
+/* The sorted opcode table. */
+static const struct sparc_opcode **sorted_opcodes;
+
+/* For faster lookup, after insns are sorted they are hashed. */
+/* ??? I think there is room for even more improvement. */
+
+#define HASH_SIZE 256
+/* It is important that we only look at insn code bits as that is how the
+ opcode table is hashed. OPCODE_BITS is a table of valid bits for each
+ of the main types (0,1,2,3). */
+static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
+#define HASH_INSN(INSN) \
+ ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
+struct opcode_hash {
+ struct opcode_hash *next;
+ const struct sparc_opcode *opcode;
+};
+static struct opcode_hash *opcode_hash_table[HASH_SIZE];
+
+static void build_hash_table
+ PARAMS ((const struct sparc_opcode **, struct opcode_hash **, int));
+static int is_delayed_branch PARAMS ((unsigned long));
+static int compare_opcodes PARAMS ((const PTR, const PTR));
+static int compute_arch_mask PARAMS ((unsigned long));
+
+/* Sign-extend a value which is N bits long. */
+#define SEX(value, bits) \
+ ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
+ >> ((8 * sizeof (int)) - bits) )
+
+static char *reg_names[] =
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+ "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
+/* psr, wim, tbr, fpsr, cpsr are v8 only. */
+ "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
+};
+
+#define freg_names (&reg_names[4 * 8])
+
+/* These are ordered according to there register number in
+ rdpr and wrpr insns. */
+static char *v9_priv_reg_names[] =
+{
+ "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
+ "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate", "fq"
+ /* "ver" - special cased */
+};
+
+/* These are ordered according to there register number in
+ rd and wr insns (-16). */
+static char *v9a_asr_reg_names[] =
+{
+ "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
+ "softint", "tick_cmpr"
+};
+
+/* Macros used to extract instruction fields. Not all fields have
+ macros defined here, only those which are actually used. */
+
+#define X_RD(i) (((i) >> 25) & 0x1f)
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_LDST_I(i) (((i) >> 13) & 1)
+#define X_ASI(i) (((i) >> 5) & 0xff)
+#define X_RS2(i) (((i) >> 0) & 0x1f)
+#define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
+#define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
+#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
+#define X_IMM22(i) X_DISP22 (i)
+#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
+
+/* These are for v9. */
+#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
+#define X_DISP19(i) (((i) >> 0) & 0x7ffff)
+#define X_MEMBAR(i) ((i) & 0x7f)
+
+/* Here is the union which was used to extract instruction fields
+ before the shift and mask macros were written.
+
+ union sparc_insn
+ {
+ unsigned long int code;
+ struct
+ {
+ unsigned int anop:2;
+ #define op ldst.anop
+ unsigned int anrd:5;
+ #define rd ldst.anrd
+ unsigned int op3:6;
+ unsigned int anrs1:5;
+ #define rs1 ldst.anrs1
+ unsigned int i:1;
+ unsigned int anasi:8;
+ #define asi ldst.anasi
+ unsigned int anrs2:5;
+ #define rs2 ldst.anrs2
+ #define shcnt rs2
+ } ldst;
+ struct
+ {
+ unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
+ unsigned int IMM13:13;
+ #define imm13 IMM13.IMM13
+ } IMM13;
+ struct
+ {
+ unsigned int anop:2;
+ unsigned int a:1;
+ unsigned int cond:4;
+ unsigned int op2:3;
+ unsigned int DISP22:22;
+ #define disp22 branch.DISP22
+ #define imm22 disp22
+ } branch;
+ struct
+ {
+ unsigned int anop:2;
+ unsigned int a:1;
+ unsigned int z:1;
+ unsigned int rcond:3;
+ unsigned int op2:3;
+ unsigned int DISP16HI:2;
+ unsigned int p:1;
+ unsigned int _rs1:5;
+ unsigned int DISP16LO:14;
+ } branch16;
+ struct
+ {
+ unsigned int anop:2;
+ unsigned int adisp30:30;
+ #define disp30 call.adisp30
+ } call;
+ };
+
+ */
+
+/* Nonzero if INSN is the opcode for a delayed branch. */
+static int
+is_delayed_branch (insn)
+ unsigned long insn;
+{
+ struct opcode_hash *op;
+
+ for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
+ {
+ CONST struct sparc_opcode *opcode = op->opcode;
+ if ((opcode->match & insn) == opcode->match
+ && (opcode->lose & insn) == 0)
+ return (opcode->flags & F_DELAYED);
+ }
+ return 0;
+}
+
+/* extern void qsort (); */
+
+/* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
+ to compare_opcodes. */
+static unsigned int current_arch_mask;
+
+/* Print one instruction from MEMADDR on INFO->STREAM.
+
+ We suffix the instruction with a comment that gives the absolute
+ address involved, as well as its symbolic form, if the instruction
+ is preceded by a findable `sethi' and it either adds an immediate
+ displacement to that register, or it is an `add' or `or' instruction
+ on that register. */
+
+int
+print_insn_sparc (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info *info;
+{
+ FILE *stream = info->stream;
+ bfd_byte buffer[4];
+ unsigned long insn;
+ register struct opcode_hash *op;
+ /* Nonzero of opcode table has been initialized. */
+ static int opcodes_initialized = 0;
+ /* bfd mach number of last call. */
+ static unsigned long current_mach = 0;
+ bfd_vma (*getword) PARAMS ((const unsigned char *));
+
+ if (!opcodes_initialized
+ || info->mach != current_mach)
+ {
+ int i;
+
+ current_arch_mask = compute_arch_mask (info->mach);
+
+ if (!opcodes_initialized)
+ sorted_opcodes = (const struct sparc_opcode **)
+ xmalloc (sparc_num_opcodes * sizeof (struct sparc_opcode *));
+ /* Reset the sorted table so we can resort it. */
+ for (i = 0; i < sparc_num_opcodes; ++i)
+ sorted_opcodes[i] = &sparc_opcodes[i];
+ qsort ((char *) sorted_opcodes, sparc_num_opcodes,
+ sizeof (sorted_opcodes[0]), compare_opcodes);
+
+ build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
+ current_mach = info->mach;
+ opcodes_initialized = 1;
+ }
+
+ {
+ int status =
+ (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ }
+
+ /* On SPARClite variants such as DANlite (sparc86x), instructions
+ are always big-endian even when the machine is in little-endian mode. */
+ if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
+ getword = bfd_getb32;
+ else
+ getword = bfd_getl32;
+
+ insn = getword (buffer);
+
+ info->insn_info_valid = 1; /* We do return this info */
+ info->insn_type = dis_nonbranch; /* Assume non branch insn */
+ info->branch_delay_insns = 0; /* Assume no delay */
+ info->target = 0; /* Assume no target known */
+
+ for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
+ {
+ CONST struct sparc_opcode *opcode = op->opcode;
+
+ /* If the insn isn't supported by the current architecture, skip it. */
+ if (! (opcode->architecture & current_arch_mask))
+ continue;
+
+ if ((opcode->match & insn) == opcode->match
+ && (opcode->lose & insn) == 0)
+ {
+ /* Nonzero means that we have found an instruction which has
+ the effect of adding or or'ing the imm13 field to rs1. */
+ int imm_added_to_rs1 = 0;
+
+ /* Nonzero means that we have found a plus sign in the args
+ field of the opcode table. */
+ int found_plus = 0;
+
+ /* Nonzero means we have an annulled branch. */
+ int is_annulled = 0;
+
+ /* Do we have an `add' or `or' instruction combining an
+ immediate with rs1? */
+ if (opcode->match == 0x80102000 || opcode->match == 0x80002000)
+ /* (or) (add) */
+ imm_added_to_rs1 = 1;
+
+ if (X_RS1 (insn) != X_RD (insn)
+ && strchr (opcode->args, 'r') != 0)
+ /* Can't do simple format if source and dest are different. */
+ continue;
+ if (X_RS2 (insn) != X_RD (insn)
+ && strchr (opcode->args, 'O') != 0)
+ /* Can't do simple format if source and dest are different. */
+ continue;
+
+ (*info->fprintf_func) (stream, opcode->name);
+
+ {
+ register CONST char *s;
+
+ if (opcode->args[0] != ',')
+ (*info->fprintf_func) (stream, " ");
+ for (s = opcode->args; *s != '\0'; ++s)
+ {
+ while (*s == ',')
+ {
+ (*info->fprintf_func) (stream, ",");
+ ++s;
+ switch (*s) {
+ case 'a':
+ (*info->fprintf_func) (stream, "a");
+ is_annulled = 1;
+ ++s;
+ continue;
+ case 'N':
+ (*info->fprintf_func) (stream, "pn");
+ ++s;
+ continue;
+
+ case 'T':
+ (*info->fprintf_func) (stream, "pt");
+ ++s;
+ continue;
+
+ default:
+ break;
+ } /* switch on arg */
+ } /* while there are comma started args */
+
+ (*info->fprintf_func) (stream, " ");
+
+ switch (*s)
+ {
+ case '+':
+ found_plus = 1;
+
+ /* note fall-through */
+ default:
+ (*info->fprintf_func) (stream, "%c", *s);
+ break;
+
+ case '#':
+ (*info->fprintf_func) (stream, "0");
+ break;
+
+#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
+ case '1':
+ case 'r':
+ reg (X_RS1 (insn));
+ break;
+
+ case '2':
+ case 'O':
+ reg (X_RS2 (insn));
+ break;
+
+ case 'd':
+ reg (X_RD (insn));
+ break;
+#undef reg
+
+#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
+#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
+ case 'e':
+ freg (X_RS1 (insn));
+ break;
+ case 'v': /* double/even */
+ case 'V': /* quad/multiple of 4 */
+ fregx (X_RS1 (insn));
+ break;
+
+ case 'f':
+ freg (X_RS2 (insn));
+ break;
+ case 'B': /* double/even */
+ case 'R': /* quad/multiple of 4 */
+ fregx (X_RS2 (insn));
+ break;
+
+ case 'g':
+ freg (X_RD (insn));
+ break;
+ case 'H': /* double/even */
+ case 'J': /* quad/multiple of 4 */
+ fregx (X_RD (insn));
+ break;
+#undef freg
+#undef fregx
+
+#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
+ case 'b':
+ creg (X_RS1 (insn));
+ break;
+
+ case 'c':
+ creg (X_RS2 (insn));
+ break;
+
+ case 'D':
+ creg (X_RD (insn));
+ break;
+#undef creg
+
+ case 'h':
+ (*info->fprintf_func) (stream, "%%hi(%#x)",
+ (0xFFFFFFFF
+ & ((int) X_IMM22 (insn) << 10)));
+ break;
+
+ case 'i': /* 13 bit immediate */
+ case 'I': /* 11 bit immediate */
+ case 'j': /* 10 bit immediate */
+ {
+ int imm;
+
+ if (*s == 'i')
+ imm = X_SIMM (insn, 13);
+ else if (*s == 'I')
+ imm = X_SIMM (insn, 11);
+ else
+ imm = X_SIMM (insn, 10);
+
+ /* Check to see whether we have a 1+i, and take
+ note of that fact.
+
+ Note: because of the way we sort the table,
+ we will be matching 1+i rather than i+1,
+ so it is OK to assume that i is after +,
+ not before it. */
+ if (found_plus)
+ imm_added_to_rs1 = 1;
+
+ if (imm <= 9)
+ (*info->fprintf_func) (stream, "%d", imm);
+ else
+ (*info->fprintf_func) (stream, "%#x", imm);
+ }
+ break;
+
+ case 'X': /* 5 bit unsigned immediate */
+ case 'Y': /* 6 bit unsigned immediate */
+ {
+ int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
+
+ if (imm <= 9)
+ (info->fprintf_func) (stream, "%d", imm);
+ else
+ (info->fprintf_func) (stream, "%#x", (unsigned) imm);
+ }
+ break;
+
+ case 'K':
+ {
+ int mask = X_MEMBAR (insn);
+ int bit = 0x40, printed_one = 0;
+ const char *name;
+
+ if (mask == 0)
+ (info->fprintf_func) (stream, "0");
+ else
+ while (bit)
+ {
+ if (mask & bit)
+ {
+ if (printed_one)
+ (info->fprintf_func) (stream, "|");
+ name = sparc_decode_membar (bit);
+ (info->fprintf_func) (stream, "%s", name);
+ printed_one = 1;
+ }
+ bit >>= 1;
+ }
+ break;
+ }
+
+ case 'k':
+ info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case 'G':
+ info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
+ break;
+
+ case 'z':
+ (*info->fprintf_func) (stream, "%%icc");
+ break;
+
+ case 'Z':
+ (*info->fprintf_func) (stream, "%%xcc");
+ break;
+
+ case 'E':
+ (*info->fprintf_func) (stream, "%%ccr");
+ break;
+
+ case 's':
+ (*info->fprintf_func) (stream, "%%fprs");
+ break;
+
+ case 'o':
+ (*info->fprintf_func) (stream, "%%asi");
+ break;
+
+ case 'W':
+ (*info->fprintf_func) (stream, "%%tick");
+ break;
+
+ case 'P':
+ (*info->fprintf_func) (stream, "%%pc");
+ break;
+
+ case '?':
+ if (X_RS1 (insn) == 31)
+ (*info->fprintf_func) (stream, "%%ver");
+ else if ((unsigned) X_RS1 (insn) < 16)
+ (*info->fprintf_func) (stream, "%%%s",
+ v9_priv_reg_names[X_RS1 (insn)]);
+ else
+ (*info->fprintf_func) (stream, "%%reserved");
+ break;
+
+ case '!':
+ if ((unsigned) X_RD (insn) < 15)
+ (*info->fprintf_func) (stream, "%%%s",
+ v9_priv_reg_names[X_RD (insn)]);
+ else
+ (*info->fprintf_func) (stream, "%%reserved");
+ break;
+
+ case '/':
+ if (X_RS1 (insn) < 16 || X_RS1 (insn) > 23)
+ (*info->fprintf_func) (stream, "%%reserved");
+ else
+ (*info->fprintf_func) (stream, "%%%s",
+ v9a_asr_reg_names[X_RS1 (insn)-16]);
+ break;
+
+ case '_':
+ if (X_RD (insn) < 16 || X_RD (insn) > 23)
+ (*info->fprintf_func) (stream, "%%reserved");
+ else
+ (*info->fprintf_func) (stream, "%%%s",
+ v9a_asr_reg_names[X_RD (insn)-16]);
+ break;
+
+ case '*':
+ {
+ const char *name = sparc_decode_prefetch (X_RD (insn));
+
+ if (name)
+ (*info->fprintf_func) (stream, "%s", name);
+ else
+ (*info->fprintf_func) (stream, "%d", X_RD (insn));
+ break;
+ }
+
+ case 'M':
+ (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
+ break;
+
+ case 'm':
+ (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
+ break;
+
+ case 'L':
+ info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case 'n':
+ (*info->fprintf_func)
+ (stream, "%#x", SEX (X_DISP22 (insn), 22));
+ break;
+
+ case 'l':
+ info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case 'A':
+ {
+ const char *name = sparc_decode_asi (X_ASI (insn));
+
+ if (name)
+ (*info->fprintf_func) (stream, "%s", name);
+ else
+ (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
+ break;
+ }
+
+ case 'C':
+ (*info->fprintf_func) (stream, "%%csr");
+ break;
+
+ case 'F':
+ (*info->fprintf_func) (stream, "%%fsr");
+ break;
+
+ case 'p':
+ (*info->fprintf_func) (stream, "%%psr");
+ break;
+
+ case 'q':
+ (*info->fprintf_func) (stream, "%%fq");
+ break;
+
+ case 'Q':
+ (*info->fprintf_func) (stream, "%%cq");
+ break;
+
+ case 't':
+ (*info->fprintf_func) (stream, "%%tbr");
+ break;
+
+ case 'w':
+ (*info->fprintf_func) (stream, "%%wim");
+ break;
+
+ case 'x':
+ (*info->fprintf_func) (stream, "%d",
+ ((X_LDST_I (insn) << 8)
+ + X_ASI (insn)));
+ break;
+
+ case 'y':
+ (*info->fprintf_func) (stream, "%%y");
+ break;
+
+ case 'u':
+ case 'U':
+ {
+ int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
+ const char *name = sparc_decode_sparclet_cpreg (val);
+
+ if (name)
+ (*info->fprintf_func) (stream, "%s", name);
+ else
+ (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
+ break;
+ }
+ }
+ }
+ }
+
+ /* If we are adding or or'ing something to rs1, then
+ check to see whether the previous instruction was
+ a sethi to the same register as in the sethi.
+ If so, attempt to print the result of the add or
+ or (in this context add and or do the same thing)
+ and its symbolic value. */
+ if (imm_added_to_rs1)
+ {
+ unsigned long prev_insn;
+ int errcode;
+
+ errcode =
+ (*info->read_memory_func)
+ (memaddr - 4, buffer, sizeof (buffer), info);
+ prev_insn = getword (buffer);
+
+ if (errcode == 0)
+ {
+ /* If it is a delayed branch, we need to look at the
+ instruction before the delayed branch. This handles
+ sequences such as
+
+ sethi %o1, %hi(_foo), %o1
+ call _printf
+ or %o1, %lo(_foo), %o1
+ */
+
+ if (is_delayed_branch (prev_insn))
+ {
+ errcode = (*info->read_memory_func)
+ (memaddr - 8, buffer, sizeof (buffer), info);
+ prev_insn = getword (buffer);
+ }
+ }
+
+ /* If there was a problem reading memory, then assume
+ the previous instruction was not sethi. */
+ if (errcode == 0)
+ {
+ /* Is it sethi to the same register? */
+ if ((prev_insn & 0xc1c00000) == 0x01000000
+ && X_RD (prev_insn) == X_RS1 (insn))
+ {
+ (*info->fprintf_func) (stream, "\t! ");
+ info->target =
+ (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
+ | X_SIMM (insn, 13);
+ (*info->print_address_func) (info->target, info);
+ info->insn_type = dis_dref;
+ info->data_size = 4; /* FIXME!!! */
+ }
+ }
+ }
+
+ if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
+ {
+ /* FIXME -- check is_annulled flag */
+ if (opcode->flags & F_UNBR)
+ info->insn_type = dis_branch;
+ if (opcode->flags & F_CONDBR)
+ info->insn_type = dis_condbranch;
+ if (opcode->flags & F_JSR)
+ info->insn_type = dis_jsr;
+ if (opcode->flags & F_DELAYED)
+ info->branch_delay_insns = 1;
+ }
+
+ return sizeof (buffer);
+ }
+ }
+
+ info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
+ (*info->fprintf_func) (stream, _("unknown"));
+ return sizeof (buffer);
+}
+
+/* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */
+
+static int
+compute_arch_mask (mach)
+ unsigned long mach;
+{
+ switch (mach)
+ {
+ case 0 :
+ case bfd_mach_sparc :
+ return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8);
+ case bfd_mach_sparc_sparclet :
+ return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
+ case bfd_mach_sparc_sparclite :
+ case bfd_mach_sparc_sparclite_le :
+ /* sparclites insns are recognized by default (because that's how
+ they've always been treated, for better or worse). Kludge this by
+ indicating generic v8 is also selected. */
+ return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
+ | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
+ case bfd_mach_sparc_v8plus :
+ case bfd_mach_sparc_v9 :
+ return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
+ case bfd_mach_sparc_v8plusa :
+ case bfd_mach_sparc_v9a :
+ return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
+ }
+ abort ();
+}
+
+/* Compare opcodes A and B. */
+
+static int
+compare_opcodes (a, b)
+ const PTR a;
+ const PTR b;
+{
+ struct sparc_opcode *op0 = * (struct sparc_opcode **) a;
+ struct sparc_opcode *op1 = * (struct sparc_opcode **) b;
+ unsigned long int match0 = op0->match, match1 = op1->match;
+ unsigned long int lose0 = op0->lose, lose1 = op1->lose;
+ register unsigned int i;
+
+ /* If one (and only one) insn isn't supported by the current architecture,
+ prefer the one that is. If neither are supported, but they're both for
+ the same architecture, continue processing. Otherwise (both unsupported
+ and for different architectures), prefer lower numbered arch's (fudged
+ by comparing the bitmasks). */
+ if (op0->architecture & current_arch_mask)
+ {
+ if (! (op1->architecture & current_arch_mask))
+ return -1;
+ }
+ else
+ {
+ if (op1->architecture & current_arch_mask)
+ return 1;
+ else if (op0->architecture != op1->architecture)
+ return op0->architecture - op1->architecture;
+ }
+
+ /* If a bit is set in both match and lose, there is something
+ wrong with the opcode table. */
+ if (match0 & lose0)
+ {
+ fprintf
+ (stderr,
+ /* xgettext:c-format */
+ _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
+ op0->name, match0, lose0);
+ op0->lose &= ~op0->match;
+ lose0 = op0->lose;
+ }
+
+ if (match1 & lose1)
+ {
+ fprintf
+ (stderr,
+ /* xgettext:c-format */
+ _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
+ op1->name, match1, lose1);
+ op1->lose &= ~op1->match;
+ lose1 = op1->lose;
+ }
+
+ /* Because the bits that are variable in one opcode are constant in
+ another, it is important to order the opcodes in the right order. */
+ for (i = 0; i < 32; ++i)
+ {
+ unsigned long int x = 1 << i;
+ int x0 = (match0 & x) != 0;
+ int x1 = (match1 & x) != 0;
+
+ if (x0 != x1)
+ return x1 - x0;
+ }
+
+ for (i = 0; i < 32; ++i)
+ {
+ unsigned long int x = 1 << i;
+ int x0 = (lose0 & x) != 0;
+ int x1 = (lose1 & x) != 0;
+
+ if (x0 != x1)
+ return x1 - x0;
+ }
+
+ /* They are functionally equal. So as long as the opcode table is
+ valid, we can put whichever one first we want, on aesthetic grounds. */
+
+ /* Our first aesthetic ground is that aliases defer to real insns. */
+ {
+ int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
+ if (alias_diff != 0)
+ /* Put the one that isn't an alias first. */
+ return alias_diff;
+ }
+
+ /* Except for aliases, two "identical" instructions had
+ better have the same opcode. This is a sanity check on the table. */
+ i = strcmp (op0->name, op1->name);
+ if (i)
+ {
+ if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
+ return i;
+ else
+ fprintf (stderr,
+ /* xgettext:c-format */
+ _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
+ op0->name, op1->name);
+ }
+
+ /* Fewer arguments are preferred. */
+ {
+ int length_diff = strlen (op0->args) - strlen (op1->args);
+ if (length_diff != 0)
+ /* Put the one with fewer arguments first. */
+ return length_diff;
+ }
+
+ /* Put 1+i before i+1. */
+ {
+ char *p0 = (char *) strchr (op0->args, '+');
+ char *p1 = (char *) strchr (op1->args, '+');
+
+ if (p0 && p1)
+ {
+ /* There is a plus in both operands. Note that a plus
+ sign cannot be the first character in args,
+ so the following [-1]'s are valid. */
+ if (p0[-1] == 'i' && p1[1] == 'i')
+ /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
+ return 1;
+ if (p0[1] == 'i' && p1[-1] == 'i')
+ /* op0 is 1+i and op1 is i+1, so op0 goes first. */
+ return -1;
+ }
+ }
+
+ /* Put 1,i before i,1. */
+ {
+ int i0 = strncmp (op0->args, "i,1", 3) == 0;
+ int i1 = strncmp (op1->args, "i,1", 3) == 0;
+
+ if (i0 ^ i1)
+ return i0 - i1;
+ }
+
+ /* They are, as far as we can tell, identical.
+ Since qsort may have rearranged the table partially, there is
+ no way to tell which one was first in the opcode table as
+ written, so just say there are equal. */
+ /* ??? This is no longer true now that we sort a vector of pointers,
+ not the table itself. */
+ return 0;
+}
+
+/* Build a hash table from the opcode table.
+ OPCODE_TABLE is a sorted list of pointers into the opcode table. */
+
+static void
+build_hash_table (opcode_table, hash_table, num_opcodes)
+ const struct sparc_opcode **opcode_table;
+ struct opcode_hash **hash_table;
+ int num_opcodes;
+{
+ register int i;
+ int hash_count[HASH_SIZE];
+ static struct opcode_hash *hash_buf = NULL;
+
+ /* Start at the end of the table and work backwards so that each
+ chain is sorted. */
+
+ memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
+ memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
+ if (hash_buf != NULL)
+ free (hash_buf);
+ hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) * num_opcodes);
+ for (i = num_opcodes - 1; i >= 0; --i)
+ {
+ register int hash = HASH_INSN (opcode_table[i]->match);
+ register struct opcode_hash *h = &hash_buf[i];
+ h->next = hash_table[hash];
+ h->opcode = opcode_table[i];
+ hash_table[hash] = h;
+ ++hash_count[hash];
+ }
+
+#if 0 /* for debugging */
+ {
+ int min_count = num_opcodes, max_count = 0;
+ int total;
+
+ for (i = 0; i < HASH_SIZE; ++i)
+ {
+ if (hash_count[i] < min_count)
+ min_count = hash_count[i];
+ if (hash_count[i] > max_count)
+ max_count = hash_count[i];
+ total += hash_count[i];
+ }
+
+ printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
+ min_count, max_count, (double) total / HASH_SIZE);
+ }
+#endif
+}
diff --git a/opcodes/sparc-opc.c b/opcodes/sparc-opc.c
new file mode 100644
index 00000000000..b50b39b4ba9
--- /dev/null
+++ b/opcodes/sparc-opc.c
@@ -0,0 +1,1920 @@
+/* Table of opcodes for the sparc.
+ Copyright (C) 1989, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
+
+This file is part of the BFD library.
+
+BFD 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, or (at your option) any later
+version.
+
+BFD 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 software; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* FIXME-someday: perhaps the ,a's and such should be embedded in the
+ instruction's name rather than the args. This would make gas faster, pinsn
+ slower, but would mess up some macros a bit. xoxorich. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/sparc.h"
+
+/* Some defines to make life easy. */
+#define MASK_V6 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V6)
+#define MASK_V7 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V7)
+#define MASK_V8 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
+#define MASK_SPARCLET SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET)
+#define MASK_SPARCLITE SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
+#define MASK_V9 SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9)
+#define MASK_V9A SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A)
+
+/* Bit masks of architectures supporting the insn. */
+
+#define v6 (MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET \
+ | MASK_SPARCLITE | MASK_V9 | MASK_V9A)
+/* v6 insns not supported on the sparclet */
+#define v6notlet (MASK_V6 | MASK_V7 | MASK_V8 \
+ | MASK_SPARCLITE | MASK_V9 | MASK_V9A)
+#define v7 (MASK_V7 | MASK_V8 | MASK_SPARCLET \
+ | MASK_SPARCLITE | MASK_V9 | MASK_V9A)
+/* Although not all insns are implemented in hardware, sparclite is defined
+ to be a superset of v8. Unimplemented insns trap and are then theoretically
+ implemented in software.
+ It's not clear that the same is true for sparclet, although the docs
+ suggest it is. Rather than complicating things, the sparclet assembler
+ recognizes all v8 insns. */
+#define v8 (MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE | MASK_V9 | MASK_V9A)
+#define sparclet (MASK_SPARCLET)
+#define sparclite (MASK_SPARCLITE)
+#define v9 (MASK_V9 | MASK_V9A)
+#define v9a (MASK_V9A)
+/* v6 insns not supported by v9 */
+#define v6notv9 (MASK_V6 | MASK_V7 | MASK_V8 \
+ | MASK_SPARCLET | MASK_SPARCLITE)
+/* v9a instructions which would appear to be aliases to v9's impdep's
+ otherwise */
+#define v9notv9a (MASK_V9)
+
+/* Table of opcode architectures.
+ The order is defined in opcode/sparc.h. */
+
+const struct sparc_opcode_arch sparc_opcode_archs[] = {
+ { "v6", MASK_V6 },
+ { "v7", MASK_V6 | MASK_V7 },
+ { "v8", MASK_V6 | MASK_V7 | MASK_V8 },
+ { "sparclet", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET },
+ { "sparclite", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLITE },
+ /* ??? Don't some v8 priviledged insns conflict with v9? */
+ { "v9", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 },
+ /* v9 with ultrasparc additions */
+ { "v9a", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 | MASK_V9A },
+ { NULL, 0 }
+};
+
+/* Given NAME, return it's architecture entry. */
+
+enum sparc_opcode_arch_val
+sparc_opcode_lookup_arch (name)
+ const char *name;
+{
+ const struct sparc_opcode_arch *p;
+
+ for (p = &sparc_opcode_archs[0]; p->name; ++p)
+ {
+ if (strcmp (name, p->name) == 0)
+ return (enum sparc_opcode_arch_val) (p - &sparc_opcode_archs[0]);
+ }
+
+ return SPARC_OPCODE_ARCH_BAD;
+}
+
+/* Branch condition field. */
+#define COND(x) (((x)&0xf)<<25)
+
+/* v9: Move (MOVcc and FMOVcc) condition field. */
+#define MCOND(x,i_or_f) ((((i_or_f)&1)<<18)|(((x)>>11)&(0xf<<14))) /* v9 */
+
+/* v9: Move register (MOVRcc and FMOVRcc) condition field. */
+#define RCOND(x) (((x)&0x7)<<10) /* v9 */
+
+#define CONDA (COND(0x8))
+#define CONDCC (COND(0xd))
+#define CONDCS (COND(0x5))
+#define CONDE (COND(0x1))
+#define CONDG (COND(0xa))
+#define CONDGE (COND(0xb))
+#define CONDGU (COND(0xc))
+#define CONDL (COND(0x3))
+#define CONDLE (COND(0x2))
+#define CONDLEU (COND(0x4))
+#define CONDN (COND(0x0))
+#define CONDNE (COND(0x9))
+#define CONDNEG (COND(0x6))
+#define CONDPOS (COND(0xe))
+#define CONDVC (COND(0xf))
+#define CONDVS (COND(0x7))
+
+#define CONDNZ CONDNE
+#define CONDZ CONDE
+#define CONDGEU CONDCC
+#define CONDLU CONDCS
+
+#define FCONDA (COND(0x8))
+#define FCONDE (COND(0x9))
+#define FCONDG (COND(0x6))
+#define FCONDGE (COND(0xb))
+#define FCONDL (COND(0x4))
+#define FCONDLE (COND(0xd))
+#define FCONDLG (COND(0x2))
+#define FCONDN (COND(0x0))
+#define FCONDNE (COND(0x1))
+#define FCONDO (COND(0xf))
+#define FCONDU (COND(0x7))
+#define FCONDUE (COND(0xa))
+#define FCONDUG (COND(0x5))
+#define FCONDUGE (COND(0xc))
+#define FCONDUL (COND(0x3))
+#define FCONDULE (COND(0xe))
+
+#define FCONDNZ FCONDNE
+#define FCONDZ FCONDE
+
+#define ICC (0) /* v9 */
+#define XCC (1<<12) /* v9 */
+#define FCC(x) (((x)&0x3)<<11) /* v9 */
+#define FBFCC(x) (((x)&0x3)<<20) /* v9 */
+
+/* The order of the opcodes in the table is significant:
+
+ * The assembler requires that all instances of the same mnemonic must
+ be consecutive. If they aren't, the assembler will bomb at runtime.
+
+ * The disassembler should not care about the order of the opcodes.
+
+*/
+
+/* Entries for commutative arithmetic operations. */
+/* ??? More entries can make use of this. */
+#define COMMUTEOP(opcode, op3, arch_mask) \
+{ opcode, F3(2, op3, 0), F3(~2, ~op3, ~0)|ASI(~0), "1,2,d", 0, arch_mask }, \
+{ opcode, F3(2, op3, 1), F3(~2, ~op3, ~1), "1,i,d", 0, arch_mask }, \
+{ opcode, F3(2, op3, 1), F3(~2, ~op3, ~1), "i,1,d", 0, arch_mask }
+
+const struct sparc_opcode sparc_opcodes[] = {
+
+{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0), "[1+2],d", 0, v6 },
+{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0, "[1],d", 0, v6 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[1+i],d", 0, v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[i+1],d", 0, v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0), "[1+2],g", 0, v6 },
+{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0)|RS2_G0, "[1],g", 0, v6 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1), "[1+i],g", 0, v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1), "[i+1],g", 0, v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|RS1_G0, "[i],g", 0, v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|SIMM13(~0), "[1],g", 0, v6 }, /* ld [rs1+0],d */
+
+{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RD(~0), "[1+2],F", 0, v6 },
+{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RS2_G0|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0), "[1+i],F", 0, v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0), "[i+1],F", 0, v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0, v6 }, /* ld [rs1+0],d */
+
+{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1],D", 0, v6notv9 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i],D", 0, v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1],D", 0, v6notv9 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0), "[1+2],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0, "[1],C", 0, v6notv9 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[1+i],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[i+1],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0, "[i],C", 0, v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0), "[1],C", 0, v6notv9 }, /* ld [rs1+0],d */
+
+/* The v9 LDUW is the same as the old 'ld' opcode, it is not the same as the
+ 'ld' pseudo-op in v9. */
+{ "lduw", F3(3, 0x00, 0), F3(~3, ~0x00, ~0), "[1+2],d", F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0, "[1],d", F_ALIAS, v9 }, /* ld [rs1+%g0],d */
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[1+i],d", F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[i+1],d", F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0, "[i],d", F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0), "[1],d", F_ALIAS, v9 }, /* ld [rs1+0],d */
+
+{ "ldd", F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI(~0), "[1+2],d", 0, v6 },
+{ "ldd", F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldd [rs1+%g0],d */
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1), "[1+i],d", 0, v6 },
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1), "[i+1],d", 0, v6 },
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldd [rs1+0],d */
+{ "ldd", F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI(~0), "[1+2],H", 0, v6 },
+{ "ldd", F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI_RS2(~0), "[1],H", 0, v6 }, /* ldd [rs1+%g0],d */
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[1+i],H", 0, v6 },
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[i+1],H", 0, v6 },
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|RS1_G0, "[i],H", 0, v6 },
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|SIMM13(~0), "[1],H", 0, v6 }, /* ldd [rs1+0],d */
+
+{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0), "[1+2],D", 0, v6notv9 },
+{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0), "[1],D", 0, v6notv9 }, /* ldd [rs1+%g0],d */
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i],D", 0, v6notv9 },
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1],D", 0, v6notv9 },
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i],D", 0, v6notv9 },
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1],D", 0, v6notv9 }, /* ldd [rs1+0],d */
+
+{ "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI(~0), "[1+2],J", 0, v9 },
+{ "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI_RS2(~0), "[1],J", 0, v9 }, /* ldd [rs1+%g0],d */
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1), "[1+i],J", 0, v9 },
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1), "[i+1],J", 0, v9 },
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1)|RS1_G0, "[i],J", 0, v9 },
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1)|SIMM13(~0), "[1],J", 0, v9 }, /* ldd [rs1+0],d */
+
+{ "ldsb", F3(3, 0x09, 0), F3(~3, ~0x09, ~0)|ASI(~0), "[1+2],d", 0, v6 },
+{ "ldsb", F3(3, 0x09, 0), F3(~3, ~0x09, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldsb [rs1+%g0],d */
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1), "[1+i],d", 0, v6 },
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1), "[i+1],d", 0, v6 },
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldsb [rs1+0],d */
+
+{ "ldsh", F3(3, 0x0a, 0), F3(~3, ~0x0a, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldsh [rs1+%g0],d */
+{ "ldsh", F3(3, 0x0a, 0), F3(~3, ~0x0a, ~0)|ASI(~0), "[1+2],d", 0, v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1), "[1+i],d", 0, v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1), "[i+1],d", 0, v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldsh [rs1+0],d */
+
+{ "ldstub", F3(3, 0x0d, 0), F3(~3, ~0x0d, ~0)|ASI(~0), "[1+2],d", 0, v6 },
+{ "ldstub", F3(3, 0x0d, 0), F3(~3, ~0x0d, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldstub [rs1+%g0],d */
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1), "[1+i],d", 0, v6 },
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1), "[i+1],d", 0, v6 },
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldstub [rs1+0],d */
+
+{ "ldsw", F3(3, 0x08, 0), F3(~3, ~0x08, ~0)|ASI(~0), "[1+2],d", 0, v9 },
+{ "ldsw", F3(3, 0x08, 0), F3(~3, ~0x08, ~0)|ASI_RS2(~0), "[1],d", 0, v9 }, /* ldsw [rs1+%g0],d */
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1), "[1+i],d", 0, v9 },
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1), "[i+1],d", 0, v9 },
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1)|RS1_G0, "[i],d", 0, v9 },
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1)|SIMM13(~0), "[1],d", 0, v9 }, /* ldsw [rs1+0],d */
+
+{ "ldub", F3(3, 0x01, 0), F3(~3, ~0x01, ~0)|ASI(~0), "[1+2],d", 0, v6 },
+{ "ldub", F3(3, 0x01, 0), F3(~3, ~0x01, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* ldub [rs1+%g0],d */
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1), "[1+i],d", 0, v6 },
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1), "[i+1],d", 0, v6 },
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* ldub [rs1+0],d */
+
+{ "lduh", F3(3, 0x02, 0), F3(~3, ~0x02, ~0)|ASI(~0), "[1+2],d", 0, v6 },
+{ "lduh", F3(3, 0x02, 0), F3(~3, ~0x02, ~0)|ASI_RS2(~0), "[1],d", 0, v6 }, /* lduh [rs1+%g0],d */
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1), "[1+i],d", 0, v6 },
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1), "[i+1],d", 0, v6 },
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1)|RS1_G0, "[i],d", 0, v6 },
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1)|SIMM13(~0), "[1],d", 0, v6 }, /* lduh [rs1+0],d */
+
+{ "ldx", F3(3, 0x0b, 0), F3(~3, ~0x0b, ~0)|ASI(~0), "[1+2],d", 0, v9 },
+{ "ldx", F3(3, 0x0b, 0), F3(~3, ~0x0b, ~0)|ASI_RS2(~0), "[1],d", 0, v9 }, /* ldx [rs1+%g0],d */
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1), "[1+i],d", 0, v9 },
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1), "[i+1],d", 0, v9 },
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1)|RS1_G0, "[i],d", 0, v9 },
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1)|SIMM13(~0), "[1],d", 0, v9 }, /* ldx [rs1+0],d */
+
+{ "ldx", F3(3, 0x21, 0)|RD(1), F3(~3, ~0x21, ~0)|RD(~1), "[1+2],F", 0, v9 },
+{ "ldx", F3(3, 0x21, 0)|RD(1), F3(~3, ~0x21, ~0)|RS2_G0|RD(~1), "[1],F", 0, v9 }, /* ld [rs1+%g0],d */
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RD(~1), "[1+i],F", 0, v9 },
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RD(~1), "[i+1],F", 0, v9 },
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~1), "[i],F", 0, v9 },
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~1),"[1],F", 0, v9 }, /* ld [rs1+0],d */
+
+{ "lda", F3(3, 0x10, 0), F3(~3, ~0x10, ~0), "[1+2]A,d", 0, v6 },
+{ "lda", F3(3, 0x10, 0), F3(~3, ~0x10, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* lda [rs1+%g0],d */
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[1+i]o,d", 0, v9 },
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[i+1]o,d", 0, v9 },
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+{ "lda", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2]A,g", 0, v9 },
+{ "lda", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1]A,g", 0, v9 }, /* lda [rs1+%g0],d */
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i]o,g", 0, v9 },
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1]o,g", 0, v9 },
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i]o,g", 0, v9 },
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1]o,g", 0, v9 }, /* ld [rs1+0],d */
+
+{ "ldda", F3(3, 0x13, 0), F3(~3, ~0x13, ~0), "[1+2]A,d", 0, v6 },
+{ "ldda", F3(3, 0x13, 0), F3(~3, ~0x13, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldda [rs1+%g0],d */
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1), "[1+i]o,d", 0, v9 },
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1), "[i+1]o,d", 0, v9 },
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "ldda", F3(3, 0x33, 0), F3(~3, ~0x33, ~0), "[1+2]A,H", 0, v9 },
+{ "ldda", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|RS2_G0, "[1]A,H", 0, v9 }, /* ldda [rs1+%g0],d */
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i]o,H", 0, v9 },
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1]o,H", 0, v9 },
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i]o,H", 0, v9 },
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1]o,H", 0, v9 }, /* ld [rs1+0],d */
+
+{ "ldqa", F3(3, 0x32, 0), F3(~3, ~0x32, ~0), "[1+2]A,J", 0, v9 },
+{ "ldqa", F3(3, 0x32, 0), F3(~3, ~0x32, ~0)|RS2_G0, "[1]A,J", 0, v9 }, /* ldd [rs1+%g0],d */
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1), "[1+i]o,J", 0, v9 },
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1), "[i+1]o,J", 0, v9 },
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1)|RS1_G0, "[i]o,J", 0, v9 },
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1)|SIMM13(~0), "[1]o,J", 0, v9 }, /* ldd [rs1+0],d */
+
+{ "ldsba", F3(3, 0x19, 0), F3(~3, ~0x19, ~0), "[1+2]A,d", 0, v6 },
+{ "ldsba", F3(3, 0x19, 0), F3(~3, ~0x19, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldsba [rs1+%g0],d */
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1), "[1+i]o,d", 0, v9 },
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1), "[i+1]o,d", 0, v9 },
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "ldsha", F3(3, 0x1a, 0), F3(~3, ~0x1a, ~0), "[1+2]A,d", 0, v6 },
+{ "ldsha", F3(3, 0x1a, 0), F3(~3, ~0x1a, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldsha [rs1+%g0],d */
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1), "[1+i]o,d", 0, v9 },
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1), "[i+1]o,d", 0, v9 },
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "ldstuba", F3(3, 0x1d, 0), F3(~3, ~0x1d, ~0), "[1+2]A,d", 0, v6 },
+{ "ldstuba", F3(3, 0x1d, 0), F3(~3, ~0x1d, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* ldstuba [rs1+%g0],d */
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1), "[1+i]o,d", 0, v9 },
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1), "[i+1]o,d", 0, v9 },
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "ldswa", F3(3, 0x18, 0), F3(~3, ~0x18, ~0), "[1+2]A,d", 0, v9 },
+{ "ldswa", F3(3, 0x18, 0), F3(~3, ~0x18, ~0)|RS2_G0, "[1]A,d", 0, v9 }, /* lda [rs1+%g0],d */
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1), "[1+i]o,d", 0, v9 },
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1), "[i+1]o,d", 0, v9 },
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "lduba", F3(3, 0x11, 0), F3(~3, ~0x11, ~0), "[1+2]A,d", 0, v6 },
+{ "lduba", F3(3, 0x11, 0), F3(~3, ~0x11, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* lduba [rs1+%g0],d */
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1), "[1+i]o,d", 0, v9 },
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1), "[i+1]o,d", 0, v9 },
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "lduha", F3(3, 0x12, 0), F3(~3, ~0x12, ~0), "[1+2]A,d", 0, v6 },
+{ "lduha", F3(3, 0x12, 0), F3(~3, ~0x12, ~0)|RS2_G0, "[1]A,d", 0, v6 }, /* lduha [rs1+%g0],d */
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1), "[1+i]o,d", 0, v9 },
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1), "[i+1]o,d", 0, v9 },
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "lduwa", F3(3, 0x10, 0), F3(~3, ~0x10, ~0), "[1+2]A,d", F_ALIAS, v9 }, /* lduwa === lda */
+{ "lduwa", F3(3, 0x10, 0), F3(~3, ~0x10, ~0)|RS2_G0, "[1]A,d", F_ALIAS, v9 }, /* lda [rs1+%g0],d */
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[1+i]o,d", F_ALIAS, v9 },
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[i+1]o,d", F_ALIAS, v9 },
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d", F_ALIAS, v9 },
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d", F_ALIAS, v9 }, /* ld [rs1+0],d */
+
+{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0), "[1+2]A,d", 0, v9 }, /* lduwa === lda */
+{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0)|RS2_G0, "[1]A,d", 0, v9 }, /* lda [rs1+%g0],d */
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[1+i]o,d", 0, v9 },
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[i+1]o,d", 0, v9 },
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* ld [rs1+0],d */
+
+{ "st", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", 0, v6 },
+{ "st", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", 0, v6 },
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", 0, v6 },
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", 0, v6 },
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* st d,[rs1+0] */
+{ "st", F3(3, 0x24, 0), F3(~3, ~0x24, ~0)|ASI(~0), "g,[1+2]", 0, v6 },
+{ "st", F3(3, 0x24, 0), F3(~3, ~0x24, ~0)|ASI_RS2(~0), "g,[1]", 0, v6 }, /* st d[rs1+%g0] */
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1), "g,[1+i]", 0, v6 },
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1), "g,[i+1]", 0, v6 },
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|RS1_G0, "g,[i]", 0, v6 },
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|SIMM13(~0), "g,[1]", 0, v6 }, /* st d,[rs1+0] */
+
+{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0), "D,[1+2]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0), "D,[1]", 0, v6notv9 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[1+i]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "D,[i+1]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "D,[i]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "D,[1]", 0, v6notv9 }, /* st d,[rs1+0] */
+{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0), "C,[1+2]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0), "C,[1]", 0, v6notv9 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[1+i]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1), "C,[i+1]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0, "C,[i]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0), "C,[1]", 0, v6notv9 }, /* st d,[rs1+0] */
+
+{ "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI(~0), "F,[1+2]", 0, v6 },
+{ "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI_RS2(~0), "F,[1]", 0, v6 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0, "F,[1+i]", 0, v6 },
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0, "F,[i+1]", 0, v6 },
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0|RS1_G0, "F,[i]", 0, v6 },
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0|SIMM13(~0), "F,[1]", 0, v6 }, /* st d,[rs1+0] */
+
+{ "stw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]", F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+%g0] */
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]", F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]", F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]", F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]", F_ALIAS, v9 }, /* st d,[rs1+0] */
+
+{ "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", 0, v6 },
+{ "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* sta d,[rs1+%g0] */
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", 0, v9 },
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", 0, v9 },
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", 0, v9 },
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* st d,[rs1+0] */
+
+{ "sta", F3(3, 0x34, 0), F3(~3, ~0x34, ~0), "g,[1+2]A", 0, v9 },
+{ "sta", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|RS2(~0), "g,[1]A", 0, v9 }, /* sta d,[rs1+%g0] */
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "g,[1+i]o", 0, v9 },
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "g,[i+1]o", 0, v9 },
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "g,[i]o", 0, v9 },
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "g,[1]o", 0, v9 }, /* st d,[rs1+0] */
+
+{ "stwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", F_ALIAS, v9 }, /* sta d,[rs1+%g0] */
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", F_ALIAS, v9 }, /* st d,[rs1+0] */
+
+{ "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", 0, v6 },
+{ "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* stb d,[rs1+%g0] */
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", 0, v6 },
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", 0, v6 },
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", 0, v6 },
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* stb d,[rs1+0] */
+
+{ "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", 0, v6 },
+{ "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stba d,[rs1+%g0] */
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", 0, v9 },
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", 0, v9 },
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", 0, v9 },
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* stb d,[rs1+0] */
+
+{ "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI(~0), "d,[1+2]", 0, v6 },
+{ "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[1+i]", 0, v6 },
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[i+1]", 0, v6 },
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0, "d,[i]", 0, v6 },
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* std d,[rs1+0] */
+
+{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "q,[1+2]", 0, v6notv9 },
+{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "q,[1]", 0, v6notv9 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[1+i]", 0, v6notv9 },
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[i+1]", 0, v6notv9 },
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "q,[i]", 0, v6notv9 },
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "q,[1]", 0, v6notv9 }, /* std d,[rs1+0] */
+{ "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI(~0), "H,[1+2]", 0, v6 },
+{ "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI_RS2(~0), "H,[1]", 0, v6 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[1+i]", 0, v6 },
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[i+1]", 0, v6 },
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|RS1_G0, "H,[i]", 0, v6 },
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|SIMM13(~0), "H,[1]", 0, v6 }, /* std d,[rs1+0] */
+
+{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "Q,[1+2]", 0, v6notv9 },
+{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "Q,[1]", 0, v6notv9 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[1+i]", 0, v6notv9 },
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[i+1]", 0, v6notv9 },
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "Q,[i]", 0, v6notv9 },
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "Q,[1]", 0, v6notv9 }, /* std d,[rs1+0] */
+{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0), "D,[1+2]", 0, v6notv9 },
+{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0), "D,[1]", 0, v6notv9 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[1+i]", 0, v6notv9 },
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[i+1]", 0, v6notv9 },
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "D,[i]", 0, v6notv9 },
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "D,[1]", 0, v6notv9 }, /* std d,[rs1+0] */
+
+{ "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0), "d,[1+2]A", 0, v6 },
+{ "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stda d,[rs1+%g0] */
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[1+i]o", 0, v9 },
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[i+1]o", 0, v9 },
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1)|RS1_G0, "d,[i]o", 0, v9 },
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* std d,[rs1+0] */
+{ "stda", F3(3, 0x37, 0), F3(~3, ~0x37, ~0), "H,[1+2]A", 0, v9 },
+{ "stda", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|RS2(~0), "H,[1]A", 0, v9 }, /* stda d,[rs1+%g0] */
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "H,[1+i]o", 0, v9 },
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "H,[i+1]o", 0, v9 },
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "H,[i]o", 0, v9 },
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "H,[1]o", 0, v9 }, /* std d,[rs1+0] */
+
+{ "sth", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", 0, v6 },
+{ "sth", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", 0, v6 }, /* sth d,[rs1+%g0] */
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", 0, v6 },
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", 0, v6 },
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", 0, v6 },
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", 0, v6 }, /* sth d,[rs1+0] */
+
+{ "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", 0, v6 },
+{ "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", 0, v6 }, /* stha ,[rs1+%g0] */
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", 0, v9 },
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", 0, v9 },
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", 0, v9 },
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* sth d,[rs1+0] */
+
+{ "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI(~0), "d,[1+2]", 0, v9 },
+{ "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI_RS2(~0), "d,[1]", 0, v9 }, /* stx d,[rs1+%g0] */
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[1+i]", 0, v9 },
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[i+1]", 0, v9 },
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RS1_G0, "d,[i]", 0, v9 },
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|SIMM13(~0), "d,[1]", 0, v9 }, /* stx d,[rs1+0] */
+
+{ "stx", F3(3, 0x25, 0)|RD(1), F3(~3, ~0x25, ~0)|ASI(~0)|RD(~1), "F,[1+2]", 0, v9 },
+{ "stx", F3(3, 0x25, 0)|RD(1), F3(~3, ~0x25, ~0)|ASI_RS2(~0)|RD(~1),"F,[1]", 0, v9 }, /* stx d,[rs1+%g0] */
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RD(~1), "F,[1+i]", 0, v9 },
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RD(~1), "F,[i+1]", 0, v9 },
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RS1_G0|RD(~1), "F,[i]", 0, v9 },
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|SIMM13(~0)|RD(~1),"F,[1]", 0, v9 }, /* stx d,[rs1+0] */
+
+{ "stxa", F3(3, 0x1e, 0), F3(~3, ~0x1e, ~0), "d,[1+2]A", 0, v9 },
+{ "stxa", F3(3, 0x1e, 0), F3(~3, ~0x1e, ~0)|RS2(~0), "d,[1]A", 0, v9 }, /* stxa d,[rs1+%g0] */
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1), "d,[1+i]o", 0, v9 },
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1), "d,[i+1]o", 0, v9 },
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1)|RS1_G0, "d,[i]o", 0, v9 },
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1)|SIMM13(~0), "d,[1]o", 0, v9 }, /* stx d,[rs1+0] */
+
+{ "stq", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "J,[1+2]", 0, v9 },
+{ "stq", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "J,[1]", 0, v9 }, /* stq [rs1+%g0] */
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "J,[1+i]", 0, v9 },
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "J,[i+1]", 0, v9 },
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "J,[i]", 0, v9 },
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "J,[1]", 0, v9 }, /* stq [rs1+0] */
+
+{ "stqa", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "J,[1+2]A", 0, v9 },
+{ "stqa", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "J,[1]A", 0, v9 }, /* stqa [rs1+%g0] */
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "J,[1+i]o", 0, v9 },
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "J,[i+1]o", 0, v9 },
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "J,[i]o", 0, v9 },
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "J,[1]o", 0, v9 }, /* stqa [rs1+0] */
+
+{ "swap", F3(3, 0x0f, 0), F3(~3, ~0x0f, ~0)|ASI(~0), "[1+2],d", 0, v7 },
+{ "swap", F3(3, 0x0f, 0), F3(~3, ~0x0f, ~0)|ASI_RS2(~0), "[1],d", 0, v7 }, /* swap [rs1+%g0],d */
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1), "[1+i],d", 0, v7 },
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1), "[i+1],d", 0, v7 },
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1)|RS1_G0, "[i],d", 0, v7 },
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1)|SIMM13(~0), "[1],d", 0, v7 }, /* swap [rs1+0],d */
+
+{ "swapa", F3(3, 0x1f, 0), F3(~3, ~0x1f, ~0), "[1+2]A,d", 0, v7 },
+{ "swapa", F3(3, 0x1f, 0), F3(~3, ~0x1f, ~0)|RS2(~0), "[1]A,d", 0, v7 }, /* swapa [rs1+%g0],d */
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1), "[1+i]o,d", 0, v9 },
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1), "[i+1]o,d", 0, v9 },
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1)|RS1_G0, "[i]o,d", 0, v9 },
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1)|SIMM13(~0), "[1]o,d", 0, v9 }, /* swap [rs1+0],d */
+
+{ "restore", F3(2, 0x3d, 0), F3(~2, ~0x3d, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "restore", F3(2, 0x3d, 0), F3(~2, ~0x3d, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "", 0, v6 }, /* restore %g0,%g0,%g0 */
+{ "restore", F3(2, 0x3d, 1), F3(~2, ~0x3d, ~1), "1,i,d", 0, v6 },
+{ "restore", F3(2, 0x3d, 1), F3(~2, ~0x3d, ~1)|RD_G0|RS1_G0|SIMM13(~0), "", 0, v6 }, /* restore %g0,0,%g0 */
+
+{ "rett", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|RD_G0|ASI(~0), "1+2", F_UNBR|F_DELAYED, v6 }, /* rett rs1+rs2 */
+{ "rett", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|RD_G0|ASI_RS2(~0), "1", F_UNBR|F_DELAYED, v6 }, /* rett rs1,%g0 */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0, "1+i", F_UNBR|F_DELAYED, v6 }, /* rett rs1+X */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0, "i+1", F_UNBR|F_DELAYED, v6 }, /* rett X+rs1 */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|RS1_G0, "i", F_UNBR|F_DELAYED, v6 }, /* rett X+rs1 */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|RS1_G0, "i", F_UNBR|F_DELAYED, v6 }, /* rett X */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|SIMM13(~0), "1", F_UNBR|F_DELAYED, v6 }, /* rett rs1+0 */
+
+{ "save", F3(2, 0x3c, 0), F3(~2, ~0x3c, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "save", F3(2, 0x3c, 1), F3(~2, ~0x3c, ~1), "1,i,d", 0, v6 },
+{ "save", 0x81e00000, ~0x81e00000, "", F_ALIAS, v6 },
+
+{ "ret", F3(2, 0x38, 1)|RS1(0x1f)|SIMM13(8), F3(~2, ~0x38, ~1)|SIMM13(~8), "", F_UNBR|F_DELAYED, v6 }, /* jmpl %i7+8,%g0 */
+{ "retl", F3(2, 0x38, 1)|RS1(0x0f)|SIMM13(8), F3(~2, ~0x38, ~1)|RS1(~0x0f)|SIMM13(~8), "", F_UNBR|F_DELAYED, v6 }, /* jmpl %o7+8,%g0 */
+
+{ "jmpl", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|ASI(~0), "1+2,d", F_JSR|F_DELAYED, v6 },
+{ "jmpl", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|ASI_RS2(~0), "1,d", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+%g0,d */
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|SIMM13(~0), "1,d", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+0,d */
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RS1_G0, "i,d", F_JSR|F_DELAYED, v6 }, /* jmpl %g0+i,d */
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "1+i,d", F_JSR|F_DELAYED, v6 },
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "i+1,d", F_JSR|F_DELAYED, v6 },
+
+{ "done", F3(2, 0x3e, 0)|RD(0), F3(~2, ~0x3e, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "retry", F3(2, 0x3e, 0)|RD(1), F3(~2, ~0x3e, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "saved", F3(2, 0x31, 0)|RD(0), F3(~2, ~0x31, ~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "restored", F3(2, 0x31, 0)|RD(1), F3(~2, ~0x31, ~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "sir", F3(2, 0x30, 1)|RD(0xf), F3(~2, ~0x30, ~1)|RD(~0xf)|RS1_G0, "i", 0, v9 },
+
+{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", 0, v8 },
+{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", 0, v8 }, /* flush rs1+%g0 */
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|SIMM13(~0), "1", 0, v8 }, /* flush rs1+0 */
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|RS1_G0, "i", 0, v8 }, /* flush %g0+i */
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "1+i", 0, v8 },
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "i+1", 0, v8 },
+
+/* IFLUSH was renamed to FLUSH in v8. */
+{ "iflush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", F_ALIAS, v6 },
+{ "iflush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", F_ALIAS, v6 }, /* flush rs1+%g0 */
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|SIMM13(~0), "1", F_ALIAS, v6 }, /* flush rs1+0 */
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|RS1_G0, "i", F_ALIAS, v6 },
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "1+i", F_ALIAS, v6 },
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "i+1", F_ALIAS, v6 },
+
+{ "return", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|ASI(~0), "1+2", 0, v9 },
+{ "return", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|ASI_RS2(~0), "1", 0, v9 }, /* return rs1+%g0 */
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|SIMM13(~0), "1", 0, v9 }, /* return rs1+0 */
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RS1_G0, "i", 0, v9 }, /* return %g0+i */
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1), "1+i", 0, v9 },
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1), "i+1", 0, v9 },
+
+{ "flushw", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "", 0, v9 },
+
+{ "membar", F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28, ~1)|RD_G0|RS1(~0xf)|SIMM13(~127), "K", 0, v9 },
+{ "stbar", F3(2, 0x28, 0)|RS1(0xf), F3(~2, ~0x28, ~0)|RD_G0|RS1(~0xf)|SIMM13(~0), "", 0, v8 },
+
+{ "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0), "[1+2],*", 0, v9 },
+{ "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0)|RS2_G0, "[1],*", 0, v9 }, /* prefetch [rs1+%g0],prefetch_fcn */
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1), "[1+i],*", 0, v9 },
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1), "[i+1],*", 0, v9 },
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1)|RS1_G0, "[i],*", 0, v9 },
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1)|SIMM13(~0), "[1],*", 0, v9 }, /* prefetch [rs1+0],prefetch_fcn */
+{ "prefetcha", F3(3, 0x3d, 0), F3(~3, ~0x3d, ~0), "[1+2]A,*", 0, v9 },
+{ "prefetcha", F3(3, 0x3d, 0), F3(~3, ~0x3d, ~0)|RS2_G0, "[1]A,*", 0, v9 }, /* prefetcha [rs1+%g0],prefetch_fcn */
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1), "[1+i]o,*", 0, v9 },
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1), "[i+1]o,*", 0, v9 },
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|RS1_G0, "[i]o,*", 0, v9 },
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|SIMM13(~0), "[1]o,*", 0, v9 }, /* prefetcha [rs1+0],d */
+
+{ "sll", F3(2, 0x25, 0), F3(~2, ~0x25, ~0)|(1<<12)|(0x7f<<5), "1,2,d", 0, v6 },
+{ "sll", F3(2, 0x25, 1), F3(~2, ~0x25, ~1)|(1<<12)|(0x7f<<5), "1,X,d", 0, v6 },
+{ "sra", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|(0x7f<<5), "1,2,d", 0, v6 },
+{ "sra", F3(2, 0x27, 1), F3(~2, ~0x27, ~1)|(1<<12)|(0x7f<<5), "1,X,d", 0, v6 },
+{ "srl", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|(0x7f<<5), "1,2,d", 0, v6 },
+{ "srl", F3(2, 0x26, 1), F3(~2, ~0x26, ~1)|(1<<12)|(0x7f<<5), "1,X,d", 0, v6 },
+
+{ "sllx", F3(2, 0x25, 0)|(1<<12), F3(~2, ~0x25, ~0)|(0x7f<<5), "1,2,d", 0, v9 },
+{ "sllx", F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1)|(0x3f<<6), "1,Y,d", 0, v9 },
+{ "srax", F3(2, 0x27, 0)|(1<<12), F3(~2, ~0x27, ~0)|(0x7f<<5), "1,2,d", 0, v9 },
+{ "srax", F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1)|(0x3f<<6), "1,Y,d", 0, v9 },
+{ "srlx", F3(2, 0x26, 0)|(1<<12), F3(~2, ~0x26, ~0)|(0x7f<<5), "1,2,d", 0, v9 },
+{ "srlx", F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1)|(0x3f<<6), "1,Y,d", 0, v9 },
+
+{ "mulscc", F3(2, 0x24, 0), F3(~2, ~0x24, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "mulscc", F3(2, 0x24, 1), F3(~2, ~0x24, ~1), "1,i,d", 0, v6 },
+
+{ "divscc", F3(2, 0x1d, 0), F3(~2, ~0x1d, ~0)|ASI(~0), "1,2,d", 0, sparclite },
+{ "divscc", F3(2, 0x1d, 1), F3(~2, ~0x1d, ~1), "1,i,d", 0, sparclite },
+
+{ "scan", F3(2, 0x2c, 0), F3(~2, ~0x2c, ~0)|ASI(~0), "1,2,d", 0, sparclet|sparclite },
+{ "scan", F3(2, 0x2c, 1), F3(~2, ~0x2c, ~1), "1,i,d", 0, sparclet|sparclite },
+
+{ "popc", F3(2, 0x2e, 0), F3(~2, ~0x2e, ~0)|RS2_G0|ASI(~0),"2,d", 0, v9 },
+{ "popc", F3(2, 0x2e, 1), F3(~2, ~0x2e, ~1)|RS2_G0, "i,d", 0, v9 },
+
+{ "clr", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|RD_G0|RS1_G0|ASI_RS2(~0), "d", F_ALIAS, v6 }, /* or %g0,%g0,d */
+{ "clr", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|RS1_G0|SIMM13(~0), "d", F_ALIAS, v6 }, /* or %g0,0,d */
+{ "clr", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v6 }, /* st %g0,[rs1+%g0] */
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0, "[1+i]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0, "[i+1]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v6 }, /* st %g0,[rs1+0] */
+
+{ "clrb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v6 }, /* stb %g0,[rs1+%g0] */
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0, "[1+i]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0, "[i+1]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v6 }, /* stb %g0,[rs1+0] */
+
+{ "clrh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v6 }, /* sth %g0,[rs1+%g0] */
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0, "[1+i]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0, "[i+1]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v6 }, /* sth %g0,[rs1+0] */
+
+{ "clrx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|RD_G0|ASI(~0), "[1+2]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|RD_G0|ASI_RS2(~0), "[1]", F_ALIAS, v9 }, /* stx %g0,[rs1+%g0] */
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0, "[1+i]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0, "[i+1]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0|RS1_G0, "[i]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0|SIMM13(~0), "[1]", F_ALIAS, v9 }, /* stx %g0,[rs1+0] */
+
+{ "orcc", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "orcc", F3(2, 0x12, 1), F3(~2, ~0x12, ~1), "1,i,d", 0, v6 },
+{ "orcc", F3(2, 0x12, 1), F3(~2, ~0x12, ~1), "i,1,d", 0, v6 },
+
+/* This is not a commutative instruction. */
+{ "orncc", F3(2, 0x16, 0), F3(~2, ~0x16, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "orncc", F3(2, 0x16, 1), F3(~2, ~0x16, ~1), "1,i,d", 0, v6 },
+
+/* This is not a commutative instruction. */
+{ "orn", F3(2, 0x06, 0), F3(~2, ~0x06, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "orn", F3(2, 0x06, 1), F3(~2, ~0x06, ~1), "1,i,d", 0, v6 },
+
+{ "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|ASI_RS2(~0), "1", 0, v6 }, /* orcc rs1, %g0, %g0 */
+{ "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|RS1_G0|ASI(~0), "2", 0, v6 }, /* orcc %g0, rs2, %g0 */
+{ "tst", F3(2, 0x12, 1), F3(~2, ~0x12, ~1)|RD_G0|SIMM13(~0), "1", 0, v6 }, /* orcc rs1, 0, %g0 */
+
+{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0), "1,2,m", 0, v8 }, /* wr r,r,%asrX */
+{ "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "1,i,m", 0, v8 }, /* wr r,i,%asrX */
+{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0), "1,m", F_ALIAS, v8 }, /* wr rs1,%g0,%asrX */
+{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0), "1,2,y", 0, v6 }, /* wr r,r,%y */
+{ "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "1,i,y", 0, v6 }, /* wr r,i,%y */
+{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI_RS2(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,%g0,%y */
+{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0), "1,2,p", 0, v6notv9 }, /* wr r,r,%psr */
+{ "wr", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "1,i,p", 0, v6notv9 }, /* wr r,i,%psr */
+{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI_RS2(~0), "1,p", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%psr */
+{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0), "1,2,w", 0, v6notv9 }, /* wr r,r,%wim */
+{ "wr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "1,i,w", 0, v6notv9 }, /* wr r,i,%wim */
+{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI_RS2(~0), "1,w", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%wim */
+{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0), "1,2,t", 0, v6notv9 }, /* wr r,r,%tbr */
+{ "wr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "1,i,t", 0, v6notv9 }, /* wr r,i,%tbr */
+{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI_RS2(~0), "1,t", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%tbr */
+
+{ "wr", F3(2, 0x30, 0)|RD(2), F3(~2, ~0x30, ~0)|RD(~2)|ASI(~0), "1,2,E", 0, v9 }, /* wr r,r,%ccr */
+{ "wr", F3(2, 0x30, 1)|RD(2), F3(~2, ~0x30, ~1)|RD(~2), "1,i,E", 0, v9 }, /* wr r,i,%ccr */
+{ "wr", F3(2, 0x30, 0)|RD(3), F3(~2, ~0x30, ~0)|RD(~3)|ASI(~0), "1,2,o", 0, v9 }, /* wr r,r,%asi */
+{ "wr", F3(2, 0x30, 1)|RD(3), F3(~2, ~0x30, ~1)|RD(~3), "1,i,o", 0, v9 }, /* wr r,i,%asi */
+{ "wr", F3(2, 0x30, 0)|RD(6), F3(~2, ~0x30, ~0)|RD(~6)|ASI(~0), "1,2,s", 0, v9 }, /* wr r,r,%fprs */
+{ "wr", F3(2, 0x30, 1)|RD(6), F3(~2, ~0x30, ~1)|RD(~6), "1,i,s", 0, v9 }, /* wr r,i,%fprs */
+
+{ "wr", F3(2, 0x30, 0)|RD(16), F3(~2, ~0x30, ~0)|RD(~16)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%pcr */
+{ "wr", F3(2, 0x30, 1)|RD(16), F3(~2, ~0x30, ~1)|RD(~16), "1,i,_", 0, v9a }, /* wr r,i,%pcr */
+{ "wr", F3(2, 0x30, 0)|RD(17), F3(~2, ~0x30, ~0)|RD(~17)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%pic */
+{ "wr", F3(2, 0x30, 1)|RD(17), F3(~2, ~0x30, ~1)|RD(~17), "1,i,_", 0, v9a }, /* wr r,i,%pic */
+{ "wr", F3(2, 0x30, 0)|RD(18), F3(~2, ~0x30, ~0)|RD(~18)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%dcr */
+{ "wr", F3(2, 0x30, 1)|RD(18), F3(~2, ~0x30, ~1)|RD(~18), "1,i,_", 0, v9a }, /* wr r,i,%dcr */
+{ "wr", F3(2, 0x30, 0)|RD(19), F3(~2, ~0x30, ~0)|RD(~19)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%gsr */
+{ "wr", F3(2, 0x30, 1)|RD(19), F3(~2, ~0x30, ~1)|RD(~19), "1,i,_", 0, v9a }, /* wr r,i,%gsr */
+{ "wr", F3(2, 0x30, 0)|RD(20), F3(~2, ~0x30, ~0)|RD(~20)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%set_softint */
+{ "wr", F3(2, 0x30, 1)|RD(20), F3(~2, ~0x30, ~1)|RD(~20), "1,i,_", 0, v9a }, /* wr r,i,%set_softint */
+{ "wr", F3(2, 0x30, 0)|RD(21), F3(~2, ~0x30, ~0)|RD(~21)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%clear_softint */
+{ "wr", F3(2, 0x30, 1)|RD(21), F3(~2, ~0x30, ~1)|RD(~21), "1,i,_", 0, v9a }, /* wr r,i,%clear_softint */
+{ "wr", F3(2, 0x30, 0)|RD(22), F3(~2, ~0x30, ~0)|RD(~22)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%softint */
+{ "wr", F3(2, 0x30, 1)|RD(22), F3(~2, ~0x30, ~1)|RD(~22), "1,i,_", 0, v9a }, /* wr r,i,%softint */
+{ "wr", F3(2, 0x30, 0)|RD(23), F3(~2, ~0x30, ~0)|RD(~23)|ASI(~0), "1,2,_", 0, v9a }, /* wr r,r,%tick_cmpr */
+{ "wr", F3(2, 0x30, 1)|RD(23), F3(~2, ~0x30, ~1)|RD(~23), "1,i,_", 0, v9a }, /* wr r,i,%tick_cmpr */
+
+{ "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0), "M,d", 0, v8 }, /* rd %asrX,r */
+{ "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0), "y,d", 0, v6 }, /* rd %y,r */
+{ "rd", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", 0, v6notv9 }, /* rd %psr,r */
+{ "rd", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", 0, v6notv9 }, /* rd %wim,r */
+{ "rd", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", 0, v6notv9 }, /* rd %tbr,r */
+
+{ "rd", F3(2, 0x28, 0)|RS1(2), F3(~2, ~0x28, ~0)|RS1(~2)|SIMM13(~0), "E,d", 0, v9 }, /* rd %ccr,r */
+{ "rd", F3(2, 0x28, 0)|RS1(3), F3(~2, ~0x28, ~0)|RS1(~3)|SIMM13(~0), "o,d", 0, v9 }, /* rd %asi,r */
+{ "rd", F3(2, 0x28, 0)|RS1(4), F3(~2, ~0x28, ~0)|RS1(~4)|SIMM13(~0), "W,d", 0, v9 }, /* rd %tick,r */
+{ "rd", F3(2, 0x28, 0)|RS1(5), F3(~2, ~0x28, ~0)|RS1(~5)|SIMM13(~0), "P,d", 0, v9 }, /* rd %pc,r */
+{ "rd", F3(2, 0x28, 0)|RS1(6), F3(~2, ~0x28, ~0)|RS1(~6)|SIMM13(~0), "s,d", 0, v9 }, /* rd %fprs,r */
+
+{ "rd", F3(2, 0x28, 0)|RS1(16), F3(~2, ~0x28, ~0)|RS1(~16)|SIMM13(~0), "/,d", 0, v9a }, /* rd %pcr,r */
+{ "rd", F3(2, 0x28, 0)|RS1(17), F3(~2, ~0x28, ~0)|RS1(~17)|SIMM13(~0), "/,d", 0, v9a }, /* rd %pic,r */
+{ "rd", F3(2, 0x28, 0)|RS1(18), F3(~2, ~0x28, ~0)|RS1(~18)|SIMM13(~0), "/,d", 0, v9a }, /* rd %dcr,r */
+{ "rd", F3(2, 0x28, 0)|RS1(19), F3(~2, ~0x28, ~0)|RS1(~19)|SIMM13(~0), "/,d", 0, v9a }, /* rd %gsr,r */
+{ "rd", F3(2, 0x28, 0)|RS1(22), F3(~2, ~0x28, ~0)|RS1(~22)|SIMM13(~0), "/,d", 0, v9a }, /* rd %softint,r */
+{ "rd", F3(2, 0x28, 0)|RS1(23), F3(~2, ~0x28, ~0)|RS1(~23)|SIMM13(~0), "/,d", 0, v9a }, /* rd %tick_cmpr,r */
+
+{ "rdpr", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|SIMM13(~0), "?,d", 0, v9 }, /* rdpr %priv,r */
+{ "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0), "1,2,!", 0, v9 }, /* wrpr r1,r2,%priv */
+{ "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|SIMM13(~0), "1,!", 0, v9 }, /* wrpr r1,%priv */
+{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1), "1,i,!", 0, v9 }, /* wrpr r1,i,%priv */
+{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1), "i,1,!", F_ALIAS, v9 }, /* wrpr i,r1,%priv */
+{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RS1(~0), "i,!", 0, v9 }, /* wrpr i,%priv */
+
+/* ??? This group seems wrong. A three operand move? */
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0), "1,2,m", F_ALIAS, v8 }, /* wr r,r,%asrX */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "1,i,m", F_ALIAS, v8 }, /* wr r,i,%asrX */
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0), "1,2,y", F_ALIAS, v6 }, /* wr r,r,%y */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "1,i,y", F_ALIAS, v6 }, /* wr r,i,%y */
+{ "mov", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0), "1,2,p", F_ALIAS, v6notv9 }, /* wr r,r,%psr */
+{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "1,i,p", F_ALIAS, v6notv9 }, /* wr r,i,%psr */
+{ "mov", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0), "1,2,w", F_ALIAS, v6notv9 }, /* wr r,r,%wim */
+{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "1,i,w", F_ALIAS, v6notv9 }, /* wr r,i,%wim */
+{ "mov", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0), "1,2,t", F_ALIAS, v6notv9 }, /* wr r,r,%tbr */
+{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "1,i,t", F_ALIAS, v6notv9 }, /* wr r,i,%tbr */
+
+{ "mov", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0), "M,d", F_ALIAS, v8 }, /* rd %asr1,r */
+{ "mov", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0), "y,d", F_ALIAS, v6 }, /* rd %y,r */
+{ "mov", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0), "p,d", F_ALIAS, v6notv9 }, /* rd %psr,r */
+{ "mov", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0), "w,d", F_ALIAS, v6notv9 }, /* rd %wim,r */
+{ "mov", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0), "t,d", F_ALIAS, v6notv9 }, /* rd %tbr,r */
+
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0), "1,m", F_ALIAS, v8 }, /* wr rs1,%g0,%asrX */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "i,m", F_ALIAS, v8 }, /* wr %g0,i,%asrX */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|SIMM13(~0), "1,m", F_ALIAS, v8 }, /* wr rs1,0,%asrX */
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI_RS2(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,%g0,%y */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0, "i,y", F_ALIAS, v6 }, /* wr %g0,i,%y */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0|SIMM13(~0), "1,y", F_ALIAS, v6 }, /* wr rs1,0,%y */
+{ "mov", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI_RS2(~0), "1,p", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%psr */
+{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0, "i,p", F_ALIAS, v6notv9 }, /* wr %g0,i,%psr */
+{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0|SIMM13(~0), "1,p", F_ALIAS, v6notv9 }, /* wr rs1,0,%psr */
+{ "mov", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI_RS2(~0), "1,w", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%wim */
+{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0, "i,w", F_ALIAS, v6notv9 }, /* wr %g0,i,%wim */
+{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0|SIMM13(~0), "1,w", F_ALIAS, v6notv9 }, /* wr rs1,0,%wim */
+{ "mov", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI_RS2(~0), "1,t", F_ALIAS, v6notv9 }, /* wr rs1,%g0,%tbr */
+{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0, "i,t", F_ALIAS, v6notv9 }, /* wr %g0,i,%tbr */
+{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0|SIMM13(~0), "1,t", F_ALIAS, v6notv9 }, /* wr rs1,0,%tbr */
+
+{ "mov", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|RS1_G0|ASI(~0), "2,d", 0, v6 }, /* or %g0,rs2,d */
+{ "mov", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|RS1_G0, "i,d", 0, v6 }, /* or %g0,i,d */
+{ "mov", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI_RS2(~0), "1,d", 0, v6 }, /* or rs1,%g0,d */
+{ "mov", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|SIMM13(~0), "1,d", 0, v6 }, /* or rs1,0,d */
+
+{ "or", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "or", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "1,i,d", 0, v6 },
+{ "or", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "i,1,d", 0, v6 },
+
+{ "bset", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI(~0), "2,r", F_ALIAS, v6 }, /* or rd,rs2,rd */
+{ "bset", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "i,r", F_ALIAS, v6 }, /* or rd,i,rd */
+
+/* This is not a commutative instruction. */
+{ "andn", F3(2, 0x05, 0), F3(~2, ~0x05, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "andn", F3(2, 0x05, 1), F3(~2, ~0x05, ~1), "1,i,d", 0, v6 },
+
+/* This is not a commutative instruction. */
+{ "andncc", F3(2, 0x15, 0), F3(~2, ~0x15, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "andncc", F3(2, 0x15, 1), F3(~2, ~0x15, ~1), "1,i,d", 0, v6 },
+
+{ "bclr", F3(2, 0x05, 0), F3(~2, ~0x05, ~0)|ASI(~0), "2,r", F_ALIAS, v6 }, /* andn rd,rs2,rd */
+{ "bclr", F3(2, 0x05, 1), F3(~2, ~0x05, ~1), "i,r", F_ALIAS, v6 }, /* andn rd,i,rd */
+
+{ "cmp", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|RD_G0|ASI(~0), "1,2", 0, v6 }, /* subcc rs1,rs2,%g0 */
+{ "cmp", F3(2, 0x14, 1), F3(~2, ~0x14, ~1)|RD_G0, "1,i", 0, v6 }, /* subcc rs1,i,%g0 */
+
+{ "sub", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "sub", F3(2, 0x04, 1), F3(~2, ~0x04, ~1), "1,i,d", 0, v6 },
+
+{ "subcc", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "subcc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "1,i,d", 0, v6 },
+
+{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
+{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v6notv9 },
+{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v9 },
+
+{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
+{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v6notv9 },
+{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v9 },
+
+{ "and", F3(2, 0x01, 0), F3(~2, ~0x01, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "1,i,d", 0, v6 },
+{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "i,1,d", 0, v6 },
+
+{ "andcc", F3(2, 0x11, 0), F3(~2, ~0x11, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "andcc", F3(2, 0x11, 1), F3(~2, ~0x11, ~1), "1,i,d", 0, v6 },
+{ "andcc", F3(2, 0x11, 1), F3(~2, ~0x11, ~1), "i,1,d", 0, v6 },
+
+{ "dec", F3(2, 0x04, 1)|SIMM13(0x1), F3(~2, ~0x04, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* sub rd,1,rd */
+{ "dec", F3(2, 0x04, 1), F3(~2, ~0x04, ~1), "i,r", F_ALIAS, v8 }, /* sub rd,imm,rd */
+{ "deccc", F3(2, 0x14, 1)|SIMM13(0x1), F3(~2, ~0x14, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* subcc rd,1,rd */
+{ "deccc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "i,r", F_ALIAS, v8 }, /* subcc rd,imm,rd */
+{ "inc", F3(2, 0x00, 1)|SIMM13(0x1), F3(~2, ~0x00, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* add rd,1,rd */
+{ "inc", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "i,r", F_ALIAS, v8 }, /* add rd,imm,rd */
+{ "inccc", F3(2, 0x10, 1)|SIMM13(0x1), F3(~2, ~0x10, ~1)|SIMM13(~0x0001), "r", F_ALIAS, v6 }, /* addcc rd,1,rd */
+{ "inccc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,r", F_ALIAS, v8 }, /* addcc rd,imm,rd */
+
+{ "btst", F3(2, 0x11, 0), F3(~2, ~0x11, ~0)|RD_G0|ASI(~0), "1,2", F_ALIAS, v6 }, /* andcc rs1,rs2,%g0 */
+{ "btst", F3(2, 0x11, 1), F3(~2, ~0x11, ~1)|RD_G0, "i,1", F_ALIAS, v6 }, /* andcc rs1,i,%g0 */
+
+{ "neg", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|RS1_G0|ASI(~0), "2,d", F_ALIAS, v6 }, /* sub %g0,rs2,rd */
+{ "neg", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|RS1_G0|ASI(~0), "O", F_ALIAS, v6 }, /* sub %g0,rd,rd */
+
+{ "add", F3(2, 0x00, 0), F3(~2, ~0x00, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "add", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "1,i,d", 0, v6 },
+{ "add", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "i,1,d", 0, v6 },
+{ "addcc", F3(2, 0x10, 0), F3(~2, ~0x10, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "1,i,d", 0, v6 },
+{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,1,d", 0, v6 },
+
+{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
+{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v6notv9 },
+{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v6notv9 },
+{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v9 },
+{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v9 },
+
+{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v6notv9 },
+{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v6notv9 },
+{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v6notv9 },
+{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v9 },
+{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v9 },
+
+{ "smul", F3(2, 0x0b, 0), F3(~2, ~0x0b, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "1,i,d", 0, v8 },
+{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "i,1,d", 0, v8 },
+{ "smulcc", F3(2, 0x1b, 0), F3(~2, ~0x1b, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "smulcc", F3(2, 0x1b, 1), F3(~2, ~0x1b, ~1), "1,i,d", 0, v8 },
+{ "smulcc", F3(2, 0x1b, 1), F3(~2, ~0x1b, ~1), "i,1,d", 0, v8 },
+{ "umul", F3(2, 0x0a, 0), F3(~2, ~0x0a, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "umul", F3(2, 0x0a, 1), F3(~2, ~0x0a, ~1), "1,i,d", 0, v8 },
+{ "umul", F3(2, 0x0a, 1), F3(~2, ~0x0a, ~1), "i,1,d", 0, v8 },
+{ "umulcc", F3(2, 0x1a, 0), F3(~2, ~0x1a, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "umulcc", F3(2, 0x1a, 1), F3(~2, ~0x1a, ~1), "1,i,d", 0, v8 },
+{ "umulcc", F3(2, 0x1a, 1), F3(~2, ~0x1a, ~1), "i,1,d", 0, v8 },
+{ "sdiv", F3(2, 0x0f, 0), F3(~2, ~0x0f, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "sdiv", F3(2, 0x0f, 1), F3(~2, ~0x0f, ~1), "1,i,d", 0, v8 },
+{ "sdiv", F3(2, 0x0f, 1), F3(~2, ~0x0f, ~1), "i,1,d", 0, v8 },
+{ "sdivcc", F3(2, 0x1f, 0), F3(~2, ~0x1f, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "sdivcc", F3(2, 0x1f, 1), F3(~2, ~0x1f, ~1), "1,i,d", 0, v8 },
+{ "sdivcc", F3(2, 0x1f, 1), F3(~2, ~0x1f, ~1), "i,1,d", 0, v8 },
+{ "udiv", F3(2, 0x0e, 0), F3(~2, ~0x0e, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "udiv", F3(2, 0x0e, 1), F3(~2, ~0x0e, ~1), "1,i,d", 0, v8 },
+{ "udiv", F3(2, 0x0e, 1), F3(~2, ~0x0e, ~1), "i,1,d", 0, v8 },
+{ "udivcc", F3(2, 0x1e, 0), F3(~2, ~0x1e, ~0)|ASI(~0), "1,2,d", 0, v8 },
+{ "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "1,i,d", 0, v8 },
+{ "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "i,1,d", 0, v8 },
+
+{ "mulx", F3(2, 0x09, 0), F3(~2, ~0x09, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "mulx", F3(2, 0x09, 1), F3(~2, ~0x09, ~1), "1,i,d", 0, v9 },
+{ "sdivx", F3(2, 0x2d, 0), F3(~2, ~0x2d, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "sdivx", F3(2, 0x2d, 1), F3(~2, ~0x2d, ~1), "1,i,d", 0, v9 },
+{ "udivx", F3(2, 0x0d, 0), F3(~2, ~0x0d, ~0)|ASI(~0), "1,2,d", 0, v9 },
+{ "udivx", F3(2, 0x0d, 1), F3(~2, ~0x0d, ~1), "1,i,d", 0, v9 },
+
+{ "call", F1(0x1), F1(~0x1), "L", F_JSR|F_DELAYED, v6 },
+{ "call", F1(0x1), F1(~0x1), "L,#", F_JSR|F_DELAYED, v6 },
+
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI(~0), "1+2", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+rs2,%o7 */
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI(~0), "1+2,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0), "1", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+%g0,%o7 */
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0), "1,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "1+i", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+i,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "1+i,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "i+1", F_JSR|F_DELAYED, v6 }, /* jmpl i+rs1,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), "i+1,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|RS1_G0, "i", F_JSR|F_DELAYED, v6 }, /* jmpl %g0+i,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|RS1_G0, "i,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|SIMM13(~0), "1", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+0,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|SIMM13(~0), "1,#", F_JSR|F_DELAYED, v6 },
+
+
+/* Conditional instructions.
+
+ Because this part of the table was such a mess earlier, I have
+ macrofied it so that all the branches and traps are generated from
+ a single-line description of each condition value. John Gilmore. */
+
+/* Define branches -- one annulled, one without, etc. */
+#define br(opcode, mask, lose, flags) \
+ { opcode, (mask)|ANNUL, (lose), ",a l", (flags), v6 }, \
+ { opcode, (mask) , (lose)|ANNUL, "l", (flags), v6 }
+
+#define brx(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask)|(2<<20)|BPRED, ANNUL|(lose), "Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|BPRED, ANNUL|(lose), ",T Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|BPRED|ANNUL, (lose), ",a Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|BPRED|ANNUL, (lose), ",a,T Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20), ANNUL|BPRED|(lose), ",N Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|ANNUL, BPRED|(lose), ",a,N Z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED, ANNUL|(lose)|(2<<20), "z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED, ANNUL|(lose)|(2<<20), ",T z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose)|(2<<20), ",a z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose)|(2<<20), ",a,T z,G", (flags), v9 }, \
+ { opcode, (mask), ANNUL|BPRED|(lose)|(2<<20), ",N z,G", (flags), v9 }, \
+ { opcode, (mask)|ANNUL, BPRED|(lose)|(2<<20), ",a,N z,G", (flags), v9 }
+
+/* Define four traps: reg+reg, reg + immediate, immediate alone, reg alone. */
+#define tr(opcode, mask, lose, flags) \
+ { opcode, (mask)|(2<<11)|IMMED, (lose)|RS1_G0, "Z,i", (flags), v9 }, /* %g0 + imm */ \
+ { opcode, (mask)|(2<<11)|IMMED, (lose), "Z,1+i", (flags), v9 }, /* rs1 + imm */ \
+ { opcode, (mask)|(2<<11), IMMED|(lose), "Z,1+2", (flags), v9 }, /* rs1 + rs2 */ \
+ { opcode, (mask)|(2<<11), IMMED|(lose)|RS2_G0, "Z,1", (flags), v9 }, /* rs1 + %g0 */ \
+ { opcode, (mask)|IMMED, (lose)|RS1_G0, "z,i", (flags)|F_ALIAS, v9 }, /* %g0 + imm */ \
+ { opcode, (mask)|IMMED, (lose), "z,1+i", (flags)|F_ALIAS, v9 }, /* rs1 + imm */ \
+ { opcode, (mask), IMMED|(lose), "z,1+2", (flags)|F_ALIAS, v9 }, /* rs1 + rs2 */ \
+ { opcode, (mask), IMMED|(lose)|RS2_G0, "z,1", (flags)|F_ALIAS, v9 }, /* rs1 + %g0 */ \
+ { opcode, (mask)|IMMED, (lose)|RS1_G0, "i", (flags), v6 }, /* %g0 + imm */ \
+ { opcode, (mask)|IMMED, (lose), "1+i", (flags), v6 }, /* rs1 + imm */ \
+ { opcode, (mask), IMMED|(lose), "1+2", (flags), v6 }, /* rs1 + rs2 */ \
+ { opcode, (mask), IMMED|(lose)|RS2_G0, "1", (flags), v6 } /* rs1 + %g0 */
+
+/* v9: We must put `brx' before `br', to ensure that we never match something
+ v9: against an expression unless it is an expression. Otherwise, we end
+ v9: up with undefined symbol tables entries, because they get added, but
+ v9: are not deleted if the pattern fails to match. */
+
+/* Define both branches and traps based on condition mask */
+#define cond(bop, top, mask, flags) \
+ brx(bop, F2(0, 1)|(mask), F2(~0, ~1)|((~mask)&COND(~0)), F_DELAYED|(flags)), /* v9 */ \
+ br(bop, F2(0, 2)|(mask), F2(~0, ~2)|((~mask)&COND(~0)), F_DELAYED|(flags)), \
+ tr(top, F3(2, 0x3a, 0)|(mask), F3(~2, ~0x3a, 0)|((~mask)&COND(~0)), ((flags) & ~(F_UNBR|F_CONDBR)))
+
+/* Define all the conditions, all the branches, all the traps. */
+
+/* Standard branch, trap mnemonics */
+cond ("b", "ta", CONDA, F_UNBR),
+/* Alternative form (just for assembly, not for disassembly) */
+cond ("ba", "t", CONDA, F_UNBR|F_ALIAS),
+
+cond ("bcc", "tcc", CONDCC, F_CONDBR),
+cond ("bcs", "tcs", CONDCS, F_CONDBR),
+cond ("be", "te", CONDE, F_CONDBR),
+cond ("beq", "teq", CONDE, F_CONDBR|F_ALIAS),
+cond ("bg", "tg", CONDG, F_CONDBR),
+cond ("bgt", "tgt", CONDG, F_CONDBR|F_ALIAS),
+cond ("bge", "tge", CONDGE, F_CONDBR),
+cond ("bgeu", "tgeu", CONDGEU, F_CONDBR|F_ALIAS), /* for cc */
+cond ("bgu", "tgu", CONDGU, F_CONDBR),
+cond ("bl", "tl", CONDL, F_CONDBR),
+cond ("blt", "tlt", CONDL, F_CONDBR|F_ALIAS),
+cond ("ble", "tle", CONDLE, F_CONDBR),
+cond ("bleu", "tleu", CONDLEU, F_CONDBR),
+cond ("blu", "tlu", CONDLU, F_CONDBR|F_ALIAS), /* for cs */
+cond ("bn", "tn", CONDN, F_CONDBR),
+cond ("bne", "tne", CONDNE, F_CONDBR),
+cond ("bneg", "tneg", CONDNEG, F_CONDBR),
+cond ("bnz", "tnz", CONDNZ, F_CONDBR|F_ALIAS), /* for ne */
+cond ("bpos", "tpos", CONDPOS, F_CONDBR),
+cond ("bvc", "tvc", CONDVC, F_CONDBR),
+cond ("bvs", "tvs", CONDVS, F_CONDBR),
+cond ("bz", "tz", CONDZ, F_CONDBR|F_ALIAS), /* for e */
+
+#undef cond
+#undef br
+#undef brr /* v9 */
+#undef tr
+
+#define brr(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask)|BPRED, ANNUL|(lose), "1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|BPRED, ANNUL|(lose), ",T 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose), ",a 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose), ",a,T 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask), ANNUL|BPRED|(lose), ",N 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|ANNUL, BPRED|(lose), ",a,N 1,k", F_DELAYED|(flags), v9 }
+
+#define condr(bop, mask, flags) /* v9 */ \
+ brr(bop, F2(0, 3)|COND(mask), F2(~0, ~3)|COND(~(mask)), (flags)) /* v9 */
+
+/* v9 */ condr("brnz", 0x5, F_CONDBR),
+/* v9 */ condr("brz", 0x1, F_CONDBR),
+/* v9 */ condr("brgez", 0x7, F_CONDBR),
+/* v9 */ condr("brlz", 0x3, F_CONDBR),
+/* v9 */ condr("brlez", 0x2, F_CONDBR),
+/* v9 */ condr("brgz", 0x6, F_CONDBR),
+
+#undef condr /* v9 */
+#undef brr /* v9 */
+
+#define movr(opcode, mask, flags) /* v9 */ \
+ { opcode, F3(2, 0x2f, 0)|RCOND(mask), F3(~2, ~0x2f, ~0)|RCOND(~(mask)), "1,2,d", (flags), v9 }, \
+ { opcode, F3(2, 0x2f, 1)|RCOND(mask), F3(~2, ~0x2f, ~1)|RCOND(~(mask)), "1,j,d", (flags), v9 }
+
+#define fmrrs(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask), (lose), "1,f,g", (flags) | F_FLOAT, v9 }
+#define fmrrd(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask), (lose), "1,B,H", (flags) | F_FLOAT, v9 }
+#define fmrrq(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask), (lose), "1,R,J", (flags) | F_FLOAT, v9 }
+
+#define fmovrs(mop, mask, flags) /* v9 */ \
+ fmrrs(mop, F3(2, 0x35, 0)|OPF_LOW5(5)|RCOND(mask), F3(~2, ~0x35, 0)|OPF_LOW5(~5)|RCOND(~(mask)), (flags)) /* v9 */
+#define fmovrd(mop, mask, flags) /* v9 */ \
+ fmrrd(mop, F3(2, 0x35, 0)|OPF_LOW5(6)|RCOND(mask), F3(~2, ~0x35, 0)|OPF_LOW5(~6)|RCOND(~(mask)), (flags)) /* v9 */
+#define fmovrq(mop, mask, flags) /* v9 */ \
+ fmrrq(mop, F3(2, 0x35, 0)|OPF_LOW5(7)|RCOND(mask), F3(~2, ~0x35, 0)|OPF_LOW5(~7)|RCOND(~(mask)), (flags)) /* v9 */
+
+/* v9 */ movr("movrne", 0x5, 0),
+/* v9 */ movr("movre", 0x1, 0),
+/* v9 */ movr("movrgez", 0x7, 0),
+/* v9 */ movr("movrlz", 0x3, 0),
+/* v9 */ movr("movrlez", 0x2, 0),
+/* v9 */ movr("movrgz", 0x6, 0),
+/* v9 */ movr("movrnz", 0x5, F_ALIAS),
+/* v9 */ movr("movrz", 0x1, F_ALIAS),
+
+/* v9 */ fmovrs("fmovrsne", 0x5, 0),
+/* v9 */ fmovrs("fmovrse", 0x1, 0),
+/* v9 */ fmovrs("fmovrsgez", 0x7, 0),
+/* v9 */ fmovrs("fmovrslz", 0x3, 0),
+/* v9 */ fmovrs("fmovrslez", 0x2, 0),
+/* v9 */ fmovrs("fmovrsgz", 0x6, 0),
+/* v9 */ fmovrs("fmovrsnz", 0x5, F_ALIAS),
+/* v9 */ fmovrs("fmovrsz", 0x1, F_ALIAS),
+
+/* v9 */ fmovrd("fmovrdne", 0x5, 0),
+/* v9 */ fmovrd("fmovrde", 0x1, 0),
+/* v9 */ fmovrd("fmovrdgez", 0x7, 0),
+/* v9 */ fmovrd("fmovrdlz", 0x3, 0),
+/* v9 */ fmovrd("fmovrdlez", 0x2, 0),
+/* v9 */ fmovrd("fmovrdgz", 0x6, 0),
+/* v9 */ fmovrd("fmovrdnz", 0x5, F_ALIAS),
+/* v9 */ fmovrd("fmovrdz", 0x1, F_ALIAS),
+
+/* v9 */ fmovrq("fmovrqne", 0x5, 0),
+/* v9 */ fmovrq("fmovrqe", 0x1, 0),
+/* v9 */ fmovrq("fmovrqgez", 0x7, 0),
+/* v9 */ fmovrq("fmovrqlz", 0x3, 0),
+/* v9 */ fmovrq("fmovrqlez", 0x2, 0),
+/* v9 */ fmovrq("fmovrqgz", 0x6, 0),
+/* v9 */ fmovrq("fmovrqnz", 0x5, F_ALIAS),
+/* v9 */ fmovrq("fmovrqz", 0x1, F_ALIAS),
+
+#undef movr /* v9 */
+#undef fmovr /* v9 */
+#undef fmrr /* v9 */
+
+#define movicc(opcode, cond, flags) /* v9 */ \
+ { opcode, F3(2, 0x2c, 0)|MCOND(cond,1)|ICC, F3(~2, ~0x2c, ~0)|MCOND(~cond,~1)|XCC|(1<<11), "z,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|MCOND(cond,1)|ICC, F3(~2, ~0x2c, ~1)|MCOND(~cond,~1)|XCC|(1<<11), "z,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|MCOND(cond,1)|XCC, F3(~2, ~0x2c, ~0)|MCOND(~cond,~1)|(1<<11), "Z,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|MCOND(cond,1)|XCC, F3(~2, ~0x2c, ~1)|MCOND(~cond,~1)|(1<<11), "Z,I,d", flags, v9 }
+
+#define movfcc(opcode, fcond, flags) /* v9 */ \
+ { opcode, F3(2, 0x2c, 0)|FCC(0)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~0)|F3(~2, ~0x2c, ~0), "6,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(0)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~0)|F3(~2, ~0x2c, ~1), "6,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|FCC(1)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~1)|F3(~2, ~0x2c, ~0), "7,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(1)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~1)|F3(~2, ~0x2c, ~1), "7,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|FCC(2)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~2)|F3(~2, ~0x2c, ~0), "8,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(2)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~2)|F3(~2, ~0x2c, ~1), "8,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|FCC(3)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~3)|F3(~2, ~0x2c, ~0), "9,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(3)|MCOND(fcond,0), MCOND(~fcond,~0)|FCC(~3)|F3(~2, ~0x2c, ~1), "9,I,d", flags, v9 }
+
+#define movcc(opcode, cond, fcond, flags) /* v9 */ \
+ movfcc (opcode, fcond, flags), /* v9 */ \
+ movicc (opcode, cond, flags) /* v9 */
+
+/* v9 */ movcc ("mova", CONDA, FCONDA, 0),
+/* v9 */ movicc ("movcc", CONDCC, 0),
+/* v9 */ movicc ("movgeu", CONDGEU, F_ALIAS),
+/* v9 */ movicc ("movcs", CONDCS, 0),
+/* v9 */ movicc ("movlu", CONDLU, F_ALIAS),
+/* v9 */ movcc ("move", CONDE, FCONDE, 0),
+/* v9 */ movcc ("movg", CONDG, FCONDG, 0),
+/* v9 */ movcc ("movge", CONDGE, FCONDGE, 0),
+/* v9 */ movicc ("movgu", CONDGU, 0),
+/* v9 */ movcc ("movl", CONDL, FCONDL, 0),
+/* v9 */ movcc ("movle", CONDLE, FCONDLE, 0),
+/* v9 */ movicc ("movleu", CONDLEU, 0),
+/* v9 */ movfcc ("movlg", FCONDLG, 0),
+/* v9 */ movcc ("movn", CONDN, FCONDN, 0),
+/* v9 */ movcc ("movne", CONDNE, FCONDNE, 0),
+/* v9 */ movicc ("movneg", CONDNEG, 0),
+/* v9 */ movcc ("movnz", CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ movfcc ("movo", FCONDO, 0),
+/* v9 */ movicc ("movpos", CONDPOS, 0),
+/* v9 */ movfcc ("movu", FCONDU, 0),
+/* v9 */ movfcc ("movue", FCONDUE, 0),
+/* v9 */ movfcc ("movug", FCONDUG, 0),
+/* v9 */ movfcc ("movuge", FCONDUGE, 0),
+/* v9 */ movfcc ("movul", FCONDUL, 0),
+/* v9 */ movfcc ("movule", FCONDULE, 0),
+/* v9 */ movicc ("movvc", CONDVC, 0),
+/* v9 */ movicc ("movvs", CONDVS, 0),
+/* v9 */ movcc ("movz", CONDZ, FCONDZ, F_ALIAS),
+
+#undef movicc /* v9 */
+#undef movfcc /* v9 */
+#undef movcc /* v9 */
+
+#define FM_SF 1 /* v9 - values for fpsize */
+#define FM_DF 2 /* v9 */
+#define FM_QF 3 /* v9 */
+
+#define fmovicc(opcode, fpsize, cond, flags) /* v9 */ \
+{ opcode, F3F(2, 0x35, 0x100+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x100+fpsize))|MCOND(~cond,~0), "z,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x180+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x180+fpsize))|MCOND(~cond,~0), "Z,f,g", flags, v9 }
+
+#define fmovfcc(opcode, fpsize, fcond, flags) /* v9 */ \
+{ opcode, F3F(2, 0x35, 0x000+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x000+fpsize))|MCOND(~fcond,~0), "6,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x040+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x040+fpsize))|MCOND(~fcond,~0), "7,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x080+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x080+fpsize))|MCOND(~fcond,~0), "8,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x0c0+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x0c0+fpsize))|MCOND(~fcond,~0), "9,f,g", flags, v9 }
+
+/* FIXME: use fmovicc/fmovfcc? */ /* v9 */
+#define fmovcc(opcode, fpsize, cond, fcond, flags) /* v9 */ \
+{ opcode, F3F(2, 0x35, 0x100+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x100+fpsize))|MCOND(~cond,~0), "z,f,g", flags | F_FLOAT, v9 }, \
+{ opcode, F3F(2, 0x35, 0x000+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x000+fpsize))|MCOND(~fcond,~0), "6,f,g", flags | F_FLOAT, v9 }, \
+{ opcode, F3F(2, 0x35, 0x180+fpsize)|MCOND(cond,0), F3F(~2, ~0x35, ~(0x180+fpsize))|MCOND(~cond,~0), "Z,f,g", flags | F_FLOAT, v9 }, \
+{ opcode, F3F(2, 0x35, 0x040+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x040+fpsize))|MCOND(~fcond,~0), "7,f,g", flags | F_FLOAT, v9 }, \
+{ opcode, F3F(2, 0x35, 0x080+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x080+fpsize))|MCOND(~fcond,~0), "8,f,g", flags | F_FLOAT, v9 }, \
+{ opcode, F3F(2, 0x35, 0x0c0+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35, ~(0x0c0+fpsize))|MCOND(~fcond,~0), "9,f,g", flags | F_FLOAT, v9 }
+
+/* v9 */ fmovcc ("fmovda", FM_DF, CONDA, FCONDA, 0),
+/* v9 */ fmovcc ("fmovqa", FM_QF, CONDA, FCONDA, 0),
+/* v9 */ fmovcc ("fmovsa", FM_SF, CONDA, FCONDA, 0),
+/* v9 */ fmovicc ("fmovdcc", FM_DF, CONDCC, 0),
+/* v9 */ fmovicc ("fmovqcc", FM_QF, CONDCC, 0),
+/* v9 */ fmovicc ("fmovscc", FM_SF, CONDCC, 0),
+/* v9 */ fmovicc ("fmovdcs", FM_DF, CONDCS, 0),
+/* v9 */ fmovicc ("fmovqcs", FM_QF, CONDCS, 0),
+/* v9 */ fmovicc ("fmovscs", FM_SF, CONDCS, 0),
+/* v9 */ fmovcc ("fmovde", FM_DF, CONDE, FCONDE, 0),
+/* v9 */ fmovcc ("fmovqe", FM_QF, CONDE, FCONDE, 0),
+/* v9 */ fmovcc ("fmovse", FM_SF, CONDE, FCONDE, 0),
+/* v9 */ fmovcc ("fmovdg", FM_DF, CONDG, FCONDG, 0),
+/* v9 */ fmovcc ("fmovqg", FM_QF, CONDG, FCONDG, 0),
+/* v9 */ fmovcc ("fmovsg", FM_SF, CONDG, FCONDG, 0),
+/* v9 */ fmovcc ("fmovdge", FM_DF, CONDGE, FCONDGE, 0),
+/* v9 */ fmovcc ("fmovqge", FM_QF, CONDGE, FCONDGE, 0),
+/* v9 */ fmovcc ("fmovsge", FM_SF, CONDGE, FCONDGE, 0),
+/* v9 */ fmovicc ("fmovdgeu", FM_DF, CONDGEU, F_ALIAS),
+/* v9 */ fmovicc ("fmovqgeu", FM_QF, CONDGEU, F_ALIAS),
+/* v9 */ fmovicc ("fmovsgeu", FM_SF, CONDGEU, F_ALIAS),
+/* v9 */ fmovicc ("fmovdgu", FM_DF, CONDGU, 0),
+/* v9 */ fmovicc ("fmovqgu", FM_QF, CONDGU, 0),
+/* v9 */ fmovicc ("fmovsgu", FM_SF, CONDGU, 0),
+/* v9 */ fmovcc ("fmovdl", FM_DF, CONDL, FCONDL, 0),
+/* v9 */ fmovcc ("fmovql", FM_QF, CONDL, FCONDL, 0),
+/* v9 */ fmovcc ("fmovsl", FM_SF, CONDL, FCONDL, 0),
+/* v9 */ fmovcc ("fmovdle", FM_DF, CONDLE, FCONDLE, 0),
+/* v9 */ fmovcc ("fmovqle", FM_QF, CONDLE, FCONDLE, 0),
+/* v9 */ fmovcc ("fmovsle", FM_SF, CONDLE, FCONDLE, 0),
+/* v9 */ fmovicc ("fmovdleu", FM_DF, CONDLEU, 0),
+/* v9 */ fmovicc ("fmovqleu", FM_QF, CONDLEU, 0),
+/* v9 */ fmovicc ("fmovsleu", FM_SF, CONDLEU, 0),
+/* v9 */ fmovfcc ("fmovdlg", FM_DF, FCONDLG, 0),
+/* v9 */ fmovfcc ("fmovqlg", FM_QF, FCONDLG, 0),
+/* v9 */ fmovfcc ("fmovslg", FM_SF, FCONDLG, 0),
+/* v9 */ fmovicc ("fmovdlu", FM_DF, CONDLU, F_ALIAS),
+/* v9 */ fmovicc ("fmovqlu", FM_QF, CONDLU, F_ALIAS),
+/* v9 */ fmovicc ("fmovslu", FM_SF, CONDLU, F_ALIAS),
+/* v9 */ fmovcc ("fmovdn", FM_DF, CONDN, FCONDN, 0),
+/* v9 */ fmovcc ("fmovqn", FM_QF, CONDN, FCONDN, 0),
+/* v9 */ fmovcc ("fmovsn", FM_SF, CONDN, FCONDN, 0),
+/* v9 */ fmovcc ("fmovdne", FM_DF, CONDNE, FCONDNE, 0),
+/* v9 */ fmovcc ("fmovqne", FM_QF, CONDNE, FCONDNE, 0),
+/* v9 */ fmovcc ("fmovsne", FM_SF, CONDNE, FCONDNE, 0),
+/* v9 */ fmovicc ("fmovdneg", FM_DF, CONDNEG, 0),
+/* v9 */ fmovicc ("fmovqneg", FM_QF, CONDNEG, 0),
+/* v9 */ fmovicc ("fmovsneg", FM_SF, CONDNEG, 0),
+/* v9 */ fmovcc ("fmovdnz", FM_DF, CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovqnz", FM_QF, CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovsnz", FM_SF, CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ fmovfcc ("fmovdo", FM_DF, FCONDO, 0),
+/* v9 */ fmovfcc ("fmovqo", FM_QF, FCONDO, 0),
+/* v9 */ fmovfcc ("fmovso", FM_SF, FCONDO, 0),
+/* v9 */ fmovicc ("fmovdpos", FM_DF, CONDPOS, 0),
+/* v9 */ fmovicc ("fmovqpos", FM_QF, CONDPOS, 0),
+/* v9 */ fmovicc ("fmovspos", FM_SF, CONDPOS, 0),
+/* v9 */ fmovfcc ("fmovdu", FM_DF, FCONDU, 0),
+/* v9 */ fmovfcc ("fmovqu", FM_QF, FCONDU, 0),
+/* v9 */ fmovfcc ("fmovsu", FM_SF, FCONDU, 0),
+/* v9 */ fmovfcc ("fmovdue", FM_DF, FCONDUE, 0),
+/* v9 */ fmovfcc ("fmovque", FM_QF, FCONDUE, 0),
+/* v9 */ fmovfcc ("fmovsue", FM_SF, FCONDUE, 0),
+/* v9 */ fmovfcc ("fmovdug", FM_DF, FCONDUG, 0),
+/* v9 */ fmovfcc ("fmovqug", FM_QF, FCONDUG, 0),
+/* v9 */ fmovfcc ("fmovsug", FM_SF, FCONDUG, 0),
+/* v9 */ fmovfcc ("fmovduge", FM_DF, FCONDUGE, 0),
+/* v9 */ fmovfcc ("fmovquge", FM_QF, FCONDUGE, 0),
+/* v9 */ fmovfcc ("fmovsuge", FM_SF, FCONDUGE, 0),
+/* v9 */ fmovfcc ("fmovdul", FM_DF, FCONDUL, 0),
+/* v9 */ fmovfcc ("fmovqul", FM_QF, FCONDUL, 0),
+/* v9 */ fmovfcc ("fmovsul", FM_SF, FCONDUL, 0),
+/* v9 */ fmovfcc ("fmovdule", FM_DF, FCONDULE, 0),
+/* v9 */ fmovfcc ("fmovqule", FM_QF, FCONDULE, 0),
+/* v9 */ fmovfcc ("fmovsule", FM_SF, FCONDULE, 0),
+/* v9 */ fmovicc ("fmovdvc", FM_DF, CONDVC, 0),
+/* v9 */ fmovicc ("fmovqvc", FM_QF, CONDVC, 0),
+/* v9 */ fmovicc ("fmovsvc", FM_SF, CONDVC, 0),
+/* v9 */ fmovicc ("fmovdvs", FM_DF, CONDVS, 0),
+/* v9 */ fmovicc ("fmovqvs", FM_QF, CONDVS, 0),
+/* v9 */ fmovicc ("fmovsvs", FM_SF, CONDVS, 0),
+/* v9 */ fmovcc ("fmovdz", FM_DF, CONDZ, FCONDZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovqz", FM_QF, CONDZ, FCONDZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovsz", FM_SF, CONDZ, FCONDZ, F_ALIAS),
+
+#undef fmovicc /* v9 */
+#undef fmovfcc /* v9 */
+#undef fmovcc /* v9 */
+#undef FM_DF /* v9 */
+#undef FM_QF /* v9 */
+#undef FM_SF /* v9 */
+
+/* Coprocessor branches. */
+#define CBR(opcode, mask, lose, flags, arch) \
+ { opcode, (mask), ANNUL|(lose), "l", flags|F_DELAYED, arch }, \
+ { opcode, (mask)|ANNUL, (lose), ",a l", flags|F_DELAYED, arch }
+
+/* Floating point branches. */
+#define FBR(opcode, mask, lose, flags) \
+ { opcode, (mask), ANNUL|(lose), "l", flags|F_DELAYED|F_FBR, v6 }, \
+ { opcode, (mask)|ANNUL, (lose), ",a l", flags|F_DELAYED|F_FBR, v6 }
+
+/* V9 extended floating point branches. */
+#define FBRX(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, FBFCC(0)|(mask)|BPRED, ANNUL|FBFCC(~0)|(lose), "6,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(0)|(mask)|BPRED, ANNUL|FBFCC(~0)|(lose), ",T 6,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(0)|(mask)|BPRED|ANNUL, FBFCC(~0)|(lose), ",a 6,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(0)|(mask)|BPRED|ANNUL, FBFCC(~0)|(lose), ",a,T 6,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(0)|(mask), ANNUL|BPRED|FBFCC(~0)|(lose), ",N 6,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(0)|(mask)|ANNUL, BPRED|FBFCC(~0)|(lose), ",a,N 6,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED, ANNUL|FBFCC(~1)|(lose), "7,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED, ANNUL|FBFCC(~1)|(lose), ",T 7,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED|ANNUL, FBFCC(~1)|(lose), ",a 7,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED|ANNUL, FBFCC(~1)|(lose), ",a,T 7,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(1)|(mask), ANNUL|BPRED|FBFCC(~1)|(lose), ",N 7,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(1)|(mask)|ANNUL, BPRED|FBFCC(~1)|(lose), ",a,N 7,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED, ANNUL|FBFCC(~2)|(lose), "8,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED, ANNUL|FBFCC(~2)|(lose), ",T 8,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED|ANNUL, FBFCC(~2)|(lose), ",a 8,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED|ANNUL, FBFCC(~2)|(lose), ",a,T 8,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(2)|(mask), ANNUL|BPRED|FBFCC(~2)|(lose), ",N 8,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(2)|(mask)|ANNUL, BPRED|FBFCC(~2)|(lose), ",a,N 8,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED, ANNUL|FBFCC(~3)|(lose), "9,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED, ANNUL|FBFCC(~3)|(lose), ",T 9,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED|ANNUL, FBFCC(~3)|(lose), ",a 9,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED|ANNUL, FBFCC(~3)|(lose), ",a,T 9,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(3)|(mask), ANNUL|BPRED|FBFCC(~3)|(lose), ",N 9,G", flags|F_DELAYED|F_FBR, v9 }, \
+ { opcode, FBFCC(3)|(mask)|ANNUL, BPRED|FBFCC(~3)|(lose), ",a,N 9,G", flags|F_DELAYED|F_FBR, v9 }
+
+/* v9: We must put `FBRX' before `FBR', to ensure that we never match
+ v9: something against an expression unless it is an expression. Otherwise,
+ v9: we end up with undefined symbol tables entries, because they get added,
+ v9: but are not deleted if the pattern fails to match. */
+
+#define CONDFC(fop, cop, mask, flags) \
+ FBRX(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \
+ FBR(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags), \
+ CBR(cop, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)), flags, v6notlet)
+
+#define CONDFCL(fop, cop, mask, flags) \
+ FBRX(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \
+ FBR(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags), \
+ CBR(cop, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)), flags, v6)
+
+#define CONDF(fop, mask, flags) \
+ FBRX(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \
+ FBR(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags)
+
+CONDFC ("fb", "cb", 0x8, 0),
+CONDFCL ("fba", "cba", 0x8, F_ALIAS),
+CONDFC ("fbe", "cb0", 0x9, 0),
+CONDF ("fbz", 0x9, F_ALIAS),
+CONDFC ("fbg", "cb2", 0x6, 0),
+CONDFC ("fbge", "cb02", 0xb, 0),
+CONDFC ("fbl", "cb1", 0x4, 0),
+CONDFC ("fble", "cb01", 0xd, 0),
+CONDFC ("fblg", "cb12", 0x2, 0),
+CONDFCL ("fbn", "cbn", 0x0, 0),
+CONDFC ("fbne", "cb123", 0x1, 0),
+CONDF ("fbnz", 0x1, F_ALIAS),
+CONDFC ("fbo", "cb012", 0xf, 0),
+CONDFC ("fbu", "cb3", 0x7, 0),
+CONDFC ("fbue", "cb03", 0xa, 0),
+CONDFC ("fbug", "cb23", 0x5, 0),
+CONDFC ("fbuge", "cb023", 0xc, 0),
+CONDFC ("fbul", "cb13", 0x3, 0),
+CONDFC ("fbule", "cb013", 0xe, 0),
+
+#undef CONDFC
+#undef CONDFCL
+#undef CONDF
+#undef CBR
+#undef FBR
+#undef FBRX /* v9 */
+
+{ "jmp", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|RD_G0|ASI(~0), "1+2", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+rs2,%g0 */
+{ "jmp", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|RD_G0|ASI_RS2(~0), "1", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+%g0,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0, "1+i", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+i,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0, "i+1", F_UNBR|F_DELAYED, v6 }, /* jmpl i+rs1,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0|RS1_G0, "i", F_UNBR|F_DELAYED, v6 }, /* jmpl %g0+i,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0|SIMM13(~0), "1", F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+0,%g0 */
+
+{ "nop", F2(0, 4), 0xfeffffff, "", 0, v6 }, /* sethi 0, %g0 */
+
+{ "set", F2(0x0, 0x4), F2(~0x0, ~0x4), "Sh,d", F_ALIAS, v6 },
+{ "setuw", F2(0x0, 0x4), F2(~0x0, ~0x4), "Sh,d", F_ALIAS, v9 },
+{ "setsw", F2(0x0, 0x4), F2(~0x0, ~0x4), "Sh,d", F_ALIAS, v9 },
+{ "setx", F2(0x0, 0x4), F2(~0x0, ~0x4), "S0,1,d", F_ALIAS, v9 },
+
+{ "sethi", F2(0x0, 0x4), F2(~0x0, ~0x4), "h,d", 0, v6 },
+
+{ "taddcc", F3(2, 0x20, 0), F3(~2, ~0x20, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "taddcc", F3(2, 0x20, 1), F3(~2, ~0x20, ~1), "1,i,d", 0, v6 },
+{ "taddcc", F3(2, 0x20, 1), F3(~2, ~0x20, ~1), "i,1,d", 0, v6 },
+{ "taddcctv", F3(2, 0x22, 0), F3(~2, ~0x22, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "taddcctv", F3(2, 0x22, 1), F3(~2, ~0x22, ~1), "1,i,d", 0, v6 },
+{ "taddcctv", F3(2, 0x22, 1), F3(~2, ~0x22, ~1), "i,1,d", 0, v6 },
+
+{ "tsubcc", F3(2, 0x21, 0), F3(~2, ~0x21, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "tsubcc", F3(2, 0x21, 1), F3(~2, ~0x21, ~1), "1,i,d", 0, v6 },
+{ "tsubcctv", F3(2, 0x23, 0), F3(~2, ~0x23, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "tsubcctv", F3(2, 0x23, 1), F3(~2, ~0x23, ~1), "1,i,d", 0, v6 },
+
+{ "unimp", F2(0x0, 0x0), 0xffc00000, "n", 0, v6notv9 },
+{ "illtrap", F2(0, 0), F2(~0, ~0)|RD_G0, "n", 0, v9 },
+
+/* This *is* a commutative instruction. */
+{ "xnor", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "xnor", F3(2, 0x07, 1), F3(~2, ~0x07, ~1), "1,i,d", 0, v6 },
+{ "xnor", F3(2, 0x07, 1), F3(~2, ~0x07, ~1), "i,1,d", 0, v6 },
+/* This *is* a commutative instruction. */
+{ "xnorcc", F3(2, 0x17, 0), F3(~2, ~0x17, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "xnorcc", F3(2, 0x17, 1), F3(~2, ~0x17, ~1), "1,i,d", 0, v6 },
+{ "xnorcc", F3(2, 0x17, 1), F3(~2, ~0x17, ~1), "i,1,d", 0, v6 },
+{ "xor", F3(2, 0x03, 0), F3(~2, ~0x03, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "xor", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "1,i,d", 0, v6 },
+{ "xor", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "i,1,d", 0, v6 },
+{ "xorcc", F3(2, 0x13, 0), F3(~2, ~0x13, ~0)|ASI(~0), "1,2,d", 0, v6 },
+{ "xorcc", F3(2, 0x13, 1), F3(~2, ~0x13, ~1), "1,i,d", 0, v6 },
+{ "xorcc", F3(2, 0x13, 1), F3(~2, ~0x13, ~1), "i,1,d", 0, v6 },
+
+{ "not", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "1,d", F_ALIAS, v6 }, /* xnor rs1,%0,rd */
+{ "not", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "r", F_ALIAS, v6 }, /* xnor rd,%0,rd */
+
+{ "btog", F3(2, 0x03, 0), F3(~2, ~0x03, ~0)|ASI(~0), "2,r", F_ALIAS, v6 }, /* xor rd,rs2,rd */
+{ "btog", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "i,r", F_ALIAS, v6 }, /* xor rd,i,rd */
+
+/* FPop1 and FPop2 are not instructions. Don't accept them. */
+
+{ "fdtoi", F3F(2, 0x34, 0x0d2), F3F(~2, ~0x34, ~0x0d2)|RS1_G0, "B,g", F_FLOAT, v6 },
+{ "fstoi", F3F(2, 0x34, 0x0d1), F3F(~2, ~0x34, ~0x0d1)|RS1_G0, "f,g", F_FLOAT, v6 },
+{ "fqtoi", F3F(2, 0x34, 0x0d3), F3F(~2, ~0x34, ~0x0d3)|RS1_G0, "R,g", F_FLOAT, v8 },
+
+{ "fdtox", F3F(2, 0x34, 0x082), F3F(~2, ~0x34, ~0x082)|RS1_G0, "B,g", F_FLOAT, v9 },
+{ "fstox", F3F(2, 0x34, 0x081), F3F(~2, ~0x34, ~0x081)|RS1_G0, "f,g", F_FLOAT, v9 },
+{ "fqtox", F3F(2, 0x34, 0x083), F3F(~2, ~0x34, ~0x083)|RS1_G0, "R,g", F_FLOAT, v9 },
+
+{ "fitod", F3F(2, 0x34, 0x0c8), F3F(~2, ~0x34, ~0x0c8)|RS1_G0, "f,H", F_FLOAT, v6 },
+{ "fitos", F3F(2, 0x34, 0x0c4), F3F(~2, ~0x34, ~0x0c4)|RS1_G0, "f,g", F_FLOAT, v6 },
+{ "fitoq", F3F(2, 0x34, 0x0cc), F3F(~2, ~0x34, ~0x0cc)|RS1_G0, "f,J", F_FLOAT, v8 },
+
+{ "fxtod", F3F(2, 0x34, 0x088), F3F(~2, ~0x34, ~0x088)|RS1_G0, "f,H", F_FLOAT, v9 },
+{ "fxtos", F3F(2, 0x34, 0x084), F3F(~2, ~0x34, ~0x084)|RS1_G0, "f,g", F_FLOAT, v9 },
+{ "fxtoq", F3F(2, 0x34, 0x08c), F3F(~2, ~0x34, ~0x08c)|RS1_G0, "f,J", F_FLOAT, v9 },
+
+{ "fdtoq", F3F(2, 0x34, 0x0ce), F3F(~2, ~0x34, ~0x0ce)|RS1_G0, "B,J", F_FLOAT, v8 },
+{ "fdtos", F3F(2, 0x34, 0x0c6), F3F(~2, ~0x34, ~0x0c6)|RS1_G0, "B,g", F_FLOAT, v6 },
+{ "fqtod", F3F(2, 0x34, 0x0cb), F3F(~2, ~0x34, ~0x0cb)|RS1_G0, "R,H", F_FLOAT, v8 },
+{ "fqtos", F3F(2, 0x34, 0x0c7), F3F(~2, ~0x34, ~0x0c7)|RS1_G0, "R,g", F_FLOAT, v8 },
+{ "fstod", F3F(2, 0x34, 0x0c9), F3F(~2, ~0x34, ~0x0c9)|RS1_G0, "f,H", F_FLOAT, v6 },
+{ "fstoq", F3F(2, 0x34, 0x0cd), F3F(~2, ~0x34, ~0x0cd)|RS1_G0, "f,J", F_FLOAT, v8 },
+
+{ "fdivd", F3F(2, 0x34, 0x04e), F3F(~2, ~0x34, ~0x04e), "v,B,H", F_FLOAT, v6 },
+{ "fdivq", F3F(2, 0x34, 0x04f), F3F(~2, ~0x34, ~0x04f), "V,R,J", F_FLOAT, v8 },
+{ "fdivs", F3F(2, 0x34, 0x04d), F3F(~2, ~0x34, ~0x04d), "e,f,g", F_FLOAT, v6 },
+{ "fmuld", F3F(2, 0x34, 0x04a), F3F(~2, ~0x34, ~0x04a), "v,B,H", F_FLOAT, v6 },
+{ "fmulq", F3F(2, 0x34, 0x04b), F3F(~2, ~0x34, ~0x04b), "V,R,J", F_FLOAT, v8 },
+{ "fmuls", F3F(2, 0x34, 0x049), F3F(~2, ~0x34, ~0x049), "e,f,g", F_FLOAT, v6 },
+
+{ "fdmulq", F3F(2, 0x34, 0x06e), F3F(~2, ~0x34, ~0x06e), "v,B,J", F_FLOAT, v8 },
+{ "fsmuld", F3F(2, 0x34, 0x069), F3F(~2, ~0x34, ~0x069), "e,f,H", F_FLOAT, v8 },
+
+{ "fsqrtd", F3F(2, 0x34, 0x02a), F3F(~2, ~0x34, ~0x02a)|RS1_G0, "B,H", F_FLOAT, v7 },
+{ "fsqrtq", F3F(2, 0x34, 0x02b), F3F(~2, ~0x34, ~0x02b)|RS1_G0, "R,J", F_FLOAT, v8 },
+{ "fsqrts", F3F(2, 0x34, 0x029), F3F(~2, ~0x34, ~0x029)|RS1_G0, "f,g", F_FLOAT, v7 },
+
+{ "fabsd", F3F(2, 0x34, 0x00a), F3F(~2, ~0x34, ~0x00a)|RS1_G0, "B,H", F_FLOAT, v9 },
+{ "fabsq", F3F(2, 0x34, 0x00b), F3F(~2, ~0x34, ~0x00b)|RS1_G0, "R,J", F_FLOAT, v9 },
+{ "fabss", F3F(2, 0x34, 0x009), F3F(~2, ~0x34, ~0x009)|RS1_G0, "f,g", F_FLOAT, v6 },
+{ "fmovd", F3F(2, 0x34, 0x002), F3F(~2, ~0x34, ~0x002)|RS1_G0, "B,H", F_FLOAT, v9 },
+{ "fmovq", F3F(2, 0x34, 0x003), F3F(~2, ~0x34, ~0x003)|RS1_G0, "R,J", F_FLOAT, v9 },
+{ "fmovs", F3F(2, 0x34, 0x001), F3F(~2, ~0x34, ~0x001)|RS1_G0, "f,g", F_FLOAT, v6 },
+{ "fnegd", F3F(2, 0x34, 0x006), F3F(~2, ~0x34, ~0x006)|RS1_G0, "B,H", F_FLOAT, v9 },
+{ "fnegq", F3F(2, 0x34, 0x007), F3F(~2, ~0x34, ~0x007)|RS1_G0, "R,J", F_FLOAT, v9 },
+{ "fnegs", F3F(2, 0x34, 0x005), F3F(~2, ~0x34, ~0x005)|RS1_G0, "f,g", F_FLOAT, v6 },
+
+{ "faddd", F3F(2, 0x34, 0x042), F3F(~2, ~0x34, ~0x042), "v,B,H", F_FLOAT, v6 },
+{ "faddq", F3F(2, 0x34, 0x043), F3F(~2, ~0x34, ~0x043), "V,R,J", F_FLOAT, v8 },
+{ "fadds", F3F(2, 0x34, 0x041), F3F(~2, ~0x34, ~0x041), "e,f,g", F_FLOAT, v6 },
+{ "fsubd", F3F(2, 0x34, 0x046), F3F(~2, ~0x34, ~0x046), "v,B,H", F_FLOAT, v6 },
+{ "fsubq", F3F(2, 0x34, 0x047), F3F(~2, ~0x34, ~0x047), "V,R,J", F_FLOAT, v8 },
+{ "fsubs", F3F(2, 0x34, 0x045), F3F(~2, ~0x34, ~0x045), "e,f,g", F_FLOAT, v6 },
+
+#define CMPFCC(x) (((x)&0x3)<<25)
+
+{ "fcmpd", F3F(2, 0x35, 0x052), F3F(~2, ~0x35, ~0x052)|RD_G0, "v,B", F_FLOAT, v6 },
+{ "fcmpd", CMPFCC(0)|F3F(2, 0x35, 0x052), CMPFCC(~0)|F3F(~2, ~0x35, ~0x052), "6,v,B", F_FLOAT, v9 },
+{ "fcmpd", CMPFCC(1)|F3F(2, 0x35, 0x052), CMPFCC(~1)|F3F(~2, ~0x35, ~0x052), "7,v,B", F_FLOAT, v9 },
+{ "fcmpd", CMPFCC(2)|F3F(2, 0x35, 0x052), CMPFCC(~2)|F3F(~2, ~0x35, ~0x052), "8,v,B", F_FLOAT, v9 },
+{ "fcmpd", CMPFCC(3)|F3F(2, 0x35, 0x052), CMPFCC(~3)|F3F(~2, ~0x35, ~0x052), "9,v,B", F_FLOAT, v9 },
+{ "fcmped", F3F(2, 0x35, 0x056), F3F(~2, ~0x35, ~0x056)|RD_G0, "v,B", F_FLOAT, v6 },
+{ "fcmped", CMPFCC(0)|F3F(2, 0x35, 0x056), CMPFCC(~0)|F3F(~2, ~0x35, ~0x056), "6,v,B", F_FLOAT, v9 },
+{ "fcmped", CMPFCC(1)|F3F(2, 0x35, 0x056), CMPFCC(~1)|F3F(~2, ~0x35, ~0x056), "7,v,B", F_FLOAT, v9 },
+{ "fcmped", CMPFCC(2)|F3F(2, 0x35, 0x056), CMPFCC(~2)|F3F(~2, ~0x35, ~0x056), "8,v,B", F_FLOAT, v9 },
+{ "fcmped", CMPFCC(3)|F3F(2, 0x35, 0x056), CMPFCC(~3)|F3F(~2, ~0x35, ~0x056), "9,v,B", F_FLOAT, v9 },
+{ "fcmpq", F3F(2, 0x35, 0x053), F3F(~2, ~0x35, ~0x053)|RD_G0, "V,R", F_FLOAT, v8 },
+{ "fcmpq", CMPFCC(0)|F3F(2, 0x35, 0x053), CMPFCC(~0)|F3F(~2, ~0x35, ~0x053), "6,V,R", F_FLOAT, v9 },
+{ "fcmpq", CMPFCC(1)|F3F(2, 0x35, 0x053), CMPFCC(~1)|F3F(~2, ~0x35, ~0x053), "7,V,R", F_FLOAT, v9 },
+{ "fcmpq", CMPFCC(2)|F3F(2, 0x35, 0x053), CMPFCC(~2)|F3F(~2, ~0x35, ~0x053), "8,V,R", F_FLOAT, v9 },
+{ "fcmpq", CMPFCC(3)|F3F(2, 0x35, 0x053), CMPFCC(~3)|F3F(~2, ~0x35, ~0x053), "9,V,R", F_FLOAT, v9 },
+{ "fcmpeq", F3F(2, 0x35, 0x057), F3F(~2, ~0x35, ~0x057)|RD_G0, "V,R", F_FLOAT, v8 },
+{ "fcmpeq", CMPFCC(0)|F3F(2, 0x35, 0x057), CMPFCC(~0)|F3F(~2, ~0x35, ~0x057), "6,V,R", F_FLOAT, v9 },
+{ "fcmpeq", CMPFCC(1)|F3F(2, 0x35, 0x057), CMPFCC(~1)|F3F(~2, ~0x35, ~0x057), "7,V,R", F_FLOAT, v9 },
+{ "fcmpeq", CMPFCC(2)|F3F(2, 0x35, 0x057), CMPFCC(~2)|F3F(~2, ~0x35, ~0x057), "8,V,R", F_FLOAT, v9 },
+{ "fcmpeq", CMPFCC(3)|F3F(2, 0x35, 0x057), CMPFCC(~3)|F3F(~2, ~0x35, ~0x057), "9,V,R", F_FLOAT, v9 },
+{ "fcmps", F3F(2, 0x35, 0x051), F3F(~2, ~0x35, ~0x051)|RD_G0, "e,f", F_FLOAT, v6 },
+{ "fcmps", CMPFCC(0)|F3F(2, 0x35, 0x051), CMPFCC(~0)|F3F(~2, ~0x35, ~0x051), "6,e,f", F_FLOAT, v9 },
+{ "fcmps", CMPFCC(1)|F3F(2, 0x35, 0x051), CMPFCC(~1)|F3F(~2, ~0x35, ~0x051), "7,e,f", F_FLOAT, v9 },
+{ "fcmps", CMPFCC(2)|F3F(2, 0x35, 0x051), CMPFCC(~2)|F3F(~2, ~0x35, ~0x051), "8,e,f", F_FLOAT, v9 },
+{ "fcmps", CMPFCC(3)|F3F(2, 0x35, 0x051), CMPFCC(~3)|F3F(~2, ~0x35, ~0x051), "9,e,f", F_FLOAT, v9 },
+{ "fcmpes", F3F(2, 0x35, 0x055), F3F(~2, ~0x35, ~0x055)|RD_G0, "e,f", F_FLOAT, v6 },
+{ "fcmpes", CMPFCC(0)|F3F(2, 0x35, 0x055), CMPFCC(~0)|F3F(~2, ~0x35, ~0x055), "6,e,f", F_FLOAT, v9 },
+{ "fcmpes", CMPFCC(1)|F3F(2, 0x35, 0x055), CMPFCC(~1)|F3F(~2, ~0x35, ~0x055), "7,e,f", F_FLOAT, v9 },
+{ "fcmpes", CMPFCC(2)|F3F(2, 0x35, 0x055), CMPFCC(~2)|F3F(~2, ~0x35, ~0x055), "8,e,f", F_FLOAT, v9 },
+{ "fcmpes", CMPFCC(3)|F3F(2, 0x35, 0x055), CMPFCC(~3)|F3F(~2, ~0x35, ~0x055), "9,e,f", F_FLOAT, v9 },
+
+/* These Extended FPop (FIFO) instructions are new in the Fujitsu
+ MB86934, replacing the CPop instructions from v6 and later
+ processors. */
+
+#define EFPOP1_2(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op)|RS1_G0, args, 0, sparclite }
+#define EFPOP1_3(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36, ~op), args, 0, sparclite }
+#define EFPOP2_2(name, op, args) { name, F3F(2, 0x37, op), F3F(~2, ~0x37, ~op)|RD_G0, args, 0, sparclite }
+
+EFPOP1_2 ("efitod", 0x0c8, "f,H"),
+EFPOP1_2 ("efitos", 0x0c4, "f,g"),
+EFPOP1_2 ("efdtoi", 0x0d2, "B,g"),
+EFPOP1_2 ("efstoi", 0x0d1, "f,g"),
+EFPOP1_2 ("efstod", 0x0c9, "f,H"),
+EFPOP1_2 ("efdtos", 0x0c6, "B,g"),
+EFPOP1_2 ("efmovs", 0x001, "f,g"),
+EFPOP1_2 ("efnegs", 0x005, "f,g"),
+EFPOP1_2 ("efabss", 0x009, "f,g"),
+EFPOP1_2 ("efsqrtd", 0x02a, "B,H"),
+EFPOP1_2 ("efsqrts", 0x029, "f,g"),
+EFPOP1_3 ("efaddd", 0x042, "v,B,H"),
+EFPOP1_3 ("efadds", 0x041, "e,f,g"),
+EFPOP1_3 ("efsubd", 0x046, "v,B,H"),
+EFPOP1_3 ("efsubs", 0x045, "e,f,g"),
+EFPOP1_3 ("efdivd", 0x04e, "v,B,H"),
+EFPOP1_3 ("efdivs", 0x04d, "e,f,g"),
+EFPOP1_3 ("efmuld", 0x04a, "v,B,H"),
+EFPOP1_3 ("efmuls", 0x049, "e,f,g"),
+EFPOP1_3 ("efsmuld", 0x069, "e,f,H"),
+EFPOP2_2 ("efcmpd", 0x052, "v,B"),
+EFPOP2_2 ("efcmped", 0x056, "v,B"),
+EFPOP2_2 ("efcmps", 0x051, "e,f"),
+EFPOP2_2 ("efcmpes", 0x055, "e,f"),
+
+#undef EFPOP1_2
+#undef EFPOP1_3
+#undef EFPOP2_2
+
+/* These are marked F_ALIAS, so that they won't conflict with sparclite insns
+ present. Otherwise, the F_ALIAS flag is ignored. */
+{ "cpop1", F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS, v6notv9 },
+{ "cpop2", F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS, v6notv9 },
+
+/* sparclet specific insns */
+
+COMMUTEOP ("umac", 0x3e, sparclet),
+COMMUTEOP ("smac", 0x3f, sparclet),
+COMMUTEOP ("umacd", 0x2e, sparclet),
+COMMUTEOP ("smacd", 0x2f, sparclet),
+COMMUTEOP ("umuld", 0x09, sparclet),
+COMMUTEOP ("smuld", 0x0d, sparclet),
+
+{ "shuffle", F3(2, 0x2d, 0), F3(~2, ~0x2d, ~0)|ASI(~0), "1,2,d", 0, sparclet },
+{ "shuffle", F3(2, 0x2d, 1), F3(~2, ~0x2d, ~1), "1,i,d", 0, sparclet },
+
+/* The manual isn't completely accurate on these insns. The `rs2' field is
+ treated as being 6 bits to account for 6 bit immediates to cpush. It is
+ assumed that it is intended that bit 5 is 0 when rs2 contains a reg. */
+#define BIT5 (1<<5)
+{ "crdcxt", F3(2, 0x36, 0)|SLCPOP(4), F3(~2, ~0x36, ~0)|SLCPOP(~4)|BIT5|RS2(~0), "U,d", 0, sparclet },
+{ "cwrcxt", F3(2, 0x36, 0)|SLCPOP(3), F3(~2, ~0x36, ~0)|SLCPOP(~3)|BIT5|RS2(~0), "1,u", 0, sparclet },
+{ "cpush", F3(2, 0x36, 0)|SLCPOP(0), F3(~2, ~0x36, ~0)|SLCPOP(~0)|BIT5|RD(~0), "1,2", 0, sparclet },
+{ "cpush", F3(2, 0x36, 1)|SLCPOP(0), F3(~2, ~0x36, ~1)|SLCPOP(~0)|RD(~0), "1,Y", 0, sparclet },
+{ "cpusha", F3(2, 0x36, 0)|SLCPOP(1), F3(~2, ~0x36, ~0)|SLCPOP(~1)|BIT5|RD(~0), "1,2", 0, sparclet },
+{ "cpusha", F3(2, 0x36, 1)|SLCPOP(1), F3(~2, ~0x36, ~1)|SLCPOP(~1)|RD(~0), "1,Y", 0, sparclet },
+{ "cpull", F3(2, 0x36, 0)|SLCPOP(2), F3(~2, ~0x36, ~0)|SLCPOP(~2)|BIT5|RS1(~0)|RS2(~0), "d", 0, sparclet },
+#undef BIT5
+
+/* sparclet coprocessor branch insns */
+#define SLCBCC2(opcode, mask, lose) \
+ { opcode, (mask), ANNUL|(lose), "l", F_DELAYED|F_CONDBR, sparclet }, \
+ { opcode, (mask)|ANNUL, (lose), ",a l", F_DELAYED|F_CONDBR, sparclet }
+#define SLCBCC(opcode, mask) \
+ SLCBCC2(opcode, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)))
+
+/* cbn,cba can't be defined here because they're defined elsewhere and GAS
+ requires all mnemonics of the same name to be consecutive. */
+/*SLCBCC("cbn", 0), - already defined */
+SLCBCC("cbe", 1),
+SLCBCC("cbf", 2),
+SLCBCC("cbef", 3),
+SLCBCC("cbr", 4),
+SLCBCC("cber", 5),
+SLCBCC("cbfr", 6),
+SLCBCC("cbefr", 7),
+/*SLCBCC("cba", 8), - already defined */
+SLCBCC("cbne", 9),
+SLCBCC("cbnf", 10),
+SLCBCC("cbnef", 11),
+SLCBCC("cbnr", 12),
+SLCBCC("cbner", 13),
+SLCBCC("cbnfr", 14),
+SLCBCC("cbnefr", 15),
+
+#undef SLCBCC2
+#undef SLCBCC
+
+{ "casa", F3(3, 0x3c, 0), F3(~3, ~0x3c, ~0), "[1]A,2,d", 0, v9 },
+{ "casa", F3(3, 0x3c, 1), F3(~3, ~0x3c, ~1), "[1]o,2,d", 0, v9 },
+{ "casxa", F3(3, 0x3e, 0), F3(~3, ~0x3e, ~0), "[1]A,2,d", 0, v9 },
+{ "casxa", F3(3, 0x3e, 1), F3(~3, ~0x3e, ~1), "[1]o,2,d", 0, v9 },
+
+/* v9 synthetic insns */
+/* FIXME: still missing "signx d", and "clruw d". Can't be done here. */
+{ "iprefetch", F2(0, 1)|(2<<20)|BPRED, F2(~0, ~1)|(1<<20)|ANNUL|COND(~0), "G", 0, v9 }, /* bn,a,pt %xcc,label */
+{ "signx", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0)|RS2_G0, "1,d", F_ALIAS, v9 }, /* sra rs1,%g0,rd */
+{ "clruw", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0)|RS2_G0, "1,d", F_ALIAS, v9 }, /* srl rs1,%g0,rd */
+{ "cas", F3(3, 0x3c, 0)|ASI(0x80), F3(~3, ~0x3c, ~0)|ASI(~0x80), "[1],2,d", F_ALIAS, v9 }, /* casa [rs1]ASI_P,rs2,rd */
+{ "casl", F3(3, 0x3c, 0)|ASI(0x88), F3(~3, ~0x3c, ~0)|ASI(~0x88), "[1],2,d", F_ALIAS, v9 }, /* casa [rs1]ASI_P_L,rs2,rd */
+{ "casx", F3(3, 0x3e, 0)|ASI(0x80), F3(~3, ~0x3e, ~0)|ASI(~0x80), "[1],2,d", F_ALIAS, v9 }, /* casxa [rs1]ASI_P,rs2,rd */
+{ "casxl", F3(3, 0x3e, 0)|ASI(0x88), F3(~3, ~0x3e, ~0)|ASI(~0x88), "[1],2,d", F_ALIAS, v9 }, /* casxa [rs1]ASI_P_L,rs2,rd */
+
+/* Ultrasparc extensions */
+{ "shutdown", F3F(2, 0x36, 0x080), F3F(~2, ~0x36, ~0x080)|RD_G0|RS1_G0|RS2_G0, "", 0, v9a },
+
+/* FIXME: Do we want to mark these as F_FLOAT, or something similar? */
+{ "fpadd16", F3F(2, 0x36, 0x050), F3F(~2, ~0x36, ~0x050), "v,B,H", 0, v9a },
+{ "fpadd16s", F3F(2, 0x36, 0x051), F3F(~2, ~0x36, ~0x051), "e,f,g", 0, v9a },
+{ "fpadd32", F3F(2, 0x36, 0x052), F3F(~2, ~0x36, ~0x052), "v,B,H", 0, v9a },
+{ "fpadd32s", F3F(2, 0x36, 0x053), F3F(~2, ~0x36, ~0x053), "e,f,g", 0, v9a },
+{ "fpsub16", F3F(2, 0x36, 0x054), F3F(~2, ~0x36, ~0x054), "v,B,H", 0, v9a },
+{ "fpsub16s", F3F(2, 0x36, 0x055), F3F(~2, ~0x36, ~0x055), "e,f,g", 0, v9a },
+{ "fpsub32", F3F(2, 0x36, 0x056), F3F(~2, ~0x36, ~0x056), "v,B,H", 0, v9a },
+{ "fpsub32s", F3F(2, 0x36, 0x057), F3F(~2, ~0x36, ~0x057), "e,f,g", 0, v9a },
+
+{ "fpack32", F3F(2, 0x36, 0x03a), F3F(~2, ~0x36, ~0x03a), "v,B,H", 0, v9a },
+{ "fpack16", F3F(2, 0x36, 0x03b), F3F(~2, ~0x36, ~0x03b)|RS1_G0, "B,g", 0, v9a },
+{ "fpackfix", F3F(2, 0x36, 0x03d), F3F(~2, ~0x36, ~0x03d)|RS1_G0, "B,g", 0, v9a },
+{ "fexpand", F3F(2, 0x36, 0x04d), F3F(~2, ~0x36, ~0x04d)|RS1_G0, "f,H", 0, v9a },
+{ "fpmerge", F3F(2, 0x36, 0x04b), F3F(~2, ~0x36, ~0x04b), "e,f,H", 0, v9a },
+
+/* Note that the mixing of 32/64 bit regs is intentional. */
+{ "fmul8x16", F3F(2, 0x36, 0x031), F3F(~2, ~0x36, ~0x031), "e,B,H", 0, v9a },
+{ "fmul8x16au", F3F(2, 0x36, 0x033), F3F(~2, ~0x36, ~0x033), "e,f,H", 0, v9a },
+{ "fmul8x16al", F3F(2, 0x36, 0x035), F3F(~2, ~0x36, ~0x035), "e,f,H", 0, v9a },
+{ "fmul8sux16", F3F(2, 0x36, 0x036), F3F(~2, ~0x36, ~0x036), "v,B,H", 0, v9a },
+{ "fmul8ulx16", F3F(2, 0x36, 0x037), F3F(~2, ~0x36, ~0x037), "v,B,H", 0, v9a },
+{ "fmuld8sux16", F3F(2, 0x36, 0x038), F3F(~2, ~0x36, ~0x038), "e,f,H", 0, v9a },
+{ "fmuld8ulx16", F3F(2, 0x36, 0x039), F3F(~2, ~0x36, ~0x039), "e,f,H", 0, v9a },
+
+{ "alignaddr", F3F(2, 0x36, 0x018), F3F(~2, ~0x36, ~0x018), "1,2,d", 0, v9a },
+{ "alignaddrl", F3F(2, 0x36, 0x01a), F3F(~2, ~0x36, ~0x01a), "1,2,d", 0, v9a },
+{ "faligndata", F3F(2, 0x36, 0x048), F3F(~2, ~0x36, ~0x048), "v,B,H", 0, v9a },
+
+{ "fzero", F3F(2, 0x36, 0x060), F3F(~2, ~0x36, ~0x060), "H", 0, v9a },
+{ "fzeros", F3F(2, 0x36, 0x061), F3F(~2, ~0x36, ~0x061), "g", 0, v9a },
+{ "fone", F3F(2, 0x36, 0x07e), F3F(~2, ~0x36, ~0x07e), "H", 0, v9a },
+{ "fones", F3F(2, 0x36, 0x07f), F3F(~2, ~0x36, ~0x07f), "g", 0, v9a },
+{ "fsrc1", F3F(2, 0x36, 0x074), F3F(~2, ~0x36, ~0x074), "v,H", 0, v9a },
+{ "fsrc1s", F3F(2, 0x36, 0x075), F3F(~2, ~0x36, ~0x075), "e,g", 0, v9a },
+{ "fsrc2", F3F(2, 0x36, 0x078), F3F(~2, ~0x36, ~0x078), "B,H", 0, v9a },
+{ "fsrc2s", F3F(2, 0x36, 0x079), F3F(~2, ~0x36, ~0x079), "f,g", 0, v9a },
+{ "fnot1", F3F(2, 0x36, 0x06a), F3F(~2, ~0x36, ~0x06a), "v,H", 0, v9a },
+{ "fnot1s", F3F(2, 0x36, 0x06b), F3F(~2, ~0x36, ~0x06b), "e,g", 0, v9a },
+{ "fnot2", F3F(2, 0x36, 0x066), F3F(~2, ~0x36, ~0x066), "B,H", 0, v9a },
+{ "fnot2s", F3F(2, 0x36, 0x067), F3F(~2, ~0x36, ~0x067), "f,g", 0, v9a },
+{ "for", F3F(2, 0x36, 0x07c), F3F(~2, ~0x36, ~0x07c), "v,B,H", 0, v9a },
+{ "fors", F3F(2, 0x36, 0x07d), F3F(~2, ~0x36, ~0x07d), "e,f,g", 0, v9a },
+{ "fnor", F3F(2, 0x36, 0x062), F3F(~2, ~0x36, ~0x062), "v,B,H", 0, v9a },
+{ "fnors", F3F(2, 0x36, 0x063), F3F(~2, ~0x36, ~0x063), "e,f,g", 0, v9a },
+{ "fand", F3F(2, 0x36, 0x070), F3F(~2, ~0x36, ~0x070), "v,B,H", 0, v9a },
+{ "fands", F3F(2, 0x36, 0x071), F3F(~2, ~0x36, ~0x071), "e,f,g", 0, v9a },
+{ "fnand", F3F(2, 0x36, 0x06e), F3F(~2, ~0x36, ~0x06e), "v,B,H", 0, v9a },
+{ "fnands", F3F(2, 0x36, 0x06f), F3F(~2, ~0x36, ~0x06f), "e,f,g", 0, v9a },
+{ "fxor", F3F(2, 0x36, 0x06c), F3F(~2, ~0x36, ~0x06c), "v,B,H", 0, v9a },
+{ "fxors", F3F(2, 0x36, 0x06d), F3F(~2, ~0x36, ~0x06d), "e,f,g", 0, v9a },
+{ "fxnor", F3F(2, 0x36, 0x072), F3F(~2, ~0x36, ~0x072), "v,B,H", 0, v9a },
+{ "fxnors", F3F(2, 0x36, 0x073), F3F(~2, ~0x36, ~0x073), "e,f,g", 0, v9a },
+{ "fornot1", F3F(2, 0x36, 0x07a), F3F(~2, ~0x36, ~0x07a), "v,B,H", 0, v9a },
+{ "fornot1s", F3F(2, 0x36, 0x07b), F3F(~2, ~0x36, ~0x07b), "e,f,g", 0, v9a },
+{ "fornot2", F3F(2, 0x36, 0x076), F3F(~2, ~0x36, ~0x076), "v,B,H", 0, v9a },
+{ "fornot2s", F3F(2, 0x36, 0x077), F3F(~2, ~0x36, ~0x077), "e,f,g", 0, v9a },
+{ "fandnot1", F3F(2, 0x36, 0x068), F3F(~2, ~0x36, ~0x068), "v,B,H", 0, v9a },
+{ "fandnot1s", F3F(2, 0x36, 0x069), F3F(~2, ~0x36, ~0x069), "e,f,g", 0, v9a },
+{ "fandnot2", F3F(2, 0x36, 0x064), F3F(~2, ~0x36, ~0x064), "v,B,H", 0, v9a },
+{ "fandnot2s", F3F(2, 0x36, 0x065), F3F(~2, ~0x36, ~0x065), "e,f,g", 0, v9a },
+
+{ "fcmpgt16", F3F(2, 0x36, 0x028), F3F(~2, ~0x36, ~0x028), "v,B,d", 0, v9a },
+{ "fcmpgt32", F3F(2, 0x36, 0x02c), F3F(~2, ~0x36, ~0x02c), "v,B,d", 0, v9a },
+{ "fcmple16", F3F(2, 0x36, 0x020), F3F(~2, ~0x36, ~0x020), "v,B,d", 0, v9a },
+{ "fcmple32", F3F(2, 0x36, 0x024), F3F(~2, ~0x36, ~0x024), "v,B,d", 0, v9a },
+{ "fcmpne16", F3F(2, 0x36, 0x022), F3F(~2, ~0x36, ~0x022), "v,B,d", 0, v9a },
+{ "fcmpne32", F3F(2, 0x36, 0x026), F3F(~2, ~0x36, ~0x026), "v,B,d", 0, v9a },
+{ "fcmpeq16", F3F(2, 0x36, 0x02a), F3F(~2, ~0x36, ~0x02a), "v,B,d", 0, v9a },
+{ "fcmpeq32", F3F(2, 0x36, 0x02e), F3F(~2, ~0x36, ~0x02e), "v,B,d", 0, v9a },
+
+{ "edge8", F3F(2, 0x36, 0x000), F3F(~2, ~0x36, ~0x000), "1,2,d", 0, v9a },
+{ "edge8l", F3F(2, 0x36, 0x002), F3F(~2, ~0x36, ~0x002), "1,2,d", 0, v9a },
+{ "edge16", F3F(2, 0x36, 0x004), F3F(~2, ~0x36, ~0x004), "1,2,d", 0, v9a },
+{ "edge16l", F3F(2, 0x36, 0x006), F3F(~2, ~0x36, ~0x006), "1,2,d", 0, v9a },
+{ "edge32", F3F(2, 0x36, 0x008), F3F(~2, ~0x36, ~0x008), "1,2,d", 0, v9a },
+{ "edge32l", F3F(2, 0x36, 0x00a), F3F(~2, ~0x36, ~0x00a), "1,2,d", 0, v9a },
+
+{ "pdist", F3F(2, 0x36, 0x03e), F3F(~2, ~0x36, ~0x03e), "v,B,H", 0, v9a },
+
+{ "array8", F3F(2, 0x36, 0x010), F3F(~2, ~0x36, ~0x010), "1,2,d", 0, v9a },
+{ "array16", F3F(2, 0x36, 0x012), F3F(~2, ~0x36, ~0x012), "1,2,d", 0, v9a },
+{ "array32", F3F(2, 0x36, 0x014), F3F(~2, ~0x36, ~0x014), "1,2,d", 0, v9a },
+
+/* More v9 specific insns, these need to come last so they do not clash
+ with v9a instructions such as "edge8" which looks like impdep1. */
+
+#define IMPDEP(name, code) \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0)|ASI(~0), "1,2,d", 0, v9notv9a }, \
+{ name, F3(2, code, 1), F3(~2, ~code, ~1), "1,i,d", 0, v9notv9a }, \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,1,2,d", 0, v9notv9a }, \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,e,f,g", 0, v9notv9a }
+
+IMPDEP ("impdep1", 0x36),
+IMPDEP ("impdep2", 0x37),
+
+#undef IMPDEP
+
+};
+
+const int sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof sparc_opcodes[0]));
+
+/* Utilities for argument parsing. */
+
+typedef struct
+{
+ int value;
+ const char *name;
+} arg;
+
+/* Look up NAME in TABLE. */
+
+static int lookup_name PARAMS ((const arg *, const char *));
+static const char *lookup_value PARAMS ((const arg *, int));
+
+static int
+lookup_name (table, name)
+ const arg *table;
+ const char *name;
+{
+ const arg *p;
+
+ for (p = table; p->name; ++p)
+ if (strcmp (name, p->name) == 0)
+ return p->value;
+
+ return -1;
+}
+
+/* Look up VALUE in TABLE. */
+
+static const char *
+lookup_value (table, value)
+ const arg *table;
+ int value;
+{
+ const arg *p;
+
+ for (p = table; p->name; ++p)
+ if (value == p->value)
+ return p->name;
+
+ return (char *) 0;
+}
+
+/* Handle ASI's. */
+
+static arg asi_table[] =
+{
+ /* These are in the v9 architecture manual. */
+ /* The shorter versions appear first, they're here because Sun's as has them.
+ Sun's as uses #ASI_P_L instead of #ASI_PL (which appears in the
+ UltraSPARC architecture manual). */
+ { 0x04, "#ASI_N" },
+ { 0x0c, "#ASI_N_L" },
+ { 0x10, "#ASI_AIUP" },
+ { 0x11, "#ASI_AIUS" },
+ { 0x18, "#ASI_AIUP_L" },
+ { 0x19, "#ASI_AIUS_L" },
+ { 0x80, "#ASI_P" },
+ { 0x81, "#ASI_S" },
+ { 0x82, "#ASI_PNF" },
+ { 0x83, "#ASI_SNF" },
+ { 0x88, "#ASI_P_L" },
+ { 0x89, "#ASI_S_L" },
+ { 0x8a, "#ASI_PNF_L" },
+ { 0x8b, "#ASI_SNF_L" },
+ { 0x04, "#ASI_NUCLEUS" },
+ { 0x0c, "#ASI_NUCLEUS_LITTLE" },
+ { 0x10, "#ASI_AS_IF_USER_PRIMARY" },
+ { 0x11, "#ASI_AS_IF_USER_SECONDARY" },
+ { 0x18, "#ASI_AS_IF_USER_PRIMARY_LITTLE" },
+ { 0x19, "#ASI_AS_IF_USER_SECONDARY_LITTLE" },
+ { 0x80, "#ASI_PRIMARY" },
+ { 0x81, "#ASI_SECONDARY" },
+ { 0x82, "#ASI_PRIMARY_NOFAULT" },
+ { 0x83, "#ASI_SECONDARY_NOFAULT" },
+ { 0x88, "#ASI_PRIMARY_LITTLE" },
+ { 0x89, "#ASI_SECONDARY_LITTLE" },
+ { 0x8a, "#ASI_PRIMARY_NOFAULT_LITTLE" },
+ { 0x8b, "#ASI_SECONDARY_NOFAULT_LITTLE" },
+ /* These are UltraSPARC extensions. */
+ /* FIXME: There are dozens of them. Not sure we want them all.
+ Most are for kernel building but some are for vis type stuff. */
+ { 0, 0 }
+};
+
+/* Return the value for ASI NAME, or -1 if not found. */
+
+int
+sparc_encode_asi (name)
+ const char *name;
+{
+ return lookup_name (asi_table, name);
+}
+
+/* Return the name for ASI value VALUE or NULL if not found. */
+
+const char *
+sparc_decode_asi (value)
+ int value;
+{
+ return lookup_value (asi_table, value);
+}
+
+/* Handle membar masks. */
+
+static arg membar_table[] =
+{
+ { 0x40, "#Sync" },
+ { 0x20, "#MemIssue" },
+ { 0x10, "#Lookaside" },
+ { 0x08, "#StoreStore" },
+ { 0x04, "#LoadStore" },
+ { 0x02, "#StoreLoad" },
+ { 0x01, "#LoadLoad" },
+ { 0, 0 }
+};
+
+/* Return the value for membar arg NAME, or -1 if not found. */
+
+int
+sparc_encode_membar (name)
+ const char *name;
+{
+ return lookup_name (membar_table, name);
+}
+
+/* Return the name for membar value VALUE or NULL if not found. */
+
+const char *
+sparc_decode_membar (value)
+ int value;
+{
+ return lookup_value (membar_table, value);
+}
+
+/* Handle prefetch args. */
+
+static arg prefetch_table[] =
+{
+ { 0, "#n_reads" },
+ { 1, "#one_read" },
+ { 2, "#n_writes" },
+ { 3, "#one_write" },
+ { 4, "#page" },
+ { 0, 0 }
+};
+
+/* Return the value for prefetch arg NAME, or -1 if not found. */
+
+int
+sparc_encode_prefetch (name)
+ const char *name;
+{
+ return lookup_name (prefetch_table, name);
+}
+
+/* Return the name for prefetch value VALUE or NULL if not found. */
+
+const char *
+sparc_decode_prefetch (value)
+ int value;
+{
+ return lookup_value (prefetch_table, value);
+}
+
+/* Handle sparclet coprocessor registers. */
+
+static arg sparclet_cpreg_table[] =
+{
+ { 0, "%ccsr" },
+ { 1, "%ccfr" },
+ { 2, "%cccrcr" },
+ { 3, "%ccpr" },
+ { 4, "%ccsr2" },
+ { 5, "%cccrr" },
+ { 6, "%ccrstr" },
+ { 0, 0 }
+};
+
+/* Return the value for sparclet cpreg arg NAME, or -1 if not found. */
+
+int
+sparc_encode_sparclet_cpreg (name)
+ const char *name;
+{
+ return lookup_name (sparclet_cpreg_table, name);
+}
+
+/* Return the name for sparclet cpreg value VALUE or NULL if not found. */
+
+const char *
+sparc_decode_sparclet_cpreg (value)
+ int value;
+{
+ return lookup_value (sparclet_cpreg_table, value);
+}
diff --git a/opcodes/stamp-h.in b/opcodes/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/opcodes/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/opcodes/sysdep.h b/opcodes/sysdep.h
new file mode 100644
index 00000000000..bb23e5fcf5d
--- /dev/null
+++ b/opcodes/sysdep.h
@@ -0,0 +1,42 @@
+/* Random host-dependent support code.
+ Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Written by Ken Raeburn.
+
+This file is part of libopcodes, the opcodes library.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Do system-dependent stuff, mainly driven by autoconf-detected info.
+
+ Well, some generic common stuff is done here too, like including
+ ansidecl.h. That's because the .h files in bfd/hosts files I'm
+ trying to replace often did that. If it can be dropped from this
+ file (check in a non-ANSI environment!), it should be. */
+
+#include "config.h"
+
+#include <ansidecl.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
diff --git a/opcodes/tic30-dis.c b/opcodes/tic30-dis.c
new file mode 100644
index 00000000000..105145778b3
--- /dev/null
+++ b/opcodes/tic30-dis.c
@@ -0,0 +1,711 @@
+/* Disassembly routines for TMS320C30 architecture
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
+
+ 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "dis-asm.h"
+#include "opcode/tic30.h"
+
+#define NORMAL_INSN 1
+#define PARALLEL_INSN 2
+
+/* Gets the type of instruction based on the top 2 or 3 bits of the
+ instruction word. */
+#define GET_TYPE(insn) (insn & 0x80000000 ? insn & 0xC0000000 : insn & 0xE0000000)
+
+/* Instruction types. */
+#define TWO_OPERAND_1 0x00000000
+#define TWO_OPERAND_2 0x40000000
+#define THREE_OPERAND 0x20000000
+#define PAR_STORE 0xC0000000
+#define MUL_ADDS 0x80000000
+#define BRANCHES 0x60000000
+
+/* Specific instruction id bits. */
+#define NORMAL_IDEN 0x1F800000
+#define PAR_STORE_IDEN 0x3E000000
+#define MUL_ADD_IDEN 0x2C000000
+#define BR_IMM_IDEN 0x1F000000
+#define BR_COND_IDEN 0x1C3F0000
+
+/* Addressing modes. */
+#define AM_REGISTER 0x00000000
+#define AM_DIRECT 0x00200000
+#define AM_INDIRECT 0x00400000
+#define AM_IMM 0x00600000
+
+#define P_FIELD 0x03000000
+
+#define REG_AR0 0x08
+#define LDP_INSN 0x08700000
+
+/* TMS320C30 program counter for current instruction. */
+static unsigned int _pc;
+
+struct instruction
+ {
+ int type;
+ template *tm;
+ partemplate *ptm;
+ };
+
+int get_tic30_instruction PARAMS ((unsigned long, struct instruction *));
+int print_two_operand
+ PARAMS ((disassemble_info *, unsigned long, struct instruction *));
+int print_three_operand
+ PARAMS ((disassemble_info *, unsigned long, struct instruction *));
+int print_par_insn
+ PARAMS ((disassemble_info *, unsigned long, struct instruction *));
+int print_branch
+ PARAMS ((disassemble_info *, unsigned long, struct instruction *));
+int get_indirect_operand PARAMS ((unsigned short, int, char *));
+int get_register_operand PARAMS ((unsigned char, char *));
+int cnvt_tmsfloat_ieee PARAMS ((unsigned long, int, float *));
+
+int
+print_insn_tic30 (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ unsigned long insn_word;
+ struct instruction insn =
+ {0, NULL, NULL};
+ bfd_vma bufaddr = pc - info->buffer_vma;
+ /* Obtain the current instruction word from the buffer. */
+ insn_word = (*(info->buffer + bufaddr) << 24) | (*(info->buffer + bufaddr + 1) << 16) |
+ (*(info->buffer + bufaddr + 2) << 8) | *(info->buffer + bufaddr + 3);
+ _pc = pc / 4;
+ /* Get the instruction refered to by the current instruction word
+ and print it out based on its type. */
+ if (!get_tic30_instruction (insn_word, &insn))
+ return -1;
+ switch (GET_TYPE (insn_word))
+ {
+ case TWO_OPERAND_1:
+ case TWO_OPERAND_2:
+ if (!print_two_operand (info, insn_word, &insn))
+ return -1;
+ break;
+ case THREE_OPERAND:
+ if (!print_three_operand (info, insn_word, &insn))
+ return -1;
+ break;
+ case PAR_STORE:
+ case MUL_ADDS:
+ if (!print_par_insn (info, insn_word, &insn))
+ return -1;
+ break;
+ case BRANCHES:
+ if (!print_branch (info, insn_word, &insn))
+ return -1;
+ break;
+ }
+ return 4;
+}
+
+int
+get_tic30_instruction (insn_word, insn)
+ unsigned long insn_word;
+ struct instruction *insn;
+{
+ switch (GET_TYPE (insn_word))
+ {
+ case TWO_OPERAND_1:
+ case TWO_OPERAND_2:
+ case THREE_OPERAND:
+ insn->type = NORMAL_INSN;
+ {
+ template *current_optab = (template *) tic30_optab;
+ for (; current_optab < tic30_optab_end; current_optab++)
+ {
+ if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
+ {
+ if (current_optab->operands == 0)
+ {
+ if (current_optab->base_opcode == insn_word)
+ {
+ insn->tm = current_optab;
+ break;
+ }
+ }
+ else if ((current_optab->base_opcode & NORMAL_IDEN) == (insn_word & NORMAL_IDEN))
+ {
+ insn->tm = current_optab;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case PAR_STORE:
+ insn->type = PARALLEL_INSN;
+ {
+ partemplate *current_optab = (partemplate *) tic30_paroptab;
+ for (; current_optab < tic30_paroptab_end; current_optab++)
+ {
+ if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
+ {
+ if ((current_optab->base_opcode & PAR_STORE_IDEN) == (insn_word & PAR_STORE_IDEN))
+ {
+ insn->ptm = current_optab;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case MUL_ADDS:
+ insn->type = PARALLEL_INSN;
+ {
+ partemplate *current_optab = (partemplate *) tic30_paroptab;
+ for (; current_optab < tic30_paroptab_end; current_optab++)
+ {
+ if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
+ {
+ if ((current_optab->base_opcode & MUL_ADD_IDEN) == (insn_word & MUL_ADD_IDEN))
+ {
+ insn->ptm = current_optab;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case BRANCHES:
+ insn->type = NORMAL_INSN;
+ {
+ template *current_optab = (template *) tic30_optab;
+ for (; current_optab < tic30_optab_end; current_optab++)
+ {
+ if (GET_TYPE (current_optab->base_opcode) == GET_TYPE (insn_word))
+ {
+ if (current_optab->operand_types[0] & Imm24)
+ {
+ if ((current_optab->base_opcode & BR_IMM_IDEN) == (insn_word & BR_IMM_IDEN))
+ {
+ insn->tm = current_optab;
+ break;
+ }
+ }
+ else if (current_optab->operands > 0)
+ {
+ if ((current_optab->base_opcode & BR_COND_IDEN) == (insn_word & BR_COND_IDEN))
+ {
+ insn->tm = current_optab;
+ break;
+ }
+ }
+ else
+ {
+ if ((current_optab->base_opcode & (BR_COND_IDEN | 0x00800000)) == (insn_word & (BR_COND_IDEN | 0x00800000)))
+ {
+ insn->tm = current_optab;
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int
+print_two_operand (info, insn_word, insn)
+ disassemble_info *info;
+ unsigned long insn_word;
+ struct instruction *insn;
+{
+ char name[12];
+ char operand[2][13] =
+ {
+ {0},
+ {0}};
+ float f_number;
+
+ if (insn->tm == NULL)
+ return 0;
+ strcpy (name, insn->tm->name);
+ if (insn->tm->opcode_modifier == AddressMode)
+ {
+ int src_op, dest_op;
+ /* Determine whether instruction is a store or a normal instruction. */
+ if ((insn->tm->operand_types[1] & (Direct | Indirect)) == (Direct | Indirect))
+ {
+ src_op = 1;
+ dest_op = 0;
+ }
+ else
+ {
+ src_op = 0;
+ dest_op = 1;
+ }
+ /* Get the destination register. */
+ if (insn->tm->operands == 2)
+ get_register_operand ((insn_word & 0x001F0000) >> 16, operand[dest_op]);
+ /* Get the source operand based on addressing mode. */
+ switch (insn_word & AddressMode)
+ {
+ case AM_REGISTER:
+ /* Check for the NOP instruction before getting the operand. */
+ if ((insn->tm->operand_types[0] & NotReq) == 0)
+ get_register_operand ((insn_word & 0x0000001F), operand[src_op]);
+ break;
+ case AM_DIRECT:
+ sprintf (operand[src_op], "@0x%lX", (insn_word & 0x0000FFFF));
+ break;
+ case AM_INDIRECT:
+ get_indirect_operand ((insn_word & 0x0000FFFF), 2, operand[src_op]);
+ break;
+ case AM_IMM:
+ /* Get the value of the immediate operand based on variable type. */
+ switch (insn->tm->imm_arg_type)
+ {
+ case Imm_Float:
+ cnvt_tmsfloat_ieee ((insn_word & 0x0000FFFF), 2, &f_number);
+ sprintf (operand[src_op], "%2.2f", f_number);
+ break;
+ case Imm_SInt:
+ sprintf (operand[src_op], "%d", (short) (insn_word & 0x0000FFFF));
+ break;
+ case Imm_UInt:
+ sprintf (operand[src_op], "%lu", (insn_word & 0x0000FFFF));
+ break;
+ default:
+ return 0;
+ }
+ /* Handle special case for LDP instruction. */
+ if ((insn_word & 0xFFFFFF00) == LDP_INSN)
+ {
+ strcpy (name, "ldp");
+ sprintf (operand[0], "0x%06lX", (insn_word & 0x000000FF) << 16);
+ operand[1][0] = '\0';
+ }
+ }
+ }
+ /* Handle case for stack and rotate instructions. */
+ else if (insn->tm->operands == 1)
+ {
+ if (insn->tm->opcode_modifier == StackOp)
+ {
+ get_register_operand ((insn_word & 0x001F0000) >> 16, operand[0]);
+ }
+ }
+ /* Output instruction to stream. */
+ info->fprintf_func (info->stream, " %s %s%c%s", name,
+ operand[0][0] ? operand[0] : "",
+ operand[1][0] ? ',' : ' ',
+ operand[1][0] ? operand[1] : "");
+ return 1;
+}
+
+int
+print_three_operand (info, insn_word, insn)
+ disassemble_info *info;
+ unsigned long insn_word;
+ struct instruction *insn;
+{
+ char operand[3][13] =
+ {
+ {0},
+ {0},
+ {0}};
+
+ if (insn->tm == NULL)
+ return 0;
+ switch (insn_word & AddressMode)
+ {
+ case AM_REGISTER:
+ get_register_operand ((insn_word & 0x000000FF), operand[0]);
+ get_register_operand ((insn_word & 0x0000FF00) >> 8, operand[1]);
+ break;
+ case AM_DIRECT:
+ get_register_operand ((insn_word & 0x000000FF), operand[0]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1]);
+ break;
+ case AM_INDIRECT:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0]);
+ get_register_operand ((insn_word & 0x0000FF00) >> 8, operand[1]);
+ break;
+ case AM_IMM:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1]);
+ break;
+ default:
+ return 0;
+ }
+ if (insn->tm->operands == 3)
+ get_register_operand ((insn_word & 0x001F0000) >> 16, operand[2]);
+ info->fprintf_func (info->stream, " %s %s,%s%c%s", insn->tm->name,
+ operand[0], operand[1],
+ operand[2][0] ? ',' : ' ',
+ operand[2][0] ? operand[2] : "");
+ return 1;
+}
+
+int
+print_par_insn (info, insn_word, insn)
+ disassemble_info *info;
+ unsigned long insn_word;
+ struct instruction *insn;
+{
+ size_t i, len;
+ char *name1, *name2;
+ char operand[2][3][13] =
+ {
+ {
+ {0},
+ {0},
+ {0}},
+ {
+ {0},
+ {0},
+ {0}}};
+
+ if (insn->ptm == NULL)
+ return 0;
+ /* Parse out the names of each of the parallel instructions from the
+ q_insn1_insn2 format. */
+ name1 = (char *) strdup (insn->ptm->name + 2);
+ name2 = "";
+ len = strlen (name1);
+ for (i = 0; i < len; i++)
+ {
+ if (name1[i] == '_')
+ {
+ name2 = &name1[i + 1];
+ name1[i] = '\0';
+ break;
+ }
+ }
+ /* Get the operands of the instruction based on the operand order. */
+ switch (insn->ptm->oporder)
+ {
+ case OO_4op1:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
+ get_register_operand ((insn_word >> 22) & 0x07, operand[0][1]);
+ break;
+ case OO_4op2:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][0]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[1][1]);
+ get_register_operand ((insn_word >> 22) & 0x07, operand[0][1]);
+ break;
+ case OO_4op3:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
+ get_register_operand ((insn_word >> 22) & 0x07, operand[0][0]);
+ break;
+ case OO_5op1:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][0]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);
+ get_register_operand ((insn_word >> 22) & 0x07, operand[0][2]);
+ break;
+ case OO_5op2:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][1]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[0][0]);
+ get_register_operand ((insn_word >> 22) & 0x07, operand[0][2]);
+ break;
+ case OO_PField:
+ if (insn_word & 0x00800000)
+ get_register_operand (0x01, operand[0][2]);
+ else
+ get_register_operand (0x00, operand[0][2]);
+ if (insn_word & 0x00400000)
+ get_register_operand (0x03, operand[1][2]);
+ else
+ get_register_operand (0x02, operand[1][2]);
+ switch (insn_word & P_FIELD)
+ {
+ case 0x00000000:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[0][1]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][1]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[1][0]);
+ break;
+ case 0x01000000:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][0]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][1]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);
+ break;
+ case 0x02000000:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][1]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[1][0]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[0][1]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[0][0]);
+ break;
+ case 0x03000000:
+ get_indirect_operand ((insn_word & 0x000000FF), 1, operand[1][1]);
+ get_indirect_operand ((insn_word & 0x0000FF00) >> 8, 1, operand[0][0]);
+ get_register_operand ((insn_word >> 16) & 0x07, operand[1][0]);
+ get_register_operand ((insn_word >> 19) & 0x07, operand[0][1]);
+ break;
+ }
+ break;
+ default:
+ return 0;
+ }
+ info->fprintf_func (info->stream, " %s %s,%s%c%s", name1,
+ operand[0][0], operand[0][1],
+ operand[0][2][0] ? ',' : ' ',
+ operand[0][2][0] ? operand[0][2] : "");
+ info->fprintf_func (info->stream, "\n\t\t\t|| %s %s,%s%c%s", name2,
+ operand[1][0], operand[1][1],
+ operand[1][2][0] ? ',' : ' ',
+ operand[1][2][0] ? operand[1][2] : "");
+ free (name1);
+ return 1;
+}
+
+int
+print_branch (info, insn_word, insn)
+ disassemble_info *info;
+ unsigned long insn_word;
+ struct instruction *insn;
+{
+ char operand[2][13] =
+ {
+ {0},
+ {0}};
+ unsigned long address;
+ int print_label = 0;
+
+ if (insn->tm == NULL)
+ return 0;
+ /* Get the operands for 24-bit immediate jumps. */
+ if (insn->tm->operand_types[0] & Imm24)
+ {
+ address = insn_word & 0x00FFFFFF;
+ sprintf (operand[0], "0x%lX", address);
+ print_label = 1;
+ }
+ /* Get the operand for the trap instruction. */
+ else if (insn->tm->operand_types[0] & IVector)
+ {
+ address = insn_word & 0x0000001F;
+ sprintf (operand[0], "0x%lX", address);
+ }
+ else
+ {
+ address = insn_word & 0x0000FFFF;
+ /* Get the operands for the DB instructions. */
+ if (insn->tm->operands == 2)
+ {
+ get_register_operand (((insn_word & 0x01C00000) >> 22) + REG_AR0, operand[0]);
+ if (insn_word & PCRel)
+ {
+ sprintf (operand[1], "%d", (short) address);
+ print_label = 1;
+ }
+ else
+ get_register_operand (insn_word & 0x0000001F, operand[1]);
+ }
+ /* Get the operands for the standard branches. */
+ else if (insn->tm->operands == 1)
+ {
+ if (insn_word & PCRel)
+ {
+ address = (short) address;
+ sprintf (operand[0], "%ld", address);
+ print_label = 1;
+ }
+ else
+ get_register_operand (insn_word & 0x0000001F, operand[0]);
+ }
+ }
+ info->fprintf_func (info->stream, " %s %s%c%s", insn->tm->name,
+ operand[0][0] ? operand[0] : "",
+ operand[1][0] ? ',' : ' ',
+ operand[1][0] ? operand[1] : "");
+ /* Print destination of branch in relation to current symbol. */
+ if (print_label && info->symbols)
+ {
+ asymbol *sym = *info->symbols;
+
+ if ((insn->tm->opcode_modifier == PCRel) && (insn_word & PCRel))
+ {
+ address = (_pc + 1 + (short) address) - ((sym->section->vma + sym->value) / 4);
+ /* Check for delayed instruction, if so adjust destination. */
+ if (insn_word & 0x00200000)
+ address += 2;
+ }
+ else
+ {
+ address -= ((sym->section->vma + sym->value) / 4);
+ }
+ if (address == 0)
+ info->fprintf_func (info->stream, " <%s>", sym->name);
+ else
+ info->fprintf_func (info->stream, " <%s %c %d>", sym->name,
+ ((short) address < 0) ? '-' : '+',
+ abs (address));
+ }
+ return 1;
+}
+
+int
+get_indirect_operand (fragment, size, buffer)
+ unsigned short fragment;
+ int size;
+ char *buffer;
+{
+ unsigned char mod;
+ unsigned arnum;
+ unsigned char disp;
+
+ if (buffer == NULL)
+ return 0;
+ /* Determine which bits identify the sections of the indirect operand based on the
+ size in bytes. */
+ switch (size)
+ {
+ case 1:
+ mod = (fragment & 0x00F8) >> 3;
+ arnum = (fragment & 0x0007);
+ disp = 0;
+ break;
+ case 2:
+ mod = (fragment & 0xF800) >> 11;
+ arnum = (fragment & 0x0700) >> 8;
+ disp = (fragment & 0x00FF);
+ break;
+ default:
+ return 0;
+ }
+ {
+ const ind_addr_type *current_ind = tic30_indaddr_tab;
+ for (; current_ind < tic30_indaddrtab_end; current_ind++)
+ {
+ if (current_ind->modfield == mod)
+ {
+ if (current_ind->displacement == IMPLIED_DISP && size == 2)
+ {
+ continue;
+ }
+ else
+ {
+ size_t i, len;
+ int bufcnt;
+
+ len = strlen (current_ind->syntax);
+ for (i = 0, bufcnt = 0; i < len; i++, bufcnt++)
+ {
+ buffer[bufcnt] = current_ind->syntax[i];
+ if (buffer[bufcnt - 1] == 'a' && buffer[bufcnt] == 'r')
+ buffer[++bufcnt] = arnum + '0';
+ if (buffer[bufcnt] == '(' && current_ind->displacement == DISP_REQUIRED)
+ {
+ sprintf (&buffer[bufcnt + 1], "%u", disp);
+ bufcnt += strlen (&buffer[bufcnt + 1]);
+ }
+ }
+ buffer[bufcnt + 1] = '\0';
+ break;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+int
+get_register_operand (fragment, buffer)
+ unsigned char fragment;
+ char *buffer;
+{
+ const reg *current_reg = tic30_regtab;
+
+ if (buffer == NULL)
+ return 0;
+ for (; current_reg < tic30_regtab_end; current_reg++)
+ {
+ if ((fragment & 0x1F) == current_reg->opcode)
+ {
+ strcpy (buffer, current_reg->name);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+cnvt_tmsfloat_ieee (tmsfloat, size, ieeefloat)
+ unsigned long tmsfloat;
+ int size;
+ float *ieeefloat;
+{
+ unsigned long exp, sign, mant;
+
+ if (size == 2)
+ {
+ if ((tmsfloat & 0x0000F000) == 0x00008000)
+ tmsfloat = 0x80000000;
+ else
+ {
+ tmsfloat <<= 16;
+ tmsfloat = (long) tmsfloat >> 4;
+ }
+ }
+ exp = tmsfloat & 0xFF000000;
+ if (exp == 0x80000000)
+ {
+ *ieeefloat = 0.0;
+ return 1;
+ }
+ exp += 0x7F000000;
+ sign = (tmsfloat & 0x00800000) << 8;
+ mant = tmsfloat & 0x007FFFFF;
+ if (exp == 0xFF000000)
+ {
+ if (mant == 0)
+ *ieeefloat = ERANGE;
+ if (sign == 0)
+ *ieeefloat = 1.0 / 0.0;
+ else
+ *ieeefloat = -1.0 / 0.0;
+ return 1;
+ }
+ exp >>= 1;
+ if (sign)
+ {
+ mant = (~mant) & 0x007FFFFF;
+ mant += 1;
+ exp += mant & 0x00800000;
+ exp &= 0x7F800000;
+ mant &= 0x007FFFFF;
+ }
+ if (tmsfloat == 0x80000000)
+ sign = mant = exp = 0;
+ tmsfloat = sign | exp | mant;
+ *ieeefloat = *((float *) &tmsfloat);
+ return 1;
+}
diff --git a/opcodes/tic80-dis.c b/opcodes/tic80-dis.c
new file mode 100644
index 00000000000..726bc12e881
--- /dev/null
+++ b/opcodes/tic80-dis.c
@@ -0,0 +1,397 @@
+/* Print TI TMS320C80 (MVP) instructions
+ Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+
+This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+
+#include "ansidecl.h"
+#include "opcode/tic80.h"
+#include "dis-asm.h"
+
+static int length;
+
+static void print_operand_bitnum PARAMS ((struct disassemble_info *, long));
+static void print_operand_condition_code PARAMS ((struct disassemble_info *, long));
+static void print_operand_control_register PARAMS ((struct disassemble_info *, long));
+static void print_operand_float PARAMS ((struct disassemble_info *, long));
+static void print_operand_integer PARAMS ((struct disassemble_info *, long));
+static void print_operand PARAMS ((struct disassemble_info *, long, unsigned long,
+ const struct tic80_operand *, bfd_vma));
+static int print_one_instruction PARAMS ((struct disassemble_info *, bfd_vma,
+ unsigned long, const struct tic80_opcode *));
+static int print_instruction PARAMS ((struct disassemble_info *, bfd_vma, unsigned long,
+ const struct tic80_opcode *));
+static int fill_instruction PARAMS ((struct disassemble_info *, bfd_vma,
+ unsigned long *));
+
+
+/* Print an integer operand. Try to be somewhat smart about the
+ format by assuming that small positive or negative integers are
+ probably loop increment values, structure offsets, or similar
+ values that are more meaningful printed as signed decimal values.
+ Larger numbers are probably better printed as hex values. */
+
+static void
+print_operand_integer (info, value)
+ struct disassemble_info *info;
+ long value;
+{
+ if ((value > 9999 || value < -9999))
+ {
+ (*info -> fprintf_func) (info -> stream, "%#lx", value);
+ }
+ else
+ {
+ (*info -> fprintf_func) (info -> stream, "%ld", value);
+ }
+}
+
+
+/* FIXME: depends upon sizeof (long) == sizeof (float) and
+ also upon host floating point format matching target
+ floating point format. */
+
+static void
+print_operand_float (info, value)
+ struct disassemble_info *info;
+ long value;
+{
+ union { float f; long l; } fval;
+
+ fval.l = value;
+ (*info -> fprintf_func) (info -> stream, "%g", fval.f);
+}
+
+
+static void
+print_operand_control_register (info, value)
+ struct disassemble_info *info;
+ long value;
+{
+ const char *tmp;
+
+ tmp = tic80_value_to_symbol (value, TIC80_OPERAND_CR);
+ if (tmp != NULL)
+ {
+ (*info -> fprintf_func) (info -> stream, "%s", tmp);
+ }
+ else
+ {
+ (*info -> fprintf_func) (info -> stream, "%#lx", value);
+ }
+}
+
+
+static void
+print_operand_condition_code (info, value)
+ struct disassemble_info *info;
+ long value;
+{
+ const char *tmp;
+
+ tmp = tic80_value_to_symbol (value, TIC80_OPERAND_CC);
+ if (tmp != NULL)
+ {
+ (*info -> fprintf_func) (info -> stream, "%s", tmp);
+ }
+ else
+ {
+ (*info -> fprintf_func) (info -> stream, "%ld", value);
+ }
+}
+
+
+static void
+print_operand_bitnum (info, value)
+ struct disassemble_info *info;
+ long value;
+{
+ int bitnum;
+ const char *tmp;
+
+ bitnum = ~value & 0x1F;
+ tmp = tic80_value_to_symbol (bitnum, TIC80_OPERAND_BITNUM);
+ if (tmp != NULL)
+ {
+ (*info -> fprintf_func) (info -> stream, "%s", tmp);
+ }
+ else
+ {
+ (*info -> fprintf_func) (info -> stream, "%ld", bitnum);
+ }
+}
+
+
+/* Print the operand as directed by the flags. */
+
+#define M_SI(insn,op) ((((op) -> flags & TIC80_OPERAND_M_SI) != 0) && ((insn) & (1 << 17)))
+#define M_LI(insn,op) ((((op) -> flags & TIC80_OPERAND_M_LI) != 0) && ((insn) & (1 << 15)))
+#define R_SCALED(insn,op) ((((op) -> flags & TIC80_OPERAND_SCALED) != 0) && ((insn) & (1 << 11)))
+
+static void
+print_operand (info, value, insn, operand, memaddr)
+ struct disassemble_info *info;
+ long value;
+ unsigned long insn;
+ const struct tic80_operand *operand;
+ bfd_vma memaddr;
+{
+ if ((operand -> flags & TIC80_OPERAND_GPR) != 0)
+ {
+ (*info -> fprintf_func) (info -> stream, "r%ld", value);
+ if (M_SI (insn, operand) || M_LI (insn, operand))
+ {
+ (*info -> fprintf_func) (info -> stream, ":m");
+ }
+ }
+ else if ((operand -> flags & TIC80_OPERAND_FPA) != 0)
+ {
+ (*info -> fprintf_func) (info -> stream, "a%ld", value);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_PCREL) != 0)
+ {
+ (*info -> print_address_func) (memaddr + 4 * value, info);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_BASEREL) != 0)
+ {
+ (*info -> print_address_func) (value, info);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_BITNUM) != 0)
+ {
+ print_operand_bitnum (info, value);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_CC) != 0)
+ {
+ print_operand_condition_code (info, value);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_CR) != 0)
+ {
+ print_operand_control_register (info, value);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_FLOAT) != 0)
+ {
+ print_operand_float (info, value);
+ }
+ else if ((operand -> flags & TIC80_OPERAND_BITFIELD))
+ {
+ (*info -> fprintf_func) (info -> stream, "%#lx", value);
+ }
+ else
+ {
+ print_operand_integer (info, value);
+ }
+
+ /* If this is a scaled operand, then print the modifier */
+
+ if (R_SCALED (insn, operand))
+ {
+ (*info -> fprintf_func) (info -> stream, ":s");
+ }
+}
+
+
+/* We have chosen an opcode table entry */
+
+static int
+print_one_instruction (info, memaddr, insn, opcode)
+ struct disassemble_info *info;
+ bfd_vma memaddr;
+ unsigned long insn;
+ const struct tic80_opcode *opcode;
+{
+ const struct tic80_operand *operand;
+ long value;
+ int status;
+ const unsigned char *opindex;
+ int close_paren;
+
+ (*info -> fprintf_func) (info -> stream, "%-10s", opcode -> name);
+
+ for (opindex = opcode -> operands; *opindex != 0; opindex++)
+ {
+ operand = tic80_operands + *opindex;
+
+ /* Extract the value from the instruction. */
+ if (operand -> extract)
+ {
+ value = (*operand -> extract) (insn, (int *) NULL);
+ }
+ else if (operand -> bits == 32)
+ {
+ status = fill_instruction (info, memaddr, (unsigned long *) &value);
+ if (status == -1)
+ {
+ return (status);
+ }
+ }
+ else
+ {
+ value = (insn >> operand -> shift) & ((1 << operand -> bits) - 1);
+ if ((operand -> flags & TIC80_OPERAND_SIGNED) != 0
+ && (value & (1 << (operand -> bits - 1))) != 0)
+ {
+ value -= 1 << operand -> bits;
+ }
+ }
+
+ /* If this operand is enclosed in parenthesis, then print
+ the open paren, otherwise just print the regular comma
+ separator, except for the first operand. */
+
+ if ((operand -> flags & TIC80_OPERAND_PARENS) == 0)
+ {
+ close_paren = 0;
+ if (opindex != opcode -> operands)
+ {
+ (*info -> fprintf_func) (info -> stream, ",");
+ }
+ }
+ else
+ {
+ close_paren = 1;
+ (*info -> fprintf_func) (info -> stream, "(");
+ }
+
+ print_operand (info, value, insn, operand, memaddr);
+
+ /* If we printed an open paren before printing this operand, close
+ it now. The flag gets reset on each loop. */
+
+ if (close_paren)
+ {
+ (*info -> fprintf_func) (info -> stream, ")");
+ }
+ }
+ return (length);
+}
+
+
+
+/* There are no specific bits that tell us for certain whether a vector
+ instruction opcode contains one or two instructions. However since
+ a destination register of r0 is illegal, we can check for nonzero
+ values in both destination register fields. Only opcodes that have
+ two valid instructions will have non-zero in both */
+
+#define TWO_INSN(insn) ((((insn) & (0x1F << 27)) != 0) && (((insn) & (0x1F << 22)) != 0))
+
+static int
+print_instruction (info, memaddr, insn, vec_opcode)
+ struct disassemble_info *info;
+ bfd_vma memaddr;
+ unsigned long insn;
+ const struct tic80_opcode *vec_opcode;
+{
+ const struct tic80_opcode *opcode;
+ const struct tic80_opcode *opcode_end;
+
+ /* Find the first opcode match in the opcodes table. For vector
+ opcodes (vec_opcode != NULL) find the first match that is not the
+ previously found match. FIXME: there should be faster ways to
+ search (hash table or binary search), but don't worry too much
+ about it until other TIc80 support is finished. */
+
+ opcode_end = tic80_opcodes + tic80_num_opcodes;
+ for (opcode = tic80_opcodes; opcode < opcode_end; opcode++)
+ {
+ if ((insn & opcode -> mask) == opcode -> opcode &&
+ opcode != vec_opcode)
+ {
+ break;
+ }
+ }
+
+ if (opcode == opcode_end)
+ {
+ /* No match found, just print the bits as a .word directive */
+ (*info -> fprintf_func) (info -> stream, ".word %#08lx", insn);
+ }
+ else
+ {
+ /* Match found, decode the instruction. */
+ length = print_one_instruction (info, memaddr, insn, opcode);
+ if (opcode -> flags & TIC80_VECTOR && vec_opcode == NULL && TWO_INSN (insn))
+ {
+ /* There is another instruction to print from the same opcode.
+ Print the separator and then find and print the other
+ instruction. */
+ (*info -> fprintf_func) (info -> stream, " || ");
+ length = print_instruction (info, memaddr, insn, opcode);
+ }
+ }
+ return (length);
+}
+
+/* Get the next 32 bit word from the instruction stream and convert it
+ into internal format in the unsigned long INSN, for which we are
+ passed the address. Return 0 on success, -1 on error. */
+
+static int
+fill_instruction (info, memaddr, insnp)
+ struct disassemble_info *info;
+ bfd_vma memaddr;
+ unsigned long *insnp;
+{
+ bfd_byte buffer[4];
+ int status;
+
+ /* Get the bits for the next 32 bit word and put in buffer */
+
+ status = (*info -> read_memory_func) (memaddr + length, buffer, 4, info);
+ if (status != 0)
+ {
+ (*info -> memory_error_func) (status, memaddr, info);
+ return (-1);
+ }
+
+ /* Read was successful, so increment count of bytes read and convert
+ the bits into internal format. */
+
+ length += 4;
+ if (info -> endian == BFD_ENDIAN_LITTLE)
+ {
+ *insnp = bfd_getl32 (buffer);
+ }
+ else if (info -> endian == BFD_ENDIAN_BIG)
+ {
+ *insnp = bfd_getb32 (buffer);
+ }
+ else
+ {
+ /* FIXME: Should probably just default to one or the other */
+ abort ();
+ }
+ return (0);
+}
+
+
+int
+print_insn_tic80 (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+ unsigned long insn;
+ int status;
+
+ length = 0;
+ info->bytes_per_line = 8;
+ status = fill_instruction (info, memaddr, &insn);
+ if (status != -1)
+ {
+ status = print_instruction (info, memaddr, insn, NULL);
+ }
+ return (status);
+}
diff --git a/opcodes/tic80-opc.c b/opcodes/tic80-opc.c
new file mode 100644
index 00000000000..425c308ba64
--- /dev/null
+++ b/opcodes/tic80-opc.c
@@ -0,0 +1,1216 @@
+/* Opcode table for TI TMS320C80 (MVP).
+ Copyright 1996, 1999 Free Software Foundation, Inc.
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the GNU binutils are distributed in the hope that they
+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 file; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/tic80.h"
+
+/* This file holds various tables for the TMS320C80 (MVP).
+
+ The opcode table is strictly constant data, so the compiler should
+ be able to put it in the .text section.
+
+ This file also holds the operand table. All knowledge about
+ inserting operands into instructions and vice-versa is kept in this
+ file.
+
+ The predefined register table maps from register names to register
+ values. */
+
+
+/* Table of predefined symbol names, such as general purpose registers,
+ floating point registers, condition codes, control registers, and bit
+ numbers.
+
+ The table is sorted case independently by name so that it is suitable for
+ searching via a binary search using a case independent comparison
+ function.
+
+ Note that the type of the symbol is stored in the upper bits of the value
+ field, which allows the value and type to be passed around as a unit in a
+ single int. The types have to be masked off before using the numeric
+ value as a number.
+*/
+
+const struct predefined_symbol tic80_predefined_symbols[] =
+{
+ { "a0", TIC80_OPERAND_FPA | 0 },
+ { "a1", TIC80_OPERAND_FPA | 1 },
+ { "alw.b", TIC80_OPERAND_CC | 7 },
+ { "alw.h", TIC80_OPERAND_CC | 15 },
+ { "alw.w", TIC80_OPERAND_CC | 23 },
+ { "ANASTAT", TIC80_OPERAND_CR | 0x34 },
+ { "BRK1", TIC80_OPERAND_CR | 0x39 },
+ { "BRK2", TIC80_OPERAND_CR | 0x3A },
+ { "CONFIG", TIC80_OPERAND_CR | 2 },
+ { "DLRU", TIC80_OPERAND_CR | 0x500 },
+ { "DTAG0", TIC80_OPERAND_CR | 0x400 },
+ { "DTAG1", TIC80_OPERAND_CR | 0x401 },
+ { "DTAG10", TIC80_OPERAND_CR | 0x40A },
+ { "DTAG11", TIC80_OPERAND_CR | 0x40B },
+ { "DTAG12", TIC80_OPERAND_CR | 0x40C },
+ { "DTAG13", TIC80_OPERAND_CR | 0x40D },
+ { "DTAG14", TIC80_OPERAND_CR | 0x40E },
+ { "DTAG15", TIC80_OPERAND_CR | 0x40F },
+ { "DTAG2", TIC80_OPERAND_CR | 0x402 },
+ { "DTAG3", TIC80_OPERAND_CR | 0x403 },
+ { "DTAG4", TIC80_OPERAND_CR | 0x404 },
+ { "DTAG5", TIC80_OPERAND_CR | 0x405 },
+ { "DTAG6", TIC80_OPERAND_CR | 0x406 },
+ { "DTAG7", TIC80_OPERAND_CR | 0x407 },
+ { "DTAG8", TIC80_OPERAND_CR | 0x408 },
+ { "DTAG9", TIC80_OPERAND_CR | 0x409 },
+ { "ECOMCNTL", TIC80_OPERAND_CR | 0x33 },
+ { "EIP", TIC80_OPERAND_CR | 1 },
+ { "EPC", TIC80_OPERAND_CR | 0 },
+ { "eq.b", TIC80_OPERAND_BITNUM | 0 },
+ { "eq.f", TIC80_OPERAND_BITNUM | 20 },
+ { "eq.h", TIC80_OPERAND_BITNUM | 10 },
+ { "eq.w", TIC80_OPERAND_BITNUM | 20 },
+ { "eq0.b", TIC80_OPERAND_CC | 2 },
+ { "eq0.h", TIC80_OPERAND_CC | 10 },
+ { "eq0.w", TIC80_OPERAND_CC | 18 },
+ { "FLTADR", TIC80_OPERAND_CR | 0x11 },
+ { "FLTDTH", TIC80_OPERAND_CR | 0x14 },
+ { "FLTDTL", TIC80_OPERAND_CR | 0x13 },
+ { "FLTOP", TIC80_OPERAND_CR | 0x10 },
+ { "FLTTAG", TIC80_OPERAND_CR | 0x12 },
+ { "FPST", TIC80_OPERAND_CR | 8 },
+ { "ge.b", TIC80_OPERAND_BITNUM | 5 },
+ { "ge.f", TIC80_OPERAND_BITNUM | 25 },
+ { "ge.h", TIC80_OPERAND_BITNUM | 15 },
+ { "ge.w", TIC80_OPERAND_BITNUM | 25 },
+ { "ge0.b", TIC80_OPERAND_CC | 3 },
+ { "ge0.h", TIC80_OPERAND_CC | 11 },
+ { "ge0.w", TIC80_OPERAND_CC | 19 },
+ { "gt.b", TIC80_OPERAND_BITNUM | 2 },
+ { "gt.f", TIC80_OPERAND_BITNUM | 22 },
+ { "gt.h", TIC80_OPERAND_BITNUM | 12 },
+ { "gt.w", TIC80_OPERAND_BITNUM | 22 },
+ { "gt0.b", TIC80_OPERAND_CC | 1 },
+ { "gt0.h", TIC80_OPERAND_CC | 9 },
+ { "gt0.w", TIC80_OPERAND_CC | 17 },
+ { "hi.b", TIC80_OPERAND_BITNUM | 6 },
+ { "hi.h", TIC80_OPERAND_BITNUM | 16 },
+ { "hi.w", TIC80_OPERAND_BITNUM | 26 },
+ { "hs.b", TIC80_OPERAND_BITNUM | 9 },
+ { "hs.h", TIC80_OPERAND_BITNUM | 19 },
+ { "hs.w", TIC80_OPERAND_BITNUM | 29 },
+ { "ib.f", TIC80_OPERAND_BITNUM | 28 },
+ { "IE", TIC80_OPERAND_CR | 6 },
+ { "ILRU", TIC80_OPERAND_CR | 0x300 },
+ { "in.f", TIC80_OPERAND_BITNUM | 27 },
+ { "IN0P", TIC80_OPERAND_CR | 0x4000 },
+ { "IN1P", TIC80_OPERAND_CR | 0x4001 },
+ { "INTPEN", TIC80_OPERAND_CR | 4 },
+ { "ITAG0", TIC80_OPERAND_CR | 0x200 },
+ { "ITAG1", TIC80_OPERAND_CR | 0x201 },
+ { "ITAG10", TIC80_OPERAND_CR | 0x20A },
+ { "ITAG11", TIC80_OPERAND_CR | 0x20B },
+ { "ITAG12", TIC80_OPERAND_CR | 0x20C },
+ { "ITAG13", TIC80_OPERAND_CR | 0x20D },
+ { "ITAG14", TIC80_OPERAND_CR | 0x20E },
+ { "ITAG15", TIC80_OPERAND_CR | 0x20F },
+ { "ITAG2", TIC80_OPERAND_CR | 0x202 },
+ { "ITAG3", TIC80_OPERAND_CR | 0x203 },
+ { "ITAG4", TIC80_OPERAND_CR | 0x204 },
+ { "ITAG5", TIC80_OPERAND_CR | 0x205 },
+ { "ITAG6", TIC80_OPERAND_CR | 0x206 },
+ { "ITAG7", TIC80_OPERAND_CR | 0x207 },
+ { "ITAG8", TIC80_OPERAND_CR | 0x208 },
+ { "ITAG9", TIC80_OPERAND_CR | 0x209 },
+ { "le.b", TIC80_OPERAND_BITNUM | 3 },
+ { "le.f", TIC80_OPERAND_BITNUM | 23 },
+ { "le.h", TIC80_OPERAND_BITNUM | 13 },
+ { "le.w", TIC80_OPERAND_BITNUM | 23 },
+ { "le0.b", TIC80_OPERAND_CC | 6 },
+ { "le0.h", TIC80_OPERAND_CC | 14 },
+ { "le0.w", TIC80_OPERAND_CC | 22 },
+ { "lo.b", TIC80_OPERAND_BITNUM | 8 },
+ { "lo.h", TIC80_OPERAND_BITNUM | 18 },
+ { "lo.w", TIC80_OPERAND_BITNUM | 28 },
+ { "ls.b", TIC80_OPERAND_BITNUM | 7 },
+ { "ls.h", TIC80_OPERAND_BITNUM | 17 },
+ { "ls.w", TIC80_OPERAND_BITNUM | 27 },
+ { "lt.b", TIC80_OPERAND_BITNUM | 4 },
+ { "lt.f", TIC80_OPERAND_BITNUM | 24 },
+ { "lt.h", TIC80_OPERAND_BITNUM | 14 },
+ { "lt.w", TIC80_OPERAND_BITNUM | 24 },
+ { "lt0.b", TIC80_OPERAND_CC | 4 },
+ { "lt0.h", TIC80_OPERAND_CC | 12 },
+ { "lt0.w", TIC80_OPERAND_CC | 20 },
+ { "MIP", TIC80_OPERAND_CR | 0x31 },
+ { "MPC", TIC80_OPERAND_CR | 0x30 },
+ { "ne.b", TIC80_OPERAND_BITNUM | 1 },
+ { "ne.f", TIC80_OPERAND_BITNUM | 21 },
+ { "ne.h", TIC80_OPERAND_BITNUM | 11 },
+ { "ne.w", TIC80_OPERAND_BITNUM | 21 },
+ { "ne0.b", TIC80_OPERAND_CC | 5 },
+ { "ne0.h", TIC80_OPERAND_CC | 13 },
+ { "ne0.w", TIC80_OPERAND_CC | 21 },
+ { "nev.b", TIC80_OPERAND_CC | 0 },
+ { "nev.h", TIC80_OPERAND_CC | 8 },
+ { "nev.w", TIC80_OPERAND_CC | 16 },
+ { "ob.f", TIC80_OPERAND_BITNUM | 29 },
+ { "or.f", TIC80_OPERAND_BITNUM | 31 },
+ { "ou.f", TIC80_OPERAND_BITNUM | 26 },
+ { "OUTP", TIC80_OPERAND_CR | 0x4002 },
+ { "PKTREQ", TIC80_OPERAND_CR | 0xD },
+ { "PPERROR", TIC80_OPERAND_CR | 0xA },
+ { "r0", TIC80_OPERAND_GPR | 0 },
+ { "r1", TIC80_OPERAND_GPR | 1 },
+ { "r10", TIC80_OPERAND_GPR | 10 },
+ { "r11", TIC80_OPERAND_GPR | 11 },
+ { "r12", TIC80_OPERAND_GPR | 12 },
+ { "r13", TIC80_OPERAND_GPR | 13 },
+ { "r14", TIC80_OPERAND_GPR | 14 },
+ { "r15", TIC80_OPERAND_GPR | 15 },
+ { "r16", TIC80_OPERAND_GPR | 16 },
+ { "r17", TIC80_OPERAND_GPR | 17 },
+ { "r18", TIC80_OPERAND_GPR | 18 },
+ { "r19", TIC80_OPERAND_GPR | 19 },
+ { "r2", TIC80_OPERAND_GPR | 2 },
+ { "r20", TIC80_OPERAND_GPR | 20 },
+ { "r21", TIC80_OPERAND_GPR | 21 },
+ { "r22", TIC80_OPERAND_GPR | 22 },
+ { "r23", TIC80_OPERAND_GPR | 23 },
+ { "r24", TIC80_OPERAND_GPR | 24 },
+ { "r25", TIC80_OPERAND_GPR | 25 },
+ { "r26", TIC80_OPERAND_GPR | 26 },
+ { "r27", TIC80_OPERAND_GPR | 27 },
+ { "r28", TIC80_OPERAND_GPR | 28 },
+ { "r29", TIC80_OPERAND_GPR | 29 },
+ { "r3", TIC80_OPERAND_GPR | 3 },
+ { "r30", TIC80_OPERAND_GPR | 30 },
+ { "r31", TIC80_OPERAND_GPR | 31 },
+ { "r4", TIC80_OPERAND_GPR | 4 },
+ { "r5", TIC80_OPERAND_GPR | 5 },
+ { "r6", TIC80_OPERAND_GPR | 6 },
+ { "r7", TIC80_OPERAND_GPR | 7 },
+ { "r8", TIC80_OPERAND_GPR | 8 },
+ { "r9", TIC80_OPERAND_GPR | 9 },
+ { "SYSSTK", TIC80_OPERAND_CR | 0x20 },
+ { "SYSTMP", TIC80_OPERAND_CR | 0x21 },
+ { "TCOUNT", TIC80_OPERAND_CR | 0xE },
+ { "TSCALE", TIC80_OPERAND_CR | 0xF },
+ { "uo.f", TIC80_OPERAND_BITNUM | 30 },
+};
+
+const int tic80_num_predefined_symbols = sizeof (tic80_predefined_symbols) / sizeof (struct predefined_symbol);
+
+/* This function takes a predefined symbol name in NAME, symbol class
+ in CLASS, and translates it to a numeric value, which it returns.
+
+ If CLASS is zero, any symbol that matches NAME is translated. If
+ CLASS is non-zero, then only a symbol that has class CLASS is
+ matched.
+
+ If no translation is possible, it returns -1, a value not used by
+ any predefined symbol. Note that the predefined symbol array is
+ presorted case independently by name.
+
+ This function is implemented with the assumption that there are no
+ duplicate names in the predefined symbol array, which happens to be
+ true at the moment.
+
+ */
+
+int
+tic80_symbol_to_value (name, class)
+ char *name;
+ int class;
+{
+ const struct predefined_symbol *pdsp;
+ int low = 0;
+ int middle;
+ int high = tic80_num_predefined_symbols - 1;
+ int cmp;
+ int rtnval = -1;
+
+ while (low <= high)
+ {
+ middle = (low + high) / 2;
+ cmp = strcasecmp (name, tic80_predefined_symbols[middle].name);
+ if (cmp < 0)
+ {
+ high = middle - 1;
+ }
+ else if (cmp > 0)
+ {
+ low = middle + 1;
+ }
+ else
+ {
+ pdsp = &tic80_predefined_symbols[middle];
+ if ((class == 0) || (class & PDS_VALUE (pdsp)))
+ {
+ rtnval = PDS_VALUE (pdsp);
+ }
+ /* For now we assume that there are no duplicate names */
+ break;
+ }
+ }
+ return (rtnval);
+}
+
+/* This function takes a value VAL and finds a matching predefined
+ symbol that is in the operand class specified by CLASS. If CLASS
+ is zero, the first matching symbol is returned. */
+
+const char *
+tic80_value_to_symbol (val, class)
+ int val;
+ int class;
+{
+ const struct predefined_symbol *pdsp;
+ int ival;
+ char *name;
+
+ name = NULL;
+ for (pdsp = tic80_predefined_symbols;
+ pdsp < tic80_predefined_symbols + tic80_num_predefined_symbols;
+ pdsp++)
+ {
+ ival = PDS_VALUE (pdsp) & ~TIC80_OPERAND_MASK;
+ if (ival == val)
+ {
+ if ((class == 0) || (class & PDS_VALUE (pdsp)))
+ {
+ /* Found the desired match */
+ name = PDS_NAME (pdsp);
+ break;
+ }
+ }
+ }
+ return (name);
+}
+
+/* This function returns a pointer to the next symbol in the predefined
+ symbol table after PDSP, or NULL if PDSP points to the last symbol. If
+ PDSP is NULL, it returns the first symbol in the table. Thus it can be
+ used to walk through the table by first calling it with NULL and then
+ calling it with each value it returned on the previous call, until it
+ returns NULL. */
+
+const struct predefined_symbol *
+tic80_next_predefined_symbol (pdsp)
+ const struct predefined_symbol *pdsp;
+{
+ if (pdsp == NULL)
+ {
+ pdsp = tic80_predefined_symbols;
+ }
+ else if (pdsp >= tic80_predefined_symbols &&
+ pdsp < tic80_predefined_symbols + tic80_num_predefined_symbols - 1)
+ {
+ pdsp++;
+ }
+ else
+ {
+ pdsp = NULL;
+ }
+ return (pdsp);
+}
+
+
+
+/* The operands table. The fields are:
+
+ bits, shift, insertion function, extraction function, flags
+ */
+
+const struct tic80_operand tic80_operands[] =
+{
+
+ /* The zero index is used to indicate the end of the list of operands. */
+
+#define UNUSED (0)
+ { 0, 0, 0, 0, 0 },
+
+ /* Short signed immediate value in bits 14-0. */
+
+#define SSI (UNUSED + 1)
+ { 15, 0, NULL, NULL, TIC80_OPERAND_SIGNED },
+
+ /* Short unsigned immediate value in bits 14-0 */
+
+#define SUI (SSI + 1)
+ { 15, 0, NULL, NULL, 0 },
+
+ /* Short unsigned bitfield in bits 14-0. We distinguish this
+ from a regular unsigned immediate value only for the convenience
+ of the disassembler and the user. */
+
+#define SUBF (SUI + 1)
+ { 15, 0, NULL, NULL, TIC80_OPERAND_BITFIELD },
+
+ /* Long signed immediate in following 32 bit word */
+
+#define LSI (SUBF + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_SIGNED },
+
+ /* Long unsigned immediate in following 32 bit word */
+
+#define LUI (LSI + 1)
+ { 32, 0, NULL, NULL, 0 },
+
+ /* Long unsigned bitfield in following 32 bit word. We distinguish
+ this from a regular unsigned immediate value only for the
+ convenience of the disassembler and the user. */
+
+#define LUBF (LUI + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_BITFIELD },
+
+ /* Single precision floating point immediate in following 32 bit
+ word. */
+
+#define SPFI (LUBF + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_FLOAT },
+
+ /* Register in bits 4-0 */
+
+#define REG_0 (SPFI + 1)
+ { 5, 0, NULL, NULL, TIC80_OPERAND_GPR },
+
+ /* Even register in bits 4-0 */
+
+#define REG_0_E (REG_0 + 1)
+ { 5, 0, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_EVEN },
+
+ /* Register in bits 26-22 */
+
+#define REG_22 (REG_0_E + 1)
+ { 5, 22, NULL, NULL, TIC80_OPERAND_GPR },
+
+ /* Even register in bits 26-22 */
+
+#define REG_22_E (REG_22 + 1)
+ { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_EVEN },
+
+ /* Register in bits 31-27 */
+
+#define REG_DEST (REG_22_E + 1)
+ { 5, 27, NULL, NULL, TIC80_OPERAND_GPR },
+
+ /* Even register in bits 31-27 */
+
+#define REG_DEST_E (REG_DEST + 1)
+ { 5, 27, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_EVEN },
+
+ /* Floating point accumulator register (a0-a3) specified by bit 16 (MSB)
+ and bit 11 (LSB) */
+ /* FIXME! Needs to use functions to insert and extract the register
+ number in bits 16 and 11. */
+
+#define REG_FPA (REG_DEST_E + 1)
+ { 0, 0, NULL, NULL, TIC80_OPERAND_FPA },
+
+ /* Short signed PC word offset in bits 14-0 */
+
+#define OFF_SS_PC (REG_FPA + 1)
+ { 15, 0, NULL, NULL, TIC80_OPERAND_PCREL | TIC80_OPERAND_SIGNED },
+
+ /* Long signed PC word offset in following 32 bit word */
+
+#define OFF_SL_PC (OFF_SS_PC + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_PCREL | TIC80_OPERAND_SIGNED },
+
+ /* Short signed base relative byte offset in bits 14-0 */
+
+#define OFF_SS_BR (OFF_SL_PC + 1)
+ { 15, 0, NULL, NULL, TIC80_OPERAND_BASEREL | TIC80_OPERAND_SIGNED },
+
+ /* Long signed base relative byte offset in following 32 bit word */
+
+#define OFF_SL_BR (OFF_SS_BR + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_BASEREL | TIC80_OPERAND_SIGNED },
+
+ /* Long signed base relative byte offset in following 32 bit word
+ with optional ":s" modifier flag in bit 11 */
+
+#define OFF_SL_BR_SCALED (OFF_SL_BR + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_BASEREL | TIC80_OPERAND_SIGNED | TIC80_OPERAND_SCALED },
+
+ /* BITNUM in bits 31-27 */
+
+#define BITNUM (OFF_SL_BR_SCALED + 1)
+ { 5, 27, NULL, NULL, TIC80_OPERAND_BITNUM },
+
+ /* Condition code in bits 31-27 */
+
+#define CC (BITNUM + 1)
+ { 5, 27, NULL, NULL, TIC80_OPERAND_CC },
+
+ /* Control register number in bits 14-0 */
+
+#define CR_SI (CC + 1)
+ { 15, 0, NULL, NULL, TIC80_OPERAND_CR },
+
+ /* Control register number in next 32 bit word */
+
+#define CR_LI (CR_SI + 1)
+ { 32, 0, NULL, NULL, TIC80_OPERAND_CR },
+
+ /* A base register in bits 26-22, enclosed in parens */
+
+#define REG_BASE (CR_LI + 1)
+ { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_PARENS },
+
+ /* A base register in bits 26-22, enclosed in parens, with optional ":m"
+ flag in bit 17 (short immediate instructions only) */
+
+#define REG_BASE_M_SI (REG_BASE + 1)
+ { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_PARENS | TIC80_OPERAND_M_SI },
+
+ /* A base register in bits 26-22, enclosed in parens, with optional ":m"
+ flag in bit 15 (long immediate and register instructions only) */
+
+#define REG_BASE_M_LI (REG_BASE_M_SI + 1)
+ { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_PARENS | TIC80_OPERAND_M_LI },
+
+ /* Scaled register in bits 4-0, with optional ":s" modifier flag in bit 11 */
+
+#define REG_SCALED (REG_BASE_M_LI + 1)
+ { 5, 0, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_SCALED },
+
+ /* Unsigned immediate in bits 4-0, used only for shift instructions */
+
+#define ROTATE (REG_SCALED + 1)
+ { 5, 0, NULL, NULL, 0 },
+
+ /* Unsigned immediate in bits 9-5, used only for shift instructions */
+#define ENDMASK (ROTATE + 1)
+ { 5, 5, NULL, NULL, TIC80_OPERAND_ENDMASK },
+
+};
+
+const int tic80_num_operands = sizeof (tic80_operands)/sizeof(*tic80_operands);
+
+
+/* Macros used to generate entries for the opcodes table. */
+
+#define FIXME 0
+
+/* Short-Immediate Format Instructions - basic opcode */
+#define OP_SI(x) (((x) & 0x7F) << 15)
+#define MASK_SI OP_SI(0x7F)
+
+/* Long-Immediate Format Instructions - basic opcode */
+#define OP_LI(x) (((x) & 0x3FF) << 12)
+#define MASK_LI OP_LI(0x3FF)
+
+/* Register Format Instructions - basic opcode */
+#define OP_REG(x) OP_LI(x) /* For readability */
+#define MASK_REG MASK_LI /* For readability */
+
+/* The 'n' bit at bit 10 */
+#define n(x) ((x) << 10)
+
+/* The 'i' bit at bit 11 */
+#define i(x) ((x) << 11)
+
+/* The 'F' bit at bit 27 */
+#define F(x) ((x) << 27)
+
+/* The 'E' bit at bit 27 */
+#define E(x) ((x) << 27)
+
+/* The 'M' bit at bit 15 in register and long immediate opcodes */
+#define M_REG(x) ((x) << 15)
+#define M_LI(x) ((x) << 15)
+
+/* The 'M' bit at bit 17 in short immediate opcodes */
+#define M_SI(x) ((x) << 17)
+
+/* The 'SZ' field at bits 14-13 in register and long immediate opcodes */
+#define SZ_REG(x) ((x) << 13)
+#define SZ_LI(x) ((x) << 13)
+
+/* The 'SZ' field at bits 16-15 in short immediate opcodes */
+#define SZ_SI(x) ((x) << 15)
+
+/* The 'D' (direct external memory access) bit at bit 10 in long immediate
+ and register opcodes. */
+#define D(x) ((x) << 10)
+
+/* The 'S' (scale offset by data size) bit at bit 11 in long immediate
+ and register opcodes. */
+#define S(x) ((x) << 11)
+
+/* The 'PD' field at bits 10-9 in floating point instructions */
+#define PD(x) ((x) << 9)
+
+/* The 'P2' field at bits 8-7 in floating point instructions */
+#define P2(x) ((x) << 7)
+
+/* The 'P1' field at bits 6-5 in floating point instructions */
+#define P1(x) ((x) << 5)
+
+/* The 'a' field at bit 16 in vector instructions */
+#define V_a1(x) ((x) << 16)
+
+/* The 'a' field at bit 11 in vector instructions */
+#define V_a0(x) ((x) << 11)
+
+/* The 'm' field at bit 10 in vector instructions */
+#define V_m(x) ((x) << 10)
+
+/* The 'S' field at bit 9 in vector instructions */
+#define V_S(x) ((x) << 9)
+
+/* The 'Z' field at bit 8 in vector instructions */
+#define V_Z(x) ((x) << 8)
+
+/* The 'p' field at bit 6 in vector instructions */
+#define V_p(x) ((x) << 6)
+
+/* The opcode field at bits 21-17 for vector instructions */
+#define OP_V(x) ((x) << 17)
+#define MASK_V OP_V(0x1F)
+
+
+/* The opcode table. Formatted for better readability on a wide screen. Also, all
+ entries with the same mnemonic are sorted so that they are adjacent in the table,
+ allowing the use of a hash table to locate the first of a sequence of opcodes that have
+ a particular name. The short immediate forms also come before the long immediate forms
+ so that the assembler will pick the "best fit" for the size of the operand, except for
+ the case of the PC relative forms, where the long forms come first and are the default
+ forms. */
+
+const struct tic80_opcode tic80_opcodes[] = {
+
+ /* The "nop" instruction is really "rdcr 0,r0". We put it first so that this
+ specific bit pattern will get disassembled as a nop rather than an rdcr. The
+ mask of all ones ensures that this will happen. */
+
+ {"nop", OP_SI(0x4), ~0, 0, {0} },
+
+ /* The "br" instruction is really "bbz target,r0,31". We put it first so that
+ this specific bit pattern will get disassembled as a br rather than bbz. */
+
+ {"br", OP_SI(0x48), 0xFFFF8000, 0, {OFF_SS_PC} },
+ {"br", OP_LI(0x391), 0xFFFFF000, 0, {OFF_SL_PC} },
+ {"br", OP_REG(0x390), 0xFFFFF000, 0, {REG_0} },
+ {"br.a", OP_SI(0x49), 0xFFFF8000, 0, {OFF_SS_PC} },
+ {"br.a", OP_LI(0x393), 0xFFFFF000, 0, {OFF_SL_PC} },
+ {"br.a", OP_REG(0x392), 0xFFFFF000, 0, {REG_0} },
+
+ /* Signed integer ADD */
+
+ {"add", OP_SI(0x58), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
+ {"add", OP_LI(0x3B1), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
+ {"add", OP_REG(0x3B0), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Unsigned integer ADD */
+
+ {"addu", OP_SI(0x59), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
+ {"addu", OP_LI(0x3B3), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
+ {"addu", OP_REG(0x3B2), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Bitwise AND */
+
+ {"and", OP_SI(0x11), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"and", OP_LI(0x323), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"and", OP_REG(0x322), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+ {"and.tt", OP_SI(0x11), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"and.tt", OP_LI(0x323), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"and.tt", OP_REG(0x322), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Bitwise AND with ones complement of both sources */
+
+ {"and.ff", OP_SI(0x18), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"and.ff", OP_LI(0x331), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"and.ff", OP_REG(0x330), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Bitwise AND with ones complement of source 1 */
+
+ {"and.ft", OP_SI(0x14), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"and.ft", OP_LI(0x329), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"and.ft", OP_REG(0x328), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Bitwise AND with ones complement of source 2 */
+
+ {"and.tf", OP_SI(0x12), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"and.tf", OP_LI(0x325), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"and.tf", OP_REG(0x324), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Branch Bit One - nonannulled */
+
+ {"bbo", OP_SI(0x4A), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
+ {"bbo", OP_LI(0x395), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
+ {"bbo", OP_REG(0x394), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
+
+ /* Branch Bit One - annulled */
+
+ {"bbo.a", OP_SI(0x4B), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
+ {"bbo.a", OP_LI(0x397), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
+ {"bbo.a", OP_REG(0x396), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
+
+ /* Branch Bit Zero - nonannulled */
+
+ {"bbz", OP_SI(0x48), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
+ {"bbz", OP_LI(0x391), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
+ {"bbz", OP_REG(0x390), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
+
+ /* Branch Bit Zero - annulled */
+
+ {"bbz.a", OP_SI(0x49), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
+ {"bbz.a", OP_LI(0x393), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
+ {"bbz.a", OP_REG(0x392), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
+
+ /* Branch Conditional - nonannulled */
+
+ {"bcnd", OP_SI(0x4C), MASK_SI, 0, {OFF_SS_PC, REG_22, CC} },
+ {"bcnd", OP_LI(0x399), MASK_LI, 0, {OFF_SL_PC, REG_22, CC} },
+ {"bcnd", OP_REG(0x398), MASK_REG, 0, {REG_0, REG_22, CC} },
+
+ /* Branch Conditional - annulled */
+
+ {"bcnd.a", OP_SI(0x4D), MASK_SI, 0, {OFF_SS_PC, REG_22, CC} },
+ {"bcnd.a", OP_LI(0x39B), MASK_LI, 0, {OFF_SL_PC, REG_22, CC} },
+ {"bcnd.a", OP_REG(0x39A), MASK_REG, 0, {REG_0, REG_22, CC} },
+
+ /* Branch Control Register */
+
+ {"brcr", OP_SI(0x6), MASK_SI, 0, {CR_SI} },
+ {"brcr", OP_LI(0x30D), MASK_LI, 0, {CR_LI} },
+ {"brcr", OP_REG(0x30C), MASK_REG, 0, {REG_0} },
+
+ /* Branch and save return - nonannulled */
+
+ {"bsr", OP_SI(0x40), MASK_SI, 0, {OFF_SS_PC, REG_DEST} },
+ {"bsr", OP_LI(0x381), MASK_LI, 0, {OFF_SL_PC, REG_DEST} },
+ {"bsr", OP_REG(0x380), MASK_REG, 0, {REG_0, REG_DEST} },
+
+ /* Branch and save return - annulled */
+
+ {"bsr.a", OP_SI(0x41), MASK_SI, 0, {OFF_SS_PC, REG_DEST} },
+ {"bsr.a", OP_LI(0x383), MASK_LI, 0, {OFF_SL_PC, REG_DEST} },
+ {"bsr.a", OP_REG(0x382), MASK_REG, 0, {REG_0, REG_DEST} },
+
+ /* Send command */
+
+ {"cmnd", OP_SI(0x2), MASK_SI, 0, {SUI} },
+ {"cmnd", OP_LI(0x305), MASK_LI, 0, {LUI} },
+ {"cmnd", OP_REG(0x304), MASK_REG, 0, {REG_0} },
+
+ /* Integer compare */
+
+ {"cmp", OP_SI(0x50), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
+ {"cmp", OP_LI(0x3A1), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
+ {"cmp", OP_REG(0x3A0), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Flush data cache subblock - don't clear subblock preset flag */
+
+ {"dcachec", OP_SI(0x38), F(1) | (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI} },
+ {"dcachec", OP_LI(0x371), F(1) | (MASK_LI & ~M_LI(1)) | S(1) | D(1), 0, {LSI, REG_BASE_M_LI} },
+ {"dcachec", OP_REG(0x370), F(1) | (MASK_REG & ~M_REG(1)) | S(1) | D(1), 0, {REG_0, REG_BASE_M_LI} },
+
+ /* Flush data cache subblock - clear subblock preset flag */
+
+ {"dcachef", OP_SI(0x38) | F(1), F(1) | (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI} },
+ {"dcachef", OP_LI(0x371) | F(1), F(1) | (MASK_LI & ~M_LI(1)) | S(1) | D(1), 0, {LSI, REG_BASE_M_LI} },
+ {"dcachef", OP_REG(0x370) | F(1), F(1) | (MASK_REG & ~M_REG(1)) | S(1) | D(1), 0, {REG_0, REG_BASE_M_LI} },
+
+ /* Direct load signed data into register */
+
+ {"dld", OP_LI(0x345) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld", OP_REG(0x344) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.b", OP_LI(0x341) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.b", OP_REG(0x340) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.d", OP_LI(0x347) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"dld.d", OP_REG(0x346) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"dld.h", OP_LI(0x343) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.h", OP_REG(0x342) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+
+ /* Direct load unsigned data into register */
+
+ {"dld.ub", OP_LI(0x351) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.ub", OP_REG(0x350) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.uh", OP_LI(0x353) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dld.uh", OP_REG(0x352) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+
+ /* Direct store data into memory */
+
+ {"dst", OP_LI(0x365) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dst", OP_REG(0x364) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dst.b", OP_LI(0x361) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dst.b", OP_REG(0x360) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dst.d", OP_LI(0x367) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"dst.d", OP_REG(0x366) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"dst.h", OP_LI(0x363) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"dst.h", OP_REG(0x362) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+
+ /* Emulation stop */
+
+ {"estop", OP_LI(0x3FC), MASK_LI, 0, {0} },
+
+ /* Emulation trap */
+
+ {"etrap", OP_SI(0x1) | E(1), MASK_SI | E(1), 0, {SUI} },
+ {"etrap", OP_LI(0x303) | E(1), MASK_LI | E(1), 0, {LUI} },
+ {"etrap", OP_REG(0x302) | E(1), MASK_REG | E(1), 0, {REG_0} },
+
+ /* Floating-point addition */
+
+ {"fadd.ddd", OP_REG(0x3E0) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
+ {"fadd.dsd", OP_REG(0x3E0) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
+ {"fadd.sdd", OP_LI(0x3E1) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
+ {"fadd.sdd", OP_REG(0x3E0) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
+ {"fadd.ssd", OP_LI(0x3E1) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
+ {"fadd.ssd", OP_REG(0x3E0) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
+ {"fadd.sss", OP_LI(0x3E1) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
+ {"fadd.sss", OP_REG(0x3E0) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Floating point compare */
+
+ {"fcmp.dd", OP_REG(0x3EA) | PD(0) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST} },
+ {"fcmp.ds", OP_REG(0x3EA) | PD(0) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST} },
+ {"fcmp.sd", OP_LI(0x3EB) | PD(0) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST} },
+ {"fcmp.sd", OP_REG(0x3EA) | PD(0) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST} },
+ {"fcmp.ss", OP_LI(0x3EB) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
+ {"fcmp.ss", OP_REG(0x3EA) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Floating point divide */
+
+ {"fdiv.ddd", OP_REG(0x3E6) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
+ {"fdiv.dsd", OP_REG(0x3E6) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
+ {"fdiv.sdd", OP_LI(0x3E7) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
+ {"fdiv.sdd", OP_REG(0x3E6) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
+ {"fdiv.ssd", OP_LI(0x3E7) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
+ {"fdiv.ssd", OP_REG(0x3E6) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
+ {"fdiv.sss", OP_LI(0x3E7) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
+ {"fdiv.sss", OP_REG(0x3E6) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Floating point multiply */
+
+ {"fmpy.ddd", OP_REG(0x3E4) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
+ {"fmpy.dsd", OP_REG(0x3E4) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
+ {"fmpy.iii", OP_LI(0x3E5) | PD(2) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_22, REG_DEST} },
+ {"fmpy.iii", OP_REG(0x3E4) | PD(2) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+ {"fmpy.sdd", OP_LI(0x3E5) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
+ {"fmpy.sdd", OP_REG(0x3E4) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
+ {"fmpy.ssd", OP_LI(0x3E5) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
+ {"fmpy.ssd", OP_REG(0x3E4) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
+ {"fmpy.sss", OP_LI(0x3E5) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
+ {"fmpy.sss", OP_REG(0x3E4) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+ {"fmpy.uuu", OP_LI(0x3E5) | PD(3) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LUI, REG_22, REG_DEST} },
+ {"fmpy.uuu", OP_REG(0x3E4) | PD(3) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Convert/Round to Minus Infinity */
+
+ {"frndm.dd", OP_REG(0x3E8) | PD(1) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
+ {"frndm.di", OP_REG(0x3E8) | PD(2) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndm.ds", OP_REG(0x3E8) | PD(0) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndm.du", OP_REG(0x3E8) | PD(3) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndm.id", OP_LI(0x3E9) | PD(1) | P2(3) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndm.id", OP_REG(0x3E8) | PD(1) | P2(3) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndm.is", OP_LI(0x3E9) | PD(0) | P2(3) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndm.is", OP_REG(0x3E8) | PD(0) | P2(3) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndm.sd", OP_LI(0x3E9) | PD(1) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
+ {"frndm.sd", OP_REG(0x3E8) | PD(1) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndm.si", OP_LI(0x3E9) | PD(2) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndm.si", OP_REG(0x3E8) | PD(2) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndm.ss", OP_LI(0x3E9) | PD(0) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndm.ss", OP_REG(0x3E8) | PD(0) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndm.su", OP_LI(0x3E9) | PD(3) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndm.su", OP_REG(0x3E8) | PD(3) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndm.ud", OP_LI(0x3E9) | PD(1) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndm.ud", OP_REG(0x3E8) | PD(1) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndm.us", OP_LI(0x3E9) | PD(0) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndm.us", OP_REG(0x3E8) | PD(0) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+
+ /* Convert/Round to Nearest */
+
+ {"frndn.dd", OP_REG(0x3E8) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
+ {"frndn.di", OP_REG(0x3E8) | PD(2) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndn.ds", OP_REG(0x3E8) | PD(0) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndn.du", OP_REG(0x3E8) | PD(3) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndn.id", OP_LI(0x3E9) | PD(1) | P2(0) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndn.id", OP_REG(0x3E8) | PD(1) | P2(0) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndn.is", OP_LI(0x3E9) | PD(0) | P2(0) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndn.is", OP_REG(0x3E8) | PD(0) | P2(0) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndn.sd", OP_LI(0x3E9) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
+ {"frndn.sd", OP_REG(0x3E8) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndn.si", OP_LI(0x3E9) | PD(2) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndn.si", OP_REG(0x3E8) | PD(2) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndn.ss", OP_LI(0x3E9) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndn.ss", OP_REG(0x3E8) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndn.su", OP_LI(0x3E9) | PD(3) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndn.su", OP_REG(0x3E8) | PD(3) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndn.ud", OP_LI(0x3E9) | PD(1) | P2(0) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndn.ud", OP_REG(0x3E8) | PD(1) | P2(0) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndn.us", OP_LI(0x3E9) | PD(0) | P2(0) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndn.us", OP_REG(0x3E8) | PD(0) | P2(0) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+
+ /* Convert/Round to Positive Infinity */
+
+ {"frndp.dd", OP_REG(0x3E8) | PD(1) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
+ {"frndp.di", OP_REG(0x3E8) | PD(2) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndp.ds", OP_REG(0x3E8) | PD(0) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndp.du", OP_REG(0x3E8) | PD(3) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndp.id", OP_LI(0x3E9) | PD(1) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndp.id", OP_REG(0x3E8) | PD(1) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndp.is", OP_LI(0x3E9) | PD(0) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndp.is", OP_REG(0x3E8) | PD(0) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndp.sd", OP_LI(0x3E9) | PD(1) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
+ {"frndp.sd", OP_REG(0x3E8) | PD(1) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndp.si", OP_LI(0x3E9) | PD(2) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndp.si", OP_REG(0x3E8) | PD(2) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndp.ss", OP_LI(0x3E9) | PD(0) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndp.ss", OP_REG(0x3E8) | PD(0) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndp.su", OP_LI(0x3E9) | PD(3) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndp.su", OP_REG(0x3E8) | PD(3) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndp.ud", OP_LI(0x3E9) | PD(1) | P2(2) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndp.ud", OP_REG(0x3E8) | PD(1) | P2(2) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndp.us", OP_LI(0x3E9) | PD(0) | P2(2) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndp.us", OP_REG(0x3E8) | PD(0) | P2(2) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+
+ /* Convert/Round to Zero */
+
+ {"frndz.dd", OP_REG(0x3E8) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
+ {"frndz.di", OP_REG(0x3E8) | PD(2) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndz.ds", OP_REG(0x3E8) | PD(0) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndz.du", OP_REG(0x3E8) | PD(3) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
+ {"frndz.id", OP_LI(0x3E9) | PD(1) | P2(1) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndz.id", OP_REG(0x3E8) | PD(1) | P2(1) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndz.is", OP_LI(0x3E9) | PD(0) | P2(1) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndz.is", OP_REG(0x3E8) | PD(0) | P2(1) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndz.sd", OP_LI(0x3E9) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
+ {"frndz.sd", OP_REG(0x3E8) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndz.si", OP_LI(0x3E9) | PD(2) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndz.si", OP_REG(0x3E8) | PD(2) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndz.ss", OP_LI(0x3E9) | PD(0) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndz.ss", OP_REG(0x3E8) | PD(0) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndz.su", OP_LI(0x3E9) | PD(3) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"frndz.su", OP_REG(0x3E8) | PD(3) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+ {"frndz.ud", OP_LI(0x3E9) | PD(1) | P2(1) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
+ {"frndz.ud", OP_REG(0x3E8) | PD(1) | P2(1) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"frndz.us", OP_LI(0x3E9) | PD(0) | P2(1) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
+ {"frndz.us", OP_REG(0x3E8) | PD(0) | P2(1) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+
+ /* Floating point square root */
+
+ {"fsqrt.dd", OP_REG(0x3EE) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
+ {"fsqrt.sd", OP_LI(0x3EF) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
+ {"fsqrt.sd", OP_REG(0x3EE) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
+ {"fsqrt.ss", OP_LI(0x3EF) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
+ {"fsqrt.ss", OP_REG(0x3EE) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
+
+ /* Floating point subtraction */
+
+ { "fsub.ddd", OP_REG(0x3E2) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
+ { "fsub.dsd", OP_REG(0x3E2) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
+ { "fsub.sdd", OP_LI(0x3E3) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
+ { "fsub.sdd", OP_REG(0x3E2) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
+ { "fsub.ssd", OP_LI(0x3E3) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
+ { "fsub.ssd", OP_REG(0x3E2) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
+ { "fsub.sss", OP_LI(0x3E3) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
+ { "fsub.sss", OP_REG(0x3E2) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Illegal instructions */
+
+ {"illop0", OP_SI(0x0), MASK_SI, 0, {0} },
+ {"illopF", 0x1FF << 13, 0x1FF << 13, 0, {0} },
+
+ /* Jump and save return */
+
+ {"jsr", OP_SI(0x44), MASK_SI, 0, {OFF_SS_BR, REG_BASE, REG_DEST} },
+ {"jsr", OP_LI(0x389), MASK_LI, 0, {OFF_SL_BR, REG_BASE, REG_DEST} },
+ {"jsr", OP_REG(0x388), MASK_REG, 0, {REG_0, REG_BASE, REG_DEST} },
+ {"jsr.a", OP_SI(0x45), MASK_SI, 0, {OFF_SS_BR, REG_BASE, REG_DEST} },
+ {"jsr.a", OP_LI(0x38B), MASK_LI, 0, {OFF_SL_BR, REG_BASE, REG_DEST} },
+ {"jsr.a", OP_REG(0x38A), MASK_REG, 0, {REG_0, REG_BASE, REG_DEST} },
+
+ /* Load Signed Data Into Register */
+
+ {"ld", OP_SI(0x22), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"ld", OP_LI(0x345) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld", OP_REG(0x344) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.b", OP_SI(0x20), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"ld.b", OP_LI(0x341) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.b", OP_REG(0x340) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.d", OP_SI(0x23), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST_E} },
+ {"ld.d", OP_LI(0x347) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"ld.d", OP_REG(0x346) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"ld.h", OP_SI(0x21), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"ld.h", OP_LI(0x343) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.h", OP_REG(0x342) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+
+ /* Load Unsigned Data Into Register */
+
+ {"ld.ub", OP_SI(0x28), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"ld.ub", OP_LI(0x351) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.ub", OP_REG(0x350) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.uh", OP_SI(0x29), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"ld.uh", OP_LI(0x353) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"ld.uh", OP_REG(0x352) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+
+ /* Leftmost one */
+
+ {"lmo", OP_LI(0x3F0), MASK_LI, 0, {REG_22, REG_DEST} },
+
+ /* Bitwise logical OR. Note that "or.tt" and "or" are the same instructions. */
+
+ {"or.ff", OP_SI(0x1E), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
+ {"or.ff", OP_LI(0x33D), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
+ {"or.ff", OP_REG(0x33C), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+ {"or.ft", OP_SI(0x1D), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
+ {"or.ft", OP_LI(0x33B), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
+ {"or.ft", OP_REG(0x33A), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+ {"or.tf", OP_SI(0x1B), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
+ {"or.tf", OP_LI(0x337), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
+ {"or.tf", OP_REG(0x336), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+ {"or.tt", OP_SI(0x17), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
+ {"or.tt", OP_LI(0x32F), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
+ {"or.tt", OP_REG(0x32E), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+ {"or", OP_SI(0x17), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
+ {"or", OP_LI(0x32F), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
+ {"or", OP_REG(0x32E), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Read Control Register */
+
+ {"rdcr", OP_SI(0x4), MASK_SI | (0x1F << 22), 0, {CR_SI, REG_DEST} },
+ {"rdcr", OP_LI(0x309), MASK_LI | (0x1F << 22), 0, {CR_LI, REG_DEST} },
+ {"rdcr", OP_REG(0x308), MASK_REG | (0x1F << 22), 0, {REG_0, REG_DEST} },
+
+ /* Rightmost one */
+
+ {"rmo", OP_LI(0x3F2), MASK_LI, 0, {REG_22, REG_DEST} },
+
+ /* Shift Register Left - note that rotl, shl, and ins are all alternate names for one of the shift instructions.
+ They appear prior to their sl equivalent so that they will be diassembled as the alternate name. */
+
+
+ {"ins", OP_REG(0x31E) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"ins", OP_SI(0xF) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"rotl", OP_REG(0x310) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"rotl", OP_SI(0x8) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"shl", OP_REG(0x31C) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"shl", OP_SI(0xE) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.dm", OP_REG(0x312) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.dm", OP_SI(0x9) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.ds", OP_REG(0x314) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.ds", OP_SI(0xA) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.dz", OP_REG(0x310) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.dz", OP_SI(0x8) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.em", OP_REG(0x318) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.em", OP_SI(0xC) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.es", OP_REG(0x31A) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.es", OP_SI(0xD) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.ez", OP_REG(0x316) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.ez", OP_SI(0xB) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.im", OP_REG(0x31E) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.im", OP_SI(0xF) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sl.iz", OP_REG(0x31C) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sl.iz", OP_SI(0xE) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+
+ /* Shift Register Left With Inverted Endmask */
+
+ {"sli.dm", OP_REG(0x312) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.dm", OP_SI(0x9) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.ds", OP_REG(0x314) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.ds", OP_SI(0xA) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.dz", OP_REG(0x310) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.dz", OP_SI(0x8) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.em", OP_REG(0x318) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.em", OP_SI(0xC) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.es", OP_REG(0x31A) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.es", OP_SI(0xD) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.ez", OP_REG(0x316) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.ez", OP_SI(0xB) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.im", OP_REG(0x31E) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.im", OP_SI(0xF) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sli.iz", OP_REG(0x31C) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sli.iz", OP_SI(0xE) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+
+ /* Shift Register Right - note that exts, extu, rotr, sra, and srl are all alternate names for one of the shift instructions.
+ They appear prior to their sr equivalent so that they will be diassembled as the alternate name. */
+
+ {"exts", OP_REG(0x314) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"exts", OP_SI(0xA) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"extu", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"extu", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"rotr", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"rotr", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sra", OP_REG(0x31A) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sra", OP_SI(0xD) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"srl", OP_REG(0x316) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"srl", OP_SI(0xB) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.dm", OP_REG(0x312) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.dm", OP_SI(0x9) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.ds", OP_REG(0x314) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.ds", OP_SI(0xA) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.dz", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.dz", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.em", OP_REG(0x318) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.em", OP_SI(0xC) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.es", OP_REG(0x31A) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.es", OP_SI(0xD) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.ez", OP_REG(0x316) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.ez", OP_SI(0xB) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.im", OP_REG(0x31E) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.im", OP_SI(0xF) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sr.iz", OP_REG(0x31C) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sr.iz", OP_SI(0xE) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+
+ /* Shift Register Right With Inverted Endmask */
+
+ {"sri.dm", OP_REG(0x312) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.dm", OP_SI(0x9) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.ds", OP_REG(0x314) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.ds", OP_SI(0xA) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.dz", OP_REG(0x310) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.dz", OP_SI(0x8) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.em", OP_REG(0x318) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.em", OP_SI(0xC) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.es", OP_REG(0x31A) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.es", OP_SI(0xD) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.ez", OP_REG(0x316) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.ez", OP_SI(0xB) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.im", OP_REG(0x31E) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.im", OP_SI(0xF) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+ {"sri.iz", OP_REG(0x31C) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
+ {"sri.iz", OP_SI(0xE) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
+
+ /* Store Data into Memory */
+
+ {"st", OP_SI(0x32), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"st", OP_LI(0x365) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"st", OP_REG(0x364) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"st.b", OP_SI(0x30), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"st.b", OP_LI(0x361) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"st.b", OP_REG(0x360) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"st.d", OP_SI(0x33), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST_E} },
+ {"st.d", OP_LI(0x367) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"st.d", OP_REG(0x366) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
+ {"st.h", OP_SI(0x31), (MASK_SI & ~M_SI(1)), 0, {OFF_SS_BR, REG_BASE_M_SI, REG_DEST} },
+ {"st.h", OP_LI(0x363) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {OFF_SL_BR_SCALED, REG_BASE_M_LI, REG_DEST} },
+ {"st.h", OP_REG(0x362) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
+
+ /* Signed Integer Subtract */
+
+ {"sub", OP_SI(0x5A), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
+ {"sub", OP_LI(0x3B5), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
+ {"sub", OP_REG(0x3B4), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Unsigned Integer Subtract */
+
+ {"subu", OP_SI(0x5B), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
+ {"subu", OP_LI(0x3B7), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
+ {"subu", OP_REG(0x3B6), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Write Control Register
+ Is a special form of the "swcr" instruction so comes before it in the table. */
+
+ {"wrcr", OP_SI(0x5), MASK_SI | (0x1F << 27), 0, {CR_SI, REG_22} },
+ {"wrcr", OP_LI(0x30B), MASK_LI | (0x1F << 27), 0, {CR_LI, REG_22} },
+ {"wrcr", OP_REG(0x30A), MASK_REG | (0x1F << 27), 0, {REG_0, REG_22} },
+
+ /* Swap Control Register */
+
+ {"swcr", OP_SI(0x5), MASK_SI, 0, {CR_SI, REG_22, REG_DEST} },
+ {"swcr", OP_LI(0x30B), MASK_LI, 0, {CR_LI, REG_22, REG_DEST} },
+ {"swcr", OP_REG(0x30A), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ /* Trap */
+
+ {"trap", OP_SI(0x1) | E(0), MASK_SI | E(1), 0, {SUI} },
+ {"trap", OP_LI(0x303) | E(0), MASK_LI | E(1), 0, {LUI} },
+ {"trap", OP_REG(0x302) | E(0), MASK_REG | E(1), 0, {REG_0} },
+
+ /* Vector Floating-Point Add */
+
+ {"vadd.dd", OP_REG(0x3C0) | P2(1) | P1(1), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0_E, REG_22_E, REG_22_E} },
+ {"vadd.sd", OP_LI(0x3C1) | P2(1) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22_E, REG_22_E} },
+ {"vadd.sd", OP_REG(0x3C0) | P2(1) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E, REG_22_E} },
+ {"vadd.ss", OP_LI(0x3C1) | P2(0) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22, REG_22} },
+ {"vadd.ss", OP_REG(0x3C0) | P2(0) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22, REG_22} },
+
+ /* Vector Floating-Point Multiply and Add to Accumulator FIXME! This is not yet fully implemented.
+ From the documentation there appears to be no way to tell the difference between the opcodes for
+ instructions that have register destinations and instructions that have accumulator destinations.
+ Further investigation is necessary. Since this isn't critical to getting a TIC80 toolchain up
+ and running, it is defered until later. */
+
+ /* Vector Floating-Point Multiply
+ Note: If r0 is in the destination reg, then this is a "vector nop" instruction. */
+
+ {"vmpy.dd", OP_REG(0x3C4) | P2(1) | P1(1), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {REG_0_E, REG_22_E, REG_22_E} },
+ {"vmpy.sd", OP_LI(0x3C5) | P2(1) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {SPFI, REG_22_E, REG_22_E} },
+ {"vmpy.sd", OP_REG(0x3C4) | P2(1) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {REG_0, REG_22_E, REG_22_E} },
+ {"vmpy.ss", OP_LI(0x3C5) | P2(0) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {SPFI, REG_22, REG_22} },
+ {"vmpy.ss", OP_REG(0x3C4) | P2(0) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {REG_0, REG_22, REG_22} },
+
+ /* Vector Floating-Point Multiply and Subtract from Accumulator
+ FIXME: See note above for vmac instruction */
+
+ /* Vector Floating-Point Subtract Accumulator From Source
+ FIXME: See note above for vmac instruction */
+
+ /* Vector Round With Floating-Point Input
+ FIXME: See note above for vmac instruction */
+
+ /* Vector Round with Integer Input */
+
+ {"vrnd.id", OP_LI (0x3CB) | P2(1) | P1(0), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LSI, REG_22_E}},
+ {"vrnd.id", OP_REG (0x3CA) | P2(1) | P1(0), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E}},
+ {"vrnd.is", OP_LI (0x3CB) | P2(0) | P1(0), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LSI, REG_22}},
+ {"vrnd.is", OP_REG (0x3CA) | P2(0) | P1(0), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22}},
+ {"vrnd.ud", OP_LI (0x3CB) | P2(1) | P1(1), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LUI, REG_22_E}},
+ {"vrnd.ud", OP_REG (0x3CA) | P2(1) | P1(1), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E}},
+ {"vrnd.us", OP_LI (0x3CB) | P2(0) | P1(1), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LUI, REG_22}},
+ {"vrnd.us", OP_REG (0x3CA) | P2(0) | P1(1), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22}},
+
+ /* Vector Floating-Point Subtract */
+
+ {"vsub.dd", OP_REG(0x3C2) | P2(1) | P1(1), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0_E, REG_22_E, REG_22_E} },
+ {"vsub.sd", OP_LI(0x3C3) | P2(1) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22_E, REG_22_E} },
+ {"vsub.sd", OP_REG(0x3C2) | P2(1) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E, REG_22_E} },
+ {"vsub.ss", OP_LI(0x3C3) | P2(0) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22, REG_22} },
+ {"vsub.ss", OP_REG(0x3C2) | P2(0) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22, REG_22} },
+
+ /* Vector Load Data Into Register - Note that the vector load/store instructions come after the other
+ vector instructions so that the disassembler will always print the load/store instruction second for
+ vector instructions that have two instructions in the same opcode. */
+
+ {"vld0.d", OP_V(0x1E) | V_m(1) | V_S(1) | V_p(0), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST_E} },
+ {"vld0.s", OP_V(0x1E) | V_m(1) | V_S(0) | V_p(0), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST} },
+ {"vld1.d", OP_V(0x1E) | V_m(1) | V_S(1) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST_E} },
+ {"vld1.s", OP_V(0x1E) | V_m(1) | V_S(0) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST} },
+
+ /* Vector Store Data Into Memory - Note that the vector load/store instructions come after the other
+ vector instructions so that the disassembler will always print the load/store instruction second for
+ vector instructions that have two instructions in the same opcode. */
+
+ {"vst.d", OP_V(0x1E) | V_m(0) | V_S(1) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST_E} },
+ {"vst.s", OP_V(0x1E) | V_m(0) | V_S(0) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST} },
+
+ {"xnor", OP_SI(0x19), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"xnor", OP_LI(0x333), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"xnor", OP_REG(0x332), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+ {"xor", OP_SI(0x16), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
+ {"xor", OP_LI(0x32D), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
+ {"xor", OP_REG(0x32C), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
+
+};
+
+const int tic80_num_opcodes = sizeof (tic80_opcodes) / sizeof (tic80_opcodes[0]);
diff --git a/opcodes/v850-dis.c b/opcodes/v850-dis.c
new file mode 100644
index 00000000000..610625b6a19
--- /dev/null
+++ b/opcodes/v850-dis.c
@@ -0,0 +1,381 @@
+/* Disassemble V850 instructions.
+ Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <stdio.h>
+
+#include "ansidecl.h"
+#include "opcode/v850.h"
+#include "dis-asm.h"
+#include "opintl.h"
+
+static const char *const v850_reg_names[] =
+{ "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp" };
+
+static const char *const v850_sreg_names[] =
+{ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+ "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
+ "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
+ "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31" };
+
+static const char *const v850_cc_names[] =
+{ "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
+ "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt" };
+
+static int
+disassemble (memaddr, info, insn)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+ unsigned long insn;
+{
+ struct v850_opcode * op = (struct v850_opcode *)v850_opcodes;
+ const struct v850_operand * operand;
+ int match = 0;
+ int short_op = ((insn & 0x0600) != 0x0600);
+ int bytes_read;
+ int target_processor;
+
+ /* Special case: 32 bit MOV */
+ if ((insn & 0xffe0) == 0x0620)
+ short_op = true;
+
+ bytes_read = short_op ? 2 : 4;
+
+ /* If this is a two byte insn, then mask off the high bits. */
+ if (short_op)
+ insn &= 0xffff;
+
+ switch (info->mach)
+ {
+ case 0:
+ default:
+ target_processor = PROCESSOR_V850;
+ break;
+
+ case bfd_mach_v850e:
+ target_processor = PROCESSOR_V850E;
+ break;
+
+ case bfd_mach_v850ea:
+ target_processor = PROCESSOR_V850EA;
+ break;
+ }
+
+ /* Find the opcode. */
+ while (op->name)
+ {
+ if ((op->mask & insn) == op->opcode
+ && (op->processors & target_processor))
+ {
+ const unsigned char * opindex_ptr;
+ unsigned int opnum;
+ unsigned int memop;
+
+ match = 1;
+ (*info->fprintf_func) (info->stream, "%s\t", op->name);
+/*fprintf (stderr, "match: mask: %x insn: %x, opcode: %x, name: %s\n", op->mask, insn, op->opcode, op->name );*/
+
+ memop = op->memop;
+ /* Now print the operands.
+
+ MEMOP is the operand number at which a memory
+ address specification starts, or zero if this
+ instruction has no memory addresses.
+
+ A memory address is always two arguments.
+
+ This information allows us to determine when to
+ insert commas into the output stream as well as
+ when to insert disp[reg] expressions onto the
+ output stream. */
+
+ for (opindex_ptr = op->operands, opnum = 1;
+ *opindex_ptr != 0;
+ opindex_ptr++, opnum++)
+ {
+ long value;
+ int flag;
+ int status;
+ bfd_byte buffer[ 4 ];
+
+ operand = &v850_operands[*opindex_ptr];
+
+ if (operand->extract)
+ value = (operand->extract) (insn, 0);
+ else
+ {
+ if (operand->bits == -1)
+ value = (insn & operand->shift);
+ else
+ value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+
+ if (operand->flags & V850_OPERAND_SIGNED)
+ value = ((long)(value << (32 - operand->bits))
+ >> (32 - operand->bits));
+ }
+
+ /* The first operand is always output without any
+ special handling.
+
+ For the following arguments:
+
+ If memop && opnum == memop + 1, then we need '[' since
+ we're about to output the register used in a memory
+ reference.
+
+ If memop && opnum == memop + 2, then we need ']' since
+ we just finished the register in a memory reference. We
+ also need a ',' before this operand.
+
+ Else we just need a comma.
+
+ We may need to output a trailing ']' if the last operand
+ in an instruction is the register for a memory address.
+
+ The exception (and there's always an exception) is the
+ "jmp" insn which needs square brackets around it's only
+ register argument. */
+
+ if (memop && opnum == memop + 1) info->fprintf_func (info->stream, "[");
+ else if (memop && opnum == memop + 2) info->fprintf_func (info->stream, "],");
+ else if (memop == 1 && opnum == 1
+ && (operand->flags & V850_OPERAND_REG))
+ info->fprintf_func (info->stream, "[");
+ else if (opnum > 1) info->fprintf_func (info->stream, ", ");
+
+ /* extract the flags, ignorng ones which do not effect disassembly output. */
+ flag = operand->flags;
+ flag &= ~ V850_OPERAND_SIGNED;
+ flag &= ~ V850_OPERAND_RELAX;
+ flag &= - flag;
+
+ switch (flag)
+ {
+ case V850_OPERAND_REG: info->fprintf_func (info->stream, "%s", v850_reg_names[value]); break;
+ case V850_OPERAND_SRG: info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); break;
+ case V850_OPERAND_CC: info->fprintf_func (info->stream, "%s", v850_cc_names[value]); break;
+ case V850_OPERAND_EP: info->fprintf_func (info->stream, "ep"); break;
+ default: info->fprintf_func (info->stream, "%d", value); break;
+ case V850_OPERAND_DISP:
+ {
+ bfd_vma addr = value + memaddr;
+
+ /* On the v850 the top 8 bits of an address are used by an overlay manager.
+ Thus it may happen that when we are looking for a symbol to match
+ against an address with some of its top bits set, the search fails to
+ turn up an exact match. In this case we try to find an exact match
+ against a symbol in the lower address space, and if we find one, we
+ use that address. We only do this for JARL instructions however, as
+ we do not want to misinterpret branch instructions. */
+ if (operand->bits == 22)
+ {
+ if ( ! info->symbol_at_address_func (addr, info)
+ && ((addr & 0xFF000000) != 0)
+ && info->symbol_at_address_func (addr & 0x00FFFFFF, info))
+ {
+ addr &= 0x00FFFFFF;
+ }
+ }
+ info->print_address_func (addr, info);
+ break;
+ }
+
+ case V850E_PUSH_POP:
+ {
+ static int list12_regs[32] = { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
+ static int list18_h_regs[32] = { 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
+ static int list18_l_regs[32] = { 3, 2, 1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8 };
+ int * regs;
+ int i;
+ unsigned long int mask = 0;
+ int pc = false;
+ int sr = false;
+
+
+ switch (operand->shift)
+ {
+ case 0xffe00001: regs = list12_regs; break;
+ case 0xfff8000f: regs = list18_h_regs; break;
+ case 0xfff8001f: regs = list18_l_regs; value &= ~0x10; break; /* Do not include magic bit */
+ default:
+ /* xgettext:c-format */
+ fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift );
+ abort();
+ }
+
+ for (i = 0; i < 32; i++)
+ {
+ if (value & (1 << i))
+ {
+ switch (regs[ i ])
+ {
+ default: mask |= (1 << regs[ i ]); break;
+ /* xgettext:c-format */
+ case 0: fprintf (stderr, _("unknown pop reg: %d\n"), i ); abort();
+ case -1: pc = true; break;
+ case -2: sr = true; break;
+ }
+ }
+ }
+
+ info->fprintf_func (info->stream, "{");
+
+ if (mask || pc || sr)
+ {
+ if (mask)
+ {
+ unsigned int bit;
+ int shown_one = false;
+
+ for (bit = 0; bit < 32; bit++)
+ if (mask & (1 << bit))
+ {
+ unsigned long int first = bit;
+ unsigned long int last;
+
+ if (shown_one)
+ info->fprintf_func (info->stream, ", ");
+ else
+ shown_one = true;
+
+ info->fprintf_func (info->stream, v850_reg_names[first]);
+
+ for (bit++; bit < 32; bit++)
+ if ((mask & (1 << bit)) == 0)
+ break;
+
+ last = bit;
+
+ if (last > first + 1)
+ {
+ info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
+ }
+ }
+ }
+
+ if (pc)
+ info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
+ if (sr)
+ info->fprintf_func (info->stream, "%sSR", (mask || pc) ? ", " : "");
+ }
+
+ info->fprintf_func (info->stream, "}");
+ }
+ break;
+
+ case V850E_IMMEDIATE16:
+ status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
+ if (status == 0)
+ {
+ bytes_read += 2;
+ value = bfd_getl16 (buffer);
+
+ /* If this is a DISPOSE instruction with ff set to 0x10, then shift value up by 16. */
+ if ((insn & 0x001fffc0) == 0x00130780)
+ value <<= 16;
+
+ info->fprintf_func (info->stream, "0x%x", value);
+ }
+ else
+ {
+ info->memory_error_func (status, memaddr + bytes_read, info);
+ }
+ break;
+
+ case V850E_IMMEDIATE32:
+ status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
+ if (status == 0)
+ {
+ bytes_read += 4;
+ value = bfd_getl32 (buffer);
+ info->fprintf_func (info->stream, "0x%lx", value);
+ }
+ else
+ {
+ info->memory_error_func (status, memaddr + bytes_read, info);
+ }
+ break;
+ }
+
+ /* Handle jmp correctly. */
+ if (memop == 1 && opnum == 1
+ && ((operand->flags & V850_OPERAND_REG) != 0))
+ (*info->fprintf_func) (info->stream, "]");
+ }
+
+ /* Close any square bracket we left open. */
+ if (memop && opnum == memop + 2)
+ (*info->fprintf_func) (info->stream, "]");
+
+ /* All done. */
+ break;
+ }
+ op++;
+ }
+
+ if (!match)
+ {
+ if (short_op)
+ info->fprintf_func (info->stream, ".short\t0x%04x", insn);
+ else
+ info->fprintf_func (info->stream, ".long\t0x%08x", insn);
+ }
+
+ return bytes_read;
+}
+
+int
+print_insn_v850 (memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info * info;
+{
+ int status;
+ bfd_byte buffer[ 4 ];
+ unsigned long insn = 0;
+
+ /* First figure out how big the opcode is. */
+
+ status = info->read_memory_func (memaddr, buffer, 2, info);
+ if (status == 0)
+ {
+ insn = bfd_getl16 (buffer);
+
+ if ( (insn & 0x0600) == 0x0600
+ && (insn & 0xffe0) != 0x0620)
+ {
+ /* If this is a 4 byte insn, read 4 bytes of stuff. */
+ status = info->read_memory_func (memaddr, buffer, 4, info);
+
+ if (status == 0)
+ insn = bfd_getl32 (buffer);
+ }
+ }
+
+ if (status != 0)
+ {
+ info->memory_error_func (status, memaddr, info);
+ return -1;
+ }
+
+ /* Make sure we tell our caller how many bytes we consumed. */
+ return disassemble (memaddr, info, insn);
+}
diff --git a/opcodes/v850-opc.c b/opcodes/v850-opc.c
new file mode 100644
index 00000000000..d34857efa10
--- /dev/null
+++ b/opcodes/v850-opc.c
@@ -0,0 +1,786 @@
+/* Assemble V850 instructions.
+ Copyright (C) 1996 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "opcode/v850.h"
+#include <stdio.h>
+#include "opintl.h"
+
+/* regular opcode */
+#define OP(x) ((x & 0x3f) << 5)
+#define OP_MASK OP (0x3f)
+
+/* conditional branch opcode */
+#define BOP(x) ((0x0b << 7) | (x & 0x0f))
+#define BOP_MASK ((0x0f << 7) | 0x0f)
+
+/* one-word opcodes */
+#define one(x) ((unsigned int) (x))
+
+/* two-word opcodes */
+#define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16))
+
+
+
+/* The functions used to insert and extract complicated operands. */
+
+/* Note: There is a conspiracy between these functions and
+ v850_insert_operand() in gas/config/tc-v850.c. Error messages
+ containing the string 'out of range' will be ignored unless a
+ specific command line option is given to GAS. */
+
+static const char * not_valid = N_ ("displacement value is not in range and is not aligned");
+static const char * out_of_range = N_ ("displacement value is out of range");
+static const char * not_aligned = N_ ("displacement value is not aligned");
+
+static const char * immediate_out_of_range = N_ ("immediate value is out of range");
+
+static unsigned long
+insert_d9 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char ** errmsg;
+{
+ if (value > 0xff || value < -0x100)
+ {
+ if ((value % 2) != 0)
+ * errmsg = _("branch value not in range and to odd offset");
+ else
+ * errmsg = _("branch value out of range");
+ }
+ else if ((value % 2) != 0)
+ * errmsg = _("branch to odd offset");
+
+ return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3));
+}
+
+static unsigned long
+extract_d9 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
+
+ if ((insn & 0x8000) != 0)
+ ret -= 0x0200;
+
+ return ret;
+}
+
+static unsigned long
+insert_d22 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char ** errmsg;
+{
+ if (value > 0x1fffff || value < -0x200000)
+ {
+ if ((value % 2) != 0)
+ * errmsg = _("branch value not in range and to an odd offset");
+ else
+ * errmsg = _("branch value out of range");
+ }
+ else if ((value % 2) != 0)
+ * errmsg = _("branch to odd offset");
+
+ return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16));
+}
+
+static unsigned long
+extract_d22 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
+
+ return (unsigned long) ((ret << 10) >> 10);
+}
+
+static unsigned long
+insert_d16_15 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char ** errmsg;
+{
+ if (value > 0x7fff || value < -0x8000)
+ {
+ if ((value % 2) != 0)
+ * errmsg = _(not_valid);
+ else
+ * errmsg = _(out_of_range);
+ }
+ else if ((value % 2) != 0)
+ * errmsg = _(not_aligned);
+
+ return insn | ((value & 0xfffe) << 16);
+}
+
+static unsigned long
+extract_d16_15 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ signed long ret = (insn & 0xfffe0000);
+
+ return ret >> 16;
+}
+
+static unsigned long
+insert_d8_7 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char ** errmsg;
+{
+ if (value > 0xff || value < 0)
+ {
+ if ((value % 2) != 0)
+ * errmsg = _(not_valid);
+ else
+ * errmsg = _(out_of_range);
+ }
+ else if ((value % 2) != 0)
+ * errmsg = _(not_aligned);
+
+ value >>= 1;
+
+ return (insn | (value & 0x7f));
+}
+
+static unsigned long
+extract_d8_7 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ unsigned long ret = (insn & 0x7f);
+
+ return ret << 1;
+}
+
+static unsigned long
+insert_d8_6 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char ** errmsg;
+{
+ if (value > 0xff || value < 0)
+ {
+ if ((value % 4) != 0)
+ *errmsg = _(not_valid);
+ else
+ * errmsg = _(out_of_range);
+ }
+ else if ((value % 4) != 0)
+ * errmsg = _(not_aligned);
+
+ value >>= 1;
+
+ return (insn | (value & 0x7e));
+}
+
+static unsigned long
+extract_d8_6 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ unsigned long ret = (insn & 0x7e);
+
+ return ret << 1;
+}
+
+static unsigned long
+insert_d5_4 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char ** errmsg;
+{
+ if (value > 0x1f || value < 0)
+ {
+ if (value & 1)
+ * errmsg = _(not_valid);
+ else
+ *errmsg = _(out_of_range);
+ }
+ else if (value & 1)
+ * errmsg = _(not_aligned);
+
+ value >>= 1;
+
+ return (insn | (value & 0x0f));
+}
+
+static unsigned long
+extract_d5_4 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ unsigned long ret = (insn & 0x0f);
+
+ return ret << 1;
+}
+
+static unsigned long
+insert_d16_16 (insn, value, errmsg)
+ unsigned long insn;
+ signed long value;
+ const char ** errmsg;
+{
+ if (value > 0x7fff || value < -0x8000)
+ * errmsg = _(out_of_range);
+
+ return (insn | ((value & 0xfffe) << 16) | ((value & 1) << 5));
+}
+
+static unsigned long
+extract_d16_16 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ signed long ret = insn & 0xfffe0000;
+
+ ret >>= 16;
+
+ ret |= ((insn & 0x20) >> 5);
+
+ return ret;
+}
+
+static unsigned long
+insert_i9 (insn, value, errmsg)
+ unsigned long insn;
+ signed long value;
+ const char ** errmsg;
+{
+ if (value > 0xff || value < -0x100)
+ * errmsg = _(immediate_out_of_range);
+
+ return insn | ((value & 0x1e0) << 13) | (value & 0x1f);
+}
+
+static unsigned long
+extract_i9 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ signed long ret = insn & 0x003c0000;
+
+ ret <<= 10;
+ ret >>= 23;
+
+ ret |= (insn & 0x1f);
+
+ return ret;
+}
+
+static unsigned long
+insert_u9 (insn, value, errmsg)
+ unsigned long insn;
+ unsigned long value;
+ const char ** errmsg;
+{
+ if (value > 0x1ff)
+ * errmsg = _(immediate_out_of_range);
+
+ return insn | ((value & 0x1e0) << 13) | (value & 0x1f);
+}
+
+static unsigned long
+extract_u9 (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ unsigned long ret = insn & 0x003c0000;
+
+ ret >>= 13;
+
+ ret |= (insn & 0x1f);
+
+ return ret;
+}
+
+static unsigned long
+insert_spe (insn, value, errmsg)
+ unsigned long insn;
+ unsigned long value;
+ const char ** errmsg;
+{
+ if (value != 3)
+ * errmsg = _("invalid register for stack adjustment");
+
+ return insn & (~ 0x180000);
+}
+
+static unsigned long
+extract_spe (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ return 3;
+}
+
+static unsigned long
+insert_i5div (insn, value, errmsg)
+ unsigned long insn;
+ unsigned long value;
+ const char ** errmsg;
+{
+ if (value > 0x1ff)
+ {
+ if (value & 1)
+ * errmsg = _("immediate value not in range and not even");
+ else
+ * errmsg = _(immediate_out_of_range);
+ }
+ else if (value & 1)
+ * errmsg = _("immediate value must be even");
+
+ value = 32 - value;
+
+ return insn | ((value & 0x1e) << 17);
+}
+
+static unsigned long
+extract_i5div (insn, invalid)
+ unsigned long insn;
+ int * invalid;
+{
+ unsigned long ret = insn & 0x3c0000;
+
+ ret >>= 17;
+
+ ret = 32 - ret;
+
+ return ret;
+}
+
+
+/* Warning: code in gas/config/tc-v850.c examines the contents of this array.
+ If you change any of the values here, be sure to look for side effects in
+ that code. */
+const struct v850_operand v850_operands[] =
+{
+#define UNUSED 0
+ { 0, 0, NULL, NULL, 0 },
+
+/* The R1 field in a format 1, 6, 7, or 9 insn. */
+#define R1 (UNUSED + 1)
+ { 5, 0, NULL, NULL, V850_OPERAND_REG },
+
+/* As above, but register 0 is not allowed. */
+#define R1_NOTR0 (R1 + 1)
+ { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
+
+/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */
+#define R2 (R1_NOTR0 + 1)
+ { 5, 11, NULL, NULL, V850_OPERAND_REG },
+
+/* As above, but register 0 is not allowed. */
+#define R2_NOTR0 (R2 + 1)
+ { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
+
+/* The imm5 field in a format 2 insn. */
+#define I5 (R2_NOTR0 + 1)
+ { 5, 0, NULL, NULL, V850_OPERAND_SIGNED },
+
+/* The unsigned imm5 field in a format 2 insn. */
+#define I5U (I5 + 1)
+ { 5, 0, NULL, NULL, 0 },
+
+/* The imm16 field in a format 6 insn. */
+#define I16 (I5U + 1)
+ { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
+
+/* The signed disp7 field in a format 4 insn. */
+#define D7 (I16 + 1)
+ { 7, 0, NULL, NULL, 0},
+
+/* The disp16 field in a format 6 insn. */
+#define D16_15 (D7 + 1)
+ { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED },
+
+/* The 3 bit immediate field in format 8 insn. */
+#define B3 (D16_15 + 1)
+ { 3, 11, NULL, NULL, 0 },
+
+/* The 4 bit condition code in a setf instruction */
+#define CCCC (B3 + 1)
+ { 4, 0, NULL, NULL, V850_OPERAND_CC },
+
+/* The unsigned DISP8 field in a format 4 insn. */
+#define D8_7 (CCCC + 1)
+ { 7, 0, insert_d8_7, extract_d8_7, 0 },
+
+/* The unsigned DISP8 field in a format 4 insn. */
+#define D8_6 (D8_7 + 1)
+ { 6, 1, insert_d8_6, extract_d8_6, 0 },
+
+/* System register operands. */
+#define SR1 (D8_6 + 1)
+ { 5, 0, NULL, NULL, V850_OPERAND_SRG },
+
+/* EP Register. */
+#define EP (SR1 + 1)
+ { 0, 0, NULL, NULL, V850_OPERAND_EP },
+
+/* The imm16 field (unsigned) in a format 6 insn. */
+#define I16U (EP + 1)
+ { 16, 16, NULL, NULL, 0},
+
+/* The R2 field as a system register. */
+#define SR2 (I16U + 1)
+ { 5, 11, NULL, NULL, V850_OPERAND_SRG },
+
+/* The disp16 field in a format 8 insn. */
+#define D16 (SR2 + 1)
+ { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
+
+/* The DISP9 field in a format 3 insn, relaxable. */
+#define D9_RELAX (D16 + 1)
+ { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP },
+
+/* The DISP22 field in a format 4 insn, relaxable.
+ This _must_ follow D9_RELAX; the assembler assumes that the longer
+ version immediately follows the shorter version for relaxing. */
+#define D22 (D9_RELAX + 1)
+ { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP },
+
+/* The signed disp4 field in a format 4 insn. */
+#define D4 (D22 + 1)
+ { 4, 0, NULL, NULL, 0},
+
+/* The unsigned disp5 field in a format 4 insn. */
+#define D5_4 (D4 + 1)
+ { 4, 0, insert_d5_4, extract_d5_4, 0 },
+
+/* The disp16 field in an format 7 unsigned byte load insn. */
+#define D16_16 (D5_4 + 1)
+ { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 },
+
+/* Third register in conditional moves. */
+#define R3 (D16_16 + 1)
+ { 5, 27, NULL, NULL, V850_OPERAND_REG },
+
+/* Condition code in conditional moves. */
+#define MOVCC (R3 + 1)
+ { 4, 17, NULL, NULL, V850_OPERAND_CC },
+
+/* The imm9 field in a multiply word. */
+#define I9 (MOVCC + 1)
+ { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED },
+
+/* The unsigned imm9 field in a multiply word. */
+#define U9 (I9 + 1)
+ { 9, 0, insert_u9, extract_u9, 0 },
+
+/* A list of registers in a prepare/dispose instruction. */
+#define LIST12 (U9 + 1)
+ { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP },
+
+/* The IMM6 field in a call instruction. */
+#define I6 (LIST12 + 1)
+ { 6, 0, NULL, NULL, 0 },
+
+/* The 16 bit immediate following a 32 bit instruction. */
+#define IMM16 (I6 + 1)
+ { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 },
+
+/* The 32 bit immediate following a 32 bit instruction. */
+#define IMM32 (IMM16 + 1)
+ { 0, 0, NULL, NULL, V850E_IMMEDIATE32 },
+
+/* The imm5 field in a push/pop instruction. */
+#define IMM5 (IMM32 + 1)
+ { 5, 1, NULL, NULL, 0 },
+
+/* Reg2 in dispose instruction. */
+#define R2DISPOSE (IMM5 + 1)
+ { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
+
+/* Stack pointer in prepare instruction. */
+#define SP (R2DISPOSE + 1)
+ { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG },
+
+/* The IMM5 field in a divide N step instruction. */
+#define I5DIV (SP + 1)
+ { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED },
+
+ /* The list of registers in a PUSHMH/POPMH instruction. */
+#define LIST18_H (I5DIV + 1)
+ { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP },
+
+ /* The list of registers in a PUSHML/POPML instruction. */
+#define LIST18_L (LIST18_H + 1)
+ { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP }, /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c */
+} ;
+
+
+/* reg-reg instruction format (Format I) */
+#define IF1 {R1, R2}
+
+/* imm-reg instruction format (Format II) */
+#define IF2 {I5, R2}
+
+/* conditional branch instruction format (Format III) */
+#define IF3 {D9_RELAX}
+
+/* 3 operand instruction (Format VI) */
+#define IF6 {I16, R1, R2}
+
+/* 3 operand instruction (Format VI) */
+#define IF6U {I16U, R1, R2}
+
+
+
+/* The opcode table.
+
+ The format of the opcode table is:
+
+ NAME OPCODE MASK { OPERANDS } MEMOP PROCESSOR
+
+ NAME is the name of the instruction.
+ OPCODE is the instruction opcode.
+ MASK is the opcode mask; this is used to tell the disassembler
+ which bits in the actual opcode must match OPCODE.
+ OPERANDS is the list of operands.
+ MEMOP specifies which operand (if any) is a memory operand.
+ PROCESSORS specifies which CPU(s) support the opcode.
+
+ The disassembler reads the table in order and prints the first
+ instruction which matches, so this table is sorted to put more
+ specific instructions before more general instructions. It is also
+ sorted by major opcode.
+
+ The table is also sorted by name. This is used by the assembler.
+ When parsing an instruction the assembler finds the first occurance
+ of the name of the instruciton in this table and then attempts to
+ match the instruction's arguments with description of the operands
+ associated with the entry it has just found in this table. If the
+ match fails the assembler looks at the next entry in this table.
+ If that entry has the same name as the previous entry, then it
+ tries to match the instruction against that entry and so on. This
+ is how the assembler copes with multiple, different formats of the
+ same instruction. */
+
+const struct v850_opcode v850_opcodes[] =
+{
+{ "breakpoint", 0xffff, 0xffff, {UNUSED}, 0, PROCESSOR_ALL },
+
+{ "jmp", one (0x0060), one (0xffe0), {R1}, 1, PROCESSOR_ALL },
+
+/* load/store instructions */
+{ "sld.bu", one (0x0300), one (0x0780), {D7, EP, R2_NOTR0}, 1, PROCESSOR_V850EA },
+{ "sld.bu", one (0x0060), one (0x07f0), {D4, EP, R2_NOTR0}, 1, PROCESSOR_V850E },
+
+{ "sld.hu", one (0x0400), one (0x0780), {D8_7, EP, R2_NOTR0}, 1, PROCESSOR_V850EA },
+{ "sld.hu", one (0x0070), one (0x07f0), {D5_4, EP, R2_NOTR0}, 1, PROCESSOR_V850E },
+
+{ "sld.b", one (0x0060), one (0x07f0), {D4, EP, R2}, 1, PROCESSOR_V850EA },
+{ "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850E },
+{ "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850 },
+
+{ "sld.h", one (0x0070), one (0x07f0), {D5_4, EP, R2}, 1, PROCESSOR_V850EA },
+{ "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850E },
+{ "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850 },
+{ "sld.w", one (0x0500), one (0x0781), {D8_6, EP, R2}, 1, PROCESSOR_ALL },
+{ "sst.b", one (0x0380), one (0x0780), {R2, D7, EP}, 2, PROCESSOR_ALL },
+{ "sst.h", one (0x0480), one (0x0780), {R2, D8_7, EP}, 2, PROCESSOR_ALL },
+{ "sst.w", one (0x0501), one (0x0781), {R2, D8_6, EP}, 2, PROCESSOR_ALL },
+
+{ "pushml", two (0x07e0, 0x0001), two (0xfff0, 0x0007), {LIST18_L}, 0, PROCESSOR_V850EA },
+{ "pushmh", two (0x07e0, 0x0003), two (0xfff0, 0x0007), {LIST18_H}, 0, PROCESSOR_V850EA },
+{ "popml", two (0x07f0, 0x0001), two (0xfff0, 0x0007), {LIST18_L}, 0, PROCESSOR_V850EA },
+{ "popmh", two (0x07f0, 0x0003), two (0xfff0, 0x0007), {LIST18_H}, 0, PROCESSOR_V850EA },
+{ "prepare", two (0x0780, 0x0003), two (0xffc0, 0x001f), {LIST12, IMM5, SP}, 0, PROCESSOR_NOT_V850 },
+{ "prepare", two (0x0780, 0x000b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 },
+{ "prepare", two (0x0780, 0x0013), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 },
+{ "prepare", two (0x0780, 0x001b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM32}, 0, PROCESSOR_NOT_V850 },
+{ "prepare", two (0x0780, 0x0001), two (0xffc0, 0x001f), {LIST12, IMM5}, 0, PROCESSOR_NOT_V850 },
+{ "dispose", one (0x0640), one (0xffc0), {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 },
+{ "dispose", two (0x0640, 0x0000), two (0xffc0, 0x001f), {IMM5, LIST12}, 0, PROCESSOR_NOT_V850 },
+
+{ "ld.b", two (0x0700, 0x0000), two (0x07e0, 0x0000), {D16, R1, R2}, 1, PROCESSOR_ALL },
+{ "ld.h", two (0x0720, 0x0000), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL },
+{ "ld.w", two (0x0720, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL },
+{ "ld.bu", two (0x0780, 0x0001), two (0x07c0, 0x0001), {D16_16, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
+{ "ld.hu", two (0x07e0, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 },
+{ "st.b", two (0x0740, 0x0000), two (0x07e0, 0x0000), {R2, D16, R1}, 2, PROCESSOR_ALL },
+{ "st.h", two (0x0760, 0x0000), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL },
+{ "st.w", two (0x0760, 0x0001), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL },
+
+/* byte swap/extend instructions */
+{ "zxb", one (0x0080), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
+{ "zxh", one (0x00c0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
+{ "sxb", one (0x00a0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
+{ "sxh", one (0x00e0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
+{ "bsh", two (0x07e0, 0x0342), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "bsw", two (0x07e0, 0x0340), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "hsw", two (0x07e0, 0x0344), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 },
+
+/* jump table instructions */
+{ "switch", one (0x0040), one (0xffe0), {R1}, 1, PROCESSOR_NOT_V850 },
+{ "callt", one (0x0200), one (0xffc0), {I6}, 0, PROCESSOR_NOT_V850 },
+{ "ctret", two (0x07e0, 0x0144), two (0xffff, 0xffff), {0}, 0, PROCESSOR_NOT_V850 },
+
+/* arithmetic operation instructions */
+{ "setf", two (0x07e0, 0x0000), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_ALL },
+{ "cmov", two (0x07e0, 0x0320), two (0x07e0, 0x07e1), {MOVCC, R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "cmov", two (0x07e0, 0x0300), two (0x07e0, 0x07e1), {MOVCC, I5, R2, R3}, 0, PROCESSOR_NOT_V850 },
+
+{ "mul", two (0x07e0, 0x0220), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "mul", two (0x07e0, 0x0240), two (0x07e0, 0x07c3), {I9, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "mulu", two (0x07e0, 0x0222), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "mulu", two (0x07e0, 0x0242), two (0x07e0, 0x07c3), {U9, R2, R3}, 0, PROCESSOR_NOT_V850 },
+
+{ "div", two (0x07e0, 0x02c0), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "divu", two (0x07e0, 0x02c2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "divhu", two (0x07e0, 0x0282), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "divh", two (0x07e0, 0x0280), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 },
+{ "divh", OP (0x02), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+
+{ "divhn", two (0x07e0, 0x0280), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "divhun", two (0x07e0, 0x0282), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "divn", two (0x07e0, 0x02c0), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "divun", two (0x07e0, 0x02c2), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "sdivhn", two (0x07e0, 0x0180), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "sdivhun", two (0x07e0, 0x0182), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "sdivn", two (0x07e0, 0x01c0), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+{ "sdivun", two (0x07e0, 0x01c2), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA },
+
+{ "nop", one (0x00), one (0xffff), {0}, 0, PROCESSOR_ALL },
+{ "mov", OP (0x10), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "mov", one (0x0620), one (0xffe0), {IMM32, R1_NOTR0}, 0, PROCESSOR_NOT_V850 },
+{ "mov", OP (0x00), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "movea", OP (0x31), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "movhi", OP (0x32), OP_MASK, {I16U, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "add", OP (0x0e), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "add", OP (0x12), OP_MASK, IF2, 0, PROCESSOR_ALL },
+{ "addi", OP (0x30), OP_MASK, IF6, 0, PROCESSOR_ALL },
+{ "sub", OP (0x0d), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "subr", OP (0x0c), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "mulh", OP (0x17), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "mulh", OP (0x07), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "mulhi", OP (0x37), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "cmp", OP (0x0f), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "cmp", OP (0x13), OP_MASK, IF2, 0, PROCESSOR_ALL },
+
+/* saturated operation instructions */
+{ "satadd", OP (0x11), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "satadd", OP (0x06), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "satsub", OP (0x05), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "satsubi", OP (0x33), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+{ "satsubr", OP (0x04), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL },
+
+/* logical operation instructions */
+{ "tst", OP (0x0b), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "or", OP (0x08), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "ori", OP (0x34), OP_MASK, IF6U, 0, PROCESSOR_ALL },
+{ "and", OP (0x0a), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "andi", OP (0x36), OP_MASK, IF6U, 0, PROCESSOR_ALL },
+{ "xor", OP (0x09), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "xori", OP (0x35), OP_MASK, IF6U, 0, PROCESSOR_ALL },
+{ "not", OP (0x01), OP_MASK, IF1, 0, PROCESSOR_ALL },
+{ "sar", OP (0x15), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL },
+{ "sar", two (0x07e0, 0x00a0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL },
+{ "shl", OP (0x16), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL },
+{ "shl", two (0x07e0, 0x00c0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL },
+{ "shr", OP (0x14), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL },
+{ "shr", two (0x07e0, 0x0080), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL },
+{ "sasf", two (0x07e0, 0x0200), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_NOT_V850 },
+
+/* branch instructions */
+ /* signed integer */
+{ "bgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "blt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "ble", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+ /* unsigned integer */
+{ "bh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+ /* common */
+{ "be", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+ /* others */
+{ "bv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "br", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "bsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+
+/* Branch macros.
+
+ We use the short form in the opcode/mask fields. The assembler
+ will twiddle bits as necessary if the long form is needed. */
+
+ /* signed integer */
+{ "jgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jlt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jle", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+ /* unsigned integer */
+{ "jh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+ /* common */
+{ "je", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+ /* others */
+{ "jv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+{ "jbr", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL },
+
+{ "jr", one (0x0780), two (0xffc0, 0x0001), {D22}, 0, PROCESSOR_ALL },
+{ "jarl", one (0x0780), two (0x07c0, 0x0001), {D22, R2}, 0, PROCESSOR_ALL},
+
+/* bit manipulation instructions */
+{ "set1", two (0x07c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
+{ "set1", two (0x07e0, 0x00e0), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
+{ "not1", two (0x47c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
+{ "not1", two (0x07e0, 0x00e2), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
+{ "clr1", two (0x87c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
+{ "clr1", two (0x07e0, 0x00e4), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
+{ "tst1", two (0xc7c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL },
+{ "tst1", two (0x07e0, 0x00e6), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 },
+
+/* special instructions */
+{ "di", two (0x07e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
+{ "ei", two (0x87e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
+{ "halt", two (0x07e0, 0x0120), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
+{ "reti", two (0x07e0, 0x0140), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL },
+{ "trap", two (0x07e0, 0x0100), two (0xffe0, 0xffff), {I5U}, 0, PROCESSOR_ALL },
+{ "ldsr", two (0x07e0, 0x0020), two (0x07e0, 0xffff), {R1, SR2}, 0, PROCESSOR_ALL },
+{ "stsr", two (0x07e0, 0x0040), two (0x07e0, 0xffff), {SR1, R2}, 0, PROCESSOR_ALL },
+{ 0, 0, 0, {0}, 0, 0 },
+
+} ;
+
+const int v850_num_opcodes =
+ sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);
+
diff --git a/opcodes/vax-dis.c b/opcodes/vax-dis.c
new file mode 100644
index 00000000000..54b59f30d40
--- /dev/null
+++ b/opcodes/vax-dis.c
@@ -0,0 +1,299 @@
+/* Print VAX instructions.
+ Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "opcode/vax.h"
+#include "dis-asm.h"
+
+/* Local function prototypes */
+static int
+print_insn_arg PARAMS ((const char *, unsigned char *, bfd_vma,
+ disassemble_info *));
+
+static int
+print_insn_mode PARAMS ((int, unsigned char *, bfd_vma, disassemble_info *));
+
+static char *reg_names[] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
+};
+
+/* Sign-extend an (unsigned char). */
+#if __STDC__ == 1
+#define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
+#else
+#define COERCE_SIGNED_CHAR(ch) ((int)(((ch) ^ 0x80) & 0xFF) - 128)
+#endif
+
+/* Get a 1 byte signed integer. */
+#define NEXTBYTE(p) \
+ (p += 1, FETCH_DATA (info, p), \
+ COERCE_SIGNED_CHAR(p[-1]))
+
+/* Get a 2 byte signed integer. */
+#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
+#define NEXTWORD(p) \
+ (p += 2, FETCH_DATA (info, p), \
+ COERCE16 ((p[-1] << 8) + p[-2]))
+
+/* Get a 4 byte signed integer. */
+#define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
+#define NEXTLONG(p) \
+ (p += 4, FETCH_DATA (info, p), \
+ (COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
+
+/* Maximum length of an instruction. */
+#define MAXLEN 25
+
+#include <setjmp.h>
+
+struct private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+ struct disassemble_info *info;
+ bfd_byte *addr;
+{
+ int status;
+ struct private *priv = (struct private *) info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ longjmp (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+
+ return 1;
+}
+
+/* Print the vax instruction at address MEMADDR in debugged memory,
+ on INFO->STREAM. Returns length of the instruction, in bytes. */
+
+int
+print_insn_vax (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info *info;
+{
+ const struct vot *votp;
+ const char *argp = NULL;
+ unsigned char *arg;
+ struct private priv;
+ bfd_byte *buffer = priv.the_buffer;
+
+ info->private_data = (PTR) &priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = memaddr;
+ if (setjmp (priv.bailout) != 0)
+ {
+ /* Error return. */
+ return -1;
+ }
+
+ FETCH_DATA (info, buffer + 2);
+ for (votp = &votstrs[0]; votp->name[0]; votp++)
+ {
+ register vax_opcodeT opcode = votp->detail.code;
+
+ /* 2 byte codes match 2 buffer pos. */
+ if ((bfd_byte) opcode == buffer[0]
+ && (opcode >> 8 == 0 || opcode >> 8 == buffer[1]))
+ {
+ argp = votp->detail.args;
+ break;
+ }
+ }
+ if (argp == NULL)
+ {
+ /* Handle undefined instructions. */
+ (*info->fprintf_func) (info->stream, ".word 0x%x",
+ (buffer[0] << 8) + buffer[1]);
+ return 2;
+ }
+
+ /* Point at first byte of argument data, and at descriptor for first
+ argument. */
+ arg = buffer + ((votp->detail.code >> 8) ? 2 : 1);
+
+ /* Make sure we have it in mem */
+ FETCH_DATA (info, arg);
+
+ (*info->fprintf_func) (info->stream, "%s", votp->name);
+ if (*argp)
+ (*info->fprintf_func) (info->stream, " ");
+
+ while (*argp)
+ {
+ arg += print_insn_arg (argp, arg, memaddr + arg - buffer, info);
+ argp += 2;
+ if (*argp)
+ (*info->fprintf_func) (info->stream, ",");
+ }
+
+ return arg - buffer;
+}
+
+/* Returns number of bytes "eaten" by the operand, or return -1 if an
+ invalid operand was found, or -2 if an opcode tabel error was
+ found. */
+
+static int
+print_insn_arg (d, p0, addr, info)
+ const char *d;
+ unsigned char *p0;
+ bfd_vma addr; /* PC for this arg to be relative to */
+ disassemble_info *info;
+{
+ int arg_len;
+
+ /* check validity of addressing length */
+ switch (d[1])
+ {
+ case 'b' : arg_len = 1; break;
+ case 'd' : arg_len = 8; break;
+ case 'f' : arg_len = 4; break;
+ case 'g' : arg_len = 8; break;
+ case 'h' : arg_len = 16; break;
+ case 'l' : arg_len = 4; break;
+ case 'o' : arg_len = 16; break;
+ case 'w' : arg_len = 2; break;
+ case 'q' : arg_len = 8; break;
+ default : abort();
+ }
+
+ /* branches have no mode byte */
+ if (d[0] == 'b')
+ {
+ unsigned char *p = p0;
+
+ if (arg_len == 1)
+ (*info->print_address_func) (addr + 1 + NEXTBYTE (p), info);
+ else
+ (*info->print_address_func) (addr + 2 + NEXTWORD (p), info);
+
+ return p - p0;
+ }
+
+ return print_insn_mode (arg_len, p0, addr, info);
+}
+
+static int
+print_insn_mode (size, p0, addr, info)
+ int size;
+ unsigned char *p0;
+ bfd_vma addr; /* PC for this arg to be relative to */
+ disassemble_info *info;
+{
+ unsigned char *p = p0;
+ unsigned char mode, reg;
+
+ /* fetch and interpret mode byte */
+ mode = (unsigned char) NEXTBYTE (p);
+ reg = mode & 0xF;
+ switch (mode & 0xF0)
+ {
+ case 0x00:
+ case 0x10:
+ case 0x20:
+ case 0x30: /* literal mode $number */
+ (*info->fprintf_func) (info->stream, "$0x%x", mode);
+ break;
+ case 0x40: /* index: base-addr[Rn] */
+ p += print_insn_mode (size, p0 + 1, addr + 1, info);
+ (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
+ break;
+ case 0x50: /* register: Rn */
+ (*info->fprintf_func) (info->stream, "%s", reg_names[reg]);
+ break;
+ case 0x60: /* register deferred: (Rn) */
+ (*info->fprintf_func) (info->stream, "(%s)", reg_names[reg]);
+ break;
+ case 0x70: /* autodecrement: -(Rn) */
+ (*info->fprintf_func) (info->stream, "-(%s)", reg_names[reg]);
+ break;
+ case 0x80: /* autoincrement: (Rn)+ */
+ if (reg == 0xF)
+ { /* immediate? */
+ int i;
+
+ FETCH_DATA (info, p + size);
+ (*info->fprintf_func) (info->stream, "$0x");
+ for (i = 0; i < size; i++)
+ (*info->fprintf_func) (info->stream, "%02x", p[size - i - 1]);
+ p += size;
+ }
+ else
+ (*info->fprintf_func) (info->stream, "(%s)+", reg_names[reg]);
+ break;
+ case 0x90: /* autoincrement deferred: @(Rn)+ */
+ if (reg == 0xF)
+ (*info->fprintf_func) (info->stream, "*0x%x", NEXTLONG (p));
+ else
+ (*info->fprintf_func) (info->stream, "@(%s)+", reg_names[reg]);
+ break;
+ case 0xB0: /* displacement byte deferred: *displ(Rn) */
+ (*info->fprintf_func) (info->stream, "*");
+ case 0xA0: /* displacement byte: displ(Rn) */
+ if (reg == 0xF)
+ (*info->print_address_func) (addr + 2 + NEXTBYTE (p), info);
+ else
+ (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTBYTE (p),
+ reg_names[reg]);
+ break;
+ case 0xD0: /* displacement word deferred: *displ(Rn) */
+ (*info->fprintf_func) (info->stream, "*");
+ case 0xC0: /* displacement word: displ(Rn) */
+ if (reg == 0xF)
+ (*info->print_address_func) (addr + 3 + NEXTWORD (p), info);
+ else
+ (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTWORD (p),
+ reg_names[reg]);
+ break;
+ case 0xF0: /* displacement long deferred: *displ(Rn) */
+ (*info->fprintf_func) (info->stream, "*");
+ case 0xE0: /* displacement long: displ(Rn) */
+ if (reg == 0xF)
+ (*info->print_address_func) (addr + 5 + NEXTLONG (p), info);
+ else
+ (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTLONG (p),
+ reg_names[reg]);
+ break;
+ }
+
+ return p - p0;
+}
diff --git a/opcodes/w65-dis.c b/opcodes/w65-dis.c
new file mode 100644
index 00000000000..a12e896de67
--- /dev/null
+++ b/opcodes/w65-dis.c
@@ -0,0 +1,118 @@
+/* Disassemble WDC 65816 instructions.
+ Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#define STATIC_TABLE
+#define DEFINE_TABLE
+
+#include "w65-opc.h"
+#include "dis-asm.h"
+
+static fprintf_ftype fpr;
+static void *stream;
+static struct disassemble_info *local_info;
+#if 0
+static char *lname[] = {"r0","r1","r2","r3","r4","r5","r6","r7","s0"};
+
+static char *findname (val)
+ unsigned int val;
+{
+ if (val >= 0x10 && val <= 0x20)
+ return lname[(val - 0x10) / 2];
+ return 0;
+}
+#endif
+static void
+print_operand (lookup, format, args)
+ int lookup;
+ char *format;
+ unsigned int *args;
+{
+ int val;
+ int c;
+
+ while (*format)
+ {
+ switch ( c = *format++)
+ {
+ case '$':
+ val = args[(*format++) - '0'];
+ if (lookup)
+ {
+#if 0
+ name = findname(val);
+ if (name)
+ fpr(stream, "%s", name);
+ else
+#endif
+ local_info->print_address_func (val, local_info);
+ }
+ else
+ fpr (stream, "0x%x", val);
+
+ break;
+ default:
+ fpr(stream,"%c", c);
+ break;
+ }
+ }
+}
+int
+print_insn_w65(memaddr, info)
+ bfd_vma memaddr;
+ struct disassemble_info *info;
+{
+
+
+ int status = 0;
+ unsigned char insn[4];
+ register struct opinfo *op;
+ int i;
+ int X =0;
+ int M = 0;
+ int args[2];
+stream = info->stream;
+ fpr = info->fprintf_func;
+local_info = info;
+ for (i = 0; i <4 && status == 0; i++)
+ {
+ status = info->read_memory_func(memaddr+i, insn + i, 1, info);
+ }
+
+
+ for (op = optable; op->val != insn[0]; op++)
+ ;
+
+ fpr(stream,"%s", op->name);
+
+ /* Prepare all the posible operand values */
+ {
+ int size = 1;
+ int asR_W65_ABS8 = insn[1];
+ int asR_W65_ABS16 = (insn[2] << 8) + asR_W65_ABS8;
+ int asR_W65_ABS24 = (insn[3] << 16) + asR_W65_ABS16;
+ int asR_W65_PCR8 = ((char)(asR_W65_ABS8)) + memaddr + 2;
+ int asR_W65_PCR16 = ((short)(asR_W65_ABS16)) + memaddr + 3;
+
+ switch (op->amode) {
+ DISASM();
+ }
+
+ return size;
+ }
+
+}
diff --git a/opcodes/w65-opc.h b/opcodes/w65-opc.h
new file mode 100644
index 00000000000..9dc3535c787
--- /dev/null
+++ b/opcodes/w65-opc.h
@@ -0,0 +1,548 @@
+ /* WDC 65816 Assembler opcode table */
+ /* (generated by the program sim/w65/gencode -a) */
+#define ADDR_IMMTOA 1 /* #a */
+#define ADDR_IMMCOP 2 /* #c */
+#define ADDR_IMMTOI 3 /* #i */
+#define ADDR_ACC 4 /* A */
+#define ADDR_PC_REL 5 /* r */
+#define ADDR_PC_REL_LONG 6 /* rl */
+#define ADDR_IMPLIED 7 /* i */
+#define ADDR_STACK 8 /* s */
+#define ADDR_DIR 9 /* d */
+#define ADDR_DIR_IDX_X 10 /* d,x */
+#define ADDR_DIR_IDX_Y 11 /* d,y */
+#define ADDR_DIR_IND 12 /* (d) */
+#define ADDR_DIR_IDX_IND_X 13 /* (d,x) */
+#define ADDR_DIR_IND_IDX_Y 14 /* (d),y */
+#define ADDR_DIR_IND_LONG 15 /* [d] */
+#define ADDR_DIR_IND_IDX_Y_LONG 16 /* [d],y */
+#define ADDR_ABS 17 /* a */
+#define ADDR_ABS_IDX_X 18 /* a,x */
+#define ADDR_ABS_IDX_Y 19 /* a,y */
+#define ADDR_ABS_LONG 20 /* al */
+#define ADDR_ABS_IND_LONG 21 /* [a] */
+#define ADDR_ABS_LONG_IDX_X 22 /* al,x */
+#define ADDR_STACK_REL 23 /* d,s */
+#define ADDR_STACK_REL_INDX_IDX 24 /* (d,s),y */
+#define ADDR_ABS_IND 25 /* (a) */
+#define ADDR_ABS_IND_IDX 26 /* (a,x) */
+#define ADDR_BLOCK_MOVE 27 /* xyz */
+struct opinfo {
+ int val;
+ int code;
+ char *name;
+ int amode;
+};
+struct opinfo optable[257]={
+#define O_adc 1
+#define O_and 2
+#define O_asl 3
+#define O_bcc 4
+#define O_bcs 5
+#define O_beq 6
+#define O_bit 7
+#define O_bmi 8
+#define O_bne 9
+#define O_bpl 10
+#define O_bra 11
+#define O_brk 12
+#define O_brl 13
+#define O_bvc 14
+#define O_bvs 15
+#define O_clc 16
+#define O_cld 17
+#define O_cli 18
+#define O_clv 19
+#define O_cmp 20
+#define O_cop 21
+#define O_cpx 22
+#define O_cpy 23
+#define O_dec 24
+#define O_dex 25
+#define O_dey 26
+#define O_eor 27
+#define O_inc 28
+#define O_inx 29
+#define O_iny 30
+#define O_jmp 31
+#define O_jsr 32
+#define O_lda 33
+#define O_ldx 34
+#define O_ldy 35
+#define O_lsr 36
+#define O_mvn 37
+#define O_mvp 38
+#define O_nop 39
+#define O_ora 40
+#define O_pea 41
+#define O_pei 42
+#define O_per 43
+#define O_pha 44
+#define O_phb 45
+#define O_phd 46
+#define O_phk 47
+#define O_php 48
+#define O_phx 49
+#define O_phy 50
+#define O_pla 51
+#define O_plb 52
+#define O_pld 53
+#define O_plp 54
+#define O_plx 55
+#define O_ply 56
+#define O_rep 57
+#define O_rol 58
+#define O_ror 59
+#define O_rti 60
+#define O_rtl 61
+#define O_rts 62
+#define O_sbc 63
+#define O_sec 64
+#define O_sed 65
+#define O_sei 66
+#define O_sep 67
+#define O_sta 68
+#define O_stp 69
+#define O_stx 70
+#define O_sty 71
+#define O_stz 72
+#define O_tax 73
+#define O_tay 74
+#define O_tcd 75
+#define O_tcs 76
+#define O_tdc 77
+#define O_trb 78
+#define O_tsb 79
+#define O_tsc 80
+#define O_tsx 81
+#define O_txa 82
+#define O_txs 83
+#define O_txy 84
+#define O_tya 85
+#define O_tyx 86
+#define O_wai 87
+#define O_wdm 88
+#define O_xba 89
+#define O_xce 90
+#ifdef DEFINE_TABLE
+ {0x69, O_adc, "adc", ADDR_IMMTOA},
+ {0x72, O_adc, "adc", ADDR_DIR_IND},
+ {0x71, O_adc, "adc", ADDR_DIR_IND_IDX_Y},
+ {0x73, O_adc, "adc", ADDR_STACK_REL_INDX_IDX},
+ {0x61, O_adc, "adc", ADDR_DIR_IDX_IND_X},
+ {0x67, O_adc, "adc", ADDR_DIR_IND_LONG},
+ {0x77, O_adc, "adc", ADDR_DIR_IND_IDX_Y_LONG},
+ {0x6D, O_adc, "adc", ADDR_ABS},
+ {0x7D, O_adc, "adc", ADDR_ABS_IDX_X},
+ {0x79, O_adc, "adc", ADDR_ABS_IDX_Y},
+ {0x6F, O_adc, "adc", ADDR_ABS_LONG},
+ {0x7F, O_adc, "adc", ADDR_ABS_LONG_IDX_X},
+ {0x65, O_adc, "adc", ADDR_DIR},
+ {0x63, O_adc, "adc", ADDR_STACK_REL},
+ {0x75, O_adc, "adc", ADDR_DIR_IDX_X},
+ {0x29, O_and, "and", ADDR_IMMTOA},
+ {0x32, O_and, "and", ADDR_DIR_IND},
+ {0x31, O_and, "and", ADDR_DIR_IND_IDX_Y},
+ {0x33, O_and, "and", ADDR_STACK_REL_INDX_IDX},
+ {0x21, O_and, "and", ADDR_DIR_IDX_IND_X},
+ {0x27, O_and, "and", ADDR_DIR_IND_LONG},
+ {0x37, O_and, "and", ADDR_DIR_IND_IDX_Y_LONG},
+ {0x2D, O_and, "and", ADDR_ABS},
+ {0x3D, O_and, "and", ADDR_ABS_IDX_X},
+ {0x39, O_and, "and", ADDR_ABS_IDX_Y},
+ {0x2F, O_and, "and", ADDR_ABS_LONG},
+ {0x3F, O_and, "and", ADDR_ABS_LONG_IDX_X},
+ {0x25, O_and, "and", ADDR_DIR},
+ {0x23, O_and, "and", ADDR_STACK_REL},
+ {0x35, O_and, "and", ADDR_DIR_IDX_X},
+ {0x0A, O_asl, "asl", ADDR_ACC},
+ {0x0E, O_asl, "asl", ADDR_ABS},
+ {0x1E, O_asl, "asl", ADDR_ABS_IDX_X},
+ {0x06, O_asl, "asl", ADDR_DIR},
+ {0x16, O_asl, "asl", ADDR_DIR_IDX_X},
+ {0x90, O_bcc, "bcc", ADDR_PC_REL},
+ {0xB0, O_bcs, "bcs", ADDR_PC_REL},
+ {0xF0, O_beq, "beq", ADDR_PC_REL},
+ {0x89, O_bit, "bit", ADDR_IMMTOA},
+ {0x24, O_bit, "bit", ADDR_DIR_IND},
+ {0x34, O_bit, "bit", ADDR_DIR_IDX_IND_X},
+ {0x2C, O_bit, "bit", ADDR_ABS},
+ {0x3C, O_bit, "bit", ADDR_ABS_IDX_X},
+ {0x30, O_bmi, "bmi", ADDR_PC_REL},
+ {0xD0, O_bne, "bne", ADDR_PC_REL},
+ {0x10, O_bpl, "bpl", ADDR_PC_REL},
+ {0x80, O_bra, "bra", ADDR_PC_REL},
+ {0x00, O_brk, "brk", ADDR_STACK},
+ {0x82, O_brl, "brl", ADDR_PC_REL_LONG},
+ {0x50, O_bvc, "bvc", ADDR_PC_REL},
+ {0x70, O_bvs, "bvs", ADDR_PC_REL},
+ {0x18, O_clc, "clc", ADDR_IMPLIED},
+ {0xD8, O_cld, "cld", ADDR_IMPLIED},
+ {0x58, O_cli, "cli", ADDR_IMPLIED},
+ {0xB8, O_clv, "clv", ADDR_IMPLIED},
+ {0xC9, O_cmp, "cmp", ADDR_IMMTOA},
+ {0xD2, O_cmp, "cmp", ADDR_DIR_IND},
+ {0xD1, O_cmp, "cmp", ADDR_DIR_IND_IDX_Y},
+ {0xD3, O_cmp, "cmp", ADDR_STACK_REL_INDX_IDX},
+ {0xC1, O_cmp, "cmp", ADDR_DIR_IDX_IND_X},
+ {0xC7, O_cmp, "cmp", ADDR_DIR_IND_LONG},
+ {0xD7, O_cmp, "cmp", ADDR_DIR_IND_IDX_Y_LONG},
+ {0xCD, O_cmp, "cmp", ADDR_ABS},
+ {0xDD, O_cmp, "cmp", ADDR_ABS_IDX_X},
+ {0xD9, O_cmp, "cmp", ADDR_ABS_IDX_Y},
+ {0xCF, O_cmp, "cmp", ADDR_ABS_LONG},
+ {0xDF, O_cmp, "cmp", ADDR_ABS_LONG_IDX_X},
+ {0xC5, O_cmp, "cmp", ADDR_DIR},
+ {0xC3, O_cmp, "cmp", ADDR_STACK_REL},
+ {0xD5, O_cmp, "cmp", ADDR_DIR_IDX_X},
+ {0x02, O_cop, "cop", ADDR_IMMCOP},
+ {0xE0, O_cpx, "cpx", ADDR_IMMTOI},
+ {0xEC, O_cpx, "cpx", ADDR_ABS},
+ {0xE4, O_cpx, "cpx", ADDR_DIR},
+ {0xC0, O_cpy, "cpy", ADDR_IMMTOI},
+ {0xCC, O_cpy, "cpy", ADDR_ABS},
+ {0xC4, O_cpy, "cpy", ADDR_DIR},
+ {0x3A, O_dec, "dec", ADDR_ACC},
+ {0xCE, O_dec, "dec", ADDR_ABS},
+ {0xDE, O_dec, "dec", ADDR_ABS_IDX_X},
+ {0xC6, O_dec, "dec", ADDR_DIR},
+ {0xD6, O_dec, "dec", ADDR_DIR_IDX_X},
+ {0xCA, O_dex, "dex", ADDR_IMPLIED},
+ {0x88, O_dey, "dey", ADDR_IMPLIED},
+ {0x49, O_eor, "eor", ADDR_IMMTOA},
+ {0x52, O_eor, "eor", ADDR_DIR_IND},
+ {0x51, O_eor, "eor", ADDR_DIR_IND_IDX_Y},
+ {0x53, O_eor, "eor", ADDR_STACK_REL_INDX_IDX},
+ {0x41, O_eor, "eor", ADDR_DIR_IDX_IND_X},
+ {0x47, O_eor, "eor", ADDR_DIR_IND_LONG},
+ {0x57, O_eor, "eor", ADDR_DIR_IND_IDX_Y_LONG},
+ {0x4D, O_eor, "eor", ADDR_ABS},
+ {0x5D, O_eor, "eor", ADDR_ABS_IDX_X},
+ {0x59, O_eor, "eor", ADDR_ABS_IDX_Y},
+ {0x4F, O_eor, "eor", ADDR_ABS_LONG},
+ {0x5F, O_eor, "eor", ADDR_ABS_LONG_IDX_X},
+ {0x45, O_eor, "eor", ADDR_DIR},
+ {0x43, O_eor, "eor", ADDR_STACK_REL},
+ {0x55, O_eor, "eor", ADDR_DIR_IDX_X},
+ {0x1A, O_inc, "inc", ADDR_ACC},
+ {0xEE, O_inc, "inc", ADDR_ABS},
+ {0xFE, O_inc, "inc", ADDR_ABS_IDX_X},
+ {0xE6, O_inc, "inc", ADDR_DIR},
+ {0xF6, O_inc, "inc", ADDR_DIR_IDX_X},
+ {0xE8, O_inx, "inx", ADDR_IMPLIED},
+ {0xC8, O_iny, "iny", ADDR_IMPLIED},
+ {0x6C, O_jmp, "jmp", ADDR_ABS_IND},
+ {0x7C, O_jmp, "jmp", ADDR_ABS_IND_IDX},
+ {0xDC, O_jmp, "jmp", ADDR_ABS_IND_LONG},
+ {0x4C, O_jmp, "jmp", ADDR_ABS},
+ {0x5C, O_jmp, "jmp", ADDR_ABS_LONG},
+ {0xFC, O_jsr, "jsr", ADDR_ABS_IND_IDX},
+ {0x20, O_jsr, "jsr", ADDR_ABS},
+ {0x22, O_jsr, "jsr", ADDR_ABS_LONG},
+ {0xA9, O_lda, "lda", ADDR_IMMTOA},
+ {0xB2, O_lda, "lda", ADDR_DIR_IND},
+ {0xB1, O_lda, "lda", ADDR_DIR_IND_IDX_Y},
+ {0xB3, O_lda, "lda", ADDR_STACK_REL_INDX_IDX},
+ {0xA1, O_lda, "lda", ADDR_DIR_IDX_IND_X},
+ {0xA7, O_lda, "lda", ADDR_DIR_IND_LONG},
+ {0xB7, O_lda, "lda", ADDR_DIR_IND_IDX_Y_LONG},
+ {0xAD, O_lda, "lda", ADDR_ABS},
+ {0xBD, O_lda, "lda", ADDR_ABS_IDX_X},
+ {0xB9, O_lda, "lda", ADDR_ABS_IDX_Y},
+ {0xAF, O_lda, "lda", ADDR_ABS_LONG},
+ {0xBF, O_lda, "lda", ADDR_ABS_LONG_IDX_X},
+ {0xA5, O_lda, "lda", ADDR_DIR},
+ {0xA3, O_lda, "lda", ADDR_STACK_REL},
+ {0xB5, O_lda, "lda", ADDR_DIR_IDX_X},
+ {0xA2, O_ldx, "ldx", ADDR_IMMTOI},
+ {0xAE, O_ldx, "ldx", ADDR_ABS},
+ {0xBE, O_ldx, "ldx", ADDR_ABS_IDX_Y},
+ {0xA6, O_ldx, "ldx", ADDR_DIR},
+ {0xB6, O_ldx, "ldx", ADDR_DIR_IDX_Y},
+ {0xA0, O_ldy, "ldy", ADDR_IMMTOI},
+ {0xAC, O_ldy, "ldy", ADDR_ABS},
+ {0xBC, O_ldy, "ldy", ADDR_ABS_IDX_X},
+ {0xA4, O_ldy, "ldy", ADDR_DIR},
+ {0xB4, O_ldy, "ldy", ADDR_DIR_IDX_X},
+ {0x4A, O_lsr, "lsr", ADDR_ACC},
+ {0x4E, O_lsr, "lsr", ADDR_ABS},
+ {0x5E, O_lsr, "lsr", ADDR_ABS_IDX_X},
+ {0x46, O_lsr, "lsr", ADDR_DIR},
+ {0x56, O_lsr, "lsr", ADDR_DIR_IDX_X},
+ {0x54, O_mvn, "mvn", ADDR_BLOCK_MOVE},
+ {0x44, O_mvp, "mvp", ADDR_BLOCK_MOVE},
+ {0xEA, O_nop, "nop", ADDR_IMPLIED},
+ {0x09, O_ora, "ora", ADDR_IMMTOA},
+ {0x12, O_ora, "ora", ADDR_DIR_IND},
+ {0x11, O_ora, "ora", ADDR_DIR_IND_IDX_Y},
+ {0x13, O_ora, "ora", ADDR_STACK_REL_INDX_IDX},
+ {0x01, O_ora, "ora", ADDR_DIR_IDX_IND_X},
+ {0x07, O_ora, "ora", ADDR_DIR_IND_LONG},
+ {0x17, O_ora, "ora", ADDR_DIR_IND_IDX_Y_LONG},
+ {0x0D, O_ora, "ora", ADDR_ABS},
+ {0x1D, O_ora, "ora", ADDR_ABS_IDX_X},
+ {0x19, O_ora, "ora", ADDR_ABS_IDX_Y},
+ {0x0F, O_ora, "ora", ADDR_ABS_LONG},
+ {0x1F, O_ora, "ora", ADDR_ABS_LONG_IDX_X},
+ {0x05, O_ora, "ora", ADDR_DIR},
+ {0x03, O_ora, "ora", ADDR_STACK_REL},
+ {0x15, O_ora, "ora", ADDR_DIR_IDX_X},
+ {0xF4, O_pea, "pea", ADDR_ABS},
+ {0xD4, O_pei, "pei", ADDR_DIR},
+ {0x62, O_per, "per", ADDR_PC_REL_LONG},
+ {0x48, O_pha, "pha", ADDR_STACK},
+ {0x8B, O_phb, "phb", ADDR_STACK},
+ {0x0B, O_phd, "phd", ADDR_STACK},
+ {0x4B, O_phk, "phk", ADDR_STACK},
+ {0x08, O_php, "php", ADDR_STACK},
+ {0xDA, O_phx, "phx", ADDR_STACK},
+ {0x5A, O_phy, "phy", ADDR_STACK},
+ {0x68, O_pla, "pla", ADDR_STACK},
+ {0xAB, O_plb, "plb", ADDR_STACK},
+ {0x2B, O_pld, "pld", ADDR_STACK},
+ {0x28, O_plp, "plp", ADDR_STACK},
+ {0xFA, O_plx, "plx", ADDR_STACK},
+ {0x7A, O_ply, "ply", ADDR_STACK},
+ {0xC2, O_rep, "rep", ADDR_IMMCOP},
+ {0x2A, O_rol, "rol", ADDR_ACC},
+ {0x2E, O_rol, "rol", ADDR_ABS},
+ {0x3E, O_rol, "rol", ADDR_ABS_IDX_X},
+ {0x26, O_rol, "rol", ADDR_DIR},
+ {0x36, O_rol, "rol", ADDR_DIR_IDX_X},
+ {0x6A, O_ror, "ror", ADDR_ACC},
+ {0x6E, O_ror, "ror", ADDR_ABS},
+ {0x7E, O_ror, "ror", ADDR_ABS_IDX_X},
+ {0x66, O_ror, "ror", ADDR_DIR},
+ {0x76, O_ror, "ror", ADDR_DIR_IDX_X},
+ {0x40, O_rti, "rti", ADDR_STACK},
+ {0x6B, O_rtl, "rtl", ADDR_STACK},
+ {0x60, O_rts, "rts", ADDR_STACK},
+ {0xE9, O_sbc, "sbc", ADDR_IMMTOA},
+ {0xF2, O_sbc, "sbc", ADDR_DIR_IND},
+ {0xF1, O_sbc, "sbc", ADDR_DIR_IND_IDX_Y},
+ {0xF3, O_sbc, "sbc", ADDR_STACK_REL_INDX_IDX},
+ {0xE1, O_sbc, "sbc", ADDR_DIR_IDX_IND_X},
+ {0xE7, O_sbc, "sbc", ADDR_DIR_IND_LONG},
+ {0xF7, O_sbc, "sbc", ADDR_DIR_IND_IDX_Y_LONG},
+ {0xED, O_sbc, "sbc", ADDR_ABS},
+ {0xFD, O_sbc, "sbc", ADDR_ABS_IDX_X},
+ {0xF9, O_sbc, "sbc", ADDR_ABS_IDX_Y},
+ {0xEF, O_sbc, "sbc", ADDR_ABS_LONG},
+ {0xFF, O_sbc, "sbc", ADDR_ABS_LONG_IDX_X},
+ {0xE5, O_sbc, "sbc", ADDR_DIR},
+ {0xE3, O_sbc, "sbc", ADDR_STACK_REL},
+ {0xF5, O_sbc, "sbc", ADDR_DIR_IDX_X},
+ {0x38, O_sec, "sec", ADDR_IMPLIED},
+ {0xF8, O_sed, "sed", ADDR_IMPLIED},
+ {0x78, O_sei, "sei", ADDR_IMPLIED},
+ {0xE2, O_sep, "sep", ADDR_IMMCOP},
+ {0x92, O_sta, "sta", ADDR_DIR_IND},
+ {0x91, O_sta, "sta", ADDR_DIR_IND_IDX_Y},
+ {0x93, O_sta, "sta", ADDR_STACK_REL_INDX_IDX},
+ {0x81, O_sta, "sta", ADDR_DIR_IDX_IND_X},
+ {0x87, O_sta, "sta", ADDR_DIR_IND_LONG},
+ {0x97, O_sta, "sta", ADDR_DIR_IND_IDX_Y_LONG},
+ {0x8D, O_sta, "sta", ADDR_ABS},
+ {0x9D, O_sta, "sta", ADDR_ABS_IDX_X},
+ {0x99, O_sta, "sta", ADDR_ABS_IDX_Y},
+ {0x8F, O_sta, "sta", ADDR_ABS_LONG},
+ {0x9F, O_sta, "sta", ADDR_ABS_LONG_IDX_X},
+ {0x85, O_sta, "sta", ADDR_DIR},
+ {0x83, O_sta, "sta", ADDR_STACK_REL},
+ {0x95, O_sta, "sta", ADDR_DIR_IDX_X},
+ {0xDB, O_stp, "stp", ADDR_IMPLIED},
+ {0x8E, O_stx, "stx", ADDR_ABS},
+ {0x86, O_stx, "stx", ADDR_DIR},
+ {0x96, O_stx, "stx", ADDR_DIR_IDX_X},
+ {0x8C, O_sty, "sty", ADDR_ABS},
+ {0x84, O_sty, "sty", ADDR_DIR},
+ {0x94, O_sty, "sty", ADDR_DIR_IDX_X},
+ {0x9C, O_stz, "stz", ADDR_ABS},
+ {0x9E, O_stz, "stz", ADDR_ABS_IDX_X},
+ {0x64, O_stz, "stz", ADDR_DIR},
+ {0x74, O_stz, "stz", ADDR_DIR_IDX_X},
+ {0xAA, O_tax, "tax", ADDR_IMPLIED},
+ {0xA8, O_tay, "tay", ADDR_IMPLIED},
+ {0x5B, O_tcd, "tcd", ADDR_IMPLIED},
+ {0x1B, O_tcs, "tcs", ADDR_IMPLIED},
+ {0x7B, O_tdc, "tdc", ADDR_IMPLIED},
+ {0x1C, O_trb, "trb", ADDR_ABS},
+ {0x14, O_trb, "trb", ADDR_DIR},
+ {0x0C, O_tsb, "tsb", ADDR_ABS},
+ {0x04, O_tsb, "tsb", ADDR_DIR},
+ {0x3B, O_tsc, "tsc", ADDR_IMPLIED},
+ {0xBA, O_tsx, "tsx", ADDR_IMPLIED},
+ {0x8A, O_txa, "txa", ADDR_IMPLIED},
+ {0x9A, O_txs, "txs", ADDR_IMPLIED},
+ {0x9B, O_txy, "txy", ADDR_IMPLIED},
+ {0x98, O_tya, "tya", ADDR_IMPLIED},
+ {0xBB, O_tyx, "tyx", ADDR_IMPLIED},
+ {0xCB, O_wai, "wai", ADDR_IMPLIED},
+ {0x42, O_wdm, "wdm", ADDR_IMPLIED},
+ {0xEB, O_xba, "xba", ADDR_IMPLIED},
+ {0xFB, O_xce, "xce", ADDR_IMPLIED},
+ { 0 }
+};
+#endif
+#define DISASM()\
+ case ADDR_IMMTOA:\
+ args[0] = M==0 ? asR_W65_ABS16 : asR_W65_ABS8;\
+ print_operand (0, " #$0", args);\
+ size += M==0 ? 2:1;\
+ break;\
+ case ADDR_IMMCOP:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (0, " #$0", args);\
+ size += 1;\
+ break;\
+ case ADDR_IMMTOI:\
+ args[0] = X==0 ? asR_W65_ABS16 : asR_W65_ABS8;\
+ print_operand (0, " #$0", args);\
+ size += X==0 ? 2:1;\
+ break;\
+ case ADDR_ACC:\
+ print_operand (0, " a", 0);\
+ size += 0;\
+ break;\
+ case ADDR_PC_REL:\
+ args[0] = asR_W65_PCR8;\
+ print_operand (0, " $0", args);\
+ size += 1;\
+ break;\
+ case ADDR_PC_REL_LONG:\
+ args[0] = asR_W65_PCR16;\
+ print_operand (0, " $0", args);\
+ size += 2;\
+ break;\
+ case ADDR_IMPLIED:\
+ size += 0;\
+ break;\
+ case ADDR_STACK:\
+ size += 0;\
+ break;\
+ case ADDR_DIR:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " <$0", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IDX_X:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " <$0,x", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IDX_Y:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " <$0,y", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IND:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " (<$0)", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IDX_IND_X:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " (<$0,x)", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IND_IDX_Y:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " (<$0),y", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IND_LONG:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " [$0]", args);\
+ size += 1;\
+ break;\
+ case ADDR_DIR_IND_IDX_Y_LONG:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (1, " [$0],y", args);\
+ size += 1;\
+ break;\
+ case ADDR_ABS:\
+ args[0] = asR_W65_ABS16;\
+ print_operand (1, " !$0", args);\
+ size += 2;\
+ break;\
+ case ADDR_ABS_IDX_X:\
+ args[0] = asR_W65_ABS16;\
+ print_operand (1, " !$0,x", args);\
+ size += 2;\
+ break;\
+ case ADDR_ABS_IDX_Y:\
+ args[0] = asR_W65_ABS16;\
+ print_operand (1, " !$0,y", args);\
+ size += 2;\
+ break;\
+ case ADDR_ABS_LONG:\
+ args[0] = asR_W65_ABS24;\
+ print_operand (1, " >$0", args);\
+ size += 3;\
+ break;\
+ case ADDR_ABS_IND_LONG:\
+ args[0] = asR_W65_ABS16;\
+ print_operand (1, " [>$0]", args);\
+ size += 2;\
+ break;\
+ case ADDR_ABS_LONG_IDX_X:\
+ args[0] = asR_W65_ABS24;\
+ print_operand (1, " >$0,x", args);\
+ size += 3;\
+ break;\
+ case ADDR_STACK_REL:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (0, " $0,s", args);\
+ size += 1;\
+ break;\
+ case ADDR_STACK_REL_INDX_IDX:\
+ args[0] = asR_W65_ABS8;\
+ print_operand (0, " ($0,s),y", args);\
+ size += 1;\
+ break;\
+ case ADDR_ABS_IND:\
+ args[0] = asR_W65_ABS16;\
+ print_operand (1, " ($0)", args);\
+ size += 2;\
+ break;\
+ case ADDR_ABS_IND_IDX:\
+ args[0] = asR_W65_ABS16;\
+ print_operand (1, " ($0,x)", args);\
+ size += 2;\
+ break;\
+ case ADDR_BLOCK_MOVE:\
+ args[0] = (asR_W65_ABS16 >>8) &0xff;\
+ args[1] = ( asR_W65_ABS16 & 0xff);\
+ print_operand (0," $0,$1",args);\
+ size += 2;\
+ break;\
+
+#define GETINFO(size,type,pcrel)\
+ case ADDR_IMMTOA: size = M==0 ? 2:1;type=M==0 ? R_W65_ABS16 : R_W65_ABS8;pcrel=0;break;\
+ case ADDR_IMMCOP: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_IMMTOI: size = X==0 ? 2:1;type=X==0 ? R_W65_ABS16 : R_W65_ABS8;pcrel=0;break;\
+ case ADDR_ACC: size = 0;type=-1;pcrel=0;break;\
+ case ADDR_PC_REL: size = 1;type=R_W65_PCR8;pcrel=0;break;\
+ case ADDR_PC_REL_LONG: size = 2;type=R_W65_PCR16;pcrel=0;break;\
+ case ADDR_IMPLIED: size = 0;type=-1;pcrel=0;break;\
+ case ADDR_STACK: size = 0;type=-1;pcrel=0;break;\
+ case ADDR_DIR: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IDX_X: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IDX_Y: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IND: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IDX_IND_X: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IND_IDX_Y: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IND_LONG: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_DIR_IND_IDX_Y_LONG: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_ABS: size = 2;type=R_W65_ABS16;pcrel=0;break;\
+ case ADDR_ABS_IDX_X: size = 2;type=R_W65_ABS16;pcrel=0;break;\
+ case ADDR_ABS_IDX_Y: size = 2;type=R_W65_ABS16;pcrel=0;break;\
+ case ADDR_ABS_LONG: size = 3;type=R_W65_ABS24;pcrel=0;break;\
+ case ADDR_ABS_IND_LONG: size = 2;type=R_W65_ABS16;pcrel=0;break;\
+ case ADDR_ABS_LONG_IDX_X: size = 3;type=R_W65_ABS24;pcrel=0;break;\
+ case ADDR_STACK_REL: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_STACK_REL_INDX_IDX: size = 1;type=R_W65_ABS8;pcrel=0;break;\
+ case ADDR_ABS_IND: size = 2;type=R_W65_ABS16;pcrel=0;break;\
+ case ADDR_ABS_IND_IDX: size = 2;type=R_W65_ABS16;pcrel=0;break;\
+ case ADDR_BLOCK_MOVE: size = 2;type=-1;pcrel=0;break;\
+
diff --git a/opcodes/z8k-dis.c b/opcodes/z8k-dis.c
new file mode 100644
index 00000000000..7123622a291
--- /dev/null
+++ b/opcodes/z8k-dis.c
@@ -0,0 +1,574 @@
+/* Disassemble z8000 code.
+ Copyright 1992, 1993, 1995, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ansidecl.h>
+#include "sysdep.h"
+#include "dis-asm.h"
+
+#define DEFINE_TABLE
+#include "z8k-opc.h"
+
+
+#include <setjmp.h>
+
+
+typedef struct
+{
+ /* These are all indexed by nibble number (i.e only every other entry
+ of bytes is used, and every 4th entry of words). */
+ unsigned char nibbles[24];
+ unsigned char bytes[24];
+ unsigned short words[24];
+
+ /* Nibble number of first word not yet fetched. */
+ int max_fetched;
+ bfd_vma insn_start;
+ jmp_buf bailout;
+
+ long tabl_index;
+ char instr_asmsrc[80];
+ unsigned long arg_reg[0x0f];
+ unsigned long immediate;
+ unsigned long displacement;
+ unsigned long address;
+ unsigned long cond_code;
+ unsigned long ctrl_code;
+ unsigned long flags;
+ unsigned long interrupts;
+}
+instr_data_s;
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, nibble) \
+ ((nibble) < ((instr_data_s *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (nibble)))
+
+static int
+fetch_data (info, nibble)
+ struct disassemble_info *info;
+ int nibble;
+{
+ unsigned char mybuf[20];
+ int status;
+ instr_data_s *priv = (instr_data_s *)info->private_data;
+
+ if ((nibble % 4) != 0)
+ abort ();
+
+ status = (*info->read_memory_func) (priv->insn_start,
+ (bfd_byte *) mybuf,
+ nibble / 2,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, priv->insn_start, info);
+ longjmp (priv->bailout, 1);
+ }
+
+ {
+ int i;
+ unsigned char *p = mybuf ;
+
+ for (i = 0; i < nibble;)
+ {
+ priv->words[i] = (p[0] << 8) | p[1];
+
+ priv->bytes[i] = *p;
+ priv->nibbles[i++] = *p >> 4;
+ priv->nibbles[i++] = *p &0xf;
+
+ ++p;
+ priv->bytes[i] = *p;
+ priv->nibbles[i++] = *p >> 4;
+ priv->nibbles[i++] = *p & 0xf;
+
+ ++p;
+ }
+ }
+ priv->max_fetched = nibble;
+ return 1;
+}
+
+static char *codes[16] =
+{
+ "f",
+ "lt",
+ "le",
+ "ule",
+ "ov/pe",
+ "mi",
+ "eq",
+ "c/ult",
+ "t",
+ "ge",
+ "gt",
+ "ugt",
+ "nov/po",
+ "pl",
+ "ne",
+ "nc/uge"
+};
+
+int z8k_lookup_instr PARAMS ((unsigned char*, disassemble_info *));
+static void output_instr
+ PARAMS ((instr_data_s *, unsigned long, disassemble_info *));
+static void unpack_instr PARAMS ((instr_data_s *, int, disassemble_info *));
+static void unparse_instr PARAMS ((instr_data_s *));
+
+static int
+print_insn_z8k (addr, info, is_segmented)
+ bfd_vma addr;
+ disassemble_info *info;
+ int is_segmented;
+{
+ instr_data_s instr_data;
+
+ info->private_data = (PTR) &instr_data;
+ instr_data.max_fetched = 0;
+ instr_data.insn_start = addr;
+ if (setjmp (instr_data.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+ instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info);
+ if (instr_data.tabl_index > 0)
+ {
+ unpack_instr (&instr_data, is_segmented, info);
+ unparse_instr (&instr_data);
+ output_instr (&instr_data, addr, info);
+ return z8k_table[instr_data.tabl_index].length;
+ }
+ else
+ {
+ FETCH_DATA (info, 4);
+ (*info->fprintf_func) (info->stream, ".word %02x%02x",
+ instr_data.bytes[0], instr_data.bytes[2]);
+ return 2;
+ }
+}
+
+int
+print_insn_z8001 (addr, info)
+ bfd_vma addr;
+ disassemble_info *info;
+{
+ return print_insn_z8k (addr, info, 1);
+}
+
+int
+print_insn_z8002 (addr, info)
+ bfd_vma addr;
+ disassemble_info *info;
+{
+ return print_insn_z8k (addr, info, 0);
+}
+
+int
+z8k_lookup_instr (nibbles, info)
+ unsigned char *nibbles;
+ disassemble_info *info;
+{
+
+ int nibl_index, tabl_index;
+ int nibl_matched;
+ unsigned short instr_nibl;
+ unsigned short tabl_datum, datum_class, datum_value;
+
+ nibl_matched = 0;
+ tabl_index = 0;
+ while (!nibl_matched && z8k_table[tabl_index].name)
+ {
+ nibl_matched = 1;
+ for (nibl_index = 0; nibl_index < z8k_table[tabl_index].length * 2 && nibl_matched; nibl_index++)
+ {
+ if ((nibl_index % 4) == 0)
+ /* Fetch one word at a time. */
+ FETCH_DATA (info, nibl_index + 4);
+ instr_nibl = nibbles[nibl_index];
+
+ tabl_datum = z8k_table[tabl_index].byte_info[nibl_index];
+ datum_class = tabl_datum & CLASS_MASK;
+ datum_value = ~CLASS_MASK & tabl_datum;
+
+ switch (datum_class)
+ {
+ case CLASS_BIT:
+ if (datum_value != instr_nibl)
+ nibl_matched = 0;
+ break;
+ case CLASS_00II:
+ if (!((~instr_nibl) & 0x4))
+ nibl_matched = 0;
+ break;
+ case CLASS_01II:
+ if (!(instr_nibl & 0x4))
+ nibl_matched = 0;
+ break;
+ case CLASS_0CCC:
+ if (!((~instr_nibl) & 0x8))
+ nibl_matched = 0;
+ break;
+ case CLASS_1CCC:
+ if (!(instr_nibl & 0x8))
+ nibl_matched = 0;
+ break;
+ case CLASS_0DISP7:
+ if (!((~instr_nibl) & 0x8))
+ nibl_matched = 0;
+ nibl_index += 1;
+ break;
+ case CLASS_1DISP7:
+ if (!(instr_nibl & 0x8))
+ nibl_matched = 0;
+ nibl_index += 1;
+ break;
+ case CLASS_REGN0:
+ if (instr_nibl == 0)
+ nibl_matched = 0;
+ break;
+ case CLASS_BIT_1OR2:
+ if ((instr_nibl | 0x2) != (datum_value | 0x2))
+ nibl_matched = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ if (nibl_matched)
+ {
+ return tabl_index;
+ }
+
+ tabl_index++;
+ }
+ return -1;
+
+}
+
+static void
+output_instr (instr_data, addr, info)
+ instr_data_s *instr_data;
+ unsigned long addr;
+ disassemble_info *info;
+{
+ int loop, loop_limit;
+ char tmp_str[20];
+ char out_str[100];
+
+ strcpy (out_str, "\t");
+
+ loop_limit = z8k_table[instr_data->tabl_index].length * 2;
+ FETCH_DATA (info, loop_limit);
+ for (loop = 0; loop < loop_limit; loop++)
+ {
+ sprintf (tmp_str, "%x", instr_data->nibbles[loop]);
+ strcat (out_str, tmp_str);
+ }
+
+ while (loop++ < 8)
+ {
+ strcat (out_str, " ");
+ }
+
+ strcat (out_str, instr_data->instr_asmsrc);
+
+ (*info->fprintf_func) (info->stream, "%s", out_str);
+}
+
+static void
+unpack_instr (instr_data, is_segmented, info)
+ instr_data_s *instr_data;
+ int is_segmented;
+ disassemble_info *info;
+{
+ int nibl_count, loop;
+ unsigned short instr_nibl, instr_byte, instr_word;
+ long instr_long;
+ unsigned short tabl_datum, datum_class, datum_value;
+
+ nibl_count = 0;
+ loop = 0;
+ while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0)
+ {
+ FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4));
+ instr_nibl = instr_data->nibbles[nibl_count];
+ instr_byte = instr_data->bytes[nibl_count];
+ instr_word = instr_data->words[nibl_count];
+
+ tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop];
+ datum_class = tabl_datum & CLASS_MASK;
+ datum_value = tabl_datum & ~CLASS_MASK;
+
+ switch (datum_class)
+ {
+ case CLASS_X:
+ instr_data->address = instr_nibl;
+ break;
+ case CLASS_BA:
+ instr_data->displacement = instr_nibl;
+ break;
+ case CLASS_BX:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_DISP:
+ switch (datum_value)
+ {
+ case ARG_DISP16:
+ instr_data->displacement = instr_word;
+ nibl_count += 3;
+ break;
+ case ARG_DISP12:
+ instr_data->displacement = instr_word & 0x0fff;
+ nibl_count += 2;
+ break;
+ default:
+ break;
+ }
+ break;
+ case CLASS_IMM:
+ switch (datum_value)
+ {
+ case ARG_IMM4:
+ instr_data->immediate = instr_nibl;
+ break;
+ case ARG_NIM8:
+ instr_data->immediate = (-instr_byte);
+ nibl_count += 1;
+ break;
+ case ARG_IMM8:
+ instr_data->immediate = instr_byte;
+ nibl_count += 1;
+ break;
+ case ARG_IMM16:
+ instr_data->immediate = instr_word;
+ nibl_count += 3;
+ break;
+ case ARG_IMM32:
+ FETCH_DATA (info, nibl_count + 8);
+ instr_long = (instr_data->words[nibl_count] << 16)
+ | (instr_data->words[nibl_count + 4]);
+ instr_data->immediate = instr_long;
+ nibl_count += 7;
+ break;
+ case ARG_IMMN:
+ instr_data->immediate = instr_nibl - 1;
+ break;
+ case ARG_IMM4M1:
+ instr_data->immediate = instr_nibl + 1;
+ break;
+ case ARG_IMM_1:
+ instr_data->immediate = 1;
+ break;
+ case ARG_IMM_2:
+ instr_data->immediate = 2;
+ break;
+ case ARG_IMM2:
+ instr_data->immediate = instr_nibl & 0x3;
+ break;
+ default:
+ break;
+ }
+ break;
+ case CLASS_CC:
+ instr_data->cond_code = instr_nibl;
+ break;
+ case CLASS_CTRL:
+ instr_data->ctrl_code = instr_nibl;
+ break;
+ case CLASS_DA:
+ case CLASS_ADDRESS:
+ if (is_segmented)
+ {
+ if (instr_nibl & 0x8)
+ {
+ FETCH_DATA (info, nibl_count + 8);
+ instr_long = (instr_data->words[nibl_count] << 16)
+ | (instr_data->words[nibl_count + 4]);
+ instr_data->address = ((instr_word & 0x7f00) << 8) +
+ (instr_long & 0xffff);
+ nibl_count += 7;
+ }
+ else
+ {
+ instr_data->address = ((instr_word & 0x7f00) << 8) +
+ (instr_word & 0x00ff);
+ nibl_count += 3;
+ }
+ }
+ else
+ {
+ instr_data->address = instr_word;
+ nibl_count += 3;
+ }
+ break;
+ case CLASS_0CCC:
+ instr_data->cond_code = instr_nibl & 0x7;
+ break;
+ case CLASS_1CCC:
+ instr_data->cond_code = instr_nibl & 0x7;
+ break;
+ case CLASS_0DISP7:
+ instr_data->displacement = instr_byte & 0x7f;
+ nibl_count += 1;
+ break;
+ case CLASS_1DISP7:
+ instr_data->displacement = instr_byte & 0x7f;
+ nibl_count += 1;
+ break;
+ case CLASS_01II:
+ instr_data->interrupts = instr_nibl & 0x3;
+ break;
+ case CLASS_00II:
+ instr_data->interrupts = instr_nibl & 0x3;
+ break;
+ case CLASS_BIT:
+ /* do nothing */
+ break;
+ case CLASS_IR:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_FLAGS:
+ instr_data->flags = instr_nibl;
+ break;
+ case CLASS_REG:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_REG_BYTE:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_REG_WORD:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_REG_QUAD:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_REG_LONG:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ case CLASS_REGN0:
+ instr_data->arg_reg[datum_value] = instr_nibl;
+ break;
+ default:
+ break;
+ }
+
+ loop += 1;
+ nibl_count += 1;
+ }
+}
+
+static void
+unparse_instr (instr_data)
+ instr_data_s *instr_data;
+{
+ unsigned short tabl_datum, datum_class, datum_value;
+ int loop, loop_limit;
+ char out_str[80], tmp_str[25];
+
+ sprintf (out_str, "\t%s\t", z8k_table[instr_data->tabl_index].name);
+
+ loop_limit = z8k_table[instr_data->tabl_index].noperands;
+ for (loop = 0; loop < loop_limit; loop++)
+ {
+ if (loop)
+ strcat (out_str, ",");
+
+ tabl_datum = z8k_table[instr_data->tabl_index].arg_info[loop];
+ datum_class = tabl_datum & CLASS_MASK;
+ datum_value = tabl_datum & ~CLASS_MASK;
+
+ switch (datum_class)
+ {
+ case CLASS_X:
+ sprintf (tmp_str, "0x%0lx(R%ld)", instr_data->address,
+ instr_data->arg_reg[datum_value]);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_BA:
+ sprintf (tmp_str, "r%ld(#%lx)", instr_data->arg_reg[datum_value],
+ instr_data->immediate);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_BX:
+ sprintf (tmp_str, "r%ld(R%ld)", instr_data->arg_reg[datum_value],
+ instr_data->arg_reg[ARG_RX]);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_DISP:
+ sprintf (tmp_str, "#0x%0lx", instr_data->displacement);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_IMM:
+ sprintf (tmp_str, "#0x%0lx", instr_data->immediate);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_CC:
+ sprintf (tmp_str, "%s", codes[instr_data->cond_code]);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_CTRL:
+ sprintf (tmp_str, "0x%0lx", instr_data->ctrl_code);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_DA:
+ case CLASS_ADDRESS:
+ sprintf (tmp_str, "#0x%0lx", instr_data->address);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_IR:
+ sprintf (tmp_str, "@R%ld", instr_data->arg_reg[datum_value]);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_FLAGS:
+ sprintf (tmp_str, "0x%0lx", instr_data->flags);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_REG_BYTE:
+ if (instr_data->arg_reg[datum_value] >= 0x8)
+ {
+ sprintf (tmp_str, "rl%ld",
+ instr_data->arg_reg[datum_value] - 0x8);
+ }
+ else
+ {
+ sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]);
+ }
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_REG_WORD:
+ sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_REG_QUAD:
+ sprintf (tmp_str, "rq%ld", instr_data->arg_reg[datum_value]);
+ strcat (out_str, tmp_str);
+ break;
+ case CLASS_REG_LONG:
+ sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]);
+ strcat (out_str, tmp_str);
+ break;
+ default:
+ break;
+ }
+ }
+
+ strcpy (instr_data->instr_asmsrc, out_str);
+}
diff --git a/opcodes/z8k-opc.h b/opcodes/z8k-opc.h
new file mode 100644
index 00000000000..379a3a3c647
--- /dev/null
+++ b/opcodes/z8k-opc.h
@@ -0,0 +1,4438 @@
+ /* THIS FILE IS AUTOMAGICALLY GENERATED, DON'T EDIT IT */
+#define ARG_MASK 0x0f
+#define ARG_SRC 0x01
+#define ARG_DST 0x02
+#define ARG_RS 0x01
+#define ARG_RD 0x02
+#define ARG_RA 0x03
+#define ARG_RB 0x04
+#define ARG_RR 0x05
+#define ARG_RX 0x06
+#define ARG_IMM4 0x01
+#define ARG_IMM8 0x02
+#define ARG_IMM16 0x03
+#define ARG_IMM32 0x04
+#define ARG_IMMN 0x05
+#define ARG_IMMNMINUS1 0x05
+#define ARG_IMM_1 0x06
+#define ARG_IMM_2 0x07
+#define ARG_DISP16 0x08
+#define ARG_NIM8 0x09
+#define ARG_IMM2 0x0a
+#define ARG_IMM1OR2 0x0b
+#define ARG_DISP12 0x0b
+#define ARG_DISP8 0x0c
+#define ARG_IMM4M1 0x0d
+#define CLASS_MASK 0x1fff0
+#define CLASS_X 0x10
+#define CLASS_BA 0x20
+#define CLASS_DA 0x30
+#define CLASS_BX 0x40
+#define CLASS_DISP 0x50
+#define CLASS_IMM 0x60
+#define CLASS_CC 0x70
+#define CLASS_CTRL 0x80
+#define CLASS_ADDRESS 0xd0
+#define CLASS_0CCC 0xe0
+#define CLASS_1CCC 0xf0
+#define CLASS_0DISP7 0x100
+#define CLASS_1DISP7 0x200
+#define CLASS_01II 0x300
+#define CLASS_00II 0x400
+#define CLASS_BIT 0x500
+#define CLASS_FLAGS 0x600
+#define CLASS_IR 0x700
+#define CLASS_DISP8 0x800
+#define CLASS_BIT_1OR2 0x900
+#define CLASS_REG 0x7000
+#define CLASS_REG_BYTE 0x2000
+#define CLASS_REG_WORD 0x3000
+#define CLASS_REG_QUAD 0x4000
+#define CLASS_REG_LONG 0x5000
+#define CLASS_REGN0 0x8000
+#define CLASS_PR 0x10000
+#define OPC_adc 0
+#define OPC_adcb 1
+#define OPC_add 2
+#define OPC_addb 3
+#define OPC_addl 4
+#define OPC_and 5
+#define OPC_andb 6
+#define OPC_bit 7
+#define OPC_bitb 8
+#define OPC_call 9
+#define OPC_calr 10
+#define OPC_clr 11
+#define OPC_clrb 12
+#define OPC_com 13
+#define OPC_comb 14
+#define OPC_comflg 15
+#define OPC_cp 16
+#define OPC_cpb 17
+#define OPC_cpd 18
+#define OPC_cpdb 19
+#define OPC_cpdr 20
+#define OPC_cpdrb 21
+#define OPC_cpi 22
+#define OPC_cpib 23
+#define OPC_cpir 24
+#define OPC_cpirb 25
+#define OPC_cpl 26
+#define OPC_cpsd 27
+#define OPC_cpsdb 28
+#define OPC_cpsdr 29
+#define OPC_cpsdrb 30
+#define OPC_cpsi 31
+#define OPC_cpsib 32
+#define OPC_cpsir 33
+#define OPC_cpsirb 34
+#define OPC_dab 35
+#define OPC_dbjnz 36
+#define OPC_dec 37
+#define OPC_decb 38
+#define OPC_di 39
+#define OPC_div 40
+#define OPC_divl 41
+#define OPC_djnz 42
+#define OPC_ei 43
+#define OPC_ex 44
+#define OPC_exb 45
+#define OPC_exts 46
+#define OPC_extsb 47
+#define OPC_extsl 48
+#define OPC_halt 49
+#define OPC_in 50
+#define OPC_inb 51
+#define OPC_inc 52
+#define OPC_incb 53
+#define OPC_ind 54
+#define OPC_indb 55
+#define OPC_inib 56
+#define OPC_inibr 57
+#define OPC_iret 58
+#define OPC_jp 59
+#define OPC_jr 60
+#define OPC_ld 61
+#define OPC_lda 62
+#define OPC_ldar 63
+#define OPC_ldb 64
+#define OPC_ldctl 65
+#define OPC_ldir 66
+#define OPC_ldirb 67
+#define OPC_ldk 68
+#define OPC_ldl 69
+#define OPC_ldm 70
+#define OPC_ldps 71
+#define OPC_ldr 72
+#define OPC_ldrb 73
+#define OPC_ldrl 74
+#define OPC_mbit 75
+#define OPC_mreq 76
+#define OPC_mres 77
+#define OPC_mset 78
+#define OPC_mult 79
+#define OPC_multl 80
+#define OPC_neg 81
+#define OPC_negb 82
+#define OPC_nop 83
+#define OPC_or 84
+#define OPC_orb 85
+#define OPC_out 86
+#define OPC_outb 87
+#define OPC_outd 88
+#define OPC_outdb 89
+#define OPC_outib 90
+#define OPC_outibr 91
+#define OPC_pop 92
+#define OPC_popl 93
+#define OPC_push 94
+#define OPC_pushl 95
+#define OPC_res 96
+#define OPC_resb 97
+#define OPC_resflg 98
+#define OPC_ret 99
+#define OPC_rl 100
+#define OPC_rlb 101
+#define OPC_rlc 102
+#define OPC_rlcb 103
+#define OPC_rldb 104
+#define OPC_rr 105
+#define OPC_rrb 106
+#define OPC_rrc 107
+#define OPC_rrcb 108
+#define OPC_rrdb 109
+#define OPC_sbc 110
+#define OPC_sbcb 111
+#define OPC_sda 112
+#define OPC_sdab 113
+#define OPC_sdal 114
+#define OPC_sdl 115
+#define OPC_sdlb 116
+#define OPC_sdll 117
+#define OPC_set 118
+#define OPC_setb 119
+#define OPC_setflg 120
+#define OPC_sinb 121
+#define OPC_sind 122
+#define OPC_sindb 123
+#define OPC_sinib 124
+#define OPC_sinibr 125
+#define OPC_sla 126
+#define OPC_slab 127
+#define OPC_slal 128
+#define OPC_sll 129
+#define OPC_sllb 130
+#define OPC_slll 131
+#define OPC_sout 132
+#define OPC_soutb 133
+#define OPC_soutd 134
+#define OPC_soutdb 135
+#define OPC_soutib 136
+#define OPC_soutibr 137
+#define OPC_sra 138
+#define OPC_srab 139
+#define OPC_sral 140
+#define OPC_srl 141
+#define OPC_srlb 142
+#define OPC_srll 143
+#define OPC_sub 144
+#define OPC_subb 145
+#define OPC_subl 146
+#define OPC_tcc 147
+#define OPC_tccb 148
+#define OPC_test 149
+#define OPC_testb 150
+#define OPC_testl 151
+#define OPC_trdb 152
+#define OPC_trdrb 153
+#define OPC_trib 154
+#define OPC_trirb 155
+#define OPC_trtdrb 156
+#define OPC_trtib 157
+#define OPC_trtirb 158
+#define OPC_trtdb 159
+#define OPC_tset 160
+#define OPC_tsetb 161
+#define OPC_xor 162
+#define OPC_xorb 163
+#define OPC_ldd 164
+#define OPC_lddb 165
+#define OPC_lddr 166
+#define OPC_lddrb 167
+#define OPC_ldi 168
+#define OPC_ldib 169
+#define OPC_sc 170
+#define OPC_bpt 171
+#define OPC_ext0e 172
+#define OPC_ext0f 172
+#define OPC_ext8e 172
+#define OPC_ext8f 172
+#define OPC_rsvd36 172
+#define OPC_rsvd38 172
+#define OPC_rsvd78 172
+#define OPC_rsvd7e 172
+#define OPC_rsvd9d 172
+#define OPC_rsvd9f 172
+#define OPC_rsvdb9 172
+#define OPC_rsvdbf 172
+#define OPC_outi 173
+typedef struct {
+#ifdef NICENAMES
+char *nicename;
+int type;
+int cycles;
+int flags;
+#endif
+char *name;
+unsigned char opcode;
+void (*func)();
+unsigned int arg_info[4];
+unsigned int byte_info[10];
+int noperands;
+int length;
+int idx;
+} opcode_entry_type;
+#ifdef DEFINE_TABLE
+opcode_entry_type z8k_table[] = {
+
+
+/* 1011 0101 ssss dddd *** adc rd,rs */
+{
+#ifdef NICENAMES
+"adc rd,rs",16,5,
+0x3c,
+#endif
+"adc",OPC_adc,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+5,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,0},
+
+
+/* 1011 0100 ssss dddd *** adcb rbd,rbs */
+{
+#ifdef NICENAMES
+"adcb rbd,rbs",8,5,
+0x3f,
+#endif
+"adcb",OPC_adcb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+4,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,1},
+
+
+/* 0000 0001 ssN0 dddd *** add rd,@rs */
+{
+#ifdef NICENAMES
+"add rd,@rs",16,7,
+0x3c,
+#endif
+"add",OPC_add,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+1,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,2},
+
+
+/* 0100 0001 0000 dddd address_src *** add rd,address_src */
+{
+#ifdef NICENAMES
+"add rd,address_src",16,9,
+0x3c,
+#endif
+"add",OPC_add,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,3},
+
+
+/* 0100 0001 ssN0 dddd address_src *** add rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"add rd,address_src(rs)",16,10,
+0x3c,
+#endif
+"add",OPC_add,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+1,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,4},
+
+
+/* 0000 0001 0000 dddd imm16 *** add rd,imm16 */
+{
+#ifdef NICENAMES
+"add rd,imm16",16,7,
+0x3c,
+#endif
+"add",OPC_add,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,5},
+
+
+/* 1000 0001 ssss dddd *** add rd,rs */
+{
+#ifdef NICENAMES
+"add rd,rs",16,4,
+0x3c,
+#endif
+"add",OPC_add,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+1,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,6},
+
+
+/* 0000 0000 ssN0 dddd *** addb rbd,@rs */
+{
+#ifdef NICENAMES
+"addb rbd,@rs",8,7,
+0x3f,
+#endif
+"addb",OPC_addb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,7},
+
+
+/* 0100 0000 0000 dddd address_src *** addb rbd,address_src */
+{
+#ifdef NICENAMES
+"addb rbd,address_src",8,9,
+0x3f,
+#endif
+"addb",OPC_addb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,8},
+
+
+/* 0100 0000 ssN0 dddd address_src *** addb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"addb rbd,address_src(rs)",8,10,
+0x3f,
+#endif
+"addb",OPC_addb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,9},
+
+
+/* 0000 0000 0000 dddd imm8 imm8 *** addb rbd,imm8 */
+{
+#ifdef NICENAMES
+"addb rbd,imm8",8,7,
+0x3f,
+#endif
+"addb",OPC_addb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,10},
+
+
+/* 1000 0000 ssss dddd *** addb rbd,rbs */
+{
+#ifdef NICENAMES
+"addb rbd,rbs",8,4,
+0x3f,
+#endif
+"addb",OPC_addb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,11},
+
+
+/* 0001 0110 ssN0 dddd *** addl rrd,@rs */
+{
+#ifdef NICENAMES
+"addl rrd,@rs",32,14,
+0x3c,
+#endif
+"addl",OPC_addl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+6,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,12},
+
+
+/* 0101 0110 0000 dddd address_src *** addl rrd,address_src */
+{
+#ifdef NICENAMES
+"addl rrd,address_src",32,15,
+0x3c,
+#endif
+"addl",OPC_addl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,13},
+
+
+/* 0101 0110 ssN0 dddd address_src *** addl rrd,address_src(rs) */
+{
+#ifdef NICENAMES
+"addl rrd,address_src(rs)",32,16,
+0x3c,
+#endif
+"addl",OPC_addl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+6,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,14},
+
+
+/* 0001 0110 0000 dddd imm32 *** addl rrd,imm32 */
+{
+#ifdef NICENAMES
+"addl rrd,imm32",32,14,
+0x3c,
+#endif
+"addl",OPC_addl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM32),},
+ {CLASS_BIT+1,CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM32),0,0,0,0,},2,6,15},
+
+
+/* 1001 0110 ssss dddd *** addl rrd,rrs */
+{
+#ifdef NICENAMES
+"addl rrd,rrs",32,8,
+0x3c,
+#endif
+"addl",OPC_addl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+6,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,16},
+
+
+/* 0000 0111 ssN0 dddd *** and rd,@rs */
+{
+#ifdef NICENAMES
+"and rd,@rs",16,7,
+0x18,
+#endif
+"and",OPC_and,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+7,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,17},
+
+
+/* 0100 0111 0000 dddd address_src *** and rd,address_src */
+{
+#ifdef NICENAMES
+"and rd,address_src",16,9,
+0x18,
+#endif
+"and",OPC_and,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+7,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,18},
+
+
+/* 0100 0111 ssN0 dddd address_src *** and rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"and rd,address_src(rs)",16,10,
+0x18,
+#endif
+"and",OPC_and,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+7,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,19},
+
+
+/* 0000 0111 0000 dddd imm16 *** and rd,imm16 */
+{
+#ifdef NICENAMES
+"and rd,imm16",16,7,
+0x18,
+#endif
+"and",OPC_and,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+7,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,20},
+
+
+/* 1000 0111 ssss dddd *** and rd,rs */
+{
+#ifdef NICENAMES
+"and rd,rs",16,4,
+0x18,
+#endif
+"and",OPC_and,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+7,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,21},
+
+
+/* 0000 0110 ssN0 dddd *** andb rbd,@rs */
+{
+#ifdef NICENAMES
+"andb rbd,@rs",8,7,
+0x1c,
+#endif
+"andb",OPC_andb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+6,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,22},
+
+
+/* 0100 0110 0000 dddd address_src *** andb rbd,address_src */
+{
+#ifdef NICENAMES
+"andb rbd,address_src",8,9,
+0x1c,
+#endif
+"andb",OPC_andb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,23},
+
+
+/* 0100 0110 ssN0 dddd address_src *** andb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"andb rbd,address_src(rs)",8,10,
+0x1c,
+#endif
+"andb",OPC_andb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+6,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,24},
+
+
+/* 0000 0110 0000 dddd imm8 imm8 *** andb rbd,imm8 */
+{
+#ifdef NICENAMES
+"andb rbd,imm8",8,7,
+0x1c,
+#endif
+"andb",OPC_andb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,25},
+
+
+/* 1000 0110 ssss dddd *** andb rbd,rbs */
+{
+#ifdef NICENAMES
+"andb rbd,rbs",8,4,
+0x1c,
+#endif
+"andb",OPC_andb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+6,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,26},
+
+
+/* 0010 0111 ddN0 imm4 *** bit @rd,imm4 */
+{
+#ifdef NICENAMES
+"bit @rd,imm4",16,8,
+0x10,
+#endif
+"bit",OPC_bit,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+2,CLASS_BIT+7,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,27},
+
+
+/* 0110 0111 ddN0 imm4 address_dst *** bit address_dst(rd),imm4 */
+{
+#ifdef NICENAMES
+"bit address_dst(rd),imm4",16,11,
+0x10,
+#endif
+"bit",OPC_bit,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+7,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,28},
+
+
+/* 0110 0111 0000 imm4 address_dst *** bit address_dst,imm4 */
+{
+#ifdef NICENAMES
+"bit address_dst,imm4",16,10,
+0x10,
+#endif
+"bit",OPC_bit,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+7,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,29},
+
+
+/* 1010 0111 dddd imm4 *** bit rd,imm4 */
+{
+#ifdef NICENAMES
+"bit rd,imm4",16,4,
+0x10,
+#endif
+"bit",OPC_bit,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xa,CLASS_BIT+7,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,30},
+
+
+/* 0010 0111 0000 ssss 0000 dddd 0000 0000 *** bit rd,rs */
+{
+#ifdef NICENAMES
+"bit rd,rs",16,10,
+0x10,
+#endif
+"bit",OPC_bit,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+7,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,31},
+
+
+/* 0010 0110 ddN0 imm4 *** bitb @rd,imm4 */
+{
+#ifdef NICENAMES
+"bitb @rd,imm4",8,8,
+0x10,
+#endif
+"bitb",OPC_bitb,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+2,CLASS_BIT+6,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,32},
+
+
+/* 0110 0110 ddN0 imm4 address_dst *** bitb address_dst(rd),imm4 */
+{
+#ifdef NICENAMES
+"bitb address_dst(rd),imm4",8,11,
+0x10,
+#endif
+"bitb",OPC_bitb,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+6,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,33},
+
+
+/* 0110 0110 0000 imm4 address_dst *** bitb address_dst,imm4 */
+{
+#ifdef NICENAMES
+"bitb address_dst,imm4",8,10,
+0x10,
+#endif
+"bitb",OPC_bitb,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+6,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,34},
+
+
+/* 1010 0110 dddd imm4 *** bitb rbd,imm4 */
+{
+#ifdef NICENAMES
+"bitb rbd,imm4",8,4,
+0x10,
+#endif
+"bitb",OPC_bitb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xa,CLASS_BIT+6,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,35},
+
+
+/* 0010 0110 0000 ssss 0000 dddd 0000 0000 *** bitb rbd,rs */
+{
+#ifdef NICENAMES
+"bitb rbd,rs",8,10,
+0x10,
+#endif
+"bitb",OPC_bitb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,36},
+
+
+/* 0011 0110 0000 0000 *** bpt */
+{
+#ifdef NICENAMES
+"bpt",8,2,
+0x00,
+#endif
+"bpt",OPC_bpt,0,{0},
+ {CLASS_BIT+3,CLASS_BIT+6,CLASS_BIT+0,CLASS_BIT+0,0,0,0,0,0,},0,2,37},
+
+
+/* 0001 1111 ddN0 0000 *** call @rd */
+{
+#ifdef NICENAMES
+"call @rd",32,10,
+0x00,
+#endif
+"call",OPC_call,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+1,CLASS_BIT+0xf,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,38},
+
+
+/* 0101 1111 0000 0000 address_dst *** call address_dst */
+{
+#ifdef NICENAMES
+"call address_dst",32,12,
+0x00,
+#endif
+"call",OPC_call,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+5,CLASS_BIT+0xf,CLASS_BIT+0,CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,39},
+
+
+/* 0101 1111 ddN0 0000 address_dst *** call address_dst(rd) */
+{
+#ifdef NICENAMES
+"call address_dst(rd)",32,13,
+0x00,
+#endif
+"call",OPC_call,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+5,CLASS_BIT+0xf,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,40},
+
+
+/* 1101 disp12 *** calr disp12 */
+{
+#ifdef NICENAMES
+"calr disp12",16,10,
+0x00,
+#endif
+"calr",OPC_calr,0,{CLASS_DISP,},
+ {CLASS_BIT+0xd,CLASS_DISP+(ARG_DISP12),0,0,0,0,0,0,0,},1,2,41},
+
+
+/* 0000 1101 ddN0 1000 *** clr @rd */
+{
+#ifdef NICENAMES
+"clr @rd",16,8,
+0x00,
+#endif
+"clr",OPC_clr,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,0,0,0,0,},1,2,42},
+
+
+/* 0100 1101 0000 1000 address_dst *** clr address_dst */
+{
+#ifdef NICENAMES
+"clr address_dst",16,11,
+0x00,
+#endif
+"clr",OPC_clr,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+8,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,43},
+
+
+/* 0100 1101 ddN0 1000 address_dst *** clr address_dst(rd) */
+{
+#ifdef NICENAMES
+"clr address_dst(rd)",16,12,
+0x00,
+#endif
+"clr",OPC_clr,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,44},
+
+
+/* 1000 1101 dddd 1000 *** clr rd */
+{
+#ifdef NICENAMES
+"clr rd",16,7,
+0x00,
+#endif
+"clr",OPC_clr,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_BIT+8,0,0,0,0,0,},1,2,45},
+
+
+/* 0000 1100 ddN0 1000 *** clrb @rd */
+{
+#ifdef NICENAMES
+"clrb @rd",8,8,
+0x00,
+#endif
+"clrb",OPC_clrb,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,0,0,0,0,},1,2,46},
+
+
+/* 0100 1100 0000 1000 address_dst *** clrb address_dst */
+{
+#ifdef NICENAMES
+"clrb address_dst",8,11,
+0x00,
+#endif
+"clrb",OPC_clrb,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+8,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,47},
+
+
+/* 0100 1100 ddN0 1000 address_dst *** clrb address_dst(rd) */
+{
+#ifdef NICENAMES
+"clrb address_dst(rd)",8,12,
+0x00,
+#endif
+"clrb",OPC_clrb,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,48},
+
+
+/* 1000 1100 dddd 1000 *** clrb rbd */
+{
+#ifdef NICENAMES
+"clrb rbd",8,7,
+0x00,
+#endif
+"clrb",OPC_clrb,0,{CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_BIT+8,0,0,0,0,0,},1,2,49},
+
+
+/* 0000 1101 ddN0 0000 *** com @rd */
+{
+#ifdef NICENAMES
+"com @rd",16,12,
+0x18,
+#endif
+"com",OPC_com,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,50},
+
+
+/* 0100 1101 0000 0000 address_dst *** com address_dst */
+{
+#ifdef NICENAMES
+"com address_dst",16,15,
+0x18,
+#endif
+"com",OPC_com,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,51},
+
+
+/* 0100 1101 ddN0 0000 address_dst *** com address_dst(rd) */
+{
+#ifdef NICENAMES
+"com address_dst(rd)",16,16,
+0x18,
+#endif
+"com",OPC_com,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,52},
+
+
+/* 1000 1101 dddd 0000 *** com rd */
+{
+#ifdef NICENAMES
+"com rd",16,7,
+0x18,
+#endif
+"com",OPC_com,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,53},
+
+
+/* 0000 1100 ddN0 0000 *** comb @rd */
+{
+#ifdef NICENAMES
+"comb @rd",8,12,
+0x1c,
+#endif
+"comb",OPC_comb,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,54},
+
+
+/* 0100 1100 0000 0000 address_dst *** comb address_dst */
+{
+#ifdef NICENAMES
+"comb address_dst",8,15,
+0x1c,
+#endif
+"comb",OPC_comb,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,55},
+
+
+/* 0100 1100 ddN0 0000 address_dst *** comb address_dst(rd) */
+{
+#ifdef NICENAMES
+"comb address_dst(rd)",8,16,
+0x1c,
+#endif
+"comb",OPC_comb,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,56},
+
+
+/* 1000 1100 dddd 0000 *** comb rbd */
+{
+#ifdef NICENAMES
+"comb rbd",8,7,
+0x1c,
+#endif
+"comb",OPC_comb,0,{CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,57},
+
+
+/* 1000 1101 flags 0101 *** comflg flags */
+{
+#ifdef NICENAMES
+"comflg flags",16,7,
+0x3c,
+#endif
+"comflg",OPC_comflg,0,{CLASS_FLAGS,},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_FLAGS,CLASS_BIT+5,0,0,0,0,0,},1,2,58},
+
+
+/* 0000 1101 ddN0 0001 imm16 *** cp @rd,imm16 */
+{
+#ifdef NICENAMES
+"cp @rd,imm16",16,11,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_IR+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+1,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,59},
+
+
+/* 0100 1101 ddN0 0001 address_dst imm16 *** cp address_dst(rd),imm16 */
+{
+#ifdef NICENAMES
+"cp address_dst(rd),imm16",16,15,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_X+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+1,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM16),0,0,0,},2,6,60},
+
+
+/* 0100 1101 0000 0001 address_dst imm16 *** cp address_dst,imm16 */
+{
+#ifdef NICENAMES
+"cp address_dst,imm16",16,14,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_DA+(ARG_DST),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+1,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM16),0,0,0,},2,6,61},
+
+
+/* 0000 1011 ssN0 dddd *** cp rd,@rs */
+{
+#ifdef NICENAMES
+"cp rd,@rs",16,7,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,62},
+
+
+/* 0100 1011 0000 dddd address_src *** cp rd,address_src */
+{
+#ifdef NICENAMES
+"cp rd,address_src",16,9,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,63},
+
+
+/* 0100 1011 ssN0 dddd address_src *** cp rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"cp rd,address_src(rs)",16,10,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,64},
+
+
+/* 0000 1011 0000 dddd imm16 *** cp rd,imm16 */
+{
+#ifdef NICENAMES
+"cp rd,imm16",16,7,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,65},
+
+
+/* 1000 1011 ssss dddd *** cp rd,rs */
+{
+#ifdef NICENAMES
+"cp rd,rs",16,4,
+0x3c,
+#endif
+"cp",OPC_cp,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+0xb,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,66},
+
+
+/* 0000 1100 ddN0 0001 imm8 imm8 *** cpb @rd,imm8 */
+{
+#ifdef NICENAMES
+"cpb @rd,imm8",8,11,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_IR+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+1,CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,67},
+
+
+/* 0100 1100 ddN0 0001 address_dst imm8 imm8 *** cpb address_dst(rd),imm8 */
+{
+#ifdef NICENAMES
+"cpb address_dst(rd),imm8",8,15,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_X+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+1,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,},2,6,68},
+
+
+/* 0100 1100 0000 0001 address_dst imm8 imm8 *** cpb address_dst,imm8 */
+{
+#ifdef NICENAMES
+"cpb address_dst,imm8",8,14,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_DA+(ARG_DST),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+1,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,},2,6,69},
+
+
+/* 0000 1010 ssN0 dddd *** cpb rbd,@rs */
+{
+#ifdef NICENAMES
+"cpb rbd,@rs",8,7,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,70},
+
+
+/* 0100 1010 0000 dddd address_src *** cpb rbd,address_src */
+{
+#ifdef NICENAMES
+"cpb rbd,address_src",8,9,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,71},
+
+
+/* 0100 1010 ssN0 dddd address_src *** cpb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"cpb rbd,address_src(rs)",8,10,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,72},
+
+
+/* 0000 1010 0000 dddd imm8 imm8 *** cpb rbd,imm8 */
+{
+#ifdef NICENAMES
+"cpb rbd,imm8",8,7,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,73},
+
+
+/* 1000 1010 ssss dddd *** cpb rbd,rbs */
+{
+#ifdef NICENAMES
+"cpb rbd,rbs",8,4,
+0x3c,
+#endif
+"cpb",OPC_cpb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+0xa,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,74},
+
+
+/* 1011 1011 ssN0 1000 0000 rrrr dddd cccc *** cpd rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpd rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpd",OPC_cpd,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,75},
+
+
+/* 1011 1010 ssN0 1000 0000 rrrr dddd cccc *** cpdb rbd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpdb rbd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpdb",OPC_cpdb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,76},
+
+
+/* 1011 1011 ssN0 1100 0000 rrrr dddd cccc *** cpdr rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpdr rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpdr",OPC_cpdr,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xc,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,77},
+
+
+/* 1011 1010 ssN0 1100 0000 rrrr dddd cccc *** cpdrb rbd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpdrb rbd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpdrb",OPC_cpdrb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xc,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,78},
+
+
+/* 1011 1011 ssN0 0000 0000 rrrr dddd cccc *** cpi rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpi rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpi",OPC_cpi,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,79},
+
+
+/* 1011 1010 ssN0 0000 0000 rrrr dddd cccc *** cpib rbd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpib rbd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpib",OPC_cpib,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,80},
+
+
+/* 1011 1011 ssN0 0100 0000 rrrr dddd cccc *** cpir rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpir rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpir",OPC_cpir,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,81},
+
+
+/* 1011 1010 ssN0 0100 0000 rrrr dddd cccc *** cpirb rbd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpirb rbd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpirb",OPC_cpirb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REG+(ARG_RD),CLASS_CC,0,},4,4,82},
+
+
+/* 0001 0000 ssN0 dddd *** cpl rrd,@rs */
+{
+#ifdef NICENAMES
+"cpl rrd,@rs",32,14,
+0x3c,
+#endif
+"cpl",OPC_cpl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,83},
+
+
+/* 0101 0000 0000 dddd address_src *** cpl rrd,address_src */
+{
+#ifdef NICENAMES
+"cpl rrd,address_src",32,15,
+0x3c,
+#endif
+"cpl",OPC_cpl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,84},
+
+
+/* 0101 0000 ssN0 dddd address_src *** cpl rrd,address_src(rs) */
+{
+#ifdef NICENAMES
+"cpl rrd,address_src(rs)",32,16,
+0x3c,
+#endif
+"cpl",OPC_cpl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,85},
+
+
+/* 0001 0000 0000 dddd imm32 *** cpl rrd,imm32 */
+{
+#ifdef NICENAMES
+"cpl rrd,imm32",32,14,
+0x3c,
+#endif
+"cpl",OPC_cpl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM32),},
+ {CLASS_BIT+1,CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM32),0,0,0,0,},2,6,86},
+
+
+/* 1001 0000 ssss dddd *** cpl rrd,rrs */
+{
+#ifdef NICENAMES
+"cpl rrd,rrs",32,8,
+0x3c,
+#endif
+"cpl",OPC_cpl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,87},
+
+
+/* 1011 1011 ssN0 1010 0000 rrrr ddN0 cccc *** cpsd @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsd @rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpsd",OPC_cpsd,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,88},
+
+
+/* 1011 1010 ssN0 1010 0000 rrrr ddN0 cccc *** cpsdb @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsdb @rd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpsdb",OPC_cpsdb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,89},
+
+
+/* 1011 1011 ssN0 1110 0000 rrrr ddN0 cccc *** cpsdr @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsdr @rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpsdr",OPC_cpsdr,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xe,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,90},
+
+
+/* 1011 1010 ssN0 1110 0000 rrrr ddN0 cccc *** cpsdrb @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsdrb @rd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpsdrb",OPC_cpsdrb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xe,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,91},
+
+
+/* 1011 1011 ssN0 0010 0000 rrrr ddN0 cccc *** cpsi @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsi @rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpsi",OPC_cpsi,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,92},
+
+
+/* 1011 1010 ssN0 0010 0000 rrrr ddN0 cccc *** cpsib @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsib @rd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpsib",OPC_cpsib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,93},
+
+
+/* 1011 1011 ssN0 0110 0000 rrrr ddN0 cccc *** cpsir @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsir @rd,@rs,rr,cc",16,11,
+0x3c,
+#endif
+"cpsir",OPC_cpsir,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,94},
+
+
+/* 1011 1010 ssN0 0110 0000 rrrr ddN0 cccc *** cpsirb @rd,@rs,rr,cc */
+{
+#ifdef NICENAMES
+"cpsirb @rd,@rs,rr,cc",8,11,
+0x3c,
+#endif
+"cpsirb",OPC_cpsirb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),CLASS_CC,},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_CC,0,},4,4,95},
+
+
+/* 1011 0000 dddd 0000 *** dab rbd */
+{
+#ifdef NICENAMES
+"dab rbd",8,5,
+0x38,
+#endif
+"dab",OPC_dab,0,{CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,96},
+
+
+/* 1111 dddd 0disp7 *** dbjnz rbd,disp7 */
+{
+#ifdef NICENAMES
+"dbjnz rbd,disp7",16,11,
+0x00,
+#endif
+"dbjnz",OPC_dbjnz,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DISP,},
+ {CLASS_BIT+0xf,CLASS_REG+(ARG_RD),CLASS_0DISP7,0,0,0,0,0,0,},2,2,97},
+
+
+/* 0010 1011 ddN0 imm4m1 *** dec @rd,imm4m1 */
+{
+#ifdef NICENAMES
+"dec @rd,imm4m1",16,11,
+0x1c,
+#endif
+"dec",OPC_dec,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+2,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,98},
+
+
+/* 0110 1011 ddN0 imm4m1 address_dst *** dec address_dst(rd),imm4m1 */
+{
+#ifdef NICENAMES
+"dec address_dst(rd),imm4m1",16,14,
+0x1c,
+#endif
+"dec",OPC_dec,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,99},
+
+
+/* 0110 1011 0000 imm4m1 address_dst *** dec address_dst,imm4m1 */
+{
+#ifdef NICENAMES
+"dec address_dst,imm4m1",16,13,
+0x1c,
+#endif
+"dec",OPC_dec,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,100},
+
+
+/* 1010 1011 dddd imm4m1 *** dec rd,imm4m1 */
+{
+#ifdef NICENAMES
+"dec rd,imm4m1",16,4,
+0x1c,
+#endif
+"dec",OPC_dec,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+0xa,CLASS_BIT+0xb,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,101},
+
+
+/* 0010 1010 ddN0 imm4m1 *** decb @rd,imm4m1 */
+{
+#ifdef NICENAMES
+"decb @rd,imm4m1",8,11,
+0x1c,
+#endif
+"decb",OPC_decb,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+2,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,102},
+
+
+/* 0110 1010 ddN0 imm4m1 address_dst *** decb address_dst(rd),imm4m1 */
+{
+#ifdef NICENAMES
+"decb address_dst(rd),imm4m1",8,14,
+0x1c,
+#endif
+"decb",OPC_decb,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,103},
+
+
+/* 0110 1010 0000 imm4m1 address_dst *** decb address_dst,imm4m1 */
+{
+#ifdef NICENAMES
+"decb address_dst,imm4m1",8,13,
+0x1c,
+#endif
+"decb",OPC_decb,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+0xa,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,104},
+
+
+/* 1010 1010 dddd imm4m1 *** decb rbd,imm4m1 */
+{
+#ifdef NICENAMES
+"decb rbd,imm4m1",8,4,
+0x1c,
+#endif
+"decb",OPC_decb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+0xa,CLASS_BIT+0xa,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,105},
+
+
+/* 0111 1100 0000 00ii *** di i2 */
+{
+#ifdef NICENAMES
+"di i2",16,7,
+0x00,
+#endif
+"di",OPC_di,0,{CLASS_IMM+(ARG_IMM2),},
+ {CLASS_BIT+7,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_00II,0,0,0,0,0,},1,2,106},
+
+
+/* 0001 1011 ssN0 dddd *** div rrd,@rs */
+{
+#ifdef NICENAMES
+"div rrd,@rs",16,107,
+0x3c,
+#endif
+"div",OPC_div,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,107},
+
+
+/* 0101 1011 0000 dddd address_src *** div rrd,address_src */
+{
+#ifdef NICENAMES
+"div rrd,address_src",16,107,
+0x3c,
+#endif
+"div",OPC_div,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,108},
+
+
+/* 0101 1011 ssN0 dddd address_src *** div rrd,address_src(rs) */
+{
+#ifdef NICENAMES
+"div rrd,address_src(rs)",16,107,
+0x3c,
+#endif
+"div",OPC_div,0,{CLASS_REG_LONG+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,109},
+
+
+/* 0001 1011 0000 dddd imm16 *** div rrd,imm16 */
+{
+#ifdef NICENAMES
+"div rrd,imm16",16,107,
+0x3c,
+#endif
+"div",OPC_div,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+1,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,110},
+
+
+/* 1001 1011 ssss dddd *** div rrd,rs */
+{
+#ifdef NICENAMES
+"div rrd,rs",16,107,
+0x3c,
+#endif
+"div",OPC_div,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+0xb,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,111},
+
+
+/* 0001 1010 ssN0 dddd *** divl rqd,@rs */
+{
+#ifdef NICENAMES
+"divl rqd,@rs",32,744,
+0x3c,
+#endif
+"divl",OPC_divl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,112},
+
+
+/* 0101 1010 0000 dddd address_src *** divl rqd,address_src */
+{
+#ifdef NICENAMES
+"divl rqd,address_src",32,745,
+0x3c,
+#endif
+"divl",OPC_divl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,113},
+
+
+/* 0101 1010 ssN0 dddd address_src *** divl rqd,address_src(rs) */
+{
+#ifdef NICENAMES
+"divl rqd,address_src(rs)",32,746,
+0x3c,
+#endif
+"divl",OPC_divl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,114},
+
+
+/* 0001 1010 0000 dddd imm32 *** divl rqd,imm32 */
+{
+#ifdef NICENAMES
+"divl rqd,imm32",32,744,
+0x3c,
+#endif
+"divl",OPC_divl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_IMM+(ARG_IMM32),},
+ {CLASS_BIT+1,CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM32),0,0,0,0,},2,6,115},
+
+
+/* 1001 1010 ssss dddd *** divl rqd,rrs */
+{
+#ifdef NICENAMES
+"divl rqd,rrs",32,744,
+0x3c,
+#endif
+"divl",OPC_divl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+0xa,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,116},
+
+
+/* 1111 dddd 1disp7 *** djnz rd,disp7 */
+{
+#ifdef NICENAMES
+"djnz rd,disp7",16,11,
+0x00,
+#endif
+"djnz",OPC_djnz,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DISP,},
+ {CLASS_BIT+0xf,CLASS_REG+(ARG_RD),CLASS_1DISP7,0,0,0,0,0,0,},2,2,117},
+
+
+/* 0111 1100 0000 01ii *** ei i2 */
+{
+#ifdef NICENAMES
+"ei i2",16,7,
+0x00,
+#endif
+"ei",OPC_ei,0,{CLASS_IMM+(ARG_IMM2),},
+ {CLASS_BIT+7,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_01II,0,0,0,0,0,},1,2,118},
+
+
+/* 0010 1101 ssN0 dddd *** ex rd,@rs */
+{
+#ifdef NICENAMES
+"ex rd,@rs",16,12,
+0x00,
+#endif
+"ex",OPC_ex,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,119},
+
+
+/* 0110 1101 0000 dddd address_src *** ex rd,address_src */
+{
+#ifdef NICENAMES
+"ex rd,address_src",16,15,
+0x00,
+#endif
+"ex",OPC_ex,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+6,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,120},
+
+
+/* 0110 1101 ssN0 dddd address_src *** ex rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"ex rd,address_src(rs)",16,16,
+0x00,
+#endif
+"ex",OPC_ex,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,121},
+
+
+/* 1010 1101 ssss dddd *** ex rd,rs */
+{
+#ifdef NICENAMES
+"ex rd,rs",16,6,
+0x00,
+#endif
+"ex",OPC_ex,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xa,CLASS_BIT+0xd,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,122},
+
+
+/* 0010 1100 ssN0 dddd *** exb rbd,@rs */
+{
+#ifdef NICENAMES
+"exb rbd,@rs",8,12,
+0x00,
+#endif
+"exb",OPC_exb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,123},
+
+
+/* 0110 1100 0000 dddd address_src *** exb rbd,address_src */
+{
+#ifdef NICENAMES
+"exb rbd,address_src",8,15,
+0x00,
+#endif
+"exb",OPC_exb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+6,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,124},
+
+
+/* 0110 1100 ssN0 dddd address_src *** exb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"exb rbd,address_src(rs)",8,16,
+0x00,
+#endif
+"exb",OPC_exb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,125},
+
+
+/* 1010 1100 ssss dddd *** exb rbd,rbs */
+{
+#ifdef NICENAMES
+"exb rbd,rbs",8,6,
+0x00,
+#endif
+"exb",OPC_exb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+0xa,CLASS_BIT+0xc,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,126},
+
+
+/* 0000 1110 imm8 *** ext0e imm8 */
+{
+#ifdef NICENAMES
+"ext0e imm8",8,10,
+0x00,
+#endif
+"ext0e",OPC_ext0e,0,{CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+0xe,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},1,2,127},
+
+
+/* 0000 1111 imm8 *** ext0f imm8 */
+{
+#ifdef NICENAMES
+"ext0f imm8",8,10,
+0x00,
+#endif
+"ext0f",OPC_ext0f,0,{CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+0xf,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},1,2,128},
+
+
+/* 1000 1110 imm8 *** ext8e imm8 */
+{
+#ifdef NICENAMES
+"ext8e imm8",8,10,
+0x00,
+#endif
+"ext8e",OPC_ext8e,0,{CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+8,CLASS_BIT+0xe,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},1,2,129},
+
+
+/* 1000 1111 imm8 *** ext8f imm8 */
+{
+#ifdef NICENAMES
+"ext8f imm8",8,10,
+0x00,
+#endif
+"ext8f",OPC_ext8f,0,{CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+8,CLASS_BIT+0xf,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},1,2,130},
+
+
+/* 1011 0001 dddd 1010 *** exts rrd */
+{
+#ifdef NICENAMES
+"exts rrd",16,11,
+0x00,
+#endif
+"exts",OPC_exts,0,{CLASS_REG_LONG+(ARG_RD),},
+ {CLASS_BIT+0xb,CLASS_BIT+1,CLASS_REG+(ARG_RD),CLASS_BIT+0xa,0,0,0,0,0,},1,2,131},
+
+
+/* 1011 0001 dddd 0000 *** extsb rd */
+{
+#ifdef NICENAMES
+"extsb rd",8,11,
+0x00,
+#endif
+"extsb",OPC_extsb,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+0xb,CLASS_BIT+1,CLASS_REG+(ARG_RD),CLASS_BIT+0,0,0,0,0,0,},1,2,132},
+
+
+/* 1011 0001 dddd 0111 *** extsl rqd */
+{
+#ifdef NICENAMES
+"extsl rqd",32,11,
+0x00,
+#endif
+"extsl",OPC_extsl,0,{CLASS_REG_QUAD+(ARG_RD),},
+ {CLASS_BIT+0xb,CLASS_BIT+1,CLASS_REG+(ARG_RD),CLASS_BIT+7,0,0,0,0,0,},1,2,133},
+
+
+/* 0111 1010 0000 0000 *** halt */
+{
+#ifdef NICENAMES
+"halt",16,8,
+0x00,
+#endif
+"halt",OPC_halt,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+0xa,CLASS_BIT+0,CLASS_BIT+0,0,0,0,0,0,},0,2,134},
+
+
+/* 0011 1101 ssN0 dddd *** in rd,@rs */
+{
+#ifdef NICENAMES
+"in rd,@rs",16,10,
+0x00,
+#endif
+"in",OPC_in,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,135},
+
+
+/* 0011 1101 dddd 0100 imm16 *** in rd,imm16 */
+{
+#ifdef NICENAMES
+"in rd,imm16",16,12,
+0x00,
+#endif
+"in",OPC_in,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+3,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_BIT+4,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,136},
+
+
+/* 0011 1100 ssN0 dddd *** inb rbd,@rs */
+{
+#ifdef NICENAMES
+"inb rbd,@rs",8,12,
+0x00,
+#endif
+"inb",OPC_inb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,137},
+
+
+/* 0011 1010 dddd 0100 imm16 *** inb rbd,imm16 */
+{
+#ifdef NICENAMES
+"inb rbd,imm16",8,10,
+0x00,
+#endif
+"inb",OPC_inb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REG+(ARG_RD),CLASS_BIT+4,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,138},
+
+
+/* 0010 1001 ddN0 imm4m1 *** inc @rd,imm4m1 */
+{
+#ifdef NICENAMES
+"inc @rd,imm4m1",16,11,
+0x1c,
+#endif
+"inc",OPC_inc,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+2,CLASS_BIT+9,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,139},
+
+
+/* 0110 1001 ddN0 imm4m1 address_dst *** inc address_dst(rd),imm4m1 */
+{
+#ifdef NICENAMES
+"inc address_dst(rd),imm4m1",16,14,
+0x1c,
+#endif
+"inc",OPC_inc,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+9,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,140},
+
+
+/* 0110 1001 0000 imm4m1 address_dst *** inc address_dst,imm4m1 */
+{
+#ifdef NICENAMES
+"inc address_dst,imm4m1",16,13,
+0x1c,
+#endif
+"inc",OPC_inc,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+9,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,141},
+
+
+/* 1010 1001 dddd imm4m1 *** inc rd,imm4m1 */
+{
+#ifdef NICENAMES
+"inc rd,imm4m1",16,4,
+0x1c,
+#endif
+"inc",OPC_inc,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+0xa,CLASS_BIT+9,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,142},
+
+
+/* 0010 1000 ddN0 imm4m1 *** incb @rd,imm4m1 */
+{
+#ifdef NICENAMES
+"incb @rd,imm4m1",8,11,
+0x1c,
+#endif
+"incb",OPC_incb,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+2,CLASS_BIT+8,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,143},
+
+
+/* 0110 1000 ddN0 imm4m1 address_dst *** incb address_dst(rd),imm4m1 */
+{
+#ifdef NICENAMES
+"incb address_dst(rd),imm4m1",8,14,
+0x1c,
+#endif
+"incb",OPC_incb,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+8,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,144},
+
+
+/* 0110 1000 0000 imm4m1 address_dst *** incb address_dst,imm4m1 */
+{
+#ifdef NICENAMES
+"incb address_dst,imm4m1",8,13,
+0x1c,
+#endif
+"incb",OPC_incb,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+6,CLASS_BIT+8,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4M1),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,145},
+
+
+/* 1010 1000 dddd imm4m1 *** incb rbd,imm4m1 */
+{
+#ifdef NICENAMES
+"incb rbd,imm4m1",8,4,
+0x1c,
+#endif
+"incb",OPC_incb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM +(ARG_IMM4M1),},
+ {CLASS_BIT+0xa,CLASS_BIT+8,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4M1),0,0,0,0,0,},2,2,146},
+
+
+/* 0011 1011 ssN0 1000 0000 aaaa ddN0 1000 *** ind @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"ind @rd,@rs,ra",16,21,
+0x04,
+#endif
+"ind",OPC_ind,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,147},
+
+
+/* 0011 1010 ssN0 1000 0000 aaaa ddN0 1000 *** indb @rd,@rs,rba */
+{
+#ifdef NICENAMES
+"indb @rd,@rs,rba",8,21,
+0x04,
+#endif
+"indb",OPC_indb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,148},
+
+
+/* 0011 1010 ssN0 0000 0000 aaaa ddN0 1000 *** inib @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"inib @rd,@rs,ra",8,21,
+0x04,
+#endif
+"inib",OPC_inib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,149},
+
+
+/* 0011 1010 ssN0 0000 0000 aaaa ddN0 0000 *** inibr @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"inibr @rd,@rs,ra",16,21,
+0x04,
+#endif
+"inibr",OPC_inibr,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,150},
+
+
+/* 0111 1011 0000 0000 *** iret */
+{
+#ifdef NICENAMES
+"iret",16,13,
+0x3f,
+#endif
+"iret",OPC_iret,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_BIT+0,0,0,0,0,0,},0,2,151},
+
+
+/* 0001 1110 ddN0 cccc *** jp cc,@rd */
+{
+#ifdef NICENAMES
+"jp cc,@rd",16,10,
+0x00,
+#endif
+"jp",OPC_jp,0,{CLASS_CC,CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+1,CLASS_BIT+0xe,CLASS_REGN0+(ARG_RD),CLASS_CC,0,0,0,0,0,},2,2,152},
+
+
+/* 0101 1110 0000 cccc address_dst *** jp cc,address_dst */
+{
+#ifdef NICENAMES
+"jp cc,address_dst",16,7,
+0x00,
+#endif
+"jp",OPC_jp,0,{CLASS_CC,CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+5,CLASS_BIT+0xe,CLASS_BIT+0,CLASS_CC,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,153},
+
+
+/* 0101 1110 ddN0 cccc address_dst *** jp cc,address_dst(rd) */
+{
+#ifdef NICENAMES
+"jp cc,address_dst(rd)",16,8,
+0x00,
+#endif
+"jp",OPC_jp,0,{CLASS_CC,CLASS_X+(ARG_RD),},
+ {CLASS_BIT+5,CLASS_BIT+0xe,CLASS_REGN0+(ARG_RD),CLASS_CC,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,154},
+
+
+/* 1110 cccc disp8 *** jr cc,disp8 */
+{
+#ifdef NICENAMES
+"jr cc,disp8",16,6,
+0x00,
+#endif
+"jr",OPC_jr,0,{CLASS_CC,CLASS_DISP,},
+ {CLASS_BIT+0xe,CLASS_CC,CLASS_DISP8,0,0,0,0,0,0,},2,2,155},
+
+
+/* 0000 1101 ddN0 0101 imm16 *** ld @rd,imm16 */
+{
+#ifdef NICENAMES
+"ld @rd,imm16",16,7,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_IR+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+5,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,156},
+
+
+/* 0010 1111 ddN0 ssss *** ld @rd,rs */
+{
+#ifdef NICENAMES
+"ld @rd,rs",16,8,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_IR+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+0xf,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,157},
+
+
+/* 0100 1101 ddN0 0101 address_dst imm16 *** ld address_dst(rd),imm16 */
+{
+#ifdef NICENAMES
+"ld address_dst(rd),imm16",16,15,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_X+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+5,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM16),0,0,0,},2,6,158},
+
+
+/* 0110 1111 ddN0 ssss address_dst *** ld address_dst(rd),rs */
+{
+#ifdef NICENAMES
+"ld address_dst(rd),rs",16,12,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_X+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0xf,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,159},
+
+
+/* 0100 1101 0000 0101 address_dst imm16 *** ld address_dst,imm16 */
+{
+#ifdef NICENAMES
+"ld address_dst,imm16",16,14,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_DA+(ARG_DST),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+5,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM16),0,0,0,},2,6,160},
+
+
+/* 0110 1111 0000 ssss address_dst *** ld address_dst,rs */
+{
+#ifdef NICENAMES
+"ld address_dst,rs",16,11,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_DA+(ARG_DST),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0xf,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,161},
+
+
+/* 0011 0011 ddN0 ssss imm16 *** ld rd(imm16),rs */
+{
+#ifdef NICENAMES
+"ld rd(imm16),rs",16,14,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_BA+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,162},
+
+
+/* 0111 0011 ddN0 ssss 0000 xxxx 0000 0000 *** ld rd(rx),rs */
+{
+#ifdef NICENAMES
+"ld rd(rx),rs",16,14,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_BX+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,163},
+
+
+/* 0010 0001 ssN0 dddd *** ld rd,@rs */
+{
+#ifdef NICENAMES
+"ld rd,@rs",16,7,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+1,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,164},
+
+
+/* 0110 0001 0000 dddd address_src *** ld rd,address_src */
+{
+#ifdef NICENAMES
+"ld rd,address_src",16,9,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+6,CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,165},
+
+
+/* 0110 0001 ssN0 dddd address_src *** ld rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"ld rd,address_src(rs)",16,10,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+1,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,166},
+
+
+/* 0010 0001 0000 dddd imm16 *** ld rd,imm16 */
+{
+#ifdef NICENAMES
+"ld rd,imm16",16,7,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+2,CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,167},
+
+
+/* 1010 0001 ssss dddd *** ld rd,rs */
+{
+#ifdef NICENAMES
+"ld rd,rs",16,3,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xa,CLASS_BIT+1,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,168},
+
+
+/* 0011 0001 ssN0 dddd imm16 *** ld rd,rs(imm16) */
+{
+#ifdef NICENAMES
+"ld rd,rs(imm16)",16,14,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_BA+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+1,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,169},
+
+
+/* 0111 0001 ssN0 dddd 0000 xxxx 0000 0000 *** ld rd,rs(rx) */
+{
+#ifdef NICENAMES
+"ld rd,rs(rx)",16,14,
+0x00,
+#endif
+"ld",OPC_ld,0,{CLASS_REG_WORD+(ARG_RD),CLASS_BX+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+1,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,170},
+
+
+/* 0111 0110 0000 dddd address_src *** lda prd,address_src */
+{
+#ifdef NICENAMES
+"lda prd,address_src",16,12,
+0x00,
+#endif
+"lda",OPC_lda,0,{CLASS_PR+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+7,CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,171},
+
+
+/* 0111 0110 ssN0 dddd address_src *** lda prd,address_src(rs) */
+{
+#ifdef NICENAMES
+"lda prd,address_src(rs)",16,13,
+0x00,
+#endif
+"lda",OPC_lda,0,{CLASS_PR+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+6,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,172},
+
+
+/* 0011 0100 ssN0 dddd imm16 *** lda prd,rs(imm16) */
+{
+#ifdef NICENAMES
+"lda prd,rs(imm16)",16,15,
+0x00,
+#endif
+"lda",OPC_lda,0,{CLASS_PR+(ARG_RD),CLASS_BA+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+4,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,173},
+
+
+/* 0111 0100 ssN0 dddd 0000 xxxx 0000 0000 *** lda prd,rs(rx) */
+{
+#ifdef NICENAMES
+"lda prd,rs(rx)",16,15,
+0x00,
+#endif
+"lda",OPC_lda,0,{CLASS_PR+(ARG_RD),CLASS_BX+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+4,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,174},
+
+
+/* 0011 0100 0000 dddd disp16 *** ldar prd,disp16 */
+{
+#ifdef NICENAMES
+"ldar prd,disp16",16,15,
+0x00,
+#endif
+"ldar",OPC_ldar,0,{CLASS_PR+(ARG_RD),CLASS_DISP,},
+ {CLASS_BIT+3,CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,175},
+
+
+/* 0000 1100 ddN0 0101 imm8 imm8 *** ldb @rd,imm8 */
+{
+#ifdef NICENAMES
+"ldb @rd,imm8",8,7,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_IR+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+5,CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,176},
+
+
+/* 0010 1110 ddN0 ssss *** ldb @rd,rbs */
+{
+#ifdef NICENAMES
+"ldb @rd,rbs",8,8,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_IR+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+0xe,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,177},
+
+
+/* 0100 1100 ddN0 0101 address_dst imm8 imm8 *** ldb address_dst(rd),imm8 */
+{
+#ifdef NICENAMES
+"ldb address_dst(rd),imm8",8,15,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_X+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+5,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,},2,6,178},
+
+
+/* 0110 1110 ddN0 ssss address_dst *** ldb address_dst(rd),rbs */
+{
+#ifdef NICENAMES
+"ldb address_dst(rd),rbs",8,12,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_X+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0xe,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,179},
+
+
+/* 0100 1100 0000 0101 address_dst imm8 imm8 *** ldb address_dst,imm8 */
+{
+#ifdef NICENAMES
+"ldb address_dst,imm8",8,14,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_DA+(ARG_DST),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+5,CLASS_ADDRESS+(ARG_DST),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,},2,6,180},
+
+
+/* 0110 1110 0000 ssss address_dst *** ldb address_dst,rbs */
+{
+#ifdef NICENAMES
+"ldb address_dst,rbs",8,11,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_DA+(ARG_DST),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0xe,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,181},
+
+
+/* 0010 0000 ssN0 dddd *** ldb rbd,@rs */
+{
+#ifdef NICENAMES
+"ldb rbd,@rs",8,7,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,182},
+
+
+/* 0110 0000 0000 dddd address_src *** ldb rbd,address_src */
+{
+#ifdef NICENAMES
+"ldb rbd,address_src",8,9,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+6,CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,183},
+
+
+/* 0110 0000 ssN0 dddd address_src *** ldb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"ldb rbd,address_src(rs)",8,10,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+6,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,184},
+
+
+/* 1100 dddd imm8 *** ldb rbd,imm8 */
+{
+#ifdef NICENAMES
+"ldb rbd,imm8",8,5,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},2,2,185},
+
+
+/* 1010 0000 ssss dddd *** ldb rbd,rbs */
+{
+#ifdef NICENAMES
+"ldb rbd,rbs",8,3,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,186},
+
+
+/* 0011 0000 ssN0 dddd imm16 *** ldb rbd,rs(imm16) */
+{
+#ifdef NICENAMES
+"ldb rbd,rs(imm16)",8,14,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_BA+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,187},
+
+
+/* 0111 0000 ssN0 dddd 0000 xxxx 0000 0000 *** ldb rbd,rs(rx) */
+{
+#ifdef NICENAMES
+"ldb rbd,rs(rx)",8,14,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_BX+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+0,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,188},
+
+
+/* 0011 0010 ddN0 ssss imm16 *** ldb rd(imm16),rbs */
+{
+#ifdef NICENAMES
+"ldb rd(imm16),rbs",8,14,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_BA+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+2,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,189},
+
+
+/* 0111 0010 ddN0 ssss 0000 xxxx 0000 0000 *** ldb rd(rx),rbs */
+{
+#ifdef NICENAMES
+"ldb rd(rx),rbs",8,14,
+0x00,
+#endif
+"ldb",OPC_ldb,0,{CLASS_BX+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+2,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,190},
+
+
+/* 0111 1101 ssss 1ccc *** ldctl ctrl,rs */
+{
+#ifdef NICENAMES
+"ldctl ctrl,rs",32,7,
+0x00,
+#endif
+"ldctl",OPC_ldctl,0,{CLASS_CTRL,CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+0xd,CLASS_REG+(ARG_RS),CLASS_1CCC,0,0,0,0,0,},2,2,191},
+
+
+/* 0111 1101 dddd 0ccc *** ldctl rd,ctrl */
+{
+#ifdef NICENAMES
+"ldctl rd,ctrl",32,7,
+0x00,
+#endif
+"ldctl",OPC_ldctl,0,{CLASS_REG_WORD+(ARG_RD),CLASS_CTRL,},
+ {CLASS_BIT+7,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_0CCC,0,0,0,0,0,},2,2,192},
+
+
+/* 1011 1011 ssN0 1001 0000 rrrr ddN0 1000 *** ldd @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"ldd @rd,@rs,rr",16,11,
+0x04,
+#endif
+"ldd",OPC_ldd,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,193},
+
+
+/* 1011 1010 ssN0 1001 0000 rrrr ddN0 1000 *** lddb @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"lddb @rd,@rs,rr",8,11,
+0x04,
+#endif
+"lddb",OPC_lddb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,194},
+
+
+/* 1011 1011 ssN0 1001 0000 rrrr ddN0 0000 *** lddr @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"lddr @rd,@rs,rr",16,11,
+0x04,
+#endif
+"lddr",OPC_lddr,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,195},
+
+
+/* 1011 1010 ssN0 1001 0000 rrrr ddN0 0000 *** lddrb @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"lddrb @rd,@rs,rr",8,11,
+0x04,
+#endif
+"lddrb",OPC_lddrb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,196},
+
+
+/* 1011 1011 ssN0 0001 0000 rrrr ddN0 1000 *** ldi @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"ldi @rd,@rs,rr",16,11,
+0x04,
+#endif
+"ldi",OPC_ldi,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,197},
+
+
+/* 1011 1010 ssN0 0001 0000 rrrr ddN0 1000 *** ldib @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"ldib @rd,@rs,rr",8,11,
+0x04,
+#endif
+"ldib",OPC_ldib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,198},
+
+
+/* 1011 1011 ssN0 0001 0000 rrrr ddN0 0000 *** ldir @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"ldir @rd,@rs,rr",16,11,
+0x04,
+#endif
+"ldir",OPC_ldir,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,199},
+
+
+/* 1011 1010 ssN0 0001 0000 rrrr ddN0 0000 *** ldirb @rd,@rs,rr */
+{
+#ifdef NICENAMES
+"ldirb @rd,@rs,rr",8,11,
+0x04,
+#endif
+"ldirb",OPC_ldirb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,200},
+
+
+/* 1011 1101 dddd imm4 *** ldk rd,imm4 */
+{
+#ifdef NICENAMES
+"ldk rd,imm4",16,5,
+0x00,
+#endif
+"ldk",OPC_ldk,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,201},
+
+
+/* 0001 1101 ddN0 ssss *** ldl @rd,rrs */
+{
+#ifdef NICENAMES
+"ldl @rd,rrs",32,11,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_IR+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,202},
+
+
+/* 0101 1101 ddN0 ssss address_dst *** ldl address_dst(rd),rrs */
+{
+#ifdef NICENAMES
+"ldl address_dst(rd),rrs",32,14,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_X+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,203},
+
+
+/* 0101 1101 0000 ssss address_dst *** ldl address_dst,rrs */
+{
+#ifdef NICENAMES
+"ldl address_dst,rrs",32,15,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_DA+(ARG_DST),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,204},
+
+
+/* 0011 0111 ddN0 ssss imm16 *** ldl rd(imm16),rrs */
+{
+#ifdef NICENAMES
+"ldl rd(imm16),rrs",32,17,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_BA+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+7,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,205},
+
+
+/* 0111 0111 ddN0 ssss 0000 xxxx 0000 0000 *** ldl rd(rx),rrs */
+{
+#ifdef NICENAMES
+"ldl rd(rx),rrs",32,17,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_BX+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+7,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,206},
+
+
+/* 0001 0100 ssN0 dddd *** ldl rrd,@rs */
+{
+#ifdef NICENAMES
+"ldl rrd,@rs",32,11,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+4,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,207},
+
+
+/* 0101 0100 0000 dddd address_src *** ldl rrd,address_src */
+{
+#ifdef NICENAMES
+"ldl rrd,address_src",32,12,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,208},
+
+
+/* 0101 0100 ssN0 dddd address_src *** ldl rrd,address_src(rs) */
+{
+#ifdef NICENAMES
+"ldl rrd,address_src(rs)",32,13,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+4,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,209},
+
+
+/* 0001 0100 0000 dddd imm32 *** ldl rrd,imm32 */
+{
+#ifdef NICENAMES
+"ldl rrd,imm32",32,11,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM32),},
+ {CLASS_BIT+1,CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM32),0,0,0,0,},2,6,210},
+
+
+/* 1001 0100 ssss dddd *** ldl rrd,rrs */
+{
+#ifdef NICENAMES
+"ldl rrd,rrs",32,5,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+4,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,211},
+
+
+/* 0011 0101 ssN0 dddd imm16 *** ldl rrd,rs(imm16) */
+{
+#ifdef NICENAMES
+"ldl rrd,rs(imm16)",32,17,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_BA+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,212},
+
+
+/* 0111 0101 ssN0 dddd 0000 xxxx 0000 0000 *** ldl rrd,rs(rx) */
+{
+#ifdef NICENAMES
+"ldl rrd,rs(rx)",32,17,
+0x00,
+#endif
+"ldl",OPC_ldl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_BX+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_REG+(ARG_RX),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,213},
+
+
+/* 0001 1100 ddN0 1001 0000 ssss 0000 nminus1 *** ldm @rd,rs,n */
+{
+#ifdef NICENAMES
+"ldm @rd,rs,n",16,11,
+0x00,
+#endif
+"ldm",OPC_ldm,0,{CLASS_IR+(ARG_RD),CLASS_REG_WORD+(ARG_RS),CLASS_IMM + (ARG_IMMN),},
+ {CLASS_BIT+1,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_IMM+(ARG_IMMNMINUS1),0,},3,4,214},
+
+
+/* 0101 1100 ddN0 1001 0000 ssss 0000 nminus1 address_dst *** ldm address_dst(rd),rs,n */
+{
+#ifdef NICENAMES
+"ldm address_dst(rd),rs,n",16,15,
+0x00,
+#endif
+"ldm",OPC_ldm,0,{CLASS_X+(ARG_RD),CLASS_REG_WORD+(ARG_RS),CLASS_IMM + (ARG_IMMN),},
+ {CLASS_BIT+5,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_IMM+(ARG_IMMNMINUS1),CLASS_ADDRESS+(ARG_DST),},3,6,215},
+
+
+/* 0101 1100 0000 1001 0000 ssss 0000 nminus1 address_dst *** ldm address_dst,rs,n */
+{
+#ifdef NICENAMES
+"ldm address_dst,rs,n",16,14,
+0x00,
+#endif
+"ldm",OPC_ldm,0,{CLASS_DA+(ARG_DST),CLASS_REG_WORD+(ARG_RS),CLASS_IMM + (ARG_IMMN),},
+ {CLASS_BIT+5,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_IMM+(ARG_IMMNMINUS1),CLASS_ADDRESS+(ARG_DST),},3,6,216},
+
+
+/* 0001 1100 ssN0 0001 0000 dddd 0000 nminus1 *** ldm rd,@rs,n */
+{
+#ifdef NICENAMES
+"ldm rd,@rs,n",16,11,
+0x00,
+#endif
+"ldm",OPC_ldm,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_IMM + (ARG_IMMN),},
+ {CLASS_BIT+1,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_IMM+(ARG_IMMNMINUS1),0,},3,4,217},
+
+
+/* 0101 1100 ssN0 0001 0000 dddd 0000 nminus1 address_src *** ldm rd,address_src(rs),n */
+{
+#ifdef NICENAMES
+"ldm rd,address_src(rs),n",16,15,
+0x00,
+#endif
+"ldm",OPC_ldm,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),CLASS_IMM + (ARG_IMMN),},
+ {CLASS_BIT+5,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_IMM+(ARG_IMMNMINUS1),CLASS_ADDRESS+(ARG_SRC),},3,6,218},
+
+
+/* 0101 1100 0000 0001 0000 dddd 0000 nminus1 address_src *** ldm rd,address_src,n */
+{
+#ifdef NICENAMES
+"ldm rd,address_src,n",16,14,
+0x00,
+#endif
+"ldm",OPC_ldm,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),CLASS_IMM + (ARG_IMMN),},
+ {CLASS_BIT+5,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_IMM+(ARG_IMMNMINUS1),CLASS_ADDRESS+(ARG_SRC),},3,6,219},
+
+
+/* 0011 1001 ssN0 0000 *** ldps @rs */
+{
+#ifdef NICENAMES
+"ldps @rs",16,12,
+0x3f,
+#endif
+"ldps",OPC_ldps,0,{CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+9,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,0,0,0,0,0,},1,2,220},
+
+
+/* 0111 1001 0000 0000 address_src *** ldps address_src */
+{
+#ifdef NICENAMES
+"ldps address_src",16,16,
+0x3f,
+#endif
+"ldps",OPC_ldps,0,{CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+7,CLASS_BIT+9,CLASS_BIT+0,CLASS_BIT+0,CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},1,4,221},
+
+
+/* 0111 1001 ssN0 0000 address_src *** ldps address_src(rs) */
+{
+#ifdef NICENAMES
+"ldps address_src(rs)",16,17,
+0x3f,
+#endif
+"ldps",OPC_ldps,0,{CLASS_X+(ARG_RS),},
+ {CLASS_BIT+7,CLASS_BIT+9,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},1,4,222},
+
+
+/* 0011 0011 0000 ssss disp16 *** ldr disp16,rs */
+{
+#ifdef NICENAMES
+"ldr disp16,rs",16,14,
+0x00,
+#endif
+"ldr",OPC_ldr,0,{CLASS_DISP,CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,223},
+
+
+/* 0011 0001 0000 dddd disp16 *** ldr rd,disp16 */
+{
+#ifdef NICENAMES
+"ldr rd,disp16",16,14,
+0x00,
+#endif
+"ldr",OPC_ldr,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DISP,},
+ {CLASS_BIT+3,CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,224},
+
+
+/* 0011 0010 0000 ssss disp16 *** ldrb disp16,rbs */
+{
+#ifdef NICENAMES
+"ldrb disp16,rbs",8,14,
+0x00,
+#endif
+"ldrb",OPC_ldrb,0,{CLASS_DISP,CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,225},
+
+
+/* 0011 0000 0000 dddd disp16 *** ldrb rbd,disp16 */
+{
+#ifdef NICENAMES
+"ldrb rbd,disp16",8,14,
+0x00,
+#endif
+"ldrb",OPC_ldrb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DISP,},
+ {CLASS_BIT+3,CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,226},
+
+
+/* 0011 0111 0000 ssss disp16 *** ldrl disp16,rrs */
+{
+#ifdef NICENAMES
+"ldrl disp16,rrs",32,17,
+0x00,
+#endif
+"ldrl",OPC_ldrl,0,{CLASS_DISP,CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+7,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,227},
+
+
+/* 0011 0101 0000 dddd disp16 *** ldrl rrd,disp16 */
+{
+#ifdef NICENAMES
+"ldrl rrd,disp16",32,17,
+0x00,
+#endif
+"ldrl",OPC_ldrl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DISP,},
+ {CLASS_BIT+3,CLASS_BIT+5,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_DISP+(ARG_DISP16),0,0,0,0,},2,4,228},
+
+
+/* 0111 1011 0000 1010 *** mbit */
+{
+#ifdef NICENAMES
+"mbit",16,7,
+0x38,
+#endif
+"mbit",OPC_mbit,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_BIT+0xa,0,0,0,0,0,},0,2,229},
+
+
+/* 0111 1011 dddd 1101 *** mreq rd */
+{
+#ifdef NICENAMES
+"mreq rd",16,12,
+0x18,
+#endif
+"mreq",OPC_mreq,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+7,CLASS_BIT+0xb,CLASS_REG+(ARG_RD),CLASS_BIT+0xd,0,0,0,0,0,},1,2,230},
+
+
+/* 0111 1011 0000 1001 *** mres */
+{
+#ifdef NICENAMES
+"mres",16,5,
+0x00,
+#endif
+"mres",OPC_mres,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_BIT+9,0,0,0,0,0,},0,2,231},
+
+
+/* 0111 1011 0000 1000 *** mset */
+{
+#ifdef NICENAMES
+"mset",16,5,
+0x00,
+#endif
+"mset",OPC_mset,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+0xb,CLASS_BIT+0,CLASS_BIT+8,0,0,0,0,0,},0,2,232},
+
+
+/* 0001 1001 ssN0 dddd *** mult rrd,@rs */
+{
+#ifdef NICENAMES
+"mult rrd,@rs",16,70,
+0x3c,
+#endif
+"mult",OPC_mult,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+9,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,233},
+
+
+/* 0101 1001 0000 dddd address_src *** mult rrd,address_src */
+{
+#ifdef NICENAMES
+"mult rrd,address_src",16,70,
+0x3c,
+#endif
+"mult",OPC_mult,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,234},
+
+
+/* 0101 1001 ssN0 dddd address_src *** mult rrd,address_src(rs) */
+{
+#ifdef NICENAMES
+"mult rrd,address_src(rs)",16,70,
+0x3c,
+#endif
+"mult",OPC_mult,0,{CLASS_REG_LONG+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+9,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,235},
+
+
+/* 0001 1001 0000 dddd imm16 *** mult rrd,imm16 */
+{
+#ifdef NICENAMES
+"mult rrd,imm16",16,70,
+0x3c,
+#endif
+"mult",OPC_mult,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+1,CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,236},
+
+
+/* 1001 1001 ssss dddd *** mult rrd,rs */
+{
+#ifdef NICENAMES
+"mult rrd,rs",16,70,
+0x3c,
+#endif
+"mult",OPC_mult,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+9,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,237},
+
+
+/* 0001 1000 ssN0 dddd *** multl rqd,@rs */
+{
+#ifdef NICENAMES
+"multl rqd,@rs",32,282,
+0x3c,
+#endif
+"multl",OPC_multl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+8,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,238},
+
+
+/* 0101 1000 0000 dddd address_src *** multl rqd,address_src */
+{
+#ifdef NICENAMES
+"multl rqd,address_src",32,282,
+0x3c,
+#endif
+"multl",OPC_multl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,239},
+
+
+/* 0101 1000 ssN0 dddd address_src *** multl rqd,address_src(rs) */
+{
+#ifdef NICENAMES
+"multl rqd,address_src(rs)",32,282,
+0x3c,
+#endif
+"multl",OPC_multl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+8,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,240},
+
+
+/* 0001 1000 0000 dddd imm32 *** multl rqd,imm32 */
+{
+#ifdef NICENAMES
+"multl rqd,imm32",32,282,
+0x3c,
+#endif
+"multl",OPC_multl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_IMM+(ARG_IMM32),},
+ {CLASS_BIT+1,CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM32),0,0,0,0,},2,6,241},
+
+
+/* 1001 1000 ssss dddd *** multl rqd,rrs */
+{
+#ifdef NICENAMES
+"multl rqd,rrs",32,282,
+0x3c,
+#endif
+"multl",OPC_multl,0,{CLASS_REG_QUAD+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+8,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,242},
+
+
+/* 0000 1101 ddN0 0010 *** neg @rd */
+{
+#ifdef NICENAMES
+"neg @rd",16,12,
+0x3c,
+#endif
+"neg",OPC_neg,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+2,0,0,0,0,0,},1,2,243},
+
+
+/* 0100 1101 0000 0010 address_dst *** neg address_dst */
+{
+#ifdef NICENAMES
+"neg address_dst",16,15,
+0x3c,
+#endif
+"neg",OPC_neg,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+2,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,244},
+
+
+/* 0100 1101 ddN0 0010 address_dst *** neg address_dst(rd) */
+{
+#ifdef NICENAMES
+"neg address_dst(rd)",16,16,
+0x3c,
+#endif
+"neg",OPC_neg,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+2,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,245},
+
+
+/* 1000 1101 dddd 0010 *** neg rd */
+{
+#ifdef NICENAMES
+"neg rd",16,7,
+0x3c,
+#endif
+"neg",OPC_neg,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_BIT+2,0,0,0,0,0,},1,2,246},
+
+
+/* 0000 1100 ddN0 0010 *** negb @rd */
+{
+#ifdef NICENAMES
+"negb @rd",8,12,
+0x3c,
+#endif
+"negb",OPC_negb,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+2,0,0,0,0,0,},1,2,247},
+
+
+/* 0100 1100 0000 0010 address_dst *** negb address_dst */
+{
+#ifdef NICENAMES
+"negb address_dst",8,15,
+0x3c,
+#endif
+"negb",OPC_negb,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+2,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,248},
+
+
+/* 0100 1100 ddN0 0010 address_dst *** negb address_dst(rd) */
+{
+#ifdef NICENAMES
+"negb address_dst(rd)",8,16,
+0x3c,
+#endif
+"negb",OPC_negb,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+2,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,249},
+
+
+/* 1000 1100 dddd 0010 *** negb rbd */
+{
+#ifdef NICENAMES
+"negb rbd",8,7,
+0x3c,
+#endif
+"negb",OPC_negb,0,{CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_BIT+2,0,0,0,0,0,},1,2,250},
+
+
+/* 1000 1101 0000 0111 *** nop */
+{
+#ifdef NICENAMES
+"nop",16,7,
+0x00,
+#endif
+"nop",OPC_nop,0,{0},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+7,0,0,0,0,0,},0,2,251},
+
+
+/* 0000 0101 ssN0 dddd *** or rd,@rs */
+{
+#ifdef NICENAMES
+"or rd,@rs",16,7,
+0x38,
+#endif
+"or",OPC_or,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,252},
+
+
+/* 0100 0101 0000 dddd address_src *** or rd,address_src */
+{
+#ifdef NICENAMES
+"or rd,address_src",16,9,
+0x38,
+#endif
+"or",OPC_or,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+5,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,253},
+
+
+/* 0100 0101 ssN0 dddd address_src *** or rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"or rd,address_src(rs)",16,10,
+0x38,
+#endif
+"or",OPC_or,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,254},
+
+
+/* 0000 0101 0000 dddd imm16 *** or rd,imm16 */
+{
+#ifdef NICENAMES
+"or rd,imm16",16,7,
+0x38,
+#endif
+"or",OPC_or,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+5,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,255},
+
+
+/* 1000 0101 ssss dddd *** or rd,rs */
+{
+#ifdef NICENAMES
+"or rd,rs",16,4,
+0x38,
+#endif
+"or",OPC_or,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+5,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,256},
+
+
+/* 0000 0100 ssN0 dddd *** orb rbd,@rs */
+{
+#ifdef NICENAMES
+"orb rbd,@rs",8,7,
+0x3c,
+#endif
+"orb",OPC_orb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+4,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,257},
+
+
+/* 0100 0100 0000 dddd address_src *** orb rbd,address_src */
+{
+#ifdef NICENAMES
+"orb rbd,address_src",8,9,
+0x3c,
+#endif
+"orb",OPC_orb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,258},
+
+
+/* 0100 0100 ssN0 dddd address_src *** orb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"orb rbd,address_src(rs)",8,10,
+0x3c,
+#endif
+"orb",OPC_orb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+4,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,259},
+
+
+/* 0000 0100 0000 dddd imm8 imm8 *** orb rbd,imm8 */
+{
+#ifdef NICENAMES
+"orb rbd,imm8",8,7,
+0x3c,
+#endif
+"orb",OPC_orb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,260},
+
+
+/* 1000 0100 ssss dddd *** orb rbd,rbs */
+{
+#ifdef NICENAMES
+"orb rbd,rbs",8,4,
+0x3c,
+#endif
+"orb",OPC_orb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+4,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,261},
+
+
+/* 0011 1111 ddN0 ssss *** out @rd,rs */
+{
+#ifdef NICENAMES
+"out @rd,rs",16,0,
+0x04,
+#endif
+"out",OPC_out,0,{CLASS_IR+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xf,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,262},
+
+
+/* 0011 1011 ssss 0110 imm16 *** out imm16,rs */
+{
+#ifdef NICENAMES
+"out imm16,rs",16,0,
+0x04,
+#endif
+"out",OPC_out,0,{CLASS_IMM+(ARG_IMM16),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REG+(ARG_RS),CLASS_BIT+6,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,263},
+
+
+/* 0011 1110 ddN0 ssss *** outb @rd,rbs */
+{
+#ifdef NICENAMES
+"outb @rd,rbs",8,0,
+0x04,
+#endif
+"outb",OPC_outb,0,{CLASS_IR+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xe,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,264},
+
+
+/* 0011 1010 ssss 0110 imm16 *** outb imm16,rbs */
+{
+#ifdef NICENAMES
+"outb imm16,rbs",8,0,
+0x04,
+#endif
+"outb",OPC_outb,0,{CLASS_IMM+(ARG_IMM16),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REG+(ARG_RS),CLASS_BIT+6,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,265},
+
+
+/* 0011 1011 ssN0 1010 0000 aaaa ddN0 1000 *** outd @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"outd @rd,@rs,ra",16,0,
+0x04,
+#endif
+"outd",OPC_outd,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,266},
+
+
+/* 0011 1010 ssN0 1010 0000 aaaa ddN0 1000 *** outdb @rd,@rs,rba */
+{
+#ifdef NICENAMES
+"outdb @rd,@rs,rba",16,0,
+0x04,
+#endif
+"outdb",OPC_outdb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,267},
+
+
+/* 0011 1011 ssN0 0010 0000 aaaa ddN0 1000 *** outi @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"outi @rd,@rs,ra",16,0,
+0x04,
+#endif
+"outi",OPC_outi,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,268},
+
+
+/* 0011 1010 ssN0 0010 0000 aaaa ddN0 1000 *** outib @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"outib @rd,@rs,ra",16,0,
+0x04,
+#endif
+"outib",OPC_outib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,269},
+
+
+/* 0011 1010 ssN0 0010 0000 aaaa ddN0 0000 *** outibr @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"outibr @rd,@rs,ra",16,0,
+0x04,
+#endif
+"outibr",OPC_outibr,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,270},
+
+
+/* 0001 0111 ssN0 ddN0 *** pop @rd,@rs */
+{
+#ifdef NICENAMES
+"pop @rd,@rs",16,12,
+0x00,
+#endif
+"pop",OPC_pop,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+7,CLASS_REGN0+(ARG_RS),CLASS_REGN0+(ARG_RD),0,0,0,0,0,},2,2,271},
+
+
+/* 0101 0111 ssN0 ddN0 address_dst *** pop address_dst(rd),@rs */
+{
+#ifdef NICENAMES
+"pop address_dst(rd),@rs",16,16,
+0x00,
+#endif
+"pop",OPC_pop,0,{CLASS_X+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+7,CLASS_REGN0+(ARG_RS),CLASS_REGN0+(ARG_RD),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,272},
+
+
+/* 0101 0111 ssN0 0000 address_dst *** pop address_dst,@rs */
+{
+#ifdef NICENAMES
+"pop address_dst,@rs",16,16,
+0x00,
+#endif
+"pop",OPC_pop,0,{CLASS_DA+(ARG_DST),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+7,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,273},
+
+
+/* 1001 0111 ssN0 dddd *** pop rd,@rs */
+{
+#ifdef NICENAMES
+"pop rd,@rs",16,8,
+0x00,
+#endif
+"pop",OPC_pop,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+7,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,274},
+
+
+/* 0001 0101 ssN0 ddN0 *** popl @rd,@rs */
+{
+#ifdef NICENAMES
+"popl @rd,@rs",32,19,
+0x00,
+#endif
+"popl",OPC_popl,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REGN0+(ARG_RD),0,0,0,0,0,},2,2,275},
+
+
+/* 0101 0101 ssN0 ddN0 address_dst *** popl address_dst(rd),@rs */
+{
+#ifdef NICENAMES
+"popl address_dst(rd),@rs",32,23,
+0x00,
+#endif
+"popl",OPC_popl,0,{CLASS_X+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REGN0+(ARG_RD),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,276},
+
+
+/* 0101 0101 ssN0 0000 address_dst *** popl address_dst,@rs */
+{
+#ifdef NICENAMES
+"popl address_dst,@rs",32,23,
+0x00,
+#endif
+"popl",OPC_popl,0,{CLASS_DA+(ARG_DST),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_BIT+0,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,277},
+
+
+/* 1001 0101 ssN0 dddd *** popl rrd,@rs */
+{
+#ifdef NICENAMES
+"popl rrd,@rs",32,12,
+0x00,
+#endif
+"popl",OPC_popl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+5,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,278},
+
+
+/* 0001 0011 ddN0 ssN0 *** push @rd,@rs */
+{
+#ifdef NICENAMES
+"push @rd,@rs",16,13,
+0x00,
+#endif
+"push",OPC_push,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_REGN0+(ARG_RS),0,0,0,0,0,},2,2,279},
+
+
+/* 0101 0011 ddN0 0000 address_src *** push @rd,address_src */
+{
+#ifdef NICENAMES
+"push @rd,address_src",16,14,
+0x00,
+#endif
+"push",OPC_push,0,{CLASS_IR+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,280},
+
+
+/* 0101 0011 ddN0 ssN0 address_src *** push @rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"push @rd,address_src(rs)",16,14,
+0x00,
+#endif
+"push",OPC_push,0,{CLASS_IR+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_REGN0+(ARG_RS),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,281},
+
+
+/* 0000 1101 ddN0 1001 imm16 *** push @rd,imm16 */
+{
+#ifdef NICENAMES
+"push @rd,imm16",16,12,
+0x00,
+#endif
+"push",OPC_push,0,{CLASS_IR+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+9,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,282},
+
+
+/* 1001 0011 ddN0 ssss *** push @rd,rs */
+{
+#ifdef NICENAMES
+"push @rd,rs",16,9,
+0x00,
+#endif
+"push",OPC_push,0,{CLASS_IR+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,283},
+
+
+/* 0001 0001 ddN0 ssN0 *** pushl @rd,@rs */
+{
+#ifdef NICENAMES
+"pushl @rd,@rs",32,20,
+0x00,
+#endif
+"pushl",OPC_pushl,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+1,CLASS_REGN0+(ARG_RD),CLASS_REGN0+(ARG_RS),0,0,0,0,0,},2,2,284},
+
+
+/* 0101 0001 ddN0 0000 address_src *** pushl @rd,address_src */
+{
+#ifdef NICENAMES
+"pushl @rd,address_src",32,21,
+0x00,
+#endif
+"pushl",OPC_pushl,0,{CLASS_IR+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+1,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,285},
+
+
+/* 0101 0001 ddN0 ssN0 address_src *** pushl @rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"pushl @rd,address_src(rs)",32,21,
+0x00,
+#endif
+"pushl",OPC_pushl,0,{CLASS_IR+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+1,CLASS_REGN0+(ARG_RD),CLASS_REGN0+(ARG_RS),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,286},
+
+
+/* 1001 0001 ddN0 ssss *** pushl @rd,rrs */
+{
+#ifdef NICENAMES
+"pushl @rd,rrs",32,12,
+0x00,
+#endif
+"pushl",OPC_pushl,0,{CLASS_IR+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+1,CLASS_REGN0+(ARG_RD),CLASS_REG+(ARG_RS),0,0,0,0,0,},2,2,287},
+
+
+/* 0010 0011 ddN0 imm4 *** res @rd,imm4 */
+{
+#ifdef NICENAMES
+"res @rd,imm4",16,11,
+0x00,
+#endif
+"res",OPC_res,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+2,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,288},
+
+
+/* 0110 0011 ddN0 imm4 address_dst *** res address_dst(rd),imm4 */
+{
+#ifdef NICENAMES
+"res address_dst(rd),imm4",16,14,
+0x00,
+#endif
+"res",OPC_res,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+3,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,289},
+
+
+/* 0110 0011 0000 imm4 address_dst *** res address_dst,imm4 */
+{
+#ifdef NICENAMES
+"res address_dst,imm4",16,13,
+0x00,
+#endif
+"res",OPC_res,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+3,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,290},
+
+
+/* 1010 0011 dddd imm4 *** res rd,imm4 */
+{
+#ifdef NICENAMES
+"res rd,imm4",16,4,
+0x00,
+#endif
+"res",OPC_res,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xa,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,291},
+
+
+/* 0010 0011 0000 ssss 0000 dddd 0000 0000 *** res rd,rs */
+{
+#ifdef NICENAMES
+"res rd,rs",16,10,
+0x00,
+#endif
+"res",OPC_res,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,292},
+
+
+/* 0010 0010 ddN0 imm4 *** resb @rd,imm4 */
+{
+#ifdef NICENAMES
+"resb @rd,imm4",8,11,
+0x00,
+#endif
+"resb",OPC_resb,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+2,CLASS_BIT+2,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,293},
+
+
+/* 0110 0010 ddN0 imm4 address_dst *** resb address_dst(rd),imm4 */
+{
+#ifdef NICENAMES
+"resb address_dst(rd),imm4",8,14,
+0x00,
+#endif
+"resb",OPC_resb,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+2,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,294},
+
+
+/* 0110 0010 0000 imm4 address_dst *** resb address_dst,imm4 */
+{
+#ifdef NICENAMES
+"resb address_dst,imm4",8,13,
+0x00,
+#endif
+"resb",OPC_resb,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+2,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,295},
+
+
+/* 1010 0010 dddd imm4 *** resb rbd,imm4 */
+{
+#ifdef NICENAMES
+"resb rbd,imm4",8,4,
+0x00,
+#endif
+"resb",OPC_resb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xa,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,296},
+
+
+/* 0010 0010 0000 ssss 0000 dddd 0000 0000 *** resb rbd,rs */
+{
+#ifdef NICENAMES
+"resb rbd,rs",8,10,
+0x00,
+#endif
+"resb",OPC_resb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,297},
+
+
+/* 1000 1101 flags 0011 *** resflg flags */
+{
+#ifdef NICENAMES
+"resflg flags",16,7,
+0x3c,
+#endif
+"resflg",OPC_resflg,0,{CLASS_FLAGS,},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_FLAGS,CLASS_BIT+3,0,0,0,0,0,},1,2,298},
+
+
+/* 1001 1110 0000 cccc *** ret cc */
+{
+#ifdef NICENAMES
+"ret cc",16,10,
+0x00,
+#endif
+"ret",OPC_ret,0,{CLASS_CC,},
+ {CLASS_BIT+9,CLASS_BIT+0xe,CLASS_BIT+0,CLASS_CC,0,0,0,0,0,},1,2,299},
+
+
+/* 1011 0011 dddd 00I0 *** rl rd,imm1or2 */
+{
+#ifdef NICENAMES
+"rl rd,imm1or2",16,6,
+0x3c,
+#endif
+"rl",OPC_rl,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+0,0,0,0,0,0,},2,2,300},
+
+
+/* 1011 0010 dddd 00I0 *** rlb rbd,imm1or2 */
+{
+#ifdef NICENAMES
+"rlb rbd,imm1or2",8,6,
+0x3c,
+#endif
+"rlb",OPC_rlb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+0,0,0,0,0,0,},2,2,301},
+
+
+/* 1011 0011 dddd 10I0 *** rlc rd,imm1or2 */
+{
+#ifdef NICENAMES
+"rlc rd,imm1or2",16,6,
+0x3c,
+#endif
+"rlc",OPC_rlc,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+8,0,0,0,0,0,},2,2,302},
+
+
+/* 1011 0010 dddd 10I0 *** rlcb rbd,imm1or2 */
+{
+#ifdef NICENAMES
+"rlcb rbd,imm1or2",8,9,
+0x10,
+#endif
+"rlcb",OPC_rlcb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+8,0,0,0,0,0,},2,2,303},
+
+
+/* 1011 1110 aaaa bbbb *** rldb rbb,rba */
+{
+#ifdef NICENAMES
+"rldb rbb,rba",8,9,
+0x10,
+#endif
+"rldb",OPC_rldb,0,{CLASS_REG_BYTE+(ARG_RB),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xe,CLASS_REG+(ARG_RA),CLASS_REG+(ARG_RB),0,0,0,0,0,},2,2,304},
+
+
+/* 1011 0011 dddd 01I0 *** rr rd,imm1or2 */
+{
+#ifdef NICENAMES
+"rr rd,imm1or2",16,6,
+0x3c,
+#endif
+"rr",OPC_rr,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+4,0,0,0,0,0,},2,2,305},
+
+
+/* 1011 0010 dddd 01I0 *** rrb rbd,imm1or2 */
+{
+#ifdef NICENAMES
+"rrb rbd,imm1or2",8,6,
+0x3c,
+#endif
+"rrb",OPC_rrb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+4,0,0,0,0,0,},2,2,306},
+
+
+/* 1011 0011 dddd 11I0 *** rrc rd,imm1or2 */
+{
+#ifdef NICENAMES
+"rrc rd,imm1or2",16,6,
+0x3c,
+#endif
+"rrc",OPC_rrc,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+0xc,0,0,0,0,0,},2,2,307},
+
+
+/* 1011 0010 dddd 11I0 *** rrcb rbd,imm1or2 */
+{
+#ifdef NICENAMES
+"rrcb rbd,imm1or2",8,9,
+0x10,
+#endif
+"rrcb",OPC_rrcb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM1OR2),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT_1OR2+0xc,0,0,0,0,0,},2,2,308},
+
+
+/* 1011 1100 aaaa bbbb *** rrdb rbb,rba */
+{
+#ifdef NICENAMES
+"rrdb rbb,rba",8,9,
+0x10,
+#endif
+"rrdb",OPC_rrdb,0,{CLASS_REG_BYTE+(ARG_RB),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+0xb,CLASS_BIT+0xc,CLASS_REG+(ARG_RA),CLASS_REG+(ARG_RB),0,0,0,0,0,},2,2,309},
+
+
+/* 0011 0110 imm8 *** rsvd36 */
+{
+#ifdef NICENAMES
+"rsvd36",8,10,
+0x00,
+#endif
+"rsvd36",OPC_rsvd36,0,{0},
+ {CLASS_BIT+3,CLASS_BIT+6,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,310},
+
+
+/* 0011 1000 imm8 *** rsvd38 */
+{
+#ifdef NICENAMES
+"rsvd38",8,10,
+0x00,
+#endif
+"rsvd38",OPC_rsvd38,0,{0},
+ {CLASS_BIT+3,CLASS_BIT+8,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,311},
+
+
+/* 0111 1000 imm8 *** rsvd78 */
+{
+#ifdef NICENAMES
+"rsvd78",8,10,
+0x00,
+#endif
+"rsvd78",OPC_rsvd78,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+8,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,312},
+
+
+/* 0111 1110 imm8 *** rsvd7e */
+{
+#ifdef NICENAMES
+"rsvd7e",8,10,
+0x00,
+#endif
+"rsvd7e",OPC_rsvd7e,0,{0},
+ {CLASS_BIT+7,CLASS_BIT+0xe,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,313},
+
+
+/* 1001 1101 imm8 *** rsvd9d */
+{
+#ifdef NICENAMES
+"rsvd9d",8,10,
+0x00,
+#endif
+"rsvd9d",OPC_rsvd9d,0,{0},
+ {CLASS_BIT+9,CLASS_BIT+0xd,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,314},
+
+
+/* 1001 1111 imm8 *** rsvd9f */
+{
+#ifdef NICENAMES
+"rsvd9f",8,10,
+0x00,
+#endif
+"rsvd9f",OPC_rsvd9f,0,{0},
+ {CLASS_BIT+9,CLASS_BIT+0xf,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,315},
+
+
+/* 1011 1001 imm8 *** rsvdb9 */
+{
+#ifdef NICENAMES
+"rsvdb9",8,10,
+0x00,
+#endif
+"rsvdb9",OPC_rsvdb9,0,{0},
+ {CLASS_BIT+0xb,CLASS_BIT+9,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,316},
+
+
+/* 1011 1111 imm8 *** rsvdbf */
+{
+#ifdef NICENAMES
+"rsvdbf",8,10,
+0x00,
+#endif
+"rsvdbf",OPC_rsvdbf,0,{0},
+ {CLASS_BIT+0xb,CLASS_BIT+0xf,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},0,2,317},
+
+
+/* 1011 0111 ssss dddd *** sbc rd,rs */
+{
+#ifdef NICENAMES
+"sbc rd,rs",16,5,
+0x3c,
+#endif
+"sbc",OPC_sbc,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+7,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,318},
+
+
+/* 1011 0110 ssss dddd *** sbcb rbd,rbs */
+{
+#ifdef NICENAMES
+"sbcb rbd,rbs",8,5,
+0x3f,
+#endif
+"sbcb",OPC_sbcb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+6,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,319},
+
+
+/* 0111 1111 imm8 *** sc imm8 */
+{
+#ifdef NICENAMES
+"sc imm8",8,33,
+0x3f,
+#endif
+"sc",OPC_sc,0,{CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+7,CLASS_BIT+0xf,CLASS_IMM+(ARG_IMM8),0,0,0,0,0,0,},1,2,320},
+
+
+/* 1011 0011 dddd 1011 0000 ssss 0000 0000 *** sda rd,rs */
+{
+#ifdef NICENAMES
+"sda rd,rs",16,15,
+0x3c,
+#endif
+"sda",OPC_sda,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,321},
+
+
+/* 1011 0010 dddd 1011 0000 ssss 0000 0000 *** sdab rbd,rs */
+{
+#ifdef NICENAMES
+"sdab rbd,rs",8,15,
+0x3c,
+#endif
+"sdab",OPC_sdab,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,322},
+
+
+/* 1011 0011 dddd 1111 0000 ssss 0000 0000 *** sdal rrd,rs */
+{
+#ifdef NICENAMES
+"sdal rrd,rs",32,15,
+0x3c,
+#endif
+"sdal",OPC_sdal,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+0xf,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,323},
+
+
+/* 1011 0011 dddd 0011 0000 ssss 0000 0000 *** sdl rd,rs */
+{
+#ifdef NICENAMES
+"sdl rd,rs",16,15,
+0x38,
+#endif
+"sdl",OPC_sdl,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,324},
+
+
+/* 1011 0010 dddd 0011 0000 ssss 0000 0000 *** sdlb rbd,rs */
+{
+#ifdef NICENAMES
+"sdlb rbd,rs",8,15,
+0x38,
+#endif
+"sdlb",OPC_sdlb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,325},
+
+
+/* 1011 0011 dddd 0111 0000 ssss 0000 0000 *** sdll rrd,rs */
+{
+#ifdef NICENAMES
+"sdll rrd,rs",32,15,
+0x38,
+#endif
+"sdll",OPC_sdll,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+7,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,326},
+
+
+/* 0010 0101 ddN0 imm4 *** set @rd,imm4 */
+{
+#ifdef NICENAMES
+"set @rd,imm4",16,11,
+0x00,
+#endif
+"set",OPC_set,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+2,CLASS_BIT+5,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,327},
+
+
+/* 0110 0101 ddN0 imm4 address_dst *** set address_dst(rd),imm4 */
+{
+#ifdef NICENAMES
+"set address_dst(rd),imm4",16,14,
+0x00,
+#endif
+"set",OPC_set,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+5,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,328},
+
+
+/* 0110 0101 0000 imm4 address_dst *** set address_dst,imm4 */
+{
+#ifdef NICENAMES
+"set address_dst,imm4",16,13,
+0x00,
+#endif
+"set",OPC_set,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+5,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,329},
+
+
+/* 1010 0101 dddd imm4 *** set rd,imm4 */
+{
+#ifdef NICENAMES
+"set rd,imm4",16,4,
+0x00,
+#endif
+"set",OPC_set,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xa,CLASS_BIT+5,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,330},
+
+
+/* 0010 0101 0000 ssss 0000 dddd 0000 0000 *** set rd,rs */
+{
+#ifdef NICENAMES
+"set rd,rs",16,10,
+0x00,
+#endif
+"set",OPC_set,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+5,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,331},
+
+
+/* 0010 0100 ddN0 imm4 *** setb @rd,imm4 */
+{
+#ifdef NICENAMES
+"setb @rd,imm4",8,11,
+0x00,
+#endif
+"setb",OPC_setb,0,{CLASS_IR+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+2,CLASS_BIT+4,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,332},
+
+
+/* 0110 0100 ddN0 imm4 address_dst *** setb address_dst(rd),imm4 */
+{
+#ifdef NICENAMES
+"setb address_dst(rd),imm4",8,14,
+0x00,
+#endif
+"setb",OPC_setb,0,{CLASS_X+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+4,CLASS_REGN0+(ARG_RD),CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,333},
+
+
+/* 0110 0100 0000 imm4 address_dst *** setb address_dst,imm4 */
+{
+#ifdef NICENAMES
+"setb address_dst,imm4",8,13,
+0x00,
+#endif
+"setb",OPC_setb,0,{CLASS_DA+(ARG_DST),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+6,CLASS_BIT+4,CLASS_BIT+0,CLASS_IMM+(ARG_IMM4),CLASS_ADDRESS+(ARG_DST),0,0,0,0,},2,4,334},
+
+
+/* 1010 0100 dddd imm4 *** setb rbd,imm4 */
+{
+#ifdef NICENAMES
+"setb rbd,imm4",8,4,
+0x00,
+#endif
+"setb",OPC_setb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM +(ARG_IMM4),},
+ {CLASS_BIT+0xa,CLASS_BIT+4,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM4),0,0,0,0,0,},2,2,335},
+
+
+/* 0010 0100 0000 ssss 0000 dddd 0000 0000 *** setb rbd,rs */
+{
+#ifdef NICENAMES
+"setb rbd,rs",8,10,
+0x00,
+#endif
+"setb",OPC_setb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+2,CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RS),CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,0,},2,4,336},
+
+
+/* 1000 1101 flags 0001 *** setflg flags */
+{
+#ifdef NICENAMES
+"setflg flags",16,7,
+0x3c,
+#endif
+"setflg",OPC_setflg,0,{CLASS_FLAGS,},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_FLAGS,CLASS_BIT+1,0,0,0,0,0,},1,2,337},
+
+
+/* 0011 1010 dddd 0101 imm16 *** sinb rbd,imm16 */
+{
+#ifdef NICENAMES
+"sinb rbd,imm16",8,0,
+0x00,
+#endif
+"sinb",OPC_sinb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REG+(ARG_RD),CLASS_BIT+5,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,338},
+
+
+/* 0011 1011 dddd 0101 imm16 *** sinb rd,imm16 */
+{
+#ifdef NICENAMES
+"sinb rd,imm16",8,0,
+0x00,
+#endif
+"sinb",OPC_sinb,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REG+(ARG_RD),CLASS_BIT+5,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,339},
+
+
+/* 0011 1011 ssN0 1000 0001 aaaa ddN0 1000 *** sind @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"sind @rd,@rs,ra",16,0,
+0x00,
+#endif
+"sind",OPC_sind,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+8,CLASS_BIT+1,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,340},
+
+
+/* 0011 1010 ssN0 1000 0001 aaaa ddN0 1000 *** sindb @rd,@rs,rba */
+{
+#ifdef NICENAMES
+"sindb @rd,@rs,rba",8,0,
+0x00,
+#endif
+"sindb",OPC_sindb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+8,CLASS_BIT+1,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,341},
+
+
+/* 0011 1010 ssN0 0001 0000 aaaa ddN0 1000 *** sinib @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"sinib @rd,@rs,ra",8,0,
+0x00,
+#endif
+"sinib",OPC_sinib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,342},
+
+
+/* 0011 1010 ssN0 0001 0000 aaaa ddN0 0000 *** sinibr @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"sinibr @rd,@rs,ra",16,0,
+0x00,
+#endif
+"sinibr",OPC_sinibr,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+1,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,343},
+
+
+/* 1011 0011 dddd 1001 0000 0000 imm8 *** sla rd,imm8 */
+{
+#ifdef NICENAMES
+"sla rd,imm8",16,13,
+0x3c,
+#endif
+"sla",OPC_sla,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+9,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_IMM8),0,0,},2,4,344},
+
+
+/* 1011 0010 dddd 1001 0000 0000 imm8 *** slab rbd,imm8 */
+{
+#ifdef NICENAMES
+"slab rbd,imm8",8,13,
+0x3c,
+#endif
+"slab",OPC_slab,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT+9,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_IMM8),0,0,},2,4,345},
+
+
+/* 1011 0011 dddd 1101 0000 0000 imm8 *** slal rrd,imm8 */
+{
+#ifdef NICENAMES
+"slal rrd,imm8",32,13,
+0x3c,
+#endif
+"slal",OPC_slal,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_IMM8),0,0,},2,4,346},
+
+
+/* 1011 0011 dddd 0001 0000 0000 imm8 *** sll rd,imm8 */
+{
+#ifdef NICENAMES
+"sll rd,imm8",16,13,
+0x38,
+#endif
+"sll",OPC_sll,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+1,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_IMM8),0,0,},2,4,347},
+
+
+/* 1011 0010 dddd 0001 0000 0000 imm8 *** sllb rbd,imm8 */
+{
+#ifdef NICENAMES
+"sllb rbd,imm8",8,13,
+0x38,
+#endif
+"sllb",OPC_sllb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT+1,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_IMM8),0,0,},2,4,348},
+
+
+/* 1011 0011 dddd 0101 0000 0000 imm8 *** slll rrd,imm8 */
+{
+#ifdef NICENAMES
+"slll rrd,imm8",32,13,
+0x38,
+#endif
+"slll",OPC_slll,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+5,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_IMM8),0,0,},2,4,349},
+
+
+/* 0011 1011 ssss 0111 imm16 *** sout imm16,rs */
+{
+#ifdef NICENAMES
+"sout imm16,rs",16,0,
+0x00,
+#endif
+"sout",OPC_sout,0,{CLASS_IMM+(ARG_IMM16),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REG+(ARG_RS),CLASS_BIT+7,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,350},
+
+
+/* 0011 1010 ssss 0111 imm16 *** soutb imm16,rbs */
+{
+#ifdef NICENAMES
+"soutb imm16,rbs",8,0,
+0x00,
+#endif
+"soutb",OPC_soutb,0,{CLASS_IMM+(ARG_IMM16),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REG+(ARG_RS),CLASS_BIT+7,CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,351},
+
+
+/* 0011 1011 ssN0 1011 0000 aaaa ddN0 1000 *** soutd @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"soutd @rd,@rs,ra",16,0,
+0x00,
+#endif
+"soutd",OPC_soutd,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xb,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,352},
+
+
+/* 0011 1010 ssN0 1011 0000 aaaa ddN0 1000 *** soutdb @rd,@rs,rba */
+{
+#ifdef NICENAMES
+"soutdb @rd,@rs,rba",8,0,
+0x00,
+#endif
+"soutdb",OPC_soutdb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+0xb,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,353},
+
+
+/* 0011 1010 ssN0 0011 0000 aaaa ddN0 1000 *** soutib @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"soutib @rd,@rs,ra",8,0,
+0x00,
+#endif
+"soutib",OPC_soutib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,},3,4,354},
+
+
+/* 0011 1010 ssN0 0011 0000 aaaa ddN0 0000 *** soutibr @rd,@rs,ra */
+{
+#ifdef NICENAMES
+"soutibr @rd,@rs,ra",16,0,
+0x00,
+#endif
+"soutibr",OPC_soutibr,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_WORD+(ARG_RA),},
+ {CLASS_BIT+3,CLASS_BIT+0xa,CLASS_REGN0+(ARG_RS),CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RD),CLASS_BIT+0,0,},3,4,355},
+
+
+/* 1011 0011 dddd 1001 1111 1111 nim8 *** sra rd,imm8 */
+{
+#ifdef NICENAMES
+"sra rd,imm8",16,13,
+0x3c,
+#endif
+"sra",OPC_sra,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+9,CLASS_BIT+0xf,CLASS_BIT+0xf,CLASS_IMM+(ARG_NIM8),0,0,},2,4,356},
+
+
+/* 1011 0010 dddd 1001 0000 0000 nim8 *** srab rbd,imm8 */
+{
+#ifdef NICENAMES
+"srab rbd,imm8",8,13,
+0x3c,
+#endif
+"srab",OPC_srab,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT+9,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_NIM8),0,0,},2,4,357},
+
+
+/* 1011 0011 dddd 1101 1111 1111 nim8 *** sral rrd,imm8 */
+{
+#ifdef NICENAMES
+"sral rrd,imm8",32,13,
+0x3c,
+#endif
+"sral",OPC_sral,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+0xd,CLASS_BIT+0xf,CLASS_BIT+0xf,CLASS_IMM+(ARG_NIM8),0,0,},2,4,358},
+
+
+/* 1011 0011 dddd 0001 1111 1111 nim8 *** srl rd,imm8 */
+{
+#ifdef NICENAMES
+"srl rd,imm8",16,13,
+0x3c,
+#endif
+"srl",OPC_srl,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+1,CLASS_BIT+0xf,CLASS_BIT+0xf,CLASS_IMM+(ARG_NIM8),0,0,},2,4,359},
+
+
+/* 1011 0010 dddd 0001 0000 0000 nim8 *** srlb rbd,imm8 */
+{
+#ifdef NICENAMES
+"srlb rbd,imm8",8,13,
+0x3c,
+#endif
+"srlb",OPC_srlb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+2,CLASS_REG+(ARG_RD),CLASS_BIT+1,CLASS_BIT+0,CLASS_BIT+0,CLASS_IMM+(ARG_NIM8),0,0,},2,4,360},
+
+
+/* 1011 0011 dddd 0101 1111 1111 nim8 *** srll rrd,imm8 */
+{
+#ifdef NICENAMES
+"srll rrd,imm8",32,13,
+0x3c,
+#endif
+"srll",OPC_srll,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0xb,CLASS_BIT+3,CLASS_REG+(ARG_RD),CLASS_BIT+5,CLASS_BIT+0xf,CLASS_BIT+0xf,CLASS_IMM+(ARG_NIM8),0,0,},2,4,361},
+
+
+/* 0000 0011 ssN0 dddd *** sub rd,@rs */
+{
+#ifdef NICENAMES
+"sub rd,@rs",16,7,
+0x3c,
+#endif
+"sub",OPC_sub,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+3,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,362},
+
+
+/* 0100 0011 0000 dddd address_src *** sub rd,address_src */
+{
+#ifdef NICENAMES
+"sub rd,address_src",16,9,
+0x3c,
+#endif
+"sub",OPC_sub,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,363},
+
+
+/* 0100 0011 ssN0 dddd address_src *** sub rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"sub rd,address_src(rs)",16,10,
+0x3c,
+#endif
+"sub",OPC_sub,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+3,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,364},
+
+
+/* 0000 0011 0000 dddd imm16 *** sub rd,imm16 */
+{
+#ifdef NICENAMES
+"sub rd,imm16",16,7,
+0x3c,
+#endif
+"sub",OPC_sub,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+3,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,365},
+
+
+/* 1000 0011 ssss dddd *** sub rd,rs */
+{
+#ifdef NICENAMES
+"sub rd,rs",16,4,
+0x3c,
+#endif
+"sub",OPC_sub,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+3,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,366},
+
+
+/* 0000 0010 ssN0 dddd *** subb rbd,@rs */
+{
+#ifdef NICENAMES
+"subb rbd,@rs",8,7,
+0x3f,
+#endif
+"subb",OPC_subb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+2,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,367},
+
+
+/* 0100 0010 0000 dddd address_src *** subb rbd,address_src */
+{
+#ifdef NICENAMES
+"subb rbd,address_src",8,9,
+0x3f,
+#endif
+"subb",OPC_subb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,368},
+
+
+/* 0100 0010 ssN0 dddd address_src *** subb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"subb rbd,address_src(rs)",8,10,
+0x3f,
+#endif
+"subb",OPC_subb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+2,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,369},
+
+
+/* 0000 0010 0000 dddd imm8 imm8 *** subb rbd,imm8 */
+{
+#ifdef NICENAMES
+"subb rbd,imm8",8,7,
+0x3f,
+#endif
+"subb",OPC_subb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,370},
+
+
+/* 1000 0010 ssss dddd *** subb rbd,rbs */
+{
+#ifdef NICENAMES
+"subb rbd,rbs",8,4,
+0x3f,
+#endif
+"subb",OPC_subb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+2,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,371},
+
+
+/* 0001 0010 ssN0 dddd *** subl rrd,@rs */
+{
+#ifdef NICENAMES
+"subl rrd,@rs",32,14,
+0x3c,
+#endif
+"subl",OPC_subl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+1,CLASS_BIT+2,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,372},
+
+
+/* 0101 0010 0000 dddd address_src *** subl rrd,address_src */
+{
+#ifdef NICENAMES
+"subl rrd,address_src",32,15,
+0x3c,
+#endif
+"subl",OPC_subl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+5,CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,373},
+
+
+/* 0101 0010 ssN0 dddd address_src *** subl rrd,address_src(rs) */
+{
+#ifdef NICENAMES
+"subl rrd,address_src(rs)",32,16,
+0x3c,
+#endif
+"subl",OPC_subl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+5,CLASS_BIT+2,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,374},
+
+
+/* 0001 0010 0000 dddd imm32 *** subl rrd,imm32 */
+{
+#ifdef NICENAMES
+"subl rrd,imm32",32,14,
+0x3c,
+#endif
+"subl",OPC_subl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_IMM+(ARG_IMM32),},
+ {CLASS_BIT+1,CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM32),0,0,0,0,},2,6,375},
+
+
+/* 1001 0010 ssss dddd *** subl rrd,rrs */
+{
+#ifdef NICENAMES
+"subl rrd,rrs",32,8,
+0x3c,
+#endif
+"subl",OPC_subl,0,{CLASS_REG_LONG+(ARG_RD),CLASS_REG_LONG+(ARG_RS),},
+ {CLASS_BIT+9,CLASS_BIT+2,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,376},
+
+
+/* 1010 1111 dddd cccc *** tcc cc,rd */
+{
+#ifdef NICENAMES
+"tcc cc,rd",16,5,
+0x00,
+#endif
+"tcc",OPC_tcc,0,{CLASS_CC,CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+0xa,CLASS_BIT+0xf,CLASS_REG+(ARG_RD),CLASS_CC,0,0,0,0,0,},2,2,377},
+
+
+/* 1010 1110 dddd cccc *** tccb cc,rbd */
+{
+#ifdef NICENAMES
+"tccb cc,rbd",8,5,
+0x00,
+#endif
+"tccb",OPC_tccb,0,{CLASS_CC,CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+0xa,CLASS_BIT+0xe,CLASS_REG+(ARG_RD),CLASS_CC,0,0,0,0,0,},2,2,378},
+
+
+/* 0000 1101 ddN0 0100 *** test @rd */
+{
+#ifdef NICENAMES
+"test @rd",16,8,
+0x18,
+#endif
+"test",OPC_test,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+4,0,0,0,0,0,},1,2,379},
+
+
+/* 0100 1101 0000 0100 address_dst *** test address_dst */
+{
+#ifdef NICENAMES
+"test address_dst",16,11,
+0x00,
+#endif
+"test",OPC_test,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+4,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,380},
+
+
+/* 0100 1101 ddN0 0100 address_dst *** test address_dst(rd) */
+{
+#ifdef NICENAMES
+"test address_dst(rd)",16,12,
+0x00,
+#endif
+"test",OPC_test,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+4,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,381},
+
+
+/* 1000 1101 dddd 0100 *** test rd */
+{
+#ifdef NICENAMES
+"test rd",16,7,
+0x00,
+#endif
+"test",OPC_test,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_BIT+4,0,0,0,0,0,},1,2,382},
+
+
+/* 0000 1100 ddN0 0100 *** testb @rd */
+{
+#ifdef NICENAMES
+"testb @rd",8,8,
+0x1c,
+#endif
+"testb",OPC_testb,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+4,0,0,0,0,0,},1,2,383},
+
+
+/* 0100 1100 0000 0100 address_dst *** testb address_dst */
+{
+#ifdef NICENAMES
+"testb address_dst",8,11,
+0x1c,
+#endif
+"testb",OPC_testb,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+4,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,384},
+
+
+/* 0100 1100 ddN0 0100 address_dst *** testb address_dst(rd) */
+{
+#ifdef NICENAMES
+"testb address_dst(rd)",8,12,
+0x1c,
+#endif
+"testb",OPC_testb,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+4,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,385},
+
+
+/* 1000 1100 dddd 0100 *** testb rbd */
+{
+#ifdef NICENAMES
+"testb rbd",8,7,
+0x1c,
+#endif
+"testb",OPC_testb,0,{CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_BIT+4,0,0,0,0,0,},1,2,386},
+
+
+/* 0001 1100 ddN0 1000 *** testl @rd */
+{
+#ifdef NICENAMES
+"testl @rd",32,13,
+0x18,
+#endif
+"testl",OPC_testl,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+1,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,0,0,0,0,0,},1,2,387},
+
+
+/* 0101 1100 0000 1000 address_dst *** testl address_dst */
+{
+#ifdef NICENAMES
+"testl address_dst",32,16,
+0x18,
+#endif
+"testl",OPC_testl,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+5,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+8,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,388},
+
+
+/* 0101 1100 ddN0 1000 address_dst *** testl address_dst(rd) */
+{
+#ifdef NICENAMES
+"testl address_dst(rd)",32,17,
+0x18,
+#endif
+"testl",OPC_testl,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+5,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,389},
+
+
+/* 1001 1100 dddd 1000 *** testl rrd */
+{
+#ifdef NICENAMES
+"testl rrd",32,13,
+0x18,
+#endif
+"testl",OPC_testl,0,{CLASS_REG_LONG+(ARG_RD),},
+ {CLASS_BIT+9,CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_BIT+8,0,0,0,0,0,},1,2,390},
+
+
+/* 1011 1000 ddN0 1000 0000 aaaa ssN0 0000 *** trdb @rd,@rs,rba */
+{
+#ifdef NICENAMES
+"trdb @rd,@rs,rba",8,25,
+0x1c,
+#endif
+"trdb",OPC_trdb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RD),CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RS),CLASS_BIT+0,0,},3,4,391},
+
+
+/* 1011 1000 ddN0 1100 0000 aaaa ssN0 0000 *** trdrb @rd,@rs,rba */
+{
+#ifdef NICENAMES
+"trdrb @rd,@rs,rba",8,25,
+0x1c,
+#endif
+"trdrb",OPC_trdrb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RA),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RD),CLASS_BIT+0xc,CLASS_BIT+0,CLASS_REG+(ARG_RA),CLASS_REGN0+(ARG_RS),CLASS_BIT+0,0,},3,4,392},
+
+
+/* 1011 1000 ddN0 0000 0000 rrrr ssN0 0000 *** trib @rd,@rs,rbr */
+{
+#ifdef NICENAMES
+"trib @rd,@rs,rbr",8,25,
+0x1c,
+#endif
+"trib",OPC_trib,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RD),CLASS_BIT+0,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RS),CLASS_BIT+0,0,},3,4,393},
+
+
+/* 1011 1000 ddN0 0100 0000 rrrr ssN0 0000 *** trirb @rd,@rs,rbr */
+{
+#ifdef NICENAMES
+"trirb @rd,@rs,rbr",8,25,
+0x1c,
+#endif
+"trirb",OPC_trirb,0,{CLASS_IR+(ARG_RD),CLASS_IR+(ARG_RS),CLASS_REG_BYTE+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RD),CLASS_BIT+4,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RS),CLASS_BIT+0,0,},3,4,394},
+
+
+/* 1011 1000 aaN0 1010 0000 rrrr bbN0 0000 *** trtdb @ra,@rb,rbr */
+{
+#ifdef NICENAMES
+"trtdb @ra,@rb,rbr",8,25,
+0x1c,
+#endif
+"trtdb",OPC_trtdb,0,{CLASS_IR+(ARG_RA),CLASS_IR+(ARG_RB),CLASS_REG_BYTE+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RA),CLASS_BIT+0xa,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RB),CLASS_BIT+0,0,},3,4,395},
+
+
+/* 1011 1000 aaN0 1110 0000 rrrr bbN0 1110 *** trtdrb @ra,@rb,rbr */
+{
+#ifdef NICENAMES
+"trtdrb @ra,@rb,rbr",8,25,
+0x1c,
+#endif
+"trtdrb",OPC_trtdrb,0,{CLASS_IR+(ARG_RA),CLASS_IR+(ARG_RB),CLASS_REG_BYTE+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RA),CLASS_BIT+0xe,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RB),CLASS_BIT+0xe,0,},3,4,396},
+
+
+/* 1011 1000 aaN0 0010 0000 rrrr bbN0 0000 *** trtib @ra,@rb,rbr */
+{
+#ifdef NICENAMES
+"trtib @ra,@rb,rbr",8,25,
+0x1c,
+#endif
+"trtib",OPC_trtib,0,{CLASS_IR+(ARG_RA),CLASS_IR+(ARG_RB),CLASS_REG_BYTE+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RA),CLASS_BIT+2,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RB),CLASS_BIT+0,0,},3,4,397},
+
+
+/* 1011 1000 aaN0 0110 0000 rrrr bbN0 1110 *** trtirb @ra,@rb,rbr */
+{
+#ifdef NICENAMES
+"trtirb @ra,@rb,rbr",8,25,
+0x1c,
+#endif
+"trtirb",OPC_trtirb,0,{CLASS_IR+(ARG_RA),CLASS_IR+(ARG_RB),CLASS_REG_BYTE+(ARG_RR),},
+ {CLASS_BIT+0xb,CLASS_BIT+8,CLASS_REGN0+(ARG_RA),CLASS_BIT+6,CLASS_BIT+0,CLASS_REG+(ARG_RR),CLASS_REGN0+(ARG_RB),CLASS_BIT+0xe,0,},3,4,398},
+
+
+/* 0000 1101 ddN0 0110 *** tset @rd */
+{
+#ifdef NICENAMES
+"tset @rd",16,11,
+0x08,
+#endif
+"tset",OPC_tset,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+6,0,0,0,0,0,},1,2,399},
+
+
+/* 0100 1101 0000 0110 address_dst *** tset address_dst */
+{
+#ifdef NICENAMES
+"tset address_dst",16,14,
+0x08,
+#endif
+"tset",OPC_tset,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_BIT+0,CLASS_BIT+6,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,400},
+
+
+/* 0100 1101 ddN0 0110 address_dst *** tset address_dst(rd) */
+{
+#ifdef NICENAMES
+"tset address_dst(rd)",16,15,
+0x08,
+#endif
+"tset",OPC_tset,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xd,CLASS_REGN0+(ARG_RD),CLASS_BIT+6,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,401},
+
+
+/* 1000 1101 dddd 0110 *** tset rd */
+{
+#ifdef NICENAMES
+"tset rd",16,7,
+0x08,
+#endif
+"tset",OPC_tset,0,{CLASS_REG_WORD+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xd,CLASS_REG+(ARG_RD),CLASS_BIT+6,0,0,0,0,0,},1,2,402},
+
+
+/* 0000 1100 ddN0 0110 *** tsetb @rd */
+{
+#ifdef NICENAMES
+"tsetb @rd",8,11,
+0x08,
+#endif
+"tsetb",OPC_tsetb,0,{CLASS_IR+(ARG_RD),},
+ {CLASS_BIT+0,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+6,0,0,0,0,0,},1,2,403},
+
+
+/* 0100 1100 0000 0110 address_dst *** tsetb address_dst */
+{
+#ifdef NICENAMES
+"tsetb address_dst",8,14,
+0x08,
+#endif
+"tsetb",OPC_tsetb,0,{CLASS_DA+(ARG_DST),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_BIT+0,CLASS_BIT+6,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,404},
+
+
+/* 0100 1100 ddN0 0110 address_dst *** tsetb address_dst(rd) */
+{
+#ifdef NICENAMES
+"tsetb address_dst(rd)",8,15,
+0x08,
+#endif
+"tsetb",OPC_tsetb,0,{CLASS_X+(ARG_RD),},
+ {CLASS_BIT+4,CLASS_BIT+0xc,CLASS_REGN0+(ARG_RD),CLASS_BIT+6,CLASS_ADDRESS+(ARG_DST),0,0,0,0,},1,4,405},
+
+
+/* 1000 1100 dddd 0110 *** tsetb rbd */
+{
+#ifdef NICENAMES
+"tsetb rbd",8,7,
+0x08,
+#endif
+"tsetb",OPC_tsetb,0,{CLASS_REG_BYTE+(ARG_RD),},
+ {CLASS_BIT+8,CLASS_BIT+0xc,CLASS_REG+(ARG_RD),CLASS_BIT+6,0,0,0,0,0,},1,2,406},
+
+
+/* 0000 1001 ssN0 dddd *** xor rd,@rs */
+{
+#ifdef NICENAMES
+"xor rd,@rs",16,7,
+0x18,
+#endif
+"xor",OPC_xor,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+9,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,407},
+
+
+/* 0100 1001 0000 dddd address_src *** xor rd,address_src */
+{
+#ifdef NICENAMES
+"xor rd,address_src",16,9,
+0x18,
+#endif
+"xor",OPC_xor,0,{CLASS_REG_WORD+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,408},
+
+
+/* 0100 1001 ssN0 dddd address_src *** xor rd,address_src(rs) */
+{
+#ifdef NICENAMES
+"xor rd,address_src(rs)",16,10,
+0x18,
+#endif
+"xor",OPC_xor,0,{CLASS_REG_WORD+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+9,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,409},
+
+
+/* 0000 1001 0000 dddd imm16 *** xor rd,imm16 */
+{
+#ifdef NICENAMES
+"xor rd,imm16",16,7,
+0x18,
+#endif
+"xor",OPC_xor,0,{CLASS_REG_WORD+(ARG_RD),CLASS_IMM+(ARG_IMM16),},
+ {CLASS_BIT+0,CLASS_BIT+9,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM16),0,0,0,0,},2,4,410},
+
+
+/* 1000 1001 ssss dddd *** xor rd,rs */
+{
+#ifdef NICENAMES
+"xor rd,rs",16,4,
+0x18,
+#endif
+"xor",OPC_xor,0,{CLASS_REG_WORD+(ARG_RD),CLASS_REG_WORD+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+9,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,411},
+
+
+/* 0000 1000 ssN0 dddd *** xorb rbd,@rs */
+{
+#ifdef NICENAMES
+"xorb rbd,@rs",8,7,
+0x1c,
+#endif
+"xorb",OPC_xorb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IR+(ARG_RS),},
+ {CLASS_BIT+0,CLASS_BIT+8,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,412},
+
+
+/* 0100 1000 0000 dddd address_src *** xorb rbd,address_src */
+{
+#ifdef NICENAMES
+"xorb rbd,address_src",8,9,
+0x1c,
+#endif
+"xorb",OPC_xorb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_DA+(ARG_SRC),},
+ {CLASS_BIT+4,CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,413},
+
+
+/* 0100 1000 ssN0 dddd address_src *** xorb rbd,address_src(rs) */
+{
+#ifdef NICENAMES
+"xorb rbd,address_src(rs)",8,10,
+0x1c,
+#endif
+"xorb",OPC_xorb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_X+(ARG_RS),},
+ {CLASS_BIT+4,CLASS_BIT+8,CLASS_REGN0+(ARG_RS),CLASS_REG+(ARG_RD),CLASS_ADDRESS+(ARG_SRC),0,0,0,0,},2,4,414},
+
+
+/* 0000 1000 0000 dddd imm8 imm8 *** xorb rbd,imm8 */
+{
+#ifdef NICENAMES
+"xorb rbd,imm8",8,7,
+0x1c,
+#endif
+"xorb",OPC_xorb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_IMM+(ARG_IMM8),},
+ {CLASS_BIT+0,CLASS_BIT+8,CLASS_BIT+0,CLASS_REG+(ARG_RD),CLASS_IMM+(ARG_IMM8),CLASS_IMM+(ARG_IMM8),0,0,0,},2,4,415},
+
+
+/* 1000 1000 ssss dddd *** xorb rbd,rbs */
+{
+#ifdef NICENAMES
+"xorb rbd,rbs",8,4,
+0x1c,
+#endif
+"xorb",OPC_xorb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+8,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,416},
+
+
+/* 1000 1000 ssss dddd *** xorb rbd,rbs */
+{
+#ifdef NICENAMES
+"xorb rbd,rbs",8,4,
+0x01,
+#endif
+"xorb",OPC_xorb,0,{CLASS_REG_BYTE+(ARG_RD),CLASS_REG_BYTE+(ARG_RS),},
+ {CLASS_BIT+8,CLASS_BIT+8,CLASS_REG+(ARG_RS),CLASS_REG+(ARG_RD),0,0,0,0,0,},2,2,417},
+0,0};
+#endif
diff --git a/opcodes/z8kgen.c b/opcodes/z8kgen.c
new file mode 100644
index 00000000000..e786bbb4c3d
--- /dev/null
+++ b/opcodes/z8kgen.c
@@ -0,0 +1,1313 @@
+/*
+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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* This program generates z8k-opc.h */
+
+#include <ansidecl.h>
+#include "sysdep.h"
+
+#define BYTE_INFO_LEN 10
+
+struct op
+{
+ char *flags;
+ int cycles;
+ char type;
+ char *bits;
+ char *name;
+ char *flavor;
+};
+
+#define iswhite(x) ((x) == ' ' || (x) == '\t')
+struct op opt[] =
+{
+ "------", 10, 8, "0000 1110 imm8", "ext0e imm8", 0,
+ "------", 10, 8, "0000 1111 imm8", "ext0f imm8", 0,
+ "------", 10, 8, "1000 1110 imm8", "ext8e imm8", 0,
+ "------", 10, 8, "1000 1111 imm8", "ext8f imm8", 0,
+
+ "------", 10, 8, "0011 0110 imm8", "rsvd36", 0,
+ "------", 10, 8, "0011 1000 imm8", "rsvd38", 0,
+ "------", 10, 8, "0111 1000 imm8", "rsvd78", 0,
+ "------", 10, 8, "0111 1110 imm8", "rsvd7e", 0,
+
+ "------", 10, 8, "1001 1101 imm8", "rsvd9d", 0,
+ "------", 10, 8, "1001 1111 imm8", "rsvd9f", 0,
+
+ "------", 10, 8, "1011 1001 imm8", "rsvdb9", 0,
+ "------", 10, 8, "1011 1111 imm8", "rsvdbf", 0,
+
+ "---V--", 11, 16, "1011 1011 ssN0 1001 0000 rrrr ddN0 1000", "ldd @rs,@rd,rr", 0,
+ "---V--", 11, 16, "1011 1011 ssN0 1001 0000 rrrr ddN0 0000", "lddr @rs,@rd,rr", 0,
+ "---V--", 11, 8, "1011 1011 ssN0 1001 0000 rrrr ddN0 0000", "lddrb @rs,@rd,rr", 0,
+ "---V--", 11, 16, "1011 1011 ssN0 0001 0000 rrrr ddN0 0000", "ldir @rd,@rs,rr", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 0000 0000 rrrr dddd cccc", "cpi rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 0100 0000 rrrr dddd cccc", "cpir rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 1100 0000 rrrr dddd cccc", "cpdr rd,@rs,rr,cc", 0,
+ "---V--", 11, 16, "1011 1011 ssN0 0001 0000 rrrr ddN0 1000", "ldi @rd,@rs,rr", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 1000 0000 rrrr dddd cccc", "cpd rd,@rs,rr,cc", 0,
+ "---V--", 11, 8, "1011 1010 ssN0 0001 0000 rrrr ddN0 0000", "ldirb @rd,@rs,rr", 0,
+ "---V--", 11, 8, "1011 1010 ssN0 1001 0000 rrrr ddN0 1000", "lddb @rs,@rd,rr", 0,
+ "---V--", 11, 8, "1011 1010 ssN0 0001 0000 rrrr ddN0 1000", "ldib @rd,@rs,rr", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 1000 0000 rrrr dddd cccc", "cpdb rbd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 1100 0000 rrrr dddd cccc", "cpdrb rbd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 0000 0000 rrrr dddd cccc", "cpib rbd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 0100 0000 rrrr dddd cccc", "cpirb rbd,@rs,rr,cc", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 1010 0000 rrrr ddN0 cccc", "cpsd @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 1010 0000 rrrr ddN0 cccc", "cpsdb @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 1110 0000 rrrr ddN0 cccc", "cpsdr @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 1110 0000 rrrr ddN0 cccc", "cpsdrb @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 0010 0000 rrrr ddN0 cccc", "cpsi @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 0010 0000 rrrr ddN0 cccc", "cpsib @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 16, "1011 1011 ssN0 0110 0000 rrrr ddN0 cccc", "cpsir @rd,@rs,rr,cc", 0,
+ "CZSV--", 11, 8, "1011 1010 ssN0 0110 0000 rrrr ddN0 cccc", "cpsirb @rd,@rs,rr,cc", 0,
+
+ "------", 2, 8, "0011 0110 0000 0000", "bpt", 0,
+ "CZSV--", 5, 16, "1011 0101 ssss dddd", "adc rd,rs", 0,
+ "CZSVDH", 5, 8, "1011 0100 ssss dddd", "adcb rbd,rbs", 0,
+ "CZSV--", 7, 16, "0000 0001 ssN0 dddd", "add rd,@rs", 0,
+"CZSV--", 9, 16, "0100 0001 0000 dddd address_src", "add rd,address_src", 0,
+ "CZSV--", 10, 16, "0100 0001 ssN0 dddd address_src", "add rd,address_src(rs)", 0,
+ "CZSV--", 7, 16, "0000 0001 0000 dddd imm16", "add rd,imm16", 0,
+ "CZSV--", 4, 16, "1000 0001 ssss dddd", "add rd,rs", 0,
+ "CZSVDH", 7, 8, "0000 0000 ssN0 dddd", "addb rbd,@rs", 0,
+"CZSVDH", 9, 8, "0100 0000 0000 dddd address_src", "addb rbd,address_src", 0,
+ "CZSVDH", 10, 8, "0100 0000 ssN0 dddd address_src", "addb rbd,address_src(rs)", 0,
+ "CZSVDH", 7, 8, "0000 0000 0000 dddd imm8 imm8", "addb rbd,imm8", 0,
+ "CZSVDH", 4, 8, "1000 0000 ssss dddd", "addb rbd,rbs", 0,
+ "CZSV--", 14, 32, "0001 0110 ssN0 dddd", "addl rrd,@rs", 0,
+ "CZSV--", 15, 32, "0101 0110 0000 dddd address_src", "addl rrd,address_src", 0,
+ "CZSV--", 16, 32, "0101 0110 ssN0 dddd address_src", "addl rrd,address_src(rs)", 0,
+ "CZSV--", 14, 32, "0001 0110 0000 dddd imm32", "addl rrd,imm32", 0,
+ "CZSV--", 8, 32, "1001 0110 ssss dddd", "addl rrd,rrs", 0,
+
+ "-ZS---", 7, 16, "0000 0111 ssN0 dddd", "and rd,@rs", 0,
+"-ZS---", 9, 16, "0100 0111 0000 dddd address_src", "and rd,address_src", 0,
+ "-ZS---", 10, 16, "0100 0111 ssN0 dddd address_src", "and rd,address_src(rs)", 0,
+ "-ZS---", 7, 16, "0000 0111 0000 dddd imm16", "and rd,imm16", 0,
+ "-ZS---", 4, 16, "1000 0111 ssss dddd", "and rd,rs", 0,
+ "-ZSP--", 7, 8, "0000 0110 ssN0 dddd", "andb rbd,@rs", 0,
+"-ZSP--", 9, 8, "0100 0110 0000 dddd address_src", "andb rbd,address_src", 0,
+ "-ZSP--", 10, 8, "0100 0110 ssN0 dddd address_src", "andb rbd,address_src(rs)", 0,
+ "-ZSP--", 7, 8, "0000 0110 0000 dddd imm8 imm8", "andb rbd,imm8", 0,
+ "-ZSP--", 4, 8, "1000 0110 ssss dddd", "andb rbd,rbs", 0,
+
+ "-Z----", 8, 16, "0010 0111 ddN0 imm4", "bit @rd,imm4", 0,
+ "-Z----", 11, 16, "0110 0111 ddN0 imm4 address_dst", "bit address_dst(rd),imm4", 0,
+ "-Z----", 10, 16, "0110 0111 0000 imm4 address_dst", "bit address_dst,imm4", 0,
+ "-Z----", 4, 16, "1010 0111 dddd imm4", "bit rd,imm4", 0,
+"-Z----", 10, 16, "0010 0111 0000 ssss 0000 dddd 0000 0000", "bit rd,rs", 0,
+
+ "-Z----", 8, 8, "0010 0110 ddN0 imm4", "bitb @rd,imm4", 0,
+ "-Z----", 11, 8, "0110 0110 ddN0 imm4 address_dst", "bitb address_dst(rd),imm4", 0,
+ "-Z----", 10, 8, "0110 0110 0000 imm4 address_dst", "bitb address_dst,imm4", 0,
+ "-Z----", 4, 8, "1010 0110 dddd imm4", "bitb rbd,imm4", 0,
+"-Z----", 10, 8, "0010 0110 0000 ssss 0000 dddd 0000 0000", "bitb rbd,rs", 0,
+
+ "------", 10, 32, "0001 1111 ddN0 0000", "call @rd", 0,
+ "------", 12, 32, "0101 1111 0000 0000 address_dst", "call address_dst", 0,
+ "------", 13, 32, "0101 1111 ddN0 0000 address_dst", "call address_dst(rd)", 0,
+ "------", 10, 16, "1101 disp12", "calr disp12", 0,
+
+ "------", 8, 16, "0000 1101 ddN0 1000", "clr @rd", 0,
+ "------", 11, 16, "0100 1101 0000 1000 address_dst", "clr address_dst", 0,
+ "------", 12, 16, "0100 1101 ddN0 1000 address_dst", "clr address_dst(rd)", 0,
+ "------", 7, 16, "1000 1101 dddd 1000", "clr rd", 0,
+ "------", 8, 8, "0000 1100 ddN0 1000", "clrb @rd", 0,
+ "------", 11, 8, "0100 1100 0000 1000 address_dst", "clrb address_dst", 0,
+ "------", 12, 8, "0100 1100 ddN0 1000 address_dst", "clrb address_dst(rd)", 0,
+ "------", 7, 8, "1000 1100 dddd 1000", "clrb rbd", 0,
+ "-ZS---", 12, 16, "0000 1101 ddN0 0000", "com @rd", 0,
+ "-ZS---", 15, 16, "0100 1101 0000 0000 address_dst", "com address_dst", 0,
+ "-ZS---", 16, 16, "0100 1101 ddN0 0000 address_dst", "com address_dst(rd)", 0,
+ "-ZS---", 7, 16, "1000 1101 dddd 0000", "com rd", 0,
+ "-ZSP--", 12, 8, "0000 1100 ddN0 0000", "comb @rd", 0,
+ "-ZSP--", 15, 8, "0100 1100 0000 0000 address_dst", "comb address_dst", 0,
+ "-ZSP--", 16, 8, "0100 1100 ddN0 0000 address_dst", "comb address_dst(rd)", 0,
+ "-ZSP--", 7, 8, "1000 1100 dddd 0000", "comb rbd", 0,
+ "CZSP--", 7, 16, "1000 1101 imm4 0101", "comflg flags", 0,
+
+ "CZSV--", 11, 16, "0000 1101 ddN0 0001 imm16", "cp @rd,imm16", 0,
+ "CZSV--", 15, 16, "0100 1101 ddN0 0001 address_dst imm16", "cp address_dst(rd),imm16", 0,
+ "CZSV--", 14, 16, "0100 1101 0000 0001 address_dst imm16", "cp address_dst,imm16", 0,
+
+ "CZSV--", 7, 16, "0000 1011 ssN0 dddd", "cp rd,@rs", 0,
+ "CZSV--", 9, 16, "0100 1011 0000 dddd address_src", "cp rd,address_src", 0,
+ "CZSV--", 10, 16, "0100 1011 ssN0 dddd address_src", "cp rd,address_src(rs)", 0,
+ "CZSV--", 7, 16, "0000 1011 0000 dddd imm16", "cp rd,imm16", 0,
+ "CZSV--", 4, 16, "1000 1011 ssss dddd", "cp rd,rs", 0,
+
+ "CZSV--", 11, 8, "0000 1100 ddN0 0001 imm8 imm8", "cpb @rd,imm8", 0,
+ "CZSV--", 15, 8, "0100 1100 ddN0 0001 address_dst imm8 imm8", "cpb address_dst(rd),imm8", 0,
+ "CZSV--", 14, 8, "0100 1100 0000 0001 address_dst imm8 imm8", "cpb address_dst,imm8", 0,
+ "CZSV--", 7, 8, "0000 1010 ssN0 dddd", "cpb rbd,@rs", 0,
+"CZSV--", 9, 8, "0100 1010 0000 dddd address_src", "cpb rbd,address_src", 0,
+ "CZSV--", 10, 8, "0100 1010 ssN0 dddd address_src", "cpb rbd,address_src(rs)", 0,
+ "CZSV--", 7, 8, "0000 1010 0000 dddd imm8 imm8", "cpb rbd,imm8", 0,
+ "CZSV--", 4, 8, "1000 1010 ssss dddd", "cpb rbd,rbs", 0,
+
+ "CZSV--", 14, 32, "0001 0000 ssN0 dddd", "cpl rrd,@rs", 0,
+ "CZSV--", 15, 32, "0101 0000 0000 dddd address_src", "cpl rrd,address_src", 0,
+ "CZSV--", 16, 32, "0101 0000 ssN0 dddd address_src", "cpl rrd,address_src(rs)", 0,
+ "CZSV--", 14, 32, "0001 0000 0000 dddd imm32", "cpl rrd,imm32", 0,
+ "CZSV--", 8, 32, "1001 0000 ssss dddd", "cpl rrd,rrs", 0,
+
+ "CZS---", 5, 8, "1011 0000 dddd 0000", "dab rbd", 0,
+ "------", 11, 16, "1111 dddd 1disp7", "dbjnz rbd,disp7", 0,
+ "-ZSV--", 11, 16, "0010 1011 ddN0 imm4m1", "dec @rd,imm4m1", 0,
+ "-ZSV--", 14, 16, "0110 1011 ddN0 imm4m1 address_dst", "dec address_dst(rd),imm4m1", 0,
+ "-ZSV--", 13, 16, "0110 1011 0000 imm4m1 address_dst", "dec address_dst,imm4m1", 0,
+ "-ZSV--", 4, 16, "1010 1011 dddd imm4m1", "dec rd,imm4m1", 0,
+ "-ZSV--", 11, 8, "0010 1010 ddN0 imm4m1", "decb @rd,imm4m1", 0,
+ "-ZSV--", 14, 8, "0110 1010 ddN0 imm4m1 address_dst", "decb address_dst(rd),imm4m1", 0,
+ "-ZSV--", 13, 8, "0110 1010 0000 imm4m1 address_dst", "decb address_dst,imm4m1", 0,
+ "-ZSV--", 4, 8, "1010 1010 dddd imm4m1", "decb rbd,imm4m1", 0,
+
+ "------", 7, 16, "0111 1100 0000 00ii", "di i2", 0,
+ "CZSV--", 107, 16, "0001 1011 ssN0 dddd", "div rrd,@rs", 0,
+ "CZSV--", 107, 16, "0101 1011 0000 dddd address_src", "div rrd,address_src", 0,
+ "CZSV--", 107, 16, "0101 1011 ssN0 dddd address_src", "div rrd,address_src(rs)", 0,
+ "CZSV--", 107, 16, "0001 1011 0000 dddd imm16", "div rrd,imm16", 0,
+ "CZSV--", 107, 16, "1001 1011 ssss dddd", "div rrd,rs", 0,
+ "CZSV--", 744, 32, "0001 1010 ssN0 dddd", "divl rqd,@rs", 0,
+ "CZSV--", 745, 32, "0101 1010 0000 dddd address_src", "divl rqd,address_src", 0,
+ "CZSV--", 746, 32, "0101 1010 ssN0 dddd address_src", "divl rqd,address_src(rs)", 0,
+ "CZSV--", 744, 32, "0001 1010 0000 dddd imm32", "divl rqd,imm32", 0,
+ "CZSV--", 744, 32, "1001 1010 ssss dddd", "divl rqd,rrs", 0,
+
+ "------", 11, 16, "1111 dddd 0disp7", "djnz rd,disp7", 0,
+ "------", 7, 16, "0111 1100 0000 01ii", "ei i2", 0,
+ "------", 6, 16, "1010 1101 ssss dddd", "ex rd,rs", 0,
+ "------", 12, 16, "0010 1101 ssN0 dddd", "ex rd,@rs", 0,
+"------", 15, 16, "0110 1101 0000 dddd address_src", "ex rd,address_src", 0,
+ "------", 16, 16, "0110 1101 ssN0 dddd address_src", "ex rd,address_src(rs)", 0,
+
+ "------", 12, 8, "0010 1100 ssN0 dddd", "exb rbd,@rs", 0,
+"------", 15, 8, "0110 1100 0000 dddd address_src", "exb rbd,address_src", 0,
+ "------", 16, 8, "0110 1100 ssN0 dddd address_src", "exb rbd,address_src(rs)", 0,
+ "------", 6, 8, "1010 1100 ssss dddd", "exb rbd,rbs", 0,
+
+ "------", 11, 16, "1011 0001 dddd 1010", "exts rrd", 0,
+ "------", 11, 8, "1011 0001 dddd 0000", "extsb rd", 0,
+ "------", 11, 32, "1011 0001 dddd 0111", "extsl rqd", 0,
+
+ "------", 8, 16, "0111 1010 0000 0000", "halt", 0,
+ "------", 10, 16, "0011 1101 ssN0 dddd", "in rd,@rs", 0,
+ "------", 12, 16, "0011 1101 dddd 0100 imm16", "in rd,imm16", 0,
+ "------", 12, 8, "0011 1100 ssN0 dddd", "inb rbd,@rs", 0,
+ "------", 10, 8, "0011 1100 dddd 0100 imm16", "inb rbd,imm16", 0,
+ "-ZSV--", 11, 16, "0010 1001 ddN0 imm4m1", "inc @rd,imm4m1", 0,
+ "-ZSV--", 14, 16, "0110 1001 ddN0 imm4m1 address_dst", "inc address_dst(rd),imm4m1", 0,
+ "-ZSV--", 13, 16, "0110 1001 0000 imm4m1 address_dst", "inc address_dst,imm4m1", 0,
+ "-ZSV--", 4, 16, "1010 1001 dddd imm4m1", "inc rd,imm4m1", 0,
+ "-ZSV--", 11, 8, "0010 1000 ddN0 imm4m1", "incb @rd,imm4m1", 0,
+ "-ZSV--", 14, 8, "0110 1000 ddN0 imm4m1 address_dst", "incb address_dst(rd),imm4m1", 0,
+ "-ZSV--", 13, 8, "0110 1000 0000 imm4m1 address_dst", "incb address_dst,imm4m1", 0,
+ "-ZSV--", 4, 8, "1010 1000 dddd imm4m1", "incb rbd,imm4m1", 0,
+ "---V--", 21, 16, "0011 1011 ssN0 1000 0000 aaaa ddN0 1000", "ind @rd,@rs,ra", 0,
+ "---V--", 21, 8, "0011 1010 ssN0 1000 0000 aaaa ddN0 1000", "indb @rd,@rs,rba", 0,
+ "---V--", 21, 8, "0011 1100 ssN0 0000 0000 aaaa ddN0 1000", "inib @rd,@rs,ra", 0,
+ "---V--", 21, 16, "0011 1100 ssN0 0000 0000 aaaa ddN0 0000", "inibr @rd,@rs,ra", 0,
+ "CZSVDH", 13, 16, "0111 1011 0000 0000", "iret", 0,
+ "------", 10, 16, "0001 1110 ddN0 cccc", "jp cc,@rd", 0,
+ "------", 7, 16, "0101 1110 0000 cccc address_dst", "jp cc,address_dst", 0,
+ "------", 8, 16, "0101 1110 ddN0 cccc address_dst", "jp cc,address_dst(rd)", 0,
+ "------", 6, 16, "1110 cccc disp8", "jr cc,disp8", 0,
+
+ "------", 7, 16, "0000 1101 ddN0 0101 imm16", "ld @rd,imm16", 0,
+ "------", 8, 16, "0010 1111 ddN0 ssss", "ld @rd,rs", 0,
+ "------", 15, 16, "0100 1101 ddN0 0101 address_dst imm16", "ld address_dst(rd),imm16", 0,
+ "------", 12, 16, "0110 1111 ddN0 ssss address_dst", "ld address_dst(rd),rs", 0,
+ "------", 14, 16, "0100 1101 0000 0101 address_dst imm16", "ld address_dst,imm16", 0,
+"------", 11, 16, "0110 1111 0000 ssss address_dst", "ld address_dst,rs", 0,
+ "------", 14, 16, "0011 0011 ddN0 ssss imm16", "ld rd(imm16),rs", 0,
+ "------", 14, 16, "0111 0011 ddN0 ssss 0000 xxxx 0000 0000", "ld rd(rx),rs", 0,
+ "------", 7, 16, "0010 0001 ssN0 dddd", "ld rd,@rs", 0,
+ "------", 9, 16, "0110 0001 0000 dddd address_src", "ld rd,address_src", 0,
+ "------", 10, 16, "0110 0001 ssN0 dddd address_src", "ld rd,address_src(rs)", 0,
+ "------", 7, 16, "0010 0001 0000 dddd imm16", "ld rd,imm16", 0,
+ "------", 3, 16, "1010 0001 ssss dddd", "ld rd,rs", 0,
+ "------", 14, 16, "0011 0001 ssN0 dddd imm16", "ld rd,rs(imm16)", 0,
+ "------", 14, 16, "0111 0001 ssN0 dddd 0000 xxxx 0000 0000", "ld rd,rs(rx)", 0,
+
+ "------", 7, 8, "0000 1100 ddN0 0101 imm8 imm8", "ldb @rd,imm8", 0,
+ "------", 8, 8, "0010 1110 ddN0 ssss", "ldb @rd,rbs", 0,
+ "------", 15, 8, "0100 1100 ddN0 0101 address_dst imm8 imm8", "ldb address_dst(rd),imm8", 0,
+ "------", 12, 8, "0100 1110 ddN0 ssN0 address_dst", "ldb address_dst(rd),rbs", 0,
+ "------", 14, 8, "0100 1100 0000 0101 address_dst imm8 imm8", "ldb address_dst,imm8", 0,
+"------", 11, 8, "0110 1110 0000 ssss address_dst", "ldb address_dst,rbs", 0,
+ "------", 14, 8, "0011 0010 ddN0 ssss imm16", "ldb rd(imm16),rbs", 0,
+ "------", 14, 8, "0111 0010 ddN0 ssss 0000 xxxx 0000 0000", "ldb rd(rx),rbs", 0,
+ "------", 7, 8, "0010 0000 ssN0 dddd", "ldb rbd,@rs", 0,
+"------", 9, 8, "0110 0000 0000 dddd address_src", "ldb rbd,address_src", 0,
+ "------", 10, 8, "0110 0000 ssN0 dddd address_src", "ldb rbd,address_src(rs)", 0,
+ "------", 5, 8, "1100 dddd imm8", "ldb rbd,imm8", 0,
+ "------", 3, 8, "1010 0000 ssss dddd", "ldb rbd,rbs", 0,
+ "------", 14, 8, "0011 0000 ssN0 dddd imm16", "ldb rbd,rs(imm16)", 0,
+ "------", 14, 8, "0111 0000 ssN0 dddd 0000 xxxx 0000 0000", "ldb rbd,rs(rx)", 0,
+
+ "------", 11, 32, "0001 1101 ddN0 ssss", "ldl @rd,rrs", 0,
+ "------", 14, 32, "0101 1101 ddN0 ssss address_dst", "ldl address_dst(rd),rrs", 0,
+ "------", 15, 32, "0101 1101 0000 ssss address_dst", "ldl address_dst,rrs", 0,
+ "------", 17, 32, "0011 0111 ddN0 ssss imm16", "ldl rd(imm16),rrs", 0,
+ "------", 17, 32, "0111 0111 ddN0 ssss 0000 xxxx 0000 0000", "ldl rd(rx),rrs", 0,
+ "------", 11, 32, "0001 0100 ssN0 dddd", "ldl rrd,@rs", 0,
+ "------", 12, 32, "0101 0100 0000 dddd address_src", "ldl rrd,address_src", 0,
+ "------", 13, 32, "0101 0100 ssN0 dddd address_src", "ldl rrd,address_src(rs)", 0,
+ "------", 11, 32, "0001 0100 0000 dddd imm32", "ldl rrd,imm32", 0,
+ "------", 5, 32, "1001 0100 ssss dddd", "ldl rrd,rrs", 0,
+ "------", 17, 32, "0011 0101 ssN0 dddd imm16", "ldl rrd,rs(imm16)", 0,
+ "------", 17, 32, "0111 0101 ssN0 dddd 0000 xxxx 0000 0000", "ldl rrd,rs(rx)", 0,
+
+ "------", 12, 16, "0111 0110 0000 dddd address_src", "lda prd,address_src", 0,
+ "------", 13, 16, "0111 0110 ssN0 dddd address_src", "lda prd,address_src(rs)", 0,
+ "------", 15, 16, "0011 0100 ssN0 dddd imm16", "lda prd,rs(imm16)", 0,
+ "------", 15, 16, "0111 0100 ssN0 dddd 0000 xxxx 0000 0000", "lda prd,rs(rx)", 0,
+ "------", 15, 16, "0011 0100 0000 dddd disp16", "ldar prd,disp16", 0,
+ "------", 7, 32, "0111 1101 ssss 1ccc", "ldctl ctrl,rs", 0,
+ "------", 7, 32, "0111 1101 dddd 0ccc", "ldctl rd,ctrl", 0,
+
+ "------", 5, 16, "1011 1101 dddd imm4", "ldk rd,imm4", 0,
+
+ "------", 11, 16, "0001 1100 ddN0 1001 0000 ssss 0000 nminus1", "ldm @rd,rs,n", 0,
+ "------", 15, 16, "0101 1100 ddN0 1001 0000 ssN0 0000 nminus1 address_dst", "ldm address_dst(rd),rs,n", 0,
+ "------", 14, 16, "0101 1100 0000 1001 0000 ssss 0000 nminus1 address_dst", "ldm address_dst,rs,n", 0,
+ "------", 11, 16, "0001 1100 ssN0 0001 0000 dddd 0000 nminus1", "ldm rd,@rs,n", 0,
+ "------", 15, 16, "0101 1100 ssN0 0001 0000 dddd 0000 nminus1 address_src", "ldm rd,address_src(rs),n", 0,
+ "------", 14, 16, "0101 1100 0000 0001 0000 dddd 0000 nminus1 address_src", "ldm rd,address_src,n", 0,
+
+ "CZSVDH", 12, 16, "0011 1001 ssN0 0000", "ldps @rs", 0,
+ "CZSVDH", 16, 16, "0111 1001 0000 0000 address_src", "ldps address_src", 0,
+ "CZSVDH", 17, 16, "0111 1001 ssN0 0000 address_src", "ldps address_src(rs)", 0,
+
+ "------", 14, 16, "0011 0011 0000 ssss disp16", "ldr disp16,rs", 0,
+ "------", 14, 16, "0011 0001 0000 dddd disp16", "ldr rd,disp16", 0,
+ "------", 14, 8, "0011 0010 0000 ssss disp16", "ldrb disp16,rbs", 0,
+ "------", 14, 8, "0011 0000 0000 dddd disp16", "ldrb rbd,disp16", 0,
+ "------", 17, 32, "0011 0111 0000 ssss disp16", "ldrl disp16,rrs", 0,
+ "------", 17, 32, "0011 0101 0000 dddd disp16", "ldrl rrd,disp16", 0,
+
+ "CZS---", 7, 16, "0111 1011 0000 1010", "mbit", 0,
+ "-ZS---", 12, 16, "0111 1011 dddd 1101", "mreq rd", 0,
+ "------", 5, 16, "0111 1011 0000 1001", "mres", 0,
+ "------", 5, 16, "0111 1011 0000 1000", "mset", 0,
+
+ "CZSV--", 70, 16, "0001 1001 ssN0 dddd", "mult rrd,@rs", 0,
+ "CZSV--", 70, 16, "0101 1001 0000 dddd address_src", "mult rrd,address_src", 0,
+ "CZSV--", 70, 16, "0101 1001 ssN0 dddd address_src", "mult rrd,address_src(rs)", 0,
+ "CZSV--", 70, 16, "0001 1001 0000 dddd imm16", "mult rrd,imm16", 0,
+ "CZSV--", 70, 16, "1001 1001 ssss dddd", "mult rrd,rs", 0,
+ "CZSV--", 282, 32, "0001 1000 ssN0 dddd", "multl rqd,@rs", 0,
+ "CZSV--", 282, 32, "0101 1000 0000 dddd address_src", "multl rqd,address_src", 0,
+ "CZSV--", 282, 32, "0101 1000 ssN0 dddd address_src", "multl rqd,address_src(rs)", 0,
+ "CZSV--", 282, 32, "0001 1000 0000 dddd imm32", "multl rqd,imm32", 0,
+ "CZSV--", 282, 32, "1001 1000 ssss dddd", "multl rqd,rrs", 0,
+ "CZSV--", 12, 16, "0000 1101 ddN0 0010", "neg @rd", 0,
+ "CZSV--", 15, 16, "0100 1101 0000 0010 address_dst", "neg address_dst", 0,
+ "CZSV--", 16, 16, "0100 1101 ddN0 0010 address_dst", "neg address_dst(rd)", 0,
+ "CZSV--", 7, 16, "1000 1101 dddd 0010", "neg rd", 0,
+ "CZSV--", 12, 8, "0000 1100 ddN0 0010", "negb @rd", 0,
+ "CZSV--", 15, 8, "0100 1100 0000 0010 address_dst", "negb address_dst", 0,
+ "CZSV--", 16, 8, "0100 1100 ddN0 0010 address_dst", "negb address_dst(rd)", 0,
+ "CZSV--", 7, 8, "1000 1100 dddd 0010", "negb rbd", 0,
+
+ "------", 7, 16, "1000 1101 0000 0111", "nop", 0,
+
+ "CZS---", 7, 16, "0000 0101 ssN0 dddd", "or rd,@rs", 0,
+ "CZS---", 9, 16, "0100 0101 0000 dddd address_src", "or rd,address_src", 0,
+ "CZS---", 10, 16, "0100 0101 ssN0 dddd address_src", "or rd,address_src(rs)", 0,
+ "CZS---", 7, 16, "0000 0101 0000 dddd imm16", "or rd,imm16", 0,
+ "CZS---", 4, 16, "1000 0101 ssss dddd", "or rd,rs", 0,
+
+ "CZSP--", 7, 8, "0000 0100 ssN0 dddd", "orb rbd,@rs", 0,
+"CZSP--", 9, 8, "0100 0100 0000 dddd address_src", "orb rbd,address_src", 0,
+ "CZSP--", 10, 8, "0100 0100 ssN0 dddd address_src", "orb rbd,address_src(rs)", 0,
+ "CZSP--", 7, 8, "0000 0100 0000 dddd imm8 imm8", "orb rbd,imm8", 0,
+ "CZSP--", 4, 8, "1000 0100 ssss dddd", "orb rbd,rbs", 0,
+
+ "---V--", 0, 16, "0011 1111 ddN0 ssss", "out @rd,rs", 0,
+ "---V--", 0, 16, "0011 1011 ssss 0110 imm16", "out imm16,rs", 0,
+ "---V--", 0, 8, "0011 1110 ddN0 ssss", "outb @rd,rbs", 0,
+ "---V--", 0, 8, "0011 1010 ssss 0110 imm16", "outb imm16,rbs", 0,
+ "---V--", 0, 16, "0011 1011 ssN0 1010 0000 aaaa ddN0 1000", "outd @rd,@rs,ra", 0,
+ "---V--", 0, 8, "0011 1010 ssN0 1010 0000 aaaa ddN0 1000", "outdb @rd,@rs,rba", 0,
+ "---V--", 0, 8, "0011 1100 ssN0 0010 0000 aaaa ddN0 1000", "outib @rd,@rs,ra", 0,
+ "---V--", 0, 16, "0011 1100 ssN0 0010 0000 aaaa ddN0 0000", "outibr @rd,@rs,ra", 0,
+
+ "------", 12, 16, "0001 0111 ssN0 ddN0", "pop @rd,@rs", 0,
+ "------", 16, 16, "0101 0111 ssN0 ddN0 address_dst", "pop address_dst(rd),@rs", 0,
+ "------", 16, 16, "0101 0111 ssN0 0000 address_dst", "pop address_dst,@rs", 0,
+ "------", 8, 16, "1001 0111 ssN0 dddd", "pop rd,@rs", 0,
+
+ "------", 19, 32, "0001 0101 ssN0 ddN0", "popl @rd,@rs", 0,
+ "------", 23, 32, "0101 0101 ssN0 ddN0 address_dst", "popl address_dst(rd),@rs", 0,
+ "------", 23, 32, "0101 0101 ssN0 0000 address_dst", "popl address_dst,@rs", 0,
+ "------", 12, 32, "1001 0101 ssN0 dddd", "popl rrd,@rs", 0,
+
+ "------", 13, 16, "0001 0011 ddN0 ssN0", "push @rd,@rs", 0,
+ "------", 14, 16, "0101 0011 ddN0 0000 address_src", "push @rd,address_src", 0,
+ "------", 14, 16, "0101 0011 ddN0 ssN0 address_src", "push @rd,address_src(rs)", 0,
+ "------", 12, 16, "0000 1101 ddN0 1001 imm16", "push @rd,imm16", 0,
+ "------", 9, 16, "1001 0011 ddN0 ssss", "push @rd,rs", 0,
+
+ "------", 20, 32, "0001 0001 ddN0 ssN0", "pushl @rd,@rs", 0,
+ "------", 21, 32, "0101 0001 ddN0 ssN0 address_src", "pushl @rd,address_src(rs)", 0,
+ "------", 21, 32, "0101 0001 ddN0 0000 address_src", "pushl @rd,address_src", 0,
+ "------", 12, 32, "1001 0001 ddN0 ssss", "pushl @rd,rrs", 0,
+
+ "------", 11, 16, "0010 0011 ddN0 imm4", "res @rd,imm4", 0,
+ "------", 14, 16, "0110 0011 ddN0 imm4 address_dst", "res address_dst(rd),imm4", 0,
+ "------", 13, 16, "0110 0011 0000 imm4 address_dst", "res address_dst,imm4", 0,
+ "------", 4, 16, "1010 0011 dddd imm4", "res rd,imm4", 0,
+"------", 10, 16, "0010 0011 0000 ssss 0000 dddd 0000 0000", "res rd,rs", 0,
+
+ "------", 11, 8, "0010 0010 ddN0 imm4", "resb @rd,imm4", 0,
+ "------", 14, 8, "0110 0010 ddN0 imm4 address_dst", "resb address_dst(rd),imm4", 0,
+ "------", 13, 8, "0110 0010 0000 imm4 address_dst", "resb address_dst,imm4", 0,
+ "------", 4, 8, "1010 0010 dddd imm4", "resb rbd,imm4", 0,
+"------", 10, 8, "0010 0010 0000 ssss 0000 dddd 0000 0000", "resb rbd,rs", 0,
+
+ "CZSV--", 7, 16, "1000 1101 imm4 0011", "resflg imm4", 0,
+ "------", 10, 16, "1001 1110 0000 cccc", "ret cc", 0,
+
+ "CZSV--", 6, 16, "1011 0011 dddd 00I0", "rl rd,imm1or2", 0,
+ "CZSV--", 6, 8, "1011 0010 dddd 00I0", "rlb rbd,imm1or2", 0,
+ "CZSV--", 6, 16, "1011 0011 dddd 10I0", "rlc rd,imm1or2", 0,
+
+ "-Z----", 9, 8, "1011 0010 dddd 10I0", "rlcb rbd,imm1or2", 0,
+ "-Z----", 9, 8, "1011 1110 aaaa bbbb", "rldb rbb,rba", 0,
+
+ "CZSV--", 6, 16, "1011 0011 dddd 01I0", "rr rd,imm1or2", 0,
+ "CZSV--", 6, 8, "1011 0010 dddd 01I0", "rrb rbd,imm1or2", 0,
+ "CZSV--", 6, 16, "1011 0011 dddd 11I0", "rrc rd,imm1or2", 0,
+
+ "-Z----", 9, 8, "1011 0010 dddd 11I0", "rrcb rbd,imm1or2", 0,
+ "-Z----", 9, 8, "1011 1100 aaaa bbbb", "rrdb rbb,rba", 0,
+ "CZSV--", 5, 16, "1011 0111 ssss dddd", "sbc rd,rs", 0,
+ "CZSVDH", 5, 8, "1011 0110 ssss dddd", "sbcb rbd,rbs", 0,
+
+ "CZSVDH", 33, 8, "0111 1111 imm8", "sc imm8", 0,
+
+"CZSV--", 15, 16, "1011 0011 dddd 1011 0000 ssss 0000 0000", "sda rd,rs", 0,
+"CZSV--", 15, 8, "1011 0010 dddd 1011 0000 ssss 0000 0000", "sdab rbd,rs", 0,
+ "CZSV--", 15, 32, "1011 0011 dddd 1111 0000 ssss 0000 0000", "sdal rrd,rs", 0,
+
+"CZS---", 15, 16, "1011 0011 dddd 0011 0000 ssss 0000 0000", "sdl rd,rs", 0,
+"CZS---", 15, 8, "1011 0010 dddd 0011 0000 ssss 0000 0000", "sdlb rbd,rs", 0,
+ "CZS---", 15, 32, "1011 0011 dddd 0111 0000 ssss 0000 0000", "sdll rrd,rs", 0,
+
+ "------", 11, 16, "0010 0101 ddN0 imm4", "set @rd,imm4", 0,
+ "------", 14, 16, "0110 0101 ddN0 imm4 address_dst", "set address_dst(rd),imm4", 0,
+ "------", 13, 16, "0110 0101 0000 imm4 address_dst", "set address_dst,imm4", 0,
+ "------", 4, 16, "1010 0101 dddd imm4", "set rd,imm4", 0,
+"------", 10, 16, "0010 0101 0000 ssss 0000 dddd 0000 0000", "set rd,rs", 0,
+ "------", 11, 8, "0010 0100 ddN0 imm4", "setb @rd,imm4", 0,
+ "------", 14, 8, "0110 0100 ddN0 imm4 address_dst", "setb address_dst(rd),imm4", 0,
+ "------", 13, 8, "0110 0100 0000 imm4 address_dst", "setb address_dst,imm4", 0,
+ "------", 4, 8, "1010 0100 dddd imm4", "setb rbd,imm4", 0,
+"------", 10, 8, "0010 0100 0000 ssss 0000 dddd 0000 0000", "setb rbd,rs", 0,
+
+ "CZSV--", 7, 16, "1000 1101 imm4 0001", "setflg imm4", 0,
+
+ "------", 0, 8, "0011 1100 dddd 0101 imm16", "sinb rbd,imm16", 0,
+ "------", 0, 8, "0011 1101 dddd 0101 imm16", "sinb rd,imm16", 0,
+ "------", 0, 16, "0011 1011 ssN0 1000 0001 aaaa ddN0 1000", "sind @rd,@rs,ra", 0,
+ "------", 0, 8, "0011 1010 ssN0 1000 0001 aaaa ddN0 1000", "sindb @rd,@rs,rba", 0,
+ "------", 0, 8, "0011 1100 ssN0 0001 0000 aaaa ddN0 1000", "sinib @rd,@rs,ra", 0,
+ "------", 0, 16, "0011 1100 ssN0 0001 0000 aaaa ddN0 0000", "sinibr @rd,@rs,ra", 0,
+
+ "CZSV--", 13, 16, "1011 0011 dddd 1001 0000 0000 imm8", "sla rd,imm8", 0,
+ "CZSV--", 13, 8, "1011 0010 dddd 1001 0000 0000 imm8", "slab rbd,imm8", 0,
+ "CZSV--", 13, 32, "1011 0011 dddd 1101 0000 0000 imm8", "slal rrd,imm8", 0,
+
+ "CZS---", 13, 16, "1011 0011 dddd 0001 0000 0000 imm8", "sll rd,imm8", 0,
+ "CZS---", 13, 8, "1011 0010 dddd 0001 0000 0000 imm8", "sllb rbd,imm8", 0,
+ "CZS---", 13, 32, "1011 0011 dddd 0101 0000 0000 imm8", "slll rrd,imm8", 0,
+
+ "------", 0, 16, "0011 1011 ssss 0111 imm16", "sout imm16,rs", 0,
+ "------", 0, 8, "0011 1010 ssss 0111 imm16", "soutb imm16,rbs", 0,
+ "------", 0, 16, "0011 1011 ssN0 1011 0000 aaaa ddN0 1000", "soutd @rd,@rs,ra", 0,
+ "------", 0, 8, "0011 1010 ssN0 1011 0000 aaaa ddN0 1000", "soutdb @rd,@rs,rba", 0,
+ "------", 0, 8, "0011 1100 ssN0 0011 0000 aaaa ddN0 1000", "soutib @rd,@rs,ra", 0,
+ "------", 0, 16, "0011 1100 ssN0 0011 0000 aaaa ddN0 0000", "soutibr @rd,@rs,ra", 0,
+
+ "CZSV--", 13, 16, "1011 0011 dddd 1001 1111 1111 nim8", "sra rd,imm8", 0,
+ "CZSV--", 13, 8, "1011 0010 dddd 1001 1111 1111 nim8", "srab rbd,imm8", 0,
+ "CZSV--", 13, 32, "1011 0011 dddd 1101 1111 1111 nim8", "sral rrd,imm8", 0,
+
+ "CZSV--", 13, 16, "1011 0011 dddd 0001 1111 1111 nim8", "srl rd,imm8", 0,
+ "CZSV--", 13, 8, "1011 0010 dddd 0001 1111 1111 nim8", "srlb rbd,imm8", 0,
+ "CZSV--", 13, 32, "1011 0011 dddd 0101 1111 1111 nim8", "srll rrd,imm8", 0,
+
+ "CZSV--", 7, 16, "0000 0011 ssN0 dddd", "sub rd,@rs", 0,
+"CZSV--", 9, 16, "0100 0011 0000 dddd address_src", "sub rd,address_src", 0,
+ "CZSV--", 10, 16, "0100 0011 ssN0 dddd address_src", "sub rd,address_src(rs)", 0,
+ "CZSV--", 7, 16, "0000 0010 0000 dddd imm16", "sub rd,imm16", 0,
+ "CZSV--", 4, 16, "1000 0011 ssss dddd", "sub rd,rs", 0,
+
+ "CZSVDH", 7, 8, "0000 0010 ssN0 dddd", "subb rbd,@rs", 0,
+"CZSVDH", 9, 8, "0100 0010 0000 dddd address_src", "subb rbd,address_src", 0,
+ "CZSVDH", 10, 8, "0100 0010 ssN0 dddd address_src", "subb rbd,address_src(rs)", 0,
+ "CZSVDH", 7, 8, "0000 0010 0000 dddd imm8 imm8", "subb rbd,imm8", 0,
+ "CZSVDH", 4, 8, "1000 0010 ssss dddd", "subb rbd,rbs", 0,
+
+ "CZSV--", 14, 32, "0001 0010 ssN0 dddd", "subl rrd,@rs", 0,
+ "CZSV--", 15, 32, "0101 0010 0000 dddd address_src", "subl rrd,address_src", 0,
+ "CZSV--", 16, 32, "0101 0010 ssN0 dddd address_src", "subl rrd,address_src(rs)", 0,
+ "CZSV--", 14, 32, "0001 0010 0000 dddd imm32", "subl rrd,imm32", 0,
+ "CZSV--", 8, 32, "1001 0010 ssss dddd", "subl rrd,rrs", 0,
+
+ "------", 5, 16, "1010 1111 dddd cccc", "tcc cc,rd", 0,
+ "------", 5, 8, "1010 1110 dddd cccc", "tccb cc,rbd", 0,
+
+ "-ZS---", 8, 16, "0000 1101 ddN0 0100", "test @rd", 0,
+ "------", 11, 16, "0100 1101 0000 0100 address_dst", "test address_dst", 0,
+ "------", 12, 16, "0100 1101 ddN0 0100 address_dst", "test address_dst(rd)", 0,
+ "------", 7, 16, "1000 1101 dddd 0100", "test rd", 0,
+
+ "-ZSP--", 8, 8, "0000 1100 ddN0 0100", "testb @rd", 0,
+ "-ZSP--", 11, 8, "0100 1100 0000 0100 address_dst", "testb address_dst", 0,
+ "-ZSP--", 12, 8, "0100 1100 ddN0 0100 address_dst", "testb address_dst(rd)", 0,
+ "-ZSP--", 7, 8, "1000 1100 dddd 0100", "testb rbd", 0,
+
+ "-ZS---", 13, 32, "0001 1100 ddN0 1000", "testl @rd", 0,
+"-ZS---", 16, 32, "0101 1100 0000 1000 address_dst", "testl address_dst", 0,
+ "-ZS---", 17, 32, "0101 1100 ddN0 1000 address_dst", "testl address_dst(rd)", 0,
+ "-ZS---", 13, 32, "1001 1100 dddd 1000", "testl rrd", 0,
+
+ "-ZSV--", 25, 8, "1011 1000 ddN0 1000 0000 aaaa ssN0 0000", "trdb @rd,@rs,rba", 0,
+ "-ZSV--", 25, 8, "1011 1000 ddN0 1100 0000 aaaa ssN0 0000", "trdrb @rd,@rs,rba", 0,
+ "-ZSV--", 25, 8, "1011 1000 ddN0 0000 0000 rrrr ssN0 0000", "trib @rd,@rs,rbr", 0,
+ "-ZSV--", 25, 8, "1011 1000 ddN0 0100 0000 rrrr ssN0 0000", "trirb @rd,@rs,rbr", 0,
+ "-ZSV--", 25, 8, "1011 1000 aaN0 1110 0000 rrrr bbN0 1110", "trtdrb @ra,@rb,rbr", 0,
+ "-ZSV--", 25, 8, "1011 1000 aaN0 0010 0000 rrrr bbN0 0000", "trtib @ra,@rb,rr", 0,
+ "-ZSV--", 25, 8, "1011 1000 aaN0 0110 0000 rrrr bbN0 1110", "trtirb @ra,@rb,rbr", 0,
+ "-ZSV--", 25, 8, "1011 1000 aaN0 1010 0000 rrrr bbN0 0000", "trtrb @ra,@rb,rbr", 0,
+
+ "--S---", 11, 16, "0000 1101 ddN0 0110", "tset @rd", 0,
+ "--S---", 14, 16, "0100 1101 0000 0110 address_dst", "tset address_dst", 0,
+ "--S---", 15, 16, "0100 1101 ddN0 0110 address_dst", "tset address_dst(rd)", 0,
+ "--S---", 7, 16, "1000 1101 dddd 0110", "tset rd", 0,
+
+ "--S---", 11, 8, "0000 1100 ddN0 0110", "tsetb @rd", 0,
+ "--S---", 14, 8, "0100 1100 0000 0110 address_dst", "tsetb address_dst", 0,
+ "--S---", 15, 8, "0100 1100 ddN0 0110 address_dst", "tsetb address_dst(rd)", 0,
+ "--S---", 7, 8, "1000 1100 dddd 0110", "tsetb rbd", 0,
+
+ "-ZS---", 7, 16, "0000 1001 ssN0 dddd", "xor rd,@rs", 0,
+"-ZS---", 9, 16, "0100 1001 0000 dddd address_src", "xor rd,address_src", 0,
+ "-ZS---", 10, 16, "0100 1001 ssN0 dddd address_src", "xor rd,address_src(rs)", 0,
+ "-ZS---", 7, 16, "0000 1001 0000 dddd imm16", "xor rd,imm16", 0,
+ "-ZS---", 4, 16, "1000 1001 ssss dddd", "xor rd,rs", 0,
+
+ "-ZSP--", 7, 8, "0000 1000 ssN0 dddd", "xorb rbd,@rs", 0,
+"-ZSP--", 9, 8, "0100 1000 0000 dddd address_src", "xorb rbd,address_src", 0,
+ "-ZSP--", 10, 8, "0100 1000 ssN0 dddd address_src", "xorb rbd,address_src(rs)", 0,
+ "-ZSP--", 7, 8, "0000 1000 0000 dddd imm8 imm8", "xorb rbd,imm8", 0,
+ "-ZSP--", 4, 8, "1000 1000 ssss dddd", "xorb rbd,rbs", 0,
+ "*", 4, 8, "1000 1000 ssss dddd", "xorb rbd,rbs", 0,
+ "*", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+int
+count ()
+{
+ struct op *p = opt;
+ int r = 0;
+
+ while (p->name)
+ {
+ r++;
+ p++;
+ }
+ return r;
+
+}
+
+static
+int
+func (a, b)
+ struct op *a;
+ struct op *b;
+{
+ return strcmp ((a)->name, (b)->name);
+}
+
+
+/* opcode
+
+ literal 0000 nnnn insert nnn into stream
+ operand 0001 nnnn insert operand reg nnn into stream
+*/
+
+struct tok_struct
+{
+
+ char *match;
+ char *token;
+ int length;
+};
+
+struct tok_struct args[] =
+{
+
+ {"address_src(rs)", "CLASS_X+(ARG_RS)",},
+ {"address_dst(rd)", "CLASS_X+(ARG_RD)",},
+
+ {"rs(imm16)", "CLASS_BA+(ARG_RS)",},
+ {"rd(imm16)", "CLASS_BA+(ARG_RD)",},
+ {"prd", "CLASS_PR+(ARG_RD)",},
+ {"address_src", "CLASS_DA+(ARG_SRC)",},
+ {"address_dst", "CLASS_DA+(ARG_DST)",},
+ {"rd(rx)", "CLASS_BX+(ARG_RD)",},
+ {"rs(rx)", "CLASS_BX+(ARG_RS)",},
+
+ {"disp16", "CLASS_DISP",},
+ {"disp12", "CLASS_DISP",},
+ {"disp7", "CLASS_DISP",},
+ {"disp8", "CLASS_DISP",},
+ {"flags", "CLASS_FLAGS",},
+
+ {"imm16", "CLASS_IMM+(ARG_IMM16)",},
+ {"imm1or2", "CLASS_IMM+(ARG_IMM1OR2)",},
+ {"imm32", "CLASS_IMM+(ARG_IMM32)",},
+ {"imm4m1", "CLASS_IMM +(ARG_IMM4M1)",},
+ {"imm4", "CLASS_IMM +(ARG_IMM4)",},
+ {"n", "CLASS_IMM + (ARG_IMMN)",},
+ {"ctrl", "CLASS_CTRL",},
+ {"rba", "CLASS_REG_BYTE+(ARG_RA)",},
+ {"rbb", "CLASS_REG_BYTE+(ARG_RB)",},
+ {"rbd", "CLASS_REG_BYTE+(ARG_RD)",},
+ {"rbs", "CLASS_REG_BYTE+(ARG_RS)",},
+ {"rbr", "CLASS_REG_BYTE+(ARG_RR)",},
+
+ {"rrd", "CLASS_REG_LONG+(ARG_RD)",},
+ {"rrs", "CLASS_REG_LONG+(ARG_RS)",},
+
+ {"rqd", "CLASS_REG_QUAD+(ARG_RD)",},
+
+ {"rd", "CLASS_REG_WORD+(ARG_RD)",},
+ {"rs", "CLASS_REG_WORD+(ARG_RS)",},
+
+ {"@rd", "CLASS_IR+(ARG_RD)",},
+ {"@ra", "CLASS_IR+(ARG_RA)",},
+ {"@rb", "CLASS_IR+(ARG_RB)",},
+ {"@rs", "CLASS_IR+(ARG_RS)",},
+
+ {"imm8", "CLASS_IMM+(ARG_IMM8)",},
+ {"i2", "CLASS_IMM+(ARG_IMM2)",},
+ {"cc", "CLASS_CC",},
+
+ {"rr", "CLASS_REG_WORD+(ARG_RR)",},
+ {"ra", "CLASS_REG_WORD+(ARG_RA)",},
+ {"rs", "CLASS_REG_WORD+(ARG_RS)",},
+
+ {"1", "CLASS_IMM+(ARG_IMM_1)",},
+ {"2", "CLASS_IMM+(ARG_IMM_2)",},
+
+ 0, 0
+};
+
+struct tok_struct toks[] =
+{
+ "0000", "CLASS_BIT+0", 1,
+ "0001", "CLASS_BIT+1", 1,
+ "0010", "CLASS_BIT+2", 1,
+ "0011", "CLASS_BIT+3", 1,
+ "0100", "CLASS_BIT+4", 1,
+ "0101", "CLASS_BIT+5", 1,
+ "0110", "CLASS_BIT+6", 1,
+ "0111", "CLASS_BIT+7", 1,
+ "1000", "CLASS_BIT+8", 1,
+ "1001", "CLASS_BIT+9", 1,
+ "1010", "CLASS_BIT+0xa", 1,
+ "1011", "CLASS_BIT+0xb", 1,
+ "1100", "CLASS_BIT+0xc", 1,
+ "1101", "CLASS_BIT+0xd", 1,
+ "1110", "CLASS_BIT+0xe", 1,
+ "1111", "CLASS_BIT+0xf", 1,
+
+ "00I0", "CLASS_BIT_1OR2+0", 1,
+ "00I0", "CLASS_BIT_1OR2+1", 1,
+ "00I0", "CLASS_BIT_1OR2+2", 1,
+ "00I0", "CLASS_BIT_1OR2+3", 1,
+ "01I0", "CLASS_BIT_1OR2+4", 1,
+ "01I0", "CLASS_BIT_1OR2+5", 1,
+ "01I0", "CLASS_BIT_1OR2+6", 1,
+ "01I0", "CLASS_BIT_1OR2+7", 1,
+ "10I0", "CLASS_BIT_1OR2+8", 1,
+ "10I0", "CLASS_BIT_1OR2+9", 1,
+ "10I0", "CLASS_BIT_1OR2+0xa", 1,
+ "10I0", "CLASS_BIT_1OR2+0xb", 1,
+ "11I0", "CLASS_BIT_1OR2+0xc", 1,
+ "11I0", "CLASS_BIT_1OR2+0xd", 1,
+ "11I0", "CLASS_BIT_1OR2+0xe", 1,
+ "11I0", "CLASS_BIT_1OR2+0xf", 1,
+
+ "ssss", "CLASS_REG+(ARG_RS)", 1,
+ "dddd", "CLASS_REG+(ARG_RD)", 1,
+ "aaaa", "CLASS_REG+(ARG_RA)", 1,
+ "bbbb", "CLASS_REG+(ARG_RB)", 1,
+ "rrrr", "CLASS_REG+(ARG_RR)", 1,
+
+ "ssN0", "CLASS_REGN0+(ARG_RS)", 1,
+ "ddN0", "CLASS_REGN0+(ARG_RD)", 1,
+ "aaN0", "CLASS_REGN0+(ARG_RA)", 1,
+ "bbN0", "CLASS_REGN0+(ARG_RB)", 1,
+ "rrN0", "CLASS_REGN0+(ARG_RR)", 1,
+
+ "cccc", "CLASS_CC", 1,
+ "nnnn", "CLASS_IMM+(ARG_IMMN)", 1,
+ "xxxx", "CLASS_REG+(ARG_RX)", 1,
+ "xxN0", "CLASS_REGN0+(ARG_RX)", 1,
+ "nminus1", "CLASS_IMM+(ARG_IMMNMINUS1)", 1,
+
+ "disp16", "CLASS_DISP+(ARG_DISP16)", 4,
+ "disp12", "CLASS_DISP+(ARG_DISP12)", 3,
+ "flags", "CLASS_FLAGS", 1,
+ "address_dst", "CLASS_ADDRESS+(ARG_DST)", 4,
+ "address_src", "CLASS_ADDRESS+(ARG_SRC)", 4,
+ "imm4m1", "CLASS_IMM+(ARG_IMM4M1)", 1,
+ "imm4", "CLASS_IMM+(ARG_IMM4)", 1,
+
+ "imm8", "CLASS_IMM+(ARG_IMM8)", 2,
+ "imm16", "CLASS_IMM+(ARG_IMM16)", 4,
+ "imm32", "CLASS_IMM+(ARG_IMM32)", 8,
+ "nim8", "CLASS_IMM+(ARG_NIM8)", 2,
+ "0ccc", "CLASS_0CCC", 1,
+ "1ccc", "CLASS_1CCC", 1,
+ "disp8", "CLASS_DISP8", 2,
+ "0disp7", "CLASS_0DISP7", 2,
+ "1disp7", "CLASS_1DISP7", 2,
+ "01ii", "CLASS_01II", 1,
+ "00ii", "CLASS_00II", 1,
+ 0, 0
+
+};
+
+char *
+translate (table, x, length)
+ struct tok_struct *table;
+ char *x;
+ int *length;
+{
+
+ int found;
+
+ found = 0;
+ while (table->match)
+ {
+ int l = strlen (table->match);
+
+ if (strncmp (table->match, x, l) == 0)
+ {
+ /* Got a hit */
+ printf ("%s", table->token);
+ *length += table->length;
+ return x + l;
+ }
+
+ table++;
+ }
+ fprintf (stderr, "Can't find %s\n", x);
+ printf ("**** Can't find %s\n", x);
+ while (*x)
+ x++;
+ return x;
+}
+
+void
+chewbits (bits, length)
+ char *bits;
+ int *length;
+{
+ int n = 0;
+
+ *length = 0;
+ printf ("{");
+ while (*bits)
+ {
+ while (*bits == ' ')
+ {
+ bits++;
+ }
+ bits = translate (toks, bits, length);
+ n++;
+ printf (",");
+
+ }
+ while (n < BYTE_INFO_LEN - 1)
+ {
+ printf ("0,");
+ n++;
+ }
+ printf ("}");
+}
+
+
+static
+int
+chewname (name)
+ char *name;
+{
+ char *n;
+ int nargs = 0;
+
+ n = name;
+ printf ("\"");
+ while (*n && !iswhite (*n))
+ {
+ printf ("%c", *n);
+ n++;
+ }
+ printf ("\","); /* Scan the operands and make entires for
+ them -remember indirect things */
+
+ n = name;
+ printf ("OPC_");
+ while (*n && !iswhite (*n))
+ {
+ printf ("%c", *n);
+ n++;
+ }
+ printf (",0,{");
+
+ while (*n)
+ {
+ int d;
+
+ while (*n == ',' || iswhite (*n))
+ n++;
+ nargs++;
+ n = translate (args, n, &d);
+ printf (",");
+ }
+ if (nargs == 0)
+ {
+ printf ("0");
+ }
+ printf ("},");
+ return nargs;
+}
+
+static
+void
+sub (x, c)
+ char *x;
+ char c;
+{
+ while (*x)
+ {
+ if (x[0] == c && x[1] == c &&
+ x[2] == c && x[3] == c)
+ {
+ x[2] = 'N';
+ x[3] = '0';
+ }
+ x++;
+ }
+}
+
+
+#if 0
+#define D(x) ((x) == '1' || (x) =='0')
+#define M(y) (strncmp(y,x,4)==0)
+printmangled (x)
+ char *x;
+{
+ return;
+ while (*x)
+ {
+ if (D (x[0]) && D (x[1]) && D (x[2]) && D (x[3]))
+ {
+ printf ("XXXX");
+ }
+ else if (M ("ssss"))
+ {
+ printf ("ssss");
+ }
+ else if (M ("dddd"))
+ {
+ printf ("dddd");
+ }
+ else
+ printf ("____");
+
+ x += 4;
+
+ if (x[0] == ' ')
+ {
+ printf ("_");
+ x++;
+ }
+ }
+
+}
+
+#endif
+/*#define WORK_TYPE*/
+void
+print_type (n)
+ struct op *n;
+{
+#ifdef WORK_TYPE
+ while (*s && !iswhite (*s))
+ {
+ l = *s;
+ s++;
+ }
+ switch (l)
+ {
+ case 'l':
+ printf ("32,");
+ break;
+ case 'b':
+ printf ("8,");
+ break;
+ default:
+ printf ("16,");
+ break;
+ }
+#else
+ printf ("%2d,", n->type);
+#endif
+}
+
+
+void
+internal ()
+{
+ int c = count ();
+ struct op *new = xmalloc (sizeof (struct op) * c);
+ struct op *p = opt;
+ memcpy (new, p, c * sizeof (struct op));
+
+ /* sort all names in table alphabetically */
+ qsort (new, c, sizeof (struct op), func);
+
+ p = new;
+ while (p->flags[0] != '*')
+ {
+ /* If there are any @rs, sub the ssss into a ssn0,
+ (rs), (ssn0)
+ */
+ int loop = 1;
+
+ printf ("\"%s\",%2d, ", p->flags, p->cycles);
+ while (loop)
+ {
+ char *s = p->name;
+
+ loop = 0;
+ while (*s)
+ {
+ if (s[0] == '@')
+ {
+ char c;
+
+ /* skip the r and sub the string */
+ s++;
+ c = s[1];
+ sub (p->bits, c);
+ }
+ if (s[0] == '(' && s[3] == ')')
+ {
+ sub (p->bits, s[2]);
+ }
+ if (s[0] == '(')
+ {
+ sub (p->bits, s[-1]);
+ }
+
+ s++;
+ }
+
+ }
+ print_type (p);
+ printf ("\"%s\",\"%s\",0,\n", p->bits, p->name);
+ p++;
+ }
+}
+
+static
+void
+gas ()
+{
+ int c = count ();
+ struct op *p = opt;
+ int idx = 0;
+ char *oldname = "";
+ struct op *new = xmalloc (sizeof (struct op) * c);
+
+ memcpy (new, p, c * sizeof (struct op));
+
+ /* sort all names in table alphabetically */
+ qsort (new, c, sizeof (struct op), func);
+
+ printf (" /* THIS FILE IS AUTOMAGICALLY GENERATED, DON'T EDIT IT */\n");
+
+ printf ("#define ARG_MASK 0x0f\n");
+
+ printf ("#define ARG_SRC 0x01\n");
+ printf ("#define ARG_DST 0x02\n");
+
+ printf ("#define ARG_RS 0x01\n");
+ printf ("#define ARG_RD 0x02\n");
+ printf ("#define ARG_RA 0x03\n");
+ printf ("#define ARG_RB 0x04\n");
+ printf ("#define ARG_RR 0x05\n");
+ printf ("#define ARG_RX 0x06\n");
+ printf ("#define ARG_IMM4 0x01\n");
+ printf ("#define ARG_IMM8 0x02\n");
+ printf ("#define ARG_IMM16 0x03\n");
+ printf ("#define ARG_IMM32 0x04\n");
+ printf ("#define ARG_IMMN 0x05\n");
+ printf ("#define ARG_IMMNMINUS1 0x05\n");
+ printf ("#define ARG_IMM_1 0x06\n");
+ printf ("#define ARG_IMM_2 0x07\n");
+ printf ("#define ARG_DISP16 0x08\n");
+ printf ("#define ARG_NIM8 0x09\n");
+ printf ("#define ARG_IMM2 0x0a\n");
+ printf ("#define ARG_IMM1OR2 0x0b\n");
+
+ printf ("#define ARG_DISP12 0x0b\n");
+ printf ("#define ARG_DISP8 0x0c\n");
+ printf ("#define ARG_IMM4M1 0x0d\n");
+ printf ("#define CLASS_MASK 0x1fff0\n");
+ printf ("#define CLASS_X 0x10\n");
+ printf ("#define CLASS_BA 0x20\n");
+ printf ("#define CLASS_DA 0x30\n");
+ printf ("#define CLASS_BX 0x40\n");
+ printf ("#define CLASS_DISP 0x50\n");
+ printf ("#define CLASS_IMM 0x60\n");
+ printf ("#define CLASS_CC 0x70\n");
+ printf ("#define CLASS_CTRL 0x80\n");
+ printf ("#define CLASS_ADDRESS 0xd0\n");
+ printf ("#define CLASS_0CCC 0xe0\n");
+ printf ("#define CLASS_1CCC 0xf0\n");
+ printf ("#define CLASS_0DISP7 0x100\n");
+ printf ("#define CLASS_1DISP7 0x200\n");
+ printf ("#define CLASS_01II 0x300\n");
+ printf ("#define CLASS_00II 0x400\n");
+ printf ("#define CLASS_BIT 0x500\n");
+ printf ("#define CLASS_FLAGS 0x600\n");
+ printf ("#define CLASS_IR 0x700\n");
+ printf ("#define CLASS_DISP8 0x800\n");
+
+ printf ("#define CLASS_BIT_1OR2 0x900\n");
+ printf ("#define CLASS_REG 0x7000\n");
+ printf ("#define CLASS_REG_BYTE 0x2000\n");
+ printf ("#define CLASS_REG_WORD 0x3000\n");
+ printf ("#define CLASS_REG_QUAD 0x4000\n");
+ printf ("#define CLASS_REG_LONG 0x5000\n");
+ printf ("#define CLASS_REGN0 0x8000\n");
+ printf ("#define CLASS_PR 0x10000\n");
+
+ printf ("#define OPC_adc 0\n");
+ printf ("#define OPC_adcb 1\n");
+ printf ("#define OPC_add 2\n");
+ printf ("#define OPC_addb 3\n");
+ printf ("#define OPC_addl 4\n");
+ printf ("#define OPC_and 5\n");
+ printf ("#define OPC_andb 6\n");
+ printf ("#define OPC_bit 7\n");
+ printf ("#define OPC_bitb 8\n");
+ printf ("#define OPC_call 9\n");
+ printf ("#define OPC_calr 10\n");
+ printf ("#define OPC_clr 11\n");
+ printf ("#define OPC_clrb 12\n");
+ printf ("#define OPC_com 13\n");
+ printf ("#define OPC_comb 14\n");
+ printf ("#define OPC_comflg 15\n");
+ printf ("#define OPC_cp 16\n");
+ printf ("#define OPC_cpb 17\n");
+ printf ("#define OPC_cpd 18\n");
+ printf ("#define OPC_cpdb 19\n");
+ printf ("#define OPC_cpdr 20\n");
+ printf ("#define OPC_cpdrb 21\n");
+ printf ("#define OPC_cpi 22\n");
+ printf ("#define OPC_cpib 23\n");
+ printf ("#define OPC_cpir 24\n");
+ printf ("#define OPC_cpirb 25\n");
+ printf ("#define OPC_cpl 26\n");
+ printf ("#define OPC_cpsd 27\n");
+ printf ("#define OPC_cpsdb 28\n");
+ printf ("#define OPC_cpsdr 29\n");
+ printf ("#define OPC_cpsdrb 30\n");
+ printf ("#define OPC_cpsi 31\n");
+ printf ("#define OPC_cpsib 32\n");
+ printf ("#define OPC_cpsir 33\n");
+ printf ("#define OPC_cpsirb 34\n");
+ printf ("#define OPC_dab 35\n");
+ printf ("#define OPC_dbjnz 36\n");
+ printf ("#define OPC_dec 37\n");
+ printf ("#define OPC_decb 38\n");
+ printf ("#define OPC_di 39\n");
+ printf ("#define OPC_div 40\n");
+ printf ("#define OPC_divl 41\n");
+ printf ("#define OPC_djnz 42\n");
+ printf ("#define OPC_ei 43\n");
+ printf ("#define OPC_ex 44\n");
+ printf ("#define OPC_exb 45\n");
+ printf ("#define OPC_exts 46\n");
+ printf ("#define OPC_extsb 47\n");
+ printf ("#define OPC_extsl 48\n");
+ printf ("#define OPC_halt 49\n");
+ printf ("#define OPC_in 50\n");
+ printf ("#define OPC_inb 51\n");
+ printf ("#define OPC_inc 52\n");
+ printf ("#define OPC_incb 53\n");
+ printf ("#define OPC_ind 54\n");
+ printf ("#define OPC_indb 55\n");
+ printf ("#define OPC_inib 56\n");
+ printf ("#define OPC_inibr 57\n");
+ printf ("#define OPC_iret 58\n");
+ printf ("#define OPC_jp 59\n");
+ printf ("#define OPC_jr 60\n");
+ printf ("#define OPC_ld 61\n");
+ printf ("#define OPC_lda 62\n");
+ printf ("#define OPC_ldar 63\n");
+ printf ("#define OPC_ldb 64\n");
+ printf ("#define OPC_ldctl 65\n");
+ printf ("#define OPC_ldir 66\n");
+ printf ("#define OPC_ldirb 67\n");
+ printf ("#define OPC_ldk 68\n");
+ printf ("#define OPC_ldl 69\n");
+ printf ("#define OPC_ldm 70\n");
+ printf ("#define OPC_ldps 71\n");
+ printf ("#define OPC_ldr 72\n");
+ printf ("#define OPC_ldrb 73\n");
+ printf ("#define OPC_ldrl 74\n");
+ printf ("#define OPC_mbit 75\n");
+ printf ("#define OPC_mreq 76\n");
+ printf ("#define OPC_mres 77\n");
+ printf ("#define OPC_mset 78\n");
+ printf ("#define OPC_mult 79\n");
+ printf ("#define OPC_multl 80\n");
+ printf ("#define OPC_neg 81\n");
+ printf ("#define OPC_negb 82\n");
+ printf ("#define OPC_nop 83\n");
+ printf ("#define OPC_or 84\n");
+ printf ("#define OPC_orb 85\n");
+ printf ("#define OPC_out 86\n");
+ printf ("#define OPC_outb 87\n");
+ printf ("#define OPC_outd 88\n");
+ printf ("#define OPC_outdb 89\n");
+ printf ("#define OPC_outib 90\n");
+ printf ("#define OPC_outibr 91\n");
+ printf ("#define OPC_pop 92\n");
+ printf ("#define OPC_popl 93\n");
+ printf ("#define OPC_push 94\n");
+ printf ("#define OPC_pushl 95\n");
+ printf ("#define OPC_res 96\n");
+ printf ("#define OPC_resb 97\n");
+ printf ("#define OPC_resflg 98\n");
+ printf ("#define OPC_ret 99\n");
+ printf ("#define OPC_rl 100\n");
+ printf ("#define OPC_rlb 101\n");
+ printf ("#define OPC_rlc 102\n");
+ printf ("#define OPC_rlcb 103\n");
+ printf ("#define OPC_rldb 104\n");
+ printf ("#define OPC_rr 105\n");
+ printf ("#define OPC_rrb 106\n");
+ printf ("#define OPC_rrc 107\n");
+ printf ("#define OPC_rrcb 108\n");
+ printf ("#define OPC_rrdb 109\n");
+ printf ("#define OPC_sbc 110\n");
+ printf ("#define OPC_sbcb 111\n");
+ printf ("#define OPC_sda 112\n");
+ printf ("#define OPC_sdab 113\n");
+ printf ("#define OPC_sdal 114\n");
+ printf ("#define OPC_sdl 115\n");
+ printf ("#define OPC_sdlb 116\n");
+ printf ("#define OPC_sdll 117\n");
+ printf ("#define OPC_set 118\n");
+ printf ("#define OPC_setb 119\n");
+ printf ("#define OPC_setflg 120\n");
+ printf ("#define OPC_sinb 121\n");
+ printf ("#define OPC_sind 122\n");
+ printf ("#define OPC_sindb 123\n");
+ printf ("#define OPC_sinib 124\n");
+ printf ("#define OPC_sinibr 125\n");
+ printf ("#define OPC_sla 126\n");
+ printf ("#define OPC_slab 127\n");
+ printf ("#define OPC_slal 128\n");
+ printf ("#define OPC_sll 129\n");
+ printf ("#define OPC_sllb 130\n");
+ printf ("#define OPC_slll 131\n");
+ printf ("#define OPC_sout 132\n");
+ printf ("#define OPC_soutb 133\n");
+ printf ("#define OPC_soutd 134\n");
+ printf ("#define OPC_soutdb 135\n");
+ printf ("#define OPC_soutib 136\n");
+ printf ("#define OPC_soutibr 137\n");
+ printf ("#define OPC_sra 138\n");
+ printf ("#define OPC_srab 139\n");
+ printf ("#define OPC_sral 140\n");
+ printf ("#define OPC_srl 141\n");
+ printf ("#define OPC_srlb 142\n");
+ printf ("#define OPC_srll 143\n");
+ printf ("#define OPC_sub 144\n");
+ printf ("#define OPC_subb 145\n");
+ printf ("#define OPC_subl 146\n");
+ printf ("#define OPC_tcc 147\n");
+ printf ("#define OPC_tccb 148\n");
+ printf ("#define OPC_test 149\n");
+ printf ("#define OPC_testb 150\n");
+ printf ("#define OPC_testl 151\n");
+ printf ("#define OPC_trdb 152\n");
+ printf ("#define OPC_trdrb 153\n");
+ printf ("#define OPC_trib 154\n");
+ printf ("#define OPC_trirb 155\n");
+ printf ("#define OPC_trtdrb 156\n");
+ printf ("#define OPC_trtib 157\n");
+ printf ("#define OPC_trtirb 158\n");
+ printf ("#define OPC_trtrb 159\n");
+ printf ("#define OPC_tset 160\n");
+ printf ("#define OPC_tsetb 161\n");
+ printf ("#define OPC_xor 162\n");
+ printf ("#define OPC_xorb 163\n");
+
+ printf ("#define OPC_ldd 164 \n");
+ printf ("#define OPC_lddb 165 \n");
+ printf ("#define OPC_lddr 166 \n");
+ printf ("#define OPC_lddrb 167 \n");
+ printf ("#define OPC_ldi 168 \n");
+ printf ("#define OPC_ldib 169 \n");
+ printf ("#define OPC_sc 170\n");
+ printf ("#define OPC_bpt 171\n");
+ printf ("#define OPC_ext0e 172\n");
+ printf ("#define OPC_ext0f 172\n");
+ printf ("#define OPC_ext8e 172\n");
+ printf ("#define OPC_ext8f 172\n");
+ printf ("#define OPC_rsvd36 172\n");
+ printf ("#define OPC_rsvd38 172\n");
+ printf ("#define OPC_rsvd78 172\n");
+ printf ("#define OPC_rsvd7e 172\n");
+ printf ("#define OPC_rsvd9d 172\n");
+ printf ("#define OPC_rsvd9f 172\n");
+ printf ("#define OPC_rsvdb9 172\n");
+ printf ("#define OPC_rsvdbf 172\n");
+#if 0
+ for (i = 0; toks[i].token; i++)
+ printf ("#define %s\t0x%x\n", toks[i].token, i * 16);
+#endif
+ printf ("typedef struct {\n");
+
+ printf ("#ifdef NICENAMES\n");
+ printf ("char *nicename;\n");
+ printf ("int type;\n");
+ printf ("int cycles;\n");
+ printf ("int flags;\n");
+ printf ("#endif\n");
+ printf ("char *name;\n");
+ printf ("unsigned char opcode;\n");
+ printf ("void (*func)();\n");
+ printf ("unsigned int arg_info[4];\n");
+ printf ("unsigned int byte_info[%d];\n", BYTE_INFO_LEN);
+ printf ("int noperands;\n");
+ printf ("int length;\n");
+ printf ("int idx;\n");
+ printf ("} opcode_entry_type;\n");
+ printf ("#ifdef DEFINE_TABLE\n");
+ printf ("opcode_entry_type z8k_table[] = {\n");
+
+ while (new->flags && new->flags[0])
+ {
+ int nargs;
+ int length;
+
+ printf ("\n\n/* %s *** %s */\n", new->bits, new->name);
+ printf ("{\n");
+
+ printf ("#ifdef NICENAMES\n");
+ printf ("\"%s\",%d,%d,\n", new->name, new->type, new->cycles);
+ {
+ int answer = 0;
+ char *p = new->flags;
+
+ while (*p)
+ {
+ answer <<= 1;
+
+ if (*p != '-')
+ answer |= 1;
+ p++;
+ }
+ printf ("0x%02x,\n", answer);
+ }
+
+ printf ("#endif\n");
+
+ nargs = chewname (new->name);
+
+ printf ("\n\t");
+ chewbits (new->bits, &length);
+ length /= 2;
+ if (length & 1)
+ abort();
+
+ printf (",%d,%d,%d", nargs, length, idx);
+ idx++;
+ oldname = new->name;
+ printf ("},\n");
+ new++;
+ }
+ printf ("0,0};\n");
+ printf ("#endif\n");
+}
+
+
+int
+main (ac, av)
+ int ac;
+ char **av;
+{
+ struct op *p = opt;
+
+ if (ac == 2 && strcmp (av[1], "-t") == 0)
+ {
+ internal ();
+ }
+ else if (ac == 2 && strcmp (av[1], "-h") == 0)
+ {
+ while (p->name)
+ {
+ printf ("%-25s\t%s\n", p->name, p->bits);
+ p++;
+ }
+ }
+
+ else if (ac == 2 && strcmp (av[1], "-a") == 0)
+ {
+ gas ();
+ }
+ else if (ac == 2 && strcmp (av[1], "-d") == 0)
+ {
+ /*dis();*/
+ }
+ else
+ {
+ printf ("Usage: %s -t\n", av[0]);
+ printf ("-t : generate new z8.c internal table\n");
+ printf ("-a : generate new table for gas\n");
+ printf ("-d : generate new table for disassemble\n");
+ printf ("-h : generate new table for humans\n");
+ }
+return 0;
+}
diff --git a/setup.com b/setup.com
new file mode 100644
index 00000000000..553afd55ae1
--- /dev/null
+++ b/setup.com
@@ -0,0 +1,8 @@
+$! setup files for openVMS/Alpha
+$!
+$ define aout [-.INCLUDE.AOUT]
+$ define coff [-.INCLUDE.COFF]
+$ define elf [-.INCLUDE.ELF]
+$ define mpw [-.INCLUDE.MPW]
+$ define nlm [-.INCLUDE.NLM]
+$ define opcode [-.INCLUDE.OPCODE]
diff --git a/symlink-tree b/symlink-tree
new file mode 100755
index 00000000000..096582db6eb
--- /dev/null
+++ b/symlink-tree
@@ -0,0 +1,48 @@
+#!/bin/sh
+# Create a symlink tree.
+#
+# Syntax: symlink-tree srcdir "ignore1 ignore2 ..."
+#
+# where srcdir is the directory to create a symlink tree to,
+# and "ignoreN" is a list of files/directories to ignore.
+
+prog=$0
+srcdir=$1
+ignore="$2"
+
+ignore_additional=". .. CVS"
+
+# If we were invoked with a relative path name, adjust ${prog} to work
+# in subdirs.
+case ${prog} in
+/*) ;;
+*) prog=../${prog} ;;
+esac
+
+# Set newsrcdir to something subdirectories can use.
+case ${srcdir} in
+/*) newsrcdir=${srcdir} ;;
+*) newsrcdir=../${srcdir} ;;
+esac
+
+for f in `ls -a ${srcdir}`; do
+ if [ -d ${srcdir}/$f ]; then
+ found=
+ for i in ${ignore} ${ignore_additional}; do
+ if [ "$f" = "$i" ]; then
+ found=yes
+ fi
+ done
+ if [ -z "${found}" ]; then
+ echo "$f ..working in"
+ if [ -d $f ]; then true; else mkdir $f; fi
+ (cd $f; ${prog} ${newsrcdir}/$f "${ignore}")
+ fi
+ else
+ echo "$f ..linked"
+ rm -f $f
+ ln -s ${srcdir}/$f .
+ fi
+done
+
+exit 0
diff --git a/ylwrap b/ylwrap
new file mode 100755
index 00000000000..2288ccde3ac
--- /dev/null
+++ b/ylwrap
@@ -0,0 +1,123 @@
+#! /bin/sh
+# ylwrap - wrapper for lex/yacc invocations.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Usage:
+# ylwrap PROGRAM INPUT [OUTPUT DESIRED]... -- [ARGS]...
+# * PROGRAM is program to run.
+# * INPUT is the input file
+# * OUTPUT is file PROG generates
+# * DESIRED is file we actually want
+# * ARGS are passed to PROG
+# Any number of OUTPUT,DESIRED pairs may be used.
+
+# The program to run.
+prog="$1"
+shift
+# Make any relative path in $prog absolute.
+case "$prog" in
+ /* | [A-Za-z]:\\*) ;;
+ */*) prog="`pwd`/$prog" ;;
+esac
+
+# The input.
+input="$1"
+shift
+case "$input" in
+ /* | [A-Za-z]:\\*)
+ # Absolute path; do nothing.
+ ;;
+ *)
+ # Relative path. Make it absolute. Why? Because otherwise any
+ # debugging info in the generated file will point to the wrong
+ # place. This is really gross.
+ input="`pwd`/$input"
+ ;;
+esac
+
+# We don't want to use the absolute path if the input in the current
+# directory like when making a tar ball.
+input_base=`echo $input | sed -e 's|.*/||'`
+if test -f $input_base && cmp $input_base $input >/dev/null 2>&1; then
+ input=$input_base
+fi
+
+pairlist=
+while test "$#" -ne 0; do
+ if test "$1" = "--"; then
+ shift
+ break
+ fi
+ pairlist="$pairlist $1"
+ shift
+done
+
+# FIXME: add hostname here for parallel makes that run commands on
+# other machines. But that might take us over the 14-char limit.
+dirname=ylwrap$$
+trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15
+mkdir $dirname || exit 1
+
+cd $dirname
+case "$input" in
+ /* | [A-Za-z]:\\*)
+ # Absolute path; do nothing.
+ ;;
+ *)
+ # Make a symbolic link, hard link or hardcopy.
+ ln -s ../"$input" . > /dev/null 2>&1 || ln ../"$input" . > /dev/null 2>&1 || cp ../"$input" .
+ ;;
+esac
+$prog ${1+"$@"} "$input"
+status=$?
+
+if test $status -eq 0; then
+ set X $pairlist
+ shift
+ first=yes
+ while test "$#" -ne 0; do
+ if test -f "$1"; then
+ # If $2 is an absolute path name, then just use that,
+ # otherwise prepend `../'.
+ case "$2" in
+ /* | [A-Za-z]:\\*) target="$2";;
+ *) target="../$2";;
+ esac
+ mv "$1" "$target" || status=$?
+ else
+ # A missing file is only an error for the first file. This
+ # is a blatant hack to let us support using "yacc -d". If -d
+ # is not specified, we don't want an error when the header
+ # file is "missing".
+ if test $first = yes; then
+ status=1
+ fi
+ fi
+ shift
+ shift
+ first=no
+ done
+else
+ status=$?
+fi
+
+# Remove the directory.
+cd ..
+rm -rf $dirname
+
+exit $status